summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore184
-rw-r--r--BUILD/FINISH.sh1
-rw-r--r--BUILD/Makefile.am44
-rw-r--r--BUILD/SETUP.sh6
-rwxr-xr-xBUILD/compile-alpha-cxx10
-rwxr-xr-xBUILD/compile-alpha-debug7
-rwxr-xr-xBUILD/compile-ia64-debug-max13
-rwxr-xr-xBUILD/compile-pentium-debug2
-rwxr-xr-xBUILD/compile-pentium-debug-max2
-rwxr-xr-xBUILD/compile-pentium-debug-no-bdb2
-rwxr-xr-xBUILD/compile-pentium-debug-openssl13
-rwxr-xr-xBUILD/compile-pentium-gcov3
-rwxr-xr-xBUILD/compile-pentium-max3
-rwxr-xr-xBUILD/compile-pentium-mysqlfs-debug13
-rwxr-xr-xBUILD/compile-pentium-pgcc23
-rwxr-xr-xBUILD/compile-pentium-symbols15
-rwxr-xr-xBUILD/compile-solaris-sparc2
-rwxr-xr-xBUILD/compile-solaris-sparc-debug16
-rwxr-xr-xBUILD/compile-solaris-sparc-purify19
-rw-r--r--BitKeeper/etc/config1
-rw-r--r--BitKeeper/etc/gone1434
-rw-r--r--BitKeeper/etc/logging_ok53
-rwxr-xr-xBitKeeper/triggers/post-commit51
-rwxr-xr-xBuild-tools/Do-all-build-steps8
-rwxr-xr-xBuild-tools/Do-compile14
-rwxr-xr-xBuild-tools/Do-linux-build3
-rwxr-xr-xBuild-tools/Do-patch-file4
-rwxr-xr-xBuild-tools/Do-rpm25
-rw-r--r--Docs/Flags/argentina.eps149
-rw-r--r--Docs/Flags/argentina.gifbin348 -> 187 bytes
-rw-r--r--Docs/Flags/argentina.pdfbin0 -> 923 bytes
-rw-r--r--Docs/Flags/armenia.eps256
-rwxr-xr-xDocs/Flags/armenia.gifbin0 -> 117 bytes
-rw-r--r--Docs/Flags/armenia.txt (renamed from Docs/Flags/island.eps)0
-rw-r--r--Docs/Flags/australia.eps145
-rw-r--r--Docs/Flags/australia.gifbin689 -> 663 bytes
-rw-r--r--Docs/Flags/australia.pdfbin0 -> 1382 bytes
-rw-r--r--Docs/Flags/austria.eps109
-rw-r--r--Docs/Flags/austria.gifbin132 -> 132 bytes
-rw-r--r--Docs/Flags/austria.pdfbin0 -> 816 bytes
-rw-r--r--Docs/Flags/belgium.eps98
-rw-r--r--Docs/Flags/belgium.gifbin0 -> 116 bytes
-rw-r--r--Docs/Flags/belgium.pdfbin0 -> 790 bytes
-rw-r--r--Docs/Flags/belgium.txt (renamed from Docs/Flags/island.gif)0
-rw-r--r--Docs/Flags/bulgaria.eps109
-rw-r--r--Docs/Flags/bulgaria.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/bulgaria.pdfbin0 -> 821 bytes
-rw-r--r--Docs/Flags/canada.eps149
-rw-r--r--Docs/Flags/canada.gifbin407 -> 411 bytes
-rw-r--r--Docs/Flags/canada.pdfbin0 -> 1103 bytes
-rw-r--r--Docs/Flags/chile.eps115
-rw-r--r--Docs/Flags/chile.gifbin370 -> 256 bytes
-rw-r--r--Docs/Flags/chile.pdfbin0 -> 978 bytes
-rw-r--r--Docs/Flags/china.eps93
-rw-r--r--Docs/Flags/china.gifbin224 -> 227 bytes
-rw-r--r--Docs/Flags/china.pdfbin0 -> 945 bytes
-rw-r--r--Docs/Flags/costa-rica.eps98
-rw-r--r--Docs/Flags/costa-rica.gifbin0 -> 147 bytes
-rw-r--r--Docs/Flags/costa-rica.pdfbin0 -> 845 bytes
-rw-r--r--Docs/Flags/costa-rica.txt (renamed from Docs/Flags/island.txt)0
-rw-r--r--Docs/Flags/czech-republic.eps137
-rw-r--r--Docs/Flags/czech-republic.gifbin248 -> 180 bytes
-rw-r--r--Docs/Flags/czech-republic.pdfbin0 -> 936 bytes
-rw-r--r--Docs/Flags/denmark.eps149
-rw-r--r--Docs/Flags/denmark.gifbin253 -> 204 bytes
-rw-r--r--Docs/Flags/denmark.pdfbin0 -> 1011 bytes
-rw-r--r--Docs/Flags/estonia.eps103
-rw-r--r--Docs/Flags/estonia.gifbin126 -> 126 bytes
-rw-r--r--Docs/Flags/estonia.pdfbin0 -> 820 bytes
-rw-r--r--Docs/Flags/finland.eps149
-rw-r--r--Docs/Flags/finland.gifbin192 -> 131 bytes
-rw-r--r--Docs/Flags/finland.pdfbin0 -> 834 bytes
-rw-r--r--Docs/Flags/france.eps149
-rw-r--r--Docs/Flags/france.gifbin158 -> 146 bytes
-rw-r--r--Docs/Flags/france.pdfbin0 -> 796 bytes
-rw-r--r--Docs/Flags/germany.eps79
-rw-r--r--Docs/Flags/germany.gifbin126 -> 126 bytes
-rw-r--r--Docs/Flags/germany.pdfbin0 -> 804 bytes
-rw-r--r--Docs/Flags/great-britain.eps141
-rw-r--r--Docs/Flags/great-britain.gifbin1193 -> 511 bytes
-rw-r--r--Docs/Flags/great-britain.pdfbin0 -> 1348 bytes
-rw-r--r--Docs/Flags/greece.eps149
-rw-r--r--Docs/Flags/greece.gifbin282 -> 267 bytes
-rw-r--r--Docs/Flags/greece.pdfbin0 -> 1006 bytes
-rw-r--r--Docs/Flags/hungary.eps109
-rw-r--r--Docs/Flags/hungary.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/hungary.pdfbin0 -> 822 bytes
-rw-r--r--Docs/Flags/iceland.eps141
-rw-r--r--Docs/Flags/iceland.gifbin197 -> 159 bytes
-rw-r--r--Docs/Flags/iceland.pdfbin0 -> 867 bytes
-rw-r--r--Docs/Flags/indonesia.eps98
-rw-r--r--Docs/Flags/indonesia.gifbin133 -> 113 bytes
-rw-r--r--Docs/Flags/indonesia.pdfbin0 -> 804 bytes
-rw-r--r--Docs/Flags/ireland.eps149
-rw-r--r--Docs/Flags/ireland.gifbin158 -> 146 bytes
-rw-r--r--Docs/Flags/ireland.pdfbin0 -> 794 bytes
-rw-r--r--Docs/Flags/italy.eps149
-rw-r--r--Docs/Flags/italy.gifbin158 -> 146 bytes
-rw-r--r--Docs/Flags/italy.pdfbin0 -> 794 bytes
-rw-r--r--Docs/Flags/japan.eps149
-rw-r--r--Docs/Flags/japan.gifbin357 -> 192 bytes
-rw-r--r--Docs/Flags/japan.pdfbin0 -> 971 bytes
-rw-r--r--Docs/Flags/latvia.eps137
-rw-r--r--Docs/Flags/latvia.gifbin117 -> 126 bytes
-rw-r--r--Docs/Flags/latvia.pdfbin0 -> 819 bytes
-rw-r--r--Docs/Flags/mexico.eps98
-rw-r--r--Docs/Flags/mexico.gifbin0 -> 615 bytes
-rw-r--r--Docs/Flags/mexico.pdfbin0 -> 1072 bytes
-rw-r--r--Docs/Flags/mexico.txt (renamed from Docs/Flags/kroatia.eps)0
-rw-r--r--Docs/Flags/netherlands.eps143
-rw-r--r--Docs/Flags/netherlands.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/netherlands.pdfbin0 -> 824 bytes
-rw-r--r--Docs/Flags/new-zealand.eps98
-rw-r--r--Docs/Flags/new-zealand.gifbin0 -> 661 bytes
-rw-r--r--Docs/Flags/new-zealand.pdfbin0 -> 1331 bytes
-rw-r--r--Docs/Flags/new-zealand.txt (renamed from Docs/Flags/kroatia.gif)0
-rwxr-xr-xDocs/Flags/norway.eps98
-rwxr-xr-xDocs/Flags/norway.gifbin0 -> 159 bytes
-rw-r--r--Docs/Flags/norway.pdfbin0 -> 864 bytes
-rw-r--r--Docs/Flags/norway.txt (renamed from Docs/Flags/kroatia.txt)0
-rw-r--r--Docs/Flags/philippines.eps98
-rw-r--r--Docs/Flags/philippines.gifbin0 -> 620 bytes
-rw-r--r--Docs/Flags/philippines.pdfbin0 -> 1197 bytes
-rw-r--r--Docs/Flags/philippines.txt (renamed from Docs/Flags/south-africa1.txt)0
-rw-r--r--Docs/Flags/poland.eps115
-rw-r--r--Docs/Flags/poland.gifbin132 -> 113 bytes
-rw-r--r--Docs/Flags/poland.pdfbin0 -> 809 bytes
-rw-r--r--Docs/Flags/portugal.eps147
-rw-r--r--Docs/Flags/portugal.gifbin633 -> 628 bytes
-rw-r--r--Docs/Flags/portugal.pdfbin0 -> 1189 bytes
-rw-r--r--Docs/Flags/romania.eps149
-rw-r--r--Docs/Flags/romania.gifbin158 -> 158 bytes
-rw-r--r--Docs/Flags/romania.pdfbin0 -> 798 bytes
-rw-r--r--Docs/Flags/russia.eps143
-rw-r--r--Docs/Flags/russia.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/russia.pdfbin0 -> 829 bytes
-rw-r--r--Docs/Flags/singapore.eps149
-rw-r--r--Docs/Flags/singapore.gifbin389 -> 377 bytes
-rw-r--r--Docs/Flags/singapore.pdfbin0 -> 1056 bytes
-rwxr-xr-xDocs/Flags/slovenia.eps98
-rw-r--r--Docs/Flags/slovenia.gifbin0 -> 609 bytes
-rw-r--r--Docs/Flags/slovenia.pdfbin0 -> 1133 bytes
-rwxr-xr-x[-rw-r--r--]Docs/Flags/slovenia.txt (renamed from mit-pthreads/machdep/linux-2.0/extra/bits/pthreadtypes.h)0
-rw-r--r--Docs/Flags/south-africa.eps141
-rw-r--r--Docs/Flags/south-africa.gifbin650 -> 415 bytes
-rw-r--r--Docs/Flags/south-africa.pdfbin0 -> 1151 bytes
-rw-r--r--Docs/Flags/south-africa1.eps87
-rw-r--r--Docs/Flags/south-africa1.gifbin650 -> 0 bytes
-rw-r--r--Docs/Flags/south-korea.eps149
-rw-r--r--Docs/Flags/south-korea.gifbin663 -> 669 bytes
-rw-r--r--Docs/Flags/south-korea.pdfbin0 -> 1444 bytes
-rw-r--r--Docs/Flags/spain.eps111
-rw-r--r--Docs/Flags/spain.gifbin138 -> 132 bytes
-rw-r--r--Docs/Flags/spain.pdfbin0 -> 809 bytes
-rw-r--r--Docs/Flags/sweden.eps145
-rw-r--r--Docs/Flags/sweden.gifbin193 -> 131 bytes
-rw-r--r--Docs/Flags/sweden.pdfbin0 -> 837 bytes
-rw-r--r--Docs/Flags/switzerland.eps121
-rw-r--r--Docs/Flags/switzerland.gifbin237 -> 135 bytes
-rw-r--r--Docs/Flags/switzerland.pdfbin0 -> 844 bytes
-rw-r--r--Docs/Flags/taiwan.eps115
-rw-r--r--Docs/Flags/taiwan.gifbin377 -> 371 bytes
-rw-r--r--Docs/Flags/taiwan.pdfbin0 -> 1050 bytes
-rw-r--r--Docs/Flags/turkey.eps98
-rw-r--r--Docs/Flags/turkey.gifbin0 -> 344 bytes
-rw-r--r--Docs/Flags/turkey.pdfbin0 -> 987 bytes
-rw-r--r--Docs/Flags/turkey.txt (renamed from mit-pthreads/machdep/linux-2.0/socketcall.h)0
-rw-r--r--Docs/Flags/ukraine.eps133
-rw-r--r--Docs/Flags/ukraine.gifbin132 -> 113 bytes
-rw-r--r--Docs/Flags/ukraine.pdfbin0 -> 810 bytes
-rw-r--r--Docs/Flags/usa.eps145
-rw-r--r--Docs/Flags/usa.gifbin731 -> 717 bytes
-rw-r--r--Docs/Flags/usa.pdfbin0 -> 1444 bytes
-rw-r--r--Docs/Flags/yugoslavia.eps98
-rw-r--r--Docs/Flags/yugoslavia.gifbin250 -> 141 bytes
-rw-r--r--Docs/Flags/yugoslavia.pdfbin0 -> 829 bytes
-rw-r--r--Docs/Makefile.am177
-rw-r--r--Docs/ManualStyleGuidelines.wiki282
-rwxr-xr-xDocs/Support/colspec-fix.pl78
-rwxr-xr-xDocs/Support/docbook-fixup.pl200
-rwxr-xr-xDocs/Support/docbook-prefix.pl50
-rwxr-xr-xDocs/Support/docbook-split70
-rwxr-xr-xDocs/Support/generate-flag-images46
-rwxr-xr-xDocs/Support/make-docbook29
-rwxr-xr-xDocs/Support/test-make-manual-de137
-rw-r--r--Docs/Support/trivial-makeinfo-4.0c.patch11
-rwxr-xr-xDocs/Support/update-reserved-words.pl98
-rwxr-xr-xDocs/Support/xwf67
-rw-r--r--Docs/bk.txt3
-rw-r--r--Docs/internals.texi730
-rw-r--r--Docs/manual.de.texi56165
-rw-r--r--Docs/manual.ja.texi4
-rw-r--r--Docs/manual.texi26714
-rw-r--r--Docs/mirrors.texi446
-rw-r--r--Docs/my_sys.txt140
-rw-r--r--Docs/mysqld_error.txt106
-rw-r--r--Docs/section.Infolinks.texi880
-rw-r--r--Docs/section.Testimonials.texi31
-rw-r--r--Docs/section.Users.texi414
-rw-r--r--Docs/template.texi522
-rw-r--r--Docs/world.sql5386
-rw-r--r--Makefile.am29
-rw-r--r--README18
-rw-r--r--SSL/NOTES376
-rw-r--r--SSL/cacert.pem21
-rw-r--r--SSL/client-cert.pem67
-rw-r--r--SSL/client-key.pem15
-rw-r--r--SSL/client-req.pem30
-rwxr-xr-xSSL/run-client10
-rwxr-xr-xSSL/run-server9
-rw-r--r--SSL/server-cert.pem67
-rw-r--r--SSL/server-key.pem15
-rw-r--r--SSL/server-req.pem30
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.dbgbin0 -> 28458 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.inobin0 -> 58611 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.insbin0 -> 57122 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.obsbin0 -> 65611 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.rul640
-rw-r--r--VC++Files/bdb/bdb.dsp707
-rw-r--r--VC++Files/client/mysql.dsp101
-rw-r--r--VC++Files/client/mysqladmin.dsp91
-rw-r--r--VC++Files/client/mysqlclient.dsp510
-rw-r--r--VC++Files/client/mysqlclient.dsw29
-rw-r--r--VC++Files/client/mysqldump.dsp101
-rw-r--r--VC++Files/client/mysqlimport.dsp92
-rw-r--r--VC++Files/client/mysqlshow.dsp91
-rw-r--r--VC++Files/dbug/dbug.dsp98
-rw-r--r--VC++Files/dbug/dbug.dsw29
-rw-r--r--VC++Files/heap/heap.dsp195
-rw-r--r--VC++Files/innobase/innobase.dsp466
-rw-r--r--VC++Files/isam/isam.dsp206
-rw-r--r--VC++Files/isam/isam.dsw29
-rw-r--r--VC++Files/isamchk/isamchk.dsp98
-rw-r--r--VC++Files/libmysql/libmySQL.dsp476
-rw-r--r--VC++Files/libmysql/libmysql.dsw29
-rw-r--r--VC++Files/libmysqld/examples/test_libmysqld.dsp66
-rw-r--r--VC++Files/libmysqld/libmysqld.dsp405
-rw-r--r--VC++Files/libmysqltest/myTest.dsp91
-rw-r--r--VC++Files/libmysqltest/mytest.c170
-rw-r--r--VC++Files/libmysqltest/mytest.dsw29
-rw-r--r--VC++Files/merge/merge.dsp134
-rw-r--r--VC++Files/merge/merge.dsw29
-rw-r--r--VC++Files/myisam/myisam.dsp284
-rw-r--r--VC++Files/myisamchk/myisamchk.dsp104
-rw-r--r--VC++Files/myisamlog/myisamlog.dsp105
-rw-r--r--VC++Files/myisammrg/myisammrg.dsp173
-rw-r--r--VC++Files/myisampack/myisampack.dsp107
-rw-r--r--VC++Files/mysql.dsp80
-rw-r--r--VC++Files/mysql.dsw782
-rw-r--r--VC++Files/mysqlbinlog/mysqlbinlog.dsp103
-rw-r--r--VC++Files/mysqlcheck/mysqlcheck.dsp102
-rw-r--r--VC++Files/mysqldemb/mysqldemb.dsp392
-rw-r--r--VC++Files/mysqlmanager/MySqlManager.dsp252
-rw-r--r--VC++Files/mysqlmanager/mysqlmanager.dsw29
-rw-r--r--VC++Files/mysqlserver/mysqlserver.dsp84
-rw-r--r--VC++Files/mysqlshutdown/myshutdown.dsp101
-rw-r--r--VC++Files/mysqlshutdown/mysqlshutdown.c198
-rw-r--r--VC++Files/mysqlshutdown/mysqlshutdown.dsp119
-rw-r--r--VC++Files/mysqlwatch/mysqlwatch.c745
-rw-r--r--VC++Files/mysqlwatch/mysqlwatch.dsp70
-rw-r--r--VC++Files/mysys/mysys.dsp518
-rw-r--r--VC++Files/mysys/mysys.dsw29
-rw-r--r--VC++Files/pack_isam/pack_isam.dsp102
-rw-r--r--VC++Files/perror/perror.dsp109
-rw-r--r--VC++Files/regex/regex.dsp114
-rw-r--r--VC++Files/regex/regex.dsw29
-rw-r--r--VC++Files/replace/replace.dsp92
-rw-r--r--VC++Files/sql/mysqld.dsp1280
-rw-r--r--VC++Files/sql/mysqldmax.dsp1003
-rw-r--r--VC++Files/sql/old/mysqld.dsw29
-rw-r--r--VC++Files/strings/backup/strings.dsp244
-rw-r--r--VC++Files/strings/backup/strings.dsw29
-rw-r--r--VC++Files/strings/noMASM/strings.dsp246
-rw-r--r--VC++Files/strings/strings.dsp248
-rw-r--r--VC++Files/test1/test1.dsp101
-rw-r--r--VC++Files/thr_insert_test/thr_insert_test.dsp109
-rw-r--r--VC++Files/thr_test/thr_test.dsp103
-rw-r--r--VC++Files/vio/vio.dsp108
-rw-r--r--VC++Files/winmysqladmin/db.cpp80
-rw-r--r--VC++Files/winmysqladmin/db.h32
-rw-r--r--VC++Files/winmysqladmin/images/Goahead.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/HELP.ICObin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/INFO.ICObin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Info.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/images/MYINI.ICObin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Myini.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Noentry.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/SETUP.BMPbin0 -> 86878 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Setup 16.bmpbin0 -> 86880 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Table.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Working.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/database.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/winmysqladmin/images/find.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/green.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/help.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/images/initsetup.cpp42
-rw-r--r--VC++Files/winmysqladmin/images/killdb.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/winmysqladmin/images/logo.icobin0 -> 2022 bytes
-rw-r--r--VC++Files/winmysqladmin/images/multitrg.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/mysql-07.bmpbin0 -> 9618 bytes
-rw-r--r--VC++Files/winmysqladmin/images/mysql-17.bmpbin0 -> 3806 bytes
-rw-r--r--VC++Files/winmysqladmin/images/mysql.BMPbin0 -> 8760 bytes
-rw-r--r--VC++Files/winmysqladmin/images/red.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/red22.BMPbin0 -> 2104 bytes
-rw-r--r--VC++Files/winmysqladmin/images/see.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/initsetup.cpp40
-rw-r--r--VC++Files/winmysqladmin/initsetup.h38
-rw-r--r--VC++Files/winmysqladmin/main.cpp2529
-rw-r--r--VC++Files/winmysqladmin/main.h314
-rw-r--r--VC++Files/winmysqladmin/mysql.h293
-rw-r--r--VC++Files/winmysqladmin/mysql_com.h242
-rw-r--r--VC++Files/winmysqladmin/mysql_version.h20
-rw-r--r--VC++Files/winmysqladmin/winmysqladmin.cpp38
-rw-r--r--VC++Files/zlib/contrib/asm386/zlibvc.dsp651
-rw-r--r--VC++Files/zlib/contrib/asm386/zlibvc.dsw41
-rw-r--r--VC++Files/zlib/zlib.dsp185
-rw-r--r--acconfig.h18
-rw-r--r--acinclude.m4258
-rw-r--r--bdb/include/btree_ext.h122
-rw-r--r--bdb/include/clib_ext.h38
-rw-r--r--bdb/include/common_ext.h44
-rw-r--r--bdb/include/env_ext.h35
-rw-r--r--bdb/include/hash_ext.h106
-rw-r--r--bdb/include/lock_ext.h39
-rw-r--r--bdb/include/log_ext.h33
-rw-r--r--bdb/include/mp_ext.h33
-rw-r--r--bdb/include/os_ext.h62
-rw-r--r--bdb/include/qam_ext.h56
-rw-r--r--bdb/include/tcl_ext.h89
-rw-r--r--bdb/include/txn_ext.h24
-rw-r--r--bdb/include/xa_ext.h17
-rwxr-xr-xbuild-tags11
-rw-r--r--client/Makefile.am6
-rw-r--r--client/client_priv.h19
-rw-r--r--client/completion_hash.cc75
-rw-r--r--client/completion_hash.h33
-rw-r--r--client/connect_test.c29
-rw-r--r--client/errmsg.c53
-rw-r--r--client/get_password.c57
-rw-r--r--client/insert_test.c37
-rw-r--r--client/list_test.c42
-rw-r--r--client/my_readline.h29
-rw-r--r--client/mysql.cc1342
-rw-r--r--client/mysqladmin.c373
-rw-r--r--client/mysqlbinlog.cc398
-rw-r--r--client/mysqlcheck.c390
-rw-r--r--client/mysqldump.c623
-rw-r--r--client/mysqlimport.c301
-rw-r--r--client/mysqlmanager-pwgen.c161
-rw-r--r--client/mysqlmanagerc.c174
-rw-r--r--client/mysqlshow.c227
-rw-r--r--client/mysqltest.c1274
-rw-r--r--client/password.c31
-rw-r--r--client/readline.cc50
-rw-r--r--client/select_test.c28
-rw-r--r--client/showdb_test.c22
-rw-r--r--client/sql_string.cc31
-rw-r--r--client/sql_string.h29
-rw-r--r--client/ssl_test.c22
-rw-r--r--client/thimble.cc20
-rw-r--r--client/thread_test.c201
-rw-r--r--client/violite.c394
-rwxr-xr-xconfig.guess9
-rwxr-xr-xconfig.sub16
-rw-r--r--configure.in238
-rw-r--r--dbug/dbug.c37
-rw-r--r--dbug/dbug_analyze.c2
-rw-r--r--dbug/example1.c2
-rw-r--r--dbug/example2.c2
-rw-r--r--dbug/example3.c2
-rw-r--r--dbug/factorial.c2
-rw-r--r--dbug/main.c2
-rw-r--r--dbug/sanity.c2
-rw-r--r--div/deadlock_test.c16
-rw-r--r--extra/Makefile.am2
-rw-r--r--extra/comp_err.c31
-rw-r--r--extra/my_print_defaults.c125
-rw-r--r--extra/mysql_install.c218
-rw-r--r--extra/perror.c139
-rw-r--r--extra/replace.c31
-rw-r--r--extra/resolve_stack_dump.c252
-rw-r--r--extra/resolveip.c71
-rw-r--r--fs/CorbaFS.idl38
-rw-r--r--fs/Makefile.am93
-rw-r--r--fs/README58
-rwxr-xr-xfs/RunServer.sh2
-rw-r--r--fs/database.c628
-rw-r--r--fs/dump.sql28
-rw-r--r--fs/korbit-kernel-2.4.1-patch35661
-rw-r--r--fs/libmysqlfs.c151
-rw-r--r--fs/libmysqlfs.h81
-rw-r--r--fs/my.cnf5
-rw-r--r--fs/mysqlcorbafs.c998
-rw-r--r--fs/mysqlcorbafs.h157
-rw-r--r--fs/mysqlcorbafs_test.c92
-rwxr-xr-xfs/mysqlfsck11
-rw-r--r--heap/_check.c12
-rw-r--r--heap/_rectest.c6
-rw-r--r--heap/heapdef.h7
-rw-r--r--heap/hp_block.c6
-rw-r--r--heap/hp_clear.c8
-rw-r--r--heap/hp_close.c12
-rw-r--r--heap/hp_create.c44
-rw-r--r--heap/hp_delete.c12
-rw-r--r--heap/hp_extra.c6
-rw-r--r--heap/hp_hash.c94
-rw-r--r--heap/hp_info.c6
-rw-r--r--heap/hp_open.c11
-rw-r--r--heap/hp_panic.c6
-rw-r--r--heap/hp_rename.c6
-rw-r--r--heap/hp_rfirst.c6
-rw-r--r--heap/hp_rkey.c8
-rw-r--r--heap/hp_rlast.c6
-rw-r--r--heap/hp_rnext.c8
-rw-r--r--heap/hp_rprev.c6
-rw-r--r--heap/hp_rrnd.c6
-rw-r--r--heap/hp_rsame.c6
-rw-r--r--heap/hp_scan.c6
-rw-r--r--heap/hp_static.c6
-rw-r--r--heap/hp_test1.c8
-rw-r--r--heap/hp_test2.c47
-rw-r--r--heap/hp_update.c6
-rw-r--r--heap/hp_write.c13
-rw-r--r--include/Makefile.am26
-rw-r--r--include/config-os2.h56
-rw-r--r--include/config-win.h101
-rw-r--r--include/dbug.h29
-rw-r--r--include/errmsg.h34
-rw-r--r--include/ft_global.h41
-rw-r--r--include/getopt.h135
-rw-r--r--include/global.h968
-rw-r--r--include/hash.h30
-rw-r--r--include/heap.h36
-rw-r--r--include/m_ctype.h95
-rw-r--r--include/m_string.h32
-rw-r--r--include/md5.h93
-rw-r--r--include/merge.h29
-rw-r--r--include/my_aes.h66
-rw-r--r--include/my_alarm.h29
-rw-r--r--include/my_alloc.h51
-rw-r--r--include/my_base.h69
-rw-r--r--include/my_bitmap.h29
-rw-r--r--include/my_dir.h29
-rw-r--r--include/my_getopt.h54
-rw-r--r--include/my_global.h1037
-rw-r--r--include/my_list.h29
-rw-r--r--include/my_net.h84
-rw-r--r--include/my_no_pthread.h29
-rw-r--r--include/my_nosys.h29
-rw-r--r--include/my_pthread.h72
-rw-r--r--include/my_semaphore.h61
-rw-r--r--include/my_sys.h331
-rw-r--r--include/my_tree.h50
-rw-r--r--include/myisam.h229
-rw-r--r--include/myisammrg.h47
-rw-r--r--include/myisampack.h29
-rw-r--r--include/mysql.h307
-rw-r--r--include/mysql_com.h98
-rw-r--r--include/mysql_embed.h34
-rw-r--r--include/mysql_version.h.in7
-rw-r--r--include/mysqld_error.h20
-rw-r--r--include/mysys_err.h45
-rw-r--r--include/nisam.h29
-rw-r--r--include/queues.h30
-rw-r--r--include/raid.h34
-rw-r--r--include/rijndael.h42
-rw-r--r--include/sha1.h67
-rw-r--r--include/sslopt-case.h42
-rw-r--r--include/sslopt-longopts.h60
-rw-r--r--include/sslopt-usage.h32
-rw-r--r--include/sslopt-vars.h30
-rw-r--r--include/t_ctype.h20
-rw-r--r--include/thr_alarm.h58
-rw-r--r--include/thr_lock.h31
-rw-r--r--include/violite.h211
-rw-r--r--innobase/btr/btr0btr.c8
-rw-r--r--innobase/btr/btr0cur.c17
-rw-r--r--innobase/btr/btr0sea.c2
-rw-r--r--innobase/buf/buf0buf.c2
-rw-r--r--innobase/buf/buf0lru.c9
-rw-r--r--innobase/configure.in1
-rw-r--r--innobase/data/data0data.c2
-rw-r--r--innobase/dict/dict0boot.c109
-rw-r--r--innobase/dict/dict0crea.c20
-rw-r--r--innobase/dict/dict0dict.c41
-rw-r--r--innobase/dict/dict0load.c32
-rw-r--r--innobase/eval/eval0eval.c8
-rw-r--r--innobase/fil/fil0fil.c11
-rw-r--r--innobase/fsp/fsp0fsp.c8
-rw-r--r--innobase/ibuf/ibuf0ibuf.c20
-rw-r--r--innobase/include/Makefile.am2
-rw-r--r--innobase/include/Makefile.i2
-rw-r--r--innobase/include/btr0btr.ic6
-rw-r--r--innobase/include/buf0buf.ic7
-rw-r--r--innobase/include/dict0dict.ic2
-rw-r--r--innobase/include/dyn0dyn.h7
-rw-r--r--innobase/include/ha0ha.ic2
-rw-r--r--innobase/include/row0mysql.ic3
-rw-r--r--innobase/include/row0vers.ic2
-rw-r--r--innobase/include/srv0srv.h1
-rw-r--r--innobase/include/sync0rw.ic3
-rw-r--r--innobase/include/univ.i2
-rw-r--r--innobase/include/ut0mem.h2
-rw-r--r--innobase/include/ut0mem.ic2
-rw-r--r--innobase/lock/lock0lock.c7
-rw-r--r--innobase/log/log0log.c17
-rw-r--r--innobase/mem/mem0dbg.c6
-rw-r--r--innobase/mtr/mtr0mtr.c8
-rw-r--r--innobase/odbc/odbc0odbc.c2
-rw-r--r--innobase/os/os0file.c33
-rw-r--r--innobase/os/os0thread.c6
-rw-r--r--innobase/page/page0cur.c9
-rw-r--r--innobase/page/page0page.c6
-rw-r--r--innobase/pars/pars0opt.c6
-rw-r--r--innobase/pars/pars0pars.c2
-rw-r--r--innobase/que/que0que.c46
-rw-r--r--innobase/rem/rem0cmp.c2
-rw-r--r--innobase/rem/rem0rec.c4
-rw-r--r--innobase/row/row0ins.c4
-rw-r--r--innobase/row/row0mysql.c97
-rw-r--r--innobase/row/row0purge.c2
-rw-r--r--innobase/row/row0sel.c21
-rw-r--r--innobase/row/row0uins.c2
-rw-r--r--innobase/row/row0umod.c2
-rw-r--r--innobase/row/row0upd.c2
-rw-r--r--innobase/srv/srv0srv.c18
-rw-r--r--innobase/srv/srv0start.c12
-rw-r--r--innobase/sync/sync0arr.c2
-rw-r--r--innobase/sync/sync0rw.c6
-rw-r--r--innobase/sync/sync0sync.c2
-rw-r--r--innobase/trx/trx0purge.c6
-rw-r--r--innobase/trx/trx0rec.c5
-rw-r--r--innobase/trx/trx0roll.c10
-rw-r--r--innobase/trx/trx0trx.c10
-rw-r--r--innobase/trx/trx0undo.c8
-rw-r--r--innobase/ut/ut0ut.c8
-rw-r--r--isam/_cache.c20
-rw-r--r--isam/_dbug.c6
-rw-r--r--isam/_dynrec.c26
-rw-r--r--isam/_key.c6
-rw-r--r--isam/_locking.c8
-rw-r--r--isam/_packrec.c12
-rw-r--r--isam/_page.c6
-rw-r--r--isam/_search.c6
-rw-r--r--isam/_statrec.c8
-rw-r--r--isam/changed.c6
-rw-r--r--isam/close.c6
-rw-r--r--isam/create.c14
-rw-r--r--isam/delete.c8
-rw-r--r--isam/extra.c7
-rw-r--r--isam/info.c6
-rw-r--r--isam/isamchk.c392
-rw-r--r--isam/isamdef.h6
-rw-r--r--isam/isamlog.c12
-rw-r--r--isam/log.c6
-rw-r--r--isam/open.c6
-rw-r--r--isam/pack_isam.c217
-rw-r--r--isam/panic.c6
-rw-r--r--isam/range.c6
-rw-r--r--isam/rfirst.c6
-rw-r--r--isam/rkey.c6
-rw-r--r--isam/rlast.c6
-rw-r--r--isam/rnext.c6
-rw-r--r--isam/rprev.c6
-rw-r--r--isam/rrnd.c6
-rw-r--r--isam/rsame.c6
-rw-r--r--isam/rsamepos.c6
-rw-r--r--isam/sort.c6
-rw-r--r--isam/static.c8
-rw-r--r--isam/test1.c8
-rw-r--r--isam/test2.c18
-rw-r--r--isam/test3.c12
-rw-r--r--isam/update.c6
-rw-r--r--isam/write.c8
-rw-r--r--libmysql/Makefile.am29
-rw-r--r--libmysql/Makefile.shared26
-rw-r--r--libmysql/conf_to_src.c29
-rw-r--r--libmysql/dll.c31
-rw-r--r--libmysql/errmsg.c54
-rw-r--r--libmysql/get_password.c31
-rw-r--r--libmysql/libmysql.c888
-rw-r--r--libmysql/libmysql.def122
-rw-r--r--libmysql/manager.c263
-rw-r--r--libmysql/net.c685
-rw-r--r--libmysql/password.c31
-rw-r--r--libmysql/violite.c443
-rw-r--r--libmysql_r/Makefile.am2
-rw-r--r--libmysqld/Makefile.am135
-rw-r--r--libmysqld/copyright14
-rw-r--r--libmysqld/embedded_priv.h31
-rw-r--r--libmysqld/examples/Makefile.am26
-rwxr-xr-xlibmysqld/examples/test-run138
-rw-r--r--libmysqld/lib_load.cc44
-rw-r--r--libmysqld/lib_sql.cc601
-rw-r--r--libmysqld/lib_vio.c222
-rw-r--r--libmysqld/libmysqld.c2092
-rw-r--r--libmysqld/libmysqld.def65
-rwxr-xr-xltconfig4
-rw-r--r--man/Makefile.am2
-rw-r--r--[-rwxr-xr-x]man/isamchk.12
-rw-r--r--man/isamlog.12
-rw-r--r--man/mysql.14
-rw-r--r--man/mysql_zap.12
-rw-r--r--[-rwxr-xr-x]man/mysqlaccess.12
-rw-r--r--[-rwxr-xr-x]man/mysqladmin.12
-rw-r--r--[-rwxr-xr-x]man/mysqld.14
-rw-r--r--man/mysqld_multi.14
-rw-r--r--man/mysqld_safe.186
-rw-r--r--[-rwxr-xr-x]man/mysqldump.12
-rw-r--r--[-rwxr-xr-x]man/mysqlshow.12
-rw-r--r--[-rwxr-xr-x]man/perror.12
-rw-r--r--man/replace.12
-rwxr-xr-xman/safe_mysqld.188
-rw-r--r--man/which.22
-rw-r--r--merge/Makefile.am8
-rw-r--r--merge/_locking.c33
-rw-r--r--merge/close.c40
-rw-r--r--merge/create.c61
-rw-r--r--merge/delete.c29
-rw-r--r--merge/extra.c46
-rw-r--r--merge/info.c60
-rw-r--r--merge/mrg_close.c40
-rw-r--r--merge/mrg_create.c61
-rw-r--r--merge/mrg_def.h29
-rw-r--r--merge/mrg_delete.c29
-rw-r--r--merge/mrg_extra.c46
-rw-r--r--merge/mrg_info.c60
-rw-r--r--merge/mrg_locking.c33
-rw-r--r--merge/mrg_open.c150
-rw-r--r--merge/mrg_panic.c47
-rw-r--r--merge/mrg_rrnd.c110
-rw-r--r--merge/mrg_rsame.c36
-rw-r--r--merge/mrg_static.c26
-rw-r--r--merge/mrg_update.c31
-rw-r--r--merge/mrgdef.h29
-rw-r--r--merge/open.c144
-rw-r--r--merge/panic.c47
-rw-r--r--merge/rrnd.c110
-rw-r--r--merge/rsame.c36
-rw-r--r--merge/static.c26
-rw-r--r--merge/update.c31
-rw-r--r--mit-pthreads/.cvsignore6
-rw-r--r--mit-pthreads/COPYRIGHT31
-rw-r--r--mit-pthreads/Changes-mysql237
-rw-r--r--mit-pthreads/FAQ122
-rw-r--r--mit-pthreads/GNUmakefile129
-rw-r--r--mit-pthreads/NOTES59
-rw-r--r--mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE9745
-rw-r--r--mit-pthreads/README40
-rw-r--r--mit-pthreads/TODO-mysql4
-rw-r--r--mit-pthreads/Whats_New198
-rw-r--r--mit-pthreads/bin/.cvsignore1
-rw-r--r--mit-pthreads/bin/Makefile.in48
-rw-r--r--mit-pthreads/bin/finger/.cvsignore1
-rwxr-xr-xmit-pthreads/bin/finger/Makefile.in60
-rwxr-xr-xmit-pthreads/bin/finger/finger.c231
-rwxr-xr-xmit-pthreads/bin/finger/net.c189
-rwxr-xr-xmit-pthreads/config/COPYING.GNU339
-rwxr-xr-xmit-pthreads/config/COPYRIGHT4
-rwxr-xr-xmit-pthreads/config/GNUmakefile.in129
-rw-r--r--mit-pthreads/config/Makefile.in56
-rw-r--r--mit-pthreads/config/acconfig.h73
-rwxr-xr-xmit-pthreads/config/aclocal.m494
-rwxr-xr-xmit-pthreads/config/config.flags.in80
-rwxr-xr-xmit-pthreads/config/config.guess505
-rwxr-xr-xmit-pthreads/config/config.h.in324
-rwxr-xr-xmit-pthreads/config/config.sub794
-rwxr-xr-xmit-pthreads/config/configure3336
-rwxr-xr-xmit-pthreads/config/configure.in745
-rwxr-xr-xmit-pthreads/config/configure.org2874
-rwxr-xr-xmit-pthreads/config/install-sh238
-rwxr-xr-xmit-pthreads/configure18
-rwxr-xr-xmit-pthreads/gen/GNUmakefile.inc9
-rw-r--r--mit-pthreads/gen/Makefile.inc24
-rw-r--r--mit-pthreads/gen/ctime.c1315
-rw-r--r--mit-pthreads/gen/difftime.c46
-rw-r--r--mit-pthreads/gen/directory.c322
-rw-r--r--mit-pthreads/gen/eprintf.c18
-rw-r--r--mit-pthreads/gen/getcwd.c248
-rw-r--r--mit-pthreads/gen/getpwent.c109
-rw-r--r--mit-pthreads/gen/getpwnamuid.c138
-rw-r--r--mit-pthreads/gen/getwd.c57
-rw-r--r--mit-pthreads/gen/isatty.c95
-rw-r--r--mit-pthreads/gen/popen.c117
-rw-r--r--mit-pthreads/gen/pwd_internal.c97
-rw-r--r--mit-pthreads/gen/pwd_internal.h29
-rw-r--r--mit-pthreads/gen/syslog.c216
-rw-r--r--mit-pthreads/gen/time.c51
-rw-r--r--mit-pthreads/gen/ttyname.c147
-rw-r--r--mit-pthreads/include/Makefile.inc30
-rwxr-xr-xmit-pthreads/include/arpa/inet.h61
-rwxr-xr-xmit-pthreads/include/arpa/nameser.h279
-rw-r--r--mit-pthreads/include/dirent.h97
-rw-r--r--mit-pthreads/include/endian.h95
-rw-r--r--mit-pthreads/include/errno.h52
-rw-r--r--mit-pthreads/include/math.h85
-rw-r--r--mit-pthreads/include/netdb.h146
-rw-r--r--mit-pthreads/include/pthread.h371
-rw-r--r--mit-pthreads/include/pthread/ac-types.h10
-rwxr-xr-xmit-pthreads/include/pthread/cleanup.h59
-rwxr-xr-xmit-pthreads/include/pthread/cond.h102
-rw-r--r--mit-pthreads/include/pthread/config.h5
-rwxr-xr-xmit-pthreads/include/pthread/debug_out.h44
-rwxr-xr-xmit-pthreads/include/pthread/fd.h122
-rwxr-xr-xmit-pthreads/include/pthread/fd_pipe.h54
-rwxr-xr-xmit-pthreads/include/pthread/kernel.h71
-rwxr-xr-xmit-pthreads/include/pthread/kthread.h67
-rwxr-xr-xmit-pthreads/include/pthread/mutex.h102
-rw-r--r--mit-pthreads/include/pthread/paths.h12
-rwxr-xr-xmit-pthreads/include/pthread/prio_queue.h78
-rwxr-xr-xmit-pthreads/include/pthread/pthread_attr.h122
-rwxr-xr-xmit-pthreads/include/pthread/pthread_once.h58
-rwxr-xr-xmit-pthreads/include/pthread/queue.h67
-rwxr-xr-xmit-pthreads/include/pthread/sleep.h63
-rwxr-xr-xmit-pthreads/include/pthread/specific.h66
-rwxr-xr-xmit-pthreads/include/pthread/state.def64
-rwxr-xr-xmit-pthreads/include/pthread/types.h46
-rwxr-xr-xmit-pthreads/include/pthread/unistd.h159
-rwxr-xr-xmit-pthreads/include/pthread/util.h89
-rwxr-xr-xmit-pthreads/include/pthread/version.h43
-rwxr-xr-xmit-pthreads/include/pthread/xtypes.h13
-rw-r--r--mit-pthreads/include/pwd.h93
-rw-r--r--mit-pthreads/include/resolv.h179
-rw-r--r--mit-pthreads/include/sched.h57
-rw-r--r--mit-pthreads/include/signal.h81
-rw-r--r--mit-pthreads/include/stdio.h371
-rw-r--r--mit-pthreads/include/stdlib.h127
-rw-r--r--mit-pthreads/include/string.h85
-rw-r--r--mit-pthreads/include/syslog.h101
-rw-r--r--mit-pthreads/include/time.h102
-rw-r--r--mit-pthreads/include/timers.h45
-rw-r--r--mit-pthreads/include/tzfile.h154
-rw-r--r--mit-pthreads/include/unistd.h183
-rw-r--r--mit-pthreads/lib/.cvsignore1
-rw-r--r--mit-pthreads/lib/Makefile.in48
-rw-r--r--mit-pthreads/lib/libpthreadutil/.cvsignore1
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/Makefile.in65
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/pthread_atexit.c135
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/pthread_tad.c170
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/pthreadutil.h75
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__math.h16
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__signal.h106
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__stdio.h13
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__stdlib.h3
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__string.h19
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__time.h21
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__unistd.h6
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/cdefs.h62
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/compat.h1
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/dirent.h7
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/signal.h3
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/socket.h296
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/timers.h60
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/uio.h12
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/compat.h43
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/dirent.h73
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/errno.h160
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/socket.h277
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/timers.h59
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__path.h13
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__signal.h7
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__stdio.h7
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__stdlib.h60
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__string.h19
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__time.h63
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__unistd.h109
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/compat.h65
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/dirent.h65
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/errno.h162
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/time.h6
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/wait.h159
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.1.c196
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.1.h111
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.3.c204
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.3.h114
-rw-r--r--mit-pthreads/machdep/engine-alpha-osf1.c207
-rw-r--r--mit-pthreads/machdep/engine-alpha-osf1.h110
-rw-r--r--mit-pthreads/machdep/engine-arm32-netbsd-1.3.c203
-rw-r--r--mit-pthreads/machdep/engine-arm32-netbsd-1.3.h102
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-10.20.c169
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-10.20.h143
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-9.03.c153
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-9.03.h141
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-1.1.c180
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-1.1.h84
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-2.0.c210
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-2.0.h98
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-1.1.c179
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-1.1.h83
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-2.0.c208
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-2.0.h97
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-1.0.c503
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-1.0.h98
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-2.0.c504
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-2.0.h99
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-0.9.c155
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-0.9.h83
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.0.c218
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.0.h97
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.3.c225
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.3.h98
-rw-r--r--mit-pthreads/machdep/engine-i386-openbsd-2.0.c215
-rw-r--r--mit-pthreads/machdep/engine-i386-openbsd-2.0.h97
-rwxr-xr-xmit-pthreads/machdep/engine-i386-sco-3.2v5.c1072
-rw-r--r--mit-pthreads/machdep/engine-i386-sco-3.2v5.h104
-rw-r--r--mit-pthreads/machdep/engine-ip22-irix-5.2.c225
-rw-r--r--mit-pthreads/machdep/engine-ip22-irix-5.2.h108
-rw-r--r--mit-pthreads/machdep/engine-m68000-netbsd.c256
-rw-r--r--mit-pthreads/machdep/engine-m68000-netbsd.h107
-rw-r--r--mit-pthreads/machdep/engine-powerpc-netbsd.c227
-rw-r--r--mit-pthreads/machdep/engine-powerpc-netbsd.h109
-rw-r--r--mit-pthreads/machdep/engine-r2000-ultrix-4.2.c209
-rw-r--r--mit-pthreads/machdep/engine-r2000-ultrix-4.2.h107
-rw-r--r--mit-pthreads/machdep/engine-romp-bsd.c99
-rw-r--r--mit-pthreads/machdep/engine-romp-bsd.h100
-rw-r--r--mit-pthreads/machdep/engine-sparc-netbsd-1.3.c232
-rw-r--r--mit-pthreads/machdep/engine-sparc-netbsd-1.3.h106
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c227
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h105
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-5.3.c308
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-5.3.h129
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/compat.h43
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/socket.h267
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/timers.h68
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__signal.h8
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__stdlib.h66
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__string.h21
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__time.h70
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__unistd.h113
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/compat.h43
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/errno.h160
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/wait.h162
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__math.h3
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__signal.h28
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__stdio.h11
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__stdlib.h24
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__string.h20
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__time.h31
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__unistd.h68
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/cdefs.h67
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/compat.h45
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/dirent.h61
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/socket.h171
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/stdtypes.h74
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/time.h228
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/timers.h71
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/uio.h25
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/wait.h92
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__math.h3
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__signal.h28
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__stdlib.h24
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__string.h20
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__time.h31
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__unistd.h66
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/cdefs.h61
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/compat.h45
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/dirent.h61
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/socket.h171
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/stdtypes.h74
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/time.h228
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/timers.h68
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/uio.h25
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/wait.h92
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__math.h4
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__signal.h15
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__stdio.h6
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__stdlib.h30
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__string.h5
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__time.h21
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__unistd.h8
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/compat.h45
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/dirent.h21
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/socket.h304
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/timers.h18
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/wait.h104
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__math.h4
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__signal.h24
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__stdio.h7
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__stdlib.h20
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__string.h18
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__time.h72
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__unistd.h56
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/cdefs.h23
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/compat.h47
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/dirent.h27
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/errno.h12
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/socket.h193
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/timers.h71
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/uio.h15
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/wait.h98
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__math.h4
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__signal.h86
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__stdio.h12
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__stdlib.h20
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__string.h18
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__time.h78
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__unistd.h62
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/cdefs.h36
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/compat.h47
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/dirent.h27
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/errno.h12
-rw-r--r--mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h15
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/extra/bits/socket.h198
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/socket.h13
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/timers.h71
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/uio.h15
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/wait.h98
-rwxr-xr-xmit-pthreads/machdep/netbsd-0.9/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__signal.h8
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__stdlib.h60
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__string.h20
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__time.h69
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__unistd.h107
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/compat.h43
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/errno.h160
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/time.h125
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/wait.h158
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__math.h6
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__path.h14
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__signal.h27
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__stdlib.h60
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__string.h20
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__time.h69
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__unistd.h107
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/compat.h43
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/dirent.h95
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/errno.h170
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/time.h153
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/timers.h45
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/wait.h163
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__signal.h8
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__stdlib.h66
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__string.h21
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__time.h70
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__unistd.h109
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/compat.h43
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/errno.h160
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/wait.h162
-rw-r--r--mit-pthreads/machdep/posix-alpha-osf1.h7
-rw-r--r--mit-pthreads/machdep/posix-bsdi-1.1.h34
-rw-r--r--mit-pthreads/machdep/posix-bsdi-2.0.h34
-rw-r--r--mit-pthreads/machdep/posix-freebsd-1.1.h33
-rw-r--r--mit-pthreads/machdep/posix-freebsd-2.0.h31
-rw-r--r--mit-pthreads/machdep/posix-hpux-10.20.h23
-rw-r--r--mit-pthreads/machdep/posix-hpux-9.03.h23
-rw-r--r--mit-pthreads/machdep/posix-i386-sco-3.2v5.h35
-rw-r--r--mit-pthreads/machdep/posix-irix-5.2.h31
-rw-r--r--mit-pthreads/machdep/posix-linux-1.0.h31
-rw-r--r--mit-pthreads/machdep/posix-linux-2.0.h31
-rw-r--r--mit-pthreads/machdep/posix-netbsd-0.9.h22
-rw-r--r--mit-pthreads/machdep/posix-netbsd-1.0.h31
-rw-r--r--mit-pthreads/machdep/posix-netbsd-1.1.h31
-rw-r--r--mit-pthreads/machdep/posix-openbsd-2.0.h31
-rw-r--r--mit-pthreads/machdep/posix-romp-bsd.h33
-rw-r--r--mit-pthreads/machdep/posix-sco-3.2v5.h35
-rw-r--r--mit-pthreads/machdep/posix-sunos-4.1.3.h27
-rw-r--r--mit-pthreads/machdep/posix-sunos-5.3.h22
-rw-r--r--mit-pthreads/machdep/posix-sunos-5.5.h22
-rw-r--r--mit-pthreads/machdep/posix-ultrix-4.2.h24
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__math.h5
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__path.h12
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__signal.h11
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__stdio.h4
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__stdlib.h28
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__string.h14
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__time.h2
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__unistd.h73
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/cdefs.h61
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/compat.h45
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/fcntlcom.h163
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/signal.h98
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/stat.h94
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/time.h69
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/timers.h68
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/wait.h22
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__math.h16
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__signal.h19
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__stdio.h6
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__stdlib.h27
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__string.h12
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__time.h69
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__unistd.h47
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/cdefs.h59
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/compat.h45
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/socket.h180
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/timers.h72
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/uio.h40
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__math.h16
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__signal.h19
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__stdio.h6
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__stdlib.h27
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__string.h12
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__time.h69
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__unistd.h47
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/cdefs.h59
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/compat.h45
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/socket.h180
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/timers.h70
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/uio.h40
-rw-r--r--mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S206
-rw-r--r--mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S228
-rw-r--r--mit-pthreads/machdep/syscall-alpha-osf1.S97
-rw-r--r--mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S193
-rw-r--r--mit-pthreads/machdep/syscall-hppa-hpux-10.20.S23
-rw-r--r--mit-pthreads/machdep/syscall-hppa-hpux-9.03.S23
-rw-r--r--mit-pthreads/machdep/syscall-i386-bsdi-1.1.S288
-rw-r--r--mit-pthreads/machdep/syscall-i386-bsdi-2.0.S294
-rw-r--r--mit-pthreads/machdep/syscall-i386-freebsd-1.1.S293
-rw-r--r--mit-pthreads/machdep/syscall-i386-freebsd-2.0.S240
-rw-r--r--mit-pthreads/machdep/syscall-i386-linux-1.0.S406
-rw-r--r--mit-pthreads/machdep/syscall-i386-linux-2.0.S389
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-0.9.S229
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-1.0.S158
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-1.1.S181
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-1.3.S200
-rw-r--r--mit-pthreads/machdep/syscall-i386-openbsd-2.0.S237
-rw-r--r--mit-pthreads/machdep/syscall-i386-sco-3.2v5.S442
-rw-r--r--mit-pthreads/machdep/syscall-ip22-irix-5.2.S106
-rw-r--r--mit-pthreads/machdep/syscall-m68000-netbsd.S83
-rw-r--r--mit-pthreads/machdep/syscall-powerpc-netbsd.S185
-rw-r--r--mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S166
-rw-r--r--mit-pthreads/machdep/syscall-romp-bsd.S327
-rw-r--r--mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S102
-rw-r--r--mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S172
-rw-r--r--mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S113
-rw-r--r--mit-pthreads/machdep/syscall-sparc-sunos-5.3.S65
-rw-r--r--mit-pthreads/machdep/syscall-sparc-sunos4.S113
-rw-r--r--mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S46
-rw-r--r--mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S53
-rw-r--r--mit-pthreads/machdep/syscall-template-alpha-osf1.S46
-rw-r--r--mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S55
-rw-r--r--mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S27
-rw-r--r--mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S27
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S48
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S59
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S49
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S56
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S49
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S48
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S67
-rw-r--r--mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S51
-rw-r--r--mit-pthreads/machdep/syscall-template-m68000-netbsd.S43
-rw-r--r--mit-pthreads/machdep/syscall-template-powerpc-netbsd.S45
-rw-r--r--mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S77
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S40
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S48
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S45
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-sunos4.S40
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__math.h2
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__signal.h66
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__stdio.h7
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__stdlib.h21
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__string.h17
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__time.h69
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__unistd.h51
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/cdefs.h66
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/compat.h45
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/dirent.h61
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/errno.h180
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/time.h83
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/timers.h68
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/wait.h121
-rw-r--r--mit-pthreads/machdep/unistd-i386-freebsd-1.1.h178
-rw-r--r--mit-pthreads/machdep/unistd-i386-linux-1.0.h59
-rw-r--r--mit-pthreads/machdep/unistd-i386-linux-2.0.h59
-rw-r--r--mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h215
-rw-r--r--mit-pthreads/net/GNUmakefile.inc14
-rw-r--r--mit-pthreads/net/Makefile.inc13
-rw-r--r--mit-pthreads/net/gethostbyaddr.c161
-rw-r--r--mit-pthreads/net/gethostbyname.c167
-rw-r--r--mit-pthreads/net/gethostent.c162
-rw-r--r--mit-pthreads/net/gethostname.c22
-rw-r--r--mit-pthreads/net/getnetbyaddr.c65
-rw-r--r--mit-pthreads/net/getnetbyname.c72
-rw-r--r--mit-pthreads/net/getnetent.c145
-rw-r--r--mit-pthreads/net/getproto.c65
-rw-r--r--mit-pthreads/net/getprotoent.c143
-rw-r--r--mit-pthreads/net/getprotoname.c73
-rw-r--r--mit-pthreads/net/getservbyname.c76
-rw-r--r--mit-pthreads/net/getservbyport.c68
-rw-r--r--mit-pthreads/net/getservent.c146
-rw-r--r--mit-pthreads/net/herror.c92
-rw-r--r--mit-pthreads/net/inet_addr.c156
-rw-r--r--mit-pthreads/net/inet_lnaof.c61
-rw-r--r--mit-pthreads/net/inet_makeaddr.c64
-rw-r--r--mit-pthreads/net/inet_netof.c60
-rw-r--r--mit-pthreads/net/inet_network.c98
-rw-r--r--mit-pthreads/net/inet_ntoa.c85
-rw-r--r--mit-pthreads/net/net_internal.c78
-rw-r--r--mit-pthreads/net/net_internal.h58
-rw-r--r--mit-pthreads/net/proto_internal.c78
-rw-r--r--mit-pthreads/net/proto_internal.h58
-rw-r--r--mit-pthreads/net/res_comp.c340
-rw-r--r--mit-pthreads/net/res_debug.c749
-rw-r--r--mit-pthreads/net/res_init.c55
-rw-r--r--mit-pthreads/net/res_internal.c576
-rw-r--r--mit-pthreads/net/res_internal.h85
-rw-r--r--mit-pthreads/net/res_mkquery.c212
-rw-r--r--mit-pthreads/net/res_query.c97
-rw-r--r--mit-pthreads/net/res_querydomain.c66
-rw-r--r--mit-pthreads/net/res_search.c168
-rw-r--r--mit-pthreads/net/res_send.c313
-rw-r--r--mit-pthreads/net/serv_internal.c80
-rw-r--r--mit-pthreads/net/serv_internal.h58
-rwxr-xr-xmit-pthreads/patches/Streepy.html2873
-rwxr-xr-xmit-pthreads/patches/Streepy2.html93
-rwxr-xr-xmit-pthreads/patches/bill_lear70
-rwxr-xr-xmit-pthreads/patches/chris_demetriou149
-rwxr-xr-xmit-pthreads/patches/mevans642
-rwxr-xr-xmit-pthreads/patches/p15390
-rwxr-xr-xmit-pthreads/patches/p15596
-rw-r--r--mit-pthreads/pthreads/GNUmakefile.inc46
-rw-r--r--mit-pthreads/pthreads/Makefile.inc75
-rw-r--r--mit-pthreads/pthreads/_exit.c80
-rw-r--r--mit-pthreads/pthreads/cleanup.c84
-rw-r--r--mit-pthreads/pthreads/cond.c437
-rw-r--r--mit-pthreads/pthreads/condattr.c90
-rw-r--r--mit-pthreads/pthreads/dump_state.c88
-rw-r--r--mit-pthreads/pthreads/errno.c53
-rw-r--r--mit-pthreads/pthreads/fd.c1083
-rw-r--r--mit-pthreads/pthreads/fd_kern.c1950
-rw-r--r--mit-pthreads/pthreads/fd_pipe.c257
-rw-r--r--mit-pthreads/pthreads/fd_sysv.c897
-rw-r--r--mit-pthreads/pthreads/file.c129
-rw-r--r--mit-pthreads/pthreads/globals.c85
-rw-r--r--mit-pthreads/pthreads/info.c77
-rw-r--r--mit-pthreads/pthreads/init.cc9
-rw-r--r--mit-pthreads/pthreads/malloc.c383
-rw-r--r--mit-pthreads/pthreads/mutex.c371
-rw-r--r--mit-pthreads/pthreads/mutexattr.c90
-rw-r--r--mit-pthreads/pthreads/panic.c58
-rw-r--r--mit-pthreads/pthreads/prio_queue.c176
-rw-r--r--mit-pthreads/pthreads/process.c208
-rw-r--r--mit-pthreads/pthreads/pthread.c293
-rw-r--r--mit-pthreads/pthreads/pthread_attr.c255
-rw-r--r--mit-pthreads/pthreads/pthread_cancel.c258
-rw-r--r--mit-pthreads/pthreads/pthread_detach.c92
-rw-r--r--mit-pthreads/pthreads/pthread_init.c135
-rw-r--r--mit-pthreads/pthreads/pthread_join.c139
-rw-r--r--mit-pthreads/pthreads/pthread_kill.c93
-rw-r--r--mit-pthreads/pthreads/pthread_once.c59
-rw-r--r--mit-pthreads/pthreads/queue.c143
-rw-r--r--mit-pthreads/pthreads/readv.c85
-rw-r--r--mit-pthreads/pthreads/schedparam.c170
-rw-r--r--mit-pthreads/pthreads/select.c255
-rw-r--r--mit-pthreads/pthreads/sig.c452
-rw-r--r--mit-pthreads/pthreads/signal.c653
-rw-r--r--mit-pthreads/pthreads/sleep.c367
-rw-r--r--mit-pthreads/pthreads/specific.c198
-rw-r--r--mit-pthreads/pthreads/stat.c116
-rw-r--r--mit-pthreads/pthreads/wait.c159
-rw-r--r--mit-pthreads/pthreads/wrapper.c149
-rw-r--r--mit-pthreads/pthreads/writev.c89
-rwxr-xr-xmit-pthreads/scripts/GNUmakefile.inc24
-rw-r--r--mit-pthreads/scripts/Makefile.inc30
-rwxr-xr-xmit-pthreads/scripts/pgcc.sh32
-rwxr-xr-xmit-pthreads/stdio/GNUmakefile.inc26
-rw-r--r--mit-pthreads/stdio/Makefile.inc20
-rwxr-xr-xmit-pthreads/stdio/README41
-rw-r--r--mit-pthreads/stdio/clrerr.c51
-rw-r--r--mit-pthreads/stdio/fclose.c73
-rw-r--r--mit-pthreads/stdio/fdopen.c93
-rw-r--r--mit-pthreads/stdio/feof.c55
-rw-r--r--mit-pthreads/stdio/ferror.c55
-rw-r--r--mit-pthreads/stdio/fflush.c98
-rw-r--r--mit-pthreads/stdio/fgetc.c65
-rw-r--r--mit-pthreads/stdio/fgetline.c170
-rw-r--r--mit-pthreads/stdio/fgetpos.c85
-rw-r--r--mit-pthreads/stdio/fgets.c110
-rw-r--r--mit-pthreads/stdio/fileno.c55
-rw-r--r--mit-pthreads/stdio/findfp.c161
-rw-r--r--mit-pthreads/stdio/flags.c93
-rw-r--r--mit-pthreads/stdio/floatio.h47
-rw-r--r--mit-pthreads/stdio/fopen.c90
-rw-r--r--mit-pthreads/stdio/fprintf.c71
-rw-r--r--mit-pthreads/stdio/fpurge.c73
-rw-r--r--mit-pthreads/stdio/fputc.c73
-rw-r--r--mit-pthreads/stdio/fputs.c67
-rw-r--r--mit-pthreads/stdio/fread.c84
-rw-r--r--mit-pthreads/stdio/freopen.c149
-rw-r--r--mit-pthreads/stdio/fscanf.c73
-rw-r--r--mit-pthreads/stdio/fseek.c248
-rw-r--r--mit-pthreads/stdio/fsetpos.c54
-rw-r--r--mit-pthreads/stdio/ftell.c90
-rw-r--r--mit-pthreads/stdio/funopen.c105
-rw-r--r--mit-pthreads/stdio/fvwrite.c190
-rw-r--r--mit-pthreads/stdio/fvwrite.h54
-rw-r--r--mit-pthreads/stdio/fwalk.c132
-rw-r--r--mit-pthreads/stdio/fwrite.c80
-rw-r--r--mit-pthreads/stdio/getc.c58
-rw-r--r--mit-pthreads/stdio/getc_unlocked.c55
-rw-r--r--mit-pthreads/stdio/getchar.c58
-rw-r--r--mit-pthreads/stdio/getchar_unlocked.c54
-rw-r--r--mit-pthreads/stdio/gets.c71
-rw-r--r--mit-pthreads/stdio/getw.c51
-rw-r--r--mit-pthreads/stdio/glue.h49
-rw-r--r--mit-pthreads/stdio/local.h90
-rw-r--r--mit-pthreads/stdio/makebuf.c122
-rw-r--r--mit-pthreads/stdio/mktemp.c126
-rw-r--r--mit-pthreads/stdio/perror.c67
-rw-r--r--mit-pthreads/stdio/printf.c56
-rw-r--r--mit-pthreads/stdio/putc.c60
-rw-r--r--mit-pthreads/stdio/putc_unlocked.c56
-rw-r--r--mit-pthreads/stdio/putchar.c60
-rw-r--r--mit-pthreads/stdio/putchar_unlocked.c56
-rw-r--r--mit-pthreads/stdio/puts.c71
-rw-r--r--mit-pthreads/stdio/putw.c64
-rw-r--r--mit-pthreads/stdio/refill.c189
-rw-r--r--mit-pthreads/stdio/remove.c50
-rw-r--r--mit-pthreads/stdio/rewind.c55
-rw-r--r--mit-pthreads/stdio/rget.c58
-rw-r--r--mit-pthreads/stdio/scanf.c72
-rw-r--r--mit-pthreads/stdio/setbuf.c52
-rw-r--r--mit-pthreads/stdio/setbuffer.c64
-rw-r--r--mit-pthreads/stdio/setvbuf.c154
-rw-r--r--mit-pthreads/stdio/snprintf.c79
-rw-r--r--mit-pthreads/stdio/sprintf.c78
-rw-r--r--mit-pthreads/stdio/sscanf.c79
-rw-r--r--mit-pthreads/stdio/stdio.c104
-rw-r--r--mit-pthreads/stdio/strerror.c72
-rw-r--r--mit-pthreads/stdio/tempnam.c87
-rw-r--r--mit-pthreads/stdio/tmpfile.c80
-rw-r--r--mit-pthreads/stdio/tmpnam.c55
-rw-r--r--mit-pthreads/stdio/ungetc.c155
-rw-r--r--mit-pthreads/stdio/vfprintf.c788
-rw-r--r--mit-pthreads/stdio/vfscanf.c750
-rw-r--r--mit-pthreads/stdio/vprintf.c51
-rw-r--r--mit-pthreads/stdio/vscanf.c55
-rw-r--r--mit-pthreads/stdio/vsnprintf.c65
-rw-r--r--mit-pthreads/stdio/vsprintf.c62
-rw-r--r--mit-pthreads/stdio/vsscanf.c62
-rw-r--r--mit-pthreads/stdio/wbuf.c89
-rw-r--r--mit-pthreads/stdio/wsetup.c91
-rw-r--r--mit-pthreads/stdio/xprintf.c883
-rwxr-xr-xmit-pthreads/stdlib/GNUmakefile.inc7
-rw-r--r--mit-pthreads/stdlib/Makefile.inc10
-rw-r--r--mit-pthreads/stdlib/abort.c67
-rw-r--r--mit-pthreads/stdlib/atexit.h46
-rw-r--r--mit-pthreads/stdlib/exit.c89
-rw-r--r--mit-pthreads/stdlib/getopt.c135
-rw-r--r--mit-pthreads/stdlib/rand.c64
-rw-r--r--mit-pthreads/stdlib/random.c389
-rw-r--r--mit-pthreads/stdlib/strtod.c178
-rw-r--r--mit-pthreads/stdlib/strtol.c131
-rw-r--r--mit-pthreads/stdlib/strtoul.c109
-rw-r--r--mit-pthreads/stdlib/system.c83
-rwxr-xr-xmit-pthreads/string/GNUmakefile.inc7
-rw-r--r--mit-pthreads/string/Makefile.inc8
-rw-r--r--mit-pthreads/string/strtok.c119
-rw-r--r--mit-pthreads/tests/.cvsignore1
-rw-r--r--mit-pthreads/tests/Makefile.in164
-rwxr-xr-xmit-pthreads/tests/README26
-rw-r--r--mit-pthreads/tests/bench_fcntl.c82
-rw-r--r--mit-pthreads/tests/bench_pipe.c115
-rw-r--r--mit-pthreads/tests/bench_read.c88
-rw-r--r--mit-pthreads/tests/p_bench_getpid.c78
-rw-r--r--mit-pthreads/tests/p_bench_mutex.c78
-rw-r--r--mit-pthreads/tests/p_bench_pthread_create.c92
-rw-r--r--mit-pthreads/tests/p_bench_read.c103
-rw-r--r--mit-pthreads/tests/p_bench_semaphore.c82
-rw-r--r--mit-pthreads/tests/p_bench_yield.c123
-rw-r--r--mit-pthreads/tests/test_create.c35
-rw-r--r--mit-pthreads/tests/test_cwd.c11
-rw-r--r--mit-pthreads/tests/test_execve.c57
-rw-r--r--mit-pthreads/tests/test_fcntl.c32
-rw-r--r--mit-pthreads/tests/test_fork.c60
-rw-r--r--mit-pthreads/tests/test_netdb.c110
-rw-r--r--mit-pthreads/tests/test_pause.c19
-rw-r--r--mit-pthreads/tests/test_preemption.c38
-rw-r--r--mit-pthreads/tests/test_preemption_float.c98
-rw-r--r--mit-pthreads/tests/test_pthread_cond_timedwait.c93
-rw-r--r--mit-pthreads/tests/test_pthread_join.c78
-rw-r--r--mit-pthreads/tests/test_pthread_mutex.c221
-rw-r--r--mit-pthreads/tests/test_pw.c20
-rw-r--r--mit-pthreads/tests/test_readdir.c42
-rw-r--r--mit-pthreads/tests/test_select.c115
-rw-r--r--mit-pthreads/tests/test_setjmp.c13
-rw-r--r--mit-pthreads/tests/test_sleep.c46
-rw-r--r--mit-pthreads/tests/test_sock_1.c204
-rw-r--r--mit-pthreads/tests/test_sock_2.c116
-rw-r--r--mit-pthreads/tests/test_sock_2a.c87
-rw-r--r--mit-pthreads/tests/test_stdio_1.c124
-rw-r--r--mit-pthreads/tests/test_switch.c97
-rw-r--r--myisam/Makefile.am19
-rw-r--r--myisam/ft_boolean_search.c603
-rw-r--r--myisam/ft_dump.c270
-rw-r--r--myisam/ft_eval.c169
-rw-r--r--myisam/ft_eval.h7
-rw-r--r--myisam/ft_nlq_search.c308
-rw-r--r--myisam/ft_parser.c161
-rw-r--r--myisam/ft_search.c231
-rw-r--r--myisam/ft_static.c32
-rw-r--r--myisam/ft_stem.c7
-rw-r--r--myisam/ft_stopwords.c15
-rw-r--r--myisam/ft_test1.c110
-rw-r--r--myisam/ft_test1.h7
-rw-r--r--myisam/ft_update.c233
-rw-r--r--myisam/ftdefs.h77
-rw-r--r--myisam/fulltext.h1
-rw-r--r--myisam/mi_cache.c74
-rw-r--r--myisam/mi_changed.c8
-rw-r--r--myisam/mi_check.c1256
-rw-r--r--myisam/mi_checksum.c6
-rw-r--r--myisam/mi_close.c14
-rw-r--r--myisam/mi_create.c118
-rw-r--r--myisam/mi_dbug.c8
-rw-r--r--myisam/mi_delete.c15
-rw-r--r--myisam/mi_delete_all.c13
-rw-r--r--myisam/mi_delete_table.c10
-rw-r--r--myisam/mi_dynrec.c155
-rw-r--r--myisam/mi_extra.c92
-rw-r--r--myisam/mi_info.c10
-rw-r--r--myisam/mi_key.c40
-rw-r--r--myisam/mi_locking.c36
-rw-r--r--myisam/mi_log.c6
-rw-r--r--myisam/mi_open.c159
-rw-r--r--myisam/mi_packrec.c22
-rw-r--r--myisam/mi_page.c10
-rw-r--r--myisam/mi_panic.c6
-rw-r--r--myisam/mi_range.c22
-rw-r--r--myisam/mi_rename.c10
-rw-r--r--myisam/mi_rfirst.c6
-rw-r--r--myisam/mi_rkey.c12
-rw-r--r--myisam/mi_rlast.c6
-rw-r--r--myisam/mi_rnext.c4
-rw-r--r--myisam/mi_rnext_same.c8
-rw-r--r--myisam/mi_rprev.c4
-rw-r--r--myisam/mi_rrnd.c6
-rw-r--r--myisam/mi_rsame.c11
-rw-r--r--myisam/mi_rsamepos.c6
-rw-r--r--myisam/mi_scan.c6
-rw-r--r--myisam/mi_search.c1253
-rw-r--r--myisam/mi_static.c18
-rw-r--r--myisam/mi_statrec.c65
-rw-r--r--myisam/mi_test1.c289
-rw-r--r--myisam/mi_test2.c189
-rw-r--r--myisam/mi_test3.c16
-rw-r--r--myisam/mi_test_all.res90
-rwxr-xr-xmyisam/mi_test_all.sh20
-rw-r--r--myisam/mi_unique.c6
-rw-r--r--myisam/mi_update.c16
-rw-r--r--myisam/mi_write.c262
-rw-r--r--myisam/myisamchk.c782
-rw-r--r--myisam/myisamdef.h143
-rw-r--r--myisam/myisamlog.c19
-rw-r--r--myisam/myisampack.c235
-rw-r--r--myisam/sort.c679
-rw-r--r--myisammrg/Makefile.am4
-rw-r--r--myisammrg/mymrgdef.h31
-rw-r--r--myisammrg/myrg_close.c8
-rw-r--r--myisammrg/myrg_create.c18
-rw-r--r--myisammrg/myrg_def.h31
-rw-r--r--myisammrg/myrg_delete.c17
-rw-r--r--myisammrg/myrg_extra.c25
-rw-r--r--myisammrg/myrg_info.c2
-rw-r--r--myisammrg/myrg_locking.c12
-rw-r--r--myisammrg/myrg_open.c64
-rw-r--r--myisammrg/myrg_panic.c8
-rw-r--r--myisammrg/myrg_queue.c2
-rw-r--r--myisammrg/myrg_rfirst.c2
-rw-r--r--myisammrg/myrg_rkey.c2
-rw-r--r--myisammrg/myrg_rlast.c2
-rw-r--r--myisammrg/myrg_rnext.c2
-rw-r--r--myisammrg/myrg_rprev.c2
-rw-r--r--myisammrg/myrg_rrnd.c12
-rw-r--r--myisammrg/myrg_rsame.c18
-rw-r--r--myisammrg/myrg_static.c12
-rw-r--r--myisammrg/myrg_update.c11
-rw-r--r--myisammrg/myrg_write.c30
-rw-r--r--mysql-test/Makefile.am2
-rwxr-xr-xmysql-test/create-test-result4
-rwxr-xr-xmysql-test/fix-result22
-rw-r--r--mysql-test/include/have_bdb.inc2
-rw-r--r--mysql-test/include/have_gemini.inc2
-rw-r--r--mysql-test/include/have_innodb.inc2
-rw-r--r--mysql-test/include/have_isam.inc2
-rw-r--r--mysql-test/include/have_openssl.inc4
-rw-r--r--mysql-test/include/have_openssl_1.inc4
-rw-r--r--mysql-test/include/have_openssl_2.inc4
-rw-r--r--mysql-test/include/have_query_cache.inc4
-rw-r--r--mysql-test/include/master-slave.inc9
-rw-r--r--mysql-test/include/not_embedded.inc5
-rw-r--r--mysql-test/install_test_db.sh45
-rw-r--r--mysql-test/mysql-test-run.sh849
-rw-r--r--mysql-test/r/alias.result59
-rw-r--r--mysql-test/r/alter_table.result90
-rw-r--r--mysql-test/r/analyse.result7
-rw-r--r--mysql-test/r/auto_increment.result59
-rw-r--r--mysql-test/r/backup.result30
-rw-r--r--mysql-test/r/bdb-crash.result29
-rw-r--r--mysql-test/r/bdb-deadlock.result21
-rw-r--r--mysql-test/r/bdb.result621
-rw-r--r--mysql-test/r/bench_count_distinct.result4
-rw-r--r--mysql-test/r/big_test.require2
-rw-r--r--mysql-test/r/bigint.result63
-rw-r--r--mysql-test/r/binary.result22
-rw-r--r--mysql-test/r/bulk_replace.result11
-rw-r--r--mysql-test/r/case.result23
-rw-r--r--mysql-test/r/check.result5
-rw-r--r--mysql-test/r/comments.result13
-rw-r--r--mysql-test/r/compare.result8
-rw-r--r--mysql-test/r/count_distinct.result35
-rw-r--r--mysql-test/r/count_distinct2.result129
-rw-r--r--mysql-test/r/create.result85
-rw-r--r--mysql-test/r/ctype_latin1_de.result207
-rw-r--r--mysql-test/r/delayed.result20
-rw-r--r--mysql-test/r/delete.result26
-rw-r--r--mysql-test/r/dirty-close.result4
-rw-r--r--mysql-test/r/dirty_close.result9
-rw-r--r--mysql-test/r/distinct.result178
-rw-r--r--mysql-test/r/drop.result39
-rw-r--r--mysql-test/r/empty_table.result6
-rw-r--r--mysql-test/r/err000001.result25
-rw-r--r--mysql-test/r/explain.result17
-rw-r--r--mysql-test/r/flush.result24
-rw-r--r--mysql-test/r/foreign_key.result15
-rw-r--r--mysql-test/r/fulltext.result180
-rw-r--r--mysql-test/r/fulltext_cache.result54
-rw-r--r--mysql-test/r/fulltext_distinct.result43
-rw-r--r--mysql-test/r/fulltext_left_join.result29
-rw-r--r--mysql-test/r/fulltext_multi.result26
-rw-r--r--mysql-test/r/fulltext_order_by.result65
-rw-r--r--mysql-test/r/fulltext_update.result20
-rw-r--r--mysql-test/r/fulltext_var.result6
-rw-r--r--mysql-test/r/func_concat.result15
-rw-r--r--mysql-test/r/func_crypt.result4
-rw-r--r--mysql-test/r/func_date_add.result35
-rw-r--r--mysql-test/r/func_encrypt.result136
-rw-r--r--mysql-test/r/func_equal.result14
-rw-r--r--mysql-test/r/func_group.result74
-rw-r--r--mysql-test/r/func_if.result13
-rw-r--r--mysql-test/r/func_in.result13
-rw-r--r--mysql-test/r/func_isnull.result6
-rw-r--r--mysql-test/r/func_like.result22
-rw-r--r--mysql-test/r/func_math.result13
-rw-r--r--mysql-test/r/func_misc.result8
-rw-r--r--mysql-test/r/func_op.result5
-rw-r--r--mysql-test/r/func_regexp.result29
-rw-r--r--mysql-test/r/func_set.result9
-rw-r--r--mysql-test/r/func_str.result114
-rw-r--r--mysql-test/r/func_system.result6
-rw-r--r--mysql-test/r/func_test.result23
-rw-r--r--mysql-test/r/func_time.result160
-rw-r--r--mysql-test/r/func_timestamp.result8
-rw-r--r--mysql-test/r/gcc296.result15
-rw-r--r--mysql-test/r/gemini.result370
-rw-r--r--mysql-test/r/grant_cache.result153
-rw-r--r--mysql-test/r/group_by.result331
-rw-r--r--mysql-test/r/handler.result139
-rw-r--r--mysql-test/r/have_gemini.require2
-rw-r--r--mysql-test/r/have_openssl.require2
-rw-r--r--mysql-test/r/have_openssl_1.require2
-rw-r--r--mysql-test/r/have_openssl_2.require2
-rw-r--r--mysql-test/r/have_query_cache.require2
-rw-r--r--mysql-test/r/have_symlink.require2
-rw-r--r--mysql-test/r/having.result59
-rw-r--r--mysql-test/r/heap.result122
-rw-r--r--mysql-test/r/innodb.result520
-rw-r--r--mysql-test/r/innodb_cache.result100
-rw-r--r--mysql-test/r/ins000001.result9
-rw-r--r--mysql-test/r/insert.result41
-rw-r--r--mysql-test/r/insert_select.result55
-rw-r--r--mysql-test/r/isam.result73
-rw-r--r--mysql-test/r/isolation.result61
-rw-r--r--mysql-test/r/join.result175
-rw-r--r--mysql-test/r/join_crash.result109
-rw-r--r--mysql-test/r/join_outer.result321
-rw-r--r--mysql-test/r/key.result161
-rw-r--r--mysql-test/r/key_diff.result13
-rw-r--r--mysql-test/r/key_primary.result10
-rw-r--r--mysql-test/r/keywords.result12
-rw-r--r--mysql-test/r/kill.result7
-rw-r--r--mysql-test/r/limit.result27
-rw-r--r--mysql-test/r/lock.result43
-rw-r--r--mysql-test/r/lock_multi.result18
-rw-r--r--mysql-test/r/merge.result411
-rw-r--r--mysql-test/r/multi_update.result72
-rw-r--r--mysql-test/r/myisam.result76
-rw-r--r--mysql-test/r/not_embedded.require2
-rw-r--r--mysql-test/r/null.result26
-rw-r--r--mysql-test/r/null_key.result71
-rw-r--r--mysql-test/r/odbc.result8
-rw-r--r--mysql-test/r/olap.result27
-rw-r--r--mysql-test/r/openssl_1.result2
-rw-r--r--mysql-test/r/openssl_2.result2
-rw-r--r--mysql-test/r/order_by.result329
-rw-r--r--mysql-test/r/order_fill_sortbuf.result10
-rw-r--r--mysql-test/r/overflow.result2
-rw-r--r--mysql-test/r/query_cache.result492
-rw-r--r--mysql-test/r/raid.result188
-rw-r--r--mysql-test/r/range.result142
-rw-r--r--mysql-test/r/rename.result25
-rw-r--r--mysql-test/r/replace.result23
-rw-r--r--mysql-test/r/rollback.result9
-rw-r--r--mysql-test/r/rpl000001.result82
-rw-r--r--mysql-test/r/rpl000002.result25
-rw-r--r--mysql-test/r/rpl000003.result12
-rw-r--r--mysql-test/r/rpl000004.result28
-rw-r--r--mysql-test/r/rpl000005.result14
-rw-r--r--mysql-test/r/rpl000006.result24
-rw-r--r--mysql-test/r/rpl000007.result19
-rw-r--r--mysql-test/r/rpl000008.result22
-rw-r--r--mysql-test/r/rpl000009.result80
-rw-r--r--mysql-test/r/rpl000010.result12
-rw-r--r--mysql-test/r/rpl000011.result14
-rw-r--r--mysql-test/r/rpl000012.result25
-rw-r--r--mysql-test/r/rpl000013.result17
-rw-r--r--mysql-test/r/rpl000014.result43
-rw-r--r--mysql-test/r/rpl000015.result34
-rw-r--r--mysql-test/r/rpl000016.result58
-rw-r--r--mysql-test/r/rpl000017.result9
-rw-r--r--mysql-test/r/rpl000018.result8
-rw-r--r--mysql-test/r/rpl_alter.result17
-rw-r--r--mysql-test/r/rpl_compat.result77
-rw-r--r--mysql-test/r/rpl_empty_master_crash.result14
-rw-r--r--mysql-test/r/rpl_failsafe.result33
-rw-r--r--mysql-test/r/rpl_get_lock.result21
-rw-r--r--mysql-test/r/rpl_log.result98
-rw-r--r--mysql-test/r/rpl_magic.result36
-rw-r--r--mysql-test/r/rpl_mystery22.result19
-rw-r--r--mysql-test/r/rpl_skip_error.result11
-rw-r--r--mysql-test/r/rpl_sporadic_master.result19
-rw-r--r--mysql-test/r/sel000001.result5
-rw-r--r--mysql-test/r/sel000002.result5
-rw-r--r--mysql-test/r/sel000003.result5
-rw-r--r--mysql-test/r/sel000031.result8
-rw-r--r--mysql-test/r/sel000032.result8
-rw-r--r--mysql-test/r/sel000033.result6
-rw-r--r--mysql-test/r/sel000100.result26
-rw-r--r--mysql-test/r/select.result1461
-rw-r--r--mysql-test/r/select_found.result171
-rw-r--r--mysql-test/r/select_safe.result29
-rw-r--r--mysql-test/r/show_check.result143
-rw-r--r--mysql-test/r/slave-running.result1
-rw-r--r--mysql-test/r/slave-stopped.result1
-rw-r--r--mysql-test/r/status.result13
-rw-r--r--mysql-test/r/symlink.result65
-rw-r--r--mysql-test/r/tablelock.result36
-rw-r--r--mysql-test/r/temp_table.result44
-rw-r--r--mysql-test/r/truncate.result18
-rw-r--r--mysql-test/r/type_blob.result187
-rw-r--r--mysql-test/r/type_date.result49
-rw-r--r--mysql-test/r/type_datetime.result38
-rw-r--r--mysql-test/r/type_decimal.result235
-rw-r--r--mysql-test/r/type_enum.result14
-rw-r--r--mysql-test/r/type_float.result33
-rw-r--r--mysql-test/r/type_ranges.result154
-rw-r--r--mysql-test/r/type_set.result6
-rw-r--r--mysql-test/r/type_time.result12
-rw-r--r--mysql-test/r/type_timestamp.result34
-rw-r--r--mysql-test/r/type_uint.result6
-rw-r--r--mysql-test/r/type_year.result6
-rw-r--r--mysql-test/r/union.result204
-rw-r--r--mysql-test/r/update.result73
-rw-r--r--mysql-test/r/user_var.result16
-rw-r--r--mysql-test/r/varbinary.result21
-rw-r--r--mysql-test/r/variables.result295
-rw-r--r--mysql-test/r/warnings.result9
-rwxr-xr-xmysql-test/resolve-stack8
-rw-r--r--mysql-test/std_data/des_key_file4
-rw-r--r--mysql-test/std_data/gemini.dat5
-rw-r--r--mysql-test/std_data/master-bin.001bin113 -> 98 bytes
-rw-r--r--mysql-test/t/alter_table.test37
-rw-r--r--mysql-test/t/analyse.test1
-rw-r--r--mysql-test/t/auto_increment.test15
-rw-r--r--mysql-test/t/backup.test6
-rw-r--r--mysql-test/t/bdb-crash.test1
-rw-r--r--mysql-test/t/bdb.test16
-rw-r--r--mysql-test/t/bench_count_distinct.test3
-rw-r--r--mysql-test/t/bigint.test23
-rw-r--r--mysql-test/t/bulk_replace.test14
-rw-r--r--mysql-test/t/check.test5
-rw-r--r--mysql-test/t/count_distinct2-master.opt1
-rw-r--r--mysql-test/t/count_distinct2.test79
-rw-r--r--mysql-test/t/create.test20
-rw-r--r--mysql-test/t/ctype_latin1_de-master.opt1
-rw-r--r--mysql-test/t/ctype_latin1_de.test46
-rw-r--r--mysql-test/t/dirty_close.test (renamed from mysql-test/t/dirty-close.test)0
-rw-r--r--mysql-test/t/distinct.test11
-rw-r--r--mysql-test/t/drop.test44
-rw-r--r--mysql-test/t/flush.test24
-rw-r--r--mysql-test/t/fulltext.test84
-rw-r--r--mysql-test/t/fulltext_cache.test14
-rw-r--r--mysql-test/t/fulltext_distinct.test41
-rw-r--r--mysql-test/t/fulltext_left_join.test2
-rw-r--r--mysql-test/t/fulltext_order_by.test7
-rw-r--r--mysql-test/t/fulltext_var.test5
-rw-r--r--mysql-test/t/func_crypt.test3
-rw-r--r--mysql-test/t/func_encrypt-master.opt1
-rw-r--r--mysql-test/t/func_encrypt.test67
-rw-r--r--mysql-test/t/func_like.test10
-rw-r--r--mysql-test/t/func_str.test16
-rw-r--r--mysql-test/t/func_system.test2
-rw-r--r--mysql-test/t/func_test.test2
-rw-r--r--mysql-test/t/func_time.test12
-rw-r--r--mysql-test/t/gemini.test355
-rw-r--r--mysql-test/t/grant_cache-master.opt1
-rw-r--r--mysql-test/t/grant_cache.test104
-rw-r--r--mysql-test/t/group_by.test68
-rw-r--r--mysql-test/t/handler.test67
-rw-r--r--mysql-test/t/having.test12
-rw-r--r--mysql-test/t/heap.test38
-rw-r--r--mysql-test/t/innodb.test105
-rw-r--r--mysql-test/t/innodb_cache-master.opt1
-rw-r--r--mysql-test/t/innodb_cache.test50
-rw-r--r--mysql-test/t/insert.test38
-rw-r--r--mysql-test/t/insert_select.test58
-rw-r--r--mysql-test/t/isam.test59
-rw-r--r--mysql-test/t/isolation.test208
-rw-r--r--mysql-test/t/join.test2
-rw-r--r--mysql-test/t/key.test28
-rw-r--r--mysql-test/t/keywords.test4
-rw-r--r--mysql-test/t/kill.test8
-rw-r--r--mysql-test/t/limit.test2
-rw-r--r--mysql-test/t/lock.test42
-rw-r--r--mysql-test/t/lock_multi.test49
-rw-r--r--mysql-test/t/merge.test75
-rw-r--r--mysql-test/t/multi_update.test82
-rw-r--r--mysql-test/t/myisam.test29
-rw-r--r--mysql-test/t/null.test1
-rw-r--r--mysql-test/t/olap.test27
-rw-r--r--mysql-test/t/openssl_1.test6
-rw-r--r--mysql-test/t/openssl_2.test5
-rw-r--r--mysql-test/t/order_by.test49
-rw-r--r--mysql-test/t/order_fill_sortbuf-master.opt1
-rw-r--r--mysql-test/t/order_fill_sortbuf.test21
-rw-r--r--mysql-test/t/query_cache-master.opt1
-rw-r--r--mysql-test/t/query_cache.test338
-rw-r--r--mysql-test/t/rename.test16
-rw-r--r--mysql-test/t/rpl000001.test33
-rw-r--r--mysql-test/t/rpl000002.test2
-rw-r--r--mysql-test/t/rpl000009.test59
-rw-r--r--mysql-test/t/rpl000014.test11
-rw-r--r--mysql-test/t/rpl000015-slave-master-info.opt2
-rw-r--r--mysql-test/t/rpl000015.test15
-rw-r--r--mysql-test/t/rpl000016-slave.opt1
-rwxr-xr-xmysql-test/t/rpl000016-slave.sh1
-rw-r--r--mysql-test/t/rpl000016.test19
-rwxr-xr-xmysql-test/t/rpl000017-slave.sh3
-rw-r--r--mysql-test/t/rpl000017.test8
-rwxr-xr-xmysql-test/t/rpl000018-master.sh3
-rw-r--r--mysql-test/t/rpl000018.test7
-rw-r--r--mysql-test/t/rpl_compat.test86
-rw-r--r--mysql-test/t/rpl_empty_master_crash.test3
-rw-r--r--mysql-test/t/rpl_failsafe.test24
-rw-r--r--mysql-test/t/rpl_get_lock.test7
-rw-r--r--mysql-test/t/rpl_log.test57
-rw-r--r--mysql-test/t/rpl_magic.test31
-rw-r--r--mysql-test/t/rpl_mystery22.test1
-rw-r--r--mysql-test/t/rpl_sporadic_master.test8
-rw-r--r--mysql-test/t/select.test13
-rw-r--r--mysql-test/t/select_found.test87
-rw-r--r--mysql-test/t/show_check.test42
-rw-r--r--mysql-test/t/status.test10
-rw-r--r--mysql-test/t/symlink.test89
-rw-r--r--mysql-test/t/tablelock.test7
-rw-r--r--mysql-test/t/truncate.test11
-rw-r--r--mysql-test/t/type_datetime.test9
-rw-r--r--mysql-test/t/type_decimal.test9
-rw-r--r--mysql-test/t/type_enum.test1
-rw-r--r--mysql-test/t/union.test100
-rw-r--r--mysql-test/t/update.test11
-rw-r--r--mysql-test/t/user_var.test2
-rw-r--r--mysql-test/t/varbinary.test16
-rw-r--r--mysql-test/t/variables-master.opt1
-rw-r--r--mysql-test/t/variables.test197
-rw-r--r--mysql-test/xml/README74
-rw-r--r--mysql-test/xml/tests/sel000001.xml21
-rw-r--r--mysql-test/xml/tests/sel000002.xml20
-rw-r--r--mysql-test/xml/tests/sel000003.xml21
-rw-r--r--mysql-test/xml/tests/sel000004.xml17
-rw-r--r--mysql-test/xml/tests/sel000005.xml17
-rw-r--r--mysql-test/xml/tests/sel000006.xml17
-rw-r--r--mysql-test/xml/tests/sel000007.xml17
-rw-r--r--mysql-test/xml/tests/sel000008.xml17
-rw-r--r--mysql-test/xml/tests/sel000009.xml17
-rw-r--r--mysql-test/xml/tests/sel000010.xml17
-rw-r--r--mysql-test/xml/tests/sel000011.xml17
-rw-r--r--mysql-test/xml/tests/sel000012.xml16
-rw-r--r--mysql-test/xml/tests/sel000013.xml16
-rw-r--r--mysql-test/xml/tests/sel000014.xml17
-rw-r--r--mysql-test/xml/tests/sel000015.xml17
-rw-r--r--mysql-test/xml/tests/sel000016.xml17
-rw-r--r--mysql-test/xml/tests/sel000017.xml17
-rw-r--r--mysql-test/xml/tests/sel000018.xml17
-rw-r--r--mysql-test/xml/tests/sel000019.xml17
-rw-r--r--mysql-test/xml/tests/sel000020.xml17
-rw-r--r--mysql-test/xml/tests/sel000021.xml17
-rw-r--r--mysql-test/xml/tests/sel000022.xml17
-rw-r--r--mysql-test/xml/tests/sel000023.xml17
-rw-r--r--mysql-test/xml/tests/sel000024.xml17
-rw-r--r--mysql-test/xml/tests/sel000025.xml17
-rw-r--r--mysql-test/xml/tests/sel000026.xml17
-rw-r--r--mysql-test/xml/tests/sel000027.xml17
-rw-r--r--mysql-test/xml/tests/sel000028.xml17
-rw-r--r--mysql-test/xml/tests/sel000029.xml17
-rw-r--r--mysql-test/xml/tests/sel000030.xml17
-rw-r--r--mysql-test/xml/xsl/README4
-rw-r--r--mysql-test/xml/xsl/mysqltest.xsl59
-rw-r--r--mysys/Makefile.am17
-rw-r--r--mysys/array.c145
-rw-r--r--mysys/charset.c85
-rw-r--r--mysys/checksum.c45
-rw-r--r--mysys/default.c52
-rw-r--r--mysys/errors.c29
-rw-r--r--mysys/getopt.c750
-rw-r--r--mysys/getopt1.c170
-rw-r--r--mysys/getvar.c112
-rw-r--r--mysys/hash.c49
-rw-r--r--mysys/list.c29
-rw-r--r--mysys/make-conf.c31
-rw-r--r--mysys/md5.c369
-rw-r--r--mysys/mf_brkhant.c29
-rw-r--r--mysys/mf_cache.c23
-rw-r--r--mysys/mf_casecnv.c37
-rw-r--r--mysys/mf_dirname.c114
-rw-r--r--mysys/mf_fn_ext.c41
-rw-r--r--mysys/mf_format.c128
-rw-r--r--mysys/mf_getdate.c29
-rw-r--r--mysys/mf_iocache.c927
-rw-r--r--mysys/mf_iocache2.c138
-rw-r--r--mysys/mf_keycache.c251
-rw-r--r--mysys/mf_loadpath.c32
-rw-r--r--mysys/mf_pack.c36
-rw-r--r--mysys/mf_pack2.c53
-rw-r--r--mysys/mf_path.c29
-rw-r--r--mysys/mf_qsort2.c29
-rw-r--r--mysys/mf_radix.c29
-rw-r--r--mysys/mf_same.c29
-rw-r--r--mysys/mf_sleep.c29
-rw-r--r--mysys/mf_sort.c31
-rw-r--r--mysys/mf_soundex.c29
-rw-r--r--mysys/mf_strip.c29
-rw-r--r--mysys/mf_tempfile.c45
-rw-r--r--mysys/mf_unixpath.c29
-rw-r--r--mysys/mf_util.c29
-rw-r--r--mysys/mf_wcomp.c29
-rw-r--r--mysys/mf_wfile.c29
-rw-r--r--mysys/mulalloc.c43
-rw-r--r--mysys/my_aes.c199
-rw-r--r--mysys/my_alarm.c29
-rw-r--r--mysys/my_alloc.c175
-rw-r--r--mysys/my_append.c29
-rw-r--r--mysys/my_bit.c31
-rw-r--r--mysys/my_bitmap.c33
-rw-r--r--mysys/my_chsize.c47
-rw-r--r--mysys/my_clock.c31
-rw-r--r--mysys/my_compress.c35
-rw-r--r--mysys/my_copy.c29
-rw-r--r--mysys/my_create.c29
-rw-r--r--mysys/my_delete.c30
-rw-r--r--mysys/my_div.c37
-rw-r--r--mysys/my_dup.c39
-rw-r--r--mysys/my_error.c61
-rw-r--r--mysys/my_fopen.c29
-rw-r--r--mysys/my_fstream.c34
-rw-r--r--mysys/my_gethostbyname.c12
-rw-r--r--mysys/my_getopt.c796
-rw-r--r--mysys/my_getwd.c29
-rw-r--r--mysys/my_init.c33
-rw-r--r--mysys/my_lib.c40
-rw-r--r--mysys/my_lock.c29
-rw-r--r--mysys/my_lockmem.c29
-rw-r--r--mysys/my_lread.c29
-rw-r--r--mysys/my_lwrite.c29
-rw-r--r--mysys/my_malloc.c29
-rw-r--r--mysys/my_messnc.c29
-rw-r--r--mysys/my_mkdir.c29
-rw-r--r--mysys/my_net.c29
-rw-r--r--mysys/my_once.c49
-rw-r--r--mysys/my_open.c62
-rw-r--r--mysys/my_pread.c29
-rw-r--r--mysys/my_pthread.c61
-rw-r--r--mysys/my_quick.c29
-rw-r--r--mysys/my_read.c62
-rw-r--r--mysys/my_realloc.c29
-rw-r--r--mysys/my_redel.c29
-rw-r--r--mysys/my_rename.c29
-rw-r--r--mysys/my_seek.c38
-rw-r--r--mysys/my_semaphore.c103
-rw-r--r--mysys/my_static.c36
-rw-r--r--mysys/my_static.h40
-rw-r--r--mysys/my_symlink.c29
-rw-r--r--mysys/my_symlink2.c50
-rw-r--r--mysys/my_tempnam.c27
-rw-r--r--mysys/my_thr_init.c88
-rw-r--r--mysys/my_vsnprintf.c58
-rw-r--r--mysys/my_wincond.c29
-rw-r--r--mysys/my_winsem.c406
-rw-r--r--mysys/my_winthread.c29
-rw-r--r--mysys/my_write.c29
-rw-r--r--mysys/mysys_priv.h31
-rw-r--r--mysys/ptr_cmp.c32
-rw-r--r--mysys/queues.c51
-rw-r--r--mysys/raid.cc145
-rw-r--r--mysys/rijndael.c1397
-rw-r--r--mysys/safemalloc.c297
-rw-r--r--mysys/sha1.c392
-rw-r--r--mysys/string.c31
-rw-r--r--mysys/test_charset.c33
-rw-r--r--mysys/test_dir.c29
-rw-r--r--mysys/test_fn.c29
-rw-r--r--mysys/testhash.c49
-rw-r--r--mysys/thr_alarm.c129
-rw-r--r--mysys/thr_lock.c29
-rw-r--r--mysys/thr_mutex.c44
-rw-r--r--mysys/thr_rwlock.c122
-rw-r--r--mysys/tree.c108
-rw-r--r--mysys/typelib.c32
-rw-r--r--pstack/Makefile.am36
-rw-r--r--pstack/aout/Makefile.am1
-rw-r--r--pstack/aout/aout64.h475
-rw-r--r--pstack/aout/stab.def264
-rw-r--r--pstack/aout/stab_gnu.h37
-rw-r--r--pstack/bucomm.c238
-rw-r--r--pstack/bucomm.h85
-rw-r--r--pstack/budbg.h58
-rw-r--r--pstack/debug.c3509
-rw-r--r--pstack/debug.h798
-rw-r--r--pstack/demangle.h90
-rw-r--r--pstack/filemode.c266
-rw-r--r--pstack/ieee.c7602
-rw-r--r--pstack/ieee.h138
-rw-r--r--pstack/libiberty.h180
-rw-r--r--pstack/linuxthreads.c90
-rw-r--r--pstack/linuxthreads.h28
-rw-r--r--pstack/pstack.c2745
-rw-r--r--pstack/pstack.h22
-rw-r--r--pstack/pstacktrace.h24
-rw-r--r--pstack/rddbg.c462
-rw-r--r--pstack/stabs.c5082
-rw-r--r--readline/bind.c65
-rw-r--r--readline/callback.c1
-rw-r--r--readline/complete.c33
-rw-r--r--readline/display.c20
-rw-r--r--readline/funmap.c12
-rw-r--r--readline/histexpand.c15
-rw-r--r--readline/histfile.c8
-rw-r--r--readline/history.c2
-rw-r--r--readline/history.h6
-rw-r--r--readline/histsearch.c2
-rw-r--r--readline/input.c2
-rw-r--r--readline/isearch.c6
-rw-r--r--readline/kill.c34
-rw-r--r--readline/macro.c19
-rw-r--r--readline/readline.c63
-rw-r--r--readline/readline.h38
-rw-r--r--readline/rlstdc.h4
-rw-r--r--readline/rltty.c11
-rw-r--r--readline/search.c20
-rw-r--r--readline/shell.c1
-rw-r--r--readline/terminal.c21
-rw-r--r--readline/tilde.c12
-rw-r--r--readline/tilde.h4
-rw-r--r--readline/undo.c9
-rw-r--r--readline/util.c14
-rw-r--r--readline/vi_mode.c72
-rw-r--r--regex/cclass.h6
-rw-r--r--regex/cname.h4
-rw-r--r--regex/debug.c2
-rw-r--r--regex/main.c18
-rw-r--r--regex/regcomp.c74
-rw-r--r--regex/regcomp.ih2
-rw-r--r--regex/regerror.c10
-rw-r--r--regex/regexec.c2
-rw-r--r--regex/regexp.c2
-rw-r--r--regex/regfree.c2
-rw-r--r--regex/reginit.c4
-rw-r--r--regex/split.c2
-rw-r--r--scripts/Makefile.am14
-rw-r--r--scripts/explain_log.sh383
-rw-r--r--scripts/make_binary_distribution.sh9
-rw-r--r--scripts/mysql_config.sh13
-rw-r--r--scripts/mysql_explain_log.sh383
-rw-r--r--scripts/mysql_fix_privilege_tables.sh69
-rw-r--r--scripts/mysql_install_db.sh38
-rw-r--r--scripts/mysql_secure_installation.sh308
-rw-r--r--scripts/mysql_tableinfo.sh478
-rw-r--r--scripts/mysqld_multi.sh40
-rw-r--r--scripts/mysqld_safe-watch.sh150
-rw-r--r--scripts/mysqld_safe.sh314
-rw-r--r--scripts/safe_mysqld-watch.sh150
-rw-r--r--scripts/safe_mysqld.sh276
-rw-r--r--sql-bench/Comments/interbase18
-rw-r--r--sql-bench/Makefile.am8
-rw-r--r--sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i68620
-rw-r--r--sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686109
-rw-r--r--sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i68616
-rw-r--r--sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i68619
-rw-r--r--sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i68635
-rw-r--r--sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i68618
-rw-r--r--sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686106
-rw-r--r--sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i68630
-rw-r--r--sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i6863
-rw-r--r--sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i68614
-rw-r--r--sql-bench/as3ap.sh636
-rw-r--r--sql-bench/bench-count-distinct.sh258
-rw-r--r--sql-bench/bench-init.pl.sh28
-rw-r--r--sql-bench/crash-me.sh60
-rw-r--r--sql-bench/limits/db2.cfg270
-rw-r--r--sql-bench/limits/interbase-dialect1.cfg514
-rw-r--r--sql-bench/limits/interbase-dialect3.cfg514
-rw-r--r--sql-bench/limits/interbase-superserver.cfg514
-rw-r--r--sql-bench/limits/mysql.cfg41
-rw-r--r--sql-bench/run-all-tests.sh20
-rw-r--r--sql-bench/server-cfg.sh397
-rw-r--r--sql-bench/test-ATIS.sh17
-rw-r--r--sql-bench/test-alter-table.sh14
-rw-r--r--sql-bench/test-big-tables.sh16
-rw-r--r--sql-bench/test-connect.sh88
-rw-r--r--sql-bench/test-insert.sh114
-rw-r--r--sql-bench/test-select.sh18
-rw-r--r--sql-bench/test-transactions.sh297
-rw-r--r--sql-bench/test-wisconsin.sh68
-rw-r--r--sql/ChangeLog5
-rw-r--r--sql/Makefile.am42
-rw-r--r--sql/cache_manager.cc12
-rw-r--r--sql/cache_manager.h10
-rw-r--r--sql/convert.cc28
-rw-r--r--sql/custom_conf.h6
-rw-r--r--sql/derror.cc47
-rw-r--r--sql/des_key_file.cc107
-rw-r--r--sql/field.cc809
-rw-r--r--sql/field.h259
-rw-r--r--sql/field_conv.cc6
-rw-r--r--sql/filesort.cc341
-rw-r--r--sql/frm_crypt.cc6
-rw-r--r--sql/gen_lex_hash.cc142
-rw-r--r--sql/ha_berkeley.cc71
-rw-r--r--sql/ha_berkeley.h18
-rw-r--r--sql/ha_gemini.cc3630
-rw-r--r--sql/ha_gemini.h208
-rw-r--r--sql/ha_hash.h31
-rw-r--r--sql/ha_heap.cc51
-rw-r--r--sql/ha_heap.h27
-rw-r--r--sql/ha_innobase.cc3554
-rw-r--r--sql/ha_innobase.h199
-rw-r--r--sql/ha_innodb.cc3587
-rw-r--r--sql/ha_innodb.h206
-rw-r--r--sql/ha_isam.cc31
-rw-r--r--sql/ha_isam.h33
-rw-r--r--sql/ha_isammrg.cc16
-rw-r--r--sql/ha_isammrg.h12
-rw-r--r--sql/ha_myisam.cc294
-rw-r--r--sql/ha_myisam.h48
-rw-r--r--sql/ha_myisammrg.cc73
-rw-r--r--sql/ha_myisammrg.h22
-rw-r--r--sql/handler.cc265
-rw-r--r--sql/handler.h160
-rw-r--r--sql/hash_filo.cc6
-rw-r--r--sql/hash_filo.h8
-rw-r--r--sql/hostname.cc11
-rw-r--r--sql/init.cc6
-rw-r--r--sql/item.cc57
-rw-r--r--sql/item.h100
-rw-r--r--sql/item_buff.cc6
-rw-r--r--sql/item_cmpfunc.cc340
-rw-r--r--sql/item_cmpfunc.h58
-rw-r--r--sql/item_create.cc66
-rw-r--r--sql/item_create.h12
-rw-r--r--sql/item_func.cc373
-rw-r--r--sql/item_func.h203
-rw-r--r--sql/item_strfunc.cc409
-rw-r--r--sql/item_strfunc.h104
-rw-r--r--sql/item_sum.cc328
-rw-r--r--sql/item_sum.h59
-rw-r--r--sql/item_timefunc.cc32
-rw-r--r--sql/item_timefunc.h136
-rw-r--r--sql/item_uniq.cc6
-rw-r--r--sql/item_uniq.h8
-rw-r--r--sql/key.cc12
-rw-r--r--sql/lex.h86
-rw-r--r--sql/lex_symbol.h6
-rw-r--r--sql/lock.cc173
-rw-r--r--sql/log.cc565
-rw-r--r--sql/log_event.cc2056
-rw-r--r--sql/log_event.h724
-rw-r--r--sql/matherr.c8
-rw-r--r--sql/md5.c351
-rw-r--r--sql/md5.h80
-rw-r--r--sql/mf_iocache.cc646
-rw-r--r--sql/mini_client.cc654
-rw-r--r--sql/mini_client.h55
-rw-r--r--sql/my_lock.c8
-rw-r--r--sql/mysql_priv.h336
-rw-r--r--sql/mysqld.cc3581
-rw-r--r--sql/net_pkg.cc51
-rw-r--r--sql/net_serv.cc490
-rw-r--r--sql/nt_servc.cc28
-rw-r--r--sql/nt_servc.h2
-rw-r--r--sql/opt_ft.h2
-rw-r--r--sql/opt_range.cc311
-rw-r--r--sql/opt_range.h39
-rw-r--r--sql/opt_sum.cc49
-rw-r--r--sql/password.c8
-rw-r--r--sql/procedure.cc6
-rw-r--r--sql/procedure.h10
-rw-r--r--sql/records.cc30
-rw-r--r--sql/repl_failsafe.cc877
-rw-r--r--sql/repl_failsafe.h37
-rw-r--r--sql/set_var.cc1293
-rw-r--r--sql/set_var.h419
-rw-r--r--sql/share/Makefile.am6
-rw-r--r--sql/share/charsets/Index4
-rw-r--r--sql/share/czech/errmsg.txt394
-rw-r--r--sql/share/danish/errmsg.txt18
-rw-r--r--sql/share/dutch/errmsg.txt51
-rw-r--r--sql/share/english/errmsg.txt18
-rw-r--r--sql/share/estonian/errmsg.txt367
-rw-r--r--sql/share/french/errmsg.txt20
-rw-r--r--sql/share/german/errmsg.txt18
-rw-r--r--sql/share/greek/errmsg.txt18
-rw-r--r--sql/share/hungarian/errmsg.txt20
-rw-r--r--sql/share/italian/errmsg.txt20
-rw-r--r--sql/share/japanese/errmsg.txt20
-rw-r--r--sql/share/korean/errmsg.txt20
-rw-r--r--sql/share/norwegian-ny/errmsg.txt20
-rw-r--r--sql/share/norwegian/errmsg.txt20
-rw-r--r--sql/share/polish/errmsg.txt20
-rw-r--r--sql/share/portuguese/errmsg.txt18
-rw-r--r--sql/share/romanian/errmsg.txt18
-rw-r--r--sql/share/russian/errmsg.txt18
-rw-r--r--sql/share/slovak/errmsg.txt20
-rw-r--r--sql/share/spanish/errmsg.txt20
-rw-r--r--sql/share/swedish/errmsg.OLD20
-rw-r--r--sql/share/swedish/errmsg.txt22
-rw-r--r--sql/share/ukrainian/errmsg.txt18
-rw-r--r--sql/slave.cc2850
-rw-r--r--sql/slave.h429
-rw-r--r--sql/sql_acl.cc803
-rw-r--r--sql/sql_acl.h103
-rw-r--r--sql/sql_analyse.cc72
-rw-r--r--sql/sql_analyse.h37
-rw-r--r--sql/sql_base.cc396
-rw-r--r--sql/sql_cache.cc3499
-rw-r--r--sql/sql_cache.h406
-rw-r--r--sql/sql_class.cc206
-rw-r--r--sql/sql_class.h486
-rw-r--r--sql/sql_crypt.cc6
-rw-r--r--sql/sql_crypt.h6
-rw-r--r--sql/sql_db.cc263
-rw-r--r--sql/sql_delete.cc592
-rw-r--r--sql/sql_do.cc2
-rw-r--r--sql/sql_handler.cc278
-rw-r--r--sql/sql_insert.cc152
-rw-r--r--sql/sql_lex.cc120
-rw-r--r--sql/sql_lex.h138
-rw-r--r--sql/sql_list.cc8
-rw-r--r--sql/sql_list.h96
-rw-r--r--sql/sql_load.cc156
-rw-r--r--sql/sql_manager.cc8
-rw-r--r--sql/sql_map.cc6
-rw-r--r--sql/sql_map.h6
-rw-r--r--sql/sql_olap.cc194
-rw-r--r--sql/sql_parse.cc1983
-rw-r--r--sql/sql_rename.cc29
-rw-r--r--sql/sql_repl.cc963
-rw-r--r--sql/sql_repl.h55
-rw-r--r--sql/sql_select.cc1951
-rw-r--r--sql/sql_select.h40
-rw-r--r--sql/sql_show.cc391
-rw-r--r--sql/sql_sort.h55
-rw-r--r--sql/sql_string.cc128
-rw-r--r--sql/sql_string.h30
-rw-r--r--sql/sql_table.cc557
-rw-r--r--sql/sql_test.cc21
-rw-r--r--sql/sql_udf.cc17
-rw-r--r--sql/sql_udf.h6
-rw-r--r--sql/sql_union.cc287
-rw-r--r--sql/sql_update.cc544
-rw-r--r--sql/sql_yacc.yy2239
-rw-r--r--sql/stacktrace.c18
-rw-r--r--sql/structs.h57
-rw-r--r--sql/table.cc69
-rw-r--r--sql/table.h46
-rw-r--r--sql/thr_malloc.cc10
-rw-r--r--sql/time.cc61
-rw-r--r--sql/udf_example.cc16
-rw-r--r--sql/uniques.cc166
-rw-r--r--sql/unireg.cc25
-rw-r--r--sql/unireg.h20
-rw-r--r--sql/violite.c443
-rw-r--r--strings/Makefile.am4
-rw-r--r--strings/atof.c31
-rw-r--r--strings/bchange.c34
-rw-r--r--strings/bcmp.c48
-rw-r--r--strings/bcopy-duff.c29
-rw-r--r--strings/bfill.c2
-rw-r--r--strings/bmove.c2
-rw-r--r--strings/bmove512.c31
-rw-r--r--strings/bmove_upp.c31
-rw-r--r--strings/bzero.c16
-rw-r--r--strings/conf_to_src.c29
-rw-r--r--strings/ctype-big5.c31
-rw-r--r--strings/ctype-czech.c33
-rw-r--r--strings/ctype-euc_kr.c31
-rw-r--r--strings/ctype-gb2312.c31
-rw-r--r--strings/ctype-gbk.c35
-rw-r--r--strings/ctype-latin1_de.c361
-rw-r--r--strings/ctype-sjis.c31
-rw-r--r--strings/ctype-tis620.c48
-rw-r--r--strings/ctype-ujis.c2
-rw-r--r--strings/ctype.c33
-rw-r--r--strings/do_ctype.c31
-rw-r--r--strings/int2str.c31
-rw-r--r--strings/is_prefix.c31
-rw-r--r--strings/llstr.c31
-rw-r--r--strings/longlong2str.c31
-rw-r--r--strings/memcmp.c29
-rw-r--r--strings/memcpy.c29
-rw-r--r--strings/memset.c18
-rw-r--r--strings/r_strinstr.c31
-rw-r--r--strings/str2int.c34
-rw-r--r--strings/str_test.c31
-rw-r--r--strings/strappend.c33
-rw-r--r--strings/strcat.c16
-rw-r--r--strings/strcend.c31
-rw-r--r--strings/strchr.c16
-rw-r--r--strings/strcmp.c16
-rw-r--r--strings/strcont.c31
-rw-r--r--strings/strend.c2
-rw-r--r--strings/strfill.c31
-rw-r--r--strings/strings-not-used.h18
-rw-r--r--strings/strinstr.c31
-rw-r--r--strings/strlen.c16
-rw-r--r--strings/strmake.c31
-rw-r--r--strings/strmov.c31
-rw-r--r--strings/strnlen.c31
-rw-r--r--strings/strnmov.c31
-rw-r--r--strings/strrchr.c16
-rw-r--r--strings/strstr.c2
-rw-r--r--strings/strto.c31
-rw-r--r--strings/strtol.c31
-rw-r--r--strings/strtoll.c31
-rw-r--r--strings/strtoul.c31
-rw-r--r--strings/strtoull.c31
-rw-r--r--strings/strxmov.c2
-rw-r--r--strings/strxnmov.c2
-rw-r--r--strings/t_ctype.h20
-rw-r--r--strings/udiv.c31
-rw-r--r--support-files/binary-configure.sh2
-rwxr-xr-xsupport-files/build-tags9
-rw-r--r--support-files/my-huge.cnf.sh19
-rw-r--r--support-files/mysql-max.spec.sh4
-rw-r--r--support-files/mysql-multi.server.sh8
-rw-r--r--support-files/mysql.server.sh22
-rw-r--r--support-files/mysql.spec.sh301
-rwxr-xr-xtests/fork2_test.pl2
-rwxr-xr-xtests/fork_big.pl2
-rw-r--r--tests/grant.pl75
-rw-r--r--tests/grant.res72
-rwxr-xr-xtests/insert_and_repair.pl2
-rwxr-xr-xtests/mail_to_db.pl110
-rw-r--r--tests/myisam-big-rows.tst72
-rwxr-xr-xtests/rename_test.pl2
-rwxr-xr-xtests/test_delayed_insert.pl2
-rwxr-xr-xtests/truncate.pl125
-rw-r--r--tools/Makefile.am20
-rw-r--r--tools/managertest1.nc16
-rw-r--r--tools/mysqlmanager-sample.pwd1
-rw-r--r--tools/mysqlmanager.c1848
-rw-r--r--vio/Makefile.am27
-rw-r--r--vio/Vio.cc23
-rw-r--r--vio/Vio.h64
-rw-r--r--vio/VioAcceptorFd.cc18
-rw-r--r--vio/VioAcceptorFd.h23
-rw-r--r--vio/VioConnectorFd.cc22
-rw-r--r--vio/VioConnectorFd.h19
-rw-r--r--vio/VioFd.cc156
-rw-r--r--vio/VioFd.h38
-rw-r--r--vio/VioPipe.cc25
-rw-r--r--vio/VioPipe.h38
-rw-r--r--vio/VioSSL.cc292
-rw-r--r--vio/VioSSL.h54
-rw-r--r--vio/VioSSLAcceptorFd.cc4
-rw-r--r--vio/VioSSLFactoriesFd.cc360
-rw-r--r--vio/VioSSLFactoriesFd.h64
-rw-r--r--vio/VioSocket.cc326
-rw-r--r--vio/VioSocket.h55
-rw-r--r--vio/test-ssl.c147
-rw-r--r--vio/test-sslclient.c105
-rw-r--r--vio/test-sslserver.c159
-rw-r--r--vio/version.cc7
-rw-r--r--vio/vio-global.h33
-rw-r--r--vio/vio.c132
-rw-r--r--vio/vioelitexx.cc26
-rw-r--r--vio/violite.h101
-rw-r--r--vio/viosocket.c327
-rw-r--r--vio/viossl.c360
-rw-r--r--vio/viosslfactories.c352
-rw-r--r--vio/viotest-ssl.c156
-rw-r--r--vio/viotest-ssl.cc104
-rw-r--r--vio/viotypes.h32
2218 files changed, 252030 insertions, 137376 deletions
diff --git a/.bzrignore b/.bzrignore
index 05b31187d09..811cd82d56c 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -7,6 +7,7 @@
*.la
*.lo
*.o
+*.reject
*.spec
*/*_pure_*warnings
*/.pure
@@ -20,6 +21,8 @@
.out
.snprj/*
.vimrc
+50
+=6
BitKeeper/etc/config
BitKeeper/etc/csets
BitKeeper/etc/csets-in
@@ -32,11 +35,14 @@ BitKeeper/tmp/bkr3sAHD
BitKeeper/tmp/gone
COPYING
COPYING.LIB
+Docs/#manual.texi#
Docs/INSTALL-BINARY
Docs/include.texi
+Docs/internals.info
Docs/manual.aux
Docs/manual.cp
Docs/manual.cps
+Docs/manual.de.log
Docs/manual.dvi
Docs/manual.fn
Docs/manual.fns
@@ -54,6 +60,10 @@ Docs/manual_letter.ps
Docs/manual_toc.html
Docs/my_sys.doc
Docs/mysql.info
+Docs/mysql.xml
+Docs/safe-mysql.xml
+Docs/tex.fmt
+Docs/texi2dvi.out
INSTALL-SOURCE
Logs/*
MIRRORS
@@ -115,17 +125,32 @@ bdb/dist/template/rec_txn
bdb/examples_java
bdb/hash/hash_auto.c
bdb/include/btree_auto.h
+bdb/include/btree_ext.h
+bdb/include/clib_ext.h
+bdb/include/common_ext.h
bdb/include/crdel_auto.h
bdb/include/db_auto.h
+bdb/include/db_ext.h
bdb/include/db_server.h
+bdb/include/env_ext.h
bdb/include/gen_client_ext.h
bdb/include/gen_server_ext.h
bdb/include/hash_auto.h
+bdb/include/hash_ext.h
+bdb/include/lock_ext.h
bdb/include/log_auto.h
+bdb/include/log_ext.h
+bdb/include/mp_ext.h
+bdb/include/mutex_ext.h
+bdb/include/os_ext.h
bdb/include/qam_auto.h
+bdb/include/qam_ext.h
bdb/include/rpc_client_ext.h
bdb/include/rpc_server_ext.h
+bdb/include/tcl_ext.h
bdb/include/txn_auto.h
+bdb/include/txn_ext.h
+bdb/include/xa_ext.h
bdb/java/src/com/sleepycat/db/DbConstants.java
bdb/log/log_auto.c
bdb/qam/qam_auto.c
@@ -151,6 +176,8 @@ client/mysqlbinlog
client/mysqlcheck
client/mysqldump
client/mysqlimport
+client/mysqlmanager-pwgen
+client/mysqlmanagerc
client/mysqlshow
client/mysqltest
client/mysys_priv.h
@@ -168,6 +195,7 @@ db-*.*.*
dbug/user.t
extra/comp_err
extra/my_print_defaults
+extra/mysql_install
extra/perror
extra/replace
extra/resolve_stack_dump
@@ -179,6 +207,8 @@ include/my_config.h
include/my_global.h
include/mysql_version.h
include/widec.h
+innobase/conftest.s1
+innobase/conftest.subs
innobase/ib_config.h
innobase/ib_config.h.in
isam/isamchk
@@ -196,12 +226,115 @@ libmysql_r/acconfig.h
libmysql_r/conf_to_src
libmysql_r/my_static.h
libmysql_r/mysys_priv.h
+libmysqld/backup_dir
+libmysqld/convert.cc
+libmysqld/derror.cc
+libmysqld/errmsg.c
+libmysqld/examples/completion_hash.cc
+libmysqld/examples/completion_hash.h
+libmysqld/examples/link_sources
+libmysqld/examples/my_readline.h
+libmysqld/examples/mysql
+libmysqld/examples/mysql.cc
+libmysqld/examples/mysqltest
+libmysqld/examples/mysqltest.c
+libmysqld/examples/readline.cc
+libmysqld/examples/sql_string.cc
+libmysqld/examples/sql_string.h
+libmysqld/examples/test-gdbinit
+libmysqld/field.cc
+libmysqld/field_conv.cc
+libmysqld/filesort.cc
+libmysqld/get_password.c
+libmysqld/ha_berkeley.cc
+libmysqld/ha_heap.cc
+libmysqld/ha_innobase.cc
+libmysqld/ha_innodb.cc
+libmysqld/ha_isam.cc
+libmysqld/ha_isammrg.cc
+libmysqld/ha_myisam.cc
+libmysqld/ha_myisammrg.cc
+libmysqld/handler.cc
+libmysqld/hash_filo.cc
+libmysqld/hostname.cc
+libmysqld/init.cc
+libmysqld/item.cc
+libmysqld/item_buff.cc
+libmysqld/item_cmpfunc.cc
+libmysqld/item_create.cc
+libmysqld/item_func.cc
+libmysqld/item_strfunc.cc
+libmysqld/item_sum.cc
+libmysqld/item_timefunc.cc
+libmysqld/item_uniq.cc
+libmysqld/key.cc
+libmysqld/lock.cc
+libmysqld/log.cc
+libmysqld/log_event.cc
+libmysqld/md5.c
+libmysqld/mf_iocache.cc
+libmysqld/mini_client.cc
+libmysqld/net_pkg.cc
+libmysqld/net_serv.cc
+libmysqld/opt_ft.cc
+libmysqld/opt_range.cc
+libmysqld/opt_sum.cc
+libmysqld/password.c
+libmysqld/procedure.cc
+libmysqld/records.cc
+libmysqld/repl_failsafe.cc
+libmysqld/simple-test
+libmysqld/slave.cc
+libmysqld/sql_acl.cc
+libmysqld/sql_analyse.cc
+libmysqld/sql_base.cc
+libmysqld/sql_cache.cc
+libmysqld/sql_class.cc
+libmysqld/sql_command
+libmysqld/sql_crypt.cc
+libmysqld/sql_db.cc
+libmysqld/sql_delete.cc
+libmysqld/sql_do.cc
+libmysqld/sql_handler.cc
+libmysqld/sql_insert.cc
+libmysqld/sql_lex.cc
+libmysqld/sql_list.cc
+libmysqld/sql_load.cc
+libmysqld/sql_manager.cc
+libmysqld/sql_map.cc
+libmysqld/sql_parse.cc
+libmysqld/sql_rename.cc
+libmysqld/sql_repl.cc
+libmysqld/sql_select.cc
+libmysqld/sql_show.cc
+libmysqld/sql_string.cc
+libmysqld/sql_table.cc
+libmysqld/sql_test.cc
+libmysqld/sql_udf.cc
+libmysqld/sql_union.cc
+libmysqld/sql_unions.cc
+libmysqld/sql_update.cc
+libmysqld/sql_yacc.cc
+libmysqld/stacktrace.c
+libmysqld/table.cc
+libmysqld/thr_malloc.cc
+libmysqld/time.cc
+libmysqld/uniques.cc
+libmysqld/unireg.cc
libtool
linked_client_sources
linked_include_sources
linked_libmysql_r_sources
linked_libmysql_sources
+linked_libmysqld_sources
+linked_libmysqldex_sources
linked_server_sources
+linked_tools_sources
+locked
+mit-pthreads/config.flags
+mit-pthreads/syscall.S
+myisam/FT1.MYD
+myisam/FT1.MYI
myisam/ft_dump
myisam/ft_eval
myisam/ft_test1
@@ -214,20 +347,34 @@ myisam/myisamlog
myisam/myisampack
myisam/test1.MYD
myisam/test1.MYI
+mysql-4.0.2-alpha-pc-linux-gnu-i686.tar.gz
+mysql-4.0.2-alpha.tar.gz
+mysql-max-4.0.2-alpha-pc-linux-gnu-i686.tar.gz
mysql-test/gmon.out
mysql-test/install_test_db
mysql-test/mysql-test-run
mysql-test/r/*.reject
+mysql-test/r/rpl000001.eval
+mysql-test/r/rpl000002.eval
+mysql-test/r/rpl000014.eval
+mysql-test/r/rpl000015.eval
+mysql-test/r/rpl000016.eval
+mysql-test/r/rpl_log.eval
+mysql-test/r/slave-running.eval
+mysql-test/r/slave-stopped.eval
mysql-test/share/mysql
mysql-test/var/*
mysql.kdevprj
mysql.proj
mysqld.S
mysqld.sym
+mysys/#mf_iocache.c#
mysys/test_charset
mysys/test_dir
+mysys/test_io_cache
mysys/test_thr_alarm
mysys/test_thr_lock
+mysys/test_vsnprintf
mysys/testhash
regex/re
repl-tests/test-repl-ts/repl-timestamp.master.reject
@@ -239,7 +386,9 @@ scripts/make_binary_distribution
scripts/msql2mysql
scripts/mysql_config
scripts/mysql_convert_table_format
+scripts/mysql_explain_log
scripts/mysql_find_rows
+scripts/mysql_fix_extensions
scripts/mysql_fix_privilege_tables
scripts/mysql_install_db
scripts/mysql_setpermission
@@ -247,10 +396,12 @@ scripts/mysql_zap
scripts/mysqlaccess
scripts/mysqlbug
scripts/mysqld_multi
+scripts/mysqld_safe
scripts/mysqldumpslow
scripts/mysqlhotcopy
scripts/safe_mysqld
sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
+sql-bench/bench-count-distinct
sql-bench/bench-init.pl
sql-bench/compare-results
sql-bench/compare-results-all
@@ -269,6 +420,7 @@ sql-bench/test-connect
sql-bench/test-create
sql-bench/test-insert
sql-bench/test-select
+sql-bench/test-transactions
sql-bench/test-wisconsin
sql/.gdbinit
sql/gen_lex_hash
@@ -277,11 +429,17 @@ sql/lex_hash.h
sql/mini_client_errors.c
sql/mysqlbinlog
sql/mysqld
+sql/mysqld-purecov
+sql/mysqld-purify
+sql/mysqld-quantify
+sql/new.cc
sql/share/*.sys
sql/share/charsets/gmon.out
sql/share/gmon.out
+sql/share/mysql
sql/share/norwegian-ny/errmsg.sys
sql/share/norwegian/errmsg.sys
+sql/sql_select.cc.orig
sql/sql_yacc.cc
sql/sql_yacc.h
stamp-h
@@ -303,7 +461,25 @@ support-files/mysql.server
support-files/mysql.spec
tags
tmp/*
-bdb/include/db_ext.h
-bdb/include/mutex_ext.h
-mit-pthreads/syscall.S
-mit-pthreads/config.flags
+tools/my_vsnprintf.c
+tools/mysqlmanager
+tools/mysqlmngd
+tools/mysys_priv.h
+vio/test-ssl
+vio/test-sslclient
+vio/test-sslserver
+vio/viotest-ssl
+mysys/getopt.c
+mysys/getopt1.c
+scripts/mysql_secure_installation
+mit-pthreads/include/bits
+mit-pthreads/include/pthread/machdep.h
+mit-pthreads/include/pthread/posix.h
+mit-pthreads/include/sys
+mit-pthreads/machdep.c
+mit-pthreads/pg++
+mit-pthreads/pgcc
+scripts/mysql_tableinfo
+libmysql/net.c
+libmysqld/sql_olap.cc
+myisam/myisam.log
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh
index fbeaf1e3c68..82f31a14dc4 100644
--- a/BUILD/FINISH.sh
+++ b/BUILD/FINISH.sh
@@ -1,5 +1,6 @@
cflags="$c_warnings $extra_flags"
cxxflags="$cxx_warnings $base_cxxflags $extra_flags"
+extra_configs="$extra_configs $local_infile_configs"
configure="./configure $base_configs $extra_configs"
for arg
do
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
new file mode 100644
index 00000000000..438b3a528cd
--- /dev/null
+++ b/BUILD/Makefile.am
@@ -0,0 +1,44 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+
+## Process this file with automake to create Makefile.in
+
+EXTRA_DIST = FINISH.sh \
+ SETUP.sh \
+ compile-alpha \
+ compile-alpha-ccc \
+ compile-alpha-cxx \
+ compile-alpha-debug \
+ compile-ia64-debug-max \
+ compile-pentium \
+ compile-pentium-debug \
+ compile-pentium-debug-max \
+ compile-pentium-debug-no-bdb \
+ compile-pentium-debug-openssl \
+ compile-pentium-gcov \
+ compile-pentium-gprof \
+ compile-pentium-max \
+ compile-pentium-myodbc \
+ compile-pentium-mysqlfs-debug \
+ compile-pentium-pgcc \
+ compile-solaris-sparc \
+ compile-solaris-sparc-debug \
+ compile-solaris-sparc-fortre \
+ compile-solaris-sparc-purify
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 52fe960e3a5..68ef3fb6977 100644
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -48,7 +48,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer"
# this is one is for someone who thinks 1% speedup is worth not being
# able to backtrace
reckless_cflags="-O3 -fomit-frame-pointer "
-debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DSAFE_MUTEX -O1"
+debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -O1"
base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti"
@@ -57,6 +57,10 @@ static_link="--with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static
alpha_configs="" # Not used yet
pentium_configs=""
sparc_configs=""
+# we need local-infile in all binaries for rpl000001
+# if you need to disable local-infile in the client, write a build script
+# and unset local_infile_configs
+local_infile_configs="--enable-local-infile"
debug_configs="--with-debug"
diff --git a/BUILD/compile-alpha-cxx b/BUILD/compile-alpha-cxx
index 2992604644b..3e6eee9a0d6 100755
--- a/BUILD/compile-alpha-cxx
+++ b/BUILD/compile-alpha-cxx
@@ -1,17 +1,17 @@
/bin/rm -f */.deps/*.P */*.o
make -k clean
/bin/rm -f */.deps/*.P */*.o
-/bin/rm -f config.cache mysql-*.tar.gz
+/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache mysql-*.tar.gz
aclocal; autoheader; aclocal; automake; autoconf
-CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
+CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared --without-extra-tools
-make
-rm */.deps/*
+make -j2
+find . -name ".deps" | xargs rm -r
make
if [ $? = 0 ]
then
- rm */.deps/*
+ find . -name ".deps" | xargs rm -r
bin/mysqladmin shutdown
sur make install
if [ $? = 0 ]
diff --git a/BUILD/compile-alpha-debug b/BUILD/compile-alpha-debug
index 6672027445e..60d1b9af659 100755
--- a/BUILD/compile-alpha-debug
+++ b/BUILD/compile-alpha-debug
@@ -1,7 +1,8 @@
+/bin/rm -f */.deps/*.P */*.o
make -k clean
-/bin/rm -f */.deps/*.P
-/bin/rm -f config.cache
+/bin/rm -f */.deps/*.P */*.o
+/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache mysql-*.tar.gz
aclocal; autoheader; aclocal; automake; autoconf
-CFLAGS=-O6 CXX=gcc CXXFLAGS="-O6 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug
+CFLAGS=-O1 CC=gcc CXX=gcc CXXFLAGS="-O1 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex --without-extra-tools
make
diff --git a/BUILD/compile-ia64-debug-max b/BUILD/compile-ia64-debug-max
new file mode 100755
index 00000000000..9cd54de428d
--- /dev/null
+++ b/BUILD/compile-ia64-debug-max
@@ -0,0 +1,13 @@
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache
+
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+ (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+
+CC=ecc CFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" CXX=ecc CXXFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static --with-debug --with-innodb --with-embedded-server
+gmake
diff --git a/BUILD/compile-pentium-debug b/BUILD/compile-pentium-debug
index 7d25ac4a406..d8a6b60809b 100755
--- a/BUILD/compile-pentium-debug
+++ b/BUILD/compile-pentium-debug
@@ -6,7 +6,7 @@ path=`dirname $0`
extra_flags="$pentium_cflags $debug_cflags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
-extra_configs="$pentium_configs $debug_configs"
+extra_configs="$pentium_configs $debug_configs $static_link"
extra_configs="$extra_configs "
diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max
index 993c48565b8..1684686ce8c 100755
--- a/BUILD/compile-pentium-debug-max
+++ b/BUILD/compile-pentium-debug-max
@@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs"
-extra_configs="$extra_configs --with-berkeley-db --with-innodb --enable-local-infile"
+extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server --with-openssl"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-debug-no-bdb b/BUILD/compile-pentium-debug-no-bdb
index fad58bec437..d7e70f868cc 100755
--- a/BUILD/compile-pentium-debug-no-bdb
+++ b/BUILD/compile-pentium-debug-no-bdb
@@ -4,6 +4,6 @@ path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $debug_cflags"
-extra_configs="$pentium_configs $debug_configs --without-berkeley-db"
+extra_configs="$pentium_configs $debug_configs --without-berkeley-db $static_link"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-debug-openssl b/BUILD/compile-pentium-debug-openssl
new file mode 100755
index 00000000000..5de1c18a5d7
--- /dev/null
+++ b/BUILD/compile-pentium-debug-openssl
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium_cflags $debug_cflags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$pentium_configs $debug_configs"
+
+extra_configs="$extra_configs --with-debug=full --with-vio --with-openssl --without-innodb"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-gcov b/BUILD/compile-pentium-gcov
index 873d1d0d8e8..05cb0bb0d78 100755
--- a/BUILD/compile-pentium-gcov
+++ b/BUILD/compile-pentium-gcov
@@ -3,7 +3,8 @@
path=`dirname $0`
. "$path/SETUP.sh"
-extra_flags="$pentium_cflags -O2 -fprofile-arcs -ftest-coverage"
+extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage"
extra_configs="$pentium_configs $debug_configs --disable-shared $static_link"
+extra_configs="$extra_configs --with-innodb --with-berkeley-db"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-max b/BUILD/compile-pentium-max
index 55f88ef4748..d41274d4f5e 100755
--- a/BUILD/compile-pentium-max
+++ b/BUILD/compile-pentium-max
@@ -8,6 +8,7 @@ extra_configs="$pentium_configs"
strip=yes
extra_configs="$extra_configs --with-innodb --with-berkeley-db \
- --enable-thread-safe-client"
+ --with-embedded-server --enable-thread-safe-client \
+ --with-openssl --with-vio"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-mysqlfs-debug b/BUILD/compile-pentium-mysqlfs-debug
new file mode 100755
index 00000000000..6643553d943
--- /dev/null
+++ b/BUILD/compile-pentium-mysqlfs-debug
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium_cflags $debug_cflags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$pentium_configs $debug_configs $static_link"
+
+extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server --without-pstack"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-pgcc b/BUILD/compile-pentium-pgcc
index ee70fd2bde0..2d806009b21 100755
--- a/BUILD/compile-pentium-pgcc
+++ b/BUILD/compile-pentium-pgcc
@@ -1,10 +1,21 @@
AM_MAKEFLAGS="-j 2"
-make -k clean
+gmake -k clean || true
/bin/rm -f */.deps/*.P config.cache
-
-aclocal; autoheader; aclocal; automake; autoconf
-
+
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+ (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+
export PATH=/usr/local/pgcc/bin:$PATH
-CFLAGS="-O6 -mpentiumpro -fomit-frame-pointer -mstack-align-double" CXX=gcc CXXFLAGS="-O6 -mpentiumpro -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -mstack-align-double" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charsets=complex --enable-thread-safe-client
-make -j 2
+CFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O6 -mpentiumpro -fomit-frame-pointer -mstack-align-double" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O6 -fomit-frame-pointer -mpentiumpro -mstack-align-double" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static
+
+gmake -j 4
+
+mkdir -p tmp
+nm --numeric-sort sql/mysqld > tmp/mysqld.sym
+objdump -d sql/mysqld > tmp/mysqld.S
strip sql/mysqld
diff --git a/BUILD/compile-pentium-symbols b/BUILD/compile-pentium-symbols
deleted file mode 100755
index 4f63763606f..00000000000
--- a/BUILD/compile-pentium-symbols
+++ /dev/null
@@ -1,15 +0,0 @@
-#! /bin/sh
-
-path=`dirname $0`
-. "$path/SETUP.sh"
-
-extra_flags="$pentium_cflags $fast_cflags -g"
-extra_configs="$pentium_configs"
-
-# Use the optimized version if it exists
-if test -d /usr/local/BerkeleyDB-opt/
-then
- extra_configs="$extra_configs --with-berkeley-db=/usr/local/BerkeleyDB-opt/"
-fi
-
-. "$path/FINISH.sh"
diff --git a/BUILD/compile-solaris-sparc b/BUILD/compile-solaris-sparc
index f8f7c8755df..083a6e3d68e 100755
--- a/BUILD/compile-solaris-sparc
+++ b/BUILD/compile-solaris-sparc
@@ -11,6 +11,6 @@ then
(cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
fi
-CFLAGS="-g -Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
gmake -j 4
diff --git a/BUILD/compile-solaris-sparc-debug b/BUILD/compile-solaris-sparc-debug
new file mode 100755
index 00000000000..527f135ac62
--- /dev/null
+++ b/BUILD/compile-solaris-sparc-debug
@@ -0,0 +1,16 @@
+#! /bin/sh
+
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache
+
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+ (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug
+
+gmake -j 4
diff --git a/BUILD/compile-solaris-sparc-purify b/BUILD/compile-solaris-sparc-purify
index 8bb53bba876..2fb5c88cd7b 100755
--- a/BUILD/compile-solaris-sparc-purify
+++ b/BUILD/compile-solaris-sparc-purify
@@ -1,17 +1,30 @@
#! /bin/sh
+
+while test $# -gt 0
+do
+ case "$1" in
+ --debug) EXTRA_CONFIG_FLAGS=--with-debug; shift ;;
+ -h | --help ) cat <<EOF; exit 0 ;;
+Usage: $0 [-h|-n] [configure-options]
+ --debug Compile with DBUG enabled
+EOF
+ *) echo "No such option '$1'" ; exit ;;
+ esac
+done
+
gmake -k clean || true
/bin/rm -f */.deps/*.P config.cache
-
aclocal && autoheader && aclocal && automake && autoconf
(cd bdb/dist && sh s_all)
(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
-CFLAGS="-g -Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_purify -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_purify -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-berkeley-db --with-innodb
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_purify -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_purify -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-berkeley-db --with-innodb $EXTRA_CONFIG_FLAGS
gmake -j 4
-cd sql ; rm mysqld ;
+cd sql ; mv mysqld mysqld-org ;
make CXXLD="purify -best-effort g++" mysqld ; mv mysqld mysqld-purify
make CXXLD="quantify -best-effort g++" mysqld ; mv mysqld mysqld-quantify
make CXXLD="purecov -best-effort g++" mysqld ; mv mysqld mysqld-purecov
+mv mysqld-org mysqld
diff --git a/BitKeeper/etc/config b/BitKeeper/etc/config
index 257f193723f..85b5a871301 100644
--- a/BitKeeper/etc/config
+++ b/BitKeeper/etc/config
@@ -68,4 +68,5 @@ pager:
#
hours:
[serg:]checkout:get
+[arjen:]checkout:get
checkout:edit
diff --git a/BitKeeper/etc/gone b/BitKeeper/etc/gone
index b952e8e0780..21b75953bbb 100644
--- a/BitKeeper/etc/gone
+++ b/BitKeeper/etc/gone
@@ -4,11 +4,44 @@ BK|config.h.in|19700101030959|00050|aecae693cca472c
BK|include/my_global.h|19700101030959|00105|f657f708961a4632
BK|libmysql/acconfig.h|19700101030959|02604|7b620dbd69ea6074
BK|mit-pthreads/config.flags|19700101030959|00594|dcec5296ef811cd6
+BK|mit-pthreads/machdep/i386-sco-3.2v5/__math.h|19700101030959|01011|79d9a37715f2c7fe
+BK|mit-pthreads/machdep/i386-sco-3.2v5/__signal.h|19700101030959|01012|45332b2a56f62580
+BK|mit-pthreads/machdep/i386-sco-3.2v5/__stdio.h|19700101030959|01013|a81562134446c64c
+BK|mit-pthreads/machdep/i386-sco-3.2v5/__stdlib.h|19700101030959|01014|bcbed6d62d1885ae
+BK|mit-pthreads/machdep/i386-sco-3.2v5/__string.h|19700101030959|01015|94a2e4f9574bf1e8
+BK|mit-pthreads/machdep/i386-sco-3.2v5/__time.h|19700101030959|01016|2cde57d8feea7fc8
+BK|mit-pthreads/machdep/i386-sco-3.2v5/__unistd.h|19700101030959|01017|5cc4575b5a74066f
+BK|mit-pthreads/machdep/i386-sco-3.2v5/compat.h|19700101030959|01018|1f7e450a2e18603e
+BK|mit-pthreads/machdep/i386-sco-3.2v5/dirent.h|19700101030959|01019|13608bf11af98f70
+BK|mit-pthreads/machdep/i386-sco-3.2v5/posix/__signal.h|19700101030959|01024|9bb7b240bec88b2d
+BK|mit-pthreads/machdep/i386-sco-3.2v5/socket.h|19700101030959|01020|9f78f7e5a7b4a83f
+BK|mit-pthreads/machdep/i386-sco-3.2v5/syscall.h|19700101030959|01021|d9543a0474656339
+BK|mit-pthreads/machdep/i386-sco-3.2v5/timers.h|19700101030959|01022|d5e694e48990538c
+BK|mit-pthreads/machdep/i386-sco-3.2v5/trash.can|19700101030959|01023|9332039abd82a925
+BK|mit-pthreads/machdep/sco-3.2v5/__math.h|19700101030959|00971|f3855eb411435a06
+BK|mit-pthreads/machdep/sco-3.2v5/__signal.h|19700101030959|00972|3d6f84e96bc1462
+BK|mit-pthreads/machdep/sco-3.2v5/__stdio.h|19700101030959|00973|b991fad3327275e0
+BK|mit-pthreads/machdep/sco-3.2v5/__stdlib.h|19700101030959|00974|6179a0922d90025e
+BK|mit-pthreads/machdep/sco-3.2v5/__string.h|19700101030959|00975|d2cc42eeb5e1666
+BK|mit-pthreads/machdep/sco-3.2v5/__time.h|19700101030959|00976|a9594bab280ced64
+BK|mit-pthreads/machdep/sco-3.2v5/__unistd.h|19700101030959|00977|99e6f1116d1f920
+BK|mit-pthreads/machdep/sco-3.2v5/compat.h|19700101030959|00978|3f150ff6223d49be
+BK|mit-pthreads/machdep/sco-3.2v5/dirent.h|19700101030959|00979|388af3465ad4680f
+BK|mit-pthreads/machdep/sco-3.2v5/posix/__signal.h|19700101030959|00984|5e14827a3b91a6db
+BK|mit-pthreads/machdep/sco-3.2v5/socket.h|19700101030959|00980|1b409f3f1fcbbf7a
+BK|mit-pthreads/machdep/sco-3.2v5/syscall.h|19700101030959|00981|c69bd58eba4d5076
+BK|mit-pthreads/machdep/sco-3.2v5/timers.h|19700101030959|00982|4907a958151368ed
+BK|mit-pthreads/machdep/sco-3.2v5/trash.can|19700101030959|00983|7eecac9fc944ade2
BK|myisam/common_words|19700101030959|01665|13c10ef32aaa7537
BK|myisam/mi_test_all|19700101030959|01666|ae7a366c45527b4e
BK|mysys/mf_reccache.c|19700101030959|01419|f8191c8485e158fe
+BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02361|6a0a837742a861bb
+BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686|19700101030959|02348|e87091e2a6dce931
+BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02326|70981cb1dd58d3fb
+BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02327|67957b2b80839c59
BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.2.12_20smp_i686|19700101030959|02437|28211fb9f0e6ab0e
BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02438|136bdd9fd1a2cd14
+BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02362|20e8179c6f87930d
BK|sql-bench/Results-linux/ATIS-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02443|defb62af5958fcac
BK|sql-bench/Results-linux/Attic/ATIS-mysql-Linux_2.0.33_i586|19700101030959|02381|ef64fcf54c271212
BK|sql-bench/Results-linux/Attic/ATIS-mysql-Linux_dynamic|19700101030959|02382|ffa77bdc262ac10f
@@ -66,29 +99,67 @@ BK|sql-bench/Results-linux/Attic/wisconsin-mysql-Linux_static|19700101030959|024
BK|sql-bench/Results-linux/Attic/wisconsin-mysql_fast-Linux_2.0.33_i586|19700101030959|02434|7d98b33fa6d91a87
BK|sql-bench/Results-linux/Attic/wisconsin-mysql_local_tcp-Linux_2.0.33_i586|19700101030959|02435|28a4840ebd5dd015
BK|sql-bench/Results-linux/Attic/wisconsin-mysql_new-Linux_2.0.33_i586|19700101030959|02436|e1f17edfbee1f22e
+BK|sql-bench/Results-linux/RUN-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02365|5e446b99518aa0b1
+BK|sql-bench/Results-linux/RUN-interbase-Linux_2.2.14_5.0_i686|19700101030959|02351|9a0d8be7d641fae7
+BK|sql-bench/Results-linux/RUN-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02334|5f0504783180d906
+BK|sql-bench/Results-linux/RUN-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02335|6abba8bd8d9f8b7b
BK|sql-bench/Results-linux/RUN-mysql-Linux_2.2.12_20smp_i686|19700101030959|02328|da28ced3e0aac09c
BK|sql-bench/Results-linux/RUN-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02329|f6fa9f46d4a6152
+BK|sql-bench/Results-linux/RUN-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02366|730674f4ac333638
BK|sql-bench/Results-linux/RUN-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02444|16694c5927b7600c
+BK|sql-bench/Results-linux/alter-table-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02367|e901749edf05bb58
+BK|sql-bench/Results-linux/alter-table-interbase-Linux_2.2.14_5.0_i686|19700101030959|02352|c4e27f25a15b6681
BK|sql-bench/Results-linux/alter-table-mysql-Linux_2.2.12_20smp_i686|19700101030959|02330|67ae4e91b5f4eabd
BK|sql-bench/Results-linux/alter-table-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02331|c85eb85ba45dd748
+BK|sql-bench/Results-linux/alter-table-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02368|19c95f9fc4ee458
BK|sql-bench/Results-linux/alter-table-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02445|b062db76cf6df5d2
+BK|sql-bench/Results-linux/big-tables-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02371|c0c1c5efea0661ad
+BK|sql-bench/Results-linux/big-tables-interbase-Linux_2.2.14_5.0_i686|19700101030959|02353|beba3adfcfd472c0
+BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02341|cabe523a8f103945
+BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02342|c682fb7ee1fb3d8
BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.2.12_20smp_i686|19700101030959|02332|a2dcb74a3c73ac18
BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02333|b5f4f4c35225f0f
+BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02372|69d33d25eda85041
BK|sql-bench/Results-linux/big-tables-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02446|a9eedd951eab7e8b
+BK|sql-bench/Results-linux/connect-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02373|744f1e38649d21d
+BK|sql-bench/Results-linux/connect-interbase-Linux_2.2.14_5.0_i686|19700101030959|02354|c28534284b9f5657
+BK|sql-bench/Results-linux/connect-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02349|ebdc62367f5fcd43
+BK|sql-bench/Results-linux/connect-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02350|7ed494b7cc7081c9
BK|sql-bench/Results-linux/connect-mysql-Linux_2.2.12_20smp_i686|19700101030959|02336|beedcd769a903c19
BK|sql-bench/Results-linux/connect-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02337|74ec2bf5f55b81f
+BK|sql-bench/Results-linux/connect-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02374|55d777517ce8091
BK|sql-bench/Results-linux/connect-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02447|f6d7665c418d62c6
+BK|sql-bench/Results-linux/create-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02377|d60ca06157cfc9b9
+BK|sql-bench/Results-linux/create-interbase-Linux_2.2.14_5.0_i686|19700101030959|02355|537da98f6c1bc6df
+BK|sql-bench/Results-linux/create-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02356|612a182b889dd778
+BK|sql-bench/Results-linux/create-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02357|b501391eec112dd0
BK|sql-bench/Results-linux/create-mysql-Linux_2.2.12_20smp_i686|19700101030959|02338|fe23ee50aea195f4
BK|sql-bench/Results-linux/create-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02339|771b40d3280fe8ad
+BK|sql-bench/Results-linux/create-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02378|35bd48cfe30c16a3
BK|sql-bench/Results-linux/create-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02448|c46d6c283c0e34ae
+BK|sql-bench/Results-linux/insert-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02379|25161ee7c13036c1
+BK|sql-bench/Results-linux/insert-interbase-Linux_2.2.14_5.0_i686|19700101030959|02358|461a48df25628c0f
+BK|sql-bench/Results-linux/insert-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02363|3260743076dbe95f
+BK|sql-bench/Results-linux/insert-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02364|9de5538694cd87ea
BK|sql-bench/Results-linux/insert-mysql-Linux_2.2.12_20smp_i686|19700101030959|02340|f120b0ead3836c81
BK|sql-bench/Results-linux/insert-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02343|17f262f12d2244bc
+BK|sql-bench/Results-linux/insert-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02380|7451b789c29b7dcd
BK|sql-bench/Results-linux/insert-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02449|3245ba5633a18e8
+BK|sql-bench/Results-linux/select-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02439|816ec12a9152b578
+BK|sql-bench/Results-linux/select-interbase-Linux_2.2.14_5.0_i686|19700101030959|02359|3535cd00c2a9cb5d
+BK|sql-bench/Results-linux/select-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02369|de288cd8c11e1749
+BK|sql-bench/Results-linux/select-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02370|a82e759dbd5d66b
BK|sql-bench/Results-linux/select-mysql-Linux_2.2.12_20smp_i686|19700101030959|02344|3b64aff0dfddfff4
BK|sql-bench/Results-linux/select-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02345|9fd9c6e036f988d7
+BK|sql-bench/Results-linux/select-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02440|862a7c0ef1b17f29
BK|sql-bench/Results-linux/select-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02450|744633c6e13a897f
+BK|sql-bench/Results-linux/wisconsin-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02441|cb767c1f9abc2ebd
+BK|sql-bench/Results-linux/wisconsin-interbase-Linux_2.2.14_5.0_i686|19700101030959|02360|9404247a2e483b34
+BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02375|8669562660b2c238
+BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02376|c7cbe3b167655f9c
BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.12_20smp_i686|19700101030959|02346|d49db545341a732f
BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02347|ad7babd436f26841
+BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02442|74b238eca114dbbe
BK|sql-bench/Results-linux/wisconsin-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02451|6ad065fe4c6b4fa9
BK|sql-bench/Results/ATIS-mysql-Linux_2.2.10_i686|19700101030959|02025|3fa4d167cceff7e8
BK|sql-bench/Results/ATIS-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02312|84ca3b85ff306133
@@ -236,7 +307,44 @@ BK|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|197001
BK|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02270|ef201ca14f635c57
BK|sql/share/romanian/errmsg.sys|19700101030959|01869|9d8282efb437e8cc
BK|sql/share/romanian/errmsg.txt|19700101030959|01870|2c64fb13a8f104ad
+miguel@hegel.local|zlib/Make_vms.com|20020319032513|57151|35050a50ec612bbf
+miguel@hegel.local|zlib/Makefile.riscos|20020319032513|63798|8ab53f195fe429af
+miguel@hegel.local|zlib/amiga/Makefile.pup|20020319032513|19225|6a9ee8128d11541f
+miguel@hegel.local|zlib/amiga/Makefile.sas|20020319032513|25562|d7128ac7e0946f0b
+miguel@hegel.local|zlib/contrib/untgz/makefile.w32|20020319032516|01267|2c584f05a16db4ba
+miguel@hegel.local|zlib/msdos/Makefile.b32|20020319032518|33760|86772037f3344353
+miguel@hegel.local|zlib/msdos/Makefile.bor|20020319032518|40099|7aa9edaac099cdb9
+miguel@hegel.local|zlib/msdos/Makefile.dj2|20020319032518|46371|ca26f5fe96e3e999
+miguel@hegel.local|zlib/msdos/Makefile.emx|20020319032518|52757|64efbf8cedc146b5
+miguel@hegel.local|zlib/msdos/Makefile.msc|20020319032518|59050|1bb69abdddf390f2
+miguel@hegel.local|zlib/msdos/Makefile.tc|20020319032518|65341|2a9dff916115ae77
+miguel@hegel.local|zlib/msdos/Makefile.w32|20020319032518|06083|8d84523c1dcdc0f7
+miguel@hegel.local|zlib/msdos/Makefile.wat|20020319032518|12471|82f8714d825e97e3
+miguel@hegel.local|zlib/nt/Makefile.emx|20020319032518|31715|7e9fcf6f5ad2e51a
+miguel@hegel.local|zlib/nt/Makefile.gcc|20020319032519|03630|351fa8bd15c704b9
+miguel@hegel.local|zlib/nt/Makefile.nt|20020319032519|09990|ee461a3dd393a061
+miguel@hegel.local|zlib/os2/Makefile.os2|20020319032519|22554|7a05f2a27812703a
monty@donna.mysql.com|myisam/mi_debug.c|20000829092809|23459|873a6e7d6ff8297c
+monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|34755|45d7837423db243f
+monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|37262|2274651e29d38b07
+monty@donna.mysql.com|sql-bench/Results-linux/RUN-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|39831|a6ef8229d40b75d1
+monty@donna.mysql.com|sql-bench/Results-linux/RUN-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|42374|65ccbcd7b1c4d7b5
+monty@donna.mysql.com|sql-bench/Results-linux/alter-table-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|44909|de84e4a2fd07f53
+monty@donna.mysql.com|sql-bench/Results-linux/alter-table-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|47422|ee162dd1474ba9d8
+monty@donna.mysql.com|sql-bench/Results-linux/big-tables-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|49948|d11a751a268a4df3
+monty@donna.mysql.com|sql-bench/Results-linux/big-tables-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|52469|c13eca5ec25cd6e1
+monty@donna.mysql.com|sql-bench/Results-linux/connect-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|54998|dfaa50e67eb15556
+monty@donna.mysql.com|sql-bench/Results-linux/connect-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|57532|4015a2bef627d8cd
+monty@donna.mysql.com|sql-bench/Results-linux/create-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|60103|fa19b9a2c7a3c3c
+monty@donna.mysql.com|sql-bench/Results-linux/create-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|62710|21ec8ba1ea3ca4c4
+monty@donna.mysql.com|sql-bench/Results-linux/insert-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|65289|a02aceb3b30de493
+monty@donna.mysql.com|sql-bench/Results-linux/insert-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|02393|7c9baa774fc324e1
+monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|05001|da73eefa16ca9383
+monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|07610|cffd7d282a90113a
+monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|10615|8dcd7271a9137341
+monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|13213|4398328883aa75da
+mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b9394876
+mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b93948768
mwagner@evoq.home.mwagner.org|mysql-test/mybin/start-mysqld|20001016055648|54840|9c8f21a7ab97793a
mwagner@evoq.home.mwagner.org|mysql-test/mybin/stop-mysqld|20001016055653|20710|89a1194045f05d1c
mwagner@evoq.home.mwagner.org|mysql-test/mybin/translate-tests|20001018130217|00206|3869c1fdf0a5ea1a
@@ -315,95 +423,1237 @@ sasha@mysql.sashanet.com|mysql-test/t/include/master-slave.inc|20001118030458|01
sasha@work.mysql.com|BitKeeper/etc/logging_ok|20001214015456|29919|32b6551b8288c2fa
serg@serg.mysql.com|mysql-test/r/3.23/mrg000001.dummy.result|20001206231604|05053|bf7e6d609f22b897
serg@serg.mysql.com|mysql-test/r/3.23/mrg000001.result|20001206231609|46662|db2ef2e717ab8332
-mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b9394876
-mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b93948768
-BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02361|6a0a837742a861bb
-BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686|19700101030959|02348|e87091e2a6dce931
-BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02326|70981cb1dd58d3fb
-BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02327|67957b2b80839c59
-BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02362|20e8179c6f87930d
-BK|sql-bench/Results-linux/RUN-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02365|5e446b99518aa0b1
-BK|sql-bench/Results-linux/RUN-interbase-Linux_2.2.14_5.0_i686|19700101030959|02351|9a0d8be7d641fae7
-BK|sql-bench/Results-linux/RUN-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02334|5f0504783180d906
-BK|sql-bench/Results-linux/RUN-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02335|6abba8bd8d9f8b7b
-BK|sql-bench/Results-linux/RUN-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02366|730674f4ac333638
-BK|sql-bench/Results-linux/alter-table-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02367|e901749edf05bb58
-BK|sql-bench/Results-linux/alter-table-interbase-Linux_2.2.14_5.0_i686|19700101030959|02352|c4e27f25a15b6681
-BK|sql-bench/Results-linux/alter-table-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02368|19c95f9fc4ee458
-BK|sql-bench/Results-linux/big-tables-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02371|c0c1c5efea0661ad
-BK|sql-bench/Results-linux/big-tables-interbase-Linux_2.2.14_5.0_i686|19700101030959|02353|beba3adfcfd472c0
-BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02341|cabe523a8f103945
-BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02342|c682fb7ee1fb3d8
-BK|sql-bench/Results-linux/big-tables-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02372|69d33d25eda85041
-BK|sql-bench/Results-linux/connect-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02373|744f1e38649d21d
-BK|sql-bench/Results-linux/connect-interbase-Linux_2.2.14_5.0_i686|19700101030959|02354|c28534284b9f5657
-BK|sql-bench/Results-linux/connect-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02349|ebdc62367f5fcd43
-BK|sql-bench/Results-linux/connect-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02350|7ed494b7cc7081c9
-BK|sql-bench/Results-linux/connect-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02374|55d777517ce8091
-BK|sql-bench/Results-linux/create-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02377|d60ca06157cfc9b9
-BK|sql-bench/Results-linux/create-interbase-Linux_2.2.14_5.0_i686|19700101030959|02355|537da98f6c1bc6df
-BK|sql-bench/Results-linux/create-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02356|612a182b889dd778
-BK|sql-bench/Results-linux/create-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02357|b501391eec112dd0
-BK|sql-bench/Results-linux/create-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02378|35bd48cfe30c16a3
-BK|sql-bench/Results-linux/insert-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02379|25161ee7c13036c1
-BK|sql-bench/Results-linux/insert-interbase-Linux_2.2.14_5.0_i686|19700101030959|02358|461a48df25628c0f
-BK|sql-bench/Results-linux/insert-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02363|3260743076dbe95f
-BK|sql-bench/Results-linux/insert-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02364|9de5538694cd87ea
-BK|sql-bench/Results-linux/insert-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02380|7451b789c29b7dcd
-BK|sql-bench/Results-linux/select-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02439|816ec12a9152b578
-BK|sql-bench/Results-linux/select-interbase-Linux_2.2.14_5.0_i686|19700101030959|02359|3535cd00c2a9cb5d
-BK|sql-bench/Results-linux/select-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02369|de288cd8c11e1749
-BK|sql-bench/Results-linux/select-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02370|a82e759dbd5d66b
-BK|sql-bench/Results-linux/select-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02440|862a7c0ef1b17f29
-BK|sql-bench/Results-linux/wisconsin-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02441|cb767c1f9abc2ebd
-BK|sql-bench/Results-linux/wisconsin-interbase-Linux_2.2.14_5.0_i686|19700101030959|02360|9404247a2e483b34
-BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02375|8669562660b2c238
-BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.0.33_i586-cmp-ms-sql,mysql,sybase|19700101030959|02376|c7cbe3b167655f9c
-BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02442|74b238eca114dbbe
-monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|34755|45d7837423db243f
-monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|37262|2274651e29d38b07
-monty@donna.mysql.com|sql-bench/Results-linux/RUN-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|39831|a6ef8229d40b75d1
-monty@donna.mysql.com|sql-bench/Results-linux/RUN-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|42374|65ccbcd7b1c4d7b5
-monty@donna.mysql.com|sql-bench/Results-linux/alter-table-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|44909|de84e4a2fd07f53
-monty@donna.mysql.com|sql-bench/Results-linux/alter-table-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|47422|ee162dd1474ba9d8
-monty@donna.mysql.com|sql-bench/Results-linux/big-tables-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|49948|d11a751a268a4df3
-monty@donna.mysql.com|sql-bench/Results-linux/big-tables-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|52469|c13eca5ec25cd6e1
-monty@donna.mysql.com|sql-bench/Results-linux/connect-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|54998|dfaa50e67eb15556
-monty@donna.mysql.com|sql-bench/Results-linux/connect-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|57532|4015a2bef627d8cd
-monty@donna.mysql.com|sql-bench/Results-linux/create-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|60103|fa19b9a2c7a3c3c
-monty@donna.mysql.com|sql-bench/Results-linux/create-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|62710|21ec8ba1ea3ca4c4
-monty@donna.mysql.com|sql-bench/Results-linux/insert-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|65289|a02aceb3b30de493
-monty@donna.mysql.com|sql-bench/Results-linux/insert-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|02393|7c9baa774fc324e1
-monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|05001|da73eefa16ca9383
-monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|07610|cffd7d282a90113a
-monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|10615|8dcd7271a9137341
-monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|13213|4398328883aa75da
-mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b9394876
-BK|mit-pthreads/machdep/i386-sco-3.2v5/__math.h|19700101030959|01011|79d9a37715f2c7fe
-BK|mit-pthreads/machdep/i386-sco-3.2v5/__signal.h|19700101030959|01012|45332b2a56f62580
-BK|mit-pthreads/machdep/i386-sco-3.2v5/__stdio.h|19700101030959|01013|a81562134446c64c
-BK|mit-pthreads/machdep/i386-sco-3.2v5/__stdlib.h|19700101030959|01014|bcbed6d62d1885ae
-BK|mit-pthreads/machdep/i386-sco-3.2v5/__string.h|19700101030959|01015|94a2e4f9574bf1e8
-BK|mit-pthreads/machdep/i386-sco-3.2v5/__time.h|19700101030959|01016|2cde57d8feea7fc8
-BK|mit-pthreads/machdep/i386-sco-3.2v5/__unistd.h|19700101030959|01017|5cc4575b5a74066f
-BK|mit-pthreads/machdep/i386-sco-3.2v5/compat.h|19700101030959|01018|1f7e450a2e18603e
-BK|mit-pthreads/machdep/i386-sco-3.2v5/dirent.h|19700101030959|01019|13608bf11af98f70
-BK|mit-pthreads/machdep/i386-sco-3.2v5/posix/__signal.h|19700101030959|01024|9bb7b240bec88b2d
-BK|mit-pthreads/machdep/i386-sco-3.2v5/socket.h|19700101030959|01020|9f78f7e5a7b4a83f
-BK|mit-pthreads/machdep/i386-sco-3.2v5/syscall.h|19700101030959|01021|d9543a0474656339
-BK|mit-pthreads/machdep/i386-sco-3.2v5/timers.h|19700101030959|01022|d5e694e48990538c
-BK|mit-pthreads/machdep/i386-sco-3.2v5/trash.can|19700101030959|01023|9332039abd82a925
-BK|mit-pthreads/machdep/sco-3.2v5/__math.h|19700101030959|00971|f3855eb411435a06
-BK|mit-pthreads/machdep/sco-3.2v5/__signal.h|19700101030959|00972|3d6f84e96bc1462
-BK|mit-pthreads/machdep/sco-3.2v5/__stdio.h|19700101030959|00973|b991fad3327275e0
-BK|mit-pthreads/machdep/sco-3.2v5/__stdlib.h|19700101030959|00974|6179a0922d90025e
-BK|mit-pthreads/machdep/sco-3.2v5/__string.h|19700101030959|00975|d2cc42eeb5e1666
-BK|mit-pthreads/machdep/sco-3.2v5/__time.h|19700101030959|00976|a9594bab280ced64
-BK|mit-pthreads/machdep/sco-3.2v5/__unistd.h|19700101030959|00977|99e6f1116d1f920
-BK|mit-pthreads/machdep/sco-3.2v5/compat.h|19700101030959|00978|3f150ff6223d49be
-BK|mit-pthreads/machdep/sco-3.2v5/dirent.h|19700101030959|00979|388af3465ad4680f
-BK|mit-pthreads/machdep/sco-3.2v5/posix/__signal.h|19700101030959|00984|5e14827a3b91a6db
-BK|mit-pthreads/machdep/sco-3.2v5/socket.h|19700101030959|00980|1b409f3f1fcbbf7a
-BK|mit-pthreads/machdep/sco-3.2v5/syscall.h|19700101030959|00981|c69bd58eba4d5076
-BK|mit-pthreads/machdep/sco-3.2v5/timers.h|19700101030959|00982|4907a958151368ed
-BK|mit-pthreads/machdep/sco-3.2v5/trash.can|19700101030959|00983|7eecac9fc944ade2
+BK|Docs/Attic/myisam.doc|19700101030959|00502|519bb06ecc870298
+BK|Docs/Flags/island.eps|19700101030959|00181|8cec5a55768bc59e
+BK|libmysql/violite.c|19700101030959|02600|984c09cffe14a11b
+BK|mysql.proj|19700101030959|00071|3e34edc585d18be8
+BK|sql-bench/Results-win32/wisconsin-mysql-win98|19700101030959|02547|8b3da9c5c5d2365b
+BK|sql-bench/Results/connect-mysql-3.21-Linux_2.2.1_i686|19700101030959|02134|c0c26d4320182d85
+BK|sql-bench/Results/create-mysql_3.21-Linux_2.0.35_i686|19700101030959|02225|df1b037d17b33587
+BK|sql/share/estonia/errmsg.sys|19700101030959|01836|83b86d7ed4cdd5d0
+BK|sql/share/french/errmsg.sys|19700101030959|01838|9f024dc5e6fe50f5
+BK|sql/share/romania/errmsg.sys|19700101030959|01871|e08aa93bae96d25e
+BK|strings/Attic/bootstrap-ctype.c|19700101030959|01360|6d2a8cda2d6a35ff
+BK|strings/Attic/ctype-dos.c|19700101030959|01344|f77bd08acf13a8c1
+BK|strings/Attic/ctype-estonia.c|19700101030959|01345|fc8a69424f7cb66b
+BK|strings/Attic/ctype-german1.c|19700101030959|01346|f7830c509bb358f7
+BK|strings/Attic/ctype-hp8.c|19700101030959|01349|749e1be0f028d349
+BK|strings/Attic/ctype-koi8_ru.c|19700101030959|01351|8ff4188c642c9bd
+BK|strings/READ-ME|19700101030959|01362|ed6c5184d4bf6b7c
+BK|support-files/Attic/my-large.cfg.sh|19700101030959|02586|842c8e76253c9396
+BK|vio/VioSSL.cc|19700101030959|00013|6e85340b11fa42a8
+BK|vio/VioSocket.h|19700101030959|00019|a26d535bd5a1a6
+BK|vio/viotypes.h|19700101030959|00027|f5a38e7326bd50f3
+Sinisa@sinisa.nasamreza.org|=6|20010818122920|53462|33f33b0a159dc5d5
+Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522133259|25000|4b5fbc60d0d9754f
+Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133300|08911|21904fbd1c95cb1
+ccarkner@nslinuxw10.bedford.progress.com|mysql-test/r/isolation.result|20010327145543|25059|4da11e109a3d93a9
+jani@hynda.mysql.fi|client/mysqlcheck|20010419221207|26716|363e3278166d84ec
+miguel@hegel.local|zlib/contrib/asm386/gvmat32.asm|20020319032514|12654|31093c1a846dfdc7
+miguel@hegel.local|zlib/contrib/asm386/gvmat32c.c|20020319032514|19182|2a8eba5481c46eab
+miguel@hegel.local|zlib/contrib/asm586/match.s|20020319032514|51538|dc1a34b5eb2a7c11
+miguel@hegel.local|zlib/contrib/delphi2/d_zlib.cpp|20020319032514|31641|d6f37620ac7b27fa
+miguel@hegel.local|zlib/contrib/delphi2/zlib.cpp|20020319032515|22372|4257437d415259e2
+miguel@hegel.local|zlib/crc32.c|20020319032516|20397|b327da5b8cf9eae8
+miguel@hegel.local|zlib/inffast.c|20020319032517|65269|bf247ff4aa2bf54b
+miguel@hegel.local|zlib/inffixed.h|20020319032517|12923|e86ef8e2efe23f77
+miguel@hegel.local|zlib/msdos/zlib.def|20020319032518|18787|165cd7dcff6ac9f
+miguel@hegel.local|zlib/trees.c|20020319032519|43770|4fbd4d005e26d38
+miguel@hegel.local|zlib/uncompr.c|20020319032519|57111|82eac43195d1222c
+miguel@hegel.local|zlib/zlib.dsp|20020319032519|12016|6eec436fab260061
+miguel@hegel.local|zlib/zlib.html|20020319032519|31060|7a635f4ac95fc56b
+monty@donna.mysql.com|mysql-test/include/have_default_master.inc|20010104005638|23980|a54c86e65a6c4af
+monty@donna.mysql.com|sql-bench/Results/ATIS-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14777|e625af7f600bf930
+monty@donna.mysql.com|sql-bench/Results/create-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20766|4e5a2ab4907748d4
+monty@donna.mysql.fi|sql/violite.c|20010523223654|08838|53d4251a69d3c
+monty@hundin.mysql.fi|sql-bench/Results/RUN-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|63204|e938a858bd12aa8d
+monty@hundin.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|42711|788ad492867b1226
+monty@hundin.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|46284|5316add301edb60
+monty@narttu.mysql.com|sql-bench/Results/insert-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|29606|975e26cac59161fa
+monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.13_SMP_alpha|20001014001004|18602|e8cc899bb933532f
+mwagner@cash.mwagner.org|Docs/include.de.texi|20020223092123|06028|112aac21b3489888
+mwagner@evoq.home.mwagner.org|Docs/Books/dubois.eps|20001231203219|33725|aa3d9c08bbcc149b
+mwagner@evoq.home.mwagner.org|Docs/Books/in_21.eps|20001231203220|05743|83a7604251d68ebd
+mwagner@evoq.home.mwagner.org|Docs/Books/pthreads.eps|20001231203220|18899|d60ad51891ef4c49
+mwagner@evoq.home.mwagner.org|Docs/Books/realmen.eps|20001231203220|22075|1ceb4839e835dad4
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000006.xml|20001017133623|51441|8ad8f44f49b21246
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000013.xml|20001017133713|03416|2717cbfbe5730174
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000021.xml|20001017133713|15460|2763b87c1549ba87
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000026.xml|20001017133713|25860|15145e496417646f
+nick@nick.leippe.com|mysql-test/t/rpl_empty_master_crash.test|20020531235552|52328|99464e737639ccc6
+sasha@mysql.sashanet.com|mysql-test/r/df_crash.result|20010406010433|59989|4a3dbee64843953d
+sasha@mysql.sashanet.com|mysql-test/std_data/m.MRG|20001212152450|17736|3f5632c37af00f18
+sasha@mysql.sashanet.com|mysql-test/t/3.23/alt000001.test|20001122072330|31588|633aed61c4bad94c
+sasha@mysql.sashanet.com|mysql-test/t/binlog-backup-restore.test|20010424233926|25316|d5b0b9bd83738a9f
+sasha@mysql.sashanet.com|vio/test-ssl|20010828000105|24508|ed0a50364f2a51d7
+serg@serg.mysql.com|mysql-test/r/ft0000001.d.result|20001211130756|19773|7c549555fbc7663e
+serg@serg.mysql.com|mysql-test/r/ft0000001.e.result|20001212121413|40468|c58d30fd7fe86f4f
+serg@serg.mysql.com|mysql-test/t/sel000015.test|20001211130731|27841|7442bf9cbc96fe07
+serg@serg.mysql.com|mysql-test/t/sel000024.test|20001211130731|07099|849f47e6cbdc4fe3
+tim@threads.polyesthetic.msg|bdb/build_win32/db_int.h|20010305004134|30736|9ee5645850a336a0
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_btrec.dsp|20010305004135|08710|c87137287d8d67dc
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_env.dsp|20010305004135|09533|1732d5e41efda77
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_lock.dsp|20010305004135|14943|257abf03544f6270
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_qam|20010305004137|28066|6eecf6833de0af98
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_txn|20010305004137|29072|1ff22b797deb0e1b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_rename.html|20010305004144|37128|36796ad9e106c3f0
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_hash.html|20010305004144|09702|73f14897664d9d08
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_q_extentsize.html|20010305004144|13496|f2fe41a5d8c46658
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_pad.html|20010305004144|16373|8a1de721eb6fc53f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_sync.html|20010305004144|19394|7a067029b6e1496b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbt.html|20010305004144|04896|ae7a81c9c5f574f6
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_close.html|20010305004144|28399|a8e722cbb66c9d7b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_conflicts.html|20010305004145|07137|58d9f7179bc864a3
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_server.html|20010305004145|31969|c13b793b525d504b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tmp_dir.html|20010305004145|34771|b563e87af5431824
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_verbose.html|20010305004145|38421|344f5119536cae0
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_file.html|20010305004145|48705|574444b46b801f9c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_map.html|20010305004144|16369|d90bbc8462ef43a6
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_realloc.html|20010305004144|19375|e8e78e57c005c7c4
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_pindex.html|20010305004147|08181|9ff6b69b56f988dd
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_append_recno.html|20010305004146|08075|a158b1fdba756ce
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errcall.html|20010305004146|10727|28a7a1fa2b3b73ee
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_nelem.html|20010305004146|19017|1829bc583d9c7554
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_delim.html|20010305004146|22753|81d9df93c3511df3
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_len.html|20010305004146|23672|e09bb30e40208dfb
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_remove.html|20010305004146|38809|5efece7ecdfc4df7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_region_init.html|20010305004146|59589|2d70678382bbbf9a
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lsn_class.html|20010305004145|24210|34809f73e15540ad
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fclose.html|20010305004146|22608|cc4a5776ac69d660
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_abort.html|20010305004147|01091|81177bcb2e5f4502
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_checkpoint.html|20010305004147|02999|173930473e76d008
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_key_range.html|20010305004147|31461|8834de5873a6acb5
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_stat.html|20010305004147|57008|bc253f0883e9c82b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbenv_class.html|20010305004147|12326|92c7a4a6c22090c7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errcall.html|20010305004147|07189|4e206d08cbb39ab7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_detect.html|20010305004147|15549|9fc15a1a95b0dfa1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_lockers.html|20010305004147|18755|7896265ea77829b3
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_rec_init.html|20010305004147|25237|1fdb2c5fc3b6407
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_recover.html|20010305004148|00983|40280da113fc9d2b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_timestamp.html|20010305004148|02804|457eeb135f1f8bc0
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_strerror.html|20010305004148|04588|fceebaa94cf9aafd
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_stat.html|20010305004148|10140|71b81d8567befc43
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_flush.html|20010305004148|14794|1691d6a3c8cc284e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fclose.html|20010305004148|20518|d08f0c134361f802
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_prepare.html|20010305004148|33784|510a245c80e715c
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get.html|20010305004148|42753|127bd361ee695c71
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_is_byteswapped.html|20010305004148|45596|8fb9e2c58051c769
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_stat.html|20010305004148|51363|3bb57be2de907fd2
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_commit.html|20010305004148|64051|25150b20b84cd519
+tim@threads.polyesthetic.msg|bdb/docs/images/api.gif|20010305004148|02578|dec2d4fe5f39dffe
+tim@threads.polyesthetic.msg|bdb/docs/images/ref.gif|20010305004148|06650|add30c753dc1972d
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/open.html|20010305004148|23468|c9a7e23579a5e93a
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_recnum.html|20010305004149|20770|f081f10254e86e75
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_hash.html|20010305004149|25978|3a0174586fbcfcdf
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_nelem.html|20010305004149|26871|979995db477052ad
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/apis.html|20010305004149|36488|a84570e410b11a6a
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/intro.html|20010305004149|49652|f261022c26987d7f
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/osf1.html|20010305004149|53358|9d4ebabfe3af8970
+tim@threads.polyesthetic.msg|bdb/docs/ref/cam/intro.html|20010305004149|04558|4c497b1a18c4c7f5
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/file.html|20010305004150|21159|d4ba2317db7c064b
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.txt|20010305004150|21985|3894a46ea11ce25a
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/faq.html|20010305004150|27218|7ca2474ba1f6676f
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/cam_conv.html|20010305004150|31862|63844ff6fa95f0c
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/nondb.html|20010305004150|36156|863fe076a46378d7
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/twopl.html|20010305004150|39650|b3f3aee667bc381d
+tim@threads.polyesthetic.msg|bdb/docs/ref/log/limits.html|20010305004150|43198|26fac1e32387b7c9
+tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/intro.html|20010305004150|13549|ad16bc20623e1192
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/errors.html|20010305004150|19994|be11ff6410e1db2c
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/app.html|20010305004151|42111|6dc3c82982164fa8
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/intro.html|20010305004151|49773|22096cea9fe159ac
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/other.html|20010305004151|63311|4991722636b3a46d
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_register.html|20010305004151|23513|399320e965adf598
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_stat.html|20010305004151|33181|516f1870c6127351
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/value_set.html|20010305004151|34118|f0b0c770a81b90b6
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_paniccall.html|20010305004152|46636|8f9741244fb6e9f6
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tmp.html|20010305004152|50733|ef3450f6fa89f2dc
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/txn_check.html|20010305004152|51549|2405b25bc92cc476
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/renumber.html|20010305004152|60219|d6cd798434da81aa
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/toc.html|20010305004152|61902|9c94c533ada43c1a
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade/process.html|20010305004151|64704|78f9ca966a587234
+tim@threads.polyesthetic.msg|bdb/include/db_auto.h|20010305004137|26350|994ddc84db334345
+tim@threads.polyesthetic.msg|bdb/include/hash_auto.h|20010305004138|09216|1b79cdd426d7ef25
+tim@threads.polyesthetic.msg|bdb/include/rpc_client_ext.h|20010305004138|28220|85436ca9b5691338
+tim@threads.polyesthetic.msg|bdb/rpc_client/db_server_clnt.c|20010305004141|41933|b548b860f765c597
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_xdr.c|20010305004141|53794|336ef020b4a22c05
+tim@threads.polyesthetic.msg|bdb/txn/txn_auto.c|20010305004143|19863|6eb282f016f606d9
+BK|sql-bench/Results-win32/connect-mysql-win98|19700101030959|02535|2a11d5e3dfc0bc67
+BK|sql-bench/Results-win32/select-mysql-win98|19700101030959|02544|f370fac2d66a9faf
+BK|sql-bench/Results/ATIS-mysql_3.21-Linux_2.0.35_i686|19700101030959|02036|c25425e045ca8dfc
+BK|sql-bench/Results/alter-table-mysql_3.21-Linux_2.0.35_i686|19700101030959|02092|762639f2560976bd
+BK|sql/Attic/mini_client.c|19700101030959|01910|9a3778c387d06a81
+BK|sql/Attic/mybinlogdump.cc|19700101030959|01908|5dbdd2bde98d6169
+BK|strings/Attic/ctype-croat.c|19700101030959|01341|d2d805ee6f10cbcc
+BK|strings/Attic/ctype-hungarian.c|19700101030959|01350|5cf0bf7fa0312637
+BK|strings/Attic/ctype-latin1.c|19700101030959|01353|cc63880f19c2303e
+BK|strings/Attic/ctype-latin2.c|19700101030959|01354|31895c4b83654342
+BK|strings/Attic/ctype-win1250.c|19700101030959|01357|1ce7a24255780a1
+BK|support-files/Attic/my-example.cnf.sh|19700101030959|02584|87a7e1f4d24b62a9
+BK|support-files/Attic/my-small.cfg.sh|19700101030959|02588|85023c559a1d96c
+BK|vio/VioConnectorFd.cc|19700101030959|00007|ddbd7821c43c83a2
+BK|vio/VioSSLFactoriesFd.cc|19700101030959|00016|89f6bf5073937947
+Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133624|23665|445526a8a20de101
+miguel@hegel.local|zlib/contrib/delphi2/readme.txt|20020319032515|03494|65d16837f8579e23
+miguel@hegel.local|zlib/contrib/iostream2/zstream.h|20020319032515|02537|351f26518ea48196
+miguel@hegel.local|zlib/infcodes.h|20020319032517|58960|3a02220a89c9a4fa
+miguel@hegel.local|zlib/inflate.c|20020319032517|19311|fb22a3a1ab6fb1a0
+miguel@hegel.local|zlib/infutil.c|20020319032518|05244|a9b414f0f4ea0868
+miguel@hegel.local|zlib/nt/zlib.dnt|20020319032519|16279|22a0ed3b86ff8c2
+miguel@hegel.local|zlib/zlib.3|20020319032519|04298|ec5cb4f64476f6a
+monty@donna.mysql.com|mysql-test/r/have_default_master.require|20010104005638|27332|1465255ffdaf82f
+monty@hundin.mysql.fi|sql-bench/Results/ATIS-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|59551|d002b0bc548ff8b3
+monty@hundin.mysql.fi|sql-bench/Results/connect-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|08804|1b715c6fd72e913e
+monty@hundin.mysql.fi|sql-bench/Results/create-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|49804|26e09af61f88d8c9
+monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|13605|ee94f987797ca948
+monty@narttu.mysql.com|sql-bench/Results/select-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|35818|34a39fbcb58d8945
+monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|37931|2db07249379f36
+monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|40155|8101a5823c17e58a
+monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.13_SMP_alpha|20001014001004|13092|583091e05a25fb6
+monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.13_SMP_alpha|20001014001004|15829|6c20c9ef46f82241
+monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|07880|e1771e0a164bc310
+monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.13_SMP_alpha|20001014001004|32465|fc410754151d622c
+mwagner@evoq.home.mwagner.org|Docs/Books/dbi.eps|20001231203219|30594|6ad58f9457e2a564
+mwagner@evoq.home.mwagner.org|Docs/Books/ecomm.eps|20001231203220|02445|58ae914b5d5ea49
+mwagner@evoq.home.mwagner.org|Docs/Books/msql.eps|20001231203220|12487|ffe7d62847663250
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000009.xml|20001017133629|19814|8677613dc624cb0c
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000029.xml|20001017133713|31058|3aba1eb23ef86c9e
+sasha@mysql.sashanet.com|mysql-test/t/rpl000018-master.sh|20010127223331|13256|bc8072e13b26b005
+serg@serg.mysql.com|mysql-test/t/sel000007.test|20001211130730|24336|f431e4f4739a24c3
+serg@serg.mysql.com|mysql-test/t/sel000021.test|20001211130731|57561|94dd47de2872264a
+tim@threads.polyesthetic.msg|bdb/build_vxworks/db_int.h|20010305004134|18702|40ba51edce41403f
+tim@threads.polyesthetic.msg|bdb/build_win32/db_tcl.dsp|20010305004135|02285|5ad951d774e41520
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_lock.dsp|20010305004135|10303|286d2566e786dde
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_env.dsp|20010305004135|14159|b0bf2649a4c797ac
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_mpool.dsp|20010305004135|15715|d17a5d09f09f5217
+tim@threads.polyesthetic.msg|bdb/build_win32/include.tcl|20010305004135|17284|f8bffb5e2510f229
+tim@threads.polyesthetic.msg|bdb/db/db_auto.c|20010305004136|32432|3186e950cc321ae7
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.tags|20010305004137|19101|7a5b14d33d4078cc
+tim@threads.polyesthetic.msg|bdb/dist/config.guess|20010305004136|14678|ead1d91caeaa748c
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_btree|20010305004137|23131|65d6b0b2f5b7a6d2
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_db|20010305004137|25141|52c5797539878fca
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_append_recno.html|20010305004144|38070|bdf0130e642f74fa
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_prefix.html|20010305004144|41420|d6e443a7e47c9b3a
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errpfx.html|20010305004144|05859|756b9b73dd28b8d9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_feedback.html|20010305004144|06786|90d495e78318a332
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_source.html|20010305004144|17353|6d12ac12652acc31
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_stat.html|20010305004144|18351|578f6f99f8e247ff
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max.html|20010305004145|08849|a2dc11fa8b2f1c9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_pageyield.html|20010305004145|28418|8aa4a6cb2f18cad7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_rec_init.html|20010305004145|30192|bf7da051ef6689ba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_max.html|20010305004145|35672|71a739e46faf33a9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_vec.html|20010305004145|45892|cc79e33b82b7a275
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_register.html|20010305004145|52499|5381c1fad82d6527
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_stat.html|20010305004145|53440|36b87b19ee2c5bba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_close.html|20010305004144|08984|8981d16589844161
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_seek.html|20010305004144|21048|fdf1b31d3f6c7473
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unlink.html|20010305004144|22800|c42b13fd26f2e90
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_cursor.html|20010305004145|29241|4f0225f98f4a11c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_del.html|20010305004145|31220|43fa05f2dfa86dbc
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_join.html|20010305004146|02717|9c4819679501ad6e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_remove.html|20010305004146|06326|8c537fc5e326293b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_ffactor.html|20010305004146|17155|a67084c644c38114
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_pad.html|20010305004146|24627|f2e0c2c2c3806a97
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_stat.html|20010305004146|26537|3473827de856d680
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_verify.html|20010305004146|29479|14db455da528229d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_class.html|20010305004145|15353|2a31b398c37d674b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_get.html|20010305004146|34739|36e2dbe65e3442e3
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_rec_init.html|20010305004146|58586|77916e00d1361c7b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_server.html|20010305004146|60631|bb74806839e8eb58
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_max.html|20010305004146|01212|910d1c17dd000729
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/get_errno.html|20010305004145|22249|e1a57c1c5f1d2695
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_compare.html|20010305004146|13902|3225b4c32016c9b1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_get.html|20010305004146|17104|aee6162219c71617
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_trickle.html|20010305004146|34409|c9df8540b9ebc898
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_begin.html|20010305004147|02053|3a2d1488ec9d8655
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_class.html|20010305004145|26179|5e57abe095aceca9
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_class.html|20010305004147|09609|b957a4d2b77acb1e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_append_recno.html|20010305004147|36282|d28bf857803b93a2
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_len.html|20010305004147|53997|8448826ea78c630e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_open.html|20010305004147|02873|2df0f0ef544da715
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_data_dir.html|20010305004147|06162|b7b3f35e96804650
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_dir.html|20010305004147|12366|484cad2123994e14
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lsn_class.html|20010305004147|20619|b1458208b6c81016
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fput.html|20010305004148|23268|6ba75e517a259703
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_del.html|20010305004148|41829|400c7a72fb10d6f4
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_join.html|20010305004148|43762|1c737805c2c49cf9
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/count.html|20010305004148|11236|8fd8daf2e2cbd7c7
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curclose.html|20010305004148|12231|8b6b8442fc8382f7
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curput.html|20010305004148|16324|c7e4fa0a68170c3d
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/cursor.html|20010305004148|17350|6dbcdb3b7d552f58
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/sync.html|20010305004148|33751|381722c07c9d8825
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/byteorder.html|20010305004149|21617|999a22f727e2dae0
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/dup.html|20010305004149|23371|523731632fca7343
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/extentsize.html|20010305004149|24263|fdcfb5572974545c
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/malloc.html|20010305004149|29537|cb0e6d7e9448d93e
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.html|20010305004149|37519|ab5254bc99af0d5c
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/script.html|20010305004149|39400|6796fd0a63161a0c
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/flags.html|20010305004149|46003|a739404f90eb8c3d
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/install.html|20010305004149|48752|660222dd1feffc4
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/irix.html|20010305004149|50564|95833aedc3a82f0
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/printlog.html|20010305004149|09591|9fa9894f839fad95
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/runtime.html|20010305004149|10629|d50f2fea4a8e58c
+tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/format.html|20010305004149|13995|9fa10ca3c7ae6751
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/intro.html|20010305004149|19435|96dd1090729e06b
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/remote.html|20010305004149|23518|52a3a79fdff8f7bd
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbisnot.html|20010305004149|29466|5ce7aed7ce41c9e6
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/conf.html|20010305004150|26401|ef560bcf13a71cd5
+tim@threads.polyesthetic.msg|bdb/docs/ref/log/config.html|20010305004150|41449|aedc53caf49c51c9
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/scope.html|20010305004150|59326|2987f97781410bc1
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/embedded.html|20010305004150|03865|d25b9719d24df88c
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/witold.html|20010305004150|65330|ad6c866cf48734b5
+tim@threads.polyesthetic.msg|bdb/docs/ref/sendmail/intro.html|20010305004150|16532|ecac45d7e2bcf51c
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/close.html|20010305004150|18046|1fe3a82f28e7ed32
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/keydata.html|20010305004150|23810|530b1581aeba63ca
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/put.html|20010305004150|25774|bdd2629c212af471
+tim@threads.polyesthetic.msg|bdb/docs/ref/toc.html|20010305004148|08788|ab1fa294d5ef4b69
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/reclimit.html|20010305004151|53098|5f54174bf6026bd5
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/recovery.html|20010305004151|53956|6e3a0c07b997c3b2
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/throughput.html|20010305004151|55655|8a7d5a958df7f91a
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/intro.html|20010305004151|02261|8bfd3804a2da1598
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv_cxx.html|20010305004151|09872|7f4fd0ebace36d8e
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/disk.html|20010305004151|11685|eb79d1157ef44d3c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/java.html|20010305004151|17120|300acccbb633e335
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/jump_set.html|20010305004151|18936|718c098a91db9dba
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_notheld.html|20010305004151|20761|ed6853b6daa5531b
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/open.html|20010305004151|27357|8b1e2a969e97069a
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/intro.html|20010305004152|41719|64592a50b1c634d6
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_tx_recover.html|20010305004152|47442|ada65907ba98eee8
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/toc.html|20010305004152|49908|af1a24798980ad1
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/incomplete.html|20010305004152|56914|af86a649a878a124
+tim@threads.polyesthetic.msg|bdb/hash/hash_auto.c|20010305004137|61459|d17c6a6ed4f181d1
+tim@threads.polyesthetic.msg|bdb/include/clib_ext.h|20010305004137|19207|ed9d9f7965f0e1d3
+tim@threads.polyesthetic.msg|bdb/rpc_server/gen_db_server.c|20010305004141|54931|d5602f9bd5c930e
+BK|Docs/Flags/island.gif|19700101030959|00142|e274d5e96ee0975a
+BK|Docs/Flags/south-africa1.txt|19700101030959|00232|87a53fdcd2149c6e
+BK|client/Attic/net.c|19700101030959|00583|c18042da6fa4e693
+BK|extra/Attic/print_defaults.c|19700101030959|01513|362952979aa7b330
+BK|sql-bench/Results-win32/RUN-mysql-win98|19700101030959|02526|7f09e396772a8665
+BK|sql-bench/Results-win32/insert-mysql-win98|19700101030959|02541|6d6cafc85a6c837
+BK|sql-bench/Results/RUN-mysql-3.21-Linux_2.2.1_i686|19700101030959|02050|f6fdd64859e11de9
+BK|sql-bench/Results/big-tables-mysql_3.21-Linux_2.0.35_i686|19700101030959|02120|190e827e569c99a4
+BK|sql-bench/Results/create-mysql-3.21-Linux_2.2.1_i686|19700101030959|02158|51581b24f45e0f5c
+Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522121240|20995|360af2095c88cb8c
+arjen@co3064164-a.bitbike.com|Docs/section.Comparisons.texi|20011108043647|22614|692b647b
+ccarkner@nslinuxw10.bedford.progress.com|mysql-test/t/isolation.test|20010327145543|39049|6a39e4138dd4a456
+miguel@hegel.local|zlib/algorithm.txt|20020319032513|12903|fbc4dda3d31c2005
+miguel@hegel.local|zlib/contrib/README.contrib|20020319032514|04353|24cb75bee0a061fb
+miguel@hegel.local|zlib/contrib/asm386/zlibvc.def|20020319032514|31637|605ee23b8a4a6a1a
+miguel@hegel.local|zlib/contrib/delphi2/zlib.bpg|20020319032515|09768|93c030edcca1838
+miguel@hegel.local|zlib/contrib/delphi2/zlib.bpr|20020319032515|16113|7a2fa98af2345144
+miguel@hegel.local|zlib/contrib/minizip/unzip.h|20020319032516|21001|bac981086af91a30
+miguel@hegel.local|zlib/contrib/minizip/zip.c|20020319032516|27911|e82bf7774e1ece95
+miguel@hegel.local|zlib/zutil.h|20020319032520|12556|1e431b0173278fb2
+monty@donna.mysql.com|innobase/ib_config.h.in|20010217121901|07616|9e57db8504e55b7
+monty@donna.mysql.com|innobase/ib_config.h|20010217121901|04019|7539e26ffc614439
+monty@narttu.mysql.com|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|27509|d12a7edef05d7185
+mwagner@evoq.home.mwagner.org|Docs/Books/manual.eps|20001231203220|09365|2a7145f88960c7ec
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000025.xml|20001017133713|24071|3e766aa1e43b303
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000030.xml|20001017133600|63205|c2b25781eefaee9
+serg@serg.mysql.com|mysql-test/t/sel000006.test|20001211130730|19922|291cc6c8d85e51df
+serg@serg.mysql.com|mysql-test/t/sel000016.test|20001211130731|32739|f495235f14c47ec
+tim@threads.polyesthetic.msg|bdb/build_win32/db_stat.dsp|20010305004135|00560|f77417f5d9984986
+tim@threads.polyesthetic.msg|bdb/dist/config.sub|20010305004136|16944|17e9990a298261a
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_remove.html|20010305004144|36184|668fa1d67a4f6941
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_malloc.html|20010305004144|01594|3581879fef5af695
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_flags.html|20010305004145|03778|b2a1f3c8498e6d95
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_detect.html|20010305004145|07983|d9ed73495defdc19
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_lockers.html|20010305004145|24923|f22d5d4640436efe
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_locks.html|20010305004145|09704|1baf2d63a6fb418d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tas_spins.html|20010305004145|33848|91c7091deca3d97f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fclose.html|20010305004145|55335|b52c7d599d83c26
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_abort.html|20010305004145|65162|a53425dd70214619
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_index.html|20010305004145|07331|a0bc165de8a0554c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_feedback.html|20010305004146|15263|a08620d86f05ec8c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_malloc.html|20010305004145|12423|b0aa5802da5bef4d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_dup.html|20010305004146|33708|75df863b4bc13aaa
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_close.html|20010305004146|36778|5cc705b97b86972c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_cachesize.html|20010305004146|39807|b82ed49a47415fec
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_detect.html|20010305004146|49591|13e53300b722cf1e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_panicstate.html|20010305004146|57577|ad2d38e398cafd31
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_get.html|20010305004146|61648|527d63a8526f336c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_put.html|20010305004146|18207|66077da9630fa8c2
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_sync.html|20010305004146|33235|253961279934d3c8
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_hash.html|20010305004147|48174|c6eb825c706a9548
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_detect.html|20010305004148|06490|14d4e7c7dca0dad7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fsync.html|20010305004148|25118|e767b233fe7730a2
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_put.html|20010305004148|57122|290ecb1275d4270
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_open.html|20010305004148|59088|39b63925d45a637e
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_pindex.html|20010305004148|00553|259f0e062eee63c7
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/ops.html|20010305004148|25566|9b24db9ba4f45724
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_compare.html|20010305004149|18156|c1e847e651704c89
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_minkey.html|20010305004149|19013|b4708e561be92b83
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/intro.html|20010305004149|27745|dd1647202258ee28
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/recno.html|20010305004149|32283|c2ae722138309e95
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/select.html|20010305004149|34120|57b1c99f6a8ea93f
+tim@threads.polyesthetic.msg|bdb/docs/ref/distrib/layout.html|20010305004149|12589|5aeb292fbd987cf8
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/error.html|20010305004149|18447|acbbdb848c9fe70f
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/terrain.html|20010305004149|33850|b396d6447a59435f
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/intro.html|20010305004150|34434|e1e07e71f3198be
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/program.html|20010305004151|23138|2f5bf497ae226ed5
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/archival.html|20010305004151|42978|7631314d840be181
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/logfile.html|20010305004151|50590|1c3002fcb6581e8c
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/read.html|20010305004151|52265|fc8b056380e09887
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/func.html|20010305004151|15332|c06e5bc63ddf7a64
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/logalloc.html|20010305004152|43372|30563c544b8ddd54
+tim@threads.polyesthetic.msg|bdb/docs/sleepycat/contact.html|20010305004152|04402|55b4da3d7bf7655b
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_archive.html|20010305004152|07446|ab2c66e01b3e3626
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_recover.html|20010305004152|12771|1b63f2acdc0b0af7
+tim@threads.polyesthetic.msg|bdb/include/env_ext.h|20010305004138|05832|33a5fdef1aeecefd
+tim@threads.polyesthetic.msg|bdb/include/txn_ext.h|20010305004138|34549|9db24c14f204890c
+BK|Docs/Flags/kroatia.eps|19700101030959|00185|f50fcd444e7efceb
+BK|Docs/Flags/south-africa1.gif|19700101030959|00154|1ea38de5a535f732
+BK|sql-bench/Results/insert-mysql_3.21-Linux_2.0.35_i686|19700101030959|02252|60c0965dff31db07
+BK|sql-bench/Results/select-mysql_3.21-Linux_2.0.35_i686|19700101030959|02278|5fadbac5f98696a
+BK|sql/share/danish/errmsg.sys|19700101030959|01831|3a6d0fb8451a3313
+BK|sql/share/dutch/errmsg.sys|19700101030959|01833|b5aff4d08478bafd
+BK|sql/share/italian/errmsg.sys|19700101030959|01846|c5108ecb850b79a
+BK|sql/share/portuguese/errmsg.sys|19700101030959|01859|c0187322f8c9d805
+BK|vio/VioAcceptorFd.cc|19700101030959|00005|a5a08947a31f88de
+BK|vio/vio-global.h|19700101030959|00021|c261412c01b2f4
+miguel@hegel.local|zlib/ChangeLog|20020319032513|28917|5d5425fc84737083
+miguel@hegel.local|zlib/compress.c|20020319032513|32512|70bccb304651dba9
+miguel@hegel.local|zlib/contrib/asm386/mkgvmt32.bat|20020319032514|25425|422cbe16a6e74695
+miguel@hegel.local|zlib/contrib/delphi2/zlib32.bpr|20020319032515|35585|41ac53acb8008ff7
+miguel@hegel.local|zlib/contrib/delphi2/zlib32.cpp|20020319032515|41979|3b0f51435e880afe
+miguel@hegel.local|zlib/contrib/minizip/ChangeLogUnzip|20020319032515|15183|50464416f4a3768f
+miguel@hegel.local|zlib/index|20020319032517|33542|5443c9f841db4a47
+miguel@hegel.local|zlib/infblock.c|20020319032517|39853|540cc1b743be5f58
+mikef@nslinux.bedford.progress.com|mysql-test/r/have_gemini.require|20010321203410|47052|206702c48b2e206b
+monty@donna.mysql.com|sql-bench/Results/ATIS-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14134|cf0d806760eefef2
+monty@donna.mysql.com|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18309|c87333d6fe04433e
+monty@donna.mysql.com|sql-bench/Results/connect-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|19522|ab58fffa30dce97e
+monty@donna.mysql.com|sql-bench/Results/insert-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22042|27b7a557c3cb07a
+monty@donna.mysql.com|sql-bench/Results/wisconsin-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24748|6a468dcd3e6f5405
+monty@hundin.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|35759|11038a44f73070e7
+monty@hundin.mysql.fi|sql-bench/Results/big-tables-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|05113|b6be70bb51013cad
+monty@hundin.mysql.fi|sql-bench/Results/select-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|19688|4ffc9cf4be665ea2
+monty@hundin.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|60398|8ba598d217450157
+monty@hundin.mysql.fi|support-files/make_mysql_pkg.sh|20010915122456|03682|c616a18bed4b9c2
+monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|04677|f761da5546f0d362
+monty@narttu.mysql.com|sql-bench/Results/RUN-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171904|13285|a88e954bc8de5460
+monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|17580|28b688e2cd4b6bb3
+monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.13_SMP_alpha|20001014001004|21372|84df7c6446e51e26
+monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|00237|45d2cdf9bea9cc37
+monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|15116|b7552710d35202b6
+mwagner@evoq.home.mwagner.org|Docs/Books/sql-99.eps|20001231203220|25230|cec4ae16fee4c640
+mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.tst|20001013104933|54568|2e626fa07144d2c8
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000002.xml|20001013074610|25702|8cd06da5293a7147
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000008.xml|20001017133627|18273|1d6082f0905c51b6
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000018.xml|20001017133713|10435|82e2e7bde83f56d8
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000022.xml|20001017133713|17202|da2083ef423ae39a
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000027.xml|20001017133713|27519|95e7de3e9934b570
+sasha@mysql.sashanet.com|mysql-test/r/mrg000002.result|20001212152450|11492|745be0854aaaaf5e
+sasha@mysql.sashanet.com|mysql-test/t/fulltext_join.test|20010730234357|20865|e347c8f04405c916
+serg@serg.mysql.com|mysql-test/r/ft0000002.b.result|20001212120058|34425|5de41ce15ae1cedb
+serg@serg.mysql.com|mysql-test/t/sel000017.test|20001211130731|37659|7c39f2b45a6aa780
+serg@serg.mysql.com|mysql-test/t/sel000018.test|20001211130731|42584|16207f3ad74de75e
+serg@serg.mysql.com|mysql-test/t/sel000022.test|20001211130731|62553|6e3e5435e66875e9
+serg@serg.mysql.com|mysql-test/t/sel000023.test|20001211130731|02042|7bdfcfaa278f837d
+serg@serg.mysql.com|mysql-test/t/sel000025.test|20001211130731|12136|65b32b4b67e4c77
+tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.eps|20020228162345|64529|31ade79a89683616
+tim@cane.mysql.fi|mysql-test/r/delete.result|20001221095802|20463|e866a6678e29f186
+tim@threads.polyesthetic.msg|bdb/build_win32/db_deadlock.dsp|20010305004134|28374|befd45d29eaeb672
+tim@threads.polyesthetic.msg|bdb/build_win32/db_dump.dsp|20010305004134|29985|e07d2a82708b61
+tim@threads.polyesthetic.msg|bdb/build_win32/db_recover.dsp|20010305004134|34274|835c32ab73359256
+tim@threads.polyesthetic.msg|bdb/build_win32/db_static.dsp|20010305004135|01425|78ea414467defc70
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_access.dsp|20010305004135|07926|8dd6017efffae14e
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_mpool.dsp|20010305004135|11076|9eb937bc70c1573
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_access.dsp|20010305004135|12614|31e87b6228470681
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.def|20010305004137|13920|bb65b471d09f7c58
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.srcfiles|20010305004137|18056|ae884700cd110cbf
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_crdel|20010305004137|24191|58795c0c5232f80d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/c_index.html|20010305004143|28133|1a854fa55012906
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_del.html|20010305004144|11427|e8bffcf9be371317
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get.html|20010305004144|29265|7e0018b93ee31eba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_type.html|20010305004144|31538|d66aa1642a4d20e2
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_open.html|20010305004144|34314|59dfa6e5198c382e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_realloc.html|20010305004144|03204|a9be244baf966892
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_verify.html|20010305004144|21372|cf80f5ba845eac2e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_remove.html|20010305004144|31547|a71d5e1ca41324a7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_cachesize.html|20010305004144|32567|f4c341d3f2c09469
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errcall.html|20010305004145|00341|ba09eec1ba15f15f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_objects.html|20010305004145|25791|1a428bbee06cb5cc
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mp_mmapsize.html|20010305004145|26668|21f27997f00accfe
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mutexlocks.html|20010305004145|27540|85bbd53b877cafe1
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_paniccall.html|20010305004144|07360|97a1d58189199453
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fget.html|20010305004145|56294|460714b5c2e3e1c5
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_register.html|20010305004145|61165|8b9dff9b5043da58
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_malloc.html|20010305004144|15535|5579a0604e14e1e7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_rename.html|20010305004144|20199|3f8c7b6674cda105
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_write.html|20010305004144|24518|63567be42d586fde
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_commit.html|20010305004145|02592|8950b5e11c8b0778
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errpfx.html|20010305004146|14381|1f26e7b0bb5a067f
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_sync.html|20010305004146|27538|dadf1f745e44faa7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errpfx.html|20010305004146|42728|d26da4bab9538234
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_dir.html|20010305004146|46674|c08aac264e7faa97
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_pageyield.html|20010305004146|56583|db4e5bdf71e171c0
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_version.html|20010305004146|06444|1cff25c44cbea934
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/pindex.src|20010305004145|09392|d65361c4acfcef06
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_commit.html|20010305004147|03924|65afb8caf9c470ae
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/what.html|20010305004145|27185|a64f42c697273c44
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_close.html|20010305004147|24101|21595167f4fdbe88
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_del.html|20010305004147|25922|f4f15b362b114506
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_remove.html|20010305004147|34343|49d3b8c7e5a5b000
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_class.html|20010305004147|11473|8ee03c40ae0dbcb8
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_put.html|20010305004147|00700|da0f0fa974385abd
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_shm_key.html|20010305004147|28699|8c576698882f0edc
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tas_spins.html|20010305004147|30425|2f9963827fbcb3f
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_archive.html|20010305004148|11996|b4a9483dbb5a2b58
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_compare.html|20010305004148|12947|756622b42572ecb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_put.html|20010305004148|16729|ad7e9f382abde491
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_stat.html|20010305004148|18608|d186a08662046aba
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_join.html|20010305004148|46525|cb3eb61ed17a1f8
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_remove.html|20010305004148|60117|9090900413ff0280
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/pindex.src|20010305004148|39123|f8754fff24f2cb24
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/error.html|20010305004148|19390|45ac854e68196844
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/verify.html|20010305004149|01382|badaeba91bda50e1
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_prefix.html|20010305004149|19903|4e7602aa68d50fe1
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/utilities.html|20010305004149|40326|54d7014fab332c7a
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sco.html|20010305004149|55174|e25f6271a1b753d0
+tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/utility.html|20010305004149|15969|8fc100fdb58adb3c
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/create.html|20010305004149|17402|9f454cb1910df0b8
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/naming.html|20010305004149|20447|1f041789686cc8a0
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.le.txt|20010305004150|23615|528ef76418c8b45c
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/data.html|20010305004149|26092|33fbf7496c58cf63
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/distrib.html|20010305004149|30742|84b56709310017f2
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/products.html|20010305004149|32785|f37221772a3b589d
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/compat.html|20010305004150|25581|b39d173789bbf70d
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/dbsizes.html|20010305004150|52571|d70da530573b9b38
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/errorret.html|20010305004150|55412|23491397d7e704e9
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/recimp.html|20010305004150|60288|bbdb0feb7d467a80
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/version.html|20010305004150|62172|d266e819d1531df8
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/hash_usenix.ps|20010305004150|05408|11cad226b0aa012b
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/refs.html|20010305004150|64422|30490b237ba9b61
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/handles.html|20010305004150|21935|18a14f4a50e7bad0
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/using.html|20010305004151|23908|28856d8c72d0660b
+tim@threads.polyesthetic.msg|bdb/docs/ref/test/run.html|20010305004151|39305|63c0398e7e2a29e2
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/toc.html|20010305004151|04069|670791f294a61494
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db.html|20010305004151|07207|e7d63f4bb8e989e8
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_stat.html|20010305004151|24428|20b5898ba061557d
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/memp_stat.html|20010305004151|25363|79e1141c63f7357
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/xa.html|20010305004152|00602|1af042e462ab829
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/config.html|20010305004152|38401|d2ace28f39ab0f8d
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/sysmem.html|20010305004152|48282|3d088eb0ef1b27e0
+tim@threads.polyesthetic.msg|bdb/docs/sleepycat/legal.html|20010305004152|02616|7388af4c578cacf6
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_checkpoint.html|20010305004152|08309|c040e4424edcc451
+tim@threads.polyesthetic.msg|bdb/include/common_ext.h|20010305004137|20146|35c8aab64ee3b8fd
+tim@threads.polyesthetic.msg|bdb/include/log_auto.h|20010305004138|13513|8d52dd0884d03051
+tim@threads.polyesthetic.msg|bdb/include/os_ext.h|20010305004138|20730|a1771032b4d2d53b
+tim@threads.polyesthetic.msg|bdb/include/rpc_server_ext.h|20010305004138|29091|952741fb85de2b80
+tonu@x3.internalnet|include/vio.h|20010520213124|42404|c62fd2b86c03da7d
+BK|Docs/Flags/kroatia.gif|19700101030959|00146|bea7bbe0316d462d
+BK|Docs/Flags/kroatia.txt|19700101030959|00224|dde7f89f25d616b2
+BK|mit-pthreads/pgcc|19700101030959|00596|154a03d0c1a0a600
+BK|sql-bench/Results-win32/ATIS-mysql-win98|19700101030959|02523|cd0705815d3af451
+BK|sql-bench/Results-win32/big-tables-mysql-win98|19700101030959|02532|99a1882effebbdf2
+BK|sql-bench/Results/ATIS-mysql-3.21-Linux_2.2.1_i686|19700101030959|02022|660fb76ed6ccfb6f
+BK|sql-bench/Results/RUN-mysql_3.21-Linux_2.0.35_i686|19700101030959|02064|ea8672d8473435
+BK|sql-bench/Results/big-tables-mysql-3.21-Linux_2.2.1_i686|19700101030959|02106|baa649caba113497
+BK|sql-bench/Results/select-mysql-3.21-Linux_2.2.1_i686|19700101030959|02265|ed3687e713ff0571
+BK|sql/Attic/lex_hash.h|19700101030959|01912|14f912771118b50c
+BK|sql/share/czech/errmsg.sys|19700101030959|01828|93104a2bd5c732a
+BK|sql/share/greek/errmsg.sys|19700101030959|01842|fedf585fa73e7cf1
+BK|sql/share/slovak/errmsg.sys|19700101030959|01862|148510616ae825cf
+BK|sql/violite.c|19700101030959|01738|d7b85be615595ace
+BK|strings/Attic/ctype-cp1251.c|19700101030959|01339|cdf74b9168408b3
+BK|strings/Attic/ctype-dec8.c|19700101030959|01343|68f257dd2202d0c7
+BK|vio/VioConnectorFd.h|19700101030959|00008|58bc11cdc885b951
+BK|vio/VioPipe.cc|19700101030959|00011|12cf83b9a2f48f6c
+BK|vio/VioSSLAcceptorFd.cc|19700101030959|00015|4c828f3688ed74ec
+BK|vio/version.cc|19700101030959|00020|7237acf12bed4a97
+arjen@fred.bitbike.com|scripts/mysql_fix_extensions.sh|20020516001337|12363|f1048a78f4759b4d
+miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsw|20020319032514|44870|3209982720f131ab
+miguel@hegel.local|zlib/contrib/asm686/match.s|20020319032514|64199|4164951e8e19f116
+miguel@hegel.local|zlib/contrib/iostream/zfstream.h|20020319032515|61553|2b4d88acc2d3b714
+miguel@hegel.local|zlib/contrib/minizip/zip.def|20020319032516|34413|e9bda2081d65c22e
+miguel@hegel.local|zlib/contrib/minizip/zlibvc.def|20020319032516|47259|6dc42f99d2d55cad
+miguel@hegel.local|zlib/contrib/untgz/untgz.c|20020319032516|07726|b74e9dde74642756
+miguel@hegel.local|zlib/contrib/visual-basic.txt|20020319032516|14096|cd461e762199bb09
+miguel@hegel.local|zlib/deflate.h|20020319032516|33700|3a012bc1f5dfbc74
+miguel@hegel.local|zlib/inftrees.c|20020319032517|25758|4fcb97357cdbc40
+miguel@hegel.local|zlib/trees.h|20020319032519|50674|87161133bc2155fd
+monty@hundin.mysql.fi|sql-bench/Results/alter-table-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|01419|14360865bbba479f
+monty@narttu.mysql.com|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|23516|441a6aefd381e319
+monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|21374|d4766c7f8e70d7a2
+monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|25875|155a83b53c0e9d6
+monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.13_SMP_alpha|20001014001004|26814|688809eb8ea77b3d
+monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|11605|ee2a063d66a183d
+monty@work.mysql.com|fs/fsck.mysql|20010411110350|07619|87170d4358b50d60
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000001.xml|20001013051507|22498|f0eb64c0346366db
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000004.xml|20001017133600|56955|515488ef221523d9
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000005.xml|20001017133618|09973|a6344e46ba572dc3
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000014.xml|20001017133713|05036|bcf55df6a036bd8f
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000019.xml|20001017133713|12133|c0f0b05e481b90e7
+mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/README|20001013051514|26509|cd4bb681e5a0cd10
+sasha@mysql.sashanet.com|mysql-test/std_data/m.frm|20001212152450|13897|e351dfe0b6824c0c
+sasha@mysql.sashanet.com|mysql-test/t/3.23/shw000001.test|20001121234128|21322|770d96a2c1c65b20
+sasha@mysql.sashanet.com|mysql-test/t/mrg000002.test|20001212152450|20137|16b3a176adc0f311
+serg@serg.mysql.com|mysql-test/r/ft0000002.c.result|20001212120059|07173|cd66b90918a87531
+serg@serg.mysql.com|mysql-test/t/sel000026.test|20001211130731|17211|d8aa2d614f23b1
+serg@serg.mysql.com|mysql-test/t/sel000029.test|20001211130731|32917|6aae34dbb3ee86d9
+tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.gif|20020228162348|36945|364ca7338682f71
+tim@threads.polyesthetic.msg|bdb/build_win32/db_archive.dsp|20010305004134|25535|e3da826e91bb086
+tim@threads.polyesthetic.msg|bdb/build_win32/db_printlog.dsp|20010305004134|32975|163f6e1073a5f396
+tim@threads.polyesthetic.msg|bdb/build_win32/db_verify.dsp|20010305004135|04464|e9a4938542f86cea
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_tpcb.dsp|20010305004135|11838|644b38dae8b38152
+tim@threads.polyesthetic.msg|bdb/build_win32/libdb.rc|20010305004135|20964|906f4936ec6a8398
+tim@threads.polyesthetic.msg|bdb/dist/template/db_server_proc|20010305004137|21042|2e8b49d42aefab55
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_err.html|20010305004143|33003|3696088bd85eeda3
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_byteswapped.html|20010305004144|30478|bcab4145183a7be2
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_put.html|20010305004144|35267|ea78709ffb6cd7e8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_cachesize.html|20010305004144|02131|47a3c8ca486eb013
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errcall.html|20010305004144|04030|faf92be4ee8bc634
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_flags.html|20010305004144|07758|4cd3700ae4387d22
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_close.html|20010305004144|22419|a3ad4ea563bafc42
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_create.html|20010305004144|05736|3e73dd35fe5dcc8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_data_dir.html|20010305004144|33569|437cec65e441c60
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_bsize.html|20010305004145|04625|1eb03c137a42e80f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_get.html|20010305004145|42084|63399d204f1885fa
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_put.html|20010305004145|44022|f5bc2f52e55f16e1
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_stat.html|20010305004145|44954|d9a98bb949070b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fput.html|20010305004145|58291|4a7aace7db01ee15
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fset.html|20010305004145|59241|ecb97931b222568d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fsync.html|20010305004145|60192|a95ab802bb28646f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_free.html|20010305004144|13076|ed61d2dfea9e069e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_open.html|20010305004144|17474|8c812591efc8abe6
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unmap.html|20010305004144|23658|d85790692f3b536e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_stat.html|20010305004145|04637|f57a656bfbac12bf
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_type.html|20010305004146|01846|398668783c4070db
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_compare.html|20010305004146|08946|d888d1ebe056bc6b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_minkey.html|20010305004146|09837|d6181e52342005c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_lorder.html|20010305004146|19980|a46750a29588268c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_del.html|20010305004146|32671|424fc0ebb3b4c5cf
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_data_dir.html|20010305004146|40779|9176f081597e4f27
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errfile.html|20010305004145|18322|f9543c9e65ed6a1d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_error_stream.html|20010305004145|19317|a4101c1d68559fa2
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max.html|20010305004146|50580|52ac3c4ca2876de
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_id.html|20010305004146|08539|b3c7995efbe12c16
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_stat.html|20010305004146|10635|2112ceb0894b34d8
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_vec.html|20010305004146|11739|c55deaa5173a3323
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_unregister.html|20010305004146|21535|8fa1fe691751d6ad
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_type.html|20010305004147|29592|4cfb6f09cbe0b8ae
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_open.html|20010305004147|32409|bfc13736b96ac509
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_put.html|20010305004147|33389|c476abe5599f21cf
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_compare.html|20010305004147|37206|e972f964d042b35e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_minkey.html|20010305004147|38144|c7e1f184bdca25fa
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_feedback.html|20010305004147|45141|69b4c07b3dbe383
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_ffactor.html|20010305004147|47226|edcc10024104d57e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_q_extentsize.html|20010305004147|52035|6ac26239fc538cb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_sync.html|20010305004147|58064|42391f7d5f200b90
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_count.html|20010305004147|62108|9c239575f4550756
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_dup.html|20010305004147|64103|aa141014c4d7f9b0
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_get.html|20010305004147|65144|e66e387b83681e73
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_close.html|20010305004147|01809|c4e2ec77d7d14d4f
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_remove.html|20010305004147|04039|e92277e3dfd9bba1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_conflicts.html|20010305004147|14497|8951eb975a90918b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mp_mmapsize.html|20010305004147|20894|b7dea9108fa65dfa
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_server.html|20010305004147|27545|d901cdab9698605d
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_max.html|20010305004147|33999|70f356b8b67782fe
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_class.html|20010305004147|19738|880aa614d1469304
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_register.html|20010305004148|17668|c68fc6fb22dd594a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_stat.html|20010305004148|27008|4628462474db62b4
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_sync.html|20010305004148|27969|5b401daadc7261eb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_checkpoint.html|20010305004148|31832|2565ac892d04b63d
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_open.html|20010305004148|47486|f588cc9bc694cbf0
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_put.html|20010305004148|48549|380c7caeced55512
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_dup.html|20010305004148|55139|325121689412d70b
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_index.html|20010305004148|61088|443e6b9a10ef4139
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_abort.html|20010305004148|63068|8cc23b6ef6f457d2
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/version.html|20010305004148|65038|eeb51f4de1bbfe8e
+tim@threads.polyesthetic.msg|bdb/docs/index.html|20010305004143|26935|450dd5db21a9bb64
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/close.html|20010305004148|10227|ed6f7427edc0431
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curget.html|20010305004148|15271|d7dd42affcd54073
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_ffactor.html|20010305004149|25120|5eb87b7ce99f3362
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/smallpic.gif|20010305004149|42169|fdf77055d7e711
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/hpux.html|20010305004149|47818|d34942564699608
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/linux.html|20010305004149|51464|f9f2d09dc6df75e
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/notes.html|20010305004149|52391|97e9b52853db15ea
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sunos.html|20010305004149|58008|fc41965e9d95985c
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/ultrix.html|20010305004149|59865|a1dd780edcde11f6
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/notes.html|20010305004149|01764|4058bf968f287f7
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/intro.html|20010305004149|06616|57ef29f26341ea
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.be.txt|20010305004150|22805|cf7d25e758432ab6
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/what.html|20010305004150|00539|dd70b9e6e085725d
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/dead.html|20010305004150|33535|f5c7debd9ba739bb
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/max.html|20010305004150|35299|f0fb32ebc251f636
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/notxn.html|20010305004150|37003|beec805d9f05e2bc
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/stdmode.html|20010305004150|38797|4048a052ea129ca3
+tim@threads.polyesthetic.msg|bdb/docs/ref/mp/intro.html|20010305004150|45138|34937731cafcf1b1
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/mt.html|20010305004150|57429|552ab570b657fc0e
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/namespace.html|20010305004150|58394|182f8f762343bdc1
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/intro.html|20010305004150|22878|7544c4688623a54c
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/error.html|20010305004151|21581|37b817c57777b460
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/intro.html|20010305004151|20749|d66c6c398e2ace0b
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/deadlock.html|20010305004151|46421|34914b9dc6b01703
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/put.html|20010305004151|51420|8cc785aeecff8535
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/term.html|20010305004151|54819|d6f3fa4fc5a630ec
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/transapp.txt|20010305004151|57368|337576ea2aae23b0
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/why.html|20010305004151|56525|c941c1a56a0adbaf
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/config.html|20010305004151|59874|c7337cb30f9bf66
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/system.html|20010305004151|03146|eae0256a127c3c89
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/close.html|20010305004151|05457|c79c866b393785cc
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbinfo.html|20010305004151|10780|7529af7145c0680a
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/envopen.html|20010305004151|14369|5e768fd180f471e4
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_detect.html|20010305004151|19846|fb307b10156762ca
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_commit.html|20010305004151|32241|e1debf9ea769426c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/disk.html|20010305004152|39192|2abdaf9059265ba9
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/callback.html|20010305004152|53656|64a2b2b85cc253c1
+tim@threads.polyesthetic.msg|bdb/docs/sleepycat/license.html|20010305004152|03483|9371001bbf0ba2dd
+tim@threads.polyesthetic.msg|bdb/docs/utility/index.html|20010305004152|05717|66c82ee036c1b369
+tim@threads.polyesthetic.msg|bdb/qam/qam_auto.c|20010305004141|31764|361954d3f149feb0
+tim@threads.polyesthetic.msg|bdb/test/logtrack.list|20010305004142|05743|7f4f1382b37d98e5
+BK|Docs/Flags/south-africa1.eps|19700101030959|00193|111e4f92f4562e9d
+BK|sql-bench/Results-win32/create-mysql-win98|19700101030959|02538|f66c2cb2909c4792
+BK|sql-bench/Results/wisconsin-mysql_3.21-Linux_2.0.35_i686|19700101030959|02302|31703d40ea6b4f66
+BK|sql/share/english/errmsg.sys|19700101030959|01834|f29bd4ea5aaf54c8
+BK|sql/share/german/errmsg.sys|19700101030959|01840|1ea60675399c84c
+BK|sql/share/korean/errmsg.sys|19700101030959|01850|a30e3687ae75a7c9
+miguel@hegel.local|zlib/contrib/delphi/zlib.mak|20020319032514|11153|7b97eb8cf290a42
+miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsp|20020319032516|54044|ec35fd54c9b49987
+miguel@hegel.local|zlib/faq|20020319032517|20799|b0d0840d3b9faf07
+miguel@hegel.local|zlib/zlib.h|20020319032519|20598|fbec7833981c782f
+monty@donna.mysql.com|sql-bench/Results/big-tables-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17709|6d8209bf72b663ed
+monty@hundin.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|32241|dd306b2e583ebde4
+monty@hundin.mysql.fi|sql-bench/Results/select-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|56860|b01175ad38fd12b6
+monty@hundin.mysql.fi|sql-bench/Results/wisconsin-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|23386|1ed1dc6abd24e7e3
+monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|15583|a2a77f37b689cd63
+monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|04134|d46860c29c5d51ee
+monty@work.mysql.com|libmysqld/WHITEPAPER|20010411110351|28263|da1226799debcf3f
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000007.xml|20001017133625|48163|bfcb6d85276be7e8
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000016.xml|20001017133713|07087|32f1ef2e3d214be0
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000023.xml|20001017133713|20719|11993b379b9838be
+sasha@mysql.sashanet.com|mysql-test/t/identity.test|20010910233028|36116|326f469b59105404
+serg@serg.mysql.com|mysql-test/r/ft0000001.a.result|20001211130756|05199|3d17aff15fa5a9f1
+serg@serg.mysql.com|mysql-test/r/ft0000001.c.result|20001211130756|14950|1040289a75243a92
+serg@serg.mysql.com|mysql-test/t/3.23/mrg000001.test|20001206231615|27540|e0327f9d1e6cb4e
+serg@serg.mysql.com|mysql-test/t/sel000009.test|20001211130730|33139|a455c38f5c942cd1
+serg@serg.mysql.com|mysql-test/t/sel000019.test|20001211130731|47552|8fd63c8dc6be8dbc
+serg@serg.mysql.com|mysql-test/t/sel000020.test|20001211130731|52532|c5758ad18a6dff1e
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.offt|20010305004137|16371|25759c9294db634e
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_log|20010305004137|27185|3fe6d62c43bc553a
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_fd.html|20010305004144|28004|15a01776b340a959
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_key_range.html|20010305004144|33389|1060761b1e359d85
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_paniccall.html|20010305004144|02405|ac7f63325b4499ce
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_del.html|20010305004144|24335|2685f75d28e4ad99
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_open.html|20010305004144|29421|e4c9706220a4cd9b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_id.html|20010305004145|43025|c9ee776f928a38f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_archive.html|20010305004145|46850|490428ce45f9f918
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_flush.html|20010305004145|49632|bb8bc4fc43c9f63d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fopen.html|20010305004145|57267|d032a963a0103472
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_stat.html|20010305004145|62160|55a9521fe04b03bd
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_sync.html|20010305004145|63168|b387035a94c20c50
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_begin.html|20010305004145|00608|557b34fd3e7363
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_close.html|20010305004145|28189|cc570e65ac7d22f
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get.html|20010305004145|34357|3b6e6005f3f17f2a
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_cachesize.html|20010305004146|12541|3befdbaf98d5a04e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_dup_compare.html|20010305004146|13472|91f36955a213e0f4
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_pagesize.html|20010305004146|20914|b8d544ec3e102c6c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_count.html|20010305004146|31395|bc025b8894450525
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbenv_class.html|20010305004145|16297|5ab8aaf8a531f76b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_open.html|20010305004146|37756|66ac1ae7fa67ca4a
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errcall.html|20010305004146|41745|bae25b45b0196773
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_locks.html|20010305004146|51576|bbde4ffbcc607f61
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_objects.html|20010305004146|53572|c47424e4d13d5327
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_stat.html|20010305004146|20379|dc2d4ffe7950fc09
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fput.html|20010305004146|26004|7ee8cda6287dee81
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_stat.html|20010305004146|31867|d370717a78971be1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_stat.html|20010305004147|06751|e8e25f86f8541696
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_max.html|20010305004147|13429|c9f705492162e175
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_region_init.html|20010305004147|26379|30534afa94cbf54e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_put.html|20010305004148|09226|5af89e4cbf29c694
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_trickle.html|20010305004148|28912|4d5c4e83a4a5c638
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_class.html|20010305004147|23221|c7bb2a3393ca9488
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_stat.html|20010305004148|34772|9a6ef8c262f218f9
+tim@threads.polyesthetic.msg|bdb/docs/images/sleepycat.gif|20010305004148|07668|ea63aaaa508ef096
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/get.html|20010305004148|20425|96c9c9a01c32d16
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/put.html|20010305004148|28752|8e18b0af61eb7f0f
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.gif|20010305004149|41251|fe43e7415b3bbdb0
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/freebsd.html|20010305004149|46918|8ed2a42e1668004c
+tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/text.html|20010305004149|14998|88b57a73860b423
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/page.html|20010305004150|37863|d56876b2565cbee
+tim@threads.polyesthetic.msg|bdb/docs/ref/perl/intro.html|20010305004150|47570|ce7e794e619e1e1d
+tim@threads.polyesthetic.msg|bdb/docs/ref/pindex.src|20010305004149|02223|7d74723f9fd25801
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/environ.html|20010305004150|54494|dc4a48aa531bd399
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/solaris.txt|20010305004150|63135|8b6bb29de0d58ffe
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/faq.html|20010305004151|22367|f8433900f7f85400
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/disk.html|20010305004151|01410|94dc4e6e3668e613
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/cxx.html|20010305004151|06323|7f3bfc9bba854d48
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/btstat.html|20010305004152|37584|40a76aef8b25a948
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tcl.html|20010305004152|49096|f5c85b09c33bda4
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/intro.html|20010305004152|57734|984a9f7dd07e0c14
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/set_flags.html|20010305004152|61061|213809ca8d7802d0
+tim@threads.polyesthetic.msg|bdb/docs/ref/xa/intro.html|20010305004152|00728|8ac020ffb869e9a8
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_deadlock.html|20010305004152|09191|f23f99911c3e5784
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_verify.html|20010305004152|15424|4fee9bfa2f9ab41a
+tim@threads.polyesthetic.msg|bdb/include/hash_ext.h|20010305004138|10079|5b31ff8413481606
+tim@threads.polyesthetic.msg|bdb/include/qam_auto.h|20010305004138|24568|96f6c045fd0d6cab
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_svc.c|20010305004141|50897|35804eb82b953f49
+BK|Docs/Flags/island.txt|19700101030959|00220|301ede0f81c5f3e1
+BK|client/violite.c|19700101030959|00561|afa871b4aab14371
+BK|include/Attic/config-win32.h|19700101030959|00116|65db818ec7e8f21b
+BK|sql-bench/Results/connect-mysql_3.21-Linux_2.0.35_i686|19700101030959|02146|650abd213e6828c6
+BK|sql-bench/Results/insert-mysql-3.21-Linux_2.2.1_i686|19700101030959|02239|fd082017c7c57a6
+BK|sql-bench/Results/wisconsin-mysql-3.21-Linux_2.2.1_i686|19700101030959|02290|8147dc16a1dc6c47
+BK|sql/ha_hash.h|19700101030959|01902|27e36916116beb3e
+BK|sql/share/hungarian/errmsg.sys|19700101030959|01845|aff82c16a77fc800
+BK|sql/share/japanese/errmsg.sys|19700101030959|01848|302478c84697dc00
+BK|sql/share/norwegian/.cvsignore|19700101030959|01853|a91d63182f0b2366
+BK|sql/share/russian/errmsg.sys|19700101030959|01860|72688df0beeabcb3
+BK|sql/share/spanish/errmsg.sys|19700101030959|01865|10c8f32da39070b2
+BK|strings/Attic/ctype-cp1257.c|19700101030959|01340|732611cbc74aeafc
+BK|strings/Attic/ctype-hebrew.c|19700101030959|01348|d3b4a000d51e76dc
+BK|strings/Attic/ctype-win1251ukr.c|19700101030959|01359|b5a7cca889bbef58
+BK|strings/Attic/memory.h|19700101030959|01336|450f586e82a26d99
+BK|tests/fork_test.pl|19700101030959|01945|3d3535329ed8cd5e
+BK|vio/VioAcceptorFd.h|19700101030959|00006|7f9c4358477ba9a3
+BK|vio/VioFd.h|19700101030959|00010|8294293a88c7b4b8
+BK|vio/VioPipe.h|19700101030959|00012|21cebbe61a1da546
+miguel@hegel.local|zlib/contrib/iostream/zfstream.cpp|20020319032515|55262|dce18d1a5d7096b7
+miguel@hegel.local|zlib/contrib/minizip/miniunz.c|20020319032515|21943|6a80009b319b1b9e
+miguel@hegel.local|zlib/contrib/minizip/unzip.def|20020319032516|14456|b4162b8c833ab6c7
+miguel@hegel.local|zlib/descrip.mms|20020319032517|08063|7d61d33062ef53ec
+miguel@hegel.local|zlib/minigzip.c|20020319032518|25601|37f8eacb80c7f8fc
+miguel@hegel.local|zlib/os2/zlib.def|20020319032519|28842|1166a95d83c5f52c
+monty@donna.mysql.com|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17106|6e532c1936df1737
+monty@donna.mysql.com|sql-bench/Results/connect-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18910|7ed15d6fd1a5944c
+monty@donna.mysql.com|sql-bench/Results/select-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24071|4f7795c27eaab86b
+monty@hundin.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|39143|662b96bc66bc91b6
+monty@hundin.mysql.fi|sql-bench/Results/create-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|12309|f3b1d326092bf44
+monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|07879|2ac8fe298953d43
+monty@narttu.mysql.com|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|09727|79ac0482599eace1
+monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.13_SMP_alpha|20001014001004|08145|21ddf9425cbdd58
+monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|30548|f1127add9307098b
+monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.13_SMP_alpha|20001014001004|23947|2c9af91e9771f618
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000003.xml|20001013074610|26659|1a622b8d30d7ade8
+sasha@mysql.sashanet.com|build-tags|20011201050944|25384|b6f6fff142121618
+sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000004.test|20001103140433|32471|daf9ad4a1a31cd3c
+sasha@mysql.sashanet.com|sounds/compilation_finished.au.gz|20010814034002|63992|70bd14095a918139
+serg@serg.mysql.com|mysql-test/t/sel000013.test|20001211130731|18090|ce8aa504ba4f74ba
+serg@serg.mysql.com|mysql-test/t/sel000028.test|20001211130731|28317|db9bfc0a808fb629
+serg@serg.mysql.com|mysql-test/t/sel000030.test|20001211130732|03110|a29683eac3e7b706
+tim@cane.mysql.fi|mysql-test/t/delete.test|20001221095802|36821|389410e29f2cebe5
+tim@threads.polyesthetic.msg|bdb/btree/btree_auto.c|20010305004134|12592|a683156a176761f
+tim@threads.polyesthetic.msg|bdb/build_win32/db_checkpoint.dsp|20010305004134|26943|8071af22db95b1db
+tim@threads.polyesthetic.msg|bdb/build_win32/db_upgrade.dsp|20010305004135|03711|90fd250190af4984
+tim@threads.polyesthetic.msg|bdb/dist/install-sh|20010305004136|21695|1858c24340b72628
+tim@threads.polyesthetic.msg|bdb/dist/template/gen_client_ret|20010305004137|22087|786a5e65119b3991
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_close.html|20010305004144|26254|fda0b4dfa946f44e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_create.html|20010305004143|29368|a87157ea60c82ee2
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_cursor.html|20010305004144|27133|7431dd96ed3492c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_lsn.html|20010305004143|34135|5edb9bce1118feae
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_compare.html|20010305004144|39551|e55a311bb0be93a8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_dup_compare.html|20010305004144|03068|a833bfc727a794e7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errfile.html|20010305004144|00766|f07d3c57bb3c8fbd
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_pagesize.html|20010305004144|12535|9644fa0f538cde17
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_count.html|20010305004144|23385|c3cd00c48b4babf5
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_dup.html|20010305004144|25301|3bdf8b0a687b43f3
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errpfx.html|20010305004145|01527|806c8c438d0ee36c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/hsearch.html|20010305004144|08165|a8b76d897a8216d8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_detect.html|20010305004145|41159|8fe406dce10e0bb
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_put.html|20010305004145|51546|11a1bec49bb90419
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_unregister.html|20010305004145|54401|45b8f9d3f8eb3d80
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_trickle.html|20010305004145|64180|8b1adf1404d7a5f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/pindex.src|20010305004143|31726|d1ecd116c42e0e23
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_class.html|20010305004145|08391|3129ff8c53721fe8
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_fd.html|20010305004145|33050|99ec316575f80428
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_rename.html|20010305004146|07200|9c0a820e864220b3
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_prefix.html|20010305004146|11627|ecd8f927371a5dbd
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_hash.html|20010305004146|18078|afe952f65389d93b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_paniccall.html|20010305004145|13411|6bc911c9d64e9237
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_flags.html|20010305004146|44734|8136e8e1ae16dc02
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_bsize.html|20010305004146|45706|7fd917bea6b163bf
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_max.html|20010305004146|47638|4f7ba5f02c66c0de
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mp_mmapsize.html|20010305004146|54573|c21e3f9c5a29b0ab
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_strerror.html|20010305004146|05414|7e1cbfbd096ca
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_archive.html|20010305004146|12836|d47f39e6dad7ee50
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_register.html|20010305004146|19292|55470e0d79382beb
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fget.html|20010305004146|23710|bfe74f8c299c2995
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fset.html|20010305004146|27124|e52fa0488faa893
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_register.html|20010305004146|29358|cba6f572fe27c7a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_byteswapped.html|20010305004147|28706|edbc66a9d5491a1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_join.html|20010305004147|30506|a3a6dead9cae65f9
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_rename.html|20010305004147|35341|19b20feaa815bc27
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_nelem.html|20010305004147|49144|fc6f22a4c285fcef
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_source.html|20010305004147|55969|b29827dbf47537d1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_close.html|20010305004147|61116|e3bf1f36bc0e8e7e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbt_class.html|20010305004147|13192|f6b04ff142e332f8
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_error_stream.html|20010305004147|15677|a738119910b452b8
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_feedback.html|20010305004147|09255|9748745e65f070d5
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_locks.html|20010305004147|17677|f0114205b169de39
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_pageyield.html|20010305004147|23054|774b3da0306a6767
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_panicstate.html|20010305004147|24142|72846d9a97cb80bb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tmp_dir.html|20010305004147|32251|f23e4f614f6d975a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_verbose.html|20010305004148|03690|9dcda0399c8256e7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/except_class.html|20010305004147|16978|195c00e4a7cbe648
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_id.html|20010305004148|08326|737cf8d8dc74084e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_get.html|20010305004148|15736|5fbbbd4baa60e052
+tim@threads.polyesthetic.msg|bdb/docs/api_java/mem_class.html|20010305004147|21486|2e5052b5b2bea584
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fopen.html|20010305004148|22355|f7cf58725aa1c406
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_register.html|20010305004148|26052|8331390a1c66fefd
+tim@threads.polyesthetic.msg|bdb/docs/api_java/pindex.src|20010305004147|10521|de828917f041d27b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/runrec_class.html|20010305004147|22358|49c5cb3efe0c201
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_commit.html|20010305004148|32812|c265042f3340baa1
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_close.html|20010305004148|38213|f40794b17e0fe443
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_remove.html|20010305004148|50431|3b2be4b0b1b3dc98
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_sync.html|20010305004148|52310|3b615ca64d934602
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_close.html|20010305004148|58109|bf191b2673a2b19e
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/pagesize.html|20010305004149|30437|eb4800704ae1131b
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/renumber.html|20010305004149|33199|b7df79bf32240b5c
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/qnx.html|20010305004149|54263|6d2849a8e8038dc9
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/intro.html|20010305004149|62808|2eed15d25078711
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/notes.html|20010305004149|63758|7e53a042c5c4d350
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/program.html|20010305004150|28026|e9bbc08bccf5d396
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/am_conv.html|20010305004150|30986|3bab32d969f21b77
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/config.html|20010305004150|32692|a593ea4c87467ddd
+tim@threads.polyesthetic.msg|bdb/docs/ref/log/intro.html|20010305004150|42339|31e7055d83ca8757
+tim@threads.polyesthetic.msg|bdb/docs/ref/mp/config.html|20010305004150|46018|771c2c91fc0b6b17
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/nested.html|20010305004151|62443|6860bbf2f29aa93b
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/dup.html|20010305004152|40004|911018877c118b45
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/tx_recover.html|20010305004152|62754|132a354cde7a8286
+tim@threads.polyesthetic.msg|bdb/docs/ref/xa/config.html|20010305004152|64479|3f3f449c305e66b4
+tim@threads.polyesthetic.msg|bdb/docs/ref/xa/faq.html|20010305004152|65373|7aa890c7b70f1293
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_upgrade.html|20010305004152|14532|6444f26a93f77ea
+tim@threads.polyesthetic.msg|bdb/include/crdel_auto.h|20010305004137|21088|1b8255da47550ece
+tim@threads.polyesthetic.msg|bdb/include/db_server.h|20010305004137|34247|61a33aa05bf368a7
+tim@threads.polyesthetic.msg|bdb/include/mutex_ext.h|20010305004138|19006|f20f47ddc346598b
+tim@threads.polyesthetic.msg|bdb/include/qam_ext.h|20010305004138|25430|9993db1fb3428b6d
+tim@threads.polyesthetic.msg|bdb/include/tcl_ext.h|20010305004138|31857|6759d22aa2ff5f39
+tim@threads.polyesthetic.msg|bdb/include/txn_auto.h|20010305004138|33645|e3f49e94fd291c45
+tim@threads.polyesthetic.msg|bdb/rpc_client/gen_client.c|20010305004141|43060|ad86f092d0996a68
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_proc.sed|20010305004141|49906|1a9af8e5b051acbd
+tim@threads.polyesthetic.msg|bdb/test/include.tcl|20010305004141|34016|20fc297b040cbe2
+BK|client/Attic/libmysql.c|19700101030959|00582|72949a7043113807
+BK|mit-pthreads/pg++|19700101030959|00597|3beac0502025d766
+BK|myisam/ft_search.c|19700101030959|01642|c011cb6e8041bb59
+BK|mysys/test_vsnprintf.c|19700101030959|01502|e3d568aca62dc81e
+BK|strings/Attic/ctype-usa7.c|19700101030959|01356|d19d859dca5675f
+BK|strings/Attic/ctype-win1251.c|19700101030959|01358|762607f4fd7d52ad
+BK|tests/fork3_test.pl|19700101030959|01947|c4a7bffb4f8e813c
+BK|vio/VioSSLFactoriesFd.h|19700101030959|00017|1d63ae149a63f85
+BK|vio/VioSocket.cc|19700101030959|00018|71c615783f29b5e1
+Sinisa@sinisa.nasamreza.org|scripts/mysql_new_fix_privilege_tables.sh|20011226144909|43765|b1664b401375eece
+miguel@hegel.local|zlib/contrib/iostream/test.cpp|20020319032515|48225|a2ea8d4d7c66cf71
+miguel@hegel.local|zlib/contrib/minizip/unzip.c|20020319032516|07891|c66c95e17321206d
+miguel@hegel.local|zlib/deflate.c|20020319032516|26978|e22894a54233bc25
+miguel@hegel.local|zlib/infcodes.c|20020319032517|52620|dffb42fdf2fb2372
+miguel@hegel.local|zlib/inffast.h|20020319032517|06651|215e4a4ccfc886fc
+miguel@hegel.local|zlib/maketree.c|20020319032518|19299|7f281aef3547fee
+miguel@hegel.local|zlib/msdos/zlib.rc|20020319032518|25240|f8a286fa8371ee09
+miguel@hegel.local|zlib/zutil.c|20020319032520|05372|6f0d1763c5deb409
+monty@donna.mysql.com|sql-bench/Results/alter-table-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|16525|2f516d2c108a9e05
+monty@donna.mysql.com|sql-bench/Results/insert-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22723|a85a6f0477c13f83
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000017.xml|20001017133713|08762|81423597605ff77f
+sasha@mysql.sashanet.com|build-tags|20011125054855|05181|7afb7e785b80f97
+sasha@mysql.sashanet.com|mysql-test/r/binlog-backup-restore.result|20010424233926|16010|605de78abda64d27
+sasha@mysql.sashanet.com|mysql-test/r/identity.result|20010910233028|16331|e41453a364242503
+serg@serg.mysql.com|mysql-test/t/sel000010.test|20001211130731|03554|ca07085ae92255f1
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_tpcb.dsp|20010305004135|16510|159c727e2c15105e
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.define|20010305004137|15254|aa9a626e58631003
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_hash|20010305004137|26120|dcbdd106ae17b865
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_minkey.html|20010305004144|40498|e2d52ba2d0174432
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_delim.html|20010305004144|14446|e0a7face764111b9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_upgrade.html|20010305004144|20363|5e6210d6f09a0c3e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errfile.html|20010305004144|06564|3b6b0822f29fc3d4
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_panicstate.html|20010305004145|29311|43228366ca64363c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirfree.html|20010305004144|09784|d59f36547c7b5384
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirlist.html|20010305004144|10606|24e75ccc86809023
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_ioinfo.html|20010305004144|14713|80365bb8c66ae84c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_checkpoint.html|20010305004145|01607|4a1704dbfcaad5dc
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_byteswapped.html|20010305004146|00979|a44d5d57d050b466
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_put.html|20010305004146|05435|2792034e8c83c56
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errfile.html|20010305004145|11465|f6eddb9ab7ef07d0
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_flags.html|20010305004146|16174|1146625feeb3bb0b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_source.html|20010305004146|25550|46998978715ccc1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_conflicts.html|20010305004146|48615|5bba88df4cc6dfba
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_lockers.html|20010305004146|52578|ebb61fd669c2eefb
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_timestamp.html|20010305004146|03286|6396a1145f8e41c1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_class.html|20010305004145|23233|ed88ab78cccbef8d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/mempfile_class.html|20010305004145|25191|672b4aa787b4aeca
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_id.html|20010305004147|04873|162661f4c2dc09d6
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_prepare.html|20010305004147|05797|818b4163518bace5
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_cursor.html|20010305004147|25020|2181d652bd1c1ff
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_fd.html|20010305004147|26830|1f70020c37023baa
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_prefix.html|20010305004147|39088|a3269aad23e6dbc
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_dup_compare.html|20010305004147|40992|3dabd840a1d9e5f3
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_errcall.html|20010305004147|41930|4e4743f5b4277199
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_delim.html|20010305004147|53019|78fcf2d750fb26ef
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_cachesize.html|20010305004147|05132|f3700cd19856f14e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_objects.html|20010305004147|19812|d1ed194631ffeb2a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mutexlocks.html|20010305004147|21961|aad8e4a059075bb6
+tim@threads.polyesthetic.msg|bdb/docs/api_java/java_index.html|20010305004147|18736|8ecfcef4a702011d
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_unregister.html|20010305004148|19590|eee284e0da176d0a
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_count.html|20010305004148|40010|4812f3756a75437
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_rename.html|20010305004148|49486|909bc643d5455b54
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_del.html|20010305004148|54185|7e94f9f01e7e4453
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_get.html|20010305004148|56098|5bbb80cf51aff594
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/join.html|20010305004148|22331|acc16686a78a732
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/cachesize.html|20010305004149|22486|99dcd466dc881093
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/aix.html|20010305004149|44137|e8ae448bdb85fa22
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/conf.html|20010305004149|45053|d0378c69618b790b
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/faq.html|20010305004149|65331|34704a907168cea7
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/common.html|20010305004149|07598|607061232e2532df
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/compile.html|20010305004149|08609|12785e3091b78bfd
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/where.html|20010305004150|01442|6cb9ec27f19ecbbb
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/diskspace.html|20010305004150|53502|959508f155721ee8
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/example.txt|20010305004150|28042|9ff88f22565208bf
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/limits.html|20010305004151|61583|3004b7a93dab148b
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/convert.html|20010305004151|00512|d7f18eb34c1b6ae
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db_cxx.html|20010305004151|08078|5c17d6a360205140
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_stat.html|20010305004151|22568|c49716e693ce225b
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/log_register.html|20010305004152|42524|7177eeb2fc099317
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/memp_register.html|20010305004152|44171|7d92464a1029d53e
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/put.html|20010305004152|44997|961a1a689be6ce
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_feedback.html|20010305004152|45815|6d7de50be92a5488
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/db_dump.html|20010305004152|54477|7d1cac3358c0482e
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/handle.html|20010305004152|56086|bb8a73b74d4399ae
+tim@threads.polyesthetic.msg|bdb/docs/utility/berkeley_db_svc.html|20010305004152|06576|91fe012778882ce4
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_dump.html|20010305004152|10062|5de7ade427f20332
+tim@threads.polyesthetic.msg|bdb/include/btree_ext.h|20010305004137|18246|5d53d710f170c6b6
+tim@threads.polyesthetic.msg|bdb/include/gen_server_ext.h|20010305004138|07539|fd7bcfe6bbca8bcb
+tim@threads.polyesthetic.msg|bdb/include/mp_ext.h|20010305004138|17070|a528b772d42d6455
+BK|include/Attic/mysql_com.h.in|19700101030959|00115|85b1ea7ced528c32
+BK|libmysql/configure.in|19700101030959|02603|c6fc04d4e3d6e291
+BK|myisam/Attic/ft_global.h|19700101030959|01673|fe46fb515f1e375
+BK|sql-bench/Results-win32/alter-table-mysql-win98|19700101030959|02529|e8743982f790462
+BK|sql-bench/Results/alter-table-mysql-3.21-Linux_2.2.1_i686|19700101030959|02073|f6f7ccd7b3c35f97
+BK|sql/Attic/mini_client_errors.c|19700101030959|01909|29edad51a5d0b068
+BK|sql/Attic/net_serv.c|19700101030959|01911|52dabcd773a39e10
+BK|strings/Attic/ctype-greek.c|19700101030959|01347|90acdff1195209ca
+BK|strings/Attic/ctype-koi8_ukr.c|19700101030959|01352|a04aa14a6d62335a
+BK|support-files/Attic/my-huge.cfg.sh|19700101030959|02585|589bdcd2d2c4360b
+BK|support-files/Attic/my-medium.cfg.sh|19700101030959|02587|c49880d26ef0648e
+BK|vio/Vio.cc|19700101030959|00003|60737ce02ab2bc25
+miguel@hegel.local|zlib/contrib/asm686/readme.686|20020319032514|04933|15e2bf4653b71f3e
+miguel@hegel.local|zlib/contrib/minizip/minizip.c|20020319032515|28588|97181367a7bc47d8
+miguel@hegel.local|zlib/inftrees.h|20020319032517|32227|ffcbe51816466e5c
+miguel@hegel.local|zlib/zconf.h|20020319032519|63437|c6b6b636c7e88d90
+monty@donna.mysql.com|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|25437|24a02e007a58bf73
+monty@hundin.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|53328|fd2699adb3190d07
+monty@narttu.mysql.com|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|19531|7dd5ac726f86cf0b
+monty@narttu.mysql.com|sql-bench/Results/connect-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|21574|1cf5d5f0d70a3fa0
+monty@narttu.mysql.com|sql-bench/Results/create-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|25516|fc207468e871ff69
+monty@narttu.mysql.com|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|33684|ddcf36cdf3f72e8c
+mwagner@evoq.home.mwagner.org|Docs/Books/prof.eps|20001231203220|15779|dc69b039543a57d7
+mwagner@evoq.home.mwagner.org|mysql-test/xml/README|20001013051440|12362|877d76bcd19f7193
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000020.xml|20001017133713|13843|8849bbf91a4fd5ec
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000028.xml|20001017133713|29282|c72bfec6600949b
+nick@nick.leippe.com|mysql-test/r/rpl_empty_master_crash.result|20020531235552|47718|615f521be2132141
+sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000005.test|20001103140433|36002|982fde89a4d6d886
+serg@serg.mysql.com|mysql-test/r/ft0000001.b.result|20001211130756|10153|505c4c00a0bddfc4
+serg@serg.mysql.com|mysql-test/t/sel000011.test|20001211130731|08373|c2a971726c9d18d6
+tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.txt|20020228162350|33044|e155c53c10374ff
+tim@threads.polyesthetic.msg|bdb/build_win32/db_java.dsp|20010305004134|31520|e3941d5a9810b360
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_btrec.dsp|20010305004135|13384|61b563f4ac1f73eb
+tim@threads.polyesthetic.msg|bdb/docs/api_c/c_pindex.html|20010305004145|05766|697acebf58a8db4
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_nelem.html|20010305004144|10635|bd8371e033b15c8f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_len.html|20010305004144|15420|f30d68257bd60e1e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_put.html|20010305004144|27355|a2c4a52329376657
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_recover.html|20010305004145|36580|8dd351545b444a24
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_timestamp.html|20010305004145|37492|ddb77d7dfb531085
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_strerror.html|20010305004145|39331|7f090bf26bdd4dc
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_exists.html|20010305004144|12261|23f077e82ca8f827
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_fsync.html|20010305004144|13884|f59339ff63d95e7d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_read.html|20010305004144|18372|c8f6ece1ed408bf8
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_key_range.html|20010305004146|03630|d79b373af096cb7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_upgrade.html|20010305004146|28493|c6231eb2f9989284
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_put.html|20010305004146|35761|11e6aa2492dd1032
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbt_class.html|20010305004145|17281|fb91648586c1aa77
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_paniccall.html|20010305004145|20292|2080056f15faa516
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_recover.html|20010305004146|02235|cdf13797131b2d97
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/except_class.html|20010305004145|21277|59839667e43592e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_flush.html|20010305004146|16027|3976f77e905f35eb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get.html|20010305004147|27733|87b8316c55b24739
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_verify.html|20010305004147|60082|20873ab17f6ed922
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_del.html|20010305004147|63111|6ec2b8a4b8dde996
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_bsize.html|20010305004147|11335|6c67beed877df84c
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max.html|20010305004147|16607|12b6e34ac5a53281
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_version.html|20010305004148|05599|854d26806930cab6
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fset.html|20010305004148|24178|5c5371a93b83275
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_begin.html|20010305004148|30859|553bf78bd7fc3e0a
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_cursor.html|20010305004148|40924|e035b3c11a91c5d6
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_type.html|20010305004148|44686|7202f3ca793e6ec3
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn.html|20010305004148|62085|8e345950e6029230
+tim@threads.polyesthetic.msg|bdb/docs/images/prev.gif|20010305004148|04639|9448d24755d708a0
+tim@threads.polyesthetic.msg|bdb/docs/images/ps.gif|20010305004148|05648|f6b1b372cb2cda4c
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/logrec.html|20010305004149|28646|5edeb34d63936e2
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/progmodel.html|20010305004149|38491|caa422dc155b6370
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/intro.html|20010305004149|00770|2975a07b53b12046
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/need.html|20010305004149|31743|43950806e35d71f
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.ps|20010305004150|02162|9851f6cdeff17481
+tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/server.html|20010305004150|14510|79f560205494295
+tim@threads.polyesthetic.msg|bdb/docs/ref/test/faq.html|20010305004151|38444|f95038006d18229
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/admin.html|20010305004151|41323|cf867ed0b00cccef
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/data_open.html|20010305004151|45592|413c1d8aba9d8018
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv.html|20010305004151|08972|f9863847dc1ed617
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/join.html|20010305004151|18031|ec21d874caa0654
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/stat.html|20010305004151|29377|775d75e3ba02d15c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/toc.html|20010305004151|30301|16e7d8e76496cbc9
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/env.html|20010305004152|40827|381e366a9c9c9a37
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/disk.html|20010305004152|55280|61799ebebe78ebb2
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/mutexlock.html|20010305004152|58567|972b710c5bdba67c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/notfound.html|20010305004152|59393|dc91c094aba92838
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_load.html|20010305004152|10976|981095940db0197
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_printlog.html|20010305004152|11895|fcc4075ad0232842
+tim@threads.polyesthetic.msg|bdb/include/db_ext.h|20010305004137|29469|a1e210bbd0de0a48
+tim@threads.polyesthetic.msg|bdb/include/gen_client_ext.h|20010305004138|06647|5c621cacb18b38
+tim@threads.polyesthetic.msg|bdb/include/lock_ext.h|20010305004138|11814|ccd0785bb206933f
+tim@threads.polyesthetic.msg|bdb/log/log_auto.c|20010305004137|49459|fe8c0369965f7151
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server.x|20010305004141|47705|811aeb6b630fe7aa
+BK|include/Attic/m_ctype.h.in|19700101030959|00114|f671e3c2d611ba97
+BK|include/global.h|19700101030959|00077|e80d28157acfdcb5
+BK|sql/share/norwegian-ny/.cvsignore|19700101030959|01855|469064b5190d703d
+BK|sql/share/swedish/errmsg.sys|19700101030959|01866|dd772e93db859993
+BK|strings/Attic/ctype-danish.c|19700101030959|01342|dc5451066eb272ae
+BK|strings/Attic/ctype-swe7.c|19700101030959|01355|bb1b012225d7d02c
+BK|strings/Attic/ptr_cmp.c|19700101030959|01337|57e682a26e769597
+BK|vio/VioFd.cc|19700101030959|00009|6e444647affef63b
+BK|vio/vioelitexx.cc|19700101030959|00022|3eaba70da792a7fc
+miguel@hegel.local|zlib/adler32.c|20020319032513|04487|f98728c6da1ac164
+miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsp|20020319032514|38372|a1c6749052ce48a
+miguel@hegel.local|zlib/contrib/delphi2/zlib.pas|20020319032515|28965|3c94d3f5262cbbdd
+miguel@hegel.local|zlib/contrib/iostream2/zstream_test.cpp|20020319032515|08848|63f635d540de8c48
+miguel@hegel.local|zlib/contrib/minizip/readme.txt|20020319032516|00611|7547b986c067c008
+miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsw|20020319032516|60515|17f28194a5cd80ea
+miguel@hegel.local|zlib/example.c|20020319032517|14327|490f57a4a9440dfa
+miguel@hegel.local|zlib/infblock.h|20020319032517|46202|4526bc327b4160ab
+miguel@hegel.local|zlib/infutil.h|20020319032518|12977|13089e09be34788c
+miguel@hegel.local|zlib/readme|20020319032519|35257|80a41fc822f5f4
+mikef@nslinux.bedford.progress.com|mysql-test/include/have_gemini.inc|20010321203410|40631|42f94f0dfd0f7b18
+monty@donna.mysql.com|sql-bench/Results/RUN-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15344|d922a0fcc1009130
+monty@donna.mysql.com|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15933|840503a555e420ec
+monty@donna.mysql.com|sql-bench/Results/create-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20136|241c337935ae1524
+monty@hundin.mysql.fi|sql-bench/Results/insert-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|15984|a0143553cccb54e2
+monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.13_SMP_alpha|20001014001004|29737|db59425a7f4aa93f
+monty@work.mysql.com|libmysqld/README|20010411110351|24268|434e9cae5fa9a4c4
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000010.xml|20001017133713|64368|9b98c9cce8fac145
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000012.xml|20001017133713|01909|a410d08dc4cfee11
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000024.xml|20001017133713|22352|dd067aa28220fa4c
+serg@serg.mysql.com|mysql-test/r/ft0000002.a.result|20001212120058|27306|a89b4db1db19f944
+serg@serg.mysql.com|mysql-test/t/sel000014.test|20001211130731|22977|74cb8c70f1d73fcc
+tim@threads.polyesthetic.msg|bdb/build_win32/db_dll.dsp|20010305004134|29137|4e9dda53c84511b6
+tim@threads.polyesthetic.msg|bdb/build_win32/db_load.dsp|20010305004134|32237|e83a2af8e24a715d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_get.html|20010305004144|26284|4bf7579a92c35195
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbm.html|20010305004144|04019|ebf1d8e329b06bba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_feedback.html|20010305004145|02860|87a78f97ba545aba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_max.html|20010305004145|06288|319c24b5245b0685
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_compare.html|20010305004145|47782|4f12fdf04d30ab94
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_sleep.html|20010305004144|21928|4b962c8b82989d8c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_yield.html|20010305004144|25375|ca5e359bcbeca7fd
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_id.html|20010305004144|04952|1e71088a7e8f6678
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_prepare.html|20010305004145|03605|19f84203db4e6608
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_err.html|20010305004145|10496|77022bd5af575696
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_close.html|20010305004146|30462|2adba79b482ee157
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tas_spins.html|20010305004146|64671|a107049f4776b358
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_verbose.html|20010305004146|04365|e804a65368b5cdc1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_put.html|20010305004146|09587|9eb85a1c9e88621
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_file.html|20010305004146|14965|9a724b41d84e0c31
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fopen.html|20010305004146|24842|abfef0a4db99c8e1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_errpfx.html|20010305004147|42881|c446da51277796df
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_flags.html|20010305004147|46212|b6b9d271bd42a94e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_upgrade.html|20010305004147|59076|782fa4cc6c633990
+tim@threads.polyesthetic.msg|bdb/docs/api_java/deadlock_class.html|20010305004147|14282|b587b2d8c9e5d0b0
+tim@threads.polyesthetic.msg|bdb/docs/api_java/get_errno.html|20010305004147|17836|89a89f8efe3a9360
+tim@threads.polyesthetic.msg|bdb/docs/api_java/java_pindex.html|20010305004148|35859|f8bc0811d8eda8e9
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_get.html|20010305004148|07401|fd52de261831f9b5
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_vec.html|20010305004148|11077|df5eb838fdbe1eab
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curdel.html|20010305004148|13236|39bf0a8cba99c064
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/delete.html|20010305004148|18364|9195664374690b24
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/opensub.html|20010305004148|24500|81c79cce793fb343
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/stability.html|20010305004148|30129|a92faac934d69cef
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/solaris.html|20010305004149|57063|3a85fb541538d0d7
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/test.html|20010305004149|58940|b2c2f275a0c3e783
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/test.html|20010305004149|02729|84090b57cb7f0cf8
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/open.html|20010305004149|21520|37a6e67d520d6c00
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/appsignals.html|20010305004150|48930|3ab63bf9399d7ead
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/byteorder.html|20010305004150|49835|f7fa52b53e4c8838
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/compatible.html|20010305004150|50729|237b98e6a6d7ed35
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/extending.html|20010305004150|56407|6a86a40872d6b8bc
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/runtime.html|20010305004150|61233|6853fdbfe15df788
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.html|20010305004150|00758|bad2247b4f8c582b
+tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/client.html|20010305004150|12568|824178f8626e45b7
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/del.html|20010305004150|19030|514a1bd568ed4c1d
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/get.html|20010305004150|20970|211de230d6a6cbc5
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/env_open.html|20010305004151|47233|c8d61102658c3bbf
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/filesys.html|20010305004151|48077|ebee24f726f99bf6
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/intro.html|20010305004151|16219|7ecd16967b0bc868
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_put.html|20010305004151|21664|fd9ed0b04b465af
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/rmw.html|20010305004151|28431|992b0143d13a3ec0
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_stat.html|20010305004152|13652|9582c327964e1f9
+tim@threads.polyesthetic.msg|bdb/include/btree_auto.h|20010305004137|17274|84d4451c78faf67e
+BK|sql/share/polish/errmsg.sys|19700101030959|01857|126b03af92054f0f
+BK|strings/Attic/ct_init.c|19700101030959|01338|f0948bdd35ceedc3
+BK|strings/Attic/ctype.c.in|19700101030959|01361|8bf48d4bcbc5f675
+BK|vio/Vio.h|19700101030959|00004|f4416b2949647602
+BK|vio/VioSSL.h|19700101030959|00014|70d367b7ec8cac3e
+BK|vio/violite.h|19700101030959|00023|58d2942a52ea7a83
+miguel@hegel.local|zlib/contrib/asm586/readme.586|20020319032514|57815|f60bfeefb27217d
+miguel@hegel.local|zlib/contrib/delphi/zlibdef.pas|20020319032514|18918|658cb04db561e3db
+miguel@hegel.local|zlib/contrib/delphi2/d_zlib.bpr|20020319032514|25335|c267d77cc2e2a2c8
+miguel@hegel.local|zlib/contrib/minizip/zip.h|20020319032516|40925|17fd39ccb4ea294c
+miguel@hegel.local|zlib/gzio.c|20020319032517|27098|e02d23e656c19359
+monty@donna.mysql.com|sql-bench/Results/select-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|23395|8ef771713f89e1
+monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|11725|dfc480becae45236
+monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|06287|d275df58a04737c8
+mwagner@evoq.home.mwagner.org|Docs/Books/algor.eps|20001231203219|20480|481984607c98d715
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000011.xml|20001017133713|00331|432156d127cbd22f
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000015.xml|20001017133749|30814|b72689a8f9b21372
+mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/mysqltest.xsl|20001013051514|27425|1b8f6ec4f1b5f634
+sasha@mysql.sashanet.com|mysql-test/t/df_crash.test|20010406010433|65180|4c365178fe437f6
+serg@serg.mysql.com|mysql-test/t/sel000008.test|20001211130730|28581|b338ef585cadf7ae
+serg@serg.mysql.com|mysql-test/t/sel000012.test|20001211130731|13215|ae64bff363c42e92
+serg@serg.mysql.com|mysql-test/t/sel000027.test|20001211130731|23677|ab44bb57a580de9
+tim@threads.polyesthetic.msg|bdb/db/crdel_auto.c|20010305004136|27298|ee4146a08fd175c1
+tim@threads.polyesthetic.msg|bdb/dist/config.hin|20010305004136|15955|fdecb7a06fa137a7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_join.html|20010305004144|32446|a58c2d81ecfea5b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_ffactor.html|20010305004144|08766|41352ddf74ccc338
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_lorder.html|20010305004144|11587|e24ae76325374653
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_dir.html|20010305004145|05444|26be310214a2ff8f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_region_init.html|20010305004145|31081|2ca19f76ee1ae790
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_shm_key.html|20010305004145|32880|cf5aaa6a995cbf55
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_version.html|20010305004145|40251|9bf7f99fefacc2bf
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_get.html|20010305004145|50583|24cdf17ba55cbecf
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_open.html|20010305004146|04518|ab95c48ac26ad3f7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_q_extentsize.html|20010305004146|21826|b17e340a68ede3ac
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_realloc.html|20010305004145|14370|64d967a58c328957
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_feedback.html|20010305004146|43755|1d5bd8dfe2d8034e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mutexlocks.html|20010305004146|55575|f73e7ffdd2d8d62f
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_shm_key.html|20010305004146|62685|65b2c2f848ddf31e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tmp_dir.html|20010305004146|00169|6c815da1fad27537
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_detect.html|20010305004146|07495|bb50519c431233ed
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fsync.html|20010305004146|28227|76d47da7c5dc8932
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_cachesize.html|20010305004147|40035|22d172a2d29f276b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_lorder.html|20010305004147|50103|f64cbdd62bbbdd7c
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_pagesize.html|20010305004147|51079|d899ea90b20b7b31
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_pad.html|20010305004147|54985|2729c192747ac7af
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errpfx.html|20010305004147|08227|a3b9a09670f6912
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_flags.html|20010305004147|10283|690847bb5e205c21
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_file.html|20010305004148|13857|74a49bae2532199a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fget.html|20010305004148|21431|ca84dee01997eb89
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_abort.html|20010305004148|29858|ec9a3517748bfa3
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_id.html|20010305004148|01920|798720b73cc9391
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_close.html|20010305004148|53244|ef431e58d72accc3
+tim@threads.polyesthetic.msg|bdb/docs/images/next.gif|20010305004148|03600|ddab96466674135b
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curdup.html|20010305004148|14243|5c855e1f5b99d990
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/partial.html|20010305004148|26629|db4a970c839b3051
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/stat.html|20010305004148|32050|fafc0f88571d9395
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/upgrade.html|20010305004149|00532|c7499736f03c1a1c
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/re_source.html|20010305004149|31346|b000d11ca4a0f9a
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/shlib.html|20010305004149|56099|7168ed40f2e1155d
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/faq.html|20010305004149|61835|cdb7646d3d2e6374
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/region.html|20010305004149|22506|cc94139c8daa7f6a
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/security.html|20010305004149|24507|e455f95aee7f5cd2
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbis.html|20010305004149|28303|e672b7615d70be2c
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/copy.html|20010305004150|51641|bcf5ff9656fafcd3
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/libtp_usenix.ps|20010305004150|08667|73329b041f7e8c41
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/open.html|20010305004150|24776|5d6eb5c3df68eeee
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/checkpoint.html|20010305004151|43948|29e077c954369ed
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/cursor.html|20010305004151|44775|824b2f28c9e8d610
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/inc.html|20010305004151|48911|5ea32b4e2a2107b3
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/writetest.txt|20010305004151|58289|4de1fc39894cd760
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/intro.html|20010305004151|60722|85fabd5518fb26be
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/eacces.html|20010305004151|12569|f0299373d8b2f65c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/eagain.html|20010305004151|13462|920800d8eb450f79
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_begin.html|20010305004151|31307|53512180de5fec80
+tim@threads.polyesthetic.msg|bdb/include/log_ext.h|20010305004138|14339|2988f11d4545c76b
+tim@threads.polyesthetic.msg|bdb/include/xa_ext.h|20010305004138|36449|50918e5ef9f095b6
+tim@threads.polyesthetic.msg|bdb/java/src/com/sleepycat/db/DbConstants.java|20010305004138|56622|15fa87eda6b72302
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 16db163b051..f5c07363623 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -1,27 +1,74 @@
+Administrator@co3064164-a.
+Administrator@co3064164-a.rochd1.qld.optushome.com.au
+Administrator@fred.
Miguel@light.local
Sinisa@sinisa.nasamreza.org
+ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
+akishkin@work.mysql.com
+arjen@co3064164-a.bitbike.com
arjen@fred.bitbike.com
+arjen@george.bitbike.com
+bar@bar.udmsearch.izhnet.ru
+bell@sanja.is.com.ua
+davida@isil.mysql.com
heikki@donna.mysql.fi
heikki@hundin.mysql.fi
+jani@dsl-jkl1657.dial.inet.fi
+jani@hynda.(none)
jani@hynda.mysql.fi
+jani@janikt.pp.saunalahti.fi
+jani@rhols221.adsl.netsonic.fi
+jani@rhols221.arenanet.fi
+jcole@abel.spaceapes.com
+jcole@main.burghcom.com
+jcole@mugatu.spaceapes.com
+jcole@sarvik.tfr.cafe.ee
+jcole@tetra.spaceapes.com
jorge@linux.jorge.mysql.com
+kaj@work.mysql.com
+lenz@kallisto.mysql.com
lenz@mysql.com
miguel@hegel.local
miguel@light.local
monty@bitch.mysql.fi
monty@donna.mysql.fi
monty@hundin.mysql.fi
+monty@mashka.mysql.fi
+monty@narttu.
+monty@narttu.mysql.fi
monty@tik.
monty@tik.mysql.fi
+monty@tramp.mysql.fi
monty@work.mysql.com
mwagner@cash.mwagner.org
+mwagner@evoq.mwagner.org
nick@nick.leippe.com
paul@central.snake.net
+paul@teton.kitebird.com
+peter@linux.local
+root@x3.internalnet
+salle@geopard.(none)
+salle@geopard.online.bg
sasha@mysql.sashanet.com
serg@serg.mysql.com
serg@sergbook.mysql.com
sinisa@rhols221.adsl.netsonic.fi
+tfr@indrek.tfr.cafe.ee
+tfr@sarvik.tfr.cafe.ee
+tim@bitch.mysql.fi
+tim@black.box
+tim@hundin.mysql.fi
+tim@threads.polyesthetic.msg
+tim@white.box
+tim@work.mysql.com
+tom@basil-firewall.home.com
+tonu@hundin.mysql.fi
+tonu@volk.internalnet
+tonu@x153.internalnet
+tonu@x3.internalnet
+venu@work.mysql.com
+walrus@mysql.com
+worm@altair.is.lan
zak@balfor.local
-monty@narttu.
-monty@mashka.mysql.fi
-bar@bar.udmsearch.izhnet.ru
+zak@linux.local
+zgreant@mysql.com
diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit
index dc5f2f2b824..603bd43e804 100755
--- a/BitKeeper/triggers/post-commit
+++ b/BitKeeper/triggers/post-commit
@@ -4,6 +4,7 @@
TO=dev-public@mysql.com
FROM=$USER@mysql.com
INTERNALS=internals@lists.mysql.com
+DOCS=docs-commit@mysql.com
LIMIT=10000
if [ "$REAL_EMAIL" = "" ]
@@ -17,37 +18,67 @@ BK_STATUS=$BK_STATUS$BK_COMMIT
if [ "$BK_STATUS" = OK ]
then
+
+#++
+# dev-public@
+#--
echo "Commit successful, notifying developers at $TO"
(
cat <<EOF
-List-ID: <bk.mysql>
+List-ID: <bk.mysql-4.0>
From: $FROM
To: $TO
-Subject: bk commit into 3.23 tree
+Subject: bk commit - 4.0 tree
EOF
bk changes -v -r+
bk cset -r+ -d
) | head -n $LIMIT | /usr/sbin/sendmail -t
+
+#++
+# internals@ mail
+#--
echo "Notifying internals list at $INTERNALS"
(
cat <<EOF
-List-ID: <bk.mysql>
+List-ID: <bk.mysql-4.0>
From: $FROM
To: $INTERNALS
-Subject: bk commit into 3.23 tree
+Subject: bk commit into 4.0 tree
+
+Below is the list of changes that have just been committed into a
+4.0 repository of $USER. When $USER does a push these changes will
+be propagated to the main repository and, within 24 hours after the
+push, to the public repository.
+For information on how to access the public repository
+see http://www.mysql.com/doc/I/n/Installing_source_tree.html
+
+EOF
+ bk changes -v -r+
+ bk cset -r+ -d
+ ) | head -n $LIMIT | /usr/sbin/sendmail -t
-Below is the list of changes that have just been commited into a local
-3.23. repository of $USER. When $USER does a push, they will be
-propogaged to the main repository and within 24 hours after the push into
-the public repository. For information on how to access
-the public repository see
-http://www.mysql.com/doc/I/n/Installing_source_tree.html
+#++
+# docs-commit@ mail
+# Picks up anything under the Docs subdirectory (relevant for docs team).
+#--
+ bk changes -v -r+ | grep -q " Docs/"
+ if [ $? -eq 0 ]
+ then
+ echo "Notifying docs list at $DOCS"
+ (
+ cat <<EOF
+List-ID: <bk.mysql-4.0>
+From: $FROM
+To: $DOCS
+Subject: bk commit - 4.0 tree (Manual)
EOF
bk changes -v -r+
bk cset -r+ -d
) | head -n $LIMIT | /usr/sbin/sendmail -t
+ fi
+
else
echo "commit failed because '$BK_STATUS', sorry life is hard..."
fi
diff --git a/Build-tools/Do-all-build-steps b/Build-tools/Do-all-build-steps
index eb14b7105cd..8ff8851aecd 100755
--- a/Build-tools/Do-all-build-steps
+++ b/Build-tools/Do-all-build-steps
@@ -63,9 +63,13 @@ aclocal; autoheader; aclocal; automake; autoconf
--with-low-memory \
--with-mit-threads=yes $EXTRA_CONFIG \
--enable-thread-safe-client \
- --with-berkeley-db \
--enable-local-infile \
- --with-innodb
+ --with-berkeley-db \
+ --with-innodb \
+ --with-vio \
+ --without-pstack \
+ --with-extra-tools \
+ --with-embedded-server
gmake -j 2
diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile
index ffd8815fdb1..0e7922c5f2f 100755
--- a/Build-tools/Do-compile
+++ b/Build-tools/Do-compile
@@ -2,12 +2,12 @@
use Getopt::Long;
$opt_distribution=$opt_user=$opt_result=$opt_config_options=$opt_config_env="";
-$opt_dbd_options=$opt_perl_options=$opt_suffix="";
+$opt_dbd_options=$opt_perl_options=$opt_make_options=$opt_suffix="";
$opt_tmp=$opt_version_suffix="";
$opt_help=$opt_Information=$opt_delete=$opt_debug=$opt_stage=$opt_rsh_mail=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_no_mysqltest=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=0;
$opt_innodb=$opt_bdb=0;
-GetOptions("Information","help","distribution=s","user=s","result=s","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip","version-suffix=s", "with-other-libc=s") || usage();
+GetOptions("Information","help","distribution=s","user=s","result=s","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","make-options=s", "sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip","version-suffix=s", "with-other-libc=s") || usage();
usage() if ($opt_help || $opt_Information);
usage() if (!$opt_distribution);
@@ -172,8 +172,11 @@ if ($opt_stage <= 1)
if ($opt_stage <= 2)
{
+ my ($command);
unlink($opt_distribution) if ($opt_delete && !$opt_use_old_distribution);
- safe_system("$make");
+ $command=$make;
+ $command.= " $opt_make_options" if (defined($opt_make_options) && $opt_make_options ne "");
+ safe_system($command);
}
#
@@ -225,7 +228,7 @@ if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest)
{
system("mkdir $bench_tmpdir") if (! -d $bench_tmpdir);
safe_cd("${test_dir}/mysql-test");
- check_system("./mysql-test-run --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --sleep=10", "tests were successful");
+ check_system("./mysql-test-run --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful");
}
# Start the server if we are going to run any of the benchmarks
@@ -368,6 +371,9 @@ To set up the environment, like 'CC=cc CXX=gcc CXXFLAGS=-O3'
--dbd-options 'options'
Options for Makefile.PL when configuring msql-mysql-modules.
+--make-options 'options'
+Options to make after configure. (Like 'CXXLD=gcc')
+
--version-suffix suffix
Can be used to set a suffix (normally 'com' or '-max') for a distribution
diff --git a/Build-tools/Do-linux-build b/Build-tools/Do-linux-build
index 60cbf3426a8..44a9ad05fa2 100755
--- a/Build-tools/Do-linux-build
+++ b/Build-tools/Do-linux-build
@@ -3,7 +3,8 @@
set -e -x
# Only use the "--with-other-libc" parameter, if another libc actually
-# exists at this location
+# exists, since this will also force static linking, which does not work
+# together with OpenSSL
OTHER_LIBC_DIR=/usr/local/mysql-glibc
OTHER_LIBC=""
if [ -d OTHER_LIBC_DIR ] ; then
diff --git a/Build-tools/Do-patch-file b/Build-tools/Do-patch-file
index 975c10c6b0e..7e6d4c493d8 100755
--- a/Build-tools/Do-patch-file
+++ b/Build-tools/Do-patch-file
@@ -13,8 +13,8 @@ NEW="mysql-$VER.tar.gz"
OLD="mysql-$PVER.tar.gz"
RESULT="mysql-$PVER-$VER.patch.gz"
PATCH_DIR=/my/web/Downloads-live/Patches
-RESULT_DIR=/my/web/Downloads-live/MySQL-3.23
-RESULT_DIR_MAX=/my/web/Downloads-live/MySQL-Max-3.23
+RESULT_DIR=/my/web/Downloads-live/MySQL-4.0
+RESULT_DIR_MAX=/my/web/Downloads-live/MySQL-Max-4.0
if test ! -f $NEWDIR/$NEW
then
diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm
index e80cb3f2028..6d107bc2413 100755
--- a/Build-tools/Do-rpm
+++ b/Build-tools/Do-rpm
@@ -5,6 +5,7 @@
function copy_to_bmachine
{
if [ x$local_build = x1 ]; then
+ rm -f $2
cp $1 $2
else
scp $1 $owner@$bmachine:$2
@@ -14,6 +15,7 @@ function copy_to_bmachine
function copy_from_bmachine
{
if [ x$local_build = x1 ]; then
+ rm -f $2
cp $1 $2
else
scp $owner@$bmachine:$1 $2
@@ -104,10 +106,7 @@ while test $# -gt 0; do
done
echo "Removing old MySQL packages"
-rm -rf $rpmdir/BUILD/mysql-*
-rm -f $rpmdir/SOURCES/mysql-*
-rm -f $rpmdir/SRPMS/MySQL-*
-rm -f $rpmdir/SPEC/mysql-*
+rm -f $bpath/NEW-RPMS/MySQL-*rpm
if [ ! -d "$logdir" ]; then
echo "$logdir does not exist, creating"
@@ -119,12 +118,20 @@ if [ ! -f "$tarball" ]; then
exit 1
fi
-echo "Building RPM for MySQL version $VER on $bmachine"
-
log=$logdir/Log-RPM-`date +%y%m%d-%H%M`
+echo "Building RPM for MySQL version $VER on $bmachine"
+echo "Details in $log"
+
(
set -x
+# remove old stuff
+rm -rf $rpmdir/BUILD/mysql-*
+rm -f $rpmdir/SOURCES/mysql-*
+rm -f $rpmdir/SRPMS/MySQL-*
+rm -f $rpmdir/SPECS/mysql-*
+rm -rf /var/tmp/mysql
+
# Copy MySQL source and spec files
#Sasha: I left the scp stuff commented out instead of deleted to make it
@@ -174,7 +181,7 @@ if [ ! x$skip_perl=x1 ]; then
set -x
# First clean up so we do not get old versions when wildcard matching
- rm -f $rpmdir/SOURCES/DBI-*.spec
+ rm -f $rpmdir/SOURCES/DBI-*.spec $rpmdir/SOURCES/mysql*
rm -f $rpmdir/RPMS/i386/Perl-*.rpm
rm -f $rpmdir/SRPMS/Perl-*.rpm
rm -f $rpmdir/RPMS/i386/MySQL*-$VER_NO_DASH*.rpm
@@ -244,5 +251,9 @@ if [ x$local_build != x1 ]; then
# And the perl ones
#scp $owner@$bmachine:$rpmdir/RPMS/i386/Perl*-*.rpm $bpath/NEW-RPMS
#scp $owner@$bmachine:$rpmdir/SRPMS/Perl*-*.rpm $bpath/NEW-RPMS
+
+ #Remove some of the files that can interfere with future builds
+
+ rm -rf /var/tmp/mysql
fi
) > $log 2>&1
diff --git a/Docs/Flags/argentina.eps b/Docs/Flags/argentina.eps
index 840e24188ad..c0a9dae067e 100644
--- a/Docs/Flags/argentina.eps
+++ b/Docs/Flags/argentina.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: argentina.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-676767676767676767676767676767676767676767676767676767676767
-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
-f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f7f7f7f7f7f7f7f7f7f7f7f7f7f8f9f9f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f5f3f2f6f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7e6cdc5eef7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f8fafdfdfaf7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f5f0f2f2f1f6f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7e79441419eebf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f9fdf3eefdf8f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f3f3eee9f1f3f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c93f00004fd5f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f9fde9edfdf8f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f2f3e4eaf2f3f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c43e00014ed0f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7fafdfdfaf7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f6f1f1f2f1f6f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7ec9b4c4ca4f1f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f8f9f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f5f3f2f6f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7e9d5cdf1f7f7f7f7f7f7f7f7f7f7f7f7f7
-585858585858585858585858585858585858585858585858585858585858
-c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00006161616161616161616161616161616161
+616161616161616161616161610000cacacacacacacacacacacacacacaca
+cacacacacacacacacacacacacacaca0000f2f2f2f2f2f2f2f2f2f2f2f2f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f20000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f9f9f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f6f3f3f6f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7eccbccecf7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7fafdfdfaf7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f6f0f2f2f0f6f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7ec9b45459becf7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f9fdf2eefdf9f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f3f2ede9f2f3f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7cb45000045cbf7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f9fdebeafdf9f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f3f2e7e7f2f3f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7cb45000045cbf7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7fafdfdfa
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f6f1f2
+f2f1f6f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7ec
+9b45459becf7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f9f9f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f6f3f3f6f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7eccbcbecf7f7f7f7f7f7f7f7f7f7f7f7f700006363636363
+636363636363636363636363636363636363636363636363630000cbcbcb
+cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb0000f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f200
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/argentina.gif b/Docs/Flags/argentina.gif
index 8fef5c3f455..b1bba9778cc 100644
--- a/Docs/Flags/argentina.gif
+++ b/Docs/Flags/argentina.gif
Binary files differ
diff --git a/Docs/Flags/argentina.pdf b/Docs/Flags/argentina.pdf
new file mode 100644
index 00000000000..4ccb26eec76
--- /dev/null
+++ b/Docs/Flags/argentina.pdf
Binary files differ
diff --git a/Docs/Flags/armenia.eps b/Docs/Flags/armenia.eps
new file mode 100644
index 00000000000..dad5ef59c31
--- /dev/null
+++ b/Docs/Flags/armenia.eps
@@ -0,0 +1,256 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: Adobe Photoshop Version 5.5
+%%Title: armenia.eps
+%%CreationDate: Sun Mar 24 2002 12:12:59
+%%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: 1288
+% 3842494D03ED000000000010004800000001000200480000000100023842494D
+% 040D000000000004000000783842494D03F30000000000080000000000000000
+% 3842494D040A00000000000100003842494D271000000000000A000100000000
+% 000000023842494D03F5000000000048002F66660001006C6666000600000000
+% 0001002F6666000100A1999A0006000000000001003200000001005A00000006
+% 000000000001003500000001002D000000060000000000013842494D03F80000
+% 000000700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E80000
+% 0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFF
+% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFFFFFF
+% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800003842494D0408000000000010
+% 000000010000024000000240000000003842494D041400000000000400000001
+% 3842494D040C0000000003890000000100000020000000160000006000000840
+% 0000036D00180001FFD8FFE000104A46494600010201004800480000FFEE000E
+% 41646F626500648000000001FFDB0084000C08080809080C09090C110B0A0B11
+% 150F0C0C0F1518131315131318110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C
+% 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C010D0B0B0D0E0D100E0E10140E0E0E
+% 14140E0E0E0E14110C0C0C0C0C11110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C
+% 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC0001108001600200301220002
+% 1101031101FFDD00040002FFC4013F0000010501010101010100000000000000
+% 030001020405060708090A0B0100010501010101010100000000000000010002
+% 030405060708090A0B1000010401030204020507060805030C33010002110304
+% 211231054151611322718132061491A1B14223241552C16233347282D1430725
+% 9253F0E1F163733516A2B283264493546445C2A3743617D255E265F2B384C3D3
+% 75E3F3462794A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F637
+% 475767778797A7B7C7D7E7F71100020201020404030405060707060535010002
+% 1103213112044151617122130532819114A1B14223C152D1F0332462E1728292
+% 435315637334F1250616A2B283072635C2D2449354A317644555367465E2F2B3
+% 84C3D375E3F34694A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6
+% F62737475767778797A7B7C7FFDA000C03010002110311003F00E171D98271EA
+% 2E6D5BB6377486CCC7744F4FA7FEED3F73558C3FA9BF59327128C8A70F7D5756
+% CB2B77A95096B9A1EC743AD0EFA251BFE637D69FFB85FF0082D3FF00A554E395
+% F841172F8AE18C8FCD139F07A65D63FCE3AB1F8AE58C40FB9C0D002F865AFF00
+% CD68FA7D3FF769FB9A8790CC118F696B6ADDB1DB6036663B2D2FF98DF5A7FEE1
+% 7FE0B4FF00E9541CCFA9BF5931B12FC8BB0F6554D6FB2C77A95186B5A5EF7436
+% D2EFA2123CAFC200B8FC570CA43E588CF83D52E91FE7152F8AE59448FB9C0582
+% 2F865A7FCD7FFFD0D2E81D47319D0BA731BD2F2AC6B716802C6BB1435C056CF7
+% B7D4CC659B5DFCB62BFF00B533BFF2A333FCFC4FFDEE5E1292E1737B7EEE4FE6
+% BE797FE28FDE74E37C23E6DBFA8FBB7ED4CEFF00CA8CCFF3F13FF7B950EBFD47
+% 31FD0BA8B1DD2F2AB6BB16F06C73B14B5A0D6FF7BBD3CC7D9B5BFC862F18492C
+% 3EDFBB8FF9AF9E3FF8A3F7952BE13F36DFD47FFFD9003842494D03FD00000000
+% 0006000000000000
+%EndPhotoshop
+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
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+
+%%EndBinary
+grestore end % Image Trailer grestore
+grestore % EPS grestore
diff --git a/Docs/Flags/armenia.gif b/Docs/Flags/armenia.gif
new file mode 100755
index 00000000000..6bd3b861015
--- /dev/null
+++ b/Docs/Flags/armenia.gif
Binary files differ
diff --git a/Docs/Flags/island.eps b/Docs/Flags/armenia.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/island.eps
+++ b/Docs/Flags/armenia.txt
diff --git a/Docs/Flags/australia.eps b/Docs/Flags/australia.eps
index f98c03e2c83..9f772787ae7 100644
--- a/Docs/Flags/australia.eps
+++ b/Docs/Flags/australia.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: australia.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-cf7b0e0808087cc6730808081084c4080808080808080808080808080808
-3f5c0600000050005300000009603a000000000000000000000000000000
-43b5b6b5b5b5a600b1b5b5b5b7b246b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-b1d2b73608087cc67308083dbcd3a5080808080808080809080808080808
-8d3e612f00005000530000355e4285000000000000000001000000000000
-bc3e82c0b5b5a600b1b5b5c17a43bfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-096bd4cf7b0e7cc6731083d0d36108080808080808084d990c0808080808
-0162753f5c06500053095f3c7b5b00000000000000004796040000000000
-b5cd7e43b5b7a600b1b7b13e87ccb5b5b5b5b5b5b5b5c8ddb6b5b5b5b5b5
-0c0c2bb5d3b8a3c6a2bcd3ae250c0c080808080808087bba170808080808
-040424913e6478008061438f1e04040000000000000077b70f0000000000
-b6b6bfbd3f85b000bc7d43c1bdb6b6b5b5b5b5b5b5b5d5e6b9b5b5b5b5b5
-d5d5d5d5d5d5d2c6d3d5d5d5d5d5c9080808080808080d0d080808080808
-4c4c4c4c4c4a3c00414a4c4c4c4c48000000000000000505000000000000
-4c4c4c4c4c4a3c00414a4c4c4c4c52b5b5b5b5b5b5b5b6b6b5b5b5b5b5b5
-d3d3d3d4d7d6d4c6d4d6d7d4d3d3c7080808080808080808080808080808
-51515152545044004950555251514c000000000000000000000000000000
-55555555545044004950555555555bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0a0a2fb9d2b19fc69db7d2b3290a0a080808080808080808080808080808
-0202288f3a6374007c613e8e220202000000000000000000000000000000
-b5b5c0b73b8aaf00bb823ebcbeb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0b74d6ce720b7cc6730e7bcfd46b0908080808080808080808080c080808
-036b6f435703500053065c3f756201000000000000000000000004000000
-b6cd7649b8b6a600b1b7b5437ecdb5b5b5b5b5b5b5b5b5b5b5b5b6b5b5b5
-b9d2b12f08087cc673080836b7d2ab080808110808080808080eac520808
-8f3a6328000050005300002f613e870000000a00000000000006a94d0000
-b73a8abfb5b5a600b1b5b5c0823ebab5b5b5b8b5b5b5b5b5b5b6e2cab5b5
-c7720b08080877bf6f0808080e7abd080819c757080808080819ae6f0808
-3c57030000004d004f000000065b37000011c552000000000012ac6a0000
-47b8b6b5b5b5a607b1b5b5b5b7b54ab5b5baeacbb5b5b5b5b5bae3d1b5b5
-08080808080808080808080808080808081c9e50080808080f080a0a0808
-0000000000000000000000000000000000149a4a00000000070002020000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5badec9b5b5b5b5b7b5b6b5b5b5
-0808080808080808080808080808080808080808080808119a0b08080808
-000000000000000000000000000000000000000000000009960300000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b7ddb6b5b5b5b5
-0808080808080808080808080808080808080808080808080c0808080808
-000000000000000000000000000000000000000000000000040000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b6b5b5b5b5b5
-080808080808080c08080808080808080808080808080808080808080808
-000000000000000400000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080809439144090808080808080808080808080808080808080808
-0000000000013d8e3d010000000000000000000000000000000000000000
-b5b5b5b5b5b5c5dbc5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080809b0f7b1090808080808080808080808081308080808080808
-000000000001adf7af010000000000000000000000000c00000000000000
-b5b5b5b5b5b5e3f7e4b5b5b5b5b5b5b5b5b5b5b5b5b5b8b5b5b5b5b5b5b5
-08080808081c8eed8f1d08080808080808080808083ccc3a080808080808
-0000000000158aed8c15000000000000000000000035cb34000000000000
-b5b5b5b5b5bbdaf4dabbb5b5b5b5b5b5b5b5b5b5b5c3ebc3b5b5b5b5b5b5
-0808080808082c1b2c08080808080808080808080827af26080808080808
-0000000000002513250000000000000000000000001fac1e000000000000
-b5b5b5b5b5b5bfbabfb5b5b5b5b5b5b5b5b5b5b5b5bde3bdb5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000000000000000000000
+00000000000000cf7c0e08080877c67a0808080e7ccf0808080808080808
+0808080808080800003f5d06000000500053000000065e3f000000000000
+000000000000000000000043b5b7b5b5b5ab00acb5b5b5b7b543b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000b3d2b737080877c67a080837b7d2b30808
+0808080808080908080808080800008e3d622f000050005300002f623d8e
+0000000000000000010000000000000000bc3d82c0b5b5ab00acb5b5c082
+3dbcb5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000096cd5cf7c0e77c67a0e7c
+cfd56c0908080808080808419c12080808080800000164753f5d06500053
+065d3f756401000000000000003b990b00000000000000b5cd7e43b5b7ab
+00acb7b5437ecdb5b5b5b5b5b5b5b5c5deb8b5b5b5b5b50000080828b3d2
+b7a0c6a2b7d2b32808080808080808080868c91f08080808080000000021
+8e3d6279007c623d8e2100000000000000000063c81800000000000000b5
+b5bebc3d82b500b5823dbcbeb5b5b5b5b5b5b5b5b5cfeabbb5b5b5b5b500
+00d6d6d6d6d6d5d3c6d3d5d6d6d6d6d6080808080808080e0e0808080808
+080000505050504f4d4200424d4f50505050000000000000000606000000
+0000000000505050504f4d4200424d4f50505050b5b5b5b5b5b5b5b7b7b5
+b5b5b5b5b50000d6d6d6d6d6d6d3c6d3d6d6d6d6d6d60808080808080808
+080808080808080000505050505050420042505050505050000000000000
+0000000000000000000000505050505050420042505050505050b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000b0b2bb5d2b7a0c6a2b7d2b52b0b0b0808
+080808080808080808080808080000030324913d6179007c623d91240303
+0000000000000000000000000000000000b6b6bfbd3d82b500b5823dbdbf
+b6b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000096dd5cf7b0e77c67a0e7c
+cfd56c0908080808080808080808080a08080800000165753f5c06500053
+065d3f7564010000000000000000000000030000000000b5cd7e43b5b7ab
+00acb7b5437ecdb5b5b5b5b5b5b5b5b5b5b5b5b6b5b5b50000b3d2b73608
+0877c67a080837b7d2b30808080f080808080808099861080800008f3d61
+2e000050005300002f623d8e0000000800000000000001955b00000000bc
+3d82c0b5b5ab00acb5b5c0823dbcb5b5b5b7b5b5b5b5b5b5b5ddcdb5b500
+00cf7a0e08080877c67a0808080e7bcf08080fbd5d080808080812a98708
+0800003f5b06000000500053000000065c3f000008bb5800000000000aa6
+830000000042b5b7b5b5b5ab00acb5b5b5b6b543b5b5b7e7ccb5b5b5b5b5
+b8e1d8b5b500000808080808080808080808080808080808199e64080808
+080d080b0b080800000000000000000000000000000000000000129b5f00
+0000000500030300000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5badf
+ceb5b5b5b5b6b5b6b6b5b500000808080808080808080808080808080808
+0808080808080c9a0f080808080000000000000000000000000000000000
+0000000000000000049607000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b6ddb7b5b5b5b500000808080808080808080808
+080808080808080808080808081008080808080000000000000000000000
+0000000000000000000000000000000800000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b7b5b5b5b5b500000808080808
+08080a080808080808080808080808080808080808080808080000000000
+0000000003000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808083886380a08080808080808080808080808080808080808
+080000000000000000328231020000000000000000000000000000000000
+0000000000b5b5b5b5b5b5c2d8c2b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000080808080808a7f7b70808080808080808080808080810
+080808080808080000000000000000a4f7b5000000000000000000000000
+0008000000000000000000b5b5b5b5b5b5e1f7e5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b7b5b5b5b5b5b5b5000008080808081b95f39e2108080808080808
+0808080827c242080808080808000000000000001491f39b1a0000000000
+00000000000020c03c0000000000000000b5b5b5b5b5badcf6dfbcb5b5b5
+b5b5b5b5b5b5b5b5bde8c5b5b5b5b5b5b500000808080808082f25340808
+0808080808080808080825b63f0808080808080000000000000000281e2e
+0000000000000000000000001eb3390000000000000000b5b5b5b5b5b5c0
+bdc1b5b5b5b5b5b5b5b5b5b5b5b5bde5c4b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/australia.gif b/Docs/Flags/australia.gif
index 1f403f92503..6c766cbb614 100644
--- a/Docs/Flags/australia.gif
+++ b/Docs/Flags/australia.gif
Binary files differ
diff --git a/Docs/Flags/australia.pdf b/Docs/Flags/australia.pdf
new file mode 100644
index 00000000000..f7a1d0fd53d
--- /dev/null
+++ b/Docs/Flags/australia.pdf
Binary files differ
diff --git a/Docs/Flags/austria.eps b/Docs/Flags/austria.eps
index 7a0b56f3690..c6c35dc81e2 100644
--- a/Docs/Flags/austria.eps
+++ b/Docs/Flags/austria.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: austria.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d60000505050505050505050505050505050
+505050505050505050505050505050000050505050505050505050505050
+50505050505050505050505050505050500000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000d7d7d7d7d7
+d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d70000535353
+535353535353535353535353535353535353535353535353535353000054
+545454545454545454545454545454545454545454545454545454545400
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-575757575757575757575757575757575757575757575757575757575757
-575757575757575757575757575757575757575757575757575757575757
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4
-464646464646464646464646464646464646464646464646464646464646
-474747474747474747474747474747474747474747474747474747474747
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/austria.gif b/Docs/Flags/austria.gif
index d72b945741a..26a97856627 100644
--- a/Docs/Flags/austria.gif
+++ b/Docs/Flags/austria.gif
Binary files differ
diff --git a/Docs/Flags/austria.pdf b/Docs/Flags/austria.pdf
new file mode 100644
index 00000000000..d50b4f265cd
--- /dev/null
+++ b/Docs/Flags/austria.pdf
Binary files differ
diff --git a/Docs/Flags/belgium.eps b/Docs/Flags/belgium.eps
new file mode 100644
index 00000000000..d27fda0e1e1
--- /dev/null
+++ b/Docs/Flags/belgium.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: belgium.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/belgium.gif b/Docs/Flags/belgium.gif
new file mode 100644
index 00000000000..2bb101dc501
--- /dev/null
+++ b/Docs/Flags/belgium.gif
Binary files differ
diff --git a/Docs/Flags/belgium.pdf b/Docs/Flags/belgium.pdf
new file mode 100644
index 00000000000..7696d4af102
--- /dev/null
+++ b/Docs/Flags/belgium.pdf
Binary files differ
diff --git a/Docs/Flags/island.gif b/Docs/Flags/belgium.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/island.gif
+++ b/Docs/Flags/belgium.txt
diff --git a/Docs/Flags/bulgaria.eps b/Docs/Flags/bulgaria.eps
index 6f4a07c616c..2eb04535d36 100644
--- a/Docs/Flags/bulgaria.eps
+++ b/Docs/Flags/bulgaria.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: bulgaria.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e20000a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a700000000000000000000000000
+000000000000000000000000000000000000000000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
+000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000
+000000000000000000000000000000000000000000000000008383838383
+8383838383838383838383838383838383838383838383838300003d3d3d
+3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d000000
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d
-333333333333333333333333333333333333333333333333333333333333
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/bulgaria.gif b/Docs/Flags/bulgaria.gif
index 35c0b117062..4c7377e907c 100644
--- a/Docs/Flags/bulgaria.gif
+++ b/Docs/Flags/bulgaria.gif
Binary files differ
diff --git a/Docs/Flags/bulgaria.pdf b/Docs/Flags/bulgaria.pdf
new file mode 100644
index 00000000000..24cb072598d
--- /dev/null
+++ b/Docs/Flags/bulgaria.pdf
Binary files differ
diff --git a/Docs/Flags/canada.eps b/Docs/Flags/canada.eps
index b770266de60..7773f12a699 100644
--- a/Docs/Flags/canada.eps
+++ b/Docs/Flags/canada.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: canada.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f6f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f3f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f3f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7e5ebf7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f79dbaf7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f79dbaf7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f6f5d0d6f4f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f2ed324fe9f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f2ed324fe9f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7d2c6c7d7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f73c000355f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f73c000356f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f1f7dac6c6e0f7f1f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7d7f764000081f6d9f7f7f76300000000000000
-0000000000000083f7f7f7d8f764000081f6d9f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7ede8d6d5e1c6c6e5d1dbe6f0f7dac6c6c6c6c6c6c6
-0000000000000083f7c4a951488a00009a3869a0d2f76300000000000000
-0000000000000083f7c4a952488a00009a386aa0d2f76300000000000000
-c6c6c6c6c6c6c6e0f7f3c7c6c6c7c6c6c7c6c6caf6f7dac6c6c6c6c6c6c6
-0000000000000083f7e106000003000002000014f0f76300000000000000
-0000000000000083f7e106000003000002000014f0f76300000000000000
-c6c6c6c6c6c6c6e0f7efcbc6c6c6c6c6c6c6c6cff1f7dac6c6c6c6c6c6c6
-0000000000000083f7cd1b00000000000000002bd9f76300000000000000
-0000000000000083f7cd1b00000000000000002bd9f76300000000000000
-c6c6c6c6c6c6c6e0f7f7eeddccc6c6c6c6cedff0f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7c87420000000002a7ed2f7f76300000000000000
-0000000000000083f7f7c87420000000002a7ed2f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7d7c6c7c7c6ddf7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7560003030072f7f7f7f76300000000000000
-0000000000000083f7f7f7f7560003030073f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f6f0f5e7edf4f0f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f2d6eaa8c4e8d4f6f7f7f76300000000000000
-0000000000000083f7f7f7f2d6eaa8c5e8d5f6f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7e6ecf7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7a3c0f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7a4c1f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7e6ebf7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f79fbcf7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f79fbcf7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f5f6f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7edf0f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7edf0f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7de
+c6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7
+f778000000000000000000000000000000007bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7f7f7f7
+f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7f7
+f7f7f7f7f7f7f778000000000000000000000000000000007bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7f7f7f7f7f7f7f7f7f7f7f77800000000000000000000000000000000
+7bf7f7f7f7f7f7f7f7f7f7f7f7f7f779000000000000000000c6c6c6c6c6
+c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000
+000000007bf7f7f7f7f7f7f5f5f7f7f7f7f7f77800000000000000000000
+0000000000007bf7f7f7f7f7f7f5f5f7f7f7f7f7f7790000000000000000
+00c6c6c6c6c6c6c6def7f7f7f7f7f7e8e8f7f7f7f7f7f7dec6c6c6c6c6c6
+c60000000000000000007bf7f7f7f7f7f7adadf7f7f7f7f7f77800000000
+0000000000000000000000007bf7f7f7f7f7f7adadf7f7f7f7f7f7790000
+00000000000000c6c6c6c6c6c6c6def7f7f7f7f7f5d3d3f5f7f7f7f7f7de
+c6c6c6c6c6c6c60000000000000000007bf7f7f7f7f5ec4242ecf5f7f7f7
+f778000000000000000000000000000000007bf7f7f7f7f5ec4242ecf5f7
+f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7f7f7d5c6c6d5
+f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7f7f7f7f74a01
+014af7f7f7f7f778000000000000000000000000000000007bf7f7f7f7f7
+4a01014af7f7f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f2f7dcc6c6dcf7f2f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7dcf76f00006ff7dcf7f7f77800000000000000000000000000000000
+7bf7f7f7dcf76f00006ff7dcf7f7f779000000000000000000c6c6c6c6c6
+c6c6def7eee9d9d5e4c6c6e4d5d9e9eef7dec6c6c6c6c6c6c60000000000
+000000007bf7caaf5e4995000095495eafcaf77800000000000000000000
+0000000000007bf7caaf5f4996000096495fafcaf7790000000000000000
+00c6c6c6c6c6c6c6def7f4c8c6c6c7c6c6c7c6c6c8f3f7dec6c6c6c6c6c6
+c60000000000000000007bf7e508000004000004000008e5f77800000000
+0000000000000000000000007bf7e508000004000004000008e5f7790000
+00000000000000c6c6c6c6c6c6c6def7f0cdc6c6c6c6c6c6c6c6cdf0f7de
+c6c6c6c6c6c6c60000000000000000007bf7d222000000000000000022d2
+f778000000000000000000000000000000007bf7d2220000000000000000
+22d2f779000000000000000000c6c6c6c6c6c6c6def7f7ecdccbc6c6c6c6
+cbdcecf7f7dec6c6c6c6c6c6c60000000000000000007bf7f6c16d1b0000
+00001b6dc0f6f778000000000000000000000000000000007bf7f6c16d1b
+000000001b6dc1f6f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f7dbc6c6c6c6dbf7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7f76b000000006bf7f7f7f77800000000000000000000000000000000
+7bf7f7f7f76b000000006bf7f7f7f779000000000000000000c6c6c6c6c6
+c6c6def7f7f7f7eef2e9e9f2eef6f7f7f7dec6c6c6c6c6c6c60000000000
+000000007bf7f7f7f4c8dcb0b0dcc8f4f7f7f77800000000000000000000
+0000000000007bf7f7f7f4c9dcb0b0dcc9f4f7f7f7790000000000000000
+00c6c6c6c6c6c6c6def7f7f7f7f7f7e9e9f7f7f7f7f7f7dec6c6c6c6c6c6
+c60000000000000000007bf7f7f7f7f7f7b2b2f7f7f7f7f7f77800000000
+0000000000000000000000007bf7f7f7f7f7f7b2b2f7f7f7f7f7f7790000
+00000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7e9e9f7f7f7f7f7f7de
+c6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7aeaef7f7f7f7f7
+f778000000000000000000000000000000007bf7f7f7f7f7f7aeaef7f7f7
+f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7f4f4f7
+f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7ea
+e9f7f7f7f7f7f778000000000000000000000000000000007bf7f7f7f7f7
+f7eaeaf7f7f7f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7f7f7f7f7f7f7f7f7f7f7f77800000000000000000000000000000000
+7bf7f7f7f7f7f7f7f7f7f7f7f7f7f779000000000000000000c6c6c6c6c6
+c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000
+000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f77800000000000000000000
+0000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f7790000000000000000
+00c6c6c6c6c6c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6
+c60000000000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f77800000000
+0000000000000000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f7790000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/canada.gif b/Docs/Flags/canada.gif
index 322d4b985b7..af672caf33d 100644
--- a/Docs/Flags/canada.gif
+++ b/Docs/Flags/canada.gif
Binary files differ
diff --git a/Docs/Flags/canada.pdf b/Docs/Flags/canada.pdf
new file mode 100644
index 00000000000..4ba0fd45ec6
--- /dev/null
+++ b/Docs/Flags/canada.pdf
Binary files differ
diff --git a/Docs/Flags/chile.eps b/Docs/Flags/chile.eps
index 8a5411a32a3..121bf0a51b3 100644
--- a/Docs/Flags/chile.eps
+++ b/Docs/Flags/chile.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: chile.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-08080808080808080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000000000000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808272008080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000020190000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5bebcb5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808776e08080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000073690000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5d4d1b5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808c7bd08080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000c5bb0000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5eae7b5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0868e3e9f7f6e9e16111f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0062e2e8f7f6e8e05b0af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5cff1f3f7f7f3f1cdb8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08083eddf7f7d9390811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000038dcf7f7d833000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5c4f0f7f7efc3b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808c1f7f7b8080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000000bff7f7b500000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5e8f7f7e5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08081fe86066e8190811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000018e85b61e711000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5bbf3cdcff3bab5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08083a2808082c360811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000033210000262f000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5c3beb5b5bfc2b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0e0e0e0e0e0e0e0e0e17f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-00000000000000000009f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-b0b0b0b0b0b0b0b0b0b3f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+0000000000000008080808080808080808f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7000000000000000000000000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5b5b5b5f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7000008080808232408080808f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000000000001c1c00000000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5bcbdb5b5b5b5f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008080808727208080808f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000006d6d000000
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5d2d2b5
+b5b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008080808c2
+c208080808f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000
+00c0c000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5b5b5e8e8b5b5b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+000866dfe5f6f6e5e06708f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f700000062dee4f6f6e4de6200f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5cff0f2f7f7f2f0cfb5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000080841def7f7de410808f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7000000003bddf7f7dd3b0000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000b5b5c5f0f7f7f0c5b5b5f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000080808bcf7f7bc080808f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000000000baf7f7ba000000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5e7f7f7e7b5b5b5f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008081beb6969eb1c0808f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000014ea6565ea1400
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5baf4d0d0f4
+bab5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008083b2f08
+082e3b0808f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000034
+28000028340000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5c3c0b5b5c0c3b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+0008080808080808080808f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7000000000000000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5b5b5b5b5b5b5b5b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000c4c4c4c4c4c4c4c4c4c4c7c7c7c7c7c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000000000000000000000000303030303030303030303
+030303030303030303000002020202020202020202030303030303030303
+03030303030303030303030000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/chile.gif b/Docs/Flags/chile.gif
index e7afe88df8b..dcd21381a0a 100644
--- a/Docs/Flags/chile.gif
+++ b/Docs/Flags/chile.gif
Binary files differ
diff --git a/Docs/Flags/chile.pdf b/Docs/Flags/chile.pdf
new file mode 100644
index 00000000000..6a1bfb10c0a
--- /dev/null
+++ b/Docs/Flags/chile.pdf
Binary files differ
diff --git a/Docs/Flags/china.eps b/Docs/Flags/china.eps
index 97b87f4727f..d76667bb762 100644
--- a/Docs/Flags/china.eps
+++ b/Docs/Flags/china.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: china.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c7e1c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000037602000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6cfc6c6c6c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000250000000e00000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6efc9c6c6c7e1c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000b70e00000377010000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c7e1c7c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000027602000000000000
000000000000000000000000000000000000000000000000000000000000
-c6d7f4fef7e2c7c6c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-004bccfcda7d03000d000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6cec6c6c6cac6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000240000001000
000000000000000000000000000000000000000000000000000000000000
-c6c6e2fff2c6c6c7d3c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00007dffc301000338010000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6eeca
+c6c6c7e1c7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+b41000000276020000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6e5d4e9c8c6c6d7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00008a3b9c0a00004c000000000000000000000000000000000000000000
+00c6d7f3fef7e3c7c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000004ac8fbd88103000f000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c7c6c6c7c7d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000003000003042a00000000000000000000000000000000000000000000
+00000000000000c6c6e2fff3c6c6c7d1c7c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6000000007cffc901000233020000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6dac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000015800000000000000000000000000000000000000000000
+00000000000000000000000000c6c6e6d5eac9c6c6d9c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000008c42a20b000053000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c7c6c6c7c7cec6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000005000005032301
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6dcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000016100000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/china.gif b/Docs/Flags/china.gif
index 4baf243f158..6e0c5eb42aa 100644
--- a/Docs/Flags/china.gif
+++ b/Docs/Flags/china.gif
Binary files differ
diff --git a/Docs/Flags/china.pdf b/Docs/Flags/china.pdf
new file mode 100644
index 00000000000..9706ee48a28
--- /dev/null
+++ b/Docs/Flags/china.pdf
Binary files differ
diff --git a/Docs/Flags/costa-rica.eps b/Docs/Flags/costa-rica.eps
new file mode 100644
index 00000000000..b225246c0c7
--- /dev/null
+++ b/Docs/Flags/costa-rica.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: costa-rica.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000a6a6a6a6a6
+a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a60000a3a3a3
+a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a30000e1
+e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7
+e7e7e7e7e7e7e7e7e7e7e7e7e70000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000e7e7e7e7e7
+e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e70000a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9
+a9a9a9a9a9a9a9a9a9a9a9a9a90000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2e2e2e2e2e2e2e2e2e2e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e200000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/costa-rica.gif b/Docs/Flags/costa-rica.gif
new file mode 100644
index 00000000000..becc817fdcc
--- /dev/null
+++ b/Docs/Flags/costa-rica.gif
Binary files differ
diff --git a/Docs/Flags/costa-rica.pdf b/Docs/Flags/costa-rica.pdf
new file mode 100644
index 00000000000..881d2018d83
--- /dev/null
+++ b/Docs/Flags/costa-rica.pdf
Binary files differ
diff --git a/Docs/Flags/island.txt b/Docs/Flags/costa-rica.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/island.txt
+++ b/Docs/Flags/costa-rica.txt
diff --git a/Docs/Flags/czech-republic.eps b/Docs/Flags/czech-republic.eps
index afa50e9a82d..c179b95db17 100644
--- a/Docs/Flags/czech-republic.eps
+++ b/Docs/Flags/czech-republic.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: czech-republic.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-56e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-50e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0014a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000014a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000000000014a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5cbf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000000000000000014a3f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808080808080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808080808080808080808081ba6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-0000000000000000000000000014a3f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-b5b5b5b5b5b5b5b5b5b5b5b5b5bae0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-080808080808080808080808081f93c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000010101010101010101010101010101
-b5b5b5b5b5b5b5b5b5b5b5b5b59f31010101010101010101010101010101
-08080808080808080808080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b46d0a00000000000000000000000000000000
-080808080808080808081f93c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b59f31000000000000000000000000000000000000
-08080808080808080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b46d0a00000000000000000000000000000000000000
-080808080808081f92c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+0000000000000056e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f700000013a2f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5bae0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008080856e2f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000000000050e1f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5caf1f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000080808081b
+a5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000
+0013a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+0008080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f700000000000000000013a2f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7000008080808080808080856e2f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7000000000000000000000050e1f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5b5b5caf1f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000080808080808080808081b
+a5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0013a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5
+b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700000808080808
+0808080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000
+00000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5b5b5b5b5b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00080808080808080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000013a2f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5b5b5b5b5b5b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000080808080808080808080808081784c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000000000000000000000000000000000030303030303
+0303030303030303030000b5b5b5b5b5b5b5b5b5b5b5b5b5a73f03030303
+0303030303030303030303000008080808080808080808080845b5c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b57b
+100000000000000000000000000000000000000808080808080808080817
+84c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5a73f00000000000000000000000000000000000000000808080808
+0808080845b5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b57b100000000000000000000000000000000000000000
+00080808080808081784c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5a73f00000000000000000000000000000000
+0000000000000008080808080845b5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b57b100000000000000000000000
+00000000000000000000000000080808081784c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5a73f00000000000000
+0000000000000000000000000000000000000008080845b5c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b57b100000
+00000000000000000000000000000000000000000000000000081784c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000000000000000000000000000000000000000000000000000b5
+a73f00000000000000000000000000000000000000000000000000000000
+0045b5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+00000000007b100000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b59f31000000000000000000000000000000000000000000
-08080808080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b46d0a00000000000000000000000000000000000000000000
-080808081f93c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b59f31000000000000000000000000000000000000000000000000
-08080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-b5b5b46d0a00000000000000000000000000000000000000000000000000
-081f92c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-b59f31000000000000000000000000000000000000000000000000000000
-53bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-6e0a00000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/czech-republic.gif b/Docs/Flags/czech-republic.gif
index 10d5a3c72e9..eeaeb4b791b 100644
--- a/Docs/Flags/czech-republic.gif
+++ b/Docs/Flags/czech-republic.gif
Binary files differ
diff --git a/Docs/Flags/czech-republic.pdf b/Docs/Flags/czech-republic.pdf
new file mode 100644
index 00000000000..7fb2680269f
--- /dev/null
+++ b/Docs/Flags/czech-republic.pdf
Binary files differ
diff --git a/Docs/Flags/denmark.eps b/Docs/Flags/denmark.eps
index 2f397c4af16..c3ddf74f725 100644
--- a/Docs/Flags/denmark.eps
+++ b/Docs/Flags/denmark.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: denmark.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c7c7c7c7c7c7c7c9fffffffac7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c7c9fffffffac7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c6c7c6c6c6c7c9fffffffac7c6c6c6c6c6c6c6c6c6c6c6c6c6c7c6c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c6c7c7c7c9fffffff9c7c7c7c6c6c6c6c6c6c6c6c6c6c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c6c7c7c7c7c7c9fffffffac7c7c7c7c7c7c7c7c7c7c7c6c7c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c6c7c7c7c7c8fffffffac7c7c7c7c6c6c6c6c6c6c7c7c6c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c7c9fffffff9c7c7c7c7c6c6c6c6c6c6c7c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c6c9fffffffac6c7c7c7c7c6c6c6c7c7c7c7c7c7c6c7c7c8
-060606060606060efffffff0060606060606060606060606060606060606
-020202020202020affffffe9020202020202020202020202020202020202
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-fbfbfbfbfbfbfbfbfffffffffbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-fdfdfdfdfdfdfdfdfffffffffdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-c7c7c6c6c6c6c6c8fffffff9c7c6c6c6c7c6c6c6c6c6c7c6c6c6c6c6c6c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c6c6c7c7c7c7c8fffffff9c7c7c7c7c7c7c7c7c7c7c6c6c6c6c7c6c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c7c8fffffffac7c7c7c7c7c7c7c7c7c7c6c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c6c8fffffffac7c7c7c7c7c7c6c7c6c7c7c6c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c6c7c7c7c7c7c7c8fffffff9c7c7c7c7c7c7c7c6c7c7c7c7c7c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c6c7c7c9fffffff9c7c6c7c7c6c7c7c7c7c7c7c6c7c7c7c6c7c7
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c6c6c8fffffffac6c7c7c7c7c6c7c7c6c7c7c6c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c6c9fffffffac6c7c6c7c6c6c6c7c7c7c7c7c6c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c7c7c7c7c7c7c7c7fffffffcc7c7c7c7c7c6c7c7c7c7c7
+c6c7c7c7c7c7c700000000000000000000fffffffc000000000000000000
+00000000000000000000000000000000000000fffffff500000000000000
+00000000000000000000000000c7c7c7c7c7c7c7c7fffffffcc7c7c7c7c7
+c7c7c7c7c7c7c7c7c7c7c7c7c700000000000000000000fffffffc000000
+00000000000000000000000000000000000000000000000000fffffff500
+00000000000000000000000000000000000000c7c6c7c6c6c6c7c7ffffff
+fcc7c6c6c6c6c6c6c6c6c6c6c6c6c6c7c7c7c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000c7c7c7c6c7
+c7c7c7fffffffcc6c7c7c6c6c6c6c6c6c6c6c6c6c7c6c7c7c70000000000
+0000000000fffffffc000000000000000000000000000000000000000000
+00000000000000fffffff500000000000000000000000000000000000000
+00c7c6c7c7c7c6c7c7fffffffcc6c7c7c7c7c7c7c7c7c7c7c7c7c7c6c7c7
+c700000000000000000000fffffffc000000000000000000000000000000
+00000000000000000000000000fffffff500000000000000000000000000
+00000000000000c7c7c6c7c7c7c7c7fffffffcc7c7c6c7c6c6c6c6c6c6c6
+c7c6c7c7c7c6c700000000000000000000fffffffc000000000000000000
+00000000000000000000000000000000000000fffffff500000000000000
+00000000000000000000000000c7c7c7c6c7c6c7c7fffffffcc6c7c7c7c6
+c6c6c6c6c7c7c6c7c7c6c7c6c700000000000000000000fffffffc000000
+00000000000000000000000000000000000000000000000000fffffff500
+00000000000000000000000000000000000000c7c7c7c7c7c7c6c7ffffff
+fcc7c6c7c6c6c7c7c6c7c7c7c7c7c7c7c6c7c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000fcfcfcfcfc
+fcfcfcfffffffffcfcfcfcfcfcfbfcfcfcfcfbfcfcfcfcfcfc0000fcfcfc
+fcfcfcfcfcfffffffffcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc0000f5
+f5f5f5f5f5f5f5fffffffff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f500
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0000c7c7c7c6c7c7c6c6ffffff
+fcc6c6c6c7c7c6c6c7c7c7c7c6c6c6c7c7c7c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000c7c7c6c6c7
+c6c7c7fffffffcc6c7c7c7c7c7c7c6c7c6c6c7c7c7c7c6c7c70000000000
+0000000000fffffffc000000000000000000000000000000000000000000
+00000000000000fffffff500000000000000000000000000000000000000
+00c7c6c6c7c7c6c7c7fffffffcc7c7c7c7c7c6c7c6c7c6c7c7c7c6c7c7c7
+c700000000000000000000fffffffc000000000000000000000000000000
+00000000000000000000000000fffffff500000000000000000000000000
+00000000000000c7c6c7c7c7c7c6c7fffffffcc7c6c6c6c7c7c7c7c7c7c7
+c7c7c6c7c7c7c700000000000000000000fffffffc000000000000000000
+00000000000000000000000000000000000000fffffff500000000000000
+00000000000000000000000000c7c7c7c6c7c7c7c7fffffffcc6c6c6c7c6
+c7c6c7c6c7c7c6c7c7c7c6c7c700000000000000000000fffffffc000000
+00000000000000000000000000000000000000000000000000fffffff500
+00000000000000000000000000000000000000c7c7c7c7c7c6c7c7ffffff
+fcc7c7c7c6c7c7c7c7c6c7c6c6c7c6c7c7c6c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000c7c7c7c7c6
+c6c6c6fffffffcc6c6c7c7c6c7c7c6c7c6c7c7c7c7c7c6c6c70000000000
+0000000000fffffffc000000000000000000000000000000000000000000
+00000000000000fffffff500000000000000000000000000000000000000
+00c7c7c6c7c7c7c7c7fffffffcc6c7c6c6c7c7c7c7c7c7c6c7c6c6c7c7c7
+c700000000000000000000fffffffc000000000000000000000000000000
+00000000000000000000000000fffffff500000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/denmark.gif b/Docs/Flags/denmark.gif
index 1d8e687adcc..b2cda874fce 100644
--- a/Docs/Flags/denmark.gif
+++ b/Docs/Flags/denmark.gif
Binary files differ
diff --git a/Docs/Flags/denmark.pdf b/Docs/Flags/denmark.pdf
new file mode 100644
index 00000000000..c405a7b0f11
--- /dev/null
+++ b/Docs/Flags/denmark.pdf
Binary files differ
diff --git a/Docs/Flags/estonia.eps b/Docs/Flags/estonia.eps
index e34768c3442..a73cd8eecce 100644
--- a/Docs/Flags/estonia.eps
+++ b/Docs/Flags/estonia.eps
@@ -1,48 +1,57 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: estonia.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
+000000000000000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000505050505050505050505050505050505
+050505050505050505050505050000000000000000000000000000000000
+00000000000000000000000000000000007a7a7a7a7a7a7a7a7a7a7a7a7a
+7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a00000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-050505050505050505050505050505050505050505050505050505050505
000000000000000000000000000000000000000000000000000000000000
-757575757575757575757575757575757575757575757575757575757575
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
@@ -57,31 +66,33 @@ b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000a4a4a4a4a4
+a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a40000a4a4a4
+a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a40000a4
+a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a400
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/estonia.gif b/Docs/Flags/estonia.gif
index b8bbf1dbb78..ac2c62b78e9 100644
--- a/Docs/Flags/estonia.gif
+++ b/Docs/Flags/estonia.gif
Binary files differ
diff --git a/Docs/Flags/estonia.pdf b/Docs/Flags/estonia.pdf
new file mode 100644
index 00000000000..12056acb79d
--- /dev/null
+++ b/Docs/Flags/estonia.pdf
Binary files differ
diff --git a/Docs/Flags/finland.eps b/Docs/Flags/finland.eps
index c88fa4e2eaa..847a0fdd30d 100644
--- a/Docs/Flags/finland.eps
+++ b/Docs/Flags/finland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: finland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f2f2f2f2f2f2f2eb18181825f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f5f5f5f5f5f5f5f3b5b5b5b9f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-191919191919191918181818191919191919191919191919191919191919
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-222222222222222218181819222222222222222222222222222222222222
-b8b8b8b8b8b8b8b8b5b5b5b5b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700001b1b1b1b1b
+1b1b1b181818181b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b0000b6b6b6
+b6b6b6b6b6b5b5b5b5b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b60000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef0000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/finland.gif b/Docs/Flags/finland.gif
index a43a398f8f1..08f367ce95c 100644
--- a/Docs/Flags/finland.gif
+++ b/Docs/Flags/finland.gif
Binary files differ
diff --git a/Docs/Flags/finland.pdf b/Docs/Flags/finland.pdf
new file mode 100644
index 00000000000..aa0506be383
--- /dev/null
+++ b/Docs/Flags/finland.pdf
Binary files differ
diff --git a/Docs/Flags/france.eps b/Docs/Flags/france.eps
index 6367b8b98ca..7d5b7fa0830 100644
--- a/Docs/Flags/france.eps
+++ b/Docs/Flags/france.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: france.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/france.gif b/Docs/Flags/france.gif
index 13fcbf29e66..f44b729895a 100644
--- a/Docs/Flags/france.gif
+++ b/Docs/Flags/france.gif
Binary files differ
diff --git a/Docs/Flags/france.pdf b/Docs/Flags/france.pdf
new file mode 100644
index 00000000000..036e96eadef
--- /dev/null
+++ b/Docs/Flags/france.pdf
Binary files differ
diff --git a/Docs/Flags/germany.eps b/Docs/Flags/germany.eps
index 568543e3680..e06e98b1883 100644
--- a/Docs/Flags/germany.eps
+++ b/Docs/Flags/germany.eps
@@ -1,22 +1,22 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: germany.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
@@ -40,48 +40,59 @@ colorimage
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-464646464646464646464646464646464646464646464646464646464646
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+000000000000000000000000004040404040404040404040404040404040
+404040404040404040404040400000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000ececececec
+ececececececececececececececececececececececececec00008e8e8e
+8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e000000
000000000000000000000000000000000000000000000000000000000000
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6000000
000000000000000000000000000000000000000000000000000000000000
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-999999999999999999999999999999999999999999999999999999999999
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/germany.gif b/Docs/Flags/germany.gif
index e25a855b3d2..aedbb037a32 100644
--- a/Docs/Flags/germany.gif
+++ b/Docs/Flags/germany.gif
Binary files differ
diff --git a/Docs/Flags/germany.pdf b/Docs/Flags/germany.pdf
new file mode 100644
index 00000000000..01df1c4cb3a
--- /dev/null
+++ b/Docs/Flags/germany.pdf
Binary files differ
diff --git a/Docs/Flags/great-britain.eps b/Docs/Flags/great-britain.eps
index 97a7ffc9b57..19464e1e3b7 100644
--- a/Docs/Flags/great-britain.eps
+++ b/Docs/Flags/great-britain.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: great-britain.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-cfd85508080808080808080811e4c6c6d70808080808080808080967decd
-2db24f000000000000000000099600009f0000000000000000000162ab20
-2ec2cab5b5b5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5b5b5cfb520
-ccc7dfa31b0808080808080811e4c6c6d7080808080808080825b4dbc6ce
-1c057a9c1300000000000000099600009f00000000000000001ea8670127
-1c057bdbbab5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5bdda670127
-edd9c6cfd85508080808080811e4c6c6d70808080808080967decdc7dde9
-e160012eb14f000000000000099600009f0000000000000162ab200373e3
-e760012ec2cab5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5cfb5210374ec
-2fc4e9ccc7dea31b0808080811e4c6c6d7080808080825b4dbc6ceedb423
-28c2b21c057a9c1300000000099600009f00000000001ea8670129c2b21c
-c0e9b21c057adabab5b5b5b5b8970000aeb5b5b5b5b5bdd9670129c2e4bc
-080b78edd9c6cfd85508080811e4c6c6d70808080967ddccc7dde8650908
-000373e160012db14f000000099600009f0000000162aa200373e1600100
-b5b6d4e760012dc1cab5b5b5b8970000aeb5b5b5b5cfb4200374eccfb5b5
-0808082fc4e9ccc7dea31b0811e4c6c6d7080825b4dac6ceedb423080808
-00000029c2b21d05799c1300099600009f00001ea8660129c2b21c000000
-b5b5b5c0e9b21d057adabab5b8970000aeb5b5bdd9660129c2e4bdb5b5b5
-080808080b78edd9c6cfd85511e4c6c6d70967ddccc7dde8650908080808
-000000000473e161012db14f099600009f0162aa200474e1600100000000
-b5b5b5b5b6d4e761012dc1cab8970000aeb5cfb4200475eccfb5b5b5b5b5
-0e0e0e0e0e0e35c9eaccc8dfaae4c6c6deb4dcc7cfedb9290e0e0e0e0e0e
-0606060606062ec7b31f0b7fa3960000a7aa6c072bc3b722060606060606
-b7b7b7b7b7b7c2eab31f0b7fde970000b0db6c072bc3e6beb7b7b7b7b7b7
-e4e4e4e4e4e4e4e4e5e5e5e5e5d9c6c6dde5e5e5e5e5e4e4e4e4e4e4e4e4
-9a9a9a9a9a9a9a9a9b9b9a9a9b5e0000709b9a9a9b9b9a9a9a9a9a9a9a9a
-9b9b9b9b9b9b9b9b9b9b9a9a9b5f0000719b9a9a9b9b9b9b9b9b9b9b9b9b
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000cfd95608080808080808080808e4c6c6e4080808080808
+0808080856d9cf00002db25000000000000000000000a00000a000000000
+00000000000050b22d00002ec2cab5b5b5b5b5b5b5b5b5b5a30000a3b5b5
+b5b5b5b5b5b5b5b5cac22e0000cbc7dea41b0808080808080808e4c6c6e4
+08080808080808081ba4dec7cb00001b057a9d130000000000000000a000
+00a00000000000000000139d7a051b00001b057bdbbab5b5b5b5b5b5b5b5
+a30000a3b5b5b5b5b5b5b5b5badb7b051b0000eed9c6cfd9560808080808
+0808e4c6c6e40808080808080856d9cfc6d9ee0000e25e002db250000000
+00000000a00000a00000000000000050b22d005ee20000e65f012ec2cab5
+b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5cac22e005fe6000031c6e9cbc7
+dea41b0808080808e4c6c6e408080808081ba4dec7cbe9c63100002ac5b0
+1b057a9d130000000000a00000a00000000000139d7a051bb0c52a0000c0
+e9b11b057adbbab5b5b5b5b5a30000a3b5b5b5b5b5badb7a051bb1eac000
+00080c7aeed9c6cfd95608080808e4c6c6e40808080856d9cfc6d9ee7a0c
+080000000476e25e002db15000000000a00000a00000000050b12d005ee2
+7604000000b5b6d4e65f012dc1cab5b5b5b5a30000a3b5b5b5b5cac12d00
+5fe6d5b6b5000008080831c6e9ccc7dea41b0808e4c6c6e408081ba4dec7
+cce9c63108080800000000002ac5b01c05799d130000a00000a00000139d
+79051cb0c52a0000000000b5b5b5c0e9b11c0579dbbab5b5a30000a3b5b5
+badb79051cb1eac0b5b5b50000080808080c7aeed9c6cfd95608e4c6c6e4
+0856d9cfc6d9ee7a0c080808080000000000000476e25f012db15000a000
+00a00050b12d005fe27604000000000000b5b5b5b5b6d4e760012dc1cab5
+a30000a3b5cac12d0160e7d5b6b5b5b5b5000008080808080831c6e9ccc7
+dea4e5c6c6e5a4dec7cce9c63108080808080800000000000000002ac5b1
+1c05799da10000a19d79051cb1c52a0000000000000000b5b5b5b5b5b5c0
+e9b21c0579dba30000a3db79051cb1eac0b5b5b5b5b5b50000e4e4e4e4e4
+e4e4e5e7e7e6e6e7dcc6c6dce7e6e6e7e7e5e4e4e4e4e4e4e40000a0a0a0
+a0a0a0a0a1a3a2a0a0a26c00006ca2a0a0a2a3a1a0a0a0a0a0a0a00000a3
+a3a3a3a3a3a3a3a4a3a1a1a36d00006da3a1a1a3a4a3a3a3a3a3a3a3a300
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-dbdbdbdbdbdbdbdfe9e8e6e6e8dbc6c6e0e8e6e6e8e9dddbdbdbdbdbdbdb
-9f9f9f9f9f9f9fa3aea79f9fab6a00007eaa9f9fa8aea19f9f9f9f9f9f9f
-abababababababacafa8a0a0ac6b00007faba0a0a9afacababababababab
-0808080808083ed2e6cac8e098e4c6c6dda3dec7cceac42f080808080808
-00000000000037d1a0120a8b93960000a59c79051db3c228000000000000
-b5b5b5b5b5b5c4eda0130a8ddb970000b0db7a051db3e9c0b5b5b5b5b5b5
-08080808108af0d6c6d2d04411e4c6c6d70855d8cfc6d9ed780b08080808
-000000000887dd4e003cb33d099600009f004fb12d0161e2730300000000
-b5b5b5b5b7d9df4e003cccc5b8970000aeb5cac12d0161e7d4b6b5b5b5b5
-0808083ed2e6cac8e091130811e4c6c6d708081aa3dec7cce9c42f080808
-00000037d09f120a8b8c0b00099600009f0000139c79051db2c228000000
-b5b5b5c4ec9f130b8dd9b8b5b8970000aeb5b5badb7a051db2e9c0b5b5b5
-08108bf0d5c6d2d04408080811e4c6c6d70808080855d8cfc6d9ed780b08
-000887dd4d003cb33e000000099600009f000000004fb12d0160e1730300
-b5b7d9df4d003cccc5b5b5b5b8970000aeb5b5b5b5cac12d0160e7d4b6b5
-3dd2e6cac8e191130808080811e4c6c6d708080808081ba3dec7cce9c42f
-37d09f120b8c8c0b00000000099600009f0000000000139c7a051cb2c229
-c4ec9f120b8dd9b8b5b5b5b5b8970000aeb5b5b5b5b5badb7a051cb2e9c0
-f0d6c6d2d04408080808080811e4c6c6d70808080808080855d8cfc6d9ee
-dd4d003db43d000000000000099600009f000000000000004fb12e0160e3
-df4d003dccc5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5cac22e0160e7
-cac8e191130808080808080811e4c6c6d708080808080808081ba3dec7cb
-120b8c8c0b00000000000000099600009f0000000000000000139c7a051a
-120b8ed9b8b5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5badb7b051a
-d2d24408080808080808080811e4c6c6d70808080808080808080855dacf
-3bb63e000000000000000000099600009f000000000000000000004fb32c
-3bcdc5b5b5b5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5b5b5cac32c
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000e4e4e4e4e4e4e4e5e7e7e6e6e7dcc6c6dc
+e7e6e6e7e7e5e4e4e4e4e4e4e40000a0a0a0a0a0a0a0a1a3a2a0a0a26c00
+006ca2a0a0a2a3a1a0a0a0a0a0a0a00000a3a3a3a3a3a3a3a3a4a3a1a1a3
+6d00006da3a1a1a3a4a3a3a3a3a3a3a3a3000008080808080831c6e9ccc7
+dea4e5c6c6e5a4dec7cce9c63108080808080800000000000000002ac4b1
+1c05799da10000a19d79051cb1c52a0000000000000000b5b5b5b5b5b5c0
+e9b21c0579dba30000a3db79051cb2eac0b5b5b5b5b5b50000080808080c
+7aeed9c6cfd95608e4c6c6e40856d9cfc6d9ee7a0c080808080000000000
+000476e260012db15000a00000a00050b12d0060e27604000000000000b5
+b5b5b5b6d4e760012dc1cbb5a30000a3b5cac12d0160e7d5b6b5b5b5b500
+0008080831c6e9ccc7dea41b0808e4c6c6e408081ba4dec7cce9c6310808
+0800000000002ac4b11c05799d140000a00000a00000139d79051cb1c52a
+0000000000b5b5b5c0e9b11c0579dbbab5b5a30000a3b5b5badb79051cb1
+eac0b5b5b50000080c7aeed9c6cfd95608080808e4c6c6e40808080856d9
+cfc6d9ee7a0c080000000476e25f002db15000000000a00000a000000000
+50b12d005ee17604000000b5b6d4e65f012dc1cbb5b5b5b5a30000a3b5b5
+b5b5cac12d005fe6d5b6b5000031c6e9cbc7dea41b0808080808e4c6c6e4
+08080808081ba4dec7cbe9c63100002ac4b01b057a9d140000000000a000
+00a00000000000139d7a051bb0c52a0000c0e9b11b057adbbab5b5b5b5b5
+a30000a3b5b5b5b5b5badb7a051bb1eac00000eed9c6cfd9560808080808
+0808e4c6c6e40808080808080856d9cfc6d9ee0000e25f002db250000000
+00000000a00000a00000000000000050b22d005ee10000e65f012dc2cbb5
+b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5cac22e005fe60000cbc7dea41b
+0808080808080808e4c6c6e408080808080808081ba4dec7cb00001b057a
+9d140000000000000000a00000a00000000000000000139d7a051b00001b
+057adbbab5b5b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5b5badb7b051b00
+00cfd95608080808080808080808e4c6c6e40808080808080808080856d9
+cf00002db25000000000000000000000a00000a000000000000000000000
+50b22d00002dc2cbb5b5b5b5b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5b5
+b5b5cac22e00000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/great-britain.gif b/Docs/Flags/great-britain.gif
index 0f555d078b3..ae92b536ad3 100644
--- a/Docs/Flags/great-britain.gif
+++ b/Docs/Flags/great-britain.gif
Binary files differ
diff --git a/Docs/Flags/great-britain.pdf b/Docs/Flags/great-britain.pdf
new file mode 100644
index 00000000000..f29dfd48861
--- /dev/null
+++ b/Docs/Flags/great-britain.pdf
Binary files differ
diff --git a/Docs/Flags/greece.eps b/Docs/Flags/greece.eps
index 3c022139c56..f59baa86106 100644
--- a/Docs/Flags/greece.eps
+++ b/Docs/Flags/greece.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: greece.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-1818181897f7a618181818bbc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
-b5b5b5b5daf7dfb5b5b5b5e5e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9
-efefefeff4f7f4efefefeff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5
-1818181897f7a618181818e7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5daf7dfb5b5b5b5f2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-efefefeff4f7f4efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-97979797cdf7d49797979777767676767676767676767676767676767676
-dadadadaeaf7ecdadadadad1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1
-f4f4f4f4f6f7f6f4f4f4f4f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f7f7f7f7f7f7f7f7f7f7f725181818181818181818181818181818181818
-f7f7f7f7f7f7f7f7f7f7f7b9b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-f7f7f7f7f7f7f7f7f7f7f7efefefefefefefefefefefefefefefefefefef
-a6a6a6a6d4f7daa6a6a6a66a676767676767676767676767676767676767
-dfdfdfdfedf7eedfdfdfdfcdcccccccccccccccccccccccccccccccccccc
-f4f4f4f4f6f7f6f4f4f4f4f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-1818181897f7a618181818e7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5daf7dfb5b5b5b5f2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-efefefeff4f7f4efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-1818181897f7a618181818c9d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-b5b5b5b5daf7dfb5b5b5b5e9edededededededededededededededededed
-efefefeff4f7f4efefefeff6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-e7e7e7e7f0f7f1e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7
-f2f2f2f2f5f7f5f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-555555555555555555555555555555555555555555555555555555555555
-c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
-f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-878787878787878787878787878787878787878787878787878787878787
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6
-e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4
-f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000001818181893f7ac18181818181818181818181818181818
+181818181818180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefeff3f7f4efefefefefefefefefefefef
+efefefefefefefefefefef00001818181893f7ac18181818181818181818
+181818181818181818181818180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefeff3f7f4efefefefefef
+efefefefefefefefefefefefefefefefef00001818181893f7ac18181818
+b1c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c50000b5b5b5b5d9f7e1b5b5
+b5b5e2e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e80000efefefeff3f7f4
+efefefeff4f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f500001818181893
+f7ac18181818def7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5
+b5d9f7e1b5b5b5b5f0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000ef
+efefeff3f7f4efefefeff6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+0093939393caf7d5939393937a7979797979797979797979797979797979
+790000d9d9d9d9e9f7edd9d9d9d9d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
+d2d2d20000f3f3f3f3f5f7f6f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
+f3f3f3f3f30000f7f7f7f7f7f7f7f7f7f7f72e1818181818181818181818
+181818181818180000f7f7f7f7f7f7f7f7f7f7f7bcb5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000f7f7f7f7f7f7f7f7f7f7f7f0efefefefefefef
+efefefefefefefefefefef0000acacacacd5f7deacacacac686161616161
+616161616161616161616161610000e1e1e1e1edf7f0e1e1e1e1cccacaca
+cacacacacacacacacacacacacacaca0000f4f4f4f4f6f7f6f4f4f4f4f2f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f200001818181893f7ac18181818
+def7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5d9f7e1b5b5
+b5b5f0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000efefefeff3f7f4
+efefefeff6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700001818181893
+f7ac18181818c8dededededededededededededededededede0000b5b5b5
+b5d9f7e1b5b5b5b5e9f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f00000ef
+efefeff3f7f4efefefeff5f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f600
+001818181893f7ac18181818181818181818181818181818181818181818
+180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefeff3f7f4efefefefefefefefefefefefefefefefefef
+efefefefef00001818181893f7ac18181818181818181818181818181818
+181818181818180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefeff3f7f4efefefefefefefefefefefef
+efefefefefefefefefefef0000dedededeecf7efdededededededededede
+dedededededededededededede0000f0f0f0f0f4f7f5f0f0f0f0f0f0f0f0
+f0f0f0f0f0f0f0f0f0f0f0f0f0f0f00000f6f6f6f6f7f7f7f6f6f6f6f6f6
+f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f60000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700006161616161
+616161616161616161616161616161616161616161616161610000cacaca
+cacacacacacacacacacacacacacacacacacacacacacacacacacaca0000f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f200
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00007979797979797979797979797979797979797979797979
+797979797979790000d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
+d2d2d2d2d2d2d2d2d20000f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
+f3f3f3f3f3f3f3f3f3f3f30000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000c5c5c5c5c5c5c5c5c5c5c5
+c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c50000e8e8e8e8e8e8e8e8e8
+e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e80000f5f5f5f5f5f5f5
+f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f500001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/greece.gif b/Docs/Flags/greece.gif
index 1ede215a373..264b295b374 100644
--- a/Docs/Flags/greece.gif
+++ b/Docs/Flags/greece.gif
Binary files differ
diff --git a/Docs/Flags/greece.pdf b/Docs/Flags/greece.pdf
new file mode 100644
index 00000000000..d54d8b3e153
--- /dev/null
+++ b/Docs/Flags/greece.pdf
Binary files differ
diff --git a/Docs/Flags/hungary.eps b/Docs/Flags/hungary.eps
index e405fc3cffe..38d9cae079f 100644
--- a/Docs/Flags/hungary.eps
+++ b/Docs/Flags/hungary.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: hungary.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d60000505050505050505050505050505050
+505050505050505050505050505050000050505050505050505050505050
+50505050505050505050505050505050500000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700005353535353
+535353535353535353535353535353535353535353535353530000cbcbcb
+cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb000053
+535353535353535353535353535353535353535353535353535353535300
000000000000000000000000000000000000000000000000000000000000
+000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-575757575757575757575757575757575757575757575757575757575757
-575757575757575757575757575757575757575757575757575757575757
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-464646464646464646464646464646464646464646464646464646464646
-c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-464646464646464646464646464646464646464646464646464646464646
+000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000000000000000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/hungary.gif b/Docs/Flags/hungary.gif
index eca0e109bbe..eb14887b5bb 100644
--- a/Docs/Flags/hungary.gif
+++ b/Docs/Flags/hungary.gif
Binary files differ
diff --git a/Docs/Flags/hungary.pdf b/Docs/Flags/hungary.pdf
new file mode 100644
index 00000000000..51ba552f2ba
--- /dev/null
+++ b/Docs/Flags/hungary.pdf
Binary files differ
diff --git a/Docs/Flags/iceland.eps b/Docs/Flags/iceland.eps
index c2a5529eb42..8a1bc21f4c8 100644
--- a/Docs/Flags/iceland.eps
+++ b/Docs/Flags/iceland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: iceland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0e0e0e0e0e0e0e15eec6c6e40e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-060606060606060ec60000cb060606060606060606060606060606060606
-b7b7b7b7b7b7b7b9c70000d6b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7
-ecececececececece6c6c6e9ecececececececececececececececececec
-c5c5c5c5c5c5c5c59f0000aec5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c6c6c6c6c6c6c6c6a00000afc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808efc6c6ec0808080808080808080808
+0808080808080800000000000000000000cf0000cb000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6ec0808080808
+0808080808080808080808080800000000000000000000cf0000cb000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808efc6c6ec0808080808080808080808080808080808080000000000
+0000000000cf0000cb0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808efc6c6ec0808080808080808080808080808080808
+0800000000000000000000cf0000cb000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808efc6c6ec0808080808080808080808
+0808080808080800000000000000000000cf0000cb000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6ec0808080808
+0808080808080808080808080800000000000000000000cf0000cb000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ececececec
+ececece9c6c6e8ecececececececececececececececececec0000cbcbcb
+cbcbcbcbcbad0000adcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb0000ce
+cececececececeae0000adcececececececececececececececececece00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-e6e6e6e6e6e6e6e6e9c6c6ebe6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6
-cecececececececeae0000becececececececececececececececececece
-d7d7d7d7d7d7d7d7af0000c0d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000efefefefefefefefe9c6c6e8efefefefef
+efefefefefefefefefefefefef0000cfcfcfcfcfcfcfcfad0000adcfcfcf
+cfcfcfcfcfcfcfcfcfcfcfcfcfcfcf0000cfcfcfcfcfcfcfcfae0000adcf
+cfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcf00000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808efc6c6ec0808080808080808080808080808080808080000000000
+0000000000cf0000cb0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808efc6c6ec0808080808080808080808080808080808
+0800000000000000000000cf0000cb000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808efc6c6ec0808080808080808080808
+0808080808080800000000000000000000cf0000cb000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6ec0808080808
+0808080808080808080808080800000000000000000000cf0000cb000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808efc6c6ec0808080808080808080808080808080808080000000000
+0000000000cf0000cb0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808efc6c6ec0808080808080808080808080808080808
+0800000000000000000000cf0000cb000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/iceland.gif b/Docs/Flags/iceland.gif
index ee4d17f5d04..4fe0c0b8124 100644
--- a/Docs/Flags/iceland.gif
+++ b/Docs/Flags/iceland.gif
Binary files differ
diff --git a/Docs/Flags/iceland.pdf b/Docs/Flags/iceland.pdf
new file mode 100644
index 00000000000..3509de59ba8
--- /dev/null
+++ b/Docs/Flags/iceland.pdf
Binary files differ
diff --git a/Docs/Flags/indonesia.eps b/Docs/Flags/indonesia.eps
index e69de29bb2d..9dcef0824df 100644
--- a/Docs/Flags/indonesia.eps
+++ b/Docs/Flags/indonesia.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: indonesia.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f40000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f4f4f40000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/indonesia.gif b/Docs/Flags/indonesia.gif
index 1c421df50ba..e05af4c8ff4 100644
--- a/Docs/Flags/indonesia.gif
+++ b/Docs/Flags/indonesia.gif
Binary files differ
diff --git a/Docs/Flags/indonesia.pdf b/Docs/Flags/indonesia.pdf
new file mode 100644
index 00000000000..48bd801fa15
--- /dev/null
+++ b/Docs/Flags/indonesia.pdf
Binary files differ
diff --git a/Docs/Flags/ireland.eps b/Docs/Flags/ireland.eps
index 610b2086fd7..01251367922 100644
--- a/Docs/Flags/ireland.eps
+++ b/Docs/Flags/ireland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: ireland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/ireland.gif b/Docs/Flags/ireland.gif
index a550678761f..631be2f33b9 100644
--- a/Docs/Flags/ireland.gif
+++ b/Docs/Flags/ireland.gif
Binary files differ
diff --git a/Docs/Flags/ireland.pdf b/Docs/Flags/ireland.pdf
new file mode 100644
index 00000000000..5f84f52f049
--- /dev/null
+++ b/Docs/Flags/ireland.pdf
Binary files differ
diff --git a/Docs/Flags/italy.eps b/Docs/Flags/italy.eps
index 20c7c7d5da3..7de3ddd9c1f 100644
--- a/Docs/Flags/italy.eps
+++ b/Docs/Flags/italy.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: italy.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/italy.gif b/Docs/Flags/italy.gif
index 511dba800c7..d59cf5ef55e 100644
--- a/Docs/Flags/italy.gif
+++ b/Docs/Flags/italy.gif
Binary files differ
diff --git a/Docs/Flags/italy.pdf b/Docs/Flags/italy.pdf
new file mode 100644
index 00000000000..02c7d316a05
--- /dev/null
+++ b/Docs/Flags/italy.pdf
Binary files differ
diff --git a/Docs/Flags/japan.eps b/Docs/Flags/japan.eps
index 8dee6e497ba..c8ea7aa8afe 100644
--- a/Docs/Flags/japan.eps
+++ b/Docs/Flags/japan.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: japan.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7edddd6d7dfeff7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c17652557cccf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c27653557cccf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f2d4c6c6c6c6c6c6d8f4f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7de4500000000000157e9f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7de4600000000000158e9f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f2ccc6c6c6c6c6c6c6c6d0f5f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7de1f000000000000000030eaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7de1f000000000000000030eaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7d4c6c6c6c6c6c6c6c6c6c6d9f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7430000000000000000000060f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7440000000000000000000060f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7ecc6c6c6c6c6c6c6c6c6c6c6c7f1f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7be000000000000000000000003d8f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7be000000000000000000000003d9f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7ddc6c6c6c6c6c6c6c6c6c6c6c6e2f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7720000000000000000000000008ff7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7720000000000000000000000008ff7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6c6c6dbf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74e0000000000000000000000006bf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74e0000000000000000000000006bf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6c6c6dcf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74f0000000000000000000000006cf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74f0000000000000000000000006df7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c6c6c6c6c6c6e3f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f77600000000000000000000000093f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f77600000000000000000000000093f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7edc6c6c6c6c6c6c6c6c6c6c6c7f2f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7c6000000000000000000000005def7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7c6000000000000000000000005def7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6dcf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f74f000000000000000000006cf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f74f000000000000000000006df7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f4cec6c6c6c6c6c6c6c6d2f5f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7e52a00000000000000003deff7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7e52a00000000000000003deff7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f4d8c6c6c6c6c6c7dbf5f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7e7580200000000056aeff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7e7590200000000056beff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f0e1dadbe3f2f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7d389666890dcf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7d389666890dcf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7eedfd7d7dfeef7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7ca7c57577ccaf7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7ca7c57577ccaf7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f3d6c6c6c6c6c6c6d6f3f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050e4f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050e4f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f3cec6c6c6c6c6c6c6c6cef3f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7e427000000000000000027e4
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7e4270000000000000000
+27e4f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6
+c6c6c6d6f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7500000000000
+000000000050f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f750000000
+0000000000000050f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7eec6c6
+c6c6c6c6c6c6c6c6c6c6eef7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7ca
+000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7ca000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7dfc6c6c6c6c6c6c6c6c6c6c6c6dff7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f77c0000000000000000000000007cf7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f77c0000000000000000000000007cf7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7d7c6c6c6c6c6c6c6c6c6c6c6c6d7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f75700000000000000000000000057f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f75700000000000000000000000057f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7d7c6c6c6c6c6c6c6c6c6c6c6c6d7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f757000000000000000000000000
+57f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f75700000000000000000000
+000057f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7dfc6c6c6c6c6c6c6c6
+c6c6c6c6dff7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f77c000000000000
+0000000000007cf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f77c00000000
+00000000000000007cf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7eec6c6
+c6c6c6c6c6c6c6c6c6c6eef7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7c9
+000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7ca000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6d6f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7500000000000000000000050f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7500000000000000000000050f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f3cec6c6c6c6c6c6c6c6cef3f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7e427000000000000000027e4f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7e427000000000000000027e4f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f3d6c6c6c6c6c6c6d6f3f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050e4f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050
+e4f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7eedfd7d7df
+eef7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7c97c56
+567cc9f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7ca
+7c57577ccaf7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/japan.gif b/Docs/Flags/japan.gif
index 37ebca66f04..7d6a9adbd78 100644
--- a/Docs/Flags/japan.gif
+++ b/Docs/Flags/japan.gif
Binary files differ
diff --git a/Docs/Flags/japan.pdf b/Docs/Flags/japan.pdf
new file mode 100644
index 00000000000..c98ff331611
--- /dev/null
+++ b/Docs/Flags/japan.pdf
Binary files differ
diff --git a/Docs/Flags/latvia.eps b/Docs/Flags/latvia.eps
index 9c1f81f3ddc..606f7e70b3c 100644
--- a/Docs/Flags/latvia.eps
+++ b/Docs/Flags/latvia.eps
@@ -2,7 +2,7 @@
%%Creator: pnmtops
%%Title: latvia.ps
%%Pages: 1
-%%BoundingBox: 295 365 317 396
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
@@ -13,9 +13,8 @@
%%EndProlog
%%Page: 1 1
gsave
-295.44 365.64 translate
-21.12 30.72 scale
-0.5 0.5 translate 90 rotate -0.5 -0.5 translate
+290.64 385.44 translate
+30.72 21.12 scale
32 22 8
[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
@@ -26,71 +25,71 @@ colorimage
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-000000000000009494949494949494949494949494949494949494949494
-949494949494940000101010101010101010101010101010101010101010
-101010101010101010000018181818181818181818181818181818181818
-181818181818181818181800009494949494949494949494949494949494
-949494949494949494949494940000101010101010101010101010101010
-101010101010101010101010101010000018181818181818181818181818
-181818181818181818181818181818181800009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-181818181818181818181818181818181818181818181800009494949494
-949494949494949494949494949494949494949494949494940000101010
-101010101010101010101010101010101010101010101010101010000018
-181818181818181818181818181818181818181818181818181818181800
-009494949494949494949494949494949494949494949494949494949494
-940000101010101010101010101010101010101010101010101010101010
-101010000018181818181818181818181818181818181818181818181818
-181818181800009494949494949494949494949494949494949494949494
-949494949494940000101010101010101010101010101010101010101010
-101010101010101010000018181818181818181818181818181818181818
-181818181818181818181800009494949494949494949494949494949494
-949494949494949494949494940000101010101010101010101010101010
-101010101010101010101010101010000018181818181818181818181818
-181818181818181818181818181818181800009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-18181818181818181818181818181818181818181818180000ffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
-00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffff00009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-181818181818181818181818181818181818181818181800009494949494
-949494949494949494949494949494949494949494949494940000101010
-101010101010101010101010101010101010101010101010101010000018
-181818181818181818181818181818181818181818181818181818181800
-009494949494949494949494949494949494949494949494949494949494
-940000101010101010101010101010101010101010101010101010101010
-101010000018181818181818181818181818181818181818181818181818
-181818181800009494949494949494949494949494949494949494949494
-949494949494940000101010101010101010101010101010101010101010
-101010101010101010000018181818181818181818181818181818181818
-181818181818181818181800009494949494949494949494949494949494
-949494949494949494949494940000101010101010101010101010101010
-101010101010101010101010101010000018181818181818181818181818
-181818181818181818181818181818181800009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-181818181818181818181818181818181818181818181800009494949494
-949494949494949494949494949494949494949494949494940000101010
-101010101010101010101010101010101010101010101010101010000018
-181818181818181818181818181818181818181818181818181818181800
-009494949494949494949494949494949494949494949494949494949494
-940000101010101010101010101010101010101010101010101010101010
-101010000018181818181818181818181818181818181818181818181818
-181818181800000000000000000000000000000000000000000000000000
+00000000000000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a50000000000000000000000000000000000000000000000
+000000000000000000000010101010101010101010101010101010101010
+10101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000000000000000
+000000000000000000000000000000000010101010101010101010101010
+10101010101010101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000
+000000000000000000000000000000000000000000000000000000000010
+101010101010101010101010101010101010101010101010101010101000
+00a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a50000000000000000000000000000000000000000000000000000000000
+000000000010101010101010101010101010101010101010101010101010
+10101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a50000000000000000000000000000000000000000000000
+000000000000000000000010101010101010101010101010101010101010
+10101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000000000000000
+000000000000000000000000000000000010101010101010101010101010
+10101010101010101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000dbdbdbdbdb
+dbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdb0000a3a3a3
+a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a30000ab
+ababababababababababababababababababababababababababababab00
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc
+dcdcdcdcdcdcdcdcdcdcdcdcdc0000a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
+a3a3a3a3a3a3a3a3a3a3a3a3a3a3a30000ababababababababababababab
+ababababababababababababababababab0000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000
+000000000000000000000000000000000000000000000000000000000010
+101010101010101010101010101010101010101010101010101010101000
+00a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a50000000000000000000000000000000000000000000000000000000000
+000000000010101010101010101010101010101010101010101010101010
+10101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a50000000000000000000000000000000000000000000000
+000000000000000000000010101010101010101010101010101010101010
+10101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000000000000000
+000000000000000000000000000000000010101010101010101010101010
+10101010101010101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000
+000000000000000000000000000000000000000000000000000000000010
+101010101010101010101010101010101010101010101010101010101000
+00a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a50000000000000000000000000000000000000000000000000000000000
+000000000010101010101010101010101010101010101010101010101010
+101010101000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000
diff --git a/Docs/Flags/latvia.gif b/Docs/Flags/latvia.gif
index 8a898328ebe..b8ba782b703 100644
--- a/Docs/Flags/latvia.gif
+++ b/Docs/Flags/latvia.gif
Binary files differ
diff --git a/Docs/Flags/latvia.pdf b/Docs/Flags/latvia.pdf
new file mode 100644
index 00000000000..1d06690e980
--- /dev/null
+++ b/Docs/Flags/latvia.pdf
Binary files differ
diff --git a/Docs/Flags/mexico.eps b/Docs/Flags/mexico.eps
new file mode 100644
index 00000000000..c6f4f0a79de
--- /dev/null
+++ b/Docs/Flags/mexico.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: mexico.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000005ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00
+000000000000000000000000000000000000000005ffffffffffffffffff
+fe00000000000000000000000000000000000000000005ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7ffffffffff
+fffffffffe00000000000000000000000000000000000000000005ffffff
+fffffffffffffe00000000000000000000000000000000000000000005ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7fffffffffffffffffffe00000000000000000000000000000000000000
+000005fffffffffffffffffffe0000000000000000000000000000000000
+0000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000000000000000
+000000000000000005fffffffffffffffffffe0000000000000000000000
+0000000000000000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000
+000000000000000000000000000005fffffffffffffffffffe0000000000
+0000000000000000000000000000000005ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00
+000000000000000000000000000000000000000005ffffffffffffffffff
+fe00000000000000000000000000000000000000000005fffffffee0bbe1
+ffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffed2
+95d3fffffe00000000000000000000000000000000000000000005ffffff
+fec876c7fffffe00000000000000000000000000000000000000000005ff
+ffc4ae7f8683cdffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7ffffd790453e3daefffe00000000000000000000000000000000000000
+000005ffffbc6114010295fffe0000000000000000000000000000000000
+0000000005fffcd699827c838df6ffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7fffbdca23f383c47f3fe00000000000000000000000000
+000000000000000005ffface770600000cf0fe0000000000000000000000
+0000000000000000000005f3e89eaa827eb98de6f5c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7f6eab996493b9a53def800000000000000
+000000000000000000000000000005f1e28f8319038123d2f30000000000
+0000000000000000000000000000000005cfcf77bab38a93bdbdd5c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7dbcf97a18c5159a1cae200
+000000000000000000000000000000000000000005c3bc67796521298bab
+cd00000000000000000000000000000000000000000005fa8cbd7c4c6076
+c079fdc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fbadcba194
+839bb6abfc00000000000000000000000000000000000000000005f978b8
+78542f63a668fb00000000000000000000000000000000000000000005ff
+e2829a795dbd8ee1ffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7ffe5a9bf5657c8b9e7fe00000000000000000000000000000000000000
+000005ffd86ecd2d20c780d9fe0000000000000000000000000000000000
+0000000005ffffe68b989f86f5ffffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7ffffe8b4aba8b5f4fffe00000000000000000000000000
+000000000000000005ffffdd7d8a8c78f0fffe0000000000000000000000
+0000000000000000000005fffffffffefeffffffffc6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7fffffffffefefffffffe00000000000000
+000000000000000000000000000005fffffffffefefffffffe0000000000
+0000000000000000000000000000000005ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00
+000000000000000000000000000000000000000005ffffffffffffffffff
+fe00000000000000000000000000000000000000000005ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7ffffffffff
+fffffffffe00000000000000000000000000000000000000000005ffffff
+fffffffffffffe00000000000000000000000000000000000000000005ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7fffffffffffffffffffe00000000000000000000000000000000000000
+000005fffffffffffffffffffe0000000000000000000000000000000000
+0000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000000000000000
+000000000000000005fffffffffffffffffffe0000000000000000000000
+0000000000000000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000
+000000000000000000000000000005fffffffffffffffffffe0000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/mexico.gif b/Docs/Flags/mexico.gif
new file mode 100644
index 00000000000..206d1236ef1
--- /dev/null
+++ b/Docs/Flags/mexico.gif
Binary files differ
diff --git a/Docs/Flags/mexico.pdf b/Docs/Flags/mexico.pdf
new file mode 100644
index 00000000000..c983198d2b5
--- /dev/null
+++ b/Docs/Flags/mexico.pdf
Binary files differ
diff --git a/Docs/Flags/kroatia.eps b/Docs/Flags/mexico.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/kroatia.eps
+++ b/Docs/Flags/mexico.txt
diff --git a/Docs/Flags/netherlands.eps b/Docs/Flags/netherlands.eps
index 6f4d9906a11..94795e98baa 100644
--- a/Docs/Flags/netherlands.eps
+++ b/Docs/Flags/netherlands.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: netherlands.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-575757575757575757575757575757575757575757575757575757575757
-575757575757575757575757575757575757575757575757575757575757
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c
-464646464646464646464646464646464646464646464646464646464646
-c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d60000505050505050505050505050505050
+505050505050505050505050505050000050505050505050505050505050
+50505050505050505050505050505050500000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700005959595959
+595959595959595959595959595959595959595959595959590000535353
+5353535353535353535353535353535353535353535353535353530000cb
+cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb00
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/netherlands.gif b/Docs/Flags/netherlands.gif
index c09d3eb495c..2f236b58949 100644
--- a/Docs/Flags/netherlands.gif
+++ b/Docs/Flags/netherlands.gif
Binary files differ
diff --git a/Docs/Flags/netherlands.pdf b/Docs/Flags/netherlands.pdf
new file mode 100644
index 00000000000..098629aee10
--- /dev/null
+++ b/Docs/Flags/netherlands.pdf
Binary files differ
diff --git a/Docs/Flags/new-zealand.eps b/Docs/Flags/new-zealand.eps
new file mode 100644
index 00000000000..9177154f8f7
--- /dev/null
+++ b/Docs/Flags/new-zealand.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: new-zealand.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000ce770d08080874c6770808080c77ce0808080808080808
+0808080808080800003e58050000004d005000000005583e000000000000
+000000000000000000000042b4b6b5b5b5aa00abb5b5b5b6b442b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000aed2b433080874c677080833b4d2ae0808
+0808080808080808080808080800008a3d5e2b00004d005000002b5e3d8a
+0000000000000000000000000000000000bb3d81bfb5b5aa00abb5b5bf81
+3dbbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000967d3ce770d74c6770c77
+ced36709080808080808083e230808080808080000015f733e58054d0050
+05583e735f0100000000000000341c0000000000000000b5cb7d42b4b6aa
+00abb6b4427dcbb5b5b5b5b5b5b5b5bfbcb5b5b5b5b5b50000080825aed2
+b49bc69db3d2ae25080808080808080a65a49a5a0808080808000000001e
+893d5e7400765d3d8a1e000000000000000253444c4d00000000000000b5
+b5bdbb3d81b300b4813dbbbdb5b5b5b5b5b5b5b6bf7285c3b5b5b5b5b500
+00d3d3d3d3d6d5d3c6d3d5d6d3d3d3d30808080808081ccfc01308080808
+0800004d4d4d4d4f4d4200424d4f4d4d4d4d00000000000015484a0b0000
+00000000004f4f4f4f4f4d4200424d4f4f4f4f4fb5b5b5b5b5b5ba4e5fb8
+b5b5b5b5b50000d6d6d6d6d6d6d3c6d3d6d6d6d6d6d60808080808082c59
+6b1808080808080000505050505050420042505050505050000000000000
+25475a1000000000000000505050505050420042505050505050b5b5b5b5
+b5b5bfbdc2b9b5b5b5b5b50000080825aed2b49bc69db4d2ae2508080808
+08080908080808080832080808000000001e8a3d5e7400775e3d8a1e0000
+00000000010000000000002c0000000000b5b5bdbb3d81b300b4813dbbbd
+b5b5b5b5b5b5b5b5b5b5b5b5b5c1b5b5b500000967d3ce770d74c6770c77
+ced36709080808086408080808183eb14528080000015f733e58054d0050
+05583e735f010000000058000000001138714021000000b5cb7d42b4b6aa
+00abb6b4427dcbb5b5b5b5b5c6b5b5b5b5b9c49bc6beb50000aed2b43308
+0874c677080833b4d2ae08083188c8821e08080a7ec8a6190800008a3d5e
+2b00004d005000002b5e3d8a00002b534b591700000252074912000000bb
+3d81bfb5b5aa00abb5b5bf813dbbb5b5c09f58abbbb5b5b6a70776bab500
+00ce770d08080874c6770808080c77ce08080882cd5f0808080861798a08
+0800003e58050000004d005000000005583e0000004b2649000000005249
+660000000042b4b6b5b5b5aa00abb5b5b5b6b442b5b5b59a26b9b5b5b5b5
+c2a1b3b5b50000080808080808080808080808080808080808622d540808
+080810081008080000000000000000000000000000000000000000552548
+0000000008000800000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5c4
+bec2b5b5b5b5b7b5b7b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+00080808080808080808080808080808080808080808081c080808080808
+080000000000000000000000000000000000000000000000001400000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5bab5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080886
+200808080808080000000000000000000000000000000000000000000000
+005f190000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5adbcb5b5b5b5b5b500000808080808080808080808080808080808
+0808081196cdc94808080808080000000000000000000000000000000000
+00000000000a7728674100000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b8bc2978c5b5b5b5b5b500000808080808080808080808
+080808080808080808083dada00808080808080000000000000000000000
+0000000000000000000000003555670000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5c17e9fb5b5b5b5b5b500000808080808
+08080808080808080808080808080808240a250908080808080000000000
+0000000000000000000000000000000000001d021e0100000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5bdb5bdb5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/new-zealand.gif b/Docs/Flags/new-zealand.gif
new file mode 100644
index 00000000000..5d74f71ecc0
--- /dev/null
+++ b/Docs/Flags/new-zealand.gif
Binary files differ
diff --git a/Docs/Flags/new-zealand.pdf b/Docs/Flags/new-zealand.pdf
new file mode 100644
index 00000000000..040f8bdb7b0
--- /dev/null
+++ b/Docs/Flags/new-zealand.pdf
Binary files differ
diff --git a/Docs/Flags/kroatia.gif b/Docs/Flags/new-zealand.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/kroatia.gif
+++ b/Docs/Flags/new-zealand.txt
diff --git a/Docs/Flags/norway.eps b/Docs/Flags/norway.eps
new file mode 100755
index 00000000000..af62cbef81f
--- /dev/null
+++ b/Docs/Flags/norway.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: norway.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000cf0000cb000000000000000000
+00000000000000000000000000000000000000ecb5b5e900000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf0000cb000000
+00000000000000000000000000000000000000000000000000ecb5b5e900
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000cf0000cb000000000000000000000000000000000000000000
+00000000000000ecb5b5e900000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000cf0000cb000000000000000000000000000000
+00000000000000000000000000ecb5b5e900000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000cf0000cb000000000000000000
+00000000000000000000000000000000000000ecb5b5e900000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf0000cb000000
+00000000000000000000000000000000000000000000000000ecb5b5e900
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000d0d0d0d0d0
+d0d0d0b00808b0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000cbcbcb
+cbcbcbcbcbad0000adcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb0000e9
+e9e9e9e9e9e9e9e3b5b5e3e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e900
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000d0d0d0d0d0d0d0d0b00808b0d0d0d0d0d0
+d0d0d0d0d0d0d0d0d0d0d0d0d00000cfcfcfcfcfcfcfcfad0000adcfcfcf
+cfcfcfcfcfcfcfcfcfcfcfcfcfcfcf0000ecececececececece3b5b5e3ec
+ececececececececececececececececec0000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000cf0000cb000000000000000000000000000000000000000000
+00000000000000ecb5b5e900000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000cf0000cb000000000000000000000000000000
+00000000000000000000000000ecb5b5e900000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000cf0000cb000000000000000000
+00000000000000000000000000000000000000ecb5b5e900000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf0000cb000000
+00000000000000000000000000000000000000000000000000ecb5b5e900
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000cf0000cb000000000000000000000000000000000000000000
+00000000000000ecb5b5e900000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000cf0000cb000000000000000000000000000000
+00000000000000000000000000ecb5b5e900000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/norway.gif b/Docs/Flags/norway.gif
new file mode 100755
index 00000000000..e88d1029f3e
--- /dev/null
+++ b/Docs/Flags/norway.gif
Binary files differ
diff --git a/Docs/Flags/norway.pdf b/Docs/Flags/norway.pdf
new file mode 100644
index 00000000000..aaddf8c5ec4
--- /dev/null
+++ b/Docs/Flags/norway.pdf
Binary files differ
diff --git a/Docs/Flags/kroatia.txt b/Docs/Flags/norway.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/kroatia.txt
+++ b/Docs/Flags/norway.txt
diff --git a/Docs/Flags/philippines.eps b/Docs/Flags/philippines.eps
new file mode 100644
index 00000000000..9c3b242568a
--- /dev/null
+++ b/Docs/Flags/philippines.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: philippines.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000a91d080808080808080808080808080808080808080808
+080808080808080000a71600000000000000000000000000000000000000
+0000000000000000000000e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000f7e45a0808080808080808080808080808
+080808080808080808080808080000f6e354000000000000000000000000
+0000000000000000000000000000000000f3efcbb5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f7fdf9a91d080808080808
+080808080808080808080808080808080808080000f6f8f5a71600000000
+0000000000000000000000000000000000000000000000eb3bbae2bbb5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f9fdf9f7e4
+5a0808080808080808080808080808080808080808080808080000f5f8f5
+f7e3540000000000000000000000000000000000000000000000000000c8
+4fb2f7f2ccb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+00f7f8f7f7f7f7a91d080808080808080808080808080808080808080808
+080000f7f6f7f7f7f7a71600000000000000000000000000000000000000
+0000000000f7eaf7f7f7f7e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000f7f7f7f7f7f8f7e45a0808080808080808080808080808
+080808080808080000f7f7f7f7f6f5f7e354000000000000000000000000
+0000000000000000000000f7f7f7f7e8d8f7f2ccb5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000f7f7f8f7f9fbf7f8f7a91d080808080808
+080808080808080808080808080000f7f7f5f7f5f0f7f5f6a71600000000
+0000000000000000000000000000000000f7f7dcf7c785f7e1f2e2bbb5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f7f7fcfafafdf8fcf9f7e4
+5a0808080808080808080808080808080808080000f7f6eef2f5f2f6eef3
+f7e3540000000000000000000000000000000000000000f7f26eaba44bd6
+66b9f7f2ccb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f7f7f7feff
+fffffaf7f7f7f7a91d080808080808080808080808080808080000f7f7f6
+f4fffffcf2f7f7f7f7a616000000000000000000000000000000000000f7
+f7ea2800000290f7f7f7f7dfbbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+00f7fafafffffffffdfaf8f7fafbe45a0808080808080808080808080808
+080000f7f2f1fefffffff7f2f4f7f5f6e354000000000000000000000000
+0000000000f5a49c0100000048a4caf79d71f2ccb5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000f7fafafffffffffdfaf8f7fbfdf4d7c4c4c4c4c4c4c4c4
+c4c4c4c4c4c4c40000f7f2f1fefffffff7f2f4f7f5f9e255000000000000
+0000000000000000000000f4a49c0200000049a4caf68a43c75602020202
+02020202020202020202020000f7f7f7fefffffffaf7f7f7f7e8cbc6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000f7f7f6f4fffffcf2f7f7f7f7a61600
+0000000000000000000000000000000000f7f7ea2800000290f7f7f7f793
+16000000000000000000000000000000000000f7f7fcfafafdf8fcf9f7f3
+d7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f7f6eef2f5f2f6eef3
+f7e4550000000000000000000000000000000000000000f7f26eaba44bd6
+66b9f7e4560000000000000000000000000000000000000000f7f7f8f7f9
+fbf7f8f7e8cbc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f7f7f5
+f7f5f0f7f5f6a816000000000000000000000000000000000000000000f7
+f7dcf7c785f7e1f2a8160000000000000000000000000000000000000000
+00f7f7f7f7f7f8f7f3d7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000f7f7f7f7f6f5f7e455000000000000000000000000000000000000
+0000000000f7f7f7f7e8d8f7e45600000000000000000000000000000000
+00000000000000f7f7f7f7f7f7e8cbc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000f7f6f7f7f7f7a81600000000000000000000000000
+0000000000000000000000f7edf7f7f7f7a8160000000000000000000000
+00000000000000000000000000f8fcf9f7f3d7c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000f6f8f5f7e455000000000000000000
+0000000000000000000000000000000000d553adf7e45600000000000000
+00000000000000000000000000000000000000f8fdfae8cbc6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f6f8f5a81600000000
+0000000000000000000000000000000000000000000000e642ada8160000
+00000000000000000000000000000000000000000000000000f7f4d7c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f7e355
+0000000000000000000000000000000000000000000000000000000000f7
+d95600000000000000000000000000000000000000000000000000000000
+00e8cbc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000a81600000000000000000000000000000000000000000000000000
+0000000000a8160000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/philippines.gif b/Docs/Flags/philippines.gif
new file mode 100644
index 00000000000..884f2a5e8d2
--- /dev/null
+++ b/Docs/Flags/philippines.gif
Binary files differ
diff --git a/Docs/Flags/philippines.pdf b/Docs/Flags/philippines.pdf
new file mode 100644
index 00000000000..0b6639c24db
--- /dev/null
+++ b/Docs/Flags/philippines.pdf
Binary files differ
diff --git a/Docs/Flags/south-africa1.txt b/Docs/Flags/philippines.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/south-africa1.txt
+++ b/Docs/Flags/philippines.txt
diff --git a/Docs/Flags/poland.eps b/Docs/Flags/poland.eps
index 40d4363a515..06c580e1625 100644
--- a/Docs/Flags/poland.eps
+++ b/Docs/Flags/poland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: poland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000030303030303030303030303030303030303030303
+030303030303030303000003030303030303030303030303030303030303
+03030303030303030303030000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/poland.gif b/Docs/Flags/poland.gif
index 756f9398ee3..902b49f745d 100644
--- a/Docs/Flags/poland.gif
+++ b/Docs/Flags/poland.gif
Binary files differ
diff --git a/Docs/Flags/poland.pdf b/Docs/Flags/poland.pdf
new file mode 100644
index 00000000000..e2c696dda21
--- /dev/null
+++ b/Docs/Flags/poland.pdf
Binary files differ
diff --git a/Docs/Flags/portugal.eps b/Docs/Flags/portugal.eps
index 7bd24809850..01a83ecd6d1 100644
--- a/Docs/Flags/portugal.eps
+++ b/Docs/Flags/portugal.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: portugal.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000000033b6cd2cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b4bcc16033010000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000035c390a0dbe0e5cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5badfd4d58e93ba2900000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-000000000035e6bf77a5cdbed1eac9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5bae6bb5194581086da26000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000003c33fe2c4b7b8c8e0e3e0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b4dfb8973e68614691b7b2000000000000000000000000000000
-0000000000000000342f302f000000000000000000000000000000000000
-000000003b904ebae65668e2bde5dec7c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5bcd4bf04e05064cd12b7b1240000000000000000000000000000
-0000000000000000e0cbd0cd000000000000000000000000000000000000
-0000000065dd91d658222963d7dad7d2c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5c4e4d26e501b2252737b7d530000000000000000000000000000
-0000000000000000b8bcbea8000000000000000000000000000000000000
-0000000064d0c8e363272e6ededaefcec6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5c4dbdb9a5b2027618c9aea4d0000000000000000000000000000
-0000000000000000babdc0aa000000000000000000000000000000000000
-00000000369700a6d95668d5bedce4c5c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5bad6b511a75064941e85bc1e0000000000000000000000000000
-00000000000000009bcbd088000000000000000000000000000000000000
-0000000001ba8fc8f7939df6d0cde3c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b4d7d097ce3f4fca874fae000000000000000000000000000000
-000000000000000006484503000000000000000000000000000000000000
-00000000002bdfc497a3bcd8e4e8c8c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b9e1dca73124a9d0d31e000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000029b9a3abdee3e3c8c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b9dcd9d89aa6ae1d00000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000000002859cfc7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b7bb4d20000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000002c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b30000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000002c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b30000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000002c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b30000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000002c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b30000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000013462d2cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b4bac35d31010000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000002ec0989ddde0e6cac6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b9ded7d49795bc2c00000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000002ee3bd749ccfbdd0eacac6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b9e5bc5991610a80db2c
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000001c046dfc5bbbb
+c4e2e3e2c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b4debb9d3b
+65653b9ab3bc010000000000000000000000000000000000000000000000
+002b29292b00000000000000000000000000000000000000000000000034
+9843b8e45f5fe4bbe6dec8c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5bad7bd08d85959d807bfaf2f0000000000000000000000000000000000
+00000000000000d8cdcdd800000000000000000000000000000000000000
+000000000060da9ecf63282863d4d9d4d5c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5c3e3d6685822225868796d610000000000000000000000
+00000000000000000000000000b4bebeb400000000000000000000000000
+000000000000000000000061d5c9e35f26265fe3d8efd1c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5c4dcdda3551f1f559b8fea5c0000000000
+00000000000000000000000000000000000000b1bdbdb100000000000000
+0000000000000000000000000000000000349801a3d75f5fd7bce0e3c7c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5bad7b414a25959a21596b5
+2e0000000000000000000000000000000000000000000000009acdcd9a00
+000000000000000000000000000000000000000000000001bc81c3f69292
+f6cfcbe6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b4d9cc91ca
+4a4aca8141bb010000000000000000000000000000000000000000000000
+000751510700000000000000000000000000000000000000000000000000
+2de2c9a4a6bbd9e2ebc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b9e3ddad281fafccdf2b000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000002fc0989ddde0e6c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5baded7d49795bc2b00000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000013462d2cac6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b4bac35d31010000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000002c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b30000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000002c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b30000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000002c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b30000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000002c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b30000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/portugal.gif b/Docs/Flags/portugal.gif
index 91bf32addb2..add53255d60 100644
--- a/Docs/Flags/portugal.gif
+++ b/Docs/Flags/portugal.gif
Binary files differ
diff --git a/Docs/Flags/portugal.pdf b/Docs/Flags/portugal.pdf
new file mode 100644
index 00000000000..d1f66f846db
--- /dev/null
+++ b/Docs/Flags/portugal.pdf
Binary files differ
diff --git a/Docs/Flags/romania.eps b/Docs/Flags/romania.eps
index 03b53f502a1..c20a7b6871b 100644
--- a/Docs/Flags/romania.eps
+++ b/Docs/Flags/romania.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: romania.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/romania.gif b/Docs/Flags/romania.gif
index 2d38df262bf..a6ffa4ad0c2 100644
--- a/Docs/Flags/romania.gif
+++ b/Docs/Flags/romania.gif
Binary files differ
diff --git a/Docs/Flags/romania.pdf b/Docs/Flags/romania.pdf
new file mode 100644
index 00000000000..45503c541bf
--- /dev/null
+++ b/Docs/Flags/romania.pdf
Binary files differ
diff --git a/Docs/Flags/russia.eps b/Docs/Flags/russia.eps
index 85c5899d891..ce1e2cb22c1 100644
--- a/Docs/Flags/russia.eps
+++ b/Docs/Flags/russia.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: russia.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-909090909090909090909090909090909090909090909090909090909090
-000000000000000000000000000000000000000000000000000000000000
-333333333333333333333333333333333333333333333333333333333333
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9
+a9a9a9a9a9a9a9a9a9a9a9a9a90000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2e2e2e2e2e2e2e2e2e2e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e200000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500008686868686
+868686868686868686868686868686868686868686868686860000000000
+00000000000000000000000000000000000000000000000000000000003d
+3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/russia.gif b/Docs/Flags/russia.gif
index f72e7f78da6..f76e19d7f1b 100644
--- a/Docs/Flags/russia.gif
+++ b/Docs/Flags/russia.gif
Binary files differ
diff --git a/Docs/Flags/russia.pdf b/Docs/Flags/russia.pdf
new file mode 100644
index 00000000000..84c304cba32
--- /dev/null
+++ b/Docs/Flags/russia.pdf
Binary files differ
diff --git a/Docs/Flags/singapore.eps b/Docs/Flags/singapore.eps
index bc5faf248a7..5ebedcb4f94 100644
--- a/Docs/Flags/singapore.eps
+++ b/Docs/Flags/singapore.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: singapore.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6cbc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000001180d0000000000000000000000000000000000000000000000
-0000000001180e0000000000000000000000000000000000000000000000
-c6c6c6d7ecd6c7c6c8c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000054bd5004000b000000000000000000000000000000000000000000
-00000054bd5004000b000000000000000000000000000000000000000000
-c6c6d8f4cdc6c6c8e9ccc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000059e72200000aae1f0000000000000000000000000000000000000000
-000059e72200000aae1f0000000000000000000000000000000000000000
-c6c7f3dfc6c7c9c6cfc8c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0004e07d000410002c0b0015000000000000000000000000000000000000
-0004e07d000410002d0b0015000000000000000000000000000000000000
-c6cff7d2c6dbe0c6c6c6d6e5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-002af73e0067830000004d9b010000000000000000000000000000000000
-002bf73f0067830000004e9c010000000000000000000000000000000000
-c6cef7d3c6c9c9c6c6c6c9c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0029f740000d0d0000000d0d000000000000000000000000000000000000
-0029f740000d0d0000000d0d000000000000000000000000000000000000
-c6c7f2e0c6c6c7c9c6c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0003dd810000060e00001500000000000000000000000000000000000000
-0003dd810000060e00001500000000000000000000000000000000000000
-c6c6d7f4cec6dcdfc6d4e6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000052e927006c7e0048a102000000000000000000000000000000000000
-000053e927006d7e0048a102000000000000000000000000000000000000
-c6c6c6d5ebd8cbc9c6c9c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000004bb859160d000d0e00000000000000000000000000000000000000
-0000004bb85a160d000d0e00000000000000000000000000000000000000
-c8c8c8c8c8cbcac8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-070707070716100707070707070707070707070707070707070707070707
-070707070716100707070707070707070707070707070707070707070707
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6cbc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000170e0000000000000000000000000000
+00000000000000000000000000000000170e000000000000000000000000
+00000000000000000000000000c6c6c6d6ecd7c7c6c8c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000050bd5405000a000000000000
+000000000000000000000000000000000000000050bd5405000a00000000
+00000000000000000000000000000000000000c6c6d7f4cdc6c6c8e8cdc6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000055e925000008aa
+2400000000000000000000000000000000000000000000000055e9250000
+08aa2400000000000000000000000000000000000000000000c6c7f2e0c6
+c6cac6cfc9c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000003de
+81000211002c0e0013000000000000000000000000000000000000000000
+03de82000211002d0e001400000000000000000000000000000000000000
+00c6cef7d3c6dae1c6c6c6d3e7c7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000028f74200618900000042a5020000000000000000000000000000
+00000000000028f74200618900000043a503000000000000000000000000
+00000000000000c6cef7d3c6c9c9c6c6c6c9c9c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000028f742000f0f0000000e0f000000000000000000
+00000000000000000000000028f742000f0f0000000e1000000000000000
+00000000000000000000000000c6c7f2e0c6c6c7c9c6c6cac6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000003de810000030f00001300000000
+00000000000000000000000000000000000003de820000030f0000130000
+00000000000000000000000000000000000000c6c6d7f4cdc6dae0c6d2e8
+c7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000055e92500658400
+3ea8030000000000000000000000000000000000000000000055e9250065
+84003ea8030000000000000000000000000000000000000000c6c6c6d6ec
+d7cac9c6c9cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+50bd541510000f1200000000000000000000000000000000000000000000
+000050bd541510000f120000000000000000000000000000000000000000
+00c6c6c6c6c6cbc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000170e0000000000000000000000000000000000000000
+00000000000000000000170e000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f40000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f4f4f40000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/singapore.gif b/Docs/Flags/singapore.gif
index 7fbd3f87f62..38b06409764 100644
--- a/Docs/Flags/singapore.gif
+++ b/Docs/Flags/singapore.gif
Binary files differ
diff --git a/Docs/Flags/singapore.pdf b/Docs/Flags/singapore.pdf
new file mode 100644
index 00000000000..1d2666f851c
--- /dev/null
+++ b/Docs/Flags/singapore.pdf
Binary files differ
diff --git a/Docs/Flags/slovenia.eps b/Docs/Flags/slovenia.eps
new file mode 100755
index 00000000000..59b6482f5fa
--- /dev/null
+++ b/Docs/Flags/slovenia.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: slovenia.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7ad4d463b3b3b5340
+e5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f77d221a0f0f0f
+2814c0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7ad8a8f97
+97978593c7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f79b43
+330d39085d18e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+753c2c0533005811bcf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7b58a95b291b576a9c6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f79b08080c55080808e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7750000054f000000bcf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7b5b5b5b281b5b5b5c6f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f79b0808149a080808e2f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f77500000c97000000bcf7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7b5b5b5b8ddb5b5b5c6f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a9a9a9763f3a74f52f6316a6a9a9a9a9a9
+a9a9a9a9a9a9a9a9a9a9a9a9a90000a7a7a74f393370f5295e0e7fa7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2aac4c3d3f7c0ceb9b6e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2000008080836dae0e0f7cbf5aa
+2108080808080808080808080808080808080800000000000cd9dfdff7c9
+f59c000000000000000000000000000000000000000000b5b5b597eff1f1
+f7ebf6d59eb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000008080822bd
+c3e9f7d8c1a0080808080808080808080808080808080808080000000000
+05d1e8f3f7eee792000000000000000000000000000000000000000000b5
+b5b5a3e0f5f7f7f6f5bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080872c3b5c1b1bf3d080808080808080808080808080808080808
+0800000000000059e8e4e7e2dd1f00000000000000000000000000000000
+0000000000b5b5b5b5a8f5f5f5f5eb9fb5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080812c0e0c4eb8308080808080808080808080808
+080808080808080000000000000096f0e8f0510000000000000000000000
+0000000000000000000000b5b5b5b5acb8f6f5f3a0b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000080808080816abf0770908080808080808
+08080808080808080808080808000000000000000179dc44000000000000
+0000000000000000000000000000000000b5b5b5b5b5aaaade9cb4b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080925080808
+080808080808080808080808080808080808080000000000000000000200
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b4
+9bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500008686868686
+868686868686868686868686868686868686868686868686860000000000
+00000000000000000000000000000000000000000000000000000000003d
+3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/slovenia.gif b/Docs/Flags/slovenia.gif
new file mode 100644
index 00000000000..2cac6590840
--- /dev/null
+++ b/Docs/Flags/slovenia.gif
Binary files differ
diff --git a/Docs/Flags/slovenia.pdf b/Docs/Flags/slovenia.pdf
new file mode 100644
index 00000000000..b00ca0e6467
--- /dev/null
+++ b/Docs/Flags/slovenia.pdf
Binary files differ
diff --git a/mit-pthreads/machdep/linux-2.0/extra/bits/pthreadtypes.h b/Docs/Flags/slovenia.txt
index e69de29bb2d..e69de29bb2d 100644..100755
--- a/mit-pthreads/machdep/linux-2.0/extra/bits/pthreadtypes.h
+++ b/Docs/Flags/slovenia.txt
diff --git a/Docs/Flags/south-africa.eps b/Docs/Flags/south-africa.eps
index 702df9d4e6a..6c080095104 100644
--- a/Docs/Flags/south-africa.eps
+++ b/Docs/Flags/south-africa.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: south-africa.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000001fb8e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5bde6a3140000000000000000000000000000000000000000000000
-0000001fb8a4140000000000000000000000000000000000000000000000
-000000000169e9d6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5d1df5100000000000000000000000000000000000000000000
-000000000169d85100000000000000000000000000000000000000000000
-00000000000023bde6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5bee8a3140000000000000000000000000000000000000000
-00000000000023bda3140000000000000000000000000000000000000000
-080000000000000370ebd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b7b5b5b5b5b5b5b6d3df5100000000000000000000000000000000000000
-000000000000000370da5100000000000000000000000000000000000000
-db480000000000000028c3e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-f5cab5b5b5b5b5b5b5c0e9a3140000000000000000000000000000000000
-00000000000000000028c3a3140000000000000000000000000000000000
-4bddac1d0000000000000477edd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-4bdde7bdb5b5b5b5b5b5b6d5e05100000000000000000000000000000000
-000000000000000000000477dc5100000000000000000000000000000000
-000982eb74050000000000002dc8e6d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8
-000982f4d7b6b5b5b5b5b5b5c1eaa45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-0000000000000000000000002dc8a45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-00000025b8d23d00000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-00000025b8f2c7b5b5b5b5b5b5b6d5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-0000000000000000000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-000000000054e19f15000000000000000000000000000000000000000000
-000000000054e2e3bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
-0000000000000c8ae9670100000000000000000000000000000000000000
-0000000000000c8af6d3b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
-000000000000159ee1530000000000000000000000000000000000000000
-000000000000159ef6cdb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
-000000000268e88b0c000000000000000000000000000000000000000000
-000000000268ecdeb9b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000001eb6e7cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5bde6a7160000000000000000000000000000
+00000000000000000000000000001eb6a716000000000000000000000000
+00000000000000000000000000000000000167e8d7c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5d1e05400000000000000
+0000000000000000000000000000000000000000000167d9540000000000
+0000000000000000000000000000000000000000000000000022bce7cac6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5bee7a7
+160000000000000000000000000000000000000000000000000000000022
+bca716000000000000000000000000000000000000000000000700000000
+0000026eead7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b7b5b5
+b5b5b5b5b6d2e15400000000000000000000000000000000000000000000
+000000000000026edb540000000000000000000000000000000000000000
+00d9450000000000000026c1e7cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000f4c9b5b5b5b5b5b5b5bfe9a7160000000000000000000000000000
+000000000000000000000000000026c1a716000000000000000000000000
+0000000000000050e0a81a0000000000000374ecd7c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6000050e0e6bdb5b5b5b5b5b5b6d4e25400000000000000
+0000000000000000000000000000000000000000000374dd540000000000
+00000000000000000000000000000b87eb70040000000000002bc6e7d7d7
+d7d7d7d7d7d7d7d7d7d7d7d7d70000000b87f5d6b6b5b5b5b5b5b5c0eaa7
+53535353535353535353535353535300000000000000000000000000002b
+c6a7545454545454545454545454545454000000000028bdcf3900000000
+00000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7000000000028bdf1c6b5b5
+b5b5b5b5b6d5e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2000000000000000000
+0000000000000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a700000000000000
+59e49b130000000000000000000000000000000000000000000000000000
+000059e5e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000
000000000000000000000000000000000000000000000000000000000000
-00000034cac22c0000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-00000034caedc2b5b5b5b5b5b5b8dae5e5e5e5e5e5e5e5e5e5e5e5e5e5e5
-000000000000000000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-001195e760010000000000003cd4944c4c4c4c4c4c4c4c4c4c4c4c4c4c4c
-001195f6d1b5b5b5b5b5b5b5c5ed90464646464646464646464646464646
-0000000000000000000000003cd5dcc8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-5fe79812000000000000098ad64508080808080808080808080808080808
-5fe8e1bab5b5b5b5b5b5b7dad63f00000000000000000000000000000000
-00000000000000000000098aecc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-cd360000000000000036cf93130808080808080808080808080808080808
-f1c5b5b5b5b5b5b5b5c4eb900c0000000000000000000000000000000000
-00000000000000000036d1dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-030000000000000783d54508080808080808080808080808080808080808
-b6b5b5b5b5b5b5b7d8d63f00000000000000000000000000000000000000
-000000000000000783ebc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000000031cb94140808080808080808080808080808080808080808
-b5b5b5b5b5b5c2ea910c0000000000000000000000000000000000000000
-00000000000031ccdcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000057dd44608080808080808080808080808080808080808080808
-b5b5b5b5b6d6d64000000000000000000000000000000000000000000000
-00000000057deac6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0000002ac795140808080808080808080808080808080808080808080808
-b5b5b5c0ea920c0000000000000000000000000000000000000000000000
-0000002ac7dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000e90e86301000000000000000000000000000000000000
+0000000000000000000e90f6d2b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
+000000000000000000000000000e90e86301000000000000000000000000
+0000000000000000000000000000000e90f6d2b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5000000000000000000000000000000000000000000
+00000000000000000000000000000000000059e49b130000000000000000
+000000000000000000000000000000000000000059e5e2bbb5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000000000000000
+0000000000000000000000000000000000000000000028bdcf3900000000
+00000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7000000000028bdf1c6b5b5
+b5b5b5b5b6d5e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2000000000000000000
+0000000000000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000000b87eb70
+040000000000002bc6a95959595959595959595959595959590000000b87
+f5d6b6b5b5b5b5b5b5c0eaa7535353535353535353535353535353000000
+00000000000000000000002bc6e2cbcbcbcbcbcbcbcbcbcbcbcbcbcbcb00
+0050e0a81a0000000000000374dd5a080808080808080808080808080808
+08000050e0e6bdb5b5b5b5b5b5b6d4e25400000000000000000000000000
+0000000000000000000000000000000374ebccb5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000d9450000000000000026c1a91d08080808080808080808
+080808080808080000f4c9b5b5b5b5b5b5b5bfe9a7160000000000000000
+000000000000000000000000000000000000000026c1e2bbb5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5000007000000000000026edb5a080808080808
+080808080808080808080808080000b7b5b5b5b5b5b5b6d2e15400000000
+000000000000000000000000000000000000000000000000026ee9ccb5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000022bcaa1d08
+080808080808080808080808080808080808080000b5b5b5b5b5b5bee7a8
+160000000000000000000000000000000000000000000000000000000022
+bce2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000000000001
+67da5b080808080808080808080808080808080808080808080000b5b5b5
+b5b5d1e15500000000000000000000000000000000000000000000000000
+0000000167e7ccb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000000001eb6aa1d08080808080808080808080808080808080808080808
+080000b5b5b5bde6a8160000000000000000000000000000000000000000
+00000000000000001eb6e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/south-africa.gif b/Docs/Flags/south-africa.gif
index 7fd4ced4469..3ed8559eb2a 100644
--- a/Docs/Flags/south-africa.gif
+++ b/Docs/Flags/south-africa.gif
Binary files differ
diff --git a/Docs/Flags/south-africa.pdf b/Docs/Flags/south-africa.pdf
new file mode 100644
index 00000000000..6b6286a7794
--- /dev/null
+++ b/Docs/Flags/south-africa.pdf
Binary files differ
diff --git a/Docs/Flags/south-africa1.eps b/Docs/Flags/south-africa1.eps
deleted file mode 100644
index 702df9d4e6a..00000000000
--- a/Docs/Flags/south-africa1.eps
+++ /dev/null
@@ -1,87 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Creator: pnmtops
-%%Title: noname.ps
-%%Pages: 1
-%%BoundingBox: 291 371 320 391
-%%EndComments
-/readstring {
- currentfile exch readhexstring pop
-} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
-%%EndProlog
-%%Page: 1 1
-gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
-{ rpicstr readstring }
-{ gpicstr readstring }
-{ bpicstr readstring }
-true 3
-colorimage
-0000001fb8e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5bde6a3140000000000000000000000000000000000000000000000
-0000001fb8a4140000000000000000000000000000000000000000000000
-000000000169e9d6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5d1df5100000000000000000000000000000000000000000000
-000000000169d85100000000000000000000000000000000000000000000
-00000000000023bde6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5bee8a3140000000000000000000000000000000000000000
-00000000000023bda3140000000000000000000000000000000000000000
-080000000000000370ebd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b7b5b5b5b5b5b5b6d3df5100000000000000000000000000000000000000
-000000000000000370da5100000000000000000000000000000000000000
-db480000000000000028c3e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-f5cab5b5b5b5b5b5b5c0e9a3140000000000000000000000000000000000
-00000000000000000028c3a3140000000000000000000000000000000000
-4bddac1d0000000000000477edd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-4bdde7bdb5b5b5b5b5b5b6d5e05100000000000000000000000000000000
-000000000000000000000477dc5100000000000000000000000000000000
-000982eb74050000000000002dc8e6d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8
-000982f4d7b6b5b5b5b5b5b5c1eaa45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-0000000000000000000000002dc8a45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-00000025b8d23d00000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-00000025b8f2c7b5b5b5b5b5b5b6d5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-0000000000000000000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-000000000054e19f15000000000000000000000000000000000000000000
-000000000054e2e3bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-0000000000000c8ae9670100000000000000000000000000000000000000
-0000000000000c8af6d3b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000000159ee1530000000000000000000000000000000000000000
-000000000000159ef6cdb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000268e88b0c000000000000000000000000000000000000000000
-000000000268ecdeb9b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-00000034cac22c0000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-00000034caedc2b5b5b5b5b5b5b8dae5e5e5e5e5e5e5e5e5e5e5e5e5e5e5
-000000000000000000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-001195e760010000000000003cd4944c4c4c4c4c4c4c4c4c4c4c4c4c4c4c
-001195f6d1b5b5b5b5b5b5b5c5ed90464646464646464646464646464646
-0000000000000000000000003cd5dcc8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-5fe79812000000000000098ad64508080808080808080808080808080808
-5fe8e1bab5b5b5b5b5b5b7dad63f00000000000000000000000000000000
-00000000000000000000098aecc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-cd360000000000000036cf93130808080808080808080808080808080808
-f1c5b5b5b5b5b5b5b5c4eb900c0000000000000000000000000000000000
-00000000000000000036d1dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-030000000000000783d54508080808080808080808080808080808080808
-b6b5b5b5b5b5b5b7d8d63f00000000000000000000000000000000000000
-000000000000000783ebc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000000031cb94140808080808080808080808080808080808080808
-b5b5b5b5b5b5c2ea910c0000000000000000000000000000000000000000
-00000000000031ccdcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000057dd44608080808080808080808080808080808080808080808
-b5b5b5b5b6d6d64000000000000000000000000000000000000000000000
-00000000057deac6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0000002ac795140808080808080808080808080808080808080808080808
-b5b5b5c0ea920c0000000000000000000000000000000000000000000000
-0000002ac7dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-grestore
-showpage
-%%Trailer
diff --git a/Docs/Flags/south-africa1.gif b/Docs/Flags/south-africa1.gif
deleted file mode 100644
index 7fd4ced4469..00000000000
--- a/Docs/Flags/south-africa1.gif
+++ /dev/null
Binary files differ
diff --git a/Docs/Flags/south-korea.eps b/Docs/Flags/south-korea.eps
index a363ab514c4..8147ce78acf 100644
--- a/Docs/Flags/south-korea.eps
+++ b/Docs/Flags/south-korea.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: south-korea.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f7
-f7f7f7f7f7f7eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f7
-f7f7f7f7f7f7eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f7
-f7f7f7f7f7985ad7f7f7f7f7f7f7f7f7f7f7f7f7f7f7c255d3f7f7f7f7f7
-f7f7f7f7f7985ad7f7f7f7f7f7f7f7f7f7f7f7f7f7f7c255d3f7f7f7f7f7
-f7f7f7f7f7985ad7f7f7f7f7f7f7f7f7f7f7f7f7f7f7c255d3f7f7f7f7f7
-f7f7f7f7d6434363f7f7f7f7f7f7f7f7f7f7f7f7f7f0474476f6f7f7f7f7
-f7f7f7f7d6434363f7f7f7f7f7f7f7f7f7f7f7f7f7f0474476f6f7f7f7f7
-f7f7f7f7d6434363f7f7f7f7f7f7f7f7f7f7f7f7f7f0474476f6f7f7f7f7
-f7f7f7f7584345e4f7f7f7f7f7f6f1f1f7f7f7f7f7f7ba5a4391f7f7f7f7
-f7f7f7f7584345e4f7f7f7f7f7f4d7d9f5f7f7f7f7f7ba5a4391f7f7f7f7
-f7f7f7f7584345e4f7f7f7f7f7f4d8d9f5f7f7f7f7f7ba5a4391f7f7f7f7
-f7f7f7f7d65ab0f7f7f7f7f5decac6c6cbe0f6f7f7f7f76570dcf7f7f7f7
-f7f7f7f7d65ab0f7f7f7f7ef791300001884f3f7f7f7f76570dcf7f7f7f7
-f7f7f7f7d65ab0f7f7f7f7ef791300001885f3f7f7f7f76570dcf7f7f7f7
-f7f7f7f7f7f3f7f7f7f7f5d2c6c6c6c6c6c6d6f7f7f7f7ecf4f7f7f7f7f7
-f7f7f7f7f7f3f7f7f7f7ed3a0000000000004ef4f7f7f7ecf4f7f7f7f7f7
-f7f7f7f7f7f3f7f7f7f7ed3a0000000000004ef4f7f7f7ecf4f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7d9c6c6c6c6c6c6c6c6e3f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76c00000000000000008ff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76e00000000000000008ff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7eebbc6c6c6c6bc68548ecef7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ee0a000000000000000026f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f41600000000095a6d3526f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c8b1c6c6c6c53908080875f5f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c600000000000000000001eaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ea140000000187b5b5b54eeaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c75fc6c6c66a080808082cf4f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c500000000000000000000e7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ea6300000058b5b5b5b593e8f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ed114b6b36080808080838f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ed0900000000000000001df7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f4b7755789b5b5b5b5b5a9f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76b080808080808080884f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76600000000000000007ef7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7d0b5b5b5b5b5b5b5b5d5f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7eef6f7f7f7ea3508080808080844f1f7f7f7ecedf7f7f7f7f7
-f7f7f7f7f7eef6f7f7f7e92f0000000000003ef1f7f7f7ecedf7f7f7f7f7
-f7f7f7f7f7eef6f7f7f7f3c1b5b5b5b5b5b5c6f5f7f7f7ecedf7f7f7f7f7
-f7f7f7f7cd569af7f7f7f7eb70140808187bf0f7f7f7f76b60d6f7f7f7f7
-f7f7f7f7cd569af7f7f7f7ea6b0c00001177f0f7f7f7f76b60d6f7f7f7f7
-f7f7f7f7cd569af7f7f7f7f4d2b8b5b5b9d5f5f7f7f7f76b60d6f7f7f7f7
-f7f7f7f7604b52dff7f7f7f7f7f1d0d2f3f7f7f7f7f7b4794787f7f7f7f7
-f7f7f7f7604b52dff7f7f7f7f7f1cfd1f3f7f7f7f7f7b4794787f7f7f7f7
-f7f7f7f7604b52dff7f7f7f7f7f5ecedf6f7f7f7f7f7b4794787f7f7f7f7
-f7f7f7f7e0504563f7f7f7f7f7f7f7f7f7f7f7f7f7f14a4678f5f7f7f7f7
-f7f7f7f7e0504563f7f7f7f7f7f7f7f7f7f7f7f7f7f14a4678f5f7f7f7f7
-f7f7f7f7e0504563f7f7f7f7f7f7f7f7f7f7f7f7f7f14a4678f5f7f7f7f7
-f7f7f7f7f79c64ddf7f7f7f7f7f7f7f7f7f7f7f7f7f7d060d8f7f7f7f7f7
-f7f7f7f7f79c64ddf7f7f7f7f7f7f7f7f7f7f7f7f7f7d060d8f7f7f7f7f7
-f7f7f7f7f79c64ddf7f7f7f7f7f7f7f7f7f7f7f7f7f7d060d8f7f7f7f7f7
-f7f7f7f7f7f7f4f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f4f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f4f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f6f7f7f7f7f7f70000f7f7f7f7f7f7f0f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f6f7f7f7f7f7f70000f7f7f7f7f7f7f0f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f6f7f7f7f7f7f70000f7f7f7f7f79f58d5f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7d05ac3f7f7f7f7f70000f7f7f7f7f79f58d5f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7d05ac3f7f7f7f7f70000f7f7f7f7f79f58
+d5f7f7f7f7f7f7f7f7f7f7f7f7f7f7d05ac3f7f7f7f7f70000f7f7f7f7db
+43435df7f7f7f7f7f7f7f7f7f7f7f7f7f54d446ef1f7f7f7f70000f7f7f7
+f7db43435df7f7f7f7f7f7f7f7f7f7f7f7f7f54d446ef1f7f7f7f70000f7
+f7f7f7db43435df7f7f7f7f7f7f7f7f7f7f7f7f7f54d446ef1f7f7f7f700
+00f7f7f7f75a4344dff7f7f7f7f7f7f2f2f7f7f7f7f7f7c660447df7f7f7
+f70000f7f7f7f75a4344dff7f7f7f7f7f6dddcf6f7f7f7f7f7c660447df7
+f7f7f70000f7f7f7f75a4344dff7f7f7f7f7f6dddcf6f7f7f7f7f7c66044
+7df7f7f7f70000f7f7f7f7d659a7f7f7f7f7f6e0cbc6c6cbe0f6f7f7f7f7
+7261d4f7f7f7f70000f7f7f7f7d659a7f7f7f7f7f3851a00001780f2f7f7
+f7f77261d4f7f7f7f70000f7f7f7f7d659a7f7f7f7f7f3851a00001880f2
+f7f7f7f77261d4f7f7f7f70000f7f7f7f7f7f2f7f7f7f7f6d4c6c6c6c6c6
+c6d4f6f7f7f7eef0f7f7f7f7f70000f7f7f7f7f7f2f7f7f7f7f246000000
+00000044f2f7f7f7eef0f7f7f7f7f70000f7f7f7f7f7f2f7f7f7f7f24600
+000000000044f2f7f7f7eef0f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7dc
+c6c6c6c6c6c6c6c6dff7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f77a000000000000000080f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f77d000000000000000080f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f3b9c6c6c6c6c173598ecbf7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f311000000000000000017f5f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f62000000000054f683517f5f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7d2abc6c6c6c6490808086cf1f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7d000000000000000000000d8f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7ed1a0000000078b5b5b556d8f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7cf5cc6c6c67c080808081ef0f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7ce00000000000000000000d3
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7ec6500000046b5b5b5b5
+a0d4f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f113507544080808
+080825f6f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f10b00000000
+000000000bf2f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f5b8714e
+7cb5b5b5b5b5a7f2f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f76e
+08080808080808086cf7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f76a000000000000000065f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7d1b5b5b5b5b5b5b5b5cef7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f2f7f7f7f7ea3408080808080830e8f7f7f7f4ecf7f7f7f7f70000f7f7f7
+f7f7f2f7f7f7f7ea2d00000000000029e7f7f7f7f4ecf7f7f7f7f70000f7
+f7f7f7f7f2f7f7f7f7f3c1b5b5b5b5b5b5c0f3f7f7f7f4ecf7f7f7f7f700
+00f7f7f7f7d85f9df7f7f7f7e9690f08080e65e7f7f7f7f7845bd7f7f7f7
+f70000f7f7f7f7d85f9df7f7f7f7e9640800000660e6f7f7f7f7845bd7f7
+f7f7f70000f7f7f7f7d85f9df7f7f7f7f3d0b7b5b5b7cff3f7f7f7f7845b
+d7f7f7f7f70000f7f7f7f75f4650e1f7f7f7f7f7ecc3c2eaf7f7f7f7f7ca
+78486cf7f7f7f70000f7f7f7f75f4650e1f7f7f7f7f7ebc1c0eaf7f7f7f7
+f7ca78486cf7f7f7f70000f7f7f7f75f4650e1f7f7f7f7f7f4e9e8f3f7f7
+f7f7f7ca78486cf7f7f7f70000f7f7f7f7dd534961f7f7f7f7f7f7f7f7f7
+f7f7f7f7f6504671ebf7f7f7f70000f7f7f7f7dd534961f7f7f7f7f7f7f7
+f7f7f7f7f7f7f6504671ebf7f7f7f70000f7f7f7f7dd534961f7f7f7f7f7
+f7f7f7f7f7f7f7f7f6504671ebf7f7f7f70000f7f7f7f7f79659d1f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7d359bff7f7f7f7f70000f7f7f7f7f79659d1f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7d359bff7f7f7f7f70000f7f7f7f7f79659
+d1f7f7f7f7f7f7f7f7f7f7f7f7f7f7d359bff7f7f7f7f70000f7f7f7f7f7
+f6eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f70000f7f7f7
+f7f7f6eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f70000f7
+f7f7f7f7f6eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/south-korea.gif b/Docs/Flags/south-korea.gif
index 0d8630ba963..f9a74adc732 100644
--- a/Docs/Flags/south-korea.gif
+++ b/Docs/Flags/south-korea.gif
Binary files differ
diff --git a/Docs/Flags/south-korea.pdf b/Docs/Flags/south-korea.pdf
new file mode 100644
index 00000000000..877d792caa8
--- /dev/null
+++ b/Docs/Flags/south-korea.pdf
Binary files differ
diff --git a/Docs/Flags/spain.eps b/Docs/Flags/spain.eps
index 340fe9c7671..bd318f2160a 100644
--- a/Docs/Flags/spain.eps
+++ b/Docs/Flags/spain.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: spain.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
-040404040404040404040404040404040404040404040404040404040404
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-fdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc
+fcfcfcfcfcfcfcfcfc000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000030303030303030303030303030303030303030303
+030303030303030303000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000000000000000000000000000000000000000000000000000000
-fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc
-f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/spain.gif b/Docs/Flags/spain.gif
index 9d2e1be0fe7..f5ad336b00d 100644
--- a/Docs/Flags/spain.gif
+++ b/Docs/Flags/spain.gif
Binary files differ
diff --git a/Docs/Flags/spain.pdf b/Docs/Flags/spain.pdf
new file mode 100644
index 00000000000..2606d779597
--- /dev/null
+++ b/Docs/Flags/spain.pdf
Binary files differ
diff --git a/Docs/Flags/sweden.eps b/Docs/Flags/sweden.eps
index 47cd1fa3e9c..18a7c8765ba 100644
--- a/Docs/Flags/sweden.eps
+++ b/Docs/Flags/sweden.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: sweden.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0e0e0e0e0e0e0e16fffffff10e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-060606060606060efffffff0060606060606060606060606060606060606
-b1b1b1b1b1b1b1ab0000000ab1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-010101010101010100000000010101010101010101010101010101010101
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-080808080808080800000000080808080808080808080808080808080808
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808fffffffc0808080808080808080808
+0808080808080800000000000000000000fffffffc000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808fffffffc0808080808
+0808080808080808080808080800000000000000000000fffffffc000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b500000002b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808fffffffc0808080808080808080808080808080808080000000000
+0000000000fffffffc0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808fffffffc0808080808080808080808080808080808
+0800000000000000000000fffffffc000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808fffffffc0808080808080808080808
+0808080808080800000000000000000000fffffffc000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808fffffffc0808080808
+0808080808080808080808080800000000000000000000fffffffc000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b500000002b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000fcfcfcfcfc
+fcfcfcfffffffffcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc0000fcfcfc
+fcfcfcfcfcfffffffffcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc000002
+020202020202020000000002020202020202020202020202020202020200
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+000000000000000000000000000000000000000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808fffffffc0808080808080808080808080808080808080000000000
+0000000000fffffffc0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808fffffffc0808080808080808080808080808080808
+0800000000000000000000fffffffc000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808fffffffc0808080808080808080808
+0808080808080800000000000000000000fffffffc000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808fffffffc0808080808
+0808080808080808080808080800000000000000000000fffffffc000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b500000002b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808fffffffc0808080808080808080808080808080808080000000000
+0000000000fffffffc0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808fffffffc0808080808080808080808080808080808
+0800000000000000000000fffffffc000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/sweden.gif b/Docs/Flags/sweden.gif
index e16ede8e641..df7151b5aa8 100644
--- a/Docs/Flags/sweden.gif
+++ b/Docs/Flags/sweden.gif
Binary files differ
diff --git a/Docs/Flags/sweden.pdf b/Docs/Flags/sweden.pdf
new file mode 100644
index 00000000000..718d57600fd
--- /dev/null
+++ b/Docs/Flags/sweden.pdf
Binary files differ
diff --git a/Docs/Flags/switzerland.eps b/Docs/Flags/switzerland.eps
index 517919e3125..635eef9f80a 100644
--- a/Docs/Flags/switzerland.eps
+++ b/Docs/Flags/switzerland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: switzerland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c7c7c7c7c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000404040400000000000000000000000000
-000000000000000000000000000404040400000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c8c8c8cbf7f7f7f4c8c8c8c8c6c6c6c6c6c6c6c6c6
-00000000000000000008080817f7f7f7e708080807000000000000000000
-00000000000000000008080817f7f7f7e708080807000000000000000000
-c6c6c6c6c6c6c6c6c9f7f7f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-c6c6c6c6c6c6c6c6c9f7f7f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-c6c6c6c6c6c6c6c6c9f7f7f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-c6c6c6c6c6c6c6c6c8f5f5f5f5f7f7f7f7f5f5f5f1c6c6c6c6c6c6c6c6c6
-00000000000000000beeeeeeeff7f7f7f6eeeeeeda000000000000000000
-00000000000000000cefefefeff7f7f7f6efefefdb000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f5f5f5f2c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000feaeaeada00000000000000000000000000
-0000000000000000000000000febebebdb00000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6
+c6000000000000000000000000000003f7f7f7f700000000000000000000
+000000000000000000000000000000000003f7f7f7f70000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6
+c6c6c6c6c6c6c6000000000000000000000000000003f7f7f7f700000000
+000000000000000000000000000000000000000000000003f7f7f7f70000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000000000000000000000003f7f7
+f7f700000000000000000000000000000000000000000000000000000003
+f7f7f7f7000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+00000003f7f7f7f700000000000000000000000000000000000000000000
+000000000003f7f7f7f7000000000000000000000000000000c6c6c6c6c6
+c6c6c6c7f7f7f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c60000000000
+000000000003f7f7f7f7f7f7f7f7f7f7f7f7000000000000000000000000
+0000000000000003f7f7f7f7f7f7f7f7f7f7f7f700000000000000000000
+00c6c6c6c6c6c6c6c6c7f7f7f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6
+c60000000000000000000003f7f7f7f7f7f7f7f7f7f7f7f7000000000000
+0000000000000000000000000003f7f7f7f7f7f7f7f7f7f7f7f700000000
+00000000000000c6c6c6c6c6c6c6c6c7f7f7f7f7f7f7f7f7f7f7f7f7c6c6
+c6c6c6c6c6c6c60000000000000000000003f7f7f7f7f7f7f7f7f7f7f7f7
+0000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7
+f7f70000000000000000000000c6c6c6c6c6c6c6c6c7f7f7f7f7f7f7f7f7
+f7f7f7f7c6c6c6c6c6c6c6c6c60000000000000000000003f7f7f7f7f7f7
+f7f7f7f7f7f70000000000000000000000000000000000000003f7f7f7f7
+f7f7f7f7f7f7f7f70000000000000000000000c6c6c6c6c6c6c6c6c6c7c7
+c7c8f7f7f7f7c7c7c7c7c6c6c6c6c6c6c6c6c60000000000000000000000
+03030306f7f7f7f703030303000000000000000000000000000000000000
+000003030306f7f7f7f7030303030000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+00000000000000000003f7f7f7f700000000000000000000000000000000
+000000000000000000000003f7f7f7f70000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6
+c6000000000000000000000000000003f7f7f7f700000000000000000000
+000000000000000000000000000000000003f7f7f7f70000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6
+c6c6c6c6c6c6c6000000000000000000000000000003f7f7f7f700000000
+000000000000000000000000000000000000000000000003f7f7f7f70000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c7c7c7c7
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000303
+030300000000000000000000000000000000000000000000000000000000
+03030303000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/switzerland.gif b/Docs/Flags/switzerland.gif
index 98cef7c28d6..8212d226678 100644
--- a/Docs/Flags/switzerland.gif
+++ b/Docs/Flags/switzerland.gif
Binary files differ
diff --git a/Docs/Flags/switzerland.pdf b/Docs/Flags/switzerland.pdf
new file mode 100644
index 00000000000..26935b96dfc
--- /dev/null
+++ b/Docs/Flags/switzerland.pdf
Binary files differ
diff --git a/Docs/Flags/taiwan.eps b/Docs/Flags/taiwan.eps
index a514bdf2af4..a57a8242464 100644
--- a/Docs/Flags/taiwan.eps
+++ b/Docs/Flags/taiwan.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: taiwan.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-080808080808081108080808080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000900000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7b5b5b5b5b5b5aa000000000000000000000000000000
-0808080808490e9e11450808080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000043069a0a3f0000000000000000000000000000000000000000
-b5b5b5b5b5c7b7deb8c6b5b5b5b5aa000000000000000000000000000000
-0808080e14658bb28d59170c080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000060c6087b089530f04000000000000000000000000000000000000
-b5b5b5b7b8cfd9e4dacbb9b6b5b5aa000000000000000000000000000000
-0808080baba1f7f7f7a0a009080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000003a89ef7f7f79d9c00000000000000000000000000000000000000
-b5b5b5b6e2dff7f7f7dfdfb5b5b5aa000000000000000000000000000000
-0808082b5becf7f7f7e06025080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000002456ecf7f7f7df5b1e000000000000000000000000000000000000
-b5b5b5bfccf4f7f7f7f1cdbdb5b5aa000000000000000000000000000000
-0808082556eaf7f7f7de5a20080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000001e50eaf7f7f7dd5418000000000000000000000000000000000000
-b5b5b5bdcaf3f7f7f7f0ccbcb5b5aa000000000000000000000000000000
-0808080bb099f7f7f799a509080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000004ad96f7f7f795a201000000000000000000000000000000000000
-b5b5b5b6e3ddf7f7f7dde0b5b5b5aa000000000000000000000000000000
-0808080d0e6b82b2855f100b080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000507667eb081590903000000000000000000000000000000000000
-b5b5b5b6b7d0d7e4d7cdb7b6b5b5aa000000000000000000000000000000
-0808080808440c970f410808080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000000003e0493073b0000000000000000000000000000000000000000
-b5b5b5b5b5c6b6dcb7c5b5b5b5b5aa000000000000000000000000000000
-0e0e0e0e0e0e0e150e0e0e0e0e0e19c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000700000000000000000000000000000000000000000000
-b0b0b0b0b0b0b0b2b0b0b0b0b0b0a6000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-010101010101010101010101010101000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000080808080808081108080808080808c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000900000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b7b5b5b5b5b5b5b500000000
+000000000000000000000000000808080808470e9e0f470808080808c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000041069a07410000000000
+0000000000000000000000000000000000b5b5b5b5b5c6b7deb7c6b5b5b5
+b5b500000000000000000000000000000000000808080d126289b28b6013
+0d080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000060a5d85b087
+5b0b050000000000000000000000000000000000000000b5b5b5b6b8ced8
+e4d9cdb8b6b5b5b500000000000000000000000000000000000808080aac
+9df7f7f7a0aa0a080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+02a99af7f7f79ca7020000000000000000000000000000000000000000b5
+b5b5b6e2def7f7f7dfe2b6b5b5b500000000000000000000000000000000
+000808082759e8f7f7f7e85b25080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000002053e8f7f7f7e8551e000000000000000000000000000000
+0000000000b5b5b5bdcbf3f7f7f7f3ccbdb5b5b500000000000000000000
+000000000000000808082858e8f7f7f7e85a26080808c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000002052e8f7f7f7e8551f000000000000000000
+0000000000000000000000b5b5b5becbf3f7f7f7f3ccbdb5b5b500000000
+000000000000000000000000000808080aac9cf7f7f79faa09080808c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000002a999f7f7f79ca701000000
+0000000000000000000000000000000000b5b5b5b5e2def7f7f7dfe2b5b5
+b5b500000000000000000000000000000000000808080e136487b2896113
+0d080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000060b5e83b085
+5c0c050000000000000000000000000000000000000000b5b5b5b7b8ced8
+e4d8ceb8b6b5b5b500000000000000000000000000000000000808080808
+480e9e0f480808080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000042069b074200000000000000000000000000000000000000000000b5
+b5b5b5b5c7b7deb7c7b5b5b5b5b500000000000000000000000000000000
+00080808080808081108080808080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000900000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b7b5b5b5b5b5b5b500000000000000000000
+00000000000000c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000002020202020202020202020202020200000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/taiwan.gif b/Docs/Flags/taiwan.gif
index 5cfc3d46425..379afea61ce 100644
--- a/Docs/Flags/taiwan.gif
+++ b/Docs/Flags/taiwan.gif
Binary files differ
diff --git a/Docs/Flags/taiwan.pdf b/Docs/Flags/taiwan.pdf
new file mode 100644
index 00000000000..013b5c16d9a
--- /dev/null
+++ b/Docs/Flags/taiwan.pdf
Binary files differ
diff --git a/Docs/Flags/turkey.eps b/Docs/Flags/turkey.eps
new file mode 100644
index 00000000000..7df5bfe70dc
--- /dev/null
+++ b/Docs/Flags/turkey.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: turkey.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c8d9e4d9c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000095f97610d0000000000000000000000000000
+00000000000000000000000000095f97610d000000000000000000000000
+00000000000000c6c6c6c6c6c6c6d1f1e4cac6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000039da951600000000000000000000
+00000000000000000000000000000000000039da96160000000000000000
+00000000000000000000000000c6c6c6c6c6c6d0f5dec6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000000000033ed78000000000000
+000000000000000000000000000000000000000000000033ee7800000000
+00000000000000000000000000000000000000c6c6c6c6c6c6efeec6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000002ccca02
+0000000000000000000000000000000000000000000000000000000002cc
+ca020000000000000000000000000000000000000000000000c6c6c6c6c6
+d2f7ddc6c6c6c6c6c6d6c8cbc6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+00003af77300000000000051091800000000000000000000000000000000
+000000003af7730000000000005209180000000000000000000000000000
+00c6c6c6c6c6dbf7d5c6c6c6c6c6cbe8f4d4c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000068f74c00000000001babe54600000000000000000000
+0000000000000000000069f74d00000000001babe5460000000000000000
+00000000000000c6c6c6c6c6dbf7d5c6c6c6c6c6cee7f1d9c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000068f74c000000000028a5d85f00000000
+0000000000000000000000000000000069f74d000000000028a5d8600000
+00000000000000000000000000c6c6c6c6c6d2f7ddc6c6c6c6c6c6d5c9c7
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000000003af77200000000000048
+0d0700000000000000000000000000000000000000003af7730000000000
+00490d07000000000000000000000000000000c6c6c6c6c6c6efeec6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000002ccca02
+0000000000000000000000000000000000000000000000000000000002cc
+ca020000000000000000000000000000000000000000000000c6c6c6c6c6
+c6d0f5dec6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+00000033ed78000000000000000000000000000000000000000000000000
+000000000033ee7800000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6d1f1e4cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000039da951600000000000000000000000000000000
+00000000000000000000000039da96160000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c8d9e4d9c9c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000095f97610d0000000000000000
+00000000000000000000000000000000000000095f97610d000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/turkey.gif b/Docs/Flags/turkey.gif
new file mode 100644
index 00000000000..45064417a3f
--- /dev/null
+++ b/Docs/Flags/turkey.gif
Binary files differ
diff --git a/Docs/Flags/turkey.pdf b/Docs/Flags/turkey.pdf
new file mode 100644
index 00000000000..899624408a8
--- /dev/null
+++ b/Docs/Flags/turkey.pdf
Binary files differ
diff --git a/mit-pthreads/machdep/linux-2.0/socketcall.h b/Docs/Flags/turkey.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/mit-pthreads/machdep/linux-2.0/socketcall.h
+++ b/Docs/Flags/turkey.txt
diff --git a/Docs/Flags/ukraine.eps b/Docs/Flags/ukraine.eps
index fe2436fa554..1cf43b4b53c 100644
--- a/Docs/Flags/ukraine.eps
+++ b/Docs/Flags/ukraine.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: ukraine.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f
-b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7
-e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8
-fefefefefefefefefefefefefefefefefefefefefefefefefefefefefefe
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-010101010101010101010101010101010101010101010101010101010101
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+000000000000001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef0000fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc
+fcfcfcfcfcfcfc0000fefefefefefefefefefefefefefefefefefefefefe
+fefefefefefefefefe000003030303030303030303030303030303030303
+03030303030303030303030000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/ukraine.gif b/Docs/Flags/ukraine.gif
index b951bef5b2a..77deda40904 100644
--- a/Docs/Flags/ukraine.gif
+++ b/Docs/Flags/ukraine.gif
Binary files differ
diff --git a/Docs/Flags/ukraine.pdf b/Docs/Flags/ukraine.pdf
new file mode 100644
index 00000000000..9731eb218ba
--- /dev/null
+++ b/Docs/Flags/ukraine.pdf
Binary files differ
diff --git a/Docs/Flags/usa.eps b/Docs/Flags/usa.eps
index 31bd9996d11..08d78b8d8e6 100644
--- a/Docs/Flags/usa.eps
+++ b/Docs/Flags/usa.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: usa.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-182608340a122c08300e0e31082b1ec6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-111f002d020a25002907062a00240b000000000000000000000000000000
-b9bdb5c1b6b8bfb5c0b7b7c0b5bfad000000000000000000000000000000
-1a2422331d182b243117183223291fdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc
-121d1a2c1610241c2a0f112b1c2211717171717171717171717171717171
-babdbcc1bbb9bfbdc0b9b9c0bdbeb4717171717171717171717171717171
-0a134413301e134513262813451316f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-020b3e0c29170b3f0c1f210c3f0c0ff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b8c5b8c0bbb8c6b8bdbeb8c6b8b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-28360e54101b430e4e1212500e4029c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9
-212f064e08133d06480b0a49063a17101010101010101010101010101010
-bec2b7cab7bac5b7c8b8b8c9b7c5b1101010101010101010101010101010
-080e580a3f250b5b0a30340a5b0c14d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-00065302391e035603292d02550406616161616161616161616161616161
-b5b7cbb6c4bdb6ccb6c0c1b6ccb6b0616161616161616161616161616161
-2a3d085c0b1b4c0856110f5808492cf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-233700570313460051090753004325f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-bec4b5ccb6bac8b5cab7b7cbb5c7bff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080c5d084425096008323708600913cccccccccccccccccccccccccccccc
-000458003e1e015b002b30005a01021f1f1f1f1f1f1f1f1f1f1f1f1f1f1f
-b5b6cdb5c5bdb5cdb5c1c2b5cdb5ac1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f
-293f085e0a1a4e0858100e5a084b29d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-22390059021348005308065500451b525252525252525252525252525252
-bec4b5cdb6bac8b5cbb7b7ccb5c7b5525252525252525252525252525252
-080c58094222095b083034085a0a16f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000452013b1b015500292e0055020ff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b6cbb5c5bcb5ccb5c0c1b5ccb5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-23370e500d19440e4b12114c0e4224cfcfcfcfcfcfcfcfcfcfcfcfcfcfcf
-1b31064a05113e06450a0946063c132f2f2f2f2f2f2f2f2f2f2f2f2f2f2f
-bcc2b7c9b6bac5b7c7b8b8c8b7c5b22f2f2f2f2f2f2f2f2f2f2f2f2f2f2f
-4f504857484d524856494956485155d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3
-494a425142474d4250434351424c47424242424242424242424242424242
-c9c9c7cbc7c8cac7cbc7c7cbc7c9c1424242424242424242424242424242
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
-3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
-3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
-d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0
-323232323232323232323232323232323232323232323232323232323232
-323232323232323232323232323232323232323232323232323232323232
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5
-4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e
-4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e
-cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd
-232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
-5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000182608330b112d082e100c32082915c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000101f002d030926002708042b00220e000000000000
+0000000000000000000000b9bdb5c1b6b8bfb5c0b7b6c1b5beb900000000
+000000000000000000000000001a2421341c162d2330151a34212617dcdc
+dcdcdcdcdcdcdcdcdcdcdcdcdc0000121d192d140e261b290d132d1a1f10
+6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f0000babdbcc1bab9bfbcc0b8bac1bc
+bdb96f6f6f6f6f6f6f6f6f6f6f6f6f6f6f0000091246122f21124712232c
+12471308f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000010a400a28190a410a
+1c260a410b00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b8c6b8c0bcb8
+c6b8bcbfb8c6b8b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000028370d5510
+18480d4c1411540d3b24cacacacacacacacacacacacacacaca0000213105
+4f08104105460d094e05351d1313131313131313131313131313130000be
+c2b6cab7b9c7b6c8b8b7cab6c3bd13131313131313131313131313131300
+00080d5a0a3e280a5d0a2b3a0a5b0c08d8d8d8d8d8d8d8d8d8d8d8d8d8d8
+d800000005540237210257022433025505005d5d5d5d5d5d5d5d5d5d5d5d
+5d5d5d0000b5b6ccb5c4beb6ccb5bfc3b5ccb6b55d5d5d5d5d5d5d5d5d5d
+5d5d5d5d5d0000293f085d0b18500854140c5c084325f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f700002238005703104a004e0c0456003d1df7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000bec4b5ccb6b9c9b5cab8b6ccb5c5bdf7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000080b5f0842280862082c3e08600b08cdcd
+cdcdcdcdcdcdcdcdcdcdcdcdcd0000000359003c21005c002538005a0300
+2525252525252525252525252525250000b5b6cdb5c5beb5ceb5bfc4b5cd
+b6b525252525252525252525252525252500002940085d0b17510855130c
+5c084424d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5000021390058030f4b004f
+0b0457003e1d4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a0000bec4b5ccb6b9c9
+b5cab8b6ccb5c6bd4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a0000090c560a3e
+24095909283a0a570b09f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000010450
+02381d015401213402510301f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b6cbb5c4bdb5cbb5bec3b5cbb6b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+002035114b0f1842114515114a11391cd1d1d1d1d1d1d1d1d1d1d1d1d1d1
+d10000192f094507103c093f0e0944093315383838383838383838383838
+3838380000bcc2b7c7b7b9c5b7c6b9b7c7b7c3bb38383838383838383838
+3838383838000047493e523e424d3e4f413e523e4a46d1d1d1d1d1d1d1d1
+d1d1d1d1d1d1d100004143384c383d4738493b384c384440383838383838
+3838383838383838380000c6c7c4c9c4c5c8c4c8c5c4c9c4c7c638383838
+38383838383838383838380000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000d5d5d5d5d5d5d5d5d5d5d5
+d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d500004a4a4a4a4a4a4a4a4a
+4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a00004a4a4a4a4a4a4a
+4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a0000cdcdcdcdcd
+cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd0000252525
+252525252525252525252525252525252525252525252525252525000025
+252525252525252525252525252525252525252525252525252525252500
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8
+d8d8d8d8d8d8d800005d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
+5d5d5d5d5d5d5d5d5d00005d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
+5d5d5d5d5d5d5d5d5d5d5d0000cacacacacacacacacacacacacacacacaca
+cacacacacacacacacacacacaca0000121212121212121212121212121212
+121212121212121212121212121212000012121212121212121212121212
+12121212121212121212121212121212120000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000dcdcdcdcdc
+dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc00006f6f6f
+6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f00006f
+6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/usa.gif b/Docs/Flags/usa.gif
index da9f4e27d6c..4d9c261808d 100644
--- a/Docs/Flags/usa.gif
+++ b/Docs/Flags/usa.gif
Binary files differ
diff --git a/Docs/Flags/usa.pdf b/Docs/Flags/usa.pdf
new file mode 100644
index 00000000000..f8bd86fdd1a
--- /dev/null
+++ b/Docs/Flags/usa.pdf
Binary files differ
diff --git a/Docs/Flags/yugoslavia.eps b/Docs/Flags/yugoslavia.eps
index e69de29bb2d..221d510451d 100644
--- a/Docs/Flags/yugoslavia.eps
+++ b/Docs/Flags/yugoslavia.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: yugoslavia.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500005555555555555555555555555555555555
+555555555555555555555555550000505050505050505050505050505050
+5050505050505050505050505050500000cacacacacacacacacacacacaca
+cacacacacacacacacacacacacacacacaca0000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000d7d7d7d7d7
+d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d70000535353
+535353535353535353535353535353535353535353535353535353000054
+545454545454545454545454545454545454545454545454545454545400
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/yugoslavia.gif b/Docs/Flags/yugoslavia.gif
index 650eac242d6..e1dd52a0541 100644
--- a/Docs/Flags/yugoslavia.gif
+++ b/Docs/Flags/yugoslavia.gif
Binary files differ
diff --git a/Docs/Flags/yugoslavia.pdf b/Docs/Flags/yugoslavia.pdf
new file mode 100644
index 00000000000..1156cd257b8
--- /dev/null
+++ b/Docs/Flags/yugoslavia.pdf
Binary files differ
diff --git a/Docs/Makefile.am b/Docs/Makefile.am
index 17def904875..80832719893 100644
--- a/Docs/Makefile.am
+++ b/Docs/Makefile.am
@@ -21,12 +21,13 @@ info_TEXINFOS = manual.texi
targets = manual.txt mysql.info manual.html
BUILT_SOURCES = $(targets) manual_toc.html include.texi
-EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt INSTALL-BINARY
+EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt \
+ INSTALL-BINARY mirrors.texi
all: $(targets) txt_files
txt_files: ../INSTALL-SOURCE ../COPYING ../COPYING.LIB \
- ../MIRRORS INSTALL-BINARY
+ INSTALL-BINARY # ../MIRRORS
CLEAN_FILES: $(BUILD_SOURCES)
touch $(BUILD_SOURCES)
@@ -47,72 +48,180 @@ include.texi: ../configure.in
grep "MYSQL_TCP_PORT_DEFAULT=" ../configure.in | \
sed -e 's;MYSQL_TCP_PORT_DEFAULT=;;' >> $@
+
+#
+# English Manual
+#
+
+# GNU Info
mysql.info: manual.texi include.texi
cd $(srcdir) && $(MAKEINFO) --no-split -I $(srcdir) $<
+# Plain Text
manual.txt: manual.texi include.texi
cd $(srcdir) && \
$(MAKEINFO) -I $(srcdir) --no-headers --no-split --output $@ $<
+# HTML, all in one file
manual.html: manual.texi include.texi $(srcdir)/Support/texi2html
cd $(srcdir) && @PERL@ $(srcdir)/Support/texi2html $(TEXI2HTML_FLAGS) $<
-
manual_toc.html: manual.html
-
-# Fix: add --output-comment with some interesting info?
-# Fix: @image worked with a older version of pdftex.
-# Note: @image will work if we first convert all images to pdf ...
-# is that worth it?
-# Comment: We need to run pdftex 2 times to get the cross references right.
+# PDF, Portable Document Format
manual.pdf: manual.texi
- cat manual.texi | sed -e 's|@image{[^}]*} *||g' > manual-tmp.texi
+ sed -e 's|@image{[^}]*} *||g' <$< >manual-tmp.texi
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
- mv manual-tmp.pdf manual.pdf
+ mv manual-tmp.pdf $@
rm -f manual-tmp.*
touch $@
-# Target to produce NuSphere Manual
-nusphere.pdf: manual.texi
- cat manual.texi \
- | sed -e 's/@example/@smallexample/g' \
- -e 's/@end example/@end smallexample/g' \
- -e 's/@c ifnusphere //g' \
- -e 's|@image{[^}]*} *||g' \
- > manual-tmp.texi
+# XML, DocBook 4.0
+mysql.xml: manual.texi include.texi
+ $(MAKEINFO) --force --no-ifinfo --docbook $<
+ mv $@ mysql-tmp.xml
+ Support/docbook-fixup.pl <mysql-tmp.xml >$@
+ rm -f mysql-tmp.xml
+
+# Postscript, A4 Paper
+manual_a4.ps: manual.texi include.texi
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
+ $(TEXI2DVI) --batch --texinfo --quiet '@afourpaper' $<
+ $(DVIPS) -t a4 manual.dvi -o $@
+ touch $@
+
+# Postscript, US Letter Paper
+manual_letter.ps: manual.texi include.texi
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
+ $(TEXI2DVI) --batch $<
+ $(DVIPS) -t letter manual.dvi -o $@
+ touch $@
+
+
+#
+# German Manual
+#
+
+# GNU Info
+mysql.de.info: manual.de.texi include.texi
+ cd $(srcdir) && $(MAKEINFO) --no-split -I $(srcdir) $<
+
+# Plain Text
+manual.de.txt: manual.de.texi include.texi
+ cd $(srcdir) && \
+ $(MAKEINFO) -I $(srcdir) --no-headers --no-split --output $@ $<
+
+# HTML, all in one file
+manual.de.html: manual.de.texi include.texi $(srcdir)/Support/texi2html
+ cd $(srcdir) && @PERL@ $(srcdir)/Support/texi2html $(TEXI2HTML_FLAGS) $<
+manual_toc.de.html: manual.html
+
+# PDF, Portable Document Format
+manual.de.pdf: manual.de.texi
+ sed -e 's|@image{[^}]*} *||g' <$< >manual-tmp.texi
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
- mv manual-tmp.pdf nusphere.pdf
+ mv manual-tmp.pdf $@
rm -f manual-tmp.*
touch $@
-# Target to produce DocBook XML
-mysql.xml: manual.texi include.texi
- $(MAKEINFO) --force --no-ifinfo --docbook manual.texi
+# XML, DocBook 4.0
+mysql.de.xml: manual.de.texi include.texi
+ $(MAKEINFO) --force --no-ifinfo --docbook $<
+ mv $@ mysql-tmp.xml
+ Support/docbook-fixup.pl <mysql-tmp.xml >$@
+ rm -f mysql-tmp.xml
-# The texi2dvi gives a lot of harmless errors. Just ignore them unless
-# you want to help with the typesetting part.
-# This is the European papersize version
-manual_a4.ps: manual.texi include.texi
+# Postscript, A4 Paper
+manual_a4.de.ps: manual.de.texi include.texi
TEXINPUTS=$(srcdir):$$TEXINPUTS \
MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
$(TEXI2DVI) --batch --texinfo --quiet '@afourpaper' $<
- $(DVIPS) -t a4 manual.dvi -o $@
+ $(DVIPS) -t a4 manual.de.dvi -o $@
touch $@
-# This is the American papersize version
-manual_letter.ps: manual.texi include.texi
+# Postscript, US Letter Paper
+manual_letter.de.ps: manual.de.texi include.texi
TEXINPUTS=$(srcdir):$$TEXINPUTS \
MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
$(TEXI2DVI) --batch $<
- $(DVIPS) -t letter manual.dvi -o $@
+ $(DVIPS) -t letter manual.de.dvi -o $@
+ touch $@
+
+
+#
+# Internals Manual
+#
+
+# GNU Info
+internals.info: internals.texi include.texi
+ cd $(srcdir) && $(MAKEINFO) --no-split -I $(srcdir) $<
+
+# Plain Text
+internals.txt: internals.texi include.texi
+ cd $(srcdir) && \
+ $(MAKEINFO) -I $(srcdir) --no-headers --no-split --output $@ $<
+
+# HTML, all in one file
+internals.html: internals.texi include.texi $(srcdir)/Support/texi2html
+ cd $(srcdir) && @PERL@ $(srcdir)/Support/texi2html $(TEXI2HTML_FLAGS) $<
+internals_toc.html: internals.html
+
+# PDF, Portable Document Format
+internals.pdf: internals.texi
+ sed -e 's|@image{[^}]*} *||g' <$< >internals-tmp.texi
+ pdftex --interaction=nonstopmode internals-tmp.texi
+ texindex internals-tmp.??
+ pdftex --interaction=nonstopmode internals-tmp.texi
+ texindex internals-tmp.??
+ pdftex --interaction=nonstopmode internals-tmp.texi
+ mv internals-tmp.pdf $@
+ rm -f internals-tmp.*
+ touch $@
+
+# Postscript, A4 Paper
+internals_a4.ps: internals.texi include.texi
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
+ $(TEXI2DVI) --batch --texinfo --quiet '@afourpaper' $<
+ $(DVIPS) -t a4 internals.dvi -o $@
+ touch $@
+
+# Postscript, US Letter Paper
+internals_letter.ps: internals.texi include.texi
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
+ $(TEXI2DVI) --batch $<
+ $(DVIPS) -t letter internals.dvi -o $@
+ touch $@
+
+
+#
+# Miscellaneous
+#
+
+# Target to produce NuSphere Manual
+nusphere.pdf: manual.texi
+ sed -e 's/@example/@smallexample/g' \
+ -e 's/@end example/@end smallexample/g' \
+ -e 's/@c ifnusphere //g' \
+ -e 's|@image{[^}]*} *||g' \
+ <$< >manual-tmp.texi
+ pdftex --interaction=nonstopmode manual-tmp.texi
+ texindex manual-tmp.??
+ pdftex --interaction=nonstopmode manual-tmp.texi
+ texindex manual-tmp.??
+ pdftex --interaction=nonstopmode manual-tmp.texi
+ mv manual-tmp.pdf $@
+ rm -f manual-tmp.*
touch $@
# Include images for the manual in the distribution
@@ -131,7 +240,7 @@ dist-hook:
GT = $(srcdir)/Support/generate-text-files.pl
../INSTALL-SOURCE: mysql.info $(GT)
- perl -w $(GT) mysql.info "Installing" "Compatibility" > $@
+ perl -w $(GT) mysql.info "Installing" "Tutorial" > $@
# We put the description for the binary installation here so that
# people who download source wont have to see it. It is moved up to
@@ -145,8 +254,8 @@ INSTALL-BINARY: mysql.info $(GT)
../COPYING.LIB: mysql.info $(GT)
perl -w $(GT) mysql.info "LGPL license" "Function Index" > $@
-../MIRRORS: manual.texi $(srcdir)/Support/generate-mirror-listing.pl
- perl -w $(srcdir)/Support/generate-mirror-listing.pl manual.texi > $@
+#../MIRRORS: manual.texi $(srcdir)/Support/generate-mirror-listing.pl
+# perl -w $(srcdir)/Support/generate-mirror-listing.pl manual.texi > $@
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/Docs/ManualStyleGuidelines.wiki b/Docs/ManualStyleGuidelines.wiki
new file mode 100644
index 00000000000..9d2a869ba1a
--- /dev/null
+++ b/Docs/ManualStyleGuidelines.wiki
@@ -0,0 +1,282 @@
+OriginalAuthor: Paul DuBois
+
+!!! ManualStyleGuidelines
+
+''Version 1.1''
+
+!! Revision History
+
+* 2002-05-17 ArjenLentz - Version 1.0, Posted to Wiki
+* 2002-06-03 ArjenLentz - Version 1.1, updates.
+
+!! MySQL Manual Style Guidelines
+
+Paul DuBois <paul@snake.net>
+
+The following list of guidelines contains items that I've been jotting
+down over time as style questions have come up in relation to the
+MySQL manual. I wouldn't say they're exactly "official", but they
+do reflect current working practice. Arjen asked me to post this
+on the list some time ago so that it can be discussed with a view
+to adding it (or something like it) to the source tree. So here it is!
+
+Present in the mysql-4.0 source tree: Docs/ManualStyleGuidelines.wiki
+
+
+The manual is written in UK English, not American English. This means:
+
+ colour, not color
+ behaviour, not behavior
+ authorise, not authorize
+ optimise, not optimize
+ etc.
+
+Write MySQL, not @strong{MySQL} (the manual used to use the latter, but no
+more).
+
+Write Unix, not UNIX.
+
+Use uppercase for SQL keywords, functions names, etc., when writing
+SQL statement examples.
+
+To write a list of items, add commas after all items preceding the last one:
+ Correct: Features, products, and services
+ Incorrect: Features, products and services
+
+How to pluralize keywords that are enclosed in @code:
+ Correct: @code{SELECT}s
+ Incorrect: @code{SELECTs} or @code{SELECT}'s or @code{SELECT}:s
+
+Use "its" and "it's" correctly. These words are exceptions to
+the normal use of "'s" to indicate possession:
+
+it's = it is (e.g., "one of the strengths of MySQL is that it's fast")
+its = possession (e.g., "MySQL is fast, which is one of its strengths")
+
+"a lot" is two words. "alot" is rebarbative.
+
+Write lowercase, not lower case
+
+Write uppercase, not upper case
+
+Write lettercase, not letter case
+
+Write "web site" (two words), not "website", and "web page" rather
+than "webpage".
+
+The word "data" is problematic. It's commonly used both in plural and in
+singular form. The manual uses it as plural, which means you use "data are"
+rather than "data is". It's unfortunate that no matter which form we use, it
+will look incorrect to some people. But we can at least be internally
+consistent.
+(Paul: I think that the O'Reilly proofread might have caught one or two of these; could you please pick up on these but don't change them back straight away until the book is finished? Thanks; Arjen).
+
+Write "press Enter", not "hit Return" or "hit Enter".
+
+When reproducing program output, reproduce it exactly, even if it contains
+typos. Don't "fix" it. (If the output is produced by a MySQL program, then
+fix the source for the program to write the output correctly without the
+typo, then update the manual to match.)
+
+Use "okay" rather than "ok" or "Ok" or "OK" in sentences. Exceptions:
+* When describing instructions for a GUI with buttons that say "OK", then use "OK". That is, use the label that the GUI uses.
+* When showing the output from a program, show the output exactly; don't change "ok" to "okay", etc.
+
+Write "Open Source" (inside @code{}), not "open source".
+
+To put something in quotes, do it ``like this,'' not "like this"
+or 'like this.' In the latter two cases, the quotes will come
+out looking rotten in printed formats.
+Exception: quotes in code examples should be written using whatever
+contention the program language requires.
+
+Table types should be written using @code{}; write @code{MyISAM}, not
+MyISAM.
+
+When possible, use table names that are singular, not plural.
+For example, use "item" rather than "items", or "person" rather than
+"people". Sometimes you can add "_list" (as in "item_list") to make it
+more clear that the name refers to a collection of items.
+
+ Some commonly occurring misspelling:
+
+ Correct Incorrect
+ ---------------------------
+ publicly publically
+ statically staticly
+ dynamically dynamicly
+ automatically automaticly
+
+There is no hyphen after "ly" words. Write statically linked, not
+statically-linked.
+
+To refer to ASCII codes, use ASCII n, not ASCII(n), unless you're
+referring to the ASCII() function, which case you use @code{ASCII()}.
+
+ ASCII 13 indicates ASCII character code 13
+ @code{ASCII(13)} indicates a function call
+
+backup is a noun or adjective (as in "a backup file"), back up is a verb
+(as in "to back up a database")
+rollback is a noun or adjective (as in "a rollback operation"), roll back
+is a verb (as in "roll back a transaction")
+
+core dump is a noun or a verb (as in "a core dump file" or "a program
+core dumps when it fails"). In the latter case, however, it's better say
+say "a program dumps core when it fails").
+
+Write character set names in @code{}, e.g., @code{latin1}, @code{win1251}.
+
+To prevent problems with various output formats, there should be no link
+titles in a @uref{}. So @uref{url} is allowed, @uref{url,blabla} is not.
+ Use this format:
+ @uref{url} (WWW)
+ Not this format:
+ @uref{url, WWW}
+ Similarly for FTP sites.
+
+URLs ending in a domain name or directory should have a "/" at the end.
+(For example, the URLs for all mirror sites should be written that way.)
+
+Privilege names are written using @strong and lowercase, as in "the
+@strong{process} privilege". Column names in the grant tables are
+written using @code and the lettercase found in the table definition,
+as in "the @code{Process_priv} column".
+
+Write "e-mail", not "email". Exceptions are the @email{} construct, and
+the Email attribute name in X509 certificate strings.
+
+Write thread-safe, transaction-safe, replication-safe, not thread safe,
+transaction safe, replication safe.
+
+Write wildcard, not wild card or wild-card.
+
+Use "indexes", not "indices": Adding indexes to a table will improve the
+performance of SELECT statements.
+Exception: when returning to array elements, use "indices": The elements
+of the array may be accessed using numeric indices, where the index
+values ranges from 0 to n.
+
+Write "heavy-load production systems" (used as an adjective),
+but "...used under heavy load" (used on its own).
+
+Write PostScript, not Postscript.
+
+When writing a list like "A, B, and C", include a comma before the last and.
+
+Write case-sensitive and case-insensitive (hyphenated).
+
+Write runtime, not run time.
+
+Write backward-compatible, not backward compatible or backwards compatible.
+
+Write application-related, not application related.
+
+Write filesystem, not file system.
+
+Write file-size, not file size.
+
+Write datafile, not data file.
+
+Write power-start, not power start.
+
+Write percent, not per cent.
+
+Write "toward", "and onward", not "towards", "onwards".
+
+Write third-party, not third party.
+
+Write turnkey, not turn-key.
+
+Write "the Net" (capitalised) if referring to the Internet in that way.
+
+Write long-awaited, not long awaited.
+
+Write natural-language, not natural language.
+
+Write low-volume <something> (when used as an adjective).
+
+Write platform-dependent, not platform dependent.
+
+Write something like "mentioned previously" instead of "above", and "later in this section" instead of "below" when making such relative references in your text.
+
+Write "... shown here", not "... shown below".
+
+Write "following some", not "something [shown] below".
+
+Write high-priority <something> (when used as an adjective), not high priority.
+
+Write "whether", not "whether or not".
+
+Write hand-held, not hand held.
+
+Write rewriting, not re-writing.
+
+Write re-issue(ing), not reissue(ing).
+
+Write command-line, not command line.
+
+Write server-side, not server side.
+
+Write "<blabla> only", not "only <blabla>".
+
+Write floating-point, not floating point.
+
+Write heavy-duty, not heavy duty.
+
+Write online, not on-line.
+
+Write user-defined, not user defined.
+
+Write multi-user, not multi user.
+
+Write multi-thread(ed), not multithread(ed).
+
+Write memory-based, not memory based.
+
+Write long-time <something> (when used as an adjective), not long time.
+
+Write 32-bit, not 32 bit or 32 bits. (Same goes for 64-bit, of course! ;-)
+
+Write "different from [what] ...", not "different than ...".
+
+Write "@-e.g., " instead of " e.g. " in the middle of a sentence. (The @- will be turned into a dash, or &mdash; for DocBook output.)
+Following "e.g." by a comma, not a space or a colon.
+
+Write "@-" if you need to put a dash in a text, no surrounding spaces.
+
+Similar story for "for example" as for "e.g."
+
+Write CPU, not cpu (it's an acronym, not a word! ;-)
+
+Write "... uses ... CPU time", not "... uses ... CPU" (unless you're referring the processor itself.)
+
+If a (comment) is at the end of a sentence, start the comment with lowercase and put the . after the closing ), such as (like this).
+If a comment is separate, start with uppercase and put the . inside the closing ). (Like this.)
+
+Write "something cannot do something", not "something can not something".
+
+Write "otherwise, ..." (with the comma) at the start of a sentence.
+
+Paul, could you please check "honoring"... is this proper British English? Thanks, Arjen.
+
+Write "byte-swapping", not "byte swapping".
+
+Write "Note:", not "NOTE:". And then continue with lowercase, it is not the start of a new sentence.
+
+Write "single-CPU" and "multiple-CPU", not "single CPU" and "multiple CPU".
+
+Paul, I think we should also decide whether to write Version or version, and in what situation. I am not changing much now because there's lots of funny instances and I don't want to risk getting it wrong. Thanks, Arjen.
+
+After a semicolon, don't use uppercase. It is NOT the start of a new sentence!
+
+It's "unstable", not "instable". ;-)
+
+It's "full-text", not "fulltext".
+
+Logical NOT/OR/AND are operators, not functions, so they take operands, not arguments.
+
+It's NetWare, not Netware (as per Novell's trademark guidelines).
+
+It's deprecated, not depricated.
+
diff --git a/Docs/Support/colspec-fix.pl b/Docs/Support/colspec-fix.pl
new file mode 100755
index 00000000000..6c64edd1441
--- /dev/null
+++ b/Docs/Support/colspec-fix.pl
@@ -0,0 +1,78 @@
+#!/usr/bin/perl -w
+
+#
+# Script to rewrite colspecs from relative values to absolute values
+#
+
+# arjen 2002-03-14 append "cm" specifier to colwidth field.
+
+use strict;
+
+my $table_width = 12.75; # Specify the max width of the table in cm
+my $gutter_width = 0.55; # Specify the width of the gutters in cm
+
+my $str = join '', <>; # Push stdin (or file)
+
+$str =~ s{([\t ]*(<colspec colwidth=\".+?\" />\s*)+)}
+ {&rel2abs($1)}ges;
+
+print STDOUT $str;
+exit;
+
+#
+# Definitions for helper sub-routines
+#
+
+sub msg {
+ print STDERR shift, "\n";
+}
+
+sub rel2abs {
+ my $str = shift;
+ my $colnum = 1;
+
+ my @widths = ();
+ my $total = 0;
+ my $output = '';
+
+ my $gutters;
+ my $content_width;
+ my $total_width;
+ my @num_cache;
+
+ $str =~ /^(\s+)/;
+ my $ws = $1;
+
+ while ($str =~ m/<colspec colwidth="(\d+)\*" \/>/g) {
+ $total += $1;
+ push @widths, $1;
+ }
+
+ msg("!!! WARNING: Total Percent > 100%: $total%") if $total > 100;
+
+ if (! $total) {
+ die 'Something bad has happened - the script believes that there are no columns';
+ }
+
+ $gutters = $#widths * $gutter_width;
+ $content_width = $table_width - $gutters;
+ # Don't forget that $#... is the last offset not the count
+
+ foreach (@widths) {
+ my $temp = sprintf ("%0.2f", $_/100 * $content_width);
+ $total_width += $temp;
+
+ if ($total_width > $content_width) {
+ $temp -= $total_width - $content_width;
+ msg("!!! WARNING: Column width reduced from " .
+ ($temp + ($total_width - $content_width)) . " to $temp !!!");
+ $total_width -= $total_width - $content_width;
+ }
+
+ $output .= $ws . '<colspec colnum="'. $colnum .'" colwidth="'. $temp .'cm" />' . "\n";
+ ++$colnum;
+ push @num_cache, $temp;
+ }
+
+ return $output . "\n$ws";
+}
diff --git a/Docs/Support/docbook-fixup.pl b/Docs/Support/docbook-fixup.pl
new file mode 100755
index 00000000000..f9934822f40
--- /dev/null
+++ b/Docs/Support/docbook-fixup.pl
@@ -0,0 +1,200 @@
+#!/usr/bin/perl -w
+
+# Fix the output of `makeinfo --docbook` version 4.0c
+# Convert the broken docbook output to well-formed XML that conforms to the O'Reilly idiom
+# See code for detailed comments
+# Authors: Arjen Lentz and Zak Greant (original code by Jeremy Cole)
+
+use strict;
+
+my $data = '';
+my @apx = ();
+my $apx = '';
+my @nodes = ();
+my $nodes = '';
+
+msg ("-- Post-processing `makeinfo --docbook` output --");
+msg ("** Written to work with makeinfo version 4.0c **\n");
+
+msg ("Discarding DTD - not required by subsequent scripts");
+# <> is a magic filehandle - either reading lines from stdin or from file(s) specified on the command line
+<>;
+
+msg ("Create an XML PI with ISO-8859-1 character encoding");
+$data = "<?xml version='1.0' encoding='ISO-8859-1'?>";
+
+msg ("Get the rest of the data");
+$data = $data . join "", <>;
+
+msg ("Add missing <bookinfo> and <abstract> opening tags");
+# Note the absence of the g (global) pattern modified. This situation can only happen once.
+# ...as soon as we find the first instance, we can stop looking.
+$data =~ s/<book lang="en">/<book lang="en"><bookinfo><abstract>/;
+
+
+# arjen 2002-05-01
+msg ("Processing docbook-prefix special strings");
+$data =~ s/FIXUPmdashFIXUP/\&mdash\;/g;
+
+$data =~ s/FIXUPdoubledashFIXUP/--/g;
+
+$data =~ s/FIXUPstrongFIXUP/<emphasis\ role\=bold>/g;
+$data =~ s/FIXUPendstrongFIXUP/<\/emphasis>/g;
+
+$data =~ s/FIXUPemphFIXUP/<emphasis>/g;
+$data =~ s/FIXUPendemphFIXUP/<\/emphasis>/g;
+
+$data =~ s/FIXUPfileFIXUP/<filename>/g;
+$data =~ s/FIXUPendfileFIXUP/<\/filename>/g;
+
+$data =~ s/FIXUPsampFIXUP/<literal>/g;
+$data =~ s/FIXUPendsampFIXUP/<\/literal>/g;
+
+
+msg ("Removing mailto: from email addresses...");
+$data =~ s/mailto://g;
+
+msg ("Removing INFORMALFIGURE...");
+$data =~ s{<informalfigure>.+?</informalfigure>}
+ {}gs;
+
+msg ("Convert ampersand to XML escape sequence...");
+$data =~ s/&(?!\w+;)/&amp;/g;
+
+# arjen 2002-05-01
+msg ("Changing (TM) to XML escape sequence...");
+$data =~ s/MySQL \(TM\)/MySQL&trade;/g;
+$data =~ s{<command>TM</command>}
+ {&trade;}g;
+
+# arjen 2002-05-01
+msg ("Changing ' -- ' to XML escape sequence...");
+$data =~ s/ -- /&mdash;/g;
+
+msg ("Changing @@ to @...");
+$data =~ s/@@/@/g;
+
+msg ("Rework references of the notation '<n>'");
+# Need to talk to Arjen about what the <n> bits are for
+$data =~ s/<(\d)>/[$1]/g;
+
+msg ("Changing '_' to '-' in references...");
+$data =~ s{((?:id|linkend)=\".+?\")}
+ {&underscore2hyphen($1)}gex;
+
+msg ("Changing ULINK to SYSTEMITEM...");
+$data =~ s{<ulink url=\"(.+?)\">\s*</ulink>}
+ {<systemitem role=\"url\">$1</systemitem>}gs;
+
+msg ("Adding PARA inside ENTRY...");
+$data =~ s{<entry>(.*?)</entry>}
+ {<entry><para>$1</para></entry>}gs;
+
+msg ("Fixing spacing problem with titles...");
+$data =~ s{(</\w+>)(\w{2,})}
+ {$1 $2}gs;
+
+msg ("Adding closing / to XREF and COLSPEC tags...");
+$data =~ s{<(xref|colspec) (.+?)>}
+ {<$1 $2 />}gs;
+
+# arjen 2002-04-26
+msg ("Removing separate target titles from LINKs and make them XREFs...");
+$data =~ s{<link (linkend=.+?)>.+?</link>}
+ {<xref $1 />}gs;
+
+# Probably need to strip these
+msg ('Adding "See " to XREFs that used to be @xref...');
+$data =~ s{([.'!)])\s*<xref }
+ {$1 See <xref }gs;
+
+msg ('Adding "see " to (XREFs) that used to be (@pxref)...');
+$data =~ s{([([,;])(\s*)<xref }
+ {$1$2see <xref }gs;
+
+msg ("Making first row in table THEAD...");
+$data =~ s{( *)<tbody>(\s*<row>.+?</row>)}
+ {$1<thead>$2\n$1</thead>\n$1<tbody>}gs;
+
+msg ("Removing EMPHASIS inside THEAD...");
+$data =~ s{<thead>(.+?)</thead>}
+ {"<thead>".&strip_tag($1, 'emphasis')."</thead>"}gsex;
+
+msg ("Removing empty PARA...");
+$data =~ s{<para>\s*</para>}
+ {}gs;
+
+msg ("Removing lf before /PARA in ENTRY...");
+$data =~ s{\n(</para></entry>)}
+ {$1}gs;
+
+msg ("Removing whitespace before /PARA if not on separate line...");
+$data =~ s{(\S+)[\t ]+</para>}
+ {$1</para>}g;
+
+msg ("Removing PARA around INDEXTERM if no text in PARA...");
+$data =~ s{<para>((?:<indexterm role=\"[^"]+\">(?:<(primary|secondary)>[^>]+</\2>)+?</indexterm>)+?)\s*</para>}
+ {$1}gs;
+
+@apx = ("Users", "MySQL Testimonials", "News", "GPL-license", "LGPL-license");
+
+foreach $apx (@apx) {
+ msg ("Removing appendix $apx...");
+ $data =~ s{<appendix id=\"$apx\">(.+?)</appendix>}
+ {}gs;
+
+ # Skip to next appendix regex if the regex did not match anything
+ next unless (defined $&);
+
+ msg ("...Building list of removed nodes...");
+
+ # Split the last bracketed regex match into an array
+ # Extract the node names from the tags and push them into an array
+ foreach (split "\n", $&) {
+ push @nodes, $1 if /<\w+ id=\"(.+?)\">/
+ }
+}
+
+# 2002-02-22 arjen@mysql.com (added fix " /" to end of regex, to make it match)
+msg ("Fixing references to removed nodes...");
+# Merge the list of node names into a set of regex alternations
+$nodes = join "|", @nodes;
+
+# Find all references to removed nodes and convert them to absolute URLs
+$data =~ s{<\w+ linkend="($nodes)" />}
+ {&xref2link($1)}ges;
+
+print STDOUT $data;
+exit;
+
+#
+# Definitions for helper sub-routines
+#
+
+sub msg {
+ print STDERR "docbook-fixup:", shift, "\n";
+}
+
+sub strip_tag($$) {
+ (my $str, my $tag) = @_;
+ $str =~ s{<$tag>(.+?)</$tag>}{$1}gs;
+ return $str;
+}
+
+sub underscore2hyphen($) {
+ my $str = shift;
+ $str =~ tr/_/-/;
+ return $str;
+}
+
+sub xref2link {
+ my $ref = shift;
+ $ref =~ tr/ /_/;
+ $ref =~ s{^((.)(.).+)$}{$2/$3/$1.html};
+ return "http://www.mysql.com/doc/" . $ref;
+}
+
+# We might need to encode the high-bit characters to ensure proper representation
+# msg ("Converting high-bit characters to entities");
+# $data =~ s/([\200-\400])/&get_entity($1)>/gs;
+# There is no get_entity function yet - no point writing it til we need it :)
diff --git a/Docs/Support/docbook-prefix.pl b/Docs/Support/docbook-prefix.pl
new file mode 100755
index 00000000000..e76d84dbfe0
--- /dev/null
+++ b/Docs/Support/docbook-prefix.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl -w
+
+# Preprocess the input of `makeinfo --docbook` version 4.0c
+# Authors: Arjen Lentz and Zak Greant (started by arjen 2002-05-01)
+
+use strict;
+
+my $data = '';
+
+msg ("-- Pre-processing `makeinfo --docbook` input --");
+msg ("** Written to work with makeinfo version 4.0c **\n");
+
+# <> is a magic filehandle - either reading lines from stdin or from file(s) specified on the command line
+msg ("Get the data");
+$data = join "", <>;
+
+msg ("Replacing '\@-' with FIXUPmdashFIXUP");
+$data =~ s/\@-/FIXUPmdashFIXUP/g;
+
+msg ("Replacing '--' with FIXUPdoubledashFIXUP");
+$data =~ s/--/FIXUPdoubledashFIXUP/g;
+
+msg ("Turning \@strong{} into LITERAL blocks");
+$data =~ s/\@strong\{(.*?)\}/FIXUPstrongFIXUP$1FIXUPendstrongFIXUP/gs;
+
+msg ("Turning \@emph{} into LITERAL blocks");
+$data =~ s/\@emph\{(.*?)\}/FIXUPemphFIXUP$1FIXUPendemphFIXUP/gs;
+
+msg ("Turning \@file{} into LITERAL blocks");
+$data =~ s/\@file\{(.*?)\}/FIXUPfileFIXUP$1FIXUPendfileFIXUP/gs;
+
+msg ("Turning \@samp{} into LITERAL blocks");
+$data =~ s/\@samp\{\@\{\}/FIXUPsampFIXUP\@\{FIXUPendsampFIXUP/g;
+$data =~ s/\@samp\{\@\}\}/FIXUPsampFIXUP\@\}FIXUPendsampFIXUP/g;
+$data =~ s/\@samp\{\@\{n\@\}\}/FIXUPsampFIXUP\@\{n\@\}FIXUPendsampFIXUP/g;
+$data =~ s/\@samp\{(.*?)\}/FIXUPsampFIXUP$1FIXUPendsampFIXUP/gs;
+
+
+msg ("Write the data");
+print STDOUT $data;
+exit;
+
+#
+# Definitions for helper sub-routines
+#
+
+sub msg {
+ print STDERR "docbook-prefix: ", shift, "\n";
+}
+
diff --git a/Docs/Support/docbook-split b/Docs/Support/docbook-split
new file mode 100755
index 00000000000..eafb437efe4
--- /dev/null
+++ b/Docs/Support/docbook-split
@@ -0,0 +1,70 @@
+#! /usr/bin/perl -w
+# O'Reilly's Perl script to chop mysql.xml into separate ch/apps/index files.
+# The indexes are actually not used, they're created straight from the xrefs.
+# Breaks the MySQL reference manual into chapters, appendices, and indexes.
+
+use strict;
+
+my $app_letter = "a"; # Start appendix letters at "a"
+my $chap_num = 1; # Start chapter numbers at one (there is no preface)
+my $directory = "mysql_refman_" . time;
+my $ext = ".xml";
+my $line = "";
+my $output_name = "";
+my $start_text = "";
+
+mkdir $directory unless -d $directory;
+
+while (defined $line) {
+ if ($line =~ /(<chapter.+)/i ) {
+ $start_text = $1;
+ $output_name = sprintf("ch%02d%s", $chap_num, $ext);
+ ++$chap_num;
+ &process_file("chapter");
+ }
+ elsif ($line =~ /(<appendix.+)/i ) {
+ $start_text = $1 ;
+ $output_name = "app$app_letter$ext";
+ ++$app_letter;
+ &process_file("appendix");
+ }
+ elsif ($line =~ /(<index\s+id=")(.*?)(">.*)/i ) {
+ $start_text = $1 . $2 . $3;
+ $output_name = lc($2) . $ext;
+ &process_file("index");
+ }
+ else {
+ # Skip junk in between chapters, appendices and indexes.
+ $line = <>;
+ }
+}
+
+sub process_file {
+ my $marker = shift;
+ my $path = "$directory/$output_name";
+
+ open (OUTPUT_FILE, ">$path") or die "Cannot open $path";
+
+ print STDERR "Creating $path\n";
+
+ # Print out XML PI
+ print OUTPUT_FILE "<?xml version='1.0' encoding='ISO-8859-1'?>\n";
+
+ # Print whatever happened to appear at the end of the previous chapter.
+ print OUTPUT_FILE "$start_text\n" if $start_text;
+
+ while (defined $line) {
+ $line = <>;
+
+ # Note: Anything after the terminating marker is lost, just like
+ # lines in between chapters.
+ if ($line =~ /(.*<\/\s*$marker\s*>)/i ) {
+ print OUTPUT_FILE "$1\n" if $1;
+ close OUTPUT_FILE;
+ return;
+ }
+ print OUTPUT_FILE $line;
+ }
+}
+
+exit 0;
diff --git a/Docs/Support/generate-flag-images b/Docs/Support/generate-flag-images
index 903c610d4bc..21140388012 100755
--- a/Docs/Support/generate-flag-images
+++ b/Docs/Support/generate-flag-images
@@ -1,37 +1,31 @@
#!/bin/sh
-tmp=/tmp/temp-pic.pnm
-
-all="argentina austria czech-republic germany great-britain hungary israel
-italy russia portugal sweden canada usa south-korea japan taiwan australia
-romania denmark france estonia poland singapore bulgaria south-africa
-netherlands chile ukraine greece finland switzerland croatia china
-brazil spain iceland ireland denmark"
-
-new=""
+flags=`grep @image mirrors.texi | cut -d" " -f1 | cut -d/ -f2 | tr -d "}" | sort | uniq`
set -x
-cd Flags
-
-# for c in $all; do cp empty.png $c.pdf; done; exit
+cd Flags
-for c in $new
+for c in $flags
do
- # For HTML version
- giftopnm ../Raw-Flags/$c.gif | \
- pnmscale -xsize 30 > $tmp
- pnmpaste $tmp 1 1 ../Images/flag-background.pnm > $c.pnm
- rm -f $tmp
- # For web version
+ # For PNM, to be used later
+ giftopnm ../Raw-Flags/$c.gif | pnmscale -xsize 30 > $c-tmp.pnm
+ pnmpaste $c-tmp.pnm 1 1 ../Images/flag-background.pnm > $c.pnm
+ rm -f $c-tmp.pnm
+
+ # For GIF version
ppmtogif $c.pnm > $c.gif
# or cjpeg -optimize -quality 70 -outfile $c.jpg
- # For PDF version (this coredumps. use empty file until fixed)
- # pnmtopng -verbose $c.pnm > $c.png
- cp ../Images/empty.png $c.pdf
- # For TeX version
- giftopnm ../Raw-Flags/$c.gif | \
- pnmscale -xsize 30 | \
- pnmtops -noturn > $c.eps
+
+ # For EPS version
+ pnmtops -noturn $c.pnm > $c.eps
+
+ # For PDF version
+ ps2pdf $c.eps $c.pdf
+
# For text version
echo -n "" > $c.txt
+
+ # PNM isn't really needed
+ rm -f $c.pnm
+
done
diff --git a/Docs/Support/make-docbook b/Docs/Support/make-docbook
new file mode 100755
index 00000000000..93dbc56c0f8
--- /dev/null
+++ b/Docs/Support/make-docbook
@@ -0,0 +1,29 @@
+#!/bin/sh
+# 2002-01-30 arjen@mysql.com
+# Use this to create mysql.xml (the DocBook XML format output of manual.texi)
+# Requires makeinfo 4.0c
+
+#create include.texi with version/port #
+ echo "@c This file is autogenerated by the Makefile" > include.texi
+ echo -n "@set mysql_version " >> include.texi
+# grep "AM_INIT_AUTOMAKE(mysql, " ../configure.in | \
+# sed -e 's;AM_INIT_AUTOMAKE(mysql, ;;' -e 's;);;' >> include.texi
+# 2002-04-26 arjen - the below just picks #.# instead of #.#.#-alpha
+# (code by mwagner - tnx)
+ grep "AM_INIT_AUTOMAKE(mysql, " ../configure.in | \
+ perl -p -e 's/AM_INIT_AUTOMAKE\(mysql,\s(\d+\.\d+)\..+/$1/' >> include.texi
+ echo -n "@set default_port " >> include.texi
+ grep "MYSQL_TCP_PORT_DEFAULT=" ../configure.in | \
+ sed -e 's;MYSQL_TCP_PORT_DEFAULT=;;' >> include.texi
+
+# produce DocBook XML
+ Support/docbook-prefix.pl < manual.texi |\
+ makeinfo --force --no-ifinfo --docbook -o - |\
+ Support/docbook-fixup.pl > mysql.xml
+
+ # See if the XML output is well-formed
+ xmlwf mysql.xml
+
+ # If all is well, keep processing
+ cat mysql.xml | Support/colspec-fix.pl | Support/docbook-split;
+
diff --git a/Docs/Support/test-make-manual-de b/Docs/Support/test-make-manual-de
new file mode 100755
index 00000000000..a5c03001bda
--- /dev/null
+++ b/Docs/Support/test-make-manual-de
@@ -0,0 +1,137 @@
+#!/bin/sh
+
+needed_flags=0
+needed_texi2html=0
+needed_texinfo_tex=0
+needed_include_texi=0
+
+if [ -z $BROWSER ]; then
+ BROWSER=netscape
+ echo "BROWSER not set, using $BROWSER"
+fi
+
+die ()
+{
+ echo
+ echo $1
+ cleanup
+ exit 1
+}
+
+cleanup ()
+{
+ echo "Cleaning up..."
+ if [ $needed_flags ]; then
+ bk clean Flags
+ fi
+
+ if [ $needed_texi2html ]; then
+ bk clean Support/texi2html
+ fi
+
+ if [ $needed_texinfo_tex ]; then
+ bk clean Support/texinfo.tex
+ fi
+
+ if [ $needed_include_texi ]; then
+ rm -f include.texi
+ fi
+
+ for file in \
+ manual.de.aux manual.de.cp manual.de.cps manual.de.dvi \
+ manual.de.fn manual.de.fns manual.de.ky manual.de.html \
+ manual.de.pg manual.de.toc manual.de.tp manual.de.vr \
+ mysql.de.info manual.de_toc.html ;
+ do
+ rm -f $file
+ done
+
+}
+
+
+if [ -e Flags/usa.txt ]; then
+ echo "Good, Flags are there."
+else
+ echo -n "Checking out Flags..."
+ bk edit Flags >/dev/null 2>&1
+ echo " Done."
+ needed_flags=1
+fi
+
+if [ -e Support/texi2html ]; then
+ echo "Good, texi2html is there."
+else
+ echo -n "Checking out texi2html..."
+ bk edit Support/texi2html >/dev/null 2>&1
+ echo " Done."
+ needed_texi2html=1
+fi
+
+if [ -e Support/texinfo.tex ]; then
+ echo "Good, texinfo.tex is there."
+else
+ echo -n "Checking out texinfo.tex..."
+ bk edit Support/texinfo.tex >/dev/null 2>&1
+ echo " Done."
+ needed_texinfo_tex=1
+fi
+
+if [ -e include.texi ]; then
+ echo "Good, include.texi is there."
+else
+ echo -n "Creating include.texi..."
+ bk edit ../configure.in >/dev/null 2>&1
+ echo "@c This file was generated by test-make-manual" > include.texi
+ echo -n "@set mysql_version " >> include.texi
+ grep "AM_INIT_AUTOMAKE(mysql, " ../configure.in | \
+ sed -e 's;AM_INIT_AUTOMAKE(mysql, ;;' -e 's;);;' >> include.texi
+ echo -n "@set default_port " >> include.texi
+ grep "MYSQL_TCP_PORT_DEFAULT=" ../configure.in | \
+ sed -e 's;MYSQL_TCP_PORT_DEFAULT=;;' >> include.texi
+ echo " Done."
+ needed_include_texi=1
+fi
+
+echo -n "Running makeinfo..."
+makeinfo --no-split -I . manual.de.texi
+
+if [ $? != 0 ]; then
+ die "Manual has errors - fix before you commit"
+else
+ echo " Looks good."
+fi
+
+
+echo -n "Running texi2html..."
+/usr/bin/perl ./Support/texi2html -iso -number manual.de.texi
+
+if [ $? != 0 ]; then
+ die "Manual has errors - fix before you commit"
+else
+ echo " Looks good."
+fi
+
+
+echo -n "Running texi2dvi..."
+texi2dvi --batch manual.de.texi > texi2dvi.out
+
+if [ $? != 0 ]; then
+ die "Manual has errors - fix before you commit (saved in texi2dvi.out)"
+else
+ rm texi2dvi.out
+ echo " Looks good."
+fi
+
+echo
+echo
+echo "Please examine your modifications in \`manual.de.html'."
+echo
+echo "If you would like to use a different browser, set the 'BROWSER' environment"
+echo "variable."
+echo
+
+$BROWSER file:`pwd`/manual.de_toc.html
+
+echo "-- Press Enter to Continue --"
+read junk
+cleanup
diff --git a/Docs/Support/trivial-makeinfo-4.0c.patch b/Docs/Support/trivial-makeinfo-4.0c.patch
new file mode 100644
index 00000000000..b2446c0e8bb
--- /dev/null
+++ b/Docs/Support/trivial-makeinfo-4.0c.patch
@@ -0,0 +1,11 @@
+--- alt-multi.c Sun Apr 14 10:03:19 2002
++++ multi.c Tue May 22 20:52:33 2001
+@@ -287,7 +287,7 @@
+ && *params != '\n' && *params != '@')
+ params++;
+ setup_output_environment (i,
+- (int) ((columnfrac * 100.00) + 0.49));
++ (int) (columnfrac * (fill_column - current_indent) + .5));
+ }
+ }
+
diff --git a/Docs/Support/update-reserved-words.pl b/Docs/Support/update-reserved-words.pl
new file mode 100755
index 00000000000..2920e083c9c
--- /dev/null
+++ b/Docs/Support/update-reserved-words.pl
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+
+# Based on a Emacs macro by david@mysql.com
+# Implemented in Perl by jeremy@mysql.com
+# 2001-11-20 Fixups by arjen@mysql.com, 2 keywords and 15 synonyms were missing
+# 2001-12-07 Fixup by arjen@mysql.com, add column headings for multitable.
+# 2002-05-01 Fixup by arjen@mysql.com, use 3 columns instead of 4.
+# 2002-05-03 Fixup by arjen@mysql.com, fill last row to full # of columns.
+# 2002-06-14 Fixup by arjen@mysql.com, Issue a "bk edit manual.texi".
+
+print STDERR "Scanning lex.h for symbols..\n";
+open LEX, "<../sql/lex.h";
+while($line = <LEX>) {
+ if($line =~ /\{\s*\"([A-Z_]+)\"/) {
+ $words{$1} = $1;
+ } elsif($line =~ /sql_functions/) {
+ last;
+ };
+};
+close LEX;
+
+print STDERR "Scanning sql_yacc.yy for non-reserved words...\n";
+open YACC, "<../sql/sql_yacc.yy";
+while(<YACC> !~ /^keyword:/) {};
+while(($line = <YACC>) =~ /[\s|]+([A-Z_]+)/) {
+ $keyword = $1;
+ $keyword =~ s/_SYM//;
+ delete $words{$keyword};
+};
+close YACC;
+
+
+print STDERR "Copying reserved words to an array...\n";
+foreach(keys %words) { push @words, $words{$_}; };
+
+print STDERR "Sorting array...\n";
+@words = sort @words;
+
+printf STDERR "There are %i reserved words.\n", scalar @words;
+
+@pre = ("\@item", " \@tab", " \@tab");
+
+$list = "";
+for($i=0; $word = shift(@words); $i++) {
+ $list .= sprintf "%s %s\n", $pre[$i%3], "\@code\{$word\}";
+}
+# Fill last row to full # of columns.
+for( ; $i%3; $i++) {
+ $list .= sprintf "%s\n", $pre[$i%3];
+}
+
+`bk edit manual.texi`;
+
+open OLD, "<manual.texi";
+open NEW, ">manual-tmp.texi";
+
+print STDERR "Copying beginning of manual.texi...\n";
+while(($line = <OLD>) !~ /START_OF_RESERVED_WORDS/) { print NEW $line; };
+print NEW "\@c START_OF_RESERVED_WORDS\n\n";
+printf NEW "\@c Reserved word list updated %s by %s.\n".
+ "\@c To regenerate, use Support/update-reserved-words.pl.\n\n",
+ &pretty_date, $ENV{USER};
+
+print STDERR "Inserting list of reserved words...\n";
+# Ensure the fractions add up to 100% otherwise it looks funny in print:
+print NEW "\@multitable \@columnfractions .33 .33 .34\n";
+print NEW "\@item \@strong{Word}\n \@tab \@strong{Word}\n \@tab \@strong{Word}\n";
+print NEW $list;
+print NEW "\@end multitable\n";
+print STDERR "Skipping over old list...\n";
+while(($line = <OLD>) !~ /END_OF_RESERVED_WORDS/) {};
+print NEW "\n\@c END_OF_RESERVED_WORDS\n";
+print STDERR "Copying end of manual.texi...\n";
+while($line = <OLD>) { print NEW $line; };
+
+close OLD;
+close NEW;
+
+print STDERR "Moving manual-tmp.texi to manual.texi...\n";
+unlink "manual.texi";
+rename "manual-tmp.texi", "manual.texi";
+
+print STDERR "Reserved word list updated successfully!\n";
+
+sub pretty_date {
+ @time = ($time = shift)?((localtime($time))[0..6]):((localtime)[0..6]);
+
+ ($sec, $min, $hour, $mday, $mon, $year, $wday) = @time;
+ $wday = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[$wday];
+ $mon = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mon];
+ $year += 1900;
+
+ $pretty = sprintf("%s %s %2i %02i:%02i:%02i %i",
+ $wday, $mon, $mday, $hour, $min, $sec, $year);
+
+ return $pretty;
+};
+
diff --git a/Docs/Support/xwf b/Docs/Support/xwf
new file mode 100755
index 00000000000..38f89774fe8
--- /dev/null
+++ b/Docs/Support/xwf
@@ -0,0 +1,67 @@
+#!/usr/bin/perl -w
+#
+# Parse document and report first syntax (well-formedness) error found.
+#
+
+use strict;
+use XML::Parser;
+use Getopt::Std;
+
+my %opts;
+getopts('e', \%opts);
+my $ENTREFS = exists( $opts{'e'} ); # flag: check ent refs
+
+my $parser = XML::Parser->new(
+ ErrorContext => 2, # output error context
+ );
+
+# get input from files
+if( @ARGV ) {
+ foreach( @ARGV ) {
+ my $file = $_;
+ unless( -r $file ) {
+ print STDERR "ERROR: Can't open '$file'.\n";
+ return;
+ }
+ my $input = '';
+ open( F, $file );
+ while( <F> ) { $input .= $_; }
+ close F;
+
+ # parse and report errors
+ if( &parse_string( $input )) {
+ print STDERR "ERROR in $file:\n$@\n";
+ } else {
+ print STDERR "'$file' is well-formed.\n";
+ }
+ }
+ print "All files checked.\n";
+
+# get input from STDIN
+} else {
+ my $input = "";
+ while( <STDIN> ) { $input .= $_; }
+ if( &parse_string( $input )) {
+ print STDERR "ERROR in stream:\n$@\n";
+ } else {
+ print STDERR "No syntax errors found in XML stream.\n";
+ }
+}
+
+
+# parse the string and return error message
+#
+# NOTE: By default, entity refs are not expanded. XML::Parser can be
+# told not to expand entity refs, but will still try to find
+# replacement text just in case, which we don't want. Therefore, we
+# need to do a stupid regexp replacement, removing entities from input.
+#
+sub parse_string {
+ my $string = shift;
+ unless( $ENTREFS ) {
+ $string =~ s/\&[^\s;]+;//g; # remove entity references
+ }
+ eval { $parser->parse( $string ); };
+ $@ =~ s/at \/.*?$//s; # remove module line number
+ return $@;
+}
diff --git a/Docs/bk.txt b/Docs/bk.txt
index cb2521b2b05..4c83c48aea6 100644
--- a/Docs/bk.txt
+++ b/Docs/bk.txt
@@ -55,5 +55,4 @@ Their developers, and especially the president of the company Larry McVoy really
like MySQL and are very anxious to help us. Make sure it is obvious that you
work for MySQL, of course. And, of course, do not bug them with little things
that you can figure out on your own or with my help - they were nice to offer us
-support, but we should not abuse it.
-
+support, but we should not abuse it. \ No newline at end of file
diff --git a/Docs/internals.texi b/Docs/internals.texi
index 2195b42d9a0..871e51c50bd 100644
--- a/Docs/internals.texi
+++ b/Docs/internals.texi
@@ -1,26 +1,30 @@
\input texinfo @c -*-texinfo-*-
-@c Copyright 1998 TcX AB, Detron HB and Monty Program KB
+@c Copyright 2002 MySQL AB, TcX AB, Detron HB and Monty Program KB
@c
@c %**start of header
@setfilename internals.info
+
@c We want the types in the same index
-@c @synindex tp fn cp
@synindex cp fn
+
@iftex
-@c Well this is normal in Europe. Maybe this should go into the include.texi?
@afourpaper
@end iftex
+
@c Get version and other info
@include include.texi
+
@ifclear tex-debug
@c This removes the black squares in the right margin
@finalout
@end ifclear
+
@c Set background for HTML
@set _body_tags BGCOLOR=#FFFFFF TEXT=#000000 LINK=#101090 VLINK=#7030B0
-@settitle @strong{MySQL} internals Manual for version @value{mysql_version}.
-@setchapternewpage off
+@settitle @strong{MySQL} Internals Manual for version @value{mysql_version}.
+@setchapternewpage odd
@paragraphindent 0
+
@c %**end of header
@ifinfo
@@ -35,67 +39,78 @@ END-INFO-DIR-ENTRY
@sp 10
@center @titlefont{@strong{MySQL} Internals Manual}
@sp 10
-@center Copyright @copyright{} 1998 TcX AB, Detron HB and Monty Program KB
+@center Copyright @copyright{} 1998-2002 MySQL AB
+@page
@end titlepage
-@node Top, Introduction, (dir), (dir)
+@node Top, caching, (dir), (dir)
@ifinfo
This is a manual about @strong{MySQL} internals.
@end ifinfo
@menu
+* caching:: How MySQL Handles Caching
+* flush tables:: How MySQL Handles @code{FLUSH TABLES}
+* filesort:: How MySQL Does Sorting (@code{filesort})
+* coding guidelines:: Coding Guidelines
+* mysys functions:: Functions In The @code{mysys} Library
+* DBUG:: DBUG Tags To Use
+* protocol:: MySQL Client/Server Protocol
+* Fulltext Search:: Fulltext Search in MySQL
@end menu
-@node caching,,,
-@chapter How MySQL handles caching
+
+@node caching, flush tables, Top, Top
+@chapter How MySQL Handles Caching
@strong{MySQL} has the following caches:
(Note that the some of the filename have a wrong spelling of cache. :)
-@itemize @bullet
+@table @strong
-@item Key cache
+@item Key Cache
A shared cache for all B-tree index blocks in the different NISAM
files. Uses hashing and reverse linked lists for quick caching of the
last used blocks and quick flushing of changed entries for a specific
table. (@file{mysys/mf_keycash.c})
-@item Record cache
+@item Record Cache
This is used for quick scanning of all records in a table.
(@file{mysys/mf_iocash.c} and @file{isam/_cash.c})
-@item Table cache
+@item Table Cache
This holds the last used tables. (@file{sql/sql_base.cc})
-@item Hostname cache
+@item Hostname Cache
For quick lookup (with reverse name resolving). Is a must when one has a
slow DNS.
(@file{sql/hostname.cc})
-@item Privilege cache
+@item Privilege Cache
To allow quick change between databases the last used privileges are
cached for each user/database combination.
(@file{sql/sql_acl.cc})
-@item Heap table cache
-Many use of GROUP BY or DISTINCT caches all found
-rows in a HEAP table (this is a very quick in-memory table with hash index)
+@item Heap Table Cache
+Many use of @code{GROUP BY} or @code{DISTINCT} caches all found rows in
+a @code{HEAP} table. (This is a very quick in-memory table with hash index.)
-@item Join row cache.
-For every full join in a SELECT statement (a full join here means there
-were no keys that one could use to find the next table in a list), the
-found rows are cached in a join cache. One SELECT query can use many
-join caches in the worst case.
-@end itemize
+@item Join Row Cache
+For every full join in a @code{SELECT} statement (a full join here means
+there were no keys that one could use to find the next table in a list),
+the found rows are cached in a join cache. One @code{SELECT} query can
+use many join caches in the worst case.
+@end table
-@node flush tables,,,
-@chapter How MySQL handles flush tables
+
+@node flush tables, filesort, caching, Top
+@chapter How MySQL Handles @code{FLUSH TABLES}
@itemize @bullet
@item
-Flush tables is handled in @code{sql/sql_base.cc::close_cached_tables()}.
+Flush tables is handled in @file{sql/sql_base.cc::close_cached_tables()}.
@item
The idea of flush tables is to force all tables to be closed. This
@@ -109,8 +124,8 @@ all tables)!
When one does a @code{FLUSH TABLES}, the variable @code{refresh_version}
will be incremented. Every time a thread releases a table it checks if
the refresh version of the table (updated at open) is the same as
-the current refresh_version. If not it will close it and broadcast
-a signal on COND_refresh (to wait any thread that is waiting for
+the current @code{refresh_version}. If not it will close it and broadcast
+a signal on @code{COND_refresh} (to wait any thread that is waiting for
all instanses of a table to be closed).
@item
@@ -119,8 +134,8 @@ The current @code{refresh_version} is also compared to the open
refresh version is different the thread will free all locks, reopen the
table and try to get the locks again; This is just to quickly get all
tables to use the newest version. This is handled by
-@code{sql/lock.cc::mysql_lock_tables()} and
-@code{sql/sql_base.cc::wait_for_tables()}.
+@file{sql/lock.cc::mysql_lock_tables()} and
+@file{sql/sql_base.cc::wait_for_tables()}.
@item
When all tables has been closed @code{FLUSH TABLES} will return an ok
@@ -134,8 +149,8 @@ After this it will give other threads a chance to open the same tables.
@end itemize
-@node Filesort,,,
-@chapter How MySQL does sorting (filesort)
+@node filesort, coding guidelines, flush tables, Top
+@chapter How MySQL Does Sorting (@code{filesort})
@itemize @bullet
@@ -146,7 +161,7 @@ Read all rows according to key or by table scanning.
Store the sort-key in a buffer (@code{sort_buffer}).
@item
-When the buffer gets full, run a qsort on it and store the result
+When the buffer gets full, run a @code{qsort} on it and store the result
in a temporary file. Save a pointer to the sorted block.
@item
@@ -170,12 +185,13 @@ Now the code in @file{sql/records.cc} will be used to read through them
in sorted order by using the row pointers in the result file.
To optimize this, we read in a big block of row pointers, sort these
and then we read the rows in the sorted order into a row buffer
-(@code{record_buffer}) .
+(@code{record_buffer}).
@end itemize
-@node Coding guidelines,,,
-@chapter Coding guidelines
+
+@node coding guidelines, mysys functions, filesort, Top
+@chapter Coding Guidelines
@itemize @bullet
@@ -183,24 +199,28 @@ and then we read the rows in the sorted order into a row buffer
We are using @uref{http://www.bitkeeper.com/, BitKeeper} for source management.
@item
-You should use the @strong{MySQL} 3.23 or 4.0 source for all developments.
+You should use the @strong{MySQL} 4.0 source for all developments.
@item
If you have any questions about the @strong{MySQL} source, you can post these
-to @email{developers@@mysql.com} and we will answer them.
-Note that we will shortly change the name of this list to
-@email{internals@@mysql.com}, to more accurately reflect what should be
-posted to this list.
+to @email{dev-public@@mysql.com} and we will answer them. Please
+remember to not use this internal email list in public!
@item
-Try to write code in a lot of black boxes that can be reused or at
-least have a clean interface.
+Try to write code in a lot of black boxes that can be reused or use at
+least a clean, easy to change interface.
@item
Reuse code; There is already a lot of algorithms in MySQL for list handling,
queues, dynamic and hashed arrays, sorting, etc. that can be reused.
@item
+Use the @code{my_*} functions like @code{my_read()}/@code{my_write()}/
+@code{my_malloc()} that you can find in the @code{mysys} library instead
+of the direct system calls; This will make your code easier to debug and
+more portable.
+
+@item
Try to always write optimized code, so that you don't have to
go back and rewrite it a couple of months later. It's better to
spend 3 times as much time designing and writing an optimal function than
@@ -221,25 +241,23 @@ Don't use two commands on the same line.
Do not check the same pointer for @code{NULL} more than once.
@item
-Use long function and variable names in English; This makes your code
-easier to read. Use the 'varible_name' style instead of 'VariableName'.
+Use long function and variable names in English. This makes your code
+easier to read.
@item
-Think assembly - make it easier for the compiler to optimize your code.
+Use @code{my_var} as opposed to @code{myVar} or @code{MyVar} (@samp{_}
+rather than dancing SHIFT to seperate words in identifiers).
@item
-Comment your code when you do something that someone else may think
-is not ''trivial''.
+Think assembly - make it easier for the compiler to optimize your code.
@item
-Use the @code{my_*} functions like @code{my_read()}/@code{my_write()}/
-@code{my_malloc()} that you can find in the @code{mysys} library instead
-of the direct system calls; This will make your code easier to debug and
-more portable.
+Comment your code when you do something that someone else may think
+is not ``trivial''.
@item
-Use @code{libstring} functions instead of standard libc string functions
-whenever possible.
+Use @code{libstring} functions (in the @file{strings} directory)
+instead of standard @code{libc} string functions whenever possible.
@item
Avoid using @code{malloc()} (its REAL slow); For memory allocations
@@ -254,10 +272,6 @@ easily discuss it thoroughly if some other developer thinks there is better
way to do the same thing!
@item
-Use my_var as opposed to myVar or MyVar (@samp{_} rather than dancing SHIFT
-to seperate words in identifiers).
-
-@item
Class names start with a capital letter.
@item
@@ -270,29 +284,28 @@ Any @code{#define}'s are in all-caps.
Matching @samp{@{} are in the same column.
@item
-Put the @samp{@{} after a 'switch' on the same line
+Put the @samp{@{} after a @code{switch} on the same line, as this gives
+better overall indentation for the switch statement:
@example
-switch (arg) {
+switch (arg) @{
@end example
-Because this gives better overall indentation for the switch statement.
-
@item
-In all other cases, @{ and @} should be on their own line, except
-if there is nothing inside @{ @}.
+In all other cases, @samp{@{} and @samp{@}} should be on their own line, except
+if there is nothing inside @samp{@{} and @samp{@}}.
@item
-Have a space after 'if'
+Have a space after @code{if}
@item
-Put a space after ',' for function arguments
+Put a space after @samp{,} for function arguments
@item
-Functions return 0 on success, and non-zero on error, so you can do:
+Functions return @samp{0} on success, and non-zero on error, so you can do:
@example
-if(a() || b() || c()) { error("something went wrong"); }
+if(a() || b() || c()) @{ error("something went wrong"); @}
@end example
@item
@@ -337,113 +350,110 @@ Suggested mode in emacs:
(setq c-default-style "MY")
@end example
-@node mysys functions,,,
-@chapter mysys functions
-
-Functions i mysys: (For flags se my_sys.h)
-
- int my_copy _A((const char *from,const char *to,myf MyFlags));
- - Copy file
-
- int my_delete _A((const char *name,myf MyFlags));
- - Delete file
-
- int my_getwd _A((string buf,uint size,myf MyFlags));
- int my_setwd _A((const char *dir,myf MyFlags));
- - Get and set working directory
-
- string my_tempnam _A((const char *pfx,myf MyFlags));
- - Make a uniq temp file name by using dir and adding something after
- pfx to make name uniq. Name is made by adding a uniq 6 length-string
- and TMP_EXT after pfx.
- Returns pointer to malloced area for filename. Should be freed by
- free().
-
- File my_open _A((const char *FileName,int Flags,myf MyFlags));
- File my_create _A((const char *FileName,int CreateFlags,
- int AccsesFlags, myf MyFlags));
- int my_close _A((File Filedes,myf MyFlags));
- uint my_read _A((File Filedes,byte *Buffer,uint Count,myf MyFlags));
- uint my_write _A((File Filedes,const byte *Buffer,uint Count,
- myf MyFlags));
- ulong my_seek _A((File fd,ulong pos,int whence,myf MyFlags));
- ulong my_tell _A((File fd,myf MyFlags));
- - Use instead of open,open-with-create-flag, close read and write
- to get automatic error-messages (flag: MYF_WME) and only have
- to test for != 0 if error (flag: MY_NABP).
-
- int my_rename _A((const char *from,const char *to,myf MyFlags));
- - Rename file
-
- FILE *my_fopen _A((const char *FileName,int Flags,myf MyFlags));
- FILE *my_fdopen _A((File Filedes,int Flags,myf MyFlags));
- int my_fclose _A((FILE *fd,myf MyFlags));
- uint my_fread _A((FILE *stream,byte *Buffer,uint Count,myf MyFlags));
- uint my_fwrite _A((FILE *stream,const byte *Buffer,uint Count,
- myf MyFlags));
- ulong my_fseek _A((FILE *stream,ulong pos,int whence,myf MyFlags));
- ulong my_ftell _A((FILE *stream,myf MyFlags));
- - Same read-interface for streams as for files
-
- gptr _mymalloc _A((uint uSize,const char *sFile,
- uint uLine, myf MyFlag));
- gptr _myrealloc _A((string pPtr,uint uSize,const char *sFile,
- uint uLine, myf MyFlag));
- void _myfree _A((gptr pPtr,const char *sFile,uint uLine));
- int _sanity _A((const char *sFile,unsigned int uLine));
- gptr _myget_copy_of_memory _A((const byte *from,uint length,
- const char *sFile, uint uLine,
- myf MyFlag));
- - malloc(size,myflag) is mapped to this functions if not compiled
- with -DSAFEMALLOC
-
- void TERMINATE _A((void));
- - Writes malloc-info on stdout if compiled with -DSAFEMALLOC.
-
- int my_chsize _A((File fd,ulong newlength,myf MyFlags));
- - Change size of file
-
- void my_error _D((int nr,myf MyFlags, ...));
- - Writes message using error number (se mysys/errors.h) on
- stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called.
-
- void my_message _A((const char *str,myf MyFlags));
- - Writes message-string on
- stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called.
-
- void my_init _A((void ));
- - Start each program (in main) with this.
- void my_end _A((int infoflag));
- - Gives info about program.
- - If infoflag & MY_CHECK_ERROR prints if some files are left open
- - If infoflag & MY_GIVE_INFO prints timing info and malloc info
- about prog.
-
- int my_redel _A((const char *from, const char *to, int MyFlags));
- - Delete from before rename of to to from. Copyes state from old
- file to new file. If MY_COPY_TIME is set sets old time.
-
- int my_copystat _A((const char *from, const char *to, int MyFlags));
- - Copye state from old file to new file.
- If MY_COPY_TIME is set sets copy also time.
-
- string my_filename _A((File fd));
- - Give filename of open file.
-
- int dirname _A((string to,const char *name));
- - Copy name of directory from filename.
-
- int test_if_hard_path _A((const char *dir_name));
- - Test if dirname is a hard path (Starts from root)
-
- void convert_dirname _A((string name));
- - Convert dirname acording to system.
- - In MSDOS changes all caracters to capitals and changes '/' to
- '\'
- string fn_ext _A((const char *name));
- - Returns pointer to extension in filename
- string fn_format _A((string to,const char *name,const char *dsk,
- const char *form,int flag));
+
+@node mysys functions, DBUG, coding guidelines, Top
+@chapter Functions In The @code{mysys} Library
+
+Functions in @code{mysys}: (For flags see @file{my_sys.h})
+
+@table @code
+@item int my_copy _A((const char *from, const char *to, myf MyFlags));
+Copy file from @code{from} to @code{to}.
+
+@item int my_delete _A((const char *name, myf MyFlags));
+Delete file @code{name}.
+
+@item int my_getwd _A((string buf, uint size, myf MyFlags));
+@item int my_setwd _A((const char *dir, myf MyFlags));
+Get and set working directory.
+
+@item string my_tempnam _A((const char *pfx, myf MyFlags));
+Make a unique temporary file name by using dir and adding something after
+@code{pfx} to make name unique. The file name is made by adding a unique
+six character string and @code{TMP_EXT} after @code{pfx}.
+Returns pointer to @code{malloc()}'ed area for filename. Should be freed by
+@code{free()}.
+
+@item File my_open _A((const char *FileName,int Flags,myf MyFlags));
+@item File my_create _A((const char *FileName, int CreateFlags, int AccsesFlags, myf MyFlags));
+@item int my_close _A((File Filedes, myf MyFlags));
+@item uint my_read _A((File Filedes, byte *Buffer, uint Count, myf MyFlags));
+@item uint my_write _A((File Filedes, const byte *Buffer, uint Count, myf MyFlags));
+@item ulong my_seek _A((File fd,ulong pos,int whence,myf MyFlags));
+@item ulong my_tell _A((File fd,myf MyFlags));
+Use instead of open, open-with-create-flag, close, read, and write
+to get automatic error messages (flag @code{MYF_WME}) and only have
+to test for != 0 if error (flag @code{MY_NABP}).
+
+@item int my_rename _A((const char *from, const char *to, myf MyFlags));
+Rename file from @code{from} to @code{to}.
+
+@item FILE *my_fopen _A((const char *FileName,int Flags,myf MyFlags));
+@item FILE *my_fdopen _A((File Filedes,int Flags,myf MyFlags));
+@item int my_fclose _A((FILE *fd,myf MyFlags));
+@item uint my_fread _A((FILE *stream,byte *Buffer,uint Count,myf MyFlags));
+@item uint my_fwrite _A((FILE *stream,const byte *Buffer,uint Count, myf MyFlags));
+@item ulong my_fseek _A((FILE *stream,ulong pos,int whence,myf MyFlags));
+@item ulong my_ftell _A((FILE *stream,myf MyFlags));
+Same read-interface for streams as for files.
+
+@item gptr _mymalloc _A((uint uSize,const char *sFile,uint uLine, myf MyFlag));
+@item gptr _myrealloc _A((string pPtr,uint uSize,const char *sFile,uint uLine, myf MyFlag));
+@item void _myfree _A((gptr pPtr,const char *sFile,uint uLine));
+@item int _sanity _A((const char *sFile,unsigned int uLine));
+@item gptr _myget_copy_of_memory _A((const byte *from,uint length,const char *sFile, uint uLine,myf MyFlag));
+@code{malloc(size,myflag)} is mapped to these functions if not compiled
+with @code{-DSAFEMALLOC}.
+
+@item void TERMINATE _A((void));
+Writes @code{malloc()} info on @code{stdout} if compiled with
+@code{-DSAFEMALLOC}.
+
+@item int my_chsize _A((File fd, ulong newlength, myf MyFlags));
+Change size of file @code{fd} to @code{newlength}.
+
+@item void my_error _D((int nr, myf MyFlags, ...));
+Writes message using error number (see @file{mysys/errors.h}) on @code{stdout},
+or using curses, if @code{MYSYS_PROGRAM_USES_CURSES()} has been called.
+
+@item void my_message _A((const char *str, myf MyFlags));
+Writes @code{str} on @code{stdout}, or using curses, if
+@code{MYSYS_PROGRAM_USES_CURSES()} has been called.
+
+@item void my_init _A((void ));
+Start each program (in @code{main()}) with this.
+
+@item void my_end _A((int infoflag));
+Gives info about program.
+If @code{infoflag & MY_CHECK_ERROR}, prints if some files are left open.
+If @code{infoflag & MY_GIVE_INFO}, prints timing info and malloc info
+about program.
+
+@item int my_redel _A((const char *from, const char *to, int MyFlags));
+Delete @code{from} before rename of @code{to} to @code{from}. Copies state
+from old file to new file. If @code{MY_COPY_TIME} is set, sets old time.
+
+@item int my_copystat _A((const char *from, const char *to, int MyFlags));
+Copy state from old file to new file. If @code{MY_COPY_TIME} is set,
+sets old time.
+
+@item string my_filename _A((File fd));
+Returns filename of open file.
+
+@item int dirname _A((string to, const char *name));
+Copy name of directory from filename.
+
+@item int test_if_hard_path _A((const char *dir_name));
+Test if @code{dir_name} is a hard path (starts from root).
+
+@item void convert_dirname _A((string name));
+Convert dirname according to system.
+In MSDOS, changes all characters to capitals and changes @samp{/} to @samp{\}.
+
+@item string fn_ext _A((const char *name));
+Returns pointer to extension in filename.
+
+@item string fn_format _A((string to,const char *name,const char *dsk,const char *form,int flag));
format a filename with replace of library and extension and
converts between different systems.
params to and name may be identicall
@@ -457,117 +467,204 @@ Functions i mysys: (For flags se my_sys.h)
"open(fn_format(temp_buffe,name,"","",4),...)" to unpack home and
convert filename to system-form.
- string fn_same _A((string toname,const char *name,int flag));
- - Copys directory and extension from name to toname if neaded.
- copy can be forced by same flags that in fn_format.
+@item string fn_same _A((string toname, const char *name, int flag));
+Copys directory and extension from @code{name} to @code{toname} if neaded.
+Copying can be forced by same flags used in @code{fn_format()}.
+
+@item int wild_compare _A((const char *str, const char *wildstr));
+Compare if @code{str} matches @code{wildstr}. @code{wildstr} can contain
+@samp{*} and @samp{?} as wildcard characters.
+Returns 0 if @code{str} and @code{wildstr} match.
+
+@item void get_date _A((string to, int timeflag));
+Get current date in a form ready for printing.
+
+@item void soundex _A((string out_pntr, string in_pntr))
+Makes @code{in_pntr} to a 5 char long string. All words that sound
+alike have the same string.
+
+@item int init_key_cache _A((ulong use_mem, ulong leave_this_much_mem));
+Use caching of keys in MISAM, PISAM, and ISAM.
+@code{KEY_CACHE_SIZE} is a good size.
+Remember to lock databases for optimal caching.
+
+@item void end_key_cache _A((void));
+End key caching.
+@end table
+
- int wild_compare _A((const char *str,const char *wildstr));
- - Compare if str matches wildstr. Wildstr can contain "*" and "?"
- as match-characters.
- Returns 0 if match.
- void get_date _A((string to,int timeflag));
- - Get current date in a form ready for printing.
+@node DBUG, protocol, mysys functions, Top
+@chapter DBUG Tags To Use
- void soundex _A((string out_pntr, string in_pntr))
- - Makes in_pntr to a 5 chars long string. All words that sounds
- alike have the same string.
+Here is some of the tags we now use:
+(We should probably add a couple of new ones)
- int init_key_cache _A((ulong use_mem,ulong leave_this_much_mem));
- - Use cacheing of keys in MISAM, PISAM, and ISAM.
- KEY_CACHE_SIZE is a good size.
- - Remember to lock databases for optimal cacheing
+@table @code
+@item enter
+Arguments to the function.
- void end_key_cache _A((void));
- - End key-cacheing.
+@item exit
+Results from the function.
-@node protocol,,,
-@chapter MySQL client/server protocol
+@item info
+Something that may be interesting.
-Raw packet without compression
-==============================
--------------------------------------------------
-| Packet Length | Packet no | Data |
-| 3 Bytes | 1 Byte | n Bytes |
--------------------------------------------------
+@item warning
+When something doesn't go the usual route or may be wrong.
-3 Byte packet length
- The length is calculated with int3store
- See include/global.h for details.
- The max packetsize can be 16 MB.
-1 Byte packet no
+@item error
+When something went wrong.
-If no compression is used the first 4 bytes of each paket
-is the header of the paket.
-The packet number is incremented for each sent packet. The first
-packet starts with 0
+@item loop
+Write in a loop, that is probably only useful when debugging
+the loop. These should normally be deleted when one is
+satisfied with the code and it has been in real use for a while.
+@end table
-n Byte data
+Some specific to mysqld, because we want to watch these carefully:
+
+@table @code
+@item trans
+Starting/stopping transactions.
+
+@item quit
+@code{info} when mysqld is preparing to die.
+
+@item query
+Print query.
+@end table
+
+
+@node protocol, Fulltext Search, DBUG, Top
+@chapter MySQL Client/Server Protocol
+
+@menu
+* raw packet without compression::
+* raw packet with compression::
+* basic packets::
+* communication::
+* fieldtype codes::
+@end menu
+
+@node raw packet without compression, raw packet with compression, protocol, protocol
+@section Raw Packet Without Compression
+
+@example
++-----------------------------------------------+
+| Packet Length | Packet no | Data |
+| 3 Bytes | 1 Byte | n Bytes |
++-----------------------------------------------+
+@end example
+
+@table @asis
+@item 3 Byte packet length
+The length is calculated with int3store
+See include/global.h for details.
+The max packetsize can be 16 MB.
+
+@item 1 Byte packet no
+If no compression is used the first 4 bytes of each packet is the header
+of the packet. The packet number is incremented for each sent packet.
+The first packet starts with 0.
+@item n Byte data
+
+@end table
The packet length can be recalculated with:
+
+@example
length = byte1 + (256 * byte2) + (256 * 256 * byte3)
-
-Raw packet with compression
-===========================
------------------------------------------------------
-| Packet Length | Packet no | Uncomp. Packet Length |
-| 3 Bytes | 1 Byte | 3 Bytes |
------------------------------------------------------
-
-3 Byte packet length
- The length is calculated with int3store
- See include/global.h for details.
- The max packetsize can be 16 MB.
-1 Byte packet no
-3 Byte uncompressed packet length
-
-If compression is used the first 7 bytes of each paket
-is the header of the paket.
-
-Basic packets
-==============
-OK-packet
- For details see sql/net_pkg.cc
- function send_ok
- -------------------------------------------------
- | Header | No of Rows | Affected Rows |
- | | 1 Byte | 1-8 Byte |
- -------------------------------------------------
- | ID (last_insert_id) | Status | Length |
- | 1-8 Byte | 2 Byte | 1-8 Byte |
- -------------------------------------------------
- | Messagetext |
- | n Byte |
- -------------------------------------------------
-
- Header
- 1 byte number of rows ? (always 0 ?)
- 1-8 bytes affected rows
- 1-8 byte id (last_insert_id)
- 2 byte Status (usually 0)
- If the OK-packege includes a message:
- 1-8 bytes length of message
- n bytes messagetext
-
-Error-packet
- -------------------------------------------------
- | Header | Statuscode | Error no |
- | | 1 Byte | 2 Byte |
- -------------------------------------------------
- | Messagetext | 0x00 |
- | n Byte | 1 Byte |
- -------------------------------------------------
-
- Header
- 1 byte status code (0xFF = ERROR)
- 2 byte error number (is only sent to new 3.23 clients.
- n byte errortext
- 1 byte 0x00
-
-
-
-The communication
-=================
+@end example
+
+
+@node raw packet with compression, basic packets, raw packet without compression, protocol
+@section Raw Packet With Compression
+
+@example
++---------------------------------------------------+
+| Packet Length | Packet no | Uncomp. Packet Length |
+| 3 Bytes | 1 Byte | 3 Bytes |
++---------------------------------------------------+
+@end example
+
+@table @asis
+@item 3 Byte packet length
+The length is calculated with int3store
+See include/global.h for details.
+The max packetsize can be 16 MB.
+
+@item 1 Byte packet no
+@item 3 Byte uncompressed packet length
+@end table
+
+If compression is used the first 7 bytes of each packet
+is the header of the packet.
+
+
+@node basic packets, communication, raw packet with compression, protocol
+@section Basic Packets
+
+@menu
+* ok packet::
+* error packet::
+@end menu
+
+
+@node ok packet, error packet, basic packets, basic packets
+@subsection OK Packet
+
+For details, see @file{sql/net_pkg.cc::send_ok()}.
+
+@example
++-----------------------------------------------+
+| Header | No of Rows | Affected Rows |
+| | 1 Byte | 1-8 Byte |
+|-----------------------------------------------|
+| ID (last_insert_id) | Status | Length |
+| 1-8 Byte | 2 Byte | 1-8 Byte |
+|-----------------------------------------------|
+| Messagetext |
+| n Byte |
++-----------------------------------------------+
+@end example
+
+@table @asis
+@item Header
+@item 1 byte number of rows ? (always 0 ?)
+@item 1-8 bytes affected rows
+@item 1-8 byte id (last_insert_id)
+@item 2 byte Status (usually 0)
+@item If the OK-packege includes a message:
+@item 1-8 bytes length of message
+@item n bytes messagetext
+@end table
+
+
+@node error packet, , ok packet, basic packets
+@subsection Error Packet
+
+@example
++-----------------------------------------------+
+| Header | Status code | Error no |
+| | 1 Byte | 2 Byte |
+|-----------------------------------------------|
+| Messagetext | 0x00 |
+| n Byte | 1 Byte |
++-----------------------------------------------+
+@end example
+
+@table @asis
+@item Header
+@item 1 byte status code (0xFF = ERROR)
+@item 2 byte error number (is only sent to new 3.23 clients.
+@item n byte errortext
+@item 1 byte 0x00
+@end table
+
+
+@node communication, fieldtype codes, basic packets, protocol
+@section Communication
> Packet from server to client
< Paket from client tor server
@@ -658,28 +755,29 @@ The communication
n data
-Fieldtype Codes:
-================
-
- display_length |enum_field_type |flags
- ----------------------------------------------------
-Blob 03 FF FF 00 |01 FC |03 90 00 00
-Mediumblob 03 FF FF FF |01 FC |03 90 00 00
-Tinyblob 03 FF 00 00 |01 FC |03 90 00 00
-Text 03 FF FF 00 |01 FC |03 10 00 00
-Mediumtext 03 FF FF FF |01 FC |03 10 00 00
-Tinytext 03 FF 00 00 |01 FC |03 10 00 00
-Integer 03 0B 00 00 |01 03 |03 03 42 00
-Mediumint 03 09 00 00 |01 09 |03 00 00 00
-Smallint 03 06 00 00 |01 02 |03 00 00 00
-Tinyint 03 04 00 00 |01 01 |03 00 00 00
-Varchar 03 XX 00 00 |01 FD |03 00 00 00
-Enum 03 05 00 00 |01 FE |03 00 01 00
-Datetime 03 13 00 00 |01 0C |03 00 00 00
-Timestamp 03 0E 00 00 |01 07 |03 61 04 00
-Time 03 08 00 00 |01 0B |03 00 00 00
-Date 03 0A 00 00 |01 0A |03 00 00 00
+@node fieldtype codes, , communication, protocol
+@section Fieldtype Codes
+@example
+ display_length |enum_field_type |flags
+ ----------------------------------------------------
+Blob 03 FF FF 00 |01 FC |03 90 00 00
+Mediumblob 03 FF FF FF |01 FC |03 90 00 00
+Tinyblob 03 FF 00 00 |01 FC |03 90 00 00
+Text 03 FF FF 00 |01 FC |03 10 00 00
+Mediumtext 03 FF FF FF |01 FC |03 10 00 00
+Tinytext 03 FF 00 00 |01 FC |03 10 00 00
+Integer 03 0B 00 00 |01 03 |03 03 42 00
+Mediumint 03 09 00 00 |01 09 |03 00 00 00
+Smallint 03 06 00 00 |01 02 |03 00 00 00
+Tinyint 03 04 00 00 |01 01 |03 00 00 00
+Varchar 03 XX 00 00 |01 FD |03 00 00 00
+Enum 03 05 00 00 |01 FE |03 00 01 00
+Datetime 03 13 00 00 |01 0C |03 00 00 00
+Timestamp 03 0E 00 00 |01 07 |03 61 04 00
+Time 03 08 00 00 |01 0B |03 00 00 00
+Date 03 0A 00 00 |01 0A |03 00 00 00
+@end example
@c The Index was empty, and ugly, so I removed it. (jcole, Sep 7, 2000)
@@ -688,6 +786,48 @@ Date 03 0A 00 00 |01 0A |03 00 00 00
@c @printindex fn
+@node Fulltext Search, , protocol, Top
+@chapter Fulltext Search in MySQL
+
+Hopefully, sometime there will be complete description of
+fulltext search algorithms.
+Now it's just unsorted notes.
+
+@menu
+* Weighting in boolean mode::
+@end menu
+
+@node Weighting in boolean mode, , , Fulltext Search
+@section Weighting in boolean mode
+
+The basic idea is as follows: in expression
+@code{A or B or (C and D and E)}, either @code{A} or @code{B} alone
+is enough to match the whole expression. While @code{C},
+@code{D}, and @code{E} should @strong{all} match. So it's
+reasonable to assign weight 1 to @code{A}, @code{B}, and
+@code{(C and D and E)}. And @code{C}, @code{D}, and @code{E}
+should get a weight of 1/3.
+
+Things become more complicated when considering boolean
+operators, as used in MySQL FTB. Obvioulsy, @code{+A +B}
+should be treated as @code{A and B}, and @code{A B} -
+as @code{A or B}. The problem is, that @code{+A B} can @strong{not}
+be rewritten in and/or terms (that's the reason why this - extended -
+set of operators was chosen). Still, aproximations can be used.
+@code{+A B C} can be approximated as @code{A or (A and (B or C))}
+or as @code{A or (A and B) or (A and C) or (A and B and C)}.
+Applying the above logic (and omitting mathematical
+transformations and normalization) one gets that for
+@code{+A_1 +A_2 ... +A_N B_1 B_2 ... B_M} the weights
+should be: @code{A_i = 1/N}, @code{B_j=1} if @code{N==0}, and,
+otherwise, in the first rewritting approach @code{B_j = 1/3},
+and in the second one - @code{B_j = (1+(M-1)*2^M)/(M*(2^(M+1)-1))}.
+
+The second expression gives somewhat steeper increase in total
+weight as number of matched B's increases, because it assigns
+higher weights to individual B's. Also the first expression in
+much simplier. So it is the first one, that is implemented in MySQL.
+
@summarycontents
@contents
diff --git a/Docs/manual.de.texi b/Docs/manual.de.texi
new file mode 100644
index 00000000000..94c822b94da
--- /dev/null
+++ b/Docs/manual.de.texi
@@ -0,0 +1,56165 @@
+\input texinfo @c -*-texinfo-*-
+@c Copyright 1997-2002 TcX AB, Detron HB und MySQL Finland AB
+@c
+@c *********************************************************
+@c Note that @node names are used on our Website.
+@c So do not change node names without checking
+@c Makefile.am und SitePages first.
+@c *********************************************************
+@c
+@c %**start of header
+
+@c there's a better way to do this.. i just don't know it yet
+@c sed will remove the "@c ifnusphere " to make this valid
+@c ifnusphere @set nusphere 1
+
+@setfilename mysql.de.info
+
+@c We want the types in the same index
+@syncodeindex tp fn
+
+@c Get version information. This file is generated by the Makefile!!
+@include include.texi
+
+@ifclear tex-debug
+@c This removes the black squares in the right margin
+@finalout
+@end ifclear
+
+@c Set background für HTML
+@set _body_tags BGCOLOR=silver TEXT=#000000 LINK=#101090 VLINK=#7030B0
+@c Set some style elements für the manual in HTML form. 'suggested'
+@c natural language colors: aqua, black, blue, fuchsia, gray, green,
+@c lime, maroon, navy, olive, purple, red, silver, teal, white, und
+@c yellow. From Steeve Buehler <ahr@YogElements.com>
+@set _extra_head <style> code {color:purple} tt {color:green} samp {color:navy} pre {color:maroon} </style>
+
+@settitle MySQL-Referenzhandbuch für Version @value{mysql_version}
+
+@c We want single-sided heading format, with chapters on new pages. To
+@c get double-sided format change 'on' below to 'odd'
+@ifclear nusphere
+@setchapternewpage on
+@end ifclear
+
+@ifset nusphere
+@setchapternewpage odd
+@end ifset
+
+@paragraphindent 0
+
+@ifset nusphere
+@smallbook
+@end ifset
+
+@c %**end of header
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* mysql: (mysql). MySQL documentation.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@titlepage
+@sp 10
+@center @titlefont{MySQL-Referenzhandbuch}
+@sp 10
+@center Copyright @copyright{} 1997-2002 MySQL AB
+@c blank page after title page makes page 1 be a page front.
+@c also makes the back of the title page blank.
+@page
+@end titlepage
+
+@c Short contents, blank page, long contents.
+@c until i can figure out the blank page, no short contents.
+@c @shortcontents
+@c @page
+@c @page
+@contents
+
+@c This should be added. The HTML conversion also needs a MySQL version
+@c Anzahl somewhere.
+
+@iftex
+@c change this to double if you want formatting für double-sided
+@c printing
+@headings single
+
+@oddheading @thischapter @| @| @thispage
+@evenheading @thispage @| @| MySQL - Technische Referenz für Version @value{mysql_version}
+
+@end iftex
+
+
+@node Top, Introduction, (dir), (dir)
+@c German node Top
+
+@c @ifhtml
+@c <IMG SRC="Images/mysql-logo.gif">
+@c <!--Image doesn't exist. Can't find suitable replacement. (Matt) -->
+@c @end ifhtml
+
+@ifinfo
+Das ist das Handbuch für das MySQL-Datenbanksystem. Diese Version gehört
+zur MySQL-Version @value{mysql_version}. Sie finden ein Handbuch zu jeder
+älteren Version von MySQL in der Binär- oder Quelldistribution der
+entsprechenden Version.
+@end ifinfo
+
+
+
+@menu
+* Introduction::
+* Deutsch::
+* Installing::
+* Tutorial::
+* MySQL Database Administration::
+* MySQL Optimisation::
+* Reference::
+* Table types::
+* Clients::
+* Extending MySQL::
+* Problems::
+* Benutzer::
+* MySQL-Benutzung durch Kunden::
+* Contrib::
+* Credits::
+* News::
+* Porting::
+* Environment variables::
+* Regexp::
+* GPL license::
+* LGPL license::
+* Function Index::
+* Concept Index::
+@end menu
+
+@node Introduction, Deutsch, Top, Top
+@c German node Einführung
+@chapter Allgemeine Informationen über MySQL
+
+@cindex Überblick
+@cindex Allgemeine Informationen
+
+MySQL ist ein sehr schneller und robuster, Multi-Thread und Multi-User
+SQL-Datenbank-Server (SQL = Structured Query Language, strukturierte
+Abfrage-Sprache).
+Die Einsatzgebiete des MySQL Server liegen in Hochleistungsapplikationen
+und in der Einbindung in weit verbreitete Massen-Software.
+@code{MySQL} ist eine Schutzmarke von @code{MySQL AB}.
+
+Die MySQL Software steht unter einer @code{Doppellizenz}. Sie
+können sie entweder frei im Sinne der @code{GNU GENERAL PUBLIC LICENSE}
+(@uref{http://www.gnu.org/licenses/}) verwenden, oder Sie erwerben eine
+komerzielle Lizenz, wenn Sie nicht durch die Restriktionen der GPL
+gebunden sein wollen.
+@xref{Lizenzpolitik}.
+
+@uref{http://www.mysql.com/, die MySQL Homepage}
+enthält die letzten Informationen über MySQL.
+
+Die folgende Liste beschreibt nützliche Teile des Handbuchs.
+
+@itemize @bullet
+@item
+Informationen zu dem Unternehmen hinter MySQL: @ref{What is MySQL AB}.
+
+@item
+Eine Diskussion der Fähigkeiten von MySQL: @ref{Features}.
+
+@item
+Installationsanweisungen: @ref{Installing}.
+
+@item
+Tipps zur Portierung von MySQL auf neue Architekturen oder Betriebssysteme:
+@ref{Porting}.
+
+@item
+Informationen zum Upgrade von einem Release der Version 3.23:
+@ref{Upgrading-from-3.23}.
+
+@item
+Informationen zum Upgrade von einem Release der Version 3.22:
+@ref{Upgrading-from-3.22}.
+
+@item
+Einführungs-Tutorial zu MySQL: @ref{Tutorial}.
+
+@item
+SQL-Beispiele und Informationen zu Benchmarks befinden sich im
+Benchmark-Verzeichnis (@file{sql-bench} in der Distribution).
+
+@item
+Die Geschichte neuer Features und Bugfixes: @ref{News}.
+
+@item
+@c German FIX was @nqs{Feature-Probleme}; no idea what @nqs is??
+Eine Liste bekannter Bugs und Feature-Probleme: @ref{Bugs}.
+
+@item
+Zukunftspläne: @ref{TODO}.
+
+@item
+Eine Liste aller Beteiligten, die zu diesem Projekt beitrugen: @ref{Credits}.
+@end itemize
+
+@strong{WICHTIG:}
+
+Berichte zu Fehlern (oft Bugs genannt) sowie Fragen und Bemerkungen sollten
+an die Mailingliste geschickt werden: @email{mysql@@lists.mysql.com}.
+@xref{Bug reports}.
+Das @code{mysqlbug} Skript sollte benutzt werden, um Fehlerberichte zu
+erzeugen.
+@c FIX! RPMs are also binary
+Bei Quelltext-Distributionen liegt das @code{mysqlbug} Skript im
+@file{scripts} Verzeichnis. Bei Binärdistributionen liegt @code{mysqlbug}
+im @file{bin} Verzeichnis. Wenn Sie einen empfindlichen Sicherheits-Bug in
+MySQL gefunden haben, sollten Sie eine E-Mail an
+@email{security@@mysql.com} schicken.
+
+@cindex Fehler, berichten
+@cindex Berichten, Fehler
+@cindex Mailing-Listen-Adresse
+@cindex @code{mysqlbug}-Skript, Speicherort
+
+
+
+
+@node Deutsch, Installing, Introduction, Top
+@c German node <no English equivalent>
+@chapter Vorbemerkungen zum deutschen Handbuch
+
+Die Übersetzung einer so umfangreichen technischen Dokumentation wie des
+MySQL-Referenzhandbuchs ist schon eine besondere Herausforderung.
+Zumindest für jemanden, der seine Zielsprache ernst nimmt:
+
+@itemize @bullet
+@item
+In diesem Handbuch wird nicht geupdated, sondern aktualisiert.
+@item
+Eine MySQL-Distribution wird nicht gedownloaded, sondern herunter
+geladen.
+@item
+Und Transaktionen werden nicht gerollbackt, sondern zurückgerollt.
+@end itemize
+
+Womit wir auch schon bei der besonderen Herausforderung wären: Jeder,
+der sich mit Transaktionen auskennt, weiß, dass beim Fehlschlagen einer
+solchen ein Rollback-Befehl ausgeführt wird. Dieses Hauptwort ins
+Deutsche zu übersetzen, würde zum Verständnis wenig beitragen - im
+Gegenteil.
+
+Damit bleiben alle technischen Fachbegriffe, die sich so und nicht
+anders etabliert haben, englisch:
+
+@itemize @bullet
+@item
+Ein SQL-Statement wird nicht als "Erklärung in der Strukturierten
+AbfrageSprache (SAS)" übersetzt.
+@item
+Abkürzungen wie TCP/IP werden nicht zu ÜSP/ZP
+(ÜbertragungsSteuerungsProtokoll/ZwischennetzProtokoll).
+@item
+Ein Client bleibt ein Client, und ein Server ein Server.
+@end itemize
+
+Die Fallstricke einer Übersetzung stecken allerdings in den Details:
+
+@itemize @bullet
+@item
+Jeder SQL-Kenner weiß, was eine "query" ist. In diesem Handbuch ist
+das eine Anfrage.
+@item
+Gibt es Probleme bei der Übermittlung einer Anfrage, kann es sein,
+dass eine Zeitüberschreitung eintritt. Der Profi hätte wahrscheinlich
+nach "Timeout" gesucht.
+@item
+Manche Dinge sind einfacher: Ein "string" ist eine Zeichenkette
+(obwohl für Profis vielleicht ungewohnt), ein "hex value" ein
+hexadezimaler Wert.
+@end itemize
+
+Richtig spannend wird die Übersetzung bei Wörtern, die in der deutschen
+Fachsprache zumeist englisch verwendet werden, obwohl es passende
+deutsche Entsprechungen gibt:
+
+@itemize @bullet
+@item
+Im Hauptspeicher ("RAM") zwischengespeicherte Daten werden auf die
+Festplatte zurückgeschrieben. Im Englischen heißt das "flushed to
+disk", und im Deutschen werden die Daten häufig "geflushed".
+@item
+Daten werden zwischengespeichert ("gecached").
+@item
+Speicher wird zugewiesen. Man kann auch "alloziert" sagen, was dem
+englischen "allocated" näher kommt.
+@end itemize
+
+Alle diese Entsprechungen, bei denen die deutsche Sprache eher in
+Vergessenheit geraten ist, wurden zweisprachig aufgenommen. Beispiele:
+
+@itemize @bullet
+@item
+Alle Daten werden zwischen Anfragen auf die Festplatte zurück
+geschrieben (flush).
+@item
+Aktualisieren Sie (Update), wenn alles in Ordnung ist.
+@item
+Auf eine höhere Version von MySQL aktualisieren (Upgrade) ...
+@end itemize
+
+Gelegentlich wird auch in diesem Handbuch die "Performance getuned",
+neue "Features" eines MySQL-"Release" werden beschrieben usw. Anregungen
+für eine weiter gehende Eindeutschung nimmt der Übersetzer gern
+entgegen. Insbesondere gilt das auch für Hinweise zur Verkürzung
+deutscher Ausdrücke. Beispielsweise heißt "case sensitive" (14
+Buchstaben) im Handbuch "abhängig von der verwendeten
+Groß-/Kleinschreibung" (44 Buchstaben).
+
+Letzter Punkt: Die Übersetzung erfolgte in äußerst enger Anlehnung an
+das englischsprachige Original. Nichts wurde hinzugefügt (ausser diesem
+Vorwort), geändert oder weggelassen (Ausnahme: die Geschichte der
+Änderungen (ChangeLog) vor Version 3.23). Es liegt in der Natur der
+Dinge, dass weder Original noch Übersetzung frei von Fehlern sind
+(obwohl wir das anstreben). Berichten Sie bitte Übersetzungsfehler,
+stilistische "Bugs", die das Verständnis beeinträchtigen und sonstige
+Anmerkungen zur Übersetzung direkt an:
+
+@c German FIX added escape @@ in e-mail address.
+Stefan Hinz, @email{handbuch@@mysql.com}
+
+Berlin, im Februar 2002
+
+Stefan Hinz, @uref{http://iConnect.de,iConnect GmbH Berlin}
+
+
+@menu
+* Manual-info::
+* What-is::
+* What is MySQL AB::
+* Licensing and Support::
+* MySQL 4.0 In A Nutshell::
+* MySQL Information Sources::
+* Compatibility::
+* TODO::
+* Comparisons::
+@end menu
+
+@node Manual-info, What-is, Deutsch, Deutsch
+@c German node Handbuch-Informationen
+@section Über dieses Handbuch
+
+@cindex Speicherort des Online-Handbuchs
+@cindex Handbuch, Online-Speicherort
+
+Das ist ein Referenzhandbuch. Es enthält keine allgemeinen Anleitungen zu
+SQL oder relationalen Datenbankkonzepten.
+@c German FIX these references don't exist:
+@c Wenn Sie allgemeine Informationen über SQL suchen,
+@c finden Sie diese hier: @ref{SQL allgemein}.
+@c Bücher, die sich speziell mit MySQL beschäftigen,
+@c finden Sie hier: @ref{MySQL-Bücher}.
+
+Da die MySQL Datenbank Software eine laufende Weiterentwicklung erfährt, wird
+das Handbuch regelmäßig aktualisiert.
+Die jeweils aktuellste Version dieses Handbuchs befindet sich unter
+@uref{http://www.mysql.com/documentation/}.
+Dieses Handbuch ist gegenwärtig verfügbar in Texinfo, als Klartext
+(plain text), Info, HTML, PostScript und PDF. Das Primärdokument ist die
+Texinfo-Datei.
+Die HTML-Version wird automatisch produziert, indem eine modifizierte
+Version von @code{texi2html} benutzt wird. Die Klartext- und Info-
+Versionen werden mit @code{makeinfo} hergestellt. Die PostScript-Version
+wird mit @code{texi2dvi} und @code{dvips} produziert. Die PDF-Version
+wird mit @code{pdftex} hergestellt.
+
+Wenn Sie Schwierigkeiten haben, Informationen zu finden, beachten Sie bitte
+auch die durchsuchbare PHP Version des Handbuchs unter
+@uref{http://www.mysql.com/doc/}.
+
+Wenn Sie Vorschläge für Hinzufügungen oder Korrekturen dieses Handbuchs
+haben, schicken Sie sie bitte an das Handbuch-Team:
+@email{docs@@mysql.com}.
+
+@cindex Handbuch, verfügbare Formate
+@cindex Texinfo
+
+Dieses Handbuch wurde geschrieben und wird gewartet von David Axmark,
+Michael (Monty) Widenius, Jeremy Cole, und Paul DuBois. Andere
+Kontributoren sind unter @ref{Credits} aufgelistet.
+Die deutsche Übersetzung stammt von Stefan Hinz. Für die
+Aktualität ist Jan Lehnardt zuständig.
+
+Das Copyright (2002) für dieses liegt bei der schwedischen Firma
+@code{MySQL AB}. @xref{Copyright}.
+
+
+@menu
+* Manual conventions::
+@end menu
+
+@node Manual conventions, , Manual-info, Manual-info
+@c German node Handbuch-Konventionen
+@subsection Konventionen in diesem Handbuch
+
+Dieses Handbuch benutzt bestimmte typographische Konventionen:
+
+@cindex Handbuch, typografische Konventionen
+@cindex Typografische Konventionen
+@cindex Konventionen, typografische
+
+@table @asis
+@item @code{constant}
+Schriftart gleicher Breite (nicht-proportionale Schrift) wird für
+Befehle und Optionen benutzt, für SQL-Statements, Datenbank-, Tabellen-
+und Spaltennamen, für C- und PERL-Code und für Umgebungsvariablen.
+Beispiel: ``Um festzustellen, wie @code{mysqladmin} funktioniert, rufen
+Sie den Befehl mit der @code{--help} Option auf.''
+
+@item @file{filename}
+Schriftart gleicher Breite, die von Anführungszeichen umgeben ist, wird
+für Datei- und Pfadnamen benutzt. Beispiel: ``Die Distribution wird im
+Verzeichnis @file{/usr/local/} installiert.''
+
+@item @samp{c}
+Schriftart gleicher Breite, die von Anführungszeichen umgeben ist, wird
+auch benutzt um Zeichenfolgen anzuzeigen. Beispiel: ``Um ein
+Platzhalterzeichen einzugeben, benutzen Sie das @samp{%} Zeichen.''
+
+@item @emph{italic}
+Kursivschrift wird für Hervorhebungen verwendet, @emph{wie in diesem
+Beispiel}.
+
+@item @strong{boldface}
+Fettschrift wird für Namen von Zugriffsrechten verwendet (zum Beispiel:
+``Gewähren Sie das @strong{process} Zugriffsrecht nicht leichtfertig'')
+und gelegentlich, um @strong{besonders starke Hervorhebungen} zu kennzeichnen.
+@end table
+
+Wenn Befehle gezeigt werden, die durch ein bestimmtes Programm
+ausgeführt werden sollen, wird dieses Programm durch einen Prompt
+(Eingabeaufforderung) vor dem Befehl angezeigt. Der @code{shell>} Prompt
+zum Beispiel zeigt an, dass Sie den Befehl von Ihrer Login-Shell aus
+ausführen sollen. @code{mysql>} zeigt an, dass Sie den Befehl vom
+@code{mysql} Client-Programm aus ausführen sollen:
+
+@example
+shell> geben sie hier ein shell-kommando ein
+mysql> geben sie hier ein mysql-kommando ein
+@end example
+
+Shell-Befehle werden mit der Bourne-Shell-Syntax dargestellt. Wenn Sie
+eine @code{csh}-Shell benutzen, müssen die Befehle evtl. etwas anders
+eingegeben werden. Das folgende Beispiel zeigt, wie mit der Bourne-Shell eine
+Umgebungsvariable gesetzt wird und anschließend ein Befehl abgesetzt
+wird:
+
+@example
+shell> VARNAME=wert irgendein_befehl
+@end example
+
+@cindex Shell-Syntax
+@cindex Befehlssyntax
+
+Um @code{csh} auszuführen, würden Sie folgende Sequenz ausführen:
+
+@example
+shell> setenv VARNAME wert
+shell> irgendein_befehl
+@end example
+
+Oft müssen Datenbank-, Tabellen- und Spaltennamen in konkreten Befehlen
+ersetzt werden. Um anzuzeigen, dass eine solche Ersetzung notwendig ist,
+benutzt dieses Handbuch @code{db_name}, @code{tbl_name} und
+@code{col_name}. Sie könnten zum Beispiel folgendes Statement sehen:
+
+@example
+mysql> SELECT spalten_name FROM datenbank_name.tabellen_name;
+@end example
+
+Wenn Sie ein ähnliches Statement eingeben wollen, müssen Sie Ihre
+eigenen Datenbank-, Tabellen- und Spaltennamen eingeben, zum Beispiel
+wie folgt:
+
+@example
+mysql> SELECT autor_name FROM bibliothek.autorenliste;
+@end example
+
+SQL-Statements können in Groß- und Kleinschreibung geschrieben werden.
+Wenn dieses Handbuch SQL-Statements darstellt, wird Großschreibung
+verwendet, um spezielle Schlüsselworte in diesem Kontext hervorzuheben.
+Kleinschreibung wird für den Rest des Statements verwendet. Folgendes
+könnten Sie im Kontext des @code{SELECT} Statements sehen:
+
+@example
+mysql> SELECT count(*) FROM tabellen_name;
+@end example
+
+Im Kontext der @code{COUNT()} Funktion hingegen könnte dasselbe
+Statement wie folgt geschrieben werden:
+
+@example
+mysql> select COUNT(*) from tabellen_name;
+@end example
+
+Wenn keine besondere Hervorhebung beabsichtigt wird, werden alle
+Schlüsselworte in Großschreibung dargestellt.
+
+In Syntax-Beschreibungen werden eckige Klammern (@samp{[} und @samp{]})
+benutzt, um wahlfrei (optionale) Wörter oder Klauseln anzuzeigen:
+
+@example
+DROP TABLE [IF EXISTS] tabellen_name
+@end example
+
+Wenn ein Syntaxelement aus einer Anzahl von Alternativen besteht, werden
+die Alternativen durch gerade Striche (@samp{|}) voneinander getrennt.
+Wenn genau ein Element aus einer Anzahl von Möglichkeiten ausgewählt
+werden (@strong{kann}), werden die Alternativen mit eckigen Klammern
+aufgelistet (@samp{[} und @samp{]}):
+
+@example
+TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
+@end example
+
+Wenn genau ein Element aus einer Anzahl von Möglichkeiten ausgewählt
+werden @strong{muss}, werden die Alternativen innerhalb geschweifter
+Klammern aufgelistet (@samp{@{} und @samp{@}}):
+
+@example
+@{DESCRIBE | DESC@} tbl_name @{col_name | wild@}
+@end example
+
+
+@node What-is, What is MySQL AB, Manual-info, Deutsch
+@c German node Was ist MySQL?
+@section Was ist MySQL?
+
+@cindex MySQL, Definition
+@cindex MySQL, Einführung
+
+
+MySQL, die populärste Open Source SQL-Datenbank, wird von MySQL AB zur
+Verfügung gestellt. MySQL AB ist ein kommerzielles Unternehmen, dessen
+Geschäft darin besteht, Serviceleistungen rund um die MySQL-Datenbank
+zur Verfügung zu stellen. @xref{What is MySQL AB}.
+
+@table @asis
+
+@item MySQL ist ein Datenbank-Managementsystem.
+
+Eine Datenbank ist eine strukturierte Sammlung von Daten. Das kann alles
+sein - von einer einfachen Einkaufsliste über eine Bildergalerie bis zu
+riesigen Informationsmengen in einem Unternehmensnetzwerk. Um Daten zu
+einer Computer-Datenbank hinzuzufügen, auf sie zuzugreifen und sie zu
+verarbeiten, benötigen Sie ein Datenbank-Managementsystem wie MySQL. Weil
+Computer sehr gut darin sind, große Datenmengen zu handhaben, spielt
+Datenbank-Management eine zentrale Rolle im Computer-Bereich, sowohl bei
+Anwendungen, die allein laufen (Stand-Alone-Utilities) als auch als Teil
+anderer Anwendungen.
+@cindex Datenbanken, Definition
+
+@item MySQL ist ein relationales Datenbank-Managementsystem.
+
+Eine relationale Datenbank speichert Daten in separaten Tabellen,
+anstatt sie alle in einem einzigen großen Speicherraum unterzubringen.
+Hierdurch werden hohe Geschwindigkeit und Flexibilität erreicht. Die
+Tabellen werden durch definierte Beziehungen verbunden (Relationen), was
+es möglich macht, Daten aus verschiedenen Tabellen auf Nachfrage zu
+kombinieren. Der SQL-Teil von MySQL steht für "Structured Query
+Language" (strukturierte Abfragesprache) - die verbreitetste
+standardisierte Sprache für Datenbankzugriffe.
+
+@cindex Relationale Datenbanken, Definition
+@cindex SQL, Definition
+@item MySQL ist Open-Source-Software.
+
+Open Source bedeutet, dass es für jeden möglich ist, solche Software zu
+benutzen und zu verändern. Jeder kann MySQL aus dem Internet herunter
+laden und benutzen, ohne irgend etwas zu bezahlen. Jeder, der daran
+interessiert ist, kann den Quelltext studieren und den eigenen
+Bedürfnissen entsprechend verändern. MySQL benutzt die GPL (GNU
+General Public License) @uref{http://www.gnu.org}, um festzulegen, was
+Sie mit der Software tun dürfen und was Sie nicht tun dürfen, abhängig
+von unterschiedlichen Situationen. Wenn Ihnen die GPL Probleme bereitet
+oder wenn Sie MySQL in eine kommerzielle Anwendung einbetten müssen,
+können Sie eine kommerziell lizensierte Version von uns erwerben.
+
+@cindex Open Source, Definition
+@cindex General Public License
+
+@item Warum sollten Sie MySQL benutzen?
+
+MySQL ist sehr schnell, zuverlässig und leicht zu benutzen. Wenn Sie
+nach diesen Eigenschaften suchen, sollten Sie MySQL ausprobieren. MySQL
+besitzt eine ganze Reihe praktischer Features, die in enger Kooperation
+mit unseren Benutzern entwickelt wurden. Einen Performance-Vergleich
+zwischen MySQL und einigen anderen Datenbank-Managementsystemen finden
+Sie auf unserer Benchmark-Seite.
+@xref{MySQL Benchmarks}.
+
+MySQL wurde ursprünglich entwickelt, um sehr große Datenbanken
+handhaben zu können, und zwar sehr viel schneller als existierende
+Lösungen. Es wurde mehrere Jahre in höchst anspruchsvollen
+Produktionsumgebungen eingesetzt. Heutzutage bietet MySQL eine
+umfangreiche Reihe sehr nützlicher Funktionen. Connectivity,
+Geschwindigkeit und Sicherheit machen MySQL äußerst geeignet, um auf
+Datenbanken über das Internet zuzugreifen.
+
+@item Die technischen Features von MySQL
+
+Weiter führende technische Informationen finden Sie unter
+@ref{Reference}. MySQL ist ein Client-Server-System, das aus einem
+multi-thread SQL-Server besteht, der unterschiedliche Backends,
+verschiedene Client-Programme und -Bibliotheken, Verwaltungswerkzeuge
+und etliche Programmschnittstellen unterstützt.
+
+Wir stellen MySQL auch als multi-thread Bibliothek zur Verfügung, die
+Sie mit Ihren Anwendungen verknüpfen können, um ein kleineres,
+schnelleres und leichter zu bedienendes Produkt zu erhalten.
+
+@item MySQL stellt beigesteuerte (contributed) Software in großer Menge
+zur Verfügung.
+
+Es ist sehr wahrscheinlich, dass Ihre Lieblingsanwendung oder -sprache
+bereits MySQL unterstützt.
+
+@end table
+
+@cindex Aussprache, MySQL
+@cindex MySQL, Aussprache
+@cindex Ziele von MySQL
+Offiziell wird MySQL 'Mai Ess Ku Ell' ausgesprochen (nicht 'Mai
+Siekwel'). Wir vermeiden allerdings, Leute zu korrigieren, die
+Mai-Siekwel sagen.
+
+@cindex MySQL-Geschichte
+@cindex Geschichte von MySQL
+@cindex MySQL, Name
+@cindex My, Ursprung
+
+Wir fingen ursprünglich mit der Intention an, den @code{mSQL}-Code zu
+benutzen, um unsere eigenen Tabellen anzusprechen, wobei wir unsere
+eigenen schnellen Low-Level-Routinen (ISAM) benutzten. Nach einigem
+Testen gelangten wir allerdings zur Überzeugung, dass @code{mSQL} weder
+schnell noch flexibel genug wäre, um unsere Anforderungen abzudecken.
+Dies resultierte in einer neuen SQL-Schnittstelle zu unserer Datenbank,
+allerdings mit fast derselben API-Schnittstelle, wie sie @code{mSQL}
+benutzt. Diese API wurde gewählt, weil sie es erlaubte, Code von
+Drittanbietern einfach zu portieren. Die Entstehung des Namens MySQL ist
+nicht völlig geklärt. Unser Basis-Verzeichnis und eine große Anzahl
+unserer Bibliotheken und Werkzeuge hatten immer schon das Präfix ``my''
+während mehr als 10 Jahren. Wie auch immer, auch Montys Tochter (einige
+Jahre jünger) heißt My. Welcher der beiden Umstände MySQL den Namen
+gab, ist immer noch ein Rätsel, sogar für uns.
+
+
+@menu
+* Features::
+* Stability::
+* Table size::
+* Year 2000 compliance::
+@end menu
+
+@node Features, Stability, What-is, What-is
+@c German node Features
+@subsection Die wichtigsten Features von MySQL
+
+@cindex Haupt-Features von MySQL
+@cindex Features von MySQL
+
+Die folgende Liste beschreibt einige wichtige Charakteristika von MySQL:
+
+@c This list is too technical und should be divided into one feature
+@c list comparable to commercial competition und a very technical on
+@c with max limits (from crash-me) und so on.
+@itemize @bullet
+@item
+Voll multi-thread unter Benutzung von Kernel-Threads. Das bedeutet, dass
+Sie sehr einfach mehrere Prozessoren benutzen können, falls verfügbar.
+
+@item
+C-, C++-, Eiffel-, Java-, Perl-, PHP-, Python- und Tcl-APIs. @xref{Clients}.
+
+@item
+Läuft auf vielen verschiedenen Plattformen. @xref{Which OS}.
+
+@item
+Viele Spaltentypen: vorzeichenbehaftete / vorzeichenlose Ganzzahlen
+(Integer), die 1, 2, 3, 4 und 8 Byte lang sind, @code{FLOAT},
+@code{DOUBLE}, @code{CHAR}, @code{VARCHAR}, @code{TEXT}, @code{BLOB},
+@code{DATE}, @code{TIME}, @code{DATETIME}, @code{TIMESTAMP},
+@code{YEAR}, @code{SET}, und @code{ENUM} Typen.
+@xref{Column types}.
+
+@item
+Sehr schnelle Joins durch Benutzung eines optimierten Multi-Joins in
+einem Durchgang (one-sweep multi-join).
+
+@item
+Volle Operator- und Funktionsunterstützung in @code{SELECT}- und
+@code{WHERE}-Teilen von Anfragen. Beispiel:
+
+@example
+mysql> SELECT CONCAT(vorname, " ", nachname) FROM tabellen_name
+ WHERE einkommen/dependents > 10000 AND age > 30;
+@end example
+
+@item
+SQL-Funktionen sind durch eine hoch optimierte Klassenbibliothek
+implementiert und sollten so schnell sein, wie es geht! Üblicherweise
+gibt es überhaupt keine Speicherzuordnung (memory allocation) nach der
+Initialisierung von Anfragen.
+
+@item
+Volle Unterstützung für SQL-@code{GROUP BY} und @code{ORDER BY}-
+Klauseln. Unterstützung für Gruppierungsfunktionen (@code{COUNT()},
+@code{COUNT(DISTINCT ...)}, @code{AVG()}, @code{STD()}, @code{SUM()},
+@code{MAX()} und @code{MIN()}).
+
+@item
+Unterstützung für @code{LEFT OUTER JOIN} und @code{RIGHT OUTER JOIN} mit
+ANSI-SQL und ODBC-Syntax.
+
+@item
+Sie können Tabellen aus unterschiedlichen Datenbanken in ein und
+derselben SQL-Anfrage benutzen (ab Version 3.22).
+
+@item
+Ein System von Zugriffsberechtigungen und Passwörtern, das sehr flexibel
+und sicher ist, und das Host-basierende Verifizierung erlaubt.
+Passwörter sind sicher, weil jeder Passwort-Verkehr verschlüsselt wird,
+wenn Sie sich mit einem Server verbinden.
+
+@item
+ODBC (Open-DataBase-Connectivity) Unterstützung für Win32 (mit
+Quelltext). Alle ODBC 2.5 Funktionen und viele weitere. Sie können zum
+Beispiel MS Access benutzen, um sich mit Ihrem MySQL-Server zu
+verbinden. @xref{ODBC}.
+
+@item
+Sehr schnelle B-tree disk Tabellen mit Index-Kompression.
+
+@item
+Bis zu 32 Indexe pro Tabelle erlaubt. Jeder Index kann aus 1 bis 16
+Spalten oder Teilen von Spalten bestehen. Die maximale Indexlänge
+beträgt 500 Bytes (das ändert sich evtl., wenn MySQL kompiliert wird).
+Ein Index kann das Präfix eines @code{CHAR}- oder @code{VARCHAR}-Felds
+benutzen.
+
+@item
+Datensätze fester und variabler Länge.
+
+@item
+Im Arbeitsspeicher gehaltene Hash-Tabellen, die als temporäre Tabellen
+benutzt werden.
+
+@item
+Kann große Datenbanken handhaben. Wir selbst benutzen MySQL bei einigen
+Datenbanken, die 50 Mio. Datensätze haben und wir kennen Benutzer, die
+MySQL mit 60.000 Tabellen und etwa 5 Milliarden Zeilen benutzen.
+
+@item
+Alle Spalten können Vorgabewerte (Defaults) haben. Sie können @code{INSERT}
+benutzen, um eine Untermenge der Tabellenspalten mit Werten zu
+bestücken. Diejenigen Spalten, die nicht explizit angesprochen werden,
+werden auf ihre Vorgabewerte gesetzt.
+
+@item
+Benutzt GNU Automake, Autoconf und Libtool aus Portabilitätsgründen.
+
+@item
+Geschrieben in C und C++. Getestet mit großen Anzahl verschiedener
+Compiler.
+
+@item
+Ein sehr schnelles Thread-basierendes Speicherzuordnungs-System (memory
+allocation system).
+
+@item
+Keine Speicherlecks (memory leaks). MySQL wurde mit Purify getestet,
+einem kommerziellen Werkzeug zur Entdeckung von Speicherlecks.
+
+@item
+Beinhaltet @code{myisamchk}, ein sehr schnelles Dienstprogramm zur Überprüfung,
+Optimierung und Reparatur von Tabellen. Die gesamte Funktionalität von
+@code{myisamchk} steht auch über die SQL-Schnittstelle zur Verfügung.
+@xref{MySQL Database Administration}.
+
+@item
+Volle Unterstützung für mehrere unterschiedliche Zeichensätze, incl. ISO-
+8859-1 (Latin1), big5, ujis und weitere. So sind zum Beispiel die
+skandinavischen Zeichen `@ringaccent{a}', `@"a' und `@"o' in Tabellen-
+und Spaltennamen erlaubt.
+
+@item
+Alle Daten werden mit dem ausgewählten Zeichensatz gespeichert. Alle
+Vergleiche für normale Zeichenkettenvergleiche sind unabhängig von
+Groß- und Kleinschreibung.
+
+@item
+Die Sortierung ist abhängig vom gewählten Zeichensatz (schwedisch als
+Vorgabe). Das kann beim Start des MySQL-Servers geändert werden. Um
+beispielsweise eine sehr fortgeschrittene Sortierung zu sehen, sehen Sie
+sich den tschechischen Sortier-Code an. MySQL unterstützt viele
+unterschiedliche Zeichensätze, die bei der Kompilierung und während der
+Laufzeit festgelegt werden können. Der neue Zeichensatz 'latin_de' sorgt
+für eine korrekte deutsche Sortierreihenfolge.
+
+@item
+Aliase auf Tabellen und Spalten sind erlaubt, wie im SQL92-Standard
+festgelegt.
+
+@item
+@code{DELETE}, @code{INSERT}, @code{REPLACE} und @code{UPDATE} geben die
+Anzahl der Zeilen zurück, die geändert wurden (bzw. betroffen sind). Es
+ist statt dessen auch möglich, die Anzahl der übereinstimmenden Zeilen
+zurückzugeben, indem beim Verbindungsstart zum Server ein entsprechendes
+Flag gesetzt wird.
+
+@item
+Funktionsnamen kollidieren nicht mit Tabellen- oder Spaltennamen.
+@code{ABS} zum Beispiel ist ein gültiger Spaltenname. Die einzige
+Einschränkung besteht drin, dass in einem Funktionsaufruf keine
+Leerzeichen zwischen Funktionsname und der öffnenden runden Klammer, die
+diesem folgt @samp{(}, erlaubt ist. @xref{Reserved words}.
+
+@item
+Alle MySQL-Programme können mit der @code{--help} oder @code{-?} Option
+aufgerufen werden, um Online-Hilfe zu erhalten.
+
+@item
+Der Server kann Clients Fehlermeldungen in verschiedenen Sprachen zur
+Verfügung stellen.
+@xref{Languages}.
+
+@item
+Clients können sich mit dem MySQL-Server über TCP/IP Sockets,
+Unix Sockets (Unix) oder Named Pipes (NT) verbinden.
+
+@item
+Der MySQL-spezifische @code{SHOW}-Befehl kann benutzt werden, um
+Informationen über Datenbanken, Tabellen und Indexe zu erhalten. Der
+@code{EXPLAIN}-Code kann benutzt werden um festzustellen, wie der
+Optimierer eine Anfrage auflöst.
+@end itemize
+
+
+@node Stability, Table size, Features, What-is
+@c German node Stabilität
+@subsection Wie stabil ist MySQL?
+
+@cindex Stabilität
+
+Dieser Abschnitt beschäftigt sich mit den Fragen ``Wie stabil ist
+MySQL?'' und ``Kann ich mich auf MySQL bei diesem Projekt verlassen?''
+Wir werden versuchen, einige Dinge klar zu stellen und einige der
+wichtigeren Fragen zu beantworten, die offensichtlich viele Leute
+beschäftigen. Dieser Abschnitt wurde aus Informationen zusammen
+gestellt, die aus der Mailing-Liste gesammelt wurden (die sehr aktiv
+beim Berichten von Bugs ist).
+
+Bei TcX funktioniert MySQL ohne jegliche Probleme in unseren Projekten
+seit Mitte 1996. Als MySQL einer breiteren Öffentlichkeit zugänglich
+gemacht wurde, fiel uns auf, dass es einige Teile von ``ungetestetem
+Code'' gab, die schnell von neuen Benutzern gefunden wurden, die
+Anfragen machten, die von unseren eigenen abwichen. Seitdem hat jedes
+neue Release weniger Portabilitätsprobleme als das vorhergehende (obwohl
+jedes viele neue Features hat).
+
+Jedes Release von MySQL war benutzbar. Probleme gab es nur, wenn
+Benutzer anfingen, Code aus den ``Grauzonen'' zu benutzen. Natürlich
+wissen Benutzer von ausserhalb nicht, was diese Grauzonen sind, daher
+versucht dieser Abschnitt, die momentan bekannten aufzuzeigen. Die
+Beschreibungen hier beziehen sich auf Version 3.23 von MySQL. Alle
+bekannten und berichteten Bugs werden in der letzten Version behoben,
+mit Ausnahme der Bugs, die im Bugs-Abschnitt aufgelistet sind, was Dinge
+sind, die auf das Design zurückzuführen sind. @xref{Bugs}.
+
+MySQL ist in mehrfachen Ebenen (Layers) und verschiedenen unabhängigen
+Modulen geschrieben. Diese Module sind im Folgenden aufgeführt, wobei
+angezeigt wird, wie gut getestet jedes von ihnen ist:
+
+@cindex Module, Auflistung
+
+@table @strong
+@item Der ISAM Tabellen-Handler --- stabil
+Dieser verwaltet Speicherung und Abfrage aller Daten in MySQL Version
+3.22 und früher. In allen Releases von MySQL gab es nicht einen einzigen
+(berichteten) Bug in diesem Code. Die einzige Möglichkeit, eine
+zerstörte (korrumpierte) Tabelle zu erhalten, besteht darin, den Server
+mitten während eines Updates zu killen. Selbst dadurch ist es
+unwahrscheinlich, dass Daten unwiederbringlich zerstört werden, denn
+alle Daten werden zwischen Anfragen auf die Festplatte zurück
+geschrieben (flush). Es hat nicht einen einzigen Bug-Bericht gegeben, in
+dem von verlorenen Daten aufgrund von MySQL-Bugs berichtet wurde.
+
+@cindex ISAM-Tabellen-Handler
+@cindex Speicherung, Daten
+@cindex Abfrage, Daten
+@cindex Daten, ISAM-Tabellen-Handler
+
+@item Der MyISAM Tabellen-Handler --- stabil
+Dieser wurde in MySQL Version 3.23 hinzu gefügt. Er basiert zum großen
+Teil auf dem ISAM Tabellen-Code, hat aber eine Menge neuer und sehr
+nützlicher Features.
+
+@item Der Parser und lexikalische Analysator --- stabil
+Es hat seit sehr langer Zeit keinen einzigen berichteten Bug in diesem
+System gegeben.
+
+@item Der C Client-Code --- stabil
+Keine bekannten Probleme. Im frühen 3.20 Release gab es einige
+Einschränkungen hinsichtlich der Größe des Sende- / Empfangs-Puffers
+(buffer size). Ab Version 3.21 ist die Puffergröße jetzt dynamisch, bis
+zu einem Vorgabewert von 16 M.
+
+@item Standard-Client-Programme --- stabil
+Dies beinhaltet @code{mysql}, @code{mysqladmin}, @code{mysqlshow},
+@code{mysqldump} und @code{mysqlimport}.
+
+@item Basis-SQL --- stabil
+Die grundlegenden SQL-Funktionen, Zeichenketten-Klassen und dynamisches
+Speicher-Handling. Nicht ein einziger berichteter Bug in diesem System.
+
+@item Anfragen-Optimierer (Query optimizer) --- stabil
+
+@item Bereichs-Optimierer (Range optimizer) --- stabil
+
+@item Join-Optimierer (Join optimizer) --- stabil
+
+@item Sperren (Locking) --- Gamma
+Dies ist sehr system-abhängig. Auf einigen Systemen gibt es große
+Probleme, wenn Standard-Betriebssystem-Sperren verwendet wird
+(@code{fcntl()}). In solchen Fällen sollten Sie den MySQL-Daemon mit dem
+Flag @code{--skip-locking} laufen lassen. Bekannt ist, dass solche
+Probleme auf manchen Linux-Systemen vorkommen sowie auf SunOS, wenn NFS-
+gemountete Dateisysteme verwendet werden.
+
+@item Linux-Threads --- stabil
+Das hauptsächliche Problem fand sich im @code{fcntl()}-Aufruf, der durch
+Benutzung der @w{@code{--skip-locking}}-Option bei @code{mysqld} behoben
+werden kann. Einige Leute haben Lockup-Probleme mit Version 0.5
+berichtet. Linux-Threads müssen rekompiliert werden, wenn Sie mehr als
+1000 gleichzeitige Verbindungen benutzen wollen. Obwohl es möglich ist,
+so viele Verbindungen mit den vorgabemäßigen Linux-Threads laufen zu
+lassen (obwohl man nie über 1021 kommen wird), macht das vorgabemäßige
+Stack-Spacing von 2 MB die Applikation unstabil, und wir konnten einen
+Coredump reproduzieren, nachdem 1021 Verbindungen im Leerlauf (idle
+connections) hergestellt wurden. @xref{Linux}.
+
+@item Solaris 2.5+ pthreads --- stabil
+Wir benutzen dies für unsere gesamte Produktionsarbeit.
+
+@item MIT-pthreads (andere Systeme) --- stabil
+Seit Version 3.20.15 gab es keine berichteten Bugs mehr, und keine
+bekannten Bugs seit Version 3.20.16. Auf einigen Systemen gibt es ein
+``Misfeature'', das heißt einige Operationen sind recht langsam (1/20
+Sekunde Schlafzyklus zwischen jeder Anfrage). Natürlich können MIT-
+Threads alles ein bisschen verlangsamen, aber Index-basierende
+@code{SELECT}-Statements werden üblicherweise in einem Zeit-Frame
+ausgeführt, also sollte es kein mutex locking/thread juggling geben.
+
+@item Andere Thread-Implementierungen --- Beta - Gamma
+Die Ports zu anderen Systemen sind noch sehr neu und können Bugs haben,
+möglicherweise auch in MySQL, aber in den meisten Fällen in der Thread-
+Implementierung selbst.
+
+@item @code{LOAD DATA ...}, @code{INSERT ... SELECT} --- stabil
+Einige Leute dachten, hier Bugs gefunden zu haben, aber üblicherweise
+haben sich diese als Missverständnisse heraus gestellt. Bitte sehen Sie
+zuerst im Handbuch nach, bevor Sie Bugs berichten!
+
+@item @code{ALTER TABLE} --- stabil
+Einige Änderungen in Version 3.22.12.
+
+@item DBD --- stabil
+Wird jetzt von Jochen Wiedmann gewartet
+(@email{wiedmann@@neckar-alb.de}). Danke!
+
+@item @code{mysqlaccess} --- stabil
+Geschrieben und gewartet von Yves Carlier
+(@email{Yves.Carlier@@rug.ac.be}). Danke!
+
+@item @code{GRANT} --- stabil
+große Änderungen in MySQL Version 3.22.12.
+
+@item @strong{MyODBC} (benutzt ODBC SDK 2.5) --- Gamma
+Scheint mit einigen Programmen gut zu laufen.
+
+@item Replikation -- Beta / Gamma
+Wir arbeiten noch an der Replikation, also erwarten Sie nicht, dass
+diese schon felsenfest steht. Auf der anderen Seite benutzen MySQL-
+Benutzer diese bereits mit guten Resultaten.
+
+@item BDB-Tabellen -- Beta
+Der Berkeley-Datenbank-Code ist sehr stabil, aber wir verbessern immer
+noch die Schnittstelle zwischen MySQL und BDB-Tabellen, also wird es
+einige Zeit dauern, bevor dies so gut wie andere Tabellentypen getestet
+ist.
+
+@item InnoDB-Tabellen -- Beta
+Diese wurden @code{MySQL} kürzlich hinzu gefügt. Sie scheinen gut zu
+funktionieren und können nach einigen anfänglichen Tests benutzt werden.
+
+@item Automatische Wiederherstellung von MyISAM-Tabellen - Beta
+Dies betrifft nur den neuen Code, der beim Öffnen einer Tabelle
+nachsieht, ob diese korrekt geschlossen wurde und ein automatisches
+Überprüfen / Reparieren der Tabelle ausführt, falls das nicht der Fall
+war.
+
+@item MERGE-Tabellen -- Beta / Gamma
+Die Benutzung von Schlüsseln bei @code{MERGE}-Tabellen ist noch nicht
+sehr ausgetestet. Der restliche Teile des @code{MERGE}-Codes ist recht
+gut getestet.
+
+@item FULLTEXT -- Beta
+Textsuche scheint zu funktionieren, wird aber noch nicht viel
+eingesetzt.
+
+@end table
+
+MySQL AB stellt E-Mail-Support für zahlende Kunden bereit, aber die
+MySQL-Mailingliste bietet üblicher Weise Antworten für die meisten
+Fragen. Bugs werden meist direkt mit einem Patch behoben; für
+schwerwiegende Bugs gibt es fast immer ein neues Release.
+
+
+@node Table size, Year 2000 compliance, Stability, What-is
+@c German node Tabellengröße
+@subsection Wie groß können MySQL-Tabellen sein?
+
+@cindex Tabellen, maximale Größe
+@cindex Größe von Tabellen
+@cindex Betriebssysteme, Dateigrößen-Beschränkungen
+@cindex Beschränkungen, Dateigröße
+@cindex Dateien, Dateigröße
+
+MySQL Version 3.22 hat eine Begrenzung auf 4G bei der Tabellengröße.
+Mit dem neuen @code{MyISAM} in MySQL Version 3.23 wurde die maximale
+Tabellengröße auf 8 Millionen Terabytes (2 ^ 63 bytes) hochgeschraubt.
+
+Beachten Sie allerdings, dass Betriebssysteme ihre eigenen Dateigrößen-
+Beschränkungen haben. Hier sind einige Beispiele:
+
+@multitable @columnfractions .5 .5
+@item @strong{Betriebssystem} @tab @strong{Dateigrößen-Beschränkung}
+@item Linux-Intel 32 bit @tab 2G, 4G oder mehr, abhängig von der Linux-Version
+@item Linux-Alpha @tab 8T (?)
+@item Solaris 2.5.1 @tab 2G (möglich sind 4G mit Patch)
+@item Solaris 2.6 @tab 4G
+@item Solaris 2.7 Intel @tab 4G
+@item Solaris 2.7 ULTRA-SPARC @tab 8T (?)
+@end multitable
+
+Auf Linux 2.2 kann man größere Tabellen als 2G benutzen, wenn man den
+LFS-Patch für das ext2 Dateisystem benutzt. Auf Linux 2.4 existiert
+zusätzlich ein Patch für das ReiserFS, um Unterstützung für große
+Dateien zu erhalten.
+
+Letztlich wird die Tabellengröße für MySQL normalerweise durch das
+Betriebssystem begrenzt.
+
+Vorgabemäßig haben MySQL-Tabellen eine maximale Größe von etwa 4G. Sie
+können die maximale Tabellengröße für eine Tabelle mit dem @code{SHOW
+TABLE STATUS}-Befehl überprüfen oder mit @code{myisamchk -dv
+tabellen_name}. @xref{SHOW}.
+
+Wenn Sie größere Tabellen als 4G benötigen (und Ihr Betriebssystem dies
+unterstützt), sollten Sie die @code{AVG_ROW_LENGTH}- und
+@code{MAX_ROWS}-Parameter benutzen, wenn Sie Ihre Tabelle anlegen.
+@xref{CREATE TABLE}. Sie können diese auch später setzen, mit
+@code{ALTER TABLE}. @xref{ALTER TABLE}.
+
+Falls auf Ihre große Tabelle nur mit Lesezugriff zugegriffen wird
+(read-only), können Sie auch @code{myisampack} benutzen, um mehrere
+Tabellen zu vereinen (merge) und sie zu einer zu komprimieren.
+@code{myisampack} komprimiert eine Tabelle üblicherweise mindestens um
+50%, also können Sie effektiv viel größere Tabellen benutzen.
+@xref{myisampack, ,@code{myisampack}}.
+
+Sie können die Dateibegrenzung des Betriebssystems für @code{MyISAM}
+Daten-Dateien umgehen, indem Sie die @code{RAID}-Option benutzen.
+@xref{CREATE TABLE}.
+
+Eine weitere Lösung kann die MERGE-Bibliothek darstellen, die Ihnen
+erlaubt, eine Sammlung identischer Tabellen zugleich zu benutzen.
+@xref{MERGE, MERGE tables}.
+
+
+@node Year 2000 compliance, , Table size, What-is
+@c German node Jahr-2000-Konformität
+@subsection Jahr-2000-Konformität
+
+@cindex Jahr-2000-Konformität
+@cindex Kompatibilität, Y2K, Jahr 2000
+@cindex Datumsfunktionen, Y2K, Jahr-2000-Konformität
+
+MySQL selbst hat keine Probleme mit der Jahr-2000-Konformität:
+
+@itemize @bullet
+@item
+MySQL benutzt Unix-Zeitfunktionen und hat keine Probleme mit
+Datumsangaben bis @code{2069}. Alle zweistelligen Jahresangaben werden
+als Angaben zwischen @code{1970} und @code{2069}, betrachtet, was
+bedeutet, dass, wenn Sie @code{01} in einer Spalte speichern, MySQL dies
+als @code{2001} behandelt.
+
+@item
+Alle MySQL Datumsfunktionen sind in einer Datei @file{sql/time.cc}
+gespeichert und sehr sorgfältig kodiert, um Jahr-2000-sicher zu sein.
+
+@item
+In MySQL Version 3.22 und später kann der neue Spaltentyp @code{YEAR}
+Jahre @code{0} und von @code{1901} bis @code{2155} in 1 Byte speichern
+und sie mit 2 oder 4 Ziffern anzeigen.
+@end itemize
+
+Probleme können Sie bekommen, wenn Sie MySQL mit Applikationen benutzen,
+die MySQL auf eine Art benutzen, die nicht Jahr-2000-sicher ist. Zum
+Beispiel speichern oder ändern viele alte Applikationen Jahresangaben,
+indem sie zweistellige Werte benutzen (was mehrdeutig ist), anstatt
+vierstellige Werte zu nehmen. Dieses Problem kann durch Applikationen
+verschlimmert werden, die Werte wie @code{00} oder @code{99} als Anzeiger
+``fehlender'' Werte benutzen.
+
+Leider sind diese Probleme möglicherweise schwer zu beheben, weil
+verschiedene Applikationen von unterschiedlichen Programmierern
+geschrieben sein können, von denen jeder einen anderen Satz von
+Konventionen und Funktionen benutzt haben kann, was die Handhabung von
+Datumsangaben betrifft.
+
+Hier ist eine einfache Demonstration, die zeigt, dass MySQL keine
+Probleme mit Datumsangaben bis zum Jahr 2030 hat:
+
+@example
+mysql> DROP TABLE IF EXISTS y2k;
+Query OK, 0 rows affected (0.01 sec)
+
+mysql> CREATE TABLE y2k (date date, date_time datetime, time_stamp timestamp);
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> INSERT INTO y2k VALUES
+ -> ("1998-12-31","1998-12-31 23:59:59",19981231235959),
+ -> ("1999-01-01","1999-01-01 00:00:00",19990101000000),
+ -> ("1999-09-09","1999-09-09 23:59:59",19990909235959),
+ -> ("2000-01-01","2000-01-01 00:00:00",20000101000000),
+ -> ("2000-02-28","2000-02-28 00:00:00",20000228000000),
+ -> ("2000-02-29","2000-02-29 00:00:00",20000229000000),
+ -> ("2000-03-01","2000-03-01 00:00:00",20000301000000),
+ -> ("2000-12-31","2000-12-31 23:59:59",20001231235959),
+ -> ("2001-01-01","2001-01-01 00:00:00",20010101000000),
+ -> ("2004-12-31","2004-12-31 23:59:59",20041231235959),
+ -> ("2005-01-01","2005-01-01 00:00:00",20050101000000),
+ -> ("2030-01-01","2030-01-01 00:00:00",20300101000000),
+ -> ("2050-01-01","2050-01-01 00:00:00",20500101000000);
+Query OK, 13 rows affected (0.01 sec)
+Records: 13 Duplicates: 0 Warnings: 0
+
+mysql> SELECT * FROM y2k;
++------------+---------------------+----------------+
+| date | date_time | time_stamp |
++------------+---------------------+----------------+
+| 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 |
+| 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 |
+| 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 |
+| 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 |
+| 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 |
+| 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 |
+| 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 |
+| 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 |
+| 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 |
+| 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 |
+| 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 |
+| 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 |
+| 2050-01-01 | 2050-01-01 00:00:00 | 00000000000000 |
++------------+---------------------+----------------+
+13 rows in set (0.00 sec)
+
+@end example
+
+Das zeigt, dass die @code{DATE}- und @code{DATETIME}-Typen für zukünftige
+Datumsangaben keine Probleme bereiten werden (sie handhaben Datumsangaben
+bis zum Jahr 9999).
+
+Der @code{TIMESTAMP}-Typ, der zur Speicherung der aktuellen Zeit benutzt
+wird, hat nur einen Bereich bis zu @code{2030-01-01}. @code{TIMESTAMP} hat
+einen Bereich von @code{1970} bis @code{2030} auf 32-Bit-Maschinen
+(vorzeichenbehafteter Wert). Auf 64-Bit-Maschinen handhabt dieser
+Spaltentyp bis zu @code{2106} (vorzeichenloser Wert).
+
+Obwohl MySQL Jahr-2000-kompatibel ist, sind Sie dafür verantwortlich,
+mehrdeutige Eingaben zu vermeiden. Siehe @ref{Year 2000 compliance} wegen
+der Regeln, die MySQL anwendet, wenn mehrdeutige Datumsangaben gemacht
+werden (Datumsangaben, die zweistellige Jahreswerte verwenden).
+
+
+
+@node What is MySQL AB, Licensing and Support, What-is, Deutsch
+@c German node Was ist MySQL AB?
+@section Was ist MySQL AB?
+
+@cindex MySQL AB, Definition
+
+@code{MySQL AB} ist das Unternehmen der MySQL Gründer und Hauptentwickler.
+MySQL AB wurde ursprünglich in Schweden von David Axmark, Allan Larsson
+und Michael @code{Monty} Widenius gegründet.
+
+Alle Entwickler des MySQL Servers sind Angestellte dieses Unternehmens.
+Wir sind eine virtuelle Firma mit Mitarbeitern, die über die ganze Welt
+verstreut in aller Herren Länder sitzen. Der Hauptteil unserer Kommunikation
+untereinander, mit unseren Anwendern, Unterstützern und Partnern wird über
+das Internet abgewickelt
+
+Wir haben uns der Entwicklung und Verbreitung des MySQL Datenbankservers
+verschrieben. MySQL hält das Copyright der MySQL Quelltexte, des MySQL Logos
+und dieses Handbuchs.. @xref{What-is}.
+
+
+Die MySQL-Kernwerte zeigen unsere Verpflichtung gegenüber MySQL und Open
+Source.
+
+Wir wollen, dass MySQL folgendes ist:
+
+@itemize @bullet
+@item
+Die beste und meist benutzte Datenbank der Welt.
+@item
+Verfügbar für alle. Alle sollen sich MySQL leisten können.
+@item
+Leicht zu benutzen.
+@item
+Kontinuierlich verbessert, trotzdem immer schnell und sicher bleibend.
+@item
+Es soll Spass machen, MySQL zu benutzen und zu verbessern.
+@item
+Frei von Bugs.
+@end itemize
+
+
+MySQL AB und die Leute von MySQL AB:
+
+@itemize @bullet
+@item
+Verbreiten die Open-Source-Philosophie und unterstützen die
+Open-Source-Community.
+@item
+Bemühen sich, gute Bürger zu sein.
+@item
+Bevorzugen Partner, die unsere Werte und unsere Geisteshaltung teilen.
+@item
+Beantworten Mail und geben Support.
+@item
+Sind ein virtuelles Unternehmen, das mit anderen im Netzwerk
+zusammenarbeitet (networking).
+@item
+Arbeiten gegen Software-Patente.
+@end itemize
+
+@menu
+* MySQL AB business model and services::
+@end menu
+
+@node MySQL AB business model and services, , What is MySQL AB, What is MySQL AB
+@c German node MySQL AB Geschäftsmodell und Services
+@subsection Geschäftsmodell und Dienstleistungen von MySQL AB
+
+Eine der uns häufig gestellten Fragen ist: Wie kann man von etwas leben,
+das man kostenlos abgibt? Hier ist die Antwort:
+MySQL AB verdient Geld mit Support, Dienstleistungen, kommerziellen
+Lizenzen und Lizenzgebühren, das wir dazu verwenden, die
+Produktentwicklung zu finanzieren und die MySQL-Geschäftsfelder
+auszubauen.
+
+
+Unser Unternehmen läuft seit der Gründung profitabel. Im Oktober 2001
+akzeptierten wir eine Risikokapitalfinanzierung durch führende
+skandinavische Investoren und eine Handvoll Business-Angels. Die
+Investitionen werden genutzt, um unser Geschäftsmodell auf solide Füße
+zu stellen und eine Grundlage für nachhaltiges Wachstum zu schaffen.
+
+@menu
+* Business Services Support::
+* Business Services Training::
+* Business Services Consulting::
+* Business Services Commercial licenses::
+* Business Services Partnering::
+* Business Services Advertising::
+* Contact information::
+@end menu
+
+@node Business Services Support, Business Services Training, MySQL AB business model and services, MySQL AB business model and services
+@c German node Business Services Support
+@subsubsection Support
+
+MySQL AB gehört den Gründern und Haupt-Entwicklern der MySQL-Datenbank
+und wird von ihnen betrieben. Die Entwickler fühlen sich verpflichtet,
+Kunden und anderen Benutzern Support zu bieten, um mit deren
+Bedürfnissen und Problemen in Kontakt zu bleiben. Unser gesamter Support
+wird durch qualifizierte Entwickler geleistet. Wirklich schwierige
+Fragen werden von Michael @code{Monty} Widenius beantwortet, der der
+erste Entwickler des MySQL-Servers ist. @xref{Support}.
+
+Um Support unterschiedlicher Grade zu bestellen, besuchen Sie bitte die
+Bestellseite unter @uref{https://order.mysql.com/}. Wenn Sie nur
+beschränkten Zugriff auf das Internet haben, setzen Sie sich bitte mit
+unserem Vertrieb unter @email{sales@@mysql.com} in Verbindung.
+
+@node Business Services Training, Business Services Consulting, Business Services Support, MySQL AB business model and services
+@c German node Business Services Training
+@subsubsection Training und Zertifizierung
+
+MySQL AB führt Schulungen zu MySQL und verwandten Themen weltweit durch.
+Wir bieten sowohl offene Kurse als auch In-house-Trainings an, die auf
+die speziellen Bedürfnisse Ihres Unternehmens zugeschnitten sind.
+MySQL-Schulungen werden auch durch unsere Partner durchgeführt, die
+Authorised MySQL Training Center.
+
+Unsere Schulungsmaterialien benutzen dieselben Beispiel-Datenbanken wie
+unsere Dokumentation und unsere Beispiel-Applikationen und werden
+ständig aktualisiert, um den Entwicklungsstand der neusten MySQL-Version
+widerzuspiegeln. Unsere Trainer erhalten Rückhalt vom Entwicklungsteam,
+um die Trainingsqualität und die kontinuierliche Entwicklung des
+Schulungsmaterials sicherzustellen. Das stellt auch sicher, dass keine
+während der Kurse aufgetretenen Fragen unbeantwortet bleiben.
+
+Wenn Sie an unseren Schulungen teilnehmen, können Sie sicher sein, die
+Ziele zu erreichen, die Sie mit Ihren MySQL-bezogenen Applikationen
+anstreben. Ausserdem haben Sie folgende Vorteile:
+
+@itemize @bullet
+@item
+Sie sparen Zeit.
+@item
+Sie verbessern die Performance Ihrer Applikation(en).
+@item
+Sie verringern die Notwendigkeit zusätzlicher Hardware, was Kosten
+spart.
+@item
+Sie verbessern Ihre Sicherheit.
+@item
+Sie erhöhen die Zufriedenheit Ihrer Kunden und Mitarbeiter.
+@item
+Sie bereiten sich auf die MySQL-Zertifizierung vor.
+@end itemize
+
+Wenn Sie an unseren Schulungen Interesse als möglicher Teilnehmer oder
+Trainingspartner haben, besuchen Sie bitte die Seite unter
+@uref{http://www.mysql.com/training/}. Wenn Sie nur beschränkten Zugriff
+auf das Internet haben, setzen Sie sich bitte mit unserem
+Trainingspersonal unter @email{training@@mysql.com} in Verbindung.
+
+Die Veröffentlichung des MySQL-Zertifizierungsprogramms ist für 2002
+geplant. Details finden Sie unter
+@uref{http://www.mysql.com/training/certification.html}. Wenn Sie stets
+die neusten Informationen über das MySQL-Zertifizierungsprogramm haben
+wollen, schicken Sie bitte eine E-Mail an
+@email{certification@@mysql.com}.
+
+
+@c German FIX this node entry was missing but the section was there...
+@node Business Services Consulting, Business Services Commercial licenses, Business Services Training, MySQL AB business model and services
+@c German node Business Services Consulting
+@subsubsection Beratung
+MySQL AB und seine authorisierten Partner bieten Benutzern des
+MySQL-Servers und denen, die ihn in ihre Software einbetten wollen,
+Beratungsleistungen, weltweit.
+
+Unsere Berater können Ihnen helfen, Ihre Datenbanken zu entwerfen und zu
+optimieren, effiziente Anfragen zu konstruieren, Ihre Plattform auf
+optimale Performance zu tunen, Migrationsprobleme zu lösen, Replikation
+aufzusetzen, robuste transaktionale Applikationen zu bauen und vieles
+mehr. Wir helfen auch Kunden dabei, den MySQL-Server für den
+Großflächigen Einsatz in ihre Produkte und Applikationen einzubauen.
+
+Unsere Berater arbeiten in enger Kooperation mit unserem
+Entwicklungsteam, was die technische Qualität unserer Dienstleistungen
+sicherstellt. Beratungsaufgaben erstrecken sich von zweitägigen
+Power-Start-Sessions bis zu Projekten, die Wochen und Monate dauern.
+Unsere Kompetenz deckt nicht nur den MySQL-Server ab, sondern auch
+Programmier- und Skripting-Sprachen wie PHP, Perl und andere.
+
+Wenn Sie an unseren Beratungsleistungen interessiert sind oder ein
+Consulting-Partner werden wollen, besuchen Sie bitte unsere Seite unter
+@uref{http://www.mysql.com/consulting/}. Wenn Sie nur beschränkten
+Zugriff auf das Internet haben, setzen Sie sich bitte mit unserem
+Beratungspersonal unter @email{consulting@@mysql.com} in Verbindung.
+
+@node Business Services Commercial licenses, Business Services Partnering, Business Services Consulting, MySQL AB business model and services
+@c German node Business Services Commercial Licenses
+@subsubsection Kommerzielle Lizenzen
+
+Die MySQL-Datenbank wird unter der @code{GNU General Public License}
+veröffentlicht (@code{GPL}). Das bedeutet, dass die MySQL-Software
+kostenlos unter der GPL benutzt werden darf. Wenn Sie nicht an die
+GPL-Bedingungen gebunden sein wollen (was in der Folge bedeutet, dass
+auch Ihre eigenen Applikationen GPL werden), können Sie eine
+kommerzielle Lizenz für dasselbe Produkt unter
+@uref{https://order.mysql.com/} erwerben.
+
+Weil MySQL AB das Copyright am MySQL-Server besitzt, können wir eine
+@code{duale Lizensierung} einsetzen, was heißt, dass dasselbe Produkt
+sowohl unter der GPL als auch unter einer kommerziellen Lizenz
+erhältlich ist. Das berührt in keiner Weise die Verpflichtung von MySQL
+AB gegenüber @code{Open Source}. Wegen Details, wann eine kommerzielle
+Lizenz erforderlich ist, sehen Sie bitte unter
+@ref{Lizenzpolitik} nach.
+
+Wir verkaufen auch kommerzielle Lizenzen von Open-Source-GPL-Software
+Dritter. Ein gutes Beispiel hierfür ist der
+@code{InnoDB}-Tabellen-Handler, der ACID-Unterstützung, Sperren auf
+Zeilenebene, Wiederherstellung nach Abstürzen, Multiversionierung,
+Fremdschlüsselunterstützung und vieles mehr bietet.
+
+@node Business Services Partnering, Business Services Advertising, Business Services Commercial licenses, MySQL AB business model and services
+@c German node Business Services Partnering
+@subsubsection Partnerprogramme
+@cindex Partnerschaft mit MySQL AB
+
+MySQL AB hat ein weltweites Partnerprogramm, dass Schulungskurse,
+Support, Beratung, Lösungen, Publikationen plus Weiterverkauf und
+Vertrieb von MySQL und verwandten Produkten beinhaltet. Partner
+erscheinen unter @uref{http://www.mysql.com/} auf der Website und
+erhalten das Recht, spezielle Versionen der MySQL-Schutzmarken zu
+benutzen, um ihre Produkte zu identifizieren und ihr Geschäft
+voranzutreiben. Wenn Sie interessiert sind, ein MySQL-AB-Partner zu
+werden, schicken Sie bitte eine E-Mail an @email{partner@@mysql.com}.
+
+Das Wort @code{MySQL} und das MySQL-Delphin-Logo sind Schutzmarken von
+MySQL AB. @xref{MySQL AB Logos and Trademarks}.
+
+@node Business Services Advertising, Contact information, Business Services Partnering, MySQL AB business model and services
+@c German node Business Services Advertising
+@subsubsection Werbung
+
+Die MySQL-Website (@uref{http://www.mysql.com/}) ist bei Entwicklern und
+Benutzern beliebt. Im Oktober 2001 bedienten wir 10 Millionen
+Seitenanfragen (PageViews). Unsere Besucher repräsentieren eine Gruppe,
+die Kaufentscheidungen und Empfehlungen sowohl für Software als auch für
+Hardware trifft. 12% unserer Besucher genehmigen Kaufentscheidungen,
+lediglich 9% sind überhaupt nicht an Kaufentscheidungen beteiligt. Mehr
+als 65% haben innerhalb des letzten halben Jahres online eingekauft, 70%
+planen, in den nächsten Monaten einzukaufen. Wenn Sie Interesse haben,
+Werbebanner auf unserer Website @uref{http://www.mysql.com/} zu
+schalten, setzen Sie sich bitte mit @email{advertising@@mysql.com} in
+Kontakt.
+
+@node Contact information, , Business Services Advertising, MySQL AB business model and services
+@c German node Kontaktinformationen
+@subsubsection Kontaktinformationen
+
+@cindex Kontaktinformationen
+@cindex Lizensierung, Kontaktinformationen
+@cindex Werbung, Kontaktinformationen
+@cindex Anstellung, Kontaktinformationen
+@cindex Partnerschaft mit MySQL
+@cindex Anstellung bei MySQL
+@cindex Jobs bei MySQL
+
+Die MySQL Website (@uref{http://www.mysql.com/})
+enthält die neusten Informationen über MySQL und MySQL AB.
+
+Für Presseservice und Anfragen aller Art, die in unseren
+Veröffentlichungen (@uref{http://www.mysql.com/news/}) nicht
+behandelt werden, wenden Sie sich bitte an
+@email{press@@mysql.com}.
+
+Zeitnahe, präzise Antworten auf technische Fragen erhalten Sie, wenn Sie
+unter @uref{https://order.mysql.com/, order} einen unserer
+@uref{http://www.mysql.com/Support/arrangements/types.html,
+Support-Verträge} abschließen.
+MySQL-Support wird von den MySQL-Entwicklern geleistet, weshalb der
+Standard extrem hoch ist.
+
+Informationen über MySQL Trainig erhalten Sie unter
+@uref{http://www.mysql.com/training/}. Wenn Sie einen
+eingeschränkten Internetzugang haben, kontaktieren Sie
+bitte unser Trainingspersonal unter @email{training@@mysql.com}.
+@xref{Business Services Training}.
+
+Für Informationen über das MySQL Zertifizierungsprogramm
+erhalten Sie unter @uref{http://www.mysql.com/training/certification.html}.
+Wenn Sie weiterhin über das MySQL Zertifizierungsprogramm informiert
+werden wollen, schreiben Sie eine E-Mail an @email{certification@@mysql.com}.
+@xref{Business Services Consulting}.
+
+Kommerzielle Lizenzen können online unter @uref{https://order.mysql.com/}
+abgewickelt werden. Dort finden Sie ausserdem Informationen darüber,
+wie Sie ihre Bestellung per Fax erledigen können. Wenn Sie Fragen bezüglich
+der Lizensierung haben, oder Sie ein Angebot über eine größere Lizenzerteilung
+erhalten wollen, füllen Sie bitte Das Kontaktformular auf unserer Website
+(@uref{http://www.mysql.com/}) aus, oder schicken Sie eine E-Mail
+an @email{licensing@@mysql.com} (für Lizenzfragen) oder an
+@email{sales@@mysql.com} (für Verkaufsinformationen).
+@xref{Lizenzpolitik}.
+
+Wenn Sie daran interessiert sind, ein Werbebanner auf unserer Website
+(@uref{http://www.mysql.com/}) zu schalten, schicken Sie bitte
+eine E-Mail an @email{advertising@@mysql.com}.
+@xref{Business Services Advertising}.
+
+Wenn Sie ein Unternehmen vertreten, dass an einer Partnerschaft mit MySQL
+interessiert ist, schicken Sie bitte eine E-Mail an
+@email{partner@@mysql.com}.
+
+Für weitere Informationen über die MySQL Schutzmarkenbestimmungen, beachten
+Sie bitte @uref{http://www.mysql.com/company/trademark.html} oder kontaktieren
+Sie @email{trademark@@mysql.com}.
+@c German FIX changed 'and' to 'und' to make German xref work
+@xref{MySQL AB Logos and Trademarks}.
+
+Wenn Sie an einem der Jobs interessiert sind, die im
+@uref{http://www.mysql.com/development/jobs/, jobs}-Abschnitt aufgeführt
+sind, schicken Sie bitte eine E-Mail an @email{jobs@@mysql.com}. Bitte
+senden Sie ihre CV nicht als Anhang an dieser mail mit, sondern
+fügen Sie sie lieber am Ende ihrer mail als Klartext (plain text) ein.
+
+Allgemeine Diskussionen mit vielen unserer Benutzer können Sie auf den
+entsprechenden @uref{http://www.mysql.com/documentation/lists.html,
+Mailing-Listen} führen.
+
+Fehlerberichte (Auch Bugreporte genannt), sowie Fragen und Kommentare, sollten
+an die Mailingliste @email{mysql@@lists.mysql.com} gehen. Wenn Sie
+ein empfindliches Sicherheitsloch im MySQL Server gefunden haben, sollten
+@c German FIX added . after schreiben and after the xref.
+Sie eine E-Mail an @email{security@@mysql.com} schreiben.
+@xref{Bug reports}.
+
+Wenn Sie Benchmarkergebnis haben, die wir veröffentlichen können, kontaktieren
+Sie uns unter @email{benchmarks@@mysql.com}.
+
+Wenn Sie Vorschläge für Hinzufügungen oder Korrekturen dieses Handbuchs
+haben, schicken Sie sie bitte an das Handbuch-Team:
+@email{docs@@mysql.com}.
+
+Fragen zur Arbeitsweise oder zu Inhalten unserer Website(@uref{http://www.mysql.com/})
+stellen Sie bitte an @email{webmaster@@mysql.com}.
+
+Fragen über das MySQL Portal (@uref{http://www.mysql.com/portal/})
+können an @email{portals@@mysql.com} geschickt werden.
+
+Die Datenschutzbestimmungen von MySQL AB können Sie unter
+@uref{http://www.mysql.com/company/privacy.html} einsehen.
+Für irgendwelche Fragen darüber, wenden Sie sich bitte an
+@email{privacy@@mysql.com}.
+
+Allgemeine Informationsanfragen schicken Sie bitte an @email{info@@mysql.com}.
+
+
+@node Licensing and Support, MySQL 4.0 In A Nutshell, What is MySQL AB, Deutsch
+@c German node Lizensierung and Support
+@section MySQL Support and Lizensierung
+
+@cindex Lizensierungsbedingungen
+@cindex Supportbedingungen
+
+Dieser Abschnitt beschreibt die MySQL Support und Lizensierungsvereinbarungen
+
+
+@menu
+* Support::
+* Copyright::
+* MySQL AB Logos and Trademarks::
+* Lizenzpolitik::
+@end menu
+
+@node Support, Copyright, Licensing and Support, Licensing and Support
+@c German node Support
+@subsection Support den MySQL AB anbietet
+
+@cindex Support, Arten
+@cindex Arten von Support
+@cindex Kommerzieller Support, Arten
+@cindex Kosten, Support
+@cindex Lizensierungskosten
+@cindex Supportkosten
+@cindex Preise, Support
+
+Wir versuchen, technischen Support in einem breiten und umfassenden
+Blickwinkel zu sehen. Fast jedes Problem im Zusammenhang mit
+MySQL-Software ist für uns wichtig, wenn es für Sie wichtig ist.
+Typischerweise suchen Kunden Hilfe dabei, wie man unterschiedliche
+Befehle und Dienstprogramme zum Funktionieren bringt, wie
+Performance-Flaschenhälse beseitigt werden können, wie man beschädigte
+Systeme repariert, wie sich Betriebssysteme oder Netzwerkkonfigurationen
+auf MySQL auswirken, wie man Datensicherung und Wiederherstellung
+optimal konfiguriert, wie man APIs benutzt usw.
+Unser Support deckt nur den MySQL-Server und unsere eigenen
+Dienstprogramme ab, nicht Produkte Dritter, die auf den MySQL-Server
+zugreifen, obwohl wir auch hierbei versuchen, zu helfen wo wir können.
+
+Detaillierte Informationen über unsere unterschiedlichen
+Support-Optionen finden Sie auf @uref{https://order.mysql.com/}, wo auch
+Support-Verträge online bestellt werden können. Wenn Sie nur
+beschränkten Zugriff auf das Internet haben, setzen Sie sich mit unserem
+Vertrieb unter @email{sales@@mysql.com} in Verbindung.
+
+Technischer Support ist wie eine Lebensversicherung. Sie können
+jahrelang ohne solches glücklich sein, doch wenn die Stunde schlägt,
+kann es zu spät sein, diese(n) zu kaufen!
+Wenn Sie den MySQL-Server für wichtige Applikationen nutzen und
+plötzlich Problemen begegnen, kann es möglicherweise zu lange dauern,
+alle Antworten selbst herauszufinden. Es kann daher sein, dass Sie
+unmittelbaren Zugriff auf die erfahrensten MySQL-Problemlöser benötigen,
+und da
+
+@node Copyright, MySQL AB Logos and Trademarks, Support, Licensing and Support
+@c German node Copyright
+@subsection Copyrights und Lizenzen, die von MySQL verwendet werden.
+
+@cindex copyrights
+@cindex licenses
+
+@code{MySQL AB} besitzt das Copyright des MySQL Quellcodes,
+der MySQL Logos and Schutzmarken und dieses Handbuch
+@xref{What is MySQL AB}.
+Es gibt einige verschiedene Lizenzen, die für die MySQL Distribution
+relevant sind:
+
+@enumerate
+@item
+
+Der MySQL-spezifische Quelltext, der benötigt wird, um die
+@code{mysqlclient}-Bibliothek zu kompilieren, ist unter der @code{LGPL}
+lizensiert. Programme im @file{client}-Verzeichnis sind GPL. Jede Datei hat
+einen Header, aus dem ersichtlich ist, welches Copyright für diese Datei
+gilt.
+
+@item Die Client-Bibliothek und die (GNU @code{getopt})-Bibliothek werden
+von der ``GNU LIBRARY GENERAL PUBLIC LICENSE'' abgedeckt. @xref{LGPL license}.
+
+@item
+Der gesamte Quelltext des Servers und der (GNU @code{readline})-Bibliothek
+werden von der ``GNU GENERAL PUBLIC LICENSE'' abgedeckt. @xref{GPL license}.
+Diese findet sich unter anderem als Datei @file{COPYING} in den
+Distributionen.
+
+@item Einige Teile des Quelltextes (die @code{regexp}-Bibliothek) werden
+von einem Copyright in Berkeley-Art abgedeckt.
+
+@item
+Ältere Versionen von (3.22 und früher) stehen unter einer
+strikteren Lizenz
+(@uref{http://www.mysql.com/support/arrangements/mypl.html}).
+Bitte beachten sie die Dokumentation der speziellen Version für
+weitere Informationen.
+
+
+@item
+Das Handbuch steht @emph{nicht} unter einer GPL-artigen Lizenz.
+Die Benutzung des Handbuchs unterliegt den folgenden Bestimmungen.
+@itemize @bullet
+@item
+Die Konvertierung in andere Formate ist erlaubt, der Inhalt jedoch
+darf auf keinen Fall geändert oder bearbeitet werden.
+@item
+Sie können eine gedruckte Version für den Privaten Gebrauch erstellen
+@item
+Für alle anderen Zwecke, wie den Verkauf von gedruckten Kopien
+oder die Verwendung (auch in Teilen) des Handbuchs in anderen
+Veröffentlichungen, ist eine vorherige Vereinbarung mit MySQL AB
+erforderlich.
+@end itemize
+Bitte senden Sie eine E-Mail an @email{docs@@mysql.com} für weitere Informationen
+oder wenn Sie daran interessiert sind, eine Übersetzung zu erstellen.
+@end enumerate
+
+Für Informationen darüber, wie die MySQL Lizenzen in der Praxis arbeiten
+beachten Sie bitte @ref{Lizenzpolitik}.
+Siehe auch @ref{MySQL AB Logos and Trademarks}.
+
+
+
+@menu
+* Verwendung des MySQL Servers unter einer kommerziellen Lizenz::
+* Webserver::
+@end menu
+
+@node Verwendung des MySQL Servers unter einer kommerziellen Lizenz, Webserver, Copyright, Copyright
+@c German node <no English equivalent>
+@subsubsection Verwendung des MySQL Servers unter einer kommerziellen Lizenz
+
+@c German FIX added . after schreiben and after the xref.
+@cindex ISP-Services
+@cindex Services, ISP
+@cindex Services, Web
+@cindex Internet Service Provider
+
+Internet Service Provider (ISP) hosten oft MySQL-Server für ihre Kunden.
+Aufgrund der GPL-Lizenz ist hierfür keine Lizensierung erforderlich.
+
+Auf der anderen Seite ermutigen wir Leute, ISPs zu benutzen, die
+MySQL-Support haben, und das wird ihnen Vertrauen geben, dass ihr ISP im
+Falle von Problemen mit ihrer MySQL-Installation helfen wird, das Problem
+zu lösen (in manchen Fällen mit der Hilfe des MySQL-Entwicklungsteams).
+
+Alle ISPs, die auf dem neuesten Stand der Dinge bleiben wollen, sollten sich
+in die @code{announce}-Mailing-Liste eintragen, um auf der Hut zu sein vor
+schwerwiegenden Problemen, die für ihre MySQL-Installationen relevant sein
+könnten.
+
+Beachten Sie bitte, dass ein ISP ohne MySQL-Lizenz seinen Kunden zumindest
+Lesezugriff auf den Quelltext der MySQL-Installation geben sollte, damit
+die Kunden feststellen können, dass diese korrekt gepatcht ist.
+
+
+@node Webserver, , Verwendung des MySQL Servers unter einer kommerziellen Lizenz, Copyright
+@c German node <no English equivalent>
+@subsubsection Einen Webserver betreiben, der MySQL benutzt
+
+@cindex Webserver, betreiben
+@cindex Einen Webserver betreiben
+
+Wenn Sie MySQL in Verbindung mit einem Webserver unter Unix betreiben,
+brauchen Sie nicht für eine Lizenz zu bezahlen.
+
+Das gilt selbst dann, wenn Sie einen kommerziellen Webserver betreiben, der
+MySQL benutzt, weil Sie nicht selbst eine eingebettete MySQL-Version
+verkaufen. Dennoch bitten wir Sie, in einem solchen Fall MySQL-Support zu
+kaufen, weil MySQL Ihrem Unternehmen hilft.
+
+
+@node MySQL AB Logos and Trademarks, Lizenzpolitik, Copyright, Licensing and Support
+@c German node MySQL AB Logos und Schutzmarken
+@subsection MySQL-AB-Logos und -Schutzmarken
+
+@cindex Logos
+@cindex Schutzmarken
+
+Viele MySQL-Datenbankbenutzer wollen auf Ihren Websites, ihren Büchern
+und Packungsprodukten das MySQL-AB-Delphin-Logo zeigen. Wir begrüßen
+das und ermuntern dazu, weisen aber darauf hin, dass das Wort
+@code{MySQL} und das MySQL-Delphin-Logo Schutzmarken von MySQL AB sind
+und nur so benutzt werden dürfen, wie in unserer Schutzmarken-Richtlinie
+unter @uref{http://www.mysql.com/company/trademark.html} festgelegt.
+
+
+
+
+@menu
+* The Original MySQL logo::
+* MySQL Logos that may be Used Without Written Permission::
+* When need MySQL logo permission::
+* MySQL AB Partnership Logos::
+@end menu
+
+@node The Original MySQL logo, MySQL Logos that may be Used Without Written Permission, MySQL AB Logos and Trademarks, MySQL AB Logos and Trademarks
+@c German node Das Original-MySQL-Logo
+@subsubsection Das Original-MySQL-Logo
+
+@c FIX: picture: MySQL logo
+
+Das MySQL-Delphin-Logo wurde von der finnischen Werbeagentur Priority im
+Jahr 2001 entworfen. Der Delphin wurde als passendes Symbol für die
+MySQL-Datenbank gewählt, weil er schlau, schnell und schlank ist und
+mühelos durch die Daten-Ozeane navigiert. Ausserdem mögen wir Delphine.
+
+Das Original-MySQL-Logo darf nur von Repräsentanten von MySQL AB und von
+Personen benutzt werden, die eine schriftliche Erlaubnis hierfür haben.
+
+@node MySQL Logos that may be Used Without Written Permission, When need MySQL logo permission, The Original MySQL logo, MySQL AB Logos and Trademarks
+@c German node MySQL-Logos die ohne schriftliche Erlaubnis benutzt werden dürfen
+@subsubsection MySQL-Logos die ohne schriftliche Erlaubnis benutzt werden dürfen
+
+@c FIX: pictures: powered by, works with, included - logos
+
+Wir haben einen Satz spezieller Logos für @emph{vorbehaltliche
+Benutzung} angelegt, die von unserer Website unter
+@uref{http://www.mysql.com/downloads/logos.html} herunter geladen werden
+können und von Dritten auf ihren Websites ohne schriftliche Erlaubnis
+von MySQL AB benutzt werden dürfen. Der Gebrauch dieser Logos ist - wie
+der Name anzeigt - nicht völlig uneingeschränkt, sondern unterliegt
+unseren Schutzmarken-Richtlinien, die Sie auf unserer Website finden.
+Sie sollten diese Richtlinien lesen, wenn Sie planen, die Logos zu
+benutzen. Die Anforderungen sind im Wesentlichen:
+
+@itemize @bullet
+@item
+Benutzen Sie das gewünschte Logo von der @uref{http://www.mysql.com/}-
+Site. Sie dürfen die Größe nach Ihren Bedürfnissen anpassen, aber keine
+Farben oder das Design ändern noch die Grafik in sonstiger Form
+verändern.
+
+@item
+Heben Sie hervor, dass Sie - und nicht MySQL AB - der Betreiber und
+Eigner der Site ist, auf der die MySQL-Schutzmarke gezeigt wird.
+
+@item
+Sie dürfen die Schutzmarke nicht auf eine Weise benutzen, die MySQL AB
+oder dem Wert der MySQL-AB-Schutzmarken schadet. Wir behalten uns das
+Recht vor, das Recht zur Benutzung der MySQL-AB-Schutzmarke zu
+widerrufen.
+
+@item
+Wenn Sie die Schutzmarke auf einer Website benutzen, machen Sie sie
+anklickbar, wobei direkt nach @uref{http://www.mysql.com/} verlinkt
+wird.
+
+@item
+Wenn Sie die MySQL-Datenbank unter GPL in einer Applikation benutzen,
+muss Ihre Applikation (i) Open Source sein, (ii) in der Lage sein, sich
+mit einem MySQL-Server zu verbinden.
+@end itemize
+
+Setzen Sie sich unter @email{trademark@@mysql.com} mit uns in
+Verbindung, um wegen spezieller Arrangements anzufragen, die Ihren
+Bedürfnissen entsprechen.
+
+@node When need MySQL logo permission, MySQL AB Partnership Logos, MySQL Logos that may be Used Without Written Permission, MySQL AB Logos and Trademarks
+@c German node Wann Sie eine Erlaubnis für die Benutzung des MySQL-Logos benötigen
+@subsubsection Wann Sie eine Erlaubnis für die Benutzung des MySQL-Logos benötigen
+
+In folgenden Fällen benötigen Sie eine schriftliche Erlaubnis von MySQL
+AB, bevor Sie die MySQL-Logos benutzen:
+
+@itemize @bullet
+@item
+Wenn Sie irgend ein MySQL-AB-Logo irgendwo ausser auf Ihrer Website
+zeigen.
+
+@item
+Wenn Sie irgend ein MySQL-AB-Logo ausser den oben erwähnten Logos zur
+@emph{vorbehaltlichen Benutzung} auf Websites oder anderswo anzeigen.
+@end itemize
+
+Aus rechtlichen und kommerziellen Gründen müssen wir die Benutzung der
+MySQL-Schutzmarken auf Produkten, Büchern usw. beobachten. Üblicherweise
+verlangen wir eine Gebühr für das Anzeigen von MySQL-AB-Logos auf
+kommerziellen Produkten, weil wir der Meinung sind, das es vertretbar
+ist, dass einige der Erlöse für die Weiterentwicklung der MySQL-
+Datenbank zurückfließen.
+
+@node MySQL AB Partnership Logos, , When need MySQL logo permission, MySQL AB Logos and Trademarks
+@c German node MySQL-AB-Partnerschafts-Logos
+@subsubsection MySQL-AB-Partnerschafts-Logos
+
+@c FIX: pictures: partnership logos - Bertrand?
+
+@c German FIX part of the this paragraph was at the end of Lizenzpolitik.
+@c (i.e. that section was pasted into the middle of this one ;-)
+MySQL-Partnerschafts-Logos dürfen nur von Unternehmen und Personen
+benutzt werden, die eine schriftliche Partnerschaftsvereinbarung mit
+MySQL AB haben. Partnerschaften beinhalten eine Zertifizierung als
+MySQL-Trainer oder -Berater. Sehen Sie bitte unter
+@c German FIX change @xref into @ref 'cos it's not a separate sentence.
+@ref{Business Services Partnering,,Partnerschaft} nach.
+
+@node Lizenzpolitik, , MySQL AB Logos and Trademarks, Licensing and Support
+@c German node <no English equivalent>
+@subsection MySQL-Lizenzpolitik
+
+@cindex Lizenzpolitik
+@cindex technischer Support, Lizensierung
+@cindex Support, Lizensierung
+@cindex General Public License, MySQL
+
+Die formalen Bedingungen der GPL-Lizenz stehen unter @ref{GPL license}.
+Im Wesentlichen ist unsere Lizenzpolitik und die Interpretation der
+GPL wie folgt:
+
+Beachten Sie bitte, dass ältere Versionen von MySQL immer noch einer
+@uref{http://www.mysql.com/Support/arrangements/mypl.html, strengeren
+Lizenz} unterliegen. Sehen Sie in der Dokumentation der betreffenden
+Version wegen entsprechender Informationen nach. Wenn Sie eine kommerzielle
+Lizenz benötigen, weil die GPL-Lizenz nicht zu den Anforderungen Ihrer
+Applikation passt, können Sie eine Lizenz unter
+@uref{https://order.mysql.com/} kaufen.
+
+Für normalen internen Gebrauch kostet MySQL nichts. Sie brauchen uns nichts
+zu bezahlen, wenn Sie nicht wollen.
+
+Eine Lizenz wird benötigt:
+
+@itemize @minus
+@item
+Wenn Sie ein Programm, das nicht freie Software ist, mit Code des
+MySQL-Servers oder der Client-Programme verbinden, die den GPL-Copyrights
+unterliegen. Das ist zum Beispiel der Fall, wenn Sie MySQL als
+eingebetteten Server (Embedded Server) in Ihren Applikationen benutzen,
+oder wenn Sie dem MySQL-Server Erweiterungen hinzufügen, die nicht freie
+Software sind. In diesen Fällen würden Ihre Applikation bzw. Ihr Code
+ebenfalls GPL werden, weil die GPL in solchen Fällen wie ein Virus wirkt.
+Sie können dieses Problem vermeiden, wenn Sie den MySQL-Server mit einer
+kommerziellen Lizenz von MySQL AB erwerben.
+Siehe @uref{http://www.gnu.org/copyleft/gpl-faq.html}.
+@item
+Wenn Sie eine kommerzielle Applikation haben, die NUR mit MySQL
+funktioniert, und wenn Sie die Applikation zusammen mit dem MySQL-Server
+ausliefern. Wir betrachten so etwas als Einbindung, selbst wenn es über das
+Netzwerk geschieht.
+
+@item
+Wenn Sie eine Distribution von MySQL besitzen und nicht den Quelltext für
+Ihre Kopie des MySQL-Servers zur Verfügung stellen, so wie es in der
+GPL-Lizenz festgelegt ist.
+xxx You have a Distribution of MySQL und you xxx Arjen: What does this mean: ...don't provide the
+source code for your copy of the MySQL server ... xxx Shouldn't it be: for your application ... ??? xxx
+, as defined in the GPL license. xxx
+@end itemize
+
+Eine Lizenz wird @strong{NICHT} benötigt:
+
+@itemize @minus
+
+@item
+Sie benötigen keine Lizenz, wenn Sie den Client-Code in kommerzielle
+Programme einschliessen. Der Client-Teil von MySQL unterliegt der
+LGPL @code{GNU Library General Public License}-Lizenz. Der
+@code{mysql}-Kommandozeilen-Client beinhaltet Code der
+@code{readline}-Bibliothek, die unter @code{GPL} steht.
+
+@item
+Wenn Sie für Ihre Art der Benutzung von MySQL keine Lizenz benötigen, aber
+MySQL mögen und die weitere Entwicklung fördern wollen, sind Sie herzlich
+eingeladen, in jedem Fall eine Lizenz zu erwerben.
+
+@item
+Wenn Sie MySQL in einem kommerziellen Zusammenhang benutzen und davon
+profitieren, bitten wir Sie, dass Sie die Weiterentwicklung von MySQL
+fördern, indem Sie einen bestimmten Grad von Support kaufen. Wir meinen,
+dass es vernünftig ist, wenn wir Sie bitten, MySQL zu unterstützen, wenn
+MySQL Ihren Geschäften hilft. (Ansonsten würde es bei Support-Anfragen
+bedeuten, dass Sie nicht nur etwas für umsonst benutzen, in das wir eine
+Menge Arbeit gesteckt haben, sondern dass Sie uns auch noch auffordern,
+kostenlosen Support zu liefern.)
+@end itemize
+
+In Situationen, wo eine MySQL-Lizenz benötigt wird, brauchen Sie eine
+Lizenz pro Maschine, auf der der MySQL-Server läuft. Eine
+Mehrprozessor-Maschine zählt jedoch als eine einzelne Maschine, und es gibt
+keine Beschränkung hinsichtlich der Anzahl von MySQL-Servern, die auf einer
+Maschine laufen, oder hinsichtlich der Anzahl von Clients, die zur gleichen
+Zeit mit einem Server verbunden sind, der auf dieser Maschine läuft!
+
+Falls Sie nicht sicher sind, ob für Ihre spezielle Benutzung von MySQL eine
+Lizenz erforderlich ist, lesen Sie diesen Abschnitt bitte nochmals, bevor
+Sie uns kontaktieren. @xref{Contact information}.
+
+Wenn Sie eine MySQL-Lizenz benötigen, ist die Bezahlung am einfachsten,
+wenn Sie das Lizenzformular auf dem Secure-Server von MySQL unter
+@uref{https://order.mysql.com/} benutzen.
+@c German FIX this section no longer exists (no price info in manual)
+@c Andere Zahlungsformen werden unter @ref{Zahlungsinformationen} besprochen.
+
+
+@menu
+* Using MySQL word in presentations::
+* Using MySQL word in company and product names::
+@end menu
+
+@node Using MySQL word in presentations, Using MySQL word in company and product names, Lizenzpolitik, Lizenzpolitik
+@c German node Benutzung des Worts MySQL in Präsentationen
+@subsubsection Benutzung des Worts @code{MySQL} in Druckmaterialien oder
+Präsentationen
+
+MySQL AB begrüßt Verweise auf die MySQL-Datenbank, aber das Wort
+@code{MySQL} ist eine Schutzmarke von MySQL AB. Deshalb müssen Sie der
+ersten oder deutlichsten Erwähnung des Worts @code{MySQL} das
+Schutzmarken-Symbol @code{TM} hinzufügen, und wo angebracht deutlich
+machen, dass @code{MySQL} eine Schutzmarke von MySQL AB ist. Details
+entnehmen Sie bitte unserer Schutzmarken-Richtlinie unter
+@uref{http://www.mysql.com/company/trademark.html}.
+
+
+@node Using MySQL word in company and product names, , Using MySQL word in presentations, Lizenzpolitik
+@c German node Benutzung des Worts MySQL in Unternehmens- und Produktnamen
+@subsubsection Benutzung des Worts @code{MySQL} in Unternehmens- und
+Produktnamen
+
+Die Benutzung des Worts @code{MySQL} in Produkt- und Unternehmensnamen
+oder in Internet-Domänen-Namen ist nur mit vorheriger schriftlicher
+Erlaubnis durch MySQL AB gestattet.
+
+
+@node MySQL 4.0 In A Nutshell, MySQL Information Sources, Licensing and Support, Deutsch
+@c German node MySQL 4.0 kurz und bündig
+@section MySQL 4.0 kurz und bündig
+
+Dateline: 16. Oktober 2001, Uppsala, Schweden
+
+Lange durch MySQL AB angekündigt und lange von unseren Benutzern
+erwartet: Der MySQL-Server 4.0 ist jetzt in der Alpha-Version zum
+Herunterladen von @uref{http://www.mysql.com/} und unseren Mirrors
+verfügbar.
+
+Die neuen Haupt-Features des MySQL-Servers 4.0 sind eng mit unserem
+bestehenden Geschäft und den Community-Nutzern verzahnt. Durch ihn wird
+die MySQL-Datenbank-Software als Lösung für geschäftskritische
+Schwerlast-Datenbanksysteme verbessert. Weitere neue Features zielen auf
+die Benutzer eingebetteter Datenbanken.
+
+
+
+@menu
+* Nutshell Stepwise Rollout::
+* Nutshell Ready for Immediate Development Use::
+* Nutshell Embedded MySQL::
+* Nutshell Other features::
+* Nutshell Future features::
+* Nutshell 4.1 development release::
+@end menu
+
+@node Nutshell Stepwise Rollout, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell, MySQL 4.0 In A Nutshell
+@c German node Kurz und bündig - Schritt für Schritt
+@subsection Schritt für Schritt
+
+Das Erscheinen des MySQL-Servers 4.0 wird in mehreren Schritten
+erfolgen, wobei die erste Version 4.0.0 genannt wird und bereits die
+meisten neuen Features enthält. Zusätzliche Features werden in die
+Versionen 4.0.1, 4.0.2 usw. eingebaut, höchstwahrscheinlich innerhalb
+weniger Monate. MySQL 4.0 wird als Beta gekennzeichnet. In MySQL 4.1
+werden dann weitere neue Features hinzugefügt. Es wird angestrebt, das
+Alpha-Release Anfang 2002 herauszubringen.
+
+
+@node Nutshell Ready for Immediate Development Use, Nutshell Embedded MySQL, Nutshell Stepwise Rollout, MySQL 4.0 In A Nutshell
+@c German node Kurz und bündig - für den sofortigen Entwicklungseinsatz
+@subsection Für den sofortigen Entwicklungseinsatz
+
+Es wird nicht empfohlen, Produktionssysteme auf den MySQL-Server 4.0
+umzustellen, bis dieser in der Beta-Version veröffentlicht wird. Selbst
+das anfängliche Release hat unsere ausgiebigen Tests ohne jegliche
+Fehler durchlaufen, auf allen Plattformen, auf denen wir testen. Wegen
+der großen Zahl neuer Features empfehlen wir daher den MySQL-Server
+selbst in der Alpha-Version für Entwicklungsarbeiten, wobei in Betracht
+gezogen werden kann, dass der MySQL-Server 4.0 das Stadium "stabil"
+erreichen wird, bevor Applikationen hiermit veröffentlicht werden, die
+jetzt im Entwicklungsstadium sind.
+
+
+@node Nutshell Embedded MySQL, Nutshell Other features, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell
+@c German node Kurz und bündig - eingebettetes MySQL
+@subsection Eingebettetes MySQL
+
+@code{libmysqld} macht den MySQL-Server für einen erheblich ausgedehnten
+Bereich von Applikationen geeignet. Wenn man die eingebettete MySQL-
+Server-Bibliothek benutzt, kann man den MySQL-Server in
+unterschiedlichste Applikationen und elektronische Geräte einbetten, bei
+denen der Endbenutzer keinerlei Ahnung davon hat, dass ihnen eine
+Datenbank unterlegt ist. Der eingebettete MySQL-Server ist ideal für
+Benutzung hinter den Kulissen in Internet-Geräten, öffentlichen Kiosken,
+schlüsselfertigen Hardware-/Software-Einheiten, Hochlast-Internet-
+Servern oder Datenbanken, die auf CD-ROM vertrieben werden.
+
+Viele Benutzer von eingebettetem MySQL können von der @emph{dualen
+Lizensierung} der MySQL-Software profitieren. Neben der GPL-Lizenz sind
+auch kommerzielle Lizenzen für diejenigen verfügbar, die nicht an die
+GPL gebunden sein wollen. Die eingebettete MySQL-Bibliothek benutzt
+dieselbe Schnittstelle wie die normale Client-Bibliothek und ist daher
+angenehm und leicht zu benutzen. @xref{libmysqld}.
+
+
+@node Nutshell Other features, Nutshell Future features, Nutshell Embedded MySQL, MySQL 4.0 In A Nutshell
+@c German node Kurz und bündig - weitere Features
+@subsection Weitere ab MySQL 4.0.0 verfügbare Features
+
+@itemize @bullet
+@item
+Version 4.0 erhöht die @emph{Geschwindigkeit des MySQL-Servers} in
+einigen Bereichen noch weiter, zum Beispiel bei Massen-@code{INSERT}s,
+beim Suchen auf komprimierten Indexen, der Erzeugung von
+@code{FULLTEXT}-Indexen oder auch bei @code{COUNT(DISTINCT)}.
+
+@item
+Der Tabellen-Handler @code{InnoDB} wird jetzt als Feature des
+standardmäßigen MySQL-Servers angeboten und enthält vollständige
+Unterstützung für @code{Transaktionen} und @code{Sperren auf
+Zeilenebene}.
+
+@item
+Der MySQL-Server 4.0 unterstützt sichere Kommunikation zwischen Client
+und Server, wodurch die Sicherheit gegen böswilliges Eindringen und
+unbefugten Zugriff erheblich erhöht wird. Bei Web-Applikationen, die ein
+Grundpfeiler der MySQL-Benutzung sind, konnten Web-Entwickler immer
+schon SSL verwenden, um den Verkehr zwischen Endbenutzer-Browser und der
+Web-Applikation zu sichern, sei sie nun in PHP, Perl, ASP oder mit
+irgend einem anderen Web-Entwicklungswerkzeug geschrieben. Der Verkehr
+zwischen dem Entwicklungswerkzeug und dem mysqld-Serverprozess konnte
+bislang aber nur dadurch gesichert werden, dass die Prozesse auf
+Computern innerhalb derselben Firewall residierten. Ab MySQL-Server 4.0
+kann der @emph{mysqld}-Server-Daemon-Prozess selbst @code{Secure Sockets
+Layer} (@code{SSL}) benutzen, was ihn in die Lage versetzt, eine sichere
+Datenübertragung zwischen einer MySQL-Datenbank und beispielsweise einer
+Windows-Applikation ausserhalb der Firewall aufzubauen.
+
+@item
+Unsere deutschen, österreichischen und schweizerischen Benutzer werden
+bemerken, dass es einen neuen Zeichensatz latin_de gibt, der die
+@emph{deutsche Sortierreihenfolge} beinhaltet, indem deutsche Umlaute in
+derselben Sortierung erscheinen wie bei deutschen Telefonbüchern üblich.
+
+@item
+Zu den Features, die die @code{Migration} von anderen Datenbanksystemen
+zum MySQL-Server erleichtern, gehören @code{TRUNCATE TABLE} (wie in
+Oracle) und @code{IDENTITY} a1s Synonym für automatisch hochgezählte
+Schlüssel (wie in Sybase). viele Benutzer werden sich auch darüber
+freuen, dass der MySQL-Server jetzt das @code{UNION}-Statement
+unterstützt, ein lang erwartetes Standard-SQL-Feature.
+
+@item
+Bei der Erstellung neuer Features für neue Benutzer haben wir die
+Gemeinschaft treuer Benutzer nicht vergessen. Es gibt jetzt Multi-
+Tabellen-@code{DELETE}-Statements. Durch das Hinzufügen von
+Unterstützung für @code{symbolisches Verknüpfen} von @code{MyISAM} auf
+Tabellenebene (und nicht nicht - wie bisher - auf Datenbankebene), sowie
+durch das vorgabemäßige Anschalten der Verknüpfungen unter Windows
+hoffen wir zeigen zu können, dass wir Verbesserungsvorschläge ernst
+nehmen. Funktionen wie @code{SQL_CALC_FOUND_ROWS} und
+@code{FOUND_ROWS()} ermöglichen herauszufinden, wie viele Zeilen eine
+Anfrage ohne eine @code{LIMIT}-Klausel zurückgegeben hätte.
+@end itemize
+
+
+@node Nutshell Future features, Nutshell 4.1 development release, Nutshell Other features, MySQL 4.0 In A Nutshell
+@c German node Kurz und bündig - zukünftige Features
+@subsection Zukünftige Features in MySQL 4.0
+
+Für die kommenden Releases des MySQL-Servers 4.0 (4.0.1, 4.0.2 usw.)
+können Sie folgende Features erwarten, die noch in der Entwicklung sind:
+
+@itemize @bullet
+@item
+Benutzer des MySQL-Servers für geschäftskritische Hochlast-Anwendungen
+werden die Ergänzungen unseres Replikationssystems und unsere Online-
+"Hot"-Datensicherung begrüßen. Spätere Versionen von 4.0 werden
+@code{absturzsichere Replikation} beinhalten, die es bereits in Version
+4.0.0 gibt, sowie den @code{LOAD DATA FROM MASTER}-Befehl, der bald das
+Aufsetzen von Slaves automatisieren wird. @code{online backup} wird das
+Hinzufügen eines neuen Replikations-Slaves erleichtern, ohne dass man
+den Master herunterfahren muss, und es gibt auf Systemen mit vielen
+Aktualisierungen nur geringe Geschwindigkeitseinbussen.
+
+@item
+Als Bequemlichkeits-Feature für Datenbank-Administratoren wird
+hinzugefügt, dass mysqld-Parameter (Startoptionen) bald ohne das
+Herunterfahren des Servers gesetzt werden können.
+
+@item
+Die neuen Eigenschaften des MySQL-Servers 4.0 für die Volltext-
+(@code{FULLTEXT})-Suche ermöglichen die @code{FULLTEXT}-Indexierung
+großer Texte sowohl mit binärer wie auch mit natürlichsprachiger
+Suchlogik. Benutzer können minimale Wortlängen anpassen und ihre
+eigenen Stopp-Wort-Listen in jeder menschlichen Sprache festlegen,
+wodurch gänzlich neue Applikationen ermöglicht werden, die auf dem
+MySQL-Server aufbauen.
+
+@item
+Viele Applikationen mit starkem Lesezugriff werden durch die noch weiter
+erhöhte Geschwindigkeit des neu geschriebenen @code{Schlüssel-Caches}
+profitieren.
+
+@item
+Viele Entwickler wird auch die @code{MySQL-Befehlshilfe} im Client
+freuen.
+@end itemize
+
+
+@node Nutshell 4.1 development release, , Nutshell Future features, MySQL 4.0 In A Nutshell
+@c German node Kurz und bündig - Entwicklungs-Release
+@subsection MySQL 4.1, das folgende Entwicklungs-Release
+
+Intern wird durch das neue .frm-Dateiformat für Tabellendefinitionen in
+MySQL-Server 4.0 die Grundlage für neue Features in MySQL-Server 4.1
+gelegt, beispielsweise @code{verschachtelte Unterabfragen},
+@code{gespeicherte Prozeduren} und @code{Fremdschlüssel-
+Integritätsregeln}, die ganz oben auf der Wunschliste vieler unserer
+Kunden stehen. Daneben werden auch einfachere Erweiterungen wie Multi-
+Tabellen-@code{UPDATE}-Statements hinzugefügt.
+
+Nach diesen Ergänzungen werden Kritiker des MySQL-Datenbankservers es
+noch schwerer haben, auf Schwächen des MySQL-Datenbank-Managementsystems
+hinzuweisen. MySQL, das seit langem für seine Stabilität,
+Geschwindigkeit und Einfachheit der Benutzung bekannt ist, wird dann den
+Anforderungen sehr anspruchsvoller Käufer genügen.
+
+
+@node MySQL Information Sources, Compatibility, MySQL 4.0 In A Nutshell, Deutsch
+@c German node MySQL-Informationsquellen
+@section MySQL-Informationsquellen
+
+
+
+@menu
+* Portals::
+* Questions::
+@end menu
+
+@node Portals, Questions, MySQL Information Sources, MySQL Information Sources
+@c German node Portale
+@subsection MySQL-Portale
+
+@cindex MySQL-Portale
+@cindex Handbücher, über MySQL
+@cindex Bücher, über MySQL
+@cindex MySQL-Testimonials
+@cindex Benutzer, von MySQL
+@cindex News-Sites
+@cindex Suchmaschinen, Web
+@cindex Web-Suchmaschinen
+@cindex Online-Magazine
+@cindex Magazine, online
+@cindex Websites
+@cindex Dienstleistungen
+@cindex PHP, Websites
+@cindex Berater, Liste
+@cindex Web-Seiten, verschiedene
+@cindex @code{Contrib}-Verzeichnis
+@cindex URLs zu MySQL-Informationen
+@cindex MySQL-bezogene Informations-URLs
+
+Die MySQL-Portale (@uref{http://www.mysql.com/portal/}) auf unserer
+Website bieten ein breites Spektrum MySQL-bezogener Informationen und
+Links. Sie sind so aufgebaut, dass Sie leicht die Dinge finden, die Sie
+interessieren.
+
+Sie können sich als Benutzer registrieren. In diesem Fall können Sie
+alle Dinge in den Portalen kommentieren und bewerten und auch selbst
+Dinge beisteuern. Bei der Registrierung können Sie auch angeben, ob und
+- wenn ja - welche Newsletter aus welchen Kategorien Sie beziehen
+wollen.
+
+Einige der momentanen MySQL-Portal-Kategorien:
+
+@itemize @bullet
+@item Bücher
+Hier finden Sie alle möglichen MySQL- oder Computer-bezogenen Bücher, die
+Sie kommentieren, bewerten oder kaufen können. Während dieses Handbuch
+(insbesondere die Online-Version) immer noch der richtige Platz für
+aktuellste technische Informationen ist, ist sein vorrangiges Ziel,
+alles zu enthalten, was man über das MySQL-Datenbanksystem wissen kann.
+Manchmal ist es nett, ein gebundenes Buch zu haben, dass man im Bett
+oder auf Reisen lesen kann. Wenn Sie ein Buch über die angegebenen
+Hyperlinks kaufen, tragen Sie zur Entwicklung der MySQL-Software bei.
+
+@item Entwicklung
+Dieses Portal hat Links auf Seiten, die den MySQL-Server für
+unterschiedliche Zwecke benutzen, mit einer Beschreibung jeder Site.
+Diese Informationen können Ihnen eine gute Vorstellung davon geben, wer
+MySQL-Datenbank-Software benutzt und wie der MySQL-Server ihre
+Anforderungen erfüllt.
+Teile Sie uns auch @emph{Ihre} Site oder Erfolgsgeschichte mit!
+
+@item Software
+Hier finden Sie eine Vielzahl von Applikationen und Wrappern, die den
+MySQL-Server benutzen, die Sie auch herunter laden können.
+
+@item Distributionen
+Hier finden Sie die verschiedenen Linux-Distributionen und weitere
+Software-Pakete, die die MySQL-Software enthalten.
+
+@item Berater
+Hier finden Sie Informationen über MySQL-Berater.
+
+@item Partner
+Hier finden Sie alle MySQL-Partner.
+@end itemize
+
+
+@node Questions, , Portals, MySQL Information Sources
+@c German node Fragen
+@subsection MySQL-Mailing-Listen
+
+@cindex Berichten, Fehler
+@cindex MySQL-Mailing-Listen
+
+
+Dieser Abschnitt führt Sie in die MySQL-Mailing-Listen ein und zeigt einige
+Richtlinien und ihre Benutzung auf.
+
+
+@menu
+* Mailing-list::
+* Asking questions::
+* Bug reports::
+* Answering questions::
+@end menu
+
+@node Mailing-list, Asking questions, Questions, Questions
+@c German node Mailing-Listen
+@subsubsection Die MySQL-Mailing-Listen
+
+@cindex Mailing-Listen
+@cindex E-Mail-Listen
+
+Um die MySQL-Haupt-Mailing-Liste zu abonnieren, schicken Sie eine Nachricht
+an die E-Mail-Adresse @email{mysql-subscribe@@lists.mysql.com}.
+
+Um sich aus der MySQL-Haupt-Mailing-Liste auszutragen, schicken Sie eine
+Nachricht an die E-Mail-Adresse @email{mysql-unsubscribe@@lists.mysql.com}.
+
+Von Bedeutung ist nur die Adresse, unter der Sie Ihre Nachrichten
+abschicken. Betreffzeile und Text der Nachricht werden ignoriert.
+
+@c the last two addresses in this paragraph are NOT @email because they
+@c shouldn't be live links.
+Wenn Ihre Antwortadresse nicht gültig ist, können Sie Ihre Adresse explizit
+angeben. Fügen Sie einen Bindestrich zum Abonnement- oder
+Abmelde-Kommando hinzu, gefolgt von Ihrer Adresse, wobei das
+@samp{@@}-Zeichen in Ihrer Adresse durch @samp{=} ersetzt wird. Um sich zum
+Beispiel mit @code{your_name@@host.domain} einzutragen, schicken Sie eine
+Nachricht an @code{mysql-subscribe-your_name=host.domain@@lists.mysql.com}.
+
+Mails an @email{mysql-subscribe@@lists.mysql.com} oder
+@email{mysql-unsubscribe@@lists.mysql.com} werden automatisch vom ezmlm
+Mailing-Listen-Prozessor bearbeitet. Informationen über ezmlm sind
+auf @uref{http://www.ezmlm.org, The ezmlm Website} verfügbar.
+
+Um eine Nachricht an die Liste selbst zu schicken, schicken Sie eine Mail
+an @code{mysql@@lists.mysql.com}. Schicken aber bitte @emph{keine} Mail an
+@email{mysql@@lists.mysql.com}, die das Abonnieren oder Austragen betrifft,
+denn Mails an diese Adresse werden automatisch an tausende anderer Benutzer
+verteilt.
+
+@c __review__jan_2001_11_13
+Wenn Ihre lokale Site viele Abonnenten für @email{mysql@@lists.mysql.com}
+hat, sollten Sie evtl. eine lokale Mailing-Liste einrichten, so dass
+Nachrichten, die von @code{lists.mysql.com} an Ihre Site gesandt werden, an
+die lokale Liste verteilt werden. In solchen Fällen wenden Sie sich bitte
+an Ihre Systemadministrator, um zur lokalen Mailing-Liste hinzugefügt oder
+aus ihr gelöscht zu werden.
+
+Wenn Sie wollen, dass der Traffic einer Mailing-Liste in eine separate
+Mailbox Ihres E-Mail-Programms geleitet wird, setzen Sie einen Filter,
+der auf die E-Mail-Header (Kopfdaten) reagiert. Sie können dazu entweder
+den @code{List-ID:}- oder den @code{Delivered-To:}-Header benutzen, um die
+Listennachrichten zu erkennen.
+
+Die folgenden MySQL-Mailing-Listen existieren:
+
+@table @code
+@item @email{announce-subscribe@@lists.mysql.com} announce
+Diese Liste kündigt neue Versionen von MySQL und verwandter Programme an.
+Sie hat geringen Traffic; alle MySQL-Benutzer sollten sie abonnieren.
+
+@item @email{mysql-subscribe@@lists.mysql.com} mysql
+Die Hauptliste für allgemeine MySQL-Diskussionen. Bitte beachten Sie, dass
+bestimmte Themen besser in spezialisierteren Listen diskutiert werden. Wenn
+Sie an die falsche Liste posten, erhalten Sie vielleicht keine Antwort!
+
+@item @email{mysql-digest-subscribe@@lists.mysql.com} mysql-digest
+Die @code{mysql}-Liste in Digest-Form (zusammengefasst). Anstelle
+individueller Nachrichten wird einmal pro Tag eine große Mail mit allen
+Nachrichten dieses Tages geschickt.
+
+@item @email{bugs-subscribe@@lists.mysql.com} bugs
+An diese Liste sollte Sie ausschließlich komplette, wiederholbare
+Bug-Berichte schicken, indem Sie das @code{mysqlbug}-Skript benutzen. (Wenn
+Sie unter Windows arbeiten, sollten Sie eine Beschreibung des
+Betriebssystems und der MySQL-Version hinzufügen.)
+Vorzugsweise sollten Sie den Problemfall mit der letzten stabilen oder
+Entwicklungs-Version von MySQL testen, bevor Sie den Bericht posten! Jeder
+sollte in der Lage sein, den Bug zu wiederholen, indem einfach @code{mysql
+test < Skript} auf den beigefügten Testfall angewandt wird. Alle Bugs, die
+auf dieser Liste gepostet werden, werden im nächsten MySQL-Release behoben
+oder dokumentiert! Wenn nur kleinere Code-Änderungen betroffen sind, werden
+wir zusätzlich ein Patch bereitstellen, das das Problem behebt.
+
+@item @email{bugs-digest-subscribe@@lists.mysql.com} bugs-digest
+Die Digest-Version (zusammengefasst) der @code{bugs}-Liste.
+
+@item @email{internals-subscribe@@lists.mysql.com} internals
+Eine Liste für Leute, die am MySQL-Code arbeiten. Auf dieser Liste kann man
+auch die MySQL-Entwicklung diskutieren und Patches posten.
+
+@item @email{internals-digest-subscribe@@lists.mysql.com} internals-digest
+Die Digest-Version (zusammengefasst) der @code{internals}-Liste.
+
+@item @email{java-subscribe@@lists.mysql.com} java
+Diskussionen über MySQL und Java, hauptsächlich über JDBC-Treiber.
+
+@item @email{java-digest-subscribe@@lists.mysql.com} java-digest
+Eine @code{java}-Liste.
+
+@item @email{win32-subscribe@@lists.mysql.com} win32
+Alles betreffend MySQL auf Microsoft-Betriebssystemen wie Win95, Win98, NT, XP,
+und Win2000.
+
+@item @email{win32-digest-subscribe@@lists.mysql.com} win32-digest
+Die Digest-Version (zusammengefasst) der @code{win32}-Liste.
+
+@item @email{myodbc-subscribe@@lists.mysql.com} myodbc
+Alles betreffend ODBC-Verbindungen zu MySQL.
+
+@item @email{myodbc-digest-subscribe@@lists.mysql.com} myodbc-digest
+Die Digest-Version (zusammengefasst) der @code{myodbc}-Liste.
+
+@item @email{plusplus-subscribe@@lists.mysql.com} plusplus
+Alles, was das Programmieren mit der C++-API von MySQL betrifft.
+
+@item @email{plusplus-digest-subscribe@@lists.mysql.com} plusplus-digest
+Die Digest-Version (zusammengefasst) der @code{plusplus}-Liste.
+
+@c __review_jan_2001_11_13
+@item @email{msql-mysql-modules-subscribe@@lists.mysql.com} msql-mysql-modules
+Eine Liste zur Perl-Unterstützung in MySQL. msql-mysql-modules
+
+@item @email{msql-mysql-modules-digest-subscribe@@lists.mysql.com} msql-mysql-modules-digest
+Die Digest-Version (zusammengefasst) der @code{msql-mysql-modules}-Liste.
+@end table
+
+Alle Listen abonnieren Sie - und tragen sich wieder aus - auf dieselbe Art
+wie oben beschrieben. Tragen Sie in Ihre Mail zum Abonnieren oder Austragen
+die entsprechende Mailing-Liste ein anstelle von @code{mysql}. Um sich zum
+Beispiel für die @code{myodbc}-Liste einzutragen, schicken Sie eine
+Nachricht an @email{myodbc-subscribe@@lists.mysql.com} oder
+@email{myodbc-unsubscribe@@lists.mysql.com}.
+
+Wenn Sie keine Antwort auf Ihre Fragen von der Mailing-Liste erhalten, ist
+eine Option, für den Support von MySQL AB zu bezahlen, was Sie in direkten
+Kontakt mit den MySQL-Entwicklern bringt. @xref{Support}.
+
+Die folgende Tabelle listet einige Mailing-Listen in anderen Sprachen als
+englisch auf. Beachten Sie, dass diese nicht von MySQL AB unterhalten
+werden. Daher können wir nicht für die Qualität dieser Listen garantieren.
+
+@table @code
+@item @email{mysql-france-subscribe@@yahoogroups.com} Eine französische Mailing-Liste
+@item @email{list@@tinc.net} Eine koreanische Mailing-Liste
+Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql
+your@@email.address} an diese Liste.
+@item @email{mysql-de-request@@lists.4t2.com} Eine deutsche Mailing-Liste
+Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql-de
+your@@email.address} an diese Liste.
+Informationen über diese Liste finden Sie unter
+@uref{http://www.4t2.com/mysql}.
+@item @email{mysql-br-request@@listas.linkway.com.br} Eine portugiesische Mailing-Liste.
+Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql-br
+your@@email.address} an diese Liste.
+@item @email{mysql-alta@@elistas.net} Eine spanische Mailing-Liste.
+Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql
+your@@email.address} an diese Liste.
+@end table
+
+
+@node Asking questions, Bug reports, Mailing-list, Questions
+@c German node Fragen stellen
+@subsubsection Wie man Fragen stellt oder Bugs berichtet
+
+@cindex Netz-Etikette
+@cindex Mailing-Listen, Speicherort der Archive
+@cindex Durchsuchen, MySQL-Webseiten
+
+Bevor Sie einen Bug berichten oder eine Frage stellen, tun Sie bitte
+folgendes:
+
+@itemize @bullet
+@item
+Suchen Sie im MySQL-Online-Handbuch:
+@*
+@uref{http://www.mysql.com/documentation/manual.php}
+@*
+Wir bemühen uns, das Handbuch aktuell zu halten, indem wir es häufig mit
+Lösungen für neu bekannt gewordene Probleme aktualisieren!
+
+@item
+Durchsuchen Sie die MySQL-Mailing-Listen-Archive:
+@*
+@uref{http://www.mysql.com/documentation/}
+@*
+@item
+Sie können ausserdem @uref{http://www.mysql.com/search.html} benutzen, um
+alle Webseiten zu durchsuchen (inklusive des Handbuchs), die unter
+@uref{http://www.mysql.com/} zu finden sind.
+@end itemize
+
+Wenn Sie weder im Handbuch noch in den Archiven eine Antwort finden können,
+versuchen Sie es mit Ihrem lokalen MySQL-Experten. Wenn Sie immer noch
+keine Antwort auf Ihre Frage finden, lesen Sie den nächsten Abschnitt über
+die Mailing-Listen unter @email{mysql@@lists.mysql.com}.
+
+
+@node Bug reports, Answering questions, Asking questions, Questions
+@c German node Bug-Berichte
+@subsubsection Wie man Bugs oder Probleme berichtet
+
+@cindex Bugs, berichten
+@cindex Berichten, Bugs
+@cindex Probleme, berichten
+@cindex Fehler, berichten
+@cindex @code{mysqlbug}-Skript
+@cindex Erzeugen, Bug-Berichte
+@cindex Skripts, @code{mysqlbug}
+
+Einen guten Bug-Bericht zu schreiben braucht Geduld, aber es gleich beim
+ersten Mal richtig zu machen spart Ihnen und uns Zeit. Ein guter
+Bug-Bericht enthält einen kompletten Testfall für den Bug, der es sehr
+wahrscheinlich macht, dass wir ihn im nächsten Release beheben. Dieser
+Abschnitt hilft Ihnen, Ihren Bericht korrekt zu schreiben, damit Sie Ihre
+Zeit nicht damit verschwenden, etwas zu schreiben, was uns wenig oder gar
+nicht weiterhilft.
+
+Wir ermutigen jeden, das @code{mysqlbug}-Skript zu benutzen, um einen
+Bug-Bericht anzufertigen (oder einen Bericht über irgendein anderes
+Problem), falls das möglich ist. Der @code{mysqlbug} findet sich im
+@file{Skripts}-Verzeichnis der Quelldistribution, bzw. im
+@file{bin}-Verzeichnis der Binärdistribution, im Verzeichnis unterhalb
+Ihres MySQL-Installationsverzeichnisses. Falls es Ihnen nicht möglich ist,
+@code{mysqlbug} zu benutzen, sollten Sie trotzdem alle notwendigen
+Informationen mitliefern, die in diesem Abschnitt aufgeführt sind.
+
+Das @code{mysqlbug}-Skript hilft Ihnen, einen Bericht zu erstellen, der
+viele der folgenden Informationen automatisch einschließt, aber falls
+etwas Wichtiges fehlt, fügen Sie es bitte Ihrer Nachricht hinzu! Bitte
+lesen Sie diesen Abschnitt sorgfältig und stellen Sie sicher, dass alle
+hier beschriebenen Informationen in Ihrem Bericht enthalten sind.
+
+@cindex Bug-Berichte, E-Mail-Adresse
+Für gewöhnlich sollten Sie Ihren Bug-Bericht und Probleme an
+@email{mysql@@lists.mysql.com} schicken. Wenn Sie einen Testfall erzeugen
+können, der den Bug klar demonstriert, sollten Sie ihn an die
+@email{bugs@@lists.mysql.com}-Liste schicken. Beachten Sie, dass Sie nur
+einen kompletten, nachvollziehbaren Bug-Bericht an diese Liste schicken
+sollten, indem Sie das @code{mysqlbug}-Skript benutzen. Falls Sie unter
+Windows arbeiten, sollten Sie eine Beschreibung des Betriebssystems und der
+MySQL-Version hinzufügen. Vorzugsweise sollten Sie den Problemfall mit der
+letzten stabilen oder Entwicklungs-Version von MySQL testen, bevor Sie den
+Bericht posten! Jeder sollte in der Lage sein, den Bug zu wiederholen,
+indem einfach @code{mysqltest < Skript} auf den beigefügten Testfall
+angewandt wird. Alle Bugs, die auf dieser Liste gepostet werden, werden im
+nächsten MySQL-Release behoben oder dokumentiert! Wenn nur kleinere
+Code-Änderungen betroffen sind, werden wir zusätzlich ein Patch
+bereitstellen, das das Problem behebt.
+
+Denken Sie daran, dass es immer möglich ist, auf eine Nachricht zu
+antworten, die zu viele Informationen enthält, aber nicht immer auf eine,
+die zu wenige Informationen enthält. Oft lassen Leute Fakten aus, weil sie
+denken, die Ursache eines Probleme zu kennen und annehmen, dass einige
+Details nicht von Wichtigkeit sind. Ein gutes Prinzip ist folgendes: Falls
+Sie im Zweifel sind, ob Sie etwas Bestimmtes mitteilen sollten, teilen Sie
+es mit! Es ist tausendmal schneller und weniger ärgerlich, ein paar Zeilen
+mehr in Ihrem Bericht zu schreiben, als gezwungen zu sein, noch einmal zu
+fragen und auf die Antwort zu warten, weil Sie beim ersten Mal nicht genug
+Informationen geliefert haben.
+
+Die häufigste Fehler besteht darin, dass Leute die Versionsnummer der
+MySQL-Distribution, die sie benutzen nicht angeben, oder vergessen anzugeben,
+auf welcher Plattform sie MySQL installiert haben (inklusive der
+Betriebssystem-Version). Diese Informationen sind äußerst relevant, und in
+99 von 100 Fällen ist der Bug-Bericht ohne sie nutzlos! Sehr oft erhalten
+wir Fragen wie 'Warum funktioniert das bei mir nicht?', nur um
+herauszufinden, dass das beschriebene Feature nicht in der benutzten
+MySQL-Version implementiert war, oder dass der Bug, der im Bericht
+beschrieben wurde, bereits in einer neueren MySQL-Version behoben wurde.
+Manchmal ist der Fehler plattformabhängig; in solchen Fällen ist es
+praktisch unmöglich, irgend etwas zu beheben, ohne das Betriebssystem und
+die Versionsnummer des Betriebssystems zu kennen.
+
+Denken Sie auch daran, Informationen über Ihren Compiler einzuschließen,
+falls sie MySQL selbst kompilieren. Oft finden Leute Fehler in
+Compilern und denken, dass das Problem MySQL-bezogen ist. Die meisten
+Compiler werden permanent weiter entwickelt und werden von Version zu
+Version besser. Um festzustellen, ob ein Problem von Ihrem Compiler abhängt
+oder nicht, müssen wir wissen, welcher Compiler benutzt wird. Beachten Sie,
+dass jedes Compiler-Problem als Bug-Bericht betrachtet und deshalb
+entsprechend berichtet werden sollte.
+
+Es ist äußerst hilfreich, wenn eine gute Beschreibung des Probleme in
+Ihrem Bug-Bericht eingeschlossen ist, das heißt ein gutes Beispiel aller
+Dinge, die Sie getan haben, die zu dem Problem führten, sowie das Problem
+selbst. Die besten Bug-Berichte sind diejenigen, die ein komplettes
+Beispiel zeigen, wie man den Bug oder das Problem reproduzieren kann.
+@xref{Reproduceable test case}.
+
+Wenn ein Programm eine Fehlermeldung produziert, ist es sehr wichtig,
+diese in Ihren Bericht einzuschließen! Wenn wir in den Archiven der
+Programme suchen, ist es besser, wenn die Fehlernachricht exakt mit
+derjenigen übereinstimmt, die das Programm produziert. (Sogar
+Groß-/Kleinschreibung sollte berücksichtigt werden!) Sie sollten nie
+versuchen, sich daran zu erinnern, was die Fehlernachricht war; stattdessen
+sollten Sie die gesamte Nachricht per Kopieren und Einfügen in Ihrem
+Bericht unterbringen!
+
+Wenn Sie ein Problem mit MyODBC haben, sollten Sie versuchen, eine
+MyODBC-Trace-Datei zu erstellen. @xref{MyODBC bug report}.
+
+Bitten denken Sie daran, dass viele Leute, die Ihren Bericht lesen, dabei
+ein 80-Spalten-Anzeigegerät benutzen. Wenn Sie Berichte oder Beispiele
+erzeugen, indem Sie das @code{mysql}-Kommandozeilen-Werkzeug benutzen, sollten
+Sie deshalb die @code{--vertical}-Option (oder den
+@code{\G}-Statement-Begrenzer) für Ausgaben benutzen, die ansonsten die
+verfügbare Anzeigebreite überschreiten würden (zum Beispiel beim
+@code{EXPLAIN SELECT}-Statement; siehe dazu das Beispiel weiter unten).
+@cindex Bug-Berichte, Kriterien für
+Bitte schließen Sie folgende Informationen in Ihren Bug-Bericht ein:
+
+@itemize @bullet
+@item
+Die Versionsnummer der MySQL-Distribution, die Sie benutzen (zum Beispiel
+MySQL Version 3.23.22). Sie finden heraus, welche Version Sie benutzen,
+indem Sie @code{mysqladmin version} eingeben. @code{mysqladmin} findet
+sich im @file{bin}-Verzeichnis unterhalb Ihres
+MySQL-Installationsverzeichnisses.
+
+@item
+Hersteller und Modell der Maschine, auf der Sie arbeiten.
+
+@item
+Name und Version des Betriebssystems. Bei den meisten Betriebssystemen
+läßt sich diese Information herausfinden, indem man das Unix-Kommando
+@code{uname -a} ausführt.
+
+@item
+Manchmal ist die Größe des Arbeitsspeichers (real und virtuell) relevant.
+Im Zweifelsfall schließen Sie diese Werte ein.
+
+@item
+Wenn Sie eine Quelldistribution von MySQL benutzen, werden Name und
+Versionsnummer des Compilers benötigt. Wenn Sie eine Binärdistribution
+haben, geben Sie den Namen der Distribution an.
+
+@item
+Wenn das Problem während der Kompilation auftritt, schließen Sie die
+exakte Fehlermeldung (bzw. -meldungen) ein und zusätzlich ein paar Zeilen
+des Kontextes um den problembehafteten Code herum in der Datei, wo der
+Fehler auftrat.
+
+@item
+Falls @code{mysqld} abstürzt, sollten Sie auch die Anfrage (Query)
+mitteilen, die @code{mysqld} zum Absturz brachte. Gewöhnlich können Sie das
+herausfinden, indem Sie @code{mysqld} mit angeschaltetem Logging laufen
+lassen. @xref{Using log files}.
+
+@item
+Falls irgend eine Datenbanktabelle mit dem Problem zu tun hat, schließen
+Sie die Ausgabe von @code{mysqldump --no-data db_name tbl_name1 tbl_name2
+...} ein. Das ist sehr leicht zu bewerkstelligen und eine sehr hilfreiche
+Möglichkeit, Informationen über jegliche Tabelle in einer Datenbank zu
+erhalten, die uns hilft, eine Situation herzustellen, die mit derjenigen
+übereinstimmt, die Sie haben.
+
+@item
+Bei Bugs, die sich auf Geschwindigkeitsprobleme beziehen, oder bei
+Problemen mit @code{SELECT}-Statements, sollten Sie immer die Ausgabe von
+@code{EXPLAIN SELECT ...} einschließen, und zumindest die Anzahl der
+Zeilen, die das @code{SELECT}-Statement produziert. Je mehr Informationen
+Sie uns über Ihre Situation geben, desto wahrscheinlicher ist es, dass
+Ihnen jemand helfen kann! Das folgende Beispiel ist ein sehr gutes Beispiel
+eines Bug-Berichts (es sollte natürlich mit dem @code{mysqlbug}-Skript
+berichtet werden):
+
+Beispiel unter Benutzung des @code{mysql}-Kommandozeilen-Werkzeugs (achten Sie
+auf die Benutzung des @code{\G}-Statement-Begrenzers für Statements, deren
+Ausgabebreite ansonsten die von 80-Zeilen-Ausgabegeräten überschreiten
+würde):
+
+@example
+mysql> SHOW VARIABLES;
+mysql> SHOW COLUMNS FROM ...\G
+ <Ausgabe von SHOW COLUMNS>
+mysql> EXPLAIN SELECT ...\G
+ <Ausgabe von EXPLAIN>
+mysql> FLUSH STATUS;
+mysql> SELECT ...;
+ <Eine Kurzfassung der Ausgabe von SELECT,
+ inclusive der Zeit, die die Anfrage benötigte>
+mysql> SHOW STATUS;
+ <Ausgabe von SHOW STATUS>
+@end example
+
+@item
+Wenn ein Problem auftritt, während @strong{mysqld} läuft, legen Sie nach
+Möglichkeit ein Eingabeskript bei, das die Anomalie reproduziert. Dieses
+Skript sollte alle notwendigen Quelltextdateien beinhalten. Je exakter das
+Skript Ihre Situation reproduzieren kann, desto besser. Wenn Sie einen
+wiederholbaren Testfall erstellen können, sollten Sie ihn an
+@email{bugs@@lists.mysql.com} schicken, damit er mit hoher Priorität
+behandelt wird!
+
+Falls Sie kein Skript zur Verfügung stellen können, sollten Sie zumindest
+die Ausgaben von @code{mysqladmin variables extended-status processlist} in
+Ihrer Mail mitschicken, um einige Informationen darüber zu geben, wie Ihr
+System arbeitet!
+
+@item
+Falls Sie keinen Testfall mit ein paar Zeilen produzieren können oder falls
+Ihre Tabelle zu Groß ist, um an die Mailing-Liste geschickt zu werden
+(mehr als 10 Zeilen), sollten Sie mit @code{mysqldump} einen Dump Ihrer
+Tabellen machen und eine @file{README}-Datei erzeugen, die Ihr Problem
+beschreibt.
+
+Erzeugen Sie ein komprimiertes Archiv Ihrer Dateien, indem Sie @code{tar}
+und @code{gzip} oder @code{zip} benutzen, und benutzen Sie @code{ftp}, um
+das Archiv nach @uref{ftp://Support.mysql.com/pub/mysql/secret/} zu
+transferieren. Schicken Sie danach eine kurze Beschreibung des Probleme an
+@email{bugs@@lists.mysql.com}.
+
+@item
+Wenn Sie glauben, dass MySQL auf eine Anfrage hin merkwürdige Ergebnisse
+liefert, fügen Sie nicht nur das Ergebnis bei, sondern auch, wie das
+Ergebnis Ihrer Meinung nach aussehen sollte, sowie eine Erklärung, wie Sie
+zu dieser Meinung gelangt sind.
+
+@item
+Wenn Sie ein Beispiel Ihres Problems schildern, ist es besser, die
+Variablen-, Tabellen- etc. Namen zu verwenden, die in Ihrer aktuellen
+Situation existieren, anstatt sich neue Namen auszudenken. Das Problem
+könnte nämlich etwas mit dem Namen der Variablen oder Tabelle zu tun haben!
+Diese Fälle sind zwar selten, aber hier sollte man lieber auf Nummer sicher
+gehen. Letztlich sollte es für Sie auch leichter sein, ein Beispiel zur
+Verfügung zu stellen, das Ihre tatsächliche Situation schildert, und es ist
+in jedem Fall besser für uns. Falls Sie mit Daten arbeiten, die Sie keinen
+anderen zeigen wollen, können Sie @code{ftp} benutzen, um die Daten nach
+@uref{ftp://Support.mysql.com/pub/mysql/secret/} zu transferieren. Falls
+die Daten streng geheim sind und Sie sie nicht einmal uns zeigen wollen,
+legen Sie bitte ein Beispiel mit anderen Namen an, betrachten Sie dies aber
+bitte als allerletzte Möglichkeit.
+
+@item
+Fügen Sie alle Optionen ein, die den relevanten Programmen übergeben
+wurden, falls möglich. Geben Sie zum Beispiel die Optionen an, die Sie
+benutzt haben, als Sie den @code{mysqld}-Daemon gestartet haben, und die
+Sie für Client-Programme wie @code{mysql} benutzen, sowie
+diejenigen, die Sie für die Konfiguration des @code{configure}-Skripts
+nehmen, denn diesen sind oft der Schlüssel für Antworten und deshalb
+äußerst relevant!
+Es ist immer eine gute Idee, sie in jedem Fall anzugeben! Wenn Sie Module
+wie Perl oder PHP benutzen, fügen Sie bitte die Versionszahl von diesen mit
+ein.
+
+@item
+Wenn sich Ihre Frage auf das Berechtigungssystem (Zugriffsberechtigungen auf
+den Datenbank-Server) bezieht, fügen Sie bitte die Ausgabe von
+@code{mysqlaccess}, die Ausgabe von @code{mysqladmin reload} und alle
+Fehlermeldungen, die Sie erhalten, wenn Sie versuchen, sich zu verbinden,
+bei! Wenn Sie Ihre Zugriffsberechtigungen testen, sollten Sie zunächst
+@code{mysqlaccess} ausführen. Führen Sie danach @code{mysqladmin reload
+version} aus und versuchen Sie dann, sich mit dem Programm zu verbinden,
+das Probleme macht. @code{mysqlaccess} liegt im @file{bin}-Verzeichnis
+unter Ihrem MySQL-Installationsverzeichnis.
+MySQL-Installationsverzeichnis.
+
+@item
+Wenn Sie einen Patch für ein Bug haben, ist das gut, aber nehmen Sie bitte
+nicht an, dass der Patch alles ist, was wir brauchen. Gehen Sie auch nicht
+davon aus, dass wir den Patch benutzen werden, wenn Sie nicht auch einige
+notwendige Informationen mitschicken, zum Beispiel Testfälle, die den Bug
+zeigen, der durch Ihren Patch behoben wird. Möglicherweise finden wir
+Probleme, die Ihr Patch verursacht, oder wir verstehen ihn überhaupt nicht.
+Wenn das der Fall ist, können wir ihn nicht benutzen.
+
+Wenn wir nicht genau feststellen können, wofür der Patch gedacht ist,
+werden wir ihn nicht benutzen. In diesen Fällen werden uns Testfälle weiter
+helfen. Zeigen Sie darin auf, dass der Patch all die Situationen bewältigt,
+die eintreten können. Falls wir einen Grenzfall finden (sogar, wenn es ein
+seltener ist), bei dem der Patch nicht funktioniert, ist er vielleicht
+nutzlos.
+
+@item
+Vermutungen, worin der Bug besteht, warum er auftritt oder wovon er
+abhängt, sind meist falsch. Selbst das MySQL-Team kann solche Dinge nicht
+erraten, sondern muss einen Debugger benutzen, um den wahren Grund des Bugs
+feststellen zu können.
+
+@item
+Geben Sie in Ihrer Mail zu erkennen, dass Sie das Referenzhandbuch gelesen
+und die Mail-Archive durchgesehen haben, damit andere wissen, dass Sie
+versucht haben, das Problem selbst zu lösen.
+
+@item
+Wenn Sie einen @code{parse error} erhalten, überprüfen Sie bitte genau Ihre
+Syntax! Wenn Sie nichts Falsches darin finden können, ist es sehr
+wahrscheinlich, dass Ihre aktuelle Version von MySQL die Anfrage, die Sie
+formuliert haben, nicht unterstützt. Wenn Sie die aktuelle Version benutzen
+und das Handbuch unter @uref{http://www.mysql.com/documentation/manual.php}
+die Syntax, die Sie benutzen, nicht beschreibt, unterstützt MySQL Ihre
+Anfrage nicht. In diesem Fall bleibt Ihnen nur, die Syntax entweder selbst
+zu implementieren oder per E-Mail an @email{mysql-licensing@@mysql.com}
+nach einem Angebot für die Implementation anzufragen!
+
+Wenn das Handbuch die Syntax, die Sie benutzen, beschreibt, Sie aber eine
+ältere Version von MySQL benutzen, sollten Sie in der
+MySQL-Änderungsgeschichte (Change History) nachsehen, wann die Syntax
+implementiert wurde. In diesem Fall haben Sie die Möglichkeit, ein Upgrade
+auf eine neuere Version von MySQL vorzunehmen.
+@xref{News}.
+
+@item
+Wenn Sie ein Problem in der Art haben, dass Ihre Daten anscheinend
+beschädigt sind oder Sie Fehlermeldungen bekommen, wenn Sie auf eine
+bestimmte Tabelle zugreifen, sollten Sie zunächst Ihre Tabellen überprüfen
+und anschließend reparieren, indem Sie @code{myisamchk} oder @code{CHECK
+TABLE} und @code{REPAIR TABLE} benutzen.
+@xref{MySQL Database Administration}.
+
+@item
+Wenn Sie oft beschädigte Tabellen erhalten, sollten Sie versuchen
+herauszufinden, wann und warum das geschieht! In diesem Fall kann die
+@file{mysql-data-directory/'hostname'.err}-Datei einige Informationen
+darüber enthalten, was geschehen ist. @xref{Error log}. Bitte fügen Sie
+jede relevante Information aus dieser Datei in Ihren Bug-Bericht ein!
+Normalerweise sollte @code{mysqld} @strong{NIE} eine Tabelle zerstören,
+ausser wenn der Server mitten während eines Updates gekillt wurde! Wenn Sie
+den Grund für den Absturz von @code{mysqld} herausfinden können, ist es
+sehr viel einfacher für uns, Ihnen eine Lösung des Problems an die Hand zu
+geben!
+@xref{What is crashing}.
+
+@item
+Falls möglich, sollten Sie die aktuellste Version von MySQL herunter laden,
+installieren und überprüfen, ob das Ihr Problem löst. Alle Versionen
+von MySQL werden gründlich getestet und sollten ohne Probleme
+funktionieren! Wir halten uns daran, alles so abwärtskompatibel wie
+möglich zu machen. Daher sollte es Ihnen möglich sein, innerhalb von
+Minuten die MySQL-Version auszutauschen!
+@xref{Which version}.
+@end itemize
+
+@cindex Technischer Support, E-Mail-Adresse
+@cindex Support, E-Mail-Adresse
+@cindex Kunden-Support, E-Mail-Adresse
+@cindex E-Mail-Adresse, für Kunden-Support
+Wenn Sie ein Support-Kunde sind, schicken Sie bitte den Bug-Bericht an
+@email{mysql-Support@@mysql.com}, damit dieser eine höhere Priorität in der
+Bearbeitung erfährt. Schicken Sie ihn gleichzeitig an die entsprechende
+Mailing-Liste, um zu sehen, ob schon jemand anderes das selbe Problem hatte
+(und vielleicht gelöst hat).
+
+Informationen zu Bug-Berichten siehe @strong{MyODBC} und @ref{ODBC Problems}.
+
+Lösungen für häufig auftretende Probleme siehe @xref{Problems}.
+
+Wenn Ihnen Antworten individuell zugesandt werden und nicht an die
+Mailing-Liste, wird es als gute Etikette betrachtet, die Antworten
+zusammenzufassen und die Zusammenfassung an die Mailing-Liste zu schicken,
+damit andere von den Antworten profitieren können, die Ihnen geholfen
+haben, Ihr Problem zu lösen!
+
+
+@node Answering questions, , Bug reports, Questions
+@c German node Fragen beantworten
+@subsubsection Richtlinien für die Beantwortung von Fragen auf der Mailing-Liste
+
+@cindex Netz-Etikette
+@cindex Fragen, Antworten
+@cindex Fragen beantworten, Etikette
+@cindex Mailing-Listen, Richtlinien
+
+Wenn Sie davon ausgehen, dass Ihre Antwort auf breites Interesse stößt,
+sollten Sie an die Mailing-Liste posten, statt direkt der Person zu
+antworten, die die Frage stellte. Versuchen Sie, Ihre Antwort so allgemein
+zu halten, dass auch andere als der ursprünglich Fragende von Ihrer Antwort
+profitieren können. Wenn Sie an die Liste posten, stellen Sie bitte sicher,
+dass Ihre Antwort kein Duplikat einer vorhergehenden Antwort ist.
+
+Versuchen Sie, den wesentlichen Teil der Frage in Ihrer Antwort
+zusammenzufassen. Fühlen Sie sich nicht verpflichtet, die gesamte
+ursprüngliche Nachricht zu zitieren.
+
+Bitte schicken Sie Ihre Mailnachrichten nicht im HTML-Format! Viele
+Benutzer lesen Nachrichten mit nicht HTML-fähigen Anwendungen!
+
+
+
+@node Compatibility, TODO, MySQL Information Sources, Deutsch
+@c German node Kompatibilität
+@section Wie Standard-kompatibel ist MySQL?
+
+@cindex Kompatibilität mit ANSI SQL
+@cindex Standard-Kompatibilität
+@cindex Erweiterungen von ANSI SQL
+@cindex ANSI SQL92, Erweiterungen
+
+
+Dieser Abschnitt beschreibt, wie sich MySQL zum ANSI SQL-Standard verhält.
+MySQL hat viele Erweiterungen zum ANSI SQL-Standard, und hier steht, welche
+das sind und wie man sie benutzt. Hier finden Sie auch Informationen über
+Funktionalität, die MySQL fehlt, und wie man mit diesen Unterschieden
+umgeht.
+
+
+@menu
+* Standards::
+* ANSI mode::
+* Extensions to ANSI::
+* Differences from ANSI::
+* Bugs::
+@end menu
+
+@node Standards, ANSI mode, Compatibility, Compatibility
+@c German node Standards
+@subsection An welche Standards hält sich MySQL?
+
+Entry-Level-SQL92. ODBC-Levels 0-2.
+
+Wir beabsichtigen ANSI SQL99 vollständig zu unterstützen. Dies
+wollen wir jedoch keinesfalls auf Kosten von Geschwindigkeit
+oder Codequalität erreichen.
+
+@node ANSI mode, Extensions to ANSI, Standards, Compatibility
+@c German node ANSI-Modus
+@subsection MySQL im ANSI-Modus laufen lassen
+
+@cindex Laufen lassen, ANSI-Modus
+@cindex ANSI-Modus, laufen lassen
+
+Wenn Sie @code{mysqld} mit der @code{--ansi}-Option starten, ändert sich
+folgendes Verhalten von MySQL:
+
+@itemize @bullet
+@item
+@code{||} ist Zeichenketten-Verkettung (Konkatenation) anstelle von
+@code{OR}.
+
+@item
+Sie können eine beliebige Anzahl von Leerzeichen zwischen Funktionnamen und
+@samp{(} eingeben. Das führt zwangsläufig dazu, dass alle Funktionsnamen
+als reservierte Wörter behandelt werden.
+
+@item
+@samp{"} ist dann ein Quotierungsbezeichner (wie das MySQL-
+@samp{`}-Anführungszeichen) und kein Zeichen, dass einen String einschließt.
+
+@item
+@code{REAL} wird zu einem Synonym für @code{FLOAT} anstelle eines Synonyms
+für @code{DOUBLE}.
+
+@item
+Der Standard-Isolationslevel für Transaktionen ist @code{SERIALIZABLE}.
+@xref{SET TRANSACTION}.
+@end itemize
+
+Das ist dasselbe, als würde man
+@code{--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY}
+benutzen.
+
+@node Extensions to ANSI, Differences from ANSI, ANSI mode, Compatibility
+@c German node Erweiterungen zu ANSI
+@subsection MySQL-Erweiterungen zu ANSI SQL92
+
+@cindex Hinweise
+MySQL beinhaltet einige Erweiterungen, die Sie in anderen SQL-Datenbanken
+wahrscheinlich nicht finden werden. Passen Sie auf, wenn Sie diese
+benutzen, denn Ihr Code ist dann nicht mehr kompatibel mit anderen
+SQL-Servern. In einigen Fällen können Sie Code schreiben, der
+MySQL-Erweiterungen enthält und dennoch portabel ist, indem Sie Kommentare
+in der Form @code{/*! ... */} benutzen. In diesem Fall wird MySQL den Code
+innerhalb des Kommentars parsen und ausführen wie jedes andere
+MySQL-Statement, aber andere SQL-Server werden die Erweiterungen
+ignorieren. Zum Beispiel:
+
+@example
+SELECT /*! STRAIGHT_JOIN */ col_name FROM tabelle1, tabelle2 WHERE ...
+@end example
+
+Wenn Sie hinter @code{'!'} die Versionsnummer angeben, wird die Syntax nur
+ausgeführt, wenn die MySQL-Version gleich oder neuer als die benutzte
+Versionsnummer ist:
+
+@example
+CREATE /*!32302 TEMPORARY */ TABLE (a int);
+@end example
+
+Je höher bedeutet, wenn Sie Version 3.23.02 oder neuer haben, wird MySQL
+das @code{TEMPORARY}-Schlüsselwort benutzen.
+
+MySQL-Erweiterungen sind:
+
+@itemize @bullet
+@item
+Die Feldtypen @code{MEDIUMINT}, @code{SET}, @code{ENUM} und die
+unterschiedlichen @code{BLOB}- und @code{TEXT}-Typen.
+
+@item
+Die Feldattribute @code{AUTO_INCREMENT}, @code{BINARY}, @code{NULL},
+@code{UNSIGNED} und @code{ZEROFILL}.
+
+@item
+Alle Zeichenkettenvergleiche achten vorgabemäßig nicht auf
+Groß-/Kleinschreibung, wobei die Sortierreihenfolge vom aktuell
+verwendeten Zeichensatz abhängig ist (ISO-8859-1 Latin1 als Vorgabe). Wenn
+Sie das nicht wollen, sollten Sie Ihre Spalten mit dem
+@code{BINARY}-Attribut deklarieren oder den @code{BINARY}-Cast
+benutzen, der dafür sorgt, dass Vergleiche mit der ASCII-Sortierung
+durchgeführt werden, die der MySQL-Server-Host benutzt.
+
+@item
+MySQL legt jede Datenbank als Verzeichnis unterhalb des MySQL-data-
+Verzeichnisses an und Tabellen innerhalb einer Datenbank als Dateien in dem
+Datenbank-Verzeichnis.
+
+Das hat ein paar Auswirkungen:
+
+@cindex Datenbanknamen, Groß-/Kleinschreibung
+@cindex Tabellennamen, Groß-/Kleinschreibung
+@cindex Groß-/Kleinschreibung von Datenbanknamen
+@cindex Groß-/Kleinschreibung von Tabellennamen
+
+@itemize @minus
+
+@item
+Bei Datenbanknamen und Tabellennamen wird auf Unterschiede in der
+Groß-/Kleinschreibung geachtet, wenn das Betriebssystem auf
+Groß-/Kleinschreibung achtet (wie auf den meisten Unix-Systemen).
+@xref{Case sensitivity}.
+
+@item
+Datenbank-, Tabellen-, Index-, Spalten- oder Alias-Namen dürfen mit einer
+Ziffer beginnen (aber nicht ausschließlich aus Ziffern bestehen).
+
+@item
+Sie können Standard-Kommandos des Betriebssystems benutzen, um Tabellen zu
+sichern (Datensicherung), umzubenennen, zu verschieben, zu löschen und zu kopieren.
+Um zum Beispiel eine Tabelle umzubennen, benennen Sie die Dateien
+@file{.MYD}, @file{.MYI} und @file{.frm} um, die der Tabelle entsprechen.
+@end itemize
+
+@item
+In SQL-Statements können Sie Tabellen aus verschiedenen Datenbanken mit der
+@code{db_name.tbl_name}-Syntax ansprechen. Einige SQL-Syntax stellen
+dieselbe Funktionalität zur Verfügung, nennen dies aber @code{User space}.
+MySQL unterstützt keine Tablespaces wie in folgendem Beispiel:
+@code{create tabelle ralph.meine_tabelle...IN mein_tablespace}.
+
+@item
+@code{LIKE} ist für numerische Spalten erlaubt.
+
+@item
+Die Benutzung von @code{INTO OUTFILE} und @code{STRAIGHT_JOIN} in einem
+@code{SELECT}-Statement. @xref{SELECT, , @code{SELECT}}.
+
+@item
+Die Option @code{SQL_SMALL_RESULT} in einem @code{SELECT}-Statement.
+
+@item
+@code{EXPLAIN SELECT}, um eine Beschreibung zu erhalten, wie Tabellen
+verknüpft werden (Join).
+
+@item
+Die Benutzung von Index-Namen, Indexen auf ein Prefix eines Feldes, und die
+Benutzung von @code{INDEX} oder @code{KEY} in einem @code{CREATE TABLE}-
+Statement. @xref{CREATE TABLE, , @code{CREATE TABLE}}.
+
+@item
+Die Benutzung von @code{TEMPORARY} oder @code{IF NOT EXISTS} mit @code{CREATE TABLE}.
+
+@item
+Die Benutzung von @code{COUNT(DISTINCT list)}, wobei 'list' mehr als ein
+Element ist.
+
+@item
+Die Benutzung von @code{CHANGE spalten_name}, @code{DROP spalten_name}, oder
+@code{DROP INDEX}, @code{IGNORE} oder @code{RENAME} in einem @code{ALTER
+TABLE}-Statement. @xref{ALTER TABLE, , @code{ALTER TABLE}}.
+
+@item
+Die Benutzung von @code{RENAME TABLE}. @xref{RENAME TABLE, , @code{RENAME TABLE}}.
+
+@item
+Die Benutzung mehrfacher @code{ADD}-, @code{ALTER}-, @code{DROP}-, oder
+@code{CHANGE}-Klauseln in einem @code{ALTER TABLE} Statement.
+
+@item
+Die Benutzung von @code{DROP TABLE} mit the keywords @code{IF EXISTS}.
+
+@item
+Sie können mehrere Tabellen löschen mit einem einzigen @code{DROP
+TABLE}-Statement.
+
+@item
+Die @code{LIMIT}-Klausel des @code{DELETE}-Statements.
+
+@item
+Die @code{DELAYED}-Klausel der @code{INSERT}- und @code{REPLACE}-
+Statements.
+
+@item
+Die @code{LOW_PRIORITY}-Klausel der @code{INSERT}-, @code{REPLACE}-,
+@code{DELETE}- und @code{UPDATE}-Statements.
+
+@cindex Oracle-Kompabilität
+@cindex Kompatibilität, mit Oracle
+@item
+Die Benutzung von @code{LOAD DATA INFILE}. In vielen Fällen ist diese
+Syntax kompatibel mit Oracles @code{LOAD DATA INFILE}. @xref{LOAD DATA, ,
+@code{LOAD DATA}}.
+
+@item
+Die @code{ANALYZE TABLE}-, @code{CHECK TABLE}-, @code{OPTIMIZE TABLE}- und
+@code{REPAIR TABLE}-Statements.
+
+@item
+Das @code{SHOW}-Statement.
+@xref{SHOW, , @code{SHOW}}.
+
+@item
+Zeichenketten dürfen sowohl durch @samp{"} als auch durch @samp{'}
+eingeschlossen werden, nicht nur durch @samp{'}.
+
+@item
+Die Benutzung des Escape(@samp{\})Zeichens.
+
+@item
+Das @code{SET OPTION}-Statement. @xref{SET OPTION, , @code{SET OPTION}}.
+
+@item
+Sie müssen nicht alle ausgewählten Spalten im @code{GROUP BY}-Teil nennen.
+Hierdurch ergibt sich eine bessere Performance für einige sehr spezifische,
+aber recht gewöhnliche Anfragen.
+
+@item
+Man kann @code{ASC} und @code{DESC} bei @code{GROUP BY} spezifizieren.
+
+@item
+Um es Benutzern leichter zu machen, die von anderen SQL-Umgebungen kommen,
+unterstützt MySQL Aliase für viele Funktionen. Zum Beispiel unterstützen
+alle Zeichenketten-Funktionen sowohl die ANSI-SQL-Syntax als auch die
+ODBC-Syntax.
+
+@item
+MySQL kennt die Operatoren @code{||} und @code{&&}, die logisches Oder und
+logisches Und bedeuten, wie in der Programmiersprache C. In MySQL sind
+@code{||} und @code{OR} Synonyme, wie auch @code{&&} und @code{AND}.
+Aufgrund dieser freundlichen Syntax unterstützt MySQL nicht den
+ANSI-SQL-@code{||}-Operator für Zeichenketten-Verkettung (Konkatenation);
+benutzen Sie statt dessen @code{CONCAT()}. Weil @code{CONCAT()} eine
+beliebige Anzahl von Argumenten entgegennimmt, ist es leicht, die Benutzung
+des @code{||}-Operators zu MySQL zu konvertieren.
+
+@item
+@code{CREATE DATABASE} oder @code{DROP DATABASE}.
+@xref{CREATE DATABASE, , @code{CREATE DATABASE}}.
+
+@cindex PostgreSQL-Kompatibilität
+@cindex Kompatibilität, mit PostgreSQL
+@item
+Der @code{%}-Operator ist ein Synonym für @code{MOD()}. Das heißt @code{N
+% M} ist äquivalent zu @code{MOD(N,M)}. @code{%} wird für C-Programmierer
+und für Kompatibilität mit PostgreSQL unterstützt.
+
+@item
+Die @code{=}-, @code{<>}-, @code{<=}-, @code{<}-, @code{>=}-, @code{>}-,
+@code{<<}-, @code{>>}-, @code{<=>}-, @code{AND}-, @code{OR}- oder
+@code{LIKE}-Operatoren können in Spaltenvergleichen links von @code{FROM}
+in @code{SELECT} Statements benutzt werden. Beispiel:
+
+@example
+mysql> SELECT spalte1=1 AND spalte2=2 FROM tabelle_name;
+@end example
+
+@item
+Die @code{LAST_INSERT_ID()}-Funktion.
+@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
+
+@item
+Die @code{REGEXP}- und @code{NOT REGEXP}-Operatoren für erweiterte reguläre
+Ausdrücke.
+
+@item
+@code{CONCAT()} oder @code{CHAR()} mit einem Argument oder mehr als zwei
+Argumenten. (In MySQL können diese Funktionen jede beliebige Anzahl von
+Argumenten entgegennehmen.)
+
+@item Die Funktionen @code{BIT_COUNT()}, @code{CASE}, @code{ELT()},
+@code{FROM_DAYS()}, @code{FORMAT()}, @code{IF()}, @code{PASSWORD()},
+@code{ENCRYPT()}, @code{md5()}, @code{ENCODE()}, @code{DECODE()},
+@code{PERIOD_ADD()}, @code{PERIOD_DIFF()}, @code{TO_DAYS()} oder
+@code{WEEKDAY()}.
+
+@item
+Die Benutzung von @code{TRIM()}, um Teile von Zeichenketten zu entfernen.
+ANSI SQL unterstützt nur die Entfernung einzelner Zeichen.
+
+@item
+Die @code{GROUP BY}-Funktionen @code{STD()}, @code{BIT_OR()} und
+@code{BIT_AND()}.
+
+@item
+Die Benutzung von @code{REPLACE} anstelle von @code{DELETE} + @code{INSERT}.
+@xref{REPLACE, , @code{REPLACE}}.
+
+@item
+Das @code{FLUSH flush_option}-Statement.
+
+@item
+Die Möglichkeit, Variablen in einem Statement mit @code{:=} zu setzen:
+@example
+SELECT @@a:=SUM(total),@@b=COUNT(*),@@a/@@b AS avg FROM test_tabelle;
+SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
+@end example
+
+@end itemize
+
+
+@node Differences from ANSI, Bugs, Extensions to ANSI, Compatibility
+@c German node Unterschiede zu ANSI
+@subsection MySQL-Unterschiede im Vergleich zu ANSI SQL92
+
+Wir versuchen möglichst, dass MySQL dem ANSI-SQL-Standard und dem
+ODBC-SQL-Standard folgt, aber in einigen Fällen macht MySQL Dinge auf
+andere Weise:
+
+@itemize @bullet
+@item
+@code{--} ist nur dann ein Kommentar, wenn darauf Whitespace folgt.
+@xref{ANSI diff comments}.
+
+@item
+Bei @code{VARCHAR}-Spalten werden Leerzeichen am Ende entfernt, wenn der
+Wert gespeichert wird. @xref{Bugs}.
+
+@item
+In einigen Fällen ändern sich @code{CHAR}-Spalten automatisch (silent) in
+@code{VARCHAR}-Spalten. @xref{Silent column changes}.
+
+@item
+Zugriffsrechte für eine Tabelle werden nicht automatisch widerrufen, wenn
+Sie eine Tabelle löschen. Sie müssen explizit ein @code{REVOKE}-Statement
+absetzen, um die Zugriffsrechte für eine Tabelle zu widerrufen.
+@xref{GRANT, , @code{GRANT}}.
+
+@item
+@code{NULL AND FALSE} werden zu @code{NULL} ausgewertet und nicht zu
+@code{FALSE}. Der Grund hierfür liegt darin, dass wir meinen, dass es keine
+gute Idee ist, eine Menge von Sonderkonditionen für diesen Fall auswerten
+zu müssen.
+@end itemize
+
+
+@menu
+* ANSI diff Sub-selects::
+* ANSI diff SELECT INTO TABLE::
+* ANSI diff Transactions::
+* ANSI diff Triggers::
+* ANSI diff Foreign Keys::
+* Beschädigte Fremdschlüssel::
+* ANSI diff Views::
+* ANSI diff comments::
+@end menu
+
+@node ANSI diff Sub-selects, ANSI diff SELECT INTO TABLE, Differences from ANSI, Differences from ANSI
+@c German node Fehlende Sub-Selects
+@subsubsection Sub-Selects
+
+@cindex Sub-Selects
+
+MySQL unterstützt momentan nur Sub-Selects der Form @code{INSERT
+... SELECT ...} und @code{REPLACE ... SELECT ...}. In anderen
+Zusammenhängen können Sie allerdings die Funktion @code{IN()} benutzen.
+
+In vielen Fällen können Sie Ihre Anfragen ohne Sub-Selects schreiben:
+
+@example
+SELECT * FROM tabelle1 WHERE id IN (SELECT id FROM tabelle2);
+@end example
+
+Das kann wie folgt umgeschrieben werden:
+
+@example
+SELECT tabelle1.* FROM tabelle1,tabelle2 WHERE tabelle1.id=tabelle2.id;
+@end example
+
+Die Anfragen:
+@example
+SELECT * FROM tabelle1 WHERE id NOT IN (SELECT id FROM tabelle2);
+SELECT * FROM tabelle1 WHERE NOT EXISTS (SELECT id FROM tabelle2 where tabelle1.id=tabelle2.id);
+@end example
+
+Können wie folgt umgeschrieben werden:
+
+@example
+SELECT tabelle1.* FROM tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id where tabelle2.id IS NULL
+@end example
+
+Für kompliziertere Unteranfragen (Subqueries) können Sie oft temporäre
+Tabelle anlegen, die die Unteranfrage enthalten. In einigen Fällen wird
+diese Option allerdings nicht funktionieren. Am häufigsten treten diese
+Fälle mit @code{DELETE}-Statements auf, wofür Standard-SQL keine
+Verknüpfungen (Joins) unterstützt. Für solche Situationen sind zwei
+Optionen verfügbar, solange MySQL noch keine Unteranfragen unterstützt.
+
+Die erste Option besteht darin, eine prozedurale Programmiersprache (wie
+PHP oder Perl) zu benutzen, um eine @code{SELECT}-Anfrage zu erhalten, die
+die Primärschlüssel enthält, die benötigt werden, um die entsprechenden
+Datensätze zu löschen, und dann diese Werte zu benutzen, um das
+@code{DELETE}-Statement zu formulieren (@code{DELETE FROM ... WHERE ... IN
+(key1, key2, ...)}).
+
+Die zweite Option besteht darin, interaktives SQL zu benutzen, um
+automatisch eine Reihe von @code{DELETE}-Statements zu formulieren, indem
+die MySQL-Erweiterung @code{CONCAT()} benutzt wird (anstelle des
+Standard-Operators @code{||}).
+Beispiel:
+
+@example
+SELECT CONCAT('DELETE FROM tabelle1 WHERE pkid = ', tabelle1.pkid, ';')
+ FROM tabelle1, tabelle2
+ WHERE tabelle1.spalte1 = tabelle2.spalte2;
+@end example
+
+Sie können diese Anfrage in eine Skriptdatei schreiben und deren Eingabe an
+den Kommandozeilen-Interpreter @code{mysql} leiten und von dort die Ausgabe
+zurück an eine zweite Instanz des Interpreters:
+
+@example
+prompt> mysql --skip-column-names meine_db < mein_skript.sql | mysql meine_db
+@end example
+
+MySQL 4.0 unterstützt das Löschen aus mehreren Tabellen (multi-table
+deletes), was benutzt werden kann, um effizient Zeilen zu löschen,
+basierend auf den Informationen aus einer Tabelle oder sogar aus mehreren
+Tabellen zur gleichen Zeit.
+
+@node ANSI diff SELECT INTO TABLE, ANSI diff Transactions, ANSI diff Sub-selects, Differences from ANSI
+@c German node Fehlendes SELECT INTO TABLE
+@subsubsection @code{SELECT INTO TABLE}
+
+@findex SELECT INTO TABLE
+
+MySQL unterstützt noch nicht die Oracle-SQL-Erweiterung @code{SELECT ...
+INTO TABLE ...}. MySQL unterstützt statt dessen die ANSI-SQL-Syntax
+@code{INSERT INTO ... SELECT ...}, die im Prinzip dasselbe ist.
+@xref{INSERT SELECT}.
+
+@example
+INSERT INTO tabelle_temp2 (fldID) SELECT tabelle_temp1.fldOrder_ID FROM tabelle_temp1 WHERE
+tabelle_temp1.fldOrder_ID > 100;
+@end example
+
+Alternativ können Sie @code{SELECT INTO OUTFILE...} oder @code{CREATE TABLE
+... SELECT} benutzen, um Ihre Probleme zu lösen.
+
+
+@node ANSI diff Transactions, ANSI diff Triggers, ANSI diff SELECT INTO TABLE, Differences from ANSI
+@c German node Fehlende Transaktionen
+@subsubsection Transaktionen
+
+@cindex Transaktionen, Support
+
+Weil MySQL heutzutage Transaktionen unterstützt, gelten die folgenden
+Erörterungen nur, wenn Sie nur Tabellentypen benutzen, die nicht
+transaktionssicher sind. @xref{COMMIT}.
+
+Oft wird von neugierigen oder kritischen Leuten gefragt: ``Warum ist MySQL
+keine transaktionale Datenbank?'' oder ``Warum unterstützt MySQL keine
+Transaktionen?''
+
+MySQL hat sich bewusst entschieden, andere Paradigmen für die
+Datenintegrität zu unterstützen: ``atomische Operationen.'' Es entspricht
+unserer Denkweise und unserer Erfahrung, dass atomische Operationen gleiche
+oder bessere Integrität bei wesentlich besserer Performance gewährleisten.
+Nichtsdestotrotz schätzen und verstehen wir das transaktionale
+Datenbank-Paradigma und planen, im Verlauf der nächsten Releases
+transaktionssichere Tabellen einzuführen, auf der Basis der
+Transaktionssicherheit pro einzelner Tabelle. Wir werden unseren Benutzern
+die Entscheidung überlassen, ob Sie in ihren Applikationen den
+Geschwindigkeitsvorteil atomischer Operationen benötigen oder die
+transaktionalen Features.
+
+Wie benutzt man die Features von MySQL, um rigorose Integrität
+beizubehalten, und wie sind diese Features im Vergleich mit dem
+transaktionalen Paradigma zu bewerten?
+
+Zunächst ist es nach dem transaktionalen Paradigma bequemer, mit
+Transaktionen zu arbeiten, wenn Ihre Applikationen auf eine Weise
+geschrieben sind, dass sie in kritischen Situationen ``rollback'' anstelle
+von ``commit'' aufrufen. Darüber hinaus stellen Transaktionen sicher, dass
+unbeendete Updates oder zerstörende Aktivitäten nicht an die Datenbank
+abgesetzt werden; der Server hat die Gelegenheit, ein automatisches
+Rollback durchzuführen, wodurch Ihre Datenbank gerettet wird.
+
+In fast allen Fällen erlaubt Ihnen MySQL, potentiellen Problemen
+vorzubauen, indem einfache Überprüfungen eingebaut und einfache Skripte
+laufen gelassen werden, die die Datenbanken auf Inkonsistenzen prüfen und
+automatisch reparieren oder Warnmeldungen ausgeben, wenn so etwas passiert.
+Beachten Sie auch, dass allein durch die Benutzung der MySQL-Logdatei oder
+durch das Hinzufügen einer speziellen Logdatei Tabellen perfekt repariert
+werden können, ohne dass ein Verlust an Datenintegrität eintritt.
+
+Darüber hinaus können fatale transaktionale Updates so umgeschrieben
+werden, dass sie atomisch sind. In der Tat gehen wir so weit zu sagen, dass
+alle Integritätsprobleme, die Transaktionen lösen, mit @code{LOCK TABLES}
+oder atomischen Update durchgeführt werden können, was sicherstellt, dass
+Sie nie einen automatischen Abbruch von der Datenbank bekommen, was ein
+gewöhnliches Problem transaktionaler Datenbanken darstellt.
+
+Nicht einmal Transaktionen können jeden Verlust verhindern, wenn der Server
+abstürzt. In solchen Fällen können sogar transaktionale Systeme Daten
+verlieren. Der Unterschied zwischen unterschiedlichen Systemen besteht
+einzig darin, wie kurz die Zeitverzögerung ist, in der Daten verloren gehen
+könnten. Kein System ist 100%-ig sicher, sondern lediglich ``sicher
+genug''. Selbst von Oracle, ansonsten als das sicherste aller
+transaktionalen Datenbanken berühmt, wird berichtet, dass es manchmal in
+solchen Situationen Daten verliert.
+
+Um mit MySQL auf der sicheren Seite zu sein, brauchen Sie lediglich
+Datensicherungen und angeschaltetes Update-Logging. Damit können Sie in
+jeder denkbaren Situation genau wie mit jeder beliebigen transaktionalen
+Datenbank Daten wiederherstellen. Natürlich ist es immer eine gute Idee,
+Datensicherungen zu haben, unabhängig von der verwendeten Datenbank.
+
+
+Das transaktionale Paradigma hat seine Vor- und Nachteile. Viele
+Benutzer und Applikationsentwickler verlassen sich auf die Einfachheit, mit
+der sie um Probleme herum Code schreiben können, dort wo anscheinend ein
+Abbruch erfolgt ist, oder wo es notwendig ist, haben sie womöglich ein
+bisschen mehr Arbeit mit MySQL, weil sie anders denken oder mehr schreiben
+müssen. Wenn Ihnen atomische Operationen neu sind oder Sie vertrauter mit
+Transaktionen sind (oder Sie sich damit besser fühlen), kommen Sie nicht
+gleich zur Schlussfolgerung, dass sich MySQL nicht mit diesen Überlegungen
+beschäftigt hat. Zuverlässigkeit und Integrität stehen für uns absolut im
+Vordergrund. Aktuelle Schätzungen gehen davon aus, dass zur Zeit mehr als
+eine Million @code{mysqld}-Server laufen, von denen viele in
+Produktionsumgebungen eingesetzt werden. Wir hören sehr, sehr selten von
+Benutzern, die irgendwelche Daten verloren haben, und in fast allen Fällen
+sind Benutzerfehler im Spiel. Das ist unserer Meinung nach der beste Beweis
+für die Stabilität und Zuverlässigkeit von MySQL.
+
+Im übrigen lassen die aktuellen Features von MySQL Zuverlässigkeit und
+Integrität auf Transaktionsebene oder besser zu, wenn in bestimmten
+Situationen Integrität von höchster Wichtigkeit ist. Wenn Sie Tabellen mit
+@code{LOCK TABLES} sperren, werden alle Updates angehalten, bis jegliche
+Integritätsprüfungen durchgeführt sind. Wenn Sie nur eine Lesesperre (Read
+Lock) machen (im Gegensatz zu einer Schreibsperre - Write Lock), werden
+Lese- und Einfügeoperationen noch zugelassen. Die neu eingefügten
+Datensätze können von nicht Clients gesehen werden, die eine
+@code{READ}-Sperre haben, bis sie ihre Lesesperre aufheben. Mit
+@code{INSERT DELAYED} können Sie Einfügeoperationen in eine lokale
+Warteschlange (Local Queue) stellen, solange, bis die Sperren aufgehoben
+sind, ohne dass der Client warten muss, bis die Einfügeoperationen
+abgeschlossen sind. @xref{INSERT DELAYED}.
+
+``Atomisch'', so wie wir es meinen, ist nichts Magisches. Es bedeutet nur,
+dass Sie sicher sein können, dass kein anderer Benutzer mit irgendeinem
+laufenden Update in Konflikt kommen kann, und dass es nie ein automatisches
+Rollback geben kann (was bei transaktionsbasierenden Systemen vorkommen
+kann, wenn Sie nicht sehr vorsichtig sind). MySQL garantiert auch, dass es
+keine schmutzigen Lesezugriffe (Dirty Reads) gibt. Sie finden einige
+Beispiele, wie man atomische Updates schreibt, im Abschnitt über Commits
+und Rollbacks.
+@c German FIX This section no longer exists
+@c @xref{Commit-Rollback}.
+
+Wir haben reichlich über Integrität und Performance nachgedacht und
+glauben, dass unser atomisches Paradigma sowohl Zuverlässigkeit als auch
+extrem hohe Performance gewährleistet, und zwar drei- bis fünfmal
+schneller, als es die schnellste und optimal eingestellte transaktionale
+Datenbank schafft. Wir haben Transaktionen nicht deshalb heraus gelassen,
+weil sie schwer zu machen sind. Der Hauptgrund für die Entscheidung für
+atomische Operationen gegen Transaktionen liegt darin, dass wir dadurch
+viele Geschwindigkeitsoptimierungen machen konnten, die auf andere Art
+nicht möglich gewesen wären.
+
+Viele unserer Benutzer, für die Geschwindigkeit das Wichtigste ist, haben
+keinerlei Bedenken hinsichtlich Transaktionen. Für sie sind Transaktionen
+kein Thema. Diejenigen Benutzer, die Sorgen mit Transaktionen haben oder
+sich darüber wundern, dass MySQL diese nicht unterstützt, gibt es eine
+``MySQL-Art'', die wir weiter oben beschrieben haben. Denjenigen, denen
+Sicherheit wichtiger als Geschwindigkeit ist, empfehlen wir die Benutzung
+von @code{BDB}- oder @code{InnoDB}-Tabellen für alle kritischen Daten.
+@xref{Table types}.
+
+Ein letzter Hinweis: Wir arbeiten zur Zeit an einem sicheren
+Replikationsschema, vom dem wir glauben, dass es besser als jedes
+kommerzielle Replikationssystem ist, das wir kennen. Dieses System wird mit
+dem atomischen, nicht-transaktionalen Paradigma mit höchster
+Zuverlässigkeit laufen. Bleiben Sie dran!
+
+
+@node ANSI diff Triggers, ANSI diff Foreign Keys, ANSI diff Transactions, Differences from ANSI
+@c German node Fehlende Trigger
+@subsubsection Gespeicherte Prozeduren und Trigger
+
+@cindex Fehlende Prozeduren und Trigger, Definition
+@cindex Prozeduren, gespeicherte
+@cindex Trigger, gespeicherte
+
+Eine gespeicherte Prozedur ist ein Satz von SQL-Kommandos, die kompiliert
+und auf dem Server gespeichert werden können. Wenn dies einmal geschehen
+ist, müssen Clients nicht mehr die gesamte Anfrage absetzen, sondern können
+sich auf die gespeicherte Prozedur beziehen. Hiermit wird bessere
+Performance erreicht, den die Anfrage muss nur einmal geparst werden, und
+es muss weniger Information zwischen Client und Server ausgetauscht werden.
+Man kann sogar die konzeptionelle Ebene steigern, indem man Bibliotheken
+von Funktionen auf dem Server bereit hält.
+
+Ein Trigger ist eine gespeicherte Prozedur, die aufgerufen wird, wenn ein
+bestimmtes Ereignis eintritt. Beispielsweise kann man eine gespeicherte
+Prozedur installieren, die jedes Mal ausgeführt wird, wenn ein Datensatz
+aus einer Transaktionstabelle gelöscht wird, und die automatisch den dazu
+gehörigen Kunden aus einer Kundentabelle löscht, wenn alle seine
+Transaktionen gelöscht wurden.
+
+Für ein späteres Release ist geplant, dass MySQL gespeicherte Prozeduren
+handhaben kann, aber ohne Trigger. Trigger verlangsamen üblicherweise
+alles, sogar Anfragen, für die sie nicht benötigt werden.
+
+Um festzustellen, ab wann MySQL gespeicherte Prozeduren bekommen wird, siehe
+auch @ref{TODO}.
+
+
+@node ANSI diff Foreign Keys, Beschädigte Fremdschlüssel, ANSI diff Triggers, Differences from ANSI
+@c German node Fehlende Fremdschlüssel
+@subsubsection Fremdschlüssel
+
+@cindex Fremdschlüssel
+@cindex Schlüssel, Fremdschlüssel
+
+Beachten Sie, dass Fremdschlüssel in SQL nicht dazu benutzt werden, um
+Tabellen zu verknüpfen, sondern hauptsächlich, um die referentielle
+Integrität zu überprüfen (Fremdschlüssel-Restriktionen). Wenn Sie durch ein
+@code{SELECT}-Statement Ergebnisse aus mehreren Tabellen erhalten wollen,
+tun Sie dies, indem Sie Tabellen verknüpfen (Join):
+
+@example
+SELECT * von tabelle1,tabelle2 where tabelle1.id = tabelle2.id;
+@end example
+
+@xref{JOIN, , @code{JOIN}}. @xref{example-Foreign keys}.
+
+Die @code{FOREIGN KEY}-Syntax in MySQL existiert nur aus
+Kompatibilitätsgründen mit den @code{CREATE TABLE}-Kommandos anderer
+Hersteller; sie tut nichts. Die @code{FOREIGN KEY}-Syntax ohne @code{ON
+DELETE ...} wird hauptsächlich für Dokumentationszwecke benutzt. Einige
+ODBC-Applikationen benutzen dies vielleicht, um automatische
+@code{WHERE}-Klauseln zu erzeugen, aber das läßt sich üblicherweise leicht
+überschreiben. @code{FOREIGN KEY} wird manchmal als Restriktionsprüfung
+benutzt, aber eine solche Überprüfung ist in der Praxis nicht notwendig,
+wenn Zeilen in Tabellen in der richtigen Reihenfolge eingefügt werden.
+MySQL unterstützt diese Klauseln nur, weil manche Applikationen verlangen,
+dass sie existieren (egal ob sie funktionieren oder nicht).
+
+In MySQL können Sie das Problem, dass @code{ON DELETE...} nicht
+implementiert ist, dadurch umgehen, dass Sie das entsprechende
+@code{DELETE}-Statement einer Applikation hinzufügen, wenn Sie Datensätze
+aus einer Tabelle löschen, die Fremdschlüssel hat. In der Praxis ist das
+genauso schnell (in einigen Fällen schneller) und wesentlich portabler, als
+wenn Sie Fremdschlüssel benutzen würden.
+
+In naher Zukunft werden wir die @code{FOREIGN KEY}-Implementation
+erweitern, so dass zumindest die Information in der Datei, die die Tabelle
+spezifiziert, gespeichert wird und somit durch @code{mysqldump} und ODBC
+abgefragt werden kann. Zu einem späteren Zeitpunkt werden wir
+Fremdschlüssel-Restriktionen für Applikationen implementieren, die nicht
+leicht durch entsprechendes Programmieren umgangen werden können.
+
+
+
+@node Beschädigte Fremdschlüssel, ANSI diff Views, ANSI diff Foreign Keys, Differences from ANSI
+@c German node <no English equivalent>
+@subsubsection Warum wir Fremdschlüssel nicht implementiert haben
+
+@cindex Fremdschlüssel, warum sie nicht implementiert sind
+
+Viele Leute, die Datenbanken unterrichten und programmieren, sind der
+festen Meinung, dass referentielle Integrität durch den Datenbank-Server
+erzwungen werden sollte. In der Tat ist dieser Ansatz in vielen Fällen sehr
+hilfreich. In vielen Gesprächen mit Datenbankbenutzern haben wir jedoch
+festgestellt, dass Fremdschlüssel oft missbraucht werden, was schwer-
+wiegende Probleme verursachen kann. Selbst wenn sie in korrekter Weise
+benutzt werden, sind sie keine magische Lösung für das Problem
+referentieller Integrität, obwohl sie die Dinge in einigen Fällen einfacher
+gestalten.
+
+Wegen der obigen Beobachtungen haben wir der Implementation von
+Fremdschlüsseln keine hohe Priorität zugewiesen. Unsere Benutzerbasis
+bestand bislang zumeist aus Entwicklern, denen es nichts ausmachte,
+referentielle Integrität im Code der Applikation zu erzwingen, und die dies
+sogar bevorzugten, weil es ihnen mehr Kontrolle gab.
+
+In den letzten Jahren hat sich unsere Benutzerbasis jedoch um einiges
+ausgeweitet. Mittlerweile haben wir viele Benutzer, die es schätzen würden,
+wenn MySQL erzwungene referentielle Integrität implementiert hätte. Aus
+diesem Grund werden wir Fremdschlüssel in naher Zukunft implementieren.
+Allerdings können wir zur Zeit noch kein definitives Auslieferungsdatum
+nennen.
+
+Einige Vorteile der Erzwingung von Fremdschlüsseln:
+
+@itemize @bullet
+@item
+Einen sauberen Entwurf der Beziehungen vorausgesetzt machen es
+Fremdschlüssel-Restriktionen schwieriger für einen Programmierer,
+Inkonsistenzen in eine Datenbank einzuführen.
+
+@item
+Wenn kaskadierende Updates und Deletes benutzt werden können, kann dies den
+Client-Code vereinfachen.
+
+@item
+Sauber entworfene Fremdschlüssel-Regeln sind hilfreich, Beziehungen
+zwischen Tabellen zu dokumentieren.
+@end itemize
+
+Nachteile:
+
+@itemize @bullet
+@item
+MySQL unterstützt noch keine erzwungene referentielle Integrität. Wenn Ihre
+Applikation also davon abhängt, können Sie sie solange nicht mit MySQL
+benutzen, bis wir dieses Feature implementieren.
+
+@item
+Fehler, die beim Entwurf von Schlüsselbeziehungen leicht zu machen sind,
+können schwer wiegende Probleme verursachen, zum Beispiel Zirkelbezüge oder
+eine falsche Kombination kaskadierender Deletes.
+
+@item
+Eine sauber geschriebene Applikation wird intern sicherstellen, dass sie
+referentielle Integritäts-Restriktionen nicht verletzt, bevor sie mit einer
+Anfrage fortfährt. Deshalb werden zusätzliche Überprüfungen auf
+Datenbankebene solche Applikationen nur verlangsamen.
+
+@item
+Es ist nichts Ungewöhnliches, dass ein Datenbankadministrator eine so
+komplexe Topologie von Beziehungen einführt, dass es sehr schwierig, wenn
+nicht gar unmöglich wird, einzelne Tabellen zu sichern oder
+wiederherzustellen.
+@end itemize
+
+
+@node ANSI diff Views, ANSI diff comments, Beschädigte Fremdschlüssel, Differences from ANSI
+@c German node Fehlende Sichten
+@subsubsection Sichten (Views)
+
+@cindex Sichten (Views)
+
+MySQL unterstützt noch keine Sichten, aber wir planen, diese in Version 4.1
+zu implementieren.
+
+Sichten sind äußerst nützlich, um Benutzern Zugang zu einem Satz von
+Beziehungen wie zu einer einzigen Tabelle zu gewähren (Lesezugriff). Viele
+SQL-Datenbanken lassen es nicht zu, dass irgend welche Zeilen in einer
+Sicht aktualisiert werden (Update). Statt dessen müssen die einzelnen
+Tabellen aktualisiert werden.
+
+Weil MySQL meist in Applikationen und in Web-Systemen eingesetzt werden, wo
+der Applikationsprogrammierer volle Kontrolle über die Datenbankbenutzung
+hat, sehen die meisten unserer Benutzer Sichten als nicht sehr wichtig an.
+(Zumindest war niemand interessiert genug, um die Implementation von
+Sichten zu finanzieren.)
+
+In MySQL werden Sichten nicht benötigt, um den Zugriff auf Spalten zu
+beschränken, weil MySQL ein sehr ausgefeiltes System der
+Zugriffsberechtigungen hat. @xref{Privilege system}.
+
+
+@node ANSI diff comments, , ANSI diff Views, Differences from ANSI
+@c German node Fehlende Kommentare
+@subsubsection @samp{--} als Beginn eines Kommentars
+
+@cindex Kommentare, Beginn
+@cindex Beginn, Kommentar
+
+Einige andere SQL-Datenbanken benutzen @samp{--}, um Kommentare zu
+beginnen. MySQL benutzt @samp{#} als Anfangszeichen, wenn auch das
+@code{mysql}-Kommandozeilen-Werkzeug alle Zeilen entfernt, die mit @samp{--}
+anfangen. Sie können in MySQL auch Kommentare im C-Stil verwenden @code{/*
+Das ist ein Kommentar */}. @xref{Comments}.
+
+MySQL ab Version 3.23.3 unterstützt Kommentare, die mit @samp{--} beginnen,
+allerdings nur, wenn der Kommentarbeginn von einem Leerzeichen gefolgt
+wird. Der Grund liegt darin, dass dieser degenerierte Kommentar-Stil eine
+Menge Probleme mit automatisch generierten SQL-Anfragen verursacht, die
+Ähnliches wie den folgenden Code benutzen, wo automatisch der Wert einer
+Zahlung für @code{!zahlung!} eingefügt wird:
+
+@example
+UPDATE tabelle_name SET kredit=kredit-!zahlung!
+@end example
+
+Was, glauben Sie, passiert, wenn der Wert von @code{zahlung} negativ wird?
+
+Weil @code{1--1} in SQL zulässig ist, sind wir der Meinung, dass es
+furchtbar ist, dass @samp{--} den Anfang eines Kommentars bedeutet.
+
+In MySQL ab Version 3.23 können Sie allerdings folgendes benutzen:
+@code{1-- Das ist ein Kommentar}
+
+Die folgenden Erörterungen treffen nur zu, wenn Sie eine MySQL-Version vor
+3.23 laufen lassen:
+
+Wenn Sie ein SQL-Programm in einer Textdatei haben, das @samp{--}-Kommentare
+enthält, sollten Sie folgendes benutzen:
+
+@example
+shell> replace " --" " #" < text-datei-mit-merkwuerigen-kommentaren.sql \
+ | mysql datenbank
+@end example
+
+anstelle des üblichen:
+
+@example
+shell> mysql datenbank < text-datei-mit-merkwuerdigen-kommentaren.sql
+@end example
+
+Sie können auch die Kommandodatei ``direkt'' editieren, um die
+@samp{--}-Kommentare zu @samp{#}-Kommentaren zu machen:
+
+@example
+shell> replace " --" " #" -- text-datei-mit-merkwuerdigen-kommentaren.sql
+@end example
+
+Machen Sie die Änderungen mit folgendem Befehl rückgängig:
+
+@example
+shell> replace " #" " --" -- text-datei-mit-merkwuerdigen-kommentaren.sql
+@end example
+
+
+
+@node Bugs, , Differences from ANSI, Compatibility
+@c German node Bugs
+@subsection Bekannte Fehler und Design-Unzulänglichkeiten in MySQL
+
+@cindex Bugs, bekannte
+@cindex Fehler, bekannte
+@cindex Design, Probleme
+@cindex Bekannte Fehler
+
+Die folgenden Probleme sind bekannt. Ihre Behebung hat eine sehr hohe
+Priorität:
+
+@itemize @bullet
+@item
+@code{ANALYZE TABLE} kann eine BDB-Tabelle in manchen Fällen unbenutzbar
+machen, bis @code{mysqld} neu gestartet wird. Wenn so etwas passiert,
+stehen Fehlermeldungen wie die folgende in der MySQL-Fehler-Datei (Error
+File):
+
+@example
+001207 22:07:56 bdb: log_flush: LSN past current end-of-log
+@end example
+
+@item
+Führen Sie mit einer @code{BDB}-Tabelle nicht @code{ALTER TABLE} aus, wenn
+Sie mit dieser noch nicht abgeschlossene Mehrfach-Statement-Transaktionen
+durchführen. (Die Transaktion wird wahrscheinlich ignoriert.)
+
+@item
+@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE} und @code{REPAIR TABLE} können
+Probleme bei Tabellen verursachen, für die @code{INSERT DELAYED} benutzt
+wird.
+
+@item
+Wenn Sie @code{LOCK TABLE ..} und @code{FLUSH TABLES ..} benutzen, können
+Sie nicht sicher sein, dass bei der fraglichen Tabelle keine halb
+abgeschlossenen Transaktionen im Gange sind.
+
+@item
+BDB-Tabellen lassen sich etwas langsam öffnen. Wenn Sie viele BDB-Tabellen
+in einer Datenbank haben, kann es sehr lange dauern, bis Sie den
+@code{mysql}-Client für diese Datenbank benutzen können, wenn Sie die
+@code{-A}-Option oder @code{rehash} benutzen. Das macht sich speziell dann
+bemerkbar, wenn Sie einen große Tabellen-Cache benutzen.
+
+@item
+Das momentane Replikationsprotokoll kann nicht mit @code{LOAD DATA INFILE}
+und mit Zeilenbegrenzungszeichen (line terminator characters) umgehen, die
+mehr als 1 Zeichen enthalten.
+@end itemize
+
+Folgende Probleme sind bekannt und werden zu gegebener Zeit behoben:
+@itemize @bullet
+@item
+Momentan funktioniert @code{MATCH} nur bei @code{SELECT}-Statements.
+
+@item
+Wenn Sie @code{SET CHARACTER SET} benutzen, können Sie keine
+landesspezifischen (nationalen) Zeichen für Datenbank-, Tabellen- und
+Spaltennamen verwenden (also z. B. kein ä, ö, ü).
+
+@item
+@code{DELETE FROM merge_table} ohne @code{WHERE} löscht nur die Zuordnung
+(das Mapping) für die Tabelle, nicht alles in der zugeordneten (gemappten)
+Tabelle.
+
+@item
+Sie können den Server nicht in ein anderes Verzeichnis bauen, wenn Sie
+MIT-Pthreads verwenden. Weil dies Änderungen an MIT-Pthreads bedingen
+würde, werden wir dieses Problem wahrscheinlich nicht beheben.
+
+@item
+@code{BLOB}-Werte können nicht ``zuverlässig'' in @code{GROUP BY}-,
+@code{ORDER BY} oder @code{DISTINCT}-Klauseln benutzt werden. In diesen
+Fällen werden bei Vergleichen nur die ersten @code{max_sort_length}
+Bytes (Vorgabewert 1024) von @code{BLOB}s benutzt. Die Voreinstellung kann
+mit der @code{-O max_sort_length}-Option für @code{mysqld} geändert werden.
+In den meisten Fällen können Sie als Workaround eine Teilzeichenkette
+(Substring) verwenden: @code{SELECT DISTINCT LEFT(blob,2048) FROM
+tabelle}.
+
+@item
+Berechnungen werden mit @code{BIGINT} oder @code{DOUBLE} durchgeführt
+(beide sind normalerweise 64 Bits lang). Es hängt von der verwendeten
+Funktion ab, welche Genauigkeit man erhält. Als allgemeine Regel gilt, dass
+Bit-Funktionen mit @code{BIGINT}-Genauigkeit, @code{IF} und @code{ELT()}
+mit @code{BIGINT}- oder @code{DOUBLE}-Genauigkeit und der Rest mit
+@code{DOUBLE}-Genauigkeit durchgeführt werden. Man sollte vermeiden,
+vorzeichenlose Werte, die größer als 63 Bits sind (9223372036854775807),
+zu verwenden, ausser für Bit-Felder!
+MySQL 4.0 bietet eine bessere @code{BIGINT}-Handhabung als MySQL 3.23.
+
+@item
+Bei allen Zeichenketten-Spalten ausser bei @code{BLOB}- und
+@code{TEXT}-Spalten werden Leerzeichen am Ende automatisch entfernt, wenn
+sie abgerufen werden. Bei @code{CHAR}-Typen ist das okay und kann gemäß
+ANSI-SQL92 als ein Feature betrachtet werden. Der Bug besteht darin, dass
+in MySQL auch @code{VARCHAR}-Spalten auf dieselbe Art behandelt werden.
+
+@item
+Pro Tabelle können höchstens 255 @code{ENUM}- und @code{SET}-Spalten
+verwendet werden.
+
+@item
+@code{safe_mysqld} leitet alle Nachrichten von @code{mysqld} in die
+@code{mysqld}-Logdatei um. Ein Problem ergibt sich, wenn Sie
+@code{mysqladmin refresh} benutzen, um die Logdatei zu schließen und
+wieder zu öffnen. In diesem Fall werden @code{stdout} und @code{stderr}
+immer noch in die alte Logdatei geleitet.
+Wenn Sie @code{--log} umfangreich benutzen, sollten Sie @code{safe_mysqld}
+editieren, um in @file{'hostname'.err} anstelle von @file{'hostname'.log}
+zu loggen, damit Sie den Speicherplatz für das alte Log leicht neu belegen
+können, indem Sie das alte Log löschen und @code{mysqladmin refresh}
+ausführen.
+
+@item
+Im @code{UPDATE}-Statement, werden Spalten von links nach rechts
+aktualisiert (Update). Wenn Sie sich auf eine aktualisierte Spalte
+beziehen, erhalten Sie den aktualisierten Werte anstelle des ursprünglichen
+Werts. Beispiel:
+
+@example
+mysql> UPDATE tabelle SET KEY=KEY+1,KEY=KEY+1;
+@end example
+
+Dieses Statement aktualisiert @code{KEY} mit @code{2} anstelle von
+@code{1}.
+
+@item
+Sie können temporäre Tabellen nicht öfter als einmal innerhalb derselbe
+Anfrage benutzen. Das Folgende zum Beispiel funktioniert nicht:
+
+@example
+select * from temporaere_tabelle, temporaere_tabelle as t2;
+@end example
+
+@item
+@code{RENAME} funktioniert nicht bei @code{TEMPORARY}-Tabellen.
+
+@item
+Unter Umständen behandelt der Optimierer (Optimizer) @code{DISTINCT}
+unterschiedlich, je nachdem, ob Sie 'versteckte' Spalten in einem Join
+benutzen oder nicht. In einem Join werden versteckte Spalten als Teil des
+Ergebnisses gezählt (selbst wenn sie nicht angezeigt werden), während
+versteckte Spalten in normalen Anfragen nicht an einem @code{DISTINCT}-Vergleich
+teilnehmen. Zukünftig werden wir dieses Verhalten wahrscheinlich ändern, so
+dass versteckte Spalten nie verglichen werden, wenn @code{DISTINCT} ausgeführt
+wird.
+
+Hierfür ein Beispiel:
+
+@example
+SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id
+DESC;
+@end example
+
+und
+
+@example
+SELECT DISTINCT band_downloads.mp3id, FROM band_downloads,band_mp3
+WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id
+ORDER BY band_downloads.id DESC;
+@end example
+
+Im zweiten Fall bekommen Sie in MySQL 3.23.x möglicherweise zwei identische
+Zeilen in der Ergebnismenge (weil die versteckten 'id'-Spalten
+unterschiedlich sein können).
+
+Beachten Sie, dass dies nur für Anfragen zutrifft, bei denen die ORDER
+BY-Spalten nicht im Ergebnis enthalten sind. ANSI-SQL erlaubt dies nicht
+
+@item
+Weil MySQL es zuläßt, mit Tabellentypen zu arbeiten, die keine
+Transaktionen unterstützen (und folglich Daten nicht per @code{rollback} in
+den vorherigen Zustand bringen können), verhalten sich einige Dinge in
+MySQL etwas anderes als in anderen SQL-Servern. Das kann manchmal etwas
+ungünstig sein, weil Spaltenwerte in der Applikation überprüft werden
+müssen. Auf der anderen Seite erhalten Sie dadurch eine nette
+Geschwindigkeitssteigerung, weil es MySQL gestattet, einige Optimierungen
+vorzunehmen, die ansonsten sehr schwer durchzuführen sein würden.
+
+Wenn Sie eine Spalte auf einen nicht zulässigen Wert setzen, speichert
+MySQL, statt ein Rollback durchzuführen, den @code{besten möglichen Wert}
+in der Spalte:
+
+@itemize @minus
+@item
+Wenn Sie versuchen, in einer numerischen Spalte einen Wert ausserhalb des
+Wertebereichs zu speichern, speichert MySQL statt dessen den kleinsten oder
+größten möglichen Wert.
+
+@item
+Wenn Sie versuchen, eine Zeichenkette, die nicht mit einer Zahl beginnt, in
+einer numerischen Spalte zu speichern, speichert MySQL 0.
+
+@item
+Wenn Sie versuchen, @code{NULL} in einer Spalte zu speichern, die keine
+@code{NULL}-Werte zuläßt, speichert MySQL 0 oder @code{''} (leere
+Zeichenkette). (Man kann dieses Verhalten jedoch mit der
+-DDONT_USE_DEFAULT_FIELDS-Kompilierungs-Option ändern.)
+
+@item
+MySQL läßt zu, dass einige falsche Datumswerte in @code{DATE}- und
+@code{DATETIME}-Spalten gespeichert werden (wie 2000-02-31 oder
+2000-02-00). Wenn das Datum völlig falsch ist, speichert MySQL den
+speziellen Datumswert 0000-00-00 in der Spalte.
+
+@item
+Wenn Sie @code{enum} auf einen nicht unterstützten Wert setzen, wird es auf
+den Fehlerwert 'leere Zeichenkette' oder (bei numerischen Werten) auf 0
+gesetzt.
+@end itemize
+
+@item
+Wenn Sie @code{PROCEDURE} auf eine Anfrage ausführen, die eine leere
+Ergebnismenge liefert, kann es in einigen Fällen vorkommen, dass
+@code{PROCEDURE} die Spalten nicht umwandelt.
+
+@item
+Wenn Sie eine Tabelle vom Typ @code{MERGE} anlegen, wird nicht überprüft,
+ob die zugrunde liegenden Tabellen von einem kompatiblen Typ sind.
+
+@item
+MySQL kann bislang nicht mit @code{NaN}-, @code{-Inf}- und
+@code{Inf}-Werten in Doubles umgehen. Wenn Sie diese benutzen, gibt es
+Probleme, wenn Daten importiert oder exportiert werden. Als Zwischenlösung
+sollten Sie @code{NaN} in @code{NULL} umwandeln (falls möglich) und
+@code{-Inf} und @code{Inf} in den kleinsten bzw. größten möglichen Wert.
+
+@item
+Negative Zahlen in der @code{LIMIT}-Klausel werden als große positive
+Zahlen behandelt.
+
+@item
+Wenn Sie @code{ALTER TABLE} benutzen, um einen @code{UNIQUE}-Index zu einer
+Tabelle hinzuzufügen, die in einer @code{MERGE}-Tabelle benutzt wird, und
+dann @code{ALTER TABLE} benutzen, um der @code{MERGE}-Tabelle einen
+normalen Index hinzuzufügen, weicht die Reihenfolge der Schlüssel für die
+Tabellen ab. Das liegt daran, dass @code{ALTER TABLE}
+@code{UNIQUE}-Schlüssel vor normalen Schlüsseln einfügt, um doppelte
+Schlüssel so früh wie möglich erkennen zu können.
+@end itemize
+
+Folgende bekannte Bugs gibt es in früheren Versionen von MySQL:
+
+@itemize @bullet
+@item
+Man kann einen hängenden Thread erhalten, wenn man @code{DROP TABLE} auf
+eine Tabelle ausführt, die zu vielen Tabellen gehört, die mit @code{LOCK
+TABLES} gesperrt sind.
+
+@item
+In folgenden Fällen können Sie einen Core Dump erhalten:
+
+@itemize @minus
+@item
+Die Routine für verzögertes Einfügen (Delayed Insert Handler) hat noch nie
+ausgeführte Einfügeoperationen (Pending Inserts) auf eine Tabelle.
+
+@item
+@code{LOCK tabelle} mit @code{WRITE}
+
+@item
+@code{FLUSH TABLES}
+@end itemize
+
+@item
+Vor MySQL-Version 3.23.2 kann ein @code{UPDATE} fehlschlagen, dass einen
+Schlüssel mit einer @code{WHERE}-Klausel auf denselben Schlüssel
+aktualisiert, weil der Schlüssel benutzt wurde, um nach Datensätzen zu
+suchen, und dieselbe Zeile mehrfach gefunden wurde:
+
+@example
+UPDATE tabelle SET KEY=KEY+1 WHERE KEY > 100;
+@end example
+
+Ein Workaround besteht in der Benutzung von:
+
+@example
+mysql> UPDATE tabelle SET KEY=KEY+1 WHERE KEY+0 > 100;
+@end example
+
+Das funktioniert, weil MySQL auf Ausdrücke (Expressions) in der
+@code{WHERE}-Klausel keine Indizes benutzt.
+
+@item
+Vor MySQL-Version 3.23 wurden alle numerischen Typen als Festkomma-Felder
+behandelt. Das bedeutet, dass Sie festlegen müssen, wie viele
+Dezimalstellen ein Fließkomma-Feld haben soll. Alle Werte wurden mit der
+korrekten Anzahl von Dezimalstellen zurückgegeben.
+@end itemize
+
+Was Plattform-spezifische Bugs angeht, sehen Sie bitte im Abschnitt über
+Kompilieren und Portieren nach.
+
+
+@node TODO, Comparisons, Compatibility, Deutsch
+@c German node TODO
+@section MySQL und die Zukunft (das TODO)
+
+@cindex TODO-Liste für MySQL
+
+
+Dieser Anhang listet die Features auf, für die wir eine Implementierung in
+MySQL geplant haben.
+
+Alles auf dieser Liste gibt nur ungefähr die Reihenfolge wieder, in der es
+gemacht werden wird. Wenn Sie die Prioritäten beeinflussen wollen,
+registrieren Sie bitte eine Lizenz oder unterstützen Sie uns und teilen uns
+mit, was Sie schneller gemacht haben wollen. @xref{Lizenzpolitik}.
+
+Geplant ist, dass wir in Zukunft den kompletten ANSI-SQL99-Standard
+unterstützen, aber mit einer Menge nützlicher Erweiterungen. Die
+Herausforderung liegt darin, dass durchzuführen, ohne
+Geschwindigkeitsvorteile zu opfern oder den Code zu kompromittieren.
+
+
+@menu
+* TODO MySQL 4.0::
+* TODO future::
+* TODO sometime::
+* TODO unplanned::
+@end menu
+
+@node TODO MySQL 4.0, TODO future, TODO, TODO
+@c German node TODO MySQL 4.0
+@subsection Dinge, die in Version 4.0 enthalten sein sollten
+
+Wir haben uns der Entwicklung von MySQL Version 4.0 zugewandt. Die meisten
+grundsätzlichen Dinge, die wir in Version 4.0 haben wollen, sind bereits
+gemacht. Das Ziel ist, den Rest der folgenden Features schnell einzubauen
+und dann zur Entwicklung von MySQL 4.1 überzugehen.
+@c German FIX Added . after @xref.
+@xref{MySQL 4.0 In A Nutshell}.
+
+Der News-Abschnitt für 4.0 beinhaltet eine Liste der Features, die wir
+bereits im 4.0-Baum implementiert haben. @xref{News-4.0.x}.
+
+@itemize @bullet
+@item
+Benutzern erlauben, die Startoptionen zu ändern, ohne den Server herunter
+fahren zu müssen.
+@item
+Störsichere Replikation.
+@item
+Mehr Funktionen für die Volltextsuche.
+@xref{Volltext-Features in MySQL 4.0}.
+@item
+Neuer Schlüssel-Cache
+@item
+Neues Dateiformat für die Tabellendefinition (@code{.frm}-Dateien). Das
+versetzt uns in die Lage, nicht irgendwann keine Bits mehr zu haben, wenn
+wir weitere Tabellenoptionen hinzufügen. Es wird nach wie vor möglich sein,
+in 4.0 das alte @code{.frm}-Dateiformat zu benutzen. Alle neu erzeugten
+Tabellen werden jedoch das neue Format benutzen.
+
+Das neue Dateiformat versetzt uns in die Lage, neue Spaltentypen, mehr
+Optionen für Schlüssel und @code{FOREIGN KEY}-Support hinzuzufügen.
+@item
+Die Replikation sollte mit @code{RAND()} und Benutzer-Variablen
+@code{@@var} funktionieren.
+@item
+Online-Datensicherung mit sehr geringen Performance-Einbussen. Das Online-Backup
+wird das Hinzufügen eines neuen Replikations-Slaves erleichtern, ohne dass
+man den Master herunter fahren muss.
+@item
+Es zulassen, dass @code{DELETE} auf @code{MyISAM}-Tabellen den
+Datensatz-Cache benutzt. Um das zu tun, müssen wir den Thread-Cache für
+Datensätze aktualisieren, wenn wir die @code{.MYD}-Datei aktualisieren.
+@item
+Zeichensatz-Festlegungen (Casts) und Syntax für die Handhabung mehrerer
+Zeichensätze.
+@item
+Hilfe für alle Befehle des Clients.
+@item
+Sichere Verbindungen (mit SSL).
+@item
+@code{SHOW COLUMNS FROM tabelle} (der vom @code{mysql}-Client benutzt für
+die Erweiterung von Spaltennamen benutzt wird) sollte nicht die Tabelle
+öffnen, sondern nur die Definitionsdatei. Das wird weniger Speicher
+beanspruchen und sehr viel schneller sein.
+@item
+Bei der Benutzung von @code{SET CHARACTER SET} sollten wir die gesamte
+Anfrage übersetzen und nicht nur Zeichenketten. Das würde Benutzern
+ermöglichen, landesspezifische Zeichen auch in Datenbank-, Tabellen- und
+Spaltenamen zu benutzen.
+@item
+Hinzufügen einer portablen Schnittstelle zu @code{gethostbyaddr_r()},
+damit wir @code{ip_to_hostname()} davon abhalten können, andere Threads zu
+blockieren, während es DNS-Lookups durchführt.
+@item
+Hinzufügen der @code{record_in_range()}-Methode zu @code{MERGE}-Tabellen,
+um den richtigen Index auswählen zu können, wenn es viele gibt, aus denen
+ausgewählt werden kann. Wir sollten auch die info-Schnittstelle erweitern,
+um die Schlüsselverteilung für jeden Index zu erhalten, wenn @code{analyze}
+über alle Unter-Tabellen läuft.
+@item
+@code{SET SQL_DEFAULT_TABLE_TYPE=[MyISAM | INNODB | BDB | HEAP]}.
+@end itemize
+
+
+@node TODO future, TODO sometime, TODO MySQL 4.0, TODO
+@c German node TODO zukünftig
+@subsection Dinge, die in naher Zukunft erledigt werden müssen
+
+@itemize @bullet
+@item
+Unteranfragen (Subqueries).
+@code{select id from t where grp in (select grp from g where u > 100)}
+@item
+Atomische Multi-Tabellen-Updates, zum Beispiel @code{update items,month set
+items.price=month.price where items.id=month.id;};
+@item
+Abgeleitete Tabellen (Derived Tables).
+@example
+select a.col1, b.col2 from (select max(col1) as col1 from root_table ) a,
+other_table b where a.col1=b.col1
+@end example
+
+Das könnte erreicht werden, indem für die Dauer der Anfrage automatisch
+temporäre Tabellen für die abgeleiteten Tabellen erzeugt werden.
+@item
+Hinzufügen eines @code{PREPARE} von Statements und Senden von Parametern an
+@code{mysqld}.
+@item
+Erweiterung des Client-Server-Protokolls, um Warnungen (Warnings) zu
+unterstützen.
+@item
+Hinzufügen von Optionen zum Client-Server-Protokoll, um
+Fortschrittsanzeigen für lange laufende Kommandos zu erhalten.
+@item
+Hinzufügen von Datenbank und echtem Tabellennamen (im Falle von Alias) zur
+MYSQL_FIELD-Struktur.
+@item
+Nicht mehr als die festgelegte Anzahl von Threads zulassen, um MyISAM
+recover zeitgleich laufen zu lassen.
+@item
+@code{INSERT ... SELECT} ändern, um optional konkurrierende Inserts zu
+benutzen.
+@item
+@code{RENAME DATABASE} implementieren. Damit das sicher für alle
+Tabellen-Handler funktioniert, sollte es wie folgt laufen:
+@itemize @bullet
+@item
+Neue Datenbank anlegen.
+@item
+Für jede Tabelle ein Umbenennen der Tabelle zu einer anderen Datenbank
+durchführen, wie wir es schon mit dem @code{RENAME}-Befehl machen.
+@item
+Alte Datenbank löschen.
+@end itemize
+@item
+Die Original-Feldtypen zurückgeben, wenn @code{SELECT MIN(column)... GROUP
+BY} ausgeführt wird.
+@item
+Mehrfache Ergebnismengen (Multiple Result Sets).
+@item
+Änderung des Protokolls, um Binärübertragung von Werten zu ermöglichen. Um
+das effizient zu machen, müssen wir eine API hinzufügen, die Bindung
+(Binding) von Variablen erlaubt.
+
+
+@code{mysqld}.
+@item
+Es soll möglich sein, @code{long_query_time} mit einer Auflösung in
+Mikrosekunden festzulegen.
+@item
+Hinzufügen eines konfigurierbaren Prompts zum
+@code{mysql}-Kommandozeilen-Werkzeug, mit Optionen wie Datenbank in Benutzung,
+Zeit und Datum ...
+@item
+Hinzufügen von Bereichsüberprüfung (Range Checking) zu
+@code{MERGE}-Tabellen.
+@item
+@code{myisampack}-Code in den Server einlinken.
+@item
+Portierung von MySQL auf BeOS.
+@item
+Portierung von MySQL-Clients auf LynxOS.
+@item
+Hinzufügen eines temporären Schlüssel-Puffer-Caches während
+@code{INSERT/DELETE/UPDATE}, um den vorherigen Zustand elegant
+wiederherstellen zu können, wenn der Index voll wird.
+@item
+Wenn ein @code{ALTER TABLE} auf eine Tabelle durchgeführt wird, die per
+Symlink auf einer anderen Festplatte ist, temporäre Tabellen auf dieser
+Festplatte erzeugen.
+@item
+Implementierung eines @code{DATE/DATETIME}-Typs, der
+Zeitzonen-Informationen sauber handhabt, damit der Umgang mit Datumswerten
+in verschiedenen Zeitzonen leichter wird.
+@item
+FreeBSD- und MIT-pThreads; nehmen schlafende Threads CPU in Anspruch?
+@item
+Prüfen, ob gesperrte Threads CPU beanspruchen.
+@item
+Configure reparieren, so dass man alle Bibliotheken (wie @code{MyISAM})
+ohne Threads kompilieren kann.
+@item
+Hinzufügen einer Option, um regelmäßig die Schlüsselseiten (Key Pages) für
+Tabellen mit verzögerten Schlüsseln (Delayed Keys) zu löschen (flush), wenn
+Sie eine Weile nicht in Gebrauch waren.
+@item
+Verknüpfungen (Join) auf Teile des Schlüssels zulassen (Optimierungsthema).
+@item
+@code{INSERT SQL_CONCURRENT} und @code{mysqld --concurrent-insert} sollen
+ein konkurrierendes Insert am Ende der Datei machen, falls die Datei
+lese-gesperrt ist.
+@item
+@code{FOREIGN}-Key-Festlegungen in der @file{.frm}-Datei speichern.
+@item
+Kaskadierendes Löschen (@code{DELETE})
+@item
+Serverseitige Cursor.
+@item
+Prüfen, ob @code{lockd} mit modernen Linux-Kernels funktioniert; wenn
+nicht, müssen wir @code{lockd} überarbeiten! Um das zu testen, startet man
+@code{mysqld} mit @code{--enable-locking} und läßt die verschiedenen fork*
+test suits laufen. Sie sollten keine Fehler produzieren, wenn @code{lockd}
+funktioniert.
+@item
+SQL-Variablen in @code{LIMIT} zulassen, wie @code{LIMIT @@a,@@b}.
+@item
+Aktualisierung von Variablen in @code{UPDATE}-Statements zulassen, zum
+Beispiel: @code{UPDATE TABLE foo SET @@a=a+b,a=@@a, b=@@a+c}
+@item
+Wenn Benutzervariablen aktualisiert werden, so ändern, dass man sie mit
+@code{GROUP BY} benutzen kann wie in folgendem Beispiel:
+@code{SELECT id, @@a:=count(*), sum(sum_col)/@@a FROM tabelle GROUP BY id}.
+@item
+Keine automatischen @code{DEFAULT}-Werte zu Spalten hinzufügen. Fehler
+ausgeben, wenn ein @code{INSERT} benutzt wird, dass keine Spalte enthält,
+die keinen @code{DEFAULT}-Wert hat.
+@item
+Caching von Anfragen und Ergebnissen. Das sollte als separates Modul
+gemacht werden, das jede Anfrage prüft. Falls diese Anfrage im Cache ist,
+soll das Cache-Ergebnis zurückgegeben werden. Wenn man eine Tabelle
+aktualisiert, sollte man so wenige Anfragen wie möglich aus dem Cache
+entfernen. Das sollte eine große Geschwindigkeitssteigerung auf Maschinen
+geben, die viel RAM haben und wo Anfragen of wiederholt werden (wie
+WWW-Applikationen). Eine Idee wäre, nur Anfrage des Typs
+@code{SELECT CACHED ...}
+zu cachen.
+@item
+@file{libmysql.c} überarbeiten, damit zwei @code{mysql_query()}-Befehle in
+einer Zeile stehen können, ohne dass Ergebnisse gelesen werden oder man
+eine nette Fehlermeldung erhält, wenn man das tut.
+@item
+Optimierung des @code{BIT}-Typs, so dass er 1 Bit aufnimmt (momentan nimmt
+@code{BIT} 1 Zeichen auf).
+@item
+Prüfen, warum MIT-pThreads @code{ctime()} auf einigen FreeBSD-Systemen
+nicht funktioniert.
+@item
+Hinzufügen einer @code{IMAGE}-Option zu @code{LOAD DATA INFILE}, damit
+@code{TIMESTAMP}- und @code{AUTO_INCREMENT}-Felder nicht aktualisiert
+werden.
+@item
+@code{LOAD DATE INFILE.. UPDATE}-Syntax hinzufügen.
+@itemize @bullet
+@item
+Wenn Daten bei Tabellen mit Primärschlüssel den Primärschlüssel enthalten,
+werden Einträge, die zu diesem Primärschlüssel passen, vom Rest der Spalten
+aktualisert. Spalten, die im herein kommenden Datenstrom NICHT enthalten
+sind, werden jedoch nicht berührt.
+@item
+Bei Tabellen mit Primärschlüsseln, wo im herein kommenden Datenstrom ein
+Teil des Schlüssels fehlt, oder wenn kein Primärschlüssel eingegeben wird,
+wird die Eingabe so behandelt wie jetzt schon @code{LOAD DATA INFILE ...
+REPLACE INTO}.
+@end itemize
+@item
+@code{LOAD DATA INFILE} soll auch folgende Syntax verstehen:
+@example
+LOAD DATA INFILE 'datei.txt' INTO TABLE tabelle
+TEXT_FIELDS (text_feld1, text_feld2, text_feld3)
+SET tabelle_feld1=concatenate(text_feld1, text_feld2), tabelle_feld3=23
+IGNORE text_feld3
+
+Das kann benutzt werden, um zusätzliche Spalten in der Textdatei zu
+überspringen oder um Spalten basierend auf Ausdrücken in den gelesenen
+Daten zu aktualisieren ...
+@end example
+@item
+@code{LOAD DATA INFILE 'datei' INTO TABLE 'tabelle' ERRORS TO err_tabelle}
+Das würde bewirken, dass alle Fehler und Warnungen in der err_tabelle
+mitgeschrieben werden. Diese Tabelle hätte etwa folgende Struktur:
+
+@example
+zeile_nummer - Zeilennummer in der Datendatei
+fehler_nachricht - die Fehler-/Warnungs-Nachricht
+und vielleicht
+@c German FIX changed all "@cQuestion ..." lines to "@c Question ..." (space).
+@c Question: ??? This is already logged in zeile_nummer (line_number)!
+daten_zeile - die Zeilennummer der Datendatei
+@end example
+@item
+Hinzufügen von echter @code{VARCHAR}-Unterstützung (gibt es schon in
+MyISAM).
+@item
+Automatische Ausgabe von @code{mysql} an Netscape.
+@item
+@code{LOCK DATABASES}. (mit vielerlei Optionen)
+@item
+
+
+Ändern wie Sortierung Speicher alloziert, um bessere
+Speicherausnutzung zu erhalten.
+@item
+@code{DECIMAL}- und @code{NUMERIC}-Typen können keine exponentiellen Zahlen
+lesen; @code{Field_decimal::store(const char *from,uint len)} muss neu
+kodiert werden, um das zu beheben.
+@item
+@code{mysql.cc} überarbeiten, damit weniger @code{malloc()}-Aufrufe
+durchgeführt werden, wenn Feldnamen gehasht werden.
+@item
+Funktionen:
+ADD_TO_SET(wert,set) und REMOVE_FROM_SET(wert,set)
+@item
+Benutzung von @code{t1 JOIN t2 ON ...} und @code{t1 JOIN t2 USING ...}
+hinzufügen. Momentan kann man diese Syntax nur mit @code{LEFT JOIN}
+benutzen.
+@item
+Volle Unterstützung für @code{unsigned long long}-Typen hinzufügen.
+@item
+Viele weitere Variablen für @code{show status}. Zähler für:
+@code{INSERT}-/@code{DELETE}-/@code{UPDATE}-Statements. Gelesene und
+aktualisierte Datensätze. Select auf 1 Tabelle und Selects mit Joins.
+Durchschnittliche Anzahl von Tabellen in Selects. Anzahl von @code{ORDER
+BY}- und @code{GROUP BY}-Anfragen.
+@item
+Wenn man @code{mysql} mitten in einer Anfrage abbricht, sollte man eine
+neue Verbindung herstellen und die alte, laufende Anfrage killen.
+Alternativ könnte man den Versuch unternehmen, so etwas im Server zu
+entdecken.
+@item
+Eine Handler-Schnittstelle für Tabelleninformation hinzufügen, damit man
+sie als Systemtabelle benutzen kann. Das wäre ein bisschen langsam, wenn
+man Informationen über alle Tabellen abfragt, aber sehr flexibel.
+@code{SHOW INFO FROM tabelle} für Basisinformationen über Tabellen sollte
+implementiert werden.
+@item
+Unterstützung für UNICODE hinzufügen.
+@item
+@code{NATURAL JOIN} und @code{UNION JOIN}.
+@item
+Anfragen wie @code{select a from crash_me left join crash_me2 using (a)}
+zulassen; in diesem Fall wird angenommen, dass a aus der crash_me-Tabelle
+kommt.
+@item
+Überarbeitung, damit @code{ON} und @code{USING} mit dem
+@code{JOIN}-Verknüpfungstyp funktioniert.
+@item
+Oracle-mäßiges @code{CONNECT BY PRIOR ...}, um hierarchische Strukturen zu
+durchsuchen.
+
+
+@item
+@code{mysqladmin copy datenbank neue_datenbank}. -- Erfordert, dass
+@code{mysqld} der COPY-Befehl hinzugefügt wird.
+@item
+Prozessliste sollte die Anzahl von Anfragen pro Thread zeigen.
+@item
+
+
+@code{SHOW HOSTS} zur Informationsausgaben über den Hostnamen-Cache.
+@item
+
+
+
+@item
+Format von @code{DATETIME} ändern, um Bruchteile von Sekunden zu speichern.
+@item
+Alle fehlenden ANSI92- und ODBC 3.0-Typen hinzufügen.
+@item
+Für berechnete Spalten Tabellennamen von leerer Zeichenkette zu @code{NULL}
+ändern.
+@item
+'Item_copy_string' nicht auf numerische Werte anwenden, um
+Zahl->Zeichenkette->Zahl-Umwandlung zu vermeiden, im Falle von:
+@code{SELECT COUNT(*)*(id+0) FROM tabelle GROUP BY id}
+@item
+Benutzung der neuen GNU-regexp-Bibliothek anstelle der aktuellen
+ermöglichen (die GNU-Bibliothek sollte viel schneller sein als die alte).
+@item
+@code{ALTER TABLE} sollte nicht mehr Clients abbrechen, die @code{INSERT
+DELAYED} ausführen.
+@item
+So überarbeiten, dass, wenn Spalten, auf die in einer @code{UPDATE}-Klausel
+verwiesen wird, die alten Werte enthalten, bevor das Update begonnen wird.
+@item
+@code{myisamchk}, @code{REPAIR} und @code{OPTIMIZE TABLE} sollten in der
+Lage sein, mit Fällen umzugehen, wo die Daten und / oder Indexdateien
+symbolische Links sind.
+@item
+Simulation von @code{pread()}/@code{pwrite()} auf Windows einarbeiten, um
+konkurrierende Inserts zu ermöglichen.
+@item
+Ein Logdatei-Analyzer, aus dem Informationen herausgefiltert (geparst)
+werden können, welche Tabellen am häufigsten angesprochen werden, wie oft
+Verknüpfungen (Joins) mit mehreren Tabellen ausgeführt werden usw. Es
+sollte Benutzern helfen, Bereiche oder Dinge im Tabellenentwurf zu
+erkennen, die optimiert werden können, um sehr viel effizientere Anfragen
+auszuführen.
+@item
+Add @code{SUM(DISTINCT)}
+@item
+@code{ANY()}-,@code{EVERY()}- und @code{SOME()}-Gruppierungsfunktionen
+hinzufügen. In ANSI-SQL funktionieren diese auf boolsche Spalten, aber wir
+können sie so erweitern, dass sie mit beliebigen Spalten / Ausdrücken
+funktionieren, indem wir folgendes anwenden: wert == 0 -> FALSE und
+wert <> 0 -> TRUE.
+@item
+So überarbeiten, dass @code{MAX(column)} vom selben Typ ist wie der
+Spaltentyp.
+@example
+create tabelle t1 (a DATE);
+insert into t1 values (now());
+create tabelle t2 select max(a) von t1;
+show columns from t2;
+@end example
+@item
+Eine nette Syntax für ein Statement entwickeln, dass auf eine Zeile ein
+@code{UPDATE} ausführt, wenn sie existiert, und eine neue Zeile einfügt
+(@code{INSERT}), wenn sie nicht existiert (so wie @code{REPLACE} bei
+@code{INSERT} / @code{DELETE} funktioniert).
+@end itemize
+
+
+@node TODO sometime, TODO unplanned, TODO future, TODO
+@c German node TODO irgendwann
+@subsection Dinge die irgendwann gemacht werden müssen
+
+@itemize @bullet
+@item
+Funktion implementieren: @code{get_changed_tables(timeout,table1,table2,...)}
+@item
+Lesen durch Tabellen so ändern, das memmap benutzt wird, falls möglich.
+Momentan benutzen nur komprimierte Tabellen memmap.
+@item
+Ein neues Zugriffsrecht @strong{'Show_priv'} für @code{SHOW}-Befehle
+hinzufügen.
+@item
+Den automatischen Zeitstempel-Code netter machen. Zeitstempel zum
+Update-Log hinzufügen mit @code{SET TIMESTAMP=#;}
+@item
+An manchen Stellen read/write mutex benutzen, um mehr Geschwindigkeit zu
+erhalten.
+@item
+Volle Unterstützung von Fremdschlüsseln. Wahrscheinlich wird man zuerst
+einmal eine prozedurale Sprache implementieren wollen.
+@item
+Einfache Sichten (Views; zunächst auf eine Tabelle, später auf jeden
+beliebigen Ausdruck).
+@item
+Automatisches Schließen einiger Tabellen, wenn eine Tabelle, eine
+temporäre Tabelle oder eine temporäre Datei einen Fehler 23 bekommt
+(nicht genug offene Dateien).
+@item
+Wenn ein Feld=# gefunden wird, alle Vorkommen von Feld auf # setzen.
+Momentan wird das nur in einigen einfachen Fällen gemacht.
+@item
+Alle konstanten Ausdrücke mit berechneten Ausdrücken austauschen, falls
+möglich.
+@item
+schlüssel = ausdruck optimieren. Momentan wird nur schlüssel = feld oder
+schlüssel = konstante optimiert.
+@item
+Einige der Copy-Funktionen verbinden, um netter Code zu erhalten.
+@item
+@file{sql_yacc.yy} in einen Inline-Parser umändern, um die Größe zu
+reduzieren und bessere Fehlermeldungen zu erhalten (5 Tage).
+@item
+Den Parser so ändern, dass er nur eine Regel pro unterschiedlicher Anzahl
+von Argumenten in Funktionen benutzt.
+@item
+Die Benutzung von vollen Berechnungsnamen (full calculation names) im
+ORDER-Teil (order part). (Für ACCESS97)
+@item
+@code{UNION}, @code{MINUS}, @code{INTERSECT} und @code{FULL OUTER JOIN}.
+(Momentan wird nur @code{LEFT OUTER JOIN} unterstützt.)
+@item
+@code{UNIQUE} bei Feldern zulassen, die @code{NULL} sein können.
+@item
+@code{SQL_OPTION MAX_SELECT_TIME=#} um einer Anfrage eine Zeitbeschränkung
+zu setzen.
+@item
+@c Question: Check translation!
+Make the update log to a Datenbank.
+Update soll in eine Datenbank loggen.
+@item
+Negative @code{LIMIT}-Parameter, um Daten vom Ende abrufen zu können.
+@item
+@c Question: Alarm? Wake up?
+Alarm around client connect/read/write Funktionen.
+@item
+Bitte beachten sie die Änderungen in @code{safe_mysqld}: Nach FSSTND (woran
+sich Debian versucht zu halten) sollten PID-Dateien als
+@file{/var/run/<progname>.pid} angelegt werden und Log-Datei in
+@file{/var/log}. Es wäre nett, wenn man "DATADIR" in die erste Deklaration
+von "pidfile" und "log" packen könnte, damit die Unterbringung dieser
+Dateien mit einem einzigen Statement geändert werden könnte.
+@item
+Einem Client erlauben, Mitloggen anzufordern.
+@item
+Benutzung von @code{zlib()} für @code{gzip}-te Dateien in @code{LOAD DATA
+INFILE} zulassen.
+@item
+Sortieren und Gruppieren von @code{BLOB}-Spalten in Ordnung bringen
+(teilweise bereits gelöst).
+@item
+Gespeicherte Prozeduren. Wird aktuell nicht als sehr wichtig erachtet, weil
+gespeicherte Prozeduren noch nicht sehr standardisiert sind. Ein weiteres
+Problem besteht darin, dass es echte gespeicherte Prozeduren dem Optimierer
+viel schwerer machen und dass in vielen Fällen das Ergebnis langsamer sein
+wird als vorher. Auf der anderen Seite werden wir versuchen, eine einfache
+(atomische) Update-Sprache hinzuzufügen, die benutzt werden kann, um
+Schleifen und ähnliches im MySQL-Server zu schreiben.
+@item
+So ändern, dass Semaphore benutzt werden, wenn Threads gezählt werden. Man
+sollte zuerst eine Semaphor-Bibliothek zu MIT-pThreads implementieren.
+@item
+Keinen neuen @code{AUTO_INCREMENT}-Wert zuweisen, wenn eine Spalte auf 0
+gesetzt wird. Statt dessen @code{NULL} setzen.
+@item
+Volle Unterstützung von Verknüpfungen (@code{JOIN}) mit Klammern.
+@item
+Als Alternative für einen Thread pro Verbindung einen Pool von Threads
+verwalten, der die Anfragen handhabt.
+@item
+Einem gestatten, mehr als eine Sperre (Lock) mit @code{GET_LOCK} zu
+erhalten. Wenn man das tut, muss man die möglichen Deadlocks handhaben, die
+diese Änderung einführen wird.
+@end itemize
+
+Zeitangaben stehen für den Umfang der Arbeit, nicht für echte Zeit.
+
+
+@node TODO unplanned, , TODO sometime, TODO
+@c German node TODO ungeplant
+@subsection Ein paar Dinge, für deren Umsetzung wir keine Pläne haben
+
+@itemize @bullet
+@item
+Nichts; auf lange Sicht planen wir, voll ANSI-92- / ANSI-99-kompatibel zu
+sein.
+@end itemize
+
+
+@node Comparisons, , TODO, Deutsch
+@c German node Vergleiche
+@section MySQL im Vergleich mit anderen Datenbanken
+
+@cindex Datenbanken, MySQL im Vergleich mit anderen
+@cindex Vergleich, MySQL zu anderen
+
+
+Dieser Abschnitt vergleicht MySQL mit anderen populären Datenbanken.
+
+Dieser Abschnitt wurde von den MySQL-Entwicklern geschrieben. Das sollte
+man beim Lesen im Hinterkopf behalten. In diesem Abschnitt sind - soweit
+uns bekannt - keine sachlichen Fehler enthalten. Wenn Sie etwas finden, was
+Sie als sachlichen Fehler erachten, kontaktieren Sie uns bitte unter
+@email{docs@@mysql.com}.
+
+Eine Liste aller unterstützten Limits, Funktionen und Typen finden Sie auf
+der @code{crash-me}-Webseite auf
+@uref{http://www.mysql.com/information/crash-me.php}.
+
+
+@menu
+* Compare mSQL::
+* Compare PostgreSQL::
+@end menu
+
+@node Compare mSQL, Compare PostgreSQL, Comparisons, Comparisons
+@c German node Vergleich mit mSQL
+@subsection MySQL im Vergleich mit @code{mSQL}
+
+@table @strong
+@item Performance
+
+Um einen echten Geschwindigkeitsvergleich zu sehen, schauen Sie bitte in
+der wachsenden Liste der MySQL-Benchmarks nach. @xref{MySQL Benchmarks}.
+
+Weil es keinen Overhead für die Erzeugung von Threads besitzt, einen
+kleineren Parser, weniger Features und einfache Sicherheitsmechanismen,
+sollte @code{mSQL} in folgenden Punkten schneller sein:
+
+@itemize @bullet
+@item
+Tests, die wiederholten Verbindungsaufbau und -abbau durchführen, wobei
+während jeder Verbindung eine sehr einfache Anfrage ausgeführt wird.
+
+@item
+@code{INSERT}-Operationen auf sehr einfache Tabellen mit wenigen Spalten
+und Schlüsseln.
+
+@item
+@code{CREATE TABLE} und @code{DROP TABLE}.
+
+@item
+@code{SELECT} auf alles, was kein Index ist. (Ein Tabellen-Scan ist sehr
+einfach.)
+@end itemize
+
+Weil diese Operationen so einfach sind, ist es schwer, hier besser zu sein,
+wenn man beim Starten einen größeren Overhead hat. Nachdem die Verbindung
+erst einmal aufgebaut ist, sollte MySQL wesentlich bessere Leistungsdaten
+bringen.
+
+Andererseits ist MySQL sehr viel schneller als @code{mSQL} (und den meisten
+anderen SQL-Implementationen) bei Folgendem:
+
+@itemize @bullet
+@item
+Komplexe @code{SELECT}-Operationen.
+
+@item
+Wenn große Ergebnismengen abgefragt werden (MySQL hat ein besseres,
+schnelleres und sichereres Protokoll).
+
+@item
+Tabellen mit Zeichenketten variabler Länge, denn MySQL hat eine
+effizientere Handhabung und kann Indizes auf @code{VARCHAR}-Spalten haben.
+
+@item
+Handhabung von Tabellen mit vielen Spalten.
+
+@item
+Handhabung von Tabellen mit großer Datensatzlänge.
+
+@item
+@code{SELECT} mit vielen Ausdrücken.
+
+@item
+@code{SELECT} auf große Tabellen.
+
+@item
+Handhabung vieler gleichzeitiger Verbindungen. MySQL ist voll
+Multi-Thread-fähig. Jede Verbindung hat ihren eigenen Thread, was bedeutet,
+dass kein Thread auf einen anderen warten muss (ausser wenn ein Thread eine
+Tabelle verändert, auf die ein anderer Thread zugreifen will). In
+@code{mSQL} müssen nach dem Verbindungsaufbau alle anderen warten, bis die
+erste Verbindung beendet wurde, egal, ob diese Verbindung eine Anfrage
+ausführt, die kurz oder lang ist. Wenn die erste Verbindung abgebaut wird,
+kann die zweite bedient werden, während alle anderen noch warten, usw.
+
+@item
+Joins (Verknüpfungen).
+@code{mSQL} kann krankhaft langsam werden, wenn Sie die Reihenfolge von
+Tabellen in einem @code{SELECT}-Statement ändern. In einem Benchmark-Test
+wurde beobachtet, dass es mehr als 15000-mal langsamer werden kann als
+MySQL. Das liegt daran, dass @code{mSQL} keinen Verknüpfungs-Optimierer
+(Join Optimizer) besitzt, der die Tabellen in optimale Reihenfolge bringt.
+Wenn Sie allerdings exakt die richtige Reihenfolge in @code{mSQL}2 benutzen
+und wenn die @code{WHERE}-Klausel einfach ist und Spalten-Indexe benutzt,
+wird die Verknüpfung relativ schnell sein!
+@xref{MySQL Benchmarks}.
+
+@item
+@code{ORDER BY} und @code{GROUP BY}.
+
+@item
+@code{DISTINCT}.
+
+@item
+Benutzung von @code{TEXT}- oder @code{BLOB}-Spalten.
+@end itemize
+
+@item SQL-Features
+
+@itemize @bullet
+@item @code{GROUP BY} und @code{HAVING}.
+@code{mSQL} unterstützt @code{GROUP BY} überhaupt nicht.
+MySQL unterstützt @code{GROUP BY} vollständig, sowohl mit @code{HAVING} als
+auch mit den folgenden Funktionen: @code{COUNT()}, @code{AVG()}, @code{MIN()},
+@code{MAX()}, @code{SUM()} und @code{STD()}. @code{COUNT(*)} ist darauf
+optimiert, sehr schnell Ergebnisse zu liefern, wenn @code{SELECT} aus einer
+Tabelle abfragt, wenn keine andere Spalte abgerufen wird und wenn es keine
+@code{WHERE}-Klausel gibt. @code{MIN()} und @code{MAX()} können
+Zeichenketten-Argumente entgegennehmen.
+
+@item @code{INSERT} und @code{UPDATE} mit Berechnungen.
+MySQL kann Berechnungen in @code{INSERT}- oder @code{UPDATE}-Statements
+ausführen. Beispiel:
+
+@example
+mysql> UPDATE SET x=x*10+y WHERE x<20;
+@end example
+
+@item Aliase.
+MySQL hat Spalten-Aliase.
+
+@item Qualifizierende Spaltenamen.
+In MySQL muss man nicht den voll qualifizierenden Namen benutzen, wenn eine
+Spalte in den benutzten Tabellen eindeutig ist.
+
+@item @code{SELECT} mit Funktionen.
+MySQL hat viele Funktionen (zu viele, um sie hier aufzulisten; siehe
+@ref{Functions}).
+
+@end itemize
+
+@item Effiziente Ausnutzung von Speicherplatz
+Das heißt, wie klein können Sie Ihre Tabellen machen?
+
+MySQL hat sehr präzise Typen, deshalb können Sie Tabellen erzeugen, die
+sehr wenig Platz brauchen. Ein Beispiel für einen nützlichen MySQL-Datentyp
+ist @code{MEDIUMINT}, der 3 Bytes lang ist. Wenn Sie 100 Millionen
+Datensätze haben, ist es schon von Wichtigkeit, auch nur ein Byte pro
+Datensatz zu sparen.
+
+@code{mSQL2} hat eine begrenztere Anzahl von Spaltentypen, daher ist es
+schwieriger, kleine Tabellen zu erhalten.
+
+@item Stabilität
+Dieser Punkt ist schwieriger objektiv zu beurteilen. Eine Erörterung der
+Stabilität von MySQL finden Sie hier: @ref{Stability}.
+
+Wir haben keine Erfahrungen mit der Stabilität von @code{mSQL}, daher
+können wir nichts darüber sagen.
+
+@item Preis
+Ein weiterer wichtiger Punkt ist die Lizenz. MySQL hat eine flexiblere
+Lizenz als @code{mSQL} und kostet auch weniger als @code{mSQL}. Welches
+Produkt auch immer Sie verwenden, ziehen Sie bitte zumindestens in
+Betracht, für eine Lizenz oder E-Mail-Support zu zahlen. (Sie müssen
+natürlich notwendigerweise eine Lizenz erwerben, wenn Sie MySQL in ein
+Produkt einbeziehen, das Sie verkaufen.)
+
+@item Perl-Schnittstellen
+MySQL hat prinzipiell dieselben Schnittstelle zu Perl wie @code{mSQL}, mit
+einigen zusätzlichen Features.
+
+@item JDBC (Java)
+MySQL hat aktuell eine große Anzahl von JDBC-Treibern:
+
+@itemize @bullet
+@item
+Die mm-Treiber: Ein Typ-4 JDBC-Treiber von Mark Matthews
+@email{mmatthew@@ecn.purdue.edu}. Er ist unter LGPL veröffentlicht.
+
+@item
+Der Resin-Treiber. Das ist ein kommerzieller JDBC-Treiber, der unter Open
+Source veröffentlicht ist. @uref{http://www.caucho.com/Projekte/jdbc-mysql/index.xtp}
+
+@item
+Der gwe-Treiber: Eine Java-Schnittstelle von GWE technologies (wird nicht
+mehr unterstützt).
+
+@item
+Der jms-Treiber: Ein verbesserter gwe-Treiber von Xiaokun Kelvin ZHU
+@email{X.Zhu@@brad.ac.uk} (wird nicht mehr unterstützt).
+
+@item
+Der twz-Treiber: Ein Typ-4 JDBC-Treiber von Terrence W. Zellers
+@email{zellert@@voicenet.com}. Das ist ein kommerzieller Treiber, der für
+Privatgebrauch und Schulungszwecke kostenlos ist (wird nicht mehr
+unterstützt).
+@end itemize
+
+Der empfohlene Treiber ist der mm-Treiber. Der Resin-Treiber mag auch gut
+sein (zumindest sehen die Benchmarks gut aus), aber wir haben über diesen
+Treiber noch nicht allzu viele Informationen erhalten.
+
+Wir wissen, dass @code{mSQL} einen JDBC-Treiber hat, aber wir haben zu
+wenig Erfahrung damit, um ihn in einen Vergleich einzubeziehen.
+
+@item Entwicklungsgeschwindigkeit
+MySQL hat ein sehr kleines Entwicklerteam, aber wir arbeiten schon lange
+mit C und C++ und sind daher sehr schnell. Weil Threads, Funktionen,
+@code{GROUP BY} usw. noch nicht in @code{mSQL} implementiert sind, hat es
+eine Menge aufzuholen. Um das in den richtigen Blickwinkel zu rücken,
+können Sie sich die @code{mSQL} @file{HISTORY}-Datei des letzten Jahres
+ansehen und sie mit dem News-Abschnitt des MySQL Referenzhandbuchs
+vergleichen (@pxref{News}). Es ist ziemlich offensichtlich, welches System
+sich schneller entwickelt hat.
+
+@item Utilities
+Sowohl @code{mSQL} als auch MySQL haben viele interessante von Dritten
+entwickelte Werkzeuge. Weil es sehr einfach ist, aufwärts zu portieren (von
+@code{mSQL} zu MySQL), sind fast alle interessanten Applikationen, die für
+@code{mSQL} verfügbar sind, auch für MySQL erhältlich.
+
+MySQL liefert ein einfaches @code{msql2mysql}-Programm mit, das
+Unterschiede in der Schreibweise zwischen @code{mSQL} und MySQL für die
+meistbenutzten C-API-Funktionen bereinigt.
+Es ändert zum Beispiel Instanzen von @code{msqlConnect()} zu
+@code{mysql_connect()}. Ein Client-Programm von @code{mSQL} zu MySQL zu
+konvertieren, erfordert meist nur geringe Anstrengung.
+@end table
+
+
+
+@menu
+* Using mSQL tools::
+* Protocol differences::
+* Syntax differences::
+@end menu
+
+@node Using mSQL tools, Protocol differences, Compare mSQL, Compare mSQL
+@c German node mSQL-Werkzeuge benutzen
+@subsubsection Wie man @code{mSQL}-Werkzeuge für MySQL konvertiert
+
+@cindex MySQL-Werkzeuge, Konvertierung
+@cindex Konvertierung, Werkzeuge
+@cindex Werkzeuge, Konvertierung
+
+Nach unserer Erfahrung nimmt es wenig Zeit in Anspruch, Werkzeuge wie
+@code{msql-tcl} und @code{msqljava} zu konvertieren, die die
+@code{mSQL}-C-API benutzen, damit sie mit der MySQL-C-API funktionieren.
+
+Die Konvertierungsprozedur läuft wie folgt:
+
+@enumerate
+@item
+Lassen Sie das Shell-Skript @code{msql2mysql} über den Quelltext laufen.
+Das erfordert das @code{replace}-Programm, das mit MySQL ausgeliefert wird.
+
+@item
+Kompilieren.
+
+@item
+Alle Kompilierfehler beheben.
+@end enumerate
+
+Die Unterschiede zwischen der @code{mSQL}-C-API und der MySQL-C-API sind:
+
+@itemize @bullet
+@item
+MySQL benutzt eine @code{MYSQL}-Struktur als Verbindungstyp, (@code{mSQL}
+benutzt einen @code{int}).
+
+@item
+@code{mysql_connect()} nimmt einen Zeiger (Pointer) auf eine
+@code{MYSQL}-Struktur als Parameter auf. Es ist einfach, einen global zu
+definieren oder @code{malloc()} zu benutzen, um einen zu erhalten.
+@code{mysql_connect()} nimmt zusätzlich zwei Parameter auf, um Benutzer und
+Passwort zu spezifizieren. Sie können diese als Vorgabewert der Benutzung
+auf @code{NULL, NULL} setzen.
+
+@item
+@code{mysql_error()} nimmt die @code{MYSQL}-Struktur als Parameter auf.
+Fügen Sie einfach den Parameter zu Ihrem alten @code{msql_error()}-Code
+hinzu, wenn Sie alten Code portieren.
+
+@item
+MySQL gibt eine Fehlernummer und eine Textnachricht für alle Fehler zurück.
+@code{mSQL} gibt nur eine Fehlernachricht zurück.
+
+@item
+Aufgrund der Tatsache, dass MySQL mehrfache Verbindungen zum Server von
+demselben Prozess aus unterstützt, existieren einige Inkompatibilitäten.
+@end itemize
+
+
+@node Protocol differences, Syntax differences, Using mSQL tools, Compare mSQL
+@c German node Protokollunterschiede
+@subsubsection Wie sich @code{mSQL}- und MySQL-Client/Server-Kommunikationsprotokolle unterscheiden
+
+@cindex Kommunikationsprotokolle
+@cindex mSQL, im Vergleich zu MySQL
+
+Es gibt genug Unterschiede, so dass es unmöglich ist (oder zumindest nicht
+leicht), beide zu unterstützen.
+
+Die signifikantesten Protokollunterschiede zwischen MySQL und @code{mSQL}
+sind folgende:
+
+@itemize @bullet
+@item
+Ein Nachrichtenpuffer (Message Buffer) darf viele Ergebniszeilen enthalten.
+
+@item
+Die Nachrichtenpuffer werden dynamisch vergrößert, wenn die Anfrage oder
+das Ergebnis größer sind als der aktuelle Puffer, bis hin zu einer
+konfigurierbaren Server- und Client-Grenze.
+
+@item
+Alle Pakete werden nummeriert, um duplizierte oder fehlende Pakete
+abzufangen.
+
+@item
+Alle Spaltenwerte werden in ASCII gesendet. Die Längen von Spalten und
+Zeilen werden als komprimierte Binärkodierung gesendet (1, 2 oder 3
+Bytes).
+
+@item
+MySQL kann ungepuffert im Ergebnis lesen (ohne die volle Ergebnismenge im
+Client speichern zu müssen).
+
+@item
+Wenn ein einzelner Lese- / Schreibvorgang mehr als 30 Sekunden in Anspruch
+nimmt, schließt der Server die Verbindung.
+
+@item
+Wenn eine Verbindung länger als 8 Stunden im Leerlauf ist, schließt der
+Server die Verbindung.
+@end itemize
+
+
+@c Question Steve: Check this node for the English original!
+@node Syntax differences, , Protocol differences, Compare mSQL
+@c German node Syntaxunterschiede
+@subsubsection Wie sich die @code{mSQL} 2.0 SQL-Syntax von MySQL unterscheidet
+
+@noindent
+@strong{Spaltentypen}
+
+@table @code
+@item
+MySQL hat folgende zusätzliche Typen (unter anderem;
+@pxref{CREATE TABLE, , @code{CREATE TABLE}}):
+@itemize @bullet
+@item
+@code{ENUM}-Typ für einen Satz von Zeichenketten.
+@item
+@code{SET}-Typ für viele Sätze von Zeichenketten.
+@item
+@code{BIGINT}-Typ für 64-Bit-Ganzzahlen (Integer).
+@end itemize
+@item
+MySQL unterstützt folgende zusätzliche Typ-Attribute:
+@itemize @bullet
+@item
+@code{UNSIGNED}-Option für Ganzzahl-Spalten (Integer).
+@item
+@code{ZEROFILL}-Option für Ganzzahl-Spalten (Integer).
+@item
+@code{AUTO_INCREMENT}-Option für Ganzzahl-Spalten (Integer), die ein
+@code{PRIMARY KEY} sind.
+@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
+@item
+@code{DEFAULT}-Wert für alle Spalten.
+@end itemize
+@item mSQL2
+@code{mSQL}-Spaltentypen korrespondieren mit den unten dargestellten
+MySQL-Typen:
+@multitable @columnfractions .15 .85
+@item @code{mSQL} @strong{Typ} @tab @strong{Korrespondierender MySQL-Typ}
+@item @code{CHAR(len)} @tab @code{CHAR(len)}
+@item @code{TEXT(len)} @tab @code{TEXT(len)}. @code{len} ist die maximale
+Länge.
+Und @code{LIKE} funktioniert.
+@item @code{INT} @tab @code{INT}. Mit vielen weiteren Optionen!
+@item @code{REAL} @tab @code{REAL}. Or @code{FLOAT}. Beide 4- und
+8-Byte-Versionen sind verfügbar.
+@item @code{UINT} @tab @code{INT UNSIGNED}
+@item @code{DATE} @tab @code{DATE}. Benutzt ANSI-SQL-Format statt
+@code{mSQL}'s eigenem Format.
+@item @code{TIME} @tab @code{TIME}
+@item @code{MONEY} @tab @code{DECIMAL(12,2)}. Ein Festkomma-Wert mit zwei
+Dezimalstellen.
+@end multitable
+@end table
+
+@noindent
+@strong{Index-Erzeugung}
+
+@table @code
+@item MySQL
+Indizes können bei der Erzeugung der Tabelle mit dem @code{CREATE
+TABLE}-Statement festgelegt werden.
+@item mSQL
+Indexe müssen erzeugt werden, nachdem die Tabelle erzeugt wurde, mit einem
+separaten @code{CREATE INDEX}-Statements.
+@end table
+
+@noindent
+@strong{Einfügen eines eindeutigen Identifikators (Unique Identifier) in eine Tabelle}
+
+@table @code
+@item MySQL
+Benutzen Sie @code{AUTO_INCREMENT} als Spaltentyp-Spezifizierer.
+@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
+@item mSQL
+Erzeugen Sie eine @code{SEQUENCE} auf eine Tabelle und wählen Sie die
+@code{_seq}-Spalte.
+@end table
+
+@noindent
+@strong{Wie man einen eindeutigen Identifikator (Unique Identifier) für eine Zeile erhält}
+
+@table @code
+@item MySQL
+Fügen Sie der Tabelle einen @code{PRIMARY KEY} oder @code{UNIQUE}-Schlüssel
+hinzu und benutzen Sie diesen.
+Neu ab Version 3.23.11: Wenn der @code{PRIMARY}- oder
+@code{UNIQUE}-Schlüssel nur aus einer Spalte besteht und diese vom Typ
+Ganzzahl (Integer) ist, können Sie auf diese auch mit @code{_rowid}
+verweisen.
+@item mSQL
+Benutzen Sie die @code{_rowid}-Spalte. Beachten Sie, dass sich
+@code{_rowid} im Zeitverlauf möglicherweise ändert, abhängig von vielen
+Faktoren.
+@end table
+
+@noindent
+@strong{Wie man die Zeit erhält, zu der eine Spalte zuletzt geändert wurde}
+
+@table @code
+@item MySQL
+Fügen Sie der Tabelle eine @code{TIMESTAMP}-Spalte hinzu. Diese Spalte wird
+automatisch auf das aktuelle Datum und die aktuelle Zeit gesetzt, und zwar
+bei @code{INSERT}- und @code{UPDATE}-Statements, es sein denn, der Spalte
+wird explizit ein Wert zugewiesen, auch der @code{NULL}-Wert.
+
+@item mSQL
+Benutzen Sie die @code{_timestamp}-Spalte .
+@end table
+
+@noindent
+@strong{@code{NULL}-Wert-Vergleiche}
+
+@table @code
+@item MySQL
+MySQL folgt ANSI-SQL, daher wird ein Vergleich mit @code{NULL} immer zu
+@code{NULL} ausgewertet.
+@item mSQL
+In @code{mSQL} ist @code{NULL = NULL} TRUE. Sie müssen @code{=NULL} zu
+@code{IS NULL} und @code{<>NULL} zu @code{IS NOT NULL}, wenn Sie alten Code
+von @code{mSQL} zu MySQL portieren.
+@end table
+
+@noindent
+@strong{Zeichenketten-Vergleich}
+
+@table @code
+@item MySQL
+Normalerweise werden Zeichenketten-Vergleiche so durchgeführt, dass sie
+unabhängig von der verwendeten Groß-/Kleinschreibung laufen, wobei die
+Sortierreihenfolge vom aktuell verwendeten Zeichensatz abhängt (ISO-8859-1
+Latin1 als Vorgabewert). Wenn Sie das nicht wollen, deklarieren Sie Ihre
+Spalten mit dem @code{BINARY}-Attribut, was bewirkt, dass Vergleiche nach
+der ASCII-Reihenfolge durchgeführt werden, wobei der ASCII-Zeichensatz
+gilt, den der MySQL-Server-Host verwendet.
+@item mSQL
+Alle Zeichenketten-Vergleiche werden so durchgeführt, dass sie abhängig von
+der verwendeten Groß-/Kleinschreibung laufen. Die Sortierung erfolgt in
+ASCII-Reihenfolge.
+@end table
+
+@noindent
+@strong{Suche, die unabhängig von Groß-/Kleinschreibung läuft}
+
+@table @code
+@item MySQL
+@code{LIKE} ist ein Operator, der abhängig oder unabhängig von der
+Groß-/Kleinschreibung läuft, was davon abhängt, welche Spalten verwendet
+werden. Wenn möglich, benutzt MySQL Indexe, wenn das @code{LIKE}-Argument
+nicht mit einem Platzhalterzeichen (Wildcard) beginnt.
+@item mSQL
+Benutzt @code{CLIKE}.
+@end table
+
+@noindent
+@strong{Handhabung von Leerzeichen am Ende}
+
+@table @code
+@item MySQL
+Entfernt alle Leerzeichen am Ende von @code{CHAR}- und
+@code{VARCHAR}-Spalten. Benutzen Sie eine @code{TEXT}-Spalte, wenn dieses
+Verhalten unerwünscht ist.
+@item mSQL
+Behält Leerzeichen am Ende bei.
+@end table
+
+@noindent
+@strong{@code{WHERE}-Klauseln}
+
+@table @code
+@item MySQL
+MySQL priorisiert alles korrekt (@code{AND} wird vor @code{OR}
+ausgewertet). Um @code{mSQL}-Verhalten in MySQL zu erreichen, benutzen
+Sie Klammern (wie im unten stehenden Beispiel gezeigt).
+@item mSQL
+Wertet alles von links nach rechts aus. Das bedeutet, dass einige logische
+Berechnungen mit mehr als drei Argumenten überhaupt nicht ausgedrückt
+werden können. Das heißt auch, dass Sie einige Anfragen ändern müssen,
+wenn Sie auf MySQL umsteigen. Das einfachste ist, Klammern hinzuzufügen.
+Nehmen wir an, Sie haben die folgende @code{mSQL}-Anfrage:
+@example
+mysql> SELECT * FROM tabelle WHERE a=1 AND b=2 OR a=3 AND b=4;
+@end example
+Damit MySQL dies auf dieselbe Art auswertet wie @code{mSQL}, müssen Sie
+Klammern hinzufügen:
+@example
+mysql> SELECT * FROM tabelle WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
+@end example
+@end table
+
+@noindent
+@strong{Zugriffskontrolle}
+
+@table @code
+@item MySQL
+Hat Tabellen, in denen Berechtigungsoptionen pro Benutzer, Host, und
+Datenbank gespeichert werden. @xref{Privileges}.
+@item mSQL
+Hat eine Datei @file{mSQL.acl}, in der Sie Lese-/Schreibrechte für Benutzer
+gewähren können.
+@item
+@end table
+
+
+@node Compare PostgreSQL, , Compare mSQL, Comparisons
+@c German node Vergleich mit PostgreSQL
+@subsection MySQL im Vergleich mit PostgreSQL
+
+@cindex PostgreSQL im Vergleich mit MySQL, Überblick
+
+Wenn Sie das Folgende lesen, beachten Sie bitte, dass sich beide Produkte
+stetig entwickeln. Wir bei MySQL AB und die PostgreSQL-Entwickler geben
+sich alle Mühe, unsere jeweilige Datenbank so gut wie möglich zu machen.
+Daher sind es beide Produkte wert bei der Wahl einer kommerziellen Datenbank
+ernsthaft in Betracht gezogen zu werden.
+
+Der folgende Vergleich wurde von uns bei MySQL AB durchgeführt. Wir haben
+uns bemüht, so akkurat und fair wie möglich zu sein. Da wir aber keine
+vollständige Kenntnis aller PostgreSQL-Features haben, während wir MySQL
+sehr genau kennen, haben wir vielleicht ein paar Dinge falsch verstanden.
+Wir werden das jedenfalls korrigieren, wenn es uns zu Ohren kommt.
+
+Zunächst wollen wir feststellen, dass sowohl PostgreSQL als auch MySQL weit
+verbreitete Produkte sind, die aber unterschiedliche Entwurfsziele haben,
+auch wenn beide sich bemühen, ANSI-SQL-kompatibel zu sein. Das bedeutet,
+dass MySQL für einige Applikationen besser geeignet ist, PostgreSQL für
+andere. Wenn Sie überlegen, welche Datenbank Sie wählen sollen, sollten Sie
+zunächst prüfen, ob die Features der Datenbank für Ihre Applikation
+zufrieden stellend sind. Wenn Sie satte Geschwindigkeit brauchen, wird Ihre
+Wahl wahrscheinlich auf MySQL fallen. Wenn Sie einige der speziellen
+Merkmale brauchen, die nur PostgreSQL anbieten kann, sollten Sie
+@code{PostgreSQL} benutzen.
+
+@cindex PostgreSQL/MySQL, Strategien
+
+
+@menu
+* MySQL-PostgreSQL goals::
+* MySQL-PostgreSQL features::
+* MySQL-PostgreSQL benchmarks::
+@end menu
+
+@node MySQL-PostgreSQL goals, MySQL-PostgreSQL features, Compare PostgreSQL, Compare PostgreSQL
+@c German node MySQL-PostgreSQL-Ziele
+@subsubsection Entwicklungsstragien von MySQL und PostgreSQL
+
+Wenn wir MySQL Dinge hinzufügen, ist es für uns eine Sache der Ehre, eine
+optimale, definitive Lösungen zu schaffen. Der Code sollte so gut sein,
+dass wir keine Notwendigkeit erkennen, ihn in der absehbaren Zukunft zu
+ändern. Wir wollen auch nicht Geschwindigkeit für Features opfern, sondern
+sind aufs Äußerste bestrebt, eine Lösung zu finden, die maximalen
+Durchsatz bietet. Das bedeutet, dass die Entwicklung ein bisschen länger
+dauert, aber die Endergebnisse sind es wert. Diese Art von Entwicklung ist
+nur möglich, weil der gesamte Server-Code nur von wenigen Leuten geprüft
+wird (aktuell zwei), bevor er in den MySQL-Server aufgenommen wird.
+
+Wir bei MySQL AB halten viel von häufigen Releases, um in der Lage zu sein,
+neue Features schnell an unsere Benutzer heraus zu geben. Deshalb bringen
+wir etwa alle drei Wochen ein kleines Release heraus und einen größeren
+Zweig (Branch) einmal im Jahr. Alle Releases werden gründlich mit unseren
+Testwerkzeugen auf vielen verschiedenen Plattformen getestet.
+
+PostgreSQL basiert auf einem Kern (Kernel), zu dem viele Leute etwas
+beigesteuert haben. Bei diesem Vorgehen ist es sinnvoll, dem Hinzufügen
+neuer Features Priorität einzuräumen, statt sie optimal zu implementieren,
+denn man kann immer noch später Dinge optimieren, wenn sich die
+Notwendigkeit hierfür ergibt.
+
+Ein weiterer großer Unterschied zwischen MySQL und PostgreSQL besteht
+darin, dass praktisch der gesamte Code des MySQL-Servers von Entwicklern
+kodiert wurde, die bei MySQL AB angestellt sind und die immer noch am
+Server-Code arbeiten. Ausnahmen bilden die Transaktions-Engines und die
+Regexp-Bibliothek.
+
+Das steht in scharfem Kontrast zum PostgreSQL-Code, wo der größte Teil des
+Codes von einer großen Gruppe von Leuten mit unterschiedlichem Hintergrund
+kodiert wird. Erst kürzlich gaben die PostgreSQL-Entwickler bekannt, dass
+ihre aktuelle Entwicklergruppe endlich Zeit gefunden hat, einen Blick auf
+all den Code der aktuellen PostgreSQL-Version zu werfen.
+
+Beide der genannten Entwicklungsmethoden hat Ihre Vorzüge und Nachteile.
+Wir hier bei MySQL AB sind natürlich der Meinung, dass unser Modell besser
+ist, weil unser Modell bessere Konsistenz gewährleistet sowie mehr
+optimalen und damit wiederverwendbaren Code und deshalb nach unserer
+Meinung weniger Bugs. Weil wir die Autoren des MySQL-Server-Codes sind,
+sind wir besser im Stande, neue Features und Releases zu koordinieren.
+
+
+@node MySQL-PostgreSQL features, MySQL-PostgreSQL benchmarks, MySQL-PostgreSQL goals, Compare PostgreSQL
+@c German node MySQL-PostgreSQL-Features
+@subsubsection Feature-Vergleich von MySQL und PostgreSQL
+
+@cindex PostgreSQL/MySQL, Features
+
+Auf der Seite @uref{http://www.mysql.com/information/crash-me.php,
+crash-me} finden Sie eine Liste der Datenbank-Konstrukte und
+-Beschränkungen, die man automatisch mit einem Programm entdecken kann.
+Beachten Sie jedoch, dass sich etliche numerische Beschränkungen mit
+Start-Optionen der jeweiligen Datenbank ändern lassen. Die genannte Seite
+ist jedoch äußerst nützlich, wenn Sie sicher stellen wollen, dass Ihre
+Applikationen mit vielen unterschiedlichen Datenbanken funktionieren, oder
+wenn Sie Ihre Applikation von einer Datenbank zu einer anderen konvertieren
+wollen.
+
+MySQL bietet folgende Vorzüge gegenüber PostgreSQL:
+
+@itemize @bullet
+@item
+@code{MySQL} ist generell viel schneller als PostgreSQL.
+@xref{MySQL-PostgreSQL benchmarks}.
+
+@item
+MySQL hat eine viel größere Benutzer-Basis als PostgreSQL, deshalb ist der
+Code besser getestet und hat sich historisch als stabiler erwiesen als der
+von PostgreSQL. MySQL wird sehr viel mehr in Produktionsumgebungen
+eingesetzt als PostgreSQL, hauptsächlich dank der Tatsache, dass MySQL AB,
+früher TCX DataKonsult AB, kommerziellen Support von höchster Qualität für
+MySQL geleistet hat, von dem Tag an, wo MySQL veröffentlicht wurde,
+wohingegen PostgreSQL bis vor kurzem nicht supported war.
+
+@item
+MySQL funktioniert unter Windows besser als PostgreSQL. MySQL läuft als
+native Windows-Applikation (als Systemdienst unter NT/Win2000/WinXP),
+während PostgreSQL unter der cygwin-Emulation läuft. Uns ist zu Ohren
+gekommen, dass PostgreSQL nicht unter Windows nicht sehr stabil läuft, aber
+wir konnten das selbst noch nicht überprüfen.
+
+@item
+MySQL hat mehr APIs zu anderen Sprachen und wird von mehr existierenden
+Programmen unterstützt als PostgreSQL. @xref{Contrib}.
+
+@item
+MySQL läuft auf 24/7-Systemen unter hoher Last. In den meisten Fällen
+braucht man nie irgend welche Cleanups auf MySQL laufen lassen. PostgreSQL
+unterstützt noch keine 24/7-Systeme, weil man gelegentlich @code{VACUUM()}
+laufen lassen muss, um durch @code{UPDATE}- und @code{DELETE}-Kommandos
+beanspruchten Platz zurück zu gewinnen, sowie um statistische Analysen
+durchzuführen, die entscheidend sind, um mit PostgreSQL gute Performance zu
+erzielen. @code{VACUUM()} wird auch benötigt nach dem Hinzufügen vieler
+Zeilen in eine Tabelle. Auf einem ausgelasteten System mit vielen
+Änderungen muss @code{VACUUM()} sehr häufig laufen gelassen werden, im
+schlimmsten Fall mehrmals täglich. Während @code{VACUUM()} läuft, was
+Stunden dauern kann, wenn die Datenbank Groß ist, ist die Datenbank vom
+Produktionsstandpunkt her gesehen praktisch tot. Das PostgreSQL-Team hat
+die Behebung dessen auf seiner TODO-Liste, aber wir vermuten, dass es nicht
+einfach sein wird, das dauerhaft zu beheben.
+
+@item
+Ein funktionierendes, getestetes Replikations-Feature, das unter anderem
+von folgenden Sites benutzt wird:
+@itemize @minus
+@item Yahoo Finance (@uref{http://finance.yahoo.com})
+@item Mobile.de (@uref{http://www.mobile.de/})
+@item Slashdot (@uref{http://www.slashdot.org})
+@end itemize
+
+@item
+In der MySQL-Distribution werden zwei unterschiedliche Test-Suites
+mitgeliefert:
+@file{mysql-test-run} und
+@uref{http://www.mysql.com/information/crash-me.php,crash-me}, sowie eine
+Benchmark-Suite. Das Testsystem wird rege mit Code aktualisiert, um jedes
+neue Feature und alle wiederholbaren Fehler, die uns zu Ohren kamen, zu
+testen. Vor jedem Release testen wir MySQL auf vielen verschiedenen
+Plattformen. Diese Tests sind technisch ausgereifter als alles, was wir von
+PostgreSQL gesehen haben, und sie stellen sicher, dass MySQL auf einem
+hohen Standard gehalten wird.
+
+@item
+Es gibt wesentlich mehr gedruckte Bücher über MySQL als über PostgreSQL.
+Alle großen Verlage wie O'Reilly, Sams, Que und New Riders bieten Bücher
+über MySQL an. Alle MySQL-Features werden ausserdem im
+MySQL-Online-Handbuch dokumentiert, denn wenn ein neues Feature
+implementiert wird, sind die MySQL-Entwickler gehalten, es zu
+dokumentieren, bevor es in den Quelltext eingeschlossen wird.
+
+@item
+MySQL unterstützt mehr Standard-ODBC-Funktionen als @code{PostgreSQL}.
+
+@item
+MySQL hat ein technisch ausgereifteres @code{ALTER TABLE}.
+
+@item
+MySQL unterstützt Tabellen ohne Transaktionen für Applikationen, die so
+viel Geschwindigkeit brauchen, wie sie bekommen können. Tabellen können
+Arbeitsspeicher-basierend, @code{HEAP}-Tabellen oder Festplatten-basierend
+@code{MyISAM} sein. @xref{Table types}.
+
+@item
+MySQL unterstützt zwei verschiedene Tabellen-Handler, die Transaktionen
+unterstützen: @code{BerkeleyDB} und @code{InnoDB}. Weil jede
+Transaktions-Engine unter unterschiedlichen Bedingungen unterschiedlich
+leistungsfähig ist, gibt das dem Applikationsschreiber mehr Optionen, die
+optimale Lösung für seinen Bedarf zu finden. @xref{Table types}.
+
+@item
+@code{MERGE}-Tabellen geben Ihnen eine einzigartige Möglichkeit, eine
+augenblickliche Sicht (View) über eine Reihe identischer Tabellen zu machen
+und diese wie eine zu benutzen. Das ist perfekt für Systeme, auf denen Sie
+Log-Dateien haben, die Sie zum Beispiel nach Monat sortieren. @xref{MERGE}.
+
+@item
+Die Option, Nur-Lese-Tabellen zu komprimieren, aber dennoch direkten
+Zugriff auf die Zeilen der Tabelle zu haben, gibt Ihnen dadurch bessere
+Performance, dass Festplattenzugriffe minimiert werden. Das ist sehr
+nützlich, wenn Sie Dinge archivieren. @xref{myisampack}.
+
+@item
+MySQL hat internen Support für Volltextsuche. @xref{Fulltext Search}.
+
+@item
+Sie können von derselben Verbindung aus auf viele Datenbanken zugreifen
+(was natürlich von Ihren Zugriffsrechten abhängt).
+
+@item
+MySQL wurde von Anfang an multi-threaded kodiert, während PostgreSQL
+Prozesse benutzt. Umschalten zwischen unterschiedlichen Zusammenhängen
+(Context Switching) und Zugriff auf allgemeine Speicherbereiche geht
+zwischen Threads wesentlich schneller als zwischen separaten Prozessen. Das
+bringt MySQL einen großen Geschwindigkeitsvorteil in
+Mehrbenutzer-Applikationen und macht es obendrein für MySQL einfacher, den
+vollen Nutzen aus symmetrischen Multiprozessor-Systemen (SMP) zu ziehen.
+
+@item
+MySQL hat ein technisch ausgereifteres System der Zugriffsberechtigungen
+(Berechtigungssystem) als PostgreSQL.
+PostgreSQL unterstützt nur @code{INSERT}-, @code{SELECT}- und
+@code{UPDATE/DELETE}-Rechtegewährung (Grants) pro Benutzer auf eine
+Datenbank oder Tabelle. MySQL dagegen erlaubt es Ihnen, einen kompletten
+Satz unterschiedlicher Zugriffsrechte auf Datenbank-, Tabellen- und
+Spaltenebene festzulegen. MySQL gestattet es auch, Zugriffsrechte als
+Host- und Benutzer-Kombinationen festzulegen. @xref{GRANT}.
+
+@item
+MySQL unterstützt ein komprimiertes Client/Server-Protokoll, was die
+Performance über langsame Verbindungen verbessert.
+
+@item
+MySQL führt ein ``Tabellen-Handler''-Konzept ein und ist die einzige
+relationale Datenbank, die wir kennen, die um dieses Konzept herum
+aufgebaut ist. Das sorgt dafür, dass unterschiedliche
+Low-Level-Tabellentypen an die SQL-Engine angeflanscht werden können, und
+dass jeder Tabellentyp für unterschiedliche Performance-Charakteristiken
+optimiert werden kann.
+
+@item
+Alle MySQL-Tabellentypen (ausser @strong{InnoDB}) sind als Dateien
+implementiert (eine Tabelle pro Datei), wodurch Datensicherungen,
+Verschieben, Löschen und sogar Symlinks auf Datenbanken und Tabellen
+wirklich einfach werden, selbst wenn der Server herunter gefahren ist.
+
+@item
+Werkzeuge, um @strong{MyISAM}-Tabellen (der meistbenutzte MySQL-Tabellentyp) zu
+reparieren und zu optimieren. Ein Reparaturwerkzeug wird nur dann benötigt,
+wenn eine Datendatei physikalisch beschädigt wurde, was üblicherweise bei
+Hardwareproblemen der Fall ist. Das Werkzeug kann meist den größten Teil der
+Daten retten.
+
+@item
+Auf eine höhere Version von MySQL aktualisieren (Upgrade) geht problemlos.
+Wenn Sie MySQL aktualisieren, brauchen Sie Ihre Daten nicht zusichern (dump)
+und zurückzusichern (restore), wie Sie es mit PostgreSQL tun müssen, wenn Sie
+dieses aktualisieren.
+@end itemize
+
+Nachteile von MySQL im Vergleich zu PostgreSQL:
+
+@itemize @bullet
+@item
+Die Transaktionsunterstützung in MySQL ist noch nicht so gut getestet wie
+das System von PostgreSQL.
+
+@item
+
+Weil MySQL Threads benutzt, die auf vielen Betriebssystemen noch nicht ganz
+tadellos funktionieren, muss man entweder die Binärdateien von
+@uref{http://www.mysql.com/downloads} benutzen oder genau unsere
+Anweisungen auf @uref{http://www.mysql.com/doc/I/n/installation_source.html}
+befolgen, um eine optimale Binärdatei zu erhalten, die in jedem Fall
+funktioniert.
+
+@item
+Tabellensperren (Locks), die von den nicht transaktionalen
+@code{MyISAM}-Tabellen benutzt werden, sind in vielen Fällen schneller als
+Seiten-Sperren (Page Locks), Zeilen-Sperren (Row Locks) oder Versionierung
+(Versioning). Der Nachteil liegt jedoch darin, dass, wenn man nicht
+berücksichtigt, wie Tabellensperren funktioniert, eine einzige lang
+laufende Anfrage eine Tabelle lange Zeit für Updates blockieren kann. Das
+kann gewöhnlich durch entsprechenden Entwurf der Applikation vermieden
+werden. Falls nicht, kann man immer noch die Tabelle, die das Problem
+verursacht, zu einem der transaktionalen Tabellentypen umändern.
+@xref{Table locking}.
+
+@item
+Mit UDF (User Defined Functions, Benutzerdefinierten Funktionen) kann man
+MySQL sowohl hinsichtlich SQL-Funktionen als auch Aggregaten erweitern,
+aber das ist noch nicht so einfach und flexibel wie in PostgreSQL.
+@xref{MySQL internals}.
+
+@item
+Updates, die über mehrere Tabellen laufen, sind in MySQL schwieriger
+durchzuführen. Das wird jedoch in MySQL 4.0 mit dem
+Multi-Table-@code{UPDATE} behoben sein und in MySQL 4.1 mit den Subselects.
+In MySQL 4.0 kann man Multi-Table-Deletes nutzen, um zeitgleich in mehreren
+Tabellen zu löschen. @xref{DELETE}.
+@end itemize
+
+PostgreSQL hat momentan folgende Vorteile gegenüber MySQL:
+
+Weil wir die Pläne (Roadmap) von MySQL kennen, haben wir in der folgenden
+Tabelle die Versionsnummern der jeweiligen MySQL-Version untergebracht, die
+das entsprechende Feature unterstützen wird. Leider konnten wir das nicht
+für frühere Vergleiche machen, denn wir kennen nicht kennen nicht die Pläne
+(Roadmap) von PostgreSQL.
+
+@multitable @columnfractions .70 .30
+@item @strong{Feature} @tab @strong{MySQL version}
+@item Subselects @tab 4.1
+@item Fremdschlüssel @tab 4.0 und 4.1
+@item Sichten (Views) @tab 4.2
+@item Gespeicherte Prozeduren @tab 4.1
+@item Erweiterbares Typ-System @tab Nicht geplant
+@item Unions @tab 4.0
+@item Full Join @tab 4.0 oder 4.1
+@item Trigger @tab 4.1
+@item Constrainst @tab 4.1
+@item Cursor @tab 4.1 oder 4.2
+@item Erweiterbare Indextypen wie R-Trees @tab R-trees sind geplant für 4.2
+@item Vererbte (Inherited) Tabellen @tab Nicht geplant
+@end multitable
+
+Andere Gründe, PostgreSQL zu benutzen:
+
+@itemize @bullet
+@item
+Im Standardgebrauch ist PostgreSQL in einigen Fällen näher an ANSI-SQL
+angelehnt.
+
+@item
+Man kann PostgreSQL beschleunigen, indem man Dinge als gespeicherte
+Prozeduren kodiert.
+
+@item
+PostgreSQL hat ein größeres Entwicklerteam, das Code zum Server
+beisteuert.
+@end itemize
+
+Nachteile von PostgreSQL im Vergleich zu MySQL:
+
+@itemize @bullet
+@item
+@code{VACUUM()} macht es problematisch, PostgreSQL in 24/7-Umgebungen
+einzusetzen.
+
+@item
+Nur Transaktionstabellen.
+
+@item
+Viel langsamere @code{INSERT}, @code{DELETE} und @code{UPDATE} Anweisungen.
+@end itemize
+
+Eine vollständige Aufstellung der Nachteile finden Sie in der ersten
+Tabelle dieses Abschnitts.
+
+
+
+@node MySQL-PostgreSQL benchmarks, , MySQL-PostgreSQL features, Compare PostgreSQL
+@c German node MySQL-PostgreSQL-Benchmarks
+@subsubsection Benchmark-Vergleiche von MySQL und PostgreSQL
+
+@cindex PostgreSQL im Vergleich mit MySQL, Benchmarks
+
+Der einzige Open-Source-Benchmark-Test, den wir kennen, der benutzt werden
+kann, um MySQL und PostgreSQL (und andere Datenbanken) miteinander zu
+vergleichen, ist unser eigener. Man findet ihn auf
+@uref{http://www.mysql.com/information/benchmarks.html}.
+
+Wir haben mehrfach bei den PostgreSQL-Entwicklern und bei einigen
+PostgreSQL-Benutzer nachgefragt, ob sie bereit wären, uns zu helfen, diesen
+Benchmark-Test zu erweitern, um ihn zu dem definitiven Benchmark-Test für
+Datenbanken zu machen, haben aber leider keinerlei Rückmeldung erhalten.
+
+Wir, die MySQL-Entwickler, haben deshalb viele Stunden damit verbracht,
+für den Benchmark-Test maximale Performance aus PostgreSQL heraus zu
+bekommen, aber da wir mit PostgreSQL nicht sehr weitgehend vertraut sind,
+sind wir sicher, dass wir einige Dinge versäumt haben. Auf der
+Benchmark-Seite haben wir genau dokumentiert, wie wir den Benchmark-Test
+durchgeführt haben, deshalb sollte es für jeden einfach sein, ihn zu
+wiederholen und unsere Ergebnisse zu bestätigen.
+
+Die Benchmarks werden üblicherweise mit und ohne die @code{--fast}-Option
+durchgeführt. Wenn wir sie mit @code{--fast} durchführen, versuchen wir,
+jeden Trick zu nutzen, den der Server benutzt, um den Code so schnell wie
+möglich auszuführen. Die Idee dahinter ist, dass der Server zeigen sollte,
+wie er mit Vorgabeeinstellungen läuft und @code{--fast} sollte zeigen, wie
+der Server läuft, wenn der Applikationsentwickler Erweiterungen im Server
+nutzt, um seine Applikation schneller laufen zu lassen.
+
+Wenn wir PostgreSQL mit der @code{--fast}-Option laufen lassen, machen wir
+ein @code{VACUUM()} nach jedem größeren Tabellen-@code{UPDATE} und
+@code{DROP TABLE}, um die Datenbank in beste Verfassung für die folgenden
+@code{SELECT}s zu bringen. Die Zeit für @code{VACUUM()} wird separat
+gemessen.
+
+PostgreSQL 7.1.1 konnten wir jedoch nicht mit der Option @code{--fast}
+laufen lassen, weil der Postmaster (der PostgreSQL Daemon) während eines
+@code{INSERT}-Tests starb und die Datenbank so beschädigt war, dass es
+unmöglich war, den Postmaster neu zu starten. Nachdem dies zweimal
+geschehen war, entschieden wir uns, den Test mit @code{--fast} bis zum
+nächsten PostgreSQL-Release zu verschieben. Die Details zur Maschine, die
+wir für den Benchmark benutzten, stehen auf der Benchmark-Seite.
+
+Bevor wir uns den anderen Benchmarks, die wir kennen, zuwenden, möchten wir
+ein paar Hintergrundinformationen zu Benchmarks geben:
+
+Es ist sehr einfach, einen Test zu schreiben, der zeigt, dass JEDE
+BELIEBIGE Datenbank die beste der Welt ist, indem man den Test einfach auf
+etwas beschränkt, was diese Datenbank sehr gut kann und nichts anderes
+testet, was die Datenbank nicht gut kann. Wenn man dann noch das Ergebnis
+mittels einer einzigen Zahl veröffentlicht, macht das die Dinge sogar noch
+einfacher.
+
+Das wäre, als ob wir die Geschwindigkeit von MySQL gegenüber PostgreSQL
+anhand der Messzeit-Zusammenfassung der MySQL-Benchmarks auf unserer
+Webseite vergleichen würden. Auf dieser Basis wäre MySQL mehr als 40 Mal
+schneller als PostgreSQL, was natürlich nicht stimmt. Wir könnten die Sache
+sogar noch verschlimmern, indem wir nur etwas testen, worin PostgreSQL die
+schlechtesten Leistungsdaten bringt und geltend machen, dass MySQL mehr als
+2000 Mal schneller ist als PostgreSQL.
+
+Tatsache ist, dass MySQL eine Menge Optimierungen vornimmt, die PostgreSQL
+nicht vornimmt. Das ist natürlich auch umgekehrt so. Ein SQL-Optimierer ist
+eine sehr komplexe Sache, und ein Unternehmen könnte Jahre damit zubringen,
+nur den Optimierer schneller und schneller zu machen.
+
+Wenn Sie sich die Ergebnisse der Benchmarks ansehen, sollten Sie nach
+Dingen Ausschau halten, die Sie in Ihrer Applikation durchführen, und dann
+nur diese Ergebnisse benutzen, um zu entscheiden, welche Datenbank wohl am
+besten für Ihre Applikation geeignet ist. Die Benchmark-Ergebnisse zeigen
+ausserdem auf, worin eine bestimmte Datenbank nicht gut ist, was Ihnen eine
+Ahnung davon geben sollte, welche Dinge Sie am besten vermeiden und was Sie
+auf andere Weise machen sollten.
+
+Wir kennen zwei Benchmark-Tests, die behaupten, dass PostgreSQL bessere
+Leistungsdaten bringt als MySQL. Beide waren Mehrbenutzer-Tests, ein Test,
+den zu schreiben wir bei MySQL AB nie die Zeit hatten, hauptsächlich, weil
+es eine wirklich große Aufgabe ist, wenn man will, dass der Test fair zu
+allen Datenbanken ist.
+
+Einer der Tests ist derjenige, für den Great Bridge bezahlt hat, und über
+den Sie hier lesen können:
+@uref{http://www.greatbridge.com/about/press.php?content_id=4}.
+
+Es ist wahrscheinlich der schlechteste Benchmark-Test, den wir jemals
+gesehen haben. Er war nicht nur so eingestellt, dass er das testete, was
+PostgreSQL absolut am besten kann, er war auch völlig unfair zu jeder
+anderen Datenbank, die in diesen Test einbezogen wurde.
+
+@strong{ACHTUNG}: Wir wissen, dass niemand der hauptsächlichen
+PostgreSQL-Entwickler die Art mochte, wie Great Bridge den Test
+durchgeführt hat, daher geben wir ihnen keinerlei Schuld dafür.
+
+Dieser Benchmark wurde in einer Menge Postings und Newsgroups verurteilt,
+daher beschränken wir uns hier darauf, kurz einige Dinge zu wiederholen,
+die dabei nicht stimmten.
+
+@itemize @bullet
+@item
+Die Tests wurden mit einem teuren, kommerziellen Werkzeug durchgeführt, was es
+für ein Open-Source-Unternehmen wie uns unmöglich macht, den Benchmark zu
+verifizieren, selbst einfach nur zu überprüfen, wie der Benchmark
+eigentlich durchgeführt wurde. Das Werkzeug ist nicht einmal ein echtes
+Benchmark-Werkzeug, sondern vielmehr ein Applikations-/Setup-Test-Werkzeug. Darauf
+als ``Standard''-Benchmark-Werkzeug Bezug zu nehmen heißt, es mit der Wahrheit
+nicht so genau zu nehmen.
+
+@item
+Great Bridge hat zugegeben, dass sie die PostgreSQL-Datenbank optimiert
+haben (mit @code{VACUUM()} vor dem Test) und dass sie das Starten vor dem
+Test getuned haben, etwas, das sie für keine der anderen getesteten
+Datenbanken gemacht haben. Dazu heißt es: ``Dieser Prozess optimiert
+Indexe und gibt etwas Festplattenspeicher frei. Die optimierten Indexe
+steigern die Performance um etliches.'' Unsere Benchmarks zeigen deutlich,
+dass der Unterschied bei einer großen Menge von Selects auf eine Datenbank
+mit und ohne @code{VACUUM()} leicht Faktor zehn betragen kann.
+
+@item
+Die Testergebnisse waren ebenfalls merkwürdig. Die AS3AP-Test-Dokumentation
+erwähnt, dass der Test ``Auswahlen, einfache Verknüpfungen, Projektionen,
+Aggregierungen, 1-Tupel-Updates und Massen-Updates'' durchführt.
+
+PostgreSQL ist gut bei der Durchführung von @code{SELECT}s und @code{JOIN}s
+(speziell nach einem @code{VACUUM()}), performt aber nicht so gut bei
+@code{INSERT}s oder @code{UPDATE}s. Die Benchmarks scheinen anzuzeigen,
+dass nur @code{SELECT}s durchgeführt wurden (oder sehr wenige Updates). Das
+würde die guten Ergebnisse für PostgreSQL in diesem Test erklären. Etwas
+weiter unten wird erläutert, wie es zu den schlechten Ergebnissen für MySQL
+kam.
+
+@item
+Sie ließen den so genannten Benchmark von einer Windows-Maschine zu einer
+Linux-Maschine über ODBC laufen, was ein normaler Datenbankbenutzer nie
+machen würde, wenn er eine unter hoher Last laufende
+Mehrbenutzer-Applikation laufen lassen würde. Dadurch wurde eher der
+ODBC-Treiber und das benutzte Windows-Protokoll zwischen den Clients
+getestet als die Datenbank selbst.
+
+@item
+Als Sie die Datenbank mit Oracle und MS-SQL betrieben (Great Bridge hat
+indirekt angedeutet, dass das die Datenbanken waren, die im Test benutzt
+wurden), benutzten sie nicht das native Protokoll, sondern statt dessen
+ODBC. Jeder, der jemals Oracle benutzt hat, weiß, dass alle echten
+Applikationen die native Schnittstelle anstatt ODBC benutzen. Einen Test
+mit ODBC fahren und erklären, dass das irgend etwas mit Situationen des
+echten Lebens zu tun hat, kann kaum als fair erachtet werden. Sie hätten
+zwei Tests fahren sollen: einen mit und einen ohne ODBC, um die korrekten
+Fakten zu ermitteln (natürlich, nachdem sie Experten geholt hätten, die
+alle getesteten Datenbanken optimal eingestellt hätten).
+
+@item
+Sie verweisen auf die TPC-C-Tests, erwähnen aber an keiner Stelle, dass der
+Test, den sie fuhren, kein echter TPC-C-Test war und dass es ihnen nicht
+einmal erlaubt ist, das einen TPC-C-Test zu nennen. Ein TPC-C-Test darf nur
+nach den Regeln durchgeführt werden, die vom TPC-Rat (TPC Council)
+festgelegt wurden (@uref{http://www.tpc.org}). Great Bridge hat das nicht
+getan. Damit haben sie sowohl das Markenzeichen TPC verletzt als auch ihre
+eigenen Benchmarks in Misskredit gebracht. Die Regeln, die vom TPC-Rat
+aufgestellt wurden, sind sehr streng, um sicherzustellen, dass niemand
+falsche Ergebnisse produziert oder nicht beweisbare Erklärungen abgibt.
+Offensichtlich hat das Great Bridge nicht interessiert.
+
+@item
+Nach dem ersten Test haben wir Kontakt mit Great Bridge aufgenommen und
+ihnen gegenüber einige der offensichtlichen Fehler erwähnt, die sie bei
+MySQL gemacht haben:
+
+@itemize @minus
+@item
+Sie haben MySQL mit einer Debug-Version unseres ODBC-Treibers laufen
+lassen.
+
+@item
+Sie haben MySQL auf einem Linux-System laufen lassen, das nicht für Threads
+optimiert war.
+
+@item
+Sie haben eine alte MySQL-Version zu einem Zeitpunkt benutzt, als eine
+empfohlene neuere bereits verfügbar war.
+
+@item
+Sie haben MySQL nicht mit den richtigen Optionen für hohe Last und
+Mehrbenutzerbetrieb gestartet (die vorgabemäßige Installation von MySQL
+ist auf minimalen Ressourcenverbrauch eingestellt).
+@end itemize
+
+Great Bridge hat einen neuen Test gefahren, wobei zwar unsere optimierten
+ODBC-Treiber und bessere Startoptionen für MySQL benutzt wurden, weigerte
+sich aber, entweder unsere aktualisierte glibc-Bibliothek oder unsere
+Standard-Binärversion (von mehr als 80% unserer Benutzer genutzt) zu
+verwenden, sondern benutzte statt dessen eine statisch gelinkte feste
+glibc-Bibliothek.
+
+Nach allem, was wir wissen, hat Great Bridge nichts getan, um
+sicherzustellen, dass die anderen Datenbanken korrekt konfiguriert wurden,
+um in ihrer Testumgebung gut zu laufen. Wir sind jedoch sicher, dass sie
+weder Oracle noch Microsoft kontaktiert haben, um sie um Rat in dieser
+Angelegenheit zu bitten ;)
+
+@item
+Der Benchmark wurde von Great Bridge bezahlt und sie beschlossen, nur
+teilweise, ausgewählte Ergebnisse zu veröffentlichen (statt alles publik zu
+machen).
+@end itemize
+
+Tim Perdue, seit langer Zeit PostgreSQL-Fan und ein widerwilliger
+MySQL-Benutzer, hat einen Vergleich auf
+@uref{http://www.phpbuilder.com/columns/tim20001112.php3,phpbuilder}
+veröffentlicht.
+
+Als wir von diesem Vergleich erfuhren, telefonierten wir mit Tim Perdue zu
+diesem Thema, weil es eine Menge merkwürdiger Dinge in seinen Ergebnissen
+gab. Er behauptete zum Beispiel, dass MySQL bei seinem Test ein Problem mit
+fünf Benutzern hatte, während wir wissen, dass es Benutzer mit ähnlichen
+Maschinen wie seine gibt, die MySQL mit 2000 simultanen Verbindungen
+betreiben, die 400 Anfragen pro Sekunde abarbeiten. (In diesem Fall war die
+Beschränkung durch die Web-Bandbreite gegeben, nicht durch die Datenbank.)
+
+Es schien, als hätte er einen Linux-Kernel benutzt, der entweder Probleme
+mit vielen Threads hatte, wie ein Kernel vor Version 2.4, der ein Problem
+mit vielen Threads auf Mehrprozessor-Maschinen hat. Wir haben in diesem
+Handbuch dokumentiert, wie man das behebt, und Tim sollte sich dieses
+Problems bewusst sein.
+
+Das andere mögliche Problem könnte eine alte glibc-Bibliothek gewesen sein,
+und dass Tim keine MySQL-Binärdistribution von unserer Site benutzte, die
+mit einer korrigierten glibc-Bibliothek gelinkt ist, sondern statt dessen
+eine eigene Version kompiliert hat. Bei jedem der genannten Fälle würden
+die Symptome genau die sein, die Tim gemessen hat.
+
+Wir haben Tim gebeten, uns Zugang zu seinen Daten zu geben, damit wir den
+Benchmark-Test wiederholen könnten, sowie die MySQL-Version auf seiner
+Maschine zu prüfen, um herauszufinden, was falsch lief, und er hat
+versprochen, uns entsprechende Mitteilung zu geben. Das hat er bis heute
+nicht gemacht.
+
+Aus diesem Grund können wir auch diesem Benchmark in keiner Weise vertrauen
+:(
+
+Im Zeitverlauf haben sich die Dinge auch geändert und die genannten
+Benchmarks sind nicht mehr so relevant. MySQL hat mittlerweile eine Reihe
+unterschiedlicher Tabellen-Handler mit unterschiedlichen Verhältnissen
+zwischen Geschwindigkeit und Anzahl gleichzeitiger Zugriffe
+(Speed/Concurrency Tradeoffs). @xref{Table types}. Es wäre interessant zu
+sehen, wie die obigen Tests mit den verschiedenen transaktionalen Tabellen
+von MySQL laufen würden. PostgreSQL hat natürlich auch neue Features
+erhalten, seit die Tests durchgeführt wurden. Weil die genannten Tests
+nicht öffentlich erhältlich sind, gibt es keine Möglichkeit für uns
+herauszufinden, wie die Datenbank heute mit denselben Tests laufen würde.
+
+
+Fazit:
+
+Der einzige Benchmark, der heutzutage existiert, den jeder herunter laden
+und laufen lassen kann, um MySQL und PostgreSQL zu vergleichen, ist der
+MySQL-Benchmark-Test. Wir hier bei MySQL sind der Überzeugung, dass
+Open-Source-Datenbanken mit Open-Source-Werkzeuge getestet werden sollten! Das
+ist die einzige Möglichkeit, um sicherzustellen, dass niemand Tests fährt,
+die nicht reproduzierbar sind, und diese dazu benutzt, um zu behaupten,
+dass eine Datenbank besser sei als die eine andere. Ohne die Fakten zu
+kennen ist es unmöglich, auf die Behauptungen des Testers einzugehen.
+
+Eine Sache, die wir merkwürdig finden, ist, dass jeder Test, den wir zu
+PostgreSQL gesehen haben - und wo es unmöglich ist, diesen zu wiederholen
+-, behauptet, dass PostgreSQL in den meisten Hinsichten besser sei, während
+unsere Tests, die jeder reproduzieren kann, eindeutig das Gegenteil
+beweisen. Damit wollen wir nicht sagen, dass PostgreSQL nicht vieles sehr
+gut kann (das kann es!) oder dass es nicht unter bestimmten Umständen
+schneller ist als MySQL. Wir würden nur gern einen fairen Test sehen, der
+zeigt, worin PostgreSQL sehr gut ist, damit wir einen freundlichen
+Wettbewerb anzetteln können!
+
+Mehr Informationen über unsere Benchmark-Suite finden Sie unter @xref{MySQL Benchmarks}.
+
+Wir arbeiten an einer noch besseren Benchmark-Suite, die Mehrbenutzer-Tests
+beinhaltet sowie eine bessere Dokumentation dessen, was die einzelnen Tests
+genau tun und wie man weitere Tests zur Suite hinzufügt.
+
+@node Installing, Tutorial, Deutsch, Top
+@c German node Installation
+@chapter Installation von MySQL
+
+@cindex Installation, Überblick
+
+
+Dieses Kapitel beschreibt, woher man MySQL bezieht und wie man MySQL
+installiert:
+
+@itemize @bullet
+@item
+Eine Liste der Site, von denen Sie MySQL beziehen können, finden Sie unter
+@ref{Getting MySQL, , Wie man MySQL erhält}.
+
+@item
+@c German FIX unsplit @ref
+Um festzustellen, welche Plattformen unterstützt werden, siehe
+@ref{Which OS}. Beachten Sie bitte, dass nicht alle
+unterstützten Systeme gleich gut
+sind, um MySQL laufen zu lassen. Auf einigen läuft es sehr viel robuster
+und effizienter als auf anderen - siehe @ref{Which OS} für
+Details.
+
+@item
+Mehrere Versionen von MySQL sind sowohl als Binär- als auch als
+Quellcode-Distributionen erhältlich. Wir stellen auch öffentlichen Zugriff
+auf unseren aktuellen Quellcode-Baum für diejenigen zur Verfügung, die die
+aktuellsten Entwicklungen sehen und uns helfen wollen, neuen Code zu
+testen. Um festzustellen, welche Version und welche Art von Distribution Sie
+benutzen sollten, siehe @ref{Which version}. Im Zweifelsfall benutzen Sie
+die Binärdistribution.
+
+@item
+Installationsanleitungen für Binär- und Quelldistributionen sind
+beschrieben in @ref{MySQL binaries} und @ref{Installing source}. Jede
+Anleitung enthält einen Abschnitt über System-spezifische Probleme, denen
+Sie begegnen können.
+
+@item
+Prozeduren, die nach der Installation durchgeführt werden sollen / müssen,
+finden Sie unter @ref{Post-installation}. Diese Prozeduren gelten, egal ob
+Sie MySQL von einer Binär- oder einer Quellcode-Distribution installieren.
+@end itemize
+
+
+@menu
+* Quick Standard Installation::
+* General Installation Issues::
+* Installing source::
+* Post-installation::
+* Upgrade::
+* Operating System Specific Notes::
+* Perl support::
+@end menu
+
+@node Quick Standard Installation, General Installation Issues, Installing, Installing
+@c German node Schnelle Standard-Installation
+@section Schnelle Standard-Installation von MySQL
+
+@c This node name ist special
+
+
+@menu
+* Linux-RPM::
+* Windows installation::
+@end menu
+
+@node Linux-RPM, Windows installation, Quick Standard Installation, Quick Standard Installation
+@c German node Linux-RPM
+@subsection MySQL auf Linux installieren
+
+@cindex RPM-Datei
+@cindex RedHat Package Manager
+
+Die empfohlene Vorgehensweise für die Installation von MySQL auf Linux ist
+die Benutzung einer RPM-Datei. Die MySQL-RPMs werden aktuell auf einer
+RedHat-Version 6.2 gebaut, sollten aber auch auf anderen Linux-Versionen
+funktionieren, die @code{rpm} unterstützen und @code{glibc} benutzen.
+
+Wenn Sie Probleme mit einer RPM-Datei haben, wenn Sie beispielsweise den
+Fehler ``@code{Sorry, the host 'xxxx' could not be looked up}'' erhalten,
+sehen Sie bitte unter @ref{Linux-RPM} nach.
+
+Die RPM-Dateien, die Sie benutzen sollten, sind:
+
+@itemize @bullet
+@item @code{MySQL-VERSION.i386.rpm}
+
+Der MySQL-Server. Sie brauchen diese, es sei denn, Sie wollen sich
+lediglich mit einem MySQL-Server verbinden, der auf einer anderen Maschine
+läuft.
+
+@item @code{MySQL-client-VERSION.i386.rpm}
+
+Die Standard-MySQL-Client-Programme. Dieses Paket sollten Sie wohl immer
+installieren.
+
+@item @code{MySQL-bench-VERSION.i386.rpm}
+
+Tests und Benchmarks. Erfordert Perl und msql-mysql-modules RPMs.
+
+@item @code{MySQL-devel-VERSION.i386.rpm}
+
+Bibliotheken und Include-Dateien, die benötigt werden, wenn Sie andere
+MySQL-Clients kompilieren wollen, beispielsweise Perl-Module.
+
+@item @code{MySQL-VERSION.src.rpm}
+
+Dieses Paket enthält den Quelltext für alle obigen Pakete. Es kann auch
+dazu benutzt werden, um RPMs für andere Architekturen zu bauen (zum
+Beispiel für Alpha oder SPARC).
+@end itemize
+
+Um alle Dateien in einem RPM-Paket zu sehen, geben Sie folgendes ein:
+@example
+shell> rpm -qpl MySQL-VERSION.i386.rpm
+@end example
+
+Um eine minimale Standard-Installation durchzuführen, geben Sie folgendes
+ein:
+
+@example
+shell> rpm -i MySQL-VERSION.i386.rpm MySQL-client-VERSION.i386.rpm
+@end example
+
+Um nur das Client-Paket zu installieren, geben Sie folgendes ein:
+
+@example
+shell> rpm -i MySQL-client-VERSION.i386.rpm
+@end example
+
+Das RPM legt Dateien in @file{/var/lib/mysql} ab. Ausserdem erzeugt das RPM
+die entsprechenden Einträge in @file{/etc/rc.d/}, um den Server beim Booten
+automatisch zu starten. (Falls Sie bereits vorher eine Installation
+durchgeführt haben, bedeutet das, dass Sie eine Kopie Ihrer vorher
+installierten MySQL-Startdateien machen sollten, falls Sie darin Änderungen
+vorgenommen haben, damit Sie diese Änderungen nicht verlieren.)
+
+Nach der Installation der RPM-Datei(en) sollte der @code{mysqld}-Daemon
+laufen und Sie sollten jetzt in der Lage sein, mit der Benutzung von MySQL
+zu beginnen. @xref{Post-installation}.
+
+Wenn etwas schief geht, finden Sie weitere Informationen im Kapitel über
+die Binär-Installationen. @xref{MySQL binaries}.
+
+@node Windows installation, , Linux-RPM, Quick Standard Installation
+@c German node Windows-Installation
+@subsection Installation von MySQL unter Windows
+
+Der MySQL-Server für Windows ist in zwei Distributionstypen erhältlich:
+@enumerate
+@item
+Die Binärdistribution enthält ein Setup-Programm, das alles Benötigte
+installiert, so dass Sie den Server sofort starten können.
+@item
+Die Quelldistribution enthält den gesamten Code und
+Unterstützungsdateien, um die ausführbaren Dateien unter Benutzung des
+VC++-6.0-Kompilers zu bauen.
+@xref{Windows source build}.
+@end enumerate
+
+Im Allgemeinen sollten Sie die Binärdistribution benutzen.
+
+Sie benötigen folgendes:
+@itemize @bullet
+@item
+Ein Windows-32-Bit-Betriebssystem der Familien Windows 9x, ME, NT oder
+Windows 2000. Die NT-Familie gestattet, den MySQL-Server als
+Systemdienst laufen zu lassen. @xref{NT start}.
+
+Wenn Sie Tabellen benutzen, die größer als 4 GB sind, sollten Sie MySQL
+auf NTFS oder einem neueren Dateisystem installieren. Vergessen Sie bei
+der Erzeugung der Tabellen nicht, @code{MAX_ROWS} und
+@code{AVG_ROW_LENGTH} zu benutzen. @xref{CREATE TABLE}.
+@item
+TCP/IP-Protokollunterstützung.
+@item
+Die MySQL-Binär- oder Quelldistribution für Windows kann von
+@uref{http://www.mysql.com/downloads/} herunter geladen werden.
+
+Hinweis: Die Distributionsdateien werden in einem komprimierten Format
+zur Verfügung gestellt. Wir empfehlen die Benutzung eines FTP-Clients,
+der in der Lage ist, abgebrochene FTP-Downloads wieder aufzunehmen
+(resume).
+@item
+Ein @code{ZIP}-Programm, um die Distributionsdatei zu entpacken.
+@item
+Genug Platz auf der Festplatte, um die Datenbanken entsprechend Ihren
+Anforderungen zu entpacken, zu installieren und zu erzeugen.
+@item
+Wenn Sie planen, sich über @code{ODBC} mit dem MySQL-Server zu
+verbinden, benötigen Sie zusätzlich den @code{MyODBC}-Treiber.
+@xref{ODBC}.
+@end itemize
+
+
+
+@menu
+* Windows binary installation::
+@end menu
+
+@node Windows binary installation, , Windows installation, Windows installation
+@c German node Windows-Binärinstallation
+@subsubsection Binärdateien installieren
+
+@enumerate
+@item
+Wenn Sie auf einem NT- oder Windows-2000-Server arbeiten, melden Sie
+sich als Benutzer mit Administrationsrechten an.
+@item
+Wenn Sie ein Upgrade einer früheren MySQL-Installation durchführen,
+müssen Sie den Server anhalten. Wenn Sie den Server als Systemdienst
+laufen lassen, geben Sie ein:
+
+@example
+C:\> NET STOP MySQL
+@end example
+
+Ansonsten geben Sie folgendes ein:
+
+@example
+C:\mysql\bin> mysqladmin -u root shutdown
+@end example
+
+@item
+Auf NT-/Windows-2000-Maschinen müssen Sie auch den Systemdienst
+entfernen, wenn Sie die ausführbare Datei des Servers (z. B. -max or -nt) austauschen wollen:
+
+@example
+C:\mysql\bin> mysqld-max-nt --remove
+@end example
+
+@item
+Entpacken Sie die Distributionsdatei in ein temporäres Verzeichnis.
+@item
+Starten Sie @file{setup.exe}, um den Installationsprozess zu beginnen.
+Wenn Sie in ein anderes Verzeichnis als das vorgabemäßige
+(@file{c:\mysql}) installieren wollen, legen Sie mit der Schaltfläche
+@code{Durchsuchen} das gewünschte Verzeichnis fest.
+@item
+Beenden Sie den Installationsprozess.
+@end enumerate
+
+
+Seit MySQL 3.23.38 enthält die Windows-Distribution sowohl die normalen als
+auch die @strong{MySQL-Max}-Binärdateien. Der wichtigste Vorteil der
+Benutzung der normalen @code{mysqld.exe}-Binärdatei liegt darin, dass sie
+etwas schneller ist und weniger Ressourcen belegt.
+
+Hier ist eine Liste der unterschiedlichen MySQL-Server, die Sie benutzen
+können:
+@multitable @columnfractions .25 .75
+@item @code{mysqld} @tab Kompiliert mit komplettem Debugging und automatischer Überprüfung der Speicherzuordnung (memory allocation), symbolischen Links, InnoDB- und BDB-Tabellen.
+@item @code{mysqld-opt} @tab Optimierte Binärdistribution ohne Unterstützung von Transaktionstabellen.
+@item @code{mysqld-nt} @tab Optimierte Binärdatei für NT mit Unterstützung von Named Pipes. Man kann diese Version auf Windows 98 laufen lassen, aber in diesem Fall werden keine Named Pipes angelegt und man muss TCP/IP installiert haben.
+@item @code{mysqld-max} @tab Optimierte Binärdistribution mit Unterstützung symbolischer Links, InnoDB und BDB-Tabellen.
+@item @code{mysqld-max-nt} @tab Wie @code{mysqld-max}, aber mit Unterstützung von Named Pipes kompiliert.
+@end multitable
+
+Alle genannten Binärdistributionen sind für den Pentium Pro Prozessor
+optimiert, sollten aber auf jedem Intel-Prozessor >= 386 laufen.
+
+ACHTUNG: Wenn Sie InnoDB-Tabellen benutzen wollen, müssen Sie bestimmte
+Start-Optionen in Ihrer @file{my.ini}-Datei festlegen! @xref{InnoDB start}.
+
+
+@node General Installation Issues, Installing source, Quick Standard Installation, Installing
+@c German node Allgemeine Installationsthemen
+@section Allgemeine Installationsthemen
+
+@c @node Methods of Installation, , ,
+@c @subsection Installationsmethoden
+
+@c FIX: this needs to be written?
+
+
+
+@menu
+* Getting MySQL::
+* Which OS::
+* Which version::
+* Installation layouts::
+* Many versions::
+* MySQL binaries::
+@end menu
+
+@node Getting MySQL, Which OS, General Installation Issues, General Installation Issues
+@c German node Wie man MySQL erhält
+@subsection Wie man MySQL erhält
+
+@cindex Download
+@cindex MySQL-Version
+@cindex Version, aktuelle
+@cindex Wie man MySQL erhält
+@cindex Mirror-Sites
+@cindex URLS zum Download von MySQL
+
+Sehen Sie wegen Informationen zur aktuellen Version und für
+Download-Anweisungen auf @uref{http://www.mysql.com/, MySQL home page}
+nach.
+
+Unser Haupt-Mirror-Server für den Download ist hier:
+
+@uref{http://mirrors.sunsite.dk/mysql/}
+
+Wenn Sie Interesse haben, eine MySQL-Mirror-Site beizusteuern, können Sie
+anonymes rsync mit @code{rsync://sunsite.dk/ftp/mirrors/mysql/} machen.
+Schicken Sie bitte eine E-Mail an @email{webmaster@@mysql.com} und geben
+Sie uns Bescheid, wo Ihr Mirror liegt, damit wir ihn der unten stehenden
+Liste hinzufügen können.
+
+Wenn Sie Probleme beim Download von unserer Hauptseite aus haben, probieren
+Sie eine der unten stehenden Mirror-Sites.
+
+Geben Sie bitte @email{webmaster@@mysql.com} Bescheid, wenn Sie auf
+schlechte oder veraltete Mirror-Sites stoßen.
+
+@c START_OF_MIRROR_LISTING
+
+@c German FIX added include of mirror listing (old German text was bad Texinfo)
+
+@c Mirrors list is created by PHP script (that really needs to be documented!) from database (tfr@mysql.com)
+@include mirrors.texi
+
+@c END_OF_MIRROR_LISTING
+
+
+@node Which OS, Which version, Getting MySQL, General Installation Issues
+@c German node Welches Betriebssystem
+@subsection Betriebssysteme, die von MySQL unterstützt werden
+
+@cindex Betriebssysteme, unterstützte
+@cindex Native Thread-Unterstützung
+@cindex Thread-Unterstützung
+@cindex Prozess-Unterstützung
+@cindex Unterstützung, für Betriebssysteme
+
+Wir benutzen GNU Autoconf, daher ist es möglich, MySQL auf alle modernen
+Betriebssysteme zu portieren, auf denen Posix-Threads und ein C++-Kompiler
+funktionieren. (Um nur den Client-Code zu kompilieren, wir lediglich ein
+C++-Kompiler benötigt.) Wir benutzen und entwickeln die Software selbst
+hauptsächlich auf Sun Solaris (Versionen 2.5 - 2.7) und SuSE Linux Version
+7.x.
+
+Beachten Sie, dass die native Thread-Unterstützung für viele
+Betriebssysteme nur mit den neuesten Versionen funktioniert. Es wurde
+berichtet, dass MySQL erfolgreich auf folgenden Betriebssystemen /
+Thread-Paket-Kombinationen kompiliert wurde:
+
+@itemize @bullet
+@item
+AIX 4.x mit nativen Threads. @xref{IBM-AIX}.
+@item
+Amiga.
+@item
+BSDI 2.x mit enthaltenem MIT-pThreads-Paket. @xref{BSDI}.
+@item
+BSDI 3.0, 3.1 und 4.x mit nativen Threads. @xref{BSDI}.
+@item
+DEC Unix 4.x mit nativen Threads. @xref{Alpha-DEC-UNIX}.
+@item
+FreeBSD 2.x mit enthaltenem MIT-pThreads-Paket. @xref{FreeBSD}.
+@item
+FreeBSD 3.x und 4.x mit nativen Threads. @xref{FreeBSD}.
+@item
+HP-UX 10.20 mit enthaltenem MIT-pThreads-Paket. @xref{HP-UX 10.20}.
+@item
+HP-UX 11.x mit nativen Threads. @xref{HP-UX 11.x}.
+@item
+Linux 2.0+ mit LinuxThreads 0.7.1+ oder @code{glibc} 2.0.7+. @xref{Linux}.
+@item
+Mac OS X Server. @xref{Mac OS X}.
+@item
+NetBSD 1.3/1.4 Intel und NetBSD 1.3 Alpha (benötigt GNU make). @xref{NetBSD}.
+@item
+OpenBSD > 2.5 mit nativen Threads. OpenBSD < 2.5 mit enthaltenem
+MIT-pThreads-Paket. @xref{OpenBSD}.
+@item
+OS/2 Warp 3, FixPack 29 und OS/2 Warp 4, FixPack 4. @xref{OS/2}.
+@item
+SGI Irix 6.x mit nativen Threads. @xref{SGI-Irix}.
+@item
+Solaris 2.5 und höher mit nativen Threads auf SPARC und x86. @xref{Solaris}.
+@item
+SunOS 4.x mit enthaltenem MIT-pThreads-Paket. @xref{Solaris}.
+@item
+Caldera (SCO) OpenServer mit einem aktuellen Port des FSU-PThreads-Pakets. @xref{Caldera}.
+@item
+Caldera (SCO) UnixWare 7.0.1. @xref{Caldera Unixware}.
+@item
+Tru64 Unix
+@item
+Windows 95, Windows 98, NT und Windows 2000. @xref{Windows}.
+@end itemize
+
+Beachten Sie, dass nicht alle Plattformen gleichermaßen gut geeignet sind,
+um MySQL laufen zu lassen. Wie gut eine bestimmte Plattform für hohe Last
+und geschäftskritische Anwendungen geeignet ist, hängt von folgenden
+Faktoren ab:
+
+@itemize @bullet
+@item
+Allgemeine Stabilität der Thread-Bibliothek. Eine Plattform mag in anderer
+Hinsicht einen exzellenten Ruf haben, aber wenn die Thread-Bibliothek
+unstabil ist, die von MySQL aufgerufen wird, läuft MySQL nur so stabil wie
+die Thread-Bibliothek, selbst wenn alles Sonstige perfekt ist.
+
+@item
+Fähigkeit des Kernels und / oder der Thread-Bibliothek, die Vorteile von
+@strong{SMP} auf Mehrprozessor-Systemen wahrzunehmen. Mit anderen Worten:
+Wenn ein Prozess einen Thread anlegen, sollte es für diesen Thread möglich
+sein, auf anderen Prozessoren zu laufen als der Original-Prozess.
+
+@item
+Fähigkeit des Kernels und / oder der Thread-Bibliothek, viele Threads
+laufen zu lassen, die häufig einen Mutex über eine kurze, kritische Region
+anlegen / lösen können ohne exzessive Kontext-Umschaltungen. Mit anderen
+Worten: Wenn die Implementation von @code{pThread_mutex_lock()} zu sehr
+darauf bedacht ist, CPU zu erlangen, wird das MySQL gewaltig schmerzen.
+Wenn man sich dieser Tatsache nicht bewusst ist, machen zusätzliche
+Prozessoren MySQL in der Tat langsamer.
+
+@item
+Allgemeine Stabilität und Performance des Dateisystems.
+
+@item
+Fähigkeit des Dateisystems, überhaupt mit großen Dateien umgehend zu
+können, und zwar effizient, wenn Ihre Tabellen Groß sind.
+
+@item
+Unser Grad von Erfahrung, hier bei MySQL AB, mit der Plattform. Wenn wir
+eine Plattform gut kennen, setzen wir plattformspezifische Optimierungen /
+Verbesserungen (Fixes) ein, die zur Kompilierzeit aktiv werden. Darüber
+hinaus können wir Sie beraten, wie Sie Ihr System optimal für MySQL
+konfigurieren.
+
+@item
+Umfang des Testens ähnlicher Konfigurationen, das wir intern durchgeführt
+haben.
+
+@item
+Anzahl von Benutzern, die MySQL auf dieser Plattform erfolgreich mit
+ähnlichen Konfigurationen haben laufen lassen. Wenn diese Zahl Groß ist,
+ist die Wahrscheinlichkeit viel geringer, plattformspezifische
+Überraschungen zu erleben.
+@end itemize
+
+Nach den genannten Kriterien sind die besten Plattformen für MySQL bislang
+x86 mit SuSE Linux 7.1, 2.4 Kernel und ReiserFS (oder jede ähnliche
+Linux-Distribution) und Sparc mit Solaris 2.7 oder 2.8. FreeBSD kommt als
+drittes, aber wir hoffen wirklich, dass es zur Spitze aufschließt, sobald
+erst einmal die Thread-Bibliothek verbessert ist. Wir hoffen auch, dass wir
+alle anderen Plattformen, auf denen MySQL kompiliert werden kann und
+korrekt läuft, die aber nicht ganz denselben Grad an Stabilität und
+Performance aufweisen, in die Spitzenkategorie aufnehmen können. Das
+erfordert von unserer Seite aus einige Kooperationsbemühungen mit den
+Entwicklern der Betriebssystem-Bibliothek-Komponenten, von denen MySQL
+abhängt. Wenn Sie Interesse daran haben, eine dieser Komponenten zu
+verbessern und in der Lage sind, ihre Entwicklung zu beeinflussen, und
+detailliertere Informationen darüber brauchen, was MySQL benötigt, um
+besser zu laufen, schicken Sie eine E-Mail an
+@email{internals@@lists.mysql.com}.
+
+Beachten Sie bitte auch, dass der obige Vergleich nichts darüber aussagen
+will, dass ein Betriebssystem allgemein besser oder schlechter als ein
+anderes sei. Wir reden hier über die Auswahl eines bestimmten
+Betriebssystems für einen ganz bestimmten Zweck - nämlich, MySQL laufen zu
+lassen, und vergleichen die Betriebssysteme nur in dieser Hinsicht.
+Folglich wäre das Ergebnis dieses Vergleichs ein anderes, wenn wir weitere
+Belange berücksichtigen würden. In manchen Fällen liegt der Grund, warum
+ein Betriebssystem besser als ein anderes geeignet ist, schlicht darin,
+dass wir auf dieser speziellen Plattform mehr Tests und Optimierungen
+durchgeführt haben. Wir stellen hier nur unsere Beobachtungen dar, um Ihnen
+bei der Entscheidung zu helfen, auf welcher Plattform Sie MySQL benutzen
+sollten.
+
+
+@node Which version, Installation layouts, Which OS, General Installation Issues
+@c German node Welche Version
+@subsection Welche MySQL-Version Sie benutzen sollten
+
+@cindex MySQL-Binärdistribution
+@cindex MySQL-Quelldistribution
+@cindex Release-Nummer
+@cindex Version, Auswahl
+@cindex Auswahl, einer MySQL-Version
+
+Zunächst müssen Sie entscheiden, ob Sie das letzte Entwicklungs-Release
+oder das letzte stabile Release benutzen wollen:
+
+@itemize @bullet
+@item
+Normalerweise, wenn Sie MySQL zum ersten Mal benutzen, oder wenn Sie
+versuchen, MySQL auf ein System zu portieren, für das es keine
+Binärdistribution gibt, empfehlen wir, das stabile Release zu nehmen
+(aktuell Version @value{mysql_version}). Beachten Sie, dass alle
+MySQL-Releases mit den MySQL-Benchmarks und einer umfassenden Test-Suite
+getestet sind, bevor das Release heraus gegeben wird.
+
+@item
+Wenn Sie ein altes System laufen lassen und es aktualisieren möchten, aber
+nicht riskieren wollen, dass ein Update nicht reibungslos klappt, sollten
+Sie zur aktuellsten Version des Zweiges aktualisieren, den Sie benutzen
+(bei dem nur die letzte Versionsnummer neuer ist als Ihre, also z. B. von
+3.23.36 auf 3.23.44, wenn 3.23.44 die neueste Version des Zweigs ist). Wir
+haben uns innerhalb der Versions-Zweige bemüht, nur schwere Fehler zu
+beseitigen und kleine, relativ sichere Änderungen zu machen.
+@end itemize
+
+Als nächstes müssen Sie entscheiden, ob Sie eine Quelldistribution oder
+eine Binärdistribution nehmen wollen. In den meisten Fällen ist es ratsam,
+eine Binärdistribution zu nehmen, wenn eine für Ihre Plattform existiert,
+weil sich diese im Allgemeinen leichter installieren läßt als eine
+Quelldistribution.
+
+In folgenden Fällen fahren Sie mit einer Quellinstallation wahrscheinlich
+besser:
+
+@itemize @bullet
+@item
+Wenn Sie MySQL an einer ganz bestimmten Stelle installieren wollen. (Die
+Standard-Binärdistributionen sind an jeder Stelle lauffähig, aber
+vielleicht wollen Sie noch mehr Flexibilität haben.)
+
+@item
+Um unterschiedlichen Bedürfnissen von Benutzern entgegen zu kommen, stellen
+wir zwei unterschiedliche Binärversionen zur Verfügung: Eine, die mit den
+nicht transaktionalen Tabellen-Handlern kompiliert ist (eine kleine,
+schnelle Binärdatei), sowie eine, die mit den wichtigsten erweiterten
+Optionen wie transaktionssicheren Tabellen kompiliert ist. Beide Versionen
+sind aus derselben Quelldistribution kompiliert. Alle nativen
+@code{MySQL}-Clients können sich mit beiden MySQL-Versionen verbinden.
+
+Die erweiterte MySQL-Binärdistribution ist mit dem @code{-max}-Suffix
+gekennzeichnet und ist mit denselben Optionen konfiguriert wie
+@code{mysqld-max}. @xref{mysqld-max, , @code{mysqld-max}}.
+
+Wenn Sie das @code{MySQL-Max}-RPM benutzen wollen, müssen Sie zuerst das
+Standard-@code{MySQL}-RPM installieren.
+
+@item
+Wenn Sie @code{mysqld} mit einigen zusätzlichen Features konfigurieren
+wollen, die NICHT in den Standard-Binärdistributionen enthalten sind. Hier
+ist eine Liste der gebräuchlichsten Zusatzoptionen, die Sie vielleicht
+nutzen wollen:
+
+@itemize @bullet
+@item @code{--with-berkeley-db}
+@item @code{--with-innodb}
+@item @code{--with-raid}
+@item @code{--with-libwrap}
+@item @code{--with-named-z-lib (ist in einigen Binärdateien enthalten)}
+@item @code{--with-debug[=full]}
+@end itemize
+
+@item
+Die vorgabemäßige Binärdistribution wird normalerweise mit Unterstützung
+für alle Zeichensätze kompiliert und sollte auf einer Vielzahl von
+Prozessoren derselben Prozessorfamilie laufen.
+
+Wenn Sie einen schnelleren MySQL-Server erhalten wollen, können Sie ihn
+erneut kompilieren und nur die Zeichensätze benutzen, die Sie brauchen. Sie
+können auch einen besseren Kompiler (wie @code{pgcc}) oder andere
+Kompilieroptionen benutzen, die besser auf Ihren Prozessor optimiert sind.
+
+@item
+Wenn Sie einen Bug gefunden und dem MySQL-Entwicklungsteam mitgeteilt
+haben, werden Sie wahrscheinlich einen Patch erhalten, den Sie mit der
+Quelldistribution verwenden müssen, um den Bug zu beheben.
+
+@item
+Wenn Sie den C- und C++-Code lesen (und / oder ändern) wollen, aus dem
+MySQL besteht, müssten Sie eine Quelldistribution laden. Der Quellcode ist
+immer das ''letzte Handbuch''. Quelldistributionen enthalten auch mehr
+Tests und Beispiele als Binärdistributionen.
+@end itemize
+
+@cindex naming, releases of MySQL
+@cindex Releases, Benennungsschema
+
+Das MySQL Benennungsschema benutzt Release-Nummern, die aus drei Zahlen und
+einem Suffix bestehen. Ein Release-Name wie @code{mysql-3.21.17-beta} zum
+Beispiel wird wie folgt interpretiert:
+
+@itemize @bullet
+@item
+Die erste Zahl (@code{3}) beschreibt das Dateiformat. Alle
+Version-3-Releases haben dasselbe Dateiformat.
+
+@item
+Die zweite Zahl (@code{21}) ist die Release-Ebene (Level). Normalerweise
+kann man hier zwischen zweien auswählen. Einer ist der stabile Zweig des
+Releases (aktuell @code{23}), der andere ist der Entwicklungs-Zweig
+(aktuell @code{4.0}). Normalerweise sind beide stabil, aber die
+Entwicklungsversion kann Macken oder fehlende Dokumentation neuer Features
+haben oder sich auf einigen Systemen nicht kompilieren lassen.
+
+@item
+Die dritte Zahl (@code{17}) ist die Versionsnummer innerhalb der
+Release-Ebene. Diese wird für jede neue Distribution hochgezählt.
+Üblicherweise werden Sie die neueste Version der Release-Ebene einsetzen
+wollen, die Sie gewählt haben.
+
+@item
+Das Suffix (@code{beta}) zeigt den Stabilitätsgrad des Releases an.
+Mögliche Suffixe sind:
+
+@itemize @minus
+@item
+@code{alpha} zeigt an, dass das Release größere Abschnitte von neuem Code
+enthält, der noch nicht zu 100% getestet wurde. Bekannte Bugs
+(üblicherweise gibt es keine) sind im News-Abschnitt dokumentiert.
+@xref{News}. In den meisten Alpha-Releases gibt es neue Befehle und
+Erweiterungen. Bei einem Alpha-Release können durch aktive
+Weiterentwicklung größere Code-Änderungen vorkommen, aber alles wird
+getestet, bevor ein Release veröffentlicht wird. Es sollte in keinem
+MySQL-Release bekannte Bugs geben.
+
+@item
+@code{beta} bedeutet, dass jeglicher neue Code getestet wurde. Es wurden
+keine neuen Features hinzugefügt, die bei altem Code Probleme verursachen
+könnten. Es sollte keine bekannten Bugs geben. Eine Version wird von Alpha
+auf Beta gesetzt, wenn innerhalb der Alpha-Version mindestens einen Monat
+lang keine schweren Fehler mehr berichtet wurden. Wir planen für eine
+solche Version dann keine neuen Features mehr, die einen alten Befehl
+unzuverlässiger machen könnten.
+
+@item
+@code{gamma} ist eine Beta-Version, die eine ganze Weile draussen war und
+offensichtlich gut funktioniert. Nur kleinere Problembehebungen wurden
+hinzugefügt. So etwas nennen viele andere Unternehmen ein Release.
+
+@item
+Wenn eine Version kein Suffix besitzt, bedeutet das, dass diese Version
+schon eine ganze Weile auf vielen unterschiedlichen Sites eingesetzt wird,
+wobei keine Bugs ausser plattformspezifischen Bugs berichtet wurden. Für
+ein solches Release werden nur kritische Fehlerbehebungen durchgeführt. So
+etwas nennen wir ein stabiles Release.
+@end itemize
+@end itemize
+
+Alle Versionen von MySQL laufen durch unsere Standard-Tests und
+-Benchmarks, um sicherzustellen, dass man sie relativ sicher benutzen kann.
+Weil die Standard-Tests im Laufe der Zeit erweitert werden, um auf alle
+früher gefundenen Bugs zu prüfen, wird die Test-Suite immer besser.
+
+@cindex releases, testing
+@cindex Testen, von MySQL-Releases
+
+Beachten Sie, dass alle Releases mindestens wie folgt getestet wurden:
+
+@table @asis
+@item Mit der internen Test-Suite
+Diese ist Teil unseres Produktionssystems für einen Kunden. Sie besitzt
+viele Tabellen mit Hunderten Megabytes an Daten.
+
+@item Mit der MySQL-Benchmark-Suite
+Diese läßt eine Reihe gebräuchlicher Anfragen laufen. Das ist zusätzlich
+ein Test darauf, ob die letzten Optimierungen den Code tatsächlich
+schneller gemacht haben.
+@xref{MySQL Benchmarks}.
+
+@item Mit dem @code{crash-me}-Test
+Dieser Test versucht festzustellen, welche Features die Datenbank
+unterstützt und was ihre Fähigkeiten und Beschränkungen sind. @xref{MySQL Benchmarks}.
+@end table
+
+Ein weiterer Test besteht darin, dass wir die neueste MySQL-Version in
+unserer internen Entwicklungsumgebung einsetzen, mindestens auf einer
+Maschine. Wir arbeiten hierbei mit mehr als 100 Gigabytes an Daten.
+
+
+@node Installation layouts, Many versions, Which version, General Installation Issues
+@c German node Installationslayouts
+@subsection Installationslayouts
+
+@cindex Installationslayouts
+@cindex Layout der Installation
+@cindex Verzeichnisstruktur, Vorgabe
+@cindex Vorgabemäßiger Installationsort
+
+Dieser Abschnitt beschreibt das vorgabemäßige Layout der Verzeichnisse,
+die durch die Installation von Binär- und Quelldistributionen angelegt
+werden.
+
+Eine Binärdistribution wird installiert, indem sie an die
+Installationsstelle entpackt wird, die Sie auswählen (typischer Weise
+@file{/usr/local/mysql}). Die Installation erstellt folgende Verzeichnisse
+an dieser Stelle:
+
+@multitable @columnfractions .3 .7
+@item @strong{Verzeichnis} @tab @strong{Verzeichnisinhalt}
+@item @file{bin} @tab Client-Programme und der
+@code{mysqld}-Server
+@item @file{data} @tab Log-Dateien, Datenbanken
+@item @file{include} @tab Include-(Header)-Dateien
+@item @file{lib} @tab Bibliotheken
+@item @file{scripts} @tab @code{mysql_install_db}
+@item @file{share/mysql} @tab Dateien mit Fehlernachrichten
+@item @file{sql-bench} @tab Benchmarks
+@end multitable
+
+Eine Quelldistribution wird installiert, nachdem Sie sie konfiguriert und
+kompiliert haben. Vorgabemäßig werden Dateien unter @file{/usr/local}
+installiert, und zwar in den folgenden Unterverzeichnissen:
+
+@multitable @columnfractions .3 .7
+@item @strong{Verzeichnis} @tab @strong{Verzeichnisinhalt}
+@item @file{bin} @tab Client-Programme und -Skripte
+@item @file{include/mysql} @tab Include-(Header)-Dateien
+@item @file{info} @tab Dokumentation im Info-Format
+@item @file{lib/mysql} @tab Bibliotheken
+@item @file{libexec} @tab Der @code{mysqld}-Server
+@item @file{share/mysql} @tab Dateien mit Fehlernachrichten
+@item @file{sql-bench} @tab Benchmarks und @code{crash-me}-Test
+@item @file{var} @tab Datenbanken und Log-Dateien
+@end multitable
+
+Innerhalb eines Installationsverzeichnisses weicht das Layout einer
+Quellinstallation von dem einer Binärinstallation wie folgt ab:
+
+@itemize @bullet
+@item
+Der @code{mysqld}-Server wird in das @file{libexec}-Verzeichnis installiert
+und nicht in das @file{bin}-Verzeichnis.
+
+@item
+Das Daten-Verzeichnis ist @file{var} und nicht @file{data}.
+
+@item
+@code{mysql_install_db} wird in das @file{/usr/local/bin} Verzeichnis
+installiert und nicht in @file{/usr/local/mysql/Skripts}.
+
+@item
+Die Header-Datei und Bibliotheksverzeichnisse sind @file{include/mysql} und
+@file{lib/mysql} und nicht @file{include} und @file{lib}.
+@end itemize
+
+Sie können Ihre eigene Binärinstallation aus einer kompilierten
+Quelldistribution erzeugen, indem Sie das Skript
+@file{Skripts/make_binary_Distribution} ausführen.
+
+
+@node Many versions, MySQL binaries, Installation layouts, General Installation Issues
+@c German node Viele Versionen
+@subsection Wann und wie Updates veröffentlicht werden
+
+@cindex Releases, Updates
+@cindex Updates, Releases von MySQL
+
+MySQL entwickelt sich ziemlich schnell hier bei MySQL AB und wir wollen,
+dass andere MySQL-Benutzer daran teilhaben. Wir versuchen, immer dann ein
+neues Release heraus zu bringen, wenn wir sehr nützliche Features haben,
+für die offensichtlich ein Bedarf besteht.
+
+Auch versuchen wir, unseren Benutzern zu helfen, wenn Sie nach Features
+anfragen, die einfach zu implementieren sind. Wir notieren, was unsere
+lizensierten Nutzer haben wollen, und insbesondere, was unsere Benutzer mit
+erweitertem E-Mail-Support haben wollen, und versuchen ihnen, eben das zu
+bieten.
+
+Niemand muss einen neuen Release herunter laden. Im News-Abschnitt steht
+stets, ob das neue Release etwas beinhaltet, was Sie wirklich brauchen.
+@xref{News}.
+
+Wenn wir MySQL aktualisieren, fahren wir folgende Politik:
+
+@itemize @bullet
+@item
+Bei kleineren Updates wird die letzte Zahl (von rechts) in der
+Versionsnummer herauf gezählt (Minor Release). Wenn es größere neue
+Features gibt oder kleinere Inkompatibilitäten mit vorherigen Versionen,
+wird die zweite Zahl der Versionsnummer herauf gezählt (Major Release).
+Wenn sich das Dateiformat ändert, wird die erste Zahl herauf gezählt.
+
+@item
+@c Question: This is supposed to mean "stable major releases". What does it
+have to do with "small bugs" => minor releases?
+Stable tested releases are meant to appear about 1-2 times a year, but
+if small bugs are found, a release mit only bug fixes will be released.
+Als stabil getestete Releases sollten etwa ein- bis zweimal im Jahr
+erscheinen, aber wenn kleinere Fehler gefunden werden, wird nur ein Release
+mit Bug-Fixes heraus gegeben.
+
+
+@item
+Funktionierende Releases sollten etwa alle 1 bis 8 Wochen erscheinen.
+
+@item
+Binärdistributionen für einige Plattformen werden von uns für größere
+Releases (Major) heraus gegeben. Andere Leute stellen vielleicht auch
+Binärdistributionen für andere Systeme her, aber nicht so häufig.
+
+@item
+Patches stellen wir üblicherweise zur Verfügung, sobald wir kleinere Bugs
+ausfindig gemacht und behoben haben.
+
+@item
+Für nicht kritische, aber störende Bugs machen wir Patches verfügbar, wenn
+sie uns zugesandt werden. Ansonsten kombinieren wir mehrere davon in einem
+größeren Patch.
+
+@item
+Wenn durch unglückliche Umstände ein Release einen schweren Fehler enthält,
+erstellen wir sobald wie möglich ein neues Release. Das würden wir auch
+gern bei anderen Unternehmen so sehen.
+@end itemize
+
+
+@c Question: I will not translate this paragraph now. Please update this!
+The current stable release ist Version 3.23; We have already moved active
+Entwicklung to Version 4.0. Bugs will still be fixed in the stable version.
+We don't believe in a complete freeze, as this also leaves out bug fixes
+und things that ``must be done.'' ``Somewhat frozen'' means that we may
+add small things that ``almost surely will not affect anything that's
+already working.''
+
+
+@node MySQL binaries, , Many versions, General Installation Issues
+@c German node MySQL-Binärdistributionen
+@subsection MySQL-Binärdistributionen, die von MySQL AB kompiliert wurden
+
+@cindex Binärdistributionen
+
+Als Service stellen wir bei MySQL AB einen Satz von Binärdistributionen von
+MySQL zur Verfügung, die auf unserer Site kompiliert wurden oder auf Sites
+von Kunden, die uns freundlicherweise Zugang zu Ihren Maschinen gewährt
+haben.
+
+Diese Distributionen werden mit @code{Skripts/make_binary_distribution}
+erzeugt und mit folgenden Kompilern und Optionen konfiguriert:
+
+@table @asis
+@item SunOS 4.1.4 2 sun4c mit @code{gcc} 2.7.2.1
+@code{CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-assembler}
+
+@item SunOS 5.5.1 (und höher) sun4u mit @code{egcs} 1.0.3a oder 2.90.27 oder gcc 2.95.2 und neuer
+@code{CC=gcc CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex --enable-assembler}
+
+@item SunOS 5.6 i86pc mit @code{gcc} 2.8.1
+@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex}
+
+@item Linux 2.0.33 i386 mit @code{pgcc} 2.90.29 (@code{egcs} 1.0.3a)
+@code{CFLAGS="-O3 -mpentium -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentium -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --with-extra-charsets=complex}
+
+@item Linux 2.2.x mit x686 mit @code{gcc} 2.95.2
+@code{CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charset=complex}
+
+@item SCO 3.2v5.0.4 i386 mit @code{gcc} 2.7-95q4
+@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
+
+@item AIX 2 4 mit @code{gcc} 2.7.2.2
+@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
+
+@item OSF1 V4.0 564 alpha mit @code{gcc} 2.8.1
+@code{CC=gcc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex}
+
+@item Irix 6.3 IP32 mit @code{gcc} 2.8.0
+@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
+
+@item BSDI BSD/OS 3.1 i386 mit @code{gcc} 2.7.2.1
+@code{CC=gcc CXX=gcc CXXFLAGS=-O ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
+
+@item BSDI BSD/OS 2.1 i386 mit @code{gcc} 2.7.2
+@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
+@end table
+
+Wenn jemand optimalere Optionen für die obigen Konfigurationen hat, können
+diese jederzeit der Entwickler-Mailing-Liste unter
+@email{internals@@lists.mysql.com} mitgeteilt werden.
+
+RPM-Distributionen von MySQL-Version 3.22 wurden durch Benutzer
+beigesteuert. Ab Version 3.22 werden die RPMs von uns bei MySQL AB erzeugt.
+
+Wenn Sie eine Debug-Version von MySQL kompilieren wollen, müssen Sie den
+oben genannten Kompilierzeilen @code{--with-debug} oder
+@code{--with-debug=full} hinzufügen und jegliche
+@code{-fomit-frame-pointer}-Optionen entfernen.
+
+
+@node Installing source, Post-installation, General Installation Issues, Installing
+@c German node Installation der Quelldistribution
+@section Installation der Quelldistribution
+
+@cindex Installation, Quelldistribution
+@cindex Quelldistribution, Installation
+@cindex Installation, Überblick
+
+Bevor Sie mit der Quellinstallation fortfahren, sehen Sie nach, ob eine
+Binärdistribution für Ihre Plattform verfügbar ist, die so wie Sie wollen
+funktioniert. Wir geben uns viel Mühe, die Binärdistributionen mit den
+bestmöglichen Optionen zu bauen.
+
+Sie benötigen folgende Werkzeuge, um MySQL aus der Quelldistribution zu bauen
+und zu installieren:
+
+@itemize @bullet
+@item
+GNU @code{gunzip}, um die Distribution zu entpacken.
+
+@item
+Ein vernünftiges @code{tar}, um die Distribution zu entpacken. Von GNU
+@code{tar} ist bekannt, dass es funktioniert. Sun @code{tar} ist dafür
+bekannt, dass es Probleme verursacht.
+
+@item
+Einen funktionierenden ANSI-C++-Kompiler. @code{gcc} >= 2.95.2, @code{egcs} >= 1.0.2
+oder @code{egcs 2.91.66}, SGI C++ und SunPro C++ sind einige der Kompiler,
+von denen bekannt ist, dass sie funktionieren. @code{libg++} wird nicht
+benötigt, wenn Sie @code{gcc} benutzen. @code{gcc} 2.7.x hat einen Bug, der
+es verunmöglicht, einige perfekt der vorgeschriebenen Form entsprechende
+C++-Dateien zu kompilieren, zum Beispiel @file{sql/sql_base.cc}. Wenn Sie
+nur @code{gcc} 2.7.x zur Verfügung haben, müssen Sie Ihren @code{gcc}
+aktualisieren, um MySQL kompilieren zu können. @code{gcc} 2.8.1 ist
+ebenfalls für Probleme auf einigen Plattformen bekannt, daher sollten Sie
+auch diesen vermeiden, wenn Sie einen neueren Kompiler für diese Plattform
+zur Verfügung haben.
+
+@code{gcc} >= 2.95.2 wird für das Kompilieren von MySQL-Versionen 3.23.x
+empfohlen.
+
+@item
+Ein gutes @code{make}-Programm. GNU @code{make} wird stets empfohlen und
+ist manchmal erforderlich. Wenn Sie Probleme bekommen, empfehlen wir, es
+mit GNU @code{make} 3.75 oder neuer zu versuchen.
+@end itemize
+
+Wenn Sie eine aktuelle Version von @strong{gcc} verwenden (aktuell genug,
+um die @code{-fno-exceptions}-Option zu verstehen), ist es @strong{SEHR
+WICHTIG}, dass Sie diese Option benutzen. Ansonsten könnte es sein, dass
+Sie eine Binärdatei kompilieren, die zu zufälligen Zeitpunkten abstürzt.
+Wir empfehlen zusätzlich, dass Sie @code{-felide-contructors} und
+@code{-fno-rtti} zusammen mit @code{-fno-exceptions} benutzen. Im Zweifel
+gehen Sie wie folgt vor:
+
+@example
+
+CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
+
+@end example
+
+Für die meisten Systeme werden Sie dadurch eine schnelle, stabile
+Binärinstallation erhalten.
+
+@c texi2html fails to split chapters if I use strong für all of this.
+Wenn Sie Probleme bekommen, @strong{BITTE BENUTZEN SIE IMMER
+@code{mysqlbug}} zum Fragenstellen die Liste
+@email{mysql@@lists.mysql.com}. Selbst wenn das Problem kein Bug ist,
+sammelt @code{mysqlbug} Systeminformationen, die anderen helfen werden, Ihr
+Problem zu lösen. Wenn Sie @code{mysqlbug} nicht benutzen, verringern Sie
+die Möglichkeit, eine Lösung Ihres Problems zu bekommen! @code{mysqlbug}
+finden Sie im @file{scripts}-Verzeichnis, nachdem Sie die Distribution
+entpackt haben. @xref{Bug reports}.
+
+
+
+@menu
+* Quick install::
+* Applying patches::
+* configure options::
+* Installing source tree::
+* Compilation problems::
+* MIT-pthreads::
+* Windows source build::
+@end menu
+
+@node Quick install, Applying patches, Installing source, Installing source
+@c German node Schnellinstallation
+@subsection Schnellinstallation, Überblick
+
+Die grundlegenden Befehle, die Sie ausführen müssen, um eine
+MySQL-Quelldistribution zu installieren, sind:
+
+@example
+shell> groupadd mysql
+shell> useradd -g mysql mysql
+shell> gunzip < mysql-VERSION.tar.gz | tar -xvf -
+shell> cd mysql-VERSION
+shell> ./configure --prefix=/usr/local/mysql
+shell> make
+shell> make install
+shell> scripts/mysql_install_db
+shell> chown -R root /usr/local/mysql
+shell> chown -R mysql /usr/local/mysql/var
+shell> chgrp -R mysql /usr/local/mysql
+shell> cp support-files/my-medium.cnf /etc/my.cnf
+shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
+@end example
+
+@c German FIX added @samp before {#}
+Wenn Sie Unterstützung für InnoDB-Tabellen haben wollen, sollten Sie die
+Datei @code{/etc/my.cnf} editieren und die @samp{#}-Zeichen vor den Parametern
+entfernen, der mit @code{innodb_...} beginnen. @xref{Option files}.
+@xref{InnoDB start}.
+
+Wenn Sie mit einem Quell-RPM anfangen, gehen Sie wie folgt vor:
+
+@example
+shell> rpm --rebuild MySQL-VERSION.src.rpm
+@end example
+
+Das erzeugt ein Binär-RPM, das Sie installieren können.
+
+Sie können neue Benutzer hinzufügen, indem Sie das
+@code{bin/mysql_setpermission}-Skript benutzen, falls Sie die @code{DBI}-
+und @code{Msql-Mysql-modules}-Perl-Module installieren.
+
+Eine detailliertere Beschreibung folgt.
+
+Um eine Quelldistribution zu installieren, führen Sie die unten stehenden
+Schritte aus und gehen dann weiter zu @ref{Post-installation}, um die
+Schritte nach der Installation und ein paar Tests durchzuführen.
+
+@enumerate
+@item
+Wählen Sie das Verzeichnis, in dem Sie die Distribution entpacken wollen,
+und wechseln Sie dort hinein.
+
+@item
+Holen Sie sich eine Distributionsdatei von einer der Sites, die unter
+@ref{Getting MySQL, , Wie man MySQL erhält} aufgelistet sind.
+
+@item
+Wenn Sie Berkeley-DB-Tabellen mit MySQL verwenden wollen, müssen Sie sich
+eine gepatchte Version des Berkeley-DB-Quellcodes besorgen. Bitte lesen Sie
+das Kapitel über Berkeley-DB-Tabellen, bevor Sie fortfahren. @xref{BDB}.
+
+MySQL-Quelldistributionen stehen als komprimierte @code{tar}-Archive zur
+Verfügung und haben Namen wie @file{mysql-VERSION.tar.gz}, wobei
+@code{VERSION} eine Zahl ist, wie @value{mysql_version}.
+
+@item
+Fügen Sie einen Benutzer (User) und eine Gruppe (Group) hinzu, unter dem /
+der @code{mysqld} laufen soll:
+
+@example
+shell> groupadd mysql
+shell> useradd -g mysql mysql
+@end example
+
+Diese Befehle fügen den Benutzer @code{mysql} und die Gruppe @code{mysql}
+hinzu. Die Syntax für @code{useradd} und @code{groupadd} kann sich auf
+unterschiedlichen Unix-Systemen geringfügig unterscheiden. Die Befehle
+können @code{adduser} und @code{addgroup} heißen. Wenn Sie wollen, können
+Sie Benutzer und Gruppe auch anders nennen als @code{mysql}.
+
+@item
+Entpacken Sie die Distribution ins aktuelle Verzeichnis:
+@example
+shell> gunzip < /pfad/zu/mysql-VERSION.tar.gz | tar xvf -
+@end example
+
+Dieser Befehl erzeugt ein Verzeichnis namens @file{mysql-VERSION}.
+
+@item
+Wechseln Sie in das oberste Verzeichnis der entpackten Distribution:
+
+@example
+shell> cd mysql-VERSION
+@end example
+
+Beachten Sie, dass Sie aktuell MySQL aus diesem obersten Verzeichnis
+konfigurieren und bauen müssen. Sie können MySQL nicht in ein anderes
+Verzeichnis bauen.
+
+@item
+Konfigurieren Sie das Release und kompilieren Sie alles:
+
+@example
+shell> ./configure --prefix=/usr/local/mysql
+shell> make
+@end example
+
+Wenn Sie @code{configure} laufen lassen, können Sie dabei einige Optionen
+angeben. Geben Sie @code{./configure --help} ein, um eine Liste von
+Optionen zu erhalten. @ref{configure options, , @code{configure}-Optionen}
+erörtert einige der nützlicheren Optionen.
+
+Wenn @code{configure} fehlschlägt und Sie sich wegen Hilfe an
+@email{mysql@@lists.mysql.com} wenden, geben Sie bitte alle Zeilen aus
+@file{config.log} an, von denen Sie annehmen, dass sie bei der
+Problembehebung hilfreich sein könnten. Fügen Sie auch die letzten Zeilen
+der Ausgabe von @code{configure} hinzu, wenn @code{configure} abbricht.
+Schicken Sie den Bug-Bericht ein, indem Sie das @code{mysqlbug}-Skript
+benutzen. @xref{Bug reports}.
+
+Wenn das Kompilieren fehlschlägt, sehen Sie unter
+@ref{Compilation problems} nach, was bei einer Reihe geläufiger Probleme
+hilft.
+
+@item
+Installieren Sie alles:
+
+@example
+shell> make install
+@end example
+
+Eventuell müssen Sie diesen Befehl als @code{root} ausführen.
+
+@item
+Erzeugen Sie die MySQL-Berechtigungstabellen (Grant Tables, nur notwendig,
+wenn Sie MySQL noch nie vorher installiert haben):
+
+@example
+shell> scripts/mysql_install_db
+@end example
+
+Beachten Sie, dass bei MySQL-Versionen vor Version 3.22.10 der MySQL-Server
+startet, wenn Sie @code{mysql_install_db} laufen lassen. Das gilt für
+neuere Versionen nicht mehr!
+
+@item
+Ändern Sie den Besitzer der Binärdateien zu @code{root} und den Besitzer
+des Daten-Verzeichnisses zu dem Benutzer, unter dem Sie @code{mysqld} laufen
+lassen wollen:
+
+@example
+shell> chown -R root /usr/local/mysql
+shell> chown -R mysql /usr/local/mysql/var
+shell> chgrp -R mysql /usr/local/mysql
+@end example
+
+Der erste Befehl ändert die @code{owner}-Attribute der Dateien auf den
+Benutzer @code{root}, der zweite ändert die @code{owner}-Attribute des
+Daten-Verzeichnisses auf den Benutzer @code{mysql} und der dritte ändert die
+@code{group}-Attribute auf die Gruppe @code{mysql}.
+
+@item
+Wenn Sie die Unterstützung für die Perl-@code{DBI}/@code{DBD}-Schnittstelle
+hinzufügen wollen, sehen Sie unter @ref{Perl} nach.
+
+@item
+Wenn Sie wollen, dass MySQL automatisch startet, wenn Sie Ihre Maschine
+hoch fahren, kopieren Sie @code{support-files/mysql.server} an die Stelle,
+wo Ihr System seine Startdateien hat. Weitere Informationen finden Sie im
+@code{support-files/mysql.server}-Skript selbst sowie unter
+@ref{Automatic start}.
+@end enumerate
+
+Nachdem alles installiert wurde, sollten Sie Ihre Distribution
+initialisieren und testen:
+
+@example
+shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
+@end example
+
+Wenn dieser Befehl sofort mit @code{mysqld daemon ended} fehlschlägt,
+finden Sie einige Informationen dazu in der Datei
+@file{mysql-Daten-Verzeichnis/'hostname'.err}. Der wahrscheinliche Grund ist
+der, dass bereits ein anderer @code{mysqld}-Server läuft. @xref{Multiple servers}.
+
+@xref{Post-installation}.
+
+
+@node Applying patches, configure options, Quick install, Installing source
+@c German node Patches anwenden
+@subsection Wie man Patches anwendet
+
+@cindex Patches, anwenden
+@cindex Anwenden, Patches
+
+Manchmal erscheinen Patches auf der Mailing-Liste oder werden auf
+@uref{http://www.mysql.com/Downloads/Patches, Patches-Bereich} auf der
+MySQL-Website eingestellt.
+
+Um einen Patch aus der Mailing-Liste anzuwenden, speichern Sie die
+Nachricht, in der der Patch enthalten ist, in eine Datei. Wechseln Sie dann
+ins oberste Verzeichnis Ihres MySQL-Source-Trees und geben Sie folgende
+Befehle ein:
+
+@example
+shell> patch -p1 < patch-datei-name
+shell> rm config.cache
+shell> make clean
+@end example
+
+Patches von der FTP-Site werden als Klartextdateien (Plain Text) oder als
+mit @code{gzip} komprimierte Dateien distribuiert. Ein Klartext-Patch
+wenden Sie genau so an, wie oben für die Patches von der Mailing-Liste
+beschrieben. Um ein komprimiertes Patch anzuwenden, wechseln Sie ins
+oberste Verzeichnis Ihres MySQL-Source-Trees und geben Sie folgende Befehle
+ein:
+
+@example
+shell> gunzip < patch-datei-name.gz | patch -p1
+shell> rm config.cache
+shell> make clean
+@end example
+
+Nachdem Sie einen Patch angewendet haben, folgen Sie den Anweisungen für
+eine normale Installation vom Quellcode, indem Sie mit dem Schritt
+@code{./configure} anfangen. Nach dem Schritt @code{make install}, starten
+Sie den MySQL-Server neu.
+
+Es kann sein, dass Sie jeden laufenden Server anhalten müssen, bevor Sie
+@code{make install} laufen lassen können. (Das machen Sie mit
+@code{mysqladmin shutdown}.) Einige Systeme lassen es nicht zu, dass eine
+neue Programmversion installiert wird, wenn diese eine Version ersetzt, die
+momentan ausgeführt wird.
+
+
+@node configure options, Installing source tree, Applying patches, Installing source
+@c German node Optionen konfigurieren
+@subsection Typische @code{configure}-Optionen
+
+@findex without-server-Option
+@cindex @code{configure}-Skript
+@cindex Optionen, configure
+@cindex Konfigurationsoptionen
+@cindex Log-Dateien
+@cindex Dateien, Log
+
+Das @code{configure}-Skript gibt Ihnen in großem Umfang Kontrolle über die
+Konfigurationsmöglichkeiten Ihrer MySQL-Distribution. Typischerweise machen
+Sie das unter Verwendung der Optionen auf der
+@code{configure}-Kommandozeile. Sie können ausserdem @code{configure}
+beeinflussen, indem Sie bestimmte Umgebungsvariablen benutzen.
+@xref{Environment variables}. Um eine Liste der Optionen zu erhalten, die
+@code{configure} unterstützt, geben Sie folgendes ein:
+
+@example
+shell> ./configure --help
+@end example
+
+Einige der gebräuchlicheren @code{configure}-Optionen sind im Folgenden
+beschrieben:
+
+@itemize @bullet
+@item
+Um nur die MySQL-Client Bibliotheken und Client-Programme und nicht den
+Server zu kompilieren, benutzen Sie die @code{--ohne-server}-Option:
+
+@example
+shell> ./configure --without-server
+@end example
+
+@c FIX incorrect..
+
+Wenn Sie keinen C++-Kompiler haben, können Sie @code{mysql} nicht
+kompilieren (MySQL ist das einzige Client-Programm, das C++ erfordert). In
+diesem Fall können Sie den Code in @code{configure} entfernen, der auf den
+C++-Kompiler testet, und dann @code{./configure} mit der
+@code{--without-server}-Option eingeben. Dieser Kompilierschritt wird nach
+wie vor versuchen, @code{mysql} zu bauen, aber Sie können alle Warnungen zu
+@file{mysql.cc} ignorieren. (Wenn @code{make} anhält, versuchen Sie
+@code{make -k}, um ihm mitzuteilen, dass es mit dem Rest des Builds
+fortfahren soll, auch wenn Fehler auftreten.)
+
+@item
+Wenn Sie nicht wollen, dass Ihre Log-Dateien und Datenbankverzeichnisse
+unter @file{/usr/local/var} liegen, benutzen Sie ein
+@code{configure}-Kommando wie folgendes:
+
+@example
+shell> ./configure --prefix=/usr/local/mysql
+shell> ./configure --prefix=/usr/local \
+ --localstatedir=/usr/local/mysql/data
+@end example
+
+Der erste Befehl ändert das Installationspräfix, so dass alles unter
+@file{/usr/local/mysql} statt unter @file{/usr/local} installiert wird. Der
+zweite Befehl bewahrt das vorgabemäßige Installationspräfix, aber
+überschreibt die vorgabemäßige Stelle für Datenbankverzeichnisse
+(normalerweise @file{/usr/local/var}) und ändert sie zu
+@code{/usr/local/mysql/data}.
+
+@cindex Speicherort des Sockets ändern
+@cindex Socket-Speicherort, ändern
+@cindex mysql.sock, Änderung des Speicherorts
+@item
+
+Wenn Sie Unix benutzen und wollen, dass der MySQL-Socket an anderer Stelle
+liegt als vorgabemäßig (normalerweise im Verzeichnis @file{/tmp} oder
+@file{/var/run}), benutzen Sie ein @code{configure}-Kommando wie folgendes:
+
+@example
+shell> ./configure --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
+@end example
+
+Beachten Sie, dass die angegebene Datei mit einem absoluten Pfadnamen
+angegeben werden muss! Sie können den Speicherort von @file{mysql.sock}
+auch später noch ändern, indem Sie die MySQL Optionsdateien benutzen.
+@xref{Problems with mysql.sock}.
+
+@cindex Kompilieren, statisch
+@cindex Statisch, Kompilieren
+@item
+Wenn Sie statisch gelinkte Programme kompilieren wollen (um zum Beispiel
+eine Binärdistribution zu machen, mehr Geschwindigkeit zu erhalten oder
+Probleme mit RedHat-Linux-Distributionen zu umgehen (Workaround)), geben
+Sie @code{configure} wie folgt ein:
+
+@example
+shell> ./configure --with-client-ldflags=-all-static \
+ --with-mysqld-ldflags=-all-static
+@end example
+
+
+
+@tindex @code{CC} Umgebungsvariable
+@tindex Umgebungsvariable, @code{CC}
+@tindex @code{CXX} Umgebungsvariable
+@tindex Umgebungsvariable, @code{CXX}
+@cindex @code{gcc}
+@cindex C++-Kompiler, @code{gcc}
+@cindex Kompiler, C++ @code{gcc}
+@item
+Wenn Sie @code{gcc} benutzen und @code{libg++} oder @code{libstdc++} nicht
+installiert haben, können Sie @code{configure} mitteilen, @code{gcc} als
+Ihren C++-Kompiler zu benutzen:
+
+@example
+shell> CC=gcc CXX=gcc ./configure
+@end example
+
+Wenn Sie @code{gcc} als C++-Kompiler benutzen, versucht dieser nicht,
+@code{libg++} oder @code{libstdc++} zu linken.
+
+Hier sind einige gebräuchliche Umgebungsvariablen, die man in Abhängigkeit
+vom verwendeten Kompiler setzen kann:
+
+@tindex CXXFLAGS Umgebungsvariable
+@tindex Umgebungsvariable, CXXFLAGS
+@multitable @columnfractions .20 .80
+@item gcc 2.7.2.1 @tab
+CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors"
+@item egcs 1.0.3a @tab
+CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti"
+@item gcc 2.95.2 @tab
+CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti"
+@item pgcc 2.90.29 oder newer @tab
+CFLAGS="-O3 -mpentiumpro -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti"
+@end multitable
+
+In den meisten Fällen erhalten Sie eine ziemlich optimale MySQL-Binärdatei,
+indem Sie die Optionen von weiter oben nutzen und die folgenden Optionen
+zur Konfigurationszeile hinzufügen:
+
+@example
+--prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
+@end example
+
+Die komplette Konfigurationszeile würde also etwa wie folgt aussehen (für
+alle aktuellen gcc-Versionen):
+
+@example
+CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
+@end example
+
+Die Binärdistributionen, die wir auf der MySQL-Website unter
+@uref{http://www.mysql.com} zur Verfügung stellen, sind allesamt mit voller
+Optimierung kompiliert und sollten daher für die meisten Benutzer perfekt
+sein. @xref{MySQL binaries}. Einiges können Sie noch fein justieren, um
+noch schnellere Binärdistributionen zu erhalten, aber das ist nur etwas für
+fortgeschrittene Benutzer. @xref{Compile and link options}.
+
+Wenn der Build fehlschlägt und Fehler produziert, die aussagen, dass Ihr
+Kompiler oder Linker nicht in der Lage ist, die gemeinsam benutzte
+(shared) Bibliothek @file{libmysqlclient.so.#} (@samp{#} ist eine
+Versionsnummer) zu erzeugen, können Sie dieses Problem umgehen, indem Sie
+die @code{--disable-shared}-Option von @code{configure} benutzen. In diesem
+Fall baut @code{configure} keine gemeinsam benutzte
+@code{libmysqlclient.so.#}-Bibliothek.
+
+@cindex Vorgabewerte, Unterdrückung
+@cindex Unterdrückung, Vorgabewerte
+@item
+Sie können MySQL so konfigurieren, dass keine @code{DEFAULT}-Spaltenwerte
+für Nicht-@code{NULL}-Spalten benutzt werden (also Spalten, bei denen nicht
+zulässig ist, dass sie @code{NULL} sind). Das führt dazu, dass
+@code{INSERT}-Statements einen Fehler erzeugen, ausser wenn ausdrücklich
+Werte für Spalten angegeben werden, die einen Nicht-@code{NULL}-Werte
+verlangen. Um die Benutzung von Vorgabewerten zu unterdrücken, geben Sie
+@code{configure} wie folgt ein:
+
+@tindex CXXFLAGS Umgebungsvariable
+@tindex Umgebungsvariable, CXXFLAGS
+@example
+shell> CXXFLAGS=-DDONT_USE_DEFAULT_FIELDS ./configure
+@end example
+
+@cindex Zeichensätze
+@findex configure-Option, --with-charset
+@findex configure-Option, --with-extra-charset
+@item
+Als Vorgabe benutzt MySQL den Zeichensatz ISO-8859-1 (Latin1). Um diesen
+Vorgabesatz zu ändern, benutzen Sie die @code{--with-charset}-Option:
+@example
+shell> ./configure --with-charset=CHARSET
+@end example
+@code{CHARSET} kann einer der folgenden sein: @code{big5}, @code{cp1251}, @code{cp1257},
+@code{czech}, @code{danish}, @code{dec8}, @code{dos}, @code{euc_kr},
+@code{gb2312}, @code{gbk}, @code{german1}, @code{hebrew}, @code{hp8},
+@code{hungarian}, @code{koi8_ru}, @code{koi8_ukr}, @code{latin1},
+@code{latin2}, @code{sjis}, @code{swe7}, @code{tis620}, @code{ujis},
+@code{usa7} oder @code{win1251ukr}.
+@xref{Character sets}.
+
+Wenn Sie Zeichen zwischen Server und Client konvertieren wollen, sollten
+Sie sich den @code{SET OPTION CHARACTER SET}-Befehl ansehen.
+@xref{SET OPTION, , @code{SET OPTION}}.
+
+@cindex @code{myisamchk}
+@strong{Achtung:} Wenn Sie Zeichensätze ändern, nachdem Sie irgend welche
+Tabellen angelegt haben, müssen Sie @code{myisamchk -r -q} über jede
+Tabelle laufen lassen, denn ansonsten könnten Ihre Indexe falsch sortiert
+werden. (Das kann passieren, wenn Sie MySQL installieren, ein paar Tabellen
+erzeugen und danach MySQL rekonfigurieren, so dass es einen anderen
+Zeichensatz benutzt, und dann neu installieren.)
+
+Mit der Option @code{--with-extra-charset=LIST} können Sie zusätzliche
+Zeichensätze definieren, die in den Server einkompiliert werden sollen.
+
+Hierbei ist @code{LIST} entweder eine Liste eines Zeichensatzes, die durch
+Leerzeichen getrennt ist, oder @code{complex}, um alle Zeichen
+einzuschließen, die nicht dynamisch geladen werden können, oder
+@code{all}, um alle Zeichensätze in die Binärdateien einzuschließen.
+
+@item
+Um MySQL mit Debug-Code zu konfigurieren, benutzen Sie die
+@code{--with-debug}-Option:
+@example
+shell> ./configure --with-debug
+@end example
+Das bewirkt, dass eine sichere Speicherzuweisung (Memory Allocator)
+eingeschlossen wird, die einige Fehler finden kann und die Ausgaben
+liefert, was passiert ist. @xref{Debugging server}.
+
+@item
+Wenn Ihre Client-Programme Threads benutzen, müssen Sie zusätzlich eine
+Thread-sichere Version der MySQL-Client-Bibliothek mit der
+@code{--enable-Thread-safe-client}-configure-Option kompilieren. Hierdurch
+wird eine @code{libmysqlclient_r}-Bibliothek angelegt, mit der Sie Ihre
+threaded Applikationen linken können. @xref{Threaded clients}.
+
+@item
+Optionen, die zu bestimmten Systemen gehören, finden sich im
+systemspezifischen Abschnitt dieses Handbuchs. @xref{Which OS, , Betriebssystemspezifische Anmerkungen}.
+@end itemize
+
+
+@node Installing source tree, Compilation problems, configure options, Installing source
+@c German node Installation vom Entwicklungs-Source-Tree
+@subsection Installation vom Entwicklungs-Source-Tree
+
+@cindex Entwicklungs-Source-Tree
+@cindex BitKeeper-Tree
+@cindex CVS-Tree
+
+@strong{VORSICHT:} Sie sollten diesen Abschnitt nur lesen, wenn Sie daran
+interessiert sind, uns beim Testen von neuem Code zu helfen. Wenn Sie nur
+wollen, dass MySQL auf Ihrem System läuft, sollten Sie eine
+Standard-Distribution wählen (entweder eine Quell- oder eine
+Binärdistribution).
+
+Um unseren aktuellsten Entwicklungs-Source-Tree zu bekommen, folgen Sie
+diesen Anweisungen:
+
+@enumerate
+@item
+Laden Sie @strong{BitKeeper} von
+@uref{http://www.bitmover.com/cgi-bin/download.cgi} herunter. Sie benötigen
+@strong{Bitkeeper} 2.0 oder neuer, um auf unser Repository zuzugreifen.
+
+@item
+Folgen Sie den Anweisungen, um BitKeeper zu installieren.
+
+@item
+Nachdem @strong{BitKeeper} installiert ist, benutzen Sie diesen Befehl, um
+den MySQL-3.23-Branch zu klonen:
+
+@example
+shell> bk clone bk://work.mysql.com:7000 mysql
+@end example
+
+Um den 4.0-Branch zu klonen, benutzen Sie statt dessen diesen Befehl:
+
+@example
+shell> bk clone bk://work.mysql.com:7001 mysql-4.0
+@end example
+
+Das erstmalige Herunterladen des Source-Trees kann eine Weile dauern,
+abhängig von Ihrer Verbindungsgeschwindigkeit. Bitte Geduld.
+
+@item
+Sie brauchen GNU @code{autoconf}, @code{automake}, @code{libtool} und
+@code{m4}, um die nächsten Befehle auszuführen.
+Wenn Sie in diesem Stadium seltsame Fehler erhalten, überprüfen Sie bitte,
+ob Sie wirklich @code{libtool} installiert haben!
+
+@example
+shell> cd mysql
+shell> bk -r edit
+shell> aclocal; autoheader; autoconf; automake;
+shell> ./configure # Geben Sie hier Ihre Lieblingsoptionen an
+shell> make
+@end example
+
+Eine Sammlung unserer Standard-configure-Skripts befindet sich im
+@file{BUILD/} Unterverzeichnis. Wenn Sie faul sind, können Sie
+@file{BUILD/compile-pentium-debug} benutzen. Um für unterschiedliche
+Architekturen zu kompilieren, ändern Sie das Skript ab und entfernen die
+Flags, die Pentium-spezifisch sind.
+
+@item
+Wenn der Build fertig ist, lassen Sie @code{make install} laufen. Seien Sie
+damit vorsichtig auf Produktionsmaschinen, denn dieser Befehl kann Ihre
+Live-Release-Installation überschreiben! Wenn Sie eine weitere Installation
+von MySQL haben, empfehlen wir, dass Sie @code{./configure} mit anderen
+Werten für die @code{prefix}-, @code{tcp-port}- und
+@code{unix-socket-path}-Optionen ausführen als die, die für Ihren
+Produktionsserver benutzt werden.
+
+@item
+Spielen Sie reichlich mit Ihrer neuen Installation herum und versuchen Sie,
+die neuen Features zum Absturz zu bringen. Fangen Sie an, indem Sie
+@code{make test} laufen lassen. @xref{MySQL-Test-Suite}.
+
+@item
+Wenn Sie bis zum @code{make}-Stadium gekommen sind und die Distribution
+sich nicht kompilieren läßt, berichten Sie das bitte an
+@email{bugs@@lists.mysql.com}. Wenn Sie die letzten Versionen der
+erforderlichen GNU-Werkzeuge installiert haben und sie abstürzen, wenn Sie
+versuchen, Ihre Konfigurationsdateien zu verarbeiten, berichten Sie das
+bitte ebenfalls. Wenn Sie jedoch @code{aclocal} und einen @code{Befehl
+nicht gefunden}-Fehler erhalten, berichten Sie diesen nicht. Stellen Sie
+statt dessen sicher, dass alle notwendigen Werkzeuge installiert sind und dass
+Ihre @code{PATH}-Variable korrekt gesetzt ist, damit Ihre Shell diese
+finden kann.
+
+@item
+Nach der erstmaligen @code{bk clone}-Operation, um den Source-Tree zu
+erhalten, sollten Sie in regelmäßigen Abständen @code{bk pull} laufen
+lassen, um Aktualisierungen zu erhalten.
+
+@item
+Sie erhalten die Änderungen-Geschichte (Change History) des Trees mit allen
+Diffs, indem Sie @code{bk sccstool} benutzen. Wenn Sie seltsame Diffs sehen
+oder Code, zu dem Sie Fragen haben, zögern Sie nicht, uns eine E-Mail an
+@email{internals@@lists.mysql.com} zu schicken. Auch wenn Sie meinen, eine
+bessere Idee zu haben, wie etwas gemacht werden sollte, schicken Sie uns
+eine E-Mail an dieselbe Adresse, mit einem Patch. @code{bk diffs} erzeugt
+ein Patch für Sie, nachdem Sie Änderungen am Quellcode durchgeführt haben.
+Wenn Sie keine Zeit haben, Ihre Idee zu kodieren, schicken Sie einfach eine
+Beschreibung.
+
+@item
+@strong{BitKeeper} hat ein nettes Hilfe-Dienstprogramm, auf das Sie über @code{bk
+helptool} zugreifen können.
+
+@end enumerate
+
+
+@node Compilation problems, MIT-pthreads, Installing source tree, Installing source
+@c German node Kompilierungsprobleme
+@subsection Probleme beim Kompilieren?
+
+@cindex Kompilieren, Probleme
+@cindex Probleme, Kompilieren
+@cindex Rekonfigurieren
+@cindex @code{config.cache}-Datei
+@cindex Dateien, @code{config.cache}
+
+Alle MySQL-Programme lassen sich sauber ohne Warnungen auf Solaris mit
+@code{gcc} kompilieren. Auf anderen Systemen können Warnungen wegen
+Unterschieden in System-Include-Dateien auftreten. Siehe @ref{MIT-pthreads}
+wegen Warnungen, die auftreten können, wenn Sie MIT-pThreads verwenden.
+Wegen anderer Probleme sehen Sie bitte in der unten stehenden Liste nach.
+
+Die Lösung für viele Probleme beinhaltet Rekonfigurieren. Wenn Sie
+rekonfigurieren müssen, beachten Sie Folgendes:
+
+@cindex @code{configure} nach dem ersten Aufruf laufen lassen
+@cindex @code{configure}, laufen lassen nach dem ersten Aufruf
+@cindex Rekonfigurieren
+@cindex config.cache
+@itemize @bullet
+@item
+Wenn @code{configure} laufen gelassen wird, nachdem es schon einmal lief,
+benutzt es möglicherweise Informationen, die bei vorherigen Aufrufen
+gesammelt wurden. Diese Information wird in der Datei @file{config.cache}
+gespeichert. Wenn @code{configure} startet, sucht es diese Datei und liest
+ihren Inhalt, wenn sie existiert, unter der Annahme, dass diese Information
+immer noch stimmt. Diese Annahme ist falsch, wenn Sie rekonfigurieren.
+
+@item
+Immer, wenn Sie @code{configure} laufen lassen, müssen Sie auch @code{make}
+laufen lassen, um erneut zu kompilieren. Sie werden jedoch einige alte
+Objektdateien vorheriger Builds entfernen wollen, denn diese wurden mit
+anderen Konfigurationsoptionen kompiliert.
+@end itemize
+
+Um zu verhindern, dass alte Konfigurationsinformationen oder Objektdateien
+benutzt werden, geben Sie vor dem erneuten Aufruf von @code{configure}
+folgende Befehle ein:
+
+@example
+shell> rm config.cache
+shell> make clean
+@end example
+
+Alternativ können Sie auch @code{make distclean} laufen lassen.
+
+Die unten stehende Liste beschreibt einige der Probleme, die beim
+Kompilieren von MySQL am häufigsten auftreten:
+
+@itemize @bullet
+@item
+@cindex @code{cc1plus}-Probleme
+@cindex @code{fatal signal 11}
+@cindex @code{sql_yacc.cc}-Probleme
+@cindex Interne Kompiler-Fehler
+@cindex Virtueller Speicher, Probleme beim Kompilieren
+@cindex configure-Option, --with-low-memory
+Wenn Sie Probleme beim Kompilieren von @file{sql_yacc.cc} erhalten, die den
+unten gezeigten ähneln, haben Sie wahrscheinlich keinen Arbeitsspeicher
+oder Swap-Platz (Auslagerungsdatei) mehr.
+
+@example
+Internal compiler error: Programm cc1plus got fatal signal 11
+ oder
+Out of virtual memory
+ oder
+Virtual memory exhausted
+@end example
+
+Das Problem liegt darin, dass @code{gcc} riesige Mengen von Arbeitsspeicher
+benötigt, um @file{sql_yacc.cc} mit Inline-Funktionen zu kompilieren.
+Versuchen Sie, @code{configure} mit der @code{--with-low-memory}-Option
+auszuführen:
+
+@example
+shell> ./configure --with-low-memory
+@end example
+
+Diese Option veranlasst, dass @code{-fno-inline} zur Kompilierzeile
+hinzugefügt wird, wenn Sie @code{gcc} benutzen, bzw. @code{-O0}, wenn Sie
+etwas anderes benutzen. Sie sollten die @code{--with-low-memory}-Option
+selbst dann benutzen, wenn Sie glauben, so viel Arbeitsspeicher und
+Swap-Platz zu haben, dass Ihnen diese unmöglich ausgehen können. Das
+Problem wurde selbst auf Systemen mit großzügiger Hardware-Ausstattung
+beobachtet, und die @code{--with-low-memory}-Option behebt es
+üblicherweise.
+
+@item
+Vorgabemäßig sucht @code{configure} @code{c++} als Kompiler-Namen aus und
+GNU @code{c++} linkt mit @code{-lg++}. Wenn Sie @code{gcc} benutzen, kann
+dieses Verhalten Probleme bei Konfigurationen wie dieser verursachen:
+
+@cindex C++-Kompiler kann keine ausführbaren Dateien (Executables) erzeugen
+@example
+configure: error: installation oder configuration problem:
+c++ compiler cannot create executables.
+@end example
+
+@tindex CXX-Umgebungsvariable
+@tindex Umgebungsvariable, CXX
+Eventuell stoßen Sie beim Kompilieren auch auf Probleme, die mit
+@code{g++}, @code{libg++} oder @code{libstdc++} zu tun haben.
+
+Eine Ursache dieser Probleme liegt darin, dass Sie kein @code{g++} haben
+dürfen, oder Sie dürfen @code{g++} haben, aber nicht @code{libg++} oder
+@code{libstdc++}. Schauen Sie in die @file{config.log}-Datei! Sie sollten
+die genaue Ursache enthalten, warum Ihr C++-Kompiler nicht funktioniert! Um
+dieses Problem zu umgehen, können Sie @code{gcc} als Ihren C++-Kompiler
+benutzen. Versuchen Sie, die Umgebungsvariable @code{CXX} auf @code{"gcc
+-O3"} zu setzen. Beispiel:
+
+@tindex CXX-Umgebungsvariable
+@tindex Umgebungsvariablen, CXX
+@example
+shell> CXX="gcc -O3" ./configure
+@end example
+
+Das funktioniert, weil @code{gcc} C++-Quellen genau so gut wie @code{g++}
+kompiliert, aber vorgabemäßig weder @code{libg++} noch @code{libstdc++}
+linkt.
+
+Eine andere Möglichkeit, das Problem zu beheben, besteht natürlich darin,
+@code{g++}, @code{libg++} und @code{libstdc++} zu installieren.
+
+@item
+Wenn Ihr Kompilieren mit Fehlern wie dem folgenden fehlschlägt, müssen Sie
+Ihre Version von @code{make} auf GNU @code{make} aktualisieren:
+
+@example
+making all in mit-pThreads
+make: Fatal error in reader: Makefile, line 18:
+Badly formed macro assignment
+ oder
+make:Datei `Makefile' line 18: Must be a separator (:
+ oder
+pThread.h: No such file or directory
+@end example
+
+@cindex Solaris-Troubleshooting
+@cindex FreeBSD-Troubleshooting
+@cindex Troubleshooting, Solaris
+@cindex Troubleshooting, FreeBSD
+Von Solaris und FreeBSD ist bekannt, dass sie problembehaftete
+@code{make}-Programme haben.
+
+GNU @code{make} Version 3.75 funktioniert bekanntermaßen.
+
+@tindex CC-Umgebungsvariable
+@tindex Umgebungsvariable, CC
+@tindex CXX-Umgebungsvariable
+@tindex Umgebungsvariable, CXX
+@tindex CFLAGS-Umgebungsvariable
+@tindex Umgebungsvariable, CFLAGS
+@tindex CXXFLAGS-Umgebungsvariable
+@tindex Umgebungsvariable, CXXFLAGS
+@item
+Wenn Sie Flags definieren wollen, die von Ihrem C- oder C++-Kompiler
+benutzt werden, fügen Sie die Flags den @code{CFLAGS}- und
+@code{CXXFLAGS}-Umgebungsvariablen hinzu. Sie können auf diese Weise auch
+die Kompilernamen festlegen, indem Sie @code{CC} und @code{CXX} benutzen.
+Beispiel:
+
+@example
+shell> CC=gcc
+shell> CFLAGS=-O3
+shell> CXX=gcc
+shell> CXXFLAGS=-O3
+shell> export CC CFLAGS CXX CXXFLAGS
+@end example
+
+Siehe @ref{MySQL binaries}: Eine Liste von Flag-Definitionen, die sich
+auf verschiedenen Systemen als nützlich erwiesen haben.
+
+@item
+Wenn Sie einen Fehler wie den folgenden erhalten, müssen Sie Ihren
+@code{gcc}-Kompiler aktualisieren:
+
+@example
+client/libmysql.c:273: parse error before `__attribute__'
+@end example
+
+@code{gcc} 2.8.1 funktioniert bekanntermaßen, aber wir empfehlen statt
+dessen @code{gcc} 2.95.2 oder @code{egcs} 1.0.3a.
+
+@item
+Wenn Sie Fehler wie die unten stehenden erhalten, wenn Sie @code{mysqld}
+kompilieren, hat @code{configure} den Typ des letzten Arguments für
+@code{accept()}, @code{getsockname()} oder @code{getpeername()} nicht
+korrekt erkannt:
+
+@example
+cxx: Error: mysqld.cc, line 645: In this statement, the referenced
+ type of the pointer value "&length" is "unsigned long", which
+ is not compatible with "int".
+new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
+@end example
+
+Um das zu beheben, editieren Sie die @file{config.h}-Datei (die von
+@code{configure} angelegt wird). Suchen Sie nach folgenden Zeilen:
+
+@example
+/* Define as the base type of the last arg to accept */
+#define SOCKET_SIZE_TYPE XXX
+@end example
+
+Ändern Sie @code{XXX} zu @code{size_t} oder @code{int}, abhängig von Ihrem
+Betriebssystem. (Beachten Sie, dass Sie das jedes Mal tun müssen, wenn Sie
+@code{configure} laufen lassen, weil @code{configure} die Datei
+@file{config.h} neu erzeugt.)
+
+@item
+Die @file{sql_yacc.cc}-Datei wird von @file{sql_yacc.yy} erzeugt.
+Normalerweise muss der Build-Prozess keine @file{sql_yacc.cc} erzeugen,
+weil MySQL schon mit einer fertig erzeugten Kopie daher kommt. Wenn Sie sie
+jedoch neu erzeugen müssen, könnten Sie folgenden Fehler erhalten:
+
+@example
+"sql_yacc.yy", line xxx fatal: default action causes potential...
+@end example
+
+Das ist ein Indiz dafür, dass Ihre Version von @code{yacc} fehlerhaft ist.
+Sie müssen statt dessen wahrscheinlich @code{bison} (die GNU-Version von
+@code{yacc}) installieren und benutzen.
+
+@item
+Wenn Sie @code{mysqld} oder einen MySQL-Client debuggen wollen, lassen Sie
+@code{configure} mit der @code{--with-debug}-Option laufen. Kompilieren Sie
+danach neu und linken Sie Ihre Clients mit der neuen Client-Bibliothek.
+@xref{Debugging client}.
+@end itemize
+
+@node MIT-pthreads, Windows source build, Compilation problems, Installing source
+@c German node MIT-pThreads
+@subsection Anmerkungen zu MIT-pThreads
+
+@cindex MIT-pThreads
+@cindex Thread-Unterstützung, nicht-native
+
+Dieser Abschnitt beschreibt einige der Themen im Zusammenhang mit MIT-pThreads.
+
+Beachten Sie, dass Sie auf Linux KEINE MIT-pThreads benutzen, sondern statt
+dessen LinuxThreads installieren sollten!
+@xref{Linux}.
+
+Wenn Ihr System keine native Thread-Unterstützung bietet, müssen Sie MySQL
+unter Verwendung des MIT-pThread-Pakets bauen. Das betrifft ältere
+FreeBSD-Systeme, SunOS 4.x, Solaris 2.4 und früher und einige andere.
+@xref{Which OS}.
+
+@itemize @bullet
+@item
+Auf den meisten Systemen können Sie die Benutzung von erzwingen, indem Sie
+@code{configure} mit der @code{--with-mit-Threads}-Option laufen lassen:
+
+@example
+shell> ./configure --with-mit-threads
+@end example
+
+Wenn Sie MIT-pThreads benutzen, wird das Bauen (Building) in ein
+Nicht-Quellcode-Verzeichnis nicht unterstützt, weil wir die Änderungen an
+diesem Code minimal halten wollen.
+
+@item
+Die Überprüfungen, die festlegen, ob MIT-pThreads benutzt werden sollten
+oder nicht, finden nur in dem Teil des Konfigurationsprozesses statt, der
+mit dem Server-Code zu tun hat. Wenn Sie die Distribution mit
+@code{--without-server} konfigurieren, um nicht den Client-Code zu bauen,
+wissen die Clients nicht, ob sie MIT-pThreads benutzen sollen oder nicht
+und werden vorgabemäßig Unix-Socket-Verbindungen benutzen. Weil
+Unix-Sockets unter MIT-pThreads nicht laufen, heißt das, dass Sie
+@code{-h} oder @code{--host} benutzen müssen, wenn Sie Client-Programme
+laufen lassen.
+
+@item
+Wenn MySQL so kompiliert wird, dass es MIT-pThreads benutzt, wird
+System-Sperren (System Locking) vorgabemäßig aus Performance-Gründen
+ausgeschaltet. Mit der @code{--use-locking}-Option können Sie dem Server
+mitteilen, System-Sperren zu benutzen.
+
+@item
+Manchmal schlägt der pThread-@code{bind()}-Befehl fehl und bindet nicht an
+ein Socket, ohne jede Fehlermeldung (zumindest auf Solaris). Als Ergebnis
+schlagen alle Verbindungen zum Server fehl. Beispiel:
+
+@example
+shell> mysqladmin version
+mysqladmin: connect to server at '' failed;
+error: 'Can't connect to mysql server on localhost (146)'
+@end example
+
+Die Lösung besteht darin, den @code{mysqld}-Server zu killen und neu zu
+starten. Uns ist das nur dann passiert, wenn wir den Server gezwungen
+haben, herunter zu fahren und sofort danach einen Neustart durchgeführt
+haben.
+
+@item
+Bei MIT-pThreads läßt sich der @code{sleep()}-Systemaufruf nicht mit
+@code{SIGINT} (break) unterbrechen. Das merken Sie nur, wenn Sie
+@code{mysqladmin --sleep} ausführen. Sie müssen dann warten, bis der
+@code{sleep()}-Aufruf beendet wurde, bevor die Unterbrechungsanforderung
+(Interrupt) bedient wird und der Prozess anhält.
+
+@item
+Wenn Sie linken, erhalten Sie möglicherweise Warnmeldungen wie diese
+(zumindest auf Solaris). Sie können sie ignorieren:
+
+@example
+ld: warning: symbol `_iob' hat differing sizes:
+ (file /my/local/pThreads/lib/libpThread.a(findfp.o) value=0x4;
+file /usr/lib/libc.so value=0x140);
+ /my/local/pThreads/lib/libpThread.a(findfp.o) definition taken
+ld: warning: symbol `__iob' hat differing sizes:
+ (file /my/local/pThreads/lib/libpThread.a(findfp.o) value=0x4;
+file /usr/lib/libc.so value=0x140);
+ /my/local/pThreads/lib/libpThread.a(findfp.o) definition taken
+@end example
+
+@item
+Einige weitere Warnungen können ebenfalls ignoriert werden:
+
+@example
+implicit declaration of function `int strtoll(...)'
+implicit declaration of function `int strtoul(...)'
+@end example
+
+@item
+Wir haben es bislang nicht geschafft, @code{readline} mit MIT-pThreads zum
+Laufen zu bringen. (Das wird zwar nicht benötigt, mag aber für einige
+interessant sein.)
+@end itemize
+
+@menu
+* Windows-Umgebung vorbereiten::
+@end menu
+
+@node Windows-Umgebung vorbereiten, , MIT-pthreads, MIT-pthreads
+@c German node <no English equivalent>
+@subsubsection Vorbereitung der Windows-Umgebung
+
+@node Windows source build, , MIT-pthreads, Installing source
+@c German node Windows-Quelldistribution
+@subsection Windows-Quelldistribution
+
+Sie benötigen folgendes:
+
+@itemize @bullet
+@item
+VC++-6.0-Kompiler (aktualisiert mit Service-Pack 4 oder 5 und dem
+Präprozessor-Paket). Das Präprozessor-Paket wird für den Makro-Assembler
+benötigt. Weitere Details finden Sie unter:
+@uref{http://msdn.microsoft.com/vstudio/sp/vs6sp5/faq.asp}.
+@item
+Die MySQL-Quelldistribution für Windows, die von
+@uref{http://www.mysql.com/downloads/} herunter geladen werden kann.
+@end itemize
+
+MySQL bauen
+
+@enumerate
+@item
+Erzeugen Sie ein Arbeitsverzeichnis (z. B. workdir).
+@item
+Entpacken Sie die Quelldistribution in dieses Verzeichnis.
+@item
+Starten Sie den VC++-6.0-Kompiler.
+@item
+Wählen Sie im @code{File}-Menü @code{Open Workspace}.
+@item
+Öffnen Sie den @file{mysql.dsw}-Workspace, den Sie im Arbeitsverzeichnis
+finden.
+@item
+Wählen Sie im @code{Build}-Menü das @code{Set Active Configuration}-
+Menü.
+@item
+Wählen Sie @code{mysqld - Win32 Debug} und klicken Sie auf OK.
+@item
+Drücken Sie @code{F7}, um mit dem Bauen des Debug-Servers, der
+Bibliotheken und einiger Client-Applikationen zu beginnen.
+@item
+Wenn das Kompilieren beendet ist, kopieren Sie die Bibliotheken und die
+ausführbaren Dateien in ein separates Verzeichnis.
+@item
+Kompilieren Sie die Release-Versionen, die Sie haben wollen, auf
+dieselbe Art.
+@item
+Erzeugen Sie das Verzeichnis für die MySQL-Dateien, z. B.
+@file{c:\mysql}.
+@item
+Kopieren Sie aus dem Arbeitsverzeichnis folgende Verzeichnisse in das
+c:\mysql-Verzeichnis:
+
+@itemize @bullet
+@item Data
+@item Docs
+@item Share
+@end itemize
+
+@item
+Erzeugen Sie das Verzeichnis @file{c:\mysql\bin} und kopieren Sie alle
+Server und Clients, die Sie vorher kompiliert haben, hinein.
+@item
+Wenn Sie wollen, können Sie auch das @file{lib}-Verzeichnis erzeugen und
+die vorher kompilierten Bibliotheken hinein kopieren.
+@item
+Führen Sie mit Visual Studio ein Clean durch.
+@end enumerate
+
+Konfigurieren und starten Sie den Server auf dieselbe Weise wie bei der
+Windows-Binärdistribution. @xref{Windows-Umgebung vorbereiten}.
+
+
+@node Post-installation, Upgrade, Installing source, Installing
+@c German node Nach der Installation
+@section Einstellungen und Tests nach der Installation
+
+@cindex Nach der Installation, Einstellungen und Tests
+@cindex Testen, nach der Installation
+@cindex Setup, nach der Installation
+
+
+Wenn Sie MySQL erst einmal installiert haben (aus einer Binär- oder einer
+Quelldistribution), müssen Sie die Berechtigungstabellen (Grant Tables)
+initialisieren, den Server starten und sicherstellen, dass der Server
+korrekt funktioniert. Eventuell wollen Sie auch einrichten, dass der Server
+automatisch gestartet und angehalten wird, wenn Ihr System startet oder
+herunter gefahren wird.
+
+Normalerweise installieren Sie die Berechtigungstabellen und starten den
+Server wie folgt:
+Bei der Installation einer Quelldistribution:
+@cindex Start, den Server
+@cindex Server, starten
+
+@example
+shell> ./scripts/mysql_install_db
+shell> cd mysql_installations_verzeichnis
+shell> ./bin/safe_mysqld --user=mysql &
+@end example
+
+Bei einer Binärdistribution (nicht RPM- oder pkg-Pakete) tun Sie folgendes:
+
+@example
+shell> cd mysql_installations_verzeichnis
+shell> ./bin/mysql_install_db
+shell> ./bin/safe_mysqld --user=mysql &
+@end example
+
+Das legt die @code{mysql}-Datenbank an, die alle Zugriffsrechte auf
+Datenbanken enthält, die @code{test}-Datenbank, die Sie benutzen können, um
+MySQL zu testen und zusätzlich Berechtigungseinträge für den Benutzer, der
+@code{mysql_install_db} ausführt sowie einen @code{root}-Benutzer (ohne
+Passworte!). Durch den letzten Befehl wird der @code{mysqld}-Server
+gestartet.
+
+@code{mysql_install_db} überschreibt keine alten Berechtigungstabellen,
+deshalb sollte es unter allen Umständen sicher sein. Wenn Sie die
+@code{test}-Datenbank nicht haben wollen, können Sie sie mit
+@code{mysqladmin -u root drop test} entfernen.
+
+Am einfachsten läßt sich das Durchtesten vom obersten Verzeichnis der
+MySQL-Distribution durchführen. Bei einer Binärdistribution ist das Ihr
+Installationsverzeichnis (üblicherweise etwas wie @file{/usr/local/mysql}).
+Bei einer Quelldistribution ist es das Hauptverzeichnis Ihres
+MySQL-Source-Trees.
+@cindex Testen, den Server
+
+
+In den unten dargestellten Befehlen dieses Abschnitts und der folgenden
+Unterabschnitte ist @code{BINDIR} der Pfad zu dem Speicherort, wo Programme
+wie @code{mysqladmin} und @code{safe_mysqld} installiert sind. Bei einer
+Binärdistribution ist das @file{bin}-Verzeichnis innerhalb der
+Distribution. Bei einer Quelldistribution ist @code{BINDIR} wahrscheinlich
+@file{/usr/local/bin}, es sei denn, Sie haben ein anderes
+Installationsverzeichnis als @file{/usr/local} angegeben, als Sie
+@code{configure} laufen ließen. @code{EXECDIR} ist der Speicherort, in dem
+der @code{mysqld}-Server installiert ist. Bei einer Binärdistribution ist
+das derselbe wie @code{BINDIR}. Bei einer Quelldistribution ist
+@code{EXECDIR} wahrscheinlich @file{/usr/local/libexec}.
+
+Das Durchtesten wird im Folgenden detailliert beschrieben.
+@cindex Testen, Installation
+
+@enumerate
+@item
+Falls notwendig, starten Sie den @code{mysqld}-Server und richten die
+anfänglichen MySQL-Berechtigungstabellen ein, die alle Zugriffsrechte
+enthalten, die festlegen, wie sich Benutzer mit dem Server verbinden
+dürfen. Das wird normalerweise mit dem @code{mysql_install_db}-Skript
+gemacht:
+
+@example
+shell> scripts/mysql_install_db
+@end example
+
+Typischerweise müssen Sie @code{mysql_install_db} nur laufen lassen, wenn
+Sie MySQL zum ersten Mal installieren. Wenn Sie eine existierende
+Installation aktualisieren (Update), können Sie deshalb diesen Schritt
+überspringen. (@code{mysql_install_db} ist jedoch ziemlich sicher und
+aktualisiert keine bereits existierenden Tabellen, daher können Sie im
+Zweifel immer @code{mysql_install_db} laufen lassen.)
+
+@code{mysql_install_db} erzeugt sechs Tabellen (@code{user}, @code{db},
+@code{host}, @code{tables_priv}, @code{columns_priv} und @code{func}) in
+der @code{mysql}-Datenbank. Eine Beschreibung der anfänglichen
+Zugriffsrechte wird in @ref{Privileges} festgelegt. Kurz gesagt
+erlauben diese Zugriffsrechte dem MySQL-Benutzer @code{root}, alles zu tun,
+und jedem, Datenbanken anzulegen oder zu benutzen, deren Name @code{'test'}
+ist oder mit @code{'test_'} beginnt.
+
+Wenn Sie die Zugriffsberechtigungstabellen (Grant Tables) nicht einrichten,
+wird folgender Fehler in der Logdatei erscheinen, wenn Sie den Server
+starten:
+
+@tindex host.frm, problems finding
+@example
+mysqld: Can't find file: 'host.frm'
+@end example
+
+Dasselbe kann auch bei einer MySQL-Binärdistribution passieren, wenn Sie
+MySQL nicht mit exakt @code{./bin/safe_mysqld} starten!
+@xref{safe_mysqld, , @code{safe_mysqld}}.
+
+Eventuell müssen Sie @code{mysql_install_db} als @code{root} laufen lassen.
+Wenn Sie wollen, können Sie jedoch den MySQL-Server als unprivilegierter
+(non-@code{root})-Benutzer laufen lassen, vorausgesetzt, dieser Benutzer
+darf Dateien im Datenbank-Verzeichnis lesen und schreiben. Anweisungen, wie
+Sie MySQL als unprivilegierter Benutzer laufen lassen können, finden Sie in
+@ref{Privilege changes, , Den MySQL-Benutzer ändern}.
+
+Wenn Sie Probleme mit @code{mysql_install_db} bekommen, sehen Sie bitte
+unter @ref{mysql_install_db, , @code{mysql_install_db}} nach.
+
+Es gibt eine Reihe von Alternativen zum Laufenlassen des
+@code{mysql_install_db}-Skripts, was mit der MySQL-Distribution
+mitgeliefert wird:
+
+@itemize @bullet
+@item
+Sie können @code{mysql_install_db} editieren, bevor Sie es laufen lassen,
+um die anfänglichen Zugriffsrechte zu ändern, die in die Rechtetabellen
+installiert werden. Das ist nützlich, wenn Sie MySQL auf einer großen Zahl
+von Maschinen mit denselben Zugriffsrechten installieren wollen. In diesem
+Fall müssen Sie wahrscheinlich nur ein paar zusätzliche
+@code{INSERT}-Statements für die @code{mysql.user}- und
+@code{mysql.db}-Tabellen hinzufügen!
+
+@item
+Wenn Sie Dinge in den Berechtigungstabellen ändern wollen, nachdem diese
+installiert wurden, lassen Sie @code{mysql_install_db} laufen und geben
+dann den Befehl @code{mysql -u root mysql} ein, um sich als
+MySQL-@code{root}-Benutzer mit den Berechtigungstabellen zu verbinden.
+Danach können Sie SQL-Statements eingeben, um die Tabellen direkt zu
+verändern.
+
+@item
+Es ist möglich, die Berechtigungstabellen komplett neu zu erzeugen, nachdem
+Sie angelegt wurden. Das werden Sie zum Beispiel tun wollen, wenn Sie die
+Tabellen bereits angelegt haben, Sie nun aber neu anlegen wollen, weil Sie
+@code{mysql_install_db} editiert haben.
+@end itemize
+
+Zu weiteren Informationen über diese Alternativen siehe
+@ref{Privilege system}.
+
+@item
+Starten Sie den MySQL-Server wie folgt:
+
+@example
+shell> cd mysql_installations_verzeichnis
+shell> bin/safe_mysqld &
+@end example
+
+Wenn Sie Probleme haben, den Server zu starten, sehen Sie unter
+@ref{Starting server} nach.
+
+@item
+Benutzen Sie @code{mysqladmin}, um sicherzustellen, dass der Server läuft.
+Die folgenden Befehle sind ein einfacher Test, um zu überprüfen, ob der
+Server läuft und auf Verbindungen reagiert:
+
+@example
+shell> BINDIR/mysqladmin version
+shell> BINDIR/mysqladmin variables
+@end example
+
+Die Ausgabe von @code{mysqladmin version} kann geringfügig variieren,
+abhängig von Ihrer Plattform und der Version von MySQL, sollte aber etwa
+wie folgt aussehen:
+
+@example
+shell> BINDIR/mysqladmin version
+mysqladmin Ver 8.14 Distrib 3.23.32, for linux on i586
+Copyright (C) 2000 MySQL AB & MySQL Finnland AB & TCX DataKonsult AB
+This software comes mit ABSOLUTELY NO WARRANTY. This ist free software,
+und you are welcome to modify und redistribute it under the GPL license
+
+Server version 3.23.32-debug
+Protokoll version 10
+Connection Localhost via Unix socket
+TCP port 3306
+UNIX socket /tmp/mysql.sock
+Uptime: 16 sec
+
+Threads: 1 Questions: 9 Slow queries: 0 Opens: 7 Flush tables: 2 Open tables: 0 Queries per second avg: 0.000 Memory in use: 132K Max memory used: 16773K
+@end example
+
+Um ein Gefühl dafür zu bekommen, was Sie sonst noch mit
+@code{BINDIR/mysqladmin} tun können, rufen Sie es mit der
+@code{--help}-Option auf.
+
+@item
+Stellen Sie sicher, dass Sie den Server herunter fahren können:
+@cindex Server, Herunterfahren
+@cindex Herunterfahren, den Server
+
+@example
+shell> BINDIR/mysqladmin -u root shutdown
+@end example
+
+@item
+Stellen Sie sicher, dass Sie den Server erneut starten können. Tun Sie das
+unter Benutzung von @code{safe_mysqld} oder indem Sie @code{mysqld} direkt
+aufrufen. Beispiel:
+
+@cindex Server, neu starten
+@cindex Neustart, des Servers
+
+@example
+shell> BINDIR/safe_mysqld --log &
+@end example
+
+Wenn @code{safe_mysqld} fehlschlägt, versuchen Sie, es vom
+MySQL-Installationsverzeichnis aus zu starten (falls Sie noch nicht dort
+sind). Wenn das nicht funktioniert, sehen Sie unter see @ref{Starting server} nach.
+
+@item
+Lassen Sie ein paar einfache Tests ablaufen um sicherzustellen, dass der
+Server funktioniert. Die Ausgabe sollte ähnlich der folgenden sein:
+
+@example
+shell> BINDIR/mysqlshow
++-----------+
+| Databases |
++-----------+
+| mysql |
++-----------+
+
+shell> BINDIR/mysqlshow mysql
+Datenbank: mysql
++--------------+
+| Tables |
++--------------+
+| columns_priv |
+| db |
+| func |
+| host |
+| tables_priv |
+| user |
++--------------+
+
+shell> BINDIR/mysql -e "select host,db,user from db" mysql
++------+--------+------+
+| host | db | user |
++------+--------+------+
+| % | test | |
+| % | test_% | |
++------+--------+------+
+@end example
+
+Zusätzlich gibt es eine Benchmark-Suite im @file{sql-bench}-Verzeichnis
+(unterhalb des MySQL-Installationsverzeichnisses), die Sie benutzen können,
+um die Leistungsdaten von MySQL auf verschiedenen Plattformen zu
+vergleichen. Das @file{sql-bench/Results}-Verzeichnis enthält die
+Ergebnisse vieler Testläufe mit verschiedenen Datenbanken und Plattformen.
+Um alle Tests durchzuführen, geben Sie folgende Befehle ein:
+
+@example
+shell> cd sql-bench
+shell> run-all-tests
+@end example
+
+Wenn Sie kein @file{sql-bench}-Verzeichnis haben, benutzen Sie
+wahrscheinlich ein RPM für eine Binärdistribution. (Quelldistributions-RPMs
+beinhalten das Benchmark-Verzeichnis.) In diesem Fall müssen Sie die
+Benchmark-Suite zuerst installieren, bevor Sie sie benutzen können. Ab
+MySQL Version 3.22 gibt es Benchmark-RPM-Dateien, die
+@file{mysql-bench-VERSION-i386.rpm} benannt sind, die Benchmark-Code und
+Daten enthalten.
+
+Wenn Sie eine Quelldistribution haben, können Sie auch die Tests im
+@file{tests}-Unterverzeichnis ausführen. Um beispielsweise
+@file{auto_increment.tst} auszuführen, geben Sie folgendes ein:
+
+@example
+shell> BINDIR/mysql -vvf test < ./tests/auto_increment.tst
+@end example
+
+Die Ergebnisse stehen dann in der @file{./tests/auto_increment.res}-Datei.
+@end enumerate
+
+
+@menu
+* mysql_install_db::
+* Starting server::
+* Automatic start::
+@end menu
+
+@node mysql_install_db, Starting server, Post-installation, Post-installation
+@c German node mysql_install_db
+@subsection Probleme mit @code{mysql_install_db}
+@cindex @code{mysql_install_db}-Skript
+@cindex Skripte, @code{mysql_install_db}
+
+Der Zweck des @code{mysql_install_db}-Skripts ist, neue
+MySQL-Berechtigungstabellen zu erzeugen. Es betrifft keine anderen Daten!
+Es tut nichts, wenn Sie bereits MySQL-Berechtigungstabellen installiert
+haben!
+
+Wenn Sie Ihre Berechtigungstabellen neu erzeugen wollen, sollten Sie den
+@code{mysqld}-Server herunter fahren, falls er läuft, und dann etwas
+Ähnliches wie folgendes tun:
+
+@example
+mv mysql-data-verzeichnis/mysql mysql-data-verzeichnis/mysql-old
+mysql_install_db
+@end example
+
+Dieser Abschnitt listet Probleme auf, denen Sie vielleicht begegnen, wenn
+Sie @code{mysql_install_db} laufen lassen:
+
+@table @strong
+@item @code{mysql_install_db} installiert die Berechtigungstabellen nicht.
+
+Eventuell stellen Sie fest, dass @code{mysql_install_db} bei der
+Installations der Berechtigungstabellen fehlschlägt und mit folgenden
+Meldungen endet:
+
+@example
+starting mysqld daemon with databases from XXXXXX
+mysql daemon ended
+@end example
+
+In diesem Fall sollten Sie einen gründlichen Blick in die Log-Datei werfen!
+Diese sollte sich im Verzeichnis @file{XXXXXX} befinden, das in der
+Fehlermeldung ausgegeben wird, und sollte anzeigen, warum @code{mysqld}
+nicht startete. Wenn Sie nicht verstehen, was passiert ist, schicken Sie
+einen Bug-Bericht inklusive Log. Benutzen Sie hierfür @code{mysqlbug}!
+@xref{Bug reports}.
+
+@item Es läuft bereits ein @code{mysqld}-Daemon.
+
+In diesem Fall müssen Sie wahrscheinlich @code{mysql_install_db} überhaupt
+nicht starten. Sie müssen @code{mysql_install_db} nur einmal starten, und
+zwar, wenn Sie MySQL zum ersten Mal installieren.
+
+@item Die Installation eines zweiten @code{mysqld}-Daemons schlägt fehl,
+wenn bereits ein Daemon läuft.
+
+Das kann vorkommen, wenn Sie bereits eine existierende MySQL-Installation
+haben, aber eine neue Installation an einem anderen Speicherort
+unterbringen wollen (zum Beispiel für Testzwecke, oder vielleicht wollen
+Sie auch einfach zwei Installationen zugleich laufen lassen. Im Allgemeinen
+ist der Grund für das Problem, wenn Sie versuchen, den zweiten Server
+laufen zu lassen, dass der zweite Server versucht, denselben Socket und
+Port wie der alte zu benutzen. In diesem Fall erhalten Sie als
+Fehlermeldung: @code{Can't start server: Bind on TCP/IP port: Address
+already in use} oder @code{Can't start server : Bind on unix socket...}.
+@xref{Multiple servers}.
+
+@item Sie haben keinen Schreibzugriff auf @file{/tmp}.
+@cindex Schreibzugriff, tmp
+@cindex Temporäre Datei, Schreibzugriff
+@cindex Dateien, @code{tmp}
+
+Wenn Sie keinen Schreibzugriff haben, um eine Socket-Datei am
+vorgabemäßigen Ort anzulegen (in @file{/tmp}) oder keine Berechtigung, um
+temporäre Dateien in @file{/tmp} anzulegen, erhalten Sie einen Fehler, wenn
+Sie @code{mysql_install_db} laufen lassen oder starten oder wenn Sie
+@code{mysqld} benutzen.
+
+So können Sie einen anderen Socket und ein anderes temporäres Verzeichnis
+festlegen:
+
+@tindex TMPDIR Umgebungsvariable
+@tindex MYSQL_UNIX_PORT Umgebungsvariable
+@tindex Umgebungsvariable, TMPDIR
+@tindex Umgebungsvariable, MYSQL_UNIX_PORT
+@example
+shell> TMPDIR=/irgendein_temporaeres_verzeichnis/
+shell> MYSQL_UNIX_PORT=/irgendein_temporaeres_verzeichnis/mysqld.sock
+shell> export TMPDIR MYSQL_UNIX_PORT
+@end example
+
+@xref{Problems with mysql.sock}.
+
+@file{irgendein_temporaeres_verzeichnis} sollte der Pfad zu einem
+Verzeichnis sein, für das Sie Schreibberechtigung haben.
+@xref{Environment variables}.
+
+Danach sollten Sie in der Lage sein, @code{mysql_install_db} laufen zu
+lassen und den Server zu starten, und zwar mit folgenden Befehlen:
+
+@example
+shell> scripts/mysql_install_db
+shell> BINDIR/safe_mysqld &
+@end example
+
+@item @code{mysqld} stürzt sofort ab
+
+Wenn Sie RedHat Version 5.0 mit einer Version von @code{glibc} laufen
+lassen, die älter als 2.0.7-5 ist, sollten Sie sicherstellen, dass Sie alle
+@code{glibc}-Patches installiert haben!
+Darüber gibt es jede Menge Informationen in den MySQL-Mail-Archiven. Links
+zu den Mail-Archiven finden Sie online unter
+@uref{http://www.mysql.com/documentation/}.
+Siehe auch @ref{Linux}.
+
+Sie können @code{mysqld} auch manuell starten, dabei die
+@code{--skip-grant-tables}-Option benutzen und dann die
+Berechtigungsinformationen selbst mit @code{mysql} eintragen:
+
+@example
+shell> BINDIR/safe_mysqld --skip-grant-tables &
+shell> BINDIR/mysql -u root mysql
+@end example
+
+Von @code{mysql} aus geben Sie die SQL-Befehle ein, die in
+@code{mysql_install_db} stehen. Stellen Sie sicher, dass Sie danach
+@code{mysqladmin flush-privileges} oder @code{mysqladmin reload} laufen
+lassen, um dem Server mitzuteilen, die Berechtigungstabellen neu zu laden.
+@end table
+
+
+@node Starting server, Automatic start, mysql_install_db, Post-installation
+@c German node Server starten
+@subsection Probleme mit dem Start des MySQL-Servers
+@cindex Server, Startprobleme
+@cindex Probleme, beim Starten des Servers
+
+Wenn Sie Tabellen einsetzen werden, die Transaktionen unterstützen (InnoDB,
+BDB), sollten Sie zuerst eine my.cnf-Datei anlegen und die
+Startoptionen für die Tabellentypen setzen, die Sie einsetzen wollen.
+@xref{Table types}.
+
+Im allgemeinen starten Sie den @code{mysqld}-Server auf eine der drei
+folgenden Weisen:
+
+@itemize @bullet
+@item
+Indem Sie @code{mysql.server} aufrufen. Dieses Skript wird hauptsächlich
+beim Systemstart und -herunterfahren eingesetzt. Es wird ausführlicher in
+@ref{Automatic start} beschrieben.
+
+@item
+Indem Sie @code{safe_mysqld} aufrufen. Dieses Skript versucht die korrekten
+Optionen für @code{mysqld} festzustellen und läßt den Server dann mit
+diesen Optionen laufen. @xref{safe_mysqld, ,@code{safe_mysqld}}.
+
+@item
+Auf Windows NT sollten Sie @code{mysqld} wie folgt als Systemdienst
+starten:
+@example
+bin\mysqld-nt --install # MySQL als Systemdienst installieren
+@end example
+
+Jetzt können Sie @code{mysqld} wie folgt starten / anhalten:
+@example
+NET START mysql
+NET STOP mysql
+@end example
+
+Beachten Sie, dass Sie in diesem Fall keine weiteren Optionen für
+@code{mysqld} benutzen können!
+
+Sie können den Systemdienst wie folgt entfernen:
+@example
+bin\mysqld-nt --remove # MySQL als Systemdienst entfernen
+@end example
+
+@item
+Indem Sie @code{mysqld} direkt aufrufen.
+@end itemize
+
+Wenn der @code{mysqld}-Daemon hoch fährt, wechselt er in das
+Daten-Verzeichnis. Dort erwartet er, Log-Dateien und die (process ID)-Datei
+schreiben zu können. Ebenfalls erwartet er dort, Datenbanken zu finden.
+
+Der Speicherort des Daten-Verzeichnisses wird zum Zeitpunkt des Kompilierens
+der Distribution fest verdrahtet. Wenn @code{mysqld} jedoch erwartet, das
+Daten-Verzeichnis irgendwo sonst als an der Stelle zu finden, wo es auf
+Ihrem System tatsächlich ist, funktioniert er nicht richtig. Wenn Sie
+Probleme mit fehlerhaften Pfaden haben, können Sie durch den Aufruf von
+@code{mysqld} mit der @code{--help}-Option herausfinden, welche Optionen
+@code{mysqld} erlaubt und was die vorgabemäßigen Pfad-Einstellung sind.
+Sie können die Vorgaben überschreiben, indem Sie die korrekten Pfadnamen
+als Kommandozeilen-Argumente für @code{mysqld} festlegen. (Diese Optionen
+können auch bei @code{safe_mysqld} benutzt werden.)
+
+Normalerweise sollte es lediglich nötig sein, @code{mysqld} das
+Basis-Verzeichnis mitzuteilen, wo MySQL installiert ist. Das können Sie mit
+der Option @code{--basedir} machen. Zusätzlich können Sie @code{--help}
+benutzen, um die Auswirkung der Pfadänderungsoptionen zu überprüfen
+(beachten Sie, dass @code{--help} die letzte Option des
+@code{mysqld}-Befehls wein @emph{muss}. Beispiel:
+
+@example
+shell> EXECDIR/mysqld --basedir=/usr/local --help
+@end example
+
+Wenn Sie die Pfadeinstellungen erst einmal festgelegt haben, die Sie
+wollen, starten Sie den Server ohne die @code{--help}-Option.
+
+Mit welcher Methode auch immer Sie den Server starten: Wenn er nicht
+korrekt hoch fährt, untersuchen Sie die Log-Datei, um zu sehen, ob Sie den
+Grund dafür herausfinden können. Log-Dateien liegen im Daten-Verzeichnis
+(typischerweise @file{/usr/local/mysql/data} bei einer Binärdistribution,
+@file{/usr/local/var} bei einer Quelldistribution und
+@file{\mysql\data\mysql.err} unter Windows). Suchen Sie im Daten-Verzeichnis
+nach Dateien mit Namen der Form @file{host_name.err} und
+@file{host_name.log}, wobei @code{host_name} der Name Ihres Server-Hosts
+ist. Sehen Sie in den letzten paar Zeilen dieser Dateien nach:
+
+@example
+shell> tail host_name.err
+shell> tail host_name.log
+@end example
+
+Wenn Sie etwas wie das Folgende in der Log-Datei finden:
+@example
+000729 14:50:10 bdb: Recovery function for LSN 1 27595 failed
+000729 14:50:10 bdb: warning: ./test/t1.db: No such file or directory
+000729 14:50:10 Can't init databases
+@end example
+
+Das bedeutet, dass Sie @code{mysqld} nicht mit @code{--bdb-no-recover}
+gestartet haben und Berkeley DB findet, dass etwas mit seinen Log-Dateien
+nicht in Ordnung ist, als es versuchte, Ihre Datenbanken
+wiederherzustellen. Um weitermachen zu können, sollten Sie alle alten
+Berkeley-DB-Log-Dateien aus dem Datenbankverzeichnis an eine andere Stelle
+verschieben, wo Sie sie später untersuchen können. Die Log-Dateien sind wie
+@file{log.0000000001} benannt, wobei die Nummer im Zeitablauf hochgezählt
+wird.
+
+Wenn Sie @code{mysqld} mit BDB-Tabellenunterstützung laufen lassen und
+@code{mysqld} beim Start einen Speicherauszug (Core Dump) liefert, könnte
+das an Problemen mit den BDB-Wiederherstellungs-Logs liegen. In diesem Fall
+können Sie versuchen, @code{mysqld} mit @code{--bdb-no-recover} zu starten.
+Wenn das hilft, sollten Sie danach alle @file{log.*}-Dateien aus dem
+Daten-Verzeichnis entfernen und versuchen, @code{mysqld} erneut zu starten.
+
+Wenn Sie folgenden Fehler bekommen, bedeutet das, dass ein anderes Programm
+(oder ein anderer @code{mysqld}-Server) bereits den TCP/IP-Port oder
+-Socket benutzt, den @code{mysqld} versucht zu benutzen:
+
+@example
+Can't start server: Bind on TCP/IP-Port: Address already in use
+ oder
+Can't start server : Bind on unix socket...
+@end example
+
+Benutzen Sie @code{ps}, um sicherzustellen, dass kein weiterer
+@code{mysqld}-Server läuft. Wenn Sie keinen weiteren Server finden, können
+Sie den Befehl @code{telnet ihr-host-name tcp-ip-port-nummer} eingeben und
+mehrere Male @code{EINGABE} drücken. Wenn Sie keine Fehlermeldung wie
+@code{telnet: Unable to connect to remote host: Connection refused}
+erhalten, benutzt irgend etwas anderes den TCP/IP-Port, den @code{mysqld}
+versucht zu benutzen. Siehe @ref{mysql_install_db} und @ref{Multiple servers}.
+
+Wenn @code{mysqld} gerade läuft, können Sie herausfinden, welche
+Pfadeinstellungen er benutzt, indem Sie folgenden Befehl ausführen:
+
+@example
+shell> mysqladmin variables
+@end example
+
+oder
+
+@example
+shell> mysqladmin -h 'ihr-host-name' variables
+@end example
+
+Wenn @code{safe_mysqld} hoch den Server hoch fährt, Sie sich aber nicht mit
+ihm verbinden können, stellen Sie sicher, dass Sie einen Eintrag wie den
+folgenden in @file{/etc/hosts} haben:
+
+@example
+127.0.0.1 localhost
+@end example
+
+Dieses Problem tritt nur auf Systemen auf, die keine funktionierende
+Thread-Bibliothek besitzen, und für die MySQL so konfiguriert werden muss,
+dass es MIT-pThreads benutzt.
+
+Wenn Sie es nicht schaffen, @code{mysqld} zu starten, können Sie versuchen,
+eine Trace-Datei anzulegen, um das Problem zu finden. @xref{Making trace files}.
+
+Wenn Sie InnoDB-Tabellen benutzen, sehen Sie bei den InnoDB-spezifischen
+Startoptionen nach. @xref{InnoDB start}.
+
+Wenn Sie BDB-(Berkeley DB)-Tabellen benutzen, sollten Sie sich mit den
+verschiedenen Startoptionen von BDB vertraut machen. @xref{BDB start}.
+
+
+@node Automatic start, , Starting server, Post-installation
+@c German node Automatischer Start
+@subsection MySQL automatisch starten und anhalten
+
+@cindex Start, Server automatisch starten
+@cindex Anhalten, den Server
+@cindex Server, starten und anhalten
+
+Die @code{mysql.server}- und @code{safe_mysqld}-Skripte können benutzt
+werden, um den Server automatisch beim Hochfahren des Systems zu starten.
+@code{mysql.server} kann ebenfalls dazu benutzt werden, den Server
+anzuhalten.
+
+Das @code{mysql.server}-Skript kann benutzt werden, um den Server zu
+starten oder anzuhalten, indem man es mit den @code{start}- oder
+@code{stop}-Argumenten aufruft:
+
+@example
+shell> mysql.server start
+shell> mysql.server stop
+@end example
+
+@code{mysql.server} liegt im @file{share/mysql}-Verzeichnis unterhalb des
+MySQL-Installationsverzeichnisses oder im @file{support-files}-Verzeichnis
+des MySQL-Source-Trees.
+
+Bevor @code{mysql.server} den Server startet, wechselt es in das
+MySQL-Installationsverzeichnis. Dann ruft es @code{safe_mysqld} auf.
+Eventuell müssen Sie @code{mysql.server} editieren, wenn Sie eine
+Binärdistribution haben, die Sie an eine nicht stardardmäßige Stelle
+installiert haben. Ändern Sie es so ab, dass es in das richtige Verzeichnis
+wechselt (@code{cd}), bevor es @code{safe_mysqld} startet. Wenn Sie wollen,
+dass der Server unter einem bestimmten Benutzer läuft, fügen Sie eine
+entsprechende @code{user}-Zeile zur @file{/etc/my.cnf}-Datei hinzu, so wie
+weiter unten in diesem Abschnitt dargestellt.
+
+@code{mysql.server stop} hält den Server an, indem es ihm ein Signal
+sendet. Sie können den Server auch automatisch herunter fahren, indem Sie
+@code{mysqladmin shutdown} ausführen.
+
+Wenn Sie möchten, können Sie diese Start- und Stop-Befehle an den
+entsprechenden Stellen Ihrer @file{/etc/rc*}-Dateien einfügen, wenn Sie
+MySQL für Produktions-Applikationen benutzen. Beachten Sie, wenn Sie
+@code{mysql.server} editieren und dann gelegentlich MySQL aktualisieren
+(Update), dass dann Ihre geänderte Version überschrieben wird. Daher
+sollten Sie eine Kopie Ihrer editierten Version machen, die Sie erneut
+installieren können.
+
+Wenn Ihr System @file{/etc/rc.local} benutzt, um externe Skripte zu
+starten, sollten Sie folgendes anhängen:
+@example
+/bin/sh -c 'cd /usr/local/mysql ; ./bin/safe_mysqld --user=mysql &'
+@end example
+
+@cindex Den Speicherort des Sockets ändern
+Sie können Optionen für @code{mysql.server} in einer globalen
+@file{/etc/my.cnf}-Datei hinzufügen. Eine typische @file{/etc/my.cnf}-Datei
+sieht wie folgt aus:
+
+@example
+[mysqld]
+datadir=/usr/local/mysql/var
+socket=/var/tmp/mysql.sock
+port=3306
+user=mysql
+
+[mysql.server]
+basedir=/usr/local/mysql
+@end example
+
+Das @code{mysql.server}-Skript kennt folgende Optionen:
+@code{datadir}, @code{basedir} und @code{pid-file}.
+
+Folgende Tabelle zeigt, welche Optionsgruppen jedes der Startskripts aus
+den Optionsdateien liest:
+
+@multitable @columnfractions .20 .80
+@item @strong{Skript} @tab @strong{Optionsgruppen}
+@item @code{mysqld} @tab @code{mysqld} und @code{server}
+@item @code{mysql.server} @tab @code{mysql.server}, @code{mysqld}, und @code{server}
+@item @code{safe_mysqld} @tab @code{mysql.server}, @code{mysqld}, und @code{server}
+@end multitable
+
+@xref{Option files}.
+
+
+@node Upgrade, Operating System Specific Notes, Post-installation, Installing
+@c German node Upgrade
+@section MySQL aktualisieren (Upgrade / Downgrade)
+
+@cindex Upgrade
+@cindex Downgrade
+
+Sie können die MySQL-form- und data-Dateien jederzeit für verschiedene
+Versionen auf derselben Architektur benutzen, solange Sie dieselbe
+Grundversion von MySQL haben. Die aktuelle Grundversion ist 3. Wenn Sie den
+Zeichensatz ändern, während MySQL läuft (was auch die Sortierreihenfolge
+betreffen kann), müssen Sie @code{myisamchk -r -q} auf alle Tabellen
+ausführen. Ansonsten könnte es sein, dass Ihre Indexe nicht korrekt
+sortiert werden.
+
+Wenn Sie vor neuen Versionen zurück schrecken, können Sie Ihren alten
+@code{mysqld} zu etwas wie @code{mysqld}-'alte-versions-nummer' umbenennen.
+Wenn Ihr neuer @code{mysqld} dann etwas Unerwartetes tut, können Sie ihn
+einfach anhalten und mit Ihrem alten @code{mysqld} neu starten!
+
+Wenn Sie ein Upgrade vornehmen, sollte Sie natürlich Ihre alten Datenbanken
+sichern.
+
+Wenn Sie nach einem Upgrade auf Probleme mit neu kompilierten
+Client-Programmen stoßen, zum Beispiel @code{Commands out of sync} oder
+unerwartete Speicherauszüge (Core Dumps), haben sie wahrscheinlich einen
+alten Header oder eine alte Bibliotheksdatei benutzt, als Sie die Programme
+kompilierten. In diesem Fall sollten Sie das Datum Ihrer
+@file{mysql.h}-Datei und @file{libmysqlclient.a}-Bibliothek überprüfen, um
+sicherzustellen, dass sie aus der neuen MySQL-Distribution stammten. Wenn
+nicht, kompilieren sie Ihre Programme bitte neu!
+
+Wenn Sie Probleme der Art erhalten, dass Ihr neuer @code{mysqld}-Server
+nicht startet oder dass Sie sich nicht ohne Passwort verbinden können,
+überprüfen Sie, ob Sie nicht etwa noch die alte @file{my.cnf}-Datei Ihrer
+alten Installation haben! Sie können das mit @code{program-name
+--print-defaults} tun. Wenn es irgend etwas anderes als den Programmnamen
+ausgibt, haben Sie eine aktive @code{my.cnf}-Datei, die sich auf die Dinge
+auswirkt!
+
+Es ist eine gute Idee, die @code{Msql-Mysql-modules}-Distribution neu zu
+bauen und neu zu installieren, wann immer Sie ein neues Release von MySQL
+installieren, speziell dann, wenn Sie Symptome wie die bemerken, dass alle
+Ihre @code{DBI}-Skripte mit Core-Dumps abbrechen, nachdem Sie MySQL
+aktualisiert haben.
+
+
+@cindex Kompatibilität, zwischen MySQL-Versionen
+@cindex Upgrade, 3.23 auf 4.0
+@menu
+* Upgrading-from-3.23::
+* Upgrading-from-3.22::
+* Upgrading-from-3.21::
+* Upgrading-from-3.20::
+* Upgrading-to-arch::
+@end menu
+
+@node Upgrading-from-3.23, Upgrading-from-3.22, Upgrade, Upgrade
+@c German node Upgrading-from-3.23
+@subsection Upgrade von 3.23 auf Version 4.0
+
+Sie können Ihre alten data-Dateien ohne jede Änderung mit Version 4.0
+benutzen. Wenn Sie Ihre Daten eines MySQL-4.0-Servers für einen älteren
+Server verwenden wollen, müssen Sie @code{mysqldump} benutzen.
+
+Alte Clients sollen mit einem Server Version 4.0 ohne jedes Problem
+funktionieren.
+
+Die folgende Liste stellt dar, auf was Sie aufpassen müssen, wenn Sie auf
+Version 4.0 aktualisieren (Upgrade):
+
+@itemize @bullet
+@item
+@file{safe_mysqld} wurde zu @file{mysqld_safe} umbenannt.
+@item
+Die alten C-API-Funktionen @code{mysql_drop_db}, @code{mysql_create_db} und
+@code{mysql_connect} werden nicht mehr unterstützt, es sei denn, MySQL wird
+mit @code{USE_OLD_FUNCTIONS} kompiliert.
+@item
+Sie sollten @code{TRUNCATE TABLE} benutzen, wenn Sie alle Zeilen aus einer
+Tabelle löschen wollen und Ihnen egal ist, wie viele Zeilen gelöscht
+wurden. (@code{TRUNCATE TABLE} ist schneller als @code{DELETE FROM tabelle}).
+@item
+Sie bekommen einen Fehler, wenn Sie ein aktives @code{LOCK TABLES} oder
+eine aktive Transaktion am Laufen haben, wenn Sie versuchen, @code{TRUNCATE
+TABLE} oder @code{DROP DATABASE} auszuführen.
+@item
+Sie sollten Ganzzahl-(Integer)-Werte in BIGINT-Spalten benutzen (anstelle
+von Zeichenketten wie in MySQL 3.23). Man kann immer noch Zeichenketten
+benutzen, aber die Benutzung von Ganzzahlen ist viel effizienter.
+@item
+Das Format von @code{SHOW OPEN TABLE} hat sich geändert.
+@item
+Multithreaded Clients sollten @code{mysql_thread_init()} und
+@code{mysql_thread_end()} benutzen. @xref{Threaded clients}.
+@end itemize
+@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade
+@c German node Upgrading-from-3.22
+@subsection Upgrade von einer Version 3.22 auf 3.23
+
+@cindex Kompatibilität, zwischen MySQL-Versionen
+@cindex Upgrade, 3.22 to 3.23
+
+MySQL-Version 3.23 unterstützt Tabellen des neuen @code{MyISAM}-Typs und
+des alten @code{ISAM}-Typs. Sie müssen Ihre alten Tabellen nicht
+konvertieren, um sie mit Version 3.23 einsetzen zu können. Vorgabemäßig
+werden alle neuen Tabellen mit dem Typ @code{MyISAM} angelegt (es sei denn,
+Sie starten @code{mysqld} mit der @code{--default-table-type=isam}-Option).
+Sie können eine @code{ISAM}-Tabelle zu einer @code{MyISAM}-Tabelle mit
+@code{ALTER TABLE tabelle TYPE=MyISAM} konvertieren oder mit dem
+Perl-Skript @code{mysql_convert_table_format}.
+
+Clients der Versionen 3.22 und 3.21 funktionieren ohne jedes Problem mit
+einem Server der Version 3.23.
+
+Die folgende Liste stellt dar, auf was Sie aufpassen müssen, wenn Sie auf
+Version 3.23 aktualisieren (Upgrade):
+
+@itemize @bullet
+@item
+Alle Tabellen, die den @code{tis620}-Zeichensatz benutzen, müssen mit
+@code{myisamchk -r} oder @code{REPAIR TABLE} in Ordnung gebracht werden.
+
+@item
+Wenn Sie ein @code{DROP DATABASE} auf eine mit symbolischem Link verknüpfte
+Datenbank ausführen, werden sowohl der symbolische Links als auch die
+Datenbank gelöscht. (Das war in Version 3.22 nicht der Fall, weil configure
+den @code{readlink}-Systemaufruf nicht erkannte).
+
+@item
+@code{OPTIMIZE TABLE} funktioniert jetzt nur bei @strong{MyISAM}-Tabellen.
+Bei anderen Tabellentypen können Sie @code{ALTER TABLE} benutzen, um die
+Tabelle zu optimieren. Während der Ausführung von @code{OPTIMIZE TABLE}
+wird die Tabelle jetzt vor dem Zugriff anderer Threads gesperrt.
+
+@item
+Der MySQL-Client @code{mysql} wir jetzt vorgabemäßig mit der Option
+@code{--no-named-commands (-g)} gestartet. Diese Option kann mit
+@code{--enable-named-commands (-G)} abgeschaltet werden. Dies kann ein paar
+Inkompatibilitätsprobleme verursachen, zum Beispiel in SQL-Skripten, die
+benannte (named) Befehle ohne ein Semikolon! Befehle im Langformat dagegen
+funktionieren noch auf der ersten Zeile.
+@c Question: ... still work from the first line?
+some cases, für Beispiel in SQL Skripts that use named Befehle ohne a
+semicolon! Long format Befehle still work from the first line.
+
+@item
+If you are using the @code{german} character sort order, you must repair
+all your Tabellen mit @code{isamchk -r}, as we have made some changes in
+the sort order!
+
+@item
+The default return type of @code{IF} will now depend on both arguments
+und not only the first argument.
+
+@item
+@code{AUTO_INCREMENT} funktioniert nicht mit negativen Zahlen. Der Grund
+liegt darin, dass negative Zahlen beim Übergang von -1 auf 0 Probleme
+verursachen. @code{AUTO_INCREMENT} wird jetzt bei MyISAM-Tabellen auf einem
+niedrigeren Level gehandhabt und ist viel schneller als vorher. Bei
+MyISAM-Tabellen werden alte Zahlen auch nicht mehr wieder benutzt, selbst
+wenn Sie einige Zeilen aus der Tabelle löschen.
+
+@item
+@code{CASE}, @code{DELAYED}, @code{ELSE}, @code{END}, @code{FULLTEXT},
+@code{INNER}, @code{RIGHT}, @code{THEN} und @code{WHEN} sind jetzt
+reservierte Wörter.
+
+@item
+@code{FLOAT(X)} ist jetzt ein echter Fließkomma-Typ und kein Wert mit
+einer festen Anzahl von Dezimalstellen.
+
+@item
+Wenn Sie @code{DECIMAL(length,dec)} deklarieren, beinhaltet das
+Längen-Argument nicht mehr den Platz für das Vorzeichen oder den
+Dezimalpunkt.
+
+@item
+Eine @code{TIME}-Zeichenkette muss jetzt von einem der folgenden Formate
+sein:
+@code{[[[DAYS] [H]H:]MM:]SS[.bruchteil]} oder
+@code{[[[[[H]H]H]H]MM]SS[.bruchteil]}
+
+@item
+@code{LIKE} vergleicht jetzt Zeichenketten unter Verwendung derselben
+Vergleichsregeln wie @code{'='}. Wenn Sie das alte Verhalten benötigen,
+können Sie MySQL mit dem @code{CXXFLAGS=-DLIKE_CMP_TOUPPER}-Flag
+kompilieren.
+
+@item
+@code{REGEXP} arbeitet jetzt bei normalen (nicht binären) Zeichenketten
+unabhängig von der Groß-/Kleinschreibung.
+
+@item
+Wenn Sie Tabellen prüfen / reparieren, sollten Sie @code{CHECK TABLE} oder
+@code{myisamchk} für @code{MyISAM}-Tabellen (@code{.MYI}) benutzen und
+@code{isamchk} für ISAM-Tabellen (@code{.ISM}).
+
+@item
+Wenn Sie wollen, dass @code{mysqldump}-Dateien zwischen MySQL-Version 3.22
+und Version 3.23 kompatibel sind, sollten Sie nicht die @code{--opt}- oder
+@code{--full}-Option für @code{mysqldump} benutzen.
+
+@item
+Überprüfen Sie Ihre Aufrufe von @code{DATE_FORMAT()} und stellen Sie
+sicher, dass vor jedem Formatierungszeichen ein @samp{%} steht. (Spätere
+MySQL-Versionen 3.22 ließen diese Syntax zu.)
+
+@item
+@code{mysql_fetch_fields_direct} ist jetzt eine Funktion (es war ein Makro)
+und gibt einen Zeiger auf @code{MYSQL_FIELD} anstelle eines
+@code{MYSQL_FIELD} zurück.
+
+@item
+@code{mysql_num_fields()} kann nicht mehr für ein @code{MYSQL*}-Objekt
+benutzt werden (es ist jetzt eine Funktion, die @code{MYSQL_RES*} als
+Argument nimmt. Sie sollten jetzt statt dessen @code{mysql_field_count()}
+benutzen.
+
+@item
+In MySQL-Version 3.22 war die Ausgabe von @code{SELECT DISTINCT ...} fast
+immer sortiert. In Version 3.23 müssen Sie @code{GROUP BY} oder @code{ORDER
+BY} benutzen, um eine sortierte Ausgabe zu erhalten.
+
+@item
+@code{SUM()} gibt jetzt @code{NULL} zurück statt 0, wenn es keine überein
+stimmenden Zeilen gibt. Das ist in Übereinstimmung mit ANSI-SQL.
+
+@item
+Ein @code{AND} oder @code{OR} mit @code{NULL}-Werten gibt jetzt @code{NULL}
+anstelle von 0 zurück. Das betrifft hauptsächlich Anfragen, die @code{NOT}
+bei einem @code{AND/OR}-Ausdruck wie @code{NOT NULL} = @code{NULL}
+benutzen.
+@code{LPAD()} und @code{RPAD()} kürzen die Ergebnis-Zeichenkette, wenn sie
+länger als das Längen-Argument ist.
+@end itemize
+
+@node Upgrading-from-3.21, Upgrading-from-3.20, Upgrading-from-3.22, Upgrade
+@c German node Upgrading-from-3.21
+@subsection Upgrade von Version 3.21 auf Version 3.22
+
+@cindex Kompatibilität, zwischen MySQL-Versionen
+@cindex Upgrade, 3.21 auf 3.22
+
+Nichts, was die Kompatibilität betrifft, hat sich zwischen Version 3.21 und
+3.22 geändert. Die einzige Falle ist die, dass neue Tabellen, die unter
+Verwendung des @code{DATE}-Typs erzeugt werden, die neue Art der
+Datenspeicherung benutzen. Diese neuen Felder kann man daher nicht von
+einer alten Version von @code{mysqld} ansprechen.
+
+Nachdem Sie MySQL-Version 3.22 installiert haben, starten Sie den neuen
+Server und lassen dann das @code{mysql_fix_privilege_tables}-Skript laufen.
+Dieses fügt die neuen Zugriffsberechtigungen ein, die Sie benötigen, um den
+@code{GRANT}-Befehl zu benutzen. Wenn Sie das vergessen, erhalten Sie ein
+@code{Access denied}, wenn Sie versuchen, @code{ALTER TABLE}, @code{CREATE
+INDEX} oder @code{DROP INDEX} zu benutzen. Wenn Ihr MySQL-Root ein Passwort
+benötigt, müssen Sie dieses als Argument zu
+@code{mysql_fix_privilege_tables} angeben.
+
+Die C-API-Schnittstelle für @code{mysql_real_connect()} hat sich geändert.
+Wenn Sie ein altes Client-Programm haben, das diese Funktion aufruft,
+müssen Sie eine @code{0} als neues @code{db}-Argument einfügen (oder den
+Client neu kodieren, so dass er das @code{db}-Element für schnellere
+Verbindungen benutzt). Zusätzlich müssen Sie @code{mysql_init()} aufrufen,
+bevor Sie @code{mysql_real_connect()} aufrufen! Diese Änderung wurde
+durchgeführt, damit die neue @code{mysql_options()}-Funktion in der
+@code{MYSQL}-Handler-Struktur Optionen speichern kann.
+
+The @code{mysqld}-Variable @code{key_buffer} wurde umbenannt in
+@code{key_buffer_size}, Sie können aber in Ihren Startdateien immer noch
+den alten Namen verwenden.
+
+
+@node Upgrading-from-3.20, Upgrading-to-arch, Upgrading-from-3.21, Upgrade
+@c German node Upgrading-from-3.20
+@subsection Upgrade von Version 3.20 auf Version 3.21
+
+@cindex Upgrade, 3.20 auf 3.21
+
+Wenn Sie eine Version benutzen, die älter als Version 3.20.28 ist, und auf
+Version 3.21 umstellen wollen, müssen Sie folgendes tun:
+
+Sie können den @code{mysqld}-Server Version 3.21 mit @code{safe_mysqld
+--old-protocol} starten, um ihn mit Clients aus einer Distribution Version
+3.20 zu benutzen. In diesem Fall gibt die neue Client-Funktion
+@code{mysql_errno()} überhaupt keine Server-Fehler zurück, nur
+@code{CR_UNKNOWN_ERROR} (funktioniert aber bei Client-Fehlern), und der
+Server benutzt die alte @code{password()}-Überprüfung statt der neuen.
+
+Wenn Sie die @code{--old-protocol}-Option @strong{NICHT} für @code{mysqld}
+benutzen, müssen Sie folgende Änderungen durchführen:
+
+@itemize @bullet
+@item
+Jeder Client-Code muss neu kompiliert werden. Wenn Sie ODBC benutzen,
+müssen Sie die neuen @strong{MyODBC}-2.x-Treiber verwenden.
+@item
+Sie müssen das Skript @code{Skripts/add_long_password} laufen lassen, um
+das @code{Password}-Feld in der @code{mysql.user}-Tabelle zu
+@code{CHAR(16)} zu ändern.
+@item
+Alle Passwörter müssen in der @code{mysql.user}-Tabelle neu zugewiesen
+werden (um 62-Bit- statt 31-Bit-Passwörter zu erhalten).
+@item
+Das Tabellenformat hat sich nicht geändert, daher müssen Sie keinerlei
+Tabellen konvertieren.
+@end itemize
+
+MySQL-Version 3.20.28 und höher kann das neue @code{user}-Tabellenformat
+handhaben, ohne sich auf Clients auszuwirken. Wenn Sie eine MySQL-Version
+vor Version 3.20.28 haben, funktionieren Passwörter damit nicht mehr, wenn
+Sie die @code{user}-Tabelle konvertieren. Um auf Nummer Sicher zu gehen,
+sollten Sie mindestens auf Version 3.20.28 aktualisieren und erst dann auf
+Version 3.21.
+
+@cindex Protokoll-Unverträglichkeit
+Der neue Client-Code funktioniert bei einem 3.20.x @code{mysqld}-Server.
+Wenn Sie daher Probleme mit 3.21.x bekommen, können Sie den alten
+3.20.x-Server benutzen, ohne die Clients neu kompilieren zu müssen.
+
+Wenn Sie nicht die @code{--old-protocol}-Option für @code{mysqld} benutzen,
+werden alte Clients folgende Fehlermeldung ausgeben:
+
+@example
+ERROR: Protocol mismatch. Server Version = 10 Client Version = 9
+@end example
+
+Die neue Perl-@code{DBI}/@code{DBD}-Schnittstelle unterstützt auch die alte
+@code{mysqlperl}-Schnittstelle. Die einzige Änderung, die Sie machen
+müssen, wenn Sie @code{mysqlperl} benutzen, ist, die Argumente für die
+@code{connect()}-Funktion zu ändern. Die neuen Argumente sind: @code{host},
+@code{database}, @code{user} und @code{password} (die @code{user}- und
+@code{password}-Argumente haben die Plätze getauscht.
+@xref{Perl DBI Class, , Perl-@code{DBI}-Klasse}.
+
+Folgende Änderungen können Anfragen in alten Applikationen betreffen:
+
+@itemize @bullet
+@item
+@code{HAVING} muss jetzt vor einer möglichen @code{ORDER BY}-Klausel
+spezifiziert werden.
+@item
+Die Parameter für @code{LOCATE()} wurden getauscht.
+@item
+Es gibt einige neue reservierte Wörter. Die wichtigsten sind @code{DATE},
+@code{TIME} und @code{TIMESTAMP}.
+@end itemize
+
+
+@node Upgrading-to-arch, , Upgrading-from-3.20, Upgrade
+@c German node Upgrading-to-arch
+@subsection Upgrade auf eine andere Architektur
+
+@cindex Upgrade, auf andere Architektur
+
+Wenn Sie MySQL-Version 3.23 benutzen, können Sie die @code{.frm}-,
+@code{.MYI}- und @code{.MYD}-Dateien zwischen verschiedenen Architekturen
+kopieren, die dasselbe Fließkomma-Format unterstützen. (MySQL kümmert sich
+um eventuelle Byte-Tausch-Belange.)
+
+Die MySQL-@code{ISAM}-Daten und Index-Dateien (@file{.ISD} und
+@file{*.ISM}, je nachdem) sind Architektur-abhängig und in manchen Fällen
+Betriebssystem-abhängig. Wenn Sie Ihre Applikationen auf eine andere
+Maschine mit einer unterschiedlichen Architektur oder einem anderen
+Betriebssystem verlagern wollen, wollten Sie nicht einfach eine Datenbank
+verschieben, indem Sie deren Dateien auf die andere Maschine kopieren.
+Benutzen Sie statt dessen @code{mysqldump}.
+
+Vorgabemäßig erzeugt @code{mysqldump} eine Datei mit SQL-Statements. Sie
+können diese Datei auf die andere Maschine übertragen und Sie als Eingabe
+für den @code{mysql}-Client benutzen.
+
+@code{mysqldump --help} zeigt Ihnen, welche Optionen verfügbar sind. Wenn
+Sie die Daten mit einer neueren Version von MySQL benutzen werden, sollten
+Sie @code{mysqldump --opt} mit der neueren Version benutzen, um einen
+schnellen, kompakten Dump zu erhalten.
+
+Die einfachste (wenngleich nicht schnellste) Art, eine Datenbank von einer
+Maschine auf eine andere zu bringen, ist, die folgenden Befehle auf der
+Maschine auszuführen, auf der die Datenbank liegt:
+
+@example
+shell> mysqladmin -h 'anderer hostname' create db_name
+shell> mysqldump --opt db_name \
+ | mysql -h 'anderer hostname' db_name
+@end example
+
+Wenn Sie eine Datenbank von einer entfernten Maschine über ein langsames
+Netzwerk kopieren wollen, können Sie folgendes benutzen:
+
+@example
+shell> mysqladmin create db_name
+shell> mysqldump -h 'anderer hostname' --opt --compress db_name \
+ | mysql db_name
+@end example
+
+Sie können das Ergebnis auch in einer Datei speichern, diese Datei auf die
+Zielmaschine übertragen und dort in die Datenbank laden. Sie können zum
+Beispiel wie folgt die Datenbank in eine Datei auf der Quellmaschine
+ausgeben (dumpen):
+
+@example
+shell> mysqldump --quick db_name | gzip > db_name.inhalte.gz
+@end example
+
+(Die in diesem Beispiel erzeugte Datei ist komprimiert.) Übertragen Sie die
+Datei, die die Datenbankinhalte enthält, auf die Zielmaschine und geben Sie
+dort diese Befehle ein:
+
+@example
+shell> mysqladmin create db_name
+shell> gunzip < db_name.inhalte.gz | mysql db_name
+@end example
+
+@cindex @code{mysqldump}
+@cindex @code{mysqlimport}
+Sie können auch @code{mysqldump} und @code{mysqlimport} benutzen, um den
+Datenbank-Transfer zu bewerkstelligen.
+Das ist bei großen Tabellen wesentlich schneller als die Benutzung von
+@code{mysqldump}. In den unten dargestellten Befehlen repräsentiert
+@code{DUMPDIR} den vollen Pfadnamen des Verzeichnisses, das Sie benutzen,
+um die Ausgabe von @code{mysqldump} zu speichern.
+
+Legen Sie zunächst das Verzeichnis für die Ausgabe-Dateien an und geben Sie
+die Datenbank aus (Dump):
+
+@example
+shell> mkdir DUMPDIR
+shell> mysqldump --tab=DUMPDIR db_name
+@end example
+
+Übertragen Sie dann die Dateien des @code{DUMPDIR}-Verzeichnisses in ein
+entsprechendes Verzeichnis auf der Zielmaschine und laden Sie dort die
+Dateien in MySQL:
+
+@example
+shell> mysqladmin create db_name # Datenbank erzeugen
+shell> cat DUMPDIR/*.sql | mysql db_name # Tabellen in der Datenbank erzeugen
+shell> mysqlimport db_name DUMPDIR/*.txt # Daten in die Tabellen laden
+@end example
+
+Vergessen Sie auch nicht, die @code{mysql}-Datenbank zu kopieren, den dort
+befinden Sie die Berechtigungstabellen (@code{user}, @code{db},
+@code{host}). Eventuell müssen Sie die Befehle als
+MySQL-@code{root}-Benutzer auf der neuen Maschine eingeben, um die
+@code{mysql}-Datenbank angelegt zu bekommen.
+
+Nachdem Sie die @code{mysql}-Datenbank auf die neue Maschine kopiert haben,
+führen Sie @code{mysqladmin flush-privileges} aus, damit der Server die
+Berechtigungsinformationen neu einliest.
+
+
+@node Operating System Specific Notes, Perl support, Upgrade, Installing
+@c German node Clientseitig
+@section Betriebssystem-spezifische Anmerkungen
+
+
+
+@menu
+* Linux::
+* Windows::
+* Solaris::
+* BSD Notes::
+* Mac OS X::
+* Other Unix Notes::
+* OS/2::
+* BeOS::
+* Novell Netware::
+@end menu
+
+@node Linux, Windows, Operating System Specific Notes, Operating System Specific Notes
+@c German node Linux
+@subsection Linux (alle Linux-Versionen)
+
+
+Die Anmerkungen weiter unten, die @strong{glibc} betreffen, gelten nur
+dann, wenn Sie MySQL selbst bauen. Wenn Sie Linux auf einer x86-Maschine
+fahren, ist es in den meisten Fällen wesentlich besser, einfach unsere
+Binärdateien zu benutzen. Wir linken unsere Binärdateien an die am besten
+gepatchte Version von @strong{glibc}, die wir bieten können, und mit den
+besten Kompiler-Optionen, wobei wir versuchen, MySQL für Hochlast-Server
+geeignet zu machen. Wenn Sie also den Text unten lesen und sich nicht
+sicher sind, was Sie tun sollen, sollten Sie zunächst unsere Binärdateien
+ausprobieren, um zu sehen, ob diese Ihren Anforderungen entsprechen.
+Kümmern Sie sich nur dann um einen eigenen Build, wenn Sie feststellen,
+dass unsere Binärdateien nicht gut genug sind. In diesem Fall wären wir für
+einen Hinweis dazu dankbar, damit wir beim nächsten Mal eine bessere
+Binärdatei bauen können. Für eine typische Benutzung, selbst bei einer
+großen Zahl gleichzeitiger Verbindungen und / oder Tabellen, die größer
+als 2 GB sind, sind unsere Binärdateien in den meisten Fällen die beste
+Wahl.
+
+MySQL benutzt auf Linux LinuxThreads. Wenn Sie eine alte Linux-Version
+benutzen, die keine @code{glibc2} hat, müssen Sie LinuxThreads
+installieren, bevor Sie MySQL kompilieren. Sie erhalten LinuxThreads unter
+@uref{http://www.mysql.com/downloads/Linux}.
+
+@strong{ACHTUNG:} Wir haben einige seltsame Probleme bei Linux 2.2.14 und
+MySQL auf SMP-Systemen festgestellt. Wenn Sie ein SMP-System haben,
+empfehlen wir, so schnell wie möglich auf Linux 2.4 zu aktualisieren
+(Upgrade)! Dadurch wird Ihr System ausserdem schneller und stabiler!
+
+Beachten Sie, dass @code{glibc}-Versionen vor und einschließlich Version
+2.1.1 einen schweren Fehler im @code{pThread_mutex_timedwait}-Handling
+haben, was benutzt wird, wenn Sie @code{INSERT DELAYED} verwenden. Wir
+empfehlen, vor einem Upgrade der glibc @code{INSERT DELAYED} nicht zu
+verwenden.
+
+Wenn Sie planen, mehr als 1000 gleichzeitige Verbindungen zu haben, müssen
+Sie einige Änderungen an LinuxThreads vornehmen, es neu kompilieren und mit
+der neuen @file{libpThread.a} linken. Setzen Sie @code{PTHREAD_THREADS_MAX} in
+@file{sysdeps/unix/sysv/linux/bits/local_lim.h} auf 4096 herauf und setzen
+Sie @code{STACK_SIZE} in @file{linuxThreads/internals.h} auf 256 KB
+herunter. Die Pfade sind relativ zum Wurzelverzeichnis von @code{glibc}.
+Beachten Sie, dass MySQL bei etwa 600 bis 1000 Verbindungen nicht stabil
+läuft, wenn @code{STACK_SIZE} auf den Vorgabewert von 2 MB gesetzt wird.
+
+Wenn Sie Probleme damit bekommen, dass MySQL nicht genug Dateien oder
+Verbindungen öffnen kann, haben Sie möglicherweise Linux nicht so
+konfiguriert, dass es genug Dateien handhaben kann.
+
+In Linux 2.2 und Folgenden können Sie die Anzahl der allozierten
+Datei-Handler herausbekommen, wenn Sie folgendes eingeben:
+
+@example
+cat /proc/sys/fs/file-max
+cat /proc/sys/fs/dquot-max
+cat /proc/sys/fs/super-max
+@end example
+
+Wenn Sie mehr als 16M Speicher haben, sollten Sie etwas Ähnliches wie
+folgendes in Ihr Boot-Skript (@file{/etc/rc/boot.local} auf SuSE)
+eintragen:
+
+@example
+echo 65536 > /proc/sys/fs/file-max
+echo 8192 > /proc/sys/fs/dquot-max
+echo 1024 > /proc/sys/fs/super-max
+@end example
+
+Das können Sie auch von der Kommandozeile aus als Root eingeben, aber in
+diesem Fall werden die alten Beschränkungen wieder benutzt, wenn Sie Ihren
+Computer neu starten.
+
+Zusätzlich sollten Sie in /etc/my.cnf einfügen:
+
+@example
+[safe_mysqld]
+open-files-limit=8192
+@end example
+
+Das sollte MySQL erlauben, bis zu 8192 Verbindungen und Dateien zu
+erzeugen.
+
+Die @code{STACK_SIZE}-Konstante in LinuxThreads steuert das Spacing von
+Thread-Stacks im Adressraum. Sie muss Groß genug sein, damit reichlich
+Platz für den Stack jedes individuellen Threads bleibt, aber klein genug,
+um den Stack irgend eines Threads davon abzuhalten, mit den globalen
+@code{mysqld}-Daten zu kollidieren. Wie wir durch Experimentieren heraus
+fanden, unmappt die Linux-Implementation von @code{mmap()} erfolgreich eine
+bereits gemappte Region, wenn Sie sie anweisen, eine Adresse auszumappen,
+die bereits in Benutzung ist, wobei sie alle Daten der gesamten Seite auf
+Null setzt, statt einen Fehler zurück zu geben. Daher beruht die Sicherheit
+von @code{mysqld} oder jeder anderen Thread-Applikation auf dem
+"Gentleman"-Verhalten des Codes, der Threads erzeugt. Der Benutzer muss
+Vorkehrungen treffen, die sicherstellen, dass die Anzahl laufender Threads
+jederzeit ausreichend gering ist, damit die Thread-Stacks sich vom globalen
+Heap fernhalten. Bei @code{mysqld} sollten Sie dieses "Gentleman"-Verhalten
+forcieren, indem Sie einen vernünftigen Wert für die the
+@code{max_connections}-Variable setzen.
+
+Wenn Sie MySQL selbst bauen und sich nicht mit dem Patchen von LinuxThreads
+herum plagen wollen, sollten Sie @code{max_connections} auf einen Wert
+nicht größer als 500 setzen. Dieser Wert sollte sogar noch kleiner sein,
+wenn Sie einen großen Schlüsselpuffer (Key Buffer), große Heap-Tabellen
+oder andere Dinge haben, die @code{mysqld} dazu bringen könnten, eine Menge
+Speicher zu allozieren, oder wenn Sie einen 2.2-Kernel mit einem 2GB-Patch
+fahren. Wenn Sie unsere Binärdateien oder RPM-Versionen 3.23.23 oder später
+benutzen, können Sie @code{max_connections} sicher auf 1500 setzen, unter
+der Annahme, dass es keine großen Schlüsselpuffer oder Heap-Tabellen mit
+vielen Daten gibt. Je mehr Sie @code{STACK_SIZE} in LinuxThreads reduzieren
+können, desto mehr können Sie sicher Threads erzeugen. Wir empfehlen einen
+Wert zwischen 128K und 256K.
+
+Wenn Sie viele gleichzeitige Verbindungen benutzen, bekommen Sie vielleicht
+Probleme durch ein "Feature" im 2.2-Kernel, der einen Prozess dafür
+bestraft, dass er sich aufspaltet (fork) oder einen Kindprozess klont, um
+einen Fork-Bombenangriff (Fork Bomb Attack) zu verhindern. Das bringt MySQL
+dazu, nicht so gut zu skalieren, wenn Sie die Anzahl gleichzeitiger Clients
+erhöhen. Wir konnten beobachten, dass sich das auf Einprozessor-Systemen
+mit sehr langsamer Thread-Erzeugung bemerkbar macht, was sich darin zeigt,
+dass es sehr lange dauern kann, sich mit MySQL zu verbinden (bis zu einer
+Minute), und genau so lange, um es herunter zu fahren. Auf
+Multiprozessor-Systemen haben wir einen allmählichen Abfall der
+Anfrage-Geschwindigkeit beobachtet, wenn die Anzahl der Clients zunimmt. Im
+Verlauf der Suche nach einer Lösung haben wir von einem unserer Benutzer
+einen Kernel-Patch erhalten, von dem dieser sagt, dass er auf seiner Site
+eine beträchtliche Rolle spielt. Der Patch ist hier verfügbar
+(@uref{http://www.mysql.com/downloads/patches/linux-fork.patch}).
+Inzwischen haben wir recht ausführliche Tests dieses Patchs sowohl auf
+Entwicklungs- als auch auf Produktionssystemen gemacht. Er hat die
+Performance von @code{MySQL} erheblich verbessert, ohne irgend welche
+Probleme zu verursachen, und wir empfehlen ihn jetzt denjenigen unserer
+Benutzer, die immer noch Hochlast-Server auf 2.2-Kerneln fahren. Dieses
+Problem wurde im 2.4-Kernel behoben. Wenn Sie daher nicht zufrieden mit der
+momentanen Performance Ihres Systems sind, ist es wahrscheinlich einfacher,
+auf 2.4 zu aktualisieren, statt den 2.2-Kernel zu patchen, was zusätzlich
+zur Behebung dieses Fairness-Bugs auch noch Multiprozessor-Systemen einen
+netten Schub gibt.
+
+Wir haben MySQL auf dem 2.4-Kernel auf einer Zweiprozessor-Maschine
+getestet und haben festgestellt, dass MySQL VIEL bessere Leistungsdaten
+bringt - es gab praktisch keine Verlangsamung bei Anfragen bis ganz herauf
+zu 1000 Clients, und der Skalierungsfaktor von MySQL (berechnet als
+Verhältnis von maximalem Durchsatz zum Durchsatz mit 1 Client) war 100%.
+Ähnliches haben wir auf einer Vierprozessor-Maschine beobachtet - praktisch
+keine Verlangsamung, während die Anzahl der Clients bis auf 1000 stieg
+sowie ein Skalierungsfaktor von 300%. Für einen unter Hochlast fahrenden
+Multiprozessor-Server empfehlen wir daher ausdrücklich den 2.4-Kernel.
+Weiter haben wir festgestellt, dass es essentiell wichtig ist, den
+@code{mysqld}-Prozess auf dem 2.4-Kernel mit der höchstmöglichen Priorität
+laufen zu lassen, um maximale Performance zu erreichen. Das kann dadurch
+erreicht werden, dass man den @code{renice -20 $$}-Befehl zu
+@code{safe_mysqld} hinzufügt. Bei unseren Tests auf der
+Vierprozessor-Maschine ergab die Erhöhung der Priorität eine 60%-ige
+Steigerung des Durchsatzes bei 400 Clients.
+
+Wir sind derzeit dabei, mehr Informationen über die Performance von
+@code{MySQL} auf dem 2.4-Kernel auf 4-Weg- und 8-Weg-Systemen zu bekommen.
+Wenn Sie Zugang zu einem solchen System haben und einige Benchmarks gemacht
+haben, schicken Sie bitte eine Mail mit den Ergebnissen an
+@email{docs@@mysql.com} - wir werden Sie dem Handbuch hinzufügen.
+
+Es gibt eine weitere Sache, die die Performance von MySQL stark
+beeinträchtigt, besonders auf SMP-Systemen. Die Implementation von mutex
+in LinuxThreads in @strong{glibc-2.1} ist sehr schlecht für Programme mit
+vielen Threads, die den mutex nur für kurze Zeit behalten. Wenn Sie MySQL
+mit unveränderten @strong{LinuxThreads} linken, führt ironischerweise
+auf einem SMP-System in manchen Fällen das Entfernen von Prozessoren zu
+einer Leistungssteigerung von MySQL. Für @strong{glibc 2.1.3} haben wir ein
+Patch bereit gestellt, um dieses Verhalten zu korrigieren:
+@uref{http://www.mysql.com/downloads/Linux/linuxThreads-2.1-patch,linuxThreads-2.1-patch}
+
+Bei Verwendung von @strong{glibc-2.2.2} benutzt MySQL-Version 3.23.36 den
+adaptiven mutex, der sogar viel besser als der gepatchte von
+@strong{glibc-2.1.3} ist. Seien Sie jedoch davor gewarnt, dass unter
+bestimmten Umständen der aktuelle mutex-Code in @strong{glibc-2.2.2}
+überdrehen kann, was die Performance von MySQL beeinträchtigt. Die Gefahr,
+dass solche Umstände eintreten, kann dadurch verringert werden, dass der
+@code{mysqld}-Prozess auf die höchste Priorität gesetzt wird. Zusätzlich
+konnten wir das Überdrehverhalten mit einem Patch korrigieren, der
+@uref{http://www.mysql.com/downloads/Linux/linuxThreads-2.2.2.patch,hier}
+erhältlich ist. Der Patch kombiniert die Korrektur des Überdrehens, die
+maximale Anzahl von Threads und das Stack-Spacing in einem. Sie wenden es
+auf das @code{linuxThreads}-Verzeichnis mit @code{patch -p0
+</tmp/linuxThreads-2.2.2.patch} an. Wir hoffen, dass der Patch in irgend
+einer Form in zukünftigen Releases von @code{glibc-2.2} enthalten sein
+wird. Wie es auch sei, wenn Sie mit @code{glibc-2.2.2} linken, müssen Sie
+immer noch @code{STACK_SIZE} und @code{PTHREAD_THREADS_MAX} korrigieren.
+Wir hoffen, dass diese Vorgabewerte zukünftig auf akzeptablere Werte für
+eine MySQL-Hochlast-Einrichtung gesetzt werden, so dass Ihr eigener Build
+auf @code{./configure; make; make install} reduziert werden kann.
+
+Wir empfehlen, dass Die die oben genannten Patches benutzen, um eine
+spezielle statische Version von @code{libpThread.a} zu bauen, die Sie nur
+für statisches Linken mit @code{MySQL} benutzen. Wir wissen, dass die
+Patches für @code{MySQL} sicher sind und seine Performance erheblich
+verbessern, aber wir können diesbezüglich nichts über andere Applikationen
+sagen. Wenn Sie andere Applikationen mit der gepatchten Version der
+Bibliothek linken oder eine gepatchte gemeinsam benutzte (shared) Version
+bauen und auf Ihrem System installieren, tun Sie das auf eigenes Risiko,
+was andere Applikationen betrifft, die von @code{LinuxThreads} abhängen.
+
+Wenn Sie während der Installation von MySQL irgend welche seltsamen
+Probleme bekommen oder gebräuchliche Utilities hängen bleiben, ist es sehr
+wahrscheinlich, dass diese entweder Bibliotheks- oder Compiler-bezogen
+sind. In diesem Fall wird die Benutzung unserer Binärdatei sie beheben.
+
+Ein bekanntes Problem der Binärdistribution ist, dass Sie auf älteren
+Linux-Systemen, die @code{libc} benutzen (wie RedHat 4.x oder Slackware)
+nicht-schwere (non-fatal) Probleme mit der Auflösung von Hostnamen
+bekommen.
+@xref{Linux-RPM}.
+
+Wenn Sie LinuxThreads benutzen, werden Sie feststellen, dass mindestens
+drei Prozesse laufen. Das sind in Wirklichkeit Threads. Es gibt einen
+Thread für den LinuxThreads-Manager, einen Thread, um Verbindungen zu
+handhaben und einen Thread, um Alarme und Signale zu handhaben.
+
+Beachten Sie, dass der Linux-Kernel und die LinuxThread-Bibliothek
+vorgabemäßig nur 1024 Threads haben können. Das bedeutet, dass Sie auf
+einem ungepatchten System nur höchstens 1021 Verbindungen zu MySQL haben
+können. Die Seite @uref{http://www.volano.com/linuxnotes.html} enthält
+Informationen, wie man diese Beschränkung umgeht.
+
+Wenn Sie einen toten @code{mysqld}-Daemon-Prozess mit @code{ps} sehen,
+bedeutet das üblicherweise, dass Sie einen Bug in MySQL oder eine zerstörte
+Tabelle gefunden haben. @xref{Crashing}.
+
+Um auf Linux einen Speicherauszug (Core Dump) zu erhalten, wenn
+@code{mysqld} mit einem SIGSEGV-Signal stirbt, können Sie @code{mysqld} mit
+der @code{--core-file}-Option starten. Beachten Sie, dass Sie
+wahrscheinlich @code{core file size} hoch setzen müssen, indem Sie
+@code{ulimit -c 1000000} zu @code{safe_mysqld} hinzufügen oder
+@code{safe_mysqld} mit @code{--core-file-sizes=1000000} starten.
+@xref{safe_mysqld, , @code{safe_mysqld}}.
+
+Wenn Sie Ihren eigenen MySQL-Client linken und bei der Ausführung diesen
+Fehler erhalten,
+
+@example
+ld.so.1: ./my: fatal: libmysqlclient.so.4: open failed: No such file or directory
+@end example
+
+kann das Problem durch eine der folgenden Methoden behoben werden:
+
+@itemize @bullet
+@item
+Linken Sie den Client mit dem folgenden Flag (anstelle von @code{-Lpath}):
+@code{-Wl,r/path-libmysqlclient.so}.
+
+@item
+Kopieren Sie @code{libmysqclient.so} nach @file{/usr/lib}.
+
+@tindex LD_RUN_PATH Umgebungsvariable
+@tindex Umgebungsvariable, LD_RUN_PATH
+@item
+Fügen Sie der @code{LD_RUN_PATH}-Umgebungsvariablen den Pfadnamen des
+Verzeichnisses hinzu, wo @code{libmysqlclient.so} liegt, bevor Sie Ihren
+Client laufen lassen.
+@end itemize
+
+Wenn Sie den Fujitsu-Compiler @code{(fcc / FCC)} benutzen, werden Sie beim
+Kompilieren von MySQL einige Probleme bekommen, weil die
+Linux-Header-Dateien sehr @code{gcc}-orientiert sind.
+
+Folgende @code{configure}-Zeile sollte mit @code{fcc/FCC} funktionieren:
+
+@example
+CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=konstante -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=konstante -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO '-D_EXTERN_INLINE=static __inline'" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-low-memory
+@end example
+
+@menu
+* Binary notes-Linux::
+* Linux-x86::
+* Linux-SPARC::
+* Linux-Alpha::
+* Linux-PowerPC::
+* Linux-MIPS::
+* Linux-IA64::
+@end menu
+
+@node Binary notes-Linux, Linux-x86, Linux, Linux
+@c German node Linux-Binärdateien
+@subsubsection Anmerkungen zur Binärdistribution (Linux)
+
+@cindex Binärdistributionen, unter Linux
+@cindex Linux, Binärdistribution
+
+MySQL benötigt zumindest Linux-Version 2.0.
+
+@strong{ACHTUNG}:
+Wir haben Berichte von MySQL-Benutzern erhalten, die schwer wiegende
+Stabilitätsprobleme mit Linux-Kernel 2.2.14 mitgeteilt haben. Wenn Sie
+diesen Kernel benutzen, sollten Sie auf 2.2.19 (oder neuer) oder auf einen
+2.4-Kernel aktualisieren. Wenn Sie eine Mehrprozessormaschine haben,
+sollten Sie auf jeden Fall in Betracht ziehen, 2.4 zu benutzen, weil Ihnen
+das erhebliche Geschwindigkeitssteigerung geben wird.
+
+Die Binärdistribution wird mit @code{-static} gelinkt, was normalerweise
+heißt, dass Sie sich nicht um die Version der Systembibliotheken kümmern
+müssen, die Sie haben. Ausserdem brauchen Sie nicht LinuxThread
+installieren. Ein Programm, das mit @code{-static} gelinkt ist, ist etwas
+größer als ein dynamisch gelinktes Programm, und gleichzeitig etwas
+schneller (3-5%). Ein Problem liegt jedoch darin, dass Sie bei einem
+statisch gelinkten Programm keine benutzerdefinierten Funktionen (UDF)
+benutzen können. Wenn Sie UDF-Funktionen schreiben oder benutzen wollen
+(das ist nur etwas für C- oder C++-Programmierer), müssen Sie MySQL selbst
+kompilieren und das dynamische Linken benutzen.
+
+Wenn Sie ein @code{libc}-basierendes System benutzen (statt eines
+@code{glibc2}-Systems), bekommen Sie bei der Binärdistribution
+wahrscheinlich Probleme mit der Auflösung von Hostnamen und mit
+@code{getpwnam()}. (Das liegt daran, dass @code{glibc} leider von einigen
+externen Bibliotheken abhängt, um Hostnamen aufzulösen und und
+@code{getpwent()}, selbst wenn es mit @code{-static} kompiliert wird.) In
+diesem Fall erhalten Sie wahrscheinlich folgende Fehlermeldung, wenn Sie
+@code{mysql_install_db} ausführen:
+
+@example
+Sorry, the host 'xxxx' could not be looked up
+@end example
+
+oder den folgenden Fehler, wenn Sie versuchen, @code{mysqld} mit der
+@code{--user}-Option laufen zu lassen:
+
+@example
+getpwnam: No such file or directory
+@end example
+
+Sie können dieses Problem auf eine der folgenden Weisen lösen:
+
+@itemize @bullet
+@item
+Holen Sie sich eine MySQL-Quelldistribution (eine RPM oder die
+@code{tar.gz}-Distribution) und installieren Sie statt dessen diese.
+@item
+Führen Sie @code{mysql_install_db --force} aus. Das führt nicht den
+@code{resolveip}-Test in @code{mysql_install_db} aus. Der Nachteil ist,
+dass Sie keine Hostnamen in the Berechtigungstabellen benutzen können,
+sondern nur IP-Nummern (ausser für @code{localhost}). Wenn Sie ein altes
+MySQL-Release benutzen, das @code{--force} nicht unterstützt, müssen Sie
+den @code{resolveip}-Test in @code{mysql_install} mit einem Editor
+deaktivieren.
+@item
+Starten Sie @code{mysqld} mit @code{su} anstelle von @code{--user}.
+@end itemize
+
+Die Linux-Intel-Binärdatei und die RPM-Releases von MySQL sind für höchst
+mögliche Geschwindigkeit konfiguriert. Wir versuchen immer, den schnellsten
+stabilen Kompiler zu benutzen, der verfügbar ist.
+
+MySQL-Perl-Unterstützung erfordert Perl-Version 5.004_03 oder neuer.
+
+Auf einigen Linux-2.2-Versionen erhalten Sie womöglich den Fehler
+@code{Resource temporarily unavailable}, wenn Sie eine Menge neuer
+Verbindungen zu einem @code{mysqld}-Server über TCP/IP aufmachen.
+
+Das Problem liegt darin, dass Linux eine Verzögerung zwischen dem
+Schließen eines TCP/IP-Sockets und dem tatsächlichen Freigeben durch das
+System hat. Da es nur Platz für eine bestimmte Anzahl von TCP/IP-Slots
+gibt, bekommen Sie den genannten Fehler, wenn Sie viele neue
+TCP/IP-Verbindungen innerhalb kurzer Zeit aufbauen, zum Beispiel, wenn Sie
+den MySQL-@file{test-connect}-Benchmark über TCP/IP laufen lassen.
+
+Wir haben dieses Problem mehrfach an verschiedene Linux-Mailing-Listen
+geschrieben, konnten aber bislang keine saubere Lösung erhalten.
+
+Die einzige bekannte 'Behebung' des Problems liegt darin, persistente
+Verbindungen bei Ihren Clients zu verwenden oder Sockets zu benutzen, wenn
+Sie den Datenbankserver und die Clients auf derselben Maschine laufen
+lassen. Wir hoffen, dass zukünftig der @code{Linux 2.4}-Kernel dieses
+Problem lösen wird.
+
+
+@node Linux-x86, Linux-SPARC, Binary notes-Linux, Linux
+@c German node Linux-x86
+@subsubsection Anmerkungen zu Linux x86
+
+MySQL erfordert @code{libc}-Version 5.4.12 oder neuer. Bekannt ist, dass
+@code{libc} 5.4.46 funktioniert. @code{glibc}-Version 2.0.6 und später
+sollten ebenfalls funktionieren. Es hat einige Probleme mit den
+@code{glibc}-RPMs von RedHat gegeben. Wenn Sie Probleme haben, prüfen Sie
+daher, ob es Updates gibt! Die @code{glibc}-2.0.7-19- und -2.0.7-29-RPMs
+funktionieren bekanntermaßen ebenfalls.
+
+Bei einigen älteren Linux-Distributionen kann @code{configure} einen Fehler
+wie folgt produzieren:
+
+@example
+Syntaxfehler in sched.h. Ändern Sie _P zu __P in der
+/usr/include/sched.h-Datei. Siehe das Installationskapitel im
+Referenzhandbuch.
+@end example
+
+Machen Sie, was die (englischsprachige) Fehlermeldung sagt. Fügen Sie also
+einen zusätzlichen Unterstrich zum @code{_P}-Makro hinzu, das nur einen
+Unterstrich hat, und versuchen Sie es noch einmal.
+
+Möglicherweise erhalten Sie beim Kompilieren Warnungen. Die folgenden davon
+können ignoriert werden:
+
+@example
+mysqld.cc -o objs-thread/mysqld.o
+mysqld.cc: In function `void init_signals()':
+mysqld.cc:315: warning: assignment of negative value `-1' to `long unsigned int'
+mysqld.cc: In function `void * signal_hand(void *)':
+mysqld.cc:346: warning: assignment of negative value `-1' to `long unsigned int'
+@end example
+
+In Debian-GNU/Linux müssen Sie folgendes tun, damit MySQL beim Hochfahren
+des Systems automatisch startet:
+
+@example
+shell> cp support-files/mysql.server /etc/init.d/mysql.server
+shell> /usr/sbin/update-rc.d mysql.server defaults 99
+@end example
+
+@code{mysql.server} befindet sich im @file{share/mysql}-Verzeichnis
+unterhalb des MySQL-Installationsverzeichnisses oder im
+@file{support-files}-Verzeichnis des MySQL-Source-Trees.
+
+Wenn @code{mysqld} beim Start immer einen Speicherauszug (Core Dump)
+erzeugt, kann das Problem darin liegen, dass Sie eine alte
+@file{/lib/libc.a} haben. Versuchen Sie sie umzubenennen, entfernen Sie
+dann @file{sql/mysqld}, führen Sie ein neues @code{make install} durch und
+versuchen Sie es noch einmal. Dieses Problem wurde von einigen
+Slackware-Installationen berichtet.
+
+Wenn Sie beim Linken von @code{mysqld} folgenden Fehler erhalten, bedeutet
+das, dass Ihre @file{libg++.a} nicht korrekt installiert ist:
+
+@example
+/usr/lib/libc.a(putc.o): In function `_IO_putc':
+putc.o(.text+0x0): multiple definition of `_IO_putc'
+@end example
+
+Sie können vermeiden, dass @file{libg++.a} benutzt wird, indem Sie
+@code{configure} wie folgt ablaufen lassen:
+
+@example
+shell> CXX=gcc ./configure
+@end example
+
+
+@node Linux-SPARC, Linux-Alpha, Linux-x86, Linux
+@c German node Linux-SPARC
+@subsubsection Anmerkungen zu Linux SPARC
+
+Bei einigen Implementationen ist @code{readdir_r()} fehlerhaft. Das äußert
+sich darin, dass @code{SHOW DATABASES} immer einen leeren Satz (Empty Set)
+zurück gibt. Das kann behoben werden, indem @code{HAVE_READDIR_R} aus
+
+
+Einige Probleme erfordern, dass Sie Ihre Linux-Installation patchen. Der
+Patch befindet sich unter
+@uref{http://www.mysql.com/downloads/patches/Linux-sparc-2.0.30.diff}.
+
+Dieser Patch bezieht sich auf Linux-Distribution
+@file{sparclinux-2.0.30.tar.gz}, die auf @code{vger.rutgers.edu} verfügbar
+ist (eine Version von Linux, die nie mit der offiziellen 2.0.30 verbunden
+wurde). Zusätzlich müssen Sie LinuxThreads 0.6 oder neuer installieren.
+
+
+@node Linux-Alpha, Linux-PowerPC, Linux-SPARC, Linux
+@c German node Linux-Alpha
+@subsubsection Anmerkungen zu Linux Alpha
+
+MySQL-Version 3.23.12 ist die erste MySQL-Version, die auf Linux-Alpha
+getestet wurde. Wenn Sie planen, MySQL auf Linux-Alpha einzusetzen, stellen
+Sie sicher, dass Sie diese oder eine neuere Version haben.
+
+Wir haben MySQL auf Alpha mit unseren Benchmarks und unserer Test-Suite
+getestet, und es scheint gut zu funktionieren. Hauptsächlich noch nicht
+getestet haben wird, wie die Dinge mit vielen gleichzeitigen Verbindungen
+funktionieren.
+
+Wir kompilieren die Standard-MySQL-Binärdatei mit SuSE 6.4, Kernel
+2.2.13-SMP, Compaq-C-Kompiler Version 6.2-504 und Compaq-C++-Kompiler
+Version 6.3-005 auf einer Compaq-DS20-Maschine mit einem
+Alpha-EV6-Prozessor.
+
+Sie finden die genannten Kompiler auf
+@uref{http://www.support.compaq.com/alpha-tools}). Durch die Verwendung
+dieser Kompiler anstelle von gcc erhalten wir eine 9% bis 14% bessere
+Performance für MySQL.
+
+Beachten Sie, dass die Konfigurationszeile die Binärversion auf die
+aktuelle CPU optimiert. Das heißt, dass Sie unsere Binärdatei nur benutzen
+können, wenn Sie einen Alpha-EV6-Prozessor haben. Ausserdem haben wir
+statisch kompiliert, um Bibliothek-Probleme zu vermeiden.
+
+@example
+CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
+@end example
+
+Bei Benutzung von egcs funktionierte bei uns die folgende
+Konfigurationszeile:
+
+@example
+CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --disable-shared
+@end example
+
+Einige bekannte Probleme, wenn MySQL auf Linux-Alpha läuft:
+
+@itemize @bullet
+@item
+Das Debuggen von threaded Applikationen wie MySQL funktioniert nicht mit
+@code{gdb 4.18}. Statt dessen sollten Sie gdb 5.0 herunter laden und
+benutzen!
+
+@item
+Wenn Sie versuchen, @code{mysqld} unter Benutzung von @code{gcc} statisch
+zu linken, wird das resultierende Image beim Starten einen Speicherauszug
+(Core Dump) erzeugen. Mit anderen Worten: Benutzen Sie @strong{NICHT}
+@code{--with-mysqld-ldflags=-all-static} mit @code{gcc}.
+@end itemize
+
+
+@node Linux-PowerPC, Linux-MIPS, Linux-Alpha, Linux
+@c German node Linux-PowerPC
+@subsubsection Anmerkungen zu Linux PowerPC
+
+MySQL sollte auf MkLinux mit dem neuesten @code{glibc}-Paket funktionieren
+(getestet mit @code{glibc} 2.0.7).
+
+
+@node Linux-MIPS, Linux-IA64, Linux-PowerPC, Linux
+@c German node Linux-MIPS
+@subsubsection Anmerkungen zu Linux MIPS
+
+Um MySQL auf Qube2 zum Laufen zu bringen (Linux Mips), benötigen Sie die
+neuesten @code{glibc}-Bibliotheken (@code{glibc-2.0.7-29C2} funktioniert
+bekanntermaßen). Ausserdem müssen Sie den @code{egcs}-C++-Kompiler
+(@code{egcs-1.0.2-9}, @code{gcc 2.95.2} oder neuer) benutzen.
+
+
+@node Linux-IA64, , Linux-MIPS, Linux
+@c German node Linux-IA64
+@subsubsection Anmerkungen zu Linux IA64
+
+Um MySQL auf Linux Ia64 zu kompilieren, mussten wir folgendes tun (wir
+vermuten, dass das leichter wird, wenn die neue gcc-Version für ia64
+herausgebracht wird).
+
+Unter Verwendung von @code{gcc-2.9-final}:
+
+@example
+CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charsets=complex
+@end example
+
+Nach @code{make} werden Sie einen Fehler erhalten, dass
+@code{sql/opt_range.cc} nicht kompiliert (interner Kompiler-Fehler). Um das
+zu beheben, gehen Sie ins sql-Verzeichnis und tippen Sie erneut @code{make}
+ein. Kopieren Sie die Kompilierzeile, ändern Sie aber -O2 zu -O0. Die
+Datei sollte nunmehr kompilieren.
+
+Jetzt können Sie folgendes tun:
+
+@example
+cd ..
+make
+make_install
+@end example
+
+und @code{mysqld} sollte lauffähig sein.
+
+Auf Ia64 benutzen die MySQL-Client-Binärdateien gemeinsam genutzte (shared)
+Bibliotheken. Wenn Sie daher unsere Binärdistribution an anderer Stelle als
+@file{/usr/local/mysql} benutzen, müssen Sie entweder
+@file{/etc/ld.so.conf} ändern oder den Pfad zum Verzeichnis hinzufügen, wo
+Sie @file{libmysqlclient.so} haben, und zwar in der
+@code{LD_LIBRARY_PATH}-Umgebungsvariablen.
+
+@xref{Link errors}.
+
+@node Windows, Solaris, Linux, Operating System Specific Notes
+@c German node Windows
+@subsection Anmerkungen zu Windows
+
+Dieser Abschnitt beschreibt Installation und Benutzung von MySQL auf
+Windows. Diese Information steht zusätzlich in der @file{README}-Datei, die
+mit der MySQL-Windows-Distribution mitgeliefert wird.
+
+
+
+@menu
+* Win95 start::
+* NT start::
+* Windows running::
+* Windows and SSH::
+* Windows symbolic links::
+* Windows client compiling::
+* Windows vs Unix::
+@end menu
+
+@node Win95 start, NT start, Windows, Windows
+@c German node Win95-Start
+@subsubsection Wie man MySQL auf Win95 / Win98 startet
+
+MySQL benutzt TCP/IP, um einen Client mit einem Server zu verbinden. (Das
+erlaubt jeder beliebigen Maschine in Ihrem Netzwerk, sich mit Ihrem
+MySQL-Server zu verbinden.) Aus diesem Grund müssen Sie MySQL auf Ihrer
+Maschine installieren, bevor Sie MySQL starten. Sie finden TCP/IP auf Ihrer
+Windows-CD-ROM.
+
+Beachten Sie, dass Sie bei Verwendung eines alten Win95-Releases (zum
+Beispiel OSR2) wahrscheinlich ist, dass Sie ein altes Winsock-Paket haben!
+MySQL erfordert Winsock 2! Sie erhalten das neueste Winsock von
+@uref{http://www.microsoft.com/}. Win98 enthält die neue
+Winsock-2-Bibliothek, deshalb trifft das Gesagte nicht auf Win98 zu.
+
+Um den @code{mysqld}-Server zu starten, öffnen Sie ein MS-DOS-Fenster
+(MS-DOS-Eingabeaufforderung) und geben Sie ein:
+
+@example
+C:\> C:\mysql\bin\mysqld
+@end example
+
+Das startet @code{mysqld} im Hintergrund ohne Fenster.
+
+Sie können den MySQL-Server killen, indem Sie eingeben:
+
+@example
+C:\> C:\mysql\bin\mysqladmin -u root shutdown
+@end example
+
+Beachten Sie, dass Win95 und Win98 die Erzeugung von Named Pipes nicht
+unterstützen. Auf Win95 und Win98 können Sie Named Pipes nur benutzen, um
+sich zu einem entfernten MySQL-Server zu verbinden, der auf einem
+NT-Server-Host läuft. (Natürlich muss auch der MySQL-Server Named Pipes
+unterstützen. Beispielsweise läßt die Verwendung von @code{mysqld-opt}
+unter NT keine Named-Pipe-Verbindungen zu. Sie sollten daher entweder
+@code{mysqld-nt} oder @code{mysqld-max-nt} verwenden.)
+
+Wenn @code{mysqld} nicht startet, überprüfen Sie bitte die
+@file{\mysql\data\mysql.err}-Datei um zu sehen, ob der Server eine Meldung
+ausgegeben hat, die auf die Ursache des Problems hinweist. Sie können auch
+versuchen, den Server mit @code{mysqld --standalone} zu starten. In diesem
+Fall erscheinen vielleicht nützliche Informationen auf dem Bildschirm, die
+Ihnen bei der Lösung des Problems helfen.
+
+Die letzte Option besteht darin, @code{mysqld} mit @code{--standalone
+--debug} zu starten. In diesem Fall schreibt @code{mysqld} eine Log-Datei
+@file{C:\mysqld.trace}, die die Ursache enthalten könnte, warum
+@code{mysqld} nicht startet. @xref{Making trace files}.
+
+
+@node NT start, Windows running, Win95 start, Windows
+@c German node NT-Start
+@subsubsection MySQL auf Windows NT oder Windows 2000 starten
+
+Der Win95-/Win98-Abschnitt trifft auch auf NT/Win2000 zu, mit folgenden
+Unterschieden:
+
+Damit MySQL mit TCP/IP auf NT läuft, müssen Sie Service-Pack 3 (oder neuer)
+installieren!
+
+Beachten Sie, dass alles Folgende, das für NT zutrifft, ebenfalls für
+Win2000 zutrifft!
+
+Für NT/Win2000 ist der Servername @code{mysqld-nt}. Normalerweise sollten
+Sie MySQL auf NT/Win2000 als Systemdienst installieren:
+
+@example
+C:\> C:\mysql\bin\mysqld-nt --install
+@end example
+
+oder
+
+@example
+C:\> C:\mysql\bin\mysqld-max-nt --install
+@end example
+
+(Unter Windows NT können Sie in der Tat jede der Server-Binärdateien als
+Systemdienst installieren, aber nur diejenigen, die Namen haben, die auf
+@code{-nt.exe} enden, bieten Unterstützung für Named Pipes.)
+
+Sie können MySQL mit diesen Befehlen starten und anhalten:
+
+@example
+C:\> NET START mysql
+C:\> NET STOP mysql
+@end example
+
+Beachten Sie, dass Sie in diesem Fall keine weiteren Optionen für
+@code{mysqld-nt} angeben können!
+
+Sie können @code{mysqld-nt} auf NT auch als allein ablaufendes Programm
+(Stand-alone) laufen lassen, wenn Sie @code{mysqld-nt} mit irgend welchen
+Optionen starten wollen! Wenn Sie @code{mysqld-nt} auf NT ohne Optionen
+laufen lassen, versucht @code{mysqld-nt}, sich mit den Vorgabeoptionen als
+Systemdienst zu starten. Wenn Sie @code{mysqld-nt} angehalten haben, müssen
+Sie es mit @code{NET START mysql} neu starten.
+
+Der Systemdienst wird installiert mit dem Namen @code{MySQL}. Einmal
+installiert, muss er mit dem Systemdienst-Steuerungs-Manager (SCM) in der
+Systemsteuerung gestartet werden, oder indem Sie den @code{NET START
+MySQL}-Befehl benutzen. Wenn irgend welche Optionen angegeben werden
+sollen, müssen diese als ``Startparameter'' im SCM-Dienstprogramm angegeben
+werden, bevor Sie den MySQL-Dienst starten. Wenn @code{mysqld-nt} läuft,
+kann er mit @code{mysqladmin} oder dem SCM-Dienstprogramm angehalten werden, oder
+indem Sie den Befehl @code{NET STOP MySQL} benutzen. Wenn Sie SCM benutzen
+@code{mysqld-nt}, um den Server anzuhalten, gibt es eine seltsame Meldung
+von SCM über @code{mysqld shutdown normally}. Wenn er als Systemdienst
+läuft, hat @code{mysqld-nt} keinen Zugriff auf die Konsole. Daher werden
+auch keine Meldungen angezeigt.
+
+Auf NT erhalten Sie möglicherweise folgende Systemdienst-Fehlermeldungen:
+@c Question: Die folgenden deutschen Meldungen auf NT überprüfen!
+@multitable @columnfractions .3 .7
+@item Zugriff verboten @tab Bedeutung: @code{mysqld-nt.exe} kann nicht
+gefunden werden.
+@item Kann nicht registrieren @tab Bedeutung: Der Pfad ist falsch.
+@item Installation des Systemdienstes fehlgeschlagen. @tab Bedeutung: Der
+Systemdienst ist bereits installiert oder der
+Systemdienst-Steuerungs-Manager ist in einem schlechten Zustand.
+@end multitable
+
+Wenn Sie Problem haben, @code{mysqld-nt} als Systemdienst zu installieren,
+versuchen Sie, ihn mit dem vollen Pfad zu installieren:
+
+@example
+C:\> C:\mysql\bin\mysqld-nt --install
+@end example
+
+Wenn das nicht funktioniert, können Sie erreichen, dass @code{mysqld-nt}
+korrekt startet, indem Sie den Pfad in der Registrierung korrigieren!
+
+Wenn Sie nicht wollen, dass @code{mysqld-nt} als Systemdienst startet,
+können Sie ihn wie folgt starten:
+
+@example
+C:\> C:\mysql\bin\mysqld-nt --standalone
+@end example
+
+oder
+
+@example
+C:\> C:\mysql\bin\mysqld --standalone --debug
+@end example
+
+Letztgenanntes gibt Ihnen eine Debug-Spur in @file{C:\mysqld.trace}.
+@xref{Making trace files}.
+
+
+@node Windows running, Windows and SSH, NT start, Windows
+@c German node Laufen lassen auf Windows
+@subsubsection MySQL auf Windows laufen lassen
+
+@cindex TCP/IP
+@cindex Named Pipes
+
+MySQL unterstützt TCP/IP auf allen Windows-Plattformen und Named Pipes auf
+NT. Vorgabemäßig werden Named Pipes für lokale Verbindungen auf NT und TCP/IP für
+alle anderen Fälle benutzt, wenn der Client TCP/IP installiert hat. Der
+Hostname legt fest, welches Protokoll benutzt wird:
+
+@multitable @columnfractions .3 .7
+@strong{Hostname} @tab @strong{Protokoll}
+@item NULL (keiner) @tab Auf NT zuerst Named Pipes versuchen. Wenn das
+nicht funktioniert, TCP/IP benutzen. Auf Win95/Win98 wird TCP/IP benutzt.
+@item . @tab Named Pipes
+@item localhost @tab TCP/IP zum aktuellen Host
+@item hostname @tab TCP/IP
+@end multitable
+
+Sie können erzwingen, dass ein MySQL-Client Named Pipes benutzt, indem Sie
+die @code{--pipe}-Option oder @code{.} als Hostnamen angeben. Benutzen Sie
+die @code{--socket}-Option, um den Namen der Pipe festzulegen.
+
+Sie können feststellen, ob MySQL funktioniert, indem Sie die folgenden
+Befehle eingeben:
+
+@example
+C:\> C:\mysql\bin\mysqlshow
+C:\> C:\mysql\bin\mysqlshow -u root mysql
+C:\> C:\mysql\bin\mysqladmin version status proc
+C:\> C:\mysql\bin\mysql test
+@end example
+
+Wenn @code{mysqld} nur langsam auf Verbindungen auf Win95/Win98 antwortet,
+gibt es wahrscheinlich ein Problem mit Ihrem DNS. Starten Sie in diesem
+Fall @code{mysqld} mit @code{--skip-name-resolve} und benutzen Sie nur
+@code{localhost} und IP-Nummern in den MySQL Berechtigungstabellen. Sie
+können DNS bei einer Verbindung zu einem @code{mysqld-nt}-MySQL-Server, der
+auf NT läuft, ebenfalls dadurch vermeiden, dass Sie das
+@code{--pipe}-Argument verwenden, um die Benutzung von Named Pipes
+festzulegen. Das funktioniert bei den meisten MySQL-Clients.
+
+Es gibt zwei Versionen des MySQL-Kommadozeilen-Werkzeugs:
+@multitable @columnfractions .25 .75
+@item @code{mysql} @tab Kompiliert auf nativem Windows, was sehr
+eingeschränkte Texteditiermöglichkeiten bietet.
+@item @code{mysqlc} @tab Kompiliert mit dem Cygnus-GNU-Kompiler und
+-Bibliotheken, was @code{readline}-Editiermöglichkeit bietet.
+@end multitable
+
+Wenn Sie @code{mysqlc.exe} benutzen wollen, müssen Sie
+@file{C:\mysql\lib\cygwinb19.dll} in Ihr Windows-Systemverzeichnis kopieren
+(@file{\windows\system} oder ein ähnlicher Ort).
+
+Vorgabemäßig geben die Berechtigungen auf Windows allen lokalen Benutzern
+volle Zugriffsrechte auf alle Datenbanken, ohne ein Passwort anzugeben. Um
+MySQL sicherer zu machen, sollten Sie für alle Benutzer ein Passwort setzen
+und die Zeile in der Tabelle @code{mysql.user}, die @code{Host='localhost'}
+und @code{User=''} enthält, löschen.
+
+Sie sollten auch für den @code{root}-Benutzer ein Passwort vergeben. Das
+folgende Beispiel entfernt den anonymen Benutzer, der von jedem genutzt
+werden kann, um auf die @code{test}-Datenbank zuzugreifen und setzt dann
+für den @code{root}-Benutzer ein Passwort:
+
+@example
+C:\> C:\mysql\bin\mysql mysql
+mysql> DELETE FROM user WHERE Host='localhost' AND User='';
+mysql> QUIT
+C:\> C:\mysql\bin\mysqladmin reload
+C:\> C:\mysql\bin\mysqladmin -u root password ihr_passwort
+@end example
+
+Nachdem Sie das Passwort gesetzt haben, sollten Sie den
+@code{mysqld}-Server herunter fahren, was Sie mit folgendem Befehl
+bewerkstelligen können:
+
+@example
+C:\> mysqladmin --user=root --password=ihr_passwort shutdown
+@end example
+
+Wenn Sie die alte Shareware-Version von MySQL-Version 3.21 unter Windows
+benutzen, schlägt der genannte Befehl mit einem Fehler fehl:
+@code{parse error near 'SET OPTION password'}. Die Lösung besteht darin,
+auf die aktuelle MySQL-Version zu aktualisieren, die frei verfügbar ist.
+
+Mit den neuen MySQL-Versionen können Sie auf einfache Art neue Benutzer
+hinzufügen und Zugriffsrechte mit den @code{GRANT}- und
+@code{REVOKE}-Befehlen ändern.
+@xref{GRANT}.
+
+@node Windows and SSH, Windows symbolic links, Windows running, Windows
+@c German node Windows und SSH
+@subsubsection Verbinden mit einem entfernten MySQL-Server von Windows mit SSH aus
+
+@c FIX this ist ugly, real ugly.
+
+@cindex SSH
+@cindex Verbinden, auf entfernte Maschine mit SSH
+
+Hier ist eine Anmerkung dazu, wie man sich über eine sichere Verbindung zu
+einem entfernten MySQL-Server mit SSH verbindet (von David Carlson
+@email{dcarlson@@mplcomm.com}):
+
+@itemize @bullet
+@item
+Installieren Sie einen SSH-Client auf Ihrer Windows-Maschine. Das beste
+nicht kostenlose Werkzeug, das ich gefunden habe, ist @code{SecureCRT} von
+@uref{http://www.vundyke.com/}. Eine andere Option ist @code{f-secure} von
+@uref{http://www.f-secure.com/}. Sie finden kostenlose Werkzeuge über
+@strong{Google} auf
+@uref{http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/}.
+
+@item
+Starten Sie Ihren Windows-SSH-Client.
+Konfigurieren Sie: @code{Host_Name = ihr_mysql_server_URL_oder_IP}.
+Konfigurieren Sie: @code{userid=ihre_userid}, um sich an Ihrem Server
+anzumelden (wahrscheinlich nicht dasselbe wie Ihr MySQL-Benutzername /
+-Passwort).
+
+@item
+Konfigurieren Sie Port-Forwarding. Machen Sie entweder ein Remote Forward
+(einstellen: @code{local_port: 3306}, @code{remote_host:
+ihr_mysql_servername_oder_ip}, @code{remote_port: 3306} ) oder ein lokales
+Forward (einstellen: @code{port: 3306}, @code{host: localhost},
+@code{remote port: 3306}).
+
+@item
+Speichern Sie alles, damit Sie es beim nächsten Mal nicht noch einmal
+eingeben müssen.
+
+@item
+Melden Sie sich an Ihrem Server mit der SSH-Sitzung, die Sie gerade erzeugt
+haben.
+
+@item
+Starten Sie auf Ihrer Windows-Maschine irgend eine Applikation wie Access.
+
+@item
+Erzeugen Sie unter Windows eine neue Datei und stellen Sie eine Verknüpfung
+zu MySQL her, indem Sie den ODBC-Treiber so benutzen, wie Sie es
+normalerweise tun, AUSSER dass Sie @code{localhost} als MySQL-Host-Server
+eingeben - NICHT @code{yourmysqlservername}.
+@end itemize
+
+Jetzt sollten Sie eine ODBC-Verbindung zu MySQL haben, die mit SSH
+verschlüsselt ist.
+
+
+@node Windows symbolic links, Windows client compiling, Windows and SSH, Windows
+@c German node Symbolische Links auf Windows
+@subsubsection Daten auf verschiedenen Platten unter Win32 aufteilen
+
+@cindex Symbolische Links
+@cindex Mehrere Festplatten benutzen, um Daten zu speichern
+@c Question: using multiple disks to start data (should be: store data)
+@cindex Festplatten, Daten verteilen über mehrere
+
+Ab MySQL-Version 3.23.16 werden die @code{mysqld-max}- und
+@code{mysql-max-nt}-Server in der MySQL-Distribution mit der
+@code{-DUSE_SYMDIR}-Option kompiliert. Das gibt Ihnen die Möglichkeit,
+Datenbanken auf verschiedene Festplatten zu verteilen, indem Sie
+symbolische Links darauf machen (in ähnlicher Weise, wie symbolische Links
+unter Unix funktionieren).
+
+Unter Windows legen Sie einen symbolischen Link auf eine Datenbank an,
+indem Sie eine Datei erzeugen, die den Pfad zum Zielverzeichnis enthält,
+und diese Datei im @file{mysql_data}-Verzeichnis unter dem Dateiname
+@file{Datenbank.sym} speichern. Beachten Sie, dass der symbolische Link nur
+dann benutzt wird, wenn das Verzeichnis @file{mysql_data_dir\datenbank}
+nicht existiert.
+
+Wenn Ihr MySQL-Daten-Verzeichnis beispielsweise @file{C:\mysql\data} ist und
+Sie die Datenbank @code{foo} dort haben wollen, die aber in
+@file{D:\data\foo} liegt, erzeugen Sie die Datei
+@file{C:\mysql\data\foo.sym}, die als Text @code{D:\data\foo\} enthält.
+Dann werden alle Tabellen, die in der Datenbank @code{foo} sind, in
+@file{D:\data\foo} erzeugt.
+
+Beachten Sie, dass wir dieses Feature nicht vorgabemäßig aktiviert haben,
+weil es mit Geschwindigkeitsnachteilen verbunden ist. Es ist selbst dann
+nicht aktiviert, wenn Sie MySQL mit Unterstützung dafür kompiliert haben.
+Um symbolische Links zu aktivieren, müssen Sie in Ihre @code{my.cnf}- oder
+@code{my.ini}-Datei folgenden Eintrag machen:
+
+@example
+[mysqld]
+use-symbolic-links
+@end example
+
+In MySQL 4.0 werden symbolische Links vorgabemäßig aktiviert sein. Wenn
+Sie dies deaktivieren wollen, benutzen Sie die @code{skip-symlink}-Option.
+
+
+@node Windows client compiling, Windows vs Unix, Windows symbolic links, Windows
+@c German node Windows kompilieren
+@subsubsection MySQL-Clients auf Windows kompilieren
+
+@cindex Kompilieren, auf Windows
+@cindex Windows, Kompilieren auf
+
+In Ihren Quell-Dateien sollten Sie @file{windows.h} einschließen, bevor
+Sie @file{mysql.h} einschließen:
+
+@example
+#if defined(_WIN32) || defined(_WIN64)
+#include <windows.h>
+#endif
+#include <mysql.h>
+@end example
+
+Sie können Ihren Code entweder mit der dynamischen
+@file{libmysql.lib}-Bibliothek linken, die nur ein Wrapper zum Laden der
+@file{libmysql.dll} bei Bedarf ist, oder mit der statischen
+@file{mysqlclient.lib}-Bibliothek.
+
+Beachten Sie, dass MySQL-Client-Bibliotheken als threaded Bibliotheken
+kompiliert werden, daher sollten Sie auch Ihren Code so kompilieren, dass
+er multi-threaded ist!
+
+
+@node Windows vs Unix, , Windows client compiling, Windows
+@c German node Windows / Unix
+@subsubsection MySQL-Windows im Vergleich zu Unix-MySQL
+
+@cindex Windows, im Vergleich zu Unix
+@cindex Betriebssysteme, Windows im Vergleich zu Unix
+
+MySQL-Windows hat sich mittlerweile als sehr stabil erwiesen. Diese Version
+von MySQL hat dieselben Features wie die entsprechende Unix-Version,
+allerdings mit folgenden Ausnahmen:
+
+@table @strong
+@item Windows 95 und Threads
+Windows 95 hat ein etwa 200 Bytes großes Hauptspeicher-Leck (Memory Leak) für
+jede Thread-Erzeugung. Jede Verbindung zu MySQL erzeugt eine neues Thread,
+daher sollten Sie @code{mysqld} nicht für längere Zeiträume auf Windows 95
+laufen lassen, wenn Ihr Server viele Verbindungen handhabt! Windows NT und
+Windows 98 haben diesen Bug nicht.
+
+@item Gleichzeitige Lesezugriffe
+MySQL vertraut auf @code{pread()}- und @code{pwrite()}-Aufrufe, um in der
+Lage zu sein, @code{INSERT} und @code{SELECT} zu mischen. Momentan benutzen
+wir mutexes, um @code{pread()} / @code{pwrite()} zu emulieren. Langfristig
+werden wir die Dateiebenen-Schnittstelle durch eine virtuelle Schnittstelle
+ersetzen, um die @code{readfile()}- / @code{writefile()}-Schnittstelle auf
+NT mit höherer Geschwindigkeit benutzen zu können.
+Die aktuelle Implementation begrenzt die Anzahl offener Dateien, die MySQL
+benutzen kann, auf 1024, was bedeutet, dass Sie nicht so viele
+gleichzeitige Threads auf NT benutzen können wie auf Unix.
+
+@item Blockierendes Lesen
+MySQL benutzt blockierendes Lesen (Blocking Read) für jede Verbindung. Das
+bedeutet in der Anwendung:
+
+@itemize @bullet
+@item
+Eine Verbindung wird nicht automatisch nach 8 Stunden abgebaut, wie es
+unter der Unix-Version von MySQL der Fall ist.
+
+@item
+Wenn eine Verbindung hängen bleibt, ist es unmöglich, sie abzubrechen, ohne
+MySQL zu killen.
+
+@item
+@code{mysqladmin kill} funktioniert nicht für schlafende Verbindungen.
+
+@item
+@code{mysqladmin shutdown} kann nicht abgebrochen werden, solange es noch
+schlafende Verbindungen gibt.
+@end itemize
+
+Geplant ist, dieses Problem zu beheben, sobald unsere Windows-Entwickler
+ein nettes Workaround heraus gefunden haben.
+
+@item UDF-Funktionen
+Momentan unterstützt MySQL-Windows keine benutzerdefinierten Funktionen
+(UDF, user defined functions).
+
+@item @code{DROP DATABASE}
+Sie können keine Datenbank löschen, die durch irgend einen Thread in
+Benutzung ist.
+
+@item MySQL vom Task-Manager aus killen
+Sie können MySQL nicht vom Task-Manager oder mit dem Shutdown-Dienstprogramm unter
+Windows 95 killen. Sie müssen es mit @code{mysqladmin shutdown} herunter
+fahren.
+
+@item Von Groß-/Kleinschreibung unabhängige Namen
+Unter Windows sind Dateinamen unabhängig von der Groß-/Kleinschreibung.
+Daher sind Datenbank- und Tabellennamen in MySQL für Windows ebenfalls
+unabhängig von der Groß-/Kleinschreibung. Die einzige Einschränkung ist
+die, dass Datenbank- und Tabellennamen innerhalb eines bestimmten
+Statements dieselbe Groß-/Kleinschreibung haben müssen.
+@xref{Case sensitivity}.
+
+@item Das @samp{\}-Verzeichnis-Zeichen
+Bestandteile von Pfadnamen werden unter Windows mit dem @samp{\}-Zeichen
+getrennt, das in MySQL als Fluchtzeichen (Escape Character) dient. Wenn Sie
+@code{LOAD DATA INFILE} oder @code{SELECT ... INTO OUTFILE} benutzen,
+müssen Sie @samp{\} an solchen Stellen doppelt eingeben:
+
+@example
+mysql> LOAD DATA INFILE "C:\\tmp\\skr.txt" INTO TABLE skr;
+mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;
+@end example
+
+Alternativ können Sie auch Dateinamen im Unix-Stil mit @samp{/}-Zeichen
+benutzen:
+
+@example
+mysql> LOAD DATA INFILE "C:/tmp/skr.txt" INTO TABLE skr;
+mysql> SELECT * INTO OUTFILE 'C:/tmp/skr.txt' FROM skr;
+@end example
+
+@item @code{Can't open named pipe}-Fehler
+Wenn Sie MySQL-Version 3.22 auf NT mit den neuesten MySQL-Clients benutzen,
+erhalten Sie folgende Fehlermeldung:
+
+@example
+error 2017: can't open named pipe to host: . pipe...
+@end example
+
+@tindex .my.cnf Datei
+Das liegt daran, dass die MySQL-Version für NT auf NT vorgabemäßig Named
+Pipes benutzt. Sie können diesen Fehler vermeiden, indem Sie bei den neuen
+MySQL-Clients die @code{--host=localhost}-Option benutzen oder eine
+Optionsdatei @file{C:\my.cnf} anlegen, die folgendes enthält:
+
+@example
+[client]
+host = localhost
+@end example
+
+@item @code{Access denied for user}-Fehler
+Wenn Sie den Fehler @code{Access denied for user: 'ein-benutzer@@unknown'
+to database 'mysql'} erhalten, wenn Sie auf einen MySQL-Server auf
+derselben Maschine zugreifen, heißt das, dass MySQL Ihren Hostnamen nicht
+richtig auflösen kann.
+
+Um das zu beheben, legen Sie eine Datei @file{\windows\hosts} mit folgender
+Zeile an:
+
+@example
+127.0.0.1 localhost
+@end example
+
+@item @code{ALTER TABLE}
+Wenn Sie ein @code{ALTER TABLE}-Statement ausführen, ist die Tabelle gegen
+Benutzung durch andere Threads gesperrt. Das hat damit zu tun, dass Sie
+unter Windows keine Datei löschen können, die durch andere Threads in
+Benutzung ist. (Zukünftig finden wir möglicherweise einen Weg, dieses
+Problem zu umgehen.)
+
+@item @code{DROP TABLE} auf eine Tabelle, die durch eine
+@code{MERGE}-Tabelle in Benutzung ist, funktioniert nicht. Der
+@code{MERGE}-Handler führt sein Tabellen-Mapping versteckt vor MySQL durch.
+Weil Windows das Löschen von Dateien verbietet, die offen sind, müssen Sie
+zuerst alle @code{MERGE}-Tabellen flushen (mit @code{FLUSH TABLES}) oder
+die @code{MERGE}-Tabelle löschen, bevor Sie die Tabelle löschen. Wir werden
+das zusammen mit der Einführung von Sichten (@code{VIEW}s) beheben.
+@end table
+
+Hier sind einige Themen für diejenigen, die uns beim Windows-Release helfen
+wollen:
+
+@cindex Windows, offene Fragen
+
+@itemize @bullet
+@item
+Einen Ein-Benutzer-Server @code{MYSQL.DLL} herstellen. Das könnte alles
+beinhalten, was einen Standard-Server ausmacht, ausser Thread-Erzeugung.
+Das würde es erheblich erleichtern, MySQL in Applikationen zu benutzen, die
+keinen echten Client/Server und keinen Zugriff auf den Server von anderen
+Hosts benötigen.
+
+@item
+Ein paar nette Start- und Stop-Icons zur MySQL-Installation hinzufügen.
+
+@item
+Ein Werkzeug bauen, das Registrierungseinträge für die MySQL-Startoptionen
+handhabt. Das Lesen der Registrierungseinträge ist bereits in
+@file{mysqld.cc} kodiert, sollte aber umgeschrieben werden, damit es mehr
+Parameter-orientiert ist. Das Werkzeug sollte auch in der Lage sein, die
+@file{C:\my.cnf}-Optionsdatei zu aktualisieren, wenn der Benutzer diese
+lieber als die Registrierungsdatei benutzen will.
+
+@item
+Wenn man @code{mysqld} als Systemdienst mit @code{--install} (auf NT)
+installiert, wäre es nett, wenn man vorgabemäßige Optionen auf der
+Kommandozeile hinzufügen könnte. Im Moment muss man diese fehlende
+Möglichkeit durch eine Liste der Parameter in der @file{C:\my.cnf}-Datei
+ersetzen.
+
+@item
+Es wäre eine feine Sache, wenn man @code{mysqld} vom Task-Manager aus
+killen könnte. Momentan muss man @code{mysqladmin shutdown} benutzen.
+
+@item
+@code{readline} auf Windows portieren, damit es im
+@code{mysql}-Kommandozeilen-Werkzeug benutzt werden kann.
+
+@item
+GUI-Versionen der Standard-MySQL-Clients (@code{mysql},
+@code{mysqlshow}, @code{mysqladmin} und @code{mysqldump}) wären nett.
+
+@item
+Nett wäre auch, wenn die Socket-Lese- und Schreib-Funktionen in
+@file{net.c} unterbrechbar wären. Das würde es ermöglichen, offen Threads
+mit @code{mysqladmin kill} auf Windows zu killen.
+
+@item
+@c Question: Is it my lack of English or why don't I understand the
+following two lines?
+@code{mysqld} always starts in the "C" locale und not in the default locale.
+We would like to have @code{mysqld} use the current locale für the sort order.
+
+@item
+Benutzerdefinierte Funktionen (UDF) mit @code{.DLL}s implementieren.
+
+@item
+Makros hinzufügen, um die schnelleren, Thread-sicheren
+Inkrementierungs-/Dekrementierungsmethoden nutzen zu können, die Windows
+bietet.
+
+@end itemize
+
+Weitere Windows-spezifische Themen sind in der @file{README}-Datei
+beschrieben, die mit der MySQL-Windows-Distribution ausgeliefert wird.
+
+
+@node Solaris, BSD Notes, Windows, Operating System Specific Notes
+@c German node Solaris
+@subsection Anmerkungen zu Solaris
+
+@cindex Installationsprobleme auf Solaris
+@cindex Probleme, Installation auf Solaris
+@cindex Tar, Probleme auf Solaris
+@cindex Fehler, Verzeichnisprüfsumme
+@cindex Prüfsummenfehler
+
+Auf Solaris bekommen Sie vielleicht schon Probleme, bevor Sie überhaupt
+Ihre MySQL-Distribution entpackt haben! Solaris-@code{tar} kann nicht mit
+langen Dateinamen umgehen. Daher sehen Sie vielleicht einen Fehler wie den
+folgenden, wenn Sie MySQL entpacken:
+
+@example
+x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2,informix,ms-sql,mysql,oracle,solid,sybase, 0 Bytes, 0 tape blocks
+tar: directory checksum error (Verzeichnis-Prüfsummenfehler)
+@end example
+
+In diesem Fall müssen Sie GNU-@code{tar} (@code{gtar}) benutzen, um die
+Distribution zu entpacken. Sie finden eine vorkompilierte Version für
+Solaris auf @uref{http://www.mysql.com/downloads/}.
+
+Native Sun-Threads funktinieren nur auf Solaris 2.5 und höher. Auf 2.4 und
+früher benutzt MySQL automatisch MIT-pThreads.
+@xref{MIT-pthreads}.
+
+Vielleicht erhalten Sie von configure folgenden Fehler:
+
+@example
+checking for restartable system calls... configure: error can not run test
+programs while cross compiling
+@end example
+
+Das bedeutet, dass mit Ihrer Kompiler-Installation etwas nicht stimmt! In
+diesem Fall sollten Sie Ihren Kompiler auf eine neuere Version
+aktualisieren. Eventuell sind Sie in der Lage, das Problem zu lösen, indem
+Sie folgende Zeile in die @file{config.cache}-Datei einfügen:
+
+@example
+ac_cv_sys_restartable_syscalls=$@{ac_cv_sys_restartable_syscalls='no'@}
+@end example
+
+Wenn Sie Solaris auf einer SPARC benutzen, ist der empfohlene Kompiler
+@code{gcc} 2.95.2. Sie finden ihn auf @uref{http://gcc.gnu.org/}.
+Beachten Sie, dass @code{egcs} 1.1.1 und @code{gcc} 2.8.1 auf SPARC nicht
+zuverlässig laufen!
+
+Die empfohlene @code{configure}-Zeile ist bei der Benutzung von @code{gcc}
+2.95.2:
+
+@example
+CC=gcc CFLAGS="-O3" \
+CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" \
+./configure --prefix=/usr/local/mysql --with-low-memory --enable-assembler
+@end example
+
+Wenn Sie eine Ultra-Sparc haben, erhalten Sie 4 % mehr Performance, wenn
+Sie "-mcpu=v8 -Wa,-xarch=v8plusa" zu CFLAGS und CXXFLAGS hinzufügen.
+
+Wenn Sie einen Sun Workshop (Fortre) 5.3 (oder neueren) Kompiler haben,
+können Sie @code{configure} wie folgt laufen lassen:
+
+@example
+CC=cc CFLAGS="-Xa -fast -xO4 -native -xstrconst -mt" \
+CXX=CC CXXFLAGS="-noex -xO4 -mt" \
+./configure --prefix=/usr/local/mysql --enable-assembler
+@end example
+
+In den MySQL-Benchmarks haben wir auf einer Ultra-Sparc 6%
+Geschwindigkeitssteigerung erreicht, wenn wir Sun Workshop 5.3 benutzen, im
+Vergleich mit der Benutzung von gcc mit -mcpu-Flags.
+
+Wenn Sie Probleme mit @code{fdatasync} oder @code{sched_yield} bekommen,
+können Sie diese beheben, indem Sie @code{LIBS=-lrt} zur
+Konfigurationszeile hinzufügen.
+
+Der folgende Absatz ist nur für ältere Kompiler als WorkShop 5.3 relevant:
+
+Eventuell müssen Sie auch das @code{configure}-Skript editieren und
+folgende Zeile ändern:
+
+@example
+#if !defined(__STDC__) || __STDC__ != 1
+@end example
+
+Ändern zu:
+
+@example
+#if !defined(__STDC__)
+@end example
+
+Wenn Sie @code{__STDC__} mit der @code{-Xc}-Option anschalten, kann der
+Sun-Kompiler nicht mit der Solaris-@file{pThread.h}-Header-Datei
+kompilieren. Das ist ein Bug von Sun (Kompiler-Problem oder beschädigte
+Include-Datei).
+
+Wenn @code{mysqld} beim Laufenlassen eine Fehlermeldung wie die unten
+stehende ausgibt, haben Sie versucht, MySQL mit dem Sun-Kompiler zu
+kompilieren, ohne die Multi-Thread-Option (@code{-mt}) anzuschalten:
+
+@example
+libc internal error: _rmutex_unlock: rmutex not held
+@end example
+
+Fügen Sie @code{-mt} zu @code{CFLAGS} und @code{CXXFLAGS} hinzu und
+versuchen Sie es noch einmal.
+
+Wenn Sie folgenden Fehler beim Kompilieren von MySQL mit @code{gcc}
+erhalten, ist Ihr @code{gcc} nicht für Ihre Version von Solaris
+konfiguriert:
+
+@example
+shell> gcc -O3 -g -O2 -DDBUG_OFF -o thr_alarm ...
+./thr_alarm.c: In function `signal_hand':
+./thr_alarm.c:556: too many arguments to function `sigwait'
+@end example
+
+Die einzige richtige Möglichkeit in diesem Fall ist, sich die neueste
+Version von @code{gcc} zu besorgen und Sie mit Ihrem aktuellen
+@code{gcc}-Kompiler zu kompilieren. Zumindest auf Solaris 2.5 haben fast
+alle Binärversionen von @code{gcc} alte, unbrauchbare Include-Dateien, die
+alle Programme beschädigen, die Threads benutzen (und möglicherweise auch
+andere Programme)!
+
+Solaris stellt keine statischen Versionen aller Systembibliotheken zur
+Verfügung (@code{libpThreads} und @code{libdl}). Daher können Sie MySQL
+nicht mit @code{--static} kompilieren. Wenn Sie es dennoch versuchen,
+erhalten Sie folgenden Fehler:
+
+@example
+ld: fatal: library -ldl: not found
+
+oder
+
+undefined reference to `dlopen'
+
+oder
+
+cannot find -lrt
+@end example
+
+Wenn zu viele Prozesse zu schnell hintereinander versuchen, sich mit
+@code{mysqld} zu verbinden, werden Sie folgenden Fehler im MySQL-Log sehen:
+
+@example
+Error in accept: Protocol error
+@end example
+
+Als Workaround können Sie versuchen, den Server mit der
+@code{--set-variable back_log=50}-Option zu starten. @xref{Command-line options}.
+
+Wenn Sie Ihren eigenen MySQL-Client linken, erhalten Sie möglicherweise
+folgenden Fehler, wenn Sie versuchen, ihn auszuführen:
+
+@example
+ld.so.1: ./my: fatal: libmysqlclient.so.#: open failed: No such file or directory
+@end example
+
+Dieses Problem kann mit einer der folgenden Methoden vermieden werden:
+
+@itemize @bullet
+@item
+Linken Sie den Client mit folgendem Flag (anstelle von @code{-Lpath}):
+@code{-Wl,r/full-path-to-libmysqlclient.so}.
+
+@item
+Kopieren Sie @file{libmysqclient.so} nach @file{/usr/lib}.
+
+@tindex LD_RUN_PATH-Umgebungsvariable
+@tindex Umgebungsvariable, LD_RUN_PATH
+@item
+Fügen Sie den Pfadnamen des Verzeichnisses, wo @file{libmysqlclient.so}
+liegt, der @code{LD_RUN_PATH}-Umgebungsvariablen hinzu, bevor Sie Ihren
+Client laufen lassen.
+@end itemize
+
+Wenn Sie die @code{--with-libwrap}-configure-Option benutzen, müssen Sie
+auch die Bibliotheken einschließen, die @file{libwrap.a} benötigt:
+
+@example
+--with-libwrap="/opt/NUtcpwrapper-7.6/lib/libwrap.a -lnsl -lsocket
+@end example
+
+Wenn Sie Probleme mit configure haben, wenn Sie versuchen, mit @code{-lz}
+zu linken und keine @code{zlib} installiert haben, haben Sie zwei
+Möglichkeiten:
+
+@itemize @bullet
+@item
+Wenn Sie in der Lage sein wollen, dass komprimierte Kommunikationsprotokoll
+zu benutzen, müssen Sie zlib von ftp.gnu.org laden und installieren.
+
+@item
+Konfigurieren Sie mit @code{--with-named-z-libs=no}.
+@end itemize
+
+Wenn Sie gcc benutzen und Probleme mit dem Laden von @code{UDF}-Funktionen
+in MySQL haben, versuchen Sie, @code{-lgcc} zur Link-Zeile für die
+@code{UDF}-Funktion hinzuzufügen.
+
+Wenn Sie wollen, dass MySQL automatisch startet, kopieren Sie
+@file{Support-files/mysql.server} nach @file{/etc/init.d} und erzeugen Sie
+einen symbolischen Link darauf, den Sie @file{/etc/rc3.d/S99mysql.server}
+nennen.
+
+
+
+
+@menu
+* Solaris 2.7::
+* Solaris x86::
+@end menu
+
+@node Solaris 2.7, Solaris x86, Solaris, Solaris
+@c German node Solaris 2.7
+@subsubsection Anmerkungen zu Solaris 2.7/2.8
+
+Normalerweise können Sie eine Solaris-2.6-Binärdatei für Solaris 2.7 und
+2.8 benutzen. Die meisten Dinge, die Solaris 2.6 betreffen, treffen auch
+für Solaris 2.7 und 2.8 zu.
+
+Beachten Sie, dass MySQL-Version 3.23.4 und höher in der Lage sein sollte,
+automatisch neue Versionen von Solaris zu erkennen und Workarounds für die
+folgenden Probleme zu aktivieren!
+
+Solaris 2.7 / 2.8 hat einige Bugs in den Include-Dateien. Eventuell sehen
+Sie folgenden Fehler, wenn Sie @code{gcc} benutzen:
+
+@example
+/usr/include/widec.h:42: warning: `getwc' redefined
+/usr/include/wchar.h:326: warning: this is the location of the previous
+definition
+@end example
+
+Wenn das auftritt, können Sie folgendes tun, um das Problem zu lösen:
+
+Kopieren Sie @code{/usr/include/widec.h} nach
+@code{.../lib/gcc-lib/os/gcc-version/include} und ändern Sie Zeile 41 von:
+
+@example
+#if !defined(lint) && !defined(__lint)
+
+nach
+
+#if !defined(lint) && !defined(__lint) && !defined(getwc)
+@end example
+
+Alternativ können Sie @file{/usr/include/widec.h} direkt editieren. Egal,
+wie Sie vorgehen: Nachdem Sie die Fehlerbehebung durchgeführt haben,
+sollten Sie @file{config.cache} entfernen und @code{configure} noch einmal
+laufen lassen!
+
+Wenn Sie beim Laufenlassen von @code{make} folgende Fehler bekommen, liegt
+das daran, dass @code{configure} die @file{curses.h}-Datei nicht erkannte
+(vermutlich aufgrund des Fehlers in @file{/usr/include/widec.h}):
+
+@example
+In file included by mysql.cc:50:
+/usr/include/term.h:1060: syntax error before `,'
+/usr/include/term.h:1081: syntax error before `;'
+@end example
+
+Das Problem lösen Sie auf eine der folgenden Weisen:
+
+@itemize @bullet
+@item
+Konfigurieren Sie mit @code{CFLAGS=-DHAVE_CURSES_H CXXFLAGS=-DHAVE_CURSES_H ./configure}.
+
+@item
+Editieren Sie @file{/usr/include/widec.h}, wie weiter oben gezeigt, und
+lassen Sie configure noch einmal laufen.
+
+@item
+Entfernen Sie die @code{#define HAVE_TERM}-Zeile aus der
+@file{config.h}-Datei und lassen Sie @code{make} noch einmal laufen.
+@end itemize
+
+Wenn Sie das Problem bekommen, dass Ihr Linker @code{-lz} nicht finden
+kann, wenn Sie Ihr Client-Programm linken, liegt das wahrscheinlich daran,
+dass Ihre @file{libz.so}-Datei in @file{/usr/local/lib} installiert ist.
+Sie können das mit einer der folgenden Methoden beheben:
+
+@itemize @bullet
+@item
+Fügen Sie @file{/usr/local/lib} zu @code{LD_LIBRARY_PATH} hinzu.
+
+@item
+Fügen Sie einen Link auf @file{libz.so} von @file{/lib} hinzu.
+
+@item
+Wenn Sie Solaris 8 benutzen, können Sie die optionale zlib aus Ihrer
+Solaris-8-CD-Distribution installieren.
+
+@item
+Konfigurieren Sie MySQL mit der @code{--with-named-z-libs=no}-Option.
+@end itemize
+
+
+@node Solaris x86, , Solaris 2.7, Solaris
+@c German node Solaris x86
+@subsubsection Anmerkungen zu Solaris x86
+
+Auf Solaris 2.8 auf x86 erzeugt @code{mysqld} einen Speicherauszug (Core
+Dump), wenn Sie darin 'strip' laufen lassen.
+
+Wenn Sie @code{gcc} oder @code{egcs} auf Solaris x86 benutzen und Probleme
+mit Speicherauszügen (Core Dumps) unter Last erleben, sollten Sie folgenden
+@code{configure}-Befehl benutzen:
+
+@example
+CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
+CXX=gcc \
+CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
+./configure --prefix=/usr/local/mysql
+@end example
+
+Das vermeidet Probleme mit der @code{libstdc++}-Bibliothek und mit
+C++-Ausnahmefehlern.
+
+Wenn das nicht hilft, sollten Sie eine Debug-Version kompilieren und sie
+mit einer Trace-Datei oder unter @code{gdb} laufen lassen. @xref{Using gdb on mysqld}.
+
+
+@node BSD Notes, Mac OS X, Solaris, Operating System Specific Notes
+@c German node BSD
+@subsection Anmerkungen zu BSD
+
+
+
+@menu
+* FreeBSD::
+* NetBSD::
+* OpenBSD::
+* OpenBSD 2.5::
+* OpenBSD 2.8::
+* BSDI::
+* BSDI2::
+* BSDI3::
+* BSDI4::
+@end menu
+
+@node FreeBSD, NetBSD, BSD Notes, BSD Notes
+@c German node FreeBSD
+@subsubsection Anmerkungen zu FreeBSD
+
+FreeBSD 3.x wird für MySQL empfohlen, weil das Thread-Paket sehr viel
+integrierter ist.
+
+Die einfachste und daher empfohlene Art der Installation ist die Benutzung
+der mysql-server- und mysql-client-Ports, die auf
+@uref{http://www.freebsd.org} verfügbar sind.
+
+Durch deren Benutzung erhalten Sie:
+@itemize @bullet
+@item
+Ein funktionierendes MySQL mit allen Optimierungen bereits aktiviert, von
+denen bekannt ist, dass Sie auf Ihrer Version von FreeBSD funktionieren.
+
+@item
+Automatische Konfiguration, automatisches Build.
+
+@item
+Start-Skripte, die in /usr/local/etc/rc.d installiert werden.
+
+@item
+Die Möglichkeit festzustellen, welche Dateien installiert sind, mit
+pkg_info -L. Und die Möglichkeit, sie mit pkg_delete zu entfernen, wenn Sie
+MySQL nicht mehr auf dieser Maschine haben wollen.
+@end itemize
+
+Empfohlen wird die Benutzung von MIT-pThreads auf FreeBSD 2.x und von
+nativen Threads auf Version 3 und höher. Es ist möglich, auf einigen späten
+2.2.x-Versionen mit nativen Threads zu arbeiten, aber Sie können beim
+Herunterfahren von @code{mysqld} Probleme bekommen.
+
+Die MySQL-@file{Makefile}-Dateien erfordern GNU-make (@code{gmake}). Wenn
+Sie MySQL kompilieren wollen, müssen Sie zuerst GNU-@code{make}
+installieren.
+
+Stellen Sie sicher, dass Ihr Namensauflöser (Name Resolver) korrekt
+eingerichtet ist. Ansonsten erleben Sie vielleicht Resolver-Verzögerungen
+oder -Fehler, wenn Sie sich mit @code{mysqld} verbinden.
+
+Stellen Sie sicher, dass der @code{localhost}-Eintrag in der
+@file{/etc/hosts}-Datei stimmt. Ansonsten werden Sie Probleme haben, sich
+mit der Datenbank zu verbinden. Die @file{/etc/hosts}-Datei sollte mit
+folgender Zeile beginnen:
+
+@example
+127.0.0.1 localhost localhost.ihre.domain
+@end example
+
+Wenn Sie bemerken, dass @code{configure} MIT-pThreads benutzen wird, lesen
+Sie die Anmerkungen zu MIT-pThreads. @xref{MIT-pthreads}.
+
+Wenn @code{make install} meldet, dass es @file{/usr/include/pThreads} nicht
+finden kann, hat @code{configure} nicht entdeckt, dass Sie MIT-pThreads
+benötigen. Das kann durch die Ausführung folgender Befehle behoben werden:
+
+@example
+shell> rm config.cache
+shell> ./configure --with-mit-threads
+@end example
+
+FreeBSD ist dafür bekannt, dass es vorgabemäßig einen sehr niedrigen Wert
+für Datei-Handles eingestellt hat. @xref{Not enough file handles}.
+Kommentieren Sie den Abschnitt ulimit -n section in safe_mysqld aus oder
+erhöhen Sie die Werte für den @code{mysqld}-Benutzer in /etc/login.conf
+(und bauen Sie es neu mit cap_mkdb /etc/login.conf). Stellen Sie ausserdem
+sicher, dass Sie die korrekte Klasse für diesen Benutzer in der
+Passwort-Datei einstellen, wenn Sie nicht den Vorgabewert benutzen
+(benutzen Sie chpass mysqld-user-name). @xref{safe_mysqld,
+,@code{safe_mysqld}}.
+
+Wenn Sie Probleme mit dem aktuellen Datum in MySQL erhalten, wird das
+Setzen der @code{TZ}-Variablen das wahrscheinlich beheben.
+@xref{Environment variables}.
+
+Um ein sicheres, stabiles System zu erhalten, sollten Sie ausschließlich
+FreeBSD-Kernels benutzen, die als @code{-STABLE} markiert sind.
+
+
+@node NetBSD, OpenBSD, FreeBSD, BSD Notes
+@c German node NetBSD
+@subsubsection Anmerkungen zu NetBSD
+
+Um auf NetBSD zu kompilieren, benötigen Sie GNU @code{make}. Ansonsten wird
+das Kompilieren abstürzen, wenn @code{make} versucht, @code{lint} auf
+C++Dateien laufen zu lassen.
+
+
+@node OpenBSD, OpenBSD 2.5, NetBSD, BSD Notes
+@c German node OpenBSD
+@subsubsection Anmerkungen zu OpenBSD
+
+
+
+@node OpenBSD 2.5, OpenBSD 2.8, OpenBSD, BSD Notes
+@c German node <no English equivalent>
+@subsubsection Anmerkungen zu OpenBSD 2.5
+
+Auf OpenBSD-Version 2.5 können Sie MySQL mit nativen Threads mit folgenden
+Optionen kompilieren:
+
+@example
+CFLAGS=-pThread CXXFLAGS=-pThread ./configure --with-mit-threads=no
+@end example
+
+
+@node OpenBSD 2.8, BSDI, OpenBSD 2.5, BSD Notes
+@c German node OpenBSD 2.8
+@subsubsection Anmerkungen zu OpenBSD 2.8
+
+Unsere Benutzer haben berichtet, dass OpenBSD 2.8 einen Thread-Bug hat, der
+Probleme mit MySQL verursacht. Die OpenBSD-Entwickler haben das Problem
+behoben, aber seit dem 25. Januar 2001 ist es nur im ``-current''-Zweig
+verfügbar. Die Symptome dieses Thread-Bugs sind langsames Antworten, hohe
+Lase, hohe Prozessorauslastung und Abstürze.
+
+
+@node BSDI, BSDI2, OpenBSD 2.8, BSD Notes
+@c German node BSDI
+@subsubsection Anmerkungen zu BSD/OS
+
+
+
+@node BSDI2, BSDI3, BSDI, BSD Notes
+@c German node <no English equivalent>
+@subsubsection Anmerkungen zu BSD/OS Version 2.x
+
+Wenn Sie folgenden Fehler beim Kompilieren von MySQL erhalten, ist Ihr
+@code{ulimit}-Wert für virtuellen Speicher zu niedrig:
+
+@example
+item_func.h: In method `Item_func_ge::Item_func_ge(const Item_func_ge &)':
+item_func.h:28: virtual memory exhausted
+make[2]: *** [item_func.o] Error 1
+@end example
+
+Versuchen Sie, @code{ulimit -v 80000} zu benutzen, und lassen Sie
+@code{make} erneut laufen. Wenn das nicht funktioniert und Sie @code{bash}
+benutzen, versuchen Sie, statt dessen @code{csh} oder @code{sh} zu
+benutzen. Einige BSDI-Benutzer haben Probleme mit @code{bash} und
+@code{ulimit} berichtet.
+
+Wenn Sie @code{gcc} benutzen, müssen Sie eventuell auch den
+@code{--with-low-memory}-Flag für @code{configure} benutzen, um in der Lage
+zu sein, @file{sql_yacc.cc} zu kompilieren.
+
+Wenn Sie Probleme mit dem aktuellen Datum in MySQL erhalten, wird das
+Setzen der @code{TZ}-Variablen das wahrscheinlich beheben.
+@xref{Environment variables}.
+
+@node BSDI3, BSDI4, BSDI2, BSD Notes
+@c German node BSDI3
+@subsubsection Anmerkungen zu BSD/OS Version 3.x
+
+Aktualisieren Sie auf BSD/OS Version 3.1. Wenn das nicht möglich ist,
+installieren Sie BSDI-Patch M300-038.
+
+Benutzen Sie zur Konfiguration von MySQL folgenden Befehl:
+
+@example
+shell> env CXX=shlicc++ CC=shlicc2 \
+ ./configure \
+ --prefix=/usr/local/mysql \
+ --localstatedir=/var/mysql \
+ --without-perl \
+ --with-unix-socket-path=/var/mysql/mysql.sock
+@end example
+
+Folgendes funktioniert bekanntermaßen ebenfalls:
+
+@example
+shell> env CC=gcc CXX=gcc CXXFLAGS=-O3 \
+ ./configure \
+ --prefix=/usr/local/mysql \
+ --with-unix-socket-path=/var/mysql/mysql.sock
+@end example
+
+Wenn Sie wollen, können Sie die Verzeichnisorte ändern oder aber die
+Vorgabewerte benutzen, indem Sie einfach keine Speicherorte angeben.
+
+Wenn Sie Performance-Probleme unter Hochlast bekommen, versuchen Sie die
+@code{--skip-thread-priority}-Option für @code{mysqld}! Dies führt alle
+Threads mit derselben Priorität aus. Auf BSDI-Version 3.1 gibt Ihnen das
+bessere Performance (zumindest solange, bis BSDI ihren Thread-Scheduler in
+Ordnung bringt).
+
+Wenn Sie beim Kompilieren den Fehler @code{virtual memory exhausted}
+erhalten, probieren Sie es mit @code{ulimit -v 80000} und lassen Sie
+@code{make} noch einmal laufen. Wenn das nicht funktioniert und Sie
+@code{bash} benutzen, versuchen Sie, statt dessen @code{csh} oder @code{sh}
+zu benutzen. Einige BSDI-Benutzer haben Probleme mit @code{bash} und
+@code{ulimit} berichtet.
+
+
+@node BSDI4, , BSDI3, BSD Notes
+@c German node BSDI4
+@subsubsection Anmerkungen zu BSD/OS Version 4.x
+
+BSDI-Version 4.x hat einige auf Threads bezogene Bugs. Wenn Sie auf dieser
+Plattform MySQL benutzen wollen, sollten Sie alle Patches installieren, die
+sich auf Threads beziehen. Zumindest M400-023 sollte installiert sein.
+
+Auf einigen Systemen mit BSDI-Version 4.x bekommen Sie vielleicht Probleme
+mit gemeinsam verwendeten (shared) Bibliotheken. Das äußert sich darin,
+dass Sie keinerlei Client-Programme wie @code{mysqladmin} ausführen können.
+In diesem Fall müssen Sie MySQL so rekonfigurieren, dass keine gemeinsam
+genutzten Bibliotheken benutzt werden, indem Sie die
+@code{--disable-shared}-Option für configure benutzen.
+
+Einige Kunden hatten auf BSDI 4.0.1 Probleme damit, dass die
+@code{mysqld}-Binärdatei nach einiger Zeit keine Tabellen mehr öffnen
+konnte. Das liegt an einigen Bugs, die sich auf Bibliothek / System
+beziehen, und die @code{mysqld} veranlassen, das aktuelle Verzeichnis zu
+wechseln, ohne danach gefragt zu haben!
+
+Die Lösung besteht darin, entweder auf 3.23.34 zu aktualisieren oder nach
+dem Laufenlassen von @code{configure} die Zeile @code{#define
+HAVE_REALPATH} aus @code{config.h} zu entfernen, bevor Sie make laufen
+lassen.
+
+Beachten Sie, dass sich aus dem Gesagten ergibt, dass Sie auf BSDI keine
+symbolischen Links von Datenbankverzeichnissen zu einem anderen
+Datenbankverzeichnis oder symbolische Links von einer Tabelle zu einer
+anderen Datenbank herstellen können! (Ein symbolischer Link auf eine andere
+Platte ist okay.)
+
+
+@node Mac OS X, Other Unix Notes, BSD Notes, Operating System Specific Notes
+@c German node Mac OS X
+@subsection Anmerkungen zu Mac OS X
+
+
+
+@menu
+* Mac OS X Public Beta::
+* Mac OS X Server::
+@end menu
+
+@node Mac OS X Public Beta, Mac OS X Server, Mac OS X, Mac OS X
+@c German node Mac OS X Public Beta
+@subsubsection Mac OS X Public Beta
+
+MySQL sollte ohne jedes Problem auf Mac OS X Public Beta (Darwin) laufen.
+Die pThread-Patches für dieses Betriebssystem benötigen Sie nicht!
+
+
+@node Mac OS X Server, , Mac OS X Public Beta, Mac OS X
+@c German node Mac OS X Server
+@subsubsection Mac OS X Server
+
+Bevor Sie versuchen, MySQL auf Mac OS X Server zu konfigurieren, müssen Sie
+das pThread-Paket von @uref{http://www.prnet.de/RegEx/mysql.html}
+installieren.
+
+Unsere Binärdatei für Mac OS X wird kompiliert auf Rhapsody 5.5, mit
+folgender Konfigurationszeile:
+
+@example
+CC=gcc CFLAGS="-O2 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O2 -fomit-frame-pointer" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex --disable-shared
+@end example
+
+Wenn Sie der Ressourcen-Datei Ihrer Shell Aliase hinzufügen wollen, um auf
+@code{mysql} und @code{mysqladmin} von der Kommandozeile aus zuzugreifen,
+geben Sie ein:
+
+@example
+alias mysql '/usr/local/mysql/bin/mysql'
+alias mysqladmin '/usr/local/mysql/bin/mysqladmin'
+@end example
+
+
+@node Other Unix Notes, OS/2, Mac OS X, Operating System Specific Notes
+@c German node Andere Unixe
+@subsection Anmerkungen zu anderen Unixen
+
+
+
+@menu
+* Binary notes-HP-UX::
+* HP-UX 10.20::
+* HP-UX 11.x::
+* IBM-AIX::
+* SunOS::
+* Alpha-DEC-UNIX::
+* Alpha-DEC-OSF1::
+* SGI-Irix::
+* Caldera::
+* Caldera Unixware::
+@end menu
+
+@node Binary notes-HP-UX, HP-UX 10.20, Other Unix Notes, Other Unix Notes
+@c German node Binary notes-HP-UX
+@subsubsection Anmerkungen zu HP-UX Notes für Binärdistributionen
+
+@cindex HP-UX, Binärdistribution
+@cindex Binärdistributionen, auf HP-UX
+
+Einige Binärdistributionen von MySQL für HP-UX werden als HP-Depot-Datei
+und als Tar-Datei ausgeliefert. Um die Depot-Datei benutzen zu können,
+müssen Sie mindestens HP-UX 10.x haben, um auf HP's Software-Depot-Werkzeuge
+zugreifen zu können.
+
+Die HP-Version von MySQL wurde auf einem HP 9000/8xx-Server unter HP-UX
+10.20 kompiliert und benutzt MIT-pThreads. Unter dieser Konfiguration
+arbeitet sie bekanntermaßen gut. MySQL-Version 3.22.26 und neuer kann auch
+mit HP's nativem Thread-Paket gebaut werden.
+
+Weitere Konfigurationen, die ebenfalls funktionieren können:
+
+@itemize @bullet
+@item
+HP 9000/7xx mit HP-UX 10.20+
+@item
+HP 9000/8xx mit HP-UX 10.30
+@end itemize
+
+Folgende Konfigurationen werden fast mit Sicherheit nicht laufen:
+
+@itemize @bullet
+@item
+HP 9000/7xx oder 8xx mit HP-UX 10.x, wobei x < 2
+@item
+HP 9000/7xx oder 8xx mit HP-UX 9.x
+@end itemize
+
+Um die Distribution zu installieren, benutzen Sie die unten stehenden
+Befehle, wobei @code{/pfad/zum/depot} der volle Pfadname der Depot-Datei
+ist:
+
+@itemize @bullet
+@item
+Um alles inklusive Server, Client- und Entwicklungs-Werkzeuge zu installieren:
+
+@example
+shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.full
+@end example
+
+@item
+Um nur den Server zu installieren:
+
+@example
+shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.server
+@end example
+
+@item
+Um nur das Client-Paket zu installieren:
+
+@example
+shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.client
+@end example
+
+@item
+Um nur die Entwicklungs-Werkzeuge zu installieren:
+
+@example
+shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.developer
+@end example
+@end itemize
+
+Das Depot speichert Binärdateien und Bibliotheken in @file{/opt/mysql} und
+Daten in @file{/var/opt/mysql}. Es legt auch die entsprechenden Einträge in
+@file{/etc/init.d} und @file{/etc/rc2.d} an, um den Server automatisch beim
+Hochfahren zu starten. Das setzt @code{root}-Rechte zum Installieren
+voraus.
+
+Um die HP-UX-tar.gz-Distribution zu installieren, müssen Sie GNU @code{tar}
+haben.
+
+
+@node HP-UX 10.20, HP-UX 11.x, Binary notes-HP-UX, Other Unix Notes
+@c German node HP-UX 10.20
+@subsubsection Anmerkungen zu HP-UX Version 10.20
+
+Es gibt einige kleine Probleme, wenn Sie MySQL auf HP-UX kompilieren. Wir
+empfehlen, anstelle des nativen HP-UX-Kompilers @code{gcc} zu benutzen,
+weil @code{gcc} besseren Code produziert!
+
+Wir empfehlen die Benutzung von gcc 2.95 auf HP-UX. Benutzen Sie keine
+hohen Optimierungs-Flags (wie -O6), weil das eventuell für HP-UX nicht
+sicher ist.
+
+Beachten Sie, dass MIT-pThreads nicht mit dem HP-UX-Kompiler kompiliert
+werden können, weil dieser keine @code{.S}-(Assembler)-Dateien kompilieren
+kann.
+
+Folgende Konfigurationszeile sollte funktionieren:
+
+@example
+CFLAGS="-DHPUX -I/opt/dce/include" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pThread --with-named-Thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared
+@end example
+
+Wenn Sie @code{gcc} 2.95 selbst kompilieren, sollten Sie ihn NICHT mit den
+DCE-Bibliotheken (@code{libdce.a} oder @code{libcma.a}) linken, wenn Sie
+MySQL mit MIT-pThreads kompilieren wollen. Wenn Sie DCE- und
+MIT-pThreads-Pakete mischen, erhalten Sie einen @code{mysqld}, mit dem Sie
+sich nicht verbinden können. Entfernen Sie die DCE-Bibliotheken, während
+Sie @code{gcc} 2.95 kompilieren!
+
+
+@node HP-UX 11.x, IBM-AIX, HP-UX 10.20, Other Unix Notes
+@c German node HP-UX 11.x
+@subsubsection Anmerkungen zu HP-UX Version 11.x
+
+Für HP-UX Version 11.x empfehlen wir MySQL-Version 3.23.15 oder später.
+
+Wegen einiger kritischer Bugs in den Standard-HP-UX-Bibliotheken sollten
+Sie folgende Patches installieren, bevor Sie MySQL auf HP-UX 11.0 laufen
+lassen:
+
+@example
+PHKL_22840 Streams cumulative
+PHNE_22397 ARPA cumulative
+@end example
+
+Das löst das Problem, dass man @code{EWOULDBLOCK} von @code{recv()}
+und @code{EBADF} von @code{accept()} in threaded Applikationen erhält.
+
+Wenn Sie @code{gcc} 2.95.1 auf einem nicht-gepatchten HP-UX-11.x-System
+benutzen, erhalten Sie den Fehler:
+
+@example
+In file included by /usr/include/unistd.h:11,
+ by ../include/global.h:125,
+ by mysql_priv.h:15,
+ by item.cc:19:
+/usr/include/sys/unistd.h:184: declaration of C function ...
+/usr/include/sys/pThread.h:440: previous declaration ...
+In file included by item.h:306,
+ by mysql_priv.h:158,
+ by item.cc:19:
+@end example
+
+Das Problem liegt darin, dass HP-UX @code{pThreads_atfork()} nicht
+konsistent definiert. Es hat konfliktbehaftete Prototypes in
+@file{/usr/include/sys/unistd.h}:184 und
+@file{/usr/include/sys/pThread.h}:440 (Details weiter unten).
+
+Eine Lösung besteht darin, @file{/usr/include/sys/unistd.h} nach
+@file{mysql/include} zu kopieren und @file{unistd.h} zu editieren, wobei es
+so abgeändert wird, dass es der Definition in @file{pThread.h} entspricht.
+Hier ist der Diff:
+
+@example
+183,184c183,184
+< extern int pThread_atfork(void (*prepare)(), void (*parent)(),
+< void (*child)());
+---
+> extern int pThread_atfork(void (*prepare)(void), void (*parent)(void),
+> void (*child)(void));
+@end example
+
+Danach sollte folgende Konfigurationszeile funktionieren:
+
+@example
+CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" ./configure --prefix=/usr/local/mysql --disable-shared
+@end example
+
+Hier sind ein paar Informationen über das Kompilieren von MySQL mit dem
+HP-UX:x-Kompiler, die uns ein Benutzer der HP-UX-Version 11.x geschickt
+hat:
+
+@example
+ Environment:
+ proper compilers.
+ setenv CC cc
+ setenv CXX aCC
+ flags
+ setenv CFLAGS -D_REENTRANT
+ setenv CXXFLAGS -D_REENTRANT
+ setenv CPPFLAGS -D_REENTRANT
+ % aCC -V
+ aCC: HP ANSI C++ B3910B X.03.14.06
+ % cc -V /tmp/empty.c
+ cpp.ansi: HP92453-01 A.11.02.00 HP C Preprocessor (ANSI)
+ ccom: HP92453-01 A.11.01.00 HP C Compiler
+ cc: "/tmp/empty.c", line 1: warning 501: Empty source file.
+
+ configuration:
+ ./configure --with-pThread \
+ --prefix=/source-control/mysql \
+ --with-named-Thread-libs=-lpThread \
+ --with-low-memory
+
+ added '#define _CTYPE_INCLUDED' to include/m_ctype.h. This
+ symbol ist the one defined in HP's /usr/include/ctype.h:
+
+ /* Don't include std ctype.h when this is included */
+ #define _CTYPE_H
+ #define __CTYPE_INCLUDED
+ #define _CTYPE_INCLUDED
+ #define _CTYPE_USING /* Don't put names in global namespace. */
+@end example
+
+@itemize @bullet
+@item
+Ich muss den Compile-Time-Flag @code{-D_REENTRANT} benutzen, um den
+Kompiler dazu zu bringen, den Prototype für @code{localtime_r} zu erkennen.
+Alternativ hätte ich auch den Prototype für @code{localtime_r} bereit
+stellen können. Aber ich wollte weitere Bugs abfangen, in die ich sonst
+gerannt wäre. Ich war nicht sicher, wo ich es benötigen würde, daher fügte
+ich es zu allen Flags hinzu.
+@item
+Die Optimierungs-Flags, die MySQL benutzt (-O3), werden von den
+HP-Kompilern nicht erkannt. Ich habe die Flags nicht geändert.
+@end itemize
+
+Wenn Sie folgenden Fehler von @code{configure} erhalten:
+
+@example
+checking for cc option to accept ANSI C... no
+configure: error: MySQL requires a ANSI C compiler (and a C++ compiler). Try gcc. See the installation chapter in the reference manual.
+@end example
+
+Überprüfen Sie, dass Sie den Pfad zum K&R-Kompiler nicht vor dem Pfad zum
+HP-UX-C- und C++-Kompiler haben.
+
+
+@node IBM-AIX, SunOS, HP-UX 11.x, Other Unix Notes
+@c German node IBM-AIX
+@subsubsection Anmerkungen zu IBM-AIX
+
+@cindex Probleme, Installation auf IBM-AIX
+
+Automatische Erkennung von @code{xlC} fehlt bei Autoconf, daher wird ein
+@code{configure}-Befehl wie folgender benötigt, wenn Sie MySQL kompilieren
+(dieses Beispiel benutzt den IBM-Kompiler):
+
+@example
+export CC="xlc_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192 "
+export CXX="xlC_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192"
+export CFLAGS="-I /usr/local/include"
+export LDLFAGS="-L /usr/local/lib"
+export CPPFLAGS=$CFLAGS
+export CXXFLAGS=$CFLAGS
+
+./configure --prefix=/usr/local \
+ --localstatedir=/var/mysql \
+ --sysconfdir=/etc/mysql \
+ --sbindir='/usr/local/bin' \
+ --libexecdir='/usr/local/bin' \
+ --enable-thread-safe-client \
+ --enable-large-files
+@end example
+
+Das sind die Optionen, die benutzt werden, um die MySQL-Distribution zu
+kompilieren, die sich auf @uref{http://www-frec.bull.com/} befindet.
+
+Wenn Sie in obiger Konfigurationszeile @code{-O3} zu @code{-O2} ändern,
+müssen Sie auch die @code{-qstrict}-Option entfernen (das ist eine
+Beschränkung im IBM-C-Kompiler).
+
+Wenn Sie @code{gcc} oder @code{egcs} benutzen, um MySQL zu kompilieren,
+@strong{MÜSSEN} Sie den @code{-fno-exceptions}-Flag benutzen, weil das
+Exception-Handling in @code{gcc} / @code{egcs} nicht Thread-sicher ist!
+(Das wurde mit @code{egcs} 1.1. getestet.) Es gibt auch ein paar bekannte
+Probleme mit dem IBM-Assembler, die dazu führen können, dass schlechter
+Code erzeugt wird, wenn er zusammen mit gcc benutzt wird.
+
+Wir empfehlen folgende @code{configure}-Zeile für @code{egcs} und
+@code{gcc 2.95} auf AIX:
+
+@example
+CC="gcc -pipe -mcpu=power -Wa,-many" \
+CXX="gcc -pipe -mcpu=power -Wa,-many" \
+CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
+./configure --prefix=/usr/local/mysql --with-low-memory
+@end example
+
+@code{-Wa,-many} ist notwendig, damit das Kompilieren gelingt. Das Problem
+ist IBM bekannt, hat es aber nicht eilig, es zu beheben, weil ein
+Workaround verfügbar ist. Wir wissen nicht, ob @code{-fno-exceptions} für
+@code{gcc 2.95} erforderlich ist, aber weil MySQL keine Exceptions benutzt
+und die obige Option schnelleren Code erzeugt, empfehlen wir, dass Sie
+diese Option für @code{egcs / gcc} immer benutzen.
+
+Wenn Sie ein Problem mit Assembler-Code bekommen, versuchen Sie, -mcpu=xxx
+so anzupassen, dass es zu Ihrem Prozessor passt. Typischerweise wird man
+power2, power oder powerpc benutzen, alternativ kann man eventuell 604 oder
+604e benutzen. Ich bin nicht ganz sicher, aber ich würde sagen, dass
+"power" meist sicher sein sollte, selbst auf einer power2-Maschine.
+
+Wenn Sie nicht wissen, welchen Prozessor Sie haben, geben Sie "uname -m"
+ein. Das gibt eine Zeichenkette zurück, die etwa wie "000514676700"
+aussieht, mit dem Format xxyyyyyymmss, wobei xx und ss immer die Nullen
+sind (0). yyyyyy ist eine eindeutige System-ID und mm ist die ID des
+CPU-Planars. Eine Tabelle dieser Werte liegt auf
+@uref{http://www.rs6000.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm}.
+Darin finden Sie Maschinentyp und Maschinenmodell, was Sie benutzen können,
+um herauszufinden, welchen Prozessortyp Sie haben.
+
+Wenn Sie Probleme mit Signalen haben (MySQL stirbt unerwartet unter hoher
+Last), haben Sie vielleicht einen Betriebssystem-Bug bei Threads und
+Signalen gefunden. In diesem Fall können Sie MySQL anweisen, keine Signale
+zu benutzen, indem Sie es wie folgt konfigurieren:
+
+@example
+shell> CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
+ CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -DDONT_USE_THR_ALARM" \
+ ./configure --prefix=/usr/local/mysql --with-debug --with-low-memory
+@end example
+
+Das berührt nicht die Performance von MySQL, hat aber den Nebeneffekt, dass
+Sie keine Clients auf einer Verbindung mit @code{mysqladmin kill} oder
+@code{mysqladmin shutdown} killen können, die ``schlafen''. Statt dessen
+wird der Client sterben, wenn er den nächsten Befehl sendet.
+
+Bei einigen Versionen von AIX für das Linken mit @code{libbind.a} bei
+@code{getservbyname} zu einem Speicherauszug (Core Dump). Das ist ein
+AIX-Bug, der IBM berichtet werden sollte.
+
+Bei AIX 4.2.1 und gcc müssen Sie folgende Änderungen durchführen:
+
+Nach dem Konfigurieren müssen Sie @file{config.h} und
+@file{include/my_config.h} editieren und die Zeile ändern, in der steht:
+
+@example
+#define HAVE_SNPRINTF 1
+@end example
+
+zu
+
+@example
+#undef HAVE_SNPRINTF
+@end example
+
+Schließlich müssen Sie in @file{mysqld.cc} einen Prototype für initgoups
+hinzufügen:
+
+@example
+#ifdef _AIX41
+extern "C" int initgroups(const char *,int);
+#endif
+@end example
+
+
+@node SunOS, Alpha-DEC-UNIX, IBM-AIX, Other Unix Notes
+@c German node SunOS
+@subsubsection Anmerkungen zu SunOS 4
+
+Auf SunOS 4 werden MIT-pThreads benötigt, um MySQL zu kompilieren, was
+letztlich bedeutet, dass Sie GNU-@code{make} benötigen.
+
+Einige SunOS-4-Systeme haben Probleme mit dynamischen Bibliotheken und
+@code{libtool}. Sie können folgende @code{configure}-Zeile benutzen, um das
+Problem zu vermeiden:
+
+@example
+shell> ./configure --disable-shared --with-mysqld-ldflags=-all-static
+@end example
+
+Wenn Sie @code{readline} kompilieren, erhalten Sie vielleicht Warnungen
+über duplizierte Defines. Diese können ignoriert werden.
+
+Wenn Sie @code{mysqld} kompilieren, gibt es ein paar @code{implicit
+declaration of function}-Warnungen. Diese können ignoriert werden.
+
+
+@node Alpha-DEC-UNIX, Alpha-DEC-OSF1, SunOS, Other Unix Notes
+@c German node Alpha-DEC-UNIX
+@subsubsection Anmerkungen zu Alpha-DEC-UNIX (Tru64)
+
+Wenn Sie egcs 1.1.2 auf Digital Unix benutzen, sollten Sie auf gcc 2.95.2
+aktualisieren, weil egcs auf DEC einige schwer wiegende Bugs hat!
+
+Wenn Sie threaded Programme unter Digital Unix kompilieren, empfiehlt die
+Dokumentation, die @code{-pThread}-Option für @code{cc} und @code{cxx} und
+die Bibliotheken @code{-lmach -lexc} zu benutzen (zusätzlich zu
+@code{-lpThread}). Sie sollten @code{configure} wie folgt laufen lassen:
+
+@example
+CC="cc -pThread" CXX="cxx -pThread -O" \
+./configure --with-named-thread-libs="-lpThread -lmach -lexc -lc"
+@end example
+
+Wenn Sie @code{mysqld} kompilieren, sehen Sie eventuell eine Reihe von
+Warnungen wie die folgende:
+
+@example
+mysqld.cc: In function void handle_connections()':
+mysqld.cc:626: passing long unsigned int *' as argument 3 of
+accept(int,sockadddr *, int *)'
+@end example
+
+Sie können diese Warnungen ignorieren. Sie treten auf, weil
+@code{configure} nur Fehler entdecken kann, keine Warnungen.
+
+Wenn Sie den Server direkt von the Kommandozeile starten, haben Sie
+vielleicht Probleme, dass er stirbt, wenn Sie sich ausloggen. (Wenn Sie
+sich ausloggen, erhalten Ihre offenen Prozesse ein @code{SIGHUP}-Signal.)
+Wenn das der Fall ist, starten Sie den Server wie folgt:
+
+@example
+shell> nohup mysqld [options] &
+@end example
+
+@code{nohup} bewirkt, dass der folgende Befehl jegliche
+@code{SIGHUP}-Signale, die vom Terminal gesendet werden, ignoriert.
+Alternativ starten Sie den Server mit @code{safe_mysqld}, was @code{mysqld}
+mit @code{nohup} für Sie aufruft.
+@xref{safe_mysqld, , @code{safe_mysqld}}.
+
+Wenn Sie ein Problem beim Kompilieren von mysys/get_opt.c bekommen,
+entfernen Sie einfach die Zeile #define _NO_PROTO am Anfang dieser Datei!
+
+Wenn Sie den CC-Kompiler von Compaq benutzen, sollte die folgende
+Konfigurationszeile funktionieren:
+
+@example
+CC="cc -pThread"
+CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
+CXX="cxx -pThread"
+CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
+export CC CFLAGS CXX CXXFLAGS
+./configure \
+--prefix=/usr/local/mysql \
+--with-low-memory \
+--enable-large-files \
+--enable-shared=yes \
+--with-named-Thread-libs="-lpThread -lmach -lexc -lc"
+gnumake
+@end example
+
+Wenn Sie ein Problem mit libtool beim Kompilieren mit gemeinsam genutzten
+(shared) Bibliotheken bekommen wie oben, wenn Sie @code{mysql} linken,
+sollten Sie dies folgendermaßen umgehen können:
+
+@example
+cd mysql
+/bin/sh ../libtool --mode=link cxx -pThread -O3 -DDBUG_OFF \
+-O4 -ansi_alias -ansi_args -fast -inline speed \
+-speculate all \ -arch host -DUNDEF_HAVE_GETHOSTBYNAME_R \
+-o mysql mysql.o readline.o sql_string.o completion_hash.o \
+../readline/libreadline.a -lcurses \
+../libmysql/.libs/libmysqlclient.so -lm
+cd ..
+gnumake
+gnumake install
+Skripts/mysql_install_db
+@end example
+
+
+@node Alpha-DEC-OSF1, SGI-Irix, Alpha-DEC-UNIX, Other Unix Notes
+@c German node Alpha-DEC-OSF1
+@subsubsection Anmerkungen zu Alpha-DEC-OSF1
+
+Wenn Sie Probleme beim Kompilieren haben und DEC @code{CC} und @code{gcc}
+installiert sind, versuchen Sie, @code{configure} wie folgt laufen zu
+lassen:
+
+@example
+CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \
+./configure --prefix=/usr/local/mysql
+@end example
+
+Wenn Sie Probleme mit der @file{c_asm.h}-Datei bekommen, können Sie wie
+folgt eine 'dummy'-@file{c_asm.h}-Datei erzeugen und benutzen:
+
+@example
+touch include/c_asm.h
+CC=gcc CFLAGS=-I./include \
+CXX=gcc CXXFLAGS=-O3 \
+./configure --prefix=/usr/local/mysql
+@end example
+
+Beachten Sie, dass die im Folgenden beschriebenen Probleme mit dem
+@code{ld}-Programm behoben werden können, indem Sie das neueste
+DEC-(Compaq)-Patch-Kit herunterladen, und zwar von folgender Seite:
+@uref{http://ftp.Support.compaq.com/public/unix/}.
+
+Auf OSF1 V4.0D und Kompiler "DEC C V5.6-071 auf Digital Unix V4.0 (Rev.
+878)" zeigt der Kompiler einige seltsame Verhaltensweisen (undefinierte
+@code{asm}-Symbole). Ausserdem scheint @code{/bin/ld} beschädigt zu sein
+(Probleme mit @code{_exit undefined}-Fehlern, die auftreten, wenn Sie
+@code{mysqld} linken). Auf diesem System konnten wir MySQL mit folgender
+@code{configure}-Zeile kompilieren, nachdem wir @code{/bin/ld} mit der
+Version von OSF 4.0C ersetzt haben:
+
+@example
+CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
+@end example
+
+Beim Digital-Kompiler "C++ V6.1-029" sollte folgendes funktionieren:
+
+@example
+CC=cc -pThread
+CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host
+CXX=cxx -pThread
+CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host -noexceptions -nortti
+export CC CFLAGS CXX CXXFLAGS
+./configure --prefix=/usr/mysql/mysql --with-mysqld-ldflags=-all-static --disable-shared --with-named-thread-libs="-lmach -lexc -lc"
+@end example
+
+In einigen Versionen von OSF1 ist die @code{alloca()}-Funktion beschädigt.
+Beheben Sie dies, indem Sie die Zeile in @file{config.h} entfernen, die
+@code{'HAVE_ALLOCA'} definiert.
+
+Die @code{alloca()}-Funktion kann ebenfalls einen falschen Prototyp in
+@code{/usr/include/alloca.h} haben. Die Warnung, die hieraus resultiert,
+kann ignoriert werden.
+
+@code{configure} benutzt automatisch folgenden Thread-Bibliotheken:
+@code{--with-named-thread-libs="-lpThread -lmach -lexc -lc"}.
+
+Wenn Sie @code{gcc} benutzen, können Sie auch versuchen, @code{configure}
+wie folgt laufen zu lassen:
+
+@example
+shell> CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ....
+@end example
+
+Wenn Sie Probleme mit Signalen haben (MySQL stirbt unerwartet unter
+Hochlast), haben Sie vielleicht einen Betriebssystem-Bug bei Threads und
+Signalen gefunden. In diesem Fall können Sie MySQL anweisen, keine Signale
+zu benutzen, indem Sie es wie folgt konfigurieren:
+
+@example
+shell> CFLAGS=-DDONT_USE_THR_ALARM \
+ CXXFLAGS=-DDONT_USE_THR_ALARM \
+ ./configure ...
+@end example
+
+Das berührt nicht die Performance von MySQL, hat aber den Nebeneffekt, dass
+Sie keine Clients auf einer Verbindung mit @code{mysqladmin kill} oder
+@code{mysqladmin shutdown} killen können, die ``schlafen''. Statt dessen
+wird der Client sterben, wenn er den nächsten Befehl sendet.
+
+Bei @code{gcc} 2.95.2 erhalten Sie wahrscheinlich folgenden
+Kompilierfehler:
+
+@example
+sql_acl.cc:1456: Internal compiler error in `scan_region', at except.c:2566
+Please submit a full bug report.
+@end example
+
+Um das zu beheben, wechseln Sie ins @code{sql}-Verzeichnis und machen ein
+``Kopieren und Einfügen'' der letzten @code{gcc}-Zeile, ändern aber
+@code{-O3} zu @code{-O0} (oder fügen @code{-O0} unmittelbar nach @code{gcc}
+hinzu, falls Sie keine @code{-O}-Option auf Ihrer Kompilierzeile haben.)
+Danach wechseln Sie einfach direkt zurück in oberste Verzeichnis und lassen
+@code{make} noch einmal laufen.
+
+
+@node SGI-Irix, Caldera, Alpha-DEC-OSF1, Other Unix Notes
+@c German node SGI-Irix
+@subsubsection Anmerkungen zu SGI Irix
+
+Wenn Sie Irix-Version 6.5.3 oder neuer benutzen, kann @code{mysqld} nur
+dann Threads erzeugen, wenn Sie ihn als Benutzer mit
+@code{CAP_SCHED_MGT}-Zugriffsrechten (wie @code{root}) laufen lassen oder
+dem @code{mysqld}-Server dieses Recht mit dem folgenden Befehl geben:
+
+@example
+shell> chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld
+@end example
+
+Sie müssen eventuell in @file{config.h} einige Dinge umdefinieren, nachdem
+Sie @code{configure} laufen gelassen haben und vor dem Kompilieren.
+
+In einigen Irix-Implementationen ist die @code{alloca()}-Funktion
+beschädigt. Wenn der @code{mysqld}-Server bei manchen
+@code{SELECT}-Statements stirbt, entfernen Sie die Zeilen aus
+@file{config.h}, die @code{HAVE_ALLOC} und @code{HAVE_ALLOCA_H} definieren.
+Wenn @code{mysqladmin create} nicht funktioniert, entfernen Sie die Zeile
+aus @file{config.h}, die @code{HAVE_READDIR_R} definiert. Eventuell müssen
+Sie auch die @code{HAVE_TERM_H}-Zeile entfernen.
+
+SGI empfiehlt, dass Sie alle Patches auf dieser Seite auf einmal
+installieren:
+http://Support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html
+
+Als absolutes Minimum sollten Sie das letzte Kernel-Rollup installieren,
+das letzte @code{rld}-Rollup und das letzte @code{libc}-Rollup.
+
+In jedem Fall brauchen Sie für die pThread-Unterstützung alle POSIX-Patches
+auf dieser Seite:
+
+@uref{http://Support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.html}
+
+Wenn Sie beim Kompilieren von @file{mysql.cc} etwa folgenden Fehler
+erhalten:
+
+@example
+"/usr/include/curses.h", line 82: error(1084): invalid combination of type
+@end example
+
+Geben Sie folgendes im obersten Verzeichnis Ihres MySQL-Source-Trees ein:
+
+@example
+shell> extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
+shell> make
+@end example
+
+Es wurden ausserdem Scheduling-Probleme berichtet. Wenn nur ein Thread
+läuft, läuft alles recht langsam. Das können Sie vermeiden, indem Sie einen
+weiteren Client-Starten. Daraus kann sich eine zwei- bis zehnfache
+Geschwindigkeitssteigerung für den anderen Thread ergeben. Das liegt an
+einem Problem mit Irix-Threads, das kaum zu verstehen ist. Eventuell müssen
+Sie improvisieren, um eine Lösung zu finden, bis dies behoben ist.
+
+Wenn Sie mit @code{gcc} kompilieren, können Sie folgenden
+@code{configure}-Befehl benutzen:
+
+@example
+CC=gcc CXX=gcc CXXFLAGS=-O3 \
+./configure --prefix=/usr/local/mysql --enable-thread-safe-client --with-named-thread-libs=-lpThread
+@end example
+
+Auf Irix 6.5.11 mit nativen Irix-C- und C++-Kompilern der Version 7.3.1.2
+soll auch folgendes funktionieren:
+
+@example
+CC=cc CXX=CC CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \
+-L/usr/local/lib' CXXFLAGS='-O3 -n32 -TARG:platform=IP22 \
+-I/usr/local/include -L/usr/local/lib' ./configure --prefix=/usr/local/mysql \
+--with-berkeley-db --with-innodb \
+--with-libwrap=/usr/local --with-named-curses-libs=/usr/local/lib/libncurses.a
+@end example
+
+
+@node Caldera, Caldera Unixware, SGI-Irix, Other Unix Notes
+@c German node SCO
+@subsubsection Anmerkungen zu Caldera
+@c German fixup: 2002-03-22 monty changed SCO -> Caldera in English manual
+
+Die aktuelle Portierung wird auf ``sco3.2v5.0.4''-
+und-``sco3.2v5.0.5''-Systemen getestet. Die Portierung auf ``sco 3.2v4.2''
+ist ebenfalls weit fortgeschritten.
+
+Momentan ist der empfohlene Kompiler auf OpenServer gcc 2.95.2. Damit
+sollten Sie in der Lage sein, MySQL einfach durch folgendes zu kompilieren:
+
+@example
+CC=gcc CXX=gcc ./configure ... (options)
+@end example
+
+@enumerate
+@item
+Bei OpenServer 5.0.X müssen Sie GDS in Skunkware 95 (95q4c) benutzen. Das
+ist deshalb notwendig, weil GNU-@code{gcc} 2.7.2 in Skunkware 97 kein
+GNU-@code{as} hat. Sie können auch @code{egcs} 1.1.2 oder neuer benutzen
+@uref{http://www.egcs.com/}. Wenn Sie @code{egcs} 1.1.2 benutzen, müssen
+Sie folgenden Befehl eingeben:
+
+@example
+shell> cp -p /usr/include/pThread/stdtypes.h /usr/local/lib/gcc-lib/i386-pc-sco3.2v5.0.5/egcs-2.91.66/include/pThread/
+@end example
+
+@item
+Sie brauchen die Portierung von GCC 2.5.x für dieses Produkt und das
+Entwicklungssystem. Sie werden auf dieser Version von Caldera (SCO) Unix benötigt.
+Sie können nicht lediglich das GCC-Dev-System benutzen.
+
+@item
+Sie sollten zuerst das FSU-PThreads-Paket holen und installieren. Dieses
+finden Sie auf
+@uref{http://www.cs.wustl.edu/~schmidt/ACE_wrappers/FSU-Threads.tar.gz}.
+Sie finden ein vorkompiliertes Paket auf
+@uref{http://www.mysql.com/downloads/SCO/FSU-Threads-3.5c.tar.gz}.
+
+@item
+FSU-PThreads kann mit SCO Unix 4.2 mit TCP/IP kompiliert werden. Oder mit
+OpenServer 3.0 oder Open Desktop 3.0 (OS 3.0 ODT 3.0), mit installiertem
+Caldera (SCO) Entwicklungssystem unter Benutzung einer guten Portierung von GCC 2.5.x
+ODT oder OS 3.0. Hierbei brauchen Sie eine gute Portierung von GCC 2.5.x.
+Ohne gute Portierung gibt es eine Menge Probleme. Die Portierung für dieses
+Produkt erfordert das Caldera (SCO) Unix-Entwicklungssystem. Ohne dieses fehlen die
+Bibliotheken und der Linker, die benötigt werden.
+
+@item
+Um FSU-PThreads auf Ihrem System zu bauen, tun Sie folgendes:
+
+@enumerate a
+@item
+Lassen Sie @code{./configure} im @file{Threads/src}-Verzeichnis laufen und
+wählen Sie die SCO-OpenServer-Option. Dieser Befehl kopiert
+@file{Makefile.SCO5} nach @file{Makefile}.
+
+@item
+Lassen Sie @code{make} laufen.
+
+@item
+Um in das vorgabemäßige @file{/usr/include}-Verzeichnis zu installieren,
+loggen Sie sich als Root ein und wechseln (@code{cd}) Sie in das
+@file{thread/src}-Verzeichnis. Führen Sie dann @code{make install} aus.
+@end enumerate
+
+@item
+Denken Sie daran, GNU @code{make} zu benutzen, wenn Sie MySQL machen.
+
+@item
+Wenn Sie @code{safe_mysqld} nicht als Root starten, erhalten Sie
+wahrscheinlich nur die 110 offenen Dateien pro Prozess. @code{mysqld} macht
+darüber in der Log-Datei einen Eintrag.
+
+@item
+Bei SCO 3.2V5.0.5 sollten Sie FSU-PThreads-Version 3.5c oder neuer
+benutzen. Ausserdem sollten Sie gcc 2.95.2 oder neuer benutzen!
+
+Folgender @code{configure}-Befehl sollte funktionieren:
+
+@example
+shell> ./configure --prefix=/usr/local/mysql --disable-shared
+@end example
+
+@item
+Bei SCO 3.2V4.2 sollten Sie FSU-PThreads-Version 3.5c oder neuer benutzen.
+Folgender @code{configure}-Befehl sollte funktionieren:
+
+@example
+shell> CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
+ ./configure \
+ --prefix=/usr/local/mysql \
+ --with-named-thread-libs="-lgThreads -lsocket -lgen -lgThreads" \
+ --with-named-curses-libs="-lcurses"
+@end example
+
+Möglicherweise bekommen Sie Probleme mit einigen Include-Dateien. In diesem
+Fall finden Sie neue, SCO-spezifische Include-Dateien auf
+@uref{http://www.mysql.com/downloads/SCO/SCO-3.2v4.2-includes.tar.gz}.
+Entpacken Sie diese Datei ins @file{include}-Verzeichnis Ihres
+MySQL-Source-Trees.
+@end enumerate
+
+Anmerkungen zur Caldera (SCO) Entwicklung:
+
+@itemize @bullet
+@item
+MySQL kann FSU-PThreads automatisch erkennen und @code{mysqld} mit
+@code{-lgThreads -lsocket -lgThreads} linken.
+
+@item
+@c Question: Good translation for "re-entrant"?
+Die Caldera (SCO) Entwicklungsbibliotheken sind re-entrant in FSU-PThreads. Caldera
+behauptet, dass seine Bibliotheken-Funktionen re-entrant sind, daher müssen
+sie mit FSU-PThreads re-entrant sein. FSU-PThreads auf OpenServer versucht,
+das SCO-Scheme zu benutzen, um Bibliotheken re-entrant zu machen.
+
+@item
+FSU-PThreads (zumindest die Version auf @uref{http://www.mysql.com/}) wird
+mit gelinktem GNU-@code{malloc} ausgeliefert. Wenn Sie Problemen mit der
+Speicherbenutzung begegnen, stellen Sie sicher, dass @file{gmalloc.o} in
+@file{libgThreads.a} und @file{libgThreads.so} beinhaltet ist.
+
+@item
+In FSU-PThreads achten folgende Systemaufrufe auf pThreads: @code{read()},
+@code{write()}, @code{getmsg()}, @code{connect()}, @code{accept()},
+@code{select()} und @code{wait()}.
+@end itemize
+
+Wenn Sie DBI auf Caldera (SCO) installieren wollen, müssen Sie @file{Makefile} in
+DBI-xxx und jedem Unterverzeichnis editieren.
+
+Beachten Sie, dass folgendes gcc 2.95.2 oder neuer voraussetzt:
+
+@example
+ALT: NEU:
+CC = cc CC = gcc
+CCCDLFLAGS = -KPIC -W1,-Bexport CCCDLFLAGS = -fpic
+CCDLFLAGS = -wl,-Bexport CCDLFLAGS =
+
+LD = ld LD = gcc -G -fpic
+LDDLFLAGS = -G -L/usr/local/lib LDDLFLAGS = -L/usr/local/lib
+LDFLAGS = -belf -L/usr/local/lib LDFLAGS = -L/usr/local/lib
+
+LD = ld LD = gcc -G -fpic
+OPTIMISE = -Od OPTIMISE = -O1
+
+OLD:
+CCCFLAGS = -belf -dy -w0 -U M_XENIX -DPERL_SCO5 -I/usr/local/include
+
+NEW:
+CCFLAGS = -U M_XENIX -DPERL_SCO5 -I/usr/local/include
+@end example
+
+Das liegt daran, dass der Perl-dynaloader keine @code{DBI}-Module lädt, die
+mit @code{icc} oder @code{cc} kompiliert wurden.
+
+Perl funktioniert am besten, wenn es mit @code{cc} kompiliert wird.
+
+
+@node Caldera Unixware, , Caldera, Other Unix Notes
+@c German node SCO Unixware
+@subsubsection Anmerkungen zu Caldera Unixware Version 7.0
+@c German fixup: 2002-03-22 monty changed SCO -> Caldera in English manual
+
+Sie benötigen mindestens MySQL-Version 3.22.13, weil diese Version einige
+Portabilitätsprobleme unter Unixware behebt.
+
+Wir waren in der Lage, MySQL mit folgendem @code{configure}-Befehl auf
+Unixware Version 7.0.1 zu kompilieren:
+
+@example
+CC=cc CXX=CC ./configure --prefix=/usr/local/mysql
+@end example
+
+Wenn Sie @code{gcc} benutzen wollen, müssen Sie @code{gcc} 2.95.2 oder
+neuer benutzen.
+
+
+
+
+@node OS/2, BeOS, Other Unix Notes, Operating System Specific Notes
+@c German node OS/2
+@subsection Anmerkungen zu OS/2
+
+MySQL benutzt eine ganze Menge offener Dateien. Deswegen sollten Sie Ihrer
+@file{CONFIG.SYS}-Datei folgendes hinzufügen:
+
+@example
+SET EMXOPT=-c -n -h1024
+@end example
+
+Wenn Sie das nicht tun, erhalten Sie wahrscheinlich folgenden Fehler:
+
+@example
+File 'xxxx' not found (Errcode: 24)
+@end example
+
+Wenn Sie MySQL auf OS/2 Warp 3 einsetzen, wird FixPack 29 oder höher
+benötigt. Bei OS/2 Warp 4 wird FixPack 4 oder höher benötigt. Das erfordert
+die PThreads-Bibliothek. MySQL muss auf einer Partition installiert werden,
+die lange Dateinamen unterstützt, also zum Beispiel HPFS, FAT32 usw.
+
+Das @file{INSTALL.CMD}-Skript muss von OS/2's eigener @file{CMD.EXE} aus
+laufen gelassen werden und funktioniert eventuell nicht mit Ersatz-Shells
+wie @file{4OS2.EXE}.
+
+Das @file{scripts/mysql-install-db}-Skript wurde umbenannt. Es heißt jetzt
+@file{install.cmd} und ist ein REXX-Skript, welches die vorgabemäßigen
+MySQL-Sicherheitseinstellungen einstellt und die WorkPlace-Shell-Icons für
+MySQL erstellt.
+
+Unterstützung für dynamische Module wird einkompiliert, ist aber noch nicht
+komplett durchgetestet. Dynamische Module sollten unter Benutzung der
+PThreads-Runtime-Bibliothek kompiliert werden.
+
+@example
+gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \
+ -o example udf_example.cc -L../lib -lmysqlclient udf_example.def
+mv example.dll example.udf
+@end example
+
+@strong{Beachten Sie:} Aufgrund von Beschränkungen in OS/2 dürfen
+UDF-module-name-stems nicht länger als 8 Zeichen sein. Module werden im
+@file{/mysql2/udf}-Verzeichnis gespeichert; das
+@code{safe-mysqld.cmd}-Skript trägt dieses Verzeichnis in die
+@code{BEGINLIBPATH}-Umgebungsvariable ein. Wenn Sie UDF-Module benutzen,
+werden festgelegte Erweiterungen ignoriert - es wird nicht angenommen, dass
+sie @file{.udf} sind.
+Unter Unix zum Beispiel könnte das gemeinsam genutzte (shared) Module
+@file{example.so} benannt sein. Sie würden daraus eine Funktion wie folgt
+laden:
+
+@example
+mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example.so";
+@end example
+
+Unter OS/2 würde das Modul @file{example.udf} heißen, aber Sie würden
+nicht die Modul-Erweiterung angeben:
+
+@example
+mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example";
+@end example
+
+
+@node BeOS, Novell Netware, OS/2, Operating System Specific Notes
+@c German node BeOS
+@subsection Anmerkungen zu BeOS
+
+Wir sind sehr daran interessiert, MySQL auf BeOS ans Laufen zu bringen,
+aber leider kennen wir niemanden, der sich mit BeOS auskennt oder Zeit hat,
+eine Portierung durchzuführen.
+
+Wir sind daran interessiert, jemanden für eine Portierung zu finden, und
+wir werden ihn / sie bei allen technischen Fragen helfen, die bei einer
+Portierung auftreten können.
+
+Wir haben vor einiger Zeit mit einigen BeOS-Entwicklern gesprochen, die uns
+sagten, dass MySQL zu 80% auf BeOS portiert ist, aber wir haben schon eine
+Weile nichts von ihnen gehört.
+
+
+@node Novell Netware, , BeOS, Operating System Specific Notes
+@c German node Novell Netware
+@subsection Anmerkungen zu Novell NetWare
+
+Wir sind sehr daran interessiert, MySQL auf NetWare ans Laufen zu bringen,
+aber leider kennen wir niemanden, der sich mit NetWare auskennt oder Zeit hat,
+eine Portierung durchzuführen.
+
+Wir sind daran interessiert, jemanden für eine Portierung zu finden, und
+wir werden ihn / sie bei allen technischen Fragen helfen, die bei einer
+Portierung auftreten können.
+
+@node Perl support, , Operating System Specific Notes, Installing
+@c German node Perl-Unterstützung
+@section Anmerkungen zur Perl-Installation
+
+@cindex Perl, Installation
+@cindex Installation, Perl
+
+@code{DBI}/@code{DBD}-Schnittstelle
+
+
+@menu
+* Perl installation::
+* ActiveState Perl::
+* Windows Perl::
+* Perl support problems::
+@end menu
+
+@node Perl installation, ActiveState Perl, Perl support, Perl support
+@c German node Perl-Installation
+@subsection Installation von Perl unter Unix
+
+Perl-Unterstützung für MySQL wird durch die @code{DBI}/@code{DBD}-
+Client-Schnittstelle zur Verfügung gestellt. @xref{Perl}. Der Perl-
+@code{DBD}/@code{DBI}-Client-Code erfordert Perl Version 5.004 oder
+später. Die Schnittstelle @strong{funktioniert nicht}, wenn Sie eine
+ältere Version von Perl haben.
+
+MySQL-Perl-Unterstützung erfordert ausserdem, dass Sie MySQL-Client-
+Programmierunterstützung installiert haben. Wenn Sie MySQL von RPM-
+Dateien installiert haben, sind Client-Programme im Client-RPM
+enthalten, aber Client-Programmierunterstützung ist im Entwickler-RPM.
+Stellen Sie sicher, dass Sie auch das letztgenannte RPM installiert
+haben.
+
+Ab Version 3.22.8 wird Perl-Unterstützung getrennt von der Haupt-MySQL-
+Unterstützung ausgeliefert. Wenn Sie Perl-Unterstützung installieren
+wollen, können Sie die benötigten Dateien von
+@uref{http://www.mysql.com/Downloads/Contrib/} herunter laden.
+
+Die Perl-Distributionen werden als komprimierte @code{tar}-Archive zur
+Verfügung gestellt und haben Namen wie @file{MODULE-VERSION.tar.gz},
+wobei @code{MODULE} der Modulname und @code{VERSION} die Versionsnummer
+ist. Sie sollten die @code{Data-Dumper}-, @code{DBI}- und @code{Msql-
+Mysql-modules}-Distributionen laden und sie in dieser Reihenfolge
+installieren. Die Installationsprozedur ist unten dargestellt. Das
+Beispiel gilt für das @code{Data-Dumper}-Modul, ist aber für alle drei
+Distributionen dieselbe:
+
+@enumerate
+@item
+Entpacken Sie die Distribution ins aktuelle Verzeichnis.
+@example
+shell> gunzip < Data-Dumper-VERSION.tar.gz | tar xvf -
+@end example
+Dieser Befehl erzeugt ein Verzeichnis namens @file{Data-Dumper-
+VERSION}.
+
+@item
+Wechseln Sie ins oberste Verzeichnis der entpackten Distribution:
+@example
+shell> cd Data-Dumper-VERSION
+@end example
+
+@item
+Bauen Sie die Distribution und kompilieren Sie alles:
+@example
+shell> perl Makefile.PL
+shell> make
+shell> make test
+shell> make install
+@end example
+@end enumerate
+
+Der @code{make test}-Befehl ist wichtig, weil er sicherstellt, dass die
+Module funktionieren. Beachten Sie, dass der MySQL-Server während der
+Befehlsausführung bei der @code{Msql-Mysql-modules}-Installation laufen
+muss, um den Schnittstellen-Code auszuführen, den ansonsten schlägt der
+Test fehl.
+
+Es ist eine gute Idee, die @code{Msql-Mysql-modules}-Distribution neu zu
+kompilieren und zu installieren, wenn Sie ein neues Release von MySQL
+installieren, insbesondere, wenn Sie Symptome feststellen wie dass alle
+Ihre @code{DBI}-Skripte einen Coredump liefern, nachdem Sie auf eine
+höhere Version von MySQL aktualisiert haben.
+
+Wenn Sie keine Rechte haben, die Perl-Module im Systemverzeichnis zu
+installieren, oder wenn Sie lokale Perl-Module installieren wollen,
+könnte Ihnen der folgende Link helfen:
+
+@example
+@uref{http://www.iserver.com/support/contrib/perl5/modules.html}
+@end example
+
+Suchen Sie nach der Überschrift
+@code{Installing New Modules that Require Locally Installed Modules}.
+
+
+@node ActiveState Perl, Windows Perl, Perl installation, Perl support
+@c German node ActiveState-Perl
+@subsection Installation von ActiveState-Perl unter Windows
+
+@cindex Installation, Perl unter Windows
+@cindex Perl, Installation unter Windows
+@cindex ActiveState-Perl
+
+Um das MySQL-@code{DBD}-Modul mit ActiveState-Perl unter Windows zu
+installieren, gehen Sie wie folgt vor:
+
+@itemize @bullet
+@item
+Laden Sie ActiveState-Perl von
+@uref{http://www.activestate.com/Products/ActivePerl/}
+und installieren Sie es.
+
+@item
+Öffnen Sie eine MS-DOS-Eingabeaufforderung.
+
+@item
+Setzen Sie - falls erforderlich - die HTTP_proxy-Variable, zum Beispiel
+wie folgt:
+
+@example
+set HTTP_proxy=my.proxy.com:3128
+@end example
+
+@item
+Starten Sie das PPM-Programm:
+
+@example
+C:\> c:\perl\bin\ppm.pl
+@end example
+
+@item
+Falls noch nicht geschehen, installieren Sie @code{DBI}:
+
+@example
+ppm> install DBI
+@end example
+
+@item
+Wenn das erfolgreich verlief, führen Sie folgenden Befehl aus:
+
+@example
+install
+ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd
+@end example
+@end itemize
+
+Das sollte zumindest bei ActiveState-Perl Version 5.6 funktionieren.
+
+Wenn Sie es nicht schaffen, dass oben Genanntes funktioniert, sollten
+Sie statt dessen den @strong{MyODBC}-Treiber installieren und sich mit
+dem MySQL-Server über ODBC verbinden:
+
+@example
+use DBI;
+$dbh= DBI->connect("DBI:ODBC:$dsn","$user","$password") ||
+ die "Fehler $DBI::errstr beim Verbinden mit $dsn\n";
+@end example
+
+
+@node Windows Perl, Perl support problems, ActiveState Perl, Perl support
+@c German node Windows-Perl
+@subsection Installation der MySQL-Perl-Distribution unter Windows
+
+Die MySQL-Perl-Distribution enthält @code{DBI},
+@code{DBD:MySQL} und @code{DBD:ODBC}.
+
+@itemize @bullet
+@item
+Laden Sie die Perl-Distribution für Windows von
+@uref{http://www.mysql.com/download.html}.
+
+@item
+Entpacken Sie die Distribution in @code{C:}, so dass Sie ein
+@file{C:\PERL}-Verzeichnis erhalten.
+
+@item
+Fügen Sie Ihrem Pfad @file{C:\PERL\BIN} hinzu.
+
+@item
+Fügen Sie Ihrem Pfad das Verzeichnis @file{C:\PERL\BIN\MSWIN32-x86-
+thread} oder @file{C:\PERL\BIN\MSWIN32-x86} hinzu.
+
+@item
+Testen Sie, ob @code{perl} funktioniert, indem Sie @code{perl -v} in
+einer MS-DOS-Eingabeaufforderung ausführen.
+@end itemize
+
+
+@node Perl support problems, , Windows Perl, Perl support
+@c German node Perl-Unterstützung Probleme
+@subsection Probleme bei der Benutzung von Perl @code{DBI}/@code{DBD}-Schnittstelle
+
+@cindex Probleme, Installation von Perl
+@cindex Perl DBI/DBD, Installationsprobleme
+
+Wenn Perl ausgibt, dass es das @file{../mysql/mysql.so}-Modul nicht
+finden kann, liegt das Problem wahrscheinlich darin, dass Perl die
+gemeinsam genutzte @file{libmysqlclient.so} nicht findet.
+
+Das können Sie mit einer der folgenden Methoden beheben:
+
+@itemize @bullet
+@item
+Kompilieren Sie die @code{Msql-Mysql-modules}-Distribution mit
+@code{perl Makefile.PL -static -config} statt mit @code{perl
+Makefile.PL}.
+
+@item
+Kopieren Sie @code{libmysqlclient.so} in das Verzeichnis, in dem Ihre
+anderen gemeinsam genutzten Bibliotheken liegen (wahrscheinlich
+@file{/usr/lib} oder @file{/lib}).
+
+@item
+Unter Linux können Sie der @file{/etc/ld.so.conf}-Datei den Pfadnamen
+des Verzeichnisses hinzufügen, in dem @file{libmysqlclient.so} liegt.
+
+@tindex LD_RUN_PATH-Umgebungsvariable
+@tindex Umgebungsvariable, LD_RUN_PATH
+@item
+Fügen Sie der @code{LD_RUN_PATH}-Umgebungsvariablen den Pfadnamen des
+Verzeichnisses hinzu, in dem @file{libmysqlclient.so} liegt.
+@end itemize
+
+Wenn Sie folgende Fehler von @code{DBD-mysql} erhalten, benutzen Sie
+wahrscheinlich @code{gcc} (oder eine alte Binärdatei, die mit @code{gcc}
+kompiliert wurde):
+
+@example
+/usr/bin/perl: can't resolve symbol '__moddi3'
+/usr/bin/perl: can't resolve symbol '__divdi3'
+@end example
+
+Fügen Sie @code{-L/usr/lib/gcc-lib/... -lgcc} zum Link-Befehl hinzu,
+wenn die @file{mysql.so}-Bibliothek gebaut wird (überprüfen Sie die
+Ausgabe von @code{make} nach @file{mysql.so}, wenn Sie den Perl-Client
+kompilieren). Die @code{-L}-Option sollte den Pfadnamen des
+Verzeichnisses angeben, in dem @file{libgcc.a} auf Ihrem System liegt.
+
+Ein weiterer Grund für dieses Problem kann sein, dass Perl und MySQL
+nicht beide mit @code{gcc} kompiliert wurden. In diesem Fall können Sie
+die fehlende Übereinstimmung (Mismatch) durch Kompilieren von beiden mit
+@code{gcc} aufheben.
+
+Wenn Sie folgende Fehler von @code{Msql-Mysql-modules} erhalten, wenn
+Sie die Tests laufen lassen:
+
+@example
+t/00base............install_driver(mysql) failed: Can't load
+'../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
+../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: uncompress at
+/usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
+@end example
+
+Bedeutet das, dass Sie die Kompressionsbibliothek (-lz) in die Link-
+Zeile einschließen müssen. Das kann man durch folgende Änderung in der
+Datei @file{lib/DBD/mysql/Install.pm} tun:
+
+@example
+$sysliblist .= " -lm";
+
+ändern in
+
+$sysliblist .= " -lm -lz";
+@end example
+
+Danach @strong{müssen} Sie 'make realclean' laufen lassen und danach mit
+der Installation von Anfang an beginnen.
+
+Wenn Sie das Perl-Modul auf einem System laufen lassen wollen, das
+dynamisches Linken nicht unterstützt (wie Caldera/SCO), können Sie eine
+statische Version von Perl erzeugen, die @code{DBI} und @code{DBD-mysql}
+enthält. Das bringt man zum Laufen, indem man eine Version von Perl
+erzeugt, in der der @code{DBI}-Code eingelinkt ist, und diese über das
+aktuelle Perls installiert. Dann benutzen Sie diese, um eine Version von
+Perl zu bauen, die zusätzlich den @code{DBD}-Code eingelinkt hat, und
+installieren diese.
+
+Unter Caldera (SCO) müssen folgende Umgebungsvariablen gesetzt sein:
+
+@example
+shell> LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib
+or
+shell>
+LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
+shell>
+LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
+shell>
+MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:/usr/skunk/man:
+@end example
+
+Erzeugen Sie zuerst ein Perl, das ein statisch gelinktes @code{DBI}
+enthält, indem Sie diese Befehle im Verzeichnis ausführen, in dem Ihre
+@code{DBI}-Distribution liegt:
+
+@example
+shell> perl Makefile.PL -static -config
+shell> make
+shell> make install
+shell> make perl
+@end example
+
+Dann müssen Sie das neue Perl installieren. Die Ausgabe von @code{make
+perl} zeigt den genauen @code{make}-Befehl an, den Sie für die
+Installation ausführen müssen. Unter Caldera (SCO) ist das @code{make -f
+Makefile.aperl inst_perl MAP_TARGET=perl}.
+
+Benutzen Sie als nächstes dieses soeben erzeugte Perl, um ein weiteres
+Perl zu erzeugen, dass auch ein statisch gelinktes @code{DBD::mysql}
+enthält, indem Sie diese Befehle im Verzeichnis ausführen, in dem Ihre
+@code{Msql-Mysql-modules}-Distribution liegt:
+
+@example
+shell> perl Makefile.PL -static -config
+shell> make
+shell> make install
+shell> make perl
+@end example
+
+Zum Schluss müssen Sie dieses neue Perl installieren. Hierbei zeigt die
+Ausgabe von @code{make perl} wiederum, welcher Befehl benutzt werden
+muss.
+
+@node Tutorial, MySQL Database Administration, Installing, Top
+@c German node Tutorial
+@chapter Einführung in MySQL: Ein MySQL-Tutorial
+
+@cindex Tutorial
+@c Question: Uh - what's a defined terminal monitor?
+@cindex terminal monitor, defined
+@c Question: Uh - what's that for the index?
+@cindex monitor, terminal
+@cindex Optionen, von MySQL
+
+
+Dieses Kapitel enthält eine Einführung in MySQL in Form eines Tutorials.
+Datei wird gezeigt, wie Sie das @code{mysql}-Client-Programm benutzen, um
+eine einfache Datenbank zu erzeugen und zu benutzen. @code{mysql} (auch
+``Terminal-Monitor'' oder einfach ``Monitor'' genannt) ist ein interaktives
+Programm, mit dem Sie sich mit einem MySQL-Server verbinden, Anfragen
+(Queries) absetzen und die Ergebnisse ansehen können. @code{mysql} kann
+auch im Stapelbetrieb (Batch Mode) benutzt werden: Sie schreiben Ihre
+Anfragen zuerst in eine Datei und veranlassen dann @code{mysql}, die
+Inhalte dieser Datei auszuführen. Hier werden beide Möglichkeiten
+beschrieben, @code{mysql} zu benutzen.
+
+Sie können @code{mysql} mit der @code{--help}-Option aufrufen, um eine
+Liste der Optionen zu sehen:
+
+@example
+shell> mysql --help
+@end example
+
+Dieses Kapitel setzt voraus, dass @code{mysql} auf Ihrer Maschine
+installiert ist und dass ein MySQL-Server verfügbar ist, mit dem Sie sich
+verbinden können. Wenn das nicht der Fall sein sollte, setzen Sie sich mit
+Ihrem MySQL-Administrator in Verbindung. (Wenn @emph{Sie} der Administrator
+sind, müssen Sie in anderen Abschnitten des Handbuchs nachsehen.)
+
+Dieses Kapitel beschreibt den gesamten Prozess der Einrichtung und
+Benutzung einer Datenbank. Wenn Sie lediglich wissen wollen, wie man auf
+eine bereits existierende Datenbank zugreift, können Sie die Abschnitte
+überspringen, die beschreiben, wie man eine Datenbank und die Tabellen, die
+sie enthält, erzeugt.
+
+Weil dieses Kapitel ein Tutorial ist, wurden notwendigerweise viele Details
+ausgelassen. Sehen Sie in den relevanten Abschnitten dieses Handbuchs nach,
+wenn Sie weitere Informationen zu den Themen suchen, die hier besprochen
+werden.
+
+
+@menu
+* Connecting-disconnecting::
+* Entering queries::
+* Database use::
+* Getting information::
+* Examples::
+* Batch mode::
+* Twin::
+* Apache::
+@end menu
+
+@node Connecting-disconnecting, Entering queries, Tutorial, Tutorial
+@c German node Verbinden und Trennen
+@section Verbindung zum Server herstellen und trennen
+
+@cindex Verbinden, mit dem Server
+@cindex Verbindung trennen, mit dem Server
+@cindex Server, verbinden
+@cindex Server, Verbindung trennen
+
+Um sich zum Server zu verbinden, müssen Sie beim Aufruf von @code{mysql} in
+der Regel einen MySQL-Benutzernamen und üblicherweise auch ein Passwort
+angeben. Wenn der Server auf einer anderen Maschine als der läuft, von der
+Sie sich einloggen, müssen Sie auch einen Hostnamen angeben. Setzen Sie
+sich mit Ihrem Administrator in Verbindung, um herauszubekommen, welche
+Verbindungsparameter Sie benutzen sollten (das heißt welchen Host,
+welchen Benutzername und welches Passwort Sie verwenden sollen). Wenn Sie
+die richtigen Parameter kennen, sollten Sie sich wie folgt verbinden
+können:
+
+@example
+shell> mysql -h host -u user -p
+Enter password: ********
+@end example
+
+@code{********} steht für Ihr Passwort. Geben Sie es ein, wenn @code{mysql}
+@code{Enter password:} anzeigt.
+
+Wenn das funktioniert hat, sehen Sie ein paar einführende Informationen,
+gefolgt von der @code{mysql>}-Eingabeaufforderung:
+
+
+@example
+shell> mysql -h host -u user -p
+Enter password: ********
+Welcome to the MySQL monitor. Commands end mit ; or \g.
+Your MySQL connection id ist 459 to server version: 3.22.20a-log
+
+Type 'help' for help.
+
+mysql>
+@end example
+
+Die Eingabeaufforderung sagt Ihnen, dass @code{mysql} bereit für die
+Eingabe von Befehlen ist.
+
+Einige
+Einige MySQL-Installationen erlauben Benutzern, sich als anonyme
+(unbenannte) Benutzer mit dem Server auf dem lokalen Host zu verbinden.
+Wenn das auf Ihrer Maschine der Fall ist, können Sie sich mit diesem Server
+verbinden, indem Sie @code{mysql} ohne irgend welche Optionen aufrufen:
+
+@example
+shell> mysql
+@end example
+
+Nachdem Sie sich erfolgreich verbunden haben, können Sie die Verbindung
+jederzeit trennen, indem Sie @code{QUIT} an der
+@code{mysql>}-Eingabeaufforderung eingeben.
+
+@example
+mysql> QUIT
+Bye
+@end example
+
+Sie können die Verbindung auch trennen, indem Sie STRG+D eingeben.
+
+Die meisten Beispiele der folgenden Abschnitte setzen voraus, dass Sie mit
+dem Server verbunden sind. Das wird durch @code{mysql>} angezeigt.
+
+
+@node Entering queries, Database use, Connecting-disconnecting, Tutorial
+@c German node Anfragen eingeben
+@section Anfragen eingeben
+
+@cindex Absetzen, Anfragen
+@cindex Anfragen, absetzen
+@cindex Eingeben, Anfragen
+
+Stellen Sie sicher, dass Sie mit dem Server verbunden sind, wie im
+vorherigen Abschnitt erörtert. Dadurch wird noch keine Datenbank
+ausgewählt, mit der Sie arbeiten können, aber das ist in Ordnung. Hier ist
+es erst einmal wichtiger, herauszufinden, wie Sie Anfragen (Queries)
+absetzen, als direkt mit dem Erzeugen von Tabellen, dem Einladen von Daten
+in diese und der Abfrage von Daten aus diesen zu beginnen. Dieser Abschnitt
+beschreibt die grundlegenden Prinzipien der Befehlseingabe, indem etliche
+Anfragen gezeigt werden, die Sie ausprobieren können, um sich mit der
+Arbeitsweise von @code{mysql} vertraut zu machen.
+
+Hier ist ein einfacher Befehl, der den Server bittet, Ihnen seine
+Versionsnummer und das aktuelle Datum mitzuteilen. Geben Sie folgendes an
+der @code{mysql>}-Eingabeaufforderung ein und drücken Sie die Eingabetaste:
+
+@example
+mysql> SELECT VERSION(), CURRENT_DATE;
++--------------+--------------+
+| version() | CURRENT_DATE |
++--------------+--------------+
+| 3.22.20a-log | 1999-03-19 |
++--------------+--------------+
+1 row in set (0.01 sec)
+mysql>
+@end example
+
+Diese Anfrage erläutert verschiedene Dinge über @code{mysql}:
+
+@itemize @bullet
+@item
+Ein Befehl besteht normalerweise aus einem SQL-Statement, gefolgt von einem
+Semikolon. (Es gibt ein paar Ausnahmen, bei denen das Semikolon nicht
+benötigt wird. @code{QUIT}, das vorher erwähnt wurde, stellt eine solche
+Ausnahme dar. Wir kommen später noch zu anderen Ausnahmen.)
+
+@item
+Wenn Sie einen Befehl absetzen, sendet @code{mysql} ihn zum Server, der ihn
+ausführt, und zeigt die Ergebnisse an. Danach wird eine neue
+@code{mysql>}-Eingabeaufforderung angezeigt, um klar zu machen, dass es für
+einen weiteren Befehl bereit ist.
+
+@item
+@code{mysql} zeigt die Ausgabe der Anfrage in Tabellenform an (Zeilen und
+Spalten). Die erste Zeile enthält Spaltenüberschriften. Die folgenden
+Zeilen sind die Ergebnisse der Anfrage. Normalerweise sind die
+Spaltenüberschriften die Spaltennamen der Tabellen, die Sie abfragen. Wenn
+Sie statt der Spaltennamen den Wert eines Ausdrucks abfragen (wie im
+gezeigten Beispiel), beschriftet @code{mysql} die Spaltenüberschrift mit
+dem Ausdruck selbst.
+
+@item
+@code{mysql} zeigt, wie viele Zeilen zurück gegeben wurden und wie lang die
+Ausführung der Anfrage dauerte, was ihnen eine grobe Einschätzung der
+Server-Performance ermöglicht. Diese Werte sind ungenau, weil sie die
+Wanduhrzeit repräsentieren (und nicht die Prozessor- oder Maschinenzeit),
+und weil sie von Faktoren wie der Serverlast und der Netzwerk-Wartezeit
+beeinflusst werden. (Um uns kurz zu fassen, zeigen wir die ``rows in
+set''-Zeile in den weiteren Beispielen dieses Kapitels nicht mehr an.)
+@end itemize
+
+Schlüsselwörter können in beliebiger Schreibweise (Groß und klein)
+eingegeben werden. Folgende Anfragen sind gleichwertig:
+
+@example
+mysql> SELECT VERSION(), CURRENT_DATE;
+mysql> select version(), current_date;
+mysql> SeLeCt vErSiOn(), current_DATE;
+@end example
+
+Hier kommt eine weitere Anfrage. Sie zeigt, wie Sie @code{mysql} als
+einfachen Rechner benutzen können:
+
+@example
+mysql> SELECT SIN(PI()/4), (4+1)*5;
++-------------+---------+
+| SIN(PI()/4) | (4+1)*5 |
++-------------+---------+
+| 0.707107 | 25 |
++-------------+---------+
+@end example
+
+Die bislang gezeigten Befehle sind relativ kurze, einzeilige Statements.
+Sie können allerdings auch mehrfache Statements auf einer einzelnen Zeile
+eingeben. Beenden Sie einfach jedes davon mit einem Semikolon:
+
+@example
+mysql> SELECT VERSION(); SELECT NOW();
++--------------+
+| version() |
++--------------+
+| 3.22.20a-log |
++--------------+
+
++---------------------+
+| NOW() |
++---------------------+
+| 1999-03-19 00:15:33 |
++---------------------+
+@end example
+
+Ein Befehl muss nicht auf einer einzelnen Zeile eingegeben werden, so dass
+längere Befehle, die mehrere Zeilen erfordern, kein Problem darstellen.
+@code{mysql} stellt anhand des beendenden Semikolons fest, wo Ihr Statement
+endet, und nicht etwa anhand des Zeilenendes. (Mit anderen Worten
+akzeptiert @code{mysql} Freiformat-Eingaben: Es sammelt Eingabezeilen,
+führt sie aber solange nicht aus, bis es das Semikolon sieht.)
+
+Hier ist ein einfaches Statement, auf mehrere Zeilen verteilt:
+
+@example
+mysql> SELECT
+ -> USER()
+ -> ,
+ -> CURRENT_DATE;
++--------------------+--------------+
+| USER() | CURRENT_DATE |
++--------------------+--------------+
+| joesmith@@localhost | 1999-03-18 |
++--------------------+--------------+
+@end example
+
+Sehen Sie, wie sich die Eingabeaufforderung von @code{mysql>} zu @code{->}
+ändert, nachdem Sie die erste Zeile der Mehrzeilen-Anfrage eingegeben
+haben. Auf diese Weise zeigt @code{mysql} an, dass es noch nicht das
+komplette Statement gesehen hat und auf den Rest wartet. Die
+Eingabeaufforderung ist Ihr Freund, denn sie stellt wertvolle Rückmeldungen
+zur Verfügung. Wenn Sie diese Rückmeldungen nutzen, werden Sie immer dessen
+gewahr sein, worauf @code{mysql} wartet.
+
+Wenn Sie den Befehl, den Sie gerade eingeben, nicht ausführen wollen,
+können Sie ihn mit @code{\c} abbrechen:
+
+@example
+mysql> SELECT
+ -> USER()
+ -> \c
+mysql>
+@end example
+
+Beachten Sie auch hierbei die Eingabeaufforderung. Sie ändert sich zurück
+zu @code{mysql>}, nachdem Sie @code{\c} eingegeben haben, und diese
+Rückmeldung bedeutet, dass @code{mysql} für einen weiteren Befehl bereit
+ist.
+
+Folgende Tabelle zeigt alle Eingabeaufforderungen, denen Sie begegnen
+können, und fasst zusammen, was sie über den Zustand von @code{mysql}
+aussagen:
+
+@cindex Eingabeaufforderungen, Bedeutungen
+@multitable @columnfractions .10 .9
+@item @strong{Eingabeaufforderung} @tab @strong{Bedeutung}
+@item @code{mysql>} @tab Bereit für den nächsten Befehl.
+@item @code{@ @ @ @ ->} @tab Wartet auf die nächste Zeile eines
+mehrzeiligen Befehls.
+@item @code{@ @ @ @ '>} @tab Wartet auf die nächste Zeile und
+fasst eine Zeichenkette zusammen, die mit einem Apostroph (@samp{'})
+beginnt.
+@item @code{@ @ @ @ ">} @tab Wartet auf die nächste Zeile und
+fasst eine Zeichenkette zusammen, die mit Anführungszeichen (@samp{"})
+beginnt.
+@end multitable
+
+Mehrzeilige Statements passieren häufig aus Versehen, wenn Sie vorhaben,
+einen Befehl auf einer einzelnen Zeile abzusetzen, aber das beendende
+Semikolon vergessen. In diesem Fall wartet @code{mysql} auf weitere
+Eingaben:
+
+@example
+mysql> SELECT USER()
+ ->
+@end example
+
+Wenn so etwas passiert (Sie dachten, Sie hätten ein Statement eingegeben,
+aber die einzige Antwort ist die @code{->}-Eingabeaufforderung), wartet
+@code{mysql} höchstwahrscheinlich auf das Semikolon. Wenn Sie nicht darauf
+achten, was Ihnen die Eingabeaufforderung mitteilen will, könnten Sie eine
+ganze Weile herum sitzen, bevor Sie feststellen, was Sie tun müssen. Geben
+Sie ein Semikolon ein, um das Statement zu vollenden, und @code{mysql} wird
+es ausführen:
+
+@example
+mysql> SELECT USER()
+ -> ;
++--------------------+
+| USER() |
++--------------------+
+| joesmith@@localhost |
++--------------------+
+@end example
+
+Die @code{'>}- und @code{">}-Eingabeaufforderungen kommen bei der Sammlung
+von Zeichenketten vor. In MySQL können Sie Zeichenketten wahlweise in
+@samp{'}- oder @samp{"}-Zeichen eingeschlossen eingeben (zum Beispiel
+@code{'hallo'} oder @code{"tschüß"}), und @code{mysql} läßt Sie auch
+Zeichenketten eingeben, die sich über mehrere Zeilen erstrecken. Wenn Sie
+eine @code{'>}- oder @code{">}-Eingabeaufforderung sehen, heißt das, dass
+Sie eine Zeile eingegeben haben, die eine Zeichenkette enthält, die mit
+@samp{'} oder @samp{"} beginnt, dass Sie aber noch nicht das entsprechende
+beendende Zeichen (ebenfalls @samp{'} oder @samp{"}) eingegeben haben. Das
+ist in Ordnung, wenn Sie tatsächlich eine mehrzeilige Zeichenkette
+eingeben, aber wie wahrscheinlich ist das? Nicht sehr wahrscheinlich.
+Wahrscheinlicher ist, dass die @code{'>}- und
+@code{">}-Eingabeaufforderungen anzeigen, dass Sie versehentlich ein
+@samp{'}- oder @samp{"}-Zeichen ausgelassen haben. Beispiel:
+
+@example
+mysql> SELECT * FROM meine_tabelle WHERE name = "Schmidt AND age < 30;
+ ">
+@end example
+
+Wenn Sie dieses @code{SELECT}-Statement eingeben, dann EINGABE drücken und
+auf das Ergebnis warten, wird nichts passieren. Statt sich zu fragen, warum
+diese Anfrage so lange dauert, beachten Sie des Rätsels Lösung, die die
+@code{">}-Eingabeaufforderung anzeigt. Sie sagt Ihnen, dass @code{mysql}
+auf den Rest einer nicht beendeten Zeichenkette wartet. (Sehen Sie den
+Fehler im Statement? Der Zeichenkette @code{"Schmidt} fehlt das zweite
+Anführungszeichen.)
+
+Was machen Sie in diesem Fall? Das einfachste ist, den Befehl abzubrechen.
+Sie können jetzt allerdings nicht einfach @code{\c} eingeben, weil
+@code{mysql} es als Teil der Zeichenkette interpretieren würde, die es
+gerade sammelt! Geben Sie daher zuerst das schließende Anführungszeichen
+ein, damit @code{mysql} weiß, dass die Zeichenkette zuende ist, und erst
+danach @code{\c}:
+
+@example
+mysql> SELECT * FROM meine_tabelle WHERE name = "Schmidt AND age < 30;
+ "> "\c
+mysql>
+@end example
+
+Die Eingabeaufforderung ändert sich wieder zu @code{mysql>} und zeigt damit
+an, dass @code{mysql} für einen weiteren Befehl bereit ist.
+
+Es ist wichtig, die Bedeutung der @code{'>}- und
+@code{">}-Eingabeaufforderungen zu kennen, denn wenn Sie versehentlich
+eine nicht beendete Zeichenkette eingeben, werden alle folgenden Zeilen,
+die Sie eingeben, von @code{mysql} ignoriert - inklusive einer Zeile, die
+@code{QUIT} enthält! Das kann recht verwirrend sein, besonders dann, wenn
+Sie nicht wissen, dass Sie das schließende Anführungszeichen eingeben
+müssen, bevor Sie den aktuellen Befehl abbrechen können.
+
+
+@node Database use, Getting information, Entering queries, Tutorial
+@c German node Datenbankbenutzung
+@section Eine Datenbank erzeugen und benutzen
+
+@cindex Datenbanken, erzeugen
+@cindex Datenbanken, benutzen
+@cindex Erzeugen, Datenbanken
+
+
+Jetzt, wo Sie wissen, wie Sie Befehle eingeben, ist es Zeit, auf eine
+Datenbank zuzugreifen.
+
+Nehmen wir an, Sie haben zuhause mehrere Haustiere (Ihre Menagerie) und Sie
+wollen unterschiedliche Arten von Information über sie im Überblick
+behalten. Das können Sie tun, indem Sie Tabellen erzeugen, die Ihre Daten
+beinhalten, und die Sie mit den gewünschten Informationen füllen. Dann
+können Sie verschiedene Arten von Fragen über Ihre Haustiere beantworten,
+indem Sie Daten aus den Tabellen abrufen. Dieser Abschnitt zeigt Ihnen:
+
+@itemize @bullet
+@item
+Wie Sie eine Datenbank erzeugen
+@item
+Wie Sie eine Tabelle anlegen
+@item
+Wie Sie Daten in die Tabelle laden
+@item
+Wie Sie auf unterschiedliche Weise Daten aus der Tabelle abfragen
+@item
+Wie Sie mehrere Tabellen benutzen
+@end itemize
+
+Die Menagerie-Datenbank wird (bewusst) einfach sein, aber man kann sich
+leicht Situationen im echten Leben vorstellen, in denen ein ähnlicher Typ
+von Datenbank benutzt werden könnte. Beispielsweise könnte ein Bauer eine
+solche Datenbankbenutzung, um den Überblick über sein Vieh zu behalten,
+oder ein Tierarzt, um seine Patientendaten im Griff zu haben. Sie finden
+eine Menagerie-Distribution, die einige der benutzten Anfragen und
+Beispielsdaten enthält, auf der MySQL-Website.
+Sie finden die Distribution entweder unter
+@uref{http://www.mysql.com/downloads/Contrib/Examples/menagerie.tar.gz,komprimiertes @code{tar}-Format}
+oder unter
+@uref{http://www.mysql.com/downloads/Contrib/Beispiele/menagerie.zip,Zip-Format}.
+
+Benutzen Sie das @code{SHOW}-Statement, um herauszufinden, welche
+Datenbanken zur Zeit auf dem Server existieren:
+
+@example
+mysql> SHOW DATABASES;
++----------+
+| database |
++----------+
+| mysql |
+| test |
+| tmp |
++----------+
+@end example
+
+Die Liste der Datenbanken weicht wahrscheinlich von derjenigen auf Ihrer
+Maschine ab, aber wahrscheinlich befinden sich die @code{mysql}- und
+@code{test}-Datenbanken darunter. Die @code{mysql}-Datenbank ist notwendig,
+weil darin die Zugriffsrechte für Benutzer gespeichert sind. Die
+@code{test}-Datenbank ist meist als Arbeitsbereich zum Ausprobieren dabei.
+
+Wenn die @code{test}-Datenbank existiert, versuchen Sie, darauf
+zuzugreifen:
+
+@example
+mysql> USE test
+database changed
+@end example
+
+Beachten Sie, dass @code{USE} - wie @code{QUIT} - kein Semikolon erfordert.
+(Sie können solche Statements mit einem Semikolon beenden, wenn Sie wollen,
+es schadet nicht.) Das @code{USE}-Statement ist auch auf andere Art
+besonders: Es muss auf einer einzigen Zeile eingegeben werden.
+
+Sie können die @code{test}-Datenbank für die folgenden Beispiele benutzen
+(wenn Sie Zugriff darauf haben), aber alles, was Sie dort anlegen, kann von
+jedem sonstigen, der Zugriff darauf hat, entfernt werden. Aus diesem Grund
+sollten Sie besser Ihren MySQL-Administrator um Erlaubnis bitten, eine
+eigene Datenbankbenutzung zu können. Nehmen wir an, Sie wollen Ihre
+Datenbank @code{menagerie} nennen. Dafür muss der Administrator folgenden
+Befehl eingeben:
+
+@example
+mysql> GRANT ALL ON menagerie.* TO ihr_mysql_name;
+@end example
+
+Wobei @code{ihr_mysql_name} der MySQL-Benutzername ist, der Ihnen
+zugewiesen wurde.
+
+
+@menu
+* Creating database::
+* Creating tables::
+* Loading tables::
+* Retrieving data::
+@end menu
+
+@node Creating database, Creating tables, Database use, Database use
+@c German node Datenbank erzeugen
+@subsection Eine Datenbank erzeugen und auswählen
+
+@cindex Auswählen, Datenbanken
+@cindex Datenbanken, auswählen
+
+Wenn der Administrator für Sie eine Datenbank erzeugt, wenn er Ihre
+Zugriffsrechte einträgt, können Sie sie unmittelbar benutzen. Ansonsten
+müssen Sie sie selbst anlegen:
+
+@example
+mysql> CREATE DATABASE menagerie;
+@end example
+
+Unter Unix sind Datenbanknamen abhängig von der Groß-/Kleinschreibung (im
+Gegensatz zu SQL-Schlüsselwörtern), daher müssen Sie sich auf Ihre
+Datenbank immer mit @code{menagerie} beziehen, nicht mit @code{Menagerie},
+@code{MENAGERIE} oder irgend einer anderen Variante. Dasselbe gilt für
+Tabellennamen. (Unter Windows trifft diese Beschränkung nicht zu. Dennoch
+muss man sich bei einer gegebenen Anfrage auf Datenbanken und Tabellen in
+derselben Schreibweise beziehen.)
+
+Das Erzeugen einer Datenbank wählt diese nicht zur Benutzung aus. Das
+müssen Sie explizit tun. Um @code{menagerie} zur aktuell ausgewählten
+Datenbank zu machen, benutzen Sie folgenden Befehl:
+
+@example
+mysql> USE menagerie
+database changed
+@end example
+
+Ihre Datenbank muss nur einmal erzeugt werden, aber Sie müssen sie jedes
+Mal zur Benutzung auswählen, wenn Sie eine @code{mysql}-Sitzung beginnen.
+Das können Sie durch die Eingabe eines @code{USE}-Statements wie oben
+beschrieben tun. Alternativ können Sie die Datenbank auf der Kommandozeile
+auswählen, wenn Sie @code{mysql} aufrufen. Geben Sie einfach ihren Namen
+nach den Verbindungsparametern ein, die Sie ansonsten eingeben müssen.
+Beispiel:
+
+@example
+shell> mysql -h host -u user -p menagerie
+Enter password: ********
+@end example
+
+Beachten Sie, dass @code{menagerie} auf der gezeigten Kommandozeile nicht
+Ihr Passwort ist! Wenn Sie Ihr Passwort auf der Kommandozeile nach der
+@code{-p}-Option eingeben wollen, müssen Sie das ohne Leerzeichen
+dazwischen machen (beispielsweise als @code{-pmeinpasswort}, nicht als
+@code{-p meinpasswort}). Es wird allerdings nicht empfohlen, das Passwort
+auf der Kommandozeile einzugeben, denn dann kann es durch andere Benutzer,
+die auf Ihrer Maschine eingeloggt sind, ausspioniert werden.
+
+
+@node Creating tables, Loading tables, Creating database, Database use
+@c German node Tabellen erzeugen
+@subsection Eine Tabelle erzeugen
+
+@cindex Tabellen, erzeugen
+@cindex Erzeugen, Tabellen
+Die Datenbank zu erzeugen ist leicht, aber bis jetzt ist sie noch leer, wie
+Ihnen @code{SHOW TABLES} zeigt:
+
+@example
+mysql> SHOW TABLES;
+Empty set (0.00 sec)
+@end example
+
+Der schwierigere Teil besteht darin, sich zu entscheiden, wie die Struktur
+Ihrer Datenbank sein sollte: Welche Tabellen Sie benötigen und welche
+Spalten in jeder Tabelle enthalten sein sollen.
+
+Sie brauchen eine Tabelle, die für jedes Ihrer Haustiere einen Datensatz
+enthält. Diese kann @code{pet}-Tabelle genannt werden, und sie sollte
+zumindest den Namen jedes Tiers enthalten. Weil lediglich der Name nicht
+besonders interessant ist, sollte die Tabelle weitere Informationen
+enthalten. Wenn zum Beispiel mehr als eine Person in Ihrer Familie ein
+Haustier hält, würden Sie den Namen des Besitzers jedes Haustiers auflisten
+wollen. Ausserdem wollen Sie vielleicht ein paar grundlegende Informationen
+wie Art und Geschlecht einfügen.
+
+Was ist mit dem Alter? Diese Information könnte interessant sein, aber es
+ist keine gute Idee, sie in der Datenbank zu speichern. Das Alter ändert
+sich, wenn die Zeit vergeht, was bedeutet, dass Sie Ihre Datensätze oft
+aktualisieren müssen. Statt dessen ist es besser, einen festen Wert wie das
+Geburtsdatum zu speichern. Immer, wenn Sie dann das Alter benötigen,
+berechnen Sie es als Differenz zwischen dem aktuellen Datum und dem
+Geburtstag. MySQL stellt Funktionen für Datumsberechnungen zur Verfügung,
+daher ist so etwas nicht schwer. Ausserdem hat die Speicherung von
+Geburtsdaten anstelle von Alter weitere Vorteile:
+
+@itemize @bullet
+@item
+Sie können die Datenbank für Aufgaben wie die Erzeugung einer Liste
+bevorstehender Tier-Geburtstage benutzen. (Wenn Sie das etwas albern
+finden, bedenken Sie, dass sich dieselbe Frage zum Beispiel bei einer
+Geschäftsdatenbank stellt, um Kunden herauszufinden, denen Sie in Kürze
+Geburtstagswünsche schicken wollen, also für die Computer-unterstützte
+persönliche Note.)
+
+@item
+Sie können Altersberechnungen mit anderen Bezugsdaten als dem aktuellen
+Datum durchführen. Wenn Sie das Sterbedatum speichern, können Sie zum
+Beispiel leicht errechnen, wie alt ein Haustier war, als es starb.
+@end itemize
+
+Wahrscheinlich fallen Ihnen weitere Informationen ein, die sinnvoller Weise
+in der @code{pet}-Tabelle gespeichert werden könnten. Für unser Beispiel
+sollen die bisher identifizierten Informationen fürs Erste ausreichen:
+Name, Besitzer, Art, Geschlecht, Geburtstag und Sterbetag.
+
+Legen Sie mit einem @code{CREATE TABLE}-Statement das Layout Ihrer Tabelle
+fest:
+
+@example
+mysql> CREATE TABLE pet (name VARCHAR(20), besitzer VARCHAR(20),
+ -> art VARCHAR(20), geschlecht CHAR(1), geburtstag DATE, sterbetag DATE);
+@end example
+
+@code{VARCHAR} ist für die @code{name}-, @code{besitzer}- und
+@code{art}-Spalten eine gute Wahl, weil die Spaltenwerte in der Länge
+variieren werden. Diese Spalten müssen auch nicht alle gleich sein, also
+@code{20} Zeichen lang. Sie können jede beliebige Länge zwischen @code{1}
+und @code{255} wählen, was immer Ihnen vernünftig erscheint. (Wenn Sie eine
+schlechte Wahl getroffen haben und sich später herausstellt, dass Sie eine
+längere Spalte brauchen, stellt MySQL ein @code{ALTER TABLE}-Statement zur
+Verfügung.)
+
+Das Geschlecht der Tiere kann vielfältig dargestellt werden, zum Beispiel
+als @code{"m"} und @code{"w"}, oder auch als @code{"männlich"} und
+@code{"weiblich"}. Am einfachsten ist es, hierfür einzelne Zeichen wie
+@code{"m"} und @code{"w"} zu verwenden.
+
+Der @code{DATE}-Datentyp für @code{geburtstag} und @code{sterbetag} liegt
+auf der Hand.
+
+Nachdem Sie eine Tabelle angelegt haben, sollte @code{SHOW TABLES} auch
+etwas zeigen:
+
+@example
+mysql> SHOW TABLES;
++---------------------+
+| Tables in menagerie |
++---------------------+
+| pet |
++---------------------+
+@end example
+
+Um sicherzustellen, dass Ihre Tabelle so wie erwartet angelegt wurde,
+benutzen Sie das @code{DESCRIBE}-Statement:
+
+@example
+mysql> DESCRIBE pet;
++------------+-------------+------+-----+---------+-------+
+| Field | Type | Null | Key | Default | Extra |
++------------+-------------+------+-----+---------+-------+
+| name | varchar(20) | YES | | NULL | |
+| besitzer | varchar(20) | YES | | NULL | |
+| art | varchar(20) | YES | | NULL | |
+| geschlecht | char(1) | YES | | NULL | |
+| geburtstag | date | YES | | NULL | |
+| sterbetag | date | YES | | NULL | |
++------------+-------------+------+-----+---------+-------+
+@end example
+
+Sie können @code{DESCRIBE} jederzeit benutzen, zum Beispiel, wenn Sie die
+Namen der Spalten Ihrer Tabelle vergessen haben oder von welchem Datentyp
+sie sind.
+
+
+@node Loading tables, Retrieving data, Creating tables, Database use
+@c German node Tabellen füllen
+@subsection Daten in Tabellen einladen
+
+@cindex Einladen, Tabellen
+@cindex Tabellen, Daten einladen
+@cindex Daten, in Tabellen laden
+
+Nachdem Sie Ihre Tabelle erzeugt haben, müssen Sie sie mit Daten füllen.
+Hierfür sind die @code{LOAD DATA}- und @code{INSERT}-Statements nützlich.
+
+Nehmen wir an, Sie haben Haustiere wie unten aufgeführt. (Achten Sie bei
+den Datumsangaben bitte darauf, dass MySQL Daten im
+@code{YYYY-MM-DD}-Format erwartet, was von dem Format abweichen kann, an
+das Sie gewohnt sind.)
+
+@multitable @columnfractions .16 .16 .16 .16 .16 .16
+@item @strong{name} @tab @strong{besitzer} @tab @strong{art} @tab @strong{geschlecht} @tab @strong{geburtstag} @tab @strong{sterbetag}
+@item Fluffy @tab Harold @tab Katze @tab w @tab 1993-02-04 @tab
+@item Claws @tab Gwen @tab Katze @tab m @tab 1994-03-17 @tab
+@item Buffy @tab Harold @tab Hund @tab w @tab 1989-05-13 @tab
+@item Fang @tab Benny @tab Hund @tab m @tab 1990-08-27 @tab
+@item Bowser @tab Diane @tab Hund @tab m @tab 1998-08-31 @tab 1995-07-29
+@item Chirpy @tab Gwen @tab Vogel @tab w @tab 1998-09-11 @tab
+@item Whistler @tab Gwen @tab Vogel @tab @tab 1997-12-09 @tab
+@item Slim @tab Benny @tab Schlange @tab m @tab 1996-04-29 @tab
+@end multitable
+
+Weil Sie mit einer leeren Tabelle beginnen, ist eine einfache Möglichkeit,
+diese mit Daten zu füllen, dass Sie eine Textdatei erzeugen, die eine Zeile
+für jedes Ihrer Tiere enthält, und die Inhalte dieser Datei dann mit einem
+einzigen Statement in die Tabelle laden.
+
+Erzeugen Sie also eine Textdatei @file{pet.txt}, die einen Datensatz pro
+Zeile enthält, mit Werten, die durch TAB-Zeichen getrennt sind, und zwar in
+der Reihenfolge, in der die Spalten im @code{CREATE TABLE}-Statement
+aufgeführt waren. Fehlende Werte (wie unbekanntes Geschlecht oder
+Sterbedaten für Tiere, die noch leben) ersetzen Sie mit @code{NULL}-Werten.
+Um das in Ihrer Textdatei darzustellen, nehmen Sie @code{\N}. Der Datensatz
+für den Vogel Whistler zum Beispiel sieht wie folgt aus (wobei der Leerraum
+zwischen den Werten ein einzelnes TAB-Zeichen darstellt):
+
+@multitable @columnfractions .15 .15 .15 .15 .25 .15
+@item @code{Whistler} @tab @code{Gwen} @tab @code{Vogel} @tab @code{\N} @tab @code{1997-12-09} @tab @code{\N}
+@end multitable
+
+Um die Textdatei @file{pet.txt} in die @code{pet}-Tabelle zu laden,
+benutzen Sie folgenden Befehl:
+
+@example
+mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
+@end example
+
+Sie können das Trennzeichen für die Spalten und das Zeichen für Zeilenende
+im @code{LOAD DATA}-Statement explizit festlegen, wenn Sie wollen, aber
+vorgabemäßig sind das das TAB-Zeichen und das Zeilenvorschub-Zeichen. Das
+reicht für das Statement aus, um die Datei @file{pet.txt} korrekt
+einzulesen.
+
+Wenn Sie einzeln neue Datensätze hinzufügen wollen, ist das
+@code{INSERT}-Statement nützlich. In seiner einfachsten Form geben Sie für
+jede Spalte Werte an, in genau der Reihenfolge, in der die Spalten im
+@code{CREATE TABLE}-Statement aufgeführt wurden. Nehmen wir an, dass Diane
+einen neuen Hamster namens Puffball bekommt. Sie fügen einen neuen
+Datensatz mittels @code{INSERT}-Statement wie folgt hinzu:
+
+@example
+mysql> INSERT INTO pet
+ -> VALUES ('Puffball','Diane','Hamster','w','1999-03-30',NULL);
+@end example
+
+Beachten Sie, dass hierbei Zeichenketten- und Datumswerte in
+Anführungszeichen stehen. Mit @code{INSERT} können Sie auch direkt
+@code{NULL} einfügen, um einen fehlenden Wert darzustellen. Sie können
+dafür nicht @code{\N} wie bei @code{LOAD DATA} verwenden.
+
+Diesem Beispiel können Sie auch entnehmen, dass es einiger Tipparbeit
+bedurft hätte, die anfänglichen Datensätze mit mehreren
+@code{INSERT}-Statements einzufügen, statt hierfür ein einziges @code{LOAD
+DATA}-Statement zu verwenden.
+
+
+@node Retrieving data, , Loading tables, Database use
+@c German node Daten abrufen
+@subsection Informationen aus einer Tabelle abfragen
+
+@cindex Daten, abrufen
+@cindex Tabellen, Daten abrufen
+@cindex Abrufen, Daten aus Tabellen
+@cindex Entladen, Tabellen
+
+
+Das @code{SELECT}-Statement wird benutzt, um Informationen aus einer
+Tabelle herauszuziehen. Die allgemeine Form des Statements ist:
+
+@example
+SELECT auszuwählende_spalten
+FROM tabelle
+WHERE gewünschte_bedingungen
+@end example
+
+@code{auszuwählende_spalten} bezeichnet, was Sie sehen wollen. Das kann
+entweder eine Liste von Spalten sein oder @code{*}, um ``alle Spalten'' zu
+bezeichnen. @code{tabelle} kennzeichnet die Tabelle, aus der Sie Spalten
+abfragen wollen. Die @code{WHERE}-Klausel ist optional. Wenn sie vorhanden
+ist, kennzeichnet @code{gewünschte_bedingungen} die Bedingungen, mit denen
+die Zeilen übereinstimmen müssen, damit sie abgefragt werden.
+
+
+@menu
+* Selecting all::
+* Selecting rows::
+* Selecting columns::
+* Sorting rows::
+* Date calculations::
+* Working with NULL::
+* Pattern matching::
+* Counting rows::
+* Multiple tables::
+@end menu
+
+@node Selecting all, Selecting rows, Retrieving data, Retrieving data
+@c German node Alles auswählen
+@subsubsection Alle Daten auswählen
+
+Die einfachste Form von @code{SELECT} fragt alles aus einer Tabelle ab:
+
+@example
+mysql> SELECT * FROM pet;
++----------+----------+----------+------------+------------+------------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++----------+----------+----------+------------+------------+------------+
+| Fluffy | Harold | Katze | w | 1993-02-04 | NULL |
+| Claws | Gwen | Katze | m | 1994-03-17 | NULL |
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
+| Fang | Benny | Hund | m | 1990-08-27 | NULL |
+| Bowser | Diane | Hund | m | 1998-08-31 | 1995-07-29 |
+| Chirpy | Gwen | Vogel | w | 1998-09-11 | NULL |
+| Whistler | Gwen | Vogel | NULL | 1997-12-09 | NULL |
+| Slim | Benny | Schlange | m | 1996-04-29 | NULL |
+| Puffball | Diane | Hamster | w | 1999-03-30 | NULL |
++----------+----------+----------+------------+------------+------------+
+@end example
+
+Diese Form von @code{SELECT} ist nützlich, wenn Sie Ihre gesamte Tabelle
+abfragen wollen, zum Beispiel, wenn Sie sich gerade mit einem anfänglichen
+Satz Daten geladen haben. Wie das so passiert, zeigt die Ausgabe einen
+Fehler auf: Bowser scheint gestorben zu sein, bevor er geboren wurde! In
+den Original-Stammbaum-Papieren finden Sie, dass das korrekte Geburtsjahr
+1989 ist, nicht 1998.
+
+Es gibt eine ganze Reihe Möglichkeiten, das zu beheben:
+
+@itemize @bullet
+@item
+Editieren Sie die Datei @file{pet.txt} und beheben Sie den Fehler. Leeren
+Sie dann die Tabelle und laden Sie erneut Daten hinein, indem Sie zuerst
+@code{DELETE} und dann @code{LOAD DATA} benutzen:
+
+@example
+mysql> SET AUTOCOMMIT=1; # Für schnelles Neuerzeugen der Tabelle
+mysql> DELETE FROM pet;
+mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
+@end example
+
+Wenn Sie das jedoch tun, müssen Sie die Daten für Puffball erneut eingeben.
+
+@item
+Den fehlerhaften Datensatz mit einem @code{UPDATE}-Statement in Ordnung
+bringen:
+
+@example
+mysql> UPDATE pet SET geburtstag = "1989-08-31" WHERE name = "Bowser";
+@end example
+@end itemize
+
+Wie gezeigt ist es einfach, eine ganze Tabelle abzufragen. Aber
+typischerweise wird das selten gewünscht sein, besonders, wenn die Tabelle
+Groß wird. Statt dessen werden Sie an der Antwort auf bestimmte Fragen
+interessiert sein, wobei Sie ein paar Beschränkungen in Bezug auf die
+Informationen, die Sie wollen, festlegen. Schauen wir uns einige
+Auswahl-Anfragen an, hinsichtlich der Fragen in Bezug auf Ihre Haustiere,
+die sie beantworten.
+
+
+@node Selecting rows, Selecting columns, Selecting all, Retrieving data
+@c German node Zeilen auswählen
+@subsubsection Bestimmte Zeilen auswählen
+
+@cindex Zeilen, auswählen
+@cindex Tabellen, Zeilen auswählen
+
+Sie können nur bestimmte Zeilen Ihrer Tabelle auswählen. Wenn Sie zum
+Beispiel die Geburtstags-Änderung von Bowser überprüfen wollen, wählen Sie
+Bowsers Datensatz wie folgt aus:
+
+@example
+mysql> SELECT * FROM pet WHERE name = "Bowser";
++--------+----------+---------+-------------+------------+------------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++--------+----------+---------+-------------+------------+------------+
+| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
++--------+----------+---------+-------------+------------+------------+
+@end example
+
+
+Die Ausgabe bestätigt, dass das Jahr inzwischen korrekt als 1989, nicht
+1998, eingetragen ist.
+
+Vergleiche von Zeichenketten achten normalerweise nicht auf
+Groß-/Kleinschreibung, daher können Sie den Namen als @code{"bowser"},
+@code{"BOWSER"} usw. angeben. Das Anfrageergebnis wird dasselbe bleiben.
+
+Sie können für jede Spalte Bedingungen festlegen, nicht nur für
+@code{name}. Wenn Sie zum Beispiel wissen wollen, welche Tiere nach 1998
+geboren wurden, formulieren Sie eine Bedingung für die
+@code{geburtstag}-Spalte:
+
+@example
+mysql> SELECT * FROM pet WHERE geburtstag >= "1998-1-1";
++----------+----------+---------+-------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++----------+----------+---------+-------------+------------+-----------+
+| Chirpy | Gwen | Vogel | w | 1998-09-11 | NULL |
+| Puffball | Diane | Hamster | w | 1999-03-30 | NULL |
++----------+----------+---------+-------------+------------+-----------+
+@end example
+
+Sie können Bedingungen kombinieren, um zum Beispiel weibliche Hunde
+festzustellen:
+
+@example
+mysql> SELECT * FROM pet WHERE art = "Hund" AND geschlecht = "w";
++-------+-----------+---------+------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++-------+-----------+---------+------------+------------+-----------+
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
++-------+-----------+---------+------------+------------+-----------+
+@end example
+
+Die vorherige Anfrage benutzt den logischen Operator @code{AND}. Es gibt
+auch einen @code{OR}-Operator:
+
+@example
+mysql> SELECT * FROM pet WHERE art = "Schlange" OR art = "Vogel";
++----------+----------+---------+-------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++----------+----------+---------+-------------+------------+-----------+
+| Chirpy | Gwen | Vogel | w | 1998-09-11 | NULL |
+| Whistler | Gwen | Vogel | NULL | 1997-12-09 | NULL |
+| Slim | Benny | Schlange| m | 1996-04-29 | NULL |
++----------+----------+---------+-------------+------------+-----------+
+@end example
+
+@code{AND} und @code{OR} können gemischt werden. Wenn Sie das tun, ist es
+eine gute Idee, Klammern zu verwenden, um anzuzeigen, wie die Bedingungen
+gruppiert werden sollen:
+
+@example
+mysql> SELECT * FROM pet WHERE (art = "Katze" AND geschlecht = "m")
+ -> OR (art = "Hund" AND geschlecht = "w");
++-------+-----------+---------+-------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++-------+-----------+---------+-------------+------------+-----------+
+| Claws | Gwen | Katze | m | 1994-03-17 | NULL |
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
++-------+-----------+---------+-------------+------------+-----------+
+@end example
+
+
+@node Selecting columns, Sorting rows, Selecting rows, Retrieving data
+@c German node Spalten auswählen
+@subsubsection Bestimmte Spalten auswählen
+
+@cindex Spalten, auswählen
+@cindex Tabellen, Spalten auswählen
+
+Wenn Sie nicht ganze Zeilen Ihrer Tabelle sehen wollen, geben Sie einfach
+die Spalten an, an denen Sie interessiert sind, getrennt durch Kommas. Wenn
+Sie zum Beispiel wissen wollen, wann Ihre Tiere geboren wurden, wählen Sie
+die @code{name}- und @code{geburtstag}-Spalten aus:
+
+@example
+mysql> SELECT name, geburtstag FROM pet;
++----------+------------+
+| name | geburtstag |
++----------+------------+
+| Fluffy | 1993-02-04 |
+| Claws | 1994-03-17 |
+| Buffy | 1989-05-13 |
+| Fang | 1990-08-27 |
+| Bowser | 1989-08-31 |
+| Chirpy | 1998-09-11 |
+| Whistler | 1997-12-09 |
+| Slim | 1996-04-29 |
+| Puffball | 1999-03-30 |
++----------+------------+
+@end example
+
+Um herauszufinden, wem welches Haustier gehört, benutzen Sie diese Anfrage:
+
+@example
+mysql> SELECT besitzer FROM pet;
++----------+
+| besitzer |
++----------+
+| Harold |
+| Gwen |
+| Harold |
+| Benny |
+| Diane |
+| Gwen |
+| Gwen |
+| Benny |
+| Diane |
++----------+
+@end example
+
+@findex DISTINCT
+Beachten Sie jedoch, dass diese Anfrage einfach die @code{besitzer}-Spalte
+jedes Datensatzes abfragt, wodurch mehrere von ihnen mehrfach erscheinen.
+Um die Ausgabe zu minimieren, fragen Sie jeden eindeutigen Datensatz nur
+einmal ab, indem Sie das Schlüsselwort @code{DISTINCT} verwenden:
+
+@example
+mysql> SELECT DISTINCT besitzer FROM pet;
++-----------+
+| besitzer |
++-----------+
+| Benny |
+| Diane |
+| Gwen |
+| Harold |
++-----------+
+@end example
+
+Sie können eine @code{WHERE}-Klausel verwenden, um die Auswahl von Zeilen
+mit der Auswahl von Spalten zu kombinieren. Um zum Beispiel nur die
+Geburtstage von Hunden und Katzen zu erhalten, benutzen Sie diese Anfrage:
+
+@example
+mysql> SELECT name, art, geburtstag FROM pet
+ -> WHERE art = "Hund" OR art = "Katze";
++--------+---------+------------+
+| name | art | geburtstag |
++--------+---------+------------+
+| Fluffy | Katze | 1993-02-04 |
+| Claws | Katze | 1994-03-17 |
+| Buffy | Hund | 1989-05-13 |
+| Fang | Hund | 1990-08-27 |
+| Bowser | Hund | 1989-08-31 |
++--------+---------+------------+
+@end example
+
+
+@node Sorting rows, Date calculations, Selecting columns, Retrieving data
+@c German node Zeilen sortieren
+@subsubsection Zeilen sortieren
+
+@cindex Zeilen, sortieren
+@cindex sortieren, Tabellenzeilen
+@cindex sortieren, Daten
+@cindex Tabellen, Zeilen sortieren
+
+Sie haben bei den vorherigen Beispielen vielleicht bemerkt, dass die
+Ergebniszeilen in keiner bestimmten Reihenfolge angezeigt werden. Häufig
+ist es jedoch einfacher, die Ausgabe der Anfrage zu überprüfen, wenn die
+Zeilen auf sinnvolle Art sortiert werden. Um ein Ergebnis zu sortieren,
+benutzen Sie die @code{ORDER BY}-Klausel.
+
+Hier sind die Geburtstage der Haustiere, sortiert nach Geburtstag:
+
+@example
+mysql> SELECT name, geburtstag FROM pet ORDER BY geburtstag;
++----------+------------+
+| name | geburtstag |
++----------+------------+
+| Buffy | 1989-05-13 |
+| Bowser | 1989-08-31 |
+| Fang | 1990-08-27 |
+| Fluffy | 1993-02-04 |
+| Claws | 1994-03-17 |
+| Slim | 1996-04-29 |
+| Whistler | 1997-12-09 |
+| Chirpy | 1998-09-11 |
+| Puffball | 1999-03-30 |
++----------+------------+
+@end example
+
+Um in umgekehrter Reihenfolge zu sortieren, fügen Sie das @code{DESC}-
+(descending) Schlüsselwort zum Namen der Spalte, die Sie sortieren wollen,
+hinzu:
+
+@example
+mysql> SELECT name, geburtstag FROM pet ORDER BY geburtstag DESC;
++----------+------------+
+| name | geburtstag |
++----------+------------+
+| Puffball | 1999-03-30 |
+| Chirpy | 1998-09-11 |
+| Whistler | 1997-12-09 |
+| Slim | 1996-04-29 |
+| Claws | 1994-03-17 |
+| Fluffy | 1993-02-04 |
+| Fang | 1990-08-27 |
+| Bowser | 1989-08-31 |
+| Buffy | 1989-05-13 |
++----------+------------+
+@end example
+
+Sie können über mehrere Spalten sortieren. Um beispielsweise zuerst nach
+der Art des Tieres und dann nach dem Geburtsdatum innerhalb der Tierart zu
+sortieren (die jüngsten Tiere zuerst), benutzen Sie folgende Anfrage:
+
+@example
+mysql> SELECT name, art, geburtstag FROM pet ORDER BY art, geburtstag DESC;
++----------+----------+------------+
+| name | art | geburtstag |
++----------+----------+------------+
+| Chirpy | Vogel | 1998-09-11 |
+| Whistler | Vogel | 1997-12-09 |
+| Claws | Katze | 1994-03-17 |
+| Fluffy | Katze | 1993-02-04 |
+| Fang | Hund | 1990-08-27 |
+| Bowser | Hund | 1989-08-31 |
+| Buffy | Hund | 1989-05-13 |
+| Puffball | Hamster | 1999-03-30 |
+| Slim | Schlange | 1996-04-29 |
++----------+----------+------------+
+@end example
+
+Beachten Sie, dass sich das @code{DESC}-Schlüsselwort nur auf die Spalte
+bezieht, die unmittelbar davor steht (@code{geburtstag}). @code{art}-Werte
+werden nach wie vor in aufsteigender Reihenfolge sortiert.
+
+
+@node Date calculations, Working with NULL, Sorting rows, Retrieving data
+@c German node Datumsberechnungen
+@subsubsection Datumsberechnungen
+
+@cindex Datumsberechnungen
+@cindex Berechnungen, Datumswerte
+@cindex Extrahieren, Datumswerte
+@cindex Alter, berechnen
+
+MySQL stellt etliche Funktionen zur Verfügung, mit denen Sie
+Datumsberechnungen wie Altersberechnungen oder das Extrahieren von
+Datumsteilen durchführen können.
+
+Um festzustellen, wie alt jedes Ihrer Haustiere ist, berechnen Sie die
+Differenz im Jahresanteil des aktuellen Datums und des Geburtstags und
+subtrahieren eins, wenn das aktuelle Datum früher im Kalender erscheint als
+das Geburtsdatum. Folgende Anfrage zeigt für jedes Haustier das
+Geburtsdatum, das aktuelle Datum und das Alter in Jahren:
+
+@example
+mysql> SELECT name, geburtstag, CURRENT_DATE,
+ -> (YEAR(CURRENT_DATE)-YEAR(geburtstag))
+ -> - (RIGHT(CURRENT_DATE,5)<RIGHT(geburtstag,5))
+ -> AS age
+ -> FROM pet;
++----------+------------+--------------+------+
+| name | geburtstag | CURRENT_DATE | age |
++----------+------------+--------------+------+
+| Fluffy | 1993-02-04 | 2001-08-29 | 8 |
+| Claws | 1994-03-17 | 2001-08-29 | 7 |
+| Buffy | 1989-05-13 | 2001-08-29 | 12 |
+| Fang | 1990-08-27 | 2001-08-29 | 11 |
+| Bowser | 1989-08-31 | 2001-08-29 | 11 |
+| Chirpy | 1998-09-11 | 2001-08-29 | 2 |
+| Whistler | 1997-12-09 | 2001-08-29 | 3 |
+| Slim | 1996-04-29 | 2001-08-29 | 5 |
+| Puffball | 1999-03-30 | 2001-08-29 | 2 |
++----------+------------+--------------+------+
+@end example
+
+Hier zieht @code{YEAR()} den Jahresanteil eines Datums heraus.
+@code{RIGHT()} zieht die rechts stehenden fünf Zeichen heraus, die für den
+@code{MM-DD}-Teil des Datums stehen. Der Teil in dem Ausdruck, der die
+@code{MM-DD}-Werte vergleicht, wird zu 1 oder 0 ausgewertet, was die
+Jahresdifferenz ein Jahr nach unten anpasst, wenn @code{CURRENT_DATE}
+früher im Jahr erscheint als @code{geburtstag}. Der gesamte Ausdruck ist
+als Überschrift etwas plump, daher wir ein Alias (@code{age}) benutzt, um
+die Spaltenüberschrift etwas lesbarer zu machen.
+
+Die Anfrage funktioniert, aber das Ergebnis könnte leichter überblickt
+werden, wenn die Zeilen in einer bestimmten Reihenfolge angezeigt würden.
+Das kann man erreichen, indem man eine @code{ORDER BY name}-Klausel
+hinzufügt, um die Ausgabe nach Namen zu sortieren:
+
+@example
+mysql> SELECT name, geburtstag, CURRENT_DATE,
+ -> (YEAR(CURRENT_DATE)-YEAR(geburtstag))
+ -> - (RIGHT(CURRENT_DATE,5)<RIGHT(geburtstag,5))
+ -> AS age
+ -> FROM pet ORDER BY name;
++----------+------------+--------------+------+
+| name | geburtstag | CURRENT_DATE | age |
++----------+------------+--------------+------+
+| Bowser | 1989-08-31 | 2001-08-29 | 11 |
+| Buffy | 1989-05-13 | 2001-08-29 | 12 |
+| Chirpy | 1998-09-11 | 2001-08-29 | 2 |
+| Claws | 1994-03-17 | 2001-08-29 | 7 |
+| Fang | 1990-08-27 | 2001-08-29 | 11 |
+| Fluffy | 1993-02-04 | 2001-08-29 | 8 |
+| Puffball | 1999-03-30 | 2001-08-29 | 2 |
+| Slim | 1996-04-29 | 2001-08-29 | 5 |
+| Whistler | 1997-12-09 | 2001-08-29 | 3 |
++----------+------------+--------------+------+
+@end example
+
+Um die Ausgabe nach Alter (@code{age}) statt nach @code{name} zu sortieren,
+benutzen Sie einfach eine andere @code{ORDER BY}-Klausel:
+
+@example
+mysql> SELECT name, geburtstag, CURRENT_DATE,
+ -> (YEAR(CURRENT_DATE)-YEAR(geburtstag))
+ -> - (RIGHT(CURRENT_DATE,5)<RIGHT(geburtstag,5))
+ -> AS age
+ -> FROM pet ORDER BY age;
++----------+------------+--------------+------+
+| name | geburtstag | CURRENT_DATE | age |
++----------+------------+--------------+------+
+| Chirpy | 1998-09-11 | 2001-08-29 | 2 |
+| Puffball | 1999-03-30 | 2001-08-29 | 2 |
+| Whistler | 1997-12-09 | 2001-08-29 | 3 |
+| Slim | 1996-04-29 | 2001-08-29 | 5 |
+| Claws | 1994-03-17 | 2001-08-29 | 7 |
+| Fluffy | 1993-02-04 | 2001-08-29 | 8 |
+| Fang | 1990-08-27 | 2001-08-29 | 11 |
+| Bowser | 1989-08-31 | 2001-08-29 | 11 |
+| Buffy | 1989-05-13 | 2001-08-29 | 12 |
++----------+------------+--------------+------+
+@end example
+
+
+Eine ähnliche Anfrage kann benutzt werden, um das Alter am Sterbetag bei
+Tieren festzustellen, die gestorben sind. Das können Sie feststellen, indem
+Sie überprüfen, ob der @code{sterbetag}-Wert @code{NULL} ist. Dann
+berechnen Sie für diejenigen Tiere mit Nicht-@code{NULL}-Werten den
+Unterschied zwischen @code{sterbetag}- und @code{geburtstag}-Werten:
+
+@example
+mysql> SELECT name, geburtstag, sterbetag,
+ -> (YEAR(sterbetag)-YEAR(geburtstag)) - (RIGHT(sterbetag,5)<RIGHT(geburtstag,5))
+ -> AS age
+ -> FROM pet WHERE sterbetag IS NOT NULL ORDER BY age;
++--------+------------+------------+------+
+| name | geburtstag | sterbetag | age |
++--------+------------+------------+------+
+| Bowser | 1989-08-31 | 1995-07-29 | 5 |
++--------+------------+------------+------+
+@end example
+
+Die Anfrage benutzt @code{sterbetag IS NOT NULL} statt @code{sterbetag !=
+NULL}, weil @code{NULL} ein spezieller Wert ist. Das wird später erklärt.
+@xref{Working with NULL, , Mit @code{NULL}-Werten arbeiten}.
+
+Was ist, wenn Sie wissen wollen, welche Tiere nächsten Monat Geburtstag
+haben? Für diese Art von Berechnung sind Jahre und Tage irrelevant. Sie
+wollen lediglich den Monatsanteil der @code{geburtstag}-Spalte extrahieren.
+MySQL bietet etliche Funktionen für die Extraktion von Datumsanteilen, wie
+@code{YEAR()}, @code{MONTH()} und @code{DAYOFMONTH()}. @code{MONTH()} ist
+hier die richtige Funktion. Um festzustellen, wie sie funktioniert, geben
+Sie eine Anfrage ein, die sowohl die Werte von @code{geburtstag} als auch
+die von @code{MONTH(geburtstag)} ausgibt:
+
+@example
+mysql> SELECT name, geburtstag, MONTH(geburtstag) FROM pet;
++----------+------------+-------------------+
+| name | geburtstag | MONTH(geburtstag) |
++----------+------------+-------------------+
+| Fluffy | 1993-02-04 | 2 |
+| Claws | 1994-03-17 | 3 |
+| Buffy | 1989-05-13 | 5 |
+| Fang | 1990-08-27 | 8 |
+| Bowser | 1989-08-31 | 8 |
+| Chirpy | 1998-09-11 | 9 |
+| Whistler | 1997-12-09 | 12 |
+| Slim | 1996-04-29 | 4 |
+| Puffball | 1999-03-30 | 3 |
++----------+------------+-------------------+
+@end example
+
+Tiere mit Geburtstagen im kommenden Monat zu finden ist ebenfalls leicht.
+Nehmen wir an, der aktuelle Monat ist April. Dann ist der Monatswert
+@code{4} und Sie suchen nach Tieren, die im Mai (Monat 5) geboren sind, wie
+folgt:
+
+@example
+mysql> SELECT name, geburtstag FROM pet WHERE MONTH(geburtstag) = 5;
++-------+------------+
+| name | geburtstag |
++-------+------------+
+| Buffy | 1989-05-13 |
++-------+------------+
+@end example
+
+Ein bisschen komplizierter ist es, wenn der aktuelle Monat Dezember ist.
+Hier können Sie nicht einfach eins zur Monatszahl (@code{12}) hinzufügen,
+weil es keinen 13. Monat gibt. Statt dessen suchen Sie nach Tieren, die im
+Januar (Monat 1) geboren sind.
+
+Sie können die Anfrage sogar so schreiben, dass sie unabhängig davon
+funktioniert, was der aktuelle Monat ist. Auf diese Art brauchen Sie keine
+bestimmte Monatszahl in der Anfrage benutzen. @code{DATE_ADD()} erlaubt
+Ihnen, einem gegebenen Datum ein Zeitintervall hinzuzufügen. Wenn Sie dem
+Wert von @code{NOW()} einen Monat hinzufügen und dann den Monatsanteil mit
+@code{MONTH()} extrahieren, ergibt das den Monat, der die kommenden
+Geburtstage enthält:
+
+@example
+mysql> SELECT name, geburtstag FROM pet
+ -> WHERE MONTH(geburtstag) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));
+@end example
+
+Eine andere Möglichkeit, diese Aufgabe zu erfüllen, ist, @code{1} zu
+addieren, um den nächsten Monat nach dem aktuellen zu erhalten (nach
+Gebrauch der Modulo-Funktion (@code{MOD}), um den Monatswert auf @code{0}
+zu stellen, falls er aktuell @code{12}) ist:
+
+@example
+mysql> SELECT name, geburtstag FROM pet
+ -> WHERE MONTH(geburtstag) = MOD(MONTH(NOW()), 12) + 1;
+@end example
+
+@code{MONTH} gibt eine Zahl zwischen 1 und 12 zurück.
+@code{MOD(irgendwas,12)} gibt eine Zahl zwischen 0 und 11 zurück. Daher
+muss die Addition nach @code{MOD()} erfolgen, weil wir ansonsten von
+November (11) bis Januar (1) gehen würden.
+
+
+@node Working with NULL, Pattern matching, Date calculations, Retrieving data
+@c German node Mit NULL arbeiten
+@subsubsection Mit @code{NULL}-Werten arbeiten
+
+@findex NULL
+@cindex NULL-Wert
+
+Der @code{NULL}-Wert birgt Überraschungen, bis Sie mit ihm vertraut sind.
+Konzeptionell bedeutet @code{NULL} einen fehlenden oder unbekannten Wert.
+Er wird in einiger Hinsicht anders als andere Werte behandelt. Um auf
+@code{NULL} zu testen, können Sie nicht die arithmetischen
+Vergleichoperatoren wie @code{=}, @code{<} oder @code{!=} verwenden. Um
+sich das zu veranschaulichen, probieren Sie folgenden Anfrage:
+
+@example
+mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
++----------+-----------+----------+----------+
+| 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL |
++----------+-----------+----------+----------+
+| NULL | NULL | NULL | NULL |
++----------+-----------+----------+----------+
+@end example
+
+Wie man sieht, erhält man aus diesen Vergleichen keine sinnvollen
+Ergebnisse. Benutzen Sie statt dessen die @code{IS NULL}- und @code{IS NOT
+NULL}-Operatoren:
+
+@example
+mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
++-----------+---------------+
+| 1 IS NULL | 1 IS NOT NULL |
++-----------+---------------+
+| 0 | 1 |
++-----------+---------------+
+@end example
+
+In MySQL bedeutet 0 oder @code{NULL} logisch Falsch und alles sonstige
+bedeutet logisch Wahr. Der vorgabemäßige Wahrheitswert einer Boolschen
+Operation ist 1.
+
+Diese besondere Behandlung von @code{NULL} ist der Grund, warum es im
+vorherigen Abschnitt notwendig war, mit @code{sterbetag IS NOT NULL}
+anstelle von @code{sterbetag != NULL} festzustellen, welche Tiere nicht
+mehr leben.
+
+
+@node Pattern matching, Counting rows, Working with NULL, Retrieving data
+@c German node Suchmuster
+@subsubsection Übereinstimmende Suchmuster
+
+@cindex Übereinstimmende Suchmuster
+@cindex Übereinstimmung, Suchmuster
+@cindex Ausdrücke, erweitert
+
+MySQL stellt Standard-SQL-Suchmuster-Übereinstimmung zur Verfügung, ebenso
+wie eine Art der Suchmuster-Übereinstimmung, die auf regulären Ausdrücken
+basiert, die denen ähnlich sind, die von Unix-Hilfsprogrammen wie
+@code{vi}, @code{grep} und @code{sed} benutzt werden.
+
+SQL-Suchmuster-Übereinstimmung gestattet Ihnen, @samp{_} zu benutzen, um
+ein einzelnes Zeichen und @samp{%}, um eine beliebige Anzahl von Zeichen
+(inklusive des 0-Zeichens) zu finden. In den MySQL-SQL-Suchmustern spielt
+die Groß-/Kleinschreibung vorgabemäßig keine Rolle. Einige Beispiele sind
+unten dargestellt. Beachten Sie, dass Sie @code{=} oder @code{!=} nicht
+benutzen können, wenn Sie SQL-Suchmuster benutzen. Stattdessen müssen Sie
+die @code{LIKE}- oder @code{NOT LIKE}-Vergleichsoperatoren benutzen.
+
+So finden Sie Namen, die mit @samp{b} anfangen:
+
+@example
+mysql> SELECT * FROM pet WHERE name LIKE "b%";
++--------+----------+------+------------+------------+------------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++--------+----------+------+------------+------------+------------+
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
+| Bowser | Diane | Hund | m | 1989-08-31 | 1995-07-29 |
++--------+----------+------+------------+------------+------------+
+@end example
+
+So finden Sie Namen, die auf @samp{fy} enden:
+
+@example
+mysql> SELECT * FROM pet WHERE name LIKE "%fy";
++--------+----------+-------+------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++--------+----------+-------+------------+------------+-----------+
+| Fluffy | Harold | Katze | w | 1993-02-04 | NULL |
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
++--------+----------+-------+------------+------------+-----------+
+@end example
+
+So finden Sie Namen, die @samp{w} enthalten:
+
+@example
+mysql> SELECT * FROM pet WHERE name LIKE "%w%";
++----------+----------+---------+-------------+------------+------------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++----------+----------+---------+-------------+------------+------------+
+| Claws | Gwen | Katze | m | 1994-03-17 | NULL |
+| Bowser | Diane | Hund | m | 1989-08-31 | 1995-07-29 |
+| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
++----------+----------+---------+-------------+------------+------------+
+@end example
+
+Um Namen zu finden, die genau fünf Zeichen enthalten, benutzen Sie das
+@samp{_}-Suchmuster-Zeichen:
+
+@example
+mysql> SELECT * FROM pet WHERE name LIKE "_____";
++-------+----------+---------+-------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++-------+----------+---------+-------------+------------+-----------+
+| Claws | Gwen | Katze | m | 1994-03-17 | NULL |
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
++-------+----------+---------+-------------+------------+-----------+
+@end example
+
+Die andere Art von Suchmuster-Übereinstimmung benutzt erweiterte reguläre
+Ausdrücke. Wenn Sie bei dieser Art von Suchmuster auf Übereinstimmung
+prüfen, benutzen Sie die @code{REGEXP}- und @code{NOT REGEXP}-Operatoren
+(oder @code{RLIKE} und @code{NOT RLIKE}, die synonym sind).
+
+Einige Charakteristika erweiterter regulärer Ausdrücke sind:
+
+@itemize @bullet
+@item
+@samp{.} findet jedes beliebige Zeichen.
+
+@item
+Eine Zeichenklasse @samp{[...]} findet jedes Zeichen innerhalb der
+eckigen Klammern. So stimmt zum Beispiel @samp{[abc]} mit @samp{a},
+@samp{b} oder @samp{c} überein. Um einen Bereich von Zeichen zu benennen,
+benutzen Sie einen Bindestrich. @samp{[a-z]} stimmt mit jedem Buchstaben in
+Kleinschreibung überein, wohingegen @samp{[0-9]} mit jeder Ziffer
+übereinstimmt.
+
+@item
+@samp{*} stimmt mit null oder mehr Instanzen der Sache überein, die ihm
+voransteht. @samp{x*} zum Beispiel stimmt mit einer beliebigen Anzahl von
+@samp{x}-Zeichen überein. @samp{[0-9]*} stimmt mit einer beliebigen Anzahl
+von Ziffern überein, und @samp{.*} mit jeder Anzahl von irgendetwas.
+
+@item
+Reguläre Ausdrücke achten auf Groß-/Kleinschreibung, aber Sie können eine
+Zeichenklasse benutzen, um beide Schreibungen zu finden, wenn Sie wollen.
+@samp{[aA]} zum Beispiel stimmt mit @samp{a} in Groß- und Kleinschreibung
+überein und @samp{[a-zA-Z]} mit jedem Buchstaben in Groß- und
+Kleinschreibung.
+
+@item
+Das Suchmuster stimmt überein, wenn es irgendwo in dem Wert auftaucht, der
+überprüft wird. (SQL-Suchmuster stimmen nur überein, wenn sie mit dem
+gesamten Wert übereinstimmen.)
+
+@item
+Um ein Suchmuster so zu verankern, dass er mit dem Anfang oder dem Ende des
+überprüften Werts übereinstimmen muss, benutzen Sie @samp{^} am Anfang oder
+@samp{$} am Ende des Suchmusters.
+@end itemize
+
+Um darzustellen, wie erweiterte reguläre Ausdrücke funktionieren, werden
+die @code{LIKE}-Anfragen von oben noch einmal mit @code{REGEXP} gezeigt.
+
+Um Namen zu finden, die mit @samp{b} anfangen, benutzen Sie @samp{^}, um
+auf Übereinstimmung am Anfang des Namens zu prüfen:
+
+@example
+mysql> SELECT * FROM pet WHERE name REGEXP "^b";
++--------+-----------+---------+-------------+------------+------------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++--------+-----------+---------+-------------+------------+------------+
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
+| Bowser | Diane | Hund | m | 1989-08-31 | 1995-07-29 |
++--------+-----------+---------+-------------+------------+------------+
+@end example
+
+Vor MySQL-Version 3.23.4 achtet @code{REGEXP} auf Groß-/Kleinschreibung.
+Daher gibt diese Anfrage ein Ergebnis ohne Zeilen zurück. Um sowohl Groß-
+als auch Kleinschreibung von @samp{b} zu finden, benutzen Sie statt dessen
+folgende Anfrage:
+
+@example
+mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
+@end example
+
+Ab MySQL 3.23.4 müssen Sie, um die Beachtung der Groß-/Kleinschreibung in
+einem @code{REGEXP}-Vergleich zu erzwingen, das @code{BINARY}-Schlüsselwort
+verwenden, um eine der Zeichenketten zu einer binären Zeichenkette zu
+machen. Diese Anfrage stimmt nur mit @samp{b} in Kleinschreibung am Anfang
+eines Namens überein:
+
+@example
+mysql> SELECT * FROM pet WHERE name REGEXP BINARY "^b";
+@end example
+
+Um Namen zu finden, die auf @samp{fy} enden, benutzen Sie @samp{$}, um
+Übereinstimmung am Ende des Namens zu finden:
+
+@example
+mysql> SELECT * FROM pet WHERE name REGEXP "fy$";
++--------+-----------+---------+-------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++--------+-----------+---------+-------------+------------+-----------+
+| Fluffy | Harold | Katze | w | 1993-02-04 | NULL |
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
++--------+-----------+---------+-------------+------------+-----------+
+@end example
+
+Um Namen zu finden, die @samp{w} in Groß- oder Kleinschreibung enthalten,
+benutzen Sie diese Anfrage:
+
+@example
+mysql> SELECT * FROM pet WHERE name REGEXP "w";
++----------+----------+---------+-------------+------------+------------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++----------+----------+---------+-------------+------------+------------+
+| Claws | Gwen | Katze | m | 1994-03-17 | NULL |
+| Bowser | Diane | Hund | m | 1989-08-31 | 1995-07-29 |
+| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
++----------+----------+---------+-------------+------------+------------+
+@end example
+
+Weil ein Suchmuster mit regulären Ausdrücken an beliebiger Stelle im Wert
+gefunden wird, ist es bei der vorherigen Anfrage nicht notwendig, ein
+Jokerzeichen (Wildcard) auf irgendeine Seite des Suchmusters zu setzen, um
+nach Übereinstimmung im gesamten Wert zu suchen, wie es bei SQL-Suchmustern
+der Fall sein müsste.
+
+Um Namen zu finden, die genau fünf Zeichen enthalten, benutzen Sie @samp{^}
+und @samp{$}, um mit Anfang und Ende des Namens Übereinstimmung zu finden,
+und fünf Instanzen von @samp{.} dazwischen:
+
+@example
+mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";
++-------+-----------+---------+-------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++-------+-----------+---------+-------------+------------+-----------+
+| Claws | Gwen | Katze | m | 1994-03-17 | NULL |
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
++-------+-----------+---------+-------------+------------+-----------+
+@end example
+
+Sie könnten die vorherige Anfrage auch unter Verwendung des @samp{@{n@}}-
+``wiederhole-@code{n}-mal''-Operators schreiben:
+
+@example
+mysql> SELECT * FROM pet WHERE name REGEXP "^.@{5@}$";
++-------+-----------+---------+-------------+------------+-----------+
+| name | besitzer | art | geschlecht | geburtstag | sterbetag |
++-------+-----------+---------+-------------+------------+-----------+
+| Claws | Gwen | Katze | m | 1994-03-17 | NULL |
+| Buffy | Harold | Hund | w | 1989-05-13 | NULL |
++-------+-----------+---------+-------------+------------+-----------+
+@end example
+
+
+@node Counting rows, Multiple tables, Pattern matching, Retrieving data
+@c German node Zeilen zählen
+@subsubsection Zeilen zählen
+
+@cindex Zeilen, zählen
+@cindex Tabellen, Zeilen zählen
+@cindex zählen, Tabellenzeilen
+
+Datenbanken werden oft benutzt, um die Frage zu beantworten, wie oft eine
+bestimmte Art von Daten in einer Tabelle erscheint. Sie wollen
+beispielsweise wissen, wie viele Haustiere Sie haben, oder wie viele
+Haustiere jeder Besitzer hat, oder Sie wollen verschiedene Arten von
+Zählungen Ihrer Tiere durchführen.
+
+Die Gesamtzahl der Tiere zählen, die Sie haben, ist dieselbe Frage wie
+``Wie viele Zeilen sind in der @code{pet}-Tabelle?'', denn es gibt einen
+Datensatz pro Haustier. Die @code{COUNT()}-Funktion zählt die Anzahl von
+Nicht-@code{NULL}-Ergebnissen, daher lautet die Anfrage, um Ihre Tiere zu
+zählen, wie folgt:
+
+@example
+mysql> SELECT COUNT(*) FROM pet;
++----------+
+| COUNT(*) |
++----------+
+| 9 |
++----------+
+@end example
+
+Sie haben vorher schon einmal die Namen der Leute abgefragt, die Haustiere
+besitzen. Sie können @code{COUNT()} benutzen, wenn Sie herausfinden wollen,
+wie viele Tiere jeder Besitzer hat:
+
+@example
+mysql> SELECT besitzer, COUNT(*) FROM pet GROUP BY besitzer;
++-----------+----------+
+| besitzer | COUNT(*) |
++-----------+----------+
+| Benny | 2 |
+| Diane | 2 |
+| Gwen | 3 |
+| Harold | 2 |
++-----------+----------+
+@end example
+
+Beachten Sie die Benutzung von @code{GROUP BY}, um alle Datensätze für
+jeden @code{besitzer} zu gruppieren. Ohne das erhalten Sie eine
+Fehlermeldung:
+
+@example
+mysql> SELECT besitzer, COUNT(besitzer) FROM pet;
+ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
+with no GROUP columns is illegal if there is no GROUP BY clause
+@end example
+
+@code{COUNT()} und @code{GROUP BY} sind nützlich, um Ihre Daten auf
+verschiedene Weise zu charakterisieren. Die folgenden Beispiele zeigen
+verschiedene Möglichkeiten, um Zählungen Ihrer Tiere durchzuführen.
+
+Anzahl der Tiere pro Art:
+
+@example
+mysql> SELECT art, COUNT(*) FROM pet GROUP BY art;
++---------+----------+
+| art | COUNT(*) |
++---------+----------+
+| Vogel | 2 |
+| Katze | 2 |
+| Hund | 3 |
+| Hamster | 1 |
+| Schlange| 1 |
++---------+----------+
+@end example
+
+Anzahl der Tiere pro Geschlecht:
+
+@example
+mysql> SELECT geschlecht, COUNT(*) FROM pet GROUP BY geschlecht;
++-------------+----------+
+| geschlecht | COUNT(*) |
++-------------+----------+
+| NULL | 1 |
+| w | 4 |
+| m | 4 |
++-------------+----------+
+@end example
+
+(In dieser Ausgabe zeigt @code{NULL} an, dass das Geschlecht unbekannt
+ist.)
+
+Anzahl der Tiere pro Kombination von Art und Geschlecht:
+
+@example
+mysql> SELECT art, geschlecht, COUNT(*) FROM pet GROUP BY art, geschlecht;
++---------+-------------+----------+
+| art | geschlecht | COUNT(*) |
++---------+-------------+----------+
+| Vogel | NULL | 1 |
+| Vogel | w | 1 |
+| Katze | w | 1 |
+| Katze | m | 1 |
+| Hund | w | 1 |
+| Hund | m | 2 |
+| Hamster | w | 1 |
+| Schlange| m | 1 |
++---------+-------------+----------+
+@end example
+
+Sie müssen nicht die gesamte Tabelle abfragen, wenn Sie @code{COUNT()}
+benutzen. Die vorherige Anfrage beispielsweise sieht lediglich für Hunde
+und Katzen wie folgt aus:
+
+@example
+mysql> SELECT art, geschlecht, COUNT(*) FROM pet
+ -> WHERE art = "Hund" OR art = "Katze"
+ -> GROUP BY art, geschlecht;
++---------+-------------+----------+
+| art | geschlecht | COUNT(*) |
++---------+-------------+----------+
+| Katze | w | 1 |
+| Katze | m | 1 |
+| Hund | w | 1 |
+| Hund | m | 2 |
++---------+-------------+----------+
+@end example
+
+Oder wenn Sie die Anzahl von Tieren pro Geschlecht wissen wollen,
+beschränkt auf die Tiere, deren Geschlecht bekannt ist:
+
+@example
+mysql> SELECT art, geschlecht, COUNT(*) FROM pet
+ -> WHERE geschlecht IS NOT NULL
+ -> GROUP BY art, geschlecht;
++---------+-------------+----------+
+| art | geschlecht | COUNT(*) |
++---------+-------------+----------+
+| Vogel | w | 1 |
+| Katze | w | 1 |
+| Katze | m | 1 |
+| Hund | w | 1 |
+| Hund | m | 2 |
+| Hamster | w | 1 |
+| Schlange| m | 1 |
++---------+-------------+----------+
+@end example
+
+
+@node Multiple tables, , Counting rows, Retrieving data
+@c German node Mehrere Tabellen
+@subsubsection Mehr als eine Tabelle benutzen
+
+@cindex Tabellen, mehrere
+
+In der @code{pet}-Tabelle behalten Sie die Übersicht über Ihre Haustiere.
+Wenn Sie weitere Informationen über sie aufzeichnen wollen, beispielsweise
+Ereignisse in ihrem Leben wie Besuche beim Tierarzt oder wenn Nachwuchs zur
+Welt kommt, brauchen Sie eine weitere Tabelle. Wie sollte diese aussehen?
+Sie benötigt:
+
+@itemize @bullet
+@item
+Den Namen des Haustiers, damit Sie wissen, auf welches Tier sich jedes
+Ereignis bezieht.
+
+@item
+Ein Datum, damit Sie wissen, wann sich das Ereignis zugetragen hat.
+
+@item
+Ein Feld, um das Ereignis zu beschreiben.
+
+@item
+Ein Feld für den Typ des Ereignisses, wenn Sie in der Lage sein wollen,
+Ereignisse zu kategorisieren.
+@end itemize
+
+Nach diesen Vorüberlegungen könnte das @code{CREATE TABLE}-Statement für
+die @code{ereignis}-Tabelle wie folgt aussehen:
+
+@example
+mysql> CREATE TABLE ereignis (name VARCHAR(20), datum DATE,
+ -> typ VARCHAR(15), bemerkung VARCHAR(255));
+@end example
+
+Wie bei der @code{pet}-Tabelle ist es am einfachsten, die anfänglichen
+Datensätze mit Hilfe einer TAB-getrennten Textdatei einzuladen, die
+folgende Informationen enthält:
+
+@multitable @columnfractions .15 .15 .15 .55
+@item Fluffy @tab 1995-05-15 @tab Nachwuchs @tab 4 Kätzchen, 3 weiblich, 1 männlich
+@item Buffy @tab 1993-06-23 @tab Nachwuchs @tab 5 Hündchen, 2 weiblich, 3 männlich
+@item Buffy @tab 1994-06-19 @tab Nachwuchs @tab 3 Hündchen, 3 weiblich
+@item Chirpy @tab 1999-03-21 @tab Tierarzt @tab Schnabel gerade gebogen
+@item Slim @tab 1997-08-03 @tab Tierarzt @tab Gebrochene Rippe
+@item Bowser @tab 1991-10-12 @tab Zwinger
+@item Fang @tab 1991-10-12 @tab Zwinger
+@item Fang @tab 1998-08-28 @tab Geburtstag @tab Geschenk: neues Kauspielzeug
+@item Claws @tab 1998-03-17 @tab Geburtstag @tab Geschenk: neues Flohhalsband
+@item Whistler @tab 1998-12-09 @tab Geburtstag @tab Erster Geburtstag
+@end multitable
+
+Laden Sie die Datensätze wie folgt ein:
+
+@example
+mysql> LOAD DATA LOCAL INFILE "ereignis.txt" INTO TABLE ereignis;
+@end example
+
+Auf der Grundlage dessen, was Sie durch die Abfragen der @code{pet}-Tabelle
+gelernt haben, sollten sie in der Lage sein, Abfragen der Datensätze der
+@code{ereignis}-Tabelle durchzuführen, was prinzipiell dasselbe ist. Aber
+wann ist die @code{ereignis}-Tabelle allein nicht ausreichend, um Fragen zu
+beantworten, die Sie stellen könnten?
+
+Nehmen wir an, Sie wollen herausfinden, wie alt jedes Haustier war, als es
+Nachwuchs bekam. In der @code{ereignis}-Tabelle steht, wann das geschah,
+aber um das Alter der Mutter auszurechnen, wird ihr Geburtstag benötigt.
+Weil dieser in der @code{pet}-Tabelle steht, brauchen Sie für diese Anfrage
+beide Tabellen:
+
+@example
+mysql> SELECT pet.name, (TO_DAYS(datum) - TO_DAYS(geburtstag))/365 AS age,anmerkung
+ -> FROM pet, ereignis
+ -> WHERE pet.name = ereignis.name AND typ = "Nachwuchs";
++--------+------+------------------------------------+
+| name | age | anmerkung |
++--------+------+------------------------------------+
+| Fluffy | 2.27 | 4 kätzchen, 3 weiblich, 1 männlich |
+| Buffy | 4.12 | 5 hündchen, 2 weiblich, 3 männlich |
+| Buffy | 5.10 | 3 hündchen, 3 weiblich |
++--------+------+------------------------------------+
+@end example
+
+Zu dieser Anfrage gibt es einiges anzumerken:
+
+@itemize @bullet
+@item
+In der @code{FROM}-Klausel stehen zwei Tabellen, weil die Anfrage aus
+beiden Tabellen Informationen herausziehen muss.
+
+@item
+Wenn Sie Informationen aus mehreren Tabellen verbinden (englisch: join),
+müssen Sie angeben, wie Datensätze in der einen Tabelle mit solchen in der
+anderen Tabelle in Übereinstimmung gebracht werden können. Das ist einfach,
+weil beide eine @code{name}-Spalte haben. Die Anfrage benutzt die
+@code{WHERE}-Klausel, um Datensätze beider Tabellen basierend auf den
+@code{name}-Werten in Übereinstimmung zu bringen.
+
+@item
+Weil die @code{name}-Spalte in beiden Tabellen vorkommt, müssen Sie
+angeben, welche Tabelle Sie meinen, wenn Sie auf die Spalte verweisen. Das
+wird gemacht, indem dem Spaltennamen der Tabellenname voran gestellt wird.
+@end itemize
+
+Sie müssen nicht unbedingt zwei verschiedene Tabellen haben, um eine
+Verknüpfung (Join) durchzuführen. Manchmal ist es nützlich, eine Tabelle
+mit sich selbst zu verknüpfen, wenn Sie nämlich Datensätze in einer Tabelle
+mit Datensätze in derselben Tabelle vergleichen wollen. Um zum Beispiel
+Zuchtpaare unter Ihren Haustieren zu finden, können Sie die
+@code{pet}-Tabelle mit sich selbst verknüpfen, um Paare von männlichen und
+weiblichen Tieren derselben Art zusammen zu bringen:
+
+@example
+mysql> SELECT p1.name, p1.geschlecht, p2.name, p2.geschlecht, p1.art
+ -> FROM pet AS p1, pet AS p2
+ -> WHERE p1.art = p2.art AND p1.geschlecht = "w" AND p2.geschlecht = "m";
++--------+-------------+--------+-------------+---------+
+| name | geschlecht | name | geschlecht | art |
++--------+-------------+--------+-------------+---------+
+| Fluffy | w | Claws | m | Katze |
+| Buffy | w | Fang | m | Hund |
+| Buffy | w | Bowser | m | Hund |
++--------+-------------+--------+-------------+---------+
+@end example
+
+In dieser Anfrage legen wir Aliase für den Tabellennamen fest, um auf die
+Spalten verweisen zu können und um auseinander zu halten, auf welche
+Instanz der Tabelle sich jede Spaltenreferenz bezieht.
+
+
+@node Getting information, Examples, Database use, Tutorial
+@c German node Informationen bekommen
+@section Informationen über Datenbanken und Tabellen
+
+@cindex Datenbanken, Informationen über
+@cindex Tabellen, Informationen über
+@findex DESCRIBE
+
+Was ist, wenn Sie den Namen einer Datenbank oder Tabelle vergessen haben
+oder für eine gegebene Tabelle die Struktur nicht mehr kennen (wie zum
+Beispiel die Spalten heißen)? MySQL löst solcherlei Probleme mit diversen
+Statements, die Informationen über die Datenbanken und Tabellen
+bereitstellen, die es unterstützt.
+
+@code{SHOW DATABASES} kennen Sie schon. Dieses listet die Datenbanken auf,
+die vom Server verwaltet werden. Um herauszufinden, welche Datenbank
+aktuell ausgewählt ist, benutzen Sie die @code{DATABASE()}-Funktion:
+
+@example
+mysql> SELECT DATABASE();
++------------+
+| DATABASE() |
++------------+
+| menagerie |
++------------+
+@end example
+
+Wenn Sie noch keine Datenbank ausgewählt haben, ist das Ergebnis leer.
+
+Um herauszufinden, welche Tabellen die aktuelle Datenbank enthält (wenn Sie
+sich zum Beispiel über den Namen einer Tabelle nicht sicher sind), benutzen
+Sie folgenden Befehl:
+
+@example
+mysql> SHOW TABLES;
++---------------------+
+| Tables in menagerie |
++---------------------+
+| ereignis |
+| pet |
++---------------------+
+@end example
+
+Wenn Sie die Struktur einer Tabelle sehen wollen, ist der
+@code{DESCRIBE}-Befehl nützlich. Er zeigt Informationen über jede
+Tabellenspalte an:
+
+@example
+mysql> DESCRIBE pet;
++------------+-------------+------+-----+---------+-------+
+| Field | Type | Null | Key | Default | Extra |
++------------+-------------+------+-----+---------+-------+
+| name | varchar(20) | YES | | NULL | |
+| besitzer | varchar(20) | YES | | NULL | |
+| art | varchar(20) | YES | | NULL | |
+| geschlecht | char(1) | YES | | NULL | |
+| geburtstag | date | YES | | NULL | |
+| sterbetag | date | YES | | NULL | |
++------------+-------------+------+-----+---------+-------+
+@end example
+
+@code{Field} zeigt den Spaltennamen, @code{Type} ist der Datentyp der
+Spalte, @code{Null} zeigt an, ob die Spalte @code{NULL}-Werte enthalten darf
+oder nicht, @code{Key} zeigt an, ob die Spalte indiziert ist oder nicht und
+@code{Default} legt den Vorgabewert der Spalte fest.
+
+Wenn Sie Indexe auf eine Tabelle haben, zeigt Ihnen @code{SHOW INDEX FROM
+tabelle} Informationen über diese an.
+
+
+@node Examples, Batch mode, Getting information, Tutorial
+@c German node Beispiele
+@section Beispiele gebräuchlicher Anfragen (Queries)
+
+@cindex Anfragen, Beispiele
+@cindex Beispiele, Anfragen
+
+Hier finden sich Beispiele, wie geläufige Probleme mit MySQL gelöst werden
+können.
+
+Einige der Beispiele benutzen die Tabelle @code{shop}, die den Stückpreis
+für jeden Artikel für bestimmte Händler enthält. Unter der Annahme, dass
+jeder Händler einen einzelnen fest Preis pro Artikel hat, ist
+(@code{artikel}, @code{haendler}) der Primärschlüssel für diese Datensätze.
+
+Starten Sie das Kommandozeilen-Werkzeug @code{mysql} und wählen Sie eine
+Datenbank aus:
+
+@example
+mysql ihr-datenbank-name
+@end example
+
+(Bei den meisten MySQL-Installationen können Sie die Datenbank 'test'
+auswählen.)
+
+Erzeugen Sie die Beispiel-Tabelle wie folgt:
+
+@example
+CREATE TABLE shop (
+ artikel INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
+ haendler CHAR(20) DEFAULT '' NOT NULL,
+ preis DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
+ PRIMARY KEY(artikel, dealer));
+
+INSERT INTO shop VALUES
+(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),
+(3,'D',1.25),(4,'D',19.95);
+@end example
+
+Die Beispieldaten sehen jetzt so aus:
+
+@example
+mysql> SELECT * FROM shop;
+
++---------+---------+-------+
+| artikel | haendler| preis |
++---------+---------+-------+
+| 0001 | A | 3.45 |
+| 0001 | B | 3.99 |
+| 0002 | A | 10.99 |
+| 0003 | B | 1.45 |
+| 0003 | C | 1.69 |
+| 0003 | D | 1.25 |
+| 0004 | D | 19.95 |
++---------+---------+-------+
+@end example
+
+
+
+@menu
+* example-Maximum-column::
+* example-Maximum-row::
+* example-Maximum-column-group::
+* example-Maximum-column-group-row::
+* example-user-variables::
+* example-Foreign keys::
+* Searching on two keys::
+* Calculating days::
+@end menu
+
+@node example-Maximum-column, example-Maximum-row, Examples, Examples
+@c German node Beispiel Maximum-Spalte
+@subsection Der höchste Wert einer Spalte
+
+``Was ist die höchste Artikelnummer?''
+
+@example
+SELECT MAX(artikel) AS artikel FROM shop
+
++---------+
+| artikel |
++---------+
+| 4 |
++---------+
+@end example
+
+
+@node example-Maximum-row, example-Maximum-column-group, example-Maximum-column, Examples
+@c German node Beispiel Maximum-Zeile
+@subsection Die Zeile, die den höchsten Wert einer bestimmten Spalte enthält
+
+``Suche Artikelnummer, Händler und Preis des teuersten Artikels.''
+
+In ANSI-SQL wird das mit einer Unterabfrage (Sub-Query) durchgeführt:
+
+@example
+SELECT artikel, haendler, preis
+FROM shop
+WHERE preis=(SELECT MAX(preis) FROM shop)
+@end example
+
+In MySQL (was noch keine Unterabfragen hat) führen Sie das in zwei
+Schritten durch:
+
+@enumerate
+@item
+Mit einem @code{SELECT}-Statement ermitteln Sie den höchsten Preis in der
+Tabelle.
+@item
+Mit diesem Wert stellen Sie die aktuelle Anfrage zusammen:
+@example
+SELECT artikel, haendler, preis
+FROM shop
+WHERE preis=19.95
+@end example
+@end enumerate
+
+Eine andere Lösung besteht darin, alle Zeilen absteigend nach Preis zu
+sortieren und nur die erste Zeile zu nehmen, indem Sie die
+MySQL-spezifische @code{LIMIT}-Klausel benutzen:
+
+@example
+SELECT artikel, haendler, preis
+FROM shop
+ORDER BY preis DESC
+LIMIT 1
+@end example
+
+@strong{ACHTUNG}: Wenn es mehrere teuerste Artikel gibt (die zum Beispiel
+alle 19.95 kosten), zeigt die @code{LIMIT}-Lösung nur einen davon!
+
+
+@node example-Maximum-column-group, example-Maximum-column-group-row, example-Maximum-row, Examples
+@c German node Beispiel Maximum-Spalte-Gruppe
+@subsection Höchster Wert einer Spalte pro Gruppe
+
+``Was ist der höchste Preis pro Artikel?''
+
+@example
+SELECT artikel, MAX(preis) AS preis
+FROM shop
+GROUP BY artikel
+
++---------+-------+
+| artikel | preis |
++---------+-------+
+| 0001 | 3.99 |
+| 0002 | 10.99 |
+| 0003 | 1.69 |
+| 0004 | 19.95 |
++---------+-------+
+@end example
+
+
+@node example-Maximum-column-group-row, example-user-variables, example-Maximum-column-group, Examples
+@c German node Beispiel Maximum-Spalte-Gruppe-Zeile
+@subsection Die Zeilen, die das gruppenweise Maximum eines bestimmten Felds enthalten
+
+``Suche für jeden Artikel den oder die Händler mit den teuersten Preisen.''
+
+In ANSI-SQL würden Sie das wie folgt mit einer Unterabfrage erledigen:
+
+@example
+SELECT artikel, haendler, preis
+FROM shop s1
+WHERE preis=(SELECT MAX(s2.preis)
+ FROM shop s2
+ WHERE s1.artikel = s2.artikel);
+@end example
+
+In MySQL macht man das am besten in mehreren Schritten:
+
+@enumerate
+@item
+Die Liste (artikel,maxpreis) holen.
+@item
+Für jeden Artikel die korrespondierenden Zeilen holen, die den höchsten
+Preis gespeichert haben.
+@end enumerate
+
+Das kann auf einfache Weise mit einer temporären Tabelle geschehen:
+
+@example
+CREATE TEMPORARY TABLE tmp (
+ artikel INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
+ preis DOUBLE(16,2) DEFAULT '0.00' NOT NULL);
+
+LOCK TABLES shop read;
+
+INSERT INTO tmp SELECT artikel, MAX(preis) FROM shop GROUP BY artikel;
+
+SELECT shop.artikel, haendler, shop.preis FROM shop, tmp
+WHERE shop.artikel=tmp.artikel AND shop.preis=tmp.preis;
+
+UNLOCK TABLES;
+
+DROP TABLE tmp;
+@end example
+
+Wenn Sie keine @code{TEMPORARY}-Tabelle benutzen, müssen Sie zusätzlich die
+'tmp'-Tabelle sperren.
+
+``Kann das mit einer einzigen Anfrage durchgeführt werden?''
+
+Ja, aber nur unter Verwendung eines recht ineffizienten Tricks, den wir den
+``MAX-CONCAT-Trick'' nennen:
+
+@example
+SELECT artikel,
+ SUBSTRING( MAX( CONCAT(LPAD(preis,6,'0'),haendler) ), 7) AS haendler,
+ 0.00+LEFT( MAX( CONCAT(LPAD(preis,6,'0'),haendler) ), 6) AS preis
+FROM shop
+GROUP BY artikel;
+
++---------+---------+-------+
+| artikel | haendler| preis |
++---------+---------+-------+
+| 0001 | B | 3.99 |
+| 0002 | A | 10.99 |
+| 0003 | C | 1.69 |
+| 0004 | D | 19.95 |
++---------+---------+-------+
+@end example
+
+Das letzte Beispiel kann etwas effizienter gemacht werden, wenn man das
+Aufteilen der verketteten Spalte im Client durchführt.
+
+
+@node example-user-variables, example-Foreign keys, example-Maximum-column-group-row, Examples
+@c German node Beispiel Benutzer-Variablen
+@subsection Wie Benutzer-Variablen verwendet werden
+
+Sie können MySQL-Benutzer-Variablen verwenden, um Ergebnisse
+zwischenzuspeichern, ohne sie in temporäre Variablen im Client speichern zu
+müssen.
+@xref{Variables}.
+
+Um zum Beispiel die Artikel mit dem höchsten und dem niedrigsten Preis
+herauszufinden, können Sie folgendes machen:
+
+@example
+select @@min_preis:=min(preis),@@max_preis:=max(preis) from shop;
+select * from shop where preis=@@min_preis or preis=@@max_preis;
+
++---------+---------+-------+
+| artikel | haendler| preis |
++---------+---------+-------+
+| 0003 | D | 1.25 |
+| 0004 | D | 19.95 |
++---------+---------+-------+
+@end example
+
+
+@node example-Foreign keys, Searching on two keys, example-user-variables, Examples
+@c German node Beispiel Fremdschlüssel
+@subsection Wie Fremdschlüssel (Foreign Keys) verwendet werden
+
+@cindex Fremdschlüssel
+@cindex Schlüssel, Fremdschlüssel
+
+Sie brauchen keine Fremdschlüssel, um zwei Tabellen zu verknüpfen.
+
+Das einzige, was MySQL nicht durchführt, ist der @code{CHECK}, um
+sicherzustellen, dass die Schlüssel, die Sie benutzen, in der oder den
+Tabelle(n) existieren, auf die Sie verweisen, und es löscht auch nicht
+automatisch Zeilen aus einer Tabelle mit einer Fremdschlüssel-Definition.
+Wenn Sie Ihre Schlüssel wie gewöhnlich benutzen, funktioniert das gut:
+
+
+@example
+CREATE TABLE personen (
+ id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ name CHAR(60) NOT NULL,
+ PRIMARY KEY (id)
+);
+
+CREATE TABLE hemden (
+ id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ stil ENUM('t-shirt', 'polo', 'dress') NOT NULL,
+ farbe ENUM('rot', 'blau', 'orange', 'weiß', 'schwarz') NOT NULL,
+ besitzer SMALLINT UNSIGNED NOT NULL references personen,
+ PRIMARY KEY (id)
+);
+
+
+INSERT INTO personen VALUES (NULL, 'Antonio Paz');
+
+INSERT INTO hemden VALUES
+(NULL, 'polo', 'blau', LAST_INSERT_ID()),
+(NULL, 'dress', 'weiß', LAST_INSERT_ID()),
+(NULL, 't-shirt', 'blau', LAST_INSERT_ID());
+
+
+INSERT INTO personen VALUES (NULL, 'Lilliana Angelovska');
+
+INSERT INTO hemden VALUES
+(NULL, 'dress', 'orange', LAST_INSERT_ID()),
+(NULL, 'polo', 'rot', LAST_INSERT_ID()),
+(NULL, 'dress', 'blau', LAST_INSERT_ID()),
+(NULL, 't-shirt', 'weiß', LAST_INSERT_ID());
+
+
+SELECT * FROM personen;
++----+---------------------+
+| id | name |
++----+---------------------+
+| 1 | Antonio Paz |
+| 2 | Lilliana Angelovska |
++----+---------------------+
+
+SELECT * FROM hemden;
++----+---------+--------+----------+
+| id | stil | farbe | besitzer |
++----+---------+--------+----------+
+| 1 | polo | blau | 1 |
+| 2 | dress | weiß | 1 |
+| 3 | t-shirt | blau | 1 |
+| 4 | dress | orange | 2 |
+| 5 | polo | rot | 2 |
+| 6 | dress | blau | 2 |
+| 7 | t-shirt | weiß | 2 |
++----+---------+--------+----------+
+
+
+SELECT h.* FROM personen p, hemden h
+ WHERE p.name LIKE 'Lilliana%'
+ AND h.besitzer = p.id
+ AND h.farbe <> 'weiß';
+
++----+-------+--------+----------+
+| id | stil | farbe | besitzer |
++----+-------+--------+----------+
+| 4 | dress | orange | 2 |
+| 5 | polo | rot | 2 |
+| 6 | dress | blau | 2 |
++----+-------+--------+----------+
+@end example
+
+
+@node Searching on two keys, Calculating days, example-Foreign keys, Examples
+@c German node Suche über zwei Schlüssel
+@subsection Über zwei Schlüssel suchen
+
+@findex UNION
+@cindex Suchen, zwei Schlüssel
+@cindex Schlüssel, suchen über zwei
+MySQL optimiert derzeit noch nicht, wenn Sie über zwei unterschiedliche
+Schlüssel suchen, die mit @code{OR} kombiniert werden (eine Suche mit einem
+Schlüssel mit verschiedenen @code{OR}-Teilen wird recht gut optimiert):
+
+@example
+SELECT feld1_index, feld2_index FROM test_tabelle WHERE feld1_index = '1'
+OR feld2_index = '1'
+@end example
+
+Der Grund liegt darin, dass wir bislang noch keine Zeit hatten, hierfür
+eine effiziente Möglichkeit zu implementieren, die das für allgemeine Fälle
+abhandelt. (Die @code{AND}-Handhabung ist im Vergleich jetzt komplett
+allgemein und funktioniert sehr gut.)
+
+In der Zwischenzeit können Sie dieses Problem sehr effizient lösen, indem
+Sie eine @code{TEMPORARY}-Tabelle verwenden. Diese Art der Optimierung ist
+ebenfalls sehr gut, wenn Sie sehr komplizierte Anfragen verwenden, bei
+denen der SQL-Server die Optimierungen in falscher Reihenfolge durchführt.
+
+@example
+CREATE TEMPORARY TABLE tmp
+SELECT feld1_index, feld2_index FROM test_tabelle WHERE feld1_index = '1';
+INSERT INTO tmp
+SELECT feld1_index, feld2_index FROM test_tabelle WHERE feld2_index = '1';
+SELECT * from tmp;
+DROP TABLE tmp;
+@end example
+
+Diese Möglichkeit der Anfrage ist im Endeffekt ein @code{UNION} von zwei
+Anfragen.
+
+
+@node Calculating days, , Searching on two keys, Examples
+@c German node Tage berechnen
+@subsection Besuche pro Tag berechnen
+
+@findex BIT_OR
+@findex BIT_COUNT
+@findex <<
+@cindex Bit_Funktionen, Beispiel
+
+Folgendes zeigt, wie Sie die Bit-Gruppen-Funktionen benutzen können, um die
+Anzahl der Tage pro Monat zu zählen, in denen ein Benutzer eine Web-Seite
+besucht hat.
+
+@example
+CREATE TABLE t1 (jahr YEAR(4), monat INT(2) UNSIGNED ZEROFILL, tag INT(2) UNSIGNED ZEROFILL);
+INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),(2000,2,23),(2000,2,23);
+
+SELECT jahr,monat,BIT_COUNT(BIT_OR(1<<tag)) AS tage FROM t1 GROUP BY jahr,monat;
+
+Das gibt folgendes Ergebnis zurück:
+
++------+-------+------+
+| jahr | monat | tage |
++------+-------+------+
+| 2000 | 01 | 3 |
+| 2000 | 02 | 2 |
++------+-------+------+
+@end example
+
+Dies berechnet, wie viele verschiedene Tage für eine gegebene
+Jahr-Monats-Kombination benutzt wurden, bei automatischer Entfernung
+doppelter Einträge (Duplikate).
+
+
+@node Batch mode, Twin, Examples, Tutorial
+@c German node Stapelbetrieb
+@section @code{mysql} im Stapelbetrieb (Batch Mode)
+
+@cindex Modi, Stapel
+@cindex Stapelbetrieb
+@cindex Laufenlassen, Stapelbetrieb
+@cindex Skript-Dateien
+@cindex Dateien, Skript
+
+In den vorherigen Abschnitten haben Sie @code{mysql} interaktiv benutzt, um
+Anfragen einzugeben und die Ergebnisse zu betrachten. Sie können
+@code{mysql} auch im Stapelbetrieb benutzen. Dafür schreiben Sie dei
+Befehle, die Sie ausführen wollen, in eine Datei, und teilen @code{mysql}
+dann mit, seine Eingaben aus dieser Datei zu lesen:
+
+@example
+shell> mysql < stapel-datei
+@end example
+
+Wenn Sie auf der Kommandozeile Verbindungsparameter angeben müssen, könnte
+der Befehl wie folgt aussehen:
+
+@example
+shell> mysql -h host -u user -p < stapel-datei
+Enter password: ********
+@end example
+
+Wenn Sie @code{mysql} auf diese Weise benutzen, erzeugen Sie eine
+Skript-Datei und führen dann das Skript aus.
+
+Warum sollten Sie ein Skript benutzen? Hier sind ein paar Gründe:
+
+@itemize @bullet
+@item
+Wenn Sie eine Anfrage wiederholt ausführen (sagen wir jeden Tag oder jede
+Woche), vermeiden Sie mit einem Skript, dass Sie sie jedes Mal zur
+Ausführung erneut eintippen müssen.
+
+@item
+Sie können aus existierenden Anfragen neue Anfragen erzeugen, die ähnlich
+sind, indem Sie die Skript-Dateien kopieren und editieren.
+
+@item
+Der Stapelbetrieb kann auch für die Entwicklung einer Anfrage nützlich
+sein, insbesondere, wenn Sie mehrzeilige Befehle oder Befehlssequenzen aus
+mehreren Statements entwickeln. Wenn Sie einen Fehler machen, müssen Sie
+nicht alles noch einmal tippen, sondern editieren einfach Ihr Skript, um
+den Fehler zu beheben, und weisen @code{mysql} an, es erneut auszuführen.
+
+@item
+Wenn Sie eine Anfrage haben, die eine größere Ausgabe erzeugt, können Sie
+die Ausgabe durch einen Pager laufen lassen, statt zuzusehen, wie Sie über
+den Bildschirm flimmert:
+
+@example
+shell> mysql < stapel-datei | more
+@end example
+
+@item
+Für weitere Verarbeitung können Sie die Ausgabe auch in eine Datei lenken:
+
+@example
+shell> mysql < stapel-datei > mysql.ausgabe
+@end example
+
+@item
+Sie können Ihr Skript an andere Leute verteilen, so dass auch sie die
+Befehle laufen lassen können.
+
+@item
+In einigen Situationen ist interaktive Benutzung nicht angebracht, zum
+Beispiel dann, wenn Sie eine Anfrage durch einen @code{cron}-Job ausführen
+lassen. In diesem Fall brauchen Sie Stapelbetrieb.
+@end itemize
+
+Das Standard-Ausgabeformat ist anders (präziser), wenn Sie @code{mysql} im
+Stapelbetrieb laufen lassen, als wenn Sie es interaktiv nutzen. Die Ausgabe
+von @code{SELECT DISTINCT art FROM pet} zum Beispiel sieht so aus, wenn Sie
+sie interaktiv laufen lassen:
+
+@example
++---------+
+| art |
++---------+
+| Vogel |
+| Katze |
+| Hund |
+| Hamster |
+| Schlange|
++---------+
+@end example
+
+Aber wie folgt, wenn sie im Stapelbetrieb läuft:
+
+@example
+art
+Vogel
+Katze
+Hund
+Hamster
+Schlange
+@end example
+
+Wenn Sie im Stapelbetrieb das interaktive Ausgabeformat haben wollen,
+benutzen Sie @code{mysql -t}. Um die Befehle auszugeben, die ausgeführt
+werden, benutzen Sie @code{mysql -vvv}.
+
+
+@node Twin, Apache, Batch mode, Tutorial
+@c German node Twin
+@section Anfragen aus dem Zwillings-Projekt
+
+@cindex Zwillingsforschung, Anfragen
+@cindex Anfragen, Zwillingsforschungs-Projekt
+
+Bei Analytikerna und Lentus haben wir die Systeme und die Feldarbeit für
+ein großes Forschungsprojekt gemacht. Dieses Projekt ist eine
+Zusammenarbeit zwischen dem Institut für Umweltmedizin des Karolinska
+Institutes, Stockholm, und der Abteilung für klinische Forschung bei
+Altersprozessen und Psychologie der University of Southern California.
+
+Das Projekt beinhaltet einen Screening-Teil, bei dem alle Zwillinge in
+Schweden, die älter als 65 Jahre sind, per Telefon interviewt wurden.
+Zwillinge, die bestimmte Kriterien erfüllen, werden im nächsten Schritt
+weiter untersucht. In diesem späteren Stadium werden Zwillinge, die
+teilnehmen wollen, von einem Arzt-Schwester-Team besucht. Einige
+Untersuchungen beinhalten physische und neuropsychologische Untersuchungen,
+Labortests, Neuroimaging, Bewertungen des psychischen Zustands und eine
+Sammlung der Familiengeschichten. Zusätzlich werden Daten über medizinische
+und umweltbedingte Risikofaktoren gesammelt.
+
+Weitere Informationen zu den Zwillingsstudien finden Sie hier:
+
+@example
+@url{http://www.imm.ki.se/TWIN/TWINGREATBRITAINW.HTM}
+@end example
+
+Der spätere Teil des Projekts wird mit einer Web-Schnittstelle verwaltet,
+die Perl und MySQL benutzt.
+
+Jeden Abend werden alle Daten der Interviews in eine MySQL-Datenbank
+verschoben.
+
+
+
+@menu
+* Twin pool::
+* Twin event::
+@end menu
+
+@node Twin pool, Twin event, Twin, Twin
+@c German node Twin-Pool
+@subsection Alle nicht verteilten Zwillinge finden
+
+Mit folgender Anfrage wird festgelegt, wer in den zweiten Teil des Projekts
+geht:
+
+@example
+select
+ concat(p1.id, p1.tvab) + 0 as tvid,
+ concat(p1.christian_name, " ", p1.surname) as Name,
+ p1.postal_code as Code,
+ p1.city as City,
+ pg.abrev as Area,
+ if(td.participation = "Aborted", "A", " ") as A,
+ p1.dead as dead1,
+ l.event as event1,
+ td.suspect as tsuspect1,
+ id.suspect as isuspect1,
+ td.severe as tsevere1,
+ id.severe as isevere1,
+ p2.dead as dead2,
+ l2.event as event2,
+ h2.nurse as nurse2,
+ h2.doctor as doctor2,
+ td2.suspect as tsuspect2,
+ id2.suspect as isuspect2,
+ td2.severe as tsevere2,
+ id2.severe as isevere2,
+ l.finish_date
+from
+ twin_project as tp
+ /* For Twin 1 */
+ left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab
+ left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab
+ left join harmony as h on tp.id = h.id and tp.tvab = h.tvab
+ left join lentus as l on tp.id = l.id and tp.tvab = l.tvab
+ /* For Twin 2 */
+ left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab
+ left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab
+ left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab
+ left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab,
+ person_data as p1,
+ person_data as p2,
+ postal_groups as pg
+where
+ /* p1 gets main twin and p2 gets his/her twin. */
+ /* ptvab is a field inverted by tvab */
+ p1.id = tp.id and p1.tvab = tp.tvab and
+ p2.id = p1.id and p2.ptvab = p1.tvab and
+ /* Just the sceening survey */
+ tp.survey_no = 5 and
+ /* Skip if partner died before 65 but allow emigration (dead=9) */
+ (p2.dead = 0 or p2.dead = 9 or
+ (p2.dead = 1 and
+ (p2.sterbetag_date = 0 or
+ (((to_days(p2.sterbetag_date) - to_days(p2.geburtstagday)) / 365)
+ >= 65))))
+ and
+ (
+ /* Twin is suspect */
+ (td.future_contact = 'Yes' and td.suspect = 2) or
+ /* Twin is suspect - Informant is Blessed */
+ (td.future_contact = 'Yes' and td.suspect = 1 and id.suspect = 1) or
+ /* No twin - Informant is Blessed */
+ (ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = 'Yes') or
+ /* Twin broken off - Informant is Blessed */
+ (td.participation = 'Aborted'
+ and id.suspect = 1 and id.future_contact = 'Yes') or
+ /* Twin broken off - No inform - Have partner */
+ (td.participation = 'Aborted' and ISNULL(id.suspect) and p2.dead = 0))
+ and
+ l.event = 'Finished'
+ /* Get at area code */
+ and substring(p1.postal_code, 1, 2) = pg.code
+ /* Not already distributed */
+ and (h.nurse is NULL or h.nurse=00 or h.doctor=00)
+ /* Has not refused or been aborted */
+ and not (h.status = 'Refused' or h.status = 'Aborted'
+ or h.status = 'Died' or h.status = 'Other')
+order by
+ tvid;
+@end example
+
+Einige Erläuterungen:
+@table @asis
+@item @code{concat(p1.id, p1.tvab) + 0 as tvid}
+Wir wollen nach den verketteten @code{id} und @code{tvab} in numerischer
+Reihenfolge sortieren. Indem wir @code{0} hinzufügen, bringen wir MySQL
+dazu, das Ergebnis als Zahl zu behandeln.
+@item Spalte @code{id}
+Diese identifiziert ein Zwillingspaar. Sie ist in allen Tabellen Schlüssel.
+@item Spalte @code{tvab}
+Diese identifiziert ein Zwillingspaar. Sie hat einen Wert von @code{1} oder
+@code{2}.
+@item Spalte @code{ptvab}
+Sie ist die Umkehrung von @code{tvab}. Wenn @code{tvab} @code{1} ist, ist
+sie @code{2}, und umgekehrt. Sie ist dafür da, MySQL die Optimierung der
+Anfrage zu erleichtern.
+@end table
+Diese Anfrage demonstriert unter anderem, wie man ein Nachschlagen (Lookup)
+in einer Tabelle von derselben Tabelle aus mit einem Join durchführt
+(@code{p1} und @code{p2}). In dem Beispiel wird das dazu benutzt, um
+festzustellen, ob der Partner eines Zwillings vor Erreichen des 65.
+Lebensjahrs starb. Wenn das der Fall ist, wird die Zeile nicht
+zurückgegeben.
+
+Das Geschilderte existiert in allen Tabellen mit zwillingsbezogenen
+Informationen. Wir haben einen Schlüssel auf beide @code{id,tvab} (alle
+Tabellen), und auf @code{id,ptvab} (@code{person_data}), um Anfragen
+schneller zu machen.
+
+Auf unserer Produktionsmaschine (einer 200MHz-UltraSPARC) gibt diese
+Anfrage etwa 150 bis 200 Zeilen zurück und benötigt weniger als eine
+Sekunde.
+
+Die aktuelle Anzahl von Datensätzen in den oben benutzten Tabellen:
+@multitable @columnfractions .3 .5
+@item @strong{Tabelle} @tab @strong{Zeilen}
+@item @code{person_data} @tab 71074
+@item @code{lentus} @tab 5291
+@item @code{twin_project} @tab 5286
+@item @code{twin_data} @tab 2012
+@item @code{informant_data} @tab 663
+@item @code{harmony} @tab 381
+@item @code{postal_groups} @tab 100
+@end multitable
+
+
+@node Twin event, , Twin pool, Twin
+@c German node Twin-Ereignis
+@subsection Eine Tabelle über den Zustand von Zwillingspaaren zeigen
+
+Jedes Interview endet mit einem Statuscode, genannt @code{ereignis}. Die
+unten stehende Anfrage wird benutzt, um eine Tabelle über alle
+Zwillingspaare anzuzeigen, kombiniert mit dem Ereignis. Das zeigt an, wie
+viele Paare beider Zwillingen im Zustand beendet sind, bei wie vielen
+Paaren ein Zwilling im Zustand beendet ist, welche ein Interview abgelehnt
+haben usw.
+
+@example
+select
+ t1.event,
+ t2.event,
+ count(*)
+from
+ lentus as t1,
+ lentus as t2,
+ twin_project as tp
+where
+ /* We are looking at one pair at a time */
+ t1.id = tp.id
+ and t1.tvab=tp.tvab
+ and t1.id = t2.id
+ /* Just the sceening survey */
+ and tp.survey_no = 5
+ /* This makes each pair only appear once */
+ and t1.tvab='1' and t2.tvab='2'
+group by
+ t1.event, t2.event;
+@end example
+
+
+@node Apache, , Twin, Tutorial
+@c German node Apache
+@section MySQL mit Apache benutzen
+
+@cindex Apache
+
+
+
+
+Der Contrib-Abschnitt beinhaltet Programme, mit denen Sie Ihre Benutzer
+durch eine MySQL-Datenbank authentifizieren können, und mit denen Sie Ihre
+Logdateien in eine MySQL-Tabelle schreiben können. @xref{Contrib}.
+
+Sie können das Log-Format von Apache so ändern, dass es durch MySQL leicht
+gelesen werden kann, indem Sie folgendes in die Apache-Konfigurationsdatei
+schreiben:
+
+@example
+LogFormat \
+ "\"%h\",%@{%Y%m%d%H%M%S@}t,%>s,\"%b\",\"%@{Content-Type@}o\", \
+ \"%U\",\"%@{Referer@}i\",\"%@{User-Agent@}i\""
+@end example
+
+In MySQL können Sie dann etwas wie das hier tun:
+
+@example
+LOAD DATA INFILE '/local/access_log' INTO TABLE tabelle
+FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
+@end example
+
+
+@node MySQL Database Administration, MySQL Optimisation, Tutorial, Top
+@c German node MySQL-Datenbankadministration
+@chapter MySQL-Datenbankadministration
+
+
+
+@menu
+* Configuring MySQL::
+* Privilege system::
+* User Account Management::
+* Disaster Prevention::
+* Database Administration::
+* Localisation::
+* Server-Side Scripts::
+* Client-Side Scripts::
+* Log Files::
+* Replication::
+@end menu
+
+@node Configuring MySQL, Privilege system, MySQL Database Administration, MySQL Database Administration
+@c German node MySQL konfigurieren
+@section MySQL konfigurieren
+
+
+
+
+@menu
+* Command-line options::
+* Option files::
+* Installing many servers::
+* Multiple servers::
+@end menu
+
+@node Command-line options, Option files, Configuring MySQL, Configuring MySQL
+@c German node Kommandozeilenoptionen
+@subsection mysqld-Kommandozeilenoptionen
+
+@findex Kommandozeilenoptionen
+@cindex Optionen, Kommandozeile
+@cindex mysqld-Optionen
+
+@code{mysqld} akzeptiert folgende Kommandozeilenoptionen:
+
+@table @code
+@item --ansi
+ANSI-SQL-Syntax anstelle von MySQL-Syntax benutzen. @xref{ANSI mode}.
+
+@item -b, --basedir=path
+Pfad zum Installationsverzeichnis. Gewöhnlich werden alle Pfade relativ zu
+diesem aufgelöst.
+
+@item --big-tables
+große Ergebnismengen zulassen, indem alle temporären Mengen in eine Datei
+gesichert werden. Das löst die meisten 'table full'-Fehler, verlangsamt
+aber in den Fällen Anfragen, in denen Tabellen im Speicher ausreichen
+würden. Ab Version 3.23.2 ist MySQL in der Lage, das automatisch zu lösen,
+indem für kleine temporäre Tabellen der Arbeitsspeicher benutzt wird und
+auf Festplatten-Tabellen umgeschaltet wird, wenn das nötig ist.
+
+@item --bind-address=IP
+IP-Adresse zum Anbinden (bind).
+
+@item --character-sets-dir=path
+Verzeichnis, wo Zeichensätze sind. @xref{Character sets}.
+
+@item --chroot=path
+Chroot den @code{mysqld}-Daemon beim Start. Empfohlene
+Sicherheitsmaßnahme. Wird allerdings @code{LOAD DATA INFILE} und
+@code{SELECT ... INTO OUTFILE} etwas einschränken.
+
+@item --core-file
+Schreibt eine Core-Datei, wenn @code{mysqld} stirbt. Auf manchen Systemen
+müssen Sie zusätzliche @code{--core-file-size} für @code{safe_mysqld}
+angeben. @xref{safe_mysqld, ,@code{safe_mysqld}}.
+
+@item -h, --datadir=path
+Pfad zum Datenbank-Wurzelverzeichnis.
+
+@item --default-character-set=charset
+Setzt den vorgabemäßigen Zeichensatz. @xref{Character sets}.
+
+@item --default-table-type=type
+Setzt den vorgabemäßigen Tabellentyp für Tabellen. @xref{Table types}.
+
+@item --debug[...]=
+Wenn MySQL mit @code{--with-debug} konfiguriert ist, können Sie diese
+Option benutzen, um eine Trace-Datei darüber zu erhalten, was @code{mysqld}
+tut. @xref{Making trace files}.
+
+@item --delay-key-write-for-all-tables
+Schlüsselpuffer (Key Buffer) für jegliche @code{MyISAM}-Tabellen nicht
+leeren (flush).
+@xref{Server parameters}.
+
+@item --enable-locking
+System-Sperren einschalten. Beachten Sie, dass Sie bei der Benutzung dieser
+Option auf Systemen, die kein voll funktionsfähiges lockd() besitzen (wie
+Linux), mysqld leicht zum Deadlock bringen können.
+
+@item -T, --exit-info
+Eine Bit-Maske verschiedener Flags, mit denen man den mysqld-Server
+debuggen kann. Man sollte diese Option nicht benutzen, wenn man nicht ganz
+genau weiß, was sie tut!
+
+@item --flush
+Alle Änderungen nach jedem SQL-Befehl auf Platte zurückschreiben (flush).
+Normalerweise schreibt MySQL alle Änderungen nach jedem SQL-Befehl auf
+Platte und läßt das Betriebssystem sich um das Synchronisieren auf Platte
+kümmern.
+@xref{Crashing}.
+
+@item -?, --help
+Kurze Hilfe ausgeben und beenden.
+
+@item --init-file=file
+Beim Start SQL-Befehle aus dieser Datei lesen.
+
+@item -L, --language=...
+Client-Fehlermeldungen in der angegebenen Sprache. Kann als voller Pfad
+angegeben werden. @xref{Languages}.
+
+@item -l, --log[=datei]
+Loggt Verbindungen und Anfragen in datei. @xref{Query log}.
+
+@item --log-isam[=datei]
+Loggt alle ISAM- / MyISAM-Änderungen in datei (wird nur benutzt, um ISAM /
+MyISAM zu debuggen).
+
+@item --log-slow-queries[=datei]
+Loggt alle Anfragen, die länger als @code{long_query_time} Sekunden für die
+Ausführung benötigt haben, in datei. @xref{Slow query log}.
+
+@item --log-update[=datei]
+Loggt Updates in @code{datei.#}, wobei @code{#} eine eindeutige Zahl ist,
+falls nicht vorgegeben.
+@xref{Update log}.
+
+@item --log-long-format
+Loggt einige zusätzliche Informationen ins Update-Log. Wenn Sie
+@code{--log-slow-queries} benutzen, werden Anfragen, die keine Indexe
+benutzen, in die Langsame-Anfragen-Log-Datei geloggt.
+
+@item --low-priority-updates
+Operationen, die Tabellen ändern
+(@code{INSERT}/@code{DELETE}/@code{UPDATE}), haben geringere Priorität als
+Selects. Das kann auch mit @code{@{INSERT | REPLACE | UPDATE | DELETE@}
+LOW_PRIORITY ...} durchgeführt werden, um lediglich die Priorität einer
+einzelnen Anfrage zu verringern, oder mit @code{SET OPTION
+SQL_LOW_PRIORITY_UPDATES=1}, um die Priorität in einem Thread zu ändern.
+@xref{Table locking}.
+
+@item --memlock
+Sperrt den @code{mysqld}-Prozess in den Arbeitsspeicher. Das funktioniert
+nur, wenn Ihr System den @code{mlockall()}-Systemaufruf versteht (wie
+Solaris). Das kann helfen, wenn Sie Probleme damit haben, dass Ihr
+Betriebssystem @code{mysqld} veranlasst, auf Platte zu swappen.
+
+@item --myisam-recover [=option[,option...]]], wobei option eine
+Kombination von @code{DEFAULT}, @code{BACKUP}, @code{FORCE} oder
+@code{QUICK} ist. Sie können sie auch explizit auf @code{""} setzen, wenn
+Sie diese Option ausschalten wollen. Wenn die Option benutzt wird,
+überprüft @code{mysqld} beim Öffnen, ob die Tabelle als zerstört markiert
+ist oder ob die Tabelle nicht ordnungsgemäß geschlossen wurde. (Die letzte
+Option funktioniert nur, wenn Sie mysqld mit @code{--skip-locking} laufen
+lassen). Wenn das der Fall ist, läßt @code{mysqld} eine Überprüfung der
+Tabelle laufen. Wenn die Tabelle beschädigt war, versucht @code{mysqld},
+sie zu reparieren.
+
+Folgende Optionen beeinflussen, wie repair funktioniert.
+
+@multitable @columnfractions .3 .7
+@item DEFAULT @tab Dasselbe, als würde man für @code{--myisam-recover}
+ keine Option angeben.
+@item BACKUP @tab Wenn die Tabelle während der Wiederherstellung geändert
+ wurde, eine Datensicherung der @file{tabelle.MYD}-Datendatei als
+ @file{tabelle-datetime.BAK} speichern.
+@item FORCE @tab Eine Wiederherstellung selbst dann laufen lassen, wenn
+ man mehr als eine Zeile aus der .MYD-Datei verlieren wird.
+@item QUICK @tab Die Zeilen der Tabelle nicht überprüfen, wenn es keine
+ gelöschten Blocks gibt.
+@end multitable
+
+Bevor eine Tabelle automatisch repariert wird, fügt MySQL darüber eine
+Bemerkung in das Fehler-Log. Wenn Sie in der Lage sein wollen, die meisten
+Sachen ohne Benutzer-Intervention zu beheben, sollten Sie die Optionen
+@code{BACKUP,FORCE} benutzen. Das erzwingt ein Reparieren einer Tabelle,
+selbst wenn dabei einige Zeilen gelöscht würden, erhält aber die alte
+Datendatei als Datensicherung, so dass Sie später herausfinden können, was
+passiert ist.
+
+@item --pid-file=pfad
+Pfad zur pid-Datei, die von @code{safe_mysqld} benutzt wird.
+
+@item -P, --port=...
+Port-Nummer, um auf TCP/IP-Verbindungen zu warten (listen).
+
+@item -o, --old-protocol
+Das 3.20-Protokoll für Kompatibilität mit einigen sehr alten Clients
+benutzen.
+
+@item --one-thread
+Nur einen Thread benutzen (zum Debuggen unter Linux). @xref{Debugging server}.
+
+@item -O, --set-variable var=option
+Weist einer Variablen einen Wert zu. @code{--help} listet Variablen auf.
+Sie finden eine komplette Beschreibung aller Variablen im @code{SHOW
+VARIABLES}-Abschnitt dieses Handbuchs. @xref{SHOW VARIABLES}. Der Abschnitt
+über das Tunen der Serverparameter enthält Informationen darüber, wie man
+diese optimiert. @xref{Server parameters}.
+
+@item --safe-mode
+Einige Optimierungsschritte überspringen. Setzt
+@code{--skip-delay-key-write} voraus.
+
+@item --safe-show-database
+Keine Datenbanken anzeigen, für die der Benutzer keine Zugriffsrechte hat.
+
+@item --safe-user-create
+Wenn das angeschaltet ist, kann ein Benutzer keine neuen Benutzer mit dem
+GRANT-Befehl anlegen, wenn der Benutzer kein @code{INSERT}-Zugriffsrecht
+auf die @code{mysql.user}-Tabelle oder irgend welche Spalten dieser Tabelle
+hat.
+
+@item --skip-concurrent-insert
+Die Fähigkeit abschalten, gleichzeitig auf @code{MyISAM}-Tabellen
+auszuwählen (select) und einzufügen (insert). (Sollte nur benutzt werden,
+wenn Sie der Meinung sind, ein Bug in diesem Feature gefunden zu haben.)
+
+@item --skip-delay-key-write
+Die @code{delay_key_write}-Option für alle Tabellen ignorieren.
+@xref{Server parameters}.
+
+@item --skip-grant-tables
+Diese Option veranlasst den Server, das Zugriffsrechte-System überhaupt
+nicht zu benutzen. Das gibt jedem @emph{vollen Zugriff} auf alle
+Datenbanken! (Einen laufenden Server können Sie anweisen, die
+Berechtigungstabellen erneut zu verwenden, indem Sie @code{mysqladmin
+flush-privileges} oder @code{mysqladmin reload} ausführen.)
+
+@item --skip-host-cache
+Nie den Host-Name-Cache für schnellere Name-IP-Auflösung benutzen, sondern
+statt dessen bei jeder Verbindung beim DNS-Server anfragen. @xref{DNS}.
+
+@item --skip-locking
+System-Sperren nicht benutzen. Um @code{isamchk} oder @code{myisamchk}
+auszuführen, müssen Sie den Server herunter fahren. @xref{Stability}.
+Beachten Sie, dass Sie in MySQL-Version 3.23 @code{REPAIR} und @code{CHECK}
+benutzen können, um @code{MyISAM}-Tabellen zu reparieren / zu prüfen.
+
+@item --skip-name-resolve
+Hostnamen werden nicht aufgelöst. Alle @code{Host}-Spaltenwerte in den
+Berechtigungstabellen müssen IP-Nummern oder @code{localhost} sein.
+@xref{DNS}.
+
+@item --skip-networking
+Auf überhaupt keine TCP/IP-Verbindungen warten (listen). Jede Interaktion
+mit @code{mysqld} muss über Unix-Sockets erfolgen. Diese Option wird
+ausdrücklich empfohlen für Systeme, auf denen nur lokale Anfragen
+(Requests) erlaubt sind. @xref{DNS}.
+
+@item --skip-new
+Keine neuen, möglicherweise falschen Routinen benutzen. Setzt
+@code{--skip-delay-key-write} voraus. Setzt ausserdem den vorgabemäßigen
+Tabellentyp auf @code{ISAM}. @xref{ISAM}.
+
+@item --skip-symlink
+Keine Dateien löschen oder umbenennen, auf die eine mit Symlink verknüpfte
+Datei im Daten-Verzeichnis zeigt.
+
+@item --skip-safemalloc
+Wenn MySQL mit @code{--with-debug=full} konfiguriert wird, überprüfen alle
+Programme den Arbeitsspeicher auf Überlauf, bei jeder Speicher-Allokation
+und -Freigabe. Da dieses Prüfen sehr langsam ist, können Sie es vermeiden,
+wenn Sie keine Arbeitsspeicherprüfung benötigten, indem Sie diese Option
+benutzen.
+
+@item --skip-show-database
+Keine 'SHOW DATABASE'-Befehle zulassen, wenn der Benutzer keine
+@strong{process}-Berechtigung hat.
+
+@item --skip-stack-trace
+Keine Stack-Traces schreiben. Diese Option ist nützlich, wenn Sie
+@code{mysqld} unter einem Debugger laufen lassen. @xref{Debugging server}.
+
+@item --skip-thread-priority
+Benutzung von Thread-Prioritäten abschalten, um schnellere Antwortzeiten zu
+erzielen.
+
+@item --socket=pfad
+Socket-Datei, die anstelle des vorgabemäßigen @code{/tmp/mysql.sock} für
+lokale Verbindungen benutzt wird.
+
+@item --sql-mode=option[,option[,option...]]
+Option kann jede beliebige Kombination von @code{REAL_AS_FLOAT},
+@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE},
+@code{SERIALIZE} und @code{ONLY_FULL_GROUP_BY} sein. Sie kann auch leer
+sein (@code{""}), wenn Sie dies zurücksetzen wollen.
+
+Alle oben angegebenen Optionen festlegen ist dasselbe wie --ansi benutzen.
+Mit dieser Option kann man nur benötigte SQL-Modi anschalten.
+@xref{ANSI mode}.
+
+@item transaction-isolation= @{ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE @}
+Setzt das vorgabemäßige Transaktions-Isolations-Level.
+@c German FIX unsplit @xref
+@xref{SET TRANSACTION}.
+
+@item -t, --tmpdir=pfad
+Pfad für temporäre Dateien. Es kann nützlich sein, wenn Ihr vorgabemäßiges
+@code{/tmp}-Verzeichnis auf einer Partition liegt, die zu klein ist, um
+temporäre Tabellen zu speichern.
+
+@item -u, --user=benutzername
+Den @code{mysqld}-Daemon unter dem Benutzer @code{benutzername} laufen
+lassen. Diese Option ist @emph{zwingend notwendig}, wenn @code{mysqld} als
+Root gestartet wird.
+
+@item -V, --version
+Versionsinformationen ausgeben und beenden.
+
+@item -W, --warnings
+Warnmeldungen wie @code{Aborted connection...} in die @code{.err}-Datei
+ausgeben. @xref{Communication errors}.
+@end table
+
+
+@node Option files, Installing many servers, Command-line options, Configuring MySQL
+@c German node Optionsdateien
+@subsection my.cnf-Optionsdateien
+
+@cindex Vorgabemäßige Optionen
+@cindex Optionsdateien
+@cindex Erzeugen, vorgabemäßige Startoptionen
+@cindex Startoptionen, vorgabemäßige
+
+Seit Version 3.22 kann MySQL vorgabemäßige Startoptionen für den Server
+und für Clients aus Optionsdateien lesen.
+
+MySQL liest Vorgabeoptionen aus folgenden Dateien unter Unix:
+
+@tindex .my.cnf-Datei
+@multitable @columnfractions .3 .7
+@item @strong{Dateiname} @tab @strong{Zweck}
+@item @code{/etc/my.cnf} @tab Globale Optionen
+@item @code{DATADIR/my.cnf} @tab Server-spezifische Optionen
+@item @code{defaults-extra-file} @tab Die Datei, die mit --defaults-extra-file=# festgelegt wird
+@item @code{~/.my.cnf} @tab Benutzerspezifische Optionen
+@end multitable
+
+@code{DATADIR} ist das MySQL-Daten-Verzeichnis (typischerweise
+@file{/usr/local/mysql/data} bei einer Binärinstallation oder
+@file{/usr/local/var} bei einer Quellinstallation). Beachten Sie, dass das
+das Verzeichnis ist, das zur Konfigurationszeit festgelegt wurde, nicht
+das, das mit @code{--datadir} festgelegt wird, wenn @code{mysqld} startet!
+(@code{--datadir} hat keinen Einfluss darauf, wo der Server nach
+Optionsdateien sucht, denn er sucht nach ihnen, bevor er irgend welche
+Kommandozeilenargumente verarbeitet.)
+
+MySQL liest Vorgabeoptionen aus folgenden Dateien unter Windows:
+
+@multitable @columnfractions .3 .7
+@item @strong{Dateiname} @tab @strong{Zweck}
+@item @code{Windows-System-Verzeichnis\my.ini} @tab Globale Optionen
+@item @code{C:\my.cnf} @tab Globale Optionen
+@item @code{C:\mysql\data\my.cnf} @tab Server-spezifische Optionen
+@end multitable
+
+Beachten Sie, dass Sie unter Windows alle Pfade mit @code{/} statt mit
+@code{\} angeben sollten. Wenn Sie @code{\} benutzen, müssen Sie das
+doppelt (@code{\\}) tun, weil @code{\} in MySQL das Fluchtzeichen
+(Escape-Character) ist.
+
+@cindex Umgebungsvariablen
+MySQL versucht, Optionsdateien in der oben angegebenen Reihenfolge zu
+lesen. Wenn es mehrere Optionsdateien gibt, erlangt eine Option, die in
+einer Datei festgelegt wird, die später gelesen wird, Vorrang über dieselbe
+Option, die in einer sonstigen Optionsdatei festgelegt wurde. Optionen, die
+auf der Kommandozeile festgelegt werden, erlangen Vorrang vor Optionen in
+jeglichen Optionsdateien. Einige Optionen können durch Umgebungsvariablen
+festgelegt werden. Optionen, die auf der Kommandozeile oder in
+Optionsdateien festgelegt werden, haben Vorrang vor Werten in
+Umgebungsvariablen. @xref{Environment variables}.
+Folgende Programme unterstützen Optionsdateien: @code{mysql},
+@code{mysqladmin}, @code{mysqld}, @code{mysqldump}, @code{mysqlimport},
+@code{mysql.server}, @code{myisamchk} und @code{myisampack}.
+
+Sie können Optionsdateien benutzen, um jede beliebig lange Option
+festzulegen, die ein Programm unterstützt! Starten Sie das Programm mit
+@code{--help}, um eine Liste der verfügbaren Optionen zu erhalten.
+
+Eine Optionsdatei kann Zeilen der folgenden Formate enthalten:
+
+@table @code
+@item #Kommentar
+Kommentarzeilen fangen mit @samp{#} oder @samp{;} an. Leere Zeilen werden
+ignoriert.
+
+@item [group]
+@code{group} ist der Name des Programms oder der Gruppe, für das oder die
+Sie Optionen setzen wollen. Nach einer Gruppen-Zeile beziehen sich alle
+@code{option}- oder @code{set-variable}-Zeilen auf die benannte Gruppe, bis
+zum Ende der Optionsdatei oder bis eine andere Gruppe angegeben wird.
+
+@item option
+Das ist äquivalent zu @code{--option} auf der Kommandozeile.
+
+@item option=value
+Das ist äquivalent zu @code{--option=value} auf der Kommandozeile.
+
+@item set-variable = variable=value
+Das ist äquivalent zu @code{--set-variable variable=value} auf der Kommandozeile.
+Diese Syntax muss verwendet werden, um eine @code{mysqld}-Variable zu
+setzen.
+@end table
+
+Die @code{client}-Gruppe gestattet Ihnen, Optionen anzugeben, die sich auf
+alle MySQL-Clients (nicht auf @code{mysqld}) beziehen. Diese Gruppe eignet
+sich bestens dafür, das Passwort festzulegen, das Sie benutzen, um sich mit
+dem Server zu verbinden. (Stellen Sie jedoch sicher, dass die Optionsdatei
+nur für Sie les- und schreibbar ist.)
+
+Beachten Sie, dass bei Optionen und Werten alle führenden Leerzeichen und
+solche am Zeilenende automatisch entfernt werden. Sie können in der
+Zeichenkette für den Wert die Escape-Sequenzen @samp{\b}, @samp{\t},
+@samp{\n}, @samp{\r}, @samp{\\} und @samp{\s} benutzen (@samp{\s} ist das
+Leerzeichen).
+
+Hier ist eine typische globale Optionsdatei:
+
+@example
+[client]
+port=3306
+socket=/tmp/mysql.sock
+
+[mysqld]
+port=3306
+socket=/tmp/mysql.sock
+set-variable = key_buffer_size=16M
+set-variable = max_allowed_packet=1M
+
+[mysqldump]
+quick
+@end example
+
+Hier ist eine typische Benutzer-Optionsdatei:
+
+@example
+[client]
+# Folgendes Passwort wird an alle Standard-MySQL-Clients geschickt:
+password=mein_password
+
+[mysql]
+no-auto-rehash
+set-variable = connect_timeout=2
+
+[mysqlhotcopy]
+interactive-timeout
+
+@end example
+
+@tindex .my.cnf Datei
+Wenn Sie eine Quelldistribution haben, finden Sie Beispielkonfigurationen
+in den Dateien mit Namen @file{my-xxxx.cnf} im
+@file{Support-files}-Verzeichnis. Wenn Sie eine Binärdistribution haben,
+suchen Sie im @file{DIR/support-files}-Verzeichnis, wobei @code{DIR} der
+Pfadname zum MySQL-Installationsverzeichnis ist (typischerweise
+@file{/usr/local/mysql}). Aktuell finden Sie dort beispielhafte
+Konfigurationsdateien für kleine, mittlere, große und sehr große Systeme.
+Sie können @file{my-xxxx.cnf} in Ihr Heimatverzeichnis kopieren, um damit
+zu experimentieren (benennen Sie die Kopie in @file{.my.cnf} um).
+
+Alle MySQL-Clients, die Optionsdateien unterstützen, unterstützen folgende
+Optionen:
+
+@multitable @columnfractions .40 .60
+@item --no-defaults @tab Keine Optionsdateien einlesen.
+@item --print-defaults @tab Den Programmnamen und alle Optionen, die das Programm erhalten wird, ausgeben.
+@item --defaults-file=voller-pfad-zur-vorgabe-datei @tab Nur die angegebene Konfigurationsdatei benutzen.
+@item --defaults-extra-file=voller-pfad-zur-vorgabe-datei @tab Diese Konfigurationsdatei nach der globalen Konfigurationsdatei einlesen, aber vor der Benutzer-Konfigurationsdatei.
+@end multitable
+
+Beachten Sie, dass die oben aufgeführten Optionen auf der Kommandozeile
+zuerst angegeben werden müssen, damit sie funktionieren!
+@code{--print-defaults} kann jedoch direkt nach den
+@code{--defaults-xxx-file}-Befehlen angegeben werden.
+
+Hinweis für Entwickler: Optionsdatei-Handhabung ist schlicht dadurch
+implementiert, dass alle übereinstimmenden Optionen verarbeitet werden
+(das heißt, Optionen in der entsprechenden Gruppe), vor jeglichen
+Kommandozeilen-Argumenten. Das funktioniert sehr gut bei Programmen, die
+die letzte Instanz einer Option benutzen, die mehrfach festgelegt wurde.
+Wenn Sie ein altes Programm benutzen, das mehrfach festgelegte Optionen auf
+diese Art handhabt, aber keine Optionsdateien liest, müssen Sie nur zwei
+Zeilen hinzufügen, um diese Fähigkeit hinzuzufügen. Sehen Sie im Quellcode
+irgend eines Standard-MySQL-Clients nach, wie das gemacht wird.
+
+In Shellskripts können Sie den @file{my_print_defaults}-Befehl benutzen, um
+die Konfigurationsdateien zu parsen:
+
+@example
+
+shell> my_print_defaults client mysql
+--port=3306
+--socket=/tmp/mysql.sock
+--no-auto-rehash
+@end example
+
+Die Ausgabe enthält alle Optionen für die Gruppen 'client' und 'mysql'.
+
+
+@node Installing many servers, Multiple servers, Option files, Configuring MySQL
+@c German node Viele Server installieren
+@subsection Viele Server auf derselben Maschine installieren
+
+@cindex Nach der Installation, mehrere Server
+@cindex Mehrere Server installieren
+@cindex Mehrere Server starten
+
+In einigen Fällen brauchen Sie vielleicht viele verschiedene
+@code{mysqld}-Daemons (Server), die auf derselben Maschine laufen.
+Beispielsweise wollen Sie eine neue MySQL-Version zum Testen benutzen,
+während gleichzeitig eine alte Version für die Produktion läuft, oder Sie
+wollen verschiedenen Benutzern Zugriff auf verschiedene
+@code{mysqld}-Server geben, die sie selbst verwalten.
+
+Eine Möglichkeit, einen neuen Server laufen zu lassen, besteht darin, ihn
+mit einem anderen Socket und einem anderen Port wie folgt zu starten:
+
+@tindex @code{MYSQL_UNIX_PORT}-Umgebungsvariable
+@tindex @code{MYSQL_TCP_PORT}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_UNIX_PORT}
+@tindex Umgebungsvariable, @code{MYSQL_TCP_PORT}
+@example
+shell> MYSQL_UNIX_PORT=/tmp/mysqld-neu.sock
+shell> MYSQL_TCP_PORT=3307
+shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
+shell> scripts/mysql_install_db
+shell> bin/safe_mysqld &
+@end example
+
+Der Umgebungsvariablen-Appendix beinhaltet eine Liste anderer
+Umgebungsvariablen, die Sie benutzen können, um @code{mysqld} zu steuern.
+@xref{Environment variables}.
+
+Der oben gezeigte Weg ist die 'schnelle und schmutzige' Lösung, die man
+üblicherweise zum Testen benutzt. Das nette daran ist, dass alle
+Verbindungen, die Sie in obiger Shell aufbauen, automatisch an den neuen
+laufenden Server weiter geleitet werden!
+
+Wenn Sie dasselbe dauerhafter durchführen wollen, sollten Sie für jeden
+Server eine Optionsdatei erzeugen. @xref{Option files}. In Ihrem
+Startskript, das beim Hochfahren ausgeführt wird (mysql.server?) sollten
+Sie für beide Server folgendes festlegen:
+
+@code{safe_mysqld --default-file=pfad-zur-optionsdatei}
+
+Zumindest folgende Optionen sollten für jeden Server unterschiedlich sein:
+
+@table @code
+@item port=#
+@item socket=pfad
+@item pid-file=pfad
+@end table
+
+Folgende Optionen sollten unterschiedlich sein, wenn sie benutzt werden:
+
+@table @code
+@item log=pfad
+@item log-bin=pfad
+@item log-update=pfad
+@item log-isam=pfad
+@item bdb-logdir=pfad
+@end table
+
+Wenn Sie mehr Performance erreichen wollen, können Sie auch folgendes
+unterschiedlich festlegen:
+
+@table @code
+@item tmpdir=pfad
+@item bdb-tmpdir=pfad
+@end table
+
+@xref{Command-line options}.
+
+Wenn Sie binäre MySQL-Versionen installieren (.tar-Dateien) und sie mit
+@code{./bin/safe_mysqld} starten, müssen Sie in den meisten Fällen
+lediglich die @code{socket}- und @code{port}-Argumente in
+@code{safe_mysqld} hinzufügen / ändern.
+
+
+
+
+@node Multiple servers, , Installing many servers, Configuring MySQL
+@c German node Mehrere Server
+@subsection Viele MySQL-Server auf derselben Maschine laufen lassen
+
+@cindex Mehrere Server
+@cindex Servers, mehrere
+@cindex Laufen lassen, mehrere Server
+
+Unter bestimmten Umständen wollen Sie vielleicht mehrere Server auf
+derselben Maschine laufen lassen. Beispielsweise wollen Sie ein neues
+MySQL-Release testen, Ihre bestehende Produktionseinrichtung aber
+unangetastet lassen. Oder Sie sind ein Internet-Service-Provider, der
+unabhängige MySQL-Installationen für verschiedene Kunden hat.
+
+Wenn Sie mehrere Server laufen lassen wollen, ist es am einfachsten, die
+Server mit unterschiedlichen TCP/IP-Ports und Socket-Dateien laufen zu
+lassen, damit sie nicht beide auf demselben TCP/IP-Port oder derselben
+Socket-Datei auf Verbindungen warten. @xref{mysqld_multi, ,
+@code{mysqld_multi}}.
+
+Nehmen wir einen existierenden Server an, der auf die existierende
+Port-Nummer und Socket-Datei konfiguriert ist. Sie konfigurieren einen
+neuen Server mit einem @code{configure}-Befehl, etwa wie folgt:
+
+@example
+shell> ./configure --with-tcp-port=port_nummer \
+ --with-unix-socket-path=datei \
+ --prefix=/usr/local/mysql-3.22.9
+@end example
+
+Hier müssen @code{port_nummer} und @code{datei} anders als die
+vorgabemäßigen Werte sein. Der @code{--prefix}-Wert sollte ein
+Installationsverzeichnis festlegen, das anders ist als dasjenige, unter dem
+die existierende MySQL-Installation liegt.
+
+Sie können den Socket, der vom aktuell laufenden MySQL-Server benutzt wird,
+mit folgendem Befehl feststellen:
+
+@example
+shell> mysqladmin -h hostname --port=port_nummer variables
+@end example
+
+Wenn Sie ``@code{localhost}'' als Hostnamen festlegen, benutzt
+@code{mysqladmin} Unix-Sockets anstelle von TCP/IP.
+
+Wenn Sie einen MySQL-Server auf dem Port laufen haben, den Sie benutzt
+haben, bekommen Sie eine Liste der wichtigsten konfigurierbaren Variablen
+in MySQL, inklusive des Socketnamens.
+
+Sie müssen keinen neuen MySQL-Server kompilieren, nur um ihn mit einem
+anderen Port und Socket zu starten. Sie können Port und Socket zur Laufzeit
+als Optionen von @code{safe_mysqld} festlegen:
+
+@example
+shell> /pfad/zu/safe_mysqld --socket=datei --port=port_nummer
+@end example
+
+@code{mysqld_multi} kann ebenfalls @code{safe_mysqld} (oder @code{mysqld})
+als Argument nehmen und die Optionen von einer Konfigurationsdatei an
+@code{safe_mysqld} und weiter an @code{mysqld} durchreichen.
+
+Wenn Sie den neuen Server mit demselben Datenbankverzeichnis laufen lassen
+und Loggen angeschaltet haben, sollten Sie auch den Namen der Logdateien
+für @code{safe_mysqld} mit @code{--log}, @code{--log-update} oder
+@code{--log-slow-queries} festlegen. Ansonsten versuchen beide Server, in
+dieselbe Logdatei zu schreiben.
+
+@strong{ACHTUNG}: Normalerweise sollten Sie nie zulassen, dass zwei Server
+Daten in derselben Datenbank aktualisieren! Wenn Ihr Betriebssystem kein
+fehlerfreies System-Sperren (System Locking) unterstützt, führt das zu
+unliebsamen Überraschungen!
+
+Wenn Sie für den zweiten Server ein anderes Datenbankverzeichnis benutzen
+wollen, können Sie das mit der @code{--datadir=path}-Option für
+@code{safe_mysqld} angeben.
+
+@strong{HINWEIS:} Mehrere MySQL-Server (@code{mysqld}) auf verschiedenen
+Maschinen laufen lassen, die auf ein gemeinsames Datenverzeichnis über
+@code{NFS} zugreifen, ist generell eine @strong{SCHLECHTE IDEE}! Das
+Problem liegt darin, dass @code{NFS} zum Flaschenhals in Punkto
+Geschwindigkeit wird, denn es ist nicht für solche Zwecke gedacht. Und
+letztlich müssten Sie immer noch eine Lösung dafür finden, dass sich zwei
+oder mehr @code{mysqlds} nicht in die Quere kommen. Momentan gibt es keine
+Plattform, die mit 100%-iger Zuverlässigkeit Datei-Sperren (File Locking,
+gewöhnlich mit dem @code{lockd}-Daemon) in jeder Situation durchführt.
+Dennoch stellt @code{NFS} ein weiteres mögliches Risiko dar, denn es macht
+es dem @code{lockd}-Daemon noch schwieriger, Datei-Sperren zu handhaben.
+Machen Sie es sich also leicht und vergessen Sie diese Idee! Die
+funktionierende Lösung ist, einen Computer mit einem Betriebssystem
+einzusetzen, dass Threads effizient handhabt und mehrere Prozessoren hat.
+
+Wenn Sie sich mit einem MySQL-Server verbinden wollen, der mit einem
+anderen Port läuft als mit dem, der in Ihren Client kompiliert ist, können
+Sie folgende Methoden benutzen:
+
+@itemize @bullet
+@item
+Starten Sie den Client mit @code{--host 'hostname' --port=port_nummer}, um
+sich über TCP/IP zu verbinden, oder mit @code{[--host localhost]
+--socket=datei}, um sich über ein Unix-Socket zu verbinden.
+
+@item
+In Ihren C- oder Perl-Programmen können Sie die Port- oder Socket-Argumente
+angeben, wenn Sie sich mit dem MySQL-Server verbinden.
+
+@item
+Wenn Sie das Perl-@code{DBD::mysql}-Modul benutzen, können Sie die Optionen
+aus den MySQL-Optionsdateien lesen. @xref{Option files}.
+
+@example
+$dsn = "DBI:mysql:test;mysql_read_default_group=client;mysql_read_default_file=/usr/local/mysql/data/my.cnf"
+$dbh = DBI->connect($dsn, $user, $password);
+@end example
+
+@item
+@tindex MYSQL_UNIX_PORT-Umgebungsvariable
+@tindex MYSQL_TCP_PORT-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_UNIX_PORT
+@tindex Umgebungsvariable, MYSQL_TCP_PORT
+Setzen Sie die @code{MYSQL_UNIX_PORT}- und
+@code{MYSQL_TCP_PORT}-Umgebungsvariablen, so dass sie auf den Unix-Socket
+und TCP/IP-Port zeigen, bevor Sie Ihre Clients starten. Wenn Sie
+normalerweise eine speziellen Socket oder Port benutzen, sollten Sie die
+Befehle zum Setzen dieser Umgebungsvariablen in Ihrer @file{.login}-Datei
+unterbringen.
+@xref{Environment variables}.
+
+@item
+@tindex .my.cnf Datei
+Legen Sie den vorgabemäßigen Socket und TCP/IP-Port in der
+@file{.my.cnf}-Datei in Ihrem Heimatverzeichnis fest.
+@xref{Option files}.
+@end itemize
+
+
+@node Privilege system, User Account Management, Configuring MySQL, MySQL Database Administration
+@c German node Berechtigungssystem
+@section Allgemeine Sicherheitsthemen und das MySQL-Zugriffsberechtigungssystem
+
+@cindex System, Sicherheit
+@cindex Zugriffsberechtigungen
+@cindex Berechtigungen, Zugriff
+@cindex Sicherheitssystem
+@cindex ACLs
+
+MySQL hat ein fortgeschrittenes, aber nicht standardisiertes Sicherheits-
+bzw. Berechtigungssystem. Dieser Abschnitt beschreibt, wie es funktioniert.
+
+
+
+@menu
+* General security::
+* Security::
+* Privileges options::
+* What Privileges::
+* Privileges::
+* Privileges provided::
+* Connecting::
+* Connection access::
+* Request access::
+* Access denied::
+@end menu
+
+@node General security, Security, Privilege system, Privilege system
+@c German node Allgemeine Sicherheitsrichtlinien
+@subsection Allgemeine Sicherheitsrichtlinien
+
+Jeder, der MySQL auf einem Computer benutzt, der mit dem Internet verbunden
+ist, sollte diesen Abschnitt lesen, um die gebräuchlichsten
+Sicherheitsfehler zu vermeiden.
+
+Wenn wir über Sicherheit sprechen, unterstreichen wir die Notwendigkeit,
+den gesamten Server-Host (und nicht nur den MySQL-Server) gegen alle Arten
+möglicher Angriffe abzusichern: Lauschangriffe, Änderungen (Altering),
+Playback und Dienstverweigerung (Denial of Service). Dieser Abschnitt deckt
+nicht alle Aspekte von Verfügbarkeit und Fehlertoleranz ab.
+
+MySQL benutzt ein Sicherheitssystem, das auf Zugriffssteuerungslisten
+(Access Control Lists, ACLs) für alle Verbindungen, Anfragen und sonstige
+Operationen basiert, die ein Benutzer durchführen kann. Zusätzlich gibt es
+einige Unterstützung für SSL-verschlüsselte Verbindungen zwischen
+MySQL-Clients und -Servern. Viele der hier geschilderten Konzepte sind
+überhaupt nicht spezifisch für MySQL, sondern beziehen sich auf fast alle
+Applikationen.
+
+Wenn Sie MySQL laufen lassen, sollten Sie möglichst immer folgende
+Richtlinien beachten:
+
+@itemize @bullet
+@item
+GEBEN SIE NIEMALS JEMANDEM AUSSER DEM MySQL-ROOT-BENUTZER ZUGRIFF AUF DIE
+@code{user}-TABELLE IN DER @code{mysql}-DATENBANK! Das verschlüsselte
+Passwort ist das echte Passwort in MySQL. Wenn Sie das in der the
+@code{user}-Tabelle aufgeführte Passwort für einen gegebenen Benutzer
+kennen, können Sie sich leicht als dieser Benutzer einloggen, wenn Sie
+Zugriff auf den Host haben, der für dieses Benutzerkonto aufgeführt ist.
+
+@item
+Lernen Sie das MySQL-Zugriffsberechtigungssystem. Die @code{GRANT}- und
+@code{REVOKE}-Befehle werden benutzt, um den Zugriff auf MySQL zu steuern.
+Gewähren Sie nicht mehr Zugriffsrechte als notwendig. Gewähren Sie niemals
+Zugriffsrechte für alle Hosts.
+
+Checkliste:
+@itemize @minus
+@item
+Probieren Sie @code{mysql -u root}. Wenn es Ihnen gelingt, sich erfolgreich
+mit dem Server zu verbinden, ohne nach einem Passwort gefragt zu werden,
+haben Sie ein Problem, denn jeder kann sich als MySQL-@code{root}-Benutzer
+mit dem Server verbinden und hat volle Berechtigungen! Lesen Sie in diesem
+Fall noch einmal die MySQL-Installationsanweisungen durch und achten Sie
+insbesondere auf den Teil, der sich mit dem Setzen des
+@code{root}-Passworts beschäftigt.
+@item
+Benutzen Sie den Befehl @code{SHOW GRANTS} und prüfen Sie nach, wer Zugriff
+auf was hat. Entfernen Sie die Berechtigungen, die nicht notwendig sind,
+indem Sie den @code{REVOKE}-Befehl benutzen.
+@end itemize
+@item
+Halten Sie keine Klartext-Passwörter in Ihrer Datenbank. Wenn Ihr Computer
+kompromittiert wird, kann der Einbrecher die gesamte Liste von Passwörtern
+nehmen und benutzen. Benutzen Sie statt dessen @code{MD5()} oder eine
+andere Einweg-Hash-Funktion.
+@item
+Benutzen Sie keine Passwörter aus Lexika. Es gibt spezielle Programme, um
+diese zu knacken. Selbst Passwörter wie ``xfish98'' sind sehr schlecht.
+Viel besser ist ``duag98'', was dasselbe Wort ``fish'' enthält, aber um
+eine Taste nach links auf einer QUERTZ-Tastatur verschoben. Eine weitere
+Methode ist, etwas wie ``Mhall'' zu benutzen, was die ersten Buchstaben des
+Satzes ``Mary had a little lamb'' enthält. Das läßt sich leicht merken und
+eintippen, aber schwierig durch jemanden erraten, der es nicht kennt.
+@item
+Investieren Sie in eine Firewall. Diese schützt sie vor mindestens 50%
+aller Exploits in jeglicher Software. Installieren Sie MySQL hinter einer
+Firewall oder in einer entmilitarisierten Zone (Demilitarized Zone, DMZ).
+
+Checkliste:
+@itemize @minus
+@item
+Versuchen Sie, Ihre Ports vom Internet aus zu scannen, indem Sie ein Werkzeug
+wie @code{nmap} benutzen. MySQL benutzt vorgabemäßig Port 3306. Dieser
+Port sollte von nicht vertrauenswürdigen Hosts aus unerreichbar sein. Eine
+weitere einfache Methode, um zu überprüfen, ob Ihr MySQL-Port offen ist
+oder nicht, ist, den folgenden Befehl von einer entfernten Maschine aus zu
+benutzen, wobei @code{server_host} der Hostname Ihres MySQL-Servers ist:
+
+@example
+shell> telnet server_host 3306
+@end example
+
+Wenn Sie eine Verbindung und einige sinnlose Zeichen erhalten, ist der Port
+offen und sollte auf Ihrer Firewall oder Ihrem Router geschlossen werden,
+sofern Sie nicht einen wirklich guten Grund haben, ihn offen zu halten.
+Wenn @code{telnet} einfach hängt oder die Verbindung abgelehnt wird, ist
+alles in Ordnung, der Port ist blockiert.
+@end itemize
+
+@item
+Trauen Sie keinen Daten, die von Benutzern eingegeben werden. Sie können
+versuchen, Ihren Code auszutricksen, indem Sie spezielle oder escapete
+Zeichenfolgen in Web-Formulare, URLs oder sonstige Applikationen, die Sie
+hergestellt haben, eingeben. Stellen Sie sicher, dass Ihre Applikation
+sicher bleibt, wenn ein Benutzer etwas wie ``@code{; DROP DATABASE
+mysql;}'' eingibt. Das ist ein extremes Beispiel, aber große
+Sicherheitslücken und Datenverlust können eintreten, wenn ein Hacker
+ähnliche Techniken benutzt und Sie nicht darauf vorbereitet sind.
+
+Denken Sie auch daran, numerische Daten zu überprüfen. Ein häufiger Fehler
+besteht darin, nur Zeichenketten zu schützen. Manchmal denken Leute, dass
+eine Datenbank, die nur öffentlich zugängliche Daten enthält, nicht
+geschützt werden muss. Das stimmt nicht. Auf solche Datenbanken können
+zumindest Dienstverweigerungsangriffe (Denial-of-Service-Attacken)
+durchgeführt werden. Die einfachste Art, sich vor dieser Art von Angriffen
+zu schützen, ist, Apostrophe um numerische Konstanten herum zu benutzen:
+@code{SELECT * FROM tabelle WHERE ID='234'} statt @code{SELECT * FROM
+tabelle WHERE ID=234}. MySQL wandelt diese Zeichenkette automatisch in eine
+Zahl um und entfernt alle nicht-numerischen Zeichen aus ihr.
+
+Checkliste:
+@itemize @minus
+@item
+Alle Web-Applikationen:
+@itemize @bullet
+@item
+Versuchen Sie, @samp{'} und @samp{"} in alle Ihr Web-Formulare einzugeben.
+Wenn Sie irgend welche MySQL-Fehler erhalten, untersuchen Sie das Problem
+unverzüglich!
+@item
+Versuchen Sie, jedwede dynamischen URLs zu ändern, indem Sie @code{%22}
+(@samp{"}), @code{%23} (@samp{#}) und @code{%27} (@samp{'}) zu den URLs
+hinzufügen.
+@item
+Versuchen Sie, Datentypen in dynamischen URLs von numerischen zu
+Zeichentypen zu ändern, die Zeichen aus den vorherigen Beispielen
+enthalten. Ihre Applikation sollte gegen solche und ähnliche Angriffe
+sicher sein.
+@item
+Versuchen Sie Buchstaben, Leerzeichen und Sonderzeichen anstelle von Zahlen
+in numerische Felder einzugeben. Ihre Applikation sollte diese entfernen,
+bevor sie sie MySQL übergibt, und Ihre Applikation sollte einen Fehler
+erzeugen. Es ist sehr gefährlich, nicht geprüfte Werte an MySQL zu
+übergeben!
+@item
+Überprüfen Sie Datengrößen, bevor Sie sie an MySQL übergeben.
+@item
+Überlegen Sie, ob es sinnvoll ist, dass sich Ihre Applikation mit einem
+anderen Benutzernamen mit der Datenbank verbindet als mit dem, den Sie für
+Verwaltungszwecke benutzen. Geben Sie Applikationen nicht mehr
+Zugriffsberechtigungen als sie brauchen.
+@end itemize
+@item
+Benutzer von PHP:
+@itemize @bullet
+@item Sehen Sie sich die @code{addslashes()}-Funktion an.
+Ab PHP 4.0.3 ist eine @code{mysql_escape_string()}-Funktion verfügbar, die
+auf der Funktion mit demselben Namen in der MySQL-C-API basiert.
+@end itemize
+@item
+Benutzer der MySQL-C-API:
+@itemize @bullet
+@item Sehen Sie sich den @code{mysql_escape_string()}-API-Aufruf an.
+@end itemize
+@item
+Benutzer von MySQL++:
+@itemize @bullet
+@item Sehen Sie sich die @code{escape}- und @code{quote}-Modifier für
+Query-Streams an.
+@end itemize
+@item
+Benutzer der Perl-DBI:
+@itemize @bullet
+@item Sehen Sie sich die @code{quote()}-Methode an oder benutzen Sie
+Platzhalter.
+@end itemize
+@item
+Benutzer von Java-JDBC:
+@itemize @bullet
+@item Benutzen Sie ein @code{PreparedStatement}-Objekt und Platzhalter.
+@end itemize
+@end itemize
+
+@item
+Übermitteln Sie keine Klartextdaten (unverschlüsselte Daten) über das
+Internet. Diese Daten sind für jeden zugänglich, der Zeit und Möglichkeit
+hat, sie abzuhören und sie für die eigenen Zwecke zu benutzen. Benutzen Sie
+statt dessen ein verschlüsseltes Protokoll wie SSL oder SSH. MySQL
+unterstützt ab Version 4.0.0 interne SSL-Verbindungen.
+SSH-Port-Forwarding kann benutzt werden, um einen verschlüsselten (und
+komprimierten) Kommunikationstunnel zu erzeugen.
+@item
+Lernen Sie die Benutzung der @code{tcpdump}- und @code{strings}-Utilities.
+In den meisten Fällen können Sie mit einem Befehl wie dem folgenden
+feststellen, ob MySQL-Datenströme verschlüsselt sind oder nicht:
+
+@example
+shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
+@end example
+
+(Das funktioniert unter Linux und sollte mit kleineren Änderungen auf
+anderen Systemen funktionieren.) Achtung: Wenn Sie keine Daten sehen,
+heißt das nicht immer, dass sie verschlüsselt sind. Wenn Sie hohe
+Sicherheit benötigen, sollten Sie sich mit einem Sicherheitsexperten in
+Verbindung setzen.
+@end itemize
+
+
+@node Security, Privileges options, General security, Privilege system
+@c German node Sicherheit
+@subsection Wie Sie MySQL gegen Cracker sicher machen
+
+@cindex Cracker, Sicherheit gegen
+@cindex Sicherheit, gegen Cracker
+
+Wenn Sie sich mit einem MySQL-Server verbinden, sollten Sie normalerweise
+ein Passwort benutzen. Das Passwort wird nicht als Klartext über die
+Verbindung übermittelt. Allerdings ist der Verschlüsselungsalgorithmus
+nicht sehr stark, so dass ein cleverer Angreifer mit einiger Mühe das
+Passwort knacken kann, wenn er in der Lage ist, den Verkehr zwischen Client
+und Server abzuhören. Wenn die Verbindung zwischen Client und Server über
+ein nicht vertrauenswürdiges Netzwerk geht, sollten Sie einen SSH-Tunnel
+benutzen, um die Kommunikation zu verschlüsseln.
+
+Jede sonstige Information wird als Klartext übermittelt, die von jedem
+gelesen werden kann, der in der Lage ist, die Verbindung abzuhören. Wenn
+Sie das beunruhigt, können Sie das komprimierte Protokoll benutzen (ab
+MySQL-Version 3.22), um so etwas zu erschweren. Um die Dinge noch sicherer
+zu machen, sollten Sie @code{ssh} benutzen. Sie finden einen Open-Source-
+@code{ssh}-Client auf @uref{http://www.openssh.org} und einen kommerziellen
+@code{ssh}-Client auf @uref{http://www.ssh.com}. Mit diesen erhalten Sie
+eine verschlüsselte TCP/IP-Verbindung zwischen einem MySQL-Server und einem
+MySQL-Client.
+
+Um ein MySQL-System sicher zu machen, sollten Sie auf jeden Fall folgende
+Vorschläge in Betracht ziehen:
+
+@itemize @bullet
+@item
+Benutzen Sie Passwörter für alle MySQL-Benutzer. Bedenken Sie, dass sich
+jeder beliebige als andere Person einloggen kann, und zwar so einfach wie
+@code{mysql -u anderer_benutzer db_name}, wenn @code{anderer_benutzer} kein
+Passwort hat. Es ist ein normales Verhalten bei
+Client-Server-Applikationen, dass der Client einen beliebigen Benutzernamen
+angeben kann. Sie können das Passwort für alle Benutzer ändern, indem Sie
+das @code{mysql_install_db}-Skript editieren, bevor Sie es laufen lassen,
+oder nur das Passwort für den MySQL-@code{root}-Benutzer, wie folgt:
+
+@example
+shell> mysql -u root mysql
+mysql> UPDATE user SET Password=PASSWORD('neues_passwort')
+ WHERE user='root';
+mysql> FLUSH PRIVILEGES;
+@end example
+
+@item
+Lassen Sie den MySQL-Daemon nicht als Unix-@code{root}-Benutzer laufen. Das
+ist sehr gefährlich, denn jeder Benutzer mit @code{FILE}-Berechtigung ist
+dann in der Lage, Dateien als @code{root} zu erzeugen (zum Beispiel
+@code{~root/.bashrc}). Um das zu verhindern, weigert sich @code{mysqld},
+als @code{root} zu laufen, es sei denn, das wird direkt durch die
+@code{--user=root}-Option angegeben.
+
+@code{mysqld} kann unter einem gewöhnlichen Benutzer ohne besondere Rechte
+laufen. Sie können auch einen neuen Unix-Benutzer @code{mysql} anlegen, um
+alles noch sicherer zu machen. Wenn Sie @code{mysqld} als ein anderer
+Unix-Benutzer laufen lassen, müssen Sie nicht den @code{root}-Benutzernamen
+in der @code{user}-Tabelle ändern, denn MySQL-Benutzernamen haben nichts
+mit den Unix-Benutzernamen zu tun. Um @code{mysqld} als anderer
+Unix-Benutzer zu starten, fügen Sie eine @code{user}-Zeile hinzu, die den
+Benutzernamen zur @code{[mysqld]}-Gruppe der
+@file{/etc/my.cnf}-Optionsdatei oder der @file{my.cnf}-Optionsdatei im
+Daten-Verzeichnis des Servers hinzufügt. Beispiel:
+
+@example
+[mysqld]
+user=mysql
+@end example
+
+Das bewirkt, dass der Server als der festgelegte Benutzer gestartet wird,
+egal ob Sie ihn manuell oder mit @code{safe_mysqld} oder
+@code{mysql.server} starten. Weitere Details finden Sie unter @ref{Privilege changes, , MySQL-Benutzer ändern}.
+
+@item
+Unterstützen Sie keine Symlinks auf Tabellen (das kann mit der
+@code{--skip-symlink}-Option abgeschaltet werden). Das ist insbesondere
+wichtig, wenn Sie @code{mysqld} als Root laufen lassen, weil jeder, der
+Schreibzugriff auf das mysqld-Daten-Verzeichnis hat, dann jede Datei im
+System zerstören könnte!
+@xref{Symbolic links to tables}.
+
+@item
+Überprüfen Sie, dass der Unix-Benutzer, der @code{mysqld} laufen läßt, der
+einzige Benutzer mit Lese-/Schreibzugriffen auf die Datenbankverzeichnisse
+ist.
+
+@item
+Geben Sie nicht allen Benutzern das @strong{process}-Zugriffsrecht. Die
+Ausgabe von @code{mysqladmin processlist} zeigt den Text der aktuell
+ausgeführten Anfragen, so dass jeder, der diesen Befehl ausführen darf, in
+der Lage wäre, eine Anfrage eines anderen Benutzers wie @code{UPDATE user
+SET password=PASSWORD('not_secure')} einzusehen.
+
+@code{mysqld} reserviert eine zusätzliche Verbindung für Benutzer, die das
+@strong{process}-Zugriffsrecht haben, so dass sich ein
+MySQL-@code{root}-Benutzer einloggen und Dinge überprüfen kann, selbst wenn
+alle normalen Verbindungen in Benutzung sind.
+
+@item
+Geben Sie nicht allen Benutzern das @strong{file}-Zugriffsrecht. Jeder
+Benutzer, der dieses Zugriffsrecht hat, kann irgendwo im Dateisystem
+Dateien mit den Rechten des the @code{mysqld}-Daemons schreiben! Um das
+etwas sicherer zu machen, sind alle Dateien, die mit @code{SELECT ... INTO
+OUTFILE} erzeugt werden, für jeden lesbar und können keine existierenden
+Dateien überschreiben.
+
+@tindex /etc/passwd
+Das @strong{file}-Zugriffsrecht kann auch benutzt werden, um jede Datei zu
+lesen, auf die der Unix-Benutzer Zugriff hat, als der der Server läuft. Das
+könnte zum Beispiel durch Benutzung von @code{LOAD DATA} missbraucht
+werden, um @file{/etc/passwd} in eine Tabelle zu laden, die anschließend
+mit @code{SELECT} gelesen wird.
+
+@item
+Wenn Sie Ihrem DNS nicht trauen, sollten Sie IP-Nummern anstelle von
+Hostnamen in den Berechtigungstabellen verwenden. In jedem Fall sollten Sie
+sehr vorsichtig damit sein, Einträge in Berechtigungstabellen vorzunehmen,
+die Hostnamen mit Platzhaltern (Wildcards) verwenden!
+
+@item
+Wenn Sie die Anzahl der Verbindungen für einen einzelnen Benutzer
+beschränken wollen, können Sie das tun, indem Sie die
+@code{max_user_Verbindungen}-Variable in @code{mysqld} setzen.
+@end itemize
+
+
+
+@node Privileges options, What Privileges, Security, Privilege system
+@c German node Berechtigungsoptionen
+@subsection Startoptionen für @code{mysqld} in Bezug auf Sicherheit
+
+Folgende @code{mysqld}-Optionen berühren Sicherheitsaspekte:
+
+@table @code
+@item --safe-show-database
+Mit dieser Option gibt @code{SHOW DATABASES} nur die Datenbanken zurück,
+für die der Benutzer irgend welche Rechte hat.
+
+@item --safe-user-create
+Wenn das angeschaltet ist, kann ein Benutzer keine neuen Benutzer mit dem
+@code{GRANT}-Befehl anlegen, wenn der kein @code{INSERT}-Zugriffsrecht auf
+die @code{mysql.user}-Tabelle hat. Wenn Sie dem Benutzer nur das Recht
+geben wollen, neue Benutzer mit den Berechtigungen anzulegen, die er
+vergeben darf, sollten Sie ihm folgende Berechtigung geben:
+
+@example
+GRANT INSERT(benutzer) on mysql.user to 'benutzer'@'hostname';
+@end example
+
+Das stellt sicher, dass der Benutzer keine Berechtigungsspalten direkt
+ändern kann, sondern dafür den @code{GRANT}-Befehl benutzen muss.
+
+@item --skip-grant-tables
+Diese Option veranlasst den Server, das Berechtigungssystem überhaupt nicht
+zu benutzen. Das gibt jedem @emph{vollen Zugriff} auf alle Datenbanken!
+(Einen laufenden Server können Sie veranlassen, die Berechtigungstabellen
+erneut zu verwenden, indem Sie @code{mysqladmin flush-privileges} oder
+@code{mysqladmin reload} ausführen.)
+
+@item --skip-name-resolve
+Hostnamen werden nicht aufgelöst. Alle @code{Host}-Spaltenwerte in den
+Berechtigungstabellen müssen IP-Nummern oder @code{localhost} sein.
+
+@item --skip-networking
+Keine TCP/IP-Verbindungen über das Netzwerk zulassen. Alle Verbindungen zu
+@code{mysqld} müssen über Unix-Sockets gemacht werden. Diese Option ist
+ungeeignet für Systeme, die MIT-pThreads benutzen, weil das
+MIT-pThreads-Paket keine Unix-Sockets unterstützt.
+
+@item --skip-show-database
+Mit dieser Option gibt das @code{SHOW DATABASES}-Statement nichts zurück.
+
+@end table
+
+
+@node What Privileges, Privileges, Privileges options, Privilege system
+@c German node Welche Berechtigungen
+@subsection Was das Berechtigungssystem macht
+
+@cindex System, Berechtigungen
+@cindex Berechtigungssystem
+@cindex Passwörter, Sicherheit
+
+Die primäre Funktion des MySQL-Berechtigungssystem ist, einen Benutzer zu
+authentifizieren, der sich von einem gegebenen Host aus verbindet, und
+diesen Benutzer Berechtigungen auf eine Datenbank zuzuordnen, wie
+@strong{select}, @strong{insert}, @strong{update} und @strong{delete}.
+
+Zusätzliche Funktionalität beinhaltet die Möglichkeit, einen anonymen
+Benutzer anzulegen und Berechtigungen für MySQL-spezifische Funktionen wie
+@code{LOAD DATA INFILE} und für administrative Operationen zu gewähren.
+
+
+@node Privileges, Privileges provided, What Privileges, Privilege system
+@c German node Berechtigungen
+@subsection Wie das Berechtigungssystem funktioniert
+
+@cindex Berechtigungssystem, Beschreibung
+
+Das MySQL-Berechtigungssystem stellt sicher, dass alle Benutzer nur genau
+die Dinge tun dürfen, zu denen sie berechtigt sind. Wenn Sie sich mit einem
+MySQL-Server verbinden, wird Ihre Identität @strong{durch den Host, von dem
+Sie sich aus verbinden,} festgelegt und @strong{durch den Benutzernamen,
+den Sie angeben}. Das System gewährt Berechtigungen gemäß Ihrer Identität
+und gemäß dem, @strong{was Sie tun wollen}.
+
+MySQL zieht sowohl Hostnamen als auch Benutzernamen heran, um Sie zu
+identifizieren, weil es kaum Grund gibt anzunehmen, dass ein gegebener
+Benutzername derselben Person woanders auf dem Internet gehört. So muss zum
+Beispiel der Benutzer @code{bill}, der sich von @code{whitehouse.gov} aus
+verbindet, nicht notwendigerweise dieselbe Person sein, die sich als
+Benutzer @code{bill} von @code{microsoft.com} aus verbindet.
+MySQL erlaubt Ihnen deshalb, Benutzer auf unterschiedlichen Hosts
+auseinander zu halten, die zufällig denselben Namen haben: Sie können
+@code{bill} einen Satz von Berechtigungen für Verbindungen von
+@code{whitehouse.gov} und einen anderen Satz von Berechtigungen für
+Verbindungen von @code{microsoft.com} aus gewähren.
+
+Die MySQL-Zugriffskontrolle läuft in zwei Phasen ab:
+
+@itemize @bullet
+@item
+Phase 1: Der Server überprüft, ob Sie das Recht haben, sich verbinden zu
+können.
+
+@item
+Phase 2: Angenommen, Sie haben das Recht, sich zu verbinden, dann überprüft
+der Server jede Anfrage, die Sie absetzen, um festzustellen, ob Sie
+ausreichende Rechte haben, um diese auszuführen. Wenn Sie zum Beispiel
+Zeilen aus einer Tabellen in einer Datenbank auswählen oder eine Tabelle in
+einer Datenbank löschen, stellt der Server sicher, dass Sie die
+@strong{select}-Berechtigung für die Tabelle bzw. die
+@strong{drop}-Berechtigung für die Datenbank haben.
+@end itemize
+
+Der Server benutzt die @code{user}-, @code{db}- und @code{host}-Tabellen in
+der @code{mysql}-Datenbank in beiden Phasen der Zugriffskontrolle. Die
+Felder in diesen Berechtigungstabellen sind unten dargestellt:
+
+@multitable @columnfractions .2 .25 .25 .25
+@item @strong{Tabellenname} @tab @code{user} @tab @code{db} @tab @code{host}
+
+@item @strong{Geltungsbereichs-Felder} @tab @code{Host} @tab @code{Host} @tab @code{Host}
+@item @tab @code{User} @tab @code{Db} @tab @code{Db}
+@item @tab @code{Password} @tab @code{User} @tab
+
+@item @strong{Berechtigungs-Felder} @tab @code{Select_priv} @tab @code{Select_priv} @tab @code{Select_priv}
+@item @tab @code{Insert_priv} @tab @code{Insert_priv} @tab @code{Insert_priv}
+@item @tab @code{Update_priv} @tab @code{Update_priv} @tab @code{Update_priv}
+@item @tab @code{Delete_priv} @tab @code{Delete_priv} @tab @code{Delete_priv}
+@item @tab @code{Index_priv} @tab @code{Index_priv} @tab @code{Index_priv}
+@item @tab @code{Alter_priv} @tab @code{Alter_priv} @tab @code{Alter_priv}
+@item @tab @code{Create_priv} @tab @code{Create_priv} @tab @code{Create_priv}
+@item @tab @code{Drop_priv} @tab @code{Drop_priv} @tab @code{Drop_priv}
+@item @tab @code{Grant_priv} @tab @code{Grant_priv} @tab @code{Grant_priv}
+@item @tab @code{References_priv} @tab @tab
+@item @tab @code{Reload_priv} @tab @tab
+@item @tab @code{Shutdown_priv} @tab @tab
+@item @tab @code{Process_priv} @tab @tab
+@item @tab @code{File_priv} @tab @tab
+@end multitable
+
+In der zweiten Phase der Zugriffskontrolle (Anfrage-Verifikation), zieht
+der Server gegebenenfalls zusätzlich die @code{tables_priv}- und
+@code{columns_priv}-Tabellen heran, falls Ihre Anfrage Tabellen betrifft.
+Die Felder in diesen Tabellen sind unten dargestellt:
+
+@multitable @columnfractions .2 .25 .25
+@item @strong{Tabellenname} @tab @code{tables_priv} @tab @code{columns_priv}
+
+@item @strong{Geltungsbereichs-Felder} @tab @code{Host} @tab @code{Host}
+@item @tab @code{Db} @tab @code{Db}
+@item @tab @code{User} @tab @code{User}
+@item @tab @code{Table_name} @tab @code{Table_name}
+@item @tab @tab @code{Column_name}
+
+@item @strong{Berechtigungs-Felder} @tab @code{Table_priv} @tab @code{Column_priv}
+@item @tab @code{Column_priv} @tab
+
+@item @strong{Sonstige Felder} @tab @code{Timestamp} @tab @code{Timestamp}
+@item @tab @code{Grantor} @tab
+@end multitable
+
+Jede Berechtigungstabelle enthält Geltungsbereichsfelder und
+Berechtigungsfelder.
+
+Geltungsbereichsfelder legen den Geltungsbereich jedes Eintrags in den
+Tabellen fest, das heißt, der Kontext, für den der Eintrag gilt. So würde
+zum Beispiel ein @code{user}-Tabelleneintrag mit @code{Host}- und
+@code{User}-Werten von @code{'thomas.loc.gov'} und @code{'bob'} benutzt
+werden, um Verbindungen zum Server zu authentifizieren, die von @code{bob}
+vom Host @code{thomas.loc.gov} gemacht werden. In ähnlicher Weise bewirkt
+ein @code{db}-Tabelleneintrag in die Felder @code{Host}, @code{User} und
+@code{Db} mit @code{'thomas.loc.gov'}, @code{'bob'} und @code{'reports'},
+dass diese benutzt werden, wenn sich @code{bob} vom Host
+@code{thomas.loc.gov} verbindet und auf die @code{reports}-Datenbank zugreift.
+Die @code{tables_priv}- und @code{columns_priv}-Tabellen enthalten
+Geltungsbereichsfelder, die Tabellen oder Tabellen-Spalten-Kombinationen
+angeben, auf die sich der jeweilige Eintrag bezieht.
+
+@cindex Groß-/Kleinschreibung, bei der Zugriffsprüfung
+Für Zwecke der Zugriffsprüfung sind Vergleiche von @code{Host}-Werten
+unabhängig von der verwendeten Groß-/Kleinschreibung. @code{User},
+@code{Password}, @code{Db} und @code{Table_name}-Werte sind abhängig von
+der verwendeten Groß-/Kleinschreibung. @code{Column_name}-Werte sind ab
+MySQL-Version 3.22.12 unabhängig von der verwendeten
+Groß-/Kleinschreibung.
+
+Berechtigungsfelder zeigen die Berechtigungen an, die durch den
+Tabelleneintrag gewährt werden, das heißt, welche Operationen durchgeführt
+werden können. Der Server kombiniert die Informationen in den verschiedenen
+Berechtigungstabellen, um daraus eine komplette Beschreibung der
+Berechtigungen des Benutzers zu formulieren. Die Regeln, nach denen hierbei
+vorgegangen wird, sind in @ref{Request access} beschrieben.
+
+Geltungsbereichsfelder sind Zeichenketten, die wie unten dargestellt
+deklariert werden. Der Vorgabewert für jedes Feld ist die leere
+Zeichenkette:
+
+@multitable @columnfractions .15 .15 .7
+@item @strong{Feldname} @tab @strong{Typ}
+@item @code{Host} @tab @code{CHAR(60)}
+@item @code{User} @tab @code{CHAR(16)}
+@item @code{Password} @tab @code{CHAR(16)}
+@item @code{Db} @tab @code{CHAR(64)} @tab (@code{CHAR(60)} für
+die @code{tables_priv}- und @code{columns_priv}-Tabellen)
+@item @code{Table_name} @tab @code{CHAR(60)}
+@item @code{Column_name} @tab @code{CHAR(60)}
+@end multitable
+
+In den @code{user}-, @code{db}- und @code{host}-Tabellen werden alle Felder
+als @code{ENUM('N','Y')} deklariert. Jedes Feld kann einen Wert von
+@code{'N'} oder @code{'Y'} haben. Der Vorgabewert ist @code{'N'}.
+
+In den @code{tables_priv}- und @code{columns_priv}-Tabellen werden Felder
+als @code{SET}-Felder deklariert:
+
+@multitable @columnfractions .2 .2 .6
+@item @strong{Tabellenname} @tab @strong{Feldname} @tab @strong{Mögliche Set-Elemente}
+@item @code{tables_priv} @tab @code{Table_priv} @tab @code{'Select', 'Insert',
+'Update', 'Delete', 'Create', 'Drop', 'Grant', 'Referenzs', 'Index', 'Alter'}
+@item @code{tables_priv} @tab @code{Column_priv} @tab @code{'Select', 'Insert',
+'Update', 'References'}
+@item @code{columns_priv} @tab @code{Column_priv} @tab @code{'Select', 'Insert',
+'Update', 'References'}
+@end multitable
+
+Kurz gesagt benutzt der Server die Berechtigungstabellen wie folgt:
+
+@itemize @bullet
+@item
+Das @code{user}-Tabellenbereichsfeld legt fest, ob eingehende Verbindungen
+zugelassen oder abgewiesen werden. Bei zugelassenen Verbindungen zeigen
+Berechtigungen, die in der @code{user}-Tabelle vergeben sind, die globalen
+(Superuser-) Rechte des Benutzers an. Diese Berechtigungen treffen auf
+@strong{alle} Datenbanken auf dem Server zu.
+
+@item
+Die @code{db}- und @code{host}-Tabellen werden zusammen benutzt:
+
+@itemize @minus
+@item
+Die Geltungsbereichsfelder der @code{db}-Tabelle legen fest, welche
+Benutzer auf welche Datenbanken von welchen Hosts aus zugreifen können. Die
+Berechtigungsfelder legen fest, welche Operationen zugelassen sind.
+
+@item
+Die @code{host}-Tabelle wird als Erweiterung der @code{db}-Tabelle benutzt,
+wenn Sie wollen, dass ein gegebener @code{db}-Tabelleneintrag auf
+verschiedene Hosts zutrifft. Wenn Sie zum Beispiel wollen, dass ein
+Benutzer eine Datenbank von mehreren Hosts in Ihrem Netzwerk aus benutzen
+kann, lassen Sie den @code{Host}-Wert in der @code{db}-Tabelle des
+Benutzers leer, und füllen dann die @code{host}-Tabelle mit einem Eintrag
+für jeden dieser Hosts. Dieser Mechanismus ist ausführlicher in
+@ref{Request access} beschrieben.
+@end itemize
+
+@item
+Die @code{tables_priv}- und @code{columns_priv}-Tabellen sind der
+@code{db}-Tabelle ähnlich, aber feinkörniger: Sie beziehen sich auf
+Tabellen- und Spaltenebenen und nicht auf Datenbankebene.
+@end itemize
+
+Beachten Sie, dass die Verwaltungsberechtigungen (@strong{reload},
+@strong{shutdown} usw.) nur in der @code{user}-Tabelle festgelegt werden.
+Das liegt daran, dass Verwaltungsoperationen Operationen auf dem Server
+selbst sind und nicht Datenbank-spezifisch, so dass es keinen Grund gibt,
+solche Berechtigungen in den anderen Berechtigungstabellen aufzuführen. So
+muss nur die @code{user}-Tabelle untersucht werden um festzustellen, ob man
+Verwaltungsoperationen durchführen kann oder nicht.
+
+Das @strong{file}-Zugriffsrecht wird auch nur in der @code{user}-Tabelle
+festgelegt. Es ist als solches keine Verwaltungsberechtigung, aber Ihre
+Möglichkeit, Dateien auf dem Server zu lesen oder zu schreiben, ist
+unabhängig von der Datenbank, auf die Sie zugreifen.
+
+Der @code{mysqld}-Server liest die Inhalte der Berechtigungstabellen
+einmal, und zwar beim Start. Änderungen in den Berechtigungstabellen werden
+wirksam wie in @ref{Privilege changes} geschildert.
+
+Wenn Sie die Inhalte der Berechtigungstabellen ändern, sollten Sie
+sicherstellen, dass Ihre Änderungen Berechtigungen einführen, die Sie so
+haben wollen. Hilfe bei der Diagnose von Problemen finden Sie unter
+@ref{Access denied}. Hinweise zu Sicherheitsthemen finden Sie unter
+@pxref{Security}.
+
+Ein nützliches Diagnosetool ist das @code{mysqlaccess}-Skript, das Yves
+Carlier für die MySQL-Distribution bereit gestellt hat. Rufen Sie
+@code{mysqlaccess} mit der @code{--help}-Option auf, um herauszufinden, wie
+es funktioniert. Beachten Sie, dass @code{mysqlaccess} den Zugriff nur
+anhand der @code{user}-, @code{db}- und @code{host}-Tabellen überprüft. Es
+überprüft keine Tabellen- oder Spaltenebenen-Berechtigungen.
+
+
+@node Privileges provided, Connecting, Privileges, Privilege system
+@c German node Zur Verfügung gestellte Berechtigungen
+@subsection Von MySQL zur Verfügung gestellte Berechtigungen
+
+@cindex Berechtigungsinformation, Speicherort
+
+Informationen über Benutzerberechtigungen sind in den @code{user}-,
+@code{db}-, @code{host}-, @code{tables_priv}- und
+@code{columns_priv}-Tabellen in der @code{mysql}-Datenbank gespeichert (das
+heißt in der Datenbank, die @code{mysql} heißt). Der MySQL-Server liest
+die Inhalte dieser Tabellen, wenn er startet, und in den Fällen, die unter
+@ref{Privilege changes} geschildert sind.
+
+Die Namen, die in diesem Handbuch benutzt werden, um auf die Berechtigungen
+zu verweisen, die MySQL zur Verfügung stellt, sind unten dargestellt,
+zusammen mit den Tabellenspaltennamen, die jeder Berechtigung in the
+Berechtigungstabellen zugeordnet sind, und dem Kontext, auf den die
+Berechtigung zutrifft.
+
+@multitable @columnfractions .15 .25 .6
+@item @strong{Berechtigung} @tab @strong{Spalte} @tab @strong{Kontext}
+@item @strong{select} @tab @code{Select_priv} @tab Tabellen
+@item @strong{insert} @tab @code{Insert_priv} @tab Tabellen
+@item @strong{update} @tab @code{Update_priv} @tab Tabellen
+@item @strong{delete} @tab @code{Delete_priv} @tab Tabellen
+@item @strong{index} @tab @code{Index_priv} @tab Tabellen
+@item @strong{alter} @tab @code{Alter_priv} @tab Tabellen
+@item @strong{create} @tab @code{Create_priv} @tab Datenbanken, Tabellen oder Indexe
+@item @strong{drop} @tab @code{Drop_priv} @tab Datenbanken oder Tabellen
+@item @strong{grant} @tab @code{Grant_priv} @tab Datenbanken oder Tabellen
+@item @strong{References} @tab @code{References_priv} @tab Datenbanken oder Tabellen
+@item @strong{reload} @tab @code{Reload_priv} @tab Serververwaltung
+@item @strong{shutdown} @tab @code{Shutdown_priv} @tab Serververwaltung
+@item @strong{process} @tab @code{Process_priv} @tab Serververwaltung
+@item @strong{file} @tab @code{File_priv} @tab Dateizugriff auf den Server
+@end multitable
+
+Die @strong{select}-, @strong{insert}-, @strong{update}- und
+@strong{delete}-Berechtigungen erlauben Ihnen, Operationen auf Zeilen in
+existierenden Tabellen in einer Datenbank durchzuführen.
+
+@code{SELECT}-Statements erfordern die @strong{select}-Berechtigung nur
+dann, wenn tatsächlich Zeilen aus einer Tabelle abgerufen werden. Sie
+können bestimmte @code{SELECT}-Statements selbst ohne Berechtigung
+durchführen, um auf jede der Datenbanken auf dem Server zuzugreifen.
+Beispielsweise könnten Sie den @code{mysql}-Client als einfachen
+Taschenrechner benutzen:
+
+@example
+mysql> SELECT 1+1;
+mysql> SELECT PI()*2;
+@end example
+
+Die @strong{index}-Berechtigung erlaubt Ihnen, Indexe zu erzeugen oder zu
+entfernen.
+
+Die @strong{alter}-Berechtigung erlaubt Ihnen, @code{ALTER TABLE} zu
+benutzen.
+
+Die @strong{create}- und @strong{drop}-Berechtigungen erlauben Ihnen, neue
+Datenbanken und Tabellen zu erzeugen oder bestehende Datenbanken und
+Tabellen zu entfernen.
+
+Denken Sie daran, dass ein Benutzer, dem Sie die @strong{drop}-Berechtigung
+für die @code{mysql}-Datenbank gewähren, in der Lage ist, die Datenbank zu
+löschen, in der die MySQL-Zugriffsberechtigungen gespeichert sind!
+
+Die @strong{grant}-Berechtigung erlaubt Ihnen, die Berechtigungen, die Sie
+selbst besitzen, an andere Benutzer zu vergeben.
+
+Die @strong{file}-Berechtigung erlaubt Ihnen, Dateien auf dem Server zu
+lesen und zu schreiben, wenn Sie die @code{LOAD DATA INFILE}- und
+@code{SELECT ... INTO OUTFILE}-Statements benutzen. Jeder Benutzer, dem
+diese Berechtigung gewährt wurde, kann jedwede Datei lesen oder schreiben,
+die der MySQL-Server lesen oder schreiben darf.
+
+Die restlichen Berechtigungen werden für Verwaltungsoperationen benutzt,
+die mit dem @code{mysqladmin}-Programm durchgeführt werden. Die unten
+stehende Tabelle zeigt, welche @code{mysqladmin}-Befehle mit jeder
+Verwaltungsberechtigung ausgeführt werden können:
+
+@multitable @columnfractions .15 .85
+@item @strong{Berechtigung} @tab @strong{Befehle, die dem Berechtigten erlaubt sind}
+@item @strong{reload} @tab @code{reload}, @code{refresh},
+@code{flush-privileges}, @code{flush-hosts}, @code{flush-logs} und
+@code{flush-tables}
+@item @strong{shutdown} @tab @code{shutdown}
+@item @strong{process} @tab @code{processlist}, @code{kill}
+@end multitable
+
+Der @code{reload}-Befehl weist den Server an, die Berechtigungstabellen neu
+einzulesen. Der @code{refresh}-Befehl schreibt alle Tabellen auf Platte
+(flush) und öffnet und schließt die Log-Dateien. @code{flush-privileges}
+ist ein Synonym für @code{reload}. Die anderen @code{flush-*}-Befehle
+führen Funktionen aus, die @code{refresh} ähnlich sind, aber im Umfang
+beschränkter und daher in einigen Fällen zu bevorzugen. Wenn Sie zum
+Beispiel nur die Log-Dateien flushen wollen, ist @code{flush-logs}
+@code{refresh} vorzuziehen.
+
+Der @code{shutdown}-Befehl fährt den Server herunter.
+
+Der @code{processlist}-Befehl zeigt Informationen über die Threads an, die
+im Server ausgeführt werden. Der @code{kill}-Befehl killt Server-Threads.
+Ihre eigenen Threads können Sie jederzeit anzeigen oder killen, aber Sie
+brauchen die @strong{process}-Berechtigung, um Threads anzuzeigen oder zu
+killen, die von anderen Benutzern initiiert wurden. @xref{KILL}.
+
+Es ist generell eine gute Idee, Berechtigungen nur den Nutzern zu gewähren,
+die diese tatsächlich brauchen, aber speziell bei folgenden Berechtigungen
+sollten Sie besondere Vorsicht walten lassen:
+
+@itemize @bullet
+@item
+Die @strong{grant}-Berechtigung erlaubt Benutzern, Ihre Berechtigungen an
+andere Benutzer zu übertragen. Zwei Benutzer mit unterschiedlichen
+Berechtigungen und mit der @strong{grant}-Berechtigung sind in der Lage,
+Ihre Berechtigungen zu kombinieren.
+
+@item
+Die @strong{alter}-Berechtigung kann benutzt werden, um das
+Berechtigungssystem zu unterlaufen, indem Tabellen umbenannt werden.
+
+@item
+Die @strong{file}-Berechtigung kann missbraucht werden, um jede öffentlich
+lesbare Datei auf dem Server in eine Datenbanktabelle einzulesen, auf deren
+Inhalte dann mit @code{SELECT} zugegriffen werden kann. Das beinhaltet die
+Inhalte aller Datenbanken, die vom Server gehostet werden!
+
+@item
+Die @strong{shutdown}-Berechtigung kann missbraucht werden, um andere
+Benutzer komplett vom Server auszuschließen, indem der Server beendet
+wird.
+
+@item
+Die @strong{process}-Berechtigung kann benutzt werden, um den Klartext von
+momentan ablaufenden Anfragen einzusehen, inklusive Anfragen, die
+Passwörter setzen oder ändern.
+
+@item
+Zugriffsrechte auf die @code{mysql}-Datenbank können benutzt werden, um
+Passwörter zu ändern und auf sonstige Berechtigungsinformationen
+zuzugreifen. (Passwörter werden verschlüsselt gespeichert, daher kann ein
+böswilliger Benutzer sie nicht einfach lesen und anschließend die
+Klartext-Passwörter kennen.) Wenn man auf die
+@code{mysql.user}-Passwort-Spalte zugreifen kann, kann man das nutzen, um
+sich als beliebiger Benutzer am MySQL-Server anzumelden. (Mit ausreichenden
+Rechten kann derselbe Benutzer dann Passwörter durch eigene ersetzen.)
+@end itemize
+
+Es gibt einige Dinge, die Sie mit dem MySQL-Berechtigungssystem nicht tun
+können:
+
+@itemize @bullet
+@item
+Sie können nicht ausdrücklich festlegen, dass ein bestimmter Benutzer
+keinen Zugriff haben soll. Das heißt, Sie können nicht explizit mit einem
+bestimmten Benutzer vergleichen und dann die Verbindung ablehnen.
+
+@item
+Sie können nicht festlegen, dass ein Benutzer das Recht hat, Tabellen in
+einer Datenbank zu erzeugen oder zu löschen, aber nicht die Datenbank
+selbst zu erzeugen oder zu löschen.
+@end itemize
+
+
+@node Connecting, Connection access, Privileges provided, Privilege system
+@c German node Verbinden
+@subsection Verbinden mit dem MySQL-Server
+
+@cindex Verbinden, mit dem MySQL-Server
+@cindex Vorgabemäßiger Hostname
+@cindex Hostname, Vorgabe
+@cindex Server, verbinden
+
+MySQL-Client-Programme erfordern im Allgemeinen, dass Sie
+Verbindungsparameter festlegen, wenn Sie sich mit einem MySQL-Server
+verbinden wollen: Der Host, mit dem Sie sich verbinden wollen, Ihr
+Benutzername und Ihr Passwort. Beispielsweise kann der @code{mysql}-Client
+wie folgt gestartet werden (optionale Argumente sind in @samp{[} und
+@samp{]} eingeschlossen):
+
+@example
+shell> mysql [-h hostname] [-u benutzername] [-pihr_passwort]
+@end example
+
+Alternative Formen der @code{-h}-, @code{-u}- und @code{-p}-Optionen sind
+@code{--host=hostname}, @code{--user=benutzername} und
+@code{--password=ihr_passwort}. Beachten Sie, dass zwischen @code{-p} oder
+@code{--password=} und dem folgenden Passwort @emph{kein Leerzeichen}
+steht!
+
+@strong{ACHTUNG:} Ein Passwort auf der Kommandozeile anzugeben ist nicht
+sicher! Jeder Benutzer auf Ihrem System kann dann Ihr Passwort
+herausfinden, indem er einen Befehl wie @code{ps auxww} eingibt.
+@xref{Option files}.
+
+@code{mysql} benutzt Vorgabewerte für Verbindungsparameter, die auf der
+Kommandozeile nicht angegeben sind:
+
+@itemize @bullet
+@item
+Der vorgabemäßige Hostname ist @code{localhost}.
+
+@item
+Der vorgabemäßige Benutzername ist Ihr Unix-Loginname.
+
+@item
+Es wird kein Passwort übergeben, wenn @code{-p} fehlt.
+@end itemize
+
+Für einen Unix-Benutzer @code{joe} sind daher folgende Befehle
+gleichbedeutend:
+
+@example
+shell> mysql -h localhost -u joe
+shell> mysql -h localhost
+shell> mysql -u joe
+shell> mysql
+@end example
+
+Andere MySQL-Clients verhalten sich ähnlich.
+
+Auf Unix-Systemen können Sie andere Vorgabewerte festlegen, die benutzt
+werden, wenn Sie eine Verbindung aufmachen, so dass Sie diese nicht jedes
+Mal auf der Kommandozeile eingeben müssen, wenn Sie ein Client-Programm
+aufrufen. Das kann auf verschiedene Weise gemacht werden:
+
+@itemize @bullet
+@item
+@tindex .my.cnf-Datei
+Sie können Verbindungsparameter im @code{[client]}-Abschnitt der
+@file{.my.cnf}-Konfigurationsdatei in Ihrem Heimatverzeichnis festlegen.
+Der relevante Abschnitt der Datei sieht etwa wie folgt aus:
+
+@example
+[client]
+host=hostname
+user=benutzername
+password=ihr_passwort
+@end example
+
+@xref{Option files}.
+
+@item
+@tindex @code{MYSQL_HOST}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_HOST}
+@tindex @code{MYSQL_PWD}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_PWD}
+@tindex @code{USER}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{USER}
+Sie können Verbindungsparameter festlegen, indem Sie Umgebungsvariablen
+benutzen. Der Host kann für @code{mysql} festgelegt werden, indem
+@code{MYSQL_HOST} benutzt wird. Der MySQL-Benutzername kann mit @code{USER}
+festgelegt werden (nur für Windows). Das Passwort kann mit @code{MYSQL_PWD}
+festgelegt werden (aber das ist unsicher, siehe nächster Abschnitt).
+@xref{Environment variables}.
+@end itemize
+
+
+@node Connection access, Request access, Connecting, Privilege system
+@c German node Verbindungszugriff
+@subsection Zugriffskontrolle, Phase 1: Verbindungsüberprüfung
+
+@cindex Zugriffskontrolle
+@cindex Kontrolle über den Zugriff
+@cindex Verbindung, Überprüfung
+@cindex Testen, Verbindung mit dem Server
+
+Wenn Sie versuchen, sich mit einem MySQL-Server zu verbinden, akzeptiert
+der Server die Verbindung oder weist sie zurück, abhängig von Ihrer
+Identität und davon, ob Sie diese mit dem korrekten Passwort verifizieren
+können. Falls nicht, lehnt der Server den Zugriff vollständig ab. Ansonsten
+akzeptiert der Server die Verbindung, geht dann in Phase 2 und wartet auf
+Anfragen.
+
+Ihre Identität basiert auf zwei Informationsbestandteilen:
+
+@itemize @bullet
+@item
+Dem Host, von dem Sie sich verbinden
+
+@item
+Ihrem MySQL-Benutzernamen
+@end itemize
+
+Die Identitätsüberprüfung wird anhand der drei Geltungsbereichs-Felder der
+@code{user}-Tabelle, nämlich (@code{Host}, @code{User} und @code{Password})
+durchgeführt. Der Server akzeptiert die Verbindung nur, wenn ein
+@code{user}-Tabelleneintrag mit Ihrem Hostnamen und Benutzernamen
+übereinstimmt und Sie das korrekte Passwort angeben können.
+
+Werte in den Geltungsbereichs-Feldern der @code{user}-Tabelle können wie folgt
+festgelegt werden:
+
+@itemize @bullet
+@item
+Ein @code{Host}-Wert kann ein Hostname oder eine IP-Nummer sein, oder
+@code{'localhost'}, was die lokale Maschine angibt.
+
+@item
+@cindex Platzhalter (Wildcards), in der @code{mysql.user}-Tabelle
+Sie können die Platzhalterzeichen @samp{%} und @samp{_} im @code{Host}-Feld
+benutzen.
+
+@item
+Ein @code{Host}-Wert @code{'%'} stimmt mit jedem Hostnamen überein.
+
+@item
+Ein leerer @code{Host}-Wert bedeutet, dass die Berechtigung zusammen mit
+dem Eintrag in der @code{host}-Tabelle gilt, der mit dem angegebenen
+Hostnamen übereinstimmt. Weitere Informationen hierzu finden Sie im
+nächsten Kapitel.
+
+@cindex Netmask-Notation, in der @code{mysql.user}-Tabelle
+@item
+Ab MySQL-Version 3.23 können @code{Host}-Werte als IP-Nummern festgelegt
+werden, und Sie können eine Netmask festlegen, die angibt, wie viele
+Adress-Bits für die Netzwerknummer benutzt werden. Beispiel:
+
+@example
+GRANT ALL PRIVILEGES on db.* to david@@'192.58.197.0/255.255.255.0';
+@end example
+
+Das erlaubt jedem, sich von einer IP zu verbinden, bei der folgendes gilt:
+
+@example
+benutzer_ip & netmask = host_ip.
+@end example
+
+Im obigen Beispiel können sich alle IP's im Intervall zwischen 192.58.197.0
+bis 192.58.197.255 mit dem MySQL-Server verbinden.
+
+@item
+@cindex anonymer Benutzer
+Platzhalterzeichen sind im @code{User}-Feld nicht erlaubt. Sie können aber
+einen leeren Wert angeben, der mit jedem Namen übereinstimmt. Wenn der
+Eintrag in der @code{user}-Tabelle, der mit einer hereinkommenden
+Verbindung übereinstimmt, einen leeren Benutzernamen hat, wird angenommen,
+dass der Benutzer der anonyme Benutzer ist (der Benutzer ohne Namen), und
+nicht der Name, den der Client tatsächlich angegeben hat. Das bedeutet,
+dass ein leerer Benutzername für alle weiteren Zugriffsüberprüfungen
+während der laufenden Verbindung benutzt wird (also während Phase 2).
+
+@item
+Das @code{Password}-Feld kann leer sein. Das bedeutet nicht, dass jedes
+Passwort übereinstimmt, sondern dass der Benutzer sich ohne Angabe eines
+Passworts verbinden muss.
+@end itemize
+
+@findex PASSWORD()
+Nicht-leere @code{Password}-Werte repräsentieren verschlüsselte Passwörter.
+MySQL speichert Passwörter nicht im Klartext, so dass jeder sie sehen
+könnte. Statt dessen wird das Passwort eines Benutzers, der sich zu
+verbinden versucht, verschlüsselt (unter Benutzung der
+@code{PASSWORD()}-Funktion). Das verschlüsselte Passwort wird dann benutzt,
+wenn Client / Server prüfen, ob das Passwort korrekt ist (das geschieht,
+ohne dass das verschlüsselte Passwort jemals über die Verbindung übertragen
+wird). Beachten Sie, dass aus der Sicht von MySQL das verschlüsselte
+Passwort das ECHTE Passwort ist, daher sollten Sie niemandem Zugriff darauf
+geben! Insbesondere sollten Sie keinem normalen Benutzer Lesezugriff auf
+die Tabellen der @code{mysql}-Datenbank geben!
+
+Die unten stehenden Beispiele zeigen, wie unterschiedliche Kombinationen
+von @code{Host}- und-@code{User}-Werten in den
+@code{user}-Tabelleneinträgen auf hereinkommende Verbindungen zutreffen:
+
+@multitable @columnfractions .25 .15 .60
+@item @code{Host} @strong{Wert} @tab @code{User} @strong{Wert} @tab @strong{Verbindungen, die mit dem Eintrag übereinstimmen}
+@item @code{'thomas.loc.gov'} @tab @code{'fred'} @tab @code{fred}, der sich von @code{thomas.loc.gov} aus verbindet
+@item @code{'thomas.loc.gov'} @tab @code{''} @tab Jeder Benutzer, der sich von @code{thomas.loc.gov} aus verbindet
+@item @code{'%'} @tab @code{'fred'} @tab @code{fred}, der sich von jedem Host aus verbindet
+@item @code{'%'} @tab @code{''} @tab Jeder Benutzer, der sich von jedem Host aus verbindet
+@item @code{'%.loc.gov'} @tab @code{'fred'} @tab @code{fred}, der sich von jedem beliebigen Host in der @code{loc.gov}-Domäne aus verbindet
+@item @code{'x.y.%'} @tab @code{'fred'} @tab @code{fred}, der sich von @code{x.y.net}, @code{x.y.com}, @code{x.y.edu} usw. aus verbindet (wahrscheinlich eher unsinnig)
+@item @code{'144.155.166.177'} @tab @code{'fred'} @tab @code{fred}, der sich vom Host mit der IP-Adresse @code{144.155.166.177} aus verbindet
+@item @code{'144.155.166.%'} @tab @code{'fred'} @tab @code{fred}, der sich von jedem beliebigen Host im Class-C-Subnet @code{144.155.166} aus verbindet
+@item @code{'144.155.166.0/255.255.255.0'} @tab @code{'fred'} @tab Dasselbe wie im vorherigen Beispiel
+@end multitable
+
+Weil Sie im @code{Host}-Feld IP-Platzhalterwerte verwenden können
+(beispielsweise @code{'144.155.166.%'}, was mit jedem Host in einem Subnet
+übereinstimmt), besteht die Möglichkeit, dass jemand diese Fähigkeit
+ausbeutet, indem er einen Host zum Beispiel
+@code{144.155.166.somewhere.com} nennt. Um solche Versuche zu vereiteln,
+verbietet MySQL den Vergleich mit Hostnamen, die mit Ziffern und einem
+Punkt übereinstimmen. Wenn Sie daher einen Host haben, der so wie
+@code{1.2.foo.com} benannt ist, wird sein Name nie mit der
+@code{Host}-Spalte der Berechtigungstabellen übereinstimmen. Nur eine
+IP-Nummer kann mit dem IP-Platzhalterwert übereinstimmen.
+
+Eine hereinkommende Verbindung kann mit mehr als einem Eintrag in der
+@code{user}-Tabelle übereinstimmen. Beispielsweise würde eine Verbindung
+von @code{thomas.loc.gov} aus durch @code{fred} mit mehreren der oben
+genannten Einträge übereinstimmen. Wie entscheidet der Server, welcher der
+Einträge benutzt werden soll, wenn mehrere zutreffen? Der Server löst
+dieses Problem, indem er die @code{user}-Tabelle nach dem Einlesen beim
+Start sortiert, und danach die Einträge in sortierter Form durchsieht, wenn
+ein Benutzer versucht, sich zu verbinden. Der erste übereinstimmende
+Eintrag ist der, der benutzt wird.
+
+Das Sortieren der @code{user}-Tabelle funktioniert wie folgt. Nehmen Sie
+an, dass die @code{user}-Tabelle so aussieht:
+
+@example
++-----------+----------+-
+| Host | User | ...
++-----------+----------+-
+| % | root | ...
+| % | jeffrey | ...
+| localhost | root | ...
+| localhost | | ...
++-----------+----------+-
+@end example
+
+Wenn der Server die Tabelle liest, ordnet er die Einträge mit den
+spezifischsten Einträgen für die @code{Host}-Werte zuerst ein (@code{'%'}
+in der @code{Host}-Spalte bedeutet ``jeder Host'' und ist am
+unspezifischsten). Einträge mit denselben @code{Host}-Werten werden mit den
+spezifischsten @code{User}-Werten zuerst geordnet (ein leerer
+@code{User}-Wert bedeutet ``jeder Benutzer'' und ist am
+unspezifischsten). Die daraus resultierende sortierte @code{user}-Tabelle
+sieht wie folgt aus:
+
+@example
++-----------+----------+-
+| Host | User | ...
++-----------+----------+-
+| localhost | root | ...
+| localhost | | ...
+| % | jeffrey | ...
+| % | root | ...
++-----------+----------+-
+@end example
+
+@cindex Berechtigungstabellen, sortieren
+@cindex sortieren, Berechtigungstabellen
+@cindex @code{user}-Tabelle, sortieren
+Beim Versuch einer Verbindung durchsucht der Server die sortierten Einträge
+und benutzt die ersten übereinstimmenden. Bei einer Verbindung von
+@code{localhost} aus durch @code{jeffrey} stimmen die Werte zuerst mit den
+Einträgen von @code{'localhost'} in der @code{Host}-Spalte überein. Hiervon
+stimmt der Eintrag mit dem leeren Benutzernamen sowohl mit dem verbindenden
+Host als auch mit dem Benutzernamen überein. (@code{'%'/'jeffrey'} hätte
+auch übereingestimmt, aber er ist nicht der erste Tabelleneintrag, der
+gefunden wird.)
+
+Hier ist ein weiteres Beispiel. Nehmen Sie an, die @code{user}-Tabelle
+sieht wie folgt aus:
+
+@example
++----------------+----------+-
+| Host | User | ...
++----------------+----------+-
+| % | jeffrey | ...
+| thomas.loc.gov | | ...
++----------------+----------+-
+@end example
+
+Die sortierte Tabelle sieht wie folgt aus:
+
+@example
++----------------+----------+-
+| Host | User | ...
++----------------+----------+-
+| thomas.loc.gov | | ...
+| % | jeffrey | ...
++----------------+----------+-
+@end example
+
+Eine Verbindung von @code{thomas.loc.gov} aus durch @code{jeffrey} stimmt
+mit dem ersten Eintrag überein, wohingegen eine Verbindung von
+@code{whitehouse.gov} aus durch @code{jeffrey} mit dem zweiten Eintrag
+übereinstimmt.
+
+Ein häufiges Missverständnis besteht darin zu denken, dass bei einem
+angegebenen Benutzernamen alle Einträge, die explizit den Benutzer nennen,
+zuerst benutzt werden, wenn der Server versucht, eine Übereinstimmung für
+die Verbindung zu finden. Das stimmt schlicht nicht. Das vorherige Beispiel
+stellt das dar, wobei eine Verbindung von @code{thomas.loc.gov} aus durch
+@code{jeffrey} zuerst gerade nicht mit dem Eintrag übereinstimmt, der
+@code{'jeffrey'} als @code{User}-Feldwert enthält, sondern mit dem Eintrag,
+der keinen Benutzernamen enthält!
+
+Wenn Sie Probleme haben, sich mit dem Server zu verbinden, geben Sie die
+@code{user}-Tabelle aus und sortieren Sie sich von Hand, um zu sehen, wo
+die erste Übereinstimmung stattfindet.
+
+
+@node Request access, Access denied, Connection access, Privilege system
+@c German node Anfragezugriff
+@subsection Zugriffskontrolle, Phase 2: Anfrageüberprüfung
+
+Wenn Sie erst einmal eine Verbindung hergestellt haben, geht der Server in
+Phase 2. Bei jeder Anfrage, die über diese Verbindung hereinkommt, prüft
+der Server, ob Sie ausreichende Berechtigungen haben, sie auszuführen,
+wobei es auf die Operation ankommt, die Sie ausführen wollen. Hier kommen
+die Berechtigungsfelder der Berechtigungstabellen ins Spiel. Diese
+Berechtigungen können aus jeder der @code{user}-, @code{db}-,
+@code{host}-, @code{tables_priv}- oder @code{columns_priv}-Tabellen
+stammen. Die Berechtigungstabellen werden mit @code{GRANT}- und
+@code{REVOKE}-Befehlen verändert. @xref{GRANT, , @code{GRANT}}. (Hilfreich
+sind die Ausführungen unter @ref{Privileges}, wo die Felder aufgelistet
+sind, die sich in jeder der Berechtigungstabellen finden.)
+
+Die @code{user}-Tabelle gewährt Berechtigungen, die Ihnen auf globaler
+Ebene zugeordnet sind und die unabhängig von der gerade aktuellen Datenbank
+zutreffen. Wenn beispielsweise die @code{user}-Tabelle Ihnen die
+@strong{delete}-Berechtigung gewährt, können Sie Zeilen aus jeder Datenbank
+auf dem Server-Host löschen! Mit anderen Worten: Berechtigungen in der
+@code{user}-Tabelle sind Superuser-Berechtigungen. Es ist klug,
+Berechtigungen in der @code{user}-Tabelle nur Superusern wie Server- oder
+Datenbankverwaltern zu gewähren. Bei anderen Benutzern sollten Sie
+Berechtigungen in der @code{user}-Tabelle auf @code{'N'} gesetzt lassen und
+Berechtigungen nur auf Datenbank-Ebene gewähren, indem Sie die @code{db}-
+und @code{host}-Tabellen benutzen.
+
+@cindex anonymer Benutzer
+@cindex Platzhalter, in @code{mysql.db}-Tabelle
+@cindex Platzhalter, in @code{mysql.host}-Tabelle
+Die @code{db}- und @code{host}-Tabellen gewähren Datenbank-spezifische
+Berechtigungen. Werte in den Geltungsbereichs-Feldern können wie folgt
+festgelegt werden:
+
+@itemize @bullet
+@item
+Die Platzhalterzeichen @samp{%} und @samp{_} können in den @code{Host}- und
+@code{Db}-Feldern jeder Tabelle benutzt werden.
+
+@item
+Ein @code{'%'}-@code{Host}-Wert in der @code{db}-Tabelle bedeutet ``jeder
+Host.'' Ein leerer @code{Host}-Wert in der @code{db}-Tabelle bedeutet
+``sieh in der @code{host}-Tabelle wegen weiterer Informationen nach''.
+
+@item
+Ein @code{'%'}- oder leerer @code{Host}-Wert in der @code{host}-Tabelle
+bedeutet ``jeder Host''.
+
+@item
+Ein @code{'%'}- oder leerer @code{Db}-Wert in einer der Tabellen bedeutet
+``jede Datenbank''.
+
+@item
+Ein leerer @code{User}-Wert in einer der Tabellen entspricht dem anonymen
+Benutzer.
+@end itemize
+
+@cindex Berechtigungstabellen, sortieren
+@cindex sortieren, Berechtigungstabellen
+@cindex @code{db}-Tabelle, sortieren
+@cindex @code{host}-Tabelle, sortieren
+Die @code{db}- und @code{host}-Tabellen werden eingelesen und sortiert,
+wenn der Server hoch fährt (zur gleichen Zeit, wenn er die
+@code{user}-Tabelle einliest). Die @code{db}-Tabelle wird nach den
+Geltungsbereichs-Feldern @code{Host}, @code{Db} und @code{User} sortiert.
+Die @code{host}-Tabelle wird nach den Geltungsbereichs-Feldern @code{Host}
+und @code{Db} sortiert. Bei der @code{user}-Tabelle werden die
+spezifischsten Werte zuerst und die unspezifischsten Werte zuletzt
+einsortiert, und wenn der Server nach übereinstimmenden Einträgen sucht,
+benutzt er die erste Übereinstimmung, die er findet.
+
+
+@cindex Platzhalter, in @code{mysql.tables_priv}-Tabelle
+@cindex Platzhalter, in @code{mysql.columns_priv}-Tabelle
+Die @code{tables_priv}- und @code{columns_priv}-Tabellen gewähren Tabellen-
+und Spalten-spezifische Berechtigungen. Werte in der
+Geltungsbereichs-Feldern können wie folgt festgelegt werden:
+
+@itemize @bullet
+@item
+Die Platzhalterzeichen @samp{%} und @samp{_} können im @code{Host}-Feld
+beider Tabellen benutzt werden.
+
+@item
+Ein @code{'%'}- oder leerer @code{Host}-Wert in jeder der beiden Tabellen bedeutet ``jeder Host.''
+
+@item
+Die @code{Db}-, @code{Table_name}- und @code{Column_name}-Felder dürfen in
+beiden Tabellen keine Platzhalter enthalten oder leer sein.
+@end itemize
+
+Die @code{tables_priv}- und @code{columns_priv}-Tabellen werden nach den
+@code{Host}-, @code{Db}- und @code{User}-Feldern sortiert. Das geschieht
+ähnlich wie das Sortieren der @code{db}-Tabelle, wenngleich das Sortieren
+einfacher ist, weil nur das @code{Host}-Feld Platzhalter enthalten darf.
+
+Der Prozess der Anfragenüberprüfung ist weiter unten beschrieben. (Wenn Sie
+mit dem Quelltext für die Zugangsüberprüfung vertraut sind, werden Sie
+feststellen, dass die Beschreibung hier leicht vom im Code verwendeten
+Algorithmus abweicht. Die Beschreibung stellt dar, was der Code tatsächlich
+tut; sie weicht nur deshalb ab, um die Erklärung zu erleichtern.)
+
+Bei Verwaltungsanfragen (@strong{shutdown}, @strong{reload} usw.) prüft der
+Server nur den @code{user}-Tabelleneintrag, weil das die einzige Tabelle
+ist, die Verwaltungsberechtigungen festlegt. Zugriff wird gewährt, wenn der
+Eintrag die verlangte Operation erlaubt, ansonsten wird er verweigert. Wenn
+Sie zum Beispiel @code{mysqladmin shutdown} ausführen wollen, aber Ihr
+@code{user}-Tabelleneintrag Ihnen nicht die @strong{shutdown}-Berechtigung
+gewährt, wird der Zugriff verweigert, ohne dass die @code{db}- oder
+@code{host}-Tabellen geprüft werden. (Sie enthalten keine
+@code{Shutdown_priv}-Spalte, daher gibt es keinen Grund, sie zur Prüfung
+heranzuziehen.)
+
+Bei Datenbank-bezogenen Anfragen (@strong{insert}, @strong{update} usw.)
+prüft der Server zuerst die globalen (superuser-) Berechtigungen, indem er
+im @code{user}-Tabelleneintrag nachsieht. Wenn der Eintrag die verlangte
+Operation erlaubt, wird der Zugriff gewährt. Wenn die globalen
+Berechtigungen in der @code{user}-Tabelle unzureichend sind, stellt der
+Server die Datenbank-spezifischen Berechtigungen des Benutzers fest, indem
+er die @code{db}- und @code{host}-Tabellen prüft:
+
+@enumerate
+@item
+Der Server sieht in der @code{db}-Tabelle nach einer Übereinstimmung in den
+@code{Host}-, @code{Db}- und @code{User}-Feldern nach. In den @code{Host}-
+und @code{User}-Feldern wird nach Übereinstimmung mit dem Hostnamen
+gesucht, von dem aus sich der Benutzer verbindet, und nach Übereinstimmung
+mit dem MySQL-Benutzernamen. Im @code{Db}-Feld wird nach Übereinstimmung
+mit der Datenbank gesucht, mit der sich der Benutzer verbinden will. Wenn
+es keinen Eintrag für @code{Host} und @code{User} gibt, wird der Zugriff
+verweigert.
+
+@item
+Wenn es keinen übereinstimmenden @code{db}-Tabelleneintrag gibt und das
+@code{Host}-Feld nicht leer ist, bestimmt dieser Eintrag die
+Datenbank-spezifischen Berechtigungen des Benutzers.
+
+@item
+Wenn das @code{Host}-Feld des übereinstimmenden @code{db}-Tabelleneintrags
+leer ist, bedeutet das, dass die @code{host}-Tabelle festlegt, welchen
+Hosts Zugriff auf die Datenbank erlaubt werden soll. In diesem Fall schlägt
+der Server weiter in der @code{host}-Tabelle nach, um eine Übereinstimmung
+in den @code{Host}- und @code{Db}-Feldern zu finden. Wenn kein
+@code{host}-Tabelleneintrag passt, wird der Zugriff verweigert. Bei einer
+Übereinstimmung werden die Datenbank-spezifischen Berechtigungen des
+Benutzers als Schnittmenge (@emph{nicht} Vereinigungsmenge!) der
+Berechtigungen in den @code{db}- und @code{host}-Tabelleneinträgen
+berechnet, was die Berechtigungen ergibt, die in beiden Einträgen
+@code{'Y'} sind. (Auf diese Weise können Sie allgemeine Berechtigungen in
+den @code{db}-Tabelleneinträgen vergeben und diese dann fallweise von Host
+zu Host beschränken, indem Sie die @code{host}-Tabelleneinträge benutzen.)
+@end enumerate
+
+Nachdem die Datenbank-spezifischen Berechtigungen festgestellt wurden, die
+durch die @code{db}- und @code{host}-Tabelleneinträge gewährt werden, fügt
+der Server diese zu den globalen Berechtigungen in der @code{user}-Tabelle
+hinzu. Wenn das Ergebnis die verlangte Operation erlaubt, wird der Zugriff
+gewährt. Ansonsten prüft der Server die Tabellen- und
+Spalten-Berechtigungen des Benutzers in den @code{tables_priv}- und
+@code{columns_priv}-Tabellen und fügt diese zu den Benutzerberechtigungen
+hinzu. Aus dem Ergebnis ergibt sich, ob der Zugriff erlaubt oder verweigert
+wird.
+
+Als Boole'scher Term ausgedrückt kann die vorstehende Beschreibung der
+Berechnung der Benutzerrechte wie folgt zusammengefasst werden:
+
+@example
+globale Berechtigungen
+ODER (Datenbankberechtigungen UND Hostberechtigungen)
+ODER Tabellenberechtigungen
+ODER Spaltenberechtigungen
+@end example
+
+Vielleicht ist es nicht offensichtlich, warum der Server bei anfänglich als
+unzureichend herausgefundenen globalen @code{user}-Eintragsberechtigungen
+für die verlangte Operation diese Berechtigungen anschließend zu den
+Datenbank-, Tabellen- und Spalten-spezifischen Berechtigungen hinzuzählt.
+Der Grund liegt darin, dass eine Anfrage möglicherweise mehr als eine Sorte
+von Berechtigungen erfordert. Wenn Sie beispielsweise ein @code{INSERT ...
+SELECT}-Statement ausführen, brauchen Sie eventuell sowohl die
+@strong{insert}- als auch die @strong{select}-Berechtigung. Ihre
+Berechtigungen mögen so sein, dass der @code{user}-Tabelleneintrag eine
+Berechtigung enthält und der @code{db}-Tabelleneintrag die andere. In
+diesem Fall haben Sie die notwendigen Berechtigungen, die Anfrage
+auszuführen, aber das Server kann das nicht aus nur einer der beiden
+Tabellen heraus erkennen, sondern muss dafür die Einträge beider Tabellen
+kombinieren.
+
+@cindex @code{host}-Tabelle
+@cindex Tabellen, @code{host}
+
+Die @code{host}-Tabelle kann benutzt werden, um eine Liste sicherer Server
+zu pflegen.
+
+Bei TcX enthält die @code{host}-Tabelle eine Liste aller Maschine des
+lokalen Netzwerks. Diesen werden alle Berechtigungen gewährt.
+
+Sie können die @code{host}-Tabelle auch dazu benutzen, die Host
+aufzuführen, die @emph{nicht} sicher sind. Nehmen Sie an, Sie haben eine
+Maschine @code{oeffentlich.ihre.domaene}, die an einem öffentlichen Ort
+ist, den Sie als nicht sicher erachten. Sie können allen Hosts in Ihrem
+Netzwerk Zugriff gewähren ausser dieser Maschine, indem Sie die
+@code{host}-Tabelleneinträge wie folgt benutzen:
+
+@example
++--------------------------+----+-
+| Host | Db | ...
++--------------------------+----+-
+| oeffentlich.ihre.domane | % | ... (alle Berechtigungen auf 'N' gesetzt)
+| %.ihre.domaene | % | ... (alle Berechtigungen auf 'Y' gesetzt)
++--------------------------+----+-
+@end example
+
+@cindex Berechtigungen, Änderungen
+@cindex Änderungen der Berechtigungen
+@cindex Tabellen, gewähren
+@cindex Berechtigungstabellen
+
+Natürlich sollten Sie Ihre Einträge in die Berechtigungstabellen immer
+testen (indem Sie zum Beispiel @code{mysqlaccess} benutzen), um
+sicherzustellen, dass Ihre Zugriffsberechtigungen tatsächlich so gesetzt
+sind, wie Sie denken.
+
+
+@node Access denied, , Request access, Privilege system
+@c German node Zugriff verweigert
+@subsection Gründe für @code{Access denied}-Fehler
+
+Wenn Sie beim Verbindungsversuch zu einem MySQL-Server @code{Access
+denied}-Fehler bekommen, gibt Ihnen die folgende Liste ein paar Hinweise,
+das Problem zu beheben:
+
+@itemize @bullet
+@item
+Haben Sie nach der Installation von MySQL das
+@code{mysql_install_db}-Skript laufen lassen, um die anfänglichen
+Berechtigungstabelleninhalte zu konfigurieren? Wenn nicht, tun Sie das!
+@xref{Default privileges}. Testen Sie die anfänglichen
+Berechtigungen, indem Sie folgenden Befehl ausführen:
+
+@example
+shell> mysql -u root test
+@end example
+
+Der Server sollte die Verbindung ohne Fehlermeldung zulassen. Stellen Sie
+auch sicher, dass Sie eine Datei @file{user.MYD} im
+MySQL-Datenbankverzeichnis haben. Üblicherweise ist das
+@file{PFAD/var/mysql/user.MYD}, wobei @code{PFAD} der Pfadname zum
+MySQL-Installationsverzeichnis ist.
+
+@item
+Nach einer gerade durchgeführten Installation sollten Sie sich mit dem
+Server verbinden und Ihre Benutzer und deren Zugriffsberechtigungen
+einrichten:
+
+@example
+shell> mysql -u root mysql
+@end example
+
+Der Server sollte die Verbindung zulassen, weil der
+MySQL-@code{root}-Benutzer anfänglich kein Passwort hat. Das ist ein
+Sicherheitsrisiko, daher sollten Sie das @code{root}-Passwort einrichten,
+während Sie Ihre anderen MySQL-Benutzer einrichten.
+
+Wenn Sie versuchen, sich als @code{root} zu verbinden, und folgenden Fehler
+erhalten:
+
+@example
+Access denied for user: '@@unknown' to database mysql
+@end example
+
+heißt das, dass Sie in der @code{user}-Tabelle keinen Eintrag
+@code{'root'} im @code{User}-Spaltenwert haben und dass @code{mysqld} den
+Hostnamen für Ihren Client nicht auflösen kann. In diesem Fall müssen Sie
+den Server mit der @code{--skip-grant-tables}-Option neu starten und Ihrer
+@file{/etc/hosts}- oder @file{\windows\hosts}-Datei einen Eintrag für Ihren
+Host hinzufügen.
+
+@item
+Wenn Sie einen Fehler wie folgt erhalten:
+
+@example
+shell> mysqladmin -u root -pxxxx ver
+Access denied for user: 'root@@localhost' (Using password: YES)
+@end example
+
+bedeutet das, dass Sie ein falsches Passwort benutzen. @xref{Passwords}.
+
+Wenn Sie das Root-Passwort vergessen haben, können Sie @code{mysqld} mit
+@code{--skip-grant-tables} neu starten, um das Passwort zu ändern. Diese
+Option wird weiter hinten im Handbuch ausführlicher beschrieben.
+
+Wenn Sie den obigen Fehler erhalten, obwohl Sie kein Passwort angegeben
+haben, bedeutet das, dass in einer der @code{my.ini}-Dateien ein falsches
+Passwort steht. @xref{Option files}. Sie können die Benutzung der
+Optionsdateien mit der @code{--no-defaults}-Option wie folgt verhindern:
+
+@example
+shell> mysqladmin --no-defaults -u root ver
+@end example
+
+@item
+@cindex @code{mysql_fix_privilege_tables}
+Wenn Sie eine bestehende MySQL-Installation von einer Version vor 3.22.11
+auf Version 3.22.11 oder später aktualisiert haben, haben Sie das
+@code{mysql_fix_privilege_tables}-Skript ausgeführt? Falls nicht, tun Sie
+das! Die Struktur der Berechtigungstabellen hat sich ab MySQL-Version
+3.22.11 geändert, als das @code{GRANT}-Statement mit Funktion erfüllt
+wurde.
+
+@item
+Falls es aussieht, als hätten sich Ihre Berechtigungen mitten in einer
+Sitzung geändert, kann es sein, dass ein Superuser sie geändert hat. Das
+Neuladen der Berechtigungstabellen betrifft neue
+Client-Verbindungen, aber auch bestehende Verbindungen, wie in
+@ref{Privilege changes} beschrieben.
+
+@item
+Wenn Sie es nicht schaffen, dass Ihr Passwort funktioniert, denken Sie
+daran, dass Sie die @code{PASSWORD()}-Funktion benutzen müssen, wenn Sie
+das Passwort mit den @code{INSERT}-, @code{UPDATE}- oder @code{SET
+PASSWORD}-Statements setzen. Die @code{PASSWORD()}-Funktion wird nicht
+benötigt, wenn Sie das Passwort mit dem @code{GRANT ... INDENTIFIED
+BY}-Statement oder dem @code{mysqladmin password}-Befehl setzen.
+@xref{Passwords}.
+
+@item
+@code{localhost} ist ein Synonym für Ihren lokalen Hostnamen und
+gleichzeitig der vorgabemäßige Host, mit dem sich Clients versuchen zu
+verbinden, wenn Sie nicht explizit einen Hostnamen angeben. Verbindungen zu
+@code{localhost} funktionieren jedoch nicht, wenn Sie auf einem System
+arbeiten, das MIT-pThreads benutzt (@code{localhost}-Verbindungen werden
+über Unix-Sockets hergestellt, die von MIT-pThreads nicht unterstützt
+werden). Um auf solchen Systemen Probleme zu vermeiden, sollten Sie die
+@code{--host}-Option zu benutzen, um den Serverhost explizit anzugeben. Das
+stellt eine TCP/IP-Verbindung zum @code{mysqld}-Server her. In diesem Fall
+muss Ihr echter Hostname in den @code{user}-Tabelleneinträgen auf dem
+Server-Host stehen. (Das gilt sogar dann, wenn Sie ein Client-Programm auf
+demselben Host fahren, wo der Server läuft.)
+
+@item
+Wenn Sie beim Versuch, sich mit @code{mysql -u user_name db_name} mit einer
+Datenbank zu verbinden, einen @code{Access denied}-Fehler erhalten, gibt es
+eventuell ein Problem mit der @code{user}-Tabelle. Das können Sie
+überprüfen, indem Sie @code{mysql -u root mysql} und folgendes
+SQL-Statement absetzen:
+
+@example
+mysql> SELECT * FROM user;
+@end example
+
+Das Ergebnis sollte einen Eintrag enthalten, in dem die @code{Host}- und
+@code{User}-Spalten mit dem Hostnamen Ihres Computers und Ihrem
+MySQL-Benutzernamen übereinstimmen.
+
+@item
+Die @code{Access denied}-Fehlermeldung sagt Ihnen, als wer Sie sich
+versuchen einzuloggen, den Host, von dem aus Sie versuchen, sich zu
+verbinden, und ob Sie ein Passwort benutzen oder nicht. Normalerweise
+sollten Sie in der @code{user}-Tabelle einen Eintrag haben, der exakt mit
+Ihrem Hostnamen und Ihrem Benutzernamen übereinstimmt, die in der
+Fehlermeldung ausgegeben wurden. Wenn Sie zum Beispiel eine Fehlermeldung
+erhalten, die @code{Using password: NO} enthält, bedeutet das, dass Sie
+versuchen sich einzuloggen, ohne ein Passwort anzugeben.
+
+@item
+Wenn Sie folgenden Fehler erhalten, wenn Sie sich von einem anderen Host
+als dem, auf dem der MySQL-Server läuft, zu verbinden, gibt es keine Zeile
+in der @code{user}-Tabelle, die mit Ihrem Host übereinstimmt:
+
+@example
+Host ... is not allowed to connect to this MySQL server
+@end example
+
+Das können Sie mit dem Kommandozeilentool @code{mysql} beheben (auf dem
+Serverhost!) und eine Zeile zur @code{user}-, @code{db}- oder
+@code{host}-Tabelle hinzufügen, die eine Benutzername-/Hostname-Kombination
+enthält, von wo aus Sie sich verbinden wollen; danach führen Sie
+@code{mysqladmin flush-privileges} aus. Wenn Sie nicht MySQL-Version 3.22
+laufen lassen und die IP-Nummer oder den Hostnamen der Maschine nicht
+kennen, von der aus Sie sich verbinden, sollten Sie einen Eintrag mit
+@code{'%'} als @code{Host}-Spaltenwert in die @code{user}-Tabelle einfügen
+und @code{mysqld} mit der @code{--log}-Option auf der Servermaschine neu
+starten. Nach dem Verbinden von der Client-Maschine aus zeigt die
+Information im MySQL-Log an, wie Sie sich wirklich verbunden haben.
+(Ersetzen Sie danach @code{'%'} im @code{user}-Tabelleneintrag durch den
+tatsächlichen Hostnamen, der im Log steht. Ansonsten erhalten Sie ein
+System, das unsicher ist.)
+
+Ein weiterer Grund für diesen Fehler unter Linux kann sein, dass Sie eine
+Binärversion von MySQL benutzen, die mit einer anderen glibc-Version
+kompiliert wurde als die, die Sie benutzen. In diesem Fall sollten Sie
+entweder die glibc Ihres Betriebssystems aktualisieren oder die
+Quellversion von MySQL herunter laden und sie selbst kompilieren. Ein
+Quell-RPM läßt sich normalerweise sehr einfach kompilieren und
+installieren, daher stellt dies kein großes Problem dar.
+
+@item
+Wenn Sie eine Fehlermeldung erhalten, in der der Hostname nicht angezeigt
+wird oder eine IP-Nummer ist, obwohl Sie sich mit einem Hostnamen versuchen
+zu verbinden:
+
+@example
+shell> mysqladmin -u root -pxxxx -h ein-hostname ver
+Access denied für user: 'root@' (Using password: YES)
+@end example
+
+bedeutet das, dass MySQL einen Fehler beim Auflösen der IP zu einem
+Hostnamen erhielt. In diesem Fall können Sie @code{mysqladmin flush-hosts}
+ausführen, um den internen DNS-Cache zu flushen. @xref{DNS}.
+
+Einige dauerhafte Lösungen sind:
+
+@itemize @minus
+@item
+Versuchen Sie herauszufinden, was mit Ihrem DNS-Server nicht funktioniert,
+und beheben Sie das Problem.
+
+@item
+Geben Sie in den MySQL-Berechtigungstabellen IP-Nummern statt Hostnamen an.
+
+@item
+Starten Sie @code{mysqld} mit @code{--skip-name-resolve}.
+
+@item
+Starten Sie @code{mysqld} mit @code{--skip-host-cache}.
+
+@item
+Verbinden Sie sich zu @code{localhost} wenn Sie Server und Client auf
+derselben Maschine laufen lassen.
+
+@item
+Tragen Sie die Client-Maschinennamen in @code{/etc/hosts} ein.
+@end itemize
+
+@item
+Wenn @code{mysql -u root test} funktioniert, aber @code{mysql -h
+your_hostname -u root test} zu @code{Access denied} führt, haben Sie
+eventuell nicht den korrekten Namen Ihres Hosts in der @code{user}-Tabelle.
+Ein häufiges Problem hierbei ist, dass der @code{Host}-Wert im
+@code{user}-Tabelleneintrag einen unqualifizierten Hostnamen festlegt, die
+Namensauflösungsroutinen Ihres Systems aber einen voll qualifizierten
+Domänennamen zurückgeben (oder umgekehrt). Wenn Sie zum Beispiel einen
+Eintrag mit dem Host @code{'tcx'} in der @code{user}-Tabelle haben, Ihr DNS
+MySQL aber mitteilt, dass Ihr Hostname @code{'tcx.subnet.se'} ist,
+funktioniert der Eintrag nicht. Fügen Sie der @code{user}-Tabelle einen
+Eintrag hinzu, der die IP-Nummer Ihres Hosts als @code{Host}-Spaltenwert
+enthält. (Alternativ könnten Sie der @code{user}-Tabelle einen Eintrag mit
+einem @code{Host}-Wert hinzufügen, der einen Platzhalter enthält, zum
+Beispiel @code{'tcx.%'}. Allerdings ist die Benutzung von
+Hostnamensendungen mit @samp{%} @emph{unsicher} und wird daher @emph{nicht}
+empfohlen!)
+
+@item
+Wenn @code{mysql -u benutzername test} funktioniert, aber @code{mysql -u
+benutzername andere_datenbank} nicht, haben Sie wahrscheinlich keinen
+Eintrag für @code{andere_datenbank} in der @code{db}-Tabelle.
+
+@item
+Wenn @code{mysql -u benutzername datenbankname} funktioniert, wenn es auf
+der Servermaschine ausgeführt wird, aber @code{mysql -u hostname -u
+benutzername datenbankname} nicht, wenn es auf einer anderen Clientmaschine
+ausgeführt wird, ist die Clientmaschine wahrscheinlich nicht in der
+@code{user}-Tabelle oder der @code{db}-Tabelle aufgeführt.
+
+@item
+Wenn Sie gar nicht herausfinden können, warum Sie @code{Access denied}
+erhalten, entfernen Sie aus der @code{user}-Tabelle alle Einträge, die
+@code{Host}-Werte haben, die Platzhalter enthalten (Einträge, die @samp{%}
+oder @samp{_} enthalten). Ein sehr häufiger Fehler besteht darin, einen
+neuen Eintrag mit @code{Host}=@code{'%'} und
+@code{User}=@code{'irgendein_benutzer'} in der Annahme hinzuzufügen, dass
+einem das erlaubt, @code{localhost} anzugeben, um sich von derselben
+Maschine aus zu verbinden. Der Grund, warum das nicht funktioniert, ist,
+dass die vorgabemäßigen Berechtigungen einen Eintrag mit
+@code{Host}=@code{'localhost'} und @code{User}=@code{''} enthalten. Weil
+dieser Eintrag einen @code{Host}-Wert @code{'localhost'} hat, der
+spezifischer ist als @code{'%'}, wird er vorrangig vor dem neuen Eintrag
+benutzt, wenn man sich von @code{localhost} verbindet! Das korrekte
+Vorgehen ist, einen zweiten Eintrag mit @code{Host}=@code{'localhost'} und
+@code{User}=@code{'irgendein_benutzer'} hinzuzufügen, oder den Eintrag mit
+@code{Host}=@code{'localhost'} und @code{User}=@code{''} zu entfernen.
+
+@item
+Wenn Sie den folgenden Fehler erhalten, gibt es eventuell Probleme mit der
+@code{db}- oder der @code{host}-Tabelle:
+
+@example
+Access to database denied
+@end example
+
+Wenn der aus der @code{db}-Tabelle ausgewählte Eintrag einen leeren Wert in
+der @code{Host}-Spalte hat, stellen Sie sicher, dass es einen oder mehrere
+korrespondierende Einträge in der @code{host}-Tabelle gibt, die festlegen,
+auf welche Hosts der @code{db}-Tabelleneintrag zutrifft.
+
+Wenn Sie bei der Benutzung der SQL-Befehle @code{SELECT ... INTO OUTFILE}
+oder @code{LOAD DATA INFILE} einen Fehler erhalten, enthält Ihr Eintrag in
+der @code{user}-Tabelle wahrscheinlich keine angeschaltete
+@strong{file}-Berechtigung.
+
+@item
+@cindex Konfigurationsdateien
+@cindex Umgebungsvariablen
+@tindex .my.cnf-Datei
+Denken Sie daran, dass Client-Programme Verbindungsparameter benutzen, die
+in Konfigurationsdateien oder Umgebungsvariablen festgelegt sind.
+@xref{Environment variables}. Wenn ein Client anscheinend falsche
+vorgabemäßige Verbindungsparameter sendet, wenn Sie diese nicht auf der
+Kommandozeile angeben, überprüfen Sie Ihre Umgebung und die
+@file{.my.cnf}-Datei in Ihrem Heimatverzeichnis. Überprüfen Sie
+gegebenenfalls auch systemweite MySQL-Konfigurationsdateien, obwohl es sehr
+viel unwahrscheinlicher ist, dass Client-Verbindungsparameter in diesen
+festgelegt werden. @xref{Option files}. Wenn Sie beim Laufenlassen eines
+Clients ohne irgend welche Optionen @code{Access denied} erhalten, stellen
+Sie sicher, dass Sie kein altes Passwort in irgendeiner Optionsdatei
+angegeben haben! @xref{Option files}.
+
+@item
+Wenn Sie in den Berechtigungstabellen direkte Änderungen vornehmen (indem
+Sie ein @code{INSERT}- oder @code{UPDATE}-Statement benutzen) und Ihre
+Änderungen anscheinend ignoriert werden, denken Sie daran, dass sie ein
+@code{FLUSH PRIVILEGES}-Statement absetzen müssen oder einen
+@code{mysqladmin flush-privileges}-Befehl ausführen, um den Server zu
+veranlassen, die Berechtigungstabellen neu einzulesen. Ansonsten haben Ihre
+Änderungen keine Auswirkung, bis der Server das nächste Mal gestartet wird.
+Denken Sie auch daran, wenn Sie ein @code{root}-Passwort mit einem
+@code{UPDATE}-Befehl festgelegt haben, dass Sie dieses solange nicht
+angeben müssen, bis Sie die Berechtigungen flushen, weil der Server vorher
+nicht weiß, dass Sie Ihr Passwort geändert haben!
+
+@item
+Wenn Sie Zugriffsprobleme mit einem Perl-, PHP-, Python- oder ODBC-Programm
+haben, versuchen Sie, sich mit @code{mysql -u benutzername datenbankname}
+oder @code{mysql -u benutzername -pihr_passwort datenbankname} zu
+verbinden. Wenn es Ihnen gelingt, sich mittels des @code{mysql}-Clients zu
+verbinden, gibt es ein Problem mit Ihrem Programm und nicht mit den
+Zugriffsberechtigungen. (Beachten Sie, dass zwischen @code{-p} und dem
+Passwort kein Leerzeichen steht; alternativ können Sie auch die
+@code{--password=ihr_passwort}-Syntax benutzen, um Ihr Passwort anzugeben.
+Wenn Sie die @code{-p}-Option allein benutzen, wird MySQL eine
+Eingabeaufforderung für das Passwort anzeigen.)
+
+@item
+Zum Testen starten Sie den @code{mysqld}-Daemon mit der
+@code{--skip-grant-tables}-Option. Anschließend können Sie die
+MySQL-Berechtigungstabellen ändern und das @code{mysqlaccess}-Skript
+benutzen, um zu sehen, ob Ihre Änderungen den gewünschten Effekt haben oder
+nicht. Wenn Sie mit Ihren Änderungen zufrieden sind, führen Sie
+@code{mysqladmin flush-privileges} aus, um @code{mysqld} mitzuteilen, die
+neuen Berechtigungstabellen zu benutzen. @strong{Beachten Sie:} Das
+Neuladen der Berechtigungstabellen überschreibt die
+@code{--skip-grant-tables}-Option. Das erlaubt Ihnen, den Server zu
+veranlassen, die Berechtigungstabellen wieder zu benutzen, ohne ihn
+herunter und dann wieder herauf fahren zu müssen.
+
+@item
+Wenn alles andere fehlschlägt, starten Sie den @code{mysqld}-Daemon mit
+einer Debugging-Option (zum Beispiel @code{--debug=d,general,query}). Das
+gibt Host- und Benutzerinformationen über Verbindungsversuche aus sowie
+Informationen über jeden abgesetzten Befehl. @xref{Making trace files}.
+
+@item
+Wenn Sie irgend welche anderen Probleme mit den MySQL-Berechtigungstabellen
+haben und meinen, das Problem der Mailing-Liste mitteilen zu müssen,
+stellen Sie immer einen Auszug Ihrer MySQL-Berechtigungstabellen zur
+Verfügung. Sie können einen Auszug der Tabellen mit dem @code{mysqldump
+mysql}-Befehl erzeugen. Berichten Sie Ihr Problem - wie immer - unter
+Benutzung des @code{mysqlbug}-Skripts. @xref{Bug reports}. In einigen
+Fällen müssen Sie vielleicht @code{mysqld} mit @code{--skip-grant-tables}
+neu starten, um @code{mysqldump} benutzen zu können.
+@end itemize
+
+
+@node User Account Management, Disaster Prevention, Privilege system, MySQL Database Administration
+@c German node Benutzerkontenverwaltung
+@section MySQL-Benutzerkonten-Verwaltung
+
+
+
+@menu
+* GRANT::
+* User names::
+* Privilege changes::
+* Default privileges::
+* Adding users::
+* User resources::
+* Passwords::
+* Password security::
+@end menu
+
+@node GRANT, User names, User Account Management, User Account Management
+@c German node GRANT
+@subsection @code{GRANT}- und @code{REVOKE}-Syntax
+
+@findex GRANT
+@findex REVOKE
+
+@cindex Berechtigungen, gewähren
+@cindex Berechtigungen, entziehen
+@cindex global Berechtigungen
+@cindex entziehen, Berechtigungen
+@cindex gewähren, Berechtigungen
+
+@example
+GRANT berechtigung_art [(spalten_liste)] [, berechtigung_art [(spalten_liste)] ...]
+ ON @{tabelle | * | *.* | datenbank.*@}
+ TO benutzername [IDENTIFIED BY 'passwort']
+ [, benutzername [IDENTIFIED BY 'passwort'] ...]
+ [REQUIRE
+ [@{SSL| X509@}]
+ [CIPHER cipher [AND]]
+ [ISSUER issuer [AND]]
+ [SUBJECT subject]]
+ [WITH GRANT OPTION]
+
+REVOKE berechtigung_art [(spalten_liste)] [, berechtigung_art [(spalten_liste)] ...]
+ ON @{tabelle | * | *.* | datenbank.*@}
+ FROM benutzername [, benutzername ...]
+@end example
+
+@code{GRANT} ist implementiert ab MySQL Version 3.22.11. Bei früheren
+MySQL-Versionen bewirkt das @code{GRANT}-Statement nichts.
+
+Die @code{GRANT}- und @code{REVOKE}-Befehle erlauben Systemverwaltern,
+Benutzer anzulegen und MySQL-Benutzern Rechte auf vier Berechtigungsebenen
+zu gewähren und zu entziehen:
+
+@table @strong
+@item Globale Ebene
+Globale Berechtigungen betreffen alle Datenbanken auf einem gegebenen
+Server. Diese Berechtigungen werden in der @code{mysql.user}-Tabelle
+gespeichert.
+
+@item Datenbank-Ebene
+Datenbank-Berechtigungen betreffen alle Tabellen in einer gegebenen
+Datenbank. Diese Berechtigungen werden in den @code{mysql.db}- und
+@code{mysql.host}-Tabellen gespeichert.
+
+@item Tabellen-Ebene
+Tabellen-Berechtigungen betreffen alle Spalten in einer gegebenen Tabelle.
+Diese Berechtigungen werden in der @code{mysql.tables_priv}-Tabelle
+gespeichert.
+
+@item Spalten-Ebene
+Spalten-Berechtigungen betreffen einzelne Spalten in einer gegebenen
+Tabelle. Diese Berechtigungen werden in der
+@code{mysql.columns_priv}-Tabelle gespeichert.
+@end table
+
+Wenn Sie ein @code{GRANT} für einen Benutzer angeben, den es nicht gibt,
+wird dieser Benutzer erzeugt. Beispiele, wie @code{GRANT} funktioniert,
+finden Sie unter @ref{Adding users}.
+
+Bei @code{GRANT} und @code{REVOKE}-Statements kann @code{berechtigung_art}
+wie folgt angegeben werden:
+
+@example
+ALL PRIVILEGES FILE RELOAD
+ALTER INDEX SELECT
+CREATE INSERT SHUTDOWN
+DELETE PROCESS UPDATE
+DROP REFERENCES USAGE
+@end example
+
+@code{ALL} ist ein Synonym für @code{ALL PRIVILEGES}. @code{REFERENCES} ist
+noch nicht implementiert. @code{USAGE} ist momentan ein Synonym für ``keine
+Berechtigungen''. Es kann benutzt werden, um einen Benutzer zu erzeugen,
+der keine Berechtigungen hat.
+
+Um einem Benutzer die @strong{grant}-Berechtigung zu entziehen, benutzen
+Sie einen @code{berechtigung_art}-Wert @code{GRANT OPTION}:
+
+@example
+REVOKE GRANT OPTION ON ... FROM ...;
+@end example
+
+Die einzigen @code{berechtigung_art}-Werte, die Sie für eine Tabelle
+festlegen können, sind @code{SELECT}, @code{INSERT}, @code{UPDATE},
+@code{DELETE}, @code{CREATE}, @code{DROP}, @code{GRANT}, @code{INDEX} und
+@code{ALTER}.
+
+Die einzigen @code{berechtigung_art}-Werte, die Sie für eine Spalte
+festlegen können (im Falle, dass Sie eine @code{spalten_liste}-Klausel
+benutzen), sind @code{SELECT}, @code{INSERT} und @code{UPDATE}.
+
+Sie können globale Berechtigungen setzen, indem Sie die @code{ON
+*.*}-Syntax benutzen. Datenbank-Berechtigungen setzen Sie mit der @code{ON
+datenbank.*}-Syntax. Wenn Sie @code{ON *} setzen und eine aktuelle
+Datenbank ausgewählt haben, setzen Sie die Berechtigungen für diese
+Datenbank. (@strong{ACHTUNG:} Wenn Sie @code{ON *} festlegen und
+@emph{keine} aktuelle Datenbank ausgewählt haben, betrifft das die globalen
+Berechtigungen!)
+
+Um die Rechtegewährung für Benutzer von uneindeutigen Hosts aus zu
+ermöglichen, unterstützt MySQL den @code{benutzername}-Wert in der Form
+@code{benutzer@@host}. Wenn Sie eine @code{user}-Zeichenkette festlegen
+wollen, die Sonderzeichen enthält (wie @samp{-}), oder eine
+@code{host}-Zeichenkette, die Sonderzeichen oder Platzhalterzeichen enthält
+(wie @samp{%}), können Sie Benutzernamen oder Hostnamen in
+Anführungszeichen setzen (beispielsweise @code{'test-benutzer'@@'test-hostname'}).
+
+Sie können im Hostnamen Platzhalter angeben. @code{benutzer@@"%.loc.gov"}
+zum Beispiel trifft auf @code{benutzer} für jeden Host in der Domäne
+@code{loc.gov} zu. @code{benutzer@@"144.155.166.%"} trifft auf
+@code{benutzer} für jeden Host im @code{144.155.166}-Class-C-Subnetz zu.
+
+Die einfache Form @code{benutzer} ist ein Synonym für
+@code{benutzer@@"%"}. @strong{ACHTUNG:} Wenn Sie anonymen Benutzern
+erlauben, sich mit dem MySQL-Server zu verbinden (was vorgabemäßig der
+Fall ist), sollten Sie auch alle lokalen Benutzer als
+@code{benutzer@@localhost} hinzufügen, weil ansonsten der Eintrag für den
+anonymen Benutzer für den lokalen Host in der @code{mysql.user}-Tabelle
+benutzt wird, wenn der Benutzer versucht, sich von der lokalen Maschine in
+den MySQL-Server einzuloggen! Anonyme Benutzer werden definiert, indem
+Einträge mit @code{User=''} in die @code{mysql.user}-Tabelle eingefügt
+werden. Das können Sie mit folgender Anfrage überprüfen:
+
+@example
+mysql> SELECT Host,User FROM mysql.user WHERE User='';
+@end example
+
+Momentan unterstützt @code{GRANT} nur Host-, Datenbank-, Tabellen- und
+Spaltennamen mit maximal 60 Zeichen. Ein Benutzername kann bis zu 16
+Zeichen lang sein.
+
+Die Berechtigungen für eine Tabelle oder Spalte werden durch ein logisches
+ODER der Berechtigungen auf jeder der vier Berechtigungsebenen zusammen
+gesetzt. Wenn die @code{mysql.user}-Tabelle beispielsweise festlegt, dass
+ein Benutzer eine globalen @strong{select}-Berechtigung hat, kann diese
+nicht durch Einträge auf Datenbank-, Tabellen- oder Spaltenebene widerrufen
+werden.
+
+Die Berechtigungen für eine Spalte können wie folgt berechnet werden:
+
+@example
+Globale Berechtigungen
+ODER (Datenbank-Berechtigungen UND Host-Berechtigungen)
+ODER Tabellen-Berechtigungen
+ODER Spalten-Berechtigungen
+@end example
+
+In den meisten Fällen können Sie einem Benutzer Rechte auf lediglich einer
+der Berechtigungsebenen gewähren, wodurch das Leben nicht so kompliziert
+ist wie oben dargestellt. Die Details der Prozedur zur Überprüfung der
+Berechtigungen sind in @ref{Privilege system} dargestellt.
+
+Wenn Sie Berechtigungen für eine Benutzer-/Hostname-Kombination gewähren,
+die in der @code{mysql.user}-Tabelle nicht existiert, wird ein Eintrag
+hinzugefügt und verbleibt dort, bis der mit einem @code{DELETE}-Befehl
+gelöscht wird. Mit anderen Worten: @code{GRANT} kann eventuell
+@code{user}-Tabelleneinträge erzeugen, aber @code{REVOKE} entfernt diese
+nicht, sondern Sie müssen das explizit mit @code{DELETE} machen.
+
+@cindex Passwörter, setzen
+Ab MySQL-Version 3.22.12 wird, wenn ein neuer Benutzer erzeugt wird oder
+wenn Sie globale Grant-Berechtigungen haben, das Passwort des Benutzers
+durch die @code{IDENTIFIED BY}-Klausel festgelegt, wenn eine angegeben
+wird. Wenn der Benutzer bereits ein Passwort hat, wird es durch das neue
+ersetzt.
+
+@strong{ACHTUNG:} Wenn Sie einen neuen Benutzer anlegen, aber keine
+@code{IDENTIFIED BY}-Klausel angeben, hat der neue Benutzer kein Passwort.
+Das ist unsicher.
+
+Passwörter können auch mit dem @code{SET PASSWORD}-Befehl gesetzt werden.
+@xref{SET OPTION, , @code{SET OPTION}}.
+
+Wenn Sie Berechtigungen für eine Datenbank gewähren, wird ein Eintrag in
+der @code{mysql.db}-Tabellen erzeugt, falls notwendig. Wenn alle
+Berechtigungen für die Datenbank mit @code{REVOKE} widerrufen wurden, wird
+dieser Eintrag gelöscht.
+
+Wenn ein Benutzer überhaupt keine Berechtigungen auf eine Tabelle hat, wird
+die Tabelle nicht angezeigt, wenn der Benutzer nach einer Liste von
+Tabellen anfragt (zum Beispiel mit einem @code{SHOW TABLES}-Statement).
+
+Die @code{mit GRANT OPTION}-Klausel gibt dem Benutzer die Möglichkeit,
+anderen Benutzern jegliche der Berechtigungen zu vergeben, die der Benutzer
+auf der angegebenen Berechtigungsebene hat. Sie sollten vorsichtig damit
+sein, wem Sie die @strong{grant}-Berechtigung geben, denn zwei Benutzer mit
+unterschiedlichen Berechtigungen können in der Lage sein, Ihre
+Berechtigungen zu addieren!
+
+Sie können einem Benutzer keine Berechtigung gewähren, die Sie selbst nicht
+haben; die @strong{grant}-Berechtigung erlaubt Ihnen nur, die
+Berechtigungen zu vergeben, die Sie selbst besitzen.
+
+Wenn Sie einem Benutzer die @strong{grant}-Berechtigung auf einer
+bestimmten Berechtigungsebene geben, denken Sie daran, dass der Benutzer
+jegliche Berechtigungen, die der Benutzer schon besitzt (oder die ihm in
+Zukunft gewährt werden!), auf dieser Ebene auch an andere Benutzer gewährt
+werden können. Nehmen Sie an, Sie gewähren einem Benutzer die
+@strong{insert}-Berechtigung auf eine Datenbank. Wenn Sie danach die
+@strong{select}-Berechtigung auf die Datenbank mit @code{WITH GRANT OPTION}
+gewähren, kann der Benutzer nicht nur die @strong{select}-Berechtigung
+weiter geben, sondern auch @strong{insert}. Wenn Sie dem Benutzer danach
+die @strong{update}-Berechtigung auf die Datenbank gewähren, kann der
+Benutzer insgesamt @strong{insert}, @strong{select} und @strong{update}
+weiter geben.
+
+Sie sollten einem normalen Benutzer keine @strong{alter}-Berechtigung
+gewähren. Wenn Sie das tun, kann der Benutzer versuchen, das
+Berechtigungssystem zu unterlaufen, indem er Tabellen umbenennt!
+
+Beachten Sie: Wenn Sie Tabellen- oder Spalten-Berechtigungen auch nur für
+einen Benutzer gewähren, untersucht der Server Tabellen- und
+Spalten-Berechtigungen für alle Benutzer. Dadurch wird MySQL etwas
+langsamer.
+
+Wenn @code{mysqld} startet, werden alle Berechtigungen in den Speicher
+eingelesen. Datenbank-, Tabellen- und Spalten-Berechtigungen werden sofort
+wirksam. Berechtigungen auf Benutzerebene werden wirksam, wenn sich der
+Benutzer das nächste Mal verbindet. Änderungen in den
+Berechtigungstabellen, die Sie mit @code{GRANT} oder @code{REVOKE}
+durchführen, werden vom Server sofort bemerkt. Wenn Sie
+Berechtigungstabellen manuell ändern (mit @code{INSERT}, @code{UPDATE}
+usw.), müssen Sie ein @code{FLUSH PRIVILEGES}-Statement ausführen oder
+@code{mysqladmin flush-privileges} laufen lassen, um den Server zu
+veranlassen, die Berechtigungstabellen neu zu laden.
+@xref{Privilege changes}.
+
+@cindex ANSI SQL, Unterschiede zu
+Die größten Unterschiede zwischen ANSI SQL und MySQL-Versionen von
+@code{GRANT} sind:
+
+@itemize @bullet
+@item
+In MySQL werden Berechtigungen für eine Benutzername-/Hostname-Kombination
+vergeben und nicht nur für einen Benutzernamen.
+
+@item
+ANSI SQL hat keine globalen oder Datenbankebene-Berechtigungen und
+unterstützt nicht alle Berechtigungsarten, die MySQL unterstützt. MySQL
+unterstützt nicht die ANSI-SQL-@code{TRIGGER}-, @code{EXECUTE}- oder
+@code{UNDER}-Berechtigungen.
+
+@item
+ANSI-SQL-Berechtigungen werden auf hierarchische Art strukturiert. Wenn Sie
+einen Benutzer entfernen, werden alle Berechtigungen, die dieser Benutzer
+gewährt hat, widerrufen. In MySQL werden die gewährten Berechtigungen nicht
+automatisch widerrufen, sondern Sie müssen das selbst tun.
+
+@item
+Wenn Sie in MySQL das @code{INSERT}-Recht nur für Teile der Spalten einer
+Tabelle haben, können Sie dennoch @code{INSERT}-Statements auf der Tabelle
+ausführen. Die Spalten, für die Sie keine @code{INSERT}-Berechtigung haben,
+werden auf ihre Vorgabewerte gesetzt. ANSI SQL erfordert, dass Sie die
+@code{INSERT}-Berechtigung auf alle Spalten haben.
+
+@item
+Wenn Sie eine Tabelle in ANSI SQL löschen, werden alle Berechtigungen für
+die Tabelle widerrufen. Wenn Sie eine Berechtigung in ANSI SQL widerrufen,
+werden alle Berechtigungen, die auf dieser Berechtigung basierend gewährt
+wurden, widerrufen. In MySQL können Berechtigungen nur explizit mit
+@code{REVOKE}-Befehlen oder durch die Manipulation der
+MySQL-Berechtigungstabellen widerrufen werden.
+@end itemize
+
+-----------
+@cindex SSL- und X509-Grundlagen
+MySQL unterstützt SSL-verschlüsselte Verbindungen. Um zu verstehen, wie
+MySQL SSL benutzt, müssen wir einige Grundlagen von SSL und X509 erläutern.
+Leute, die damit schon vertraut sind, können dieses Kapitel überspringen.
+
+Vorgabemäßig benutzt MySQL unverschlüsselte Verbindungen zwischen Client
+und Server. Das heißt, dass jeder auf dem Weg dazwischen lauschen und Ihre
+Daten, die übertragen werden, mitlesen kann. Darüber hinaus könnten einige
+Leute auch den Inhalt von Daten ändern, die zwischen Client und Server
+ausgetauscht werden. Möglicherweise haben Sie auch wirklich geheime Daten
+über öffentliche Netzwerke zu übertragen, und eine Öffentlichkeit solcher
+Art ist unakzeptabel.
+
+SSL ist ein Protokoll, das unterschiedliche Verschlüsselungsalgorithmen
+benutzt, um sicherzustellen, dass Daten aus einem öffentlichen Netzwerk
+vertraut werden kann. Es besitzt Mechanismen, um Veränderungen, Verlust
+oder wiederholtes Abspielen (Replay) von Daten zu entdecken. SSL enthält
+auch Algorithmen, um die Identität zu erkennen und zu überprüfen, indem der
+X509-Standard benutzt wird.
+
+@cindex Was ist Verschlüsselung
+Mittels Verschlüsselung werden jegliche Arten von Daten unlesbar gemacht.
+Darüber hinaus werden in der heutigen Praxis Verschlüsselungsalgorithmen
+viele weitere Elemente hinzugefügt. Sie sollten vielen Arten bekannter
+Angriffe widerstehen, wie dem Herumspielen mit der Reihenfolge
+verschlüsselter Nachrichten oder dem doppelten Abspielen (Replay) von
+Daten.
+
+@cindex Was ist ein X509-Zertifikat?
+X509 ist der Standard, der es ermöglicht, jemanden im Internet zu
+identifizieren. Er wird meistens beim E-Commerce über das Internet benutzt.
+Kurz gesagt sollte es ein Unternehmen namens "Zertifizierungsautorität"
+geben, die jedem elektronische Zertifikate zuordnet, der diese braucht.
+Zertifikate beruhen auf asymmetrischen Verschlüsselungsalgorithmen, die
+zwei Verschlüsselungsschlüssel haben - öffentlichen und geheimen.
+Zertifikatsbesitzer können ihre Identität jeder anderen Seite beweisen.
+Zertifikate beinhalten den öffentlichen Schlüssel des Besitzers. Alle
+Daten, die damit verschlüsselt werden, können nur vom Besitzer des geheimen
+Schlüssels entschlüsselt werden.
+
+@cindex Mögliche Fragen:
+Frage: Warum benutzt MySQL nicht standardmäßig verschlüsselte Verbindungen?
+Antwort: Weil es MySQL langsamer macht. Jede zusätzliche Funktionalität
+erfordert, dass ein Computer zusätzliche Arbeit verrichtet, und das
+Verschlüsseln von Daten ist eine CPU-intensive Operation, die leicht die
+Zeit und Leistung übertreffen kann, die MySQL selbst verbraucht und
+benötigt. MySQL ist vorgabemäßig auf Geschwindigkeit optimiert.
+Frage: Ich brauche mehr Informationen über SSL / X509 / Verschlüsselung
+usw.
+Antwort: Benutzen Sie Ihre bevorzugte Internet-Suchmaschine und suchen Sie
+nach den Schlüsselwörtern, die Sie interessieren.
+
+
+@cindex SSL-bezogene Optionen
+
+MySQL kann x509-Zertifikat-Attribute prüfen, zusätzlich zum meist benutzten
+Benutzername-/Passwort-Schema. Alle gewöhnlich Optionen werden immer noch
+benötigt (Benutzername, Passwörter, IP-Adressmaske,
+Datenbank-/Tabellenname).
+
+Es gibt verschiedene Möglichkeiten, Verbindungen zu begrenzen:
+
+@itemize @bullet
+@item
+Ohne jegliche SSL-/X509-Optionen werden alle Arten verschlüsselter und
+unverschlüsselter Verbindungen zugelassen, wenn Benutzername und Passwort
+gültig sind.
+
+@item
+Die @code{REQUIRE SSL}-Option erzwingt SSL-verschlüsselte Verbindungen.
+Beachten Sie, dass dieses Erfordernis übergangen werden kann, wenn es
+irgend welche weiteren ACL-Datensätze gibt, die Verbindungen ohne SSL
+zulassen.
+
+Beispiel:
+@example
+GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SSL
+@end example
+
+
+@item
+* @code{REQUIRE X509} Wenn ein X509-Zertifikat erforderlich ist, bedeutet
+das, dass der Client ein gültiges Zertifikat haben muss, aber wir kümmern
+uns nicht um das genaue Zertifikat, den Herausgeber (Issuer) oder den
+Betreff (Subject). Die einzige Einschränkung ist, dass es möglich sein
+sollte, seine Unterschrift (Signature) mit einigen unserer CA-Zertifikate
+zu überprüfen.
+
+Beispiel:
+@example
+GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE X509
+@end example
+
+@item
+@code{REQUIRE ISSUER issuer} macht Verbindungen restriktiver: Jetzt muss
+der Client ein gültiges X509-Zertifikat vorlegen, das von einem CA-Issuer
+herausgegeben wurde. Die Benutzung von X509-Zertifikaten impliziert immer
+Verschlüsselung, daher wird die Option "SSL" nicht mehr benötigt.
+
+Beispiel:
+@example
+GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finnland AB, CN=Tonu Samuel/Email=tonu@@mysql.com"
+@end example
+
+@item
+@code{REQUIRE SUBJECT betreff} erfordert, dass der Client ein gültiges
+X509-Zertifikat mit dem Betreff "betreff" darauf hat. Wenn der Client ein
+gültiges Zertifikat hat, was aber einen anderen Betreff besitzt, wird die
+Verbindung nicht zugelassen.
+
+Beispiel:
+@example
+GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com"
+@end example
+
+@item
+@code{REQUIRE CIPHER cipher} wird benötigt um sicherzustellen, dass
+Chiffrierungen und Schlüssellängen benutzt werden, die stark genug sind.
+SSL selbst kann schwach sein, wenn alte Algorithmen mit kurzen
+Verschlüsselungsschlüsseln benutzt werden. Wenn diese Option benutzt wird,
+können wir exakte Chiffrierungen anfordern, bevor die Verbindung erlaubt
+wird.
+
+Beispiel:
+@example
+GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA"
+@end example
+
+Es ist erlaubt, die Optionen in Kombination wie folgt zu benutzen:
+@example
+GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret"
+ REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com"
+ AND ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finnland AB, CN=Tonu Samuel/Email=tonu@@mysql.com"
+ AND CIPHER "EDH-RSA-DES-CBC3-SHA"
+@end example
+
+Es ist aber nicht erlaubt, irgend eine der Optionen doppelt zu benutzen.
+Nur unterschiedliche Optionen dürfen gemischt werden.
+@end itemize
+-----------
+
+@node User names, Privilege changes, GRANT, User Account Management
+@c German node Benutzernamen
+@subsection MySQL-Benutzernamen und -Passwörter
+
+@cindex Benutzernamen und Passwörter
+@cindex Passwörter, für Benutzer
+
+Es gibt mehrere Unterschiede in der Art, wie Benutzernamen und Passwörter
+von MySQL benutzt werden, und der Art, wie sie von Unix oder Windows
+benutzt werden:
+
+@itemize @bullet
+@item
+Benutzernamen, wie sie von MySQL für Authentifizierungszwecke benutzt
+werden, haben nicht zu tun mit Unix-Benutzernamen (Login-Namen) oder
+Windows-Benutzernamen. Die meisten MySQL-Clients versuchen sich zwar
+vorgabemäßig einzuloggen, indem sie den aktuellen Unix-Benutzernamen als
+den MySQL-Benutzernamen verwenden, aber das geschieht nur aus Gründen der
+Bequemlichkeit. Client-Programme lassen zu, dass ein anderer Name mit den
+@code{-u}- oder @code{--user}-Optionen angegeben wird. Das bedeutet, dass
+Sie eine Datenbank nicht auf irgend eine Weise sicher machen können, wenn
+nicht alle MySQL-Benutzernamen Passwörter haben. Jeder kann versuchen, sich
+mit dem Server zu verbinden, indem er irgend einen Namen angibt, und wird
+damit Erfolg haben, wenn er einen Namen angibt, der kein Passwort hat.
+
+@item
+MySQL-Benutzernamen können bis zu 16 Zeichen lang sein; Unix-Benutzernamen
+sind typischerweise auf 8 Zeichen begrenzt.
+
+@item
+MySQL-Passwörter haben nichts mit Unix-Passwörtern zu tun. Es gibt keine
+notwendige Verbindungen zwischen dem Passwort, das Sie benutzen, um sich an
+einer Unix-Maschine anzumelden, und dem Passwort, das Sie benutzen, um auf
+eine Datenbank auf dieser Maschine zuzugreifen.
+
+@item
+@c German FIX unsplit @ref
+MySQL verschlüsselt Passwörter mit einem anderen Algorithmus als dem, der
+während des Unix-Login-Prozesses benutzt wird, siehe die Beschreibungen der
+@code{PASSWORD()}- und @code{ENCRYPT()}-Funktionen in
+@ref{Miscellaneous functions}.
+Beachten Sie, dass trotz der Tatsache, dass das Passwort
+'zerhackt' gespeichert wird, es ausreicht, Ihr 'zerhacktes' Passwort zu
+kennen, um sich am MySQL-Server anmelden zu können!
+@end itemize
+
+MySQL-Benutzer und ihre Berechtigungen werden normalerweise mit dem
+@code{GRANT}-Befehl erzeugt. @xref{GRANT}.
+
+Wenn Sie sich an einem MySQL-Server mit einem Kommandozeilen-Client
+anmelden, sollten Sie das Passwort mit @code{--password=ihr-passwort}
+eingeben. @xref{Connecting}.
+
+@example
+mysql --user=monty --password=rate_mal datenbankname
+@end example
+
+Wenn Sie möchten, dass der Client eine Eingabeaufforderung für das Passwort
+präsentiert, sollten Sie @code{--password} ohne Argument benutzen.
+
+@example
+mysql --user=monty --password datenbankname
+@end example
+
+Oder in der kurzen Form:
+
+@example
+mysql -u monty -p datenbankname
+@end example
+
+Beachten Sie, dass in den letzten Beispielen 'datenbankname' @strong{NICHT}
+das Passwort ist.
+
+Wenn Sie die @code{-p}-Option zur Eingabe des Passworts benutzen wollen,
+tun Sie das wie folgt:
+
+@example
+mysql -u monty -prate_mal datenbankname
+@end example
+
+Auf einigen Systemen kürzt die Bibliothek, die MySQL benutzt, um die
+Eingabeaufforderung für das Passwort auszugeben, das Passwort auf 8
+Zeichen. Intern hat MySQL keine Beschränkung hinsichtlich der Länge des
+Passworts.
+
+
+@node Privilege changes, Default privileges, User names, User Account Management
+@c German node Berechtigungsänderungen
+@subsection Wann Berechtigungsänderungen wirksam werden
+
+Wenn @code{mysqld} startet, werden alle Berechtigungstabelleninhalte in den
+Arbeitsspeicher eingelesen und werden zu diesem Zeitpunkt wirksam.
+
+Änderungen in den Berechtigungstabellen, die mit @code{GRANT},
+@code{REVOKE} oder @code{SET PASSWORD} durchgeführt werden, werden
+unmittelbar vom Server bemerkt.
+
+Wenn Sie die Berechtigungstabellen manuell ändern (mit @code{INSERT},
+@code{UPDATE} usw.), müssen Sie ein @code{FLUSH PRIVILEGES}-Statement
+ausführen oder @code{mysqladmin flush-privileges} oder @code{mysqladmin
+reload} laufen lassen, um den Server anzuweisen, die Berechtigungstabellen
+neu einzulesen. Ansonsten haben Ihre Änderungen @emph{keine Auswirkung},
+bis Sie den Server neu starten. Wenn Sie die Berechtigungstabellen manuell
+ändern, aber vergessen, die Berechtigungen neu zu laden, werden Sie sich
+wundern, warum trotz Ihrer Änderungen kein Unterschied zu bemerken ist!
+
+Wenn der Server bemerkt, dass sich die Berechtigungstabellen geändert
+haben, werden bestehende Client-Verbindungen wie folgt davon betroffen:
+
+@itemize @bullet
+@item
+Tabellen- und Spalten-Berechtigungsänderungen werden bei der nächsten
+Anfrage des Clients wirksam.
+
+@item
+Datenbank-Berechtigungsänderungen werden beim nächsten @code{USE
+datenbank}-Befehl wirksam.
+@end itemize
+
+Globale Berechtigungsänderungen und Passwortänderungen werden beim nächsten
+Mal wirksam, wenn sich der Client verbindet.
+
+
+@node Default privileges, Adding users, Privilege changes, User Account Management
+@c German node Vorgabemäßige Berechtigungen
+@subsection Einrichtung der anfänglichen MySQL-Berechtigungen
+
+@cindex Berechtigungen, vorgabemäßig
+@cindex Vorgaben, Berechtigungen
+@cindex Root-Passwort
+@cindex Superuser
+@cindex Benutzer, Root
+@cindex anonymer Benutzer
+@cindex Passwort, Root-Benutzer
+
+Nach der Installation von MySQL konfigurieren Sie die anfänglichen
+Zugriffsberechtigungen, indem Sie @code{scripts/mysql_install_db} laufen
+lassen.
+@xref{Quick install}.
+Das @code{mysql_install_db}-Skript startet den @code{mysqld}-Server und
+initialisiert dann die Berechtigungstabellen, so dass diese folgenden Satz
+an Berechtigungen enthalten:
+
+@itemize @bullet
+@item
+Der MySQL-@code{root}-Benutzer wird als Superuser angelegt, der alles tun
+darf. Verbindungen müssen vom lokalen Host aus gemacht werden.
+
+@strong{HINWEIS:}
+Das anfängliche @code{root}-Passwort ist leer, daher kann sich jeder als
+@code{root} @emph{ohne Passwort} verbinden und hat alle Berechtigungen.
+
+@item
+@cindex anonymer Benutzer
+Ein anonymer Benutzer wird erzeugt, der mit Datenbanken, die den Namen
+@code{'test'} haben oder mit @code{'test_'} anfangen, alles tun darf.
+Verbindungen müssen vom lokalen Host aus gemacht werden. Das heißt, dass
+sich jeder lokale Benutzer ohne Passwort verbinden kann und als anonymer
+Benutzer behandelt wird.
+
+@item
+Andere Berechtigungen werden verweigert. Beispielsweise können normale
+Benutzer nicht @code{mysqladmin shutdown} oder @code{mysqladmin
+processlist} benutzen.
+@end itemize
+
+@strong{HINWEIS:} Die vorgabemäßigen Berechtigungen sind unter Windows
+anders.
+@xref{Windows running}.
+
+Weil Ihre Installation anfangs weit offen ist, sollten Sie als eins der
+ersten Dinge ein Passwort für den MySQL-@code{root}-Benutzer anlegen. Das
+können Sie wie folgt tun (beachten Sie, dass das Passwort mit der
+@code{PASSWORD()}-Funktion angegeben wird):
+
+@example
+shell> mysql -u root mysql
+mysql> UPDATE user SET Password=PASSWORD('neues_passwort')
+ WHERE user='root';
+mysql> FLUSH PRIVILEGES;
+@end example
+
+Ab MySQL-Version 3.22 können Sie das @code{SET PASSWORD}-Statement
+benutzen:
+
+@example
+shell> mysql -u root mysql
+mysql> SET PASSWORD FOR root=PASSWORD('neues_passwort');
+@end example
+
+Eine weitere Möglichkeit, das Passwort zu setzen, besteht in der Benutzung
+des @code{mysqladmin}-Befehls:
+
+@example
+shell> mysqladmin -u root password neues_passwort
+@end example
+
+Nur Benutzer mit Schreib-/Aktualisierungszugriff auf die
+@code{mysql}-Datenbank können das Passwort für andere Benutzer ändern. Alle
+normalen Benutzer (nicht anonyme Benutzer) können nur ihr eigenes Passwort
+ändern, entweder mit einem der obigen Befehle oder mit @code{SET
+PASSWORD=PASSWORD('neues_passwort')}.
+
+Denken Sie daran, wenn Sie das Passwort in der @code{user}-Tabelle direkt
+mit der ersten Methode ändern, dass Sie den Server anweisen müssen, die
+Berechtigungstabellen neu einzulesen (mit @code{FLUSH PRIVILEGES}), weil
+die Änderungen ansonsten nicht wahrgenommen werden.
+
+Sobald das @code{root}-Passwort gesetzt wurde, müssen Sie in der Folge
+immer das Passwort angeben, wenn Sie sich als @code{root} mit dem Server
+verbinden.
+
+Eventuell wollen Sie das @code{root}-Passwort leer lassen, damit Sie es für
+die weitere Konfiguration oder für Tests nicht angeben müssen. Stellen Sie
+jedoch sicher, dass Sie es setzen, bevor Sie Ihre Installation für irgend
+welche Produktionsaufgaben benutzen.
+
+Sehen Sie im @code{scripts/mysql_install_db}-Skript nach, wie es die
+vorgabemäßigen Berechtigungen installiert. Sie können das als Grundlage
+für das Hinzufügen weiterer Benutzer nehmen.
+
+Wenn Sie wollen, dass die anfänglichen Berechtigungen anders sind als die
+gerade beschriebenen, können Sie @code{mysql_install_db} abändern, bevor
+Sie es benutzen.
+
+@cindex Berechtigungstabellen, neu erzeugen
+@cindex neu erzeugen, Berechtigungstabellen
+Um die Berechtigungstabellen komplett neu zu erzeugen, entfernen Sie alle
+@file{.frm}-, @file{.MYI}- und @file{.MYD}-Dateien im Verzeichnis, das die
+@code{mysql}-Datenbank enthält. (Das ist das Verzeichnis namens
+@file{mysql} unter dem Datenbank-Verzeichnis, was aufgelistet wird, wenn
+Sie @code{mysqld --help} laufen lassen.) Lassen Sie dann das
+@code{mysql_install_db}-Skript laufen, eventuell nachdem Sie es editiert
+haben, um die Berechtigungen zu enthalten, die Sie haben wollen.
+
+@strong{HINWEIS:} Bei MySQL-Versionen vor Version 3.22.10 sollten Sie die
+@file{.frm}-Dateien NICHT löschen. Wenn Sie das versehentlich doch tun,
+müssen Sie sie aus Ihrer MySQL-Distribution zurück kopieren, bevor Sie
+@code{mysql_install_db} laufen lassen.
+
+
+@node Adding users, User resources, Default privileges, User Account Management
+@c German node Benutzer hinzufügen
+@subsection Neue MySQL-Benutzer hinzufügen
+
+@findex GRANT-Statement
+@findex Statements, GRANT
+
+@cindex Berechtigungen, hinzufügen
+@cindex hinzufügen, neue Benutzerberechtigungen
+@cindex Benutzerberechtigungen, hinzufügen
+
+Sie können Benutzer auf zwei Arten hinzufügen: Indem Sie
+@code{GRANT}-Statements verwenden oder indem Sie die
+MySQL-Berechtigungstabellen direkt verändern. Die bevorzugte Methode ist,
+@code{GRANT}-Statements zu benutzen, denn sie sind präziser und weniger
+fehleranfällig. @xref{GRANT}.
+
+Ausserdem gibt es eine Menge von Dritten beigesteuerte Programme wie
+@code{phpmyadmin}, die benutzt werden können, um Benutzer zu erzeugen und
+zu verwalten. @xref{Contrib}.
+
+Die unten stehenden Beispiele zeigen, wie man den @code{mysql}-Client
+benutzt, um neue Benutzer zu erzeugen. Die Beispiele setzen voraus, dass
+Berechtigungen mit den Vorgabewerten eingerichtet wurden, die im vorherigen
+Abschnitt beschrieben wurden. Um also Änderungen machen zu können, müssen
+Sie sich von derselben Maschine aus verbinden, wo @code{mysqld} läuft, und
+Sie müssen sich als MySQL-@code{root}-Benutzer verbinden, und der
+@code{root}-Benutzer muss die @strong{insert}-Berechtigung für die
+@code{mysql}-Datenbank und die @strong{reload}-Verwaltungsberechtigung
+haben. Wenn Sie bereits das @code{root}-Benutzerpasswort geändert haben,
+müssen Sie es für die unten stehenden @code{mysql}-Befehle eingeben.
+
+Sie fügen neue Benutzer mit @code{GRANT}-Statements hinzu:
+
+@example
+shell> mysql --user=root mysql
+mysql> GRANT ALL PRIVILEGES ON *.* TO monty@@localhost
+ IDENTIFIED BY 'ein_passwort' WITH GRANT OPTION;
+mysql> GRANT ALL PRIVILEGES ON *.* TO monty@@"%"
+ IDENTIFIED BY 'ein_passwort' WITH GRANT OPTION;
+mysql> GRANT RELOAD,PROCESS ON *.* TO admin@@localhost;
+mysql> GRANT USAGE ON *.* TO dummy@@localhost;
+@end example
+
+Diese @code{GRANT}-Statements richten drei neue Benutzer ein:
+
+@table @code
+@item monty
+Einen echten Superuser, der sich von irgendwo her mit dem Server verbinden
+kann, aber das Passwort @code{'ein_passwort'} dafür verwenden muss.
+Beachten Sie, dass man @code{GRANT}-Statements sowohl für
+@code{monty@@localhost} als auch für @code{monty@@"%"} verwenden muss. Wenn
+man keinen Eintrag mit @code{localhost} hinzufügt, hat der Eintrag für den
+anonymen Benutzer für @code{localhost} Vorrang, der durch
+@code{mysql_install_db} angelegt wird, wenn man sich vom lokalen Host aus
+verbindet, weil dieser einen spezifischeren @code{Host}-Feldwert hat und
+daher früher in der @code{user}-Tabellen-Sortierreihenfolge auftaucht.
+
+@item admin
+Ein Benutzer, der sich ohne Passwort von @code{localhost} aus verbinden
+kann und der die @strong{reload}- und @strong{process}-
+Verwaltungsberechtigungen hat. Das erlaubt dem Benutzt, die
+@code{mysqladmin reload}-, @code{mysqladmin refresh}- und @code{mysqladmin
+flush-*}-Befehle sowie @code{mysqladmin processlist} auszuführen. Es werden
+keine Datenbank-bezogenen Berechtigungen gewährt. (Diese können später
+gewährt werden, indem zusätzliche @code{GRANT}-Statements ausgeführt
+werden.)
+
+@item dummy
+Ein Benutzer, der sich ohne Passwort verbinden kann, aber nur vom lokalen
+Host aus. Die globalen Berechtigungen sind alle auf @code{'N'} gesetzt -
+diese @code{USAGE}-Berechtigung erlaubt Ihnen, einen Benutzer ohne
+Berechtigungen anzulegen. Es wird angenommen, dass Sie später
+Datenbank-spezifische Berechtigungen gewähren.
+@end table
+
+@findex INSERT-Statement, Grant-Berechtigungen
+@findex Statements, INSERT
+Sie können dieselben Benutzerzugriffsinformationen direkt mittels
+@code{INSERT}-Statements eingeben und dann den Server anweisen, die
+Berechtigungstabellen neu zu laden:
+
+@example
+shell> mysql --user=root mysql
+mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('ein_passwort'),
+ 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+mysql> INSERT INTO user VALUES('%','monty',PASSWORD('ein_passwort'),
+ 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+mysql> INSERT INTO user SET Host='localhost',User='admin',
+ Reload_priv='Y', Process_priv='Y';
+mysql> INSERT INTO user (Host,User,Password)
+ VALUES('localhost','dummy','');
+mysql> FLUSH PRIVILEGES;
+@end example
+
+Abhängig von Ihrer MySQL-Version müssen Sie oben eventuell eine andere
+Anzahl von @code{'Y'}-Werten eingeben (Versionen vor Version 3.22.11 hatten
+weniger Berechtigungsspalten). Beim @code{admin}-Benutzer wird die besser
+lesbare @code{INSERT}-Syntax benutzt, die ab Version 3.22.11 verfügbar ist.
+
+Beachten Sie, dass Sie für die Einrichtung eines Superusers lediglich einen
+@code{user}-Tabelleneintrag mit Berechtigungsfeldern einrichten müssen, die
+auf @code{'Y'} gesetzt sind. Es sind keine @code{db}- oder
+@code{host}-Tabelleneinträge nötig.
+
+The Berechtigungsspalten in der @code{user}-Tabelle wurden im letzten
+@code{INSERT}-Statement nicht explizit gesetzt (für den Benutzer
+@code{dummy}), daher erhalten diese Spalten ihren Vorgabewert von
+@code{'N'}. Das ist dasselbe, was @code{GRANT USAGE} macht.
+
+Das folgende Beispiel fügt einen Benutzer @code{custom} hinzu, der sich von
+@code{localhost}, @code{server.domain} und @code{whitehouse.gov} aus
+verbinden kann. Er will auf die @code{bankkonto}-Datenbank nur von
+@code{localhost} aus zugreifen, auf die @code{spesen}-Datenbank nur von
+@code{whitehouse.gov} aus und auf die @code{kunde}-Datenbank von allen drei
+Hosts aus. Er will von allen drei Hosts aus das Passwort @code{dumm}
+benutzen.
+
+Um die Berechtigungen dieses Benutzers mit @code{GRANT}-Statements
+einzurichten, geben Sie folgende Befehle ein:
+
+@example
+shell> mysql --user=root mysql
+mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
+ ON bankkonto.*
+ TO custom@@localhost
+ IDENTIFIED BY 'dumm';
+mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
+ ON spesen.*
+ TO custom@@whitehouse.gov
+ IDENTIFIED BY 'dumm';
+mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
+ ON kunde.*
+ TO custom@@'%'
+ IDENTIFIED BY 'dumm';
+@end example
+
+Der Grund, warum wir Grant-Statements für den Benutzer 'custom' eingeben,
+ist, dass wir dem Benutzer Zugriff auf MySQL sowohl von der lokalen
+Maschine mit Unix-Sockets als auch von der entfernten Maschine
+'whitehouse.gov' über TCP/IP geben wollen.
+
+Um die Benutzerberechtigungen durch direkte Änderungen an den
+Berechtigungstabellen einzugeben, geben Sie folgende Befehle ein (beachten
+Sie das @code{FLUSH PRIVILEGES} am Ende):
+
+@example
+shell> mysql --user=root mysql
+mysql> INSERT INTO user (Host,User,Password)
+ VALUES('localhost','custom',PASSWORD('dumm'));
+mysql> INSERT INTO user (Host,User,Password)
+ VALUES('server.domain','custom',PASSWORD('dumm'));
+mysql> INSERT INTO user (Host,User,Password)
+ VALUES('whitehouse.gov','custom',PASSWORD('dumm'));
+mysql> INSERT INTO db
+ (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
+ Create_priv,Drop_priv)
+ VALUES
+ ('localhost','bankkonto','custom','Y','Y','Y','Y','Y','Y');
+mysql> INSERT INTO db
+ (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
+ Create_priv,Drop_priv)
+ VALUES
+ ('whitehouse.gov','spesen','custom','Y','Y','Y','Y','Y','Y');
+mysql> INSERT INTO db
+ (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
+ Create_priv,Drop_priv)
+ VALUES('%','kunde','custom','Y','Y','Y','Y','Y','Y');
+mysql> FLUSH PRIVILEGES;
+@end example
+
+Die ersten drei @code{INSERT}-Statements fügen @code{user}-Tabelleneinträge
+hinzu, die dem Benutzer @code{custom} erlauben, sich von den verschiedenen
+Hosts aus mit dem gegebenen Passwort zu verbinden, gewähren ihm aber keine
+Berechtigungen (alle Berechtigungen werden auf den Vorgabewert @code{'N'}
+gesetzt). Die nächsten drei @code{INSERT}-Statements fügen
+@code{db}-Tabelleneinträge hinzu, die @code{custom} Berechtigungen für die
+@code{bankkonto}-, @code{spesen}- und @code{kunde}-Datenbanken gewähren,
+aber nur, wenn auf sie von den korrekten Hosts aus zugegriffen wird. Wie
+immer, wenn die Berechtigungstabellen direkt verändert werden, muss dem
+Server gesagt werden, dass er sie neu laden muss (mit @code{FLUSH
+PRIVILEGES}), damit die Berechtigungsänderungen wirksam werden.
+
+Wenn Sie einem bestimmten Benutzer Zugriff von irgendeiner Maschine in
+einer gegebenen Domäne geben wollen, können Sie ein @code{GRANT}-Statement
+wie das folgende absetzen:
+
+@example
+mysql> GRANT ...
+ ON *.*
+ TO benutzername@@"%.domaene.de"
+ IDENTIFIED BY 'passwort';
+@end example
+
+Um dasselbe durch direkte Änderung der Berechtigungstabellen einzugeben,
+machen Sie folgendes:
+
+@example
+mysql> INSERT INTO user VALUES ('%.domaene.de', 'benutzername',
+ PASSWORD('passwort'),...);
+mysql> FLUSH PRIVILEGES;
+@end example
+
+Sie können auch @code{xmysqladmin}, @code{mysql_webadmin} und sogar
+@code{xmysql} benutzen, um die Werte in den Berechtigungstabellen
+einzufügen, zu ändern und zu aktualisieren. Sie finden diese Werkzeuge unter
+@uref{http://www.mysql.com/downloads/contrib/,Contrib-Verzeichnis der
+MySQL-Website}.
+
+@node User resources, Passwords, Adding users, User Account Management
+@c New section added by arjen 2002-05-17 to keep en/de in sync
+@subsection Limiting user resources
+
+@c FIX Original section text - to be translated.
+@c FIX Also check manual.texi for other mentions of MAX_..._PER_HOUR
+
+Starting from MySQL 4.0.2 one can limit certain resources per user.
+
+So far, the only available method of limiting user usage of MySQL
+server resources has been setting the @code{max_user_connections}
+startup variable to a non-zero value. But this method is strictly
+global and does not allow for management of individual users, which
+could be of paricular interest to Internet Service Providers.
+
+Therefore, management of three resources is introduced on the
+individual user level:
+
+@itemize @bullet
+@item Number of all queries per hour:
+All commands that could be run by a user.
+@item Number of all updates per hour:
+Any command that changes any table or database.
+@item Number of connections made per hour:
+New connections opened per hour.
+@end itemize
+
+A user in the aforementioned context is a single entry in the
+@code{user} table, which is uniquely identified by its @code{user}
+and @code{host} columns.
+
+All users are by default not limited in using the above resources,
+unless the limits are granted to them. These limits can be granted
+@strong{only} via global @code{GRANT (*.*)}, using this syntax:
+
+@example
+GRANT ... WITH MAX_QUERIES_PER_HOUR = N1
+ MAX_UPDATES_PER_HOUR = N2
+ MAX_CONNECTIONS_PER_HOUR = N3;
+@end example
+
+One can specify any combination of the above resources.
+N1, N2 and N3 are integers and stands for count / hour.
+
+If user reaches any of the above limits withing one hour, his
+connection will be terminated or refused and the appropriate error
+message shall be issued.
+
+Current usage values for a particular user can be flushed (set to zero)
+by issuing a @code{GRANT} statement with any of the above clauses,
+including a @code{GRANT} statement with the current values.
+
+Also, current values for all users will be flushed if privileges are
+reloaded (in the server or using @code{mysqladmin reload})
+or if the @code{FLUSH USER_RESOURCES} command is issued.
+
+The feature is enabled as soon as a single user is granted with any
+of the limiting @code{GRANT} clauses.
+
+As a prerequisite for enabling this feature, the @code{user} table in
+the @code{mysql} database must contain the additional columns, as
+defined in the table creation scripts @code{mysql_install_db} and
+@code{mysql_install_db.sh} in @file{scripts} subdirectory.
+
+@node Passwords, Password security, User resources, User Account Management
+@c German node Passwörter
+@subsection Passwörter einrichten
+
+@findex PASSWORD()
+@findex SET PASSWORD Statement
+
+@cindex Passwörter, setzen
+@cindex setzen, Passwörter
+
+In den meisten Fällen sollten Sie @code{GRANT} benutzen, um Ihre Benutzer /
+Passwörter einzurichten, daher trifft das folgende nur für fortgeschrittene
+Benutzer zu. @xref{GRANT, , @code{GRANT}}.
+
+Die Beispiele in den vorherigen Abschnitten erläutern ein wichtiges
+Prinzip: Wenn Sie ein nicht leeres Passwort mit @code{INSERT}- oder
+@code{UPDATE}-Statements setzen, müssen Sie die @code{PASSWORD()}-Funktion
+benutzen, um es zu verschlüsseln. Das liegt daran, dass die
+@code{user}-Tabelle Passwörter in verschlüsselter Form speichert, nicht als
+Klartext. Wenn Sie diese Tatsache vergessen, ist es möglich, dass sie
+Passwörter wie folgt setzen:
+
+@example
+shell> mysql -u root mysql
+mysql> INSERT INTO user (Host,User,Password)
+ VALUES('%','heinzholger','keks');
+mysql> FLUSH PRIVILEGES;
+@end example
+
+Das Ergebnis ist, dass der Klartextwert @code{'keks'} als Passwort in
+der @code{user}-Tabelle gespeichert ist. Wenn der Benutzer @code{heinzholger}
+versucht, sich mittels dieses Passworts mit dem Server zu verbinden,
+verschlüsselt der @code{mysql}-Client es mit @code{PASSWORD()}, erzeugt
+damit einen Authentifikationsvektor, der auf dem @strong{verschlüsselten}
+Passwort und einer Zufallszahl basiert, die er vom Server erhält, und
+schickt das Ergebnis zum Server. Der Server benutzt den
+@code{password}-Wert in der @code{user}-Tabelle (den @strong{nicht
+verschlüsselten} Wert @code{'keks'}), um dieselben Berechnungen
+durchzuführen, und vergleicht die Ergebnisse. Der Vergleich schlägt fehl
+und der Server verweigert die Verbindung:
+
+@example
+shell> mysql -u heinzholger -pkeks test
+Access denied
+@end example
+
+Passwörter müssen verschlüsselt sein, wenn sie in die @code{user}-Tabelle
+eingefügt werden, daher hätte das @code{INSERT}-Statement also wie folgt
+formuliert sein müssen:
+
+@example
+mysql> INSERT INTO user (Host,User,Password)
+ VALUES('%','heinzholger',PASSWORD('keks'));
+@end example
+
+Sie müssen die @code{PASSWORD()}-Funktion auch benutzen, wenn Sie @code{SET
+PASSWORD}-Statements gebrauchen:
+
+@example
+mysql> SET PASSWORD FOR heinzholger@@"%" = PASSWORD('keks');
+@end example
+
+Wenn Sie Passwörter mit dem @code{GRANT ... IDENTIFIED BY}-Statement oder
+dem @code{mysqladmin password}-Befehl setzen, wird die
+@code{PASSWORD()}-Funktion nicht benötigt. Beide sorgen dafür, dass das
+Passwort verschlüsselt wird, daher würden Sie ein Passwort @code{'keks'}
+wie folgt setzen:
+
+@example
+mysql> GRANT USAGE ON *.* TO heinzholger@@"%" IDENTIFIED BY 'keks';
+@end example
+
+oder
+
+@example
+shell> mysqladmin -u heinzholger password keks
+@end example
+
+@strong{NOTE:} @code{PASSWORD()} verschlüsselt Passwörter nicht auf
+dieselbe Art, wie das bei Unix-Passwörtern der Fall ist. Wenn daher Ihr
+Unix-Passwort und Ihr MySQL-Passwort identisch sind, sollten Sie daraus
+nicht schließen, dass @code{PASSWORD()} denselben Verschlüsselungswert
+ergibt wie der, der in der Unix-Passwortdatei gespeichert ist.
+@xref{User names}.
+
+
+@node Password security, , Passwords, User Account Management
+@c German node Passwort-Sicherheit
+@subsection Wie Sie Ihre Passwörter sicher halten
+
+Es ist nicht ratsam, Ihr Passwort so einzugeben, dass es von anderen
+Benutzern entdeckt werden kann. Die verschiedenen Methoden, Passwörter
+bei der Benutzung von Client-Programmen einzugeben, sind unten aufgeführt,
+jeweils mit einer Einschätzung des Risikos der Methode:
+
+@itemize @bullet
+@item
+Geben Sie einem normalen Benutzer nie Zugriff auf die
+@code{mysql.user}-Tabelle. Wenn jemand das verschlüsselte Passwort für
+einen Benutzer kennt, ermöglicht ihm das, sich als dieser Benutzer
+einzuloggen. Die Passwörter sind nur 'zerhackt', so dass niemand das echte
+Passwort sehen können sollte, das Sie benutzen (falls Sie ein ähnliches
+Passwort für Ihre anderen Applikationen benutzen sollten).
+
+@item
+Sie können auf der Kommandozeile die @code{-pyour_pass}- oder
+@code{--password=your_pass}-Option benutzen. Das ist bequem, aber unsicher,
+weil Ihr Passwort für Systemzustandsprogramme (wie @code{ps}) sichtbar
+wird, die möglicherweise von anderen Benutzer aufgerufen werden, um
+Kommandozeilen anzuzeigen. (MySQL-Clients überschreiben typischerweise die
+Kommandozeilenargumente während der Initialisierungssequenz mit Nullen,
+dennoch gibt es einen kurzen Zeitraum, während dessen der Wert sichtbar
+ist.)
+
+@item
+Sie können eine @code{-p}- oder @code{--password}-Option (ohne
+@code{ihr_passwort}-Wert) benutzen. In diesem Fall erbittet das
+Client-Programm das Passwort vom Terminal:
+@findex -p-Option
+@findex -password-Option
+
+@example
+shell> mysql -u benutzername -p
+Enter password: ********
+@end example
+
+Die @samp{*}-Zeichen stehen für Ihr Passwort.
+
+Es ist sicherer, Ihr Passwort auf diese Art einzugeben statt auf der
+Kommandozeile, weil es für andere Benutzer nicht sichtbar wird. Diese
+Methode ist jedoch nur für Programme geeignet, die interaktiv laufen. Wenn
+Sie einen Client von einem Skript aus aufrufen wollen, das nicht interaktiv
+läuft, gibt es keine Möglichkeit, das Passwort vom Terminal aus einzugeben.
+Auf solchen Systemen kann es sogar vorkommen, dass die erste Zeile Ihres
+Skripts gelesen und (fälschlicherweise) als Ihr Passwort interpretiert
+wird!
+
+@item
+@tindex .my.cnf-Datei
+Sie können Ihr Passwort in einer Konfigurationsdatei speichern.
+Beispielsweise können Sie Ihr Passwort im @code{[client]}-Abschnitt der
+@file{.my.cnf}-Datei in Ihrem Heimatverzeichnis aufführen:
+
+@example
+[client]
+password=ihr_passwort
+@end example
+
+Wenn Sie Ihr Passwort in @file{.my.cnf} speichern, sollte die Datei nicht
+für die Gruppe (group) lesbar oder schreibbar sein. Stellen Sie sicher,
+dass der Zugriffsmodus der Datei @code{400} oder @code{600} ist.
+
+@xref{Option files}.
+@item
+Sie können Ihr Passwort in der @code{MYSQL_PWD}-Umgebungsvariablen
+speichern, aber diese Methode wird als extrem unsicher erachtet und sollte
+nicht gewählt werden. Einige Versionen von @code{ps} beinhalten eine
+Option, die Umgebung laufender Prozesse anzeigen zu lassen; Ihr Passwort
+würde dann für alle im Klartext lesbar sein, wenn Sie @code{MYSQL_PWD}
+setzen. Selbst auf Systemen ohne eine solche Version von @code{ps} ist es
+nicht ratsam, anzunehmen, dass es keine andere Methode gibt,
+Prozessumgebungen einzusehen. @xref{Environment variables}.
+@end itemize
+
+Alles in allem sind die sichersten Methoden, das Passwort entweder durch
+Client-Programm entgegen nehmen zu lassen oder es in einer sauber
+abgesicherten @file{.my.cnf}-Datei einzugeben.
+
+
+@node Disaster Prevention, Database Administration, User Account Management, MySQL Database Administration
+@c German node Katastrophenschutz und Wiederherstellung
+@section Katastrophenschutz und Wiederherstellung
+
+
+
+@menu
+* Backup::
+* BACKUP TABLE::
+* RESTORE TABLE::
+* CHECK TABLE::
+* REPAIR TABLE::
+* Table maintenance::
+* Maintenance regimen::
+* Table-info::
+@end menu
+
+@node Backup, BACKUP TABLE, Disaster Prevention, Disaster Prevention
+@c German node Datensicherung
+@subsection Datenbank-Datensicherungen
+
+@cindex Datenbanken, Datensicherungen
+@cindex Datensicherungen
+
+Weil MySQL-Tabellen als Dateien gespeichert werden, ist es leicht, eine
+Datensicherung durchzuführen. Um eine konsistente Datensicherung zu
+erhalten, machen Sie ein @code{LOCK TABLES} auf die relevanten Tabellen,
+gefolgt von @code{FLUSH TABLES} für die Tabellen.
+@xref{LOCK TABLES, , @code{LOCK TABLES}}.
+@xref{FLUSH, , @code{FLUSH}}.
+Sie brauchen lediglich eine Lesesperre (Read Lock); das erlaubt anderen
+Threads, die Tabellen weiterhin abzufragen, während Sie eine Kopie der
+Dateien im Datenbank-Verzeichnis machen. @code{FLUSH TABLE} wird benötigt,
+um sicherzustellen, dass alle aktiven Indexseiten auf Platte zurück
+geschrieben werden, bevor Sie die Datensicherung beginnen.
+
+Wenn Sie eine Tabellensicherung auf SQL-Ebene machen wollen, können Sie
+@code{SELECT INTO OUTFILE} oder @code{BACKUP TABLE} benutzen.
+@xref{SELECT}. @xref{BACKUP TABLE}.
+
+Eine weitere Möglichkeit, eine Datenbank zu sichern, stellt die Benutzung
+des @code{mysqldump}-Programms oder des @code{mysqlhotcopy-Skript}s dar.
+@xref{mysqldump, , @code{mysqldump}}. @xref{mysqlhotcopy, ,
+@code{mysqlhotcopy}}.
+
+@enumerate
+@item
+Machen Sie eine komplette Sicherung Ihrer Datenbanken:
+
+@example
+shell> mysqldump --tab=/pfad/zum/verzeichnis/ --opt --full
+
+or
+
+shell> mysqlhotcopy Datenbank /pfad/zum/verzeichnis/
+@end example
+
+Sie können auch einfach alle Tabellendateien (@file{*.frm}-, @file{*.MYD}-
+und @file{*.MYI}-Dateien) kopieren, solange der Server nicht gerade etwas
+aktualisiert. Das Skript @code{mysqlhotcopy} benutzt diese Methode.
+
+@item
+@cindex Log-Dateien, Namen
+Halten Sie @code{mysqld} an, wenn er läuft, und starten Sie ihn mit der
+@code{--log-update[=datei]}-Option. @xref{Update log}. Die
+Update-Log-Datei(en) gibt Ihnen die Information, die Sie dafür benötigen,
+um Änderungen an der Datenbank zu replizieren, die ab dem Zeitpunkt
+durchgeführt wurden, als Sie @code{mysqldump} ausführten.
+@end enumerate
+
+Wenn Sie etwas wiederherstellen müssen, versuchen Sie zunächst, Ihre
+Tabellen mit @code{REPAIR TABLE} oder @code{myisamchk -r} wieder
+herzustellen. Das sollte in 99,9% aller Fälle funktionieren. Wenn
+@code{myisamchk} fehlschlägt, probieren Sie folgende Prozedur (das
+funktioniert nur, wenn Sie MySQL mit @code{--log-update} gestartet haben.
+@xref{Update log}.):
+
+@enumerate
+@item
+Stellen Sie die originale @code{mysqldump}-Datensicherung wieder her.
+@item
+Führen Sie folgenden Befehl aus, um die Aktualisierungen (Updates) im
+Binär-Log noch einmal laufen zu lassen:
+
+@example
+shell> mysqlbinlog hostname-bin.[0-9]* | mysql
+@end example
+
+Wenn Sie das Update-Log benutzen, können Sie folgendes machen:
+
+@example
+shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
+@end example
+@end enumerate
+
+@code{ls} wird benutzt, um alle Update-Log-Dateien in der richtigen
+Reihenfolge zu erhalten.
+
+Mit @code{SELECT * INTO OUTFILE 'datei' FROM tabelle} können Sie auch
+selektive Datensicherungen herstellen und diese wieder herstellen mit
+@code{LOAD DATA INFILE 'datei' REPLACE ...}. Um Duplikate zu vermeiden,
+benötigen Sie einen Primärschlüssel (@code{PRIMARY KEY}) oder einen
+eindeutigen Schlüssel (@code{UNIQUE}) in der Tabelle. Das Schlüsselwort
+@code{REPLACE} führt dazu, dass alte Datensätze durch neue ersetzt werden,
+wenn ein neuer Datensatz einen alten auf einem eindeutigen Schlüsselwert
+duplizieren würde.
+
+Wenn Sie bei der Datensicherung auf Ihrem System Performance-Probleme
+bekommen, können Sie diese lösen, indem Sie Replikation einrichten und die
+Datensicherungen auf dem Slave statt auf dem Master durchführen.
+@xref{Replication Intro}.
+
+Wenn Sie ein Veritas-Dateisystem benutzen, können Sie folgendes tun:
+
+@enumerate
+@item
+Führen Sie einen Client- (Perl ?) @code{FLUSH TABLES mit READ LOCK} aus.
+
+@item
+Forken Sie eine Shell oder führen Sie einen anderen Client aus @code{mount
+vxfs snapshot}.
+
+@item
+Führen Sie im ersten Client @code{UNLOCK TABLES} aus.
+
+@item
+Kopieren Sie die Dateien von snapshot
+
+@item
+Unmounten Sie snapshot
+@end enumerate
+
+
+@node BACKUP TABLE, RESTORE TABLE, Backup, Disaster Prevention
+@c German node BACKUP TABLE
+@subsection @code{BACKUP TABLE}-Syntax
+
+@findex BACKUP TABLE
+
+@cindex Datensicherungen, Datenbank
+
+@example
+BACKUP TABLE tabelle[,tabelle...] TO '/pfad/zum/backup/verzeichnis'
+@end example
+
+Machen Sie eine Kopie aller Tabellendateien ins Datensicherungsverzeichnis,
+was die Mindestanforderung für die Wiederherstellung darstellt. Momentan
+funktioniert das nur bei @code{MyISAM}-Tabellen. Bei @code{MyISAM}-Tabellen
+kopiert man @code{.frm}- (Definition) und @code{.MYD}- (Daten) Dateien. Die
+Indexdatei kann aus diesen beiden aufgebaut werden.
+
+@c German FIX changed @xref to @ref
+Bevor Sie diesen Befehl ausführen, sehen Sie bitte unter
+@ref{Backup} nach.
+
+Während der Datensicherung gilt eine Lesesperre (Read Lock) für jede
+Tabelle, eine nach der anderen, während sie gesichert werden. Wenn Sie
+mehrere Tabellen als Schnappschuss sichern wollen, müssen Sie zuerst ein
+@code{LOCK TABLES} ausführen, das eine Lesesperre für jede Tabelle in der
+zu sichernden Gruppe enthält.
+
+Der Befehl gibt eine Tabelle mit folgenden Spalten zurück:
+
+@multitable @columnfractions .35 .65
+@item @strong{Spalte} @tab @strong{Wert}
+@item Table @tab Tabellenname
+@item Op @tab Immer ``backup''
+@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
+@item Msg_text @tab Die Meldung.
+@end multitable
+
+Beachten Sie, dass @code{BACKUP TABLE} erst ab MySQL 3.23.25 verfügbar ist.
+
+
+@node RESTORE TABLE, CHECK TABLE, BACKUP TABLE, Disaster Prevention
+@c German node RESTORE TABLE
+@subsection @code{RESTORE TABLE}-Syntax
+
+@findex RESTORE TABLE
+
+@example
+RESTORE TABLE tabelle[,tabelle...] FROM '/pfad/zum/backup/verzeichnis'
+@end example
+
+Stellt die Tabelle(n) aus der Datensicherung her, die mit @code{BACKUP
+TABLE} gesichert wurde(n). Bestehende Tabellen werden nicht überschrieben;
+wenn Sie über bestehende Tabellen wiederherstellen wollen, erhalten Sie
+eine Fehlermeldung. RESTORE benötigt länger als Datensicherung, weil der Index neu
+aufgebaut werden muss. Je mehr Schlüssel Sie haben, desto länger dauert es.
+Genau wie @code{BACKUP TABLE} funktioniert RESTORE momentan nur mit
+@code{MyISAM}-Tabellen.
+
+
+Der Befehl gibt eine Tabelle mit folgenden Spalten zurück:
+
+@multitable @columnfractions .35 .65
+@item @strong{Spalte} @tab @strong{Wert}
+@item Table @tab Tabellenname
+@item Op @tab Immer ``restore''
+@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
+@item Msg_text @tab Die Meldung.
+@end multitable
+
+
+@node CHECK TABLE, REPAIR TABLE, RESTORE TABLE, Disaster Prevention
+@c German node CHECK TABLE
+@subsection @code{CHECK TABLE}-Syntax
+
+@findex CHECK TABLE
+
+@example
+CHECK TABLE tabelle[,tabelle...] [option [option...]]
+
+option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
+@end example
+
+@code{CHECK TABLE} funktioniert nur bei @code{MyISAM}-Tabellen. Bei
+@code{MyISAM}-Tabellen ist es dasselbe, wie @code{myisamchk -m tabelle}
+über die Tabelle laufen zu lassen.
+
+Wenn Sie keine Option angeben, wird @code{MEDIUM} benutzt.
+
+Prüft die Tabelle(n) auf Fehler. Bei @code{MyISAM}-Tabellen werden die
+Schlüssel-Statistiken aktualisiert. Der Befehl gibt eine Tabelle mit
+folgenden Spalten zurück:
+
+@multitable @columnfractions .35 .65
+@item @strong{Spalte} @tab @strong{Wert}
+@item Table @tab Tabellenname
+@item Op @tab Immer ``check''.
+@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
+@item Msg_text @tab Die Meldung.
+@end multitable
+
+Beachten Sie, dass Sie viele Zeilen an Information für jede geprüfte
+Tabelle erhalten. Die letzte Zeile enthält den @code{Msg_type status} und
+sollte normalerweise @code{OK} sein. Wenn Sie nicht @code{OK} erhalten, oder @code{Not
+checked}, sollten Sie im Normalfall eine Reparatur der Tabelle durchführen.
+@xref{Table maintenance}. @code{Not checked} bedeutet, dass bei der Tabelle
+der angegebene @code{TYPE} MySQL mitgeteilt hat, dass es keinerlei
+Notwendigkeit gab, die Tabelle zu prüfen.
+
+Die unterschiedlichen Prüfoptionen stehen für folgendes:
+
+@multitable @columnfractions .20 .80
+@item @strong{Option} @tab @strong{Bedeutung}
+@item @code{QUICK} @tab Keine Zeilen nach falschen Verknüpfungen (Links) durchsehen (scannen).
+@item @code{FAST} @tab Nur Tabellen prüfen, die nicht ordnungsgemäß geschlossen wurden.
+@item @code{CHANGED} @tab Nur Tabellen prüfen, die seit der letzten Prüfung geändert wurden oder die nicht ordnungsgemäß geschlossen wurden.
+@item @code{MEDIUM} @tab Zeilen durchsehen (scannen), um zu bestätigen, dass gelöschte Verknüpfungen (Links) in Ordnung sind. Diese Option berechnet auch eine Schlüssel-Prüfsumme für die Zeilen und bestätigt diese mit einer berechneten Prüfsumme für die Schlüssel.
+@item @code{EXTENDED} @tab Schlägt komplett alle Schlüssel für jede Zeile nach (Lookup). Hierdurch wird sichergestellt, dass die Tabelle 100% konsistent ist, aber das benötigt lange Zeit!
+@end multitable
+
+Bei @code{MyISAM}-Tabellen dynamischer Größe führt eine Prüfung immer
+eine @code{MEDIUM}-Prüfung durch. Bei Zeilen statischer Länge wird das
+Durchsehen (Scan) der Zeilen durch @code{QUICK} und @code{FAST}
+übersprungen, weil solche Zeilen sehr selten beschädigt sind.
+
+Sie können Prüfoptionen wie folgt kombinieren:
+
+@example
+CHECK TABLE test_tabelle FAST QUICK;
+@end example
+
+Das würde nur eine QUICK-Prüfung der Tabelle durchführen, wenn diese nicht
+ordnungsgemäß geschlossen worden wäre.
+
+@strong{HINWEIS:} In einigen Fällen kann @code{CHECK TABLE} zu einer
+Änderung der Tabelle führen! Das geschieht, wenn die Tabelle als
+'beschädigt' oder 'nicht ordnungsgemäß geschlossen' gekennzeichnet ist,
+aber @code{CHECK TABLE} keine Probleme in der Tabelle gefunden hat. In
+diesem Fall kennzeichnet @code{CHECK TABLE} die Tabelle als in Ordnung.
+
+Wenn eine Tabelle beschädigt ist, liegt das Problem höchst wahrscheinlich
+in den Indexen und nicht im Daten-Teil. Alle oben genannten Prüfoptionen
+prüfen die Indexe gründlich und sollten daher die meisten Fehler finden.
+
+Wenn Sie lediglich eine Tabelle prüfen wollen, von der Sie annehmen, dass
+sie in Ordnung ist, sollten Sie keine Prüfoptionen oder die
+@code{QUICK}-Option angeben. Letztere sollte benutzt werden, wenn Sie es
+eilig haben und das sehr geringe Risiko auf sich nehmen können, dass
+@code{QUICK} keinen Fehler in der Daten-Datei findet. (In den meisten Fällen
+sollte MySQL bei normalem Gebrauch jeden Fehler in der Daten-Datei finden.
+Wenn das geschieht, wird die Tabelle als 'beschädigt' gekennzeichnet, was
+bedeutet, dass die Tabelle solange nicht benutzt werden kann, bis sie
+repariert ist.)
+
+@code{FAST} und @code{CHANGED} sind in erster Linie für die Benutzung durch
+ein Skript vorgesehen (zum Beispiel für die Ausführung durch cron), wenn
+Sie Ihre Tabellen von Zeit zu Zeit prüfen wollen. Für die meisten
+Anwendungsfälle sollte man @code{FAST} vor @code{CHANGED} bevorzugen. (Der
+einzige Fall, wo das nicht so ist, ist, wenn Sie vermuten, einen Bug im
+@code{MyISAM}-Code gefunden zu haben.)
+
+@code{EXTENDED} ist nur für den Fall vorgesehen, dass Sie eine normale
+Prüfung haben durchlaufen lassen, aber immer noch seltsame Fehler von einer
+Tabelle erhalten, wenn MySQL versucht, eine Zeile zu aktualisieren oder
+eine Zeile über einen Schlüssel zu finden (das ist sehr unwahrscheinlich,
+wenn eine normale Prüfung durchgelaufen ist!).
+
+Es wurde berichtet, dass bei der Tabellenprüfung einige Dinge nicht
+automatisch korrigiert werden können:
+
+@itemize @bullet
+@item
+@code{Found row where the auto_increment column has the value 0}.
+
+Das bedeutet, dass es in der Tabelle eine Zeile gibt, in der die
+@code{auto_increment}-Index-Spalte den Wert 0 enthält. (Es ist möglich,
+eine Zeile zu erzeugen, in der die auto_increment-Spalte 0 ist, indem man
+die Spalte explizit mit einem @code{UPDATE}-Statement auf 0 setzt.)
+
+Das ist für sich genommen kein Fehler, kann aber Probleme verursachen, wenn
+Sie die Tabelle dumpen und dann wiederherstellen, oder ein @code{ALTER
+TABLE} auf die Tabelle machen. In diesen Fällen ändert sich der Wert der
+auto_increment-Spalte gemäß den Regeln für auto_increment-Spalten, was
+Probleme wie doppelte Schlüsseleintragsfehler bringen könnte.
+
+Um diese Warnmeldung loszuwerden, führen Sie einfach ein
+@code{UPDATE}-Statement durch und setzen die Spalte auf irgend einen
+anderen Wert als 0.
+@end itemize
+
+
+@node REPAIR TABLE, Table maintenance, CHECK TABLE, Disaster Prevention
+@c German node REPAIR TABLE
+@subsection @code{REPAIR TABLE}-Syntax
+
+@findex REPAIR TABLE
+
+@example
+REPAIR TABLE tabelle[,tabelle...] [QUICK] [EXTENDED]
+@end example
+
+@code{REPAIR TABLE} funktioniert nur bei @code{MyISAM}-Tabellen und ist
+dasselbe, wie @code{myisamchk -r tabelle} auf die Tabelle auszuführen.
+
+Normalerweise sollten sie diesen Befehl nie ausführen müssen, aber wenn ein
+Unglück passiert, ist es sehr wahrscheinlich, dass Sie alle Daten einer
+MyISAM-Tabelle mit @code{REPAIR TABLE} retten können. Wenn Ihre Tabellen
+häufig beschädigt werden, sollten Sie versuchen, den Grund hierfür
+herauszufinden! @xref{Crashing}. @xref{MyISAM table problems}.
+
+@code{REPAIR TABLE} repariert eine möglicherweise beschädigte Tabelle. Der
+Befehl gibt eine Tabelle mit folgenden Spalten zurück:
+
+@multitable @columnfractions .35 .65
+@item @strong{Spalte} @tab @strong{Wert}
+@item Table @tab Tabellenname
+@item Op @tab Immer ``repair''
+@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
+@item Msg_text @tab Die Meldung.
+@end multitable
+
+Beachten Sie, dass Sie viele Zeilen an Informationen für jede reparierte
+Tabelle erhalten. Die letzte Zeile enthält den @code{Msg_type status} und
+sollte normalerweise @code{OK} sein. Wenn Sie nicht @code{OK} erhalten,
+sollten Sie versuchen, die Tabelle mit @code{myisamchk -o} zu reparieren,
+weil @code{REPAIR TABLE} noch nicht alle Optionen von @code{myisamchk}
+enthält. In naher Zukunft werden wir das flexibler gestalten.
+
+Wenn @code{QUICK} angegeben wird, versucht MySQL lediglich ein
+@code{REPAIR} des Indexbaums.
+
+Wenn Sie @code{EXTENDED} benutzen, erzeugt MySQL den Index Zeile für Zeile,
+anstatt einen Index auf einmal durch Sortieren zu erzeugen. Das kann bei
+Schlüsseln fester Länge besser sein, wenn Sie lange @code{char()}-Schlüssel
+haben, die sich gut komprimieren lassen.
+
+
+@node Table maintenance, Maintenance regimen, REPAIR TABLE, Disaster Prevention
+@c German node Tabellenwartung
+@subsection Benutzung von @code{myisamchk} für Tabellenwartung und Absturzreparatur
+
+Ab MySQL-Version 3.23.13 können Sie MyISAM-Tabellen mit dem @code{CHECK
+TABLE}-Befehl überprüfen. @xref{CHECK TABLE}. Mit dem @code{REPAIR
+TABLE}-Befehl können Sie Tabellen reparieren. @xref{REPAIR TABLE}.
+
+Um MyISAM-Tabellen (@code{.MYI} und @code{.MYD}) zu überprüfen und / oder
+zu reparieren, sollten sie das @code{myisamchk}-Dienstprogramm benutzen. Um
+ISAM-Tabellen (@code{.ISM} und @code{.ISD}) zu überprüfen und / oder zu
+reparieren, sollten Sie das @code{isamchk}-Dienstprogramm benutzen.
+@xref{Table types}.
+
+Der folgende Text behandelt @code{myisamchk}, trifft aber voll umfänglich
+auch auf das alte @code{isamchk} zu.
+
+Sie können das @code{myisamchk}-Dienstprogramm benutzen, um Informationen über
+Ihre Datenbanktabellen zu erhalten, sie zu prüfen und zu reparieren, oder
+um sie zu optimieren. Die folgenden Abschnitte beschreiben, wie man
+@code{myisamchk} aufruft (inklusive einer Beschreibung seiner Optionen),
+wie man einen Wartungsplan für Tabellen erstellt und wie die
+unterschiedlichen Funktionen von @code{myisamchk} benutzt werden.
+
+In den meisten Fällen können Sie auch den Befehl @code{OPTIMIZE TABLES}
+benutzen, um Tabellen zu optimieren und zu reparieren, aber dieser ist
+nicht so schnell und (in Fall wirklich schwerer Fehler) nicht so
+zuverlässig wie @code{myisamchk}.
+Auf der anderen Seite ist @code{OPTIMIZE TABLE} leichter zu benutzen, und
+Sie brauchen sich nicht um das Flushen von Tabellen zu kümmern.
+@xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.
+
+Obwohl das Reparieren bei @code{myisamchk} recht sicher ist, ist es immer
+eine gute Idee, eine Datensicherung zu machen, bevor eine Reparatur
+durchgeführt wird (oder etwas Sonstiges, das viele Änderungen an einer
+Tabelle durchführt).
+
+
+
+@menu
+* myisamchk syntax::
+* myisamchk general options::
+* myisamchk check options::
+* myisamchk repair options::
+* myisamchk other options::
+* myisamchk memory::
+* Crash recovery::
+* Check::
+* Repair::
+* Optimisation::
+@end menu
+
+@node myisamchk syntax, myisamchk general options, Table maintenance, Table maintenance
+@c German node myisamchk-Syntax
+@subsubsection Aufrufsyntax von @code{myisamchk}
+
+@code{myisamchk} wird wie folgt aufgerufen:
+
+@example
+shell> myisamchk [optionen] tabelle
+@end example
+
+@code{optionen} legt fest, was @code{myisamchk} tun soll. Die Optionen sind
+unten beschrieben. (Sie erhalten eine Liste der Optionen, wenn Sie
+@code{myisamchk --help} eingeben.) Ohne Optionen aufgerufen prüft
+@code{myisamchk} einfach nur Ihre Tabelle. Um mehr Informationen zu
+erhalten oder @code{myisamchk} anzuweisen, korrigierende Aktionen
+durchzuführen, geben Sie Optionen wie unten und in den folgenden
+Abschnitten beschrieben an.
+
+@code{tabelle} ist die Datenbanktabelle, die Sie prüfen oder reparieren
+wollen. Wenn Sie @code{myisamchk} anderswo als im Datenbank-Verzeichnis
+ausführen, müssen Sie den Pfad zur Datei angeben, denn @code{myisamchk}
+weiß nicht, wo Ihre Datenbank liegt. In der Tat kümmert sich
+@code{myisamchk} nicht darum, ob die Dateien, die es bearbeiten soll, in
+einem Datenbank-Verzeichnis liegen oder nicht; sie können diese Dateien
+daher an eine andere Stelle kopieren und die Wiederherstellungsoperationen
+dort durchführen.
+
+Sie können in der @code{myisamchk}-Befehlszeile mehrere Tabellen angeben,
+wenn Sie wollen. Sie können auch einen Namen als Indexdateinamen angeben
+(mit dem Suffix @file{.MYI}), was Ihnen gestattet, alle Tabellen in einem
+Verzeichnis anzugeben, indem Sie das Muster @file{*.MYI} benutzen. Wenn Sie
+zum Beispiel in einem Datenbank-Verzeichnis sind, können Sie alle Tabellen
+im Verzeichnis wie folgt prüfen:
+
+@example
+shell> myisamchk *.MYI
+@end example
+
+Wenn Sie nicht im Datenbank-Verzeichnis sind, können Sie alle dortigen
+Tabellen prüfen, indem Sie den Pfad zum Verzeichnis angeben:
+
+@example
+shell> myisamchk /pfad/zum/datenbank_verzeichnis/*.MYI
+@end example
+
+Sie können sogar alle Tabellen in allen Datenbanken prüfen, indem Sie einen
+Platzhalter im Pfad zum MySQL-Daten-Verzeichnis angeben:
+
+@example
+shell> myisamchk /pfad/zum/datadir/*/*.MYI
+@end example
+
+Um schnell alle Tabellen zu prüfen, wird folgender Befehl empfohlen:
+
+@example
+myisamchk --silent --fast /pfad/zum/datadir/*/*.MYI
+isamchk --silent /pfad/zum/datadir/*/*.ISM
+@end example
+
+Wenn Sie alle Tabellen prüfen und alle Tabellen reparieren wollen, die
+beschädigt sind, können Sie folgende Kommandozeile eingeben:
+
+@example
+myisamchk --silent --force --fast --update-state -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M /pfad/zum/datadir/*/*.MYI
+isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M /pfad/zum/datadir/*/*.ISM
+@end example
+
+Hierbei wird angenommen, dass Sie mehr als 64 MB Arbeitsspeicher frei
+haben.
+
+Wenn Sie einen Fehler wie den folgenden erhalten:
+
+@example
+myisamchk: warning: 1 clients is using oder hasn't closed the table properly
+@end example
+
+Bedeutet das, dass Sie versuchen, eine Tabelle zu überprüfen, die durch ein
+anderes Programm aktualisiert wurde (wie dem @code{mysqld}-Server), das die
+Datei noch nicht geschlossen hat oder das abgestürzt ist, ohne die Datei
+ordnungsgemäß zu schließen.
+
+Wenn @code{mysqld} läuft, müssen Sie ein Sync/Schließen aller Tabellen mit
+@code{FLUSH TABLES} erzwingen und sicherstellen, dass niemand die Tabellen
+benutzt, während Sie @code{myisamchk} laufen lassen. In MySQL-Version 3.23
+ist die einfachste Möglichkeit, dieses Problem zu vermeiden, die Benutzung
+von @code{CHECK TABLE} anstelle von @code{myisamchk}.
+
+
+
+@node myisamchk general options, myisamchk check options, myisamchk syntax, Table maintenance
+@c German node Allgemeine Optionen für myisamchk
+@subsubsection Allgemeine Optionen für @code{myisamchk}
+
+@cindex Optionen, @code{myisamchk}
+@cindex @code{myisamchk}, Optionen
+
+@code{myisamchk} unterstützt folgende Optionen:
+
+@table @code
+@item -# oder --debug=debug_optionen
+Ausgabe eines Debug-Logs. Die Zeichenkette @code{debug_optionen} ist häufig
+@code{'d:t:o,dateiname'}.
+@item -? oder --help
+Hilfetext ausgeben und beenden.
+@item -O var=option, --set-variable var=option
+Setzt den Wert einer Variablen. Mögliche Variablen und ihre Vorgabewerte
+für myisamchk können mit @code{myisamchk --help} herausgefunden werden:
+@multitable @columnfractions .3 .7
+@item key_buffer_size @tab 523264
+@item read_buffer_size @tab 262136
+@item write_buffer_size @tab 262136
+@item sort_buffer_size @tab 2097144
+@item sort_key_blocks @tab 16
+@item decode_bits @tab 9
+@end multitable
+
+@code{sort_buffer_size} wird benutzt, wenn Schlüssel repariert werden,
+indem Schlüssel sortiert werden, was der Normalfall ist, wenn Sie
+@code{--recover} benutzen.
+
+@code{key_buffer_size} wird benutzt, wenn Sie die Tabelle mit
+@code{--extended-check} prüfen oder wenn die Schlüssel repariert werden,
+indem Schlüssel Zeile für Zeile in die Tabelle eingefügt werden (als wenn
+normale Einfügeoperationen (Insert) durchgeführt werden). Eine Reparatur
+mittels Key-Buffer (Schlüsselpuffer) wird in folgenden Fällen benutzt:
+
+@itemize @bullet
+@item
+Wenn Sie @code{--safe-recover} benutzen.
+@item
+Wenn die temporären Dateien, die benötigt werden, um die Schlüssel zu
+sortieren, mehr als zweimal so Groß werden würden, als wenn die
+Schlüsseldatei direkt erzeugt würde. Das ist oft dann der Fall, wenn Sie
+große @code{CHAR}-, @code{VARCHAR}- oder @code{TEXT}-Schlüssel haben, weil
+das Sortieren die gesamten Schlüssel während des Sortierens speichern muss.
+Wenn Sie viel temporären Platz haben und @code{myisamchk} zwingen können,
+mittels Sortieren zu reparieren, können Sie die
+@code{--sort-recover}-Option benutzen.
+@end itemize
+
+Die Reparatur durch den Key-Buffer (Schlüsselpuffer) nimmt weit weniger
+Plattenplatz in Anspruch als wenn Sortieren benutzt wird, ist aber auch
+viel langsamer.
+
+Wenn Sie eine schnellere Reparatur wollen, setzen Sie die obigen Variablen
+auf ungefähr 1/4 Ihres verfügbaren Arbeitsspeichers. Sie können beide
+Variablen auf große Werte setzen, weil nur einer der oben aufgeführten
+Puffer zur gleichen Zeit benutzt wird.
+
+@item -s oder --silent
+Schweigsamer Modus. Ausgaben erfolgen nur im Fehlerfall. Sie können
+@code{-s} doppelt benutzen (@code{-ss}), um @code{myisamchk} sehr
+schweigsam zu machen.
+@item -v oder --verbose
+Geschwätziger Modus. Es werden mehr Informationen ausgegeben. Dies kann
+auch bei @code{-d} und @code{-e} benutzt werden. Benutzen Sie @code{-v}
+mehrfach (@code{-vv}, @code{-vvv}), um noch ausführlichere Meldungen
+auszugeben!
+@item -V oder --version
+Die aktuelle Version von @code{myisamchk} ausgeben und beenden.
+@item -w or, --wait
+Statt einen Fehler auszugeben, wenn die Tabelle gesperrt ist, warten, bis
+die Tabelle entsperrt ist, bevor fortgefahren wird. Beachten Sie: Wenn Sie
+@code{mysqld} auf der Tabelle mit @code{--skip-locking} laufen lassen, kann
+die Tabelle nur mit einem weiteren @code{myisamchk}-Befehl gesperrt werden.
+@end table
+
+
+@node myisamchk check options, myisamchk repair options, myisamchk general options, Table maintenance
+@c German node Prüfoptionen für myisamchk
+@subsubsection Prüfoptionen für @code{myisamchk}
+
+@cindex Prüfoptionen, myisamchk
+@cindex Tabellen, prüfen
+
+@table @code
+@item -c oder --check
+Tabelle auf Fehler überprüfen. Das ist die vorgabemäßige Operation, wenn
+Sie @code{myisamchk} keine sonstigen Optionen angeben, die dies
+überschreiben.
+
+@item -e oder --extend-check
+Tabelle SEHR gründlich prüfen (was recht langsam ist, wenn Sie viele Indexe
+haben). Diese Option sollte nur in Extremfällen benutzt werden.
+Normalerweise sollten @code{myisamchk} oder @code{myisamchk --medium-check}
+in fast allen Fällen in der Lage sein, herauszufinden, ob es in der Tabelle
+irgend welche Fehler gibt.
+
+Wenn Sie @code{--extended-check} benutzen und viel Arbeitsspeicher haben,
+setzen Sie den Wert von @code{key_buffer_size} um etliches herauf!
+
+@item -F oder --fast
+Nur Tabellen prüfen, die nicht ordnungsgemäß geschlossen wurden.
+@item -C oder --check-only-changed
+Nur Tabellen prüfen, die seit der letzten Prüfung geändert wurden.
+@item -f oder --force
+@code{myisamchk} mit @code{-r} (repair) auf die Tabelle neu starten, wenn
+@code{myisamchk} in der Tabelle irgend welche Fehler findet.
+@item -i oder --information
+Statistische Informationen über die Tabelle, die geprüft wird, ausgeben.
+@item -m oder --medium-check
+Schneller als extended-check, findet aber nur 99,99% aller Fehler. Das
+sollte allerdings in den meisten Fällen ausreichen.
+@item -U oder --update-state
+In der @file{.MYI}-Datei speichern, wann die Tabelle geprüft wurde und ob
+die Tabelle beschädigt wurde. Das sollte benutzt werden, um vollen Nutzen
+aus der @code{--check-only-changed}-Option ziehen zu können. Sie sollten
+diese Option nicht benutzen, wenn der @code{mysqld}-Server die Tabelle
+benutzt und Sie ihn mit @code{--skip-locking} laufen lassen.
+@item -T oder --read-only
+Die Tabelle nicht als geprüft kennzeichnen. Das ist hilfreich, wenn Sie
+@code{myisamchk} benutzen, um eine Tabelle zu prüfen, die von irgend einer
+anderen Applikation benutzt wird, die kein Sperren durchführt (wie
+@code{mysqld --skip-locking}).
+@end table
+
+
+@node myisamchk repair options, myisamchk other options, myisamchk check options, Table maintenance
+@c German node Reparaturoptionen für myisamchk
+@subsubsection Reparaturoptionen für @code{myisamchk}
+
+@cindex Reparaturoptionen, myisamchk
+@cindex Dateien, reparieren
+
+Folgende Optionen werden benutzt, wenn Sie @code{myisamchk} mit @code{-r}
+oder @code{-o} starten:
+
+@table @code
+@item -D # oder --data-file-length=#
+Maximale Länge der Daten-Datei (wenn die Daten-Datei neu erzeugt wird, wenn
+sie 'voll' ist).
+@item -e oder --extend-check
+Es wird versucht, jede mögliche Zeile der Daten-Datei wiederherzustellen.
+Normalerweise wird dies auch eine Menge Zeilen-'Müll' finden. Benutzen Sie
+diese Option nur dann, wenn Sie völlig verzweifelt sind.
+@item -f oder --force
+Alte temporäre Dateien (@code{tabelle.TMD}) werden überschrieben, anstatt
+abzubrechen.
+@item -k # oder keys-used=#
+Wenn Sie ISAM benutzen, weist das den ISAM-Tabellen-Handler an, nur die
+ersten @code{#}-Indexe zu benutzen. Wenn Sie @code{MyISAM} benutzen, sagt
+es dem Handler, welche Schlüssel benutzt werden sollen, wobei jedes
+Binärbit für einen Schlüssel steht (der erste Schlüssel ist Bit 0). Das
+kann benutzt werden, um schnelleres Einfügen (Insert) zu erreichen!
+Deaktivierte Indexe können reaktiviert werden, indem man @code{myisamchk
+-r} benutzt.
+@item -l oder --no-symlinks
+Symbolischen Links wird nicht gefolgt. Normalerweise repariert
+@code{myisamchk} die Tabelle, auf die ein Symlink verweist. Diese Option
+gibt es in MySQL 4.0 nicht, weil MySQL 4.0 während der Reparatur keine
+Symlinks entfernt.
+@item -r oder --recover
+Kann fast alles reparieren, ausser eindeutige Schlüssel, die nicht
+eindeutig sind (was ein extrem unwahrscheinlicher Fehler bei ISAM- /
+MyISAM-Tabellen ist). Wenn Sie eine Tabelle wiederherstellen wollen,
+sollten Sie zuerst diese Option ausprobieren. Nur wenn myisamchk berichtet,
+dass die Tabelle mit @code{-r} nicht wiederhergestellt werden kann, sollten
+Sie @code{-o} probieren. (Hinweis: Im unwahrscheinlichen Fall, dass
+@code{-r} fehlschlägt, ist die Daten-Datei immer noch intakt.) Wenn Sie
+viel Arbeitsspeicher haben, sollten Sie die Größe von
+@code{sort_buffer_size} herauf setzen!
+@item -o oder --safe-recover
+Benutzt eine alte Wiederherstellungsmethode (liest alle Zeilen der Reihe
+nach und aktualisiert alle Indexbäume, basierend auf den gefundenen
+Zeilen); das ist sehr viel langsamer als @code{-r}, kann aber eine Reihe
+sehr unwahrscheinlicher Fälle behandeln, die @code{-r} nicht behandeln
+kann. Diese Wiederherstellungsmethode benutzt viel weniger Plattenspeicher
+als @code{-r}. Normalerweise sollte man immer zuerst versuchen, mit
+@code{-r} zu reparieren und nur im Falle des Fehlschlagens @code{-o}
+benutzen.
+
+Wenn Sie viel Arbeitsspeicher haben, sollten Sie die Größe von
+@code{key_buffer_size} herauf setzen!
+@item -n oder --sort-recover
+Zwingt @code{myisamchk} zu sortieren, um Schlüssel aufzulösen, selbst wenn
+die temporären Dateien sehr Groß sein sollten. Diese Option hat keine
+Auswirkung, wenn Sie Volltextschlüssel in der Tabelle haben.
+
+@item --character-sets-dir=...
+Verzeichnis, wo Zeichensätze gespeichert sind.
+@item --set-character-set=name
+Ändert den Zeichensatz, der vom Index benutzt wird.
+@item -t oder --tmpdir=path
+Pfad zum Speichern temporärer Dateien. Wenn dieser nicht gesetzt ist,
+benutzt @code{myisamchk} hierfür die Umgebungsvariable @code{TMPDIR}.
+@item -q oder --quick
+Repariert schneller, indem die Daten-Datei nicht verändert wird. Man kann
+ein zweites @code{-q} angeben, um @code{myisamchk} zu zwingen, die
+Original-Daten-Datei zu ändern, falls doppelte Schlüssel auftreten.
+@item -u oder --unpack
+Datei entpacken, die mit myisampack gepackt wurde.
+@end table
+
+
+@node myisamchk other options, myisamchk memory, myisamchk repair options, Table maintenance
+@c German node Andere Optionen für myisamchk
+@subsubsection Weitere Optionen für @code{myisamchk}
+
+Weitere Aktionen, die @code{myisamchk} ausführen kann, neben der Prüfung
+und Reparatur von Tabellen:
+
+@table @code
+@item -a oder --analyze
+Analysiert die Verteilung von Schlüsseln. Das verbessert die Performance
+bei Tabellenverknüpfungen (Joins), indem der Join-Optimierer in die Lage
+versetzt wird, besser auszuwählen, in welcher Reihenfolge die Tabellen
+verknüpft werden sollten und welche Schlüssel er dabei verwenden sollte:
+@code{myisamchk --describe --verbose tabelle'} oder Benutzung von
+@code{SHOW KEYS} in MySQL.
+@item -d oder --description
+Gibt ein paar Informationen über die Tabelle aus.
+@item -A oder --set-auto-increment[=value]
+Zwingt auto_increment, mit diesem oder einem höheren Wert anzufangen. Wenn
+kein Wert angegeben wird, wird der nächste auto_increment-Wert auf den
+höchsten benutzten Wert für den auto-Schlüssel + 1 gesetzt.
+@item -S oder --sort-index
+Sortiert die Blöcke des Indexbaums in Hoch-Niedrig-Reihenfolge. Das
+optimiert Suchoperationen und macht das Durchsehen (Scanning) von Tabellen
+nach Schlüsseln schneller.
+@item -R oder --sort-records=#
+Sortiert Datensätze in Übereinstimmung mit einem Index. Das macht Ihre
+Daten viel konzentrierter und kann @code{SELECT} mit Bereichen und
+@code{ORDER BY}-Operationen auf diesem Index erheblich beschleunigen. (Beim
+ersten Sortieren kann das SEHR langsam sein!) Um die Anzahl von Indexen
+einer Tabelle herauszufinden, benutzen Sie @code{SHOW INDEX}, was die
+Indexe einer Tabelle in genau der Reihenfolge zeigt, in der
+@code{myisamchk} sie sieht. Indexe werden mit 1 beginnend nummeriert.
+@end table
+
+
+@node myisamchk memory, Crash recovery, myisamchk other options, Table maintenance
+@c German node Speicher bei myisamchk
+@subsubsection Speicherbenutzung von @code{myisamchk}
+
+@cindex memory usage, myisamchk
+
+Die Speicherzuordnung ist wichtig, wenn Sie @code{myisamchk} laufen lassen.
+@code{myisamchk} benutzt nicht mehr Speicher, als Sie mir der
+@code{-O}-Option festlegen. Wenn Sie @code{myisamchk} für sehr große
+Dateien benutzen wollen, sollten Sie zuerst entscheiden, wieviel Speicher
+Sie benutzen wollen. Die Vorgabe liegt bei nur etwa 3 MB, um Dinge zu
+reparieren. Indem größere Werte benutzt werden, können Sie
+@code{myisamchk} dazu bringen, schneller zu arbeiten. Wenn Sie
+beispielsweise 32 MB Arbeitsspeicher haben, könnten Sie Optionen wie die
+folgende benutzen (zusätzlich zu weiteren Optionen, die Sie eventuell
+angeben):
+
+@example
+shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
+@end example
+
+@code{-O sort=16M} sollte für die meisten Fälle ausreichen.
+
+Denken Sie daran, dass @code{myisamchk} temporäre Dateien in @code{TMPDIR}
+benutzt. Wenn @code{TMPDIR} auf ein Speicher-Dateisystem zeigt, können
+Kein-Speicher-Fehler schnell auftreten. Wenn das passiert, setzen Sie
+@code{TMPDIR} so, dass es auf ein Verzeichnis mit mehr Speicherplatz zeigt
+und starten Sie @code{myisamchk} erneut.
+
+Beim Reparieren benötigt @code{myisamchk} große Mengen von
+Festplattenspeicher:
+
+@itemize @bullet
+@item
+Die doppelte Größe der Daten-Datei (die Originaldatei und eine Kopie).
+Dieser Platz wird nicht benötigt, wenn die Reparatur mit @code{--quick}
+durchgeführt wird, weil in diesem Fall nur die Index-Datei neu erzeugt
+wird. Der Platz wird auf derselben Festplatte benötigt, wo die
+Original-Daten-Datei liegt!
+@item
+Platz für die neue Index-Datei, die die alte ersetzt. Die alte Index-Datei
+wird beim Start beschnitten, daher kann man diesen Platz üblicherweise
+ignorieren. Der Platz wird auf derselben Platte benötigt, auf der die
+Original-Index-Datei liegt!
+@item
+Wenn Sie @code{--recover} oder @code{--sort-recover} benutzen (aber nicht,
+wenn Sie @code{--safe-recover} benutzen), brauchen Sie Platz für einen
+Sortierpuffer (Sort Buffer) für:
+@code{(größter_schlüssel + zeilen_zeiger_länge) * anzahl_der_zeilen * 2}.
+Sie können die Länge der Schlüssel und die Zeilen-Zeiger-Länger mit
+@code{myisamchk -dv tabelle} prüfen.
+Dieser Platz wird auf der temporären Platte zugeordnet (festgelegt durch
+@code{TMPDIR} oder @code{--tmpdir=#}).
+@end itemize
+
+Wenn Sie während der Reparatur ein Problem mit dem Plattenplatz bekommen,
+können Sie @code{--safe-recover} anstelle von @code{--recover}
+ausprobieren.
+
+
+@node Crash recovery, Check, myisamchk memory, Table maintenance
+@c German node Fehlerbeseitigung nach Abstürzen
+@subsubsection Benutzung von @code{myisamchk} für die Fehlerbeseitigung nach Abstürzen
+
+@cindex Absturz, Wiederherstellung
+@cindex Wiederherstellung, nach Absturz
+
+Wenn Sie @code{mysqld} mit @code{--skip-locking} laufen lassen (was auf
+einigen Systemen wie Linux die Vorgabe ist), können Sie @code{myisamchk}
+nicht zuverlässig dafür benutzen, eine Tabelle zu prüfen, wenn
+@code{mysqld} diese Tabelle benutzt. Wenn Sie sicher sein können, dass
+niemand auf die Tabellen mit @code{mysqld} zugreift, während Sie
+@code{myisamchk} laufen lassen, müssen Sie nur ein @code{mysqladmin
+flush-tables} durchführen, bevor Sie anfangen, die Tabellen zu prüfen. Wenn
+Sie das nicht garantieren können, müssen Sie @code{mysqld} herunter fahren,
+während Sie die Tabellen prüfen. Wenn Sie @code{myisamchk} laufen lassen,
+währen @code{mysqld} die Tabellen aktualisiert, erhalten Sie möglicherweise
+die Meldung, dass eine Tabelle beschädigt ist, selbst wenn sie es nicht
+ist.
+
+Wenn Sie @code{--skip-locking} nicht benutzen, können Sie jederzeit
+@code{myisamchk} benutzen, um Tabellen zu prüfen. Während Sie das tun,
+warten alle Clients, die versuchen, die Tabelle zu aktualisieren, bis
+@code{myisamchk} fertig ist, bevor sie weiter machen.
+
+Wenn Sie @code{myisamchk} benutzen, um Tabellen zu reparieren oder zu
+optimieren, @strong{MÜSSEN} Sie stets sicherstellen, dass der
+@code{mysqld}-Server die Tabelle nicht benutzt (das trifft auch zu, wenn
+Sie @code{--skip-locking} benutzen). Wenn Sie @code{mysqld} nicht herunter
+fahren, sollten Sie zumindest @code{mysqladmin flush-tables} ausführen,
+bevor Sie @code{myisamchk} benutzen.
+
+Dieses Kapitel beschreibt, wie man MySQL-Datenbanken auf Datenbeschädigung
+prüft und damit umgeht. Wenn Ihre Tabellen häufig beschädigt sind, wollten
+Sie versuchen, den Grund hierfür herauszufinden! @xref{Crashing}.
+
+Der Abschnitt über @code{MyISAM}-Tabellen enthält Gründe, warum eine
+Tabelle beschädigt sein könnte. @xref{MyISAM table problems}.
+
+Wenn Sie eine Wiederherstellung nach einem Absturz durchführen, ist es
+wichtig zu wissen, das jede Tabelle @code{tabelle} in einer Datenbank mit
+drei Dateien im Datenbank-Verzeichnis korrespondiert:
+
+@multitable @columnfractions .2 .8
+@item @strong{Datei} @tab @strong{Zweck}
+@item @file{tabelle.frm} @tab Tabellendefinitionsdatei (form)
+@item @file{tabelle.MYD} @tab Daten-Datei (data)
+@item @file{tabelle.MYI} @tab Index-Datei (index)
+@end multitable
+
+Jeder der drei Dateitypen kann auf verschiedene Weisen beschädigt werden.
+Probleme treten aber zumeist bei Daten-Dateien und Index-Dateien auf.
+
+@code{myisamchk} funktioniert so, dass Zeile für Zeile eine Kopie der
+@file{.MYD}-(data)-Datei gemacht wird. Es beendet die Reparaturphase damit,
+dass die alte @file{.MYD}-Datei entfernt wird und die neue Datei mit dem
+Orginal-Dateinamen benannt wird. Wenn Sie @code{--quick} benutzen, erzeugt
+@code{myisamchk} keine temporäre @file{.MYD}-Datei, sondern nimmt statt
+dessen an, dass die @file{.MYD}-Datei korrekt ist, und erzeugt nur eine
+neue Index-Datei, ohne die @file{.MYD}-Datei zu berühren. Das ist sicher,
+weil @code{myisamchk} automatisch feststellt, wenn die @file{.MYD}-Datei
+beschädigt ist, und die Reparatur in diesem Fall abbricht. Sie können
+@code{myisamchk} auch mit zwei @code{--quick}-Optionen aufrufen. In diesem
+Fall bricht @code{myisamchk} bei einigen Fehlern (wie doppelten
+Schlüsseleinträgen) nicht ab, sondern versucht statt dessen, diese
+aufzulösen, indem die @file{.MYD}-Datei verändert wird. Normalerweise ist
+die Benutzung von zwei @code{--quick}-Optionen nur sinnvoll, wenn Sie zu
+wenig frei Plattenplatz haben, um eine normale Reparatur durchzuführen. In
+diesem Fall sollten Sie zumindest eine Datensicherung machen, bevor Sie
+@code{myisamchk} laufen lassen.
+
+
+@node Check, Repair, Crash recovery, Table maintenance
+@c German node Prüfung
+@subsubsection Wie Tabellen auf Fehler überprüft werden
+
+@cindex Prüfen, Tabellen auf Fehler
+@cindex Tabellen, Fehlerprüfung
+@cindex Fehler, Tabellen prüfen auf
+
+Um eine MyISAM-Tabelle zu prüfen, benutzen Sie folgende Befehle:
+
+@table @code
+@item myisamchk tabelle
+Das findet 99.99% aller Fehler. Nicht gefunden werden Beschädigungen, die
+@strong{NUR} die Daten-Datei betreffen (was sehr ungewöhnlich ist). Wenn
+Sie eine Tabelle prüfen wollen, sollten Sie @code{myisamchk} normalerweise
+ohne Optionen oder entweder mit der @code{-s}- oder @code{--silent}-Option
+laufen lassen.
+
+@item myisamchk -m tabelle
+Das findet 99.999% aller Fehler. Zuerst prüft es alle Indexeinträge auf
+Fehler und liest dann alle Zeilen durch. Es berechnet eine Prüfsumme für
+alle Schlüssel in den Zeilen und bestätigt dann, dass die Prüfsumme mit der
+Prüfsumme für die Schlüssel im Indexbaum übereinstimmt.
+
+@item myisamchk -e tabelle
+Das führt eine vollständige, gründlich Prüfung aller Daten durch (@code{-e}
+bedeutet ``extended check'' - erweiterte Prüfung). Es führt ein Prüf-Lesen
+jedes Schlüssels für jede Zeile durch, um zu bestätigen, dass sie
+tatsächlich auf die richtige Zeile verweisen. Das kann bei einer großen
+Tabelle mit vielen Schlüsseln SEHR LANG dauern. @code{myisamchk} hält
+normalerweise an, wenn es den ersten Fehler gefunden hat. Wenn Sie mehr
+Informationen haben wollen, können Sie die
+@code{--verbose}-(@code{-v})-Option benutzen. Das veranlasst
+@code{myisamchk}, weiterzumachen, bis maximal 20 Fehler gefunden wurden.
+Bei normalem Gebrauch ist ein einfaches @code{myisamchk} (ohne weitere
+Argumente ausser dem Tabellennamen) ausreichend.
+
+@item myisamchk -e -i tabelle
+Wie der vorherige Befehl, jedoch weist die @code{-i}-Option
+@code{myisamchk} an, zusätzlich einige statistische Informationen
+auszugeben.
+@end table
+
+
+@node Repair, Optimisation, Check, Table maintenance
+@c German node Reparatur
+@subsubsection Wie Tabellen repariert werden
+
+@cindex Tabellen, Reparatur
+@cindex Reparatur, Tabellen
+
+Der folgende Abschnitt behandelt nur die Benutzung von @code{myisamchk} mit
+@code{MyISAM}-Tabellen (Erweiterungen @code{.MYI} und @code{.MYD}). Wenn
+Sie @code{ISAM}-Tabellen benutzen (Erweiterungen @code{.ISM} und
+@code{.ISD}), sollten Sie statt dessen @code{isamchk} benutzen.
+
+Ab MySQL-Version 3.23.14 können Sie MyISAM-Tabellen mit dem
+@code{REPAIR TABLE}-Befehl reparieren. @xref{REPAIR TABLE}.
+
+Zu den Symptomen einer beschädigten Tabelle gehören Anfragen, die
+unerwartet abbrechen, und beobachtbare Fehler wie folgender:
+
+@itemize @bullet
+@item
+@file{tabelle.frm} is locked against change
+@item
+Can't find file @file{tabelle.MYI} (Errcode: ###)
+@item
+Unexpected end of file
+@item
+Record file is crashed
+@item
+Got error ### from table handler
+
+Um mehr Information über den Fehler zu erhalten, lassen Sie @code{perror
+###} laufen. Hier sind die häufigsten Fehler, die auf ein Problem mit der
+Tabelle hinweisen:
+
+@example
+shell> perror 126 127 132 134 135 136 141 144 145
+126 = Index-Datei ist beschädigt / falsches Dateiformat
+127 = Daten-Datei ist beschädigt
+132 = Alte Datenbank-Datei
+134 = Datensatz wurde bereits gelöscht (oder Daten-Datei beschädigt)
+135 = Kein Platz mehr in der Daten-Datei
+136 = Kein Platz mehr in der Index-Datei
+141 = Doppelter Eintrag für eindeutigen Schlüssel oder Beschränkung beim Schreiben oder Aktualisiern
+144 = Tabelle ist beschädigt und die letzte Reparatur ist fehlgeschlagen
+145 = Tabelle ist als beschädigt gekennzeichnet und sollte repariert werden
+@end example
+
+Beachten Sie, dass Fehler 135 (kein Platz mehr in der Daten-Datei) kein
+Fehler ist, der durch eine einfache Reparatur behoben werden kann. In
+diesem Fall müssen Sie folgendes durchführen:
+
+@example
+ALTER TABLE tabelle MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
+@end example
+
+@end itemize
+
+In den anderen Fällen müssen Sie Ihre Tabellen reparieren. @code{myisamchk}
+kann üblicherweise die meisten Dinge, die schief gehen können, finden und
+beheben.
+
+Der Reparaturprozess läuft in vier Phasen ab, die unten beschrieben sind.
+Bevor Sie anfangen, sollten Sie in das Datenbank-Verzeichnis wechseln und
+die Berechtigungen der Tabellen-Dateien prüfen. Stellen Sie sicher, dass
+diese durch den Unix-Benutzer lesbar sind, unter dem @code{mysqld} läuft
+(und für Sie, weil Sie auf die Dateien zugreifen müssen, wenn Sie sie
+prüfen). Wenn Sie in der Folge Dateien verändern müssen, müssen diese für
+Sie auch schreibbar sein.
+
+Wenn Sie MySQL-Version 3.23.16 und höher benutzen, können (und sollten) Sie
+die @code{CHECK}- und @code{REPAIR}-Befehle benutzen, um
+@code{MyISAM}-Tabellen zu prüfen und zu reparieren. @xref{REPAIR TABLE}.
+
+Der Handbuchabschnitt über Tabellenwartung beinhaltet die Optionen für
+@code{isamchk} / @code{myisamchk}. @xref{Table maintenance}.
+
+Der folgende Abschnitt ist für Fälle, in denen die obigen Befehle
+fehlschlagen, oder wenn Sie die erweiterten Features benutzen wollen, die
+@code{isamchk} / @code{myisamchk} zur Verfügung stellt.
+
+Wenn Sie eine Tabelle von der Kommandozeile aus reparieren wollen, müssen
+Sie zuerst den @code{mysqld}-Server herunter fahren. Beachten Sie bei
+@code{mysqladmin shutdown} auf einen entfernten Server, dass der
+@code{mysqld}-Server noch für eine Weile aktiv bleibt, nachdem
+@code{mysqladmin} beendet ist, bis alle Anfragen beendet und alle Schlüssel
+auf Platte zurück geschrieben (flush) wurden.
+
+@noindent
+@strong{Phase 1: Prüfen Ihrer Tabellen}
+
+Lassen Sie @code{myisamchk *.MYI} laufen, oder @code{myisamchk -e *.MYI},
+wenn Sie mehr Zeit haben. Benutzen Sie die @code{-s}-(silent)-Option, um
+unnötige Informationen zu unterdrücken.
+
+Wenn der @code{mysqld}-Server herunter gefahren ist, sollten Sie die
+@code{--update}-Option benutzen, um @code{myisamchk} zu veranlassen, die
+Tabelle als 'geprüft' zu kennzeichnen.
+
+Sie müssen nur die Tabellen reparieren, bei denen @code{myisamchk} bekannt
+gibt, dass sie Fehler enthalten. Gehen Sie bei solchen Tabellen zu Phase 2
+über.
+
+Wenn Sie beim Prüfen merkwürdige Fehler erhalten (wie @code{out of
+memory}-Fehler), oder wenn @code{myisamchk} abstürzt, gehen Sie zu Phase
+3.
+
+@noindent
+@strong{Phase 2: Einfache, sichere Reparatur}
+
+HINWEIS: Wenn Sie wollen, dass die Reparatur sehr viel schneller abläuft,
+sollten Sie allen @code{isamchk/myisamchk}-Befehlen folgendes hinzufügen:
+@code{-O sort_buffer=# -O key_buffer=#} (wobei # etwa 1/4 des verfügbaren
+Arbeitsspeichers ist).
+
+Probieren Sie zuerst @code{myisamchk -r -q tabelle} (@code{-r -q} bedeutet
+``quick recovery mode'' - schnelles Wiederherstellen). Dies versucht, die
+Index-Datei zu reparieren, ohne die Daten-Datei zu berühren. Wenn die
+Daten-Datei alles enthält, was sie sollte, und die Löschverknüpfungen auf
+die korrekten Stellen in der Daten-Datei zeigen, sollte das funktionieren
+und die Tabelle ist repariert. Machen Sie dann mit der Reparatur der
+nächsten Tabelle weiter. Ansonsten führen Sie folgende Prozedur durch:
+
+@enumerate
+@item
+Machen Sie eine Datensicherung der Daten-Datei, bevor Sie fortfahren.
+
+@item
+Geben Sie @code{myisamchk -r tabelle} (@code{-r} bedeutet ``recovery mode''
+- Wiederherstellung) ein. Das entfernt falsche und gelöschte Datensätze aus
+der Daten-Datei und stellt die Index-Datei wieder her.
+
+@item
+Wenn die vorherigen Schritte fehlschlagen, geben Sie @code{myisamchk
+--safe-recover tabelle} ein. Der Modus für sicheres Wiederherstellen
+benutzt eine alte Wiederherstellungsmethode, die ein paar Fälle behandelt,
+die der normale Wiederherstellungsmodus nicht behandelt (ist aber
+langsamer).
+@end enumerate
+
+Wenn Sie bei der Reparatur merkwürdige Fehler erhalten (wie @code{out of
+memory}-Fehler), oder wenn @code{myisamchk} abstürzt, gehen Sie zu Phase
+3.
+
+@noindent
+@strong{Phase 3: Schwierige Reparatur}
+
+Diese Phase sollten Sie nur dann erreichen, wenn der erste 16-KB-Block der
+Index-Datei zerstört ist oder falsche Informationen enthält, oder wenn die
+Index-Datei fehlt. In diesem Fall ist es notwendig, eine neue Index-Datei
+zu erzeugen. Das machen Sie wie folgt:
+
+@enumerate
+@item
+Verschieben Sie die Daten-Datei an einen sicheren Ort.
+
+@item
+Benutzen Sie die Tabellen-Beschreibungsdatei, um eine neue (leere)
+Daten-Datei und Index-Dateien zu erzeugen:
+
+@example
+shell> mysql datenbank
+mysql> SET AUTOCOMMIT=1;
+mysql> TRUNCATE TABLE tabelle;
+mysql> quit
+@end example
+
+Wenn Ihre SQL-Version kein @code{TRUNCATE TABLE} hat, benutzen Sie statt
+dessen @code{DELETE FROM tabelle}.
+
+@item
+Kopieren Sie Ihre alte Daten-Datei zurück, über die neu erzeugte
+Daten-Datei. (Verschieben Sie Ihre alte Daten-Datei nicht einfach, damit
+Sie eine Kopie erhalten, falls etwas schief geht.)
+@end enumerate
+
+Gehen Sie zurück zu Phase 2. @code{myisamchk -r -q} sollte jetzt
+funktionieren. (Das sollte keine Endlosschleife sein.)
+
+@noindent
+@strong{Phase 4: Sehr schwierige Reparatur}
+
+Diese Phase sollten Sie nur dann erreichen, wenn auch die
+Beschreibungsdatei beschädigt ist. Das sollte nie passieren, weil die
+Beschreibungsdatei nicht verändert wird, nachdem die Tabelle erzeugt wurde:
+
+@enumerate
+@item
+Stellen Sie die Beschreibungsdatei von einer Datensicherung wieder her und
+gehen Sie zurück zu Phase 3. Sie können auch die Index-Datei
+wiederherstellen und zu Phase 2 zurück gehen. Im letzteren Fall sollten
+Sie mit @code{myisamchk -r} anfangen.
+
+@item
+Wenn Sie keine Datensicherung haben, aber genau wissen, wie die Tabelle
+erzeugt wurde, erzeugen Sie eine Kopie der Tabelle in einer anderen
+Datenbank. Entfernen Sie die neue Daten-Datei und verschieben Sie die
+Beschreibungs- und Index-Dateien von der anderen Datenbank in Ihre
+beschädigte Datenbank. Das ergibt neue Beschreibungs- und Index-Dateien,
+läßt aber die Daten-Datei in Ruhe. Gehen Sie zurück zu Phase 2 und
+versuchen Sie, die Index-Datei wiederherzustellen.
+@end enumerate
+
+
+@node Optimisation, , Repair, Table maintenance
+@c German node Optimierung
+@subsubsection Tabellenoptimierung
+
+@cindex Tabellen, Optimierung
+@cindex Optimierung, Tabellen
+
+Um fragmentierte Datensätze zu vereinigen und verschwendeten Speicherplatz
+zu beseitigen, der sich durch Löschen und Aktualisieren von Datensätzen
+ergibt, lassen Sie @code{myisamchk} im Wiederherstellungsmodus laufen:
+
+@example
+shell> myisamchk -r tabelle
+@end example
+
+Auf dieselbe Weise können Sie eine Tabelle optimieren, indem Sie das
+SQL-Statement @code{OPTIMIZE TABLE} benutzen. @code{OPTIMIZE TABLE} führt
+eine Reparatur der Tabelle und eine Analyse der Schlüssel durch und
+sortiert den Indexbaum, um schnelleres Nachschlagen der Schlüssel (Key
+Lookup) zu ermöglichen. Ausserdem schaltet es die Möglichkeit ungewollter
+Interaktionen zwischen einem Dienstprogramm und dem Server aus, weil der Server
+bei der Benutzung von @code{OPTIMIZE TABLE} die ganze Arbeit verrichtet.
+@xref{OPTIMIZE TABLE}.
+
+@code{myisamchk} hat eine Anzahl weiterer Optionen, die Sie für die
+Verbesserung der Performance einer Tabelle benutzen können:
+
+@table @code
+@item -S, --sort-index
+@item -R index_nummer, --sort-records=index_nummer
+@item -a, --analyze
+@end table
+
+Eine detaillierte Beschreibung der Optionen steht unter
+@xref{myisamchk syntax}.
+
+
+@node Maintenance regimen, Table-info, Table maintenance, Disaster Prevention
+@c German node Wartungsplan
+@subsection Wartungsplan für Tabellen erstellen
+
+@cindex Wartung, Tabellen
+@cindex Tabellen, Wartungsplan
+
+Ab MySQL-Version 3.23.13 können Sie MyISAM-Tabellen mit dem @code{CHECK
+TABLE}-Befehl prüfen. @xref{CHECK TABLE}. Sie können Tabellen mit dem
+@code{REPAIR TABLE}-Befehl reparieren. @xref{REPAIR TABLE}.
+
+Es ist eine gute Idee, Tabellenüberprüfungen auf regelmäßiger Basis
+durchzuführen statt darauf zu warten, dass Probleme auftreten. Für
+Wartungszwecke benutzen Sie @code{myisamchk -s}, um Tabellen zu überprüfen.
+Die @code{-s}-Option (Kurzform für @code{--silent}) veranlasst
+@code{myisamchk}, im schweigsamen Modus zu laufen, wobei Meldungen nur
+ausgegeben werden, wenn Fehler auftreten.
+
+@tindex .pid-(process ID)-Datei
+Ebenfalls eine gute Idee ist es, Tabellen zu überprüfen, wenn der Server
+hoch fährt. Wenn beispielsweise die Maschine mitten während einer
+Aktualisierung (Update) neu gebootet hat, müssen Sie üblicherweise alle
+Tabellen prüfen, die betroffen sein könnten. (Das ist ein Fall von
+``erwarteter Tabellenbeschädigung''.) Sie können @code{safe_mysqld} einen
+Test hinzufügen, der @code{myisamchk} laufen läßt, um alle Tabellen zu
+überprüfen, die innerhalb der letzten 24 Stunden geändert wurden, wenn nach
+einem Reboot eine alte @file{.pid}-(process ID)-Datei übrig blieb. (Die
+@file{.pid}-Datei wird von @code{mysqld} erzeugt, wenn er hoch fährt, und
+entfernt, wenn er normal beendet wird. Die Anwesenheit einer
+@file{.pid}-Datei beim Systemstart zeigt an, dass @code{mysqld} regelwidrig
+abgebrochen wurde.)
+
+Eine noch bessere Testmethode besteht darin, jede Tabelle zu prüfen, deren
+Zeit der letzten Änderung neuer ist als die der @file{.pid}-Datei.
+
+Ausserdem sollten Sie Ihre Tabellen regelmäßig während der normalen
+Systemtätigkeit prüfen. Bei MySQL AB lassen wir einen @code{cron}-Job
+laufen, um alle wichtigen Tabellen einmal pro Woche zu prüfen, indem wir
+folgende Zeile in der @file{crontab}-Datei benutzen:
+
+@example
+35 0 * * 0 /pfad/zu/myisamchk --fast --silent /pfad/zu/datadir/*/*.MYI
+@end example
+
+Das gibt Informationen über beschädigte Tabellen aus, so dass wir diese
+prüfen und reparieren können, falls notwendig.
+
+Da wir mittlerweile seit einigen Jahren keinerlei unerwartet beschädigte
+Tabellen hatten (Tabellen, die aus anderen Gründen als Hardware-Schäden
+beschädigt wurden), reicht uns einmal pro Woche völlig aus.
+
+Wir empfehlen, dass Sie jede Nacht @code{myisamchk -s} auf alle Tabellen
+ausführen, die während der letzten 24 Stunden aktualisiert wurden, bis Sie
+MySQL so sehr vertrauen, wie wir selbst das mittlerweile tun.
+
+@cindex Tabellen, defragmentieren
+Normalerweise brauchen Sie MySQL-Tabellen nicht so sehr warten. Wenn Sie
+Tabellen mit Zeilen dynamischer Länge ändern (Tabellen mit
+@code{VARCHAR}-, @code{BLOB}- oder @code{TEXT}-Spalten) oder Tabellen mit
+vielen gelöschten Zeilen haben, werden Sie diese von Zeit zu Zeit (einmal
+im Monat?) defragmentieren wollen bzw. freien Speicherplatz schaffen.
+
+Das können Sie mit @code{OPTIMIZE TABLE} auf die in Frage kommenden
+Tabellen tun, oder, wenn Sie den @code{mysqld}-Server für eine Weile
+herunter fahren können:
+
+@example
+isamchk -r --silent --sort-index -O sort_buffer_size=16M */*.ISM
+myisamchk -r --silent --sort-index -O sort_buffer_size=16M */*.MYI
+@end example
+
+
+@node Table-info, , Maintenance regimen, Disaster Prevention
+@c German node Tabelleninformation
+@subsection Informationen über eine Tabelle erhalten
+
+@cindex Tabellen, Informationen
+
+Um eine Beschreibung einer Tabelle oder Statistiken über sie zu erhalten,
+benutzen Sie die unten stehenden Befehle. Einige davon werden später
+detaillierter erläutert:
+
+@table @code
+@item myisamchk -d tabelle
+Läßt @code{myisamchk} im ``Beschreibungsmodus'' laufen, um eine
+Beschreibung Ihrer Tabelle zu erzeugen. Wenn Sie den MySQL-Server mit der
+@code{--skip-locking}-Option starten, kann @code{myisamchk} eventuell
+Fehler über eine Tabelle berichten, die aktualisiert wird, während es
+läuft. Weil @code{myisamchk} jedoch im Beschreibungsmodus keine Tabelle
+ändert, gibt es kein Risiko, dass Daten zerstört werden.
+
+@item myisamchk -d -v tabelle
+Um mehr Informationen über das, was @code{myisamchk} tut, zu erzeugen,
+fügen Sie @code{-v} als Option hinzu, damit es im geschwätzigen Modus
+läuft.
+
+@item myisamchk -eis tabelle
+Zeigt nur die wichtigsten Informationen über die Tabelle. Das ist langsam,
+weil es die ganze Tabelle lesen muss.
+
+@item myisamchk -eiv tabelle
+Wie @code{-eis}, sagt aber zusätzlich, was getan werden muss.
+@end table
+
+@cindex Beispiele, @code{myisamchk}-Ausgabe
+@cindex @code{myisamchk}, Beispiele der Ausgabe
+Beispiel einer @code{myisamchk -d}-Ausgabe:
+@example
+MyISAM file: firma.MYI
+Record format: Fixed length
+Data records: 1403698 Deleted blocks: 0
+Recordlength: 226
+
+table description:
+Key Start Len Index Type
+1 2 8 unique double
+2 15 10 multip. text packed stripped
+3 219 8 multip. double
+4 63 10 multip. text packed stripped
+5 167 2 multip. unsigned short
+6 177 4 multip. unsigned long
+7 155 4 multip. text
+8 138 4 multip. unsigned long
+9 177 4 multip. unsigned long
+ 193 1 text
+@end example
+
+Beispiel einer @code{myisamchk -d -v}-Ausgabe:
+@example
+MyISAM file: firma
+Record format: Fixed length
+File-version: 1
+Creation time: 1999-10-30 12:12:51
+Recover time: 1999-10-31 19:13:01
+Status: checked
+Data records: 1403698 Deleted blocks: 0
+Datafile parts: 1403698 Deleted data: 0
+Datafilepointer (bytes): 3 Keyfile pointer (bytes): 3
+Max datafile length: 3791650815 Max keyfile length: 4294967294
+Recordlength: 226
+
+table description:
+Key Start Len Index Type Rec/key Root Blocksize
+1 2 8 unique double 1 15845376 1024
+2 15 10 multip. text packed stripped 2 25062400 1024
+3 219 8 multip. double 73 40907776 1024
+4 63 10 multip. text packed stripped 5 48097280 1024
+5 167 2 multip. unsigned short 4840 55200768 1024
+6 177 4 multip. unsigned long 1346 65145856 1024
+7 155 4 multip. text 4995 75090944 1024
+8 138 4 multip. unsigned long 87 85036032 1024
+9 177 4 multip. unsigned long 178 96481280 1024
+ 193 1 text
+@end example
+
+Beispiel einer @code{myisamchk -eis}-Ausgabe:
+@example
+Checking MyISAMDatei: firma
+Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
+Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
+Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
+Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
+Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
+Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
+Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
+Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
+Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
+Total: Keyblocks used: 98% Packed: 17%
+
+Records: 1403698 M.recordlength: 226 Packed: 0%
+Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
+Record blocks: 1403698 Delete blocks: 0
+Recorddata: 317235748 Deleted data: 0
+Lost space: 0 Linkdata: 0
+
+User time 1626.51, System time 232.36
+Maximum resident set size 0, Integral resident set size 0
+Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
+Blocks in 0 out 0, Messages in 0 out 0, Signals 0
+Voluntary context switches 639, Involuntary context switches 28966
+@end example
+
+Beispiel einer @code{myisamchk -eiv}-Ausgabe:
+@example
+Checking MyISAM file: firma
+Data records: 1403698 Deleted blocks: 0
+- check file-size
+- check delete-chain
+block_size 1024:
+index 1:
+index 2:
+index 3:
+index 4:
+index 5:
+index 6:
+index 7:
+index 8:
+index 9:
+No recordlinks
+- check index reference
+- check data record references index: 1
+Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
+- check data record references index: 2
+Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
+- check data record references index: 3
+Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
+- check data record references index: 4
+Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
+- check data record references index: 5
+Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
+- check data record references index: 6
+Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
+- check data record references index: 7
+Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
+- check data record references index: 8
+Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
+- check data record references index: 9
+Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
+Total: Keyblocks used: 9% Packed: 17%
+
+- check records und index references
+[LOTS OF ROW NUMBERS DELETED]
+
+Records: 1403698 M.recordlength: 226 Packed: 0%
+Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
+Record blocks: 1403698 Delete blocks: 0
+Recorddata: 317235748 Deleted data: 0
+Lost space: 0 Linkdata: 0
+
+User time 1639.63, System time 251.61
+Maximum resident set size 0, Integral resident set size 0
+Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
+Blocks in 4 out 0, Messages in 0 out 0, Signals 0
+Voluntary context switches 10604, Involuntary context switches 122798
+@end example
+
+Hier stehen die Größen der Daten- und Index-Dateien der Tabelle, die in
+den vorstehenden Beispielen benutzt wurde:
+
+@example
+-rw-rw-r-- 1 monty tcx 317235748 Jan 12 17:30 firma.MYD
+-rw-rw-r-- 1 davida tcx 96482304 Jan 12 18:35 firma.MYM
+@end example
+
+Erläuterungen der Informationen, die @code{myisamchk} erzeugt, werden unten
+gegeben. ``keyfile'' ist die Index-Datei. ``Record'' und ``row'' sind
+Synonyme:
+
+@table @code
+@item ISAM file
+Name der ISAM-(Index)-Datei.
+
+@item Isam-version
+Version des ISAM-Formats. Momentan immer 2.
+
+@item Creation time
+Wann die Daten-Datei erzeugt wurde.
+
+@item Recover time
+Wann die Index-/Daten-Datei das letzte Mal rekonstruiert wurden.
+
+@item Data records
+Wie viele Datensätze in der Tabelle sind.
+
+@item Deleted blocks
+Wie viele gelöschte Blöcke noch Platz belegen.
+Sie können Ihre Tabelle optimieren, um diesen Platz zu minimieren.
+@xref{Optimisation}.
+
+@item Datafile: Parts
+Bei dynamischem Datensatzformat zeigt dies an, wie viele Datenblöcke es
+gibt. Bei einer optimierten Tabelle ohne fragmentierte Datensätze ist das
+dasselbe wie @code{Data records}.
+
+@item Deleted data
+Wie viele Bytes nicht zurückgewonnener gelöschter Daten es gibt.
+Sie können Ihre Tabelle optimieren, um diesen Platz zu minimieren.
+@xref{Optimisation}.
+
+@item Datafile pointer
+Die Größe des Daten-Datei-Zeigers in Bytes. Das sind normalerweise 2, 3, 4
+oder 5 Bytes. Die meisten Tabellen schaffen 2 Bytes, aber das kann bislang
+von MySQL noch nicht gesteuert werden. Bei festen Tabellen ist das eine
+Datensatzadresse. Bei dynamischen Tabellen ist es eine Byte-Adresse.
+
+@item Keyfile pointer
+Die Größe des Index-Datei-Zeigers in Bytes. Sie beträgt normalerweise 1, 2
+oder 3 Bytes. Die meisten Tabellen schaffen 2 Bytes, aber das wird von
+MySQL automatisch berechnet. Es ist immer die Block-Adresse.
+
+@item Max datafile length
+Wie lang die Daten-Datei (@code{.MYD}-Datei) der Tabelle werden kann, in
+Bytes.
+
+@item Max keyfile length
+Wie lang die Index-Datei (@code{.MYI}-Datei) der Tabelle werden kann, in
+Bytes.
+
+@item Recordlength
+Wie viel Platz jeder Datensatz benötigt, in Bytes.
+
+@item Record format
+Das Format, das benutzt wird, um Tabellenzeilen zu speichern.
+Die oben stehenden Beispiele benutzen @code{Fixed length}.
+Andere mögliche Werte sind @code{Compressed} und @code{Packed}.
+
+@item Table description
+Eine Liste aller Schlüssel in der Tabelle. Für jeden Schlüssel werden
+einige Low-Level-Informationen angezeigt:
+
+@table @code
+@item Key
+Die Nummer des Schlüssels.
+
+@item Start
+Wo im Datensatz dieser Index-Teil anfängt.
+
+@item Len
+Wie lang dieser Index-Teil ist. Bei gepackten Zahlen sollte das immer die
+gesamte Länge der Spalte sein. Bei Zeichenketten kann es kürzer als die
+gesamte Länge der indizierten Spalte sein, weil Sie ein Prefix einer
+Zeichenkettenspalte indexieren können.
+
+@item Index
+@code{unique} oder @code{multip.} (multiple). Zeigt an, ob ein Wert einmal
+oder mehrfach in diesem Index vorkommen darf.
+
+@item Type
+Welchen Datentyp dieser Index-Teil hat. Das ist ein ISAM-Datentyp mit den
+Optionen @code{packed}, @code{stripped} oder @code{empty}.
+
+@item Root
+Adresse des Root-Index-Blocks.
+
+@item Blocksize
+Die Größe jedes Index-Blocks. Vorgabemäßig ist das 1024, doch dieser Wert
+kann beim Kompilieren geändert werden.
+
+@item Rec/key
+Das ist ein statistischer Wert, der vom Optimierer benutzt wird. Es sagt
+aus, wie viele Datensätze es pro Wert für diesen Schlüssel gibt. Ein
+eindeutiger Schlüssel hat immer einen Wert von 1. Das kann aktualisiert
+werden, nachdem eine Tabelle geladen wurde (oder in größerem Umfang
+geändert) mit @code{myisamchk -a}. Wenn dies überhaupt nicht aktualisiert
+wurde, wird ein Wert von 30 angenommen.
+@end table
+
+@item
+Im ersten Beispiel oben ist der neunte Schlüssel ein mehrteiliger Schlüssel
+mit zwei Teilen.
+
+@item Keyblocks used
+Welcher Prozentsatz von Schlüsselblöcken benutzt wird. Weil die Tabellen,
+die in den Beispielen benutzt wurden, direkt vorher mit @code{myisamchk}
+reorganisiert wurden, sind diese Werte sehr hoch (sehr nahe am
+theoretischen Maximum).
+
+@item Packed
+MySQL versucht, Schlüssel mit einem gemeinsamen Suffix zu packen. Das geht
+nur bei @code{CHAR}-, @code{VARCHAR} und @code{DECIMAL}-Schlüsseln. Bei
+langen Zeichenketten wie Namen kann das den benutzten Platz signifikant
+verringern. Im dritten Beispiel oben ist der vierte Schlüssel zehn Zeichen
+lang, wodurch ein 60%-ige Verringerung des Platzbedarfs erreicht wird.
+
+@item Max levels
+Wie tief der B-Baum für diesen Schlüssel ist. große Tabellen mit langen
+Schlüsseln haben hohe Werte.
+
+@item Records
+Wie viele Zeilen in der Tabelle enthalten sind.
+
+@item M.recordlength
+Die durchschnittliche Datensatzlänge. Bei Tabellen mit Datensätzen fester
+Länge ist das die exakte Datensatzlänge.
+
+@item Packed
+MySQL schneidet Leerzeichen am Ende von Zeichenketten ab. Der
+@code{Packed}-Wert zeigt an, welcher Prozentsatz dadurch gespart wurde.
+
+@item Recordspace used
+Welcher Prozentsatz der Daten-Datei benutzt wird.
+
+@item Empty space
+Welcher Prozentsatz der Daten-Datei unbenutzt ist.
+
+@item Blocks/Record
+Durchschnittliche Anzahl der Blöcke pro Datensatz (das heißt, aus wie
+vielen Verknüpfungen (Links) ein fragmentierter Datensatz zusammengesetzt
+ist). Bei Tabellen mit festem Format ist das immer 1. Dieser Wert sollte so
+nah wie möglich an 1,0 bleiben. Wenn er zu Groß wird, können Sie die
+Tabelle @code{myisamchk} reorganisieren.
+@xref{Optimisation}.
+
+@item Recordblocks
+Wie viele Blöcke (Verknüpfungen, Links) benutzt werden. Bei festem Format
+ist das die Anzahl der Datensätze.
+
+@item Deleteblocks
+Wie viele Blöcke (Verknüpfungen, Links) gelöscht sind.
+
+@item Recorddata
+Wie viele Bytes in der Daten-Datei benutzt sind.
+
+@item Deleted data
+Wie viele Bytes in der Daten-Datei gelöscht sind (unbenutzt).
+
+@item Lost space
+Wenn ein Datensatz auf eine kürzere Länge aktualisiert wird, geht etwas
+Platz verloren. Das ist die Summe aller solcher Verluste in Bytes.
+
+@item Linkdata
+When das dynamische Tabellenformat benutzt wird, werden Datensatzfragmente
+mit Zeigern (Pointer) verknüpft (jeder mit 4 bis 7 Bytes). @code{Linkdata}
+ist die Summe des Speicherplatzes, der von diesen Zeigern benutzt wird.
+@end table
+
+Wenn eine Tabelle mit @code{myisampack} komprimiert wurde, gibt
+@code{myisamchk -d} zusätzliche Informationen über jede Tabellenspalte aus,
+siehe @ref{myisampack, , @code{myisampack}}, wo sich ein Beispiel solcher
+Informationen und was sie bedeuten befindet.
+
+
+@node Database Administration, Localisation, Disaster Prevention, MySQL Database Administration
+@c German node Datenbankadministration
+@section Datenbankverwaltung Sprachreferenz
+
+
+
+
+@menu
+* OPTIMIZE TABLE::
+* ANALYZE TABLE::
+* FLUSH::
+* KILL::
+* SHOW::
+@end menu
+
+@node OPTIMIZE TABLE, ANALYZE TABLE, Database Administration, Database Administration
+@c German node OPTIMIZE TABLE
+@subsection @code{OPTIMIZE TABLE}-Syntax
+
+@findex OPTIMIZE TABLE
+
+@cindex Tabellen, defragmentieren
+@cindex Tabellen, Fragmentierung
+
+@example
+OPTIMIZE TABLE tabelle[,tabelle]...
+@end example
+
+@code{OPTIMIZE TABLE} sollte benutzt werden, wenn Sie große Teile der
+Tabelle gelöscht haben oder bei Tabellen mit Zeilen variabler Länge viele
+Änderungen durchgeführt haben (Tabellen, die @code{VARCHAR}-, @code{BLOB}-
+oder @code{TEXT}-Spalten enthalten). Gelöschte Datensätze werden in einer
+verknüpften Liste vorgehalten, und nachfolgenden @code{INSERT}-Operationen
+benutzen die Positionen alter Datensätze. Sie können @code{OPTIMIZE TABLE}
+benutzen, um unbenutzten Platz freizugeben und die Daten-Datei zu
+defragmentieren.
+
+Momentan funktioniert @code{OPTIMIZE TABLE} nur auf @strong{MyISAM}- und
+@code{BDB}-Tabellen. Bei @code{BDB}-Tabellen ist @code{OPTIMIZE TABLE}
+momentan auf @code{ANALYZE TABLE} gemappt. @xref{ANALYZE TABLE}.
+
+Sie können @code{OPTIMIZE TABLE} auf andere Tabellentypen zum Laufen
+bringen, indem Sie @code{mysqld} mit @code{--skip-new} oder
+@code{--safe-mode} starten, aber in diesem Fall wird @code{OPTIMIZE TABLE}
+lediglich auf @code{ALTER TABLE} gemappt.
+
+@code{OPTIMIZE TABLE} funktioniert wie folgt:
+@itemize @bullet
+@item
+Wenn die Tabelle gelöschte oder aufgeteilte Zeilen hat, wird sie repariert.
+@item
+Wenn die Index-Seiten nicht sortiert sind, werden sie sortiert.
+@item
+Wenn die Statistiken nicht aktuell sind (und eine Reparatur nicht durch das
+Sortieren des Indexes durchgeführt werden könnte), werden sie aktualisiert.
+@end itemize
+
+@code{OPTIMIZE TABLE} für @code{MyISAM}-Tabellen ist äquivalent zum
+Laufenlassen von @code{myisamchk --quick --check-changed-tables
+--sort-index --analyze} auf die Tabelle.
+
+Beachten Sie, dass die Tabelle während der Zeit, in der @code{OPTIMIZE TABLE} läuft, gesperrt ist!
+
+
+@node ANALYZE TABLE, FLUSH, OPTIMIZE TABLE, Database Administration
+@c German node ANALYZE TABLE
+@subsection @code{ANALYZE TABLE}-Syntax
+
+@findex ANALYZE TABLE
+
+@example
+ANALYZE TABLE tabelle[,tabelle...]
+@end example
+
+Analysiert und speichert die Schlüsselverteilung der Tabelle. Während der
+Analyse ist die Tabelle mit einer Lesesperre gesperrt. Das funktioniert auf
+@code{MyISAM} und @code{BDB}-Tabellen.
+
+Das ist äquivalent zum Laufenlassen von @code{myisamchk -a} auf die
+Tabelle.
+
+MySQL benutzt die gespeicherte Schlüsselverteilung, um zu entscheiden, in
+welcher Reihenfolge Tabellen verknüpft werden sollen, wenn man eine
+Verknüpfung (Join) auf irgend etwas anderes als eine Konstante macht.
+
+Der Befehl gibt eine Tabelle mit folgenden Spalten zurück:
+
+@multitable @columnfractions .35 .65
+@item @strong{Spalte} @tab @strong{Wert}
+@item Table @tab Tabellenname.
+@item Op @tab Immer ``analyze''.
+@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
+@item Msg_text @tab Die Meldung.
+@end multitable
+
+Sie können die gespeicherte Schlüsselverteilung mit dem @code{SHOW
+INDEX}-Befehl überprüfen. @xref{SHOW DATABASE INFO}.
+
+Wenn die Tabelle seit dem letzten @code{ANALYZE TABLE}-Befehl nicht
+geändert wurde, wird sie nicht noch einmal analysiert.
+
+
+@node FLUSH, KILL, ANALYZE TABLE, Database Administration
+@c German node FLUSH
+@subsection @code{FLUSH}-Syntax
+
+@findex FLUSH
+
+@cindex @code{mysqladmin}
+@cindex Löschen, Caches
+@cindex Caches, löschen
+
+@example
+FLUSH flush_option [,flush_option]
+@end example
+
+Wenn Sie einige der internen Caches, die MySQL benutzt, löschen wollen,
+benutzen Sie den @code{FLUSH}-Befehl. Um @code{FLUSH} ausführen zu können,
+müssen Sie die @strong{RELOAD}-Berechtigung haben.
+
+@code{flush_option} kann eine der folgenden sein:
+
+@multitable @columnfractions .15 .85
+@item @code{HOSTS} @tab Leert die Host-Cache-Tabellen. Sie sollten die
+Host-Tabellen flushen, wenn einige Ihrer Hosts die IP-Nummer ändern oder
+wenn Sie die Fehlermeldung @code{Host ... is blocked} erhalten. Wenn mehr
+als @code{max_connect_errors} Fehler in einer Zeile für einen gegebenen
+Host während der Verbindung zum MySQL-Server vorkommen, nimmt MySQL an,
+dass etwas nicht stimmt und blockiert den Host von weiteren
+Verbindungsversuchen. Wenn die Host-Tabellen geflusht werden, gestattet das
+dem Host, einen erneuten Verbindungsversuch zu machen.
+@c German FIX unwrapped @xref
+@xref{Blocked host}. Sie können @code{mysqld} mit @code{-O
+max_connection_errors=999999999} starten, um diese Fehlermeldung zu
+vermeiden.
+
+@item @code{LOGS} @tab Schließt alle Log-Dateien und öffnet sie danach
+wieder. Wenn Sie die Update-Log-Datei oder eine binäre Log-Datei ohne
+Erweiterung angegeben haben, wird die Erweiterungsnummer der Log-Datei um
+eins relativ zur vorherigen Datei hoch gezählt. Wenn Sie eine Erweiterung
+im Dateinamen benutzt haben, schließt MySQL die Update-Log-Datei und
+öffnet sie danach wieder. @xref{Update log}. Das ist dasselbe, wie
+dem @code{mysqld}-Server das @code{SIGHUP}-Signal senden.
+
+@item @code{PRIVILEGES} @tab Lädt die Berechtigungen aus den
+Berechtigungstabellen der @code{mysql}-Datenbank neu.
+
+@item @code{TABLES} @tab Schließt alle offenen Tabellen und erzwingt, dass
+alle Tabellen in Benutzung geschlossen werden.
+
+@item @code{[TABLE | TABLES] tabelle [,tabelle...]} @tab Flusht nur die
+angegebenen Tabellen.
+
+@item @code{TABLES WITH READ LOCK} @tab Schließt alle offenen Tabellen und
+sperrt alle Tabellen aller Datenbanken mit einer Lesesperre, bis man
+@code{UNLOCK TABLES} ausführt. Das ist eine sehr bequeme Möglichkeit,
+Datensicherungen zu erzeugen, wenn Sie ein Dateisystem wie Veritas haben,
+das Schnappschüsse aufnehmen kann.
+
+@item @code{STATUS} @tab Setzt alle Status-Variablen auf null zurück. Das
+sollte man nur benutzen, wenn man eine Anfrage debuggt.
+@end multitable
+
+Jeden der oben genannten Befehle können Sie auch mit dem
+@code{mysqladmin}-Dienstprogramm ausführen, indem Sie @code{flush-hosts},
+@code{flush-logs}, @code{reload} oder @code{flush-tables}-Befehle
+eingeben.
+
+Sehen Sie sich auch den @code{RESET}-Befehl an, der bei der Replikation
+benutzt wird. @xref{Replication SQL}.
+
+
+
+@node KILL, SHOW, FLUSH, Database Administration
+@c German node KILL
+@subsection @code{KILL}-Syntax
+
+@findex KILL
+
+@cindex @code{mysqladmin}
+
+@example
+KILL Thread_id
+@end example
+
+Jede Verbindung zu @code{mysqld} läuft durch einen separaten Thread. Sie
+können sehen, welche Threads laufen, indem Sie den @code{SHOW
+PROCESSLIST}-Befehl ausführen, und einen Thread killen, indem Sie den
+@code{KILL Thread_id}-Befehl ausführen.
+
+Wenn Sie die @strong{process}-Berechtigung haben, können Sie alle Threads
+sehen und killen. Ansonsten können Sie nur Ihre eigenen Threads sehen und
+killen.
+
+Sie können auch die @code{mysqladmin processlist}- und @code{mysqladmin
+kill}-Befehle benutzen, um Threads einzusehen und zu killen.
+
+Wenn Sie ein @code{KILL} ausführen, wird ein Thread-spezifischer @code{kill
+flag} für den Thread gesetzt.
+
+In den meisten Fällen kann es einige Zeit dauern, bis der Thread stirbt,
+weil der kill-Flag nur in bestimmten Intervallen geprüft wird:
+
+@itemize @bullet
+@item
+Bei @code{SELECT}-, @code{ORDER BY}- und @code{GROUP BY}-Schleifen wird der
+Flag geprüft, nachdem ein Block von Zeilen gelesen wurde. Wenn der
+kill-Flag gesetzt ist, wird das Statement abgebrochen.
+@item
+Bei @code{ALTER TABLE} wird der kill-Flag geprüft, bevor jeder Block von
+Zeilen aus der Original-Tabelle gelesen wird. Wenn der Flag gesetzt ist,
+wird der Befehl abgebrochen und die temporäre Tabelle wird gelöscht.
+@item
+Bei @code{UPDATE TABLE} und @code{DELETE TABLE} wird der kill-Flag geprüft,
+nachdem jeder Block gelesen wurde sowie nach jeder aktualisierten oder
+gelöschten Zeile. Wenn der Flag gesetzt ist, wird das Statement
+abgebrochen. Beachten Sie, dass die Änderungen nicht zurück gerollt
+(Rollback) werden, wenn Sie keine Transaktionen benutzen!
+@item
+@code{GET_LOCK()} wird mit @code{NULL} abgebrochen.
+@item
+Ein @code{INSERT DELAYED}-Thread flusht schnell alle Zeilen, die er im
+Speicher hat, und stirbt.
+@item
+Wenn der Thread im Tabellen-Lock-Handler ist (Status: @code{Locked}), wird
+die Tabellen-Sperre schnell abgebrochen.
+@item
+Wenn der Thread bei einem @code{write}-Aufruf auf freien Plattenplatz
+wartet, wird der Schreibvorgang mit einer Meldung, dass die Platte voll
+ist, abgebrochen.
+@end itemize
+
+
+
+
+@node SHOW, , KILL, Database Administration
+@c German node SHOW
+@subsection @code{SHOW}-Syntax
+
+@findex SHOW DATABASE INFO
+@findex SHOW DATABASES
+@findex SHOW TABLES
+@findex SHOW COLUMNS
+@findex SHOW FIELDS
+@findex SHOW INDEX
+@findex SHOW KEYS
+@findex SHOW STATUS
+@findex SHOW VARIABLES
+@findex SHOW PROCESSLIST
+@findex SHOW TABLE STATUS
+@findex SHOW GRANTS
+@findex SHOW CREATE TABLE
+@findex SHOW MASTER STATUS
+@findex SHOW MASTER LOGS
+@findex SHOW SLAVE STATUS
+
+@example
+ SHOW DATABASES [LIKE platzhalter]
+oder SHOW [OPEN] TABLES [FROM datenbank] [LIKE platzhalter]
+oder SHOW [FULL] COLUMNS FROM tabelle [FROM datenbank] [LIKE platzhalter]
+oder SHOW INDEX FROM tabelle [FROM datenbank]
+oder SHOW TABLE STATUS [FROM datenbank] [LIKE platzhalter]
+oder SHOW STATUS [LIKE platzhalter]
+oder SHOW VARIABLES [LIKE platzhalter]
+oder SHOW LOGS
+oder SHOW [FULL] PROCESSLIST
+oder SHOW GRANTS FOR benutzer
+oder SHOW CREATE TABLE tabelle
+oder SHOW MASTER STATUS
+oder SHOW MASTER LOGS
+oder SHOW SLAVE STATUS
+@end example
+
+@code{SHOW} stellt Informationen über Datenbanken, Tabellen, Spalten oder
+Status-Informationen über den Server zur Verfügung. Wenn der @code{LIKE
+platzhalter}-Teil benutzt wird, kann die @code{platzhalter}-Zeichenkette
+eine Zeichenkette sein, die die SQL-@samp{%}- und @samp{_}-
+Platzhalterzeichen benutzt.
+
+
+
+@menu
+* SHOW DATABASE INFO::
+* SHOW TABLE STATUS::
+* SHOW STATUS::
+* SHOW VARIABLES::
+* SHOW LOGS::
+* SHOW PROCESSLIST::
+* SHOW GRANTS::
+* SHOW CREATE TABLE::
+@end menu
+
+@node SHOW DATABASE INFO, SHOW TABLE STATUS, SHOW, SHOW
+@c German node SHOW DATABASE INFO
+@subsubsection Informationen über Datenbank, Tabellen, Spalten und Indexe abrufen
+
+@cindex Anzeigen, Informationen, @code{SHOW}
+
+Sie können @code{datenbank.tabelle} als Alternative zur @code{tabelle FROM
+datenbank}-Syntax benutzen. Diese beiden Statements sind äquivalent:
+
+@example
+mysql> SHOW INDEX FROM tabelle FROM datenbank;
+mysql> SHOW INDEX FROM datenbank.tabelle;
+@end example
+
+@code{SHOW DATABASES} listet die Datenbanken auf dem MySQL-Server-Host auf.
+Diese Liste erhalten Sie auch mit dem @code{mysqlshow}-Befehl.
+
+@code{SHOW TABLES} listet die Tabellen in einer gegebenen Datenbank auf.
+Sie erhalten diese Liste auch mit dem @code{mysqlshow datenbank}-Befehl.
+
+@strong{HINWEIS:} Wenn ein Benutzer keinerlei Berechtigungen für eine
+Tabelle hat, wird die Tabelle in der Ausgabe von @code{SHOW TABLES} oder
+@code{mysqlshow datenbank} nicht aufgeführt.
+
+@code{SHOW OPEN TABLES} listet die Tabellen auf, die momentan im
+Tabellen-Cache geöffnet sind. @xref{Open tables}. Das @code{Comment}-Feld
+zeigt an, wie oft die Tabelle gecachet (@code{cached}) und in Benutzung
+(@code{in_use}) ist.
+
+@code{SHOW COLUMNS} listet die Spalten in einer gegebenen Tabelle auf. Wenn
+Sie die @code{FULL}-Option angeben, erhalten Sie auch die Berechtigungen,
+die Sie für jede Spalte besitzen. Wenn die Spaltentypen von dem abweichen,
+was Sie erwarten, nämlich, was Sie im @code{CREATE TABLE}-Statement
+angegeben haben, beachten Sie, dass MySQL manchmal Spaltentypen ändert.
+@xref{Silent column changes}.
+
+Das @code{DESCRIBE}-Statement gibt ähnliche Informationen wie @code{SHOW
+COLUMNS} aus. @xref{DESCRIBE, , @code{DESCRIBE}}.
+
+@code{SHOW FIELDS} ist ein Synonym für @code{SHOW COLUMNS}. @code{SHOW
+KEYS} ist ein Synonym für @code{SHOW INDEX}. Sie können die Spalten oder
+Indexe einer Tabelle auch mit @code{mysqlshow Datenbanktabelle} oder
+@code{mysqlshow -k Datenbanktabelle} anzeigen.
+
+@code{SHOW INDEX} gibt die Index-Informationen in einem Format aus, das dem
+@code{SQLStatistics}-Aufruf in ODBC stark ähnelt. Folgende Spalten werden
+zurückgegeben:
+
+@multitable @columnfractions .35 .65
+@item @strong{Spalte} @tab @strong{Bedeutung}
+@item @code{Table} @tab Name der Tabelle.
+@item @code{Non_unique} @tab 0, wenn der Index keine Duplikate enthalten darf.
+@item @code{Key_name} @tab Name des Indexes.
+@item @code{Seq_in_index} @tab Spaltensequenznummer im Index, zählt ab 1.
+@item @code{Column_name} @tab Spaltenname.
+@item @code{Collation} @tab Wie die Spalte im Index sortiert ist.
+ In MySQL können diese Werte @samp{A} (Ascending - aufsteigend)
+ oder @code{NULL} (Not sorted - unsortiert) sein.
+@item @code{Cardinality} @tab Anzahl der eindeutigen Werte im Index.
+ Dieser Wert wird durch Laufenlassen von @code{isamchk -a} aktualisiert.
+@item @code{Sub_part} @tab Anzahl der indizierten Zeichen, wenn die Spalte nur teilweise indiziert ist.
+ @code{NULL}, wenn der gesamte Schlüssel indiziert ist.
+@item @code{Comment} @tab Verschiedene Anmerkungen. Momentan teilt es nur mit,
+ ob der Index FULLTEXT ist oder nicht.
+@end multitable
+
+Beachten Sie: Weil @code{Cardinality} basierend auf statistischen Werten
+gezählt wird, die als Ganzzahlen gespeichert sind, ist es nicht
+notwendigerweise bei kleinen Tabellen korrekt.
+
+
+@node SHOW TABLE STATUS, SHOW STATUS, SHOW DATABASE INFO, SHOW
+@c German node SHOW TABLE STATUS
+@subsubsection @code{SHOW TABLE STATUS}
+
+@cindex anzeigen, Tabellen-Status
+@cindex Tabellen, Status anzeigen
+@cindex Status, Tabellen
+
+@example
+SHOW TABLE STATUS [FROM datenbank] [LIKE platzhalter]
+@end example
+
+@code{SHOW TABLE STATUS} (neu in Version 3.23) funktioniert wie @code{SHOW
+STATUS}, zeigt aber viele weitere Informationen über jede Tabelle. Diese
+Liste erhalten Sie auch mit dem @code{mysqlshow --status datenbank}-Befehl.
+Folgende Spalten werden zurückgegeben:
+
+@multitable @columnfractions .30 .70
+@item @strong{Spalte} @tab @strong{Bedeutung}
+@item @code{Name} @tab Name der Tabelle.
+@item @code{Type} @tab Typ der Tabelle. @xref{Table types}.
+@item @code{Row_format} @tab Das Zeilenspeicherformat (fest, dynamisch oder komprimiert).
+@item @code{Rows} @tab Anzahl der Zeilen.
+@item @code{Avg_row_length} @tab Durchschnittliche Zeilenlänge.
+@item @code{Data_length} @tab Länge der Daten-Datei.
+@item @code{Max_data_length} @tab Maximale Länge der Daten-Datei.
+@item @code{Index_length} @tab Länge der Index-Datei.
+@item @code{Data_free} @tab Anzahl der zugewiesenen (allocated), aber nicht benutzten Bytes.
+@item @code{Auto_increment} @tab Nächster autoincrement-Wert.
+@item @code{Create_time} @tab Wann die Tabelle erzeugt wurde.
+@item @code{Update_time} @tab Wann die Daten-Datei das letzte Mal aktualisiert wurde.
+@item @code{Check_time} @tab Wann die Tabelle das letzte Mal geprüft wurde.
+@item @code{Create_options} @tab Zusätzliche Optionen, die beim @code{CREATE TABLE} benutzt wurden.
+@item @code{Comment} @tab Der Kommentar, der beim Erzeugen der Tabelle angegeben wurde (oder einige Informationen, warum MySQL nicht auf die Tabelleninformationen zugreifen konnte).
+@end multitable
+
+Bei @code{InnoDB}-Tabellen wird im Tabellenkommentar der freie Platz im
+Tablespace ausgegeben.
+
+
+@node SHOW STATUS, SHOW VARIABLES, SHOW TABLE STATUS, SHOW
+@c German node SHOW STATUS
+@subsubsection @code{SHOW STATUS}
+
+@cindex @code{mysqladmin}
+@code{SHOW STATUS} zeigt Server-Status-Informationen an (wie
+@code{mysqladmin extended-status}). Die Ausgabe ähnelt der unten stehenden,
+obwohl Format und Anzahl der Zeilen wahrscheinlich abweichen:
+
+@example
++--------------------------+------------+
+| Variable_name | Value |
++--------------------------+------------+
+| Aborted_clients | 0 |
+| Aborted_connects | 0 |
+| Bytes_received | 155372598 |
+| Bytes_sent | 1176560426 |
+| Connections | 30023 |
+| Created_tmp_disk_tables | 0 |
+| Created_tmp_tables | 8340 |
+| Created_tmp_files | 60 |
+| Delayed_insert_Threads | 0 |
+| Delayed_writes | 0 |
+| Delayed_errors | 0 |
+| Flush_commands | 1 |
+| Handler_delete | 462604 |
+| Handler_read_first | 105881 |
+| Handler_read_key | 27820558 |
+| Handler_read_next | 390681754 |
+| Handler_read_prev | 6022500 |
+| Handler_read_rnd | 30546748 |
+| Handler_read_rnd_next | 246216530 |
+| Handler_update | 16945404 |
+| Handler_write | 60356676 |
+| Key_blocks_used | 14955 |
+| Key_read_requests | 96854827 |
+| Key_reads | 162040 |
+| Key_write_requests | 7589728 |
+| Key_writes | 3813196 |
+| Max_used_connections | 0 |
+| Not_flushed_key_blocks | 0 |
+| Not_flushed_delayed_rows | 0 |
+| Open_tables | 1 |
+| Open_files | 2 |
+| Open_streams | 0 |
+| Opened_tables | 44600 |
+| Questions | 2026873 |
+| Select_full_join | 0 |
+| Select_full_range_join | 0 |
+| Select_range | 99646 |
+| Select_range_check | 0 |
+| Select_scan | 30802 |
+| Slave_running | OFF |
+| Slave_open_temp_tables | 0 |
+| Slow_launch_threads | 0 |
+| Slow_queries | 0 |
+| Sort_merge_passes | 30 |
+| Sort_range | 500 |
+| Sort_rows | 30296250 |
+| Sort_scan | 4650 |
+| Table_locks_immediate | 1920382 |
+| Table_locks_waited | 0 |
+| Threads_cached | 0 |
+| Threads_created | 30022 |
+| Threads_connected | 1 |
+| Threads_running | 1 |
+| Uptime | 80380 |
++--------------------------+------------+
+@end example
+
+@cindex variables, status
+The status variables listed höher have the following Bedeutung:
+
+@multitable @columnfractions .35 .65
+@item @strong{Variable} @tab @strong{Bedeutung}
+@item @code{Aborted_clients} @tab Anzahl der Verbindungen, die abgebrochen
+wurden, weil der Client starb, ohne die Verbindung ordnungsgemäß zu
+schließen. @xref{Communication errors}.
+@item @code{Aborted_connects} @tab Anzahl der fehlgeschlagenen Versuche,
+sich mit dem MySQL-Server zu verbinden. @xref{Communication errors}.
+@item @code{Bytes_received} @tab Anzahl der Bytes, die von allen Clients
+empfangen wurden.
+@item @code{Bytes_sent} @tab Anzahl der Bytes, die an alle Clients gesendet
+wurden.
+@item @code{Connections} @tab Anzahl der Verbindungsversuche zum MySQL-Server.
+@item @code{Created_tmp_disk_tables} @tab Anzahl der (implizit) auf der
+Platte erzeugten temporären Tabellen bei der Ausführung von Statements.
+@item @code{Created_tmp_tables} @tab Anzahl der (implizit) im
+Arbeitsspeicher erzeugten temporären Tabellen bei der Ausführung von
+Statements.
+@item @code{Created_tmp_files} @tab Wie viele temporäre Dateien
+@code{mysqld} erzeugt hat.
+@item @code{Delayed_insert_Threads} @tab Anzahl der verzögerten
+Insert-Handler-Threads in Benutzung.
+@item @code{Delayed_writes} @tab Anzahl der Zeilen, die mit @code{INSERT
+DELAYED} geschrieben wurden.
+@item @code{Delayed_errors} @tab Anzahl der Zeilen, die mit @code{INSERT
+DELAYED} geschrieben wurden, und bei denen irgend ein Fehler auftrat
+(wahrscheinlich @code{duplicate key}).
+@item @code{Flush_commands} @tab Anzahl der ausgeführten @code{FLUSH}-Befehle.
+@item @code{Handler_delete} @tab Wie oft eine Zeile aus einer Tabelle
+gelöscht wurde.
+@item @code{Handler_read_first} @tab Wie oft der erste Eintrag aus einem
+Index gelesen wurde. Wenn dieser Wert hoch ist, legt das nahe, dass der
+Server viele komplette Index-Scans macht (zum Beispiel @code{SELECT spalte1
+FROM foo}, unter der Annahme, dass spalte1 indiziert ist).
+@item @code{Handler_read_key} @tab Anzahl der Anfragen, eine Zeile
+basierend auf einem Schlüssel zu lesen. Wenn dieser Wert hoch ist, ist das
+ein gutes Indiz dafür, dass Ihre Anfragen und Tabellen korrekt indiziert
+sind.
+@item @code{Handler_read_next} @tab Anzahl der Anfragen, die nächste Zeile
+in der Reihenfolge des Schlüssels zu lesen. Dieser Wert wird herauf
+gezählt, wenn Sie eine Index-Spalte mit einer Bereichsbeschränkung (Limit)
+abfragen. Er wird ebenfalls herauf gezählt, wenn Sie einen Index-Scan
+durchführen.
+@item @code{Handler_read_rnd} @tab Anzahl der Anfragen, eine Zeile
+basierend auf einer festen Position zu lesen. Dieser Wert wird hoch sein,
+wenn Sie viele Anfragen ausführen, die erfordern, dass das Ergebnis
+sortiert wird.
+@item @code{Handler_read_rnd_next} @tab Anzahl der Anfragen, die nächste
+Zeile in der Daten-Datei zu lesen. Dieser Wert wird hoch sein, wenn Sie
+viele Tabellen-Scans durchführen. Im Allgemeinen weist das darauf hin, dass
+Ihre Tabellen nicht korrekt indiziert sind, oder dass Ihre Anfragen nicht
+so geschrieben sind, dass Sie Vorteile aus den Indexen ziehen, die Sie
+haben.
+@item @code{Handler_update} @tab Anzahl der Anfragen, eine Zeile in einer
+Tabelle zu aktualisieren.
+@item @code{Handler_write} @tab Anzahl der Anfragen, eine Zeile in eine
+Tabelle einzufügen.
+@item @code{Key_blocks_used} @tab Die Anzahl der benutzten Blocks im
+Schlüssel-Cache.
+@item @code{Key_read_requests} @tab Die Anzahl der Anfragen, einen
+Schlüssel-Block aus dem Cache zu lesen.
+@item @code{Key_reads} @tab Die Anzahl physikalischer Lesezugriffen eines
+Schlüssel-Blocks von der Platte.
+@item @code{Key_write_requests} @tab Die Anzahl der Anfragen, einen
+Schlüssel-Block in den Cache zu schreiben.
+@item @code{Key_writes} @tab Die Anzahl physikalischer Schreibvorgänge
+eines Schlüssel-Blocks auf Platte.
+@item @code{Max_used_connections} @tab Die höchste Anzahl von Verbindungen,
+die gleichzeitig in Benutzung sind.
+@item @code{Not_flushed_key_blocks} @tab Schlüssel-Blöcke im
+Schlüssel-Cache, die verändert wurden, aber noch nicht auf die Platte
+zurück geschrieben (flush).
+@item @code{Not_flushed_delayed_rows} @tab Anzahl der Zeilen, die in
+@code{INSERT DELAY}-Warteschleifen darauf warten, geschrieben zu werden.
+@item @code{Open_tables} @tab Anzahl der offenen Tabellen.
+@item @code{Open_files} @tab Anzahl der offenen Dateien.
+@item @code{Open_streams} @tab Anzahl der offenen Streams (hauptsächlich
+zum Loggen benutzt).
+@item @code{Opened_tables} @tab Anzahl der Tabellen, die geöffnet wurden.
+@item @code{Select_full_join} @tab Anzahl der Joins ohne Schlüssel (sollte
+0 sein).
+@item @code{Select_full_range_join} @tab Anzahl der Joins, bei denen eine
+Bereichssuche auf die Referenztabelle statt fand.
+@item @code{Select_range} @tab Anzahl der Joins, bei denen Bereiche auf die
+erste Tabelle benutzt wurden. (Es ist normalerweise unkritisch, wenn dieser
+Wert hoch ist.)
+@item @code{Select_scan} @tab Anzahl der Joins, bei denen die erste Tabelle
+gescannt wurde.
+@item @code{Select_range_check} @tab Anzahl der Joins ohne Schlüssel, bei
+denen nach jeder Zeile auf Schlüsselbenutzung geprüft wurde (sollte 0
+sein).
+@item @code{Questions} @tab Anzahl der Anfragen, die zum Server geschickt
+wurden.
+@item @code{Slave_open_temp_tables} @tab Anzahl der temporären Tabellen,
+die momentan vom Slave-Thread geöffnet sind.
+@item @code{Slow_launch_threads} @tab Anzahl der Threads, die länger als
+@code{slow_launch_time} brauchten, um sich zu verbinden.
+@item @code{Slow_queries} @tab Anzahl der Anfragen, die länger als
+@code{long_query_time} benötigten. @xref{Slow query log}.
+@item @code{Sort_merge_passes} @tab Anzahl der Verschmelzungen (Merge), die
+von einem Sortiervorgang benötigt wurden. Wenn dieser Wert hoch ist,
+sollten Sie in Betracht ziehen, @code{sort_buffer} herauf zu setzen.
+@item @code{Sort_range} @tab Anzahl der Sortiervorgänge, die mit Bereichen
+durchgeführt wurden.
+@item @code{Sort_rows} @tab Anzahl der sortierten Zeilen.
+@item @code{Sort_scan} @tab Anzahl der Sortiervorgänge, die durchgeführt
+wurden, indem die Tabelle gescannt wurde.
+@item @code{Table_locks_immediate} @tab Wie oft eine Tabellensperre sofort
+erlangt wurde. Verfügbar nach Version 3.23.33.
+@item @code{Table_locks_waited} @tab Wie oft eine Tabellensperre nicht
+sofort erlangt werden konnte und gewartet werden musst. Wenn dieser Wert
+hoch ist und Sie Performance-Probleme haben, sollten Sie zunächst Ihre
+Anfragen optimieren und dann entweder Ihre Tabelle(n) zerteilen oder
+Replikation benutzen. Verfügbar nach Version 3.23.33.
+@item @code{Threads_cached} @tab Anzahl der Threads im Thread-Cache.
+@item @code{Threads_connected} @tab Anzahl der momentan offenen
+Verbindungen.
+@item @code{Threads_created} @tab Anzahl der Threads, die zur Handhabung
+von Verbindungen erzeugt wurden.
+@item @code{Threads_running} @tab Anzahl der Threads, die nicht schlafen.
+@item @code{Uptime} @tab Seit wie vielen Sekunden der Server hoch gefahren
+ist.
+@end multitable
+
+Einige Anmerkungen zum oben Aufgeführten:
+
+@itemize @bullet
+@item
+Wenn @code{Opened_tables} hoch ist, ist Ihre @code{table_cache}-Variable
+wahrscheinlich zu niedrig.
+@item
+Wenn @code{key_reads} hoch ist, ist Ihr @code{key_cache} wahrscheinlich zu
+klein. Die Cache-Zugriffsrate kann mit @code{key_reads} /
+@code{key_read_requests} berechnet werden.
+@item
+Wenn @code{Handler_read_rnd} hoch ist, haben Sie wahrscheinlich viele
+Anfragen, die MySQL zwingen, ganze Tabellen zu scannen, oder Sie haben
+Joins, die Schlüssel nicht richtig benutzen.
+@item
+Wenn @code{Threads_created} hoch ist, sollten Sie eventuell die
+@code{Thread_cache_size}-Variable herauf setzen.
+@item
+Wenn @code{Created_tmp_disk_tables} hoch ist, sollten Sie eventuell die
+@code{tmp_table_size}-Variable herauf setzen, damit temporäre Tabellen im
+Speicher erzeugt werden statt auf der Platte.
+@end itemize
+
+
+@node SHOW VARIABLES, SHOW LOGS, SHOW STATUS, SHOW
+@c German node SHOW VARIABLES
+@subsubsection @code{SHOW VARIABLES}
+
+@example
+SHOW VARIABLES [LIKE platzhalter]
+@end example
+
+@code{SHOW VARIABLES} zeigt die Werte einiger MySQL-Systemvariablen. Sie
+erhalten diese List auch mit dem @code{mysqladmin variables}-Befehl. Wenn
+die Vorgabewerte unpassend sind, können Sie die meisten dieser Variablen
+mit Kommandozeilenoptionen setzen, wenn Sie @code{mysqld} hoch fahren.
+@xref{Command-line options}.
+
+Die Ausgabe ähnelt der unten stehenden,
+obwohl Format und Anzahl der Zeilen wahrscheinlich abweichen:
+
+@example
++-------------------------+---------------------------+
+| Variable_name | Value |
++-------------------------+---------------------------+
+| ansi_mode | OFF |
+| back_log | 50 |
+| basedir | /my/monty/ |
+| bdb_cache_size | 16777216 |
+| bdb_log_buffer_size | 32768 |
+| bdb_home | /my/monty/data/ |
+| bdb_max_lock | 10000 |
+| bdb_logdir | |
+| bdb_shared_data | OFF |
+| bdb_tmpdir | /tmp/ |
+| binlog_cache_size | 32768 |
+| concurrent_insert | ON |
+| connect_timeout | 5 |
+| datadir | /my/monty/data/ |
+| delay_key_write | ON |
+| delayed_insert_limit | 100 |
+| delayed_insert_timeout | 300 |
+| delayed_queue_size | 1000 |
+| flush | OFF |
+| flush_time | 0 |
+| have_bdb | YES |
+| have_innodb | YES |
+| have_raid | YES |
+| have_openssl | NO |
+| init_file | |
+| interactive_timeout | 28800 |
+| join_buffer_size | 131072 |
+| key_buffer_size | 16776192 |
+| language | /my/monty/share/english/ |
+| large_files_support | ON |
+| log | OFF |
+| log_update | OFF |
+| log_bin | OFF |
+| log_slave_updates | OFF |
+| long_query_time | 10 |
+| low_priority_updates | OFF |
+| lower_case_table_names | 0 |
+| max_allowed_packet | 1048576 |
+| max_binlog_cache_size | 4294967295 |
+| max_connections | 100 |
+| max_connect_errors | 10 |
+| max_delayed_threads | 20 |
+| max_heap_table_size | 16777216 |
+| max_join_size | 4294967295 |
+| max_sort_length | 1024 |
+| max_tmp_tables | 32 |
+| max_write_lock_count | 4294967295 |
+| myisam_recover_options | DEFAULT |
+| myisam_sort_buffer_size | 8388608 |
+| net_buffer_length | 16384 |
+| net_read_timeout | 30 |
+| net_retry_count | 10 |
+| net_write_timeout | 60 |
+| open_files_limit | 0 |
+| pid_file | /my/monty/data/donna.pid |
+| port | 3306 |
+| protocol_version | 10 |
+| record_buffer | 131072 |
+| query_buffer_size | 0 |
+| safe_show_database | OFF |
+| server_id | 0 |
+| skip_locking | ON |
+| skip_networking | OFF |
+| skip_show_database | OFF |
+| slow_launch_time | 2 |
+| socket | /tmp/mysql.sock |
+| sort_buffer | 2097116 |
+| table_cache | 64 |
+| table_type | MYISAM |
+| Thread_cache_size | 4 |
+| Thread_stack | 65536 |
+| tmp_table_size | 1048576 |
+| tmpdir | /tmp/ |
+| version | 3.23.29a-gamma-debug |
+| wait_timeout | 28800 |
++-------------------------+---------------------------+
+@end example
+
+Jede Option ist unten beschrieben. Die Werte für Puffergrößen, Längen und
+Stack-Größen sind in Bytes angegeben. Sie können Wert mit den Suffixen
+@samp{K} oder @samp{M} angeben, um Kilobytes oder Megabytes zu
+kennzeichnen. @code{16M} zum Beispiel bedeutet 16 Megabytes. Bei den
+Suffixen spielt Groß-/Kleinschreibung keine Rolle, @code{16M} und
+@code{16m} sind äquivalent:
+
+@cindex Variablen, Werte
+@table @code
+@item @code{ansi_mode}.
+Ist @code{ON}, wenn @code{mysqld} mit @code{--ansi} gestartet wurde.
+@xref{ANSI mode}.
+
+@item @code{back_log}
+Die Anzahl unerledigter Verbindungsanforderung, die MySQL haben kann. Dies
+kommt ins Spiel, wenn der Haupt-Thread von MySQL @strong{SEHR} viele
+Verbindungsanforderungen in sehr kurzer Zeit erhält. Dann dauert es etwas
+(wenngleich sehr kurz), damit der Haupt-Thread die Verbindung prüfen und
+einen neuen Thread starten kann. Der @code{back_log}-Wert zeigt an, wie
+viele Verbindungen während dieser kurzen Zeit gestapelt (gestackt) werden können, bevor
+MySQL für einen Moment aufhört, neue Anforderungen zu beantworten. Sie
+brauchen diesen Wert nur dann herauf setzen, wenn Sie eine große Zahl von
+Verbindungen in kurzer Zeit erwarten.
+
+Mit anderen Worten ist dieser Wert die Größe der Listen-Queue
+(Warteschlange) für herein kommende TCP/IP-Verbindungen. Ihr Betriebssystem
+hat seine eigene Beschränkung hinsichtlich der Größe dieser Queue. Die
+Handbuchseiten zum Unix-@code{listen(2)}-System sollten hier weitere
+Details haben. Sehen Sie in der Dokumentation Ihres Betriebssystems nach,
+wie hoch der Wert dieser Variablen maximal sein kann. Wenn Sie versuchen,
+@code{back_log} höher als die Begrenzung Ihres Betriebssystems zu setzen,
+ist das ineffektiv.
+
+@item @code{basedir}
+Der Wert der @code{--basedir}-Option.
+
+@item @code{bdb_cache_size}
+Der zugewiesene Puffer, um Index und Zeilen bei @code{BDB}-Tabellen zu
+cachen. Wenn Sie keine @code{BDB}-Tabellen benutzen, sollten Sie
+@code{mysqld} mit @code{--skip-bdb} starten, um für diesen Cache keinen
+Arbeitsspeicher zu verschwenden.
+
+@item @code{bdb_log_buffer_size}
+Der zugewiesene Puffer, um Index und Zeilen bei @code{BDB}-Tabellen zu
+cachen. Wenn Sie keine @code{BDB}-Tabellen benutzen, sollten Sie diesen
+Wert auf o setzen und @code{mysqld} mit @code{--skip-bdb} starten, um für
+diesen Cache keinen Arbeitsspeicher zu verschwenden.
+
+@item @code{bdb_home}
+Der Wert der @code{--bdb-home}-Option.
+
+@item @code{bdb_max_lock}
+Die maximale Anzahl von Sperren (Vorgabewert: 1000), die bei einer
+@code{BDB}-Tabelle aktiv sein können. Sie sollten diesen Wert herauf
+setzen, wenn Sie Fehler folgender Art bekommen: @code{bdb:
+Lock table is out of available locks} oder @code{Got error 12 from ...},
+wenn Sie lange Transaktionen durchführen oder wenn @code{mysqld} viele
+Zeile untersuchen muss, um die Anfrage zu berechnen.
+
+@item @code{bdb_logdir}
+Der Wert der @code{--bdb-logdir}-Option.
+
+@item @code{bdb_shared_data}
+Ist @code{ON}, wenn Sie @code{--bdb-shared-data} benutzen.
+
+@item @code{bdb_tmpdir}
+Der Wert der @code{--bdb-tmpdir}-Option.
+
+@item @code{binlog_cache_size}. Die Größe des Caches, in dem
+SQL-Statements für das Binär-Log während einer Transaktion vorgehalten
+werden. Wenn Sie oft große, aus vielen Statements bestehende Transaktionen
+durchführen, können Sie diesen Wert herauf setzen, um mehr Performance zu
+erzielen. @xref{COMMIT}.
+
+@item @code{character_set}
+Der vorgabemäßige Zeichensatz.
+
+@item @code{character_sets}
+Die unterstützten Zeichensätze.
+
+@item @code{concurrent_inserts}
+Falls @code{ON} (Vorgabe), läßt MySQL @code{INSERT} auf
+@code{MyISAM}-Tabellen zu, auf die zur gleichen Zeit @code{SELECT}-Anfragen
+laufen. Sie können diese Option ausschalten, indem Sie @code{mysqld} mit
+@code{--safe} oder @code{--skip-new} starten.
+
+@cindex timeout
+@item @code{connect_timeout}
+Die Anzahl von Sekunden, die der @code{mysqld}-Server auf ein
+Verbindungspaket wartet, bevor er mit @code{Bad handshake} antwortet.
+
+@item @code{datadir}
+Der Wert der @code{--datadir}-Option.
+
+@item @code{delay_key_write}
+Falls angeschaltet (Vorgabe), akzeptiert MySQL die
+@code{delay_key_write}-Option von @code{CREATE TABLE}. Das heißt, dass der
+Schlüsselpuffer für Tabellen bei dieser Option nicht bei jeder
+Index-Aktualisierung auf Platte zurückgeschrieben (flush) wird, sondern
+nur, wenn eine Tabelle geschlossen wird. Das beschleunigt Schreibvorgänge
+auf Schlüssel ganz erheblich, aber Sie sollten eine automatische Prüfung
+aller Tabellen mit @code{myisamchk --fast --force} hinzufügen, wenn Sie
+diese Option benutzen. Beachten Sie: Wenn Sie @code{mysqld} mit der
+@code{--delay-key-write-for-all-tables}-Option startet, heißt das, dass
+alle Tabelle so behandelt werden, als wenn sie mit der
+@code{delay_key_write}-Option erzeugt worden wären. Sie können diesen Flag
+löschen, wenn Sie @code{mysqld} mit @code{--skip-new} oder
+@code{--safe-mode} starten.
+
+@item @code{delayed_insert_limit}
+Nachdem @code{delayed_insert_limit} Zeilen eingefügt wurden, prüft der
+@code{INSERT DELAYED}-Handler, ob noch irgend welche
+@code{SELECT}-Statements anhängig sind. Falls ja, wird deren Ausführung
+zugelassen, bevor weiter gemacht wird.
+
+@item @code{delayed_insert_timeout}
+Wie lange ein @code{INSERT DELAYED}-Thread auf @code{INSERT}-Statements
+warten soll, bevor abgebrochen wird.
+
+@item @code{delayed_queue_size}
+Welche Warteschleifen-(Queue)-Speichergröße (in Zeilen) für die Handhabung
+von @code{INSERT DELAYED} zugewiesen werden soll. Wenn die Queue voll ist,
+wartet jeder Client, der @code{INSERT DELAYED} ausführt, bis es wieder
+Platz in der Queue gibt.
+
+@item @code{flush}
+Ist @code{ON}, wenn Sie MySQL mit der @code{--flush}-Option gestartet
+haben.
+
+@item @code{flush_time}
+Wenn diese Variable auf einen Wert ungleich 0 gesetzt wird, dann werden
+alle @code{flush_time} Sekunden alle Tabelle geschlossen (um Ressourcen
+frei zu geben und Dinge auf Platte zurück zu schreiben). Diese Option
+empfehlen wir nur auf Windows 95, Windows 98 oder auf Systemen, auf denen
+Sie sehr wenige Ressourcen haben.
+
+@item @code{have_bdb}
+Ist @code{YES}, wenn @code{mysqld} Berkeley-DB-Tabellen unterstützt. Ist
+@code{DISABLED}, wenn @code{--skip-bdb} benutzt wird.
+@item @code{have_innodb}
+Ist @code{YES}, wenn @code{mysqld} InnoDB-Tabellen unterstützt. Ist
+@code{DISABLED}, wenn @code{--skip-innodb} benutzt wird.
+@item @code{have_raid}
+Ist @code{YES}, wenn @code{mysqld} die @code{RAID}-Option unterstützt.
+@item @code{have_openssl}
+Ist @code{YES}, wenn @code{mysqld} SSL (Verschlüsselung) auf dem
+Client-/Server-Protokoll unterstützt.
+
+@item @code{init_file}
+Der Name der Datei, die mit der @code{--init-file}-Option angegeben wurde,
+als Sie den Server starteten. Das ist eine Datei mit SQL-Statements, die
+der Server beim Start ausführen soll.
+
+@item @code{interactive_timeout}
+Die Anzahl von Sekunden, die der Server bei einer interaktiven Verbindung
+wartet, bis er sie schließt. Ein interaktiver Client ist definiert als
+Client, der die @code{CLIENT_INTERACTIVE}-Option für
+@code{mysql_real_connect()} benutzt. Siehe auch @code{wait_timeout}.
+
+@item @code{join_buffer_size}
+Die Größe des Puffers, der für volle Joins benutzt wird (Joins, die keine
+Indexe benutzen). Der Puffer wird einmal pro vollem Join zwischen zwei
+Tabellen zugewiesen. Setzen Sie diesen Wert herauf, um einen schnelleren
+vollen Join zu erhalten, wenn das Addieren von Indexen nicht möglich ist.
+(Normalerweise ist die beste Art, schnelle Joins zu erhalten, das Addieren
+von Indexen.)
+
+@c Make texi2html Support index @anchor{Index cache size}. Then change
+@c some xrefs to point here
+@cindex Indexe, Blockgröße
+@item @code{key_buffer_size}
+Index-Blöcke werden gepuffert und von allen Threads geteilt.
+@code{key_buffer_size} ist die Größe des Puffers, der für Index-Blöcke
+benutzt wird.
+
+Setzen Sie diesen Wert herauf, um eine bessere Index-Handhabung zu erzielen
+(für alle Lesevorgänge und für mehrfache Schreibvorgänge), so weit, wie Sie
+es sich leisten können; 64 MB auf einer 256-MB-Maschine, auf der
+hauptsächlich MySQL läuft, ist ein gebräuchlicher Wert. Wenn Sie diesen
+Wert allerdings zu hoch setzen (mehr als 50% Ihres gesamten
+Arbeitsspeichers), kann es sein, dass Ihr System anfängt auszulagern
+(Paging), was SEHR langsam werden kann. Denken Sie daran, dass Sie Platzt
+für den Dateisystem-Cache des Betriebssystems lassen müssen, weil MySQL
+Daten-Lesen nicht cachet.
+
+Sie können die Performance des Schlüsselpuffers mit @code{show status}
+überprüfen und sich die Variablen @code{Key_read_requests},
+@code{Key_reads}, @code{Key_write_requests} und @code{Key_writes} ansehen.
+Das Verhältnis @code{Key_reads/Key_read_request} sollte normalerweise <
+0,01 sein. @code{Key_write/Key_write_requests} ist üblicherweise nahe 1,
+wenn Sie hauptsächlich Aktualisieren (Update) und Löschen (Delete)
+ausführen, kann aber sehr viel kleiner werden, wenn Sie tendenziell
+Aktualisierungen ausführen, die viele Zeilen gleichzeitig betreffen, oder
+wenn Sie @code{delay_key_write} benutzen. @xref{SHOW}.
+
+Um noch mehr Geschwindigkeit beim Schreiben vieler Zeilen auf einmal zu
+erhalten, benutzen Sie @code{LOCK TABLES}. @xref{LOCK TABLES, , @code{LOCK TABLES}}.
+
+@item @code{language}
+Die Sprache, in der Fehlermeldungen ausgegeben werden.
+
+@item @code{large_file_support}
+Ob @code{mysqld} mit Optionen für die Unterstützung großer Dateien
+kompiliert wurde.
+
+@item @code{locked_in_memory}
+Ob @code{mysqld} mit @code{--memlock} in den Speicher gesperrt wurde.
+
+@item @code{log}
+Ob das Loggen aller Anfragen angeschaltet ist.
+
+@item @code{log_update}
+Ob das Update-Log angeschaltet ist.
+
+@item @code{log_bin}
+Ob das Binär-Log angeschaltet ist.
+
+@item @code{log_slave_updates}
+Ob Aktualisierungen vom Slave geloggt werden sollen.
+
+@item @code{long_query_time}
+Wenn eine Anfrage länger als diesen Wert (in Sekunden) benötigt, wird der
+@code{Slow_queries}-Zähler hoch gezählt. Wenn Sie @code{--log-slow-queries}
+benutzen, wird die Anfrage in die Slow-Query-Logdatei geschrieben.
+@xref{Slow query log}.
+
+@item @code{lower_case_table_names}
+Wenn auf 1 gesetzt, werden Tabellennamen in Kleinschreibung auf Platte
+gespeichert. Tabellennamen sind dann unabhängig von der verwendeten
+Groß-/Kleinschreibung.
+@xref{Case sensitivity}.
+
+@item @code{max_allowed_packet}
+Die maximale Größe eine Pakets. Der Nachrichtenpuffer wird auf
+@code{net_buffer_length} Bytes Länge initialisiert, kann aber wenn nötig
+bis zu @code{max_allowed_packet} Bytes Groß werden. Der Vorgabewert ist
+klein, um große (möglicherweise falsche) Pakete abzufangen. Sie müssen
+diesen Wert erhöhen, wenn Sie große @code{BLOB}-Spalten verwenden. Er
+sollte so Groß sein wie die größte @code{BLOB}-Spalte, die Sie verwenden
+wollen. Das aktuelle Protokoll begrenzt @code{max_allowed_packet} auf 16 MB.
+
+@item @code{max_binlog_cache_size}
+Wenn eine Transaktion aus mehreren Statements mehr als diese Speichermenge
+benötigt, erhält man den Fehler "Multi-Statement transaction required more
+than 'max_binlog_cache_size' bytes of storage".
+
+@item @code{max_binlog_size}
+Verfügbar nach Version 3.23.33. Wenn ein Schreibvorgang ins binäre
+(Replikations-) Log den angegebenen Wert übersteigt, werden die Logs
+rotiert. Sie können den Wert auf weniger als 1024 Bytes setzen oder auf
+mehr als 1 GB. Vorgabe ist 1 GB.
+
+@item @code{max_connections}
+Die Anzahl von Clients, die gleichzeitig verbunden sind. Wenn Sie diesen
+Wert hoch setzen, wird die Anzahl der Datei-Deskriptoren heraufgesetzt, die
+@code{mysqld} benötigt. Siehe weiter unten, Bemerkungen zu Beschränkungen
+bei Datei-Deskriptoren. @xref{Too many connections}.
+
+@item @code{max_connect_errors}
+Wenn es mehr als diese Anzahl unterbrochener Verbindungen von einem Host
+gibt, wird dieser Host von weiteren Verbindungen abgeschnitten. Sie können
+diese Sperre mit dem @code{FLUSH HOSTS}-Befehl aufheben.
+
+@item @code{max_delayed_Threads}
+Nicht mehr als diese Anzahl von Threads zulassen, um @code{INSERT
+DELAYED}-Statements abzuarbeiten. Wenn Sie versuchen, Daten in eine neue
+Tabelle einzufügen, wenn alle @code{INSERT DELAYED}-Threads in Benutzung
+sind, wird die Zeile eingefügt, als ob das @code{DELAYED}-Attribut nicht
+angegeben wäre.
+
+@item @code{max_heap_table_size}
+Kein Erzeugen von Heap-Tabellen zulassen, die größer als dieser Wert sind.
+
+@item @code{max_join_size}
+Joins, die wahrscheinlich mehr als @code{max_join_size} Datensätze lesen
+werden, geben einen Fehler zurück. Setzen Sie diesen Wert, wenn Ihre
+Benutzer dazu neigen, Joins auszuführen, denen eine @code{WHERE}-Klausel
+fehlt und die daher lange Zeit benötigen und womöglich Millionen von Zeilen
+zurück geben.
+
+@item @code{max_sort_length}
+Die Anzahl von Bytes, die beim Sortieren von @code{BLOB}- oder
+@code{TEXT}-Werten benutzt werden (nur die ersten @code{max_sort_length}
+Bytes jedes Werts werden benutzt, der Rest wird ignoriert).
+
+@item @code{max_user_connections}
+Die maximale Anzahl aktiver Verbindungen für einen einzelnen Benutzer (0 =
+keine Beschränkung).
+
+@item @code{max_tmp_tables}
+(Diese Option macht bislang noch nichts.)
+Maximale Anzahl von temporären Tabellen, die ein Client zur selben Zeit
+offen halten darf.
+
+@item @code{max_write_lock_count}
+Nach dieser Anzahl Schreibsperren wird einigen Lesesperren erlaubt,
+zwischendurch zu laufen.
+
+@item @code{myisam_recover_options}
+Der Wert der @code{--myisam-recover}-Option.
+
+@item @code{myisam_sort_buffer_size}
+Der Puffer, der beim Sortieren des Indexes zugewiesen wird, wenn man ein
+@code{REPAIR} oder ausführt oder Indexe mit @code{CREATE INDEX} oder
+@code{ALTER TABLE} erzeugt.
+
+@item @code{myisam_max_extra_sort_file_size}.
+Wenn das Erzeugen der temporären Datei für schnelle Index-Erzeugung um
+diesen Wert größer sein würde als die Benutzung des Schlüssel-Caches, wird
+die Schlüssel-Cache-Methode bevorzugt. Wird hauptsächlich benutzt, um lange
+Zeichen-Schlüssel in großen Tabellen zu zwingen, die langsamere
+Schlüssel-Cache-Methode zu benutzen, um den Index zu erzeugen.
+@strong{HINWEIS:} Dieser Parameter wird in Megabytes angegeben!
+
+@item @code{myisam_max_sort_file_size}
+Die maximale Größe der temporären Datei, die MySQL benutzen darf, während
+es den Index erzeugt (während @code{REPAIR}, @code{ALTER TABLE} oder
+@code{LOAD DATA INFILE}). Wenn die Datei größer als dieser Wert würde, wird
+der Index über den Schlüssel-Cache erzeugt (was langsamer ist).
+@strong{HINWEIS:} Dieser Parameter wird in Megabytes angegeben!
+
+@item @code{net_buffer_length}
+Der Kommunikationspuffer wird zwischen Anfragen auf diesen Wert zurück
+gesetzt. Normalerweise sollte das nicht geändert werden, aber wenn Sie sehr
+wenig Arbeitsspeicher haben, können Sie ihn auf die erwartete Größe einer
+Anfrage setzen (also die erwartete Länge von SQL-Statements, die von
+Clients gesendet werden. Wenn Statements diese Länge überschreiten, wird
+der Puffer automatisch vergrößert, bis zu @code{max_allowed_packet} Bytes.)
+
+@item @code{net_read_timeout}
+Anzahl von Sekunden, die auf weitere Daten von einer Verbindung gewartet
+wird, bevor das Lesen abgebrochen wird. Beachten Sie: Wenn keine Daten von
+einer Verbindung erwartet werden, ist der Timeout durch
+@code{write_timeout} definiert. Siehe auch @code{slave_read_timeout}.
+
+@item @code{net_retry_count}
+Wenn ein Lesevorgang auf einem Kommunikations-Port unterbrochen wird, wird
+so oft wie angegeben neu versucht, bevor aufgegeben wird. Dieser Wert
+sollte auf @code{FreeBSD} recht hoch sein, weil interne
+Unterbrechnungsanforderungen (Interrupts) an alle Threads gesendet werden.
+
+@item @code{net_write_timeout}
+Anzahl von Sekunden, die auf das Schreiben eines Blocks zu einer Verbindung
+gewartet wird, bis das Schreiben abgebrochen wird.
+
+@item @code{open_files_limit}
+Wenn dieser Wert ungleich 0 ist, benutzt @code{mysqld} Datei-Deskriptoren,
+die mit @code{setrlimit()} benutzt werden. Wenn dieser Wert gleich 0 ist,
+reserviert @code{mysqld} @code{max_connections * 5} oder
+@code{max_connections + table_cache * 2} (je nachdem, was größer ist)
+Anzahl von Dateien. Sie sollten diesen Wert herauf setzen, wenn
+@code{mysqld} Ihnen die Fehlermeldung 'Too many open files' gibt.
+
+@item @code{pid_file}
+Der Wert der @code{--pid-file}-Option.
+
+@item @code{port}
+Der Wert der @code{--port}-Option.
+
+@item @code{protocol_version}
+Die Protokoll-Version, die vom MySQL-Server benutzt wird.
+
+@item @code{record_buffer}
+Jeder Thread, der einen sequentiellen Scan ausführt, alloziert einen Puffer
+dieser Größe für jede Tabelle, die er scannt. Wenn Sie viele sequentielle
+Scans ausführen, sollten Sie diesen Wert herauf setzen.
+
+@item @code{record_rnd_buffer}
+Wenn Zeilen nach einem Sortiervorgang in sortierter Reihenfolge gelesen
+werden, werden die Zeilen aus diesem Puffer gelesen, um Suchvorgänge auf
+der Platte zu vermeiden. Wenn dieser Wert nicht gesetzt ist, wird er auf
+den Wert von @code{record_buffer} gesetzt.
+
+@item @code{query_buffer_size}
+Die anfängliche Zuweisung des Anfragen-Puffers. Wenn die meisten Ihrer
+Anfragen lang sind (zum Beispiel beim Einfügen von Blobs), sollten Sie
+diesen Wert herauf setzen!
+
+@item @code{safe_show_databases}
+Keine Datenbanken zeigen, wenn der Benutzer keinerlei Datenbank- oder
+Tabellen-Berechtigungen dafür hat. Das kann die Sicherheit erhöhen, wenn
+Sie sich Sorgen machen, dass Leute in der Lage sind zu sehen, welche
+Datenbanken andere Benutzer haben. Siehe auch
+@code{skip_show_databases}.
+
+@item @code{server_id}
+Der Wert der @code{--server-id}-Option.
+
+@item @code{skip_locking}
+Ist @code{OFF}, wenn @code{mysqld} externes Sperren benutzt.
+
+@item @code{skip_networking}
+Ist @code{ON}, wenn nur lokale (Socket-) Verbindungen zugelassen sind.
+
+@item @code{skip_show_databases}
+Hält Leute davon ab, @code{SHOW DATABASES} zu benutzen, wenn sie keine
+the @code{PROCESS_PRIV}-Berechtigung haben. Das kann die Sicherheit erhöhen, wenn
+Sie sich Sorgen machen, dass Leute in der Lage sind zu sehen, welche
+Datenbanken andere Benutzer haben. Siehe auch @code{safe_show_databases}.
+
+@item @code{slave_read_timeout}
+Anzahl von Sekunden, die auf weitere Daten von einer
+Master-/Slave-Verbindung gewartet wird, bevor das Lesen abgebrochen wird.
+
+@item @code{slow_launch_time}
+Wenn das Erzeugen des Threads länger als dieser Wert (in Sekunden) dauert,
+word der @code{Slow_launch_threads}-Zähler herauf gezählt.
+
+@item @code{socket}
+Der Unix-Socket, der vom Server benutzt wird.
+
+@item @code{sort_buffer}
+Jeder Thread, der einen Sortierdurchgang durchführen muss, alloziert einen
+Puffer dieser Größe. Setzen Sie diesen Wert herauf, um schnellere
+@code{ORDER BY}- oder @code{GROUP BY}-Operationen zu erhalten.
+@xref{Temporary files}.
+
+@item @code{table_cache}
+Die Anzahl offener Tabellen für alle Threads. Wenn dieser Wert herauf
+gesetzt wird, erhöht sich die Anzahl von Datei-Deskriptoren, die
+@code{mysqld} benötigt. Sie können prüfen, ob Sie den Tabellen-Cache
+vergrößern müssen, indem Sie die @code{Opened_tables}-Variable prüfen.
+@xref{SHOW}. Wenn diese Variable sehr Groß ist und Sie @code{FLUSH TABLES}
+nicht oft brauchen (was lediglich alle Tabellen zwingt, geschlossen und
+wieder geöffnet zu werden), sollten Sie den Wert dieser Variablen herauf
+setzen.
+
+Wegen weiterer Informationen zum Tabellen-Cache sehen Sie unter
+@ref{Open tables} nach.
+
+@item @code{table_type}
+Der vorgabemäßige Tabellentyp.
+
+@item @code{thread_cache_size}
+Wie viele Threads in einem Cache für weitere Benutzung offen gehalten
+werden sollen. Wenn eine Client die Verbindung schließt, werden die
+Threads des Clients in den Cache geschrieben, wenn es nicht mehr als
+@code{Thread_cache_size} Threads als vorher gibt. Alle neuen Threads werden
+zuerst aus dem Cache genommen und nur, wenn der Cache leer ist, wird ein
+neuer Thread erzeugt. Diese Variable kann hoch gesetzt werden, um die
+Performance zu verbessern, wenn Sie sehr viele neue Verbindungen haben.
+(Normalerweise führt das nicht zu namhafter Performance-Steigerung, wenn
+Sie eine gute Thread-Implementierung haben.) Wie effizient der aktuelle
+Thread-Cache für Sie ist, können Sie feststellen, indem Sie den Unterschied
+zwischen @code{Connections} und @code{Threads_created} betrachten.
+
+@item @code{thread_concurrency}
+On Solaris, @code{mysqld} will call @code{thr_setconcurrency()} mit
+this value. @code{thr_setconcurrency()} permits the Applikation to give
+the Threads System a hint für the desired Anzahl von Threads that should
+be run at the same time.
+
+@item @code{thread_stack}
+Die Stack-Größe jedes Threads. Viele der Beschränkungen, die durch den
+@code{crash-me}-Test festgestellt werden, hängen von diesem Wert ab. Der
+Vorgabewert ist Groß genug für normale Operationen.
+@xref{MySQL Benchmarks}.
+
+@item @code{timezone}
+Die Zeitzone für den Server.
+
+@item @code{tmp_table_size}
+Wenn eine temporäre Tabelle im Arbeitsspeicher diese Größe überschreitet,
+wandelt MySQL sie automatisch in eine @code{MyISAM}-Tabelle auf der Platte
+um. Setzen Sie den Wert von @code{tmp_table_size} herauf, wenn Sie viele
+fortgeschrittene @code{GROUP BY}-Anfragen und viel Arbeitsspeicher haben.
+
+@item @code{tmpdir}
+Das Verzeichnis, das für temporäre Dateien und temporäre Tabellen benutzt
+wird.
+
+@item @code{version}
+Die Versionsnummer des Servers.
+
+@item @code{wait_timeout}
+Die Anzahl von Sekunden, die der Server auf Aktivität auf einer Verbindung
+wartet, bevor er sie schließt. Siehe auch @code{interactive_timeout}.
+@end table
+
+Der Handbuchabschnitt, der das Tunen von MySQL beschreibt, enthält einige
+Informationen darüber, wie die oben aufgeführten Variablen getunt werden.
+@xref{Server parameters}.
+
+
+@node SHOW LOGS, SHOW PROCESSLIST, SHOW VARIABLES, SHOW
+@c German node SHOW LOGS
+@subsubsection @code{SHOW LOGS}
+
+@code{SHOW LOGS} zeigt Ihnen Statusinformationen über bestehende
+Log-Dateien. Momentan werden nur Informationen über Berkeley-DB-Log-Dateien
+angezeigt.
+
+@itemize @bullet
+@item @code{File} zeigt den vollen Pfad zur Log-Datei.
+@item @code{Type} zeigt den Typ der Log-Datei (@code{BDB} für
+Berkeley-DB-Log-Dateien).
+@item @code{Status} zeigt den Status der Log-Datei (@code{FREE}, wenn die
+Datei entfernt werden kann, oder @code{IN USE}, wenn die Datei vom
+Transaktions-Subsystem benötigt wird)
+@end itemize
+
+
+@node SHOW PROCESSLIST, SHOW GRANTS, SHOW LOGS, SHOW
+@c German node SHOW PROCESSLIST
+@subsubsection @code{SHOW PROCESSLIST}
+
+@findex Threads
+@findex PROCESSLIST
+
+@cindex Threads, anzeigen
+@cindex Prozesse, anzeigen
+
+@code{SHOW PROCESSLIST} zeigt, welche Threads laufen. Diese Information
+erhalten Sie auch mit dem @code{mysqladmin processlist}-Befehl. Wenn Sie
+die @strong{process}-Berechtigung haben, können Sie alle Threads sehen.
+Ansonsten sehen Sie nur Ihre eigenen Threads. @xref{KILL, , @code{KILL}}.
+Wenn Sie die @code{FULL}-Option nicht benutzen, werden nur die ersten 100
+Zeichen jeder Anfrage gezeigt.
+
+Dieser Befehl ist sehr nützlich, wenn Sie die 'too many
+connections'-Fehlermeldung erhalten und herausfinden wollen, was vor sich
+geht. MySQL reserviert eine zusätzliche Verbindung für einen Client mit der
+@code{Process_priv}-Berechtigung, um sicherzustellen, dass Sie sich
+jederzeit einloggen und das System prüfen können (unter der Annahme, dass
+Sie diese Berechtigung nicht allen Ihren Benutzern geben).
+
+
+@node SHOW GRANTS, SHOW CREATE TABLE, SHOW PROCESSLIST, SHOW
+@c German node SHOW GRANTS
+@subsubsection @code{SHOW GRANTS}
+
+@cindex Berechtigungen, anzeigen
+
+@code{SHOW GRANTS FOR benutzer} listet die @code{Grant}-Befehle auf, die
+abgesetzt werden müssen, um die Berechtigungen für einen Benutzer zu
+duplizieren. Beispiel:
+
+@example
+mysql> SHOW GRANTS FOR root@@localhost;
++----------------------------------------------------------------------+
+| Grants for root@@localhost |
++----------------------------------------------------------------------+
+| GRANT ALL PRIVILEGES ON *.* TO 'root'@@'localhost' WITH GRANT OPTION |
++----------------------------------------------------------------------+
+@end example
+
+
+@node SHOW CREATE TABLE, , SHOW GRANTS, SHOW
+@c German node SHOW CREATE TABLE
+@subsubsection @code{SHOW CREATE TABLE}
+
+Zeigt ein @code{CREATE TABLE}-Statement an, das die angegebene Tabelle
+erzeugt:
+
+@example
+mysql> show create table tabelle\G
+*************************** 1. row ***************************
+ Table: tabelle
+Create Table: CREATE TABLE tabelle (
+ id int(11) default NULL auto_increment,
+ s char(60) default NULL,
+ PRIMARY KEY (id)
+) TYPE=MyISAM
+
+@end example
+
+@code{SHOW CREATE TABLE} setzt Tabellen- und Spaltennamen gemäß der
+@code{SQL_QUOTE_SHOW_CREATE}-Option in Anführungszeichen.
+@ref{SET OPTION, , @code{SET OPTION SQL_QUOTE_SHOW_CREATE}}.
+
+
+@node Localisation, Server-Side Scripts, Database Administration, MySQL Database Administration
+@c German node Lokalisierung
+@section MySQL-Lokalisierung und internationaler Gebrauch
+
+
+
+@menu
+* Character sets::
+* Languages::
+* Adding character set::
+* Character arrays::
+* String collating::
+* Multi-byte characters::
+* Problems with character sets::
+@end menu
+
+@node Character sets, Languages, Localisation, Localisation
+@c German node Zeichensätze
+@subsection Der für Daten und Sortieren benutzte Zeichensatz
+
+@cindex Zeichensätze
+@cindex Daten, Zeichensätze
+@cindex sortieren, Zeichensätze
+
+Vorgabemäßig benutzt MySQL den ISO-8859-1-(Latin1)-Zeichensatz, wobei nach
+schwedischer / finnischer Reihenfolge sortiert wird. Dieser Zeichensatz ist
+für die USA und Westeuropa geeignet.
+
+Alle standardmäßigen MySQL-Binärdistributionen werden mit
+@code{--with-extra-charsets=complex} kompiliert. Das fügt allen
+Standard-Programmen Code hinzu, damit diese @code{latin1} und alle
+Multi-Byte-Zeichensätze in der Binärdatei handhaben können. Andere
+Zeichensätze werden bei Bedarf aus einer Zeichensatz-Definitionsdatei
+geladen.
+
+Der Zeichensatz legt fest, welche Zeichen in Namen erlaubt sind und wie
+Dinge durch die @code{ORDER BY}- und @code{GROUP BY}-Klauseln des
+@code{SELECT}-Statements sortiert werden.
+
+Sie können den Zeichensatz mit der @code{--default-character-set}-Option
+ändern, wenn Sie den Server starten. Die verfügbaren Zeichensätze hängen
+von den @code{--with-charset=charset}- und @code{--with-extra-charset=
+list-of-charset | complex | all}-Optionen für @code{configure} ab und den
+Zeichensatz-Konfigurationsdateien, die in @file{SHAREDIR/charsets/Index}
+aufgeführt sind. @xref{configure options}.
+
+Wenn Sie den Zeichensatz ändern, wenn Sie MySQL laufen lassen (was
+eventuell auch die Sortierreihenfolge ändert), müssen Sie @code{myisamchk
+-r -q} über alle Tabellen laufen lassen. Ansonsten sind Ihre Indexe
+eventuell nicht richtig sortiert.
+
+Wenn sich ein Client mit dem MySQL-Server verbindet, schickt der Server den
+vorgabemäßigen Zeichensatz, der in Benutzung ist, an den Client. Der
+Client schaltet für diese Verbindung auf den Gebrauch dieses Zeichensatzes
+um.
+
+Man sollte bei einer SQL-Anfrage @code{mysql_real_escape_string()}
+benutzen, wenn man Zeichenketten escapet. @code{mysql_real_escape_string()}
+ist identisch mit der alten @code{mysql_escape_string()}-Funktion, ausser
+dass es die MySQL-Connection-Handle als ersten Parameter nimmt.
+
+Wenn der Client mit anderen Pfaden kompiliert wird, als wo der Server
+installiert ist, und der Benutzer, der MySQL konfigurierte, nicht alle
+Zeichensätze in die MySQL-Binärdatei eingeschlossen hat, muss man für den
+Client festlegen, wo dieser die zusätzlichen Zeichensätze finden kann, die
+er benötigt, falls der Server mit einem anderen Zeichensatz läuft als der
+Client.
+
+Das kann man in einer MySQL-Optionsdatei festlegen:
+
+@example
+[client]
+character-sets-dir=/usr/local/mysql/share/mysql/charsets
+@end example
+
+Wobei der Pfad auf das Verzeichnis zeigt, in dem sich die dynamischen
+MySQL-Zeichensätze befinden.
+
+Man kann den Client zwingen, einen bestimmten Zeichensatz zu benutzen,
+indem man angibt:
+
+@example
+[client]
+default-character-set=character-set-name
+@end example
+
+Aber normalerweise wird das nie benötigt.
+
+
+@menu
+* German character set::
+@end menu
+
+@node German character set, , Character sets, Character sets
+@c German node Deutscher Zeichensatz
+@subsubsection Deutscher Zeichensatz
+
+Um eine deutsche Sortierreihenfolge zu erhalten, startet man @code{mysqld}
+mit @code{--default-character-set=latin_de}. Das ergibt die folgenden
+Kennzeichen:
+
+Beim Sortieren und Vergleichen von Zeichenketten wird das folgende Mapping
+auf die Zeichenketten durchgeführt, bevor der Vergleich ausgeführt wird:
+
+@example
+ä -> ae
+ö -> oe
+ü -> ue
+ß -> ss
+@end example
+
+Alle Akzentzeichen werden in ihr Nicht-Akzent-Pendant in Großschreibung
+umgewandelt. Alle Buchstaben werden in Großschreibung umgewandelt.
+
+Beim Zeichenkettenvergleich mit @code{LIKE} wird das Mapping von einem auf
+zwei Buchstaben nicht durchgeführt. Alle Buchstaben werden in
+Großschreibung umgewandelt. Akzente werden aus allen Buchstaben entfernt,
+mit folgenden Ausnahmen: @code{Ü}, @code{ü}, @code{Ö}, @code{ö}, @code{Ä}
+und @code{ä}.
+
+
+@node Languages, Adding character set, Character sets, Localisation
+@c German node Sprachen
+@subsection Nicht englische Fehlermeldungen
+
+@cindex Fehlermeldungen, Sprachen
+@cindex Meldungen, Sprachen
+@cindex Dateien, Fehlermeldungen
+@cindex Sprachunterstützung
+
+@code{mysqld} kann Fehlermeldungen in folgenden Sprachen ausgeben:
+tschechisch, dänisch, niederländisch, englisch (die Vorgabe), estnisch,
+französisch, deutsch, griechisch, ungarisch, italienisch, japanisch,
+koreanisch, norwegisch, norwegisch-ny, polnisch, portugiesisch, rumänisch,
+russisch, slowakisch, spanisch und schwedisch.
+
+Um @code{mysqld} mit einer bestimmten Sprache zu starten, benutzen Sie die
+@code{--language=sprache} oder @code{-L sprache}-Optionen. Beispiel:
+
+@example
+shell> mysqld --language=german
+@end example
+
+oder:
+
+@example
+shell> mysqld --language=/usr/local/share/german
+@end example
+
+Beachten Sie, dass alle Sprachnamen in Kleinschreibung angegeben werden.
+
+Die Sprachdateien liegen (vorgabemäßig) in
+@file{@var{mysql_base_dir}/share/@var{language}/}.
+
+Um die Fehlermeldungsdatei zu aktualisieren, editieren Sie die
+@file{errmsg.txt}-Datei und führen folgenden Befehl aus, um die
+@file{errmsg.sys}-Datei zu erzeugen:
+
+@example
+shell> comp_err errmsg.txt errmsg.sys
+@end example
+
+Wenn Sie auf eine neuere Version von MySQL aktualisieren, denken Sie daran,
+Ihre Änderungen mit der neuen @file{errmsg.txt}-Datei zu wiederholen!
+
+
+@node Adding character set, Character arrays, Languages, Localisation
+@c German node Zeichensatz hinzufügen
+@subsection Einen neuen Zeichensatz hinzufügen
+
+@cindex Zeichensätze, hinzufügen
+@cindex hinzufügen, Zeichensätze
+
+Um MySQL einen weiteren Zeichensatz hinzuzufügen, führen Sie folgende
+Prozedur durch:
+
+Entscheiden Sie, ob der Zeichensatz einfach oder komplex ist. Wenn der
+Zeichensatz keine besonderen Zeichenkettenvergleichsroutinen zum Sortieren
+und keine Multi-Byte-Unterstützung benötigt, ist er einfach. Wenn er eines
+oder beide Features benötigt, ist er komplex.
+
+@code{latin1} und @code{dänisch} zum Beispiel sind einfache Zeichensätze,
+wohingegen @code{big5} oder @code{tschechisch} komplexe Zeichensätze sind.
+
+Im folgenden Abschnitt wird angenommen, dass Sie Ihren Zeichensatz
+@code{MEINSET} nennen.
+
+Bei einem einfachen Zeichensatz machen Sie folgendes:
+
+@enumerate
+@item
+Fügen Sie MEINSET am Ende der @file{sql/share/charsets/Index}-Datei hinzu.
+Geben Sie ihm eine eindeutige Nummer.
+
+@item
+Erzeugen Sie die Datei @file{sql/share/charsets/MEINSET.conf}.
+(Sie können hierfür als Grundlage @file{sql/share/charsets/latin1.conf}
+benutzen).
+
+Die Syntax für die Datei ist sehr einfach:
+
+@itemize @bullet
+@item
+Kommentare fangen mit einem '#'-Zeichen an und gehen bis zum Ende der
+Zeile.
+@item
+Wörter werden durch beliebige Mengen von Leerraum getrennt.
+@item
+Bei der Definition des Zeichensatzes muss jedes Wort eine Zahl im
+hexadezimalen Format sein.
+@item
+Das @code{ctype}-Array nimmt bis zu 257 Wörter auf. Die @code{to_lower}-,
+@code{to_upper}- und @code{sort_order}-Arrays nehmen danach jeweils bis zu
+256 Wörter auf.
+@end itemize
+
+@xref{Character arrays}.
+
+@item
+Fügen Sie den Zeichensatznamen den @code{CHARSETS_AVAILABLE}- und
+@code{COMPILED_CHARSETS}-Listen in @code{configure.in} hinzu.
+
+@item
+Rekonfigurieren, rekompilieren und testen Sie.
+
+@end enumerate
+
+Bei einem komplexen Zeichensatz machen Sie folgendes:
+
+@enumerate
+@item
+Erzeugen Sie die Datei @file{strings/ctype-MEINSET.c} in der
+MySQL-Quelldistribution.
+
+@item
+Fügen Sie MEINSET am Ende der @file{sql/share/charsets/Index}-Datei hinzu.
+Weisen Sie ihm eine eindeutige Nummer zu.
+
+@item
+Sehen Sie sich eine der bestehenden @file{ctype-*.c}-Dateien an, um zu
+sehen, was definiert werden muss, zum Beispiel
+@file{strings/ctype-big5.c}. Beachten Sie, dass die Arrays in Ihrer Datei
+Namen wie @code{ctype_MEINSET}, @code{to_lower_MEINSET} usw. haben müssen.
+Das entspricht den Arrays im einfachen Zeichensatz.
+@xref{Character arrays}. Bei einem komplexen Zeichensatz
+
+@item
+fügen Sie am Anfang der Datei einen speziellen Kommentar wie folgt ein:
+
+@example
+/*
+ * Dieser Kommentar wird von configure geparst, um ctype.c zu erzeugen,
+ * also ändern Sie ihn nicht, wenn Sie nicht genau wissen, was Sie tun.
+ *
+ * .configure. number_MEINSET=MYNUMBER
+ * .configure. strxfrm_multiply_MEINSET=N
+ * .configure. mbmaxlen_MEINSET=N
+ */
+@end example
+
+Das @code{configure}-Programm benutzt diesen Kommentar, um den Zeichensatz
+automatisch in die MySQL-Bibliothek einzufügen.
+
+Die Zeilen mit strxfrm_multiply und mbmaxlen werden in den folgenden
+Abschnitten erläutert. Geben Sie diese nur dann ein, wenn Sie die
+Zeichenketten-Vergleichsfunktionen oder die
+Multi-Byte-Zeichensatzfunktionen benötigen.
+
+@item
+Danach sollten Sie einige der folgenden Funktionen erzeugen:
+
+@itemize @bullet
+@item @code{my_strncoll_MEINSET()}
+@item @code{my_strcoll_MEINSET()}
+@item @code{my_strxfrm_MEINSET()}
+@item @code{my_like_range_MEINSET()}
+@end itemize
+
+@xref{String collating}.
+
+@item
+Fügen Sie den Zeichensatznamen den @code{CHARSETS_AVAILABLE}- und
+@code{COMPILED_CHARSETS}-Listen in @code{configure.in} hinzu.
+
+@item
+Rekonfigurieren, rekompilieren und testen Sie.
+@end enumerate
+
+Die Datei @file{sql/share/charsets/README} enthält einige weitere
+Anweisungen.
+
+Wenn Sie wollen, dass der Zeichensatz in die MySQL-Distribution aufgenommen
+wird, senden Sie einen Patch an @email{internals@@lists.mysql.com}.
+
+
+@node Character arrays, String collating, Adding character set, Localisation
+@c German node Zeichen-Arrays
+@subsection Die Zeichen-Definitions-Arrays
+
+@code{to_lower[]} und @code{to_upper[]} sind einfache Arrays, die die
+Buchstaben in Klein- und Großschreibung enthalten, die jedem Mitglied des
+Zeichensatzes entsprechen. Beispiel:
+
+@example
+to_lower['A'] enthält 'a'
+to_upper['a'] enthält 'A'
+@end example
+
+@code{sort_order[]} ist eine Map, die anzeigt, wie Buchstaben für
+Vergleichs- und Sortierzwecke geordnet werden sollten. Bei vielen
+Zeichensätzen ist das dasselbe wie @code{to_upper[]} (was bedeutet, dass
+das Sortieren ohne Berücksichtigung der Groß-/Kleinschreibung erfolgt).
+MySQL sortiert Buchstaben auf der Grundlage des Wertes von
+@code{sort_order[character]}. Wegen komplizierterer Sortierregeln sehen Sie
+die Erörterung zu Zeichenketten-Vergleichen unten an
+@xref{String collating}.
+
+@code{ctype[]} ist ein Array von Bit-Werten, mit einem Element pro Zeichen.
+(Beachten Sie, dass @code{to_lower[]}, @code{to_upper[]} und
+@code{sort_order[]} durch den Buchstabenwert indiziert werden, aber
+@code{ctype[]} durch den Buchstabenwert + 1. Das ist aus Gründen der
+Abwärtskompatibilität notwendig, um EOF (Dateiende) handhaben zu können.)
+
+Sie finden folgenden Bitmasken-Definitionen in @file{m_ctype.h}:
+
+@example
+#define _U 01 /* Großschreibung */
+#define _L 02 /* Kleinschreibung */
+#define _N 04 /* Numerisch (Ziffer) */
+#define _S 010 /* Leerzeichen */
+#define _P 020 /* Punkt */
+#define _C 040 /* Steuerungszeichen (Control) */
+#define _B 0100 /* leer */
+#define _X 0200 /* heXadezimale Ziffer */
+@end example
+
+Der @code{ctype[]}-Eintrag für jeden Buchstaben sollte die
+Vereinigungsmenge der betreffenden Bitmasken-Werte sein, die den Buchstaben
+beschreiben. @code{'A'} beispielsweise ist Buchstabe in Großschreibung
+(@code{_U}) und gleichzeitig eine hexadezimale Ziffer (@code{_X}), daher
+sollte @code{ctype['A'+1]} folgenden Wert erhalten:
+
+@example
+_U + _X = 01 + 0200 = 0201
+@end example
+
+
+@node String collating, Multi-byte characters, Character arrays, Localisation
+@c German node Zeichenketten-Vergleich
+@subsection Unterstützung für Zeichenketten-Vergleich
+
+@cindex Vergleich, Zeichenketten
+@cindex Zeichenkettenvergleich
+
+Wenn die Sortierregeln Ihrer Sprache zu komplex sind, um durch die einfache
+@code{sort_order[]}-Tabelle gehandhabt zu werden, müssen Sie die
+Zeichenketten-Vergleichsfunktionen benutzen.
+
+Zum jetzigen Zeitpunkt ist die beste Dokumentation hierüber die
+Zeichensätze, die bereits implementiert sind. Sehen Sie sich als Beispiele
+die Zeichensätze big5, tschechisch, gbk, sjis und tis160 an.
+
+Sie müssen den @code{strxfrm_multiply_MEINSET=N}-Wert mit einem speziellen
+Kommentar am Anfang der Datei festlegen. @code{N} sollte auf das höchste
+Verhältnis gesetzt werden, auf das die Zeichenketten während
+@code{my_strxfrm_MEINSET} anwachsen können (es muss eine positive Ganzzahl
+sein).
+
+
+@node Multi-byte characters, Problems with character sets, String collating, Localisation
+@c German node Multi-Byte-Zeichen
+@subsection Unterstützung für Multi-Byte-Zeichen
+
+@cindex Buchstaben, Multi-Byte
+@cindex Multi-Byte-Zeichen
+
+Wenn Sie Unterstützung für einen neuen Zeichensatz hinzufügen wollen, der
+Multi-Byte-Buchstaben enthält, müssen Sie die Multi-Byte-Zeichenfunktionen
+benutzen.
+
+Zum jetzigen Zeitpunkt ist die beste Dokumentation hierüber die
+Zeichensätze, die bereits implementiert sind. Sehen Sie sich als Beispiele
+die Zeichensätze euc_kr, gb2312, gbk, sjis und ujis an. Diese sind in den
+@code{ctype-'charset'.c}-Dateien im @file{strings}-Verzeichnis
+implementiert.
+
+Sie müssen den @code{mbmaxlen_MEINSET=N}-Wert in einem speziellen Kommentar
+am Anfang der Quelldatei angeben. @code{N} sollte auf die Größe in Bytes
+des größten Buchstabens im Zeichensatz gesetzt werden.
+
+@node Problems with character sets, , Multi-byte characters, Localisation
+@c German node Probleme mit Zeichensätzen
+@subsection Probleme mit Zeichensätzen
+
+Wenn Sie versuchen, einen Zeichensatz zu benutzen, der nicht in Ihre
+Binärdatei kompiliert ist, können Sie verschiedene Probleme bekommen:
+
+@itemize @bullet
+@item
+Ihr Programm hat einen falschen Pfad zum Speicherort der Zeichensätze.
+(Vorgabe ist @file{/usr/local/mysql/share/mysql/charsets}). Das kann durch
+die Benutzung der @code{--character-sets-dir}-Option für das fragliche
+Programm behoben werden.
+@item
+Der Zeichensatz ist ein Multi-Byte-Zeichensatz, der nicht dynamisch geladen
+werden kann. Wenn das der Fall ist, müssen Sie das Programm mit
+Unterstützung für diesen Zeichensatz neu kompilieren.
+@item
+Der Zeichensatz ist ein dynamischer Zeichensatz, aber Sie haben keine
+configure-Datei dafür. In diesem Fall müssen Sie die configure-Datei für
+den Zeichensatz aus einer neuen MySQL-Distribution installieren.
+@item
+Ihre @file{Index}-Datei enthält nicht den Namen für den Zeichensatz.
+
+@example
+ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found
+(Errcode: 2)
+@end example
+
+In diesem Fall müssen Sie sich entweder eine neue @code{Index}-Datei holen
+oder den Namen jedes fehlenden Zeichensatzes von Hand eintragen.
+@end itemize
+
+Bei MyISAM-Tabellen können Sie den Zeichensatznamen und die Anzahl für eine
+Tabelle mit @code{myisamchk -dvv tabelle} prüfen.
+
+
+@node Server-Side Scripts, Client-Side Scripts, Localisation, MySQL Database Administration
+@c German node Serverseitige Skripte
+@section Serverseitige Skripte und Dienstprogramme für MySQL
+
+
+
+@menu
+* Server-Side Overview::
+* safe_mysqld::
+* mysqld_multi::
+* myisampack::
+* mysqld-max::
+@end menu
+
+@node Server-Side Overview, safe_mysqld, Server-Side Scripts, Server-Side Scripts
+@c German node Überblick über serverseitige Programme
+@subsection Überblick über serverseitige Programme und Dienstprogramme
+
+@cindex Umgebungsvariablen
+@cindex Programme, Auflistung
+
+Alle MySQL-Clients, die mittels der @code{mysqlclient}-Bibliothek mit dem
+Server kommunizieren, benutzen folgenden Umgebungsvariablen:
+
+@tindex @code{MYSQL_UNIX_PORT}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_UNIX_PORT}
+@tindex @code{MYSQL_TCP_PORT}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_TCP_PORT}
+@tindex @code{MYSQL_PWD}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_PWD}
+@tindex @code{MYSQL_DEBUG}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_DEBUG}
+@multitable @columnfractions .25 .75
+@item @strong{Name} @tab @strong{Beschreibung}
+@item @code{MYSQL_UNIX_PORT} @tab Der vorgabemäßige Socket; benutzt für Verbindungen zu @code{localhost}
+@item @code{MYSQL_TCP_PORT} @tab Der vorgabemäßige TCP/IP-Port
+@item @code{MYSQL_PWD} @tab Das vorgabemäßige Passwort
+@item @code{MYSQL_DEBUG} @tab Debug-Trace-Optionen beim Debuggen
+@item @code{TMPDIR} @tab Das Verzeichnis, in dem temporäre Tabellen / Dateien erzeugt werden
+@end multitable
+
+Die Benutzung von @code{MYSQL_PWD} ist unsicher.
+@xref{Connecting}.
+
+@tindex @code{MYSQL_HISTFILE}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_HISTFILE}
+@tindex @code{HOME}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{HOME}
+@cindex History-Datei
+@cindex Kommandozeilen-History
+@tindex .mysql-History-Datei
+Der @file{mysql}-Client benutzt die Datei, die in der
+@code{MYSQL_HISTFILE}-Umgebungsvariablen angegeben ist, um die
+Kommandozeilen-History zu speichern. Der Vorgabewert für die History-Datei
+ist @file{$HOME/.mysql_history}, wobei @code{$HOME} der Wert der
+@code{HOME}-Umgebungsvariablen ist. @xref{Environment variables}.
+
+Alle MySQL-Programme nehmen viele unterschiedliche Optionen auf. Jedes
+MySQL-Programm bietet jedoch eine @code{--help}-Option, die Sie benutzen
+können, um eine vollständige Beschreibung der unterschiedlichen
+Programmoptionen zu erhalten. Probieren Sie zum Beispiel @code{mysql
+--help} aus.
+
+Sie können Vorgabeoptionen für alle Standard-Client-Programme mit einer
+Optionsdatei überschreiben. @ref{Option files}.
+
+Die unten stehende Liste beschreibt kurz die MySQL-Programme:
+
+@table @code
+
+@cindex @code{myisamchk}
+@item myisamchk
+Dienstprogramm zur Beschreibung, Prüfung, Optimierung und Reparatur von
+MySQL-Tabellen. Weil @code{myisamchk} viele Funktionen hat, ist es in einem
+eigenen Kapitel beschrieben. @xref{MySQL Database Administration}.
+
+@cindex @code{make_binary_distribution}
+@item make_binary_distribution
+Macht ein Binär-Release eines kompilierten MySQL. Dieses könnte über FTP an
+@file{/pub/mysql/Incoming} oder an @code{Support.mysql.com} geschickt
+werden, damit andere MySQL-Benutzer es benutzen können.
+
+@cindex @code{msql2mysql}
+@item msql2mysql
+Ein Shell-Skript, das @code{mSQL}-Programme zu MySQL konvertiert. Es deckt
+nicht alle Fälle ab, ist aber hilfreich, um mit dem Konvertieren
+anzufangen.
+
+@cindex @code{mysqlaccess}
+@item mysqlaccess
+Ein Skript, das die Zugriffsberechtigungen für eine Host-, Benutzer- und
+Datenbank-Kombination prüft.
+
+@cindex @code{mysqladmin}
+@item mysqladmin
+Dienstprogramm für die Durchführung von Verwaltungsoperationen wie Erzeugen
+und Löschen von Datenbanken, Neuladen der Berechtigungstabellen,
+Zurückschreiben von Tabellen auf Platte und Neuöffnen von Log-Dateien.
+@code{mysqladmin} kann auch benutzt werden, um Versionsnummer sowie Status-
+und Prozess-Informationen vom Server zu erhalten.
+@xref{mysqladmin, , @code{mysqladmin}}.
+
+@cindex @code{mysqlbug}
+@item mysqlbug
+Das MySQL-Bug-Bericht-Skript. Dieses Skript sollte immer benutzt werden,
+wenn Sie einen Bug-Bericht an die MySQL-Liste ausfüllen.
+
+@cindex @code{mysqld}
+@item mysqld
+Der SQL-Daemon. Dieser sollte immer laufen.
+
+@cindex @code{mysqldump}
+@item mysqldump
+Dumpt eine MySQL-Datenbank in eine Datei als SQL-Statements oder als
+Tabulator-separierte Textdateien. Verbesserte Freeware, ursprünglich von
+Igor Romanenko. @xref{mysqldump, , @code{mysqldump}}.
+
+@cindex @code{mysqlimport}
+@item mysqlimport
+Importiert Textdateien in die jeweiligen Tabellen mittels @code{LOAD DATA
+INFILE}. @xref{mysqlimport, , @code{mysqlimport}}.
+
+@cindex @code{mysqlshow}
+@item mysqlshow
+Zeigt Informationen über Datenbanken, Tabellen, Spalten und Indexe an.
+
+@cindex @code{mysql_install_db}
+@item mysql_install_db
+Erzeugt die MySQL-Berechtigungstabellen mit vorgabemäßigen Berechtigungen.
+Dieses Skript wird gewöhnlich nur einmal ausgeführt, wenn Sie MySQL das
+erste Mal auf einem System installieren.
+
+@cindex @code{replace}
+@item replace
+Ein Dienstprogramm, das von @code{msql2mysql} benutzt wird, aber auch
+darüber hinaus benutzt werden kann. @code{replace} ändert Zeichenketten in
+Dateien oder auf der Standardeingabe. Benutzt eine finite Status-Maschine,
+um zuerst Übereinstimmung mit längeren Zeichenketten zu finden. Kann
+benutzt werden, um Zeichenketten umzudrehen. Der folgende Befehl zum
+Beispiel dreht @code{a} und @code{b} in den angegebenen Dateien um:
+
+@example
+shell> replace a b b a --Datei1 Datei2 ...
+@end example
+@end table
+
+
+@node safe_mysqld, mysqld_multi, Server-Side Overview, Server-Side Scripts
+@c German node safe_mysqld
+@subsection safe_mysqld, der Wrapper um mysqld
+
+@cindex Werkzeuge, safe_mysqld
+@cindex Skripts
+@cindex @code{safe_mysqld}
+
+@code{safe_mysqld} ist die empfohlene Art, einen @code{mysqld}-Daemon unter
+Unix zu starten. @code{safe_mysqld} fügt einige Sicherheits-Features hinzu
+wie das Neustarten des Servers, wenn ein Fehler auftritt, und das
+Mitschreiben von Laufzeitinformationen in eine Log-Datei.
+
+Wenn Sie nicht @code{--mysqld=#} oder @code{--mysqld-version=#} benutzen,
+benutzt @code{safe_mysqld} eine ausführbare Datei namens @code{mysqld-max},
+wenn es diese gibt. Wenn nicht, startet @code{safe_mysqld} @code{mysqld}.
+Das macht es sehr einfach, @code{mysqld-max} anstelle von @code{mysqld}
+versuchsweise zu benutzen. Kopieren Sie einfach @code{mysqld-max} dorthin,
+wo @code{mysqld} liegt, und es wird benutzt werden.
+
+Normalerweise sollte man das @code{safe_mysqld}-Skript nie editieren,
+sondern statt dessen die Optionen für @code{safe_mysqld} in den
+@code{[safe_mysqld]}-Abschnitt der @code{my.cnf}-Datei einfügen.
+@code{safe_mysqld} liest alle Optionen des @code{[mysqld]}-,
+@code{[server]}- und @code{[safe_mysqld]}-Abschnitts aus den
+Optionsdateien. @xref{Option files}.
+
+Beachten Sie, dass alle Optionen auf der Kommandozeile für
+@code{safe_mysqld} an @code{mysqld} durchgereicht werden. Wenn Sie in
+@code{safe_mysqld} irgend welche Optionen benutzen wollen, die
+@code{mysqld} nicht unterstützt, müssen Sie diese in der Optionsdatei
+angeben.
+
+Die meisten Optionen für @code{safe_mysqld} sind dieselben wie die Optionen
+für @code{mysqld}. @xref{Command-line options}.
+
+@code{safe_mysqld} unterstützt folgende Optionen:
+
+@table @code
+@item --basedir=pfad
+@item --core-file-size=#
+Größe der Core-Datei, die @code{mysqld} in der Lage sein sollte zu
+erzeugen. Wird an @code{ulimit -c} durchgereicht.
+@item --datadir=pfad
+@item --defaults-extra-file=pfad
+@item --defaults-file=pfad
+@item --err-log=pfad
+@item --ledir=pfad
+Pfad zu @code{mysqld}
+@item --log=pfad
+@item --mysqld=mysqld-version
+Name der @code{mysqld}-Version im @code{ledir}-Verzeichnis, die Sie starten
+wollen.
+@item --mysqld-version=version
+Ähnlich wie @code{--mysqld=}, aber hier für nur das Suffix für
+@code{mysqld} angegeben. Wenn Sie zum Beispiel @code{--mysqld-version=max}
+benutzen, startet @code{safe_mysqld} die @code{ledir/mysqld-max}-Version.
+Wenn das Argument für @code{--mysqld-version} leer ist, wird
+@code{ledir/mysqld} benutzt.
+@item --no-defaults
+@item --open-files-limit=#
+Anzahl der Dateien, die @code{mysqld} in der Lage sein sollte zu öffnen.
+Wird an @code{ulimit -n} durchgereicht. Beachten Sie, dass Sie
+@code{safe_mysqld} als Root starten müssen, damit dies korrekt
+funktioniert!
+@item --pid-file=pfad
+@item --port=#
+@item --socket=pfad
+@item --timezone=#
+Setzt die Zeitzone (die @code{TZ})-Variable auf den Wert dieses Parameters.
+@item --user=#
+@end table
+
+Das @code{safe_mysqld}-Skript ist so geschrieben, dass es normalerweise
+einen Server starten kann, der aus einer Quell- oder einer Binärversion von
+MySQL installiert wurde, selbst wenn diese den Server an etwas anderen
+Stellen installieren. @code{safe_mysqld} erwartet, dass eine der folgenden
+Bedingungen zutrifft:
+
+@itemize @bullet
+@item
+Server und Datenbanken liegen relativ zum Verzeichnis, aus dem
+@code{safe_mysqld} aufgerufen wird. @code{safe_mysqld} sucht unterhalb
+seines Arbeitsverzeichnisses nach @file{bin}- und
+@file{data}-Verzeichnissen (bei Binärdistributionen) oder nach
+@file{libexec}- und @file{var}-Verzeichnissen (bei Quelldistributionen).
+Diese Bedingung sollte zutreffen, wenn Sie @code{safe_mysqld} aus Ihrem
+MySQL-Installationsverzeichnis ausführen (zum Beispiel
+@file{/usr/local/mysql} bei einer Binärdistribution).
+
+@item
+Wenn Server und Datenbanken nicht relativ zum Arbeitsverzeichnis liegen,
+versucht @code{safe_mysqld}, sie anhand absoluter Pfadnamen zu finden.
+Typische Speicherort sind @file{/usr/local/libexec} und
+@file{/usr/local/var}. Die tatsächlichen Speicherorte werden festgelegt,
+wenn die Distribution gebaut wird, woher @code{safe_mysqld} kommt. Sie
+sollten korrekt sein, wenn MySQL an einem Standardort installiert wurde.
+@end itemize
+
+Weil @code{safe_mysqld} versucht, Server und Datenbanken relativ zum
+eigenen Arbeitsverzeichnis zu finden, können Sie eine Binärdistribution von
+MySQL irgendwo hin installieren, so lange Sie @code{safe_mysqld} aus dem
+MySQL-Installationsverzeichnis starten:
+
+@example
+shell> cd mysql_installations_verzeichnis
+shell> bin/safe_mysqld &
+@end example
+
+Wenn @code{safe_mysqld} fehlschlägt, selbst wenn es aus dem
+MySQL-Installationsverzeichnis aufgerufen wurde, können Sie es so ändern,
+dass es den Pfad zu @code{mysqld} und die Pfadnamen-Optionen benutzt, die
+auf Ihrem System korrekt sind. Beachten Sie, dass bei zukünftigen
+Aktualisierungen von MySQL Ihre veränderte Version von @code{safe_mysqld}
+überschrieben wird. Daher sollten Sie eine Kopie Ihrer editierten Version
+machen, damit Sie diese neu installieren können.
+
+
+@node mysqld_multi, myisampack, safe_mysqld, Server-Side Scripts
+@c German node mysqld_multi
+@subsection mysqld_multi, Programm zur Verwaltung mehrerer MySQL-Server
+
+@cindex Werkzeuge, mysqld_multi
+@cindex Skripts
+@cindex multi mysqld
+@cindex @code{mysqld_multi}
+
+@code{mysqld_multi} ist für die Verwaltung mehrerer @code{mysqld}-Prozesse
+gedacht, die auf unterschiedlichen UNIX-Sockets und TCP/IP-Ports laufen.
+
+Das Programm sucht nach Gruppe(n), die [mysqld#] benannt sind, in my.cnf
+(oder der angegebenen --config-file=...), wobei # jede positive Zahl ab 1
+sein kann. Diese Gruppen sollten dieselben sein wie die übliche
+@code{[mysqld]}-Gruppe (zum Beispiel Optionen für mysqld, siehe
+ausführliche Informationen im Handbuch über diese Gruppe), aber mit
+denjenigen Port-, Socket- usw. Optionen, die für jeden separaten
+@code{mysqld}-Prozess gewünscht sind. Die Zahl im Gruppennamen hat eine
+andere Funktion: Sie kann benutzt werden, um bestimmte @code{mysqld}-Server
+zu starten, anzuhalten, oder Berichte über sie mit diesem Programm
+auszugeben. Unten stehen weitere Informationen zur Benutzung und zu den
+Optionen.
+
+@example
+Benutzung: mysqld_multi [OPTIONS] @{start|stop|report@} [GNR,GNR,GNR...]
+oder mysqld_multi [OPTIONS] @{start|stop|report@} [GNR-GNR,GNR,GNR-GNR,...]
+@end example
+
+Die GNR oben bedeutet die Gruppennummer. Sie können jede GNR starten,
+anhalten oder Berichtsinformationen über sie ausgeben, oder über mehrere
+von ihnen zugleich. (Siehe --example) Die GNRs in der Liste können mit
+Komma getrennt oder mit Bindestrich kombiniert werden, wobei letzteres
+heißt, dass alle GNRs zwischen GNR1-GNR2 betroffen sind. Ohne GNR-Argument
+werden alle gefundenen Gruppen entweder gestartet, angehalten, oder es
+werden Berichtsinformationen über sie ausgegeben. Beachten Sie, dass Sie in
+der GNR-Liste keinen Leerraum haben dürfen. Alles nach Leerraum wird
+ignoriert.
+
+@code{mysqld_multi} unterstützt folgende Optionen:
+
+@table @code
+@cindex config-file option
+@item --config-file=...
+Alternative config-Datei. HINWEIS: Das betrifft nicht die eigenen Optionen
+des Programms (Gruppe @code{[mysqld_multi]}), sondern nur die Gruppen
+[mysqld#]. Ohne diese Option wird alles aus der normalen my.cnfDatei heraus
+gesucht.
+@cindex Beispiel option
+@item --example
+Zeigt ein Beispiel einer config-Datei.
+@cindex help option
+@item --help
+Hilfetext ausgeben und beenden.
+@cindex log option
+@item --log=...
+Log-Datei. Name und voller Pfad zur Log-Datei. HINWEIS: Wenn es die Datei
+gibt, wird alles angehängt.
+@cindex mysqladmin option
+@item --mysqladmin=...
+@code{mysqladmin}-Binärdatei, die zum Herunterfahren des Servers benutzt
+wird.
+@cindex mysqld option
+@item --mysqld=...
+@code{mysqld}-Binärdatei, die benutzt wird. Beachten Sie, dass Sie auch
+@code{safe_mysqld} diese Option angeben können. Die Optionen werden an
+@code{mysqld} durchgereicht. Stellen Sie jedoch sicher, dass Sie
+@code{mysqld} in Ihrer Umgebungsvariablen @code{PATH} haben oder bearbeiten
+Sie @code{safe_mysqld}.
+@cindex no-log option
+@item --no-log
+An stdout ausgeben statt in die Log-Datei. Vorgabemäßig ist die Log-Datei
+angeschaltet.
+@cindex password option
+@item --password=...
+Passwort für Benutzer von @code{mysqladmin}.
+@cindex tcp-ip option
+@item --tcp-ip
+Zu MySQL-Server(n) über den TCP/IP-Port statt über den UNIX-Socket
+verbinden. Das betrifft das Anhalten und Berichten. Wenn eine Socket-Datei
+fehlt, kann der Server trotzdem laufen, aber man kann nur über den
+TCP/IP-Port auf ihn zugreifen. Vorgabemäßig wird die Verbindung über den
+UNIX-Socket hergestellt.
+@cindex user option
+@item --user=...
+MySQL-Benutzer von @code{mysqladmin}.
+@cindex version option
+@item --version
+Versionsnummer ausgeben und beenden.
+@end table
+
+Einige Anmerkungen zu @code{mysqld_multi}:
+
+@itemize @bullet
+@item
+Stellen Sie sicher, dass der MySQL-Benutzer, der die @code{mysqld}-Dienste
+anhält (indem er zum Beispiel @code{mysqladmin} benutzt), dasselbe Passwort
+und denselben Benutzernamen für alle Daten-Verzeichnisse benutzt, auf die
+zugegriffen wird (zur 'mysql'-Datenbank). Stellen Sie ausserdem sicher,
+dass der Benutzer die 'Shutdown_priv'-Berechtigung hat! Wenn Sie viele
+Daten-Verzeichnisse und viele verschiedene 'mysql'-Datenbanken mit
+unterschiedlichen Passwörtern für den MySQL-'root'-Benutzer haben, sollten
+Sie einen allgemeinen 'multi_admin'-Benutzer anlegen, der dasselbe Passwort
+benutzt (siehe unten). Hier ein Beispiel dafür:
+@example
+shell> mysql -u root -S /tmp/mysql.sock -proot_password -e
+"GRANT SHUTDOWN ON *.* TO multi_admin@@localhost IDENTIFIED BY 'multipass'"
+@xref{Privileges}.
+@end example
+Das oben Angegebene müssen Sie für jeden laufenden @code{mysqld} im
+Daten-Verzeichnis tun, das Sie haben (ändern Sie einfach den Socket,
+-S=...).
+@item
+@code{pid-file} ist sehr wichtig, wenn Sie @code{safe_mysqld} benutzen, um
+@code{mysqld} zu starten (zum Beispiel --mysqld=safe_mysqld). Jeder
+@code{mysqld} sollte seine eigene @code{pid-file} haben. Der Vorteil der
+Benutzung von @code{safe_mysqld} anstelle von @code{mysqld} direkt ist
+hierbei, dass @code{safe_mysqld} jeden @code{mysqld}-Prozess 'bewacht' und
+neu startet, falls ein @code{mysqld}-Prozess wegen eines Signals kill -9
+fehlschlägt oder ähnliches (wenn beispielsweise Speicherzugriffsfehler
+auftreten, was bei MySQL natürlich nie passiert ;-). Beachten Sie bitte,
+dass es für das @code{safe_mysqld}-Skript eventuell erforderlich ist, es
+von einer bestimmten Stelle aus zu starten. Das heißt, dass Sie eventuell
+in ein bestimmtes Verzeichnis wechseln müssen, bevor Sie
+@code{mysqld_multi} starten. Wenn Sie beim Starten Probleme haben, sehen
+Sie bitte im @code{safe_mysqld}-Skript nach. Überprüfen Sie insbesondere
+folgende Zeilen:
+@example
+--------------------------------------------------------------------------
+MY_PWD=`pwd` Check if we are starting this relative (for the binary
+release) if test -d /data/mysql -a -f ./share/mysql/englisch/errmsg.sys
+-a -x ./bin/mysqld
+--------------------------------------------------------------------------
+@xref{safe_mysqld, , @code{safe_mysqld}}.
+@end example
+Der obige Test soll erfolgreich verlaufen, ansonsten können Sie Probleme
+bekommen.
+@item
+Vermeiden Sie Gefahren, die auftauchen, wenn Sie mehrere @code{mysqlds} im
+selben Daten-Verzeichnis starten. Benutzen Sie unterschiedlichen
+Daten-Verzeichnisse, es sei denn, Sie wissen @strong{GENAU}, was Sie tun!
+@item
+Die Socket-Datei und der TCP/IP-Port müssen für jeden @code{mysqld}
+verschieden sein.
+@item
+Die erste und die fünfte @code{mysqld}-Gruppe wurden beim Beispiel
+absichtlich ausgelassen. Sie haben eventuell 'Lücken' in der config-Datei.
+Das gibt Ihnen mehr Flexibilität. Die Reihenfolge, in der die
+@code{mysqlds} gestartet oder angehalten werden, hängt von der Reihenfolge
+ab, in der sie in der config-Datei erscheinen.
+@item
+Wenn Sie auf eine bestimmte Gruppe verweisen wollen, wenn Sie GNR bei
+diesem Programm benutzen, nehmen Sie einfach die Nummer am Ende des
+Gruppennamens ( [mysqld# <== ).
+@item
+Eventuell sollten Sie die Option '--user' für @code{mysqld} benutzen, aber
+um das zu tun, müssen Sie root sein, wenn Sie das
+@code{mysqld_multi}-Skript starten. Wenn Sie die Option in der config-Datei
+haben, macht das nichts; Sie erhalten nur eine Warnmeldung, wenn Sie nicht
+der Superuser sind und die @code{mysqlds} unter @strong{IHREM} UNIX-Account
+gestartet werden. @strong{WICHTIG}: Stellen Sie sicher, dass die
+@code{pid-file} und das Daten-Verzeichnis für @strong{DENJENIGEN}
+UNIX-Benutzer lesbar und schreibbar sind (und ausführbar im letzteren
+Fall), als der der spezifische @code{mysqld}-Prozess gestartet wird.
+Benutzen Sie hier @strong{NICHT} den UNIX-root-Account, es sei denn, Sie
+wissen @strong{GENAU}, was Sie tun!
+@item
+@strong{SEHR WICHTIG}: Stellen Sie sicher, dass Sie die Bedeutung der
+Optionen verstehen, die an die @code{mysqlds} durchgereicht werden und
+@strong{WARUM} Sie mehrere verschiedene @code{mysqld}-Prozesse haben
+wollen. Mehrere @code{mysqlds} in einem Daten-Verzeichnis starten
+@strong{ergibt keine zusätzliche Performance} bei einem threaded System!
+@end itemize
+
+@xref{Multiple servers}.
+
+Hier ist ein Beispiel einer config-Datei für @code{mysqld_multi}.
+
+@example
+# Diese Datei sollte wahrscheinlich in Ihrem Heimatverzeichnis liegen (~/.my.cnf) oder in /etc/my.cnf
+# Version 2.1 von Jani Tolonen
+
+[mysqld_multi]
+mysqld = /usr/local/bin/safe_mysqld
+mysqladmin = /usr/local/bin/mysqladmin
+user = multi_admin
+password = multipass
+
+[mysqld2]
+socket = /tmp/mysql.sock2
+port = 3307
+pid-file = /usr/local/mysql/var2/hostname.pid2
+datadir = /usr/local/mysql/var2
+language = /usr/local/share/mysql/english
+user = john
+
+[mysqld3]
+socket = /tmp/mysql.sock3
+port = 3308
+pid-file = /usr/local/mysql/var3/hostname.pid3
+datadir = /usr/local/mysql/var3
+language = /usr/local/share/mysql/swedish
+user = monty
+
+[mysqld4]
+socket = /tmp/mysql.sock4
+port = 3309
+pid-file = /usr/local/mysql/var4/hostname.pid4
+datadir = /usr/local/mysql/var4
+language = /usr/local/share/mysql/estonian
+user = tonu
+
+[mysqld6]
+socket = /tmp/mysql.sock6
+port = 3311
+pid-file = /usr/local/mysql/var6/hostname.pid6
+datadir = /usr/local/mysql/var6
+language = /usr/local/share/mysql/japanese
+user = jani
+@end example
+
+@xref{Option files}.
+
+
+@node myisampack, mysqld-max, mysqld_multi, Server-Side Scripts
+@c German node myisampack
+@subsection myisampack, MySQL-Programm zum Erzeugen komprimierter Nur-Lese-Tabellen
+
+@cindex komprimierte Tabellen
+@cindex Tabellen, komprimierte
+@cindex MyISAM, komprimierte Tabellen
+@cindex @code{myisampack}
+@cindex @code{pack_isam}
+
+@code{myisampack} wird benutzt, um MyISAM-Tabellen zu komprimieren.
+@code{pack_isam} wird benutzt, um ISAM-Tabellen zu komprimieren. Weil
+ISAM-Tabellen veraltet sind, wird hier nur @code{myisampack} erörtert, aber
+alles, was auf @code{myisampack} zutrifft, gilt auch für @code{pack_isam}.
+
+@code{myisampack} funktioniert, indem jede Spalte in der Tabelle separat
+komprimiert wird. Die Informationen, die benötigt werden, um Spalten zu
+dekomprimieren, werden in den Arbeitsspeicher gelesen, wenn die Tabelle
+geöffnet wird. Das ergibt viel bessere Performance beim Zugriff auf
+einzelne Datensätze, denn man muss nur exakt einen Datensatz
+dekomprimieren, nicht einen viel größeren Block, wie das zum Beispiel bei
+der Benutzung von Stacker auf MS-DOS nötig ist. Üblicherweise komprimiert
+@code{myisampack} die Daten-Datei auf 40%-70%.
+
+MySQL benutzt Speicher-Mapping (@code{mmap()}) auf komprimierte Tabellen
+und geht zu normalen Lesen / Schreiben von Dateien zurück, wenn
+@code{mmap()} nicht funktioniert.
+
+Für @code{myisampack} gibt es momentan zwei Einschränkungen:
+@itemize @bullet
+@item
+Nach dem Komprimieren ist die Tabelle nur-lesbar.
+@item
+@code{myisampack} kann auch @code{BLOB}- oder @code{TEXT}-Spalten
+komprimieren. Das ältere @code{pack_isam} konnte das nicht.
+@end itemize
+
+Die Behebung dieser Einschränkungen steht mit niedrigen Priorität auf
+unserer TODO-Liste.
+
+@code{myisampack} wird wie folgt aufgerufen:
+
+@example
+shell> myisampack [options] Dateiname ...
+@end example
+
+Jeder Dateiname sollte der Name einer Index-(@file{.MYI})-Datei sein. Wenn
+Sie nicht im Datenbank-Verzeichnis sind, müssen Sie den Pfadnamen zur Datei
+angeben. Die @file{.MYI} Erweiterung kann weggelassen werden.
+
+@code{myisampack} unterstützt folgende Optionen:
+
+@table @code
+@item -b, --backup
+Stellt eine Datensicherung der Tabelle als @code{tabelle.OLD} her.
+
+@item -#, --debug=debug_options
+Debug-Log ausgeben. Die @code{debug_options}-Zeichenkette ist häufig
+@code{'d:t:o,filename'}.
+
+@item -f, --force
+Erzwingt die Komprimierung der Tabelle, selbst wenn sie dadurch größer
+wird oder die temporäre Datei existiert. @code{myisampack} erzeugt eine
+temporäre Datei namens @file{tabelle.TMD}, während es die Tabelle
+komprimiert. Wenn Sie @code{myisampack} killen, kann es sein, dass die
+@file{.TMD}-Datei nicht gelöscht wird. Normalerweise wird @code{myisampack}
+mit einer Fehlermeldung beendet, wenn es eine existierende
+@file{tabelle.TMD}-Datei findet. Mit @code{--force} packt @code{myisampack}
+die Tabelle trotzdem.
+
+@item -?, --help
+Hilfetext ausgeben und beenden.
+
+@item -j große_tabelle, --join=große_tabelle
+Verbindet alle Tabellen, die auf der Kommandozeile angegeben wurden, in
+eine einzige große Tabelle @code{große_tabelle}. Alle Tabellen, die
+kombiniert werden sollen, MÜSSEN identisch sein (dieselben Spaltennamen und
+-typen, dieselben Indexe usw.).
+
+@item -p #, --packlength=#
+Legt die Speichergröße der Datensatzlänge in Bytes fest. Der Wert sollte
+1, 2 oder 3 sein. (@code{myisampack} speichert alle Zeilen mit
+Längenzeigern von 1, 2, oder 3 Bytes. In den meisten Fällen kann
+@code{myisampack} den richtigen Längenwert festlegen, bevor es anfängt, die
+Datei zu komprimieren. Während des Komprimierungsprozesses stellt es aber
+eventuell fest, dass es eine kürzere Länge hätte nehmen können. In diesem
+Fall gibt @code{myisampack} einen Hinweis aus, dass Sie beim nächsten Mal,
+wenn Sie dieselbe Datei packen, eine kürzere Datensatzlänge nehmen
+sollten.)
+
+@item -s, --silent
+Schweigsamer Modus. Ausgaben erfolgen nur, wenn Fehler auftreten.
+
+@item -t, --test
+Tabelle nicht tatsächlich komprimieren, sondern nur testweise packen.
+
+@item -T dir_name, --tmp_dir=dir_name
+Das genannte Verzeichnis als Speicherort der temporären Tabelle benutzen.
+
+@item -v, --verbose
+Geschwätziger Modus. Informationen über den Fortschritt und das
+Komprimierungsergebnis ausgeben.
+
+@item -V, --version
+Versionsinformationen ausgeben und beenden.
+
+@item -w, --wait
+Warten und noch einmal versuchen, wenn die Tabelle in Benutzung ist. Wenn
+der @code{mysqld}-Server mit der @code{--skip-locking}-Option aufgerufen
+wurde, ist es keine gute Idee, @code{myisampack} aufzurufen, wenn die
+Tabelle während des Komprimierungsprozesses möglicherweise aktualisiert
+wird.
+@end table
+
+@cindex Beispiele, komprimierte Tabellen
+Die unten stehende Befehlssequenz zeigt eine typische
+Tabellen-Komprimierungssitzung:
+
+@example
+shell> ls -l station.*
+-rw-rw-r-- 1 monty my 994128 Apr 17 19:00 station.MYD
+-rw-rw-r-- 1 monty my 53248 Apr 17 19:00 station.MYI
+-rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm
+
+shell> myisamchk -dvv station
+
+MyISAM file: station
+Isam-version: 2
+Creation time: 1996-03-13 10:08:58
+Recover time: 1997-02-02 3:06:43
+Data records: 1192 Deleted blocks: 0
+Datafile: Parts: 1192 Deleted data: 0
+Datafile pointer (bytes): 2 Keyfile pointer (bytes): 2
+Max datafile length: 54657023 Max keyfile length: 33554431
+Recordlength: 834
+Record format: Fixed length
+
+table description:
+Key Start Len Index Type Root Blocksize Rec/key
+1 2 4 unique unsigned long 1024 1024 1
+2 32 30 multip. text 10240 1024 1
+
+Field Start Length Type
+1 1 1
+2 2 4
+3 6 4
+4 10 1
+5 11 20
+6 31 1
+7 32 30
+8 62 35
+9 97 35
+10 132 35
+11 167 4
+12 171 16
+13 187 35
+14 222 4
+15 226 16
+16 242 20
+17 262 20
+18 282 20
+19 302 30
+20 332 4
+21 336 4
+22 340 1
+23 341 8
+24 349 8
+25 357 8
+26 365 2
+27 367 2
+28 369 4
+29 373 4
+30 377 1
+31 378 2
+32 380 8
+33 388 4
+34 392 4
+35 396 4
+36 400 4
+37 404 1
+38 405 4
+39 409 4
+40 413 4
+41 417 4
+42 421 4
+43 425 4
+44 429 20
+45 449 30
+46 479 1
+47 480 1
+48 481 79
+49 560 79
+50 639 79
+51 718 79
+52 797 8
+53 805 1
+54 806 1
+55 807 20
+56 827 4
+57 831 4
+
+shell> myisampack station.MYI
+Compressing station.MYI: (1192 records)
+- Calculating statistics
+
+normal: 20 empty-space: 16 empty-zero: 12 empty-fill: 11
+pre-space: 0 end-space: 12 table-lookups: 5 zero: 7
+Original trees: 57 After join: 17
+- Compressing file
+87.14%
+
+shell> ls -l station.*
+-rw-rw-r-- 1 monty my 127874 Apr 17 19:00 station.MYD
+-rw-rw-r-- 1 monty my 55296 Apr 17 19:04 station.MYI
+-rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm
+
+shell> myisamchk -dvv station
+
+MyISAM file: station
+Isam-version: 2
+Creation time: 1996-03-13 10:08:58
+Recover time: 1997-04-17 19:04:26
+Data records: 1192 Deleted blocks: 0
+Datafile: Parts: 1192 Deleted data: 0
+Datafilepointer (bytes): 3 Keyfile pointer (bytes): 1
+Max datafile length: 16777215 Max keyfile length: 131071
+Recordlength: 834
+Record format: Compressed
+
+table description:
+Key Start Len Index Type Root Blocksize Rec/key
+1 2 4 unique unsigned long 10240 1024 1
+2 32 30 multip. text 54272 1024 1
+
+Field Start Length Type Huff tree Bits
+1 1 1 constant 1 0
+2 2 4 zerofill(1) 2 9
+3 6 4 no zeros, zerofill(1) 2 9
+4 10 1 3 9
+5 11 20 table-lookup 4 0
+6 31 1 3 9
+7 32 30 no endspace, not_always 5 9
+8 62 35 no endspace, not_always, no empty 6 9
+9 97 35 no empty 7 9
+10 132 35 no endspace, not_always, no empty 6 9
+11 167 4 zerofill(1) 2 9
+12 171 16 no endspace, not_always, no empty 5 9
+13 187 35 no endspace, not_always, no empty 6 9
+14 222 4 zerofill(1) 2 9
+15 226 16 no endspace, not_always, no empty 5 9
+16 242 20 no endspace, not_always 8 9
+17 262 20 no endspace, no empty 8 9
+18 282 20 no endspace, no empty 5 9
+19 302 30 no endspace, no empty 6 9
+20 332 4 always zero 2 9
+21 336 4 always zero 2 9
+22 340 1 3 9
+23 341 8 table-lookup 9 0
+24 349 8 table-lookup 10 0
+25 357 8 always zero 2 9
+26 365 2 2 9
+27 367 2 no zeros, zerofill(1) 2 9
+28 369 4 no zeros, zerofill(1) 2 9
+29 373 4 table-lookup 11 0
+30 377 1 3 9
+31 378 2 no zeros, zerofill(1) 2 9
+32 380 8 no zeros 2 9
+33 388 4 always zero 2 9
+34 392 4 table-lookup 12 0
+35 396 4 no zeros, zerofill(1) 13 9
+36 400 4 no zeros, zerofill(1) 2 9
+37 404 1 2 9
+38 405 4 no zeros 2 9
+39 409 4 always zero 2 9
+40 413 4 no zeros 2 9
+41 417 4 always zero 2 9
+42 421 4 no zeros 2 9
+43 425 4 always zero 2 9
+44 429 20 no empty 3 9
+45 449 30 no empty 3 9
+46 479 1 14 4
+47 480 1 14 4
+48 481 79 no endspace, no empty 15 9
+49 560 79 no empty 2 9
+50 639 79 no empty 2 9
+51 718 79 no endspace 16 9
+52 797 8 no empty 2 9
+53 805 1 17 1
+54 806 1 3 9
+55 807 20 no empty 3 9
+56 827 4 no zeros, zerofill(2) 2 9
+57 831 4 no zeros, zerofill(1) 2 9
+@end example
+
+Die Informationen, die @code{myisampack} ausgibt, sind unten beschrieben:
+
+@table @code
+@item normal
+Die Anzahl von Spalten, für die keine spezielle Komprimierung benutzt wird.
+
+@item empty-space
+Die Anzahl von Spalten, die Werte enthalten, die ausschließlich aus
+Leerzeichen bestehen. Diese Werte nehmen 1 Bit in Anspruch.
+
+@item empty-zero
+Die Anzahl von Spalten, die Werte enthalten, die nur aus binären Nullen
+bestehen. Diese Werte nehmen 1 Bit in Anspruch.
+
+@item empty-fill
+Die Anzahl von Ganzzahl-Spalten, die nicht den gesamten Bereich Ihres Typs
+einnehmen. Diese werden auf einen kleineren Typ geändert (eine
+@code{INTEGER}-Spalte kann zum Beispiel auf @code{MEDIUMINT} geändert
+werden).
+
+@item pre-space
+Die Anzahl von Dezimal-Spalten, die mit führenden Leerzeichen gespeichert
+sind. In diesem Fall enthält jeder Wert einen Zähler für die Anzahl
+führender Leerzeichen.
+
+@item end-space
+Die Anzahl von Spalten, die viele Leerzeichen am Ende enthalten. In diesem
+Fall enthält jeder Wert einen Zähler für die Anzahl von Leerzeichen am
+Ende.
+
+@item table-lookup
+Die Spalte hat nur eine kleine Anzahl verschiedener Werte, die in
+@code{ENUM} umgewandelt werden, bevor die Huffman-Kompression durchgeführt
+wird.
+
+@item zero
+Die Anzahl von Spalten, bei denen alle Werte 0 sind.
+
+@item Original trees
+Die anfängliche Anzahl von Huffman-Bäumen.
+
+@item After join
+Die Anzahl von unterschiedlichen Huffman-Bäumen, die übrig sind, nachdem
+Bäume zusammengefasst wurden, um etwas Header-Platz zu sparen.
+@end table
+
+Nachdem eine Tabelle komprimiert wurde, gibt @code{myisamchk -dvv}
+zusätzliche Informationen über jedes Feld aus:
+
+@table @code
+@item Type
+Der Feldtyp kann folgende Deskriptoren enthalten:
+
+@table @code
+@item constant
+Alle Zeilen haben denselben Wert.
+
+@item no endspace
+Kein Leerzeichen am Ende speichern.
+
+@item no endspace, not_always
+Kein Leerzeichen am Ende speichern und bei allen Werten keine Komprimierung
+für Leerzeichen am Ende durchführen.
+
+@item no endspace, no empty
+Kein Leerzeichen am Ende speichern. Keine leeren Werte speichern.
+
+@item table-lookup
+Die Spalte wurde zu @code{ENUM} umgewandelt.
+
+@item zerofill(n)
+Die wichtigsten @code{n} Bytes im Wert sind immer 0 und wurden nicht
+gespeichert.
+
+@item no zeros
+Keine Nullen speichern.
+
+@item always zero
+0-Werte sind in 1 Bit gespeichert.
+@end table
+
+@item Huff tree
+Der Huffman-Baum, der zu dem Feld gehört.
+
+@item Bits
+Die Anzahl von Bits, die im Huffman-Baum benutzt werden.
+@end table
+
+Nachdem Sie @code{pack_isam}/@code{myisampack} laufen gelassen haben,
+müssen Sie @code{isamchk} / @code{myisamchk} laufen lassen, um den Index
+neu zu erzeugen. Zugleich können Sie die Index-Blöcke sortieren und die
+Statistiken erzeugen, die benötigt werden, damit der MySQL-Optimierer
+effizienter läuft:
+
+@example
+myisamchk -rq --analyze --sort-index tabelle.MYI
+isamchk -rq --analyze --sort-index tabelle.ISM
+@end example
+
+Nachdem Sie die komprimierte Tabelle ins MySQL-Datenbank-Verzeichnis
+gespielt haben, müssen Sie @code{mysqladmin flush-tables} ausführen, um
+@code{mysqld} anzuweisen, die neue Tabelle zu benutzen.
+
+Wenn Sie eine gepackte Tabelle entpacken wollen, können Sie das mit der
+@code{--unpack}-Option für @code{isamchk} oder @code{myisamchk} tun.
+
+
+@node mysqld-max, , myisampack, Server-Side Scripts
+@c German node mysqld-max
+@subsection mysqld-max, ein erweiterter mysqld-Server
+
+@cindex @code{mysqld-max}
+
+@code{mysqld-max} ist der MySQL-Server (@code{mysqld}), der mit folgenden
+configure-Optionen konfiguriert wurde:
+
+@multitable @columnfractions .3 .7
+@item @strong{Option} @tab @strong{Kommentar}
+@item --with-server-suffix=-max @tab Zur @code{mysqld}-Versionszeichenkette ein Suffix hinzufügen.
+@item --with-bdb @tab Unterstützung für Berkeley-DB-(BDB)-Tabellen
+@item --with-innodb @tab Unterstützung für InnoDB-Tabellen.
+@item CFLAGS=-DUSE_SYMDIR @tab Symbolische-Links-Unterstützung für Windows.
+@end multitable
+
+Sie finden die MySQL-max-Binärdateien unter
+@uref{http://www.mysql.com/downloads/mysql-max-3.23.html}.
+
+Die Windows-MySQL-3.23-Binärdistribution beinhaltet sowohl die
+Standard-@code{mysqld.exe}-Binärdatei als auch die
+@code{mysqld-max.exe}-Binärdatei.
+@uref{http://www.mysql.com/downloads/mysql-3.23.html}.
+@xref{Windows installation}.
+
+Beachten Sie, dass, weil InnoDB und Berkeley-DB nicht für alle Plattformen
+verfügbar sind, einige der @code{Max}-Binärdateien eventuell noch
+Unterstützung für diese beiden Typen haben. Sie können überprüfen, welche
+Tabellentypen unterstützt werden, indem Sie die folgende Anfrage ausführen:
+
+@example
+mysql> show variables like "have_%";
++---------------+-------+
+| Variable_name | Value |
++---------------+-------+
+| have_bdb | YES |
+| have_innodb | NO |
+| have_isam | YES |
+| have_raid | NO |
+| have_openssl | NO |
++---------------+-------+
+@end example
+
+Die Bedeutung dieser Werte ist:
+
+@multitable @columnfractions .3 .7
+@item @strong{Wert} @tab @strong{Bedeutung}.
+@item YES @tab Die Option ist aktiviert und benutzbar.
+@item NO @tab MySQL ist nicht mit Unterstützung für diese Option kompiliert.
+@item DISABLED @tab Die xxxx-Option ist deaktiviert, weil @code{mysqld} mit @code{--skip-xxxx} gestartet wurde oder weil @code{mysqld} nicht mit allen notwendigen Optionen gestartet wurde, um die Option zu aktivieren. In diesem Fall sollte die @code{hostname.err}-Datei den Grund dafür enthalten, warum die Option deaktiviert wurde.
+@end multitable
+
+@strong{HINWEIS}: Um InnoDB-Tabellen erzeugen zu können, @strong{MÜSSEN}
+Sie Ihre Startoptionen editieren und zumindest die
+@code{innodb_data_file_path}-Option eingeben. @xref{InnoDB start}.
+
+Um bessere Performance für BDB-Tabellen zu erzielen, sollten Sie auch für
+diese einige Konfigurationsoptionen angeben. @xref{BDB start}.
+
+@code{safe_mysqld} versucht automatisch, eine @code{mysqld}-Binärdatei mit
+dem @code{-max}-Präfix zu starten. Das macht es sehr einfach, eine andere
+@code{mysqld}-Binärdatei in einer bestehenden Installation auszutesten.
+Lassen Sie einfach @code{configure} mit den Optionen, die Sie wollen,
+laufen, und installieren Sie dann die neue @code{mysqld}-Binärdatei als
+@code{mysqld-max} im selben Verzeichnis, wo Ihre alte
+@code{mysqld}-Binärdatei liegt. @xref{safe_mysqld, , @code{safe_mysqld}}.
+
+Der @code{mysqld-max}-RPM benutzt das oben erwähnte
+@code{safe_mysqld}-Feature. Er installiert nur die ausführbare Datei
+@code{mysqld-max} und @code{safe_mysqld} benutzt diese automatisch, wenn
+@code{safe_mysqld} neu gestartet wird.
+
+Folgende Tabelle zeigt, welche Tabellentypen unsere
+Standard-@strong{MySQL-Max}-Binärdateien beinhalten:
+
+@multitable @columnfractions .4 .3 .3
+@item @strong{System} @tab @strong{BDB} @tab @strong{InnoDB}
+@item AIX 4.3 @tab NEIN @tab JA
+@item HP-UX 11.0 @tab NEIN @tab JA
+@item Linux-Alpha @tab NEIN @tab JA
+@item Linux-Intel @tab JA @tab JA
+@item Linux-Ia64 @tab NEIN @tab JA
+@item Solaris-intel @tab NEIN @tab JA
+@item Solaris-sparc @tab JA @tab JA
+@item Caldera (SCO) OSR5 @tab JA @tab JA
+@item UnixWare @tab JA @tab JA
+@item Windows/NT @tab JA @tab JA
+@end multitable
+
+
+@node Client-Side Scripts, Log Files, Server-Side Scripts, MySQL Database Administration
+@c German node Clientseitige Skripte
+@section Clientseitige Skripte und Hilfsprogramme von MySQL
+
+
+
+@menu
+* Client-Side Overview::
+* mysql::
+* mysqladmin::
+* Using mysqlcheck::
+* mysqldump::
+* mysqlhotcopy::
+* mysqlimport::
+* mysqlshow::
+* perror::
+* Batch Commands::
+@end menu
+
+@node Client-Side Overview, mysql, Client-Side Scripts, Client-Side Scripts
+@c German node Überblick über die clientseitigen Skripte
+@subsection Überblick über die clientseitigen Skripte und Dienstprogramme
+
+@cindex Umgebungsvariablen
+@cindex Programme, Auflistung
+
+Alle MySQL-Clients, die mittels der @code{mysqlclient}-Bibliothek mit dem
+Server kommunizieren, benutzen folgende Umgebungsvariablen:
+
+@tindex @code{MYSQL_UNIX_PORT}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_UNIX_PORT}
+@tindex @code{MYSQL_TCP_PORT}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_TCP_PORT}
+@tindex @code{MYSQL_PWD}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_PWD}
+@tindex @code{MYSQL_DEBUG}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_DEBUG}
+@multitable @columnfractions .25 .75
+@item @strong{Name} @tab @strong{Beschreibung}
+@item @code{MYSQL_UNIX_PORT} @tab Der vorgabemäßige Socket, benutzt für Verbindungen zu @code{localhost}
+@item @code{MYSQL_TCP_PORT} @tab Der vorgabemäßige TCP/IP-Port
+@item @code{MYSQL_PWD} @tab Das vorgabemäßige Passwort
+@item @code{MYSQL_DEBUG} @tab Debug-Trace-Optionen beim Debuggen
+@item @code{TMPDIR} @tab Das Verzeichnis, in dem temporäre Tabellen / Dateien erzeugt werden
+@end multitable
+
+Die Benutzung von @code{MYSQL_PWD} ist unsicher.
+@xref{Connecting}.
+
+@tindex @code{MYSQL_HISTFILE}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{MYSQL_HISTFILE}
+@tindex @code{HOME}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{HOME}
+@cindex History-Datei
+@cindex Kommandozeilen-History
+@tindex .mysql_History-Datei
+Der @file{mysql}-Client benutzt die Datei in der @code{MYSQL_HISTFILE}-
+Umgebungsvariablen genannte Datei, um die Kommandozeilen-History zu
+speichern. Der Vorgabewert für die History-Datei ist
+@file{$HOME/.mysql_history}, wobei @code{$HOME} der Wert der
+@code{HOME}-Umgebungsvariablen ist. @xref{Environment variables}.
+
+Alle MySQL-Programme haben viele verschiedene Optionen. Jedes
+MySQL-Programm stellt jedoch ein @code{--help}-Option zur Verfügung, die
+Sie benutzen können, um eine vollständige Beschreibung der verschiedenen
+Optionen des Programms zu erhalten. Probieren Sie zum Beispiel @code{mysql
+--help} aus.
+
+Sie können die vorgabemäßigen Optionen für alle Standard-Client-Programme
+mit einer Optionsdatei überschreiben. @ref{Option files}.
+
+Die unten stehende Liste beschreibt kurz die MySQL-Programme:
+
+@table @code
+@cindex @code{myisamchk}
+@item myisamchk
+Dienstprogramm zur Beschreibung, Prüfung, Optimierung und Reparatur von
+MySQL-Tabellen. Weil @code{myisamchk} viele Funktionen hat, ist es in einem
+eigenen Kapitel beschrieben. @xref{MySQL Database Administration}.
+
+@cindex @code{make_binary_distribution}
+@item make_binary_distribution
+Macht ein Binär-Release eines kompilierten MySQL. Dieses könnte über FTP an
+@file{/pub/mysql/Incoming} oder an @code{Support.mysql.com} geschickt
+werden, damit andere MySQL-Benutzer es benutzen können.
+
+@cindex @code{msql2mysql}
+@item msql2mysql
+Ein Shell-Skript, das @code{mSQL}-Programme zu MySQL konvertiert. Es deckt
+nicht alle Fälle ab, ist aber hilfreich, um mit dem Konvertieren
+anzufangen.
+
+@cindex @code{mysqlaccess}
+@item mysqlaccess
+Ein Skript, das die Zugriffsberechtigungen für eine Host-, Benutzer- und
+Datenbank-Kombination prüft.
+
+@cindex @code{mysqladmin}
+@item mysqladmin
+Dienstprogramm für die Durchführung von Verwaltungsoperationen wie Erzeugen
+und Löschen von Datenbanken, Neulanden der Berechtigungstabellen,
+Zurückschreiben von Tabellen auf Platte und Neuöffnen von Log-Dateien.
+@code{mysqladmin} kann auch benutzt werden, um Versionsnummer sowie Status-
+und Prozess-Informationen vom Server zu erhalten.
+@xref{mysqladmin, , @code{mysqladmin}}.
+
+@cindex @code{mysqlbug}
+@item mysqlbug
+Das MySQL-Bug-Bericht-Skript. Dieses Skript sollte immer benutzt werden,
+wenn Sie einen Bug-Bericht an die MySQL-Liste ausfüllen.
+
+@cindex @code{mysqld}
+@item mysqld
+Der SQL-Daemon. Dieser sollte immer laufen.
+
+@cindex @code{mysqldump}
+@item mysqldump
+Dumpt eine MySQL-Datenbank in eine Datei als SQL-Statements oder als
+Tabulator-separierte Textdateien. Verbesserte Freeware, ursprünglich von
+Igor Romanenko. @xref{mysqldump, , @code{mysqldump}}.
+
+@cindex @code{mysqlimport}
+@item mysqlimport
+Importiert Textdateien in die jeweiligen Tabellen mittels @code{LOAD DATA
+INFILE}. @xref{mysqlimport, , @code{mysqlimport}}.
+
+@cindex @code{mysqlshow}
+@item mysqlshow
+Zeigt Informationen über Datenbanken, Tabellen, Spalten und Indexe an.
+
+@cindex @code{mysql_install_db}
+@item mysql_install_db
+Erzeugt die MySQL-Berechtigungstabellen mit vorgabemäßigen Berechtigungen.
+Dieses Skript wird gewöhnlich nur einmal ausgeführt, wenn Sie MySQL das
+erste Mal auf einem System installieren.
+
+@cindex @code{replace}
+@item replace
+Ein Dienstprogramm, das von @code{msql2mysql} benutzt wird, aber auch
+darüber hinaus benutzt werden kann. @code{replace} ändert Zeichenketten in
+Dateien oder auf der Standardeingabe. Benutzt eine finite Status-Maschine,
+um zuerst Übereinstimmung mit längeren Zeichenketten zu finden. Kann
+benutzt werden, um Zeichenketten umzudrehen. Der folgende Befehl zum
+Beispiel dreht @code{a} und @code{b} in den angegebenen Dateien um:
+
+@example
+shell> replace a b b a --Datei1 Datei2 ...
+@end example
+@end table
+
+
+@node mysql, mysqladmin, Client-Side Overview, Client-Side Scripts
+@c German node mysql
+@subsection Das Kommandozeilen-Werkzeug
+
+@cindex Kommandozeilen-Werkzeug
+@cindex Werkzeuge, Kommandozeile
+@cindex Skripte
+@cindex @code{mysql}
+
+@code{mysql} ist eine einfache SQL-Shell (mit GNU
+@code{readline}-Fähigkeiten). Sie unterstützt interaktiven und nicht
+interaktiven Gebrauch. Wenn sie interaktiv benutzt wird, werden
+Anfrageergebnisse in einem ASCII-Tabellenformat ausgegeben. Wenn sie nicht
+interaktiv benutzt wird (zum Beispiel als Filter), wird das Ergebnis in
+Tabulator-separiertem Format ausgegeben. (Das Ausgabeformat kann mit den
+Kommandozeilenoptionen geändert werden.) Skripte können Sie einfach wie
+folgt laufen lassen:
+
+@example
+shell> mysql datenbank < skript.sql > ausgabe.tab
+@end example
+
+Wenn Sie Probleme haben, die auf ungenügenden Speicher beim Client
+zurückzuführen sind, benutzen Sie die @code{--quick}-Option! Diese zwingt
+@code{mysql}, @code{mysql_use_result()} statt @code{mysql_store_result()}
+zu benutzen, um die Ergebnismenge zu holen.
+
+Die Benutzung von @code{mysql} ist sehr einfach. Starten Sie es einfach wie
+folgt:
+@code{mysql datenbank} oder @code{mysql --user=benutzername
+--password=ihr_passwort datenbank}. Geben Sie ein SQL-Statement ein,
+beenden Sie es mit @samp{;}, @samp{\g} oder @samp{\G}, und drücken Sie die
+Eingabetaste.
+
+@cindex @code{mysql}-Kommandozeilenoptionen
+@cindex Kommandozeilenoptionen, @code{mysql}
+@cindex Optionen, Kommandozeile, @code{mysql}
+@cindex Startparameter, @code{mysql}
+@code{mysql} unterstützt folgende Optionen:
+
+@table @code
+@cindex @code{help}, @code{mysql}-Option
+@item -?, --help
+Hilfetext ausgeben und beenden.
+
+@cindex @code{no-auto-rehash}, @code{mysql}-Option
+@item -A, --no-auto-rehash
+Kein automatisches Rehashing. Man muss 'rehash' benutzen, um Tabellen- und
+Feld-Vervollständigung zu erhalten. Durch die Option wird mysql schneller
+gestartet.
+
+@cindex @code{batch}, @code{mysql}-Option
+@item -B, --batch
+Ergebnisse mit einem Tabulator als Trennzeichen ausgeben, jede
+Tabellenzeile auf einer neuen Zeile. Keine History-Datei benutzen.
+
+@cindex @code{character-sets-dir}, @code{mysql}-Option
+@item --character-sets-dir=...
+Verzeichnis, in dem sich die Zeichensätze befinden.
+
+@cindex @code{compress}, @code{mysql}-Option
+@item -C, --compress
+Im Client-Server-Protokoll Komprimierung benutzen.
+
+@cindex @code{debug}, @code{mysql}-Option
+@item -#, --debug[=...]
+Debug loggen. Vorgabe ist 'd:t:o,/tmp/mysql.trace'.
+
+@cindex @code{database}, @code{mysql}-Option
+@item -D, --database=...
+Datenbank, die benutzt werden soll. Hauptsächlich nützlich in der
+@code{my.cnf}-Datei.
+
+@cindex @code{default-character-set}, @code{mysql}-Option
+@item --default-character-set=...
+Den vorgabemäßigen Zeichensatz setzen.
+
+@cindex @code{execute}, @code{mysql}-Option
+@item -e, --execute=...
+Befehl ausführen und beenden. (Ausgabe wie bei --batch)
+
+@cindex @code{vertical}, @code{mysql}-Option
+@item -E, --vertical
+Ausgabe einer Anfrage (Zeilen) vertikal darstellen. Ohne diese Option
+können Sie diese Ausgabe auch dadurch erzwingen, dass Sie Ihre Statements
+mit @code{\G} beenden.
+
+@cindex @code{force}, @code{mysql}-Option
+@item -f, --force
+Weitermachen, auch wenn ein SQL-Fehler auftritt.
+
+@cindex @code{no-named-commands}, @code{mysql}-Option
+@item -g, --no-named-commands
+Benannte Befehle werden deaktiviert. Benutzen Sie nur die \*-Form, oder
+benutzen Sie benannte Befehle nur bei Zeilen, die mit einem Semikolon
+enden. Ab Version 10.9 startet der Client vorgabemäßig mit ANGESCHALTETER
+Option! Wenn die -g-Option angeschaltet ist, funktionieren Befehle im
+Langformat jedoch immer noch von der ersten Zeile aus.
+
+@cindex @code{enable-named-commands}, @code{mysql}-Option
+@item -G, --enable-named-commands
+Benannte Befehle sind @strong{angeschaltet}. Befehle im Langformat sind
+ebenso zugelassen wie die abgekürzten \*-Befehle.
+
+@cindex @code{ignore-space}, @code{mysql}-Option
+@item -i, --ignore-space
+Leerzeichen nach Funktionsnamen ignorieren.
+
+@cindex @code{host}, @code{mysql}-Option
+@item -h, --host=...
+Connect to the given host.
+
+@cindex @code{html}, @code{mysql}-Option
+@item -H, --html
+HTML-Ausgabe produzieren.
+
+@cindex @code{skip-line-numbers}, @code{mysql}-Option
+@item -L, --skip-line-numbers
+Bei Fehlern keine Zeilennummer ausgeben. Nützlich, wenn man mit
+Ergebnisdateien vergleichen will, die Fehlermeldungen enthalten.
+
+@cindex @code{no-pager}, @code{mysql}-Option
+@item --no-pager
+Pager deaktivieren und nach stdout ausgeben. Siehe auch interaktive Hilfe
+(\h).
+
+@cindex @code{no-tee}, @code{mysql}-Option
+@item --no-tee
+Ausgabedatei (Outfile) deaktivieren. Siehe auch interaktive Hilfe (\h).
+
+@cindex @code{unbuffered}, @code{mysql}-Option
+@item -n, --unbuffered
+Nach jeder Anfrage Buffer zurückschreiben (flush).
+
+@cindex @code{skip-column-names}, @code{mysql}-Option
+@item -N, --skip-column-names
+In Ergebnissen keine Spaltennamen ausgeben.
+
+@cindex @code{set-variable}, @code{mysql}-Option
+@item -O, --set-variable var=option
+Einer Variablen einen Wert zuweisen. @code{--help} listet Variablen auf.
+
+@cindex @code{one-database}, @code{mysql}-Option
+@item -o, --one-database
+Nur die vorgabemäßige Datenbank aktualisieren. Das ist nützlich, wenn man
+in der Update-Logdatei Aktualisierungen (Updates) auf eine andere Datenbank
+überspringen will.
+
+@cindex @code{pager}, @code{mysql}-Option
+@item @code{--pager[=...]}
+Ausgabetyp. Vorgabe ist Ihre @code{ENV}-Variable @code{PAGER}. Gültige
+Pager sind less, more, cat [> Dateiname] usw. Siehe auch interaktive Hilfe
+(\h). Diese Option funktioniert nicht im Stapelmodus. Der Pager
+funktioniert nur unter UNIX.
+
+@cindex @code{password}, @code{mysql}-Option
+@item -p[password], --password[=...]
+Passwort, das für die Verbindung zum Server benutzt wird. Wenn das Passwort
+nicht auf der Kommandozeile angegeben wird, wird eine Eingabeaufforderung
+dafür ausgegeben. Beachten Sie: Wenn Sie die Kurzform @code{-p} benutzen,
+darf zwischen der Option und dem Passwort kein Leerzeichen stehen.
+
+@cindex @code{port}, @code{mysql}-Option
+@item -P --port=...
+TCP/IP-Portnummer, die für die Verbindung benutzt wird.
+
+@cindex @code{quick}, @code{mysql}-Option
+@item -q, --quick
+Ergebnisse nicht cachen, Zeile für Zeile ausgeben. Das kann den Server
+verlangsamen, wenn die Ausgabe verschoben wird. Keine History-Datei
+benutzen.
+
+@cindex @code{raw}, @code{mysql}-Option
+@item -r, --raw
+Spaltenwerte ohne Escape-Umwandlung schreiben. Benutzt für @code{--batch}.
+
+@cindex @code{silent}, @code{mysql}-Option
+@item -s, --silent
+Schweigsamer sein.
+
+@cindex @code{socket}, @code{mysql}-Option
+@item -S --socket=...
+Socket-Datei, die für die Verbindung benutzt wird.
+
+@cindex @code{table}, @code{mysql}-Option
+@item -t --table
+Ausgabe im Tabellenformat. Das ist die Vorgabe im Nicht-Stapelmodus.
+
+@cindex @code{debug-info}, @code{mysql}-Option
+@item -T, --debug-info
+Beim Verlassen einige Debug-Informationen ausgeben.
+
+@cindex @code{tee}, @code{mysql}-Option
+@item --tee=...
+Alles an die Ausgabedatei anhängen. Siehe auch interaktive Hilfe (\h).
+Funktioniert nicht im Stapelmodus.
+
+@cindex @code{user}, @code{mysql}-Option
+@item -u, --user=#
+Benutzer zum Einloggen, falls nicht der aktuelle UNIX-Benutzer.
+
+@cindex @code{safe-updates}, @code{mysql}-Option
+@item -U, --safe-updates[=#], --i-am-a-dummy[=#]
+Läßt nur @code{UPDATE} und @code{DELETE} zu, die Schlüssel benutzen. Siehe
+unten wegen weiterer Informationen über diese Option. Sie können diese
+Option zurücksetzen, wenn Sie sie in Ihrer @code{my.cnf}-Datei haben, indem
+Sie @code{--safe-updates=0} benutzen.
+
+@cindex @code{verbose}, @code{mysql}-Option
+@item -v, --verbose
+Geschwätzigere Ausgabe (-v -v -v ergibt das Tabellen-Ausgabeformat).
+
+@cindex @code{version}, @code{mysql}-Option
+@item -V, --version
+Versionsinformationen ausgeben und beenden.
+
+@cindex @code{wait}, @code{mysql}-Option
+@item -w, --wait
+Wenn die Verbindung geschlossen wurde, warten und noch einmal versuchen,
+statt abzubrechen.
+@end table
+
+Mit @code{-O} oder @code{--set-variable} können Sie auch die folgenden
+Variablen setzen:
+
+@cindex timeout, @code{connect_timeout}-Variable
+@cindex @code{connect_timeout}-Variable
+@cindex @code{max_allowed_packet}
+@cindex @code{net_buffer_length}
+@cindex @code{select_limit}
+@cindex @code{max_join_size}
+@multitable @columnfractions .3 .2 .5
+@item Variablenname @tab Vorgabe @tab Beschreibung
+@item connect_timeout @tab 0 @tab Anzahl von Sekunden, bevor die Verbindung wegen Zeitüberschreitung abgebrochen wird
+@item max_allowed_packet @tab 16777216 @tab Maximale Paketlänge, die zum Server gesendet bzw. von diesem empfangen wird
+@item net_buffer_length @tab 16384 @tab Puffer für TCP/IP- und Socket-Kommunikation
+@item select_limit @tab 1000 @tab Automatisches Limit für SELECT bei Benutzung von --i-am-a-dummy
+@item max_join_size @tab 1000000 @tab Automatisches Limit für Zeilen in einem Join bei Benutzung von --i-am-a-dummy.
+@end multitable
+
+Wenn Sie 'help' auf der Kommandozeile eingeben, gibt @code{mysql} die
+Befehle aus, die es unterstützt:
+
+@cindex Befehle, Auflistung
+@example
+mysql> help
+
+MySQL-Befehle:
+help (\h) Diesen Text anzeigen.
+? (\h) Synonym für `help'.
+clear (\c) Lösch-Befehl.
+connect (\r) Erneut mit dem Server verbinden. Optionale Argumente sind db und host.
+edit (\e) Befehl mit $EDITOR editieren.
+ego (\G) Befehl an den MySQL-Server schicken, Ergebnis vertikal anzeigen.
+exit (\q) mysql beenden. Dasselbe wie quit.
+go (\g) Befehl an den MySQL-Server schicken.
+nopager (\n) Pager deaktivieren, nach stdout ausgeben.
+notee (\t) Nicht in die Ausgabedatei (Outfile) schreiben.
+pager (\P) PAGER [auf_pager] setzen. Anfrageergebnisse über PAGER ausgeben.
+print (\p) Aktuellen Befehl ausgeben.
+quit (\q) mysql beenden.
+rehash (\#) Vervollständigungs-Hash neu aufbauen.
+source (\.) Eine SQLsSkriptdatei ausführen. Benötigt einen Dateinamen als Argument.
+status (\s) Statusinformationen vom Server abrufen.
+tee (\T) Ausgabedatei [auf_outfile] setzen. Alles an die angegebene Ausgabedatei anhängen.
+use (\u) Eine andere Datenbankbenutzung. Benötigt Datenbanknamen als Argument.
+@end example
+
+Bei diesen Befehlen funktioniert PAGER nur unter UNIX.
+
+@cindex status command
+Der @code{status}-Befehl gibt Ihnen einige Informationen über die
+Verbindung und den Server, den Sie benutzen. Wenn der Server im
+@code{--safe-updates}-Modus läuft, gibt @code{status} auch die Werte der
+@code{mysql}-Variablen aus, die Ihre Anfragen beeinflussen.
+
+@cindex @code{safe-mode}-Befehl
+Eine nützliche Startoption für Anfänger (eingeführt in MySQL-Version
+3.23.11) ist @code{--safe-updates} (oder @code{--i-am-a-dummy} für
+Benutzer, die irgendwann ein @code{DELETE FROM tabelle} eingeben, aber
+vergessen, die @code{WHERE}-Klausel) zu benutzen. Wenn Sie diese Option
+benutzen, schickt @code{mysql} beim Öffnen der Verbindung folgenden Befehl
+an den MySQL-Server:
+
+@example
+SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
+ SQL_MAX_JOIN_SIZE=#max_join_size#"
+@end example
+
+Wobei @code{#select_limit#} und @code{#max_join_size#} Variablen sind, die
+auf der @code{mysql}-Kommandozeile gesetzt werden können.
+@c German FIX unsplit @xref
+@xref{SET OPTION}.
+
+Die Auswirkung davon ist folgende:
+
+@itemize @bullet
+@item
+@code{UPDATE}- oder @code{DELETE}-Statements ohne Schlüsselbeschränkung im
+@code{WHERE}-Teil sind nicht zugelassen. Man kann jedoch ein
+@code{UPDATE/DELETE} durch die Benutzung von @code{LIMIT} erzwingen:
+@example
+UPDATE tabelle SET not_key_column=# WHERE not_key_column=# LIMIT 1;
+@end example
+@item
+Alle großen Ergebnisse werden automatisch auf @code{#select_limit#} Zeilen
+begrenzt.
+@item
+@code{SELECT}'s, die wahrscheinlich mehr als @code{#max_join_size}
+Zeilenkombinationen durchgehen müssen, werden abgebrochen.
+@end itemize
+
+Einige nützliche Anmerkungen zum @code{mysql}-Client:
+
+Einige Daten sind lesbarer, wenn sie vertikal angezeigt werden statt auf
+die übliche horizontale kastenähnliche Art. Langer Text zum Beispiel, der
+Zeilenumbrüche beinhaltet, ist bei vertikaler Ausgabe meist viel einfacher
+zu lesen.
+
+@example
+mysql> select * from mails where length(txt) < 300 limit 300,1\G
+*************************** 1. row ***************************
+ msg_nro: 3068
+ date: 2000-03-01 23:29:50
+time_zone: +0200
+mail_from: Monty
+ reply: monty@@no.spam.com
+ mail_to: "Thimble Smith" <tim@@no.spam.com>
+ sbj: UTF-8
+ txt: >>>>> "Thimble" == Thimble Smith writes:
+
+Thimble> Hi. Meines Erachtens eine gute Idee. Kennt sich jemand mit UTF-8
+Thimble> oder Unicode aus? Ansonsten packe ich das auf meine TODO-Liste
+Thimble> und warte, was passiert.
+
+Ja, mach das bitte!
+
+Regards,
+Monty
+ Datei: inbox-jani-1
+ hash: 190402944
+1 row in set (0.09 sec)
+@end example
+
+@itemize @bullet
+@item
+Zum Mitloggen benutzen Sie die @code{tee}-Option. @code{tee} wird mit der
+Option @code{--tee=...} oder interaktiv auf der Kommandozeile mi dem Befehl
+@code{tee} gestartet. Alle Daten, die auf dem Bildschirm erscheinen, werden
+auch in die angegebene Datei geschrieben. Das kann auch für Debug-Zwecke
+sehr hilfreich sein. @code{tee} kann von der Kommandozeile aus mit dem
+Befehl @code{notee} deaktiviert werden. Wenn @code{tee} noch einmal
+eingegeben wird, wird wiederum mit dem Loggen begonnen. Ohne Parameter wird
+die vorherige Datei wiederum benutzt. Beachten Sie, dass @code{tee} die
+Ergebnisse nach jedem Befehl in die Datei zurückschreibt, direkt bevor die
+Kommandozeilenaufforderung für den nächsten Befehl erscheint.
+
+@item
+Das Durchstöbern oder Durchsuchen der Ergebnisse im interaktiven Modus in
+UNIX-less, -more oder einem ähnlichen Programm ist jetzt möglich mit der
+Option @code{--pager[=...]}. Ohne Argument aufgerufen sieht der
+@code{mysql}-Client in der Umgebungsvariablen PAGER nach und setzt
+@code{pager} auf diesen Wert. @code{pager} kann von der interaktiven
+Kommandozeile mit dem Befehl @code{pager} gestartet und mit @code{nopager}
+deaktiviert werden. Optional nimmt der Befehl ein Argument entgegen und
+setzt @code{pager} darauf. @code{pager} kann ohne Argument aufgerufen
+werden, aber das erfordert, dass die Option @code{--pager} benutzt wurde,
+ansonsten gibt @code{pager} in stdout aus. @code{pager} funktioniert nur
+unter UNIX, denn es benutzt die popen()-Funktion, die es unter Windows
+nicht gibt. Unter Windows kann statt dessen die @code{tee}-Option benutzt
+werden, wenngleich diese in manchen Situationen nicht ganz so handlich ist
+wie @code{pager}.
+
+@item
+Ein paar Tipps zu @code{pager}: Sie können es benutzen, um in eine Datei zu
+schreiben:
+@example
+mysql> pager cat > /tmp/log.txt
+@end example
+Die Ergebnisse werden nur in eine Datei geschrieben. Sie können auch
+Optionen an Programme übergeben, die Sie mit @code{pager} zusammen benutzen
+wollen:
+@example
+mysql> pager less -n -i -S
+@end example
+Beachten Sie hierbei die Option '-S'. Beim Durchstöbern der Ergebnisse
+werden Sie diese wahrscheinlich als sehr nützlich erachten. Probieren Sie
+dei Option mit horizontaler Ausgabe (Befehle enden mit '\g', oder ';') und
+mit vertikaler Ausgabe (Befehle enden mit '\G') aus. Manchmal ist ein sehr
+breites Ergebnis schwer am Bildschirm zu lesen. Mit der Option -S für less
+können Sie die Ergebnisse im interaktiven less von links nach rechts
+durchstöbern, wobei verhindert wird, dass Zeilen, die länger sind als Ihre
+Bildschirmbreite, in die nächste Zeile umgebrochen werden. Das kann ein
+Ergebnis sehr viel lesbarer gestalten. Sie können den Modus im interaktiven
+less an- und abschalten, wenn Sie '-S' benutzen. Siehe 'h' für weitere
+Hilfe zu less.
+
+@item
+Zum Schluss (falls Sie das nicht schon aus den oben aufgeführten Beispielen
+heraus gefunden haben ;-) können Sie sehr komplexe Dinge tun, um die
+Ergebnisse zu handhaben. Folgendes würde die Ergebnisse beispielsweise an
+zwei verschiedene Dateien in zwei unterschiedlichen Verzeichnissen
+schicken, auf zwei unterschiedlichen Festplatten, die auf /dr1 und /dr2
+gemountet sind, und dennoch die Ergebnisse über less am Bildschirm
+anzeigen:
+@example
+mysql> pager cat | tee /dr1/tmp/res.txt | tee /dr2/tmp/res2.txt | less -n -i -S
+@end example
+
+@item
+Sie können die obigen Funktionen auch kombinieren, indem Sie @code{tee}
+anschalten und @code{pager} auf 'less' setzen. Dann können Sie die
+Ergebnisse in 'less' durchstöbern und trotzdem wird alles zugleich an eine
+Datei angehängt. Der Unterschied zwischen @code{UNIX tee}, was mit
+@code{pager} benutzt wird, und dem im @code{mysql}-Client eingebauten
+@code{tee} ist, dass das eingebaute @code{tee} sogar dann funktioniert,
+wenn kein @code{UNIX tee} verfügbar ist. Darüber hinaus gibt das eingebaute
+@code{tee} alles, was mitgeloggt wird, auch am Bildschirm aus, wohingegen
+das @code{UNIX tee} in Verbindung mit @code{pager} nicht so viel mitloggt.
+Letztlich läßt sich das interaktive @code{tee} auch handlicher aus- und
+einschalten, wenn Sie teilweise mitloggen wollen, aber in der Lage sein,
+das Feature zwischendurch auszuschalten.
+@end itemize
+
+
+@node mysqladmin, Using mysqlcheck, mysql, Client-Side Scripts
+@c German node mysqladmin
+@subsection mysqladmin, Verwaltung eines MySQL-Servers
+
+@cindex Administration, Server
+@cindex Serververwaltung
+@cindex @code{mysladmn}
+
+Ein Dienstprogramm, um Verwaltungsoperationen durchzuführen. Die Syntax ist::
+
+@example
+shell> mysqladmin [OPTIONS] befehl [befehl-option] befehl ...
+@end example
+
+Sie erhalten eine Auflistung der Optionen, die Ihre
+@code{mysqladmin}-Version unterstützt, indem Sie @code{mysqladmin --help}
+ausführen.
+
+Das aktuelle @code{mysqladmin} unterstützt folgende Befehle:
+
+@table @code
+@item create datenbank
+Eine neue Datenbank erzeugen.
+
+@item drop datenbank
+Eine Datenbank und alle ihre Tabellen löschen.
+
+@item extended-status
+Eine erweiterte Statusmeldung vom Server ausgeben.
+
+@item flush-hosts
+Alle gecacheten Hosts zurückschreiben (flush).
+
+@item flush-logs
+Alle Logs zurückschreiben (flush).
+
+@item flush-tables
+Alle Tabellen zurückschreiben (flush).
+
+@item flush-privileges
+Berechtigungstabellen neu laden (dasselbe wie reload).
+
+@item kill id,id,...
+MySQL-Threads killen.
+
+@item password
+Ein neues Passwort setzen. Altes Passwort zu neuem Passwort ändern.
+
+@item ping
+Überprüfen, ob mysqld lebt.
+
+@item processlist
+Auflistung aktiver Threads im Server.
+
+@item reload
+Berechtigungstabellen neu laden.
+
+@item refresh
+Alle Tabellen zurückschreiben (flush), Log-Dateien schließen und erneut
+öffnen.
+
+@item shutdown
+Server herunter fahren.
+
+@item slave-start
+Slave-Replikations-Thread starten.
+
+@item slave-stop
+Slave-Replikations-Thread anhalten.
+
+@item status
+Eine kurze Statusmeldung vom Server ausgeben.
+
+@item variables
+Verfügbare Variablen ausgeben.
+
+@item version
+Versionsinformation vom Server abrufen.
+@end table
+
+Alle Befehle können auf ihr eindeutiges Präfix abgekürzt werden. Beispiel:
+
+@example
+shell> mysqladmin proc stat
++----+-------+-----------+----+-------------+------+-------+------+
+| Id | User | Host | db | Command | Time | State | Info |
++----+-------+-----------+----+-------------+------+-------+------+
+| 6 | monty | localhost | | Processlist | 0 | | |
++----+-------+-----------+----+-------------+------+-------+------+
+Uptime: 10077 Threads: 1 Questions: 9 Slow queries: 0 Opens: 6 Flush tables: 1 Open tables: 2 Memory in use: 1092K Max memory used: 1116K
+@end example
+
+@cindex Status-Befehl, Ergebnisse
+Das Ergebnis des @code{mysqladmin status}-Befehls hat folgende Spalten:
+
+@cindex uptime
+@multitable @columnfractions .3 .7
+@item Uptime @tab Anzahl von Sekunden, seit der MySQL-Server hoch gefahren ist.
+@cindex Threads
+@item Threads @tab Anzahl aktiver Threads (Clients).
+@cindex questions
+@item Questions @tab Anzahl von Questions von Clients, seit @code{mysqld} gestartet wurde.
+@cindex slow queries
+@item Slow queries @tab Anfragen, die länger als @code{long_query_time} Sekunden benötigten. @xref{Slow query log}.
+@cindex opens
+@item Opens @tab Wie viele Tabellen @code{mysqld} geöffnet hat.
+@cindex flush tables
+@cindex tables, flush
+@item Flush Tables @tab Anzahl von @code{flush ...}-, @code{refresh}- und @code{reload}-Befehlen.
+@cindex open tables
+@item Open Tables @tab Anzahl der Tabellen, die gerade geöffnet sind.
+@cindex memory use
+@item Memory in use @tab Arbeitsspeicher, der direkt vom @code{mysqld}-Code beansprucht wird (nur verfügbar, wenn MySQL mit --with-debug=full kompiliert wurde).
+@cindex max memory used
+@item Max memory used @tab Maximaler Arbeitsspeicher, der direkt vom @code{mysqld}-Code beansprucht wird (nur verfügbar, wenn MySQL mit --with-debug=full kompiliert wurde).
+@end multitable
+
+Wenn Sie @code{mysqladmin shutdown} auf einem Socket ausführen (mit anderen
+Worten, auf dem Computer, wo @code{mysqld} läuft), wartet
+@code{mysqladmin}, bis MySQL die @code{pid-file} entfernt hat, um
+sicherzustellen, dass der @code{mysqld}-Server korrekt angehalten wurde.
+
+
+@node Using mysqlcheck, mysqldump, mysqladmin, Client-Side Scripts
+@c German node mysqlcheck
+@subsection Benutzung von @code{mysqlcheck} für Tabellenwartung und Wiederherstellung nach Abstürzen
+
+Ab MySQL-Version 3.23.38 können Sie ein neues Prüf- und Reparatur-Werkzeug
+für @code{MyISAM}-Tabellen einsetzen. Der Unterschied zu @code{myisamchk}
+ist, dass @code{mysqlcheck} benutzt werden kann, wenn der
+@code{mysqld}-Server läuft, wohingegen @code{myisamchk} nur benutzt werden
+sollte, wenn er nicht läuft. Der Vorteil ist, dass Sie den Server zum
+Prüfen oder zur Reparatur Ihrer Tabellen nicht mehr herunter fahren müssen.
+
+@code{mysqlcheck} benutzt die MySQL-Server-Befehle @code{CHECK},
+@code{REPAIR}, @code{ANALYZE} und @code{OPTIMIZE} auf eine für den Benutzer
+bequeme Weise.
+
+Es gibt drei alternative Möglichkeiten, @code{mysqlcheck} aufzurufen:
+
+@example
+shell> mysqlcheck [OPTIONS] datenbank [tabellen]
+shell> mysqlcheck [OPTIONS] --databases datenbank1 [datenbank2 datenbank3...]
+shell> mysqlcheck [OPTIONS] --all-databases
+@end example
+
+Daher kann es hinsichtlich der Auswahl von Datenbanken und Tabellen ähnlich
+wie @code{mysqldump} benutzt werden.
+
+@code{mysqlcheck} besitzt im Vergleich zu den anderen Clients ein
+besonderes Feature: Das vorgabemäßige Verhalten, Tabellen mit -c zu
+prüfen, kann geändert werden, indem die Binärdatei umbenannt wird. Wenn Sie
+nur ein Werkzeug haben wollen, das vorgabemäßig Tabellen repariert,
+kopieren Sie eine @code{mysqlcheck} mit einem neuen Namen auf Ihre
+Festplatte, nämlich @code{mysqlrepair}, oder legen alternativ einen
+symbolischen Link auf @code{mysqlrepair} und benennen den Link
+@code{mysqlrepair}. Wenn Sie jetzt @code{mysqlrepair} aufrufen, repariert
+es vorgabemäßig Tabellen.
+
+Folgende Namen können Sie benutzen, um das vorgabemäßige Verhalten von
+@code{mysqlcheck} zu verändern:
+
+@example
+mysqlrepair: Vorgabe-Option: -r (reparieren)
+mysqlanalyze: Vorgabe-Option: -a (analysieren)
+mysqloptimize: Vorgabe-Option: -o (optimieren)
+@end example
+
+Die verfügbaren Optionen für @code{mysqlcheck} sind hier aufgelistet. Bitte
+prüfen Sie mit @code{mysqlcheck --help}, welche davon Ihre Version
+unterstützt.
+
+@table @code
+@item -A, --all-databases
+Prüft alle Datenbanken. Das ist dasselbe wie --databases mit allen
+Datenbanken ausgewählt.
+@item -1, --all-in-1
+Statt für jede Tabelle eine Anfrage auszuführen, alle Anfragen in 1 Anfrage
+pro Datenbank ausführen. Tabellennamen stehen in einer durch Kommas
+getrennten Liste.
+@item -a, --analyze
+Analysiert die angegebene Tabelle.
+@item --auto-repair
+Wenn eine geprüfte Tabelle beschädigt ist, sie automatisch reparieren. Die
+Reparatur wird durchgeführt, nachdem alle Tabellen geprüft wurden, falls
+beschädigte gefunden wurden.
+@item -#, --debug=...
+Debug-Log-Datei ausgeben. Das ist häufig 'd:t:o,filename'.
+@item --character-sets-dir=...
+Verzeichnis, wo Zeichensätze gespeichert sind.
+@item -c, --check
+Tabelle auf Fehler prüfen.
+@item -C, --check-only-changed
+Nur die Tabellen prüfen, die seit der letzten Prüfung geändert wurden oder
+die nicht ordnungsgemäß geschlossen wurden.
+@item --compress
+Kompression im Client-Server-Protokoll benutzen.
+@item -?, --help
+Diese Nachricht ausgeben und beenden.
+@item -B, --databases
+Mehrere Datenbanken prüfen. Beachten Sie den Unterschied im Gebrauch: In
+diesem Fall werden keine Tabellen angegeben. Alle Namensargumente werden
+als Datenbanknamen erachtet.
+@item --default-character-set=...
+Setzt den vorgabemäßigen Zeichensatz.
+@item -F, --fast
+Nur Tabellen prüfen, die nicht ordnungsgemäß geschlossen wurden.
+@item -f, --force
+Fortfahren, auch wenn ein SQL-Fehler auftritt.
+@item -e, --extended
+Wenn Sie diese Option beim Prüfen von Tabellen benutzen, stellt das sicher,
+dass die Tabelle zu 100% konsistent ist, dauert aber sehr lange.
+Wenn Sie diese Option beim Reparieren von Tabellen benutzen, wird eine
+erweiterte Reparatur der Tabelle durchgeführt, was nicht nur sehr lange
+dauern kann, sondern auch viele 'Müll'-Zeilen produzieren kann!
+@item -h, --host=...
+Mit dem angegebenen Host verbinden.
+@item -m, --medium-check
+Schneller als extended-check, findet aber nur 99,99% aller Fehler. Sollte
+in den meisten Fällen genügen.
+@item -o, --optimize
+Tabelle optimieren.
+@item -p, --password[=...]
+Passwort, das bei der Verbindung zum Server benutzt werden soll. Wenn das
+Passwort nicht angegeben wird, wird vom Terminal eine Eingabeaufforderung
+präsentiert.
+@item -P, --port=...
+Portnummer, die für Verbindungen zum Server benutzt werden soll.
+@item -q, --quick
+Wenn Sie diese Option beim Prüfen von Tabellen benutzen, verhindert das,
+dass die Zeilen nach falschen Verknüpfungen (Links) durchgesehen werden
+(gescannt). Das ist die schnellste Prüfmethode.
+Wenn Sie diese Option beim Reparieren von Tabellen benutzen, wird versucht,
+nur den Index-Baum zu reparieren. Das ist die schnellste Reparaturmethode.
+@item -r, --repair
+Kann fast alles reparieren, ausser eindeutige Schlüssel, die nicht
+eindeutig sind.
+@item -s, --silent
+Nur Fehlermeldungen ausgeben.
+@item -S, --socket=...
+Socket-Datei, die für die Verbindung benutzt werden soll.
+@item --tables
+Option --databases (-B) überschreiben.
+@item -u, --user=#
+Benutzer zum Einloggen, falls nicht der aktuelle Unix-Benutzer.
+@item -v, --verbose
+Informationen über die verschiedenen Phasen ausgeben.
+@item -V, --version
+Versionsinformationen ausgeben und beenden.
+@end table
+
+
+@node mysqldump, mysqlhotcopy, Using mysqlcheck, Client-Side Scripts
+@c German node mysqldump
+@subsection mysqldump, Tabellenstrukturen und -daten dumpen
+
+@cindex dumpen, Datenbanken
+@cindex Datenbanken, dumpen
+@cindex Tabellen, dumpen
+@cindex Datensicherung, Datenbanken
+
+@cindex @code{mysqldump}
+Dienstprogramm, um eine Datenbank oder eine Sammlung von Datenbanken zu
+sichern oder um Daten auf einen anderen SQL-Server zu übertragen (nicht
+notwendigerweise ein MySQL-Server). Der Dump enthält SQL-Statements, um
+Datenbanken und Tabellen zu erzeugen und / oder Tabellen mit Daten zu
+füllen.
+
+Wenn Sie eine Datensicherung auf dem Server machen, sollten Sie in Betracht
+ziehen, statt dessen @code{mysqlhotcopy} zu benutzen. @xref{mysqlhotcopy, ,
+@code{mysqlhotcopy}}.
+
+@example
+shell> mysqldump [OPTIONS] datenbank [tabellen]
+OR mysqldump [OPTIONS] --databases [OPTIONS] datenbank1 [datenbank2 datenbank3...]
+OR mysqldump [OPTIONS] --all-databases [OPTIONS]
+@end example
+
+Wenn Sie keine Tabellen angeben oder @code{--databases} bzw.
+@code{--all-databases} benutzen, wird die gesamte Datenbank (bzw. werden
+alle Datenbanken) gedumpt.
+
+Sie erhalten eine Auflistung der Optionen, die Ihre Version von
+@code{mysqldump} unterstützt, indem Sie @code{mysqldump --help} eingeben.
+
+Wenn Sie @code{mysqldump} ohne @code{--quick} oder @code{--opt} ausführen,
+beachten Sie, dass @code{mysqldump} die gesamte Ergebnismenge in den
+Arbeitsspeicher lädt, bevor das Ergebnis gedumpt wird. Das kann zu
+Problemen führen, wenn Sie eine große Datenbank dumpen.
+
+Wenn Sie eine neue Version des @code{mysqldump}-Programms benutzen und
+einen Dump erzeugen, der in einen sehr alten MySQL-Server eingelesen werden
+soll, sollten Sie die @code{--opt}- und @code{-e}-Optionen nicht benutzen.
+
+@code{mysqldump} unterstützt folgende Optionen:
+
+@table @code
+@item --add-locks
+Führt @code{LOCK TABLES} vor und @code{UNLOCK TABLE} nach jedem
+Tabellen-Dump durch (um schnelleres Einfügen in MySQL zu erreichen).
+@item --add-drop-table
+Ein @code{drop table} vor jedem @code{create}-Statement hinzufügen.
+@item -A, --all-databases
+Alle Datenbanken dumpen. Das ist dasselbe wie @code{--databases} mit allen
+Datenbanken ausgewählt.
+@item -a, --all
+Alle MySQL-spezifischen Optionen für @code{create} benutzen.
+@item --allow-keywords
+Erzeugung von Spaltennamen zulassen, die Schlüsselwörter sind. Das
+funktioniert, indem jedem Spaltenname der Tabellenname als Präfix angefügt
+wird.
+@item -c, --complete-insert
+Vollständige @code{insert}-Statements benutzen (mit Spaltennamen).
+@item -C, --compress
+Alle Informationen zwischen Client und Server komprimieren, wenn bei
+Kompression unterstützen.
+@item -B, --databases
+Mehrere Datenbanken prüfen. Beachten Sie den Unterschied im Gebrauch: In
+diesem Fall werden keine Tabellen angegeben. Alle Namensargumente werden
+als Datenbanknamen erachtet. Vor jeder Ausgabe einer neuen Datenbank wird
+@code{USE datenbank;} eingefügt.
+@item --delayed
+Zeilen mit dem @code{INSERT DELAYED}-Befehl einfügen.
+@item -e, --extended-insert
+Die neue mehrzeilige @code{INSERT}-Syntax benutzen. (Ergibt kompaktere und
+schnellere inserts-Statements.)
+@item -#, --debug[=option_string]
+Programmbenutzung tracen (für Debug-Zwecke).
+@item --help
+Hilfetext ausgeben und beenden.
+@item --fields-terminated-by=...
+@itemx --fields-enclosed-by=...
+@itemx --fields-optionally-enclosed-by=...
+@itemx --fields-escaped-by=...
+@itemx --lines-terminated-by=...
+Diese Optionen werden zusammen mit der @code{-T}-Option benutzt und haben
+dieselbe Bedeutung wie die entsprechenden Klauseln für @code{LOAD DATA
+INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.
+@item -F, --flush-logs
+Log-Datei im MySQL-Server zurückschreiben, bevor der Dump durchgeführt
+wird.
+@item -f, --force,
+Fortfahren, selbst wenn beim Dump einer Tabelle ein SQL-Fehler auftritt.
+@item -h, --host=..
+Daten auf dem MySQL-Server auf dem genannten Host dumpen. Der
+vorgabemäßige Host ist @code{localhost}.
+@item -l, --lock-tables.
+Alle Tabellen sperren, bevor mit dem Dump begonnen wird. Die Tabellen
+werden mit @code{READ LOCAL} gesperrt, um gleichzeitiges Einfügen zu
+erlauben (bei @code{MyISAM}-Tabellen).
+@item -n, --no-create-db
+'CREATE DATABASE /*!32312 IF NOT EXISTS*/ datenbank;' wird nicht in die
+Ausgabe gschrieben. Diese Zeile wird ansonsten hinzugefügt, wenn
+--databases oder --all-databases angegeben wurde.
+@item -t, --no-create-info
+Keine Tabellenerzeugungsinformation schreiben (das @code{CREATE
+TABLE}-Statement).
+@item -d, --no-data
+Keine Zeileninformationen für die Tabelle schreiben. Das ist sehr
+nützlich, wenn Sie lediglich einen Dump der Tabellenstruktur erzeugen
+wollen.
+@item --opt
+Dasselbe wie @code{--quick --add-drop-table --add-locks --extended-insert
+--lock-tables}. Das sollte den schnellstmöglichen Dump zum Einlesen in
+einen MySQL-Server ergeben.
+@item -pihr_passwort, --password[=ihr_passwort]
+Das Passwort, das für die Verbindung zum Server benutzt werden soll. Wenn
+Sie keinen @samp{=ihr_passwort}-Teil angeben, zeigt @code{mysqldump} eine
+Eingabeaufforderung für Ihr Passwort.
+@item -P port_num, --port=port_num
+Die TCP/IP-Portnummer, die für die Verbindung zu einem Host benutzt werden
+soll. (Diese wird für Verbindungen zu Hosts ausser @code{localhost}
+benutzt, für den Unix-Sockets benutzt werden.)
+@item -q, --quick
+Anfrage nicht puffern, sondern direkt zu stdout dumpen. Benutzt für die
+Durchführung @code{mysql_use_result()}.
+@item -r, --result-file=...
+Direkte Ausgabe in die angegebene Datei. Diese Ausgabe sollte bei MS-DOS
+benutzt werden, weil sie verhindert, dass das Zeichen für neue Zeile '\n'
+in '\n\r' (new line + carriage return) umgewandelt werden.
+@item -S /pfad/zu/socket, --socket=/pfad/zu/socket
+Die Socket-Datei, die für die Verbindung zu @code{localhost} benutzt werden
+soll (was der vorgabemäßige Host ist).
+@item --tables
+Überschreibt die Option --databases (-B).
+@item -T, --tab=pfad-zu-einem-verzeichnis
+Erzeugt eine @code{tabelle.sql}-Datei, die die SQL-CREATE-Befehle enthält,
+und eine @code{tabelle.txt}-Datei, die die Daten enthält, für jede
+angegebene Tabelle. @strong{HINWEIS}: Das funktioniert nur, wenn
+@code{mysqldump} auf derselben Maschine läuft wie der @code{mysqld}-Daemon.
+Das Format der @code{.txt}-Datei hängt von den @code{--fields-xxx}- und
+@code{--lines--xxx}-Optionen ab.
+@item -u benutzername, --user=benutzername
+Der MySQL-Benutzername, der für die Verbindung zum Server benutzt werden
+soll. Der Vorgabewert ist Ihr Unix-Loginname.
+@item -O var=option, --set-variable var=option
+Den Wert einer Variablen setzen. Die möglichen Werte sind unten aufgeführt.
+@item -v, --verbose
+Geschwätziger Modus. Gibt mehr Informationen darüber aus, was das Programm
+tut.
+@item -V, --version
+Versionsinformationen ausgeben und beenden.
+@item -w, --where='wo-bedingung'
+Nur ausgewählte Datensätze dumpen. Beachten Sie, dass Anführungszeichen
+zwingend erforderlich sind:
+
+@example
+"--where=user='jimf'" "-wuserid>1" "-wuserid<1"
+@end example
+@item -O net_buffer_length=#, where # < 16M
+Beim Erzeugen von mehrzeiligen insert-Statements (wie bei der Option
+@code{--extended-insert} oder @code{--opt}), erzeugt @code{mysqldump}
+Zeilen bis zur Länge von @code{net_buffer_length}. Wenn Sie diesen Wert
+herauf setzen, müssen Sie sicherstellen, dass die
+@code{max_allowed_packet}-Variable im MySQL-Server größer als
+@code{net_buffer_length} ist.
+@end table
+
+Der häufigste Gebrauch von @code{mysqldump} dient wahrscheinlich der
+Herstellung einer Datensicherung ganzer Datenbanken. @xref{Backup}.
+
+@example
+mysqldump --opt datenbank > datensicherung.sql
+@end example
+
+Diese können Sie zurück in MySQL einlesen mit:
+
+@example
+mysql datenbank < datensicherung.sql
+@end example
+
+oder
+
+@example
+mysql -e "source /pfad-zur-datensicherung/datensicherung.sql" datenbank
+@end example
+
+Ausserdem ist es sehr nützlich, um einen anderen MySQL-Server mit
+Informationen aus einer Datenbank zu füllen:
+
+@example
+mysqldump --opt datenbank | mysql ---host=entfernter-host -C datenbank
+@end example
+
+Es ist möglich, mehrere Datenbanken mit einem Befehl zu dumpen:
+
+@example
+mysqldump --databases datenbank1 [datenbank2 datenbank3...] > meine_datenbanken.sql
+@end example
+
+Wenn Sie alle Datenbanken dumpen wollen, benutzen Sie:
+
+@example
+mysqldump --all-databases > alle_datenbanken.sql
+@end example
+
+
+@node mysqlhotcopy, mysqlimport, mysqldump, Client-Side Scripts
+@c German node mysqlhotcopy
+@subsection mysqlhotcopy, MySQL-Datenbanken und Tabellen kopieren
+
+@cindex dumpen, Datenbanken
+@cindex Datenbanken, dumpen
+@cindex Tabellen, dumpen
+@cindex Datensicherung, Datenbanken
+
+@code{mysqlhotcopy} ist a perl Skript that uses @code{LOCK TABLES},
+@code{FLUSH TABLES} und @code{cp} oder @code{scp} to quickly make a backup
+of a Datenbank. It's the fastest way to make a backup of the Datenbank,
+of single Tabellen but it can only be run on the same machine where the
+Datenbankverzeichnisse are.
+
+@example
+mysqlhotcopy datenbank [/pfad/zu/new_Verzeichnis]
+
+mysqlhotcopy datenbank_1 ... datenbank_n /pfad/zu/new_Verzeichnis
+
+mysqlhotcopy datenbank./regex/
+@end example
+
+@code{mysqlhotcopy} unterstützt folgende Optionen:
+
+@table @code
+@item -?, --help
+Hilfe ausgeben und beenden.
+@item -u, --user=#
+Benutzername zum Einloggen.
+@item -p, --password=#
+Passwort für die Verbindung zum Server.
+@item -P, --port=#
+Port zur Verbindung zum lokalen Server.
+@item -S, --socket=#
+Socket zur Verbindung zum lokalen Server.
+@item --allowold
+Nicht abbrechen, wenn das Ziel bereits existiert (sondern in _old umbenennen)
+@item --keepold
+Vorheriges (jetzt umbenanntes) Ziel nach dem Durchführen nicht löschen.
+@item --noindices
+Keine kompletten Index-Dateien in die Kopie einfügen, um die Datensicherung
+kleiner und schneller zu machen. Die Indexe können später mit
+@code{myisamchk -rq.} neu aufgebaut werden.
+@item --method=#
+Kopiermethode (@code{cp} oder @code{scp}).
+@item -q, --quiet
+Keine Meldungen ausgeben, ausser bei Fehlern.
+@item --debug
+Debug anschalten.
+@item -n, --dryrun
+Aktionen berichten, ohne sie auszuführen.
+@item --regexp=#
+Alle Datenbanken mit übereinstimmenden regexp-Namen sichern.
+@item --suffix=#
+Suffix für Namen kopierter Datenbanken.
+@item --checkpoint=#
+Checkpoint-Eingang in angegebene datenbank.tabelle einfügen.
+@item --flushlog
+Log-Dateien zurückschreiben, sobald alle Tabellen gesperrt sind.
+@item --tmpdir=#
+Temporäres Verzeichnis (anstelle von /tmp).
+@end table
+
+Geben Sie @code{perldoc mysqlhotcopy} ein, um eine vollständigere
+Dokumentation von @code{mysqlhotcopy} zu erhalten.
+
+@code{mysqlhotcopy} liest die Gruppen @code{[client]} und
+@code{[mysqlhotcopy]} aus den Optionsdateien.
+
+Damit Sie @code{mysqlhotcopy} ausführen können, benötigen Sie Schreibrechte
+im Datensicherungsverzeichnis, @code{SELECT}-Berechtigung auf die Tabellen,
+die Sie kopieren wollen, und die MySQL-@code{Reload}-Berechtigung (damit
+Sie @code{FLUSH TABLES} ausführen können).
+
+
+@node mysqlimport, mysqlshow, mysqlhotcopy, Client-Side Scripts
+@c German node mysqlimport
+@subsection mysqlimport, Daten aus Textdateien importieren
+
+@cindex importieren, Daten
+@cindex Daten, importieren
+@cindex Dateien, Text-
+@cindex Textdateien, importieren
+@cindex @code{mysqlimport}
+
+@code{mysqlimport} stellt eine Kommandozeilen-Schnittstelle für das
+@code{LOAD DATA INFILE} SQL-Statement zur Verfügung. Die meisten Optionen
+für @code{mysqlimport} entsprechen denselben Optionen für @code{LOAD DATA
+INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.
+
+@code{mysqlimport} wird wie folgt aufgerufen:
+
+@example
+shell> mysqlimport [optionen] datenbank textdatei1 [textdatei2....]
+@end example
+
+Bei jeder Textdatei, die auf der Kommandozeile angegeben wird, entfernt
+@code{mysqlimport} jegliche Erweiterungen vom Dateinamen und benutzt das
+Ergebnis, um festzulegen, in welche Tabelle der Dateiinhalt importiert
+werden soll. Dateien namens @file{patient.txt}, @file{patient.text} und
+@file{patient} beispielsweise würden alle in eine Tabelle namens
+@code{patient} importiert werden.
+
+@code{mysqlimport} unterstützt folgende Optionen:
+
+@table @code
+@item -c, --columns=...
+Diese Option nimmt ein durch Kommas getrennte Auflistung von Feldnamen als
+Argument entgegen. Die Feldliste wird benutzt, um einen korrekten
+@code{LOAD DATA INFILE}-Befehl zu erzeugen, der an MySQL durchgereicht
+wird. @xref{LOAD DATA, , @code{LOAD DATA}}.
+
+@item -C, --compress
+Komprimiert alle Informationen zwischen Client und Server, wenn bei
+Kompression unterstützen.
+
+@item -#, --debug[=option_string]
+Programmbenutzung tracen (zum Debuggen).
+
+@item -d, --delete
+Tabelle leeren, bevor die Textdatei importiert wird.
+
+@item --fields-terminated-by=...
+@itemx --fields-enclosed-by=...
+@itemx --fields-optionally-enclosed-by=...
+@itemx --fields-escaped-by=...
+@itemx --lines-terminated-by=...
+Diese Optionen haben dieselbe Bedeutung wie die entsprechenden Klauseln für
+@code{LOAD DATA INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.
+
+@item -f, --force
+Fehler ignorieren. Wenn beispielsweise eine Tabelle für eine Textdatei
+nicht existiert, mit den verbleibenden Dateien weitermachen. Ohne
+@code{--force} wird @code{mysqlimport} beendet, wenn die Tabelle nicht
+existiert.
+
+@item --help
+Hilfetext ausgeben und beenden.
+
+@item -h host_name, --host=host_name
+Daten in den MySQL-Server auf dem genannten Host importieren. Der
+vorgabemäßige Host ist @code{localhost}.
+
+@item -i, --ignore
+Siehe Beschreibung für die @code{--replace}-Option.
+
+@item -l, --lock-tables
+@strong{ALLE} Tabellen für Schreibvorgänge sperren, bevor irgend welche
+Textdateien verarbeitet werden. Das stellt sich, dass alle Tabellen auf dem
+Server synchronisiert werden.
+
+@item -L, --local
+Liest Eingabedateien vom Client. Vorgabemäßig wird angenommen, dass
+Textdateien auf dem Server liegen, wenn Sie sich über @code{localhost}
+verbinden (was der vorgabemäßige Host ist).
+
+@item -pihr_passwort, --password[=ihr_passwort]
+Das Passwort, das für die Verbindung zum Server benutzt werden soll. Wenn
+Sie keinen @samp{=ihr_passwort}-Teil angeben, zeigt @code{mysqlimport}
+eine Eingabeaufforderung für Ihr Passwort.
+
+@item -P port_num, --port=port_num
+Die TCP/IP-Portnummer, die für die Verbindung zu einem Host benutzt werden
+soll. (Diese wird für Verbindungen zu Hosts ausser @code{localhost}
+benutzt, für den Unix-Sockets benutzt werden.)
+
+@item -r, --replace
+Die @code{--replace}- und @code{--ignore}-Optionen steuern die Handhabung
+von Eingabe-Datensätzen, die bestehende Datensätze auf eindeutigen
+Schlüsseln duplizieren würden. Wenn Sie @code{--replace} angeben, werden
+bestehende Zeilen ersetzt, die denselben eindeutigen Schlüsselwert
+besitzen. Wenn Sie @code{--ignore} angeben, werden Zeilen, die eine
+bestehende Zeile duplizieren würden, übersprungen. Wenn Sie keine der
+beiden Optionen angeben, tritt ein Fehler auf, wenn ein doppelter
+Schlüsseleintrag gefunden wird, und der Rest der Textdatei wird ignoriert.
+
+@item -s, --silent
+Schweigsamer Modus. Ausgaben erfolgen nur, wenn Fehler auftreten.
+
+@item -S /pfad/zu/socket, --socket=/pfad/zu/socket
+Die Socket-Datei, die für die Verbindung zu @code{localhost} benutzt werden
+soll (der der vorgabemäßige Host ist).
+
+@item -u benutzername, --user=benutzername
+Der MySQL-Benutzername, der für die Verbindung zum Server benutzt werden
+soll. Der Vorgabewert ist Ihr Unix-Loginname.
+
+@item -v, --verbose
+Geschwätziger Modus. Mehr Informationen darüber ausgeben, was das Programm
+macht.
+
+@item -V, --version
+Versionsinformationen ausgeben und beenden.
+@end table
+
+Hier ist ein Beispiel für die Benutzung von @code{mysqlimport}:
+
+@example
+$ mysql --version
+mysql Ver 9.33 Distrib 3.22.25, for pc-linux-gnu (i686)
+$ uname -a
+Linux xxx.com 2.2.5-15 #1 Mon Apr 19 22:21:09 EDT 1999 i586 unknown
+$ mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
+$ ed
+a
+100 Max Sydow
+101 Graf Dracula
+.
+w imptest.txt
+32
+q
+$ od -c imptest.txt
+0000000 1 0 0 \t M a x S y d o w \n 1 0
+0000020 1 \t G r a f D r a c u l a \n
+0000040
+$ mysqlimport --local test imptest.txt
+test.imptest: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
+$ mysql -e 'SELECT * FROM imptest' test
++------+---------------+
+| id | n |
++------+---------------+
+| 100 | Max Sydow |
+| 101 | Graf Dracula |
++------+---------------+
+@end example
+
+
+@node mysqlshow, perror, mysqlimport, Client-Side Scripts
+@c German node mysqlshow
+@subsection Datenbanken, Tabellen und Spalten anzeigen
+
+@cindex Datenbanken, anzeigen
+@cindex anzeigen, Datenbankinformationen
+@cindex Tabellen, anzeigen
+@cindex Spalten, anzeigen
+@cindex Anzeigen, Datenbankinformationen
+
+@code{mysqlshow} wird benutzt, um schnell nachzusehen, welche Datenbanken,
+Tabellen und Tabellenspalten es gibt.
+
+Mit dem @code{mysql}-Programm können Sie dieselben Information mit den
+@code{SHOW}-Befehlen erhalten. @xref{SHOW}.
+
+@code{mysqlshow} wird wie folgt aufgerufen:
+
+@example
+shell> mysqlshow [optionen] [datenbank [tabelle [spalte]]]
+@end example
+
+@itemize @bullet
+@item
+Wenn keine Datenbank angegeben wird, werden alle passenden Datenbanken
+gezeigt.
+@item
+Wenn keine Tabelle angegeben wird, werden alle passenden Tabellen in der
+Datenbank gezeigt.
+@item
+Wenn keine Spalte angegeben wird, werden alle passenden Spalten und
+Spaltentypen in der Tabelle gezeigt.
+@end itemize
+
+Beachten Sie, dass Sie in neueren MySQL-Versionen nur die Datenbanken,
+Tabellen und Spalten sehen können, für die Sie irgend welche Berechtigungen
+haben.
+
+Wenn das letzte Argument einen Shell- oder SQL-Platzhalter enthält
+(@code{*}, @code{?}, @code{%} oder @code{_}), wird nur das gezeigt, was dem
+Platzhalter entspricht. Das kann zu Verwirrung führen, wenn Sie Spalten
+einer Tabelle anzeigen, die einen Unterstrich (@code{_}) enthalten, weil
+Ihnen @code{mysqlshow} in diesem Fall nur die Tabellennamen zeigt, die dem
+Muster entsprechen. Das kann leicht durch Hinzufügen eines zusätzlichen
+@code{%} am Ende der Kommandozeile (als separates Argument) behoben werden.
+
+
+@node perror, Batch Commands, mysqlshow, Client-Side Scripts
+@c German node perror
+@subsection perror, Erklärung der Fehler-Codes
+
+@cindex Fehlermeldungen, anzeigen
+@cindex perror
+
+@code{perror} wird benutzt, um Fehlermeldungen auszugeben. @code{perror}
+wird wie folgt aufgerufen:
+
+@example
+shell> perror [optionen] [ERRORCODE [ERRORCODE...]]
+
+For example:
+
+shell> perror 64 79
+Error code 64: Machine ist not on the network
+Error code 79: Can not access a needed shared library
+@end example
+
+@code{perror} wird benutzt, um eine Beschreibung für einen
+Systemfehler-Code anzuzeigen, oder einen Fehler-Code des
+MyISAM/ISAM-Tabellen-Handlers. Die Fehlermeldungen sind hauptsächlich
+abhängig vom Betriebssystem.
+
+
+@node Batch Commands, , perror, Client-Side Scripts
+@c German node Stapelbefehle
+@subsection Wie SQL-Befehle aus einer Textdatei laufen gelassen werden
+
+@c FIX add the 'source' befehl
+
+Der @code{mysql}-Client wird typischerweise interaktiv benutzt, wie folgt:
+
+@example
+shell> mysql datenbank
+@end example
+
+Es ist jedoch möglich, Ihre SQL-Befehle in eine Datei zu schreiben und
+@code{mysql} anzuweisen, ihre Eingaben aus dieser Datei zu lesen. Um das zu
+tun, erzeugen Sie eine Textdatei @file{textdatei}, die die Befehle enthält,
+die Sie ausführen wollen. Dann rufen Sie @code{mysql} wie gezeigt auf:
+
+@example
+shell> mysql datenbank < textdatei
+@end example
+
+Sie können Ihre Textdatei auch mit einem @code{USE datenbank}-Statement
+beginnen lassen. In diesem Fall ist es nicht notwendig, den Datenbanknamen
+auf der Kommandozeile anzugeben:
+
+@example
+shell> mysql < textdatei
+@end example
+
+@xref{Client-Side Scripts}.
+
+
+@node Log Files, Replication, Client-Side Scripts, MySQL Database Administration
+@c German node Log-Dateien
+@section Die MySQL-Log-Dateien
+
+@cindex Log-Dateien
+
+MySQL hat mehrere unterschiedliche Log-Dateien, die Ihnen helfen können
+herauszufinden, was innerhalb @code{mysqld} vor sich geht:
+
+@multitable @columnfractions .3 .7
+@item Die Fehler-Log-Datei @tab Probleme, die beim Start, beim Laufenlassen oder beim Anhalten von @code{mysqld} auftreten.
+@item Die ISAM-Log-Datei @tab Loggt alle Änderungen in ISAM-Tabellen mit. Wird nur benutzt, um den ISAM-Code zu debuggen.
+@item Die Anfragen-Log-Datei @tab Hergestellte Verbindungen und ausgeführte Anfragen.
+@item Die Update-Log-Datei @tab Veraltet: Speichert Statements, die Daten verändern.
+@item Die Binär-Log-Datei @tab Speichert alle Statements, die etwas ändern. Wird auch für Replikation benutzt.
+@item Die Slow-Log-Datei @tab Speichert alle Anfragen, die länger als @code{long_query_time} zur Ausführung benötigten oder keine Indexe benutzten.
+@end multitable
+
+Alle Log-Dateien liegen im @code{mysqld} Daten-Verzeichnis. Sie können
+@code{mysqld} zwingen, die Log-Dateien neu zu öffnen (oder in manchen
+Fällen auf eine neue Log-Datei umzuschalten), indem Sie @code{FLUSH LOGS}
+ausführen. @xref{FLUSH}.
+
+
+
+@menu
+* Error log::
+* Query log::
+* Update log::
+* Binary log::
+* Slow query log::
+* Log file maintenance::
+@end menu
+
+@node Error log, Query log, Log Files, Log Files
+@c German node Fehler-Log-Datei
+@subsection Die Fehler-Log-Datei
+
+@code{mysqld} schreibt alle Fehler nach stderr, die das
+@code{safe_mysqld}-Skript in eine Datei namens @code{'hostname'.err}
+umleitet. (Unter Windows schreibt @code{mysqld} direkt in die Datei
+@file{\mysql\data\mysql.err}.)
+
+Diese enthält Informationen, wann @code{mysqld} gestartet und angehalten
+wurde und zusätzlich jeden kritischen Fehler, der während der Laufzeit
+passierte. Wenn @code{mysqld} unerwartet stirbt und @code{safe_mysqld} ihn
+neu starten muss, schreibt @code{safe_mysqld} eine @code{restarted
+mysqld}-Zeile in diese Datei. Diese Log-Datei enthält auch Warnungen, wenn
+@code{mysqld} eine Tabelle bemerkt, die automatisch geprüft oder repariert
+werden muss.
+
+Auf manchen Betriebssystemen enthält die Fehler-Log-Datei einen
+Stack-Trace, wo @code{mysqld} starb. Dieser kann benutzt werden, um
+herauszufinden, wo @code{mysqld} starb. @xref{Using stack trace}.
+
+
+@node Query log, Update log, Error log, Log Files
+@c German node Anfragen-Log-Datei
+@subsection Die allgemeine Anfragen-Log-Datei
+
+@cindex Anfragen-Log-Datei
+@cindex Dateien, Anfragen-Log-Datei
+
+Wenn Sie wissen wollen, was innerhalb @code{mysqld} geschieht, sollten Sie
+ihn mit @code{--log[=file]} starten. Diese Option loggt alle Verbindungen
+und Anfragen in die Log-Datei (vorgabemäßig @file{'hostname'.log}
+benannt). Diese Log-Datei kann sehr nützlich sein, wenn Sie einen Fehler in
+einem Client vermuten und wissen wollen, was genau @code{mysqld} sich bei
+dem dachte, was es vom Client geschickt bekam.
+
+Vorgabemäßig startet das @code{mysql.server}-Skript den MySQL-Server mit
+der @code{-l}-Option. Wenn Sie bessere Performance brauchen, wenn Sie MySQL
+in einer Produktionsumgebung starten, können Sie die @code{-l}-Option aus
+@code{mysql.server} entfernen oder sie zu @code{--log-binary} ändern.
+
+Die Einträge in diese Log-Datei werden geschrieben, wenn @code{mysqld} die
+Anfragen erhält. Die Reihenfolge kann vor derjenigen abweichen, in der die
+Statements ausgeführt werden. Das steht im Gegensatz zur Update-Log-Datei
+und zur Binär-Log-Datei, bei denen geschrieben wird, nachdem die Anfrage
+ausgeführt wurde, aber bevor irgend welche Sperren aufgehoben werden.
+
+
+@node Update log, Binary log, Query log, Log Files
+@c German node Update-Log-Datei
+@subsection Die Update-Log-Datei
+
+@cindex Update-Log-Datei
+@cindex Dateien, Update-Log-Datei
+
+@strong{HINWEIS}: Die Update-Log-Datei wird durch die binäre Log-Datei
+ersetzt. @xref{Binary log}. Mit dieser können Sie alles machen, was
+Sie mit der Update-Log-Datei machen können.
+
+Wenn er mit der @code{--log-update[=datei]}-Option gestartet wird, schreibt
+@code{mysqld} eine Log-Datei, die alle SQL-Befehle enthält, die Daten
+aktualisieren. Wenn kein Dateiname angegeben wird, ist die Vorgabe der Name
+der Host-Maschine. Wenn ein Dateiname angegeben wird, der aber keine
+Pfadangabe enthält, wird die Datei ins Daten-Verzeichnis geschrieben. Wenn
+@file{datei} keine Erweiterung hat, erzeugt @code{mysqld} eine Log-Datei,
+die er wie folgt benennt: @file{datei.###}, wobei @code{###} eine Zahl ist,
+die jedes Mal hochgezählt wird, wenn Sie @code{mysqladmin refresh} oder
+@code{mysqladmin flush-logs} oder das @code{FLUSH LOGS}-Statement
+ausführen, oder wenn Sie den Server neu starten.
+
+@strong{HINWEIS:} Damit das dargestellte Schema funktioniert, sollten Sie
+NICHT eigene Dateien mit demselben Dateinamen wie die Update-Log-Datei plus
+Erweiterungen, die als die hochgezählte Zahl betrachtet werden könnten, im
+Verzeichnis anlegen, das von der Update-Log-Datei benutzt wird!
+
+Wenn Sie die @code{--log} oder @code{-l}-Optionen benutzen, schreibt
+@code{mysqld} eine allgemeine Log-Datei mit dem Dateinamen
+@file{hostname.log}. Neustarts und Refresh-Operationen führen dann nicht
+dazu, dass eine neue Log-Datei erzeugt wird (obwohl diese geschlossen und
+wieder geöffnet wird). In diesem Fall können Sie sie (unter Unix) wie folgt
+kopieren:
+
+@example
+mv hostname.log hostname-old.log
+mysqladmin flush-logs
+cp hostname-old.log ins-datensicherungs-verzeichnis
+rm hostname-old.log
+@end example
+
+Das Mitloggen mittels der Update-Log-Datei ist clever, weil es nur
+Statements loggt, die tatsächlich Daten aktualisieren. Wenn ein
+@code{UPDATE} oder ein @code{DELETE} mit einem @code{WHERE} keine passenden
+Zeilen findet, wird nichts in die Log-Datei geschrieben. Es werden sogar
+@code{UPDATE}-Statements übersprungen, die eine Spalte auf einen Wert
+setzen, die sie bereits hat.
+
+Das Schreiben in die Update-Log-Datei wird unmittelbar durchgeführt,
+nachdem eine Anfrage fertig ist, aber bevor irgend welche Sperren
+aufgehoben sind oder irgendein Commit durchgeführt wurde. Das stellt
+sicher, dass die Log-Datei stets in der Reihenfolge der Ausführung
+mitschreibt.
+
+Wenn Sie eine Datenbank von Update-Log-Datei-Dateien aktualisieren wollen,
+könnten Sie folgendes tun (angenommen, Ihre Update-Log-Dateien haben Namen
+der Form @file{datei.###}):
+
+@example
+shell> ls -1 -t -r datei.[0-9]* | xargs cat | mysql
+@end example
+
+@code{ls} wird benutzt, um alle Log-Dateien in der richtigen Reihenfolge zu
+erhalten.
+
+Das ist nützlich, wenn Sie Datensicherungsdateien nach einem Absturz
+zurückspielen müssen und die Aktualisierungen neu ausführen wollen, die
+zwischen der Zeit der Datensicherung und dem Absturz lagen.
+
+
+@node Binary log, Slow query log, Update log, Log Files
+@c German node Binär-Log-Datei
+@subsection Die binäre Update-Log-Datei
+
+@cindex Binär-Log-Datei
+@cindex Dateien, Binär-Log-Datei
+
+In Zukunft wird die Binär-Log-Datei die Update-Log-Datei ersetzen, daher
+empfehlen wir, dass Sie so bald wie möglich zu diesem Log-Format wechseln!
+
+Die Binär-Log-Datei enthält alle Informationen, die im Update-Log verfügbar
+sind, in einem effizienteren Format. Sie enthält ausserdem Informationen
+darüber, wie lange jede Anfrage brauchte, die die Datenbank aktualisierte.
+
+Die Binär-Log-Datei wird auch benutzt, wenn Sie einen Slave von einem
+Master replizieren. @xref{Replication}.
+
+Mit der @code{--log-bin[=datei]}-Option gestartet, schreibt @code{mysqld}
+eine Log-Datei, die alle SQL-Befehle enthält, die Daten aktualisieren. Wenn
+kein Dateiname angegeben wird, ist die Vorgabe der Name der Host-Machine,
+gefolgt von @code{-bin}. Wenn der Dateiname angegeben wird, aber keine
+Pfadangabe enthält, wird die Datei ins Daten-Verzeichnis geschrieben.
+
+Sie können folgende Optionen für @code{mysqld} benutzen, um zu
+beeinflussen, was in die Binär-Log-Datei geschrieben wird:
+
+@multitable @columnfractions .4 .6
+@item @code{binlog-do-db=datenbank} @tab
+Weist den Master an, Aktualisierungen für die angegebene Datenbank zu
+loggen und alle anderen, nicht explizit erwähnten, auszuschließen.
+(Beispiel: @code{binlog-do-db=eine_datenbank})
+
+@item @code{binlog-ignore-db=datenbank} @tab
+Weist den Master an, Aktualisierungen für die angegebene Datenbank nicht in
+die Binär-Log-Datei zu loggen (Beispiel:
+@code{binlog-ignore-db=eine_datenbank}).
+@end multitable
+
+@code{mysqld} hängt dem Binär-Log-Datei-Dateinamen eine Erweiterung an, die
+eine Zahl ist, die jedes Mal heraufgezählt wird, wenn Sie @code{mysqladmin
+refresh}, @code{mysqladmin flush-logs} oder ein @code{FLUSH LOGS}-Statement
+ausführen oder den Server neu starten.
+
+Damit Sie feststellen können, welche verschiedenen Binär-Log-Datei-Dateien
+benutzt wurden, erzeugt @code{mysqld} auch eine Binär-Log-Index-Datei, die
+die Namen aller benutzten Binär-Log-Datei-Dateien enthält. Vorgabemäßig
+hat diese denselben Namen wie die Binär-Log-Datei, mit der Erweiterung
+@code{'.index'}. Sie können den Namen der Binär-Log-Index-Datei mit der
+@code{--log-bin-index=[filename]}-Option ändern.
+
+Wenn Sie Replikation benutzen, sollten Sie keine alten Binär-Log-Dateien
+löschen, bis Sie sicher sind, dass kein Slave sie jemals wieder benötigen
+wird. Eine Art, das zu tun, ist, einmal pro Tag @code{mysqladmin
+flush-logs} auszuführen, und danach alle Logs zu entfernen, die älter als 3
+Tage sind.
+
+Sie können die Binär-Log-Datei mit dem @code{mysqlbinlog}-Befehl
+untersuchen. Beispielsweise können Sie einen MySQL-Server wie folgt aus der
+Binär-Log-Datei aktualisieren:
+
+@example
+mysqlbinlog log-file | mysql -h server_name
+@end example
+
+Sie können auch das @code{mysqlbinlog}-Programm benutzen, um die
+Binär-Log-Datei direkt von einem entfernten MySQL-Server zu lesen!
+
+@code{mysqlbinlog --help} gibt Ihnen weitere Informationen zur Benutzung
+dieses Programms.
+
+Wenn Sie @code{BEGIN [WORK]} oder @code{SET AUTOCOMMIT=0} verwenden, müssen
+Sie die MySQL-Binär-Log-Datei für Datensicherungen anstelle der alten
+Update-Log-Datei benutzen.
+
+Das Loggen in die Binär-Log-Datei wird unmittelbar nach jeder Anfrage
+geschrieben, aber bevor irgend welche Sperren aufgehoben wurden oder irgend
+ein Commit durchgeführt wurde. Das stellt sicher, dass die Log-Datei in der
+Reihenfolge der Ausführung mitschreibt.
+
+Alle Aktualisierungen (@code{UPDATE}, @code{DELETE} oder @code{INSERT}),
+die eine transaktionale Tabelle (like BDB-Tabellen) ändern, werden bis zu
+einem @code{COMMIT} gecachet. Jegliche Aktualisierungen auf eine nicht
+transaktionale Tabelle werden sofort in der Binär-Log-Datei gespeichert.
+Jedem Thread wird beim Start ein Puffer der Größe @code{binlog_cache_size}
+für die Pufferung von Anfragen zugewiesen. Wenn eine Anfrage größer als
+dieser ist, öffnet der Thread eine temporäre Datei, um den größeren Cache
+zu handhaben. Die temporäre Datei wird gelöscht, wenn der Thread beendet
+wird.
+
+@code{max_binlog_cache_size} kann dazu benutzt werden, um die gesamte
+benutzte Größe zu begrenzen, und um eine Anfrage aus mehreren
+Transaktionen zu cachen.
+
+Wenn Sie die Update- oder Binär-Log-Datei benutzen, funktionieren
+gleichzeitige Einfügeoperationen nicht im Zusammenhang mit @code{CREATE ...
+INSERT} und @code{INSERT ... SELECT}. Damit stellen Sie sicher, dass Sie
+eine exakte Kopie Ihrer Tabellen wieder herstellen können, indem Sie die
+Log-Datei auf eine Datensicherung anwenden.
+
+
+@node Slow query log, Log file maintenance, Binary log, Log Files
+@c German node Langsame-Anfragen-Log-Datei
+@subsection Die Anfragen-Log-Datei für langsame Anfragen
+
+@cindex Langsame-Anfragen-Log-Datei
+@cindex Dateien, Langsame-Anfragen-Log-Datei
+
+Mit der @code{--log-slow-queries[=datei]}-Option gestartet schreibt
+@code{mysqld} eine Log-Datei, die alle SQL-Befehle enthält, die länger als
+@code{long_query_time} zur Ausführung brauchten. Die Zeit, um die
+anfänglichen Tabellensperren zu erhalten, wird nicht zur Ausführungszeit
+hinzugezählt.
+
+Anfragen-Log-Datei für langsame Anfragen wird geschrieben, nachdem jede
+Anfrage ausgeführt wurde und nachdem alle Sperren aufgehoben wurden. Das
+kann von der Reihenfolge abweichen, in der die Statements ausgeführt
+wurden.
+
+Wenn kein Dateiname angegeben wird, ist die Vorgabe der Name der
+Host-Maschine mit dem Suffix @code{-slow.log}. Wenn ein Dateiname angegeben
+wird, der aber keine Pfadangabe enthält, wird die Datei ins Daten-Verzeichnis geschrieben.
+
+Die Anfragen-Log-Datei für langsame Anfragen kann benutzt werden, um
+Anfragen zu finden, die für die Ausführung lange Zeit benötigen und daher
+Kandidaten für Optimierungen sind, was bei einer großen Log-Datei
+allerdings eine schwierige Aufgabe werden kann. Sie können die
+Anfragen-Log-Datei für langsame Anfragen durch den
+@code{mysqldumpslow}-Befehl durchschleifen (pipen), um eine Zusammenfassung
+der Anfragen zu erhalten, die in der Log-Datei erscheinen.
+
+Wenn Sie @code{--log-long-format} benutzen, erscheinen auch Anfragen, die
+keine Indexe benutzen. @xref{Command-line options}.
+
+
+@node Log file maintenance, , Slow query log, Log Files
+@c German node Log-Datei-Wartung
+@subsection Wartung und Pflege der Log-Dateien
+
+@cindex Dateien, Log-Dateien
+@cindex Wartung, Log-Dateien
+@cindex Log-Dateien, Wartung
+
+MySQL hat viele Log-Dateien, die es leicht machen festzustellen, was vor
+sich geht. @xref{Log Files}. Von Zeit zu Zeit jedoch muss man hinter
+@code{MySQL} saubermachen, damit die Log-Dateien nicht zu viel
+Festplattenplatz in Anspruch nehmen.
+
+Wenn Sie MySQL mit Log-Dateien benutzen, werden Sie von Zeit zu Zeit alte
+Log-Dateien entfernen wollen und MySQL mitteilen, in neue Dateien zu
+loggen. @xref{Backup}.
+
+Bei einer Linux-(@code{RedHat})-Installation können Sie hierfür das
+@code{mysql-log-rotate}-Skript benutzen. Wenn Sie MySQL von einer
+RPM-Distribution installiert haben, sollte das Skript automatisch
+installiert worden sein. Beachten Sie, dass Sie damit vorsichtig umgehen
+sollten, wenn Sie die Log-Datei für Replikation benutzen!
+
+Auf anderen Systemen müssen Sie selbst ein kurzes Skript installieren, dass
+Sie von @code{cron} starten können, um Log-Dateien zu handhaben.
+
+Sie können MySQL zwingen, mit neuen Log-Dateien zu starten, indem Sie
+@code{mysqladmin flush-logs} oder den SQL-Befehl @code{FLUSH LOGS}
+benutzen. Wenn Sie MySQL-Version 3.21 benutzen, müssen Sie @code{mysqladmin
+refresh} benutzen.
+
+Der obige Befehl macht folgendes:
+
+@itemize @bullet
+@item
+Wenn standardmäßiges Loggen (@code{--log}) oder Loggen langsamer Anfragen
+(@code{--log-slow-queries}) benutzt wird, wird die Log-Datei geschlossen
+und wieder geöffnet (@file{mysql.log} und @file{`hostname`-slow.log} als
+Vorgabe).
+@item
+Wenn Update-Logging (@code{--log-update}) benutzt wird, wird die
+Update-Log-Datei geschlossen und eine neue Log-Datei mit einer höheren
+Log-Zahl geöffnet.
+@end itemize
+
+Wenn Sie nur eine Update-Log-Datei benutzen, müssen Sie die Log-Dateien nur
+auf Platte zurückschreiben (flush) und dann die alten
+Update-Log-Datei-Dateien zu einer Datensicherungsdatei verschieben. Wenn
+Sie normales Loggen benutzen, können Sie etwas wie das Folgende tun:
+
+@example
+shell> cd mysql-data-verzeichnis
+shell> mv mysql.log mysql.old
+shell> mysqladmin flush-logs
+@end example
+
+Und dann eine Datensicherung nehmen und @file{mysql.old} entfernen.
+
+
+@node Replication, , Log Files, MySQL Database Administration
+@c German node Replikation
+@section Replikation bei MySQL
+
+@cindex Replikation
+@cindex erhöhen, Geschwindigkeit
+@cindex Geschwindigkeit, erhöhen
+@cindex Datenbanken, replizieren
+
+
+Dieses Kapitel beschreibt die verschiedenen Replikationsfeatures in MySQL.
+Es dient als Referenz für die Optionen, die bei Replikation verfügbar sind.
+Sie erhalten eine Einführung in die Replikation und lernen, wie Sie sie
+implementieren. Am Ende des Kapitels werden einige häufige gestellte Fragen
+und die dazugehörigen Antworten aufgelistet sowie Beschreibungen der
+Probleme und wie man sie löst.
+
+
+@menu
+* Replication Intro::
+* Replication Implementation::
+* Replication HOWTO::
+* Replication Features::
+* Replication Options::
+* Replication SQL::
+* Replication FAQ::
+* Replication Problems::
+@end menu
+
+@node Replication Intro, Replication Implementation, Replication, Replication
+@c German node Einführung in die Replikation
+@subsection Einführung in die Replikation
+
+Einweg-Replikation wird benutzt, um sowohl Stabilität als auch
+Geschwindigkeit zu steigern. Was Stabilität betrifft, haben Sie zwei
+Möglichkeiten und können zur Möglichkeit der Datensicherung zurückkehren,
+wenn Sie Probleme mit dem Master haben. Die Geschwindigkeitssteigerung wird
+dadurch erreicht, dass ein Teil der Anfragen, die nichts aktualisieren, an
+den Replikationsserver geschickt werden. Das funktioniert naturgemäß nur
+dann, wenn Anfragen, die nichts aktualisieren, überwiegen, aber das ist der
+Normalfall.
+
+@c German FIX changes @xref to @pxref (because it's in parenthesis).
+Ab Version 3.23.15 unterstützt MySQL intern Einweg-Replikation. Ein Server
+agiert als Master, der andere als Slave. Beachten Sie, dass ein Server
+beide Rolle - als Master und als Slave - in einem Paar spielen kann. Der
+Master hält eine Binär-Log-Datei der Aktualisierungen vor
+(@pxref{Binary log}) sowie eine Index-Datei für Binär-Log-Dateien, um
+hinsichtlich der Log-Rotation auf dem Laufenden zu bleiben. Der Slave
+informiert den Master beim Verbinden darüber, wo er seit der letzten
+erfolgreich durchgeführten Aktualisierung aufgehört hat, schließt zu den
+Aktualisierungen auf, blockiert danach und wartet darauf, dass ihn der
+Master über neue Aktualisierungen informiert.
+
+Beachten Sie, dass alle Aktualisierungen auf eine Datenbank, die repliziert
+wird, durch den Master durchgeführt werden sollten!
+
+Ein weiterer Vorteil von Replikation ist, dass man permanente (live)
+Datensicherungen vom System erhält, wenn man die Datensicherung auf dem
+Slave durchführt statt auf dem Master. @xref{Backup}.
+
+
+@node Replication Implementation, Replication HOWTO, Replication Intro, Replication
+@c German node Replikationsimplementation
+@subsection Replikationsimplementation
+
+@cindex Master-Slave-Einrichtung
+
+@c German FIX changes @xref to @pxref (because it's in parenthesis).
+MySQL-Replikation basiert darauf, dass der Server alle Änderungen Ihrer
+Datenbank im Binär-Log verfolgt (Updates, Deletes usw.)
+(@pxref{Binary log}) und der oder die Slave-Server die gespeicherten
+Anfragen aus der Binär-Log-Datei des Masters lesen, so dass der Slave
+dieselben Anfragen auf seine Kopie der Daten ausführen kann.
+
+Es ist @strong{sehr wichtig} sich klarzumachen, dass die Binär-Log-Datei
+schlicht eine Aufzeichnung ist, die ab einem festen Zeitpunkt an startet
+(ab dem Moment, wo Sie Binär-Loggen starten). Alle Slaves, die Sie
+aufsetzen, benötigen Kopien aller Daten vom Master, wie Sie zu dem
+Zeitpunkt existierten, als Binär-Loggen auf dem Master aktiviert wurde.
+Wenn Sie Ihre Slaves mit Daten starten, die nicht mit dem übereinstimmen,
+was auf dem Master war, @strong{als die Binär-Log-Datei gestartet wurde},
+funktionieren Ihre Slaves womöglich nicht richtig.
+
+Eine zukünftige Version (4.0) von MySQL wird die Notwendigkeit beseitigen,
+(eventuell große) Schnappschüsse von Daten für neue Slaves vorzuhalten,
+die Sie über die Live-Datensicherungs-Funktionalität aufsetzen wollen,
+wobei kein Sperren (Locking) erforderlich ist. Zu dieser Zeit ist es jedoch
+notwendig, alle Schreibzugriffe entweder mit einer globalen Lese-Sperre
+oder durch das Herunterfahren des Masters zu blockieren, während man einen
+Schnappschuss anlegt.
+
+Sobald ein Slave korrekt konfiguriert ist und läuft, verbindet er sich
+einfach mit dem Master und wartet darauf, dass Aktualisierung ausgeführt
+werden. Wenn der Master abgeschaltet wird oder der Slave die Verbindung zum
+Master verliert, versucht er alle @code{master-connect-retry} Sekunden,
+sich neu zu verbinden, bis er sich neu verbinden kann, und nimmt dann das
+Warten auf Aktualisierungen wieder auf.
+
+Jeder Slave achtet darauf, wo er aufgehört hat. Der Master-Server weiß
+nicht, wie viele Slaves es gibt oder welche zu einem gegebenen Zeitpunkt
+auf aktuellem Stand sind.
+
+Der nächste Abschnitt erläutert den Master-Slave-Einrichtungsprozess
+detaillierter.
+
+
+@node Replication HOWTO, Replication Features, Replication Implementation, Replication
+@c German node Wie man Replikation aufsetzt
+@subsection Wie man Replikation aufsetzt
+
+Unten findet sich eine kurze Beschreibung, wie Sie komplette Replikation
+auf Ihrem aktuellen MySQL-Server einrichten können. Es wird angenommen,
+dass Sie alle Ihre Datenbanken replizieren wollen und bislang Replikation
+noch nicht konfiguriert haben. Sie müssen Ihren Master-Server kurz herunter
+fahren, um die unten stehenden Schritte fertigzustellen.
+
+@enumerate
+@item
+Stellen Sie sicher, dass Sie eine aktuelle Version von MySQL auf dem Master
+und dem Slave oder den Slaves haben.
+
+Benutzen Sie Version 3.23.29 oder höher. Vorherige Releases benutzten ein
+anderes Binär-Log-Format und hatten Bugs, die in neueren Releases behoben
+wurden. Bitte berichten Sie keine Bugs, bevor Sie bestätigen können, dass
+das Problem im neuesten Release beobachtet werden kann.
+
+@item
+Richten Sie einen speziellen Replikationsbenutzer auf dem Master mit der
+@code{FILE}-Berechtigung und Berechtigungen, sich von allen Slaves aus zu
+verbinden, ein. Wenn der Benutzer ausschließlich Replikation durchführt
+(was empfohlen wird), müssen Sie ihm keine zusätzlichen Berechtigungen
+geben.
+
+Erzeugen Sie zum Beispiel einen Benutzer namens @code{repl}, der auf Ihren
+Master von jedem Host aus zugreifen kann, mit folgendem Befehl:
+
+@example
+GRANT FILE ON *.* TO repl@@"%" IDENTIFIED BY 'passwort';
+@end example
+
+@item
+Fahren Sie den MySQL-Master herunter:
+
+@example
+mysqladmin -u root -ppasswort shutdown
+@end example
+
+@item
+Machen Sie einen Schnappschuss aller Daten auf Ihrem Master-Server.
+
+Die einfachste Art, das (unter Unix) zu tun, ist, einfach @strong{tar} zu
+benutzen, um ein Archiv Ihre gesamten Daten-Verzeichnisses zu erzeugen. Der
+genaue Speicherort Ihres Daten-Verzeichnisses hängt von Ihrer Installation
+ab.
+
+@example
+tar -cvf /tmp/mysql-snapshot.tar /pfad/zu/data-dir
+@end example
+
+Windows-Benutzer können WinZip oder ähnliche Software benutzen, um ein
+Archiv des Daten-Verzeichnisses anzulegen.
+
+@item
+In der Datei @code{my.cnf} für den Master fügen Sie @code{log-bin} und
+@code{server-id=eindeutige_nummer} zum @code{[mysqld]}-Abschnitt und hinzu
+und starten Sie den Server neu. Es ist sehr wichtig, dass die ID auf dem
+Slave sich von der ID auf dem Master unterscheidet. Denken Sie sich
+@code{server-id} als etwas, dass einer IP-Adresse ähnlich ist - es
+identifiziert in der Gemeinschaft der Replikationspartner die
+Server-Instanz eindeutig.
+
+@example
+[mysqld]
+log-bin
+server-id=1
+@end example
+
+@item
+Starten Sie den MySQL-Master neu.
+
+@item
+Fügen Sie auf dem Slave oder den Slaves folgendes zur Datei
+@code{my.cnf} hinzu:
+
+@example
+master-host=hostname_des_masters
+master-user=replikations_benutzername
+master-password=replikations_benutzerpasswort
+master-port=TCP/IP-Port_für_master>
+server-id=eine_eindeutige_nummer_zwischen_2_und_2^32-1
+@end example
+
+Ersetzen Sie die Beispielwerte durch etwas, was für Ihr System stimmig ist.
+
+@code{server-id} muss für jeden Partner, der an Replikation teilnimmt,
+unterschiedlich sein. Wenn Sie keine server-id angeben, wird sie auf 1
+gesetzt, falls Sie @code{master-host} nicht definiert haben, ansonsten wird
+sie auf 2 gesetzt. Beachten Sie für den Fall, dass sie @code{server-id}
+weglassen, dass der Master Verbindungen von allen Slaves verweigert und die
+Slaves verweigern werden, sich mit dem Master zu verbinden. Daher ist das
+Weglassen der @code{server-id} nur dann eine gute Idee, wenn Sie es nur für
+Datensicherungen mit einer Binär-Log-Datei verwenden.
+
+
+@item
+Kopieren Sie die Schnappschuss-Daten in Ihr Daten-Verzeichnis auf Ihrem
+Slave oder Ihren Slaves. Stellen Sie sicher, dass die Berechtigungen auf
+die Dateien und Verzeichnisse korrekt sind. Der Benutzer, unter dem MySQL
+läuft, muss in der Lage sein, sie zu lesen und zu schreiben, genau wie auf
+dem Master.
+
+@item Starten Sie den Slave oder die Slaves neu.
+
+@end enumerate
+
+Nachdem Sie das Obige durchgeführt haben, sollten sich die Slaves mit dem
+Master verbinden können und alle Aktualisierungen mitbekommen, die nach der
+Aufnahme des Schnappschusses passieren.
+
+
+Wenn Sie vergessen haben, die @code{server-id} für den Slave zu setzen,
+erhalten Sie folgenden Fehler in der Fehler-Log-Datei:
+
+@example
+Warning: one should set server_id to a non-0 value if master_host ist set.
+The server will not act as a slave.
+@end example
+
+Wenn Sie vergessen haben, selbiges für den Master zu machen, sind die
+Slaves nicht in der Lage, sich mit dem Master zu verbinden.
+
+Wenn ein Slave aus irgend welchen Gründen nicht in der Lage ist zu
+replizieren, finden Sie Fehlermeldungen in der Fehler-Log-Datei auf dem
+Slave.
+
+Sobald ein Slave repliziert, finden Sie eine Datei namens
+@code{master.info} im selben Verzeichnis, wo auch Ihre Fehler-Log-Datei
+liegt. Die @code{master.info}-Datei wird vom Slave benutzt, um auf dem
+Laufenden zu bleiben, wie viel der Binär-Log-Datei des Masters er bereits
+abgearbeitet hat. Sie sollten die Datei @strong{NICHT} entfernen oder
+editieren, es sei denn, Sie wissen genau, was Sie tun. Selbst in diesem
+Fall sollten Sie vorzugsweise den @code{CHANGE MASTER TO}-Befehl benutzen.
+
+
+
+
+@node Replication Features, Replication Options, Replication HOWTO, Replication
+@c German node Replikationsfeatures
+@subsection Replikationsfeatures und bekannte Probleme
+
+@cindex Optionen, Replikation
+@cindex @code{my.cnf}-Datei
+@cindex Dateien,@code{my.cnf}
+
+Unten steht eine Erläuterung dessen, was unterstützt wird und was nicht:
+
+@itemize @bullet
+@item
+Replikation läuft korrekt mit @code{AUTO_INCREMENT}-,
+@code{LAST_INSERT_ID}- und @code{TIMESTAMP}-Werten.
+@item
+@code{RAND()} bei Updates repliziert nicht korrekt. Benutzen Sie
+@code{RAND(ein_nicht_zufalls_ausdruck)}, wenn Sie Updates mit
+@code{RAND()} replizieren. Sie können zum Beispiel @code{UNIX_TIMESTAMP()}
+als Argument für @code{RAND()} benutzen.
+@item
+Sie müssen auf Master und Slave denselben Zeichensatz
+(@code{--default-character-set}) benutzen. Wenn nicht, erhalten Sie
+eventuell Fehler wegen doppelter Schlüsseleinträge (duplicate key) auf dem
+Slave, weil ein Schlüssel, der auf dem Master als eindeutig betrachtet
+wird, das in einem anderen Zeichensatz eventuell nicht ist.
+@item
+@code{LOAD DATA INFILE} wird korrekt gehandhabt, solange die Datei zur Zeit
+der Update-Ausführung noch auf dem Master-Server liegt. @code{LOAD LOCAL
+DATA INFILE} wird übersprungen.
+@item
+Aktualisierungsanfragen, die Benutzer-Variablen benutzen, sind (noch) nicht
+replikationssicher.
+@item
+@code{FLUSH}-Befehle werden nicht in der Binär-Log-Datei gespeichert und
+werden deswegen nicht auf den Slaves repliziert. Das stellt normalerweise
+kein Problem dar, weil @code{FLUSH} nichts ändert. In Bezug auf die
+@code{MySQL}-Berechtigungstabellen heißt das jedoch, dass Sie bei direkten
+Änderungen in diesen Tabellen ohne Benutzung des @code{GRANT}-Statements
+und der anschließenden Replikation der
+@code{MySQL}-Berechtigungs-Datenbank auf den Slaves @code{FLUSH PRIVILEGES}
+ausführen müssen, damit die neuen Berechtigungen wirksam werden.
+@item
+Temporäre Tabellen werden ab Version 3.23.29 korrekt repliziert,
+ausgenommen im Fall, dass Sie den Slave-Server schließen (nicht nur den
+Slave-Thread), Sie noch einige temporäre Tabellen offen haben und diese bei
+nachfolgenden Aktualisierungen benutzt werden. Um mit diesem Problem fertig
+zu werden, schließen Sie den Slave mit @code{SLAVE STOP} und prüfen dann
+die @code{Slave_open_temp_tables}-Variable, um zu sehen, ob Sie 0 ist. Dann
+führen Sie @code{mysqladmin shutdown} aus. Wenn die Variable nicht 0 ist,
+starten Sie den Slave-Thread neu mit @code{SLAVE START} und probieren es
+noch einmal. Zukünftig (ab Version 4.0) wird es eine sauberere Lösung
+geben.
+In früheren Versionen wurden temporäre Tabellen nicht korrekt repliziert.
+Wir empfehlen, dass Sie entweder auf eine neuere Version aktualisieren oder
+vor allen Anfragen mit temporären Tabellen @code{SET SQL_LOG_BIN=0} auf
+alle Clients ausführen.
+@item
+MySQL unterstütz nur einen Master und viele Slaves. In Version 4.x wird ein
+Abstimmungsalgorithmus eingebaut, der automatisch den Master umschaltet,
+wenn etwas mit dem aktuellen Master schief geht. Ausserdem werden wir
+'Agenten'-Prozesse einführen, die bei der Lastverteilung helfen, indem sie
+SELECT-Anfragen an verschiedene Slaves senden.
+@item
+Ab Version 3.23.26 ist es sicher, Server in einer zirkulären
+Master-Slave-Beziehung mit angeschaltetem @code{log-slave-updates} zu
+verbinden. Beachten Sie jedoch, dass bei dieser Art von Einrichtung viele
+Anfrage nicht richtig funktionieren, es sei denn, Ihr Client-Code ist so
+geschrieben, dass er sich um mögliche Probleme kümmert, die durch
+Aktualisierungen auftreten können, die in unterschiedlicher Reihenfolge auf
+verschiedenen Servern laufen.
+
+Das bedeutet, dass Sie eine Einrichtung wie die folgende machen können:
+
+@example
+A -> B -> C -> A
+@end example
+
+Diese Einrichtung funktioniert nur dann, wenn Sie ausschließlich
+Aktualisierungen ausführen, die nicht zwischen den Tabellen zu Konflikten
+führen. Mit anderen Worten, wenn Sie Daten in A und C einfügen, sollten Sie
+nie eine Zeile in A einfügen, die zu einem Konflikt mit einem Schlüsselwert
+bei einem Zeilen-Einfügevorgang in C führt. Ebenfalls sollte Sie nie
+dieselben Zeilen auf zwei Servern einfügen, wenn die Reihenfolge, in der
+die Aktualisierungen durchgeführt werden, eine Rolle spielt.
+
+Beachten Sie, dass sich das Log-Format in Version 3.23.26 geändert hat, so
+das Slaves vor Version 3.23.26 diese nicht lesen können.
+@item
+Wenn die Anfrage auf dem Slave zu einem Fehler führt, beendet sich der
+Slave-Thread und in der @code{.err}-Datei erscheint eine Meldung. Sie
+sollten sich dann manuell mit dem Slave verbinden, die Ursache des Fehlers
+beheben (zum Beispiel nicht existierende Tabellen) und dann den SQL-Befehl
+@code{SLAVE START} laufen lassen (verfügbar ab Version 3.23.16). In Version
+3.23.15 müssen Sie den Server neu starten.
+@item
+Wenn die Verbindung zum Master verloren geht, versucht der Slave
+unmittelbar, sich neu zu verbinden, und wenn das fehlschlägt, alle
+@code{master-connect-retry} Sekunden (Vorgabe 60 Sekunden). Deswegen ist es
+sicher, den Master herunter zu fahren und dann nach einer Weile wieder
+hochzufahren. Der Slave ist auch in der Lage, mit
+Netzwerk-Verbindungsausfällen umzugehen.
+@item
+Den Slave (sauber) herunterzufahren ist ebenfalls sicher, weil er sich
+merkt, wo er aufgehört hat. Unsauberes Herunterfahren kann zu Problemen
+führen, insbesondere dann, wenn der Platten-Cache nicht synchronisiert
+wurde, als das System starb. Die Fehlertoleranz Ihres Systems wird stark
+verbessert, wenn Sie ein gutes UPS haben.
+@item
+Wenn der Master auf einem Port auf Anfragen wartet, der nicht Standard ist,
+müssen Sie diesen mit dem @code{master-port}-Parameter in @code{my.cnf}
+angeben.
+@item
+In Version 3.23.15 werden alle Tabellen und Datenbanken repliziert. Ab
+Version 3.23.16 können Sie die Replikation mit der
+@code{replicate-do-db}-Anweisung in @code{my.cnf} auf einen Satz von
+Datenbanken beschränken oder einen Satz von Datenbanken mit
+@code{replicate-ignore-db} ausschließen. Beachten Sie, dass es bis Version
+3.23.23 einen Bug gab, so dass mit @code{LOAD DATA INFILE} nicht sauber
+umgegangen wurde, wenn Sie diesen Befehl in einer Datenbank ausführten, die
+von der Replikation ausgeschlossen war.
+@item
+Ab Version 3.23.16 schaltet @code{SET SQL_LOG_BIN = 0}
+Replikations-(Binär)-Loggen auf dem Master aus und @code{SET SQL_LOG_BIN =
+1} schaltet es wieder an. Sie benötigen die process-Berechtigung, um das
+auszuführen.
+@item
+Ab Version 3.23.19, you can clean up stale Replikation leftovers when
+something goes wrong und you want a clean start mit @code{FLUSH MASTER}
+und @code{FLUSH SLAVE}-Befehle. In Version 3.23.26 we have renamed them to
+@code{RESET MASTER} und @code{RESET SLAVE} respectively to clarify
+what they do. The old @code{FLUSH} variants still work, though, for
+Kompatibilität.
+
+@item
+Ab Version 3.23.21, you can use @code{LOAD TABLE FROM MASTER} for
+network backup und to set up Replikation initially. We have recently
+received a Anzahl von bug reports concerning it that we are investigating, so
+we recommend that you use it only in testing until we make it mehr stable.
+@item
+Ab Version 3.23.23, you can change masters und adjust log position
+mit @code{CHANGE MASTER TO}.
+@item
+Ab Version 3.23.23, you tell the master that updates in certain
+Datenbanken should not be logged to the Binär-Log-Datei mit @code{binlog-ignore-db}.
+@item
+Ab Version 3.23.26 können Sie @code{replicate-rewrite-db} benutzen, um den
+Slave anzuweisen, Aktualisierungen einer Datenbank auf dem Master auf eine
+mit einem anderen Namen auf dem Slave anzuwenden.
+@item
+Ab Version 3.23.28 können Sie @code{PURGE MASTER LOGS TO 'log-name'}
+benutzen, um alte Log-Dateien loszuwerden, während der Slave läuft.
+@end itemize
+
+
+@node Replication Options, Replication SQL, Replication Features, Replication
+@c German node Replikationsoptionen
+@subsection Replikationsoptionen in my.cnf
+
+Wenn Sie Replikation benutzen, empfehlen wir, dass Sie MySQL-Version
+3.23.30 oder höher benutzen. Ältere Versionen funktionieren, haben aber
+einige Bugs und fehlende Features.
+
+Sowohl auf dem Master als auch auf dem Slave müssen Sie die
+@code{server-id}-Option benutzen. Diese setzt eine eindeutige
+Replikations-ID. Sie sollten einen eindeutigen Wert im Bereich zwischen 1
+und 2^32-1 für jeden Master und Slave benutzen. Beispiel: @code{server-id=3}
+
+In folgender Tabelle stehen die Optionen, die Sie für den @strong{MASTER}
+benutzen können:
+
+@multitable @columnfractions .3 .7
+
+@item @strong{Option} @tab @strong{Beschreibung}
+@item @code{log-bin=dateiname} @tab
+Schreibt in die binäre Update-Log-Datei am angegebenen Ort. Beachten Sie,
+dass, wenn Sie ihr einen Parameter mit einer Erweiterung angeben (zum
+Beispiel @code{log-bin=/mysql/logs/replikation.log}), Versionen bis zu
+3.23.24 während der Replikation nicht richtig funktionieren, wen Sie
+@code{FLUSH LOGS} ausführen. Das Problem ist seit Version 3.23.25 behoben.
+Wenn Sie Log-Namen dieser Art benutzen, wird @code{FLUSH LOGS} auf dem
+binären Log ignoriert. Um das Log zu löschen, führen Sie @code{FLUSH
+MASTER} aus. Vergessen Sie dabei nicht, @code{FLUSH SLAVE} auf allen Slaves
+laufen zu lassen.Ab Version 3.23.26 sollten Sie @code{RESET MASTER} und
+@code{RESET SLAVE} benutzen.
+
+@item @code{log-bin-index=dateiname} @tab
+Weil der Benutzer @code{FLUSH LOGS}-Befehle ausführen könnte, muss man
+wissen, welches Log momentan aktiv ist und welche in welcher Reihenfolge
+durch Log-Rotation herausgenommen wurden. Diese Informationen sind in der
+Binär-Log-Index-Datei gespeichert. Der Vorgabewert ist `hostname`.index.
+
+Beispiel: @code{log-bin-index=datenbank.index}.
+
+@item @code{sql-bin-update-same} @tab
+Falls gesetzt, führt das Setzen von @code{SQL_LOG_BIN} auf einen Wert
+automatisch dazu, dass @code{SQL_LOG_UPDATE} auf denselben Wert gesetzt
+wird, und umgekehrt.
+
+@item @code{binlog-do-db=datenbank} @tab
+Weist den Master an, Aktualisierung in die Binär-Log-Datei zu loggen, wenn
+die aktuelle Datenbank 'datenbank' ist. Alle anderen Datenbanken werden
+ignoriert. Beachten Sie bei der Benutzung, dass Sie sicherstellen sollten,
+dass Sie Aktualisierungen nur in der aktuellen Datenbank ausführen.
+
+Beispiel: @code{binlog-do-db=eine_datenbank}.
+
+@item @code{binlog-ignore-db=datenbank} @tab
+Weist den Master an, das Aktualisierung der aktuellen Datenbank 'datenbank'
+nicht in der Binär-Log-Datei gespeichert werden sollen. ignoriert. Beachten
+Sie bei der Benutzung, dass Sie sicherstellen sollten, dass Sie
+Aktualisierungen nur in der aktuellen Datenbank ausführen.
+
+Beispiel: @code{binlog-ignore-db=eine_datenbank}
+@end multitable
+
+Folgende Tabelle enthält die Optionen, die Sie für @strong{SLAVE} benutzen
+können:
+
+@multitable @columnfractions .3 .7
+
+@item @strong{Option} @tab @strong{Beschreibung}
+@item @code{master-host=host} @tab
+Hostname des Masters oder IP-Adresse für Replikation. Falls nicht gesetzt,
+startet der Slave-Thread nicht.
+
+Beispiel: @code{master-host=datenbank-master.meinefirma.de}.
+
+@item @code{master-user=benutzername} @tab
+Der Benutzer, den der Slave-Thread für Authentifizierung benutzt, wenn er
+sich mit dem Master verbindet. Der Benutzer muss die
+@code{FILE}-Berechtigung besitzen. Wenn der Master-Benutzer nicht gesetzt
+ist, wird Benutzer @code{test} angenommen.
+
+Beispiel: @code{master-user=steve}.
+
+@item @code{master-password=passwort} @tab
+Das Passwort, das der Slave-Thread für Authentifizierung benutzt, wenn er
+sich mit dem Master verbindet. Wenn nicht gesetzt, wird ein leeres Passwort
+angenommen.
+
+Beispiel: @code{master-password=hund}.
+
+@item @code{master-port=portnummer} @tab
+Der Port, auf dem der Master auf Verbindungen wartet. Wenn nicht gesetzt,
+wird die kompilierte Einstellung von @code{MYSQL_PORT} angenommen. Wenn Sie
+nicht an den @code{configure}-Optionen gedreht haben, sollte das 3306 sein.
+
+Beispiel: @code{master-port=3306}.
+
+@item @code{master-connect-retry=sekunden} @tab
+Die Anzahl Sekunden, die der Slave-Thread schläft, bevor er wiederum
+versucht, sich mit dem Master zu verbinden, falls der Master herunter fuhr
+oder die Verbindung verloren ging. Vorgabewert ist 60.
+
+Beispiel: @code{master-connect-retry=60}.
+
+@item @code{master-ssl} @tab
+Schaltet SSL an.
+
+Beispiel: @code{master-ssl}.
+
+@item @code{master-ssl-key} @tab
+Der Name der SSL-Schlüsseldatei für den Master.
+
+Beispiel: @code{master-ssl-key=SSL/master-key.pem}.
+
+@item @code{master-ssl-cert} @tab
+Der Dateiname des SSL-Zertifikats für den Master.
+
+Beispiel: @code{master-ssl-key=SSL/master-cert.pem}.
+
+@item @code{master-info-file=dateiname} @tab
+Der Speicherort der Datei, die sich merkt, bis wohin der Master während des
+Replikationsprozesses verfolgt wurde. Vorgabewert ist master.info im data-
+Verzeichnis.
+
+Beispiel: @code{master-info-file=master.info}.
+
+@item @code{replicate-do-table=datenbank.tabelle} @tab
+Weist den Slave-Thread an, die Replikation auf die angegebene Tabelle zu
+beschränken. Um mehr als eine Tabelle anzugeben, benutzen Sie die Anweisung
+mehrfach, einmal für jede Tabelle. Das funktioniert auch bei
+Datenbank-übergreifenden Aktualisierungen, im Gegensatz zu
+@code{replicate-do-db}.
+
+Beispiel: @code{replicate-do-table=eine_datenbank.eine_tabelle}.
+
+@item @code{replicate-ignore-table=datenbank.tabelle} @tab
+Weist den Slave-Thread an, die angegebene Tabelle nicht zu replizieren. Um
+mehr als eine Tabelle anzugeben, die ignoriert werden soll, geben Sie die
+Anweisung mehrfach ein, einmal für jede Tabelle. Das funktioniert auch bei
+Datenbank-übergreifenden Aktualisierungen, im Gegensatz zu
+@code{replicate-ignore-db}.
+
+Beispiel: @code{replicate-ignore-table=eine_datenbank.eine_tabelle}.
+
+@item @code{replicate-wild-do-table=datenbank.tabelle} @tab
+Weist den Slave-Thread an, die Replikation auf Tabellen zu beschränken, die
+dem angegebenen Platzhalter-Muster entsprechen. Um mehr als ein
+Tabellenmuster anzugeben, das ignoriert werden soll, geben Sie die
+Anweisung mehrfach ein, einmal für jedes Tabellenmuster. Das funktioniert
+auch bei Datenbank-übergreifenden Aktualisierungen.
+
+Beispiel: @code{replicate-wild-do-table=foo%.bar%} repliziert nur
+Aktualisierungen auf Tabellen in allen Datenbanken, die mit 'foo' anfangen
+und deren Tabellennamen mit 'bar' beginnen.
+
+@item @code{replicate-wild-ignore-table=datenbank.tabelle} @tab
+Weist den Slave-Thread an, Tabellen nicht zu replizieren, die dem
+angegebenen Platzhalter-Muster entsprechen. Um mehr als ein
+Tabellenmuster anzugeben, das ignoriert werden soll, geben Sie die
+Anweisung mehrfach ein, einmal für jedes Tabellenmuster. Das funktioniert
+auch bei Datenbank-übergreifenden Aktualisierungen.
+
+Beispiel: @code{replicate-wild-ignore-table=foo%.bar%} aktualisiert keine
+Tabellen in Datenbanken, die mit 'foo' anfangen und deren Tabellennamen mit
+'bar' beginnen.
+
+@item @code{replicate-ignore-db=datenbank} @tab
+Weist den Slave-Thread an, die angegebene Datenbank nicht zu replizieren.
+Um mehr als eine Datenbank anzugeben, die ignoriert werden soll, geben Sie
+die Anweisung mehrfach ein, einmal für jede Datenbank. Diese Option
+funktioniert nicht für Datenbank-übergreifende Aktualisierungen. Wenn Sie
+Datenbank-übergreifende Aktualisierungen brauchen, stellen Sie sicher, dass
+Sie Version 3.23.28 oder höher verwenden und benutzen Sie
+@code{replicate-wild-ignore-table=datenbank.%}
+
+Beispiel: @code{replicate-ignore-db=eine_datenbank}.
+
+@item @code{replicate-do-db=datenbank} @tab
+
+Weist den Slave-Thread an, die Replikation auf die angegebene Datenbank zu
+beschränken. Um mehr als eine Datenbank anzugeben, benutzen Sie die
+Anweisung mehrfach, einmal für jede Datenbank. Beachten Sie, dass das nicht
+funktioniert, wenn Sie Datenbank-übergreifende Anfragen wie @code{UPDATE
+eine_datenbank.eine_tabelle SET foo='bar'} ausführen, während Sie eine
+andere oder keine Datenbank ausgewählt haben. Wenn Sie
+Datenbank-übergreifende Aktualisierungen brauchen, stellen Sie sicher, dass
+Sie Version 3.23.28 oder höher verwenden und benutzen Sie
+@code{replicate-wild-do-table=datenbank.%}.
+
+Beispiel: @code{replicate-do-db=eine_datenbank}.
+
+@item @code{log-slave-updates} @tab
+Weist den Slave an, Aktualisierungen vom Slave-Thread in die binäre
+Log-Datei zu schreiben. Ist vorgabemäßig ausgeschaltet. Sie müssen diese
+Option anschalten, wenn Sie planen, die Slave in eine zirkuläre Kette zu
+hängen ('Daisy-Chain').
+
+@item @code{replicate-rewrite-db=von_name->zu_name} @tab
+Aktualisierungen auf eine Datenbank mit einem anderen Namen als dem
+Orginalnamen.
+
+Beispiel: @code{replicate-rewrite-db=master_datenbank->slave_datenbank}.
+
+@item @code{skip-slave-start} @tab
+Weist den Slave-Server an, den Slave nicht beim Hochfahren zu starten. Der
+Benutzer kann ihn später mit @code{SLAVE START} starten.
+
+@item @code{slave_read_timeout=#} @tab
+Anzahl von Sekunden, die der Slave auf weitere Daten vom Master wartet,
+bevor er abbricht.
+@end multitable
+
+
+@node Replication SQL, Replication FAQ, Replication Options, Replication
+@c German node SQL und Replikation
+@subsection SQL-Befehle in Bezug auf Replikation
+
+@cindex SQL-Befehle, Replikation
+@cindex Befehle, Replikation
+@cindex Replikation, Befehle
+
+Replikation kann über die SQL-Schnittstelle gesteuert werden. Hier eine
+Zusammenfassung der Befehle:
+
+@multitable @columnfractions .30 .70
+@item @strong{Befehl} @tab @strong{Beschreibung}
+
+@item @code{SLAVE START}
+ @tab Startet den Slave-Thread. (Slave)
+
+@item @code{SLAVE STOP}
+ @tab Hält den Slave-Thread an. (Slave)
+
+@item @code{SET SQL_LOG_BIN=0}
+ @tab Schaltet das Loggen in die Update-Log-Datei aus, wenn der Benutzer
+die process-Berechtigung hat. Wird ansonsten ignoriert. (Master)
+
+@item @code{SET SQL_LOG_BIN=1}
+ @tab Schaltet das Loggen in die Update-Log-Datei wieder an, wenn der
+Benutzer die process-Berechtigung hat. Wird ansonsten ignoriert. (Master)
+
+@item @code{SET SQL_SLAVE_SKIP_COUNTER=n}
+ @tab Die nächsten @code{n} Ereignisse vom Master ignorieren. Gilt nur,
+wenn der Slave-Thread nicht läuft, gibt ansonsten einen Fehler aus.
+Nützlich für den Ausgleich von Replikationsabweichungen.
+
+@item @code{RESET MASTER}
+ @tab Löscht alle Binär-Log-Dateien, die in der Index-Datei aufgeführt
+sind, und setzt die BinärLog-Index-Datei auf leer zurück. In Versionen vor
+3.23.26 versions heißt dieser Befehl @code{FLUSH MASTER}. (Master)
+
+@item @code{RESET SLAVE}
+ @tab Führt dazu, dass der Slave seine Replikationsposition in den
+Master-Logs vergisst. In Versionen vor 3.23.26 versions heißt dieser
+Befehl @code{FLUSH SLAVE}. (Slave)
+
+@item @code{LOAD TABLE tabelle FROM MASTER}
+ @tab Lädt eine Kopie der Tabelle vom Master auf den Slave. (Slave)
+
+@item @code{CHANGE MASTER TO master_def_list}
+ @tab Ändert die Master-Parameters auf den Wert, der in
+@code{master_def_list} angegeben ist, und startet den Slave-Thread neu.
+@code{master_def_list} ist eine durch Kommas getrennte Liste
+@code{master_def}, wobei @code{master_def} eins der folgenden Elemente ist:
+@code{MASTER_HOST}, @code{MASTER_USER}, @code{MASTER_PASSWORD},
+@code{MASTER_PORT}, @code{MASTER_CONNECT_RETRY}, @code{MASTER_LOG_FILE}
+oder @code{MASTER_LOG_POS}. Beispiel:
+
+@example
+
+CHANGE MASTER TO
+ MASTER_HOST='master2.meinefirma.com',
+ MASTER_USER='replikation',
+ MASTER_PASSWORD='gro33esgeheimnis',
+ MASTER_PORT=3306,
+ MASTER_LOG_FILE='master2-bin.001',
+ MASTER_LOG_POS=4;
+
+@end example
+
+Sie müssen nur die Werte angeben, die geändert werden sollen. Die Werte,
+die Sie auslassen, bleiben dieselben, ausser wenn Sie den Host oder den
+Port ändern. In diesem Fall nimmt der Slave an, dass der Master ein anderer
+ist, weil Sie sich zu einem anderen Host oder über einen anderen Port
+verbinden. Daher treffen die alten Werte von Log und Position nicht mehr zu
+und werden automatisch auf eine leere Zeichenkette bzw. auf 0 zurück
+gesetzt (dem Startwert). Beachten Sie, dass sich der Slave beim Neustart an
+seinen alten Master erinnert. Falls das nicht wünschenswert ist, sollten
+Sie die @file{master.info}-Datei löschen, bevor Sie neu starten. Der Slave
+liest dann seinen Master aus der Datei @code{my.cnf} oder von der
+Kommandozeile. (Slave)
+
+@item @code{SHOW MASTER STATUS}
+ @tab Stellt Statusinformationen über die Binär-Log-Datei des Masters zur
+Verfügung. (Master)
+
+@item @code{SHOW SLAVE STATUS}
+ @tab Stellt Statusinformationen über die wichtigsten Parameter des
+Slave-Threads zur Verfügung. (Slave)
+@item @code{SHOW MASTER LOGS}
+ @tab Nur verfügbar ab Version 3.23.28. Listet die Binär-Log-Dateien auf
+dem Master auf. Sie sollten diesen Befehl vor @code{PURGE MASTER LOGS TO}
+benutzen, um herauszufinden, wie weit Sie gehen sollten.
+
+@item @code{PURGE MASTER LOGS TO 'logname'}
+ @tab Verfügbar ab Version 3.23.28. Löscht alle Replikations-Logs, die in
+der Index-Log-Datei aufgeführt sind, die vor dem angegebenen Log liegen und
+entfernt Sie aus dem Log-Index, so dass die angegebene Log-Datei nunmehr
+die erste wird. Beispiel:
+
+@example
+PURGE MASTER LOGS TO 'mysql-bin.010'
+@end example
+
+Dieser Befehl macht nichts und schlägt mit einer Fehlermeldung fehl, wenn
+Sie einen aktiven Slave haben, der momentan eine der Log-Dateien liest, die
+Sie zu löschen versuchen. Wenn Sie jedoch einen schlafenden Slave haben und
+gerade eine der Log-Dateien löschen, die dieser Slave lesen will, wird der
+Slave nicht in der Lage sein zu replizieren, sobald er wach wird. Der
+Befehl kann sicher verwendet werden, während Slaves replizieren - Sie
+brauchen diese also nicht anhalten.
+
+Zuerst müssen Sie alle Slaves mit @code{SHOW SLAVE STATUS} überprüfen, um
+festzustellen, an welcher Log-Datei sie gerade sind, dann eine Auflistung
+aller Log-Dateien auf dem Master mit @code{SHOW MASTER LOGS} machen, die
+früheste davon herausfinden, an der noch ein Slave arbeitet (wenn alle
+Slaves aktuell sind, ist das die letzte Log-Datei auf der Liste), dann alle
+Logs, die Sie löschen wollen, sichern (optional), und schließlich bis zum
+Ziel-Log löschen.
+
+@end multitable
+
+
+@node Replication FAQ, Replication Problems, Replication SQL, Replication
+@c German node Replikations-FAQ
+@subsection Replikation - Häufig gestellte Fragen
+
+@cindex @code{Binlog_Dump}
+@strong{Frage}: Warum sehe ich manchmal mehr als eine
+@code{Binlog_Dump}-Thread auf dem Master, nachdem ich den Slave neu
+gestartet habe?
+
+@strong{Antwort}: @code{Binlog_Dump} ist ein kontinuierlicher Prozess, der
+folgendermaßen vom Server gehandhabt wird:
+
+@itemize @bullet
+@item
+Zu den Aktualisierungen aufschließen.
+@item
+Sobald keine Aktualisierungen mehr übrig sind, in den Zustand
+@code{pThread_cond_wait()} gehen, durch den er entweder durch eine
+Aktualisierung oder einen Kill erweckt werden kann.
+@item
+Beim Aufwachen den Grund dafür prüfen. Wenn er nicht sterben soll,
+mit der @code{Binlog_dump}-Schleife weitermachen.
+@item
+Wenn ein schwerer Fehler auftritt, wenn zum Beispiel ein toter Client
+entdeckt wird, die Schleife beenden.
+@end itemize
+
+Wenn der Slave-Thread also beim Slave anhält, bemerkt das der entsprechende
+@code{Binlog_Dump}-Thread auf dem Master solange nicht, bis zumindest eine
+Aktualisierung (oder ein Kill) auf den Master durchgeführt wird, was
+benötigt wird, um ihn von @code{pThread_cond_wait()} aufzuwecken. In der
+Zwischenzeit könnte der Slave bereits eine weitere Verbindung geöffnet
+haben, die in einem weiteren @code{Binlog_Dump}-Thread resultiert.
+
+Das beschriebene Problem sollten in Versionen ab 3.23.26 nicht auftreten.
+In Version 3.23.26 kam @code{server-id} für jeden Replikationsserver hinzu,
+und nun werden alle alten Zombie-Threads auf dem Master gekillt, wenn ein
+neuer Replikations-Thread sich vom selben Slave aus verbindet.
+
+@strong{Frage}: Wie rotiere ich Replikations-Logs?
+
+@strong{Antwort}: In Version 3.23.28 sollten Sie den @code{PURGE MASTER
+LOGS TO}-Befehl benutzen, nachdem festgestellt wurde, welche Logs gelöscht
+werden können und nachdem sie optional gesichert wurden. In früheren
+Versionen ist der Prozess sehr viel anstrengender und kann nicht sicher
+durchgeführt werden, ohne alle Slaves anzuhalten, falls Sie planen,
+Log-Namen wiederholt zu verwenden. Sie müssen die Slave-Threads anhalten,
+die Binär-Log-Index-Datei editieren, alle alten Logs löschen, den Master
+neu starten, die Slave-Threads neu starten und dann die alten Log-Dateien
+entfernen.
+
+
+@strong{Frage}: Wie aktualisiere ich bei einer laufenden
+Replikationseinrichtung?
+
+@strong{Antwort}: Wenn Sie vor Version 3.23.26 aktualisieren, sollten Sie
+nur die Master-Tabellen sperren, warten, bis die Slaves auf aktuellem Stand
+sind, und dann @code{FLUSH MASTER} auf dem Master und @code{FLUSH SLAVE}
+auf dem Slave laufen lassen, um die Logs zurückzusetzen, und danach neue
+Versionen des Masters und des Slaves neu starten. Beachten Sie, dass der
+Slave für einige Zeit heruntergefahren bleiben kann - weil der Master alle
+Aktualisierung loggt, wird der Slave in der Lage sein, auf den aktuellen
+Stand zu kommen, sobald er hoch gefahren ist und sich verbinden kann.
+
+Nach Version 3.23.26 wurde das Replikationsprotokoll für Änderungen
+gesperrt, daher können Sie Masters und Slaves im laufenden Betrieb auf eine
+neuere 3.23-Version aktualisieren, und Sie können unterschiedliche
+Versionen von MySQL auf Slave und Master laufen haben, solange beide neuer
+als Version 3.23.26 sind.
+
+@cindex Replikation, Zweiweg-
+@strong{Frage}: Welche Dinge sollte ich beachten, wenn ich
+Zweiweg-Replikation aufsetze?
+
+@strong{Antwort}: MySQL-Replikation unterstützt derzeit kein
+Sperr-Protokoll zwischen Master und Slave, um die Atomizität einer
+verteilten (Cross-Server-) Aktualisierung zu gewährleisten. Mit anderen
+Worten ist es für einen Client A möglich, eine Aktualisierung zu Co-Master
+1 zu machen. In der Zwischenzeit, bevor er sich an Co-Master 2 wendet,
+könnte Client B eine Aktualisierung auf Co-Master 2 machen, die dazu führt,
+dass die Aktualisierung von Client A anders funktioniert als auf Master 1.
+Wenn daher die Aktualisierung von Client A zu Co-Master 2 durchdringt,
+produziert das Tabellen, die anders sein werden als die auf Co-Master 1,
+selbst nachdem alle Aktualisierungen von Co-Master 2 ebenfalls durchgeführt
+wurden. Daher sollten sie keine zwei Server in einer Zweiweg-Replikation
+verketten, es sei denn, Sie können sicher sein, dass Ihre Aktualisierungen
+immer in bestimmter Reihenfolge ablaufen, oder indem Sie irgendwie in Ihrem
+Client-Code Vorkehrungen gegen Aktualisierung treffen, die nicht in der
+richtigen Reihenfolge sind.
+
+Sie müssen sich auch darüber im Klaren sein, dass Zweiweg-Replikation Ihre
+Performance nicht wesentlich verbessert, falls überhaupt, sofern
+Aktualisierungen betroffen sind. Beide Server müssen ungefähr dieselbe
+Menge Aktualisierungen durchführen, was auch ein Server hätte tun können.
+Der einzige Unterschied liegt darin, dass es sehr viel weniger
+Lock-Contention gibt, weil die Aktualisierungen, die von einem anderen
+Server stammen, in einem Slave-Thread serialisiert werden. Dennoch kann der
+erzielte Vorteil durch Netzwerk-Verzögerungen konterkariert werden.
+
+@cindex Performance, verbessern
+@cindex erhöhen, Performance
+@strong{Frage}: Wie kann ich Replikation benutzen, um die Performance
+meines Systems zu verbessern?
+
+@strong{Antwort}: Sie sollten einen Server als Master aufsetzen und alle
+Schreibvorgänge zu ihm lenken, und so viele Slaves wie möglich einrichten
+und die Lesevorgänge zwischen Master und Slaves verteilen. Ausserdem können
+Sie die Slaves mit @code{--skip-bdb}, @code{--low-priority-updates} und
+@code{--delay-key-write-for-all-tables} starten, um für die Slaves
+Geschwindigkeitsverbesserungen zu erzielen. In diesem Fall benutzt der
+Slave nicht transaktionale @code{MyISAM}-Tabellen anstelle von
+@code{BDB}-Tabellen, um mehr Geschwindigkeit zu erhalten.
+
+@strong{Frage}: Was muss ich in meinem Client-Code tun, damit dieser
+Performance-verbessernde Replikation nutzt?
+
+@strong{Antwort}:
+Wenn der Teil Ihres Codes, der für den Datenbankzugriff zuständig ist,
+korrekt abstrahiert / modularisiert ist, sollte die Konvertierung zur
+replizierten Einrichtung sehr glatt und einfach verlaufen: Ändern Sie die
+Implementation Ihres Datenbankzugriffs so, dass von irgend einem Slave oder
+dem Master gelesen und immer zum Master geschrieben wird. Wenn Ihr Code
+nicht diese Abstraktionsebene besitzt, ist die Einrichtung eines
+Replikationssystems ein guter Grund, ihn zu säubern. Sie könnten damit
+beginnen, eine Wrapper-Bibliothek oder ein Wrapper-Modul mit folgenden
+Funktionen zu benutzen:
+
+@itemize @bullet
+@item
+@code{safe_writer_connect()}
+@item
+@code{safe_reader_connect()}
+@item
+@code{safe_reader_query()}
+@item
+@code{safe_writer_query()}
+@end itemize
+
+@code{safe_} bedeutet, dass die Funktion sich um die Handhabung jeglicher
+Fehlerbedingungen kümmert.
+
+Danach sollten Sie Ihren Client-Code so umwandeln, dass er die
+Wrapper-Bibliothek benutzt. Dieser Prozess kann anfangs etwas anstrengend
+und aufregend sein, wird sich aber auf lange Sicht lohnen. Alle
+Applikationen, die dem geschilderten Muster folgen, werden ebenfalls Nutzen
+aus der Master-/Slaves-Lösung ziehen. Der Code wird sich viel einfacher
+pflegen lassen und Optionen zur Problemlösung werden trivial sein. Sie
+brauchen einfach nur ein oder zwei Funktionen zu ändern, um zum Beispiel zu
+loggen, wie lang jede Anfrage dauerte, oder welche Anfrage unter Ihren
+Tausenden einen Fehler produzierte. Wenn Sie schon eine Menge Code
+geschrieben haben, wollen Sie den Umwandlungsprozess wahrscheinlich
+automatisieren. Hierfür können Sie zum Beispiel Monty's
+@code{replace}-Dienstprogramm benutzen, das der Standard-Distribution von
+MySQL beiliegt, oder Ihr eigenes Perl-Skript schreiben. Hoffentlich folgt
+Ihr Code irgend einem erkennbaren Muster - wenn nicht, ist es
+wahrscheinlich ohnehin besser, ihn neu zu schreiben, oder zumindest, ihn
+durchzugehen und manuell in ein Muster zu bringen.
+
+Beachten Sie, dass Sie natürlich andere Namen für die Funktionen verwenden
+können. Wichtig ist, eine einheitliche Schnittstelle für Verbindungen zum
+Lesen, Verbindungen zum Schreiben, Durchführen von Lesevorgängen und
+Durchführung von Schreibvorgängen zu haben.
+
+
+@strong{Frage}: Wann und in welchem Umfang kann MySQL-Replikation die
+Performance meines Systems verbessern?
+
+@strong{Antwort}: MySQL-Replikation bringt die meisten Vorteile auf einem
+System mit häufigen Lesevorgängen und nicht so häufigen Schreibvorgängen.
+Theoretisch können Sie eine Einrichtung aus einem Master und vielen Slaves
+so skalieren, dass Sie solange Slaves hinzufügen, bis Sie entweder keine
+Netzwerk-Bandbreite mehr haben oder bis Ihre Aktualisierungslast so weit
+ansteigt, dass der Master sie nicht mehr handhaben kann.
+
+Im festlegen zu können, wie viele Slaves sie haben können, bevor die
+zusätzlichen Vorteile aufgewogen werden, und um wieviel Sie die Performance
+Ihrer Site steigern können, müssen Sie Ihre Anfragenmuster kennen und
+empirisch (durch Benchmarks) festlegen, wie das Verhältnis zwischen dem
+Durchsatz von Lesevorgängen (pro Sekunde, oder @code{max_reads}) und
+Schreibvorgängen (@code{max_writes}) auf einem typischen Master und einem
+typischen Slave ist. Das unten stehende Beispiel zeigt Ihnen eine eher
+vereinfachte Berechnung, was Sie mit Replikation für ein imaginäres System
+erreichen können.
+
+Nehmen wir an, Ihr Systemlast besteht aus 10% Schreibvorgängen und 90%
+Lesevorgängen, und Sie haben festgestellt, dass @code{max_reads} = 1200 - 2
+* @code{max_writes} ist. Mit anderen Worten kann Ihr System 1.200
+Lesevorgänge pro Sekunde ohne Schreibzugriffe ausführen, und der
+durchschnittliche Schreibvorgang ist zweimal so langsam wie der
+durchschnittliche Lesevorgang, und das Verhältnis ist linear. Nehmen wir
+ferner an, dass Ihr Master und Slave dieselbe Kapazität haben, und dass es
+N Slaves und 1 Master gibt. Dann gilt für jeden Server (Master oder Slave):
+
+@code{lesen = 1200 - 2 * schreiben} (aus Benchmarks)
+
+@code{lesen = 9 * schreiben / (N + 1) } (lesen aufgeteilt, aber schreiben
+geht an alle Server)
+
+@code{9 * schreiben / (N+1) + 2 * schreiben = 1200}
+
+@code{schreiben = 1200/(2 + 9/(N+1)}
+
+Wenn also N = 0, was bedeutet, dass es keine Replikation gibt, kann Ihr
+System 1200 / 11, also etwa 109 Schreibvorgänge pro Sekunden handhaben (was
+heißt, dass Sie neunmal so viele Lesevorgänge haben, was der Natur Ihrer
+Applikation entspricht).
+
+Wenn N = 1 ist, können Sie bis zu 184 Schreibvorgänge pro Sekunde haben.
+
+Wenn N = 8 ist, können Sie bis zu 400 haben.
+
+Wenn N = 17 ist, können Sie 480 haben.
+
+Wenn schließlich N gegen unendlich geht (und Ihr Budget gegen negativ
+unendlich), können Sie sehr nahe an 600 Schreibvorgänge pro Sekunde kommen
+und damit den Systemdurchsatz um etwa den Faktor 5,5 erhöhen. Mit nur 8
+Servern jedoch kommen Sie bereits auf eine Steigerung um fast den Faktor 4.
+
+Beachten Sie, dass diese Berechnungen von unbegrenzter Netzwerk-Bandbreite
+ausgehen und verschiedene andere Faktoren vernachlässigen, die auf Ihrem
+System signifikant sein könnten. In vielen Fällen werden Sie nicht in der
+Lage sein, präzise vorauszusagen, was auf Ihrem System passieren wird, wenn
+Sie N Replikations-Slaves hinzufügen. Dennoch kann die Beantwortung
+folgender Fragen Ihnen helfen zu entscheiden, ob und wie viel (wenn
+überhaupt) Replikation bewirken kann, dass sich Ihre System-Performance
+verbessert:
+
+@itemize @bullet
+@item
+Was ist das Lese-/Schreibverhältnis auf Ihrem System?
+@item
+Wieviel zusätzliche Schreiblast kann ein Server handhaben, wenn Sie die
+Leselast verringern?
+@item
+Für wie viele Slave haben Sie Bandbreite auf Ihrem Netzwerk?
+@end itemize
+
+@strong{Frage}: Wie kann ich Replikation benutzen, um Redundanz / hohe
+Verfügbarkeit zur Verfügung zu stellen?
+
+@strong{Antwort}: Mit den momentan verfügbaren Features würden Sie einen
+Master und einen Slave (nicht mehrere Slaves) aufsetzen und ein Skript
+schreiben, das den Master beobachtet, um zu sehen, ob er hochgefahren ist,
+und Ihre Applikationen und die Slaves anweisen, den Master im Falle von
+Fehlschlägen zu ändern. Einige Vorschläge:
+set up a master und a slave (or several slaves) und write a Skript
+
+@itemize @bullet
+@item
+Um einem Slave mitzuteilen, den Master zu ändern, benutzen Sie den
+@code{CHANGE MASTER TO}-Befehl.
+@item
+Eine gute Möglichkeit, Ihre Applikationen darüber informiert zu halten, wo
+der Master ist, ist ein dynamischer DNS-Eintrag für den Master. Bei
+@strong{bind} können Sie @code{nsupdate} benutzen, um Ihr DNS dynamisch zu
+aktualisieren.
+@item
+Sie sollten Ihre Slaves mit der @code{log-bin}-Option und ohne
+@code{log-slave-updates} laufen lassen. Auf diese Art wird der Slave bereit
+sein, ein Master zu werden, sobald Sie @code{STOP SLAVE} eingeben,
+@code{RESET MASTER} und @code{CHANGE MASTER TO} auf den anderen Slaves. Das
+wird auch dabei helfen, fehlgelaufene Aktualisierungen zu entdecken, die
+auf Grund von Fehlkonfiguration des Slaves passieren (im Idealfall sollten
+Sie die Zugriffsrechte so konfigurieren, dass kein Client einen Slave
+aktualisieren kann, ausser der Slave-Thread), in Kombination mit den Bugs
+in Ihren Client-Programmen (die den Slave nie direkt aktualisieren
+sollten).
+
+@end itemize
+
+Momentan arbeiten wir an der Integration eines Systems in MySQL, das
+automatisch den Master auswählt, aber bis es fertig ist, müssen Sie Ihre
+eigenen Beobachtungswerkzeuge schaffen.
+
+
+@node Replication Problems, , Replication FAQ, Replication
+@c German node Replikationsprobleme
+@subsection Problemlösung bei Replikation
+
+Wenn Sie den Anweisungen gefolgt sind und Ihre Replikationseinrichtung
+nicht funktioniert, beseitigen Sie zunächst die Möglichkeit von
+Benutzerfehlern, indem Sie folgendes prüfen:
+
+@itemize @bullet
+@item
+Loggt der Master in die Binär-Log-Datei? Prüfen Sie das mit @code{SHOW
+MASTER STATUS}. Wenn das der Fall ist, ist die @code{Position} nicht 0.
+Wenn nicht, überprüfen Sie, ob Sie dem Master die @code{log-bin}-Option
+angegeben und die @code{server-id} gesetzt haben.
+@item
+Läuft der Slave? Überprüfen Sie das mit @code{SHOW SLAVE STATUS}. Die
+Antwort steht in der @code{Slave_running}-Spalte. Wenn nicht, überprüfen
+Sie die Slave-Optionen und überprüfen Sie die Fehler-Log-Datei auf
+Meldungen.
+@item
+Wenn der Slave läuft, hat er eine Verbindung mit dem Master hergestellt?
+Führen Sie @code{SHOW PROCESSLIST} aus, finden Sie den Thread mit dem
+@code{System user}-Wert in der @code{User}-Spalte und @code{none} in der
+@code{Host}-Spalte und überprüfen Sie die @code{State}-Spalte. Wenn dort
+steht @code{connecting to master}, überprüfen Sie die Berechtigungen für
+den Replikations-Benutzer auf dem Master, den Master-Hostnamen, Ihre
+DNS-Einrichtung, ob der Master tatsächlich läuft, ob er durch den Slave
+erreichbar ist, und wenn all das in Ordnung zu sein scheint, lesen Sie die
+Fehler-Log-Dateien.
+@item
+Wenn der Slave lief, aber dann anhielt, schauen Sie in die Ausgabe von SHOW
+SLAVE STATUS und überprüfen Sie die Fehler-Log-Dateien. Das passiert
+üblicherweise, wenn eine Anfrage, die auf dem Master funktionierte, auf dem
+Slave fehlschlägt. Das sollte nie vorkommen, wenn Sie einen korrekten
+Schnappschuss des Masters aufgenommen haben und die Daten nie auf dem Slave
+ausserhalb des Slave-Threads verändern. Wenn das doch auftritt, ist es ein
+Bug und sollte berichtet werden.
+@item
+Wenn eine Anfrage, die auf dem Master funktionierte, nicht auf dem Slave
+läuft, und eine komplette Datenbank-Synchronisation (das richtige, was man
+tun sollte) nicht ratsam erscheint, versuchen Sie folgendes:
+@itemize @minus
+@item
+Überprüfen Sie zunächst, ob irgend ein 'streunender' Datensatz im Weg ist.
+Finden Sie heraus, wie das geschehen konnte, dann löschen Sie ihn und
+lassen @code{SLAVE START} laufen.
+@item
+Wenn das Obige nicht funktioniert oder nicht zutrifft, versuchen Sie
+herauszufinden, ob es sicher ist, die Aktualisierung manuell durchzuführen
+(falls notwendig) und ignorieren Sie dann die nächste Anfrage vom Master.
+@item
+Wenn Sie sich entschieden haben, dass Sie die nächste Anfrage überspringen
+können, führen Sie @code{SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;} aus,
+um eine Anfrage zu überspringen, die kein auto_increment oder
+last_insert_id benutzt, ansonsten @code{SET SQL_SLAVE_SKIP_COUNTER=2; SLAVE
+START;}. Der Grund, warum auto_increment- / last_insert_id-Anfragen anders
+sind, liegt darin, dass für Sie zwei Ereignisse in der Binär-Log-Datei des
+Masters verzeichnet sind.
+
+@item
+Wenn Sie sicher sind, dass der Slave perfekt mit dem Master synchronisiert
+gestartet ist, und dass niemand die fraglichen Tabellen ausserhalb des
+Slave-Threads aktualisiert hat, berichten Sie den Bug, damit wir die oben
+beschriebenen Tricks nicht noch einmal machen müssen.
+@end itemize
+@item
+Stellen Sie sicher, dass es sich nicht um alten Bug handelt, indem
+Sie auf die aktuellste Version aktualisieren.
+@item
+Wenn alles Weitere fehlschlägt, lesen Sie die Fehler-Log-Dateien. Wenn
+diese Groß sind, führen Sie ein @code{grep -i slave /pfad/zu/your-log.err}
+auf dem Slave durch. Es gibt kein allgemeines Muster, nach dem man auf dem
+Master suchen könnte, weil die einzigen Fehler, die dieser mitschreibt,
+allgemeine Systemfehler sind - falls möglich, wird er Fehler an die Slaves
+senden, wenn etwas schief ging.
+@end itemize
+
+Wenn Sie sicher sind, dass es keine Benutzerfehler gibt und die Replikation
+immer noch nicht funktioniert oder nicht stabil ist, ist es an der Zeit,
+einen Bug-Bericht auszuarbeiten. Um dem Bug auf die Spur zu kommen,
+brauchen wir soviel Informationen von Ihnen wie möglich. Bitte nehmen Sie
+sich etwas Zeit und schreiben Sie einen guten Bug-Bericht. Im Idealfall
+hätten wir gerne einen Test-Fall in dem Format, das Sie im
+@code{mysql-test/t/rpl*}-Verzeichnis des Source-Baums finden. Wenn Sie
+einen solchen Test-Fall schicken, können Sie in den meisten Fällen ein Patch
+innerhalb von ein oder zwei Tagen erwarten. Diese Zeitspanne hängt
+allerdings von einer Anzahl weiterer Faktoren ab.
+
+Die zweitbeste Option ist ein einfaches Programm mit leicht
+konfigurierbaren Verbindungsargumenten für Master und Slave, das das
+Problem auf Ihrem System veranschaulicht. Sie können dies in Perl oder C
+schreiben, abhängig davon, welche Sprache Sie besser beherrschen.
+
+Wenn Sie den Bug auf eine der beiden oben beschriebenen Weisen
+demonstrieren können, benutzen Sie @code{mysqlbug}, um einen Bug-Bericht
+vorzubereiten, und schicken Sie ihn an @email{bugs@@lists.mysql.com}. Wenn
+Sie ein 'Phantom' haben - ein Problem, das auftritt, aber nicht einfach
+reproduziert werden kann - tun Sie folgendes:
+
+@itemize @bullet
+@item
+Stellen Sie sicher, dass kein Benutzerfehler im Spiel ist. Beispielsweise
+könnte der Slave ausserhalb des Slave-Threads aktualisiert werden - dann
+sind die Daten nicht synchronisiert und Sie haben womöglich einen Fehler
+wegen doppelter Schlüsseleinträge bei Aktualisierungen, wobei der
+Slave-Thread dann anhält und darauf wartet, dass Sie die Tabellen manuell
+in Ordnung und in Synchronisation bringen.
+@item
+Lassen Sie den Slave mit @code{log-slave-updates} und @code{log-bin} laufen
+- das behält eine Log-Datei aller Aktualisierungen auf dem Slave bei.
+@item
+Sichern Sie alle Beweise, bevor Sie die Replikation zurück setzen. Wenn wir
+keine oder nur schemenhafte Informationen haben, brauchen wir eine Weile,
+um dem Problem auf den Grund zu gehen. Die Beweise, die Sie für uns sammeln
+sollten, sind:
+@itemize @minus
+@item
+Alle Binär-Log-Dateien auf dem Master.
+@item
+Alle Binär-Log-Dateien auf dem Slave.
+@item
+Die Ausgabe von @code{SHOW MASTER STATUS} auf dem Master zu der Zeit, als
+Sie das Problem entdeckten.
+@item
+Die Ausgabe von @code{SHOW SLAVE STATUS} auf dem Master zu der Zeit, als
+Sie das Problem entdeckten.
+@item
+Fehler-Log-Dateien auf Master und Slave.
+@end itemize
+@item
+Benutzen Sie @code{mysqlbinlog}, um die Binär-Log-Dateien zu untersuchen.
+Folgendes sollte hilfreich sein, um eine Anfrage zu finden, die Probleme
+verursacht, zum Beispiel:
+@example
+mysqlbinlog -j pos_from_slave_status /pfad/zu/log_from_slave_status | head
+@end example
+@end itemize
+
+Sobald Sie die Beweise des Phantomproblems gesammelt haben, versuchen Sie
+zuerst, es in einen separaten Test-Fall zu isolieren. Berichten Sie dann
+das Problem an @email{bugs@@lists.mysql.com}, wobei Sie soviel
+Informationen wie möglich mitschicken.
+
+
+
+
+@node MySQL Optimisation, Reference, MySQL Database Administration, Top
+@c German node MySQL-Optimierung
+@chapter MySQL-Optimierung
+
+
+
+Optimierung ist eine komplizierte Aufgabe, weil sie ein umfassendes
+Verständnis des gesamten Systems voraussetzt. Es ist möglich, einige lokale
+Optimierungen Ihres Systems oder Ihrer Applikation mit geringem Wissen
+durchzuführen. Je optimaler Sie allerdings Ihr System gestalten wollen,
+desto mehr müssen Sie darüber wissen.
+
+Dieses Kapitel erklärt und gibt Beispiele für verschiedene Möglichkeiten,
+MySQL zu optimieren. Denken Sie allerdings daran, dass es immer noch
+zusätzliche Möglichkeiten gibt, das System noch schneller zu machen.
+
+
+@menu
+* Optimise Overview::
+* Query Speed::
+* Locking Issues::
+* Optimising Database Structure::
+* Optimising the Server::
+* Disk issues::
+@end menu
+
+@node Optimise Overview, Query Speed, MySQL Optimisation, MySQL Optimisation
+@c German node Überblick über Optimierung
+@section Überblick über Optimierung
+
+Der wichtigste Teil, um ein System schnell zu machen, ist natürlich das
+grundlegende Design. Ausserdem müssen Sie wissen, welche Dinge Ihr System
+macht und was die Flaschenhälse sind.
+
+Die wichtigsten Flaschenhälse sind:
+@itemize @bullet
+@item Suchvorgänge auf Festplatte.
+Die Festplatte benötigt Zeit, um ein Stück Daten zu finden. Bei modernen
+Festplatten (Stand: 1999) ist die mittlere Zugriffszeit üblicherweise
+weniger als 10 ms, daher können theoretisch etwa 1.000 Suchvorgänge pro
+Sekunde durchgeführt werden. Bei neueren Festplatten wird diese Zeit
+allmählich besser. Für einzelne Tabellen ist sie sehr schwer zu optimieren.
+Eine Möglichkeit, das zu optimieren, besteht darin, Daten auf mehr als eine
+Platte zu verteilen.
+
+@item Lesen von / Schreiben auf Festplatte.
+Wenn die Festplatte in der richtigen Position ist, um die Daten zu lesen,
+die wir brauchen, kann sie bei modernen Platten (Stand: 1999) etwas 10 bis
+20 MB pro Sekunde heraus geben. Das ist leichter zu optimieren als
+Suchvorgänge, weil man von mehrfachen Festplatten parallel lesen kann.
+
+@item CPU-Zyklen.
+Wenn die Daten im Hauptspeicher sind (oder bereits dort waren), müssen sie
+verarbeitet werden, um das Ergebnis zu erhalten. Kleine Tabellen im
+Vergleich zum Arbeitsspeicher ist der Faktor, der am meisten begrenzt. Auf
+der anderen Seite ist Geschwindigkeit bei kleinen Tabellen üblicherweise
+nicht das Problem.
+
+@item Speicher-Bandbreite.
+Wenn der Prozessor mehr Daten braucht, als in den CPU-Cache passen, wird
+die Bandbreite des Hauptspeichers zum Flaschenhals. Auf den meisten
+Systemen ist das ein ungewöhnlicher Flaschenhals, aber man sollte sich
+dessen bewusst sein.
+@end itemize
+
+
+
+
+@menu
+* Design Limitations::
+* Portability::
+* Internal use::
+* MySQL Benchmarks::
+* Custom Benchmarks::
+@end menu
+
+@node Design Limitations, Portability, Optimise Overview, Optimise Overview
+@c German node Design-Einschränkungen
+@subsection MySQL-Design-Einschränkungen
+
+@cindex Design, Einschränkungen
+@cindex Einschränkungen, Design
+
+Weil MySQL extrem schnelles Tabellensperren beherrscht (mehrfache Leser /
+einzelne Schreiber), ist das größte verbleibende Problem eine Mischung aus
+einem laufenden Strom von Einfügevorgängen und langsamen Selects auf
+dieselbe Tabelle.
+
+Wir glauben, dass diese Wahl auf einer sehr großen Anzahl von Systemen
+letztlich einen Gewinn darstellt. Auch dieser Fall ist üblicherweise
+dadurch zu lösen, dass man mehrfache Kopien der Tabelle vorhält, aber man
+benötigt mehr Anstrengung und Hardware.
+
+Wir arbeiten auch an einigen Erweiterungen, um dieses Problem in Hinsicht
+auf einige häufige Applikationsnischen zu lösen.
+
+
+@node Portability, Internal use, Design Limitations, Optimise Overview
+@c German node Portabilität
+@subsection Portabilität
+
+@cindex Portabilität
+@cindex Crash-me-Programm
+@cindex Programme, Crash-me
+
+Weil alle SQL-Server unterschiedliche Teile von SQL implementieren, ist es
+immer Arbeit, portable SQL-Applikationen zu schreiben. Bei sehr einfachen
+Selects und Inserts ist das sehr einfach, aber je mehr Sie brauchen, desto
+schwieriger wird es. Wenn Sie eine Applikation wollen, die bei vielen
+Datenbanken noch schnell läuft, wird es sogar noch schwieriger!
+
+Um eine komplexe Applikation portabel zu machen, müssen Sie sich für eine
+Reihe von SQL-Servern entscheiden, mit denen sie funktionieren soll.
+
+Sie können das MySQL-Crash-me-Programm bzw. die Webpage
+@uref{http://www.mysql.com/information/crash-me.php} benutzen, um
+Funktionen, Typen und Einschränkungen zu finden, die Sie mit einer Auswahl
+von Datenbank-Servern benutzen können. Crash-me testet bei weitem nicht
+alles, was möglich ist, aber mit etwa 450 unterschiedlichen Dingen ist es
+recht umfassend.
+
+Sie sollten zum Beispiel keine Spaltennamen benutzen, die länger als 10
+Zeichen sind, wenn Sie auch Informix oder DB2 benutzen wollen.
+
+Sowohl die MySQL-Benchmarks als auch die Crash-me-Programme sind sehr
+Datenbank-abhängig. Indem Sie einen Blick darauf werfen, wie wir damit
+umgegangen sind, bekommen Sie ein Gefühl dafür, was Sie in Ihrer
+Applikation schreiben müssen, damit diese Datenbank-unabhängig läuft. Die
+Benchmark-Tests selbst befinden sich im @file{sql-bench}-Verzeichnis der
+MySQL-Quelldistribution. Sie sind in Perl mit der
+DBI-Datenbank-Schnittstelle geschrieben (die den Zugriffsteil des Problems
+löst).
+
+Siehe @uref{http://www.mysql.com/information/benchmarks.html} wegen der
+Ergebnisse aus diesem Benchmark-Test.
+
+Wie Sie an den Ergebnissen sehen, haben alle Datenbanken einige
+Schwachpunkte, das heißt, sie haben verschiedene Design-Kompromisse, die
+zu unterschiedlichem Verhalten führen.
+
+Wenn Sie nach Datenbank-Unabhängigkeit streben, müssen Sie ein gutes Gefühl
+für die Flaschenhälse jedes SQL-Servers bekommen. MySQL ist SEHR schnell
+beim Abrufen und Aktualisieren von Dingen, hat aber Probleme, wenn
+gleichzeitig langsame Leser / Schreiber auf dieselbe Tabelle zugreifen.
+Oracle hat ein großes Problem, wenn Sie versuchen, auf Zeilen zuzugreifen,
+der kürzlich aktualisiert wurden (solange, bis sie auf Platte
+zurückgeschrieben wurden). Transaktionale Datenbanken sind allgemein nicht
+sehr gut darin, Zusammenfassungstabellen aus Log-Tabellen zu erzeugen, weil
+in diesem Fall Sperren auf Zeilenebene fast nutzlos ist.
+
+Um Ihre Applikation @emph{wirklich} Datenbank-unabhängig zu machen, müssen
+Sie eine leicht erweiterbare Schnittstelle definieren, über die Sie Ihre
+Daten manipulieren. Weil auf den meisten Systemen C++ verfügbar ist, ist es
+sinnvoll, C++-Klassen als Schnittstellen zu den Datenbanken zu benutzen.
+
+Wenn Sie irgend ein spezifisches Feature einer Datenbankbenutzung (wie den
+@code{REPLACE}-Befehl in MySQL), sollten Sie eine Methode für die anderen
+SQL-Server codieren, um dasselbe Feature (wenngleich langsamer) zu
+implementieren. Bei MySQL können Sie die @code{/*! */}-Syntax benutzen, um
+MySQL-spezifische Schlüsselwörter in einer Anfrage zu verwenden. Der Code
+innerhalb von @code{/**/} wird von den meisten anderen SQL-Servern als
+Kommentar behandelt (ignoriert).
+
+Wenn WIRKLICH hohe Performance wichtiger als Exaktheit ist, wie bei einigen
+Web-Applikationen, besteht eine Möglichkeit darin, eine Applikationsebene
+zu erzeugen, die alle Ergebnisse cachet, um Ihnen noch höhere Performance
+zu bringen. Indem Sie alte Ergebnisse nach einer Weile 'auslaufen' lassen,
+können Sie den Cache in vernünftiger Weise 'frisch' halten. Das ist in
+Fällen extrem hoher Last recht nett, wobei Sie den Cache dynamisch
+vergrößern und die Verfallszeit (Expire Timeout) höher setzen können, bis
+wieder Normalauslastung eintritt.
+
+In diesem Fall sollte die Tabellenerzeugungsinformation Informationen über
+die ursprüngliche Cache-Größe enthalten und darüber, wie oft die Tabelle
+normalerweise aktualisiert (refresh) werden sollte.
+
+
+@node Internal use, MySQL Benchmarks, Portability, Optimise Overview
+@c German node Interner Gebrauch
+@subsection Wofür benutzen wir MySQL?
+
+@cindex Gebrauch, von MySQL
+@cindex Kunden, von MySQL
+
+In der anfänglichen Phase der Entwicklung von MySQL wurden die Features von
+MySQL für unseren größten Kunden gemacht. Dieser macht Data-Warehousing
+für eine Reihe der größten Einzelhändler in Schweden.
+
+Aus allen Verkaufsstellen erhalten wir wöchentliche Zusammenfassungen aller
+Bonuskarten-Transaktionen, und es wird erwartet, dass daraus nützliche
+Informationen für die Eigentümer der Verkaufsstellen zur Verfügung gestellt
+werden, damit diese herausfinden können, wie ihre Werbemaßnahmen ihre
+Kunden beeinflussen.
+
+Die Datenmenge ist recht riesig (etwa 7 Millionen
+Zusammenfassungs-Transaktionen pro Monat), und wir haben Daten von 4 bis 10
+Jahren, die wir dem Benutzer präsentieren müssen. Wir bekamen wöchentliche
+Anfragen von Kunden, die 'sofortigen' Zugriff auf neue Berichte aus diesen
+Daten wollten.
+
+Die Lösung bestand darin, alle Informationen monatsweise in komprimierten
+'Transaktions-' Tabellen zu speichern. Wir haben einen Satz einfacher
+Makros (ein Skript), die aus diesen Tabellen Zusammenfassungstabellen
+erzeugen, die nach verschiedenen Kriterien gruppiert sind (Produktgruppe,
+Kunden-ID, Verkaufsstelle usw.). Die Berichte sind Web-Seiten, die
+dynamisch durch ein kleines Perl-Skript erzeugt werden, das eine Web-Seite
+parst, die enthaltenen SQL-Statements ausführt und die Ergebnisse einfügt.
+Wir hätten statt dessen PHP oder mod_perl benutzt, aber diese waren damals
+noch nicht verfügbar.
+
+Für grafische Darstellungen schrieben wir ein einfaches Werkzeug in
+@code{C}, das GIFs auf der Grundlage der Ergebnisse einer SQL-Anfrage
+erzeugen kann (nach einigem Verarbeiten des Ergebnisses). Dieses wird
+ebenfalls dynamisch durch ein Perl-Skript ausgeführt, das die
+@code{HTML}-Dateien parst.
+
+In den meisten Fällen kann ein neuer Bericht einfach durch das Kopieren
+eines bestehenden Skripts und das Verändern der SQL-Anfrage darin erzeugt
+werden. In einigen Fällen müssen wir einer bestehenden
+Zusammenfassungstabelle weitere Felder hinzufügen oder eine neue
+generieren, aber auch das ist recht einfach, weil wir alle
+Transaktionstabellen auf Platte haben. (Momentan haben wir mindestens 50 GB
+an Transaktionstabellen und 200 GB weiterer Kundendaten.)
+
+Wir lassen unsere Kunden auch direkt mit ODBC auf die Transaktionstabellen
+zugreifen, so dass fortgeschrittene Benutzer selbst mit den Daten
+experimentieren können.
+
+Wir hatten mit der Handhabung keinerlei Probleme, auf einer recht
+bescheidenen Sun Ultra SPARCstation (2x200 MHz). Kürzlich haben wir einen
+unserer Server auf eine mit 2 Prozessoren bestückte 400 MHz-UltraSPARC
+erweitert und planen jetzt, Transaktionen auf Produktebene zu handhaben,
+was eine zehnfache Steigerung der Datenmenge bedeuten würde. Wir glauben,
+dass wir auch damit Schritt halten können, indem wir unseren Systemen
+einfach mehr Festplattenplatz hinzufügen.
+
+Wir experimentieren auch mit Intel-Linux, um in der Lage zu sein, mehr
+CPU-Power preisgünstiger zu erhalten. Jetzt, wo wir das binäre portable
+Datenbankformat haben (neu seit Version 3.23), werden wir dieses für einige
+Teile der Applikation benutzen.
+
+Unser anfängliches Gefühl sagt uns, dass Linux viel besser bei geringer bis
+mittlerer Last ist, während Solaris wegen der extremen
+Festplatten-Eingabe-/Ausgabe-Geschwindigkeit (Disk-IO) bei Hochlast besser
+ist, aber wir können noch nichts Endgültiges darüber aussagen. Nach einigen
+Diskussionen mit den Linux-Kernel-Entwicklern ist das eventuell ein
+Seiteneffekt von Linux, das dem Stapel-Job so viel Ressourcen gibt, dass
+die interaktive Performance sehr gering wird. Dadurch scheint die Maschine
+sehr langsam und unempfänglich für Eingaben zu lassen, während große
+Stapel-Jobs abgearbeitet werden. Wir hoffen, dass dies in zukünftigen
+Linux-Kernels besser gehandhabt wird.
+
+
+@node MySQL Benchmarks, Custom Benchmarks, Internal use, Optimise Overview
+@c German node MySQL-Benchmarks
+@subsection Die MySQL-Benchmark-Suite
+
+@cindex Benchmark-Suite
+@cindex Crash-me-Programm
+
+Dieser Abschnitt sollte eine technische Beschreibung der MySQL-
+Benchmark-Suite (und von @code{crash-me}) enthalten, aber diese
+Beschreibung wurde noch nicht geschrieben. Momentan können Sie eine gute
+Idee über den Benchmark bekommen, wenn Sie einen Blick auf den Code und die
+Ergebnisse im @file{sql-bench}-Verzeichnis jeder MySQL-Quelldistribution
+werfen.
+
+Diese Benchmark-Suite ist als Benchmark gedacht, der jedem Benutzer
+mitteilt, welche Dinge in einer gegebenen SQL-Implementation gut performen
+und welche schlecht.
+
+Beachten Sie, dass dieser Benchmark single-threaded ist. Daher misst er die
+minimale Zeit der Operationen. In Zukunft planen wir, auch etliche
+multi-threaded Test hinzuzufügen.
+
+Beispiele (die auf derselben NT-4.0-Maschine liefen):
+
+@multitable @columnfractions .6 .2 .2
+@strong{2.000.000 Zeilen vom Index lesen} @tab @strong{Sekunden} @tab @strong{Sekunden}
+@item mysql @tab 367 @tab 249
+@item mysql_odbc @tab 464
+@item db2_odbc @tab 1206
+@item informix_odbc @tab 121126
+@item ms-sql_odbc @tab 1634
+@item oracle_odbc @tab 20800
+@item solid_odbc @tab 877
+@item sybase_odbc @tab 17614
+@end multitable
+
+@multitable @columnfractions .6 .2 .2
+@strong{350.768 Zeilen einfügen} @tab @strong{Sekunden} @tab @strong{Sekunden}
+@item mysql @tab 381 @tab 206
+@item mysql_odbc @tab 619
+@item db2_odbc @tab 3460
+@item informix_odbc @tab 2692
+@item ms-sql_odbc @tab 4012
+@item oracle_odbc @tab 11291
+@item solid_odbc @tab 1801
+@item sybase_odbc @tab 4802
+@end multitable
+
+Im obigen Test lief MySQL mit einem 8 MB Index-Cache.
+
+Weitere Benchmark-Ergebnisse haben wir unter
+@uref{http://www.mysql.com/information/benchmarks.html} gesammelt.
+
+Beachten Sie, dass Oracle nicht beinhaltet ist, weil sie gebeten haben,
+entfernt zu werden. Alle Oracle-Benchmarks müssen von Oracle freigegeben
+werden! Wir glauben, dass das die Aussagefähigkeit von Oracle-Benchmarks
+@strong{SEHR} zweifelhaft erscheinen läßt, weil alle obigen Benchmarks
+dafür da sind zu zeigen, was eine Standard-Installation bei einem einzelnen
+Client machen kann.
+
+Um eine Benchmark-Suite laufen zu lassen, müssen Sie eine
+MySQL-Quelldistribution herunter laden, den Perl-DBI-Treiber und den
+Perl-DBD-Treiber für die gewünschte Datenbank installieren und dann
+folgendes tun:
+
+@example
+cd sql-bench
+perl run-all-tests --server=#
+@end example
+
+Wobei # einer der unterstützten Server ist. Sie erhalten eine Auflistung
+aller Optionen und unterstützten Server, indem Sie @code{run-all-tests
+--help} ausführen.
+
+@cindex Crash-me
+@code{Crash-me} versucht herauszufinden, welche Features eine Datenbank
+unterstützt und wo ihre Fähigkeiten und Einschränkungen sind, indem
+tatsächliche Anfragen ausgeführt werden. Beispielsweise stellt es fest:
+
+@itemize @bullet
+@item
+Welche Spaltentypen unterstützt werden.
+@item
+Wie viele Indexe unterstützt werden.
+@item
+Welche Funktionen unterstützt werden.
+@item
+Wie Groß eine Anfrage sein kann.
+@item
+Wie Groß eine @code{VARCHAR}-Spalte sein kann.
+@end itemize
+
+Sie finden die Ergebnisse von Crash-me für viele verschiedene Datenbanken
+unter @uref{http://www.mysql.com/information/crash-me.php}.
+
+
+@node Custom Benchmarks, , MySQL Benchmarks, Optimise Overview
+@c German node Benutzerspezifische Benchmarks
+@subsection Wie Sie Ihre eigenen Benchmarks benutzen
+
+@cindex Benchmarks
+@cindex Performance, Benchmarks
+
+Sie sollten Ihre Applikation und Datenbank auf jeden Fall einem
+Benchmark-Test unterziehen um herauszufinden, wo Flaschenhälse sind. Indem
+Sie einen Flaschenhals beseitigen (oder ihn durch ein 'Dummy-Modul'
+ersetzen), können Sie leicht den nächsten Flaschenhals herausfinden (usw.).
+Selbst wenn die insgesamte Performance für Ihre Applikation ausreichend
+ist, sollten Sie zumindest einen Plan für jeden Flaschenhals aufstellen und
+entscheiden, auf welche Weise dieser beseitigt werden soll, wenn Sie eines
+Tages die zusätzliche Performance benötigen.
+
+Als Beispiel für ein portables Benchmark-Programm schauen Sie sich die
+MySQL-Benchmark-Suite an. @xref{MySQL Benchmarks, , MySQL-Benchmarks}. Sie
+können jedes Programm dieser Suite nehmen und es Ihren Bedürfnissen
+entsprechend abändern. Wenn Sie das tun, können Sie unterschiedliche
+Lösungen für Ihr Problem finden und testen, was bei Ihnen wirklich die
+schnellste Lösung ist.
+
+Es ist häufig der Fall, dass Probleme nur dann auftreten, wenn das System
+unter schwerer Last läuft. Viele Kunden nahmen mit uns Kontakt auf, nachdem
+sie ein (getestetes) System in eine Produktionsumgebung stellten und
+Lastprobleme bekamen. Bei jedem dieser Fälle gab es bislang entweder
+Probleme mit dem Grund-Design (Tabellen-Scans laufen NICHT gut unter hoher
+Last) oder im Zusammenhang mit dem Betriebssystem / den Bibliotheken. Das
+meiste davon wäre @strong{SEHR} viel einfacher zu beheben, wenn die Systeme
+nicht bereits in einer Produktionsumgebung liefen.
+
+Um solcherlei Probleme zu vermeiden, sollten Sie einige Anstrengung darauf
+verwenden, Ihre gesamte Applikation unter der schlimmstmöglichen Last zu
+benchmarken! Hierfür können Sie Super Smack benutzen, das Sie hier
+erhalten:
+@uref{http://www.mysql.com/downloads/super-smack/super-smack-1.0.tar.gz}.
+Wie der Name nahelegt, kann es Ihr System auf die Knie zwingen, wenn Sie
+das wollen. Achten Sie daher darauf, es nur auf Entwicklungssystemen zu
+verwenden.
+
+
+@node Query Speed, Locking Issues, Optimise Overview, MySQL Optimisation
+@c German node Anfragen-Geschwindigkeit
+@section @code{SELECT}s und andere Anfragen optimieren
+
+@cindex Anfragen, Geschwindigkeit von
+@cindex Berechtigungsprüfungen, Auswirkung auf Geschwindigkeit
+@cindex Geschwindigkeit, von Anfragen
+
+Zunächst etwas, das alle Anfragen betrifft: Je komplexer das
+Berechtigungssystem, das Sie einrichten, desto mehr Overhead bekommen Sie.
+
+Falls Sie noch keinerlei @code{GRANT}-Statements ausgeführt haben,
+optimiert MySQL die Berechtigungsprüfung zum Teil. Wenn Sie also sehr hohe
+Zugriffszahlen haben, kann es einen Zeitvorteil darstellen, Grants zu
+vermeiden. Ansonsten können mehr Berechtigungsprüfungen in einem größeren
+Overhead resultieren.
+
+Wenn Sie Probleme bei einer bestimmten MySQL-Funktion haben, können Sie den
+Zeitbedarf jederzeit wie folgt mit dem MySQL-Client feststellen:
+
+@example
+mysql> select benchmark(1000000,1+1);
++------------------------+
+| benchmark(1000000,1+1) |
++------------------------+
+| 0 |
++------------------------+
+1 row in set (0.32 sec)
+@end example
+
+Das Ergebnis zeigt, dass MySQL 1.000.000 @code{+}-Operationen in 0,32
+Sekunden auf einer @code{PentiumII-400MHz}-Maschine ausführen kann.
+
+Alle MySQL-Funktionen sollten sehr optimiert sein, aber es mag einige
+Ausnahmen geben und @code{benchmark(schleifenzaehler,ausdruck)} ist ein
+großartiges Werkzeug, um herauszufinden, ob das das Problem bei Ihrer
+Anfrage darstellt.
+
+
+
+@menu
+* EXPLAIN::
+* Estimating performance::
+* SELECT speed::
+* Where optimisations::
+* DISTINCT optimisation::
+* LEFT JOIN optimisation::
+* LIMIT optimisation::
+* Insert speed::
+* Update speed::
+* Delete speed::
+* Tips::
+@end menu
+
+@node EXPLAIN, Estimating performance, Query Speed, Query Speed
+@c German node EXPLAIN
+@subsection @code{EXPLAIN}-Syntax (Informationen über ein @code{SELECT} erhalten)
+
+@findex EXPLAIN
+@findex SELECT, Optimierung
+
+@example
+ EXPLAIN tabelle
+oder EXPLAIN SELECT select_optionen
+@end example
+
+@code{EXPLAIN tabelle} ist ein Synonym für @code{DESCRIBE tabelle} oder
+@code{SHOW COLUMNS FROM tabelle}.
+
+Wenn Sie einem @code{SELECT}-Statement das Schlüsselwort @code{EXPLAIN}
+voran stellen, erklärt MySQL explains, wie er das @code{SELECT} ausführen
+würde, indem Informationen darüber gemacht werden, wie Tabellen verknüpft
+(Join) werden und in welcher Reihenfolge.
+
+Mit der Hilfe von @code{EXPLAIN} können Sie erkennen, wo Sie Tabellen
+Indexe hinzufügen müssen, um ein schnelleres @code{SELECT} zu erhalten, das
+Indexe benutzt, um die Datensätze zu finden. Ausserdem sehen Sie, ob der
+Optimierer die Tabellen in optimaler Reihenfolge verknüpft. Um den
+Optimierer zu zwingen, eine spezielle Verknüpfungsreihenfolge bei einem
+@code{SELECT}-Statement einzuhalten, fügen Sie eine
+@code{STRAIGHT_JOIN}-Klausel hinzu.
+
+Bei nicht einfachen Verknüpfungen (Joins) gibt @code{EXPLAIN} für jede
+Tabelle, die im @code{SELECT}-Statement benutzt wurde, eine
+Informationszeile zurück. Die Tabellen sind in der Reihenfolge aufgelistet,
+in der sie gelesen werden würden. MySQL löst alle Joins mit einer
+Single-Sweep-Multi-Join-Methode auf. Das bedeutet, dass MySQL eine Zeile
+aus der ersten Tabelle liest, dann die passende Zeile in der zweiten
+Tabelle sucht, dann in der dritten Tabelle usw. Wenn alle Tabellen
+verarbeitet wurden, gibt er die ausgewählten Spalten aus und geht
+rückwärts durch die Tabellenliste durch, bis eine Tabelle gefunden wird,
+bei der es weitere passende Zeilen gibt. Die nächste Zeile wird aus dieser
+Tabelle gelesen, und der Prozess fährt mit der nächsten Tabelle fort.
+
+Die Ausgabe von @code{EXPLAIN} enthält folgende Spalten:
+
+@table @code
+@item table
+Die Tabelle, auf die sich die Ausgabezeile bezieht.
+
+@item type
+Der Join-Typ. Informationen über die verschiedenen Typen finden Sie weiter
+unten.
+
+@item possible_keys
+Die @code{possible_keys}-Spalte gibt an, welche Indexe MySQL verwenden
+konnte, um Zeilen in dieser Tabelle zu finden. Beachten Sie, dass diese
+Spalte völlig unabhängig von der Reihenfolge der Tabellen ist. Das heißt,
+dass einige der Schlüssel in possible_keys möglicherweise bei der
+tatsächlich verwendeten Tabellenreihenfolge nicht verwendbar sind.
+
+Wenn diese Spalte leer ist, gibt es keine relevanten Indexe. In diesem Fall
+können Sie die Performance Ihrer Anfrage womöglich verbessern, indem Sie
+die @code{WHERE}-Klausel untersuchen, um festzustellen, ob diese auf eine
+oder mehrere Spalten verweist, die zweckmäßigerweise indiziert werden
+sollten. Wenn das der Fall ist, erzeugen Sie einen entsprechenden Index und
+prüfen Sie die Anfrage noch einmal mit @code{EXPLAIN}. @xref{ALTER TABLE}.
+
+Um zu sehen, welche Indexe eine Tabelle hat, benutzen Sie @code{SHOW INDEX
+FROM tabelle}.
+
+@item key
+@c German FIX changed @xref to @ref
+Die @code{key}-Spalte gibt den Schlüssel an, den MySQL tatsächlich benutzen
+wird. Der Schlüssel ist @code{NULL}, wenn kein Index gewählt wurde. Wenn
+MySQL den falschen Index wählt, können Sie ihn wahrscheinlich zwingen,
+einen anderen Index zu nehmen, indem Sie @code{myisamchk --analyze} oder
+@ref{myisamchk syntax} ausführen oder @code{USE INDEX/IGNORE INDEX}
+benutzen. @xref{JOIN}.
+
+@item key_len
+Die @code{key_len}-Spalte gibt die Länge des Schlüssels an, den MySQL
+benutzen wird. Die Länge ist @code{NULL}, wenn @code{key} @code{NULL} ist.
+Beachten Sie, dass Ihnen das angibt, wie viele Teile eines mehrteiligen
+Schlüssels MySQL tatsächlich benutzen wird.
+
+@item ref
+Die @code{ref}-Spalte zeigt an, welche Spalten oder Konstanten beim
+@code{key} benutzt werden, um Zeilen aus der Tabelle auszuwählen.
+
+@item rows
+die @code{rows}-Spalte gibt die Anzahl von Zeilen an, von denen MySQL
+annimmt, dass es sie untersuchen muss, um die Anfrage auszuführen.
+
+@item Extra
+Diese Spalte enthält zusätzliche Informationen darüber, wie MySQL die
+Anfrage auflösen wird. Folgende unterschiedliche Text-Zeichenketten können
+in dieser Spalte stehen:
+
+@table @code
+@item Distinct
+MySQL wird die Suche nach weiteren Zeilen für die aktuelle
+Zeilenkombination nicht fortsetzen, nachdem er die erste passende Zeile
+gefunden hat.
+
+@item Not exists
+MySQL war in der Lage, eine @code{LEFT JOIN}-Optimierung der Anfrage
+durchzuführen, und wird keine weiteren Spalten in dieser Tabelle für die
+vorherige Zeilenkombination mehr untersuchen, nachdem er eine Zeile
+gefunden hat, die den @code{LEFT JOIN}-Kriterien entspricht.
+
+Hier ist ein Beispiel dafür:
+
+@example
+SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
+@end example
+
+Angenommen, @code{t2.id} ist mit @code{NOT NULL} definiert. In diesem Fall
+scannt MySQL @code{t1} und schlägt die Zeilen in @code{t2} über
+@code{t1.id} nach. Wenn MySQL eine übereinstimmende Zeile in @code{t2}
+findet, weiß er, dass @code{t2.id} nie @code{NULL} sein kann und scannt
+nicht durch den Rest der Zeilen in @code{t2}, die dieselbe @code{id} haben.
+Mit anderen Worten, für jede Zeile in @code{t1} muss MySQL nur ein einziges
+Mal in @code{t2} nachschlagen, unabhängig davon, wie viel übereinstimmende
+Zeilen es in @code{t2} gibt.
+
+@item @code{range checked for each record (index map: #)}
+MySQL hat keinen gut geeigneten Index zum Benutzen gefunden. Statt dessen
+wird er für jede Zeilenkombination in der vorherigen Tabelle eine Prüfung
+vornehmen, welchen Index er benutzen soll (falls überhaupt) und diesen
+Index benutzen, um Zeilen aus der Tabelle abzurufen. Das ist nicht sehr
+schnell, aber immer noch schneller, als einen Join ohne Index
+durchzuführen.
+
+@item Using filesort
+MySQL braucht einen zusätzlichen Durchgang, um herauszufinden, wie die
+Zeilen in sortierter Reihenfolge abgerufen werden sollen. Die Sortierung
+wird durchgeführt, indem in Abhängigkeit vom @code{join type} durch alle
+Zeilen durchgegangen wird und der Sortierschlüssel und Zeiger auf die
+Zeilen für alle Zeilen gespeichert wird, die dem @code{WHERE} entsprechen.
+Danach werden die Schlüssel sortiert. Schließlich werden die Zeilen in
+sortierter Reihenfolge abgerufen.
+
+@item Using index
+Die Spalteninformation wird aus der Tabelle abgerufen, indem nur
+Informationen aus dem Index-Baum benutzt werden, ohne dass zum Suchen
+zusätzlich in den tatsächlichen Zeilen gelesen werden muss. Das kann
+gemacht werden, wenn alle benutzten Spalten der Tabelle Teil desselben
+Indexes sind.
+
+@item Using temporary
+Um die Anfrage aufzulösen muss MySQL eine temporäre Tabelle erzeugen, die
+das Ergebnis enthält. Das passiert typischerweise, wenn Sie ein @code{ORDER
+BY} auf eine andere Spalte setzen als auf die, die Sie im @code{GROUP BY}
+angegeben haben.
+
+@item Where used
+Eine @code{WHERE}-Klausel wird benutzt, um zu begrenzen, bei welchen Zeilen
+auf Übereinstimmung in der nächsten Tabelle gesucht wird oder welche Zeilen
+an den Client geschickt werden. Wenn Sie diese Information nicht haben und
+die Tabelle vom Typ @code{ALL} oder @code{index} ast, ist vielleicht in
+Ihrer Anfrage etwas falsch (falls Sie nicht vorhaben, alle Zeilen aus der
+Tabelle zu holen / zu untersuchen).
+@end table
+
+Wenn Sie wollen, dass Ihre Anfragen so schnell wie möglich laufen, sollten
+Sie auf @code{Using filesort} und @code{Using temporary} achten.
+@end table
+
+Die verschiedenen Join-Typen sind unten aufgeführt, sortiert vom besten zum
+schlechtesten Typ:
+
+@cindex Systemtabelle
+@cindex Tabellen, System-
+@table @code
+@item system
+Die Tabelle hat nur eine Zeile (= Systemtabelle). Das ist ein spezieller
+Fall des @code{const}-Join-Typs.
+
+@cindex Konstanten-Tabelle
+@cindex Tabellen, Konstanten-
+@item const
+Die Tabelle hat höchsten eine übereinstimmende Zeile, die am Anfang der
+Anfrage gelesen werden wird. Weil es nur eine Zeile gibt, können
+Spaltenwerte in dieser Zeile vom Optimierer als Konstanten betrachtet
+werden. @code{const}-Tabellen sind sehr schnell, weil sie nur einmal
+gelesen werden!
+
+@item eq_ref
+Aus dieser Tabelle wird für jede Zeilenkombination der vorherigen Tabellen
+eine Zeile gelesen. Das ist der bestmögliche Join-Typ, ausgenommen die
+@code{const}-Typen. Er wird benutzt, wenn alle Teile eines Indexes vom Join
+benutzt werden und der Index @code{UNIQUE} oder ein @code{PRIMARY KEY} ist.
+
+@item ref
+Alle Zeilen mit übereinstimmenden Index-Werten werden für jede
+Zeilenkombination der vorherigen Tabellen gelesen. @code{ref} wird benutzt,
+wenn der Join nur das am weitesten links stehende Präfix des Schlüssels
+benutzt, oder wenn der Schlüssel nicht @code{UNIQUE} oder ein @code{PRIMARY
+KEY} ist (mit anderen Worten, wenn der Join auf der Grundlage des
+Schlüsselwerts keine einzelne Zeile auswählen kann). Wenn der Schlüssel,
+der benutzt wird, nur mit einigen wenigen Zeilen übereinstimmt, ist dieser
+Join-Typ gut.
+
+@item range
+Nur Zeilen, die innerhalb eines angegebenen Bereichs sind, werden abrufen,
+wobei ein Index benutzt wird, um die Zeilen auszuwählen. Die
+@code{key}-Spalte gibt an, welcher Index benutzt wird. @code{key_len}
+enthält den längsten Schlüsselteil, der benutzt wurde. Die
+@code{ref}-Spalte ist für diesen Typ NULL.
+
+@item index
+Das ist dasselbe wie @code{ALL}, ausser dass nur der Index-Baum gescannt
+wird. Das ist üblicherweise schneller als @code{ALL}, weil die Index-Datei
+üblicherweise kleiner ist als die Daten-Datei.
+
+@item ALL
+Für jede Zeilenkombination der vorherigen Tabellen wird ein kompletter
+Tabellenscan durchgeführt. Das ist normalerweise nicht gut, wenn die
+Tabelle die erste Tabelle ist, die nicht als @code{const} gekennzeichnet
+ist, und üblicherweise @strong{sehr} schlecht in allen anderen Fällen. Sie
+können @code{ALL} normalerweise vermeiden, indem Sie mehr Indexe
+hinzufügen, so dass die Zeile auf der Grundlage der Konstanten-Werte oder
+Spaltenwerte von früheren Tabellen abgerufen werden kann.
+@end table
+
+Sie erhalten einen guten Anhaltspunkt, wie gut ein Join ist, wenn Sie alle
+Werte in der @code{rows}-Spalte der @code{EXPLAIN}-Ausgabe multiplizieren.
+Das sollte grob aussagen, wie vielen Zeilen MySQL untersuchen muss, um die
+Anfrage auszuführen. Diese Anzahl wird auch benutzt, wenn Sie Anfragen mit
+der @code{max_join_size}-Variablen begrenzen.
+@xref{Server parameters}.
+
+Das folgende Beispiel zeigt, wie ein @code{JOIN} progressiv optimiert
+werden kann, indem die Informationen genutzt werden, die @code{EXPLAIN}
+bereit stellt.
+
+Angenommen, Sie haben unten stehendes @code{SELECT}-Statement, das Sie mit
+@code{EXPLAIN} untersuchen:
+
+@example
+EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
+ tt.ProjectReference, tt.EstimatedShipDate,
+ tt.ActualShipDate, tt.ClientID,
+ tt.ServiceCodes, tt.RepetitiveID,
+ tt.CurrentProcess, tt.CurrentDPPerson,
+ tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
+ et_1.COUNTRY, do.CUSTNAME
+ FROM tt, et, et AS et_1, do
+ WHERE tt.SubmitTime IS NULL
+ AND tt.ActualPC = et.EMPLOYID
+ AND tt.AssignedPC = et_1.EMPLOYID
+ AND tt.ClientID = do.CUSTNMBR;
+@end example
+
+Nehmen wir bei diesem Beispiel folgendes an:
+
+@itemize @bullet
+@item
+Die Spalten, die verglichen werden, wurden wie folgt deklariert:
+
+@multitable @columnfractions .1 .2 .7
+@item @strong{Tabelle} @tab @strong{Spalte} @tab @strong{Spaltentyp}
+@item @code{tt} @tab @code{ActualPC} @tab @code{CHAR(10)}
+@item @code{tt} @tab @code{AssignedPC} @tab @code{CHAR(10)}
+@item @code{tt} @tab @code{ClientID} @tab @code{CHAR(10)}
+@item @code{et} @tab @code{EMPLOYID} @tab @code{CHAR(15)}
+@item @code{do} @tab @code{CUSTNMBR} @tab @code{CHAR(15)}
+@end multitable
+
+@item
+Die Tabellen haben die unten stehenden Indexe:
+
+@multitable @columnfractions .1 .9
+@item @strong{Tabelle} @tab @strong{Index}
+@item @code{tt} @tab @code{ActualPC}
+@item @code{tt} @tab @code{AssignedPC}
+@item @code{tt} @tab @code{ClientID}
+@item @code{et} @tab @code{EMPLOYID} (primary key)
+@item @code{do} @tab @code{CUSTNMBR} (primary key)
+@end multitable
+
+@item
+Die @code{tt.ActualPC}-Werte sind nicht gleichmäßig verteilt.
+@end itemize
+
+Anfangs, bevor die Optimierung durchgeführt wurde, ergab das
+@code{EXPLAIN}-Statement folgende Informationen:
+
+@example
+table type possible_keys key key_len ref rows Extra
+et ALL PRIMARY NULL NULL NULL 74
+do ALL PRIMARY NULL NULL NULL 2135
+et_1 ALL PRIMARY NULL NULL NULL 74
+tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872
+ range checked for each record (key map: 35)
+@end example
+
+Weil @code{type} bei jeder Tabelle @code{ALL} ist, zeigt die Ausgabe, dass
+MySQL eine komplette Verknüpfung (Full Join) aller Tabellen durchführt! Das
+dauert recht lange, weil das Produkt der Zeilenanzahl in jeder Tabelle
+untersucht werden muss! In diesem Fall ist das @code{74 * 2.135 * 74 *
+3.872 = 45.268.558.720} Zeilen. Wenn die Tabellen größer wären, können Sie
+sich vorstellen, wie lange das dauern würde.
+
+Ein Problem liegt hier darin, dass MySQL (noch) keine Indexe auf Spalten
+effizient benutzen kann, wenn sie unterschiedlich deklariert sind. In
+diesem Zusammenhang sind @code{VARCHAR} und @code{CHAR} dasselbe, es sei
+denn, sie sind mit unterschiedlichen Längen deklariert. Weil
+@code{tt.ActualPC} als @code{CHAR(10)} und @code{et.EMPLOYID} als
+@code{CHAR(15)} deklariert ist, gibt eine Unstimmigkeit der Längen.
+
+Um diese Ungleichheit der Spaltenlängen zu beheben, benutzen Sie
+@code{ALTER TABLE}, um @code{ActualPC} von 10 auf 15 Zeichen zu verlängern:
+
+@example
+mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);
+@end example
+
+Jetzt sind @code{tt.ActualPC} und @code{et.EMPLOYID} beide
+@code{VARCHAR(15)}. Eine erneute Ausführung des @code{EXPLAIN}-Statements
+ergibt dieses Ergebnis:
+
+@example
+table type possible_keys key key_len rew rows Extra
+tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used
+do ALL PRIMARY NULL NULL NULL 2135
+ range checked for each record (key map: 1)
+et_1 ALL PRIMARY NULL NULL NULL 74
+ range checked for each record (key map: 1)
+et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
+@end example
+
+Das ist nicht perfekt, aber viel besser (das Produkt der @code{rows}-Werte
+ist jetzt um einen Faktor 74 niedriger). Diese Version wird innerhalb von
+ein paar Sekunden ausgeführt.
+
+Eine zweite Änderung kann durchgeführt werden, um die Unstimmigkeit der
+Spaltenlängen für die @code{tt.AssignedPC = et_1.EMPLOYID}- und
+@code{tt.ClientID = do.CUSTNMBR}-Vergleiche zu beheben:
+
+@example
+mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
+ MODIFY ClientID VARCHAR(15);
+@end example
+
+Jetzt ergibt @code{EXPLAIN} folgende Ausgabe:
+
+@example
+table type possible_keys key key_len rew rows Extra
+et ALL PRIMARY NULL NULL NULL 74
+tt rew AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
+et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
+do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
+@end example
+
+Das ist fast so gut, wie es überhaupt geht.
+
+Das verbleibende Problem besteht darin, dass MySQL vorgabemäßig annimmt,
+dass die Werte in der @code{tt.ActualPC}-Spalte gleichmäßig verteilt sind,
+was in der @code{tt}-Tabelle nicht der Fall ist. Glücklicherweise ist es
+einfach, MySQL darüber zu informieren:
+
+@example
+shell> myisamchk --analyze PFAD_ZU_MYSQL_DATENBANK/tt
+shell> mysqladmin refresh
+@end example
+
+Jetzt ist der Join perfekt und @code{EXPLAIN} ergibt dieses Ergebnis:
+
+@example
+table type possible_keys key key_len ref rows Extra
+tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used
+et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
+et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
+do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
+@end example
+
+Beachten Sie, dass die @code{rows}-Spalte in der Ausgabe von @code{EXPLAIN}
+eine gehobene Form von Vermutung des MySQL-Join-Optimierers ist. Um eine
+Anfrage zu optimieren, sollten Sie überprüfen, ob diese Zahlen der Wahrheit
+nahe kommen. Wenn nicht, erhalten Sie eventuell bessere Performance, wenn
+Sie @code{STRAIGHT_JOIN} in Ihrem @code{SELECT}-Statement benutzen und
+versuchen, die Tabellen in der @code{FROM}-Klausel in anderer Reihenfolge
+anzugeben.
+
+
+@node Estimating performance, SELECT speed, EXPLAIN, Query Speed
+@c German node Performance abschätzen
+@subsection Anfragen-Performance abschätzen
+
+@cindex abschätzen, Anfragen-Performance
+@cindex Anfragen, Performance abschätzen
+@cindex Performance, abschätzen
+
+In den meisten Fällen können Sie die Performance schätzen, indem Sie
+Suchvorgänge auf Festplatte zählen. Bei kleinen Tabellen können Sie die
+Zeile üblicherweise mit 1 Festplatten-Suchvorgang finden (weil der Index
+wahrscheinlich im Cache ist). Bei größeren Tabellen können Sie schätzen,
+dass Sie (bei der Benutzung von B++-Baum-Indexen) brauchen werden:
+@code{log(zeilen_zahl) / log(index_block_laenge / 3 * 2 / (index_laenge +
+daten_zeiger_laenge)) + 1} Suchvorgänge, um die Zeile zu finden.
+
+In MySQL ist ein Index-Block üblicherweise 1024 Bytes lang und der
+Daten-Zeiger üblicherweise 4 Bytes. Eine 500.000-Zeilen-Tabelle mit einer
+Indexlänge von 3 (medium integer) ergibt:
+@code{log(500.000)/log(1024/3*2/(3+4)) + 1} = 4 Suchvorgänge.
+
+Da der obige Index etwa 500.000 * 7 * 3/2 = 5,2 MB benötigen würde
+(angenommen, dass die Index-Puffer zu 2/3 gefüllt sind, was ein typischer
+Wert sit), haben Sie wahrscheinlich viel vom Index im Arbeitsspeicher und
+werden wahrscheinlich nur 1 bis 2 Betriebssystem-Aufrufe benötigen, um
+Daten zu lesen, um die Zeile zu finden.
+
+Bei Schreibvorgängen brauchen Sie jedoch 4 Suchanfragen (wie oben), um
+herauszufinden, wo der neue Index platziert wird, und normalerweise 2
+Suchvorgänge, um den Index zu aktualisieren und die Zeile zu schreiben.
+
+Beachten Sie, dass oben Gesagtes nicht bedeutet, dass Ihre Applikation
+allmählich mit N log N verfällt! Solange alles durch das Betriebssystem
+oder den SQL-Server gecachet wird, werden die Dinge nur marginal langsamer,
+wenn die Tabellen größer werden. Wenn die Daten zu Groß werden, um
+gecachet zu werden, werden die Dinge anfangen, viel langsamer zu laufen,
+bis Ihre Applikation schließlich komplett durch Suchvorgänge auf
+Festplatte ausgebremst wird (die mit N log N zunehmen). Um das zu
+vermeiden, vergrößern Sie den Index-Cache, wenn die Daten wachsen.
+@xref{Server parameters}.
+
+
+@node SELECT speed, Where optimisations, Estimating performance, Query Speed
+@c German node SELECT-Geschwindigkeit
+@subsection Geschwindigkeit von @code{SELECT}-Anfragen
+
+@findex SELECT-Geschwindigkeit
+
+@cindex Geschwindigkeit, von Anfragen
+
+Wenn Sie ein langsames @code{SELECT ... WHERE} schneller machen wollen, ist
+im Allgemeinen das erste, was zu prüfen ist, ob Sie einen Index hinzufügen
+können oder nicht. @xref{MySQL indexes, , MySQL-Indexe}. Alle Verweise
+(Reference) zwischen verschiedenen Tabellen sollten üblicherweise mit
+Indexen gemacht werden. Sie können den @code{EXPLAIN}-Befehl benutzen, um
+herauszufinden, welche Indexe für ein @code{SELECT} benutzt werden.
+@xref{EXPLAIN, , @code{EXPLAIN}}.
+
+Einige allgemeine Tipps:
+
+@itemize @bullet
+@item
+Um MySQL zu helfen, Anfragen besser zu optimieren, lassen Sie
+@code{myisamchk --analyze} auf eine Tabelle laufen, nachdem sie mit
+relevanten Daten gefüllt wurde. Das aktualisiert einen Wert für jeden
+Index-Teil, der die durchschnittliche Anzahl von Zeilen angibt, die
+denselben Wert haben. (Bei eindeutigen Indexen ist das natürlich immer 1).
+MySQL benutzt diesen Wert, um zu entscheiden, welcher Index benutzt werden
+soll, wenn Sie zwei Tabellen mit einem 'nicht konstanten Ausdruck'
+verbinden. Sie können das Ergebnis nach dem Laufenlassen von @code{analyze}
+mit @code{SHOW INDEX FROM tabelle} überprüfen und die
+@code{Cardinality}-Spalte untersuchen.
+
+@item
+Um einen Index und Daten gemäß einem Index zu sortieren, benutzen Sie
+@code{myisamchk --sort-index --sort-records=1} (wenn Sie nach Index 1
+sortieren wollen). Wenn Sie einen eindeutigen Index haben, von dem Sie alle
+Datensätze gemäß der Reihenfolge dieses Indexes lesen wollen, ist das eine
+gute Art, das schneller zu machen. Beachten Sie jedoch, dieses Sortieren
+nicht optimal geschrieben wird und bei einer großen Tabelle lange dauert!
+@end itemize
+
+
+@node Where optimisations, DISTINCT optimisation, SELECT speed, Query Speed
+@c German node WHERE-Optimierung
+@subsection Wie MySQL @code{WHERE}-Klauseln optimiert
+
+@findex WHERE
+
+@cindex Optimierungen
+
+Die @code{WHERE}-Optimierungen wurden hier in den @code{SELECT}-Teil
+aufgenommen, weil sie meist in Verbindung mit @code{SELECT} benutzt werden,
+aber dieselben Optimierungen treffen für @code{WHERE} bei @code{DELETE}-
+und @code{UPDATE}-Statements zu.
+
+Beachten Sie auch, dass dieser Abschnitt nicht vollständig ist. MySQL führt
+viele Optimierungen durch und wir hatten noch keine Zeit, alle davon zu
+dokumentieren.
+
+Einige der Optimierungen, die MySQL durchführt, sind unten aufgeführt:
+
+@itemize @bullet
+@item
+Entfernung unnötiger Klammern:
+@example
+ ((a AND b) AND c OR (((a AND b) AND (c AND d))))
+-> (a AND b AND c) OR (a AND b AND c AND d)
+@end example
+@item
+Konstanten-'Falten' (Folding):
+@example
+ (a<b AND b=c) AND a=5
+-> b>5 AND b=c AND a=5
+@end example
+@item
+Bedingungsentfernung bei Konstanten (notwendig wegen Konstanten-'Falten'):
+@example
+ (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
+-> B=5 OR B=6
+@end example
+@item
+Konstante Ausdrücke, die von Indexen benutzt werden, werden nur einmal
+ausgewertet.
+@item
+@code{COUNT(*)} auf eine einzelne Tabelle ohne ein @code{WHERE} wird direkt
+aus der Tabelleninformation abgerufen. Das wird auch bei jeglichen
+@code{NOT NULL}-Ausdrücken gemacht, wenn diese nur für eine Tabelle benutzt
+werden.
+@item
+Früherkennung ungültiger Konstanten-Ausdrücke. MySQL stellt schnell fest,
+dass einige @code{SELECT}-Statements unmöglich sind, und gibt keine Zeilen
+zurück.
+@item
+@code{HAVING} wird mit @code{WHERE} vereinigt, wenn Sie @code{GROUP BY}
+oder Gruppen-Funktionen (@code{COUNT()}, @code{MIN()} usw.) nicht
+benutzen.
+@item
+Für jeden Sub-Join wird ein einfacheres @code{WHERE} konstruiert, um eine
+schnelle @code{WHERE}-Evaluierung für jeden Sub-Join zu erzielen, und auch,
+um Datensätze so bald wie möglich überspringen zu können.
+@cindex Konstanten-Tabelle
+@cindex Tabellen, Konstanten-
+@item
+Alle Konstanten-Tabellen werden zuerst gelesen, vor jeder anderen Tabelle
+in der Anfrage. Eine Konstanten-Tabelle ist:
+@itemize @minus
+@item
+Eine leere Tabelle oder eine Tabelle mit 1 Zeile.
+@item
+Eine Tabelle, die bei einer @code{WHERE}-Klausel auf einen
+@code{UNIQUE}-Index oder einen @code{PRIMARY KEY} benutzt wird, wobei alle
+Index-Teile mit konstanten Ausdrücken benutzt werden und die Index-Teile
+als @code{NOT NULL} definiert sind.
+@end itemize
+Alle folgenden Tabellen werden als Konstanten-Tabellen benutzt:
+@example
+mysql> SELECT * FROM t WHERE primary_key=1;
+mysql> SELECT * FROM t1,t2
+ WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
+@end example
+
+@item
+Die beste Join-Kombination, um Tabellen zu verknüpfen, wird gefunden, wenn
+man alle Möglichkeiten probiert. Wenn alle Spalten in @code{ORDER BY} und
+in @code{GROUP BY} aus derselben Tabelle stammen, wird diese Tabelle
+vorzugsweise vorn hingestellt, wenn verknüpft wird.
+@item
+Wenn es eine @code{ORDER BY}-Klausel und eine andere @code{GROUP
+BY}-Klausel gibt, oder wenn @code{ORDER BY} oder @code{GROUP BY} Spalten
+aus Tabellen enthält, die nicht aus der ersten Tabelle in der Join-Reihe
+stammen, wird eine temporäre Tabelle erzeugt.
+@item
+Wenn Sie @code{SQL_SMALL_RESULT} benutzen, benutzt MySQL eine temporäre
+Tabelle im Arbeitsspeicher.
+@item
+Jeder Tabellen-Index wird abgefragt und der beste Index, der weniger als
+30% der Zeilen überspannt, wird benutzt. Wenn ein solcher Index nicht
+gefunden werden kann, wird ein schneller Tabellenscan benutzt.
+@item
+In einigen Fällen kann MySQL Zeilen vom Index lesen, ohne überhaupt in der
+Daten-Datei nachzuschlagen. Wenn alle Spalten, die vom Index benutzt
+werden, numerisch sind, wird nur der Index-Baum benutzt, um die Anfrage
+aufzulösen.
+@item
+Bevor jeder Datensatz herausgegeben wird, werden die, die nicht mit der
+@code{HAVING}-Klausel übereinstimmen, übersprungen.
+@end itemize
+
+Einige Beispiele von Anfragen, die sehr schnell sind:
+
+@example
+mysql> SELECT COUNT(*) FROM tabelle;
+mysql> SELECT MIN(schluessel_teil1),MAX(schluessel_teil1) FROM tabelle;
+mysql> SELECT MAX(schluessel_teil2) FROM tabelle
+ WHERE schluessel_teil_1=konstante;
+mysql> SELECT ... FROM tabelle
+ ORDER BY schluessel_teil1,schluessel_teil2,... LIMIT 10;
+mysql> SELECT ... FROM tabelle
+ ORDER BY schluessel_teil1 DESC,schluessel_teil2 DESC,... LIMIT 10;
+@end example
+
+Die folgenden Anfragen werden aufgelöst, indem nur der Index-Baum benutzt
+wird (unter der Annahme, dass die indizierten Spalten numerisch sind):
+
+@example
+mysql> SELECT schluessel_teil1,schluessel_teil2 FROM tabelle WHERE schluessel_teil1=val;
+mysql> SELECT COUNT(*) FROM tabelle
+ WHERE schluessel_teil1=val1 AND schluessel_teil2=val2;
+mysql> SELECT schluessel_teil2 FROM tabelle GROUP BY schluessel_teil1;
+@end example
+
+Die folgenden Anfragen benutzen Indexierung, um die Zeilen in sortierter
+Reihenfolge abzufragen, ohne einen separaten Sortierdurchgang:
+
+@example
+mysql> SELECT ... FROM tabelle ORDER BY schluessel_teil1,schluessel_teil2,... ;
+mysql> SELECT ... FROM tabelle ORDER BY schluessel_teil1 DESC,schluessel_teil2 DESC,... ;
+@end example
+
+
+@node DISTINCT optimisation, LEFT JOIN optimisation, Where optimisations, Query Speed
+@c German node DISTINCT-Optimierung
+@subsection Wie MySQL @code{DISTINCT} optimiert
+
+@findex DISTINCT
+
+@cindex Optimierung, DISTINCT
+
+@code{DISTINCT} wird für alle Spalten in @code{GROUP BY} umgewandelt,
+@code{DISTINCT} in Kombination mit @code{ORDER BY} benötigt in vielen
+Fällen ebenfalls eine temporäre Tabelle.
+
+Wenn @code{LIMIT #} mit @code{DISTINCT} kombiniert wird, hält MySQL an,
+sobald er @code{#} eindeutige Zeilen findet.
+
+Wenn Sie nicht Spalten aus allen benutzten Tabellen verwenden, hält MySQL
+mit dem Scannen der nicht benutzten Tabellen an, sobald er die erste
+Übereinstimmung gefunden hat.
+
+@example
+SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
+@end example
+
+Im Beispiel wird angenommen, dass t1 vor t2 benutzt wird (überprüfen Sie
+das mit @code{EXPLAIN}). In diesem Fall hört MySQL auf, von t2 zu lesen
+(für diese bestimmte Zeile in t1), sobald die erste Zeile in t2 gefunden
+wurde.
+
+
+@node LEFT JOIN optimisation, LIMIT optimisation, DISTINCT optimisation, Query Speed
+@c German node LEFT-JOIN-Optimierung
+@subsection Wie MySQL @code{LEFT JOIN} optimiert
+
+@findex LEFT JOIN
+
+@cindex Optimierung, LEFT JOIN
+
+@code{A LEFT JOIN B} ist in MySQL wie folgt implementiert:
+
+@itemize @bullet
+@item
+Die Tabelle @code{B} wird als abhängig von Tabelle @code{A} und allen
+Tabellen, von denen @code{A} abhängig ist, gesetzt.
+
+@item
+Die Tabelle @code{A} wird als abhängig von allen Tabellen (ausser @code{B})
+gesetzt, die in der @code{LEFT JOIN}-Bedingung aufgeführt sind.
+
+@item
+Alle @code{LEFT JOIN}-Bedingungen werden zu @code{WHERE}-Klausel
+verschoben.
+
+@item
+Alle Standard-Join-Optimierungen werden durchgeführt, mit der Ausnahme,
+dass eine Tabelle immer nach allen Tabellen gelesen wird, von denen sie
+abhängig ist. Wenn es eine zirkuläre Abhängigkeit gibt, gibt MySQL einen
+Fehler aus.
+
+@item
+Alle Standard-@code{WHERE}-Optimierungen werden durchgeführt.
+
+@item
+Wenn es eine Zeile in @code{A} gibt, die mit der @code{WHERE}-Klausel
+übereinstimmt, aber keine Zeile in @code{B}, die mit der @code{LEFT
+JOIN}-Bedingung übereinstimmt, wird eine zusätzliche Zeile für @code{B}
+erzeugt, deren Spalten alle auf @code{NULL} gesetzt sind.
+
+@item
+Wenn Sie @code{LEFT JOIN} benutzen, um Zeilen zu finden, die in einer
+Tabelle nicht existieren, und Sie folgendes im @code{WHERE}-Teil angeben:
+@code{spalten_name IS NULL}, wobei spalten_name eine Spalte ist, die als
+@code{NOT NULL} deklariert ist, hört MySQL mit der Suche nach weiteren
+Zeilen auf (für eine bestimmte Schlüsselkombination), nachdem er eine Zeile
+gefunden hat, die mit der @code{LEFT JOIN}-Bedingung übereinstimmt.
+@end itemize
+
+@code{RIGHT JOIN} ist analog zu @code{LEFT JOIN} implementiert.
+
+Die Lese-Reihenfolge der Tabellen, die von @code{LEFT JOIN} und
+@code{STRAIGHT JOIN} erzwungen wird, hilft dem Optimierer (der berechnet,
+in welcher Reihenfolge die Tabellen verknüpft werden sollen), seine Arbeit
+schneller durchzuführen, weil weniger Tabellenvertauschungen überprüft
+werden müssen.
+
+Beachten Sie, dass das oben Gesagte bedeutet, dass bei einer Anfrage des
+folgenden Typs:
+
+@example
+SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
+@end example
+
+MySQL einen kompletten Scan von @code{b} durchführen wird, weil der
+@code{LEFT JOIN} erzwingt, dass diese vor @code{d} gelesen wird.
+
+Das läßt sich in diesem Fall beheben, indem die Anfrage wie folgt geändert
+wird:
+
+@example
+SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
+@end example
+
+
+@node LIMIT optimisation, Insert speed, LEFT JOIN optimisation, Query Speed
+@c German node LIMIT-Optimierung
+@subsection Wie MySQL @code{LIMIT} optimiert
+
+@findex LIMIT
+
+@cindex Optimierung, LIMIT
+
+In einigen Fällen handhabt MySQL die Anfrage unterschiedlich, wenn Sie
+@code{LIMIT #} statt @code{HAVING} benutzen:
+
+@itemize @bullet
+@item
+Wenn Sie nur einige wenige Zeilen mit @code{LIMIT} auswählen, benutzt MySQL
+in einigen Fällen Indexe, wenn er ansonsten vorzugsweise einen
+vollständigen Tabellenscan durchführen würde.
+@item
+Wenn Sie @code{LIMIT #} mit @code{ORDER BY} benutzen, beendet MySQL das
+Sortieren, sobald er die ersten @code{#} Zeilen gefunden hat, anstatt die
+gesamte Tabelle zu sortieren.
+@item
+Wenn Sie @code{LIMIT #} mit @code{DISTINCT} kombinieren, hört MySQL auf,
+sobald er @code{#} eindeutige Zeilen gefunden hat.
+@item
+In einigen Fällen kann @code{GROUP BY} aufgelöst werden, indem der
+Schlüssel in der Reihenfolge gelesen wird (oder der Schlüssel sortiert
+wird) und danach Zusammenfassungen berechnet werden, bis sich der
+Schlüsselwert ändert. In diesem Fall berechnet @code{LIMIT #} keine
+unnötigen @code{GROUP BY}'s.
+@item
+Sobald MySQL die ersten @code{#} Zeilen an den Client geschickt hat, wird
+die Anfrage abgebrochen.
+@item
+@code{LIMIT 0} gibt immer schnell eine leere Ergebnismenge (empty set)
+zurück. Das ist nützlich, um die Anfrage zu überprüfen und die Spaltentypen
+der Ergebnisspalten zu erhalten.
+@item
+Die Größe der temporären Tabellen benutzt @code{LIMIT #}, um zu berechnen,
+wieviel Platz benötigt wird, um die Anfrage aufzulösen.
+@end itemize
+
+
+@node Insert speed, Update speed, LIMIT optimisation, Query Speed
+@c German node INSERT-Geschwindigkeit
+@subsection Geschwindigkeit von @code{INSERT}-Anfragen
+
+@findex INSERT
+
+@cindex Geschwindigkeit, beim Einfügen
+@cindex Einfügen, Geschwindigkeit
+
+Die Zeit, einen Datensatz einzufügen, besteht ungefähr aus:
+
+@itemize @bullet
+@item
+Verbindung: (3)
+@item
+Anfrage an den Server schicken: (2)
+@item
+Anfrage parsen: (2)
+@item
+Datensatz einfügen: (1 x Größe des Datensatzes)
+@item
+Indexe einfügen: (1 x Anzahl der Indexe)
+@item
+Schließen: (1)
+@end itemize
+
+Wobei die Zahlen in etwa proportional zur Gesamtzeit sind. Diese Berechnung
+zieht den anfänglichen Overhead, um Tabellen zu öffnen, nicht in Betracht
+(was einmal für jede gleichzeitig laufende Anfrage gemacht wird).
+
+Die Größe der Tabelle verlangsamt das Einfügen von Indexen um N log N
+(B-Bäume).
+
+Einige Möglichkeiten, die Geschwindigkeit von Einfügeoperationen zu
+steigern:
+
+@itemize @bullet
+@item
+Wenn Sie viele Zeilen vom selben Client aus zur gleichen Zeit einfügen,
+benutzen Sie mehrfache Werte (Liste) im @code{INSERT}-Statements. Das geht
+viel schneller (in manchen Fälle um Faktoren) als separate
+@code{INSERT}-Statements zu benutzen. Tunen Sie die
+@code{myisam_bulk_insert_tree_size}-Variable, um das sogar noch zu
+beschleunigen. @xref{SHOW VARIABLES}.
+@item
+Wenn Sie viele Zeilen von unterschiedlichen Clients aus einfügen, können
+Sie mehr Geschwindigkeit erzielen, wenn Sie das @code{INSERT
+DELAYED}-Statement benutzen. @xref{INSERT, , @code{INSERT}}.
+@item
+Beachten Sie, dass Sie mit @code{MyISAM}-Tabellen Zeilen zur selben Zeit
+einfügen können, zu der @code{SELECT}s laufen, wenn es keine gelöschten
+Zeilen in den Tabellen gibt.
+@item
+Wenn Daten in eine Tabelle aus einer Textdatei eingeladen werden, benutzen
+Sie @code{LOAD DATA INFILE}. Das ist üblicherweise 20 mal schneller als
+viele @code{INSERT}-Statements zu benutzen. @xref{LOAD DATA, , @code{LOAD DATA}}.
+@item
+Mit etwas zusätzlicher Mühe ist es möglich, @code{LOAD DATA INFILE} noch
+schneller laufen zu lassen, wenn die Tabelle viele Indexe hat. Gehen Sie
+wie folgt vor:
+
+@enumerate
+@item
+Optional erzeugen Sie die Tabelle mit @code{CREATE TABLE}, zum Beispiel mit
+@code{mysql} oder über die Perl-DBI.
+
+@item
+Führen Sie ein @code{FLUSH TABLES}-Statement oder den Shell-Befehl
+@code{mysqladmin flush-tables} aus.
+
+@item
+Geben Sie @code{myisamchk --keys-used=0 -rq /pfad/zu/db/tabelle} ein.
+Dadurch entfernen Sie die Benutzung aller Indexe von der Tabelle.
+
+@item
+Fügen Sie Daten in die Tabelle mit @code{LOAD DATA INFILE} ein. Dadurch
+werden keine Indexe aktualisiert, was deswegen sehr schnell läuft.
+
+@item
+Wenn Sie in Zukunft nur noch aus der Tabelle lesen, benutzen Sie
+@code{myisampack}, um sie kleiner zu machen. @xref{Compressed format}.
+
+@item
+Erzeugen Sie die Indexe mit @code{myisamchk -r -q /pfad/zu/db/tabelle} neu.
+Hierdurch wird der Index-Baum im Speicher erzeugt, bevor er auf die Platte
+geschrieben wird, was viel schneller ist, weil viele Suchvorgänge auf
+Platte vermieden werden. Der sich ergebende Index-Baum ist ausserdem
+perfekt ausbalanciert.
+
+@item
+Führen Sie ein @code{FLUSH TABLES}-Statement oder den Shell-Befehl
+@code{mysqladmin flush-tables} aus.
+@end enumerate
+
+Diese Prozedur wird in Zukunft in @code{LOAD DATA INFILE} eingebaut werden.
+
+Ab @strong{MySQL 4.0} können Sie auch @code{ALTER TABLE tabelle DISABLE
+KEYS} anstelle von @code{myisamchk --keys-used=0 -rq /pfad/zu/db/tabelle}
+und @code{ALTER TABLE tabelle ENABLE KEYS} anstelle von @code{myisamchk -r
+-q /pfad/zu/db/tabelle} benutzen. Damit können Sie auch die @code{FLUSH
+TABLES}-Schritte überspringen.
+@item
+Sie können die Einfügegeschwindigkeit steigern, indem Sie Tabellen sperren:
+
+@example
+mysql> LOCK TABLES a WRITE;
+mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33);
+mysql> INSERT INTO a VALUES (8,26),(6,29);
+mysql> UNLOCK TABLES;
+@end example
+
+Der hauptsächliche Geschwindigkeitsunterschied liegt darin, dass der
+Index-Puffer nur einmal auf Platte zurück geschrieben wird, nachdem alle
+@code{INSERT}-Statements fertig sind. Normalerweise würden die Index-Puffer
+so oft zurück geschrieben wie es @code{INSERT}-Statements gibt. Das Sperren
+wird nicht benötigt, wenn Sie alle Zeilen mit einem einzigen Statement
+einfügen können.
+
+Durch das Sperren wird auch die Gesamtzeit von Tests auf mehrere
+Verbindungen gesenkt, aber die maximale Wartezeit für einige Threads wird
+erhöht (weil sie auf Sperren warten). Beispiel:
+
+@example
+Thread 1 führt 1000 Einfügevorgänge durch.
+Thread 2, 3 und 4 fügen 1 Einfügevorgang durch.
+Thread 5 führt 1000 Einfügevorgänge durch.
+@end example
+
+Wenn Sie kein Sperren benutzen, sind die Threads 2, 3 und 4 vor 1 und 5
+fertig. Wenn Sie Sperren benutzen, sind 2, 3 und 4 wahrscheinlich nicht vor
+1 oder 5 fertig, aber die Gesamtzeit sollte etwa 40% geringer sein.
+
+Weil @code{INSERT}-, @code{UPDATE}- und @code{DELETE}-Operationen in MySQL
+sehr schnell sind, erhalten Sie bessere Performance über alles, wenn Sie um
+alles herum Sperren hinzufügen, was mehr als etwa 5 Einfügeoperationen oder
+Aktualisierungen (Updates) in einer Zeile durchführt. Wenn Sie sehr viele
+Einfügeoperationen in einer Zeile durchführen, können Sie ein @code{LOCK
+TABLES} machen, gefolgt von einem gelegentlichen @code{UNLOCK TABLES}
+(etwa alle 1.000 Zeilen), um anderen Threads zu gestatten, auf die Tabelle
+zuzugreifen. Das Ergebnis wäre ebenfalls ein netter Geschwindigkeitsgewinn.
+
+Natürlich ist @code{LOAD DATA INFILE} zum Einladen von Daten viel
+schneller.
+@end itemize
+
+Um sowohl für @code{LOAD DATA INFILE} als auch für @code{INSERT} mehr
+Geschwindigkeit zu erzielen, vergrößern Sie den Schlüssel-Puffer.
+@xref{Server parameters}.
+
+
+@node Update speed, Delete speed, Insert speed, Query Speed
+@c German node UPDATE-Geschwindigkeit
+@subsection Geschwindigkeit von @code{UPDATE}-Anfragen
+
+Update-Anfragen werden wie eine @code{SELECT}-Anfrage optimiert, mit dem
+zusätzlichen Overhead eines Schreibvorgangs. Die Geschwindigkeit des
+Schreibvorgangs hängt von der Größe der Daten und von der Anzahl der
+Indexe, die aktualisiert werden, ab. Indexe, die nicht geändert werden,
+werden nicht aktualisiert.
+
+Eine weitere Möglichkeit, Aktualisierungen (Updates) schnell zu machen,
+ist, sie zu verzögern und dann später viele Aktualisierungen hintereinander
+zu machen. Viele Aktualisierungen hintereinander sind viel schneller als
+nur eine zugleich, wenn Sie die Tabelle sperren.
+
+Beachten Sie, dass die Aktualisierung eines Datensatzes bei dynamischem
+Datensatzformat dazu führen kann, dass der Datensatz aufgespalten wird.
+Wenn Sie das oft durchführen, ist es daher sehr wichtig, gelegentlich
+@code{OPTIMIZE TABLE} auszuführen. @xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.
+
+
+@node Delete speed, Tips, Update speed, Query Speed
+@c German node DELETE-Geschwindigkeit
+@subsection Geschwindigkeit von @code{DELETE}-Anfragen
+
+Wenn Sie alle Zeilen in der Tabelle löschen wollen, sollten Sie
+@code{TRUNCATE TABLE tabelle} benutzen. @xref{TRUNCATE}.
+
+Die Zeit, die für das Löschen eines Datensatzes benötigt wird, ist exakt
+proportional zur Anzahl der Indexe. Um Datensätze schneller zu löschen,
+können Sie die Größe des Index-Caches herauf setzen.
+@xref{Server parameters}.
+
+
+@node Tips, , Delete speed, Query Speed
+@c German node Tipps
+@subsection Weitere Optimierungstipps
+
+@cindex Optimierung, Tipps
+@cindex Tipps, Optimierung
+
+Ungeordnete Liste von Tipps für schnellere Systeme:
+
+@itemize @bullet
+@item
+Benutzen Sie persistente Verbindungen zur Datenbank, um
+Verbindungs-Overhead zu vermeiden. Wenn Sie keine persistenten Verbindungen
+benutzen können und viele neue Verbindungen zur Datenbank aufmachen,
+sollten Sie den Wert der @code{Thread_cache_size}-Variablen ändern.
+@xref{Server parameters}.
+@item
+Überprüfen Sie immer, dass alle Ihre Anfragen tatsächlich die Indexe
+benutzen, die Sie in den Tabellen erzeugt haben. In MySQL kann man das mit
+dem @code{EXPLAIN}-Befehl tun. @xref{EXPLAIN, Explain, Explain, Handbuch}.
+@item
+Versuchen Sie, komplexe @code{SELECT}-Anfragen auf Tabellen zu vermeiden,
+die viel aktualisiert werden, um Probleme mit Tabellensperren zu vermeiden.
+@item
+Die neuen @code{MyISAM}-Tabellen können Zeilen in eine Tabelle ohne
+gelöschte Zeile zur gleichen Zeit einfügen, wie eine andere Tabelle aus ihr
+liest. Wenn das für Sie wichtig ist, sollten Sie Methoden in Betracht
+ziehen, bei denen Sie keine Zeilen löschen müssen, oder @code{OPTIMIZE
+TABLE} laufen lassen, nachdem Sie viele Zeilen gelöscht haben.
+@item
+Benutzen Sie @code{ALTER TABLE ... ORDER BY ausdruck1,ausdruck2,...}, wenn
+Sie Zeilen zumeist in der Reihenfolge ausdruck1,ausdruck2,... abrufen. Wenn
+Sie diese Option nach großen Änderungen in der Tabelle nutzen, erzielen
+Sie eventuell höhere Performance.
+@item
+In einigen Fällen kann es sinnvoll sein, eine Spalte einzuführen, die auf
+der Grundlage von Informationen aus anderen Spalten 'gehashed' ist. Wenn
+diese Spalte kurz und halbwegs eindeutig ist, kann das schneller sein als
+ein großer Index auf mehrere Spalten. In MySQL ist es sehr einfach, eine
+solche zusätzliche Spalte zu benutzen:
+@code{SELECT * FROM tabelle WHERE hash=MD5(concat(spalte1,spalte2))
+AND spalte_1='constant' AND spalte_2='constant'}
+@item
+Bei Tabellen, die sich viel ändern, sollten Sie versuchen, alle
+@code{VARCHAR}- oder @code{BLOB}-Spalten zu vermeiden. Sonst erhalten Sie
+dynamische Zeilenlängen, sobald Sie eine einzige @code{VARCHAR}- oder
+@code{BLOB}-Spalte verwenden. @xref{Table types}.
+@item
+Normalerweise nützt es nichts, eine Tabelle in verschiedene Tabellen
+aufzuteilen, nur weil die Zeile 'viel' werden. Um auf eine Zeile
+zuzugreifen, ist das wichtigste, was die Performance betrifft, der
+Suchvorgang nach dem ersten Byte der Zeile auf der Platte. Nachdem die
+Daten gefunden wurden, können die meisten neuen Platten die gesamte Zeile
+für die meisten Applikationen schnell genug lesen. Der einzige Fall, wo es
+wirklich etwas ausmacht, wenn eine Tabelle aufgeteilt wird, ist, wenn die
+Tabelle dynamische Zeilenlänge hat (siehe oben), was nicht in eine feste
+Zeilenlänge umgewandelt werden kann, oder wenn Sie die Tabelle sehr oft
+scannen müssen, die meisten der Spalten hierfür aber nicht benötigen.
+@xref{Table types}.
+@item
+Wenn Sie sehr oft etwas auf der Grundlage von Informationen aus sehr vielen
+Zeilen berechnen müssen (zum Beispiel Dinge zählen), ist es wahrscheinlich
+besser, eine neue Tabelle einzuführen und den Zähler in Echtzeit zu
+aktualisieren. Eine Aktualisierung des Typs @code{UPDATE tabelle set
+zaehler=zaehler+1 where index_spalte=konstante} ist sehr schnell!
+
+Das ist sehr wichtig, wenn Sie Datenbanken wie MySQL benutzen, die nur
+Tabellensperren haben (viele Leser / einzelne Schreiber). Bei den meisten
+sonstigen Datenbanken ergibt das ebenfalls bessere Performance, weil der
+Zeilensperr-Manager weniger zu tun haben wird.
+@item
+Wenn Sie Statistiken aus großen Log-Tabellen gewinnen wollen, benutzen Sie
+Zusammenfassungstabellen, statt die gesamte Tabelle zu scannen. Die Wartung
+der Zusammenfassungen sollte wesentlich leichter sein, als die Statistiken
+'live' zu generieren. Es ist viel schneller, neue Zusammenfassungstabellen
+aus den Logs zu erzeugen, wenn sich Dinge ändern (abhängig von
+Geschäftsentscheidungen) als eine laufende Applikation ändern zu müssen!
+@item
+Wenn möglich sollte man Berichte als 'live' oder 'statistisch'
+klassifizieren, wobei die Daten, die für statistische Berichte benötigt
+werden, nur auf der Grundlage von Zusammenfassungstabellen erzeugt werden,
+die aus den eigentlichen Daten generiert werden.
+@item
+Ziehen Sie Vorteile aus der Tatsache, dass Spalten Vorgabewerte haben.
+Fügen Sie nur dann explizit Werte ein, wenn der einzufügende Wert vom
+Vorgabewert abweicht. Das verringert das Parsen, das MySQL durchführen
+muss, und erhöht die Einfügegeschwindigkeit.
+@item
+In einigen Fällen ist es bequem, Daten zu komprimieren und in einem Blob zu
+speichern. In diesem Fall müssen Sie in Ihrer Applikation etwas
+zusätzlichen Code unterbringen, um die Dinge im Blob zu packen bzw. zu
+entpacken. Das kann aber in manchen Phasen etliches an Zugriffen einsparen.
+Das ist praktisch, wenn Sie Daten haben, die mit einer statischen
+Tabellenstruktur nicht konform sind.
+@item
+Normalerweise sollten Sie versuchen, alle Daten nicht redundant zu halten
+(was sich in der Datenbanktheorie dritte Normalform nennt). Scheuen Sie
+sich aber nicht davor, Dinge zu duplizieren oder Zusammenfassungstabellen
+zu erzeugen, wenn Sie dies brauchen, um mehr Geschwindigkeit zu erzielen.
+@item
+Gespeicherte Prozeduren (Stored Procedures) oder UDF (user defined
+functions, benutzerdefinierte Funktionen) sind eine gute Möglichkeit, mehr
+Performance zu erzielen. Sie sollten jedoch immer eine andere (langsamere)
+Möglichkeit parat haben, wenn Sie eine Datenbank benutzen, die gespeicherte
+Prozeduren nicht unterstützt.
+@item
+Man erreicht immer etwas, wenn man Anfragen / Antworten in der Applikation
+cachet und versucht, viele Einfüge- oder Aktualisierungsvorgänge zugleich
+durchzuführen. Wenn Ihre Datenbank Tabellensperren unterstützt (wie MySQL
+und Oracle), sollte das dazu führen, dass der Index-Cache nur einmal auf
+Platte zurück geschrieben wird, nachdem alles Einfügen / Aktualisieren
+ausgeführt ist.
+@item
+Benutzen Sie @code{INSERT /*! DELAYED */}, wenn Sie nicht wissen brauchen,
+wann Ihre Daten geschrieben werden. Das erhöht die Geschwindigkeit, weil
+viele Datensätze mit einem einzige Festplattenschreibzugriff geschrieben
+werden können.
+@item
+Benutzten Sie @code{INSERT /*! LOW_PRIORITY */}, wenn Sie wollen, dass Ihre
+Selects höhere Priorität haben.
+@item
+Benutzen Sie @code{SELECT /*! HIGH_PRIORITY */}, um zu bewirken, dass
+Selects in der Wartereihe nach vorn springen. Das heißt, der Select wird
+sogar dann durchgeführt, wenn jemand darauf wartet, etwas zu schreiben.
+@item
+Benutzen Sie das mehrzeilige @code{INSERT}-Statement, um viele Zeilen mit
+einem SQL-Befehl zu speichern (viele SQL-Server unterstützen das).
+@item
+Benutzen Sie @code{LOAD DATA INFILE}, um größere Datenmengen zu laden. Das
+ist schneller als normale Einfügevorgänge und wird noch schneller, wenn
+@code{myisamchk} in @code{mysqld} integriert wird.
+@item
+Benutzen Sie @code{AUTO_INCREMENT}-Spalten, um eindeutige Werte zu
+erzeugen.
+@item
+Benutzen Sie gelegentlich @code{OPTIMIZE TABLE}, um Fragmentierungen zu
+vermeiden, wenn Sie das dynamische Tabellenformat verwenden.
+@c German FIX changed @xref from TABLE to OPTIMIZE TABLE (point to proper node)
+@xref{OPTIMIZE TABLE}.
+@item
+Benutzen Sie - wenn möglich - @code{HEAP}-Tabellen, um mehr Geschwindigkeit
+zu erzielen. @xref{Table types}.
+@item
+Bei einer normalen Webserver-Konfiguration sollten Bilder als separate
+Dateien gespeichert werden. Das heißt, speichern Sie nur einen Verweis zur
+Datei in der Datenbank. Der Hauptgrund ist, dass normale Webserver viel
+besser darin sind, Dateien zu cachen als Datenbankinhalte. Daher ist es
+viel einfacher, ein schnelles System zu bekommen, wenn Sie Dateien
+benutzen.
+@item
+Benutzen Sie für nicht kritische Daten, auf die oft zugegriffen wird,
+Tabellen im Arbeitsspeicher (zum Beispiel Informationen über die Banner,
+die Benutzern ohne Cookies zuletzt präsentiert wurden).
+@item
+Spalten mit identischen Informationen in unterschiedlichen Tabellen sollten
+identisch deklariert sein und identische Namen haben. Vor Version 3.23
+konnte man ansonsten langsame Joins erhalten.
+
+Versuchen Sie, die Namen einfach zu halten (benutzen Sie @code{name}
+anstelle von @code{kunde_name} in der Kundentabelle). Um Namen für andere
+SQL-Server portabel zu halten, sollten Sie sie kürzer als 18 Zeichen
+halten.
+@item
+Wenn Sie WIRKLICH hohe Geschwindigkeit brauchen, sollten Sie einen Blick
+auf die Low-Level-Schnittstellen zur Datenspeicherung werfen, die die
+unterschiedlichen SQL-Server unterstützen! Wenn Sie zum Beispiel auf
+@code{MyISAM} direkt zugreifen, erhalten Sie eine
+Geschwindigkeitssteigerung um den Faktor 2 bis 5, im Vergleich zur
+Benutzung der SQL-Schnittstelle. Um das durchführen zu können, müssen die
+Daten auf demselben Server liegen wie die Applikation und üblicherweise
+sollte auf sie nur von einem Prozess zugegriffen werden (weil externes
+Dateisperren reichlich langsam ist). Man könnte die oben genannten Probleme
+beseitigen, indem Low-Level-@code{MyISAM}-Befehle in den MySQL-Server
+eingebaut werden (das wäre eine einfache Möglichkeit, bei Bedarf mehr
+Performance zu erlangen). Indem die Datenbankshnittstelle sorgfältig
+entworfen wird, sollte es recht einfach sein, diese Arten von Optimierung
+zu unterstützen.
+@item
+In vielen Fällen ist es schneller, auf Daten aus einer Datenbank (mit einer
+direkten Verbindung) als über eine Textdatei zuzugreifen, schon deshalb,
+weil die Datenbank wahrscheinlich kompakter ist als die Textdatei (wenn Sie
+numerische Daten benutzen) und hierdurch weniger Festplattenzugriffe
+erforderlich sind. Ausserdem wird Code eingespart, weil Sie Ihre
+Textdateien nicht parsen müssen, um Zeilen- und Spaltenbegrenzungen zu
+finden.
+@item
+Ausserdem können Sie Replikation benutzen, um die Geschwindigkeit zu
+steigern. @xref{Replication}.
+@item
+Wenn eine Tabelle mit @code{DELAY_KEY_WRITE=1} deklariert wird, werden
+Aktualisierungen auf Indexe schneller, weil diese nicht auf Platte
+geschrieben werden, bis die Datei geschlossen wird. Der Nachteil ist, dass
+Sie auf diesen Tabellen @code{myisamchk} laufen lassen sollten, bevor Sie
+@code{mysqld} starten, um sicherzustellen, dass diese in Ordnung sind,
+falls irgend etwas @code{mysqld} mittendrin killt. Weil die
+Schlüssel-Informationen jederzeit aus den Daten erzeugt werden können,
+sollten Sie durch @code{DELAY_KEY_WRITE} nichts verlieren.
+@end itemize
+
+
+@node Locking Issues, Optimising Database Structure, Query Speed, MySQL Optimisation
+@c German node Sperren (Locks)
+@section Sperren (Locking)
+
+
+
+
+@menu
+* Internal locking::
+* Table locking::
+@end menu
+
+@node Internal locking, Table locking, Locking Issues, Locking Issues
+@c German node Internes Sperren
+@subsection Wie MySQL Tabellen sperrt
+
+@cindex internes Sperren
+@cindex sperren, Tabellen
+@cindex Tabellen, sperren
+
+Im Anhang finden Sie eine Erörterung zu den unterschiedlichen
+Sperrmethoden. @xref{Locking methods}.
+
+Jedes Sperren in MySQL ist blockierungsfrei. Das wird erreicht, indem alle
+Sperren zugleich am Anfang einer Anfrage angefordert werden, und indem
+Tabellen immer in derselben Reihenfolge gesperrt werden.
+
+The Sperrmethode, die MySQL für @code{WRITE}-Sperren benutzt, funktioniert
+wie folgt:
+
+@itemize @bullet
+@item
+Falls es keine Sperren auf die Tabelle gibt, wird eine Schreibsperre
+gemacht.
+@item
+Ansonsten wird die Sperranforderung in die Schreibsperren-Warteschlange
+eingereiht.
+@end itemize
+
+Die Sperrmethode, die MySQL für @code{READ}Sperren benutzt, funktioniert
+wie folgt:
+
+@itemize @bullet
+@item
+Falls es keine Schreibsperren auf die Tabelle gibt, wird eine Lesesperre
+gemacht.
+@item
+Ansonsten wird die Sperranforderung in die Lesesperren-Warteschlange
+eingereiht.
+@end itemize
+
+Wenn eine Sperre aufgehoben wird, wird die Sperren den Threads in der
+Schreibsperren-Warteschlange verfügbar gemacht, danach den Threads in der
+Lesesperren-Warteschlange.
+
+Das bedeutet, wenn Sie viele Aktualisierungen auf eine Tabelle haben,
+warten @code{SELECT}-Statements, bis es keine Aktualisierungen mehr gibt.
+
+Um das für den Fall zu umgehen, dass es viele @code{INSERT}-
+und-@code{SELECT}-Operationen auf eine Tabelle gibt, können Sie Zeilen in
+eine temporäre Tabelle einfügen und die echte Tabelle gelegentlich aus den
+Daten der temporäre Tabelle aktualisieren.
+
+Das machen Sie wie folgt:
+@example
+mysql> LOCK TABLES echte_tabelle WRITE, einfuege_tabelle WRITE;
+mysql> insert into echte_tabelle select * von einfuege_tabelle;
+mysql> TRUNCATE TABLE einfuege_tabelle;
+mysql> UNLOCK TABLES;
+@end example
+
+Sie können bei @code{INSERT}, @code{UPDATE} oder @code{DELETE} die
+@code{LOW_PRIORITY}-Option oder bei @code{SELECT} die
+@code{HIGH_PRIORITY}-Option benutzen, wenn Sie dem Abruf von Daten in
+bestimmten Fällen Priorität einräumen wollen. Sie können auch @code{mysqld}
+mit @code{--low-priority-updates} starten, um dasselbe Verhalten zu
+erreichen.
+
+Die Benutzung von @code{SQL_BUFFER_RESULT} kann ebenfalls helfen,
+Tabellensperren kürzer zu machen. @xref{SELECT}.
+
+Sie können auch den Sperr-Code in @file{mysys/thr_lock.c} ändern, um eine
+einzige Warteschlagen zu benutzen. In diesem Fall haben Schreibsperren und
+Lesesperren dieselbe Priorität, was bei einigen Applikationen eventuell
+hilfreich ist.
+
+
+@node Table locking, , Internal locking, Locking Issues
+@c German node Tabellensperren
+@subsection Themen, die Tabellensperren betreffen
+
+@cindex Probleme, Tabellensperren
+
+Der Tabellensperren-Code in MySQL ist blockierungsfrei.
+
+MySQL benutzt Tabellensperren (anstelle von Zeilensperren oder
+Spaltensperren) für alle Tabellentypen ausser @code{BDB}-Tabellen, um eine
+sehr hohe Sperrgeschwindigkeit zu erzielen. Bei großen Tabellen ist
+Tabellensperren bei den meisten Applikationen VIEL besser als
+Zeilensperren, aber es gibt natürlich ein paar Fallstricke.
+
+Bei @code{BDB}- und @code{InnoDB}-Tabellen benutzt MySQL Tabellensperren,
+wenn Sie die Tabelle explizit mit @code{LOCK TABLES} sperren oder einen
+Befehl ausführen, der jede Zeile in der Tabelle ändern wird, wie
+@code{ALTER TABLE}. Bei diesen Tabellentypen empfehlen wir, @code{LOCK
+TABLES} überhaupt nicht zu benutzen.
+
+Ab MySQL-Version 3.23.7 können Sie Zeilen in @code{MyISAM}-Tabellen zur
+gleichen Zeit einfügen, während andere Threads aus der Tabelle lesen.
+Beachten Sie, dass das momentan nur funktioniert, wenn es zu der Zeit, zu
+der das Einfügen vorgenommen wird, keine durch gelöschte Zeilen verursachte
+Löcher in der Tabelle gibt. Wenn alle Löcher mit neuen Daten gefüllt
+wurden, werden gleichzeitige Einfügevorgänge automatisch wieder aktiviert.
+
+Tabellensperren ermöglicht, dass viele Threads gleichzeitig aus einer
+Tabelle lesen, aber bevor ein Thread in die Tabelle schreiben kann, muss er
+zunächst exklusiven Zugriff erhalten. Während der Aktualisierung müssen
+andere Threads, die auf diese Tabelle zugreifen wollen, warten, bis die
+Aktualisierung fertig ist.
+
+Weil Aktualisierung von Tabellen normalerweise als wichtiger erachtet
+werden als @code{SELECT}, erhalten alle Statements, die eine Tabelle
+aktualisieren, eine höhere Priorität als Statements, die Informationen aus
+der Tabelle abrufen. Das sollte sicherstellen, dass Aktualisierungen nicht
+'verhungern', wenn viele große Anfragen auf eine bestimmte Tabelle
+durchgeführt werden. (Sie können das ändern, indem Sie bei dem Statement,
+dass die Aktualisierung durchführt, LOW_PRIORITY verwenden, oder beim
+@code{SELECT}-Statement @code{HIGH_PRIORITY}.)
+
+Ab MySQL-Version 3.23.7 können Sie die @code{max_write_lock_count}-Variable
+benutzen, um MySQL zu zwingen, temporär allen @code{SELECT}-Statements, die
+auf eine Tabelle warten, nach einer bestimmten Anzahl von Einfügevorgängen
+auf eine Tabelle höhere Priorität einzuräumen.
+
+Tabellensperren ist jedoch bei folgendem Szenario nicht sehr gut:
+
+@itemize @bullet
+@item
+Ein Client führt ein @code{SELECT} aus, das lange Zeit läuft.
+@item
+Ein anderer Client führt danach ein @code{UPDATE} auf die benutzte Tabelle
+aus. Dieser Client wartet, bis das @code{SELECT} fertig ist.
+@item
+Ein weiterer Client führt ein weiteres @code{SELECT}-Statement auf dieselbe
+Tabelle aus. Weil @code{UPDATE} höhere Priorität als @code{SELECT} hat,
+wartet dieses @code{SELECT}, bis das @code{UPDATE} fertig ist. Es wartet
+auch darauf, dass das erste @code{SELECT} fertig ist!
+@item
+Ein Thread wartet bei etwas wie @code{Platte voll}. In diesem Fall warten
+alle anderen Threads, die auf die problemverursachende Tabelle zugreifen
+wollen, bis mehr Speicher verfügbar gemacht wurde.
+@end itemize
+
+Mögliche Lösungen dieses Problems sind:
+
+@itemize @bullet
+@item
+Versuchen Sie, @code{SELECT}-Statements schneller ablaufen zu lassen.
+Hierfür müssen Sie eventuell Zusammenfassungstabellen erzeugen.
+
+@item
+Starten Sie @code{mysqld} mit @code{--low-priority-updates}. Das gibt allen
+Statements, die eine Tabelle aktualisieren (ändern), geringere Priorität
+als einem @code{SELECT}-Statement. Im vorstehenden Szenario würde das
+@code{SELECT}-Statement vor dem @code{INSERT}-Statement ausgeführt werden.
+
+@item
+Sie können auch einem bestimmten @code{INSERT}-, @code{UPDATE}- oder
+@code{DELETE}-Statement mit dem @code{LOW_PRIORITY}-Attribut geringere
+Priorität geben.
+
+@item
+Starten Sie @code{mysqld} mit einem niedrigen Wert für
+@strong{max_write_lock_count}, um @code{READ}-Sperren nach einer bestimmten
+Anzahl von @code{WRITE}-Sperren zu ermöglichen.
+
+@item
+Sie können festlegen, dass alle Aktualisierungen von einem bestimmten
+Thread mit niedriger Priorität ausgeführt werden, indem Sie den SQL-Befehl
+@code{SET SQL_LOW_PRIORITY_UPDATES=1} benutzen. @xref{SET OPTION, ,
+@code{SET OPTION}}.
+
+@item
+Sie können mit dem @code{HIGH_PRIORITY}-Attribut festlegen, dass ein
+bestimmtes @code{SELECT} sehr wichtig ist. @xref{SELECT, , @code{SELECT}}.
+
+@item
+Wenn Sie Probleme mit @code{INSERT} in Kombination mit @code{SELECT} haben,
+stellen Sie auf die neuen @code{MyISAM}-Tabellen um, weil diese
+gleichzeitige @code{SELECT}s und @code{INSERT}s unterstützen.
+
+@item
+Wenn Sie hauptsächlich @code{INSERT}- und @code{SELECT}-Statements mischen,
+wird das @code{DELAYED}-Attribut für @code{INSERT} wahrscheinlich Ihre
+Probleme lösen. @xref{INSERT, , @code{INSERT}}.
+
+@item
+Wenn Sie Probleme mit @code{SELECT} und @code{DELETE} haben, mag die
+@code{LIMIT}-Option für @code{DELETE} helfen. @xref{DELETE, ,
+@code{DELETE}}.
+@end itemize
+
+
+@node Optimising Database Structure, Optimising the Server, Locking Issues, MySQL Optimisation
+@c German node Optimierung der Datenbank-Struktur
+@section Optimierung der Datenbank-Struktur
+
+
+
+
+@menu
+* Design::
+* Data size::
+* MySQL indexes::
+* Indexes::
+* Multiple-column indexes::
+* Open tables::
+* Table cache::
+* Creating many tables::
+@end menu
+
+@node Design, Data size, Optimising Database Structure, Optimising Database Structure
+@c German node Design
+@subsection MySQL-Datenbank-Design-Überlegungen
+
+@cindex Design, Überlegungen zum Datenbank-Design
+@cindex Datenbank-Design
+@cindex Speicherung von Daten
+
+MySQL speichert Zeilendaten und Indexdaten in separaten Dateien. Viele
+(fast alle) anderen Datenbanken vermischen Zeilen- und Indexdaten in
+derselben Datei. Wir glauben, dass die Wahl, die MySQL getroffen hat, für
+einen sehr weiten Bereich moderner Systeme besser ist.
+
+Eine weitere Möglichkeit, Zeilendaten zu speichern, besteht darin, die
+Information für jede Spalten in einem separaten Bereich zu halten
+(Beispiele sind SDBM und Focus). Das verursacht Performance-Einbussen für
+jede Anfrage, die auf mehr als eine Spalte zugreift. Weil das so schnell
+schlechter wird, wenn auf mehr als eine Spalte zugegriffen wird, glauben
+wir, dass dieses Modell für Mehrzweck-Datenbanken nicht gut ist.
+
+Der häufigere Fall ist, dass Index und Daten zusammen gespeichert sind (wie
+bei Oracle, Sybase usw.). In diesem Fall befindet sich die
+Zeileninformation auf der Leaf-Page des Indexes. Das Gute daran ist, dass
+man sich damit - abhängig davon, wie gut der Index gecachet ist - einen
+Festplatten-Lesezugriff spart. Das Schlechte an diesem Layout sind
+folgende Dinge:
+
+@itemize @bullet
+@item
+Tabellenscannen geht viel langsamer, weil man durch alle Indexe lesen muss,
+um an die Daten zu kommen.
+@item
+Man kann nicht nur die Index-Tabelle benutzen, um Daten einer Anfrage
+abzurufen.
+@item
+Man verliert viel Speicherplatz, weil man Indexe von den Nodes duplizieren
+muss (weil man die Zeile nicht in den Nodes speichern kann).
+@item
+Löschvorgänge werden die Tabelle im Zeitablauf zersetzen (weil Indexe in
+Nodes üblicherweise bei Löschvorgängen nicht aktualisiert werden).
+@item
+Ist es schwieriger, NUR die Index-Daten zu cachen.
+@end itemize
+
+
+@node Data size, MySQL indexes, Design, Optimising Database Structure
+@c German node Datengröße
+@subsection Wie Sie Ihre Daten so klein wie möglich bekommen
+
+@cindex Daten, Größe
+@cindex verringern, Datengröße
+@cindex Speicherplatz, minimieren
+@cindex Tabellen, Performance verbessern
+@cindex Performance, verbessern
+
+Eine der grundlegendsten Optimierungen besteht darin, Ihre Daten (und
+Indexe) dazu zu bekommen, dass sie möglichst wenige Platz auf der Platte
+(und im Arbeitsspeicher) benutzen. Das kann zu gewaltigen Verbesserungen
+führen, weil Lesezugriffe von der Platte schneller ablaufen und
+normalerweise weniger Hauptspeicher benutzt wird. Das Indexieren nimmt
+darüber hinaus weniger Ressourcen in Anspruch, wenn es auf kleinere Spalten
+durchgeführt wird.
+
+MySQL unterstützt viele verschiedene Tabellentypen und Zeilenformate. Wenn
+Sie das richtige Tabellenformat benutzen, kann Ihnen das große
+Performance-Gewinne bringen.
+@xref{Table types}.
+
+Sie erhalten bessere Performance auf eine Tabelle und minimieren den
+benötigten Speicherplatz, wenn Sie die unten aufgeführten Techniken
+verwenden:
+
+@itemize @bullet
+@item
+Benutzen Sie die effizientesten (kleinsten) möglichen Typen. MySQL hat
+viele spezialisierte Typen, die Plattenplatz und Arbeitsspeicher sparen.
+
+@item
+Benutzen Sie - falls möglich - die kleineren Ganzzahl-Typen, um kleinere
+Tabellen zu erhalten. @code{MEDIUMINT} zum Beispiel ist oft besser als
+@code{INT}.
+
+@item
+Deklarieren Sie Spalten - falls möglich - als @code{NOT NULL}. Das macht
+alles schneller und Sie sparen ein Bit pro Spalte. Beachten Sie, dass, wenn
+Sie wirklich @code{NULL} in Ihrer Applikation benötigen, Sie dieses
+natürlich benutzen sollten. Vermeiden Sie nur, einfach alle Spalten
+vorgabemäßig auf @code{NULL} zu haben.
+
+@item
+Wenn Sie keine Spalten variabler Länge haben (@code{VARCHAR}, @code{TEXT}
+oder @code{BLOB}-Spalten), wird ein Festgrößenformat benutzt. Das ist
+schneller, mag aber leider etwas Speicherplatz verschwenden.
+@xref{MyISAM table formats}.
+
+@item
+Der primäre Index einer Tabelle sollte so kurz wie möglich sein. Das macht
+die Identifikation einer Zeile schnell und effizient.
+
+@item
+Bei jeder Tabelle müssen Sie entscheiden, welche Speicher- / Index-Methode
+benutzt werden soll. @xref{Table types}.
+
+@item
+Erzeugen Sie nur die Indexe, die Sie tatsächlich brauchen. Indexe sind gut
+für das Abfragen von Daten, aber schlecht, wenn Sie Dinge schnell speichern
+müssen. Wenn Sie meist auf eine Tabelle zugreifen, indem Sie nach einer
+Kombination von Spalten suchen, legen Sie einen Index auf diese. Der erste
+Index-Teil sollte die meistbenutzte Spalte sein. Wenn Sie IMMER viele
+Spalten benutzen, sollten Sie die Spalte zuerst benutzen, die mehr
+Duplikate hat, um eine bessere Kompression des Indexes zu erzielen.
+
+@item
+Wenn es sehr wahrscheinlich ist, dass eine Spalte ein eindeutiges Präfix
+auf der ersten Anzahl von Zeichen hat, ist es besser, nur dieses Präfix zu
+indexieren. MySQL unterstützt einen Index auf einem Teil einer
+Zeichen-Spalte. Kürzere Indexe sind nicht nur schneller, weil sie weniger
+Plattenplatz brauchen, sondern auch, weil Sie mehr Treffer im Index-Cache
+erhalten und daher weniger Festplattenzugriffe benötigen.
+@xref{Server parameters}.
+
+@item
+Unter manchen Umständen kann es vorteilhaft sein, eine Tabelle zu teilen,
+die sehr oft gescannt wird. Das gilt insbesondere, wenn diese ein
+dynamisches Tabellenformat hat und es möglich ist, durch die Zerlegung eine
+kleinere Tabelle mit statischem Format zu erhalten, die benutzt werden
+kann, um die relevanten Zeilen zu finden.
+@end itemize
+
+
+@node MySQL indexes, Indexes, Data size, Optimising Database Structure
+@c German node MySQL-Indexe
+@subsection Wie MySQL Indexe benutzt
+
+@cindex Indexe, Benutzung von
+
+Indexe werden benutzt, um Zeilen mit einem bestimmten Spaltenwert schnell
+zu finden. Ohne Index müsste MySQL mit dem ersten Datensatz anfangen und
+dann durch die gesamte Tabelle lesen, bis er die relevanten Zeilen findet.
+Je größer die Tabelle, desto mehr Zeit kostet das. Wenn die Tabellen für
+die infrage kommenden Zeilen einen Index hat, kann MySQL schnell eine
+Position bekommen, um mitten in der Daten-Datei loszusuchen, ohne alle
+Daten zu betrachten. Wenn eine Tabelle 1.000 Zeilen hat, ist das mindestens
+100 mal schneller als sequentielles Lesen. Wenn Sie jedoch auf fast alle
+1.000 Zeilen zugreifen müssen, geht sequentielles Lesen schneller, weil man
+mehrfache Festplattenzugriffe einspart.
+
+Alle MySQL-Indexe (@code{PRIMARY}, @code{UNIQUE} und @code{INDEX}) sind in
+B-Bäumen gespeichert. Zeichenketten werden automatisch präfix-komprimiert,
+ebenfalls werden Leerzeichen am Ende komprimiert.
+@c German FIX unsplit @xref
+@xref{CREATE INDEX, ,@code{CREATE INDEX}}.
+
+Indexe werden benutzt, um:
+@itemize @bullet
+@item
+Schnell die Zeilen zu finden, die mit einer @code{WHERE}-Klausel
+übereinstimmen.
+
+@item
+Zeilen aus anderen Tabellen abzurufen, wenn Sie Joins durchführen.
+
+@item
+Den @code{MAX()}- oder @code{MIN()}-Wert für eine spezielle indizierte
+Spalte zu finden. Das wird durch einen Präprozessor optimiert, der
+überprüft, ob Sie @code{WHERE} schluessel_teil_# = constant auf allen
+Schlüsselteilen < N verwenden. In diesem Fall führt MySQL ein einzige
+Schlüsselnachschlagen durch und ersetzt den @code{MIN()}-Ausdruck mit einer
+Konstanten. Wenn alle Ausdrücke durch Konstanten ersetzt sind, gibt die
+Anfrage sofort ein Ergebnis zurück:
+
+@example
+SELECT MIN(schluessel_teil2),MAX(schluessel_teil2) FROM tabelle where schluessel_teil1=10
+@end example
+
+@item
+Eine Tabelle zu sortieren oder zu gruppieren, wenn das Sortieren oder
+Gruppieren mit dem am weitesten links stehenden Präfix eines benutzbaren
+Schlüssels durchgeführt wird (zum Beispiel @code{ORDER BY
+schluessel_teil_1,schluessel_teil_2}). Der Schlüssel wird in umgekehrter
+Reihenfolge gelesen, wenn allen Schlüsselteilen @code{DESC} folgt.
+
+Der Index kann auch benutzt werden, selbst wenn @code{ORDER BY} nicht exakt
+mit dem Index übereinstimmt, solange alle unbenutzten Indexteile und alle
+zusätzlichen @code{ORDER BY}-Spalten Konstanten in der @code{WHERE}-Klausel
+sind. Folgende Anfragen werden einen Index benutzen, um den @code{ORDER
+BY}-Teil aufzulösen:
+
+@example
+SELECT * FROM foo ORDER BY schluessel_teil1,schluessel_teil2,schluessel_teil3;
+SELECT * FROM foo WHERE spalte=konstante ORDER BY spalte, schluessel_teil1;
+SELECT * FROM foo WHERE schluessel_teil1=konstante GROUP BY schluessel_teil2;
+@end example
+
+@item
+In einigen Fällen kann eine Anfrage so optimiert werden, dass Sie Werte
+abruft, ohne in der Daten-Datei nachzuschlagen. Wenn alle benutzten Spalten
+einer Tabelle numerisch sind und ein ganz links stehendes Präfix für einen
+Schlüssel ergeben, können die Werte mit größerer Geschwindigkeit aus dem
+Index-Baum abgerufen werden:
+
+@example
+SELECT schluessel_teil3 FROM tabelle WHERE schluessel_teil1=1
+@end example
+
+@end itemize
+
+Angenommen, Sie führen folgendes @code{SELECT}-Statement aus:
+
+@example
+mysql> SELECT * FROM tabelle WHERE spalte1=val1 AND spalte2=val2;
+@end example
+
+Wenn es einen mehrspaltigen Index auf @code{spalte1} und @code{spalte2}
+gibt, können die entsprechenden Zeilen direkt geholt werden. Wenn es
+separate einspaltige Indexe auf @code{spalte1} und @code{spalte2} gibt,
+versucht der Optimierer, den restriktivsten Index zu finden, indem er
+entscheidet, welcher Index weniger Zeilen finden wird, und diesen Index
+dann benutzen, um Zeilen abzurufen.
+
+@cindex Indexe, ganz links stehendes Präfix von
+@cindex ganz links stehendes Präfix von Indexen
+Wenn die Tabelle einen mehrspaltigen Index hat, kann jedes Präfix auf der
+linken Seite vom Optimierer verwendet werden, um Zeilen zu finden. Wenn Sie
+zum Beispiel einen dreispaltigen Index auf @code{(spalte1,spalte2,spalte3)}
+haben, haben Sie Suchmöglichkeiten auf @code{(spalte1)},
+@code{(spalte1,spalte2)} und @code{(spalte1,spalte2,spalte3)} indiziert.
+
+MySQL kann keinen teilweisen Index verwenden, wenn die Spalten kein ganz
+linkes Präfix des Indexes bilden. Angenommen, Sie haben folgende
+@code{SELECT}-Statements:
+
+@example
+mysql> SELECT * FROM tabelle WHERE spalte1=wert1;
+mysql> SELECT * FROM tabelle WHERE spalte2=wert2;
+mysql> SELECT * FROM tabelle WHERE spalte2=wert2 AND spalte3=wert3;
+@end example
+
+Wenn es einen Index auf @code{(spalte1,spalte2,spalte3)} gibt, benutzt nur die
+erste der drei Anfragen den Index. Die zweite und dritte Anfrage umfassen
+indizierte Spalten, aber @code{(spalte2)} und @code{(spalte2,spalte3)} sind
+nicht die ganz linken Präfixe von @code{(spalte1,spalte2,spalte3)}.
+
+@findex LIKE und Indexe
+@findex LIKE und Platzhalter
+@cindex Indexe und @code{LIKE}
+@cindex Platzhalter und @code{LIKE}
+MySQL benutzt Indexe auch für @code{LIKE}-Vergleiche, wenn das Argument für
+@code{LIKE} eine Zeichenketten-Konstante ist, die nicht mit einem
+Platzhalterzeichen anfängt. Die folgenden @code{SELECT}-Statements zum
+Beispiel benutzen Indexe:
+
+@example
+mysql> select * from tabelle where schluessel_spalte LIKE "Patrick%";
+mysql> select * from tabelle where schluessel_spalte LIKE "Pat%_ck%";
+@end example
+
+Im ersten Statement werden nur Zeilen mit @code{"Patrick" <=
+schluessel_spalte < "Patricl"} berücksichtigt. Im zweiten Statement werden
+nur Zeilen mit @code{"Pat" <= schluessel_spalte < "Pau"} berücksichtigt.
+
+Die folgenden @code{SELECT}-Statements benutzen keine Indexe:
+@example
+mysql> select * from tabelle where schluessel_spalte LIKE "%Patrick%";
+mysql> select * from tabelle where schluessel_spalte LIKE andere_spalte;
+@end example
+
+Im ersten Statement fängt der @code{LIKE}-Wert mit einem Platzhalterzeichen
+an. Im zweiten Statement ist der @code{LIKE}-Wert keine Konstante.
+
+@findex @code{IS NULL} und Indexe
+@cindex Indexe und @code{IS NULL}
+Suchen mit @code{spalte IS NULL} benutzt Indexe, wenn spalte ein Index ist.
+
+MySQL benutzt normalerweise den Index, der die geringste Anzahl von Zeilen
+findet. Ein Index wird benutzt für Spalten, die Sie mit folgenden
+Operatoren vergleichen: @code{=}, @code{>}, @code{>=}, @code{<}, @code{<=},
+@code{BETWEEN} und einem @code{LIKE} ohne Platzhalter-Präfix wie
+@code{'etwas%'}.
+
+Jeder Index, der nicht alle @code{AND}-Ebenen in der @code{WHERE}-Klausel
+umfasst, wird nicht benutzt, um die Anfrage zu optimieren. Mit anderen
+Worte: Um einen Index benutzen zu können, muss ein Präfix des Indexes in
+jeder @code{AND}-Gruppe benutzt werden.
+
+Die folgenden @code{WHERE}-Klauseln benutzen Indexe:
+@example
+... WHERE index_teil1=1 AND index_teil2=2 AND andere_spalte=3
+... WHERE index=1 OR A=10 AND index=2 /* index = 1 OR index = 2 */
+... WHERE index_teil1='hello' AND index_teil_3=5
+ /* optimiert "index_teil1='hello'" */
+... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
+ /* kann den Index auf index1 benutzen, aber nicht auf index2 oder index 3 */
+@end example
+
+Die folgenden @code{WHERE}-Klauseln benutzen @strong{KEINE} Indexe:
+@example
+... WHERE index_teil2=1 AND index_teil3=2 /* index_teil_1 wird nicht benutzt */
+... WHERE index=1 OR A=10 /* Index wird nicht in beiden AND-Teilen benutzt */
+... WHERE index_teil1=1 OR index_teil2=10 /* Kein Index umfasst alle Zeilen */
+@end example
+
+Beachten Sie, dass MySQL in manchen Fällen keinen Index benutzt, selbst
+wenn einer verfügbar wäre. Einige solcher Fälle sind hier aufgeführt:
+
+@itemize @bullet
+@item
+Wenn die Benutzung des Indexes erfordern würde, dass MySQL auf mehr als 30%
+der Zeilen in der Tabelle zugreift. (In diesem Fall ist ein Tabellenscan
+wahrscheinlich viel schneller, weil dieser weniger Festplattenzugriffe
+braucht.) Beachten Sie, dass MySQL den Index dennoch benutzt, wenn eine
+Anfrage @code{LIMIT} benutzt, um nur ein paar Zeilen abzufragen, weil er
+dann schneller die wenigen Zeilen im Ergebnis finden kann.
+@end itemize
+
+
+
+
+@node Indexes, Multiple-column indexes, MySQL indexes, Optimising Database Structure
+@c German node Indexe
+@subsection Spalten-Indexe
+
+@cindex Indexe, Spalten
+@cindex Spalten, Indexe
+@cindex Schlüssel
+
+Alle MySQL-Spaltentypen können indiziert werden. Die Benutzung von Indexen
+auf den relevanten Spalten ist die beste Art, die Performance von
+@code{SELECT}-Operationen zu verbessern.
+
+Die maximale Anzahl von Schlüsseln und die maximale Index-Länge ist durch
+den Tabellen-Handler vorgegeben. @xref{Table types}. Bei allen
+Tabellen-Handlern können Sie zumindest 16 Schlüssel und eine
+Gesamtindexlänge von zumindest 256 Bytes haben.
+
+Bei @code{CHAR}- und @code{VARCHAR}-Spalten können Sie ein Präfix einer
+Spalte indexieren. Das ist viel schneller und erfordert weniger
+Plattenspeicher als das Indexieren einer ganzen Spalte. Die Syntax, die im
+@code{CREATE TABLE}-Statement benutzt wird, um ein Spaltenpräfix zu
+indexieren, sieht wie folgt aus:
+
+@example
+KEY index_name (spalten_name(laenge))
+@end example
+
+Das unten stehende Beispiel erzeugt einen Index auf die ersten 10 Zeichen
+der @code{name}-Spalte:
+
+@example
+mysql> CREATE TABLE test (
+ name CHAR(200) NOT NULL,
+ KEY index_name (name(10)));
+@end example
+
+Bei @code{BLOB}- und @code{TEXT}-Spalten müssen Sie ein Präfix der Spalte
+indexieren. Sie können nicht die gesamte Spalte indexieren.
+
+Ab MySQL-Version 3.23.23 können Sie auch spezielle @strong{FULLTEXT}-Indexe
+erzeugen. Sie werden für die Volltextsuche benutzt. Nur der
+@code{MyISAM}-Tabellentyp unterstützt @code{FULLTEXT}-Indexe. Sie können
+nur auf @code{VARCHAR}- und @code{TEXT}-Spalten erzeugt werden. Die
+Indexierung erfolgt immer über die gesamte Spalte; teilweises Indexieren
+wird nicht unterstützt. Siehe @ref{Fulltext Search} für Details.
+
+@node Multiple-column indexes, Open tables, Indexes, Optimising Database Structure
+@c German node Mehrspaltige Indexe
+@subsection Mehrspaltige Indexe
+
+@cindex mehrspaltige Indexe
+@cindex Indexe, mehrspaltige
+@cindex Schlüssel, mehrspaltige
+
+MySQL kann Indexe auf mehrfache Spalten erzeugen. Ein Index darf aus bis zu
+15 Spalten bestehen. (Auf @code{CHAR}- und @code{VARCHAR}-Spalten können
+Sie auch ein Präfix der Spalte als Teil eines Indexes benutzen).
+
+Ein mehrspaltiger Index kann als sortiertes Array betrachtet werden, das
+Werte enthält, die durch die Verkettung der Werte der indizierten Spalten
+erzeugt werden.
+
+MySQL benutzt mehrspaltige Indexe in einer Art, dass Anfragen schnell
+werden, wenn Sie eine bekannte Menge für die erste Spalte des Indexes in
+einer @code{WHERE}-Klausel angeben, selbst wenn Sie keine Werte für die
+anderen Spalten angeben.
+
+Angenommen, einen Tabelle wurde wie folgt erzeugt:
+
+@example
+mysql> CREATE TABLE test (
+ id INT NOT NULL,
+ nachname CHAR(30) NOT NULL,
+ vorname CHAR(30) NOT NULL,
+ PRIMARY KEY (id),
+ INDEX name (nachname,vorname));
+@end example
+
+Dann ist der Index @code{name} ein Index über @code{nachname} und
+@code{vorname}. Der Index wird für Anfragen benutzt, die Werte in einem
+bekannten Bereich für @code{nachname} angeben, oder sowohl für
+@code{nachname} als auch für und @code{vorname}.
+Daher wird der @code{name}-Index in folgenden Anfragen benutzt:
+
+@example
+mysql> SELECT * FROM test WHERE nachname="Widenius";
+
+mysql> SELECT * FROM test WHERE nachname="Widenius"
+ AND vorname="Michael";
+
+mysql> SELECT * FROM test WHERE nachname="Widenius"
+ AND (vorname="Michael" OR vorname="Monty");
+
+mysql> SELECT * FROM test WHERE nachname="Widenius"
+ AND vorname >="M" AND vorname < "N";
+@end example
+
+In folgenden Anfragen wird der @code{name}-Index jedoch NICHT benutzt:
+
+@example
+mysql> SELECT * FROM test WHERE vorname="Michael";
+
+mysql> SELECT * FROM test WHERE nachname="Widenius"
+ OR vorname="Michael";
+@end example
+
+Weitere Informationen über die Art, wie MySQL Indexe benutzt, um die
+Anfragen-Performance zu verbessern, finden Sie unter @ref{MySQL indexes, ,
+MySQL-Indexe}.
+
+
+@node Open tables, Table cache, Multiple-column indexes, Optimising Database Structure
+@c German node Tabellen-Cache
+@subsection Wie MySQL Tabellen öffnet und schließt
+
+@findex table_cache
+
+@cindex Tabellen, öffnen
+@cindex Tabellen, schließen
+@cindex öffnen, Tabellen
+@cindex schließen, Tabellen
+@cindex Tabellen-Cache
+
+@code{table_cache}, @code{max_connections} und @code{max_tmp_tables}
+beeinflussen die maximale Anzahl von Dateien, die der Server offen halten
+kann. Wenn Sie einen oder mehrere dieser Werte erhöhen, können Sie an eine
+Begrenzung stoßen, die durch Ihr Betriebssystem in Bezug auf die Anzahl
+offener Datei-Deskriptoren pro Prozess festgelegt wird. Diese Begrenzung
+kann man jedoch auf vielen Systemen erhöhen. Sehen Sie im Handbuch Ihres
+Betriebssystems nach, wie man das macht, weil die Methode, wie die
+Begrenzung geändert wird, sich von System zu System stark unterscheidet.
+
+@code{table_cache} ist verwandt mit @code{max_connections}. Für 200
+gleichzeitig laufende Verbindungen sollten Sie zum Beispiel einen
+Tabellen-Cache von mindestens @code{200 * n} haben, wobei @code{n} die
+maximale Anzahl von Tabellen in einem Join ist. Zusätzlich müssen Sie
+einige externe Datei-Deskriptoren für temporäre Tabellen und Dateien
+reservieren.
+
+Stellen Sie sicher, dass Ihr Betriebssystem die Anzahl offener
+Datei-Deskriptoren handhaben kann, die durch die
+@code{table_cache}-Einstellung impliziert wird. Wenn
+@code{table_cache} zu hoch gesetzt wird, hat MySQL eventuell keine
+Datei-Deskriptoren mehr und verweigert Verbindungen, führt keine Anfragen
+mehr aus und läuft sehr unzuverlässig. Beachten Sie auch, dass der
+MyISAM-Tabellen-Handler zwei Datei-Deskriptoren für jede einzelne offene
+Tabelle benötigt. Sie können die Anzahl von Datei-Deskriptoren, die für
+MySQL verfügbar sind, in der @code{--open-files-limit=#}-Startoption
+angeben. @xref{Not enough file handles}.
+
+Der Cache offener Tabellen kann bis auf @code{table_cache} anwachsen
+(Vorgabewert 64; das kann mit der @code{-O Tabellen-Cache=#}-Option für
+@code{mysqld} geändert werden). Eine Tabelle wird nie geschlossen, ausser
+wen der Cache voll ist und ein anderer Thread versucht, eine Tabelle zu
+öffnen, oder wenn Sie @code{mysqladmin refresh} oder @code{mysqladmin
+flush-tables} benutzen.
+
+Wenn sich der Tabellen-Cache füllt, benutzt der Server folgenden Prozedur,
+um einen Cache-Eintrag für die Benutzung zu finden:
+
+@itemize @bullet
+@item
+Tabellen, die momentan nicht in Benutzung sind, werden freigegeben, in der
+Reihenfolge der kürzlich am wenigsten benutzten Tabellen.
+
+@item
+Wenn der Cache voll ist und keine Tabellen freigegeben werden können, aber
+eine neue Tabelle geöffnet werden muss, wird der Cache temporär wie
+benötigt vergrößert.
+
+@item
+Wenn der Cache gerade im Zustand temporärer Erweiterung ist und eine
+Tabelle vom Zustand benutzt in den Zustand nicht benutzt wechselt, wird die
+Tabelle geschlossen und vom Cache freigesetzt.
+@end itemize
+
+Eine Tabelle wird für jeden gleichzeitigen Zugriff geöffnet. Das bedeutet,
+dass die Tabelle zweimal geöffnet werden muss, wenn Sie zwei Threads haben,
+die auf dieselbe Tabelle zugreifen oder einen Thread, der auf die Tabelle
+zweimal in derselben Anfrage zugreift (mit @code{AS}). Das erste öffnen
+jeder Tabelle benötigt nur einen Datei-Deskriptor. Der zusätzliche
+Deskriptor wird für die Index-Datei benötigt; dieser Deskriptor wird
+mit allen Threads geteilt (shared).
+
+Wenn Sie eine Tabelle mit dem @code{HANDLER tabelle OPEN}-Statement öffnen,
+wird dem Thread ein dediziertes Tabellenobjekt zugewiesen. Diese
+Tabellenobjekt wird nicht mit anderen Threads geteilt und wird solange
+nicht geschlossen, bis der Thread @code{HANDLER tabelle CLOSE} aufruft oder
+stirbt.
+@xref{INSERT}.
+
+Sie können prüfen, ob Ihr Tabellen-Cache zu klein ist, indem Sie die
+mysqld-Variable @code{opened_tables} ansehen. Wenn diese recht Groß ist,
+selbst wenn Sie nicht viele @code{FLUSH TABLES} ausgeführt haben, sollten
+Sie Ihren Tabellen-Cache vergrößern. @xref{SHOW STATUS}.
+
+
+@node Table cache, Creating many tables, Open tables, Optimising Database Structure
+@c German node Viele Tabellen erzeugen
+@subsection Nachteile der Erzeugung großer Mengen von Tabellen in derselben Datenbank
+
+@cindex Tabellen, zu viele
+
+Wenn Sie viele Dateien in einem Verzeichnis haben, werden open-, close- und
+create-Operationen langsam. Wenn Sie ein @code{SELECT}-Statements auf viele
+unterschiedliche Tabellen ausführen, gibt es ein bisschen Overhead, wenn
+der Tabellen-Cache voll ist, weil für jede Tabelle, die geöffnet wird, eine
+andere geschlossen werden muss. Sie können diese Overhead verringern, indem
+Sie den Tabellen-Cache größer machen.
+
+
+@node Creating many tables, , Table cache, Optimising Database Structure
+@c German node Offene Tabellen
+@subsection Warum gibt es so viele offene Tabellen?
+
+@cindex Tabellen, offene
+@cindex offene Tabellen
+
+Wenn Sie @code{mysqladmin status} ausführen, werden Sie etwa folgendes
+sehen:
+
+@example
+Uptime: 426 Running Threads: 1 Questions: 11082 Reloads: 1 Open Tables: 12
+@end example
+
+Das kann etwas verwirrend sein, wenn Sie nur 6 Tabellen haben.
+
+MySQL ist multi-threaded, daher kann er viele Anfragen auf dieselbe Tabelle
+simultan verarbeiten. Um das Problem zu minimieren, dass zwei Threads
+verschiedene Zustände in Bezug auf dieselbe Datei haben, wird die Tabelle
+unabhängig für jeden gleichzeitigen Thread geöffnet. Das benötigt etwas
+Arbeitsspeicher und einen externen Datei-Deskriptor für die Daten-Datei.
+Der Index-Datei-Deskriptor wird mit allen Threads geteilt.
+
+
+@node Optimising the Server, Disk issues, Optimising Database Structure, MySQL Optimisation
+@c German node Optimierung des Servers
+@section Optimierung des MySQL-Servers
+
+
+
+
+@menu
+* System::
+* Server parameters::
+* Compile and link options::
+* Memory use::
+* DNS::
+* SET OPTION::
+@end menu
+
+@node System, Server parameters, Optimising the Server, Optimising the Server
+@c German node System
+@subsection System / Kompilierzeitpunkt und Tuning der Startparameter
+
+@cindex Kompilieren, Optimierung
+@cindex System-Optimierung
+@cindex Startparameter, tunen
+
+Wir fangen mit den Dingen auf Systemebene an, weil einige dieser
+Entscheidungen sehr früh getroffen werden müssen. In anderen Fällen mag ein
+kurzer Blick auf diesen Teil ausreichen, weil er nicht so wichtig für
+große Verbesserungen ist. Es ist jedoch immer nett, ein Gefühl dafür zu
+bekommen, wie viel man gewinnen kann, wenn man Dinge auf dieser Ebene
+ändert.
+
+Es ist wirklich wichtig, dass vorgabemäßige Betriebssystem zu kennen! Um
+das meiste aus Mehrprozessor-Maschinen herauszuholen, sollte man Solaris
+benutzen (weil die Threads wirklich gut funktionieren) oder Linux (weil der
+2.2-Kernel wirklich gute Mehrprozessor-Unterstützung bietet). Linux hat auf
+32-Bit-Maschinen vorgabemäßig eine Dateigrößenbeschränkung von 2 GB. Das
+wird hoffentlich bald behoben, wenn neue Dateisysteme herausgebracht werden
+(XFS/Reiserfs). Wenn Sie dringen Unterstützung für größere Datei als 2 GB
+auf Linux-Intel-32-Bit benötigen, sollten Sie den LFS-Patch für das
+ext2-Dateisystem holen.
+
+Weil wir MySQL noch nicht auf allzu vielen Plattformen in einer
+Produktionsumgebung getestet haben, empfehlen wir, dass Sie Ihre geplante
+Plattform testen, bevor Sie sich dafür entscheiden.
+
+@cindex Sperren
+Weitere Tipps:
+@itemize @bullet
+@item
+Wenn Sie genug Arbeitsspeicher haben, könnten Sie alle Swap-Geräte
+entfernen. Einige Betriebssysteme benutzen in bestimmten Zusammenhängen ein
+Swap-Gerät, selbst wenn Sie freien Arbeitsspeicher haben.
+@item
+Benutzen Sie die @code{--skip-locking}-MySQL-Option, um externe Sperren zu
+vermeiden. Beachten Sie, dass das die Funktionalität von MySQL nicht
+tangiert, solange Sie nur einen Server laufen lassen. Denken Sie lediglich
+daran, den Server herunterzufahren (oder die relevanten Teile zu sperren),
+bevor Sie @code{myisamchk} laufen lassen. Auf manchen Systemen ist diese
+Umschaltung zwingend erforderlich, weil externes Sperren in keinem Fall
+funktioniert.
+
+Die @code{--skip-locking}-Option ist vorgabemäßig angeschaltet, wenn Sie
+mit MIT-pThreads kompilieren, weil @code{flock()} von MIT-pThreads nicht
+vollständig auf allen Plattformen unterstützt wird. Auch für Linux ist es
+vorgabemäßig angeschaltet, weil Linux-Dateisperren bis jetzt nicht
+zuverlässig funktionieren.
+
+Der einzige Fall, wo Sie @code{--skip-locking} nicht benutzen können, sit,
+wenn Sie mehrfache MySQL-@emph{Server} (nicht Clients) auf denselben Daten
+laufen lassen, oder wenn Sie @code{myisamchk} auf eine Tabelle ausführen,
+ohne zuerst die @code{mysqld}-Server-Tabellen auf Platte zurückzuschreiben
+und zu sperren.
+
+Sie können immer noch @code{LOCK TABLES} / @code{UNLOCK TABLES} benutzen,
+selbst wenn Sie @code{--skip-locking} benutzen.
+@end itemize
+
+
+@node Server parameters, Compile and link options, System, Optimising the Server
+@c German node Serverparameter
+@subsection Serverparameter tunen
+
+@cindex Parameter, Server
+@cindex @code{mysqld}-Server, Puffer-Größen
+@cindex Puffer-Größen, @code{mysqld}-Server
+@cindex Startparameter
+
+Sie erhalten die Puffer-Größen, die der @code{mysqld}-Server benutzt, mit
+diesem Befehl:
+
+@example
+shell> mysqld --help
+@end example
+
+@cindex @code{mysqld}-Optionen
+@cindex Variablen, @code{mysqld}
+Dieser Befehl erzeugt eine Auflistung aller @code{mysqld}-Optionen und
+konfigurierbaren Variablen. Die Ausgabe enthält die Vorgabewerte und sieht
+etwa wie folgt aus:
+
+@example
+Possible variables for option --set-variable (-O) are:
+back_log current value: 5
+bdb_cache_size current value: 1048540
+binlog_cache_size current_value: 32768
+connect_timeout current value: 5
+delayed_insert_timeout current value: 300
+delayed_insert_limit current value: 100
+delayed_queue_size current value: 1000
+flush_time current value: 0
+interactive_timeout current value: 28800
+join_buffer_size current value: 131072
+key_buffer_size current value: 1048540
+lower_case_tabelles current value: 0
+long_query_time current value: 10
+max_allowed_packet current value: 1048576
+max_binlog_cache_size current_value: 4294967295
+max_connections current value: 100
+max_connect_errors current value: 10
+max_delayed_threads current value: 20
+max_heap_table_size current value: 16777216
+max_join_size current value: 4294967295
+max_sort_length current value: 1024
+max_tmp_tables current value: 32
+max_write_lock_count current value: 4294967295
+myisam_sort_buffer_size current value: 8388608
+net_buffer_length current value: 16384
+net_retry_count current value: 10
+net_read_timeout current value: 30
+net_write_timeout current value: 60
+query_buffer_size current value: 0
+record_buffer current value: 131072
+record_rnd_buffer current value: 131072
+slow_launch_time current value: 2
+sort_buffer current value: 2097116
+table_cache current value: 64
+thread_concurrency current value: 10
+tmp_table_size current value: 1048576
+thread_stack current value: 131072
+wait_timeout current value: 28800
+@end example
+
+Wenn aktuell ein @code{mysqld}-Server läuft, können Sie feststellen, welche
+Werte er für die Variablen tatsächlich benutzt, wenn Sie diesen Befehl
+ausführen:
+
+@example
+shell> mysqladmin variables
+@end example
+
+Sie finden eine komplette Beschreibung aller Variablen im @code{SHOW
+VARIABLES}-Abschnitt dieses Handbuchs. @xref{SHOW VARIABLES}.
+
+Wenn Sie @code{SHOW STATUS} eingeben, können Sie einige statistische
+Informationen des Servers sehen. @xref{SHOW STATUS}.
+
+MySQL benutzt Algorithmen, die sehr skalierbar sind, daher können Sie
+üblicherweise mit sehr wenig Arbeitsspeicher fahren. Wenn Sie MySQL jedoch
+mehr Speicher geben, erzielen Sie damit normalerweise auch bessere
+Performance.
+
+Wenn Sie einen MySQL-Server tunen, sind die zwei wichtigsten Variablen
+@code{key_buffer_size} und @code{table_cache}. Sie sollten zunächst sicher
+sein, dass diese beiden richtig gesetzt sind, bevor Sie versuchen, irgend
+eine der anderen Variablen zu ändern.
+
+Wenn Sie viel Arbeitsspeicher haben (>= 256 MB) und viele Tabellen und
+maximale Performance bei einer mäßigen Anzahl von Clients haben wollen,
+sollten Sie etwas wie das Folgende benutzen:
+
+@example
+shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \
+ -O sort_buffer=4M -O record_buffer=1M &
+@end example
+
+Wenn Sie nur 128 MB und nur wenige Tabellen haben, aber viele
+Sortiervorgänge durchführen, können Sie etwas wie das Folgende benutzen:
+
+@example
+shell> safe_mysqld -O key_buffer=16M -O sort_buffer=1M
+@end example
+
+Wenn Sie wenig Arbeitsspeicher und viele Verbindungen haben, können Sie
+etwas wie das Folgende benutzen:
+
+@example
+shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \
+ -O record_buffer=100k &
+@end example
+
+Oder sogar:
+
+@example
+shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \
+ -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &
+@end example
+
+Wenn Sie @code{GROUP BY} oder @code{ORDER BY} auf Dateien anwenden, die
+größer als Ihr verfügbarer Arbeitsspeicher sind, sollten Sie den Wert von
+@code{record_rnd_buffer} heraufsetzen, um das Lesen von Zeilen nach
+Sortiervorgängen zu beschleunigen.
+
+Wenn Sie MySQL installiert haben, enthält das
+@file{Support-files}-Verzeichnis einige unterschiedliche
+@code{my.cnf}-Beispiel-Dateien: @file{my-huge.cnf}, @file{my-large.cnf},
+@file{my-medium.cnf} und @file{my-small.cnf}. Diese können Sie als
+Grundlage nehmen, um Ihr System zu optimieren.
+
+Wenn es sehr viele Verbindungen gibt, können ``Swapping-Probleme''
+auftauchen, wen Sie @code{mysqld} nicht so konfiguriert haben, dass er für
+jede Verbindung sehr wenig Speicher benutzt. @code{mysqld} bringt natürlich
+bessere Leistungsdaten, wenn Sie genug Speicher für alle Verbindungen
+haben.
+
+Beachten Sie, dass Änderungen einer Option für @code{mysqld} sich nur auf
+diese Instanz des Servers auswirken.
+
+Um die Auswirkung einer Parameteränderung zu sehen, geben Sie folgendes
+ein:
+
+@example
+shell> mysqld -O key_buffer=32m --help
+@end example
+
+Stellen Sie sicher, dass die @code{--help}-Option zuletzt kommt, ansonsten
+wird die Auswirkung jeglicher Optionen, die danach auf der Kommandozeile
+kommen, in der Ausgabe nicht gezeigt.
+output.
+
+
+@node Compile and link options, Memory use, Server parameters, Optimising the Server
+@c German node Kompilier- und Link-Optionen
+@subsection Wie Kompilieren und Linken die Geschwindigkeit von MySQL beeinflusst
+
+@cindex Linken, Geschwindigkeit
+@cindex Kompilieren, Geschwindigkeit
+@cindex Geschwindigkeit, Kompilieren
+@cindex Geschwindigkeit, Linken
+
+Die meisten der folgenden Tests wurden mit den MySQL-Benchmarks unter Linux
+durchgeführt, aber sie sollten einen guten Anhaltspunkt für andere
+Betriebssysteme und Auslastungen geben.
+
+Sie erhalten die schnellste ausführbare Datei, wenn Sie mit @code{-static}
+linken.
+
+Unter Linux erhalten Sie den schnellsten Code, wenn Sie mit @code{pgcc} und
+@code{-O3} kompilieren. Um @file{sql_yacc.cc} mit diesen Optionen zu
+kompilieren, brauchen Sie etwa 200 MB Arbeitsspeicher, weil @code{gcc/pgcc}
+viel Speicher benötigt, um alle Funktionen inline zu machen. Sie sollten
+beim Konfigurieren von MySQL auch @code{CXX=gcc} setzen, um das
+Einschließen der @code{libstdc++}-Bibliothek zu vermeiden (die nicht
+benötigt wird). Beachten Sie, dass bei einigen Version von @code{pgcc} der
+erzeugte Code nur auf echten Pentium-Prozessoren läuft, selbst wenn Sie in
+den Compiler-Optionen angeben, dass Sie wollen, dass der Code auf alle
+Prozessoren vom Typ x586 läuft (wie AMD).
+
+Einfach durch die Benutzung eines besseren Compilers und / oder besserer
+Compiler-Optionen können Sie eine 10-30%-ige Geschwindigkeitssteigerung in
+Ihrer Applikation erhalten. Das ist besonders wichtig, wenn Sie den
+SQL-Server selbst kompilieren!
+
+Wir haben sowohl Cygnus CodeFusion als auch Fujitsu-Compiler getestet, aber
+es stellte sich heraus, dass keiner von beiden ausreichend Bug-frei war,
+damit MySQL mit angeschalteten Optimierungen kompiliert werden konnte.
+
+Wenn Sie MySQL kompilieren, sollten Sie nur Unterstützung für die
+Zeichensätze einschließen, die Sie benutzen werden (Option
+@code{--with-charset=xxx}). Die Standard-MySQL-Binärdistributionen werden
+mit Unterstützung für alle Zeichensätze kompiliert.
+
+Hier ist eine Auflistung einiger Messungen, die wir durchgeführt haben:
+@itemize @bullet
+@item
+Wenn Sie @code{pgcc} benutzen und alles mit @code{-O6} kompilieren, ist der
+@code{mysqld}-Server 1% schneller als mit @code{gcc} 2.95.2.
+
+@item
+Wenn Sie dynamisch linken (ohne @code{-static}), ist das Ergebnis unter
+Linux 13% langsamer. Beachten Sie, dass Sie dennoch dynamisch gelinkte
+MySQL-Bibliotheken benutzen können. Nur beim Server ist das kritisch in
+Bezug auf Performance.
+
+@item
+Wenn Sie Ihre @code{mysqld}-Binärdatei mit @code{strip libexec/mysqld}
+strippen, ist die resultierende Binärdatei bis zu 4% schneller.
+
+@item
+Wenn Sie sich über TCP/IP statt über Unix-Sockets verbinden, ist das auf
+demselben Computer 7,5% langsamer. (Wenn Sie sich zu @code{localhost}
+verbinden, benutzt MySQL vorgabemäßig Sockets.)
+
+@item
+Wenn Sie sich über TCP/IP von einem anderen Computer über ein
+100-MBit-Ethernet verbinden, ist das 8% bis 11% langsamer.
+
+@item
+Wenn Sie mit @code{--with-debug=full} kompilieren, verlangsamen sich die
+meisten Anfragen um 20%, manche Anfragen jedoch werden wesentlich langsamer
+(der MySQL-Benchmarks zeigte 35%). Wenn Sie @code{--with-debug} benutzen,
+beträgt die Verlangsamung nur 15%. Wenn Sie eine @code{mysqld}-Version, die
+mit @code{--with-debug=full} kompiliert wurde, mit @code{--skip-safemalloc}
+starten, ist die Geschwindigkeit etwa dasselbe, als wenn Sie mit
+@code{--with-debug} konfigurieren.
+
+@item
+Auf einer Sun SPARCstation 20 ist SunPro C++ 4.2 5% schneller als
+@code{gcc} 2.95.2.
+
+@item
+Das Kompilieren mit @code{gcc} 2.95.2 für ultrasparc mit der Option
+@code{-mcpu=v8 -Wa,-xarch=v8plusa} ergibt 4% mehr Performance.
+
+@item
+Auf Solaris 2.5.1 sind MIT-pThreads 8% bis 12% langsamer als Solaris-native
+Threads, auf einem Einprozessorsystem. Bei mehr Last / Prozessoren sollte
+der Unterschied größer werden.
+
+@item
+Laufenlassen mit @code{--log-bin} macht @strong{MySQL} 1% langsamer.
+
+@item
+Wenn beim Kompilieren unter Linux-x86 mit gcc keine Frame-Pointers
+@code{-fomit-frame-pointer} oder @code{-fomit-frame-pointer -ffixed-ebp}
+verwendet werden, ist @code{mysqld} 1% bis 4% schneller.
+@end itemize
+
+Die MySQL-Linux-Distribution, die von MySQL AB zur Verfügung gestellt wird,
+wurde früher mit @code{pgcc} kompiliert, aber wir mussten zum normalen gcc
+zurück gehen, weil es einen Bug in @code{pgcc} gibt, der Code erzeugt, der
+nicht auf AMD läuft. Wir werden gcc solange benutzen, bis dieser Bug
+behoben ist. Bis dahin können Sie, falls Sie keine AMD-Maschine haben, eine
+schnellere Binärdatei erhalten, wenn Sie mit @code{pgcc} kompilieren. Die
+Standard-MySQL-Linux-Binärdatei wird statisch gelinkt, um sie schneller und
+portierbarer zu machen.
+
+
+@node Memory use, DNS, Compile and link options, Optimising the Server
+@c German node Speicherbenutzung
+@subsection Wie MySQL Speicher benutzt
+
+@cindex Speicherbenutzung
+
+Die unten stehende Liste zeigt einige Möglichkeiten, wie der
+@code{mysqld}-Server Speicher benutzt. Wo es zutrifft, wird der Name der
+für die Speicherbenutzung relevanten Servervariablen angegeben.
+
+@itemize @bullet
+@item
+Der Schlüssel-Puffer (Variable @code{key_buffer_size}) wird von allen
+Threads geteilt. Andere Puffer, die vom Server benutzt werden, werden bei
+Bedarf zugewiesen. @xref{Server parameters}.
+
+@item
+Jede Verbindung benutzt etwas Thread-spezifischen Platz: Einen Stack
+(Vorgabe 64 KB, Variable @code{thread_stack}), einen Verbindungspuffer
+(Variable @code{net_buffer_length}) und a Ergebnispuffer (Variable
+@code{net_buffer_length}). Die Verbindungspuffer und Ergebnispuffer werden
+bei Bedarf dynamisch bis zu @code{max_allowed_packet} vergrößert. Wenn
+eine Anfrage läuft, wird auch eine Kopie der aktuellen Anfragezeichenkette
+zugewiesen.
+
+@item
+Alle Threads teilen sich denselben grundlegenden Speicher.
+
+@item
+Nur die komprimierten ISAM- / MyISAM-Tabellen werden Speicher-gemappt. Das
+liegt daran, dass der 32-Bit-Adressraum von 4 GB für die meisten großen
+Tabellen nicht Groß genug ist. Wenn Systeme mit 64-Bit-Adressraum
+gebräuchlicher werden, werden wir vielleicht eine allgemeine Unterstützung
+für Speicher-Mapping hinzufügen.
+
+@item
+Jeder Anfrage, die einen sequentiellen Scan über eine Tabelle durchführt,
+wird ein Lesepuffer zugewiesen (Variable @code{record_buffer}).
+
+@item
+Wenn Zeilen in 'zufälliger' Reihenfolge gelesen werden (zum Beispiel nach
+einem Sortiervorgang), wird ein Zufalls-Lesepuffer zugewiesen, um
+Suchvorgänge auf Festplatte zu vermeiden. (Variable @code{record_rnd_buffer}).
+
+@item
+Alle Joins werden in einem Durchgang durchgeführt und die meisten Joins
+können sogar ohne Benutzung einer temporären Tabelle durchgeführt werden.
+Die meisten temporären Tabellen sind Speicher-basierende (HEAP-) Tabellen.
+Temporäre Tabellen mit großer Datensatzlänge (berechnet als Summe aller
+Spaltenlängen) oder die @code{BLOB}-Spalten enthalten, werden auf
+Festplatte gespeichert.
+
+Ein Problem in MySQL-Versionen vor Version 3.23.2 ist, dass Sie den Fehler
+@code{The table tabelle is full} erhalten, wenn die Größe der HEAP-Tabelle
+@code{tmp_table_size} überschreitet. In neueren Versionen wird dies so
+gehandhabt, dass die Speicher-basierende (HEAP-) Tabelle bei Bedarf
+automatisch in eine Festplatten-basierende Tabelle (MyISAM) umgewandelt
+wird. Um das Problem zu umgehen, können Sie die Größe von temporären
+Tabellen durch Setzen der @code{tmp_table_size}-Option für @code{mysqld}
+ändern, oder durch Setzen der SQL-Option @code{SQL_BIG_TABLES} im
+Client-Programm. @xref{SET OPTION, , @code{SET OPTION}}. In MySQL-Version
+3.20 war die maximale Größe der temporären Tabelle
+@code{record_buffer*16}. Wenn Sie also diese Version benutzen, müssen Sie
+den Wert von @code{record_buffer} herauf setzen. Sie können @code{mysqld}
+auch mit der @code{--big-tables}-Option starten, um temporäre Tabellen
+immer auf Festplatte zu speichern. Das wird jedoch die Geschwindigkeit
+vieler komplizierter Anfragen beeinflussen.
+
+@item
+Den meisten Sortier-Anfragen werden ein Sortierpuffer und 0 bis 2 temporäre
+Dateien zugewiesen, abhängig von der Größe der Ergebnismenge.
+@xref{Temporary files}.
+
+@item
+Fast alles Parsen und Berechnen wird in einem lokalen Speicherbereich
+durchgeführt. Für kleine Sachen wird kein Speicher-Overhead benötigt, und
+das normale, langsame Zuweisen und Freimachen von Speicher wird vermieden.
+Speicher wird nur für unerwartet lange Zeichenketten zugewiesen (das wird
+mit @code{malloc()} und @code{free()} gemacht).
+
+@item
+Jede Index-Datei wird einmal geöffnet. Die Daten-Datei wird einmal für
+jeden gleichzeitig laufenden Thread geöffnet. Für jeden gleichzeitigen
+Thread wird eine Tabellenstruktur, Spaltenstrukturen für jede Spalte und
+ein Puffer der Größe @code{3 * n} zugewiesen, wobei @code{n} die maximale
+Zeilenlänge ist (@code{BLOB}-Spalten werden nicht mitgerechnet). Eine
+@code{BLOB}-Spalte benutzt 5 bis 8 Bytes plus die Länge der
+@code{BLOB}-Daten. Der @code{ISAM}- / @code{MyISAM}-Tabellen-Handler
+benutzt einen zusätzlichen Zeilenpuffer für internen Gebrauch.
+
+@item
+Bei jeder Tabelle, die @code{BLOB}-Spalten enthält, wird ein Puffer
+dynamisch vergrößert, um größere @code{BLOB}-Werte einzulesen. Wenn Sie
+eine Tabelle scannen, wird ein Puffer so Groß wie der größte
+@code{BLOB}-Wert zugewiesen.
+
+@item
+Tabellen-Handler für alle Tabellen in Benutzung werden in einem Cache
+gespeichert und als FIFO verwaltet. Normalerweise hat der Cache 64
+Einträge. Wenn eine Tabelle gleichzeitig von zwei laufenden Threads
+benutzt wurde, enthält der Cache zwei Einträge für die Tabelle.
+@xref{Open tables}.
+
+@item
+Ein @code{mysqladmin flush-tables}-Befehl schließt alle Tabellen, die
+nicht in Benutzung sind, und kennzeichnet alle Tabellen in Benutzung als zu
+schließen, sobald der aktuell ausführende Thread fertig ist. Das setzt
+effektiv den meisten benutzten Speicher frei.
+@end itemize
+
+@code{ps} und andere System-Status-Programme berichten vielleicht, dass
+@code{mysqld} viel Arbeitsspeicher benutzt. Das kann durch Thread-Stacks
+auf verschiedenen Speicheradressen verursacht werden. @code{ps} der
+Solaris-Version zum Beispiel zählt den unbenutzten Speicher zwischen Stacks
+zum benutzten Speicher hinzu. Das können Sie bestätigen, wenn Sie den
+verfügbaren Swap mit @code{swap -s} überprüfen. Wir haben @code{mysqld} mit
+kommerziellen Memory-Leak-Detektoren getestet, daher sollte es keine
+Memory-Leaks geben.
+
+
+@node DNS, SET OPTION, Memory use, Optimising the Server
+@c German node DNS
+@subsection Wie MySQL DNS benutzt
+
+@cindex DNS
+@cindex Caching von Hostnamen
+
+Wenn sich ein neuer Thread mit @code{mysqld} verbindet, erzeugt
+@code{mysqld} einen neuen Thread, um die Anfrage zu handhaben. Dieser
+Thread prüft zuerst, ob der Hostname im Hostnamen-Cache ist. Falls nicht,
+ruft der Thread @code{gethostbyaddr_r()} und @code{gethostbyname_r()} auf,
+um den Hostname aufzulösen.
+
+Wenn das Betriebssystem die oben genannten Thread-sicheren Aufrufe nicht
+unterstützt, sperrt der Thread ein Mutex und ruft statt dessen
+@code{gethostbyaddr()} und @code{gethostbyname()} auf. Beachten Sie, dass
+in diesem Fall kein anderer Thread andere Hostnamen auflösen kann, die
+nicht im Hostnamen-Cache sind, bis der erste Thread fertig ist.
+
+Sie können das DNS-Nachschlagen von Hostnamen (DNS-Lookup) abschalten,
+indem Sie @code{mysqld} mit @code{--skip-name-resolve} starten. In diesem
+Fall können Sie jedoch in den MySQL-Berechtigungstabellen nur IP-Nummern
+verwenden.
+
+Wenn Sie ein sehr langsames DNS und viele Hosts haben, können Sie mehr
+Performance erzielen, wenn Sie entweder das DNS-Nachschlagen von Hostnamen
+(DNS-Lookup) abschalten (mit @code{--skip-name-resolve}) oder
+@code{HOST_CACHE_SIZE} (Vorgabe: 128) erhöhen und @code{mysqld}
+neu kompilieren.
+
+Sie können den Hostnamen-Cache mit @code{--skip-host-cache} abschalten. Sie
+können den Hostnamen-Cache mit @code{FLUSH HOSTS} oder @code{mysqladmin
+flush-hosts} löschen.
+
+Wenn Sie keine Verbindungen über @code{TCP/IP} zulassen wollen, starten Sie
+@code{mysqld} mit @code{--skip-networking}.
+
+
+@node SET OPTION, , DNS, Optimising the Server
+@c German node SET OPTION
+@subsection @code{SET}-Syntax
+
+@findex SET OPTION
+
+@example
+SET [OPTION] SQL_VALUE_OPTION= wert, ...
+@end example
+
+@code{SET OPTION} setzt verschiedene Optionen, die die Arbeitsweise des
+Servers oder Ihrer Clients beeinflussen. Jede Option, die Sie setzen,
+bleibt in Kraft, bis die aktuelle Sitzung beendet wird, oder bis Sie die
+Option auf einen anderen Wert setzen.
+
+@table @code
+@item characterset zeichensatz_name | DEFAULT
+Das mappt alle Zeichenketten von und zum Client auf das angegebene Mapping.
+Momentan ist die einzige Option für @code{zeichensatz_name}
+@code{cp1251_koi8}, aber Sie können leicht neue Mappings hinzufügen, indem
+Sie die @file{sql/convert.cc}-Datei in der MySQL-Quelldistribution
+editieren. Das vorgabemäßige Mapping kann durch Setzen des
+@code{zeichensatz_name}-Werts auf @code{DEFAULT} wieder hergestellt
+werden.
+
+Beachten Sie, dass sich die Syntax für das Setzen der
+@code{characterset}-Option von der Syntax für das Setzen anderer Optionen
+unterscheidet.
+
+@item PASSWORD = PASSWORD('ein_passwort')
+@cindex Passwörter, setzen
+Setzt das Passwort für den aktuellen Benutzer. Jeder nicht anonyme Benutzer
+kann sein eigenes Passwort ändern!
+
+@item PASSWORD FOR benutzer = PASSWORD('ein_passwort')
+Setzt das Passwort für einen bestimmten Benutzer auf dem aktuellen
+Server-Host. Das kann nur ein Benutzer mit Zugriff auf die
+@code{mysql}-Datenbank tun. Der Benutzer sollte im
+@code{user@@hostname}-Format eingegeben werden, wobei @code{user} und
+@code{hostname} exakt so sind, wie sie in den @code{User}- und
+@code{Host}-Spalten des @code{mysql.user}-Tabelleneintrags aufgelistet
+sind. Wenn Sie zum Beispiel in den Spalten @code{User} und @code{Host} die
+Einträge @code{'bob'} und @code{'%.loc.gov'} haben wollen, schreiben Sie:
+
+@example
+mysql> SET PASSWORD FOR bob@@"%.loc.gov" = PASSWORD("newpass");
+
+oder
+
+mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' und host="%.loc.gov";
+@end example
+
+@item SQL_AUTO_IS_NULL = 0 | 1
+Falls auf @code{1} gesetzt (Vorgabe), wird mit folgendem Konstrukt die
+letzte eingefügte Zeile einer Tabelle mit einer auto_increment-Zeile
+gefunden:
+@code{WHERE auto_increment_spalte IS NULL}. Das wird von einigen
+ODBC-Programme wie Access benutzt.
+
+@item AUTOCOMMIT= 0 | 1
+Falls auf @code{1} gesetzt, werden alle Änderungen einer Tabelle auf einmal
+durchgeführt. Um eine Transaktion aus mehreren Befehlen anzufangen, müssen
+Sie das @code{BEGIN}-Statement benutzen. @xref{COMMIT}. Falls auf @code{0}
+gesetzt, müssen Sie @code{COMMIT} / @code{ROLLBACK} benutzen, um diese
+Transaktion zu akzeptieren / zu widerrufen. @xref{COMMIT}. Beachten Sie,
+dass MySQL nach dem Umschalten vom @code{AUTOCOMMIT}-Modus zum
+@code{AUTOCOMMIT}-Modus ein automatisches @code{COMMIT} auf alle offenen
+Transaktionen durchführt.
+
+@item SQL_BIG_TABLES = 0 | 1
+@cindex table is full
+Falls auf @code{1} gesetzt, werden alle temporären Tabellen auf Platte
+statt im Arbeitsspeicher gespeichert. Das ist etwas langsamer, aber Sie
+erhalten nicht den Fehler @code{The table tabelle is full}, wenn Sie große
+@code{SELECT}-Operationen ausführen, die eine große temporäre Tabelle
+erfordern. Der Vorgabewert für eine neue Verbindung ist @code{0} (das
+heißt, temporäre Tabellen im Arbeitsspeicher benutzen).
+
+@item SQL_BIG_SELECTS = 0 | 1
+Falls auf @code{0} gesetzt, bricht MySQL ab, wenn ein @code{SELECT} versucht
+wird, das wahrscheinlich sehr lange dauern wird. Das ist nützlich, wenn ein
+unratsames @code{WHERE}-Statement abgesetzt wurde. Ein große Anfrage ist
+definiert als ein @code{SELECT}, das wahrscheinlich mehr als
+@code{max_join_size} Zeilen untersuchen muss. Der Vorgabewert für eine neue
+Verbindung ist @code{1} (was alle @code{SELECT}-Statements zuläßt).
+
+@item SQL_BUFFER_RESULT = 0 | 1
+@code{SQL_BUFFER_RESULT} erzwingt, dass das Ergebnis von @code{SELECT}'s in
+eine temporäre Tabelle geschrieben wird. Das hilft MySQL, die
+Tabellensperren frühzeitig aufzuheben, und ist hilfreich in Fällen, wo es
+lange dauert, das Ergebnis an den Client zu senden.
+
+@item SQL_LOW_PRIORITY_UPDATES = 0 | 1
+Falls auf @code{1} gesetzt, warten alle @code{INSERT}-, @code{UPDATE}-,
+@code{DELETE}- und @code{LOCK TABLE WRITE}-Statements, bis es kein
+anhängiges @code{SELECT} oder @code{LOCK TABLE READ} für die betroffene
+Tabelle gibt.
+
+@item SQL_MAX_JOIN_SIZE = wert | DEFAULT
+Nicht zulassen, dass @code{SELECT}s, die wahrscheinlich mehr als
+@code{value} Zeilenkombinationen untersuchen müssen, ausgeführt werden.
+Wenn Sie diesen Wert setzen, können Sie @code{SELECT}s abfangen, bei denen
+Schlüssel nicht korrekt verwendet werden und die wahrscheinlich sehr lange
+dauern. Wenn dieser Wert auf etwas anderes als @code{DEFAULT} gesetzt wird,
+wird der @code{SQL_BIG_SELECTS}-Flag zurückgesetzt. Wenn Sie den
+@code{SQL_BIG_SELECTS}-Flag wieder setzen, wird die
+@code{SQL_MAX_JOIN_SIZE}-Variable ignoriert. Sie können für diese Variable
+einen Vorgabewert setzen, wenn Sie @code{mysqld} mit @code{-O
+max_join_size=#} starten.
+
+@item SQL_SAFE_UPDATES = 0 | 1
+Falls auf @code{1} gesetzt, bricht MySQL ab, wenn ein @code{UPDATE} oder
+@code{DELETE} versucht wird, das keinen Schlüssel oder kein @code{LIMIT} in
+der @code{WHERE}-Klausel benutzt. Das ermöglicht das Abfangen falscher
+Aktualisierungen, wenn SQL-Befehle von Hand eingegeben werden.
+
+@item SQL_SELECT_LIMIT = wert | DEFAULT
+Die maximale Anzahl von Datensätzen, die von @code{SELECT}-Statements
+zurückgegeben werden. Wenn ein @code{SELECT} eine @code{LIMIT}-Klausel hat,
+hat das @code{LIMIT} Vorrang vor dem Wert von @code{SQL_SELECT_LIMIT}. Der
+Vorgabewert für eine neue Verbindung ist ``unbegrenzt.'' Wenn Sie diese
+Begrenzung geändert haben, kann der Vorgabewert wieder hergestellt werden,
+indem Sie einen @code{SQL_SELECT_LIMIT}-Wert von @code{DEFAULT} verwenden.
+
+@item SQL_LOG_OFF = 0 | 1
+Falls auf @code{1} gesetzt, wird für diesen Client kein Loggen ins
+Standard-Log durchgeführt, wenn der Client die
+@strong{process}-Berechtigung hat. Das betrifft nicht die
+Update-Log-Datei!
+
+@item SQL_LOG_UPDATE = 0 | 1
+Falls auf @code{0} gesetzt, wird für diesen Client kein Loggen in die
+Update-Log-Datei durchgeführt, wenn der Client die
+@strong{process}-Berechtigung hat. Das betrifft nicht das Standard-Log!
+
+@item SQL_QUOTE_SHOW_CREATE = 0 | 1
+Falls auf @code{1} gesetzt, setzt @code{SHOW CREATE TABLE} Tabellen- und
+Spaltennamen in Anführungszeichen. Das ist vorgabemäßig
+@strong{angeschaltet}, damit Replikation von Tabellen mit merkwürdigen
+Spaltennamen funktioniert. @ref{SHOW CREATE TABLE, , @code{SHOW CREATE TABLE}}.
+
+@item TIMESTAMP = zeitstempel_wert | DEFAULT
+Setzt die Zeit für diesen Client. Das wird benutzt, um den
+Original-Zeitstempel zu erhalten, wenn sie die Update-Log-Datei benutzen,
+um Zeilen wiederherzustellen. @code{zeitstempel_wert} sollte ein
+UNIX-Epoche-Zeitstempel sein, kein MySQL-Zeitstempel.
+
+@item LAST_INSERT_ID = #
+Setzt den Wert, der von @code{LAST_INSERT_ID()} zurückgegeben wird. Dieser
+wird in der Update-Log-Datei gespeichert, wenn Sie @code{LAST_INSERT_ID()}
+in einem Befehl benutzen, der eine Tabelle aktualisiert.
+
+@item INSERT_ID = #
+Setzt den Wert, der von einem folgenden @code{INSERT}- oder @code{ALTER
+TABLE}-Befehl benutzt wird, wenn ein @code{AUTO_INCREMENT}-Wert eingefügt
+wird. Das wird hauptsächlich zusammen mit der Update-Log-Datei benutzt.
+@end table
+
+
+
+
+
+
+@node Disk issues, , Optimising the Server, MySQL Optimisation
+@c German node Festplatte
+@section Festplatte, Anmerkungen
+
+@cindex Festplatten, Anmerkungen
+@cindex Performance, Anmerkungen zur Festplatte
+
+@itemize @bullet
+@item
+Wie bereits erwähnt sind Suchvorgänge auf der Festplatte ein großer
+Performance-Flaschenhals. Die Probleme werden mehr und mehr deutlich, wenn
+die Datenmenge wächst, so dass effizientes Caching unmöglich wird. Bei
+großen Datenbanken, in denen Sie auf Daten mehr oder weniger zufällig
+zugreifen, können Sie sicher davon ausgehen, dass Sie zumindest eine
+Plattenzugriff brauchen, um zu lesen, und eine Reihe weiterer
+Plattenzugriffe, um Dinge zu schreiben. Um dieses Problem zu minimieren,
+benutzen Sie Platten mit geringen Zugriffszeiten!
+
+@item
+Erhöhen Sie die Anzahl verfügbarer Festplattenscheiben (und verringern Sie
+dadurch den Such-Overhead), indem Sie entweder Dateien auf andere Platten
+symbolisch verknüpfen (SymLink) oder die Platten 'stripen'.
+
+@table @strong
+@item Using Symbolische Links
+Das bedeutet, dass Sie die Index- und / oder Daten-Datei(en) aus dem
+normalen Daten-Verzeichnis auf eine andere Festplatte verknüpfen (die auch
+'gestriped' sein kann). Das macht sowohl den Suchvorgang als auch die
+Lesezeiten besser (wenn die Platten nicht für andere Dinge benutzt werden).
+@xref{Symbolic links}.
+
+@cindex Stripen, Definition
+@item Stripen
+'Stripen' heißt, dass Sie viele Festplatten haben und den ersten Block
+auf die erste Platte legen, den zweiten Block auf die zweite Platte und den
+n-ten Block auf die n-te Platte usw. Das bedeutet, wenn Ihre normale
+Datengröße weniger als die Stripe-Größe ist (oder perfekt passt), dass
+Sie wesentlich bessere Performance erhalten. Beachten Sie, dass Stripen
+sehr stark vom Betriebssystem und von der Stripe-Größe abhängig ist.
+Machen Sie Benchmark-Tests Ihrer Applikation mit unterschiedlichen
+Stripe-Größen. @xref{Custom Benchmarks}.
+
+Beachten Sie, dass der Geschwindigkeitsunterschied für das Stripen
+@strong{sehr} stark vom Parameter abhängig ist. Abhängig davon, wie Sie den
+Stripe-Parameter setzen und von der Anzahl von Festplatten erhalten Sie
+Unterschiede in der Größenordnung von Faktoren. Beachten Sie, dass Sie
+entscheiden müssen, ob Sie für zufällige oder sequentielle Zugriffe
+optimieren.
+@end table
+
+@item
+Aus Gründen der Zuverlässigkeit sollten sie vielleicht RAID 0 + 1 nehmen
+(Stripen + Spiegeln), doch in diesem Fall brauchen Sie 2 * n Laufwerke, um
+n Datenlaufwerke zu haben. Das ist wahrscheinlich die beste Option, wenn
+Sie genug Geld dafür haben! Sie müssen jedoch eventuell zusätzlich in
+Software für die Verwaltung von Volumes investieren, um das effizient zu
+handhaben.
+
+@item
+Eine gute Option ist es, nicht ganz so wichtige Daten (die wieder
+hergestellt werden können) auf RAID-0-Platten zu halten, während wirklich
+wichtige Daten (wie Host-Informationen und Log-Dateien) auf einer RAID-0+1-
+oder RAID-N-Platte gehalten werden. RAID-N kann ein Problem darstellen,
+wenn Sie viele Schreibzugriffe haben, weil Zeit benötigt wird, die
+Paritätsbits zu aktualisieren.
+
+@item
+Sie können auch den Parameter für das Dateisystem setzen, das die Datenbank
+benutzt. Eine einfache Änderung ist, das Dateisystem mit der noatime-Option
+zu mounten. Das bringt es dazu, das Aktualisieren der letzten Zugriffszeit
+in der Inode zu überspringen und vermeidet dadurch einige
+Platten-Suchzugriffe.
+
+@item
+Unter Linux können Sie viel mehr Performance erhalten (bis zu 100% unter
+Last ist nicht ungewöhnlich), wenn Sie hdpram benutzen, um die
+Schnittstelle Ihrer Festplatte zu konfigurieren! Das folgende Beispiel
+sollte recht gute hdparm-Optionen für MySQL (und wahrscheinlich viele
+andere Applikationen) darstellen:
+
+@example
+hdparm -m 16 -d 1
+@end example
+
+Beachten Sie, dass Performance und Zuverlässigkeit beim oben Genannten von
+Ihrer Hardware abhängen, daher empfehlen wir sehr, dass Sie Ihr System
+gründlich testen, nachdem Sie @code{hdparm} benutzt haben! Sehen Sie in der
+Handbuchseite (ManPage) von @code{hdparm} nach weiteren Informationen! Wenn
+@code{hdparm} nicht vernünftig benutzt wird, kann das Ergebnis eine
+Beschädigung des Dateisystems sein. Machen Sie eine Datensicherung von
+allem, bevor Sie experimentieren!
+
+@item
+Auf vielen Betriebssystemen können Sie die Platten mit dem 'async'-Flag
+mounten, um das Dateisystem auf asynchrone Aktualisierung zu setzen. Wenn
+Ihr Computer ausreichend stabil ist, sollte Ihnen das mehr Performance
+geben, ohne zu viel Zuverlässigkeit zu opfern. (Dieser Flag ist unter Linux
+vorgabemäßig angeschaltet.)
+
+@item
+Wenn Sie nicht wissen müssen, wann auf eine Datei zuletzt zugegriffen
+wurden (was auf einem Datenbank-Server nicht wirklich nötig ist), können
+Sie Ihr Dateisystem mit dem noatime-Flag mounten.
+@end itemize
+
+
+
+@menu
+* Symbolic links::
+@end menu
+
+@node Symbolic links, , Disk issues, Disk issues
+@c German node Symbolische Links
+@subsection Symbolische Links benutzen
+
+@cindex Symbolische Links
+@cindex Links, symbolische
+
+Sie können Tabellen und Datenbanken vom Datenbank-Verzeichnis an andere
+Stellen verschieben und sie mit symbolischen Links auf neue Speicherorte
+ersetzen. Das könnten Sie zum Beispiel tun, um eine Datenbank auf ein
+Dateisystem mit mehr freiem Speicherplatz zu verlagern oder um die
+Geschwindigkeit Ihres System durch Verteilen Ihrer Tabellen auf
+unterschiedliche Platten zu steigern.
+
+Die empfohlene Art, das zu tun, ist, nur Datenbanken auf unterschiedliche
+Platten per SymLink zu verknüpfen, und das bei Tabellen nur im Notfall zu
+tun.
+
+@cindex Datenbanken, Symbolische Links
+
+
+@menu
+* Symbolic links to databases::
+* Symbolic links to tables::
+@end menu
+
+@node Symbolic links to databases, Symbolic links to tables, Symbolic links, Symbolic links
+@c German node Symbolische Links auf Datenbanken
+@subsubsection Benutzung symbolischer Links für Datenbanken
+
+Um eine Datenbank per SymLink zu verknüpfen, legt man zuerst ein
+Verzeichnis auf einer Platte mit freiem Speicherplatz an und erzeugt dann
+einen SymLink vom MySQL-Datenbank-Verzeichnis aus darauf:
+
+@example
+shell> mkdir /dr1/datenbanken/test
+shell> ln -s /dr1/datenbanken/test mysqld-datadir
+@end example
+
+MySQL unterstützt nicht das Verknüpfen eines Verzeichnisses zu mehrfachen
+Datenbanken. Wenn Sie ein Datenbank-Verzeichnis mit einem symbolischen Link
+ersetzen, funktioniert das solange gut, wie Sie keinen symbolischen Link
+zwischen Datenbanken machen. Angenommen, Sie haben eine Datenbank
+@code{datenbank1} unter dem MySQL-Daten-Verzeichnis und machen dann einen
+Symlink @code{datenbank2}, der auf @code{datenbank1} zeigt:
+
+@example
+shell> cd /pfad/zu/datadir
+shell> ln -s datenbank1 datenbank2
+@end example
+
+Jetzt erscheint für jede Tabelle @code{tabelle_a} in @code{datenbank1} auch
+eine Tabelle @code{tabelle_a} in @code{datenbank2}. Wenn ein Thread
+@code{datenbank1.tabelle_a} aktualisiert und ein anderer Thread
+@code{datenbank2.tabelle_a} aktualisiert, gibt es Probleme.
+
+Wenn Sie das wirklich brauchen, müssen Sie folgenden Code in
+@file{mysys/mf_format.c} ändern:
+
+@example
+if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
+@end example
+
+zu:
+
+@example
+if (1)
+@end example
+
+Unter Windows können Sie interne symbolische Links auf Verzeichnisse
+benutzen, indem Sie MySQL mit @code{-DUSE_SYMDIR} kompilieren. Das erlaubt
+Ihnen, verschiedene Datenbanken auf verschiedene Platte zu legen.
+@xref{Windows symbolic links}.
+
+
+@node Symbolic links to tables, , Symbolic links to databases, Symbolic links
+@c German node Symbolische Links auf Tabellen
+@subsubsection Benutzung symbolischer Links für Tabellen
+
+@cindex Datenbanken, Symbolische Links
+
+Vor MySQL 4.0 konnten Sie Tabellen nicht per SymLink verknüpfen, wenn Sie
+nicht sehr sorgfältig dabei vorgingen. Das Problem liegt darin, dass bei
+@code{ALTER TABLE}, @code{REPAIR TABLE} oder @code{OPTIMIZE TABLE} auf eine
+per Symlink verknüpfte Datei die SymLinks entfernt und durch die
+Original-Dateien verknüpft werden. Das geschieht, weil beim obigen Befehl
+eine temporäre Datei im Datenbank-Verzeichnis erzeugt wird, und wenn der
+Befehl ausgeführt ist, die Original-Datei durch die temporäre Datei
+ersetzt wird.
+
+Sie sollten Tabellen auf Systemen, die keinen vollständig funktionierenden
+@code{realpath()}-Aufruf haben, nicht per SymLink verknüpfen. (Zumindest
+Linux und Solaris unterstützen @code{realpath()}.)
+
+In MySQL 4.0 werden Symlinks nur für @code{MyISAM}-Tabellen vollständig
+unterstützt. Bei anderen Tabellentypen erhalten Sie wahrscheinlich
+merkwürdige Probleme, wenn Sie einen der obigen Befehle ausführen.
+
+Die Handhabung symbolischer Links in MySQL 4.0 funktioniert auf folgende
+Art (das gilt meist nur für @code{MyISAM}-Tabellen):
+
+@itemize @bullet
+@item
+Im Daten-Verzeichnis liegen immer die Tabellendefinitionsdatei und die
+Daten-/Index-Dateien.
+
+@item
+Sie können die Index-Datei und die Daten-Datei unabhängig voneinander auf
+unterschiedliche Verzeichnisse per SymLink verknüpfen.
+
+@item
+Das Erzeugen der SymLinks kann durch das Betriebssystem (wenn @code{mysqld}
+nicht läuft) oder mit dem @code{INDEX/DATA
+directory="pfad-zum-verzeichnis"}-Befehl in @code{CREATE TABLE}
+durchgeführt werden. @xref{CREATE TABLE}.
+
+@item
+@code{myisamchk} ersetzt keinen Symlink mit der Index-/Datendatei, sondern
+arbeitet direkt mit den Dateien, auf die die SymLinks verweisen. Jegliche
+temporäre Dateien werden im selben Verzeichnis erzeugt, wo die
+Daten-/Index-Datei ist.
+
+@item
+Wenn Sie eine Tabelle löschen, die Symlinks benutzt, werden sowohl der
+Symlink als auch die Datei, auf die der SymLink zeigt, gelöscht. Das ist
+ein guter Grund dafür, @code{mysqld} NICHT als Root laufen zu lassen und
+niemandem zu erlauben, Schreibzugriff auf die MySQL-Datenbankverzeichnisse
+zu haben.
+
+@item
+Wenn Sie eine Tabelle mit @code{ALTER TABLE RENAME} umbenennen und nicht
+die Datenbank ändern, wird der Symlink im Datenbank-Verzeichnis auf den
+neuen Namen umbenannt und die Daten-/Index-Datei wird entsprechend
+umbenannt.
+
+@item
+Wenn Sie @code{ALTER TABLE RENAME} benutzen, um eine Tabelle in eine andere
+Datenbank zu verschieben, wird die Tabelle in das andere
+Datenbank-Verzeichnis verschoben und die alten SymLinks und die Dateien,
+auf die sie zeigen, werden gelöscht.
+
+@item
+Wenn Sie keine Symlinks benutzen, sollten Sie die
+@code{--skip-symlink}-Option für @code{mysqld} benutzen, damit niemand eine
+Datei ausserhalb des @code{mysqld} Daten-Verzeichnisses löschen oder
+umbenennen kann.
+@end itemize
+
+Dinge, die noch nicht unterstützt werden:
+
+@cindex TODO, SymLinks
+@itemize @bullet
+@item
+@code{ALTER TABLE} ignoriert alle @code{INDEX/DATA directory="pfad"}-Optionen.
+@item
+@code{CREATE TABLE} berichtet nicht, wenn eine Tabelle symbolische Links hat.
+@item
+@code{mysqldump} gibt die Information über symbolische Links nicht in der Ausgabe aus.
+@item
+@code{BACKUP TABLE} und @code{RESTORE TABLE} respektieren keine symbolischen Links.
+@end itemize
+
+
+@node Reference, Table types, MySQL Optimisation, Top
+@c German node Referenz
+@chapter MySQL-Sprachreferenz
+
+
+MySQL hat eine sehr komplexe, aber intuitive und leicht zu erlernende
+SQL-Schnittstelle. Dieses Kapitel beschreibt die verschiedenen Befehle,
+Typen und Funktionen, die Sie kennen müssen, um MySQL effizient und
+effektiv zu benutzen. Dieses Kapitel dient auch als Referenz für die
+gesamte in MySQL beinhaltete Funktionalität. Um dieses Kapitel effektiv zu
+nutzen, sollten Sie unter den verschiedenen Stichworten nachschlagen.
+
+
+@menu
+* Language Structure::
+* Column types::
+* Functions::
+* Data Manipulation::
+* Data Definition::
+* Basic User Commands::
+* Transactional Commands::
+* Fulltext Search::
+* Query Cache::
+@end menu
+
+@node Language Structure, Column types, Reference, Reference
+@c German node Sprachstruktur
+@section Sprachstruktur
+
+
+
+@menu
+* Literals::
+* Legal names::
+* Name case sensitivity::
+* Variables::
+* Comments::
+* Reserved words::
+@end menu
+
+@node Literals, Legal names, Language Structure, Language Structure
+@c German node Literale
+@subsection Literale: Wie Zeichenketten und Zahlen geschrieben werden
+
+@cindex Zeichenketten, Definition
+@cindex Zeichenketten, Fluchtzeichen (Escape-Zeichen)
+@cindex Literale
+@cindex Fluchtzeichen (Escape-Zeichen)
+@cindex Backslash, Fluchtzeichen (Escape-Zeichen)
+
+
+
+Dieser Abschnitt beschreibt die verschiedenen Arten, in MySQL Zeichenketten
+und Zahlen zu schreiben. Ebenfalls enthalten sind die verschiedenen Nuancen
+und Fallstricke, in denen man sich bei den grundlegenden Datentypen von
+MySQL verfangen kann.
+
+
+@menu
+* String syntax::
+* Number syntax::
+* Hexadecimal values::
+* NULL values::
+@end menu
+
+@node String syntax, Number syntax, Literals, Literals
+@c German node Zeichenketten-Syntax
+@subsubsection Zeichenketten
+
+Eine Zeichenkette ist eine Folge von Zeichen, die entweder von Apostrophs
+(einfachen Anführungszeichen, @samp{'}) oder (doppelten) Anführungszeichen
+(@samp{"}) umgeben ist (nur einfache Anführungszeichen, wenn Sie MySQL im
+ANSI-Modus laufen lassen). Beispiele:
+
+@example
+'eine Zeichenkette'
+"eine weitere Zeichenkette"
+@end example
+
+Innerhalb einer Zeichenkette haben bestimmte Folgen eine spezielle
+Bedeutung. Jede dieser Folgen fängt mit einem Backslash (@samp{\}) an,
+bekannt als @emph{Fluchtzeichen (Escape-Zeichen)}. MySQL erkennt folgende
+Flucht-Folgen (Escape-Folgen):
+
+@c these aren't really Funktionen, aber that's wahrscheinlich the most reasonable index
+@table @code
+@findex \0 (ASCII 0)
+@findex NUL
+@item \0
+Ein ASCII-0- (@code{NUL}) Zeichen.
+
+@findex \' (Apostroph)
+@findex single quote (\')
+@item \'
+Ein Apostroph- (@samp{'}) Zeichen.
+
+@findex \" (Anführungszeichen)
+@findex Anführungszeichen (\")
+@item \"
+Ein Anführungszeichen (@samp{"}).
+
+@findex \b (Rückschritt, Backspace)
+@findex backspace (\b)
+@item \b
+Ein Rückschritt- (Backspace-) Zeichen.
+
+@findex \n (neue Zeile)
+@findex newline (\n)
+@item \n
+Ein Neue-Zeile- (Newline-) Zeichen.
+
+@findex \r (Wagenrücklauf (carriage return))
+@findex return (\r)
+@findex Wagenrücklauf (carriage return) (\r)
+@item \r
+Ein Wagenrücklauf- (carriage return) Zeichen.
+
+@findex \t (Tabulator)
+@findex tab (\t)
+@item \t
+Ein Tabulator-Zeichen.
+
+@findex \z (Steuerung-Z) ASCII(26)
+@findex (Steuerung-Z) \z
+@item \z
+ASCII(26) (Steuerung-Z). Dieses Zeichen kann kodiert werden, um das Problem
+zu umgehen, dass ASCII(26) unter Windows für Dateiende (END-OF-FILE) steht.
+(ASCII(26) verursacht Probleme, wenn Sie @code{mysql Datenbank < Dateiname}
+benutzen.)
+
+@findex \\ (Fluchtzeichen, Escape-Zeichen)
+@findex escape (\\)
+@item \\
+Ein Backslash- (@samp{\}) Zeichen.
+
+@c German FIX added space before %
+@findex % (Platzhalterzeichen)
+@findex Wild card character (%)
+@item \%
+Ein @samp{%}-Zeichen. Dieses wird benutzt, um nach literalen Instanzen von
+@samp{%} in Zusammenhängen zu suchen, wo @samp{%} ansonsten als
+Platzhalterzeichen interpretiert werden würde.
+@xref{String comparison functions}.
+
+@findex _ (Platzhalterzeichen)
+@findex Wild card character (_)
+@item \_
+Ein @samp{_}-Zeichen. Dieses wird benutzt, um nach literalen Instanzen von
+@samp{_} in Zusammenhängen zu suchen, wo @samp{_} ansonsten als
+Platzhalterzeichen interpretiert werden würde.
+@xref{String comparison functions}.
+@end table
+
+Beachten Sie, dass bei der Benutzung von @samp{\%} oder @samp{\_} in
+einigen Zeichenketten-Zusammenhängen diese die Zeichenketten @samp{\%} und
+@samp{\_} und nicht @samp{%} und @samp{_} zurückgeben.
+
+@cindex Anführungszeichen, in Zeichenketten
+@noindent
+Es gibt verschiedene Möglichkeiten, Anführungszeichen innerhalb einer
+Zeichenkette zu schreiben:
+
+@itemize @bullet
+@item
+Ein @samp{'} innerhalb einer Zeichenkette, die mit @samp{'} begrenzt wird,
+kann als @samp{''} geschrieben werden.
+
+@item
+Ein @samp{"} innerhalb einer Zeichenkette, die @samp{"} begrenzt wird, kann
+als @samp{""} geschrieben werden.
+
+@item
+Sie können dem Anführungszeichen ein Fluchtzeichen (Escape-Zeichen)
+(@samp{\}) voranstellen.
+
+@item
+Ein @samp{'} innerhalb einer Zeichenkette, die mit @samp{"} begrenzt wird,
+braucht keine spezielle Behandlung und muss nicht verdoppelt oder escapet
+werden. In gleicher Weise benötigt @samp{"} innerhalb einer Zeichenkette,
+die mit @samp{'} begrenzt wird, keine spezielle Behandlung.
+@end itemize
+
+Die unten stehenden @code{SELECT}-Statements zeigen, wie Quoten und Escapen
+funktionieren:
+
+@example
+mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
++-------+---------+-----------+--------+--------+
+| hello | "hello" | ""hello"" | hel'lo | 'hello |
++-------+---------+-----------+--------+--------+
+
+mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
++-------+---------+-----------+--------+--------+
+| hello | 'hello' | ''hello'' | hel"lo | "hello |
++-------+---------+-----------+--------+--------+
+
+mysql> SELECT "Das\nsind\nvier\nZeilen";
++--------------------+
+| Das
+sind
+vier
+Zeilen |
++--------------------+
+@end example
+
+@cindex Binärdaten quoten
+
+Wenn Sie Binärdaten in eine @code{BLOB}-Spalte einfügen, müssen folgende
+Zeichen durch Flucht-Folgen repräsentiert werden:
+@table @code
+@item NUL
+ASCII 0. Dieses geben Sie als @samp{\0} ein (ein Backslash und ein
+ASCII-@samp{0}-Zeichen).
+@item \
+ASCII 92, Backslash. Das geben Sie als @samp{\\} ein.
+@item '
+ASCII 39, Apostroph. Das geben Sie als @samp{\'} ein.
+@item "
+ASCII 34, Anführungszeichen. Das geben Sie als @samp{\"} ein.
+@end table
+
+@cindex Quoten
+@cindex @code{BLOB}, Binärdaten einfügen
+@findex mysql_escape_string()
+@findex DBI->quote
+Wenn Sie C-Code schreiben, können Sie die C-API-Funktion
+@code{mysql_escape_string()} für Fluchtzeichen (Escape-Zeichen) für das
+@code{INSERT}-Statement benutzen. @xref{C API function overview}. In Perl
+können Sie die @code{quote}-Methode des @code{DBI}-Pakets benutzen, um
+Sonderzeichen in die korrekten Flucht-Folgen umzuwandeln.
+@xref{Perl DBI Class, , Perl-@code{DBI}-Klasse}.
+
+Sie sollten auf jede Zeichenkette, die eins der oben erwähnten
+Sonderzeichen enthalten könnte, eine der Flucht-Funktionen anwenden!
+
+
+@node Number syntax, Hexadecimal values, String syntax, Literals
+@c German node Zahlen-Syntax
+@subsubsection Zahlen
+
+@cindex Zahlen
+@cindex gültige Zahlen, Beispiele
+@cindex Ganzzahlen
+@cindex Fließkommazahlen
+@cindex negative Werte
+
+Ganzzahlen werden als Folge von Ziffern repräsentiert. Fließkommazahlen
+benutzen @samp{.} als Dezimalseparator. Jedem Zahlentyp kann @samp{-}
+vorangestellt werden, um einen negativen Wert anzuzeigen.
+
+Beispiele gültiger Ganzzahlen:
+
+@example
+1221
+0
+-32
+@end example
+
+Beispiele gültiger Fließkommazahlen:
+
+@example
+294.42
+-32032.6809e+10
+148.00
+@end example
+
+Eine Ganzzahl kann in einem Fließkomma-Zusammenhang benutzt werden, sie
+wird dann als die äquivalente Fließkommazahl interpretiert.
+
+
+@node Hexadecimal values, NULL values, Number syntax, Literals
+@c German node Hexadezimale Werte
+@subsubsection Hexadezimale Werte
+
+@tindex hexadezimale Werte
+
+MySQL unterstützt hexadezimale Werte. In Zahlen-Zusammenhängen
+funktionieren diese wie eine Ganzzahl (64-Bit-Genauigkeit). Im
+Zeichenketten-Zusammenhang funktionieren sie wie eine binäre Zeichenkette,
+wobei jedes Paar hexadezimaler Ziffern in ein Zeichen umgewandelt wird:
+
+@example
+mysql> SELECT x'FF'
+ -> 255
+mysql> SELECT 0xa+0;
+ -> 10
+mysql> select 0x5061756c;
+ -> Paul
+@end example
+
+Die x'hexadezimale_zeichenkette'-Syntax (neu in Version 4.0) basiert auf
+ANSI-SQL. Die 0x-Syntax basiert auf ODBC. Hexadezimale Zeichenketten werden
+oft von ODBC benutzt, um Werte für BLOB-Spalten anzugeben.
+
+
+@node NULL values, , Hexadecimal values, Literals
+@c German node NULL-Werte
+@subsubsection @code{NULL}-Werte
+
+@tindex NULL-Wert
+
+Der @code{NULL}-Wert bedeutet ``keine Daten'' und unterscheidet sich von
+Werten wie @code{0} bei numerischen Typen oder der leeren Zeichenkette bei
+Zeichenkettentypen. @xref{Problems with NULL, , Probleme mit @code{NULL}}.
+
+@code{NULL} kann durch @code{\N} repräsentiert werden, wenn Sie die
+Textdatei-Import- oder Exportformate (@code{LOAD DATA INFILE}, @code{SELECT
+... INTO OUTFILE}) benutzen. @xref{LOAD DATA, , @code{LOAD DATA}}.
+
+
+@node Legal names, Name case sensitivity, Literals, Language Structure
+@c German node Erlaubte Namen
+@subsection Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen
+
+@cindex Namen
+@cindex erlaubte Namen
+@cindex Datenbanken, Namen
+@cindex Tabellen, Namen
+@cindex Indexe, Namen
+@cindex Spalten, Namen
+@cindex Aliase, Namen
+
+
+
+Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen folgen in MySQL
+alle denselben Regeln.
+
+@tindex Bezeichner, quoten
+@tindex Quoten von Bezeichnern
+@tindex `
+@tindex "
+Beachten Sie, dass sich die Regeln ab MySQL-Version 3.23.6 geändert haben,
+als das Quoten von Bezeichnern (für Datenbank-, Tabellen- und Spaltennamen)
+eingeführt wurde, mit @samp{`}. @samp{"} funktioniert ebenfalls, um
+Bezeichner zu quoten, wenn Sie im ANSI-Modus fahren. @xref{ANSI mode}.
+
+@multitable @columnfractions .15 .15 .70
+@item @strong{Bezeichner} @tab @strong{Maximale Länge} @tab @strong{Erlaubte Zeichen}
+@item Datenbank @tab 64 @tab Jedes Zeichen, dass für ein Verzeichnis erlaubt ist, ausser @samp{/} oder @samp{.}.
+@item Tabelle @tab 64 @tab Jedes Zeichen, dass für einen Dateinamen erlaubt ist, ausser @samp{/} oder @samp{.}.
+@item Spalte @tab 64 @tab Alle Zeichen.
+@item Alias @tab 255 @tab Alle Zeichen.
+@end multitable
+
+Hinzuzufügen ist, dass Sie ASCII(0), ASCII(255) oder das Quote-Zeichen in
+einem Bezeichner nicht verwenden dürfen.
+
+Beachten Sie, dass, falls der Bezeichner ein reserviertes Wort ist oder
+Sonderzeichen enthält, er bei der Benutzung immer in @code{`} angegeben
+sein muss:
+
+@example
+SELECT * from `select` where `select`.id > 100;
+@end example
+
+In vorherigen Versionen von MySQL sind die Namensregeln wie folgt:
+
+@itemize @bullet
+@item
+Ein Name muss aus alphanumerischen Zeichen des aktuellen Zeichensatzes
+bestehen und darf darüber hinaus @samp{_} und @samp{$} enthalten. Der
+vorgabemäßige Zeichensatz ist ISO-8859-1 Latin1; dass kann durch die
+@code{--default-character-set}-Option für @code{mysqld} geändert werden.
+@xref{Character sets}.
+
+@item
+Ein Name kann mit jedem Zeichen anfangen, das in einem Namen erlaubt ist.
+Insbesondere kann ein Name auch mit einer Zahl anfangen (das ist in vielen
+anderen Datenbanksystemen anders!). Jedoch kann ein Namen nicht @emph{nur}
+aus Zahlen bestehen.
+
+@item
+Sie können das @samp{.}-Zeichen in Namen nicht benutzen, weil es benutzt
+wird, um das Format zu erweitern, mit dem man auf Spalten verweisen kann
+(siehe unten).
+@end itemize
+
+Es wird empfohlen, dass Sie keine Namen wie @code{1e} verwenden, weil ein
+Ausdruck wie @code{1e+1} mehrdeutig ist. Er kann als der Ausdruck @code{1e
++ 1} oder als die Zahl @code{1e+1} interpretiert werden.
+
+In MySQL können Sie in folgender Form auf Spalten verweisen:
+
+@multitable @columnfractions .35 .65
+@item @strong{Spaltenverweis} @tab @strong{Bedeutung}
+@item @code{spalten_name} @tab Spalte des Namens @code{spalten_name} einer
+beliebigen, in der Anfrage verwendeten Tabelle.
+@item @code{tabelle.spalten_name} @tab Spalte des Namens
+@code{spalten_name} der Tabelle @code{tabelle} der aktuellen Datenbank.
+@item @code{datenbank.tabelle.spalten_name} @tab Spalte des Namens
+@code{spalten_name} der Tabelle @code{tabelle} der Datenbank
+@code{datenbank}. Diese Form ist ab MySQL-Version 3.22 verfügbar.
+@item
+@code{`spalte`} @tab Eine Spalte, die ein reserviertes Wort ist oder
+Sonderzeichen enthält.
+@end multitable
+
+Das @code{tabelle}- oder @code{datenbank.tabelle}-Präfix müssen Sie bei
+einem Spaltenverweis in einem Statement nicht angeben, es sei denn, der
+Verweis wäre ansonsten doppeldeutig. Nehmen Sie zum Beispiel an, die
+Tabellen @code{t1} und @code{t2} enthielten beide jeweils eine Spalte
+@code{c} und Sie verweisen auf @code{c} in einem @code{SELECT}-Statement,
+das sowohl @code{t1} als auch @code{t2} benutzt. In diesem Fall ist
+@code{c} mehrdeutig, weil es innerhalb der im Statement benutzten Tabellen
+nicht eindeutig ist. Daher müssen Sie angeben, welche Tabelle Sie meinen,
+indem Sie @code{t1.c} oder @code{t2.c} schreiben. Ähnliches gilt, wenn Sie
+aus einer Tabelle @code{t} in Datenbank @code{datenbank1} und von eine
+Tabelle @code{t} in Datenbank @code{datenbank2} abrufen. Dann müssen Sie
+auf Spalten in diesen Tabellen als @code{datenbank1.t.spalten_name} und
+@code{datenbank2.t.spalten_name} verweisen.
+
+@cindex ODBC Kompatibilität
+@cindex Kompatibilität, mit ODBC
+Die Syntax @code{.tabelle} bedeutet die Tabelle @code{tabelle} in der
+aktuellen Datenbank. Diese Syntax wird aus Gründen der ODBC-Kompatibilität
+akzeptiert, weil einige ODBC-Programme Tabellenname ein @samp{.}-Zeichen
+voranstellen.
+
+
+@node Name case sensitivity, Variables, Legal names, Language Structure
+@c German node Groß-/Kleinschreibung in Namen
+@subsection Groß-/Kleinschreibung in Namen
+
+@cindex Namen, Groß-/Kleinschreibung
+@cindex Groß-/Kleinschreibung, in Namen
+@cindex Datenbanknamen, Groß-/Kleinschreibung
+@cindex Tabellennamen, Groß-/Kleinschreibung
+@cindex Spaltennamen, Groß-/Kleinschreibung
+@cindex Aliasnamen, Groß-/Kleinschreibung
+
+In MySQL entsprechen Datenbanken und Tabellen Verzeichnissen und Dateien
+innerhalb dieser Verzeichnisse. Folglich hängt die Groß-/Kleinschreibung
+davon ab, wie das zugrunde liegende Betriebssystem die
+Groß-/Kleinschreibung von Datenbank- und Tabellennamen festlegt. Das
+bedeutet, dass Datenbank- und Tabellennamen unter Unix von der
+Groß-/Kleinschreibung abhängen und unter Windows nicht.
+@xref{Extensions to ANSI}.
+
+@strong{HINWEIS:} Obwohl die Groß-/Kleinschreibung für Datenbank- und
+Tabellennamen unter Windows keine Rolle spielt, sollten Sie nicht auf eine
+angegebene Datenbank oder Tabelle innerhalb derselben Anfrage mit
+unterschiedlicher Schreibweise verweisen. Folgende Anfrage würde nicht
+funktionieren, weil sie auf eine Tabelle sowohl mit @code{meine_tabelle}
+als auch mit @code{MEINE_TABELLE} verweist:
+
+@example
+mysql> SELECT * FROM meine_tabelle WHERE MEINE_TABELLE.spalte=1;
+@end example
+
+Spaltennamen hängen in keinem Fall von der verwendeten
+Groß-/Kleinschreibung ab.
+
+Aliase auf Tabellen hängen von der Groß-/Kleinschreibung ab. Folgende
+Anfrage würde nicht funktionieren, weil sie auf den Alias sowohl mit
+@code{a} als auch mit @code{A} verweist:
+
+@example
+mysql> SELECT spalten_name FROM tabelle AS a
+ WHERE a.spalten_name = 1 OR A.spalten_name = 2;
+@end example
+
+Aliase auf Spalten hängen nicht von der verwendeten Groß-/Kleinschreibung
+ab.
+
+Wenn Sie Probleme damit haben, sich an die Schreibweise von Tabellennamen zu
+erinnern, halten Sie sich an eine durchgehende Konvention. Benutzen Sie zum
+Beispiel bei der Erzeugung von Datenbanken und Tabellen Kleinschreibung in
+Namen.
+
+Eine Möglichkeit, dieses Problem zu vermeiden, ist, @code{mysqld} mit
+@code{-O lower_case_tabelles=1} zu starten. Vorgabemäßig ist diese Option
+1 unter Windows und 0 unter Unix.
+
+Wenn @code{lower_case_tabelles} 1 ist, wandelt MySQL alle Tabellennamen in
+Kleinschreibung um, sowohl beim Speichern als auch beim Nachschlagen. Wenn
+Sie diese Option ändern, beachten Sie, dass Sie zuerst Ihre alten
+Tabellennamen in Kleinschreibung umwandeln müssen, bevor Sie @code{mysqld}
+starten.
+
+
+@node Variables, Comments, Name case sensitivity, Language Structure
+@c German node Variablen
+@subsection Benutzer-Variablen
+
+@cindex Variablen, Benutzer-
+@cindex Benutzer-Variablen
+@cindex Namen, Variablen
+
+MySQL unterstützt Thread-spezifische Variablen mit der
+@code{@@variablename}-Syntax. Eine Variable kann aus alphanumerischen
+Zeichen des aktuellen Zeichensatzes sowie aus @samp{_}, @samp{$} und
+@samp{.} bestehen. Der vorgabemäßige Zeichensatz ist ISO-8859-1 Latin1;
+das kann mit der @code{--default-character-set}-Option für @code{mysqld}
+geändert werden. @xref{Character sets}.
+
+Variablen müssen nicht initialisiert werden. Sie enthalten vorgabemäßig
+@code{NULL} und können Ganzzahl-, Real- oder Zeichenketten-Werte speichern.
+Alle Variablen für einen Thread werden automatisch freigegeben, wenn der
+Thread beendet wird.
+
+Sie können eine Variable mit der @code{SET}-Syntax setzen:
+
+@example
+SET @@variable= @{ ganzzahl_ausdruck | realzahl_ausdruck | zeichenketten_ausdruck @} [,@@variable= ...].
+@end example
+
+Sie können eine Variable in einem Ausdruck auch mit der
+@code{@@variable:=expr}-Syntax setzen:
+
+@example
+select @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
++----------------------+------+------+------+
+| @@t1:=(@@t2:=1)+@@t3:=4 | @@t1 | @@t2 | @@t3 |
++----------------------+------+------+------+
+| 5 | 5 | 1 | 4 |
++----------------------+------+------+------+
+@end example
+
+(Wir mussten hier die @code{:=}-Syntax benutzen, weil @code{=} für
+Vergleiche reserviert ist.)
+
+Benutzer-Variablen können benutzt werden, wo Ausdrücke erlaubt sind.
+Beachten Sie, dass das momentan keine Zusammenhänge einschließt, in denen
+explizit Zahlen erforderlich sind, wie in der @code{LIMIT}-Klausel eines
+@code{SELECT}-Statements oder der @code{IGNORE Anzahl LINES}-Klausel eines
+@code{LOAD DATA}-Statements.
+
+@strong{HINWEIS:} In einem @code{SELECT}-Statement wird jeder Ausdruck
+erst dann ausgewertet, wenn er an den Client geschickt wird. Das heißt,
+dass Sie in der @code{HAVING}-, @code{GROUP BY}- oder @code{ORDER
+BY}-Klausel nicht auf einen Ausdruck verweisen können, der Variablen
+beinhaltet, die nicht im @code{SELECT}-Teil gesetzt wurden. Folgendes
+Statement zum Beispiel funktioniert erwartungsgemäß NICHT:
+
+@example
+SELECT (@@aa:=id) AS a, (@@aa+3) AS b FROM tabelle HAVING b=5;
+@end example
+
+Der Grund ist, dass @code{@@aa} nicht den Wert der aktuellen Zeile enthält,
+sondern den Wert von @code{id} der vorher akzeptierten Zeile.
+
+
+
+@node Comments, Reserved words, Variables, Language Structure
+@c German node Kommentare
+@subsection Kommentar-Syntax
+
+@findex Kommentar-Syntax
+
+@cindex Kommentare, hinzufügen
+
+Der MySQL-Server die Kommentar-Stile @code{# bis Zeilenende}, @code{-- bis
+Zeilenende} und @code{/* mittendrin oder mehrzeilig */}:
+
+@example
+mysql> select 1+1; # Dieser Kommentar geht bis zum Zeilenende
+mysql> select 1+1; -- Dieser Kommentar geht bis zum Zeilenende
+mysql> select 1 /* Das ist ein Kommentar mittendrin */ + 1;
+mysql> select 1+
+/*
+Das ist ein
+mehrzeiliger
+Kommentar
+*/
+1;
+@end example
+
+Beachten Sie, dass Sie beim Kommentarstil @code{--} mindestens ein
+Leerzeichen hinter @code{--} setzen müssen!
+
+Obwohl der Server die Kommentar-Syntax wie beschrieben versteht, gibt es
+einige Einschränkungen in der Art, wie der @code{mysql}-Client @code{/* ...
+*/}-Kommentare parst:
+
+@itemize @bullet
+@item
+Einfache und doppelte Anführungszeichen werden genommen, um den Anfang
+einer Zeichenkette zu bestimmen, selbst innerhalb eines Kommentars. Wenn
+die Zeichenkette nicht durch ein zweites Anführungszeichen innerhalb des
+Kommentars abgeschlossen wird, bemerkt der Parser nicht, dass der Kommentar
+zuende ist. Wenn Sie @code{mysql} interaktiv ausführen, sehen Sie, dass
+@code{mysql} verwirrt ist, weil sich die Eingabeaufforderung von
+@code{mysql>} zu to @code{'>} oder @code{">} ändert.
+
+@item
+Ein Semikolon wird genommen, um das Ende des aktuellen SQL-Statements
+kenntlich zu machen. Alles Folgende wird als Anfang des nächsten Statements
+aufgefasst.
+@end itemize
+
+Diese Einschränkungen gelten sowohl, wenn Sie @code{mysql} interaktiv
+ausführen und wenn Sie Befehle in eine Datei schreiben und @code{mysql} mit
+@code{mysql < some-file} anweisen, seine Eingaben aus dieser Datei zu
+lesen.
+
+MySQL unterstützt nicht den ANSI-SQL-Kommentarstil @samp{--} ohne
+nachfolgendes Leerzeichen. @xref{ANSI diff comments}.
+
+
+@node Reserved words, , Comments, Language Structure
+@c German node Reservierte Wörter
+@subsection Ist MySQL pingelig hinsichtlich reservierter Wörter?
+
+@cindex Schlüsselwörter
+@cindex reservierte Wörter, Ausnahmen
+
+Ein häufiges Problem rührt daher, dass versucht wird, eine Tabelle mit
+Spaltennamen zu erzeugen, den die Namen von Datentypen oder in MySQL
+eingebauten Funktionen entsprechen, wie @code{TIMESTAMP} oder @code{GROUP}.
+Sie dürfen das tun (beispielsweise ist @code{ABS} ein zulässiger
+Spaltenname), aber es sind dann keine Leerzeichen zwischen einem
+Funktionsname und der @samp{(} erlaubt, wenn Sie Funktionen benutzen, deren
+Namen auch Spaltennamen sind.
+
+Folgende Wörter sind in MySQL explizit reserviert. Die meisten davon sind
+in ANSI-SQL92 als Spalten- und / oder Tabellennamen verboten (zum Beispiel
+@code{group}). Einige wenige sind reserviert, weil MySQL sie benötigt und
+(momentan) einen @code{yacc}-Parser benutzt:
+
+@c This ist fixed von including the symbols Tabelle von lex.h here und then running
+@c fix-mysql-reserved-words in emacs (or let David do it):
+@c (defun fix-mysql-reserved-words ()
+@c (interactive)
+@c (let ((cnt 0))
+@c (insert "\n@item ")
+@c (while (looking-at "[ \t]*{ +\"\\([^\"]+\\)\"[ \t]*,.*\n")
+@c (replace-match "@code{\\1}")
+@c (incf cnt)
+@c (if (> cnt 3)
+@c (progn
+@c (setf cnt 0)
+@c (insert "\n@item "))
+@c (insert " @tab ")))))
+@c But remove the non alphanumeric Einträge von Hand first.
+@c Updated after 3.23.4 990928 von David
+
+@multitable @columnfractions .25 .25 .25 .25
+@item @code{action} @tab @code{add} @tab @code{aggregate} @tab @code{all}
+@item @code{alter} @tab @code{after} @tab @code{and} @tab @code{as}
+@item @code{asc} @tab @code{avg} @tab @code{avg_row_length} @tab @code{auto_increment}
+@item @code{between} @tab @code{bigint} @tab @code{bit} @tab @code{binary}
+@item @code{blob} @tab @code{bool} @tab @code{both} @tab @code{by}
+@item @code{cascade} @tab @code{case} @tab @code{char} @tab @code{character}
+@item @code{change} @tab @code{check} @tab @code{checksum} @tab @code{column}
+@item @code{columns} @tab @code{comment} @tab @code{constraint} @tab @code{create}
+@item @code{cross} @tab @code{current_date} @tab @code{current_time} @tab @code{current_timestamp}
+@item @code{data} @tab @code{database} @tab @code{databases} @tab @code{date}
+@item @code{datetime} @tab @code{day} @tab @code{day_hour} @tab @code{day_minute}
+@item @code{day_second} @tab @code{dayofmonth} @tab @code{dayofweek} @tab @code{dayofyear}
+@item @code{dec} @tab @code{decimal} @tab @code{default} @tab @code{delayed}
+@item @code{delay_key_write} @tab @code{delete} @tab @code{desc} @tab @code{describe}
+@item @code{distinct} @tab @code{distinctrow} @tab @code{double} @tab @code{drop}
+@item @code{end} @tab @code{else} @tab @code{escape} @tab @code{escaped}
+@item @code{enclosed} @tab @code{enum} @tab @code{explain} @tab @code{exists}
+@item @code{fields} @tab @code{file} @tab @code{first} @tab @code{float}
+@item @code{float4} @tab @code{float8} @tab @code{flush} @tab @code{foreign}
+@item @code{from} @tab @code{for} @tab @code{full} @tab @code{Funktion}
+@item @code{global} @tab @code{grant} @tab @code{grants} @tab @code{group}
+@item @code{having} @tab @code{heap} @tab @code{high_priority} @tab @code{hour}
+@item @code{hour_minute} @tab @code{hour_second} @tab @code{hosts} @tab @code{identified}
+@item @code{ignore} @tab @code{in} @tab @code{index} @tab @code{infile}
+@item @code{inner} @tab @code{insert} @tab @code{insert_id} @tab @code{int}
+@item @code{integer} @tab @code{interval} @tab @code{int1} @tab @code{int2}
+@item @code{int3} @tab @code{int4} @tab @code{int8} @tab @code{into}
+@item @code{if} @tab @code{is} @tab @code{isam} @tab @code{join}
+@item @code{key} @tab @code{keys} @tab @code{kill} @tab @code{last_insert_id}
+@item @code{leading} @tab @code{left} @tab @code{length} @tab @code{like}
+@item @code{lines} @tab @code{limit} @tab @code{load} @tab @code{local}
+@item @code{lock} @tab @code{logs} @tab @code{long} @tab @code{longblob}
+@item @code{longtext} @tab @code{low_priority} @tab @code{max} @tab @code{max_rows}
+@item @code{match} @tab @code{mediumblob} @tab @code{mediumtext} @tab @code{mediumint}
+@item @code{middleint} @tab @code{min_rows} @tab @code{minute} @tab @code{minute_second}
+@item @code{modify} @tab @code{month} @tab @code{monthname} @tab @code{myisam}
+@item @code{natural} @tab @code{numeric} @tab @code{no} @tab @code{not}
+@item @code{null} @tab @code{on} @tab @code{optimize} @tab @code{option}
+@item @code{optionally} @tab @code{or} @tab @code{order} @tab @code{outer}
+@item @code{outfile} @tab @code{pack_keys} @tab @code{partial} @tab @code{password}
+@item @code{precision} @tab @code{primary} @tab @code{procedure} @tab @code{process}
+@item @code{processlist} @tab @code{privileges} @tab @code{read} @tab @code{real}
+@item @code{references} @tab @code{reload} @tab @code{regexp} @tab @code{rename}
+@item @code{replace} @tab @code{restrict} @tab @code{returns} @tab @code{revoke}
+@item @code{rlike} @tab @code{row} @tab @code{rows} @tab @code{second}
+@item @code{select} @tab @code{set} @tab @code{show} @tab @code{shutdown}
+@item @code{smallint} @tab @code{soname} @tab @code{sql_big_tables} @tab @code{sql_big_selects}
+@item @code{sql_low_priority_updates} @tab @code{sql_log_off} @tab @code{sql_log_update} @tab @code{sql_select_limit}
+@item @code{sql_small_result} @tab @code{sql_big_result} @tab @code{sql_warnings} @tab @code{straight_join}
+@item @code{starting} @tab @code{status} @tab @code{string} @tab @code{table}
+@item @code{tables} @tab @code{temporary} @tab @code{terminated} @tab @code{text}
+@item @code{then} @tab @code{time} @tab @code{timestamp} @tab @code{tinyblob}
+@item @code{tinytext} @tab @code{tinyint} @tab @code{trailing} @tab @code{to}
+@item @code{type} @tab @code{use} @tab @code{using} @tab @code{unique}
+@item @code{unlock} @tab @code{unsigned} @tab @code{update} @tab @code{usage}
+@item @code{values} @tab @code{varchar} @tab @code{variables} @tab @code{varying}
+@item @code{varbinary} @tab @code{mit} @tab @code{write} @tab @code{when}
+@item @code{where} @tab @code{year} @tab @code{year_month} @tab @code{zerofill}
+@end multitable
+
+Folgende Symbole (aus der obigen Tabelle) sind von ANSI-SQL verboten, aber
+von MySQL als Spalten- und Tabellennamen zugelassen. Der Grund ist, dass
+einige davon sehr natürliche Namen sind und viele Leute diese bereits in
+Benutzung haben.
+
+@itemize @bullet
+@item @code{ACTION}
+@item @code{BIT}
+@item @code{DATE}
+@item @code{ENUM}
+@item @code{NO}
+@item @code{TEXT}
+@item @code{TIME}
+@item @code{TIMESTAMP}
+@end itemize
+
+
+@node Column types, Functions, Language Structure, Reference
+@c German node Spaltentypen
+@section Spaltentypen
+
+@cindex Spalten, Typen
+@cindex Typen, Spalten
+
+MySQL unterstützt eine Reihe von Spaltentypen, die in drei Kategorien
+eingeteilt werden können: numerische Typen, Datums- und Zeit-Typen und
+Zeichenketten-Typen. Dieser Abschnitt gibt zuerst einen Überblick über die
+verfügbaren Typen und fasst den Speicherbedarf jedes Spaltentyps zusammen.
+Danach folgt eine detaillierter Beschreibung der Eigenschaften der Typen
+jeder Kategorie. Die detailliertere Beschreibung sollte wegen zusätzlicher
+Informationen über bestimmte Spaltentypen herangezogen werden, wie zu den
+erlaubten Formaten, in denen Sie Werte festlegen können.
+
+Die von MySQL unterstützten Spaltentypen sind unten aufgeführt. Folgende
+Code-Buchstaben werden in der Beschreibung benutzt:
+
+@cindex Anzeigebreite
+@cindex Größe, Anzeigebreite
+@cindex Ziffern
+@cindex Dezimalpunkt
+@cindex Klammern, eckige
+@cindex eckige Klammern
+@table @code
+@item M
+Gibt die maximale Anzeigebreite an. Die größte erlaubte Anzeigebreite ist
+255.
+
+@item D
+Trifft auf Fließkomma-Typen zu und bezeichnet die Anzahl von Ziffern nach
+dem Dezimalpunkt. Der größte mögliche Wert ist 30, aber er sollte nicht
+größer sein als @code{M}-2.
+@end table
+
+Eckige Klammern (@samp{[} und @samp{]}) geben Teile der Typ-Festlegung an,
+die optional sind.
+
+@tindex Typen
+
+@c The @w{-Anzahl} stuff keeps a linebreak von occurring between
+@c the - und Anzahl.
+
+Wenn Sie @code{ZEROFILL} für eine Spalte angeben, beachten Sie, dass MySQL
+der Spalte automatisch ein @code{UNSIGNED}-Attribut hinzufügt.
+
+@table @code
+@tindex TINYINT
+@item TINYINT[(M)] [UNSIGNED] [ZEROFILL]
+
+Eine sehr kleine Ganzzahl. Der vorzeichenbehaftete Bereich ist @code{-128}
+bis @code{127}. Der vorzeichenlose Bereich ist @code{0} to @code{255}.
+
+@tindex SMALLINT
+@item SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
+
+Eine kleine Ganzzahl. Der vorzeichenbehaftete Bereich ist @code{-32768} bis
+@code{32767}. Der vorzeichenlose Bereich ist @code{0} bis @code{65535}.
+
+@tindex MEDIUMINT
+@item MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
+
+A Ganzzahl mittlerer Größe. Der vorzeichenbehaftete Bereich ist
+@code{-8388608} bis @code{8388607}. Der vorzeichenlose Bereich ist @code{0}
+bis @code{16777215}.
+
+@tindex INT
+@item INT[(M)] [UNSIGNED] [ZEROFILL]
+
+Eine Ganzzahl normaler Größe. Der vorzeichenbehaftete Bereich ist
+@code{-2147483648} bis @code{2147483647}. Der vorzeichenlose Bereich ist
+@code{0} bis @code{4294967295}.
+
+@tindex INTEGER
+@item INTEGER[(M)] [UNSIGNED] [ZEROFILL]
+
+Ein Synonym für @code{INT}.
+
+@tindex BIGINT
+@item BIGINT[(M)] [UNSIGNED] [ZEROFILL]
+
+Eine große Ganzzahl. Der vorzeichenbehaftete Bereich ist
+@code{-9223372036854775808} bis @code{9223372036854775807}. Der
+vorzeichenlose Bereich ist @code{0} bis @code{18446744073709551615}.
+
+Einiger Dinge sollten Sie sich bei @code{BIGINT}-Spalten bewusst sein:
+
+@itemize @bullet
+@item
+@cindex Rundungsfehler
+Weil alle arithmetischen Berechnungen mit vorzeichenbehafteten
+@code{BIGINT}- oder @code{DOUBLE}-Werten durchgeführt werden, sollten Sie
+keine vorzeichenlosen Ganzzahlen größer als @code{9223372036854775807} (63
+Bits) benutzen, ausser bei Bit-Funktionen! Wenn Sie das doch tun, können
+einige der letzten Ziffern im Ergebnis falsch sein, weil Rundungsfehler
+beim Umwandeln von @code{BIGINT} in @code{DOUBLE} auftreten.
+
+MySQL 4.0 kann @code{BIGINT} in folgenden Fällen handhaben:
+@itemize @bullet
+@item
+Benutzen Sie Ganzzahlen, um große vorzeichenlose Wert in einer
+@code{BIGINT}-Spalte zu speichern.
+@item
+Bei @code{MIN(große_ganzzahl_spalte)} und
+@code{MAX(große_ganzzahl_spalte)}.
+@item
+Bei der Benutzung der Operatoren (@code{+}, @code{-}, @code{*} usw.), wenn
+beide Operanden Ganzzahlen sind.
+@end itemize
+
+@item
+Sie können immer einen genauen Ganzzahlwert in einer @code{BIGINT}-Spalte
+speichern, wenn Sie sie als Zeichenkette speichern, denn in diesem Fall
+wird diese nicht zwischendurch als Double dargestellt.
+@item
+@samp{-}, @samp{+} und @samp{*} benutzen arithmetische
+@code{BIGINT}-Berechnungen, wenn beide Argumente @code{INTEGER}-Werte sind!
+Das heißt, wenn Sie zwei Ganzzahlen multiplizieren (oder Ergebnisse von
+Funktionen, die Ganzzahlen zurückgeben), erhalten Sie vielleicht
+unerwartete Ergebnisse, wenn das Ergebnis größer als
+@code{9223372036854775807} ist.
+@end itemize
+
+@cindex Fließkommazahl
+@tindex FLOAT
+@tindex FLOAT(genauigkeit)
+@item FLOAT(genauigkeit) [ZEROFILL]
+
+Eine Fließkommazahl. Kann nicht vorzeichenlos sein. @code{genauigkeit} ist
+@code{<=24} bei einer Fließkommazahl einfacher Genauigkeit und zwischen 25
+und 53 bei einer Fließkommazahl doppelter Genauigkeit. Diese Typen sind
+wie die unten beschriebenen @code{FLOAT} und @code{DOUBLE}-Typen.
+@code{FLOAT(X)} hat denselben Wertebereich wie die entsprechenden
+@code{FLOAT}- und @code{DOUBLE}-Typen, jedoch ist die Anzeigebreite und die
+Anzahl der Dezimalstellen undefiniert.
+
+In MySQL-Version 3.23 ist das ein echter Fließkommawert. In früheren
+MySQL-Versionen hat @code{FLOAT(genauigkeit)} immer 2 Dezimalstellen.
+
+Beachten Sie, dass bei der Benutzung von @code{FLOAT} unerwartete Probleme
+auftreten können, weil alle Berechnungen in MySQL mit doppelter Genauigkeit
+durchgeführt werden. @xref{No matching rows}.
+
+@cindex ODBC-Kompatibilität
+@cindex Kompatibilität, mit ODBC
+Diese Syntax steht wegen der ODBC-Kompatibilität zur Verfügung.
+
+@tindex FLOAT
+@tindex FLOAT(M,D)
+@item FLOAT[(M,D)] [ZEROFILL]
+
+Eine kleine Fließkommazahl (einfacher Genauigkeit). Kann nicht
+vorzeichenlos sein. Der Wertebereich umfasst @code{@w{-3.402823466E+38}}
+bis @code{@w{-1.175494351E-38}}, @code{0} und @code{@w{1.175494351E-38}}
+bis @code{3.402823466E+38}. M ist die Anzeigebreite und D ist die Anzahl
+von Dezimalstellen. @code{FLOAT} ohne Argument oder mit einem Argument <=
+24 steht für eine Fließkommazahl einfacher Genauigkeit.
+
+@tindex DOUBLE
+@tindex FLOAT(genauigkeit)
+@item DOUBLE[(M,D)] [ZEROFILL]
+
+Eine normal große Fließkommazahl (doppelter Genauigkeit). Kann nicht
+vorzeichenlos sein. Der Wertebereich umfasst
+@code{@w{-1.7976931348623157E+308}} bis
+@code{@w{-2.2250738585072014E-308}}, @code{0} und
+@code{2.2250738585072014E-308} bis @code{1.7976931348623157E+308}. M ist
+die Anzeigebreite und D ist die Anzahl von Dezimalstellen. @code{DOUBLE}
+ohne Argument oder @code{FLOAT(X)} mit 25 <= X <= 53 steht für eine
+Fließkommazahl doppelter Genauigkeit.
+
+@tindex DOUBLE PRECISION
+@tindex REAL
+@item DOUBLE PRECISION[(M,D)] [ZEROFILL]
+@itemx REAL[(M,D)] [ZEROFILL]
+
+Synonyme für @code{DOUBLE}.
+
+@tindex DECIMAL
+@item DECIMAL[(M[,D])] [ZEROFILL]
+
+Eine unkomprimierte Fließkommazahl. Kann nicht vorzeichenlos sein. Verhält
+sich wie eine @code{CHAR}-Spalte: ``Unkomprimiert'' bedeutet, dass die Zahl
+als Zeichenkette gespeichert wird, wobei ein Zeichen für jede Ziffer des
+Wertes steht. Der Dezimalpunkt und, bei negativen Zahlen, das
+@samp{-}-Zeichen, werden in M nicht mitgezählt (aber hierfür wird Platz
+reserviert). Wenn @code{D} 0 ist, haben Werte keinen Dezimalpunkt oder
+Bruchteil. Der maximale Wertebereich von @code{DECIMAL}-Werte ist derselbe
+wie für @code{DOUBLE}, aber der tatsächliche Wertebereich einer gegebenen
+@code{DECIMAL}-Spalte kann durch die Auswahl von @code{M} und @code{D}
+eingeschränkt sein.
+
+Wenn @code{D} weggelassen wird, wird es auf 0 gesetzt. Wenn @code{M}
+ausgelassen wird, wird es auf 10 gesetzt.
+
+Beachten Sie, dass in MySQL-Version 3.22 das @code{M}-Argument den Platz
+für das Vorzeichen und den Dezimalpunkt beinhaltete!
+
+@tindex NUMERIC
+@item NUMERIC(M,D) [ZEROFILL]
+
+Synonym für @code{DECIMAL}.
+
+@tindex DATE
+@item DATE
+
+Ein Datum. Der unterstützte Wertebereich ist @code{'1000-01-01'} bis
+@code{'9999-12-31'}. MySQL zeigt @code{DATE}-Werte im
+@code{'YYYY-MM-DD'}-Format an, gestattet jedoch, @code{DATE}-Spalten Werte
+entweder als Zeichenketten oder als Zahlen zuzuweisen. @xref{DATETIME}.
+
+@tindex DATETIME
+@item DATETIME
+
+Eine Datums-/Zeit-Kombination. Der unterstützte Wertebereich ist
+@code{'1000-01-01 00:00:00'} bis @code{'9999-12-31 23:59:59'}. MySQL zeigt
+@code{DATETIME}-Werte im @code{'YYYY-MM-DD HH:MM:SS'}-Format an, gestattet
+jedoch, @code{DATETIME}-Spalten Werte entweder als Zeichenketten oder als
+Zahlen zuzuweisen.
+@xref{DATETIME}.
+
+@tindex TIMESTAMP
+@item TIMESTAMP[(M)]
+
+Ein Zeitstempel. Der Wertebereich ist @code{'1970-01-01 00:00:00'} bis
+irgendwann im Jahr @code{2037}. MySQL zeigt @code{TIMESTAMP}-Werte im
+@code{YYYYMMDDHHMMSS}-, @code{YYMMDDHHMMSS}-, @code{YYYYMMDD}- oder
+@code{YYMMDD}-Format an, abhängig davon, ob @code{M} @code{14} (oder
+fehlend), @code{12}, @code{8} oder @code{6} ist, gestattet aber, dass Sie
+@code{TIMESTAMP}-Spalten Werte entweder als Zeichenketten oder als Zahlen
+zuweisen. Eine @code{TIMESTAMP}-Spalte ist nützlich, um Datum und Zeit
+einer @code{INSERT}- oder @code{UPDATE}-Operation zu speichern, weil sie
+automatisch auf das Datum und die Zeit der jüngsten Operation gesetzt wird,
+wenn Sie nicht selbst einen Wert zuweisen. Sie können sie auch auf das
+aktuelle Datum und die aktuelle Zeit setzen, indem Sie einen
+@code{NULL}-Wert zuweisen. @xref{Date and time types}.
+
+Ein @code{TIMESTAMP} wird immer mit 4 Bytes gespeichert. Das
+@code{M}-Argument betrifft nur die Anzeige der @code{TIMESTAMP}-Spalte.
+
+Beachten Sie, dass @code{TIMESTAMP(X)}-Spalten, bei denen X 8 oder 14 ist,
+als Zahlen interpretiert werden, während andere @code{TIMESTAMP(X)}-Spalten
+als Zeichenketten interpretiert werden. Das soll lediglich sicherstellen,
+dass Sie Tabellen mit diesen Typen verlässlich dumpen und wiederherstellen
+können! @xref{DATETIME}.
+
+@tindex TIME
+@item TIME
+
+Ein Zeit-Typ. Der Wertebereich ist @code{'-838:59:59'} bis
+@code{'838:59:59'}. MySQL zeigt @code{TIME}-Werte im
+@code{'HH:MM:SS'}-Format an, gestattet aber, @code{TIME}-Spalten Werte
+entweder als Zeichenketten oder als Zahlen zuweisen. @xref{TIME}.
+
+@tindex YEAR
+@item YEAR[(2|4)]
+
+Ein Jahr in 2- oder 4-Ziffernformat (Vorgabe ist 4-Ziffern). Die zulässigen
+Werte reichen von @code{1901} bis @code{2155} sowie @code{0000} im
+4-Ziffern-Jahresformat, und von 1970 bis 2069 beim 2-Ziffernformat (70 bis
+69). MySQL zeigt @code{YEAR}-Werte im @code{YYYY}-Format an, gestattet
+aber, @code{YEAR}-Spalten Werte entweder als Zeichenketten oder als Zahlen
+zuweisen. (Der @code{YEAR}-Typ ist neu seit MySQL-Version 3.22.).
+@xref{YEAR}.
+
+@tindex NATIONAL CHAR
+@tindex NCHAR
+@tindex CHAR
+@tindex CHARACTER
+@item [NATIONAL] CHAR(M) [BINARY]
+
+Eine Zeichenkette fester Länge, die beim Speichern rechts stets mit
+Leerzeichen bis zur angegebenen Länge aufgefüllt wird. Der Wertebereich von
+@code{M} ist 1 bis 255 Zeichen. Leerzeichen am Ende werden beim Abruf des
+Wertes entfernt. @code{CHAR}-Werte werden nach dem vorgabemäßigen
+Zeichensatz ohne Berücksichtigung der Groß-/Kleinschreibung sortiert und
+verglichen, es sei denn, dass Schlüsselwort @code{BINARY} wird angegeben.
+
+@code{NATIONAL CHAR} (Kurzform @code{NCHAR}) ist die Art, wie ANSI-SQL bei
+einer CHAR-Spalte festlegt, dass der vorgabemäßige Zeichensatz verwendet
+werden soll. Das ist der Vorgabewert in MySQL.
+
+@code{CHAR} ist eine Abkürzung für @code{CHARACTER}.
+
+MySQL erlaubt das Anlegen einer Spalte des Typs @code{CHAR(0)}. Das ist
+hauptsächlich nützlich, wenn Sie mit alten Applikationen kompatibel sein
+müssen, die auf die Existenz einer Spalte vertrauen, den Wert aber nicht
+tatsächlich benutzen. Es ist ebenfalls nett, um eine Spalte anzulegen, die
+nur 2 Werte annehmen kann: Eine @code{CHAR(0)}, die nicht als @code{NOT
+NULL} definiert ist, belegt nur 1 Bit und kann 2 Werte annehmen:
+@code{NULL} oder @code{""}. @xref{CHAR}.
+
+@tindex CHARACTER VARYING
+@tindex CHAR VARYING
+@tindex VARCHAR
+@item [NATIONAL] VARCHAR(M) [BINARY]
+
+Eine Zeichenkette variabler Länge. @strong{HINWEIS:} Leerzeichen am Ende
+werden bei der Speicherung des Wertes entfernt (das unterscheidet den Typ
+von der ANSI-SQL-Spezifikation). Der Wertebereich von @code{M} ist 1 bis
+255 Zeichen. @code{VARCHAR}-Werte werden nach dem vorgabemäßigen
+Zeichensatz ohne Berücksichtigung der Groß-/Kleinschreibung sortiert und
+verglichen, es sei denn, dass Schlüsselwort @code{BINARY} wird angegeben.
+@xref{Silent column changes}.
+
+@code{VARCHAR} ist eine Abkürzung für @code{CHARACTER VARYING}.
+@xref{CHAR}.
+
+@tindex TINYBLOB
+@tindex TINYTEXT
+@item TINYBLOB
+@itemx TINYTEXT
+
+Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von 255
+(2^8 - 1) Zeichen. @xref{Silent column changes}. @xref{BLOB}.
+
+@tindex BLOB
+@tindex TEXT
+@item BLOB
+@itemx TEXT
+
+Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von
+65535 (2^16 - 1) Zeichen. @xref{Silent column changes}. @xref{BLOB}.
+
+@tindex MEDIUMBLOB
+@tindex MEDIUMTEXT
+@item MEDIUMBLOB
+@itemx MEDIUMTEXT
+
+Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von
+16777215 (2^24 - 1) Zeichen. @xref{Silent column changes}.
+@xref{BLOB}.
+
+@tindex LONGBLOB
+@tindex LONGTEXT
+@item LONGBLOB
+@itemx LONGTEXT
+
+Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von
+4294967295 (2^32 - 1) Zeichen. @xref{Silent column changes}.
+Beachten Sie, dass Sie nicht den gesamten Wertebereich dieses Typs benutzen
+können, weil das Client-Server-Protokoll und MyISAM-Tabellen momentan eine
+Beschränkungen auf 16 MB pro Kommunikationspaket / Tabellenzeile haben.
+@xref{BLOB}.
+
+@tindex ENUM
+@item ENUM('wert1','wert2',...)
+
+An Aufzählung. Ein Zeichenkettenobjekt, das nur einen Wert haben kann, der
+aus den Auflistungswerten @code{'wert1'}, @code{'wert2'}, @code{...},
+@code{NULL} oder dem speziellen @code{""}-Fehlerwert ausgewählt wird. Eine
+@code{ENUM} kann maximal 65535 unterschiedliche Werte haben. @xref{ENUM}.
+
+@tindex SET
+@item SET('wert1','wert2',...)
+
+Eine Reihe. Ein Zeichenkettenobjekt, das 0 oder mehr Werte haben kann, von
+denen jeder aus den Auflistungswerten @code{'wert1'}, @code{'wert2'},
+@code{...} ausgewählt werden muss. Eine @code{SET} kann maximal 64 Elemente
+haben. @xref{SET}.
+@end table
+
+
+
+@menu
+* Numeric types::
+* Date and time types::
+* String types::
+* Choosing types::
+* Other-vendor column types::
+* Storage requirements::
+@end menu
+
+@node Numeric types, Date and time types, Column types, Column types
+@c German node Numerische Typen
+@subsection Numerische Typen
+
+MySQL unterstützt alle numerischen Typen von ANSI/ISO-SQL92. Diese Typen
+beinhalten die exakten numerischen Datentypen (@code{NUMERIC},
+@code{DECIMAL}, @code{INTEGER} und @code{SMALLINT}) sowie die
+näherungsweisen numerischen Datentypen (@code{FLOAT}, @code{REAL} und
+@code{DOUBLE PRECISION}). Das Schlüsselwort @code{INT} ist ein Synonym für
+@code{INTEGER} und das Schlüsselwort @code{DEC} ist ein Synonym für
+@code{DECIMAL}.
+
+Die @code{NUMERIC}- und @code{DECIMAL}-Typen sind in MySQL als derselbe Typ
+implementiert, wie es vom SQL92-Standard zugelassen ist. Sie werden für
+Werte benutzt, bei denen es wichtig ist, die exakte Genauigkeit zu
+bewahren, zum Beispiel bei monetären Daten. Wenn Sie eine Spalte mit einem
+dieser Typen deklarieren, können Genauigkeit und Bereich festgelegt werden
+(und werden das üblicherweise auch). Beispiel:
+
+@example
+ gehalt DECIMAL(9,2)
+@end example
+
+In diesem Beispiel repräsentiert @code{9} (@code{genauigkeit}) die Anzahl
+signifikanter Dezimalziffern, die für Werte gespeichert werden, und
+@code{2} (@code{bereich}) repräsentiert die Anzahl von Ziffern, die nach
+dem Dezimalpunkt gespeichert werden. In diesem Fall liegt der Wertebereich,
+der in der @code{gehalt}-Spalte gespeichert werden kann, deswegen zwischen
+@code{-9999999.99} und @code{9999999.99}.
+(MySQL kann tatsächlich Zahlen bis zu @code{9999999.99} in dieser Spalte
+speichern, weil er nicht das Vorzeichen für positive Zahlen speichern
+muss).
+
+In ANSI/ISO-SQL92 ist die Syntax @code{DECIMAL(p)} äquivalent zu
+@code{DECIMAL(p,0)}. Gleichermaßen ist die Syntax @code{DECIMAL}
+äquivalent zu @code{DECIMAL(p,0)}, wobei es der Implementation überlassen
+bleibt, den Wert von @code{p} festzulegen. MySQL unterstützt momentan keine
+dieser abweichenden Formen der @code{DECIMAL}- / @code{NUMERIC}-Datentypen.
+Das ist im Allgemeinen kein ernstes Problem, weil der hauptsächliche Nutzen
+dieser Typen darin liegt, sowohl Genauigkeit als auch Bereich explizit
+steuern zu können.
+
+@code{DECIMAL}- und @code{NUMERIC}-Werte sind als Zeichenketten gespeichert
+statt als Fließkommazahlen, um die dezimale Genauigkeit dieser Werte zu
+bewahren. Ein Zeichen wird benutzt für jede Ziffer des Werts, den
+Dezimalpunkt (wenn @code{bereich} > 0) und das @samp{-}-Zeichen (für
+negative Zahlen). Wenn @code{bereich} 0 ist, enthalten @code{DECIMAL}- und
+@code{NUMERIC}-Werte weder Dezimalpunkt noch Bruchteil.
+
+Der maximale Wertebereich von @code{DECIMAL}- und @code{NUMERIC}-Werten ist
+derselbe wie für @code{DOUBLE}, aber der tatsächliche Wertebereich einer
+gegebenen @code{DECIMAL}- oder @code{NUMERIC}-Spalte kann durch
+@code{genauigkeit} oder @code{bereich} für eine gegebene Spalte beschränkt
+werden. Wenn einer solchen Spalte ein Wert mit mehr Ziffern nach dem
+Dezimalpunkt zugewiesen wird, als durch @code{bereich} zugelassen, wird der
+Wert auf diesen @code{bereich} gerundet. Wenn einer @code{DECIMAL}- oder
+@code{NUMERIC}-Spalte ein Wert zugewiesen wird, dessen Größe den
+Wertebereich überschreitet, der von der festgelegten (oder vorgabemäßigen)
+@code{genauigkeit} und @code{bereich} festgelegt wird, speichert MySQL den
+Wert des entsprechenden Endpunkts des Wertebereichs.
+
+Als Erweiterung zum ANSI/ISO-SQL92-Standard unterstützt MySQL auch die
+Ganzzahltypen @code{TINYINT}, @code{MEDIUMINT} und @code{BIGINT}, wie oben
+aufgelistet. Ein andere Erweiterung wird von MySQL unterstützt, um optional
+die Anzeigebreite eines Ganzzahlwerts in Klammern festzulegen, die auf das
+Basis-Schlüsselwort des Typs folgen (zum Beispiel @code{INT(4)}). Die
+optionale Breitenspezifizierung wird benutzt, um die Anzeige von Werten,
+deren Breite geringer ist als für die Spalte festgelegt, linksseitig mit
+Leerzeichen aufzufüllen. Das begrenzt allerdings nicht den Wertebereich,
+der in der Spalte gespeichert werden kann, noch die Anzahl von Ziffern, die
+bei Werten angezeigt werden, die die angegebene Breite für die Spalte
+überschreiten. In Verbindung mit dem optionalen Erweiterungsattribut
+@code{ZEROFILL} wird - statt vorgabemäßig mit Leerzeichen - mit Nullen
+aufgefüllt. Bei einer Spalte zum Beispiel, die als @code{INT(5) ZEROFILL}
+deklariert wurde, wird @code{4} als @code{00004} dargestellt. Beachten Sie,
+dass Werte in einer Ganzzahlspalte, die größer sind als die Anzeigebreite,
+Probleme bei der Erzeugung temporärer Tabellen für einige komplizierte
+Joins durch MySQL auftreten können, weil MySQL in diesen Fällen darauf
+vertraut, dass die Daten in die Original-Spaltenbreite passten.
+
+Alle Ganzzahl-Typen können ein optionales (Nicht-Standard-) Attribut
+@code{UNSIGNED} haben. Vorzeichenlose Werte können dafür benutzt werden,
+nur positive Zahlen in einer Spalte zuzulassen, wenn Sie eine Wertebereich
+brauchen, der etwas größer ausfällt.
+
+Der @code{FLOAT}-Typ wird benutzt, um näherungsweise numerische Datentypen
+zu repräsentieren. Der ANSI/ISO-SQL92-Standard erlaubt eine optionale
+Festlegung der Genauigkeit (aber nicht den Wertebereich des Exponenten) in
+Bits, gefolgt vom Schlüsselwort @code{FLOAT} in Klammern. Die
+MySQL-Implementation unterstützt ebenfalls diese optionale
+Genauigkeitsfestlegung. Wenn das Schlüsselwort @code{FLOAT} für einen
+Spaltentyp ohne Genauigkeitsfestlegung benutzt wird, benutzt MySQL 4 Bytes,
+um die Werte zu speichern. Eine abweichende Syntax wird ebenfalls
+unterstützt, wobei zwei Zahlen in Klammern dem @code{FLOAT}-Schlüsselwort
+folgen. Mit dieser Option legt die erste Zahl wie gehabt den Speicherbedarf
+für den Wert in Bytes fest, und die zweite Zahl legt die Anzahl von Ziffern
+fest, die nach dem Dezimalpunkt gespeichert und angezeigt werden sollen
+(wie bei @code{DECIMAL} und @code{NUMERIC}). Wenn MySQL in einer solchen
+Spalte einen Wert mit mehr Dezimalziffern nach dem Dezimalpunkt speichern
+soll als für die Spalte festgelegt, wird der Wert beim Speichern gerundet,
+um die zusätzlichen Ziffern zu entfernen.
+
+Die @code{REAL}- und @code{DOUBLE PRECISION}-Typen akzeptieren keine
+Genauigkeitsfestlegungen. Als Erweiterung zum ANSI/ISO-SQL92-Standard
+erkennt MySQL @code{DOUBLE} als ein Synonym für den @code{DOUBLE
+PRECISION}-Typ. Im Gegensatz zur Anforderung des Standard, dass die
+Genauigkeit für @code{REAL} kleiner sein muss als die für @code{DOUBLE
+PRECISION}, implementiert MySQL beide als 8-Byte-Fließkommawerte doppelter
+Genauigkeit (wenn er nicht im ``ANSI-Modus'' läuft). Für maximale
+Portabilität sollte Code, der die Speicherung näherungsweiser numerischer
+Daten erfordert, @code{FLOAT} oder @code{DOUBLE PRECISION} ohne Festlegung
+der Genauigkeit oder Anzahl von Dezimalstellen benutzen.
+
+Wenn ein Wert in einer numerischen Spalte gespeichert werden soll, der
+ausserhalb des erlaubten Wertebereichs des Spaltentyps ist, schneidet MySQL
+den Wert auf den entsprechenden Endpunkt des Wertebereichs ab und speichert
+statt dessen diesen Wert.
+
+Der Wertebereich einer @code{INT}-Spalte ist zum Beispiel
+@code{-2147483648} bis @code{2147483647}. Wenn Sie versuchen,
+@code{-9999999999} in eine @code{INT}-Spalte einzufügen, wird der Wert auf
+den unteren Endpunkt des Bereichs abgeschnitten, und es wird
+@code{-2147483648} gespeichert. Gleichermaßen wird beim Einfügen in eine
+solche Spalte nicht @code{9999999999}, sondern @code{2147483647}
+gespeichert.
+
+Wenn die @code{INT}-Spalte @code{UNSIGNED} ist, ist die Größe des
+Wertebereichs dieselbe, aber ihre Endpunkte verschieben sich zu @code{0}
+und @code{4294967295}. Wenn Sie versuchen, @code{-9999999999} bzw.
+@code{9999999999} zu speichern, werden die in der Spalte gespeicherten
+Werte statt dessen zu @code{0} bzw. @code{4294967296}.
+
+Umwandlungen, die aufgrund von Abschneiden geschehen, werden als
+``Warnungen'' bei @code{ALTER TABLE}, @code{LOAD DATA INFILE},
+@code{UPDATE} und in mehrzeiligen @code{INSERT}-Statements berichtet.
+
+
+@node Date and time types, String types, Numeric types, Column types
+@c German node Datums- und Zeit-Typen
+@subsection Datums- und Zeit-Typen
+
+@cindex Typen, Datum und Zeit
+@cindex Datums- und Zeit-Typen
+
+
+
+Die Datums- und Zeit-Typen sind @code{DATETIME}, @code{DATE},
+@code{TIMESTAMP}, @code{TIME} und @code{YEAR}. Jeder dieser Typen hat einen
+zulässigen Wertebereich sowie einen ``0''-Wert, der benutzt wird, wenn Sie
+einen wirklich unzulässigen Wert speichern. Beachten Sie, dass MySQL es
+zuläßt, dass Sie bestimmte 'nicht ganz' zulässige Datumswerte speichern,
+zum Beispiel @code{1999-11-31}. Der Grund hierfür ist, dass wir meinen,
+dass es in der Verantwortung der Applikation liegt, Datumsüberprüfungen
+vorzunehmen, und nicht beim SQL-Server. Um Datumsprüfungen 'schnell' zu
+machen, überprüft MySQL nur, dass der Monat im Bereich 0 bis 12 liegt und
+der Tag im Bereich 0 bis 31. Diese Bereiche sind deshalb so definiert, weil
+es MySQL zuläßt, dass Sie in einer @code{DATE}- oder
+@code{DATETIME}-Spalte Datumsangaben speichern, bei denen der Tag oder
+Monat-Tag 0 sind. Das ist extrem nützlich für Applikationen, die einen
+Geburtstag speichern müssen, dessen exaktes Datum unbekannt ist. In diesem
+Fall können Sie einfach Datumsangaben wie @code{1999-00-00} oder
+@code{1999-01-00} speichern. (Sie können nicht erwarten, von Funktionen wie
+@code{DATE_SUB()} oder @code{DATE_ADD} für solche Datumsangaben korrekte
+Werte zu erhalten.)
+
+Einige allgemeine Überlegungen, die man im Kopf behalten sollte, wenn man
+mit Datums- und Zeit-Typen arbeitet:
+
+@itemize @bullet
+@item
+MySQL ruft Werte für einen gegebenen Datums- oder Zeit-Typ in einem
+Standard-Format ab, versucht aber, eine Vielzahl von Formaten zu
+interpretieren, die Sie bereit stellen (wenn Sie zum Beispiel einen Wert
+angeben, der zugewiesen oder mit einem Datums- oder Zeit-Typ verglichen
+werden soll). Dennoch werden nur die in den folgenden Abschnitten
+beschriebenen Formate unterstützt. Es wird davon ausgegangen, dass Sie
+zulässige Werte bereitstellen; und es können unvorhersehbare Ergebnisse
+zustande kommen, wenn Sie Werte in anderen Formaten angeben.
+
+@item
+Obwohl MySQL versucht, Werte in verschiedenen Formaten zu interpretieren,
+erwartet er immer, dass der Jahresanteil von Datumswerten ganz links steht.
+Datumsangaben müssen in der Reihenfolge Jahr - Monat - Tag gemacht werden
+(zum Beispiel @code{'98-09-04'}) statt in der Reihenfolge Monat - Tag -
+Jahr oder Tag - Monat - Jahr, die anderswo häufig gebraucht werden (zum
+Beispiel @code{'09-04-98'}, @code{'04-09-98'}).
+
+@item
+MySQL wandelt einen Datums- oder Zeitwert automatisch in eine Zahl um, wenn
+der Wert in einem numerischen Zusammenhang benutzt wird, und umgekehrt.
+
+@item
+Wenn MySQL auf einen Datums- oder Zeitwert trifft, der ausserhalb des
+Wertebereichs oder in sonstiger Weise für den Typ nicht zulässig ist (siehe
+Anfang dieses Abschnitts), wird der Wert zum ``0''-Wert dieses Typs
+umgewandelt. (Die Ausnahme ist, dass @code{TIME}-Werte ausserhalb des
+Wertebereichs auf den entsprechenden Endpunkt des @code{TIME}-Wertebereichs
+abgeschnitten werden.) Die unten stehende Tabelle zeigt das Format des
+``0''-Werts für jeden Typ:
+
+@multitable @columnfractions .3 .7
+@item @strong{Spaltentyp} @tab @strong{``0''-Wert}
+@item @code{DATETIME} @tab @code{'0000-00-00 00:00:00'}
+@item @code{DATE} @tab @code{'0000-00-00'}
+@item @code{TIMESTAMP} @tab @code{00000000000000} (Länge abhängig von der Anzeigebreite)
+@item @code{TIME} @tab @code{'00:00:00'}
+@item @code{YEAR} @tab @code{0000}
+@end multitable
+
+@item
+Die ``0''-Werte sind speziell, aber Sie können diese explizit speichern
+oder auf sie verweisen, indem Sie die in der Tabelle dargestellten Werte
+benutzen. Sie können das auch mit den Werten @code{'0'} oder @code{0}
+machen, die leichter zu schreiben sind.
+
+@item
+``0''-Datums- oder -Zeitwerte, die über @strong{MyODBC} benutzt werden,
+werden in @strong{MyODBC}-Version 2.50.12 und höher automatisch in
+@code{NULL} umgewandelt, weil ODBC solche Werte nicht handhaben kann.
+@end itemize
+
+
+@menu
+* Y2K issues::
+* DATETIME::
+* TIME::
+* YEAR::
+@end menu
+
+@node Y2K issues, DATETIME, Date and time types, Date and time types
+@c German node Jahr 2000
+@subsubsection Jahr-2000-Probleme und Datumstypen
+
+@cindex Jahr-2000-Probleme
+@cindex Datumstypen, Jahr-2000-Probleme
+
+MySQL selbst ist Jahr-2000-konform (Jahr-2000-sicher,
+@pxref{Year 2000 compliance}), aber Eingabewerte, die an MySQL
+übergeben werden, sind das möglicherweise nicht. Jede Eingabe von
+Jahreswerten mit 2 Ziffern ist mehrdeutig, weil das Jahrhundert unbekannt
+ist. Solche Werte müssen in 4-stellige Form umgedeutet werden, weil MySQL
+Jahre intern mit 4 Ziffern speichert.
+
+Bei @code{DATETIME}-, @code{DATE}-, @code{TIMESTAMP}- und @code{YEAR}-Typen
+interpretiert MySQL Datumsangaben mit mehrdeutigen Jahreswerten nach
+folgenden Regeln:
+
+@itemize @bullet
+@item
+Jahreswerte im Bereich @code{00 bis 69} werden in @code{2000 bis 2069}
+umgewandelt.
+
+@item
+Jahreswerte im Bereich @code{70 bis 99} werden in @code{1970 bis 1999}
+umgewandelt.
+@end itemize
+
+Denken Sie daran, dass diese Regeln nur eine vernünftige Schätzung dessen
+bedeuten, was die Daten tatsächlich darstellen sollen. Wenn die von MySQL
+benutzten Heuristiken keine korrekten Werte ergeben, müssen Sie eindeutige
+Eingaben in Form 4-stelliger Jahreswerte bereit stellen.
+
+@code{ORDER BY} sortiert 2-stellige @code{YEAR/DATE/DATETIME}-Typen
+korrekt.
+
+Beachten Sie, dass einige Funktionen wie @code{MIN()} und @code{MAX()} ein
+@code{TIMESTAMP / DATE} in eine Zahl umwandeln. Das heißt, dass ein
+Zeitstempel mit einer 2-stelligen Jahresangabe bei diesen Funktionen nicht
+korrekt funktioniert. Das kann in diesem Fall dadurch behoben werden, dass
+der @code{TIMESTAMP / DATE} in ein 4-stelliges Jahresformat umgewandelt
+wird, oder etwas wie @code{MIN(DATE_ADD(zeitstempel,INTERVAL 0 DAYS))}
+benutzt wird.
+
+
+@node DATETIME, TIME, Y2K issues, Date and time types
+@c German node DATETIME
+@subsubsection Die @code{DATETIME}-, @code{DATE}- und @code{TIMESTAMP}-Typen
+
+@tindex DATETIME
+@tindex DATE
+@tindex TIMESTAMP
+
+Die @code{DATETIME}-, @code{DATE}- und @code{TIMESTAMP}-Typen sind
+verwandt. Dieser Abschnitt beschreibt ihre Charakteristiken, wo sie sich
+ähnlich sind und wo sie sich unterscheiden.
+
+Der @code{DATETIME}-Typ wird benutzt, wenn Sie Werte brauchen, die sowohl
+Datums- als auch Zeitinformationen beinhalten. MySQL ruft
+@code{DATETIME}-Werte ab und zeigt sie an im @code{'YYYY-MM-DD
+HH:MM:SS'}-Format. Der unterstützte Wertebereich ist @code{'1000-01-01
+00:00:00'} bis @code{'9999-12-31 23:59:59'}. (``Unterstützt'' heißt, dass
+frühere Werte zwar funktionieren können, dass es aber keine Garantie dafür
+gibt.)
+
+Der @code{DATE}-Typ wird benutzt, wenn Sie nur einen Datumswert brauchen,
+ohne Zeitanteil. MySQL ruft @code{DATE}-Werte ab und zeigt sie an im
+@code{'YYYY-MM-DD'}-Format. Der unterstützte Wertebereich ist
+@code{'1000-01-01'} bis @code{'9999-12-31'}.
+
+Der @code{TIMESTAMP}-Typ ist ein Typ, den Sie dafür benutzen können, um
+@code{INSERT}- oder @code{UPDATE}-Operationen mit dem aktuellen Datum und
+der aktuellen Zeit zu stempeln. Wenn Sie mehrfache @code{TIMESTAMP}-Spalten
+haben, wird nur die erste automatisch aktualisiert.
+
+Die automatische Aktualisierung der @code{TIMESTAMP}-Spalte geschieht unter
+einer der folgenden Bedingungen:
+
+@itemize @bullet
+@item
+Die Spalte wird in einem @code{INSERT}- oder @code{LOAD DATA
+INFILE}-Statement nicht explizit angegeben.
+@item
+Die Spalte wird in einem @code{UPDATE}-Statement nicht explizit angegeben,
+aber ein anderer Spaltenwert ändert sich. (Beachten Sie, dass ein
+@code{UPDATE}, das eine Spalte auf einen Wert setzt, den diese bereits hat,
+nicht dazu führt, dass die @code{TIMESTAMP}-Spalte aktualisiert wird, weil
+MySQL das Aktualisieren in einem solchen Fall auf Effizienzgründen
+ignoriert.)
+@item
+Wenn Sie die @code{TIMESTAMP}-Spalte explizit auf @code{NULL} setzen.
+@end itemize
+
+@code{TIMESTAMP}-Spalten abgesehen von der ersten können ebenfalls auf das
+aktuelle Datum und die aktuelle Zeit gesetzt werden. Setzen Sie die Spalte
+einfach auf @code{NULL} oder auf @code{NOW()}.
+
+Sie können jede @code{TIMESTAMP}-Spalte auf einen Wert setzen, der vom
+aktuellen Datum und der aktuellen Zeit abweicht, indem Sie sie explizit auf
+den gewünschten Wert setzen. Das gilt sogar für die erste
+@code{TIMESTAMP}-Spalte. Sie können diese Eigenschaft benutzen, wenn Sie
+einen @code{TIMESTAMP} auf das aktuelle Datum und die aktuelle Zeit setzen
+wollen, wenn Sie eine Zeile erzeugen, nicht aber, wenn die Zeile später
+aktualisiert wird:
+
+@itemize @bullet
+@item
+Lassen Sie MySQL die Spalte setzen, wenn die Zeile erzeugt wird. Das
+initialisiert sie auf das aktuelle Datum und die aktuelle Zeit.
+
+@item
+Wenn Sie nachfolgende Aktualisierungen anderer Spalten in der Zeile
+durchführen, setzen Sie die @code{TIMESTAMP}-Spalte explizit auf ihren
+aktuellen Wert.
+@end itemize
+
+Auf der anderen Seite finden Sie vielleicht mindestens so einfach, eine
+@code{DATETIME}-Spalte zu benutzen, die Sie auf @code{NOW()}
+initialisieren, wenn die Zeile erzeugt wird, und die Sie bei nachfolgenden
+Aktualisierungen nicht anfassen.
+
+@code{TIMESTAMP}-Werte haben einen Wertebereich von 1970 bis irgendwann im
+Jahr 2037, bei einer Auflösung von einer Sekunde. Werte werden als Zahlen
+angezeigt.
+
+Das Format, in dem MySQL @code{TIMESTAMP}-Werte abruft und anzeigt, hängt
+von der Anzeigebreite ab, wie in der obigen Tabelle dargestellt. Das
+`volle' @code{TIMESTAMP}-Format ist 14 Ziffern, aber
+@code{TIMESTAMP}-Spalten können mit kürzeren Anzeigebreiten angelegt
+werden:
+
+@multitable @columnfractions .3 .7
+@item @strong{Spaltentyp} @tab @strong{Anzeigeformat}
+@item @code{TIMESTAMP(14)} @tab @code{YYYYMMDDHHMMSS}
+@item @code{TIMESTAMP(12)} @tab @code{YYMMDDHHMMSS}
+@item @code{TIMESTAMP(10)} @tab @code{YYMMDDHHMM}
+@item @code{TIMESTAMP(8)} @tab @code{YYYYMMDD}
+@item @code{TIMESTAMP(6)} @tab @code{YYMMDD}
+@item @code{TIMESTAMP(4)} @tab @code{YYMM}
+@item @code{TIMESTAMP(2)} @tab @code{YY}
+@end multitable
+
+Alle @code{TIMESTAMP}-Spalten haben dieselbe Speichergröße, unabhängig von
+der Anzeigebreite. Die gebräuchlichsten Anzeigebreiten sind 6, 8, 12 und
+14. Sie können zur Zeit der Tabellenerzeugung beliebige Anzeigebreiten
+festlegen, aber Werte von 0 oder größer als 14 werden auf 14 gesetzt.
+Ungerade Werte im Bereich von 1 bis 13 werden auf die nächst höhere gerade
+Zahl gesetzt.
+
+Sie können @code{DATETIME}-, @code{DATE}- und @code{TIMESTAMP}-Werte mit
+folgenden Formaten festlegen:
+
+@itemize @bullet
+@item
+Als eine Zeichenkette im @code{'YYYY-MM-DD HH:MM:SS'}- oder @code{'YY-MM-DD
+HH:MM:SS'}-Format. Eine ``entspannte'' Syntax ist zugelassen - jedes
+Satzzeichen kann als Begrenzer zwischen Datumsanteilen oder Zeitanteilen
+verwendet werden. Beispielsweise sind @code{'98-12-31 11:30:45'},
+@code{'98.12.31 11+30+45'}, @code{'98/12/31 11*30*45'} und
+@code{'98@@12@@31 11^30^45'} äquivalent.
+
+@item
+Als eine Zeichenkette im @code{'YYYY-MM-DD'}- oder
+@code{'YY-MM-DD'}-Format. Auch hier ist eine ``entspannte'' Syntax
+zugelassen. Beispielsweise sind @code{'98-12-31'}, @code{'98.12.31'},
+@code{'98/12/31'} und @code{'98@@12@@31'} äquivalent.
+
+@item
+Als eine Zeichenkette ohne Begrenzer im @code{'YYYYMMDDHHMMSS'}- oder
+@code{'YYMMDDHHMMSS'}-Format, vorausgesetzt, die Zeichenkette ergibt als
+Datum einen Sinn. @code{'19970523091528'} und @code{'970523091528'}
+beispielsweise werden als @code{'1997-05-23 09:15:28'} interpretiert, aber
+@code{'971122129015'} ist unzulässig (es hat einen Minutenanteil, der
+keinen Sinn ergibt) und wird in @code{'0000-00-00 00:00:00'} umgewandelt.
+
+@item
+Als eine Zeichenkette ohne Begrenzer im @code{'YYYYMMDD'}- oder
+@code{'YYMMDD'}-Format, vorausgesetzt, die Zeichenkette ergibt als Datum
+einen Sinn. @code{'19970523'} und @code{'970523'} werden als
+@code{'1997-05-23'} interpretiert, aber @code{'971332'} ist unzulässig (es
+hat einen Monatsanteil und einen Tagesanteil, der keinen Sinn ergibt) und
+wird in @code{'0000-00-00'} umgewandelt.
+
+@item
+Als eine Zahl im @code{YYYYMMDDHHMMSS}- oder @code{YYMMDDHHMMSS}-Format,
+vorausgesetzt, die Zahl ergibt als Datum einen Sinn. @code{19830905132800}
+und @code{830905132800} zum Beispiel werden als @code{'1983-09-05
+13:28:00'} interpretiert.
+
+@item
+Als eine Zahl im @code{YYYYMMDD}- oder @code{YYMMDD}-Format, vorausgesetzt,
+die Zahl ergibt als Datum einen Sinn. @code{19830905} und @code{830905} zum
+Beispiel werden als @code{'1983-09-05'} interpretiert.
+
+@item
+Als Ergebnis einer Funktion, die einen Wert zurückgibt, der in einem
+@code{DATETIME}-, @code{DATE}- oder @code{TIMESTAMP}-Zusammenhang einen
+Sinn ergibt, wie @code{NOW()} oder @code{CURRENT_DATE}.
+@end itemize
+
+Unzulässige @code{DATETIME}-, @code{DATE}- oder @code{TIMESTAMP}-Werte
+werden in den ``0''-Wert des jeweiligen Typs umgewandelt (@code{'0000-00-00
+00:00:00'}, @code{'0000-00-00'} oder @code{00000000000000}).
+
+Bei Werten, die als Zeichenketten angegeben werden, die Begrenzer für
+Datumsanteile enthalten, ist es nicht notwendig, zwei Ziffern für Monats-
+oder Tageswerte anzugeben, die weniger als @code{10} sind.
+@code{'1979-6-9'} ist dasselbe wie @code{'1979-06-09'}. Gleichermaßen ist
+es bei Zeichenketten, die Begrenzer für Zeitanteile enthalten, nicht
+notwendig, zwei Ziffern für Stunden-, Monats- oder Sekundenwerte anzugeben,
+die weniger als @code{10} sind. @code{'1979-10-30 1:2:3'} ist dasselbe wie
+@code{'1979-10-30 01:02:03'}.
+
+Werte, die als Zahlen angegeben sind, sollten 6, 8, 12 oder 14 Ziffern lang
+sein. Wenn die Zahl 8 oder 14 Ziffern lang ist, wird angenommen, dass sie
+im @code{YYYYMMDD}- oder @code{YYYYMMDDHHMMSS}-Format ist und dass das Jahr
+durch die ersten 4 Ziffern angegeben wird. Wenn die Zahl 6 oder 12 Ziffern
+lang ist, wird angenommen, dass sie im @code{YYMMDD}- oder
+@code{YYMMDDHHMMSS}-Format ist und dass das Jahr durch die ersten 2 Ziffern
+angegeben wird. Zahlen, die nicht diesen Längen entsprechen, werden
+interpretiert, als ob sie mit führenden Nullen auf die nächst mögliche
+Länge gebracht worden wären.
+
+@cindex nicht begrenzte Zeichenketten
+@cindex Zeichenketten, non-delimited
+Werte, die als nicht begrenzte Zeichenketten angegeben werden, werden
+interpretiert, indem ihre Länge als gegeben angenommen wird. Wenn die
+Zeichenkette 8 oder 14 Zeichen lang ist, wird angenommen, dass das Jahr
+durch die ersten 4 Zeichen angegeben wird. Ansonsten wird angenommen, dass
+das Jahr durch die ersten 2 Zeichen angegeben wird. Die Zeichenkette wird
+von links nach rechts interpretiert, um die Jahres-, Monats-, Tages-,
+Stunden- und Sekundenwerte zu finden, für so viele Anteile, wie in der
+Zeichenkette vorkommen. Das bedeutet, dass Sie keine Zeichenketten benutzen
+sollten, die weniger als 6 Zeichen haben. Wenn Sie zum Beispiel
+@code{'9903'} angeben, in der Annahme, dass das März 1999 darstellt, werden
+Sie feststellen, dass MySQL einen ``0''-Datumswert in Ihre Tabelle einfügt.
+Das liegt daran, dass die Jahres- und Monatswerte @code{99} und @code{03}
+sind, aber der Tagesanteil fehlt (0), so dass der Wert kein zulässiges
+Datum darstellt.
+
+@code{TIMESTAMP}-Spalten speichern zulässige Werte mit der vollen
+Genauigkeit, mit der der Wert angegeben wurde, unabhängig von der
+Anzeigebreite. Das hat mehrere Auswirkungen:
+
+@itemize @bullet
+@item
+Geben Sie immer Jahr, Monat und Tag an, selbst wenn Ihre Spaltentypen
+@code{TIMESTAMP(4)} oder @code{TIMESTAMP(2)} sind. Ansonsten wäre der Wert
+kein zulässiges Datum und @code{0} würde gespeichert werden.
+
+@item
+Wenn Sie @code{ALTER TABLE} benutzen, um eine enge @code{TIMESTAMP}-Spalte
+breiter zu machen, werden Informationen angezeigt, die vorher ``versteckt''
+waren.
+
+@item
+Gleichermaßen führt das Verengen einer @code{TIMESTAMP}-Spalte nicht dazu,
+dass Informationen verloren gehen, ausser in dem Sinn, dass weniger
+Informationen dargestellt werden, wenn die Werte angezeigt werden.
+
+@item
+Obwohl @code{TIMESTAMP}-Werte mit voller Genauigkeit gespeichert werden,
+ist die einzige Funktion, die direkt mit dem zugrunde liegenden
+gespeicherten Wert arbeitet, @code{UNIX_TIMESTAMP()}. Alle anderen
+Funktionen arbeiten mit dem formatierten, abgerufenen Wert. Das bedeutet,
+Sie können keine Funktionen wie @code{HOUR()} oder @code{SECOND()}
+benutzen, wenn nicht auch der relevante Teil des @code{TIMESTAMP}-Werts im
+formatierten Werte enthalten ist. Wenn zum Beispiel der @code{HH}-Teil
+einer @code{TIMESTAMP}-Spalte nicht angezeigt wird, wenn die Anzeigebreite
+nicht mindestens 10 beträgt, wird der Versuch, @code{HOUR()} auf kürzere
+@code{TIMESTAMP}-Werte anzuwenden, unsinnige Ergebnisse erzeugen.
+@end itemize
+
+Bis zu einem gewissen Grad können Sie einem Objekt eines Datumstyp Werte
+eines anderen Datumstyps zuweisen. Jedoch kann eine Änderung des Wertes
+oder ein Informationsverlust eintreten:
+
+@itemize @bullet
+@item
+Wenn Sie einem @code{DATETIME}- oder @code{TIMESTAMP}-Objekt einen
+@code{DATE}-Wert zuweisen, wird der Zeitanteil im Ergebniswert auf
+@code{'00:00:00'} gesetzt, weil der @code{DATE}-Wert keine
+Zeitinformationen enthält.
+
+@item
+Wenn Sie einem @code{DATE}-Objekt einen @code{DATETIME}- oder
+@code{TIMESTAMP}-Wert zuweisen, wird der Zeitanteil des Ergebniswerts
+gelöscht, weil der @code{DATE}-Typ keine Zeitinformationen speichert.
+
+@item
+Denken Sie daran, dass @code{DATETIME}-, @code{DATE}- und
+@code{TIMESTAMP}-Werte zwar in denselben Formaten angegeben werden können,
+dass die Typen jedoch nicht alle denselben Wertebereich haben.
+@code{TIMESTAMP}-Werte zum Beispiel können nicht früher als @code{1970}
+oder später als @code{2037} sein. Das bedeutet, dass ein Datum wie
+@code{'1968-01-01'}, was als @code{DATETIME} oder @code{DATE}-Wert zulässig
+wäre, kein gültiger @code{TIMESTAMP}-Wert ist und in @code{0} umgewandelt
+wird, wenn er einem solchen Objekt zugewiesen wird.
+@end itemize
+
+@cindex Probleme, Datumswerte
+@cindex Datumswerte, Probleme
+Seien Sie auf der Hut vor Fallstricken, wenn Sie Datumswerte angeben:
+
+@itemize @bullet
+@item
+Das entspannte Format läßt Werte als Zeichenketten zu, die täuschen
+können. Ein Wert wie @code{'10:11:12'} zum Beispiel sieht wegen des
+@samp{:}-Begrenzers wie ein Zeitwert aus, wird er aber in einem
+Datums-Zusammenhang benutzt, wird er als das Datum @code{'2010-11-12'}
+interpretiert. Der Wert @code{'10:45:15'} wird in @code{'0000-00-00'}
+umgewandelt, weil @code{'45'} kein zulässiger Monat ist.
+
+@item
+Jahreswerte, die als zwei Ziffern angegeben werden, sind mehrdeutig, weil
+das Jahrhundert unbekannt ist.
+unknown. MySQL interpretiert 2-stellige Jahreswerte nach folgenden Regeln:
+
+@itemize @minus
+@item
+Jahreswerte im Bereich @code{00 bis 69} werden in @code{2000 bis 2069}
+umgewandelt.
+
+@item
+Jahreswerte im Bereich @code{70 bis 99} werden in @code{1970 bis 1999}
+umgewandelt.
+@end itemize
+@end itemize
+
+
+@node TIME, YEAR, DATETIME, Date and time types
+@c German node TIME
+@subsubsection Der @code{TIME}-Typ
+
+@tindex TIME
+
+MySQL ruft @code{TIME}-Werte ab und zeigt sie an im
+@code{'HH:MM:SS'}-Format (oder @code{'HHH:MM:SS'}-Format für große
+Stundenwerte). @code{TIME}-Werte rangieren von @code{'-838:59:59'} bis
+@code{'838:59:59'}. Der Grund dafür, dass der Stundenanteil so Groß sein
+kann, liegt darin, dass der @code{TIME}-Typ nicht nur benutzt werden kann,
+um die Tageszeit zu repräsentieren (wobei die Stunden weniger als 24 sein
+müssen), sondern auch abgelaufene Zeit oder ein Zeitintervall zwischen zwei
+Ereignissen (was viel größer als 24 Stunden oder sogar negativ sein kann).
+
+Sie können @code{TIME}-Werte in einer Vielzahl von Formaten angeben:
+
+@itemize @bullet
+@item
+Als eine Zeichenkette im @code{'D HH:MM:SS.bruchteil'}-Format. (Beachten
+Sie, dass MySQL bislang nicht den Bruchteil für die TIME-Spalte speichert.)
+Man kann auch folgende ``entspannte'' Syntax benutzen:
+
+@code{HH:MM:SS.bruchteil}, @code{HH:MM:SS}, @code{HH:MM}, @code{D HH:MM:SS},
+@code{D HH:MM}, @code{D HH} oder @code{SS}. Hierbei ist @code{D} Tage
+zwischen 0 und 33.
+
+@item
+Als eine Zeichenkette ohne Begrenzer im @code{'HHMMSS'}-Format,
+vorausgesetzt, dass diese als Zeitangabe einen Sinn ergibt. @code{'101112'}
+zum Beispiel wird als @code{'10:11:12'} interpretiert, aber @code{'109712'}
+ist unzulässig (es hat einen Minutenanteil, der keinen Sinn ergibt) und
+wird in @code{'00:00:00'} umgewandelt.
+
+@item
+Als eine Zahl im @code{HHMMSS}-Format, vorausgesetzt, dass diese als
+Zeitangabe einen Sinn ergibt. @code{101112} zum Beispiel wird als
+@code{'10:11:12'} interpretiert. Folgende alternativen Formate werden
+ebenfalls verstanden: @code{SS}, @code{MMSS}, @code{HHMMSS},
+@code{HHMMSS.bruchteil}. Beachten Sie, dass MySQL bislang noch nicht den
+Bruchteil speichert.
+
+@item
+Als Ergebnis einer Funktion, die einen Wert zurück gibt, der in einem
+@code{TIME}-Zusammenhang akzeptabel ist, wie @code{CURRENT_TIME}.
+@end itemize
+
+Bei @code{TIME}-Werten, die als Zeichenketten angegeben sind, die einen
+Begrenzer für den Zeitanteil beinhalten, ist es nicht notwendig, zwei
+Ziffern für Stunden-, Minuten- oder Sekunden-Werte anzugeben, die weniger
+als @code{10} sind. @code{'8:3:2'} ist dasselbe wie @code{'08:03:02'}.
+
+Seien Sie vorsichtig damit, einer @code{TIME}-Spalte ``kurze''
+@code{TIME}-Werte zuzuweisen. Ohne Semikolon interpretiert MySQL Werte
+unter der Annahme, dass die am weitesten rechts stehenden Ziffern Sekunden
+repräsentieren. (MySQL interpretiert @code{TIME}-Werte als vergangene Zeit
+statt als Tageszeit.) Sie könnten zum Beispiel denken, dass @code{'1112'}
+und @code{1112} @code{'11:12:00'} bedeuten (12 Minuten nach 11 Uhr), aber
+MySQL interpretiert sie als @code{'00:11:12'} (11 Minuten, 12 Sekunden).
+Gleichermaßen wird @code{'12'} und @code{12} als @code{'00:00:12'}
+interpretiert. @code{TIME}-Werte mit Semikolon werden statt dessen immer
+als Tageszeit interpretiert. Das heißt, @code{'11:12'} bedeutet
+@code{'11:12:00'}, nicht @code{'00:11:12'}.
+
+Werte, die ausserhalb des @code{TIME}-Wertebereichs liegen, ansonsten aber
+zulässig sind, werden auf den entsprechenden Endpunkt des Wertebereichs
+abgeschnitten. @code{'-850:00:00'} bzw. @code{'850:00:00'} werden in
+@code{'-838:59:59'} bzw. @code{'838:59:59'} umgewandelt.
+
+Unzulässige @code{TIME}-Werte werden in @code{'00:00:00'} umgewandelt.
+Beachten Sie, dass es keine Möglichkeit gibt zu unterscheiden, wenn ein
+Wert von @code{'00:00:00'} in einer Tabelle gespeichert ist, ob dieser
+originär als @code{'00:00:00'} eingegeben wurde oder ob es ein unzulässiger
+Wert war, weil @code{'00:00:00'} selbst ein zulässiger @code{TIME}-Wert
+ist.
+
+
+@node YEAR, , TIME, Date and time types
+@c German node YEAR
+@subsubsection Der @code{YEAR}-Typ
+
+@tindex YEAR
+
+Der @code{YEAR}-Typ ist ein 1-Byte-Typ, der für die Darstellung von Jahren
+benutzt wird.
+
+MySQL ruft @code{YEAR}-Werte ab und speichert sie im @code{YYYY}-Format.
+Der Wertebereich ist @code{1901} bis @code{2155}.
+
+Sie können @code{YEAR}-Werte in einer Vielzahl von Formaten angeben:
+
+@itemize @bullet
+@item
+Als vierstellige Zeichenkette im Wertebereich von @code{'1901'} bis
+@code{'2155'}.
+
+@item
+Als vierstellige Zahl im Wertebereich von @code{1901} bis @code{2155}.
+
+@item
+Als zweistellige Zeichenkette im Wertebereich von @code{'00'} bis
+@code{'99'}. Werte in den Bereichen von @code{'00'} bis @code{'69'} und
+@code{'70'} bis @code{'99'} werden in @code{YEAR}-Werte in den Bereichen
+von @code{2000} bis @code{2069} und @code{1970} bis @code{1999}
+umgewandelt.
+
+@item
+Als zweistellige Zahl im Wertebereich von @code{1} bis @code{99}. Werte in
+den Bereichen von @code{1} bis @code{69} und @code{70} bis @code{99} werden
+in @code{YEAR}-Werte in den Bereichen von @code{2001} bis @code{2069} und
+@code{1970} bis @code{1999} umgewandelt. Beachten Sie, dass der
+Wertebereich für zweistellige Zahlen sich geringfügig vom Wertebereich für
+zweistellige Zeichenketten unterscheidet, weil Sie 0 nicht direkt als Zahl
+eingeben können und sie dann als @code{2000} interpretiert wird. Sie
+@emph{müssen} sie als Zeichenkette @code{'0'} oder @code{'00'} angeben,
+oder sie wird als @code{0000} interpretiert.
+
+@item
+Als Ergebnis einer Funktion, die einen Wert zurück gibt, der in einem
+@code{YEAR}-Zusammenhang akzeptabel ist, wie @code{NOW()}.
+@end itemize
+
+Unzulässige @code{YEAR}-Werte werden in @code{0000} umgewandelt.
+
+
+@node String types, Choosing types, Date and time types, Column types
+@c German node Zeichenketten-Typen
+@subsection Zeichenketten-Typen
+
+@cindex Typen, Zeichenketten
+@cindex Zeichenketten-Typen
+
+@tindex CHAR
+@tindex VARCHAR
+
+
+
+Die Zeichenketten-Typen sind @code{CHAR}, @code{VARCHAR}, @code{BLOB},
+@code{TEXT}, @code{ENUM} und @code{SET}. Dieser Abschnitt beschreibt, wie
+diese Typen funktionieren, ihren Speicherbedarf und wie sie in Anfragen
+benutzt werden.
+
+
+@menu
+* CHAR::
+* BLOB::
+* ENUM::
+* SET::
+@end menu
+
+@node CHAR, BLOB, String types, String types
+@c German node CHAR
+@subsubsection Die @code{CHAR}- und @code{VARCHAR}-Typen
+
+Die @code{CHAR}- und @code{VARCHAR}-Typen sind ähnlich, unterscheiden sich
+aber in der Art, wie sie gespeichert und abgerufen werden.
+
+Die Länge einer @code{CHAR}-Spalte wird auf die Länge festgelegt, die Sie
+bei der Erzeugung der Tabelle angeben. Die Länge kann zwischen 1 und 255
+variieren. (Ab MySQL-Version 3.23 kann die Länge zwischen 0 und 255
+liegen.) Wenn @code{CHAR}-Werte gespeichert werden, werden sie am rechten
+Ende bis zur festgelegten Länge mit Leerzeichen aufgefüllt. Wenn
+@code{CHAR}-Werte abgerufen werden, werden die Leerzeichen am Ende
+entfernt.
+
+Werte in @code{VARCHAR}-Spalten sind Zeichenketten variabler Länge. Sie
+können eine @code{VARCHAR}-Spalte mit jeder Länge zwischen 1 und 255
+deklarieren, genau wie für @code{CHAR}-Spalten. Im Gegensatz zu @code{CHAR}
+werden @code{VARCHAR}-Werte jedoch nur mit so vielen Zeichen wie nötig
+gespeichert, plus 1 Byte, um die Länge zu speichern. Die Werte werden nicht
+aufgefüllt; statt dessen werden Leerzeichen am Ende beim Speichern
+entfernt. (Diese Entfernung von Leerzeichen weicht von der
+ANSI-SQL-Spezifikation ab.)
+
+Wenn Sie einer @code{CHAR}- oder @code{VARCHAR}-Spalte einen Wert zuweisen,
+der die maximale Spaltenlänge überschreitet, wird der Wert so zurecht
+geschnitten, das er passt.
+
+Die unten stehende Tabelle stellt die Unterschiede zwischen den beiden
+Spaltentypen dar, indem das Ergebnis der Speicherung unterschiedlicher
+Zeichenkettenwerte in @code{CHAR(4)}- und @code{VARCHAR(4)}-Spalten gezeigt
+wird:
+
+@c Need to use @(space) to make sure second Spaltenwerte retain spacing
+@c in output für Tabelle below.
+
+@multitable @columnfractions .2 .15 .2 .2 .25
+@item @strong{Wert} @tab @code{CHAR(4)} @tab @strong{Speicherbedarf} @tab @code{VARCHAR(4)} @tab @strong{Speicherbedarf}
+@item @code{''} @tab @code{'@ @ @ @ '} @tab 4 Bytes @tab @code{''} @tab 1 Byte
+@item @code{'ab'} @tab @code{'ab@ @ '} @tab 4 Bytes @tab @code{'ab'} @tab 3 Bytes
+@item @code{'abcd'} @tab @code{'abcd'} @tab 4 Bytes @tab @code{'abcd'} @tab 5 Bytes
+@item @code{'abcdefgh'} @tab @code{'abcd'} @tab 4 Bytes @tab @code{'abcd'} @tab 5 Bytes
+@end multitable
+
+Die Werte, die aus den @code{CHAR(4)}- und @code{VARCHAR(4)}-Spalten
+abgerufen werden, sind in jedem Fall gleich, weil Leerzeichen am Ende von
+@code{CHAR}-Spalten beim Abruf entfernt werden.
+
+Werte in @code{CHAR}- und @code{VARCHAR}-Spalten werden unabhängig von der
+Groß-/Kleinschreibung sortiert und verglichen, es sei denn, beim Erzeugen
+der Tabelle wurde das @code{BINARY}-Attribut festgelegt. Das
+@code{BINARY}-Attribut bedeutet, dass Spaltenwerte abhängig von der
+Groß-/Kleinschreibung in Übereinstimmung mit der ASCII-Reihenfolge der
+Maschine sortiert und verglichen werden, auf der der MySQL-Server läuft.
+@code{BINARY} beeinflusst nicht, wie die Spalte gespeichert oder abgerufen
+wird.
+
+Das @code{BINARY}-Attribut ist 'klebrig', das heißt, dass der gesamte
+Ausdruck als ein @code{BINARY}-Wert verglichen wird, sobald eine
+@code{BINARY}-Spalte im Ausdruck benutzt wird.
+
+MySQL ändert eventuell 'still' den Typ von @code{CHAR}- oder
+@code{VARCHAR}-Spalten bei der Tabellenerzeugung.
+@c German FIX unwrapped @xref
+@xref{Silent column changes}.
+
+
+@node BLOB, ENUM, CHAR, String types
+@c German node BLOB
+@subsubsection Die @code{BLOB}- und @code{TEXT}-Typen
+
+@tindex BLOB
+@tindex TEXT
+
+Ein @code{BLOB} ist großes Binärobjekt (Binary Large OBject), das eine
+variable Menge von Daten enthalten kann. Die vier @code{BLOB}-Typen
+@code{TINYBLOB}, @code{BLOB}, @code{MEDIUMBLOB} und @code{LONGBLOB}
+unterscheiden sich nur hinsichtlich der maximalen Länge der Werte, die sie
+aufnehmen können.
+@xref{Storage requirements}.
+
+Die vier @code{TEXT}-Typen @code{TINYTEXT}, @code{TEXT},
+@code{MEDIUMTEXT} und @code{LONGTEXT} entsprechen den vier
+@code{BLOB}-Typen und haben dieselben maximalen Längen und denselben
+Speicherbedarf. Der einzige Unterschied zwischen @code{BLOB}- und
+@code{TEXT}-Typen ist, dass beim Sortieren und Vergleichen bei
+@code{BLOB}-Werten Groß-/Kleinschreibung berücksichtigt wird, bei
+@code{TEXT}-Werten dagegen nicht. Mit anderen Worten ist ein @code{TEXT}
+ein @code{BLOB} ohne Berücksichtigung der Groß-/Kleinschreibung.
+
+Wenn Sie einer @code{BLOB}- oder @code{TEXT}-Spalte einen Wert zuweisen,
+der die maximale Länge des Spaltentyps überschreitet, wird der Wert so
+zurecht geschnitten, dass er passt.
+
+In fast jeder Hinsicht können Sie eine @code{TEXT}-Spalte als eine
+@code{VARCHAR}-Spalte betrachten, die so Groß sein kann, wie Sie wollen.
+Gleichermaßen können Sie eine @code{BLOB}-Spalte als eine @code{VARCHAR
+BINARY}-Spalte betrachten. Die Unterschiede sind:
+
+@itemize @bullet
+@item
+Seit MySQL-Version 3.23.2 können Sie Indexe auf @code{BLOB}- und
+@code{TEXT}-Spalten anlegen. Ältere Versionen von MySQL unterstützten das
+nicht.
+
+@item
+Leerzeichen am Ende werden beim Speichern von @code{BLOB}- und
+@code{TEXT}-Spalten nicht wie bei @code{VARCHAR}-Spalten entfernt.
+
+@item
+@cindex Vorgabewerte, @code{BLOB}- und @code{TEXT}-Spalten
+@cindex @code{BLOB}-Spalten, Vorgabewerte
+@cindex @code{TEXT}-Spalten, Vorgabewerte
+@code{BLOB}- und @code{TEXT}-Spalten können keine @code{DEFAULT}-Werte
+haben.
+@end itemize
+
+@strong{MyODBC} definiert @code{BLOB}-Werte als @code{LONGVARBINARY} und
+@code{TEXT}-Werte als @code{LONGVARCHAR}.
+
+Weil @code{BLOB}- und @code{TEXT}-Werte extrem lang sein können, treffen
+Sie bei der Benutzung eventuell auf Beschränkungen:
+
+@itemize @bullet
+@item
+Wenn Sie @code{GROUP BY} oder @code{ORDER BY} für @code{BLOB}- oder
+@code{TEXT}-Spalten benutzen wollen, müssen Sie den Spaltenwert in ein
+Objekt fester Länge umwandeln. Standardmäßig wird das mit der
+@code{SUBSTRING}-Funktion gemacht. Beispiel:
+
+@example
+mysql> select kommentar from tabelle,substring(kommentar,20) as substr
+ ORDER BY substr;
+@end example
+
+Wenn Sie das nicht tun, werden nur die ersten @code{max_sort_length} Bytes
+der Spalte beim Sortieren benutzt. Der Vorgabewert von
+@code{max_sort_length} ist 1024; dieser Wert kann mit der @code{-O}-Option
+geändert werden, wenn der @code{mysqld}-Server gestartet wird. Sie können
+auf einen Ausdruck, der @code{BLOB}- oder @code{TEXT}-Werte enthält,
+gruppieren, indem Sie die Spaltenposition angeben oder ein Alias benutzen:
+
+@example
+mysql> select id,substring(blob_spalte,1,100) from tabelle
+ GROUP BY 2;
+mysql> select id,substring(blob_spalte,1,100) as b from tabelle
+ GROUP BY b;
+@end example
+
+@item
+Die maximale Größe eines @code{BLOB}- oder @code{TEXT}-Objekts wird durch
+seinen Typ festgelegt, aber der größte Wert, den Sie tatsächlich zwischen
+Client und Server übertragen können, wird von der Menge verfügbaren
+Arbeitsspeichers und der Größe des Kommunikationspuffers festgelegt. Sie
+können die Nachrichtenpuffergröße ändern, müssen das aber auf beiden
+Seiten, also beim Client und beim Server, tun. @xref{Server parameters}.
+@end itemize
+
+Beachten Sie, dass intern jeder @code{BLOB}- oder @code{TEXT}-Wert durch
+ein separat zugewiesenes Objekt dargestellt wird. Das steht im Gegensatz zu
+allen anderen Spaltentypen, für die Speicherplatz einmal pro Spalte
+zugewiesen wird, wenn die Tabelle geöffnet wird.
+
+
+@node ENUM, SET, BLOB, String types
+@c German node ENUM
+@subsubsection Der @code{ENUM}-Typ
+
+@tindex ENUM
+
+Ein @code{ENUM} ist ein Zeichenketten-Objekt, dessen Wert normalerweise aus
+einer Liste zulässiger Werte ausgesucht wird, die explizit bei der
+Spaltenspezifizierung bei der Tabellenerzeugung aufgezählt werden.
+
+Der Wert kann unter bestimmten Umständen auch die leere Zeichenkette
+(@code{""}) oder @code{NULL} sein:
+
+@itemize @bullet
+@item
+Wenn Sie in eine @code{ENUM} einen ungültigen Wert einfügen (das ist eine
+Zeichenkette, die es in der Auflistung zugelassener Werte nicht gibt), wird
+statt dessen die leere Zeichenkette als spezieller Fehlerwert eingefügt.
+Diese Zeichenkette kann von einer 'normalen' leeren Zeichenkette dadurch
+unterschieden werden, dass diese Zeichenkette den numerischen Wert 0 hat.
+Mehr dazu später.
+
+@item
+Wenn ein @code{ENUM} als @code{NULL} deklariert ist, ist @code{NULL}
+ebenfalls ein zulässiger Wert für die Spalte und der Vorgabewert ist
+@code{NULL}. Wenn ein @code{ENUM} als @code{NOT NULL} deklariert ist, ist
+der Vorgabewert das erste Element der Auflistung erlaubter Werte.
+@end itemize
+
+Jeder Aufzählungswert hat einen Index:
+
+@itemize @bullet
+@item
+Werte der Auflistung zulässiger Elemente in der Spaltenspezifikation fangen
+mit 1 an.
+
+@item
+Der Indexwert des Fehlerwerts leere Zeichenkette ist 0. Folglich können Sie
+folgendes @code{SELECT}-Statement benutzen, um Zeilen zu finden, denen
+unzulässige @code{ENUM}-Werte zugewiesen wurden:
+
+@example
+mysql> SELECT * FROM tabelle WHERE enum_spalte=0;
+@end example
+
+@item
+Der Index des @code{NULL}-Werts ist @code{NULL}.
+@end itemize
+
+Wenn beispielsweise eine Spalte als @code{ENUM("eins", "zwei", "drei")}
+festgelegt wurde, kann sie einen der unten dargestellen Werte besitzen. Der
+Index jedes Werts wird auch dargestellt:
+
+@multitable @columnfractions .2 .8
+@item @strong{Wert} @tab @strong{Index}
+@item @code{NULL} @tab @code{NULL}
+@item @code{""} @tab 0
+@item @code{"eins"} @tab 1
+@item @code{"zwei"} @tab 2
+@item @code{"drei"} @tab 3
+@end multitable
+
+Eine Aufzählung kann maximal 65535 Elemente enthalten.
+
+Groß-/Kleinschreibung ist irrelevant, wenn Sie einer @code{ENUM}-Spalte
+Werte zuweisen. Jedoch haben Werte, die später aus der Spalte abgerufen
+werden, dieselbe Groß-/Kleinschreibung wie die Werte, die für die
+Festlegung zulässiger Werte bei der Tabellenerzeugung verwendet wurden.
+
+Wenn Sie eine @code{ENUM} in einem numerischen Zusammenhang benutzen, wird
+der Index des Spaltenwerts zurückgegeben. Sie können beispielsweise
+numerische Werte aus einer @code{ENUM}-Spalte wie folgt abrufen:
+
+@example
+mysql> SELECT enum_spalte+0 FROM tabelle;
+@end example
+
+Wenn Sie eine Zahl in eine @code{ENUM} speichern, wird die Zahl als Index
+behandelt und der gespeicherte Wert ist das Aufzählungselement mit diesem
+Index. (Das funktioniert jedoch nicht bei @code{LOAD DATA}, was alle
+Eingaben als Zeichenketten behandelt.)
+
+@code{ENUM}-Werte werden in der Reihenfolge sortiert, wie die
+Aufzählungselemente bei der Spaltenspezifizierung eingegeben wurden. (Mit
+anderen Worten werden @code{ENUM}-Werte nach ihren Indexzahlen sortiert.)
+So wird beispielsweise @code{"a"} vor @code{"b"} einsortiert bei
+@code{ENUM("a", "b")}, aber @code{"b"} wird vor @code{"a"} einsortiert bei
+@code{ENUM("b", "a")}. Die leere Zeichenkette wird vor nicht leeren
+Zeichenketten und @code{NULL}-Werte vor allen anderen Aufzählungswerten
+einsortiert.
+
+Wenn Sie alle möglichen Werte einer @code{ENUM}-Spalte erhalten wollen,
+benutzen Sie: @code{SHOW COLUMNS FROM tabelle LIKE enum_spalte} und gehen
+die @code{ENUM}-Definition in der zweiten Spalte durch.
+
+
+@node SET, , ENUM, String types
+@c German node SET
+@subsubsection Der @code{SET}-Typ
+
+@tindex SET
+
+Ein @code{SET} ist ein Zeichenketten-Objekt, das 0 oder mehr Werte haben
+kann, wovon jedes aus einer Auflistung zulässiger Werte stammen muss, die
+bei der Tabellenerzeugung festgelegt wurden. @code{SET}-Spaltenwerte, die
+aus mehrfachen SET-Elementen bestehen, werden angegeben, indem die Elemente
+durch Kommas (@samp{,}) getrennt werden. Daraus ergibt sich, dass
+@code{SET}-Elemente selbst keine Kommas enthalten dürfen.
+
+Eine Spalte beispielsweise, die als @code{SET("eins", "zwei") NOT NULL}
+festgelegt wurde, kann folgende Werte haben:
+
+@example
+""
+"eins"
+"zwei"
+"eins,zwei"
+@end example
+
+
+Eine @code{SET} kann maximal 64 unterschiedliche Elemente besitzen.
+
+MySQL speichert @code{SET}-Werte numerisch, wobei das niedrigste Bit in der
+Reihenfolge der gespeicherten Werte dem ersten SET-Element entspricht. Wenn
+Sie einen @code{SET}-Wert in einem numerischen Zusammenhang abrufen, hat
+der abgerufene Werte Bits gesetzt, die den SET-Elementen, aus denen sich
+der Spaltenwert zusammensetzt, entspricht. Beispielsweise können Sie
+numerische Werte aus einer @code{SET}-Spalte wie folgt abrufen:
+
+@example
+mysql> SELECT set_spalte+0 FROM tabelle;
+@end example
+
+Wenn in einer @code{SET}-Spalte eine Zahl gespeichert wird, legen die Bits,
+die in der binären Darstellung der Zahl gesetzt sind, die SET-Elemente im
+Spaltenwert fest. Angenommen, eine Spalte ist als
+@code{SET("a","b","c","d")} festgelegt, dann haben die Elemente folgende
+Bitwerte:
+
+@multitable @columnfractions .2 .2 .6
+@item @code{SET} @strong{Element} @tab @strong{Dezimalwert} @tab @strong{Binärwert}
+@item @code{a} @tab @code{1} @tab @code{0001}
+@item @code{b} @tab @code{2} @tab @code{0010}
+@item @code{c} @tab @code{4} @tab @code{0100}
+@item @code{d} @tab @code{8} @tab @code{1000}
+@end multitable
+
+Wenn Sie dieser Spalte einen Wert von @code{9} zuweisen, ist das binär
+@code{1001}. Daher werden der erste und der vierte @code{SET}-Wert, die
+Elemente @code{"a"} und @code{"d"}, ausgewählt, und der Ergebniswert ist
+@code{"a,d"}.
+
+Bei einem Wert, der mehr als ein @code{SET}-Element enthält, spielt es
+keine Rolle, in welcher Reihenfolge die Elemente aufgelistet sind, wenn Sie
+den Wert einfügen. Es spielt ebenfalls keine Rolle, wie oft ein gegebenes
+Element im Wert aufgelistet ist. Wenn der Wert später abgerufen wird,
+erscheint jedes Element im Wert einmal, wobei die Elemente in der
+Reihenfolge erscheinen, in der sie bei der Tabellenerzeugung festgelegt
+wurden. Wenn eine Spalte beispielsweise als @code{SET("a","b","c","d")}
+festgelegt ist, erscheinen @code{"a,d"}, @code{"d,a"} und
+@code{"d,a,a,d,d"} als @code{"a,d"}, wenn sie abgerufen werden.
+
+@code{SET}-Werte werden numerisch sortiert. @code{NULL}-Werte werden vor
+Nicht-@code{NULL}-@code{SET}-Werten einsortiert.
+
+Normalerweise führt man @code{SELECT} auf eine @code{SET}-Spalte mit dem
+@code{LIKE}-Operator oder der @code{FIND_IN_SET()}-Funktion aus:
+
+@example
+mysql> SELECT * FROM tabelle WHERE set_spalte LIKE '%wert%';
+mysql> SELECT * FROM tabelle WHERE FIND_IN_SET('wert',set_spalte)>0;
+@end example
+
+Aber auch folgendes funktioniert:
+
+@example
+mysql> SELECT * FROM tabelle WHERE set_spalte = 'wert1,wert2';
+mysql> SELECT * FROM tabelle WHERE set_spalte & 1;
+@end example
+
+Das erste dieser Statements sucht nach einer exakten Übereinstimmung, das
+zweite sucht Werte, die das erste SET-Element enthalten.
+
+Wenn Sie alle möglichen Werte einer @code{SET}-Spalte erhalten wollen,
+benutzen Sie: @code{SHOW COLUMNS FROM tabelle LIKE set_spalte} und gehen
+die @code{SET}-Definition in der zweiten Spalte durch.
+
+
+@node Choosing types, Other-vendor column types, String types, Column types
+@c German node Typen auswählen
+@subsection Den richtigen Typ für eine Spalte auswählen
+
+@cindex Typen, Spalten
+@cindex Typen auswählen
+
+Um möglichst effizient zu speichern, benutzen Sie in jedem Fall den
+präzisesten Typ. Wenn zum Beispiel eine Ganzzahl-Spalte für Werte im
+Bereich zwischen @code{1} und @code{99999} benutzt wird, ist
+@code{MEDIUMINT UNSIGNED} der beste Typ.
+
+Akkurate Darstellung monetärer Werte ist ein häufiges Problem. In MySQL
+sollten Sie den @code{DECIMAL}-Typ benutzen. Dieser wird als Zeichenkette
+gepeichert, weshalb kein Genauigkeitsverlust auftreten sollte. Wenn
+Genauigkeit nicht allzu wichtig ist, sollte auch der @code{DOUBLE}-Typ
+ausreichen.
+
+Um hohe Präzision zu erzielen, können Sie immer auch in einen Festkommawert
+umwandeln, der in einer @code{BIGINT} gespeichert wird. Das erlaubt Ihnen,
+alle Berechnungen mit Ganzzahlen durchzuführen und die Ergebnisse nur wenn
+notwendig in Fließkommawerte zurückzuwandeln.
+
+
+@node Other-vendor column types, Storage requirements, Choosing types, Column types
+@c German node Spaltentypen anderer Hersteller
+@subsection Spaltentypen anderer Datenbanken benutzen
+
+@cindex Typen, Portabilität
+@cindex Portabilität, Typen
+@cindex Spalten, andere Typen
+
+Um es einfacher zu machen, Code zu verwenden, der für SQL-Implementationen
+anderer Hersteller geschrieben wurde, ordnet (mappt) MySQL Spaltentypen zu
+wie in unten stehender Tabelle dargestellt. Diese Mappings machen es
+leichter, Tabellendefinitionen anderer Datenbanken nach MySQL zu
+verschieben:
+
+@multitable @columnfractions .4 .6
+@item @strong{Typ anderer Hersteller} @tab @strong{MySQL-Typ}
+@item @code{BINARY(NUM)} @tab @code{CHAR(NUM) BINARY}
+@item @code{CHAR VARYING(NUM)} @tab @code{VARCHAR(NUM)}
+@item @code{FLOAT4} @tab @code{FLOAT}
+@item @code{FLOAT8} @tab @code{DOUBLE}
+@item @code{INT1} @tab @code{TINYINT}
+@item @code{INT2} @tab @code{SMALLINT}
+@item @code{INT3} @tab @code{MEDIUMINT}
+@item @code{INT4} @tab @code{INT}
+@item @code{INT8} @tab @code{BIGINT}
+@item @code{LONG VARBINARY} @tab @code{MEDIUMBLOB}
+@item @code{LONG VARCHAR} @tab @code{MEDIUMTEXT}
+@item @code{MIDDLEINT} @tab @code{MEDIUMINT}
+@item @code{VARBINARY(NUM)} @tab @code{VARCHAR(NUM) BINARY}
+@end multitable
+
+Dass Zuordnen (Mapping) von Spaltentypen geschieht bei der Erzeugung der
+Tabelle. Wenn Sie eine Tabelle mit Typen erzeugen, die von anderen
+Herstellern benutzt werden, und dann ein @code{DESCRIBE tabelle}-Statement
+absetzen, zeigt MySQL die Tabellenstruktur mit den äquivalenten MySQL-Typen
+an.
+
+
+@node Storage requirements, , Other-vendor column types, Column types
+@c German node Speicherbedarf
+@subsection Speicherbedarf von Spaltentypen
+
+@cindex Speicherbedarf, Spaltentyp
+@cindex Spalten, Speicherbedarf
+
+Der Speicherbedarf jedes Spaltentyps, der von MySQL unterstützt wird, ist
+unten nach Kategorie sortiert aufgelistet:
+
+@cindex numerische Typen
+@cindex Typen, numerische
+
+@subsubheading Speicherbedarf für numerische Typen
+
+@multitable @columnfractions .5 .5
+@item @strong{Spaltentyp} @tab @strong{Speicherbedarf}
+@item @code{TINYINT} @tab 1 Byte
+@item @code{SMALLINT} @tab 2 Bytes
+@item @code{MEDIUMINT} @tab 3 Bytes
+@item @code{INT} @tab 4 Bytes
+@item @code{INTEGER} @tab 4 Bytes
+@item @code{BIGINT} @tab 8 Bytes
+@item @code{FLOAT(X)} @tab 4, wenn X <= 24, oder 8, wenn 25 <= X <= 53
+@item @code{FLOAT} @tab 4 Bytes
+@item @code{DOUBLE} @tab 8 Bytes
+@item @code{DOUBLE PRECISION} @tab 8 Bytes
+@item @code{REAL} @tab 8 Bytes
+@item @code{DECIMAL(M,D)} @tab @code{M+2} Bytes, wenn D > 0, @code{M+1} Bytes, wenn D = 0 (@code{D}+2, wenn @code{M < D})
+@item @code{NUMERIC(M,D)} @tab @code{M+2} Bytes, wenn D > 0, @code{M+1} Bytes, wenn D = 0 (@code{D}+2, wenn @code{M < D})
+@end multitable
+
+@cindex Datumstypen
+@cindex Zeittypen
+@cindex Typen, Datum
+@cindex Typen, Zeit
+
+@subsubheading Speicherbedarf für Datums- und Zeit-Typen
+
+@multitable @columnfractions .5 .5
+@item @strong{Spaltentyp} @tab @strong{Speicherbedarf}
+@item @code{DATE} @tab 3 Bytes
+@item @code{DATETIME} @tab 8 Bytes
+@item @code{TIMESTAMP} @tab 4 Bytes
+@item @code{TIME} @tab 3 Bytes
+@item @code{YEAR} @tab 1 Byte
+@end multitable
+
+@subsubheading Speicherbedarf für Zeichenketten-Typen
+
+@multitable @columnfractions .5 .5
+@item @strong{Spaltentyp} @tab @strong{Speicherbedarf}
+@item @code{CHAR(M)} @tab @code{M} Bytes, @code{1 <= M <= 255}
+@item @code{VARCHAR(M)} @tab @code{L}+1 Bytes, wobei @code{L <= M} und
+@code{1 <= M <= 255}
+@item @code{TINYBLOB}, @code{TINYTEXT} @tab @code{L}+1 Bytes,
+wobei @code{L} < 2^8
+@item @code{BLOB}, @code{TEXT} @tab @code{L}+2 Bytes,
+wobei @code{L} < 2^16
+@item @code{MEDIUMBLOB}, @code{MEDIUMTEXT} @tab @code{L}+3 Bytes,
+wobei @code{L} < 2^24
+@item @code{LONGBLOB}, @code{LONGTEXT} @tab @code{L}+4 Bytes,
+wobei @code{L} < 2^32
+@item @code{ENUM('wert1','wert2',...)} @tab 1 oder 2 Bytes, abhängig von
+der Anzahl der Aufzählungswerte (65535 Werte maximal)
+@item @code{SET('wert1','wert2',...)} @tab 1, 2, 3, 4 oder 8 Bytes,
+abhängig von der Anzahl von SET-Elementen (64 Elemente maximal)
+@end multitable
+
+@cindex @code{BLOB}, Größe
+@cindex @code{TEXT}, Größe
+@cindex @code{VARCHAR}, Größe
+@code{VARCHAR} und die @code{BLOB}- und @code{TEXT}-Typen sind Typen
+variabler Länge, bei denen der Speicherbedarf von der tatsächlichen Länge
+der Spaltenwerte abhängt (in der vorstehenden Tabelle dargestellt durch
+@code{L}) statt von der maximal möglichen Größe des Typs.
+@code{VARCHAR(10)} zum Beispiel kann eine Zeichenkette mit einer maximalen
+Länge von 10 Zeichen enthalten. Der tatsächliche Speicherbedarf ist die
+Länge der Zeichenkette (@code{L}) plus 1 Byte, um die Länge zu speichern.
+Bei der Zeichenkette @code{'abcd'} ist @code{L} 4 und der Speicherbedarf 5
+Bytes.
+
+Die @code{BLOB}- und @code{TEXT}-Typen benötigen 1, 2, 3 oder 4 Bytes, um
+die Länge des Spaltenwerts zu speichern, abhängig von der maximal möglichen
+Länge des Typs. @xref{BLOB}.
+
+Wenn eine Tabelle irgend welche Spaltentypen variabler Länge enthält, ist
+das Datensatzformat ebenfalls von variabler Länge. Beachten Sie, dass MySQL
+bei der Erzeugung einer Tabelle unter bestimmten Umständen eine Spalte
+eines Typs variabler Länge in einen Typ fester Länge umwandelt, und
+umgekehrt. @xref{Silent column changes}.
+
+@cindex ENUM, Größe
+Die Größe eines @code{ENUM}-Objekts hängt von der Anzahl unterschiedlicher
+Aufzählungswerte ab. Bei Aufzählungen mit bis zu 255 möglichen Werten wird
+1 Byte benutzt, bei Aufzählungen mit bis zu 65535 Werten 2 Bytes.
+@xref{ENUM}.
+
+@cindex SET, Größe
+Die Größe eines @code{SET}-Objekts hängt von der Anzahl unterschiedlicher
+SET-Elemente ab. Wenn die SET-Größe @code{N} ist, belegt das Objekt
+@code{(N+7)/8} Bytes, gerundet auf 1, 2, 3, 4 oder 8 Bytes. Ein @code{SET}
+kann maximal 64 Elemente besitzen. @xref{SET}.
+
+
+@node Functions, Data Manipulation, Column types, Reference
+@c German node Funktionen
+@section Funktionen für die Benutzung in @code{SELECT}- und @code{WHERE}-Klauseln
+
+@cindex Funktionen für @code{SELECT} und @code{WHERE}-Klauseln
+
+Ein @code{select_ausdruck} oder eine @code{where_definition} in einem
+SQL-Statement kann aus jedem beliebigen Ausdruck bestehen, der die unten
+beschriebenen Funktionen benutzt.
+
+Ein Ausdruck, der @code{NULL} enthält, erzeugt immer einen
+@code{NULL}-Wert, wenn es in der Dokumentation für die Operatoren und
+Funktionen, die im Ausdruck vorkommen, nicht anders beschrieben ist.
+
+@strong{HINWEIS:} Zwischen Funktionsname und der folgenden Klammer darf
+kein Leerraum stehen. Das hilft dem MySQL-Parser, zwischen
+Funktionsaufrufen und Tabellen- oder Spaltenverweisen zu unterscheiden, die
+denselben Namen haben wie eine Funktion. Leerzeichen um Argumente herum
+sind dagegen zulässig.
+
+Sie können MySQL zwingen, Leerzeichen nach dem Funktionsnamen zu
+akzeptieren, indem Sie @code{mysqld} mit @code{--ansi} starten oder
+@code{CLIENT_IGNORE_SPACE} bei @code{mysql_connect()}, benutzen, aber in
+diesem Fall werden alle Funktionsnamen zu reservierten Wörtern.
+@xref{ANSI mode}.
+
+@need 2000
+
+Der Kürze zuliebe sind die Ausgaben des @code{mysql}-Programms in gekürzter
+Form dargestellt. Daher wird
+
+@example
+mysql> select MOD(29,9);
++-----------+
+| mod(29,9) |
++-----------+
+| 2 |
++-----------+
+1 rows in set (0.00 sec)
+@end example
+
+wie folgt dargestellt:
+
+@example
+mysql> select MOD(29,9);
+ -> 2
+@end example
+
+
+
+@menu
+* Non-typed Operators::
+* String functions::
+* Numeric Functions::
+* Date and time functions::
+* Other Functions::
+* Group by functions::
+@end menu
+
+@node Non-typed Operators, String functions, Functions, Functions
+@c German node Nicht typenspezifische Operatoren
+@subsection Nicht typenspezifische Operatoren und Funktionen
+
+
+
+@menu
+* Parentheses::
+* Comparison Operators::
+* Logical Operators::
+* Control flow functions::
+@end menu
+
+@node Parentheses, Comparison Operators, Non-typed Operators, Non-typed Operators
+@c German node Klammer
+@subsubsection Klammer
+
+@findex () (Klammern)
+@findex Klammern ( und )
+
+@cindex Funktionen, Gruppierungs-
+@cindex Gruppierung, Ausdrücke
+
+@example
+( ... )
+@end example
+
+Benutzen Sie Klammern, um die Reihenfolge der Auswertung in einem Ausdruck
+zu erzwingen. Beispiel:
+
+@example
+mysql> select 1+2*3;
+ -> 7
+mysql> select (1+2)*3;
+ -> 9
+@end example
+
+
+
+@node Comparison Operators, Logical Operators, Parentheses, Non-typed Operators
+@c German node Vergleichsoperatoren
+@subsubsection Vergleichsoperatoren
+
+@findex Vergleichsoperatoren
+
+@cindex Casts
+@cindex Typumwandlungen
+
+Vergleichsoperationen ergeben einen Wert von @code{1} (TRUE), @code{0}
+(FALSE) oder @code{NULL}. Diese Funktionen funktionieren sowohl bei Zahlen
+als auch bei Zeichenketten. Zeichenketten werden bei Bedarf automatisch in
+Zahlen und Zahlen in Zeichenketten umgewandelt (wie in Perl oder PHP).
+
+MySQL führt Vergleiche nach folgenden Regeln durch:
+
+@itemize @bullet
+@item
+Wenn ein oder beide Argumente @code{NULL} sind, ist das Ergebnis des
+Vergleichs @code{NULL}, ausser beim @code{<=>} Operator.
+
+@item
+Wenn beide Argumente in einer Vergleichsoperation Zeichenketten sind,
+werden sie als Zeichenketten verglichen.
+
+@item
+Wenn beide Argumente Ganzzahlen sind, werden sie als Ganzzahlen verglichen.
+
+@item
+Hexadezimale Werte werden als binäre Zeichenketten behandelt, wenn sie
+nicht mit einer Zahl verglichen werden.
+
+@item
+@cindex ODBC-Kompatibilität
+@cindex Kompatibilität, mit ODBC
+Wenn eins der Argumente eine @code{TIMESTAMP}- oder @code{DATETIME}-Spalte
+ist und das andere Argument eine Konstante, wird die Konstante in einen
+Zeitstempel umgewandelt, bevor der Vergleich durchgeführt wird. Das wird
+gemacht, um ODBC-freundlicher zu sein.
+
+@item
+In allen anderen Fällen werden die Argumente als Fließkommazahlen
+verglichen.
+@end itemize
+
+Vorgabemäßig werden Zeichenketten-Vergleiche unabhängig von der verwendeten
+Groß-/Kleinschreibung durchgeführt, indem der aktuelle Zeichensatz benutzt
+wird (vorgabemäßig ISO-8859-1 Latin1, der auch für englisch exzellent
+funktioniert).
+
+Die unten stehenden Beispiele erläutern die Umwandlung von Zeichenketten in
+Zahlen für Vergleichsoperationen:
+
+@example
+mysql> SELECT 1 > '6x';
+ -> 0
+mysql> SELECT 7 > '6x';
+ -> 1
+mysql> SELECT 0 > 'x6';
+ -> 0
+mysql> SELECT 0 = 'x6';
+ -> 1
+@end example
+
+@table @code
+@findex = (gleich)
+@findex gleich (=)
+@item =
+Gleich:
+@example
+mysql> select 1 = 0;
+ -> 0
+mysql> select '0' = 0;
+ -> 1
+mysql> select '0.0' = 0;
+ -> 1
+mysql> select '0.01' = 0;
+ -> 0
+mysql> select '.01' = 0.01;
+ -> 1
+@end example
+
+@findex <> (ungleich)
+@findex ungleich (<>)
+@findex != (ungleich)
+@findex ungleich (!=)
+@item <>
+@itemx !=
+Ungleich:
+@example
+mysql> select '.01' <> '0.01';
+ -> 1
+mysql> select .01 <> '0.01';
+ -> 0
+mysql> select 'zapp' <> 'zappp';
+ -> 1
+@end example
+
+@findex <= (kleiner oder gleich)
+@findex kleiner oder gleich (<=)
+@item <=
+Kleiner oder gleich:
+@example
+mysql> select 0.1 <= 2;
+ -> 1
+@end example
+
+@findex < (kleiner als)
+@findex kleiner als (<)
+@item <
+Kleiner als:
+@example
+mysql> select 2 < 2;
+ -> 0
+@end example
+
+@findex >= (größer oder gleich)
+@findex größer oder gleich (>=)
+@item >=
+Größer oder gleich:
+@example
+mysql> select 2 >= 2;
+ -> 1
+@end example
+
+@findex > (größer als)
+@findex größer als (>)
+@item >
+Größer als:
+@example
+mysql> select 2 > 2;
+ -> 0
+@end example
+
+@cindex @code{NULL}, testen auf Null
+@findex <=> (Gleich)
+@item <=>
+Null-sicheres gleich:
+@example
+mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
+ -> 1 1 0
+@end example
+
+@cindex @code{NULL}, testen auf Null
+@findex IS NULL
+@findex IS NOT NULL
+@item IS NULL
+@itemx IS NOT NULL
+Testet, ob eine Wert @code{NULL} ist oder nicht:
+@example
+mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL;
+ -> 0 0 1
+mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
+ -> 1 1 0
+@end example
+
+@findex BETWEEN ... AND
+@item ausdruck BETWEEN min AND max
+Wenn @code{ausdruck} größer oder gleich @code{min} ist und @code{ausdruck}
+kleiner oder gleich @code{max} ist, gibt @code{BETWEEN} @code{1} zurück,
+andernfalls @code{0}. Das ist äquivalent zum Ausdruck @code{(min <=
+ausdruck AND ausdruck <= max)}, wenn alle Argumente vom selben Typ sind.
+Das erste Argument (@code{ausdruck}) legt fest, wie der Vergleich
+durchgeführt wird:
+
+@itemize @bullet
+@item
+Wenn @code{ausdruck} eine @code{TIMESTAMP}-, @code{DATE}- oder
+@code{DATETIME}-Spalte ist, werden @code{MIN()} und @code{MAX()} im selben
+Format formatiert als wären sie Konstanten.
+@item
+Wenn @code{ausdruck} ein Zeichenketten-Ausdruck ohne Berücksichtigung der
+Groß-/Kleinschreibung ist, wird ein Zeichenkettenvergleich ohne
+Berücksichtigung der Groß-/Kleinschreibung durchgeführt.
+@item
+Wenn @code{ausdruck} ein Zeichenketten-Ausdruck mit Berücksichtigung der
+Groß-/Kleinschreibung ist, wird ein Zeichenkettenvergleich mit
+Berücksichtigung der Groß-/Kleinschreibung durchgeführt.
+@item
+Wenn @code{ausdruck} ist ein Ganzzahl-Ausdruck ist, wird ein
+Ganzzahlvergleich durchgeführt.
+@item
+Ansonsten wird ein Fließkommazahlenvergleich durchgeführt.
+@end itemize
+
+@example
+mysql> select 1 BETWEEN 2 AND 3;
+ -> 0
+mysql> select 'b' BETWEEN 'a' AND 'c';
+ -> 1
+mysql> select 2 BETWEEN 2 AND '3';
+ -> 1
+mysql> select 2 BETWEEN 2 AND 'x-3';
+ -> 0
+@end example
+
+@findex IN
+@item ausdruck IN (wert,...)
+Gibt @code{1} zurück, wenn @code{ausdruck} einen Wert hat, der in der
+@code{IN}-Liste enthalten ist, ansonsten @code{0}. Wenn alle Werte
+Konstanten sind, werden alle Werte gemäß dem Typ von @code{ausdruck}
+ausgewertet und sortiert. Danach wird ein Element mittels binärer Suche
+gesucht. Das heißt, dass @code{IN} sehr schnell ist, wenn die
+@code{IN}-Werteliste ausschließlich aus Konstanten besteht. Wenn
+@code{ausdruck} ein Zeichenketten-Ausdruck mit Berücksichtigung der
+Groß-/Kleinschreibung ist, wird der Zeichenkettenvergleich unter
+Berücksichtigung der Groß-/Kleinschreibung durchgeführt:
+
+@example
+mysql> select 2 IN (0,3,5,'wefwf');
+ -> 0
+mysql> select 'wefwf' IN (0,3,5,'wefwf');
+ -> 1
+@end example
+
+@findex NOT IN
+@item ausdruck NOT IN (wert,...)
+Dasselbe wie @code{NOT (ausdruck IN (wert,...))}.
+
+@findex ISNULL()
+@item ISNULL(ausdruck)
+Wenn @code{ausdruck} @code{NULL} ist, gibt @code{ISNULL()} @code{1} zurück,
+ansonsten @code{0}:
+@example
+mysql> select ISNULL(1+1);
+ -> 0
+mysql> select ISNULL(1/0);
+ -> 1
+@end example
+
+Beachten Sie, dass ein Vergleich von @code{NULL}-Werten mit @code{=} immer
+UNWAHR ergibt!
+
+@cindex @code{NULL}, testen auf Null
+@findex COALESCE()
+@item COALESCE(liste)
+Gibt das erste Nicht-@code{NULL}-Element in der Liste zurück:
+
+@example
+mysql> select COALESCE(NULL,1);
+ -> 1
+mysql> select COALESCE(NULL,NULL,NULL);
+ -> NULL
+@end example
+
+@findex INTERVAL()
+@item INTERVAL(N,N1,N2,N3,...)
+Gibt @code{0} zurück, wenn @code{N} < @code{N1}, @code{1}, wenn @code{N} <
+@code{N2} usw. Alle Argumente werden als Ganzzahlen behandelt. Es ist
+erforderlich, dass @code{N1} < @code{N2} < @code{N3} < @code{...} <
+@code{Nn} ist, damit diese Funktion korrekt funktioniert. Das liegt daran,
+dass eine (sehr schnelle) binäre Suche benutzt wird:
+
+@example
+mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
+ -> 3
+mysql> select INTERVAL(10, 1, 10, 100, 1000);
+ -> 2
+mysql> select INTERVAL(22, 23, 30, 44, 200);
+ -> 0
+@end example
+@end table
+
+Wenn Sie eine Zeichenkette, die Groß-/Kleinschreibung nicht
+berücksichtigt, mit einem der Standard-Operatoren vergleichen (@code{=},
+@code{<>}..., aber nicht @code{LIKE}), werden Leerzeichen am Ende
+ignoriert:
+
+@example
+mysql> select "a" ="A ";
+ -> 1
+@end example
+
+
+@node Logical Operators, Control flow functions, Comparison Operators, Non-typed Operators
+@c German node Logische Operatoren
+@subsubsection Logische Operatoren
+
+@findex Logische Funktionen
+@findex Funktionen, logische
+
+Alle logischen Funktionen geben @code{1} (TRUE), @code{0} (FALSE) oder
+@code{NULL} (unbekannt, was in den meisten Fällen dasselbe wie FALSE ist)
+zurück:
+
+@table @code
+@findex NOT, logisch
+@findex ! (logisch NOT)
+@item NOT
+@itemx !
+Logisch NOT. Gibt @code{1} zurück, wenn das Argument @code{0} ist,
+ansonsten @code{0}.
+Ausnahme: @code{NOT NULL} gibt @code{NULL} zurück:
+@example
+mysql> select NOT 1;
+ -> 0
+mysql> select NOT NULL;
+ -> NULL
+mysql> select ! (1+1);
+ -> 0
+mysql> select ! 1+1;
+ -> 1
+@end example
+Das letzte Beispiel gibt @code{1} zurück, weil der Ausdruck auf dieselbe
+Art ausgewertet wird wie @code{(!1)+1}.
+
+@findex OR, logisch
+@findex || (logisch OR)
+@item OR
+@itemx ||
+Logisch OR. Gibt @code{1} zurück, wenn eins der Argumente nicht @code{0}
+und nicht @code{NULL} ist:
+@example
+mysql> select 1 || 0;
+ -> 1
+mysql> select 0 || 0;
+ -> 0
+mysql> select 1 || NULL;
+ -> 1
+
+@end example
+
+@findex AND, logisch
+@findex && (logisch AND)
+@item AND
+@itemx &&
+Logisch AND. Gibt @code{0} zurück, wenn eins der Argumente @code{0} oder
+@code{NULL} ist, ansonsten @code{1}:
+@example
+mysql> select 1 && NULL;
+ -> 0
+mysql> select 1 && 0;
+ -> 0
+@end example
+@end table
+
+
+@node Control flow functions, , Logical Operators, Non-typed Operators
+@c German node Ablaufsteuerungsfunktionen
+@subsubsection Ablaufsteuerungsfunktionen
+
+@findex Ablaufsteuerungsfunktionen
+@findex Funktionen, Ablaufsteuerung
+
+@table @code
+@cindex @code{NULL}, testen auf Null
+@findex IFNULL()
+@item IFNULL(ausdruck1,ausdruck2)
+Wenn @code{ausdruck1} nicht @code{NULL} ist, gibt @code{IFNULL()}
+@code{ausdruck1} zurück, ansonsten @code{ausdruck2}. @code{IFNULL()} gibt
+einen numerischen oder einen Zeichenketten-Wert zurück, je nachdem, in
+welchem Zusammenhang es benutzt wird:
+@example
+mysql> select IFNULL(1,0);
+ -> 1
+mysql> select IFNULL(NULL,10);
+ -> 10
+mysql> select IFNULL(1/0,10);
+ -> 10
+mysql> select IFNULL(1/0,'ja');
+ -> 'ja'
+@end example
+
+@findex NULLIF()
+@item NULLIF(ausdruck1,ausdruck2)
+Wenn @code{ausdruck1 = ausdruck2} wahr ist, gibt die Funktion @code{NULL}
+zurück, ansonsten @code{ausdruck1}. Das ist dasselbe wie @code{CASE WHEN x
+= y THEN NULL ELSE x END}:
+@example
+mysql> select NULLIF(1,1);
+ -> NULL
+mysql> select NULLIF(1,2);
+ -> 1
+@end example
+
+Beachten Sie, dass @code{ausdruck1} in MySQL zweimal ausgewertet wird, wenn
+die Argumente gleich sind.
+
+@findex IF()
+@item IF(ausdruck1,ausdruck2,ausdruck3)
+Wenn @code{ausdruck1} TRUE ist (@code{ausdruck1 <> 0} und @code{ausdruck1
+<> NULL}), gibt @code{IF()} @code{ausdruck2} zurück, ansonsten
+@code{ausdruck3}. @code{IF()} gibt einen numerischen oder einen
+Zeichenketten-Wert zurück, je nachdem, in welchem Zusammenhang es benutzt
+wird:
+
+@example
+mysql> select IF(1>2,2,3);
+ -> 3
+mysql> select IF(1<2,'ja','nein');
+ -> 'ja'
+mysql> select IF(strcmp('test','test1'),'nein','ja');
+ -> 'nein'
+@end example
+
+@code{ausdruck1} wird als Ganzzahlwert ausgewertet, woraus folgt, dass Sie
+das Testen auf Fließkomma- oder Zeichenketten-Werte mit einer
+Vergleichsoperation durchführen sollten:
+
+@example
+mysql> select IF(0.1,1,0);
+ -> 0
+mysql> select IF(0.1<>0,1,0);
+ -> 1
+@end example
+
+Im ersten Fall gibt @code{IF(0.1)} @code{0} zurück, weil @code{0.1} in
+einen Ganzzahlwert umgewandelt wird, wodurch es auf @code{IF(0)} getestet
+wird. Das ist vielleicht nicht das, was Sie erwarten. Im zweiten Fall
+testet der Vergleich den Original-Fließkommawert, um zu sehen, ob er nicht
+0 ist. Das Ergebnis des Vergleichs wird als Ganzzahl benutzt.
+
+Der vorgabemäßige Rückgabewert von @code{IF()} (der eine Rolle spielen
+kann, wenn er in einer temporären Tabelle gespeichert wird), wird in
+MySQL-Version 3.23 wie folgt berechnet:
+
+@multitable @columnfractions .55 .45
+@item @strong{Ausdruck} @tab @strong{Rückgabewert}
+@item ausdruck2 oder ausdruck3 gibt Zeichenkette zurück @tab Zeichenkette
+@item ausdruck2 oder ausdruck3 gibt Fließkommawert zurück @tab Fließkommawert
+@item ausdruck2 oder ausdruck3 gibt Ganzzahl zurück @tab Ganzzahl
+@end multitable
+
+@findex CASE
+@item CASE wert WHEN [vergleichs-wert] THEN ergebnis [WHEN [vergleichs-wert] THEN ergebnis ...] [ELSE ergebnis] END
+@item CASE WHEN [bedingung] THEN ergebnis [WHEN [bedingung] THEN ergebnis ...] [ELSE ergebnis] END
+
+Die erste Version gibt @code{ergebnis} zurück, wo
+@code{wert=vergleichs-wert}. Die zweite Version gibt das Ergebnis für die
+erste Bedingung zurück, die WAHR ist. Wenn es keinen übereinstimmenden
+Ergebniswert gab, wird das Ergebnis nach @code{ELSE} zurückgegeben. Wenn es
+keinen @code{ELSE}-Teil gibt, wird @code{NULL} zurückgegeben:
+
+@example
+mysql> SELECT CASE 1 WHEN 1 THEN "eins" WHEN 2 THEN "zwei" ELSE "mehr" END;
+ -> "eins"
+mysql> SELECT CASE WHEN 1>0 THEN "wahr" ELSE "unwahr" END;
+ -> "wahr"
+mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
+ -> NULL
+@end example
+@end table
+
+Der Typ des Rückgabewerts (@code{INTEGER}, @code{DOUBLE} oder
+@code{STRING}) ist derselbe wie der Typ des ersten zurückgegebenen Werts
+(der Ausdruck nach dem ersten @code{THEN}).
+
+
+@node String functions, Numeric Functions, Non-typed Operators, Functions
+@c German node Zeichenketten-Funktionen
+@subsection Zeichenketten-Funktionen
+
+@findex Zeichenketten-Funktionen
+@findex Funktionen, Zeichenketten
+
+Funktionen für Zeichenkettenwerte geben @code{NULL} zurück, wenn die Länge
+des Ergebnisses größer wäre als der
+@code{max_allowed_packet}-Serverparameter. @xref{Server parameters}.
+
+Bei Funktionen, die mit Zeichenkettenpositionen arbeiten, wird die erste
+Position als 1 gezählt.
+
+@table @code
+@findex ASCII()
+@item ASCII(zeichenkette)
+Gibt den ASCII-Code-Wert des äußersten linken Zeichens der Zeichenkette
+@code{zeichenkette} zurück. Gibt @code{0} zurück, wenn @code{zeichenkette}
+die leere Zeichenkette ist. Gibt @code{NULL} zurück, wenn
+@code{zeichenkette} @code{NULL} ist:
+
+@example
+mysql> select ASCII('2');
+ -> 50
+mysql> select ASCII(2);
+ -> 50
+mysql> select ASCII('dx');
+ -> 100
+@end example
+
+Siehe auch @code{ORD()}-Funktion.
+
+@findex ORD()
+@item ORD(zeichenkette)
+Wenn das äußerste linke Zeichen der Zeichenkette @code{zeichenkette} ein
+Multi-Byte-Zeichen ist, gibt diese Funktion den Code des
+Multi-Byte-Zeichens zurück, indem der ASCII-Code-Wert des Zeichens in
+folgendem Format zurückgegeben wird:
+@code{((erstes byte ASCII code)*256+(zweites byte ASCII code))[*256+drittes byte ASCII code...]}.
+Wenn das äußerste linke Zeichen kein Multi-Byte-Zeichen ist, wird derselbe
+Wert wie bei der @code{ASCII()}-Funktion zurückgegeben:
+
+@example
+mysql> select ORD('2');
+ -> 50
+@end example
+
+@findex CONV()
+@item CONV(N,von_basis,zu_basis)
+Wandelt Zahlen zwischen verschiedenen Zahlsystemen um. Gibt eine
+Zeichenkettendarstellung der Zahl @code{N} zurück, umgewandelt von Basis
+@code{von_basis} zu Basis @code{zu_basis}. Gibt @code{NULL} zurück, wenn
+irgend ein Argument @code{NULL} ist. Das Argument @code{N} wird als
+Ganzzahl interpretiert, kann aber als Ganzzahl oder Zeichenkette angegeben
+werden. Die kleinste Basis ist @code{2} und die größte Basis @code{36}.
+Wenn @code{zu_basis} eine negative Zahl ist, wird @code{N} als
+vorzeichenbehaftete Zahl betrachtet. Ansonsten wird @code{N} als
+vorzeichenlos behandelt. @code{CONV} arbeitet mit 64-Bit-Genauigkeit:
+
+@example
+mysql> select CONV("a",16,2);
+ -> '1010'
+mysql> select CONV("6E",18,8);
+ -> '172'
+mysql> select CONV(-17,10,-18);
+ -> '-H'
+mysql> select CONV(10+"10"+'10'+0xa,10,10);
+ -> '40'
+@end example
+
+@findex BIN()
+@item BIN(N)
+Gibt eine Zeichenkettendarstellung des Binärwerts von @code{N} zurück,
+wobei @code{N} eine @code{BIGINT}-Zahl ist. Das ist äquivalent zu
+@code{CONV(N,10,2)}. Gibt @code{NULL} zurück, wenn @code{N} @code{NULL}
+ist:
+
+@example
+mysql> select BIN(12);
+ -> '1100'
+@end example
+
+@findex OCT()
+@item OCT(N)
+Gibt eine Zeichenkettendarstellung des Oktalwerts von @code{N} zurück,
+wobei @code{N} eine @code{BIGINT}-Zahl ist. Das ist äquivalent zu
+@code{CONV(N,10,8)}. Gibt @code{NULL} zurück, wenn @code{N} @code{NULL}
+ist:
+
+@example
+mysql> select OCT(12);
+ -> '14'
+@end example
+
+@findex HEX()
+@item HEX(N)
+Gibt eine Zeichenkettendarstellung des hexadezimalen Werts von @code{N}
+zurück, wobei @code{N} eine @code{BIGINT}-Zahl ist. Das ist äquivalent zu
+@code{CONV(N,10,16)}. Gibt @code{NULL} zurück, wenn @code{N} @code{NULL}
+ist:
+
+@example
+mysql> select HEX(255);
+ -> 'FF'
+@end example
+
+@findex CHAR()
+@item CHAR(N,...)
+@code{CHAR()} interpretiert die Argumente als Ganzzahlen und gibt eine
+Zeichenkette zurück, die aus den Zeichen besteht, die durch die
+ASCII-Code-Werte dieser Ganzzahlen gegeben sind. @code{NULL}-Werte werden
+übersprungen:
+
+@example
+mysql> select CHAR(77,121,83,81,'76');
+ -> 'MySQL'
+mysql> select CHAR(77,77.3,'77.3');
+ -> 'MMM'
+@end example
+
+@findex CONCAT()
+@item CONCAT(zeichenkette1,zeichenkette2,...)
+Gibt die Zeichenkette zurück, die durch die Verkettung der Argumente
+entsteht. Gibt @code{NULL} zurück, wenn irgend ein Argument @code{NULL}
+ist. Kann mehr als 2 Argumente haben. Ein numerisches Argument wird in die
+äquivalente Zeichenkettenform umgewandelt:
+
+@example
+mysql> select CONCAT('My', 'S', 'QL');
+ -> 'MySQL'
+mysql> select CONCAT('My', NULL, 'QL');
+ -> NULL
+mysql> select CONCAT(14.3);
+ -> '14.3'
+@end example
+
+@findex CONCAT_WS()
+@item CONCAT_WS(trennzeichen, zeichenkette1, zeichenkette2,...)
+
+@code{CONCAT_WS()} steht für CONCAT mit Trennzeichen und ist eine spezielle
+Form von @code{CONCAT()}. Das erste Argument ist das Trennzeichen für die
+restlichen Argumente. Das Trennzeichen kann eine Zeichenkette sein, so wie
+die übrigen Argumente. Wenn das Trennzeichen @code{NULL} ist, ist das
+Ergebnis @code{NULL}. Die Funktion überspringt jegliche @code{NULL}s und
+leere Zeichenketten nach dem Trennzeichen-Argument. Das Trennzeichen wird
+zwischen den zu verknüpfenden Zeichenketten hinzugefügt:
+
+@example
+mysql> select CONCAT_WS(",","Vorname","Zweiter Vorname","Nachname");
+ -> 'Vorname,Zweiter Vorname,Nachname'
+mysql> select CONCAT_WS(",","Vorname",NULL,"Nachname");
+ -> 'Vorname,Nachname'
+@end example
+
+@findex LENGTH()
+@findex OCTET_LENGTH()
+@findex CHAR_LENGTH()
+@findex CHARACTER_LENGTH()
+@item LENGTH(zeichenkette)
+@itemx OCTET_LENGTH(zeichenkette)
+@itemx CHAR_LENGTH(zeichenkette)
+@itemx CHARACTER_LENGTH(zeichenkette)
+Gibt die Länge der Zeichenkette @code{zeichenkette} an:
+
+@example
+mysql> select LENGTH('text');
+ -> 4
+mysql> select OCTET_LENGTH('text');
+ -> 4
+@end example
+
+Beachten Sie, dass bei @code{CHAR_LENGTH()} Multi-Byte-Zeichen nur einmal
+gezählt werden.
+
+@findex LOCATE()
+@findex POSITION()
+@item LOCATE(teilzeichenfolge,zeichenkette)
+@itemx POSITION(teilzeichenfolge IN zeichenkette)
+Gibt die Position des ersten Auftretens der Teilzeichenfolge
+@code{teilzeichenfolge} in der Zeichenkette @code{zeichenkette} an. Gibt
+@code{0} zurück, wenn @code{teilzeichenfolge} nicht in @code{zeichenkette}
+enthalten ist:
+
+@example
+mysql> select LOCATE('bar', 'foobarbar');
+ -> 4
+mysql> select LOCATE('xbar', 'foobar');
+ -> 0
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex LOCATE()
+@item LOCATE(teilzeichenfolge,zeichenkette,position)
+Gibt die Position des ersten Auftretens der Teilzeichenfolge
+@code{teilzeichenfolge} in der Zeichenkette @code{zeichenkette} ab Position
+@code{position} an. Gibt @code{0} zurück, wenn @code{teilzeichenfolge}
+nicht in @code{zeichenkette} enthalten ist:
+
+@example
+mysql> select LOCATE('bar', 'foobarbar',5);
+ -> 7
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex INSTR()
+@item INSTR(zeichenkette,teilzeichenfolge)
+Gibt die Position des ersten Auftretens der Teilzeichenfolge
+@code{teilzeichenfolge} in der Zeichenkette @code{zeichenkette} an. Das ist
+dasselbe wie @code{LOCATE()} mit zwei Argumenten, ausser dass die Argumente
+vertauscht sind:
+
+@example
+mysql> select INSTR('foobarbar', 'bar');
+ -> 4
+mysql> select INSTR('xbar', 'foobar');
+ -> 0
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex LPAD()
+@item LPAD(zeichenkette,laenge,fuellzeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, links aufgefüllt mit der
+Zeichenkette @code{fuellzeichenkette}, bis @code{zeichenkette}
+@code{laenge} Zeichen lang ist. Wenn @code{zeichenkette} länger als
+@code{laenge} ist, wird sie auf @code{laenge} Zeichen verkürzt.
+
+@example
+mysql> select LPAD('hi',4,'??');
+ -> '??hi'
+@end example
+
+@findex RPAD()
+@item RPAD(zeichenkette,laenge,fuellzeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, rechts aufgefüllt mit der
+Zeichenkette @code{fuellzeichenkette}, bis @code{zeichenkette}
+@code{laenge} Zeichen lang ist. Wenn @code{zeichenkette} länger als
+@code{laenge} ist, wird sie auf @code{laenge} Zeichen verkürzt.
+
+@example
+mysql> select RPAD('hi',5,'?');
+ -> 'hi???'
+@end example
+
+@findex LEFT()
+@item LEFT(zeichenkette,laenge)
+Gibt die äußersten linken @code{laenge} Zeichen der Zeichenkette
+@code{zeichenkette} zurück:
+
+@example
+mysql> select LEFT('foobarbar', 5);
+ -> 'fooba'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex RIGHT()
+@item RIGHT(zeichenkette,laenge)
+Gibt die äußersten rechten @code{laenge} Zeichen der Zeichenkette
+@code{zeichenkette} zurück:
+
+@example
+mysql> select RIGHT('foobarbar', 4);
+ -> 'rbar'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex SUBSTRING()
+@findex MID()
+@item SUBSTRING(zeichenkette,position,laenge)
+@itemx SUBSTRING(zeichenkette FROM position FOR laenge)
+@itemx MID(zeichenkette,position,laenge)
+Gibt eine @code{laenge} Zeichen lange Teilzeichenfolge der Zeichenkette
+@code{zeichenkette} ab Position @code{position} zurück. Die abweichende
+Form, die @code{FROM} benutzt, ist ANSI-SQL92-Syntax:
+
+@example
+mysql> select SUBSTRING('Heinzholger',5,6);
+ -> 'zholge'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex SUBSTRING()
+@item SUBSTRING(zeichenkette,position)
+@item SUBSTRING(zeichenkette FROM position)
+Gibt eine Teilzeichenfolge der Zeichenkette @code{zeichenkette} ab Position
+@code{position} zurück:
+
+@example
+mysql> select SUBSTRING('Heinzholger',5);
+ -> 'zholger'
+mysql> select SUBSTRING('foobarbar' FROM 4);
+ -> 'barbar'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex SUBSTRING_INDEX()
+@item SUBSTRING_INDEX(zeichenkette,begrenzer,zaehler)
+Gibt die Teilzeichenfolge von Zeichenkette @code{zeichenkette} vor
+@code{zaehler} Vorkommen des Begrenzers @code{begrenzer} zurück. Wenn
+@code{zaehler} positiv ist, wird alle links vom letzten Begrenzer
+zurückgegeben (von links gezählt). Wenn @code{zaehler} negativ ist, wird
+alles rechts vom letzten Begrenzer (von rechts gezählt) zurückgegeben:
+
+@example
+mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
+ -> 'www.mysql'
+mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
+ -> 'mysql.com'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex LTRIM()
+@item LTRIM(zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, bei der führende
+Leerzeichen entfernt wurden:
+
+@example
+mysql> select LTRIM(' barbar');
+ -> 'barbar'
+@end example
+
+@findex RTRIM()
+@item RTRIM(zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, bei der Leerzeichen am
+Ende entfernt wurden:
+
+@example
+mysql> select RTRIM('barbar ');
+ -> 'barbar'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex TRIM()
+@item TRIM([[BOTH | LEADING | TRAILING] [entfernzeichenkette] FROM] zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle
+@code{entfernzeichenkette}-Präfixe und / oder -Suffixe entfernt wurden.
+Wenn keiner der Spezifizierer @code{BOTH}, @code{LEADING} oder
+@code{TRAILING} angegeben wird, wird @code{BOTH} angenommen. Wenn
+@code{entfernzeichenkette} nicht angegeben ist, werden Leerzeichen entfernt:
+
+@example
+mysql> select TRIM(' bar ');
+ -> 'bar'
+mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
+ -> 'barxxx'
+mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
+ -> 'bar'
+mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
+ -> 'barx'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex SOUNDEX()
+@item SOUNDEX(zeichenkette)
+Gibt eine Soundex-Zeichenkette von @code{zeichenkette} zurück. Zwei
+Zeichenketten, die fast gleich klingen, sollten identische
+Soundex-Zeichenketten haben. Eine Standard-Soundex-Zeichenkette ist 4
+Zeichen lang, aber die @code{SOUNDEX()}-Funktion gibt eine beliebig lange
+Zeichenkette zurück. Sie können @code{SUBSTRING()} auf das Ergebnis
+anwenden, um eine Standard-Soundex-Zeichenkette zu erhalten. Alle nicht
+alphanumerischen Zeichen in der angegebenen Zeichenkette werden ignoriert.
+Alle internationalen alphabetischen Zeichen ausserhalb des Wertebereichs A
+bis Z werden als Vokale behandelt:
+
+@example
+mysql> select SOUNDEX('Hello');
+ -> 'H400'
+mysql> select SOUNDEX('Quadratically');
+ -> 'Q36324'
+@end example
+
+@findex SPACE()
+@item SPACE(N)
+Gibt eine Zeichenkette zurück, die aus @code{N} Leerzeichen besteht:
+
+@example
+mysql> select SPACE(6);
+ -> ' '
+@end example
+
+@findex REPLACE()
+@item REPLACE(zeichenkette,von_zeichenkette,zu_zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle Vorkommen
+der Zeichenkette @code{von_zeichenkette} durch die Zeichenkette
+@code{zu_zeichenkette} ersetzt wurden:
+
+@example
+mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
+ -> 'WwWwWw.mysql.com'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex REPEAT()
+@item REPEAT(zeichenkette,zaehler)
+Gibt eine Zeichenkette zurück, die aus der Zeichenkette @code{zeichenkette}
+besteht, die @code{zaehler} mal wiederholt wurde. Wenn @code{zaehler <= 0}
+ist, wird eine leere Zeichenkette zurückgegeben. Gibt @code{NULL} zurück,
+wenn @code{zeichenkette} oder @code{zaehler} @code{NULL} sind:
+
+@example
+mysql> select REPEAT('MySQL', 3);
+ -> 'MySQLMySQLMySQL'
+@end example
+
+@findex REVERSE()
+@item REVERSE(zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} in umgedrehter Reihenfolge der
+Zeichen zurück:
+
+@example
+mysql> select REVERSE('abc');
+ -> 'cba'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex INSERT()
+@item INSERT(zeichenkette,position,laenge,neue_zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, wobei eine
+Teilzeichenfolge ab Position @code{position} mit @code{laenge} Zeichen
+Länge durch die Zeichenkette @code{neue_zeichenkette} ersetzt wurde:
+
+@example
+mysql> select INSERT('Heinzholger', 6, 4, 'DIET');
+ -> 'HeinzDIETer'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex ELT()
+@item ELT(N,zeichenkette1,zeichenkette2,zeichenkette3,...)
+Gibt @code{zeichenkette1} zurück, wenn @code{N} = @code{1} ist,
+@code{zeichenkette2}, wenn @code{N} = @code{2} ist usw.. Gibt @code{NULL}
+zurück, wenn @code{N} kleiner als @code{1} oder größer als die Anzahl von
+Argumenten ist. @code{ELT()} ist das Komplement von @code{FIELD()}:
+
+@example
+mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
+ -> 'ej'
+mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
+ -> 'foo'
+@end example
+
+@findex FIELD()
+@item FIELD(zeichenkette,zeichenkette1,zeichenkette2,zeichenkette3,...)
+Gibt den Index von @code{zeichenkette} in der Liste @code{zeichenkette1},
+@code{zeichenkette2}, @code{zeichenkette3}, @code{...} zurück. Gibt
+@code{0} zurück, wenn @code{zeichenkette} nicht gefunden wird.
+@code{FIELD()} ist das Komplement von @code{ELT()}:
+
+@example
+mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
+ -> 2
+mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
+ -> 0
+@end example
+
+@findex FIND_IN_SET()
+@item FIND_IN_SET(zeichenkette,zeichenkettenliste)
+Gibt einen Wert @code{1} bis @code{N} zurück, wenn die Zeichenkette
+@code{zeichenkette} in der Liste @code{zeichenkettenliste} ist, die aus
+@code{N} Teilzeichenfolgen besteht. Eine Zeichenkettenliste ist eine
+Zeichenkette, die aus Teilzeichenfolgen zusammen gesetzt ist, die durch
+@samp{,}-Zeichen getrennt sind. Wenn das erste Argument eine
+Zeichenketten-Konstante ist und das zweite eine Spalte des Typs @code{SET},
+wird die @code{FIND_IN_SET()}-Funktion optimiert, Bit-Arithmetik zu
+benutzen! Gibt @code{0} zurück, wenn @code{zeichenkette} nicht in
+@code{zeichenkettenliste} ist oder wenn @code{zeichenkettenliste} die leere
+Zeichenkette ist. Gibt @code{NULL} zurück, wenn eines oder beide Argumente
+@code{NULL} sind. Diese Funktion funktioniert nicht korrekt, wenn das erste
+Argument ein @samp{,} enthält:
+
+@example
+mysql> SELECT FIND_IN_SET('b','a,b,c,d');
+ -> 2
+@end example
+
+@findex MAKE_SET()
+@item MAKE_SET(bits,zeichenkette1,zeichenkette2,...)
+Gibt einen Satz (eine Zeichenkette, die Teilzeichenfolgen enthält, die
+durch @samp{,} getrennt sind) zurück, der aus Zeichenketten besteht, die
+das entsprechende Bit in @code{bits} gesetzt haben. @code{zeichenkette1}
+entspricht Bit 0, @code{zeichenkette2} Bit 1 usw. @code{NULL}-Zeichenketten
+in @code{zeichenkette1}, @code{zeichenkette2} usw. werden nicht an das
+Ergebnis angehängt:
+
+@example
+mysql> SELECT MAKE_SET(1,'a','b','c');
+ -> 'a'
+mysql> SELECT MAKE_SET(1 | 4,'hallo','liebe','welt');
+ -> 'hallo,welt'
+mysql> SELECT MAKE_SET(0,'a','b','c');
+ -> ''
+@end example
+
+@findex EXPORT_SET()
+@item EXPORT_SET(bits,an,aus,[trennzeichen,[anzahl_bits]])
+Gibt eine Zeichenkette zurück, in der Sie für jedes bit, das in 'bit'
+gesetzt ist, eine 'an'-Zeichenkette erhalten, und für jedes zurückgesetzte
+Bit eine 'aus'-Zeichenkette. Jede Zeichenkette wird mit 'trennzeichen'
+getrennt (vorgabemäßig ','), und nur die 'anzahl_bits' (vorgabemäßig 64)
+von 'bits' wird benutzt:
+
+@example
+mysql> select EXPORT_SET(5,'Y','N',',',4)
+ -> Y,N,Y,N
+@end example
+
+@findex LCASE()
+@findex LOWER()
+@item LCASE(zeichenkette)
+@itemx LOWER(zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle Zeichen in
+Kleinschreibung gemäß dem aktuellen Zeichensatz-Mapping (Vorgabe ist
+ISO-8859-1 Latin1) umgewandelt wurden:
+
+@example
+mysql> select LCASE('HEINZholger');
+ -> 'heinzholger'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex UCASE()
+@findex UPPER()
+@item UCASE(zeichenkette)
+@itemx UPPER(zeichenkette)
+Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle Zeichen in
+Großschreibung gemäß dem aktuellen Zeichensatz-Mapping (Vorgabe ist
+ISO-8859-1 Latin1) umgewandelt wurden:
+
+@example
+mysql> select UCASE('Hej');
+ -> 'HEJ'
+@end example
+
+Diese Funktion ist Multi-Byte-sicher.
+
+@findex FILE
+@findex LOAD_FILE()
+@item LOAD_FILE(datei)
+Liest die Datei @code{datei} und gibt den Dateiinhalt als Zeichenkette
+zurück. Die Datei muss auf dem Server sein, Sie müssen den vollen Pfadnamen
+zur Datei angeben und Sie müssen die @strong{file}-Berechtigung besitzen.
+Die Datei muss von allen lesbar sein und kleiner als
+@code{max_allowed_packet}.
+
+Wenn die Datei nicht existiert oder aus den oben genannten Gründen nicht
+gelesen werden kann, gibt die Funktion @code{NULL} zurück:
+
+@example
+mysql> UPDATE tabelle
+ SET blob_spalte=LOAD_FILE("/tmp/bild")
+ WHERE id=1;
+@end example
+@end table
+
+Wenn Sie nicht MySQL-Version 3.23 benutzen, müssen Sie das Lesen der Datei
+innerhalb Ihrer Applikation durchführen und ein @code{INSERT}-Statement
+erzeugen, um die Datenbank mit der Dateiinformation zu aktualisieren. Eine
+Art, das zu tun, finden Sie - wenn Sie die MySQL++-Bibliothek benutzen -
+unter
+@uref{http://www.mysql.com/documentation/mysql++/mysql++-examples.html}.
+
+MySQL konvertiert Zahlen bei Bedarf automatisch in Zeichenketten, und
+umgekehrt:
+
+@example
+mysql> SELECT 1+"1";
+ -> 2
+mysql> SELECT CONCAT(2,' test');
+ -> '2 test'
+@end example
+
+Wenn Sie eine Zahl explizit in eine Zeichenkette umwandeln wollen,
+übergeben Sie sie als Argument an @code{CONCAT()}.
+
+Wenn in einer Zeichenketten-Funktion eine binäre Zeichenkette als Argument
+angegeben wird, ist die resultierende Zeichenkette ebenfalls eine binäre
+Zeichenkette. Eine Zahl, die in eine Zeichenkette umgewandelt wird, wird
+als binäre Zeichenkette behandelt. Das betrifft nur Vergleichsoperationen.
+
+
+
+@menu
+* String comparison functions::
+* Case Sensitivity Operators::
+@end menu
+
+@node String comparison functions, Case Sensitivity Operators, String functions, String functions
+@c German node Zeichenketten-Vergleichsfunktionen
+@subsubsection Zeichenketten-Vergleichsfunktionen
+
+@findex Zeichenketten-Vergleichsfunktionen
+@findex Funktionen, Zeichenketten-Vergleich
+
+@cindex Groß-/Kleinschreibung, in Zeichenketten-Vergleichen
+@cindex Zeichenketten-Vergleiche, Groß-/Kleinschreibung
+
+Normalerweise wird ein Vergleich unter Berücksichtigung der
+Groß-/Kleinschreibung durchgeführt, wenn irgend ein Ausdruck in einem
+Zeichenkettenvergleich abhängig von der verwendeten Groß-/Kleinschreibung
+ist.
+
+@table @code
+@findex LIKE
+@item ausdruck LIKE muster [ESCAPE 'fluchtzeichen']
+Mustervergleich, der den einfachen SQL-Vergleich mit regulären Ausdrücken
+benutzt. Gibt @code{1} (TRUE) oder @code{0} (FALSE) zurück. Bei @code{LIKE}
+können Sie die folgenden zwei Platzhalterzeichen im Muster benutzen:
+
+@multitable @columnfractions .1 .9
+@item @code{%} @tab Entspricht einer beliebigen Anzahl von Zeichen, selbst 0 Zeichen
+@item @code{_} @tab Entspricht genau einem Zeichen
+@end multitable
+
+@example
+mysql> select 'David!' LIKE 'David_';
+ -> 1
+mysql> select 'David!' LIKE '%D%v%';
+ -> 1
+@end example
+
+Um auf literale Instanzen des Platzhalterzeichens zu testen, stellen Sie
+dem Zeichen ein Fluchtzeichen (Escape-Zeichen) voran. Wenn Sie das
+@code{ESCAPE}-Zeichen nicht angeben, wird @samp{\} angenommen:
+
+@multitable @columnfractions .1 .9
+@item @code{\%} @tab Entspricht einem @code{%}-Zeichen
+@item @code{\_} @tab Entspricht einem @code{_}-Zeichen
+@end multitable
+
+@example
+mysql> select 'David!' LIKE 'David\_';
+ -> 0
+mysql> select 'David_' LIKE 'David\_';
+ -> 1
+@end example
+
+Um ein anderes Fluchtzeichen (Escape-Zeichen) anzugeben, benutzen Sie die
+@code{ESCAPE}-Klausel:
+
+@example
+mysql> select 'David_' LIKE 'David|_' ESCAPE '|';
+ -> 1
+@end example
+
+Die folgenden beiden Statements zeigen, dass Zeichenketten-Vergleiche die
+Groß-/Kleinschreibung nicht berücksichtigen, solange nicht einer der
+Operanden eine binäre Zeichenkette ist:
+case insensitive unless one of the operands ist a binäre Zeichenkette:
+
+@example
+mysql> select 'abc' LIKE 'ABC';
+ -> 1
+mysql> SELECT 'abc' LIKE BINARY 'ABC';
+ -> 0
+@end example
+
+@code{LIKE} ist bei numerischen Ausdrücken zulässig! (Das ist eine
+MySQL-Erweiterung zum ANSI-SQL-@code{LIKE}.)
+
+@example
+mysql> select 10 LIKE '1%';
+ -> 1
+@end example
+
+HINWEIS: Weil MySQL die C Escape-Syntax in Zeichenketten benutzt
+(beispielsweise @samp{\n}), müssen Sie jedes @samp{\}-Zeichen, das Sie in
+@code{LIKE}-Zeichenketten benutzen, verdoppeln. Um zum Beispiel nach
+@samp{\n} zu suchen, geben Sie @samp{\\n} ein. Um nach @samp{\} zu suchen,
+geben Sie @samp{\\\\} ein (die Backslashes werden einmal vom Parser
+entfernt und noch einmal, wenn der Mustervergleich durchgeführt wird, so
+dass letztlich ein einzelner Backslash übrig bleibt).
+
+@findex NOT LIKE
+@item ausdruck NOT LIKE muster [ESCAPE 'fluchtzeichen']
+Dasselbe wie @code{NOT (ausdruck LIKE muster [ESCAPE 'fluchtzeichen'])}.
+
+@cindex mSQL-Kompatibilität
+@cindex Kompatibilität, mit mSQL
+@findex REGEXP
+@findex RLIKE
+@item ausdruck REGEXP muster
+@itemx ausdruck RLIKE muster
+Führt einen Mustervergleich eines Zeichenkettenausdrucks @code{ausdruck}
+gegen ein Muster @code{muster} durch. Das Muster kann ein erweiterter
+regulärer Ausdruck sein. @xref{Regexp}. Gibt @code{1} zurück, wenn
+@code{ausdruck} mit @code{muster} übereinstimmt, ansonsten @code{0}.
+@code{RLIKE} ist ein Synonym für @code{REGEXP}, was aus Gründen der
+@code{mSQL}-Kompatibilität zur Verfügung steht. HINWEIS: Weil MySQL die
+C-Escape-Syntax in Zeichenketten benutzt (beispielsweise @samp{\n}), müssen
+Sie jeden @samp{\}, den Sie in Ihren @code{REGEXP}-Zeichenketten benutzen,
+verdoppeln. Ab MySQL-Version 3.23.4 berücksichtigt @code{REGEXP} nicht die
+verwendete Groß-/Kleinschreibung für normale (nicht binäre)
+Zeichenketten:
+
+@example
+mysql> select 'Monty!' REGEXP 'm%y%%';
+ -> 0
+mysql> select 'Monty!' REGEXP '.*';
+ -> 1
+mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line';
+ -> 1
+mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A";
+ -> 1 0
+mysql> select "a" REGEXP "^[a-d]";
+ -> 1
+@end example
+
+@item
+@code{REGEXP} und @code{RLIKE} benutzen den aktuellen Zeichensatz
+(vorgabemäßig ISO-8859-1 Latin1), wenn über den Typ eines Zeichens
+entschieden wird.
+
+@findex NOT REGEXP
+@item ausdruck NOT REGEXP muster
+@itemx ausdruck NOT RLIKE muster
+Dasselbe wie @code{NOT (ausdruck REGEXP muster)}.
+
+@findex STRCMP()
+@item STRCMP(ausdruck1,ausdruck2)
+@code{STRCMP()} gibt @code{0} zurück, wenn die Zeichenketten gleich sind,
+@code{-1}, wenn das erste Argument kleiner als das zweite ist (nach der
+aktuellen Sortierreihenfolge), und ansonsten @code{1}:
+
+@example
+mysql> select STRCMP('text', 'text2');
+ -> -1
+mysql> select STRCMP('text2', 'text');
+ -> 1
+mysql> select STRCMP('text', 'text');
+ -> 0
+@end example
+
+@findex MATCH ... AGAINST()
+@item MATCH (spalte1,spalte2,...) AGAINST (ausdruck)
+@code{MATCH ... AGAINST()} wird für Volltextsuche benutzt und gibt die
+Relevanz zurück - ein Ähnlichkeitsmaß zwischen dem Text in den Spalten
+@code{(spalte1,spalte2,...)} und der Anfrage @code{ausdruck}. Die Relevanz
+ist eine positive Fließkommazahl. 0 Relevanz bedeutet keine Ähnlichkeit.
+Damit @code{MATCH ... AGAINST()} funktioniert, muss zuerst ein
+@strong{FULLTEXT}-Index erzeugt werden. @xref{CREATE TABLE, , @code{CREATE TABLE}}. @code{MATCH ... AGAINST()} ist verfügbar ab MySQL-Version 3.23.23.
+Für Details und Benutzungsbeispiele siehe @pxref{Fulltext Search}.
+@end table
+
+
+@node Case Sensitivity Operators, , String comparison functions, String functions
+@c German node Operatoren und Groß-/Kleinschreibung
+@subsubsection Groß-/Kleinschreibung
+
+@findex Casts
+
+@cindex Cast-Operatoren
+@cindex Operatoren, Cast-
+
+@table @code
+@findex BINARY
+@item @code{BINARY}
+Der @code{BINARY}-Operator macht die folgende Zeichenkette zu einer binären
+Zeichenkette. Das ist eine einfache Möglichkeit, einen Spaltenvergleich
+zwangsweise in Abhängigkeit von der verwendeten Groß-/Kleinschreibung
+durchzuführen, selbst wenn die Spalte nicht als @code{BINARY} oder
+@code{BLOB} definiert ist:
+@example
+mysql> select "a" = "A";
+ -> 1
+mysql> select BINARY "a" = "A";
+ -> 0
+@end example
+
+@code{BINARY} wurde in MySQL-Version 3.23.0 eingeführt.
+
+Beachten Sie, dass MySQL in manchen Fällen nicht in der Lage ist, den Index
+effizient zu benutzen, wenn Sie eine indizierte Spalte zu @code{BINARY}
+machen.
+@end table
+
+Wenn Sie ein Blob ohne Berücksichtigung der Groß-/Kleinschreibung
+vergleichen wollen, können Sie den Blob jederzeit in Großschreibung
+umwandeln, bevor Sie den Vergleich durchführen:
+
+@example
+SELECT 'A' LIKE UPPER(blob_spalte) FROM tabelle;
+@end example
+
+Wir planen, bald Casting zwischen unterschiedlichen Zeichensätzen
+einzuführen, um Zeichenketten-Vergleiche noch flexibler zu machen.
+
+
+@node Numeric Functions, Date and time functions, String functions, Functions
+@c German node Numerische Funktionen
+@subsection Numerische Funktionen
+
+
+
+@menu
+* Arithmetic functions::
+* Mathematical functions::
+@end menu
+
+@node Arithmetic functions, Mathematical functions, Numeric Functions, Numeric Functions
+@c German node Arithmetische Funktionen
+@subsubsection Arithmetische Operationen
+
+Es gibt die üblichen arithmetischen Operatoren. Beachten Sie, dass das
+Ergebnis im Falle von @samp{-}, @samp{+} und @samp{*} mit
+@code{BIGINT}-Genauigkeit (64-Bit) berechnet wird, wenn beide Argumente
+Ganzzahlen sind!
+
+@cindex Operationen, arithmetische
+@cindex arithmetische Ausdrücke
+@table @code
+@findex + (Addition)
+@findex Addition (+)
+@item +
+Addition:
+@example
+mysql> select 3+5;
+ -> 8
+@end example
+
+@findex - (Subtraktion)
+@findex Subtraktion (-)
+@item -
+Subtraktion:
+@example
+mysql> select 3-5;
+ -> -2
+@end example
+
+@findex * (Multiplikation)
+@findex Multiplikation (*)
+@item *
+Multiplication:
+@example
+mysql> select 3*5;
+ -> 15
+mysql> select 18014398509481984*18014398509481984.0;
+ -> 324518553658426726783156020576256.0
+mysql> select 18014398509481984*18014398509481984;
+ -> 0
+@end example
+
+Das Ergebnis des letzten Ausdrucks ist falsch, weil die
+Ganzzahl-Multiplikation den 64-Bit-Wertebereich von
+@code{BIGINT}-Berechnungen überschreitet.
+
+@findex / (Division)
+@findex Division (/)
+@item /
+Division:
+@example
+mysql> select 3/5;
+ -> 0.60
+@end example
+
+Division durch 0 erzeugt ein @code{NULL}-Ergebnis:
+
+@example
+mysql> select 102/(1-1);
+ -> NULL
+@end example
+
+Eine Division wird nur dann mit @code{BIGINT}-Arithmetik berechnet, wenn
+sie in einem Zusammenhang durchgeführt wird, in dem das Ergebnis in eine
+Ganzzahl umgewandelt wird!
+@end table
+
+
+@node Mathematical functions, , Arithmetic functions, Numeric Functions
+@c German node Mathematische Funktionen
+@subsubsection Mathematische Funktionen
+Alle mathematischen Funktionen geben im Fehlerfall @code{NULL} zurück.
+
+@findex mathematische Funktionen
+@findex Funktionen, mathematische
+
+@table @code
+@findex - (unäres Minus)
+@findex Minus, unäres (-)
+@findex unäres Minus (-)
+@item -
+Unäres Minus. Ändert das Vorzeichen des Arguments:
+@example
+mysql> select - 2;
+ -> -2
+@end example
+
+Wenn dieser Operator mit einer @code{BIGINT} benutzt wird, beachten Sie,
+dass der Rückgabewert eine @code{BIGINT} ist! Das bedeutet, dass Sie
+@code{-} auf Ganzzahlen, die den Wert @code{-2^63} haben könnten, vermeiden
+sollten!
+
+@findex ABS()
+@item ABS(X)
+Gibt den absoluten Wert von @code{X} zurück:
+@example
+mysql> select ABS(2);
+ -> 2
+mysql> select ABS(-32);
+ -> 32
+@end example
+
+Diese Funktion kann bei @code{BIGINT}-Werten sicher benutzt werden.
+
+@findex SIGN()
+@item SIGN(X)
+Gibt das Vorzeichen des Arguments als @code{-1}, @code{0} oder @code{1}
+zurück, abhängig davon, ob @code{X} negativ, 0 oder positiv ist:
+@example
+mysql> select SIGN(-32);
+ -> -1
+mysql> select SIGN(0);
+ -> 0
+mysql> select SIGN(234);
+ -> 1
+@end example
+
+@findex MOD()
+@c German FIX added space before %
+@findex % (Modulo)
+@findex Modulo (%)
+@item MOD(N,M)
+@c German FIX added space before %
+@itemx %
+Modulo (wie der @code{%}-Operator in C). Gibt den Rest von @code{N}
+dividiert durch @code{M} zurück:
+@example
+mysql> select MOD(234, 10);
+ -> 4
+mysql> select 253% 7;
+ -> 1
+mysql> select MOD(29,9);
+ -> 2
+@end example
+
+Diese Funktion kann bei @code{BIGINT}-Werten sicher benutzt werden.
+
+@findex FLOOR()
+@item FLOOR(X)
+Gibt den größten Ganzzahl-Wert zurück, der nicht größer als @code{X}
+ist:
+@example
+mysql> select FLOOR(1.23);
+ -> 1
+mysql> select FLOOR(-1.23);
+ -> -2
+@end example
+
+Beachten Sie, dass der Rückgabewert in eine @code{BIGINT} umgewandelt
+wird!
+
+@findex CEILING()
+@item CEILING(X)
+Gibt den kleinsten Ganzzahl-Wert zurück, der nicht kleiner als @code{X}
+ist:
+@example
+mysql> select CEILING(1.23);
+ -> 2
+mysql> select CEILING(-1.23);
+ -> -1
+@end example
+
+Beachten Sie, dass der Rückgabewert in eine @code{BIGINT} umgewandelt wird!
+
+@findex ROUND()
+@item ROUND(X)
+Gibt das Argument @code{X} zurück, gerundet auf die nächste Ganzzahl:
+@example
+mysql> select ROUND(-1.23);
+ -> -1
+mysql> select ROUND(-1.58);
+ -> -2
+mysql> select ROUND(1.58);
+ -> 2
+@end example
+
+Beachten Sie, dass das Verhalten von @code{ROUND()} abhängig von der
+C-Bibliothek-Implementation ist, wenn das Argument in der Mitte zwischen
+zwei Ganzzahlen liegt. Einige runden auf die nächste gerade Zahl, oder
+immer nach oben, immer nach unten oder immer Richtung 0. Wenn Sie eine
+bestimmte Art zu runden brauchen, sollten Sie statt dessen wohldefinierte
+Funktionen wie @code{TRUNCATE()} oder @code{FLOOR()} benutzen.
+
+@findex ROUND()
+@item ROUND(X,D)
+Gibt das Argument @code{X} zurück, gerundet auf eine Zahl mit @code{D}
+Dezimalstellen. Wenn @code{D} @code{0} ist, hat das Ergebnis keinen
+Dezimalpunkt oder Bruchteil:
+
+@example
+mysql> select ROUND(1.298, 1);
+ -> 1.3
+mysql> select ROUND(1.298, 0);
+ -> 1
+@end example
+
+@findex EXP()
+@item EXP(X)
+Gibt den Wert @code{e} (die Basis des natürlichen Logarithmus) hoch
+@code{X} zurück:
+@example
+mysql> select EXP(2);
+ -> 7.389056
+mysql> select EXP(-2);
+ -> 0.135335
+@end example
+@findex LOG()
+@item LOG(X)
+Gibt den natürlichen Logarithmus von @code{X} zurück:
+@example
+mysql> select LOG(2);
+ -> 0.693147
+mysql> select LOG(-2);
+ -> NULL
+@end example
+Wenn Sie den Logarithmus einer Zahl @code{X} zu einer beliebigen Basis
+@code{B} errechnen wollen, benutzen Sie die Formel @code{LOG(X)/LOG(B)}.
+
+@findex LOG10()
+@item LOG10(X)
+Gibt den Logarithmus zur Basis 10 von @code{X} zurück:
+@example
+mysql> select LOG10(2);
+ -> 0.301030
+mysql> select LOG10(100);
+ -> 2.000000
+mysql> select LOG10(-100);
+ -> NULL
+@end example
+
+@findex POW()
+@findex POWER()
+@item POW(X,Y)
+@itemx POWER(X,Y)
+Gibt den Wert @code{X} hoch @code{Y} zurück:
+@example
+mysql> select POW(2,2);
+ -> 4.000000
+mysql> select POW(2,-2);
+ -> 0.250000
+@end example
+
+@findex SQRT()
+@item SQRT(X)
+Gibt die nicht negative Quadratwurzel von @code{X} zurück:
+@example
+mysql> select SQRT(4);
+ -> 2.000000
+mysql> select SQRT(20);
+ -> 4.472136
+@end example
+
+@findex PI()
+@item PI()
+Gibt den Wert PI zurück. Die vorgabemäßig angezeigte Anzahl von
+Dezimalstellen ist 5, aber MySQL benutzt intern die volle doppelte
+Genauigkeit für PI.
+@example
+mysql> select PI();
+ -> 3.141593
+mysql> SELECT PI()+0.000000000000000000;
+ -> 3.141592653589793116
+@end example
+
+@findex COS()
+@item COS(X)
+Gibt den Cosinus von @code{X} zurück, wobei @code{X} in Radianten angegeben
+wird:
+@example
+mysql> select COS(PI());
+ -> -1.000000
+@end example
+
+@findex SIN()
+@item SIN(X)
+Gibt den Sinus von @code{X} zurück, wobei @code{X} in Radianten angegeben
+wird:
+@example
+mysql> select SIN(PI());
+ -> 0.000000
+@end example
+
+@findex TAN()
+@item TAN(X)
+Gibt den Tangens von @code{X} zurück, wobei @code{X} in Radianten angegeben
+wird:
+@example
+mysql> select TAN(PI()+1);
+ -> 1.557408
+@end example
+
+@findex ACOS()
+@item ACOS(X)
+Gibt den Arcuscosinus von @code{X} zurück, dass heißt den Wert, dessen
+Cosinus @code{X} ist. Gibt @code{NULL} zurück, wenn @code{X} nicht im
+Bereich von @code{-1} bis @code{1} liegt:
+@example
+mysql> select ACOS(1);
+ -> 0.000000
+mysql> select ACOS(1.0001);
+ -> NULL
+mysql> select ACOS(0);
+ -> 1.570796
+@end example
+
+@findex ASIN()
+@item ASIN(X)
+Gibt den Arcussinus von @code{X} zurück, das heißt den Wert, dessen Sinus
+@code{X} ist. Gibt @code{NULL} zurück, wenn @code{X} nicht im Bereich von
+@code{-1} bis @code{1} liegt:
+@example
+mysql> select ASIN(0.2);
+ -> 0.201358
+mysql> select ASIN('foo');
+ -> 0.000000
+@end example
+
+@findex ATAN()
+@item ATAN(X)
+Gibt den Arcustangens von @code{X} zurück, das heißt den Wert, dessen
+Tangens @code{X} ist:
+@example
+mysql> select ATAN(2);
+ -> 1.107149
+mysql> select ATAN(-2);
+ -> -1.107149
+@end example
+
+@findex ATAN2()
+@item ATAN2(Y,X)
+Gibt den Arcustangens der beiden Variablen @code{X} und @code{Y} zurück.
+Das ähnelt der Berechnung des Arcustangens von @code{Y / X}, ausser dass
+die Vorzeichen beider Argumente benutzt werden, um den Quadranten des
+Ergebnisses zu bestimmen:
+@example
+mysql> select ATAN(-2,2);
+ -> -0.785398
+mysql> select ATAN(PI(),0);
+ -> 1.570796
+@end example
+
+@findex COT()
+@item COT(X)
+Gibt den Cotangens von @code{X} zurück:
+@example
+mysql> select COT(12);
+ -> -1.57267341
+mysql> select COT(0);
+ -> NULL
+@end example
+
+@findex RAND()
+@item RAND()
+@itemx RAND(N)
+Gibt eine Zufallszahl (Fließkommawert) im Bereich von @code{0} bis
+@code{1.0} zurück. Wenn ein Ganzzahl-Argument @code{N} angegeben wird, wird
+es als Ausgangswert benutzt:
+@example
+mysql> select RAND();
+ -> 0.5925
+mysql> select RAND(20);
+ -> 0.1811
+mysql> select RAND(20);
+ -> 0.1811
+mysql> select RAND();
+ -> 0.2079
+mysql> select RAND();
+ -> 0.7888
+@end example
+Sie können eine Spalte mit @code{RAND()}-Werten nicht in einer @code{ORDER
+BY}-Klausel verwenden, weil @code{ORDER BY} die Spalte mehrfach auswerten
+würde. In MySQL-Version 3.23 können Sie jedoch folgendes tun:
+@code{SELECT * FROM tabelle ORDER BY RAND()}
+
+Das ist nützlich, um eine Zufallsstichprobe aus @code{SELECT * FROM
+tabelle1,tabelle2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000} zu
+erhalten.
+
+Beachten Sie, dass ein @code{RAND()} in einer @code{WHERE}-Klausel jedes
+Mal von Neuem ausgewertet wird, wenn @code{WHERE} ausgeführt wird.
+
+@findex LEAST()
+@item LEAST(X,Y,...)
+Mit zwei oder mehr Argumenten gibt die Funktion das kleinste Argument (das
+mit dem niedrigsten Wert) zurück. Die Argumente werden nach folgenden
+Regeln verglichen:
+
+@itemize @bullet
+@item
+Wenn der Rückgabewert in einem @code{INTEGER}-Zusammenhang benutzt wird
+oder alle Argumente Ganzzahl-Werte sind, werden sie als Ganzzahlen
+verglichen.
+
+@item
+Wenn der Rückgabewert in einem @code{REAL}-Zusammenhang benutzt wird oder
+alle Argumente Realzahlen sind, werden sie als Realzahlen verglichen.
+
+@item
+Wenn irgend ein Argument eine von der Groß-/Kleinschreibung abhängige
+Zeichenkette ist, werden die Argumente als Zeichenketten, die von der
+Groß-/Kleinschreibung abhängen, verglichen.
+
+@item
+In sonstigen Fällen werden die Argumente als Zeichenketten verglichen, die
+nicht von der Groß-/Kleinschreibung abhängen:
+@end itemize
+
+@example
+mysql> select LEAST(2,0);
+ -> 0
+mysql> select LEAST(34.0,3.0,5.0,767.0);
+ -> 3.0
+mysql> select LEAST("B","A","C");
+ -> "A"
+@end example
+In MySQL-Versionen vor Version 3.22.5 können Sie @code{MIN()} statt
+@code{LEAST} benutzen.
+
+@findex GREATEST()
+@item GREATEST(X,Y,...)
+Gibt das größte Argument (das mit dem höchsten Wert) zurück. Die Argumente
+werden nach denselben Regeln wie bei @code{LEAST} verglichen:
+@example
+mysql> select GREATEST(2,0);
+ -> 2
+mysql> select GREATEST(34.0,3.0,5.0,767.0);
+ -> 767.0
+mysql> select GREATEST("B","A","C");
+ -> "C"
+@end example
+In MySQL-Versionen vor Version 3.22.5 können Sie @code{MAX()} statt
+@code{GREATEST} benutzen.
+
+@findex DEGREES()
+@item DEGREES(X)
+Gibt das Argument @code{X} zurück, von Radianten zu Grad umgewandelt:
+@example
+mysql> select DEGREES(PI());
+ -> 180.000000
+@end example
+
+@findex RADIANS()
+@item RADIANS(X)
+Gibt das Argument @code{X} zurück, von Grad zu Radianten umgewandelt:
+@example
+mysql> select RADIANS(90);
+ -> 1.570796
+@end example
+
+@findex TRUNCATE()
+@item TRUNCATE(X,D)
+Gibt die Zahl @code{X} zurück, auf @code{D} Dezimalstellen beschnitten.
+Wenn @code{D} @code{0} ist, hat das Ergebnis keinen Dezimalpunkt oder
+Bruchteil:
+@example
+mysql> select TRUNCATE(1.223,1);
+ -> 1.2
+mysql> select TRUNCATE(1.999,1);
+ -> 1.9
+mysql> select TRUNCATE(1.999,0);
+ -> 1
+@end example
+
+Beachten Sie, dass Dezimalzahlen in Computern normalerweise nicht als
+exakte Zahlen, sondern als Double-Werte gespeichert werden. Daher können
+verwirrende Ergebnisse wie im folgenden Beispiel auftreten:
+
+@cindex Rundungsfehler
+@example
+mysql> select TRUNCATE(10.28*100,0);
+ -> 1027
+@end example
+
+Das Obige passiert, weil 10.28 tatsächlich als etwas wie
+10.2799999999999999 gespeichert wird.
+@end table
+
+
+@node Date and time functions, Other Functions, Numeric Functions, Functions
+@c German node Datums- und Zeit-Funktionen
+@subsection Datums- und Zeit-Funktionen
+
+@findex Datums- und Zeit-Funktionen
+@findex Funktionen, Datums- und Zeit-
+
+Eine Beschreibung des Wertebereichs aller Typen und der gültigen Formate
+für Datums- und Zeitwerte finden Sie unter @ref{Date and time types}.
+
+Hier ist ein Beispiel, das Datums-Funktionen benutzt. Die unten stehende
+Anfrage wählt alle Datensätze mit einem @code{datum_spalte}-Wert innerhalb
+der letzten 30 Tage aus:
+
+@example
+mysql> SELECT etwas FROM tabelle
+ WHERE TO_DAYS(NOW()) - TO_DAYS(datum_spalte) <= 30;
+@end example
+
+@table @code
+@findex DAYOFWEEK()
+@item DAYOFWEEK(datum)
+Gibt den Wochentag-Index zurück.
+
+Für @code{datum} gilt: @code{1} = Sonntag, @code{2} = Montag, ... @code{7}
+= Samstag). Diese Index-Werte entsprechen dem ODBC-Standard:
+
+@example
+mysql> select DAYOFWEEK('1998-02-03');
+ -> 3
+@end example
+
+@findex WEEKDAY()
+@item WEEKDAY(datum)
+Gibt den Wochentag-Index für @code{datum} zurück (@code{0} = Montag,
+@code{1} = Dienstag, ... @code{6} = Sonntag):
+
+@example
+mysql> select WEEKDAY('1997-10-04 22:23:00');
+ -> 5
+mysql> select WEEKDAY('1997-11-05');
+ -> 2
+@end example
+
+@findex DAYOFMONTH()
+@item DAYOFMONTH(datum)
+Gibt den Tag des Monats für @code{datum} im Bereich @code{1} bis @code{31}
+zurück:
+
+@example
+mysql> select DAYOFMONTH('1998-02-03');
+ -> 3
+@end example
+
+@findex DAYOFYEAR()
+@item DAYOFYEAR(datum)
+Gibt den Tag des Jahres für @code{datum} im Bereich @code{1} bis @code{366}
+zurück:
+
+@example
+mysql> select DAYOFYEAR('1998-02-03');
+ -> 34
+@end example
+
+@findex MONTH()
+@item MONTH(datum)
+Gibt den Monat für @code{datum} im Bereich @code{1} bis @code{12} zurück:
+
+@example
+mysql> select MONTH('1998-02-03');
+ -> 2
+@end example
+
+@findex DAYNAME()
+@item DAYNAME(datum)
+Gibt den Namen des Wochentags für @code{datum} zurück (auf englisch):
+
+@example
+mysql> select DAYNAME("1998-02-05");
+ -> 'Thursday'
+@end example
+
+@findex MONTHNAME()
+@item MONTHNAME(datum)
+Gibt den Namen des Monats für @code{datum} zurück (auf englisch):
+
+@example
+mysql> select MONTHNAME("1998-02-05");
+ -> 'February'
+@end example
+
+@findex QUARTER()
+@item QUARTER(datum)
+Gibt das Quartal des Jahres für @code{datum} im Bereich @code{1} bis
+@code{4} zurück:
+
+@example
+mysql> select QUARTER('98-04-01');
+ -> 2
+@end example
+
+@findex WEEK()
+@item WEEK(datum)
+@itemx WEEK(datum,erste)
+Mit einem einzelnen Argument gibt diese Funktion die Woche für @code{datum}
+im Bereich @code{0} bis @code{53} zurück (ja, es kann Anfänge der Woche 53
+geben), für Orte, in denen Sonntag der erste Wochentag ist. In der Form mit
+zwei Argumenten gestattet @code{WEEK()} es, festzulegen, ob die Woche am
+Sonntag oder am Montag beginnt. Die Woche beginnt am Sonntag, wenn das
+zweite Argument @code{0} ist, und am Montag, wenn das zweite Argument
+@code{1} ist:
+
+@example
+mysql> select WEEK('1998-02-20');
+ -> 7
+mysql> select WEEK('1998-02-20',0);
+ -> 7
+mysql> select WEEK('1998-02-20',1);
+ -> 8
+mysql> select WEEK('1998-12-31',1);
+ -> 53
+@end example
+
+@findex YEAR()
+@item YEAR(datum)
+Gibt das Jahr für @code{datum} im Bereich @code{1000} bis @code{9999}
+zurück:
+
+@example
+mysql> select YEAR('98-02-03');
+ -> 1998
+@end example
+
+@item YEARWEEK(datum)
+@itemx YEARWEEK(datum,erste)
+Gibt Jahr und Woche für ein Datum zurück. Das zweite Argument funktioniert
+genau wie das zweite Argument von @code{WEEK()}. Beachten Sie, dass das
+Jahr sich in der ersten und letzten Woche des Jahres vom Jahr im
+Datums-Argument unterscheiden kann:
+
+@example
+mysql> select YEARWEEK('1987-01-01');
+ -> 198653
+@end example
+
+@findex HOUR()
+@item HOUR(zeit)
+Gibt die Stunde für @code{zeit} im Bereich @code{0} bis @code{23} zurück:
+
+@example
+mysql> select HOUR('10:05:03');
+ -> 10
+@end example
+
+@findex MINUTE()
+@item MINUTE(zeit)
+Gibt die Minute für @code{zeit} im Bereich @code{0} bis @code{59} zurück:
+
+@example
+mysql> select MINUTE('98-02-03 10:05:03');
+ -> 5
+@end example
+
+@findex SECOND()
+@item SECOND(zeit)
+Gibt die Sekunde für @code{zeit} im Bereich @code{0} bis @code{59} zurück:
+
+@example
+mysql> select SECOND('10:05:03');
+ -> 3
+@end example
+
+@findex PERIOD_ADD()
+@item PERIOD_ADD(P,N)
+Zählt @code{N} Monate zur Periode @code{P} hinzu (im Format @code{YYMM}
+oder @code{YYYYMM}). Gibt einen Wert im Format @code{YYYYMM} zurück.
+
+Beachten Sie, dass das Perioden-Argument @code{P} @emph{kein} Datums-Wert
+ist:
+
+@example
+mysql> select PERIOD_ADD(9801,2);
+ -> 199803
+@end example
+
+@findex PERIOD_DIFF()
+@item PERIOD_DIFF(P1,P2)
+Gibt die Anzahl von Monaten zwischen den Perioden @code{P1} und @code{P2}
+zurück. @code{P1} und @code{P2} sollten im Format @code{YYMM} oder
+@code{YYYYMM} sein.
+
+Beachten Sie, dass die Perioden-Argumente @code{P1} und @code{P2}
+@emph{keine} Datumswerte sind:
+
+@example
+mysql> select PERIOD_DIFF(9802,199703);
+ -> 11
+@end example
+
+@findex DATE_ADD()
+@findex DATE_SUB()
+@findex ADDDATE()
+@findex SUBDATE()
+@findex EXTRACT()
+@item DATE_ADD(datum,INTERVAL ausdruck typ)
+@itemx DATE_SUB(datum,INTERVAL ausdruck typ)
+@itemx ADDDATE(datum,INTERVAL ausdruck typ)
+@itemx SUBDATE(datum,INTERVAL ausdruck typ)
+
+Diese Funktionen führen Datumsberechnungen durch. Sie wurden in
+MySQL-Version 3.22 eingeführt. @code{ADDDATE()} und @code{SUBDATE()} sind
+Synonyme für @code{DATE_ADD()} und @code{DATE_SUB()}.
+
+In MySQL-Version 3.23 können Sie @code{+} und @code{-} anstelle von
+@code{DATE_ADD()} und @code{DATE_SUB()} benutzen, wenn der Ausdruck auf der
+rechten Seite eine DATE oder DATETIME-Spalte ist (siehe Beispiel).
+
+@code{datum} ist ein @code{DATETIME}- oder @code{DATE}-Wert, der das
+Anfangsdatum festlegt. @code{ausdruck} ist ein Ausdruck, der den
+Intervallwert festlegt, der zum Anfangsdatum hinzugezählt oder von diesem
+abgezogen wird. @code{ausdruck} ist eine Zeichenkette; sie kann mit einem
+@samp{-} für negative Intervalle beginnen. @code{typ} ist ein
+Schlüsselwort, das angibt, wie der Ausdruck interpretiert werden soll.
+
+Die verwandte Funktion @code{EXTRACT(typ FROM datum)} gibt das
+'typ'-Intervall des Datums zurück.
+
+Folgende Tabelle zeigt, in welchem Zusammenhang die @code{typ}- und
+@code{ausdruck}-Argumente stehen:
+
+@multitable @columnfractions .5 .5
+@item @code{typ} @strong{wert} @tab @strong{erwartet} @code{ausdruck} @strong{format}
+@item @code{SECOND} @tab @code{Sekunden}
+@item @code{MINUTE} @tab @code{Minuten}
+@item @code{HOUR} @tab @code{Stunden}
+@item @code{DAY} @tab @code{Tage}
+@item @code{MONTH} @tab @code{Monate}
+@item @code{YEAR} @tab @code{Jahre}
+@item @code{MINUTE_SECOND} @tab @code{"Minuten:Sekunden"}
+@item @code{HOUR_MINUTE} @tab @code{"Stunden:Minuten"}
+@item @code{DAY_HOUR} @tab @code{"Tage Stunden"}
+@item @code{YEAR_MONTH} @tab @code{"Jahre-Monate"}
+@item @code{HOUR_SECOND} @tab @code{"Stunden:Minuten:Sekunden"}
+@item @code{DAY_MINUTE} @tab @code{"Tage Stunden:Minuten"}
+@item @code{DAY_SECOND} @tab @code{"Tage Stunden:Minuten:Sekunden"}
+@end multitable
+
+MySQL erlaubt beliebige Satzzeichen-Begrenzer im @code{ausdruck}-Format.
+Die in der Tabelle gezeigten Begrenzer sind Vorschläge. Wenn das
+@code{datum}-Argument ein @code{DATE}-Wert ist und Ihre Berechnungen nur
+@code{YEAR}, @code{MONTH} und @code{DAY}-Anteile beinhalten (also keine
+Zeit-Anteile), ist das Ergebnis ein @code{DATE}-Wert. Ansonsten ist das
+Ergebnis ein @code{DATETIME}-Wert:
+
+@example
+mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
+ -> 1998-01-01 00:00:00
+mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
+ -> 1998-01-01
+mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
+ -> 1997-12-31 23:59:59
+mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
+ INTERVAL 1 SECOND);
+ -> 1998-01-01 00:00:00
+mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
+ INTERVAL 1 DAY);
+ -> 1998-01-01 23:59:59
+mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
+ INTERVAL "1:1" MINUTE_SECOND);
+ -> 1998-01-01 00:01:00
+mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
+ INTERVAL "1 1:1:1" DAY_SECOND);
+ -> 1997-12-30 22:58:59
+mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
+ INTERVAL "-1 10" DAY_HOUR);
+ -> 1997-12-30 14:00:00
+mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
+ -> 1997-12-02
+@end example
+
+Wenn Sie einen Intervallwert angeben, der zu kurz ist (nicht alle
+Intervall-Anteile beinhaltet, die vom @code{typ}-Schlüsselwort erwartet
+werden), nimmt MySQL an, dass Sie den äußersten linken Teil des
+Intervallwerts ausgelassen haben. Wenn Sie beispielsweise einen @code{typ}
+@code{DAY_SECOND} angeben, wird vom Wert von @code{ausdruck} erwartet, dass
+dieser Tages-, Stunden-, Minuten- und Sekunden-Anteile enthält. Wenn Sie
+einen Wert wie @code{"1:10"} angeben, nimmt MySQL an, dass die Tages- und
+Stunden-Anteile fehlen und der Wert Minuten und Sekunden darstellt. Mit
+anderen Worten wird @code{"1:10" DAY_SECOND} so interpretiert, dass es
+äquivalent zu @code{"1:10" MINUTE_SECOND} ist. Das ist analog zur Weise,
+wie MySQL @code{TIME}-Werte interpretiert, die eher vergangene Zeit als
+Tageszeit darstellen.
+
+Beachten Sie, dass ein Datumswert automatisch in einen DATETIME-Wert
+umgewandelt wird, wenn Sie einen DATE-Wert zu etwas hinzuzählen oder von
+etwas abziehen, das einen Zeit-Anteil hat:
+
+@example
+mysql> select date_add("1999-01-01", interval 1 day);
+ -> 1999-01-02
+mysql> select date_add("1999-01-01", interval 1 hour);
+ -> 1999-01-01 01:00:00
+@end example
+
+Wenn Sie wirklich falsche Datumsangaben benutzen, ist das Ergebnis
+@code{NULL}. Wenn Sie @code{MONTH}, @code{YEAR_MONTH} oder @code{YEAR}
+hinzuzählen und das Datumsergebnis einen Tag hat, der größer ist als der
+höchste Tag für den neuen Monat, wird der Tag auf den höchsten Tag des
+neuen Monats angepasst:
+
+@example
+mysql> select DATE_ADD('1998-01-30', Interval 1 month);
+ -> 1998-02-28
+@end example
+
+Beachten Sie, dass das Wort @code{INTERVAL} und das
+@code{typ}-Schlüsselwort in den vorstehenden Beispielen nicht von der
+verwendeten Groß-/Kleinschreibung abhängen.
+
+@findex EXTRACT()
+@item EXTRACT(typ FROM datum)
+
+Die @code{EXTRACT()}-Funktion benutzt dieselbe Art von
+Intervalltyp-Spezifikatoren wie @code{DATE_ADD()} oder @code{DATE_SUB()},
+extrahiert aber Anteile aus dem Datum, statt Datumsberechnungen
+durchzuführen:
+
+@example
+mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
+ -> 1999
+mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
+ -> 199907
+mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
+ -> 20102
+@end example
+
+@findex TO_DAYS()
+@item TO_DAYS(datum)
+Gibt für ein Datum @code{datum} eine Tagesanzahl zurück (die Anzahl von
+Tagen seit dem Jahr 0):
+
+@example
+mysql> select TO_DAYS(950501);
+ -> 728779
+mysql> select TO_DAYS('1997-10-07');
+ -> 729669
+@end example
+
+@code{TO_DAYS()} ist nicht für die Benutzung mit Werten vor der Einführung
+des Gregorianischen Kalenders (1582) vorgesehen, weil es nicht die Tage
+berücksichtigt, die verloren gingen, als der Kalender geändert wurde.
+
+@findex FROM_DAYS()
+@item FROM_DAYS(N)
+Gibt für eine Tagesanzahl @code{N} einen @code{DATE}-Wert zurück:
+
+@example
+mysql> select FROM_DAYS(729669);
+ -> '1997-10-07'
+@end example
+
+@code{FROM_DAYS()} ist nicht für die Benutzung mit Werten vor der Einführung
+des Gregorianischen Kalenders (1582) vorgesehen, weil es nicht die Tage
+berücksichtigt, die verloren gingen, als der Kalender geändert wurde.
+
+@findex DATE_FORMAT()
+@item DATE_FORMAT(datum,format)
+Formatiert den @code{datum}-Wert gemäß der @code{format}-Zeichenkette.
+Folgende Spezifikatoren können in der @code{format}-Zeichenkette benutzt
+werden:
+@multitable @columnfractions .1 .6
+@item @code{%M} @tab Monatsname auf englisch (@code{January} bis @code{December})
+@item @code{%W} @tab Name des Wochentags auf englisch (@code{Sunday} bis @code{Saturday})
+@item @code{%D} @tab Tag des Monats mit englischem Suffix (@code{1st}, @code{2nd}, @code{3rd} usw.)
+@item @code{%Y} @tab Jahr, numerisch, 4 Ziffern
+@item @code{%y} @tab Jahr, numerisch, 2 Ziffern
+@item @code{%X} @tab Jahr der Woche, wobei Sonntag der erste Tag der Woche ist, numerisch, 4 Ziffern, benutzt mit '%V'
+@item @code{%x} @tab Jahr der Woche, wobei Montag der erste Tag der Woche ist, numerisch, 4 Ziffern, benutzt mit '%v'
+@item @code{%a} @tab Abgekürzter Name des Wochentags auf englisch (@code{Sun}..@code{Sat})
+@item @code{%d} @tab Tag des Monats, numerisch (@code{00} bis @code{31})
+@item @code{%e} @tab Tag des Monats, numerisch (@code{0} bis @code{31})
+@item @code{%m} @tab Monat, numerisch (@code{01} bis @code{12})
+@item @code{%c} @tab Monat, numerisch (@code{1} bis @code{12})
+@item @code{%b} @tab Abgekürzter Monatsname auf englisch (@code{Jan} bis @code{Dec})
+@item @code{%j} @tab Tag des Jahrs (@code{001} bis @code{366})
+@item @code{%H} @tab Stunde (@code{00} bis @code{23})
+@item @code{%k} @tab Stunde (@code{0} bis @code{23})
+@item @code{%h} @tab Stunde (@code{01} bis @code{12})
+@item @code{%I} @tab Stunde (@code{01} bis @code{12})
+@item @code{%l} @tab Stunde (@code{1} bis @code{12})
+@item @code{%i} @tab Minuten, numerisch (@code{00} bis @code{59})
+@item @code{%r} @tab Uhrzeit, 12-Stunden-Format (@code{hh:mm:ss [AP]M})
+@item @code{%T} @tab Uhrzeit, 24-Stunden-Format (@code{hh:mm:ss})
+@item @code{%S} @tab Sekunden (@code{00} bis @code{59})
+@item @code{%s} @tab Sekunden (@code{00} bis @code{59})
+@item @code{%p} @tab @code{AM} oder @code{PM}
+@item @code{%w} @tab Wochentag (@code{0}=Sonntag bis @code{6}=Samstag)
+@item @code{%U} @tab Woche (@code{0} bis @code{53}), wobei Sonntag der erste Tag der Woche ist
+@item @code{%u} @tab Woche (@code{0} bis @code{53}), wobei Montag der erste Tag der Woche ist
+@item @code{%V} @tab Woche (@code{1} bis @code{53}), wobei Sonntag der erste Tag der Woche ist. Benutzt mit '%X'
+@item @code{%v} @tab Woche (@code{1} bis @code{53}), wobei Montag der erste Tag der Woche ist. Benutzt mit '%x'
+@item @code{%%} @tab Ein Literal @samp{%}.
+@end multitable
+
+Alle anderen Zeichen werden einfach ohne Interpretation ins Ergebnis
+kopiert:
+
+@example
+mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W%M%Y');
+ -> 'Saturday October 1997'
+mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
+ -> '22:23:00'
+mysql> select DATE_FORMAT('1997-10-04 22:23:00',
+ '%D%y%a%d%m%b%j');
+ -> '4th 97 Sat 04 10 Oct 277'
+mysql> select DATE_FORMAT('1997-10-04 22:23:00',
+ '%H%k%I%r%T%S%w');
+ -> '22 22 10 10:23:00 PM 22:23:00 00 6'
+mysql> select DATE_FORMAT('1999-01-01', '%X%V');
+ -> '1998 52'
+@end example
+
+Ab MySQL-Version 3.23 ist das @samp{%}-Zeichen vor
+Format-Spezifikator-Zeichen erforderlich. In früheren Versionen von MySQL
+war @samp{%} optional.
+
+@findex TIME_FORMAT()
+@item TIME_FORMAT(zeit,format)
+Dieses wird benutzt wie die obige @code{DATE_FORMAT()}-Funktion, aber die
+@code{format}-Zeichenkette darf nur die Spezifikatoren enthalten, die
+Stunden, Minuten und Sekunden handhaben. Andere Spezifikatoren erzeugen
+einen @code{NULL}-Wert oder @code{0}.
+
+@findex CURDATE()
+@findex CURRENT_DATE
+@item CURDATE()
+@itemx CURRENT_DATE
+Gibt das Datum von heute im @code{'YYYY-MM-DD'}- oder
+@code{YYYYMMDD}-format zurück, abhängig davon, ob die Funktion in einem
+Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:
+
+@example
+mysql> select CURDATE();
+ -> '1997-12-15'
+mysql> select CURDATE() + 0;
+ -> 19971215
+@end example
+
+@findex CURTIME()
+@findex CURRENT_TIME
+@item CURTIME()
+@itemx CURRENT_TIME
+Gibt die aktuelle Zeit als einen Wert im @code{'HH:MM:SS'}- oder
+@code{HHMMSS}-format zurück, abhängig davon, ob die Funktion in einem
+Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:
+
+@example
+mysql> select CURTIME();
+ -> '23:50:26'
+mysql> select CURTIME() + 0;
+ -> 235026
+@end example
+
+@findex NOW()
+@findex SYSDATE()
+@findex CURRENT_TIMESTAMP
+@item NOW()
+@itemx SYSDATE()
+@itemx CURRENT_TIMESTAMP
+Gibt das aktuelle Datum und die aktuelle Zeit als einen Wert im
+@code{'YYYY-MM-DD HH:MM:SS'}- oder @code{YYYYMMDDHHMMSS}-Format zurück,
+abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem
+numerischen Zusammenhang benutzt wird:
+
+@example
+mysql> select NOW();
+ -> '1997-12-15 23:50:26'
+mysql> select NOW() + 0;
+ -> 19971215235026
+@end example
+
+@findex UNIX_TIMESTAMP()
+@item UNIX_TIMESTAMP()
+@itemx UNIX_TIMESTAMP(datum)
+Ohne Argument aufgerufen gibt die Funktion einen Unix-Zeitstempel zurück
+(Sekunden seit @code{'1970-01-01 00:00:00'} GMT). Wenn
+@code{UNIX_TIMESTAMP()} mit einem @code{datum}-Argument aufgerufen wird,
+gibt sie den Wert des Arguments als Sekunden seit @code{'1970-01-01
+00:00:00'} GMT zurück. @code{datum} kann eine @code{DATE}-Zeichenkette,
+eine @code{DATETIME}-Zeichenkette, ein @code{TIMESTAMP} oder eine Zahl im
+Format @code{YYMMDD} oder @code{YYYYMMDD} in lokaler Zeit sein:
+
+@example
+mysql> select UNIX_TIMESTAMP();
+ -> 882226357
+mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
+ -> 875996580
+@end example
+
+Wenn @code{UNIX_TIMESTAMP} auf einer @code{TIMESTAMP}-Spalte benutzt wird,
+erhält die Funktion den Wert direkt, ohne implizite
+``zeichenkette-zu-unix-zeitstempel''-Umwandlung. Wenn Sie
+@code{UNIX_TIMESTAMP()} einen falschen Wert oder einen Wert ausserhalb des
+Wertebereichs angeben, gibt sie 0 zurück.
+
+@findex FROM_UNIXTIME()
+@item FROM_UNIXTIME(unix_zeitstempel)
+Gibt das @code{unix_timestamp}-Argument als Wert im @code{'YYYY-MM-DD
+HH:MM:SS'}- oder @code{YYYYMMDDHHMMSS}-Format zurück, abhängig davon, ob
+die Funktion in einem Zeichenketten- oder in einem numerischen Zusammenhang
+benutzt wird:
+
+@example
+mysql> select FROM_UNIXTIME(875996580);
+ -> '1997-10-04 22:23:00'
+mysql> select FROM_UNIXTIME(875996580) + 0;
+ -> 19971004222300
+@end example
+
+@findex FROM_UNIXTIME()
+@item FROM_UNIXTIME(unix_zeitstempel,format)
+Gibt das @code{unix_timestamp}-Argument als Wert zurück, der wie mit der
+@code{format}-Zeichenkette angegeben formatiert ist. @code{format} kann
+dieselben Spezifikatoren wie die @code{DATE_FORMAT()}-Funktion enthalten:
+
+@example
+mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
+ '%Y%D%M%h:%i:%s%x');
+ -> '1997 23rd December 03:43:30 x'
+@end example
+
+@findex SEC_TO_TIME()
+@item SEC_TO_TIME(sekunden)
+Gibt das @code{sekunden}-Argument, umgewandelt in Stunden, Minuten und
+Sekunden, als Wert im @code{'HH:MM:SS'}- oder @code{HHMMSS}-Format zurück,
+abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem
+numerischen Zusammenhang benutzt wird:
+
+@example
+mysql> select SEC_TO_TIME(2378);
+ -> '00:39:38'
+mysql> select SEC_TO_TIME(2378) + 0;
+ -> 3938
+@end example
+
+@findex TIME_TO_SEC()
+@item TIME_TO_SEC(zeit)
+Gibt das @code{zeit}-Argument, umgewandelt in Sekunden, zurück:
+
+@example
+mysql> select TIME_TO_SEC('22:23:00');
+ -> 80580
+mysql> select TIME_TO_SEC('00:39:38');
+ -> 2378
+@end example
+@end table
+
+
+@node Other Functions, Group by functions, Date and time functions, Functions
+@c German node Weitere Funktionen
+@subsection Weitere Funktionen
+
+
+
+@menu
+* Bit functions::
+* Miscellaneous functions::
+@end menu
+
+@node Bit functions, Miscellaneous functions, Other Functions, Other Functions
+@c German node Bit-Funktionen
+@subsubsection Bit-Funktionen
+
+@findex arithmetische Funktionen
+@findex Bit-Funktionen
+@findex Funktionen, arithmetische
+@findex Funktionen, Bit-
+
+MySQL benutzt @code{BIGINT}-Berechnungen (64-Bit) für Bit-Operationen, so
+dass diese Operatoren einen maximalen Wertebereich von 64 Bits haben.
+
+@table @code
+@findex | (bitweises OR)
+@findex OR, bitweises
+@item |
+Bitweises OR:
+@example
+mysql> select 29 | 15;
+ -> 31
+@end example
+
+@findex & (bitweises AND)
+@findex AND, bitweises
+@item &
+Bitweises AND:
+@example
+mysql> select 29 & 15;
+ -> 13
+@end example
+
+@findex << (left shift)
+@item <<
+Verschiebt eine @code{BIGINT}-Zahl nach links:
+@example
+mysql> select 1 << 2;
+ -> 4
+@end example
+
+@findex >> (right shift)
+@item >>
+Verschiebt eine @code{BIGINT}-Zahl nach rechts:
+@example
+mysql> select 4 >> 2;
+ -> 1
+@end example
+
+@findex ~
+@item ~
+Invertiert alle Bits:
+@example
+mysql> select 5 & ~1;
+ -> 4
+@end example
+
+@findex BIT_COUNT()
+@item BIT_COUNT(N)
+Gibt die Anzahl von Bits, die im Argument @code{N} gesetzt sind, zurück:
+@example
+mysql> select BIT_COUNT(29);
+ -> 4
+@end example
+@end table
+
+
+@node Miscellaneous functions, , Bit functions, Other Functions
+@c German node Verschiedene Funktionen
+@subsubsection Verschiedene Funktionen
+
+@findex Verschiedene Funktionen
+@findex Funktionen, verschiedene
+
+@table @code
+@findex DATABASE()
+@item DATABASE()
+Gibt den aktuellen Datenbanknamen zurück:
+
+@example
+mysql> select DATABASE();
+ -> 'test'
+@end example
+
+Wenn es keine aktuelle Datenbank gibt, gibt @code{DATABASE()} die leere
+Zeichenkette zurück.
+
+@findex USER()
+@findex SYSTEM_USER()
+@findex SESSION_USER()
+@item USER()
+@itemx SYSTEM_USER()
+@itemx SESSION_USER()
+Gibt den aktuellen MySQL-Benutzernamen zurück:
+
+@example
+mysql> select USER();
+ -> 'heinzholger@@localhost'
+@end example
+
+Ab MySQL-Version 3.22.11 beinhaltet dieser Wert den Client-Hostnamen sowie
+den Benutzernamen. Sie können nur den Benutzernamen-Anteil wie folgt
+extrahieren (was funktioniert, ob der Wert nun einen Hostnamen-Anteil hat
+oder nicht):
+
+@example
+mysql> select substring_index(USER(),"@@",1);
+ -> 'heinzholger'
+@end example
+
+@findex PASSWORD()
+@item PASSWORD(zeichenkette)
+
+Berechnet eine Passwort-Zeichenkette aus dem Klartext-Passwort
+@code{zeichenkette}. Diese Funktion wird benutzt, um MySQL-Passwörter zum
+Speichern in der @code{Password}-Spalte der
+@code{user}-Berechtigungstabelle zu verschlüsseln:
+
+@example
+mysql> select PASSWORD('schlechtespasswort');
+ -> '1ccbb34b4e2b2f95'
+@end example
+
+@cindex Passwort-Verschlüsselung, Umkehrbarkeit
+Die @code{PASSWORD()}-Verschlüsselung ist nicht umkehrbar.
+
+@code{PASSWORD()} führt keine Passwort-Verschlüsselung in der Art durch,
+wie Unix-Passwörter verschlüsselt werden. Sie sollten nicht annehmen, dass
+Ihr Unix-Passwort und Ihr MySQL-Passwort dasselbe sind. @code{PASSWORD()}
+ergibt denselben verschlüsselten Wert, wie er in der Unix-Passwortdatei
+gespeichert ist. Siehe @code{ENCRYPT()}.
+
+@findex ENCRYPT()
+@item ENCRYPT(zeichenkette[,salt])
+Verschlüsselt @code{zeichenkette} unter Benutzung des
+Unix-@code{crypt()}-Systemaufrufs. Das @code{salt}-Argument sollte eine
+Zeichenkette mit zwei Zeichen sein (ab MySQL-Version 3.22.16 darf
+@code{salt} länger als zwei Zeichen sein):
+
+@example
+mysql> select ENCRYPT("hello");
+ -> 'VxuFAJXVARROc'
+@end example
+
+Wenn @code{crypt()} auf Ihrem System nicht verfügbar ist, gibt
+@code{ENCRYPT()} immer @code{NULL} zurück.
+
+@code{ENCRYPT()} ignoriert alle ausser den ersten 8 Zeichen von
+@code{zeichenkette}, zumindest auf einigen Systemen. Das wird durch den
+zugrunde liegenden @code{crypt()}-Systemaufruf festgelegt.
+
+@findex ENCODE()
+@item ENCODE(zeichenkette,passwort_zeichenkette)
+Verschlüsselt @code{zeichenkette}, indem @code{passwort_zeichenkette} als
+Passwort benutzt wird. Um das Ergebnis zu entschlüsseln, benutzen Sie
+@code{DECODE()}.
+
+Das Ergebnis ist eine binäre Zeichenkette derselben Länge wie
+@code{zeichenkette}. Wenn Sie sie in einer Spalte speichern wollen,
+benutzen Sie eine @code{BLOB}-Spalte.
+
+@findex DECODE()
+@item DECODE(crypt_zeichenkette,passwort_zeichenkette)
+Entschlüsselt die verschlüsselte Zeichenkette @code{crypt_zeichenkette},
+indem @code{passwort_zeichenkette} als Passwort benutzt wird.
+@code{crypt_zeichenkette} sollte eine Zeichenkette sein, die von
+@code{ENCODE()} zurückgegeben wird.
+
+@findex MD5()
+@item MD5(zeichenkette)
+Berechnet eine MD5-Prüfsumme für die Zeichenkette. Der Wert wird als eine
+32 Stellen lange hexadezimale Zahl zurückgegeben, die zum Beispiel als
+Hash-Schlüssel benutzt werden kann:
+
+@example
+mysql> select MD5("testing");
+ -> 'ae2b1fca515949e5d54fb22b8ed95575'
+@end example
+
+Das ist ein "RSA Data Sicherheit, Inc. MD5 Message-Digest Algorithm".
+
+@findex LAST_INSERT_ID([ausdruck])
+@item LAST_INSERT_ID([ausdruck])
+Gibt den letzten automatisch erzeugten Wert zurück, der in eine
+@code{AUTO_INCREMENT}-Spalte eingefügt wurde. @xref{mysql_insert_id,,
+@code{mysql_insert_id()}}.
+
+@example
+mysql> select LAST_INSERT_ID();
+ -> 195
+@end example
+
+Die letzte ID, die erzeugt wurde, wird im Server für jede Verbindung
+separat gespeichert. Sie wird nicht durch andere Clients geändert. Sie wird
+nicht einmal geändert, wenn Sie eine andere @code{AUTO_INCREMENT}-Spalte
+mit einem nicht 'magischen' Wert aktualisieren (also einem Wert, der nicht
+@code{NULL} und nicht @code{0} ist).
+
+Wenn Sie viele Zeilen zugleich mit einem Insert-Statement einfügen, gibt
+@code{LAST_INSERT_ID()} den Wert für die erste eingefügte Zeile zurück. Der
+Grund dafür liegt darin, dass es Ihnen dadurch ermöglicht wird, dasselbe
+@code{INSERT}-Statement auf einfache Weise auf einem anderen Server zu
+reproduzieren.
+
+@cindex Zahlenfolgen-Emulation
+Wenn @code{ausdruck} als Argument zu @code{LAST_INSERT_ID()} angegeben
+wird, wird der Wert des Arguments von der Funktion zurückgegeben, als
+nächster Wert gesetzt, der von @code{LAST_INSERT_ID()} zurückgegeben wird
+und als nächster auto_increment-Wert benutzt. Damit können Sie Zahlenfolgen
+emulieren:
+
+Erzeugen Sie zuerst die Tabelle:
+
+@example
+mysql> create table sequenz (id int not null);
+mysql> insert into sequenz values (0);
+@end example
+
+Danach kann die Tabelle benutzt werden, um wie folgt Zahlenfolgen zu
+erzeugen:
+
+@example
+mysql> update sequenz set id=LAST_INSERT_ID(id+1);
+@end example
+
+Sie können Zahlenfolgen erzeugen, ohne @code{LAST_INSERT_ID()} aufzurufen,
+aber der Nutzen, die Funktion auf diese Art zu benutzen, liegt darin, dass
+der ID-Wert im Server als letzter automatisch erzeugter Wert gehalten wird.
+Sie können die neue ID auf dieselbe Art abrufen, wie Sie jeden anderen
+normalen @code{AUTO_INCREMENT}-Wert in MySQL lesen würden.
+@code{LAST_INSERT_ID()} (ohne Argument) zum Beispiel gibt die neue ID
+zurück. Die C-API-Funktion @code{mysql_insert_id()} kann ebenfalls benutzt
+werden, um den Wert zu erhalten.
+
+Beachten Sie, dass Sie diese Funktion nicht benutzen können, um den Wert
+von @code{LAST_INSERT_ID(ausdruck)} abzurufen, nachdem Sie andere
+SQL-Statements wie @code{SELECT} oder @code{SET} ausgeführt haben, weil
+@code{mysql_insert_id()} nur nach @code{INSERT}- und
+@code{UPDATE}-Statements aktualisiert wird.
+
+
+@findex FORMAT()
+@item FORMAT(X,D)
+Formatiert die Zahl @code{X} in ein Format wie @code{'#,###,###.##'},
+gerundet auf @code{D} Dezimalstellen. Wenn @code{D} @code{0} ist, hat das
+Ergebnis keinen Dezimalpunkt oder Bruchteil:
+
+@example
+mysql> select FORMAT(12332.123456, 4);
+ -> '12,332.1235'
+mysql> select FORMAT(12332.1,4);
+ -> '12,332.1000'
+mysql> select FORMAT(12332.2,0);
+ -> '12,332'
+@end example
+
+@findex VERSION()
+@item VERSION()
+Gibt eine Zeichenkette zurück, die die MySQL-Serverversion anzeigt:
+
+@example
+mysql> select VERSION();
+ -> '3.23.13-log'
+@end example
+
+Wenn Ihre Versionsnummer mit @code{-log} endet, bedeutet das, dass Loggen
+angeschaltet ist.
+
+@findex CONNECTION_ID()
+@item CONNECTION_ID()
+Gibt die Verbindungskennnummer (@code{Thread_id}) für die Verbindung
+zurück. Jede Verbindung hat ihre eigene eindeutige Kennnummer:
+
+@example
+mysql> select CONNECTION_ID();
+ -> 1
+@end example
+
+@cindex Zeitüberschreitung (Timeout)
+@findex GET_LOCK()
+@item GET_LOCK(zeichenkette,zeitueberschreitung)
+Versucht, eine Sperre mit dem Namen, der durch die Zeichenkette
+@code{zeichenkette} angegeben wird, zu erlangen, mit einem Timeout von
+@code{zeitueberschreitung} Sekunden. Gibt @code{1} zurück, wenn die Sperre
+erfolgreich erlangt wurde, und @code{0}, wenn der Versuch wegen
+Zeitüberschreitung abgebrochen wurde, oder @code{NULL}, wenn ein Fehler
+auftrat (wenn zum Beispiel kein Arbeitsspeicher mehr frei ist oder der
+Thread mit @code{mysqladmin kill} gekillt wurde). Eine Sperre wird
+aufgehoben, wenn Sie @code{RELEASE_LOCK()} ausführen, einen neuen
+@code{GET_LOCK()} ausführen oder der Thread beendet wird. Diese Funktion
+kann benutzt werden, um Applikations-Sperren zu implementieren oder um
+Datensatz-Sperren zu simulieren. Sie blockiert Anfragen von anderen Clients
+nach Sperren mit demselben Namen; Clients, die sich auf einen angegebenen
+Namen für die Sperr-Zeichenkette einigen, können die Zeichenkette benutzen,
+um kooperatives beratendes Sperren (advisory locking) auszuführen:
+
+@example
+mysql> select GET_LOCK("lock1",10);
+ -> 1
+mysql> select GET_LOCK("lock2",10);
+ -> 1
+mysql> select RELEASE_LOCK("lock2");
+ -> 1
+mysql> select RELEASE_LOCK("lock1");
+ -> NULL
+@end example
+
+Beachten Sie, dass der zweite @code{RELEASE_LOCK()}-Aufruf @code{NULL}
+zurückgibt, weil die Sperre @code{"lock1"} automatisch durch den zweiten
+@code{GET_LOCK()}-Aufruf aufgehoben wurde.
+
+@findex RELEASE_LOCK()
+@item RELEASE_LOCK(zeichenkette)
+Hebt die Sperre auf, die durch die Zeichenkette @code{zeichenkette} benannt
+ist, die mit @code{GET_LOCK()} erlangt wurde. Gibt @code{1} zurück, wenn
+die Sperre aufgehoben wurde, und @code{0}, wenn die Sperre nicht durch
+diesen Thread gemacht wurde (in diesem Fall wird die Sperre nicht
+aufgehoben), oder @code{NULL}, wenn die benannte Sperre nicht existiert.
+Die Sperre existiert nicht, wenn sie nie durch einen Aufruf von
+@code{GET_LOCK()} erlangt wurde oder wenn sie bereits aufgehoben wurde.
+
+@findex BENCHMARK()
+@item BENCHMARK(zaehler,ausdruck)
+Die @code{BENCHMARK()}-Funktion den Ausdruck @code{ausdruck} wiederholt
+@code{zaehler} mal aus. Sie kann benutzt werden, um die Zeit zu ermitteln,
+die MySQL benötigt, um den Ausdruck zu verarbeiten. Der Ergebniswert ist
+immer @code{0}. Die Funktion ist für die Benutzung im @code{mysql}-Client
+gedacht, der die Ausführungszeiten von Anfragen zum Beispiel wie folgt
+darstellt:
+
+@example
+mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
++----------------------------------------------+
+| BENCHMARK(1000000,encode("hello","goodbye")) |
++----------------------------------------------+
+| 0 |
++----------------------------------------------+
+1 row in set (4.74 sec)
+@end example
+
+Die berichtete Zeit ist die am Client-Ende verstrichene Zeit, nicht die
+Prozessorzeit am Server-Ende. Es ist ratsam, @code{BENCHMARK()} mehrere
+Male auszuführen und das Ergebnis unter Berücksichtigung der Last, unter
+der die Server-Maschine fährt, zu interpretieren.
+
+@findex INET_NTOA()
+@item INET_NTOA(ausdruck)
+Gibt die Netzwerk-Adresse (4 oder 8 Bytes) für den numerischen Ausdruck
+zurück:
+
+@example
+mysql> select INET_NTOA(3520061480);
+ -> "209.207.224.40"
+@end example
+
+@findex INET_ATON()
+@item INET_ATON(ausdruck)
+Gibt eine Ganzzahl zurück, die den numerischen Wert einer Netzwerk-Adresse
+darstellt. Adressen können 4-Byte- oder 8-Byte-Adressen sein:
+
+@example
+mysql> select INET_ATON("209.207.224.40");
+ -> 3520061480
+@end example
+
+Die erzeugte Zahl ist immer in Netzwerk-Byte-Reihenfolge; die obige Zahl
+wird zum Beispiel errechnet als @code{209*255^3 + 207*255^2 + 224*255
++40}.
+
+@findex MASTER_POS_WAIT()
+@item MASTER_POS_WAIT(log_name, log_position)
+Blockiert, bis der Slave während der Replikation die festgelegte Position
+in der Master-Log-Datei erreicht. Wenn die Master-Information nicht
+initialisiert wird, wird NULL zurückgegeben. Wenn der Slave nicht läuft,
+blockiert die Funktion und wartet, bis er gestartet wurde, und geht dann
+hinter die angegebene Position. Wenn der Slave bereits hinter der
+angegebenen Position ist, kehrt die Funktion sofort zurück. Der
+Rückgabewert ist die Anzahl von Log-Events, die sie warten muss, um bis zur
+angegebenen Position zu kommen, oder NULL in Fehlerfällen. Nützlich für die
+Steuerung der Master-Slave-Synchronisation, aber ursprünglich geschrieben,
+um das Testen der Replikation zu erleichtern.
+@end table
+
+
+@node Group by functions, , Other Functions, Functions
+@c German node GROUP-BY-Funktionen
+@subsection Funktionen zur Benutzung bei @code{GROUP BY}-Klauseln
+
+@findex GROUP-BY-Funktionen
+@findex Funktionen, GROUP BY
+
+Wenn Sie in einem Statement eine Gruppierungsfunktion benutzen, die
+keine @code{GROUP BY}-Klausel enthält, ist das gleichbedeutend mit der
+Gruppierung aller Zeilen.
+
+@table @code
+@findex COUNT()
+@item COUNT(ausdruck)
+Gibt die Anzahl der Zeilen mit Nicht-@code{NULL}-Werten zurück, die
+durch ein @code{SELECT}-Statement abgerufen werden:
+
+@example
+mysql> select student.student_name,COUNT(*)
+ from student,kurs
+ where student.student_id=kurs.student_id
+ GROUP BY student_name;
+
+@end example
+
+@code{COUNT(*)} ist insofern anders, als es die Anzahl der abgerufenen
+Zeilen zurückgibt, egal ob sie @code{NULL}-Werte enthalten oder nicht.
+
+@code{COUNT(*)} ist darauf optimiert, das Ergebnis sehr schnell
+zurückzugeben, wenn es mittels eines @code{SELECT} von einer Tabelle
+abruft, wenn keine weiteren Spalten abgerufen werden und es keine
+@code{WHERE}-Klausel gibt. Beispiel:
+
+@example
+mysql> select COUNT(*) from student;
+@end example
+
+@findex COUNT(DISTINCT)
+@findex DISTINCT
+@item COUNT(DISTINCT ausdruck,[ausdruck...])
+Gibt die Anzahl unterschiedlicher Nich-@code{NULL}-Werte zurück:
+
+@example
+mysql> select COUNT(DISTINCT ergebnisse) from student;
+@end example
+
+Bei MySQL erhalten Sie die Anzahl unterschiedlicher
+Ausdruckskombinationen, die nicht NULL enthalten, indem Sie eine Liste
+von Ausdrücken angeben. In ANSI-SQL müssten Sie eine Verkettung aller
+Ausdrücke innerhalb von @code{CODE(DISTINCT ..)} angeben.
+
+@findex AVG()
+@item AVG(ausdruck)
+Gibt den Durchschnittswert von @code{ausdruck} zurück:
+
+@example
+mysql> select student_name, AVG(test_ergebnis)
+ from student
+ GROUP BY student_name;
+@end example
+
+@findex MIN()
+@findex MAX()
+@item MIN(ausdruck)
+@itemx MAX(ausdruck)
+Gibt den kleinsten oder größten Wert von @code{ausdruck} zurück.
+@code{MIN()} und @code{MAX()} können Zeichenketten-Argumente aufnehmen
+und geben in solchen Fällen den kleinsten oder größten Zeichenketten-
+Wert zurück. @xref{MySQL indexes}.
+
+@example
+mysql> select student_name, MIN(test_ergebnis), MAX(test_ergebnis)
+ from student
+ GROUP BY student_name;
+@end example
+
+@findex SUM()
+@item SUM(ausdruck)
+Gibt die Summe von @code{ausdruck} zurück. Beachten Sie, dass der
+Rückgabewert NULL ist, wenn die Ergebnismenge keine Zeilen hat!
+
+@findex STD()
+@findex STDDEV()
+@cindex Oracle-Kompatibilität
+@cindex Kompatibilität, mit Oracle
+@item STD(ausdruck)
+@itemx STDDEV(ausdruck)
+Gibt die Standardabweichung von @code{ausdruck} zurück. Das ist eine
+Erweiterung zu ANSI-SQL. Die @code{STDDEV()}-Form dieser Funktion wird
+aus Gründen der Oracle-Kompatibilität zur Verfügung gestellt.
+
+@findex BIT_OR()
+@item BIT_OR(ausdruck)
+Gibt das bitweise @code{OR} aller Bits in @code{ausdruck} zurück. Die
+Berechnung wird mit 64-Bit-(@code{BIGINT})-Genauigkeit durchgeführt.
+
+@findex BIT_AND()
+@item BIT_AND(ausdruck)
+Gibt das bitweise @code{AND} aller Bits in @code{ausdruck} zurück. Die
+Berechnung wird mit 64-Bit-(@code{BIGINT})-Genauigkeit durchgeführt.
+@end table
+
+@cindex @code{GROUP BY}, Erweiterungen zu ANSI-SQL
+MySQL hat die Benutzung von @code{GROUP BY} erweitert. Sie können
+Spalten oder Berechnungen im @code{SELECT}-Ausdruck angeben, die nicht
+im @code{GROUP BY}-Teil erscheinen. Das steht für @emph{jeden möglichen
+Wert für diese Gruppe}. Das können Sie benutzen, um bessere Performance
+zu erzielen, indem Sie Sortieren und Gruppieren unnötiger Bestandteile
+vermeiden. Zum Beispiel müssen Sie in folgender Anfrage nicht nach
+@code{kunde.name} gruppieren:
+
+@example
+mysql> select bestellung.kunde_id,kunde.name,max(zahlungen)
+ from bestellung,kunde
+ where bestellung.kunde_id = kunde.kunde_id
+ GROUP BY bestellung.kunde_id;
+@end example
+
+In ANSI-SQL müssten Sie der @code{GROUP BY}-Klausel @code{kunde.name}
+hinzufügen. In MySQL ist der Name überflüßig, solange Sie nicht im
+ANSI-Modus fahren.
+
+@strong{Benutzen Sie dieses Feature nicht}, wenn die Spalten, die Sie im
+@code{GROUP BY}-Teil auslassen, in der Gruppe nicht eindeutig sind!
+Sonst erhalten Sie unvorhersagbare Ergebnisse.
+
+In einigen Fällen können Sie @code{MIN()} und @code{MAX()} benutzen, um
+einen bestimmten Spaltenwert zu erhalten, selbst wenn er nicht eindeutig
+ist. Folgendes gibt den Wert von @code{spalte} aus der Zeile zurück, die
+den kleinsten Wert in der @code{sortierung}-Spalte enthält:
+
+@example
+substr(MIN(concat(rpad(sortierung,6,' '),spalte)),7)
+@end example
+
+@node Data Manipulation, Data Definition, Functions, Reference
+@c German node Datenmanipulation
+@section Datenmanipulation: @code{SELECT}, @code{INSERT}, @code{UPDATE}, @code{DELETE}
+
+
+
+@menu
+* SELECT::
+* HANDLER::
+* INSERT::
+* INSERT DELAYED::
+* UPDATE::
+* DELETE::
+* TRUNCATE::
+* REPLACE::
+* LOAD DATA::
+@end menu
+
+@node SELECT, HANDLER, Data Manipulation, Data Manipulation
+@c German node SELECT
+@subsection @code{SELECT}-Syntax
+
+@findex SELECT
+
+@c help SELECT
+@example
+SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
+ [HIGH_PRIORITY]
+ [DISTINCT | DISTINCTROW | ALL]
+ select_ausdruck,...
+ [INTO @{OUTFILE | DUMPFILE@} 'datei' export_optionen]
+ [FROM tabellenreferenz
+ [WHERE where_definition]
+ [GROUP BY @{positive_ganzzahl | spalten_name | formel@} [ASC | DESC], ...]
+ [HAVING where_definition]
+ [ORDER BY @{positive_ganzzahl | spalten_name | formel@} [ASC | DESC] ,...]
+ [LIMIT [offset,] zeilen]
+ [PROCEDURE prozedur_name]
+ [FOR UPDATE | LOCK IN SHARE MODE]]
+@end example
+@c help end
+
+@code{SELECT} wird benutzt, um ausgewählte Zeilen aus einer oder mehreren
+Tabellen abzurufen. @code{select_ausdruck} gibt die Spalten an, die Sie
+abrufen wollen. @code{SELECT} kann auch benutzt werden, um Zeilen ohne
+Bezug zu irgend einer Tabelle abzurufen. Beispiel:
+
+@example
+mysql> SELECT 1 + 1;
+ -> 2
+@end example
+
+Alle benutzten Schlüsselwörter müssen genau in der oben angegebenen
+Reihenfolge genannt werden. Beispielsweise muss eine @code{HAVING}-Klausel
+nach jeglicher @code{GROUP BY}-Klausel und vor jeglicher @code{ORDER
+BY}-Klausel kommen.
+
+@itemize @bullet
+
+@item
+@cindex Aliase, für Ausdrücke
+@cindex Ausdruck-Aliase
+Einem @code{SELECT}-Ausdruck kann mit @code{AS} ein Alias zugewiesen
+werden. Der Alias wird als Spaltenname verwendet und kann bei @code{ORDER
+BY}- oder @code{HAVING}-Klauseln benutzt werden. Beispiel:
+
+@example
+mysql> select concat(nachname,', ',vorname) AS voller_name
+ from tabelle ORDER BY voller_name;
+@end example
+
+@item
+The @code{FROM tabellenreferenz}-Klausel gibt die Tabellen an, aus denen
+Zeilen abgerufen werden sollen. Wenn Sie mehr als eine Tabelle aufführen,
+führen Sie einen Join durch. Informationen über die Join-Syntax finden Sie
+unter @ref{JOIN, , @code{JOIN}}.
+
+@item
+Sie können auf eine Spalte als @code{spalten_name} verweisen, als
+@code{tabelle.spalten_name} oder als @code{datenbank.tabelle.spalten_name}.
+Sie müssen das @code{tabelle}- oder @code{datenbank.tabelle}-Präfix für
+einen Spaltenverweis in einem @code{SELECT}-Statement nicht angeben, es sei
+denn, der Verweis wäre ansonsten mehrdeutig. Sie @ref{Legal names}; hier
+finden sich Beispiele von Mehrdeutigkeit, die erfordern, dass Sie
+ausführlichere Spaltenverweis-Formen benutzen.
+
+@item
+@cindex Aliase, für Tabellen
+@cindex Tabellen-Aliase
+Einem Tabellenverweis kann mit @code{tabelle [AS] alias_name} ein
+Tabellen-Alias zugewiesen werden:
+
+@example
+mysql> select t1.name, t2.gehalt from angestellte AS t1, info AS t2
+ where t1.name = t2.name;
+mysql> select t1.name, t2.gehalt from angestellte t1, info t2
+ where t1.name = t2.name;
+@end example
+
+@item
+Auf Spalten, die für die Ausgabe ausgewählt wurden, kann in @code{ORDER
+BY}- und @code{GROUP BY}-Klauseln mit Spaltennamen, Spalten-Aliasen oder
+Spaltenpositionen verwiesen werden. Spaltenpositionen fangen mit 1 an:
+
+@example
+mysql> select hochschule, region, seed von tournament
+ ORDER BY region, seed;
+mysql> select hochschule, region AS r, seed AS s from turnier
+ ORDER BY r, s;
+mysql> select hochschule, region, seed from turnier
+ ORDER BY 2, 3;
+@end example
+
+Um in absteigender Reihenfolge zu sortieren, fügen Sie dem Namen der
+Spalte das @code{DESC}-Schlüsselwort in the @code{ORDER BY}-Klausel hinzu
+(descending, absteigend), nach der Sie sortieren. Die Vorgabe ist
+aufsteigende Reihenfolge. Das können Sie auch explizit angeben, indem Sie
+das @code{ASC}-Schlüsselwort verwenden.
+
+@item
+In der @code{WHERE}-Klausel können Sie beliebige Funktionen verwenden, die
+MySQL unterstützt. @xref{Functions}.
+
+@item
+Die @code{HAVING}-Klausel kann auf jede Spalte oder jeden Alias verweisen,
+die bzw. der im @code{select_ausdruck} genannt wurde. Die Klausel wird
+zuletzt angewandt, direkt bevor Ergebnisse an den Client geschickt werden,
+ohne jede Optimierung. Benutzen Sie kein @code{HAVING} für Dinge, die in
+der @code{WHERE}-Klausel stehen sollten. Schreiben Sie beispielsweise nicht
+folgendes:
+
+@example
+mysql> select spalten_name from tabelle HAVING spalten_name > 0;
+@end example
+
+Sondern statt dessen:
+
+@example
+mysql> select spalten_name from tabelle WHERE spalten_name > 0;
+@end example
+
+Ab MySQL-Version 3.22.5 können Sie Anfragen auch wie folgt schreiben:
+
+@example
+mysql> select user,max(gehalt) from benutzer
+ group by benutzer HAVING max(gehalt)>10;
+@end example
+
+In älteren MySQL-Versionen schreiben Sie statt dessen:
+
+@example
+mysql> select benutzer,max(gehalt) AS summe from benutzer
+ group by benutzer HAVING summe>10;
+@end example
+
+@item
+@code{SQL_SMALL_RESULT}, @code{SQL_BIG_RESULT}, @code{SQL_BUFFER_RESULT},
+@code{STRAIGHT_JOIN} und @code{HIGH_PRIORITY} sind MySQL Erweiterungen zu
+ANSI-SQL92.
+
+@item
+@code{HIGH_PRIORITY} gibt dem @code{SELECT} höhere Priorität als einem
+Statement, das eine Tabelle aktualisiert. Sie sollten das nur für Anfragen
+benutzen, die sehr schnell sind und sofort durchgeführt werden müssen. Eine
+@code{SELECT HIGH_PRIORITY}-Anfrage läuft, wenn die Tabelle eine
+Lese-Sperre hat, selbst wenn es ein Update-Statement gibt, das darauf
+wartet, dass die Tabelle freigegeben wird.
+
+@item
+@code{SQL_BIG_RESULT} kann bei @code{GROUP BY} oder @code{DISTINCT} benutzt
+werden, um dem Optimierer mitzuteilen, dass das Ergebnis sehr viele Zeilen
+haben wird. In diesem Fall benutzt MySQL bei Bedarf direkt
+Festplatten-basierende temporäre Tabellen. Ausserdem bevorzugt MySQL in
+diesem Fall Sortieren vor dem Anlegen einer temporären Tabelle mit einem
+Schlüssel auf den @code{GROUP BY}-Elementen.
+
+@item
+@cindex @code{GROUP BY}, Erweiterungen zu ANSI-SQL
+Wenn Sie @code{GROUP BY} benutzen, werden die Ausgabe-Zeilen gemäß dem
+@code{GROUP BY} sortiert, als hätten Sie ein @code{ORDER BY} für alle
+Felder im @code{GROUP BY} angegeben. MySQL hat @code{GROUP BY} erweitert,
+so dass Sie dafür auch @code{ASC} und @code{DESC} angeben können:
+
+@example
+SELECT a,COUNT(b) FROM tabelle GROUP BY a DESC
+@end example
+
+@item
+MySQL hat die Benutzung von @code{GROUP BY} erweitert, um es Ihnen zu
+gestatten, auch Felder auszuwählen, die nicht in der @code{GROUP
+BY}-Klausel erwähnt wurden. Wenn Sie nicht die Ergebnisse erhalten, die Sie
+von Ihrer Anfrage erwarten, lesen Sie bitte die @code{GROUP
+BY}-Beschreibung.
+
+@item
+@cindex Hinweise
+@code{SQL_BUFFER_RESULT} erzwingt, dass das Ergebnis in eine temporäre
+Tabelle geschrieben wird. Das hilft MySQL, frühzeitig Tabellensperren
+aufzuheben, und hilft in Fällen, in denen es lange dauert, das Ergebnis an
+den Client zu senden.
+
+@item
+@cindex Hinweise
+@code{SQL_SMALL_RESULT}, eine MySQL-spezifische Option, kann bei
+@code{GROUP BY} oder @code{DISTINCT} benutzt werden, um dem Optimierer
+mitzuteilen, dass der Ergebnissatz klein sein wird. In diesem Fall benutzt
+MySQL schnelle temporäre Tabellen, um die Ergebnistabelle zu speichern,
+anstatt Sortieren zu benutzen. In MySQL-Version 3.23 sollte das
+normalerweise nicht benötigt werden.
+
+@item
+@cindex Hinweise
+@code{STRAIGHT_JOIN} zwingt den Optimierer, Tabellen in der Reihenfolge zu
+verknüpfen, in der sie in der @code{FROM}-Klausel aufgelistet sind. Sie
+können das benutzen, um die Geschwindigkeit einer Anfrage zu erhöhen, wenn
+der Optimierer Tabellen in nicht optimaler Reihenfolge verknüpft.
+@xref{EXPLAIN, , @code{EXPLAIN}}.
+
+@item
+Die @code{LIMIT}-Klausel wird benutzt, um die Anzahl von Zeilen, die vom
+@code{SELECT}-Statement zurückgegeben werden, zu beschränken. @code{LIMIT}
+erwartet ein oder zwei numerische Argumente.
+
+Wenn zwei Argumente angegeben sind, legt das erste den Offset der ersten
+Zeile fest, die zurückgegeben wird, und das zweite gibt die maximale Anzahl
+von Zeilen an, die zurückgegeben werden. Der Offset der anfänglichen Zeile
+ist 0 (nicht 1):
+
+@example
+mysql> select * from tabelle LIMIT 5,10; # Zeilen 6 bis 15 zurückgeben
+@end example
+
+Wenn ein Argument angegeben wird, stellt es die maximale Anzahl von Zeilen
+dar, die zurückgegeben werden:
+
+@example
+mysql> select * from tabelle LIMIT 5; # Die ersten 5 Zeilen zurückgeben
+@end example
+
+Mit anderen Worten ist @code{LIMIT n} äquivalent zu @code{LIMIT 0,n}.
+
+@item
+@tindex /etc/passwd
+Die @code{SELECT ... INTO OUTFILE 'datei'}-Form von @code{SELECT} schreibt
+die ausgewählten Zeilen in eine Datei. Die Datei wird auf dem Server-Host
+erzeugt und darf nicht bereits bestehen (das verhindert unter anderem, dass
+Datenbanktabellen und Dateien wie @file{/etc/passwd} zerstört werden). Sie
+benötigen die @strong{file}-Berechtigung auf dem Server-Host, um diese Form
+von @code{SELECT} auszuführen.
+
+@code{SELECT ... INTO OUTFILE} ist hauptsächlich dafür vorgesehen, um eine
+Tabelle auf der Server-Maschine schnell zu dumpen. Wenn Sie die
+resultierende Datei auf einem anderen Host als dem Server-Host haben
+wollen, können Sie @code{SELECT ... INTO OUTFILE} nicht benutzen. In diesem
+Fall sollten Sie statt dessen ein Client-Programm wie @code{mysqldump
+--tab} oder @code{mysql -e "SELECT ..." > outfile} benutzen, um die Datei
+zu erzeugen.
+
+@code{SELECT ... INTO OUTFILE} ist das Komplement von @code{LOAD DATA
+INFILE}; die Syntax für den @code{export_optionen}-Teil des Statements
+besteht aus denselben @code{FIELDS}- und @code{LINES}-Klauseln, die beim
+@code{LOAD DATA INFILE}-Statement benutzt werden. @xref{LOAD DATA, ,
+@code{LOAD DATA}}.
+
+In der resultierenden Textdatei werden nur folgende Zeichen durch das
+@code{ESCAPED BY}-Zeichen escapet:
+
+@itemize @bullet
+@item Das @code{ESCAPED BY}-Zeichen
+@item Das erste Zeichen in @code{FIELDS TERMINATED BY}
+@item Das erste Zeichen in @code{LINES TERMINATED BY}
+@end itemize
+
+Zusätzlich wird @code{ASCII 0} in @code{ESCAPED BY}, gefolgt von 0
+(@code{ASCII 48}), umgewandelt.
+
+Der Grund hierfür ist, dass Sie jegliche @code{FIELDS TERMINATED BY}-,
+@code{ESCAPED BY}- oder @code{LINES TERMINATED BY}-Zeichen escapen MÜSSEN,
+um die Datei zuverlässig wieder einlesen zu können. @code{ASCII 0} wird
+escapet, um das Lesen mit einigen Pagern zu erleichtern.
+
+Weil sich die resultierende Datei nicht nach der SQL-Syntax richten muss,
+muss nicht weiter escapet werden.
+
+Im Folgenden ein Beispiel, wie man eine Datei in einem Format erhält, das
+von vielen alten Programmen benutzt wird:
+
+@example
+SELECT a,b,a+b INTO OUTFILE "/tmp/resultat.text"
+FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
+LINES TERMINATED BY "\n"
+FROM tabelle;
+@end example
+
+@item
+@findex DUMPFILE
+Wenn Sie @code{INTO DUMPFILE} anstelle von @code{INTO OUTFILE} benutzen,
+schreibt MySQL nur eine Zeile in die Datei, ohne jede Spalten- oder
+Zeilen-Begrenzer und ohne jedes Escapen. Das ist nützlich, wenn Sie ein
+Blob in eine Datei speichern wollen.
+
+@item
+Beachten Sie, dass jede Datei, die von @code{INTO OUTFILE} und @code{INTO
+DUMPFILE} erzeugt wird, für alle Benutzer lesbar ist! Der Grund liegt
+darin, dass der MySQL-Server keine Datei erzeugen kann, die jemandem
+anderen gehört als dem Benutzer, unter dem er läuft (Sie sollten
+@code{mysqld} nie als Root laufen lassen), daher muss die Datei für
+jedermann lesbar sein, damit Sie die Zeilen abrufen können.
+
+@item
+Wenn Sie @code{FOR UPDATE} bei einem Tabellen-Handler mit
+Seiten-/Zeilen-Sperren benutzen, werden die untersuchten Zeilen
+schreib-gesperrt.
+@end itemize
+
+
+
+@menu
+* JOIN::
+* UNION::
+@end menu
+
+@node JOIN, UNION, SELECT, SELECT
+@c German node JOIN
+@subsubsection @code{JOIN}-Syntax
+
+@findex JOIN
+@findex INNER JOIN
+@findex CROSS JOIN
+@findex LEFT JOIN
+@findex LEFT OUTER JOIN
+@findex NATURAL LEFT JOIN
+@findex NATURAL LEFT OUTER JOIN
+@findex RIGHT JOIN
+@findex RIGHT OUTER JOIN
+@findex NATURAL RIGHT JOIN
+@findex NATURAL RIGHT OUTER JOIN
+@findex STRAIGHT_JOIN
+
+MySQL unterstützt folgende @code{JOIN}-Syntaxen für
+@code{SELECT}-Statements:
+
+@example
+tabellen_verweis, tabellen_verweis
+tabellen_verweis [CROSS] JOIN tabellen_verweis
+tabellen_verweis INNER JOIN tabellen_verweis join_bedingung
+tabellen_verweis STRAIGHT_JOIN tabellen_verweis
+tabellen_verweis LEFT [OUTER] JOIN tabellen_verweis join_bedingung
+tabellen_verweis LEFT [OUTER] JOIN tabellen_verweis
+tabellen_verweis NATURAL [LEFT [OUTER]] JOIN tabellen_verweis
+@{ oder tabellen_verweis LEFT OUTER JOIN tabellen_verweis ON bedingungs_ausdruck @}
+tabellen_verweis RIGHT [OUTER] JOIN tabellen_verweis join_bedingung
+tabellen_verweis RIGHT [OUTER] JOIN tabellen_verweis
+tabellen_verweis NATURAL [RIGHT [OUTER]] JOIN tabellen_verweis
+@end example
+
+Wobei @code{tabellen_verweis} definiert ist als:
+@example
+tabelle [[AS] alias] [USE INDEX (schluessel_liste)] [IGNORE INDEX (schluessel_liste)]
+@end example
+
+Und @code{join_bedingung} definiert ist als:
+
+@example
+ON bedingungs_ausdruck |
+USING (spalten_liste)
+@end example
+
+Sie sollten nie irgend welche Bedingungen im @code{ON}-Teil haben, die dazu
+benutzt werden, um die Zeilen, die im Ergebnissatz auftauchen, zu
+beschränken. Wenn Sie so etwas tun wollen, müssen Sie das in der
+@code{WHERE}-Klausel tun.
+
+Beachten Sie, dass vor Version 3.23.17 @code{INNER JOIN} keine
+@code{join_bedingung} aufnahm!
+
+@cindex ODBC-Kompatibilität
+@cindex Kompatibilität, mit ODBC
+Die letzte oben dargestellte @code{LEFT OUTER JOIN}-Syntax gibt es nur aus
+Gründen der Kompatibilität mit ODBC:
+
+@itemize @bullet
+@item
+Einem Tabellenverweis kann mit @code{tabelle AS alias_name} oder
+@code{tabelle alias_name} ein Alias zugewiesen werden:
+
+@example
+mysql> select t1.name, t2.gehalt from angestellte AS t1, info AS t2
+ where t1.name = t2.name;
+@end example
+
+@item
+Der @code{ON}-Bedingungscode ist jeglicher Bedingungscode der Form, wie er
+auch in einer @code{WHERE}-Klausel benutzt werden kann.
+
+@item
+Wenn es für die rechte Tabelle keinen übereinstimmenden Datensatz im
+@code{ON}- oder @code{USING}-Teil eines @code{LEFT JOIN} gibt, wird für die
+rechte Tabelle eine Zeile benutzt, in der alle Spalten auf @code{NULL}
+gesetzt sind. Das können Sie benutzen, um Datensätze in einer Tabelle
+herauszusuchen, die in einer anderen Tabelle kein Gegenstück haben:
+
+@example
+mysql> select tabelle1.* from tabelle1
+ LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id
+ where tabelle2.id is NULL;
+@end example
+
+Dieses Beispiel findet alle Zeilen in @code{tabelle1} mit einem
+@code{id}-Wert, der in @code{tabelle2} nicht vorhanden ist (also alle
+Zeilen in @code{tabelle1} ohne entsprechende Zeile in @code{tabelle2}).
+Hierbei wird natürlich angenommen, dass @code{tabelle2.id} als @code{NOT
+NULL} deklariert ist. @xref{LEFT JOIN optimisation}.
+
+@item
+Die @code{USING}-@code{(spalten_liste)}-Klausel nennt eine Auflistung von
+Spalten, die in beiden Tabellen existieren müssen. Eine
+@code{USING}-Klausel wie:
+
+@example
+A LEFT JOIN B USING (C1,C2,C3,...)
+@end example
+
+Ist definiert als semantisch identisch mit einem @code{ON}-Ausdruck wie
+diesem:
+
+@example
+A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
+@end example
+
+@item
+Der @code{NATURAL [LEFT] JOIN} zweier Tabellen ist definiert als semantisch
+identisch äquivalent zu einem @code{INNER JOIN} oder einem @code{LEFT JOIN}
+mit einer @code{USING}-Klausel, die alle Spalten nennt, die in beiden
+Tabellen existieren.
+
+@item
+@code{RIGHT JOIN} funktioniert analog wie @code{LEFT JOIN}. Um Code
+zwischen Datenbanken portabel zu halten, wird empfohlen, @code{LEFT JOIN}
+anstelle von @code{RIGHT JOIN} zu benutzen.
+
+@item
+@cindex Hinweise
+@code{STRAIGHT_JOIN} ist identisch mit @code{JOIN}, ausser dass die linke
+Tabelle immer vor der rechten Tabelle gelesen wird. Das kann in den
+(wenigen) Fällen benutzt werden, wo der Optimierer die Tabellen in die
+falsche Reihenfolge bringt.
+
+@item
+@cindex Hinweise
+Ab MySQL-Version 3.23.12 können Sie Hinweise darüber geben, welchen Index
+MySQL benutzen sollte, wenn Informationen aus einer Tabelle abgerufen
+werden. Das ist nützlich, wenn @code{EXPLAIN} zeigt, dass MySQL den
+falschen Index benutzt. Indem Sie @code{USE INDEX (schluessel_liste)}
+angeben, können Sie MySQL anweisen, nur einen der angegebenen Indexe zu
+benutzen, um Zeilen in der Tabelle zu finden. Die alternative Syntax
+@code{IGNORE INDEX (schluessel_liste)} kann benutzt werden, um MySQL
+anzuweisen, einen bestimmten Index nicht zu benutzen.
+@end itemize
+
+Einige Beispiele:
+
+@example
+mysql> select * from tabelle1,tabelle2 where tabelle1.id=tabelle2.id;
+mysql> select * from tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id;
+mysql> select * from tabelle1 LEFT JOIN tabelle2 USING (id);
+mysql> select * from tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id
+ LEFT JOIN table3 ON tabelle2.id=table3.id;
+mysql> select * from tabelle1 USE INDEX (schluessel1,schluessel2) WHERE schluessel1=1 und schluessel2=2 AND
+ schluessel3=3;
+mysql> select * from tabelle1 IGNORE INDEX (schluessel3) WHERE schluessel1=1 und schluessel2=2 AND
+ schluessel3=3;
+@end example
+
+@xref{LEFT JOIN optimisation, , @code{LEFT JOIN}-Optimierung}.
+
+
+@node UNION, , JOIN, SELECT
+@c German node UNION
+@subsubsection @code{UNION}-Syntax
+
+@findex UNION
+
+@example
+SELECT ....
+UNION [ALL]
+SELECT ....
+ [UNION
+ SELECT ...]
+@end example
+
+@code{UNION} ist implementiert in MySQL 4.0.0.
+
+@code{UNION} wird benutzt, um das Ergebnis vieler @code{SELECT}-Statements
+in einem Ergebnissatz zu kombinieren.
+
+Die @code{SELECT}-Befehle sind normale SELECT-Befehle, aber mit folgenden
+Einschränkungen:
+
+@itemize @bullet
+@item
+Nur der letzte @code{SELECT}-Befehl darf @code{INTO OUTFILE} enthalten.
+@item
+Nur der letzte @code{SELECT}-Befehl darf @code{ORDER BY} enthalten.
+@end itemize
+
+Wenn Sie das Schlüsselwort @code{ALL} für @code{UNION} nicht benutzen, sind
+alle zurückgegebenen Zeilen eindeutig (unique), als hätten Sie ein
+@code{DISTINCT} für den gesamten Ergebnissatz gemacht. Wenn Sie @code{ALL}
+angeben, erhalten Sie alle übereinstimmenden Zeilen von allen benutzten
+@code{SELECT}-Statements.
+
+@node HANDLER, INSERT, SELECT, Data Manipulation
+@c German node INSERT
+@subsection @code{INSERT}-Syntax
+
+@findex INSERT
+
+@example
+ INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
+ [INTO] tabelle [(spalten_name,...)]
+ VALUES (ausdruck,...),(...),...
+oder INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
+ [INTO] tabelle [(spalten_name,...)]
+ SELECT ...
+oder INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
+ [INTO] tabelle
+ SET spalten_name=ausdruck, spalten_name=ausdruck, ...
+
+@end example
+
+@code{INSERT} fügt neue Zeilen in eine bestehende Tabelle ein. Die
+@code{INSERT ... VALUES}-Form des Statements fügt Zeilen basierend auf
+explizit angegebenen Werten ein. Die @code{INSERT ... SELECT}-Form fügt
+Zeilen ein, die aus einer oder mehreren anderen Tabellen ausgewählt wurden.
+Die @code{INSERT ... VALUES}-Form mit mehrfachen Wertelisten wird ab
+MySQL-Version 3.22.5 unterstützt. Die @code{spalten_name=expression}-Syntax
+wird ab MySQL-Version 3.22.10 unterstützt.
+
+@code{tabelle} ist die Tabelle, in die Zeilen eingefügt werden sollen. Die
+Spaltennamenliste oder die @code{SET}-Klausel geben an, für welche Spalten
+das Statement Werte angibt:
+
+@itemize @bullet
+@item
+Wenn Sie keine Spaltenliste für @code{INSERT ... VALUES} oder @code{INSERT
+... SELECT} angeben, müssen für alle Spalten Werte in der
+@code{VALUES()}-Liste oder vom @code{SELECT} bereit stehen. Wenn Sie die
+Reihenfolge der Tabellenspalten nicht kennen, benutzen Sie @code{DESCRIBE
+tabelle}, um sie herauszufinden.
+
+@item
+Jede Spalte, die nicht explizit in einer Werteliste angegeben wird, wird
+auf ihren Vorgabewert gesetzt. Wenn Sie beispielsweise eine Spaltenliste
+angeben, die nicht alle Tabellenspalten nennt, werden unbenannte Spalten
+auf ihre Vorgabewerte gesetzt. Die Zuweisung von Vorgabewerten ist in
+@ref{CREATE TABLE, , @code{CREATE TABLE}} beschrieben.
+
+@item
+Ein @code{ausdruck} kann sich auf jede Spalte beziehen, die vorher in einer
+Werteliste angegeben wurde. Beispielsweise können Sie folgendes eingeben:
+
+@example
+mysql> INSERT INTO tabelle (spalte1,spalte2) VALUES(15,spalte1*2);
+@end example
+
+Aber nicht das hier:
+
+@example
+mysql> INSERT INTO tabelle (spalte1,spalte2) VALUES(spalte2*2,15);
+@end example
+
+@item
+Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird die Ausführung
+von @code{INSERT} verzögert, bis kein anderer Client mehr aus der Tabelle
+liest. In diesem Fall muss der Client warten, bis das INSERT-Statement
+fertig ist, was lange Zeit dauern kann, wenn die Tabelle stark benutzt
+wird. Das ist im Gegensatz zu @code{INSERT DELAYED}, was den Client sofort
+weitermachen läßt. @xref{INSERT DELAYED}. Beachten Sie, dass
+@code{LOW_PRIORITY} normalerweise nicht bei @code{MyISAM}-Tabellen benutzt
+werden sollte, weil dadurch gleichzeitige Einfügeoperationen verhindert
+werden. @xref{MyISAM}.
+
+@item
+Wenn Sie das Schlüsselwort @code{IGNORE} in einem @code{INSERT} mit vielen
+Wertezeilen angeben, werden alle Zeilen, die einen bestehenden
+@code{PRIMARY}- oder @code{UNIQUE}-Schlüssel duplizieren würden, ignoriert
+und nicht eingefügt. Wenn Sie @code{IGNORE} nicht angeben, wird die
+Einfügeoperation abgebrochen, wenn es eine Zeile gibt, die einen
+bestehenden Schlüsselwert duplizieren würde. Mit der C-API-Funktion
+@code{mysql_info()} können Sie feststellen, wie viele Zeilen in die Tabelle
+eingefügt wurden.
+
+@item
+Wenn MySQL mit der @code{DONT_USE_DEFAULT_FIELDS}-Option konfiguriert
+wurde, erzeugen @code{INSERT}-Statements einen Fehler, wenn Sie nicht
+explizit Werte für alle Spalten angeben, die einen Nicht-@code{NULL}-Wert
+erfordern. @xref{configure options, , @code{configure}-Optionen}.
+
+@item
+Den Wert, der für eine @code{AUTO_INCREMENT}-Spalte benutzt wurde, finden
+Sie mit der @code{mysql_insert_id}-Funktion heraus. @xref{mysql_insert_id,
+, @code{mysql_insert_id()}}.
+@end itemize
+
+@findex mysql_info()
+Wenn Sie ein @code{INSERT ... SELECT}- oder ein @code{INSERT ...
+VALUES}-Statement mit mehrfachen Wertlisten benutzen, können Sie die
+C-API-Funktion @code{mysql_info()} benutzen, um Informationen über die
+Anfrage zu erhalten. Das Format der Informationszeichenkette ist unten
+dargestellt:
+
+@example
+Records: 100 Duplicates: 0 Warnings: 0
+@end example
+
+@code{Duplicates} zeigt die Anzahl von Zeilen, die nicht eingefügt werden
+konnten, weil sie einen bestehenden eindeutigen Indexwert dupliziert
+hätten. @code{Warnings} zeigen die Anzahl von Versuchen, Spaltenwerte
+einzufügen, die in irgend einer Weise problematisch waren. Warnungen
+erfolgen unter folgenden Umständen:
+
+@itemize @bullet
+@item
+Wenn @code{NULL} in eine Spalte eingefügt wird, die als @code{NOT NULL}
+deklariert ist. Die Spalte wird auf ihren Vorgabewert gesetzt.
+
+@item
+Wenn eine numerische Spalte auf einen Wert ausserhalb des Wertebereichs der
+Spalte gesetzt wird. Der Wert wird auf den entsprechenden Endpunkt des
+Bereichs abgeschnitten.
+
+@item
+Wenn eine numerische Spalte auf einen Wert wie @code{'10.34 a'} gesetzt
+wird. Die unsinnigen Zeichen am Ende werden entfernt und der verbleibende
+numerische Anteil eingefügt. Wenn der Wert als Zahl überhaupt keinen Sinn
+ergibt, wird die Spalte auf @code{0} gesetzt.
+
+@item
+Wenn eine Zeichenkette in eine @code{CHAR}-, @code{VARCHAR}-, @code{TEXT}-
+oder @code{BLOB}-Spalte eingefügt wird, die die maximale Länge der Spalte
+überschreitet. Der Wert wird auf die maximale Spaltenlänge beschnitten.
+
+@item
+Wenn ein Wert in eine DATE- oder TIME-Spalte eingefügt wird, der für den
+Spaltentyp nicht zulässig ist. Die Spalte wird auf den entsprechenden
+0-Wert für diesen Typ gesetzt.
+@end itemize
+
+@findex HANDLER
+@node INSERT, INSERT DELAYED, HANDLER, Data Manipulation
+@c German node HANDLER
+@subsection @code{HANDLER}-Syntax
+
+@example
+HANDLER tabelle OPEN [ AS alias ]
+HANDLER tabelle READ index @{ = | >= | <= | < @} (wert1, wert2, ... ) [ WHERE ... ] [LIMIT ... ]
+HANDLER tabelle READ index @{ FIRST | NEXT | PREV | LAST @} [ WHERE ... ] [LIMIT ... ]
+HANDLER tabelle READ @{ FIRST | NEXT @} [ WHERE ... ] [LIMIT ... ]
+HANDLER tabelle CLOSE
+@end example
+
+Das @code{HANDLER}-Statement ermöglicht direkten Zugriff auf die
+MySQL-Tabellenschnittstelle unter Umgehung des SQL-Optimierers. Daher ist
+es schneller als SELECT.
+
+Die erste Form des @code{HANDLER}-Statements öffnet eine Tabelle und macht
+sie über die folgenden @code{HANDLER ... READ}-Routinen zugänglich. Dieses
+Tabellenobjekt wird nicht mit anderen Threads geteilt und wird nicht
+geschlossen, bis der Thread @code{HANDLER tabelle CLOSE} aufruft oder
+stirbt.
+
+Die zweite Form holt eine (oder mehrere, festgelegt durch die
+@code{LIMIT}-Klausel) Zeile, bei der der angegebene Index mit der Bedingung
+übereinstimmt und die @code{WHERE}-Bedingung erfüllt ist. Wenn der Index
+aus mehreren Teilen besteht (also mehrere Spalten überspannt), werden die
+Werte in einer Komma-getrennten Liste angegeben, wobei es möglich ist, nur
+Werte für einige erste Spalten anzugeben.
+
+Die dritte Form holt eine (oder mehrere, festgelegt durch die
+@code{LIMIT}-Klausel) Zeile in Index-Reihenfolge aus der Tabelle, bei der
+die @code{WHERE}-Bedingung erfüllt ist.
+
+Die vierte Form (ohne Index-Angabe) holt eine (oder mehrere, festgelegt
+durch die @code{LIMIT}-Klausel) Zeile in natürlicher Zeilenreihenfolge aus
+der Tabelle (wie in der Daten-Datei gespeichert), bei der die
+@code{WHERE}-Bedingung erfüllt ist. Das ist schneller als @code{HANDLER
+tabelle READ index}, wenn ein kompletter Tabellen-Scan erwünscht ist.
+
+Die letzte Form schließt eine mit @code{HANDLER ... OPEN} geöffnete
+Tabelle.
+
+@code{HANDLER} ist in gewisser Hinsicht ein Statement auf niedriger Ebene
+(Low-Level), dass zum Beispiel keine Konsistenz gewährleistet. Das heißt,
+@code{HANDLER ... OPEN} nimmt @strong{KEINEN} Schnappschuss der Tabelle auf
+und sperrt die Tabelle @strong{NICHT}. Das bedeutet, dass nach
+@code{HANDLER ... OPEN} Tabellendaten verändert werden können (durch diesen
+oder einen anderen Thread) und dass diese Veränderungen nur teilweise in
+@code{HANDLER ... NEXT}- oder @code{HANDLER ... PREV}-Scans erscheinen.
+
+
+
+
+@findex REPLACE ... SELECT
+@findex INSERT ... SELECT
+
+
+
+@menu
+* INSERT SELECT::
+@end menu
+
+@node INSERT SELECT, , INSERT, INSERT
+@c German node INSERT SELECT
+@subsubsection @code{INSERT ... SELECT}-Syntax
+
+@example
+INSERT [LOW_PRIORITY] [IGNORE] [INTO] tabelle [(spalten_liste)] SELECT ...
+@end example
+
+Mit dem @code{INSERT ... SELECT}-Statement können Sie schnell viele Zeilen
+aus einer oder mehreren anderen Tabellen einfügen.
+
+@example
+INSERT INTO temporaere_tabelle2 (fldID) SELECT temporaere_tabelle1.fldOrder_ID FROM temporaere_tabelle1 WHERE
+temporaere_tabelle1.fldOrder_ID > 100;
+@end example
+
+Folgende Bedingungen gelten für ein @code{INSERT ... SELECT}-Statement:
+
+@c German FIX changed all @Minus to @minus
+@itemize @minus
+@item
+Die Ziel-Tabelle des @code{INSERT}-Statements darf nicht in der
+@code{FROM}-Klausel des @code{SELECT}-Teils der Anfrage erscheinen, weil es
+in ANSI-SQL verboten ist, aus derselben Tabelle auszuwählen
+(@code{SELECT}), in die eingefügt wird. (Das Problem liegt darin, dass das
+@code{SELECT} möglicherweise Datensätze finden würde, die früher während
+desselben Laufs eingefügt wurden. Wenn man Sub-Select-Klauseln verwendet,
+könnte die Situation schnell sehr verwirrend werden!)
+
+@item
+@code{AUTO_INCREMENT}-Spalten funktionieren wie gehabt.
+
+@item
+Sie können die C-API-Funktion @code{mysql_info()} benutzen, um
+Informationen über die Anfrage zu erhalten. @xref{INSERT}.
+
+@item
+Um sicherzustellen, dass die Update-Log-Datei/Binär-Log-Datei benutzt
+werden kann, um die Original-Tabellenlänge neu zu erzeugen, läßt MySQL
+während @code{INSERT .... SELECT} keine gleichzeitigen Einfügeoperationen
+zu.
+@end itemize
+
+Sie können natürlich @code{REPLACE} anstelle von @code{INSERT} benutzen, um
+alte Zeilen zu überschreiben.
+
+
+@node INSERT DELAYED, UPDATE, INSERT, Data Manipulation
+@c German node INSERT DELAYED
+@subsection @code{INSERT DELAYED}-Syntax
+
+@findex INSERT DELAYED
+@findex DELAYED
+
+@cindex INSERT DELAYED
+
+@example
+INSERT DELAYED ...
+@end example
+
+Die @code{DELAYED}-Option für das @code{INSERT}-Statement ist eine
+MySQL-spezifische Option, die sehr nützlich ist, wenn Sie Clients haben,
+die nicht warten können, bis das @code{INSERT} fertig ist. Die ist ein
+häufiges Problem, wenn Sie MySQL zum Loggen benutzen und gelegentlich
+@code{SELECT}- und @code{UPDATE}-Statements laufen lassen, die lange Zeit
+benötigen. @code{DELAYED} wurde in MySQL-Version 3.22.15 eingeführt. Es ist
+eine MySQL Erweiterung zu ANSI-SQL92.
+
+@code{INSERT DELAYED} funktioniert nur bei @code{ISAM}- und
+@code{MyISAM}-Tabellen. Beachten Sie: Weil @code{MyISAM}-Tabellen
+gleichzeitige @code{SELECT} und @code{INSERT} unterstützen, wenn es keine
+freien Blöcke mitten in der Daten-Datei gibt, müssen Sie @code{INSERT
+DELAYED} bei @code{MyISAM} nur sehr selten benutzen. @xref{MyISAM}.
+
+Wenn Sie @code{INSERT DELAYED} benutzen, erhält der Client sofort ein Okay,
+und die Zeile wird eingefügt, wenn die Tabelle nicht mehr durch einen
+anderen Thread in Benutzung ist.
+
+Ein weiterer großer Vorteil von @code{INSERT DELAYED} ist, dass
+Einfügeoperationen vieler Clients gebündelt und in einem Block geschrieben
+werden. Das ist viel schneller als viele separate Inserts durchzuführen.
+
+Beachten Sie, dass momentan die Zeilen in der Warteschlange solange nur im
+Arbeitsspeicher gehalten werden, bis sie in die Tabelle eingefügt sind. Das
+heißt, wenn Sie @code{mysqld} auf die harte Tour killen (@code{kill -9})
+oder wenn @code{mysqld} unerwartet stirbt, sind Zeilen in der
+Warteschlange, die noch nicht auf Festplatte geschrieben wurden, verloren!
+
+Im Folgenden ist detailliert beschrieben, was geschieht, wenn Sie die
+@code{DELAYED}-Option für @code{INSERT} oder @code{REPLACE} benutzen. In
+dieser Beschreibung ist der ``Thread'' der Thread, der einen @code{INSERT
+DELAYED}-Befehl empfängt. ``Handler'' ist der Thread, der alle @code{INSERT
+DELAYED}-Statements für ein bestimmte Tabelle handhabt.
+
+@itemize @bullet
+@item
+When ein Thread ein @code{DELAYED}-Statement für eine Tabelle ausführt,
+wird ein Handler-Thread erzeugt, um alle @code{DELAYED}-Statements für die
+Tabelle auszuführen, wenn ein solcher Handler nicht schon existiert.
+
+@item
+Der Thread prüft, ob der Handler bereit eine @code{DELAYED}-Sperre erhalten
+hat oder nicht. Wenn nicht, weist es den Handler-Thread an, das zu tun. Die
+@code{DELAYED}-Sperre kann selbst dann erlangt werden, wenn ein anderer
+Thread eine @code{READ}- oder @code{WRITE}-Sperre auf der Tabelle hat. Der
+Handler wartet jedoch auf alle @code{ALTER TABLE}-Sperren oder @code{FLUSH
+TABLES}, um sicherzustellen, dass die Tabellenstruktur aktuell ist.
+
+@item
+Der Thread führt das @code{INSERT}-Statement aus, aber statt die Zeile in
+die Tabelle zu schreiben stellt er eine Kopie der endgültigen Zeile in eine
+Warteschlange, die vom Handler-Thread verwaltet wird. Alle Syntaxfehler
+werden vom Thread erkannt und dem Client-Programm mitgeteilt.
+
+@item
+Der Client kann die Anzahl von Duplikaten oder den
+@code{AUTO_INCREMENT}-Wert für die resultierende Zeile nicht mitteilen. Er
+kann Sie vom Server nicht erhalten, weil das @code{INSERT} zurückkehrt,
+bevor die Einfügeoperation fertig ist. Wenn Sie die C-API benutzen, gibt
+die @code{mysql_info()}-Funktion aus demselben Grund nichts Sinnvolles
+zurück.
+
+@item
+Die Update-Log-Datei wird vom Handler-Thread aktualisiert, wenn die Zeile
+in die Tabelle eingefügt wird. Im Falle des Einfügens mehrerer Zeilen wird
+die Update-Log-Datei aktualisiert, wenn die erste Zeile eingefügt wird.
+
+@item
+Nachdem alle @code{delayed_insert_limit} Zeilen geschrieben wurden, prüft
+der Handler, ob noch irgend welche @code{SELECT}-Statements anhängig sind
+oder nicht. Falls ja, gestattet er diesen, ausgeführt zu werden, bevor
+weiter gemacht wird.
+
+@cindex delayed_insert_limit
+@cindex timeout
+@item
+Wenn der Handler keine Zeilen mehr in seiner Warteschlange hat, wird die
+Tabellensperre aufgehoben. Wenn innerhalb von @code{delayed_insert_timeout}
+Sekunden keine neuen @code{INSERT DELAYED}-Befehle mehr empfangen werden,
+beendet sich der Handler.
+
+@item
+Wenn mehr als @code{delayed_queue_size} Zeilen bereits in einer bestimmten
+Handler-Warteschlange anhängig sind, wartet der Thread, der nach
+@code{INSERT DELAYED} anfragt, bis es wieder Platz in der Warteschlange
+gibt. Damit wird sichergestellt, dass der @code{mysqld}-Server nicht den
+gesamten Arbeitsspeicher für die DELAYED-Warteschlange verbraucht.
+
+@item
+Der Handler-Thread zeigt sich in der MySQL-Prozessliste mit
+@code{delayed_insert} in der @code{Command}-Spalte. Er wird gekillt, wenn
+Sie einen @code{FLUSH TABLES}-Befehl ausführen oder ihn mit @code{KILL
+Thread_id} killen. Er wird jedoch zuerst alle Zeilen in der Warteschlange
+in die Tabelle schreiben, bevor er sich beendet. Während dieser Zeit
+akzeptiert er keine neuen @code{INSERT}-Befehle von anderen Threads mehr.
+Wenn Sie danach einen @code{INSERT DELAYED}-Befehl ausführen, wird ein
+neuer Handler-Thread erzeugt.
+
+@item
+Beachten Sie, dass oben Gesagtes bedeutet, dass @code{INSERT
+DELAYED}-Befehle höhere Priorität haben als normale @code{INSERT}-Befehle,
+wenn es einen @code{INSERT DELAYED}-Handler gibt, der bereits läuft!
+Andere Aktualisierungsbefehle müssen warten, bis die @code{INSERT
+DELAYED}-Warteschlange leer ist, jemand den Handler-Thread killt (mit
+@code{KILL Thread_id}) oder jemand @code{FLUSH TABLES} ausführt.
+
+@item
+Die folgenden Status-Variablen stellen Informationen über @code{INSERT
+DELAYED}-Befehle bereits:
+
+@multitable @columnfractions .35 .65
+@item @strong{Variable} @tab @strong{Bedeutung}
+@item @code{Delayed_insert_thread} @tab Nummer des Handler-Threads
+@item @code{Delayed_writes} @tab Anzahl der Zeilen, die mit @code{INSERT DELAYED} geschrieben wurden
+@item @code{Not_flushed_delayed_rows} @tab Anzahl der Zeilen, die darauf warten, geschrieben zu werden
+@end multitable
+
+Sie können diese Variablen betrachten, wenn Sie ein @code{SHOW
+STATUS}-Statement oder einen @code{mysqladmin extended-status}-Befehl
+ausführen.
+@end itemize
+
+Beachten Sie, dass @code{INSERT DELAYED} langsamer ist als ein normales
+INSERT, wenn die Tabelle nicht in Benutzung ist. Ausserdem gibt es einen
+zusätzlichen Overhead für den Server, um einen separaten Thread für jede
+Tabelle zu handhaben, für die Sie @code{INSERT DELAYED} benutzen. Das
+heißt, Sie sollten @code{INSERT DELAYED} nur benutzen, wenn Sie es
+wirklich benötigen!
+
+
+@node UPDATE, DELETE, INSERT DELAYED, Data Manipulation
+@c German node UPDATE
+@subsection @code{UPDATE}-Syntax
+
+@findex UPDATE
+
+@example
+UPDATE [LOW_PRIORITY] [IGNORE] tabelle
+ SET spalten_name1=ausdruck1, [spalten_name2=ausdruck2, ...]
+ [WHERE where_definition]
+ [LIMIT #]
+@end example
+
+@code{UPDATE} aktualisiert Spalten in bestehenden Tabellenzeilen mit neuen
+Werten. Die @code{SET}-Klausel gibt an, welche Spalten geändert werden
+sollen und welche Werte ihnen zugewiesen werden. Die @code{WHERE}-Klausel
+legt - falls angegeben - fest, welche Zeilen aktualisiert werden sollen.
+Ansonsten werden alle Zeile aktualisiert. Wenn die @code{ORDER BY}-Klausel
+angegeben ist, werden die Zeilen in der angegebenen Reihenfolge
+aktualisiert.
+
+Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird die Ausführung
+von @code{UPDATE} verzögert, bis keine anderen Clients mehr aus der Tabelle
+lesen.
+
+Wenn Sie das Schlüsselwort @code{IGNORE} angeben, bricht das
+UPDATE-Statement nicht ab, selbst wenn während der Aktualisierung Fehler
+wegen doppelter Schlüsseleinträge auftreten. Zeilen, die Konflikte
+verursachen würden, werden nicht aktualisiert.
+
+Wenn Sie auf eine Spalte von @code{tabelle} in einem Ausdruck zugreifen,
+benutzt @code{UPDATE} den momentanen Wert der Spalte. Folgendes Statement
+zum Beispiel setzt die @code{age}-Spalte auf ihren momentanen Wert plus 1:
+
+@example
+mysql> UPDATE personen SET age=age+1;
+@end example
+
+@code{UPDATE}-Zuweisungen werden von links nach rechts ausgewertet.
+Folgendes Statement zum Beispiel verdoppelt die @code{age}-Spalte und
+inkrementiert sie danach:
+
+@example
+mysql> UPDATE personen SET age=age*2, age=age+1;
+@end example
+
+Wenn Sie eine Spalte auf einen Wert setzen, den sie momentan besitzt,
+erkennt MySQL dies und aktualisiert sie nicht.
+
+@findex mysql_info()
+@code{UPDATE} gibt die Anzahl von Zeilen zurück, die tatsächlich geändert
+wurden. Ab MySQL-Version 3.22 gibt die C-API-Funktion @code{mysql_info()}
+die Anzahl von Zeilen zurück, die übereinstimmten und aktualisiert wurden,
+und die Anzahl von Warnungen, die während @code{UPDATE} geschahen.
+
+In MySQL-Version 3.23 können Sie @code{LIMIT #} benutzen, um
+sicherzustellen, dass nur eine angegebene Anzahl von Zeilen geändert wird.
+
+
+@node DELETE, TRUNCATE, UPDATE, Data Manipulation
+@c German node DELETE
+@subsection @code{DELETE}-Syntax
+
+@findex DELETE
+
+@example
+DELETE [LOW_PRIORITY | QUICK] FROM tabelle
+ [WHERE where_definition]
+ [ORDER BY ...]
+ [LIMIT zeilen]
+
+oder
+
+DELETE [LOW_PRIORITY | QUICK] tabelle[.*] [tabelle[.*] ...] FROM
+tabellenverweis [WHERE where_definition]
+@end example
+
+@code{DELETE} löscht Zeilen aus @code{tabelle}, die mit der in
+@code{where_definition} angegebenen Bedingung übereinstimmen, und gibt die
+Anzahl der gelöschten Datensätze zurück.
+
+Wenn Sie @code{DELETE} ohne @code{WHERE}-Klausel angeben, werden alle
+Zeilen gelöscht. Wenn Sie das im @code{AUTOCOMMIT}-Modus machen,
+funktioniert es wie @code{TRUNCATE}. @xref{TRUNCATE}. In MySQL 3.23 gibt
+@code{DELETE} ohne eine @code{WHERE}-Klausel als Anzahl von betroffenen
+Datensätzen 0 zurück.
+
+Wenn Sie wissen wollen, wie viele Datensätze tatsächlich gelöscht wurden,
+wenn Sie alle Zeilen löschen, und eine Geschwindigkeitseinbusse in Kauf
+nehmen, können Sie ein @code{DELETE}-Statement folgender Form eingeben:
+
+@example
+mysql> DELETE FROM tabelle WHERE 1>0;
+@end example
+
+Beachten Sie, dass das VIEL langsamer als @code{DELETE FROM tabelle} ohne
+@code{WHERE}-Klausel ist, weil es Zeilen eine nach der anderen löscht.
+
+Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird die Ausführung
+von @code{DELETE} verzögert, bis kein anderer Client mehr aus der Tabelle
+liest.
+
+Wenn Sie das Wort @code{QUICK} angeben, fasst der Tabellen-Handler während
+des Löschvorgangs keine Index-Blätter (Index Leafs) zusammen, was bestimmte
+Arten von Löschvorgängen beschleunigen kann.
+
+In MyISAM-Tabellen werden gelöschte Datensätze in einer verknüpften Liste
+verwaltet und nachfolgende @code{INSERT}-Operationen benutzen alte
+Datensatzpositionen neu. Um unbenutzten Platz freizugeben und Dateigrößen
+zu verringern, benutzen Sie das @code{OPTIMIZE TABLE}-Statement oder das
+@code{myisamchk}-Dienstprogramm, um die Tabellen neu zu organisieren.
+@code{OPTIMIZE TABLE} ist einfacher, aber @code{myisamchk} ist schneller.
+Siehe @ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} und @ref{Optimisation}.
+
+Das Multi-Tabellen-Löschformat wird ab MySQL 4.0.0 unterstützt.
+
+Die Idee ist, dass nur übereinstimmende Zeilen aus den Tabellen, die VOR
+der @code{FROM}-Klausel stehen, gelöscht werden. Die Auswirkung ist, dass
+Sie Zeilen aus vielen Tabellen zugleich löschen können, sowie dass
+zusätzliche Tabellen zum Suchen benutzt werden.
+
+Das @code{.*}-Zeichen nach den Tabellennamen ist nur aus Gründen der
+Kompatibilität mit @code{Access} vorhanden:
+
+@example
+DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
+@end example
+
+In diesem Fall werden übereinstimmende Zeilen nur aus den Tabellen
+@code{t1} und @code{t2} gelöscht.
+
+@code{ORDER BY} und Benutzung mehrfacher Tabellen bei DELETE wird in MySQL
+4.0 unterstützt.
+
+Wenn eine @code{ORDER BY}-Klausel benutzt wird, werden die Zeilen in dieser
+Reihenfolge gelöscht. Das ist nur in Verbindung mit @code{LIMIT} wirklich
+sinnvoll. Beispiel:
+
+@example
+DELETE FROM logdatei
+WHERE user = 'jcole'
+ORDER BY zeitstempel
+LIMIT 1
+@end example
+
+Das löscht den ältesten Eintrag (von @code{zeitstempel}), wo die Zeile mit
+der @code{WHERE}-Klausel übereinstimmt.
+
+Die MySQL-spezifische @code{LIMIT rows}-Option für @code{DELETE} weist den
+Server an, welche maximale Anzahl von Zeilen gelöscht wird, bevor die
+Kontrolle an den Client zurück gegeben wird. Das kann benutzt werden um
+sicherzustellen, dass ein bestimmter @code{DELETE}-Befehl nicht zu viel
+Zeit beansprucht. Sie können den @code{DELETE}-Befehl einfach wiederholen,
+bis die Anzahl betroffener Zeilen kleiner ist als der @code{LIMIT}-Wert.
+
+
+@node TRUNCATE, REPLACE, DELETE, Data Manipulation
+@c German node TRUNCATE
+@subsection @code{TRUNCATE}-Syntax
+
+@findex TRUNCATE
+
+@example
+TRUNCATE TABLE tabelle
+@end example
+
+In Version 3.23 wird @code{TRUNCATE TABLE} auf @code{COMMIT ; DELETE FROM
+tabelle} gemappt. @xref{DELETE}.
+
+Die Unterschiede zwischen @code{TRUNCATE TABLE} und @code{DELETE FROM ..}
+sind:
+
+@itemize @bullet
+@item
+TRUNCATE führt ein Löschen und Neuerzeugen der Tabelle durch, was viel
+schneller sit, als Zeilen eine nach der anderen zu löschen.
+@item
+Nicht transaktionssicher. Sie erhalten einen Fehler, wenn Sie eine aktive
+Transaktion haben oder eine aktive Tabellensperre.
+@item
+Gibt die Anzahl gelöschter Zeilen nicht zurück.
+@item
+Solange die Tabellendefinitionsdatei @file{tabelle.frm} gültig ist, kann
+die Tabelle auf diese Weise neu erzeugt werden, selbst wenn die Daten- oder
+Index-Dateien beschädigt wurden.
+@end itemize
+
+@code{TRUNCATE} ist eine Oracle-SQL-Erweiterung.
+
+@node REPLACE, LOAD DATA, TRUNCATE, Data Manipulation
+@c German node REPLACE
+@subsection @code{REPLACE}-Syntax
+
+@findex REPLACE
+
+@example
+ REPLACE [LOW_PRIORITY | DELAYED]
+ [INTO] tabelle [(spalten_name,...)]
+ VALUES (ausdruck,...),(...),...
+or REPLACE [LOW_PRIORITY | DELAYED]
+ [INTO] tabelle [(spalten_name,...)]
+ SELECT ...
+or REPLACE [LOW_PRIORITY | DELAYED]
+ [INTO] tabelle
+ SET spalten_name=ausdruck, spalten_name=ausdruck,...
+@end example
+
+@code{REPLACE} funktioniert genau wie @code{INSERT}, ausser dass der alte
+Datensatz gelöscht wird, bevor ein neuer eingefügt wird, wenn ein alter
+Datensatz in der Tabelle denselben Wert wie der neue auf einem eindeutigen
+Index hat. @xref{INSERT, , @code{INSERT}}.
+
+Mit anderen Worten können Sie auf die Werte einer alten Zeile nicht mit
+einem @code{REPLACE}-Statement zugreifen. In einigen alten MySQL-Versionen
+sah es so aus, als könnten Sie das tun, aber das war ein Bug und wurde
+korrigiert.
+
+Wenn man einen @code{REPLACE}-Befehl benutzt, gibt
+@code{mysql_affected_rows()} 2 zurück, wenn die neue Zeile eine alte
+ersetzte. Das liegt daran, dass in diesem Fall eine Zeile eingefügt wurde
+und dann das Duplikat gelöscht wurde.
+
+Das macht es einfach zu überprüfen, ob @code{REPLACE} eine Zeile
+hinzugefügt oder eine ersetzt hat.
+
+
+@node LOAD DATA, , REPLACE, Data Manipulation
+@c German node LOAD DATA
+@subsection @code{LOAD DATA INFILE}-Syntax
+
+@findex LOAD DATA INFILE
+
+@example
+LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'datei.txt'
+ [REPLACE | IGNORE]
+ INTO TABLE tabelle
+ [FIELDS
+ [TERMINATED BY '\t']
+ [[OPTIONALLY] ENCLOSED BY '']
+ [ESCAPED BY '\\' ]
+ ]
+ [LINES TERMINATED BY '\n']
+ [IGNORE Anzahl LINES]
+ [(spalten_name,...)]
+@end example
+
+Das @code{LOAD DATA INFILE}-Statement liest Zeilen aus einer Textdatei in
+eine Tabelle mit sehr hoher Geschwindigkeit. Wenn das
+@code{LOCAL}-Schlüsselwort angegeben wird, wird die Datei vom Client-Host
+gelesen. Wenn @code{LOCAL} nicht angegeben wird, muss die Datei auf dem
+Server liegen. (@code{LOCAL} ist verfügbar ab MySQL-Version 3.22.6.)
+
+Aus Sicherheitsgründen müssen Dateien, die als auf dem Server liegende
+Textdateien eingelesen werden, entweder im Datenbank-Verzeichnis liegen
+oder von allen lesbar sein. Darüber hinaus brauchen Sie, wenn Sie
+@code{LOAD DATA INFILE} mit Server-Dateien benutzen, die
+@strong{file}-Berechtigung auf dem Server-Host. @xref{Privileges}.
+
+Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird das
+@code{LOAD DATA}-Statement verzögert, bis keine anderen Clients mehr aus
+der Tabelle lesen.
+
+Wenn Sie das Schlüsselwort @code{CONCURRENT} bei einer
+@code{MyISAM}-Tabelle angeben, können andere Threads Daten aus der Tabelle
+abrufen, während @code{LOAD DATA} ausgeführt wird. Die Benutzung dieser
+Option beeinflusst natürlich die Performance von @code{LOAD DATA} ein
+bisschen, selbst wenn kein anderer Thread die Tabelle zur gleichen Zeit
+benutzt.
+
+@code{LOCAL} ist etwas langsamer, als wenn der Server direkt auf die
+Dateien zugreifen kann, weil die Inhalte der Datei vom Client-Host auf den
+Server-Host übertragen werden müssen. Auf der anderen Seite benötigen Sie
+keine @strong{file}-Berechtigung, um lokale Dateien zu laden.
+
+@c old version
+Wenn Sie MySQL vor Version 3.23.24 benutzen, können Sie nicht aus einer
+FIFO lesen, wenn Sie @code{LOAD DATA INFILE} benutzen. Wenn Sie aus einer
+FIFO lesen müssen (zum Beispiel aus der Ausgabe von gunzip), benutzen Sie
+statt dessen @code{LOAD DATA LOCAL INFILE}.
+
+@cindex @code{mysqlimport}
+Sie können Daten-Dateien auch mit dem @code{mysqlimport}-Dienstprogramm
+laden; es arbeitet, indem es einen @code{LOAD DATA INFILE}-Befehl an den
+Server schickt. Die @code{--local}-Option veranlasst @code{mysqlimport},
+Daten-Dateien vom Client-Host zu lesen. Sie können die
+@code{--compress}-Option angeben, um bessere Performance über langsame
+Netzwerke zu erzielen, wenn der Client und der Server das komprimierte
+Protokoll unterstützen.
+
+Bei der Suche nach Dateien auf dem Server-Host geht der Server nach
+folgenden Regeln vor:
+
+@itemize @bullet
+@item
+Wenn ein absoluter Pfadname angegeben wird, benutzt der Server den
+Pfadnamen so, wie er ist.
+
+@item
+Wenn ein relativer Pfadname mit einer oder mehreren führenden Bestandteilen
+angegeben wird, sucht der Server die Datei relativ zum Daten-Verzeichnis
+des Servers.
+
+@item
+Wenn ein Dateiname ohne führende Bestandteile angegeben wird, sucht der
+Server die Datei im Datenbank-Verzeichnis der aktuellen Datenbank.
+@end itemize
+
+Beachten Sie, dass diese Regeln bedeuten, dass eine Datei, die als
+@file{./meinedatei.txt} angegeben wird, aus dem Daten-Verzeichnis des
+Servers gelesen wird, wohingegen eine Datei, die als @file{meinedatei.txt}
+angegeben wird, aus dem Datenbank-Verzeichnis der aktuellen Datenbank
+gelesen wird. Das folgende @code{LOAD DATA}-Statement beispielsweise liest
+die Datei @file{daten.txt} aus dem Datenbank-Verzeichnis von
+@code{datenbank1}, weil @code{datenbank1} die aktuelle Datenbank ist,
+obwohl das Statement die Datei explizit in eine Tabelle in der
+@code{datenbank2}-Datenbank lädt:
+
+@example
+mysql> USE datenbank1;
+mysql> LOAD DATA INFILE "daten.txt" INTO TABLE datenbank2.meine_tabelle;
+@end example
+
+Die @code{REPLACE}- und @code{IGNORE}-Schlüsselwörter steuern die
+Handhabung von Eingabe-Datensätzen, die bestehende Datensätze auf
+eindeutigen Schlüsselwerten duplizieren. Wenn Sie @code{REPLACE} angeben,
+ersetzen neue Zeilen bestehende Zeilen, die denselben eindeutigen
+Schlüsselwert besitzen. Wenn Sie @code{IGNORE} angeben, werden
+Eingabe-Zeilen, die eine bestehende Zeile auf einem Schlüsselwert
+duplizieren, übersprungen. Wenn Sie keine der beiden Optionen angeben,
+tritt ein Fehler auf, wenn ein doppelter Schlüsselwert gefunden wird, und
+der Rest der Textdatei wird ignoriert.
+
+Wenn Sie Daten aus einer lokalen Datei mit dem @code{LOCAL}-Schlüsselwort
+laden, hat der Server keine Möglichkeit, die Übertragung der Datei mitten
+in einer Operation zu beenden. Daher ist das vorgabemäßige Verhalten
+dasselbe, als wenn @code{IGNORE} angegeben wäre.
+
+Wenn Sie @code{LOAD DATA INFILE} auf einer leeren @code{MyISAM}-Tabelle
+benutzen, werden alle nicht eindeutigen Indexe in einem separaten Stapel
+erzeugt (wie bei @code{REPAIR}). Das macht @code{LOAD DATA INFILE}
+normalerweise viel schneller, wenn Sie viele Indexe haben.
+
+@code{LOAD DATA INFILE} ist das Komplement von @code{SELECT ... INTO OUTFILE}.
+@xref{SELECT, , @code{SELECT}}. Um Daten aus einer Datenbank in eine Datei
+zu schreiben, benutzen Sie @code{SELECT ... INTO OUTFILE}. Um die Datei
+zurück in die Datenbank zu lesen, benutzen Sie @code{LOAD DATA INFILE}. Die
+Syntax der @code{FIELDS}- und @code{LINES}-Klauseln ist für beide Befehle
+dieselbe. Beide Klauseln sind optional, aber @code{FIELDS} muss
+@code{LINES} vorangehen, wenn beide angegeben werden.
+
+Wenn Sie eine @code{FIELDS}-Klausel angeben, ist jede ihrer Unterklauseln
+(@code{TERMINATED BY}, @code{[OPTIONALLY] ENCLOSED BY} und @code{ESCAPED
+BY}) ebenfalls optional, ausser dass Sie zumindest eine von ihnen angeben
+müssen.
+
+Wenn Sie keine @code{FIELDS}-Klausel benutzen, sind die Vorgabewerte
+dieselben, als wenn Sie folgendes geschrieben hätten:
+
+@example
+FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
+@end example
+
+Wenn Sie keine @code{LINES}-Klausel angeben, sind die Vorgabewerte
+dieselben, als wenn Sie folgendes geschrieben hätten:
+
+@example
+LINES TERMINATED BY '\n'
+@end example
+
+Mit anderen Worten veranlassen die Vorgabewerte @code{LOAD DATA INFILE},
+beim Lesen von Eingaben wie folgt zu arbeiten:
+
+@itemize @bullet
+@item
+Zeilenbegrenzungen werden an Neue-Zeile-Zeichen gesucht (\n).
+
+@item
+Zeilen werden an Tabulatoren (\t) in Felder aufgeteilt.
+
+@item
+Es wird nicht davon ausgegangen, dass Felder in Anführungszeichen
+eingeschlossen sind.
+
+@item
+Tabulatoren, Neue-Zeile-Zeichen oder @samp{\}, denen ein @samp{\}-Zeichen
+voran gestellt ist, werden als Literale interpretiert, die Teil des
+Feldwerts sind.
+@end itemize
+
+Im Vergleich dazu veranlassen die Vorgabewerte von @code{SELECT ... INTO
+OUTFILE} dieses, wie folgt zu arbeiten:
+
+@itemize @bullet
+@item
+Zwischen Felder werden Tabulatoren (\t) geschrieben.
+
+@item
+Felder werden nicht in Anführungsstriche geschrieben.
+
+@item
+@samp{\} wird benutzt, um Tabulator, Neue-Zeile-Zeichen oder @samp{\}
+innerhalb von Feldwerten zu escapen.
+
+@item
+Am Ende von Zeilen werden Neue-Zeile-Zeichen (\n) geschrieben.
+@end itemize
+
+Beachten Sie, dass Sie @code{FIELDS ESCAPED BY '\\'} (mit zwei Backslashes)
+schreiben müssen, damit der Wert als ein einzelner Backslash gelesen wird.
+
+Die @code{IGNORE anzahl LINES}-Option kann benutzt werden, um eine
+Kopfzeile aus Spaltennamen am Anfang der Datei zu ignorieren:
+
+@example
+mysql> LOAD DATA INFILE "/tmp/datei.txt" into Tabelle test IGNORE 1 LINES;
+@end example
+
+Wenn Sie @code{SELECT ... INTO OUTFILE} zusammen mit @code{LOAD DATA
+INFILE} benutzen, um Daten aus einer Datenbank in eine Datei zu schreiben
+und dann die Datei später zurück in die Datenbank zu lesen, müssen die
+Optionen für die Behandlung von Feldern und Zeilen für beide Befehle
+übereinstimmen. Ansonsten interpretiert @code{LOAD DATA INFILE} die Inhalte
+der Datei nicht korrekt. Angenommen, Sie benutzen @code{SELECT ... INTO
+OUTFILE}, um eine Datei zu schreiben, deren Feldern durch Kommas begrenzt
+sind:
+
+@example
+mysql> SELECT * INTO OUTFILE 'daten.txt'
+ FIELDS TERMINATED BY ','
+ FROM ...;
+@end example
+
+Um die Komma-begrenzte Datei wieder einzulesen, lautet das korrekte
+Statement:
+
+@example
+mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle2
+ FIELDS TERMINATED BY ',';
+@end example
+
+Wenn Sie statt dessen versuchen, die Datei mit dem unten stehenden
+Statement einzulesen, funktioniert das nicht, weil es @code{LOAD DATA
+INFILE} anweist, nach Tabulatoren zwischen Feldern zu suchen:
+
+@example
+mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle2
+ FIELDS TERMINATED BY '\t';
+@end example
+
+Das wahrscheinliche Ergebnis ist, dass jede Eingabezeile als ein einzelnes
+Feld interpretiert wird.
+
+@code{LOAD DATA INFILE} kann auch benutzt werden, um Dateien aus externen
+Quellen einzulesen. Eine Datei im dBASE-Format zum Beispiel hat Felder, die
+durch Kommas getrennt und in Anführungszeichens eingeschlossen sind. Wenn
+Zeilen in der Datei von Neue-Zeile-Zeichen begrenzt sind, zeigt der unten
+stehende Befehl die Feld- und Zeilen-Handhabungsoptionen, die für das Laden
+der Datei benutzt werden:
+
+@example
+mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle
+ FIELDS TERMINATED BY ',' ENCLOSED BY '"'
+ LINES TERMINATED BY '\n';
+@end example
+
+Jede der Feld- oder Zeilen-Handhabungsoptionen kann eine leere Zeichenkette
+angeben (@code{''}). Wenn nicht leer, müssen die @code{FIELDS [OPTIONALLY]
+ENCLOSED BY}- und @code{FIELDS ESCAPED BY}-Werte ein einzelnes Zeichen
+sein. Die @code{FIELDS TERMINATED BY}- und @code{LINES TERMINATED BY}-Werte
+können aus mehr als einem Zeichen bestehen. Um zum Beispiel Zeilen zu
+schreiben, die durch Wagenrücklauf-Neue-Zeile-Paare getrennt sind, oder um
+eine Datei einzulesen, die solche Zeilen enthält, geben Sie eine
+@code{LINES TERMINATED BY '\r\n'}-Klausel an.
+
+Um beispielsweise eine Datei mit Witzen einzulesen, die durch @code{%%}
+getrennt sind, können Sie folgendes eingeben:
+
+@example
+create table witze (a int not null auto_increment primary key, witz text not null);
+load data infile "/tmp/witze.txt" into table witze fields terminated by "" lines terminated by "\n%%\n" (witz);
+@end example
+
+@code{FIELDS [OPTIONALLY] ENCLOSED BY} steuert die Art von
+Anführungszeichen von Feldern. Wenn Sie bei der Ausgabe (@code{SELECT ...
+INTO OUTFILE}) das Wort @code{OPTIONALLY} auslassen, sind alle Felder vom
+@code{ENCLOSED BY}-Zeichen eingeschlossen. Ein Beispiel einer solchen
+Ausgabe (mit Kommas als Feldbegrenzern) ist unten dargestellt:
+
+@example
+"1","eine Zeichenkette","100.20"
+"2","eine Zeichenkette, die ein Komma (,) enthält","102.20"
+"3","eine Zeichenkette, die ein \" Anführungszeichen enthält","102.20"
+"4","eine Zeichenkette, die ein \", Anführungszeichen und Komma (,) enthält","102.20"
+@end example
+
+Wenn Sie @code{OPTIONALLY} angeben, wird das @code{ENCLOSED BY}-Zeichen nur
+benutzt, um @code{CHAR}- und @code{VARCHAR}-Felder zu umschließen:
+
+@example
+1,"eine Zeichenkette",100.20
+2,"eine Zeichenkette mit einem , Komma",102.20
+3,"eine Zeichenkette mit einem \" Anführungszeichen",102.20
+4,"eine Zeichenkette mit \", Anführungszeichen und Komma",102.20
+@end example
+
+Beachten Sie, dass @code{ENCLOSED BY}-Zeichen innerhalb eines Feldwerts
+escapet werden, indem ihnen das @code{ESCAPED BY}-Zeichen vorangestellt
+wird. Beachten Sie auch, dass es bei der Angabe eines leeren empty
+@code{ESCAPED BY}-Werts möglich ist, Ausgaben zu erzeugen, die nicht
+korrekt von @code{LOAD DATA INFILE} eingelesen werden können. Die oben
+dargestellte Ausgabe zum Beispiel würde wie im Folgenden gezeigt
+erscheinen, wenn das Fluchtzeichen (Escape-Zeichen) leer ist. Beachten Sie,
+dass das zweite Feld der vierten Zeile nach dem Anführungszeichen ein Komma
+enthält, was (irrtümlich) als Feldbegrenzer interpretiert wird:
+
+@example
+1,"eine Zeichenkette",100.20
+2,"eine Zeichenkette mit einem , Komma",102.20
+3,"eine Zeichenkette mit einem " Anführungszeichen",102.20
+4,"eine Zeichenkette mit ", Anführungszeichen und Komma",102.20
+@end example
+
+Für die Eingabe wird das @code{ENCLOSED BY}-Zeichen - falls vorhanden - vom
+Ende von Feldwerten entfernt. (Das gilt, egal ob @code{OPTIONALLY}
+angegeben ist oder nicht; @code{OPTIONALLY} hat keine Auswirkung auf die
+Interpretation der Eingabe.) @code{ENCLOSED BY}-Zeichen, denen das
+@code{ESCAPED BY}-Zeichen vorangestellt ist, werden als Teil des aktuellen
+Feldwerts interpretiert. Zusätzlich werden verdoppelte @code{ENCLOSED
+BY}-Zeichen innerhalb von Feldern als ein einzelnes @code{ENCLOSED
+BY}-Zeichen interpretiert, falls das Feld selbst mit diesem Zeichen
+anfängt. Wenn beispielsweise @code{ENCLOSED BY '"'} angegeben wird, werden
+Anführungszeichen wie folgt behandelt:
+
+@example
+"Der ""BIG"" Boss" -> Der "BIG" Boss
+Der "BIG" Boss -> Der "BIG" Boss
+Der ""BIG"" Boss -> Der ""BIG"" Boss
+@end example
+
+@code{FIELDS ESCAPED BY} steuert, wie Sonderzeichen geschrieben oder
+gelesen werden. Wenn das @code{FIELDS ESCAPED BY}-Zeichen nicht leer ist,
+wird es benutzt, um es bei der Ausgabe folgenden Zeichen voranzustellen:
+@itemize @bullet
+@item
+Dem @code{FIELDS ESCAPED BY}-Zeichen
+@item
+Dem @code{FIELDS [OPTIONALLY] ENCLOSED BY}-Zeichen
+@item
+Dem ersten Zeichen von @code{FIELDS TERMINATED BY}- und @code{LINES
+TERMINATED BY}-Werten
+@item
+ASCII @code{0} (was tatsächlich nach dem Fluchtzeichen (Escape-Zeichen)
+als ASCII @code{'0'} geschrieben wird, nicht ein Byte mit Wert 0)
+@end itemize
+
+Wenn das @code{FIELDS ESCAPED BY}-Zeichen leer ist, werden keine Zeichen
+escapet. Es ist wahrscheinlich keine gute Idee, ein leeres Fluchtzeichen
+(Escape-Zeichen) anzugeben, insbesondere, wenn Feldwerte in Ihren Daten
+irgend welche der Zeichen enthalten, die gerade aufgelistet wurden.
+
+Für die Eingabe werden, falls das @code{FIELDS ESCAPED BY}-Zeichen nicht
+leer ist, Vorkommen dieses Zeichens entfernt, und die folgenden Zeichen
+werden buchstäblich als Teil des Feldwerts genommen. Die Ausnahmen sind ein
+escapetes @samp{0} oder @samp{N} (beispielsweise @code{\0} oder @code{\N},
+wenn das Fluchtzeichen (Escape-Zeichen) @samp{\} ist). Diese Folgen werden
+als ASCII-@code{0} interpretiert (ein Byte mit Wert 0) und @code{NULL}.
+Siehe unten zu den Regeln der @code{NULL}-Handhabung.
+
+Weitere Informationen über die @samp{\}-Escape-Syntax finden Sie unter
+@ref{Literals}.
+
+In bestimmten Fällen beeinflussen sich die Handhabungsoptionen für Felder
+und Zeilen gegenseitig:
+
+@itemize @bullet
+@item
+Wenn @code{LINES TERMINATED BY} eine leere Zeichenkette ist und
+@code{FIELDS TERMINATED BY} nicht leer ist, werden Zeile auch durch
+@code{FIELDS TERMINATED BY} begrenzt.
+@item
+Wenn die @code{FIELDS TERMINATED BY}- und @code{FIELDS ENCLOSED BY}-Werte
+beide leer sind (@code{''}), wird ein Festzeilen- (nicht begrenztes) Format
+benutzt. Beim Festzeilenformat werden keine Begrenzer zwischen Feldern
+benutzt. Statt dessen werden Spaltenwerte geschrieben und gelesen, indem
+die Anzeigebreite der Spalten benutzt wird. Wenn eine Spalte zum Beispiel
+als @code{INT(7)} deklariert ist, werden Werte für die Spalte mit
+7-Zeichen-Feldern geschrieben. Bei der Eingabe werden Werte für die Spalte
+mit 7-Zeichen-Feldern bezogen. Festzeilenformate beeinflussen auch die
+Handhabung von @code{NULL}-Werten (siehe unten). Beachten Sie, dass
+Festgrößenformate nicht funktionieren, wenn Sie einen
+Multi-Byte-Zeichensatz benutzen.
+@end itemize
+
+Die Handhabung von @code{NULL}-Werten variiert in Abhängigkeit von den
+@code{FIELDS}- und @code{LINES}-Optionen, die Sie benutzen:
+
+@itemize @bullet
+@item
+Bei den vorgabemäßigen @code{FIELDS}- und @code{LINES}-Werten wird
+@code{NULL} für die Ausgabe als @code{\N} geschrieben und @code{\N} als
+@code{NULL} für die Eingabe gelesen (unter der Annahme, dass das
+@code{ESCAPED BY}-Zeichen @samp{\} ist).
+
+@item
+Wenn @code{FIELDS ENCLOSED BY} nicht leer ist, wird ein Feld, das das
+Literalwort @code{NULL} als seinen Wert enthält, als @code{NULL}-Wert
+gelesen (das weicht ab vom Wort @code{NULL}, begrenzt durch @code{FIELDS
+ENCLOSED BY}-Zeichen, was als die Zeichenkette @code{'NULL'} gelesen wird).
+
+@item
+Wenn @code{FIELDS ESCAPED BY} leer ist, wird @code{NULL} als das Wort
+@code{NULL} gelesen.
+
+@item
+Beim Festzeilenformat (was auftritt, wenn sowohl @code{FIELDS TERMINATED
+BY} als auch @code{FIELDS ENCLOSED BY} leer sind), wird @code{NULL} als
+leere Zeichenkette geschrieben. Beachten Sie, dass das dazu führt, dass
+@code{NULL}-Werte und leere Zeichenketten in der Tabelle nicht mehr
+unterscheidbar sind, wenn in die Datei geschrieben wird, weil sie beide als
+leere Zeichenketten geschrieben werden. Wenn Sie in der Lage sein müssen,
+diese zu unterscheiden, wenn Sie die Datei wieder einlesen, sollten Sie
+kein Festzeilenformat benutzen.
+@end itemize
+
+Einige Fälle werden von @code{LOAD DATA INFILE} nicht unterstützt:
+@itemize @bullet
+
+@item
+Festgrößenzeilen (@code{FIELDS TERMINATED BY} und @code{FIELDS ENCLOSED
+BY} sind beide leer) und @code{BLOB}- oder @code{TEXT}-Spalten.
+
+@item
+Wenn Sie ein Trennzeichen angeben, das dasselbe wie ein anderes ist oder
+einem anderen vorangestellt ist. @code{LOAD DATA INFILE} kann in diesem
+Fall die Eingabe nicht korrekt interpretieren. Folgende
+@code{FIELDS}-Klausel zum Beispiel würde Probleme bereiten:
+
+@example
+FIELDS TERMINATED BY '"' ENCLOSED BY '"'
+@end example
+
+@item
+Wenn @code{FIELDS ESCAPED BY} leer ist, führt ein Feldwert, der ein
+Vorkommen von @code{FIELDS ENCLOSED BY} oder @code{LINES TERMINATED BY}
+gefolgt vom @code{FIELDS TERMINATED BY}-Wert enthält, dazu, dass @code{LOAD
+DATA INFILE} mit dem Einlesen eines Feldes oder einer Zeile zu früh
+aufhört. Das passiert, weil @code{LOAD DATA INFILE} nicht korrekt festlegen
+kann, wo der Feld- oder Zeilenwert endet.
+@end itemize
+
+Das folgende Beispiel lädt alle Spalten der @code{personen}-Tabelle:
+
+@example
+mysql> LOAD DATA INFILE 'personen.txt' INTO TABLE personen;
+@end example
+
+Es ist keine Felderliste angegeben, daher erwartet @code{LOAD DATA INFILE},
+dass die Eingabefelder ein Feld für jede Tabellenspalte enthalten. Die
+Vorgabewerte für @code{FIELDS} und @code{LINES}-Werte werden benutzt.
+
+Wenn Sie Daten nur in einige Tabellenspalten einladen wollen, geben Sie
+eine Felderliste an:
+
+@example
+mysql> LOAD DATA INFILE 'personen.txt'
+ INTO TABLE personen (spalte1,spalte2,...);
+@end example
+
+Eine Felderliste müssen Sie ausserdem angeben, wenn die Reihenfolge der
+Felder in der Eingabedatei von der Reihenfolge der Tabellenspalten
+abweicht. Ansonsten kann MySQL nicht feststellen, wie er Eingabefelder
+Tabellenspalten zuordnen soll.
+
+Wenn eine Zeile zu wenige Felder hat, werden die Spalten, für die es kein
+Eingabefeld gibt, auf ihre Vorgabewerte gesetzt. Die Zuweisung von
+Vorgabewerten ist unter @ref{CREATE TABLE, , @code{CREATE TABLE}}
+beschrieben.
+
+Ein leerer Feldwert wird anders interpretiert als ein fehlender Feldwert:
+
+@itemize @bullet
+@item
+Bei Zeichenketten-Typen wird die Spalte auf die leere Zeichenkette gesetzt.
+
+@item
+Bei numerischen Typen wird die Spalte auf @code{0} gesetzt.
+
+@item
+Bei Datums- und Zeit-Typen wird die Spalte auf den entsprechenden
+``0''-Wert für den Typ gesetzt.
+@xref{Date and time types}.
+@end itemize
+
+Beachten Sie, dass das dieselben Werte sind, die sich ergeben, wenn Sie
+einer Zeichenkette explizit eine leere Zeichenkette zuweisen oder solches
+für einen DATE- oder TIME-Type in einem @code{INSERT}- oder
+@code{UPDATE}-Statement tun.
+
+@code{TIMESTAMP}-Spalten werden nur dann auf das aktuelle Datum und die
+aktuelle Zeit gesetzt, wenn es einen @code{NULL}-Wert für die Spalte gibt
+oder (nur für die erste @code{TIMESTAMP}-Spalte) die
+@code{TIMESTAMP}-Spalte in der Felderliste ausgelassen ist, wenn eine
+Felderliste angegeben wird.
+
+Wenn eine Eingabezeile zu viele Felder hat, werden die zusätzlichen Felder
+ignoriert und die Anzahl von Warnungen herauf gezählt.
+
+@code{LOAD DATA INFILE} betrachtet alle Eingaben als Zeichenketten, daher
+können Sie für @code{ENUM} oder @code{SET}-Spalten keine numerischen Werte
+benutzen, wie Sie das bei @code{INSERT}-Statements tun können. Alle
+@code{ENUM}- und @code{SET}-Werte müssen als Zeichenketten angegeben
+werden!
+
+@findex mysql_info()
+Wenn Sie die C-API benutzen, können Sie Informationen über die Anfrage
+durch den Aufruf der API-Funktion @code{mysql_info()} erhalten, wenn die
+@code{LOAD DATA INFILE}-Anfrage beendet ist. Das Format der
+Informationszeichenkette sieht wie folgt aus:
+
+@example
+Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
+@end example
+
+Warnungen erfolgen unter denselben Umständen, als wenn Werte über das
+@code{INSERT}-Statement (@pxref{INSERT, , @code{INSERT}}) eingefügt werden,
+ausser dass @code{LOAD DATA INFILE} zusätzlich Warnungen erzeugt, wenn es
+zu wenige oder zu viele Felder in der Eingabezeile gibt. Die Warnungen
+werden nirgendwo gespeichert; die Anzahl von Warnungen kann daher nur als
+Anhaltspunkt dafür benutzt werden, ob alles gut ging. Wenn Sie Warnungen
+erhalten und genau wissen wollen, warum Sie diese erhalten, besteht eine
+Möglichkeit dafür darin, @code{SELECT ... INTO OUTFILE} in eine andere
+Datei zu benutzen und diese mit der Original-Eingabedatei zu vergleichen.
+
+Wenn Sie wollen, dass @code{LOAD DATA} aus einer Pipe liest, können Sie
+folgenden Trick benutzen:
+
+@example
+mkfifo /mysql/db/x/x
+chmod 666 /mysql/db/x/x
+cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x
+mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
+@end example
+
+Wenn Sie eine MySQL-Version vor 3.23.25 benutzen, können Sie das nur mit
+@code{LOAD DATA LOCAL INFILE} durchführen.
+
+Weitere Informationen über die Effizienz von @code{INSERT} versus
+@code{LOAD DATA INFILE} und Möglichkeiten, die Geschwindigkeit zu steigern,
+finden Sie unter @code{LOAD DATA INFILE}, @xref{Insert speed}.
+
+
+@node Data Definition, Basic User Commands, Data Manipulation, Reference
+@c German node Datendefinition
+@section Datendefinition: @code{CREATE}, @code{DROP}, @code{ALTER}
+
+
+
+@menu
+* CREATE DATABASE::
+* DROP DATABASE::
+* CREATE TABLE::
+* ALTER TABLE::
+* RENAME TABLE::
+* DROP TABLE::
+* CREATE INDEX::
+* DROP INDEX::
+@end menu
+
+@node CREATE DATABASE, DROP DATABASE, Data Definition, Data Definition
+@c German node CREATE DATABASE
+@subsection @code{CREATE DATABASE}-Syntax
+
+@findex CREATE DATABASE
+
+@example
+CREATE DATABASE [IF NOT EXISTS] datenbank
+@end example
+
+@c German FIX unwrapped @ref
+@code{CREATE DATABASE} erzeugt eine Datenbank mit dem angegebenen Namen.
+Die Regeln für erlaubte Datenbanknamen finden Sie unter @ref{Legal names}.
+Ein Fehler tritt auf, wenn die Datenbank bereits existiert und Sie
+@code{IF NOT EXISTS} nicht angeben.
+
+Datenbanken sind in MySQL als Verzeichnisse implementiert, die Dateien
+enthalten, die den Tabellen in der Datenbank entsprechen. Weil es keine
+Tabellen in einer Datenbank gibt, wenn diese erstmalig erzeugt wird,
+erzeugt das @code{CREATE DATABASE}-Statement nur ein Verzeichnis unter dem
+MySQL-Daten-Verzeichnis.
+
+@cindex @code{mysqladmin}
+Sie können auch mit @code{mysqladmin} Datenbanken erzeugen.
+@xref{Client-Side Scripts}.
+
+
+@node DROP DATABASE, CREATE TABLE, CREATE DATABASE, Data Definition
+@c German node DROP DATABASE
+@subsection @code{DROP DATABASE}-Syntax
+
+@findex DROP DATABASE
+
+@example
+DROP DATABASE [IF EXISTS] datenbank
+@end example
+
+@code{DROP DATABASE} löscht alle Tabellen in der Datenbank und löscht die
+Datenbank. Wenn Sie ein @code{DROP DATABASE} auf eine symbolisch verknüpfte
+Datenbank ausführen, werden sowohl der Link als auch die Original-Datenbank
+gelöscht. @strong{Seien Sie mit diesem Befehl sehr vorsichtig!}
+
+@code{DROP DATABASE} gibt die Anzahl von Dateien zurück, die aus dem
+Datenbank-Verzeichnis entfernt wurden. Normalerweise ist das dreimal die
+Anzahl der Tabellen, weil normalerweise jede Tabelle einer
+@file{.MYD}-Datei, einer @file{.MYI}-Datei und einer @file{.frm}-Datei
+entspricht.
+
+Der @code{DROP DATABASE}-Befehl entfernt aus dem angegebenen
+Datenbank-Verzeichnis alle Dateien mit folgenden Erweiterungen:
+
+@multitable @columnfractions .25 .25 .25 .25
+@item .BAK @tab .DAT @tab .HSH @tab .ISD
+@item .ISM @tab .ISM @tab .MRG @tab .MYD
+@item .MYI @tab .db @tab .frm
+@end multitable
+
+Alle Unterverzeichnisse, die aus 2 Ziffern bestehen
+(@code{RAID}-Verzeichnisse), werden ebenfalls gelöscht.
+
+Ab MySQL-Version 3.22 können Sie die Schlüsselwörter @code{IF EXISTS}
+benutzen, um eine Fehlermeldung zu vermeiden, die erscheint, wenn die
+Datenbank nicht existiert.
+
+@cindex @code{mysqladmin}
+Sie können Datenbanken auch mit @code{mysqladmin} löschen.
+@xref{Client-Side Scripts}.
+
+
+
+@node CREATE TABLE, ALTER TABLE, DROP DATABASE, Data Definition
+@c German node CREATE TABLE
+@subsection @code{CREATE TABLE}-Syntax
+
+@findex CREATE TABLE
+
+
+@example
+CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tabelle [(create_definition,...)]
+[tabellen_optionen] [select_statement]
+
+create_definition:
+ spalten_name typ [NOT NULL | NULL] [DEFAULT vorgabe_wert] [AUTO_INCREMENT]
+ [PRIMARY KEY] [referenz_definition]
+ oder PRIMARY KEY (index_spalten_name,...)
+ oder KEY [index_name] (index_spalten_name,...)
+ oder INDEX [index_name] (index_spalten_name,...)
+ oder UNIQUE [INDEX] [index_name] (index_spalten_name,...)
+ oder FULLTEXT [INDEX] [index_name] (index_spalten_name,...)
+ oder [CONSTRAINT symbol] FOREIGN KEY index_name (index_spalten_name,...)
+ [referenz_definition]
+ oder CHECK (ausdruck)
+
+typ:
+ TINYINT[(laenge)] [UNSIGNED] [ZEROFILL]
+ oder SMALLINT[(laenge)] [UNSIGNED] [ZEROFILL]
+ oder MEDIUMINT[(laenge)] [UNSIGNED] [ZEROFILL]
+ oder INT[(laenge)] [UNSIGNED] [ZEROFILL]
+ oder INTEGER[(laenge)] [UNSIGNED] [ZEROFILL]
+ oder BIGINT[(laenge)] [UNSIGNED] [ZEROFILL]
+ oder REAL[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
+ oder DOUBLE[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
+ oder FLOAT[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
+ oder DECIMAL(laenge,dezimalstellen) [UNSIGNED] [ZEROFILL]
+ oder NUMERIC(laenge,dezimalstellen) [UNSIGNED] [ZEROFILL]
+ oder CHAR(laenge) [BINARY]
+ oder VARCHAR(laenge) [BINARY]
+ oder DATE
+ oder TIME
+ oder TIMESTAMP
+ oder DATETIME
+ oder TINYBLOB
+ oder BLOB
+ oder MEDIUMBLOB
+ oder LONGBLOB
+ oder TINYTEXT
+ oder TEXT
+ oder MEDIUMTEXT
+ oder LONGTEXT
+ oder ENUM(wert1,wert2,wert3,...)
+ oder SET(wert1,wert2,wert3,...)
+
+index_spalten_name:
+ spalten_name [(laenge)]
+
+referenz_definition:
+ REFERENCES tabelle [(index_spalten_name,...)]
+ [MATCH FULL | MATCH PARTIAL]
+ [ON DELETE referenz_option]
+ [ON UPDATE referenz_option]
+
+referenz_option:
+ RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
+
+tabellen_optionen:
+ TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM @}
+or AUTO_INCREMENT = #
+or AVG_ROW_LENGTH = #
+or CHECKSUM = @{0 | 1@}
+or COMMENT = "string"
+or MAX_ROWS = #
+or MIN_ROWS = #
+or PACK_KEYS = @{0 | 1 | DEFAULT@}
+or PASSWORD = "string"
+or DELAY_KEY_WRITE = @{0 | 1@}
+or ROW_FORMAT= @{ default | dynamic | fixed | compressed @}
+or RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=# RAID_CHUNKSIZE=#
+or UNION = (tabelle,[tabelle...])
+or INSERT_METHOD= @{NO | FIRST | LAST @}
+or DATA directory="verzeichnis"
+or INDEX directory="verzeichnis"
+
+select_statement:
+ [IGNORE | REPLACE] SELECT ... (jedes zulässige SELECT-Statement)
+@end example
+
+@code{CREATE TABLE} erzeugt eine Tabelle mit dem angegebenen Namen in der
+aktuellen Datenbank. Die Regeln für erlaubte Tabellennamen finden Sie unter
+@ref{Legal names}. Ein Fehler tritt auf, wenn es keine aktuelle
+Datenbank gibt oder wenn die Tabelle bereits existiert.
+
+Ab MySQL-Version 3.22 kann der Tabellenname als @code{datenbank.tabelle}
+angegeben werden. Das funktioniert unabhängig davon, ob es eine aktuelle
+Datenbank gibt oder nicht.
+
+In MySQL-Version 3.23 können Sie das @code{TEMPORARY}-Schlüsselwort
+benutzen, wenn Sie eine Tabelle erzeugen. Eine temporäre Tabelle wird
+automatisch gelöscht, wenn eine Verbindung stirbt und der Name sich auf die
+Verbindung bezieht. Das bedeutet, dass zwei verschiedene Verbindungen beide
+denselben temporären Tabellenname benutzen können, oder miteinander oder
+einer bestehenden Tabelle gleichen Namens in Konflikt zu geraten. (Die
+bestehende Tabelle ist versteckt, bis die temporäre Tabelle gelöscht wird.)
+
+Ab MySQL-Version 3.23 können Sie die Schlüsselwörter @code{IF NOT EXISTS}
+benutzen, so dass kein Fehler auftritt, wenn die Tabelle bereits besteht.
+Beachten Sie, dass keine Überprüfung erfolgt, dass die Tabellenstrukturen
+identisch sind.
+
+Jede Tabelle @code{tabelle} wird durch einige Dateien im
+Datenbank-Verzeichnis dargestellt. Im Falle von MyISAM-Tabellen erhalten
+Sie:
+
+@multitable @columnfractions .2 .8
+@item @strong{Datei} @tab @strong{Zweck}
+@item @code{tabelle.frm} @tab Tabellendefinitionsdatei (form)
+@item @code{tabelle.MYD} @tab Daten-Datei
+@item @code{tabelle.MYI} @tab Index-Datei
+@end multitable
+
+Weitere Information über die Eigenschaften der verschiedenen Spaltentypen
+finden Sie unter @ref{Column types}:
+
+@itemize @bullet
+@item
+Wenn weder @code{NULL} noch @code{NOT NULL} angegeben ist, wird die Spalte
+behandelt, als wenn @code{NULL} angegeben worden wäre.
+
+@item
+Eine Ganzzahl-Spalte kann das zusätzliche Attribut @code{AUTO_INCREMENT}
+haben. Wenn Sie einen Wert von @code{NULL} (empfohlen) oder @code{0} in
+eine @code{AUTO_INCREMENT}-Spalte einfügen, wird die Spalte auf
+@code{wert+1} gesetzt, wobei @code{wert} der größte momentan in der
+Tabelle vorhandene Spaltenwert ist. @code{AUTO_INCREMENT}-Folgen fangen mit
+@code{1} an. @xref{mysql_insert_id, , @code{mysql_insert_id()}}.
+
+Wenn Sie eine Zeile löschen, die den höchsten Wert einer
+@code{AUTO_INCREMENT}-Spalte enthält, wird der Wert bei einer @code{ISAM}-
+oder @code{BDB}-Tabelle wieder verwendet, nicht aber bei einer
+@code{MyISAM}- oder @code{InnoDB}-Tabelle. Wenn Sie alle Zeilen in der
+Tabelle mit @code{DELETE FROM tabelle} (ohne ein @code{WHERE}) im
+@code{AUTOCOMMIT}-Modus löschen, fängt die Folge bei allen Tabellentypen
+von Neuem an.
+
+@strong{HINWEIS:} Es darf nur eine @code{AUTO_INCREMENT}-Spalte pro Tabelle
+geben und diese muss indiziert sein. MySQL-Version 3.23 funktioniert
+darüber hinaus nur korrekt, wenn die @code{AUTO_INCREMENT}-Spalte nur
+positive Werte hat. Das Einfügen einer negativen Zahl wird als Einfügen
+einer sehr großen positiven Zahl betrachtet. Damit werden
+Genauigkeitsprobleme vermieden, wenn Zahlen vom positiven zum negativen
+Bereich übergehen. Ausserdem wird sichergestellt, dass man nicht
+versehentlich eine @code{AUTO_INCREMENT}-Spalte erhält, die 0 enthält.
+
+@cindex ODBC-Kompatibilität
+@cindex Kompatibilität, mit ODBC
+Um MySQL kompatibel mit einigen ODBC-Applikationen zu machen, können Sie
+die letzte eingefügte Zeile mit folgender Anfrage finden:
+
+@example
+SELECT * FROM tabelle WHERE auto_spalte IS NULL
+@end example
+
+@item
+@code{NULL}-Werte werden bei @code{TIMESTAMP}-Spalten anders als bei
+anderen Spaltentypen gehandhabt. Sie können @code{NULL} nicht wortgetreu in
+einer @code{TIMESTAMP}-Spalte speichern: Wenn Sie die Spalte auf
+@code{NULL} setzen, wird sie auf das aktuelle Datum und die aktuelle Zeit
+gesetzt. Weil @code{TIMESTAMP}-Spalten sich auf diese Art verhalten,
+treffen die @code{NULL}- und @code{NOT NULL}-Attribute nicht auf normale
+Art zu und werden ignoriert, wenn Sie sie angeben.
+
+Auf der anderen Seite berichtet der Server, um es für MySQL-Clients
+leichter zu machen, @code{TIMESTAMP}-Spalten zu benutzen, dass solchen
+Spalten @code{NULL}-Werte zugewiesen werden können (was stimmt), obwohl
+@code{TIMESTAMP} nie wirklich einen @code{NULL}-Wert enthalten wird. Sie
+können das sehen, wenn Sie @code{DESCRIBE tabelle} eingeben, um eine
+Beschreibung Ihrer Tabelle zu erhalten.
+
+Beachten Sie, dass das Setzen einer @code{TIMESTAMP}-Spalte auf @code{0}
+nicht dasselbe ist wie das Setzen auf @code{NULL}, weil @code{0} ein
+gültiger @code{TIMESTAMP}-Wert ist.
+
+@item
+Wenn kein @code{DEFAULT}-Wert für eine Spalte angegeben wird, weist MySQL
+automatisch einen zu.
+
+Wenn die Spalte @code{NULL} als Wert aufnehmen darf, ist der Vorgabewert
+@code{NULL}.
+
+Wenn die Spalte als @code{NOT NULL} deklariert ist, hängt der Vorgabewert
+vom Spaltentyp ab:
+
+@itemize @minus
+@item
+Bei numerischen Typen ausser denen, die mit dem
+@code{AUTO_INCREMENT}-Attribut deklariert wurden, ist der Vorgabewert
+@code{0}. Bei einer @code{AUTO_INCREMENT}-Spalte ist der Vorgabewert der
+nächste Wert in der Folge.
+
+@item
+Bei Datums- und Zeit-Typen ausser @code{TIMESTAMP} ist der Vorgabewert der
+entsprechende 0-Wert für den Typ. Bei der ersten @code{TIMESTAMP}-Spalte
+einer Tabelle ist der Vorgabewert das aktuelle Datum und die aktuelle Zeit.
+@xref{Date and time types}.
+
+@item
+Bei Zeichenketten-Typen ausser @code{ENUM} ist der Vorgabewert die leere
+Zeichenkette. Bei @code{ENUM} ist der Vorgabewert der erste
+Aufzählungswert.
+@end itemize
+
+Vorgabewerte müssen Konstanten sein. Das heißt zum Beispiel, dass Sie den
+Vorgabewert einer DATE-Spalte nicht als Wert einer Funktion wie
+@code{NOW()} oder @code{CURRENT_DATE} setzen können.
+
+@item
+@code{KEY} ist ein Synonym für @code{INDEX}.
+
+@item
+In MySQL darf ein @code{UNIQUE}-Schlüssel nur unterschiedliche Werte haben.
+Ein Fehler tritt auf, wenn Sie versuchen, eine neue Zeile hinzuzufügen, der
+Schlüsselwert dem einer bestehenden Zeile entspricht.
+
+@item
+@tindex PRIMARY KEY
+Ein @code{PRIMARY KEY} ist ein eindeutiger @code{KEY} mit der zusätzlichen
+Beschränkung, dass alle Schlüsselspalten als @code{NOT NULL} deklariert
+sein müssen. In MySQL wird der Schlüssel @code{PRIMARY} genannt. Eine
+Tabelle darf nur einen @code{PRIMARY KEY} haben. Wenn Sie keinen
+@code{PRIMARY KEY} haben und irgend welche Applikationen nach einem
+@code{PRIMARY KEY} in Ihrer Tabelle verlangen, gibt MySQL den ersten
+@code{UNIQUE}-Schlüssel, der keinerlei @code{NULL}-Spalten hat, als
+@code{PRIMARY KEY} zurück.
+
+@item
+Ein @code{PRIMARY KEY} kann ein mehrspaltiger Index sein. Sie können jedoch
+keinen mehrspaltiger Index mit dem @code{PRIMARY KEY}-Schlüsselattribut in
+einer Spaltenspezifikation erzeugen. Wenn Sie das tun, wird nur die erste
+Spalte als @code{PRIMARY} gekennzeichnet. Sie müssen die @code{PRIMARY
+KEY(index_spalten_name, ...)}-Syntax benutzen.
+
+@item
+Wenn der @code{PRIMARY}- oder @code{UNIQUE}-Schlüssel aus nur einer Spalte
+besteht und diese vom Typ Ganzzahl ist, können Sie auf sie auch als
+@code{_rowid} verweisen (neu ab Version 3.23.11).
+
+@item
+Wenn Sie einem Index keinen Namen zuweisen, wird dem Index derselbe Name
+zugewiesen wie der erste @code{index_spalten_name}, mit einem optionalen
+Suffix (@code{_2}, @code{_3}, @code{...}), um ihn eindeutig zu machen. Sie
+können die Indexnamen für eine Tabelle mit @code{SHOW INDEX FROM tabelle}
+anzeigen. @xref{SHOW, , @code{SHOW}}.
+
+@item
+@cindex @code{NULL}-Werte und Indexe
+@cindex Indexe und @code{NULL}-Werte
+Nur der @code{MyISAM}-Tabellentyp unterstützt Indexe auf Spalten, die
+@code{NULL}-Werte enthalten können. In anderen Fällen müssen Sie solche
+Spalten als @code{NOT NULL} deklarieren, sonst tritt ein Fehler auf.
+
+@item
+Mit der @code{spalten_name(laenge)}-Syntax können Sie einen Index
+festlegen, der nur einen Teil einer @code{CHAR}- oder @code{VARCHAR}-Spalte
+enthält. Das kann die Index-Datei viel kleiner machen.
+@xref{Indexes}.
+
+@item
+@cindex @code{BLOB}-Spalten, Indexierung
+@cindex Indexe und @code{BLOB}-Spalten
+@cindex @code{TEXT}-Spalten, Indexierung
+@cindex Indexe und @code{TEXT}-Spalten
+Nur der @code{MyISAM}-Tabellentyp unterstützt Indexierung auf @code{BLOB}-
+und @code{TEXT}-Spalten. Wenn Sie einen Index auf eine @code{BLOB}- oder
+@code{TEXT}-Spalte setzen, MÜSSEN Sie immer die Länge des Indexes angeben:
+@example
+CREATE TABLE test (blob_spalte BLOB, index(blob_spalte(10)));
+@end example
+
+@item
+Wenn Sie @code{ORDER BY} oder @code{GROUP BY} bei einer @code{TEXT}- oder
+@code{BLOB}-Spalte benutzen, werden nur die ersten @code{max_sort_length}
+Bytes benutzt. @xref{BLOB, , @code{BLOB}}.
+
+@item
+Ab MySQL-Version 3.23.23 können Sie auch spezielle @strong{FULLTEXT}-Indexe
+erzeugen, Diese werden für Volltextsuche benutzt. Nur der
+@code{MyISAM}-Tabellentyp unterstützt @code{FULLTEXT}-Indexe. Sie können
+auf @code{VARCHAR}- und @code{TEXT}-Spalten erzeugt werden. Die Indexierung
+erfolgt immer über die gesamte Spalte, teilweise Indexierung wird nicht
+unterstützt. Siehe @ref{Fulltext Search} für Details zur Funktionsweise.
+
+@item
+Die @code{FOREIGN KEY}-, @code{CHECK}- und @code{REFERENCES}-Klauseln tun
+momentan noch nichts. Die Syntax wird nur aus Gründen der Kompatibilität
+bereit gestellt, um das Portieren von Code von anderen SQL-Servern zu
+erleichtern und um Applikationen laufen zu lassen, die Tabellen mit
+Referenzen erzeugen.
+@c German FIX old ref was @xref{Fehlende Funktionen}.
+@xref{ANSI diff Foreign Keys}.
+
+@item
+Jede @code{NULL}-Spalte benötigt ein zusätzliches Bit, gerundet auf das
+nächste Byte.
+
+@item
+Die maximale Datensatzlänge in Bytes kann wie folgt berechnet werden:
+
+@example
+Zeilenlänge = 1
+ + (Summe Spaltenlängen)
+ + (Anzahl von NULL-Spalten + 7)/8
+ + (Anzahl von Spalten variabler Länge)
+@end example
+
+@item
+Die @code{tabellen_optionen}- und @code{SELECT}-Optionen sind implementiert
+ab MySQL-Version 3.23.
+
+Die unterschiedlichen Tabellentypen sind:
+
+@multitable @columnfractions .20 .80
+@item BDB oder Berkeley_db @tab Transaktionssichere Tabellen mit Seitensperren (Page Locking). @xref{BDB}.
+@item HEAP @tab Die Daten dieser Tabelle werden nur im Arbeitsspeicher gehalten. @xref{HEAP}.
+@item ISAM @tab Der Original-Tabellen-Handler. @xref{ISAM}.
+@item InnoDB @tab Transaktionssichere Tabellen mit Zeilensperren. @xref{InnoDB}.
+@item MERGE @tab Eine Sammlung von MyISAM-Tabellen, die als eine Tabelle benutzt werden. @xref{MERGE}.
+@item MRG_MERGE @tab Ein Alias für MERGE-Tabellen.
+@item MyISAM @tab Der neue binäre portable Tabellen-Handler, der ISAM ersetzt. @xref{MyISAM}.
+@end multitable
+@xref{Table types}.
+
+Wenn ein Tabellentyp angegeben wird und dieser besondere Typ nicht
+verfügbar ist, wählt MySQL den Tabellentyp, der dem angegebenen am nächsten
+kommt. Wenn beispielsweise @code{TYPE=BDB} angegeben wird und die
+Distribution von MySQL keine @code{BDB}-Tabellen unterstützt, wird die
+Tabelle statt dessen als @code{MyISAM} erzeugt.
+
+Die anderen Tabellenoptionen werden benutzt, um das Verhalten der Tabelle
+zu optimieren. In den meisten Fällen müssen Sie keine davon angeben. Die
+Optionen funktionieren bei allen Tabellentypen, falls nicht anders
+angegeben:
+
+@multitable @columnfractions .20 .80
+@item @code{AUTO_INCREMENT} @tab Der nächste auto_increment-Wert, den Sie für Ihre Tabelle setzen wollen (MyISAM).
+@item @code{AVG_ROW_LENGTH} @tab Näherungsweise die durchschnittliche Zeilenlänge Ihrer Tabelle. Diese Option müssen Sie nur für große Tabellen mit unterschiedlich großen Datensätzen setzen.
+@item @code{CHECKSUM} @tab Setzen Sie diesen Wert auf 1, wenn Sie wollen, dass MySQL eine Prüfsumme für alle Zeilen unterhält (macht die Tabelle ein bisschen langsamer bei der Aktualisierung, aber macht es einfacher, beschädigte Tabellen zu finden) (MyISAM).
+@item @code{COMMENT} @tab Ein 60-Zeichen-Kommentar für Ihre Tabelle.
+@item @code{MAX_ROWS} @tab Maximale Anzahl von Zeilen, die Sie in Ihrer Tabelle zu speichern planen.
+@item @code{MIN_ROWS} @tab Minimale Anzahl von Zeilen, die Sie in Ihrer Tabelle zu speichern planen.
+@item @code{PACK_KEYS} @tab Setzen Sie diesen Wert auf 1, wenn Sie einen kleineren Index erhalten wollen. Das macht Aktualisierungen üblicherweise langsamer und liest schneller (MyISAM, ISAM). Setzen auf 0 schaltet die Komprimierung von Schlüsseln ab. Setzen auf @code{DEFAULT} (MySQL 4.0) weist die Tabellen-Handler an, nur lange @code{CHAR}- / @code{VARCHAR}-Spalten zu packen.
+@item @code{PASSWORD} @tab Verschlüsselt die @code{.frm}-Datei mit einem Passwort. Diese Option tut nichts in der Standard-MySQL-Version.
+@item @code{DELAY_KEY_WRITE} @tab Setzen Sie diesen Wert auf 1, wenn Sie Schlüssel-Tabellen-Aktualisierungen verzögern wollen, bis die Tabelle geschlossen wird (MyISAM).
+@item @code{ROW_FORMAT} @tab Definiert, wie die Zeilen gespeichert werden sollen. Momentan funktioniert diese Option nur bei MyISAM-Tabellen, die die @code{DYNAMIC}- und @code{FIXED}-Zeilenformate unterstützen. @xref{MyISAM table formats}.
+@end multitable
+
+Wenn Sie eine @code{MyISAM}-Tabelle benutzen, verwendet MySQL das Produkt
+aus @code{max_rows * avg_row_length} um zu entscheiden, wie Groß die
+resultierende Tabelle sein wird. Wenn Sie keine der obigen Optionen
+angeben, ist die maximale Größe für eine Tabelle 4 GB (oder 2 GB, wenn Ihr
+Betriebssystem nur 2 GB-Tabellen unterstützt). Das geschieht, um
+Zeigergrößen gering zu halten und um den Index kleiner und schneller zu
+machen, wenn Sie nicht wirklich große Dateien benötigen.
+
+Wenn Sie @code{PACK_KEYS} nicht benutzen, ist die Vorgabe, nur
+Zeichenketten zu komprimieren, nicht Zahlen. Wenn Sie @code{PACK_KEYS=1}
+benutzen, werden auch Zahlen komprimiert.
+
+Wenn Sie binäre Zahlschlüssel komprimieren, benutzt MySQL die
+Präfix-Komprimierung. Das bedeutet, dass Sie nur dann einen Nutzen daraus
+ziehen, wenn Sie Zahlen haben, die sich oft wiederholen. Präfix-Kompression
+bedeutet, das jeder Schlüssel ein zusätzliches Byte benötigt, um
+darzustellen, wie viele Bytes des vorherigen Schlüssels für den nächsten
+Schlüssel dieselben sind (beachten Sie, dass der Zeiger auf die Zeile in
+der Reihenfolge 'hohes Byte zuerst' direkt nach dem Schlüssel gespeichert
+wird, um die Kompression zu verbessern). Das heißt, wenn Sie viele gleiche
+Schlüssel auf zwei Zeilen hintereinander haben, werden alle folgenden
+'gleichen' Schlüssel üblicherweise nur 2 Bytes in Anspruch nehmen
+(inklusive dem Zeiger auf die Zeile). Vergleichen Sie das mit dem
+Normalfall, bei dem die folgenden Schlüssel speicher_platz_fuer_schlüssel +
+zeiger_groesse beanspruchen (üblicherweise 4). Auf der anderen Seite
+verlieren Sie 1 Byte pro Schlüssel, wenn alle Schlüssel völlig
+unterschiedlich sind, falls der Schlüssel kein Schlüssel ist, der
+@code{NULL}-Werte haben kann (in diesem Fall wird die komprimierte
+Schlüssellänge, die im selben Byte gespeichert ist, benutzt, um zu
+kennzeichnen, ob ein Schlüssel @code{NULL} ist).
+
+@item
+Wenn Sie ein @code{SELECT} nach dem @code{CREATE}-Statement angeben,
+erzeugt MySQL neue Felder für alle Elemente im @code{SELECT}. Beispiel:
+
+@example
+mysql> CREATE TABLE test (a int not null auto_increment,
+ primary key (a), key(b))
+ TYPE=MyISAM SELECT b,c from test2;
+@end example
+
+Das erzeugt eine @code{MyISAM}-Tabelle mit drei Spalten a, b und c.
+Beachten Sie, dass die Spalten des @code{SELECT}-Statements an die rechte
+Seite der Tabelle angehängt werden, nicht überlappend. Nehmen wir folgendes
+Beispiel:
+
+@example
+mysql> select * from foo;
++---+
+| n |
++---+
+| 1 |
++---+
+
+mysql> create table bar (m int) select n from foo;
+Query OK, 1 row affected (0.02 sec)
+Records: 1 Duplicates: 0 Warnings: 0
+
+mysql> select * from bar;
++------+---+
+| m | n |
++------+---+
+| NULL | 1 |
++------+---+
+1 row in set (0.00 sec)
+@end example
+
+Für jede Zeile in Tabelle @code{foo} wird eine Zeile in @code{bar} mit den
+Werten von @code{foo} und Vorgabewerten für die neuen Spalten eingefügt.
+
+@code{CREATE TABLE ... SELECT} erzeugt nicht automatisch irgend welche
+Indexe. Das wird absichtlich gemacht, um den Befehl so flexibel wie möglich
+zu machen. Wenn Sie Indexe in der erzeugten Tabelle haben wollen, geben Sie
+diese vor dem @code{SELECT}-Statement an:
+
+@example
+mysql> create table bar (unique (n)) select n von foo;
+@end example
+
+Wenn Fehler beim Kopieren der Daten in die Tabelle auftreten, wird diese
+automatisch gelöscht.
+
+Um sicherzustellen, dass die Update-Log-Datei/Binär-Log-Datei benutzt
+werden kann, um die Original-Tabellen neu zu erzeugen, läßt MySQL keine
+gleichzeitigen Einfügeoperationen während @code{CREATE TABLE .... SELECT}
+zu.
+@item
+Die @code{RAID_TYPE}-Option hilft, die 2 GB- / 4 GB-Grenze für die
+MyISAM-Daten-Datei zu durchbrechen (nicht für die Index-Datei), auf
+Betriebssystemen, die keine großen Dateien unterstützen.
+Sie erzielen mehr Geschwindigkeit vom I/O-Flaschenhals, wenn Sie die
+@code{RAID}-Verzeichnisse auf unterschiedliche physikalische Platten legen.
+@code{RAID_TYPE} funktioniert auf jedem Betriebssystem, solange Sie MySQL
+mit @code{--with-raid} konfiguriert haben. Momentan ist der einzige
+zulässige @code{RAID_TYPE} @code{STRIPED} (@code{1} und @code{RAID0} sind
+Aliase dafür).
+
+Wenn Sie @code{RAID_TYPE=STRIPED} bei einer @code{MyISAM}-Tabelle angeben,
+erzeugt @code{MyISAM} @code{RAID_CHUNKS}-Unterverzeichnisse namens 00, 01,
+02 im Datenbank-Verzeichnis. In jedem dieser Verzeichnisse erzeugt
+@code{MyISAM} eine @code{tabelle.MYD}. Wenn Sie Daten in die Daten-Datei
+schreiben, mappt der @code{RAID}-Handler die ersten @code{RAID_CHUNKSIZE} *
+1024 Bytes auf die erste Datei, die nächsten @code{RAID_CHUNKSIZE} * 1024
+Bytes auf die nächste Datei usw.
+
+@item
+@code{UNION} wird benutzt, wenn Sie eine Sammlung identischer Tabelle als
+eine benutzen wollen. Das funktioniert nur bei MERGE-Tabellen. @xref{MERGE}.
+
+Momentan benötigen Sie @code{SELECT}-, @code{UPDATE}-
+und-@code{DELETE}-Berechtigungen auf die Tabellen, die Sie auf eine
+@code{MERGE}-Tabelle mappen. Alle gemappten Tabellen müssen sich in
+derselben Datenbank wie die @code{MERGE}-Tabelle befinden.
+
+@item
+Wenn Sie Daten in eine @code{MERGE}-Tabelle einfügen wollen, müssen Sie mit
+@code{INSERT_METHOD} angeben, in welche Tabelle die Zeile eingefügt werden
+soll. @xref{MERGE}.
+
+@item
+In der erzeugten Tabelle wird der @code{PRIMARY}-Schlüssel zuerst
+platziert, gefolgt von allen @code{UNIQUE}-Schlüsseln und danach von den
+normalen Schlüsseln. Das hilft dem MySQL-Optimierer zu priorisieren,
+welcher Schlüssel benutzt werden soll, und auch, Duplikate von
+@code{UNIQUE}-Schlüsseln zu entdecken.
+
+@item
+Wenn Sie @code{DATA directory="verzeichnis"} oder @code{INDEX
+directory="verzeichnis"} benutzen, können Sie angeben, wohin die
+Tabellen-Handler ihre Tabellen- und Index-Dateien legen sollen. Das
+funktioniert nur bei @code{MyISAM}-Tabellen in @code{MySQL} 4.0, wenn Sie
+die @code{--skip-symlink}-Option nicht benutzen. @xref{Symbolic links to tables}.
+
+@end itemize
+
+
+@menu
+* Silent column changes::
+@end menu
+
+@node Silent column changes, , CREATE TABLE, CREATE TABLE
+@c German node Stille Spaltentyp-Änderungen
+@subsubsection Stille Spaltentyp-Änderungen
+
+@cindex Stille Spaltentyp-Änderungen
+
+In einigen Fällen ändert MySQL lautlos eine Spaltenspezifikation von der,
+die in einem @code{CREATE TABLE}-Statement angegeben wurde. (Das kann auch
+bei @code{ALTER TABLE} passieren.):
+
+@itemize @bullet
+@item
+@code{VARCHAR}-Spalten mit einer Länge kleiner 4 werden in @code{CHAR}
+geändert.
+
+@item
+Wenn irgend eine Spalte in einer Tabelle eine variable Länge hat, hat im
+Ergebnis jede Zeile eine variable Länge. Wenn daher eine Tabelle irgend
+welche Spalten variabler Länge enthält (@code{VARCHAR}, @code{TEXT} oder
+@code{BLOB}), werden alle @code{CHAR}-Spalten, die länger als drei Zeichen
+sind, in @code{VARCHAR}-Spalten umgewandelt. Das beeinflusst die Benutzung
+dieser Spalten in keiner Weise, denn in MySQL ist @code{VARCHAR} nur eine
+andere Art, Zeichen zu speichern. MySQL führt diese Umwandlung durch, weil
+sie Platz spart und Tabellenoperationen schneller macht.
+@xref{Table types}.
+
+@item
+@code{TIMESTAMP}-Anzeigebreiten müssen geradzahlig und im Bereich von 2 bis
+14 sein. Wenn Sie eine Anzeigebreite von 0 oder größer als 14 angeben,
+wird die Größe auf 14 gesetzt. Ungerade Werte im Bereich von 1 bis 13
+werden auf den nächst höheren geraden Wert gesetzt.
+
+@item
+Sie können keinen echten @code{NULL}-Wert in einer @code{TIMESTAMP}-Spalte
+speichern. Wenn Sie sie auf @code{NULL} setzen, wird sie auf das aktuelle
+Datum und die aktuelle Zeit gesetzt. Weil sich @code{TIMESTAMP}-Spalten so
+verhalten, treffen die Attribute @code{NULL} und @code{NOT NULL} nicht auf
+normale Weise zu und werden ignoriert, wenn Sie sie angeben. @code{DESCRIBE
+tabelle} zeigt dagegen immer an, dass einer @code{TIMESTAMP}-Spalte
+@code{NULL}-Werte zugewiesen werden können.
+
+@item
+MySQL mappt bestimmte Spaltentypen, die von anderen
+SQL-Datenbank-Herstellern benutzt werden, auf MySQL-Typen.
+@xref{Other-vendor column types}.
+@end itemize
+
+Wenn Sie sehen wollen, ob MySQL einen anderen Spaltentyp als den, den Sie
+angegeben haben, benutzt hat, geben Sie nach dem Erzeugen oder Ändern Ihrer
+Tabelle ein @code{DESCRIBE tabelle}-Statement ein.
+
+@cindex @code{myisampack}
+Bestimmte andere Spaltentyp-Änderungen können auftreten, wenn Sie eine
+Tabelle mit @code{myisampack} komprimieren. @xref{Compressed format}.
+
+
+@node ALTER TABLE, RENAME TABLE, CREATE TABLE, Data Definition
+@c German node ALTER TABLE
+@subsection @code{ALTER TABLE}-Syntax
+
+@findex ALTER TABLE
+
+@example
+ALTER [IGNORE] TABLE tabelle aenderungs_angabe [, aenderungs_angabe ...]
+
+aenderungs_angabe:
+ ADD [COLUMN] create_definition [FIRST | AFTER spalten_name]
+ oder ADD [COLUMN] (create_definition, create_definition,...)
+ oder ADD INDEX [index_name] (index_spalten_name,...)
+ oder ADD PRIMARY KEY (index_spalten_name,...)
+ oder ADD UNIQUE [index_name] (index_spalten_name,...)
+ oder ADD FULLTEXT [index_name] (index_spalten_name,...)
+ or ADD [CONSTRAINT symbol] FOREIGN KEY index_name (index_spalten_name,...)
+ [referenz_definition]
+ oder ALTER [COLUMN] spalten_name @{SET DEFAULT literal | DROP DEFAULT@}
+ oder CHANGE [COLUMN] alter_spalten_name create_definition
+ oder MODIFY [COLUMN] create_definition
+ oder DROP [COLUMN] spalten_name
+ oder DROP PRIMARY KEY
+ oder DROP INDEX index_name
+ oder DISABLE KEYS
+ oder ENABLE KEYS
+ oder RENAME [TO] neue_tabelle
+ oder ORDER BY spalte
+ oder tabellen_optionen
+@end example
+
+Mit @code{ALTER TABLE} können Sie die Struktur einer bestehenden Tabelle
+ändern. Sie können beispielsweise Spalten hinzufügen oder löschen, Indexe
+erzeugen oder löschen, den Typ bestehender Spalten ändern oder Spalten oder
+die Tabelle selbst umbenennen. Sie können auch den Kommentar für die
+Tabelle und den Typ der Tabelle ändern. @xref{CREATE TABLE, , @code{CREATE TABLE}}.
+
+Wenn Sie @code{ALTER TABLE} benutzen, um eine Spaltenspezifikation zu
+ändern, und @code{DESCRIBE tabelle} anzeigt, dass die Spalte nicht geändert
+wurde, ist es möglich, dass MySQL Ihre Änderungen aus einem der Gründe
+ignoriert hat, die in @ref{Silent column changes} beschrieben sind.
+Wenn Sie beispielsweise versuchen, eine @code{VARCHAR}-Spalte zu
+@code{CHAR} zu ändern, benutzt MySQL dennoch @code{VARCHAR}, wenn die
+Tabelle weitere Spalten variabler Länge enthält.
+
+@code{ALTER TABLE} funktioniert mittels Anlegen einer temporären Kopie der
+Original-Tabelle. Die Änderungen werden an der Kopie durchgeführt, dann
+wird die Original-Tabelle gelöscht und die neue umbenannt. Das wird so
+durchgeführt, dass alle Aktualisierungen automatisch ohne irgend welche
+fehlgeschlagenen Aktualisierungen an die neue Tabelle weitergeleitet
+werden. Während @code{ALTER TABLE} ausgeführt wird, ist die alte Tabelle
+durch andere Clients lesbar. Aktualisierungen und Schreibvorgänge in die
+Tabelle werden angehalten, bis die neue Tabelle bereit ist.
+
+Beachten Sie, dass MySQL immer eine temporäre Tabelle anlegt, wenn Sie für
+@code{ALTER TABLE} irgend eine Option ausser @code{RENAME} angeben, selbst
+wenn die Daten eigentlich nicht kopiert werden müssten (zum Beispiel, wenn
+Sie einen Spaltennamen ändern). Wir planen, dass zu beheben, aber da man
+@code{ALTER TABLE} normalerweise nicht ausführen muss, ist das auf unserer
+TODO-Liste nicht sehr hoch angesetzt.
+
+@itemize @bullet
+@item
+Um @code{ALTER TABLE} ausführen zu können, benötigen Sie @strong{ALTER}-,
+@strong{INSERT}- und @strong{CREATE}-Berechtigungen für die Tabelle.
+
+@item
+@code{IGNORE} ist eine MySQL-Erweiterung zu ANSI-SQL92. Es steuert, wie
+@code{ALTER TABLE} funktioniert, wenn es in der neuen Tabelle Duplikate auf
+eindeutigen Schlüsseln gibt. Wenn @code{IGNORE} nicht angegeben wird, wird
+das Kopieren abgebrochen und zurückgesetzt. Wenn @code{IGNORE} angegeben
+wird, wird bei Zeilen mit Duplikaten auf einem eindeutigen Schlüssel nur
+die erste Zeile benutzt, die anderen werden gelöscht.
+
+@item
+Sie können mehrfache @code{ADD}-, @code{ALTER}-, @code{DROP}- und
+@code{CHANGE}-Klauseln in einem einzigen @code{ALTER TABLE}-Statement
+angeben. Das ist eine MySQL-Erweiterung zu ANSI-SQL92, welches nur eine
+Klausel pro @code{ALTER TABLE}-Statement zuläßt.
+
+@item
+@code{CHANGE spalten_name}, @code{DROP spalten_name} und @code{DROP INDEX}
+sind MySQL-Erweiterungen zu ANSI-SQL92.
+
+@item
+@code{MODIFY} ist eine Oracle-Erweiterung zu @code{ALTER TABLE}.
+
+@item
+Das optionale Wort @code{COLUMN} kann weggelassen werden.
+
+@item
+Wenn Sie @code{ALTER TABLE tabelle RENAME TO neuer_name} ohne weitere
+Optionen benutzen, benennt MySQL einfach die Dateien um, die der Tabelle
+@code{tabelle} entsprechen. Es besteht keine Notwendigkeit, die temporäre
+Tabelle zu erzeugen. @xref{RENAME TABLE,, @code{RENAME TABLE}}.
+
+@item
+Ab @strong{MySQL 4.0} kann das obige Feature explizit aktiviert werden.
+@code{ALTER TABLE ... DISABLE KEYS} veranlasst MySQL, mit dem Aktualisieren
+nicht eindeutiger Indexe für die @code{MyISAM}-Tabelle aufzuhören. Dann
+sollte @code{ALTER TABLE ... ENABLE KEYS} benutzt werden, um fehlende
+Indexe wieder zu erzeugen. Weil MySQL das mit Algorithmen durchführt, die
+viel schneller sind als das Einfügen von Schlüsseln nacheinander, kann das
+Abschalten von Schlüsseln bei Masseneinfügeoperationen erheblich
+Geschwindigkeitsvorteile bringen.
+
+@item
+@code{create_definition}-Klauseln benutzen dieselbe Syntax für @code{ADD}
+und @code{CHANGE} wie bei @code{CREATE TABLE}. Beachten Sie, dass diese
+Syntax den Spaltenname beinhaltet, nicht nur den Spaltentyp.
+@c German FIX unsplit @xref
+@xref{CREATE TABLE, , @code{CREATE TABLE}}.
+
+@item
+Sie können eine Spalte mit einer @code{CHANGE alter_spalten_name
+create_definition}-Klausel umbenennen. Um das zu tun, geben Sie den alten
+und den neuen Spaltennamen und den Typ an, den die Spalte momentan hat. Um
+beispielsweise eine @code{INTEGER}-Spalte von @code{a} nach @code{b}
+umzubenennen, tun Sie folgendes:
+
+@example
+mysql> ALTER TABLE t1 CHANGE a b INTEGER;
+@end example
+
+Wenn Sie einen Spaltentyp, nicht aber den Namen ändern wollen, benötigt
+@code{CHANGE} dennoch zwei Spaltennamen, selbst wenn sie dieselben sind.
+Beispiel:
+
+@example
+mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
+@end example
+
+Ab MySQL-Version 3.22.16a können Sie jedoch auch @code{MODIFY} benutzen, um
+einen Spaltentyp ohne Umbenennung zu ändern:
+
+@example
+mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
+@end example
+
+@item
+Wenn Sie @code{CHANGE} oder @code{MODIFY} benutzen, um eine Spalte zu
+kürzen, für die es einen Index auf einem Teil der Spalte gibt (wenn Sie zum
+Beispiel einen Index auf den ersten 10 Zeichen einer @code{VARCHAR}-Spalte
+haben), können Sie die Spalte nicht kürzer als die Anzahl von Zeichen
+machen, die indiziert sind.
+
+@item
+Wenn Sie versuchen, einen Spaltentyp mit @code{CHANGE} oder @code{MODIFY}
+zu ändern, versucht MySQL, Daten so umzuwandeln, dass sie so gut wie
+möglich zum neuen Typ passen.
+
+@item
+AB MySQL-Version 3.22 können Sie @code{FIRST} oder @code{ADD ... AFTER
+spalten_name} benutzen, um eine Spalte an einer bestimmten Position
+innerhalb einer Tabellenzeile einzufügen. Vorgabemäßig wird die Spalte am
+Ende hinzugefügt.
+
+@findex ALTER COLUMN
+@item
+@code{ALTER COLUMN} gibt einen Vorgabewert für eine Spalte an oder entfernt
+den alten Vorgabewert. Wenn der alte Vorgabewert entfernt wird und die
+Spalte @code{NULL} sein darf, ist der neue Vorgabewert @code{NULL}. Wenn
+die Spalte nicht @code{NULL} sein darf, weist MySQL einen Vorgabewert zu,
+wie in @ref{CREATE TABLE, , @code{CREATE TABLE}} beschrieben.
+
+@findex DROP INDEX
+@item
+@code{DROP INDEX} entfernt einen Index. Das ist eine MySQL-Erweiterung zu
+ANSI-SQL92. @xref{DROP INDEX}.
+
+@item
+Wenn Spalten aus einer Tabelle gelöscht werden, werden sie auch aus
+jeglichen Indexen entfernt, deren Teil sie sind. Wenn alle Spalten, aus
+denen ein Index besteht, gelöscht werden, wird der Index ebenfalls
+gelöscht.
+
+@item
+Wenn eine Tabelle nur eine Spalte enthält, kann die Spalte nicht gelöscht
+werden. Wenn Sie beabsichtigen, die Tabelle zu entfernen, benutzen Sie
+statt dessen @code{DROP TABLE}.
+
+@findex DROP PRIMARY KEY
+@item
+@code{DROP PRIMARY KEY} löscht den Primärschlüssel. Wenn es keinen solchen
+gibt, löscht es den ersten @code{UNIQUE}-Index in der Tabelle. (MySQL
+kennzeichnet den ersten @code{UNIQUE}-Schlüssel als @code{PRIMARY KEY},
+wenn @code{PRIMARY KEY} nicht explizit angegeben wurde.)
+
+@findex UNIQUE
+@findex PRIMARY KEY
+Wenn Sie einen @code{UNIQUE INDEX} oder @code{PRIMARY KEY} zu einer Tabelle
+hinzufügen, wird dieser vor jedem Nicht-@code{UNIQUE}-Index gespeichert, so
+dass MySQL doppelte Schlüsseleinträge so früh wie möglich feststellen kann.
+
+@findex ORDER BY
+@item
+@code{ORDER BY} gestattet Ihnen, eine Tabelle mit Zeilen in einer
+bestimmten Reihenfolge zu erzeugen. Beachten Sie, dass die Tabelle nach
+INSERTs und DELETEs nicht in dieser Reihenfolge verbleibt. In einigen
+Fällen kann es das Sortieren für MySQL erleichtern, wenn die Tabelle nach
+der Spalte geordnet ist, nach der Sie sie später ordnen wollen. Diese
+Option ist hauptsächlich nützlich, wenn Sie wissen, dass Sie die Zeilen
+meistens in einer bestimmten Reihenfolge abfragen werden. Wenn Sie diese
+Option nach großen Änderungen in der Tabelle benutzen, können Sie
+möglicherweise eine höhere Performance erzielen.
+
+@findex ALTER TABLE
+@item
+Wenn Sie @code{ALTER TABLE} auf einer @code{MyISAM}-Tabelle benutzen,
+werden alle nicht eindeutigen Indexe in einem separaten Stapellauf erzeugt
+(wie bei @code{REPAIR}). Das sollte @code{ALTER TABLE} viel schneller
+machen, wenn Sie viele Indexe haben.
+
+@item
+Ab @strong{MySQL 4.0} kann dies explizit aktiviert werden. @code{ALTER
+TABLE ... DISABLE KEYS} veranlasst MySQL, mit der Aktualisierung nicht
+eindeutiger Indexe für @code{MyISAM}-Tabellen aufzuhören. @code{ALTER TABLE
+... ENABLE KEYS} sollte dann benutzt werden, um fehlende Indexe wieder zu
+erzeugen. Weil MySQL das mit Algorithmen durchführt, die viel schneller
+sind als das Einfügen von Schlüsseln nacheinander, kann das Abschalten von
+Schlüsseln bei Masseneinfügeoperationen erheblich Geschwindigkeitsvorteile
+bringen.
+
+@item
+@findex mysql_info()
+Mit der C-API-Funktion @code{mysql_info()} können Sie herausfinden, wie
+viele Datensätze kopiert wurden und (wenn @code{IGNORE} benutzt wird) wie
+viele Datensätze aufgrund der Duplizierung eindeutiger Schlüsselwerte
+gelöscht wurden.
+
+@item
+@cindex Fremdschlüssel
+@cindex Referenzen
+Die @code{FOREIGN KEY}-, @code{CHECK}- und @code{REFERENCES}-Klauseln
+machen nichts. Die Syntax für sie steht nur aus Kompatibilitätsgründen
+bereit, um das Portieren von Code von anderen SQL-Servern zu erleichtern
+und um Applikationen laufen zu lassen, die Tabellen mit Referenzen
+erzeugen.
+@c German FIX old ref was @xref{Fehlende Funktionen}.
+@xref{ANSI diff Foreign Keys}.
+@end itemize
+
+Hier ist ein Beispiel, das einige der Anwendungsfälle von @code{ALTER
+TABLE} zeigt. Wir fangen mit einer Tabelle @code{t1} an, die wie folgt
+erzeugt wird:
+
+@example
+mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
+@end example
+
+Um die Tabelle von @code{t1} nach @code{t2} umzubenennen, geben Sie ein:
+
+@example
+mysql> ALTER TABLE t1 RENAME t2;
+@end example
+
+Um Spalte @code{a} von @code{INTEGER} nach @code{TINYINT NOT NULL} zu
+ändern (der Name bleibt derselbe) und Spalte @code{b} von @code{CHAR(10)}
+nach @code{CHAR(20)} zu ändern und gleichzeitig von @code{b} nach @code{c}
+umzubenennen, geben Sie ein:
+
+@example
+mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
+@end example
+
+Jetzt wird eine @code{TIMESTAMP}-Spalte namens @code{d} hinzugefügt:
+
+@example
+mysql> ALTER TABLE t2 ADD d TIMESTAMP;
+@end example
+
+Nunmehr erzeugen wir einen Index auf Spalte @code{d} und machen Spalte
+@code{a} zum Primärschlüssel:
+
+@example
+mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
+@end example
+
+Wir entfernen Spalte @code{c}:
+
+@example
+mysql> ALTER TABLE t2 DROP COLUMN c;
+@end example
+
+Und fügen eine neue @code{AUTO_INCREMENT}-Ganzzahl-Spalte namens @code{c}
+hinzu:
+
+@example
+mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ ADD INDEX (c);
+@end example
+
+Beachten Sie, dass wir @code{c} indiziert haben, weil
+@code{AUTO_INCREMENT}-Spalten indiziert sein müssen, und auch, dass wir
+@code{c} als @code{NOT NULL} deklariert haben, weil indizierte Spalten
+nicht @code{NULL} sein dürfen.
+
+Wenn Sie eine @code{AUTO_INCREMENT}-Spalte hinzufügen, werden automatisch
+Spaltenwerte mit Zahlenfolgen eingefügt. Sie können die erste Zahl setzen,
+indem Sie @code{SET INSERT_ID=#} vor @code{ALTER TABLE} ausführen oder
+indem Sie die @code{AUTO_INCREMENT = #}-Tabellenoption benutzen.
+@xref{SET OPTION}.
+
+Wenn Sie bei MyISAM-Tabellen nicht die @code{AUTO_INCREMENT}-Spalte ändern,
+ist die Folgezahl davon nicht betroffen. Wenn Sie eine
+@code{AUTO_INCREMENT}-Spalte löschen und dann eine weitere
+@code{AUTO_INCREMENT}-Spalte hinzufügen, fangen die Zahlen wieder bei 1 an.
+
+@xref{ALTER TABLE problems}.
+
+
+@node RENAME TABLE, DROP TABLE, ALTER TABLE, Data Definition
+@c German node RENAME TABLE
+@subsection @code{RENAME TABLE}-Syntax
+
+@findex RENAME TABLE
+
+@example
+RENAME TABLE tabelle TO neue_tabelle[, tabelle2 TO neue_tabelle2,...]
+@end example
+
+Das Umbenennen wird atomisch durchgeführt, was heißt, dass kein anderer
+Thread auf die Tabelle(n) zugreifen kann, während umbenannt wird. Das
+ermöglicht, eine Tabelle durch eine leere zu ersetzen:
+
+@example
+CREATE TABLE neue_tabelle (...);
+RENAME TABLE alte_tabelle TO datensicherung_tabelle, neue_tabelle TO alte_tabelle;
+@end example
+
+Das Umbenennen wird von links nach rechts durchgeführt, was bedeutet, dass
+Sie beim Vertauschen zweier Tabellennamen folgendes tun können:
+
+@example
+RENAME TABLE alte_tabelle TO datensicherung_tabelle,
+ neue_tabelle TO alte_tabelle,
+ datensicherung_tabelle TO neue_tabelle;
+@end example
+
+Solange zwei Datenbanken auf derselben Platte liegen, können Sie auch von
+einer Datenbank in eine andere umbenennen:
+
+@example
+RENAME TABLE aktuelle_datenbank.tabelle TO andere_datenbank.tabelle;
+@end example
+
+Wenn Sie @code{RENAME} ausführen, dürfen Sie keine gesperrten Tabellen oder
+aktive Transaktionen haben. Ausserdem benötigen Sie die @code{ALTER}- und
+@code{DROP}-Berechtigungen für die Original-Tabelle und die @code{CREATE}-
+und @code{INSERT}-Berechtigungen auf die neue Tabelle.
+
+Wenn beim Umbenennen mehrfacher Tabellen Fehler auftreten, führt MySQL ein
+entgegengesetztes Umbenennen aller umbenannten Tabellen durch, um alles
+wieder in den Ausgangszustand zu versetzen.
+
+
+@node DROP TABLE, CREATE INDEX, RENAME TABLE, Data Definition
+@c German node DROP TABLE
+@subsection @code{DROP TABLE}-Syntax
+
+@findex DROP TABLE
+
+@example
+DROP TABLE [IF EXISTS] tabelle [, tabelle,...] [RESTRICT | CASCADE]
+@end example
+
+@code{DROP TABLE} entfernt eine oder mehrere Tabellen. Alle Tabellendaten
+und die Tabellendefinition werden @emph{zerstört}, seien Sie daher
+@strong{vorsichtig} mit diesem Befehl!
+
+Ab MySQL-Version 3.22 können Sie die Schlüsselwörter @code{IF EXISTS}
+benutzen, um Fehler zu vermeiden, die auftreten, wenn Tabellen nicht
+existieren.
+
+@code{RESTRICT} und @code{CASCADE} sind wegen leichterer Portierung
+zugelassen. Momentan tun sie nichts.
+
+@strong{HINWEIS}: @code{DROP TABLE} ist nicht transaktionssicher und führt
+automatisch jegliche aktiven Transaktionen zuende.
+
+
+@node CREATE INDEX, DROP INDEX, DROP TABLE, Data Definition
+@c German node CREATE INDEX
+@subsection @code{CREATE INDEX}-Syntax
+
+@findex CREATE INDEX
+
+@cindex Indexe
+@cindex Indexe, mehrteilige
+@cindex mehrteilige Indexe
+
+@example
+CREATE [UNIQUE|FULLTEXT] INDEX index_name ON tabelle (spalten_name[(laenge)],... )
+@end example
+
+Das @code{CREATE INDEX}-Statement macht vor MySQL-Version 3.22 nichts. Ab
+Version 3.22 ist @code{CREATE INDEX} auf ein @code{ALTER TABLE}-Statement
+gemappt, um Indexe zu erzeugen. @xref{ALTER TABLE, , @code{ALTER TABLE}}.
+
+Normalerweise erzeugen Sie alle Indexe auf eine Tabelle zur Zeit, wo die
+Tabelle selbst mit @code{CREATE TABLE} erzeugt wird.
+@c German FIX unsplit @xref
+@xref{CREATE TABLE, ,@code{CREATE TABLE}}.
+@code{CREATE INDEX} gestattet, bestehenden Tabellen
+Indexe hinzuzufügen.
+
+A Spaltenliste der Form @code{(spalte1,spalte2,...)} erzeugt einen
+mehrspaltigen Index. Die Indexwerte werden durch Verkettung der Werte der
+angegebenen Spalten erzeugt.
+
+Bei @code{CHAR}- und @code{VARCHAR}-Spalten können Indexe, die nur einen
+Teil einer Spalte benutzen, mit der @code{spalten_name(laenge)}-Syntax
+erzeugt werden. (Bei @code{BLOB}- und @code{TEXT}-Spalten ist die
+Längenangabe erforderlich.) Unten stehendes Statement zeigt, wie ein Index
+erzeugt wird, der die ersten 10 Zeichen der @code{name}-Spalte benutzt:
+
+@example
+mysql> CREATE INDEX teil_von_name ON kunde (name(10));
+@end example
+
+Weil sich die meisten Namen üblicherweise in den ersten 10 Zeichen
+unterscheiden, sollte dieser Index nicht viel langsamer sein, als wenn der
+Index aus der gesamten @code{name}-Spalte erzeugt worden wäre. Die
+Benutzung von Teilspalten für Indexe kann die Index-Datei auch viel kleiner
+machen, was viel Speicherplatz sparen und zusätzlich
+@code{INSERT}-Operationen beschleunigen kann!
+
+Beachten Sie, dass Sie einen Index auf eine Spalte, die @code{NULL}-Werte
+haben darf, oder auf eine @code{BLOB}/@code{TEXT}-Spalte erst ab
+MySQL-Version 3.23.2 und nur beim @code{MyISAM}-Tabellentyp erzeugen
+können.
+
+Weitere Informationen darüber, wie MySQL Indexe benutzt, finden Sie unter
+@ref{MySQL indexes, , MySQL-Indexe}.
+
+@code{FULLTEXT}-Indexe können nur @code{VARCHAR}- und @code{TEXT}-Spalten
+indexieren und funktionieren nur bei @code{MyISAM}-Tabellen.
+@code{FULLTEXT}-Indexe sind ab MySQL-Version 3.23.23 verfügbar.
+@ref{Fulltext Search}.
+
+
+@node DROP INDEX, , CREATE INDEX, Data Definition
+@c German node DROP INDEX
+@subsection @code{DROP INDEX}-Syntax
+
+@findex DROP INDEX
+
+@example
+DROP INDEX index_name ON tabelle
+@end example
+
+@code{DROP INDEX} löscht den Index namens @code{index_name} aus der Tabelle
+@code{tabelle}. @code{DROP INDEX} macht vor MySQL-Version 3.22 nichts. Ab
+Version 3.22 ist @code{DROP INDEX} auf ein @code{ALTER TABLE}-Statement
+gemappt, um den Index zu löschen. @xref{ALTER TABLE, , @code{ALTER TABLE}}.
+
+
+@node Basic User Commands, Transactional Commands, Data Definition, Reference
+@c German node Grundlegende Benutzerbefehle
+@section Grundlegende Befehle des MySQL-Dienstprogramms für Benutzer
+
+
+
+@menu
+* USE::
+* DESCRIBE::
+@end menu
+
+@node USE, DESCRIBE, Basic User Commands, Basic User Commands
+@c German node USE
+@subsection @code{USE}-Syntax
+
+@findex USE
+
+@example
+USE datenbank
+@end example
+
+Das @code{USE datenbank}-Statement weist MySQL an, @code{datenbank} als
+vorgabemäßige Datenbank für nachfolgende Anfragen zu benutzen. Die
+Datenbank bleibt die aktuelle, entweder bis zum Ende der Sitzung, oder bis
+ein weiteres @code{USE}-Statement abgesetzt wird:
+
+@example
+mysql> USE datenbank1;
+mysql> SELECT count(*) FROM tabelle; # wählt aus von datenbank1.tabelle
+mysql> USE datenbank2;
+mysql> SELECT count(*) FROM tabelle; # wählt aus von datenbank2.tabelle
+@end example
+
+Wenn Sie eine bestimmte Datenbank mit dem @code{USE}-Statement zu aktuellen
+machen, heißt das nicht, dass Sie nicht auf Tabellen in anderen
+Datenbanken zugreifen können. Das unten stehende Beispiel zeigt den Zugriff
+auf die @code{autor}-Tabelle in der @code{datenbank1}-Datenbank und auf
+die @code{herausgeber}-Tabelle in der @code{datenbank2}-Datenbank:
+
+@example
+mysql> USE datenbank1;
+mysql> SELECT autor_name,herausgeber_name FROM autor,datenbank2.herausgeber
+ WHERE autor.herausgeber_id = datenbank2.herausgeber.herausgeber_id;
+@end example
+
+@cindex Sybase Kompatibilität
+@cindex Kompatibilität, mit Sybase
+The @code{USE}-Statement wird für die Sybase-Kompatibilität zur Verfügung
+gestellt.
+
+
+@node DESCRIBE, , USE, Basic User Commands
+@c German node DESCRIBE
+@subsection @code{DESCRIBE}-Syntax (Informationen über Spalten erhalten)
+
+@findex DESC
+@findex DESCRIBE
+
+@example
+@{DESCRIBE | DESC@} tabelle @{spalten_name | platzhalter@}
+@end example
+
+@code{DESCRIBE} ist ein Kürzel für @code{SHOW COLUMNS FROM}.
+@xref{SHOW DATABASE INFO}.
+
+@code{DESCRIBE} stellt Informationen über die Spalten einer Tabelle bereit.
+@code{spalten_name} kann ein Spaltenname oder eine Zeichenkette sein, die
+die SQL-@samp{%}- und -@samp{_}-Platzhalterzeichen enthält.
+
+Wenn die Spaltentypen sich von dem unterscheiden, was Sie auf der Grundlage
+eines @code{CREATE TABLE}-Statements erwartet hätten, beachten Sie, dass
+MySQL manchmal Spaltentypen ändert. @xref{Silent column changes}.
+
+@cindex Oracle-Kompatibilität
+@cindex Kompatibilität, mit Oracle
+Dieses Statement wird für die Oracle-Kompatibilität zur Verfügung gestellt.
+
+Das @code{SHOW}-Statement stellt ähnliche Informationen bereit.
+@xref{SHOW, , @code{SHOW}}.
+
+
+@node Transactional Commands, Fulltext Search, Basic User Commands, Reference
+@c German node Transaktionale Befehle
+@section Transaktionale und Sperrbefehle von MySQL
+
+
+
+@menu
+* COMMIT::
+* LOCK TABLES::
+* SET TRANSACTION::
+@end menu
+
+@node COMMIT, LOCK TABLES, Transactional Commands, Transactional Commands
+@c German node COMMIT
+@subsection @code{BEGIN/COMMIT/ROLLBACK}-Syntax
+
+@findex BEGIN
+@findex COMMIT
+@findex ROLLBACK
+
+Vorgabemäßig läuft MySQL im @code{autocommit}-Modus. Das heißt, dass
+MySQL eine Aktualisierung auf Platte speichert, sobald Sie eine
+Aktualisierung ausführen.
+
+Wenn Sie transaktionssichere Tabellen (wie @code{InnoDB} oder @code{BDB} )
+benutzen, können Sie MySQL mit folgendem Befehl in den
+Nicht-@code{autocommit}-Modus setzen:
+
+@example
+SET AUTOCOMMIT=0
+@end example
+
+Danach müssen Sie @code{COMMIT} benutzen, um Ihre Änderungen auf Platte zu
+sichern, oder @code{ROLLBACK}, wenn Sie die Änderungen verwerfen wollen,
+die Sie seit dem Beginn der Transaktion gemacht haben.
+
+Wenn Sie für eine Reihe von Statements zum @code{AUTOCOMMIT}-Modus
+umschalten wollen, können Sie das @code{BEGIN}- oder @code{BEGIN
+WORK}-Statement benutzen:
+
+@example
+BEGIN;
+SELECT @@A:=SUM(gehalt) FROM tabelle1 WHERE type=1;
+UPDATE tabelle2 SET zusammenfassung=@@A WHERE type=1;
+COMMIT;
+@end example
+
+Beachten Sie, dass bei der Benutzung nicht transaktionssicher Tabellen die
+Änderungen dennoch sofort gespeichert werden, unabhängig vom Status des
+@code{autocommit}-Modus.
+
+Wenn Sie @code{ROLLBACK} bei der Aktualisierung einer nicht transaktionalen
+Tabelle ausführen, erhalten Sie einen Fehler
+(@code{ER_WARNING_NOT_COMPLETE_ROLLBACK}) als Warnung. Alle
+transaktionssicheren Tabellen werden zurückgesetzt, aber nicht
+transaktionale Tabelle ändern sich nicht.
+
+Wenn Sie @code{BEGIN} oder @code{SET AUTOCOMMIT=0} benutzen, sollten Sie
+die MySQL-Binär-Log-Datei für Datensicherungen benutzen statt der älteren
+Update-Log-Datei. Transaktionen werden in der Binär-Log-Datei in einem
+Stück gespeichert, beim @code{COMMIT}, um sicherzustellen, dass
+Transaktionen, die zurückgesetzt werden (Rollback), nicht gespeichert
+werden. @xref{Binary log}.
+
+Folgende Befehle beenden automatisch eine Transaktion (als ob Sie ein
+@code{COMMIT} vor der Ausführung des Befehls ausgeführt hätten:
+
+@multitable @columnfractions .33 .33 .33
+@item @code{ALTER TABLE} @tab @code{BEGIN} @tab @code{CREATE INDEX}
+@item @code{DROP DATABASE} @tab @code{DROP TABLE} @tab @code{RENAME TABLE}
+@item @code{TRUNCATE}
+@end multitable
+
+@c German FIX changed @xref to @xref
+Sie können die Isolationsebene (Isolation Level) für Transaktionen mit
+@code{SET TRANSACTION ISOLATION LEVEL ...} @ref{SET TRANSACTION} ändern.
+
+
+@node LOCK TABLES, SET TRANSACTION, COMMIT, Transactional Commands
+@c German node LOCK TABLES
+@subsection @code{LOCK TABLES/UNLOCK TABLES}-Syntax
+
+@findex LOCK TABLES
+@findex UNLOCK TABLES
+
+@example
+LOCK TABLES tabelle [AS alias] @{READ | [READ LOCAL] | [LOW_PRIORITY] WRITE@}
+ [, tabelle @{READ | [LOW_PRIORITY] WRITE@} ...]
+...
+UNLOCK TABLES
+@end example
+
+@code{LOCK TABLES} sperrt Tabellen für den aktuellen Thread. @code{UNLOCK
+TABLES} hebt alle Sperren auf, die vom aktuellen Thread veranlasst wurden.
+Alle Tabellen, die durch den aktuellen Thread gesperrt sind, werden
+automatisch entsperrt, wenn der Thread ein weiteres @code{LOCK TABLES}
+absetzt oder wenn die Verbindung zum Server geschlossen wird.
+
+Die wichtigsten Gründe für die Benutzung von @code{LOCK TABLES} sind die
+Emulation von Transaktionen oder um mehr Geschwindigkeit bei der
+Aktualisierung von Tabellen zu erhalten. Das wird später detaillierter
+erläutert.
+
+Wenn ein Thread eine @code{READ}-Sperre auf eine Tabelle erlangt, kann
+dieser Thread (und alle anderen Threads) nur aus der Tabelle lesen. Wenn
+ein Thread eine @code{WRITE}-Sperre auf eine Tabelle erlangt, kann nur der
+Thread, der die Sperre veranlasst hat, @code{READ} oder @code{WRITE} auf
+der Tabelle durchführen. Andere Threads werden blockiert.
+
+Der Unterschied zwischen @code{READ LOCAL} und @code{READ} ist, dass
+@code{READ LOCAL} nicht kollidierende @code{INSERT}-Statements während der
+Dauer der Sperre zuläßt. Das kann jedoch nicht benutzt werden, wenn Sie
+Datenbankdateien ausserhalb von MySQL bearbeiten, während die Sperre aktiv
+ist.
+
+Wenn Sie @code{LOCK TABLES} benutzen, müssen Sie alle Tabellen sperren, die
+Sie benutzen werden, und Sie müssen denselben Alias benutzen, den Sie in
+Ihren Anfragen benutzen werden! Wenn Sie eine Tabelle in einer Anfrage
+mehrfach (mit Aliasen) benutzen, müssen Sie für jeden Alias eine Sperre
+machen!
+
+@code{WRITE}-Sperren haben normalerweise höhere Priorität als
+@code{READ}-Sperren, um sicherzustellen, dass Aktualisierungen so früh wie
+möglich bearbeitet werden. Dass heißt, wenn ein Thread eine
+@code{READ}-Sperre erlangt und dann ein anderer Thread eine
+@code{WRITE}-Sperre verlangt, dass nachfolgende @code{READ}-Sperrenanfragen
+warten, bis der @code{WRITE}-Thread die Sperre erhalten und freigegeben
+hat. Sie können @code{LOW_PRIORITY WRITE}-Sperren benutzen, um anderen
+Threads zu gestatten, @code{READ}-Sperren zu erlangen, während der Thread
+auf die @code{WRITE}-Sperre wartet. Sie sollten nur dann @code{LOW_PRIORITY
+WRITE}-Sperren benutzen, wenn Sie sicher sind, dass es irgendwann eine Zeit
+gibt, in der kein anderer Thread eine @code{READ}-Sperre haben wird.
+
+@code{LOCK TABLES} funktioniert wie folgt:
+@enumerate
+@item
+Sortiert alle Tabellen, die gesperrt werden sollen, in einer intern
+definierten Reihenfolge (aus Benutzersicht ist die Reihenfolge
+undefiniert).
+@item
+Wenn eine Tabelle mit einer Lese- und einer Schreibsperre gesperrt ist,
+wird die Schreibsperre vor die Lesesperre platziert.
+@item
+Sperrt eine Tabelle nach der anderen, bis der Thread alle Sperren erhalten
+hat.
+@end enumerate
+
+Diese Methode stellt sicher, dass Tabellensperren blockierungsfrei ist. Bei
+diesem Schema gibt es jedoch ein paar weitere Dinge, derer man sich bewusst
+sein muss:
+
+Wenn Sie eine @code{LOW_PRIORITY_WRITE}-Sperre für eine Tabelle benutzen,
+heißt das, dass MySQL auf diese bestimmte Sperre wartet, bis es keinen
+Thread gibt, der eine @code{READ}-Sperre will. Wenn der Thread die
+@code{WRITE}-Sperre erhalten hat und darauf wartet, die Sperre für die
+nächste Tabelle in der Tabellensperrliste zu erhalten, warten alle anderen
+Threads darauf, dass die @code{WRITE}-Sperre aufgehoben wird. Wenn das bei
+Ihrer Applikation zu ernsthaften Problemen führt, sollten Sie in Betracht
+ziehen, einige Ihrer Tabelle in transaktionssichere Tabelle umzuwandeln.
+
+Es ist sicher, einen Thread mit @code{KILL} zu killen, der auf eine
+Tabellensperre wartet. @xref{KILL}.
+
+Beachten Sie, dass Sie @strong{NICHT} irgend welche Tabellen sperren
+sollten, die Sie mit @code{INSERT DELAYED} benutzen. Das liegt darin, dass
+in diesem Fall das @code{INSERT} von einem separaten Thread durchgeführt
+wird.
+
+Normalerweise müssen Sie Tabellen nicht sperren, weil alle einzelnen
+@code{UPDATE}-Statements atomisch sind. Kein anderer Thread kann mit einem
+aktuell ausgeführten SQL-Statement in die Quere kommen. Es gibt dennoch
+einige Fällen, in denen es wünschenswert sein kann, Tabellen zu sperren:
+
+@itemize @bullet
+@item
+Wenn Sie viele Operationen auf einer großen Zahl von Tabellen laufen
+lassen wollen, ist es viel schneller, die Tabellen zu sperren, die Sie
+benutzen werden. Der Nachteil besteht natürlich darin, dass kein anderer
+Thread eine @code{READ}-gesperrte Tabelle aktualisieren und kein anderer
+Thread eine @code{WRITE}-gesperrte Tabelle lesen kann.
+
+Der Grund, dass einiges mit @code{LOCK TABLES} schneller geht, liegt darin,
+dass MySQL den Schlüssel-Cache für die gesperrten Tabellen nicht auf Platte
+zurückschreibt (flush), bis @code{UNLOCK TABLES} aufgerufen wird
+(normalerweise wird der Schlüssel-Cache nach jedem SQL-Statement auf Platte
+zurückgeschrieben). Das erhöht die Geschwindigkeit bei den Operationen
+INSERT / UPDATE / DELETE bei @code{MyISAM}-Tabellen.
+@item
+Wenn Sie einen Tabellen-Handler in MySQL benutzen, der keine Transaktionen
+unterstützt, müssen Sie @code{LOCK TABLES} benutzen, wenn Sie sicherstellen
+wollen, dass kann anderer Thread zwischen einem @code{SELECT} und einem
+@code{UPDATE} dazwischen kommen kann. Das unten stehende Beispiel erfordert
+@code{LOCK TABLES}, um sicher ausgeführt zu werden:
+
+@example
+mysql> LOCK TABLES trans READ, kunde WRITE;
+mysql> select sum(wert) from trans where kunde_id=irgendeine_id;
+mysql> update kunde set gesamt_wert=summe_aus_vorherigem_statement
+ where kunde_id=irgendeine_id;
+mysql> UNLOCK TABLES;
+@end example
+
+Ohne @code{LOCK TABLES} besteht die Möglichkeit, dass ein anderer Thread
+eine neue Zeile in die @code{trans}-Tabelle einfügt, zwischen der
+Ausführung des @code{SELECT}- und des @code{UPDATE}-Statements.
+@end itemize
+
+Wenn Sie inkrementelle Updates (@code{UPDATE kunde SET
+wert=wert+neuer_wert}) oder die @code{LAST_INSERT_ID()}-Funktion benutzen,
+können Sie @code{LOCK TABLES} in vielen Fällen vermeiden.
+
+Einige Problemfälle können Sie auch lösen, indem Sie die Sperrfunktionen
+auf Benutzerebene @code{GET_LOCK()} und @code{RELEASE_LOCK()} benutzen.
+Diese Sperren werden in einer Hash-Tabelle im Server gespeichert und sind
+mit @code{pThread_mutex_lock()} und @code{pThread_mutex_unlock()} für die
+Erzielung höherer Geschwindigkeit implementiert.
+@xref{Miscellaneous functions}.
+
+Siehe @ref{Internal locking} wegen weiterer Informationen über
+Sperrmethoden.
+
+Sie können alle Tabellen in allen Datenbanken mit Lesesperren sperren, und
+zwar mit dem @code{FLUSH TABLES WITH READ LOCK}-Befehl. @xref{FLUSH}. Das
+ist eine sehr bequeme Möglichkeit, Datensicherungen zu erhalten, wenn Sie
+ein Dateisystem wie Veritas haben, dass Schnappschüsse im Zeitverlauf
+aufnehmen kann.
+
+@strong{HINWEIS}: @code{LOCK TABLES} ist nicht transaktionssicher und
+schickt automatisch jegliche aktiven Transaktionen ab (Commit), bevor es
+versucht, die Tabellen zu sperren.
+
+
+@node SET TRANSACTION, , LOCK TABLES, Transactional Commands
+@c German node SET TRANSACTION
+@subsection @code{SET TRANSACTION}-Syntax
+
+@findex ISOLATION LEVEL
+
+@example
+SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
+[READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]
+@end example
+
+Setzt die Transaktionsisolationsebene für die globale, gesamte Sitzung oder
+für die nächste Transaktion.
+
+Das vorgabemäßige Verhalten ist das Setzen der Isolationsebene für die
+nächste (nicht angefangene) Transaktion.
+
+Wenn Sie die @code{GLOBAL}-Berechtigung setzen, betrifft das alle neu
+erzeugten Threads. Sie benötigen dafür die @code{PROCESS}-Berechtigung.
+
+Wenn Sie die @code{SESSION}-Berechtigung setzen, betrifft das die folgenden
+und alle zukünftigen Transaktionen.
+
+Sie können die vorgabemäßige Isolationsebene für @code{mysqld} mit
+@code{--transaction-isolation=...} setzen. @xref{Command-line options}.
+
+
+@node Fulltext Search, Query Cache, Transactional Commands, Reference
+@c German node Volltextsuche
+@section MySQL-Volltextsuche
+
+@cindex Suchen, Volltext
+@cindex Volltextsuche
+@cindex FULLTEXT
+
+Ab Version 3.23.23 bietet MySQL Unterstützung für Volltext-Indexierung und
+-Suche. Volltext-Indexe sind in MySQL Indexe vom Typ @code{FULLTEXT}.
+@code{FULLTEXT}-Indexe können von @code{VARCHAR}- und @code{TEXT}-Spalten
+zur Zeit von @code{CREATE TABLE} erzeugt werden oder später mit @code{ALTER
+TABLE} oder @code{CREATE INDEX} hinzugefügt werden. Bei großen Datenmengen
+ist es viel schneller, einen @code{FULLTEXT}-Index mit @code{ALTER TABLE}
+(oder @code{CREATE INDEX}) hinzuzufügen, als Zeilen in eine leere Tabelle
+mit einem @code{FULLTEXT}-Index einzufügen.
+
+Die Volltextsuche wird mit der @code{MATCH}-Funktion durchgeführt.
+
+@example
+mysql> CREATE TABLE artikel (
+ -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ -> titel VARCHAR(200),
+ -> artikeltext TEXT,
+ -> FULLTEXT (titel,artikeltext)
+ -> );
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> INSERT INTO artikel VALUES
+ -> (0,'MySQL-Tutorial', 'DBMS steht für DataBase-Management ...'),
+ -> (0,'Wie man MySQL effizient einsetzt', 'Nachdem Sie ...'),
+ -> (0,'MySQL optimieren','In diesem Tutorial wird gezeigt, wie ...'),
+ -> (0,'1001 MySQL-Tricks','1. Lassen Sie mysqld nie als root laufen. 2. Normalisieren ...'),
+ -> (0,'MySQL vs. YourSQL', 'Im folgenden Datenbankvergleich ...'),
+ -> (0,'MySQL-Sicherheitsaspekte', 'Wenn er korrekt konfiguriert ist, ist MySQL ...');
+Query OK, 5 rows affected (0.00 sec)
+Records: 5 Duplicates: 0 Warnings: 0
+
+mysql> SELECT * FROM artikel WHERE MATCH (titel,artikeltext) AGAINST ('Datenbank');
++----+-------------------+---------------------------------------------+
+| id | titel | artikeltext |
++----+-------------------+---------------------------------------------+
+| 5 | MySQL vs. YourSQL | Im folgenden Datenbankvergleich ... |
+| 1 | MySQL-Tutorial | DBMS steht für DataBase-Management ... |
++----+-------------------+---------------------------------------------+
+2 rows in set (0.00 sec)
+@end example
+
+Die Funktion @code{MATCH} prüft eine natürlichsprachige Anfrage gegen
+(@code{AGAINST}) eine Textsammlung (einfach ein Satz von Spalten, der vom
+@code{FULLTEXT}-Index abgedeckt wird). Für jede Zeile in einer Tabelle gibt
+sie eine Relevanz zurück - ein Ähnlichkeitsmaß zwischen dem Text in dieser
+Zeile (in den Spalten, die Teil der Textsammlung sind) und der Anfrage.
+Wenn sie in einer @code{WHERE}-Klausel benutzt wird (siehe Beispiel oben),
+werden die zurückgegebenen Zeilen automatisch nach absteigender Relevanz
+sortiert. Die Relevanz ist eine nicht negative Fließkommazahl. 0 Relevanz
+bedeutet keine Ähnlichkeit. Die Relevanz wird auf der Grundlage der Anzahl
+von Wörtern in der Zeile, der Anzahl eindeutiger Wörter in dieser Zeile,
+der Gesamtzahl von Wörtern in der Textsammlung und der Anzahl von
+Dokumenten (Zeilen) berechnet, die ein bestimmtes Wort enthalten.
+
+Das obige Beispiel ist ein grundlegendes Beispiel der Benutzung der
+@code{MATCH}-Funktion. Die Zeilen werden nach absteigender Relevanz
+zurückgegeben.
+
+@example
+mysql> SELECT id,MATCH (titel,artikeltext) AGAINST ('Tutorial') FROM artikel;
++----+------------------------------------------------+
+| id | MATCH (titel,artikeltext) AGAINST ('Tutorial') |
++----+------------------------------------------------+
+| 1 | 0.64840710366884 |
+| 2 | 0 |
+| 3 | 0.66266459031789 |
+| 4 | 0 |
+| 5 | 0 |
+| 6 | 0 |
++----+------------------------------------------------+
+5 rows in set (0.00 sec)
+@end example
+
+Dieses Beispiel zeigt, wie man Relevanzen abruft. Weil weder die
+@code{WHERE}- noch die @code{ORDER BY}-Klausel vorhanden sind, werden die
+Zeilen unsortiert zurückgegeben.
+
+@example
+mysql> SELECT id, artikeltext, MATCH (titel,artikeltext) AGAINST (
+ -> 'Sicherheits-Implikationen, wenn Sie MySQL als root laufen lassen') AS rang
+ -> FROM artikel WHERE MATCH (titel,artikeltext) AGAINST
+ -> ('Sicherheits-Implikationen, wenn Sie MySQL als root laufen lassen');
++----+----------------------------------------------------------------+-----------------+
+| id | artikeltext | rang |
++----+----------------------------------------------------------------+-----------------+
+| 4 | 1. Lassen Sie mysqld nie als root laufen. 2. Normalisieren ... | 1.5055546709332 |
+| 6 | Wenn er korrekt konfiguriert ist, ist MySQL ... | 1.31140957288 |
++----+----------------------------------------------------------------+-----------------+
+2 rows in set (0.00 sec)
+@end example
+
+Das ist ein komplexeres Beispiel - die Anfrage gibt die Relevanz zurück und
+sortiert die Zeilen auch noch nach absteigender Relevanz. Um das zu
+erzielen, müssen Sie @code{MATCH} zweimal angeben. Beachten Sie, dass das
+keinen zusätzlichen Overhead verursacht, weil der MySQL-Optimierer bemerkt,
+dass diese zwei @code{MATCH}-Aufrufe identisch sind und daher den Code für
+die Volltextsuche nur einmal aufruft.
+
+MySQL benutzt einen sehr einfachen Parser, um Text in Wörter zu zerlegen.
+Ein ``Wort'' ist jede Folge von Buchstaben, Zahlen, @samp{'} und @samp{_}.
+Jedes ``Wort'', das in der Liste der Stopwords vorkommt oder einfach nur
+zu kurz ist (3 Zeichen oder weniger), wird ignoriert.
+
+Jedes korrekte Wort in der Textsammlung und in der Anfrage wird nach seiner
+Signifikanz in der Anfrage oder der Textsammlung gewichtet. Daher hat ein
+Wort, dass in vielen Dokumenten vorkommt, ein geringeres Gewicht (und kann
+sogar 0 Gewicht haben), weil es in dieser bestimmten Textsammlung einen
+geringen semantischen Wert hat. Ansonsten, wenn das Wort selten vorkommt,
+erhält es ein höheres Gewicht. Die Gewichte der Wörter werden anschließend
+kombiniert, um die Relevanz der Zeile zu berechnen.
+
+Solch eine Technik funktioniert am besten bei großen Textsammlungen (in
+der Tat wurde sie sorgfältig darauf optimiert). Bei sehr kleinen Tabellen
+spiegelt die Wortverteilung nicht adäquat seinen semantischen Wert wider,
+so dass dieses Modell manchmal bizarre Ergebnisse ergeben kann:
+
+@example
+mysql> SELECT * FROM artikel WHERE MATCH (titel,artikeltext) AGAINST ('MySQL');
+Empty set (0.00 sec)
+@end example
+
+Die Suche nach dem Wort @code{MySQL} erzeugt im obigen Beispiel keine
+Ergebnisse. Das Wort @code{MySQL} ist in mehr als der Hälfte der Zeilen
+vorhanden und wird deshalb als Stopword betrachtet (eins mit dem
+semantischen Wert 0). Das ist in der Tat das gewünschte Verhalten - eine
+natürlichsprachige Anfrage sollte bei einer 1 GB großen Tabelle nicht jede
+zweite Zeile zurückgeben.
+
+Bei einem Wort, dass in der Hälfte der Zeilen in einer Tabelle
+übereinstimmt, ist es nicht sehr wahrscheinlich, dass relevante Dokumente
+gefunden werden, sondern statt dessen viele irrelevante Dokumente. Das
+kennen wir alle aus Recherchen über Suchmaschinen auf dem Internet. Das ist
+die Überlegung, die dahinter steht, dass solchen Wörtern ein niedriger
+semantischer Wert @strong{in diesem bestimmten Satz von Daten} gegeben
+wird.
+
+
+
+@menu
+* Fulltext Restrictions::
+* Fulltext Fine-tuning::
+* Volltext-Features in MySQL 4.0::
+* Fulltext TODO::
+@end menu
+
+@node Fulltext Restrictions, Fulltext Fine-tuning, Fulltext Search, Fulltext Search
+@c German node Volltext-Einschränkungen
+@subsection Volltext-Einschränkungen
+
+@itemize @bullet
+@item
+Alle Parameter der @code{MATCH}-Funktion müssen Spalten derselben Tabelle
+sein, die Teil desselben Volltext-Indexes ist.
+@item
+Das Argument für @code{AGAINST} muss eine Konstanten-Zeichenkette sein.
+@end itemize
+
+
+@node Fulltext Fine-tuning, Volltext-Features in MySQL 4.0, Fulltext Restrictions, Fulltext Search
+@c German node Volltext-Feineinstellungen
+@subsection MySQL-Volltextsuche fein einstellen
+
+@c German FIX changed @xref to @pxref
+Leider hat die Volltextsuche noch keine durch den Benutzer einstellbare
+Parameter, doch diese stehen sehr weit oben auf der TODO-Liste. Wenn Sie
+jedoch eine MySQL-Quelldistribution
+(@pxref{Installing source})
+haben, können Sie das Verhalten der Volltextsuche in einiger Hinsicht
+ändern.
+
+Beachten Sie, dass die Volltextsuche sorgfältig auf beste Sucheffektivität
+eingestellt wurde. Wenn Sie dieses vorgabemäßige Verhalten ändern, wird
+das die Suchergebnisse in den meisten Fällen verschlechtern. Ändern Sie die
+MySQL-Quelltexte deshalb nur, wenn Sie genau wissen, was Sie tun!
+
+@itemize @bullet
+
+@item
+Die minimale zu indexierende Wortlänge wird in der
+@code{myisam/ftdefs.h}-Datei in folgender Zeile festgelegt:
+@example
+#define MIN_WORD_LEN 4
+@end example
+Ändern Sie diesen Wert nach Belieben, kompilieren Sie MySQL neu und bauen
+Sie Ihre @code{FULLTEXT}-Indexe neu auf.
+
+@item
+Die Stopword-Liste wird in @code{myisam/ft_static.c} definiert. Ändern Sie
+sie nach Ihrem Geschmack, kompilieren Sie MySQL neu und bauen Sie Ihre
+@code{FULLTEXT}-Indexe neu auf.
+
+@item
+Die 50%-Schwelle wird durch das spezielle, ausgewählte Gewichtungsschema
+festgelegt. Um dieses abzuschalten, ändern Sie folgende Zeile in
+@code{myisam/ftdefs.h}:
+@example
+#define GWS_IN_USE GWS_PROB
+@end example
+zu
+@example
+#define GWS_IN_USE GWS_FREQ
+@end example
+und kompilieren Sie MySQL neu.
+In diesem Fall brauchen Sie die Indexe nicht neu aufzubauen.
+
+@end itemize
+
+
+@node Volltext-Features in MySQL 4.0, Fulltext TODO, Fulltext Fine-tuning, Fulltext Search
+@c German node <no English equivalent>
+@subsection Neue Features der Volltextsuche in MySQL 4.0
+
+Dieser Abschnitt enthält eine Auflistung der Volltext-Features, die bereits
+im MySQL-4.0-Baum implementiert sind. Er erläutert den @strong{More
+Funktionen für Volltextsuche}-Eintrag in @ref{TODO}.
+
+@itemize @bullet
+@item @code{REPAIR TABLE} mit @code{FULLTEXT}-Indexen, @code{ALTER TABLE}
+mit @code{FULLTEXT}-Indexen und @code{OPTIMIZE TABLE} mit
+@code{FULLTEXT}-Indexen läuft jetzt bis zu 100 mal schneller.
+
+@item @code{MATCH ... AGAINST} wird folgende @strong{Boolesch Operatoren}
+unterstützen:
+
+@itemize @bullet
+@item @code{+}wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile
+enthalten sein @strong{muss}.
+@item @code{-}wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile
+@strong{nicht} enthalten sein darf.
+@item @code{<} und @code{>} können benutzt werden, um die Wortgewichtung in
+der Anfrage herab- und heraufzusetzen.
+@item @code{~} kann benutzt werden, um einem 'Rausch-Wort' ein
+@strong{negatives} Gewicht zuzuweisen.
+@item @code{*} ist ein Trunkierungsoperator.
+@end itemize
+
+Die Boole'sche Suche benutzt eine vereinfachte Art, die Relevanz zu
+berechnen, die keine 50%-Schwelle hat.
+
+@item Suchen sind jetzt wegen optimierter Suchalgorithmen bis zu 2 mal
+schneller.
+
+@item Das Dienstprogramm @code{ft_dump} wurde für
+Low-Level-@code{FULLTEXT}-Index-Operationen hinzugefügt (Anfragen / Dumps /
+Statistiken).
+
+@end itemize
+
+
+@node Fulltext TODO, , Volltext-Features in MySQL 4.0, Fulltext Search
+@c German node Volltext-TODO-Liste
+@subsection Volltextsuche TODO-Liste
+
+@itemize @bullet
+@item Alle Operationen mit @code{FULLTEXT}-Index @strong{schneller} machen.
+@item Unterstützung für Klammern @code{()} in Boole'scher Volltextsuche.
+@item Phrasensuche, Näherungsoperatoren
+@item Boole'sche Suche funktioniert ohne @code{FULLTEXT}-Index (ja,
+@strong{sehr} langsam).
+@item Unterstützung für "immer indizierte Wörter". Das könnten beliebige
+Zeichenketten sein, die der Benutzer wie Wörter behandeln will. Beispiele
+sind "C++", "AS/400", "TCP/IP" usw.
+@item Unterstützung für Volltextsuche in @code{MERGE}-Tabellen.
+@item Unterstützung für Multi-Byte-Zeichensätze.
+@item Die Stopword-Liste von der Sprache der Daten abhängig machen.
+@item Eindämmen (Stemming, natürlich abhängig von der Sprache der Daten).
+@item Generischer Benutzer-unterstützbarer UDF- (?) Preparser.
+@item Das Modell flexibler machen (durch Hinzufügen einiger regulierbarer
+Parameter für @code{FULLTEXT} in @code{CREATE/ALTER TABLE}).
+@end itemize
+
+
+@c ACHTUNG! Folgender NODE ist neu seit 2002-01-15!
+@c ATTENTION! The following node ist new since 2001-01-15!
+
+@node Query Cache, , Fulltext Search, Reference
+@c German node Anfragen-Cache
+@section MySQL-Anfragen-Cache
+
+@cindex Anfragen-Cache
+@cindex @code{SELECT}, Anfragen-Cache
+
+Ab Version 4.0.1 besitzt der @code{MySQL-Server} einen
+@code{Anfragen-Cache}. Wenn er benutzt wird, speichert er den Text einer
+@code{SELECT}-Anfrage zusammen mit dem entsprechenden Ergebnis, das an den
+Client gesendet wird. Wenn eine weitere identische Anfrage empfangen wird,
+kann der Server die Ergebnisse aus dem Cache beziehen, statt dieselbe
+Anfrage zu parsen und noch einmal auszuführen.
+
+Der Anfragen-Cache ist extrem nützlich in Umgebungen, in denen sich
+(einige) Tabellen nicht häufig ändern und in denen Sie viele identische
+Anfragen haben. Das ist eine typische Situation für viele Web-Server, die
+viele dynamische Inhalte benutzen.
+
+Im folgenden finden Sie einige Performance-Daten für den Anfragen-Cache
+(die wir mit der MySQL-Benchmark-Suite auf einer Linux Alpha 2 x 500 MHz
+mit 2 GB RAM und einem 64-MB-Anfragen-Cache gewonnen haben):
+
+@itemize @bullet
+@item
+Wenn Sie den Anfragen-Cache-Code abschalten wollen, setzen Sie
+@code{query_cache_size=0}. Wenn Sie den Anfragen-Cache-Code abschalten,
+gibt es keinen bemerkbaren Overhead.
+@item
+Wenn alle Anfragen, die Sie ausführen, einfach sind (wie das Auswählen
+einer Zeile aus einer Tabelle mit einer Zeile), sich aber dennoch
+unterscheiden, so dass die Anfragen nicht gecachet werden können, ist der
+Overhead bei einem aktiven Anfragen-Cache 13%. Das sollte als Szenario für
+den schlechtesten Fall angesehen werden. Im echten Leben sind Anfragen
+jedoch meist viel komplizierter, so dass der Overhead normalerweise
+beträchtlich geringer ist.
+@item
+Die Suche nach einer Zeile in einer Einzeilen-Tabelle ist 238% schneller.
+Das kann als minimale Geschwindigkeitssteigerung für eine gecachete Anfrage
+betrachtet werden.
+@end itemize
+
+
+
+@menu
+* Query Cache How::
+* Query Cache Configuration::
+* Query Cache in SELECT::
+* Query Cache Status and Maintenance::
+@end menu
+
+@node Query Cache How, Query Cache Configuration, Query Cache, Query Cache
+@c German node Anfragen-Cache-Funktionsweise
+@subsection Wie der Anfragen-Cache funktioniert
+
+Anfragen werden vor dem Parsen verglichen, daher werden
+
+@example
+SELECT * FROM TABELLE
+@end example
+
+und
+
+@example
+Select * from tabelle
+@end example
+
+als unterschiedliche Anfragen für den Anfragen-Cache betrachtet. Anfragen
+müssen also exakt gleich sein (Byte für Byte), um als identisch erkannt zu
+werden. Zusätzlich kann eine Anfrage als unterschiedlich betrachtet werden,
+wenn ein Client zum Beispiel ein neues Kommunikationsprotokollformat
+benutzt oder einen anderen Zeichensatz als ein anderer Client.
+
+Anfragen, die unterschiedliche Datenbanken, Protokollversionen oder
+unterschiedliche vorgabemäßige Zeichensätze benutzen, werden als
+unterschiedliche Anfragen angesehen und separat gecachet.
+
+Der Cache funktioniert auch bei Anfragen der Art @code{SELECT CALC_ROWS
+...} und @code{SELECT FOUND_ROWS() ...}, weil die Anzahl der gefundenen
+Zeilen ebenfalls im Cache gespeichert wird.
+
+Wenn sich eine Tabelle ändert (@code{INSERT}, @code{UPDATE}, @code{DELETE},
+@code{TRUNCATE}, @code{ALTER} oder @code{DROP TABLE|DATABASE}), werden alle
+gecacheten Anfragen, die diese Tabelle benutzten (möglicherweise über eine
+@code{MRG_MyISAM}-Tabelle!) ungültig und werden aus dem Cache entfernt.
+
+Momentan werden alle @code{InnoDB}-Tabellen beim @code{COMMIT} als für den
+Cache ungültig gekennzeichnet. In Zukunft wird das geändert, so dass nur
+Tabellen, die in der Transaktion geändert wurden, für die entsprechenden
+Cache-Einträge als ungültig markiert werden.
+
+Eine Anfrage kann nicht gecachet werden, wenn sie eine der folgenden
+Funktionen enthält:
+@multitable @columnfractions .25 .25 .25 .25
+@item @strong{Funktion} @tab @strong{Funktion}
+ @tab @strong{Funktion} @tab @strong{Funktion}
+@item @code{Benutzerdefinierte Funktionen} @tab @code{CONNECTION_ID}
+ @tab @code{FOUND_ROWS} @tab @code{GET_LOCK}
+@item @code{RELEASE_LOCK} @tab @code{LOAD_FILE}
+ @tab @code{MASTER_POS_WAIT} @tab @code{NOW}
+@item @code{SYSDATE} @tab @code{CURRENT_TIMESTAMP}
+ @tab @code{CURDATE} @tab @code{CURRENT_DATE}
+@item @code{CURTIME} @tab @code{CURRENT_TIME}
+ @tab @code{DATABASE} @tab @code{ENCRYPT} (mit einem Parameter)
+@item @code{LAST_INSERT_ID} @tab @code{RAND}
+ @tab @code{UNIX_TIMESTAMP} (ohne Parameter) @tab @code{USER}
+@item @code{BENCHMARK}
+@end multitable
+
+Eine Anfrage kann ebenfalls nicht gecachet werden, wenn sie
+Benutzer-Variablen enthält oder wenn sie in der Form @code{SELECT ... IN
+SHARE MODE} oder der Form @code{SELECT * FROM AUTOINCREMENT_FIELD IS NULL}
+(um als ODBC-Workaround die letzte eingefügte ID abzurufen) ist.
+
+@code{FOUND ROWS()} gibt jedoch den korrekten Werte zurück, selbst wenn
+eine vorhergehende Anfrage aus dem Cache geholt wurde.
+
+Anfragen, die keinerlei Tabellen benutzen oder solche, bei denen der
+Benutzer eine Spaltenberechtigung für irgend eine der beteiligten Tabellen
+hat, werden nicht gecachet.
+
+Bevor eine Anfrage aus dem Anfragen-Cache geholt wird, prüft MySQL, ob der
+Benutzer die SELECT-Berechtigung für alle beteiligten Datenbanken und
+Tabellen hat. Wenn nicht, wird das Cache-Ergebnis nicht benutzt.
+
+@node Query Cache Configuration, Query Cache in SELECT, Query Cache How, Query Cache
+@c German node Anfragen-Cache-Konfiguration
+@subsection Anfragen-Cache-Konfiguration
+
+Aufgrund des Anfragen-Caches gibt es ein paar neue @code{MySQL}
+Systemvariablen für @code{mysqld}, die in einer Konfigurationsdatei oder
+auf der Kommandozeile beim Starten von @code{mysqld} gesetzt werden können:
+
+@itemize
+@item @code{query_cache_limit}
+Keine Ergebnisse cachen, die größer als dieser Wert sind (Vorgabe 1 MB).
+
+@item @code{query_cache_size}
+Der zugewiesene Arbeitsspeicher, um Ergebnisse aus alten Anfragen zu
+speichern. Wenn er 0 ist, ist der Anfragen-Cache abgeschaltet (Vorgabe).
+
+@item @code{query_cache_startup_type}
+Dieser Wert (nur Zahlen) kann wie folgt gesetzt werden:
+@multitable @columnfractions .3 .7
+@item @strong{Option} @tab @strong{Beschreibung}
+@item 0 @tab (OFF - AUS, Ergebnisse nicht cachen oder abrufen)
+@item 1 @tab (ON - AN, alle Ergebnisse ausser @code{SELECT SQL_NO_CACHE ...}-Anfragen cachen)
+@item 2 @tab (DEMAND - AUF VERLANGEN, nur @code{SELECT SQL_CACHE ...}-Anfragen cachen)
+@end multitable
+@end itemize
+
+
+Innerhalb eines Threads (Verbindung) kann das Verhalten des Anfragen-Caches
+abweichend von der Vorgabe verändert werden. Die Syntax ist wie folgt:
+
+@code{SQL_QUERY_CACHE_TYPE = OFF | ON | DEMAND}
+@code{SQL_QUERY_CACHE_TYPE = 0 | 1 | 2}
+
+@multitable @columnfractions .3 .7
+@item @strong{Option} @tab @strong{Beschreibung}
+@item 0 oder OFF @tab Keine Ergebnisse cachen oder abrufen.
+@item 1 oder ON @tab Alle Ergebnisse ausser @code{SELECT SQL_NO_CACHE ...}-Anfragen cachen.
+@item 2 oder DEMAND @tab Nur @code{SELECT SQL_CACHE ...}-Anfragen cachen.
+@end multitable
+
+Vorgabemäßig hängt @code{SQL_QUERY_CACHE_TYPE} vom Wert von
+@code{query_cache_startup_type} ab, als der Thread erzeugt wurde.
+
+
+@node Query Cache in SELECT, Query Cache Status and Maintenance, Query Cache Configuration, Query Cache
+@c German node Anfragen-Cache in SELECT
+@subsection Anfragen-Cache-Optionen in @code{SELECT}
+
+Es gibt zwei mögliche Anfragen-Cache-bezogene Parameter, die in einer
+@code{SELECT}-Anfrage angegeben werden können:
+
+@findex SQL_CACHE
+@findex SQL_NO_CACHE
+
+@multitable @columnfractions .3 .7
+@item @strong{Option} @tab @strong{Beschreibung}
+@item @code{SQL_CACHE}
+ @tab Wenn @code{SQL_QUERY_CACHE_TYPE} @code{DEMAND} ist, darf die Anfrage gecachet werden.
+ Wenn @code{SQL_QUERY_CACHE_TYPE} @code{ON} ist, ist das die Vorgabe.
+ Wenn @code{SQL_QUERY_CACHE_TYPE} @code{OFF} ist, nichts tun.
+@item @code{SQL_NO_CACHE}
+ @tab Diese Anfrage wird nicht gecachet.
+@end multitable
+
+
+@node Query Cache Status and Maintenance, , Query Cache in SELECT, Query Cache
+@c German node Anfragen-Cache-Status und -Wartung
+@subsection Anfragen-Cache-Status und -Wartung
+
+Mit dem @code{FLUSH QUERY CACHE}-Befehl können Sie den Anfragen-Cache
+defragmentieren, um den Speicher besser zu benutzen. Dieser Befehl entfernt
+keinerlei Anfragen aus dem Cache.
+@code{FLUSH TABLES} schreibt auch den Anfragen-Cache zurück auf Platte.
+
+Der @code{RESET QUERY CACHE}-Befehl entfernt alle Anfragenergebnisse aus
+dem Anfragen-Cache.
+
+Sie können die Anfragen-Cache-Performance in @code{SHOW STATUS} beobachten:
+
+@multitable @columnfractions .3 .7
+@item @strong{Variable} @tab @strong{Beschreibung}
+@item @code{Qcache_queries_in_cache}
+ @tab Anzahl von Anfragen, die im Cache registriert sind.
+@item @code{Qcache_inserts}
+ @tab Anzahl von Anfragen, die zum Cache hinzugefügt wurden.
+@item @code{Qcache_hits}
+ @tab Anzahl von Cache-Hits.
+@item @code{Qcache_not_cached}
+ @tab Anzahl von nicht gecacheten Anfragen
+ (nicht cachebar oder wegen @code{SQL_QUERY_CACHE_TYPE}).
+@item @code{Qcache_free_memory}
+ @tab Menge des freien Speichers für den Anfragen-Cache.
+@item @code{Qcache_total_blocks}
+ @tab Gesamtzahl von Blöcken im Anfragen-Cache.
+@item @code{Qcache_free_blocks}
+ @tab Anzahl freier Speicherblöcke im Anfragen-Cache.
+@end multitable
+
+Gesamtzahl von Anfragen =
+@code{Qcache_inserts} + @code{Qcache_hits} + @code{Qcache_not_cached}.
+
+Der Anfragen-Cache benutzt variable Blocklängen, so dass
+@code{Qcache_total_blocks} und @code{Qcache_free_blocks} eine
+Speicherfragmentierung des Anfragen-Caches anzeigen können. Nach
+@code{FLUSH QUERY CACHE} verbleibt nur ein einzelner (großer) freier
+Block.
+
+Hinweis: Jede Anfrage benötigt minimal zwei Blöcke (einen für den
+Anfragentext und einen weiteren für das Anfragenergebnis). Ausserdem
+benötigt jede Tabelle, die in einer Anfrage benutzt wurde, einen Block.
+Wenn allerdings zwei oder mehr Anfragen dieselbe Tabelle benutzen, muss nur
+ein Block zugewiesen werden.
+
+
+@c ACHTUNG! Folgender NODE ist geändert, 2002-01-15!
+@c ATTENTION! The following node has been changed 2001-01-15!
+@node Table types, Clients, Reference, Top
+@c German node Tabellentypen
+@chapter MySQL-Tabellentypen
+
+@cindex Tabellentypen, Auswahl
+@cindex @code{InnoDB}-Tabellentyp
+@cindex @code{Berkeley_db}-Tabellentyp
+@cindex @code{HEAP}-Tabellentyp
+@cindex @code{ISAM}-Tabellentyp
+@cindex @code{BDB}-Tabellentyp
+@cindex @code{MERGE}-Tabellentyp
+@cindex MySQL-Tabellentypen
+@cindex @code{MyISAM}-Tabellentyp
+@cindex Typen, Tabellen-
+
+AB MySQL-Version 3.23.6 können Sie unter drei grundlegenden
+Tabellenformaten (@code{ISAM}, @code{HEAP} und @code{MyISAM} wählen. Neuere
+MySQL-Versionen können zusätzliche Tabellentypen unterstützen
+(@code{InnoDB}, oder @code{BDB}), abhängig davon, wie Sie sie kompilieren.
+
+
+Beim Erzeugen einer neuen Tabelle können Sie MySQL mitteilen, welcher
+Tabellentyp dafür benutzt werden soll. MySQL erzeugt immer eine
+@code{.frm}-Datei, die die Tabellen- und Spaltendefinitionen enthält.
+Abhängig vom Tabellentyp werden Index und Daten in anderen Dateien
+gespeichert.
+
+Beachten Sie, dass Sie für die Benutzung von @code{InnoDB}-Tabellen
+zumindest die @code{innodb_data_file_path}-Startoption benötigen.
+@xref{InnoDB start}.
+
+Der vorgabemäßige Tabellentyp in MySQL ist @code{MyISAM}. Wenn Sie
+versuchen, einen Tabellentyp zu benutzen, der nicht einkompiliert oder
+aktiviert ist, erzeugt MySQL statt dessen eine Tabelle vom Typ
+@code{MyISAM}. Das ist ein sehr nützliches Feature, wenn Sie Tabellen
+zwischen unterschiedlichen SQL-Servern kopieren wollen, die
+unterschiedliche Tabellentypen unterstützten (zum Beispiel Tabellen zu
+einem Slave kopieren, der für Geschwindigkeit optimiert ist, aber keine
+transaktionalen Tabellen hat). Dieses automatische Ändern des Tabellentyps
+kann andererseits für neue MySQL-Benutzer sehr verwirrend sein. Wir planen
+für MySQL 4.0, das zu beheben, indem eine Warnung ausgegeben wird, wenn ein
+Tabellentyp automatisch geändert wird.
+
+Sie können Tabellen zwischen unterschiedlichen Typen mit dem @code{ALTER
+TABLE}-Statement umwandeln. @xref{ALTER TABLE, , @code{ALTER TABLE}}.
+
+MySQL unterstützt zwei unterschiedliche Arten von Tabellen:
+transaktionssichere Tabellen (@code{InnoDB} und @code{BDB}) und nicht
+transaktionssichere Tabellen (@code{HEAP}, @code{ISAM}, @code{MERGE} und
+@code{MyISAM}).
+
+Vorteile transaktionssicherer Tabellen (TST):
+
+@itemize @bullet
+@item
+Sicherer. Selbst wenn MySQL abstürzt oder wenn Sie Hardware-Probleme
+bekommen, bekommen Sie Ihre Daten zurück, entweder über automatische
+Wiederherstellung oder von einer Datensicherung plus Transaktionslog-Datei.
+@item
+Sie können viele Statements kombinieren und alle in einem Rutsch mit dem
+@code{COMMIT}-Befehl akzeptieren.
+@item
+Sie können @code{ROLLBACK} ausführen, um Ihre Änderungen zu ignorieren
+(wenn Sie nicht im Auto-Commit-Modus fahren).
+@item
+Wenn eine Aktualisierung fehlschlägt, werden Ihre Änderungen
+zurückgesichert. (Bei nicht transaktionssicheren Tabellen sind
+durchgeführte Änderungen permanent.)
+@end itemize
+
+Vorteile nicht transaktionssicherer Tabellen (NTST):
+
+@itemize @bullet
+@item
+Viel schneller, da es keinen Transaktionsoverhead gibt.
+@item
+Benötigen aufgrund des fehlenden Transaktionsoverheads weniger
+Speicherplatz.
+@item
+Benötigen weniger Arbeitsspeicher für Aktualisierungen.
+@end itemize
+
+Sie können TST- and NTST-Tabellen in denselben Statements kombinieren, um
+das Beste aus beiden Welten zu bekommen.
+
+
+
+@menu
+* MyISAM::
+* MERGE::
+* ISAM::
+* HEAP::
+* InnoDB::
+* BDB::
+@end menu
+
+@node MyISAM, MERGE, Table types, Table types
+@c German node MyISAM
+@section MyISAM-Tabellen
+
+@code{MyISAM} ist der vorgabemäßige Tabellentyp in MySQL-Version 3.23. Er
+basiert auf dem @code{ISAM}-Code und hat viele nützliche Erweiterungen.
+
+Der Index wird in einer Datei mit der Endung @code{.MYI} (MYIndex)
+gespeichert, die Daten in einer Datei mit der Endung @code{.MYD} (MYData).
+Sie können @code{MyISAM}-Tabellen mit dem @code{myisamchk}-Dienstprogramm
+überprüfen und reparieren. @xref{Repair}. Sie können
+@code{MyISAM}-Tabellen mit @code{myisampack} komprimieren, damit sie viel
+weniger Speicherplatz benötigen. @xref{myisampack}.
+
+Folgende Neuerungen gibt es bei @code{MyISAM}:
+
+@itemize @bullet
+@item
+Es gibt einen Flag in der @code{MyISAM}-Datei, der anzeigt, ob die Tabelle
+korrekt geschlossen wurde. Wenn @code{mysqld} mit @code{--myisam-recover}
+gestartet wird, werden @code{MyISAM}-Tabellen beim Öffnen automatisch
+geprüft und / oder repariert, falls die Tabelle nicht korrekt geschlossen
+wurde.
+@item
+Sie können neue Zeilen in eine Tabelle, die keinerlei freie Blöcke mitten
+in der Daten-Datei hat, einfügen (@code{INSERT}), während zeitgleich
+andere Threads aus der Tabelle lesen (zeitgleiches Einfügen). Ein freier
+Block kann entstehen, wenn eine Aktualisierung einer Zeile dynamischer
+Länge, die viele Daten enthält, mit weniger Daten durchgeführt wird, oder
+wenn Zeilen gelöscht werden. Wenn alle freien Blöcke aufgebraucht sind,
+können alle zukünftigen Einfügeoperationen auf die zeitgleiche Art
+erfolgen.
+@item
+Unterstützung für große Dateien (63-Bit) auf Dateisystemen /
+Betriebssystemen, die große Dateien unterstützen.
+@item
+Alle Daten werden mit dem niedrigen Byte zuerst gespeichert. Das macht die
+Daten Maschinen- und Betriebssystem-unabhängig. Die einzige Anforderung
+ist, dass die Maschine zweien-komplementäre vorzeichenbehaftete Ganzzahlen
+(two's-complement signed integers) benutzt, was bei jeder Maschine in den
+letzten 20 Jahren der Fall war), sowie das IEEE-Fließkomma-Format (bei
+Mainstream-Maschinen absolut dominierend). Die einzige Art von Maschinen,
+die vielleicht keine Binärkompatibilität unterstützen, sind eingebettete
+Systeme (Embedded Systems), weil diese manchmal eigentümliche Prozessoren
+haben.
+
+Wenn Daten mit dem niedrigen Byte zuerst gespeichert werden, ergibt sich
+daraus kein großer Geschwindigkeitsnachteil. Die Bytes in einer
+Tabellenzeile sind normalerweise unzusammenhängend und man benötigt kaum
+mehr Ressourcen, um ein unzusammenhängendes Byte in Reihenfolge statt in
+umgekehrter Reihenfolge zu lesen. Der tatsächliche Hole-Spaltenwert-Code
+ist im Vergleich zu sonstigem Code ebenfalls nicht zeitkritisch.
+@item
+Alle Zahlenschlüssel werden mit dem hohen Byte zuerst gespeichert, um
+bessere Index-Kompression zu erzielen.
+@item
+Die interne Handhabung einer @code{AUTO_INCREMENT}-Spalte. @code{MyISAM}
+aktualisiert diese automatisch bei @code{INSERT / UPDATE}. Der
+@code{AUTO_INCREMENT}-Wert kann mit @code{myisamchk} zurückgesetzt werden.
+Das macht @code{AUTO_INCREMENT}-Spalten schneller (mindestens 10%), und
+alten Zahlen werden im Gegensatz zum alten @code{ISAM} nicht wieder
+benutzt. Beachten Sie, dass das alte Verhalten immer noch da ist, wenn ein
+@code{AUTO_INCREMENT} am Ende eines mehrteiligen Schlüssels definiert wird.
+@item
+Wenn er in sortierter Reihenfolge eingefügt wird (wie bei der Benutzung
+einer @code{AUTO_INCREMENT}-Spalte), wird der Schlüsselbaum gespalten, so
+dass der hohe Knoten nur einen Schlüssel enthält. Das verbessert die
+Platzausnutzung im Schlüsselbaum.
+@item
+@code{BLOB}- und @code{TEXT}-Spalten können indiziert werden.
+@item
+@code{NULL}-Werte sind in indizierten Spalten erlaubt. Dafür werden 0 bis 1
+Byte pro Schlüssel benötigt.
+@item
+Die maximale Schlüssellänge beträgt vorgabemäßig 500 Bytes (das kann beim
+Neukompilieren geändert werden). Wenn Schlüssel länger als 250 Bytes sind,
+wird für diese eine höhere Schlüsselblockgröße als die vorgabemäßigen
+1024 Bytes benutzt.
+@item
+Die maximale Anzahl von Schlüsseln pro Tabelle beträgt vorgabemäßig 32.
+Diese kann bis auf 64 erhöht werden, ohne dass @code{myisamchk} neu
+kompiliert werden muss.
+@item
+@code{myisamchk} kennzeichnet Tabellen als geprüft, wenn es mit
+@code{--update-state} läuft. @code{myisamchk --fast} prüft nur die
+Tabellen, die diese Kennzeichnung nicht haben.
+@item
+@code{myisamchk -a} speichert Statistiken für Schlüsselteile (und nicht nur
+für gesamte Schlüssel wie bei @code{ISAM}).
+@item
+Zeilen dynamischer Größe werden viel weniger fragmentiert werden, wenn
+Lösch- mit Aktualisierungs- und Einfügeoperationen gemischt werden. Dafür
+wird gesorgt, indem angrenzende gelöschte Blöcke automatisch kombiniert
+werden und dadurch, dass Blöcke erweitert werden, wenn der nächste Block
+gelöscht wird.
+@item
+@code{myisampack} kann @code{BLOB}- and @code{VARCHAR}-Spalten
+komprimieren.
+@item
+Sie können die Daten-Datei und die Index-Datei in unterschiedliche
+Verzeichnisse legen, um mehr Geschwindigkeit zu erhalten (mit der
+@code{DATA/INDEX DIRECTORY="pfad"}-Option für @code{CREATE TABLE}).
+@xref{CREATE TABLE}.
+@end itemize
+
+@code{MyISAM} unterstützt ausserdem die folgenden Dinge, die MySQL in naher
+Zukunft benutzen können wird:
+
+@itemize @bullet
+@item
+Unterstützung für einen echten @code{VARCHAR}-Typ. Eine
+@code{VARCHAR}-Spalte fängt mit einer in 2 Bytes gespeicherten Länge an.
+@item
+Tabellen mit @code{VARCHAR} können eine feste oder dynamische
+Datensatzlänge haben.
+@item
+@code{VARCHAR} und @code{CHAR} können bis zu 64 KB Groß sein. Alle
+Schlüsselsegmente haben ihre eigene Sprachdefinition. Das versetzt MySQL in
+die Lage, unterschiedliche Sprachdefinitionen pro Spalte zu haben.
+@item
+Ein gehashter berechneter Index kann für @code{UNIQUE} benutzt werden. Das
+erlaubt Ihnen, @code{UNIQUE} auf jeder beliebigen Kombination von Spalten
+in einer Tabelle zu haben. (Sie können jedoch auf einem @code{UNIQUE}
+berechneten Index nicht suchen.)
+@end itemize
+
+Beachten Sie, dass Index-Dateien bei @code{MyISAM} üblicherweise viel
+kleiner sind als bei @code{ISAM}. Das bedeutet, dass @code{MyISAM}
+normalerweise weniger Systemressourcen verbraucht als @code{ISAM},
+allerdings mehr Prozessorleistung beim Einfügen von Daten in einen
+komprimierten Index.
+
+Folgende Optionen für @code{mysqld} können benutzt werden, um das Verhalten
+von @code{MyISAM}-Tabellen zu ändern. @xref{SHOW VARIABLES}.
+
+@multitable @columnfractions .40 .60
+@item @strong{Option} @tab @strong{Beschreibung}
+@item @code{--myisam-recover=#}
+ @tab Automatische Wiederherstellung beschädigter Tabellen.
+@item @code{-O myisam_sort_buffer_size=#}
+ @tab Der beim Wiederherstellen von Tabellen benutzte Puffer.
+@item @code{--delay-key-write-for-all-tables}
+ @tab Keine Schlüsselpuffer zwischen Schreibvorgängen auf jedwede
+MyISAM-Tabelle zurückschreiben (flush).
+@item @code{-O myisam_max_extra_sort_file_size=#}
+ @tab Wird benutzt, um MySQL bei der Entscheidung zu helfen, wann die
+langsame, aber sichere Schlüssel-Cache-Index-Erzeugungsmethode benutzt
+werden sollte. @strong{Hinweis:} Dieser Parameter wird in Megabytes
+angegeben!
+@item @code{-O myisam_max_sort_file_size=#}
+ @tab Die schnelle Index-Sortiermethode beim Erzeugen eines Indexes nicht
+benutzen, wenn die temporäre Datei größer als dieser Wert werden würde.
+@strong{Hinweis:} Dieser Parameter wird in Megabytes angegeben!
+megabytes!--
+@item @code{-O myisam_bulk_insert_tree_size=#}
+ @tab Die Größe des Baum-Caches, der bei der Optimierung von
+Massen-Einfügeoperationen benutzt wird. @strong{Hinweis:} Das ist die
+Begrenzung @strong{pro Thread}!
+@end multitable
+
+Die automatische Wiederherstellung wird aktiviert, wenn Sie @code{mysqld}
+mit @code{--myisam-recover=#} starten. @xref{Command-line options}. Beim
+Öffnen wird geprüft, ob die Tabelle als beschädigt gekennzeichnet ist oder
+ob die Zählvariable für die Tabelle nicht 0 ist und Sie mit
+@code{--skip-locking} laufen lassen. Wenn eine dieser Bedingungen erfüllt
+ist, geschieht folgendes:
+
+@itemize @bullet
+@item
+Die Tabelle wird auf Fehler geprüft.
+@item
+Wenn ein Fehler gefunden wird, wird eine schnelle Reparatur der Tabelle
+versucht (mit Sortieren und ohne Neuerzeugung der Daten-Datei).
+@item
+Wenn die Reparatur wegen eines Fehlers in der Daten-Datei fehlschlägt (zum
+Beispiel ein Fehler wegen eines doppelten Schlüsseleintrags), wird die
+Reparatur noch einmal versucht, diesmal allerdings mit Neuerzeugung der
+Daten-Datei.
+@item
+Wenn dieser Versuch fehlschlägt, wird die Reparatur noch einmal mit der
+alten Reparaturoption versucht (Zeile für Zeile ohne Sortieren schreiben),
+was jede Sorte von Fehler beheben sollte, bei gewissen
+Festplatten-Erfordernissen ...
+@end itemize
+
+Wenn die Wiederherstellung nicht in der Lage ist, alle Zeilen aus einem
+vorher abgeschlossenen Statement wiederherzustellen, und Sie nicht
+@code{FORCE} als Option für @code{myisam-recover} angegeben haben, wird die
+automatische Reparatur mit einer Fehlermeldung in der Fehlerdatei
+abgebrochen:
+
+@example
+Error: Couldn't repair table: test.g00pages
+@end example
+
+Hätten Sie in diesem Fall die @code{FORCE}-Option benutzt, würden Sie statt
+dessen in der Fehlerdatei eine Warnung erhalten:
+
+@example
+Warning: Found 344 of 354 rows when repairing ./test/g00pages
+@end example
+
+Wenn Sie automatisches Wiederherstellung mit der @code{BACKUP}-Option
+laufen lassen, beachten Sie, dass Sie ein Cron-Skript haben sollten, dass
+automatisch Dateien mit Namen wie @file{tabellenname-datetime.BAK} aus den
+Datenbank-Verzeichnissen auf ein Sicherungsmedium verschiebt.
+
+@xref{Command-line options}.
+
+
+
+@menu
+* Key space::
+* MyISAM table formats::
+* MyISAM table problems::
+@end menu
+
+@node Key space, MyISAM table formats, MyISAM, MyISAM
+@c German node Speicherplatz für Schlüssel
+@subsection Für Schlüssel benötigter Speicherplatz
+
+@cindex Speicherplatz für Schlüssel, MyISAM
+
+MySQL unterstützt unterschiedliche Index-Typen, doch der normale Typ ist
+ISAM oder MyISAM. Diese benutzen einen B-Baum-Index, und Sie können die
+Größe der Index-Datei grob als @code{(schluessel_laenge+4)/0.67}
+kalkuliert, summiert über alle Schlüssel. (Das ist der schlechteste Fall,
+bei dem alle Schlüssel in sortierter Reihenfolge eingeordnet werden und es
+keinerlei Schlüssel-Komprimierung gibt.)
+
+Zeichenketten-Indexe werden Leerzeichen-komprimiert. Wenn der erste
+Index-Teil eine Zeichenkette ist, wird er zusätzlich Präfix-komprimiert.
+Leerzeichen-Kompression macht die Index-Datei kleiner als in den obigen
+Zahlen dargestellt, wenn die Zeichenkettenspalte viele Leerzeichen am Ende
+hat oder eine @code{VARCHAR}-Spalte ist, die nicht immer in voller Länge
+genutzt wird. Präfix-Kompression wird bei Schlüsseln benutzt, die mit einer
+Zeichenkette beginnen. Präfix-Kompression hilft, wenn es viele
+Zeichenketten mit identischem Präfix gibt.
+
+Bei @code{MyISAM}-Tabellen können Sie auch Zahlen Präfix-komprimieren,
+indem Sie beim Erzeugen der Tabelle @code{PACK_KEYS=1} angeben. Das hilft,
+wenn Sie viele Ganzzahl-Schlüssel mit identischem Präfix haben, wenn die
+Zahlen mit dem hohen Byte zuerst gespeichert werden.
+
+
+@node MyISAM table formats, MyISAM table problems, Key space, MyISAM
+@c German node MyISAM-Tabellenformate
+@subsection MyISAM-Tabellenformate
+
+@strong{MyISAM} unterstützt 3 verschiedene Tabellentypen. Zwei von ihnen
+werden automatisch gewählt, abhängig vom Spaltentyp, den Sie benutzen. Der
+dritte, komprimierte Tabellen, kann nur mit dem
+@code{myisampack}-Dienstprogramm erzeugt werden.
+
+Wenn Sie eine Tabelle erzeugen (@code{CREATE}) oder ändern (@code{ALTER}),
+können Sie bei Tabellen, die kein @code{BLOB} enthalten, ein dynamisches
+(@code{DYNAMIC}) oder festes (@code{FIXED}) Tabellenformat mit der
+@code{ROW_FORMAT=#}-Tabellenoption erzwingen. Zukünftig werden Sie in der
+Lage sein, Tabellen zu komprimieren / dekomprimieren, indem Sie
+@code{ROW_FORMAT=compressed | default} für @code{ALTER TABLE} angeben.
+@xref{CREATE TABLE}.
+
+
+
+@menu
+* Static format::
+* Dynamic format::
+* Compressed format::
+@end menu
+
+@node Static format, Dynamic format, MyISAM table formats, MyISAM table formats
+@c German node Statisches Format
+@subsubsection Kennzeichen statischer (Festlängen-) Tabellen
+
+Das ist das vorgabemäßige Format. Es wird benutzt, wenn die Tabelle keine
+@code{VARCHAR}-, @code{BLOB}- oder @code{TEXT}-Spalten enthält.
+
+Dieses Format ist das einfachste und sicherste Format. Es ist auch das
+schnellste der Formate auf Platte. Die Geschwindigkeit ergibt sich aus der
+einfachen Weise, wie Daten auf der Platte gefunden werden können. Wenn man
+etwas mit einem Index und statischem Format nachschlägt, ist es sehr
+einfach. Man multipliziert einfach die Zeilennummer mit der Zeilenlänge.
+
+Wenn eine Tabelle gescannt wird, ist es ausserdem sehr einfach, mit jedem
+Plattenzugriff eine konstante Anzahl von Datensätzen zu lesen.
+
+Die Sicherheit zeigt sich, wenn Ihr Computer beim Schreiben in eine
+MyISAM-Datei fester Länge abstürzt. In diesem Fall kann @code{myisamchk}
+leicht herausfinden, wo jede Zeile anfängt und aufhört. Daher kann es
+üblicherweise alle Datensätze mit Ausnahme desjenigen, in den nur teilweise
+geschrieben wurde, wieder herstellen. Beachten Sie, dass in MySQL alle
+Indexe in jedem Fall wiederhergestellt werden können:
+
+@itemize @bullet
+@item
+Alle @code{CHAR}-, @code{NUMERIC}- und @code{DECIMAL}-Spalten werden mit
+Leerzeichen auf die Spaltenbreite aufgefüllt.
+@item
+Sehr schnell.
+@item
+Leicht zu cachen.
+@item
+Nach einem Absturz leicht zu rekonstruieren, weil sich Datensätze an festen
+Positionen befinden.
+@item
+müssen nicht (mit @code{myisamchk}) reorganisiert werden, es sei denn, eine
+riesige Anzahl von Datensätzen wurde gelöscht und Sie wollen dem
+Betriebssystem freien Speicherplatz zurückgeben.
+@item
+Benötigen normalerweise mehr Speicherplatz als dynamische Tabellen.
+@end itemize
+
+
+@node Dynamic format, Compressed format, Static format, MyISAM table formats
+@c German node Dynamisches Format
+@subsubsection Kennzeichen dynamischer Tabellen
+
+@cindex Kennzeichen dynamischer Tabellen
+@cindex Tabellen, dynamische
+
+Dieses Format wird benutzt, wenn die Tabelle irgend welche @code{VARCHAR}-,
+@code{BLOB}- oder @code{TEXT}-Spalten enthält, oder wenn die Tabelle mit
+@code{ROW_FORMAT=dynamic} erzeugt wurde.
+
+Dieses Format ist etwas komplexer, weil jede Zeile einen Header haben muss,
+der aussagt, wie lang sie ist. Ein Datensatz kann ausserdem an mehr als
+einem Speicherplatz enden, wenn er bei einer Aktualisierung verlängert
+wird.
+
+@cindex Tabellen, defragmentieren
+Sie können @code{OPTIMIZE table} oder @code{myisamchk} benutzen, um eine
+Tabelle zu defragmentieren. Wenn Sie statische Daten haben, auf die Sie oft
+zugreifen oder die Sie in derselben Tabelle oft ändern, als @code{VARCHAR}-
+oder @code{BLOB}-Spalten haben, ist es eine gute Idee, die dynamischen
+Spalten in andere Tabellen zu verschieben, einfach um Fragmentierung zu
+vermeiden:
+
+@itemize @bullet
+@item
+Alle Zeichenketten-Spalten sind dynamisch (ausser denen mit einer Länge
+kleiner 4).
+@item
+Jedem Datensatz ist eine Bitmap vorangestellt, die angibt, welche Spalten
+bei Zeichenketten-Spalten leer (@code{''}) sind oder 0 bei numerischen
+Spalten. (Das ist nicht dasselbe wie Spalten, die @code{NULL}-Werte
+enthalten.) Wenn eine Zeichenketten-Spalte nach der Entfernung von
+Leerzeichen am Ende eine Länge von 0 hat oder eine numerische Spalte einen
+Wert von 0 hat, wird sie in der Bitmap markiert und nicht auf Platte
+gespeichert. Nicht leere Zeichenketten werden als ein Längen-Byte plus dem
+Zeichenketten-Inhalt gespeichert.
+@item
+Benötigen üblicherweise weniger Plattenplatz als Festlängen-Tabellen.
+@item
+Jeder Datensatz benutzt nur so viel Speicherplatz wie erforderlich. Wenn
+ein Datensatz größer wird, wird er in so viele Teile wie erforderlich
+aufgeteilt. Hierdurch wird Datensatzfragmentierung hervorgerufen.
+@item
+Wenn Sie eine Zeile mit Informationen aktualisieren, die die Zeilenlänge
+überschreiten, wird die Zeile fragmentiert. In diesem Fall sollten Sie von
+Zeit zu Zeit @code{myisamchk -r} laufen lassen, um bessere Performance zu
+erzielen. Benutzen Sie @code{myisamchk -ei tabellen_name}, um einige
+statistische Informationen zu erhalten.
+@item
+Sind nach einem Absturz nicht so einfach zu rekonstruieren, weil ein
+Datensatz in viele Teile fragmentiert sein und ein Link (Fragment) fehlen
+kann.
+@item
+Die erwartete Zeilenlänge bei Datensätzen dynamischer Länge ist:
+
+@example
+3
++ (anzahl_der_spalten + 7) / 8
++ (anzahl_der_zeichenketten_spalten)
++ komprimierte_groesse_numerischer_spalten
++ laenge_von_zeichenketten
++ (anzahl_von_NULL_spalten + 7) / 8
+@end example
+
+Für jeden Link kommen 6 Bytes hinzu. Ein dynamischer Datensatz wird immer
+dann verknüpft (linked), wenn eine Aktualisierung eine Vergrößerung des
+Datensatzes bewirkt. Jede neue Verknüpfung hat mindestens 20 Bytes, so dass
+die nächste Vergrößerung wahrscheinlich in dieselbe Verknüpfung passt.
+Wenn nicht, entsteht eine weitere Verknüpfung. Sie können mit
+@code{myisamchk -ed} prüfen, wie viele Verknüpfungen es gibt. Alle
+Verknüpfungen können mit @code{myisamchk -r} entfernt werden.
+@end itemize
+
+
+@node Compressed format, , Dynamic format, MyISAM table formats
+@c German node Komprimiertes Format
+@subsubsection Kennzeichen komprimierter Tabellen
+
+@cindex Tabellen, komprimiertes Format
+
+Das ist ein Nur-Lese-Typ, der mit dem optionalen
+@code{myisampack}-Dienstprogramm (@code{pack_isam} für
+@code{ISAM}-Tabellen) erzeugt wird:
+
+@itemize @bullet
+@item
+All MySQL-Distributionen, selbst diejenigen, die es vor der GPL-Version von
+MySQL gab, können Tabellen lesen, die mit @code{myisampack} komprimiert
+wurden.
+@item
+Komprimierte Tabellen benötigen viel weniger Speicherplatz. Das minimiert
+Plattenzugriffe, was sehr nett ist, wenn Sie langsame Platten benutzen (wie
+CD-ROMs).
+@item
+Jeder Datensatz wird separat komprimiert (sehr geringer Zugriffs-Overhead).
+Der Header für einen Datensatz hat eine feste Länge (1 bis 3 Bytes),
+abhängig vom größten Datensatz in der Tabelle. Jede Spalte wird
+unterschiedlich komprimiert. Einige Kompressionstypen sind:
+@itemize @minus
+@item
+Für jede Spalte gibt es üblicherweise eine unterschiedliche
+Huffman-Tabelle.
+@item
+Komprimierung von Leerzeichen am Ende.
+@item
+Komprimierung von Leerzeichen am Anfang.
+@item
+Zahlen mit dem Wert @code{0} werden mit 1 Bit gespeichert.
+@item
+Wenn Werte in einer Ganzzahl-Spalte einen kleinen Wertebereich haben, wird
+die Spalte mit dem kleinsten möglichen Typ gespeichert. Eine
+@code{BIGINT}-Spalte (8 Bytes) kann beispielsweise als
+@code{TINYINT}-Spalte (1 Byte) gespeichert werden, wenn sich alle Werte im
+Bereich von @code{0} bis @code{255} befinden.
+@item
+Wenn eine Spalte nur einen kleinen Satz möglicher Werte besitzt, wird der
+Spaltentyp zu @code{ENUM} umgewandelt.
+@item
+Eine Spalte kann auch eine Kombination der obigen Komprimierungen benutzen.
+@end itemize
+@item
+Kann Datensätze fester oder dynamischer Länge handhaben, aber nicht
+@code{BLOB}- oder @code{TEXT}-Spalten.
+@item
+Kann mit @code{myisamchk} dekomprimiert werden.
+@end itemize
+
+
+@node MyISAM table problems, , MyISAM table formats, MyISAM
+@c German node MyISAM-Tabellenprobleme
+@subsection MyISAM-Tabellenprobleme
+
+Das Dateiformat, das MySQL benutzt, um Daten zu speichern, wurde ausgiebig
+getestet, aber es gibt immer Umstände, die dazu führen können, dass
+Datenbanktabellen beschädigt werden.
+
+
+
+@menu
+* Corrupted MyISAM tables::
+* MyISAM table close::
+@end menu
+
+@node Corrupted MyISAM tables, MyISAM table close, MyISAM table problems, MyISAM table problems
+@c German node Beschädigte MyISAM-Tabellen
+@subsubsection Beschädigte MyISAM-Tabellen
+
+Obwohl das MyISAM-Tabellenformat sehr zuverlässig ist (alle Änderungen an
+einer Tabelle werden geschrieben, bevor das SQL-Statement zurückkehrt),
+können Sie dennoch beschädigte Tabellen bekommen, wenn eines der folgenden
+Dinge passiert:
+
+@itemize @bullet
+@item
+Der @code{mysqld}-Prozess wird mitten in einem Schreibvorgang gekillt.
+@item
+Unerwartetes Herunterfahren des Computers (wenn der Computer beispielsweise
+abgeschaltet wird).
+@item
+Ein Hardware-Fehler.
+@item
+Sie benutzen ein externes Programm (wie myisamchk) auf einer benutzten
+Tabelle.
+@item
+Ein Software-Bug im MySQL- oder MyISAM-Code.
+@end itemize
+
+Typische Symptome einer beschädigten Tabelle sind:
+
+@itemize @bullet
+@item
+Sie erhalten den Fehler @code{Incorrect key file for table: '...'. Try to
+repair it}, wenn Sie Daten aus der Tabelle auswählen.
+@item
+Anfragen finden keine Zeilen in der Tabelle oder geben unvollständige Daten
+zurück.
+@end itemize
+
+Sie können mit dem Befehl @code{CHECK TABLE} prüfen, ob eine Tabelle in
+Ordnung ist. @xref{CHECK TABLE}.
+
+Sie können eine beschädigte Tabelle mit @code{REPAIR TABLE} reparieren.
+@xref{REPAIR TABLE}. Wenn @code{mysqld} nicht läuft, können Sie eine
+Tabelle auch mit dem @code{myisamchk}-Befehl reparieren.
+@code{myisamchk-Syntax}.
+
+Wenn Ihre Tabellen oft beschädigt werden, sollten Sie versuchen, den Grund
+dafür herauszufinden! @xref{Crashing}.
+
+In diesem Fall ist es am wichtigsten zu wissen, ob die Tabelle durch einen
+Absturz von @code{mysqld} beschädigt wurde (das können Sie leicht
+feststellen, wenn es eine aktuelle Zeile @code{restarted mysqld} in der
+mysqld-Fehlerdatei gibt). Wenn das nicht der Fall ist, sollten Sie
+versuchen, daraus einen Testfall zu machen. @xref{Reproduceable test case}.
+
+
+@node MyISAM table close, , Corrupted MyISAM tables, MyISAM table problems
+@c German node MyISAM-Tabellenschließen
+@subsubsection Client benutzt Tabelle oder hat sie nicht korrekt geschlossen
+
+Jede @code{MyISAM}-@code{.MYI}-Datei hat im Header einen Zähler, der
+benutzt werden kann, um zu prüfen, ob die Tabelle korrekt geschlossen
+wurde.
+
+Wenn Sie folgende Warnmeldung von @code{CHECK TABLE} oder @code{myisamchk}
+erhalten:
+
+@example
+# client is using or hasn't closed the table properly
+@end example
+
+heißt das, dass der Zähler nicht mehr synchron ist. Das bedeutet nicht,
+dass die Tabelle beschädigt ist, aber Sie sollten zumindest eine
+Überprüfung vornehmen, um sicherzustellen, dass die Tabelle in Ordnung ist.
+
+Der Zähler funktioniert wie folgt:
+
+@itemize @bullet
+@item
+Wenn die Tabelle das erste Mal in MySQL aktualisiert wird, wird der Zähler
+im Header der Index-Dateien heraufgezählt.
+@item
+Der Zähler wird während weiterer Aktualisierungen nicht verändert.
+@item
+Wenn die letzte Instanz einer Tabelle geschlossen wird (wegen eines
+@code{FLUSH} oder weil es nicht mehr genug Platz im Tabellen-Cache gibt),
+wird der Zähler heruntergezählt, wenn die Tabelle zu irgend einem Zeitpunkt
+aktualisiert wurde.
+@item
+Wenn Sie eine Tabelle reparieren oder prüfen und sie in Ordnung ist, wird
+der Zähler auf 0 zurückgesetzt.
+@item
+Um Probleme zu vermeiden, die durch Interaktion mit anderen Prozessen
+entstehen, die vielleicht eine Prüfung der Tabelle durchführen, wird der
+Zähler beim Schließen nicht heruntergezählt, wenn er 0 war.
+@end itemize
+
+Mit anderen Worten kann der Zähler nur in folgenden Fällen nicht mehr
+synchron sein:
+
+@itemize @bullet
+@item
+Die @code{MyISAM}-Tabellen werden ohne @code{LOCK} und @code{FLUSH TABLES}
+kopiert.
+@item
+MySQL ist zwischen einer Aktualisierung und dem endgültigen Schließen
+abgestürzt. (Beachten Sie, dass die Tabelle trotzdem in Ordnung sein kann,
+weil MySQL stets für alles zwischen jedem Statement Schreibvorgänge
+durchführt.
+@item
+Jemand hat @code{myisamchk --repair} oder @code{myisamchk --update-state}
+auf eine Tabelle ausgeführt, die durch @code{mysqld} in Benutzung war.
+@item
+Viele @code{mysqld}-Server benutzen die Tabelle und einer davon hat
+@code{REPAIR} oder @code{CHECK} der Tabelle ausgeführt, während sie durch
+einen anderen Server in Benutzung war. Hierbei kann @code{CHECK} sicher
+ausgeführt werden (selbst wenn Sie Warnungen von anderen Servern erhalten
+werden), aber @code{REPAIR} sollte vermieden werden, weil es momentan die
+Daten-Datei durch eine neue ersetzt, was anderen Servern nicht signalisiert
+wird.
+@end itemize
+
+
+@node MERGE, ISAM, MyISAM, Table types
+@c German node MERGE
+@section MERGE-Tabellen
+
+@cindex Tabellen, Merge-
+@cindex MERGE-Tabellen, Definition
+
+@code{MERGE}-Tabellen sind neu seit MySQL-Version 3.23.25. Der Code ist
+noch Gamma, sollte aber ausreichend stabil sein.
+
+Eine @code{MERGE}-Tabelle (auch bekannt als @code{MRG_MyISAM}-Tabelle) ist
+eine Sammlung identischer @code{MyISAM}-Tabellen, die wie eine benutzt
+werden können. Sie können auf dieser Sammlung von Tabellen nur
+@code{SELECT}, @code{DELETE} und @code{UPDATE} ausführen. Wenn Sie eine
+@code{MERGE}-Tabelle löschen (@code{DROP}), löschen Sie nur die
+@code{MERGE}-Spezifikation.
+
+Beachten Sie, dass @code{DELETE FROM merge_tabelle} ohne @code{WHERE} nur
+das Mapping für die Tabelle löscht, nicht alles in den gemappten Tabellen.
+(Geplant ist, das in Version 4.1 zu beheben.)
+
+Mit identischen Tabellen ist gemeint, dass alle Tabellen mit identischen
+Spalten- und Schlüsselinformationen erzeugt wurden. Sie können kein MERGE
+auf Tabellen ausführen, deren Spalten unterschiedlich komprimiert sind,
+nicht genau dieselben Spalten oder die Schlüssel in unterschiedlicher
+Reihenfolge haben. Einige der Tabellen können jedoch mit @code{myisampack}
+komprimiert sein. @xref{myisampack}.
+
+Wenn Sie eine @code{MERGE}-Tabelle erzeugen, erhalten Sie eine
+@code{.frm}-Tabellendefinitionsdatei und eine
+@code{.MRG}-Tabellenlistendatei. Die @code{.MRG} enthält lediglich eine
+Liste der Index-Dateien (@code{.MYI}-Dateien), die wie eine benutzt werden
+sollen. Alle benutzten Tabellen müssen in derselben Datenbank wie die
+@code{MERGE}-Tabelle selbst sein.
+
+Momentan benötigen Sie @code{SELECT}-, @code{UPDATE}- und
+@code{DELETE}-Berechtigungen für die Tabellen, die Sie auf eine
+@code{MERGE}-Tabelle mappen.
+
+@code{MERGE}-Tabellen können bei der Lösung folgender Probleme helfen:
+
+@itemize @bullet
+@item
+Auf einfache Weise einen Satz von Log-Tabellen verwalten. Beispielsweise
+können Sie Daten aus unterschiedlichen Monaten in separaten Dateien
+speichern, einige davon mit @code{myisampack} komprimieren und dann eine
+@code{MERGE}-Tabelle erzeugen, um sie wie eine zu benutzen.
+@item
+Mehr Geschwindigkeit. Sie können eine große Nur-Lese-Tabelle nach
+bestimmten Kriterien aufspalten und die verschiedenen Tabellenteile auf
+unterschiedlichen Festplatten speichern. Eine @code{MERGE}-Tabelle darauf
+könnte viel schneller sein als die große Tabelle zu benutzen. (Natürlich
+können Sie auch ein RAID benutzen, um dieselben Vorteile zu erzielen.)
+@item
+Effizientere Suchen durchführen. Wenn Sie genau wissen, wonach Sie suchen,
+können Sie mit einigen Anfragen in lediglich einer der aufgespaltenen
+Tabellen suchen und die @strong{MERGE}-Tabelle für andere benutzen. Es
+können sogar viele unterschiedliche @code{MERGE}-Tabellen aktiv sein,
+möglicherweise mit Dateien, die sich überlappen.
+@item
+Effizientere Reparaturen durchführen. Es ist leichter, die individuellen
+Dateien zu reparieren, die auf eine @code{MERGE}-Datei gemappt sind, als
+eine wirklich große Datei zu reparieren.
+@item
+Sofortiges Mappen vieler Dateien als einer. Eine @code{MERGE}-Tabelle
+benutzt den Index der individuellen Tabellen. Sie muss selbst keinen
+eigenen Index warten. Dadurch können Sie @code{MERGE}-Tabellensammlungen
+SEHR schnell erzeugen oder neu mappen. Beachten Sie, dass Sie die
+Schlüsseldefinitionen angeben, wenn Sie eine @code{MERGE}-Tabelle erzeugen!
+@item
+Wenn Sie einen Satz von Tabellen bei Bedarf oder im Stapel zu einer großen
+Tabelle vereinigen, sollten Sie statt dessen bei Bedarf eine
+@code{MERGE}-Tabelle darauf erzeugen. Das ist viel schneller und spart eine
+Menge Speicherplatz.
+@item
+Umgehen der Dateigrößengrenze des Betriebssystems.
+@item
+Sie können ein Alias / Synonym für eine Tabelle erzeugen, indem Sie sie
+einfach ein MERGE über eine Tabelle benutzen. Das sollte keine spürbaren
+Performance-Auswirkungen haben (nur eine Reihe indirekter Aufrufen und
+memcpy's bei jedem Lesen).
+@end itemize
+
+Die Nachteile von @code{MERGE}-Tabellen sind:
+
+@itemize @bullet
+@item
+Sie können nur identische @code{MyISAM}-Tabellen für eine
+@code{MERGE}-Tabelle benutzen.
+@item
+@code{AUTO_INCREMENT}-Spalten werden bei @code{INSERT} nicht automatisch
+aktualisiert.
+@item
+@code{REPLACE} funktioniert nicht.
+@item
+@code{MERGE}-Tabellen benutzen mehr Datei-Deskriptoren. Wenn Sie eine
+@strong{MERGE} benutzen, die über 10 Tabellen mappt, und 10 Benutzer diese
+benutzen, benötigen Sie 10 * 10 + 10 Datei-Deskriptoren (10 Daten-Dateien
+für 10 Benutzer und 10 gemeinsam genutzte Index-Dateien).
+@item
+Lesevorgänge von Schlüsseln sind langsamer. Wenn Sie eine Leseoperation auf
+einen Schlüssel durchführen, muss der @code{MERGE}-Handler ein Lesen auf
+alle zugrunde liegenden Tabellen ausführen, um zu prüfen, welche am
+nächsten zum angegebenen Schlüssel passt. Wenn Sie ein 'Lese nächsten'
+ausführen, muss der @code{MERGE}-Handler die Lese-Puffer durchsuchen, um
+den nächsten Schlüssel zu finden. Erst wenn ein Schlüsselpuffer
+aufgebraucht ist, muss der Handler den nächsten Schlüsselblock lesen. Das
+macht @code{MERGE}-Schlüssel bei @code{eq_ref}-Suchen viel langsamer, aber
+nicht viel langsamer bei @code{ref}-Suchen.
+@xref{EXPLAIN}.
+@item
+Sie können kein @code{DROP TABLE}, @code{ALTER TABLE} oder @code{DELETE
+FROM tabelle} ohne eine @code{WHERE}-Klausel auf jeder Tabelle, die von
+einer @code{MERGE}-Tabelle gemappt ist, ausführen, wenn diese 'offen' ist.
+Wenn Sie das tun, könnte die @code{MERGE}-Tabelle immer noch auf die
+Originaltabelle verweisen, und Sie würden unerwartete Ergebnisse erhalten.
+@end itemize
+
+Wenn Sie eine @code{MERGE}-Tabelle erzeugen, müssen Sie mit
+@code{UNION(liste-von-tabellen)} angeben, welche Tabellen Sie wie eine
+benutzen wollen. Optional können Sie mit @code{INSERT_METHOD} angeben, ob
+Sie wollen, dass Einfügungen in die @code{MERGE}-Tabelle in der ersten oder
+der letzten Tabelle in der @code{UNION}-Liste geschehen sollen. Wenn Sie
+keine @code{INSERT_METHOD} oder @code{NO} angeben, geben alle
+@code{INSERT}-Befehle auf die @code{MERGE}-Tabelle einen Fehler zurück.
+
+Folgendes Beispiel zeigt, wie Sie @code{MERGE}-Tabellen benutzen:
+
+@example
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, nachricht CHAR(20));
+CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, nachricht CHAR(20));
+INSERT INTO t1 (nachricht) VALUES ("test"),("tabelle"),("t1");
+INSERT INTO t2 (nachricht) VALUES ("test"),("tabelle"),("t2");
+CREATE TABLE gesamt (a INT NOT NULL, nachricht CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
+@end example
+
+Beachten Sie, dass wir keinen @code{UNIQUE}- oder @code{PRIMARY
+KEY}-Schlüssel in der @code{gesamt}-Tabelle angegeben haben, weil der
+Schlüssel in der @code{gesamt}-Tabelle nicht eindeutig sein wird.
+
+Beachten Sie auch, dass Sie die @code{.MRG}-Datei direkt von ausserhalb des
+MySQL-Servers manipulieren können:
+
+@example
+shell> cd /mysql-data-verzeichnis/aktuelle-datenbank
+shell> ls -1 t1.MYI t2.MYI > gesamt.MRG
+shell> mysqladmin flush-tables
+@end example
+
+Jetzt können Sie Dinge wie folgendes tun:
+
+@example
+mysql> select * from gesamt;
++---+-----------+
+| a | nachricht |
++---+-----------+
+| 1 | test |
+| 2 | table |
+| 3 | t1 |
+| 1 | test |
+| 2 | table |
+| 3 | t2 |
++---+-----------+
+@end example
+
+Um eine @code{MERGE}-Tabelle neu zu mappen, können Sie folgendes tun:
+
+@itemize @bullet
+@item
+Die Tabelle löschen (@code{DROP}) und neu erzeugen.
+@item
+@code{ALTER TABLE tabelle UNION(...)} benutzen.
+@item
+Die @code{.MRG}-Datei ändern und ein @code{FLUSH TABLE} auf die
+@code{MERGE}-Tabelle und alle zugrunde liegenden Tabellen ausführen, um den
+Handler zu zwingen, die neue Definitionsdatei einzulesen.
+@end itemize
+
+
+@menu
+* MERGE table problems::
+@end menu
+
+@node MERGE table problems, , MERGE, MERGE
+@c German node MERGE-Tabellenprobleme
+@subsection MERGE-Tabellenprobleme.
+
+Folgende Probleme sind bei @code{MERGE}-Tabellen bekannt:
+
+@itemize @bullet
+@item
+@code{DELETE FROM merge_tabelle} ohne @code{WHERE} löscht nur das Mapping
+für die Tabelle, nicht alles in den gemappten Tabellen.
+@item
+@code{RENAME TABLE} auf eine Tabelle, die in einer aktiven
+@code{MERGE}-Tabelle benutzt wird, kann die Tabelle beschädigen. Das wird
+in MySQL 4.0.x behoben.
+@item
+Beim Erzeugen einer Tabelle des Typs @code{MERGE} wird nicht geprüft, ob
+die zugrunde liegenden Tabellen kompatible Typen sind. Wenn Sie
+@code{MERGE}-Tabellen in dieser Weise benutzen, ist es sehr wahrscheinlich,
+dass merkwürdige Probleme auftauchen.
+@item
+Wenn Sie @code{ALTER TABLE} benutzen, um als erstes eine
+@code{UNIQUE}-Index zu einer Tabelle hinzuzufügen, die in einer
+@code{MERGE}-Tabelle benutzt wird, und dann @code{ALTER TABLE} benutzen, um
+einen normalen Index auf die @code{MERGE}-Tabelle hinzuzufügen, wird die
+Schlüssel-Reihenfolge für die Tabellen anders sein, wenn es einen alten,
+nicht eindeutigen Schlüssel in der Tabelle gab. Das liegt daran, dass
+@code{ALTER TABLE} @code{UNIQUE}-Schlüssel vor normale Schlüssel einfügt,
+um in der Lage zu sein, doppelte Schlüsseleinträge so früh wie möglich zu
+erkennen.
+@item
+Der Bereichsoptimierer kann @code{MERGE}-Tabellen noch nicht effizient
+benutzen und kann manchmal nicht optimale Joins produzieren. Das wird in
+MySQL 4.0.x behoben.
+@item
+@code{DROP TABLE} auf eine Tabelle, die in einer @code{MERGE}-Tabelle
+benutzt wird, funktioniert unter Windows nicht, weil der
+@code{MERGE}-Handler das Tabellen-Mapping versteckt vor der oberen Ebene
+von MySQL durchführt. Weil Windows es nicht zuläßt, dass Dateien gelöscht
+werden, die offen sind, müssen Sie zuerst alle @code{MERGE}-Tabellen auf
+Platte zurückschreiben (mit @code{FLUSH TABLES}) oder die
+@code{MERGE}-Tabelle löschen, bevor Sie die Tabelle löschen. Das wird zu
+dem Zeitpunkt behoben, wenn Sichten (@code{VIEW}s) eingeführt werden.
+@end itemize
+
+@node ISAM, HEAP, MERGE, Table types
+@c German node ISAM
+@section ISAM-Tabellen
+
+@cindex tables, ISAM
+
+Sie können auch den veralteten @code{ISAM}-Tabellentyp benutzen. Dieser
+wird recht bald verschwinden (wahrscheinlich in MySQL 4.1), weil
+@code{MyISAM} eine bessere Implementation derselbe Sache ist. @code{ISAM}
+benutzt einen @code{B-tree}-Index. Der Index wird in einer Datei mit der
+Endung @code{.ISM} gespeichert, und die Daten in einer Datei mit der Endung
+@code{.ISD}. Sie können @code{ISAM}-Tabellen mit dem
+@code{isamchk}-Dienstprogramm prüfen / reparieren. @xref{Disaster Prevention}.
+
+@code{ISAM} hat folgende Features / Eigenschaften:
+
+@itemize @bullet
+@item Komprimierte und Festlängen-Schlüssel
+@item Feste und dynamische Datensatzlängen
+@item 16 Schlüssel mit 16 Schlüsselteilen pro Schlüssel
+@item Maximale Schlüssellänge 256 (Vorgabe)
+@item Daten werden im Maschinenformat gespeichert. Das ist schnell, aber
+Maschinen- / Betriebssystem-abhängig.
+@end itemize
+
+Die meisten Dinge, die für @code{MyISAM}-Tabellen gelten, gelten auch für
+@code{ISAM}-Tabellen. @xref{MyISAM}. Die größten Unterschiede im Vergleich
+zu @code{MyISAM} sind:
+
+@itemize @bullet
+@item @code{ISAM}-Tabellen sind nicht binärportabel zwischen verschiedenen
+Betriebssystemen / Plattformen.
+@item Handhabt keine Tabellen > 4 GB.
+@item Unterstützt nur Präfix-Komprimierung von Zeichenketten.
+@item Kleinere Schlüssel-Beschränkungen.
+@item Dynamische Tabelle werden schneller fragmentiert.
+@item Tabellen werden mit @code{pack_isam} statt mit @code{myisampack}
+komprimiert.
+@end itemize
+
+Wenn Sie eine @code{ISAM}-Tabelle in eine @code{MyISAM}-Tabelle umwandeln
+wollen, können Sie Dienstprogramme wie @code{mysqlcheck} oder ein
+@code{ALTER TABLE}-Statement benutzen:
+
+@example
+mysql> ALTER TABLE tabelle TYPE = MYISAM;
+@end example
+
+Die eingebetteten (embedded) MySQL-Versionen unterstützen keine
+@code{ISAM}-Tabellen.
+
+@node HEAP, InnoDB, ISAM, Table types
+@c German node HEAP
+@section HEAP-Tabellen
+
+@cindex Tabellen, @code{HEAP}
+
+@code{HEAP}-Tabellen benutzen eine gehashten Index und werden im
+Arbeitsspeicher gespeichert. Das macht sie sehr schnell, aber wenn MySQL
+abstürzt, verlieren Sie alle darin gespeicherten Daten. @code{HEAP} ist
+sehr nützlich für temporäre Tabellen.
+
+Die MySQL-internen @code{HEAP}-Tabellen benutzen 100% dynamisches Hashen
+ohne Overflow-Bereiche. Es wird kein zusätzlicher Platz für freie Listen
+benötigt. @code{HEAP}-Tabellen haben auch keine Probleme mit Löschen plus
+Einfügen, was normalerweise bei gehashten Tabellen häufig vorkommt:
+
+@example
+mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) as down
+ FROM log_tabelle GROUP BY ip;
+mysql> SELECT COUNT(ip),AVG(down) FROM test;
+mysql> DROP TABLE test;
+@end example
+
+Einige Dinge sollten Sie bei der Benutzung von @code{HEAP}-Tabellen in
+Betracht ziehen:
+
+@itemize @bullet
+@item
+Sie sollten immer @code{MAX_ROWS} im @code{CREATE}-Statement angeben, um
+sicherzustellen, dass Sie nicht versehentlich den gesamten Arbeitsspeicher
+benutzen.
+@item
+Indexe werden nur bei @code{=} und @code{<=>} benutzt (sind aber SEHR
+schnell).
+@item
+@code{HEAP}-Tabellen können nur ganze Schlüssel benutzen, um nach einer
+Zeile zu suchen. Vergleichen Sie das mit @code{MyISAM}-Tabellen, bei denen
+jedes Präfix des Schlüssels für das Suchen von Zeilen benutzt werden kann.
+@item
+@code{HEAP}-Tabellen benutzen ein festes Datensatzlängenformat.
+@item
+@code{HEAP} unterstützt keine @code{BLOB}/@code{TEXT}-Spalten.
+@item
+@code{HEAP} unterstützt keine @code{AUTO_INCREMENT}-Spalten.
+@item
+@code{HEAP} unterstützt keinen Index auf eine @code{NULL}-Spalte.
+@item
+Es darf keine nicht eindeutigen Schlüssel auf eine @code{HEAP}-Tabelle
+geben (das ist ungebräuchlich für gehashte Tabellen).
+@item
+@code{HEAP}-Tabellen werden von allen Clients gemeinsam benutzt (so wie
+jede andere Tabelle).
+@item
+Sie können nicht nach dem nächsten Eintrag in der Reihenfolge suchen (also
+den Index benutzen, um ein @code{ORDER BY} zu machen).
+@item
+Die Daten für @code{HEAP}-Tabellen werden in kleinen Blöcken zugewiesen.
+Die Tabellen sind 100% dynamisch (beim Einfügen). Es werden keine
+Overflow-Bereiche und kein zusätzlicher Platz für Schlüssel benötigt.
+Gelöschte Zeilen werden in eine verknüpfte Liste geschrieben und wieder
+benutzt, wenn Sie neue Daten in die Tabelle einfügen.
+@item
+Sie brauchen genug zusätzlichen Arbeitsspeicher für alle
+@code{HEAP}-Tabellen, die Sie zugleich benutzen wollen.
+@item
+Um Speicher freizugeben, führen Sie @code{DELETE FROM heap_tabelle},
+@code{TRUNCATE heap_tabelle} oder @code{DROP TABLE heap_tabelle} aus.
+@item
+MySQL kann nicht herausfinden, wie viele Zeilen es zwischen zwei Werten
+ungefähr gibt (das wird vom Bereichsoptimierer benötigt, um zu entscheiden,
+welcher Index benutzt wird). Das kann einige Anfragen betreffen, wenn Sie
+eine @code{MyISAM}-Tabelle in eine @code{HEAP}-Tabelle umwandeln.
+@item
+Um sicherzustellen, dass Sie nicht versehentlich etwas Unkluges tun, können
+Sie keine @code{HEAP}-Tabellen größer als @code{max_heap_table_size}
+erzeugen.
+@end itemize
+
+Der für eine Zeile in einer @code{HEAP}-Tabelle benötigte Speicher ist:
+
+@example
+SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2)
++ ALIGN(length_of_row+1, sizeof(char*))
+@end example
+
+@code{sizeof(char*)} ist 4 auf 32-Bit-Maschinen und 8 auf 64-Bit-Maschinen.
+
+
+@node InnoDB, BDB, HEAP, Table types
+@c German node InnoDB
+@section InnoDB-Tabellen
+
+
+
+@menu
+* InnoDB overview::
+* InnoDB start::
+* InnoDB init::
+* Using InnoDB tables::
+* Adding and removing::
+* Backing up::
+* Moving::
+* InnoDB transaction model::
+* Implementation::
+* Table and index::
+* File space management::
+* Error handling::
+* InnoDB restrictions::
+* InnoDB contact information::
+@end menu
+
+@node InnoDB overview, InnoDB start, InnoDB, InnoDB
+@c German node Überblick über InnoDB
+@subsection Überblick über InnoDB-Tabellen
+
+@cindex Transaktionen, Unterstützung
+@cindex transaktionssichere Tabellen
+@cindex ACID
+
+InnoDB stellt MySQL einen transaktionssicheren (@code{ACID}-kompatiblen)
+Tabellen-Handler mit Fähigkeiten für Commit, Rollback und Reparatur nach
+Absturz zur Verfügung. InnoDB beherrscht Sperren auf Zeilenebene sowie ein
+konsistentes, nicht sperrendes Lesen in der Art von Oracle bei
+@code{SELECT}s. Diese Features steigern die Handhabung gleichzeitiger
+Verbindungen und die Performance. Es gibt bei InnoDB keine Notwendigkeit
+für Sperr-Eskalation, weil die Sperren auf Zeilenebene bei InnoDB in sehr
+wenig Speicherplatz passen. InnoDB-Tabellen unterstützen als erster
+Tabellentyp in MySQL @code{FOREIGN KEY}-Beschränkungen.
+
+InnoDB wurde für maximale Performance bei der Bearbeitung großer
+Datenmengen entworfen. Seine Prozessor-Effizienz wird wahrscheinlich von
+keiner anderen Festplatten-basierenden relationalen Datenbank-Engine
+erreicht.
+
+Technisch gesehen ist InnoDB ein komplettes Datenbank-Backend, das unter
+MySQL platziert ist. InnoDB hat seinen eigenen Puffer-Pool, um Daten und
+Indexe im Hauptspeicher zu cachen. InnoDB speichert seine Tabellen und
+Indexe in einem Tabellenplatz (Tablespace), der aus mehreren Dateien
+bestehen kann. Das unterscheidet sich beispielsweise von MyISAM-Tabellen,
+bei denen jede Tabelle als separate Datei gespeichert ist. InnoDB-Tabellen
+können jede beliebige Größe annehmen, sogar auf Betriebssystemen, deren
+Dateigröße auf 2 GB beschränkt ist.
+
+Die neuesten Informationen über InnoDB finden Sie unter
+@uref{http://www.innodb.com/}. Die aktuellste Version des InnoDB-Handbuchs
+ist immer dort zu finden, und Sie können auch kommerzielle Lizenzen und
+kommerziellen Support für InnoDB bestellen.
+
+InnoDB wird momentan (Oktober 2001) für die Produktion auf mehreren großen
+Datenbank-Sites benutzt, die hohe Performance benötigen. Die bekannte
+Internet-Newssite Slashdot.org läuft auf InnoDB. Mytrix Inc. speichert über
+1 TB an Daten in InnoDB, und eine andere Site handhabt eine
+durchschnittliche Last von 800 Einfüge- und Update-Operationen pro Sekunde
+mit InnoDB.
+
+InnoDB-Tabellen sind in der MySQL-Quelldistribution ab Version 3.23.34a
+enthalten und in der MySQL-Max-Binärversion aktiviert. Für Windows sind die
+Max-Binärdateien in der Standarddistribution enthalten.
+
+Wenn Sie eine Binärversion von MySQL herunter geladen haben, die
+Unterstützung für InnoDB enthält, folgen Sie einfach den Anweisungen im
+Handbuch für die Installation einer Binärversion von MySQL. Wenn Sie
+bereits MySQL-3.23 installiert haben, können Sie MySQL-Max am einfachsten
+installieren, indem Sie die ausführbare Datei für den Server
+(@file{mysqld}) durch die entsprechende ausführbare Datei in der
+Max-Distribution ersetzen. MySQL and MySQL-Max unterscheiden sich nur in
+Bezug auf die ausführbare Datei für den Server. @xref{MySQL binaries}. @xref{mysqld-max, , @code{mysqld-max}}.
+
+@c German FIX changed @xref to @ref
+Um MySQL mit InnoDB-Unterstützung zu kompilieren, laden Sie MySQL-3.23.34a
+oder neuer von @uref{http://www.mysql.com/} herunter und konfigurieren Sie
+MySQL mit der @code{--with-innodb}-Option. Sehen Sie im Handbuch unter
+@ref{Installing source} nach.
+
+@example
+cd /pfad/zur/quelldistribution/von/mysql-3.23.37
+./configure --with-innodb
+@end example
+
+Um InnoDB zu benutzen, müssen Sie InnoDB init in Ihrer @file{my.cnf}- oder
+@file{my.ini}-Datei angeben. In dieser Datei müssen Sie mindestens
+folgenden Zeile im @code{[mysqld]}-Abschnitt hinzufügen:
+
+@example
+innodb_data_file_path=ibdata:30M
+@end example
+
+@c German FIX changed @xref to @ref
+Für eine gute Performance ist es jedoch am besten, Optionen wie die unten
+im Abschnitt @ref{InnoDB start} empfohlenen anzugeben.
+
+InnoDB wird unter der GNU-GPL-Lizenz Version 2 (vom Juni 1991) vertrieben.
+In den Quelldistributionen von MySQL erscheint InnoDB als Unterverzeichnis.
+
+
+@node InnoDB start, InnoDB init, InnoDB overview, InnoDB
+@c German node Mit InnoDB anfangen
+@subsection Mit InnoDB anfangen - Optionen
+
+Um InnoDB-Tabellen in MySQL-Max-3.23 zu benutzen, @strong{MÜSSEN} Sie
+Konfigurationsparameter im @code{[mysqld]}-Abschnitt der
+MySQL-Konfigurationsdatei @file{my.cnf} angeben. @xref{Option files}.
+
+Der einzige erforderliche Parameter, um InnoDB in MySQL-Max-3.23 benutzen
+zu können, ist @code{innodb_data_file_path}.
+In MySQL-4.0 müssen Sie nicht einmal @code{innodb_data_file_path} angeben.
+Vorgabemäßig wird eine 64 MB große Daten-Datei @file{ibdata1} im
+@code{datadir} von MySQL erzeugt.
+
+Um jedoch eine gute Performance zu erzielen, MÜSSEN Sie explizit die unten
+in Beispielen aufgeführten InnoDB-Parameter setzen.
+
+Der Vorgabewert für @code{innodb_data_home_dir} ist das @code{datadir} von
+MySQL. Wenn Sie @code{innodb_data_home_dir} nicht angeben, können Sie in
+@code{innodb_data_file_path} keine absoluten Pfade benutzen.
+
+Nehmen wir an, Sie haben eine Windows-NT-Maschine mit 128 MB RAM und einer
+einzelnen 10 GB großen Festplatte. Unten steht ein Beispiel von möglichen
+Konfigurationsparametern in @file{my.cnf} für InnoDB:
+
+@example
+[mysqld]
+# Hier können Ihre sonstigen MySQL-Serveroptionen stehen
+# ...
+#
+innodb_data_home_dir = c:\ibdata
+# Die Daten-Dateien müssen in der Lage sein,
+# Ihre Daten und Indexe aufzunehmen
+innodb_data_file_path = ibdata1:2000M;ibdata2:2000M
+# Puffer-Poolgröße auf 50% bis 80%
+# des Arbeitsspeichers Ihres Computers setzen
+set-variable = innodb_buffer_pool_size=70M
+set-variable = innodb_additional_mem_pool_size=10M
+innodb_log_group_home_dir = c:\iblogs
+# .._log_arch_dir muss dasselbe sein wie
+# .._log_group_home_dir
+innodb_log_arch_dir = c:\iblogs
+innodb_log_archive=0
+set-variable = innodb_log_files_in_group=3
+# Die Log-Dateigröße auf ungefähr 15%
+# der Puffer-Poolgröße setzen
+set-variable = innodb_log_file_size=10M
+set-variable = innodb_log_buffer_size=8M
+# ..flush_log_at_trx_commit auf 0 setzen,
+# wenn Sie es sich leisten können,
+# ein paar der letzten Transaktionen zu verlieren
+innodb_flush_log_at_trx_commit=1
+set-variable = innodb_file_io_threads=4
+set-variable = innodb_lock_wait_timeout=50
+@end example
+
+Beachten Sie, dass die Daten-Dateien bei einigen Betriebssystemen kleiner
+als 2 GB sein müssen! Die Gesamtgröße von Daten-Dateien muss größer oder
+gleich 10 MB sein. Die Gesamtgröße der Log-Dateien MUSS auf
+32-Bit-Computern kleiner als 4 GB sein.
+
+@strong{InnoDB legt keine Verzeichnisse an. Diese müssen Sie selbst
+erzeugen!}
+Stellen Sie auch sicher, dass der MySQL-Server Rechte hat, Dateien in den
+Verzeichnissen anzulegen, die Sie angeben.
+
+Wenn Sie zum ersten Mal eine InnoDB-Datenbank erzeugen, sollten Sie den
+MySQL-Server am besten von der Kommandozeilen-Eingabeaufforderung starten.
+InnoDB gibt dann Informationen über die Datenbank-Erzeugung auf dem
+Bildschirm aus und Sie sehen, was passiert. Unten in Abschnitt 3 sehen Sie,
+wie die Ausgaben aussehen sollten.
+Unter Windows können Sie @file{mysqld-max.exe} so starten:
+@example
+ihr-pfad-zu-mysqld>mysqld-max --standalone --console
+@end example
+
+Nehmen wir an, Sie haben einen Linux-Computer mit 512 MB RAM und drei
+Festplatten mit jeweils 20 GB (in Verzeichnispfaden @file{/}, @file{/dr2}
+and @file{/dr3}). Unten ist ein Beispiel möglicher Konfigurationsparameter
+in @file{my.cnf} für InnoDB:
+
+@example
+[mysqld]
+# Hier können Ihre sonstigen MySQL-Serveroptionen stehen
+# ...
+#
+innodb_data_home_dir = /
+# Die Daten-Dateien müssen in der Lage sein,
+# Ihre Daten und Indexe aufzunehmen
+innodb_data_file_path = ibdata/ibdata1:2000M;dr2/ibdata/ibdata2:2000M
+# Puffer-Poolgröße auf 50% bis 80%
+# des Arbeitsspeichers Ihres Computers setzen
+set-variable = innodb_buffer_pool_size=350M
+set-variable = innodb_additional_mem_pool_size=20M
+innodb_log_group_home_dir = /dr3/iblogs
+# .._log_arch_dir muss dasselbe sein wie
+# .._log_group_home_dir
+innodb_log_arch_dir = /dr3/iblogs
+innodb_log_archive=0
+set-variable = innodb_log_files_in_group=3
+# Die Log-Dateigröße auf ungefähr 15%
+# der Puffer-Poolgröße setzen
+set-variable = innodb_log_file_size=50M
+set-variable = innodb_log_buffer_size=8M
+# ..flush_log_at_trx_commit auf 0 setzen,
+# wenn Sie es sich leisten können,
+# ein paar der letzten Transaktionen zu verlieren
+innodb_flush_log_at_trx_commit=1
+set-variable = innodb_file_io_threads=4
+set-variable = innodb_lock_wait_timeout=50
+#innodb_flush_method=fdatasync
+#innodb_fast_shutdown=1
+#set-variable = innodb_thread_concurrency=5
+@end example
+
+Beachten Sie, dass die beiden Daten-Dateien auf unterschiedliche Platten
+platziert wurden. Der Grund für den Namen @code{innodb_data_file_path}
+ist, dass Sie auch Pfade zu Ihren Daten-Dateien angeben können und dass
+@code{innodb_data_home_dir} nur textlich mit Ihren Daten-Datei-Pfaden
+verkettet wird, wobei ein möglicher Schrägstrich oder Backslash dazwischen
+hinzugefügt wird. InnoDB füllt den Tabellenplatz (Tablespace), der durch
+die Daten-Dateien gebildet wird, von unten nach oben. In manchen Fällen
+verbessert es die Performance der Datenbank, wenn nicht alle Daten auf
+derselben physikalischen Festplatte platziert sind. Es verbessert häufig
+die Performance, Log-Dateien auf anderen Platten als die Daten zu
+platzieren.
+
+Die Bedeutung der Konfigurationsparameter ist wie folgt:
+
+@multitable @columnfractions .30 .70
+@item @strong{Option} @tab @strong{Beschreibung}
+@item @code{innodb_data_home_dir} @tab
+Der allgemeine Teil des Verzeichnispfads für alle InnoDB-Daten-Dateien. Die
+Vorgabe für diesen Parameter ist das @code{datadir} von MySQL.
+@item @code{innodb_data_file_path} @tab
+Pfade zu individuellen Daten-Dateien und ihre Größen. Der volle
+Verzeichnispfad zu jeder Daten-Datei wird durch Verkettung von
+innodb_data_home_dir mit den hier angegebenen Pfaden hergestellt. Die
+Dateigrößen werden in Megabytes angegeben, daher das 'M' nach der obigen
+Angabe. InnoDB versteht auch die Abkürzung 'G', 1G bedeutet 1024M. Ab
+3.23.44 können Sie die Dateigröße auf mehr als 4 GB setzen, wenn das
+Betriebssystem große Dateien unterstützt. Auf einige Betriebssystemen
+müssen Dateien kleiner als 2 GB sein. Die Summe der Dateigrößen muss
+mindestens 10 MB betragen.
+@item @code{innodb_mirrored_log_groups} @tab
+Anzahl identischer Kopien von Log-Gruppen, die für die Datenbank gehalten
+werden. Momentan sollte dieser Parameter auf 1 gesetzt werden.
+@item @code{innodb_log_group_home_dir} @tab
+Verzeichnispfad zu den InnoDB-Log-Dateien.
+@item @code{innodb_log_files_in_group} @tab
+Anzahl von Log-Dateien in der Log-Gruppe. InnoDB schreibt in zirkulärer
+Weise in die Dateien. Hier wird ein Wert 3 empfohlen.
+@item @code{innodb_log_file_size} @tab
+Größe jeder Log-Datei in einer Log-Gruppe in Megabytes. Sinnvolle Werte
+reichen von 1 MB bis 1/n-tel der Größe des Puffer-Pools, die unten
+angegeben wird, wobei n die Anzahl der Log-Dateien in der Gruppe ist. Je
+größer der Wert, desto weniger Checkpoint-Flush-Aktivität wird im Puffer
+benötigt, was Festplatten-Ein- und -Ausgaben erspart. Größere Log-Dateien
+bedeutet jedoch auch, dass die Wiederherstellung im Fall eines Absturzes
+langsamer ist. Die Gesamtgröße aller Log-Dateien muss auf 32-Bit-Computern
+kleiner als 4 GB sein.
+@item @code{innodb_log_buffer_size} @tab
+Die Größe des Puffers, den InnoDB benutzt, um in die Log-Dateien auf
+Platte zu schreiben. Sinnvolle Werte liegen im Bereich von 1 MB bis zur
+Hälfte der Gesamtgröße der Log-Dateien. Ein großer Log-Puffer erlaubt,
+dass große Transaktionen laufen können, ohne dass die Notwendigkeit
+besteht, das Log auf Platte zu schreiben, bis die Transaktion abgeschickt
+(commit) wird. Wenn Sie daher große Transaktionen haben, sparen Sie
+Festplatten-Ein- und Ausgaben, wenn Sie den Log-Puffer Groß machen.
+@item @code{innodb_flush_log_at_trx_commit} @tab
+Normalerweise wird dieser Parameter auf 1 gesetzt, was bedeutet, dass beim
+Abschicken (commit) einer Transaktion das Log auf Platte geschrieben wird
+(flush) und die durch die Transaktion gemachten Änderungen permanent werden
+und einen Datenbankabsturz überleben. Wenn Sie willens sind, in Bezug auf
+diese Sicherheit Kompromisse einzugeben und eher kleine Transaktionen
+laufen lassen, können Sie diesen Wert auf 0 setzen, um Festplatten-Ein- und
+-Ausgaben in Bezug auf die Log-Dateien zu verringern.
+@item @code{innodb_log_arch_dir} @tab
+Das Verzeichnis, in dem komplett geschriebene Log-Dateien archiviert
+werden, wenn Archivierung benutzt wird. Der Wert dieses Parameters sollte
+momentan derselbe sein wie @code{innodb_log_group_home_dir}.
+@item @code{innodb_log_archive} @tab
+Dieser Wert sollte momentan auf 0 gesetzt werden. Weil MySQL die
+Wiederherstellung aus einer Datensicherung unter Benutzung seiner eigenen
+Log-Dateien durchführt, gibt es momentan keine Notwendigkeit,
+InnoDB-Log-Dateien zu archivieren.
+@item @code{innodb_buffer_pool_size} @tab
+Die Größe des Speicherpuffers, den InnoDB benutzt, um Daten und Indexe
+seiner Tabellen zu cachen. Je größer Sie diesen Wert setzen, desto weniger
+Festplatten-Ein- und -Ausgaben werden für den Zugriff auf Daten in Tabellen
+benötigt. Auf einem dedizierten Datenbank-Server können Sie diesen
+Parameter auf bis zu 80% des physikalischen Arbeitsspeichers der Maschine
+setzen. Setzen Sie ihn allerdings nicht zu hoch, weil bei manchen
+Betriebssystemen der Wettbewerb um Arbeitsspeicher zu Paging führt.
+@item @code{innodb_additional_mem_pool_size} @tab
+Die Größe des Speicher-Pools, den InnoDB für die Speicherung von
+Daten-Wörterbuchinformationen und anderen internen Datenstrukturen benutzt.
+Ein sinnvoller Wert hierfür könnte 2 MB sein. Je mehr Tabellen Sie jedoch
+in Ihrer Applikation haben, desto mehr müssen Sie hier zuweisen. Wenn
+InnoDB in diesem Pool keinen Speicherplatz mehr hat, läßt es sich
+Speicherplatz vom Betriebssystem zuweisen und schreibt Warnmeldungen in die
+MySQL-Fehler-Log-Datei.
+@item @code{innodb_file_io_threads} @tab
+Die Anzahl der Datei-Ein- und -Ausgabe-Threads in InnoDB. Normalerweise
+sollte dieser Wert 4 sein, aber Windows-Festplatten könnten von einer
+höheren Zahl profitieren.
+@item @code{innodb_lock_wait_timeout} @tab
+Timeout in Sekunden. Solange wartet eine InnoDB-Transaktion auf eine
+Sperre, bevor sie abgebrochen (Rollback) wird. InnoDB erkennt automatisch
+Transaktionsblockierungen in seiner eigenen Sperr-Tabelle und bricht die
+Transaktion ab (Rollback). Wenn Sie den @code{LOCK TABLES}-Befehl oder
+andere transaktionssichere Tabellen-Handler als InnoDB in derselben
+Transaktion benutzen, kann eine Blockierung auftreten, die InnoDB nicht
+erkennen kann. In solchen Fällen ist ein Timeout nützlich, um die Situation
+zu bereinigen.
+@item @code{innodb_flush_method} @tab
+(Verfügbar ab Version 3.23.40.)
+Der Vorgabewert hierfür ist @code{fdatasync}.
+Ein andere Option ist @code{O_DSYNC}.
+@end multitable
+
+
+@node InnoDB init, Using InnoDB tables, InnoDB start, InnoDB
+@c German node InnoDB initialisieren
+@subsection InnoDB-Tabellenplatz (Tablespace) erzeugen
+
+Angenommen, Sie haben MySQL installiert und @file{my.cnf} so editiert, dass
+sie die notwendigen InnoDB Konfigurationsparameter enthält. Bevor Sie MySQL
+starten, sollten Sie überprüfen, dass die für InnoDB-Daten- und Log-Dateien
+angegebenen Verzeichnisse existieren und dass Sie auf diese Zugriffsrechte
+haben. InnoDB kann keine Verzeichnisse anlegen, nur Dateien. Überprüfen Sie
+auch, ob Sie auf der Festplatte genug Platz für Daten- und Log-Dateien
+haben.
+
+Wenn Sie jetzt MySQL starten, fängt InnoDB an, Ihre Daten- und Log-Dateien
+zu erzeugen. InnoDB gibt dabei etwas wie das folgende aus:
+
+@example
+~/mysqlm/sql > mysqld
+InnoDB: The first specified data file /home/stefan/data/ibdata1 did not exist:
+InnoDB: a new database to be created!
+InnoDB: Setting file /home/stefan/data/ibdata1 size to 134217728
+InnoDB: Database physically writes the file full: wait...
+InnoDB: Data file /home/stefan/data/ibdata2 did not exist: new to be created
+InnoDB: Setting file /home/stefan/data/ibdata2 size to 262144000
+InnoDB: Database physically writes the file full: wait...
+InnoDB: Log file /home/stefan/data/logs/ib_logfile0 did not exist: new to be created
+InnoDB: Setting log file /home/stefan/data/logs/ib_logfile0 size to 5242880
+InnoDB: Log file /home/stefan/data/logs/ib_logfile1 did not exist: new to be created
+InnoDB: Setting log file /home/stefan/data/logs/ib_logfile1 size to 5242880
+InnoDB: Log file /home/stefan/data/logs/ib_logfile2 did not exist: new to be created
+InnoDB: Setting log file /home/stefan/data/logs/ib_logfile2 size to 5242880
+InnoDB: Started
+mysqld: ready for connections
+@end example
+
+Jetzt wurde eine neue InnoDB-Datenbank erzeugt. Sie können sich mit den
+üblichen MySQL-Client-Programmen wie @code{mysql} mit dem MySQL-Server
+verbinden. Wenn Sie den MySQL-Server mit @file{mysqladmin shutdown}
+herunter fahren, gibt InnoDB etwa wie das folgende aus:
+
+@example
+010321 18:33:34 mysqld: Normal shutdown
+010321 18:33:34 mysqld: Shutdown Complete
+InnoDB: Starting shutdown...
+InnoDB: Shutdown completed
+@end example
+
+Wenn Sie jetzt einen Blick auf die Daten-Dateien und Log-Verzeichnisse
+werfen, sehen Sie die erzeugten Dateien. Das Log-Verzeichnis enthält auch
+eine kleine Datei namens @file{ib_arch_log_0000000000}. Diese Datei
+resultiert aus der Datenbank-Erzeugung, nach der InnoDB die
+Log-Archivierung ausgeschaltet hat. Wenn MySQL noch einmal gestartet wird,
+sieht die Ausgabe etwa wie folgt aus:
+
+@example
+~/mysqlm/sql > mysqld
+InnoDB: Started
+mysqld: ready for connections
+@end example
+
+
+
+@menu
+* Error creating InnoDB::
+@end menu
+
+@node Error creating InnoDB, , InnoDB init, InnoDB init
+@c German node Fehler bei der Erzeugung von InnoDB
+@subsubsection Falls etwas bei der Datenbank-Erzeugung schiefgeht
+
+Falls etwas bei der Datenbank-Erzeugung schiefgeht, sollten Sie alle durch
+InnoDB erzeugten Dateien löschen. Das heißt alle Daten-Dateien, alle
+Log-Dateien, die kleine archivierte Log-Datei und - falls Sie bereits
+InnoDB-Tabellen erzeugt haben, auch die entsprechenden @file{.frm}-Dateien
+für diese Tabellen in den MySQL-Datenbankverzeichnissen. Danach können Sie
+die InnoDB-Datenbankerzeugung erneut versuchen.
+
+
+@node Using InnoDB tables, Adding and removing, InnoDB init, InnoDB
+@c German node InnoDB-Tabellen benutzen
+@subsection InnoDB-Tabellen erzeugen
+
+Angenommen, Sie haben den MySQL-Client mit dem Befehl @code{mysql test}
+gestartet. Um eine Tabelle im InnoDB-Format zu erzeugen, müssen Sie im
+SQL-Befehl zur Tabellenerzeugung @code{TYPE = InnoDB} angeben:
+
+@example
+CREATE TABLE kunde (A INT, B CHAR (20), INDEX (A)) TYPE = InnoDB;
+@end example
+
+Dieser SQL-Befehl erzeugt eine Tabelle und einen Index auf die Spalte
+@code{A} im InnoDB-Tabellenplatz (Tablespace), der aus den Daten-Dateien
+besteht, die Sie in @file{my.cnf} angegeben haben. MySQL erzeugt zusätzlich
+eine Datei @file{kunde.frm} im MySQL-Datenbankverzeichnis @file{test}.
+Intern fügt InnoDB seinem eigenen Datenwörterbuch einen Eintrag für die
+Tabelle @code{'test/kunde'} hinzu. Wenn Sie daher eine Tabelle namens
+@code{kunde} in einer anderen Datenbank von MySQL erzeugen, kollidieren die
+Tabellennamen innerhalb InnoDB nicht.
+
+Sie können den freien Speicherplatz im InnoDB-Tabellenplatz (Tablespace)
+mit dem Tabellen-Status-Befehl von MySQL für jede Tabelle, die Sie mit
+@code{TYPE = InnoDB} erzeugt haben, abfragen. Die Menge freien Platzes im
+Tabellenplatz (Tablespace) erscheint im Kommentar-Abschnitt der Tabelle in
+der Ausgabe von @code{SHOW}. Beispiel:
+
+@example
+SHOW TABLE STATUS FROM test LIKE 'kunde'
+@end example
+
+Beachten Sie, dass die Statistiken, die @code{SHOW} über InnoDB-Tabellen
+ausgibt, nur Näherungswerte sind: Sie werden für die SQL-Optimierung
+benutzt. Die für Tabelle und Indexe reservierten Größen in Bytes sind
+allerdings genau.
+
+@subsubsection MyISAM-Tabellen in InnoDB-Tabellen umwandeln
+
+InnoDB hat keine spezielle Optimierung für separate Index-Erzeugung. Daher
+lohnt es sich nicht, die Tabelle zu exportieren und importieren und die
+Indexe danach zu erzeugen. Die schnellste Art, eine Tabelle in InnoDB zu
+ändern, ist, die Einfügungen direkt in eine InnoDB-Tabelle vorzunehmen,
+das heißt, @code{ALTER TABLE ... TYPE=INNODB} zu benutzen oder eine leere
+InnoDB-Tabelle mit identischen Definitionen zu nehmen und die Zeilen mit
+@code{INSERT INTO ... SELECT * FROM ...} einzufügen.
+
+Um eine bessere Kontrolle über den Einfügeprozess zu erhalten, kann es
+besser sein, große Tabellen in Teilstücken einzufügen:
+
+@example
+INSERT INTO neue_tabelle SELECT * FROM alte_tabelle WHERE schluessel > etwas
+ AND schluessel <= etwas_anderes;
+@end example
+
+Nachdem alle Daten eingefügt wurden, können Sie die Tabellen umbenennen.
+
+Während der Umwandlung großer Tabellen sollten Sie den InnoDB-Puffer-Pool
+hoch setzen, um Festplatten-Ein- und -Ausgaben zu verringern, allerdings
+nicht höher als 80% des physikalischen Arbeitsspeichers. Sie sollten die
+InnoDB-Log-Dateien Groß machen und auch den Log-Puffer.
+
+Stellen Sie sicher, dass Sie genug Tabellenplatz (Tablespace) haben!
+InnoDB-Tabellen benötigen viel mehr Platz als MyISAM-Tabellen. Wenn ein
+@code{ALTER TABLE} nicht mehr genug Platz hat, wird ein Rollback gestartet,
+das Stunden dauern kann, wenn es auf der Festplatte stattfindet. Bei
+Einfügeoperationen verwendet InnoDB den Einfügepuffer, um sekundäre
+Index-Datensätze mit Indexen in Stapeln zu vermischen. Das spart eine Menge
+an Festplatten-Ein- und -Ausgaben. Beim Rollback wird kein solcher
+Mechanismus benutzt, weshalb das Rollback bis zu 30 mal länger als das
+Einfügen dauern kann.
+
+Falls Sie keine wertvollen Daten in Ihren InnoDB-Dateien haben, ist es im
+Fall eines 'festgefahrenen' Rollback besser, den Datenbank-Prozess zu
+killen und alle InnoDB-Daten- und Log-Dateien sowie alle InnoDB-Tabellen
+(@file{.frm}-Dateien) zu löschen und noch einmal anzufangen, statt darauf
+zu warten, dass Millionen von Festplatten-Ein- und -Ausgaben beendet
+werden.
+
+@subsubsection Fremdschlüssel-(Foreign Key)-Beschränkungen
+
+InnoDB-Version 3.23.44 hat Fremdschlüssel-(Foreign Key)-Beschränkungen.
+InnoDB ist der erste MySQL-Tabellentyp, der die Definition von
+Fremdschlüssel-Beschränkungen zuläßt, um die Integrität Ihrer Daten zu
+überwachen.
+
+Die Syntax einer Fremdschlüsseldefinition in InnoDB:
+@example
+FOREIGN KEY (index_spalten_name, ...) REFERENCES tabellen_name (index_spalten_name, ...)
+@end example
+
+Beispiel:
+
+@example
+CREATE TABLE eltern(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
+CREATE TABLE kind(id INT, eltern_id INT, INDEX par_ind (eltern_id),
+ FOREIGN KEY (eltern_id) REFERENCES eltern(id)) TYPE=INNODB;
+@end example
+
+Beide Tabellen müssen vom Typ InnoDB sein und es muss einen Index geben,
+bei dem der Fremdschlüssel und der referenzierte Schlüssel als erste
+Spalten aufgeführt sind. Jegliches @code{ALTER TABLE} entfernt momentan
+alle Fremdschlüsselbeschränkungen, die für die Tabelle definiert wurden,
+aber nicht die Beschränkungen, die die Tabelle referenzieren.
+Korrespondierende Spalten im Fremdschlüssel und dem referenzierten
+Schlüssel müssen ähnliche interne Datentypen innerhalb InnoDB sein, so dass
+sie ohne Typumwandlung verglichen werden können. Die Längen von
+Zeichenkettentypen müssen nicht dieselben sein. Die Größe und Vorzeichen /
+kein Vorzeichen von Ganzzahltypen müssen dieselben sein.
+
+Beim Prüfen von Fremdschlüsseln setzt InnoDB gemeinsame Sperren auf
+Zeilenebene auf kind- und eltern-Datensätze, die es betrachten muss. InnoDB
+prüft Fremdschlüssel-(Foreign Key)-Beschränkungen sofort: Die Prüfung wird
+nicht bis zu einem Transaktions-Commit verschoben.
+
+InnoDB läßt zu, dass jegliche Tabelle gelöscht wird, selbst wenn das die
+Fremdschlüssel-(Foreign Key)-Beschränkungen durchbrechen würde, die die
+Tabelle referenzieren. Wenn Sie eine Tabelle löschen, werden die
+Beschränkungen, die in ihrem CREATE-Statement definiert wurden, ebenfalls
+gelöscht.
+
+Wenn Sie eine gelöschte Tabelle neu erzeugen, muss sie eine Definition
+haben, die mit den Fremdschlüssel-(Foreign Key)-Beschränkungen konform ist,
+die sie referenzieren. Sie muss die richten Spaltennamen und -typen haben,
+und sie muss - wie oben angegeben - Indexe auf die referenzierten Schlüssel
+haben.
+
+Sie können die Fremdschlüssel-(Foreign Key)-Beschränkungen für eine Tabelle
+wie folgt auflisten:
+@code{T} with
+@example
+SHOW TABLE STATUS FROM ihr_datenbank_name LIKE 'T';
+@end example
+Die Fremdschlüssel-(Foreign Key)-Beschränkungen werden im
+Tabellen-Kommentar der Ausgabe aufgelistet.
+
+InnoDB unterstützt noch kein @code{CASCADE ON DELETE} oder andere spezielle
+Optionen für diese Beschränkungen.
+
+@node Adding and removing, Backing up, Using InnoDB tables, InnoDB
+@c German node Hinzufügen und entfernen
+@subsection Hinzufügen und Entfernen von InnoDB-Daten- und -Log-Dateien
+
+Sie können die Größe einer InnoDB-Daten-Datei nicht vergrößern. Um Ihrem
+Tabellenplatz (Tablespace) mehr hinzuzufügen, müssen Sie eine neue
+Daten-Datei hinzufügen. Um das zu tun, müssen Sie Ihre MySQL-Datenbank
+herunter fahren, die @file{my.cnf}-Datei editieren und eine neue Datei zu
+@code{innodb_data_file_path} hinzufügen. Dann starten Sie MySQL erneut.
+
+Momentan können Sie keine Daten-Datei aus InnoDB entfernen. Um die Größe
+Ihrer Datenbank zu verringern, müssen Sie @file{mysqldump} benutzen, um
+alle Ihre Tabellen zu dumpen, eine neue Datenbank erzeugen und Ihre
+Tabellen in die neue Datenbank importieren.
+
+Wenn Sie die Anzahl oder die Größe Ihrer InnoDB-Log-Dateien ändern wollen,
+müssen Sie MySQL herunter fahren und sicher stellen, dass er ohne Fehler
+herunter fuhr. Dann kopieren Sie die alten Log-Dateien an eine sichere
+Stelle, falls etwas beim Herunterfahren schiefging und Sie die Datenbank
+wiederherstellen müssen. Löschen Sie die alten Log-Dateien aus dem
+Log-Datei-Verzeichnis, editieren Sie @file{my.cnf} und starten Sie MySQL
+noch einmal. InnoDB meldet beim Starten, dass es neue Log-Dateien anlegt.
+
+
+@node Backing up, Moving, Adding and removing, InnoDB
+@c German node Datensicherung InnoDB
+@subsection Datensicherung und Wiederherstellung einer InnoDB-Datenbank
+
+Der Schlüssel zur sicheren Datenbankverwaltung sind regelmäßige
+Datensicherungen. Im eine 'binäre' Sicherung Ihrer Datenbank zu machen, tun
+Sie folgendes:
+
+@itemize @bullet
+@item
+Fahren Sie Ihre MySQL-Datenbank herunter und stellen Sie sicher, dass dabei
+keine Fehler auftraten.
+@item
+Kopieren Sie Ihre Daten-Dateien an eine sichere Stelle.
+@item
+Kopieren Sie alle InnoDB-Log-Dateien an eine sichere Stelle.
+@item
+Kopieren Sie Ihre @file{my.cnf} Konfigurationsdatei(en) an eine sichere
+Stelle.
+@item
+Kopieren Sie alle @file{.frm}-Dateien für Ihre InnoDB-Tabellen an eine
+sichere Stelle.
+@end itemize
+
+Momentan gibt es kein Online- oder inkrementelles Datensicherungsprogramm
+für InnoDB, obwohl diese auf der TODO-Liste sind.
+
+Zusätzlich zu den beschriebenen Binär-Datensicherungen sollten Sie
+ausserdem regelmäßig Dumps Ihrer Tabellen mit @file{mysqldump} machen. Der
+Grund ist, dass eine Binärdatei beschädigt sein kann, ohne dass Sie das
+bemerken. Gedumpte Tabellen werden in Textdateien gespeichert, die
+Menschen-lesbar und viel einfacher als binäre Datenbankdateien sind. Aus
+gedumpten Dateien läßt sich Tabellenbeschädigung leichter erkennen und da
+ihr Format einfacher ist, ist das Risiko ernsthafter Datenbeschädigung in
+ihnen geringer.
+
+Es ist eine gute Idee, Dumps zur gleichen Zeit zu machen wie die binäre
+Datensicherung Ihrer Datenbank. Sie müssen alle Clients aus Ihrer Datenbank
+ausschließen, um konsistente Schnappschüsse aller Ihrer Tabellen im Dump
+zu bekommen. Danach können Sie die binäre Datensicherung machen, so dass
+Sie einen konsistenten Schnappschuss Ihrer Datenbank in zwei Formaten
+haben.
+
+Um in der Lage zu sein, Ihre InnoDB-Datenbank aus den beschriebenen binären
+Datensicherungen wiederherzustellen, müssen Sie Ihre MySQL-Datenbank mit
+allgemeinem Loggen und angeschalteter Log-Archivierung von MySQL laufen
+lassen. Mit allgemeinem Loggen ist hier der Log-Mechanismus des
+MySQL-Servers gemeint, der unabhängig von den InnoDB-Logs ist.
+
+Zum Wiederherstellen nach einem Absturz des MySQL-Serverprozesses ist es
+lediglich nötig, diesen erneut zu starten. InnoDB prüft automatisch die
+Log-Dateien und führt ein Roll-Forward der Datenbank bis zum aktuellen
+Stand durch. InnoDB macht ein automatisches Rollback nicht abgeschlossener
+(committed) Transaktionen, die zur Zeit des Absturzes anhängig waren.
+Während der Wiederherstellung gibt InnoDB etwa folgendes aus:
+
+@example
+~/mysqlm/sql > mysqld
+InnoDB: Database was not shut down normally.
+InnoDB: Starting recovery from log files...
+InnoDB: Starting log scan based on checkpoint at
+InnoDB: log sequence number 0 13674004
+InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
+InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
+InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
+InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
+...
+InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
+InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
+InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
+InnoDB: 1 uncommitted transaction(s) which must be rolled back
+InnoDB: Starting rollback of uncommitted transactions
+InnoDB: Rolling back trx no 16745
+InnoDB: Rolling back of trx no 16745 completed
+InnoDB: Rollback of uncommitted transactions completed
+InnoDB: Starting an apply batch of log records to the database...
+InnoDB: Apply batch completed
+InnoDB: Started
+mysqld: ready for connections
+@end example
+
+Wenn Ihre Datenbank beschädigt wird oder Ihre Festplatte Fehler hat, müssen
+Sie eine Wiederherstellung aus einer Datensicherung durchführen. Im Falle
+der Beschädigung sollten Sie zunächst eine Datensicherung finden, die nicht
+beschädigt ist. Machen Sie aus der Datensicherung eine Wiederherstellung
+aus den allgemeinen Log-Dateien von MySQL unter Beachtung der Anleitungen
+im MySQL-Handbuch.
+
+
+
+@menu
+* InnoDB checkpoints::
+@end menu
+
+@node InnoDB checkpoints, , Backing up, Backing up
+@c German node InnoDB-Checkpoints
+@subsubsection Checkpoints
+
+InnoDB hat einen Checkpoint-Mechanismus implementiert, der sich Fuzzy
+Checkpoint nennt. InnoDB schreibt veränderten Datenbankseiten aus dem
+Puffer-Pool in kleinen Stapeln (Batch) auf Platte (flush), daher besteht
+keine Notwendigkeit, den Puffer-Pool in einem einzelnen Stapel
+zurückzuschreiben, was in der Praxis dazu führen würde, dass SQL-Statements
+von Benutzern für eine Weile angehalten würden.
+
+Bei der Reparatur nach Abstürzen sucht InnoDB nach einem Checkpoint-Label in
+den Log-Dateien. Es weiß, dass alle Änderungen an der Datenbank vor dem
+Label bereits im Platten-Image der Datenbank enthalten sind. InnoDB scannt
+anschließend die Log-Dateien ab dem Checkpoint vorwärts und wendet die
+geloggten Änderungen auf die Datenbank an.
+
+InnoDB schreibt in zirkulärer Art in die Log-Dateien. Alle abgeschickten
+(committed) Änderungen, die dazu führen, dass sich die Datenbankseiten im
+Puffer-Pool vom Image auf der Platte unterscheiden, müssen in den
+Log-Dateien verfügbar sein, für den Fall, dass InnoDB eine
+Wiederherstellung durchführen muss. Das heißt, wenn InnoDB anfängt, eine
+Log-Datei auf zirkuläre Weise wieder zu benutzen, muss es sicherstellen,
+dass die Datenbankseiten-Images auf der Festplatte bereits die Änderungen
+enthalten, die in der Log-Datei mitgeschrieben sind, die InnoDB benutzen
+wird. Mit anderen Worten muss InnoDB einen Checkpoint machen, was oft das
+Zurückschreiben auf Platte (flush) geänderter Datenbankseiten beinhaltet.
+
+Das erklärt, warum es Festplatten-Ein- und -Ausgaben sparen kann, wenn man
+die Log-Dateien sehr Groß macht. Es kann sinnvoll sein, die Gesamtgröße
+der Log-Dateien so Groß wie den Puffer-Pool oder sogar noch größer zu
+machen. Der Nachteil großer Log-Dateien ist, dass eine Reparatur nach
+Absturz länger dauern kann, weil mehr Log-Einträge auf die Datenbank
+angewendet werden müssen.
+
+
+@node Moving, InnoDB transaction model, Backing up, InnoDB
+@c German node Verschieben
+@subsection Eine InnoDB-Datenbank auf eine andere Maschine verschieben
+
+InnoDB-Daten- und Log-Dateien sind auf allen Plattformen binärkompatibel,
+wenn das Fließkommazahlenformat auf den Maschinen dasselbe ist. Sie können
+eine InnoDB-Datenbank einfach verschieben, indem Sie alle relevanten
+Dateien kopieren, die im vorherigen Abschnitt über Datensicherung erwähnt
+wurden. Wenn sich das Fließkommaformat auf den Maschinen unterscheidet,
+sie aber keine @code{FLOAT}- oder @code{DOUBLE}-Datentypen in Ihren
+Tabellen benutzt haben, ist die Prozedur dieselbe: Kopieren Sie einfach die
+relevanten Dateien. Wenn die Formate unterschiedlich sind und Ihre Tabellen
+Fließkomma-Daten enthalten, müssen Sie @file{mysqldump} und
+@file{mysqlimport} benutzen, um diese Tabellen zu verschieben.
+
+Ein Tipp zur Performance: Schalten Sie Auto-Commit aus, wenn Sie Daten in
+Ihre Datenbank importieren (unter der Annahme, dass Ihr Tabellenplatz
+(Tablespace) genug Platz für das große Rollback-Segment enthält, den die
+große Import-Transaktion erzeugen wird). Machen Sie das Commit erst nach
+dem Import einer ganzen Tabelle oder eines Segments einer Tabelle.
+
+
+@node InnoDB transaction model, Implementation, Moving, InnoDB
+@c German node InnoDB-Transaktionsmodell
+@subsection InnoDB-Transaktionsmodell
+
+Im InnoDB-Transaktionsmodell war das Ziel, die besten Eigenschaften einer
+multiversionsfähigen Datenbank mit dem traditionellen Zwei-Phasen-Sperren
+zu verbinden. InnoDB führt Sperren auf Zeilenebene durch und läßt Anfragen
+vorgabemäßig als nicht sperrende konsistente Leseoperationen laufen, im
+Stil von Oracle. Das Tabellensperren ist in InnoDB so platzsparend
+gespeichert, dass keine Sperr-Eskalation benötigt wird: Typischerweise
+dürfen mehrere Benutzer jede Zeile in der Datenbank oder eine beliebige
+Teilmenge der Zeilen sperren, ohne dass InnoDB keinen Speicher mehr hat.
+
+Bei InnoDB findet jede Benutzeraktivität innerhalb von Transaktionen statt.
+Wenn der Auto-Commit-Modus in MySQL benutzt wird, stellt jedes
+SQL-Statement eine einzelne Transaktion dar. Wenn der Auto-Commit-Modus
+ausgeschaltet wird, kann man sich vorstellen, dass ein Benutzer stets eine
+Transaktion offen hat. Wenn er das SQL-@code{COMMIT}- oder
+@code{ROLLBACK}-Statement absetzt, beendet das die aktuelle Transaktion und
+eine neue beginnt. Beide Statements heben alle InnoDB-Sperren auf, die
+während der aktuellen Transaktion gesetzt wurden. Ein @code{COMMIT}
+bedeutet, dass die in der aktuellen Transaktion gemachten Änderungen
+permanent und sichtbar für andere Benutzer gemacht werden. Auf der anderen
+Seite bricht ein @code{ROLLBACK} alle Änderungen ab, die in der aktuellen
+Transaktion gemacht wurden.
+
+
+
+@menu
+* InnoDB consistent read::
+* InnoDB locking reads::
+* InnoDB Next-key locking::
+* InnoDB Locks set::
+* InnoDB Deadlock detection::
+* InnoDB Consistent read example::
+@end menu
+
+@node InnoDB consistent read, InnoDB locking reads, InnoDB transaction model, InnoDB transaction model
+@c German node Konsistentes Lesen bei InnoDB
+@subsubsection Konsistentes Lesen
+
+Konsistentes Lesen bedeutet, dass InnoDB seine Multiversionsfähigkeiten
+nutzt, um einer Anfrage einen Schnappschuss der Datenbank zu einem
+bestimmten Zeitpunkt zu zeigen. Die Anfrage sieht genau die Änderungen, die
+von Transaktionen durchgeführt wurden, die bis zu diesem Zeitpunkt
+abgeschlossen wurden (committed), und keine Änderungen, die später gemacht
+wurden oder die noch nicht abgeschlossen sind. Die Ausnahme von der Regel
+ist, dass die Anfrage die Änderungen sieht, die durch die Transaktion
+selbst durchgeführt wurde, die die Anfrage absetzt.
+
+Wenn eine Transaktion ihr erstes Konsistentes Lesen durchführt, weist
+InnoDB den Schnappschuss oder Zeitpunkt zu, den jedes Konsistente Lesen
+in derselben Transaktion benutzen wird. Im Schnappschuss sind alle
+Transaktionen enthalten, die vor der Zuweisung zum Schnappschuss
+abgeschlossen (committed) wurden. Daher ist Konsistentes Lesens innerhalb
+derselben Transaktion auch untereinander konsistent. Sie können einen
+frischeren Schnappschuss für Ihre Anfragen erhalten, indem Sie die aktuelle
+Transaktion beenden (commit) und danach neue Anfragen absetzen.
+
+Konsistentes Lesen ist der vorgabemäßige Modus, in dem InnoDB
+@code{SELECT}-Statements abarbeitet. Konsistentes Lesen setzt keinerlei
+Sperren auf die Tabellen, auf die es zugreift. Daher können andere Benutzer
+zur selben Zeit, wie Konsistentes Lesen auf die Tabelle durchgeführt wird,
+diese verändern.
+
+
+@node InnoDB locking reads, InnoDB Next-key locking, InnoDB consistent read, InnoDB transaction model
+@c German node Lese-Sperren bei InnoDB
+@subsubsection Lesevorgänge sperren
+
+Unter manchen Umständen ist Konsistentes Lesen nicht wünschenswert.
+Angenommen, Sie wollen eine neue Zeile in die Tabelle @code{kind} einfügen
+und dabei sicherstellen, dass das Kind bereits Eltern in der Tabelle
+@code{eltern} hat.
+
+Wenn Sie Konsistentes Lesen benutzen, um die Tabelle @code{eltern} zu lesen
+und in der Tat die Eltern des Kindes in der Tabelle sehen, können Sie dann
+sicher die Kind-Zeile zur Tabelle @code{kind} hinzufügen? Nein, denn es
+kann sein, dass zwischenzeitlich jemand anderes die Eltern-Zeile aus der
+Tabelle @code{eltern} gelöscht hat und Sie das nicht sehen.
+
+Die Lösung besteht darin, das @code{SELECT} im Sperrmodus durchzuführen.
+@code{LOCK IN SHARE MODE}.
+
+@example
+SELECT * FROM eltern WHERE NAME = 'Hinz' LOCK IN SHARE MODE;
+@end example
+
+Wenn Sie ein Lesen im Share-Modus durchführen, heißt das, dass die letzten
+verfügbaren Daten gelesen werden und eine Shared-Modus-Sperre auf die Zeile
+gesetzt wird, die gelesen wird. Wenn die letzten Daten zu einer noch nicht
+abgeschlossenen Transaktion eines anderen Benutzers gehören, wird gewartet,
+bis die Transaktion abgeschlossen (committed) ist. Eine Shared-Modus-Sperre
+verhindert, dass andere die Zeile aktualisieren oder löschen, die gerade
+gelesen wurde. Nachdem festgestellt wurde, dass die obige Anfrage die
+Eltern @code{'Hinr'} zurückgibt, kann das Kind sicher zur Tabelle
+@code{kind} hinzugefügt und die Transaktion abgeschlossen werden. Dieses
+Beispiel zeigt, wie Sie in Ihren Applikations-Code referentielle Integrität
+integrieren können.
+
+Sehen wir uns ein weiteres Beispiel an. Wir haben ein ganzzahliges
+Zählerfeld in einer Tabelle @code{kind_codes}, was benutzt wird, um jedem
+Kinde, das wir der Tabelle @code{kind} hinzufügen, eine eindeutige Kennung
+zuzuweisen. Es ist offensichtlich, dass Konsistentes Lesen oder
+Shared-Modus-Lesen kein geeignetes Mittel ist, um den aktuellen Wert des
+Zählers zu ermitteln, weil nämlich zwei Benutzer der Datenbank denselben
+Wert des Zählers sehen können und wir daher einen Fehler wegen doppelter
+Schlüsseleinträge erhalten, wenn wir zwei Kinder mit derselben Kennung in
+die Tabelle einfügen.
+
+In diesem Fall gibt es zwei geeignete Möglichkeiten, das Lesen und
+Heraufzählen des Zählers zu implementieren:
+(1) Zuerst den Zähler um eins erhöhen und erst danach lesen.
+(2) Zuerst den Zähler im Sperr-Modus @code{FOR UPDATE} lesen und danach
+heraufzählen:
+
+@example
+SELECT COUNTER_FIELD FROM kind_codes FOR UPDATE;
+UPDATE kind_codes SET COUNTER_FIELD = COUNTER_FIELD + 1;
+@end example
+
+@code{SELECT ... FOR UPDATE} liest die letzten verfügbaren Daten und setzt
+exklusive Sperren auf jede Zeile, die es liest. Daher setzt es dieselben
+Sperren, die ein gesuchtes SQL-@code{UPDATE} auf die Zeilen setzen würde.
+
+
+@node InnoDB Next-key locking, InnoDB Locks set, InnoDB locking reads, InnoDB transaction model
+@c German node Nächsten-Schlüssel-Sperren bei InnoDB
+@subsubsection Nächsten Schlüssel sperren: Wie das Phantom-Problem vermieden wird
+
+Beim Sperren auf Zeilenebene benutzt InnoDB einen Algorithmus, der
+Nächsten-Schlüssel-Sperren genannt wird. InnoDB führt das Sperren auf
+Zeilenebene so durch, dass es beim Suchen oder Scannen eines Indexes auf
+eine Tabelle gemeinsam genutzte (shared) oder exklusive Sperren auf die
+Index-Datensätze setzt, die es findet. Daher werden die Sperren auf
+Zeilenebene genauer Index-Datensatz-Sperren genannt.
+
+Die Sperren, die InnoDB auf Index-Datensätze setzt, betreffen auch die
+'Lücke' vor diesem Index-Datensatz. Wenn ein Benutzer eine gemeinsam
+benutzte (shared) oder exklusive Sperre auf den Datensatz R in einem Index
+hat, kann ein anderen Benutzer keinen Datensatz direkt vor R (in der
+Index-Reihenfolge) einfügen. Dieses Sperren von Lücken wird durchgeführt,
+um das so genannte Phantom-Problem zu vermeiden. Angenommen, man will alle
+Kinder aus der Tabelle @code{kind} lesen und sperren, die eine Kennung
+größer 100 haben, und irgend ein Feld in der ausgewählten Zeile
+aktualisieren:
+
+@example
+SELECT * FROM kind WHERE ID > 100 FOR UPDATE;
+@end example
+
+Angenommen, es gibt einen Index auf der Tabelle @code{kind} auf der Spalte
+@code{ID}. Unsere Anfrage scannt diesen Index ab dem ersten Datensatz, bei
+dem @code{ID} größer als 100 ist. Wenn jetzt die auf den Index-Datensatz
+gesetzten Sperren nicht Einfügeoperationen sperren würden, die in die
+Lücken ausgeführt würden, könnte zwischenzeitlich ein neues Kind in die
+Tabelle eingefügt werden. Wenn jetzt unsere Transaktion noch einmal
+folgendes ausführen würde:
+
+@example
+SELECT * FROM kind WHERE ID > 100 FOR UPDATE;
+@end example
+
+Sehen wir ein neues Kind in der Ergebnismenge, die die Anfrage zurückgibt.
+Das verstößt gegen das Isolationsprinzip von Transaktionen: Eine
+Transaktion sollte in der Lage sein, so abzulaufen, dass die Daten, die sie
+gelesen hat, sich nicht während der Transaktion ändern. Wenn wir einen Satz
+von Zeilen als Daten-Posten betrachten, würde das neue 'Phantom'-Kind
+dieses Isolationsprinzip durchbrechen.
+
+Wenn InnoDB einen Index scannt, kann es auch die Lücke nach dem letzten
+Datensatz im Index sperren. Genau das passiert im vorherigen Beispiel: Die
+Sperren, die von InnoDB gesetzt werden, verhindert jedes Einfügen in die
+Tabelle an Stellen, wo @code{ID} größer als 100 ist.
+
+Sie können Nächsten-Schlüssel-Sperren dazu benutzen, eine
+Eindeutigkeitsprüfung in Ihre Applikation zu implementieren: Wenn Sie Ihre
+Daten im Share-Modus lesen und kein Duplikat für eine Zeile sehen, die Sie
+einfügen werden, können Sie Ihre Zeile sicher einfügen und wissen, dass das
+Nächsten-Schlüssel-Sperren verhindern wird, dass zwischenzeitlich jemand
+eine Duplikatzeile Ihrer Zeile einfügt. Daher gestattet Ihnen das
+Nächsten-Schlüssel-Sperren, die Nicht-Existenz von irgend etwas in Ihrer
+Tabelle zu 'sperren'.
+
+@node InnoDB Locks set, InnoDB Deadlock detection, InnoDB Next-key locking, InnoDB transaction model
+@c German node Bei InnoDB gesetzte Sperren
+@subsubsection Sperren, die in InnoDB durch unterschiedliche SQL-Statements gesetzt werden
+
+@itemize @bullet
+@item
+@code{SELECT ... FROM ...} : Das ist Konsistentes Lesen, es wird ein
+Schnappschuss einer Datenbank gelesen und es werden keine Sperren gesetzt.
+@item
+@code{SELECT ... FROM ... LOCK IN SHARE MODE} : setzt gemeinsam genutztes
+(shared) Nächsten-Schlüssel-Sperren auf alle Index-Datensätze, die beim
+Lesen gefunden werden.
+@item
+@code{SELECT ... FROM ... FOR UPDATE} : setzt exklusives
+Nächsten-Schlüssel-Sperren auf alle Index-Datensätze, die beim Lesen
+gefunden werden.
+@item
+@code{INSERT INTO ... VALUES (...)} : setzt eine exklusive Sperre auf die
+eingefügte Zeile. Beachten Sie, dass diese Sperre kein
+Nächsten-Schlüssel-Sperren ist und andere Benutzer nicht davon abhält,
+etwas in die Lücke vor der eingefügten Zeile einzufügen. Wenn ein Fehler
+wegen doppelter Schlüsseleinträge auftritt, setzt dieser Befehl eine
+gemeinsam genutzte (shared) Sperre auf den doppelten (Duplikat)
+Index-Datensatz.
+@item
+@code{INSERT INTO T SELECT ... FROM S WHERE ...} setzt eine exklusive
+Sperre (kein Nächsten-Schlüssel-Sperren) auf jede Zeile, die in @code{T}
+eingefügt wurde. Sucht nach @code{S} in Form von Konsistentem Lesen, aber
+setzt Nächsten-Schlüssel-Sperren auf @code{S}, wenn bei MySQL das Loggen
+angeschaltet ist. InnoDB muss in letzterem Fall Sperren setzen, weil bei
+einer Roll-Forward-Wiederherstellung aus einer Datensicherung jedes
+SQL-Statement auf genau dieselbe Weise ausgeführt werden muss, wie es
+ursprünglich ausgeführt wurde.
+@item
+@code{CREATE TABLE ... SELECT ...} führt @code{SELECT} als Konsistentes
+Lesen oder mit gemeinsam genutzten (shared) Sperren aus, wie im vorherigen
+Punkt.
+@item
+@code{REPLACE} wird wie Einfügen ausgeführt, wenn es keine Kollision auf
+einem eindeutigen Schlüssel gibt. Ansonsten wird ein exklusives
+Nächsten-Schlüssel-Sperren auf die Reihe gesetzt, die aktualisiert werden
+muss.
+@item
+@code{UPDATE ... SET ... WHERE ...} setzt ein exklusives
+Nächsten-Schlüssel-Sperren auf jeden Datensatz, der beim Suchen gefunden
+wird.
+@item
+@code{DELETE FROM ... WHERE ...} setzt ein exklusives
+Nächsten-Schlüssel-Sperren auf jeden Datensatz, der beim Suchen gefunden
+wird.
+@item
+Wenn auf der Tabelle eine @code{FOREIGN KEY}-Beschränkung definiert ist,
+setzt jedes Einfügen, Aktualisieren oder Löschen, was die Überprüfung der
+Beschränkungsbedingung erfordert, gemeinsam genutzte (shared) Sperren auf
+Datensatzebene auf die Datensätze, die bei der Überprüfung der Beschränkung
+betrachtet werden. Auch im Falle, dass die Beschränkung fehlschlägt, setzt
+InnoDB diese Sperren.
+@item
+@code{LOCK TABLES ... } : setzt Tabellensperren. In der Implementation
+setzt die MySQL-Ebene des Codes diese Sperren. Die automatische
+Blockierungserkennung von InnoDB kann keine Blockierungen bemerken, bei
+denen solche Tabellensperren involviert sind, siehe nächster Abschnitt
+weiter unten. Sehen Sie auch im Abschnitt 13 ('InnoDB-Einschränkungen')
+wegen folgendem nach: Weil MySQL keine Sperren auf Zeilenebene erkennt, ist
+es möglich, dass Sie eine Sperre auf eine Tabelle erhalten, auf der ein
+anderer Benutzer momentan Sperren auf Zeilenebene hat. Das gefährdet
+allerdings nicht die Transaktionsintegrität.
+@end itemize
+
+
+@node InnoDB Deadlock detection, InnoDB Consistent read example, InnoDB Locks set, InnoDB transaction model
+@c German node Blockierungserkennung bei InnoDB
+@subsubsection Blockierungserkennung und Rollback
+
+InnoDB erkennt automatisch eine Blockierung von Transaktionen und rollt die
+Transaktion zurück, deren Sperranforderung diejenige war, die die
+Blockierung aufbaute, also einen Kreis im Warte-Diagramm von Transaktionen.
+InnoDB kann keine Blockierungen erkennen, bei denen eine Sperre im Spiel
+ist, die durch ein MySQL-@code{LOCK TABLES}-Statement verursacht wurde,
+oder wenn eine Sperre durch einen anderen Tabellen-Handler als InnoDB
+gesetzt wurde. Solche Situationen müssen Sie mit
+@code{innodb_lock_wait_timeout}, das in @file{my.cnf} gesetzt wird.
+
+Wenn InnoDB ein komplettes Rollback einer Transaktion durchführt, werden
+alle Sperren der Transaktion aufgehoben. Wenn jedoch nur ein einzelnes
+SQL-Statement als Ergebnis eines Fehlers zurückgerollt wird, können einige
+der Sperren, die durch das SQL-Statement gesetzt wurde, verbleiben. Das
+liegt daran, dass InnoDB Zeilensperren in einem Format speichert, die ihm
+unmöglich machen, im Nachhinein zu erkennen, welche Sperre durch welches
+SQL-Statement gesetzt wurde.
+
+@node InnoDB Consistent read example, , InnoDB Deadlock detection, InnoDB transaction model
+@c German node Konsistentes Lesen bei InnoDB im Beispiel
+@subsubsection Ein Beispiel, wie konsistentes Lesen bei InnoDB funktioniert
+
+Wenn Sie ein Konsistentes Lesen ausführen, also ein gewöhnliches
+@code{SELECT}-Statement, gibt InnoDB Ihrer Transaktion einen Zeitpunkt
+(Timepoint), gemäß dem Ihre Anfrage die Datenbank sieht. Wenn daher
+Transaktion B eine Zeile löscht und das wirksam wird (commit), nachdem Ihr
+Zeitpunkt zugewiesen wurde, werden Sie die Zeile nicht als gelöscht sehen.
+Gleiches gilt für Einfüge- und Aktualisierungsoperationen.
+
+Sie können Ihren Zeitpunkt 'vorstellen', indem Sie Ihre Transaktion
+abschicken (commit) und dann ein weiteres @code{SELECT} ausführen.
+
+Das nennt sich Multiversioned Concurrency Control (multiversionierte
+Gleichzeitigkeitskontrolle):
+
+@example
+ Benutzer A Benutzer B
+
+ set autocommit=0; set autocommit=0;
+zeit
+| SELECT * FROM t;
+| empty set
+| INSERT INTO t VALUES (1, 2);
+|
+v SELECT * FROM t;
+ empty set
+ COMMIT;
+
+ SELECT * FROM t;
+ empty set;
+
+ COMMIT;
+
+ SELECT * FROM t;
+ ---------------------
+ | 1 | 2 |
+ ---------------------
+@end example
+
+Daher sieht Benutzer A die durch B eingefügte Zeile erst, wenn B das
+Einfügen und A seine eigene Transaktion abgeschickt hat (commit), so dass
+der Zeitpunkt hinter das Commit von B 'vorgestellt' ist.
+
+Wenn Sie den 'frischsten' Zustand der Datenbank sehen wollen, sollten Sie
+ein sperrendes Lesen (Locking Read) benutzen:
+
+@example
+SELECT * FROM t LOCK IN SHARE MODE;
+@end example
+
+
+@subsection Tipps zur Performance-Steigerung
+
+@strong{1.}
+Wenn das Unix-@file{top} oder der Windows-@file{Task-Manager} zeigen, dass
+die CPU-Auslastung weniger als 70% beträgt, ist Ihre Auslastung
+wahrscheinlich Platten-gebunden. Das kann daran liegen, dass Sie zu viele
+Transaktionen abschicken (commit) oder dass der Puffer-Pool zu klein ist.
+Dann kann es helfen, den Puffer-Pool zu vergrößern. Setzen Sie ihn aber
+nicht höher als 80% des physikalischen Arbeitsspeichers.
+
+@strong{2.}
+Packen Sie mehrere Änderungen in eine Transaktion. InnoDB muss das Log
+jedes Mal auf Platte zurückschreiben (flush), wenn eine Transaktion
+abgeschickt wird (commit), wenn diese Transaktion irgend welche Änderungen
+an der Datenbank vorgenommen hat. Weil die Rotationsgeschwindigkeit einer
+Platte typischerweise höchsten 167 Umdrehungen pro Sekunde beträgt,
+beschränkt das die Anzahl von Commits auf eben diese Zahl pro Sekunde, wenn
+die Festplatte nicht das Betriebssystem täuscht.
+
+@strong{3.}
+Wenn Sie es sich leisten können, einige der zuletzt abgeschickten
+(committed) Transaktionen zu verlieren, können Sie den
+@file{my.cnf}-Parameter @code{innodb_flush_log_at_trx_commit} auf 0 setzen.
+InnoDB versucht dann trotzdem, das Log einmal pro Sekunde auf Platte
+zurückzuschreiben (flush), doch dieses Zurückschreiben ist nicht
+garantiert.
+
+@strong{4.}
+Machen Sie Ihre Log-Dateien Groß, selbst so Groß wie den Puffer-Pool.
+Wenn InnoDB seine Log-Dateien vollgeschrieben hat, muss es die veränderten
+Inhalte des Puffer-Pools in einem Checkpoint auf Platte schreiben. Kleine
+Log-Dateien verursachen daher unnötige Festplatten-Schreibzugriffe. Der
+Nachteil großer Log-Dateien liegt darin, dass die Wiederherstellungszeit
+länger wird.
+
+@strong{5.}
+Ausserdem sollte der Log-Puffer recht Groß sein, sagen wir 8 MB.
+
+@strong{6.} (Relevant from 3.23.39 up.)
+In einigen Versionen von Linux und Unix ist das Zurückschreiben von Dateien
+auf Platte (flush) mit dem Unix-@code{fdatasync} und anderen ähnlichen
+Methoden überraschend langsam. InnoDB benutzt vorgabemäßig die
+@code{fdatasync}-Funktion. Wenn Sie mit der Datenbank-Schreib-Performance
+nicht zufrieden sind, können Sie versuchen, die @code{innodb_flush_method}
+in @file{my.cnf} auf @code{O_DSYNC} zu setzen, obwohl O_DSYNC auf den
+meisten Systemen langsamer zu sein scheint.
+
+@strong{7.} Wenn Sie Daten in InnoDB importieren, stellen Sie sicher, dass
+MySQL @code{autocommit=1} nicht angeschaltet hat, denn dann benötigt jedes
+Einfügen ein Zurückschreiben des Logs auf Platte (flush). Setzen Sie vor
+Ihre SQL-Importdatei die Zeile
+
+@example
+set autocommit=0;
+@end example
+
+und danach
+
+@example
+commit;
+@end example
+
+Wenn Sie die @file{mysqldump}-Option @code{--opt} benutzen, erhalten Sie
+Dump-Dateien, die sich sehr schnell auch in eine InnoDB-Tabelle importieren
+lassen, selbst ohne sie in die oben erwähnten @code{set autocommit=0; ...
+commit;}-Wrapper zu verpacken.
+
+@strong{8.}
+Hüten Sie sich vor großen Rollbacks beim Einfügen von Massendaten: InnoDB
+benutzt den Einfüge-Puffer, um beim Einfügen Festplatten-Ein- und -Ausgaben
+zu sparen, doch beim entsprechenden Rollback wird kein solcher Mechanismus
+benutzt. Ein Festplatten-gebundenes Rollback kann die 30-fache Zeit des
+entsprechenden Einfügevorgangs in Anspruch nehmen. Es hilft nicht, den
+Datenbankprozess zu killen, weil der Rollback erneut starten wird, wenn die
+Datenbank hochfährt. Die einzige Möglichkeit, ein aus dem Ruder gelaufenes
+Rollback loszuwerden, besteht darin, den Puffer-Pool zu erhöhen, so dass
+das Rollback CPU-gebunden wird und damit schnell läuft, oder indem die
+gesamte InnoDB-Datenbank gelöscht wird.
+
+@strong{9.}
+Seien Sie auch vor anderen großen Festplatten-gebundenen Operationen auf
+der Hut. Benutzen Sie @code{DROP TABLE} oder @code{TRUNCATE} (ab
+MySQL-4.0), um eine Tabelle zu löschen, nicht @code{DELETE FROM tabelle}.
+
+@strong{10.}
+Benutzen Sie das mehrzeilige @code{INSERT}, um den Kommunikations-Overhead
+zwischen Client und Server zu verringern, wenn Sie viele Zeilen einfügen
+müssen:
+
+@example
+INSERT INTO tabelle VALUES (1, 2), (5, 5);
+@end example
+
+Dieser Tipp gilt natürlich für jeden Tabellentyp, nicht nur für InnoDB.
+
+@subsubsection Der InnoDB-Monitor
+
+Ab Version 3.23.41 beinhaltet InnoDB den InnoDB-Monitor, der Informationen
+über den internen Zustand von InnoDB ausgibt. Wenn er angeschaltet ist,
+veranlasst der InnoDB-Monitor den MySQL-Server @file{mysqld}, etwa alle 15
+Sekunden Daten an die Standardausgabe auszugeben (Hinweis: der MySQL-Client
+gibt nichts aus). Diese Daten sind nützlich, um die Performance zu tunen.
+Unter Windows müssen Sie @code{mysqld-max} von einer DOS-Kommandozeile aus
+mit @code{--standalone --console} starten, um die Ausgabe auf das
+DOS-Fenster umzuleiten.
+
+Es gibt einen separaten @code{innodb_lock_monitor}, der dieselben
+Informationen ausgibt wie @code{innodb_monitor}, aber zusätzlich
+Informationen über Sperren, die durch jede Transaktion gesetzt werden.
+
+Die ausgegebene Information enthält Daten über:
+@itemize @bullet
+@item
+Sperren, die auf eine Transaktion warten,
+@item
+Semaphore, die auf Threads warten,
+@item
+anhängige Datei-Ein- und -Ausgabeanforderungen,
+@item
+Puffer-Pool-Statistiken und
+@item
+Bereinigungs- (purge) und Einfüge-Puffer-Vermengungs- (merge) Aktivität des
+Haupt-Threads von InnoDB.
+@end itemize
+
+Sie können den InnoDB-Monitor mit folgendem SQL-Befehl starten:
+
+@example
+CREATE TABLE innodb_monitor(a int) type = innodb;
+@end example
+
+Und ihn mit folgendem Befehl anhalten:
+
+@example
+DROP TABLE innodb_monitor;
+@end example
+
+Die @code{CREATE TABLE}-Syntax ist nur eine Möglichkeit, einen Befehl durch
+den MySQL-SQL-Parser an die InnoDB-Engine durchzureichen. Wenn Sie die
+Datenbank herunter fahren, während der Monitor läuft, und Sie den Monitor
+erneut starten wollen, müssen Sie die Tabelle löschen, bevor Sie ein
+erneutes @code{CREATE TABLE} absetzen können, um den Monitor zu starten.
+Diese Syntax wird sich in zukünftigen Releases möglicherweise ändern.
+
+
+Beispiel für die Ausgabe des InnoDB-Monitors:
+
+@example
+================================
+010809 18:45:06 INNODB MONITOR OUTPUT
+================================
+--------------------------
+LOCKS HELD BY transactions
+--------------------------
+LOCK INFO:
+Number of locks in the record hash table 1294
+LOCKS FOR TRANSACTION ID 0 579342744
+TABLE LOCK table test/tabelle trx id 0 582333343 lock_mode IX
+
+RECORD LOCKS space id 0 page no 12758 n bits 104 table test/tabelle index
+PRIMARY trx id 0 582333343 lock_mode X
+Record lock, heap no 2 PHYSICAL RECORD: n_fields 74; 1-byte offs FALSE;
+info bits 0
+ 0: len 4; hex 0001a801; asc ;; 1: len 6; hex 000022b5b39f; asc ";; 2: len 7;
+hex 000002001e03ec; asc ;; 3: len 4; hex 00000001;
+...
+-----------------------------------------------
+CURRENT SEMAPHORES RESERVED AND SEMAPHORE WAITS
+-----------------------------------------------
+SYNC INFO:
+Sorry, cannot give mutex list info in non-debug version!
+Sorry, cannot give rw-lock list info in non-debug version!
+-----------------------------------------------------
+SYNC ARRAY INFO: reservation count 6041054, signal count 2913432
+4a239430 waited for by thread 49627477 op. S-LOCK file NOT KNOWN line 0
+Mut ex 0 sp 5530989 r 62038708 sys 2155035; rws 0 8257574 8025336; rwx 0 1121090 1848344
+-----------------------------------------------------
+CURRENT PENDING FILE I/O'S
+--------------------------
+Pending normal aio reads:
+Reserved slot, messages 40157658 4a4a40b8
+Reserved slot, messages 40157658 4a477e28
+...
+Reserved slot, messages 40157658 4a4424a8
+Reserved slot, messages 40157658 4a39ea38
+Total of 36 reserved aio slots
+Pending aio writes:
+Total of 0 reserved aio slots
+Pending insert buffer aio reads:
+Total of 0 reserved aio slots
+Pending log writes or reads:
+Reserved slot, messages 40158c98 40157f98
+Total of 1 reserved aio slots
+Pending synchronous reads or writes:
+Total of 0 reserved aio slots
+-----------
+BUFFER POOL
+-----------
+LRU list length 8034
+Free list length 0
+Flush list length 999
+Buffer pool size in pages 8192
+Pending reads 39
+Pending writes: LRU 0, flush list 0, single page 0
+Pages read 31383918, created 51310, written 2985115
+----------------------------
+END OF INNODB MONITOR OUTPUT
+============================
+010809 18:45:22 InnoDB starts purge
+010809 18:45:22 InnoDB purged 0 pages
+@end example
+
+Einige Anmerkungen zur Ausgabe:
+
+@itemize @bullet
+@item
+Wenn der Abschnitt @code{LOCKS HELD BY transactions} warten auf Sperren
+berichtet, kann es sein, dass Ihre Applikation Sperr-Konflikte hat. Die
+Ausgabe kann auch helfen, Gründe für Transaktions-Blockierungen
+aufzuspüren.
+@item
+Der Abschnitt @code{SYNC INFO} berichtet reservierte Semaphore, wenn Sie
+InnoDB mit @code{UNIV_SYNC_DEBUG} kompilieren, definiert in @file{univ.i}.
+@item
+Der Abschnitt @code{SYNC ARRAY INFO} berichtet Threads, die auf ein
+Semaphor warten, und Statistiken, wie viele Male Threads ein Spin oder ein
+Warten auf einem Mutex oder einem Lese-/Schreibe-Sperr-Semaphor benötigten.
+Eine große Anzahl auf Semaphore wartender Threads kann ein Ergebnis von
+Festplatten-Ein- und -Ausgaben oder Konfliktproblemen innerhalb von InnoDB
+sein. Konflikte können durch starke Parallelen von Anfragen oder durch
+Probleme des Betriebssystems beim Thread Scheduling hervorgerufen werden.
+@item
+Der Abschnitt @code{CURRENT PENDING FILE I/O'S} listet anhängige Datei-Ein-
+und -Ausgabeanforderungen auf. Eine große Anzahl davon zeigt an, dass die
+Auslastung Festplatten-Ein- und -Ausgabe-gebunden ist.
+@item
+Der Abschnitt @code{BUFFER POOL} gibt statistische Informationen über
+gelesene und geschriebene Seiten. Aus diesen Zahlen können Sie errechnen,
+wie viele Daten-Datei-Ein- und Ausgaben Ihre Anfragen aktuell durchführen.
+@end itemize
+
+@node Implementation, Table and index, InnoDB transaction model, InnoDB
+@c German node Implementation
+@subsection Implementation des Multiversionings
+
+Weil InnoDB eine multiversionierte Datenbank ist, muss es Informationen
+über alte Versionen von Zeilen im Tabellenplatz (Tablespace) aufbewahren.
+Diese Informationen werden in einer Datenstruktur gespeichert, die wir in
+Anlehnung an eine analoge Struktur in Oracle Rollback-Segment nennen.
+
+InnoDB fügt jeder Zeile, die in der Datenbank gespeichert wird, intern zwei
+Felder hinzu. Ein 6 Byte großes Feld enthält den
+Transaktions-Identifikator der letzten Transaktion, die die Zeile eingefügt
+oder aktualisiert hat. Ein Löschen wir intern als eine Aktualisierung
+behandelt, wobei ein spezielles Bit in die Zeile eingefügt wird, um sie als
+gelöscht zu markieren. Jede Zeile enthält ausserdem ein 7 Byte großes
+Feld, das Roll-Zeiger genannt wird. Der Roll-Zeiger zeigt auf einen
+Rückgängig-Log-Datensatz, der in das Rollback-Segment geschrieben wird.
+Wenn die Zeile aktualisiert wurde, enthält der Rückgängig-Log-Datensatz die
+Informationen, die notwendig sind, um den Inhalt der Zeile wieder
+herzustellen, bevor sie aktualisiert wurde.
+
+InnoDB benutzt die Informationen im Rollback-Segment, um die
+Rückgängig-Operationen durchzuführen, die bei einem Transaktions-Rollback
+notwendig sind. Diese Informationen benutzt es auch dafür, um frühere
+Informationen einer Zeile beim Konsistenten Lesen aufzubauen.
+
+Rückgängig-Logs im Rollback-Segment lassen sich in Logs für Einfügen und
+für Aktualisieren unterteilen. Einfüge-Rückgängig-Logs werden nur für
+Transaktions-Rollbacks benötigt und können verworfen werden, sobald die
+Transaktion abgeschickt ist (commit). Aktualisierungs-Rückgängig-Logs
+werden auch für Konsistentes Lesens benutzt und können daher erst verworfen
+werden, wenn keine Transaktion mehr vorhanden ist, für die InnoDB einen
+Schnappschuss zugewiesen hat, dessen Informationen beim Konsistenten Lesen
+benötigt werden könnten, um daraus eine frühere Version der Datenbank-Zeile
+aufzubauen.
+
+Sie müssen daran denken, Ihre Transaktionen regelmäßig abzuschicken
+(commit), auch die Transaktionen, die nur Konsistentes Lesens ausführen.
+Ansonsten kann InnoDB Daten aus dem Aktualisierungs-Rückgängig-Log nicht
+verwerfen und das Rollback-Segment könnte zu Groß werden und Ihren
+Tabellenplatz (Tablespace) komplett füllen.
+
+Die physikalische Größe eines Rückgängig-Log-Datensatzes im
+Rollback-Segment ist typischerweise kleiner als die entsprechende
+eingefügte oder aktualisierte Zeile. Sie können diese Informationen
+benutzen, um den Platzbedarf für Ihr Rollback-Segment zu berechnen.
+
+In diesem multiversionierten Schema wird eine Zeile nicht unmittelbar
+physikalisch aus der Datenbank entfernt, wenn Sie sie mit einem
+SQL-Statement löschen. Erst wenn InnoDB den Datensatz des
+Aktualisierungs-Rückgängig-Logs löschen kann, der für das Löschen
+geschrieben wurde, kann es die entsprechende Zeile und ihre
+Index-Datensätze auch physikalisch aus der Datenbank entfernen. Diese
+Entfernungsoperation wird Purge genannt und ist recht schnell, wobei sie
+überschlägig dieselbe Zeit benötigt wie das SQL-Statement, das das Löschen
+ausführte.
+
+
+@node Table and index, File space management, Implementation, InnoDB
+@c German node Tabelle und Index
+@subsection Tabellen- und Index-Strukturen
+
+MySQL speichert seine Daten-Wörterbuch-Informationen über Tabellen in
+@file{.frm}-Dateien in den Datenbank-Verzeichnissen. Jedoch hat auch jede
+Tabelle vom Typ InnoDB ihren eigenen Eintrag, in InnoDB-internen
+Daten-Wörterbüchern innerhalb des Tabellenplatzes (Tablespace). Wenn MySQL
+eine Tabelle oder Datenbank löscht, muss er sowohl eine oder mehrere
+@file{.frm}-Datei(en) als auch die entsprechenden Einträge im
+InnoDB-Daten-Wörterbuch löschen. Das ist der Grund, warum Sie
+InnoDB-Tabellen nicht einfach zwischen Datenbanken verschieben können,
+indem Sie die @file{.frm}-Dateien verschieben und warum @code{DROP
+DATABASE} bei InnoDB-Tabellen in MySQL-Versionen bis 3.23.43 nicht
+funktionierte.
+
+Jede InnoDB-Tabelle hat einen speziellen Index, der Cluster-Index genannt
+wird, in dem die Daten der Zeilen gespeichert sind. Wenn Sie auf Ihre
+Tabelle einen @code{PRIMARY KEY} definieren, ist der Index des
+Primärschlüssels der Cluster-Index.
+
+Wenn Sie für Ihre Tabelle keinen Primärschlüssel definieren, erzeugt InnoDB
+intern einen Cluster-Index, bei dem die Zeilen nach der Zeilen-Kennung (ID)
+geordnet sind, die InnoDB Zeilen in einer solchen Tabelle zuweist. Die
+Zeilen-Kennung ist ein 6 Byte großes Feld, das monoton erhöht wird, wenn
+neue Zeilen eingefügt werden. Daher liegen nach der Zeilen-Kennung
+geordnete Zeile physikalisch in der Einfüge-Reihenfolge vor.
+
+Der Zugriff auf eine Zeile über den Cluster-Index ist schnell, weil die
+Zeilendaten auf derselben Seite sind, auf die die Index-Suche führt. In
+vielen Datenbanken werden die Daten traditionell auf einer anderen Seite
+als derjenigen, wo sich der Index-Datensatz befindet, gespeichert. Wenn die
+Tabelle Groß ist, spart die Cluster-Index-Architektur im Vergleich zur
+traditionellen Lösung auf Festplatten-Ein- und -Ausgaben.
+
+In InnoDB enthalten die Datensätze in Nicht-Cluster-Indexen (die wir auch
+sekundäre Indexe nennen) den Primärschlüsselwert für die Zeile. InnoDB
+benutzt diesen Primärschlüsselwert, um vom Cluster-Index aus nach der Zeile
+zu suchen. Beachten Sie, dass die sekundären Indexe mehr Platz benötigen,
+wenn der Primärschlüssel lang ist.
+
+
+
+@menu
+* InnoDB physical structure::
+* InnoDB Insert buffering::
+* InnoDB Adaptive hash::
+* InnoDB Physical record::
+@end menu
+
+@node InnoDB physical structure, InnoDB Insert buffering, Table and index, Table and index
+@c German node Physikalische Struktur von InnoDB
+@subsubsection Physikalische Struktur eines Indexes
+
+Alle Indexe in InnoDB sind B-Bäume, in denen die Index-Datensätze in den
+Blätter-Seiten des Baums gespeichert sind. Die vorgabemäßige Größe einer
+Index-Seite ist 16 KB. Wenn neue Datensätze eingefügt werden, versucht
+InnoDB, 1/16 der Seite für zukünftige Einfügungen und Aktualisierungen des
+Index-Datensatzes freizuhalten.
+
+Wenn Index-Datensätze in sequentieller (aufsteigender oder absteigender)
+Reihenfolge eingefügt werden, sind die resultierenden Index-Seiten ungefähr
+zu 15/16 gefüllt. Wenn der Füllfaktor einer Index-Seite unter 1/12 fällt,
+versucht InnoDB, den Index-Baum zusammenzuziehen, um die Seite
+freizugeben.
+
+
+@node InnoDB Insert buffering, InnoDB Adaptive hash, InnoDB physical structure, Table and index
+@c German node Einfügepuffer von InnoDB
+@subsubsection Einfügepufferung
+
+Häufig wird der Primärschlüssel in Datenbank-Applikationen als eindeutiger
+Identifizierer benutzt und neue Zeilen in aufsteigender Reihenfolge des
+Primärschlüssels eingefügt. Daher erfordern Einfügungen in den
+Cluster-Index keine wahlfreien (random) Lesezugriffe auf die Platte.
+
+Sekundäre Indexe auf der anderen Seite sind üblicherweise nicht eindeutig
+und Einfügungen in sekundäre Indexe erfolgen in einer relativ wahlfreien
+Reihenfolge. Wenn InnoDB keinen speziellen Mechanismus hierfür benutzen
+würde, würden diese viele wahlfreie Festplatten-Ein- und -Ausgaben
+verursachen.
+
+Wenn ein Index-Datensatz in einen nicht eindeutigen sekundären Index
+eingefügt werden soll, prüft InnoDB, ob die sekundäre Index-Seite bereits
+im Puffer-Pool ist. Wenn das der Fall ist, führt InnoDB das Einfügen direkt
+in die Index-Seite durch. Wenn die Index-Seite aber nicht im Puffer-Pool
+gefunden wird, fügt InnoDB den Datensatz in eine spezielle
+Einfüge-Puffer-Struktur ein. Der Einfüge-Puffer wird so klein gehalten,
+dass er komplett in den Puffer-Pool passt, so dass Einfügungen sehr schnell
+durchgeführt werden können.
+
+Der Einfüge-Puffer wird periodisch mit den sekundären Index-Bäumen in der
+Datenbank vermengt. Oft können mehrere Einfügeoperationen auf derselben
+Seite im Index-Baum zusammengefasst werden, so dass Festplatten-Ein- und
+-Ausgaben eingespart werden. Messungen ergaben, dass der Einfüge-Puffer
+Einfügungen in eine Tabelle bis zu 15 mal schneller machen kann.
+
+
+@node InnoDB Adaptive hash, InnoDB Physical record, InnoDB Insert buffering, Table and index
+@c German node Anpassungsfähiger Hash in InnoDB
+@subsubsection Anpassungsfähige Hash-Indexe
+
+Wenn eine Datenbank fast komplette in den Hauptspeicher passt, können
+Anfragen am schnellsten unter Verwendung von Hash-Indexen ausgeführt
+werden. InnoDB hat einen automatischen Mechanismus, der Index-Suchen
+beobachtet, die auf den Indexen durchgeführt werden, die für eine Tabelle
+definiert wurden. Wenn InnoDB bemerkt, dass Anfragen vom Aufbauen eines
+Hash-Indexes profitieren könnten, wird ein solcher Index automatisch
+aufgebaut.
+
+Beachten Sie aber, dass der Hash-Index immer auf der Grundlage eines
+bestehenden B-Baum-Indexes auf die Tabelle aufgebaut wird. InnoDB kann
+einen Hash-Index auf einem Präfix beliebiger Länge des Schlüssels aufbauen,
+der für den B-Baum definiert wurde, abhängig vom Suchmuster, das InnoDB auf
+dem Index-Baum beobachtet. Ein Hash-Index kann partiell sein: Es ist nicht
+erforderlich, dass der gesamte Index-Baum im Puffer-Pool
+zwischengespeichert ist. InnoDB baut Hash-Indexe bei Bedarf automatisch für
+die Index-Seiten auf, auf die oft zugegriffen wird.
+
+In gewisser Hinsicht kommt InnoDB durch den anpassungsfähigen
+Hash-Index-Mechanismus (wobei sich InnoDB üppig verfügbarem Hauptspeicher
+anpasst) der Architektur von Hauptspeicher-Datenbanken nahe.
+
+
+@node InnoDB Physical record, , InnoDB Adaptive hash, Table and index
+@c German node Physikalischer Datensatz in InnoDB
+@subsubsection Physikalische Datensatzstruktur
+
+@itemize @bullet
+@item
+Jeder Index-Datensatz in InnoDB enthält einen Header von 6 Bytes. Der
+Header wird benutzt, um nachfolgende Datensätze zu verknüpfen, sowie beim
+Sperren auf Zeilenebene.
+@item
+Datensätze im Cluster-Index enthalten Felder für alle benutzerdefinierten
+Spalten. Zusätzlich gibt es ein 6 Byte großes Feld für die
+Transaktions-Kennung und ein 7 Byte großes Feld für den Roll-Zeiger.
+@item
+Wenn der Benutzer keinen Primärschlüssel für eine Tabelle definiert hat,
+enthält jeder Cluster-Index-Datensatz zusätzlich ein 6 Byte großes
+Zeilenkennungsfeld.
+@item
+Jeder sekundäre Index-Datensatz enthält auch alle Felder, die für den
+Cluster-Index-Schlüssel definiert wurden.
+@item
+Ein Datensatz enthält auch einen Zeiger zu jedem Feld des Datensatzes. Wenn
+die Gesamtlänge des Feldes in einem Datensatz kleiner als 128 Bytes ist,
+ist der Zeiger 1 Byte lang, ansonsten 2 Bytes.
+@end itemize
+
+@subsubsection Wie eine Auto-Increment-Spalte in InnoDB funktioniert
+
+Wenn der Benutzer nach einem Datenbankstart zuerst einen Datensatz in eine
+Tabelle @code{T} einfügt, in der eine Auto-Increment-Spalte definiert
+wurde, und er keinen expliziten Wert für die Spalte angibt, führt InnoDB
+@code{SELECT MAX(auto-inc-column) FROM T} aus und weist den um 1
+hochgezählten Wert der Spalte und dem Auto-Increment-Zähler der Tabelle zu.
+Wir sagen dazu, dass der Auto-Increment-Zähler für Tabelle @code{T}
+initialisiert wurde.
+
+InnoDB führt dieselbe Prozedur der Initialisierung des
+Auto-Increment-Zählers für eine frisch erzeugte Tabelle durch.
+
+Wenn Sie für die Auto-Increment-Spalte einen Wert von 0 angeben, beachten
+Sie, dass InnoDB die Zeile so behandelt, als hätten Sie den Wert nicht
+angegeben.
+
+Wenn nach der Initialisierung des Auto-Increment-Zählers der Benutzer eine
+Zeile eingibt, in der er explizit den Spaltenwert angibt, und dieser
+größer als der aktuelle Zählerwert ist, wird der Zähler auf den
+angegebenen Spaltenwert gesetzt. Wenn der Benutzer nicht explizit einen
+Wert angibt, zählt InnoDB den Zähler um 1 hoch und weist der Spalte diesen
+neuen Wert zu.
+
+Der Auto-Increment-Mechanismus umgeht beim Zuweisen von Werten vom Zähler
+Sperren und Transaktionshandhabung. Daher können Lücken in der
+Nummernfolge entstehen, wenn Sie Transaktionen zurückrollen (Rollback), die
+Nummern vom Zähler erhalten haben.
+
+Das Verhalten von Auto-Increment ist für die Fälle undefiniert, in denen
+ein Benutzer der Spalte einen negativen Wert gibt oder wenn der Wert
+größer als die größte Ganzzahl wird, die im festgelegten Ganzzahl-Typ
+gespeichert werden kann.
+
+
+@node File space management, Error handling, Table and index, InnoDB
+@c German node Verwaltung von Datei-Speicherplatz
+@subsection Verwaltung von Datei-Speicherplatz und Festplatten-Eingaben / -Ausgaben
+
+
+
+@menu
+* InnoDB Disk I/O::
+* InnoDB File space::
+* InnoDB File Defragmenting::
+@end menu
+
+@node InnoDB Disk I/O, InnoDB File space, File space management, File space management
+@c German node Festplatten-Ein- und -Ausgaben bei InnoDB
+@subsubsection Festplatten-Ein- und -Ausgaben
+
+Bei Festplatten-Ein- und -Ausgaben benutzt InnoDB asynchrone Ein- und
+Ausgaben. Unter Windows NT benutzt es die nativen Ein- und Ausgaben, die
+vom Betriebssystem zur Verfügung gestellt werden. Unter Unix benutzt InnoDB
+simulierte asynchrone Ein- und Ausgaben, die in InnoDB eingebaut sind:
+InnoDB erzeugt eine Reihe von Ein-/Ausgabe-Threads, die sich um Ein- und
+Ausgabeoperationen kümmern, zum Beispiel Vorwärts-Lesen (Read-Ahead).
+Zukünftig werden wir auch für Windows NT simulierte Ein-/Ausgaben
+unterstützen sowie für die Unix-Versionen, die so etwas besitzen, native
+Ein-/Ausgaben.
+
+Unter Windows NT benutzt InnoDB ungepufferte Ein- und Ausgaben. Das heißt,
+dass die Festplatten-Seiten, die InnoDB liest oder schreibt, nicht im
+Datei-Cache des Betriebssystems gepuffert werden. Das spart einiges an
+Arbeitsspeicher-Bandbreite.
+
+Ab Version 3.23.41 benutzt InnoDB eine neuartige Datei-Flush-Technik, die
+Doublewrite heißt. Sie erhöht die Sicherheit bei Reparaturen nach Absturz,
+wenn ein Betriebssystemabsturz oder ein Stromausfall aufgetreten sind, und
+verbessert auf den meisten Unix-Versionen die Performance, indem die
+Notwendigkeit von Fsync-Operationen verringert wird.
+
+Doublewrite bedeutet, dass InnoDB zuerst in einen zusammenhängenden
+Tabellenplatz (Tablespace) namens Doublewrite-Puffer schreibt, bevor Seiten
+in eine Daten-Datei geschrieben werden. Erst nachdem das Schreiben und
+Zurückschreiben (Flush) in den Doublewrite-Puffer fertig sind, schreibt
+InnoDB die Seiten an ihre korrekten Positionen in der Daten-Datei. Wenn das
+Betriebssystem mitten in einem Seiten-Schreiben abstürzt, findet InnoDB bei
+der Wiederherstellung eine gute Kopie der Seite im Doublewrite-Puffer.
+
+Ab Version 3.23.41 können Sie auch eine Raw-Disk-Partition als Daten-Datei
+benutzen, obwohl das bisher noch nicht getestet wurde. Wenn Sie eine neue
+Daten-Datei erzeugen, müssen Sie das Schlüsselwort @code{newraw}
+unmittelbar nach der Daten-Datei-Größe in @code{innodb_data_file_path}
+angeben. Die Partition muss größer oder gleich der Größe sein, die Sie
+angeben. Beachten Sie, dass in InnoDB 1 MB 1024 x 1024 Bytes ist, während 1
+MB in Festplatten-Spezifikationen üblicherweise 1.000.000 Bytes bedeutet.
+
+@example
+innodb_data_file_path=hdd1:5Gnewraw;hdd2:2Gnewraw
+@end example
+
+Wenn Sie die Datenbank wieder starten, @strong{müssen} -sue das
+Schlüsselwort in @code{raw} ändern. Ansonsten schreibt InnoDB über Ihre
+Partition!
+
+@example
+innodb_data_file_path=hdd1:5Graw;hdd2:2Graw
+@end example
+
+Wenn Sie Raw-Disk benutzen, können Sie unter einigen Unixen ungepufferte
+Ein- und Ausgaben ausführen.
+
+Es gibt zwei Vorwärts-Lesen-(Read-Ahead-)Heuristiken in InnoDB:
+sequentielles Vorwärts-Lesen und wahlfreies (random) Vorwärts-Lesen. Beim
+sequentiellen Vorwärts-Lesen bemerkt InnoDB, dass das Zugriffsschema auf
+ein Segment im Tabellenplatz (Tablespace) sequentiell ist. InnoDB schickt
+dann vorab einen Stapel von Lesevorgängen von Datenbankseiten an das
+Ein-/Ausgabesystem. Beim wahlfreien Vorwärts-Lesen bemerkt InnoDB, dass ein
+bestimmter Bereich im Tabellenplatz (Tablespace) im Zustand des vollständig
+Eingelesenwerdens in den Puffer-Pool zu sein scheint. Dann schickt InnoDB
+die verbleibenden Lesevorgänge an das Ein-/Ausgabesystem.
+
+
+@node InnoDB File space, InnoDB File Defragmenting, InnoDB Disk I/O, File space management
+@c German node Speicherplatz in InnoDB
+@subsubsection Speicherplatzverwaltung
+
+Die Daten-Dateien, die Sie in der Konfigurationsdatei definieren, formen
+den Tabellenplatz (Tablespace) von InnoDB. Die Dateien werden einfach
+verkettet, um den Tabellenplatz (Tablespace) zu formen, es wird kein
+Striping benutzt. Momentan können Sie nicht direkt angeben, wo der Platz
+für Ihre Tabellen zugewiesen werden soll, ausser wenn Sie folgende Tatsache
+benutzen: InnoDB weist Speicherplatz von einem neu erzeugten Tabellenplatz
+(Tablespace) vom niedrigen Ende ausgehend zu.
+
+Der Tabellenplatz (Tablespace) besteht aus Datenbankseiten, deren
+vorgabemäßige Größe 16 KB beträgt. Diese Seiten werden bis zu einer
+Ausdehnung von 64 aufeinander folgenden Seiten gruppiert. Die 'Dateien'
+innerhalb eines Tabellenplatzes (Tablespace) werden in InnoDB Segmente
+genannt. Der Name des Rollback-Segments ist in gewisser Hinsicht
+irreführend, weil dieses tatsächlich viele Segmente im Tabellenplatz
+enthält.
+
+Für jeden Index in InnoDB werden zwei Segmente zugewiesen: eins für die
+Nicht-Blätter-Knoten (Non-Leaf-Nodes) des B-Baum, das andere für die
+Blätter-Knoten. Die Idee dahinter ist, für die Blätter-Knoten, die die
+Daten enthalten, bessere Sequentialität zu erzielen.
+
+Wenn ein Segment innerhalb des Tabellenplatzes anwächst, weist ihm InnoDB
+die ersten 32 Seiten individuell zu. Danach fängt InnoDB an, dem Segment
+ganze Ausdehnungen zuzuweisen. InnoDB kann einem großen Segment bis zu
+vier Ausdehnungen auf einmal hinzufügen, um gute Sequentialität für die
+Daten sicherzustellen.
+
+Einige Seiten im Tabellenplatz enthalten Bitmaps anderer Seiten. Daher
+können einige Ausdehnungen in einem InnoDB-Tabellenplatz (Tablespace) nicht
+Segmenten als Ganzes zugewiesen werden, sondern nur als individuelle
+Seiten.
+
+Wenn Sie eine Anfrage @code{SHOW TABLE STATUS FROM ... LIKE ...} ausführen,
+um den verfügbaren freien Platz im Tabellenplatz festzustellen, berichtet
+InnoDB den Platz, der in völlig freien Ausdehnungen im Tabellenplatz sicher
+benutzt werden kann. InnoDB reserviert immer einige Ausdehnungen für
+Säuberungs- und interne Zwecke. Diese Ausdehnungen werden nicht in den
+freien Platz einbezogen.
+
+Wenn Sie Daten aus einer Tabelle löschen, zieht InnoDB die entsprechenden
+B-Baum-Indexe zusammen. Es hängt vom Schema der Löschvorgänge ab, ob das
+individuelle Seiten oder Ausdehnungen im Tabellenplatz freigibt, so dass
+der freigegebene Platz anderen Benutzern zur Verfügung steht. Wenn eine
+Tabelle gelöscht wird oder alle Zeilen aus ihr gelöscht werden, gibt das
+garantiert Platz frei für andere Benutzer, aber denken Sie daran, dass
+gelöschte Zeile physikalisch nur durch eine Purge-Operation entfernt werden
+können, nachdem Sie nicht mehr für ein Transaktions-Rollback oder für
+Konsistentes Lesen benötigt werden.
+
+
+@node InnoDB File Defragmenting, , InnoDB File space, File space management
+@c German node Datei-Defragmentierung in InnoDB
+@subsubsection Eine Tabelle defragmentieren
+
+Wenn es wahlfreie (random) Einfüge- oder Löschvorgänge in die Indexe einer
+Tabelle gibt, können die Indexe fragmentiert werden. Unter Fragmentierung
+verstehen wird, dass die physikalische Reihenfolge der Index-Seiten auf der
+Platte der alphabetischen Reihenfolge der Datensätze auf den Seiten nicht
+nahe kommt oder dass es viele unbenutzte Seiten in den 64-Seiten-Blöcken
+gibt, die dem Index zugewiesen wurden.
+
+Index-Scans können beschleunigt werden, wenn Sie von Zeit zu Zeit
+@code{mysqldump} benutzen, um die Tabelle in eine Textdatei zu dumpen, dann
+die Tabelle zu löschen und sie aus dem Dump neu aufzubauen. Eine weitere
+Möglichkeit zur Defragmentierung besteht darin, den Tabellentyp in
+@code{MyISAM} zu ändern (@code{ALTER}) und danach wieder in @code{InnoDB}
+zurück. Beachten Sie, dass die @code{MyISAM}-Tabelle auf Ihrem
+Betriebssystem in eine einzige Datei passen muss.
+
+Wenn die Einfügungen in einen Index immer aufsteigend sind und Datensätze
+nur vom Ende gelöscht werden, garantiert der
+Speicherplatzverwaltungs-Algorithmus von InnoDB, dass keine Fragmentierung
+im Index auftritt.
+
+
+@node Error handling, InnoDB restrictions, File space management, InnoDB
+@c German node Fehlerbehandlung
+@subsection Fehlerbehandlung
+
+Die Fehlerbehandlung in InnoDB ist nicht immer so, wie es die
+ANSI-SQL-Standards festlegen. Nach ANSI-Standard sollte jeder Fehler
+während eines SQL-Statements ein Rollback des Statements verursachen.
+InnoDB rollt manchmal nur Teile des Statements oder auch die gesamte
+Transaktion zurück. Folgende Liste gibt die Fehlerbehandlung von InnoDB an:
+
+@itemize @bullet
+@item
+Wenn es keinen Speicherplatz mehr im Tabellenplatz (Tablespace) gibt,
+bekommen Sie den MySQL-Fehler @code{'Table is full'} und InnoDB rollt das
+SQL-Statement zurück.
+@item
+Eine Transaktions-Blockierung oder eine Zeitüberschreitung beim Warten auf
+eine Sperre führen dazu, dass InnoDB die gesamte Transaktion zurückrollt.
+@item
+Ein Fehler wegen doppelter Schlüsseleinträge rollt das Einfügen dieser
+Zeile zurück, selbst in einem Statement wie @code{INSERT INTO ... SELECT
+...}. Das wird sich voraussichtlich ändern, so dass das SQL-Statement
+zurückgerollt wird, wenn Sie die @code{IGNORE}-Option in Ihrem Statement
+nicht angegeben haben.
+@item
+Ein Fehler 'row too long' rollt das SQL-Statement zurück.
+@item
+Andere Fehler werden zumeist durch die MySQL-Code-Ebene entdeckt und rollen
+das entsprechende SQL-Statement zurück.
+@end itemize
+
+
+@node InnoDB restrictions, InnoDB contact information, Error handling, InnoDB
+@c German node InnoDB-Einschränkungen
+@subsection Beschränkungen von InnoDB-Tabellen
+
+@itemize @bullet
+
+@item
+@strong{ACHTUNG:} Konvertieren Sie @strong{KEINE} MySQL-Systemtabellen von
+MyISAM in InnoDB-Tabellen! Das wird nicht unterstützt. Wenn Sie es dennoch
+tun, startet MySQL nicht mehr, bis Sie die alten Systemtabellen aus einer
+Datensicherung wiederhergestellt haben oder sie mit dem
+mysql_install_db-Skript neu erzeugen.
+
+@item
+@code{SHOW TABLE STATUS} gibt keine genauen Statistiken über
+InnoDB-Tabellen, ausser über die physikalische Größe, die durch die
+Tabelle reserviert wird. Der Zeilenzähler ist nur eine grobe Schätzung, die
+bei der SQL-Optimierung benutzt wird.
+
+@item
+Wenn Sie versuchen, einen eindeutigen Index auf ein Präfix einer Spalte zu
+erzeugen, erhalten Sie einen Fehler:
+
+@example
+CREATE TABLE T (A CHAR(20), B INT, UNIQUE (A(5))) TYPE = InnoDB;
+@end example
+
+Wenn Sie einen nicht eindeutigen Index auf ein Spaltenpräfix erzeugen,
+erzeugt InnoDB einen Index über die gesamte Spalte.
+@item
+@code{INSERT DELAYED} wird für InnoDB-Tabellen nicht unterstützt.
+@item
+Die MySQL-@code{LOCK TABLES}-Operation weiß nichts von InnoDB-Sperren auf
+Zeilenebene, die in bereits fertigen SQL-Statements gesetzt sind. Das
+bedeutet, dass Sie eine Tabellensperre auf eine Tabelle selbst dann
+erhalten können, wenn es noch Transaktionen anderer Benutzer gibt, die
+Sperren auf Zeilenebene auf dieselbe Tabelle haben. Daher kann es sein,
+dass Ihre Operationen auf die Tabelle warten müssen, wenn sie mit diesen
+Sperren anderer Benutzer kollidieren. Auch eine Blockierung ist möglich.
+Dennoch gefährdet das nicht die Transaktionsintegrität, weil sich die
+Sperren auf Zeilenebene, die InnoDB setzt, um die Integrität kümmern.
+Zusätzlich hindert eine Tabellensperren andere Transaktionen daran, weitere
+Sperren auf Zeilenebene (in einem konfliktbehafteten Sperrmodus) auf die
+Tabelle zu erlangen.
+@item
+Sie können keinen Schlüssel auf eine @code{BLOB}- oder @code{TEXT}-Spalte
+setzen.
+@item
+Eine Tabelle kann nicht mehr als 1.000 Spalten enthalten.
+@item
+@code{DELETE FROM TABLE} erzeugt die Tabelle nicht neu, sondern löscht
+statt dessen alle Zeilen, eine nach der anderen, was nicht sehr schnell
+ist. In zukünftigen MySQL-Versionen können Sie @code{TRUNCATE} benutzen,
+was schnell ist.
+@item
+Die vorgabemäßige Datenbank-Seitengröße in InnoDB beträgt 16 KB. Indem
+Sie den Code neu kompilieren, können Sie sie auf Werte zwischen 8 KB und 64
+KB setzen. Die maximale Zeilenlänge beträgt etwas weniger als die Hälfte
+der Datenbank-Seite in den InnoDB-Versionen kleiner oder gleich 3.23.40. Ab
+Quelldistribution 3.23.41 dürfen BLOB- und TEXT-Spalten bis zu 4 GB Groß
+sein, die gesamte Zeilenlänge kann auch < 4 GB betragen. InnoDB speichert
+Felder, deren Größe kleiner oder gleich 128 Bytes beträgt, nicht auf
+separaten Seiten. Nachdem InnoDB die Zeile geändert hat, indem lange Felder
+auf separaten Seiten gespeichert werden, muss die restliche Zeilenlänge
+weniger als die Hälfte einer Datenbank-Seite betragen. Die maximale
+Schlüssellänge beträgt 7.000 Bytes.
+@item
+Auf einigen Betriebssystemen müssen Daten-Dateien kleiner als 2 GB sein.
+Die Gesamtgröße der Log-Dateien muss auf 32-Bit-Computern kleiner als 4 GB
+sein.
+@item
+Die maximale Größe des Tabellenplatzes (Tablespace) beträgt 4 Milliarden
+Datenbank-Seiten. Das ist auch die maximale Größe für eine Tabelle. Die
+minimale Größe des Tabellenplatzes (Tablespace) beträgt 10 MB.
+@end itemize
+
+
+@node InnoDB contact information, , InnoDB restrictions, InnoDB
+@c German node InnoDB-Kontaktinformationen
+@subsection InnoDB-Kontaktinformationen
+
+Kontaktinformationen von Innobase Oy, Hersteller der InnoDB-Engine:
+Website: @uref{http://www.innodb.com/}.
+E-Mail: @email{Heikki.Tuuri@@innodb.com}
+
+@example
+Telefon: 358-9-6969 3250 (Büro) 358-40-5617367 (mobil)
+Innobase Oy Inc.
+World Trade Center Helsinki
+Aleksanterinkatu 17
+P.O.Box 800
+00101 Helsinki
+Finnland
+@end example
+
+
+@node BDB, , InnoDB, Table types
+@c German node BDB
+@section BDB- oder Berkeley_db-Tabellen
+
+@cindex Tabellen, @code{BDB}
+@cindex Tabellen, @code{Berkeley DB}
+
+
+@menu
+* BDB overview::
+* BDB install::
+* BDB start::
+* BDB characteristics::
+* BDB TODO::
+* BDB portability::
+* BDB errors::
+@end menu
+
+@node BDB overview, BDB install, BDB, BDB
+@c German node BDB-Überblick
+@subsection Überblick über BDB-Tabellen
+
+Unterstützung für BDB-Tabellen ist in der MySQL-Quelldistribution seit
+Version 3.23.34 enthalten und in der MySQL-Max-Binärdistribution aktiviert.
+
+BerkeleyDB, erhältlich unter @uref{http://www.sleepycat.com/}, stattet
+MySQL mit einem transaktionalen Tabellen-Handler aus. Wenn Sie
+BerkeleyDB-Tabellen benutzen, haben Ihre Tabellen eine höhere Chance,
+Abstürze zu überleben. Zusätzlich stehen @code{COMMIT} und @code{ROLLBACK}
+für Transaktionen zur Verfügung. Die MySQL-Quelldistribution enthält eine
+BDB-Distribution, die eine Reihe kleiner Patches hat, damit sie glatter mit
+MySQL zusammen arbeitet. Sie können keine nicht gepatchte
+@code{BDB}-Version für MySQL verwenden.
+
+Wir bei MySQL AB arbeiten in enger Kooperation mit Sleepycat, um die hohe
+Qualität der MySQL-/BDB-Schnittstelle zu halten.
+
+Was den Support für BDB-Tabellen angeht, sehen wir uns in der Pflicht,
+unseren Benutzern zu helfen, Probleme zu lokalisieren und Ihnen zu helfen,
+einen reproduzierbaren Testfall für jegliche Probleme mit BDB-Tabellen zu
+erstellen. Solche ein Fall wird an Sleepycat weiter geleitet, die sich dann
+an uns wenden, um uns zu helfen, das Problem zu finden und zu beheben. Weil
+das also in zwei Schritten abläuft, kann es bei jeglichen Problemen mit
+BDB-Tabellen etwas länger dauern, diese zu lösen, als das bei anderen
+Tabellen-Handlern der Fall ist. Weil jedoch der BerkeleyDB-Code selbst auch
+von vielen sonstigen Applikationen benutzt wird, sind hierbei keine großen
+Probleme zu erwarten. @xref{Support}.
+
+
+@node BDB install, BDB start, BDB overview, BDB
+@c German node BDB installieren
+@subsection BDB installieren
+
+Wenn Sie eine Binärdistribution von MySQL herunter geladen haben, die
+Unterstützung für BerkeleyDB enthält, folgen Sie einfach den Anweisungen
+zur Installation einer Binärversion von MySQL. @xref{MySQL binaries}. @xref{mysqld-max, , @code{mysqld-max}}.
+
+Um MySQL mit BerkeleyDB-Unterstützung zu kompilieren, laden Sie
+MySQL-Version 3.23.34 oder neuer herunter und konfigurieren Sie
+@code{MySQL} mit der @code{--with-berkeley-db}-Option.
+@c German FIX unwrapped @xref
+@xref{Installing source}.
+
+@example
+cd /pfad/zur/quelle/von/mysql-3.23.34
+./configure --with-berkeley-db
+@end example
+
+Bitte sehen Sie wegen aktuellerer Informationen im Handbuch nach, das mit
+der @code{BDB}-Distribution mitgeliefert wird.
+
+Obwohl BerkeleyDB selbst sehr gut getestet und zuverlässig ist, wird die
+MySQL-Schnittstelle noch als Beta-Qualität erachtet. Wir verbessern diese
+aktiv und optimieren sie, um sie sehr bald stabil zu bekommen.
+
+
+@node BDB start, BDB characteristics, BDB install, BDB
+@c German node BDB starten
+@subsection BDB-Startoptionen
+
+Wenn Sie mit @code{AUTOCOMMIT=0} fahren, werden Ihre Änderungen in
+@code{BDB}-Tabellen erst aktualisiert, wenn Sie @code{COMMIT} ausführen.
+Statt dessen können Sie @code{ROLLBACK} ausführen, um Ihre Änderungen zu
+verwerfen. @xref{COMMIT}.
+
+Wenn Sie mit @code{AUTOCOMMIT=1} fahren (der Vorgabe), werden Ihre
+Änderungen sofort abgeschickt. Sie können eine ausgedehnte Transaktion mit
+dem SQL-Befehl @code{BEGIN WORK} starten. Danach werden Ihre Änderungen
+solange nicht abgeschickt, bis Sie @code{COMMIT} ausführen (oder sich für
+@code{ROLLBACK} entscheiden, um Ihre Änderungen zu verwerfen).
+
+Folgende Optionen für @code{mysqld} können benutzt werden, um das Verhalten
+von BDB-Tabellen zu ändern:
+
+@multitable @columnfractions .30 .70
+@item @strong{Option} @tab @strong{Beschreibung}
+@item @code{--bdb-home=directory}
+ @tab Base Verzeichnis für BDB-Tabellen. Das sollte dasselbe Verzeichnis sein, das Sie für --datadir benutzen.
+@item @code{--bdb-lock-detect=#}
+ @tab Berkeley-Sperr-Erkennung. # steht für DEFAULT, OLDEST, RANDOM oder YOUNGEST.
+@item @code{--bdb-logdir=Verzeichnis}
+ @tab BerkeleyDB-Log-Datei-Verzeichnis.
+@item @code{--bdb-no-sync}
+ @tab Flush-Logs nicht synchronisieren.
+@item @code{--bdb-no-recover}
+ @tab BerkeleyDB nicht im Wiederherstellungsmodus starten.
+@item @code{--bdb-shared-data}
+ @tab BerkeleyDB im Multi-Prozess-Modus starten (@code{DB_PRIVATE} bei der Initialisierung von BerkeleyDB nicht verwenden).
+@item @code{--bdb-tmpdir=verzeichnis}
+ @tab Name der temporären Datei von BerkeleyDB.
+@item @code{--skip-bdb}
+ @tab BerkeleyDB nicht benutzen.
+@item @code{-O bdb_max_lock=1000}
+ @tab Setzt die höchste Anzahl möglicher Sperren. @xref{SHOW VARIABLES}.
+@end multitable
+
+Wenn Sie @code{--skip-bdb} benutzen, initialisiert MySQL nicht die
+BerkeleyDB-Bibliothek und spart deshalb viel Speicher. Natürlich können Sie
+@code{BDB}-Tabellen nicht benutzen, wenn Sie diese Option verwenden.
+
+Normalerweise sollten Sie @code{mysqld} ohne @code{--bdb-no-recover}
+starten, wenn Sie vorhaben, BDB-Tabellen zu verwenden. Das kann allerdings
+zu Problemen führen, wenn Sie @code{mysqld} starten und die BDB-Log-Dateien
+beschädigt sind. @xref{Starting server}.
+
+Mit @code{bdb_max_lock} können Sie die maximale Anzahl von Sperren
+festlegen (vorgabemäßig 10.000), die auf einer BDB-Tabelle aktiv sein
+können. Sie sollten diesen Wert herauf setzen, wenn Sie Fehler vom Typ
+@code{bdb: Lock table is out of available locks} oder @code{Got error 12
+from ...} erhalten, wenn Sie lange Transaktionen ausführen oder wenn
+@code{mysqld} viele Zeilen untersuchen muss, um die Anfrage zu berechnen.
+
+Sie könnten auch @code{binlog_cache_size} und @code{max_binlog_cache_size}
+ändern, wenn Sie große, vielzeilige Transaktionen benutzen. @xref{COMMIT}.
+
+
+@node BDB characteristics, BDB TODO, BDB start, BDB
+@c German node BDB-Charakteristiken
+@subsection Kennzeichen von @code{BDB}-Tabellen
+
+@itemize @bullet
+@item
+Um Transaktionen zurückrollen zu können, unterhält BDB Log-Dateien. Um
+maximale Performance zu erzielen, sollten Sie diese auf andere Festplatten
+platzieren als Ihre Datenbanken, indem Sie die @code{--bdb_log_dir}-Option
+benutzen.
+@item
+MySQL macht jedes Mal, wenn eine neue BDB-Log-Datei gestartet wird, einen
+Checkpoint und entfernt alle Log-Dateien, die nicht für aktuelle
+Transaktionen benötigt werden. Sie können auch jederzeit @code{FLUSH LOGS}
+laufen lassen, um einen Checkpoint für die BerkeleyDB-Tabellen anzulegen.
+
+Für die Wiederherstellung nach Abstürzen sollten Sie Datensicherungen der
+Tabellen plus das Binär-Log von MySQL benutzen. @xref{Backup}.
+
+@strong{Achtung}: Wenn Sie alte Log-Dateien löschen, die in Benutzung sind,
+ist BDB nicht in der Lage, Wiederherstellungen durchzuführen, und Sie
+könnten Daten verlieren, wenn etwas schief geht.
+@item
+MySQL erfordert einen @code{PRIMARY KEY} in jeder BDB-Tabelle, um auf
+vorher gelesene Zeilen verweisen zu können. Wenn Sie keine Primärschlüssel
+anlegen, erzeugt MySQL einen versteckten @code{PRIMARY KEY}. Der versteckte
+Schlüssel hat eine Länge von 5 Bytes und wird bei jedem Einfügeversuch um 1
+hochgezählt.
+@item
+Wenn alle Spalten, auf die Sie in einer @code{BDB}-Tabelle zugreifen, Teil
+desselben Indexes oder Teil des Primärschlüssels sind, kann MySQL die
+Anfrage ausführen, ohne auf die tatsächliche Zeile zugreifen zu müssen. Bei
+einer @code{MyISAM}-Tabelle gilt das nur, wenn die Spalten Teil desselben
+Indexes sind.
+@item
+Der @code{PRIMARY KEY} ist schneller als jeder andere Schlüssel, weil
+@code{PRIMARY KEY} zusammen mit den Zeilendaten gespeichert wird. Weil die
+anderen Schlüssel als Schlüsseldaten plus @code{PRIMARY KEY} gespeichert
+werden, ist es wichtig, den @code{PRIMARY KEY} so kurz wie möglich zu
+halten, um Plattenplatz zu sparen und bessere Geschwindigkeit zu erzielen.
+@item
+@code{LOCK TABLES} funktioniert bei @code{BDB}-Tabellen wie bei anderen
+Tabellen. Wenn Sie @code{LOCK TABLE} nicht benutzen, führt MySQL einer
+interne mehrfache Schreibsperre auf die Tabelle aus, um sicherzustellen,
+dass die Tabelle korrekt gesperrt ist, wenn ein anderer Thread eine
+Tabellensperre ausführt.
+@item
+Internes Sperren in @code{BDB}-Tabellen wird auf Seitenebene durchgeführt.
+@item
+@code{SELECT COUNT(*) FROM tabelle} ist langsam, weil @code{BDB}-Tabellen
+keinen Zähler für die Anzahl der Zeilen in der Tabelle unterhalten.
+@item
+Scannen ist langsamer als bei @code{MyISAM}-Tabellen, weil Daten in
+BDB-Tabellen in B-Bäumen und nicht in separaten Daten-Dateien gespeichert
+werden.
+@item
+Die Applikation muss stets darauf vorbereitet sein, Fälle zu handhaben, bei
+denen jegliche Änderung einer @code{BDB}-Tabelle zu einem automatischen
+Rollback führen kann und jegliches Lesen fehlschlagen kann, weil ein
+Blockierungsfehler auftritt.
+@item
+Schlüssel werden nicht auf vorherige Schlüssel komprimiert, wie das bei
+ISAM- und MyISAM-Tabellen der Fall ist. Mit anderen Worten benötigt die
+Schlüsselinformation etwas mehr Platz bei @code{BDB}-Tabellen im Vergleich
+zu MyISAM-Tabellen, die nicht @code{PACK_KEYS=0} benutzen.
+@item
+Oft gibt es Löcher in der BDB-Tabelle, damit Sie neue Zeilen in der Mitte
+des Schlüsselbaums einfügen können. Das macht BDB-Tabellen etwas größer
+als MyISAM-Tabellen.
+@item
+Der Optimierer muss näherungsweise die Anzahl von Zeilen in der Tabelle
+kennen. MySQL löst dieses Problem, indem Einfügeoperationen gezählt werden,
+und unterhält diese in einem separaten Segment in jeder BDB-Tabelle. Wenn
+Sie nicht viele @code{DELETE} oder @code{ROLLBACK} ausführen, sollte diese
+Zahl ausreichend genau für den MySQL-Optimierer sein. Weil MySQL die Zahl
+nur beim Schließen speichert, kann sie falsch sein, wenn MySQL unerwartet
+stirbt. Das sollte kein schwerer Fehler sein, selbst wenn die Zahl nicht
+100% korrekt ist. Man kann die Anzahl von Zeilen aktualisieren, indem man
+@code{ANALYZE TABLE} oder @code{OPTIMIZE TABLE} ausführt.
+@c German FIX Unsplit @xref
+@xref{ANALYZE TABLE}. @xref{OPTIMIZE TABLE}.
+@item
+Wenn die Platte bei einer @code{BDB}-Tabelle voll wird, erhalten Sie einen
+Fehler (wahrscheinlich Fehler 28) und die Transaktion sollte zurückgerollt
+werden. Das steht im Gegensatz zu @code{MyISAM}- and @code{ISAM}-Tabellen,
+bei denen @code{mysqld} wartet, bis genug Plattenplatz frei ist, bevor
+weiter gemacht wird.
+@end itemize
+
+
+@node BDB TODO, BDB portability, BDB characteristics, BDB
+@c German node BDB-TODO-Liste
+@subsection Was in naher Zukunft bei BDB in Ordnung gebracht werden muss
+
+@itemize @bullet
+@item
+Viele BDB-Tabellen zur gleichen Zeit öffnen ist sehr langsam. Wenn Sie
+BDB-Tabellen benutzen wollen, sollten Sie einen sehr großen Tabellen-Cache
+haben (evtl. größer als 256) und beim @code{mysql}-Client
+@code{--no-auto-rehash} benutzen. Das soll partiell in Version 4.0 behoben
+werden.
+@item
+@code{SHOW TABLE STATUS} gibt momentan noch nicht viele Informationen über
+BDB-Tabellen aus.
+@item
+Performance optimieren.
+@item
+Es sollten überhaupt keine Seitensperren mehr benutzt werden, wenn Tabellen
+gescannt werden.
+@end itemize
+
+
+@node BDB portability, BDB errors, BDB TODO, BDB
+@c German node BDB-Portabilität
+@subsection Betriebssysteme, die von @strong{BDB} unterstützt werden
+
+Wenn Sie MySQL mit Unterstützung für BDB-Tabellen gebaut haben und
+folgenden Fehler in der Log-Datei sehen, wenn Sie @code{mysqld} starten:
+
+@example
+bdb: architecture lacks fast mutexes: applications cannot be threaded
+Can't init databases
+@end example
+
+Bedeutet das, dass @code{BDB}-Tabellen für Ihre Architektur nicht
+unterstützt werden. In diesem Fall müssen Sie MySQL erneut bauen, ohne
+Unterstützung für BDB-Tabellen.
+
+HINWEIS: Folgende Liste ist nicht komplett. Sie wird aktualisiert, sobald
+wir mehr Informationen darüber haben.
+
+Momentan wissen wir, dass BDB-Tabellen auf folgenden Betriebssystemen
+laufen:
+
+@itemize @bullet
+@item
+Linux 2.x intel
+@item
+Solaris sparc
+@item
+Caldera (SCO) OpenServer
+@item
+Caldera (SCO) UnixWare 7.0.1
+@end itemize
+
+Auf folgenden Betriebssystemen läuft BDB nicht:
+
+@itemize @bullet
+@item
+Linux 2.x Alpha
+@item
+Mac OS X
+@end itemize
+
+
+@node BDB errors, , BDB portability, BDB
+@c German node BDB-Fehler
+@subsection Fehler, die bei der Benutzung von BDB-Tabellen auftreten können
+
+@itemize @bullet
+@item
+Wenn Sie folgenden Fehler in der @code{hostname.err}-Log-Datei beim Start
+von @code{mysqld} erhalten:
+
+@example
+bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version #
+@end example
+Bedeutet das, dass die neue @code{BDB}-Version das alte Log-Dateiformat
+nicht unterstützt. In diesem Fall müssen Sie alle @code{BDB}-Log-Dateien
+aus Ihrem Datenbankverzeichnis löschen (die Dateien haben das Format
+@code{log.XXXXXXXXXX}) und @code{mysqld} neu starten. Wir empfehlen
+ausserdem, dass Sie @code{mysqldump --opt} auf Ihre alten
+@code{BDB}-Tabellen ausführen, die alten Tabellen löschen und aus dem Dump
+wiederherstellen.
+@item
+Wenn Sie im @code{auto_commit}-Modus fahren und eine Tabelle löschen, die
+durch einen anderen Thread benutzt wird, erhalten Sie womöglich folgende
+Fehlermeldungen in der MySQL-Fehlerdatei:
+
+@example
+001119 23:43:56 bdb: Missing log fileid entry
+001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: Invalid
+@end example
+
+Das ist kein schwerer Fehler, aber wir empfehlen, alle Tabellen zu löschen,
+wenn Sie nicht im @code{auto_commit}-Modus sind, bis dieses Problem behoben
+ist (die Behebung ist nicht trivial).
+@end itemize
+
+
+@node Clients, Extending MySQL, Table types, Top
+@c German node MySQL-APIs
+@chapter MySQL-APIs
+
+@cindex Client-Werkzeuge
+@cindex APIs
+@cindex @code{mysqlclient}-Bibliothek
+@cindex Puffergrößen, Client
+@cindex Bibliothek, @code{mysqlclient}
+
+
+Dieses Kapitel beschreibt die APIs, die für MySQL bereitstehen, wo man sie
+bekommt und wie man sie benutzt. Die C-API ist am ausführlichsten beschrieben,
+da sie vom MySQL-Team stammt und als Basis für die meisten anderen APIs
+dient.
+
+
+@menu
+* PHP::
+* Perl::
+* ODBC::
+* C::
+* Cplusplus::
+* Java::
+* Python::
+* Tcl::
+* Eiffel::
+@end menu
+
+@node PHP, Perl, Clients, Clients
+@c German node PHP
+@section MySQL-PHP-API
+
+@cindex PHP-API
+
+PHP ist eine serverseitige Skriptsprache, die in HTML eingebettet werden
+kann und mit der man dynamische Webseiten erstellen kann. PHP unterstützt
+eine Vielzahl von Datenbanken. Darunter befindet sich auch MySQL. PHP kann
+als alleinstehendes Programm oder als Teil des Apache Webservers eingesetzt
+werden.
+
+
+Die Distribution und die Dokumentation gibt es unter
+@uref{http://www.php.net/, PHP-Website}.
+
+
+@menu
+* PHP problems::
+@end menu
+
+@node PHP problems, , PHP, PHP
+@c German node PHP-Probleme
+@subsection Allgemeine Probleme mit MySQL und PHP
+
+@itemize @bullet
+@item Error: "Maximum Execution Time Exceeded"
+Dies ist eine PHP-Beschränkung. Ändern sie den Wert für die maximale
+Ausführungszeit in der @file{php3.ini}-Datei. Es ist ausserdem keine
+schlechte Idee, die Beschränkung für die maximale Benutzung von RAM von 8
+MB auf 16 MB per Skript zu verdoppeln.
+
+
+@item Error: "Fatal error: Call to unsupported oder undefined function mysql_connect() in .."
+Das bedeutet, dass Ihre PHP-Version nicht mit MySQL-Unterstützung
+ausgestattet ist. Sie können entweder ein dynamisches MySQL-Modul für PHP
+kompilieren oder PHP mit seiner eingebautet MySQL-Unterstützung neu
+kompilieren. Im PHP-Manual ist dies ausführlich beschrieben.
+
+@item Error: "undefined reference to `uncompress'"
+Die Client-Bibliothek wurde mit der Unterstützung für ein komprimiertes
+Client-/Server-Protokoll kompiliert. Um den Fehler zu beheben, müssen Sie
+@code{-lz} als letztes angeben, wenn Sie gegen @code{-lmysqlclient}
+linken.
+@end itemize
+
+
+@node Perl, ODBC, PHP, Clients
+@c German node Perl
+@section MySQL-Perl-API
+
+@cindex APIs, Perl
+@cindex Perl-API
+
+Dieser Abschnitt dokumentiert die Perl-@code{DBI}-Schnittstelle. Die
+frühere Schnittstelle hieß @code{mysqlperl}. @code{DBI}/@code{DBD} ist
+jetzt die empfohlene Perl-Schnittstelle. @code{mysqlperl} ist überflüßig
+und deshalb hier nicht näher beschrieben.
+
+
+
+@menu
+* DBI with DBD::
+* Perl DBI Class::
+* DBI-info::
+@end menu
+
+@node DBI with DBD, Perl DBI Class, Perl, Perl
+@c German node DBI mit DBD
+@subsection @code{DBI} mit @code{DBD::mysql}
+
+@cindex @code{DBI}-Schnittstelle
+
+@code{DBI} ist eine allgemeine Schnittstelle für viele Datenbanken. Das
+bedeutet, Sie können ein Skript schreiben, dass viele verschiedene
+Datenbanken unterstützt, ohne es zu ändern. Sie brauchen für jeden
+Datenbanktyp einen Datenbank-Treiber (DBD). Für MySQL heißt dieser Treiber
+@code{DBD::mysql}. Für weitere Informationen über Perl5 DBI besuchen Sie
+bitte die @code{DBI}-Website und lesen Sie die Dokumentation:
+
+@example
+@uref{http://www.symbolstone.org/technology/perl/DBI/index.html}
+@end example
+Für weitere Informationen über objektorientierte Programmierung (OOP) in
+Perl5 besuchen Sie die OOP-Seite:
+@example
+@uref{http://language.perl.com/info/documentation.html}
+@end example
+
+Beachten Sie, dass Sie, wenn Sie Transaktionen mit Perl einsetzen wollen,
+@code{Msql-Mysql-modules} der Version 1.2216 oder neuer benötigen.
+
+Installationsanweisungen für MySQL-Perl-Unterstützung finden Sie unter
+@ref{Perl}.
+
+
+@node Perl DBI Class, DBI-info, DBI with DBD, Perl
+@c German node Perl-DBI-Klasse
+@subsection Die @code{DBI}-Schnittstelle
+
+@cindex @code{DBI}-Perl-Modul
+
+@noindent
+@strong{Portable DBI-Methoden}
+
+@multitable @columnfractions .3 .7
+@item @code{connect} @tab Errichtet eine Verbindung zum Datenbankserver.
+@item @code{disconnect} @tab Trennt eine Verbindung zum Datenbankserver.
+@item @code{prepare} @tab Bereitet ein SQL-Statement zur Abfrage vor.
+@item @code{execute} @tab Führt eine vorbereitetes Statement aus.
+@item @code{do} @tab Bereitet ein SQL-Statement vor und führt es aus.
+@item @code{quote} @tab Quotet eine Zeichenkette oder einen @code{BLOB}-Wert zum Einfügen.
+@item @code{fetchrow_array} @tab Holt die nächste Zeile als einen Array aus Feldern.
+@item @code{fetchrow_arrayref} @tab Holt die nächste Zeile als eine Referenz eines Arrays aus Feldern.
+@item @code{fetchrow_hashref} @tab Holt die nächste Zeile als eine Referenz einer Hash-Tabelle.
+@item @code{fetchall_arrayref} @tab Holt alle Zeilen als einen Array von Arrays.
+@item @code{finish} @tab Beendet ein Statement und läßt das System Resourcen freigeben.
+@item @code{rows} @tab Gibt die Anzahl der betroffenen Zeilen zurück.
+@item @code{data_sources} @tab Gibt einen Array mit den verfügbaren Daten auf localhost zurück.
+@item @code{ChopBlanks} @tab Kontroliert, ob die @code{fetchrow_*}-Methoden Leerzeichen entfernen.
+@item @code{NUM_OF_PARAMS} @tab Die Anzahl der Platzhalter in einem vorbereiteten Statement.
+@item @code{NULLABLE} @tab Welche Spalten @code{NULL} sein können.
+@item @code{trace} @tab Tracen zum Debuggen ausführen.
+@end multitable
+
+@noindent
+@strong{MySQL-spezifische Methoden}
+
+@multitable @columnfractions .3 .7
+@item @code{insertid} @tab Der letzte @code{AUTO_INCREMENT}-Wert.
+@item @code{is_blob} @tab Welche Spalten @code{BLOB}-Werte sind.
+@item @code{is_key} @tab Welche Spalten Schlüssel sind.
+@item @code{is_num} @tab Welche Spalten numerisch sind.
+@item @code{is_pri_key} @tab Welche Spalten Primärschlüssel sind.
+@item @code{is_not_null} @tab Welche Spalten NICHT @code{NULL} sein können. Siehe auch @code{NULLABLE}.
+@item @code{length} @tab Maximal mögliche Spaltengröße.
+@item @code{max_length} @tab Maximale Spaltengröße, die im aktuellen Ergebnis enthalten ist.
+@item @code{NAME} @tab Spaltennamen.
+@item @code{NUM_OF_FIELDS} @tab Anzahl der zurückgegebenen Felder.
+@item @code{table} @tab Tabellennamen im zurückgegebenen Ergebnis.
+@item @code{type} @tab Alle Spaltentypen.
+@end multitable
+
+Die Perl-Methoden werden im Folgenden detaillierter erläutert. Die
+Variablen für die zurückgegebenen Werte haben folgende Bedeutung:
+
+@table @code
+@item $dbh
+Datenbank-Handle
+
+@item $sth
+Statement-Handle
+
+@item $rc
+Rückgabe-Code (oft ein Status)
+
+@item $rv
+Rückgabewert (oft ein Status)
+@end table
+
+@noindent
+@strong{Portable DBI-Methoden}
+
+@table @code
+
+@findex DBI->connect()
+@findex connect()-DBI-Methode
+@item connect($datenquelle, $benutzername, $passwort)
+Benutzen Sie die @code{connect}-Methode, um eine Verbindung zur Datenbank
+der Datenquelle herzustellen. Der @code{$datenquelle}-Wert sollte mit
+@code{DBI:Treiber_name:} beginnen. Beispielanwendungen von @code{connect}
+mit dem @code{DBD::mysql} Treiber:
+@example
+$dbh = DBI->connect("DBI:mysql:$datenbank", $benutzer, $passwort);
+$dbh = DBI->connect("DBI:mysql:$datenbank:$hostname",
+ $benutzer, $passwort);
+$dbh = DBI->connect("DBI:mysql:$datenbank:$hostname:$port",
+ $benutzer, $passwort);
+@end example
+Wenn der Benutzername und / oder das Passwort nicht angegeben werden,
+verwendet @code{DBI} die Werte der @code{DBI_USER}- und @code{DBI_PASS}-
+Umgebungsvariablen. Wen Sie keinen Hostnamen angeben, wird @code{'localhost'}
+verwendet. Wenn Sie keine Portnummer angeben, wird der MySQL-Port
+(@value{default_port}) verwendet.
+
+Seit @code{Msql-Mysql-modules}-Version 1.2009 erlaubt der
+@code{$datenquelle}-Wert bestimmte Modifikatoren:
+
+@table @code
+@item mysql_read_default_file=datei
+Liest @file{datei} als eine Optionsdatei. Für weitere Informationen zu
+Optionsdateien beachten Sie bitte @ref{Option files}.
+
+@item mysql_read_default_group=group_name
+Beim Lesen einer Optionsdatei ist die Standardgruppe normalerweise die
+@code{[client]}-Gruppe. Wenn Sie die @code{mysql_read_default_group}-
+Option angeben, wird die Standardgruppe @code{[gruppenname]}.
+
+@item mysql_compression=1
+Aktiviert die Kompression während der Kommunikation zwischen Client und
+Server (ab Version 3.22.3).
+
+@item mysql_socket=/pfad/zur/socket
+Gibt den Pfad des Unix-Sockets an, der zum Verbinden mit dem
+Server verwendet wird (MySQL-Version 3.21.15 oder neuer).
+@end table
+
+Sie können mehrere Modifikatoren angeben, dabei muss jedem ein Semikolon
+vorangestellt sein.
+
+Wenn Sie zum Beispiel vermeiden wollen, dass sie Benutzername und Passwort
+im @code{DBI}-Skript angeben müssen, können Sie sie aus der
+@file{~/.my.cnf}-Optionsdatei nehmen. Ihr @code{connect}-Aufruf sieht
+folgendermaßen aus:
+
+@example
+$dbh = DBI->connect("DBI:mysql:$datenbank"
+ . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf",
+ $benutzer, $passwort);
+@end example
+
+Dieser Aufruf liest die Optionen für die @code{[client]}-Gruppe aus der
+Optionsdatei. Wenn Sie dasselbe für die @code{[perl]}-Gruppe tun wollen,
+könnte Ihr Code so aussehen:
+
+@example
+$dbh = DBI->connect("DBI:mysql:$Datenbank"
+ . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf"
+ . ";mysql_read_default_group=perl",
+ $benutzer, $passwort);
+@end example
+
+@findex DBI->disconnect
+@findex disconnect-DBI-Methode
+@item disconnect
+Die @code{disconnect}-Methode beendet die Verbindung mit der Datenbank.
+Dies wird typischerweise kurz vor dem Ende eines Scripts ausgeführt.
+Beispiel:
+@example
+$rc = $dbh->disconnect;
+@end example
+
+@findex DBI->prepare()
+@findex prepare()-DBI-Methode
+@item prepare($statement)
+Bereitet ein SQL-Statement zum Ausführen durch den Datenbankserver vor und
+gibt ein "Statement-Handle" @code{($sth)} zurück, mit der Sie die
+@code{execute}-Methode aufrufen.
+Normalerweise werden Sie @code{SELECT}-Statements (und
+@code{SELECT}-ähnliche Statements so wie @code{SHOW}, @code{DESCRIBE} und
+@code{EXPLAIN}) mit der Bedeutung von @code{prepare} und @code{execute}
+verwenden.
+Beispiel:
+@example
+$sth = $dbh->prepare($statement)
+ or die "$statement: $dbh->errstr kann nicht vorbereitet werden\n";
+@end example
+
+@findex DBI->execute
+@findex execute-DBI-Methode
+@item execute
+Die @code{execute}-Methode führt ein vorbereitetes Statement aus. Bei
+Nicht-@code{SELECT}-Statements gibt @code{execute} die Anzahl der
+betroffenen Zeilen zurück. Wenn Zeilen betroffen sind, gibt @code{execute}
+@code{"0E0"} zurück, was in Perl als 0 und true erkannt wird. Wenn ein
+Fehler auftritt, gibt @code{execute} @code{undef} zurück. Bei
+@code{SELECT}-Statements beginnt @code{execute} die SQL-Anfrage in der
+Datenbank; Sie müssen eine der @code{fetch_*}-Methoden nutzen, die weiter
+unten beschrieben sind, um Daten erhalten. Beispiel:
+@example
+$rv = $sth->execute
+ or die "Die Query: $sth->errstr kann nicht ausgeführt werden.";
+@end example
+
+@findex DBI->do()
+@findex do()-DBI-Methode
+@item do($statement)
+Die @code{do}-Methode bereitet ein Statement vor, führt es aus und gibt die
+Anzahl der betroffenen Zeilen zurück. Wenn Zeilen betroffen sind, gibt
+@code{execute} @code{"0E0"} zurück, was in Perl als 0 und true erkannt
+wird. Diese Methode wird normalerweise verwendet, um
+Nicht-@code{SELECT}-Statements zu bearbeiten, die (z. B. wegen
+Treiber-Beschränkungen) nicht vorbereitet werden können, oder die nicht
+mehr als einmal vorbereitet werden müssen (INSERTS, DELETE usw.). Beispiel:
+@example
+$rv = $dbh->do($statement)
+ or die "$statement: $dbh- >errstr kann nicht vorbereitet werden\n";
+@end example
+
+Im Allgemeinen ist die @code{do}-Methode VIEL schneller (und vorzuziehen)
+als die @code{prepare}/@code{execute}-Methoden, die ohne Parameter
+aufgerufen werden.
+
+@findex DBI->quote()
+@findex quote()-DBI-Methode
+@cindex Zeichenketten quoten
+@cindex Zeichenketten, quoten
+@item quote($string)
+Die @code{quote}-Methode wird verwendet, um Sonderzeichen zu "escapen", die
+in Zeichenketten enthalten sein können, und um notwendige äußere
+Anführungszeichen hinzuzufügen. Beispiel:
+@example
+$sql = $dbh->quote($string)
+@end example
+
+@findex DBI->fetchrow_array
+@findex fetchrow_array-DBI-Methode
+@item fetchrow_array
+Die Methode holt die nächste Datenzeile und gibt sie als ein Array mit den
+Feldwerten zurück. Beispiel:
+@example
+while(@@row = $sth->fetchrow_array) @{
+ print qw($row[0]\t$row[1]\t$row[2]\n);
+@}
+@end example
+
+@findex DBI->fetchrow_arrayref
+@findex fetchrow_arrayref-DBI-Methode
+@item fetchrow_arrayref
+Die Methode holt die nächste Datenzeile und gibt sie als eine Referenz auf
+ein Array mit den Feldwerten zurück. Beispiel:
+@example
+while($row_ref = $sth->fetchrow_arrayref) @{
+ print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n);
+@}
+@end example
+
+@findex DBI->fetchrow_hashref
+@findex fetchrow_hashref-DBI-Methode
+@item fetchrow_hashref
+Diese Methode holt eine Datenzeile und gibt eine Referenz auf einen Hash
+zurück, der Name-/Wert-Paare enthält. Die Methode ist lange nicht so
+performant wie das Verwenden von Referenzen auf ein Array, wie weiter oben
+beschrieben ist. Beispiel:
+@example
+while($hash_ref = $sth->fetchrow_hashref) @{
+ print qw($hash_ref->@{vorname@}\t$hash_ref->@{nachname@}\t\
+ $hash_ref- > title@}\n);
+@}
+@end example
+
+@findex DBI->fetchall_arrayref
+@findex fetchall_arrayref-DBI-Methode
+@item fetchall_arrayref
+Diese Methode gibt alle Zeilen eines Ergebnisses einer SQL-Anfrage zurück.
+Sie gibt eine Referenz auf ein Array mit Referenzen auf Arrays mit den
+Werten der einzelnen Zeilen zurück. Sie können mit zwei verschachtelten
+Schleifen auf die Werte zugreifen. Beispiel:
+@example
+my $table = $sth->fetchall_arrayref
+ or die "$sth->errstr\n";
+my($i, $j);
+for $i ( 0 .. $#@{$table@} ) @{
+ für $j ( 0 .. $#@{$table->[$i]@} ) @{
+ print "$table->[$i][$j]\t";
+ @}
+ print "\n";
+@}
+@end example
+
+@findex DBI->finish
+@findex finish-DBI-Methode
+@item finish
+Bewirkt, dass keine weiteren Daten von dem SQL-Anfrageergebnis geholt
+werden. Sie können diese Methode aufrufen, um Systemressourcen freizugeben.
+Beispiel:
+@example
+s$rc = $sth->finish;
+@end example
+
+@findex DBI->rows
+@findex rows-DBI-Methode
+@item rows
+Gibt die Anzahl der veränderten Zeilen (die aktualisiert oder gelöscht
+wurden) des letzten Befehls zurück. Dies wird normalerweise nach
+Nicht-@code{SELECT}-@code{execute}-Statements verwendet. Beispiel:
+@example
+$rv = $sth->rows;
+@end example
+
+@findex DBI->@{NULLABLE@}
+@findex NULLABLE-DBI-Methode
+@item NULLABLE
+Gibt eine Referenz auf ein Array mit Boole'schen Werten zurück; für jedes
+Element TRUE kann die Spalte @code{NULL}-Werte enthalten. Beispiel:
+@example
+$null_possible = $sth->@{NULLABLE@};
+@end example
+
+@findex DBI->@{NUM_OF_FIELDS@}
+@findex NUM_OF_FIELDS-DBI-Methode
+@item NUM_OF_FIELDS
+Dieses Attribut enthält die Anzahl der Zeilen, die eine @code{SELECT}- oder
+@code{SHOW FIELDS}-SQL-Anfrage zurückgibt. Sie können es verwenden, um zu
+prüfen, ob eine Anfrage ein Ergebnis zurückgegeben hat: 0 weist auf eine
+Nicht-@code{SELECT}-Anfrage hin, wie @code{INSERT}, @code{DELETE} oder
+@code{UPDATE}. Beispiel:
+@example
+$nr_of_fields = $sth->@{NUM_OF_FIELDS@};
+@end example
+
+@findex DBI->datasource()
+@findex datasource()-DBI-Methode
+@item datasource($Treiber_name)
+Diese Methode gibt einen Array zurück, der die Namen der verfügbaren
+Datenbanken auf @code{'localhost'} enthält. Beispiel:
+@example
+@@dbs = DBI->datasource("mysql");
+@end example
+
+@findex DBI->@{ChopBlanks@}
+@findex ChopBlanks-DBI-Methode
+@item ChopBlanks
+Dieses Attribut gibt an, ob die @code{fetchrow_*}-Methoden vor- und
+nachstehende Leerzeichen entfernen. Beispiel:
+@example
+$sth->@{'ChopBlanks'@} =1;
+@end example
+
+@findex DBI->trace
+@findex trace-DBI-Methode
+@item trace($trace_ebene)
+@itemx trace($trace_ebene, $trace_dateiname)
+@code{trace} aktiviert oder deaktiviert "Tracing".
+Wenn @code{DBI} als eine Klassenmethode aufgerufen wird, steuert es das
+"Tracing" mit allen Datenbankverbindungen. Wenn es als Datenbank- oder
+Statement-Handle-Methode aufgerufen wird, steuert es nur die verwendete
+Verbindung (und deren spätere Ableitungen). Wenn Sie @code{$trace_ebene}
+auf 2 setzen, bewirkt es detaillierte Informationen. Der Wert 0 stellt
+"Tracing" ab. Die Ausgabe des "Tracing" wird vorgabemäßig nach "standard
+error" geleitet. Wenn @code{$trace_dateiname} angegeben ist, wird die
+Ausgabe für @emph{alle} "getraceten" Verbindungen an das Ende dieser Datei
+geschrieben. Beispiel:
+@example
+DBI->trace(2); # alles tracen
+DBI->trace(2,"/tmp/dbi.out"); # alles nach /tmp/dbi.out tracen
+$dth->trace(2); # diese Datenbankverbindung tracen
+$sth->trace(2); # dieses Statement-Handle tracen.
+@end example
+
+@tindex @code{DBI_TRACE}-Umgebungsvariable
+@tindex Umgebungsvariable, @code{DBI_TRACE}
+Sie können @code{DBI}-Tracing auch anschalten, indem Sie die
+@code{DBI_TRACE}-Umgebungsvariable setzen. Wenn Sie sie auf einen
+numerischen Wert setzen, ist das dasselbe, wie @code{DBI->(wert)}
+aufzurufen. Wenn Sie sie auf einen Pfadnamen setzen, ist das dasselbe, wie
+@code{DBI->(2,wert)} aufzurufen.
+
+@end table
+
+@noindent
+@strong{MySQL-spezifische Methoden}
+
+Die unten stehenden Methoden sind MySQL-spezifisch und nicht Teil des
+@code{DBI}-Standards. Mehrere von ihnen sind veraltet:
+@code{is_blob}, @code{is_key}, @code{is_num}, @code{is_pri_key},
+@code{is_not_null}, @code{length}, @code{max_length} und @code{table}.
+Wo immer es @code{DBI}-Standard-Alternativen gibt, ist das unten angemerkt:
+
+@table @code
+@findex DBI->@{insertid@}
+@findex insertid-DBI-Methode
+@tindex AUTO_INCREMENT, Benutzung bei DBI
+@item insertid
+Wenn Sie das @code{AUTO_INCREMENT}-Feature von MySQL benutzen, werden neue,
+automatisch heraufgezählte Werte hier gespeichert. Beispiel:
+@example
+$new_id = $sth->@{insertid@};
+@end example
+
+Alternativ können Sie @code{$dbh->@{'mysql_insertid'@}} verwenden.
+
+@findex DBI->@{is_blob@}
+@findex is_blob-DBI-Methode
+@item is_blob
+Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
+Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
+ein @code{BLOB} ist. Beispiel:
+@example
+$keys = $sth->@{is_blob@};
+@end example
+
+@findex DBI->@{is_key@}
+@findex is_key-DBI-Methode
+@item is_key
+Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
+Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
+ein Schlüssel ist. Beispiel:
+@example
+$keys = $sth->@{is_key@};
+@end example
+
+@findex DBI->@{is_num@}
+@findex is_num DBI-Methode
+@item is_num
+Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
+Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
+numerische Werte enthält. Beispiel:
+@example
+$nums = $sth->@{is_num@};
+@end example
+
+@findex DBI->@{is_pri_key@}
+@findex is_pri_key DBI-Methode
+@item is_pri_key
+Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
+Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
+ein Primärschlüssel ist. Beispiel:
+@example
+$pri_keys = $sth->@{is_pri_key@};
+@end example
+
+@findex DBI->@{is_not_null@}
+@findex is_not_null DBI-Methode
+@item is_not_null
+Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
+Element des Arrays bedeutet der Wert FALSE, dass die entsprechende Spalte
+NULL enthalten kann. Beispiel:
+@example
+$not_nulls = $sth->@{is_not_null@};
+@end example
+
+Das oben beschriebene @code{NULLABLE}-Attribut ist @code{is_not_null} in
+jedem Fall vorzuziehen, da es zum DBI-Standard gehört.
+
+@findex DBI->@{length@}
+@findex length-DBI-Methode
+@findex DBI->@{max_length@}
+@findex max_length-DBI-Methode
+@item length
+@itemx max_length
+Beide Methoden geben je einen Array mit Spaltenlängen zurück. Der
+@code{length}-Array gibt die maximal mögliche Länge jeder Spalte an (wie es
+in der Tabellendefinition festgelegt wurde). Der @code{max_length}-Array
+gibt die Länge des aktuell längsten Wertes in den Spalten an. Beispiel:
+@example
+$lengths = $sth->@{length@};
+$max_lengths = $sth->@{max_length@};
+@end example
+
+@findex DBI->@{NAME@}
+@findex NAME-DBI-Methode
+@item NAME
+Gibt eine Referenz auf ein Array mit den Spaltennamen zurück. Beispiel:
+@example
+$names = $sth->@{NAME@};
+@end example
+
+@findex DBI->@{table@}
+@findex table-DBI-Methode
+@item table
+Gibt eine Referenz auf ein Array mit den Tabellennamen zurück. Beispiel:
+@example
+$tables = $sth->@{table@};
+@end example
+
+@findex DBI->@{type@}
+@findex type-DBI-Methode
+@item type
+Gibt eine Referenz auf ein Array mit den Spaltentypen zurück. Beispiel:
+@example
+$types = $sth->@{type@};
+@end example
+
+@end table
+
+
+@node DBI-info, , Perl DBI Class, Perl
+@c German node DBI-Informationen
+@subsection Weitere @code{DBI}/@code{DBD}-Informationen
+
+@cindex @code{DBI/DBD}
+
+Bitte verwenden Sie den @code{perldoc}-Befehl, um weitere Informationen
+über @code{DBI} zu erhalten.
+
+@example
+perldoc DBI
+perldoc DBI::FAQ
+perldoc DBD::mysql
+@end example
+
+Sie können ausserdem @code{pod2man}, @code{pod2html} usw. verwenden, um in
+andere Formate zu wandeln.
+
+Die neuesten @code{DBI}-Informationen finden Sie auf der @code{DBI} Website:
+@example
+@uref{http://www.symbolstone.org/technology/perl/DBI/index.html}
+@end example
+
+
+@node ODBC, C, Perl, Clients
+@c German node ODBC
+@section MySQL-ODBC-Unterstützung
+
+@cindex ODBC
+@cindex Windows
+@cindex MyODBC
+
+
+
+MySQL unterstützt ODBC mit Hilfe des @strong{MyODBC}-Programms. Dieses
+Kapitel erläutert, wie Sie @strong{MyODBC} installieren und benutzen. Hier
+werden Sie außerdem eine Liste von Programmen finden, die mit
+@strong{MyODBC} zusammenarbeiten.
+
+@menu
+* Installing MyODBC::
+* ODBC administrator::
+* MyODBC connect parameters::
+* ODBC Problems::
+* MyODBC clients::
+* ODBC and last_insert_id::
+* MyODBC bug report::
+@end menu
+
+@node Installing MyODBC, ODBC administrator, ODBC, ODBC
+@c German node MyODBC-Installation
+@subsection Wie Sie MyODBC installieren
+
+@strong{MyODBC} ist ein 32-Bit-ODBC- (2.50) -Level-0- (mit Level-1- und
+Level-2-Features) Treiber für die Anbindung an ODBC-fähige Applikationen an
+MySQL. @strong{MyODBC} funktioniert unter Windows95, Windows98, NT, und
+auf den meisten Unix-Plattformen.
+
+@strong{MyODBC} ist "public domain". Sie finden die neueste Version bei
+@uref{http://www.mysql.com/downloads/api-myodbc.html}.
+
+Wenn Sie ein Problem mit @strong{MyODBC} haben und Ihr Programm auch
+mit OLEDB arbeitet, sollten sie den OLEDB Treiber probieren, den sie im
+"Contrib"-Abschnitt finden. @xref{Contrib}.
+
+Normalerweise müssen Sie @strong{MyODBC} nur auf Windows-Maschinen
+installieren. Sie brauchen @strong{MyODBC} für Unix nur, wenn sie ein
+Programm wie ColdFusion haben, das auf einer Unix-Maschine läuft und ODBC
+für die Datenbankverbindung nutzt.
+
+Wenn Sie @strong{MyODBC} unter Unix installieren wollen, brauchen Sie noch
+einen @strong{ODBC}-Manager. @strong{MyODBC} arbeitet mit den meisten
+Unix-ODBC-Managern zusammen.
+@c German FIX node doesn't exist, should probably be to Portals?
+@c Eine Liste finden Sie in dem @strong{ODBC}-verwandten Linkabschnitt
+@c auf der MySQL-Seite @xref{Nützliche Links}.
+
+Um @strong{MyODBC} unter Windows zu installieren, sollten sie die passende
+@strong{MyODBC} Zip-Datei (für Windows 95/98 oder NT / Windows 2000)
+herunterladen, es mit @code{WINZIP} oder einem ähnlichen Programm
+entpacken, und die @code{SETUP.EXE}-Datei ausführen.
+
+Unter Windows NT kann folgender Fehler während der Installation auftreten
+(@strong{MyODBC}):
+
+@example
+Während des Kopiervorgangs ist ein Fehler aufgetreten:
+C:\WINDOWS\SYSTEM\MFC30.DLL. Starten Sie Windows neu und beginnen die
+Installation erneut, noch bevor sie ein anderes Programm starten, das ODBC
+verwendet.
+@end example
+
+Das Problem in diesem Fall ist, dass ein anderes Programm ODBC verwendet
+und dass unter Windows zwei Programme nicht gleichzeitig auf eine Datei
+zugreifen können. Deshalb kann es sein, dass Sie nicht in der Lage sind,
+die ODBC-Treiber mit Microsofts ODBC Setup Programm zu installieren. In den
+meisten Fällen genügt es, den @code{Ignorieren}-Knopf zu drücken, um die
+restlichen Dateien zu installieren und die Installation abzuschließen. Wenn
+das nicht funktioniert, booten Sie Ihren Rechner im Abgesicherten Modus,
+indem sie F8 vor dem Starten von Windows drücken und den Abgesicherten
+Modus auswählen. Installieren sie @strong{MyODBC}, und starten Sie wieder
+im normalen Modus.
+
+@itemize @bullet
+@item
+Um eine Verbindung mit einer ODBC-Applikation, die MySQL nicht nativ
+unterstützt, von Windows zu Unix herzustellen, müssen Sie zunächst
+@strong{MyODBC} unter Windows installieren.
+@item
+Der Windows-Benutzer muss Zugriffsrechte auf den MySQL-Server der
+Unix-Maschine besitzen. Diese richten Sie mit dem @code{GRANT}-Befehl ein.
+@xref{GRANT,,@code{GRANT}}.
+@item
+Sie müssen wie folgt einen ODBC-DSN-Eintrag erstellen:
+
+@itemize @minus
+@item
+Öffnen Sie die Systemsteuerung der Windows-Maschine.
+@item
+Doppelklicken Sie das ODBC-Datenquellen-Symbol.
+@item
+Klicken Sie auf die Registerkarte Benutzer-DSN.
+@item
+Klicken Sie auf Hinzufügen.
+@item
+Wählen Sie MySQL im Fenster "Neue Datenquelle hinzufügen" und klicken Sie
+auf den Fertig-Knopf.
+@item
+Das MySQL-Treiber-Standard-Konfigurationsfenster wird nun angezeigt.
+@xref{ODBC administrator}.
+@end itemize
+
+@item
+Starten Sie nun ihre Applikation und wählen Sie den ODBC-Treiber mit der
+von ihnen im ODBC angegebenen DSN.
+@end itemize
+
+Bitte beachten Sie, dass weitere Konfigurationsoptionen im MySQL-Fenster
+vorhanden sind (trace, don't prompt on connect usw.). Probieren Sie diese
+aus, wenn Sie Probleme haben.
+
+@node ODBC administrator, MyODBC connect parameters, Installing MyODBC, ODBC
+@c German node ODBC-Administrator
+@subsection Wie Sie die verschiedenen Felder im ODBC-Administrator Programm ausfüllen
+
+@cindex ODBC, Administrator
+
+Es gibt drei Möglichkeiten, den Server unter Windows 95 anzugeben:
+
+@itemize @bullet
+@item
+Verwenden Sie die IP-Adresse des Servers.
+@item
+Fügen Sie der Datei @file{\windows\lmhosts} folgende Informationen an:
+
+@example
+ip hostname
+@end example
+
+Beispiel:
+
+@example
+194.216.84.21 mein_hostname
+@end example
+
+@item
+Konfigurieren Sie DNS:
+@end itemize
+
+Beispiel: Wie Sie das @code{ODBC setup} ausfüllen:
+@example
+Windows DSN Name: test
+Beschreibung: Das ist meine Datenbank
+MySql Datenbank: test
+Server: 194.216.84.21
+User: monty
+Password: mein_passwort
+Port:
+@end example
+
+Der Wert für @code{Windows DSN Namen} muss in ihrem Windows-ODBC-Setup
+eindeutig sein.
+
+Sie müssen die Werte für @code{Server}, @code{User}, @code{Password} oder
+@code{Port} im ODBC-Setup-Fenster nicht angeben. Wenn Sie es jedoch tun,
+werden diese Werte als Standardwerte verwendet, wenn Sie versuchen, eine
+Verbindung aufzubauen. Sie können die Werte auch zur Laufzeit ihres
+Programms angeben.
+
+Wenn Sie die Portnummer nicht angeben, wird der Standard-Port
+(@value{default_port}) verwendet.
+
+Wenn Sie die Option @code{Optionen aus C:\my.cnf lesen} angeben, werden die
+Gruppen @code{client} und @code{odbc} aus der @file{C:\my.cnf}-Datei
+gelesen. Sie können alle Optionen verwenden, die für @code{mysql_options()}
+gültig sind. @xref{mysql_options, , @code{mysql_options}}.
+
+
+@node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC
+@c German node MyODBC-Verbindungsparameter
+@subsection Verbindungsparameter für MyODBC
+
+Man kann die folgenden Parameter für @strong{MyODBC} im
+@code{[Servername]}-Abschnitt in der @code{ODBC.INI}-Datei oder über das
+@code{InConnectionString}-Argument im @code{SQLDriverConnect()}-Aufruf
+angeben:
+
+@multitable @columnfractions .2 .2 .6
+@item @strong{Parameter} @tab @strong{Standardwert} @tab @strong{Bedeutung}
+@item user @tab ODBC (unter Windows) @tab Der Benutzername, der verwendet wird, um zu MySQL zu verbinden.
+@item server @tab localhost @tab Der Hostname des MySQL-Servers.
+@item database @tab @tab Die Standarddatenbank
+@item option @tab 0 @tab Eine Ganzzahl, die angibt, wie @strong{MyODBC} arbeiten soll. Siehe unten.
+@item port @tab 3306 @tab Der TCP/IP-Port, der verwendet werden soll, wenn der @code{server} nicht @code{localhost} ist.
+@item stmt @tab @tab Ein Statement, das bei der Verbindung zu @code{MySQL} ausgeführt wird.
+@item password @tab @tab Das Passwort für die @code{server}-@code{user}-Kombination.
+@item socket @tab @tab Der Socket oder die Windows-Pipe, über die verbunden werden soll.
+@end multitable
+
+Die Option "argument" wird verwendet, um @strong{MyODBC} zu sagen, dass der
+Client nicht 100% ODBC-kompatibel ist. Unter Windows setzt man diese Option
+normalerweise im Verbindungsdialog, Sie können aber auch das
+"option"-Argument verwenden. Die folgenden Optionen sind in derselben
+Reihenfolge wie im @strong{MyODBC}-Verbindungsdialog:
+
+@multitable @columnfractions .1 .9
+@item @strong{Bit} @tab @strong{Bedeutung}
+@item 1 @tab Der Client kann nicht damit umgehen, dass @strong{MyODBC} die wirkliche Breite einer Spalte zurückgibt.
+@item 2 @tab Der Client kann nicht damit umgehen, dass MySQL die wirkliche Anzahl an "affected rows" zurückgibt. Wenn dieses Bit gesetzt ist, wird MySQL statt dessen 'found rows' zurückgeben. Dies wird erst ab MySQL 3.21.14 unterstützt.
+@item 4 @tab Erstellt ein Debug-Log in c:\myodbc.log. Das ist dasselbe, als wenn Sie @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in Ihre @file{AUTOEXEC.BAT} schreiben.
+@item 8 @tab Entfernt jede Paket-Beschränkung für Ergebnisse und Parameter.
+@item 16 @tab Nicht auf Eingaben warten, sogar wenn der Treiber dies verlangt.
+@item 32 @tab Einen ODBC 1.0 Treiber simulieren.
+@item 64 @tab Die Angabe 'datenbank' in 'datenbank.tabelle.spalte' ignorieren.
+@item 128 @tab Die Verwendung von ODBC-Manager-Zeigern erzwingen (experimentell).
+@item 256 @tab Die Verwendung des erweiterten 'fetch' verbieten (experimentell).
+@item 512 @tab CHAR-Felder bis zur vollen Spaltenlänge füllen.
+@item 1024 @tab SQLDescribeCol() wird voll qualifizierte Spaltennamen zurückgeben.
+@item 2048 @tab Verwendet das komprimierte Client-/Server Protokoll.
+@item 4096 @tab Weist den Server an, Leerzeichen nach einem Funktionsnamen und vor @code{'('} zu ignorieren (wird von PowerBuilder benötigt). So werden alle Funktionsnamen zu Schlüsselwörtern!
+@item 8192 @tab Über "Named Pipes" zu einem @code{mysqld}-Server verbinden, der unter Windows NT läuft.
+@item 16384 @tab Ändert LONGLONG-Spalten zu INT-Spalten (einige Applikationen können mit LONGLONG nicht umgehen).
+@item 32768 @tab Gibt 'user' als Tabellenqualifizierer und Tabellen-Besitzer von SQL-Tabellen zurück (experimentell).
+@item 65536 @tab Liest die Parameter @code{client} und @code{odbc}-Gruppen aus der @file{my.cnf}-Datei.
+@item 131072 @tab Fügt einige Sicherheitsüberprüfungen hinzu (sollte nicht nötig sein, aber ...).
+@end multitable
+
+Wenn Sie viele Optionen haben wollen, sollten Sie die obigen Flags
+hinzufügen. Zum Beispiel gibt Ihnen die Option 12 (4+8) Debugging und keine
+Paketbeschränkungen.
+
+Die Standard-@file{MYODBC.DLL}-Datei wird für optimale Performance
+kompiliert. Wenn Sie @strong{MyODBC} debuggen wollen (um zum Beispiel
+"tracing" zu aktivieren), sollten Sie stattdessen @code{MYODBCD.DLL}
+verwenden. Um diese Datei zu installieren, kopieren Sie @file{MYODBCD.DLL}
+einfach über die installierte @code{MYODBC.DLL}-Datei.
+
+
+@node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC
+@c German node ODBC-Probleme
+@subsection Wie Sie Probleme mit MyODBC berichten
+
+@strong{MyODBC} wurde mit Access, Admndemo.exe, C++-Builder,
+Borland Builder 4, Centura Team Developer (vorher Gupta SQL/Windows),
+ColdFusion (unter Solaris und NT mit Service Pack 5), Crystal Reports,
+DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes
+4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32
+bit, VC++ und Visual Basic getestet.
+
+Wenn Sie weitere Applikationen kennen, die mit @strong{MyODBC}
+zusammenarbeiten, sagen Sie uns bitte unter @email{myodbc@@lists.mysql.com}
+Bescheid!
+
+Mit einigen Programmen können Fehler wie diese auftreten: @code{Another
+user hat modifies the record that you have modified}. Meistens lösen Sie
+das folgendermaßen:
+
+@itemize @bullet
+@item
+Fügen Sie der Tabelle einen Primärschlüssel hinzu, wenn noch keiner
+existiert.
+@item
+Fügen Sie eine TIMESTAMP-Spalte hinzu, wenn noch keine existiert.
+@item
+Verwenden Sie ausschließlich 'Double Float'-Felder. Manche Programme
+kommen mit 'Single Float'-Feldern nicht klar.
+@end itemize
+
+Wenn das nicht helfen sollte, dann erstellen Sie eine @code{MyODBC}
+'Trace'-Datei und versuchen Sie, die Fehlerquelle so zu erschließen.
+
+
+@node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC
+@c German node MyODBC-Clients
+@subsection Programme, die bekanntermaßen mit MyODBC zusammenarbeiten
+
+Die meisten Programme sollten mit @strong{MyODBC} zusammenarbeiten. Für die
+unten aufgeführten haben wir es selbst getestet oder haben die Bestätigung
+eines Benutzers, dass es läuft.
+
+@table @asis
+@item @strong{Programm}
+@strong{Anmerkung}
+@cindex Microsoft Access
+
+@item Access
+Um Access zum Laufen zu bringen:
+@itemize @bullet
+@item
+Wenn Sie Access 2000 verwenden, sollten Sie die neuesten (Version 2.6 oder
+höher) Microsoft-MDAC (@code{Microsoft Data Access Components}) von
+@uref{http://www.microsoft.com/data} herunterladen. Dies wird folgenden Bug
+in Access beheben: Wenn Sie Daten nach MySQL exportieren, werden Tabellen-
+und Spaltennamen nicht spezifiziert. Ein anderer Weg, diesen Bug zu
+umgehen, ist, MyODBC auf Version 2.50.33 und MySQL auf Version 3.23.x zu
+aktualisieren, welche beide zusammen einen Workaround für diesen Bug
+implementiert haben.
+
+Ausserdem sollten Sie das Microsoft-Jet-4.0-Service-Pack 5 (SP5)
+einspielen, welches hier
+@uref{http://support.microsoft.com/support/kb/articles/Q 239/1/14.ASP}
+gefunden werden kann. Dies behebt einige Fälle, in denen Spalten als
+@code{#deleted#} in Access markiert sind.
+
+Beachten Sie, dass Sie, wenn Sie die MySQL-Version 3.22 verwenden, den
+MDAC-Patch einspielen und MyODBC 2.50.32 oder 2.50.34 und höher benutzen
+müssen, um dieses Problem zu umgehen.
+@item
+Für alle Access-Versionen sollten Sie die MyODBC-Optionen auf @code{Return
+matching rows} setzen. Für Access 2.0 sollten Sie ausserdem @code{Simulate
+ODBC 1.0} einschalten.
+@item
+Sie sollten einen Timestamp in alle Tabellen einfügen, die Sie
+aktualisieren wollen. Für maximale Portablilität werden
+@code{TIMESTAMP(14)} oder einfach @code{TIMESTAMP} anstelle von
+@code{TIMESTAMP(X)}-Variationen empfohlen.
+@item
+Sie sollten einen Primärschlüssel in Ihren Tabellen haben. Falls nicht,
+können neue oder geänderte Zeilen als @code{#DELETED#} erscheinen.
+@item
+Verwenden sie ausschließlich @code{DOUBLE}-Float-Felder. Access kann nicht
+richtig mit "Single Floats" vergleichen. Die Symptome sind, dass entweder
+neue oder geänderte Zeilen als @code{#DELETED#} erscheinen oder Sie keine
+Zeilen finden oder ändern können.
+@item
+Wenn Sie eine Tabelle mit MyODBC verbinden, die eine @code{BIGINT}-Spalte hat,
+werden die Ergebnisse als @code{#DELETED} angezeigt. Sie umgehen das Problem
+folgendermaßen:
+@itemize @bullet
+@item
+Fügen Sie eine weitere @code{TIMESTAMP}-"Dummy-Spalte" hinzu, am besten
+@code{TIMESTAMP(14)}.
+@item
+Wählen Sie @code{'BIGINT Spalten zu INT wandeln'} im Verbindungsdialog des
+ODBC-DSN-Administrators.
+@item
+Entfernen Sie die Tabellenverknüpfung aus Access und stellen Sie sie wieder
+her.
+@end itemize
+
+Die vorherigen Zeilen werden weiterhin als @code{#DELETED#} angezeigt, aber
+neue/geänderte Zeilen werden korrekt dargestellt.
+@item
+Wenn Sie weiterhin den Fehler @code{Ein anderer Benutzer hat Ihre Daten geändert}
+erhalten, nachdem Sie die @code{TIMESTAMP}-Spalte hinzugefügt haben, könnte
+Ihnen der folgende Trick helfen:
+
+Verwenden Sie anstelle von @code{Datenblattansicht} ein Formular mit den
+von Ihnen gewünschten Feldern und benutzen Sie dann
+@code{Formularblattansicht}. Sie sollten den @code{StandardWert} für die
+@code{TIMESTAMP}-Spalte auf @code{NOW()} setzen. Zusätzlich ist es sicher
+nützlich, die @code{TIMESTAMP}-Spalte zu verstecken, damit Ihre Anwender
+nicht erschrecken.
+@item
+Manchmal erstellt Access ungültige SQL-Anfragen, die MySQL nicht versteht.
+
+
+Wählen Sie zur Lösung dieses Problems
+@code{"Abfrage|SQL-spezifisch|Pass-Through"} aus dem Access-Menü.
+@item
+Wenn Sie statt dessen @code{MEMO}-Spalten haben wollen, sollten Sie die
+Spalte mit @code{ALTER TABLE} in @code{TEXT} ändern.
+@item
+Access kann nicht immer sauber mit @code{DATE}-Spalten umgehen. Wenn Sie ein
+solches Problem haben, ändern Sie die entsprechenden Spalten in @code{DATETIME}.
+@item
+Wenn Sie in Access eine Spalte @code{BYTE} haben, wird Access versuchen,
+diese in @code{TINYINT} anstelle von @code{TINYINT UNSIGNED} zu
+exportieren. Das führt zu Problemen, wenn Sie Werte in der Spalte haben,
+die größer als 127 sind!
+@end itemize
+
+@cindex ADO program
+@item ADO
+Wenn Sie mit der ADO-API und @strong{MyODBC} kodieren, müssen Sie auf
+einige vorgabemäßige Eigenschaften achten, die vom MySQL-Server nicht
+unterstützt werden. Die Benutzung von @code{CursorLocationProperty} als
+@code{adUseServer} zum Beispiel gibt für @code{RecordCountProperty} ein
+Ergebnis von -1 zurück. Um den richtigen Wert zu erhalten, müssen Sie diese
+Eigenschaft auf @code{adUseClient} setzen, wie im unten stehenden
+Visual-Basic-Code gezeigt:
+
+@example
+Dim myconn As New ADODB.Connection
+Dim myrs As New Recordset
+Dim mySQL As String
+Dim myrows As Long
+
+myconn.Open "DSN=MyODBCsample"
+mySQL = "SELECT * from user"
+myrs.Source = mySQL
+Set myrs.ActiveConnection = myconn
+myrs.CursorLocation = adUseClient
+myrs.Open
+myrows = myrs.RecordCount
+
+myrs.Close
+myconn.Close
+@end example
+
+Ein weiterer Workaround besteht darin, ein @code{SELECT COUNT(*)}-Statement
+für eine ähnliche Anfrage zu benutzen, um das korrekte Zählen der Zeilen zu
+erreichen.
+
+@item Active server pages (ASP)
+Sie sollten den Option-Flag @code{Return matching rows} benutzen.
+
+@item BDE-Applikationen
+Damit diese funktionieren, sollten Sie die Option-Flags
+@code{Don't optimize column widths} und @code{Return matching rows}
+benutzen.
+
+@cindex Borland Builder 4
+@item Borland Builder 4
+Wenn Sie eine Anfrage starten, können Sie die Eigenschaft @code{Active}
+oder die Methode @code{Open} benutzen. Beachten Sie, dass @code{Active}
+automatisch mit einer @code{SELECT * FROM ...}-Anfrage startet, was keine
+gute Idee ist, wenn Ihre Tabellen Groß sind!
+@item ColdFusion (unter Unix)
+Die folgenden Informationen sind der ColdFusion-Dokumentation entnommen:
+
+Lesen Sie folgende Informationen, um den ColdFusion-Server für Linux so zu
+konfigurieren, dass er den unixODBC-Treiber bei @strong{MyODBC} für
+MySQL-Datenquellen benutzt. Allaire kann bestätigen, dass die
+@strong{MyODBC}-Version 2.50.26 mit MySQL-Version 3.22.27 und ColdFusion
+für Linux funktioniert. (Jede neuere Version sollte ebenfalls
+funktionieren.) Sie können @strong{MyODBC} von
+@uref{http://www.mysql.com/downloads/api-myodbc.html} herunter laden.
+
+@cindex ColdFusion
+Bei ColdFusion Version 4.5.1 können Sie den ColdFusion Administrator
+benutzen, um die MySQL-Datenquelle hinzuzufügen. Der Treiber liegt der
+ColdFusion Version 4.5.1 jedoch nicht bei. Bevor der MySQL-Treiber in der
+Auswahlliste der ODBC-Datenquellen erscheint, müssen Sie den
+@strong{MyODBC}-Treiber bauen und nach
+@file{/opt/coldfusion/lib/libmyodbc.so} kopieren.
+
+Das Contrib-Verzeichnis enthält das Programm mydsn-xxx.zip, mit dem Sie die
+DSN-Registrierungs-Datei für den MyODBC-Treiber auf
+Coldfusion-Applikationen bauen können.
+
+@cindex DataJunction
+@item DataJunction
+Sie müssen es ändern, damit es @code{VARCHAR} statt @code{ENUM} ausgibt,
+weil es Letzteres in einer Art ausgibt, die MySQL nicht versteht.
+
+@cindex Excel
+@item Excel
+Funktioniert. Einige Tipps:
+@itemize @bullet
+@item
+Wenn Sie Probleme mit Datumsangaben haben, versuchen Sie, sie als
+Zeichenketten mit der @code{CONCAT()}-Funktion abzurufen. Beispiel:
+@example
+select CONCAT(sonnenaufgang), CONCAT(sonnenuntergang)
+ from aufgang_untergang;
+@end example
+Werte, die auf diese Art als Zeichenketten abgerufen werden, sollten
+korrekt als Zeitwerte von Excel97 erkannt werden.
+
+Der Zweck von @code{CONCAT()} in diesem Beispiel ist, ODBC auszutricksen,
+so dass es denkt, dass die Spalte vom Typ "Zeichenkette" sei. Ohne
+@code{CONCAT()} weiß ODBC, dass die Spalte vom Typ "Zeit" ist, und Excel
+versteht das nicht.
+
+Beachten Sie, dass das ein Bug in Excel ist, weil es eine Zeichenkette
+automatisch in eine Zeitangabe umwandelt. Das wäre sehr gut, wenn die
+Quelle eine Textdatei wäre, ist aber einfach nur dumm, wenn die Quelle eine
+ODBC-Verbindung ist, die exakte Typen für jede Spalte übermittelt.
+@end itemize
+@cindex Word
+@item Word
+
+Um Daten von MySQL in Word- / Excel-Dokumente abzurufen, müssen Sie den
+@code{MyODBC}-Treiber benutzen und das Add-in Microsoft Query hinzufügen.
+
+Erzeugen Sie zum Beispiel eine Datenbank mit einer Tabelle, die 2
+Text-Spalten enthält:
+
+@itemize @bullet
+@item
+Fügen Sie Zeilen mit dem @code{mysql}-Kommandozeilenwerkzeug ein.
+@item
+Erzeugen Sie eine DSN-Datei mit dem MyODBC-Treiber, die Sie zum Beispiel my
+nennen, für die oben genannten Datenbank.
+@item
+Öffnen Sie Word.
+@item
+Erzeugen Sie ein leeres Dokument.
+@item
+Öffnen Sie die Symbolleiste 'Datenbank' und klicken Sie auf die
+Schaltfläche 'Datenbank einfügen'.
+@item
+Klicken Sie auf die Schaltfläche 'Daten abrufen'.
+@item
+Klicken Sie auf die Schaltfläche 'MS Query'.
+@item
+Erzeugen Sie in MS Query eine neue Datenquelle unter Benutzung der
+DSN-Datei my.
+@item
+Wählen Sie die neue Anfrage aus.
+@item
+Wählen Sie die Spalten aus, die Sie haben wollen.
+@item
+Legen Sie bei Bedarf einen Filter fest.
+@item
+Legen Sie bei Bedarf eine Sortierung fest.
+@item
+Wählen Sie 'Daten an Word zurückgeben'.
+@item
+Klicken Sie auf 'Beenden'.
+@item
+Klicken Sie auf 'Daten einfügen' und wählen Sie die Datensätze aus.
+@item
+Klicken Sie auf 'OK', und Sie sehen die Zeilen in Ihrem Word-Dokument.
+@end itemize
+
+@cindex odbcadmin
+@item odbcadmin
+Test-Programm für ODBC.
+@cindex Delphi-Programm
+@item Delphi
+Sie müssen BDE-Version 3.2 oder neuer benutzen. Setzen Sie die `Don't
+optimize column width'-Option, wenn Sie sich mit MySQL verbinden.
+
+Hier ist möglicherweise nützlicher Delphi-Code, der sowohl einen
+ODBC-Eintrag als auch einen BDE-Eintrag für @strong{MyODBC} setzt (der
+BDE-Eintrag erfordert einen BDE-Alias-Editor, der kostenlos auf einer
+Delphi Super Page in Ihrer Nähe herunter geladen werden kann (Dank dafür an
+Bryan Brunton @email{bryan@@flesherfab.com}:
+
+@example
+fReg:= TRegistry.Create;
+ fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
+ fReg.WriteString('Database', 'Documents');
+ fReg.WriteString('Description', ' ');
+ fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
+ fReg.WriteString('Flag', '1');
+ fReg.WriteString('Password', '');
+ fReg.WriteString('Port', ' ');
+ fReg.WriteString('Server', 'xmark');
+ fReg.WriteString('User', 'winuser');
+ fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
+ fReg.WriteString('DocumentsFab', 'MySQL');
+ fReg.CloseKey;
+ fReg.Free;
+
+ Memo1.Lines.Add('DATABASE NAME=');
+ Memo1.Lines.Add('USER NAME=');
+ Memo1.Lines.Add('ODBC DSN=DocumentsFab');
+ Memo1.Lines.Add('OPEN MODE=READ/WRITE');
+ Memo1.Lines.Add('BATCH COUNT=200');
+ Memo1.Lines.Add('LANGTreiber=');
+ Memo1.Lines.Add('MAX ROWS=-1');
+ Memo1.Lines.Add('SCHEMA CACHE DIR=');
+ Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
+ Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
+ Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
+ Memo1.Lines.Add('SQLQRYMODE=');
+ Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
+ Memo1.Lines.Add('ENABLE BCD=FALSE');
+ Memo1.Lines.Add('ROWSET SIZE=20');
+ Memo1.Lines.Add('BLOBS TO CACHE=64');
+ Memo1.Lines.Add('BLOB SIZE=32');
+
+ AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);
+@end example
+
+@cindex C++-Builder
+@item C++-Builder
+Getestet mit BDE-Version 3.0. Das einzige bekannte Problem ist, dass
+Anfragefelder nicht aktualisiert werden, wenn sich die Tabellenstruktur
+ändert. BDE scheint jedoch keine Primärschlüssel zu erkennen, sondern nur
+den Index PRIMARY, obwohl das eigentlich kein Problem darstellt.
+
+@item Vision
+Sie sollten den Option-Flag @code{Return matching rows} benutzen.
+
+@cindex Visual Basic
+@item Visual Basic
+Damit Sie eine Tabelle aktualisieren können, müssen Sie für die Tabelle
+einen Primärschlüssel definieren.
+
+Visual Basic mit ADO kann keine großen Ganzzahlen handhaben. Das heißt,
+dass einige Anfragen wie @code{SHOW PROCESSLIST} nicht korrekt
+funktionieren. Das läßt sich beheben, indem man die Option
+@code{OPTION=16834} in der ODBC-Verbindungs-Zeichenkette hinzufügt oder die
+@code{Change BIGINT columns to INT}-Option im MySQL-Verbindungsbildschirm
+setzt. Eventuell sollten Sie auch die @code{Return matching rows}-Option
+setzen.
+
+@item VisualInterDev
+Wenn Sie den Fehler @code{[Microsoft][ODBC Driver Manager] Driver does not
+support this parameter} erhalten, kann es daran liegen, dass Sie ein
+@code{BIGINT} in Ihrem Ergebnis haben. Versuchen Sie, die @code{Change
+BIGINT columns to INT}-Option im MySQL-Verbindungsbildschirm zu setzen.
+
+@item Visual Objects
+Sie sollten den Option-Flag @code{Don't optimize column widths} setzen.
+@end table
+
+
+@node ODBC and last_insert_id, MyODBC bug report, MyODBC clients, ODBC
+@c German node ODBC und last_insert_id
+@subsection Wie man den Wert einer @code{AUTO_INCREMENT}-Spalte in ODBC erhält
+
+@cindex AUTO-INCREMENT, ODBC
+
+Ein häufiges Problem ist es, den Wert einer automatisch erzeugten Kennung
+von einem @code{INSERT} zu erhalten. Bei ODBC können Sie etwas wie
+folgendes tun (unter der Annahme, dass @code{auto} ein
+@code{AUTO_INCREMENT}-Feld ist):
+
+@example
+INSERT INTO foo (auto,text) VALUES(NULL,'text');
+SELECT LAST_INSERT_ID();
+@end example
+
+Oder, wenn Sie die Kennung in eine andere Tabelle einfügen wollen:
+
+@example
+INSERT INTO foo (auto,text) VALUES(NULL,'text');
+INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text');
+@end example
+
+@xref{Getting unique ID}.
+
+Bei einigen ODBC-Applikationen (zumindest Delphi und Access) kann folgende
+Anfrage benutzt werden, um eine neu eingefügte Zeile zu finden:
+@example
+SELECT * FROM tabelle WHERE auto IS NULL;
+@end example
+
+
+@node MyODBC bug report, , ODBC and last_insert_id, ODBC
+@c German node MyODBC-Bug-Bericht
+@subsection Probleme mit MyODBC berichten
+
+@cindex berichten, MyODBC-Probleme
+@cindex Probleme, ODBC
+@cindex MyODBC, Probleme berichten
+
+Wenn Sie Probleme mit @strong{MyODBC} bekommen, sollten Sie als erstes eine
+Log-Datei durch den ODBC-Manager anlegen lassen (das Log, das Sie erhalten,
+wenn Sie Logs von ODBCADMIN abfragen) sowie ein @strong{MyODBC}-Log.
+
+Um ein @strong{MyODBC}-Log zu erhalten, tun Sie folgendes:
+
+@enumerate
+@item
+Stellen Sie sicher, dass Sie @code{myodbcd.dll} und nicht @code{myodbc.dll}
+benutzen. Am einfachsten ist es, wenn Sie sich @code{myodbcd.dll} aus der
+MyODBC-Distribution holen und es über @code{myodbc.dll} kopieren, die sich
+wahrscheinlich in Ihrem @code{C:\windows\system32}- oder
+@code{C:\winnt\system32}-Verzeichnis befindet.
+
+Denken Sie daran, dass Sie wahrscheinlich die alten myodbc.dll nach dem
+Testen wiederherstellen wollen, weil Sie um einiges schneller ist als
+@code{myodbcd.dll}.
+@item
+Kreuzen Sie `Trace MyODBC' im @strong{MyODBC}-Verbindungs- bzw.
+Konfigurationsfenster an. Das Log wird in die Datei @file{C:\myodbc.log}
+geschrieben.
+
+Wenn Sie zu diesem Fenster zurückkehren und feststellen, dass die
+Trace-Option nicht mehr angekreuzt ist, heißt das, dass Sie nicht den
+@code{myodbcd.dll}-Treiber benutzen (siehe oben).
+@item
+Starten Sie Ihre Applikation und versuchen Sie, eine Fehlfunktion zu
+bekommen.
+@end enumerate
+
+Untersuchen Sie die @code{MyODBC-Trace-Datei}, um herauszufinden, was
+möglicherweise schief geht. Sie können die abgesetzten Anfragen finden,
+indem Sie nach der Zeichenkette @code{>mysql_real_query} in der
+@file{myodbc.log}-Datei suchen.
+
+Sie sollten die Anfragen auch zusätzlich im @code{mysql}-Monitor oder in
+@code{admndemo} laufen lassen, um herauszufinden, ob der Fehler bei MyODBC
+oder bei MySQL liegt.
+
+Wenn Sie herausgefunden haben, was schief läuft, schicken Sie bitte nur die
+relevanten Zeilen (maximal 40 Zeilen) an @email{myodbc@@lists.mysql.com}.
+Bitte schicken Sie nie die gesamte MyODBC- oder ODBC-Log-Datei!
+
+Wenn Sie nicht herausfinden können, was schief läuft, besteht die letzte
+Option darin, eine Archivdatei anzulegen (tar oder zip), die eine
+MyODBC-Trace-Datei, die ODBC-Log-Datei und eine README-Datei enthält, die
+das Problem erläutert. Schicken Sie diese an
+@uref{ftp://support.mysql.com/pub/mysql/secret}. Nur wir bei MySQL AB haben
+Zugriff auf die Dateien, die Sie hochspielen, und wir gehen mit den Daten
+sehr diskret um!
+
+Wenn Sie ein Programm erzeugen können, das dieses Problem ebenfalls zeigt,
+laden Sie dieses bitte ebenfalls hoch!
+
+Wenn das Programm mit irgend einem anderen SQL-Server funktioniert, sollten
+Sie eine ODBC-Log-Datei anlegen, in der Sie dasselbe in dem anderen
+SQL-Server ausführen.
+
+Bedenken Sie, dass wir umso eher das Problem beheben können, desto mehr
+Informationen Sie uns zur Verfügung stellen!
+
+
+@node C, Cplusplus, ODBC, Clients
+@c German node C
+@section MySQL-C-API
+
+@cindex C-API, datatypes
+@cindex Datentypen, C-API
+
+
+Der C-API-Code wird mit MySQL ausgeliefert. Er ist in der
+@code{mysqlclient}-Bibliothek enthalten und erlaubt C-Programmen, auf eine
+Datenbank zuzugreifen.
+
+Viele Clients in der MySQL-Quelldistribution sind in C geschrieben. Wenn
+Sie nach Beispielen für den Gebrauch der C-API suchen, schauen Sie sich
+diese Clients an. Sie finden Sie im @code{clients}-Verzeichnis in der
+MySQL-Quelldistribution.
+
+Viele andere Client-APIs (alle ausser Java) benutzen die
+@code{mysqlclient}-Bibliothek, um mit dem MySQL-Server zu kommunizieren.
+Das heißt zum Beispiel, dass Sie viele derselben Umgebungsvariablen nutzen
+können, die von anderen Client-Programmen benutzt werden, weil sie von der
+Bibliothek referenziert werden. Eine Liste dieser Variablen findet sich
+unter @ref{Client-Side Scripts}.
+
+Der Client hat eine maximale Kommunikationspuffergröße. Die anfänglich
+zugewiesene Puffergröße (16 KB) wird automatisch bis zur maximale Größe
+(16 MB) vergrößert. Weil Puffergrößen nur bei Bedarf vergrößert werden,
+bedeutet die einfache Erhöhung der maximalen Größe nicht per se, dass mehr
+Ressourcen benutzt werden. Die Überprüfung der Größe ist hauptsächlich
+eine Prüfung auf irrtümliche Anfragen und Kommunikationspakete.
+
+Der Kommunikationspuffer muss Groß genug sein, um ein einzelnes
+SQL-Statement aufzunehmen (für den Client-Server-Verkehr) und eine Zeile
+zurückgegebener Daten (für den Server-Client-Verkehr). Der
+Kommunikationspuffer jedes Threads wird dynamisch vergrößert, um jede
+Anfrage oder Zeile bis zur maximalen Größe zu handhaben. Wenn Sie
+beispielsweise @code{BLOB}-Werte haben, die bis zu 16 MB an Daten
+beinhalten, müssen Sie eine Kommunikationspuffergrenze von zumindest 16 MB
+haben (sowohl beim Server als auch beim Client). Die vorgabemäßige
+maximale Größe beim Client liegt bei 16 MB, aber die vorgabemäßige
+maximale Grenze beim Server liegt bei 1 MB. Das können Sie vergrößern,
+indem Sie den Wert des @code{max_allowed_packet}-Parameters setzen, wenn
+der Server gestartet wird. @xref{Server parameters}.
+
+Der MySQL-Server verringert den Kommunikationspuffer auf
+@code{net_buffer_length} Bytes nach jeder Anfrage. Bei Clients wird die
+Größe des zugewiesenen Puffers bei einer Verbindung nicht herabgesetzt,
+bis die Verbindung geschlossen wird. Dann wird der Client-Speicher wieder
+freigesetzt.
+
+Zum Programmieren mit Threads siehe @ref{Threaded clients}. Um eine
+Standalone-Applikation herzustellen, die "Server" und "Client" im selben
+Programm beinhaltet (und nicht mit einem externen MySQL-Server
+kommuniziert), siehe @ref{libmysqld}.
+
+
+@menu
+* C API datatypes::
+* C API function overview::
+* C API functions::
+* C Thread functions::
+* C Embedded Server func::
+* C API problems::
+* Building clients::
+* Threaded clients::
+* libmysqld::
+@end menu
+
+@node C API datatypes, C API function overview, C, C
+@c German node C-API-Datentypen
+@subsection C-API-Datentypen
+
+@table @code
+@tindex MYSQL C type
+@item MYSQL
+This structure represents a handle to one Datenbank connection. It is
+used für almost all MySQL Funktionen.
+
+@tindex MYSQL_RES C-Typ
+@item MYSQL_RES
+Diese Struktur repräsentiert das Ergebnis einer Anfrage, die Zeilen
+zurückgibt (@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}).
+Die von der Anfrage zurückgegebene Informationen wird im Weiteren
+@emph{result set} (Ergebnismenge) genannt.
+
+@tindex MYSQL_ROW C-Typ
+@item MYSQL_ROW
+Das ist eine Typ-sichere Repräsentation einer Zeile von Daten. Momentan ist
+sie als ein Array gezählter Byte-Zeichenketten implementiert. (Sie können
+diese nicht als NULL-begrenzte Zeichenketten behandeln, falls Feldwert
+binäre Daten enthalten können, welche solche Werte intern NULL-Bytes
+enthalten können.) Zeilen werden mit dem Aufruf von
+@code{mysql_fetch_row()} abgeholt.
+
+@tindex MYSQL_FIELD C-Typ
+@item MYSQL_FIELD
+Diese Struktur enthält Informationen über ein Feld, wie Feldname, Feldtyp
+und Feldgröße. Seine Elemente werden weiter unten genauer beschrieben. Sie
+erhalten die @code{MYSQL_FIELD}-Strukturen für jedes Feld durch den
+wiederholten Aufruf von @code{mysql_fetch_field()}. Feldwerte sind nicht
+Teil dieser Struktur, sondern in der @code{MYSQL_ROW}-Struktur enthalten.
+
+
+@tindex MYSQL_FIELD_OFFSET C-Typ
+@item MYSQL_FIELD_OFFSET
+Das ist eine Typ-sichere Repräsentation eines Offsets in einer
+MySQL-Feldliste (benutzt von @code{mysql_field_seek()}.) Offsets sind
+Feldnummern innerhalb einer Zeile, beginnend mit 0.
+
+@tindex my_ulonglong C-Typ
+@tindex my_ulonglong-Werte, Ausgabe
+@item my_ulonglong
+Der Typ, der für die Anzahl von Zeilen und für @code{mysql_affected_rows()},
+@code{mysql_num_rows()}, und @code{mysql_insert_id()} benutzt wird. Dieser
+Typ stellt einen Bereich von @code{0} bis @code{1.84e19} zur Verfügung.
+
+Auf manchen Systemen funktioniert der Versuch, einen Wert des Typs
+@code{my_ulonglong} auszugeben, nicht. Um einen solchen Wert auszugeben,
+wandeln Sie ihn in @code{unsigned long} um und benutzen Sie ein
+@code{%lu}-Ausgabeformat. Beispiel:
+@example
+printf (Anzahl von Zeilen: %lu\n", (unsigned long) mysql_num_rows(result));
+@end example
+@end table
+
+@noindent
+Die @code{MYSQL_FIELD}-Struktur enthält die unten aufgeführten Elemente:
+
+@table @code
+@item char * name
+Der Name des Feldes, als NULL-begrenzte Zeichenkette.
+
+@item char * table
+Der Name der Tabelle, die dieses Feld enthält, falls es kein berechnetes
+Feld ist. Bei berechneten Feldern ist der @code{table}-Wert eine leere
+Zeichenkette.
+
+@item char * def
+Der Vorgabewert dieses Felds als eine NULL-begrenzte Zeichenkette. Dieser
+wird nur gesetzt, wenn Sie @code{mysql_list_fields()} benutzen.
+
+@item enum enum_field_types-Typ
+Der Typ des Felds. Der @code{type}-Wert kann einer der folgenden sein:
+
+@multitable @columnfractions .3 .55
+@item @strong{Typwert} @tab @strong{Typbedeutung}
+@item @code{FIELD_TYPE_TINY} @tab @code{TINYINT}-Feld
+@item @code{FIELD_TYPE_SHORT} @tab @code{SMALLINT}-Feld
+@item @code{FIELD_TYPE_LONG} @tab @code{INTEGER}-Feld
+@item @code{FIELD_TYPE_INT24} @tab @code{MEDIUMINT}-Feld
+@item @code{FIELD_TYPE_LONGLONG} @tab @code{BIGINT}-Feld
+@item @code{FIELD_TYPE_DECIMAL} @tab @code{DECIMAL}- oder @code{NUMERIC}-Feld
+@item @code{FIELD_TYPE_FLOAT} @tab @code{FLOAT}-Feld
+@item @code{FIELD_TYPE_DOUBLE} @tab @code{DOUBLE}- oder @code{REAL}-Feld
+@item @code{FIELD_TYPE_TIMESTAMP} @tab @code{TIMESTAMP}-Feld
+@item @code{FIELD_TYPE_DATE} @tab @code{DATE}-Feld
+@item @code{FIELD_TYPE_TIME} @tab @code{TIME}-Feld
+@item @code{FIELD_TYPE_DATETIME} @tab @code{DATETIME}-Feld
+@item @code{FIELD_TYPE_YEAR} @tab @code{YEAR}-Feld
+@item @code{FIELD_TYPE_STRING} @tab @code{CHAR}- oder @code{VARCHAR}-Feld
+@item @code{FIELD_TYPE_BLOB} @tab @code{BLOB}- oder @code{TEXT}-Feld (benutzen Sie @code{max_length}, um die maximale Länge festzulegen)
+@item @code{FIELD_TYPE_SET} @tab @code{SET}-Feld
+@item @code{FIELD_TYPE_ENUM} @tab @code{ENUM}-Feld
+@item @code{FIELD_TYPE_NULL} @tab @code{NULL}-Feld
+@item @code{FIELD_TYPE_CHAR} @tab Veraltet; benutzen Sie statt dessen @code{FIELD_TYPE_TINY}
+@end multitable
+
+Sie können das @code{IS_NUM()}-Makro benutzen, um zu testen, ob ein Feld
+einen numerischen Typ besitzt oder nicht. Übergeben Sie den
+@code{type}-Wert an @code{IS_NUM()}, und Sie erhalten WAHR (true), wenn das
+Feld numerisch ist:
+
+@example
+if (IS_NUM(field->type))
+ printf("Feld ist numerisch\n");
+@end example
+
+@item unsigned int length
+Die Breite des Felds, wie in der Tabellendefinition festgelegt.
+
+@item unsigned int max_length
+Die maximale Breite des Felds für die Ergebnismenge (die Länge des längsten
+Feldwerts für die Zeilen, die tatsächlich in der Ergebnismenge enthalten
+sind). Wenn Sie @code{mysql_store_result()} oder @code{mysql_list_fields()}
+benutzen, enthält die Variable die maximale Länge für das Feld. Wenn Sie
+@code{mysql_use_result()} benutzen, ist sie 0.
+
+@item unsigned int flags
+Unterschiedliche Bit-Flags für das Feld. Der @code{flags}-Wert kann 0 oder
+mehr der folgenden Bits gesetzt haben:
+
+@multitable @columnfractions .3 .55
+@item @strong{Flag-Wert} @tab @strong{Flag-Bedeutung}
+@item @code{NOT_NULL_FLAG} @tab Feld darf nicht @code{NULL} sein
+@item @code{PRI_KEY_FLAG} @tab Feld ist Teil eines Primärschlüssels
+@item @code{UNIQUE_KEY_FLAG} @tab Feld ist Teil eines eindeutigen Schlüssels
+@item @code{MULTIPLE_KEY_FLAG} @tab Feld ist Teil eines nicht eindeutigen Schlüssels
+@item @code{UNSIGNED_FLAG} @tab Feld hat das @code{UNSIGNED}-Attribute
+@item @code{ZEROFILL_FLAG} @tab Feld hat das @code{ZEROFILL}-Attribute
+@item @code{BINARY_FLAG} @tab Feld hat das @code{BINARY}-Attribute
+@item @code{AUTO_INCREMENT_FLAG} @tab Feld hat das @code{AUTO_INCREMENT}-Attribut
+@item @code{ENUM_FLAG} @tab Feld ist ein @code{ENUM} (veraltet)
+@item @code{BLOB_FLAG} @tab Feld ist ein @code{BLOB} oder @code{TEXT} (veraltet)
+@item @code{TIMESTAMP_FLAG} @tab Feld ist ein @code{TIMESTAMP} (veraltet)
+@end multitable
+
+Die Benutzung der @code{BLOB_FLAG}-, @code{ENUM_FLAG}- und
+@code{TIMESTAMP_FLAG}-Flags ist veraltet, weil sie den Feldtyp statt eines
+Attributs seines Typs angeben. Statt dessen sollten Sie @code{field->type}
+gegen @code{FIELD_TYPE_BLOB}, @code{FIELD_TYPE_ENUM} oder
+@code{FIELD_TYPE_TIMESTAMP} testen.
+
+@noindent
+Das unten stehende Beispiel zeigt eine typische Benutzung des
+@code{flags}-Werts:
+
+@example
+if (field->flags & NOT_NULL_FLAG)
+ printf("Feld darf nicht NULL sein\n");
+@end example
+
+Sie können aus Bequemlichkeitsgründen folgende Makros benutzen, um den
+Bool'schen Status des @code{flags}-Werts zu bestimmen:
+
+@multitable @columnfractions .3 .5
+@item @code{IS_NOT_NULL(flags)} @tab WAHR, wenn der Feldwert als @code{NOT NULL} definiert ist
+@item @code{IS_PRI_KEY(flags)} @tab WAHR, wenn der Feldwert ein Primärschlüssel ist
+@item @code{IS_BLOB(flags)} @tab WAHR, wenn der Feldwert ein @code{BLOB} oder @code{TEXT} ist (veraltet; testen Sie statt dessen @code{field->type})
+@end multitable
+
+@item unsigned int decimals
+Die Anzahl von Dezimalstellen für numerische Felder.
+@end table
+
+
+@node C API function overview, C API functions, C API datatypes, C
+@c German node C-API-Funktionsüberblick
+@subsection C-API-Funktionsüberblick
+
+@cindex C-API, Funktionen
+@cindex Funktionen, C-API
+
+Die in der C-API verfügbaren Funktionen sind unten aufgeführt und im
+nächsten Abschnitt detaillierter beschrieben.
+@xref{C API functions}.
+
+@multitable @columnfractions .3 .7
+@item @strong{mysql_affected_rows()} @tab
+Gibt die Anzahl von Zeilen zurück, die durch die letzte @code{UPDATE}-,
+@code{DELETE}- oder @code{INSERT}-Anfrage geändert, gelöscht bzw.
+hinzugefügt wurden.
+
+@item @strong{mysql_close()} @tab
+Schließt eine Server-Verbindung.
+
+@item @strong{mysql_connect()} @tab
+Stellt die Verbindung mit einem MySQL-Server her. Diese Funktion ist
+veraltet, benutzen Sie statt dessen @code{mysql_real_connect()}.
+
+@item @strong{mysql_change_user()} @tab
+Ändert Benutzer und Datenbank bei einer geöffneten Verbindung.
+
+@item @strong{mysql_character_set_name()} @tab
+Gibt den Namen des vorgabemäßigen Zeichensatzes für die Verbindung zurück.
+
+@item @strong{mysql_create_db()} @tab
+Erzeugt eine Datenbank. Diese Funktion ist veraltet, benutzen Sie statt
+dessen den SQL-Befehl @code{CREATE DATABASE}.
+
+@item @strong{mysql_data_seek()} @tab
+Sucht bis zu einer beliebigen Zeile in einer Anfrage-Ergebnismenge.
+
+@item @strong{mysql_debug()} @tab
+Macht ein @code{DBUG_PUSH} mit der angegebenen Zeichenkette.
+
+@item @strong{mysql_drop_db()} @tab
+Löscht eine Datenbank. Diese Funktion ist veraltet, benutzen Sie statt
+dessen den SQL-Befehl @code{DROP DATABASE}.
+
+@item @strong{mysql_dump_debug_info()} @tab
+Veranlasst den Server, Debug-Informationen in die Log-Datei zu schreiben.
+
+@item @strong{mysql_eof()} @tab
+Stellt fest, ob die letzte Zeile der Ergebnismenge gelesen wurde oder
+nicht. Diese Funktion ist veraltet, benutzen Sie statt dessen
+@code{mysql_errno()} oder @code{mysql_error()}.
+
+@item @strong{mysql_errno()} @tab
+Gibt die Fehlernummer der zuletzt aufgerufenen MySQL-Funktion zurück.
+
+@item @strong{mysql_error()} @tab
+Gibt die Fehlermeldung der zuletzt aufgerufenen MySQL-Funktion zurück.
+
+@item @strong{mysql_real_escape_string()} @tab
+Escapet Sonderzeichen in einer Zeichenkette, die für ein SQL-Statement
+benutzt wird, wobei der aktuelle Zeichensatz der Verbindung berücksichtigt
+wird.
+
+@item @strong{mysql_escape_string()} @tab
+Escapet Sonderzeichen in einer Zeichenkette, die für ein SQL-Statement
+benutzt wird.
+
+@item @strong{mysql_fetch_field()} @tab
+Gibt den Typ des nächsten Tabellenfelds zurück.
+
+@item @strong{mysql_fetch_field_direct()} @tab
+Gibt den Typ eines Tabellenfelds zurück, angegeben durch eine Feldnummer.
+
+@item @strong{mysql_fetch_fields()} @tab
+Gibt ein Array aller Feldstrukturen zurück.
+
+@item @strong{mysql_fetch_lengths()} @tab
+Gibt die Länge aller Spalten in der aktuellen Zeile zurück.
+
+@item @strong{mysql_fetch_row()} @tab
+Holt die nächste Zeile aus der Ergebnismenge.
+
+@item @strong{mysql_field_seek()} @tab
+Setzt den Spaltencursor auf eine bestimmte Spalte.
+
+@item @strong{mysql_field_count()} @tab
+Gibt die Anzahl der Ergebnisspalten für die letzte Anfrage zurück.
+
+@item @strong{mysql_field_tell()} @tab
+Gibt die Position des Feldcursors zurück, der für das letzte
+@code{mysql_fetch_field()} benutzt wurde.
+
+@item @strong{mysql_free_result()} @tab
+Gibt Speicher frei, der von einer Ergebnismenge benutzt wird.
+
+@item @strong{mysql_get_client_info()} @tab
+Gibt Client-Versionsinformationen zurück.
+
+@item @strong{mysql_get_host_info()} @tab
+Gibt eine Zeichenkette zurück, die die Verbindung beschreibt.
+
+@item @strong{mysql_get_proto_info()} @tab
+Gibt die Protokollversion zruück, die von der Verbindung benutzt wird.
+
+@item @strong{mysql_get_server_info()} @tab
+Gibt die Server-Versionsnummer zurück.
+
+@item @strong{mysql_info()} @tab
+Gibt Informationen über die zuletzt ausgeführte Anfrage zurück.
+
+@item @strong{mysql_init()} @tab
+Holt oder initialisiert eine @code{MYSQL}-Struktur.
+
+@item @strong{mysql_insert_id()} @tab
+Gibt die Kennung zurück, die für eine @code{AUTO_INCREMENT}-Spalte durch
+die letzte Anfrage erzeugt wurde.
+
+@item @strong{mysql_kill()} @tab
+Tötet einen angegebenen Thread.
+
+@item @strong{mysql_list_dbs()} @tab
+Gibt die Datenbanknamen zurück, die mit einem einfachen regulären Ausdruck
+übereinstimmen.
+
+@item @strong{mysql_list_fields()} @tab
+Gibt die Feldnamen zurück, die mit einem einfachen regulären Ausdruck
+übereinstimmen.
+
+@item @strong{mysql_list_processes()} @tab
+Gibt eine Liste der aktuellen Server-Threads zurück.
+
+@item @strong{mysql_list_tables()} @tab
+Gibt Tabellenamen zurück, die mit einem einfachen regulären Ausdruck
+übereinstimmen.
+
+@item @strong{mysql_num_fields()} @tab
+Gibt die Anzahl von Spalten in einer Ergebnismenge zurück.
+
+@item @strong{mysql_num_rows()} @tab
+Gibt die Anzahl von Zeilen in einer Ergebnismenge zurück.
+
+@item @strong{mysql_options()} @tab
+Setzt Verbindungsoptionen für @code{mysql_connect()}.
+
+@item @strong{mysql_ping()} @tab
+Prüft, ob die Verbindung zum Server funktioniert oder nicht und verbindet
+sich erneut, falls notwendig.
+
+@item @strong{mysql_Anfrage()} @tab
+Führt eine SQL-Anfrage aus, die als NULL-begrenzte Zeichenkette angegeben
+wird.
+
+@item @strong{mysql_real_connect()} @tab
+Verbindet sich mit einem MySQL-Server.
+
+@item @strong{mysql_real_query()} @tab
+Führt eine SQL-Anfrage aus, die als gezählte Zeichenkette angegeben wird.
+
+@item @strong{mysql_reload()} @tab
+Weist den Server an, die Berechtigungstabellen erneut zu laden.
+
+@item @strong{mysql_row_seek()} @tab
+Sucht bis zu einer Zeile in einer Ergebnismenge, indem sie den Wert
+benutzt, der von @code{mysql_row_tell()} zurückgegeben wird.
+
+@item @strong{mysql_row_tell()} @tab
+Gibt die Zeilencursorposition zurück.
+
+@item @strong{mysql_select_db()} @tab
+Wählt eine Datenbank aus.
+
+@item @strong{mysql_shutdown()} @tab
+Fährt den Datenbankserver herunter.
+
+@item @strong{mysql_stat()} @tab
+Gibt den Serverstatus als Zeichenkette zurück.
+
+@item @strong{mysql_store_result()} @tab
+Ruft eine komplette Ergebnismenge zum Client ab.
+
+@item @strong{mysql_thread_id()} @tab
+Gibt die aktuelle Thread-Kennung zurück.
+
+@item @strong{mysql_thread_safe()} @tab
+Gibt 1 zurück, wenn die Clients Thread-sicher kompiliert sind.
+
+@item @strong{mysql_use_result()} @tab
+Initialisiert den zeilenweisen Abruf einer Ergebnismenge.
+@end multitable
+
+Um sich mit dem Server zu verbinden, rufen Sie @code{mysql_init()} auf, um
+einen Verbindungs-Handler zu initialisieren. Rufen Sie dann
+@code{mysql_real_connect()} mit diesem Handler auf (mit Informationen wie
+Hostname, Benutzername und Passwort). Beim Verbinden setzt
+@code{mysql_real_connect()} den @code{reconnect}-Flag (Teil der
+MYSQL-Struktur) auf einen Wert von @code{1}. Dieser Flag legt bei einer
+Anfrage, die wegen einer verloren gegangenen Serververbindung nicht
+ausgeführt werden kann, fest, dass ein erneutes Verbinden versucht wird,
+bevor aufgegeben wird. Wenn Sie mit der Verbindung fertig sind, rufen Sie
+@code{mysql_close()} auf, um sie zu beenden.
+
+Während eine Verbindung aktiv ist, kann der Client SQL-Anfragen an den
+Server schicken, indem er @code{mysql_query()} oder
+@code{mysql_real_query()} benutzt. Der Unterschied zwischen beiden ist,
+dass @code{mysql_query()} erwartet, dass die Anfrage als NULL-separierte
+Zeichenkette angegeben wird, während @code{mysql_real_query()} eine
+gezählte Zeichenkette erwartet. Wenn die Zeichenkette Binärdaten enthält
+(was NULL-Bytes beinhalten kann), müssen Sie @code{mysql_real_query()}
+benutzen.
+
+Bei jeder Nicht-@code{SELECT}-Anfrage (wie @code{INSERT}, @code{UPDATE},
+@code{DELETE}) finden Sie heraus, wie viele Zeilen geändert (betroffen)
+wurden, indem Sie @code{mysql_affected_rows()} aufrufen.
+
+Bei @code{SELECT}-Anfragen rufen Sie die ausgewählten Zeilen als
+Ergebnismenge ab. (Beachten Sie, dass einige Statements ähnlich wie
+@code{SELECT} sind, weil auch sie Zeilen zurückgeben. Das sind @code{SHOW},
+@code{DESCRIBE} und @code{EXPLAIN}. Sie werden auf dieselbe Weise behandelt
+wie @code{SELECT}-Statements.)
+
+Es gibt für einen Client zwei Möglichkeiten, Ergebnismengen zu verarbeiten.
+Eine Möglichkeit besteht darin, die gesamte Ergebnismenge auf einmal
+abzurufen, indem @code{mysql_store_result()} aufgerufen wird. Diese
+Funktion holt alle Zeilen vom Server ab, die von der Anfrage zurückgegeben
+werden, und speichert sie im Client. Die zweite Möglichkeit besteht darin,
+dass der Client die Ergebnismenge zeilenweise abruft, indem er
+@code{mysql_use_result()} aufruft. Diese Funktion initialisiert den Abruf,
+holt aber keinerlei Zeilen vom Server ab.
+
+In beiden Fällen können Sie auf Zeilen zugreifen, indem Sie
+@code{mysql_fetch_row()} aufrufen. Bei @code{mysql_store_result()} greift
+@code{mysql_fetch_row()} auf Zeilen zurück, die bereits vom Server geholt
+wurden. Bei @code{mysql_use_result()} ruft @code{mysql_fetch_row()} die
+Zeilen direkt vom Server ab. Informationen über die Größe der Daten in
+jeder Zeile sind durch Aufruf von @code{mysql_fetch_lengths()} verfügbar.
+
+Wenn Sie mit einer Ergebnismenge fertig sind, rufen Sie
+@code{mysql_free_result()} auf, um den hierfür benutzten Speicher
+freizugeben.
+
+Die beiden Abrufmechanismen sind komplementär. Client-Programme sollten
+entscheiden, welcher Ansatz der für ihre Erfordernisse geeignetste ist. In
+der Praxis wird für Clients häufiger @code{mysql_store_result()} verwendet.
+
+Ein Vorteil von @code{mysql_store_result()} ist, dass bereits alle Zeilen
+zum Client geholt wurden. Deshalb können Sie nicht nur sequentiell auf
+Zeilen zugreifen, sondern sich in der Ergebnismenge vorwärts und rückwärts
+bewegen, indem Sie @code{mysql_data_seek()} oder @code{mysql_row_seek()}
+benutzen, um die aktuelle Position innerhalb der Ergebnismenge zu ändern.
+Sie können auch herausfinden, wie viele Zeilen es gibt, indem Sie
+@code{mysql_num_rows()} aufrufen. Auf der anderen Seite kann der
+Speicherbedarf für @code{mysql_store_result()} sehr hoch sein, wenn Sie
+große Ergebnismengen abrufen, so dass Speichermangel eintreten kann.
+
+Ein Vorteil von @code{mysql_use_result()} ist, dass der Client weniger
+Arbeitsspeicher für die Ergebnismenge benötigt, weil er nur eine Zeile
+zugleich erhält (und weil weniger Zuweisungs-Overhead da ist, kann
+@code{mysql_use_result()} schneller sein). Die Nachteile liegen darin, dass
+Sie jede Zeile schnell verarbeiten müssen, um zu vermeiden, den Server zu
+blockieren. Ausserdem haben Sie keinen wahlfreien (random) Zugriff auf die
+Zeilen innerhalb einer Ergebnismenge (Sie können auf die Zeilen nur
+sequentiell zugreifen), und Sie wissen nicht, wie viele Zeilen sich in der
+Ergebnismenge befinden, bis Sie sie alle abgerufen haben. Darüber hinaus
+@emph{müssen} Sie alle Zeilen abrufen, selbst wenn Sie während des Abrufs
+feststellen, dass Sie die Information gefunden haben, nach der Sie suchen.
+
+Die API ermöglicht Clients, auf die Anfragen entsprechend zu antworten
+(Zeilen nur wenn nötig abzurufen), ohne zu wissen, ob die Anfragen ein
+@code{SELECT} ist oder nicht. Das erreichen Sie durch Aufruf von
+@code{mysql_store_result()} nach jedem @code{mysql_query()} (oder
+@code{mysql_real_query()}). Wenn der Ergebnismengenaufruf erfolgreich ist,
+war die Anfrage ein @code{SELECT} und Sie können die Zeilen lesen. Wenn der
+Ergebnismengenaufruf fehlschlägt, rufen Sie @code{mysql_field_count()} auf,
+um festzustellen, ob ein Ergebnis erwartet wurde oder nicht. Wenn
+@code{mysql_field_count()} 0 zurückgibt, gab die Anfrage keine Daten zurück
+(was anzeigt, dass sie kein @code{INSERT}, @code{UPDATE}, @code{DELETE}
+usw. war), und es wurde nicht erwartet, dass sie Zeilen zurückgibt. Wenn
+@code{mysql_field_count()} ungleich 0 ist, sollte die Anfrage Zeilen
+zurückgegeben haben, tat das aber nicht. Das zeigt an, dass die Anfrage ein
+@code{SELECT} war, das fehlschlug. Sehen Sie in der Beschreibung von
+@code{mysql_field_count()} wegen eines Beispiels nach, wie das gemacht
+wird.
+
+Sowohl @code{mysql_store_result()} als auch @code{mysql_use_result()}
+gestatten Ihnen, Informationen über die Felder zu erlangen, aus denen die
+Ergebnismenge besteht (die Anzahl der Felder, ihre Namen, Typen usw.). Sie
+können sequentiell auf Feldinformationen innerhalb der Zeile zugreifen,
+indem Sie @code{mysql_fetch_field()} wiederholt aufrufen, oder direkt auf
+die Feldnummer innerhalb einer Zeile durch Aufruf von
+@code{mysql_fetch_field_direct()}. Die aktuelle Feldcursorposition kann
+durch den Aufruf von @code{mysql_field_seek()} geändert werden. Wenn Sie
+den Feldcursor setzen, betrifft das nachfolgende Aufrufe von
+@code{mysql_fetch_field()}. Sie erhalten alle Feldinformationen auf einmal,
+wenn Sie @code{mysql_fetch_fields()} aufrufen.
+
+Um Fehler zu erkennen und zu berichten, stellt MySQL den Zugriff auf
+Fehlerinformationen durch die @code{mysql_errno()}- und
+@code{mysql_error()}-Funktionen zur Verfügung. Diese geben den Fehlercode
+oder die Fehlermeldung für die zuletzt aufgerufenen Funktionen zur
+Verfügung, die erfolgreich sein oder fehlschlagen können, so dass Sie
+feststellen können, wann ein Fehler auftrat und welcher es war.
+
+
+@node C API functions, C Thread functions, C API function overview, C
+@c German node C-API-Funktionen
+@subsection C-API-Funktionsbeschreibungen
+
+
+In den unten stehenden Beschreibungen bedeutet ein Parameter oder
+Rückgabewert von @code{NULL} @code{NULL} im Sinne der
+C-Programmier-Sprache, nicht einen MySQL-@code{NULL}-Wert.
+
+Funktionen, die einen Wert zurückgeben, geben allgemein einen Zeiger oder
+eine Ganzzahl zurück. Falls nicht anders angegeben geben Funktionen, die
+einen Zeiger zurückgeben, einen Nicht-@code{NULL}-Wert zurück, um Erfolg
+anzuzeigen, oder einen @code{NULL}-Wert, um einen Fehler anzuzeigen.
+Funktionen, die eine Ganzzahl zurückgeben, geben 0 zurück, um Erfolg
+anzuzeigen, und Nicht-0, um einen Fehler anzuzeigen. Beachten Sie, dass
+``Nicht-0'' genau das bedeutet. Wenn die Funktionsbeschreibung nichts
+anderes aussagt, testen Sie nicht gegen einen anderen Wert als 0:
+
+@example
+if (ergebnis) /* korrekt */
+ ... FEHLER ...
+
+if (ergebnis < 0) /* nicht korrekt */
+ ... FEHLER ...
+
+if (ergebnis == -1) /* nicht korrekt */
+ ... FEHLER ...
+@end example
+
+Wenn eine Funktion einen Fehler zurückgibt, listet der Unterabschnitt
+@strong{Errors} der Funktionsbeschreibung die möglichen Fehlertypen auf.
+Sie finden heraus, welcher davon auftrat, indem Sie @code{mysql_errno()}
+aufrufen. Eine Zeichenketten-Darstellung des Fehler kann durch Aufruf von
+@code{mysql_error()} erlangt werden.
+
+
+@menu
+* mysql_affected_rows::
+* mysql_close::
+* mysql_connect::
+* mysql_change_user::
+* mysql_character_set_name::
+* mysql_create_db::
+* mysql_data_seek::
+* mysql_debug::
+* mysql_drop_db::
+* mysql_dump_debug_info::
+* mysql_eof::
+* mysql_errno::
+* mysql_error::
+* mysql_escape_string::
+* mysql_fetch_field::
+* mysql_fetch_fields::
+* mysql_fetch_field_direct::
+* mysql_fetch_lengths::
+* mysql_fetch_row::
+* mysql_field_count::
+* mysql_field_seek::
+* mysql_field_tell::
+* mysql_free_result::
+* mysql_get_client_info::
+* mysql_get_host_info::
+* mysql_get_proto_info::
+* mysql_get_server_info::
+* mysql_info::
+* mysql_init::
+* mysql_insert_id::
+* mysql_kill::
+* mysql_list_dbs::
+* mysql_list_fields::
+* mysql_list_processes::
+* mysql_list_tables::
+* mysql_num_fields::
+* mysql_num_rows::
+* mysql_options::
+* mysql_ping::
+* mysql_query::
+* mysql_real_connect::
+* mysql_real_escape_string::
+* mysql_real_query::
+* mysql_reload::
+* mysql_row_seek::
+* mysql_row_tell::
+* mysql_select_db::
+* mysql_shutdown::
+* mysql_stat::
+* mysql_store_result::
+* mysql_thread_id::
+* mysql_use_result::
+@end menu
+
+@node mysql_affected_rows, mysql_close, C API functions, C API functions
+@c German node mysql_affected_rows
+@subsubsection @code{mysql_affected_rows()}
+
+@findex @code{mysql_affected_rows()}
+
+@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt die Anzahl von Zeilen zurück, die durch das letzte @code{UPDATE}
+geändert, durch das letzte @code{DELETE} gelöscht oder durch das letzte
+@code{INSERT} eingefügt wurden. Kann direkt nach @code{mysql_query()}
+aufgerufen werden, bei @code{UPDATE}-, @code{DELETE}- oder
+@code{INSERT}-Statements. Bei @code{SELECT}-Statements funktioniert
+@code{mysql_affected_rows()} wie @code{mysql_num_rows()}.
+
+@subsubheading Rückgabewerte
+
+Eine Ganzzahl größer als 0 gibt die Anzahl von Zeilen an, die betroffen
+oder abgerufen wurden. 0 gibt an, dass keine Datensätze bei einem
+@code{UPDATE}-Statement geändert wurden, keine Zeilen der
+@code{WHERE}-Klausel in der Anfrage entsprachen oder dass bislang keine
+Anfrage ausgeführt wurde. -1 gibt an, dass die Anfrage einen Fehler
+zurückgab oder dass - bei einer @code{SELECT}-Anfrage -
+@code{mysql_affected_rows()} vor @code{mysql_store_result()} aufgerufen
+wurde.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+@example
+mysql_query(&mysql,"UPDATE produkte SET kosten=kosten*1.25 WHERE gruppe=10");
+printf("%ld produkte updated",(long) mysql_affected_rows(&mysql));
+@end example
+
+Wenn man den Flag @code{CLIENT_FOUND_ROWS} angibt, wenn man sich mit
+@code{mysqld} verbindet, gibt @code{mysql_affected_rows()} die Anzahl von
+Zeilen zurück, die mit dem @code{WHERE}-Statement bei
+@code{UPDATE}-Statements übereinstimmten.
+
+Beachten Sie bei der Benutzung des @code{REPLACE}-Befehls, dass
+@code{mysql_affected_rows()} 2 zurückgibt, wenn die neue Zeile eine alte
+Zeile ersetzte. Das liegt daran, dass in diesem Fall eine neue Zeile
+eingefügt und dann das alte Duplikat gelöscht wurde.
+
+
+@node mysql_close, mysql_connect, mysql_affected_rows, C API functions
+@c German node mysql_close
+@subsubsection @code{mysql_close()}
+
+@findex @code{mysql_close()}
+
+@code{void mysql_close(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+Schließt eine vorher geöffnete Verbindung. @code{mysql_close()} gibt auch
+den Verbindungs-Handle frei, der von @code{mysql} zugewiesen wurde, wenn
+der Handle automatisch mit @code{mysql_init()} oder @code{mysql_connect()}
+zugewiesen wurde.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_connect, mysql_change_user, mysql_close, C API functions
+@c German node mysql_connect
+@subsubsection @code{mysql_connect()}
+
+@findex @code{mysql_connect()}
+
+@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)}
+
+@subsubheading Beschreibung
+
+Diese Funktion ist veraltet. Sie sollten statt dessen
+@code{mysql_real_connect()} benutzen.
+
+@code{mysql_connect()} versucht, eine Verbindung zu einer
+MySQL-Datenbankmaschine aufzubauen, die auf @code{host} läuft.
+@code{mysql_connect()} muss erfolgreich beendet werden, bevor Sie irgend
+welche weiteren API-Funktionen aufrufen können, mit Ausnahme von
+@code{mysql_get_client_info()}.
+
+Die Bedeutung der Parameter ist dieselbe wie die entsprechenden Parameter
+bei @code{mysql_real_connect()}, mit dem Unterschied, dass die
+Verbindungsparameter @code{NULL} sein dürfen. In diesem Fall weist die
+C-API automatisch Speicher für die Verbindungsstruktur zu und gibt diesen
+frei, wenn Sie @code{mysql_close()} aufrufen. Der Nachteil dieses Ansatzes
+besteht darin, dass Sie keine Fehlermeldung abrufen können, wenn die
+Verbindung fehlschlägt. (Um Fehlerinformationen von @code{mysql_errno()}
+oder @code{mysql_error()} abrufen zu können, müssen Sie einen gültigen
+@code{MYSQL}-Zeiger angeben.)
+
+@subsubheading Rückgabewerte
+
+Dieselben wie für @code{mysql_real_connect()}.
+
+@subsubheading Fehler
+
+Dieselben wie für @code{mysql_real_connect()}.
+
+
+@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions
+@c German node mysql_change_user
+@subsubsection @code{mysql_change_user()}
+
+@findex @code{mysql_change_user()}
+
+@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const
+char *password, const char *db)}
+
+@subsubheading Beschreibung
+
+Ändert den Benutzer und veranlasst, dass die Datenbank, die mit @code{db}
+angegeben wurde, die vorgabemäßige (aktuelle) Datenbank für die Verbindung
+wird, die durch @code{mysql} festgelegt wurde. In nachfolgenden Anfragen
+ist diese Datenbank die Vorgabe für Tabellenverweise, bei denen nicht
+explizit eine Datenbank angegeben wird.
+
+Diese Funktion wurde in MySQL-Version 3.23.3 eingeführt.
+
+@code{mysql_change_user()} schlägt fehl, wenn sich der Benutzer nicht
+authentifizieren kann oder wenn er keine Zugriffsrechte auf die Datenbank
+hat. In diesem Fall werden Benutzer und Datenbank nicht geändert.
+
+Der @code{db}-Parameter kann auf @code{NULL} gesetzt werden, wenn Sie keine
+vorgabemäßige Datenbank haben wollen.
+
+@subsubheading Rückgabewerte
+
+0 für Erfolg. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+Dieselben, die Sie von @code{mysql_real_connect()} erhalten.
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurde in nicht korrekter Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler ist aufgetreten.
+@item ER_UNKNOWN_COM_ERROR
+Der MySQL-Server hat diesen Befehl nicht implementiert (wahrscheinlich ein
+alter Server).
+@item ER_ACCESS_DENIED_ERROR
+Benutzername oder Passwort sind falsch.
+@item ER_BAD_DB_ERROR
+Die Datenbank existiert nicht.
+@item ER_DBACCESS_DENIED_ERROR
+Der Benutzer hat keine Zugriffsrechte auf die Datenbank.
+@item ER_WRONG_DB_NAME
+Der Datenbankname war zu lang.
+@end table
+
+@subsubheading Beispiel
+
+@example
+if (mysql_change_user(&mysql, "benutzer", "passwort", "neue_datenbank"))
+@{
+ fprintf(stderr, "Änderung des Benutzers fehlgeschlagen. Fehler: %s\n",
+ mysql_error(&mysql));
+@}
+@end example
+
+
+@node mysql_character_set_name, mysql_create_db, mysql_change_user, C API functions
+@c German node mysql_character_set_name
+@subsubsection @code{mysql_character_set_name()}
+
+@findex @code{mysql_character_set_name()}
+
+@code{const char *mysql_character_set_name(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt den vorgabemäßigen Zeichensatz für die aktuelle Verbindung zurück.
+
+@subsubheading Rückgabewerte
+
+Der vorgabemäßige Zeichensatz
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions
+@c German node mysql_create_db
+@subsubsection @code{mysql_create_db()}
+
+@findex @code{mysql_create_db()}
+
+@code{int mysql_create_db(MYSQL *mysql, const char *db)}
+
+@subsubheading Beschreibung
+Erzeugt die Datenbank, die durch den @code{db}-Parameter angegeben wird.
+
+Diese Funktion ist veraltet. Vorzugsweise sollten Sie @code{mysql_query()}
+benutzen, um statt dessen ein SQL-@code{CREATE DATABASE}-Statement
+abzusetzen.
+
+@subsubheading Rückgabewerte
+
+0, wenn die Datenbank erfolgreich erzeugt wurde. Nicht-0, wenn ein Fehler
+auftrat.
+
+@subsubheading Fehler
+@table @code
+
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden in nicht korrekter Reihenfolge ausgeführt.
+
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+@subsubheading Beispiel
+
+@example
+if(mysql_create_db(&mysql, "meine_datenbank"))
+@{
+ fprintf(stderr, "Erzeugung der neuen Datenbank fehlgeschlagen. Fehler: %s\n",
+ mysql_error(&mysql));
+@}
+@end example
+
+
+@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions
+@c German node mysql_data_seek
+@subsubsection @code{mysql_data_seek()}
+
+@findex @code{mysql_data_seek()}
+
+@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)}
+
+@subsubheading Beschreibung
+Sucht bis zu einer beliebigen Zeile in einer Anfrageergebnismenge. Das
+setzt voraus, dass die Ergebnismengenstruktur das gesamte Anfrageergebnis
+enthält. Daher kann @code{mysql_data_seek()} nur in Verbindung mit
+@code{mysql_store_result()} benutzt werden, nicht in Verbindung mit
+@code{mysql_use_result()}.
+
+Der Offset sollte ein Wert im Bereich von 0 bis
+@code{mysql_num_rows(ergebnis)-1} sein.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions
+@c German node mysql_debug
+@subsubsection @code{mysql_debug()}
+
+@findex @code{mysql_debug()}
+
+@code{void mysql_debug(char *debug)}
+
+@subsubheading Beschreibung
+Führt ein @code{DBUG_PUSH} mit der angegebenen Zeichenkette durch.
+@code{mysql_debug()} benutzt die Debug-Bibliothek von Fred Fish. Um diese
+Funktion benutzen zu können, müssen Sie die Client-Bibliothek so
+kompilieren, dass sie Debuggen unterstützt. @xref{Debugging server}.
+@xref{Debugging client}.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+Der unten stehende Aufruf führt dazu, dass die Client-Bibliothek eine
+Trace-Datei in @file{/tmp/client.trace} auf der Client-Maschine erzeugt:
+
+@example
+mysql_debug("d:t:O,/tmp/client.trace");
+@end example
+
+
+@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions
+@c German node mysql_drop_db
+@subsubsection @code{mysql_drop_db()}
+
+@findex @code{mysql_drop_db()}
+
+@code{int mysql_drop_db(MYSQL *mysql, const char *db)}
+
+@subsubheading Beschreibung
+Löscht die Datenbank, die durch den @code{db}-Parameter angegeben wird.
+
+Diese Funktion ist veraltet. Benutzen Sie vorzugsweise
+@code{mysql_query()}, um statt dessen ein SQL-@code{DROP
+DATABASE}-Statement abzusetzen.
+
+@subsubheading Rückgabewerte
+
+0, wenn die Datenbank erfolgreich gelöscht wurde. Nicht-0, wenn ein Fehler
+auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+@subsubheading Beispiel
+
+@example
+if(mysql_drop_db(&mysql, "meine_datenbank"))
+ fprintf(stderr, "Löschen der Datenbank fehlgeschlagen: Fehler: %s\n",
+ mysql_error(&mysql));
+@end example
+
+
+@node mysql_dump_debug_info, mysql_eof, mysql_drop_db, C API functions
+@c German node mysql_dump_debug_info
+@subsubsection @code{mysql_dump_debug_info()}
+
+@findex @code{mysql_dump_debug_info()}
+
+@code{int mysql_dump_debug_info(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Weist den Server an, Debug-Informationen ins Log zu schreiben. Damit das
+funktioniert, muss der verbundene Benutzer die
+@strong{process}-Berechtigung haben.
+
+@subsubheading Rückgabewerte
+
+0, wenn der Befehl erfolgreich war. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions
+@c German node mysql_eof
+@subsubsection @code{mysql_eof()}
+
+@findex @code{mysql_eof()}
+
+@code{my_bool mysql_eof(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Diese Funktion ist veraltet. Benutzen Sie statt dessen @code{mysql_errno()}
+oder @code{mysql_error()}.
+
+@code{mysql_eof()} stellt fest, ob die letzte Zeile einer Ergebnismenge
+gelesen wurde oder nicht.
+
+Wenn Sie eine Ergebnismenge durch einen erfolgreichen Aufruf von
+@code{mysql_store_result()} erhalten, erhält der Client den gesamten Satz
+in einer Operation. In diesem Fall bedeutet eine @code{NULL}-Rückgabe von
+@code{mysql_fetch_row()} immer, dass das Ende der Ergebnismenge erreicht
+wurde und es unnötig ist, @code{mysql_eof()} aufzurufen.
+
+Wenn Sie auf der anderen Seite @code{mysql_use_result()} aufrufen, um den
+Abruf einer Ergebnismenge zu initialisieren, werden die Zeilen des Satzes
+Zeile für Zeile vom Server erlangt, indem Sie @code{mysql_fetch_row()}
+wiederholt aufrufen. Weil während dieses Prozesses ein Verbindungsfehler
+auftreten kann, bedeutet ein @code{NULL}-Rückgabewert von
+@code{mysql_fetch_row()} nicht notwendigerweise, dass das Ende der
+Ergebnismenge auf normale Weise erreicht wurde. In diesem Fall können Sie
+@code{mysql_eof()} benutzen, um festzustellen, was passiert ist.
+@code{mysql_eof()} gibt einen Nicht-0-Wert zurück, wenn das Ende der
+Ergebnismenge erreicht wurde, und 0, wenn ein Fehler auftrat.
+
+Historisch liegt @code{mysql_eof()} vor den Standard-MySQL-Fehlerfunktionen
+@code{mysql_errno()} und @code{mysql_error()}. Weil diese Fehlerfunktionen
+dieselben Informationen zur Verfügung stellen, wird ihre Benutzung des des
+veralteten @code{mysql_eof()} empfohlen. (Sie stellen in der Tat sogar mehr
+Informationen zur Verfügung, weil @code{mysql_eof()} nur einen Bool'schen
+Wert zurückgibt, während die Fehlerfunktionen den Grund angeben, warum der
+Fehler auftrat.)
+
+@subsubheading Rückgabewerte
+
+0, wenn kein Fehler auftrat. Nicht-0, wenn das Ende der Ergebnismenge
+erreicht wurde.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+Folgendes Beispiel zeigt, wie Sie @code{mysql_eof()} benutzen können:
+
+@example
+mysql_query(&mysql,"SELECT * FROM tabelle");
+ergebnis = mysql_use_result(&mysql);
+while((zeile = mysql_fetch_row(ergebnis)))
+@{
+ // Daten verarbeiten usw.
+@}
+if(!mysql_eof(ergebnis)) // mysql_fetch_row() schlug wegen eines Fehlers fehl
+@{
+ fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
+@}
+@end example
+
+Sie können denselben Effekt jedoch auch mit den
+Standard-MySQL-Fehlerfunktionen erreichen:
+
+@example
+mysql_query(&mysql,"SELECT * FROM tabelle");
+result = mysql_use_result(&mysql);
+while((zeile = mysql_fetch_row(ergebnis)))
+@{
+ // Daten verarbeiten usw.
+@}
+if(mysql_errno(&mysql)) // mysql_fetch_row() schlug wegen eines Fehlers fehl
+@{
+ fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
+@}
+@end example
+
+
+@node mysql_errno, mysql_error, mysql_eof, C API functions
+@c German node mysql_errno
+@subsubsection @code{mysql_errno()}
+
+@findex @code{mysql_errno()}
+
+@code{unsigned int mysql_errno(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Für die von @code{mysql} angegebene Verbindung gibt @code{mysql_errno()}
+den Fehlercode für die zuletzt aufgerufene API-Funktion zurück, die
+erfolgreich sein oder fehlschlagen kann. Ein Rückgabewert von 0 bedeutet,
+dass kein Fehler auftrat. Client-Fehlermeldungsnummern sind in der
+MySQL-@file{errmsg.h}-Header-Datei aufgelistet.
+Server-Fehlermeldungsnummern sind in @file{mysqld_error.h} aufgelistet. In
+der MySQL-Quelldistribution finden Sie eine komplette Liste der
+Fehlermeldungen und Fehlernummern in der Datei
+@file{Docs/mysqld_error.txt}.
+
+@subsubheading Rückgabewerte
+
+Ein Fehlercode-Wert. 0, wenn kein Fehler auftrat.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_error, mysql_escape_string, mysql_errno, C API functions
+@c German node mysql_error
+@subsubsection @code{mysql_error()}
+
+@findex @code{mysql_error()}
+
+@code{char *mysql_error(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Für die von @code{mysql} angegebene Verbindung gibt @code{mysql_error()}
+die Fehlermeldung für die zuletzt aufgerufene API-Funktion zurück, die
+erfolgreich sein oder fehlschlagen kann. Eine leere Zeichenkette
+(@code{""}) wird zurückgegeben, wenn kein Fehler auftrat. Das bedeutet,
+dass folgende zwei Tests äquivalent sind:
+
+@example
+if(mysql_errno(&mysql))
+@{
+ // Ein Fehler trat auf
+@}
+
+if(mysql_error(&mysql)[0] != '\0')
+@{
+ // Ein Fehler trat auf
+@}
+@end example
+
+Die Sprache der Client-Fehlermeldungen kann durch erneutes Kompilieren der
+MySQL-Client-Bibliothek geändert werden. Sie können Fehlermeldungen in
+mehreren unterschiedlichen Sprachen auswählen. @xref{Languages}.
+
+@subsubheading Rückgabewerte
+
+Eine Zeichenkette, die den Fehler beschreibt. Eine leere Zeichenkette, wenn
+kein Fehler auftrat.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions
+@c German node mysql_escape_string
+@subsubsection @code{mysql_escape_string()}
+
+@findex @code{mysql_escape_string()}
+
+Statt dessen sollten Sie @code{mysql_real_escape_string()} benutzen!
+
+Das ist identisch mit @code{mysql_real_escape_string()}, ausser dass die
+Verbindung als erstes Argument genommen wird.
+@code{mysql_real_escape_string()} escapet die Zeichenkette gemäß dem
+aktuellen Zeichensatz, wohingegen @code{mysql_escape_string()} die aktuelle
+Zeichensatzeinstellung ignoriert.
+
+
+@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions
+@c German node mysql_fetch_field
+@subsubsection @code{mysql_fetch_field()}
+
+@findex @code{mysql_fetch_field()}
+
+@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Gibt die Definition einer Spalte der Ergebnismenge als
+@code{MYSQL_FIELD}-Struktur zurück. Rufen Sie diese Funktion wiederholt
+auf, um Informationen über alle Spalten in der Ergebnismenge zu erhalten.
+@code{mysql_fetch_field()} gibt @code{NULL} zurück, wenn es keine weiteren
+Felder mehr gibt.
+
+@code{mysql_fetch_field()} wird zurückgesetzt, so dass sie Informationen
+über das erste Feld zurückgibt, und zwar jedes Mal, wenn Sie eine neue
+@code{SELECT}-Anfrage ausführen. Das von @code{mysql_fetch_field()}
+zurückgegebene Feld wird auch durch Aufrufe von @code{mysql_field_seek()}
+betroffen.
+
+Wenn Sie @code{mysql_query()} aufgerufen haben, um ein @code{SELECT} auf
+eine Tabelle auszuführen, aber nicht @code{mysql_store_result()} aufgerufen
+haben, gibt MySQL die vorgabemäßige BLOB-Länge (8 KB) zurück, wenn Sie
+@code{mysql_fetch_field()} aufrufen, um nach der Länge eines
+@code{BLOB}-Felds zu fragen. (Die Größe von 8 KB wird gewählt, weil MySQL
+die maximale Länge des @code{BLOB} nicht kennt. Das wird irgendwann einmal
+konfigurierbar gemacht.) Nachdem Sie die Ergebnismenge erst einmal
+abgerufen haben, enthält @code{field->max_length} die Länge des längsten
+Werts dieser Spalte in der bestimmten Anfrage.
+
+@subsubheading Rückgabewerte
+
+Die @code{MYSQL_FIELD}-Struktur der aktuellen Spalte. @code{NULL}, wenn
+keine Spalten mehr übrig sind.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+@example
+MYSQL_FIELD *field;
+
+while((field = mysql_fetch_field(ergebnis)))
+@{
+ printf("Feldname %s\n", field->name);
+@}
+@end example
+
+
+@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions
+@c German node mysql_fetch_fields
+@subsubsection @code{mysql_fetch_fields()}
+
+@findex @code{mysql_fetch_fields()}
+
+@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Gibt ein Array aller @code{MYSQL_FIELD}-Strukturen für eine Ergebnismenge
+zurück. Jede Struktur stellt Felddefinitionen für eine Spalte der
+Ergebnismenge zur Verfügung.
+
+@subsubheading Rückgabewerte
+
+Ein Array von @code{MYSQL_FIELD}-Strukturen für alle Spalten einer
+Ergebnismenge.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+@example
+unsigned int num_fields;
+unsigned int i;
+MYSQL_FIELD *fields;
+
+num_fields = mysql_num_fields(ergebnis);
+fields = mysql_fetch_fields(ergebnis);
+for(i = 0; i < num_fields; i++)
+@{
+ printf("Feld %u ist %s\n", i, fields[i].name);
+@}
+@end example
+
+
+@node mysql_fetch_field_direct, mysql_fetch_lengths, mysql_fetch_fields, C API functions
+@c German node mysql_fetch_field_direct
+@subsubsection @code{mysql_fetch_field_direct()}
+
+@findex @code{mysql_fetch_field_direct()}
+
+@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int feldnr)}
+
+@subsubheading Beschreibung
+
+Mit der Angabe einer Feldnummer @code{feldnr} für eine Spalte innerhalb
+einer Ergebnismenge gibt sie die Felddefinition dieser Spalte als
+@code{MYSQL_FIELD}-Struktur zurück. Sie können diese Funktion verwenden, um
+die Definition für eine beliebige Spalte abzurufen. Der Wert von
+@code{feldnr} sollte im Bereich von 0 bis
+@code{mysql_num_fields(ergebnis)-1} liegen.
+
+@subsubheading Rückgabewerte
+
+Die @code{MYSQL_FIELD}-Struktur für die angegebene Spalte.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+@example
+unsigned int num_fields;
+unsigned int i;
+MYSQL_FIELD *field;
+
+num_fields = mysql_num_fields(ergebnis);
+for(i = 0; i < num_fields; i++)
+@{
+ field = mysql_fetch_field_direct(ergebnis, i);
+ printf("Feld %u ist %s\n", i, field->name);
+@}
+@end example
+
+
+@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions
+@c German node mysql_fetch_lengths
+@subsubsection @code{mysql_fetch_lengths()}
+
+@findex @code{mysql_fetch_lengths()}
+
+@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Gibt die Länge der Spalten der aktuellen Zeile innerhalb der Ergebnismenge
+zurück. Wenn Sie vorhaben, Feldwerte zu kopieren, sind diese
+Längeninformationen auch nützlich für Optimierungen, weil Sie vermeiden
+können, @code{strlen()} aufzurufen. Wenn die Ergebnismenge Binärdaten
+enthält, kommt hinzu, dass Sie diese Funktion benutzen @emph{müssen}, um
+die Größe der Daten zu bestimmen, weil @code{strlen()} falsche Ergebnisse
+für Felder zurückgibt, die NULL-Zeichen enthalten.
+
+Die Länge leerer Spalten und von Spalten, die @code{NULL}-Werte enthalten,
+ist 0. Um zu sehen, wie man diese beiden Fälle auseinander hält, sehen Sie
+in der Beschreibung von @code{mysql_fetch_row()} nach.
+
+@subsubheading Rückgabewerte
+
+Ein Array vorzeichenloser langer Ganzzahlen (long integer), die die Größe
+jeder Spalte darstellen (ohne irgend welche begrenzenden NULL-Zeichen).
+@code{NULL}, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@code{mysql_fetch_lengths()} ist nur für die aktuelle Zeile der
+Ergebnismenge gültig. Sie gibt @code{NULL} zurück, wenn Sie sie vor
+@code{mysql_fetch_row()} oder nach dem Abruf aller Zeilen im Ergebnis
+aufrufen.
+
+@subsubheading Beispiel
+
+@example
+MYSQL_ROW zeile;
+unsigned long *laengen;
+unsigned int anzahl_felder;
+unsigned int i;
+
+zeile = mysql_fetch_row(ergebnis);
+if (zeile)
+@{
+ anzahl_felder = mysql_num_fields(ergebnis);
+ laengen = mysql_fetch_lengths(ergebnis);
+ for(i = 0; i < anzahl_felder; i++)
+ @{
+ printf("Spalte %u ist %lu Bytes lang.\n", i, lengths[i]);
+ @}
+@}
+@end example
+
+
+@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions
+@c German node mysql_fetch_row
+@subsubsection @code{mysql_fetch_row()}
+
+@findex @code{mysql_fetch_row()}
+
+@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Ruft die nächste Zeile einer Ergebnismenge ab. Wenn sie nach
+@code{mysql_store_result()} benutzt wird, gibt @code{mysql_fetch_row()}
+@code{NULL} zurück, wenn es keine weiteren Zeilen zum Abruf mehr gibt. Wenn
+sie nach @code{mysql_use_result()} benutzt wird, gibt
+@code{mysql_fetch_row()} @code{NULL} zurück, wenn es keine Zeilen mehr zum
+Abruf gibt oder wenn ein Fehler auftrat.
+
+Die Anzahl von Werten in der Zeile wird durch
+@code{mysql_num_fields(ergebnis)} gegeben. Wenn @code{zeile} den
+Rückgabewert eines Aufrufs von @code{mysql_fetch_row()} enthält, wird auf
+Zeiger auf die Werte als @code{zeile[0]} bis
+@code{zeile[mysql_num_fields(ergebnis)-1]} zugegriffen. @code{NULL}-Werte
+in der Zeile werden durch @code{NULL}-Zeiger angezeigt.
+
+Die Längen der Feldwerte in der Zeile können durch Aufruf von
+@code{mysql_fetch_lengths()} bestimmt werden. Leere Felder und Felder, die
+@code{NULL} enthalten, haben beide die Länge 0. Sie können diese
+auseinanderhalten, indem Sie den Zeiger für den Feldwert überprüfen. Wenn
+der Zeiger @code{NULL} ist, ist das Feld @code{NULL}, ansonsten ist das
+Feld leer.
+
+@subsubheading Rückgabewerte
+
+Eine @code{MYSQL_ROW}-Struktur für die nächste Zeile. @code{NULL}, wenn
+keine weiteren Zeilen abzurufen sind oder wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+@subsubheading Beispiel
+
+@example
+MYSQL_ROW zeile;
+unsigned int anzahl_felder;
+unsigned int i;
+
+anzahl_felder = mysql_num_fields(ergebnis);
+while ((zeile = mysql_fetch_row(ergebnis)))
+@{
+ unsigned long *laengen;
+ laengen = mysql_fetch_lengths(ergebnis);
+ for(i = 0; i < anzahl_felder; i++)
+ @{
+ printf("[%.*s] ", (int) laengen[i], zeile[i] ? zeile[i] : "NULL");
+ @}
+ printf("\n");
+@}
+@end example
+
+
+@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions
+@c German node mysql_field_count
+@subsubsection @code{mysql_field_count()}
+
+@findex @code{mysql_field_count()}
+
+@code{unsigned int mysql_field_count(MYSQL *mysql)}
+
+Wenn Sie eine Version von MySQL vor Version 3.22.24 benutzen, sollten Sie
+statt dessen @code{unsigned int mysql_num_fields(MYSQL *mysql)} benutzen.
+
+@subsubheading Beschreibung
+
+Gibt die Anzahl von Spalten der letzten Anfrage auf der Verbindung zurück.
+
+Normalerweise wird diese Funktion benutzt, wenn @code{mysql_store_result()}
+@code{NULL} zurückgab (und Sie daher keinen Ergebnismengen-Zeiger haben).
+In diesem Fall können Sie @code{mysql_field_count()} aufrufen, um
+festzustellen, ob @code{mysql_store_result()} ein leeres Ergebnis hätte
+zurückgeben sollen oder nicht. Das gestattet dem Client-Programm, die
+richtigen Aktionen zu ergreifen, ohne wissen zu müssen, ob die Anfrage ein
+@code{SELECT} war oder nicht (oder ein @code{SELECT}-ähnliches Statement).
+Das unten stehende Beispiel zeigt, wie man das machen kann.
+
+@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.
+
+@subsubheading Rückgabewerte
+
+Eine vorzeichenlose Ganzzahl, die die Anzahl von Feldern in einer
+Ergebnismenge darstellt.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+@example
+MYSQL_RES *result;
+unsigned int anzahl_felder;
+unsigned int anzahl_zeilen;
+
+if (mysql_query(&mysql,anfrage))
+@{
+ // FEHLER
+@}
+else // Anfrage war erfolgreich, zurückgegebene Daten verarbeiten
+@{
+ ergebnis = mysql_store_result(&mysql);
+ if (ergebnis) // Es gibt Zeilen
+ @{
+ anzahl_felder = mysql_num_fields(ergebnis);
+ // Zeilen abrufen, dann mysql_free_result(result) aufrufen
+ @}
+ else // mysql_store_result() gab nichts zurück, hätte es etwas zurückgeben sollen?
+ @{
+ if(mysql_field_count(&mysql) == 0)
+ @{
+ // Anfrage gibt keine Daten zurück
+ // (Anfrage war kein SELECT)
+ anzahl_zeilen = mysql_affected_rows(&mysql);
+ @}
+ else // mysql_store_result() hätte Daten zurückgeben sollen
+ @{
+ fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
+ @}
+ @}
+@}
+@end example
+
+Eine Alternative besteht darin, den @code{mysql_field_count(&mysql)}-Aufruf
+durch @code{mysql_errno(&mysql)} zu ersetzen. In diesem Fall überprüfen Sie
+direkt auf einen Fehler von @code{mysql_store_result()}, statt aus dem Wert
+von @code{mysql_field_count()} zu schlussfolgern, ob das Statement ein
+@code{SELECT} war oder nicht.
+
+
+@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions
+@c German node mysql_field_seek
+@subsubsection @code{mysql_field_seek()}
+
+@findex @code{mysql_field_seek()}
+
+@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)}
+
+@subsubheading Beschreibung
+
+Setzt den Feldcursor auf den angegebenen Offset. Der nächste Aufruf von
+@code{mysql_fetch_field()} ruf die Felddefinition der Spalte ab, die mit
+diesem Offset verknüpft ist.
+
+Um bis zum Anfang einer Zeile zu suchen, geben Sie einen @code{offset}-Wert
+von 0 an.
+
+@subsubheading Rückgabewerte
+
+Der vorherige Wert des Feldcursors.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions
+@c German node mysql_field_tell
+@subsubsection @code{mysql_field_tell()}
+
+@findex @code{mysql_field_tell()}
+
+@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Gibt die Position des Feldcursors für die letzte @code{mysql_fetch_field()}
+zurück. Dieser Wert kann als Argument für @code{mysql_field_seek()} benutzt
+werden.
+
+@subsubheading Rückgabewerte
+
+Der aktuelle Offset des Feldcursors.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions
+@c German node mysql_free_result
+@subsubsection @code{mysql_free_result()}
+
+@findex @code{mysql_free_result()}
+
+@code{void mysql_free_result(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Gibt den Speicher frei, der für eine Ergebnismenge von
+@code{mysql_store_result()}, @code{mysql_use_result()},
+@code{mysql_list_dbs()} usw. zugewiesen wurde. Wenn Sie mit einer
+Ergebnismenge fertig sind, müssen Sie den von ihr benutzten Speicher durch
+Aufruf von @code{mysql_free_result()} freigeben.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_get_client_info, mysql_get_host_info, mysql_free_result, C API functions
+@c German node mysql_get_client_info
+@subsubsection @code{mysql_get_client_info()}
+
+@findex @code{mysql_get_client_info()}
+
+@code{char *mysql_get_client_info(void)}
+
+@subsubheading Beschreibung
+
+Returns a string that represents the client Bibliothek version.
+
+@subsubheading Rückgabewerte
+
+A character string that represents the MySQL-Client Bibliothek version.
+
+@subsubheading Fehler
+Keine.
+
+
+@node mysql_get_host_info, mysql_get_proto_info, mysql_get_client_info, C API functions
+@c German node mysql_get_host_info
+@subsubsection @code{mysql_get_host_info()}
+
+@findex @code{mysql_get_host_info()}
+
+@code{char *mysql_get_host_info(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt eine Zeichenkette zurück, die den Typ der benutzten Verbindung
+beschreibt, inklusive des Server-Hostnamens.
+
+@subsubheading Rückgabewerte
+
+Eine Zeichenkette, die den Server-Hostnamen und den Verbindungstyp
+bezeichnet.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_get_proto_info, mysql_get_server_info, mysql_get_host_info, C API functions
+@c German node mysql_get_proto_info
+@subsubsection @code{mysql_get_proto_info()}
+
+@findex @code{mysql_get_proto_info()}
+
+@code{unsigned int mysql_get_proto_info(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt die Protokollversion zurück, die von der aktuellen Verbindung benutzt
+wird.
+
+@subsubheading Rückgabewerte
+
+Eine vorzeichenlose Ganzzahl, die die Protokollversion bezeichnet, die von
+der aktuellen Verbindung benutzt wird.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_get_server_info, mysql_info, mysql_get_proto_info, C API functions
+@c German node mysql_get_server_info
+@subsubsection @code{mysql_get_server_info()}
+
+@findex @code{mysql_get_server_info()}
+
+@code{char *mysql_get_server_info(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt eine Zeichenkette zurück, die die Server-Versionsnummer bezeichnet.
+
+@subsubheading Rückgabewerte
+
+Eine Zeichenkette, die die Server-Versionsnummer bezeichnet.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_info, mysql_init, mysql_get_server_info, C API functions
+@c German node mysql_info
+@subsubsection @code{mysql_info()}
+
+@findex @code{mysql_info()}
+
+@code{char *mysql_info(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Ruft eine Zeichenkette ab, die Informationen über die zuletzt ausgeführte
+Anfrage zurückgibt, aber nur für die unten aufgeführten Statements. Bei
+anderen Statements gibt @code{mysql_info()} @code{NULL} zurück. Das Format
+der Zeichenkette variiert in Abhängigkeit vom Anfragetyp, wie unten
+beschrieben. Die Nummern dienen nur der Veranschaulichung; die Zeichenkette
+enthält die der Anfrage entsprechenden Werte.
+
+@table @code
+@item INSERT INTO ... SELECT ...
+Zeichenkettenformat: @code{Records: 100 Duplicates: 0 Warnings: 0}
+@item INSERT INTO ... VALUES (...),(...),(...)...
+Zeichenkettenformat: @code{Records: 3 Duplicates: 0 Warnings: 0}
+@item LOAD DATA INFILE ...
+Zeichenkettenformat: @code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0}
+@item ALTER TABLE
+Zeichenkettenformat: @code{Records: 3 Duplicates: 0 Warnings: 0}
+@item UPDATE
+Zeichenkettenformat: @code{Rows matched: 40 Changed: 40 Warnings: 0}
+@end table
+
+Beachten Sie, dass @code{mysql_info()} einen Nicht-@code{NULL}-Wert für das
+@code{INSERT ... VALUES}-Statement nur dann zurückgibt, wenn im Statement
+mehrfache Wertlisten angegeben sind.
+
+@subsubheading Rückgabewerte
+
+Eine Zeichenkette, die zusätzliche Informationen über die zuletzt
+ausgeführte Anfrage bereitstellt. @code{NULL}, wenn für die Anfrage keine
+Information verfügbar ist.
+
+@subsubheading Fehler
+Keine.
+
+
+@node mysql_init, mysql_insert_id, mysql_info, C API functions
+@c German node mysql_init
+@subsubsection @code{mysql_init()}
+
+@findex @code{mysql_init()}
+
+@code{MYSQL *mysql_init(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Alloziert oder initialisiert ein @code{MYSQL}-Objekt, das für
+@code{mysql_real_connect()} geeignet ist. Wenn @code{mysql} ein
+@code{NULL}-Zeiger ist, alloziert, initialisiert und gibt diese Funktion
+ein neues Objekt zurück. Ansonsten wird das Objekt initialisiert und die
+Adresse des Objekts zurückgegeben. Wenn @code{mysql_init()} ein neues
+Objekt alloziert, wird es freigegeben, wenn @code{mysql_close()} aufgerufen
+wird, um die Verbindung zu schließen.
+
+@subsubheading Rückgabewerte
+
+Ein initialisiertes @code{MYSQL*}-Handle. @code{NULL}, wenn der Speicher
+nicht ausreichte, um ein neues Objekt zu allozieren.
+
+@subsubheading Fehler
+
+Im Falle von ungenügendem Speicher wird @code{NULL} zurückgegeben.
+
+
+@node mysql_insert_id, mysql_kill, mysql_init, C API functions
+@c German node mysql_insert_id
+@subsubsection @code{mysql_insert_id()}
+
+@findex @code{mysql_insert_id()}
+
+@code{my_ulonglong mysql_insert_id(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt die Kennung zurück, die für eine @code{AUTO_INCREMENT}-Spalte durch
+die vorherige Anfrage erzeugt wurde. Benutzen Sie diese Funktion, nachdem
+Sie eine @code{INSERT}-Anfrage für eine Tabelle durchgeführt haben, die ein
+@code{AUTO_INCREMENT}-Feld enthält.
+
+Beachten Sie, dass @code{mysql_insert_id()} @code{0} zurückgibt, wenn die
+vorherige Anfrage keinen @code{AUTO_INCREMENT}-Wert erzeugt hat. Wenn Sie
+den Wert für spätere Benutzung speichern wollen, stellen Sie sicher, dass
+Sie @code{mysql_insert_id()} unmittelbar nach der Anfrage aufrufen, die den
+Wert erzeugt.
+
+@code{mysql_insert_id()} wird nach @code{INSERT}- und
+@code{UPDATE}-Statements aktualisiert, die einen @code{AUTO_INCREMENT}-Wert
+erzeugen oder einen Spaltenwert auf @code{LAST_INSERT_ID(ausdruck)} setzen.
+@xref{Miscellaneous functions}.
+
+Beachten Sie auch, dass der Wert der SQL-@code{LAST_INSERT_ID()}-Funktion
+immer den aktuellsten erzeugten @code{AUTO_INCREMENT}-Wert enthält, und
+zwischen Anfragen nicht zurückgesetzt wird, weil der Wert dieser Funktion
+im Server gewartet wird.
+
+@subsubheading Rückgabewerte
+
+Der Wert des @code{AUTO_INCREMENT}-Felds, das durch die vorherige Anfrage
+aktualisiert wurde. Gibt 0 zurück, wenn es keine vorherige Anfrage auf der
+Verbindung gab oder wenn die Anfrage keinen @code{AUTO_INCREMENT}-Wert
+aktualisierte.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions
+@c German node mysql_kill
+@subsubsection @code{mysql_kill()}
+
+@findex @code{mysql_kill()}
+
+@code{int mysql_kill(MYSQL *mysql, unsigned long pid)}
+
+@subsubheading Beschreibung
+
+Bittet den Server, den Thread zu töten, der durch @code{pid} angegeben
+wurde.
+
+@subsubheading Rückgabewerte
+
+0 für Erfolg. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions
+@c German node mysql_list_dbs
+@subsubsection @code{mysql_list_dbs()}
+
+@findex @code{mysql_list_dbs()}
+
+@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)}
+
+@subsubheading Beschreibung
+
+Gibt eine Ergebnismenge zurück, die aus den Datenbanknamen auf dem Server
+besteht, die mit dem einfachen regulären Ausdruck übereinstimmen, der durch
+den @code{wild}-Parameter angegeben wird. @code{wild} darf die
+Platzhalterzeichen @samp{%} oder @samp{_} enthalten oder ein
+@code{NULL}-Zeiger sein, der mit allen Datenbanken übereinstimmt. Der
+Aufruf von @code{mysql_list_dbs()} ist ähnlich der Ausführung der Anfrage
+@code{SHOW DATABASES [LIKE wild]}.
+
+Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.
+
+@subsubheading Rückgabewerte
+
+Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein
+Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_OUT_OF_MEMORY
+Kein Speicher mehr.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions
+@c German node mysql_list_fields
+@subsubsection @code{mysql_list_fields()}
+
+@findex @code{mysql_list_fields()}
+
+@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)}
+
+@subsubheading Beschreibung
+
+Gibt eine Ergebnismenge zurück, die aus Feldnamen in der angegebenen
+Tabelle bestehen, die mit einem einfachen regulären Ausdruck
+übereinstimmen, der durch den @code{wild}-Parameter angegeben wird.
+@code{wild} darf die Platzhalterzeichen @samp{%} oder @samp{_} enthalten
+oder ein @code{NULL}-Zeiger sein, der mit allen Datenbanken übereinstimmt.
+Der Aufruf von @code{mysql_list_fields()} ist ähnlich der Ausführung der
+Anfrage @code{SHOW COLUMNS FROM tabelle [LIKE wild]}.
+
+Beachten Sie, dass empfohlen wird, @code{SHOW COLUMNS FROM tabelle} statt
+@code{mysql_list_fields()} zu benutzen.
+
+Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.
+
+@subsubheading Rückgabewerte
+
+Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions
+@c German node mysql_list_processes
+@subsubsection @code{mysql_list_processes()}
+
+@findex @code{mysql_list_processes()}
+
+@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt eine Ergebnismenge zurück, die die aktuellen Server-Threads
+beschreibt. Das ist dieselbe Art von Information, die von @code{mysqladmin
+processlist} oder einer @code{SHOW PROCESSLIST}-Anfrage zur Verfügung
+gestellt wird.
+
+Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.
+
+@subsubheading Rückgabewerte
+
+Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein
+Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions
+@c German node mysql_list_tables
+@subsubsection @code{mysql_list_tables()}
+
+@findex @code{mysql_list_tables()}
+
+@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)}
+
+@subsubheading Beschreibung
+
+Gibt eine Ergebnismenge zurück, die aus Tabellennamen in der aktuellen
+Datenbank besteht, die mit einem einfachen regulären Ausdruck
+übereinstimmen, der durch den @code{wild}-Parameter angegeben wird.
+@code{wild} darf die Platzhalterzeichen @samp{%} oder @samp{_} enthalten
+oder ein @code{NULL}-Zeiger sein, der mit allen Tabellen übereinstimmt. Der
+Aufruf von @code{mysql_list_tables()} ist ähnlich der Ausführung der
+Anfrage @code{SHOW tables [LIKE wild]}.
+
+Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.
+
+@subsubheading Rückgabewerte
+
+Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_num_fields, mysql_num_rows, mysql_list_tables, C API functions
+@c German node mysql_num_fields
+@subsubsection @code{mysql_num_fields()}
+
+@findex @code{mysql_num_fields()}
+@findex @code{mysql_field_count()}
+
+@code{unsigned int mysql_num_fields(MYSQL_RES *result)}
+
+oder
+
+@code{unsigned int mysql_num_fields(MYSQL *mysql)}
+
+Die zweite Form funktioniert nicht bei MySQL-Version 3.22.24 oder neuer. Um
+ein @code{MYSQL*}-Argument zu übergeben, müssen Sie statt dessen
+@code{unsigned int mysql_field_count(MYSQL *mysql)} benutzen.
+
+@subsubheading Beschreibung
+
+Gibt die Anzahl von Spalten in einer Ergebnismenge zurück.
+
+Beachten Sie, dass Sie die Anzahl von Spalten entweder durch einen Zeiger
+auf die Ergebnismenge oder auf ein Verbindungs-Handle erhalten. Das
+Verbindungs-Handle benutzen Sie, wenn @code{mysql_store_result()} oder
+@code{mysql_use_result()} @code{NULL} zurückgibt (und Sie daher keinen
+Ergebnismengen-Zeiger haben). In diesem Fall können Sie
+@code{mysql_field_count()} aufrufen, um festzustellen, ob
+@code{mysql_store_result()} eine leere Ergebnismenge produziert haben
+sollte oder nicht. Das erlaubt dem Client-Programm, die korrekten Aktionen
+vorzunehmen, ohne wissen zu müssen, ob die Anfrage ein @code{SELECT}- (oder
+@code{SELECT}-ähnliches) Statement war oder nicht. Das unten stehende
+Beispiel zeigt, wie das gemacht wird.
+
+@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.
+
+@subsubheading Rückgabewerte
+
+Eine vorzeichenlose Ganzzahl, die die Anzahl von Feldern in einer
+Ergebnismenge darstellt.
+
+@subsubheading Fehler
+
+Keine.
+
+@subsubheading Beispiel
+
+@example
+MYSQL_RES *ergebnis;
+unsigned int anzahl_felder;
+unsigned int anzahl_zeilen;
+
+if (mysql_query(&mysql,anfrage_zeichenkette))
+@{
+ // FEHLER
+@}
+else // Anfrage erfolgreich, zurückgegebene Daten verarbeiten
+@{
+ ergebnis = mysql_store_result(&mysql);
+ if (ergebnis) // Es gibt Zeilen
+ @{
+ anzahl_felder = mysql_num_fields(ergebnis);
+ // Zeilen abrufen, dann mysql_free_result(ergebnis) aufrufen
+ @}
+ else // mysql_store_result() gab nichts zurück, hätte es das tun sollen?
+ @{
+ if (mysql_errno(&mysql))
+ @{
+ fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
+ @}
+ else if (mysql_field_count(&mysql) == 0)
+ @{
+ // Anfrage gibt keine Daten zurück
+ // (war kein SELECT)
+ anzahl_zeilen = mysql_affected_rows(&mysql);
+ @}
+ @}
+@}
+@end example
+
+Eine Alternative (wenn Sie WISSEN, dass Ihre Anfrage eine Ergebnismenge
+hätte zurückgeben sollen) ist es, den @code{mysql_errno(&mysql)}-Aufruf
+durch eine Prüfung zu ersetzen, ob @code{mysql_field_count(&mysql)} gleich
+0 ist. Das passiert nur, wenn etwas schief lief.
+
+
+@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions
+@c German node mysql_num_rows
+@subsubsection @code{mysql_num_rows()}
+
+@findex @code{mysql_num_rows()}
+
+@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)}
+
+@subsubheading Beschreibung
+
+Gibt die Anzahl von Zeilen in der Ergebnismenge zurück.
+
+Die Benutzung von @code{mysql_num_rows()} hängt davon ab, ob Sie
+@code{mysql_store_result()} oder @code{mysql_use_result()} benutzen, um die
+Ergebnismenge zurückzugeben.. Wenn Sie @code{mysql_store_result()}
+benutzen, kann @code{mysql_num_rows()} unmittelbar aufgerufen werden. Wenn
+Sie @code{mysql_use_result()} benutzen, gibt @code{mysql_num_rows()} nicht
+den richtigen Wert zurück, bis alle Zeilen in der Ergebnismenge abgerufen
+wurden.
+
+@subsubheading Rückgabewerte
+
+Die Anzahl von Zeilen in der Ergebnismenge.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_options, mysql_ping, mysql_num_rows, C API functions
+@c German node mysql_options
+@subsubsection @code{mysql_options()}
+
+@findex @code{mysql_options()}
+
+@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)}
+
+@subsubheading Beschreibung
+
+Kann benutzt werden, um zusätzliche Optionen zu setzen und das Verhalten
+einer Verbindung zu beeinflussen. Diese Funktion kann mehrfach aufgerufen
+werden, um mehrere Optionen zu setzen.
+
+@code{mysql_options()} sollte nach @code{mysql_init()} und vor
+@code{mysql_connect()} oder @code{mysql_real_connect()} aufgerufen werden.
+
+Das @code{option}-Argument ist die Option, die Sie setzen wollen. Das
+@code{arg}-Argument ist der Wert für die Option. Wenn die Option eine
+Ganzzahl ist, sollte @code{arg} auf den Wert der Ganzzahl zeigen.
+
+Mögliche Optionswerte:
+
+@multitable @columnfractions .25 .25 .5
+@item @strong{Option} @tab @strong{Argumenttyp} @tab @strong{Funktion}
+@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Verbindungszeitüberschreitung (Timeout) in Sekunden.
+@item @code{MYSQL_OPT_COMPRESS} @tab Unbenutzt @tab Das komprimierte Client-/Server-Protokoll verwenden.
+@item @code{MYSQL_OPT_NAMED_PIPE} @tab Unbenutzt @tab Named Pipes benutzen, um sich mit einem MySQL-Server unter NT zu verbinden.
+@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Befehl, der beim Verbinden mit dem MySQL-Server ausgeführt werden soll. Wird beim erneuten Verbinden automatisch wieder ausgeführt.
+@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Optionen aus der benannten Optionsdatei einlesen anstelle von @file{my.cnf}.
+@item @code{MYSQL_READ_DEFAULT_GROUP} @tab @code{char *} @tab Optionen aus der benannten Gruppe von @file{my.cnf} oder der Datei einlesen, die durch @code{MYSQL_READ_DEFAULT_FILE} angegeben wurde.
+@end multitable
+
+Beachten Sie, dass die Gruppe @code{client} immer gelesen wird, wenn Sie
+@code{MYSQL_READ_DEFAULT_FILE} oder @code{MYSQL_READ_DEFAULT_GROUP}
+benutzen.
+
+Die angegebene Gruppe in der Optionsdatei kann folgende Optionen enthalten:
+
+@multitable @columnfractions .3 .7
+@item @code{connect_timeout} @tab Zeitüberschreitung (Timeout) für die
+Verbindung in Sekunden. Unter Linux wird dieser Wert zusätzlich für die
+Wartezeit auf die erste Antwort vom Server benutzt.
+@item @code{compress} @tab Das komprimierte Client-/Server-Protokoll
+benutzen.
+@item @code{database} @tab Mit dieser Datenbank verbinden, wenn im
+Verbindungsbefehl keine Datenbank angegeben wurde.
+@item @code{debug} @tab Debug-Optionen.
+@item @code{host} @tab Vorgabemäßiger Hostname.
+@item @code{init-commund} @tab Befehl, der bei der Verbindung zum
+MySQL-Server ausgeführt wird. Wird automatisch beim erneuten Verbinden
+erneut ausgeführt.
+@item @code{interactive-timeout} @tab Dasselbe wie die Angabe von
+@code{CLIENT_INTERACTIVE} für @code{mysql_real_connect()}.
+@xref{mysql_real_connect}.
+@item @code{password} @tab Vorgabemäßiges Passwort.
+@item @code{pipe} @tab Named Pipes benutzen, um sich mit einem MySQL-Server unter NT zu verbinden.
+@item @code{port} @tab Vorgabemäßige Port-Nummer.
+@item @code{return-found-rows} @tab Weist @code{mysql_info()} an, gefundene
+Zeilen anstelle von aktualisierten Zeilen zurückzugeben, wenn @code{UPDATE}
+benutzt wird.
+@item @code{socket} @tab Vorgabemäßige Socket-Nummer.
+@item
+@item @code{user} @tab Vorgabemäßiger Benutzer.
+@end multitable
+
+Beachten Sie, dass @code{timeout} durch @code{connect_timeout} ersetzt
+wurde. Dennoch wird @code{timeout} noch für eine Weile funktionieren.
+
+Weitere Informationen über Optionsdateien finden Sie unter
+@ref{Option files}.
+
+@subsubheading Rückgabewerte
+
+0 bei Erfolg. Nicht-0, wenn Sie eine unbekannte Option verwenden.
+
+@subsubheading Beispiel
+
+@example
+MYSQL mysql;
+
+mysql_init(&mysql);
+mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
+mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
+if (!mysql_real_connect(&mysql,"host","benutzer","passwort","datenbank",0,NULL,0))
+@{
+ fprintf(stderr, "Keine Verbindung zur Datenbank: Fehler: %s\n",
+ mysql_error(&mysql));
+@}
+@end example
+
+Im obigen Beispiel wird der Client angewiesen, das komprimierte
+Client-/Server-Protokoll zu benutzen und zusätzliche Optionen aus dem
+@code{odbc}-Abschnitt in @code{my.cnf} zu lesen.
+
+
+@node mysql_ping, mysql_query, mysql_options, C API functions
+@c German node mysql_ping
+@subsubsection @code{mysql_ping()}
+
+@findex @code{mysql_ping()}
+
+@code{int mysql_ping(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Prüft, ob die Verbindung zum Server funktioniert oder nicht. Wenn diese weg
+ist, wird automatisch eine erneute Verbindung versucht.
+
+Diese Funktion kann von Clients benutzt werden, die für lange Zeit im
+Leerlauf laufen, um zu prüfen, ob der Server die Verbindung geschlossen
+hat, und sich bei Bedarf erneut zu verbinden.
+
+@subsubheading Rückgabewerte
+
+0, wenn der Server da ist. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_query, mysql_real_connect, mysql_ping, C API functions
+@c German node mysql_query
+@subsubsection @code{mysql_query()}
+
+@findex @code{mysql_query()}
+
+@code{int mysql_query(MYSQL *mysql, const char *anfrage)}
+
+@subsubheading Beschreibung
+Führt die SQL-Anfrage aus, auf die durch die NULL-begrenzte Zeichenkette
+@code{anfrage} gezeigt wird. Die Anfrage muss aus einem einzelnen
+SQL-Statement bestehen. Sie dürfen kein Semikolon (@samp{;}) oder @code{\g}
+zum Statement hinzufügen.
+
+@code{mysql_query()} kann nicht für Anfragen benutzt werden, die Binärdaten
+enthalten. Hierfür sollten Sie statt dessen @code{mysql_real_query()}
+benutzen. (Binärdaten können das @samp{\0}-Zeichen enthalten, was
+@code{mysql_query()} als Ende der Anfrage-Zeichenkette interpretiert.)
+
+Wenn Sie wissen wollen, ob die Anfrage eine Ergebnismenge zurückgeben
+sollte oder nicht, können Sie @code{mysql_field_count()} benutzen, um
+hierauf zu prüfen. @xref{mysql_field_count, , @code{mysql_field_count}}.
+
+@subsubheading Rückgabewerte
+
+0, wenn die Anfrage erfolgreich war. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions
+@c German node mysql_real_connect
+@subsubsection @code{mysql_real_connect()}
+
+@findex @code{mysql_real_connect()}
+
+@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
+ const char *user, const char *passwd, const char *db,
+ unsigned int port, const char *unix_socket,
+ unsigned int client_flag)}
+
+@subsubheading Beschreibung
+
+@code{mysql_real_connect()} versucht, eine Verbindung zu einer
+MySQL-Datenbankmaschine aufzubauen, die auf @code{host} läuft.
+@code{mysql_real_connect()} muss erfolgreich verlaufen sein, bevor Sie
+irgend eine andere API-Funktion ausführen können, mit Ausnahme von
+@code{mysql_get_client_info()}.
+
+Die Parameter werden wie folgt angegeben:
+
+@itemize @bullet
+@item
+Der erste Parameter sollte die Adresse einer existierenden
+@code{MYSQL}-Struktur sein. Vor dem Aufruf von @code{mysql_real_connect()}
+müssen Sie @code{mysql_init()} aufrufen, um die @code{MYSQL}-Struktur zu
+initialisieren. Sie können viele der Verbindungsoptionen mit dem
+@code{mysql_options()}-Aufruf ändern. @xref{mysql_options}.
+
+@item
+Der Wert von @code{host} kann entweder ein Hostname oder eine IP-Adresse
+sein. Wenn @code{host} @code{NULL} oder die Zeichenkette @code{"localhost"}
+ist, wird eine Verbindung zum lokalen Host angenommen. Wenn das
+Betriebssystem Sockets (Unix) oder Named Pipes (Windows NT) unterstützt,
+werden diese statt TCP/IP benutzt, um sich mit dem Server zu verbinden.
+
+@item
+Der @code{user}-Parameter enthält die MySQL-Login-Benutzerkennung. Wenn
+@code{user} @code{NULL} ist, wird der aktuelle Benutzer angenommen. Unter
+Unix ist das der aktuelle Login-Name. Unter Windows-ODBC muss der aktuelle
+Benutzername explizit angegeben werden. @xref{ODBC administrator}.
+
+@item
+Der @code{passwd}-Parameter enthält das Passwort für @code{user}. Wenn
+@code{passwd} @code{NULL} ist, werden nur Einträge in der
+@code{user}-Tabelle für Benutzer auf Übereinstimmung überprüft, die ein
+leeres Passwort-Feld haben. Das erlaubt dem Datenbank-Administrator, das
+MySQL-Berechtigungssystem so einzurichten, dass Benutzer unterschiedliche
+Berechtigungen haben, je nachdem, ob sie ein Passwort angegeben haben oder
+nicht.
+
+HINWEIS: Versuchen Sie nicht, dass Passwort zu verschlüsseln, bevor Sie
+@code{mysql_real_connect()} aufrufen. Die Passwortverschlüsselung wird
+automatisch durch die Client-API gehandhabt.
+
+@item
+@code{db} ist der Datenbankname. Wenn @code{db} nicht @code{NULL} ist,
+wird die vorgabemäßige Datenbank für die Verbindung auf diesen Wert
+gesetzt.
+
+@item
+Wenn @code{port} nicht 0 ist, wird dieser Wert als Port-Nummer für die
+TCP/IP-Verbindung benutzt. Beachten Sie, dass der @code{host}-Parameter den
+Verbindungstyp festlegt.
+
+@item
+Wenn @code{unix_socket} nicht @code{NULL} ist, legt die Zeichenkette den
+Socket oder die Named Pipe fest, die benutzt werden sollen. Beachten Sie,
+dass der @code{host}-Parameter den Verbindungstyp festlegt.
+
+@item
+Der Wert von @code{client_flag} ist üblicherweise 0, kann aber unter sehr
+speziellen Umständen auf eine Kombination folgender Flags gesetzt werden:
+
+@multitable @columnfractions .25 .7
+@item @strong{Flag-Name} @tab @strong{Flag-Bedeutung}
+@item @code{CLIENT_COMPRESS} @tab Komprimiertes Protokoll benutzen.
+@item @code{CLIENT_FOUND_ROWS} @tab Die Anzahl gefundener
+(übereinstimmender) Zeilen zurückgeben, nicht die Anzahl betroffener
+Zeilen.
+@item @code{CLIENT_IGNORE_SPACE} @tab Leerzeichen nach Funktionsnamen
+zulassen. Macht alle Funktionsnamen zu reservierten Wörter.
+@item @code{CLIENT_INTERACTIVE} @tab @code{interactive_timeout} Sekunden
+zulassen (anstelle von @code{wait_timeout} Sekunden) von Inaktivität, bevor
+die Verbindung geschlossen wird.
+@item @code{CLIENT_NO_SCHEMA} @tab Die
+@code{datenbank.tabelle.spalte}-Syntax nicht zulassen. Das ist für ODBC.
+Der Flag veranlasst den Parser, einen Fehler zu erzeugen, wenn Sie diese
+Syntax benutzen, was für die Fehlersuche in einigen ODBC-Programmen
+hilfreich ist.
+@item @code{CLIENT_ODBC} @tab Der Client ist ein ODBC-Client. Das
+ändert
+@item @code{CLIENT_SSL} @tab SSL benutzen (verschlüsseltes Protokoll).
+@end multitable
+@end itemize
+
+@subsubheading Rückgabewerte
+
+Ein @code{MYSQL*}-Verbindungs-Handle, wenn die Verbindung erfolgreich war,
+@code{NULL}, wenn die Verbindung nicht erfolgreich war. Bei einer
+erfolgreichen Verbindung ist der Rückgabewert derselbe wie der Wert des
+ersten Parameters, es sei denn, Sie übergeben für diesen Parameter
+@code{NULL}.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_CONN_HOST_ERROR
+Verbindung zum MySQL-Server fehlgeschlagen.
+
+@item CR_CONNECTION_ERROR
+Verbindung zum lokalen MySQL-Server fehlgeschlagen.
+
+@item CR_IPSOCK_ERROR
+IP-Socket konnte nicht erzeugt werden.
+
+@item CR_OUT_OF_MEMORY
+Kein Speicher mehr.
+
+@item CR_SOCKET_CREATE_ERROR
+Unix-Socket konnte nicht erzeugt werden.
+
+@item CR_UNKNOWN_HOST
+IP-Adresse für den Hostnamen konnte nicht gefunden werden.
+
+@item CR_VERSION_ERROR
+Eine Protokollunverträglichkeit resultierte aus dem Versuch, sich mit einer
+Client-Bibliothek mit einem Server zu verbinden, die eine andere
+Protokollversion benutzt. Das kann passieren, wenn Sie eine sehr alte
+Client-Bibliothek benutzen und sich mit einem neuen Server verbinden, der
+nicht mit der @code{--old-protocol}-Option gestartet wurde.
+
+@item CR_NAMEDPIPEOPEN_ERROR
+Named Pipe unter Windows konnte nicht erzeugt werden.
+
+@item CR_NAMEDPIPEWAIT_ERROR
+Fehler beim Warten auf eine Named Pipe unter Windows.
+
+@item CR_NAMEDPIPESETSTATE_ERROR
+Pipe-Handler unter Windows konnte nicht erlangt werden.
+
+@item CR_SERVER_LOST
+Wenn @code{connect_timeout} > 0 ist und die Verbindung zum Server länger
+als @code{connect_timeout} benötigte, oder wenn der Server während der
+Ausführung von @code{init-command} starb.
+
+@end table
+
+@subsubheading Beispiel
+
+@example
+MYSQL mysql;
+
+mysql_init(&mysql);
+mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
+if (!mysql_real_connect(&mysql,"host","benutzer","passwort","datenbank",0,NULL,0))
+@{
+ fprintf(stderr, "Verbindung zur Datenbank fehlgeschlagen: Fehler: %s\n",
+ mysql_error(&mysql));
+@}
+@end example
+
+Wenn Sie @code{mysql_options()} benutzen, liest die MySQL-Bibliothek die
+@code{[client]}- und @code{ihr_programm_name}-Abschnitte in der
+@code{my.cnf}-Datei. Das stellt sicher, dass Ihr Programm funktioniert,
+selbst wenn jemand MySQL auf Nicht-Standard-Weise eingerichtet hat.
+
+Beachten Sie, dass @code{mysql_real_connect()} beim Verbinden den
+@code{reconnect}-Flag (Teil der MySQL-Struktur) auf einen Wert von @code{1}
+setzt. Dieser Flag gibt an, dass ein erneuter Verbindungsversuch zum Server
+gemacht wird, bevor aufgegeben wird, wenn eine Anfrage wegen einer verloren
+gegangenen Verbindung nicht ausgeführt werden kann.
+
+
+@node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions
+@c German node mysql_real_escape_string
+@subsubsection @code{mysql_real_escape_string()}
+
+@findex @code{mysql_real_escape_string()}
+
+@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *nach, const char *von, unsigned int laenge)}
+
+@subsubheading Beschreibung
+
+Diese Funktion wird benutzt, um eine zulässige SQL-Zeichenkette zu
+erzeugen, die Sie in einem SQL-Statement benutzen können.
+@xref{String syntax}.
+
+Die Zeichenkette in @code{von} wird in eine escapete SQL-Zeichenkette
+kodiert, wobei der aktuelle Zeichensatz der Verbindung berücksichtigt wird.
+Das Ergebnis wird in @code{nach} platziert und ein Null-Byte am Ende
+angefügt. Kodierte Zeichen sind @code{NUL} (ASCII 0), @samp{\n}, @samp{\r},
+@samp{\}, @samp{'}, @samp{"} und Control-Z (@pxref{Literals}).
+
+Die Zeichenkette, auf die von @code{von} gezeigt wird, muss @code{laenge}
+Bytes lang sein. Sie müssen den @code{nach}-Puffer so zuweisen, dass er
+mindestens @code{laenge*2+1} Bytes lang ist. (Im schlimmsten Fall muss
+jedes Zeichen mit zwei Bytes kodiert werden, und Sie brauchen Platz für das
+Null-Byte am Ende.) Wenn @code{mysql_escape_string()} zurückgibt, sind die
+Inhalte von @code{nach} eine Null-begrenzte Zeichenkette. Der Rückgabewert
+ist die Länge der kodierten Zeichenkette, ohne das Null-Zeichen am Ende.
+
+@subsubheading Beispiel
+
+@example
+char anfrage[1000],*end;
+
+end = strmov(anfrage,"INSERT INTO tabelle values(");
+*end++ = '\'';
+end += mysql_real_escape_string(&mysql, end,"Was is'n das?",12);
+*end++ = '\'';
+*end++ = ',';
+*end++ = '\'';
+end += mysql_real_escape_string(&mysql, end,"Binärdaten: \0\r\n",17);
+*end++ = '\'';
+*end++ = ')';
+
+if (mysql_real_query(&mysql,anfrage,(unsigned int) (end - anfrage)))
+@{
+ fprintf(stderr, "Einfügen der Zeile fehlgeschlagen, Fehler: %s\n",
+ mysql_error(&mysql));
+@}
+@end example
+
+Die im Beispiel benutzte @code{strmov()}-Funktion ist in der
+@code{mysqlclient}-Bibliothek enthalten und funktioniert wie
+@code{strcpy()}, gibt aber einen Zeiger auf Null am Ende des ersten
+Parameters zurück.
+
+@subsubheading Rückgabewerte
+
+Die Länge des Wertes in @code{nach}, ohne das Null-Zeichen am Ende.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions
+@c German node mysql_real_query
+@subsubsection @code{mysql_real_query()}
+
+@findex @code{mysql_real_query()}
+
+@code{int mysql_real_query(MYSQL *mysql, const char *anfrage, unsigned int laenge)}
+
+@subsubheading Beschreibung
+
+Führt die SQL-Anfrage aus, auf die von @code{anfrage} gezeigt wird, was
+eine @code{laenge} Bytes lange Zeichenkette sein sollte. Die0 Anfrage muss
+aus einem einzelnen SQL-Statement bestehen. Sie dürfen kein Semikolon
+(@samp{;}) oder @code{\g} zum Statement hinzufügen.
+
+Sie @emph{müssen} @code{mysql_real_query()} statt @code{mysql_query()} für
+Anfragen benutzen, die Binärdaten enthalten, weil Binärdaten das
+@samp{\0}-Zeichen enthalten können. Ausserdem ist @code{mysql_real_query()}
+schneller als @code{mysql_query()}, weil es in der Anfragezeichenkette
+nicht @code{strlen()} aufruft.
+
+Wenn Sie wissen wollen, ob die Anfrage eine Ergebnismenge zurückgeben
+sollte oder nicht, können Sie hierfür @code{mysql_field_count()} benutzen.
+@xref{mysql_field_count, @code{mysql_field_count}}.
+
+@subsubheading Rückgabewerte
+
+0, wenn die Anfrage erfolgreich war. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions
+@c German node mysql_reload
+@subsubsection @code{mysql_reload()}
+
+@findex @code{mysql_reload()}
+
+@code{int mysql_reload(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Weist den MySQL-Server an, die Berechtigungstabellen neu zu laden. Der
+verbundene Benutzer muss die @strong{reload}-Berechtigung haben.
+
+Diese Funktion ist veraltet. Vorzugsweise sollten Sie @code{mysql_query()}
+benutzen, um statt dessen ein SQL-@code{FLUSH PRIVILEGES}-Statement
+auszuführen.
+
+@subsubheading Rückgabewerte
+
+0 bei Erfolg. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions
+@c German node mysql_row_seek
+@subsubsection @code{mysql_row_seek()}
+
+@findex @code{mysql_row_seek()}
+
+@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *ergebnis, MYSQL_ROW_OFFSET offset)}
+
+@subsubheading Beschreibung
+Setzt den Zeilencursor auf eine beliebige Zeile in einer
+Anfrageergebnismenge. Dafür ist erforderlich, dass die
+Ergebnismengenstruktur das gesamte Ergebnis der Anfrage enthält, so dass
+@code{mysql_row_seek()} nur in Verbindung mit @code{mysql_store_result()}
+benutzt werden kann, nicht mit @code{mysql_use_result()}.
+
+Der Offset sollte ein Wert sein, der von einem Aufruf von
+@code{mysql_row_tell()} oder @code{mysql_row_seek()} zurückgegeben wird.
+Dieser Wert ist nicht einfach eine Zeilennummer; wenn Sie eine Zeile
+innerhalb einer Ergebnismenge mittels einer Zeilennummer suchen wollen,
+benutzen Sie statt dessen @code{mysql_data_seek()}.
+
+@subsubheading Rückgabewerte
+
+Der vorherige Wert des Zeilencursors. Dieser Wert kann an einen
+nachfolgenden Aufruf von @code{mysql_row_seek()} übergeben werden.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions
+@c German node mysql_row_tell
+@subsubsection @code{mysql_row_tell()}
+
+@findex @code{mysql_row_tell()}
+
+@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *ergebnis)}
+
+@subsubheading Beschreibung
+
+Gibt die aktuelle Position des Zeilencursors für das letzte
+@code{mysql_fetch_row()} zurück. Dieser Wert kann als Argument für
+@code{mysql_row_seek()} benutzt werden.
+
+Sie sollten @code{mysql_row_tell()} nur nach @code{mysql_store_result()},
+nicht nach @code{mysql_use_result()} benutzen.
+
+@subsubheading Rückgabewerte
+
+Der aktuelle Offset des Zeilencursors.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions
+@c German node mysql_select_db
+@subsubsection @code{mysql_select_db()}
+
+@findex @code{mysql_select_db()}
+
+@code{int mysql_select_db(MYSQL *mysql, const char *db)}
+
+@subsubheading Beschreibung
+
+Führt dazu, dass die Datenbank, die durch @code{db} angegeben wird, die
+vorgabemäßige (aktuelle) Datenbank auf der von @code{mysql} angegebenen
+Verbindung wird. Bei nachfolgenden Anfragen ist diese Datenbank die Vorgabe
+für Tabellenverweise, die nicht explizit einen Datenbank-Spezifizierer
+enthalten.
+
+@code{mysql_select_db()} schlägt fehl, wenn der verbundene Benutzer keine
+Zugriffsrechte auf die Datenbank hat.
+
+@subsubheading Rückgabewerte
+
+0 bei Erfolg. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_shutdown, mysql_stat, mysql_select_db, C API functions
+@c German node mysql_shutdown
+@subsubsection @code{mysql_shutdown()}
+
+@findex @code{mysql_shutdown()}
+
+@code{int mysql_shutdown(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Führt dazu, dass der Datenbankserver herunter fährt. Der verbundene
+Benutzer muss die @strong{shutdown}-Berechtigung haben.
+
+@subsubheading Rückgabewerte
+
+0 bei Erfolg. Nicht-0, wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions
+@c German node mysql_stat
+@subsubsection @code{mysql_stat()}
+
+@findex @code{mysql_stat()}
+
+@code{char *mysql_stat(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt eine Zeichenkette zurück, die Informationen enthält, die ähnlich denen
+sind, die vom @code{mysqladmin status}-Befehl zur Verfügung gestellt
+werden. Das schließt die Betriebszeit (Uptime) in Sekunden und die Anzahl
+laufender Threads, Anfragen (Questions), Neuladen (Reloads) und offener
+Tabellen ein.
+
+@subsubheading Rückgabewerte
+
+Eine Zeichenkette, die den Serverstatus beschreibt. @code{NULL}, wenn ein
+Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions
+@c German node mysql_store_result
+@subsubsection @code{mysql_store_result()}
+
+@findex @code{mysql_store_result()}
+
+@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Sie müssen @code{mysql_store_result()} oder @code{mysql_use_result()} für
+jede Anfrage aufrufen, die erfolgreich Daten abruft (@code{SELECT},
+@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}).
+
+Für andere Anfragen müssen Sie @code{mysql_store_result()} oder
+@code{mysql_use_result()} nicht aufrufen, es schadet aber auch nicht, noch
+führt es zu wahrnehmbaren Performance-Störungen, wenn Sie
+@code{mysql_store_result()} in jedem Fall aufrufen. Sie können feststellen,
+ob die Anfrage keine Ergebnismenge hatte, wenn Sie prüfen, ob
+@code{mysql_store_result()} 0 zurückgibt (mehr darüber später).
+
+Wenn Sie wissen wollen, ob die Anfrage eine Ergebnismenge zurückgeben
+sollte oder nicht, können Sie hierfür @code{mysql_field_count()} benutzen.
+@xref{mysql_field_count, @code{mysql_field_count}}.
+
+@code{mysql_store_result()} liest das gesamte Ergebnis einer Anfrage zum
+Client ein, weist eine @code{MYSQL_RES}-Struktur zu und platziert das
+Ergebnis in diese Struktur.
+
+@code{mysql_store_results()} gibt einen NULL-Zeiger zurück, wenn die
+Anfrage keine Ergebnismenge zurückgab (wenn die Anfrage zum Beispiel ein
+@code{INSERT}-Statement war).
+
+@code{mysql_store_results()} gibt auch einen NULL-Zeiger zurück, wenn das
+Lesen der Ergebnismenge fehlschlug. Sie können prüfen, ob Sie einen Fehler
+erhielten, wenn @code{mysql_error()} keinen NULL-Zeiger zurückgibt, wenn
+@code{mysql_errno()} ungleich 0 zurückgibt oder wenn
+@code{mysql_field_count()} ungleich 0 zurückgibt.
+
+Eine leere Ergebnismenge wird zurückgegeben, wenn keine Zeilen
+zurückgegeben werden. (Eine leere Ergebnismenge unterscheidet sich als
+Rückgabewert von einem NULL-Zeiger.)
+
+Nachdem Sie erst einmal @code{mysql_store_result()} aufgerufen und ein
+Ergebnis erhalten haben, das kein NULL-Zeiger ist, können Sie
+@code{mysql_num_rows()} aufrufen, um herauszufinden, wie viele Zeilen es in
+der Ergebnismenge gibt.
+
+Sie können @code{mysql_fetch_row()} aufrufen, um Zeilen aus der
+Ergebnismenge zu holen, oder @code{mysql_row_seek()} und
+@code{mysql_row_tell()}, um die aktuelle Zeilenposition innerhalb der
+Ergebnismenge zu erhalten oder zu setzen.
+
+Sie müssen @code{mysql_free_result()} aufrufen, wenn Sie mit der
+Ergebnismenge fertig sind.
+
+@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.
+
+@subsubheading Rückgabewerte
+
+Eine @code{MYSQL_RES}-Ergebnisstruktur mit den Ergebnissen. @code{NULL},
+wenn ein Fehler auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_OUT_OF_MEMORY
+Kein Speicher mehr.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+
+@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions
+@c German node mysql_thread_id
+@subsubsection @code{mysql_thread_id()}
+
+@findex @code{mysql_thread_id()}
+
+@code{unsigned long mysql_thread_id(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Gibt die Thread-Kennung der aktuellen Verbindung zurück. Der Wert kann als
+Argument für @code{mysql_kill()} benutzt werden, um den Thread zu töten.
+
+Wenn die Verbindung verloren ging und Sie sich mit @code{mysql_ping()}
+erneut verbinden, ändert sich die Thread-Kennung. Das heißt, dass Sie
+nicht die Thread-Kennung holen und für spätere Benutzung speichern sollten.
+Sie sollten sie holen, wenn Sie sie benötigen.
+
+@subsubheading Rückgabewerte
+
+Die Thread-Kennung der aktuellen Verbindung.
+
+@subsubheading Fehler
+
+Keine.
+
+
+@node mysql_use_result, , mysql_thread_id, C API functions
+@c German node mysql_use_result
+@subsubsection @code{mysql_use_result()}
+
+@findex @code{mysql_use_result()}
+
+@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)}
+
+@subsubheading Beschreibung
+
+Sie müssen @code{mysql_store_result()} oder @code{mysql_use_result()} für
+jede Anfrage aufrufen, die erfolgreich Daten abruft (@code{SELECT},
+@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}).
+
+@code{mysql_use_result()} initiiert einen Ergebnismengen-Abruf, aber liest
+die Ergebnismenge nicht tatsächlich in den Client wie
+@code{mysql_store_result()}. Statt dessen muss jede Zeile individuell
+abgerufen werden, indem Aufrufe von @code{mysql_fetch_row()} durchgeführt
+werden. Das liest das Ergebnis einer Anfrage direkt vom Server, ohne es in
+einer temporären Tabelle oder einem lokalen Puffer zu speichern, was
+manchmal schneller ist und viel weniger Speicher benutzt als
+@code{mysql_store_result()}. Dem Client wird nur Speicher für die aktuelle
+Zeile zugewiesen sowie ein Kommunikationspuffer, der bis zu
+@code{max_allowed_packet} Bytes Groß werden kann.
+
+Auf der anderen Seite sollten Sie @code{mysql_use_result()} nicht benutzen,
+wenn Sie viele Verarbeitungen für jede Zeile auf der Client-Seite
+durchführen oder wenn die Ausgabe auf den Bildschirm geschickt wird, auf
+dem der Benutzer @code{^S} (stop scroll) eingeben kann. Das bindet den
+Server und verhindert, dass andere Threads irgend welche Tabellen
+aktualisieren können, von denen gerade Daten geholt werden.
+
+Wenn Sie @code{mysql_use_result()} benutzen, müssen Sie
+@code{mysql_fetch_row()} ausführen, bis ein @code{NULL}-Wert zurückgegeben
+wird, denn ansonsten werden die nicht geholten Zeilen als Teil der
+Ergebnismenge bei Ihrer nächsten Anfrage zurückgegeben. Die C-API gibt den
+Fehler @code{Commands out of sync; You can't run this command now} aus,
+wenn Sie das vergessen!
+
+Sie können @code{mysql_data_seek()}, @code{mysql_row_seek()},
+@code{mysql_row_tell()}, @code{mysql_num_rows()} oder
+@code{mysql_affected_rows()} nicht bei einem Ergebnis verwenden, das von
+@code{mysql_use_result()} zurückgegeben wird. Ausserdem dürfen Sie keine
+anderen Anfragen absetzen, bis @code{mysql_use_result()} beendet ist.
+(Nachdem Sie alle Zeilen abgeholt haben, wird @code{mysql_num_rows()}
+jedoch exakt die Anzahl der geholten Zeilen zurückgeben.)
+
+Sie müssen @code{mysql_free_result()} aufrufen, wenn Sie mit der
+Ergebnismenge fertig sind.
+
+@subsubheading Rückgabewerte
+
+Eine @code{MYSQL_RES}-Ergebnisstruktur. @code{NULL}, wenn ein Fehler
+auftrat.
+
+@subsubheading Fehler
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
+@item CR_OUT_OF_MEMORY
+Kein Speicher mehr.
+@item CR_SERVER_GONE_ERROR
+Der MySQL-Server ist weg.
+@item CR_SERVER_LOST
+Die Verbindung zum Server ging während der Anfrage verloren.
+@item CR_UNKNOWN_ERROR
+Ein unbekannter Fehler trat auf.
+@end table
+
+@node C Thread functions, C Embedded Server func, C API functions, C
+@c German node C-Thread-Funktionen
+@subsection C-Threaded-Funktionsbeschreibungen
+
+Sie benötigen folgende Funktionen, wenn Sie einen threaded Client erstellen
+wollen. @xref{Threaded clients}.
+
+
+@menu
+* my_init::
+* mysql_thread_init::
+* mysql_thread_end::
+* mysql_thread_safe::
+@end menu
+
+@node my_init, mysql_thread_init, C Thread functions, C Thread functions
+@c German node my_init()
+@subsubsection @code{my_init()}
+
+@findex @code{my_init()}
+
+@subsubheading Beschreibung
+
+Diese Funktion muss einmal im Programm aufgerufen werden, bevor Sie irgend
+eine MySQL-Funktion aufrufen. Sie initialisiert einige globale Variablen,
+die MySQL braucht. Wenn Sie eine Thread-sichere Client-Bibliothek benutzen,
+wird diese ebenfalls @code{mysql_thread_init()} für diesen Thread aufrufen.
+
+Diese Funktion wird automatisch von @code{mysql_init()},
+@code{mysql_server_init()} und @code{mysql_connect()} aufgerufen.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@node mysql_thread_init, mysql_thread_end, my_init, C Thread functions
+@c German node mysql_thread_init()
+@subsubsection @code{mysql_thread_init()}
+
+@findex @code{mysql_thread_init()}
+
+@subsubheading Beschreibung
+
+Diese Funktion muss für jeden erzeugten Thread aufgerufen werden, um
+Thread-spezifische Variablen zu initialisieren.
+
+Diese Funktion wird automatisch von @code{my_init()} und
+@code{mysql_connect()} aufgerufen.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@node mysql_thread_end, mysql_thread_safe, mysql_thread_init, C Thread functions
+@c German node mysql_thread_end()
+@subsubsection @code{mysql_thread_end()}
+
+@findex @code{mysql_thread_end()}
+
+@subsubheading Beschreibung
+
+Diese Funktion muss vor dem Aufruf von @code{pthread_exit()} aufgerufen
+werden, um den von @code{mysql_thread_init()} zugewiesenen Speicher
+freizusetzen.
+
+Beachten Sie, dass diese Funktion @strong{nicht automatisch} von der
+Client-Bibliothek aufgerufen wird. Sie muss explizit aufgerufen werden, um
+Speicherlecks zu vermeiden.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@node mysql_thread_safe, , mysql_thread_end, C Thread functions
+@c Arjen note: new @node 2002-04-19, please translate text!
+@subsubsection @code{mysql_thread_safe()}
+
+@findex @code{mysql_thread_safe()}
+
+@code{unsigned int mysql_thread_safe(void)}
+
+@subsubheading Description
+
+This function indicates whether the client is compiled as thread safe.
+
+@subsubheading Return Values
+
+1 is the client is thread safe, 0 otherwise.
+
+@node C Embedded Server func, C API problems, C Thread functions, C
+@c German node C-Embedded-Server-Funktionen
+@subsection C-Embedded-Server-Funktionsbeschreibungen
+
+Sie müssen folgende Funktionen benutzen, wenn Sie wollen, dass Ihre
+Applikation gegen die eingebettete MySQL-Server-Bibliothek gelinkt werden
+kann. @xref{libmysqld}.
+
+Wenn das Programm mit @code{-lmysqlclient} anstelle von @code{-lmysqld}
+gelinkt wird, tun diese Funktionen nicht. Das ermöglicht die Auswahl
+zwischen der Benutzung des eingebetteten MySQL-Servers und eines
+Standalone-Servers, ohne irgend welchen Code zu verändern.
+
+
+@menu
+* mysql_server_init::
+* mysql_server_end::
+@end menu
+
+@node mysql_server_init, mysql_server_end, C Embedded Server func, C Embedded Server func
+@c German node mysql_server_init()
+@subsubsection @code{mysql_server_init()}
+
+@findex @code{mysql_server_init()}
+
+@code{void mysql_server_init(int argc, const char **argv, const char **groups)}
+
+@subsubheading Beschreibung
+
+Diese Funktion @strong{muss} einmal im Programm aufgerufen werden, bevor
+irgend eine andere MySQL-Funktion aufgerufen wird. Sie startet den Server
+und initialisiert jegliche Subsysteme (@code{mysys}, InnoDB usw.), die der
+Server benutzt. Wenn diese Funktion nicht aufgerufen wird, stürzt das
+Programm ab.
+
+Die @code{argc}- und @code{argv}-Argumente sind analog zu den Argumenten
+für @code{main()}. Das erste Element von @code{argv} wird ignoriert (es
+enthält typischerweise den Programmnamen). Aus Bequemlichkeitsgründen kann
+@code{argc} @code{0} sein, wenn es keine Kommandozeilenargumente für den
+Server gibt.
+
+Die @code{NULL}-begrenzte Liste von Zeichenketten in @code{groups} wählt
+aus, welche Gruppen in den Optionsdateien aktiv sind.
+@xref{Option files}. Aus Bequemlichkeitsgründen kann @code{groups}
+@code{NULL} sein. In diesem Fall ist die @code{[server]}-Gruppe aktiv.
+
+@subsubheading Beispiel
+
+@example
+#include <mysql.h>
+#include <stdlib.h>
+
+static char *server_args[] = @{
+ "Mein Programm", /* Diese Zeichenkette ist unbenutzt */
+ "--datadir=.",
+ "--set-variable=key_buffer_size=32M"
+@};
+static char *server_groups[] = @{
+ "server",
+ "Dieser_Programm_SERVER",
+ (char *)NULL
+@};
+
+int main(void) @{
+ mysql_server_init(sizeof(server_args) / sizeof(char *),
+ server_args, server_groups);
+
+ /* Hier können Sie irgend welche MySQL-API-Funktionen benutzen */
+
+ mysql_server_end();
+
+ return EXIT_SUCCESS;
+@}
+@end example
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@node mysql_server_end, , mysql_server_init, C Embedded Server func
+@c German node mysql_server_end()
+@subsubsection @code{mysql_server_end()}
+
+@findex @code{mysql_server_end()}
+
+@subsubheading Beschreibung
+
+Diese Funktion @strong{muss} einmal im Programm nach allen anderen
+MySQL-Funktionen aufgerufen werden. Sie fährt den eingebetteten Server
+herunter.
+
+@subsubheading Rückgabewerte
+
+Keine.
+
+@node C API problems, Building clients, C Embedded Server func, C
+@c German node C-API-Probleme
+@subsection Häufige Fragen und Probleme bei der Benutzung der C-API
+
+@tindex @code{mysql_query()}
+@tindex @code{mysql_store_result()}
+
+
+
+@menu
+* NULL mysql_store_result::
+* Query results::
+* Getting unique ID::
+* C API linking problems::
+@end menu
+
+@node NULL mysql_store_result, Query results, C API problems, C API problems
+@c German node NULL mysql_store_result
+@subsubsection Warum gibt @code{mysql_store_result()} manchmal @code{NULL} zurück, nachdem @code{mysql_query()} Erfolg zurückgegeben hat?
+
+@code{mysql_store_result()} kann @code{NULL} zurückgeben, auch nach einem
+erfolgreichen Aufruf von @code{mysql_query()}. Wenn das passiert, bedeutet
+das, dass eine der folgenden Bedingungen eingetreten ist:
+
+@itemize @bullet
+@item
+Es gab einen @code{malloc()}-Fehler (zum Beispiel, wenn die Ergebnismenge
+zu Groß war).
+
+@item
+Die Daten konnten nicht gelesen werden (ein Fehler mit der Verbindung trat
+auf).
+
+@item
+Die Anfrage gab keine Daten zurück (sie war zum Beispiel ein @code{INSERT},
+@code{UPDATE} oder @code{DELETE}).
+@end itemize
+
+Sie können jederzeit prüfen, ob das Statement eine leere Ergebnismenge
+geliefert haben sollte oder nicht, indem Sie @code{mysql_field_count()}
+aufrufen. Wenn @code{mysql_field_count()} 0 zurückliefert, ist das Ergebnis
+leer und die letzte Anfrage war ein Statement, die keine Rückgabewerte
+liefert (zum Beispiel ein @code{INSERT} oder ein @code{DELETE}). Wenn
+@code{mysql_field_count()} einen Nicht-0-Wert zurückgibt, hätte das
+Statement ein nicht leeres Ergebnis zurückliefern sollen. Sehen Sie in der
+Beschreibung von @code{mysql_field_count()}-Funktion wegen eines Beispiels
+nach.
+
+Sie können durch Aufruf von @code{mysql_error()} oder @code{mysql_errno()}
+auf einen Fehler überprüfen.
+
+@cindex Anfragen, C-API-Ergebnisse
+
+
+@node Query results, Getting unique ID, NULL mysql_store_result, C API problems
+@c German node Anfrageergebnisse
+@subsubsection Welche Ergebnisse kann ich von einer Anfrage bekommen?
+
+Zusätzlich zur Ergebnismenge, die von einer Anfrage zurückgegeben wird,
+können Sie auch folgende Informationen bekommen:
+
+@itemize @bullet
+@item
+@code{mysql_affected_rows()} gibt die Anzahl von Zeilen zurück, die durch
+die letzte Anfrage betroffen wurden, wenn Sie ein @code{INSERT},
+@code{UPDATE} oder @code{DELETE} ausführen. Eine Ausnahme besteht darin,
+wenn @code{DELETE} ohne eine @code{WHERE}-Klausel benutzt wird. In diesem
+Fall wird die Tabelle leer neu erzeugt, was viel schneller ist! Daher gibt
+@code{mysql_affected_rows()} 0 für die Anzahl betroffener Datensätze
+zurück.
+
+@item
+@code{mysql_num_rows()} gibt die Anzahl von Zeilen in einer Ergebnismenge
+zurück. Bei @code{mysql_store_result()} kann @code{mysql_num_rows()}
+aufgerufen werden, sobald @code{mysql_store_result()} etwas zurückgibt. Bei
+@code{mysql_use_result()} kann @code{mysql_num_rows()} erst aufgerufen
+werden, nachdem Sie alle Zeilen mit @code{mysql_fetch_row()} geholt haben.
+
+@item
+@code{mysql_insert_id()} gibt die Kennung zurück, die von der letzten
+Anfrage erzeugt wurde, die eine Zeile in eine Tabelle mit einem
+@code{AUTO_INCREMENT}-Index einfügte. @xref{mysql_insert_id, ,
+@code{mysql_insert_id()}}.
+
+@item
+Einige Anfragen (@code{LOAD DATA INFILE ...}, @code{INSERT INTO ... SELECT
+...}, @code{UPDATE}) geben zusätzliche Informationen zurück. Das Ergebnis
+wird von @code{mysql_info()} zurückgegeben. Siehe die Beschreibung für
+@code{mysql_info()} hinsichtlich des Formats der Zeichenkette, die diese
+Funktion zurückgibt. @code{mysql_info()} gibt einen @code{NULL}-Zeiger
+zurück, wenn es keine zusätzlichen Informationen gibt.
+@end itemize
+
+
+@node Getting unique ID, C API linking problems, Query results, C API problems
+@c German node Eindeutige Kennung erhalten
+@subsubsection Wie erhalte ich die eindeutige Kennung für die letzte eingefügte Zeile?
+
+@cindex eindeutige Kennung
+@cindex letzte Zeile, eindeutige Kennung
+@cindex Kennung, eindeutige
+@cindex Tabellen, eindeutige Kennung für die letzte Zeile
+
+Wenn Sie einen Datensatz in eine Tabelle einfügen, der eine Spalte enthält,
+die das @code{AUTO_INCREMENT}-Attribut hat, erhalten Sie die letzte
+erzeugte Kennung durch Aufruf der @code{mysql_insert_id()}-Funktion.
+
+Sie können die Kennung auch dadurch abrufen, dass Sie die
+@code{LAST_INSERT_ID()}-Funktion in einer Anfrage-Zeichenkette verwenden,
+die Sie an @code{mysql_query()} übergeben.
+
+Sie können überprüfen, ob ein @code{AUTO_INCREMENT}-Index benutzt wird,
+wenn Sie folgenden Code ausführen. Er prüft auch, ob die Anfrage ein
+@code{INSERT} mit einem @code{AUTO_INCREMENT}-Index war:
+
+@example
+if (mysql_error(&mysql)[0] == 0 &&
+ mysql_num_fields(ergebnis) == 0 &&
+ mysql_insert_id(&mysql) != 0)
+@{
+ used_id = mysql_insert_id(&mysql);
+@}
+@end example
+
+Die letzte erzeugte Kennung wird im Server auf der Grundlage der jeweiligen
+Verbindung gewartet. Sie wird nicht durch andere Clients geändert. Sie wird
+nicht einmal geändert, wenn Sie eine andere @code{AUTO_INCREMENT}-Spalte
+mit einem nicht magischen Wert aktualisieren (einem Wert, der nicht
+@code{NULL} und nicht @code{0} ist).
+
+Wenn Sie die Kennung benutzen wollen, die für eine Tabelle erzeugt wurde,
+um sie in eine zweite Tabelle einzufügen, können Sie SQL-Statements wie
+folgt benutzen:
+
+@example
+INSERT INTO foo (auto,text)
+ VALUES(NULL,'text'); # Kennung durch Einfügen von NULL erzeugen
+INSERT INTO foo2 (id,text)
+ VALUES(LAST_INSERT_ID(),'text'); # Kennung in zweiter Tabelle benutzen
+@end example
+
+
+@node C API linking problems, , Getting unique ID, C API problems
+@c German node C-API-Linking-Probleme
+@subsubsection Probleme beim Linken mit der C-API
+
+@cindex Linken, Probleme
+@cindex C-API, Link-Probleme
+
+Wenn Sie mit der C-API linken, können auf manchen Systemen folgende Fehler
+auftreten:
+
+@example
+gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl
+
+Undefined first referenced
+ symbol in file
+floor /usr/local/lib/mysql/libmysqlclient.a(password.o)
+ld: fatal: Symbol referencing errors. No output written to client
+@end example
+
+Wenn das auf Ihrem System passiert, müssen Sie die math-Bibliothek
+einschließen, indem Sie @code{-lm} am Ende der Kompilier- / Link-Zeile
+hinzufügen.
+
+
+@node Building clients, Threaded clients, C API problems, C
+@c German node Clients bauen
+@subsection Client-Programme bauen
+
+@cindex Client-Programme, bauen
+@cindex linken
+@cindex bauen, Client-Programme
+@cindex Programme, Client
+
+Wenn Sie MySQL-Clients kompilieren, die Sie selbst geschrieben oder von
+Dritten erhalten haben, müssen diese mit der @code{-lmysqlclient
+-lz}-Option für den Link-Befehl gelinkt werden. Eventuell sollten Sie auch
+eine @code{-L}-Option verwenden, um dem Linker mitzuteilen, wo sich die
+Bibliothek befindet. Wenn zum Beispiel die Bibliothek in
+@file{/usr/local/mysql/lib} installiert ist, benutzen Sie
+@code{-L/usr/local/mysql/lib -lmysqlclient -lz} für den Link-Befehl.
+
+Für Clients, die MySQL-Header-Dateien benutzen, müssen Sie eventuell eine
+@code{-I}-Option angeben, wenn Sie sie kompilieren (zum Beispiel
+@code{-I/usr/local/mysql/include}), so dass der Kompiler die Header-Dateien
+finden kann.
+
+
+@node Threaded clients, libmysqld, Building clients, C
+@c German node Threaded Clients
+@subsection Wie man einen threaded Client herstellt
+
+@cindex Clients, Threaded
+@cindex Threaded Clients
+
+Die Client-Bibliothek ist fast Thread-sicher. Das größte Problem besteht
+darin, dass die Subroutinen in @file{net.c}, die von Sockets lesen, nicht
+Interrupt-sicher sind. Das wurde mit dem Hintergedanken gemacht, dass Sie
+eventuell Ihre eigenen Alarme haben möchten, die ein langes Lesen vom
+Server unterbrechen können. Wenn Sie Interrupt-Handler für den
+@code{SIGPIPE}-Interrupt installieren, sollte die Socket-Handhabung
+Thread-sicher sein.
+
+In den älteren Binärdistributionen wurden die Client-Bibliotheken
+normalerweise nicht mit der Thread-sicheren Option kompiliert (die
+Windows-Binärdateien sind vorgabemäßig Thread-sicher kompiliert). Neuere
+Binärdistributionen sollten sowohl eine normale als auch eine
+Thread-sichere Client-Bibliothek haben.
+
+Um einen threaded Client zu erhalten, bei dem Sie den Client durch andere
+Threads unterbrechen (interrupt) und Zeitüberschreitungen (Timeouts) setzen
+können, wenn Sie mit dem MySQL-Server kommunizieren, sollten Sie die
+@code{-lmysys}-, @code{-lstring}-, und @code{-ldbug}-Bibliotheken und den
+@code{net_serv.o}-Code benutzen, den der Server benutzt.
+
+Wenn Sie keine Unterbrechungen (Interrupts) oder Zeitüberschreitungen
+(Timeouts) benötigen, können Sie einfach eine Thread-sicher
+Client-Bibliothek @code{(mysqlclient_r)} kompilieren und diese benutzen.
+@xref{C,,MySQL-C-API}. In diesem Fall müssen Sie sich nicht um die
+@code{net_serv.o}-Objektdatei oder die anderen MySQL-Bibliotheken kümmern.
+
+Wenn Sie einen threaded Client benutzen und Unterbrechungen (Interrupts)
+und Zeitüberschreitungen (Timeouts) benutzen wollen, können Sie in
+umfangreicher Weise die Routinen in der @file{thr_alarm.c}-Datei benutzen.
+Wenn Sie Routinen aus der @code{mysys}-Bibliothek benutzen, müssen Sie
+lediglich daran denken, @code{my_init()} zuerst aufzurufen!
+@xref{C Thread functions}.
+
+Alle Funktionen ausser @code{mysql_real_connect()} sind vorgabemäßig
+Thread-sicher. Die folgenden Hinweise beschreiben, wie man eine
+Thread-sichere Client-Bibliothek kompiliert und sie auf Thread-sichere
+Weise benutzt. (Die unten stehenden Hinweise für
+@code{mysql_real_connect()} beziehen sich in der Tat auch auf
+@code{mysql_connect()}. Weil aber @code{mysql_connect()} veraltet ist,
+sollten Sie in jedem Fall @code{mysql_real_connect()} benutzen.)
+
+Um @code{mysql_real_connect()} Thread-sicher zu machen, müssen Sie die
+Client-Bibliothek mit diesem Befehl neu kompilieren:
+
+@example
+shell> ./configure --enable-thread-safe-client
+@end example
+
+Das erzeugt eine Thread-sichere Client-Bibliothek @code{libmysqlclient_r}.
+@code{--enable-thread-safe-client}. Diese Bibliothek ist pro Verbindung
+Thread-sicher. Sie können zwei Threads dieselbe Verbindung benutzen lassen,
+solange Sie folgendes tun:
+
+@itemize @bullet
+@item
+Zwei Threads können zur gleichen Zeit keine Anfrage an MySQL über dieselbe
+Verbindung schicken. Insbesondere müssen Sie sicherstellen, dass zwischen
+einem @code{mysql_query()} und einem @code{mysql_store_result()} kein
+anderer Thread dieselbe Verbindung benutzt.
+@item
+Viele Threads können auf unterschiedliche Ergebnismengen zugreifen, die mit
+@code{mysql_store_result()} abgerufen wurden.
+@item
+Wenn Sie @code{mysql_use_result} benutzen, müssen Sie sicherstellen, dass
+kein anderer Thread irgend etwas über dieselbe Verbindung anfragt, bis die
+Ergebnismenge geschlossen wurde. Für threaded Clients, die dieselbe
+Verbindung benutzen, ist es jedoch am besten, @code{mysql_use_result()} zu
+benutzen.
+@item
+
+Wenn Sie mehrfache Threads über dieselbe Verbindung benutzen wollen, müssen
+Sie eine mutex-Sperre um Ihre @code{mysql_query()}- und
+@code{mysql_store_result()}-Aufruf-Kombination haben. Sobald
+@code{mysql_store_result()} fertig ist, kann die Sperre aufgehoben werden
+und andere Threads können über dieselbe Verbindung anfragen.
+@item
+Wenn Sie mit POSIX-Threads programmieren, können Sie
+@code{pthread_mutex_lock()} und @code{pthread_mutex_unlock()} benutzen, um
+eine mutex-Sperre aufzubauen und aufzuheben.
+@end itemize
+
+Sie müssen folgendes wissen, wenn Sie einen Thread haben, der
+MySQL-Funktionen aufruft, dieser Thread aber keine Verbindung zur
+MySQL-Datenbank aufgebaut hat:
+
+Wenn Sie @code{mysql_init()} oder @code{mysql_connect()} aufrufen, erzeugt
+MySQL eine Thread-spezifische Variable für diesen Thread, die von der
+Debug-Bibliothek benutzt wird (unter anderem).
+
+Wenn Sie in einem Thread-Aufruf eine MySQL-Funktion haben, bevor ein Thread
+@code{mysql_init()} oder @code{mysql_connect()} aufgerufen hat, hat der
+Thread nicht notwendigerweise Thread-spezifische Variablen zur Hand, und
+Sie werden wahrscheinlich früher oder später einen Coredump erhalten.
+
+Damit alles reibungslos funktioniert, müssen Sie folgendes tun:
+
+@enumerate
+@item
+Rufen Sie bei Programmbeginn @code{my_init()} auf, wenn Ihr Programm
+irgend welche MySQL-Funktion vor dem Aufruf von @code{mysql_real_connect()}
+benutzt.
+@item
+Rufen Sie @code{mysql_thread_init()} im Thread-Handler auf, bevor Sie
+irgend welche MySQL-Funktionen aufrufen.
+@item
+Rufen Sie im Thread @code{mysql_thread_end()} auf, bevor Sie
+@code{pthread_exit()} aufrufen. Das gibt Speicher frei, der von
+MySQL-Thread-spezifischen Variablen benutzt wird.
+@end enumerate
+
+Eventuell erhalten Sie Fehler wegen undefinierter Symbole, wenn Sie Ihren
+Client mit @code{mysqlclient_r} linken. In den meisten Fällen liegt das
+daran, dass Sie die Thread-Bibliotheken nicht auf der Link- /
+Kompilierzeile eingeschlossen haben.
+
+@node libmysqld, , Threaded clients, C
+@c German node libmysqld
+@subsection libmysqld, die eingebettete MySQL-Server-Bibliothek
+
+@cindex libmysqld
+@cindex eingebettete MySQL-Server-Bibliothek
+
+
+@menu
+* libmysqld overview::
+* libmysqld compiling::
+* libmysqld example::
+* libmysqld licensing::
+@end menu
+
+@node libmysqld overview, libmysqld compiling, libmysqld, libmysqld
+@c German node libmysqld Überblick
+@subsubsection Überblick über die eingebettete MySQL-Server-Bibliothek
+
+Die eingebettete MySQL-Server-Bibliothek ermöglicht es, einen MySQL-Server
+mit allen Features innerhalb einer Client-Applikation laufen zu lassen. Die
+hauptsächlichen Vorteile sind erhöhte Geschwindigkeit und einfachere
+Verwaltung eingebetteter Applikationen.
+
+@node libmysqld compiling, libmysqld example, libmysqld overview, libmysqld
+@c German node libmysqld kompilieren
+@subsubsection Programme mit @code{libmysqld} kompilieren
+
+Momentan müssen alle unterstützten Bibliotheken explizit aufgelistet
+werden, wenn Sie mit @code{-lmysqld} linken. In Zukunft wird
+@code{mysql_config --libmysqld-libs} die Bibliotheken benennen, um das zu
+erleichtern. Darüber hinaus werden alle unterstützten Bibliotheken
+wahrscheinlich in libmysqld eingeschlossen werden, um dies noch weiter zu
+vereinfachen.
+
+Die korrekten Flags zum Kompilieren und Linken eines threaded Programms
+müssen benutzt werden, selbst wenn Sie nicht direkt irgend welche
+Thread-Funktionen in Ihrem Code aufrufen.
+
+@node libmysqld example, libmysqld licensing, libmysqld compiling, libmysqld
+@c German node libmysqld Beispiel
+@subsubsection Ein einfaches Embedded-Server-Beispiel
+
+Dieses Beispiel-Programm und makefile sollten ohne Änderungen auf einem
+Linux- oder FreeBSD-System funktionieren. Bei anderen Betriebssystemen sind
+kleinere Änderungen notwendig. Dieses Beispiel ist so angelegt, dass
+genügend Details dargestellt werden, um die Problematik zu verstehen, ohne
+zu viel "Verwirrendes" einzubringen, das Teil einer echten Applikation ist.
+
+Um das Beispiel auszuprobieren, erzeugen Sie ein @file{example}-Verzeichnis
+auf derselben Ebene wie das mysql-4.0-Quell-Verzeichnis. Speichern Sie die
+@file{example.c}-Quelle und das @file{GNUmakefile} im Verzeichnis und
+lassen Sie GNU-@file{make} innerhalb des @file{example}-Verzeichnisses
+laufen.
+
+@file{example.c}
+@example
+/*
+ * Ein einfacher Beispiel-Client, der die eingebettete
+ * MySQL-Server-Bibliothek benutzt
+ */
+
+#include <mysql.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+enum on_error @{ E_okay, E_warn, E_fail @};
+
+static void die(MYSQL *db, char *fmt, ...);
+MYSQL *db_connect(const char *dbname);
+void db_disconnect(MYSQL *db);
+void db_do_Anfrage(MYSQL *db, const char *query, enum on_error on_error);
+
+const char *server_groups[] = @{ "test_client_SERVER", "server", NULL @};
+
+int
+main(int argc, char **argv)
+@{
+ MYSQL *one, *two;
+
+ /* Das muss vor allen weiteren mysql-Funktionen aufgerufen werden.
+ *
+ * Sie können mysql_server_init(0, NULL, NULL) benutzen,
+ * was den Server initialisiert und die Gruppen
+ * groups = @{ "server", NULL @} benutzt.
+ *
+ * In Ihre $HOME/.my.cnf-Datei sollten Sie folgendes eintragen:
+
+[test_client_SERVER]
+language = /pfad/zur/quelle/von/mysql/sql/share/english
+
+ * Natürlich können Sie auch argc und argv ändern,
+ * bevor Sie sie an diese Funktion übergeben.
+ * Oder erzeugen Sie neue auf jede Art, die Sie wollen.
+ * Alle Argumente in argv (ausser argv[0], was der Programmname ist)
+ * müssen allerdings gültige Optionen für den MySQL-Server sein.
+ * Wenn Sie diesen Client gegen die normale mysqlclient-
+ * Bibliothek linken, ist diese Funktion nur ein Stumpf, der nichts tut.
+ */
+ mysql_server_init(argc, argv, server_groups);
+
+ one = db_connect("test");
+ two = db_connect(NULL);
+
+ db_do_query(one, "show table status", E_fail);
+ db_do_query(two, "show databases", E_fail);
+
+ mysql_close(two);
+ mysql_close(one);
+
+ /* Folgendes muss nach allen anderen mysql-Funktionen aufgerufen werden */
+ mysql_server_end();
+
+ exit(EXIT_SUCCESS);
+@}
+
+void
+die(MYSQL *db, char *fmt, ...)
+@{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ putc('\n', stderr);
+ if (db)
+ db_disconnect(db);
+ exit(EXIT_FAILURE);
+@}
+
+MYSQL *
+db_connect(const char *dbname)
+@{
+ MYSQL *db = mysql_init(NULL);
+ if (!db)
+ die(db, "mysql_init fehlgeschlagen: kein Speicher mehr");
+ mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "simple");
+ if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
+ die(db, "mysql_real_connect fehlgeschlagen: %s", mysql_error(db));
+
+ return db;
+@}
+
+void
+db_disconnect(MYSQL *db)
+@{
+ mysql_close(db);
+@}
+
+/*
+ * show_query: Dieser Code ist aus mysql.cc. Diese Funktion
+ * ist dafür gedacht, intern für db_do_query() benutzt zu werden.
+ */
+static char *
+show_query(MYSQL *db)
+@{
+ MYSQL_RES *res;
+ MYSQL_FIELD *field;
+ MYSQL_ROW row;
+ char sep[256], *psep = sep;
+ char *is_num = 0;
+ char *err = 0;
+ unsigned int length = 1; /* anfangs "|" */
+ unsigned int off;
+
+ if (!(res = mysql_store_result(db)))
+ return mysql_error(db);
+
+ if (!(is_num = malloc(mysql_num_fields(res))))
+ @{
+ err = "Kein Speicher mehr";
+ goto err;
+ @}
+
+ /* set up */
+ *psep++ = '+';
+ while ((field = mysql_fetch_field(res)))
+ @{
+ unsigned int len = strlen(field->name);
+ if (len < field->max_length)
+ len = field->max_length;
+ if (len < 2 && !IS_NOT_NULL(field->flags))
+ len = 2; /* \N */
+ field->max_length = len + 1; /* die API verbiegen ... */
+ len += 2; length += len + 1; /* " " davor, " |" danach */
+ if (length >= 255)
+ @{
+ err = "Zeile zu lang";
+ goto err;
+ @}
+ memset(psep, '-', len); psep += len;
+ *psep++ = '+';
+ *psep = '\0';
+ @}
+
+ /* Spaltenüberschriften */
+ puts(sep);
+ mysql_field_seek(res,0);
+ fputc('|',stdout);
+ für (off=0; (field = mysql_fetch_field(res)) ; off++)
+ @{
+ printf(" %-*s|",field->max_length, field->name);
+ is_num[off]= IS_NUM(field->type);
+ @}
+ fputc('\n',stdout);
+ puts(sep);
+
+ /* Zeilen */
+ while ((row = mysql_fetch_row(res)))
+ @{
+ (void) fputs("|",stdout);
+ mysql_field_seek(res,0);
+ for (off=0 ; off < mysql_num_fields(res); off++)
+ @{
+ field = mysql_fetch_field(res);
+ printf(is_num[off] ? "%*s |" : " %-*s|",
+ field->max_length, row[off] ? (char*) row[off] : "NULL");
+ @}
+ (void) fputc('\n',stdout);
+ @}
+ puts(sep);
+
+err:
+ if (is_num)
+ free(is_num);
+ mysql_free_result(res);
+
+ return err;
+@}
+
+void
+db_do_query(MYSQL *db, const char *query, enum on_error on_error)
+@{
+ char *err = 0;
+ if (mysql_query(db, query) != 0)
+ goto err;
+
+ if (mysql_field_count(db) > 0)
+ @{
+ if ((err = show_query(db)))
+ goto err;
+ @}
+ else if (mysql_affected_rows(db))
+ printf("Betroffene Zeilen: %lld [%s]\n", mysql_affected_rows(db), query);
+
+ return;
+
+err:
+ switch (on_error) @{
+ case E_okay:
+ break;
+ case E_warn:
+ fprintf(stderr, "db_do_query fehlgeschlagen: %s [%s]\n",
+ err ? err : mysql_error(db), query);
+ break;
+ case E_fail:
+ die(db, "db_do_query fehlgeschlagen: %s [%s]",
+ err ? err : mysql_error(db), query);
+ break;
+ @}
+@}
+@end example
+
+@file{GNUmakefile}
+@example
+# Platzieren Sie diese in Ihr mysql-Quell-Verzeichnis
+m := ../mysql-4.0
+
+CC := cc
+CPPFLAGS := -I$m/include -D_thread_SAFE -D_REENTRANT
+CFLAGS := -g -W -Wall
+LDFLAGS := -static
+LDLIBS = $(embed_libs) -lz -lm -lcrypt
+
+ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
+# FreeBSD
+LDFLAGS += -pThread
+else
+# Linux wird angenommen
+LDLIBS += -lpThread
+endif
+
+
+# Standard-Bibliotheken
+
+embed_libs := \
+ $m/libmysqld/.libs/libmysqld.a \
+ $m/isam/libnisam.a \
+ $m/myisam/libmyisam.a \
+ $m/heap/libheap.a \
+ $m/merge/libmerge.a \
+ $m/myisammrg/libmyisammrg.a
+
+
+# Optional gebaute Bibliotheken
+
+ifneq (,$(shell test -r $m/innobase/usr/libusr.a && echo "yes"))
+embed_libs += \
+ $m/innobase/usr/libusr.a \
+ $m/innobase/odbc/libodbc.a \
+ $m/innobase/srv/libsrv.a \
+ $m/innobase/que/libque.a \
+ $m/innobase/srv/libsrv.a \
+ $m/innobase/dict/libdict.a \
+ $m/innobase/ibuf/libibuf.a \
+ $m/innobase/row/librow.a \
+ $m/innobase/pars/libpars.a \
+ $m/innobase/btr/libbtr.a \
+ $m/innobase/trx/libtrx.a \
+ $m/innobase/read/libread.a \
+ $m/innobase/usr/libusr.a \
+ $m/innobase/buf/libbuf.a \
+ $m/innobase/ibuf/libibuf.a \
+ $m/innobase/eval/libeval.a \
+ $m/innobase/log/liblog.a \
+ $m/innobase/fsp/libfsp.a \
+ $m/innobase/fut/libfut.a \
+ $m/innobase/fil/libfil.a \
+ $m/innobase/lock/liblock.a \
+ $m/innobase/mtr/libmtr.a \
+ $m/innobase/page/libpage.a \
+ $m/innobase/rem/librem.a \
+ $m/innobase/thr/libthr.a \
+ $m/innobase/com/libcom.a \
+ $m/innobase/sync/libsync.a \
+ $m/innobase/data/libdata.a \
+ $m/innobase/mach/libmach.a \
+ $m/innobase/ha/libha.a \
+ $m/innobase/dyn/libdyn.a \
+ $m/innobase/mem/libmem.a \
+ $m/innobase/sync/libsync.a \
+ $m/innobase/ut/libut.a \
+ $m/innobase/os/libos.a \
+ $m/innobase/ut/libut.a
+endif
+
+ifneq (,$(shell test -r $m/bdb/build_unix/libdb.a && echo "yes"))
+embed_libs += $m/bdb/build_unix/libdb.a
+endif
+
+
+# Unterstützte Bibliotheken
+
+embed_libs += \
+ $m/mysys/libmysys.a \
+ $m/strings/libmystrings.a \
+ $m/dbug/libdbug.a \
+ $m/regex/libregex.a
+
+
+# Optional gebaute unterstützte Bibliotheken
+
+ifneq (,$(shell test -r $m/readline/libreadline.a && echo "yes"))
+embed_libs += $m/readline/libreadline.a
+endif
+
+# Das funktioniert bei einfachen Ein-Datei-Test-Programmen
+sources := $(wildcard *.c)
+objects := $(patsubst %c,%o,$(sources))
+targets := $(basename $(sources))
+
+all: $(targets)
+
+clean:
+ rm -f $(targets) $(objects) *.core
+@end example
+
+@node libmysqld licensing, , libmysqld example, libmysqld
+@c German node libmysqld Lizensierung
+@subsubsection Lizensierung des eingebetteten Servers
+
+Der MySQL-Quelltext wird von der GNU-GPL-Lizenz abgedeckt
+(@pxref{GPL license}). Eine Folge davon ist, dass jegliches Programm, das
+durch Linken mit @code{libmysqld} den MySQL-Quelltext enthält, als freie
+Software (unter einer mit der GPL kompatiblen Lizenz) veröffentlicht werden
+muss.
+
+Wir ermutigen jeden, freie Software durch Veröffentlichung von Code unter
+der GPL oder einer kompatiblen Lizenz zu fördern. Für diejenigen, die dazu
+nicht in der Lage sind, ist eine weitere Option, den MySQL-Code von MySQL
+AB unter einer lockereren Lizenz zu erwerben. Wegen Details betreffs dieses
+Themas siehe unter @ref{Lizenzpolitik}.
+
+@node Cplusplus, Java, C, Clients
+@c German node Cplusplus
+@section MySQL-C++-APIs
+
+
+
+@cindex C++-APIs
+
+Zwei APIs sind im
+MySQL-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib-Verzeichnis}
+verfügbar.
+
+
+@menu
+* Borland C++::
+@end menu
+
+@node Borland C++, , Cplusplus, Cplusplus
+@c German node Borland C++
+@subsection Borland C++
+
+@cindex Borland C++-Kompiler
+
+Sie können den MySQL-Windows-Quellcode mit Borlund C++ 5.02 kompilieren.
+(Der Windows-Quellcode beinhaltet nur Projekte für Microsoft VC++, für
+Borland C++ müssen Sie die Projektdateien selbst erstellen).
+
+Ein bekanntes Problem bei Borland C++ ist, dass es eine andere
+Strukturanordnung benutzt als VC++. Das bedeutet, dass Sie Probleme
+bekommen, wenn Sie versuchen, die vorgabemäßigen
+@code{libmysql.dll}-Bibliotheken (die mit VC++ kompiliert wurden) mit
+Borland C++ zu verwenden. Sie können eins der folgenden Dinge tun, um
+dieses Problem zu vermeiden:
+
+@itemize @bullet
+@item
+Sie können statische MySQL-Bibliotheken für Borland C++ verwenden, die Sie
+unter @uref{http://www.mysql.com/downloads/os-win32.html} finden.
+@item
+Rufen Sie @code{mysql_init()} nur mit @code{NULL} als Argument auf, kein
+vorher zugewiesenes (prä-alloziertes) MySQL-Strukt.
+@end itemize
+
+
+@node Java, Python, Cplusplus, Clients
+@c German node Java
+@section MySQL Java Connectivity (JDBC)
+
+@cindex Java-Connectivity
+@cindex JDBC
+
+Es gibt 2 unterstützte JDBC-Treiber für MySQL (den mm-Treiber und den
+Reisin JDBC-Treiber). Sie finden den mm-Treiber unter
+@uref{http://mmmysql.sourceforge.net/} oder
+@uref{http://www.mysql.com/Downloads/Contrib/} und den Reisin-Treiber unter
+@uref{http://www.caucho.com/Projekte/jdbc-mysql/index.xtp}. Wegen der
+Dokumentation sehen Sie sich irgend eine JDBC-Dokumentation durch sowie die
+eigene Dokumentation der Treiber wegen MySQL-spezifischer Features.
+
+
+@node Python, Tcl, Java, Clients
+@c German node Python
+@section MySQL-Python-APIs
+
+@cindex Python-APIs
+
+Das
+MySQL-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib-Verzeichnis}
+enthält eine Python-Schnittstelle, die von Joseph Skinner geschrieben
+wurde.
+
+Sie können auch die Python-Schnittstelle zu iODBC benutzen, um auf einen
+MySQL-Server zuzugreifen.
+@uref{http://starship.skyport.net/~lemburg/,mxODBC}
+
+
+@node Tcl, Eiffel, Python, Clients
+@c German node Tcl
+@section MySQL-Tcl-APIs
+
+@cindex Tcl-APIs
+
+@uref{http://www.binevolve.com/~tdarugar/tcl-sql/, Tcl bei binevolve}.
+Das
+@uref{http://www.mysql.com/Downloads/Contrib,Contrib-Verzeichnis} enthält
+eine Tcl-Schnittstelle, die auf msqltcl 1.50 basiert.
+
+
+@node Eiffel, , Tcl, Clients
+@c German node Eiffel
+@section MySQL-Eiffel-Wrapper
+
+@cindex Eiffel-Wrapper
+@cindex Wrapper, Eiffel
+
+Das
+MySQL-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib-Verzeichnis}
+enthält einen Eiffel-Wrapper, der von Michael Ravits geschrieben wurde.
+
+
+@node Extending MySQL, Problems, Clients, Top
+@c German node MySQL erweitern
+@chapter MySQL erweitern
+
+
+
+@menu
+* MySQL internals::
+* Adding procedures::
+* MySQL-Interna::
+@end menu
+
+@node MySQL internals, Adding procedures, Extending MySQL, Extending MySQL
+@c German node Hinzufügen von Funktionen
+@section Hinzufügen neuer Funktionen zu MySQL
+
+@cindex Funktionen, neue
+@cindex hinzufügen, neue Funktionen
+@cindex benutzerdefinierte Funktionen, hinzufügen
+@cindex UDFs, Definition
+@cindex Funktionen, benutzerdefinierte
+
+Es gibt zwei Möglichkeiten, MySQL neue Funktionen hinzuzufügen:
+
+@itemize @bullet
+@item
+Sie können die Funktion über die benutzerdefinierbare Funktions-
+(UDF-) Schnittstelle hinzufügen. Benutzerdefinierbare Funktionen werden
+dynamisch mittels @code{CREATE FUNCTION} und @code{DROP
+FUNCTION}-Statements hinzugefügt bzw. gelöscht.
+@xref{CREATE FUNCTION, ,@code{CREATE FUNCTION}}.
+
+@item
+Sie können die Funktion als native (eingebaute) MySQL-Funktion hinzufügen.
+Native Funktionen werden in den @code{mysqld}-Server kompiliert und stehen
+dann dauerhaft zur Verfügung.
+@end itemize
+
+Jede Methode hat Vorteile und Nachteile:
+
+@itemize @bullet
+@item
+Wenn Sie eine benutzerdefinierte Funktion schreiben, müssen Sie die
+Objekt-Datei zusätzlich zum Server selbst installieren. Wenn Sie Ihre
+Funktion in den Server einkompilieren, brauchen Sie das nicht zu tun.
+@item
+Sie können der binären MySQL-Distribution benutzerdefinierte Funktionen
+hinzufügen. Native Funktionen erfordern, dass Sie eine Quelldistribution
+verändern.
+@item
+Wenn Sie Ihre MySQL-Distribution aktualisieren, können Sie weiterhin Ihre
+vorher installierten benutzerdefinierten Funktionen benutzen. Bei nativen
+Funktionen müssen Sie Ihre Änderungen jedes Mal wiederholen, wenn Sie
+aktualisieren.
+@end itemize
+
+Gleich welche Methode Sie zum Hinzufügen neuer Funktionen verwenden, können
+Sie diese genau wie die nativen Funktionen, z. B. @code{ABS()} oder
+@code{SOUNDEX()}, benutzen.
+
+
+
+@menu
+* CREATE FUNCTION::
+* Adding UDF::
+* Adding native function::
+@end menu
+
+@node CREATE FUNCTION, Adding UDF, MySQL internals, MySQL internals
+@c German node CREATE FUNCTION
+@subsection @code{CREATE FUNCTION / DROP FUNCTION}-Syntax
+
+@findex CREATE FUNCTION
+@findex DROP FUNCTION
+@findex UDF-Funktionen
+@findex benutzerdefinierte Funktionen
+@findex Funktionen, benutzerdefinierte
+
+@example
+CREATE [AGGREGATE] FUNCTION funktion RETURNS @{STRING|REAL|INTEGER@}
+ SONAME gemeinsame_bibliothek
+
+DROP FUNCTION funktion
+@end example
+
+Eine benutzerdefinierte Funktion (UDF) ist eine Möglichkeit, MySQL durch
+eine neue Funktion zu erweitern, die wie die nativen (eingebauten)
+MySQL-Funktionen, z. B. @code{ABS()} und @code{CONCAT()}, funktioniert.
+
+@code{AGGREGATE} ist eine neue Option für MySQL-Version 3.23. Eine
+@code{AGGREGATE}-Funktion funktioniert genau wie eine native MySQL-
+@code{GROUP}-Funktion wie @code{SUM} oder @code{COUNT()}.
+
+@code{CREATE FUNCTION} speichert den Funktionnamen, -typ und die gemeinsam
+genutzte Bibliothek in der @code{mysql.func}-Systemtabelle. Sie benötigen
+die @strong{insert}- und @strong{delete}-Berechtigungen für die
+@code{mysql}-Datenbank, um Funktionen zu erzeugen und zu löschen.
+
+Alle aktiven Funktionen werden jedes Mal wieder geladen, wenn der Server
+startet, es sei denn, Sie starten ihn mit der
+@code{--skip-grant-tables}-Option. In diesem Fall wird die
+UDF-Initialisierung übersprungen, so dass UDFs nicht verfügbar sind. (Eine
+aktive Funktion ist eine, die mit @code{CREATE FUNCTION} geladen und nicht
+mit @code{DROP FUNCTION} entfernt wurde.)
+
+Wegen weiterer Anleitungen zum Schreiben benutzerdefinierte Funktionen
+siehe @ref{MySQL internals}. Damit der UDF-Mechanismus
+funktioniert, müssen Funktionen in C oder C++ geschrieben sein. Ihr
+Betriebssystem muss dynamisches Laden unterstützen und Sie müssen
+@code{mysqld} dynamisch (nicht statisch) kompiliert haben.
+
+Beachten Sie, dass Sie für das Funktionieren von @code{AGGREGATE} eine
+@code{mysql.func}-Tabelle benötigen, die die Spalte @code{typ} enthält.
+Wenn das nicht der Fall ist, sollten Sie das Skript
+@code{mysql_fix_privilege_tables} laufen lassen, um diesen Mangel zu
+beheben.
+
+
+@node Adding UDF, Adding native function, CREATE FUNCTION, MySQL internals
+@c German node UDF hinzufügen
+@subsection Hinzufügen einer neuen benutzerdefinierten Funktion
+
+@cindex hinzufügen, benutzerdefinierte Funktionen
+@cindex benutzerdefinierte Funktionen, hinzufügen
+@cindex Funktionen, benutzerdefinierte, hinzufügen
+
+
+
+Damit der UDF-Mechanismus funktioniert, müssen Funktionen in C oder C++
+geschrieben sein. Ihr Betriebssystem muss dynamisches Laden unterstützen
+und Sie müssen @code{mysqld} dynamisch (nicht statisch) kompiliert
+haben. Die MySQL-Quelldistribution enthält eine Datei
+@file{sql/udf_example.cc}, die 5 neue Funktionen definiert. Sehen Sie in
+dieser Datei nach, wie die UDF-Aufruf-Konventionen funktionieren.
+
+Damit @code{mysqld} UDF-Funktionen benutzen kann, sollten Sie MySQL mit
+@code{--with-mysqld-ldflags=-rdynamic} konfigurieren. Der Grund liegt
+darin, dass Sie auf vielen Plattformen (inklusive Linux) eine dynamische
+Bibliothek (mit @code{dlopen()}) von einem statisch gelinkten Programm
+laden können, was Sie erhalten würden, wenn Sie
+@code{--with-mysqld-ldflags=-all-static} benutzen. Wenn Sie eine UDF
+benutzen wollen, die auf Symbole von @code{mysqld} zugreifen muss (wie das
+@code{methaPhone}-Beispiel in @file{sql/udf_example.cc}, das
+@code{default_charset_info} benutzt), müssen Sie das Programm mit
+@code{-rdynamic} benutzen (siehe @code{man dlopen}).
+
+Für jede Funktion, die Sie in SQL-Statements benutzen wollen, sollten Sie
+die entsprechenden C- (oder C++-) Funktionen benutzen. In den unten
+stehenden Ausführungen wird ``xxx'' als Beispiel-Funktionsname benutzt. Um
+zwischen SQL- und C-/C++-Benutzung zu unterscheiden, kennzeichnet
+@code{XXX()} (Großschreibung) einen SQL-Funktionsaufruf und @code{xxx()}
+(Kleinschreibung) einen C-/C++-Funktionsaufruf.
+
+The C-/C++-Funktionen, die Sie für die Implementierung der Schnittstelle
+für @code{XXX()} schreiben, sind:
+
+@table @asis
+@item @code{xxx()} (required)
+Die Hauptfunktion. Hier wird das Funktionsergebnis berechnet. Der
+Zusammenhang zwischen dem SQL-Typ und dem Rückgabe-Typ Ihrer
+C-/C++-Funktion ist unten dargestellt:
+
+@multitable @columnfractions .2 .8
+@item @strong{SQL-Typ} @tab @strong{C-/C++-Typ}
+@item @code{STRING} @tab @code{char *}
+@item @code{INTEGER} @tab @code{long long}
+@item @code{REAL} @tab @code{double}
+@end multitable
+
+@item @code{xxx_init()} (optional)
+Die Initialisierungsfunktion für @code{xxx()}. Sie kann für folgendes
+benutzt werden:
+
+@itemize @bullet
+@item
+Um die Anzahl von Argumenten für @code{XXX()} zu prüfen.
+@item
+Um zu prüfen, ob die Argumente vom erforderlichen Typ sind oder,
+alternativ, MySQL mitzuteilen, den Argumenttyp zu erzwingen, den Sie beim
+Aufruf der Hauptfunktion brauchen.
+@item
+Um jeglichen Speicher zuzuweisen, der von der Hauptfunktion benötigt wird.
+@item
+Um die maximale Länge des Ergebnisses anzugeben.
+@item
+Um (für @code{REAL}-Funktionen) die maximale Anzahl von Dezimalstellen
+anzugeben.
+@item
+Um festzulegen, ob das Ergebnis @code{NULL} sein darf oder nicht.
+@end itemize
+
+@item @code{xxx_deinit()} (optional)
+Die Deinitialisierungsfunktion für @code{xxx()}. Sie sollte jeglichen
+Speicher freigeben (deallozieren), der durch die Initialisierungsfunktion
+zugewiesen wurde.
+@end table
+
+Wenn ein SQL-Statement @code{XXX()} aufruft, ruft MySQL die
+Initialisierungsfunktion @code{xxx_init()} auf, damit diese die notwendige
+Einrichtung vornehmen kann wie Argumente prüfen oder Speicherzuweisung.
+Wenn @code{xxx_init()} einen Fehler zurückgibt, wird das SQL-Statement mit
+einer Fehlermeldung abgebrochen, die Haupt- und
+Deinitialisierungsfunktionen werden nicht aufgerufen. Ansonsten wird die
+Hauptfunktion @code{xxx()} für jede Zeile aufgerufen. Nachdem alle Zeilen
+abgearbeitet sind, wird die Deinitialisierungsfunktion @code{xxx_deinit()}
+aufgerufen, damit sie die erforderlichen Aufräumarbeiten ausführen kann.
+
+Alle Funktionen müssen Thread-sicher sein (nicht nur die Hauptfunktion,
+sondern auch die Initialisierungs- und Deinitialisierungsfunktionen). Das
+heißt, dass Sie keinerlei globale oder statische Variablen zuweisen
+dürfen, die sich ändern! Wenn Sie Speicher brauchen, sollten Sie ihn in
+@code{xxx_init()} zuweisen und in @code{xxx_deinit()} freigeben.
+
+
+@menu
+* UDF calling::
+* UDF arguments::
+* UDF return values::
+* UDF compiling::
+@end menu
+
+@node UDF calling, UDF arguments, Adding UDF, Adding UDF
+@c German node UDF-Aufruf-Sequenzen
+@subsubsection UDF-Aufruf-Sequenzen
+
+@cindex Sequenzen aufrufen, UDF
+
+Die Hauptfunktion sollte wie unten dargestellt deklariert werden. Beachten
+Sie, dass sich der Rückgabetyp und der Parameter unterscheiden, abhängig
+davon, wie Sie die SQL-Funktion @code{XXX()} deklarieren, damit sie
+@code{STRING}, @code{INTEGER} oder @code{REAL} im @code{CREATE
+FUNCTION}-Statement zurückgibt:
+
+@noindent
+Bei @code{STRING}-Funktionen:
+
+@example
+char *xxx(UDF_INIT *initid, UDF_ARGS *args,
+ char *result, unsigned long *length,
+ char *is_null, char *error);
+@end example
+
+@noindent
+Bei @code{INTEGER}-Funktionen:
+
+@example
+long long xxx(UDF_INIT *initid, UDF_ARGS *args,
+ char *is_null, char *error);
+@end example
+
+@noindent
+Bei @code{REAL}-Funktionen:
+
+@example
+double xxx(UDF_INIT *initid, UDF_ARGS *args,
+ char *is_null, char *error);
+@end example
+
+Die Initialisierungs- und Deinitialisierungsfunktionen werden wie folgt
+deklariert:
+
+@example
+my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
+
+void xxx_deinit(UDF_INIT *initid);
+@end example
+
+Der @code{initid}-Parameter wird an alle drei Funktionen übergeben. Er
+zeigt auf eine @code{UDF_INIT}-Struktur, die benutzt wird, um Informationen
+zwischen den Funktionen zu übermitteln. Die
+@code{UDF_INIT}-Strukturmitglieder sind unten aufgelistet. Die
+Initialisierungsfunktion sollte alle Mitglieder ausfüllen, die sie ändern
+will. (Um für ein Mitglied den Vorgabewert zu verwenden, lassen Sie es
+unverändert.)
+
+@table @code
+@item my_bool maybe_null
+@code{xxx_init()} sollte @code{maybe_null} auf @code{1} setzen, wenn
+@code{xxx()} @code{NULL} zurückgeben kann. Der Vorgabewert ist @code{1},
+wenn irgend eins der Argumente als @code{maybe_null} deklariert ist.
+
+@item unsigned int Dezimalstellen
+Anzahl von Dezimalstellen. Der Vorgabewert ist die maximale Anzahl von
+Dezimalstellen in den Argumenten, die an die Hauptfunktion übergeben
+werden. (Wenn der Funktion beispielsweise die Argumente @code{1.34},
+@code{1.345} und @code{1.3} übergeben werden, wäre der Vorgabewert 3, weil
+@code{1.345} 3 Dezimalstellen hat.
+
+@item unsigned int max_length
+Die maximale Länge des Zeichenkettenergebnisses. Der Vorgabewert ist
+unterschiedlich, abhängig vom Ergebnistyp der Funktion. Bei
+Zeichenketten-Funktionen ist die Vorgabe die Länge des längsten Arguments.
+Bei Ganzzahl-Funktionen ist die Vorgabe 21 Ziffern. Bei REAL-Funktionen ist
+die Vorgabe 13 plus die Anzahl von Dezimalstellen, die von
+@code{initid->Dezimalstellen} angezeigt werden. (Bei numerischen Funktionen
+enthält die Länge jedes Vorzeichen- oder Dezimalpunkt-Zeichen.)
+
+Wenn Sie einen Blob zurückgeben wollen, können Sie diesen auf 65 KB oder
+16MB setzen. Der Speicher wird nicht zugewiesen, aber dazu verwendet, um zu
+entscheiden, welcher Spaltentyp benutzt werden soll, falls es notwendig
+werden sollte, Daten temporär zu speichern.
+
+@item char *ptr
+Ein Zeiger, den die Funktion für eigene Zwecke verwenden kann.
+Beispielsweise können Funktionen @code{initid->ptr} benutzen, um
+Informationen über den zugewiesenen Speicher zwischen den Funktionen zu
+kommunizieren. Beispiel, um in @code{xxx_init()} Speicher zuzuweisen und
+ihn diesem Zeiger zuzuordnen:
+
+@example
+initid->ptr = allocated_memory;
+@end example
+
+In @code{xxx()} und @code{xxx_deinit()} verweisen Sie auf
+@code{initid->ptr}, um Speicher zu verwenden oder freizugeben.
+@end table
+
+
+@node UDF arguments, UDF return values, UDF calling, Adding UDF
+@c German node UDF-Argumente
+@subsubsection Verarbeitung von Argumenten
+
+@cindex Verarbeitung von Argumenten
+@cindex Verarbeitung, Argumente
+
+Der @code{args}-Parameter zeigt auf eine @code{UDF_ARGS}-Struktur, die
+unten aufgelistete Mitglieder hat:
+
+@table @code
+@item unsigned int arg_count
+Die Anzahl von Argumenten. Prüfen Sie diesen Wert in der
+Initialisierungsfunktion, wenn Sie wollen, dass Ihre Funktion mit einer
+bestimmten Anzahl von Argumenten aufgerufen wird. Beispiel:
+
+@example
+if (args->arg_count != 2)
+@{
+ strcpy(message,"XXX() benoetigt zwei Argumente");
+ return 1;
+@}
+@end example
+
+
+@item enum Item_result *arg_type
+Die Typen für jedes Argument. Die möglichen Typenwerte sind
+@code{STRING_RESULT}, @code{INT_RESULT} und @code{REAL_RESULT}.
+
+Um sicherzustellen, dass die Argumente vom angegebenen Typ sind und einen
+Fehler zurückgeben, falls nicht, prüfen Sie das @code{arg_type}-Array in
+der Initialisierungsfunktion. Beispiel:
+
+@example
+if (args->arg_type[0] != STRING_RESULT ||
+ args->arg_type[1] != INT_RESULT)
+@{
+ strcpy(message,"XXX() erfordert eine Zeichenkette und eine Ganzzahl");
+ return 1;
+@}
+@end example
+
+Als Alternative dazu, dass Ihre Funktionsargumente von bestimmten Typen
+sein müssen, können Sie die Initialisierungsfunktion benutzen, um die
+@code{arg_type}-Elemente auf die Typen zu setzen, die Sie wollen. Das
+veranlasst MySQL, die Typen der Argumente bei jedem Aufruf von @code{xxx()}
+zu erzwingen. Um beispielsweise zu erzwingen, dass die ersten zwei
+Argumente Zeichenkette und Ganzzahl sind, geben Sie in @code{xxx_init()}
+folgendes ein:
+
+@example
+args->arg_type[0] = STRING_RESULT;
+args->arg_type[1] = INT_RESULT;
+@end example
+
+@item char **args
+@code{args->args} kommuniziert der Initialisierungsfunktion Informationen
+über die allgemeine Natur der Argumente, mit der Ihre Funktion aufgerufen
+wurde. Bei einem Konstanten-Argument @code{i} zeigt @code{args->args[i]}
+auf den Argumentwert. (Siehe unten wegen Anleitungen, wie auf diesen Wert
+korrekt zugegriffen wird.) Bei einem Nicht-Konstanten-Argument ist
+@code{args->args[i]} @code{0}. Ein Konstanten-Argument ist ein Ausdruck,
+der nur Konstanten wie @code{3} oder @code{4*7-2} oder @code{SIN(3.14)}
+benutzt. Ein Nicht-Konstanten-Argument ist ein Ausdruck, der auf Werte
+verweist, die sich von Zeile zu Zeile ändern können, wie Spaltennamen oder
+Funktionen, die mit Nicht-Konstanten-Argumenten aufgerufen werden.
+
+Bei jedem Aufruf der Hauptfunktion enthält @code{args->args} die
+tatsächlichen Argumente, die für die Zeile übergeben werden, die momentan
+verarbeitet wird.
+
+Funktionen können auf ein Argument @code{i} wie folgt verweisen:
+
+@itemize @bullet
+@item
+Ein Argument des Typs @code{STRING_RESULT} wird als ein Zeichenkettenzeiger
+plus einer Länge angegeben, um die Handhabung von Binärdaten oder Daten
+beliebiger Länge zu erlauben. Die Zeichenketten-Inhalte sind als
+@code{args->args[i]} und die Zeichenkettenlänge als @code{args->lengths[i]}
+verfügbar. Sie sollten nicht davon ausgehen, dass Zeichenketten
+null-terminiert sind.
+
+@item
+Bei einem Argument des Typs @code{INT_RESULT} müssen Sie
+@code{args->args[i]} zu einem @code{long long}-Wert machen (cast):
+
+@example
+long long int_val;
+int_val = *((long long*) args->args[i]);
+@end example
+
+@item
+Bei einem Argument des Typs @code{REAL_RESULT} müssen Sie
+@code{args->args[i]} zu einem @code{double}-Wert machen (cast):
+
+@example
+double real_val;
+real_val = *((double*) args->args[i]);
+@end example
+@end itemize
+
+@item unsigned long *lengths
+Bei der Initialisierungsfunktion gibt das @code{lengths}-Array die maximale
+Zeichenkettenlänge jedes Arguments an. Bei jedem Aufruf der Hauptfunktion
+enthält @code{lengths} die tatsächlichen Längen jeglicher
+Zeichenketten-Argumente, die für die momentan verarbeitete Zeile übergeben
+werden. Bei Argumenten des Typs @code{INT_RESULT} oder @code{REAL_RESULT}
+enthält @code{lengths} immer noch die maximale Länge des Arguments (wie bei
+der Initialisierungsfunktion).
+@end table
+
+
+@node UDF return values, UDF compiling, UDF arguments, Adding UDF
+@c German node UDF-Rückgabewerte
+@subsubsection Rückgabewerte und Fehlerbehandlung
+
+@cindex UDFs, Rückgabewerte
+@cindex Rückgabewerte, UDFs
+@cindex Fehler, Handhabung in UDFs
+@cindex Handhabung, Fehler
+
+Die Initialisierungsfunktion sollte @code{0} zurückgeben, wenn kein Fehler
+auftrat, ansonsten @code{1}. Wenn ein Fehler auftritt, sollte
+@code{xxx_init()} eine null-terminierte Fehlermeldung im
+@code{message}-Parameter enthalten. Die Meldung wird an den Client
+übergeben. Der Meldungspuffer ist @code{MYSQL_ERRMSG_SIZE} Zeichen lang,
+aber Sie sollten versuchen, die Meldung kleiner als 80 Zeichen zu halten,
+damit sie auf die Anzeigebreite eines Standard-Terminals passt.
+
+Der Rückgabewert der Hauptfunktion @code{xxx()} ist der Funktionswert, bei
+@code{long long}- und @code{double}-Funktionen. Eine Zeichenkettenfunktion
+sollte einen Zeiger auf das Ergebnis und die Länge der Zeichenkette in den
+@code{length}-Argumenten zurückgeben.
+
+Setzen Sie diese auf die Inhalte und Länge des Rückgabewerts. Beispiel:
+
+@example
+memcpy(result, "ergebnis_zeichenkette", 13);
+*length = 13;
+@end example
+
+Der @code{result}-Puffer, der an die Berechnungsfunktionen übergeben wird,
+ist 255 Byte Groß. Wenn Ihr Ergebnis dort hinein passt, müssen Sie sich um
+die Speicherzuweisung für Ergebnisse nicht kümmern.
+
+Wenn Ihre Zeichenketten-Funktion eine Zeichenkette zurückgeben muss, die
+länger als 255 Bytes ist, müssen Sie den Platz dafür mit @code{malloc()} in
+Ihrer @code{xxx_init()}-Funktion oder Ihrer @code{xxx()}-Funktion zuweisen
+und in Ihrer @code{xxx_deinit()}-Funktion freigeben. Sie können den
+zugewiesenen Speicher im @code{ptr}-Slot in der @code{UDF_INIT}-Struktur
+für erneute Benutzung durch zukünftige @code{xxx()}-Aufrufe speichern.
+@xref{UDF calling}.
+
+Um einen Rückgabewert von @code{NULL} in der Hauptfunktion anzuzeigen,
+setzen Sie @code{is_null} auf @code{1}:
+
+@example
+*is_null = 1;
+@end example
+
+Um eine Fehlerrückgabe in der Hauptfunktion anzuzeigen, setzen Sie den
+@code{error}-Parameter auf @code{1}:
+
+@example
+*error = 1;
+@end example
+
+Wenn @code{xxx()} @code{*error} für beliebige Zeilen auf @code{1} setzt,
+ist der Funktionswert der aktuellen Zeile @code{NULL}, was auch für
+nachfolgende Zeilen gilt, die von dem Statement verarbeitet werden, in dem
+@code{XXX()} aufgerufen wurde. (@code{xxx()} wird für nachfolgende Zeilen
+nicht einmal aufgerufen.) @strong{HINWEIS:} In MySQL-Versionen vor 3.22.10
+sollten Sie sowohl @code{*error} als auch und @code{*is_null} setzen:
+
+@example
+*error = 1;
+*is_null = 1;
+@end example
+
+
+@node UDF compiling, , UDF return values, Adding UDF
+@c German node UDF kompilieren
+@subsubsection Kompilieren und Installieren benutzerdefinierter Funktionen
+
+@cindex Kompilieren, benutzerdefinierte Funktionen
+@cindex UDFs, kompilieren
+@cindex installieren, benutzerdefinierte Funktionen
+
+Dateien, die UDFs implementieren, müssen auf dem Host kompiliert und
+installiert werden, auf dem der Server läuft. Dieser Prozess wird unten am
+Beispiel der UDF-Datei @file{udf_example.cc} beschrieben, die in der
+MySQL-Quelldistribution enthalten ist. Diese Datei enthält folgende
+Funktionen:
+
+@itemize @bullet
+@item
+@code{metaphon()} gibt eine metaphon-Zeichenkette des
+Zeichenkettenarguments zurück. Das ist etwas wie eine Soundex-Zeichenkette,
+nur etwas besser für englisch angepasst.
+@item
+@code{myfunc_double()} gibt die Summe der ASCII-Werte der Zeichen in ihren
+Argumenten zurück, geteilt durch die Summe der Längen ihrer Argumente.
+@item
+@code{myfunc_int()} gibt die Summe der Längen ihrer Argumente zurück.
+@item
+@code{sequence([const int])} gibt eine Sequenz zurück, die mit der
+angegebenen Zahl startet oder mit 1, wenn keine Zahl angegeben wurde.
+@item
+@code{lookup()} gibt die IP-Nummer für einen Hostnamen zurück.
+@item
+@code{reverse_lookup()} gibt den Hostnamen für eine IP-Nummer zurück. Die
+Funktion kann mit einer Zeichenkette @code{"xxx.xxx.xxx.xxx"} oder mit vier
+Zahlen aufgerufen werden.
+@end itemize
+
+Eine dynamisch ladbare Datei sollte als gemeinsam nutzbare Objektdatei
+kompiliert werden, etwa mit folgendem Befehl:
+
+@example
+shell> gcc -shared -o udf_example.so myfunc.cc
+@end example
+
+Die korrekten Kompiler-Optionen für Ihr System finden Sie leicht heraus,
+wenn Sie diesen Befehl im @file{sql}-Verzeichnis Ihres MySQL-Quellbaums
+laufen lassen:
+
+@example
+shell> make udf_example.o
+@end example
+
+Sie sollten einen Kompilierbefehl laufen lassen, der dem ähnelt, was
+@code{make} anzeigt, ausser dass Sie die @code{-c}-Option kurz vor dem
+Zeilenende entfernen und @code{-o udf_example.so} am Zeilenende hinzufügen
+sollten. (Auf manchen Systemen können Sie @code{-c} im Befehl lassen.)
+
+Wenn Sie ein gemeinsam genutztes Objekt kompiliert haben, das UDFs enthält,
+müssen Sie es danach installieren und MySQL darüber informieren. Wenn Sie
+ein gemeinsam genutztes Objekt von @file{udf_example.cc} kompilieren, wird
+eine Datei etwa mit dem Namen @file{udf_example.so} erzeugt (der exakte
+Name variiert von Plattform zu Plattform). Kopieren Sie diese Datei in ein
+Verzeichnis, das von @code{ld} durchsucht wird, wie @file{/usr/lib}. Auf
+vielen Systemen können Sie die @code{LD_LIBRARY}- oder
+@code{LD_LIBRARY_PATH}-Umgebungsvariable so setzen, dass sie auf das
+Verzeichnis zeigt, wo Sie Ihre UDF-Funktionsdateien haben. Das
+@code{dlopen}-Handbuch sagt Ihnen, welche Variable Sie auf Ihrem System
+setzen sollten. Sie sollten diese auf @code{mysql.server} oder
+@code{safe_mysqld} setzen und @code{mysqld} neu starten.
+
+Nachdem die Bibliothek installiert ist, unterrichten Sie @code{mysqld} über
+die neuen Funktionen mit diesen Befehlen:
+
+@example
+mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so";
+mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so";
+mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so";
+mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
+mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
+mysql> CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so";
+@end example
+
+Funktionen können mit @code{DROP FUNCTION} gelöscht werden:
+
+@example
+mysql> DROP FUNCTION metaphon;
+mysql> DROP FUNCTION myfunc_double;
+mysql> DROP FUNCTION myfunc_int;
+mysql> DROP FUNCTION lookup;
+mysql> DROP FUNCTION reverse_lookup;
+mysql> DROP FUNCTION avgcost;
+@end example
+
+Die @code{CREATE FUNCTION}- und @code{DROP FUNCTION}-Statements
+aktualisieren die Systemtabelle @code{func} in der @code{mysql}-Datenbank.
+Der Funktionsname, -typ und gemeinsam genutzte Bibliothek werden in der
+Tabelle gespeichert. Sie benötigen die @strong{insert}- und
+@strong{delete}-Berechtigungen für die @code{mysql}-Datenbank, um
+Funktionen zu erzeugen und zu löschen.
+
+Sie sollten @code{CREATE FUNCTION} nicht benutzen, um eine Funktion
+hinzuzufügen, die bereits erzeugt wurde. Wenn Sie eine Funktion erneut
+installieren wollen, sollten Sie sie zuerst mit @code{DROP FUNCTION}
+entfernen und dann mit @code{CREATE FUNCTION} erneut installieren. Sie
+müssen so etwas zum Beispiel tun, wenn Sie eine neue Version Ihrer Funktion
+kompilieren, damit @code{mysqld} die neue Version erhält. Ansonsten würde
+der Server mit der alten Version weitermachen.
+
+Aktive Funktionen werden jedes Mal neu geladen, wenn der Server startet, es
+sei denn, Sie starten @code{mysqld} mit der
+@code{--skip-grant-tables}-Option. In diesem Fall wird die
+UDF-Initialisierung übersprungen und UDFs sind nicht verfügbar. (Eine
+aktive Funktion ist eine, die mit @code{CREATE FUNCTION} geladen und nicht
+mit @code{DROP FUNCTION} entfernt wurde.)
+
+
+@node Adding native function, , Adding UDF, MySQL internals
+@c German node Native Funktion hinzufügen
+@subsection Hinzufügen einer neuen nativen Function
+
+@cindex hinzufügen, native Funktionen
+@cindex native Funktionen, hinzufügen
+@cindex Funktionen, native, hinzufügen
+
+Die Prozedur zum Hinzufügen einer neuen nativen Funktion wird hier
+beschrieben. Beachten Sie, dass Sie einer Binärdistribution keine nativen
+Funktionen hinzufügen können, weil die Prozedur die Änderung des
+MySQL-Quelltextes beinhaltet. Sie müssen MySQL selbst aus einer
+Quelldistribution kompilieren. Beachten Sie auch, dass Sie die Prozedur
+wiederholen müssen, wenn Sie auf eine andere Version von MySQL
+aktualisieren (beispielsweise wenn eine neue Version herauskommt).
+
+Um eine neue native MySQL-Funktion hinzuzufügen, gehen Sie wie folgt vor:
+
+@enumerate
+@item
+Fügen Sie @file{lex.h} eine neue Zeile hinzu, die den Funktionsnamen im
+@code{sql_functions[]}-Array definiert.
+@item
+Wenn der Funktionsprototyp einfach ist (nur keins, eins, zwei oder drei
+Argumente entgegennimmt), sollten Sie in lex.h SYM(FUNC_ARG#) angeben
+(wobei # die Anzahl von Argumenten ist), als zweites Argument im
+@code{sql_functions[]}-Array, und eine Funktion hinzufügen, die ein
+Funktionsobjekt in @file{item_create.cc} erzeugt. Sehen Sie sich als
+Beispiel hierfür @code{"ABS"} und @code{create_funcs_abs()} an.
+
+Wenn der Funktionsprototyp kompliziert ist (zum Beispiel eine variable
+Anzahl von Argumenten entgegennimmt), sollten Sie zwei Zeile zu
+@file{sql_yacc.yy} hinzufügen. Eine gibt das Präprozessorsymbol an, das
+@code{yacc} definieren soll (das sollte am Anfang der Datei stehen).
+Definieren Sie dann die Funktionsparameter und fügen Sie ein ``item'' mit
+diesen Parametern zur @code{simple_expression}-Parsing-Regel hinzu. Sehen
+Sie sich als Beispiel alle Vorkommen von @code{ATAN} in @file{sql_yacc.yy}
+an, um zu sehen, wie das gemacht wird.
+@item
+Deklarieren Sie in @file{item_func.h} eine Klasse, die von
+@code{Item_num_func} oder @code{Item_str_func} erbt, je nachdem, ob Ihre
+Funktion eine Zahl oder eine Zeichenkette zurückgibt.
+@item
+Fügen Sie in @file{item_func.cc} eine der folgenden Deklarationen hinzu, je
+nachdem, ob Sie eine numerische oder eine Zeichenketten-Funktion
+definieren:
+@example
+double Item_func_newname::val()
+longlong Item_func_newname::val_int()
+String *Item_func_newname::Str(String *str)
+@end example
+
+Wenn Sie Ihr Objekt von irgend einem der Standard-Items erben (wie von
+@code{Item_num_func}, müssen Sie wahrscheinlich eine der oben genannten
+Funktionen definieren und das Elternobjekt sich um die anderen Funktionen
+kümmern lassen. Beispielsweise definiert die @code{Item_str_func}-Klasse
+eine @code{val()}-Funktion, die @code{atof()} auf dem Wert ausführt, der
+von @code{::str()} zurückgegeben wurde.
+
+@item
+Sie müssen wahrscheinlich auch die folgende Objektfunktion definieren:
+@example
+void Item_func_newname::fix_length_und_dec()
+@end example
+Diese Funktion sollte zumindest @code{max_length} basierend auf den
+angegebenen Argumenten berechnen. @code{max_length} ist die maximale Anzahl
+von Zeichen, die die Funktion zurückgeben kann. Diese Funktion sollte auch
+@code{maybe_null = 0} setzen, wenn die Hauptfunktion keinen
+@code{NULL}-Wert zurückgeben kann. Die Funktion kann prüfen, ob irgend eins
+der Funktionsargumente @code{NULL} zurückgeben kann, indem die Argumente
+der @code{maybe_null}-Variable geprüft werden. Sehen Sie sich als typisches
+Beispiel, wie das gemacht wird, @code{Item_func_mod::fix_length_and_dec}
+an.
+@end enumerate
+
+Alle Funktionen müssen Thread-sicher sein (mit anderen Worten: Benutzen Sie
+keine globalen oder statischen Variablen in den Funktionen, ohne sie mit
+mutexes zu schützen).
+
+Wenn Sie von @code{::val()}, @code{::val_int()} oder @code{::str()}
+@code{NULL} zurückgeben wollen, sollten Sie @code{null_value} auf 1 setzen
+und 0 zurückgeben.
+
+Bei @code{::str()}-Objektfunktionen gibt es einige zusätzliche
+Überlegungen, auf die man achten sollte:
+
+@itemize @bullet
+@item
+Das @code{String *str}-Argument stellt einen Zeichenketten-Puffer zur
+Verfügung, der benutzt werden kann, um das Ergebnis zu speichern. (Weitere
+Informationen über den @code{String}-Typ finden Sie durch einen Blick in
+die @file{sql_string.h}-Datei.)
+@item
+Die @code{::str()}-Funktion sollte die Zeichenkette zurückgeben, die das
+Ergebnis enthält, oder @code{(char*) 0}, wenn das Ergebnis @code{NULL} ist.
+@item
+Alle aktuellen Zeichenketten-Funktionen versuchen, die Zuweisung jeglichen
+Speichers zu vermeiden, ausser wenn das absolut notwendig ist!
+@end itemize
+
+
+@node Adding procedures, MySQL-Interna, MySQL internals, Extending MySQL
+@c German node Hinzufügen von Prozeduren
+@section Hinzufügen neuer Prozeduren zu MySQL
+
+@cindex Prozeduren, hinzufügen
+@cindex hinzufügen, Prozeduren
+@cindex neue Prozeduren, hinzufügen
+
+In MySQL können Sie eine Prozedur in C++ definieren, die auf Daten in einer
+Anfrage zugreifen und diese ändern kann, bevor sie an den Client geschickt
+werden. Die Änderung kann Zeile für Zeile oder auf @code{GROUP BY}-Ebene
+geschehen.
+
+Wir haben eine Beispiel-Prozedur in MySQL-Version 3.23 erzeugt, um zu
+zeigen, was getan werden kann.
+
+Zusätzlich empfehlen wir, dass Sie einen Blick auf 'mylua' werfen, das Sie
+im Contrib-Verzeichnis finden. @xref{Contrib}. Hiermit können Sie die
+LUA-Sprache benutzen, um eine Prozedur zur Laufzeit in @code{mysqld} zu
+laden.
+
+
+
+@menu
+* procedure analyse::
+* Writing a procedure::
+@end menu
+
+@node procedure analyse, Writing a procedure, Adding procedures, Adding procedures
+@c German node Prozeduranalyse
+@subsection Prozeduranalyse
+
+@code{analyse([max Elemente,[max memory]])}
+
+Diese Prozedur ist in @file{sql/sql_analyse.cc} definiert. Sie untersucht
+das Ergebnis Ihrer Anfrage und gibt eine Analyse des Ergebnisses zurück:
+
+@itemize @bullet
+@item
+@code{max elements} (Vorgabe 256) ist die maximale Anzahl unterschiedlicher
+Werte, die @code{analyse} pro Spalte findet. Dieses wird von @code{analyse}
+benutzt, um zu prüfen, ob der optimale Spaltentyp vom Typ @code{ENUM} sein
+sollte.
+@item
+@code{max memory} (Vorgabe 8.192) ist der maximale Speicher, den
+@code{analyse} pro Spalte zuweisen sollte, wenn Sie versuchen, alle
+unterschiedlichen (distinct) Werte zu finden.
+@end itemize
+
+@example
+SELECT ... FROM ... WHERE ... Prozeduranalyse([max elements,[max memory]])
+@end example
+
+
+@node Writing a procedure, , procedure analyse, Adding procedures
+@c German node Eine Prozedur schreiben
+@subsection Eine Prozedur schreiben
+
+Im Moment ist die einzige Dokumentation hierfür der Quelltext.
+
+Sie finden alle Informationen über Prozeduren, wenn Sie folgende Dateien
+untersuchen:
+
+@itemize @bullet
+@item @file{sql/sql_analyse.cc}
+@item @file{sql/procedure.h}
+@item @file{sql/procedure.cc}
+@item @file{sql/sql_select.cc}
+@end itemize
+
+
+@node MySQL-Interna, , Adding procedures, Extending MySQL
+@c German node <no English equivalent>
+@section MySQL-Interna
+
+@cindex Interna
+@cindex Thread
+
+Dieses Kapitel beschreibt viele Dinge, die Sie wissen müssen, wenn Sie am
+MySQL-Code arbeiten. Wenn Sie an der MySQL-Entwicklung mitarbeiten wollen,
+Zugriff auf den messerscharfen Code von Zwischenversionen haben wollen,
+oder einfach nur über die Entwicklung auf dem Laufenden bleiben wollen,
+folgen Sie den Anweisungen unter @xref{Installing source}.
+Wenn Sie an MySQL-Interna interessiert sind, sollten Sie auch
+@email{internals@@lists.mysql.com} abonnieren. Das ist eine Liste mit
+relativ geringem Verkehr, verglichen mit @email{mysql@@lists.mysql.com}.
+
+
+
+@menu
+* MySQL-Thread::
+* MySQL-Test-Suite::
+@end menu
+
+@node MySQL-Thread, MySQL-Test-Suite, MySQL-Interna, MySQL-Interna
+@c German node <no English equivalent>
+@subsection MySQL-Thread
+
+Der MySQL-Server erzeugt folgenden Thread:
+
+@itemize @bullet
+
+@item
+Der TCP/IP-Verbindungs-Thread erledigt alle Verbindungsanfragen und erzeugt
+einen neuen dedizierten Thread, um die Verarbeitung von Authentifizierung
+und SQL-Anfragen für jede Verbindung zu handhaben.
+
+@item
+Unter Windows NT gibt es einen Named-Pipe-Handler-Thread, der dasselbe tut
+wie der TCP/IP-Verbindungs-Thread, auf Named-Pipe-Verbindungsanforderungen.
+
+@item
+Der Signal-Thread handhabt alle Signale. Dieser Thread handhabt
+normalerweise auch Alarme und Aufrufe von @code{process_alarm()}, um
+Zeitüberschreitungen auf Verbindungen zu erzwingen, die zu lange im
+Leerlauf waren.
+
+@item
+Wenn @code{mysqld} mit @code{-DUSE_ALARM_THREAD} kompiliert wird, wird ein
+dedizierter Thread erzeugt, der Alarme handhabt. Das ist nur nützlich auf
+manchen Systemen, auf denen es Probleme mit @code{sigwait()} gibt, oder
+wenn man den @code{thr_alarm()}-Code in seiner Applikation ohne einen
+dedizierten Signal-Handhabungs-Thread benutzen will.
+
+@item
+Wenn man die @code{--flush_time=#}-Option benutzt, wird ein dedizierter
+Thread erzeugt, der alle Tabellen im angegebenen Intervall auf Platte
+zurückschreibt.
+
+@item
+Jede Verbindung hat ihren eigenen Thread.
+
+@item
+Jede unterschiedliche Tabelle, auf der man @code{INSERT DELAYED} benutzt,
+erhält ihren eigenen Thread.
+
+@item
+Wenn Sie @code{--master-host} benutzen, wird ein Slave-Replikations-Thread
+gestartet, der Aktualisierungen vom Master liest und anwendet.
+@end itemize
+
+@code{mysqladmin processlist} zeigt nur die Verbindungs-, @code{INSERT
+DELAYED}- und Replikations-Threads.
+
+
+@node MySQL-Test-Suite, , MySQL-Thread, MySQL-Interna
+@c German node <no English equivalent>
+@subsection MySQL-Test-Suite
+
+@cindex mysqltest, MySQL-Test-Suite
+@cindex mysqld testen, mysqltest
+
+Bis vor Kurzem basierte unsere vollumfängliche Haupt-Test-Suite auf
+proprietären Kundendaten und war deshalb nicht öffentlich verfügbar. Der
+einzige öffentlich verfügbare Teil unseres Testprozesses bestand aus dem
+@code{Crash-me}-Test, einem Perl-DBI/DBD-Benchmark, der im
+@code{sql-bench}-Verzeichnis liegt, und verschiedenen Tests im
+@code{tests}-Verzeichnis. Das Fehlen einer standardisierten, öffentlich
+verfügbaren Test-Suite machte es unseren Benutzern und auch Entwicklern
+schwer, Regressionstests auf den MySQL-Code durchzuführen. Um das Problem
+anzugehen, haben wir ein neues Testsystem geschaffen, das ab Version
+3.23.29 den Quell- und Binärdistributionen beiliegt.
+
+Der aktuelle Satz von Testfällen testet nicht alles in MySQL, sollte aber
+die offensichtlichsten Bugs im SQL-Verarbeitungscode offen legen, sowie
+Betriebssystem- und Bibliotheks-Probleme, und er testet recht gründlich die
+Replikation. Unser letztliches Ziel ist es, dass die Tests 100% des Codes
+abdecken. Beiträge zu unserer Test-Suite sind herzlich willkommen,
+besonders Tests, die die Funktionalität untersuchen, die für Ihr System
+kritisch ist, weil das sicherstellt, dass alle zukünftigen MySQL-Releases
+mit Ihren Applikationen funktionieren.
+
+
+
+@menu
+* mysqltest laufen lassen::
+* MySQL-Tests erweitern::
+* mysqltest-Bugs berichten::
+@end menu
+
+@node mysqltest laufen lassen, MySQL-Tests erweitern, MySQL-Test-Suite, MySQL-Test-Suite
+@c German node <no English equivalent>
+@subsubsection Die MySQL-Test-Suite laufen lassen
+
+Das Testsystem besteht aus einem Test-Sprachinterpreter (@code{mysqltest}),
+einem Shell-Skript, um alle Tests laufen zu lassen
+tests(@code{mysql-test-run}), den eigentlichen Testfällen, die in einer
+speziellen Testsprache geschrieben sind, und ihren erwarteten Ergebnissen.
+Um die Test-Suite nach dem Bauen auf Ihrem System laufen zu lassen, geben
+Sie @code{make test} oder @code{mysql-test/mysql-test-run} von der Wurzel
+der Quellinstallation aus ein. Wenn Sie eine Binärdistribution installiert
+haben, wechseln Sie (@code{cd}) zur Wurzel der Installation (zum Beispiel
+@code{/usr/local/mysql}) und geben @code{scripts/mysql-test-run} ein. Alle
+Tests sollten erfolgreich durchlaufen. Wenn nicht, sollten Sie versuchen,
+den Grund herauszufinden, und das Problem zu berichten, wenn es ein Bug in
+MySQL ist. @xref{mysqltest-Bugs berichten}.
+
+Wenn eine Kopie von @code{mysqld} auf Ihrer Maschine läuft, wo Sie die
+Test-Suite laufen lassen wollen, müssen Sie ihn nicht anhalten, solange er
+nicht die Ports @code{9306} und @code{9307} benutzt. Wenn einer dieser
+Ports belegt ist, sollten Sie @code{mysql-test-run} editieren und die Werte
+des Master- und / oder Slave-Ports auf verfügbare Ports ändern.
+
+Sie können einen einzelnen Testfall mit @code{mysql-test/mysql-test-run
+test_name} laufen lassen.
+
+Wenn ein Test fehlschlägt, sollten Sie versuchen, @code{mysql-test-run} mit
+der @code{--force}-Option laufen zu lassen, um zu prüfen, ob irgend ein
+weiterer Test fehlschlägt.
+
+
+@node MySQL-Tests erweitern, mysqltest-Bugs berichten, mysqltest laufen lassen, MySQL-Test-Suite
+@c German node <no English equivalent>
+@subsubsection Die MySQL-Test-Suite erweitern
+
+Sie können die @code{mysqltest}-Sprache benutzen, um Ihre eigenen Testfälle
+zu schreiben. Leider gibt es noch keine komplette Dokumentation dafür - das
+soll in Kürze aber der Fall sein. Sie können sich jedoch die aktuellen
+Testfälle ansehen und sie als Beispiel benutzen. Folgende Punkte sollen
+Ihnen beim Start helfen:
+
+@itemize @bullet
+@item
+Die Tests liegen in @code{mysql-test/t/*.test}
+
+@item
+Ein Testfall besteht aus @code{;}-begrenzten Statements und ist ähnlich der
+Eingabe in den @code{mysql}-Kommandozeilen-Client. Ein Statement ist
+vorgabemäßig eine Anfrage, die an den MySQL-Server geschickt werden soll,
+es sei denn, es wird als interner Befehl erkannt (zum Beispiel
+@code{sleep}).
+
+@item
+Alle Anfragen, die Ergebnisse produzieren, zum Beispiel @code{SELECT},
+@code{SHOW}, @code{EXPLAIN} usw., müssen mit
+@code{@@/pfad/zu/ergebnis/datei} beginnen. Die Datei muss die erwarteten
+Ergebnisse enthalten. Eine einfache Art, die Ergebnisdatei zu erzeugen,
+ist, @code{mysqltest -r < t/test-case-name.test} vom
+@code{mysql-test}-Verzeichnis aus laufen zu lassen und dann die erzeugten
+Ergebnisdateien zu editieren und sie - falls nötig - an die erwartete
+Ausgabe anzupassen. Seien Sie in diesem Fall sehr vorsichtig, keine
+unsichtbaren Zeichen hinzuzufügen oder zu löschen - stellen Sie sicher,
+dass Sie nur den Text ändern und / oder Zeilen löschen. Wenn Sie eine Zeile
+einfügen müssen, achten Sie darauf, dass die Felder mit einem harten
+Tabulator-Zeichen getrennt sind und dass es ein hartes Tabulator-Zeichen am
+Zeilenende gibt. Gegebenfalls sollten Sie @code{od -c} benutzen, um sich zu
+vergewissern, dass Ihr Texteditor beim Editieren nichts durcheinander
+gebracht hat. Wir hoffen natürlich, dass Sie die Ausgabe von
+@code{mysqltest -r} nie editieren müssen, weil das nur der Fall ist, wenn
+Sie einen Bug finden.
+
+@item
+Um mit unserer Einrichtung konsistent zu sein, sollten Sie Ihre
+Ergebnisdateien ins @code{mysql-test/r}-Verzeichnis stellen und sie
+@code{test_name.result} nennen. Wenn der Test mehr als ein Ergebnis
+erzeugt, sollten Sie @code{test_name.a.result}, @code{test_name.b.result}
+usw. verwenden.
+
+@item
+Wenn ein Statement einen Fehler zurückgibt, sollten Sie die Zeile vor dem
+Statement mit @code{--error fehler_nummer} kennzeichnen. Die Fehlernummer
+kann eine Auflistung möglicher Fehlerzahlen sein, getrennt durch
+@code{','}.
+
+@item
+Wenn Sie einen Replikations-Testfall schreiben, sollten Sie in die erste
+Zeile der Testdatei @code{source include/master-slave.inc;} schreiben. Um
+zwischen Master und Slave umzuschalten, benutzen Sie @code{connection
+master;} und @code{connection slave;}. Wenn Sie etwas auf einer
+abwechselnden Verbindung machen müssen, können Sie @code{connection
+master1;} für den Master und @code{connection slave1;} für den Slave
+eingeben.
+
+@item
+Wenn Sie etwas in einer Schleife ausführen müssen, können Sie zum Beispiel
+folgendes tun:
+@example
+let $1=1000;
+while ($1)
+@{
+ # machen Sie Ihre Anfragen hier
+ dec $1;
+@}
+@end example
+
+@item
+Um zwischen Anfragen zu schlafen, benutzen Sie den @code{sleep}-Befehl. Er
+unterstützt Bruchteile von Sekunden, daher können Sie zum Beispiel
+@code{sleep 1.3;} ausführen, um 1,3 Sekunden zu schlafen.
+
+@item
+Um den Slave für Ihren Testfall mit zusätzlichen Optionen laufen zu lassen,
+geben Sie diese im Kommandozeilenformat in
+@code{mysql-test/t/test_name-slave.opt} ein. Für den Master geben Sie sie
+in @code{mysql-test/t/test_name-master.opt} ein.
+
+@item
+Wenn Sie eine Frage zur Test-Suite haben oder einen Testfall beisteuern
+wollen, schicken Sie eine E-Mail an @email{Interna@@lists.mysql.com}. Weil
+die Liste keine Dateianhänge akzeptiert, sollten Sie alle relevanten
+Dateien per FTP an @url{ftp://support.mysql.com/pub/mysql/Incoming}
+schicken.
+
+@end itemize
+
+
+@node mysqltest-Bugs berichten, , MySQL-Tests erweitern, MySQL-Test-Suite
+@c German node <no English equivalent>
+@subsubsection Bugs in der MySQL-Test-Suite berichten
+
+Wenn Ihre MySQL-Version die Test-Suite nicht fehlerfrei durchläuft, sollten
+Sie folgendes tun:
+
+@itemize @bullet
+@item
+Schicken Sie keinen Bug-Bericht, bevor Sie so weit wie möglich
+herausgefunden haben, was schief ging! Benutzen Sie für den Bug-Bericht
+bitte das @code{mysqlbug}-Skript, so dass wir Informationen über Ihr System
+und die @code{MySQL}-Version erhalten. @xref{Bug reports}.
+@item
+Stellen Sie sicher, dass die Ausgabe von @code{mysql-test-run} beiliegt,
+sowie alle Inhalte aller @code{.reject}-Dateien im
+@code{mysql-test/r}-Verzeichnis.
+@item
+Wenn ein Test in der Test-Suite fehlschlägt, prüfen Sie, ob der Test auch
+fehlschlägt, wenn er allein laufen gelassen wird:
+
+@example
+cd mysql-test
+mysql-test-run --local test-name
+@end example
+
+Wenn das fehlschlägt, sollten Sie MySQL mit @code{--with-debug}
+konfigurieren und @code{mysql-test-run} mit der @code{--debug}-Option
+laufen lassen. Wenn auch das fehlschlägt, schicken Sie dei Trace-Datei
+@file{var/tmp/master.trace} an ftp://support.mysql.com/pub/mysql/secret, so
+dass wir sie untersuchen können. Denken Sie bitte daran, eine volle
+Beschreibung Ihres Systems beizufügen sowie die Version Ihrer
+mysqld-Binärdatei und wie Sie sie kompiliert haben.
+
+@item
+Versuchen Sie auch, @code{mysql-test-run} mit der @code{--force}-Option
+laufen zu lassen, um zu sehen, ob auch andere Tests fehlschlagen.
+
+@item
+Wenn Sie MySQL selbst kompiliert haben, sehen Sie im Handbuch nach, wie
+MySQL auf Ihrer Plattform kompiliert wird, oder benutzen Sie vorzugsweise
+eine der Binärdateien, die wir für Sie kompiliert haben und die Sie unter
+@uref{http://www.mysql.com/downloads/} finden. Alle unsere
+Standard-Binärdateien sollten die Test-Suite fehlerfrei durchlaufen!
+
+@item
+Wenn Sie einen Fehler wie @code{Result length mismatch} oder @code{Result
+content mismatch} erhalten, heißt das, dass die Ausgabe des Tests nicht
+genau mit der erwarteten Ausgabe übereinstimmt. Das könnte ein Bug in MySQL
+sein, könnte aber auch heißen, dass Ihre mysqld-Version unter bestimmten
+Umständen leicht abweichende Ausgaben erzeugt.
+
+Fehlgeschlagene Testergebnisse werden in eine Datei mit demselben Namen wie
+die Ergebnisdatei, mit der Endung @code{.reject}, gestellt. Wenn Ihr
+Testfall fehlschlägt, sollten Sie ein DIFF beider Dateien vornehmen. Wenn
+Sie nicht erkennen können, in welcher Hinsicht sie sich unterscheiden,
+untersuchen Sie beide mit @code{od -c} und prüfen Sie auch ihre Längen.
+
+@item
+Wenn ein Testfall völlig fehlschlägt, sollten Sie die Log-Dateien im
+@code{mysql-test/var/log}-Verzeichnis nach Hinweisen untersuchen, was
+schief ging.
+
+@item
+Wenn Sie MySQL mit Debugging kompiliert haben, können Sie versuchen, das zu
+debuggen, indem Sie @code{mysql-test-run} mit den @code{--gdb}- und / oder
+@code{--debug}-Optionen laufen lassen.
+@xref{Making trace files}.
+
+Wenn Sie MySQL nicht für Debugging kompiliert haben, sollten Sie das besser
+tun. Geben Sie einfach die @code{--with-debug}-Option für @code{configure}
+an! @xref{Installing source}.
+@end itemize
+
+
+
+
+@node Problems, Benutzer, Extending MySQL, Top
+@c German node Probleme
+@appendix Probleme und häufige Fehler
+
+@cindex Probleme, häufige Fehler
+@cindex Fehler, häufige
+
+
+Dieses Kapitel listet einige gebräuchliche Probleme und Fehlermeldungen
+auf, denen Benutzer in die Arme laufen. Sie lernen herauszufinden, was das
+Problem ist und wie Sie es lösen. Hier finden sich auch korrekte Lösungen
+einiger häufiger Probleme.
+
+
+@menu
+* What is crashing::
+* Common errors::
+* Installation Issues::
+* Administration Issues::
+* Query Issues::
+* Table Definition Issues::
+@end menu
+
+@node What is crashing, Common errors, Problems, Problems
+@c German node Was ist ein Absturz
+@appendixsec Wie man feststellt, was Probleme verursacht
+
+Wenn Sie Probleme bekommen, sollten Sie als erstes herausfinden, welches
+Programm oder Hardware-Teil die Probleme verursacht:
+
+@itemize @bullet
+@item
+Wenn Sie eins der folgenden Symptome beobachten, gibt es wahrscheinlich ein
+Hardware- (Speicher, Hauptplatine, Prozessor oder Festplatte) oder
+Kernel-Problem:
+@itemize @minus
+@item
+Die Tastatur funktioniert nicht. Normalerweise können Sie das durch Drücken
+der Feststelltaste (Caps Lock) überprüfen. Wenn sich die Anzeigeleuchte
+beim Drücken nicht an- und ausschaltet, müssen Sie Ihre Tastatur ersetzen.
+(Bevor Sie das tun, sollten Sie Ihren Computer neu starten und alle
+Kabelverbindungen zur Tastatur überprüfen.)
+@item
+Der Mauszeiger bewegt sich nicht.
+@item
+Die Maschine antwortet auf entfernte Ping-Versuche nicht.
+@item
+Andere Programme, die mit MySQL nichts zu tun haben, funktionieren nicht
+korrekt.
+@item
+Wenn Ihr System unerwartet neu startet (ein fehlerhaftes Programm auf
+Benutzerebene sollte NIE in der Lage sein, Ihr System zum Absturz zu
+bringen).
+@end itemize
+
+In solchen Fällen sollten Sie zunächst alle Kabel überprüfen und
+Diagnoseprogramme laufen lassen, um Ihre Hardware zu untersuchen! Sie
+sollten auch prüfen, ob Patches, Aktualisierungen oder Service-Packs für
+Ihre Betriebssystem verfügbar sind, die Ihre Probleme möglicherweise lösen.
+Prüfen Sie auch, ob Ihre Bibliotheken (wie glibc) aktuell sind.
+
+Es ist immer eine gute Idee, eine Maschine mit ECC-Speicher zu benutzen, um
+Speicherprobleme frühzeitig zu erkennen!
+@item
+Wenn Ihre Tastatur gesperrt ist, können Sie das eventuell beheben, indem
+Sie sich von einer anderen Maschine aus verbinden und @code{kbd_mode -a}
+ausführen.
+
+@item
+Untersuchen Sie Ihre System-Log-Datei (/var/log/messages oder ähnliches)
+nach Gründen für Ihre Probleme. Wenn Sie glauben, dass das Problem an MySQL
+liegt, sollten Sie auch die Log-Dateien von MySQL überprüfen.
+@xref{Update log}.
+
+@item
+Wenn Sie nicht glauben, ein Hardware-Problem zu haben, sollten Sie
+herausfinden, welches Programm die Probleme verursacht.
+
+Probieren Sie @code{top}, @code{ps}, @code{taskmanager} oder ein ähnliches
+Programm, um zu prüfen, welches Programm die gesamte Prozessorzeit
+konsumiert oder die Maschine blockiert.
+
+@item
+Prüfen Sie mit @code{top}, @code{df} oder einem ähnlichen Programm, wenn
+Sie keinen freien Arbeitsspeicher, Festplattenspeicher, verfügbare
+Datei-Handler oder eine andere kritische Ressource mehr haben.
+
+@item
+Wenn das Problem an einem aus dem Ruder gelaufenen Prozess liegt, können
+Sie versuchen, diesen zu killen. Wenn er nicht sterben will, gibt es
+wahrscheinlich einen Bug im Betriebssystem.
+@end itemize
+
+Wenn Sie alle anderen Möglichkeiten untersucht und ausgeschlossen haben und
+zur Schlussfolgerung gekommen sind, dass die Probleme durch den
+MySQL-Server oder ein MySQL-Client-Programm verursacht werden, ist es an
+der Zeit, einen Bug-Bericht für die Mailing-Liste oder unser Support-Team
+zu schreiben. Machen Sie im Bug-Bericht eine sehr detaillierte
+Beschreibung, wie sich Ihr System verhält und was Sie vermuten, was
+passiert. Sie sollten auch angeben, warum Sie denken, dass MySQL die
+Probleme verursacht. Ziehen Sie alle Situationen in diesem Kapitel in
+Betracht. Geben Sie genau an, welche Probleme wie auftauchen, wenn Sie Ihr
+System untersuchen. Benutzen Sie Kopieren und Einfügen, wenn Sie Ausgaben
+und / oder Fehlermeldungen von Programmen oder aus Log-Dateien beifügen!
+
+Versuchen Sie detailliert zu beschreiben, welches Programm nicht
+funktioniert, und alle Symptome, die Sie sehen! In der Vergangenheit haben
+wir viele Bug-Berichte erhalten, in denen schlicht steht, dass "das System
+nicht funktioniert". Daraus können wir natürlich keinerlei Informationen
+ziehen, wie das Problem gelöst werden könnte.
+
+Wenn ein Programm fehlschlägt, ist es immer nützlich, folgendes zu wissen:
+
+@itemize @bullet
+@item
+Hat das fragliche Programm einen Segmentation-Fehler verursacht (Core
+Dump)?
+@item
+Nimmt das Programm sich die gesamte Prozessorleistung? Überprüfen Sie das
+mit @code{top}. Lassen Sie das Programm eine Weile laufen, denn vielleicht
+evaluiert es gerade nur etwas Schwieriges.
+@item
+Wenn der @code{mysqld}-Server Probleme verursacht, können Sie dann
+@code{mysqladmin -u root ping} oder @code{mysqladmin -u root processlist}
+ausführen?
+@item
+Was sagt ein Client-Programm (zum Beispiel @code{mysql}), wenn Sie
+versuchen, sich mit dem MySQL-Server zu verbinden? Bricht der Client
+zusammen? Erhalten Sie von diesem Programm irgend welche Ausgaben?
+@end itemize
+
+Wenn Sie einen Bug-Bericht senden, sollten Sie immer den Angaben folgen,
+die in diesem Handbuch beschrieben sind. @xref{Asking questions}.
+
+
+@node Common errors, Installation Issues, What is crashing, Problems
+@c German node Häufige Fehler
+@appendixsec Einige gebräuchliche Fehler bei der Benutzung von MySQL
+
+@cindex errors, Auflistung
+
+
+
+Dieser Abschnitt listet einige Fehler auf, die Benutzer häufig erhalten.
+Hier finden Sie Beschreibungen dieser Fehler und wie man die Probleme löst.
+
+
+@menu
+* Error Access denied::
+* Gone away::
+* Can not connect to server::
+* Blocked host::
+* Too many connections::
+* Non-transactional tables::
+* Out of memory::
+* Packet too large::
+* Communication errors::
+* Full table::
+* Cannot create::
+* Commands out of sync::
+* Ignoring user::
+* Cannot find table::
+* Cannot initialize character set::
+* Not enough file handles::
+@end menu
+
+@node Error Access denied, Gone away, Common errors, Common errors
+@c German node Zugriff-verweigert-Fehler
+@appendixsubsec @code{Access denied}-Fehler
+
+@cindex Fehler, Zugriff verweigert
+@cindex Probleme, Zugriff-verweigert-Fehler
+@cindex access denied
+
+@xref{Privileges}, insbesondere @xref{Access denied}.
+
+
+@node Gone away, Can not connect to server, Error Access denied, Common errors
+@c German node Weg gegangen
+@appendixsubsec @code{MySQL server has gone away}-Fehler
+
+Dieser Abschnitt behandelt auch den verwandten @code{Lost connection to
+server during query}-Fehler.
+
+Der häufigste Grund für den @code{MySQL server has gone away}-Fehler ist
+eine Zeitüberschreitung, nach der der Server die Verbindung schloss.
+Vorgabemäßig schließt der Server die Verbindung nach 8 Stunden, wenn
+nichts passiert ist. Sie können diesen Wert mit der
+@code{wait_timeout}-Variablen ändern, die beim Start von @code{mysqld}
+gesetzt wird.
+
+Ein weiterer häufiger Grund für den @code{MySQL server has gone
+away}-Fehler ist das Absetzen eines ``close'' auf Ihre MySQL-Verbindung mit
+dem anschließenden Versuch, auf der geschlossenen Verbindung eine Anfrage
+abzusetzen.
+
+Sie können überprüfen, ob der MySQL-Server gestorben ist, indem Sie
+@code{mysqladmin version} ausführen und die Uptime untersuchen.
+
+Wenn Sie ein Skript haben, müssen Sie die Anfrage lediglich noch einmal für
+den Client absetzen, um eine automatische Neuverbindung zu machen.
+
+Normalerweise können Sie folgende Fehler-Codes für diesen Fall abfragen
+(die Betriebssystem-abhängig sind):
+
+@multitable @columnfractions .3 .7
+@item @code{CR_SERVER_GONE_ERROR} @tab Der Client konnte keine Anfrage an
+den Server schicken.
+@item @code{CR_SERVER_LOST} @tab Der Client erhielt beim Schreiben zum
+Server keinen Fehler, bekam aber keine vollständige (oder überhaupt keine)
+Antwort.
+@end multitable
+
+Sie erhalten diese Fehler auch, wenn Sie eine Anfrage zum Server schicken,
+die falsch oder zu Groß ist. Wenn @code{mysqld} ein Paket erhält, das zu
+Groß oder nicht in Ordnung ist, nimmt er hat, dass etwas mit dem Client
+schief ging und schließt die Verbindung. Wenn Sie große Anfragen brauchen
+(beispielsweise wenn Sie mit @code{BLOB}-Spalten arbeiten), können Sie die
+Anfragebeschränkung erhöhen, indem Sie @code{mysqld} mit der @code{-O
+max_allowed_packet=#}-Option starten (Vorgabe 1 MB). Der zusätzliche
+Speicher wird bei Bedarf zugewiesen, daher benutzt @code{mysqld} nur dann
+mehr Speicher, wenn Sie eine große Anfrage ausführen oder wenn
+@code{mysqld} ein großes Ergebnis zurückgeben muss!
+
+
+@node Can not connect to server, Blocked host, Gone away, Common errors
+@c German node Keine Verbindung zum Server
+@appendixsubsec @code{Can't connect to [local] MySQL server}-Fehler
+
+Ein MySQL-Client unter Unix kann sich auf zwei unterschiedliche Arten mit
+dem @code{mysqld}-Server verbinden: Unix-Sockets, die sich durch eine Datei
+im Dateisystem verbinden (Vorgabe @file{/tmp/mysqld.sock}) oder über
+TCP/IP, was sich über eine Portnummer verbindet. Unix-Sockets sind
+schneller als TCP/IP, können aber nur benutzt werden, wenn man sich zu
+einem Server auf demselben Computer verbindet. Unix-Sockets werden benutzt,
+wenn Sie keinen Hostnamen oder den speziellen Hostnamen @code{localhost}
+angeben.
+
+Unter Windows können Sie sich nur mit TCP/IP verbinden, wenn der
+@code{mysqld}-Server unter Windows 95 / 98 läuft. Wenn er unter Windows NT
+läuft, können Sie sich auch mit Named Pipes verbinden. Der Name der Named
+Pipe ist MySQL. Wenn Sie bei der Verbindung zu @code{mysqld} keinen
+Hostnamen angeben, versucht ein MySQL-Client zuerst, sich über die Named
+Pipe zu verbinden. Erst wenn das fehlschlägt, versucht er, sich über den
+TCP/IP-Port zu verbinden. Sie können die Benutzung von Named Pipes unter
+Windows erzwingen, indem Sie @code{.} als Hostnamen benutzen.
+
+Der Fehler (2002) @code{Can't connect to ...} bedeutet normalerweise, dass
+auf dem System kein MySQL-Server läuft oder dass Sie eine falsche
+Socket-Datei oder einen falschen TCP/IP-Port bei der Verbindung mit dem
+@code{mysqld}-Server benutzen.
+
+Prüfen Sie zuerst mit @code{ps} oder dem Task-Manager unter Windows, ob es
+einen laufenden Prozess namens @code{mysqld} auf Ihrem Server gibt! Wenn es
+keinen @code{mysqld}-Prozess gibt, sollten Sie einen starten. @xref{Starting server}.
+
+Wenn ein @code{mysqld}-Prozess läuft, können Sie den Server mit diesen
+unterschiedlichen Verbindungen überprüfen (die Portnummer und
+Socket-Pfadnamen können auf Ihrem System natürlich anders sein):
+
+@example
+shell> mysqladmin version
+shell> mysqladmin variables
+shell> mysqladmin -h `hostname` version variables
+shell> mysqladmin -h `hostname` --port=3306 version
+shell> mysqladmin -h 'ip_ihres_hosts' version
+shell> mysqladmin --socket=/tmp/mysql.sock version
+@end example
+
+Beachten Sie die Benutzung umgedrehter Anführungszeichen statt normaler
+Anführungszeichen beim @code{hostname}-Befehl. Diese verursachen, dass die
+Ausgabe durch @code{hostname} (das heißt des aktuellen Hostnamens) im
+@code{mysqladmin}-Befehl ersetzt wird.
+
+Hier sind einige Gründe für das Auftreten des @code{Can't connect to local
+MySQL server}-Fehlers:
+
+@itemize @bullet
+@item
+@code{mysqld} läuft nicht.
+@item
+Sie fahren auf einem System, das MIT-pThread verwendet. Wenn Sie auf einem
+System fahren, das keine nativen Threads hat, benutzt @code{mysqld} das
+MIT-pThread-Paket. @xref{Which OS}. Nicht alle
+MIT-pThread-Versionen unterstützen jedoch Unix-Sockets. Auf einem System
+ohne Socket-Unterstützung müssen Sie den Hostnamen immer explizit angeben,
+wenn Sie sich mit dem Server verbinden. Benutzen Sie diesen Befehl, um die
+Verbindung zum Server zu überprüfen:
+@example
+shell> mysqladmin -h `hostname` version
+@end example
+@item
+Jemand hat den Unix-Socket entfernt, den @code{mysqld} benutzt (Vorgabe
+@file{/tmp/mysqld.sock}). Vielleicht gibt es einen @code{cron}-Job, der den
+MySQL-Socket entfernt (beispielsweise ein Job, der alte Dateien aus dem
+@file{/tmp}-Verzeichnis entfernt). Sie können @code{mysqladmin version}
+laufen lassen und überprüfen, dass der Socket, den @code{mysqladmin}
+versucht zu benutzen, tatsächlich existiert. Die Problemlösung besteht in
+diesem Fall darin, den @code{cron}-Job so zu ändern, dass er nicht
+@file{mysqld.sock} entfernt oder den Socket an andere Stelle zu platzieren.
+@xref{Problems with mysql.sock}.
+@item
+Sie haben den @code{mysqld}-Server mit der
+@code{--socket=/pfad/zu/socket}-Option gestartet. Wenn Sie den
+Socket-Pfadnamen zum Server ändern, müssen Sie auch die MySQL-Clients
+darüber unterrichten. Das können Sie tun, indem Sie den Socket-Pfad als
+Argument an den Client übergeben. @xref{Problems with mysql.sock}.
+@item
+Sie benutzen Linux und ein Thread ist gestorben (Core Dump). In diesem Fall
+müssen Sie den anderen @code{mysqld}-Thread killen (beispielsweise mit dem
+@code{mysql_zap}-Skript), bevor Sie einen neuen MySQL-Server starten
+können. @xref{Crashing}.
+@item
+Eventuell haben Sie keine Lese- und Schreibberechtigungen entweder für das
+Verzeichnis, in dem die Socket-Datei liegt, oder keine Berechtigung für die
+Socket-Datei selbst. In diesem Fall können Sie entweder die Berechtigung
+für die Datei und / oder das Verzeichnis ändern oder @code{mysqld} neu
+starten, so dass er ein Verzeichnis benutzt, auf das Sie Zugriff haben.
+@end itemize
+
+Wenn Sie die Fehlermeldung @code{Can't connect to MySQL server on
+ein_hostname} erhalten, können Sie folgendes probieren, um den Grund des
+Problems herauszufinden:
+
+@itemize @bullet
+@item
+Überprüfen Sie, ob der Server hochgefahren ist, indem Sie @code{telnet
+ihr_hostname tcp-ip-port-nummer} ausführen und einige Male die Eingabetaste
+(@code{RETURN}) drücken. Wenn es auf diesem Port einen laufenden
+MySQL-Server gibt, sollten Sie eine Antwort erhalten, die die
+Versionsnummer des Server enthält. Wenn Sie einen Fehler wie @code{telnet:
+Unable to connect to remote host: Connection refused} erhalten, gibt es auf
+diesem Port keinen laufenden Server.
+@item
+Versuchen Sie, sich mit dem @code{mysqld}-Daemon auf der lokalen Maschine
+zu verbinden und prüfen Sie den TCP/IP-Port, den @code{mysqld} laut
+Konfiguration benutzen soll (Variable @code{port}), mit @code{mysqladmin
+variables}.
+@item
+Prüfen Sie, ob Ihr @code{mysqld}-Server nicht gestartet wurde, indem Sie
+die @code{--skip-networking}-Option verwenden.
+@end itemize
+
+
+@node Blocked host, Too many connections, Can not connect to server, Common errors
+@c German node Blockierter Host
+@appendixsubsec @code{Host '...' is blocked}-Fehler
+
+Wenn Sie einen Fehler wie folgt erhalten:
+
+@example
+Host 'hostname' is blocked because of too many connection errors.
+Unblock with 'mysqladmin flush-hosts'
+@end example
+
+Bedeutet das, dass @code{mysqld} zu viele (@code{max_connect_errors})
+Verbindungsanforderungen vom Host @code{'hostname'} erhalten hat, die
+mittendrin unterbrochen wurden. Nach @code{max_connect_errors}
+fehlgeschlagenen Anfragen nimmt @code{mysqld} an, dass etwas nicht stimmt
+(wie ein Angriff eines Crackers) und blockiert weitere
+Verbindungsanforderungen von der Site, bis jemand @code{mysqladmin
+flush-hosts} ausführt.
+
+Vorgabemäßig blockiert @code{mysqld} einen Host nach 10
+Verbindungsfehlern. Das können Sie leicht durch Starten des Servers wie
+folgt ändern:
+
+@example
+shell> safe_mysqld -O max_connect_errors=10000 &
+@end example
+
+Beachten Sie, dass Sie bei dieser Fehlermeldung für einen gegebenen Host
+zunächst prüfen sollten, ob etwas mit den TCP/IP-Verbindungen von diesem
+Host aus nicht stimmt. Wenn Ihre TCP/IP-Verbindungen nicht funktionieren,
+nützt es Ihnen nichts, den Wert der @code{max_connect_errors}-Variablen
+heraufzusetzen!
+
+
+@node Too many connections, Non-transactional tables, Blocked host, Common errors
+@c German node Zu viele Verbindungen
+@appendixsubsec @code{Too many connections}-Fehler
+
+Wenn Sie beim Verbindungsversuch den Fehler @code{Too many connections}
+erhalten, heißt das, dass es bereits @code{max_connections} Clients gibt,
+die mit dem @code{mysqld}-Server verbunden sind.
+
+Wenn Sie mehr Verbindungen als die Vorgabe (100) benötigen, können Sie
+@code{mysqld} mit einem größeren Wert für die
+@code{max_connections}-Variable neu starten.
+
+Beachten Sie, dass @code{mysqld} tatsächlich (@code{max_connections}+1)
+Clients für Verbindungen zuläßt. Die letzte Verbindung wird für einen
+Benutzer mit der @strong{process}-Berechtigung reserviert. Wenn Sie keinem
+normalen Benutzer diese Berechtigung geben (diese sollte sie nie
+benötigen), kann sich ein Administrator mit dieser Berechtigung einloggen
+und @code{SHOW PROCESSLIST} benutzen, um herauszufinden, was schief geht.
+@xref{SHOW}.
+
+Die maximale Anzahl von Verbindungen ist davon abhängig, wie gut die
+Thread-Bibliothek auf der Plattform ist. Linux oder Solaris sollten in der
+Lage sein, 500 bis 1000 gleichzeitige Verbindungen zu unterstützen, abhängig
+davon, wie viel Arbeitsspeicher Sie haben und was Ihre Clients ausführen.
+
+
+@node Non-transactional tables, Out of memory, Too many connections, Common errors
+@c German node Nicht transaktionale Tabellen
+@appendixsubsec @code{Some non-transactional changed tables couldn't be rolled back}-Fehler
+
+@cindex Nicht transaktionale Tabellen
+
+Wenn Sie den Fehler @code{Warning: Some non-transactional changed tables
+couldn't be rolled back} erhalten, wenn Sie ein @code{ROLLBACK} versuchen,
+bedeutet das, dass einige der bei der Transaktion benutzten Tabellen keine
+Transaktionen unterstützen. Diese nicht transkationalen Tabellen werden vom
+@code{ROLLBACK}-Statement nicht betroffen.
+
+Der typischste Fall, bei dem dieser Fehler auftritt, ist, wenn Sie versucht
+haben, eine Tabelle von einem Typ zu erzeugen, der von Ihrer
+@code{mysqld}-Binärdatei nicht unterstützt wird. Wenn @code{mysqld} einen
+Tabellentyp nicht unterstützt (oder wenn der Tabellentyp durch die
+Startoption ausgeschaltet ist), wird statt dessen ein Tabellentyp erzeugt,
+der dem angeforderten am nächsten entspricht (wahrscheinlich
+@code{MyISAM}.
+
+Sie können den Tabellentyp für eine Tabelle wie folgt überprüfen:
+
+@code{SHOW TABLE STATUS LIKE 'tabelle'}. @xref{SHOW TABLE STATUS}.
+
+Sie können die Erweiterungen, die Ihre @code{mysqld}-Binärdatei
+unterstützt, wie folgt überprüfen:
+
+@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}.
+
+
+@node Out of memory, Packet too large, Non-transactional tables, Common errors
+@c German node Kein Speicher verfügbar
+@appendixsubsec @code{No free memory}-Fehler
+
+Wenn Sie eine Anfrage ausführen und etwas wie folgenden Fehler erhalten:
+
+@example
+mysql: No free memory at line 42, 'malloc.c'
+mysql: needed 8136 byte (8k), memory in use: 12481367 Bytes (12189k)
+ERROR 2008: MySQL client ran No free memory
+@end example
+
+Beachten Sie, dass sich dieser Fehler auf den MySQL-Client @code{mysql}
+bezieht. Der Grund für diesen Fehler ist einfach, dass der Client nicht
+genug freien Speicher hat, um das gesamte Ergebnis zu speichern.
+
+Um das Problem zu beheben, prüfen Sie zunächst, ob Ihre Anfrage korrekt
+ist. Sollte sie vernünftigerweise so viele Zeilen zurückgeben? Wenn das der
+Fall ist, können Sie @code{mysql --quick} benutzen, was
+@code{mysql_use_result()} benutzt, um die Ergebnismenge abzurufen.
+Hierdurch wird Last vom Client auf den Server verlagert.
+
+
+@node Packet too large, Communication errors, Out of memory, Common errors
+@c German node Paket zu Groß
+@appendixsubsec @code{Packet too large}-Fehler
+
+Wenn ein MySQL-Client oder der @code{mysqld}-Server ein Paket erhält, das
+größer als @code{max_allowed_packet} Bytes ist, gibt er einen @code{Packet
+too large}-Fehler aus und schließt die Verbindung.
+
+Wenn Sie den @code{mysql}-Client benutzen, müssen Sie einen größeren
+Puffer angeben, indem Sie den Client mit @code{mysql
+--set-variable=max_allowed_packet=8M} starten.
+
+Wenn Sie andere Clients benutzen, die die Angabe der maximalen Paketgröße
+nicht zulassen (wie @code{DBI}), müssen Sie die Paketgröße beim Start des
+Servers setzen. Sie können eine Kommandozeilenoption für @code{mysqld}
+benutzen, um @code{max_allowed_packet} auf eine höhere Größe zu setzen.
+Wenn Sie zum Beispiel beabsichtigen, die volle Länge eines @code{BLOB} in
+eine Tabelle zu speichern, müssen Sie den Server mit der
+@code{--set-variable=max_allowed_packet=16M}-Option starten.
+
+Sie können merkwürdige Probleme mit großen Paketen erhalten, wenn Sie
+große Blobs benutzen, aber @code{mysqld} keinen Zugriff auf genug Speicher
+gegeben haben, um die Anfrage zu handhaben. Wenn Sie vermuten, dass das der
+Fall ist, versuchen Sie, am Anfang des @code{safe_mysqld}-Skripts
+@code{ulimit -d 256000} hinzuzufügen, und starten Sie @code{mysqld} neu.
+
+@node Communication errors, Full table, Packet too large, Common errors
+@c German node Kommunikationsfehler
+@appendixsubsec Kommunikationsfehler / Abgebrochene Verbindung
+
+@cindex Abgebrochene Clients
+@cindex Abgebrochene Verbindung
+@cindex Verbindung, abgebrochen
+
+Ab @code{MySQL 3.23.40} erhalten Sie den @code{Aborted connection}-Fehler
+nur dann, wenn Sie @code{mysqld} mit @code{--warnings} starten.
+
+Wenn Sie Fehler wie den folgenden in Ihrer Fehler-Log-Datei entdecken:
+
+@example
+010301 14:38:23 Aborted connection 854 to db: 'Benutzer' user: 'josh'
+@end example
+
+@xref{Error log}.
+
+Bedeutet das, dass eins der folgenden Dinge passiert ist:
+
+@itemize @bullet
+@item
+Das Client-Programm rief vor dem Beenden nicht @code{mysql_close()} auf.
+@item
+Der Client schlief länger als @code{wait_timeout} oder
+@code{interactive_timeout}, ohne Anfragen auszuführen.
+@c German FIX unsplit @xref
+@xref{SHOW VARIABLES}.
+@item
+Das Client-Programm wurde abrupt während einer Übertragung beendet.
+@end itemize
+
+Wenn das oben Genannte passiert, wird die Servervariable
+@code{Aborted_clients} heraufgezählt.
+
+Die Servervariable @code{Aborted_connects} wird in folgenden Fällen
+heraufgezählt:
+
+@itemize @bullet
+@item
+Wenn ein Verbindungspaket nicht die richtigen Informationen enthält.
+@item
+Wenn der Benutzer keine Berechtigung hat, sich mit einer Datenbank zu
+verbinden.
+@item
+Wenn ein Benutzer ein falsches Passwort angegeben hat.
+@item
+Wenn es länger als @code{connect_timeout} Sekunden dauert, um ein
+Verbindungspaket zu erhalten.
+@end itemize
+
+Beachten Sie, dass obiges auch anzeigen könnte, dass jemand versucht, in
+Ihre Datenbank einzubrechen!
+
+@xref{SHOW VARIABLES}.
+
+Andere Gründe für Probleme mit abgebrochenen Clients / abgebrochenen
+Verbindungen:
+@itemize @bullet
+@item
+Benutzung des Duplex-Ethernet-Protokolls, sowohl Halb- als auch
+Voll-Duplex, unter Linux. Viele Linux-Ethernet-Treiber haben diesen Bug.
+Sie können auf diesen Bug überprüfen, indem Sie eine sehr große Datei via
+FTP zwischen diesen beiden Maschinen übertragen. Wenn ein Transfer nach dem
+Schema schnelle Übertragung - Pause - schnelle Übertragung - Pause läuft,
+haben Sie ein Linux-Duplex-Syndrom. Die einzige Lösung besteht darin, Halb-
+und Vollduplex auf Hubs und Switches auszuschalten.
+@item
+Probleme mit der Thread-Bibliothek, was Unterbrechungen bei Lesevorgängen
+verursacht.
+@item
+Schlecht konfiguriertes TCP/IP.
+@item
+Fehlerhafte Ethernets, Hubs, Switches, Kabel usw. Das kann nur durch
+Austausch von Hardware sauber diagnostiziert werden.
+@item
+@code{max_allowed_packet} ist zu klein oder Anfragen erfordern mehr
+Speicher, als Sie für @code{mysqld} zugewiesen haben.
+@c German FIX unwrapped @xref
+@xref{Packet too large}.
+@end itemize
+
+
+@node Full table, Cannot create, Communication errors, Common errors
+@c German node Tabelle voll
+@appendixsubsec @code{The table is full}-Fehler
+
+@cindex Tabelle ist voll
+
+Der Fehler tritt in älteren MySQL-Versionen auf, wenn eine
+Hauptspeicher-basierende temporäre Tabelle größer als
+@code{tmp_table_size} Bytes wird. Um dieses Problem zu vermeiden, können
+Sie die @code{-O tmp_table_size=#}-Option für @code{mysqld} benutzen, um
+die Größe der temporären Tabelle zu erhöhen, oder die SQL-Option
+@code{SQL_BIG_TABLES} verwenden, bevor Sie die problematische Anfrage
+abschicken. @xref{SET OPTION, , @code{SET OPTION}}.
+
+Sie können auch @code{mysqld} mit der @code{--big-tables}-Option starten.
+Das ist genau dasselbe, wie @code{SQL_BIG_TABLES} für alle Anfragen zu
+benutzen.
+
+In MySQL-Version 3.23 werden Hauptspeicher-basierende temporäre Tabellen
+automatisch in Festplatten-basierende @code{MyISAM}-Tabellen umgewandelt,
+wenn die Tabelle größer als @code{tmp_table_size} wird.
+
+
+@node Cannot create, Commands out of sync, Full table, Common errors
+@c German node Kann nicht erzeugen
+@appendixsubsec @code{Can't create/write to file}-Fehler
+
+@cindex can't create/write to file
+
+Wenn Sie für einige Anfragen Fehler folgenden Typs erhalten:
+
+@example
+Can't create/write to file '\\sqla3fe_0.ism'.
+@end example
+
+Bedeutet das, dass MySQL keine temporäre Datei für die Ergebnismenge im
+angegebenen temporären Verzeichnis erzeugen kann. (Der obige Fehler ist
+eine typische Fehlermeldung unter Windows; die Unix-Fehlermeldung ist
+ähnlich.) Das Problem läßt sich beheben, indem Sie @code{mysqld} mit
+@code{--tmpdir=pfad} starten oder folgendes in Ihrer Optionsdatei ergänzen:
+
+@example
+[mysqld]
+tmpdir=C:/temp
+@end example
+
+Unter der Annahme, dass das @file{c:\\temp}-Verzeichnis existiert.
+@xref{Option files}.
+
+Überprüfen Sie auch den Fehler-Code, den Sie bei @code{perror} erhalten.
+Ein Grund kann ein Fehler wegen fehlenden Festplattenspeichers sein:
+
+@example
+shell> perror 28
+Error code 28: No space left on device
+@end example
+
+
+@node Commands out of sync, Ignoring user, Cannot create, Common errors
+@c German node Befehl nicht synchronisiert
+@appendixsubsec @code{Command out of sync}-Fehler in Client
+
+@cindex Befehle nicht synchronisiert
+
+Wenn Sie den Fehler @code{command out of sync; You can't run this command
+now} in Ihrem Client-Code erhalten, rufen Sie Client-Funktionen in der
+falschen Reihenfolge auf!
+
+Das kann zum Beispiel passieren, wenn Sie @code{mysql_use_result()}
+benutzen und versuchen, eine neue Anfrage auszuführen, bevor Sie
+@code{mysql_free_result()} aufgerufen haben. Der Fehler passiert ebenfalls,
+wenn Sie versuchen, zwei Anfragen auszuführen, die Daten zurückgeben, ohne
+zwischendrin @code{mysql_use_result()} oder @code{mysql_store_result()}
+aufzurufen.
+
+
+@node Ignoring user, Cannot find table, Commands out of sync, Common errors
+@c German node Benutzer ignoriert
+@appendixsubsec @code{User ignored}-Fehler
+
+Wenn Sie folgenden Fehler erhalten:
+
+@code{Found wrong password for user: 'benutzer@@ein_host'; User ignored}
+
+Bedeutet das, dass @code{mysqld} beim Start oder nach dem Neuladen der
+Berechtigungstabellen einen Eintrag in der @code{user}-Tabelle mit einem
+ungültigen Passwort gefunden hat. Als Ergebnis wird der Eintrag vom
+Berechtigungssystem einfach ignoriert.
+
+Mögliche Gründe und Problembehebung:
+
+@itemize @bullet
+@item
+Sie lassen eine neue Version von @code{mysqld} mit einer alten
+@code{user}-Tabelle laufen. Das können Sie prüfen, indem Sie
+@code{mysqlshow mysql user} eingeben, um zu sehen, ob das Passwortfeld
+kürzer als 16 Zeichen ist. Wenn das der Fall ist, können Sie diesen Zustand
+beheben, indem Sie das @code{scripts/add_long_password}-Skript laufen
+lassen.
+
+@item
+Der Benutzer hat ein altes Passwort (8 Zeichen lang) und Sie haben
+@code{mysqld} nicht mit der @code{--old-protocol}-Option gestartet.
+
+@item
+@findex PASSWORD()
+Sie haben in der @code{user}-Tabelle ein Passwort eingegeben, ohne die
+@code{PASSWORD()}-Funktion zu benutzen. Benutzen Sie @code{mysql}, um den
+Benutzer in der @code{user}-Tabelle mit einem neuen Passwort zu
+aktualisieren. Stellen Sie sicher, dass Sie die @code{PASSWORD()}-Funktion
+benutzen:
+
+@example
+mysql> update user set password=PASSWORD('ihr_passwort')
+ where user='XXX';
+@end example
+@end itemize
+
+
+@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors
+@c German node Tabelle nicht gefunden
+@appendixsubsec @code{Table 'xxx' doesn't exist}-Fehler
+
+Wenn Sie den Fehler @code{Table 'xxx' doesn't exist} oder @code{Can't find
+file: 'xxx' (errno: 2)} erhalten, bedeutet das, dass in der aktuellen
+Datenbank keine Tabelle mit dem Namen @code{xxx} existiert.
+
+Beachten Sie, dass Datenbank- und Tabellennamen @strong{abhängig von der
+verwendeten Groß-/Kleinschreibung} sind, weil MySQL Verzeichnisse und
+Dateien benutzt, um Datenbanken und Tabellen zu speichern! (Unter Windows
+sind Datenbank- und Tabellennamen unabhängig von der Schreibweise, aber
+alle Verweise auf eine gegebene Tabelle innerhalb einer Anfrage müssen
+dieselbe Schreibweise benutzen!)
+
+Sie finden heraus, welche Tabellen sich in der aktuellen Datenbank
+befinden, indem Sie @code{SHOW TABLES} eingeben. @xref{SHOW, ,
+@code{SHOW}}.
+
+
+@node Cannot initialize character set, Not enough file handles, Cannot find table, Common errors
+@c German node Zeichensatz kann nicht initialisiert werden
+@appendixsubsec @code{Can@'t initialize charset xxx}-Fehler.
+
+@cindex Multibyte-Zeichensätze
+
+Wenn Sie folgenden Fehler erhalten:
+
+@example
+MySQL Connection Failed: Can't initialize charset xxx
+@end example
+
+Bedeutet das eins der folgenden Dinge:
+
+@itemize @bullet
+@item
+Der Zeichensatz ist ein Multi-Byte-Zeichensatz und Ihr Client unterstützt
+diesen Zeichensatz nicht.
+
+In diesem Fall müssen Sie Ihren Client neu kompilieren und die
+@code{--with-charset=xxx}- oder die @code{--with-extra-charsets=xxx}-Option
+angeben. @xref{configure options}.
+
+Alle Standard-MySQL-Binärdistributionen werden mit
+@code{--with-extra-character-sets=complex} kompiliert, was die
+Unterstützung für alle Multi-Byte-Zeichensätze aktiviert.
+@xref{Character sets}.
+
+@item
+Der Zeichensatz ist ein einfacher Zeichensatz, der nicht in @code{mysqld}
+kompiliert wurde, und die Zeichensatz-Definitionsdateien sind nicht an der
+Stelle, an der der Client sie erwartet.
+
+In diesem Fall müssen Sie:
+
+@itemize @bullet
+@item
+Den Client mit Unterstützung für den Zeichensatz neu kompilieren.
+@xref{configure options}.
+@item
+Dem Client angeben, wo die Zeichensatz-Definitionsdateien sind. Bei vielen
+Clients können Sie das mit der
+@code{--character-sets-dir=pfad-to-charset-dir}-Option machen.
+@item
+Die Zeichensatz-Definitionsdatei in den Pfad kopieren, wo der Client sie zu
+finden erwartet.
+@end itemize
+@end itemize
+
+
+@node Not enough file handles, , Cannot initialize character set, Common errors
+@c German node Nicht genug Datei-Handles
+@appendixsubsec File Not Found
+
+Wenn Sie den Fehler @code{ERROR '...' not found (errno: 23)}, @code{Can't
+open file: ... (errno: 24)} oder irgend einen anderen Fehler mit
+@code{errno 23} oder @code{errno 24} erhalten, bedeutet das, dass Sie MySQL
+nicht genug Datei-Deskriptoren zugewiesen haben. Sie können das
+@code{perror}-Dienstprogramm benutzen, um eine Beschreibung dessen zu
+erhalten, was die Fehlernummer bedeutet:
+
+@example
+shell> perror 23
+File table overflow
+shell> perror 24
+Too many open files
+shell> perror 11
+Resource temporarily unavailable
+@end example
+
+Das Problem hierbei ist, dass @code{mysqld} versucht, zu viele Dateien
+gleichzeitig offen zu halten. Sie können entweder @code{mysqld}
+veranlassen, nicht so viele Dateien auf einmal zu öffnen, oder die Anzahl
+von Datei-Deskriptoren heraufsetzen, über die @code{mysqld} verfügen kann.
+
+Um @code{mysqld} anzuweisen, weniger Dateien zugleich offen zu halten,
+können Sie den Tabellen-Cache kleiner machen, indem Sie die @code{-O
+table_cache=32}-Option für @code{safe_mysqld} benutzen (der Vorgabewert ist
+64). Wenn Sie den Wert von @code{max_connections} verringern, reduziert
+auch das die Anzahl offener Dateien (der Vorgabewert ist 90).
+
+@tindex ulimit
+Um die Anzahl von Datei-Deskriptoren, die @code{mysqld} zur Verfügung
+stehen, zu ändern, können Sie die @code{--open-files-limit=#}-Option für
+@code{safe_mysqld} oder die @code{-O open-files-limit=#}-Option für
+@code{mysqld} benutzen. @xref{SHOW VARIABLES}. Die einfachste Art, das zu
+tun, besteht darin, eine Option zu Ihrer Optionsdatei hinzuzufügen.
+@xref{Option files}. Wenn Sie eine alte @code{mysqld}-Version haben, die
+das nicht unterstützt, können Sie das @code{safe_mysqld}-Skript editieren.
+Es gibt dort eine auskommentierte Zeile @code{ulimit -n 256}. Entfernen Sie
+das @code{'#'}-Zeichen, um diese Zeile zu aktivieren, und ändern Sie die
+Anzahl 256, um die Anzahl verfügbarer Datei-Deskriptoren zu beeinflussen.
+
+Mit @code{ulimit} (und @code{open-files-limit}) kann man die Anzahl von
+Datei-Deskriptoren heraufsetzen, aber nur bis zu der Grenze, die das
+Betriebssystem vorgibt. Darüber hinaus gibt es eine 'harte' Grenze, die nur
+überschrieben werden kann, wenn Sie @code{safe_mysqld} oder @code{mysqld}
+als Root starten (denken Sie daran, dass Sie in diesem Fall auch die
+@code{--user=..}-Option benutzen müssen). Wenn Sie die
+Betriebssystem-Grenze hinsichtlich der Anzahl von Datei-Deskriptoren, die
+für jeden Prozess verfügbar sind, heraufsetzen müssen, schauen Sie in der
+Dokumentation Ihres Betriebssystems nach.
+
+Beachten Sie, dass @code{ulimit} nicht funktioniert, wenn Sie die
+@code{tcsh}-Shell laufen lassen! @code{tcsh} berichtet auch nicht korrekte
+Werte, wenn Sie die aktuellen Grenzen abfragen! In diesem Fall sollten Sie
+@code{safe_mysqld} mit @code{sh} starten!
+
+
+@node Installation Issues, Administration Issues, Common errors, Problems
+@c German node Installationsprobleme
+@appendixsec Installationsbezogene Themen
+
+
+
+@menu
+* Link errors::
+* Changing MySQL user::
+* File permissions ::
+@end menu
+
+@node Link errors, Changing MySQL user, Installation Issues, Installation Issues
+@c German node Link-Fehler
+@appendixsubsec Probleme beim Linken mit der MySQL-Client-Bibliothek
+
+@cindex linken, Fehler
+@cindex Fehler, linken
+@cindex Probleme, linken
+
+Wenn Sie Ihr Programm linken und Fehler für unreferenzierte Symbole
+erhalten, die mit @code{mysql_} beginnen, wie folgende:
+
+@example
+/tmp/ccFKsdPa.o: In function `main':
+/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
+/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
+/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect'
+/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
+/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'
+@end example
+
+Sollten Sie das durch Hinzufügen von
+@code{-Lpath-to-the-mysql-library-lmysqlclient} als @strong{LETZTES} in
+Ihrer Link-Zeile beheben können.
+
+Wenn Sie @code{undefined reference}-Fehler bei der @code{uncompress}- oder
+@code{compress}-Funktion erhalten, fügen Sie @code{-lz} als
+@strong{LETZTES} zu Ihrer Link-Zeile hinzu und versuchen Sie es noch
+einmal!
+
+Wenn Sie @code{undefined reference}-Fehler bei Funktionen erhalten, die es
+auf Ihrem System geben sollte, wie @code{connect}, sehen Sie in der
+Handbuch-Seite (ManPage) für die fragliche Funktion nach, welche
+Bibliotheken Sie zur Link-Zeile hinzufügen sollten!
+
+Wenn Sie @code{undefined reference}-Fehler bei Funktionen erhalten, die es
+auf Ihrem System nicht gibt, wie folgenden:
+
+@example
+mf_format.o(.text+0x201): undefined reference to `__lxstat'
+@end example
+
+Heißt das üblicherweise, dass Ihre Bibliothek auf einem System kompiliert
+wurde, das nicht 100% kompatibel zu Ihrem System ist. In diesem Fall
+sollten Sie die letzte MySQL-Quelldistribution herunter laden und sie
+selbst kompilieren. @xref{Installing source}.
+
+Wenn Sie versuchen, ein Programm laufen zu lassen und Fehler für
+unreferenzierte Symbole erhalten, die mit @code{mysql_} anfangen, oder den
+Fehler, dass die @code{mysqlclient}-Bibliothek nicht gefunden werden kann,
+heißt das, dass Ihr System die gemeinsam genutzte
+@code{libmysqlclient.so}-Bibliothek nicht findet.
+
+Das Problem beheben Sie, indem Sie Ihr System anweisen, dort nach gemeinsam
+genutzten Bibliotheken zu suchen, wo sich die Bibliothek befindet, mit
+einer der folgenden Methoden:
+
+@itemize @bullet
+@item
+Fügen Sie den Pfad zum Verzeichnis, in dem Sie @code{libmysqlclient.so}
+haben, der @code{LD_LIBRARY_PATH}-Umgebungsvariablen hinzu.
+@item
+Fügen Sie den Pfad zum Verzeichnis, in dem Sie @code{libmysqlclient.so}
+haben, der @code{LD_LIBRARY}-Umgebungsvariablen hinzu.
+@item
+Kopieren Sie @code{libmysqlclient.so} an eine Stelle, die von Ihrem System
+durchsucht wird, wie @file{/lib}, und aktualisieren Sie die Informationen
+über gemeinsam genutzte Bibliotheken, indem Sie @code{ldconfig} ausführen.
+@end itemize
+
+Eine weitere Möglichkeit, dieses Problem zu lösen, besteht darin, Ihr
+Programm statisch mit @code{-static} zu linken oder die dynamischen
+MySQL-Bibliotheken zu entfernen, bevor Sie Ihren Code linken. Im letzteren
+Fall sollten Sie sicherstellen, dass keine anderen Programme die
+dynamischen Bibliotheken benutzen!
+
+
+@node Changing MySQL user, File permissions , Link errors, Installation Issues
+@c German node Änderung des MySQL-Benutzers
+@appendixsubsec Wie man MySQL als normaler Benutzer laufen läßt
+
+@cindex starten, @code{mysqld}
+@cindex @code{mysqld}, starten
+
+Der MySQL-Server @code{mysqld} kann von jedem beliebigen Benutzer gestartet
+werden und unter diesem laufen. Damit @code{mysqld} als Unix-Benutzer
+@code{benutzername} läuft, müssen Sie folgendes tun:
+
+@enumerate
+@item
+Halten Sie den Server an, falls er läuft (benutzen Sie @code{mysqladmin
+shutdown}).
+
+@item
+Ändern Sie die Datenbankverzeichnisse und Dateien so, dass
+@code{benutzername} die Berechtigungen zum Lesen und Schreiben von Dateien
+darin hat (das müssen Sie eventuell als Unix-@code{root}-Benutzer machen):
+
+@example
+shell> chown -R benutzername /pfad/zu/mysql/datadir
+@end example
+
+Wenn Verzeichnisse oder Dateien im MySQL-Daten-Verzeichnis symbolische
+Links sind, müssen Sie auch diesen Verknüpfungen folgen und die
+Verzeichnisse und Dateien, auf die sie zeigen, ändern. @code{chown -R} kann
+SymLinks für Sie folgen.
+
+@item
+Starten Sie den Server als Benutzer @code{benutzername} oder, wenn Sie
+MySQL-Version 3.22 oder später benutzen, starten Sie @code{mysqld} als
+Unix-@code{root}-Benutzer und benutzen Sie die
+@code{--user=benutzername}-Option. @code{mysqld} schaltet um und läuft dann
+unter Unix-Benutzer @code{benutzername}, bevor er irgend welche
+Verbindungen annimmt.
+
+@item
+Um den Server automatisch beim Hochfahren des Systems unter dem angegebenen
+Benutzernamen zu starten, fügen Sie zur @code{[mysqld]}-Gruppe der
+@file{/etc/my.cnf}-Optionendatei oder der @file{my.cnf}-Optionendatei im
+Datenverzeichnis des Servers eine @code{user}-Zeile hinzu, die den
+Benutzernamen angibt. Beispiel:
+
+@example
+[mysqld]
+user=benutzername
+@end example
+@end enumerate
+
+Nunmehr sollte Ihr @code{mysqld}-Prozess korrekt unter dem Unix-Benutzer
+@code{benutzername} laufen. Dennoch hat sich eins nicht geändert: Die
+Inhalte der Berechtigungstabellen. Vorgabemäßig (direkt nach dem
+Laufenlassen des Skripts @code{mysql_install_db}, das die
+Berechtigungstabellen installiert), ist der MySQL-Benutzer @code{root} der
+einzige Benutzer mit Zugriffsrechten auf die @code{mysql}-Datenbank. Er ist
+auch der einzige, der Datenbanken erzeugen und löschen kann. Wenn Sie diese
+Berechtigungen nicht geändert haben, sind sie noch gültig. Das sollte Sie
+nicht davon abhalten, auf MySQL als der MySQL-@code{root}-Benutzer
+zuzugreifen, wenn Sie als ein anderer Unix-Benutzer als @code{root}
+eingeloggt sind. Geben Sie einfach für Client-Programme die @code{-u
+root}-Option an.
+
+Beachten Sie, dass der Zugriff auf MySQL als @code{root} (indem Sie
+@code{-u root} auf der Kommandozeile eingeben) @emph{nichts} damit zu tun
+hat, dass Sie MySQL als Unix-@code{root}-Benutzer laufen lassen oder als
+irgend ein anderer Unix-Benutzer. Die Zugriffsberechtigungen und
+Benutzernamen von MySQL sind komplett unterschiedlich von den
+Unix-Benutzernamen. Die einzige Verbindung mit Unix-Benutzernamen besteht
+darin, dass ein Client versuchen wird, sich mit Ihrem Unix-Login-Namen als
+MySQL-Benutzernamen zu verbinden, wenn Sie beim Aufruf eines
+Client-Programms keine @code{-u}-Option angeben.
+
+Wenn Ihre Unix-Box selbst nicht abgesichert ist, sollten Sie zumindest ein
+Passwort für den MySQL-@code{root}-Benutzer in den Berechtigungstabellen
+angeben. Ansonsten kann jeder beliebige Benutzer mit einem Konto auf der
+Maschine @code{mysql -u root datenbank} eingeben und tun, was er will.
+
+
+@node File permissions , , Changing MySQL user, Installation Issues
+@c German node Dateirechte
+@appendixsubsec Probleme mit Dateirechten
+
+@cindex Dateien, Rechte
+@cindex Fehlermeldungen, can't find file
+@cindex Dateien, Nachricht not found
+
+Wenn Sie Probleme mit Dateirechten haben, wenn @code{mysql} zum Beispiel
+folgende Fehlermeldung beim Erzeugen einer Tabelle ausgibt:
+
+@example
+Error: Can't find file: 'pfad/mit/dateiname.frm' (Errcode: 13)
+@end example
+
+@tindex UMASK-Umgebungsvariable
+@tindex Umgebungsvariable, UMASK
+Kann es sein, dass die Umgebungsvariable @code{UMASK} falsch gesetzt ist,
+wenn @code{mysqld} startet. Der vorgabemäßige umask-Wert ist @code{0660}.
+Sie können dieses Verhalten ändern, indem Sie @code{safe_mysqld} wie folgt
+starten:
+
+@example
+shell> UMASK=384 # = 600 in oktal
+shell> export UMASK
+shell> /pfad/zu/safe_mysqld &
+@end example
+
+@tindex UMASK_DIR-Umgebungsvariable
+@tindex Umgebungsvariable, UMASK_DIR
+Vorgabemäßig erzeugt MySQL Datenbank- und @code{RAID}-Verzeichnisse mit
+dem Berechtigungstyp 0700. Dieses Verhalten können Sie durch Setzen der
+@code{UMASK_DIR}-Variablen ändern. Wenn Sie diese setzen, werden neue
+Verzeichnisse mit kombiniertem @code{UMASK} und @code{UMASK_DIR} erzeugt.
+Wenn Sie zum Beispiel Gruppenzugriff auf alle neuen Verzeichnisse geben
+wollen, können Sie folgendes tun:
+
+@example
+shell> UMASK_DIR=504 # = 770 in oktal
+shell> export UMASK_DIR
+shell> /pfad/zu/safe_mysqld &
+@end example
+
+Ab MySQL-Version 3.23.25 nimmt MySQL an, dass die Werte für @code{UMASK}
+und @code{UMASK_DIR} in oktal angegeben sind, wenn sie mit einer 0
+anfangen.
+
+@xref{Environment variables}.
+
+
+@node Administration Issues, Query Issues, Installation Issues, Problems
+@c German node Administrationsprobleme
+@appendixsec Administrationsbezogene Themen
+
+
+
+@menu
+* Crashing::
+* Resetting permissions::
+* Full disk::
+* Temporary files::
+* Problems with mysql.sock::
+* Timezone problems::
+@end menu
+
+@node Crashing, Resetting permissions, Administration Issues, Administration Issues
+@c German node Abstürze
+@appendixsubsec Was zu tun ist, wenn MySQL andauernd abstürzt
+
+@cindex Absturz, wiederholter
+
+Alle MySQL-Versionen werden auf vielen Plattformen getestet, bevor sie
+herausgegeben werden. Das heißt nicht, dass es keinerlei Bugs in MySQL
+gibt, aber es heißt, dass, wenn es Bugs gibt, diese sehr wenige und schwer
+zu finden sind. Wenn Sie ein Problem haben, ist es immer hilfreich
+herauszufinden, was Ihr System zum Absturz bringt, weil Sie dann viel
+bessere Chancen haben, es schnell zu beheben.
+
+Zunächst sollten Sie versuchen herauszufinden, ob das Problem darin
+besteht, dass Ihr @code{mysqld}-Daemon stirbt, oder ob Sie ein Problem mit
+Ihrem Client haben. Sie können herausfinden, seit wann Ihr
+@code{mysqld}-Server hochgefahren ist, indem Sie @code{mysqladmin version}
+ausführen. Wenn @code{mysqld} gestorben ist, finden Sie den Grund hierfür
+womöglich in der Datei @file{mysql-daten-verzeichnis/`hostname`.err}.
+@xref{Error log}.
+
+Viele Abstürze von MySQL werden durch beschädigte Index- oder Daten-Dateien
+verursacht. MySQL aktualisiert die Daten auf Platte mit dem @code{write()}
+Systemaufruf, nach jedem SQL-Statement und bevor der Client über das
+Ergebnis unterrichtet wird. (Das gilt nicht, wenn Sie mit
+@code{delayed_key_writes} fahren, denn in diesem Fall werden nur die Daten
+geschrieben.) Das bedeutet, dass die Daten sicher sind, selbst wenn
+@code{mysqld} abstürzt, weil das Betriebssystem sicherstellt, dass die
+nicht von MySQL zurückgeschriebenen Daten (flush) auf Platte
+zurückgeschrieben werden. Sie können MySQL zwingen, alles nach jedem
+SQL-Befehl auf Platte zurückzusynchronisieren, indem Sie @code{mysqld} mit
+@code{--flush} starten.
+
+Das Gesagte bedeutet, dass Sie normalerweise keine beschädigten Tabellen
+erhalten sollten, ausser in folgenden Fällen:
+
+@itemize @bullet
+@item
+Jemand oder etwas killte @code{mysqld} oder die Maschine mitten während
+einer Aktualisierung.
+@item
+Sie haben einen Bug in @code{mysqld} gefunden, der dazu führte, dass er
+mitten während einer Aktualisierung starb.
+@item
+Jemand manipuliert die Daten- / Index-Dateien ausserhalb von
+@strong{mysqld}, ohne die Tabelle korrekt zu sperren.
+@item
+Wenn Sie viele @code{mysqld}-Server auf denselben Daten auf einem System
+laufen lassen, das Dateisystem-Sperren nicht gut unterstützt (das wird
+normalerweise vom @code{lockd}-Daemon gehandhabt) oder wenn Sie mehrere
+Server mit @code{--skip-locking} fahren.
+@item
+Wenn Sie eine beschädigte Index- / Daten-Datei haben, die sehr falsche
+Daten enthält, die @code{mysqld} durcheinander brachten.
+@item
+Sie haben einen Bug im Datenspeicher-Code gefunden. Das ist nicht sehr
+wahrscheinlich, aber zumindest möglich. In diesem Fall können Sie
+versuchen, den Dateityp auf einen anderen Datenbank-Handler umzustellen,
+indem Sie @code{ALTER TABLE} auf eine reparierte Kopie der Tabelle
+anwenden!
+@end itemize
+
+Weil es sehr schwierig ist herauszufinden, warum etwas abstürzt, versuchen
+Sie zuerst herauszufinden, ob Dinge, die bei anderen funktionieren, bei
+Ihnen abstürzen, oder ob das nicht der Fall ist. Versuchen Sie bitte
+folgendes:
+
+@itemize @bullet
+@item
+Fahren Sie den @code{mysqld}-Daemon mit @code{mysqladmin shutdown} herunter
+und führen Sie @code{myisamchk --silent --force */*.MYI} auf alle Tabellen
+aus. Starten Sie den @code{mysqld}-Daemon erneut. Das stellt sicher, dass
+Sie von einem sauberen Ausgangszustand aus fahren.
+@xref{MySQL Database Administration}.
+
+@item
+Benutzen Sie @code{mysqld --log} und versuchen Sie den Informationen im Log
+zu entnehmen, ob eine bestimmte Anfrage den Server killt oder nicht. Etwa
+95% aller Bugs beziehen sich auf eine bestimmte Anfrage! Normalerweise ist
+das eine der letzten Anfragen in der Log-Datei, direkt bevor MySQL neu
+startete. @xref{Query log}. Wenn Sie MySQL wiederholt mit einer
+der Anfragen killen, selbst wenn Sie alle Tabellen direkt vor der
+Ausführung der Anfrage überprüft haben, haben Sie den Bug eingegrenzt und
+sollten dafür einen Bug-Bericht schreiben! @xref{Bug reports}.
+
+@item
+Versuchen Sie, einen Testfall herzustellen, den wir zur Reproduzierung des
+Problems verwenden können. @xref{Reproduceable test case}.
+
+@item
+Versuchen Sie, die beigefügten mysql-test test und MySQL-Benchmarks laufen
+zu lassen. @xref{MySQL-Test-Suite}. Sie können MySQL recht gut prüfen. Sie
+können den Benchmarks auch selbst Code hinzufügen, der Ihre Applikation
+simuliert! Die Benchmarks finden sich im @file{bench}-Verzeichnis in der
+Quelldistribution oder bei einer Binärdistribution im
+@file{sql-bench}-Verzeichnis unter Ihrem MySQL-Installationsverzeichnis.
+
+@item
+Probieren Sie @code{fork_test.pl} und @code{fork2_test.pl}.
+
+@item
+Wenn Sie MySQL zum Debuggen konfigurieren, ist es wesentlich einfacher,
+Informationen über mögliche Fehler zu erhalten, wenn etwas schief geht.
+Konfigurieren Sie MySQL mit der @code{--with-debug}-Option oder mit der
+@code{--with-debug=full}-Option für @code{configure} neu und kompilieren
+Sie neu. @xref{Debugging server}.
+
+@item
+Wenn MySQL zum Debuggen konfiguriert wird, wird ein sicherer
+Speicher-Zuweiser (Memory Allocator) hinzugefügt, der einige Fehler finden
+kann. Ausserdem erfolgen etliche Ausgaben über das, was gerade geschieht.
+
+@item
+Haben Sie die neuesten Patches für Ihr Betriebssystem installiert?
+
+@item
+Benutzen Sie die @code{--skip-locking}-Option für @code{mysqld}. Auf
+manchen Systemen arbeitet der @code{lockd}-Sperrmanager nicht korrekt. Die
+@code{--skip-locking}-Option weist @code{mysqld} an, keine externen Sperren
+zu benutzen. (Das heißt, dass Sie nicht zwei @code{mysqld}-Server auf
+denselben Daten laufen lassen können und dass Sie vorsichtig sein müssen,
+wenn Sie @code{myisamchk} benutzen, aber es kann aufschlussreich sein, die
+Option testweise zu benutzen.)
+
+@item
+Haben Sie @code{mysqladmin -u root processlist} ausprobiert, wenn
+@code{mysqld} zu laufen scheint, aber nicht antwortet? Manchmal ist
+@code{mysqld} nicht komatös, obwohl es so aussieht. Das Problem kann darin
+bestehen, dass alle Verbindungen in Benutzung sind, oder es kann ein
+internes Sperrproblem vorliegen. @code{mysqladmin processlist} ist
+üblicherweise in der Lage, in solchen Fällen eine Verbindung aufzubauen und
+kann nützliche Informationen über die momentane Anzahl von Verbindungen und
+ihren Status liefern.
+
+@item
+Lassen Sie den Befehl @code{mysqladmin -i 5 status} oder @code{mysqladmin
+-i 5 -r status} in einem separaten Fenster laufen, um statistische
+Informationen auszugeben, während Sie Ihre anderen Anfragen laufen lassen.
+
+@item
+Versuchen Sie folgendes:
+@enumerate
+@item
+Starten Sie @code{mysqld} von @code{gdb} aus (oder in einem anderen
+Debugger).
+@xref{Using gdb on mysqld}.
+
+@item
+Lassen Sie Ihre Test-Skripts laufen.
+
+@item
+Geben Sie die Ablaufverfolgung (Backtrace) und die lokalen Variablen der
+untersten 3 Ebenen aus. In gdb können Sie das mit folgenden Befehle tun,
+wenn @code{mysqld} innerhalb von gdb abgestürzt ist:
+
+@example
+backtrace
+info local
+up
+info local
+up
+info local
+@end example
+
+Mit gdb können Sie auch untersuchen, welchen Thread es gibt (mit @code{info
+thread} und zu einem speziellen Thread umschalten (mit @code{thread #},
+wobei @code{#} die Thread-Kennung ist).
+@end enumerate
+
+@item
+Versuchen Sie, Ihre Applikation mit einem Perl-Skript zu simulieren, um
+MySQL zu zwingen, abzustürzen oder fehlerhaftes Verhalten an den Tag zu
+legen.
+
+@item
+Senden Sie einen normalen Bug-Bericht. @xref{Bug reports}. Geben Sie mehr
+Details an als üblich. Weil MySQL bei vielen Leuten funktioniert, kann es
+sein, dass der Absturz das Ergebnis von etwas ist, das nur auf Ihrem
+Computer existiert (beispielsweise ein Fehler, der aus Ihren besonderen
+Systembibliotheken resultiert).
+
+@item
+Wenn Sie ein Problem mit Tabellen haben, die Zeilen dynamischer Länge
+enthalten, und Sie nicht @code{BLOB/TEXT}-Spalten benutzen (sondern nur
+@code{VARCHAR}-Spalten), können Sie versuchen, alle @code{VARCHAR}- in
+@code{CHAR}-Spalten umzuwandeln, indem Sie @code{ALTER TABLE} verwenden.
+Das erzwingt, dass MySQL Zeilen fester Länge verwendet. Zeilen fester Länge
+benötigen etwas mehr Platz, sind aber fehlertoleranter gegenüber
+Beschädigungen!
+
+Der aktuelle Code mit dynamischen Zeilen ist bei MySQL AB seit mindestens
+drei Jahren ohne jedes Problem in Benutzung, aber naturgemäß sind Zeilen
+dynamischer Länge fehleranfälliger. Daher kann es eine gute Idee sein, das
+oben Gesagte auszuprobieren.
+@end itemize
+
+
+@node Resetting permissions, Full disk, Crashing, Administration Issues
+@c German node Berechtigungen zurücksetzen
+@appendixsubsec Wie ein vergessenes Passwort zurückgesetzt wird
+
+@cindex Passwörter, vergessen
+@cindex Passwörter, zurücksetzen
+@cindex Root-Benutzer, Passwort zurücksetzen
+
+Wenn Sie das @code{root}-Benutzerpasswort für MySQL vergessen haben, können
+Sie es mit folgender Prozedur wiederherstellen:
+
+@enumerate
+@item
+Fahren Sie den @code{mysqld}-Server durch Senden von @code{kill} (nicht
+@code{kill -9}) an den @code{mysqld}-Server herunter. Die Prozess-Kennung
+(PID) wird in einer @code{.pid}-Datei gespeichert, die sich normalerweise
+im MySQL-Datenbank-Verzeichnis befindet:
+
+@example
+kill `cat /mysql-daten-verzeichnis/hostname.pid`
+@end example
+
+Hierfür müssen Sie entweder der Unix-@code{root}-Benutzer sein oder
+derselbe Benutzer, unter dem der Server läuft.
+
+@item
+Starten Sie @code{mysqld} mit der @code{--skip-grant-tables}-Option neu.
+@item
+Verbinden Sie sich mit dem @code{mysqld}-Server mit @code{mysql -h hostname
+mysql} und ändern Sie das Passwort mit einem @code{GRANT}-Befehl.
+@xref{GRANT,,@code{GRANT}}. Sie können dasselbe auch mit @code{mysqladmin
+-h hostname -u benutzer password 'neues_passwort'} machen.
+
+@item
+Laden Sie die Berechtigungstabellen neu mit @code{mysqladmin -h hostname
+flush-privileges} oder mit dem SQL-Befehl @code{FLUSH PRIVILEGES}.
+@end enumerate
+
+Beachten Sie, dass nach dem Start von @code{mysqld} mit
+@code{--skip-grant-tables} jede Benutzung von @code{GRANT}-Befehlen zu
+einem @code{Unknown command}-Fehler führt, bis Sie @code{FLUSH PRIVILEGES}
+ausgeführt haben.
+
+
+@node Full disk, Temporary files, Resetting permissions, Administration Issues
+@c German node Platte voll
+@appendixsubsec Wie MySQL mit vollen Festplatten umgeht
+
+@cindex volle Festplatte
+@cindex Festplatte voll
+
+@noindent
+Wenn etwas hinsichtlich der Festplatte passiert, tut MySQL folgendes:
+
+@itemize @bullet
+@item
+Er prüft einmal pro Minute, um festzustellen, ob es genug Platz gibt, um
+die aktuelle Zeile zu schreiben oder nicht. Wenn genug Platz vorhanden ist,
+wird fortgefahren, als sei nichts geschehen.
+@item
+Alle 6 Minuten schreibt er einen Eintrag in die Log-Datei mit einer Warnung
+wegen voller Festplatte.
+@end itemize
+
+@noindent
+Um das Problem abzumildern, können Sie folgende Aktionen unternehmen:
+
+@itemize @bullet
+@item
+Um einfach weiterzumachen, müssen Sie lediglich genug Festplattenplatz
+freigeben, damit alle Datensätze eingefügt werden können.
+@item
+Um den Thread abzubrechen, müssen Sie @code{mysqladmin kill} an den Thread
+senden. Der Thread wird beim nächsten Mal, wenn er die Festplatte prüft (in
+1 Minute) abgebrochen.
+@item
+Beachten Sie, dass eventuell ein anderer Thread auf die Tabelle wartet, die
+den Zustand ``Platte voll'' verursachte. Wenn Sie mehrere ``gesperrte''
+Threads haben, kann es sein, dass Sie einen Thread killen, der wegen
+``Platte voll'' wartet, dass dafür aber ein anderer Thread weitermacht.
+@end itemize
+
+Ausnahmen zum obigen Verhalten treten bei der Benutzung von @code{REPAIR}
+oder @code{OPTIMIZE} auf, oder wenn die Indexe nach einem @code{LOAD DATA
+INFILE}- oder einem @code{ALTER TABLE}-Statement im Stapel erzeugt werden.
+
+Alle obigen Befehle benutzen eventuell große temporäre Dateien, die - sich
+selbst überlassen - für den Rest des Systems große Probleme verursachen
+können. Wenn MySQL ein ``Platte voll'' erhält, während irgend eine der
+obigen Operationen ausgeführt wird, entfernt er die großen temporären
+Dateien und markiert die Tabelle als beschädigt (ausser bei @code{ALTER
+TABLE}, wobei die alte Tabelle unverändert gelassen wird).
+
+
+@node Temporary files, Problems with mysql.sock, Full disk, Administration Issues
+@c German node Temporäre Dateien
+@appendixsubsec Wohin MySQL temporäre Dateien speichert
+
+MySQL benutzt den Wert der @code{TMPDIR}-Umgebungsvariablen als Pfadnamen
+des Verzeichnisses, in dem temporäre Dateien gespeichert werden. Wenn Sie
+@code{TMPDIR} nicht gesetzt haben, benutzt MySQL die System-Vorgabe, die
+normalerweise @file{/tmp} oder @file{/usr/tmp} ist. Wenn das Dateisystem,
+das Ihr Verzeichnis für temporäre Dateien enthält, zu klein ist, sollten
+Sie @code{safe_mysqld} editieren, um @code{TMPDIR} so zu setzen, dass sie
+auf ein Verzeichnis in einem Dateisystem zeigt, wo Sie genug Platz haben!
+Sie können das temporäre Verzeichnis auch mit der @code{--tmpdir}-Option
+für @code{mysqld} setzen.
+
+MySQL erzeugt alle temporären Dateien als versteckte Dateien. Das stellt
+sicher, dass die temporären Dateien entfernt werden, wenn @code{mysqld}
+beendet wird. Der Nachteil versteckter Dateien ist, dass Sie eine große
+temporäre Datei nicht sehen, die das Dateisystem auffüllt, in dem sich das
+Verzeichnis für temporäre Dateien befindet.
+
+Zum Sortieren (@code{ORDER BY} oder @code{GROUP BY}) benutzt MySQL
+normalerweise ein oder zwei temporäre Dateien. Der maximal benötigte
+Speicherplatz ist:
+
+@example
+(laenge_dessen_was_sortiert_wird + groesse_von(datenbank_zeiger)) *
+anzahl_uebereinstimmender_zeilen * 2
+@end example
+
+@code{groesse_von(datenbank_zeiger)} ist üblicherweise 4, kann in Zukunft
+aber für wirklich große Tabellen anwachsen.
+
+Bei einigen @code{SELECT}-Anfragen erzeugt MySQL zusätzliche temporäre
+SQL-Tabellen. Diese sind nicht versteckt und haben Namen der Form
+@file{SQL_*}.
+
+@code{ALTER TABLE} erzeugt eine temporäre Tabelle im selben Verzeichnis, in
+dem sich die Original-Tabelle befindet.
+
+
+@node Problems with mysql.sock, Timezone problems, Temporary files, Administration Issues
+@c German node Probleme mit mysql.sock
+@appendixsubsec Wie Sie die MySQL-Socket-Datei @file{/tmp/mysql.sock} schützen oder ändern
+
+@cindex @code{mysql.sock}, schützen
+@cindex löschen, @code{mysql.sock}
+
+Wenn Sie Probleme damit haben, dass jeder beliebige den
+MySQL-Kommunikations-Socket @file{/tmp/mysql.sock} löschen kann, können Sie
+unter den meisten Versionen von Unix Ihr @file{/tmp}-Dateisystem schützen,
+indem Sie darauf das @code{sticky} Bit setzen. Loggen Sie sich als
+@code{root} ein und tun Sie folgendes:
+
+@example
+shell> chmod +t /tmp
+@end example
+
+Das schützt Ihr @file{/tmp}-Dateisystem, so dass Dateien nur von ihren
+Besitzern oder dem Superuser (@code{root}) gelöscht werden können.
+
+Sie können überprüfen, ob das @code{sticky} Bit gesetzt ist, indem Sie
+@code{ls -ld /tmp} ausführen. Wenn das letzte Berechtigungsbit @code{t}
+ist, ist das Bit gesetzt.
+
+@cindex Speicherort des Sockets ändern
+
+Sie können den Speicherort ändern, den MySQL benutzt, um die Socket-Datei
+Socket-Datei abzulegen, indem Sie eine der folgenden Prozeduren ausführen:
+
+@itemize @bullet
+@item
+Geben Sie den Pfad in einer globalen oder lokalen Optionsdatei an.
+Beispielsweise können Sie in @code{/etc/my.cnf} eintragen:
+
+@example
+[client]
+socket=pfad-fuer-socket-datei
+
+[mysqld]
+socket=pfad-fuer-socket-datei
+@end example
+@xref{Option files}.
+@item
+Geben Sie den Pfad auf der Kommandozeile für @code{safe_mysqld} und die
+meisten Clients mit der @code{--socket=pfad-fuer-socket-datei}-Option an.
+@item
+Geben Sie den Pfad zum Socket in der
+@code{MYSQL_UNIX_PORT}-Umgebungsvariablen an.
+variable.
+@item
+Definieren Sie den Pfad mit der @code{configure}-Option
+@code{--with-unix-socket-path=pfad-fuer-socket-datei}.
+@xref{configure options}.
+@end itemize
+
+Mit folgendem Befehl können Sie testen, ob der Socket funktioniert:
+
+@example
+shell> mysqladmin --socket=/pfad/zu/socket version
+@end example
+
+@node Timezone problems, , Problems with mysql.sock, Administration Issues
+@c German node Zeitzonen-Probleme
+@appendixsubsec Zeitzonen-Probleme
+
+@cindex Zeitzonen-Probleme
+@cindex Probleme, Zeitzone
+
+@tindex TZ-Umgebungsvariable
+@tindex Umgebungsvariable, TZ
+
+Wenn es Probleme damit gibt, dass @code{SELECT NOW()} Werte in GMT
+(Greenwich Mean Time) zurückgibt und nicht in Ihrer lokalen Zeit, müssen
+Sie die @code{TZ}-Umgebungsvariable auf Ihre aktuelle Zeitzone setzen. Das
+sollte für die Umgebung gemacht werden, in der der Server läuft, zum
+Beispiel in @code{safe_mysqld} oder @code{mysql.server}.
+@xref{Environment variables}.
+
+
+@node Query Issues, Table Definition Issues, Administration Issues, Problems
+@c German node Anfragenprobleme
+@appendixsec Anfragenbezogene Themen
+
+
+
+@menu
+* Case sensitivity::
+* Using DATE::
+* Problems with NULL::
+* Problems with alias::
+* Deleting from related tables::
+* No matching rows::
+@end menu
+
+@node Case sensitivity, Using DATE, Query Issues, Query Issues
+@c German node Groß-/Kleinschreibung
+@appendixsubsec Groß-/Kleinschreibung beim Suchen
+
+@cindex Groß-/Kleinschreibung, beim Suchen
+@cindex Suchen und Groß-/Kleinschreibung
+@cindex chinesisch
+@cindex Big5, chinesische Zeichensatz-Kodierung
+
+Vorgabemäßig sind MySQL-Suchen unabhängig von der verwendeten
+Groß-/Kleinschreibung (obwohl es einige Zeichensätze gibt, die nie
+unabhängig von der verwendeten Groß-/Kleinschreibung sind, wie
+@code{tschechisch}). Wenn Sie daher mit @code{spalten_name LIKE 'a%'}
+suchen, erhalten Sie alle Spaltenwerte, die mit @code{A} oder @code{a}
+anfangen. Wenn Sie die Suche abhängig von der verwendeten
+Groß-/Kleinschreibung machen wollen, verwenden Sie etwas wie
+@code{INSTR(spalten_name, "A")=1}, um ein Präfix zu überprüfen, oder
+benutzen Sie @code{STRCMP(spalten_name, "A") = 0}, wenn der Spaltenwert
+exakt @code{"A"} sein muss.
+
+Einfache Vergleichsoperationen (@code{>=, >, = , < , <=}, Sortieren und
+Gruppieren) basieren auf dem ``Sortierwert'' jedes Zeichens. Buchstaben mit
+demselben Sortierwert (wie E, e und é) werden als dasselbe Zeichen
+behandelt!
+
+In älteren MySQL-Versionen wurden @code{LIKE}-Vergleiche mit dem
+Großschreibungswert jedes Zeichens durchgeführt (E == e, aber E <> é). In
+neueren MySQL-Versionen funktioniert @code{LIKE} genau wie die anderen
+Vergleichsoperatoren.
+
+Wenn Sie wollen, dass eine Spalte immer abhängig von der verwendeten
+Groß-/Kleinschreibung behandelt wird, deklarieren Sie sie als
+@code{BINARY}. @xref{CREATE TABLE, , @code{CREATE TABLE}}.
+
+Wenn Sie chinesische Daten in der so genannten Big5-Kodierung verwenden,
+sollten Sie alle Zeichenspalten @code{BINARY} machen. Das funktioniert,
+weil die Sortierreihenfolge von Big5-Zeichen auf der Reihenfolge von
+ASCII-Codes basiert.
+
+
+@node Using DATE, Problems with NULL, Case sensitivity, Query Issues
+@c German node Benutzung von DATE
+@appendixsubsec Probleme bei der Benutzung von @code{DATE}-Spalten
+
+@findex DATE
+
+@cindex DATE-Spalten, Probleme
+@cindex Probleme, @code{DATE}-Spalten
+
+Das Format eines @code{DATE}-Werts ist @code{'YYYY-MM-DD'}. Gemäß ANSI-SQL
+ist kein anderes Format zulässig. Sie sollten dieses Format in
+@code{UPDATE}-Ausdrücken und in der WHERE-Klausel von
+@code{SELECT}-Statements benutzen. Beispiel:
+
+@example
+mysql> SELECT * FROM tabelle WHERE date >= '1997-05-05';
+@end example
+
+Aus Gründen der Annehmlichkeit konvertiert MySQL automatisch ein Datum in
+eine Zahl, wenn das Datum in einem numerischen Zusammenhang benutzt wird
+(und umgekehrt). MySQL unterstützt ausserdem ein ``entspanntes''
+Zeichenkettenformat beim Aktualisieren und in einer @code{WHERE}-Klausel,
+die ein Datum mit einer @code{TIMESTAMP}-, @code{DATE}- oder einer
+@code{DATETIME}-Spalte vergleicht. (Entspannt heißt hierbei, dass jedes
+beliebige Satzzeichen als Trennzeichen zwischen Bestandteilen benutzt
+werden darf. Beispielsweise sind @code{'1998-08-15'} und
+@code{'1998#08#15'} äquivalent.) MySQL kann auch eine Zeichenkette
+umwandeln, die keine Trennzeichen enthält (wie @code{'19980815'}),
+vorausgesetzt, dass diese als Datum einen Sinn ergibt.
+
+Das spezielle Datum @code{'0000-00-00'} kann als @code{'0000-00-00'}
+gespeichert und abgerufen werden. Wenn man ein @code{'0000-00-00'}-Datum
+über @strong{MyODBC} benutzt, wird es automatisch in @code{NULL}
+umgewandelt (@strong{MyODBC}-Version 2.50.12 und höher), weil ODBC diese
+Art von Datum nicht handhaben kann.
+
+Weil MySQL die oben genannten Umwandlungen durchführt, funktionieren
+folgende Statements:
+
+@example
+mysql> INSERT INTO tabelle (idate) VALUES (19970505);
+mysql> INSERT INTO tabelle (idate) VALUES ('19970505');
+mysql> INSERT INTO tabelle (idate) VALUES ('97-05-05');
+mysql> INSERT INTO tabelle (idate) VALUES ('1997.05.05');
+mysql> INSERT INTO tabelle (idate) VALUES ('1997 05 05');
+mysql> INSERT INTO tabelle (idate) VALUES ('0000-00-00');
+
+mysql> SELECT idate FROM tabelle WHERE idate >= '1997-05-05';
+mysql> SELECT idate FROM tabelle WHERE idate >= 19970505;
+mysql> SELECT mod(idate,100) FROM tabelle WHERE idate >= 19970505;
+mysql> SELECT idate FROM tabelle WHERE idate >= '19970505';
+@end example
+
+@noindent
+Folgendes jedoch funktioniert nicht:
+
+@example
+mysql> SELECT idate FROM tabelle WHERE STRCMP(idate,'19970505')=0;
+@end example
+
+@code{STRCMP()} ist eine Zeichenkettenfunktion, daher wird @code{idate} in
+eine Zeichenkette umgewandelt und ein Zeichenkettenvergleich durchgeführt.
+MySQL wandelt @code{'19970505'} nicht in ein Datum um und führt einen
+Datumsvergleich durch.
+
+Beachten Sie, dass MySQL nicht prüft, ob ein Datum korrekt ist oder nicht.
+Wenn Sie ein falsches Datum wie @code{'1998-2-31'} speichern, wird das
+falsche Datum gespeichert. Wenn das Datum in keinen vernünftigen Wert
+umgewandelt werden kann, wird @code{0} im @code{DATE}-Feld gespeichert. Das
+ist hauptsächlich eine Sache der Geschwindigkeit, und wir sind der Meinung,
+dass es Sache der Applikation und nicht des Servers ist, Datumsangaben zu
+überprüfen.
+
+
+@node Problems with NULL, Problems with alias, Using DATE, Query Issues
+@c German node Probleme mit NULL
+@appendixsubsec Probleme mit @code{NULL}-Werten
+
+@cindex @code{NULL}-Werte im Vergleich mit leeren Werten
+
+@tindex NULL
+
+Das Konzept des @code{NULL}-Wert ist eine häufige Quelle der Verwirrung für
+SQL-Anfänger. Diese denken häufig, @code{NULL} sei dasselbe wie eine leere
+Zeichenkette @code{''}. Das ist nicht der Fall! So sind zum Beispiel
+folgende Statements grundverschieden:
+
+@example
+mysql> INSERT INTO meine_tabelle (Telefon) VALUES (NULL);
+mysql> INSERT INTO meine_tabelle (Telefon) VALUES ("");
+@end example
+
+Beide Statements fügen einen Wert in die @code{Telefon}-Spalte ein, aber
+das erste fügt einen @code{NULL}-Wert und das zweite eine leere
+Zeichenkette ein. Die Bedeutung des ersten ist etwa ``Telefonnummer
+unbekannt'' und des zweiten ``Keine Telefonnummer''.
+
+In SQL ist der @code{NULL}-Wert im Vergleich mit jedem anderen Wert immer
+UNWAHR (false), selbst im Vergleich mit @code{NULL}. Ein Ausdruck, der
+@code{NULL} enthält, erzeugt immer einen @code{NULL}-Wert, ausser wenn es
+in der Dokumentation der Operatoren und Funktionen, die im Ausdruck
+beteiligt sind, anders angegeben ist. Alle Spalten im folgenden Beispiel
+geben @code{NULL} zurück:
+
+@example
+mysql> SELECT NULL,1+NULL,CONCAT('unsichtbar',NULL);
+@end example
+
+Wenn Sie nach Spaltenwerten suchen, die @code{NULL} sind, können Sie nicht
+@code{=NULL} benutzen. Folgendes Statement gibt keine Zeilen zurück, weil
+@code{ausdruck = NULL} für jeden beliebigen Ausdruck UNWAHR (false) ist:
+
+@example
+mysql> SELECT * FROM meine_tabelle WHERE Telefon = NULL;
+@end example
+
+Um nach @code{NULL}-Werten zu suchen, müssen Sie @code{IS NULL} benutzen.
+Folgende Beispiele zeigen, wie Sie die @code{NULL}-Telefonnummer und die
+leere Telefonnummer finden:
+
+@example
+mysql> SELECT * FROM meine_tabelle WHERE Telefon IS NULL;
+mysql> SELECT * FROM meine_tabelle WHERE Telefon = "";
+@end example
+
+In MySQL können Sie - wie bei vielen anderen SQL-Servern - keine Spalten
+indexieren, die @code{NULL}-Werte enthalten dürfen. Sie müssen solche
+Spalten aus @code{NOT NULL} deklarieren. Sie dürfen in eine indexierte
+Spalte keine @code{NULL}-Werte einfügen.
+
+@findex LOAD DATA INFILE
+Wenn Sie Daten mit @code{LOAD DATA INFILE} einlesen, werden leere Spalten
+mit @code{''} aktualisiert. Wenn Sie einen @code{NULL}-Wert in einer Spalte
+haben wollen, müssen Sie in der Textdatei @code{\N} benutzen. Unter manchen
+Umständen kann auch das Literalwort @code{'NULL'} benutzt werden.
+@xref{LOAD DATA, , @code{LOAD DATA}}.
+
+Wenn Sie @code{ORDER BY} benutzen, werden @code{NULL}-Werte zuerst
+angezeigt. Wenn Sie mit @code{DESC} in absteigender Reihenfolge sortieren,
+werden @code{NULL}-Werte zuletzt angezeigt. Wenn Sie @code{GROUP BY}
+benutzen, werden alle @code{NULL}-Werte als gleich betrachtet.
+
+Um die Handhabung von @code{NULL} zu erleichtern, können Sie die @code{IS
+NULL}- und @code{IS NOT NULL}-Operatoren und die @code{IFNULL()}-Funktion
+benutzen.
+
+@cindex @code{TIMESTAMP} und @code{NULL}-Werte
+@cindex @code{AUTO_INCREMENT} und @code{NULL}-Werte
+@cindex @code{NULL}-Werte und @code{TIMESTAMP}-Spalten
+@cindex @code{NULL}-Werte und @code{AUTO_INCREMENT}-Spalten
+Bei manchen Spaltentypen werden @code{NULL}-Werte besonders behandelt. Wenn
+Sie @code{NULL} in die erste @code{TIMESTAMP}-Spalte einer Tabelle
+einfügen, werden das aktuelle Datum und die aktuelle Zeit eingefügt. Wenn
+Sie @code{NULL} in eine @code{AUTO_INCREMENT}-Spalte einfügen, wird die
+nächste Zahl in der Zahlenfolge eingefügt.
+
+
+@node Problems with alias, Deleting from related tables, Problems with NULL, Query Issues
+@c German node Probleme mit alias
+@appendixsubsec Probleme mit @code{alias}
+
+@tindex alias
+
+Sie können ein Alias verwenden, um auf eine Spalte im @code{GROUP BY}-,
+@code{ORDER BY}- oder @code{HAVING}-Teil zu verweisen. Aliase können auch
+verwendet werden, um Spalten bessere Namen zu geben:
+
+@example
+SELECT SQRT(a*b) as wurzel FROM tabelle GROUP BY wurzel HAVING wurzel > 0;
+SELECT id,COUNT(*) AS zaehl FROM tabelle GROUP BY id HAVING zaehl > 0;
+SELECT id AS "kunden-kennung" FROM tabelle;
+@end example
+
+Beachten Sie, dass ANSI-SQL verbietet, in einer @code{WHERE}-Klausel auf
+ein Alias zu verweisen. Das liegt daran, dass der Spaltenwert
+möglicherweise noch nicht feststeht, wenn der @code{WHERE}-Code ausgeführt
+wird. Folgende Anfrage zum Beispiel ist @strong{unzulässig}:
+
+@example
+SELECT id,COUNT(*) AS zaehl FROM tabelle WHERE zaehl > 0 GROUP BY id;
+@end example
+
+Das @code{WHERE}-Statement wird ausgeführt, um festzulegen, welche Zeilen
+im @code{GROUP BY}-Teil enthalten sein sollen, während @code{HAVING}
+benutzt wird, um zu entscheiden, welche Zeilen der Ergebnismenge benutzt
+werden sollten.
+
+
+@node Deleting from related tables, No matching rows, Problems with alias, Query Issues
+@c German node Löschen aus verwandten Tabellen
+@appendixsubsec Zeilen aus verwandten Tabellen löschen
+
+@cindex löschen, Zeilen
+@cindex Zeilen, löschen
+@cindex Tabellen, Zeilen löschen
+
+Weil MySQL keine Sub-Selects oder die Benutzung von mehr als einer Tabelle
+im @code{DELETE}-Statement unterstützt, müssen Sie folgenden Ansatz wählen,
+um Zeilen aus zwei verwandten Tabellen zu löschen:
+
+@enumerate
+@item
+Wählen (@code{SELECT}) Sie die Zeilen auf der Grundlage einer
+@code{WHERE}-Bedingung in der Haupt-Tabelle aus.
+@item
+Löschen (@code{DELETE}) Sie die Zeilen in der Haupt-Tabelle auf der
+Grundlage derselben Bedingung.
+@item
+Löschen Sie die Zeilen aus der verwandten Tabelle, bei denen die verwandte
+Spalte in den ausgewählten Zeilen vorkommt (@code{DELETE FROM
+verwandte_tabelle WHERE verwandte_spalte IN (ausgewaehlte_zeilen)}.
+@end enumerate
+
+Wenn die Gesamtzahl von Zeichen in der Anfrage mit @code{verwandte_spalte}
+mehr als 1.048.576 beträgt (der Vorgabewert von @code{max_allowed_packet},
+sollten Sie sie in kleinere Teile aufspalten und mehrfache
+@code{DELETE}-Statements ausführen. Wahrscheinlich geht das Löschen
+(@code{DELETE}) am Schnellsten, wenn Sie nur 100 bis 1000
+@code{verwandte_spalte}-Kennungen pro Anfrage löschen, wenn
+@code{verwandte_spalte} ein Index ist. Wenn @code{verwandte_spalte} kein
+Index ist, ist die Geschwindigkeit unabhängig von der Anzahl von Argumenten
+in der @code{IN}-Klausel.
+
+
+@node No matching rows, , Deleting from related tables, Query Issues
+@c German node Keine übereinstimmenden Zeilen
+@appendixsubsec Probleme bei keinen übereinstimmenden Zeilen lösen
+
+@cindex keine übereinstimmenden Zeilen
+@cindex Zeilen, Übereinstimmungsprobleme
+
+Wenn Sie eine komplizierte Anfrage haben, die viele Tabellen hat und keine
+Zeilen zurückgibt, sollten Sie folgende Prozedur benutzen, um
+herauszufinden, was bei Ihrer Anfrage falsch ist:
+
+@enumerate
+@item
+Testen Sie die Anfrage mit @code{EXPLAIN} und prüfen Sie, ob Sie etwas
+finden können, das offensichtlich falsch ist. @xref{EXPLAIN, ,
+@code{EXPLAIN}}.
+
+@item
+Wählen Sie in der @code{WHERE}-Klausel nur die Felder aus, die benutzt
+werden.
+
+@item
+Entfernen Sie nacheinander Tabelle für Tabelle aus der Anfrage, bis sie
+Zeilen zurückgibt. Wenn die Tabellen Groß sind, ist es eine gute Idee,
+@code{LIMIT 10} bei der Anfrage zu benutzen.
+
+@item
+Machen Sie ein @code{SELECT} für die Spalte, die mit einer Zeile hätte
+übereinstimmen sollen, gegen die Tabelle, die als letzte aus der Anfrage
+entfernt wurde.
+
+@item
+Wenn Sie @code{FLOAT}- oder @code{DOUBLE}-Spalten mit Zahlen vergleichen,
+die Dezimalstellen haben, können Sie nicht @code{=} benutzen! Das Problem
+tritt in den meisten Computersprachen auf, weil Fließkommawerte keine
+exakten Werte sind:
+
+@example
+mysql> SELECT * FROM tabelle WHERE float_spalte=3.5;
+mysql> SELECT * FROM tabelle WHERE float_spalte between 3.45 und 3.55;
+@end example
+
+In den meisten Fällen kann dies durch Umwandlung von @code{FLOAT} in
+@code{DOUBLE} behoben werden!
+
+@item
+Wenn Sie immer noch nicht herausfinden können, was schief geht, erzeugen
+Sie einen minimalen Test, der mit @code{mysql test < anfrage.sql} laufen
+gelassen werden kann, um Ihre Probleme aufzuzeigen. Sie können eine
+Testdatei mit @code{mysqldump --quick datenbanktabellen > anfrage.sql}
+erzeugen. Öffnen Sie die Datei in einem Editor, entfernen Sie ein paar
+Einfügezeilen (wenn es davon zu viele gibt) und fügen Sie Ihr
+SELECT--Statement am Ende der Datei an.
+
+Testen Sie, ob es hiermit immer noch das Problem gibt:
+
+@example
+shell> mysqladmin create test2
+shell> mysql test2 < anfrage.sql
+@end example
+
+Schicken Sie die Testdatei mittels @code{mysqlbug} an
+@email{mysql@@lists.mysql.com}.
+@end enumerate
+
+
+@node Table Definition Issues, , Query Issues, Problems
+@c German node Tabellendefinitionsprobleme
+@appendixsec Tabellendefinitionsbezogene Themen
+
+
+
+@menu
+* ALTER TABLE problems::
+* Change column order::
+* Temporary table problems::
+@end menu
+
+@node ALTER TABLE problems, Change column order, Table Definition Issues, Table Definition Issues
+@c German node Probleme mit ALTER TABLE
+@appendixsubsec Probleme mit @code{ALTER TABLE}.
+
+@tindex ALTER TABLE
+
+@code{ALTER TABLE} ändert eine Tabelle zum aktuellen Zeichensatz. Wenn Sie
+während @code{ALTER TABLE} einen Fehler wegen doppelter Schlüsseleinträge
+bekommen, liegt das entweder daran, dass die neuen Zeichensätze auf bei
+Schlüsseln auf dieselben Werte gemappt sind, oder dass die Tabelle
+beschädigt ist, wobei Sie @code{REPAIR TABLE} auf die Tabelle laufen lassen
+sollten.
+
+Wenn @code{ALTER TABLE} mit einem Fehler wie folgt stirbt:
+
+@example
+Error on rename of './datenbank/name.frm' to './datenbank/B-a.frm' (Errcode: 17)
+@end example
+
+Kann das Problem darin bestehen, dass MySQL bei einem vorhergehenden
+@code{ALTER TABLE} abgestürzt ist und es eine alte Tabelle namens
+@file{A-etwas} oder @file{B-etwas} gibt, die herum liegt. Gehen Sie in
+diesem Fall ins MySQL-Daten-Verzeichnis und löschen Sie alle Dateien, die
+Namen wie @code{A-} oder @code{B-} haben. (Statt löschen können Sie sie
+auch an eine andere Stelle verschieben.)
+
+@code{ALTER TABLE} funktioniert auf folgenden Weise:
+
+@itemize @bullet
+@item Erzeugt eine neue Tabellen namens @file{A-xxx} mit den angeforderten
+Änderungen.
+@item Alle Zeilen der alten Tabelle werden nach @file{A-xxx} kopiert.
+@item Die alte Tabelle wird in @file{B-xxx} umbenannt.
+@item @file{A-xxx} wird in Ihren alten Tabellennamen umbenannt.
+@item @file{B-xxx} wird gelöscht.
+@end itemize
+
+Wenn etwas bei dieser Umbennungsoperation fehlschlägt, versucht MySQL, die
+Änderungen rückgängig zu machen. Wenn etwas Schwerwiegendes schief geht
+(was natürlich passieren kann), läßt MySQL eventuell die alte Tabelle als
+@file{B-xxx}, aber ein einfaches Umbenennen auf Systemebene sollte Ihre
+Daten zurückbringen.
+
+
+@node Change column order, Temporary table problems, ALTER TABLE problems, Table Definition Issues
+@c German node Änderung der Spalten-Reihenfolge
+@appendixsubsec Wie man die Reihenfolge der Spalten in einer Tabelle ändert
+
+@cindex neu sortieren, Spalten
+@cindex Spalten, ändern
+@cindex ändern, Spalten-Reihenfolge
+@cindex Tabellen, Spalten-Reihenfolge ändern
+
+Im großen und Ganzen geht es bei SQL darum, die Applikation vom
+Daten-Speicherformat zu abstrahieren. Sie sollten immer die Reihenfolge
+angeben, in der Sie Ihre Daten abrufen wollen. Beispiel:
+
+@example
+SELECT spalten_name1, spalten_name2, spalten_name3 FROM tabelle;
+@end example
+
+Das gibt die Spalten in der Reihenfolge @code{spalten_name1},
+@code{spalten_name2}, @code{spalten_name3} zurück, wohingegen:
+
+@example
+SELECT spalten_name1, spalten_name3, spalten_name2 FROM tabelle;
+@end example
+
+die Spalten in der Reihenfolge @code{spalten_name1}, @code{spalten_name3},
+@code{spalten_name2} zurückgibt.
+
+Sie sollten in einer Applikation @strong{NIE} @code{SELECT *} benutzen und
+die Spalten basierend auf ihrer Position abrufen, weil die Reihenfolge, in
+der Spalten zurückgegeben werden, im Zeitablauf @strong{NICHT} garantiert
+werden kann. Eine einfache Änderung in Ihrer Datenbank kann dazu führen,
+dass Ihre Applikation dramatisch scheitert.
+
+Wenn Sie dennoch die Spalten-Reihenfolge ändern wollen, können Sie das wie
+folgt tun:
+
+@enumerate
+@item
+Erzeugen Sie eine neue Tabelle mit den Spalten in der richtigen
+Reihenfolge.
+@item
+Führen Sie @code{INSERT INTO neue_tabelle SELECT
+felder-in-der-reihenfolge-von-neue_tabelle FROM alte_tabelle} aus.
+@item
+Löschen Sie @code{alte_tabelle} oder benennen Sie sie um.
+@item
+Führen Sie @code{ALTER TABLE neue_tabelle RENAME alte_tabelle} aus.
+@end enumerate
+
+
+@node Temporary table problems, , Change column order, Table Definition Issues
+@c German node Probleme mit temporären Tabellen
+@appendixsubsec TEMPORARY TABLE-Probleme
+
+@cindex temporäre Tabellen, Probleme
+
+Im Folgenden eine Auflistung der Beschränkungen bei @code{TEMPORARY TABLES}.
+
+@itemize @bullet
+@item
+Eine temporäre Tabelle kann nur vom Typ @code{HEAP}, @code{ISAM} oder
+@code{MyISAM} sein.
+@item
+Sie können temporäre Tabellen nicht mehr als einmal in derselben Anfrage
+benutzen. Folgendes zum Beispiel funktioniert nicht:
+
+@example
+select * from temporary_table, temporary_table as t2;
+@end example
+
+Das soll in Version 4.0 behoben werden.
+@item
+Sie können kein @code{RENAME} auf eine @code{TEMPORARY}-Tabelle benutzen.
+Beachten Sie, dass @code{ALTER TABLE alter_name RENAME neuer_name} dagegen
+funktioniert!
+Das soll in Version 4.0 behoben werden.
+@end itemize
+
+
+
+@c German FIX this appendix should be removed (as was done from English ver.)
+@node Benutzer, MySQL-Benutzung durch Kunden, Problems, Top
+@c German node <no English equivalent>
+@appendix Einige MySQL-Benutzer
+
+@cindex Benutzer, von MySQL
+@cindex News-Sites
+
+Dieser Anhang listet einige Benutzer von MySQL auf, die uns ihre
+Genehmigung erteilt haben, sie in dieser Dokumentation aufzuführen. Diese
+Liste ist bei weitem nicht vollständig, sollte aber eine allgemeine
+Vorstellung davon geben, wer MySQL benutzt und wofür es benutzt werden
+kann.
+
+
+@appendixsec Allgemeine News-Sites
+
+@itemize @bullet
+
+@item @uref{http://www.yahoo.com/, Yahoo!}
+
+@item @uref{http://slashdot.org/, Slashdot: Eine Pro-Linux- / Tech-News- und Kommentar-/Diskussions-Site}
+
+@item @uref{http://www.linux.com/, Alles über Linux}
+
+@item @uref{http://www.linuxtoday.com/, Linuxtoday}
+
+@item @uref{http://www.32bitsonline.com/, 32Bits Online: weil es mehr als eine Art zu computern gibt}
+
+@item @uref{http://www.freshmeat.net/, Freshmeat: Neues über neue Versionen und computerbezogene Themen}
+
+@end itemize
+
+@cindex Suchmaschinen, web
+@cindex Web-Suchmaschinen
+@appendixsec Einige Web-Suchmaschinen
+
+@itemize @bullet
+
+@item @uref{http://www.aaa.com.au, AAA Matilda Web Search}
+
+@item @uref{http://www.whatsnu.com/, What's New}
+
+@item @uref{http://www.aladin.de/, Aladin}
+
+@item @uref{http://www.columbus-finder.de/, Columbus Finder}
+
+@item @uref{http://www.spider.de/, Spider}
+
+@item @uref{http://www.blitzsuche.de/, Blitzsuche}
+
+@item @uref{http://www.indoseek.co.id, Indoseek Indonesien}
+
+@item @uref{http://www.yaboo.dk/, Yaboo - Yet Another BOOkmarker}
+
+
+@item @uref{http://www.ozsearch.com.au, OzSearch Internet Guide}
+
+@item @uref{http://www.splatsearch.com/, Splat! Search}
+
+@item @uref{http://osdls.library.arizona.edu/, The Open Source Digital Library System Project}
+@end itemize
+
+@appendixsec Einige Informations-Suchmaschinen mit Konzentration auf bestimmte Felder
+
+@itemize @bullet
+
+@item @uref{http://www.spylog.ru/, SpyLOG ; Eine sehr populäre Web-Counter-Site}
+
+@item @uref{http://www.tucows.com/, TuCows Network; Archiv für Freie Software}
+
+@item @uref{http://www.jobvertise.com,Jobvertise: Angebot und Nachfrage nach Jobs}
+
+@item @uref{http://www.musicdatabase.com, die Musik-Datenbank}
+
+@item @uref{http://www.soccersearch.com, Fussball-Suchseite}
+
+@item @uref{http://www.headrush.net/takedown, TAKEDOWN - Ringen}
+
+@item @uref{http://www.lyrics.net, das internationale Liedtext-Netzwerk}
+
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://TheMatrix.com/~matrix/bund_search.phtml, Musiker die andere Musiker suchen (kostenloser Service)}
+
+@item @uref{http://www.addall.com/AddBooks/Stores.html,AddALL Büchersuche und Preisvergleich}
+
+@item @uref{http://www.herbaria.harvard.edu/Data/Gray/gray.html,Harvard's Gray Herbarium Index von Pflanzennamen}
+
+@item @uref{http://www.game-Entwickler.com/, die Spiele-Entwicklungs-Suchmaschine}
+
+@item @uref{www.theinnkeeper.com, der Innkeeper Reiseführer}
+
+@item @uref{http://www.macgamedatabase.com/, die Mac-Game-Datenbank benutzt PHP und MySQL}
+@c Von: Marc Antony Vose <suzerain@suzerain.com>
+
+@item @uref{http://www.csse.monash.edu.au/publications/, Research
+Veröffentlichungen an der Monash University in Australien}
+
+@item @uref{http://www.ipielle.emr.it/bts/index.html,
+Berufsbezogene Gesundheits- und Sicherheits-Website-Datenbank (ein Projekt für die ECC)}
+@c c.presutti@ipielle.emr.it
+
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://data.mch.mcgill.ca/, Bioinformatik-Datenbanken am
+Montreal-Kinderkrankenhaus die MySQL benutzen}
+@c saeed@www.debelle.mcgill.ca
+@end itemize
+
+@cindex Online-Magazine
+@cindex magazines, online
+@appendixsec Online-Magazine
+
+@itemize @bullet
+@item @uref{http://www.spoiler.com, Spoiler Webzine}.
+Ein Online-Magazin für Musik, Literatur, Kunst und Design.
+@item @uref{http://www.linux-magazin.de/newsflash/, Tägliche Nachrichten über Linux in deutscher Sprache}
+@item @uref{http://www.betazine.com,Betazine - Das ultimate Online-Betatester-Magazin}
+@item @uref{http://www.currents.net/ccinfo/aboutcc.html,Computer Currents Magazine}
+@end itemize
+
+@cindex Websites
+@appendixsec Websites die MySQL als Backend benutzen
+
+@itemize @bullet
+
+@item @uref{http://liftoff.msfc.nasa.gov, NASA}
+@item @uref{http://kids.msfc.nasa.gov, NASA KIDS}
+@item @uref{http://science.nasa.gov, Science@@NASA}
+
+@item @uref{http://www.handy.de/, handy.de}
+
+@item @uref{http://lindev.jmc.tju.edu/qwor, Qt Widget and Object Repository}
+
+@item @uref{http://www.samba-choro.com.br, Brasilianische Samba-Site (auf portugiesisch)}
+
+@item @uref{http://pgss.iss.uw.edu.pl/en_index.ISS, polnische allgemeine Sozial-Umschau}
+
+@item @uref{http://www.expo2000.com, Expo2000} Weltweiter Verkauf von
+Ticket für diese Veranstaltung wurde mit MySQL und tcl/tk implementiert.
+Mehr als 5.000 Reiseagenturen in der ganzen Welt hatten Zugriff darauf.
+
+@item @uref{http://www.freevote.com/, FreeVote.com ist ein kostenloser
+Abstimmungsservice mit Millionen Benutzern.}
+
+@item @uref{http://f1.tauzero.se, Forza Motorsport}
+
+@item @uref{http://www.dreamhost.com/, DreamHost Web-Hosting}
+
+@end itemize
+
+@cindex services
+@appendixsec Einige Domain- / Internet- / Web- und verwandte Services
+
+@itemize @bullet
+
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://www.wix.com/mysql-hosting, Registrar von Webprovidern
+die MySQL unterstützen}
+
+@item @uref{http://www.yi.org/, dynamische DNS-Services}
+
+@item @uref{http://www.dynodns.net/, dynamischer Domain-Name-Service}
+
+@item @uref{http://www.ods.org/, Open DNS Project; kostenloser dynamischer DNS-Service}
+
+@c @item @uref{http://dynodns.net, kostenlose dynamische DNS-Implementation}
+@c EMAIL: A Moore <amoore@mooreSysteme.com>
+
+@item @uref{http://www.hn.org/, Hammernode; öffentliche DNS-Server}
+
+@item @uref{http://www.fdns.net/, kostenlose 3rd-Level-Domains}
+
+@item @uref{http://worldcommunity.com/, Online-Datenbank}
+
+@item @uref{http://www.bigbiz.com, BigBiz Internet-Services}
+
+@item @uref{http://virt.circle.net, The Virt Gazette}
+
+@item @uref{http://www.california.com, Global InfoNet Inc}
+
+@item @uref{http://www.webhosters.com, WebHosters - ein Führer für WWW-Provider}
+
+@item @uref{http://online.dn.ru, Internet-Informations-Server}
+
+@item @uref{http://www.stopbit.com, eine Technologie-News-Site}
+
+@item @uref{http://www.worldnetla.net, WorldNet Communications - ein Internet Service Provider}
+
+@item @uref{http://www.netizen.com.au/, Netizen: Web-Beratung in Australien}
+
+@item @uref{http://www.trainingpages.co.uk, Suchseite für Trainingskurse in Großbritannien}
+
+@item @uref{http://chat.nitco.com, Gannon Chat (GPL). Geschrieben in Perl und JavaScript}
+
+@item @uref{http://www.addurls.com/, ein allgemeines Links-Verzeichnis}
+
+@item @uref{http://www.bookmarktracker.com, ein Web-basierender Bookmark-Verwaltungs-Service}
+
+@item @uref{http://www.cdrom.com,Walnut Creek CDROM}
+
+@item @uref{http://www.wwwThread.org/, WWWThread; interaktive Diskussionsforen}
+
+@item @uref{http://pvmon.portici.enea.it/Meteo, auf italienisch; Datenspeicherung von meteo station}
+
+@item @uref{http://www.buysell.net/, Online-"Person To Person"-Auktion}
+
+@item @uref{http://tips.pair.com, Tipps zur Web-Entwicklung}
+
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://www.mailfriends.com, Mailfriends.com ist ein kostenloser Service für jeden der über das Internet einen Freund finden will.}
+
+@item @uref{http://www.uninova.com/cgi-bin/wctelnets?list, Website Telnet BBS List}
+
+@item @uref{http://www.uninova.com/cnc.html, UniNova Digitale Postkarten}
+
+@c @item @uref{http://cabinboy.powersurfr.com, eine Internet-RFC-Suchmaschine}
+
+@item @uref{http://www.dslreports.com, DSL-Provider-Suche mit Testberichten}.
+Mit MySQL und Modperl hergestellt. Alle Seiten werden dynamisch aus einer
+MySQL-Datenbank erzeugt.
+@end itemize
+
+@cindex PHP, Websites
+@appendixsec Websites, die @code{PHP} und MySQL benutzen
+
+@itemize @bullet
+@c @item @uref{http://www.wh200th.com, Site zum 200. Jahrestag des Weißen Hauses}
+
+@item @uref{http://support.jgaa.com/, Jgaa's Internet - Offizielle Support-Site}
+
+@item @uref{http://io.incluso.com, Ionline - online publication:} MySQL, PHP, Java, Web-Programmierung, DB-Entwicklung
+
+@item @uref{http://www.baboo.com, BaBoo(Browse und bookmark). Kostenloser Web-basierender Bookmarkmanager und Kalender}
+
+@item @uref{http://www.courses.pjc.cc.fl.us/Schedule/index.php, Kursplanungssystem am Pensacola Junior College}
+
+@item @uref{http://www.fccj.org, Florida Community College in Jacksonville}
+
+@item @uref{http://www.32bit.com/, 32bit.com; Ein umfangreiches Shareware- / Freeware-Archiv}
+
+@item @uref{http://www.jokes2000.com/, Jokes 2000}
+@c Added 990604; EMAIL: ah@dybdahl.dk
+
+
+@item @uref{http://www.burken.nu/ , Burken.NU} Burken ist ein Webhotel, das Skripte unter anderem für entfernte Benutzer zur Verfügung stellt, beispielsweise Counter, Gästebücher usw.
+@c Added 990608; EMAIL: spacedmp@SpaceDump.Burken.NU (Anders Olausson)
+
+@item @uref{http://tips.pair.com, tips.pair.com} Enthält Tipps zu HTML, JavaScript, 2D-/3D-Grafiken und PHP3/MySQL. Alle Seiten werden aus einer Datenbank erzeugt.
+@c Added 990614; EMAIL: downey@image.dk (Rune Madsen)
+
+@item @uref{http://www.Softwarezrus.com/, Softwarezrus.com} E-Commerce-Site, die Computer verkauft.
+@end itemize
+
+@cindex Berater, Auflistung
+@appendixsec Einige MySQL-Berater
+
+@itemize @bullet
+
+@item @uref{http://iConnect.de, iConnect GmbH Berlin}
+
+@item @uref{http://www.ayni.com, Ayni AG}
+
+@item @uref{http://worldcommunity.com/, Online-Datenbank}
+
+@item @uref{http://www2.dataguard.no/,DataGuard (mit MySQL und PHP)}
+
+@item @uref{http://wwits.net/programs/mysql.phtml, WWITS (mit MySQL und PHP)}
+
+@item @uref{http://www.worldcommunity.com/, WCN - The World Community Network}
+
+@item @uref{http://www.chipcastle.com, Chip Castle Dot Com Inc}
+@c Added 990603 EMAIL: chip@chipcastle.com (Chip Castle)
+
+@item @uref{http://www.cyber.com.au/, Cybersource Pty. Ltd}
+
+@item @uref{http://www.spring.de, Spring infotainment GmbH & Co. KG}
+@c added 990905 "Oliver Pischke" <opischke@spring.de>
+
+@item @uref{http://www.wamdesign.com/, Entwickelt Websites mit MySQL}
+@c Added 990905; max@wamdesign.com
+
+@item @uref{http://www.berkeleyconsultants.com, Berkeley-Berater-Gruppe}
+
+@item @uref{http://www.jammconsulting.com/, JAMM Consulting Inc.}
+
+@end itemize
+
+@appendixsec Programmierung
+
+@cindex Websites, verschiedene
+@appendixsec Nicht kategorisierte Seiten
+
+@itemize @bullet
+
+@item @uref{http://www.feature-showcase.com/htmls/demo_mysql.sql, AZC.COM's Feature Showcase}
+
+@item @uref{http://www.teach.org.uk/subjects/trainingcourse/g.html, Kurssuche}
+
+@item @uref{http://www.northerbys.com, Northerbys Online-Auktionen}
+
+@item @uref{http://www.schiphol.nl/flights/home.htm, Amsterdamer Flughafen Schiphol}
+
+@item @uref{http://TheMatrix.com/seventhsin/query.phtml, CD-Datenbank}
+
+@item @uref{http://TheMatrix.com/~flmm/GEAR.html, Datenbank gebrauchter Audio-Geräte}
+
+@item @uref{http://www.kiss.de/musik-mueller, Notenblätter}
+
+@item @uref{http://www.bagism.com, Bagism - Eine John-Lennon-Fanseite}
+
+@item @uref{http://www.selftaught.com/, US-Folkart-Broker}
+
+@item @uref{http://organizer.net/, Mail lesen auf dem Web}
+
+@item @uref{http://www.mypage.org/, Kostenlose Homepages auf www.somecoolname.mypage.org}
+
+@item @uref{http://www.schulweb.de/, Der Server für Schulen im Web (auf deutsch)}
+
+@item @uref{http://www.ald.net/, Auldhaefen Online-Services}
+
+@item @uref{http://www.cary.net/, CaryNET Information Center}
+
+@item @uref{http://www.Dataden.com/, Dataden Computer Systems}
+
+@item @uref{http://undree.grm.se/ undr@'emuseet (auf schwedisch)}
+
+@item @uref{http://www.him.net/, HOMESITE Internet Marketing}
+
+@item @uref{http://www.jade-v.com/techinfo.html, Jade-V Network Services }
+
+@item @uref{http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml, Weather World 2010 Technical Credits} @*
+
+@item @uref{http://gimp.foebud.org/registry/doc/, Über die Gimp-Plugin-Registrierung}
+
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://www.fast-inc.com/produkte/Archiver/database.html, Java-Werkzeug Archiver technical detail (leicht optimistisch was die MySQL-ANSI-92-Kompatibilität betrifft)}
+
+@item @uref{http://www.gamesdomain.com/cheats/usrcheat.phtml, Games Domain Cheats Datenbank}
+
+@item @uref{http://www.kcilink.com/poweredby/, The "Powered By" Page (Kcilink)}
+
+@item @uref{http://www.netcasting.net/index.whtml, Netcasting}
+
+@item @uref{http://homepages.tig.com.au/~mjj/nblTipps, NBL (Australian National Basketball League) tipping}
+
+@item @uref{http://www.cgishop.com/, CGI-Shop}
+
+@item @uref{http://www.whirlycott.com/, Whirlycott: Website-Design}
+
+@item @uref{http://www.mtp.dk, Museum Tusculanum Press}
+
+@item @uref{http://csdgi.historie.ku.dk/biblio, Centro Siciliano di Documentazione}
+
+@item @uref{http://caribou.dyn.ml.org:8000, Quake-Statistik-Datenbank}
+
+@item @uref{http://www.astroforum.ch, Astroforum: Astrologie und verwandte Dinge (auf deutsch)}
+
+@item @uref{http://www.opendebate.com, OpenDebate - Interaktive Umfragen & Offene Diskussionen}
+
+@item @uref{http://vermeer.organik.uni-erlangen.de/dissertationen/, Online-Server für Dissertationen im Bereich Chemie}
+
+@item @uref{http://www.freschinfo.com, FreSch! The Free Scholarship Search Service}
+
+@item @uref{http://www.nada.kth.se/~staffanu/pinball, Stockholmer Flipper-Finder}
+
+@item @uref{http://www.hek.com, HEK - eine Baufirma}
+
+@item @uref{http://www.nbi.nl, Elsevier Business Information}
+
+@item @uref{http://vaccination.medicallink.se/, Medizinische Links (mit ColdFusion und MySQL)}
+
+@item @uref{http://www.joblink-usa.com, Suche nach Jobs & Leuten auf JobLink-USA}
+
+@item @uref{http://www.skydive.net/competfs, Competition Formation Skydiving}
+
+@item @uref{http://www.galaxy-net.net/Galaxy-NET Telecommunikation, E-Commerce und interne Buchhaltung}
+
+@item @uref{http://www.borsen.dk/, Dänemarks führende Wirtschaftszeitung B@o{}rsen}
+
+@item @uref{http://tmmm.simplenet.com/indb/, Die Internet-NES-Datenbank}
+
+@item @uref{http://www.russia.cz, Reisebüro in Prag in 3 Sprachen}
+
+@item @uref{http://www.linkstation.de, Linkstation}
+
+@item @uref{http://www.peoplestaff.com, Durchsuchbare Online-Datenbank bei Peoplestaff}
+
+@item @uref{http://www.dreamhorse.com, Durchsuchbares Datenbank-System für Pferde-bezogene Werbung}
+
+@item @uref{http://pootpoot.com/,The Poot site}
+
+@item @uref{http://grateful.net/hw_html/,"Playin' in the LAN"; Netzwerk-Monitoring-Suite}
+
+@c Update von Christopher Milton <cmilton@bwn.net> 1999-12-21
+@item @uref{http://www.usapa.army.mil,U.S. Army Publishing Agency}
+
+@item @uref{http://www.nekretnine.co.yu/,Makler in Jugoslawien}
+
+@item @uref{http://demo.cpsoft.com/pims/devFAQ.html, PIMS; Patienten-Informations-Management-System}
+
+@item @uref{http://cpsoft.com,Pilkington Software Inc}
+
+@item @uref{http://www.no-quarter.org/, Memorial für Vietnam-Veteranen (The Wall) - Datenbank}
+
+@item @uref{http://www.gamers-union.com/,Gamer's Union ist auf Auktionen für gebrauchtes und nicht mehr gedrucktes Spiele-Material spezialisiert}
+
+@item @uref{http://www.montereyhigh.com/office/dbul.php3, Ein tägliches Bulletin an der Monterey-Highschool}
+
+@item @uref{http://www.myEastside.com,Website der Gemeinde Lake
+Washington's Eastside für Einwohner und Unternehmen}
+
+@item @uref{http://bowling-france.net/, Französische Bowling-Site}
+@end itemize
+
+Schicken Sie Ergänzungen dieser Liste an @email{webmaster@@mysql.com}.
+
+@page
+
+
+
+
+@node MySQL-Benutzung durch Kunden, Contrib, Benutzer, Top
+@c German node <no English equivalent>
+@appendix MySQL-Benutzung durch Kunden
+
+@cindex MySQL-Benutzung
+
+Der Abschnitt 'Einige MySQL-Benutzer' enthält viele verschiedene Links zu
+MySQL-Benutzern, aber wenig Informationen darüber, wie diese MySQL
+benutzen. @xref{Benutzer}. Dieser Handbuch-Abschnitt soll Ihnen Anregungen
+geben, wie MySQL für Problemlösungen eingesetzt wird.
+
+Dieser Abschnitt ist neu und wir planen, hier in Bälde weitere Geschichten
+unterzubringen. Wenn Sie Interesse haben, teilzunehmen, und erzählen
+wollen, wie Sie MySQL in einer einzigartigen Umgebung nutzen, oder
+Erfolgsgeschichten zu Ihrer Benutzung von MySQL haben, schreiben Sie an
+@code{docs@@mysql.com} mit Betreff @code{Success:}. Beachten Sie, dass es
+einige Zeit bis zur Beantwortung dauern kann, da wir sehr beschäftigt sind.
+
+@itemize @bullet
+@item
+@strong{Peter Zaitsev von Spylog.ru} schreibt:
+Ich denke, die Größe meiner Datenbank könnte für Euch interessant sein.
+Die gesamte Datenbank liegt momentan auf 15 Servern und enthält etwa 60.000
+Tabellen, die etwa 5.000.000.000 Zeilen enthalten. Mein unter der höchsten
+Last stehender Server hat momentan etwa 10.000 Tabellen mit 1.000.000.000
+Zeilen. Die größten Tabellen enthalten etwa 50.000.000 Zeilen, und dieser
+Wert wird sich noch steigern, wenn ich auf den 2.4-Kernel mit großen
+Dateien umstelle. Momentan muss ich viele Logs für große Sites löschen, um
+Tabellengröße unter 2 GB zu halten.
+
+@item
+@strong{Texas Instruments} benutzt MySQL für die Handhabung von Tabellen,
+die bis zu 2 Milliarden Zeilen in einer Validations-Regressions-Datenbank
+enthalten.
+@end itemize
+
+@page
+
+
+
+
+@node Contrib, Credits, MySQL-Benutzung durch Kunden, Top
+@c German node Contrib
+@appendix Beigesteuerte Programme
+
+@cindex Beigesteuerte Programme
+@cindex Programme, beigesteuerte
+
+Viele Benutzer von MySQL haben @emph{sehr} nützliche Support-Werkzeuge und
+Add-ons beigesteuert.
+
+@ifclear web
+Eine Auflistung, was unter @uref{http://www.mysql.com/Downloads/Contrib/}
+(oder einem Mirror) verfügbar ist, steht unten. Wenn Sie
+MySQL-Unterstützung für die Perl-@code{DBI}/@code{DBD}-Schnittstelle bauen
+wollen, sollten Sie sich @code{Data-Dumper}, @code{DBI} und die
+@code{Msql-Mysql-modules}-Dateien holen und installieren.
+@xref{Perl}.
+@end ifclear
+
+@appendix sec-APIs
+
+@cindex Perl, Module
+@itemize @bullet
+@item Perl-Module
+@itemize @minus
+@item @uref{http://www.mysql.com/Downloads/Contrib/Data-Dumper-2.101.tar.gz, Data-Dumper-2.101.tar.gz}
+Perl-@code{Data-Dumper}-Module. Nützlich für
+@code{DBI}/@code{DBD}-Unterstützung für ältere Perl-Installationen.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/DBI-1.15.tar.gz, DBI-1.15.tar.gz}
+Perl-@code{DBI}-Module.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/KAMXbase1.2.tar.gz,KAMXbase1.2.tar.gz}
+Konvertiert zwischen @file{.dbf}-Dateien und MySQL-Tabellen. Perl-Module
+geschrieben von Pratap Pereira @email{pereira@@ee.eng.ohio-state.edu},
+erweitert von Kevin A. McGrail
+@email{kmcgrail@@digital1.peregrinehw.com}. Dieser Konverter kann
+MEMO-Felder handhaben.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/Msql-Mysql-modules-1.2216.tar.gz, Msql-Mysql-modules-1.2216.tar.gz}
+Perl-@code{DBD}-Module, um auf mSQL- und MySQL-Datenbanken zuzugreifen.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/Data-ShowTable-3.3.tar.gz, Data-ShowTable-3.3.tar.gz}
+Perl-@code{Data-ShowTable}-Module. Nützlich für @code{DBI}/@code{DBD}-Unterstützung.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/HandySQL-1.1.tar.gz, HandySQL-1.1.tar.gz}
+HandySQL ist ein MySQL-Zugriffsmodul. Es bietet eine C-Schnittstelle, die
+in Perl eingebettet ist und ist ungefähr 20% schneller als reguläres DBI.
+
+@end itemize
+
+@cindex JDBC
+@item JDBC
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-1.2c.tar.gz, mm.mysql.jdbc-1.2c.tar.gz}
+Der mm-JDBC-Treiber für MySQL. Das ist ein Produktions-Release und wird
+aktiv weiter entwickelt. Von Mark Matthews (@email{mmatthew@@ecn.purdue.edu}).
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-2.0pre5.tar.gz, mm.mysql.jdbc-2.0pre5.tar.gz}
+Der mm-JDBC-Treiber für MySQL. Das ist eine Pre-Release-Beta-Version und
+wird aktiv weiter entwickelt. Von Mark Matthews (@email{mmatthew@@ecn.purdue.edu}).
+Die beiden obigen Treibern stehen unter LGPL-Lizenz. Bitte sehen Sie unter
+@uref{http://www.worldserver.com/mm.mysql/} nach den aktuellsten Treibern
+nach (und wegen weiterer JDBC-Informationen), weil diese Treibern
+vielleicht schon veraltet sind.
+
+@item @uref{http://www.caucho.com/Projekte/jdbc-mysql/index.xtp}
+Der kommerzielle Resin-JDBC-Treiber, der unter Open Source veröffentlicht
+wird. Er behauptet, schneller als der mm-Treiber zu sein, aber wir haben
+darüber bislang noch nicht viele Informationen.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/twz1jdbcForMysql-1.0.4-GA.tar.gz, twz1jdbcForMysql-1.0.4-GA.tar.gz}
+Der twz-Treiber: Ein Typ-4-JDBC-Treiber von Terrence W. Zellers
+@email{zellert@@voicenet.com}. Dieser ist kommerziell, aber kostenlos für
+privaten und Schulungsgebrauch. (Wird nicht mehr unterstützt.)
+@c no answer von Server 990830
+@c You can always find the latest Treiber at @uref{http://www.voicenet.com/~zellert/tjFM/}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/pmdamysql.tgz,pmdamysql.tgz}
+Ein MySQL-PMDA. Stellt MySQL-Serverstatus- und Konfigurationsvariablen zur
+Verfügung.
+@end itemize
+
+@cindex OLEDB
+@item OLEDB
+@itemize @bullet
+@item @uref{http://www.mysql.com/downloads/Win32/MyOLEDB.exe, MyOLEDB.exe}
+OLEDB-Handler für MySQL. Von SWsoft.
+@item @uref{http://www.mysql.com/downloads/Win32/MySamples.zip, MySamples.zip}
+Beispiele und Dokumentation für MyOLEDB. Von SWsoft.
+@item @uref{http://www.mysql.com/downloads/Win32/Myoledb.zip, Myoledb.zip}
+Quelltext für MyOLEDB. Von SWsoft.
+@item @uref{http://www.mysql.com/downloads/Win32/MyOLEDB.chm, MyOLEDB.chm}
+Hilfedateien für MyOLEDB.
+@item @uref{http://www.mysql.com/downloads/Win32/libmyodbc.zip, libmyodbc.zip}
+Statische MyODBC-Bibliothek zum Bauen von MyOLEDB. Basiert auf MyODBC-Code.
+@end itemize
+
+@cindex C++
+@item C++
+@itemize @bullet
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-c++-0.02.tar.gz, mysql-c++-0.02.tar.gz}
+MySQL-C++-Wrapper-Bibliothek. Von Rolund Haenel,
+@email{rh@@ginster.net}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MyDAO.tar.gz, MyDAO}
+MySQL-C++-API. Von Satish @email{spitfire@@pn3.vsnl.net.in}. Inspiriert
+von Rolund Haenels C++-API und Ed Carps MyC-Bibliothek.
+
+@item @uref{http://www.mysql.com/download_mysql++.html, mysql++}
+MySQL-C++-API (mehr als nur eine Wrapper-Bibliothek). Ursprünglich von
+@email{kevina@@clark.net}. Mittlerweile gepflegt von Sinisa bei MySQL AB.
+
+@item @uref{http://nelsonjr.homepage.com/NJrAPI,NJrAPI}
+Eine in C++ geschriebene, Datenbank-unabhängige Bibliothek, die MySQL
+unterstützt.
+@end itemize
+
+@cindex Delphi
+@item Delphi
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/delphi-interface.gz, delphi-interface.gz}
+Delphi-Schnittstelle zu @code{libmysql.dll}, von Blestan Tabakov,
+@email{root@@tdg.bis.bg}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/DelphiMySQL2.zip, DelphiMySQL2.zip}
+Delphi-Schnittstelle zu @code{libmysql.dll}, von @email{bsilva@@umesd.k12.or.us}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/Udmysel.pas, Udmysql.pas}
+Ein Wrapper für libmysql.dll für die Benutzung in Delphi. Von Reiner Sombrowsky.
+
+@item @uref{http://www.fichtner.net/delphi/mysql.delphi.phtml, Eine Delphi-Schnittstelle zu MySQL.}
+Mit Quelltext. Von Matthias Fichtner.
+
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://www.productivity.org/projects/tmysql/, @strong{TmySQL}
+Eine Bibliothek um MySQL mit Delphi zu benutzen}.
+
+@item @uref{http://www.geocities.com/CapeCanaveral/2064/mysql.html, Delphi TDataset-component}.
+@item
+@item @uref{http://www.mysql.com/Downloads/Contrib/Win32/SBMySQL50Share.exe, Delphi 5 Shareware MySQL Dataset Components}
+@end itemize
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz, mysql-ruby-2.2.0.tar.gz}
+MySQL Ruvon module. Von TOMITA Masahiro @email{tommy@@tmtm.org}
+@uref{http://www.netlab.co.jp/ruby/, Ruby} ist eine objektorientierte Interpretersprache.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/JdmMysqlTreiber-0.1.0.tar.gz,JdmMysqlTreiber-0.1.0.tar.gz}
+Ein VisualWorks 3.0 Smalltalk-Treiber für MySQL. Von
+@email{joshmiller@@earthlink.net}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/Db.py, Db.py}
+Python-Modul mit Caching. Von @email{gundalf@@rosmail.com}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLmodule-1.4.tar.gz, MySQLmodule-1.4.tar.gz}
+Python-Schnittstelle für MySQL. Von Joseph Skinner @email{joe@@earthlight.co.nz}. Geändert von Joerg Senekowitsch @email{senekow@@ibm.net}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-python-0.3.0.tar.gz, MySQL-python-0.3.0.tar.gz}
+MySQLdb-Python ist eine DB-API v2.0-kompatible Schnittstelle zu MySQL.
+Transaktionen werden unterstützt, wenn der Server und die Tabellen sie
+unterstützen. Sie ist Thread-sicher und enthält ein Kompatibilitätsmodul
+für älteren Code, der für die nicht mehr gepflegte
+MySQLmodule-Schnittstelle geschrieben wurde.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mex_12.tar.gz, mysql_mex_1_12.tar.gz}
+Ein Schnittstellenprogramm für das Matlab-Programm von MathWorks. Die
+Schnittstelle wurde von Kimmo Uutela und John Fisher (nicht von Mathworks)
+hergestellt. Siehe
+@uref{http://boojum.hut.fi/~kuutela/mysqlmex.html,mysqlmex.html} wegen
+weiterer Informationen.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltcl-1.53.tar.gz, mysqltcl-1.53.tar.gz}
+Tcl-Schnittstelle für MySQL. Basiert auf @file{msqltcl-1.50.tar.gz}.
+Aktualisiert von Tobias Ritzau, @email{tobri@@ida.liu.se}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MyC-0.1.tar.gz, MyC-0.1.tar.gz}
+Eine Visual-Basic-ähnliche API von Ed Carp.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/sqlscreens-1.0.1.tar.gz, sqlscreens-1.0.1.tar.gz}
+Tcl/Tk-Code, um Datenbank-Screens zu erzeugen. Von Jean-Francois Dockes.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/Vdb-dflts-2.1.tar.gz, Vdb-dflts-2.1.tar.gz}
+Das ist eine neue Version eines Satzes von Bibliothek-Dienstprogrammen, die
+eine generische Schnittstelle zu SQL-Datenbank-Maschinen zur Verfügung
+stellen, um Ihre Applikation zu einer Stufe-3-Applikation (3-Tier) zu
+machen. Der Vorteil ist, dass Sie sehr einfach zwischen verschiedenen
+Datenbank-Maschinen umschalten bzw. zu anderen Datenbanken wechseln können.
+Sie implementieren einfach eine Datei für das neue Backend und brauche
+keinerlei Änderungen an Ihren Applikationen vorzunehmen. Von
+@email{damian@@cablenet.net}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/DbFramework-1.10.tar.gz, DbFramework-1.10.tar.gz}
+DbFramework ist eine Sammlung von Klassen zur Manipulation von
+MySQL-Datenbanken. Die Klassen basieren lose auf der CDIF Data Model
+Subject Area. Von Paul Sharpe @email{paul@@miraclefish.com}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/pike-mysql-1.4.tar.gz, pike-mysql-1.4.tar.gz}
+MySQL-Modul für pike. Zur Benutzung mit dem Roxen-Webserver.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/squile.tar.gz, squile.tar.gz}
+Modul für @code{guile}, das es @code{guile} erlaubt, mit SQL-Datenbanken zu
+interagieren. Von Hal Roberts.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/stk-mysql.tar.gz, stk-mysql.tar.gz}
+Interface für Stk. Stk ist Tk-widgets mit Scheme darunter anstelle von Tcl.
+Von Terry Stefan.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/eiffel-wrapper-1.0.tar.gz,eiffel-wrapper-1.0.tar.gz}
+Eiffel-Wrapper von Michael Ravits.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/SQLmy0.06.tgz,SQLmy0.06.tgz}
+Ersetzbarer FlagShip-Datenbank-Treiber (RDD) für MySQL. Von Alejundro
+Fernundez Herrero.
+@uref{http://www.fship.com/rdds.html, Flagship-RDD-Homepage}
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mydsn-1.0.zip,mydsn-1.0.zip}
+Binärdatei und Quellcode für @code{mydsn.dll}. mydsn sollte benutzt werden,
+um die DSN-Registrierungsdatei für den MyODBC-Treiber in
+Coldfusion-Applikationen zu bauen und zu entfernen. Von Miguel Angel
+Solórzano.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-ADA95_API.zip, MySQL-ADA95_API.zip}
+Eine ADA95-Schnittstelle zur MySQL-API. Von Francois Fabien.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MyTool-DLL_for_VB_und_MySQL.zip, MyTool-DLL_for_VB_und_MySQL.zip}
+Eine DLL mit MySQL-C-API für Visual Basic.
+Von Ken Menzel @email{kenm@@icarz.com}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MYSQLX.EXE, MYSQL.EXE}
+MySQL-ActiveX-Objekt für den direkten Zugriff auf Ihre MySQL-Server von
+IIS/ASP, VB und VC++ aus, der die langsameren ODBC-Methoden überspringt.
+Voll aktualisierbar, multi-threaded mit voller Unterstützung für alle
+MySQL-Feldtypen (Version 2001.1.1). Von SciBit @uref{http://www.scibit.com/}.
+
+@item @uref{http://www.fastflow.it/mylua/, MyLUA Homepage}
+Wie man die LUA-Sprache benutzt, um MySQL-@code{PROCEDURE} zu schreiben,
+das zur Laufzeit geladen werden kann.
+
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/lua-4.0.tar.gz, Lua 4.0}
+LUA 4.0
+@item @uref{http://www.mysql.com/Downloads/Contrib/mylua-3.23.32.1.tar.gz, mylua-3.23.32.1.tar.gz}
+Patch für MySQL 3.23.32, um LUA 4.0 zu benutzen. Von Cristian Giussani.
+@end itemize
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/patched_myodbc.zip, patched_myodbc.zip}
+Patch (für Omniform-4.0-Unterstützung) des MyODBC-Treibers.
+Von Thomas Thaele @email{tthaele@@papenmeier.de}
+
+@end itemize
+
+@appendixsec Clients
+
+@itemize @bullet
+@item Grafische Clients
+@itemize @minus
+@item @uref{http://www.ideit.com/produkte/dbvis/, DbVisualizer}.
+Freeware-JDBC-Client, der Daten und Strukturen mehrerer Datenbanken auf
+einmal grafisch visualisiert. Von Innovative-IT Development AB.
+
+@item @uref{http://www.mysql.com/downloads/gui-clients.html, MySQLGUI}
+Die MySQL-GUI-Client-Homepage. Von Sinisa bei MySQL AB.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_navigator_0.9.0.tar.gz, MySQL Navigator 0.9}
+MySQL Navigator ist ein MySQL-Datenbank-Server-GUI-Client-Programm. Der
+Zweck von MySQL Navigator ist, eine nützliche Schnittstelle zu
+MySQL-Datenbank-Servern zur Verfügung zu stellen, wobei mehrere
+Betriebssysteme und Sprachen unterstützt werden. Momentan können Sie
+Datenbanken importieren / exportieren, Anfragen eingeben, Ergebnismengen
+holen, Skripte editieren, Skripte laufen lassen, Benutzer hinzufügen,
+ändern und löschen, und Client- und Server-Informationen abrufen. Benutzt
+QT 2.2. GPL @uref{http://sql.kldp.org/mysql, Homepage für MySQL Navigator}.
+
+@item @uref{http://www.mysql.com/downloads/Win32/secman.zip, MySQL-Sicherheits-GUI}
+Eine Benutzer- und Sicherheitsverwaltungs-GUI für MySQL unter Windows.
+Von Martin Jeremic.
+@uref{http://jsoft.webjump.com/, Homepage für MySQL-Sicherheits-GUI}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1.tar.gz, kmysqladmin-0.4.1.tar.gz}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.src.rpm, kmysqladmin-0.4.1-1.src.rpm}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.i386.rpm, kmysqladmin-0.4.1-1.i386.rpm}
+Ein Verwaltungswerkzeug für den MySQL-Server, das QT / KDE benutzt. Nur
+unter Linux getestet.
+
+@item
+@uref{http://www.mysql.com/Downloads/Contrib/mysql-admin-using-java+swing.tar.gz, Java client mit Swing} Von Fredy Fischer,
+@email{se-afs@@dial.eunet.ch}. Sie finden die letzte Version immer unter
+@uref{http://www.trash.net/~ffischer/admin/index.html, hier}.
+
+@item @uref{http://www.mysql.com/downloads/Win32/MySQL-Maker-1.0.zip,MySQL-Maker 1.0}.
+Shareware-MySQL-Client für Windows. Ein WYSIWYG-Werkzeug, mit dem Sie
+Datenbanken und Tabellen erzeugen, ändern und löschen können. Sie können
+die Feldstruktur ändern, Felder hinzufügen und Daten hinzufügen, ändern und
+löschen, direkt ohne ODBC-Treiber.
+@uref{http://www.presult.de/presult/frames/fs_mysqlmaker.html, MySQL-Maker-Homepage}
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlwinadmn.zip, mysqlwinadmn.zip}
+Windows-GUI (nur Binärdatei) zur Verwaltung einer Datenbank, von David B. Mansel,
+@email{david@@zhadum.org}.
+
+@item @uref{http://home.online.no/~runeberg/myqa, MyQA}
+Ein Linux-basierender Anfrage-Client für den MySQL-Datenbank-Server. Mit
+MyQA können Sie SQL-Anfragen eingeben, diese ausführen und die Ergebnisse
+betrachten, alles in einer grafischen Benutzerschnittstelle. Die GUI ähnelt
+grob dem 'Anfrage-Analyzer'-Client, der mit dem Microsoft SQL-Server
+ausgeliefert wird.
+
+@item @uref{http://members.xoom.com/_opex_/mysqlmanager/index.html, MySQL-Manager}
+Ein grafischer MySQL-Server-Manager für MySQL-Server. Geschrieben in Java,
+für Windows.
+
+
+@item @uref{http://www.mysql.com/downloads/Win32/netadmin.zip, netadmin.zip}
+Ein Verwaltungswerkzeug für MySQL unter Windows 95/98 und Windows NT 4.0.
+Nur getestet mit MySQL-Versions 3.23.5 bis 3.23.7. Geschrieben mit den
+Tmysql-Komponenten.
+
+Sie können Anfragen schreiben und Tabellen darstellen, Indexe,
+Tabellensyntax sowie Benutzer, Host und Datenbank verwalten und vieles
+mehr. Das Werkzeug ist eine Beta-Version und hat noch viele Bugs. Sie
+können das Programm mit allen Features testen. Bitte schicken Sie Bugs und
+Hinweise an Marco Suess @email{ms@@it-netservice.de}. Original-URL
+@url{http://www.it-netservice.de/pages/Software/index.html}.
+
+@item @uref{http://www.mysql.com/downloads/Win32/netadmin2.zip, netadmin2.zip}
+Neue Version von netadmin. Siehe oben wegen Details.
+
+@item @uref{http://www.mysql.com/downloads/Win32/ARTADMIN203.EXE,Atronic's MySQL-Client für Windows 2.0.3.0}.
+Die Homepage hierfür ist unter @uref{http://www.artronic.hr}.
+
+@item @uref{http://www.mysql.com/downloads/Win32/mysqlfront.zip, mysqlfront}
+Homepage: @uref{http://www.mysqlfront.de/}.
+Win32-Client für die Verwaltung von Datenbanken, Tabellen, Tabellendaten,
+Indexen und Import-/Export-Dateien. Freeware. Von Ansgar Becker.
+
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://www.mysql.com/downloads/Win32/W9xstop.zip,Dienstprogramm
+von Artronic um MySQL unter Windows 9x anzuhalten}.
+
+@item @uref{http://bardo.hyperlink.cz/mysqlmon,ein leichtgewichtiger GUI-Client für Windows}.
+
+@item @uref{http://dbtools.vila.bol.com.br/, DB-Werkzeuge}
+Ein Werkzeug zur Verwaltung von MySQL-Datenbanken. Momentan nur für
+Windows. Einige Features:
+@itemize @bullet
+@item Verwaltung von Servern, Datenbanken, Tabellen, Spalten, Indexen und
+Benutzern.
+@item Import-Assistent, um Strukturen und Daten von MS Access, MS Excel,
+Dbase, FoxPro, Paradox und ODBC Datenbanken zu übernehmen.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/KMYENG113.zip,KMYENG113.zip}
+Eine Verwaltungs-GUI für MySQL. Funktioniert nur unter Windows, kein
+Quellcode verfügbar. Verfügbar in englisch und japanisch. Von Mitunobu Kaneko.
+Homepage: @uref{http://sql.jnts.ne.jp/}
+@end itemize
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/xmysqladmin-1.0.tar.gz, xmysqladmin-1.0.tar.gz}
+Ein X-basierendes Frontend zur MySQL-Datenbank-Maschine. Erlaubt Neuladen,
+Status-Prüfungen, Prozesssteuerung, myisamchk, grant/revoke-Berechtigungen,
+Erzeugung von Datenbanken, Löschen von Datenbanken, Erzeugen, Ändern,
+Durchsuchen und Löschen von Tabellen. Original von Gilbert Therrien,
+@email{gilbert@@ican.net}, jetzt aber Public Domain und von MySQL AB
+unterstützt.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/xmysql-1.9.tar.gz, xmysql-1.9.tar.gz}.
+@item @uref{http://web.wt.net/~dblhack, xmysql-Homepage}
+Ein Frontend zur MySQL-Datenbank-Maschine, mit der man auf einfache Weise
+Anfragen und Tabellenwartung durchführen kann sowie Stapel-Anfrragen. Von
+Rick Mehalick, @email{dblhack@@wt.net}.
+Erfordert @uref{http://bragg.phys.uwm.edu/xforms,xforms 0.88}, um zu
+funktionieren.
+@item @uref{http://www.tamos.net/sw/dbMetrix,dbMetrix}
+Ein Open-Source-Client für das Durchsuchen von Datenbanken und die
+Ausführung von SQL. Unterstützt MySQL, Oracle, PostgreSQL und mSQL.
+@item @uref{http://www.multimania.com/bbrox/GtkSQL,GtkSQL}
+Ein Anfrage-Werkzeug für MySQL und PostgreSQL.
+@item @uref{http://dbman.linux.cz/,dbMan}
+Ein Anfrage-Werkzeug, geschrieben in Perl. Benutzt DBI und Tk.
+@item @uref{http://www.mysql.com/downloads/Win32/Msc201.EXE, Mascon 202}
+@item @uref{http://www.mysql.com/downloads/Win32/FrMsc202.EXE, Free Mascon 202}
+Mascon ist eine mächtige Win32-GUI für die Verwaltung von
+MySQL-Server-Datenbanken. Die Features von Mascon beinhalten visuellen
+Tabellenentwurf, Verbindungen zu mehrfachen Servern, Daten- und
+Blob-Editierung von Tabellen, Sicherheitseinstellungen, SQL-Farb-Coding,
+Dump-Funktionalität und vieles mehr.
+@uref{http://www.scibit.com/produkte/Software/Utils/Mascon.asp,Mascon-Homepage}.
+@item @uref{http://www.virtualbeer.net/dbui/,DBUI}
+DBUI ist ein grafischer Gtk-Datenbank-Editor.
+@item @uref{http://www.rtlabs.com/, MacSQL}
+GUI für MySQL-, ODBC- und JDBC-Datenbanken für Mac OS.
+@item @uref{http://www.caleb.com.au/, JRetriever}
+JRetriever ist ein generisches Datenbank-Frontend-Werkzeug für
+JDBC-kompatible Datenbanken, geschrieben mit Java 2. JRetriever zeigt
+Datenbank- und Tabellenansichten in einem Windows-Explorer-ähnlichen
+Frontend an. Der Benutzer kann Daten entweder durch Klicken auf den
+Tabellen-Ordner oder durch das Zusammenstellen eigener SQL-Statements mit
+dem eingebauten SQL-Editor abrufen. Das Werkzeug wurde mit Oracle 8 und
+MySQL als Backend-Datenbanken getestet. Es erfordert JDK 1.3 von JavaSoft.
+@item @uref{http://www.jetools.com/products/databrowser/, DataBrowser}
+Der DataBrowser ist ein Datenbank- und Plattform-übergreifendes
+Datenzugriffswerkzeug. Es ist benutzerfreundlicher als Werkzeuge wie SQL
+Plus, psql (kommandozeilenbasierende Werkzeuge). Es ist flexibler als TOAD,
+ISQL und PGAccess, die als GUIs auf eine einzige Plattform oder Datenbank
+beschränkt sind.
+@item @uref{http://www.intrex.net/amit/Software/, SQLC}
+Die SQL Console ist eine eigenständige Java-Applikation, mit der Sie auf
+ein SQL-Datenbanksystem zugreifen und SQL-Anfragen und -Aktualisierung
+absetzen können. Es hat eine leicht benutzbare grafische
+Benutzerschnittstelle. Die SQL Console benutzt JDBC, um sich mit dem
+Datenbanksystem zu verbinden. Daher können Sie sich mit den richtigen
+JDBC-Treibern mit diesem Dienstprogramm mit den beliebtesten
+Datenbanksystemen verbinden.
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mmc.zip, MySQL MMC}
+MySQL MMC ist ein GUI-Management-Werkzeug, das mit kdevelop entwickelt
+wurde. Es besitzt eine sehr gute Schnittstelle, die komplett Microsoft
+Enterprise Tool (für SQL Server) oder Sybase Central ähnelt. Damit können
+Sie Server, Datenbanken, Tabellen, Indexe und Benutzer verwalten und
+Tabellendaten in Gittern editieren, sowie SQL ausführen.
+@end itemize
+
+@cindex Web-Clients
+@item Web-Clients
+@itemize @minus
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladmin-atif-1.0.tar.gz, mysqladmin-atif-1.0.tar.gz}
+WWW-MySQL-Verwaltungswerkzeug für die @code{user}-, @code{db}- und
+@code{host}-Tabellen. Von Tim Sailer, geändert von Atif Ghaffar
+@email{aghaffar@@artemedia.ch}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-webadmin-1.0a8-rz.tar.gz, mysql-webadmin-1.0a8-rz.tar.gz}
+Ein in PHP-FI geschriebenes Werkzeug zur Verwaltung von MySQL-Datenbanken,
+entfernt über das Web mit einem Web-Browser. Von Peter Kuppelwieser,
+@email{peter.kuppelwieser@@kantea.it}. Aktualisiert von Wim Bonis,
+@email{bonis@@kiss.de}. Wird nicht mehr gepflegt!
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm.tar.gz, mysqladm.tar.gz}
+MySQL-Web-Datenbankadministration, geschrieben in Perl. Von Tim Sailer.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm-2.tar.gz, mysqladm-2.tar.gz}
+Aktualisierte Version von @file{mysqladm.tar.gz}, von High Tide.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/billowmysql.zip, billowmysql.zip}
+Akualisierte Version von @file{mysqladm.tar.gz}, von Ying Gao. Sie erhalten
+die neueste Version von @uref{http://civeng.com/sqldemo/, der Homepage}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/myadmin-0.4.tar.gz, myadmin-0.4.tar.gz}.
+@item @uref{http://myadmin.cheapnet.net/, MyAdmin-Homepage}
+Ein Web-basierender MySQL-Administrator von Mike Machado.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin_2.2.0.tar.gz,phpMyAdmin_2.2.0.tar.gz}
+Ein Satz von PHP3-Skripten, um MySQL über das WWW zu administrieren.
+
+@item @uref{http://www.phpwizard.net/Projekte/phpMyAdmin/, phpMyAdmin Homepage}
+Ein PHP3-Werkzeug im Geiste von mysql-webadmin, von Tobias Ratschiller,
+tobias@@dnet.it.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/useradm.tar.gz, useradm.tar.gz}
+MySQL-Administrator in PHP. Von Ofni Thomas @email{othomas@@vaidSysteme.com}.
+
+@item @uref{http://gossamer-thread.com/perl/mysqlman/mysql.cgi, MySQLMan}
+Ähnliche Funktionalität wie phpmyadmin, aber geschrieben in Perl und unter
+Verwenden von HTML-Vorlagen. Von Alex Krohn.
+@end itemize
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-editor.tar.gz,mysql-editor.tar.gz}
+Mit diesen CGI-Skripten in Perl können Sie die Inhalte von
+MySQL-Datenbanken editieren. Von Tomas Zeman.
+@item
+@uref{http://worldcommunity.com/openquelle/futuresql, FutureSQL Web-Datenbankadministrations-Werkzeug}.
+FutureSQL von Peter F. Brown ist ein Open-Source-Web-Datenbank-Werkzeug für
+die schelle Applikationsentwicklung. Geschrieben in Perl, verwendet MySQL.
+Benutzt @code{DBI:DBD} und @code{CGI.pm}.
+
+Mit FutureSQL können Sie schnell config-Dateien einrichten, um Datensätze
+einer MySQL-Datenbank zu betrachten, zu editieren, zu löschen und
+anderweitig zu verarbeiten. Es benutzt ein Daten-Wörterbuch,
+Konfigurationsdateien und Vorlagen und erlaubt "Pre-Processing" und
+"Post-Processing" von Feldern, Datensätzen und Operationen.
+@end itemize
+
+@cindex Web-Werkzeuge
+@cindex Werkzeuge,, Web
+@appendixsec Web-Werkzeuge
+
+@itemize @bullet
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mod_mysql_include_1.0.tar.gz, mod_mysql_include_1.0.tar.gz}
+Apache-Modul, um HTML von MySQL-Anfragen in Ihre Seiten zu integrieren und
+um Aktualisierungsanfragen auszuführen. Ursprünglich geschrieben, um ein
+einfaches, schnelles Banner-Rotationssystem mit geringem Overhead zu
+implementieren. Von Sasha Pachev.
+
+@item @uref{http://htcheck.sourceforge.net, htCheck} - URL-Überprüfer mit
+MySQL-Backend. Gelistete (spidered) URLs können später abgefragt werden,
+wobei SQL verwendet wird, um verschiedene Sorten von Information abzurufen,
+z. B. Broken Links. Geschrieben von Gabriele Bartolini.
+
+@item @uref{http://www.odbsoft.com/cook/sources.htm}
+Dieses Paket hat diverse Funktionen zum Erzeugen von HTML-Code aus einer
+SQL-Tabellenstruktur und zum Erzeugen von SQL-Statements (Select, Insert,
+Update, Delete) aus einem HTML-Formular. Sie können komplette
+Formular-Schnittstellen zu einer SQL-Datenbank bauen (Anfrage, Hinzufügen,
+Aktualisierung, Löschen), ohne jedes Programmieren! Von Marc Beneteau, @email{marc@@odbsoft.com}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/sqlhtml.tar.gz, sqlhtml.tar.gz}
+SQL/HTML ist ein HTML-Datenbankmanager für MySQL mit @code{DBI} 1.06.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/udmsearch-3.0.23.tar.gz, UdmSearch 3.0.23 (stabile Version)}.
+@c German FIX removed comma (",") to make description work inside uref
+@item @uref{http://www.mysql.com/Downloads/Contrib/mnogosearch-3.1.12.tar.gz, mnogosearch 3.1.12 (Entwicklungs- aber empfohlene Version)}.
+@item @uref{http://search.mnoGo.ru, UdmSearch-Homepage}
+Eine SQL-basierende Suchmaschine fürs Internet. Von Alexander I. Barkov @email{bar@@izhcom.ru}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.doc, wmtcl.doc}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.lex, wmtcl.lex}
+Hiermit können Sie HTML-Dateien mit Einfügungen von Tcl-Code schreiben. Von @email{vvs@@scil.npi.msu.su}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.lsm, www-sql-0.5.7.lsm}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.tar.gz, www-sql-0.5.7.tar.gz}
+Ein CGI-Programm, das eine HTML-Datei mit speziellen Tags parst, die Tags
+selbst parst und Daten aus einer MySQL-Datenbank einfügt.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/genquery.zip, genquery.zip}
+Perl-SQL-Datenbankschnittstellenpaket für HTML.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/cgi++-0.8.tar.gz, cgi++-0.8.tar.gz}
+Ein Makro-Prozessor, um leicht CGI/Datenbank-Programme in C++ zu schreiben. Von Sasha Pachev.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/webboard-1.0.zip, WebBoard 1.0}
+EU-Industries Internet-Message-Board.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz, DBIx-TextIndex-0.02.tar.gz}
+Volltextsuche mit Perl auf @code{BLOB}/@code{TEXT}-Spalten. Von Daniel Koch.
+@end itemize
+
+@cindex Werkzeuge, Benchmark-
+@cindex Benchmark, Werkzeuge
+@appendixsec Performance-Benchmark-Werkzeuge
+
+@itemize @bullet
+@item @uref{http://www.mysql.com/downloads/super-smack/super-smack-1.0.tar.gz,
+ super-smack}
+Multi-Threaded Benchmark-Werkzeug für MySQL und @strong{PostgreSQL}.
+Geschrieben in C++. Leicht zu erweitern für die Unterstützung anderer
+Datenbanken, die C/C++-Client-Bibliotheken haben. Von Sasha Pachev.
+@end itemize
+
+@cindex Werkzeuge, Authentifizierung
+@cindex Authentifizierungswerkzeuge
+@appendixsec Authentifizierungswerkzeuge
+
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/ascend-radius-mysql-0.7.2.patch.gz,ascend-radius-mysql-0.7.2.patch.gz}
+Das ist ein Authentifizierungs- und Logging-Patch, der MySQL für Ascend-Radius benutzt. Von @email{takeshi@@SoftAgency.co.jp}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/icradius-0.10.tar.gz, icradius 0.10}
+@uref{http://www.mysql.com/Downloads/Contrib/icradius.README, icradius readme-Datei}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/checkpassword-0.81-mysql-0.6.6.patch.gz,
+checkpassword-0.81-mysql-0.6.6.patch.gz}
+MySQL-Authentifizierungs-Patch für QMAIL und checkpassword. Diese sind
+nützlich für die Benutzerverwaltung (mail, pop account) von MySQL.
+Von @email{takeshi@@SoftAgency.co.jp}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/jradius-diff.gz, jradius-diff.gz}
+MySQL-Unterstützung für Livingston's Radius 2.01. Authentifizierung und
+Abrechnung. Von Jose de Leon, @email{jdl@@thevision.net}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mod_auth_mysql-2.20.tar.gz, mod_auth_mysql-2.20.tar.gz}
+Apache-Authentifizierungsmodul für MySQL. Von Zeev Suraski,
+@email{bourbon@@netvision.net.il}.
+
+@c @strong{Bitte} registrieren Sie dieses Modul unter:
+@c @url{http://bourbon.netvision.net.il/mysql/mod_auth_mysql/register.html}.
+@c Die Registrierungsinformationen werden nur für statistische Zwecke
+@c benutzt und fördern die Weiterentwicklung dieses Moduls!
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mod_log_mysql-1.05.tar.gz, mod_log_mysql-1.05.tar.gz}
+MySQL-Loggingmodul für Apache. Von Zeev Suraski,
+@email{bourbon@@netvision.net.il}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mypasswd-2.0.tar.gz, mypasswd-2.0.tar.gz}
+Zusatz für @code{mod_auth_mysql}. Das kleine Werzeug ermöglicht Ihnen,
+Benutzerdatensätze hinzuzufügen oder zu ändern, wobei Gruppen- und / oder
+Passwort-Einträge in MySQL-Tabellen gespeichert werden. Von Harry
+Brueckner, @email{brueckner@@respublica.de}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd.README, mysql-passwd.README}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd-1.2.tar.gz, mysql-passwd-1.2.tar.gz}
+Zusatz für @code{mod_auth_mysql}. Ein System aus zwei Bestandteilen zur
+Benutzung mit @code{mod_auth_mysql}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/pam_mysql.tar.gz, pam_mysql.tar.gz}
+Dieses Modul authentifiziert Benutzer via @code{pam}, mit MySQL.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/nsapi_auth_mysql.tar, nsapi_auth_mysql.tar}
+Netscape-Webserver-API- (NSAPI) Funktionen, um (BASIC) Benutzer gegen
+MySQL-Tabellen zu authentifizieren. Von Yuan John Jiang.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/qmail-1.03-mysql-0.6.6.patch.gz,qmail-1.03-mysql-0.6.6.patch.gz}
+Patch für qmail, um Benutzer einer MySQL-Tabelle zu authentifizieren.
+Von @email{takeshi@@SoftAgency.co.jp}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/proftpd-1.2.0rc2-fix-mysql.patch, proftpd-1.2.0rc2-fix-mysql.patch}
+Patch für proftpd1.2.0rc2. Von @email{takeshi@@SoftAgency.co.jp}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/pwcheck_mysql-0.1.tar.gz,pwcheck_mysql-0.1.tar.gz}
+Ein Authentifizierungsmodul für den Cyrus-IMAP-Server. Von Aaron Newsome.
+
+
+@end itemize
+
+@cindex Konverter
+@appendixsec Konverter
+
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/mssql2mysql.txt, mssql2mysql.txt}
+Konverter von MS-SQL zu MySQL. Von Michael Kofler.
+@uref{http://www.kofler.cc/mysql/mssql2mysql.html, mssql2mysql Homepage}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.14.tar.gz, dbf2mysql-1.14.tar.gz}
+Konvertiert zwischen @file{.dbf}-Dateien und MySQL-Tabellen. Von Maarten
+Boekhold (@email{boekhold@@cindy.et.tudelft.nl}), William Volkman und
+Michael Widenius. Dieser Konverter schließt rudimentäre Unterstützung (nur
+lesen) für MEMO-Felder ein.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.13.tgz, dbf2mysql-1.13.tgz}
+Konvertiert zwischen @file{.dbf}-Dateien und MySQL-Tabellen. Von Maarten
+Boekhold, @email{boekhold@@cindy.et.tudelft.nl} und Michael Widenius.
+Dieser Konverter kann keine MEMO-Felder handhaben.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql.zip, dbf2mysql.zip}
+Konvertiert zwischen FoxPro-@file{.dbf}-Dateien und MySQL-Tabellen unter Windows.
+Von Alexunder Eltsyn, @email{ae@@nica.ru} oder @email{ae@@usa.net}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2sql.zip, dbf2sql.zip}
+Kurzes, einfaches Programm, dass Ihnen bei der Überführung Ihrer Daten von
+Foxpro-Tabellen in MySQL-Tabellen helfen kann. Von Danko Josic.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/dump2h-1.20.gz, dump2h-1.20.gz}
+Konvertiert von einer @code{mysqldump}-Ausgabe in eine C-Header-Datei. Von
+Harry Brueckner, @email{brueckner@@mail.respublica.de}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/exportsql.txt, exportsql.txt}
+Ein Skript, das @code{access_to_mysql.txt} ähnelt, ausser dass dieses voll
+konfigurierbar ist, eine bessere Typumwandlung hat (inklusive Erkennung von
+@code{TIMESTAMP}-Feldern), bei der Konvertierung Warnungen und Vorschläge
+bereit stellt, Anführungszeichen, @strong{alle} Sonderzeichen in Text und
+Binärdaten erkennt usw. Es konvertiert ausserdem nach @code{mSQL} Version 1
+und 2, und kostet nichts. Siehe @uref{http://www.cynergi.net/exportsql/}
+wegen der neuesten Version. Von Pedro Freire, @email{Support@@cynergi.net}.
+@strong{HINWEIS:} Funktioniert nicht mit Access 2!
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/access_to_mysql.txt, access_to_mysql.txt}
+Kopieren Sie diese Funktion in ein Access-Modul einer Datenbank, die die
+Tabellen enthält, die Sie exportieren wollen. Siehe auch @code{exportsql}.
+Von Brian Andrews. @strong{HINWEIS:} Funktioniert nicht mit Access 2!
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/importsql.txt, importsql.txt}
+Ein Skript, das genau das Gegenteil von @code{exportsql.txt} macht. Es
+importiert Daten von MySQL in eine Access-Datenbank via ODBC. Das ist sehr
+handlich, wenn es mit exportsql kombiniert wird, weil Sie damit Access für
+das Datenbank-Design und die -Administration verwenden können und das
+Getane dann mit Ihrem MySQL-Server synchronisieren können. Siehe
+@uref{http://www.netdive.com/freebies/importsql/} wegen Aktualisierungen.
+Geschrieben von Laurent Bossavit von NetDIVE.
+@strong{HINWEIS:} Funktioniert nicht mit Access 2!
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mdatabase2sql.bas,
+mdatabase2sql.bas}
+Konverter von Access97 nach MySQL von Moshe Gurvich.
+
+@item
+@uref{http://www.mysql.com/Downloads/Contrib/msql2mysqlWrapper-1.0.tgz,
+msql2mysqlWrapper 1.0}
+Ein C-Wrapper von @code{mSQL} nach MySQL. Von @email{alfred@@sb.net}
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/sqlconv.pl, sqlconv.pl}
+Ein einfaches Skript, das zum Kopieren von Feldern von einer MySQL-Tabelle
+in eine andere im Massenverfahren benutzt werden kann. Im Wesentlichen
+können Sie @code{mysqldump} laufen lassen und die Ausgabe an das
+@code{sqlconv.pl}-Skript übergeben. Das Skript parst die
+@code{mysqldump}-Ausgabe und ordnet die Felder neu, so dass sie in die neue
+Tabelle eingefügt werden können. Ein Beispiel hierfür ist, dass Sie eine
+neue Tabelle für eine andere Site, an der Sie arbeiten, erstellen wollen,
+die Tabelle jedoch ein bisschen anders ist (also die Felder in anderer
+Reihenfolge hat usw.). Von Steve Shreeve.
+@item @uref{http://www.mysql.com/Downloads/Contrib/oracledump oderacledump}
+Perl-Programm, um Oracle-Datenbanken nach MySQL zu konvertieren. Hat
+dasselbe Ausgabeformat wie mysqldump. Von Johan Andersson.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/excel2mysql.pl, excel2mysql.pl}
+Perl-Programm, um Excel-Tabellen in eine MySQL-Datenbank zu importieren.
+Von Stephen Hurd @email{shurd@@sk.sympatico.ca}
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/T2S_100.ZIP, T2S_100.ZIP}.
+Windows-Programm zum Konvertieren von Textdateien in MySQL-Datenbanken. Von
+Asaf Azulay.
+
+@end itemize
+
+@appendixsec MySQL mit anderen Produkten benutzen
+
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/emacs-sql-mode.tar.gz, emacs-sql-mode.tar.gz}
+Raw-Portierung eines SQL-Modus für XEmacs. Unterstützt Vervollständigung.
+Original von Peter D. Pezaris @email{pez@@atlantic2.sbi.com} und teilweise
+MySQL-Portierung von David Axmark.
+
+@item @uref{http://www.mysql.com/downloads/Win32/myaccess97_1_4.zip, MyAccess97 1.4}.
+@item @uref{http://www.mysql.com/downloads/Win32/myaccess2000_1_4.zip, MyAccess2000 1.4}.
+
+MyAccess ist ein Add-In für MS-Access 97/2000, mit dem MySQL-Datenbanken
+innerhalb von Access verwaltet werden können. Hauptfunktionen sind:
+@itemize @minus
+@item Erzeugen und Ändern von Tabellen
+@item Anfragen an MySQL ausführen
+@item ''Erzeugen von Tabellen-Skripten'' von MySQL
+@item Importieren / Exportieren von Tabellen aus Access nach MySQL und umgekehrt
+@item Änderungen mitschreiben (Log)
+@item Einen Datenbank-Definitionsbericht anzeigen
+@end itemize
+
+Geschrieben von Hubertus Hiden. @uref{http://www.accessmysql.com, MyAccess-Homepage}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/radius-0.3.tar.gz, radius-0.3.tar.gz}
+Patches für @code{radiusd}, damit es MySQL unterstützt. Von Wim Bonis,
+@email{bonis@@kiss.de}.
+@end itemize
+
+@cindex Werkzeuge, nützliche
+@appendixsec Nützliche Werkzeuge
+
+@itemize @bullet
+@item @uref{http://worldcommunity.com/opensource/utilities/mysql_backup.html, MySQL-Datensicherung}.
+
+Ein Datensicherungsskript für MySQL. Von Peter F. Brown.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mytop, mytop}
+@item @uref{http://public.yahoo.com/~jzawodn/mytop/, mytop Homepage}
+mytop ist ein Perl-Programm, mit dem Sie MySQL-Server beobachten können,
+indem Sie aktive Threads, Anfragen und Server-Performance über alles
+betrachten. Von Jeremy D. Zawodny.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_watchdog.pl, mysql_watchdog.pl}
+Den MySQL-Daemon auf mögliche Blockierungen überwachen. Von Yermo Lamers,
+@email{yml@@yml.com}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltop.tar.gz, mysqltop.tar.gz}
+Sendet eine Anfrage in einem festen Zeitintervall an den Server und zeigt
+die Ergebnistabelle. Von Thomas Wana.
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tar.gz,mysql_structure_dumper.tar.gz}
+Gibt die Struktur aller Tabellen in einer Datenbank aus. Von Thomas Wana.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tgz, structure_dumper.tgz}
+Gibt die Struktur aller Tabellen in einer Datenbank aus. Von Thomas Wana.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlsync, mysqlsync-1.0-alpha.tar.gz}.
+Ein Perl-Skript, um entfernte Kopien einer MySQL-Datenbank mit einer
+zentralen Master-Kopie synchronisiert zu halten. Von Mark Jeftovic. @email{markjr@@easydns.com}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLTutor-0.2.tar.gz, MySQLTutor}.
+MySQLTutor. Ein MySQL-Tutorial für Anfänger.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB.zip, MySQLDB.zip}
+Eine COM-Bibliothek für MySQL von Alok Singh.
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB-readme.html, MySQLDB-readme.html}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_replicate.pl, mysql_replicate.pl}
+Perl-Programm, das Replikation handhabt. Von @email{elble@@icculus.nsg.nwu.edu}
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz, DBIx-TextIndex-0.02.tar.gz}
+Perl-Skript, das umgekehrte Indexierung für Textsuchen benutzt. Von Daniel
+Koch.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbcheck, dbcheck}
+Perl-Skript, das eine Datensicherung der Tabellen macht, bevor isamchk
+darauf laufen gelassen wird. Von Elizabeth.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mybackup}.
+@item @uref{http://www.mswanson.com/mybackup, mybackup-Homepage}
+Wrapper für mysqldump, um alle Datenbanken zu sichern. Von Marc Swanson.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mdu.pl.gz,mdu.pl.gz}
+Gibt die Speicherbenutzung einer MySQL-Datenbank aus.
+@end itemize
+
+@cindex RPMs, für gebräuchliche Werkzeuge
+@cindex Werkzeuge, RPMs für
+@appendixsec RPMs für gebräuchliche Werkzeuge (die meisten sind für RedHat 6.1)
+
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Data-ShowTable-3.3-2.i386.rpm,perl-Data-ShowTable-3.3-2.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Msql-Mysql-modules-1.2210-2.i386.rpm,perl-Msql-Mysql-modules-1.2210-2.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-3.0.13-1.i386.rpm,php-pg-3.0.13-1.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-manual-3.0.13-1.i386.rpm,php-pg-manual-3.0.13-1.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-mysql-3.0.13-1.i386.rpm,php-pg-mysql-3.0.13-1.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin-2.0.5-1.noarch.rpm,phpMyAdmin-2.0.5-1.noarch.rpm}
+@end itemize
+
+@cindex Funktionen, nützliche
+@appendixsec Nützliche Funktionen
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysnprintf.c,mysnprintf.c}
+sprintf()-Funktion für SQL-Anfragen, die Blobs escapen kann. Von Chunhua Liu.
+@end itemize
+
+@appendixsec Windows-Programme
+@itemize @bullet
+@item @uref{http://www.mysql.com/Downloads/Contrib/LaunchMySQL.zip, LaunchMySQL.zip}
+Das Programm startet den MySQL-Server, fährt ihn herunter und gibt
+Status-Informationen aus. Von Bill Thompson
+@end itemize
+
+@appendixsec Nicht kategorisiert
+
+@itemize @bullet
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/findres.pl, findres.pl}
+Findet reservierte Wörter in Tabellen. Von Nem W Schlecht.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/handicap.tar.gz, handicap.tar.gz}
+Performance-Handicapping-System für Yachten. Benutzt PHP. Von
+@email{rhill@@stobyn.ml.org}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/hylalog-1.0.tar.gz, hylalog-1.0.tar.gz}
+Speichert ausgehende @code{hylafax}-Faxe in einer MySQL-Datenbank. Von
+Sinisa Milivojevic, @email{sinisa@@mysql.com}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mrtg-mysql-1.0.tar.gz, mrtg-mysql-1.0.tar.gz}
+MySQL-Status-Ausgabe mit MRTG, von Luuk de Boer, @email{luuk@@wxs.nl}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/wuftpd-2.4.2.18-mysql_Support.2.tar.gz, wuftpd-2.4.2.18-mysql_Support.2.tar.gz}
+Patches, um Loggen nach MySQL für WU-ftpd hinzuzufügen. Von Zeev Suraski,
+@email{bourbon@@netvision.net.il}.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/wu-ftpd-2.6.0-mysql.4.tar.gz,wu-ftpd-2.6.0-mysql.4.tar.gz}
+Patches, um Loggen nach MySQL für WU-ftpd 2.6.0 hinzuzufügen. Von
+@email{takeshi@@SoftAgency.co.jp}, basierend auf den
+Zeev-Suraski-wuftpd-Patches.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/Old-Versions, Alte Versionen}
+Frühere Versionen von Dingen in diesen Listen, an denen Sie wahrscheinlich
+nicht interessiert sind.
+@end itemize
+@page
+
+
+
+
+@node Credits, News, Contrib, Top
+@c German node Danksagungen
+@appendix Danksagungen
+
+@cindex Entwickler, Auflistung
+
+Dieser Anhang listet die Entwickler, Kontributoren und Unterstützer auf,
+die mitgeholfen haben, dass MySQL das wird, was es heute ist.
+
+
+
+@menu
+* Developers::
+* Contributors::
+* Supporters::
+@end menu
+
+@node Developers, Contributors, Credits, Credits
+@c German node Entwickler
+@appendixsec Entwickler bei MySQL AB
+
+Hier sind die Entwickler, die von @code{MySQL AB} angestellt wurden, um an
+@code{MySQL} zu arbeiten, ungefähr in der Reihenfolge ihres Eintritts.
+Neben dem Namen wird aufgelistet, für welche Teilaufgaben der Entwickler
+verantwortlich ist oder welche Leistungen er erbracht hat.
+
+@table @asis
+@item Michael (Monty) Widenius
+Schrieb folgende Bestandteile von MySQL:
+@itemize @bullet
+@item
+Den gesamten Haupt-Code in @code{mysqld}.
+@item
+Neue Funktionen für die Zeichenketten-Bibliothek.
+@item
+Das meiste der @code{mysys}-Bibliothek.
+@item
+Die @code{ISAM}- und @code{MyISAM}-Bibliotheken (B-Baum-Index-Datei-Handler
+mit Index-Komprimierung und verschiedenen Datensatzformaten).
+@item
+Die @code{HEAP}-Bibliothek. Ein Speicher-Tabellensystem mit unserem
+überragenden komplett dynamischen Hashing. In Gebrauch seit 1981 und
+veröffentlicht um 1984.
+@item
+Das @code{replace}-Programm (ansehen, es ist COOL!).
+@item
+@strong{MyODBC}, den ODBC-Treiber für Windows95.
+@item
+Behob Bugs in MIT-pThread, um sie für MySQL zum Laufen zu bringen, sowie
+Unireg, ein curses-basierendes Applikationswerkzeug vielen Utilities.
+@item
+Portierung von @code{mSQL}-Werkzeugen wie @code{msqlperl},
+@code{DBD}/@code{DBI} und @code{db2mysql}.
+@item
+Das meiste von Crash-me und die Grundlage für die MySQL-Benchmarks.
+@end itemize
+
+@item David Axmark
+@itemize @bullet
+@item
+Koordinator und ursprünglicher Haupt-Schreiber des
+@strong{Referenzhandbuchs}, inklusive Verbesserungen von @code{texi2HTML}.
+@item
+Automatische Website-Aktualisierung des Handbuchs.
+@item
+Ursprüngliche Autoconf-, Automake- und Libtool-Unterstützung.
+@item
+Den Lizensierungs-Kram.
+@item
+Teile all der Textdateien. (Heutzutage ist nur noch die @file{README}
+übrig. Der Rest befindet sich im Handbuch.)
+@item
+Viel Testen neuer Features.
+@item
+Unser ``kostenloser'' Inhouse-Software-Anwalt.
+@item
+Derjenige, der die Mailing-Liste wartet (und nie die Zeit hatte, es richtig
+zu machen ...)
+@item
+Unser Original-Portabilitätscode (jetzt mehr als 10 Jahre alt). Heutzutage
+sind nur noch Teile von @code{mysys} übrig.
+@item
+Jemand, den Monty mitten in der Nacht anrufen kann, wenn er gerade das neue
+Feature zum Laufen gebracht hat.
+@end itemize
+
+@item Jani Tolonen
+@itemize @bullet
+@item
+@code{mysqlimport}
+@item
+Etliche Erweiterungen zum @code{mysql}-Client.
+@item
+@code{Prozeduranalyse()}
+@end itemize
+
+@item Sinisa Milivojevic
+@itemize @bullet
+@item
+Kompression (mit @code{zlib}) im Client-Server-Protokoll.
+@item
+Perfektes Hashing für die lexikalische Analyse-Phase.
+@item
+Den MySQLGUI-Client.
+@item
+Derjenige, der mysql++ wartet.
+@end itemize
+
+@item Tonu Samuel
+@itemize @bullet
+@item
+Unser Sicherheitsexperte.
+@item
+Vio-Schnittstelle (die Grundlage für das verschlüsselte Client-Server-Protokoll).
+@item
+MySQL-Dateisystem (eine Art, MySQL-Datenbanken als Dateien und
+Verzeichnisse zu benutzen).
+@item
+Den CASE-Ausdruck.
+@item
+Die MD5()- und COALESCE()-Funktionen.
+@item
+@code{RAID}-Unterstützung für @code{MyISAM}-Tabellen.
+@end itemize
+
+@item Sasha Pachev
+@itemize @bullet
+@item
+Replikation.
+@item
+@code{SHOW CREATE TABLE}.
+@item
+mod_mysql_include
+@item
+cgi++
+@item
+mysql-bench
+@end itemize
+
+@item Matt Wagner
+@itemize @bullet
+@item
+MySQL-Test-Suite.
+@item
+Unser Webmaster.
+@end itemize
+
+@item Miguel Solorzano
+@itemize @bullet
+@item
+Winmysqladmin.
+@end itemize
+
+@item Timothy Smith
+@itemize @bullet
+@item
+Dynamische Zeichen-Unterstützung.
+@item
+Verantwortlich für MySQL-configure.
+@end itemize
+
+@item Sergei Golubchik
+@itemize @bullet
+@item
+Volltextsuche.
+@item
+Fügte Schlüssel zur @code{MERGE}-Bibliothek hinzu.
+@end itemize
+
+@item Jeremy Cole
+@itemize @bullet
+@item
+
+Korrekturlesen und Editieren dieses netten Handbuchs.
+@item
+@code{ALTER TABLE ... ORDER BY ...}.
+@item
+@code{UPDATE ... ORDER BY ...}.
+@item
+@code{DELETE ... ORDER BY ...}.
+@end itemize
+
+@item John Dean
+@itemize @bullet
+@item
+Den MySQL-GUI-Client.
+@end itemize
+
+@item Indrek Siitan
+@itemize @bullet
+@item
+Designer / Programmierer unserer Web-Schnittstelle.
+@end itemize
+@end table
+
+Folgende Nicht-Entwickler arbeiten ebenfalls bei oder zusammen mit MySQL
+AB:
+
+@table @asis
+@item
+Hans Kierkegaard - verantwortlich für die MySQL-Lizenz-Handhabung.
+@item
+Antti Halonen - Vertriebsleiter.
+@item
+Jonas Norrman - Beantwortet Lizensierungsfrage, die an
+@email{info@@mysql.com} geschickt werden.
+@item
+Erik Granberg - bedient MySQL-Partner (und eine Menge sonstiger Kram).
+@item
+Allan Larsson (der BOSS für TCX DataKonsult AB).
+@end table
+
+
+@node Contributors, Supporters, Developers, Credits
+@c German node Kontributoren
+@appendixsec Kontributoren zu MySQL
+
+@cindex Kontributoren, Auflistung
+
+Während @code{MySQL AB} das gesammte Copyright für den @code{MySQL Server}
+und das @code{MySQL manual} besitzt, möchten wir hier diejenigen Menschen
+nennen, die das Ein oder Andere zur @code{MySQL Distribution} beigetragen
+haben. Die Kontributoren sind in eher zufälliger Reihenfolge aufgeführt:
+
+@table @asis
+@item Paul DuBois
+Hilft mit, das Referenzhandbuch korrekt und verständlich zu machen. Das
+beinhaltet, Montys und Davids Englischversuche in das Englisch zu
+übertragen, das andere Leute kennen.
+@item Gianmassimo Vigazzola @email{qwerg@@mbox.vol.it} oder @email{qwerg@@tin.it}
+Die ursprüngliche Portierung auf Win32/NT.
+@item Kim Aldale
+Half, Montys und Davids frühe Englischversuche ins Englische umzuschreiben.
+@item Per Eric Olsson
+Mehr oder weniger konstruktive Kritik und Testen des dynamischen
+Datensatzformats.
+@item Irena Pancirov @email{irena@@mail.yacc.it}
+Win32-Portierung mit dem Borland-Compiler. @code{mysqlshutdown.exe} und
+@code{mysqlwatch.exe}
+@item David J. Hughes
+Er bemühte sich, eine Shareware-SQL-Datenbank herzustellen. Wir bei TcX
+fingen mit @code{mSQL} an, fanden aber, dass es unsere Bedürfnisse nicht
+befriedigen könne, daher schrieben wir stattdessen eine SQL-Schnittstelle
+zu unserem Applikation-Builder Unireg. @code{mysqladmin} und @code{mysql}
+sind Programme, die stark von ihren @code{mSQL}-Pendants beeinflusst sind.
+Wir haben uns große Mühe gegeben, die MySQL-Syntax zu einer Obermenge von
+@code{mSQL} zu machen. Viele API-Ideen sind von @code{mSQL} entliehen,
+damit es einfach ist, kostenlose @code{mSQL}-Programme nach MySQL zu
+portieren. MySQL enthält keinen Code von @code{mSQL}. Zwei Dateien in der
+Distribution (@file{client/insert_test.c} und @file{client/select_test.c})
+basieren auf den entsprechenden (keinem Copyright unterliegenden) Dateien
+in der @code{mSQL}-Distribution, sind aber als Beispiele abgeändert, die
+die notwendigen Änderungen aufzeigen, wenn man Code von @code{mSQL} nach
+MySQL konvertiert. (@code{mSQL} unterliegt dem Copyright von David J. Hughes.)
+@item Fred Fish
+Seine exzellente C-Debugging- und Trace-Bibliothek. Monty hat eine Reihe
+kleinerer Verbesserungen an der Bibliothek vorgenommen (Geschwindigkeit und
+zusätzliche Optionen).
+@item Richard A. O'Keefe
+Seine Public-Domain-Zeichenketten-Bibliothek.
+@item Henry Spencer
+Seine Regex-Bibliothek, benutzt bei @code{WHERE spalte REGEXP regexp}.
+@item Free Software Foundation
+Von ihnen haben wir einen exzellenten Compiler (@code{gcc}), die
+@code{libc}-Bibliothek (aus der wir @file{strto.c} entliehen haben, damit
+einiger Code unter Linux funktioniert), und die @code{readline}-Bibliothek
+(für den @code{mysql}-Client).
+@item Free Software Foundation und das XEmacs-Entwicklungsteam
+Ihr großartiger Editor, der für fast jeden Artikeltext bei TcX/MySQL
+AB/detron benutzt wird.
+@item Patrick Lynch
+Für seine Hilfe bei @code{http://www.mysql.com/}.
+@item Fred Lindberg
+Er half, qmail aufzusetzen, um die MySQL Mailing-Liste zu handhaben, und
+für seine unglaubliche Unterstützung bei der Verwaltung der MySQL
+Mailing-Listen.
+@item Igor Romanenko @email{igor@@frog.kiev.ua}
+@code{mysqldump} (vormals @code{msqldump}, aber portiert und verbessert von
+Monty).
+@item Yuri Dario
+Er unterhält die MySQL-OS/2-Portierung und baut sie aus.
+@item Tim Bunce, Alligator Descartes
+Für die @code{DBD}-(Perl)-Schnittstelle.
+@item Tim Bunce
+Autor von @code{mysqlhotcopy}.
+@item Andreas Koenig @email{a.koenig@@mind.de}
+Für die Perl-Schnittstelle zu MySQL.
+@item Eugene Chan @email{eugene@@acenet.com.sg}
+Für den Port von PHP zu MySQL.
+@item Michael J. Miller Jr. @email{mke@@terrapin.turbolift.com}
+Er schrieb das erste MySQL-Handbuch, und nahm etliche Bereinigungen der
+Rechtschreibung / Sprache für die FAQ vor (aus dieser entstand vor langer
+Zeit das MySQL-Handbuch).
+@item Yan Cailin
+Erster Übersetzer des MySQL-Referenzhandbuch in vereinfachtes Chinesisch,
+Anfang 2000, auf der die Big5- und HK-kodierten Versionen
+(@uref{http://mysql.hitstar.com, mysql.hitstar.com}) basieren.
+@uref{http://linuxdb.yeah.net, Private Homepage bei linuxdb.yeah.net}.
+@item Giovanni Maruzzelli @email{maruzz@@matrice.it}
+Für die Portierung von iODBC (Unix ODBC).
+@item Chris Provenzano
+Portierbarer Benutzerebene-pThread. Aus dem Copyright: Dieses Produkt
+beinhaltet Software, die von Chris Provenzano, University of California,
+Berkeley und Kontributoren entwickelt wurde. Momentan benutzen wir Version
+1_60_beta6, die von Monty gepatcht wurde (siehe @file{with-pThread/Changes-mysql}).
+@item Xavier Leroy @email{Xavier.Leroy@@inria.fr}
+Der Autor von LinuxThread (benutzt von MySQL unter Linux).
+@item Zarko Mocnik @email{zarko.mocnik@@dem.si}
+Sortieren für slowenische Sprache und die @file{cset.tar.gz}-Module, die es
+vereinfachen, andere Zeichensätze hinzuzufügen.
+@item "TAMITO" @email{tommy@@valley.ne.jp}
+Die @code{_MB}-Zeichensatz-Makros und die ujis- und sjis-Zeichensätze.
+@item Joshua Chamas @email{joshua@@chamas.com}
+Grundlage für gleichzeitige Einfügeoperationen, erweiterte Datums-Syntax,
+Debuggen unter NT und Antworten in der MySQL-Mailing-Liste.
+@item Yves Carlier @email{Yves.Carlier@@rug.ac.be}
+@code{mysqlaccess}, ein Programm, das die Zugriffsrechte für einen Benutzer
+anzeigt.
+@item Rhys Stefan @email{rhys@@wales.com} (und GWE Technologies Limited)
+Für JDBC, ein Modul, um Daten aus MySQL mit einem Java-Client zu
+extrahieren.
+@item Dr. Xiaokun Kelvin ZHU @email{X.Zhu@@brad.ac.uk}
+Weiterentwicklung der JDBC-Treiber und anderer MySQL-bezogener
+Java-Werkzeuge.
+@item James Cooper @email{pixel@@organic.com}
+Aufsetzen eines durchsuchbaren Mailing-Listen-Archivs auf seiner Site.
+@item Rick Mehalick @email{Rick_Mehalick@@i-o.com}
+Für @code{xmysql}, einen grafischen X-Client für MySQL.
+@item Doug Sisk @email{sisk@@wix.com}
+Er stellt RPM-Pakete von MySQL für RedHat Linux bereit.
+@item Diemund Alexunder V. @email{axeld@@vial.ethz.ch}
+Er stelle RPM-Pakete von MySQL für RedHat Linux-Alpha bereit.
+@item Antoni Pamies Olive @email{toni@@readysoft.es}
+Er stellt RPM-Versionen vieler MySQL-Clients für Intel und SPARC bereit.
+@item Jay Bloodworth @email{jay@@pathways.sde.state.sc.us}
+Er stellte RPM-Versionen für MySQL-Version 3.21 bereit.
+@item Jochen Wiedmann @email{wiedmann@@neckar-alb.de}
+Für die Wartung der Perl-@code{DBD::mysql}-Module.
+@item Therrien Gilbert @email{gilbert@@ican.net}, Jean-Marc Pouyot @email{jmp@@scalaire.fr}
+Französische Fehlermeldungen.
+@item Petr snajdr, @email{snajdr@@pvt.net}
+Tschechische Fehlermeldungen.
+@item Jaroslaw Lewundowski @email{jotel@@itnet.com.pl}
+Polnische Fehlermeldungen.
+@item Miguel Angel Fernundez Roiz
+Spanische Fehlermeldungen.
+@item Roy-Magne Mo @email{rmo@@www.hivolda.no}
+Norwegische Fehlermeldungen und Testen von Version 3.21.#.
+@item Timur I. Bakeyev @email{root@@timur.tatarstan.ru}
+Russische Fehlermeldungen.
+@item @email{brenno@@dewinter.com} && Filippo Grassilli @email{phil@@hyppo.com}
+Italienische Fehlermeldungen.
+@item Dirk Munzinger @email{dirk@@trinity.saar.de}
+Deutsche Fehlermeldungen.
+@item Billik Stefan @email{billik@@sun.uniag.sk}
+Slowakische Fehlermeldungen.
+@item Stefan Saroiu @email{tzoompy@@cs.washington.edu}
+Rumänische Fehlermeldungen.
+@item Peter Feher
+Ungarische Fehlermeldungen.
+@item Roberto M. Serqueira
+Portugiesische Fehlermeldungen.
+@item Carsten H. Pedersen
+Dänische Fehlermeldungen
+@item David Sacerdote @email{davids@@secnet.com}
+Knowhow für die Sicherheitsprüfung von DNS-Hostnamen.
+@item Wei-Jou Chen @email{jou@@nematic.ieo.nctu.edu.tw}
+Unterstützung für chinesisch(BIG5)-Zeichen.
+@item Wei He @email{hewei@@mail.ied.ac.cn}
+Viel Funktionalität für den chinesischen (GBK-) Zeichensatz.
+@item Zeev Suraski @email{bourbon@@netvision.net.il}
+@code{FROM_UNIXTIME()}-Zeitformatierung, @code{ENCRYPT()}-Funktionen und
+@code{bison}-Ratgeber.
+Aktives Mitglied der Mailing-Liste.
+@item Luuk de Boer @email{luuk@@wxs.nl}
+Portierte (und erweiterte) die Benchmark-Suite für @code{DBI}/@code{DBD}.
+War eine große Hilfe bei @code{Crash-me} und beim Laufenlassen von
+Benchmarks. Einige neue Datumsfunktionen. Das mysql_setpermissions-Skript.
+@item Jay Flaherty @email{fty@@mediapulse.com}
+Große Teile des Perl-@code{DBI}/@code{DBD}-Abschnitts im Handbuch.
+@item Paul Southworth @email{pauls@@etext.org}, Ray Loyzaga @email{yar@@cs.su.oz.au}
+Korrekturlesen des Referenzhandbuchs.
+@item Alexis Mikhailov @email{root@@medinf.chuvashia.su}
+Benutzerdefinierte Funktionen (UDFs); @code{CREATE FUNCTION} und
+@code{DROP FUNCTION}.
+@item Andreas F. Bobak @email{bobak@@relog.ch}
+Die @code{AGGREGATE}-Erweiterung für UDF-Funktionen.
+@item Ross Wakelin @email{R.Wakelin@@march.co.uk}
+Half, InstallShield für MySQL-Win32 aufzusetzen.
+@item Jethro Wright III @email{jetman@@li.net}
+Die @file{libmysql.dll}-Bibliothek.
+@item James Pereria @email{jpereira@@iafrica.com}
+Mysqlmanager, ein grafisches Win32-Werkzeug für die Administration von MySQL.
+@item Curt Sampson @email{cjs@@portal.ca}
+Portierung von MIT-pThread auf NetBSD/Alpha und NetBSD 1.3/i386.
+@item Antony T. Curtis @email{antony.curtis@@olcs.net}
+Portiierung von MySQL auf OS/2.
+@item Martin Ramsch @email{m.ramsch@@computer.org}
+Beispiele im MySQL-Tutorial.
+@item Steve Harvey
+Er machte @code{mysqlaccess} sicherer.
+@item Konark IA-64 Centre of Persistent Systems Private Limited
+@uref{http://www.pspl.co.in/konark/}. Hilfe bei der Win64-Portierung des
+MySQL-Servers.
+@item Albert Chin-A-Young.
+Configure-Aktualisierungen für Tru64, Unterstützung großer Dateien und
+verbesserte Unterstützung von TCP-Wrappern.
+@item John Birrell
+Emulation von pthread_mutex() für OS/2.
+@item Benjamin Pflugmann
+Erweiterte @code{MERGE}-Tabellen, so dass sie @code{INSERTS} handhaben.
+Aktives Mitglied der MySQL-Mailing-Listen.
+@end table
+
+Andere Kontributoren, Bug-Finder und Tester: James H. Thompson, Maurizio
+Menghini, Wojciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar
+Haneke, @email{jehamby@@lightside}, @email{psmith@@BayNetworks.com},
+@email{duane@@connect.com.au}, Ted Deppner @email{ted@@psyber.com},
+Mike Simons, Jaakko Hyvatti.
+
+Und viele Bug-Berichte und Patches von den Leuten auf der Mailing-Liste.
+
+Große Anerkennung zollen wir denjenigen, die uns halfen, Fragen auf der
+@code{mysql@@lists.mysql.com}-Mailing-Liste zu beantworten:
+
+@table @asis
+@item Daniel Koch @email{dkoch@@amcity.com}
+Irix-Setup.
+@item Luuk de Boer @email{luuk@@wxs.nl}
+Benchmark-Fragen.
+@item Tim Sailer @email{tps@@Benutzer.buoy.com}
+@code{DBD-mysql}-Fragen.
+@item Boyd Lynn Gerber @email{gerberb@@zenez.com}
+SCO-bezogene Fragen.
+@item Richard Mehalick @email{RM186061@@shellus.com}
+@code{xmysql}-bezogene Fragen und grundsätzliche Installationsfragen.
+@item Zeev Suraski @email{bourbon@@netvision.net.il}
+Fragen zur Apache-Modul-Konfiguration (log & auth), PHP-bezogene Fragen,
+SQL-Syntax-bezogene Fragen und andere allgemeine Fragen.
+@item France Guasch @email{frankie@@citel.upc.es}
+Allgemeine Fragen.
+@item Jonathan J Smith @email{jsmith@@wtp.net}
+Fragen zu Betriebssystem-spezifschen Dingen bei Linux, SQL-Syntax- und
+andere Dinge, die etwas Überarbeitung bedürfen.
+@item David Sklar @email{sklar@@student.net}
+MySQL von PHP und Perl aus benutzen.
+@item Alistair MacDonald @email{A.MacDonald@@uel.ac.uk}
+Noch nicht festgelegt, aber er ist flexibel und kann Linux und vielleicht
+HP-UX handhaben. Wird versuchen, Benutzer dazu zu bringen, @code{mysqlbug}
+zu benutzen.
+@item John Lyon @email{jlyon@@imag.net}
+Fragen zur Installation von MySQL auf Linux-Systemen, entweder mit
+@file{.rpm}-Dateien oder durch Kompilieren vom Quelltext.
+@item Lorvid Ltd. @email{lorvid@@WOLFENET.com}
+Einfache Fragen zu Rechnung / Lizenz / Support / Copyright.
+@item Patrick Sherrill @email{patrick@@coconet.com}
+Fragen zur ODBC- und VisualC++-Schnittstelle.
+@item Rundy Harmon @email{rjharmon@@uptimecomputers.com}
+@code{DBD}, Linux, und einige SQL-Syntax-Fragen.
+@end table
+
+
+@node Supporters, , Contributors, Credits
+@c German node Unterstützer
+@appendixsec Unterstützer von MySQL
+
+@cindex Unterstützende Unternehmen, Auflistung
+
+Während @code{MySQL AB} das gesammte Copyright für den @code{MySQL Server}
+und das @code{MySQL manual} besitzt, möchten wir hier diejenigen Unternehmen
+nennen, die die Entwicklung des @code{MySQL Servers} unterstützt haben.
+Sie haben geholfen, indem sie uns für die Entwicklung eines neuen
+Features bezahlten, indem sie MySQL-Features selbst entwickelten oder indem
+sie uns Hardware für die MySQL-Entwicklung gaben.
+
+@table @asis
+@item VA Linux / Andover.net
+Stiftete Replikation.
+@item NuSphere
+Editieren des MySQL-Referenzhandbuchs.
+@item Stork Design studio
+Die MySQL-Website zwischen 1998 und 2000.
+@item Intel
+Trugen zur Entwicklung auf Windows- und Linux-Plattformen bei.
+@item Compaq
+Trugen zur Entwicklung auf Linux/Alpha bei.
+@item SWSoft
+Entwicklung der eingebetteten @code{mysqld}-Version.
+@item FutureQuest
+@code{--skip-show-variables}
+@end table
+
+
+
+
+@node News, Porting, Credits, Top
+@c German node Neuigkeiten
+@appendix MySQL-Änderungsverlauf (Change History)
+
+@cindex ChangeLog
+@cindex Änderungen, Log
+@cindex Log, Änderungen
+
+Dieser Anhang listet die Änderungen von Version zu Version im
+MySQL-Quellcode auf.
+
+Beachten Sie, dass wir versuchen, das Handbuch zeitgleich mit den
+Änderungen an MySQL zu aktualisieren. Wenn Sie unten eine Version
+aufgelistet sehen, die Sie auf der
+@uref{http://www.mysql.com/downloads/,MySQL-Download-Seite} nicht finden
+können, heißt das, dass die Version noch nicht veröffentlicht wurde!
+
+
+
+@menu
+* News-4.0.x::
+* News-3.23.x::
+@end menu
+
+@node News-4.0.x, News-3.23.x, News, News
+@c German node Neuigkeiten-4.0.x
+@appendixsec Änderungen in Release 4.0.x (Entwicklung; Alpha)
+
+Wir arbeiten mittlerweile aktiv an MySQL 4.0 und werden nur noch kritische
+Bug-Bereinigungen für MySQL 3.23 herausgeben. Wir aktualisieren diesen
+Abschnitt, wenn wir neue Features hinzufügen, so dass andere unserer
+Entwicklung folgen können.
+
+Unser TODO-Abschnitt enthält, was wir für 4.0 planen. @xref{TODO}.
+
+@cindex Änderungen, Version 4.0
+
+
+@menu
+* News-4.0.2::
+* News-4.0.1::
+* News-4.0.0::
+@end menu
+
+@node News-4.0.2, News-4.0.1, News-4.0.x, News-4.0.x
+@c German node Neuigkeiten-4.0.2
+@appendixsubsec Änderungen in Release 4.0.2
+
+@itemize @bullet
+@item
+Bug in @code{FLUSH QUERY CACHE} behoben.
+@item
+@code{CAST()}- und @code{CONVERT()}-Funktionen hinzugefügt.
+@item
+Reihenfolge geändert, wie Schlüssel in Tabellen erzeugt werden.
+@item
+Neue Spalten @code{Null} und @code{Index_type} zu @code{SHOW INDEX}
+hinzugefügt.
+@end itemize
+
+@node News-4.0.1, News-4.0.0, News-4.0.2, News-4.0.x
+@c German node Neuigkeiten-4.0.1
+@appendixsubsec Änderungen in Release 4.0.1
+
+@itemize @bullet
+@item
+Bug behoben, wenn @code{HANDLER} mit einem nicht unterstützten Tabellentyp
+verwendet wurde.
+@item
+@code{mysqldump} schreibt jetzt @code{ALTER TABLE tabelle DISABLE KEYS} und
+@code{ALTER TABLE tabelle DISABLE KEYS} in den SQL-Dump.
+@item
+@code{mysql_fix_extensions}-Skript hinzugefügt.
+@item
+Stack-Überlaufproblem @code{LOAD DATA FROM MASTER} auf OSF1 behoben.
+@item
+Herunterfahr-Problem auf HPUX behoben.
+@item
+Funktionen @code{des_encrypt()} und @code{des_decrypt()} hinzugefügt.
+@item
+Statement FLUSH DES_KEY_FILE hinzugefügt.
+@item
+mysqld-Option @code{--des-key-file} hinzugefügt.
+@item
+@code{HEX(string)} gibt jetzt die Buchstaben in der Zeichenkette
+konvertiert in hexadezimal zurück.
+@item
+Problem mit @code{GRANT} bei der Benutzung von @code{lower_case_tables ==
+1} behoben.
+@item
+@code{SELECT ... IN SHARE MODE} in @code{SELECT .. LOCK IN SHARE MODE} (wie
+in MySQL 3.23) geändert.
+@item
+Ein neuer Anfragen-Cache, der Ergebnisse identischer @code{SELECT}-Anfragen
+zwischenspeichert.
+@item
+Coredump-Bug auf 64-Bit-Maschinen beim Erhalt eines falschen
+Kommunikationspakets behoben.
+@item
+@code{MATCH ... AGAINST(... IN BOOLEAN MODE)} funktioniert jetzt auch ohne
+@code{FULLTEXT}-Index.
+@item
+Slave, der vom 3.23-Master repliziert, in Ordnung gebracht.
+@item
+Diverse Replikationsprobleme behoben / bereinigt.
+@item
+Herunterfahren funktioniert jetzt auf Mac OS X.
+@item
+@file{myisam/ft_dump}-Werkzeug zur Low-Level-Inspektion von
+@code{FULLTEXT}-Indexen hinzugefügt.
+@item
+Bug in @code{DELETE ... WHERE ... MATCH ...} behoben.
+@item
+Unterstützung für @code{MATCH ... AGAINST(... IN BOOLEAN MODE)}
+hinzugefügt. @strong{Hinweis: Sie müssen Ihre Tabellen mit
+@code{ALTER TABLE tabelle TYPE=MyISAM} neu aufbauen, um Boole'sche
+Volltextsuche benutzen zu können.}
+@item
+@code{LOCATE()} und @code{INSTR()} sind abhängig von der verwendeten
+Groß-/Kleinschreibung, wenn keins der Argumente eine binäre Zeichenkette
+ist.
+@item
+@code{RND()}-Initialisierung geändert, so dass @code{RND(N)} und
+@code{RND(N+1)} verschiedener sind.
+@item
+Coredump-Bug in @code{UPDATE ... ORDER BY} behoben.
+@item
+@code{INSERT INTO .. SELECT} geändert, damit es bei Fehlern vorgabemäßig
+anhält.
+@item
+@code{DATA DIRECTORY}- und @code{INDEX DIRECTORY}-Anweisungen werden unter
+Windows ignoriert.
+@item
+Boole'sche Volltextsuche hinzugefügt. Diese sollte als frühe Alphaversion
+betrachtet werden.
+@item
+@code{MODIFY} und @code{CHANGE} in @code{ALTER TABLE} erweitert, damit sie
+das @code{AFTER}-Schlüsselwort akzeptieren.
+@item
+Index wird jetzt in @code{ORDER BY} von einer ganzen InnoDB-Tabelle
+verwendet.
+@end itemize
+
+@node News-4.0.0, , News-4.0.1, News-4.0.x
+@c German node Neuigkeiten-4.0.0
+@appendixsubsec Änderungen in Release 4.0.0
+
+@itemize @bullet
+@item
+Variablen @code{ft_min_word_len}, @code{ft_max_word_len} und
+@code{ft_max_word_len_for_sort} hinzugefügt.
+@c German FIX removed extra @itemize @bullet from right here
+@item
+Dokumentation für @code{libmysqld}, die eingebettete
+MySQL-Server-Bibliothek, hinzugefügt. Beispielprogramme (ein
+@code{mysql}-Client und @code{mysqltest}-Testprogramm) hinzugefügt, die
+@code{libmysqld} benutzen.
+@item
+@code{my_thread_init()} und @code{my_thread_end()} aus mysql_com.h entfernt
+und @code{mysql_thread_init()} und @code{mysql_thread_end()} zu mysql.h
+hinzugefügt.
+@item
+Vorzeichenlose @code{BIGINT}-Konstanten funktionieren jetzt. @code{MIN()}
+und @code{MAX()} handhabt vorzeichenbehaftete und vorzeichenlose
+@code{BIGINT}-Zahlen korrekt.
+@item
+Neuer Zeichensatz @code{latin_de}, der korrektes deutsches Sortieren
+ermöglicht.
+@item
+@code{TRUNCATE TABLE} und @code{DELETE FROM tabelle} sind jetzt separate
+Funktionen. Ein Vorteil davon ist, dass @code{DELETE FROM tabelle} jetzt
+die Anzahl gelöschter Zeilen zurückgibt.
+@item
+@code{DROP DATABASE} führt jetzt ein @code{DROP TABLE} auf alle Tabellen in
+der Datenbank aus, was ein Problem mit InnoDB-Tabellen behebt.
+@item
+Unterstützung für @code{UNION} hinzugefügt.
+@item
+Eine neue @code{HANDLER}-Schnittstelle zu @code{MyISAM}-Tabellen.
+@item
+Unterstützung für @code{INSERT} auf @code{MERGE}-Tabellen hinzugefügt.
+Patch von Benjamin Pflugmann.
+@item
+@code{WEEK(#,0)} dem Kalender in den USA angepasst.
+@item
+@code{COUNT(DISTINCT)} ist etwa 30% schneller.
+@item
+Alle internen Listen-Handlings in der Geschwindigkeit verbessert.
+@item
+Das Erzeugen von Volltext-Indexen ist jetzt viel schneller.
+@item
+Baum-ähnlicher Cache, um Massen-Einfügevorgänge und die
+@code{myisam_bulk_insert_tree_size}-Variable zu beschleunigen.
+@item
+Suchen auf komprimierten (@code{CHAR}/@code{VARCHAR})-Schlüsseln ist jetzt
+viel schneller.
+@item
+Anfragen folgenden Typs optimiert:
+@code{SELECT DISTINCT * from tabelle ORDER by schluessel_teil1 LIMIT #}
+@item
+@code{SHOW CREATE TABLE} zeigt jetzt alle Tabellenattribute.
+@item
+@code{ORDER BY ... DESC} kann jetzt Schlüssel benutzen.
+@item
+@code{LOAD DATA FROM MASTER} setzt jetzt "auto-magisch" einen Slave auf.
+@item
+@code{safe_mysqld} in @code{mysqld_safe} umbenannt.
+@item
+Unterstützung für symbolische Links auf @code{MyISAM}-Tabellen hinzugefügt.
+Symlink-Handhabung ist jetzt vorgabemäßig für Windows aktiviert.
+@item
+@code{LOAD DATA FROM MASTER} setzt "auto-magisch" einen Slave auf.
+@item
+@code{SQL_CALC_FOUND_ROWS} und @code{FOUND_ROWS()} hinzugefügt. Das
+ermöglicht es herauszufinden, wie viele Zeilen eine Anfrage ohne eine
+@code{LIMIT}-Klausel zurückgegeben hätte.
+@item
+Ausgabeformat von @code{SHOW OPEN TABLES} geändert.
+@item
+@code{SELECT ausdruck LIMIT ...} wird zugelassen.
+@item
+@code{IDENTITY} als Synonym für @code{AUTO_INCREMENT} hinzugefügt (wie
+Sybase).
+@item
+@code{ORDER BY}-Syntax zu @code{UPDATE} und @code{DELETE} hinzugefügt.
+@item
+@code{SHOW INDEXES} ist jetzt ein Synonym für @code{SHOW INDEX}.
+@item
+@code{ALTER TABLE tabelle DISABLE KEYS}- und @code{ALTER TABLE tabelle
+ENABLE KEYS}-Befehle hinzugefügt.
+@item
+@code{IN} kann anstelle von @code{FROM} in @code{SHOW}-Befehlen benutzt
+werden.
+@item
+ANSI-SQL-Syntax @code{X'Hexadezimalzahl'} wird zugelassen.
+@item
+Globale Sperr-Handhabung für @code{FLUSH TABLES with READ LOCK} aufgeräumt.
+@item
+Problem mit @code{DATETIME = constant} in @code{WHERE}-Optimierungen
+behoben.
+@end itemize
+
+
+@node News-3.23.x, , News-4.0.x, News
+@c German node Neuigkeiten-3.23.x
+@appendixsec Änderungen in Release 3.23.x (Stabil)
+
+@cindex changes, version 3.23
+
+Das 3.23-Release hat etliche wichtige Features, die in früheren Versionen
+nicht vorhanden sind. Es wurden drei neue Tabellentypen hinzugefügt:
+
+@table @asis
+@item @strong{MyISAM}
+Eine neue ISAM-Bibliothek, die auf SQL und Unterstützung großer Dateien
+abgestimmt ist.
+@item @strong{BerkeleyDB} oder @strong{BDB}
+Benutzt die Berkeley-DB-Bibliothek von Sleepycat Software, um
+transaktionssichere Tabellen zu implementieren.
+@item @strong{InnoDB}
+Ein transaktionssicherer Tabellen-Handler, der Sperren auf Zeilenebene und
+viele Oracle-ähnliche Features unterstützt.
+@end table
+
+Beachten Sie, dass nur MyISAM in der Standard-Binärdistribution verfügbar
+ist.
+
+Das 3.23-Release beinhaltet ausserdem Unterstützung für
+Datenbank-Replikation zwischen einem Master und vielen Slaves,
+Volltext-Indexierung und vieles mehr.
+
+Alle neuen Features werden in der 4.0-Version weiter entwickelt. Nur
+Bug-Behebungen und kleinere Verbesserungen bestehender Features werden zu
+3.23 hinzugefügt.
+
+Der Replikationscode und der BerkeleyDB-Code sind noch nicht so gut
+getestet wie der Rest des Codes, daher wird es wahrscheinlich zukünftig
+noch einige Releases von 3.23 mit kleineren Behebungen für diesen Teil des
+Codes geben. Solange Sie diese Features nicht benutzen, sollten Sie mit
+MySQL 3.23 auf der sicheren Seite liegen!
+
+Beachten Sie, dass das Gesagte nicht heißt, dass Replikation oder Berkeley
+DB nicht funktionieren. Wir haben den gesamten Code ausgiebig getestet,
+inklusive Replikation und BDB, ohne irgend welche Probleme zu finden. Es
+heißt nur, dass nicht so viele Benutzer diesen Code verwenden wie den Rest
+des Codes, weshalb wir noch nicht 100% auf diesen Teil des Codes vertrauen.
+
+
+@menu
+* News-3.23.43::
+* News-3.23.42::
+* News-3.23.41::
+* News-3.23.40::
+* News-3.23.39::
+* News-3.23.38::
+* News-3.23.37::
+* News-3.23.36::
+* News-3.23.35::
+* News-3.23.34a::
+* News-3.23.34::
+* News-3.23.33::
+* News-3.23.32::
+* News-3.23.31::
+* News-3.23.30::
+* News-3.23.29::
+* News-3.23.28::
+* News-3.23.27::
+* News-3.23.26::
+* News-3.23.25::
+* News-3.23.24::
+* News-3.23.23::
+* News-3.23.22::
+* News-3.23.21::
+* News-3.23.20::
+* News-3.23.19::
+* News-3.23.18::
+* News-3.23.17::
+* News-3.23.16::
+* News-3.23.15::
+* News-3.23.14::
+* News-3.23.13::
+* News-3.23.12::
+* News-3.23.11::
+* News-3.23.10::
+* News-3.23.9::
+* News-3.23.8::
+* News-3.23.7::
+* News-3.23.6::
+* News-3.23.5::
+* News-3.23.4::
+* News-3.23.3::
+* News-3.23.2::
+* News-3.23.1::
+* News-3.23.0::
+@end menu
+
+@node News-3.23.43, News-3.23.42, News-3.23.x, News-3.23.x
+@c German node Neuigkeiten-3.23.43
+@appendixsubsec Änderungen in Release 3.23.43
+@itemize @bullet
+@item
+Bug behoben, der mit sehr geringer Wahrscheinlichkeit auftritt, der keine
+übereinstimmenden Zeilen zurückgab bei SELECT mit vielen Tabellen,
+mehrspaltigen Indexen und 'Bereichs-'-Typen.
+@item
+Coredump-Bug behoben, der mit sehr geringer Wahrscheinlichkeit auftritt,
+wenn man @code{EXPLAIN SELECT} mit vielen Tabellen und @code{ORDER BY}
+ausführt.
+@item
+Bug in @code{LOAD DATA FROM MASTER} bei der Benutzung einer Tabelle mit
+@code{CHECKSUM=1} behoben.
+@item
+Eindeutige Fehlermeldung hinzugefügt, die man bei einer Blockierung
+(Deadlock) während einer Transaktion mit BDB-Tabellen erhält.
+@item
+Problem mit @code{BDB}-Tabellen und @code{UNIQUE}-Spalten, die als
+@code{NULL} definiert wurden, behoben.
+@item
+Problem mit @code{myisampack} bei der Benutzung von CHAR-Spalten, die
+Leerzeichen aufgefüllt wurden, behoben.
+@item
+Patch von Yuri Dario für OS2 angewandt.
+@item
+Bug in @code{--safe-user-create} behoben.
+@end itemize
+
+@node News-3.23.42, News-3.23.41, News-3.23.43, News-3.23.x
+@c German node Neuigkeiten-3.23.42
+@appendixsubsec Änderungen in Release 3.23.42
+@itemize @bullet
+@item
+Problem bei der Benutzung von @code{LOCK TABLES} und @code{BDB}-Tabellen
+behoben.
+@item
+Problem mit @code{REPAIR TABLE} auf MyISAM-Tabellen mit Zeilenlängen
+zwischen 65517 und 65520 Bytes behoben.
+@item
+Seltenen Hänger bei @code{mysqladmin shutdown} behoben, wenn es viel
+Aktivität auf einem anderen Thread gab.
+@item
+Problem mit @code{INSERT DELAYED} behoben, bei dem ein verzögerter Thread
+auf @code{Upgrade locks} ohne ersichtlichen Grund hängen konnte.
+@item
+Problem mit @code{myisampack} und @code{BLOB} behoben.
+@item
+Problem beim Editieren von @code{.MRG}-Tabellen von Hand behoben.
+(Patch von Benjamin Pflugmann).
+@item
+Es wird erzwungen, dass alle Tabellen in einer @code{MERGE}-Tabelle von
+derselben Datenbank kommen.
+@item
+Bug mit @code{LOAD DATA INFILE} und transaktionalen Tabellen behoben.
+@item
+Bug bei der Benutzung von @code{INSERT DELAYED} mit falschen
+Spaltendefinitionen behoben.
+@item
+Coredump während @code{REPAIR} besonders beschädigter Tabellen behoben.
+@item
+Bug in @code{InnoDB}- und @code{AUTO_INCREMENT}-Spalten behoben.
+@item
+Bug in @code{InnoDB} und @code{RENAME TABLE}-Spalten behoben.
+@item
+Kritischer Bug in @code{InnoDB}- und @code{BLOB}-Spalten behoben. Wenn man
+@code{BLOB}-Spalten größer als 8000 Bytes in einer @code{InnoDB}-Tabelle
+benutzte, musste man die Tabelle mit @code{mysqldump} sichern, löschen und
+aus dem Dump neu aufbauen.
+@item
+Großen Patch für OS/2 von Yuri Dario angewandt.
+@item
+Problem mit @code{InnoDB} behoben, bei dem man den Fehler @code{Can't
+execute the given command...} bekommen konnte, selbst wenn man keine aktive
+Transaktion hatte.
+@item
+Einige kleine Probleme behoben, die Gemini betrafen.
+@item
+Echte arithmetische Operationen werden selbst dann in einem
+Ganzzahl-Zusammenhang benutzt, wenn nicht alle Argumente Ganzzahlen sind.
+(Behebt einen wenig häufigen Bug in einigen Ganzzahl-Kontexten.)
+@item
+Unter Windows wird nicht alles in Kleinschreibung erzwungen (um ein Problem
+mit Windows und @code{ALTER TABLE} zu beheben). @code{--lower_case_names}
+funktioniert jetzt auch unter Unix.
+@item
+Automatisches Rollback behoben, das ausgeführt wurde, wenn das Beenden
+eines Threads keinen anderen Thread blockiert.
+@end itemize
+
+@node News-3.23.41, News-3.23.40, News-3.23.42, News-3.23.x
+@c German node Neuigkeiten-3.23.41
+@appendixsubsec Änderungen in Release 3.23.41
+
+@itemize @bullet
+@item
+Option @code{--sql-mode=option[,option[,option]]} hinzugefügt.
+@xref{Command-line options}.
+@item
+Mögliches Problem mit @code{shutdown} auf Solaris behoben, wobei die
+@file{.pid}-Datei nicht gelöscht wurde.
+@item
+InnoDB unterstützt jetzt Zeilen < 4 GB. Die vorherige Beschränkung war
+8.000 Bytes.
+@item
+Die @code{doublewrite}-Datei-Flush-Methode wird in InnoDB benutzt. Sie
+reduziert die Notwendigkeit von Unix-fsync-Aufrufen auf einen Bruchteil und
+verbessert die Performance auf den meisten Unix-Varianten.
+@item
+Sie können jetzt den InnoDB-Monitor benutzen, um etliche Informationen über
+den InnoDB-Status auf die Standardausgabe auszugeben, inklusive Sperren.
+Nützlich zum Tunen der Performance.
+@item
+Mehrere Bugs, die in InnoDB Hänger verursachen konnten, behoben.
+@item
+@code{record_buffer} in @code{record_buffer} und @code{record_rnd_buffer}
+aufgeteilt. Um zu vorherigen MySQL-Versionen kompatibel zu bleiben, wird
+@code{record_rnd_buffer} auf den Wert von @code{record_buffer} gesetzt,
+wenn es nicht explizit gesetzt wird.
+@item
+Optimierungs-Bug in @code{ORDER BY} behoben, bei dem einige @code{ORDER
+BY}-Teile fälschlicherweise entfernt wurden.
+@item
+Overflow-Bug bei @code{ALTER TABLE} und @code{MERGE}-Tabellen behoben.
+@item
+Prototypen für @code{my_thread_init()} und @code{my_thread_end()} zu
+@file{mysql_com.h} hinzugefügt.
+@item
+Option @code{--safe-user-create} to @code{mysqld} hinzugefügt.
+@item
+Bug in @code{SELECT DISTINCT ... HAVING} behoben, der die Fehlermeldung
+@code{Can't find record in '#...} verursachte.
+@end itemize
+
+
+@node News-3.23.40, News-3.23.39, News-3.23.41, News-3.23.x
+@c German node Neuigkeiten-3.23.40
+@appendixsubsec Änderungen in Release 3.23.40
+
+@itemize @bullet
+@item
+Problem mit @code{--low-priority-updates} und @code{INSERT}'s behoben.
+@item
+Bug im Slave-Thread beseitigt, bei dem dieser in seltenen Fällen um 22 Byte
+vor den Offset im Master kommen konnte.
+@item
+@code{slave_wait_timeout} für Replikation hinzugefügt.
+@item
+Problem mit @code{UPDATE} und @code{BDB}-Tabellen behoben.
+@item
+Problematischen Bug in @code{BDB}-Tabellen behoben, der bei der Benutzung
+von Schlüsselteilen auftrat.
+@item
+Problem bei der Benutzung von @code{GRANT FILE ON datenbank.* ...} behoben.
+Vorher wurde die @code{DROP}-Berechtigung für die Datenbank hinzugefügt.
+@item
+Bug bei @code{DELETE FROM tabelle ... LIMIT 0} und @code{UPDATE FROM
+tabelle ... LIMIT 0} behoben, die sich vorher so verhielten, als gäbe es
+keine @code{LIMIT}-Klausel (sie löschten oder aktualisierten alle
+ausgewählten Zeilen).
+@item
+@code{CHECK TABLE} prüft jetzt, ob eine @code{AUTO_INCREMENT}-Spalte den
+Wert 0 enthält.
+@item
+Wenn man @code{SIGHUP} an @code{mysqld} schickt, werden jetzt nur die Logs
+auf Platte zurückgeschrieben (flush), nicht die Replikation zurückgesetzt.
+@item
+Parser in Ordnung gebracht, so dass er jetzt Fließkommazahlen des Typs
+@code{1.0e1} (kein Vorzeichen nach @code{e}) zuläßt.
+@item
+Option @code{--force} für @code{myisamchk} aktualisiert jetzt auch Zustände
+(Status).
+@item
+Option @code{--warnings} für @code{mysqld} hinzugefügt. @code{mysqld} gibt
+jetzt nur den Fehler @code{Aborted connection} aus, wenn diese Option
+benutzt wird.
+@item
+Problem mit @code{SHOW CREATE TABLE} behoben, wenn man keinen @code{PRIMARY
+KEY} hatte.
+@item
+Saubere Behebung der Umbenennung von @code{innodb_unix_file_flush_method}
+in @code{innodb_flush_method}.
+@item
+Bug beim Umwandeln von @code{UNSIGNED BIGINT} in @code{DOUBLE} behoben.
+Dieser verursachte bei Vergleichen mit @code{BIGINT}-Werten ausserhalb des
+vorzeichenbehafteten Bereichs ein Problem.
+@item
+Bug in @code{BDB}-Tabellen behoben, wenn man leere Tabellen abfragte.
+@item
+Bug bei der Benutzung von @code{COUNT(DISTINCT)} mit @code{LEFT JOIN}
+behoben, wenn es keine übereinstimmenden Zeilen gab.
+@item
+Alle Dokumentation bezüglich @code{GEMINI}-Tabellen entfernt. @code{GEMINI}
+wird nicht unter einer Open-Source-Lizenz herausgegeben.
+@end itemize
+
+
+@node News-3.23.39, News-3.23.38, News-3.23.40, News-3.23.x
+@c German node Neuigkeiten-3.23.39
+@appendixsubsec Änderungen in Release 3.23.39
+
+@itemize @bullet
+@item
+Die @code{AUTO_INCREMENT}-Zahlenfolge wurde beim Löschen und Hinzufügen
+einer @code{AUTO_INCREMENT}-Spalte nicht zurückgesetzt.
+@item
+@code{CREATE ... SELECT} erzeugt jetzt nicht eindeutige Indexe verzögert.
+@item
+Problem behoben, bei dem @code{LOCK TABLES tabelle READ} gefolgt von
+@code{FLUSH TABLES} eine exklusive Sperre auf die Tabelle setzte.
+@item
+@code{REAL}-@@Variablen wurden mit 2 Ziffern dargestellt, wenn sie in
+Zeichenketten umgewandelt wurden.
+@item
+Problem mit hängendem Client behoben, wenn @code{LOAD TABLE FROM MASTER}
+fehlschlug.
+@item
+@code{myisamchk --fast --force} repariert jetzt keine Tabellen mehr, bei
+denen nur der Öffnen-Zähler falsch ist.
+@item
+Funktionen zur Handhabung von symbolischen Links hinzugefügt, um sich das
+Leben in Version 4.0 zu erleichtern.
+@item
+Wir benutzen jetzt die @code{-lcma}-Thread-Bibliothek unter HP-UX 10.20, so
+dass MySQL auf HP-UX stabiler läuft.
+@item
+Problem mit @code{IF()} und Anzahl von Dezimalstellen im Ergebnis behoben.
+@item
+Funktionen zum Extrahieren von Datumsanteilen in Ordnung gebracht, so dass
+sie jetzt mit Datumsangaben funktionieren, bei denen Tag und / oder Monat 0
+sind.
+@item
+Argumentlänge in Optionsdateien von 256 auf 512 Zeichen erweitert.
+@item
+Problem bei Herunterfahren, wenn @code{INSERT DELAYED} auf ein @code{LOCK
+TABLE} wartete, behoben.
+@item
+Coredump-Bug in InnoDB behoben, wenn der Tabellenplatz (Tablespace) voll
+war.
+@item
+Problem mit @code{MERGE}-Tabellen und großen Tabellen (> 4 GB) und der
+Benutzung von @code{ORDER BY} behoben.
+@end itemize
+
+
+@node News-3.23.38, News-3.23.37, News-3.23.39, News-3.23.x
+@c German node Neuigkeiten-3.23.38
+@appendixsubsec Änderungen in Release 3.23.38
+
+@itemize @bullet
+@item
+Bug behoben, bei dem @code{SELECT} von @code{MERGE}-Tabellen manchmal zu
+falsch sortierten Zeilen führte.
+@item
+Bug in @code{REPLACE()} bei der Benutzung des ujis-Zeichensatzes behoben.
+@item
+Sleepycat-BDB-Patches 3.2.9.1 und 3.2.9.2 angewandt.
+@item
+Option @code{--skip-stack-trace} zu @code{mysqld} hinzugefügt.
+@item
+@code{CREATE TEMPORARY} funktioniert jetzt mit @code{InnoDB}-Tabellen.
+@item
+@code{InnoDB} zieht jetzt Teile von Schlüsseln (Sub-Keys) ganzen Schlüsseln
+vor.
+@item
+Option @code{CONCURRENT} für @code{LOAD DATA} hinzugefügt.
+@item
+Bessere Fehlermeldung, wenn die Slave-@code{max_allowed_packet}-Variable zu
+niedrig ist, um ein sehr langes Log-Ereignis vom Master zu lesen.
+@item
+Bug behoben, wenn zu viele Zeilen bei der Benutzung von @code{SELECT
+DISTINCT ... HAVING} entfernt wurden.
+@item
+@code{SHOW CREATE TABLE} gibt jetzt @code{TEMPORARY} für temporäre Tabellen
+zurück.
+@item
+@code{Rows_examined} für Langsame-Anfragen-Log-Datei hinzugefügt.
+@item
+Probleme mit Funktion behoben, die eine leere Zeichenkette zurückgab, wenn
+sie zusammen mit einer Gruppenfunktion und einem @code{WHERE} benutzt
+wurde, das keine Zeilenübereinstimmung ergab.
+@item
+Neues Programm @code{mysqlcheck}.
+@item
+Datenbankname zur Ausgabe für administrative Befehle wie @code{CHECK},
+@code{REPAIR}, @code{OPTIMIZE} hinzugefügt.
+@item
+Viele Portabilitätsbehebungen für InnoDB.
+@item
+Optimierer geändert, so dass Anfragen wie @code{SELECT * FROM
+tabelle,tabelle2 ... ORDER BY schluessel_teil1 LIMIT #} den Index auf
+@code{schluessel_teil1} anstelle von @code{filesort} benutzen.
+@item
+Bug bei der Ausführung von @code{LOCK TABLE to_table WRITE,...; INSERT INTO
+to_table... SELECT ...} behoben, wenn @code{to_table} leer war.
+@item
+Bug mit @code{LOCK TABLE} und BDB-Tabellen behoben.
+@end itemize
+
+
+@node News-3.23.37, News-3.23.36, News-3.23.38, News-3.23.x
+@c German node Neuigkeiten-3.23.37
+@appendixsubsec Änderungen in Release 3.23.37
+
+@itemize @bullet
+@item
+Bug bei der Benutzung von @code{MATCH} in @code{HAVING}-Klausel.
+@item
+Bug bei der Benutzung von @code{HEAP}-Tabellen mit @code{LIKE} behoben.
+@item
+@code{--mysql-version} für @code{safe_mysqld} hinzugefügt.
+@item
+@code{INNOBASE} in @code{InnoDB} geändert (weil der @code{INNOBASE}-Name
+bereits benutzt wurde). Alle @code{configure}-Optionen und
+@code{mysqld}-Startoptionen benutzen jetzt @code{innodb} anstelle von
+@code{innobase}. Das heißt, dass Sie jegliche Konfigurationsdateien, in
+denen Sie @code{innobase}-Optionen benutzt haben, ändern müssen, bevor Sie
+auf diese Version aktualisieren!
+@item
+Bug bei der Benutzung von Indexen auf @code{CHAR(255) NULL}-Spalten
+behoben.
+@item
+Slave-Thread wird jetzt auch dann gestartet, wenn @code{master-host} nicht
+gesetzt ist, so lange @code{server-id} gesetzt wird und es eine gültige
+@code{master.info} gibt.
+@item
+Teilweise Aktualisierungen (beendet mit kill) werden jetzt mit einem
+speziellen Fehler-Code in die Binär-Log-Datei geschrieben. Der Slave
+weigert sich, sie auszuführen, wenn der Fehler-Code anzeigt, dass die
+Aktualisierung abnorm beendet wurde, und muss mit @code{SET
+SQL_SLAVE_SKIP_COUNTER=1; SLAVE START} wieder dazu veranlasst werden,
+nachdem eine manuelle Überprüfung / Korrektur der Datenintegrität
+durchgeführt wurde.
+@item
+Bug behoben, der das Löschen einer internen temporären Tabelle beim Beenden
+des Threads irrtümlicherweise in die Binär-Log-Datei schrieb. Dieser Bug
+betraf Replikation.
+@item
+Bug in @code{REGEXP()} auf 64-Bit-Maschinen.
+@item
+@code{UPDATE} und @code{DELETE} mit @code{WHERE eindeutiger_schluessel_teil
+IS NULL} aktualisierte / löschte nicht alle Zeilen.
+@item
+@code{INSERT DELAYED} für Tabellen abgeschaltet, die Transaktionen
+unterstützen.
+@item
+Bug bei der Benutzung von DATE-Funktionen auf
+@code{TEXT}/@code{BLOB}-Spalten mit falschem Datumsformat behoben.
+@item
+UDFs (benutzerdefinierte Funktionen) funktionieren jetzt auch unter
+Windows (Patch von Ralph Masona).
+@item
+Bug in @code{ALTER TABLE} und @code{LOAD DATA INFILE} behoben, der das
+Sortieren von Schlüsseln deaktivierte. Diese Befehle sollten jetzt in den
+meisten Fällen schneller sein.
+@item
+Performance-Bug beim erneuten Öffnen von Tabellen behoben (Tabellen, die
+auf ein @code{FLUSH} oder @code{REPAIR} warteten), die für die nächste
+Anfrage keine Indexe benutzten.
+@item
+Problem mit @code{ALTER TABLE} für Innobase-Tabellen auf FreeBSD behoben.
+@item
+@code{mysqld}-Variablen @code{myisam_max_sort_file_size} und
+@code{myisam_max_extra_sort_file_size} hinzugefügt.
+@item
+Signale werden frühzeitig initialisiert, um Problem mit Signalen in
+Innobase zu vermeiden.
+@item
+Patch für den @code{tis620}-Zeichensatz hinzugefügt, um Vergleiche
+unabhängig von der verwendeten Groß-/Kleinschreibung zu machen und einen
+Bug in @code{LIKE} für diesen Zeichensatz zu beheben. @strong{HINWEIS}:
+Alle Tabellen, die den @code{tis620}-Zeichensatz benutzen, müssen mit
+@code{myisamchk -r} oder @code{REPAIR TABLE} in Ordnung gebracht werden!
+@item
+@code{--skip-safemalloc}-Option zu @code{mysqld} hinzugefügt.
+@end itemize
+
+
+@node News-3.23.36, News-3.23.35, News-3.23.37, News-3.23.x
+@c German node Neuigkeiten-3.23.36
+@appendixsubsec Änderungen in Release 3.23.36
+
+@itemize @bullet
+@item
+Bug behoben, der Datenbanknamen mit einem @samp{.}-Zeichen zuließ. Das
+behebt ein schwerwiegendes Sicherheitsproblem, wenn man @code{mysqld} unter
+dem Benutzer root laufen läßt.
+@item
+Bug behoben, wenn die Erzeugung eines Threads fehlschlägt (das konnte bei
+der Herstellung SEHR vieler Verbindungen in kurzer Zeit passieren).
+@item
+Einige Probleme mit @code{FLUSH TABLES} und @code{TEMPORARY}-Tabellen
+behoben. (Problem mit dem Freisetzen des Schlüssel-Cache und Fehler
+@code{Can't reopen table...}).
+@item
+Problem in Innobase mit anderen Zeichensätze als @code{latin1} und ein
+anderes Problem bei der Benutzung von vielen Spalten behoben.
+@item
+Bug behoben, der einen Coredump bei der Benutzung einer sehr komplexen
+Anfrage mit @code{DISTINCT} und Summenfunktionen verursachte.
+@item
+@code{SET TRANSACTION ISOLATION LEVEL ...} hinzugefügt.
+@item
+@code{SELECT ... FOR UPDATE} hinzugefügt.
+@item
+Bug behoben, bei dem die Anzahl von betroffenen Zeilen nicht zurückgegeben
+wurde, wenn @code{MySQL} ohne Transaktionsunterstützung kompiliert wurde.
+@item
+Bug in @code{UPDATE} behoben, bei dem nicht immer Schlüssel benutzt wurden,
+um die zu aktualisierenden Zeilen zu finden.
+@item
+Bug in @code{CONCAT_WS()} behoben, bei dem diese Funktion falsche
+Ergebnisse zurückgab.
+@item
+@code{CREATE ... INSERT} und @code{INSERT ... SELECT} geändert, so dass
+diese noch kleine gleichzeitigen Einfügevorgänge zulassen, weil das dazu
+führen könnte, dass die Binär-Log-Datei schwer zu wiederholen ist.
+(Gleichzeitige Einfügevorgänge sind aktiviert, wenn Sie nicht die Binär-
+oder Update-Log-Datei verwenden.)
+@item
+Einige Makros geändert, so dass schnelles mutex mit glibc 2.2 verwendet
+werden kann.
+@end itemize
+
+
+@node News-3.23.35, News-3.23.34a, News-3.23.36, News-3.23.x
+@c German node Neuigkeiten-3.23.35
+@appendixsubsec Änderungen in Release 3.23.35
+
+@itemize @bullet
+@item
+Neu eingeführter Bug in @code{ORDER BY} behoben.
+@item
+Falsches Definieren von @code{CLIENT_TRANSACTIONS} behoben.
+@item
+Bug in @code{SHOW VARIABLES} bei der Benutzung von @code{INNOBASE}-Tabellen
+behoben.
+@item
+Das Setzen und Benutzen von Benutzer-Variablen in @code{SELECT DISTINCT}
+funktionierte nicht.
+@item
+@code{SHOW ANALYZE} für kleine Tabellen verbessert.
+@item
+Handhabung von Argumenten im Benchmark-Skript @file{run-all-tests} behoben.
+@end itemize
+
+
+@node News-3.23.34a, News-3.23.34, News-3.23.35, News-3.23.x
+@c German node Neuigkeiten-3.23.34a
+@appendixsubsec Änderungen in Release 3.23.34a
+
+@itemize @bullet
+@item
+Zusätzliche Dateien zur Distribution hinzugefügt, die es ermöglichen, mit
+@code{INNOBASE}-Unterstützung zu kompilieren.
+@end itemize
+
+
+@node News-3.23.34, News-3.23.33, News-3.23.34a, News-3.23.x
+@c German node Neuigkeiten-3.23.34
+@appendixsubsec Änderungen in Release 3.23.34
+
+@itemize @bullet
+@item
+@code{INNOBASE}-Tabellen-Handler und @code{BDB}-Tabellen-Handler zur
+MySQL-Quelldistribution hinzugefügt.
+@item
+Die Dokumentation zu @code{GEMINI}-Tabellen aktualisiert.
+@item
+Bug in @code{INSERT DELAYED} behoben, der den Thread zum Hängen brachte,
+wenn @code{NULL} in eine @code{AUTO_INCREMENT}-Spalte eingefügt wurde.
+@item
+Bug in @code{CHECK TABLE} / @code{REPAIR TABLE} behoben, der einen Thread
+zum Hängen bringen konnte.
+@item
+@code{REPLACE} ersetzt keine Zeile mehr, die mit einem durch
+@code{auto_increment} erzeugten Schlüssel in Konflikt steht.
+@item
+@code{mysqld} setzt jetzt nur @code{CLIENT_TRANSACTIONS} in
+@code{mysql->server_capabilities}, wenn der Server einen
+transaktionssicheren Handler unterstützt.
+@item
+@code{LOAD DATA INFILE} läßt jetzt das Einfügen numerischer Werte in
+@code{ENUM}- und @code{SET}-Spalten zu.
+@item
+Fehlerdiagnose beim Slave-Thread-Exit verbessert.
+@item
+Bug in @code{ALTER TABLE ... ORDER BY} behoben.
+@item
+Option @code{max_user_connections} für @code{mysqld} hinzugefügt.
+@item
+Anfragelänge für Replikation auf @code{max_allowed_packet} begrenzt, nicht
+auf die willkürliche Länge von 4 MB.
+@item
+Leerzeichen um @code{=} herum im Argument zu @code{--set-variable} werden
+zugelassen.
+@item
+Problem beim automatischen Reparieren behoben, der einen Thread im Zustand
+@code{Waiting for table} lassen konnte.
+@item
+@code{SHOW CREATE TABLE} gibt jetzt das @code{UNION()} für
+@code{MERGE}-Tabellen aus.
+@item
+@code{ALTER TABLE} merkt sich jetzt die alte @code{UNION()}-Definition.
+@item
+Bug beim Replizieren von Timestamps behoben.
+@item
+Bug bei der bidirektionalen Replikation behoben.
+@item
+Bug im @code{BDB}-Tabellen-Handler behoben, der bei der Benutzung eines
+Indexes auf mehrteilige Schlüssel vorkam, wenn ein Schlüsselteil
+@code{NULL} sein konnte.
+@item
+@code{MAX()}-Optimierung für Schlüsselteile (Sub-Keys) für
+@code{BDB}-Tabellen verbessert.
+@item
+Problem behoben, bei dem 'Müll'-Ergebnisse bei der Benutzung von
+@code{BDB}-Tabellen und @code{BLOB}- oder @code{TEXT}-Feldern beim
+Verknüpfen (Join) vieler Tabellen auftraten.
+@item
+Problem mit @code{BDB}-Tabellen und @code{TEXT}-Spalten behoben.
+@item
+Bug bei der Benutzung eines @code{BLOB}-Schlüssels behoben, wenn eine
+Konstanten-Zeile nicht gefunden wurde.
+@item
+Problem behoben, dass @code{mysqlbinlog} den Timestamp-Wert für jede
+Anfrage schreibt. Das stellt sicher, dass man dieselben Werte bei
+Datumsfunktionen wie @code{NOW()} bei der Benutzung von @code{mysqlbinlog}
+erhält, um die Anfragen zu einem anderen Server durchzureichen (pipe).
+@item
+Es wird zugelassen, dass @code{--skip-gemini}, @code{--skip-bdb} und
+@code{--skip-innobase} für @code{mysqld} angegeben werden, selbst wenn
+diese Datenbanken nicht in @code{mysqld} einkompiliert sind.
+@item
+Man kann jetzt @code{GROUP BY ... DESC} ausführen.
+@item
+Blockierung im @code{SET}-Code behoben, wenn man @code{SET @@foo=bar}
+ausführte, wobei @code{bar} ein Spaltenverweis ist. Hier wurde die
+Fehlermeldung nicht korrekt erzeugt.
+@end itemize
+
+
+@node News-3.23.33, News-3.23.32, News-3.23.34, News-3.23.x
+@c German node Neuigkeiten-3.23.33
+@appendixsubsec Änderungen in Release 3.23.33
+
+@itemize @bullet
+@item
+DNS-Lookups benutzen jetzt nicht mehr denselben mutex wie der
+Hostnamen-Cache. Das gestattet, dass bekannte Hosts schnell aufgelöst
+werden können, selbst wenn ein DNS-Lookup lange Zeit braucht.
+@item
+@code{--character-sets-dir} für @code{myisampack} hinzugefügt.
+@item
+Warnungen beim Laufenlassen von @code{REPAIR TABLE ... EXTENDED} entfernt.
+@item
+Bug, der einen Coredump bei der Benutzung von @code{GROUP BY} auf ein Alias
+verursachte, wobei der Alias dasselbe wie ein existierender Spaltenname
+war, entfernt.
+@item
+@code{SEQUENCE()} als Beispiel-UDF-Funktion hinzugefügt.
+@item
+@code{mysql_install_db} geändert, so dass es @code{BINARY} für
+@code{CHAR}-Spalten in den Berechtigungstabellen benutzt.
+@item
+@code{TRUNCATE tabelle} zu @code{TRUNCATE TABLE tabelle} geändert, um
+dieselbe Syntax wie Oracle zu verwenden. Bis Version 4.0 lassen wir
+weiterhin @code{TRUNCATE tabelle} zu, um alten Code nicht zum Absturz zu
+bringen.
+@item
+'no found rows'-Bug in @code{MyISAM}-Tabellen behoben, wenn ein @code{BLOB}
+erster Teil eines mehrteiligen Schlüssels war.
+@item
+Bug behoben, bei dem @code{CASE} mit @code{GROUP BY} nicht funktionierte.
+@item
+Option @code{--sort-recover} für @code{myisamchk} hinzugefügt.
+@item
+@code{myisamchk -S} und @code{OPTIMIZE TABLE} funktionieren jetzt unter
+Windows.
+@item
+Bug bei der Benutzung von @code{DISTINCT} auf Ergebnisse von Funktionen
+behoben, die sich auf eine Gruppenfunktion bezogen, wie:
+@example
+SELECT a, DISTINCT SEC_TO_TIME(sum(a)) from tabelle GROUP BY a, b;
+@end example
+@item
+Puffer-Überlauf in @code{libmysqlclient}-Bibliothek behoben. Bug bei der
+Handhabung des @code{STOP}-Ereignisses nach @code{ROTATE}-Ereignis bei
+Replikation.
+@item
+Einen weiteren Puffer-Überlauf in @code{DROP DATABASE} behoben.
+@item
+@code{Table_locks_immediate}- und
+@code{Table_locks_waited}-Status-Variablen hinzugefügt.
+@item
+Bug in Replikation behoben, der den Slave-Server-Start bei existierendem
+@code{master.info} unterbrach. Das behebt einen Bug, der in Version 3.23.32
+eingeführt wurde.
+@item
+@code{SET SQL_SLAVE_SKIP_COUNTER=n}-Befehl hinzugefügt, um nach
+Replikationsstörungen ohne volle Datenbankkopie wiederherzustellen.
+@item
+@code{max_binlog_size}-Variable hinzugefügt; die Binär-Log-Datei wird
+automatisch rotiert, wenn die Größe die Grenze überschreitet.
+@item
+@code{Last_error}, @code{Last_errno} und @code{Slave_skip_counter} für
+@code{SHOW SLAVE STATUS} hinzugefügt.
+@item
+Bug in @code{MASTER_POS_WAIT()}-Funktion behoben.
+@item
+Coredump-Handler auf @code{SIGILL} und @code{SIGBUS} zusätzlich zu
+@code{SIGSEGV}.
+@item
+Auf x86-Linux wird im Coredump-Handler die aktuelle Anfrage und die Thread-
+(Verbindungs-) Kennung, falls verfügbar, angegeben.
+@item
+Mehrere Timing-Bugs in der Test-Suite behoben.
+@item
+@code{mysqltest} erweitert, so dass es sich um Probleme mit dem Timing in
+der Test-Suite kümmert.
+@item
+@code{ALTER TABLE} kann jetzt auch benutzt werden, um die Definition einer
+@code{MERGE}-Tabelle zu ändern.
+@item
+Erzeugung von @code{MERGE}-Tabellen unter Windows in Ordnung gebracht.
+@item
+Portabilitätsbehebungen für OpenBSD und OS/2.
+@item
+@code{--temp-pool}-Option zu @code{mysqld} hinzugefügt. Das Benutzen dieser
+Option führt dazu, dass temporäre Dateien nur einen kleinen Satz von Namen
+benutzen, statt eines eindeutigen Namens für jede neue Datei. Das ist ein
+Workaround um ein Problem im Linux-Kernel beim Erzeugen einer großen Menge
+neuer Dateien mit unterschiedlichen Namen. Beim alten Verhalten scheint es
+so, als ein Linux ein Speicher-'Loch' hätte, weil zum
+Verzeichniseintrags-Cache statt zum Festplatten-Cache zugewiesen
+(alloziert) wird.
+@end itemize
+
+
+@node News-3.23.32, News-3.23.31, News-3.23.33, News-3.23.x
+@c German node Neuigkeiten-3.23.32
+@appendixsubsec Änderungen in Release 3.23.32
+
+@itemize @bullet
+@item
+Code geändert, um um einen Compiler-Bug in Compaq C++ auf OSF1
+herumzuarbeiten, der @code{BACKUP}, @code{RESTORE}, @code{CHECK},
+@code{REPAIR} und @code{ANALYZE TABLE} beschädigte.
+@item
+Option @code{FULL} für @code{SHOW COLUMNS} hinzugefügt. Jetzt wird die
+Berechtigungsliste für die Spalten nur angezeigt, wenn diese Option
+angegeben wird.
+@item
+Bug in @code{SHOW LOGS} behoben, wenn es keine BDB-Logs gab.
+@item
+Timing-Problem in Replikation behoben, dass das Abschicken einer
+Aktualisierung an den Client verzögern konnte, bis eine weitere
+Aktualisierung durchgeführt wurde.
+@item
+Feldnamen bei der Benutzung von @code{mysql_list_fields()} nicht umwandeln.
+Damit bleibt dieser Code kompatibel mit @code{SHOW FIELDS}.
+@item
+@code{MERGE}-Tabellen funktionierten nicht unter Windows.
+@item
+Problem mit @code{SET PASSWORD=...} unter Windows.
+@item
+Fehlende @file{my_config.h} für RPM-Distribution hinzugefügt.
+@item
+@code{TRIM("foo" von "foo")} gab keine leere Zeichenkette zurück.
+@item
+@code{--with-version-suffix} für @code{configure} hinzugefügt.
+@item
+Coredump behoben, wenn der Client eine Verbindung ohne @code{mysql_close()}
+abbrach.
+@item
+Bug in @code{RESTORE TABLE} behoben, wenn man versuchte, aus einem nicht
+vorhandenen Verzeichnis wiederherzustellen.
+@item
+Bug behoben, der einen Coredump auf dem Slave bei der Replikation von
+@code{SET PASSWORD} verursachte.
+@item
+@code{MASTER_POS_WAIT()} hinzugefügt.
+@end itemize
+
+
+@node News-3.23.31, News-3.23.30, News-3.23.32, News-3.23.x
+@c German node Neuigkeiten-3.23.31
+@appendixsubsec Änderungen in Release 3.23.31
+
+@itemize @bullet
+@item
+Die Test-Suite testet jetzt jeden erreichbaren BDB-Schnittstellen-Code.
+Während der Tests fanden und behoben wir viele Fehler im
+Schnittstelle-Code.
+@item
+Die Benutzung von @code{HAVING} auf eine leere Tabelle konnte eine
+Ergebniszeile ergeben, ohne dass es das sollte.
+@item
+Problem behoben, so dass das MySQL-RPM nicht mehr von Perl5 abhängt.
+@item
+Einige Probleme mit @code{HEAP}-Tabellen unter Windows behoben.
+@item
+@code{SHOW TABLE STATUS} zeigte nicht die korrekte durchschnittliche
+Zeilenlänge bei Tabellen größer als 4 GB.
+@item
+@code{CHECK TABLE ... EXTENDED} prüften keine Zeilen-Links für Tabellen
+fester Größe.
+@item
+Option @code{MEDIUM} für @code{CHECK TABLE} hinzugefügt.
+@item
+Problem bei der Benutzung von @code{DECIMAL()}-Schlüsseln auf negative
+Zahlen behoben.
+@item
+@code{HOUR()} (und einige andere @code{TIME}-Funktionen) auf einer
+@code{CHAR}-Spalte gaben immer @code{NULL} zurück.
+@item
+Sicherheits-Bug in etwas behoben (bitte aktualisieren Sie, wenn Sie eine
+frühere MySQL-3.23-Version benutzen).
+@item
+Bug mit Puffer-Überlauf behoben, wenn eine bestimmte Fehlermeldung
+ausgegeben wurde.
+@item
+Benutzung von @code{setrlimit()} unter Linux hinzugefügt, damit
+@code{-O --open-files-limit=#} unter Linux läuft.
+@item
+Neue @code{mysqld}-Variable @code{bdb_version} hinzugefügt.
+@item
+Bug bei der Benutzung von Ausdrücken folgenden Typs behoben:
+@example
+SELECT ... FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=t2.a
+@end example
+In diesem Fall wurde der Test in der @code{WHERE}-Klausel fälschlicherweise
+weg optimiert.
+@item
+Bug in @code{MyISAM} beim Löschen von Schlüsseln mit möglichen
+@code{NULL}-Werten behoben, wenn die erste Schlüsselspalte keine
+Präfix-komprimierte Text-Spalte war.
+@item
+@code{mysql.server} repariert, so dass es den
+@code{mysql.server}-Optionsabschnitt anstelle von @code{mysql_server}
+liest.
+@item
+@code{safe_mysqld} und @code{mysql.server} repariert, so dass sie den
+@code{server}-Optionsabschnitt lesen.
+@item
+@code{thread_created}-Status-Variable zu @code{mysqld} hinzugefügt.
+@end itemize
+
+
+@node News-3.23.30, News-3.23.29, News-3.23.31, News-3.23.x
+@c German node Neuigkeiten-3.23.30
+@appendixsubsec Änderungen in Release 3.23.30
+
+@itemize @bullet
+@item
+@code{SHOW OPEN TABLES}-Befehl hinzugefügt.
+@item
+@code{myisamdump} funktioniert jetzt mit alten @code{mysqld}-Servern.
+@item
+@code{myisamchk -k#} funktioniert jetzt wieder.
+@item
+Problem mit Replikation behoben, wenn die Binär-Log-Datei-Datei auf
+32-Bit-Systemen größer als 2 GB wurde.
+@item
+@code{LOCK TABLES} startet jetzt automatisch eine neue Transaktion.
+@item
+@code{BDB}-Tabellen so geändert, dass sie interne Sub-Transaktionen
+benutzen und offene Dateien wiederholt benutzen, um mehr Geschwindigkeit zu
+erzielen.
+@item
+Option @code{--mysqld=#} für @code{safe_mysqld} hinzugefügt.
+@item
+Hexadezimale Konstanten in @code{--fields-*-by}- und
+@code{--lines-terminated-by}-Optionen für @code{mysqldump} und
+@code{mysqlimport} werden jetzt zugelassen. Von Paul DuBois.
+@item
+Option @code{--safe-show-Datenbank} für @code{mysqld} hinzugefügt.
+@item
+@code{have_bdb}, @code{have_gemini}, @code{have_innobase},
+@code{have_raid} und @code{have_openssl} für @code{SHOW VARIABLES}
+hinzugefügt, um das Testen auf unterstützte Erweiterungen zu erleichtern.
+@item
+Option @code{--open-files-limit} für @code{mysqld} hinzugefügt.
+@item
+Option @code{--open-files} zu @code{--open-files-limit} in
+@code{safe_mysqld} geändert.
+@item
+Bug behoben, bei dem einige Zeilen nicht gefunden wurden, wenn
+@code{HEAP}-Tabellen viele Schlüssel hatten.
+@item
+@code{--bdb-no-sync} funktioniert jetzt.
+@item
+@code{--bdb-recover} in @code{--bdb-no-recover} geändert, weil recover
+vorgabemäßig angeschaltet sein sollte.
+@item
+Die vorgabemäßige Anzahl von BDB-Sperren auf 10.000 geändert.
+@item
+Bug aus Version 3.23.29 behoben, beim Zuweisen der gemeinsam genutzten
+Struktur, die für BDB-Tabellen benötigt wird.
+@item
+@file{mysqld_multi.sh} für benutzerkonfigurierbare Variablen geändert.
+Patch von Christopher McCrory.
+@item
+Include-Dateien für Solaris 2.8 in Ordnung gebracht.
+@item
+Bug mit @code{--skip-networking} auf Debian Linux behoben.
+@item
+Problem behoben, dass einige temporäre Dateien den Namen @code{UNOPENED} in
+Fehlermeldungen hatten.
+@item
+Bug beim Laufenlassen von zwei gleichzeitigen @code{SHOW LOGS}-Anfragen
+behoben.
+@end itemize
+
+
+@node News-3.23.29, News-3.23.28, News-3.23.30, News-3.23.x
+@c German node Neuigkeiten-3.23.29
+@appendixsubsec Änderungen in Release 3.23.29
+
+@itemize @bullet
+@item
+Configure-Aktualisierungen für Tru64, Unterstützung großer Dateien und
+besser TCP-Wrapper-Unterstützung. Von Albert Chin-A-Young.
+@item
+Bug in @code{<=>}-Operator behoben.
+@item
+Bug in @code{REPLACE} mit BDB-Tabellen behoben.
+@item
+@code{LPAD()} und @code{RPAD()} kürzen jetzt die Ergebnis-Zeichenkette,
+wenn sie länger als das Längenargument ist.
+@item
+@code{SHOW LOGS}-Befehl hinzugefügt.
+@item
+Unbenutzte BDB-Logs werden beim Herunterfahren entfernt.
+@item
+Beim Erzeugen einer Tabelle werden @code{PRIMARY}-Schlüsseln zuerst
+gesetzt, gefolgt von @code{UNIQUE}-Schlüsseln.
+@item
+Bug in @code{UPDATE} behoben, wenn mehrteilige Schlüssel benutzt wurden,
+bei denen alle Schlüsselteile sowohl in der Aktualisierung als auch im
+@code{WHERE}-Teil angegeben wurden. In diesem Fall könnte MySQL versuchen,
+einen Datensatz zu aktualisieren, der nicht dem gesamten @code{WHERE}-Teil
+entspricht.
+@item
+Löschen von Tabellen so geändert, dass zunächst die Tabelle und dann die
+@file{.frm}-Datei gelöscht wird.
+@item
+Bug im Hostnamen-Cache behoben, der dazu führte, dass @code{mysqld} den
+Hostnamen als @code{''} in manchen Fehlermeldungen berichtete.
+@item
+Bug mit @code{HEAP}-Tabellen behoben; die Variable
+@code{max_heap_table_size} wurde nicht benutzt. Jetzt kann entweder
+@code{MAX_ROWS} oder @code{max_heap_table_size} benutzt werden, um die
+Größe einer @code{HEAP}-Tabelle zu beschränken.
+@item
+Die vorgabemäßige Server-Kennung auf 1 für Master-Server und 2 für Slaves
+geändert, um die Benutzung der Binär-Log-Datei zu erleichtern.
+@item
+Variable @code{bdb_lock_max} in @code{bdb_max_lock} umbenannt.
+@item
+Unterstützung für @code{auto_increment} auf Unter-Felder (Sub-Fields) für
+BDB-Tabellen hinzugefügt.
+@item
+@code{ANALYZE} von BDB-Tabellen hinzugefügt.
+@item
+In BDB-Tabellen wird jetzt die Anzahl von Zeilen gespeichert. Das hilft,
+Anfragen zu optimieren, wenn dafür die ungefähre Anzahl von Zeilen benötigt
+wird.
+@item
+Wenn es einen Fehler in einem mehrzeiligen Statement gibt, wird jetzt nur
+das letzte Statement zurückgerollt, nicht die gesamte Transaktion.
+@item
+Wenn man @code{ROLLBACK} nach der Aktualisierung einer nicht
+transaktionalen Tabelle ausführt, erhält man als Warnung einen Fehler.
+@item
+Option @code{--bdb-shared-data} für @code{mysqld} hinzugefügt.
+@item
+Status-Variable @code{Slave_open_temp_tables} hinzugefügt.
+@item
+Variablen @code{binlog_cache_size} und @code{max_binlog_cache_size} für
+@code{mysqld} hinzugefügt.
+@item
+@code{DROP TABLE}, @code{RENAME TABLE}, @code{CREATE INDEX} und
+@code{DROP INDEX} sind jetzt Transaktions-Endpunkte.
+@item
+Wenn Sie ein @code{DROP DATABASE} auf eine symbolisch verknüpfte Datenbank
+ausführen, werden sowohl der Link als auch die Original-Datenbank gelöscht.
+@item
+@code{DROP DATABASE} funktioniert jetzt auf OS/2.
+@item
+Bug bei der Ausführung von @code{SELECT DISTINCT ... tabelle1 LEFT JOIN
+tabelle2 ...} behoben, wenn tabelle2 leer war.
+@item
+@code{--abort-slave-event-count}- und
+@code{--disconnect-slave-event-count}-Optionen für @code{mysqld} zum
+Debuggen und Testen der Replikation hinzugefügt.
+@item
+Replikation temporärer Tabellen in Ordnung gebracht. Handhabt alles ausser
+dem Neustart von Slaves.
+@item
+@code{SHOW KEYS} zeigt jetzt, ob ein Schlüssel @code{FULLTEXT} ist oder
+nicht.
+@item
+Neues Skript @file{mysqld_multi}. @xref{mysqld_multi, , @code{mysqld_multi}}.
+@item
+Neues Skript @file{mysql-multi.server.sh} hinzugefügt. Vielen Dank an Tim
+Bunce @email{Tim.Bunce@@ig.co.uk} für die Modifizierung von
+@file{mysql.server}, um auf einfache Weise Hosts zu handhaben, die viele
+@code{mysqld}-Prozesse laufen lassen.
+@item
+@file{safe_mysqld}, @file{mysql.server} und @file{mysql_install_db} wurden
+so abgeändert, dass sie @code{mysql_print_defaults} anstelle verschiedener
+Hacks benutzen, um @file{my.cnf}-Dateien zu lesen. Zusätzlich wurde die
+Handhabung verschiedener Pfade konsistenter gemacht, in Bezug auf wie
+@code{mysqld} vorgabemäßig handhabt.
+@item
+Berkeley-DB-Transaktions-Logs, die nicht mehr in Benutzung sind, werden
+automatisch entfernt.
+@item
+Bug bei mehreren @code{FULLTEXT}-Indexen in einer Tabelle behoben.
+@item
+Warnung hinzugefügt, wenn sich die von Zeilen bei
+@code{REPAIR}/@code{OPTIMIZE} ändert.
+@item
+Patches für OS/2 von @code{Yuri Dario} angewandt.
+@item
+@code{FLUSH TABLES tabelle} schrieb den Index-Baum nicht immer korrekt auf
+die Festplatte zurück.
+@item
+@code{--bootstrap} läuft jetzt in einem separaten Thread. Das behebt ein
+Problem, das bei @code{mysql_install_db} einen Coredump auf einigen
+Linux-Maschinen verursachte.
+@item
+@code{mi_create()} abgeändert, so dass es weniger Stack-Platz benötigt.
+@item
+Bug beim Optimierer, wenn er versucht, @code{MATCH}, mit
+@code{UNIQUE}-Schlüsseln benutzt, zu überoptimieren.
+@item
+@code{Crash-me} und die MySQL-Benchmarks funktionieren jetzt auch mit
+FrontBase.
+@item
+@code{RESTRICT} und @code{CASCADE} werden nach einem @code{DROP TABLE}
+zugelassen, um die Portierung einfacher zu machen.
+@item
+Status-Variable zurückgesetzt, die Probleme hervorrufen konnte, wenn man
+@code{--slow-log} benutzte.
+@item
+Variable @code{connect_timeout} für @code{mysql} und @code{mysqladmin}
+hinzugefügt.
+@item
+@code{connect_timeout} als Alias für @code{timeout} für Optionsdateien, die
+von @code{mysql_options()} gelesen werden, hinzugefügt.
+@end itemize
+
+
+@node News-3.23.28, News-3.23.27, News-3.23.29, News-3.23.x
+@c German node Neuigkeiten-3.23.28
+@appendixsubsec Änderungen in Release 3.23.28
+
+@itemize @bullet
+@item
+Neue Optionen @code{--pager[=...]}, @code{--no-pager}, @code{--tee=...} und
+@code{--no-tee} für den @code{mysql}-Client hinzugefügt. Die entsprechenden
+neuen interaktiven Befehle heißen @code{pager}, @code{nopager}, @code{tee}
+und @code{notee}. Siehe @xref{mysql, , @code{mysql}}, @code{mysql --help}
+und die interaktive Hilfe wegen weiterer Informationen.
+@item
+Absturz behoben, der beim Fehlschlagen der Reparatur von
+@code{MyISAM}-Tabellen auftrat.
+@item
+Größerer Performance-Bug im Tabellensperren-Code behoben, wenn man
+permanent VIELE @code{SELECT}-, @code{UPDATE}- und @code{INSERT}-Statements
+laufen hatte. Das Symptom zeigte sich darin, dass die @code{UPDATE}- und
+@code{INSERT}-Anfragen lange gesperrt waren, während neue
+@code{SELECT}-Statements vor den Aktualisierungen ausgeführt wurden.
+@item
+Beim Lesen von @code{options_files} mit @code{mysql_options()} wurde die
+@code{return-found-rows}-Option ignoriert.
+@item
+Man kann jetzt @code{interactive-timeout} in der Optionsdatei angeben, die
+von @code{mysql_options()} gelesen wird. Das ermöglicht es, Programme, die
+lange laufen (wie @code{mysqlhotcopy}), zu zwingen,
+@code{interactive_timeout} anstelle von @code{wait_timeout} zu benutzen.
+@item
+Zur Langsame-Anfragen-Log-Datei Zeit und Benutzernamen für jede geloggte
+Anfrage hinzugefügt. Wenn Sie @code{--log-long-format} benutzen, werden
+auch Anfragen, die keinen Index benutzen, geloggt, selbst wenn die Anfrage
+weniger als @code{long_query_time} Sekunden benötigt.
+@item
+Problem in @code{LEFT JOIN} behoben, was dazu führte, dass alle Spalten in
+einer Verweistabelle @code{NULL} waren.
+@item
+Problem bei der Benutzung von @code{NATURAL JOIN} ohne Schlüssel behoben.
+@item
+Bug bei der Benutzung eines mehrteiligen Schlüssels behoben, bei dem der
+erste Teil vom Typ @code{TEXT} oder @code{BLOB} war.
+@item
+@code{DROP} von temporären Tabellen wurde nicht in der
+Update-/Binär-Log-Datei gespeichert.
+@item
+Bug behoben, der bei @code{SELECT DISTINCT * ... LIMIT #} nur eine Zeile
+zurückgab.
+@item
+Bug im Assembler-Code in @code{strstr()} für sparc behoben und
+@file{global.h}-Header-Datei aufgeräumt, um ein Problem mit schlechtem
+Aliasing des Compilers zu vermeiden, der bei RedHat 7.0 beiliegt (berichtet
+von Trond Eivind Glomsrød).
+@item
+Die Option @code{--skip-networking} funktioniert jetzt sauber unter Windows
+NT.
+@item
+Lang ausstehender Bug in den @code{ISAM}-Tabellen behoben, wenn eine Zeile
+mit einer Länge von mehr als 65 KB um ein einzelnes Byte gekürzt wurde.
+@item
+Bug in @code{MyISAM} beim Laufenlassen mehrfacher Aktualisierungsprozesse
+auf dieselbe Tabelle behoben.
+@item
+Es wird zugelassen, dass @code{FLUSH TABLE tabelle} benutzt wird.
+@item
+@code{--replicate-ignore-table}, @code{--replicate-do-table},
+@code{--replicate-wild-ignore-table} und @code{--replicate-wild-do-table}
+hinzugefügt.
+@item
+Alle Log-Dateien so geändert, dass sie unseren eigenen
+@code{IO_CACHE}-Mechanismus anstelle von @code{FILE} benutzen, um
+Betriebssystemprobleme zu vermeiden, wenn zu viele Dateien offen sind.
+@item
+Optionen @code{--open-files} und @code{--timezone} für @code{safe_mysqld}
+hinzugefügt.
+@item
+Schweren Bug in @code{CREATE TEMPORARY TABLE ... SELECT ...} behoben.
+@item
+Problem mit @code{CREATE TABLE ... SELECT NULL} behoben.
+@item
+Variablen @code{large_file_support}, @code{net_read_timeout},
+@code{net_write_timeout} und @code{query_buffer_size} für @code{SHOW
+VARIABLES} hinzugefügt.
+@item
+Status-Variablen @code{created_tmp_files} und @code{sort_merge_passes} für
+@code{SHOW STATUS} hinzugefügt.
+@item
+Bug behoben, bei dem kein Index-Name nach der @code{FOREIGN KEY}-Definition
+zugelassen wurde.
+@item
+@code{TRUNCATE tabelle} als ein Synonym für @code{DELETE FROM tabelle}
+hinzugefügt.
+@item
+Bug in einer BDB-Schlüsselvergleichsfunktion beim Vergleich von
+Schlüsselteilen behoben.
+@item
+Variable @code{bdb_lock_max} für @code{mysqld} hinzugefügt.
+@item
+Weitere Tests zur Benchmark-Suite hinzugefügt.
+@item
+Überlauf-Bug im Client-Code bei der Benutzung von überlangen Datenbanknamen
+behoben.
+@item
+@code{mysql_connect()} bricht jetzt unter Linux ab, wenn der Server nicht
+in @code{timeout} Sekunden antwortet.
+@item
+@code{SLAVE START} funktionierte nicht, wenn Sie mit
+@code{--skip-slave-start} starteten und vorher nicht explizit @code{CHANGE
+MASTER TO} laufen ließen.
+@item
+Die Ausgabe von @code{SHOW MASTER STATUS} in Ordnung gebracht, damit sie
+konsistent mit @code{SHOW SLAVE STATUS} ist. (Sie hat jetzt kein
+Verzeichnis im Log-Namen.)
+@item
+@code{PURGE MASTER LOGS TO} hinzugefügt.
+@item
+@code{SHOW MASTER LOGS} hinzugefügt.
+@item
+@code{--safemalloc-mem-limit}-Option für @code{mysqld} hinzugefügt, um
+Speichermangel zu simulieren, wenn mit @code{--with-debug=full} kompiliert
+wurde.
+@item
+Mehrere Coredumps unter Bedingungen, in denen Arbeitsspeicher fehlt,
+behoben.
+@item
+@code{SHOW SLAVE STATUS} benutzte einen nicht initialisierten mutex, wenn
+der Slave noch nicht gestartet wurde.
+@item
+Bug in @code{ELT()} und @code{MAKE_SET()} behoben, wenn die Anfrage eine
+temporäre Tabelle benutzte.
+@item
+@code{CHANGE MASTER TO} ohne Angabe von @code{MASTER_LOG_POS} setzte es auf
+0 statt auf 4 und erreichte die magische Zahl im binären Master-Log.
+@item
+@code{ALTER TABLE ... ORDER BY ...}-Syntax hinzugefügt. Das erzeugt die
+Tabelle mit Zeilen in einer festgelegten Reihenfolge.
+@end itemize
+
+
+@node News-3.23.27, News-3.23.26, News-3.23.28, News-3.23.x
+@c German node Neuigkeiten-3.23.27
+@appendixsubsec Änderungen in Release 3.23.27
+
+@itemize @bullet
+@item
+Bug behoben, bei dem das automatische Reparieren von MyISAM-Tabellen
+manchmal fehlschlug, wenn die Daten-Datei beschädigt war.
+@item
+Bug in @code{SHOW CREATE} bei der Benutzung von
+@code{AUTO_INCREMENT}-Spalten behoben.
+@item
+BDB-Tabellen so geändert, dass sie die neue Vergleichsfunktion in Berkeley
+DB 3.2.3 benutzen.
+@item
+Sie können jetzt Unix-Sockets bei @code{mit-pThread} benutzen.
+@item
+Neuer latin5- (türkischer) Zeichensatz.
+@item
+Kleinere Portabilitätsbehebungen.
+@end itemize
+
+
+@node News-3.23.26, News-3.23.25, News-3.23.27, News-3.23.x
+@c German node Neuigkeiten-3.23.26
+@appendixsubsec Änderungen in Release 3.23.26
+
+@itemize @bullet
+@item
+@code{<>} funktioniert jetzt sauber mit @code{NULL}.
+@item
+Problem mit @code{SUBSTRING_INDEX()} und @code{REPLACE()} behoben (Patch
+von Alexunder Igonitchev).
+@item
+@code{CREATE TEMPORARY TABLE IF NOT EXISTS} gab keinen Fehler, wenn die
+Tabelle existierte.
+@item
+Wenn Sie keinen @code{PRIMARY KEY} in einer BDB-Tabelle erzeugen, wird ein
+versteckter @code{PRIMARY KEY} erzeugt.
+@item
+Nur-Lese-Schlüssel-Optimierung to BDB-Tabellen hinzugefügt.
+@item
+@code{LEFT JOIN} bevorzugte in manchen Fällen einen vollen Tabellen-Scan,
+wenn es keine @code{WHERE}-Klausel gab.
+@item
+Bei der Benutzung von @code{--log-slow-query} die Wartezeit auf eine Sperre
+nicht zählen.
+@item
+Bug im Sperr-Code unter Windows behoben, der dazu führte, dass der
+Schlüssel-Cache berichtete, dass die Schlüssel-Datei beschädigt sei, obwohl
+sie in Ordnung war.
+@item
+Automatische Reparatur von @code{MyISAM}-Tabellen, wenn Sie @code{mysqld}
+mit @code{--myisam-recover} starten, hinzugefügt.
+@item
+Das @code{TYPE=}-Schlüsselwort wurde von @code{CHECK} und @code{REPAIR}
+entfernt. Es wird zugelassen, dass @code{CHECK}-Optionen kombiniert werden.
+(Sie können immer noch @code{TYPE=} benutzen, aber die Benutzung wird nicht
+empfohlen.)
+@item
+Mutex-Bug im binären Replikations-Log behoben - lange
+Aktualisierungsanfragen konnten vom Slave nur teilweise gelesen werden,
+wenn er das zur falschen Zeit machte, was nicht schwerwiegend ist, aber zu
+einem Performance-verschlechternden erneuten Verbinden führte, sowie zu
+einer beunruhigenden Nachricht in der Fehler-Log-Datei.
+@item
+Das Format der Binär-Log-Datei wurde geändert - hinzugefügt wurden magische
+Zahl, Serverversion, Binlog-Version, Server-Kennung und Anfragen-Fehlercode
+für jedes Anfrage-Ereignis.
+@item
+Replikations-Thread vom Slave killt jetzt alle darnieder liegenden Threads
+vom selben Server.
+@item
+Lange Replikations-Benutzernamen wurden bislang nicht korrekt gehandhabt.
+@item
+@code{--replicate-rewrite-db}-Option zu @code{mysqld} hinzugefügt.
+@item
+@code{--skip-slave-start}-Option to @code{mysqld} hinzugefügt.
+@item
+Aktualisierungen, die einen Fehlercode erzeugten (wie @code{INSERT INTO
+foo(schluessel) values (1),(1)}) beendeten bislang irrtümlich den
+Slave-Thread.
+@item
+Optimierung von Anfragen, bei denen @code{DISTINCT} nur auf Spalten aus
+denselben Tabellen benutzt wird, hinzugefügt.
+@item
+Fließkommazahlen ohne Vorzeichen nach dem Exponent (wie 1e1) werden
+zugelassen.
+@item
+@code{SHOW GRANTS} zeigte nicht immer alle Spaltenberechtigungen.
+@item
+@code{--default-extra-file=#} für alle MySQL-Clients hinzugefügt.
+@item
+Spalten, auf die in @code{INSERT}-Statements verwiesen wird, werden nun
+sauber initialisiert.
+@item
+@code{UPDATE} funktioniert nicht immer, wenn es mit einem Bereich auf einem
+Timestamp benutzt wurde, der Teil des Schlüssels war, der benutzt wurde, um
+Zeilen zu finden.
+@item
+Bug in @code{FULLTEXT}-Index beim Einfügen einer @code{NULL}-Spalte
+behoben.
+@item
+@code{mkstemp()} wird jetzt anstelle von @code{tempnam()} benutzt. Basiert
+auf einem Patch von John Jones.
+@end itemize
+
+
+@node News-3.23.25, News-3.23.24, News-3.23.26, News-3.23.x
+@c German node Neuigkeiten-3.23.25
+@appendixsubsec Änderungen in Release 3.23.25
+
+@itemize @bullet
+@item
+@code{database} funktioniert als zweites Argument für @code{mysqlhotcopy}.
+@item
+@code{UMASK} und @code{UMASK_DIR} können jetzt oktal angegeben werden.
+@item
+@code{RIGHT JOIN}. Hierdurch wird @code{RIGHT} zu einem reservierten Wort.
+@item
+@code{@@@@IDENTITY} als ein Synonym für @code{LAST_INSERT_ID()}
+hinzugefügt, aus Gründen der Visual-Basic-Kompatibilität.)
+@item
+Bug in @code{myisamchk} und @code{REPAIR} bei der Benutzung von
+@code{FULLTEXT}-Indexen behoben.
+@item
+@code{LOAD DATA INFILE} funktioniert jetzt mit FIFOs (Patch von Toni L.
+Harbaugh-Blackford).
+@item
+@code{FLUSH LOGS} brach die Replikation ab, wenn Sie einen Log-Namen mit
+einer expliziten Erweiterung als Wert der @code{log-bin}-Option angaben.
+@item
+Bug in @code{MyISAM} mit komprimierten mehrteiligen Schlüsseln behoben.
+@item
+Absturz bei der Benutzung von @code{CHECK TABLE} unter Windows behoben.
+@item
+Bug, bei dem @code{FULLTEXT}-Index immer den koi8_ukr-Zeichensatz
+benutzten, behoben.
+@item
+Berechtigungsüberprüfung für @code{CHECK TABLE} in Ordnung gebracht.
+@item
+Der @code{MyISAM}-Reparatur-/Reindexierungs-Code benutzte nicht die
+@code{--tempdir}-Option für seine temporären Dateien.
+@item
+@code{BACKUP TABLE/RESTORE TABLE} hinzugefügt.
+@item
+Coredump auf @code{CHANGE MASTER TO} behoben, wenn der Slave keinen Master
+hatte, mit dem er startet.
+@item
+Falsche @code{time} in der Prozessliste für @code{Connect} des
+Slave-Threads in Ordnung gebracht.
+@item
+Der Slave loggt jetzt, wann er sich mit dem Master verbindet.
+@item
+Coredump-Bug beim Ausführen von @code{FLUSH MASTER} behoben, wenn man kein
+Dateinamens-Argument für @code{--log-bin} angab.
+@item
+Fehlende @file{ha_berkeley.x}-Dateien zu MySQL unter Windows hinzugefügt.
+@item
+Einige mutex-Bugs im Log-Code behoben, die zu Thread-Blockierungen führen
+konnten, wenn neue Log-Dateien nicht erzeugt werden konnten.
+@item
+Sperrzeit und Anzahl von ausgewählten bearbeiteten Zeilen zur
+Langsame-Anfragen-Log-Datei hinzugefügt.
+@item
+@code{--memlock}-Option für @code{mysqld}, um @code{mysqld} im
+Arbeitsspeicher auf Systemen mit dem @code{mlockall()}-Aufruf (wie in
+Solaris) zu sperren, hinzugefügt.
+@item
+@code{HEAP}-Tabellen benutzten Schlüssel nicht korrekt (Bug aus Version
+3.23.23).
+@item
+Bessere Unterstützung für @code{MERGE}-Tabellen (Schlüssel, Mapping,
+Erzeugung, Dokumentation und mehr) hinzugefügt. @xref{MERGE}.
+@item
+Bug in @code{mysqldump} aus Version 3.23 behoben, der dazu führte, dass
+einige @code{CHAR}-Spalten nicht in Anführungsstrichen standen.
+@item
+@code{analyze}, @code{check}, @code{optimize} und Reparatur-Code
+zusammengefasst.
+@item
+@code{OPTIMIZE TABLE} wird jetzt auf @code{REPAIR} mit Statistiken und
+Sortieren des Index-Baums gemappt. Das heißt, das es momentan nur auf
+@code{MyISAM}-Tabellen funktioniert.
+@item
+Einen pre-alloced Block zu root_malloc hinzugefügt, um weniger mallocs zu
+erhalten.
+@item
+Viele neue Statistik-Variablen hinzugefügt.
+@item
+@code{ORDER BY}-Bug bei BDB-Tabellen behoben.
+@item
+Warnungen entfernt, dass @code{mysqld} die @file{.pid}-Datei unter Windows
+nicht entfernen konnte.
+@item
+@code{--log-isam} zum Loggen von @strong{MyISAM}-Tabellen anstelle von
+isam-Tabellen abgeändert.
+@item
+@code{CHECK TABLE} funktioniert jetzt auch unter Windows.
+@item
+Datei-mutexes hinzugefügt, um @code{pwrite()} unter Windows sicher zu
+machen.
+@end itemize
+
+
+@node News-3.23.24, News-3.23.23, News-3.23.25, News-3.23.x
+@c German node Neuigkeiten-3.23.24
+@appendixsubsec Änderungen in Release 3.23.24
+
+@itemize @bullet
+@item
+@code{mysqld}-Variable @code{created_tmp_disk_tables} hinzugefügt.
+@item
+Um das verlässliche Dumpen und Wiederherstellen von Tabellen mit
+@code{TIMESTAMP(X)}-Spalten zu ermöglichen, berichtet MySQL jetzt Spalten
+mit @code{X} anders als 14 oder 8 als Zeichenketten.
+@item
+Sortierreihenfolge für latin1 abgeändert im Vergleich zu MySQL-Version vor
+3.23.23. Jede Tabelle mit @code{CHAR}-Spalten, die Zeichen mit ASCII-Werten
+größer als 128 enthalten darf, die vor Version 3.23.22 erzeugt oder
+geändert wurde, muss repariert werden!
+@item
+Kleines Speicherleck behoben, das in Version 3.23.22 beim Einfügen einer
+temporären Tabelle eingeführt wurde.
+@item
+Problem mit BDB-Tabellen und Lesen auf einem eindeutigen (nicht primären)
+Schlüssel behoben.
+@item
+Der win1251-Zeichensatz wurde wiederhergestellt (er ist jetzt nur als nicht
+empfohlen gekennzeichnet).
+@end itemize
+
+
+@node News-3.23.23, News-3.23.22, News-3.23.24, News-3.23.x
+@c German node Neuigkeiten-3.23.23
+@appendixsubsec Änderungen in Release 3.23.23
+
+@itemize @bullet
+@item
+Geänderte Sortierreihenfolge für 'deutsch'; Alle Tabellen mit 'deutscher'
+Sortierreihenfolge müssen mit @code{REPAIR TABLE} oder @code{myisamchk}
+repariert werden, bevor sie benutzt werden können!
+@item
+Option @code{--core-file} für @code{mysqld} hinzugefügt, um eine Core-Datei
+unter Linux zu erhalten, wenn @code{mysqld} durch das SIGSEGV-Signal
+stirbt.
+@item
+MySQL-Client @code{mysql} startet jetzt vorgabemäßig mit
+@code{--no-named-commands} (@code{-g}). Diese Option kann mit
+@code{--enable-named-commands} (@code{-G}) abgeschaltet werden. Das kann in
+manchen Fällen Inkompatibilitätsprobleme hervorrufen, zum Beispiel in
+SQL-Skripten, die benannte Befehle ohne Semikolon benutzen!
+Langformat-Befehle funktionieren immer noch von der ersten Zeile.
+@item
+Problem bei der Benutzung vieler anhängiger @code{DROP TABLE}-Statements
+zugleich behoben.
+@item
+Der Optimierer verwendete Schlüssel nicht korrekt bei der Benutzung von
+@code{LEFT JOIN} auf eine leere Tabelle.
+@item
+Kürzerer Hilfetext beim Aufruf von @code{mysqld} mit falschen Optionen.
+@item
+Nicht schwerwiegender @code{free()}-Bug in @code{mysqlimport} behoben.
+@item
+Bug in der @code{MyISAM}-Index-Handhabung von
+@code{DECIMAL}-/@code{NUMERIC}-Schlüsseln behoben.
+@item
+Bug beim gleichzeitigen Einfügen in @code{MyISAM}-Tabellen behoben; in
+manchen Zusammenhängen gab die Benutzung von @code{MIN(schluessel_teil)}
+oder @code{MAX(schluessel_teil)} eine leere Ergebnismenge zurück.
+@item
+@code{mysqlhotcopy} für die Benutzung der neuen @code{FLUSH TABLES
+tabellen_liste}-Syntax aktualisiert. Nur Tabellen, die gesichert werden,
+werden jetzt auf Platte zurückgeschrieben (flush).
+@item
+Verhalten von @code{--enable-thread-safe-client} so geändert, dass sowohl
+nicht gethreadete (@code{-lmysqlclient}) als auch gethreadete
+(@code{-lmysqlclient_r}) Bibliotheken eingebaut werden. Benutzer, die gegen
+ein gethreadetes @code{-lmysqlclient} linkten, müssen jetzt gegen
+@code{libmysqlclient_r} linken.
+@item
+Atomischer @code{RENAME}-Befehl hinzugefügt.
+@item
+Einträge mit @code{NULL} werden in @code{COUNT(DISTINCT ...)} nicht
+gezählt.
+@item
+@code{ALTER TABLE}, @code{LOAD DATA INFILE} auf leere Tabellen und
+@code{INSERT ... SELECT ...} auf leere Tabellen so geändert, dass nicht
+eindeutige Indexe in einem separaten Stapellauf mit Sortieren erzeugt
+werden. Das macht die genannten Aufrufe viel schneller, wenn Sie viele
+Indexe haben.
+@item
+@code{ALTER TABLE} loggt jetzt die zuerst benutzte insert_id korrekt.
+@item
+Absturz beim Hinzufügen eines Vorgabewerts zu einer @code{BLOB}-Spalte
+behoben.
+@item
+Bug bei @code{DATE_ADD/DATE_SUB} behoben, der eine DATETIME anstelle eines
+DATE zurückgab.
+@item
+Problem mit dem Thread-Cache behoben, der dazu führte, dass einige Threads
+als @code{***DEAD***} in @code{SHOW PROCESSLIST} erschienen.
+@item
+Eine Sperre in unserem thr_rwlock-Code beseitigt, die dazu führen konnte,
+dass SELECTs, die zur selben Zeit laufen wie gleichzeitige Einfügevorgänge,
+abstürzen. Das betrifft nur Systeme, die nicht den
+@code{pthread_rwlock_rdlock}-Code haben.
+@item
+Beim Löschen von Zeilen mit einem nicht eindeutigen Schlüssel in einer
+HEAP-Tabelle wurden nicht immer alle Zeilen gelöscht.
+@item
+Bug im Bereichsoptimierer für HEAP-Tabellen bei Suchen auf einem Teil-Index
+behoben.
+@item
+@code{SELECT} auf Teilschlüsseln funktioniert jetzt bei BDB-Tabellen.
+@item
+@code{INSERT INTO bdb_tabelle ... SELECT} funktioniert jetzt bei
+BDB-Tabellen.
+@item
+@code{CHECK TABLE} aktualisiert jetzt Schlüsselstatistiken für die Tabelle.
+@item
+@code{ANALYZE TABLE} aktualisiert jetzt nur Tabellen, die seit dem letzten
+@code{ANALYZE} geändert wurden. Beachten Sie, dass das ein neues Feature
+ist, und dass Tabellen nicht als analysiert gekennzeichnet werden, bis sie
+auf irgend eine Weise mit Version 3.23.23 oder neuer aktualisiert wurden.
+Bei älteren Tabellen müssen Sie @code{CHECK TABLE} ausführen, um die
+Schlüsselverteilung zu aktualisieren.
+@item
+Einige kleinere Berechtigungsprobleme bei @code{CHECK}, @code{ANALYZE},
+@code{REPAIR} und @code{SHOW CREATE} behoben.
+@item
+@code{CHANGE MASTER TO}-Befehl hinzugefügt.
+@item
+@code{FAST}-, @code{QUICK}- @code{EXTENDED}-Überprüfungsarten zu
+@code{CHECK TABLES} hinzugefügt.
+@item
+@code{myisamchk} abgeändert, so dass @code{--fast} und
+@code{--check-changed-tables} auch bei @code{--sort-index} und
+@code{--analyze} berücksichtigt werden.
+@item
+Schwerwiegenden Bug in @code{LOAD TABLE FROM MASTER} behoben, bei dem die
+Tabelle während des Neuaufbaus des Indexes nicht gesperrt wurde.
+@item
+@code{LOAD DATA INFILE} brach die Replikation ab, wenn die Datenbank aus
+der Replikation ausgeschlossen war.
+@item
+Mehr Variablen zu @code{SHOW SLAVE STATUS} und @code{SHOW MASTER STATUS}
+hinzugefügt.
+@item
+@code{SLAVE STOP} gibt jetzt solange nichts zurück, bis der Thread
+tatsächlich beendet ist.
+@item
+Volltextsuche mit der @code{MATCH}-Funktion und @code{FULLTEXT}-Indextyp
+hinzugefügt (für MyISAM-Dateien). Das macht @code{FULLTEXT} zu einem
+reservierten Wort.
+@end itemize
+
+
+@node News-3.23.22, News-3.23.21, News-3.23.23, News-3.23.x
+@c German node Neuigkeiten-3.23.22
+@appendixsubsec Änderungen in Release 3.23.22
+
+@itemize @bullet
+@item
+@code{lex_hash.h} wird jetzt für jede MySQL-Distribution korrekt erzeugt.
+@item
+@code{MASTER} und @code{COLLECTION} sind jetzt reservierte Wörter.
+@item
+Die Log-Datei, die von @code{--slow-query-log} erzeugt wird, enthielt nicht
+die gesamten Anfragen.
+@item
+Offene Transaktionen in BDB-Tabellen werden jetzt nicht mehr zurückgerollt,
+wenn die Verbindung unerwartet geschlossen wird.
+@item
+Workaround für einen Bug in @code{gcc} 2.96 (intel) und @code{gcc} 2.9
+(Ia64) in @code{gen_lex_hash.c} hinzugefügt.
+@item
+Speicherleck in der Client-Bibliothek bei der Benutzung von @code{host=} in
+der @code{my.cnf}-Datei behoben.
+@item
+Funktionen optimiert, die Stunden/Minuten/Sekunden bearbeiten.
+@item
+Bug beim Vergleich des Ergebnisses von @code{DATE_ADD()}/@code{DATE_SUB()}
+mit einer Zahl behoben.
+@item
+Bedeutung von @code{-F, --fast} für @code{myisamchk} geändert. Option
+@code{-C, --check-only-changed} für @code{myisamchk} hinzugefügt.
+@item
+@code{ANALYZE tabelle} zum Aktualisieren von Schlüsselstatistiken für
+Tabellen hinzugefügt.
+@item
+Binäreinheiten @code{0x...} abgeändert, so dass sie vorgabemäßig als
+Ganzzahlen betrachtet werden.
+@item
+Fehlerbehebung für SCO und @code{SHOW PROCESSLIST}.
+@item
+@code{auto-rehash} beim erneuten Verbinden für den @code{mysql}-Client
+hinzugefügt.
+@item
+Neu eingeführten Bug in @code{MyISAM} behoben, bei dem die Index-Datei
+nicht größer als 64 MB werden durfte.
+@item
+@code{SHOW MASTER STATUS} und @code{SHOW SLAVE STATUS} hinzugefügt.
+@end itemize
+
+
+@node News-3.23.21, News-3.23.20, News-3.23.22, News-3.23.x
+@c German node Neuigkeiten-3.23.21
+@appendixsubsec Änderungen in Release 3.23.21
+
+@itemize @bullet
+@item
+@code{mysql_character_set_name(MYSQL *mysql)}-Funktion zur MySQL-C-API
+hinzugefügt.
+@item
+Update-Log-Datei @code{ASCII 0}-sicher gemacht.
+@item
+@code{mysql_config}-Skript hinzugefügt.
+@item
+Problem bei der Benutzung von @code{<} oder @code{>} mit einer CHAR-Spalte,
+die nur teilweise indexiert war, behoben.
+@item
+Man erhielt einen Coredump, wenn die Log-Datei nicht vom MySQL-Benutzer
+lesbar war.
+@item
+@code{mysqladmin} so geändert, dass es die @code{CREATE
+DATABASE}/@code{DROP DATABASE}-Befehle anstelle der alten, nicht
+empfohlenen API-Aufrufe benutzt.
+@item
+@code{chown}-Warnung in @code{safe_mysqld} in Ordnung gebracht.
+@item
+Bug in @code{ORDER BY} behoben, der in Version 3.23.19 eingeführt wurde.
+@item
+@code{DELETE FROM tabelle} wird nur dann optimiert, ein Löschen und
+Neuerzeugen der Tabelle auszuführen, wenn man sich im
+@code{AUTOCOMMIT}-Modus befindet (benötigt für BDB-Tabellen).
+@item
+Zusätzliche Prüfungen hinzugefügt, um Index-Beschädigung zu vermeiden, wenn
+die @code{ISAM}/@code{MyISAM}-Index-Dateien während eines
+@code{INSERT}/@code{UPDATE} voll werden.
+@item
+@code{myisamchk} aktualisierte die Zeilenprüfsumme nicht korrekt, wenn es
+mit @code{-ro} benutzt wurde (sondern gab nur bei nachfolgenden Läufen eine
+Warnung aus).
+@item
+Bug in @code{REPAIR TABLE} behoben, so dass es bei Tabellen ohne Indexe
+funktioniert.
+@item
+Puffer-Überlauf in @code{DROP DATABASE} behoben.
+@item
+@code{LOAD TABLE FROM MASTER} ist ausreichend ohne Bugs, um es als Feature
+vorstellen zu können.
+@item
+@code{MATCH} und @code{AGAINST} sind jetzt reservierte Wörter.
+@end itemize
+
+
+@node News-3.23.20, News-3.23.19, News-3.23.21, News-3.23.x
+@c German node Neuigkeiten-3.23.20
+@appendixsubsec Änderungen in Release 3.23.20
+
+@itemize @bullet
+@item
+Bug in Version 3.23.19 behoben; @code{DELETE FROM tabelle} entfernte die
+.frm-Datei.
+@item
+@code{SHOW CREATE TABLE}.
+@end itemize
+
+
+@node News-3.23.19, News-3.23.18, News-3.23.20, News-3.23.x
+@c German node Neuigkeiten-3.23.19
+@appendixsubsec Änderungen in Release 3.23.19
+
+@itemize @bullet
+@item
+Copyright für alle Dateien zu GPL für den Server-Code und die
+Dienstprogramme und LGPL für die Client-Bibliotheken geändert.
+@item
+Bug behoben, bei dem nicht alle übereinstimmenden Zeilen bei einer
+@code{MyISAM}-Tabelle aktualisiert wurden, wenn man eine Aktualisierung
+basierend auf einem Schlüssel auf eine Tabelle mit vielen Schlüsseln
+durchführte, und sich einige Schlüsselwerte änderten.
+@item
+Die Linux-MySQL-RPMs und -Binärdateien werden jetzt bei einer
+Linux-Thread-Version statisch gelinkt, die schnellere mutex-Handhabung bei
+der Benutzung mit MySQL hat.
+@item
+@code{ORDER BY} kann jetzt @code{REF}-Schlüssel benutzen, um eine
+Untermenge von Zeilen zu finden, die sortiert werden müssen.
+@item
+Der Name von @code{print_defaults} wurde in @code{my_print_defaults}
+geändert, um Namenskonflikte zu vermeiden.
+@item
+@code{NULLIF()} funktioniert jetzt gemäß ANSI-SQL99.
+@item
+@code{net_read_timeout} und @code{net_write_timeout} als Startparameter für
+@code{mysqld} hinzugefügt.
+@item
+Bug behoben, der den Index bei der Ausführung von @code{myisamchk
+--sort-records} auf eine Tabelle mit Präfix-komprimiertem Index zerstörte.
+@item
+pack_isam und myisampack zur Standard-MySQL-Distribution hinzugefügt.
+@item
+Die Syntax @code{BEGIN WORK} hinzugefügt (dasselbe wie @code{BEGIN}).
+@item
+Coredump-Bug bei der Benutzung von @code{ORDER BY} auf
+@code{CONV()}-Ausdruck behoben.
+@item @code{LOAD TABLE FROM MASTER} hinzugefügt.
+@item @code{FLUSH MASTER} und @code{FLUSH SLAVE} hinzugefügt.
+@item Großes/kleines 'endian'-Problem in der Replikation behoben.
+@end itemize
+
+
+@node News-3.23.18, News-3.23.17, News-3.23.19, News-3.23.x
+@c German node Neuigkeiten-3.23.18
+@appendixsubsec Änderungen in Release 3.23.18
+
+@itemize @bullet
+@item
+Problem aus Version 3.23.17 bei der Auswahl eines Zeichensatzes auf der
+Client-Seite behoben.
+@item
+@code{FLUSH TABLES with READ LOCK} geändert, so dass es eine globale Sperre
+macht, die für das Herstellen einer Kopie der MySQL-Daten-Dateien geeignet
+ist.
+@item
+@code{CREATE TABLE ... SELECT ... PROCEDURE} funktioniert jetzt.
+@item
+Interne temporäre Tabellen benutzen jetzt einen komprimierten Index bei der
+Benutzung von @code{GROUP BY} auf @code{VARCHAR/CHAR}-Spalten.
+@item
+Problem behoben beim Sperren derselbe Tabelle mit einer @code{READ}- und
+einer @code{WRITE}-Sperre.
+@item
+Problem mit myisamchk und @code{RAID}-Tabellen behoben.
+@end itemize
+
+
+@node News-3.23.17, News-3.23.16, News-3.23.18, News-3.23.x
+@c German node Neuigkeiten-3.23.17
+@appendixsubsec Änderungen in Release 3.23.17
+
+@itemize @bullet
+@item
+Bug in @code{find_in_set()} behoben, wenn das erste Argument @code{NULL}
+war.
+@item
+Tabellensperren für Berkeley-DB hinzugefügt.
+@item
+Bug bei @code{LEFT JOIN} und @code{ORDER BY} behoben, bei dem die erste
+Tabelle nur eine übereinstimmende Zeile hatte.
+@item
+4 @code{my.cnf}-Beispiel-Dateien im @file{Support-files}-Verzeichnis
+hinzugefügt.
+@item
+@code{duplicated key}-Problem bei der Ausführung großer @code{GROUP BY}s
+behoben. (Dieser Bug wurde wahrscheinlich in Version 3.23.15 eingeführt).
+@item
+Syntax für @code{INNER JOIN} geändert, um ANSI-SQL zu entsprechen.
+@item
+@code{NATURAL JOIN}-Syntax hinzugefügt.
+@item
+Viele Korrekturen in der @code{BDB}-Schnittstelle.
+@item
+Handhabung von @code{--no-defaults} und @code{--defaults-file} für
+@code{safe_mysqld.sh} und @code{mysql_install_db.sh} hinzugefügt.
+@item
+Bug beim Lesen komprimierter Tabellen mit vielen Threads behoben.
+@item
+@code{USE INDEX} funktioniert jetzt mit @code{PRIMARY}-Schlüsseln.
+@item
+@code{BEGIN}-Statement geändert, so dass es eine Transaktion im
+@code{AUTOCOMMIT}-Modus startet.
+@item
+Symbolische-Links-Unterstützung für Windows.
+@item
+Protokoll geändert, so dass der Client weiß, ob der Server im AUTOCOMMIT-
+Modus ist und ob es eine anhängige Transaktion gibt. Wenn das der Fall ist,
+gibt die Client-Bibliothek einen Fehler aus, bevor sie sich wieder mit dem
+Server verbindet, damit der Client weiß, dass der Server ein Rollback
+durchgeführt hat. Das Protokoll ist noch abwärtskompatibel mit den alten
+Clients.
+@item
+@code{KILL} funktioniert jetzt auf einem Thread, der durch ein 'Schreiben'
+auf einen toten Client gesperrt ist.
+@item
+Speicherleck im Replikations-Slave-Thread behoben.
+@item
+Neue Option @code{log-slave-updates} hinzugefügt, die das
+Hintereinanderhängen im Kreis (Daisy-Chaining, 'Ringelrei') von Slaves
+erlaubt.
+@item
+Compile-Fehler auf FreeBSD und anderen Systemen behoben, auf denen
+@code{pthread_t} nicht dasselbe wie @code{int} ist.
+@item
+Herunterfahren des Masters bricht den Slave-Thread nicht mehr ab.
+@item
+Race-Bedingung im @code{INSERT DELAYED}-Code beim Ausführen von @code{ALTER
+TABLE} behoben.
+@item
+Blockierungsüberprüfung für @code{INSERT DELAYED} hinzugefügt.
+@end itemize
+
+
+@node News-3.23.16, News-3.23.15, News-3.23.17, News-3.23.x
+@c German node Neuigkeiten-3.23.16
+@appendixsubsec Änderungen in Release 3.23.16
+
+@itemize @bullet
+@item
+Option @code{TYPE=QUICK} für @code{CHECK} und @code{REPAIR} hinzugefügt.
+@item
+Bug in @code{REPAIR TABLE} behoben, wenn die Tabelle durch einen anderen
+Thread in Benutzung war.
+@item
+Einen Thread-Cache hinzugefügt, um zu ermöglichen, MySQL mit @code{gdb} zu
+debuggen, wenn man viele erneute Verbindungen durchführt. Das verbessert
+auch Systeme, auf denen man keine persistenten Verbindungen benutzen kann.
+@item
+Viele Korrekturen in der Berkeley-DB-Schnittstelle.
+@item
+@code{UPDATE IGNORE} bricht jetzt nicht mehr ab, wenn eine Aktualisierung
+zu einem @code{DUPLICATE_KEY}-Fehler führt.
+@item
+@code{CREATE TEMPORARY TABLE}-Befehle werden in die Update-Log-Datei
+geschrieben.
+@item
+Bug bei der Handhabung von maskierten IP-Nummern in den
+Berechtigungstabellen behoben.
+@item
+Bug mit @code{delayed_key_writes}-Tabellen und @code{CHECK TABLE} behoben.
+@item
+@code{replicate-do-db} und @code{replicate-ignore-db}-Optionen hinzugefügt,
+um auf Datenbanken zu beschränken, die repliziert werden.
+@item
+@code{SQL_LOG_BIN}-Option hinzugefügt.
+@end itemize
+
+
+@node News-3.23.15, News-3.23.14, News-3.23.16, News-3.23.x
+@c German node Neuigkeiten-3.23.15
+@appendixsubsec Änderungen in Release 3.23.15
+
+@itemize @bullet
+@item
+Um @code{mysqld} als @code{root} zu starten, müssen Sie jetzt die @code{--
+user=root}-Option benutzen.
+@item
+Schnittstelle zu Berkeley-DB hinzugefügt. (Diese funktioniert noch nicht
+richtig. Spielen Sie mit ihr auf eigenes Risiko herum!)
+@item
+Replikation zwischen Master und Slaves hinzugefügt.
+@item
+Bug behoben, bei dem ein anderer Thread eine Sperre stehlen konnte, wenn
+ein Thread eine Sperre auf eine Tabelle hatte und einen @code{FLUSH
+TABLES}-Befehl ausführte.
+@item
+Die @code{slow_launch_time}-Variable und die
+@code{slow_launch_thread}-Status-Variable zu @code{mysqld} hinzugefügt.
+Diese können mit @code{mysqladmin variables} und @code{mysqladmin
+extended-status} betrachtet werden.
+@item
+Funktionen @code{INET_NTOA()} und @code{INET_ATON()} hinzugefügt.
+@item
+Der vorgabemäßige Typ von @code{IF()} hängt jetzt vom zweiten und dritten
+Argument ab und nicht nur vom zweiten.
+@item
+Fall behoben, bei dem @code{myisamchk} beim Versuch, eine Tabelle zu
+reparieren, in eine Schleife geraten konnte.
+@item
+@code{INSERT DELAYED} nicht in die Update-Log-Datei schreiben, wenn
+@code{SQL_LOG_UPDATE=0}.
+@item
+Problem mit @code{REPLACE} auf @code{HEAP}-Tabellen behoben.
+@item
+Mögliche Zeichensätze und Zeitzone zu @code{SHOW VARIABLES} hinzugefügt.
+@item
+Bug im Sperr-Code behoben, der zu Sperrproblemen bei gleichzeitigen
+Einfügevorgängen unter hoher Last führen konnte.
+@item
+Problem bei @code{DELETE} vieler Zeilen auf eine Tabelle mit komprimierten
+Schlüsseln behoben, bei dem MySQL den Index scannte, um Zeilen zu finden.
+@item
+Problem mit @code{CHECK} auf Tabelle mit gelöschten Schlüsselblöcken
+behoben.
+@item
+Bug beim Neuverbinden (auf der Client-Seite) behoben, bei dem in manchen
+Situationen Speicher nicht freigegeben wurde.
+@item
+Probleme in der Update-Log-Datei bei der Benutzung von
+@code{LAST_INSERT_ID()} zum Aktualisieren einer Tabelle mit einem
+auto_increment-Schlüssel behoben.
+@item
+Funktion @code{NULLIF()} hinzugefügt.
+@item
+Bug bei der Benutzung von @code{LOAD DATA INFILE} auf eine Tabelle mit
+@code{BLOB/TEXT}-Spalten behoben.
+@item
+MyISAM optimiert, um es beim Einfügen von Schlüsseln in sortierter
+Reihenfolge schneller zu machen.
+@item
+@code{EXPLAIN SELECT ...} gibt jetzt auch aus, ob MySQL eine temporäre
+Tabelle oder Dateisortieren verwendet, wenn das @code{SELECT} aufgelöst
+wird.
+@item
+Optimierung hinzugefügt, um @code{ORDER BY}-Teile zu überspringen, bei
+denen der Teil ein konstanter Ausdruck im @code{WHERE}-Teil ist. Indexe
+können jetzt benutzt werden, selbst wenn das @code{ORDER BY} nicht genau
+mit dem Index übereinstimmt, solange alle nicht benutzten Index-Teile und
+alle zusätzlichen @code{ORDER BY}-Spalten Konstanten in der
+@code{WHERE}-Klausel sind. @xref{MySQL indexes}.
+@item
+@code{UPDATE} und @code{DELETE} auf einen gesamten eindeutigen Schlüssel im
+@code{WHERE}-Teil ist jetzt schneller als vorher.
+@item
+@code{RAID_CHUNKSIZE} so geändert, dass es in 1024 Bytes inkrementiert.
+@item
+Coredump in LOAD_FILE(NULL) behoben.
+@end itemize
+
+
+@node News-3.23.14, News-3.23.13, News-3.23.15, News-3.23.x
+@c German node Neuigkeiten-3.23.14
+@appendixsubsec Änderungen in Release 3.23.14
+
+@itemize @bullet
+@item
+Bug in @code{CONCAT()} behoben, bei dem eins der Argumente eine Funktion
+war, die ein verändertes Argument zurückgab.
+@item
+Kritischen Bug in @code{myisamchk} behoben, wobei es den Header in der
+Index-Datei aktualisierte, wenn man die Tabelle nur prüfte. Das brachte den
+@code{mysqld}-Daemon durcheinander, wenn er dieselbe Tabelle zur gleichen
+Zeit aktualisierte. Jetzt wird der Status in der Index-Datei nur dann
+aktualisiert, wenn man @code{--update-state} benutzt. Bei älteren
+@code{myisamchk}-Versionen sollten Sie @code{--read-only} benutzen, wenn
+Sie Tabellen nur prüfen, wenn es auch nur die geringste Chance gibt, dass
+der @code{mysqld}-Server zur gleichen Zeit auf der Tabelle arbeitet!
+@item
+@code{DROP TABLE} wird nicht mehr in der Update-Log-Datei geloggt.
+@item
+Problem beim Suchen auf @code{DECIMAL()}-Schlüsselfeld behoben, wenn die
+Spalte Daten mit führenden Nullen enthielt.
+@item
+Bug in @code{myisamchk} behoben, wenn auto_increment nicht der erste
+Schlüssel ist.
+@item
+@code{DATETIME} wird im ISO-8601-Format zugelassen: 2000-03-12T12:00:00
+@item
+Dynamische Zeichensätze hinzugefügt. Eine @code{mysqld}-Binärdatei kann
+jetzt viele unterschiedliche Zeichensätze handhaben (welche, können Sie
+beim Start von @code{mysqld} angeben).
+@item
+Befehl @code{REPAIR TABLE} hinzugefügt.
+@item
+C-API-Funktion @code{mysql_thread_safe()} hinzugefügt.
+@item
+@code{UMASK_DIR}-Umgebungsvariable hinzugefügt.
+@item
+Funktion @code{CONNECTION_ID()} hinzugefügt.
+@item
+Bei der Benutzung von @code{=} auf @code{BLOB}- oder @code{VARCHAR
+BINARY}-Schlüsseln, bei denen nur ein Teil der Spalte indexiert war, wurde
+nicht die gesamte Spalte der Ergebniszeile verglichen.
+@item
+Problembehebung für sjis-Zeichensatz und @code{ORDER BY}.
+@item
+Beim Laufenlassen im ANSI-Modus wird nicht mehr zugelassen, dass Spalten
+benutzt werden, die nicht im @code{GROUP BY}-Teil angegeben wurden.
+@end itemize
+
+
+@node News-3.23.13, News-3.23.12, News-3.23.14, News-3.23.x
+@c German node Neuigkeiten-3.23.13
+@appendixsubsec Änderungen in Release 3.23.13
+
+@itemize @bullet
+@item
+Problem behoben bei der Ausführung von Sperren auf dieselbe Tabelle mehr
+als zweimal im selben @code{LOCK TABLE}-Befehl. Dadurch wurde das Problem
+behoben, das man bekam, wenn man test-ATIS test mit @code{--fast} oder
+@code{--check-only-changed} laufen ließ.
+@item
+Option @code{SQL_Puffer_RESULT} für @code{SELECT} hinzugefügt.
+@item
+Leerzeichen am Ende von Double-/Float-Zahlen in Ergebnissen aus temporären
+Tabellen entfernt.
+@code{CHECK TABLE}-Befehl hinzugefügt.
+@item
+Änderungen für MyISAM in Version 3.23.12 hinzugefügt, die wegen
+CVS-Problemen nicht in die Quelldistribution gelangten.
+@item
+Bug behoben, so dass @code{mysqladmin shutdown} darauf wartet, dass der
+lokale Server herunter fährt.
+@item
+Mögliche Endlosschleife bei der Zeitstempel-Berechnung repariert.
+@item
+@code{print_defaults} für die @file{.rpm}-Dateien hinzugefügt.
+@code{mysqlbug} aus der Client-@file{.rpm}-Datei entfernt.
+@end itemize
+
+
+@node News-3.23.12, News-3.23.11, News-3.23.13, News-3.23.x
+@c German node Neuigkeiten-3.23.12
+@appendixsubsec Änderungen in Release 3.23.12
+
+@itemize @bullet
+@item
+Bug in @code{MyISAM} behoben, bei dem @code{REPLACE ... SELECT ...} eine
+beschädigte Tabelle ergeben konnte.
+@item
+Bug in @code{myisamchk} behoben, bei dem der auto_increment-Wert falsch
+zurückgesetzt wurde.
+@item
+VIELE Patches für Linux Alpha. MySQL scheint mittlerweile auf Linux Alpha
+relativ stabil zu laufen.
+@item
+@code{DISTINCT} auf @code{HEAP} temporäre Tabellen so geändert, dass
+gehashte Schlüssel verwendet werden, um doppelte Zeilen (Duplikate) schnell
+zu finden. Das betrifft meistens Anfragen des Typs @code{SELECT DISTINCT
+... GROUP BY ...}. Das behebt ein Problem, bei dem nicht alle Duplikate in
+Anfragen des genannten Typs entfernt wurden. Zusätzlich ist der neue Code
+VIEL schneller.
+@item
+Patches hinzugefügt, damit MySQL auf Mac OS X kompiliert.
+@item
+Option @code{IF NOT EXISTS} für @code{CREATE DATABASE} hinzugefügt.
+@item
+Optionen @code{--all-databases} und @code{--databases} für @code{mysqldump}
+hinzugefügt, um das Dumpen vieler Datenbanken zugleich zu ermöglichen.
+@item
+Bug im komprimierten @code{DECIMAL()}-Index in @code{MyISAM}-Tabellen
+behoben.
+@item
+Bug beim Speichern von 0 in ein Timestamp-Feld behoben.
+@item
+Beim Ausführen von @code{mysqladmin shutdown} auf eine lokale Verbindung
+wartet @code{mysqladmin} jetzt, bis die PID-Datei entfernt ist, bevor es
+sich beendet.
+@item
+Coredump bei einigen @code{COUNT(DISTINCT ...)}-Anfragen behoben.
+@item
+@code{myisamchk} funktioniert jetzt sauber bei RAID-Tabellen.
+@item
+Problem bei @code{LEFT JOIN} und @code{schluessel_feld IS NULL} behoben.
+@item
+Bug in @code{net_clear()} behoben, der den Fehler @code{Aborted connection}
+in MySQL-Clients ausgeben konnte.
+@item
+Optionen @code{USE INDEX (schluessel_liste)} und @code{IGNORE INDEX
+(schluessel_liste)} als Join-Parameter in @code{SELECT} hinzugefügt.
+@item
+@code{DELETE} und @code{RENAME} sollten jetzt auf @code{RAID}-Tabellen
+funktionieren.
+@end itemize
+
+
+@node News-3.23.11, News-3.23.10, News-3.23.12, News-3.23.x
+@c German node Neuigkeiten-3.23.11
+@appendixsubsec Änderungen in Release 3.23.11
+
+@itemize @bullet
+@item
+@code{ALTER TABLE tabelle ADD (feld_liste)}-Syntax wird zugelassen.
+@item
+Problem mit dem Optimierer behoben, der manchmal falsche Schlüssel
+benutzte.
+@item
+@code{GRANT/REVOKE ALL PRIVILEGES} betrifft jetzt nicht mehr @code{GRANT
+OPTION}.
+@item
+Zusätzliche Klammer (@code{)}) aus der Ausgabe von @code{SHOW GRANTS}
+entfernt.
+@item
+Problem beim Speichern von Zahlen in Timestamps behoben.
+@item
+Problem mit Zeitzonen behoben, die einen Halbstunden-Offset haben.
+@item
+Syntax @code{UNIQUE INDEX} in @code{CREATE}-Statements wird jetzt
+zugelassen.
+@item
+@code{mysqlhotcopy} hinzugefügt. Das ist ein schnelles
+Online-Datensicherungsdienstprogramm für lokale MySQL-Datenbanken. Von Tim
+Bunce.
+@item
+Neues, sichereres @code{mysqlaccess} hinzugefügt. Dank an Steve Harvey
+hierfür.
+@item
+Optionen @code{--i-am-a-dummy} und @code{--safe-updates} für @code{mysql}
+hinzugefügt.
+@item
+Variablen @code{select_limit} und @code{max_join_size} für @code{mysql}
+hinzugefügt.
+@item
+SQL-Variablen @code{SQL_MAX_JOIN_SIZE} und @code{SQL_SAFE_UPDATES}
+hinzugefügt.
+@item
+@code{READ LOCAL}-Sperre hinzugefügt, die die Tabelle nicht für
+gleichzeitige Einfügevorgänge sperrt (das wird von @code{mysqldump}
+benutzt).
+@item
+@code{LOCK TABLES ... READ} läßt keine gleichzeitigen Einfügevorgänge mehr
+zu.
+@item
+Option @code{--skip-delay-key-write} für @code{mysqld} hinzugefügt.
+@item
+Sicherheitsproblem im Protokoll betreffend Passwortüberprüfung behoben.
+@item
+@code{_rowid} kann jetzt als Alias für eine eindeutig indexierte Spalte vom
+Typ Ganzzahl benutzt werden.
+@item
+Zurück-Blockieren (Back Blocking) für @code{SIGPIPE} beim Kompilieren mit
+@code{--thread-safe-clients} hinzugefügt, um Dinge für alte Clients sicher
+zu machen.
+@end itemize
+
+
+@node News-3.23.10, News-3.23.9, News-3.23.11, News-3.23.x
+@c German node Neuigkeiten-3.23.10
+@appendixsubsec Änderungen in Release 3.23.10
+
+@itemize @bullet
+@item
+Bug in Version 3.23.9 behoben, bei dem Speicher nicht korrekt freigegeben
+wurde, wenn man @code{LOCK TABLES} ausführte.
+@end itemize
+
+
+@node News-3.23.9, News-3.23.8, News-3.23.10, News-3.23.x
+@c German node Neuigkeiten-3.23.9
+@appendixsubsec Änderungen in Release 3.23.9
+
+@itemize @bullet
+@item
+Problem behoben, dass betroffene Anfragen Berechnungen auf
+Gruppenfunktionen durchführten.
+@item
+Problem mit timestamps und @code{INSERT DELAYED} behoben.
+@item
+@code{datum_spalte BETWEEN konstanten_datum AND konstanten_datum}
+funktioniert.
+@item
+Problem behoben, wenn man nur eine 0 zu @code{NULL} in einer Tabelle mit
+@code{BLOB/TEXT}-Spalten änderte.
+@item
+Bug im Bereichsoptimierer bei der Benutzung von vielen Schlüsselteilen und
+/ oder den mittleren Schlüsselteilen behoben: @code{WHERE K1=1 and K3=2 and
+(K2=2 and K4=4 or K2=3 and K4=5)}
+@item
+Befehl @code{source} für @code{mysql} hinzugefügt, um Lesen von
+Stapeldateien innerhalb des @code{mysql}-Clients zu ermöglichen.
+Original-Patch von Matthew Vanecek.
+@item
+Kritisches Problem mit der @code{WITH GRANT OPTION}-Option behoben.
+@item
+Keinen unnötigen @code{GRANT}-Fehler bei der Benutzung von Tabellen von
+vielen Datenbanken in derselben Anfrage ausgeben.
+@item
+VIO-Wrapper (benötigt für SSL-Unterstützung) hinzugefügt. Von Andrei
+Errapart und Tõnu Samuel).
+@item
+Optimiererproblem bei @code{SELECT} bei der Benutzung von vielen
+überlappenden Indexen behoben. MySQL sollte jetzt in der Lage sein,
+Schlüssel noch besser auszusuchen, wenn es viele Schlüssel zur Auswahl
+gibt.
+@item
+Optimierer so geändert, dass er einen Bereichsschlüssel anstelle eines
+Verweisschlüssels bevorzugt, wenn der Bereichsschlüssel mehr Spalten als
+der Verweisschlüssel benutzen kann (der nur Spalten mit = verwenden
+kann). Folgender Anfragentyp beispielsweise sollte jetzt schneller sein:
+@code{SELECT * from schluessel_teil_1=konstante und schluessel_teil_2 >
+konstante2}
+@item
+Bug behoben, bei dem eine Änderung aller @code{VARCHAR}-Spalten in
+@code{CHAR}-Spalten den Spaltentyp nicht von dynamisch auf fest änderte.
+@item
+Fließkomma-Ausnahmefehler für FreeBSD abgeschaltet, um Coredump beim
+Ausführen von @code{SELECT floor(pow(2,63))} zu vermeiden.
+@item
+@code{mysqld}-Startoption @code{--delay-key-write} in
+@code{--delay-key-write-for-all-tables} geändert.
+@item
+@code{read-next-on-key} für @code{HEAP}-Tabellen hinzugefügt. Das sollte
+alle Probleme mit @code{HEAP}-Tabellen bei der Benutzung von
+Nicht-@code{UNIQUE}-Schlüsseln beheben.
+@item
+Optionen für die Ausgabe vorgabemäßiger Argumente für alle Clients
+hinzugefügt.
+@item
+@code{--log-slow-queries} für @code{mysqld} hinzugefügt, um alle Anfragen
+in einer separate Log-Datei zu loggen, die lange dauerten, mit einer
+Zeitangabe, wie lange die Anfrage benötigte.
+@item
+Coredump bei der Ausführung von @code{WHERE schluessel_spalte=RAND(...)}
+behoben.
+@item
+Optimierungs-Bug in @code{SELECT ... LEFT JOIN ... schluessel_spalte IS
+NULL} behoben, wenn @code{schluessel_spalte} @code{NULL}-Werte enthalten
+konnte.
+@item
+Problem mit 8-Bit-Zeichen als Trennzeichen in @code{LOAD DATA INFILE}
+behoben.
+@end itemize
+
+
+@node News-3.23.8, News-3.23.7, News-3.23.9, News-3.23.x
+@c German node Neuigkeiten-3.23.8
+@appendixsubsec Änderungen in Release 3.23.8
+
+@itemize @bullet
+@item
+Problem bei der Handhabung von Index-Dateien größer als 8 GB behoben.
+@item
+neueste Patches für mit-pThread für NetBSD angewandt.
+@item
+Probleme mit Zeitzonen < GMT - 11 behoben.
+@item
+Bug beim Löschen komprimierter Schlüssel in @code{MyISAM} behoben.
+@item
+Problem mit @code{ISAM} bei der Ausführung einiger @code{ORDER BY ...
+DESC}-Anfragen behoben.
+@item
+Bug bei der Ausführung eines Joins auf einen Text-Schlüssel behoben, der
+nicht den gesamten Schlüssel abdeckte.
+@item
+Option @code{--delay-key-write} schaltete verzögertes Schlüssel-Schreiben
+nicht an.
+@item
+Aktualisierung von @code{TEXT}-Spalten, die nur Änderungen der
+Groß-/Kleinschreibung beinhalteten, in Ordnung gebracht.
+@item
+@code{INSERT DELAYED} aktualisiert jetzt Timestamps, die angegeben sind.
+@item
+Funktion @code{YEARWEEK()} und Optionen @code{x}, @code{X}, @code{v} und
+@code{V} für @code{DATE_FORMAT()} hinzugefügt.
+@item
+Problem mit @code{MAX(indexierte_spalte)} und HEAP-Tabellen behoben.
+@item
+Problem mit @code{BLOB NULL}-Schlüsseln und @code{LIKE} "praefix%"
+behoben.
+@item
+Problem mit @code{MyISAM} und Zeilen fester Länge < 5 Bytes behoben.
+@item
+Problem behoben, bei dem es vorkommen konnte, dass MySQL auf freigegebenen
+Speicher zugriff, wenn er sehr komplizierte @code{GROUP BY}-Anfragen
+ausführte.
+@item
+Coredump behoben, wenn man eine beschädigte Tabelle erhielt, in der ein
+@code{ENUM}-Feldwert zu Groß war.
+@end itemize
+
+
+@node News-3.23.7, News-3.23.6, News-3.23.8, News-3.23.x
+@c German node Neuigkeiten-3.23.7
+@appendixsubsec Änderungen in Release 3.23.7
+
+@itemize @bullet
+@item
+Workaround unter Linux in Ordnung gebracht, um Probleme mit
+@code{pthread_mutex_timedwait}, was bei @code{INSERT DELAYED} benutzt wird,
+zu vermeiden. @xref{Linux}.
+@item
+Man erhält jetzt einen 'disk full'-Fehler, wenn die Festplatten beim
+Sortieren voll wird (statt darauf zu warten, bis mehr Plattenplatz
+verfügbar ist).
+@item
+Bug in @code{MyISAM} mit Schlüsseln > 250 Zeichen behoben.
+@item
+In @code{MyISAM} kann man jetzt ein @code{INSERT} zur selben Zeit
+durchführen, in der andere Threads aus der Tabelle lesen.
+@item
+Variable @code{max_write_lock_count} für @code{mysqld} hinzugefügt, um eine
+@code{READ}-Sperre nach einer bestimmten Anzahl von @code{WRITE}-Sperren zu
+erzwingen.
+@item
+Flag @code{delayed_key_write} bei @code{show variables} invertiert.
+@item
+Variable @code{concurrency} in @code{thread_concurrency} umbenannt.
+@item
+Folgende Funktionen sind jetzt Multi-Byte-sicher:
+@code{LOCATE(teilzeichenfolge,zeichenkette)},
+@code{POSITION(teilzeichenfolge IN zeichenkette)},
+@code{LOCATE(teilzeichenfolge,zeichenkette,position)},
+@code{INSTR(zeichenkette,teilzeichenfolge)},
+@code{LEFT(zeichenkette,laenge)}, @code{RIGHT(zeichenkette,laenge)},
+@code{SUBSTRING(zeichenkette,pos,laenge)}, @code{SUBSTRING(zeichenkette
+FROM position FOR laenge)}, @code{MID(zeichenkette,position,laenge)},
+@code{SUBSTRING(zeichenkette,position)}, @code{SUBSTRING(zeichenkette FROM
+pos)}, @code{SUBSTRING_INDEX(zeichenkette,begrenzer,zaehler)},
+@code{RTRIM(zeichenkette)}, @code{TRIM([[BOTH | TRAILING]
+[entfernzeichenkette] FROM] zeichenkette)},
+@code{REPLACE(zeichenkette,from_zeichenkette,to_zeichenkette)},
+@code{REVERSE(zeichenkette)},
+@code{INSERT(zeichenkette,pos,laenge,newstr)}, @code{LCASE(zeichenkette)},
+@code{LOWER(zeichenkette)}, @code{UCASE(zeichenkette)} und
+@code{UPPER(zeichenkette)}. Patch von Wei He.
+@item
+Coredump beim Aufheben einer Sperre von einer nicht existierenden Tabelle
+behoben.
+@item
+Sperren auf Tabellen werden jetzt entfernt, bevor Duplikate entfernt
+werden.
+@item
+Option @code{FULL} für @code{SHOW PROCESSLIST} hinzugefügt.
+@item
+Option @code{--verbose} für @code{mysqladmin} hinzugefügt.
+@item
+Problem beim automatischen Umwandeln von HEAP in MyISAM behoben.
+@item
+Bug in HEAP-Tabellen behoben, wenn man INSERT + DELETE + INSERT + Scannen
+der Tabelle ausführt.
+@item
+Bugs auf Alpha mit @code{REPLACE()} und @code{LOAD DATA INFILE} behoben.
+@item
+@code{mysqld}-Variable @code{interactive_timeout} hinzugefügt.
+@item
+Argument für @code{mysql_data_seek()} von @code{ulong} zu @code{ulonglong}
+geändert.
+@end itemize
+
+
+@node News-3.23.6, News-3.23.5, News-3.23.7, News-3.23.x
+@c German node Neuigkeiten-3.23.6
+@appendixsubsec Änderungen in Release 3.23.6
+
+@itemize @bullet
+@item
+@code{mysqld}-Option @code{-O lower_case_tables=@{0|1@}} hinzugefügt, damit
+Benutzer Tabellennamen to Kleinschreibung erzwingen können.
+@item
+@code{SELECT ... INTO DUMPFILE} hinzugefügt.
+@item
+@code{mysqld}-Option @code{--ansi} hinzugefügt, um einige Funktionen
+@code{ANSI-SQL}-kompatibler zu machen.
+@item
+Temporäre Tabellen fangen jetzt mit @code{#sql} an.
+@item
+Quoten von Bezeichnern mit @code{`} (@code{"} im @code{--ansi}-Modus).
+@item
+Jetzt wird snprintf() bei der Ausgabe von Fließkommazahlen benutzt, um
+einige Puffer-Überläufe unter FreeBSD zu vermeiden.
+@item
+@code{[floor()} überlaufsicher unter FreeBSD gemacht.
+@item
+Option @code{--quote-names} für @code{mysqldump} hinzugefügt.
+@item
+Bug behoben, dass man einen Teil eines @code{PRIMARY KEY NOT NULL} machen
+konnte.
+@item
+@code{encrypt()} in Ordnung gebracht, um Thread-sicher zu sein und Puffer
+nicht erneut zu benutzen.
+@item
+@code{mysql_odbc_escape_string()}-Funktion zur Unterstützung von
+big5-Zeichen in MyODBC hinzugefügt.
+@item
+Die Tabellen-Handler wurden umgeschrieben und benutzen jetzt Klassen.
+Hierdurch wird viel neuer Code eingeführt, aber die Tabellenhandhabung wird
+schneller und besser.
+@item
+Patch von Sasha für benutzerdefinierte Variablen angewandt.
+@item
+@code{FLOAT} und @code{DOUBLE} (ohne jeden Längen-Modifikator) sind jetzt
+keine festen Dezimalpunkt-Zahlen mehr.
+@item
+Die Bedeutung von @code{FLOAT(X)} wurde geändert: Jetzt ist das dasselbe
+wie @code{FLOAT}, wenn X <= 24, und @code{DOUBLE}, wenn 24 < X <= 53.
+@item
+@code{DECIMAL(X)} ist jetzt ein Alias für @code{DECIMAL(X,0)}, und
+@code{DECIMAL} ist jetzt ein Alias für @code{DECIMAL(10,0)}. Dasselbe gilt
+für @code{NUMERIC}.
+@item
+Option @code{ROW_FORMAT=@{default | dynamic | static | compressed@}} für
+@code{CREATE_TABLE} hinzugefügt.
+@item
+@code{DELETE FROM tabelle} funktionierte nicht auf temporären Tabellen.
+@item
+Funktion @code{CHAR_LENGTH()} geändert, so dass sie
+Multi-Byte-Zeichen-sicher ist.
+@item
+Funktion @code{ORD(zeichenkette)} hinzugefügt.
+@end itemize
+
+
+@node News-3.23.5, News-3.23.4, News-3.23.6, News-3.23.x
+@c German node Neuigkeiten-3.23.5
+@appendixsubsec Änderungen in Release 3.23.5
+
+@itemize @bullet
+@item
+Einige Jahr-2000-Probleme in der neuen Daten-Handhabung in Version 3.23
+behoben.
+@item
+Problem mit @code{SELECT DISTINCT ... ORDER BY RAND()} behoben.
+@item
+Patches von Sergei A. Golubchik für Textsuche auf MyISAM-Ebene angewandt.
+@item
+Cache-Überlaufproblem bei der Benutzung von Full Joins ohne Schlüssel
+behoben.
+@item
+Einige configure-Probleme bereinigt.
+@item
+Einige kleine Änderungen, um das Parsen schneller zu machen.
+@item
+@code{ALTER TABLE} + Hinzufügen einer Spalte nach dem letzten Feld
+funktionierte nicht.
+@item
+Problem bei der Benutzung einer auto_increment-Spalte in zwei Schlüsseln
+behoben.
+@item
+Bei MyISAM kann man jetzt den auto_increment-Teil als Untermenge haben:
+@code{CREATE TABLE foo (a int not null auto_increment, b char(5), primary
+key (b,a))}
+@item
+Bug in MyISAM mit komprimierten CHAR-Schlüsseln, die @code{NULL} sein
+konnten, behoben.
+@item
+@code{AS} auf Feldname mit @code{CREATE TABLE tabelle SELECT ...}
+funktionierte nicht.
+@item
+Benutzung von @code{NATIONAL} und @code{NCHAR} bei der Definition von
+Zeichenspalten wird zugelassen. Das ist dasselbe, als wenn man
+@code{BINARY} nicht benutzt.
+@item
+Keine @code{NULL}-Spalten in einem @code{PRIMARY KEY} zulassen (nur in
+@code{UNIQUE}-Schlüsseln).
+@item
+@code{LAST_INSERT_ID} wird gelöscht (clear), wenn man diese in ODBC
+benutzt: @code{WHERE auto_increment_spalte IS NULL}. Das scheint einige
+Probleme mit Access zu beheben.
+@item
+@code{SET SQL_AUTO_IS_NULL=0|1} schaltet jetzt die Handhabung von Suchen
+nach der letzten eingefügten Zeile bei @code{WHERE auto_increment_spalte IS
+NULL} aus / an.
+@item
+Neue @code{mysqld}-Variable @code{concurrency} für Solaris hinzugefügt.
+@item
+Option @code{--relative} für @code{mysqladmin} hinzugefügt, um mit
+@code{extended-status} eine bessere Beobachtung von Änderungen zu erzielen.
+@item
+Bug bei der Benutzung von @code{COUNT(DISTINCT ...)} auf eine leere Tabelle
+behoben.
+@item
+Unterstützung für den chinesischen Zeichensatz GBK hinzugefügt.
+@item
+Problem mit @code{LOAD DATA INFILE} und @code{BLOB}-Spalten behoben.
+@item
+Bit-Operator @code{~} (Negation) hinzugefügt.
+@item
+Problem mit @code{UDF}-Funktionen behoben.
+@end itemize
+
+
+@node News-3.23.4, News-3.23.3, News-3.23.5, News-3.23.x
+@c German node Neuigkeiten-3.23.4
+@appendixsubsec Änderungen in Release 3.23.4
+
+@itemize @bullet
+@item
+Einfügen eines @code{DATETIME}-Werts in eine @code{TIME}-Spalte versucht
+jetzt nicht mehr, darin 'Tage' zu speichern.
+@item
+Problem mit der Speicherung von Float / Double auf kleinen Endian-Maschinen
+behoben (das betraf @code{SUM()}).
+@item
+Verbindungs-Zeitüberschreitung (Timeout) auf TCP/IP-Verbindungen
+hinzugefügt.
+@item
+Problem mit @code{LIKE} "%" auf einem Index, der @code{NULL}-Werte
+enthalten darf, behoben.
+@item
+@code{REVOKE ALL PRIVILEGES} widerrief nicht alle Berechtigungen.
+@item
+Erzeugung temporärer Tabellen mit demselben Namen wie die Original-Tabelle
+wird zugelassen.
+@item
+Wenn man einem Benutzer eine Berechtigungsoption (Grant Option) für eine
+Datenbank gewährte, konnte er die Berechtigungen nicht an andere Benutzer
+weitergeben.
+@item
+Neuer Befehl @code{SHOW GRANTS FOR benutzer} hinzugefügt (von Sinisa).
+@item
+Neue @code{date_add}-Syntax @code{date/datetime + INTERVAL # intervall_typ}
+hinzugefügt. Von Joshua Chamas.
+@item
+Berechtigungsüberprüfung für @code{LOAD DATA REPLACE} in Ordnung gebracht.
+@item
+Automatische Reparatur beschädigter Include-Dateien auf Solaris 2.7
+hinzugefügt.
+@item
+Einige configure-Probleme behoben, um Probleme bei der Erkennung großer
+Dateisysteme zu beheben.
+@item
+@code{REGEXP} ist jetzt unabhängig von der verwendeten
+Groß-/Kleinschreibung, wenn Sie nicht binäre Zeichenketten verwenden.
+@end itemize
+
+
+@node News-3.23.3, News-3.23.2, News-3.23.4, News-3.23.x
+@c German node Neuigkeiten-3.23.3
+@appendixsubsec Änderungen in Release 3.23.3
+
+@itemize @bullet
+@item
+Patches für MIT-pThread auf NetBSD angewandt.
+@item
+Bereichs-Bug in MyISAM behoben.
+@item
+@code{ASC} ist jetzt wieder Vorgabe für @code{ORDER BY}.
+@item
+@code{LIMIT} für @code{UPDATE} hinzugefügt.
+@item
+Neue Client-Funktion @code{mysql_change_user()} hinzugefügt.
+@item
+Zeichensatz zu @code{SHOW VARIABLES} hinzugefügt.
+@item
+Unterstützung von @code{--[leerraum]}-Kommentaren hinzugefügt.
+@item
+@code{INSERT into tabelle VALUES ()} wird zugelassen. Das heißt, Sie
+können jetzt eine leere Wertliste angeben, die in eine Zeile eingefügt
+wird, und in der jede Spalte auf ihren Vorgabewert gesetzt wird.
+@item
+@code{SUBSTRING(text FROM position)} geändert, um ANSI-SQL-kompatibel zu
+sein. (Vorher gab dieses Konstrukt das rechteste 'position'-Zeichen
+zurück.)
+@item
+@code{SUM()} mit @code{GROUP BY} gab auf manchen Systemen 0 zurück.
+@item
+Ausgabe bei @code{SHOW TABLE STATUS} geändert.
+@item
+@code{DELAY_KEY_WRITE}-Option für @code{CREATE TABLE} hinzugefügt.
+@item
+@code{AUTO_INCREMENT} wird für jeden beliebigen Schlüsselteil zugelassen.
+@item
+Problem mit @code{YEAR(NOW())} und @code{YEAR(CURDATE())} behoben.
+@item
+@code{CASE}-Konstrukt hinzugefügt.
+@item
+Neue Funktion @code{COALESCE()} hinzugefügt.
+@end itemize
+
+
+@node News-3.23.2, News-3.23.1, News-3.23.3, News-3.23.x
+@c German node Neuigkeiten-3.23.2
+@appendixsubsec Änderungen in Release 3.23.2
+
+@itemize @bullet
+@item
+Bereichsoptimierer-Bug behoben: @code{SELECT * FROM tabelle WHERE
+schluessel_teil1 >= konstante AND (schluessel_teil2 = konstante OR
+schluessel_teil2 = konstante)}. Der Bug bestand darin, dass manche Zeilen
+im Ergebnis doppelt auftauchen konnten.
+@item
+Das Laufenlassen von @code{myisamchk} ohne @code{-a} aktualisierte die
+Index-Verteilung falsch.
+@item
+@code{SET SQL_LOW_PRIORITY_UPDATES=1} gab vorher einen Parser-Fehler.
+@item
+Sie können jetzt Spalten indexieren, die in der @code{WHERE}-Klausel
+benutzt werden. @code{UPDATE tabelle SET KEY=KEY+1 WHERE KEY > 100}
+@item
+Datums-Handhabung sollte jetzt etwas schneller sein.
+@item
+Handhabung von 'fuzzy' Datumsangaben möglich (Datumsangaben, bei denen der
+Tag oder der Monat 0 sind, wie 1999-01-00).
+@item
+Optimierung von @code{SELECT ... WHERE schluessel_teil1=konstante1 AND
+schluessel_teil_2=konstante2 AND schluessel_teil1=konstante4 AND
+schluessel_teil2=konstante4} in Ordnung gebracht. Indextyp sollte
+@code{range} anstelle von @code{ref} sein.
+@item
+@code{egcs}-1.1.2-Optimierer-Bug behoben (bei der Benutzung von
+@code{BLOB}s) auf Linux Alpha.
+@item
+Problem mit @code{LOCK TABLES} in Kombination mit @code{DELETE FROM
+tabelle} behoben.
+@item
+MyISAM-Tabellen lassen jetzt Schlüssel auf @code{NULL} und
+@code{BLOB/TEXT}-Spalten zu.
+@item
+Folgender Join ist jetzt viel schneller: @code{SELECT ... FROM t1 LEFT JOIN
+t2 ON ... WHERE t2.nicht_null_spalte IS NULL}.
+@item
+@code{ORDER BY} und @code{GROUP BY} können jetzt auf Funktionen angewendet
+werden.
+@item
+Handhabung von 'konstante' geändert, um Handhabung von @code{ORDER BY
+RAND()} zu gestatten.
+@item
+Indexe werden jetzt für @code{WHERE schluessel_spalte = funktion} benutzt.
+@item
+Indexe werden jetzt für @code{WHERE schluessel_spalte = spalten_name}
+benutzt, selbst wenn die Spalten nicht identisch komprimiert sind.
+@item
+Indexe werden jetzt für @code{WHERE spalten_name IS NULL} benutzt.
+@item
+HEAP-Tabellen so geändert, dass in der Reihenfolge niedriges Byte zuerst
+gespeichert wird (um es zu erleichtern, MyISAM-Tabellen zu konvertieren).
+@item
+Automatische Änderung temporärer HEAP-Tabellen in MyISAM-Tabellen im Falle
+von 'table is full'-Fehlern.
+@item
+Option @code{--init-file=datei} für @code{mysqld} hinzugefügt.
+@item
+@code{COUNT(DISTINCT wert, [wert, ...])} hinzugefügt.
+@item
+@code{CREATE TEMPORARY TABLE} erzeugt jetzt eine temporäre Tabelle in ihrem
+eigenen Namensraum, die automatisch gelöscht wird, wenn die Verbindung
+beendet wird.
+@item
+Neue reservierte Wörter (erforderlich für @code{CASE}): @code{CASE, THEN,
+WHEN, ELSE und END}.
+@item
+Neue Funktionen @code{EXPORT_SET()} und @code{MD5()} hinzugefügt.
+@item
+Unterstützung für den GB2312 chinesischen Zeichensatz hinzugefügt.
+@end itemize
+
+
+@node News-3.23.1, News-3.23.0, News-3.23.2, News-3.23.x
+@c German node Neuigkeiten-3.23.1
+@appendixsubsec Änderungen in Release 3.23.1
+
+@itemize @bullet
+@item
+Einige Kompilierungsprobleme behoben.
+@end itemize
+
+
+@node News-3.23.0, , News-3.23.1, News-3.23.x
+@c German node Neuigkeiten-3.23.0
+@appendixsubsec Änderungen in Release 3.23.0
+
+@itemize @bullet
+@item
+Eine neue Tabellen-Handler-Bibliothek (@code{MyISAM}) mit vielen neuen
+Features hinzugefügt. @xref{MyISAM}.
+@item
+Sie können @code{HEAP}-Tabellen im Hauptspeicher erzeugen, die zum
+Nachschlagen extrem schnell sind.
+@item
+Unterstützung für große Dateien (63-Bit) auf Systemen, die große Dateien
+unterstützen, hinzugefügt.
+@item
+Neue Funktion @code{LOAD_FILE(datei)} hinzugefügt, um die Inhalte einer
+Datei als Zeichenkettenwert zu erhalten.
+@item
+Neuer Operator @code{<=>} hinzugefügt, der wie @code{=} funktioniert, aber
+WAHR (true) zurückgibt, wenn beide Argumente @code{NULL} sind. Das ist
+nützlich, um Änderungen zwischen Tabellen zu vergleichen.
+@item
+ODBC-3.0-@code{EXTRACT(intervall FROM datetime)}-Funktion hinzugefügt.
+@item
+Spalten, die als @code{FLOAT(X)} definiert sind, werden beim Speichern
+nicht gerundet und dürfen beim Abruf in wissenschaftlicher Notation sein
+(1.0 E+10).
+@item
+@code{REPLACE} ist jetzt schneller als vorher.
+@item
+@code{LIKE}-Zeichenvergleiche geändert, so dass sie sich wie @code{=}
+verhalten. Das heißt, dass @code{'e' LIKE '@'é'} jetzt WAHR (true) ist
+(falls hier etwas nicht richtig angezeigt wird: Das letztgenannte 'e' ist
+das französische 'e' mit Akzent).
+@item
+@code{SHOW TABLE STATUS} gibt eine Menge an Informationen über die Tabellen
+zurück.
+@item
+@code{LIKE} für den @code{SHOW STATUS}-Befehl hinzugefügt.
+@item
+Berechtigungsspalte zu @code{SHOW COLUMNS} hinzugefügt.
+@item
+Spalten @code{packed} und @code{comment} für @code{SHOW INDEX} hinzugefügt.
+@item
+Kommentare zu Tabellen (mit @code{CREATE TABLE ... COMMENT "kommentar"})
+hinzugefügt.
+@item
+@code{UNIQUE}, wie bei @code{CREATE TABLE tabelle (spalte int not null
+UNIQUE)}, hinzugefügt.
+@item
+Neue CREATE-Syntax: @code{CREATE TABLE tabelle SELECT ...}
+@item
+Neue CREATE-Syntax: @code{CREATE TABLE IF NOT EXISTS ...}
+@item
+Die Erzeugung von @code{CHAR(0)}-Spalten wird zugelassen.
+@item
+@code{DATE_FORMAT()} erfordert jetzt @samp{%} vor jeglichem
+Formatierungszeichen.
+@item
+@code{DELAYED} ist jetzt ein reserviertes Wort (tut uns leid :( ).
+@item
+Eine Beispiel-Prozedur wurde hinzugefügt: @code{analyse}, Datei:
+@file{sql_analyse.c}. Diese beschreibt die Daten in Ihrer Anfrage.
+Probieren Sie folgendes:
+@example
+SELECT ... FROM ... WHERE ... prozeduranalyse([max elemente,[max speicher]])
+@end example
+
+Diese Prozedur ist extrem nützlich, wenn Sie die Daten in Ihrer Tabelle
+prüfen wollen!
+@item
+@code{BINARY}-Cast, um zu erzwingen, dass eine Zeichenkette abhängig von
+der verwendeten Groß-/Kleinschreibung verglichen wird.
+@item
+Option @code{--skip-show-database} für @code{mysqld} hinzugefügt.
+@item
+Das Prüfen, ob sich eine Zeile bei einem @code{UPDATE} geändert hat,
+funktioniert jetzt auch bei @code{BLOB}-/@code{TEXT}-Spalten.
+@item
+Die @code{INNER}-Join-Syntax wurde hinzugefügt. @strong{HINWEIS}: Hierdurch
+wurde @code{INNER} zu einem reservierten Wort!
+@item
+Unterstützung für Netmasks zum Hostname in den MySQL-Tabellen hinzugefügt.
+Sie können eine Netmask mit der @code{IP/NETMASK}-Syntax angeben.
+@item
+Wenn Sie eine @code{NOT NULL DATE/DATETIME}-Spalte mit @code{IS NULL}
+vergleichen, wird das zu einem Vergleich auf @code{0} geändert, um einige
+ODBC-Applikationen zufrieden zu stellen (von @email{shreeve@@uci.edu}).
+@item
+@code{NULL IN (...)} gibt jetzt @code{NULL} anstelle von @code{0} zurück.
+Das stellt sicher, dass @code{null_spalte NOT IN (...)} nicht mit
+@code{NULL}-Werten übereinstimmt.
+@item
+Speicherung von Fließkommawerten in @code{TIME}-Spalten in Ordnung
+gebracht.
+@item
+Das Parsen von @code{TIME}-Zeichenketten geändert, so dass es strenger ist.
+Jetzt wird der Bruchteil-Sekunden-Teil erkannt (und momentan noch
+übergangen). Folgende Formate werden unterstützt:
+@table @code
+@item [[DAYS] [H]H:]MM:]SS[.bruchteil]
+@item [[[[[H]H]H]H]MM]SS[.bruchteil]
+@end table
+@item
+Erkennen (und Ignorieren) des zweiten Bruchteil-Anteils von @code{DATETIME}
+hinzugefügt.
+@item
+@code{LOW_PRIORITY}-Attribut für @code{LOAD DATA INFILE} hinzugefügt.
+@item
+Der vorgabemäßige Index-Name benutzt jetzt dieselbe Groß-/Kleinschreibung
+wie der benutzte Spaltenname.
+@item
+Vorgabemäßige Anzahl von Verbindungen auf 100 geändert.
+@item
+Bei der Benutzung von @code{LOAD DATA INFILE} werden größere Puffer
+verwendet.
+@item
+@code{DECIMAL(x,y)} funktioniert jetzt gemäß ANSI-SQL.
+@item
+Aggregat-UDF-Funktionen. Dank an Andreas F. Bobak @email{bobak@@relog.ch}
+hierfür!
+@item
+@code{LAST_INSERT_ID()} wird jetzt bei @code{INSERT INTO ... SELECT}
+aktualisiert.
+@item
+Einige kleinere Änderungen am Join-Tabellenoptimierer, um einige Joins
+schneller zu machen.
+@item
+@code{SELECT DISTINCT} ist viel schneller. Es benutzt die neue
+@code{UNIQUE}-Funktionalität in @code{MyISAM}. Ein Unterschied im Vergleich
+zur MySQL-Version 3.22 besteht darin, dass die Ausgabe von @code{DISTINCT}
+nicht mehr sortiert wird.
+@item
+Alle C-Client-API-Makros sind jetzt Funktionen, um die gemeinsam genutzten
+(shared) Bibliotheken verlässlicher zu machen. Deswegen können Sie nicht
+mehr @code{mysql_num_fields()} auf ein @code{MYSQL}-Objekt aufrufen,
+sondern müssen statt dessen @code{mysql_field_count()} benutzen.
+@item
+Benutzung von @code{LIBEWRAP}; Patch von Henning P. Schmiedehausen.
+@item
+@code{AUTO_INCREMENT} wird nur noch für numerische Spalten zugelassen.
+@item
+Durch die Verwendung von @code{AUTO_INCREMENT} wird die Spalte automatisch
+@code{NOT NULL}.
+@item
+@code{NULL} wird als Vorgabewert für AUTO_INCREMENT-Spalten angezeigt.
+@item
+@code{SQL_BIG_RESULT}; @code{SQL_SMALL_RESULT} ist jetzt Vorgabe.
+@item
+Ein gemeinsam genutztes (shared) Bibliothek-RPM hinzugefügt. Diese
+Verbesserung wurde von David Fox (dsfox@@cogsci.ucsd.edu) beigesteuert.
+@item
+Ein @code{--enable-large-files/--disable-large-files}-Schalter zu
+@code{configure} hinzugefügt. Siehe @file{configure.in} wegen mancher
+Systeme, auf denen dies wegen nicht funktionierender Implementation
+automatisch abgeschaltet ist.
+@item
+@code{readline} für Version 4.0 aktualisiert.
+@item
+Neue @code{CREATE TABLE}-Optionen: @code{PACK_KEYS} und @code{CHECKSUM}.
+@item
+@code{mysqld}-Option @code{--default-table-type} hinzugefügt.
+@end itemize
+
+
+@node Porting, Environment variables, News, Top
+@c German node Portierung
+@appendix Anmerkungen zur Portierung auf andere Systeme
+
+@cindex Portierung, auf andere Systeme
+
+Für den Server wird eine funktionierende Posix-Thread-Bibliothek benötigt.
+Auf Solaris 2.5 benutzen wir Sun PThread (die native Thread-Unterstützung
+in Version 2.4 und früher ist nicht gut genug). Auf Linux benutzen wir
+LinuxThread von Xavier Leroy, @email{Xavier.Leroy@@inria.fr}.
+
+Der schwierige Teil der Portierung auf eine neue Unix-Variante ohne gute
+native Thread-Unterstützung ist wahrscheinlich, MIT-pThread zu portieren.
+Siehe @file{with-pThread/README} und
+@uref{http://www.humanfactor.com/pThread/, POSIX-Thread programmieren}.
+
+Die MySQL-Distribution enthält eine gepatchte Version von Provenzanos
+PThread von MIT (siehe
+@uref{http://www.mit.edu:8001/people/proven/pThread.html,
+MIT-PThread-Website}). Diese kann für einige Betriebssysteme benutzt
+werden, die kein POSIX-Thread haben.
+
+Es ist ebenfalls möglich, ein anderes Thread-Paket auf Benutzerebene namens
+FSU-PThread zu benutzen (siehe
+@uref{http://www.informatik.hu-berlin.de/~mueller/pThread.html,
+FSU-PThread-Homepage}). Diese Implementation wird für die SCO-Portierung
+benutzt.
+
+In den @file{thr_lock.c}- und @file{thr_alarm.c}-Programmen im
+@file{mysys}-Verzeichnis finden Sie einige Tests / Beispiele dieser
+Probleme.
+
+Sowohl Server als auch Client benötigen einen funktionierenden C++-Kompiler
+(wir benutzen @code{gcc} und haben SparcWorks ausprobiert). Ein anderer
+bekanntermaßen funktionierender Compiler ist Irix @code{cc}.
+
+Um nur den Client zu kompilieren, benutzen Sie @code{./configure
+--without-server}.
+
+Es gibt momentan keine Unterstützung, um nur den Server zu kompilieren,
+noch ist es wahrscheinlich, dass eine solche hinzugefügt wird, falls nicht
+jemand einen guten Grund dafür findet.
+
+Wenn Sie irgend welche @file{Makefile} oder das configure-Skript ändern
+wollen / müssen, müssen Sie sich Automake und Autoconf holen. Wir haben die
+@code{automake-1.2}- und @code{autoconf-2.12}-Distributionen benutzt.
+
+Alle Schritte, die notwendig sind, um alles aus den grundlegendsten Dateien
+neu zu machen (make):
+
+@example
+/bin/rm */.deps/*.P
+/bin/rm -f config.cache
+aclocal
+autoheader
+aclocal
+automake
+autoconf
+./configure --with-debug=full --prefix='ihr_installationsverzeichnis'
+
+# Die oben erzeugten makefiles benötigen GNU-make 3.75 oder neuer.
+# (unten gmake genannt)
+gmake clean all install init-db
+@end example
+
+Wenn Sie bei einer neuen Portierung Probleme bekommen, kann es sein, dass
+Sie MySQL etwas debuggen müssen! @xref{Debugging server}.
+
+@strong{HINWEIS:} Bevor Sie mit dem Debuggen von @code{mysqld} anfangen,
+bringen Sie sich zuerst die Testprogramme @code{mysys/thr_alarm} und
+@code{mysys/thr_lock} zum Laufen. Das stellt sicher, dass Ihre
+Thread-Installation zumindest überhaupt eine Chance hat, zu funktionieren!
+
+
+
+@menu
+* Debugging server::
+* Debugging client::
+* The DBUG package::
+* Locking methods::
+* RTS-threads::
+* Thread packages::
+@end menu
+
+@node Debugging server, Debugging client, Porting, Porting
+@c German node Server debuggen
+@appendixsec Einen MySQL-Server debuggen
+
+@cindex Server, debuggen
+@cindex debuggen, Server
+@cindex Absturz
+
+Wenn Sie Funktionalität benutzen, die in MySQL sehr neu ist, können Sie
+versuchen, @code{mysqld} mit der @code{--skip-new}-Option laufen zu lassen
+(die alle sehr neue, potenziell unsichere Funktionalität abschaltet) oder
+mit @code{--safe-mode}, was viel an Optimierung abschaltet, die
+möglicherweise Probleme verursacht. @xref{Crashing}.
+
+Wenn @code{mysqld} nicht starten will, sollten Sie prüfen, ob Sie irgend
+welche @code{my.cnf}-Dateien haben, die mit Ihrer Konfiguration in Konflikt
+kommen! Sie können Ihre @code{my.cnf}-Argumente mit @code{mysqld
+--print-defaults} prüfen und sie vermeiden, indem Sie mit @code{mysqld
+--no-defaults ...} starten.
+
+Wenn @code{mysqld} anfängt, Prozessorleistung oder Speicher zu fressen,
+oder wenn er ``hängt'', können Sie @code{mysqladmin processlist status}
+benutzen, um herauszufinden, ob irgend etwas eine Anfrage ausführt, die
+sehr lange dauert. Es ist eine gute Idee, @code{mysqladmin -i10 processlist
+status} in irgend einem Fenster laufen zu haben, wenn Sie
+Performance-Probleme oder Probleme damit haben, dass sich neue Clients
+nicht verbinden können.
+
+Der Befehl @code{mysqladmin debug} dumpt Informationen über Sperren, die in
+Gebrauch sind, den benutzten Speicher und den Anfragengebrauch in die
+mysql-Log-Datei aus. Das kann helfen, einige Probleme zu lösen. Dieser
+Befehl stellt auch nützliche Informationen zur Verfügung, selbst wenn Sie
+MySQL nicht zum Debuggen kompiliert haben!
+
+Wenn das Problem darin besteht, dass einige Tabellen langsamer und
+langsamer werden, sollten Sie versuchen, die Tabelle mit @code{OPTIMIZE
+TABLE} der @code{myisamchk} zu optimieren.
+@xref{MySQL Database Administration}. Sie sollten langsame Anfragen
+darüber hinaus mit @code{EXPLAIN} überprüfen.
+
+Ebenfalls sollten Sie den Abschnitt über betriebssystemspezifische Dinge in
+diesem Handbuch lesen, weil Sie Probleme haben könnten, die einzigartig für
+Ihre Umgebung sind. @xref{Operating System Specific Notes}.
+
+
+
+@menu
+* Compiling for debugging::
+* Making trace files::
+* Using gdb on mysqld::
+* Using stack trace::
+* Using log files::
+* Reproduceable test case::
+@end menu
+
+@node Compiling for debugging, Making trace files, Debugging server, Debugging server
+@c German node Zum Debuggen kompilieren
+@appendixsubsec MySQL zum Debuggen kompilieren
+
+Wenn Sie sehr spezielle Probleme haben, können Sie immer versuchen, MySQL
+zu debuggen. Dafür müssen Sie MySQL mit der @code{--with-debug}- oder der
+@code{--with-debug=full}-Option kompilieren. Sie können prüfen, ob MySQL
+mit Debuggen kompiliert wurde oder nicht, wenn Sie @code{mysqld --help}
+ausführen. Wenn das @code{--debug}-Flag in den Optionen aufgeführt ist,
+haben Sie Debuggen eingeschaltet. @code{mysqladmin ver} gibt die
+@code{mysqld}-Version in diesem Fall ebenfalls als @code{mysql ... --debug}
+aus.
+
+Wenn Sie gcc oder egcs benutzen, ist die empfohlene configure-Zeile:
+
+@example
+CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex
+@end example
+
+Das vermeidet Probleme mit der @code{libstdc++}-Bibliothek und mit
+C++-Ausnahmen (viele Compiler haben Probleme mit C++-Ausnahmen in threaded
+Code) und kompiliert eine MySQL-Version mit Unterstützung für alle
+Zeichensätze.
+
+Wenn Sie einen Speicherüberlauffehler vermuten, können Sie MySQL mit
+@code{--with-debug=full} kompilieren, was zusätzlich einen
+(@code{SAFEMALLOC})-Prüfer für die Speicherzuweisung installiert. Das
+Laufenlassen mit @code{SAFEMALLOC} ist jedoch recht langsam. Wenn Sie daher
+Performance-Probleme bekommen, sollten Sie @code{mysqld} mit der
+@code{--skip-safemalloc}-Option starten. Das schaltet die
+Speicherüberlaufprüfung für jeden Aufruf von @code{malloc} und @code{free}
+ab.
+
+Wenn @code{mysqld} nicht mehr abstürzt, wenn Sie ihn mit
+@code{--with-debug} kompilieren, haben Sie wahrscheinlich einen
+Compiler-Bug oder einen Timing-Bug innerhalb von MySQL gefunden. In diesem
+Fall können Sie versuchen, @code{-g} für die @code{CFLAGS}- und
+@code{CXXFLAGS}-Variablen oben hinzuzufügen und nicht mehr
+@code{--with-debug} zu benutzen. Wenn @code{mysqld} jetzt stirbt, können
+Sie wenigstens mit @code{gdb} mit ihm verbinden oder @code{gdb} auf die
+Core-Datei benutzen, um herauszufinden, was passiert ist.
+
+Wenn Sie MySQL zum Debuggen konfigurieren, können Sie viele zusätzliche
+Sicherheitprüffunktionen hinzufügen, die die Gesundheit von @code{mysqld}
+beobachten. Wenn Sie etwas ``Unerwartetes'' finden, wird ein Eintrag nach
+@code{stderr} geschrieben, den @code{safe_mysqld} in die Fehler-Log-Datei
+leitet! Das heißt auch, dass Sie bei unerwarteten Problemen mit MySQL und
+der Benutzung einer Quelldistribution als erstes MySQL zum Debuggen
+konfigurieren sollten! (Die zweite Sache wäre natürlich, eine E-Mail an
+@email{mysql@@lists.mysql.com} zu schicken und um Hilfe zu bitten. Bitte
+benutzen Sie das @code{mysqlbug}-Skript für alle Bug-Berichte oder Fragen
+hinsichtlich der MySQL-Version, die Sie benutzen!
+
+In der Windows-MySQL-Distribution wird @code{mysqld.exe} vorgabemäßig mit
+Unterstützung für Trace-Dateien kompiliert.
+
+
+@node Making trace files, Using gdb on mysqld, Compiling for debugging, Debugging server
+@c German node Trace-Dateien
+@appendixsubsec Trace-Dateien erzeugen
+
+Wenn der @code{mysqld}-Server nicht startet oder wenn Sie den
+@code{mysqld}-Server schnell zum Absturz bringen können, können Sie
+versuchen, eine Trace-Datei zu erzeugen, um das Problem zu finden.
+
+Hierfür brauchen Sie einen @code{mysqld}, der zum Debuggen kompiliert ist.
+Sie können das mit @code{mysqld -V} prüfen. Wenn die Versionsnummer mit
+@code{-debug} endet, ist Unterstützung für Trace-Dateien einkompiliert.
+
+Starten Sie den @code{mysqld}-Server mit einem Trace-Log in
+@file{/tmp/mysqld.trace} (oder @file{C:\mysqld.trace} unter Windows):
+
+@code{mysqld --debug}
+
+Unter Windows sollten Sie auch den @code{--standalone}-Flag benutzen, um
+@code{mysqld} nicht als Systemdienst zu starten.
+
+Machen Sie folgendes in einem DOS-Fenster:
+
+@example
+mysqld --debug --standalone
+@end example
+
+Danach können Sie das @code{mysql.exe}-Kommandozeilenwerkzeug in einem
+zweiten DOS-Fenster benutzen, um das Problem zu reproduzieren. Sie können
+den obigen @code{mysqld}-Server mit @code{mysqladmin shutdown} herunter
+fahren.
+
+Beachten Sie, dass die Trace-Datei sehr @emph{Groß} wird! Wenn Sie eine
+kleinere Trace-Datei haben wollen, können Sie etwa folgendes tun:
+
+@code{mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace}
+
+Das gibt nur Informationen für die interessantesten Dinge in
+@file{/tmp/mysqld.trace} aus.
+
+Wenn Sie hierüber einen Bug-Bericht erstellen, schicken Sie bitte nur die
+Zeilen aus der Trace-Datei an die entsprechende Mailing-Liste, in denen
+etwas schief zu gehen scheint! Wenn Sie diese Stelle nicht finden können,
+können Sie die Trace-Datei per FTP einschicken, zusammen mit einem
+kompletten Bug-Bericht, an @uref{ftp://Support.mysql.com/pub/mysql/secret},
+so dass ein MySQL-Entwickler sich das ansehen kann.
+
+Die Trace-Datei wird mit dem @strong{DBUG}-Paket von Fred Fish hergestellt.
+@xref{The DBUG package}.
+
+
+@node Using gdb on mysqld, Using stack trace, Making trace files, Debugging server
+@c German node gdb auf mysqld benutzen
+@appendixsubsec mysqld unter gdb debuggen
+
+@cindex gdb, using
+
+Auf den meisten Systemen können Sie @code{mysqld} von @code{gdb} starten,
+um mehr Informationen zu erhalten, wenn @code{mysqld} abstürzt.
+
+Bei einigen älteren @code{gdb}-Versionen unter Linux müssen Sie @code{run
+--one-thread} benutzen, um den @code{mysqld}-Thread debuggen zu können. In
+diesem Fall können Sie zur gleichen Zeit nur einen Thread aktiv haben.
+
+Wenn Sie @code{mysqld} unter gdb laufen lassen, sollten Sie den Stack-Trace
+mit @code{--skip-stack-trace} abschalten, um Segmentation-Fehler innerhalb
+gdb abfangen zu können.
+
+Es ist sehr schwierig, MySQL unter @code{gdb} zu debuggen, wenn Sie
+permanent viele neue Verbindungen aufbauen, weil @code{gdb} den Speicher
+für den alten Thread nicht freigibt. Sie können dieses Problem vermeiden,
+indem Sie @code{mysqld} mit @code{-O thread_cache_size=
+'maximale_verbindungen +1'} starten. In den meisten Fällen hilft bereits
+schon die Benutzung von @code{-O thread_cache_size=5'} recht viel!
+
+Wenn Sie einen Coredump unter Linux erhalten wollen, wenn @code{mysqld} mit
+einem SIGSEGV-Signal stirbt, können Sie @code{mysqld} mit der
+@code{--core-file}-Option starten. Diese Core-Datei kann benutzt werden, um
+eine Zurückverfolgung (Backtrace) zu machen, die Ihnen helfen kann
+herauszufinden, warum @code{mysqld} starb:
+
+@example
+shell> gdb mysqld core
+gdb> backtrace full
+gdb> exit
+@end example
+
+@xref{Crashing}.
+
+Wenn Sie gdb 4.17.x oder höher unter Linux benutzen, sollten Sie eine
+@file{.gdb}-Datei mit folgenden Informationen in Ihrem aktuellen
+Verzeichnis installieren:
+
+@example
+set print sevenbit off
+handle SIGUSR1 nostop noprint
+handle SIGUSR2 nostop noprint
+handle SIGWAITING nostop noprint
+handle SIGLWP nostop noprint
+handle SIGPIPE nostop
+handle SIGALRM nostop
+handle SIGHUP nostop
+handle SIGTERM nostop noprint
+@end example
+
+Wenn Sie Probleme haben, den Thread mit gdb zu debuggen, sollten Sie gdb
+5.x herunter laden und diesen statt dessen benutzen. Die neue gdb-Version
+hat eine stark verbesserte Thread-Handhabung!
+
+Hier ist ein Beispiel, wie man mysqld debuggt:
+
+@example
+shell> gdb /usr/local/libexec/mysqld
+gdb> run
+...
+backtrace full # Tun Sie das, wenn mysqld abstürzt
+@end example
+
+Schließen Sie die obige Ausgabe in eine Mail ein, die mit @code{mysqlbug}
+erzeugt wurde und schicken Sie sie an @code{mysql@@lists.mysql.com}.
+
+Wenn @code{mysqld} hängen bleibt, können Sie versuchen, einige
+Systemwerkzeuge wie @code{strace} oder @code{/usr/proc/bin/pstack} zu
+benutzen, um herauszufinden, was @code{mysqld} zum Hängen brachte.
+
+@example
+strace /tmp/log libexec/mysqld
+@end example
+
+@findex DBI->trace
+@findex Trace-DBI-Methode
+@tindex DBI_TRACE-Umgebungsvariable
+@tindex Umgebungsvariable, DBI_TRACE
+Wenn Sie die Perl-@code{DBI}-Schnittstelle benutzen, können Sie
+Debug-Informationen anschalten, indem Sie die @code{trace}-Methode benutzen
+oder die @code{DBI_TRACE}-Umgebungsvariable setzen.
+@xref{Perl DBI Class, , Perl @code{DBI} Class}.
+
+
+@node Using stack trace, Using log files, Using gdb on mysqld, Debugging server
+@c German node Stack-Trace benutzen
+@appendixsubsec Einen Stack-Trace benutzen
+
+Auf manchen Betriebssystemen enthält die Fehler-Log-Datei einen
+Stack-Trace, wenn @code{mysqld} unerwartet stirbt. Diese können Sie
+benutzen, um herauszufinden, wo (und vielleicht warum) @code{mysqld} starb.
+@xref{Error log}. Um einen Stack-Trace zu erhalten, sollten Sie
+@code{mysqld} NICHT mit der @code{-fomit-frame-pointer}-Option für gcc
+kompilieren. @xref{Compiling for debugging}.
+
+Wenn die Fehlerdatei etwas wie folgendes enthält:
+
+@example
+mysqld got signal 11;
+The manual section 'debugging a MySQL server' tells you how to use a
+stack trace and/or the core file to produce a readable backtrace that may
+help in finding out why mysqld died
+Attemping backtrace. You can use the following information to find out
+where mysqld died. Wenn you see no messages after this, something went
+terribly wrong
+stack range sanity check, ok, backtrace follows
+0x40077552
+0x81281a0
+0x8128f47
+0x8127be0
+0x8127995
+0x8104947
+0x80ff28f
+0x810131b
+0x80ee4bc
+0x80c3c91
+0x80c6b43
+0x80c1fd9
+0x80c1686
+@end example
+
+Können Sie herausfinden, wo @code{mysqld} starb, indem Sie folgendes tun:
+
+@enumerate
+@item
+Kopieren Sie die obigen Zahlen in eine Datei, zum Beispiel
+@file{mysqld.stack}.
+
+@item
+Machen Sie eine symbolische Datei für den @code{mysqld}-Server:
+@example
+nm -n libexec/mysqld > /tmp/mysqld.sym
+@end example
+
+Beachten Sie, dass viele MySQL-Binärdistributionen die obige Datei namens
+@code{mysqld.sym.gz} enthalten. In diesem Fall müssen Sie sie wie folgt
+entpacken:
+@example
+gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
+@end example
+
+@item
+Führen Sie @code{resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack}
+aus.
+
+Das gibt aus, wo @code{mysqld} starb. Wenn Ihnen das nicht hilft,
+herauszufinden, warum @code{mysqld} starb, sollten Sie einen Bug-Bericht
+machen und die Ausgabe des obigen Befehls in diesen Bericht einschließen.
+
+Beachten Sie aber, dass es uns in den meisten Fällen nicht weiterhilft, nur
+einen Stack-Trace zu haben, um die Ursache des Problems herauszufinden. Um
+den Bug feststellen oder einen Workaround zur Verfügung stellen zu können,
+müssen wir in den meisten Fällen die Anfrage kennen, die @code{mysqld}
+tötete, und am besten einen Testfall, so dass wir das Problem wiederholen
+können! @xref{Bug reports}.
+@end enumerate
+
+
+@node Using log files, Reproduceable test case, Using stack trace, Debugging server
+@c German node Log-Dateien benutzen
+@appendixsubsec Log-Dateien benutzen, um Gründe für Fehler in mysqld zu finden
+
+Beachten Sie, dass Sie vor dem Start von @code{mysqld} mit @code{--log}
+alle Ihre Tabellen mit @code{myisamchk} prüfen sollten.
+@xref{MySQL Database Administration}.
+
+Wenn @code{mysqld} stirbt oder hängenbleibt, sollten Sie ihn mit
+@code{--log} starten. Wenn @code{mysqld} wieder stirbt, können Sie das Ende
+der Log-Datei nach der Anfrage durchsuchen, die @code{mysqld} tötete.
+
+Wenn Sie @code{--log} ohne einen Dateinamen verwenden, wird das Log im
+Datenbank-Verzeichnis als 'hostname'.log gespeichert. In den meisten Fällen
+ist es die letzte Anfrage in der Log-Datei, die @code{mysqld} tötete, aber
+das sollten Sie falls möglich sicherstellen, indem Sie @code{mysqld} neu
+starten und dieselbe Anfrage mit dem @code{mysql}-Kommandozeilenwerkzeug
+wiederholen. Wenn das funktioniert, sollten Sie ebenfalls alle
+komplizierten Anfragen testen, die nicht beendet wurden.
+
+Sie können auch den Befehl @code{EXPLAIN} auf alle @code{SELECT}-Statements
+ausprobieren, die lange Zeit benötigen, um sicherzustellen, dass
+@code{mysqld} Indexe korrekt benutzt. @xref{EXPLAIN, , @code{EXPLAIN}}.
+
+Sie finden Anfragen, die zur Ausführung lange Zeit benötigen, indem Sie
+@code{mysqld} mit @code{--log-slow-queries} starten.
+@xref{Slow query log}.
+
+Wenn Sie den Text @code{mysqld restarted} in der Fehler-Log-Datei-Datei
+(normalerweise namens @file{hostname.err}) finden, haben Sie wahrscheinlich
+eine Anfrage gefunden, die @code{mysqld} zum Absturz brachte. Wenn das
+passiert, sollten Sie alle Ihre Tabellen mit @code{myisamchk} prüfen
+(@pxref{MySQL Database Administration}) und die Anfragen in den
+MySQL-Log-Dateien untersuchen, um herauszufinden, ob eine nicht
+funktioniert. Wenn Sie eine solche Anfrage finden, versuchen Sie zunächst,
+auf die neueste MySQL-Version zu aktualisieren. Wenn das nicht hilft und Sie
+nichts im @code{mysql}-Mailarchiv finden können, sollten Sie den Bug an
+@email{mysql@@lists.mysql.com} berichten. Links zu Mailarchiven finden Sie
+online auf der @uref{http://www.mysql.com/documentation/,
+MySQL-Dokumentationsseite}.
+
+Wenn Sie @code{mysqld} mit @code{--with-myisam-recover} gestartet haben,
+prüft MySQL automatisch @code{MyISAM}-Tabellen und versucht sie zu
+reparieren, wenn sie als 'nicht korrekt geschlossen' oder 'beschädigt'
+gekennzeichnet sind. Wenn das passiert, schreibt MySQL einen Eintrag in die
+@code{hostname.err}-Datei @code{'Warning: Checking table ...'}, der von
+@code{Warning: Repairing table} gefolgt wird, wenn die Tabelle repariert
+werden muss. Wenn Sie viele solcher Fehler erhalten, ohne dass
+@code{mysqld} direkt davor unerwartet gestorben ist, stimmt etwas nicht und
+muss weiter untersucht werden. @xref{Command-line options}.
+
+Natürlich ist es kein gutes Zeichen, wenn @code{mysqld} unerwartet stirbt,
+doch in diesem Fall sollte man nicht die @code{Checking table...}-Meldungen
+untersuchen, sondern statt dessen versuchen herauszufinden, warum
+@code{mysqld} starb.
+
+
+@node Reproduceable test case, , Using log files, Debugging server
+@c German node Reproduzierbarer Testfall
+@appendixsubsec Einen Testfall herstellen, wenn Sie Tabellenbeschädigung feststellen
+
+Wenn Sie beschädigte Tabellen erhalten oder wenn @code{mysqld} immer nach
+irgend einem Aktualisierungsbefehl fehlschlägt, können Sie mit folgendem
+überprüfen, ob der Bug reproduzierbar ist:
+
+@itemize @bullet
+@item
+Fahren Sie den MySQL-Daemon herunter (mit @code{mysqladmin shutdown}).
+@item
+Machen Sie eine Datensicherung der Tabellen (um dem sehr unwahrscheinlichen
+Fall vorzubeugen, dass die Reparatur etwas Schlechtes macht).
+@item
+Prüfen Sie alle Tabellen mit @code{myisamchk -s Datenbank/*.MYI}.
+Reparieren Sie jegliche beschädigten Tabellen mit @code{myisamchk -r
+datenbank/tabelle.MYI}.
+@item
+Machen Sie eine Datensicherung der Tabellen.
+@item
+Entfernen (oder verschieben) Sie jegliche alten Log-Dateien aus dem
+MySQL-Daten-Verzeichnis, wenn Sie mehr Platz brauchen.
+@item
+Starten Sie @code{mysqld} mit @code{--log-binary}. @xref{Binary log}.
+Wenn Sie eine Anfrage finden wollen, die @code{mysqld} zum Absturz brachte,
+sollten Sie @code{--log --log-binary} benutzen.
+@item
+Wenn Sie eine beschädigte Tabelle erhalten, halten Sie @code{mysqld} an.
+@item
+Stellen Sie die Datensicherung wieder her.
+@item
+Starten Sie den @code{mysqld}-Server neu, @strong{ohne}
+@code{--log-binary}.
+@item
+Führen Sie die Befehle mit @code{mysqlbinlog update-log-file | mysql}
+erneut aus. Die Update-Log-Datei wird im MySQL-Datenbank-Verzeichnis unter
+dem Namen @code{hostname-bin.#} gespeichert.
+@item
+Wenn die Tabellen wieder beschädigt werden oder Sie @code{mysqld} wieder
+dazu bringen können zu sterben, haben Sie einen reproduzierbaren Bug
+gefunden, der sich leicht beheben lassen sollte! Schicken Sie die Tabellen
+und die Binär-Log-Datei an @uref{ftp://support.mysql.com/pub/mysql/secret}
+und schicken Sie eine E-Mail an @email{bugs@@lists.mysql.com} oder (wenn
+Sie ein Support-Kunde sind) an @email{Support@@mysql.com}, und das
+MySQL-Team wird den Bug so schnell wie möglich beheben.
+@end itemize
+
+Sie können auch das Skript @code{mysql_find_rows} benutzen, um einfach
+einige der Aktualisierungs-Statements auszuführen, wenn Sie das Problem
+eingrenzen wollen.
+
+
+@node Debugging client, The DBUG package, Debugging server, Porting
+@c German node Clients debuggen
+@appendixsec Einen MySQL-Client debuggen
+
+@cindex debuggen, Client
+@cindex Clients, debuggen
+
+Um einen MySQL-Client mit dem integrierten Debug-Paket debuggen zu können,
+sollten Sie MySQL mit @code{--with-debug} oder @code{--with-debug=full}
+kompilieren. @xref{configure options}.
+
+@tindex MYSQL_DEBUG-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_DEBUG
+Bevor Sie einen Client laufen lassen, sollten Sie die
+@code{MYSQL_DEBUG}-Umgebungsvariable setzen:
+
+@example
+shell> MYSQL_DEBUG=d:t:O,/tmp/client.trace
+shell> export MYSQL_DEBUG
+@end example
+
+Das bringt Clients dazu, eine Trace-Datei in @file{/tmp/client.trace} zu
+erzeugen.
+
+Wenn Sie Probleme mit Ihrem eigenen Client-Code haben, sollten Sie
+versuchen, sich mit dem Server zu verbinden und Ihre Anfragen mit einem
+Client laufen zu lassen, der bekanntermaßen funktioniert. Lassen Sie dabei
+@code{mysql} im Debug-Modus laufen (unter der Annahme, dass Sie MySQL mit
+angeschaltetem Debuggen kompiliert haben):
+
+@example
+shell> mysql --debug=d:t:O,/tmp/client.trace
+@end example
+
+Das stellt nützliche Informationen für den Fall bereit, dass Sie einen
+Bug-Bericht schicken. @xref{Bug reports}.
+
+Wenn Ihr Client bei irgend einem 'zulässigen' Sperr-Code abstürzt, sollten
+Sie sicherstellen, dass Ihre @file{mysql.h}-Include-Datei mit Ihrer
+MySQL-Bibliotheksdatei zusammenpasst. Es ist ein häufiger Fehler, eine alte
+@file{mysql.h}-Datei aus einer alten MySQL-Installation mit einer neuen
+MySQL-Bibliothek zu benutzen.
+
+
+@node The DBUG package, Locking methods, Debugging client, Porting
+@c German node Das DBUG-Paket
+@appendixsec Das DBUG-Paket
+
+@cindex DBUG-Paket
+
+Der MySQL-Server und die meisten MySQL-Clients werden mit dem DBUG-Paket
+kompiliert, das ursprünglich von Fred Fish stammt. Wenn man MySQL zum
+Debuggen kompiliert hat, ermöglicht es dieses Paket, eine Trace-Datei davon
+zu erhalten, was das Programm debuggt. @xref{Making trace files}.
+
+Man benutzt das Debug-Paket durch Aufruf des Programms mit der
+@code{--debug="..."}- oder der @code{-#...}-Option.
+
+Die meisten MySQL-Programme haben eine vorgabemäßige Debug-Zeichenkette,
+die benutzt wird, wenn Sie keine Option für @code{--debug} angeben. Die
+vorgabemäßige Trace-Datei ist üblicherweise
+@code{/tmp/programm_name.trace} unter Unix und @code{\programm_name.trace}
+unter Windows.
+
+Die Debug-Steuerungs-Zeichenkette ist eine Folge durch Doppelpunkte
+getrennter Felder, wie folgt:
+
+@example
+<feld_1>:<feld_2>:...:<feld_N>
+@end example
+
+Jedes Feld besteht aus einem zwingend erforderlichen Flag-Zeichen, gefolgt
+durch ein optionales Komma (",") und eine durch Kommas getrennte Auflistung
+von Modifikatoren:
+
+@example
+flag[,modifikator,modifikator,...,modifikator]
+@end example
+
+Aktuell werden folgende Flag-Zeichen erkannt:
+
+@multitable @columnfractions .1 .9
+@item d
+ @tab Ausgabe von DBUG_<N>-Makros des aktuellen Status ermöglichen.
+Gegebenenfalls gefolgt von einer Auflistung von Schlüsselwörtern, die
+Ausgaben nur für die DBUG-Makros mit diesem Schlüsselwort auswählt. Eine
+leere Auflistung von Schlüsselwörtern bedeutet Ausgabe für alle Makros.
+@item D
+ @tab Nach jeder Debugger-Ausgabezeile verzögern. Das Argument ist die
+Anzahl von Zehntelsekunden der Verzögerung, abhängig von den Fähigkeiten
+der Maschine. @code{-#D,20} bedeutet als eine Verzögerung von 2 Sekunden.
+@item f
+ @tab Debuggen und / oder Tracen und Profilen auf die in der Auflistung
+genannten Funktionen beschränken. Beachten Sie, dass eine leere Liste alle
+Funktionen abschaltet. Die entsprechenden "d"- oder "t"-Flags müssen immer
+noch angegeben werden; dieser Flag beschränkt nur ihre Aktionen, wenn Sie
+angeschaltet sind.
+@item F
+ @tab Den Quell-Dateinamen für jede Zeile der Debug- oder Trace-Ausgabe
+festlegen.
+@item i
+ @tab Den Prozess mit der PID- oder Thread-Kennung für jede Ziele der
+Debug- oder Trace-Ausgabe festlegen.
+@item g @tab Profiling anschalten. Es wird eine Datei namens 'dbugmon.out'
+erzeugt, die Informationen enthält, die benutzt werden können, um das
+Programm zu profilen. Wir gegebenenfalls von einer Auflistung von
+Schlüsselwörter gefolgt, die Profiling nur für die Funktionen in dieser
+Liste auswählen. Eine leere Liste bedeutet, dass alle Funktionen in
+Betracht gezogen werden.
+@item L
+ @tab Die Quell-Datei-Zeilennummer für jede Zeile der Debug- oder
+Trace-Ausgabe festlegen.
+@item n
+ @tab Die aktuelle Funktionsverschachtelungstiefe für jede Zeile der Debug-
+oder Trace-Ausgabe ausgeben.
+@item N
+ @tab Jede Zeile der dbug-Ausgabe nummerieren.
+@item o
+ @tab Die Debugger-Ausgabe in die angegebene Datei umlenken. Die
+vorgabemäßige Ausgabe ist stderr.
+@item O
+ @tab Wie @code{O}, aber die Datei wird nach jedem Schreiben auf die Platte
+zurückgeschrieben (flush). Wenn nötig, wird die Datei geschlossen und
+wieder geöffnet.
+@item p
+ @tab Debugger-Aktionen auf die angegebenen Prozesse beschränken. Ein
+Prozess muss mit dem DBUG_PROCESS-Makro gekennzeichnet sein und mit einer
+der Aktionen in der Liste übereinstimmen, damit Debugger-Aktionen
+durchgeführt werden.
+@item P
+ @tab Den aktuellen Prozessnamen für jede Zeile der Debug- oder
+Trace-Ausgabe ausgeben.
+@item r
+ @tab Wenn ein neuer Zustand gepusht wird, nicht die
+Funktionsverschachtelungsebene des alten Zustands übernehmen (erben).
+Nützlich, wenn die Ausgabe am linken Rand anfangen soll.
+@item S
+ @tab Funktion _sanity(_datei_,_zeile_) bei jeder debuggten Funktion
+ausführen, bis _sanity() etwas anderes als 0 zurückgibt. (Wird meist
+zusammen mit safemalloc benutzt, um Speicherlecks zu finden.)
+@item t
+ @tab Trace-Zeile für Funktionsaufrufen / Funktionsende anschalten. Wird
+gegebenenfalls gefolgt von einer Liste (die nur einen Modifikator enthält), in
+der numerisch eine maximale Trace-Ebene angegeben wird, nach der keine
+Ausgaben mehr erfolgen, weder für Debuggen noch für das Tracen von Makros. Die
+Vorgabe ist eine Kompilierzeit-Option.
+@end multitable
+
+Einige Beispiele von Debug-Steuerungs-Zeichenketten, die auf einer
+Shell-Kommandozeile erscheinen können (das "-#" wird typischerweise
+benutzt, um eine Steuerungs-Zeichenkette für ein Applikationsprogramm
+einzuführen):
+
+@example
+-#d:t
+-#d:f,main,subr1:F:L:t,20
+-#d,input,output,files:n
+-#d:t:i:O,\\mysqld.trace
+@end example
+
+In MySQL werden gebräuchlicherweise (mit der @code{d}-Option) folgende Tags
+ausgegeben: @code{enter}, @code{exit}, @code{error}, @code{warning},
+@code{info} und @code{loop}.
+
+
+@node Locking methods, RTS-threads, The DBUG package, Porting
+@c German node Sperrmethoden
+@appendixsec Sperrmethoden
+
+@cindex Sperrmethoden
+@cindex Methoden, Sperr-
+
+Momentan unterstützt MySQL Tabellensperren nur für @code{ISAM}- /
+@code{MyISAM}- und @code{HEAP}-Tabellen und Sperren auf Seitenebene nur für
+@code{BDB}-Tabellen. @xref{Internal locking}. Bei @code{MyISAM}-Tabellen
+können Sie @code{INSERT} und @code{SELECT} ohne Sperren frei vermischen.
+(@code{Versionierung}).
+
+Ab Version 3.23.33 können Sie die Tabellensperr-Konkurrenz auf Ihrem System
+durch Prüfen der @code{Table_locks_waited}- und
+@code{Table_locks_immediate}-Umgebungsvariablen analysieren.
+
+Einige Datenbankbenutzer behaupten, dass MySQL keine große Anzahl
+gleichzeitiger Benutzer unterstützen kann, weil es kein Sperren auf
+Zeilenebene hat. Das mag bei einigen speziellen Applikationen zutreffen,
+aber nicht allgemein. Wie immer hängt das völlig davon ab, was Ihre
+Applikation macht, und davon, wie das Zugriffs-/Aktualisierungs-Muster der
+Daten aussieht.
+
+Vorteile für Zeilensperren:
+
+@itemize @bullet
+@item
+Weniger Sperrkonflikte beim Zugriff auf unterschiedliche Zeilen in vielen
+Threads.
+@item
+Weniger Änderungen bei Rollbacks.
+@item
+Macht es möglich, eine einzelne Zeile lange zu sperren.
+@end itemize
+
+Nachteile:
+
+@itemize @bullet
+@item
+Benötigt mehr Speicher als Sperren auf Seiten- oder Tabellenebene.
+@item
+Ist langsamer als Sperren auf Seiten- oder Tabellenebene, wenn es einen
+großen Teil der Tabelle betrifft, weil man viel mehr Sperren durchführen
+muss.
+@item
+Ist definitiv viel schlechter als andere Sperren, wenn Sie oft @code{GROUP
+BY} auf einen großen Teil der Daten ausführen oder wenn man die gesamte
+Tabelle oft scannen muss.
+@item
+Bei Sperren auf höherer Ebene kann man einfacher Sperren unterschiedlichen
+Typs unterstützen, um die Applikation zu optimieren, weil der
+Sperr-Overhead sich weniger als bei Sperren auf Zeilenebene bemerkbar
+macht.
+@end itemize
+
+Tabellensperren sind Seiten- oder Zeilensperren in folgenden Fällen
+überlegen:
+
+@itemize @bullet
+@item
+Wenn man meist liest.
+@item
+Wenn Lese- und Aktualisierungsoperationen auf strengen Schlüsseln erfolgen.
+Das ist dann der Fall, wenn man eine Zeile aktualisiert oder löscht, die
+mit einem Schlüssel-Lesen geholt werden kann:
+@example
+UPDATE tabelle SET spalte=wert WHERE eindeutige_schluessel_nummer
+DELETE FROM tabelle WHERE eindeutiger_schluessel=#
+@end example
+@item
+@code{SELECT} in Kombination mit @code{INSERT} (und sehr wenigen
+@code{UPDATE}'s und @code{DELETE}'s).
+@item
+Viele Scans / @code{GROUP BY} auf die gesamte Tabelle ohne irgend welche
+Schreibvorgänge.
+@end itemize
+
+Andere Optionen als Sperren auf Zeilen- / Seiten-Ebene:
+
+Versionierung (wie die, die wir bei MySQL für gleichzeitige Einfügevorgänge
+nutzen), bei der man gleichzeitig einen Schreibvorgang haben kann, während
+viele Lesevorgänge stattfinden. Das heißt, dass die Datenbank / Tabelle
+verschiedene Sichten der Daten unterstützt, abhängig davon, wann man
+anfing, darauf zuzugreifen. Andere Namen hierfür sind Zeitreisen, Kopieren
+beim Schreiben (Copy on Write) oder Kopieren bei Bedarf (Copy on Demand).
+
+Kopieren bei Bedarf ist in vielen Fällen viel besser als Sperren auf
+Seiten- oder Zeilenebene. Im schlimmsten Fall wird jedoch viel mehr
+Speicher verbraucht als bei der Benutzung normaler Sperren.
+
+Anstelle von Zeilen-Sperren kann man Sperren auf Applikationsebene
+benutzen (wie get_lock/release_lock in MySQL). Das funktioniert natürlich
+nur bei 'wohl erzogenen' Applikationen.
+
+In vielen Fällen kann man auf fortgeschrittene Art raten, welcher Sperrtyp
+der beste für die Applikation ist, aber allgemein ist es sehr schwer zu
+sagen, dass ein bestimmter Sperrtyp besser ist als ein anderer. Alles hängt
+von der Applikation ab, und verschiedene Teile der Applikation können nach
+unterschiedlichen Sperrtypen verlangen.
+
+Hier sind einige Tipps zu Sperren in MySQL:
+
+Bei Web-Applikation führen die meisten Applikationen viele SELECTs aus,
+sehr wenige DELETEs, UPDATEs hauptsächlich auf Schlüssel und INSERTs in
+einigen bestimmten Tabellen. Die grundlegende Einrichtung von MySQL ist
+hierfür BESTENS optimiert.
+
+Gleichzeitige Benutzer sind kein Problem, solange man UPDATEs und SELECTs
+nicht vermischt, die beide gleichzeitig viele Zeilen in derselben Tabelle
+untersuchen müssen.
+
+Wenn man INSERTs und DELETEs auf dieselbe Tabelle mischt, kann @code{INSERT
+DELAYED} eine große Hilfe sein.
+
+Man kann auch @code{LOCK TABLES} benutzen, um Dinge zu beschleunigen (viele
+UPDATEs innerhalb einer einzelnen Sperre sind viel schneller als UPDATEs
+ohne Sperren). Daten in unterschiedliche Tabellen aufteilen hilft hierbei
+auch.
+
+Wenn Sie Geschwindigkeitsprobleme mit den Tabellensperren in MySQL
+bekommen, können Sie diese eventuell dadurch lösen, dass Sie Ihre Tabellen
+in @code{BDB}-Tabellen umwandeln.
+@xref{BDB}.
+
+Der Optimierungsabschnitt dieses Handbuchs behandelt viele verschiedene
+Aspekte dessen, wie man seine Applikationen optimieren kann. @xref{Tips}.
+
+
+@node RTS-threads, Thread packages, Locking methods, Porting
+@c German node RTS-Thread
+@appendixsec Anmerkungen zu RTS-Thread
+
+@cindex RTS-Thread
+@cindex Thread, RTS
+
+Ich habe versucht, die RTS-Thread-Pakete bei MySQL zu benutzen, bin aber
+über folgende Probleme gestolpert:
+
+Sie benutzen die alte Version vieler POSIX-Aufrufe und es ist sehr mühsam,
+Wrapper für alle Funktionen zu schreiben. Ich neige dazu zu denken, dass es
+leichter ist, die Thread-Bibliotheken auf die neueste POSIX-Spezifikation
+zu ändern.
+
+Einige Wrapper sind bereits geschrieben. Siehe @file{mysys/my_pThread.c}
+wegen weiterer Informationen.
+
+Zumindest folgendes sollte geändert werden:
+
+@code{pthread_get_specific} sollte ein Argument benutzen.
+@code{sigwait} sollte zwei Argumente entgegennehmen.
+Viele Funktionen (zumindest @code{pthread_cond_wait} und
+@code{pthread_cond_timedwait}) sollten bei einem Fehler den Fehler-Code
+zurückgeben. Momentan geben sie -1 zurück und setzen @code{errno}.
+
+Ein weiteres Problem ist, dass Threads auf Benutzerebene das
+@code{ALRM}-Signal benutzen und dass dieses viele Funktionen abbricht
+(@code{read}, @code{write}, @code{open}, ...). MySQL sollte versuchen, nach
+der Unterbrechung all dieser Funktionen weiterzumachen, aber das ist nicht
+einfach zu verifizieren.
+
+Das größte ungelöste Problem ist folgendes:
+
+Um Alarme auf Thread-Ebene zu erhalten, änderte ich
+@file{mysys/thr_alarm.c} in der Art, dass es zwischen Alarmen wartet, mit
+@code{pthread_cond_timedwait()}, aber das bricht mit Fehler @code{EINTR}
+ab. Ich versuchte, die Thread-Bibliothek zu debuggen, um den Grund
+herauszufinden, konnte aber keine einfache Lösung finden.
+
+Wenn jemand MySQL mit RTS-Thread ausprobieren möchte, schlage ich folgendes
+vor:
+
+@itemize @bullet
+@item
+Funktionen, die MySQL benutzt, von der Thread-Bibliothek zu POSIX ändern.
+Das sollte nicht lange dauern.
+@item
+Alle Bibliotheken mit @code{-DHAVE_rts_thread} kompilieren.
+@item
+@code{thr_alarm} kompilieren.
+@item
+Wenn es kleine Unterschiede in der Implementation gibt, können diese
+behoben werden, indem man @file{my_pThread.h} und @file{my_pThread.c}
+ändert.
+@item
+@code{thr_alarm} laufen lassen. Wenn es ohne irgend welche ``warning''-,
+``error''- oder ``aborted''-Meldungen läuft, sind Sie auf dem richtigen
+Weg. Hier ist ein erfolgreiches Laufenlassen unter Solaris:
+@example
+Main Thread: 1
+Thread 0 (5) started
+Thread: 5 Waiting
+process_alarm
+Thread 1 (6) started
+Thread: 6 Waiting
+process_alarm
+process_alarm
+thread_alarm
+Thread: 6 Slept for 1 (1) sec
+Thread: 6 Waiting
+process_alarm
+process_alarm
+thread_alarm
+Thread: 6 Slept for 2 (2) sec
+Thread: 6 Simulation of no alarm needed
+Thread: 6 Slept for 0 (3) sec
+Thread: 6 Waiting
+process_alarm
+process_alarm
+thread_alarm
+Thread: 6 Slept for 4 (4) sec
+Thread: 6 Waiting
+process_alarm
+thread_alarm
+Thread: 5 Slept for 10 (10) sec
+Thread: 5 Waiting
+process_alarm
+process_alarm
+thread_alarm
+Thread: 6 Slept for 5 (5) sec
+Thread: 6 Waiting
+process_alarm
+process_alarm
+
+...
+thread_alarm
+Thread: 5 Slept for 0 (1) sec
+end
+@end example
+@end itemize
+
+
+@node Thread packages, , RTS-threads, Porting
+@c German node Thread-Pakete
+@appendixsec Unterschiede zwischen verschiedenen Thread-Paketen
+
+@cindex Thread-Pakete, Unterschiede
+
+MySQL ist sehr abhängig vom verwendeten Thread-Paket. Wenn Sie daher eine
+gute Plattform für MySQL auswählen, ist das Thread-Paket sehr wichtig.
+
+Es gibt mindestens drei Typen von Thread-Paketen:
+
+@itemize @bullet
+@item
+Benutzer-Thread in einem einzelnen Prozess. Das Thread-Umschalten wird mit
+Alarmen gemacht und die Thread-Bibliothek verwaltet alle nicht
+Thread-sicheren Funktionen mit Sperren. Lese-, Schreib- und
+Auswahl-Operationen werden üblicherweise mit einer Thread-spezifischen
+Auswahl verwaltet, die auf einen anderen Thread umschaltet, wenn der
+laufende Thread auf Daten warten muss.
+Wenn die Benutzer-Thread-Pakete in die Standard-Bibliotheken integriert
+sind (FreeBSD- und BSDI-Thread), erfordert das Thread-Paket weniger
+Overhead als Thread-Pakete, die alle unsicheren Aufrufen mappen müssen
+(MIT-pThread, FSU-PThread und RTS-Thread). In einigen Umgebungen
+(beispielsweise SCO) sind alle Systemaufrufe Thread-sicher, weshalb das
+Mapping sehr leicht durchgeführt werden kann (FSU-PThread unter SCO).
+Nachteil: Alle gemappten Aufrufe benötigen etwas Zeit und es ist sehr
+verzwickt, alle Situationen handhaben zu können. Üblicherweise gibt es auch
+einige Systemaufrufe, die vom Thread-Paket nicht gehandhabt werden (wie
+MIT-pThread und Sockets). Thread-Scheduling ist nicht immer optimal.
+@item
+Benutzer-Thread in separaten Prozessen. Das Thread-Umschalten wird vom
+Kernel durchgeführt und alle Daten werden zwischen den Threads geteilt. Das
+Thread-Paket verwaltet die Standard-Thread-Aufrufe, so dass diese Daten
+zwischen Threads teilen können. LinuxThread benutzt diese Methode.
+Nachteil: viele Prozesse. Die Erzeugung von Threads ist langsam. Wenn ein
+Thread stirbt, bleiben die übrigen üblicherweise hängen, und Sie müssen
+alle töten, bevor Sie neu starten können. Man kann sagen, dass die
+Thread-Umschaltung ziemlich viel kostet.
+@item
+Kernel-Thread. Das Thread-Umschalten wird von der Thread-Bibliothek oder
+dem Kernel durchgeführt und ist sehr schnell. Alles wird in einem Prozess
+gemacht, aber auch manchen Systemen zeigt @code{ps} die verschiedenen
+Threads. Wenn ein Thread abbricht, bricht der gesamte Prozess ab. Die
+meisten Systemaufrufe sind Thread-sicher und sollten sehr wenig Overhead
+beanspruchen. Solaris, HP-UX, AIX und OSF1 haben Kernel-Thread.
+@end itemize
+
+Auf manchen Systemen wird Kernel-Thread gehandhabt, indem
+Benutzerebenen-Thread in die Systembibliotheken integriert wird. In solchen
+Fällen kann das Umschalten nur von der Thread-Bibliothek durchgeführt
+werden und der Kernel ist sich nicht wirklich ``der Threads bewusst''.
+
+
+
+
+@node Environment variables, Regexp, Porting, Top
+@c German node Umgebungsvariablen
+@appendix Umgebungsvariablen
+
+@cindex Umgebungsvariablen, Auflistung
+
+Hier ist eine Auflistung aller Umgebungsvariablen, die direkt oder indirekt
+von MySQL benutzt werden. Die meisten von ihnen finden sich auch an anderen
+Stellen dieses Handbuchs.
+
+Beachten Sie, dass jegliche Optionen auf der Kommandozeile vorrangig vor
+Werten, die in Konfigurationsdateien und Umgebungsvariablen angegeben sind,
+und Werte in Konfigurationsdateien vorrangig vor Werten in
+Umgebungsvariablen sind.
+
+In vielen Fällen ist es vorzuziehen, eine configure-Datei anstelle von
+Umgebungsvariablen zu verwenden, um das Verhalten von MySQL zu
+beeinflussen. @xref{Option files}.
+
+@tindex CCX-Umgebungsvariable
+@tindex Umgebungsvariable, CCX
+@tindex CC-Umgebungsvariable
+@tindex Umgebungsvariable, CC
+@tindex CFLAGS-Umgebungsvariable
+@tindex Umgebungsvariable, CFLAGS
+@tindex CXXFLAGS-Umgebungsvariable
+@tindex Umgebungsvariable, CXXFLAGS
+@tindex DBI_USER-Umgebungsvariable
+@tindex Umgebungsvariable, DBI_USER
+@tindex DBI_TRACE-Umgebungsvariable
+@tindex Umgebungsvariable, DBI_TRACE
+@tindex HOME-Umgebungsvariable
+@tindex Umgebungsvariable, HOME
+@tindex LD_RUN_PATH-Umgebungsvariable
+@tindex Umgebungsvariable, LD_RUN_PATH
+@tindex MYSQL_DEBUG-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_DEBUG
+@tindex MYSQL_HISTFILE-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_HISTFILE
+@tindex MYSQL_HOST-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_HOST
+@tindex MYSQL_PWD-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_PWD
+@tindex MYSQL_TCP_PORT-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_TCP_PORT
+@tindex MYSQL_UNIX_PORT-Umgebungsvariable
+@tindex Umgebungsvariable, MYSQL_UNIX_PORT
+@tindex PATH-Umgebungsvariable
+@tindex Umgebungsvariable, PATH
+@tindex TMPDIR-Umgebungsvariable
+@tindex Umgebungsvariable, TMPDIR
+@tindex TZ-Umgebungsvariable
+@tindex Umgebungsvariable, TZ
+@tindex UMASK_DIR-Umgebungsvariable
+@tindex Umgebungsvariable, UMASK_DIR
+@tindex UMASK-Umgebungsvariable
+@tindex Umgebungsvariable, UMASK
+@tindex USER-Umgebungsvariable
+@tindex Umgebungsvariable, USER
+
+@multitable @columnfractions .2 .8
+@item @code{CCX} @tab Setzen Sie diese für Ihren C++-Kompiler, wenn Sie
+configure laufen lassen.
+@item @code{CC} @tab Setzen Sie diese für Ihren C-Kompiler, wenn Sie
+configure laufen lassen.
+@item @code{CFLAGS} @tab Flags für Ihren C-Kompiler, wenn Sie
+configure laufen lassen.
+@item @code{CXXFLAGS} @tab Flags für Ihren C++-Kompiler wenn Sie
+configure laufen lassen.
+@item @code{DBI_USER} @tab Der vorgabemäßige Benutzername für Perl-DBI.
+@item @code{DBI_TRACE} @tab Beim Tracen in Perl-DBI benutzt.
+@item @code{HOME} @tab Der vorgabemäßige Pfad für die
+@code{mysql}-History-Datei ist @file{$HOME/.mysql_history}.
+@item @code{LD_RUN_PATH} @tab Wird benutzt um anzugeben, wo Ihr
+@code{libmysqlclient.so} ist.
+@item @code{MYSQL_DEBUG} @tab Debug-Trace-Optionen beim Debuggen.
+@item @code{MYSQL_HISTFILE} @tab Der Pfad zur @code{mysql}-History-Datei.
+@item @code{MYSQL_HOST} @tab Vorgabemäßiger Hostname, der von der
+@code{mysql}-Befehlszeilenaufforderung benutzt wird.
+@item @code{MYSQL_PWD} @tab Das vorgabemäßige Passwort bei der Verbindung
+mit @code{mysqld}. Beachten Sie, dass die Benutzung dieser
+Umgebungsvariablen unsicher ist!
+@item @code{MYSQL_TCP_PORT} @tab Der vorgabemäßige TCP/IP-Port.
+@item @code{MYSQL_UNIX_PORT} @tab Der vorgabemäßige Socket; benutzt für
+Verbindungen nach @code{localhost}.
+@item @code{PATH} @tab Wird von der Shell benutzt, um die MySQL-Programme
+zu finden.
+@item @code{TMPDIR} @tab Das Verzeichnis, in dem temporäre Tabellen /
+Dateien erzeugt werden.
+@item @code{TZ} @tab Diese Variable sollte auf Ihre lokale Zeitzone gesetzt
+sein. @xref{Timezone problems}.
+@item @code{UMASK_DIR} @tab Die Erzeugungsmaske (Creation Mask) des
+Benutzer-Verzeichnisses, wenn Verzeichnisse angelegt werden. Beachten Sie,
+dass diese mit @code{UMASK} mit einem logischen UND verknüpft wird!
+@item @code{UMASK} @tab Die Erzeugungsmaske (Creation Mask) bei der
+Erzeugung von Dateien.
+@item @code{USER} @tab Der vorgabemäßige Benutzer unter Windows, der beim
+Verbinden mit @code{mysqld} benutzt wird.
+@end multitable
+
+
+
+
+@node Regexp, GPL license, Environment variables, Top
+@c German node Reguläre Ausdrücke
+@appendix Beschreibung der MySQL-Syntax für reguläre Ausdrücke
+
+@cindex regex
+@cindex Syntax regulärer Ausdrücke, Beschreibung
+@cindex Syntax, reguläre Ausdrücke
+
+Ein regulärer Ausdruck (regex) ist eine mächtige Möglichkeit, eine komplexe
+Suche zu formulieren.
+
+MySQL benutzt Henry Spencers Implementation regulärer Ausdrücke, die
+anstrebt, POSIX-1003.2-konform zu sein. MySQL benutzt die erweiterte
+Version.
+
+Die vorliegende vereinfachte Referenz überspringt die Details. Um genauere
+Informationen zu erhalten, sehen Sie sich Henry Spencers
+@code{regex(7)}-Handbuchseite an, die in der Quelldistribution enthalten
+ist. @xref{Credits}.
+
+Ein regulärer Ausdruck beschreibt einen Satz von Zeichenketten. Der
+einfachste regexp ist einer, der keine Sonderzeichen enthält. Der regexp
+@code{hello} beispielsweise stimmt mit @code{hello} und sonst nichts
+überein.
+
+Nicht triviale reguläre Ausdrücke benutzen bestimmte spezielle Konstrukte,
+so dass sie mit mehr als einer Zeichenkette übereinstimmen können. Der
+regexp @code{hallo|stefan} beispielsweise stimmt entweder mit der
+Zeichenkette @code{hallo} oder der Zeichenkette @code{stefan} überein.
+
+Um ein komplexeres Beispiel zu geben, stimmt der regexp @code{B[an]*s} mit
+jeder der Zeichenketten @code{Bananas}, @code{Baaaaas}, @code{Bs} und jeder
+anderen Zeichenkette überein, die mit einem @code{B} anfängt, mit einem
+@code{s} aufhört und jede beliebige Anzahl von @code{a}- oder
+@code{n}-Zeichen dazwischen enthält.
+
+Ein regulärer Ausdruck kann jedes der folgenden Sonderzeichen bzw.
+Konstrukte benutzen (0 = keine Übereinstimmung):
+@table @code
+@item ^
+Stimmt mit dem Anfang einer Zeichenkette überein.
+@example
+mysql> select "fo\nfo" REGEXP "^fo$"; -> 0
+mysql> select "fofo" REGEXP "^fo"; -> 1
+@end example
+@item $
+Stimmt mit dem Ende einer Zeichenkette überein.
+@example
+mysql> select "fo\no" REGEXP "^fo\no$"; -> 1
+mysql> select "fo\no" REGEXP "^fo$"; -> 0
+@end example
+@item .
+Stimmt mit jedem Zeichen überein (inklusive neue Zeile).
+@example
+mysql> select "fofo" REGEXP "^f.*"; -> 1
+mysql> select "fo\nfo" REGEXP "^f.*"; -> 1
+@end example
+@item a*
+Stimmt mit jeder Folge von 0 oder mehr @code{a}-Zeichen überein.
+@example
+mysql> select "Ban" REGEXP "^Ba*n"; -> 1
+mysql> select "Baaan" REGEXP "^Ba*n"; -> 1
+mysql> select "Bn" REGEXP "^Ba*n"; -> 1
+@end example
+@item a+
+Stimmt mit jeder Folge von einem oder mehr @code{a}-Zeichen überein.
+@example
+mysql> select "Ban" REGEXP "^Ba+n"; -> 1
+mysql> select "Bn" REGEXP "^Ba+n"; -> 0
+@end example
+@item a?
+Stimmt mit 0 oder einem @code{a}-Zeichen überein.
+@example
+mysql> select "Bn" REGEXP "^Ba?n"; -> 1
+mysql> select "Ban" REGEXP "^Ba?n"; -> 1
+mysql> select "Baan" REGEXP "^Ba?n"; -> 0
+@end example
+@item de|abc
+Stimmt mit den Zeichenfolgen @code{de} oder @code{abc} überein.
+@example
+mysql> select "pi" REGEXP "pi|apa"; -> 1
+mysql> select "axe" REGEXP "pi|apa"; -> 0
+mysql> select "apa" REGEXP "pi|apa"; -> 1
+mysql> select "apa" REGEXP "^(pi|apa)$"; -> 1
+mysql> select "pi" REGEXP "^(pi|apa)$"; -> 1
+mysql> select "pix" REGEXP "^(pi|apa)$"; -> 0
+@end example
+@item (abc)*
+Stimmt mit 0 oder mehr Instanzen der Folge @code{abc} überein.
+@example
+mysql> select "pi" REGEXP "^(pi)*$"; -> 1
+mysql> select "pip" REGEXP "^(pi)*$"; -> 0
+mysql> select "pipi" REGEXP "^(pi)*$"; -> 1
+@end example
+@item @{1@}
+@itemx @{2,3@}
+Es gibt eine allgemeinere Schreibweise für regexps, die mit vielen
+Vorkommen des vorherigen Atoms übereinstimmen.
+@table @code
+@item a*
+Kann als @code{a@{0,@}} geschrieben werden.
+@item a+
+Kann als @code{a@{1,@}} geschrieben werden.
+@item a?
+Kann als @code{a@{0,1@}} geschrieben werden.
+@end table
+
+Um genauer zu sein, stimmt ein Atom, gefolgt von einer Begrenzung, die eine
+Ganzzahl @code{i} und keine Kommas enthält, mit einer Folge von genau
+@code{i} Übereinstimmungen des Atoms überein. Ein Atom gefolgt von einer
+Begrenzung, die eine Ganzzahl @code{i} und ein Komma enthält, stimmt mit
+einer Folge von @code{i} oder mehr Übereinstimmungen des Atoms überein. Ein
+Atom, gefolgt von einer Begrenzung, die zwei Ganzzahlen @code{i} und
+@code{j} Übereinstimmungen enthält, stimmt mit einer Folge von @code{i} bis
+@code{j} (inklusive) Übereinstimmungen des Atoms überein.
+
+Beide Argumente müssen im Bereich von @code{0} bis @code{RE_DUP_MAX}
+(Vorgabe 255) inklusive sein. Wenn es zwei Argumente gibt, muss das zweite
+größer oder gleich dem ersten sein.
+@item [a-dX]
+@itemx [^a-dX]
+Stimmt mit jedem Zeichen überein, was entweder @code{a}, @code{b},
+@code{c}, @code{d} oder @code{X} ist (oder nicht ist, wenn ^ benutzt wird).
+Um ein literales @code{]}-Zeichen einzuschließen, muss es unmittelbar der
+öffnenden Klammer @code{[} folgen. Um ein literales @code{-}-Zeichen
+einzuschließen, muss es zuerst oder zuletzt geschrieben werden. Daher
+stimmt @code{[0-9]} mit jeder Dezimalziffer überein. Alle Zeichen, die
+innerhalb eines @code{[]}-Paars keine definierte Bedeutung haben, haben
+keine spezielle Bedeutung und stimmen nur mit sich selbst überein.
+@example
+mysql> select "aXbc" REGEXP "[a-dXYZ]"; -> 1
+mysql> select "aXbc" REGEXP "^[a-dXYZ]$"; -> 0
+mysql> select "aXbc" REGEXP "^[a-dXYZ]+$"; -> 1
+mysql> select "aXbc" REGEXP "^[^a-dXYZ]+$"; -> 0
+mysql> select "gheis" REGEXP "^[^a-dXYZ]+$"; -> 1
+mysql> select "gheisa" REGEXP "^[^a-dXYZ]+$"; -> 0
+@end example
+@item [[.zeichen.]]
+Die Zeichenfolge des vereinigten Elements. Die Folge ist ein einzelnes
+Element der Ausdrucksliste in der Klammer. Ein Klammerausdruck, der ein
+Mehrzeichen-Vereinigungselement enthält, kann daher mit mehr als einem
+Zeichen übereinstimmen. Wenn die Vereinigungsfolge zum Beispiel ein
+@code{ch}-Vereinigungselement enthält, stimmt der reguläre Ausdruck
+@code{[[.ch.]]*c} mit den ersten fünf Zeichen von @code{chchcc} überein.
+
+@item [=zeichen_klasse=]
+Eine Äquivalenzklasse, die für Zeichenfolgen aller Vereinigungselemente
+dieser steht, inklusive sich selbst.
+
+Wenn zum Beispiel @code{o} und @code{(+)} die Mitglieder einer
+Äquivalenzklasse sind, sind @code{[[=o=]]}, @code{[[=(+)=]]} und
+@code{[o(+)]} allesamt Synonyme. Eine Äquivalenzklasse darf kein Endpunkt
+eines Bereichs sein.
+
+@item [:zeichen_klasse:]
+Innerhalb eines Klammerausdrucks steht der Name einer Zeichenklasse, die in
+@code{[:} und @code{:]} eingeschlossen ist, für die Auflistung aller
+Zeichen, die zu dieser Klasse gehören. Standard-Zeichenklassennamen sind:
+
+@multitable @columnfractions .33 .33 .33
+@item alnum @tab digit @tab punct
+@item alpha @tab graph @tab space
+@item empty @tab lower @tab upper
+@item cntrl @tab print @tab xdigit
+@end multitable
+
+Diese stehen für die Zeichenklassen, die auf der
+@code{ctype(3)}-Handbuchseite definiert sind. Ein Locale darf andere zur
+Verfügung stellen. Eine Zeichenklasse darf nicht als Endpunkt eines
+Bereichs benutzt werden.
+@example
+mysql> select "justalnums" REGEXP "[[:alnum:]]+"; -> 1
+mysql> select "!!" REGEXP "[[:alnum:]]+"; -> 0
+@end example
+
+@item [[:<:]]
+@itemx [[:>:]]
+Diese stimmen mit der Null-Zeichenkette am Anfang bzw. am Ende eines Worts
+überein. Ein Wort ist definiert als Folge von Wort-Zeichen, dem weder
+Wortzeichen vorangestellt sind noch darauf folgen. Ein Wortzeichen ist ein
+alnum-Zeichen (wie in @code{ctype(3)} definiert) oder ein Unterstrich
+(@code{_}).
+@example
+mysql> select "a word a" REGEXP "[[:<:]]word[[:>:]]"; -> 1
+mysql> select "a xword a" REGEXP "[[:<:]]word[[:>:]]"; -> 0
+@end example
+@end table
+
+@example
+mysql> select "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1
+@end example
+
+
+@page
+@c This node name ist special
+
+
+
+@node GPL license, LGPL license, Regexp, Top
+@c German node GPL-Lizenz
+@appendix GNU GENERAL PUBLIC LICENSE
+
+@cindex GPL, General Public License
+@cindex GPL, GNU General Public License
+
+@center Version 2, Juni 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Jeder hat das Recht, diese Lizenzurkunde zu vervielfältigen und
+unveränderte Kopien zu verbreiten; Änderungen sind jedoch nicht gestattet.
+@end display
+
+@appendixsec Vorwort
+
+Die meisten Softwarelizenzen sind daraufhin entworfen worden, Ihnen die
+Freiheit zu nehmen, die Software weiterzugeben und zu verändern.
+Im Gegensatz dazu soll Ihnen die GNU General Public License, die
+allgemeine öffentliche GNU-Lizenz, ebendiese Freiheit garantieren.
+Sie soll sicherstellen, dass die Software für alle Benutzer frei ist.
+Diese Lizenz gilt für den Großteil der von der Free Software Foundation
+herausgegebenen Software und für alle anderen Programme, deren Autoren
+ihr Werk dieser Lizenz unterstellt haben. Auch Sie können diese
+Möglichkeit der Lizenzierung für Ihre Programme anwenden.
+(Ein anderer Teil der Software der Free Software Foundation unterliegt
+stattdessen der GNU Library General Public License, der allgemeinen
+öffentlichen GNU-Lizenz für Bibliotheken.)
+
+Die Bezeichnung "freie" Software bezieht sich auf Freiheit, nicht auf
+den Preis. Unsere Lizenzen sollen Ihnen die Freiheit garantieren,
+Kopien freier Software zu verbreiten (und etwas für diesen Service zu
+berechnen, wenn Sie möchten), die Möglichkeit, die Software im Quelltext
+zu erhalten oder den Quelltext auf Wunsch zu bekommen. Die Lizenzen
+sollen garantieren, dass Sie die Software ändern oder Teile davon in
+neuen freien Programmen verwenden dürfen - und dass Sie wissen, dass
+Sie dies alles tun dürfen.
+
+Um Ihre Rechte zu schützen, müssen wir Einschränkungen machen, die es
+jedem verbieten, Ihnen diese Rechte zu verweigern oder Sie aufzufordern,
+auf diese Rechte zu verzichten. Aus diesen Einschränkungen folgen
+bestimmte Verantwortlichkeiten für Sie, wenn Sie Kopien der Software
+verbreiten oder sie verändern.
+
+Beispielsweise müssen Sie den Empfängern alle Rechte gewähren, die
+Sie selbst haben, wenn Sie - kostenlos oder gegen Bezahlung - Kopien
+eines solchen Programms verbreiten. Sie müssen sicherstellen, dass auch
+sie den Quelltext erhalten bzw. erhalten können. Und Sie müssen ihnen
+diese Bedingungen zeigen, damit sie Ihre Rechte kennen.
+
+Wir schützen Ihre Rechte in zwei Schritten: (1) Wir stellen die Software
+unter ein Urheberrecht (Copyright), und (2) wir bieten Ihnen diese Lizenz
+an, die Ihnen das Recht gibt, die Software zu vervielfältigen, zu
+verbreiten und/oder zu verändern.
+
+Um die Autoren und uns zu schützen, wollen wir darüberhinaus sicherstellen,
+dass jeder erfährt, dass für diese freie Software keinerlei Garantie besteht.
+Wenn die Software von jemand anderem modifiziert und weitergegeben wird,
+möchten wir, dass die Empfänger wissen, dass sie nicht das Original erhalten
+haben, damit von anderen verursachte Probleme nicht den Ruf des
+ursprünglichen Autors schädigen.
+
+Schließlich und endlich ist jedes freie Programm permanent durch
+Software-Patente bedroht. Wir möchten die Gefahr ausschließen, dass
+Distributoren eines freien Programms individuell Patente lizensieren
+ - mit dem Ergebnis, dass das Programm proprietär würde. Um dies zu
+ verhindern, haben wir klargestellt, dass jedes Patent entweder für freie
+Benutzung durch jedermann lizenziert werden muss oder überhaupt nicht
+lizenziert werden darf.
+
+Es folgen die genauen Bedingungen für die Vervielfältigung,
+Verbreitung und Bearbeitung:
+
+@iftex
+@appendixsec Bedingungen für die Vervielfältigung,
+Verbreitung und Bearbeitung
+@end iftex
+@ifinfo
+@center GNU GENERAL PUBLIC LICENSE
+@center Bedingungen für die Vervielfältigung, Verbreitung
+und Bearbeitung
+@end ifinfo
+
+@enumerate 0
+@item
+Diese Lizenz gilt für jedes Programm und jedes andere Werk, in dem
+ein entsprechender Vermerk des Copyright-Inhabers darauf hinweist,
+dass das Werk unter den Bestimmungen dieser General Public License
+verbreitet werden darf. Im folgenden wird jedes derartige Programm
+oder Werk als "das Programm" bezeichnet; die Formulierung "auf dem
+Programm basierendes Werk" bezeichnet das Programm sowie jegliche
+Bearbeitung des Programms im urheberrechtlichen Sinne, also ein Werk,
+welches das Programm, auch auszugsweise, sei es unverändert oder
+verändert und/oder in eine andere Sprache übersetzt, enthält.
+(Im folgenden wird die Übersetzung ohne Einschränkung als
+"Bearbeitung" eingestuft.) Jeder Lizenznehmer wird im folgenden
+als "Sie" angesprochen.
+
+Andere Handlungen als Vervielfältigung, Verbreitung und Bearbeitung
+werden von dieser Lizenz nicht berührt; sie fallen nicht in Ihren
+Anwendungsbereich. Der Vorgang der Ausführung des Programms wird
+nicht eingeschränkt, und die Ausgaben des Programms unterliegen
+dieser Lizenz nur, wenn der Inhalt ein auf dem Programm basierendes
+Werk darstellt (unabhängig davon, dass die Ausgabe durch die
+Ausführung des Programmes erfolgte). Ob dies zutrifft, hängt von den
+Funktionen des Programms ab.
+
+@item
+Sie dürfen auf beliebigen Medien unveränderte Kopien des Quelltextes
+des Programms, wie sie ihn erhalten haben, anfertigen und verbreiten.
+Voraussetzung hierfür ist, dass Sie mit jeder Kopie einen entsprechenden
+Copyright-Vermerk sowie einen Haftungsausschluss veröffentlichen, alle
+Vermerke, die sich auf diese Lizenz und das Fehlen einer Garantie
+beziehen, unverändert lassen und desweiteren allen anderen Empfängern
+des Programms zusammen mit dem Programm eine Kopie dieser Lizenz
+zukommen lassen.
+
+Sie dürfen für den eigentlichen Kopiervorgang eine Gebühr verlangen.
+Wenn Sie es wünschen, dürfen Sie auch gegen Entgelt eine Garantie
+für das Programm anbieten.
+
+@item
+Sie dürfen Ihre Kopie(n) des Programms oder eines Teils davon
+verändern, wodurch ein auf dem Programm basierendes Werk entsteht;
+Sie dürfen derartige Bearbeitungen unter den Bestimmungen von
+Paragraph 1 vervielfältigen und verbreiten, vorausgesetzt, dass
+zusätzlich alle folgenden Bedingungen erfüllt werden:
+
+@enumerate a
+@item
+Sie müssen die veränderten Dateien mit einem auffälligen Vermerk
+versehen, der auf die von Ihnen vorgenommene Modifizierung und
+das Datum jeder Änderung hinweist.
+
+@item
+Sie müssen dafür sorgen, dass jede von Ihnen verbreitete oder
+veröffentlichte Arbeit, die ganz oder teilweise von dem Programm
+oder Teilen davon abgeleitet ist, Dritten gegenüber als Ganzes
+unter den Bedingungen dieser Lizenz ohne Lizenzgebühren zur
+Verfügung gestellt wird.
+
+@item
+Wenn das veränderte Programm normalerweise bei der Ausführung
+interaktiv Kommandos einliest, müssen Sie dafür sorgen, dass es,
+wenn es auf dem üblichsten Wege für solche interaktive Nutzung
+gestartet wird, eine Meldung ausgibt oder ausdruckt, die einen
+geeigneten Copyright-Vermerk enthält sowie einen Hinweis, dass es
+keine Gewährleistung gibt (oder anderenfalls, dass Sie Garantie
+leisten), und dass die Benutzer das Programm unter diesen
+Bedingungen weiter verbreiten dürfen. Auch muss der Benutzer darauf
+hingewiesen werden, wie er eine Kopie dieser Lizenz ansehen kann.
+(Ausnahme: Wenn das Programm selbst interaktiv arbeitet, aber
+normalerweise keine derartige Meldung ausgibt, muss Ihr auf dem
+Programm basierendes Werk auch keine solche Meldung ausgeben).
+@end enumerate
+
+Diese Anforderungen betreffen das veränderte Werk als Ganzes.
+Wenn identifizierbare Abschnitte des Werkes nicht von dem
+Programm abgeleitet sind und vernünftigerweise selbst als
+unabhängige und eigenständige Werke betrachtet werden können, dann
+erstrecken sich diese Lizenz und Ihre Bedingungen nicht auf
+diese Abschnitte, wenn sie als eigenständige Werke verbreitet
+werden. Wenn Sie jedoch dieselben Abschnitte als Teil eines
+Ganzen verbreiten, dass ein auf dem Programm basierendes Werk
+darstellt, dann muss die Verbreitung des Ganzen nach den
+Bedingungen dieser Lizenz erfolgen, deren Bedingungen für
+weitere Lizenznehmer somit auf die Gesamtheit ausgedehnt werden
+- und damit auf jeden einzelnen Teil, unabhängig vom jeweiligen Autor.
+
+Somit ist es nicht die Absicht dieses Abschnittes, Rechte für
+Werke in Anspruch zu nehmen oder zu beschneiden, die komplett
+von Ihnen geschrieben wurden; vielmehr ist es die Absicht,
+die Rechte zur Kontrolle der Verbreitung von Werken, die auf
+dem Programm basieren oder unter seiner auszugsweisen
+Verwendung zusammengestellt worden sind, auszuüben.
+
+Ferner bringt ein einfaches Zusammenstellen eines anderen Werkes,
+das nicht auf dem Programm basiert, zusammen mit dem Programm
+oder einem auf dem Programm basierenden Werk auf ein- und
+demselben Speicher- oder Vertriebsmedium das andere Werk nicht in
+den Anwendungsbereich dieser Lizenz.
+
+@item
+Sie dürfen das Programm (oder ein darauf basierendes Werk gemäß
+Paragraph 2) als Objectcode oder in ausführbarer Form unter den
+Bedingungen von Paragraph 1 und 2 vervielfältigen und verbreiten
+- vorausgesetzt, dass Sie außerdem eine der folgenden Leistungen
+erbringen:
+
+@enumerate a
+@item
+Liefern Sie das Programm zusammen mit dem vollständigen
+zugehörigen maschinenlesbaren Quelltext auf einem für den
+Datenaustausch üblichen Medium aus, wobei die Verteilung unter den
+Bedingungen der Paragraphen 1 und 2 erfolgen muß. Oder:
+
+@item
+Liefern Sie das Programm zusammen mit einem mindestens drei
+Jahre lang gültigen schriftlichen Angebot aus, jedem Dritten
+eine vollständige maschinenlesbare Kopie des Quelltextes zur
+Verfügung zu stellen - zu nicht höheren Kosten als denen, die
+durch den physikalischen Kopiervorgang anfallen -, wobei der
+Quelltext unter den Bedingungen der Paragraphen 1 und 2 auf
+einem für den Datenaustausch üblichen Medium weitergegeben
+wird. Oder:
+
+@item
+Liefern Sie das Programm zusammen mit dem schriftlichen An-
+gebot der Zurverfügungstellung des Quelltextes aus, das Sie
+selbst erhalten haben. (Diese Alternative ist nur für
+nicht-kommerzielle Verbreitung zulässig und nur, wenn Sie
+das Programm als Objectcode oder in ausführbarer Form mit
+einem entsprechenden Angebot gemäß Absatz b erhalten haben.)
+@end enumerate
+
+Unter dem Quelltext eines Werkes wird diejenige Form des Werkes
+verstanden, die für Bearbeitungen vorzugsweise verwendet wird.
+Für ein ausführbares Programm bedeutet "der komplette Quell-
+text": Der Quelltext aller im Programm enthaltenen Module ein-
+schließlich aller zugehörigen Modulschnittstellen-Definitions-
+dateien sowie der zur Compilation und Installation verwendeten
+Skripte. Als besondere Ausnahme jedoch braucht der verteilte
+Quelltext nichts von dem zu enthalten, was üblicherweise
+(entweder als Quelltext oder in binärer Form) zusammen mit den
+Hauptkomponenten des Betriebssystems (Kernel, Compiler usw.)
+geliefert wird, unter dem das Programm läuft - es sei denn,
+diese Komponente selbst gehört zum ausführbaren Programm.
+
+Wenn die Verbreitung eines ausführbaren Programms oder des
+Objectcodes dadurch erfolgt, dass der Kopierzugriff auf eine
+dafür vorgesehene Stelle gewährt wird, so gilt die Gewährung
+eines gleichwertigen Zugriffs auf den Quelltext als Verbreitung
+des Quelltextes, auch wenn Dritte nicht dazu gezwungen sind,
+den Quelltext zusammen mit dem Objectcode zu kopieren.
+
+@item
+Sie dürfen das Programm nicht vervielfältigen, verändern, weiter
+lizenzieren oder verbreiten, sofern es nicht durch diese Lizenz
+ausdrücklich gestattet ist. Jeder anderweitige Versuch der
+Vervielfältigung, Modifizierung, Weiterlizenzierung und Verbreitung
+ist nichtig und beendet automatisch Ihre Rechte unter dieser
+Lizenz. Jedoch werden die Lizenzen Dritter, die von Ihnen Kopien
+oder Rechte unter dieser Lizenz erhalten haben, nicht beendet,
+solange diese die Lizenz voll anerkennen und befolgen.
+
+@item
+Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da Sie sie
+nicht unterzeichnet haben. Jedoch gibt Ihnen nichts anderes die
+Erlaubnis, das Programm oder von ihm abgeleitete Werke zu
+verändern oder zu verbreiten. Diese Handlungen sind gesetzlich
+verboten, wenn Sie diese Lizenz nicht anerkennen. Indem Sie das
+Programm (oder ein darauf basierendes Werk) verändern oder
+verbreiten, erklären Sie Ihr Einverständnis mit dieser Lizenz und
+mit allen Ihren Bedingungen bezüglich der Vervielfältigung,
+Verbreitung und Veränderung des Programms oder eines darauf
+basierenden Werkes.
+
+@item
+Jedesmal, wenn Sie das Programm (oder ein auf dem Programm
+basierendes Werk) weitergeben, erhält der Empfänger automatisch
+vom ursprünglichen Lizenzgeber die Lizenz, das Programm
+entsprechend den hier festgelegten Bestimmungen zu vervielfältigen,
+zu verbreiten und zu verändern. Sie dürfen keine weiteren
+Einschränkungen der Durchsetzung der hierin zugestandenen Rechte
+des Empfängers vornehmen. Sie sind nicht dafür verantwortlich,
+die Einhaltung dieser Lizenz durch Dritte durchzusetzen.
+
+@item
+Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs einer
+Patentverletzung oder aus einem anderen Grunde (nicht auf Patent
+fragen begrenzt) Bedingungen (durch Gerichtsbeschluß, Vergleich
+oder anderweitig) auferlegt werden, die den Bedingungen dieser
+Lizenz widersprechen, so befreien Sie diese Umstände nicht von
+den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht möglich ist,
+das Programm unter gleichzeitiger Beachtung der Bedingungen in
+dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu ver-
+breiten, dann dürfen Sie als Folge das Programm überhaupt nicht
+verbreiten. Wenn zum Beispiel ein Patent nicht die gebührenfreie
+Weiterverbreitung des Programms durch diejenigen erlaubt, die das
+Programm direkt oder indirekt von Ihnen erhalten haben, dann
+besteht der einzige Weg, sowohl das Patentrecht als auch diese
+Lizenz zu befolgen, darin, ganz auf die Verbreitung des Programms
+zu verzichten.
+
+Sollte sich ein Teil dieses Paragraphen als ungültig oder unter
+bestimmten Umständen nicht durchsetzbar erweisen, so soll dieser
+Paragraph seinem Sinne nach angewandt werden; im übrigen soll
+dieser Paragraph als Ganzes gelten.
+
+Zweck dieses Paragraphen ist nicht, Sie dazu zu bringen,
+irgendwelche Patente oder andere Eigentumsansprüche zu verletzen oder
+die Gültigkeit solcher Ansprüche zu bestreiten; dieser Paragraph
+hat einzig den Zweck, die Integrität des Verbreitungssystems der
+freien Software zu schützen, das durch die Praxis öffentlicher
+Lizenzen verwirklicht wird. Viele Leute haben großzügige Beiträge
+zu dem großen Angebot der mit diesem System verbreiteten Software
+im Vertrauen auf die konsistente Anwendung dieses Systems
+geleistet; es liegt am Autor/Geber, zu entscheiden, ob er die
+Software mittels irgendeines anderen Systems verbreiten will; ein
+Lizenznehmer hat auf diese Entscheidung keinen Einfluss.
+
+Dieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als
+Konsequenz aus dem Rest dieser Lizenz betrachtet wird.
+
+@item
+Wenn die Verbreitung und/oder die Benutzung des Programms in be-
+stimmten Staaten entweder durch Patente oder durch urheberrechtlich
+geschützte Schnittstellen eingeschränkt ist, kann der Urheberrechts-
+inhaber, der das Programm unter diese Lizenz gestellt hat, eine
+explizite geographische Beschränkung der Verbreitung angeben, in der
+diese Staaten ausgeschlossen werden, so dass die Verbreitung nur
+innerhalb und zwischen den Staaten erlaubt ist, die nicht ausge-
+schlossen sind. In einem solchen Fall beinhaltet diese Lizenz die
+Beschränkung, als wäre sie in diesem Text niedergeschrieben.
+
+@item
+Die Free Software Foundation kann von Zeit zu Zeit überarbeitete
+und/oder neue Versionen der General Public License veröffentlichen.
+Solche neuen Versionen werden vom Grundprinzip her der gegenwärtigen
+entsprechen, können aber im Detail abweichen, um neuen Problemen und
+Anforderungen gerecht zu werden.
+
+Jede Version dieser Lizenz hat eine eindeutige Versionsnummer.
+Wenn in einem Programm angegeben wird, dass es dieser Lizenz in einer
+bestimmten Versionsnummer oder "jeder späteren Version" ("any later
+version") unterliegt, so haben Sie die Wahl, entweder den Bestimmungen
+der genannten Version zu folgen oder denen jeder beliebigen späteren
+Version, die von der Free Software Foundation veröffentlicht wurde.
+Wenn das Programm keine Versionsnummer angibt, können Sie eine beliebige
+Version wählen, die je von der Free Software Foundation veröffentlicht
+wurde.
+
+@item
+Wenn Sie den Wunsch haben, Teile des Programms in anderen freien Programmen
+zu verwenden, deren Bedingungen für die Verbreitung anders sind, schreiben
+Sie an den Autor, um ihn um die Erlaubnis zu bitten. Für Software, die unter
+dem Copyright der Free Software Foundation steht, schreiben Sie an die Free
+Software Foundation; wir machen zu diesem Zweck gelegentlich Ausnahmen.
+Unsere Entscheidung wird von den beiden Zielen geleitet werden, zum einen
+den freien Status aller von unserer freien Software abgeleiteten Werke zu
+erhalten und zum anderen das gemeinschaftliche Nutzen und Wiederverwenden
+von Software im allgemeinen zu fördern
+
+@iftex
+@heading Keine Gewährleistung
+@end iftex
+@ifinfo
+@center Keine Gewährleistung
+@end ifinfo
+
+@item
+Da das Programm ohne jegliche Kosten lizenziert wird, besteht keinerlei
+Gewährleistung für das Programm, soweit dies gesetzlich zulässig ist.
+Sofern nicht anderweitig schriftlich bestätigt, stellen die Copyright-Inhaber
+und/oder Dritte das Programm so zur Verfügung, "wie es ist", ohne irgendeine
+Gewährleistung, weder ausdrücklich noch implizit, einschließlich - aber nicht
+begrenzt auf - Marktreife oder Verwendbarkeit für einen bestimmten Zweck.
+Das volle Risiko bezüglich Qualität und Leistungsfähigkeit des Programms
+liegt bei Ihnen. Sollte sich das Programm als fehlerhaft herausstellen,
+liegen die Kosten für notwendigen Service, Reparatur oder Korrektur bei Ihnen.
+
+@item
+In keinem Fall, außer wenn durch geltendes Recht gefordert oder schriftlich
+zugesichert, ist irgendein Copyright-Inhaber oder irgendein Dritter, der das
+Programm wie oben erlaubt modifiziert oder verbreitet hat, Ihnen gegenüber
+für irgendwelche Schäden haftbar, einschließlich jeglicher allgemeiner oder
+spezieller Schäden, Schäden durch Seiteneffekte (Nebenwirkungen) oder
+Folgeschäden, die aus der Benutzung des Programms oder der Unbenutzbarkeit des
+Programms folgen (einschließlich - aber nicht beschränkt auf - Datenverluste,
+fehlerhafte Verarbeitung von Daten, Verluste, die von Ihnen oder anderen
+getragen werden müssen oder dem Unvermögen des Programms, mit irgendeinem
+anderen Programm zusammenzuarbeiten), selbst wenn ein Copyright-Inhaber
+oder Dritter über die Möglichkeit solcher Schäden unterrichtet worden war.
+@end enumerate
+
+@iftex
+@heading Ende der Bedingungen
+@end iftex
+@ifinfo
+@center Ende der Bedingungen
+@end ifinfo
+
+@page
+@appendixsec Anhang: Wie Sie diese Bedingungen auf Ihre neuen Programme anwendbar machen
+
+Wenn Sie ein neues Programm entwickeln und wollen, dass es von größtmöglichem
+Nutzen für die Allgemeinheit ist, dann erreichen Sie das am besten, indem
+Sie es zu freier Software machen, die jeder unter diesen Bestimmungen
+weiterverbreiten und verändern kann.
+
+Um dies zu erreichen, fügen Sie die folgenden Anmerkungen zu Ihrem Programm
+hinzu. Am sichersten ist es, sie an den Anfang einer jeden Quelldatei zu
+stellen, um den Gewährleistungsausschluß möglichst deutlich darzustellen;
+außerdem sollte jede Datei mindestens eine "Copyright"-Zeile besitzen sowie
+einen kurzen Hinweis darauf, wo die vollständige Lizenz gefunden werden kann.
+
+@smallexample
+@var{eine Zeile mit dem Programmnamen und einer kurzen Beschreibung}
+Copyright (C) @var{yyyy} @var{Name des Autors}
+
+This Programm ist free Software; you can redistribute it und / oder modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License oder
+(at your option) any later version.
+
+This Programm ist distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; ohne even the implied warranty of
+MERCHANTABILITY oder FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License für mehr details.
+
+You should have received a copy of the GNU General Public License
+along mit this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+@end smallexample
+
+Also add information on how to contact you von electronic und paper mail.
+
+@smallexample auf deutsch
+@var{eine Zeile mit dem Programmnamen und einer kurzen Beschreibung}
+Copyright (C) @var{yyyy} @var{Name des Autors}
+
+ Dieses Programm ist freie Software. Sie können es unter
+ den Bedingungen der GNU General Public License, wie von der
+ Free Software Foundation herausgegeben, weitergeben und/oder
+ modifizieren, entweder unter Version 2 der Lizenz oder (wenn
+ Sie es wünschen) jeder späteren Version.
+
+ Die Veröffentlichung dieses Programms erfolgt in der
+ Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE JEDE
+ GEWÄHRLEISTUNG - sogar ohne die implizite Gewährleistung
+ der MARKTREIFE oder der EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ Details finden Sie in der GNU General Public License.
+
+ Sie sollten eine Kopie der GNU General Public License zusammen
+ mit diesem Programm erhalten haben. Falls nicht, schreiben Sie
+ an die Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+@end smallexample
+
+
+Wenn Ihr Programm interaktiv ist, sorgen Sie dafür, dass es nach dem
+Start einen kurzen Vermerk ausgibt:
+
+@smallexample
+Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
+Gnomovision comes mit ABSOLUTELY NO WARRANTY; für details type `show w'.
+Das ist free Software und you are welcome to redistribute it
+under certain conditions; type `show c' für details.
+@end smallexample
+
+@smallexample auf deutsch
+ Gnomovision Version 69, Copyright (C) 19[jj] [Name des Autors]
+ Für Gnomovision besteht KEINERLEI GARANTIE; geben Sie `show w'
+ für Details ein. Gnomovision ist freie Software, die Sie unter
+ bestimmten Bedingungen weitergeben dürfen; geben Sie `show c'
+ für Details ein.
+@end smallexample
+
+Die hypothetischen Kommandos `show w' und `show c' sollten die
+entsprechenden Teile der GNU-GPL anzeigen. Natürlich können die von
+Ihnen verwendeten Kommandos anders heißen als `show w' und `show c';
+es könnten auch Mausklicks oder Menüpunkte sein - was immer am besten
+in Ihr Programm passt.
+
+Soweit vorhanden, sollten Sie auch Ihren Arbeitgeber (wenn Sie als
+Programmierer arbeiten) oder Ihre Schule einen Copyright-Verzicht
+für das Programm unterschreiben lassen. Hier ein Beispiel;
+ändern Sie bitte die Namen:
+
+@example
+Yoyodyne, Inc., herefrom disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end example
+
+@example auf deutsch
+Die Yoyodyne GmbH erhebt keinerlei urheberrechtlichen Anspruch auf das
+Programm "Gnomovision" (einem Schrittmacher für Compiler),
+geschrieben von James Hacker.
+
+@var{Unterschrift von Ty Coon}, 1 April 1989
+Ty Coon, Vizepräsident
+@end example
+
+Diese General Public License gestattet nicht die Einbindung des Programms
+in proprietäre Programme. Ist Ihr Programm eine Funktionsbibliothek, so
+kann es sinnvoller sein, das Linken proprietärer Programme mit dieser
+Bibliothek zu gestatten. Wenn Sie dies tun wollen, sollten Sie die
+GNU Library General Public License anstelle dieser Lizenz verwenden.
+
+@display
+@c German FIX added @@ in e-mail addresses
+Erstellt im Auftrag der S.u.S.E. GmbH [suse@@suse.de]
+von Katja Lachmann Übersetzungen [na194@@fim.uni-erlangen.de],
+überarbeitet von Peter Gerwinski [peter.gerwinski@@uni-essen.de] (31. Oktober 1996)
+
+Diese Übersetzung wird mit der Absicht angeboten, das Verständnis der
+GNU General Public License (GNU-GPL) zu erleichtern. Es handelt sich jedoch
+nicht um eine offizielle oder im rechtlichen Sinne anerkannte Übersetzung.
+
+Die Free Software Foundation (FSF) ist nicht der Herausgeber dieser Übersetzung,
+und sie hat diese Übersetzung auch nicht als rechtskräftigen Ersatz für die
+Original-GNU-GPL anerkannt. Da die Übersetzung nicht sorgfältig von Anwälten
+überprüft wurde, können die Übersetzer nicht garantieren, dass die Übersetzung
+die rechtlichen Aussagen der GNU-GPL exakt wiedergibt. Wenn Sie sichergehen
+wollen, dass von Ihnen geplante Aktivitäten im Sinne der GNU-GPL gestattet sind,
+halten Sie sich bitte an die englischsprachige Originalversion.
+
+Die Free Software Foundation möchte Sie darum bitten, diese Übersetzung
+nicht als offizielle Lizenzbedingungen für von Ihnen geschriebene Programme
+zu verwenden. Bitte benutzen Sie hierfür stattdessen die von der
+Free Software Foundation herausgegebene englischsprachige Originalversion.
+@end display
+
+@page
+
+
+
+
+@node LGPL license, Function Index, GPL license, Top
+@c German node LGPL-Lizenz
+@appendix GNU LESSER GENERAL PUBLIC LICENSE
+
+@cindex LGPL, Lesser General Public License
+@cindex LGPL, GNU Library General Public License
+
+@center Version 2.1, Februar 1999
+
+@display
+Copyright @copyright{} 1991, 1999 Free Software Foundation, Inc.
+59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
+
+Es ist jedermann gestattet, diese Lizenzurkunde zu vervielfältigen
+und unveränderte Kopien zu verbreiten. Änderungen sind jedoch nicht erlaubt.
+
+[Dies ist die erste freigegebene Version der Lesser GPL.
+Sie ist als Nachfolgerin der GNU Library Public License zu betrachten und
+erhielt daher die Versionsnummer 2.1.]
+@end display
+
+Diese Übersetzung ist kein rechtskräftiger Ersatz für die
+englischsprachige Originalversion!
+
+@appendixsec Vorwort
+
+Die meisten Softwarelizenzen sind daraufhin entworfen worden, Ihnen die
+Freiheit zu nehmen, die Software weiterzugeben und zu verändern.
+Im Gegensatz dazu sollen Ihnen die GNU General Public Licenses,
+die Allgemeinen Öffentlichen GNU-Lizenzen, ebendiese Freiheit des
+Weitergebens und Veränderns garantieren und somit sicherstellen, dass diese
+Software für alle Benutzer frei ist.
+
+Diese Lizenz, die Kleine Allgemeine Öffentliche Lizenz
+(Lesser General Public License), gilt für einige besonders bezeichnete
+Software-Pakete - typischerweise Programmbibliotheken - von der
+Free Software Foundation und anderen Autoren, die beschließen,
+diese Lizenz zu verwenden. Auch Sie können sie verwenden; wir empfehlen
+aber, vorher gründlich darüber nachzudenken, ob diese Lizenz (LGPL)
+oder aber die gewöhnliche Allgemeine Öffentliche Lizenz (GPL) die
+bessere Strategie zur Anwendung im jeweiligen speziellen Fall ist.
+Dabei bieten Ihnen die untenstehenden Erläuterungen eine Grundlage
+für Ihre Entscheidung.
+
+Die Bezeichnung ,,freie`` Software bezieht sich auf Freiheit der Nutzung,
+nicht auf den Preis. Unsere Allgemeinen Öffentlichen Lizenzen sollen
+sicherstellen, dass Sie die Freiheit haben, Kopien freier Software zu
+verbreiten (und etwas für diesen Service zu berechnen, wenn Sie möchten),
+dass Sie die Software im Quelltext erhalten oder den Quelltext auf Wunsch
+bekommen können, dass Sie die Software ändern oder Teile davon in neuen
+freien Programmen verwenden dürfen, und dass Sie darüber informiert sind,
+dass Sie dies alles tun dürfen.
+
+Um Ihre Rechte zu schützen, müssen wir Einschränkungen machen, die es jedem,
+der die Software weitergibt, verbieten, Ihnen diese Rechte zu verweigern
+oder Sie zum Verzicht auf diese Rechte aufzufordern. Aus diesen
+Einschränkungen ergeben sich bestimmte Verantwortlichkeiten für Sie, wenn Sie
+Kopien der Bibliothek verbreiten oder sie verändern.
+
+Beispielsweise müssen Sie den Empfängern alle Rechte gewähren, die wir Ihnen
+eingeräumt haben, wenn Sie - kostenlos oder gegen Bezahlung - Kopien der
+Bibliothek verbreiten. Sie müssen sicherstellen, dass auch die Empfänger
+den Quelltext erhalten bzw. erhalten können. Wenn Sie einen anderen Code
+mit der Bibliothek linken, müssen Sie den Empfängern die vollständigen
+Objekt-Dateien zukommen lassen, so dass sie selbst diesen Code mit der
+Bibliothek neu linken können, auch nachdem sie Veränderungen an der
+Bibliothek vorgenommen und sie neu compiliert haben. Und Sie müssen ihnen
+diese Bedingungen zeigen, damit sie Ihre Rechte kennen.
+
+Wir schützen Ihre Rechte in zwei Schritten: (1) Wir stellen die Bibliothek
+unter ein Urheberrecht (Copyright), und (2) wir bieten Ihnen diese Lizenz
+an, die Ihnen das Recht gibt, die Bibliothek zu vervielfältigen, zu
+verbreiten und/oder zu verändern.
+
+Um jeden, der die Software weitergibt, zu schützen, wollen wir darüber
+hinaus vollkommen klarstellen, dass für diese freie Bibliothek keinerlei
+Garantie besteht. Auch sollten, falls die Software von jemand anderem
+modifiziert und weitergegeben wird, die Empfänger wissen, dass sie nicht
+das Original erhalten haben, damit irgendwelche von anderen verursachte
+Probleme nicht den Ruf des ursprünglichen Autors schädigen.
+
+Schließlich und endlich stellen Software-Patente für die Existenz jedes
+freien Programms eine ständige Bedrohung dar. Wir möchten sicherstellen,
+dass keine Firma den Benutzern eines freien Programms Einschränkungen
+auferlegen kann, indem sie von einem Patentinhaber eine die freie Nutzung
+einschränkende Lizenz erwirbt. Deshalb bestehen wir darauf, dass jegliche
+für eine Version der Bibliothek erworbene Patentlizenz mit der in dieser
+Lizenz (also der LGPL) im einzelnen angegebenen Nutzungsfreiheit voll
+vereinbar sein muß.
+
+Die meiste GNU-Software einschließlich einiger Bibliotheken fällt unter
+die gewöhnliche Allgemeine Öffentliche GNU-Lizenz (GNU-GPL).
+Die vorliegende Lizenz, also die GNU-LGPL, gilt für gewisse näher
+bezeichnete Bibliotheken. Sie unterscheidet sich wesentlich von der
+gewöhnlichen Allgemeinen Öffentlichen Lizenz (GNU-GPL). Wir benutzen
+diese Lizenz für gewisse Bibliotheken, um das Linken (d.h. die Verknüpfung
+von Bibliotheken und anderen Programmteilen zu einem lauffähigen
+Programm - Anmerkung der Übersetzer) von Programmen, die nicht frei
+sind, mit diesen Bibliotheken zu gestatten.
+
+Wenn ein Programm mit einer Bibliothek gelinkt wurde, sei es nun statisch
+oder dynamisch, so ist die Kombination der beiden, rechtlich gesehen,
+ein ,,kombiniertes Datenwerk``, also eine abgeleitete Version der
+Orginal-Bibliothek. Die gewöhnliche GPL erlaubt ein solches Linken nur
+dann, wenn die ganze Kombination die Kriterien für freie Software erfüllt.
+Die LGPL erlaubt dagegen weniger strenge Kriterien für das Linken von
+irgendeiner anderen Software mit der Bibliothek.
+
+Wir nennen diese Lizenz die "Kleine" Allgemeine Öffentliche Lizenz
+@dfn{Lesser} General Public License weil sie weniger @emph{Less} dazu beiträgt,
+die Freiheit des Benutzers zu schützen, als die gewöhnliche Allgemeine
+Öffentliche Lizenz (GPL). Sie verschafft auch anderen Entwicklern freier
+Software ein "Weniger" an Vorteil gegenüber konkurrierenden nichtfreien Programmen.
+Diese Nachteile sind ein Grund dafür, dass wir die gewöhnliche GPL für viele
+Bibliotheken benutzen. Die "kleine" Lizenz (LGPL) bietet aber unter bestimmten
+besonderen Umständen doch Vorteile.
+
+So kann, wenn auch nur bei seltenen Gelegenheiten, eine besondere Notwendigkeit
+bestehen, einen Anreiz zur möglichst weitgehenden Benutzung einer bestimmten
+Bibliothek zu schaffen, so dass diese dann ein De-facto-Standard wird. Um dies
+zu erreichen, müssen nichtfreie Programme die Bibliothek benutzen dürfen.
+Ein häufigerer Fall ist der, dass eine freie Bibliothek dasselbe leistet wie
+weithin benutzte nichtfreie Bibliotheken. In diesem Falle bringt es wenig
+Nutzen, die freie Bibliothek allein auf freie Software zu beschränken, und
+dann benutzen wir eben die LGPL.
+
+In anderen Fällen ermöglicht die Erlaubnis zur Benutzung einer speziellen
+Bibliothek in nichtfreien Programmen viel mehr Leuten, eine umfangreiche
+Sammlung freier Software zu nutzen. So ermöglicht z.B. die Erlaubnis zur
+Benutzung der GNU-C-Bibliothek in nichtfreien Programmen einer viel größeren
+Zahl von Leuten, das ganze GNU-Betriebssystem ebenso wie seine Variante, das
+Betriebssystem GNU/Linux, zu benutzen.
+
+Obwohl die LGPL die Freiheit des Benutzers weniger schützt, stellt sie doch
+sicher, dass der Benutzer eines Programms, das mit der Bibliothek gelinkt wurde,
+die Freiheit und die erforderlichen Mittel hat, das Programm unter Benutzung
+einer abgeänderten Version der Bibliothek zu betreiben.
+
+Die genauen Bedingungen für das Kopieren, Weitergeben und Abändern finden Sie
+im nachstehenden Kapitel. Achten Sie genau auf den Unterschied zwischen
+"work Basiert auf the library", d.h. "Datenwerk, das auf der Bibliothek basiert"
+und "work that uses the library" d.h. "Datenwerk, das die Bibliothek benutzt".
+Ersteres enthält Code, der von der Bibliothek abgeleitet ist, während letzteres
+lediglich mit der Bibliothek kombiniert werden muß, um betriebsfähig zu sein.
+
+@iftex
+@appendixsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center GNU LESSER GENERAL PUBLIC LICENSE
+@center Bedingungen für die Vervielfältigung, Verbreitung und Bearbeitung
+
+@end ifinfo
+
+@enumerate 0
+@item
+Diese Lizenz gilt für jedes Programm und jedes andere Datenwerk, in dem
+ein entsprechender Vermerk des Copyright-Inhabers oder eines anderen dazu
+Befugten darauf hinweist, dass das Datenwerk unter den Bestimmungen dieser
+Lesser General Public License (im weiteren auch als "diese Lizenz"
+bezeichnet) verbreitet werden darf. Jeder Lizenznehmer wird hierin
+einfach als "Sie" angesprochen.
+
+Eine "Bibliothek" bedeutet eine Zusammenstellung von Software-Funktionen
+und/oder Daten, die so vorbereitet ist, dass sie sich bequem mit
+Anwendungsprogrammen (welche einige dieser Funktionen und Daten benutzen) zum Bilden
+von ausführbaren Programmen linken (d.h. verbinden, kombinieren) läßt.
+
+Der Begriff "Bibliothek" bezieht sich im weiteren immer nur auf solche
+Software-Bibliotheken und solche Datenwerke, die unter diesen Bedingungen
+der Lesser-GPL-Lizenz verbreitet worden sind. Ein "auf der Bibliothek
+basierendes Datenwerk" bezeichnet die betreffende Bibliothek selbst
+sowie jegliche davon abgeleitete Bearbeitung im urheberrechtlichen Sinne,
+also ein Datenwerk, welches die Bibliothek oder einen Teil davon, sei
+es unverändert oder verändert und/oder direkt in eine andere Sprache
+übersetzt, enthält. (Im folgenden wird die Übersetzung ohne
+Einschränkung als "Bearbeitung" eingestuft.)
+
+Unter dem "Quelltext" eines Datenwerks ist seine für das Vornehmen
+von Veränderungen bevorzugte Form zu verstehen. Für eine Bibliothek
+bedeutet "vollständiger Quelltext" den gesamten Quelltext für alle in
+ihr enthaltenen Bestandteile, für jegliche zu ihr gehörenden Dateien
+zur Definition von Schnittstellen und schließlich auch für die Skripte,
+die zur Steuerung der Compilation und Installation der Bibliothek
+benutzt werden.
+
+Andere Handlungen als Vervielfältigung, Verbreitung und Bearbeitung
+werden von dieser Lizenz nicht berührt; sie fallen nicht in Ihren
+Anwendungsbereich. Das Ausführen eines Programms unter Benutzung der
+Bibliothek wird nicht eingeschränkt, und die Ausgaben des Programms
+unterliegen dieser Lizenz nur dann, wenn der Inhalt ein auf der
+Bibliothek basierendes Datenwerk darstellt (unabhängig davon, dass die
+Bibliothek in einem Werkzeug zum Schreiben dieses Programms benutzt
+wurde). Ob dies zutrifft, hängt davon ab, was die Bibliothek bewirkt
+und was das Programm, das die Bibliothek nutzt, bewirkt.
+
+@item
+Sie dürfen auf beliebigen Medien unveränderte Kopien des vollständigen
+Quelltextes des Programms so, wie sie ihn erhalten haben, anfertigen
+und verbreiten. Voraussetzung hierfür ist, dass Sie mit jeder Kopie
+deutlich erkennbar und in angemessener Form einen entsprechenden
+Copyright-Vermerk sowie einen Haftungsausschluss veröffentlichen, alle
+Vermerke, die sich auf diese Lizenz und das Fehlen einer Garantie
+beziehen, unverändert lassen und zusammen mit der Bibliothek jeweils
+eine Kopie dieser Lizenz weitergeben.
+
+Sie dürfen für den eigentlichen Kopier- und Versandvorgang eine Gebühr
+verlangen. Wenn Sie es wünschen, dürfen Sie auch gegen Entgelt eine
+Garantie anbieten.
+
+@item
+Sie dürfen Ihre Kopie(n) der Bibliothek oder irgendeines Teils davon
+verändern, wodurch ein auf der Bibliothek basierendes Datenwerk
+entsteht, und Sie dürfen derartige Bearbeitungen unter den Bestimmungen
+von Paragraph 1 vervielfältigen und verbreiten, vorausgesetzt, dass
+zusätzlich alle im folgenden genannten Bedingungen erfüllt werden:
+
+@enumerate a
+@item
+Das Bearbeitungsergebnis muss selbst wieder eine Software-Bibliothek sein.
+
+@item
+Sie müssen die veränderten Dateien mit einem auffälligen Vermerk
+versehen, der auf die von Ihnen vorgenommene Modifizierung der
+Dateien hinweist und das Datum jeder Änderung angibt.
+
+@item
+Sie müssen dafür sorgen, dass das Datenwerk als Ganzes Dritten unter
+den Bedingungen dieser Lizenz ohne Lizenzgebühren zur Verfügung
+gestellt wird.
+
+@item
+Wenn sich eine Funktionseinheit der bearbeiteten Bibliothek auf eine
+Funktion oder Datentabelle stützt, die von einem die Funktionseinheit
+nutzenden Anwendungsprogramm bereitgestellt werden muß, ohne dass sie
+als Argument übergeben werden muß, wenn die Funktionseinheit angesprochen
+wird, dann müssen Sie sich nach bestem Wissen und Gewissen bemühen,
+sicherzustellen, dass die betreffende Funktionseinheit auch dann noch
+funktioniert, wenn die Anwendung eine solche Funktion oder Datentabelle
+nicht bietet, und dass sie den sinnvoll bleibenden Teil Ihres
+Bestimmungszwecks noch ausführt.
+
+(So hat z.B. eine Funktion zum Berechnen von Quadratwurzeln einen von
+der Anwendung unabhängigen genau definierten Zweck. Deshalb verlangt
+§2 Absatz d, dass jede von der Anwendung bereitgestellte Funktion oder
+von dieser Funktion benutzte Tabelle optional sein muß: Auch wenn die
+Anwendung sie nicht bereitstellt, muss die Quadratwurzelfunktion trotzdem
+noch Quadratwurzeln berechnen).
+@end enumerate
+
+Diese Anforderungen gelten für das bearbeitete Datenwerk als Ganzes.
+Wenn identifizierbare Teile davon nicht von der Bibliothek stammen und
+vernünftigerweise als unabhängige und gesonderte Datenwerke für sich selbst
+zu betrachten sind, dann gelten diese Lizenz und Ihre Bedingungen nicht
+für die betreffenden Teile, wenn Sie diese als gesonderte Datenwerke
+weitergeben. Wenn Sie jedoch dieselben Teile als Teil eines Ganzen
+weitergeben, dass ein auf der Bibliothek basierendes Datenwerk darstellt,
+dann muss die Weitergabe dieses Ganzen nach den Bedingungen dieser Lizenz
+erfolgen, deren Bedingungen für weitere Lizenznehmer somit auf das
+gesamte Ganze ausgedehnt werden - und somit auf jeden einzelnen Teil,
+unabhängig vom jeweiligen Autor.
+
+Somit ist es nicht die Absicht dieses Abschnittes, Rechte für Datenwerke
+in Anspruch zu nehmen oder Ihnen Rechte für Datenwerke streitig zu
+machen, die komplett von Ihnen geschrieben wurden; vielmehr ist es die
+Absicht, die Rechte zur Kontrolle der Verbreitung von Datenwerken, die
+auf der Bibliothek basieren oder unter Ihrer auszugsweisen Verwendung
+zusammengestellt worden sind, auszuüben.
+
+Ferner bringt auch dass einfache Zusammenlegen eines anderen Datenwerkes,
+das nicht auf der Bibliothek basiert, mit der Bibliothek oder mit
+einem auf der Bibliothek basierenden Datenwerk auf ein- und demselben
+Speicher- oder Vertriebsmedium dieses andere Datenwerk nicht in den
+Anwendungsbereich dieser Lizenz.
+
+@item
+Sie können sich für die Anwendung der Bedingungen der gewöhnlichen
+Allgemeinen Öffentlichen GNU-Lizenz (GNU-GPL) statt dieser Lizenz
+auf eine gegebene Kopie der Bibliothek entscheiden. Um dies zu tun,
+müssen Sie alle Eintragungen, die sich auf diese Lizenz beziehen,
+ändern, so dass sie nun für die gewöhnliche GNU-GPL, Version 2,
+statt für diese Lizenz (LGPL) gelten. (Wenn eine neuere Version
+als Version 2 der gewöhnlichen GNU-GPL erschienen ist, können Sie
+diese angeben, wenn Sie das wünschen.) Nehmen Sie keine anderen
+Veränderungen in diesen Eintragungen vor.
+
+Wenn diese Veränderung in einer gegebenen Kopie einmal vorgenommen
+ist, dann ist sie für diese Kopie nicht mehr zurücknehmbar, und
+somit gilt dann die gewöhnliche GNU-GPL für alle nachfolgenden Kopien
+und abgeleiteten Datenwerke, die von dieser Kopie gemacht worden sind.
+
+Diese Option ist nützlich, wenn Sie einen Teil des Codes der Bibliothek
+in ein Programm kopieren wollen, das keine Bibliothek ist.
+
+@item
+Sie können die Bibliothek (oder einen Teil oder eine Ableitung von ihr,
+gemäß Paragraph 2) in Objektcode-Form oder in ausführbarer Form unter
+den Bedingungen der obigen Paragraphen 1 und 2 kopieren und weitergeben,
+sofern Sie den vollständigen entsprechenden maschinenlesbaren Quelltext
+beifügen, der unter den Bedingungen der obigen Paragraphen 1 und 2
+auf einem Medium weitergegeben werden muß, das üblicherweise zum
+Austausch von Software benutzt wird.
+
+Wenn die Weitergabe von Objektcode durch das Angebot eines Zugangs zum
+Kopienabruf von einem angegebenen Ort erfolgt, dann erfüllt das Angebot
+eines gleichwertigen Zugangs zum Kopieren des Quelltextes von demselben
+Ort die Anforderung, auch den Quelltext weiterzugeben, obwohl Dritte
+nicht verplichtet sind, den Quelltext zusammen mit dem Objektcode zu
+kopieren.
+
+@item
+Ein Programm, das nichts von irgendeinem Teil der Bibliothek
+Abgeleitetes enthält, aber darauf ausgelegt ist, mit der Bibliothek
+zusammenzuarbeiten, indem es mit ihr compiliert oder gelinkt wird,
+nennt man ein "Datenwerk, das die Bibliothek nutzt". Solch ein
+Datenwerk, für sich allein genommen, ist kein von der Bibliothek abgelei
+tetes Datenwerk und fällt daher nicht unter diese Lizenz.
+
+Wird jedoch ein "Datenwerk, das die Bibliothek nutzt", mit der
+Bibliothek gelinkt, so entsteht ein ausführbares Programm, dass ein
+von der Bibliothek abgeleitetes Datenwerk (weil es Teile der Bibliothek
+enthält) und kein "Datenwerk, das die Bibliothek nutzt" ist.
+Das ausführbare Programm fällt daher unter diese Lizenz.
+Paragraph 6 gibt die Bedingungen für die Weitergabe solcher
+ausführbarer Programme an.
+
+Wenn ein "Datenwerk, das die Bibliothek nutzt", Material aus einer
+Header-Datei verwendet, die Teil der Bibliothek ist, dann kann der
+Objektcode für das Datenwerk ein von der Bibliothek abgeleitetes
+Datenwerk sein, selbst wenn der Quelltext dies nicht ist. Ob dies
+jeweils zutrifft, ist besonders dann von Bedeutung, wenn das Datenwerk
+ohne die Bibliothek gelinkt werden kann oder wenn das Datenwerk selbst
+eine Bibliothek ist. Die genaue Grenze, von der an dies zutrifft,
+ist rechtlich nicht genau definiert.
+
+Wenn solch eine Objektdatei nur numerische Parameter, Daten-
+struktur-Layouts und Zugriffsfunktionen sowie kleine Makros und kleine
+Inlinefunktionen (zehn Zeilen lang oder kürzer) benutzt, dann
+unterliegt die Benutzung der Objektdatei keinen Beschränkungen, ohne
+Rücksicht darauf, ob es rechtlich gesehen ein abgeleitetes Datenwerk ist.
+(Ausführbare Programme, welche diesen Objektcode plus Teile der
+Bibliothek enthalten, fallen jedoch weiterhin unter die Bestimmungen
+von Paragraph 6).
+
+Ansonsten können Sie, wenn das Datenwerk ein von der Bibliothek
+abgeleitetes ist, den Objektcode für das Datenwerk unter den Bedingungen
+von Paragraph 6 weitergeben. Alle ausführbaren Programme, welche
+dieses Datenwerk enthalten, fallen ebenfalls unter Paragraph 6,
+gleichgültig, ob sie direkt mit der Bibliothek selbst gelinkt sind
+oder nicht.
+
+@item
+Als Ausnahme von den Bestimmungen der vorstehenden fünf Paragraphen
+dürfen Sie auch ein "Datenwerk, das die Bibliothek nutzt", mit der
+Bibliothek kombinieren oder linken, um ein Datenwerk zu erzeugen,
+das Teile der Bibliothek enthält, und dieses unter Bedingungen Ihrer
+eigenen Wahl weitergeben, sofern diese Bedingungen Bearbeitungen
+für den eigenen Gebrauch des Empfängers und ein Rückbilden
+("reverse engineering") zum Beheben von Mängeln solcher Bearbeitungen
+gestatten.
+
+Sie müssen bei jeder Kopie des Datenwerks deutlich erkennbar angeben,
+dass die Bibliothek darin genutzt wird und dass die Bibliothek und Ihre
+Benutzung durch die Lizenz abgedeckt sind. Sie müssen eine Kopie
+dieser Lizenz mitgeben. Wenn das Datenwerk bei seiner Ausführung
+Copyright-Vermerke anzeigt, müssen Sie den Copyright-Vermerk für
+die Bibliothek mit anzeigen lassen und dem Benutzer einen Hinweis
+geben, der ihn zu einer Kopie dieser Lizenz führt. Ferner müssen Sie
+eines der nachfolgend genannten fünf Dinge tun:
+
+@enumerate a
+@item
+Liefern Sie das Datenwerk zusammen mit dem vollständigen zugehörigen
+maschinenlesbaren Quelltext der Bibliothek aus, und zwar
+einschließlich jeglicher in dem Datenwerk angewandter Änderungen (wobei
+dessen Weitergabe gemäß den Bedingungen der Paragraphen 1 und 2
+erfolgen muß); und wenn das Datenwerk ein ausführbares, mit der
+Bibliothek gelinktes Programm ist, dann liefern Sie es zusammen
+mit dem vollständigen maschinenlesbaren "Datenwerk, das die
+Bibliothek nutzt, in Form von Objektcode und/oder Quelltext, so dass
+der Benutzer die Bibliothek verändern und dann erneut linken kann,
+um ein verändertes ausführbares Programm zu erzeugen, das die
+veränderte Bibliothek enthält. (Es versteht sich, dass der Benutzer,
+der die Inhalte von Definitionsdateien in der veränderten Bibliothek
+verändert, nicht notwendigerweise in der Lage sein wird, die Anwendung
+neu zu compilieren, um die veränderten Definitionen zu benutzen.)
+
+@item
+Benutzen Sie einen geeigneten ,,shared-library-Mechanismus`` zum
+Linken mit der Bibliothek. Geeignet ist ein solcher Mechanismus,
+der erstens während der Laufzeit eine im Computersystem des Benutzers
+bereits vorhandene Kopie der Bibliothek benutzt, anstatt
+Bibliotheksfunktionen in das ausführbare Programm zu kopieren, und der zweitens
+auch mit einer veränderten Version der Bibliothek, wenn der Benutzer
+eine solche installiert, richtig funktioniert, solange die veränderte
+Version schnittstellenkompatibel mit der Version ist, mit der das
+Datenwerk erstellt wurde.
+
+@item
+Liefern Sie das Datenwerk zusammen mit einem mindestens drei Jahre
+lang gültigen schriftlichen Angebot, demselben Benutzer die oben in
+Paragraph 6, Absatz (a) genannten Materialien zu Kosten, welche die
+reinen Weitergabekosten nicht übersteigen, zur Verfügung zu stellen.
+
+@item
+Wenn die Weitergabe des Datenwerks dadurch erfolgt, dass die
+Möglichkeit des Abrufens einer Kopie von einem bestimmten Ort
+angeboten wird, bieten Sie gleichwertigen Zugang zum Kopieren der
+oben angegebenen Materialien von dem gleichen Ort an.
+
+@item
+Sie vergewissern sich, dass der Benutzer bereits eine Kopie dieser
+Materialien erhalten hat oder dass Sie diesem Benutzer bereits eine
+Kopie geschickt haben.
+@end enumerate
+
+Für ein ausführbares Programm muss die verlangte Form des
+"Datenwerks, das die Bibliothek nutzt" alle Daten und Hilfsprogramme
+mit einschließen, die man braucht, um daraus das ausführbare Programm
+zu reproduzieren. Doch gilt eine spezielle Ausnahme: Die
+weiterzugebenden Materialien brauchen nicht alles das zu enthalten, was
+normalerweise (in Quelltext-Form oder in binärer Form) mit den
+Hauptbestandteilen (Compiler, Kern usw.) des Betriebssystems,
+auf denen das ausführbare Programm läuft, weitergegeben wird, es
+sei denn, das ausführbare Programm gehört selbst zu diesem
+Hauptbestandteil.
+
+Es kann vorkommen, dass diese Anforderung im Widerspruch zu
+Lizenzbeschränkungen anderer, proprietärer Bibliotheken steht, die
+normalerweise nicht zum Betriebssystem gehören. Ein solcher
+Widerspruch bedeutet, dass Sie nicht gleichzeitig jene proprietären
+Bibliotheken und die vorliegende Bibliothek zusammen in einem
+ausführbaren Programm, das Sie weitergeben, verwenden dürfen.
+
+@item
+Sie dürfen Bibliotheks-Funktionseinheiten, die ein auf der Bibliothek
+basierendes Datenwerk darstellen, zusammen mit anderen, nicht unter
+diese Lizenz fallenden Funktionseinheiten in eine einzelne Bibliothek
+einbauen und eine solche kombinierte Bibliothek weitergeben,
+vorausgesetzt, dass die gesonderte Weitergabe des auf der Bibliothek
+basierenden Datenwerks einerseits und der anderen Funktionseinheiten
+andererseits ansonsten gestattet ist, und vorausgesetzt, dass Sie
+folgende zwei Dinge tun:
+
+@enumerate a
+@item
+Geben Sie zusammen mit der kombinierten Bibliothek auch eine Kopie
+desselben auf der Bibliothek basierenden Datenwerks mit, die nicht
+mit irgendwelchen anderen Funktionseinheiten kombiniert ist.
+Dieses Datenwerk muss unter den Bedingungen der obigen Paragraphen
+weitergegeben werden.
+
+@item
+Weisen Sie bei der kombinierten Bibliothek an prominenter Stelle
+auf die Tatsache hin, dass ein Teil davon ein auf der Bibliothek
+basierendes Datenwerk ist, und erklären Sie, wo man die mitgegebene
+unkombinierte Form desselben Datenwerks finden kann.
+@end enumerate
+
+@item
+Sie dürfen die Bibliothek nicht vervielfältigen, verändern, weiter
+lizenzieren oder verbreiten oder mit ihr linken, sofern es nicht durch
+diese Lizenz ausdrücklich gestattet ist. Jeder anderweitige Versuch
+der Vervielfältigung, Modifizierung, Weiterlizenzierung und
+Verbreitung sowie des Linkens mit der Bibliothek ist unzulässig und
+beendet automatisch Ihre Rechte unter dieser Lizenz. Doch werden
+die Lizenzen Dritter, die von Ihnen Kopien oder Rechte unter dieser
+Lizenz erhalten haben, nicht beendet, solange diese Dritten die Lizenz
+voll anerkennen und befolgen.
+
+@item
+Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da Sie diese
+nicht unterzeichnet haben. Doch gibt Ihnen sonst nichts die Erlaubnis,
+die Bibliothek oder von ihr abgeleitete Datenwerke zu verändern oder
+zu verbreiten. Diese Handlungen sind gesetzlich verboten, wenn Sie
+diese Lizenz nicht annehmen. Indem Sie die Bibliothek (oder ein darauf
+basierendes Datenwerk) verändern oder verbreiten, erklären Sie Ihr
+Einverständnis mit dieser Lizenz, die Ihnen das erlaubt, mit allen
+Ihren Bedingungen bezüglich der Vervielfältigung, Verbreitung und
+Veränderung der Bibliothek oder eines darauf basierenden Datenwerks.
+
+@item
+Jedesmal, wenn Sie die Bibliothek (oder irgendein auf der Bibliothek
+basierendes Datenwerk) weitergeben, erhält der Empfänger automatisch
+vom ursprünglichen Lizenzgeber die Lizenz, die Bibliothek entsprechend
+den hier festgelegten Bestimmungen zu vervielfältigen, zu verbreiten
+und zu verändern und mit ihr zu linken. Sie dürfen keine weiteren
+Einschränkungen der Ausübung der hierin zugestandenen Rechte des
+Empfängers vornehmen. Sie sind nicht dafür verantwortlich, die
+Einhaltung dieser Lizenz durch Dritte durchzusetzen.
+
+@item
+Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs einer
+Patentverletzung oder aus einem anderen Grunde (nicht auf
+Patentfragen begrenzt) Bedingungen (durch Gerichtsbeschluss,
+Vergleich oder anderweitig) auferlegt werden, die den Bedingungen
+dieser Lizenz widersprechen, so befreien diese Umstände Sie nicht
+von den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht möglich ist,
+die Bibliothek unter gleichzeitiger Beachtung der Bedingungen in
+dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu verbreiten,
+dann dürfen Sie als Folge davon die Bibliothek überhaupt nicht
+verbreiten. Wenn zum Beispiel ein Patent nicht die gebührenfreie
+Weiterverbreitung der Bibliothek durch diejenigen erlaubt, welche
+die Bibliothek direkt oder indirekt von Ihnen erhalten haben, dann
+besteht der einzige Weg, sowohl dem Patentrecht als auch dieser
+Lizenz zu genügen, darin, ganz auf die Verbreitung der Bibliothek
+zu verzichten.
+
+Sollte sich ein Teil dieses Paragraphen als ungültig oder unter
+bestimmten Umständen nicht durchsetzbar erweisen, so soll dieser
+Paragraph seinem Sinne nach angewandt werden; im übrigen soll
+dieser Paragraph als Ganzes gelten.
+
+Zweck dieses Paragraphen ist nicht, Sie dazu zu bringen, irgendwelche
+Patente oder andere Eigentumsansprüche zu verletzen oder die Gültigkeit
+solcher Ansprüche zu bestreiten; dieser Paragraph hat vielmehr einzig
+den Zweck, die Integrität des Verbreitungssystems der freien Software
+zu schützen, das durch die Praxis öffentlicher Lizenzen verwirklicht
+wird. Viele Leute haben großzügige Beiträge zu dem weitreichenden
+Angebot der durch dieses System verbreiteten Software im Vertrauen
+auf die konsistente Anwendung dieses Systems geleistet; es obliegt
+dem Autor bzw. Geber, zu entscheiden, ob er die Software mittels
+irgendeines anderen Systems verbreiten will; ein Lizenznehmer jedoch
+darf darüber nicht entscheiden.
+
+Dieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als
+Konsequenz aus den übrigen Bestimmungen dieser Lizenz zu betrachten
+ist.
+
+@item
+Wenn die Verbreitung und/oder die Benutzung der Bibliothek in
+bestimmten Staaten entweder durch Patente oder durch urheberrechtlich
+geschützte Schnittstellen eingeschränkt ist, kann der
+Urheberrechtsinhaber, der die Bibliothek unter diese Lizenz gestellt
+hat, eine explizite geographische Beschränkung der Verbreitung angeben,
+in der diese Staaten ausgeschlossen werden, so dass die Verbreitung nur
+innerhalb und zwischen den Staaten erlaubt ist, die nicht demgemäß
+ausgeschlossen sind. In einem solchen Fall beinhaltet diese Lizenz
+die Beschränkung, als wäre sie in diesem Text niedergeschrieben.
+
+@item
+Die Free Software Foundation kann von Zeit zu Zeit überarbeitete
+und/oder neue Versionen der Lesser General Public License
+veröffentlichen. Solche neuen Versionen werden vom Grundprinzip her
+der gegenwärtigen entsprechen, können aber im Detail abweichen, um
+neuen Problemen und Anforderungen gerecht zu werden.
+
+Jede Version dieser Lizenz hat eine eindeutige Versionsnummer.
+Wenn in einem Programm angegeben wird, dass es dieser Lizenz in einer
+bestimmten Versionsnummer oder "jeder späteren Version" ("any later
+version") unterliegt, so haben Sie die Wahl, entweder den Bestimmungen
+der genannten Version zu folgen oder denen jeder beliebigen späteren
+Version, die von der Free Software Foundation veröffentlicht wurde.
+Wenn die Bibliothek keine Lizenz-Versionsnummer angibt, können Sie
+eine beliebige Version wählen, die jemals von der Free Software
+Foundation veröffentlicht wurde.
+
+@item
+Wenn Sie den Wunsch haben, Teile der Bibliothek in anderen
+freien Programmen zu verwenden, deren Bedingungen für die Verbreitung
+anders sind, schreiben Sie an den Autor der Bibliothek, um ihn um die
+Erlaubnis zu bitten. Für Software, die unter dem Copyright der Free
+Software Foundation steht, schreiben Sie an die Free Software
+Foundation; wir machen zu diesem Zweck gelegentlich Ausnahmen.
+Unsere Entscheidung wird von den beiden Zielen geleitet werden,
+zum einen den freien Status aller von unserer freien Software
+abgeleiteten Datenwerke zu erhalten und zum anderen das
+gemeinschaftliche Nutzen und Wiederverwenden von Software im
+allgemeinen zu fördern.
+
+@iftex
+@heading Keine Gewährleistung
+@end iftex
+@ifinfo
+@center Keine Gewährleistung
+@end ifinfo
+
+@item
+Da die Bibliothek ohne jegliche Gebühren lizenziert wird, besteht
+keinerlei Gewährleistung für die Bibliothek, soweit dies gesetzlich
+zulässig ist. Sofern nicht anderweitig schriftlich bestätigt, stellen
+die Copyright-Inhaber und/oder Dritte die Bibliothek "so, wie sie ist"
+zur Verfügung, ohne Gewährleistung irgendeiner Art, weder ausdrücklich
+noch implizit. Dieser Garantieausschluss gilt auch - ohne darauf
+beschränkt zu sein - für Marktreife oder Verwendbarkeit für einen
+bestimmten Zweck. Das volle Risiko bezüglich Qualität und Leistungs-
+fähigkeit der Bibliothek liegt bei Ihnen. Sollte sich die Bibliothek
+als fehlerhaft herausstellen, liegen die Kosten für notwendigen
+Service, Reparatur oder Korrektur sämtlich bei Ihnen.
+
+@item
+In keinem Fall, außer wenn dies durch geltendes Recht gefordert
+wird oder schriftlich zugesichert wurde, ist irgendein
+Copyright-Inhaber oder irgendein Dritter, der die Bibliothek wie oben
+erlaubt modifiziert oder verbreitet hat, Ihnen gegenüber für
+irgendwelche Schäden haftbar. Dies gilt auch für jegliche allgemeine
+oder spezielle Schäden, für Schäden durch Nebenwirkungen oder
+Folgeschäden, die sich aus der Benutzung oder der Unbenutzbarkeit
+der Bibliothek ergeben (das gilt insbesondere - ohne darauf
+beschränkt zu sein - für Datenverluste, das Hineinbringen von
+Ungenauigkeiten in irgendwelche Daten, für Verluste, die Sie oder
+Dritte erlitten haben oder für ein Unvermögen der Bibliothek,
+mit irgendeiner anderen Software zusammenzuarbeiten), und zwar
+auch dann, wenn ein Copyright-Inhaber oder ein Dritter über die
+Möglichkeit solcher Schäden informiert worden ist.
+
+@end enumerate
+
+@iftex
+@heading Ende der Bedingungen
+@end iftex
+@ifinfo
+@center Ende der Bedingungen
+@end ifinfo
+
+@appendixsec Anhang: Wie Sie diese Bedingungen auf Ihre eigenen, neuen Bibliotheken anwenden können
+
+Wenn Sie eine neue Bibliothek entwickeln und wünschen, dass sie
+von größtmöglichem Nutzen für die Allgemeinheit ist, dann empfehlen
+wir Ihnen, sie zu einer freien Software zu machen, die jedermann
+weiterverteilen und verändern kann. Dies können sie tun, indem Sie
+eine Weiterverteilung unter den Bedingungen dieser Lizenz, also
+der Lesser GPL erlauben (oder - als Alternative - unter den Bedingungen
+der gewöhnlichen Allgemeinen Öffentlichen GNU-Lizenz, der GPL).
+
+Zur Anwendung dieser Bedingungen fügen Sie zu der Bibliothek die
+unten angegebenen Vermerke hinzu. Es ist am sichersten, sie an
+den Start jeder Quelldatei anzufügen, um so am wirksamsten den
+Garantieausschluß bekannt zu machen; zumindest aber sollte jede
+Datei die Copyright-Zeile und eine Angabe enthalten, wo die
+vollständigen Vermerke zu finden sind.
+
+
+
+@smallexample
+@var{eine Zeile mit dem Namen der Bibliothek und einer kurzen
+Beschreibung Ihres Zwecks}
+Copyright (C) @var{yyyy} @var{Name des Autors}
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public License
+as published by the Free Software Foundation; either version 2.1
+of the License oder (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but ohne ANY WARRANTY; ohne even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General
+Public License along with this library; if not, write to the
+
+Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Auf Deutsch:
+
+Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen
+der GNU Lesser General Public License, wie von der Free Software
+Foundation veröffentlicht, weiterverteilen und/oder modifizieren;
+entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option)
+jeder späteren Version.
+
+Diese Bibliothek wird in der Hoffnung weiterverbreitet, dass sie
+nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne
+die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT
+FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der
+GNU Lesser General Public License.
+
+Sie sollten eine Kopie der GNU Lesser General Public License
+zusammen mit dieser Bibliothek erhalten haben; falls nicht,
+schreiben Sie an die
+Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+@end smallexample
+
+Fügen Sie auch einen kurzen Hinweis hinzu, wie Sie elektronisch
+und per Brief erreichbar sind.
+
+@smallexample
+Soweit vorhanden, sollten Sie auch Ihren Arbeitgeber
+(wenn Sie als Programmierer arbeiten) oder Ihre Schule einen
+Copyright-Verzicht für die Bibliothek unterschreiben lassen.
+Hier ein Beispiel. Die Namen müssen Sie natürlich ändern.
+
+Yoyodyne, Inc., hereby disclaims all copyright interest
+in the library "Frob" (a library for tweaking knobs)
+written by James Random Hacker.
+
+
+Unterschrift von Ty Coon , 1 April 1990
+Ty Coon, President of Vice
+
+Auf Deutsch:
+
+DIe Yoyodyne GmbH erhebt keinen urheberechtlichen Anspruch
+auf die von James Random Hacker geschriebene Bibliothek "Frob"
+(eine Bibliothek für das Zwicken von Knöpfen).
+
+
+Unterschrift von Ty Coon, 1. April 1990
+Ty Coon, Vizepräsident
+@end smallexample
+
+Das war schon alles!
+
+
+
+@c German FIX this node entry and section header were missing!
+@c I made a guess as to what the German section title should be like ;-)
+@node Function Index, Concept Index, LGPL license, Top
+@c German node Function Index
+@unnumbered SQL Command, Typ und Funktion Index
+
+@printindex fn
+
+@page
+
+
+@node Concept Index, , Function Index, Top
+@c German node Concept Index
+@unnumbered Concept Index
+
+@printindex cp
+
+
+
+
+
+@bye
diff --git a/Docs/manual.ja.texi b/Docs/manual.ja.texi
index aac97c61c8d..2a0b0fbf34b 100644
--- a/Docs/manual.ja.texi
+++ b/Docs/manual.ja.texi
@@ -3187,7 +3187,7 @@ encounter per year, but we are as always very flexible towards our customers!
@c @image{Flags/estonia} Estonia [Tradenet] @
@c @uref{http://mysql.tradenet.ee, WWW}
@item
-@c EMAIL: tonu@spamm.ee (Tonu Samuel)
+@c EMAIL: tonu@spam.ee (Tonu Samuel)
@image{Flags/estonia} Estonia [OKinteractive] @
@uref{http://mysql.mirror.ok.ee, WWW}
@item
@@ -23949,7 +23949,7 @@ Uptime: 10077 Threads: 1 Questions: 9 Slow queries: 0 Opens: 6 Flush tables
@item Max memory used @tab mysqld ¤Î¥³¡¼¥É¤Ë¤è¤Ã¤ÆľÀܳä¤êÅö¤Æ¤é¤ì¤ëºÇÂç¥á¥â¥ê¡¼ÎÌ (only available when @strong{MySQL} is compiled with --with-debug)
@end multitable
-If you do @code{myslqadmin shutdown} on a socket (in other words, on a
+If you do @code{mysqladmin shutdown} on a socket (in other words, on a
the computer where @code{mysqld} is running), @code{mysqladmin} will
wait until the @code{MySQL} @code{pid-file} is removed to ensure that
the @code{mysqld server} has stopped properly.
diff --git a/Docs/manual.texi b/Docs/manual.texi
index 19ce75e5d7d..b589d6ffd13 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -1,15 +1,27 @@
\input texinfo @c -*-texinfo-*-
-@c Copyright 1997-2001 TcX AB, Detron HB and MySQL Finland AB
+@c Copyright 1997-2002 TcX AB, Detron HB and MySQL Finland AB
+@c
+@c This manual is NOT distributed under a GPL style license.
+@c Use of the manual is subject to the following terms:
+@c - Conversion to other formats is allowed, but the actual
+@c content may not be altered or edited in any way.
+@c - You may create a printed copy for your own personal use.
+@c - For all other uses, such as selling printed copies or
+@c using (parts of) the manual in another publication,
+@c prior written agreement from MySQL AB is required.
+@c
+@c Please e-mail docs@mysql.com for more information or if
+@c you are interested in doing a translation.
@c
@c *********************************************************
-@c Note that @node names are used on our Website.
+@c Note that @node names are used on our web site.
@c So do not change node names without checking
@c Makefile.am and SitePages first.
@c *********************************************************
@c
@c %**start of header
-@c there's a better way to do this.. i just don't know it yet
+@c there's a better way to do this... i just don't know it yet
@c sed will remove the "@c ifnusphere " to make this valid
@c ifnusphere @set nusphere 1
@@ -66,7 +78,7 @@ END-INFO-DIR-ENTRY
@sp 10
@center @titlefont{MySQL Reference Manual}
@sp 10
-@center Copyright @copyright{} 1997-2001 MySQL AB
+@center Copyright @copyright{} 1997-2002 MySQL AB
@c blank page after title page makes page 1 be a page front.
@c also makes the back of the title page blank.
@page
@@ -95,102 +107,95 @@ END-INFO-DIR-ENTRY
@node Top, Introduction, (dir), (dir)
-@c @ifhtml
-@c <IMG SRC="Images/mysql-logo.gif">
-@c <!--Image doesn't exist. Can't find suitable replacement. (Matt) -->
-@c @end ifhtml
-
@ifinfo
-This is a manual for MySQL. This version is about the
-@value{mysql_version} version of MySQL. You can find a manual
-about any older version of MySQL in the binary or source
-distribution for that version.
+This is a manual for the @code{MySQL Database System}.
+This version is about the @value{mysql_version} version of
+@code{MySQL Server}. You can find a specific manual for any older
+version of @code{MySQL Server} in the binary or source distribution
+for that version.
@end ifinfo
@menu
-* Introduction:: General Information about MySQL
+* Introduction:: General Information
* Installing:: Installing MySQL
* Tutorial:: MySQL Tutorial
-* MySQL Database Administration:: MySQL Database Administration
-* MySQL Optimization:: MySQL Optimization
-* Reference:: MySQL language reference
-* Table types:: MySQL table types
-* Clients:: MySQL client tools and APIs
+* MySQL Database Administration:: Database Administration
+* MySQL Optimisation:: MySQL Optimisation
+* Reference:: MySQL Language Reference
+* Table types:: MySQL Table Types
+* Clients:: MySQL Client Tools and APIs
* Extending MySQL:: Extending MySQL
* Problems:: Problems
-* Users:: Some MySQL users
-* MySQL customer usage:: MySQL customer usage
-* Contrib:: Contributed programs
+* Contrib:: Contributed Programs
* Credits:: Contributors to MySQL
-* News:: MySQL change history
-* Porting:: Comments on porting to other systems
+* News:: MySQL Change History
+* Porting:: Porting to Other Systems
* Environment variables:: MySQL environment variables
-* Regexp:: Description of MySQL regular expression syntax
-* Unireg:: What is Unireg?
+* Regexp:: MySQL Regular Expression Syntax
* GPL license:: GNU General Public License
-* LGPL license:: GNU Library General Public License
-* Placeholder:: Pieces of the manual in transit
-* Function Index:: SQL command, type and function index
+* LGPL license:: GNU Lesser General Public License
+* Function Index:: SQL Command, Type and Function Index
* Concept Index:: Concept Index
@end menu
-
-
@node Introduction, Installing, Top, Top
-@chapter General Information About MySQL
+@chapter General Information
@cindex overview
@cindex general information
-@cindex online location of manual
-@cindex manual, online location
-This is the MySQL reference manual; it documents MySQL
-Version @value{mysql_version}. As MySQL is work in progress,
-the manual gets updated frequently. There is a very good chance that
-this version is out of date, unless you are looking at it online. The
-most recent version of this manual is available at
-@uref{http://www.mysql.com/documentation/} in many different formats. If you
-have a hard time finding information in the manual, you can try the
-searchable PHP version at @uref{http://www.mysql.com/documentation/manual.php}.
-
-MySQL is a very fast, multi-threaded, multi-user, and robust SQL
-(Structured Query Language) database server.
-
-MySQL is free software. It is licensed with the @strong{GNU
-GENERAL PUBLIC LICENSE} @uref{http://www.gnu.org/}.
+The @code{MySQL (TM)} software delivers a very fast, multi-threaded,
+multi-user, and robust @code{SQL} (@code{Structured Query Language})
+database server.
+@code{MySQL Server} is intended for mission-critical, heavy-load
+production systems as well as for embedding into mass-deployed software.
+@code{MySQL} is a trademark of @code{MySQL AB}.
+
+The @code{MySQL} software has @code{Dual Licensing}, which means you can use
+the @code{MySQL} software free of charge under the
+@code{GNU General Public License} (@uref{http://www.gnu.org/licenses/}).
+You can also purchase commercial @code{MySQL} licenses from
+@code{MySQL AB} if you do not wish to be bound by the terms of the
+@code{GPL}.
@xref{Licensing and Support}.
-@uref{http://www.mysql.com/, The MySQL home page}
-provides the latest information about MySQL.
+The @code{MySQL} web site (@uref{http://www.mysql.com/}) provides the
+latest information about the @code{MySQL} software.
-The following list describes some useful sections of the manual:
+The following list describes some sections of particular interest in this manual:
@itemize @bullet
@item
-For information about the company behind MySQL, see
-@ref{What is MySQL AB}.
+For information about the company behind the @code{MySQL Database Server},
+see @ref{What is MySQL AB}.
@item
-For a discussion of MySQL's capabilities, see @ref{Features}.
+For a discussion about the capabilities of the @code{MySQL Database Server},
+see @ref{Features}.
@item
For installation instructions, see @ref{Installing}.
@item
-For tips on porting MySQL to new architectures or operating
-systems, see @ref{Porting}.
+For tips on porting the @code{MySQL Database Software} to new architectures
+or operating systems, see @ref{Porting}.
+
+@item
+For information about upgrading from a Version 3.23 release, see
+@ref{Upgrading-from-3.23}.
@item
For information about upgrading from a Version 3.22 release, see
@ref{Upgrading-from-3.22}.
@item
-For a tutorial introduction to MySQL, see @ref{Tutorial}.
+For a tutorial introduction to the @code{MySQL Database Server},
+see @ref{Tutorial}.
@item
-For examples of SQL and benchmarking information, see the benchmarking
-directory (@file{sql-bench} in the distribution).
+For examples of @code{SQL} and benchmarking information, see the
+benchmarking directory (@file{sql-bench} in the distribution).
@item
For a history of new features and bug fixes, see @ref{News}.
@@ -205,7 +210,7 @@ For future plans, see @ref{TODO}.
For a list of all the contributors to this project, see @ref{Credits}.
@end itemize
-@strong{IMPORTANT:}
+@strong{Important}:
Reports of errors (often called bugs), as well as questions and comments,
should be sent to the mailing list at @email{mysql@@lists.mysql.com}.
@@ -215,7 +220,7 @@ The @code{mysqlbug} script should be used to generate bug reports.
For source distributions, the @code{mysqlbug} script can be found in the
@file{scripts} directory. For binary distributions, @code{mysqlbug} can
be found in the @file{bin} directory. If you have found a sensitive
-security bug in MySQL, you should send an email to
+security bug in @code{MySQL Server}, you should send an e-mail to
@email{security@@mysql.com}.
@cindex errors, reporting
@@ -223,267 +228,70 @@ security bug in MySQL, you should send an email to
@cindex mailing list address
@cindex @code{mysqlbug} script, location
-If you have any suggestions concerning additions or corrections to this
-manual, please send them to the manual team at @email{docs@@mysql.com}.
-
-This is a reference manual; it does not provide general instruction on SQL
-or relational database concepts. If you want general information about SQL,
-see @ref{General-SQL}. For books that focus more specifically on
-MySQL, see @ref{MySQL-Books}.
-
@menu
-* MySQL and MySQL AB:: MySQL, MySQL AB, and Open Source
+* Manual-info:: About This Manual
+* What-is:: What Is MySQL?
+* What is MySQL AB:: What Is MySQL AB?
+* Licensing and Support:: MySQL Support and Licensing
+* MySQL 4.0 In A Nutshell:: MySQL 4.0 In A Nutshell
* MySQL Information Sources:: MySQL Information Sources
-* Licensing and Support:: MySQL Licensing and Support
* Compatibility:: How Standards-compatible Is MySQL?
-* Comparisons:: How MySQL Compares to Other Databases
* TODO:: MySQL and the future (The TODO)
+* Comparisons:: How MySQL Compares to Other @code{Open Source} Databases
@end menu
-@node MySQL and MySQL AB, MySQL Information Sources, Introduction, Introduction
-@section MySQL, MySQL AB, and Open Source
-
-@menu
-* What-is:: What is MySQL?
-* What is MySQL AB:: What is MySQL AB?
-* Manual-info:: About this manual
-* Manual conventions:: Conventions used in this manual
-* History:: History of MySQL
-* Features:: The main features of MySQL
-* Stability:: How stable is MySQL?
-* Table size:: How Big Can MySQL Tables Be?
-* Year 2000 compliance:: Year 2000 compliance
-@end menu
-
-
-@node What-is, What is MySQL AB, MySQL and MySQL AB, MySQL and MySQL AB
-@subsection What Is MySQL
-
-@cindex MySQL, defined
-@cindex MySQL, introduction
-
-MySQL, the most popular Open Source SQL database, is provided
-by MySQL AB. MySQL AB is a commercial company that
-builds its business providing services around the MySQL database.
-@xref{What is MySQL AB}.
+@node Manual-info, What-is, Introduction, Introduction
+@section About This Manual
-@table @asis
-
-@item MySQL is a database management system.
-
-A database is a structured collection of data. It may be anything from a
-simple shopping list to a picture gallery or the vast amounts of
-information in a corporate network. To add, access, and process data
-stored in a computer database, you need a database management system
-such as MySQL. Since computers are very good at handling large
-amounts of data, database management plays a central role in computing,
-as stand-alone utilities, or as parts of other applications.
-
-@cindex databases, defined
-
-@item MySQL is a relational database management system.
-
-A relational database stores data in separate tables rather than putting
-all the data in one big storeroom. This adds speed and flexibility. The
-tables are linked by defined relations making it possible to combine
-data from several tables on request. The SQL part of MySQL
-stands for "Structured Query Language" - the most common standardized
-language used to access databases.
-
-@cindex relational databases, defined
-@cindex SQL, defined
-@item MySQL is Open Source Software.
-
-Open Source means that it is possible for anyone to use and modify.
-Anybody can download MySQL from the Internet and use it
-without paying anything. Anybody so inclined can study the source code
-and change it to fit their needs. MySQL uses the GPL (GNU
-General Public License) @uref{http://www.gnu.org}, to define what you
-may and may not do with the software in different situations. If you
-feel uncomfortable with the GPL or need to embed MySQL into a
-commercial application you can buy a commercially licensed version from
-us.
-
-@cindex open source, defined
-@cindex General Public License
-
-@item Why use MySQL?
-
-MySQL is very fast, reliable, and easy to use. If that is what
-you are looking for, you should give it a try. MySQL also has a
-very practical set of features developed in very close cooperation with
-our users. You can find a performance comparison of MySQL
-to some other database managers on our benchmark page.
-@xref{MySQL Benchmarks}.
-
-MySQL was originally developed to handle very large databases
-much faster than existing solutions and has been successfully used in
-highly demanding production environments for several years. Though
-under constant development, MySQL today offers a rich and very
-useful set of functions. The connectivity, speed, and security make
-MySQL highly suited for accessing databases on the Internet.
-
-@item The technical features of MySQL
-
-For advanced technical information, see @ref{Reference}. MySQL is
-a client/server system that consists of a multi-threaded SQL server
-that supports different backends, several different client programs and
-libraries, administrative tools, and several programming interfaces.
-
-We also provide MySQL as a multi-threaded library which you can
-link into your application to get a smaller, faster, easier to manage
-product.
-
-@item MySQL has a lot of contributed software available.
-
-It is very likely that you will find that your favorite application or
-language already supports MySQL.
-
-@end table
-
-@cindex pronunciation, MySQL
-@cindex MySQL, pronunciation
-@cindex goals of MySQL
-The official way to pronounce MySQL is ``My Ess Que Ell'' (not
-MY-SEQUEL). But we try to avoid correcting people who say MY-SEQUEL.
-
-
-@node What is MySQL AB, Manual-info, What-is, MySQL and MySQL AB
-@subsection What Is MySQL AB
-
-@cindex MySQL AB, defined
-
-MySQL AB is the Swedish company owned and run by the MySQL
-founders and main developers. We are dedicated to developing MySQL
-and spreading our database to new users. MySQL AB owns the copyright
-to the MySQL server source code and the MySQL trademark.
-A significant amount of revenues from our services goes to developing
-MySQL. @xref{What-is}.
-
-MySQL AB has been profitable providing MySQL from the start.
-We don't get any outside funding, but have earned all our money ourselves.
-
-We are searching after partners that would like to support our development
-of MySQL so that we could accelerate the development pace. If you
-are interested in doing this, you can email @email{partner@@mysql.com} about
-this!
-
-MySQL AB has currently 20+ people
-(@uref{http://www.mysql.com/development/team.html}) on its payroll and is growing rapidly.
-
-
-Our main sources of income are:
-
-@itemize @bullet
-@item
-Commercial high quality support for MySQL provided by the
-MySQL developers themselves. If you are interested in purchasing
-a support contract, please visit @uref{https://order.mysql.com/} to view our
-support options or to order support.
-
-@item
-Consulting services. We have developers and consultants in 12 countries
-and partners in many other countries that can help you with almost any
-MySQL related issues. If you need consulting services, please
-email a good description of your needs to @email{info@@mysql.com}! If we
-can't handle this ourselves we can usually find a partner or a developer
-that can help you with your problems.
-
-@item
-We sell licenses for using MySQL as an embedded database.
-@xref{Cost}. If you have a commercial product for which you need a fast,
-high quality database, but you can't afford to make your product Open Source,
-you can buy the right to use the MySQL server under a normal
-commercial copyright. If you are interested in this you can buy
-MySQL licenses at @uref{https://order.mysql.com/} or contact us
-at @email{licensing@@mysql.com}.
-
-@item
-Advertising. @uref{http://www.mysql.com/} is a very popular web site with
-more than 10,000,000 page views per months (January 2001). By putting a
-banner on this you are guaranteed to reach a lot of potential customers
-in the Open source, Linux and database community. If you are interested
-in this email @email{advertising@@mysql.com}.
-
-@item
-We are building a partner program to be able to provide MySQL
-services in every country. If you are interested in becoming a partner
-of MySQL AB please visit
-@uref{http://www.mysql.com/information/partners.html} or email
-@email{partner@@mysql.com}.
-
-@item
-We provide MySQL training through our partner programs. For more
-information, please email @email{info@@mysql.com}.
-
-@item
-The MySQL brand has, since 1995, been associated with speed and
-reliability, and is known to be something you can depend upon. If you are
-interested in using the MySQL trademark in your marketing, you
-can email @email{info@@mysql.com} about this.
-@end itemize
-
-The MySQL core values show our dedication to MySQL and
-Open Source.
-
-We want MySQL to be:
-
-@itemize @bullet
-@item
-The best and the most used database in the world.
-@item
-Available and affordable for all.
-@item
-Easy to use.
-@item
-Continuously improved while remaining fast and safe.
-@item
-Fun to use and improve.
-@item
-Free from bugs.
-@end itemize
+@cindex online location of manual
+@cindex manual, online location
-MySQL AB and the people of MySQL AB:
+This is the @code{MySQL} reference manual; it documents @code{MySQL}
+Version @value{mysql_version}. Being a reference manual, it does not
+provide general instruction on @code{SQL} or relational database
+concepts.
-@itemize @bullet
-@item
-Promote Open Source Philosophy and support the Open Source Community.
-@item
-Aim to be good citizens.
-@item
-Prefer partners that share our values and mind-set.
-@item
-Answer mail and give support.
-@item
-Are a virtual company, networking with others.
-@item
-Work against software patents.
-@end itemize
+As the @code{MySQL Database Software} is under constant development,
+the manual is also updated frequently.
+The most recent version of this manual is available at
+@uref{http://www.mysql.com/documentation/} in many different formats,
+including Texinfo, plain text, Info, HTML, PostScript, PDF,
+and Windows HLP versions.
+The primary document is the Texinfo file.
+The HTML version is produced automatically using a modified version of
+@code{texi2html}.
+The plain text and Info versions are produced with @code{makeinfo}.
+The PostScript version is produced using @code{texi2dvi} and @code{dvips}.
+The PDF version is produced with @code{pdftex}.
-@node Manual-info, Manual conventions, What is MySQL AB, MySQL and MySQL AB
-@subsection About This Manual
+If you have a hard time finding information in the manual, you can try
+our searchable PHP version at @uref{http://www.mysql.com/doc/}.
-This manual is currently available in Texinfo, plain text, Info, HTML,
-PostScript, and PDF versions. The primary document is the Texinfo file.
-The HTML version is produced automatically using a modified version of
-@code{texi2html}. The plain text and Info versions are produced with
-@code{makeinfo}. The Postscript version is produced using @code{texi2dvi}
-and @code{dvips}. The PDF version is produced with @code{pdftex}.
+If you have any suggestions concerning additions or corrections to this
+manual, please send them to the documentation team at @email{docs@@mysql.com}.
@cindex manual, available formats
@cindex Texinfo
This manual is written and maintained by David Axmark, Michael (Monty)
-Widenius, Jeremy Cole, and Paul DuBois. For other contributors,
-see @ref{Credits}.
+Widenius, Jeremy Cole, Arjen Lentz, and Paul DuBois. For other
+contributors, see @ref{Credits}.
+
+The copyright (2002) to this manual is owned by the Swedish company
+@code{MySQL AB}. @xref{Copyright}.
+@menu
+* Manual conventions:: Conventions Used in This Manual
+@end menu
-@node Manual conventions, History, Manual-info, MySQL and MySQL AB
+@node Manual conventions, , Manual-info, Manual-info
@subsection Conventions Used in This Manual
+@c We use British English. But let's not publicise that here yet ;-)
+
This manual uses certain typographical conventions:
@cindex manual, typographical conventions
@@ -493,7 +301,7 @@ This manual uses certain typographical conventions:
@table @asis
@item @code{constant}
Constant-width font is used for command names and options; SQL statements;
-database, table and column names; C and Perl code; and environment variables.
+database, table, and column names; C and Perl code; and environment variables.
Example: ``To see how @code{mysqladmin} works, invoke it with the
@code{--help} option.''
@@ -504,15 +312,14 @@ pathnames. Example: ``The distribution is installed under the
@item @samp{c}
Constant-width font with surrounding quotes is also used to indicate
-character sequences. Example: ``To specify a wild card, use the @samp{%}
+character sequences. Example: ``To specify a wildcard, use the @samp{%}
character.''
@item @emph{italic}
Italic font is used for emphasis, @emph{like this}.
@item @strong{boldface}
-Boldface font is used for access privilege names (for example, ``do not grant
-the @strong{process} privilege lightly'') and occasionally to convey
+Boldface font is used in table headings and to convey
@strong{especially strong emphasis}.
@end table
@@ -546,7 +353,7 @@ shell> setenv VARNAME value
shell> some_command
@end example
-Often, database, table, and column names must be substituted into commands. To
+Often database, table, and column names must be substituted into commands. To
indicate that such substitution is necessary, this manual uses
@code{db_name}, @code{tbl_name} and @code{col_name}. For example, you might
see a statement like this:
@@ -562,28 +369,12 @@ your own database, table, and column names, perhaps like this:
mysql> SELECT author_name FROM biblio_db.author_list;
@end example
-SQL statements may be written in uppercase or lowercase. When this manual
-shows a SQL statement, uppercase is used for particular keywords if those
-keywords are under discussion (to emphasize them) and lowercase is used for
-the rest of the statement. For example, you might see the following in a
-discussion of the @code{SELECT} statement:
-
-@example
-mysql> SELECT count(*) FROM tbl_name;
-@end example
-
-On the other hand, in a discussion of the @code{COUNT()} function, the
-same statement would be written like this:
-
-@example
-mysql> select COUNT(*) from tbl_name;
-@end example
-
-If no particular emphasis is intended, all keywords are written uniformly
-in uppercase.
+SQL keywords are not case-sensitive and may be written in uppercase or
+lowercase. This manual uses uppercase.
In syntax descriptions, square brackets (@samp{[} and @samp{]}) are used
-to indicate optional words or clauses:
+to indicate optional words or clauses. For example, in the following
+statement, @code{IF EXISTS} is optional:
@example
DROP TABLE [IF EXISTS] tbl_name
@@ -606,7 +397,116 @@ alternatives are listed within braces (@samp{@{} and @samp{@}}):
@end example
-@node History, Features, Manual conventions, MySQL and MySQL AB
+@node What-is, What is MySQL AB, Manual-info, Introduction
+@section What Is MySQL?
+
+@cindex MySQL, defined
+@cindex MySQL, introduction
+
+@code{MySQL}, the most popular @code{Open Source} SQL database, is
+developed and provided by @code{MySQL AB}. @code{MySQL AB} is a
+commercial company that builds its business providing services around
+the @code{MySQL} database.
+@xref{What is MySQL AB}.
+
+The @code{MySQL} web site (@uref{http://www.mysql.com/})
+provides the latest information about @code{MySQL} software and
+@code{MySQL AB}.
+
+@table @asis
+
+@item @code{MySQL} is a database management system.
+
+A database is a structured collection of data. It may be anything from a
+simple shopping list to a picture gallery or the vast amounts of
+information in a corporate network. To add, access, and process data
+stored in a computer database, you need a database management system
+such as @code{MySQL} Server. Since computers are very good at handling large
+amounts of data, database management plays a central role in computing,
+as stand-alone utilities, or as parts of other applications.
+
+@cindex databases, defined
+
+@item MySQL is a relational database management system.
+
+A relational database stores data in separate tables rather than putting
+all the data in one big storeroom. This adds speed and flexibility.
+The tables are linked by defined relations making it possible to combine
+data from several tables on request. The @code{SQL} part of
+``@code{MySQL}'' stands for ``@code{Structured Query Language}''@-the
+most common standardised language used to access databases.
+
+@cindex relational databases, defined
+@cindex SQL, defined
+@item MySQL software is @code{Open Source}.
+
+@code{Open Source} means that it is possible for anyone to use and modify.
+Anybody can download the @code{MySQL} software from the Internet and use it
+without paying anything. Anybody so inclined can study the source code
+and change it to fit their needs. The @code{MySQL} software uses the
+@code{GPL} (@code{GNU General Public License}),
+@uref{http://www.gnu.org/licenses/}, to define what you
+may and may not do with the software in different situations.
+If you feel uncomfortable with the @code{GPL} or need to embed
+@code{MySQL} code into a commercial application you can buy a
+commercially licensed version from us.
+@xref{MySQL licenses}.
+
+@cindex @code{Open Source}, defined
+@cindex General Public License
+
+@item Why use the MySQL Database Server?
+
+The @code{MySQL Database Server} is very fast, reliable, and easy to use.
+If that is what you are looking for, you should give it a try.
+@code{MySQL Server} also has a practical set of features developed in
+close cooperation with our users. You can find a performance comparison
+of @code{MySQL Server} to some other database managers on our benchmark page.
+@xref{MySQL Benchmarks}.
+
+@code{MySQL Server} was originally developed to handle large databases
+much faster than existing solutions and has been successfully used in
+highly demanding production environments for several years. Though
+under constant development, @code{MySQL Server} today offers a rich and
+useful set of functions. Its connectivity, speed, and security make
+@code{MySQL Server} highly suited for accessing databases on the Internet.
+
+@item The technical features of MySQL Server
+
+For advanced technical information, see @ref{Reference}.
+The @code{MySQL Database Software} is a client/server system that consists
+of a multi-threaded @code{SQL} server that supports different backends,
+several different client programs and libraries, administrative tools,
+and a wide range of programming interfaces (@code{API}s).
+
+We also provide @code{MySQL Server} as a multi-threaded library which you
+can link into your application to get a smaller, faster, easier-to-manage
+product.
+
+@item There is a large amount of contributed MySQL software available.
+
+It is very likely that you will find that your favorite application or
+language already supports the @code{MySQL Database Server}.
+
+@end table
+
+@cindex pronunciation, MySQL
+@cindex MySQL, pronunciation
+@cindex goals of MySQL
+The official way to pronounce @code{MySQL} is ``My Ess Que Ell'' (not
+``my sequel''), but we don't mind if you pronounce it as ``my sequel''
+or in some other localised way.
+
+
+@menu
+* History:: History of MySQL
+* Features:: The Main Features of MySQL
+* Stability:: How Stable Is MySQL?
+* Table size:: How Big Can MySQL Tables Be?
+* Year 2000 compliance:: Year 2000 Compliance
+@end menu
+
+@node History, Features, What-is, What-is
@subsection History of MySQL
@cindex MySQL history
@@ -621,373 +521,310 @@ flexible enough for our needs. This resulted in a new SQL interface to our
database but with almost the same API interface as @code{mSQL}. This API was
chosen to ease porting of third-party code.
-The derivation of the name MySQL is not perfectly clear. Our base
+The derivation of the name @code{MySQL} is not perfectly clear. Our base
directory and a large number of our libraries and tools have had the prefix
``my'' for well over 10 years. However, Monty's daughter (some years younger)
-is also named My. Which of the two gave its name to MySQL is
+is also named My. Which of the two gave its name to @code{MySQL} is
still a mystery, even for us.
-@node Features, Stability, History, MySQL and MySQL AB
+@node Features, Stability, History, What-is
@subsection The Main Features of MySQL
@cindex main features of MySQL
@cindex features of MySQL
The following list describes some of the important characteristics
-of MySQL:
+of the @code{MySQL Database Software}. @xref{MySQL 4.0 In A Nutshell}.
@c This list is too technical and should be divided into one feature
@c list comparable to commercial competition and a very technical on
@c with max limits (from crash-me) and so on.
+@table @asis
+@item Internals and Portability
@itemize @bullet
@item
+Written in C and C++. Tested with a broad range of different compilers.
+@item
+Works on many different platforms. @xref{Which OS}.
+@item
+Uses GNU Automake (1.4), Autoconf (Version 2.52 or newer), and Libtool for
+portability.
+@item
+APIs for C, C++, Eiffel, Java, Perl, PHP, Python, and Tcl. @xref{Clients}.
+@item
Fully multi-threaded using kernel threads. This means it can easily
use multiple CPUs if available.
-
@item
-C, C++, Eiffel, Java, Perl, PHP, Python and Tcl APIs. @xref{Clients}.
-
+Very fast B-tree disk tables with index compression.
@item
-Works on many different platforms. @xref{Which OS}.
+A very fast thread-based memory allocation system.
+@item
+Very fast joins using an optimised one-sweep multi-join.
+@item
+In-memory hash tables which are used as temporary tables.
+@item
+SQL functions are implemented through a highly optimised class library and
+should be as fast as possible! Usually there isn't any memory allocation
+at all after query initialisation.
+@item
+The @code{MySQL} code gets tested with Purify
+(a commercial memory leakage detector) as well as with Valgrind,
+a GPL tool (@uref{http://developer.kde.org/~sewardj/}).
+@end itemize
+@item Column Types
+@itemize @bullet
@item
Many column types: signed/unsigned integers 1, 2, 3, 4, and 8 bytes
long, @code{FLOAT}, @code{DOUBLE}, @code{CHAR}, @code{VARCHAR},
@code{TEXT}, @code{BLOB}, @code{DATE}, @code{TIME}, @code{DATETIME},
-@code{TIMESTAMP}, @code{YEAR}, @code{SET}, and @code{ENUM} types.
+@code{TIMESTAMP}, @code{YEAR}, @code{SET}, and @code{ENUM} types.
@xref{Column types}.
-
@item
-Very fast joins using an optimized one-sweep multi-join.
+Fixed-length and variable-length records.
+@item
+@cindex default values
+All columns have default values.
+You can use @code{INSERT} to insert a subset of a table's columns; those
+columns that are not explicitly given values are set to their default
+values.
+@end itemize
+@item Commands and Functions
+@itemize @bullet
@item
Full operator and function support in the @code{SELECT} and @code{WHERE}
parts of queries. For example:
@example
-mysql> SELECT CONCAT(first_name, " ", last_name) FROM tbl_name
- WHERE income/dependents > 10000 AND age > 30;
+mysql> SELECT CONCAT(first_name, " ", last_name)
+ -> FROM tbl_name
+ -> WHERE income/dependents > 10000 AND age > 30;
@end example
@item
-SQL functions are implemented through a highly optimized class library and
-should be as fast as possible! Usually there isn't any memory allocation
-at all after query initialization.
-
-@item
-Full support for SQL @code{GROUP BY} and @code{ORDER BY} clauses. Support
-for group functions (@code{COUNT()}, @code{COUNT(DISTINCT ...)},
-@code{AVG()}, @code{STD()}, @code{SUM()}, @code{MAX()} and @code{MIN()}).
-
+Full support for SQL @code{GROUP BY} and
+@code{ORDER BY} clauses. Support
+for group functions (@code{COUNT()},
+@code{COUNT(DISTINCT ...)},
+@code{AVG()}, @code{STD()},
+@code{SUM()}, @code{MAX()}, and @code{MIN()}).
@item
Support for @code{LEFT OUTER JOIN} and @code{RIGHT OUTER JOIN} with ANSI
SQL and ODBC syntax.
-
+@item
+Aliases on tables and columns are allowed as in the SQL92 standard.
+@item
+@code{DELETE}, @code{INSERT}, @code{REPLACE}, and @code{UPDATE} return
+the number of rows that were changed (affected). It is possible to return
+the number of rows matched instead by setting a flag when connecting to the
+server.
+@item
+The @code{MySQL}-specific @code{SHOW} command can be used to retrieve
+information about databases, tables, and indexes. The @code{EXPLAIN} command
+can be used to determine how the optimiser resolves a query.
+@item
+Function names do not clash with table or column names. For example,
+@code{ABS} is a valid column name. The only restriction is that for a
+function call, no spaces are allowed between the function name and the
+@samp{(} that follows it. @xref{Reserved words}.
@item
You can mix tables from different databases in the same query (as of
Version 3.22).
+@end itemize
+@item Security
+@itemize @bullet
@item
A privilege and password system that is very flexible and secure, and
allows host-based verification. Passwords are secure because all
password traffic is encrypted when you connect to a server.
+@end itemize
+@item Scalability and Limits
+@itemize @bullet
@item
-ODBC (Open-DataBase-Connectivity) support for Win32 (with source). All
-ODBC 2.5 functions and many others. For example, you can use MS Access to
-connect to your MySQL server. @xref{ODBC}.
-
-@item
-Very fast B-tree disk tables with index compression.
-
+Handles large databases. We are using @code{MySQL Server} with some
+databases that contain 50 million records and we know of users that
+use @code{MySQL Server} with 60,000 tables and about 5,000,000,000 rows.
@item
Up to 32 indexes per table are allowed. Each index may consist of 1 to 16
-columns or parts of columns. The maximum index length is 500 bytes (this
-may be changed when compiling MySQL). An index may use a prefix
-of a @code{CHAR} or @code{VARCHAR} field.
-
-@item
-Fixed-length and variable-length records.
-
-@item
-In-memory hash tables which are used as temporary tables.
-
-@item
-Handles large databases. We are using MySQL with some
-databases that contain 50,000,000 records and we know of users that
-uses MySQL with 60,000 tables and about 5,000,000,000 rows
-
-@item
-All columns have default values. You can use @code{INSERT} to insert a
-subset of a table's columns; those columns that are not explicitly given
-values are set to their default values.
-
-@item
-Uses GNU Automake, Autoconf, and Libtool for portability.
-
-@item
-Written in C and C++. Tested with a broad range of different compilers.
+columns or parts of columns. The maximum index width is 500 bytes
+(this may be changed when compiling @code{MySQL Server}).
+An index may use a prefix of a @code{CHAR} or @code{VARCHAR} field.
+@end itemize
+@item Connectivity
+@itemize @bullet
@item
-A very fast thread-based memory allocation system.
-
+Clients may connect to the @code{MySQL} server using TCP/IP Sockets,
+Unix Sockets (Unix), or Named Pipes (NT).
@item
-No memory leaks. MySQL has been tested with Purify, a commercial
-memory leakage detector.
+@code{ODBC} (Open-DataBase-Connectivity) support for Win32 (with source).
+All ODBC 2.5 functions and many others. For example, you can use
+MS Access to connect to your @code{MySQL} server. @xref{ODBC}.
+@end itemize
+@item Localisation
+@itemize @bullet
@item
-Includes @code{myisamchk}, a very fast utility for table checking,
-optimization, and repair. All of the functionality of @code{myisamchk}
-is also available through the SQL interface as well.
-@xref{MySQL Database Administration}.
-
+The server can provide error messages to clients in many languages.
+@xref{Languages}.
@item
Full support for several different character sets, including
-ISO-8859-1 (Latin1), big5, ujis, and more. For example, the
-Scandinavian characters `@ringaccent{a}', `@"a' and `@"o' are allowed
-in table and column names.
-
+ISO-8859-1 (Latin1), german, big5, ujis, and more. For example,
+the Scandinavian characters 'å', 'ä' and 'ö' are allowed in table
+and column names.
@item
-All data are saved in the chosen character set. All comparisons for normal
-string columns are case insensitive.
-
+All data is saved in the chosen character set. All comparisons for normal
+string columns are case-insensitive.
@item
Sorting is done according to the chosen character set (the Swedish
-way by default). It is possible to change this when the MySQL server
-is started up. To see an example of very advanced sorting, look at the
-Czech sorting code. MySQL supports many different character sets
-that can be specified at compile and run time.
-
-@item
-Aliases on tables and columns are allowed as in the SQL92 standard.
-
-@item
-@code{DELETE}, @code{INSERT}, @code{REPLACE}, and @code{UPDATE} return
-the number of rows that were changed (affected). It is possible to return
-the number of rows matched instead by setting a flag when connecting to the
-server.
+way by default). It is possible to change this when the @code{MySQL}
+server is started. To see an example of very advanced sorting, look
+at the Czech sorting code. @code{MySQL Server} supports many different
+character sets that can be specified at compile and runtime.
+@end itemize
+@item Clients and Tools
+@itemize @bullet
@item
-Function names do not clash with table or column names. For example,
-@code{ABS} is a valid column name. The only restriction is that for a
-function call, no spaces are allowed between the function name and the
-@samp{(} that follows it. @xref{Reserved words}.
-
+Includes @code{myisamchk}, a very fast utility for table checking,
+optimisation, and repair. All of the functionality of @code{myisamchk}
+is also available through the SQL interface as well.
+@xref{MySQL Database Administration}.
@item
-All MySQL programs can be invoked with the @code{--help} or @code{-?}
+All @code{MySQL} programs can be invoked with the @code{--help} or @code{-?}
options to obtain online assistance.
-
-@item
-The server can provide error messages to clients in many languages.
-@xref{Languages}.
-
-@item
-Clients may connect to the MySQL server using TCP/IP Sockets,
-Unix Sockets (Unix), or Named Pipes (NT).
-
-@item
-The MySQL-specific @code{SHOW} command can be used to retrieve
-information about databases, tables, and indexes. The @code{EXPLAIN} command
-can be used to determine how the optimizer resolves a query.
@end itemize
+@end table
-@node Stability, Table size, Features, MySQL and MySQL AB
+
+@node Stability, Table size, Features, What-is
@subsection How Stable Is MySQL?
@cindex stability
-This section addresses the questions ``How stable is MySQL?'' and
-``Can I depend on MySQL in this project?'' We will try to clarify
-some issues and to answer some of the more important questions that seem to
-concern many people. This section has been put together from information
-gathered from the mailing list (which is very active in reporting bugs).
-
-At TcX, MySQL has worked without any problems in our projects since
-mid-1996. When MySQL was released to a wider public, we noticed that
-there were some pieces of ``untested code'' that were quickly found by the
-new users who made queries in a manner different than our own. Each new
-release has had fewer portability problems than the previous one (even though
-each has had many new features).
-
-Each release of MySQL has been usable, and there have been problems
-only when users start to use code from the ``gray zones.'' Naturally, outside
-users don't know what the gray zones are; this section attempts to indicate
-those that are currently known. The descriptions deal with Version 3.23
-of MySQL. All known and reported bugs are fixed in the latest
-version, with the exception of the bugs listed in the bugs section, which
-are things that are design-related. @xref{Bugs}.
-
-MySQL is written in multiple layers and different independent
-modules. These modules are listed below with an indication of how
+This section addresses the questions ``@emph{How stable is MySQL Server?}''
+and ``@emph{Can I depend on MySQL Server in this project?}''
+We will try to clarify these issues and answer some important
+questions that concern many potential users. The information in this
+section is based on data gathered from the mailing list, which is
+very active in identifying problems as well as reporting types of use.
+
+Original code stems back from the early '80s, providing a stable code
+base, and the ISAM table format remains backward-compatible.
+At TcX, the predecessor of @code{MySQL AB}, @code{MySQL} code has worked
+in projects since mid-1996, without any problems.
+When the @code{MySQL Database Software} was released to a wider public,
+we noticed that there were
+some pieces of ``untested code'' that were quickly found by the new
+users who made different types of queries from us. Each new release
+has had fewer portability problems (even though each new release has
+had many new features).
+
+Each release of the @code{MySQL Server} has been usable. There have only
+been problems
+when users try code from the ``gray zones.'' Naturally, new users
+don't know what the gray zones are; this section attempts to indicate
+those that are currently known.
+The descriptions mostly deal with Version 3.23 of @code{MySQL Server}.
+All known and reported bugs are fixed in the latest version, with the
+exception of those listed in the bugs section, which are things that
+are design-related. @xref{Bugs}.
+
+The @code{MySQL Server} design is multi-layered with independent modules.
+Some of the newer modules are listed here with an indication of how
well-tested each of them is:
@cindex modules, list of
@table @strong
-@item The ISAM table handler --- Stable
-This manages storage and retrieval of all data in MySQL Version 3.22
-and earlier. In all MySQL releases there hasn't been a single
-(reported) bug in this code. The only known way to get a corrupted table
-is to kill the server in the middle of an update. Even that is unlikely
-to destroy any data beyond rescue, because all data are flushed to disk
-between each query. There hasn't been a single bug report about lost data
-because of bugs in MySQL.
-
-@cindex ISAM table handler
-@cindex storing, data
-@cindex retrieving, data
-@cindex data, ISAM table handler
-
-@item The MyISAM table handler --- Stable
-This is new in MySQL Version 3.23. It's largely based on the ISAM
-table code but has a lot of new and very useful features.
-
-@item The parser and lexical analyser --- Stable
-There hasn't been a single reported bug in this system for a long time.
-
-@item The C client code --- Stable
-No known problems. In early Version 3.20 releases, there were some limitations
-in the send/receive buffer size. As of Version 3.21, the buffer size is now
-dynamic up to a default of 16M.
-
-@item Standard client programs --- Stable
-These include @code{mysql}, @code{mysqladmin}, @code{mysqlshow},
-@code{mysqldump}, and @code{mysqlimport}.
-
-@item Basic SQL --- Stable
-The basic SQL function system and string classes and dynamic memory
-handling. Not a single reported bug in this system.
-
-@item Query optimizer --- Stable
-
-@item Range optimizer --- Stable
-
-@item Join optimizer --- Stable
-
-@item Locking --- Gamma
+@item Replication -- Gamma
+Large server clusters using replication are in production use, with
+good results. Work on enhanced replication features is continuing
+in @code{MySQL} 4.0.
+
+@item @code{InnoDB} tables -- Stable (in 3.23 from 3.23.49)
+The @code{InnoDB} transactional table handler has now been declared
+stable in the @code{MySQL} 3.23 tree, starting from version 3.23.49.
+@code{InnoDB} is being used in large, heavy-load production systems.
+
+@item @code{BDB} tables -- Gamma
+The @code{Berkeley DB} code is very stable, but we are still improving
+the @code{BDB} transactional table handler interface in
+@code{MySQL Server}, so it will take some time before this is as well
+tested as the other table types.
+
+@item @code{FULLTEXT} -- Beta
+Full-text search works but is not yet widely used.
+Important enhancements are being implemented for @code{MySQL} 4.0.
+
+@item @code{MyODBC 2.50} (uses ODBC SDK 2.5) -- Gamma
+Increasingly in wide use. Some issues brought up appear to be
+application-related and independent of the ODBC driver or underlying
+database server.
+
+@item Automatic recovery of @code{MyISAM} tables -- Gamma
+This status only regards the new code in the @code{MyISAM} table
+handler that checks if the table was closed properly on open and
+executes an automatic check/repair of the table if it wasn't.
+
+@item Bulk-insert -- Alpha
+New feature in @code{MyISAM} tables in @code{MySQL} 4.0 for faster
+insert of many rows.
+
+@item Locking -- Gamma
This is very system-dependent. On some systems there are big problems
-using standard OS locking (@code{fcntl()}). In these cases, you should run the
-MySQL daemon with the @code{--skip-locking} flag. Problems are known
-to occur on some Linux systems, and on SunOS when using NFS-mounted file
-systems.
-
-@item Linux threads --- Stable
-The major problem found has been with the @code{fcntl()} call, which is
-fixed by using the @w{@code{--skip-locking}} option to
-@code{mysqld}. Some people have reported lockup problems with Version 0.5.
-LinuxThreads will need to be recompiled if you plan to use
-1000+ concurrent connections. Although it is possible to run that many
-connections with the default LinuxThreads (however, you will never go
-above 1021), the default stack spacing of 2 MB makes the application
-unstable, and we have been able to reproduce a coredump after creating
-1021 idle connections. @xref{Linux}.
-
-@item Solaris 2.5+ pthreads --- Stable
-We use this for all our production work.
-
-@item MIT-pthreads (Other systems) --- Stable
-There have been no reported bugs since Version 3.20.15 and no known bugs since
-Version 3.20.16. On some systems, there is a ``misfeature'' where some
-operations are quite slow (a 1/20 second sleep is done between each query).
-Of course, MIT-pthreads may slow down everything a bit, but index-based
-@code{SELECT} statements are usually done in one time frame so there shouldn't
-be a mutex locking/thread juggling.
-
-@item Other thread implementions --- Beta - Gamma
-The ports to other systems are still very new and may have bugs, possibly
-in MySQL, but most often in the thread implementation itself.
-
-@item @code{LOAD DATA ...}, @code{INSERT ... SELECT} --- Stable
-Some people thought they had found bugs here, but these usually have
-turned out to be misunderstandings. Please check the manual before reporting
-problems!
-
-@item @code{ALTER TABLE} --- Stable
-Small changes in Version 3.22.12.
-
-@item DBD --- Stable
-Now maintained by Jochen Wiedmann
-(@email{wiedmann@@neckar-alb.de}). Thanks!
-
-@item @code{mysqlaccess} --- Stable
-Written and maintained by Yves Carlier
-(@email{Yves.Carlier@@rug.ac.be}). Thanks!
-
-@item @code{GRANT} --- Stable
-Big changes made in MySQL Version 3.22.12.
-
-@item @strong{MyODBC} (uses ODBC SDK 2.5) --- Gamma
-It seems to work well with some programs.
-
-@item Replication -- Beta / Gamma
-We are still working on replication, so don't expect this to be rock
-solid yet. On the other hand, some MySQL users are already
-using this with good results.
-
-@item BDB Tables -- Beta
-The Berkeley DB code is very stable, but we are still improving the interface
-between MySQL and BDB tables, so it will take some time before this
-is as tested as the other table types.
-
-@item InnoDB Tables -- Beta
-This is a recent addition to @code{MySQL}. They appear to work good and
-can be used after some initial testing.
-
-@item Automatic recovery of MyISAM tables - Beta
-This only affects the new code that checks if the table was closed properly
-on open and executes an automatic check/repair of the table if it wasn't.
-
-@item MERGE tables -- Beta / Gamma
-The usage of keys on @code{MERGE} tables is still not that tested. The
-other part of the @code{MERGE} code is quite well tested.
-
-@item FULLTEXT -- Beta
-Text search seems to work, but is still not widely used.
+using standard OS locking (@code{fcntl()}). In these cases, you should
+run @code{mysqld} with the @code{--skip-external-locking} flag.
+Problems are known to occur on some Linux systems, and on SunOS when
+using NFS-mounted filesystems.
@end table
-MySQL AB provides e-mail support for paying customers, but the
-MySQL mailing list usually provides answers to common questions.
-Bugs are usually fixed right away with a patch; for serious bugs, there is
-almost always a new release.
+@code{MySQL AB} provides high-quality support for paying customers,
+but the @code{MySQL} mailing list usually provides answers to common
+questions. Bugs are usually fixed right away with a patch; for serious
+bugs, there is almost always a new release.
-@node Table size, Year 2000 compliance, Stability, MySQL and MySQL AB
+@node Table size, Year 2000 compliance, Stability, What-is
@subsection How Big Can MySQL Tables Be?
@cindex tables, maximum size
@cindex size of tables
-@cindex operating systems, file size limits
-@cindex limits, file size
+@cindex operating systems, file-size limits
+@cindex limits, file-size
@cindex files, size limits
-MySQL Version 3.22 has a 4G limit on table size. With the new
-@code{MyISAM} in MySQL Version 3.23 the maximum table size is
-pushed up to 8 million terabytes (2 ^ 63 bytes).
+@code{MySQL} Version 3.22 has a 4G limit on table size. With the new
+@code{MyISAM} table type in @code{MySQL} Version 3.23, the maximum table
+size is pushed up to 8 million terabytes (2 ^ 63 bytes).
-Note, however, that operating systems have their own file size
+Note, however, that operating systems have their own file-size
limits. Here are some examples:
-@multitable @columnfractions .5 .5
-@item @strong{Operating System} @tab @strong{File Size Limit}
+@multitable @columnfractions .30 .50
+@item @strong{Operating System} @tab @strong{File-Size Limit}
@item Linux-Intel 32 bit @tab 2G, 4G or more, depends on Linux version
@item Linux-Alpha @tab 8T (?)
@item Solaris 2.5.1 @tab 2G (possible 4G with patch)
-@item Solaris 2.6 @tab 4G
+@item Solaris 2.6 @tab 4G (can be changed with flag)
@item Solaris 2.7 Intel @tab 4G
-@item Solaris 2.7 ULTRA-SPARC @tab 8T (?)
+@item Solaris 2.7 UltraSPARC @tab 512G
@end multitable
On Linux 2.2 you can get bigger tables than 2G by using the LFS patch for
-the ext2 file system. On Linux 2.4 there exists also patches for ReiserFS
+the ext2 filesystem. On Linux 2.4 patches also exist for ReiserFS
to get support for big files.
-This means that the table size for MySQL is normally limited by
-the operating system.
+This means that the table size for @code{MySQL} databases is normally
+limited by the operating system.
-By default, MySQL tables have a maximum size of about 4G. You can
+By default, @code{MySQL} tables have a maximum size of about 4G. You can
check the maximum table size for a table with the @code{SHOW TABLE STATUS}
command or with the @code{myisamchk -dv table_name}.
@xref{SHOW}.
@@ -1006,58 +843,61 @@ have, in effect, much bigger tables. @xref{myisampack, ,
You can go around the operating system file limit for @code{MyISAM} data
files by using the @code{RAID} option. @xref{CREATE TABLE}.
-Another solution can be the included MERGE library, which allows you to
-handle a collection of identical tables as one. @xref{MERGE, MERGE
-tables}.
+Another solution can be the included @code{MERGE} library, which allows
+you to handle a collection of identical tables as one.
+@xref{MERGE, , @code{MERGE} tables}.
-@node Year 2000 compliance, , Table size, MySQL and MySQL AB
+@node Year 2000 compliance, , Table size, What-is
@subsection Year 2000 Compliance
@cindex Year 2000 compliance
@cindex compliance, Y2K
@cindex date functions, Y2K compliance
-MySQL itself has no problems with Year 2000 (Y2K) compliance:
+The @code{MySQL Server} itself has no problems with Year 2000 (Y2K)
+compliance:
@itemize @bullet
@item
-MySQL uses Unix time functions and has no problems with dates
+@code{MySQL Server} uses Unix time functions and has no problems with dates
until @code{2069}; all 2-digit years are regarded to be in the range
@code{1970} to @code{2069}, which means that if you store @code{01} in a
-@code{year} column, MySQL treats it as @code{2001}.
+@code{year} column, @code{MySQL Server} treats it as @code{2001}.
@item
-All MySQL date functions are stored in one file @file{sql/time.cc}
-and coded very carefully to be year 2000-safe.
+All @code{MySQL} date functions are stored in one file, @file{sql/time.cc},
+and are coded very carefully to be year 2000-safe.
@item
-In MySQL Version 3.22 and later, the new @code{YEAR} column type
-can store years @code{0} and @code{1901} to @code{2155} in 1 byte and display
-them using 2 or 4 digits.
+In @code{MySQL} Version 3.22 and later, the new @code{YEAR} column type
+can store years @code{0} and @code{1901} to @code{2155} in 1 byte and
+display them using 2 or 4 digits.
@end itemize
-You may run into problems with applications that use MySQL in a
-way that is not Y2K-safe. For example, many old applications store
+You may run into problems with applications that use @code{MySQL Server}
+in a way that is not Y2K-safe. For example, many old applications store
or manipulate years using 2-digit values (which are ambiguous) rather than
4-digit values. This problem may be compounded by applications that use
values such as @code{00} or @code{99} as ``missing'' value indicators.
-Unfortunately, these problems may be difficult to fix, because different
+Unfortunately, these problems may be difficult to fix because different
applications may be written by different programmers, each of whom may
use a different set of conventions and date-handling functions.
-Here is a simple demonstration illustrating that MySQL doesn't have
-any problems with dates until the year 2030:
+Here is a simple demonstration illustrating that @code{MySQL Server}
+doesn't have any problems with dates until the year 2030:
@example
mysql> DROP TABLE IF EXISTS y2k;
Query OK, 0 rows affected (0.01 sec)
-mysql> CREATE TABLE y2k (date date, date_time datetime, time_stamp timestamp);
+mysql> CREATE TABLE y2k (date DATE,
+ -> date_time DATETIME,
+ -> time_stamp TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)
-mysql> INSERT INTO y2k VALUES
+mysql> INSERT INTO y2k VALUES
-> ("1998-12-31","1998-12-31 23:59:59",19981231235959),
-> ("1999-01-01","1999-01-01 00:00:00",19990101000000),
-> ("1999-09-09","1999-09-09 23:59:59",19990909235959),
@@ -1105,1027 +945,1041 @@ range up to only @code{2030-01-01}. @code{TIMESTAMP} has a range of
@code{1970} to @code{2030} on 32-bit machines (signed value). On 64-bit
machines it handles times up to @code{2106} (unsigned value).
-Even though MySQL is Y2K-compliant, it is your responsibility to
-provide unambiguous input. See @ref{Y2K issues} for MySQL's rules
-for dealing with ambiguous date input data (data containing 2-digit year
-values).
+Even though @code{MySQL Server} is Y2K-compliant, it is your responsibility
+to provide unambiguous input. See @ref{Y2K issues} for @code{MySQL Server}'s
+rules for dealing with ambiguous date input data (data containing 2-digit
+year values).
-@node MySQL Information Sources, Licensing and Support, MySQL and MySQL AB, Introduction
-@section MySQL Information Sources
-@cindex manuals, about MySQL
-@cindex books, about MySQL
+@node What is MySQL AB, Licensing and Support, What-is, Introduction
+@section What Is MySQL AB?
-@menu
-* MySQL-Books:: Books About MySQL
-* General-SQL:: General SQL Information and Tutorials
-* Useful Links:: Useful MySQL-related Links
-* Questions:: MySQL Mailing Lists
-@end menu
+@cindex MySQL AB, defined
+@code{MySQL AB} is the company of the @code{MySQL} founders and main
+developers. @code{MySQL AB} was originally established in Sweden by
+David Axmark, Allan Larsson, and Michael @code{Monty} Widenius.
-@node MySQL-Books, General-SQL, MySQL Information Sources, MySQL Information Sources
-@subsection Books About MySQL
-
-For the latest book information, with user comments, please visit
-@uref{http://www.mysql.com/portal/books/html/index.html}.
-
-While this manual is still the right place for up to date technical
-information, its primary goal is to contain everything there is to know
-about MySQL. It is sometimes nice to have a bound book to read
-in bed or while you travel. Here is a list of books about MySQL and
-related subjects (in English).
-
-By purchasing a book through these hyperlinks provided herein, you are
-contributing to the development of MySQL.
-
-@emph{MySQL}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0735709211&bfmtype=book, Barnes and Noble}
-@item Publisher @tab New Riders
-@item Author @tab Paul DuBois
-@item Pub Date @tab 1st Edition December 1999
-@item ISBN @tab 0735709211
-@item Pages @tab 800
-@item Price @tab $49.99 US
-@item Downloadable examples @tab
- @uref{http://www.kitebird.com/mysql-book/, @code{samp_db} distribution}
-@item Errata @tab
-@uref{http://www.kitebird.com/mysql-book/errata.html, are available here}
-@end multitable
+All the developers of the @code{MySQL} server are employed by the company.
+We are a virtual organisation with people in a dozen countries around
+the world. We communicate extensively over the Net every day with each
+other and with our users, supporters and partners.
-Foreword by Michael ``Monty'' Widenius, MySQL Moderator.
-@*
+We are dedicated to developing the @code{MySQL} software and spreading
+our database to new users. @code{MySQL AB} owns the copyright to the
+@code{MySQL} source code, the @code{MySQL} logo and trademark, and this
+manual. @xref{What-is}.
-In @emph{MySQL}, Paul DuBois provides you with a comprehensive guide to
-one of the most popular relational database systems. Paul has
-contributed to the online documentation for MySQL and is an
-active member of the MySQL community. The principal MySQL
-developer, Monty Widenius, and a network of his fellow developers
-reviewed the manuscript, and provided Paul with the kind of insight
-no one else could supply.
-@*
+@menu
+* MySQL AB business model and services:: The Business Model and Services of MySQL AB
+* Contact information:: Contact Information
+@end menu
-Instead of merely giving you a general overview of MySQL, Paul
-teaches you how to make the most of its capabilities. Through two
-sample database applications that run throughout the book, he
-gives you solutions to problems you're sure to face. He helps you
-integrate MySQL efficiently with third-party tools, such as PHP
-and Perl, enabling you to generate dynamic Web pages through
-database queries. He teaches you to write programs that access
-MySQL databases, and also provides a comprehensive set of
-references to column types, operators, functions, SQL syntax,
-MySQL programming, C API, Perl @code{DBI}, and PHP API.
-@emph{MySQL} simply gives you the kind of information you won't find
-anywhere else.
-@*
+The @code{MySQL} core values show our dedication to @code{MySQL} and
+@code{Open Source}.
-If you use MySQL, this book provides you with:
+We want the @code{MySQL Database Software} to be:
@itemize @bullet
@item
-An introduction to MySQL and SQL.
+The best and the most widely used database in the world.
+@item
+Available and affordable for all.
+@item
+Easy to use.
+@item
+Continuously improving while remaining fast and safe.
+@item
+Fun to use and improve.
@item
-Coverage of MySQL's data types and how to use them.
+Free from bugs.
+@end itemize
+
+@code{MySQL AB} and the people at @code{MySQL AB}:
+@itemize @bullet
@item
-Thorough treatment of how to write client programs in C.
+Promote @code{Open Source} philosophy and support the
+@code{Open Source} community.
@item
-A guide to using the Perl @code{DBI} and PHP APIs for developing
-command-line and Web-based applications.
+Aim to be good citizens.
@item
-Tips on administrative issues such as user accounts, backup,
-crash recovery, and security.
+Prefer partners that share our values and mind-set.
@item
-Help in choosing an ISP for MySQL access.
+Answer e-mail and provide support.
@item
-A comprehensive reference for MySQL's data types, operators,
-functions, and SQL statements and utilities.
+Are a virtual company, networking with others.
@item
-Complete reference guides for MySQL's C API, the Perl @code{DBI} API,
-and PHP's MySQL-related functions.
+Work against software patents.
@end itemize
-@*
-
-@emph{MySQL & mSQL}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1565924347&bfmtype=book, Barnes and Noble}
-@item Publisher @tab O'Reilly
-@item Authors @tab Randy Jay Yarger, George Reese & Tim King
-@item Pub Date @tab 1st Edition July 1999
-@item ISBN @tab 1-56592-434-7, Order Number: 4347
-@item Pages @tab 506
-@item Price @tab $34.95
-@end multitable
-
-This book teaches you how to use MySQL and @code{mSQL}, two popular
-and robust database products that support key subsets of SQL on both Linux
-and Unix systems. Anyone who knows basic C, Java, Perl, or Python can
-write a program to interact with a database, either as a stand-alone
-application or through a Web page. This book takes you through the
-whole process, from installation and configuration to programming
-interfaces and basic administration. Includes plenty of tutorial
-material.
-@*
-
-@emph{Sams' Teach Yourself MySQL in 21 Days}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0672319144&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Sams
-@item Authors @tab Mark Maslakowski and Tony Butcher
-@item Pub Date @tab June 2000
-@item ISBN @tab 0672319144
-@item Pages @tab 650
-@item Price @tab $39.99
-@end multitable
-
-Sams' @emph{Teach Yourself MySQL in 21 Days} is for intermediate Linux users
-who want to move into databases. A large share of the audience is Web
-developers who need a database to store large amounts of information that
-can be retrieved via the Web.
-
-Sams' @emph{Teach Yourself MySQL in 21 Days} is a practical, step-by-step
-tutorial. The reader will learn to design and employ this open source
-database technology into his or her Web site using practical, hands-on
-examples to follow.
-@*
-
-@emph{E-Commerce Solutions with MySQL}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0761524452&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Prima Communications, Inc.
-@item Authors @tab N/A
-@item Pub Date @tab January 2000
-@item ISBN @tab 0761524452
-@item Pages @tab 500
-@item Price @tab $39.99
-@end multitable
-
-No description available.
-@*
-
-@emph{MySQL and PHP from Scratch}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0789724405&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Que
-@item Authors @tab N/A
-@item Pub Date @tab September 2000
-@item ISBN @tab 0789724405
-@item Pages @tab 550
-@item Price @tab $34.99
-@end multitable
-
-This book puts together information on installing, setting up, and
-troubleshooting Apache, MySQL, PHP3, and IMP into one complete
-volume. You also learn how each piece is part of a whole by learning,
-step-by-step, how to create a web-based e-mail system. Learn to run
-the equivalent of Active Server Pages (ASP) using PHP3, set up an
-e-commerce site using a database and the Apache web server, and create
-a data entry system (such as sales, product quality tracking, customer
-preferences, etc) that no installation in the PC.
-@*
-
-@emph{Professional MySQL Programming}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=1861005164, Barnes and Noble}
-@item Publisher @tab Wrox Press, Inc.
-@item Authors @tab N/A
-@item Pub Date @tab Late 2001
-@item ISBN @tab 1861005164
-@item Pages @tab 1000
-@item Price @tab $49.99
-@end multitable
-
-No description available.
-@*
-
-@emph{Professional Linux Programming}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1861003013&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Wrox Press, Inc.
-@item Authors @tab N/A
-@item Pub Date @tab September 2000
-@item ISBN @tab 1861003013
-@item Pages @tab 1155
-@item Price @tab $47.99
-@end multitable
-
-In this follow-up to the best-selling @emph{Beginning Linux Programming},
-you will learn from the authors' real-world knowledge and experience of
-developing software for Linux; you'll be taken through the development
-of a sample 'DVD Store' application, with 'theme' chapters addressing
-different aspects of its implementation. Meanwhile, individual
-``take-a-break'' chapters cover important topics that go beyond the
-bounds of the central theme. All focus on the practical aspects of
-programming, showing how crucial it is to choose the right tools for
-the job, use them as they should be used, and get things right first
-time.
-@*
-
-@emph{PHP and MySQL Web Development}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0672317842&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Sams
-@item Authors @tab Luke Welling, Laura Thomson
-@item Pub Date @tab March 2001
-@item ISBN @tab 0672317842
-@item Pages @tab 700
-@item Price @tab $49.99
-@end multitable
-
-@emph{PHP and MySQL Web Development} introduces you to the advantages
-of implementing both MySQL and PHP. These advantages are detailed
-through the provision of both statistics and several case studies. A
-practical web application is developed throughout the book, providing
-you with the tools necessary to implement a functional online
-database. Each function is developed separately, allowing you the
-choice to incorporate only those parts that you would like to
-implement. Programming concepts of the PHP language are highlighted,
-including functions which tie MySQL support into a PHP script and
-advanced topics regarding table manipulation.
-@*
-
-@strong{Books recommended by the MySQL Developers}
-
-@emph{SQL-99 Complete, Really}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0879305681&bfmtype=book, Barnes and Noble}
-@item Publisher @tab CMP Books
-@item Authors @tab Peter Gulutzan, Trudy Pelzer
-@item Pub Date @tab April 1999
-@item ISBN @tab 0879305681
-@item Pages @tab 1104
-@item Price @tab $55.96
-@end multitable
-This book contains complete descriptions of the new standards for
-syntax, data structures, and retrieval processes of SQL databases. As
-an example-based reference manual, it includes all of the CLI
-functions, information, schema tables, and status codes, as well as a
-working SQL database provided on the companion disk.
-@*
+The @code{MySQL} web site (@uref{http://www.mysql.com/})
+provides the latest information about @code{MySQL} and @code{MySQL AB}.
-@emph{C, A reference manual}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0133262243&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Prentice Hall
-@item Authors @tab Samuel P. Harbison, Guy L. Steele
-@item Pub Date @tab September 1994
-@item ISBN @tab 0133262243
-@item Pages @tab 480
-@item Price @tab $35.99
-@end multitable
-A new and improved revision of the bestselling C language
-reference. This manual introduces the notion of "Clean C", writing C
-code that can be compiled as a C++ program, C programming style that
-emphasizes correctness, portability, maintainability, and
-incorporates the ISO C Amendment 1 (1994) which specifies new
-facilities for writing portable, international programs in C.
-@*
+@node MySQL AB business model and services, Contact information, What is MySQL AB, What is MySQL AB
+@subsection The Business Model and Services of MySQL AB
-@emph{C++ for Real Programmers}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0120499428&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Academic Press, Incorporated
-@item Authors @tab Jeff Alger, Jim Keogh
-@item Pub Date @tab February 1998
-@item ISBN @tab 0120499428
-@item Pages @tab 388
-@item Price @tab $39.95
-@end multitable
+One of the most common questions we encounter is:
+``@emph{How can you make a living from something you give away for free?}''
+This is how.
-@emph{C++ For Real Programmers} bridges the gap between C++ as described
-in beginner and intermediate-level books and C++ as it is practiced by
-experts. Numerous valuable techniques are described, organized into
-three simple themes: indirection, class hierarchies, and memory
-management. It also provides in-depth coverage of template creation,
-exception handling, pointers and optimization techniques. The focus of
-the book is on ANSI C++ and, as such, is compiler independent.
-
-@emph{C++ For Real Programmers} is a revision of
-@emph{Secrets of the C++ Masters} and includes a new appendix comparing C++
-with Java. The book comes with a 3.5" disk for Windows with source code.
-@*
+@code{MySQL AB} makes money on support, services, commercial licenses,
+and royalties, and we use these revenues to fund product development
+and to expand the @code{MySQL} business.
-@emph{Algorithms in C}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0201514257&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Addison Wesley Longman, Inc.
-@item Authors @tab Robert Sedgewick
-@item Pub Date @tab April 1990
-@item ISBN @tab 0201514257
-@item Pages @tab 648
-@item Price @tab $45.75
-@end multitable
-
-@emph{Algorithms in C} describes a variety of algorithms in a number of
-areas of interest, including: sorting, searching, string-processing, and
-geometric, graph and mathematical algorithms. The book emphasizes
-fundamental techniques, providing readers with the tools to confidently
-implement, run, and debug useful algorithms.
-@*
-
-@emph{Multithreaded Programming with Pthreads}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0136807291&bfmtype=book, Barnes and Noble}
-@item Publisher @tab Prentice Hall
-@item Authors @tab Bil Lewis, Daniel J. Berg
-@item Pub Date @tab October 1997
-@item ISBN @tab 0136807291
-@item Pages @tab 432
-@item Price @tab $34.95
-@end multitable
+@menu
+* Business Services Support:: Support
+* Business Services Training:: Training and Certification
+* Business Services Consulting:: Consulting
+* Business Services Commercial licenses:: Commercial Licenses
+* Business Services Partnering:: Partnering
+* Business Services Advertising:: Advertising
+@end menu
-Based on the best-selling @emph{Threads Primer},
-@emph{Multithreaded Programming with Pthreads} gives you a solid
-understanding of Posix threads: what they are, how they work, when to use
-them, and how to optimize them. It retains the clarity and humor of
-@emph{Threads Primer}, but includes expanded comparisons to Win32 and OS/2
-implementations. Code examples tested on all of the major UNIX platforms
-are featured along with detailed explanations of how and why they use threads.
-@*
+The company has been profitable since its inception. In October 2001,
+we accepted venture financing from leading Scandinavian investors and
+a handful of business angels. This investment is used to solidify our
+business model and build a basis for sustainable growth.
-@emph{Programming the PERL DBI: Database Programming with PERL}
-@multitable @columnfractions .3 .7
-@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1565926994&bfmtype=book, Barnes and Noble}
-@item Publisher @tab O'Reilly & Associates, Incorporated
-@item Authors @tab Alligator Descartes, Tim Bunce
-@item Pub Date @tab February 2000
-@item ISBN @tab 1565926994
-@item Pages @tab 400
-@item Price @tab $27.96
-@end multitable
-@emph{Programming the Perl DBI} is coauthored by Alligator Descartes, one
-of the most active members of the DBI community, and by Tim Bunce, the
-inventor of DBI. For the uninitiated, the book explains the architecture
-of DBI and shows you how to write DBI-based programs. For the experienced
-DBI dabbler, this book explains DBI's nuances and the peculiarities of each
-individual DBD.
+@node Business Services Support, Business Services Training, MySQL AB business model and services, MySQL AB business model and services
+@subsubsection Support
+@code{MySQL AB} is run and owned by the founders and main developers of
+the @code{MySQL} database. The developers are committed to giving support
+to customers and other users in order to stay in touch with their needs
+and problems. All our support is given by qualified developers. Really
+tricky questions are answered by Michael @code{Monty} Widenius, principal
+author of the @code{MySQL Server}.
+@xref{Support}.
-The book includes:
-@itemize @bullet
-@item
-An introduction to DBI and its design.
-@item
-How to construct queries and bind parameters.
-@item
-Working with database, driver, and statement handles.
-@item
-Debugging techniques.
-@item
-Coverage of each existing DBD.
-@item
-A complete reference to DBI.
-@end itemize
-@*
+To order support at various levels, please visit the order section at
+@uref{https://order.mysql.com/} or contact our sales staff at
+@email{sales@@mysql.com}.
-@node General-SQL, Useful Links, MySQL-Books, MySQL Information Sources
-@subsection General SQL Information and Tutorials
+@node Business Services Training, Business Services Consulting, Business Services Support, MySQL AB business model and services
+@subsubsection Training and Certification
+@cindex training
+@cindex MySQL training
+@cindex certification
+@cindex MySQL certification
+@code{MySQL AB} delivers @code{MySQL} and related training worldwide.
+We offer both open courses and in-house courses tailored to the
+specific needs of your company. @code{MySQL Training} is also available
+through our partners, the @code{Authorised MySQL Training Centers}.
+
+Our training material uses the same example databases as our
+documentation and our sample applications, and it is always updated
+to reflect the latest @code{MySQL} version. Our trainers are backed by
+the development team to guarantee the quality of the training and the
+continuous development of the course material. This also ensures
+that no questions raised during the courses remain unanswered.
+
+Attending our training courses will enable you to achieve your goals
+related to your @code{MySQL} applications. You will also:
+@itemize @bullet
+@item
+Save time.
+@item
+Improve the performance of your application(s).
+@item
+Reduce or eliminate the need for additional hardware, decreasing cost.
+@item
+Enhance security.
+@item
+Increase customers' and co-workers' satisfaction.
+@item
+Prepare yourself for @code{MySQL Certification}.
+@end itemize
+
+If you are interested in our training as a potential participant or
+as a training partner, please visit the training section at
+@uref{http://www.mysql.com/training/} or contact us at:
+@email{training@@mysql.com}.
+
+The @code{MySQL Certification Program} is being released in the second
+half of 2002. For details please see
+@uref{http://www.mysql.com/training/certification.html}.
+
+
+@node Business Services Consulting, Business Services Commercial licenses, Business Services Training, MySQL AB business model and services
+@subsubsection Consulting
+@cindex consulting
+@cindex MySQL consulting
+@code{MySQL AB} and its @code{Authorised Partners} offer consulting
+services to users of @code{MySQL Server} and to those who embed
+@code{MySQL Server} in their own software, all over the world.
+
+Our consultants can help you design and tune your databases, construct
+efficient queries, tune your platform for optimal performance, resolve
+migration issues, set up replication, build robust transactional
+applications, and more.
+We also help customers embed @code{MySQL Server} in their products and
+applications for large-scale deployment.
+
+Our consultants work in close collaboration with our development team,
+which ensures the technical quality of our professional services.
+Consulting assignments range from 2-day power-start sessions to
+projects that span weeks and months. Our expertise not only covers
+@code{MySQL Server}, but also extends into programming and scripting
+languages such as PHP, Perl, and more.
+
+If you are interested in our consulting services or want to become a
+consulting partner, please visit the consulting section of our web site
+at @uref{http://www.mysql.com/consulting/} or contact our consulting
+staff at @email{consulting@@mysql.com}.
+
+
+@node Business Services Commercial licenses, Business Services Partnering, Business Services Consulting, MySQL AB business model and services
+@subsubsection Commercial Licenses
+The @code{MySQL} database is released under the
+@code{GNU General Public License} (@code{GPL}).
+This means that the @code{MySQL} software can be used free of charge
+under the @code{GPL}. If you do not want to be bound by the @code{GPL}
+terms (like the requirement that your own application becomes @code{GPL}
+as well), you may purchase a commercial license for the same product
+from @code{MySQL AB} at @uref{https://order.mysql.com/}.
+Since @code{MySQL AB} owns the copyright to the @code{MySQL} source code,
+we are able to employ @code{Dual Licensing} which means that the same
+product is available under @code{GPL} and under a commercial
+license. This does not in any way affect the @code{Open Source}
+commitment of @code{MySQL AB}. For details about when a commercial
+license is required, please see @ref{MySQL licenses}.
+
+We also sell commercial licenses of third-party @code{Open Source GPL}
+software that adds value to @code{MySQL Server}. A good example is the
+@code{InnoDB} transactional table handler that offers @code{ACID}
+support, row-level locking, crash recovery, multi-versioning, foreign
+key support, and more. @xref{InnoDB}.
+
+
+@node Business Services Partnering, Business Services Advertising, Business Services Commercial licenses, MySQL AB business model and services
+@subsubsection Partnering
+@cindex partnering with MySQL AB
+@code{MySQL AB} has a worldwide partner programme that covers training
+courses, consulting & support, publications plus reselling and
+distributing @code{MySQL} and related products. @code{MySQL AB Partners}
+get visibility on the @uref{http://www.mysql.com/} web site and the right
+to use special versions of the @code{MySQL} trademarks to identify their
+products and promote their business.
+
+If you are interested in becoming a @code{MySQL AB Partner}, please e-mail
+@email{partner@@mysql.com}.
-The following book has been recommended by several people on the MySQL
-mailing list:
+The word @code{MySQL} and the @code{MySQL} dolphin logo are trademarks of
+@code{MySQL AB}. @xref{MySQL AB Logos and Trademarks}.
+These trademarks represent a significant value that the @code{MySQL}
+founders have built over the years.
-@example
-Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky
-@emph{The Practical SQL Handbook: Using Structured Query Language}
-Second Edition
-Addison-Wesley
-ISBN 0-201-62623-3
-http://www.awl.com
-@end example
-The following book has also received some recommendations by MySQL
-users:
+@node Business Services Advertising, , Business Services Partnering, MySQL AB business model and services
+@subsubsection Advertising
+The @code{MySQL} web site (@uref{http://www.mysql.com/}) is popular among
+developers and users. In October 2001, we served 10 million page views.
+Our visitors represent a group that makes purchase decisions and
+recommendations for both software and hardware. Twelve percent of our
+visitors authorise purchase decisions, and only nine percent are not
+involved in purchase decisions at all. More than 65% have made one or
+more online business purchase within the last half-year, and 70% plan
+to make one in the next months.
-@example
-Martin Gruber
-@emph{Understanding SQL}
-ISBN 0-89588-644-8
-Publisher Sybex 510 523 8233
-Alameda, CA USA
-@end example
+If you are interested in placing banner ads on our web site,
+@uref{http://www.mysql.com/}, please send an e-mail message to
+@email{advertising@@mysql.com}.
-A SQL tutorial is available on the net at
-http://w3.one.net/~jhoffman/sqltut.htm
+@node Contact information, , MySQL AB business model and services, What is MySQL AB
+@subsection Contact Information
-@node Useful Links, Questions, General-SQL, MySQL Information Sources
-@subsection Useful MySQL-related Links
+@cindex contact information
+@cindex employment, contact information
+@cindex licensing, contact information
+@cindex advertising, contact information
+@cindex employment with MySQL
+@cindex jobs at MySQL
-Apart from the following links, you can find and download a lot of
-MySQL programs, tools and APIs from the
-@uref{http://www.mysql.com/Downloads/Contrib/, Contrib directory}.
-@cindex @code{Contrib} directory
+The @code{MySQL} web site (@uref{http://www.mysql.com/})
+provides the latest information about @code{MySQL} and @code{MySQL AB}.
-@cindex URLs to MySQL information
-@cindex related information URLs
-MySQL
-@subheading Tutorials and Manuals
+For press service and inquiries not covered in our News releases
+(@uref{http://www.mysql.com/news/}), please send e-mail to
+@email{press@@mysql.com}.
-@table @asis
-@item @uref{http://michael.bacarella.com/research/mysqlmyths.html, MySQL Myths Debunked}
-MySQL used in the real world.
+If you have a valid support contract with @code{MySQL AB}, you will
+get timely, precise answers to your technical questions about the
+@code{MySQL} software. For more information, see @ref{Support}.
+You can order your support contract at
+@uref{https://order.mysql.com/}, or send an e-mail message to
+@email{sales@@mysql.com}.
-@item @uref{http://www.4t2.com/mysql}
-Information about the German MySQL mailing list.
+For information about @code{MySQL} training, please visit the training
+section at @uref{http://www.mysql.com/training/}. If you have
+restricted access to the Internet, please contact the @code{MySQL AB}
+training staff at @email{training@@mysql.com}.
+@xref{Business Services Training}.
+
+For information on the @code{MySQL Certification Program}, please see
+@uref{http://www.mysql.com/training/certification.html}.
+@xref{Business Services Training}.
+
+If you're interested in consulting, please visit the consulting
+section at @uref{http://www.mysql.com/consulting/}. If you have
+restricted access to the Internet, please contact the @code{MySQL AB}
+consulting staff at @email{consulting@@mysql.com}.
+@xref{Business Services Consulting}.
+
+Commercial licenses may be purchased online at
+@uref{https://order.mysql.com/}. There you will also find information
+on how to fax your purchase order to @code{MySQL AB}. If you have
+questions regarding licensing or you want a quote for a high-volume
+license deal, please fill in the contact form on our web site
+(@uref{http://www.mysql.com/}) or send an e-mail message
+to @email{licensing@@mysql.com} (for licensing questions) or to
+@email{sales@@mysql.com} (for sales inquiries).
+@xref{MySQL licenses}.
-@item @uref{http://www2.rent-a-database.de/mysql/}
-MySQL handbook in German.
+If you represent a business that is interested in partnering with
+@code{MySQL AB}, please send e-mail to @email{partner@@mysql.com}.
+@xref{Business Services Partnering}.
+
+If you are interested in placing a banner advertisement on the
+@code{MySQL} web site (@uref{http://www.mysql.com/}), please send
+e-mail to @email{advertising@@mysql.com}.
+@xref{Business Services Advertising}.
+
+For more information on the @code{MySQL} trademark policy, refer to
+@uref{http://www.mysql.com/company/trademark.html} or send e-mail to
+@email{trademark@@mysql.com}.
+@xref{MySQL AB Logos and Trademarks}.
+
+If you are interested in any of the @code{MySQL AB} jobs listed in our
+jobs section (@uref{http://www.mysql.com/development/jobs/}),
+please send an e-mail message to @email{jobs@@mysql.com}.
+Please do not send your CV as an attachment, but rather as plain text
+at the end of your e-mail message.
+
+For general discussion among our many users, please direct your
+attention to the appropriate mailing list.
+@xref{Questions}.
+
+Reports of errors (often called bugs), as well as questions and
+comments, should be sent to the mailing list at
+@email{mysql@@lists.mysql.com}. If you have found a sensitive
+security bug in the @code{MySQL Server}, please send an e-mail
+to @email{security@@mysql.com}.
+@xref{Bug reports}.
-@item @uref{http://www.bitmover.com:8888//home/bk/mysql}
-Web access to the MySQL BitKeeper repository.
+If you have benchmark results that we can publish, please
+contact us at @email{benchmarks@@mysql.com}.
-@item @uref{http://www.analysisandsolutions.com/code/mybasic.htm}
-Beginners MySQL Tutorial on how to install and set up
-MySQL on a Windows machine.
+If you have any suggestions concerning additions or corrections to this
+manual, please send them to the manual team at @email{docs@@mysql.com}.
-@item @uref{http://www.devshed.com/Server_Side/MySQL/}
-A lot of MySQL tutorials.
+For questions or comments about the workings or content of the
+@code{MySQL} web site (@uref{http://www.mysql.com/}),
+please send e-mail to @email{webmaster@@mysql.com}.
-@item @uref{http://mysql.hitstar.com/}
-MySQL manual in Chinese.
+Questions about the @code{MySQL Portals}
+(@uref{http://www.mysql.com/portal/})
+may be sent to @email{portals@@mysql.com}.
-@item @uref{http://www.linuxplanet.com/linuxplanet/tutorials/1046/1/}
-Setting Up a MySQL-based Web site.
+@code{MySQL AB} has a privacy policy, which can be read at
+@uref{http://www.mysql.com/company/privacy.html}.
+For any queries regarding this policy, please e-mail
+@email{privacy@@mysql.com}.
-@item @uref{http://www.hotwired.com/webmonkey/backend/tutorials/tutorial1.html}
-MySQL-Perl tutorial.
+For all other inquires, please send e-mail to @email{info@@mysql.com}.
-@item @uref{http://www.iserver.com/support/contrib/perl5/modules.html}
-Installing new Perl modules that require locally installed modules.
-@item @uref{http://www.hotwired.com/webmonkey/databases/tutorials/tutorial4.html}
-PHP/MySQL Tutorial.
+@node Licensing and Support, MySQL 4.0 In A Nutshell, What is MySQL AB, Introduction
+@section MySQL Support and Licensing
-@item @uref{http://www.useractive.com/}
-Hands on tutorial for MySQL.
-@end table
+@cindex licensing terms
+@cindex support terms
-@subheading Porting MySQL/Using MySQL on Different Systems
+This section describes @code{MySQL} support and licensing arrangements.
-@table @asis
-@item @uref{http://www.entropy.ch/software/macosx/mysql/}
-Binary of MySQL for Mac OS X Client. Includes information of how to
-build and use MySQL on Mac OS X.
+@menu
+* Support:: Support Offered by MySQL AB
+* Copyright:: Copyrights and Licenses Used by MySQL
+* MySQL licenses:: MySQL Licenses
+* MySQL AB Logos and Trademarks:: MySQL AB Logos and Trademarks
+@end menu
-@item @uref{http://xclave.macnn.com/MySQL/}
-The Mac OS Xclave. Running MySQL on Mac OS X.
-@item @uref{http://www.prnet.de/RegEx/mysql.html}
-MySQL for Mac OS X Server.
+@node Support, Copyright, Licensing and Support, Licensing and Support
+@subsection Support Offered by MySQL AB
-@item @uref{http://www.latencyzero.com/macosx/mysql.html}
-Building MySQL for Mac OS X.
+@cindex support, types
+@cindex types of support
+@cindex commercial support, types
+@cindex costs, support
+@cindex licensing costs
+@cindex support costs
+@cindex prices, support
+
+Technical support from @code{MySQL AB} means individualised answers
+to your unique problems direct from the software engineers who code
+the @code{MySQL} database engine.
+
+We try to take a broad and inclusive view of technical support. Almost
+any problem involving @code{MySQL} software is important to us if it's
+important to you.
+Typically customers seek help on how to get different commands and
+utilities to work, remove performance bottlenecks, restore crashed
+systems, understand operating system or networking impacts on @code{MySQL},
+set up best practices for backup and recovery, utilise @code{API}s, etc.
+Our support covers only the @code{MySQL} server and our own utilities,
+not third-party products that access the @code{MySQL} server, though we
+try to help with these where we can.
+
+Detailed information about our various support options is given at
+@uref{https://order.mysql.com/}, where support contracts can also be
+ordered online. If you have restricted access to the Internet, contact
+our sales staff at @email{sales@@mysql.com}.
+
+Technical support is like life insurance. You can live happily
+without it for years, but when your hour arrives it becomes
+critically important, yet it's too late to buy it!
+If you use @code{MySQL} Server for important applications and encounter
+sudden troubles, it might take too long to figure out all the answers
+yourself. You may need immediate access to the most experienced
+@code{MySQL} troubleshooters available, those employed by @code{MySQL AB}.
+
+
+@node Copyright, MySQL licenses, Support, Licensing and Support
+@subsection Copyrights and Licenses Used by MySQL
-@item @uref{http://www.essencesw.com/Software/mysqllib.html}
-New Client libraries for the Mac OS Classic (Macintosh).
+@cindex copyrights
+@cindex licenses
-@item @uref{http://www.lilback.com/macsql/}
-Client libraries for Mac OS Classic (Macintosh).
+@code{MySQL AB} owns the copyright to the @code{MySQL} source code,
+the @code{MySQL} logos and trademarks and this manual.
+@xref{What is MySQL AB}.
+Several different licenses are relevant to the @code{MySQL}
+distribution:
-@item @uref{http://sixk.maniasys.com/index_en.html}
-MySQL for Amiga
-@end table
+@enumerate
+@item
+All the @code{MySQL}-specific source in the server, the @code{mysqlclient}
+library and the client, as well as the @code{GNU} @code{readline} library
+is covered by the @code{GNU General Public License}.
+@xref{GPL license}.
+The text of this license can also be found as the file @file{COPYING}
+in the distributions.
-@subheading Perl-related Links
+@item
+The @code{GNU} @code{getopt} library is covered by the
+@code{GNU Lesser General Public License}.
+@xref{LGPL license}.
-@table @asis
-@item @uref{http://dbimysql.photoflux.com/}
-Perl DBI with MySQL FAQ.
-@end table
+@item
+Some parts of the source (the @code{regexp} library) are covered
+by a Berkeley-style copyright.
-@subheading MySQL Discussion Forums
+@item
+Older versions of @code{MySQL} (3.22 and earlier) are subject to a
+more strict license
+(@uref{http://www.mysql.com/support/arrangements/mypl.html}).
+See the documentation of the specific version for information.
-@table @asis
-@item @uref{http://www.weberdev.com/}
-Examples using MySQL; (check Top 20)
+@item
+The manual is currently @strong{not} distributed under a @code{GPL}-style license.
+Use of the manual is subject to the following terms:
+@itemize @bullet
+@item
+Conversion to other formats is allowed, but the actual content
+may not be altered or edited in any way.
+@item
+You may create a printed copy for your own personal use.
+@item
+For all other uses, such as selling printed copies or using
+(parts of) the manual in another publication, prior written
+agreement from @code{MySQL AB} is required.
+@end itemize
+Please e-mail @email{docs@@mysql.com} for more information or
+if you are interested in doing a translation.
+@end enumerate
-@item @uref{http://futurerealm.com/forum/futureforum.htm}
-FutureForum Web Discussion Software.
-@end table
+For information about how the @code{MySQL} licenses work in practice,
+please refer to @ref{MySQL licenses}.
+Also see @ref{MySQL AB Logos and Trademarks}.
-@c FIX We should get longer descriptions for things in this category!
-@subheading Commercial Applications that Support MySQL
-@table @asis
-@item @uref{http://www.supportwizard.com/}
-SupportWizard; Interactive helpdesk on the Web (This product includes a
-licensed copy of MySQL.)
-
-@item @uref{http://www.sonork.com/}
-Sonork, Instant Messenger that is not only Internet oriented. It's
-focused on private networks and on small to medium companies. Client
-is free, server is free for up to 5 seats.
-
-@item @uref{http://www.stweb.org/}
-StWeb - Stratos Web and Application server - An easy-to-use, cross
-platform, Internet/Intranet development and deployment system for
-development of web-enabled applications. The standard version of StWeb
-has a native interface to MySQL database.
-
-@item @uref{http://www.rightnowtech.com/}
-Right Now Web; Web automation for customer service.
-
-@item @uref{http://www.icaap.org/Bazaar/}
-Bazaar; Interactive Discussion Forums with Web interface.
-
-@cindex PhoneSweep
-@item @uref{http://www.phonesweep.com/}
-PhoneSweepT is the world's first commercial Telephone Scanner. Many break-ins
-in recent years have come not through the Internet, but through unauthorized
-dial-up modems. PhoneSweep lets you find these modems by repeatedly placing
-phone calls to every phone number that your organization
-controls. PhoneSweep has a built-in expert system that can recognize
-more than 250 different kinds of remote-access programs, including
-Carbon Copy(TM), pcANYWHERE(TM), and Windows NT RAS. All information is stored
-in the SQL database. It then generates a comprehensive report detailing
-which services were discovered on which dial-up numbers in your organization.
-@end table
+@node MySQL licenses, MySQL AB Logos and Trademarks, Copyright, Licensing and Support
+@subsection MySQL Licenses
-@subheading SQL Clients and Report Writers
+@cindex licensing policy
+@cindex technical support, licensing
+@cindex support, licensing
+@cindex General Public License, MySQL
+@cindex GPL, MySQL
+@cindex licensing, examples
+@cindex selling products
+@cindex products, selling
-@table @asis
-@item @uref{http://www.urbanresearch.com/software/utils/urbsql/index.html, urSQL}
-SQL Editor and Query Utility. Custom syntax highlighting, editable
-results grid, exportable result-sets, basic MySQL admin functions,
-Etc.. For Windows.
+The @code{MySQL} software is released under the
+@code{GNU General Public License} (@code{GPL}),
+which probably is the best known @code{Open Source} license.
+The formal terms of the @code{GPL} license can be found at
+@uref{http://www.gnu.org/licenses/}.
+See also @uref{http://www.gnu.org/licenses/gpl-faq.html} and
+@uref{http://www.gnu.org/philosophy/enforcing-gpl.html}.
+
+Since the @code{MySQL} software is released under the @code{GPL},
+it may often be used for free, but for certain uses you may want
+or need to buy commercial licenses from @code{MySQL AB} at
+@uref{https://order.mysql.com/}.
-@item @uref{http://www.edatanew.com/, MySQL Data Manager}
-MySQL Data Manager * is platform independent web client
-(written in perl) for MySQL server over TCP/IP.
+Older versions of @code{MySQL} (3.22 and earlier) are subject to a
+more strict license
+(@uref{http://www.mysql.com/support/arrangements/mypl.html}).
+See the documentation of the specific version for information.
-@item @uref{http://ksql.sourceforge.net/}
-KDE MySQL client.
+Please note that the use of the @code{MySQL} software under commercial
+license, @code{GPL}, or the old @code{MySQL} license does not
+automatically give you the right to use @code{MySQL AB} trademarks.
+@xref{MySQL AB Logos and Trademarks}.
-@item @uref{http://www.ecker-software.de}
-A Windows GUI client by David Ecker.
-@item @uref{http://www.icaap.org/software/kiosk/}
-Kiosk; a MySQL client for database management. Written in Perl.
-Will be a part of Bazaar.
+@menu
+* Using the MySQL software under a commercial license:: Using the MySQL Software Under a Commercial License
+* Using the MySQL software for free under GPL:: Using the MySQL Software for Free Under GPL
+@end menu
-@item @uref{http://www.casestudio.com/}
-Db design tool that supports MySQL 3.23.
+@node Using the MySQL software under a commercial license, Using the MySQL software for free under GPL, MySQL licenses, MySQL licenses
+@subsubsection Using the MySQL Software Under a Commercial License
-@item @uref{http://home.skif.net/~voland/zeos/eng/index.html}
-Zeos - A client that supports MySQL, Interbase and PostgreSQL.
+The @code{GPL} license is contagious in the sense that when a program
+is linked to a @code{GPL} program the resulting product must also be
+released under @code{GPL} lest you break the license terms and forfeit
+your right to use the @code{GPL} program altogether.
-@item @uref{http://www.geocities.com/SiliconValley/Ridge/4280/GenericReportWriter/grwhome.html}
-A free report writer in Java
+You need a commercial license:
-@item @uref{http://www.javaframework.de}
-MySQLExport - Export of MySQL create statements and data in a lot of
-different formats (SQL, HTML, CVS, text, ZIP, GZIP...)
+@itemize @bullet
+@item
+When you link a program with code from the @code{MySQL} software or from
+@code{GPL} released clients and don't want the resulting product to be
+@code{GPL}, maybe because you want to build a commercial product or keep
+the added non-@code{GPL} code closed source for other reasons. When
+purchasing commercial licenses, you are not using the @code{MySQL} software
+under @code{GPL} even though it's the same code.
-@item @uref{http://dlabs.4t2.com}
-M2D, a MySQL Administration client for Windows. M2D supports
-administration of MySQL databases, creation of new databases and
-tables, editing, and more.
+@item
+When you distribute a non-@code{GPL} application that @strong{only} works with the
+@code{MySQL} software and ship it with the @code{MySQL} software. This type
+of solution is actually considered to be linking even if it's done over
+a network.
-@item @uref{http://dlabs.4t2.com}
-Dexter, a small server written in Perl which can be used as a proxy server for
-MySQL or as a database extender.
+@item
+When you distribute copies of the @code{MySQL} software without providing
+the source code as required under the @code{GPL} license.
-@item @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp}
-Mascon is a powerful Win32 GUI for administering MySQL databases.
+@item
+When you want to support the further development of the @code{MySQL}
+database even if you don't formally need a commercial license.
+Purchasing support directly from @code{MySQL AB} is another good way
+of contributing to the development of the @code{MySQL} software, with
+immediate advantages for you.
+@xref{Support}.
+@end itemize
-@item @uref{http://www.rtlabs.com/}
-MacSQL Monitor. GUI for MySQL, ODBC, and JDBC databases for the Mac OS.
-@end table
+If you require a license, you will need one for each installation of the
+@code{MySQL} software. This covers any number of CPUs on a machine, and there
+is no artificial limit on the number of clients that connect to the server
+in any way.
-@subheading Distributions that Include MySQL
+To purchase commercial licenses and support, please visit the order section
+of our web site at @uref{https://order.mysql.com/}. If you have special
+licensing needs or you have restricted access to the Internet, please contact
+our sales staff at @email{sales@@mysql.com}.
-@c FIX add the rest (at least a couple more Linuxes)
-@table @asis
-@item @uref{http://www.suse.com/}
-SuSE Linux (6.1 and above)
+@node Using the MySQL software for free under GPL, , Using the MySQL software under a commercial license, MySQL licenses
+@subsubsection Using the MySQL Software for Free Under GPL
-@item @uref{http://www.redhat.com/}
-RedHat Linux (7.0 and above)
+@cindex licensing, free
+@cindex free licensing
-@item @uref{http://distro.conectiva.com.br}
-Conectiva Linux (4.0 and above)
-@end table
+You can use the @code{MySQL} software for free under the @code{GPL}:
-@subheading Web Development Tools that Support MySQL
+@itemize @bullet
+@item
+When you link a program with code from the @code{MySQL} software and
+release the resulting product under @code{GPL}.
-@table @asis
-@item @uref{http://www.php.net/}
-PHP: A server-side HTML-embedded scripting language.
+@item
+When you distribute the @code{MySQL} source code bundled with
+other programs that are not linked to or dependent on @code{MySQL Server}
+for their functionality even if you sell the distribution commercially.
-@item @uref{http://www.midgard-project.org}
-The Midgard Application Server; a powerful Web development environment
-based on MySQL and PHP.
+@item
+When using the @code{MySQL} software internally in your company.
-@item @uref{http://www.smartworker.org}
-SmartWorker is a platform for Web application development.
+@item
+@cindex ISP services
+@cindex services, ISP
+@cindex services, web
+@cindex Internet Service Providers
+When you are an Internet Service Provider (ISPs) offering web
+hosting with @code{MySQL} servers for your customers.
+On the other hand, we do encourage people to use ISPs that have
+@code{MySQL} support, as this will give them the confidence that if
+they have some problem with the @code{MySQL} installation, their ISP
+will in fact have the resources to solve the problem for them.
-@item @uref{http://xsp.lentus.se/}
-XSP: e(X)tendible (S)erver (P)ages and is a HTML embedded tag language
-written in Java (previously known as XTAGS.)
+All ISPs that want to keep themselves up-to-date should subscribe
+to our @code{announce} mailing list so that they can be aware of
+critical issues that may be relevant for their @code{MySQL} installations.
-@cindex dbServ
-@item @uref{http://www.dbServ.de/}
-dbServ is an extension to a web server to integrate database output into
-your HTML code. You may use any HTML function in your output. Only the
-client will stop you. It works as standalone server or as Java servlet.
+Note that even if an ISP does not have a commercial license for
+@code{MySQL Server}, they should at least give their customers read
+access to the source of the @code{MySQL} installation so that the
+customers can verify that it is patched correctly.
-@item @uref{http://www.chilisoft.com/}
-Platform independent ASP from Chili!Soft
+@item
+@cindex web server, running
+@cindex running a web server
+When you use the @code{MySQL} Database Software in conjunction with
+a web server, you do not need a commercial license. This is true even
+if you run a commercial web server that uses @code{MySQL Server}, because
+you are not selling an embedded @code{MySQL} version yourself. However,
+in this case we would like you to purchase @code{MySQL} support because
+the @code{MySQL} software is helping your enterprise.
+@end itemize
+
+If your use of @code{MySQL} database software does not require a commercial
+license, we encourage you to purchase support from @code{MySQL AB} anyway.
+This way you contribute toward @code{MySQL} development and also gain
+immediate advantages for yourself. @xref{Support}.
+
+If you use the @code{MySQL} database software in a commercial context
+such that you profit by its use, we ask that you further the development
+of the @code{MySQL} software by purchasing some level of support. We feel
+that if the @code{MySQL} database helps your business, it is reasonable to
+ask that you help @code{MySQL AB}.
+(Otherwise, if you ask us support questions, you are not only using
+for free something into which we've put a lot a work, you're asking
+us to provide free support, too.)
+
+
+@node MySQL AB Logos and Trademarks, , MySQL licenses, Licensing and Support
+@subsection MySQL AB Logos and Trademarks
+
+@cindex logos
+@cindex trademarks
+
+Many users of the @code{MySQL} database want to display the
+@code{MySQL AB} dolphin logo on their web sites, books, or
+boxed products. We welcome and encourage this, although it should be
+noted that the word @code{MySQL} and the @code{MySQL} dolphin logo
+are trademarks of @code{MySQL AB} and may only be used as stated in
+our trademark policy at
+@uref{http://www.mysql.com/company/trademark.html}.
-@item @uref{http://www.voicenet.com/~zellert/tjFM}
-A JDBC driver for MySQL.
+@menu
+* The Original MySQL logo:: The Original MySQL Logo
+* MySQL Logos that may be Used Without Written Permission:: MySQL Logos that may be Used Without Written Permission
+* When need MySQL logo permission:: When do you need a Written Permission to use MySQL Logos?
+* MySQL AB Partnership Logos:: MySQL AB Partnership Logos
+* Using MySQL word in presentations:: Using the word @code{MySQL} in Printed Text or Presentations
+* Using MySQL word in company and product names:: Using the word @code{MySQL} in Company and Product Names
+@end menu
-@item @uref{http://www.wernhart.priv.at/php/}
-MySQL + PHP demos.
-@item @uref{http://www.dbwww.com/}
-ForwardSQL: HTML interface to manipulate MySQL databases.
+@node The Original MySQL logo, MySQL Logos that may be Used Without Written Permission, MySQL AB Logos and Trademarks, MySQL AB Logos and Trademarks
+@subsubsection The Original MySQL Logo
-@item @uref{http://www.daa.com.au/~james/www-sql/}
-WWW-SQL: Display database information.
+@c FIX: picture: MySQL logo
-@item @uref{http://www.minivend.com/minivend/}
-Minivend: A Web shopping cart.
+The @code{MySQL} dolphin logo was designed by the Finnish advertising
+agency Priority in 2001. The dolphin was chosen as a suitable symbol
+for the @code{MySQL} database since it is a smart, fast, and lean animal,
+effortlessly navigating oceans of data. We also happen to like dolphins.
-@item @uref{http://www.heitml.com/}
-HeiTML: A server-side extension of HTML and a 4GL language at the same time.
+The original @code{MySQL} logo may only be used by representatives of
+@code{MySQL AB} and by those having a written agreement allowing them
+to do so.
-@item @uref{http://www.metahtml.com/}
-Metahtml: A Dynamic Programming Language for WWW Applications.
-@item @uref{http://www.binevolve.com/}
-VelocityGen for Perl and Tcl.
+@node MySQL Logos that may be Used Without Written Permission, When need MySQL logo permission, The Original MySQL logo, MySQL AB Logos and Trademarks
+@subsubsection MySQL Logos that may be Used Without Written Permission
-@item @uref{http://hawkeye.net/}
-Hawkeye Internet Server Suite.
+@c FIX: pictures: powered by, works with, included - logos
-@item @uref{http://www.fastflow.com/}
-Network Database Connection For Linux
+We have designed a set of special @emph{Conditional Use} logos that may be
+downloaded from our web site at
+@uref{http://www.mysql.com/downloads/logos.html}
+and used on third-party web sites without written permission from
+@code{MySQL AB}.
+The use of these logos is not entirely unrestricted but, as the name
+implies, subject to our trademark policy that is also available on our
+web site. You should read through the trademark policy if you plan to
+use them. The requirements are basically:
-@item @uref{http://www.wdbi.net/}
-WDBI: Web browser as a universal front end to databases which supports
-MySQL well.
+@itemize @bullet
+@item
+Use the logo you need as displayed on the @uref{http://www.mysql.com/}
+site. You may scale it to fit your needs, but not change colours or design,
+or alter the graphics in any way.
-@item @uref{http://www.webgroove.com/}
-WebGroove Script: HTML compiler and server-side scripting language.
+@item
+Make it evident that you, and not @code{MySQL AB}, are the creator and
+owner of the site that displays the @code{MySQL} trademark.
-@item @uref{http://www.ihtml.com/}
-A server-side Web site scripting language.
+@item
+Don't use the trademark in a way that is detrimental to @code{MySQL AB}
+or to the value of @code{MySQL AB} trademarks. We reserve the right to
+revoke the right to use the @code{MySQL AB} trademark.
-@item @uref{ftp://ftp.igc.apc.org/pub/myodbc/README}
-How to use MySQL with ColdFusion on Solaris.
+@item
+If you use the trademark on a web site, make it clickable, leading directly
+to @uref{http://www.mysql.com/}.
-@item @uref{http://calistra.com/MySQL/}
-Calistra's ODBC MySQL Administrator.
+@item
+If you are using the @code{MySQL} database under @code{GPL} in an
+application, your application must be @code{Open Source} and
+be able to connect to a @code{MySQL} server.
+@end itemize
-@cindex Webmerger
-@item @uref{http://www.webmerger.com}
-Webmerger - This CGI tool interprets files and generates dynamic output
-based on a set of simple tags. Ready-to-run drivers for MySQL and
-PostgreSQL through ODBC.
+Contact us at @email{trademark@@mysql.com} to inquire about special
+arrangements to fit your needs.
-@item @uref{http://phpclub.net/}
-PHPclub - Tips and tricks for PHP.
+@node When need MySQL logo permission, MySQL AB Partnership Logos, MySQL Logos that may be Used Without Written Permission, MySQL AB Logos and Trademarks
+@subsubsection When do you need a Written Permission to use MySQL Logos?
-@item @uref{http://www.penguinservices.com/scripts}
-MySQL and Perl Scripts.
+In the following cases you need a written permission from @code{MySQL AB}
+before using @code{MySQL} logos:
-@item @uref{http://www.widgetchuck.com}
-The Widgetchuck; Web Site Tools and Gadgets
+@itemize @bullet
+@item
+When displaying any @code{MySQL AB} logo anywhere except on your web site.
-@item @uref{http://www.adcycle.com/}
-AdCycle - advertising management software.
+@item
+When displaying any @code{MySQL AB} logo except the @emph{Conditional Use}
+logos mentioned previously on web sites or elsewhere.
+@end itemize
-@cindex pwPage
-@item @uref{http://sourceforge.net/projects/pwpage/}
-pwPage - provides an extremely fast and simple approach to the creation
-of database forms. That is, if a database table exists and an HTML page
-has been constructed using a few simple guidelines, pwPage can be
-immediately used for table data selections, insertions, updates, deletions
-and selectable table content reviewing.
+Out of legal and commercial reasons we have to monitor the use of MySQL
+trademarks on products, books, etc. We will usually require a fee for
+displaying @code{MySQL AB} logos on commercial products, since we think
+it is reasonable that some of the revenue is returned to fund further
+development of the @code{MySQL} database.
-@item @uref{http://www.omnis-software.com/products/studio/studio.html}
-OMNIS Studio is a rapid application development (RAD) tool.
-@cindex Web+
-@item @uref{http://www.webplus.com}
-talentsoft Web+ 4.6 - a powerful and comprehensive development language for
-use in creating web-based client/server applications without writing
-complicated, low-level, and time-consuming CGI programs.
-@end table
+@node MySQL AB Partnership Logos, Using MySQL word in presentations, When need MySQL logo permission, MySQL AB Logos and Trademarks
+@subsubsection MySQL AB Partnership Logos
-@subheading Database Design Tools with MySQL Support
+@c FIX: pictures: partnership logos - Bertrand?
-@table @asis
-@item @uref{http://www.mysql.com/documentation/dezign/}
-"DeZign for databases" is a database development tool that uses an
-entity relationship diagram (ERD).
-@end table
+@code{MySQL} partnership logos may only be used by companies and persons
+having a written partnership agreement with @code{MySQL AB}. Partnerships
+include certification as a @code{MySQL} trainer or consultant.
+Please see @ref{Business Services Partnering,,Partnering}.
-@subheading Web Servers with MySQL Tools
-@table @asis
-@item @uref{ftp://ftp.kcilink.com/pub/}
-mod_auth_mysql, An Apache authentication module.
+@node Using MySQL word in presentations, Using MySQL word in company and product names, MySQL AB Partnership Logos, MySQL AB Logos and Trademarks
+@subsubsection Using the word @code{MySQL} in Printed Text or Presentations
-@item @uref{http://www.roxen.com/}
-The Roxen Challenger Web server.
-@end table
+@code{MySQL AB} welcomes references to the @code{MySQL} database, but
+note that the word @code{MySQL} is a trademark of @code{MySQL AB}.
+Because of this, you should append the trademark symbol (@code{TM}) to
+the first or most prominent use of the word @code{MySQL} in a text and
+where appropriate, state that @code{MySQL} is a trademark of
+@code{MySQL AB}. Please refer to our trademark policy at
+@uref{http://www.mysql.com/company/trademark.html} for details.
-@subheading Extensions for Other Programs
-@table @asis
-@item @uref{http://www.seawood.org/msql_bind/}
-MySQL support for BIND (The Internet Domain Name Server).
+@node Using MySQL word in company and product names, , Using MySQL word in presentations, MySQL AB Logos and Trademarks
+@subsubsection Using the word @code{MySQL} in Company and Product Names
-@item @uref{http://www.inet-interactive.com/sendmail/}
-MySQL support for Sendmail and Procmail.
-@end table
+Use of the word @code{MySQL} in product or company names or in Internet
+domain names is not allowed without written permission from @code{MySQL AB}.
-@subheading Using MySQL with Other Programs
-@table @asis
-@item @uref{http://www.iserver.com/support/addonhelp/database/mysql/msaccess.html}
-Using MySQL with Access.
+@node MySQL 4.0 In A Nutshell, MySQL Information Sources, Licensing and Support, Introduction
+@section MySQL 4.0 In A Nutshell
-@item @uref{http://www.iserver.com/support/contrib/perl5/modules.html}
-Installing new Perl modules that require locally installed modules.
-@end table
+Dateline: 16 October 2001, Uppsala, Sweden
-@subheading ODBC-related Links
+Long promised by @code{MySQL AB} and long awaited by our users,
+MySQL Server 4.0 is now available in beta version for download from
+@uref{http://www.mysql.com/} and our mirrors.
-@table @asis
-@item @uref{http://www.iodbc.org/}
-Popular iODBC Driver Manager (libiodbc) now available as Open Source.
+Main new features of MySQL Server 4.0 are geared toward our existing
+business and community users, enhancing the MySQL database software
+as the solution for mission-critical, heavy-load database systems.
+Other new features target the users of embedded databases.
-@item @uref{http://users.ids.net/~bjepson/freeODBC/}
-The FreeODBC Pages.
+@menu
+* Nutshell Stepwise Rollout:: Stepwise Rollout
+* Nutshell Ready for Immediate Development Use:: Ready for Immediate Development Use
+* Nutshell Embedded MySQL:: Embedded MySQL
+* Nutshell Other features:: Other Features Available From MySQL 4.0.0
+* Nutshell Future features:: Future MySQL 4.0 Features
+* Nutshell 4.1 development release:: MySQL 4.1, The Following Development Release
+@end menu
-@item @uref{http://genix.net/unixODBC/}
-The unixODBC Project goals are to develop and promote unixODBC to be the
-definitive standard for ODBC on the Linux platform. This is to include GUI
-support for KDE.
-@item @uref{http://www.sw-soft.com/products/BtrieveODBC/}
-A MySQL-based ODBC driver for Btrieve.
-@end table
+@node Nutshell Stepwise Rollout, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell, MySQL 4.0 In A Nutshell
+@subsection Stepwise Rollout
-@subheading @strong{API}-related Links
+The rollout of MySQL Server 4.0 will come in several steps, with
+the first version labelled 4.0.0 already containing most of the
+new features. Additional features will be incorporated into
+MySQL 4.0.1, 4.0.2, and onward; very probably within a couple of months,
+MySQL 4.0 will be labelled beta. Further new features will then
+be added in MySQL 4.1, which is targeted for alpha release
+in third quarter 2002.
-@table @asis
-@item @uref{http://www.jppp.com/}
-Partially implemented TDataset-compatible components for MySQL.
-@item @uref{http://www.riverstyx.net/qpopmysql/}
-qpopmysql - A patch to allow POP3 authentication from a MySQL
-database. There's also a link to Paul Khavkine's patch for Procmail to
-allow any MTA to deliver to users in a MySQL database.
+@node Nutshell Ready for Immediate Development Use, Nutshell Embedded MySQL, Nutshell Stepwise Rollout, MySQL 4.0 In A Nutshell
+@subsection Ready for Immediate Development Use
-@item @uref{http://www.pbc.ottawa.on.ca}
-Visual Basic class generator for Active X.
+Users are not recommended to switch their production systems
+to MySQL Server 4.0 until it is released in beta version.
+However, even the initial release has passed our extensive
+test suite without any errors on any of the platforms we test on.
+Due to the large number of new features, we thus recommend
+MySQL Server 4.0 even in alpha form for development use, with
+the release schedule of MySQL Server 4.0 being such that it will
+reach stable state before the deployment of user applications
+now under development.
-@item @uref{http://www.essencesw.com/Software/mysqllib.html}
-New Client libraries for the Mac OS Classic (Macintosh).
-@item @uref{http://www.lilback.com/macsql/}
-Client libraries for the Macintosh.
+@node Nutshell Embedded MySQL, Nutshell Other features, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell
+@subsection Embedded MySQL
-@item @uref{http://www.essencesw.com/Plugins/mysqlplug.html}
-Plugin for REALbasic (for Macintosh)
+@code{libmysqld} makes MySQL Server suitable for a vastly expanded realm of
+applications. Using the embedded MySQL server library, one can
+embed MySQL Server into various applications and electronics devices, where
+the end user has no knowledge of there actually being an underlying
+database. Embedded MySQL Server is ideal for use behind
+the scenes in internet appliances, public kiosks, turnkey
+hardware/software combination units, high performance internet
+servers, self-contained databases distributed on CD-ROM, etc.
-@item @uref{http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html}
-A library that emulates BSD sockets and pthreads on Macintosh. This can
-be used if you want to compile the MySQL client library on Mac.
-It could probably even be sued to port MySQL to Macintosh, but we
-don't know of anyone that has tried that.
+Many users of @code{libmysqld} will benefit from the MySQL
+@emph{Dual Licensing}. For those not wishing to be bound by the GPL,
+the software is also made available under a commercial license.
+The embedded MySQL library uses the same interface as the normal
+client library, so it is convenient and easy to use. @xref{libmysqld}.
-@cindex SCMDB
-@item @uref{http://www.dedecker.net/jessie/scmdb/}
-SCMDB - an add-on for SCM that ports the MySQL C library to scheme
-(SCM). With this library scheme developers can make connections to a
-MySQL database and use embedded SQL in their programs.
-@end table
-@subheading Other MySQL-related Links
+@node Nutshell Other features, Nutshell Future features, Nutshell Embedded MySQL, MySQL 4.0 In A Nutshell
+@subsection Other Features Available From MySQL 4.0.0
-@table @asis
-@item @uref{http://www.satisoft.com/, SAT}
-The Small Application Toolkit (SAT) is a collection of utilities
-intended to simplify the development of small, multi-user, GUI based
-applications in a (Microsoft -or- X) Windows Client / Unix Server
-environment.
+@itemize @bullet
+@item
+Version 4.0 further increases @emph{the speed of MySQL Server}
+in a number of areas,
+such as bulk @code{INSERT}s, searching on packed indexes, creation of
+@code{FULLTEXT} indexes, as well as @code{COUNT(DISTINCT)}.
-@item @uref{http://www.wix.com/mysql-hosting/}
-Registry of Web providers who support MySQL.
+@item
+The table handler @code{InnoDB} is now offered as a feature of the
+standard MySQL server, including full support for @code{transactions}
+and @code{row-level locking}.
-@item @uref{http://www.softagency.co.jp/mysql/index.en.html}
-Links about using MySQL in Japan/Asia.
+@item
+MySQL Server 4.0 will support secure traffic between the client and the server,
+greatly increasing security against malicious intrusion and unauthorised
+access. Web applications being a cornerstone of MySQL use, web developers
+have been able to use @code{Secure Socket Layer} (@code{SSL}) to secure the
+traffic between the the end user browser and the web application, be it
+written in PHP, Perl, ASP or using any other web development tool. However,
+the traffic between the development tool and the @code{mysqld} server
+process has been protected only by virtue of them being processes
+residing on computers within the same firewall. In MySQL Server 4.0,
+the @code{mysqld} server daemon process can itself use @code{SSL},
+thus enabling secure traffic to MySQL databases from, say, a Windows
+application residing outside the firewall.
-@item @uref{http://abattoir.cc.ndsu.nodak.edu/~nem/mysql/udf/}
-MySQL UDF Registry.
+@item
+Our German, Austrian, and Swiss users will note that we have a new character
+set, @code{latin_de}, which corrects the @emph{German sorting order},
+placing German umlauts in the same order as German telephone books.
-@item @uref{http://www.open.com.au/products.html}
-Commercial Web defect tracking system.
+@item
+Features to simplify migration from other database systems to MySQL
+Server include @code{TRUNCATE TABLE} (like in Oracle) and @code{IDENTITY} as a
+synonym for automatically incremented keys (like in Sybase). Many users will
+also be happy to learn that MySQL Server now supports the @code{UNION} statement,
+a long-awaited standard SQL feature.
-@item @uref{http://www.stonekeep.com/pts/}
-PTS: Project Tracking System.
+@item
+In the process of building features for new users, we have not forgotten
+requests by the community of loyal users.
+We have multi-table @code{DELETE} statements.
+By adding support for @code{symbolic linking} to @code{MyISAM} on the table
+level (and not just the database level as before), as well as by enabling symlink
+handling by default on Windows, we hope to show that we take enhancement
+requests seriously.
+Functions like @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()} make it
+possible to know how many rows a query would have returned without a
+@code{LIMIT} clause.
+@end itemize
-@item @uref{http://tomato.nvgc.vt.edu/~hroberts/mot}
-Job and software tracking system.
-@item @uref{http://www.cynergi.net/exportsql/}
-ExportSQL: A script to export data from Access95+.
+@node Nutshell Future features, Nutshell 4.1 development release, Nutshell Other features, MySQL 4.0 In A Nutshell
+@subsection Future MySQL 4.0 Features
-@item @uref{http://SAL.KachinaTech.COM/H/1/MYSQL.html}
-SAL (Scientific Applications on Linux) MySQL entry.
+For the upcoming MySQL Server 4.x releases,
+expect the following features now still under development:
-@item @uref{http://www.infotech-nj.com/itech/index.shtml}
-A consulting company which mentions MySQL in the right company.
+@itemize @bullet
+@item
+Mission-critical, heavy-load users of MySQL Server will appreciate
+the additions to our replication system and our online hot backup.
+Later versions of 4.0 will include @code{fail-safe replication};
+already existing in 4.0.0, the @code{LOAD DATA FROM MASTER} command
+will soon automate slave setup. The @code{online backup} will make
+it easy to add a new replication slave without taking down
+the master, and have a very low performance penalty on
+update-heavy systems.
-@item @uref{http://www.pmpcs.com/}
-PMP Computer Solutions. Database developers using MySQL and
-@code{mSQL}.
+@item
+A convenience feature for Database Administrators is that
+@code{mysqld} parameters (startup options) can soon be set without
+taking down the servers.
-@item @uref{http://www.aewa.org/}
-Airborne Early Warning Association.
+@item
+The new @code{FULLTEXT} search properties of MySQL Server 4.0 enable the
+use of @code{FULLTEXT} indexing of large text masses with both binary and
+natural-language searching logic. Users can customise minimal word
+length and define their own stop word lists in any human language,
+enabling a new set of applications to be built on MySQL Server.
-@item @uref{http://www.dedserius.com/y2kmatrix/}
-Y2K tester.
-@end table
+@item
+Many read-heavy applications will benefit from
+further increased speed through the rewritten @code{key cache}.
-@subheading SQL and Database Interfaces
+@item
+Many developers will also be happy to see the @code{MySQL command help}
+in the client.
+@end itemize
-@table @asis
-@item @uref{http://java.sun.com/products/jdbc/}
-The JDBC database access API.
-@item @uref{http://www.gagme.com/mysql}
-Patch for @code{mSQL} Tcl.
+@node Nutshell 4.1 development release, , Nutshell Future features, MySQL 4.0 In A Nutshell
+@subsection MySQL 4.1, The Following Development Release
-@item @uref{http://www.amsoft.ru/easysql/}
-EasySQL: An ODBC-like driver manager.
+Internally, through a new .frm file format for table definitions,
+MySQL Server 4.0 lays the foundation for the new features of
+MySQL Server 4.1 and onward,
+such as @code{nested subqueries}, @code{stored procedures}, and
+@code{foreign key integrity rules}, which form the top of the
+wish list for many of our customers. Along with those, we will
+also include simpler additions, such as
+multi-table @code{UPDATE} statements.
-@item @uref{http://www.lightlink.com/hessling/rexxsql.html}
-A REXX interface to SQL databases.
+After those additions, critics of the MySQL Database Server have
+to be more imaginative
+than ever in pointing out deficiencies in the MySQL Database
+Management System. For long already known for its stability,
+speed, and ease of use, MySQL Server will then match the requirement
+checklist of very demanding buyers.
-@item @uref{http://www.mytcl.cx/}
-Tcl interface based on tcl-sql with many bugfixes.
-@item @uref{http://www.binevolve.com/~tdarugar/tcl-sql/}
-Tcl interface.
+@node MySQL Information Sources, Compatibility, MySQL 4.0 In A Nutshell, Introduction
+@section MySQL Information Sources
-@item @uref{http://www.contrib.andrew.cmu.edu/~shadow/sql.html}
-SQL Reference Page with a lot of interesting links.
+@menu
+* Portals:: MySQL Portals
+* Questions:: MySQL Mailing Lists
+@end menu
-@end table
-@subheading Examples of MySQL Use
+@node Portals, Questions, MySQL Information Sources, MySQL Information Sources
+@subsection MySQL Portals
-@table @asis
-@c Added 990601
-@c EMAIL: thuss@little6.com (Todd Huss)
-@item @uref{http://www.little6.com/about/linux/}
-Little6 Inc., An online contract and job finding site that is powered by
-MySQL, PHP3, and Linux.
-
-@c Added 990521
-@c EMAIL: nh@delec.com (Hillbrecht Nicole)
-@item @uref{http://www.delec.com/is/products/prep/examples/BookShelf/index.html}
-DELECis - A tool that makes it very easy to create an automatically generated
-table documentation. They have used MySQL as an example.
-
-@c Added 990521
-@c EMAIL: info@worldrecords.com (Jim Rota)
-@item @uref{http://www.worldrecords.com}
-World Records - A search engine for information about music that uses
-MySQL and PHP.
-
-@item @uref{http://www.webtechniques.com/archives/1998/01/note/}
-A Contact Database using MySQL and PHP.
-
-@item @uref{http://modems.rosenet.net/mysql/}
-Web based interface and Community Calendar with PHP.
+@cindex MySQL Portals
+@cindex manuals, about MySQL
+@cindex books, about MySQL
+@cindex MySQL Testimonials
+@cindex users, of MySQL
+@cindex news sites
+@cindex search engines, web
+@cindex web search engines
+@cindex online magazines
+@cindex magazines, online
+@cindex web sites
+@cindex services
+@cindex PHP, web sites
+@cindex consultants, list of
+@cindex web pages, miscellaneous
+@cindex @code{Contrib} directory
+@cindex URLs to MySQL information
+@cindex MySQL related information URLs
-@item @uref{http://www.odbsoft.com/cook/sources.htm}
-Perl package to generate html from a SQL table structure and for generating
-SQL statements from an html form.
-
-@item @uref{http://www.gusnet.cx/proj/telsql/}
-Basic telephone database using @code{DBI}/@code{DBD}.
-
-@item @uref{http://tecfa.unige.ch/guides/java/staf2x/ex/jdbc/coffee-break}
-JDBC examples by Daniel K. Schneider.
-
-@item @uref{http://www.spade.com/linux/howto/PostgreSQL-HOWTO-41.html}
-SQL BNF
-
-@item @uref{http://www.ooc.com/}
-Object Oriented Concepts Inc; CORBA applications with examples in source.
-
-@item @uref{http://www.pbc.ottawa.on.ca/}
-DBWiz; Includes an example of how to manage cursors in VB.
-
-@cindex Pluribus
-@item @uref{http://keilor.cs.umass.edu/pluribus/}
-Pluribus is a free search engine that learns to improve
-the quality of its results over time. Pluribus works by recording
-which pages a user prefers among those returned for a query. A user
-votes for a page by selecting it; Pluribus then uses that knowledge
-to improve the quality of the results when someone else submits the
-same (or similar) query. Uses PHP and MySQL.
-
-@c EMAIL: paul@sword.damocles.com (Paul Bannister)
-@item @uref{http://www.stopbit.com/}
-Stopbit - A technology news site using MySQL and PHP.
-
-@item @uref{http://www.linuxsupportline.com/~kalendar/}
-KDE based calendar manager - The calendar manager has both single user
-(file based) and multi-user (MySQL database) support.
-
-@item @uref{http://tim.desert.net/~tim/imger/}
-Example of storing/retrieving images with MySQL and CGI.
-
-@item @uref{http://www.penguinservices.com/scripts}
-Online shopping cart system.
-
-@c Added 990928 from editor@city-gallery.com
-@cindex Old Photo Album
-@item @uref{http://www.city-gallery.com/album/}
-Old Photo Album - The album is a collaborative popular history of photography
-project that generates all pages from data stored in a MySQL
-database. Pages are dynamically generated through a php3 interface to the
-database content. Users contribute images and descriptions. Contributed
-images are stored on the web server to avoid storing them in the database
-as BLOBs. All other information is stored on the shared MySQL server.
-@end table
+The @code{MySQL Portals} (@uref{http://www.mysql.com/portal/})
+represent the ultimate resource to find @code{MySQL AB Partners},
+as well as books, or other @code{MySQL}-related solutions that you
+may be looking for. Items are categorised and rated in order to
+make it easy for you to locate information.
-@subheading General Database Links
+By registering as a user, you will have the ability to comment on and
+rate items presented in portals. You will also receive relevant
+newsletters according to your user profile that you may update at
+any time.
-@table @asis
-@item @uref{http://www.pcslink.com/~ej/dbweb.html}
-Database Jump Site
+Some of the current @code{MySQL Portal} categories include:
-@item @uref{http://black.hole-in-the.net/guy/webdb/}
-Homepage of the webdb-l (Web Databases) mailing list.
+@table @strong
+@item Partners
+Find @code{MySQL AB} partners worldwide.
-@item @uref{http://www.symbolstone.org/technology/perl/DBI/index.html}
-Perl @code{DBI}/@code{DBD} modules homepage.
+@item Books
+Comment on, vote for, and buy books related to @code{MySQL}.
-@item @uref{http://www.student.uni-koeln.de/cygwin/}
-Cygwin tools. Unix on top of Windows.
+@item Development
+Various links to different sites that are using @code{MySQL Server}
+for different purposes, with a description of each site.
+This information can give you an idea of who uses the @code{MySQL}
+database software and how @code{MySQL Server} can fulfill
+requirements.
-@item @uref{http://dbasecentral.com/}
-dbasecentral.com; Development and distribution of powerful and easy-to-use
-database applications and systems.
+Let us know about @emph{your} site or success story, too!
+Visit @uref{http://www.mysql.com/feedback/testimonial.php}.
-@cindex Tek-Tips forums
-@cindex forums, Tek-Tips
-@item @uref{http://www.tek-tips.com/}
-Tek-Tips Forums are 800+ independent peer-to-peer non-commercial support
-forums for Computer Professionals. Features include automatic e-mail
-notification of responses, a links library, and member confidentiality
-guaranteed.
+@item Software
+Find, buy, and download several applications and wrappers that make
+use of the @code{MySQL} server.
-@item @uref{http://www.public.asu.edu/~peterjn/btree/}
-B-Trees: Balanced Tree Data Structures.
+@item Distributions
+From here you can find the various Linux distributions and other
+software packages that contain the @code{MySQL} software.
-@item @uref{http://www.fit.qut.edu.au/~maire/baobab/lecture/sld001.htm}
-A lecture about B-Trees.
+@item Service Providers
+Companies providing @code{MySQL}-related services.
@end table
-There are also many Web pages that use MySQL. @xref{Users}.
-Send any additions to this list to @email{webmaster@@mysql.com}. We now
-require that you show a MySQL logo somewhere if you wish your
-site to be added. It is okay to have it on a ``used tools'' page or
-something similar.
-
-@node Questions, , Useful Links, MySQL Information Sources
+@node Questions, , Portals, MySQL Information Sources
@subsection MySQL Mailing Lists
@cindex reporting, errors
+@cindex errors, reporting
@cindex MySQL mailing lists
@menu
-* Mailing-list:: The MySQL mailing lists
-* Asking questions:: Asking questions or reporting bugs
-* Bug reports:: How to report bugs or problems
-* Answering questions:: Guidelines for answering questions on the mailing list
+* Mailing-list:: The MySQL Mailing Lists
+* Asking questions:: Asking Questions or Reporting Bugs
+* Bug reports:: How to Report Bugs or Problems
+* Answering questions:: Guidelines for Answering Questions on the Mailing List
@end menu
This section introduces you to the MySQL mailing lists, and gives
-some guidelines as to how to use them.
+some guidelines as to how to use them. By subscribing to a mailing
+list, you will receive as e-mail messages all other postings on the list,
+and you will be able to send in your own questions and answers.
@node Mailing-list, Asking questions, Questions, Questions
@subsubsection The MySQL Mailing Lists
@cindex mailing lists
-@cindex email lists
+@cindex e-mail lists
To subscribe to the main MySQL mailing list, send a message to the
electronic mail address @email{mysql-subscribe@@lists.mysql.com}.
@@ -2136,10 +1990,10 @@ the electronic mail address @email{mysql-unsubscribe@@lists.mysql.com}.
Only the address to which you send your messages is significant. The
subject line and the body of the message are ignored.
-@c the last two addresses in this paragraph are NOT @email because they
+@c the last two addresses in this paragraph are not @email because they
@c shouldn't be live links.
If your reply address is not valid, you can specify your address
-explicitly. Adding a hyphen to the subscribe or unsubscribe command
+explicitly, by adding a hyphen to the subscribe or unsubscribe command
word, followed by your address with the @samp{@@} character in your
address replaced by a @samp{=}. For example, to subscribe
@code{your_name@@host.domain}, send a message to
@@ -2148,16 +2002,16 @@ address replaced by a @samp{=}. For example, to subscribe
Mail to @email{mysql-subscribe@@lists.mysql.com} or
@email{mysql-unsubscribe@@lists.mysql.com} is handled automatically by the
ezmlm mailing list processor. Information about ezmlm is available at
-@uref{http://www.ezmlm.org, The ezmlm Website}.
+the ezmlm web site (@uref{http://www.ezmlm.org/}).
To post a message to the list itself, send your message to
-@code{mysql@@lists.mysql.com}. However, please @emph{do not} send mail about
-subscribing or unsubscribing to @email{mysql@@lists.mysql.com}, because any
+@code{mysql@@lists.mysql.com}. However, please @strong{do not} send mail about
+subscribing or unsubscribing to @email{mysql@@lists.mysql.com} because any
mail sent to that address is distributed automatically to thousands of other
users.
Your local site may have many subscribers to @email{mysql@@lists.mysql.com}.
-If so, it may have a local mailing list, so that messages sent from
+If so, it may have a local mailing list, so messages sent from
@code{lists.mysql.com} to your site are propagated to the local list. In such
cases, please contact your system administrator to be added to or dropped
from the local MySQL list.
@@ -2172,12 +2026,12 @@ The following MySQL mailing lists exist:
@table @code
@item @email{announce-subscribe@@lists.mysql.com} announce
This is for announcement of new versions of MySQL and related
-programs. This is a low volume list all MySQL users should
+programs. This is a low-volume list all MySQL users should
subscribe to.
@item @email{mysql-subscribe@@lists.mysql.com} mysql
The main list for general MySQL discussion. Please note that some
-topics are better discussed on the more-specialized lists. If you post to the
+topics are better discussed on the more-specialised lists. If you post to the
wrong list, you may not get an answer!
@item @email{mysql-digest-subscribe@@lists.mysql.com} mysql-digest
@@ -2189,10 +2043,10 @@ On this list you should only post a full, repeatable bug report using
the @code{mysqlbug} script (if you are running on Windows, you should
include a description of the operating system and the MySQL version).
Preferably, you should test the problem using the latest stable or development
-version of MySQL before posting! Anyone should be able to repeat the
-bug by just using @code{mysql test < script} on the included test case. All
-bugs posted on this list will be corrected or documented in the next
-MySQL release! If there are only small code changes involved, we
+version of MySQL Server before posting! Anyone should be able to repeat the
+bug by just using @code{mysql test < script} on the included test case. All
+bugs posted on this list will be corrected or documented in the next
+MySQL release! If only small code changes are needed, we
will also post a patch that fixes the problem.
@item @email{bugs-digest-subscribe@@lists.mysql.com} bugs-digest
@@ -2206,24 +2060,30 @@ can also discuss MySQL development and post patches.
A digest version of the @code{internals} list.
@item @email{java-subscribe@@lists.mysql.com} java
-Discussion about MySQL and Java. Mostly about the JDBC drivers.
+Discussion about the MySQL server and Java. Mostly about the JDBC drivers.
@item @email{java-digest-subscribe@@lists.mysql.com} java-digest
A digest version of the @code{java} list.
@item @email{win32-subscribe@@lists.mysql.com} win32
-All things concerning MySQL on Microsoft operating systems such as
-Win95, Win98, NT, and Win2000.
+All things concerning the MySQL software on Microsoft operating systems
+such as Windows 9x/Me/NT/2000/XP.
@item @email{win32-digest-subscribe@@lists.mysql.com} win32-digest
A digest version of the @code{win32} list.
@item @email{myodbc-subscribe@@lists.mysql.com} myodbc
-All things about connecting to MySQL with ODBC.
+All things about connecting to the MySQL server with ODBC.
@item @email{myodbc-digest-subscribe@@lists.mysql.com} myodbc-digest
A digest version of the @code{myodbc} list.
+@item @email{mycc-subscribe@@lists.mysql.com} mycc
+All things about the MySQL @code{MyCC} graphical client.
+
+@item @email{mycc-digest-subscribe@@lists.mysql.com} mycc-digest
+A digest version of the @code{mycc} list.
+
@item @email{plusplus-subscribe@@lists.mysql.com} plusplus
All things concerning programming with the C++ API to MySQL.
@@ -2231,14 +2091,14 @@ All things concerning programming with the C++ API to MySQL.
A digest version of the @code{plusplus} list.
@item @email{msql-mysql-modules-subscribe@@lists.mysql.com} msql-mysql-modules
-A list about the Perl support in MySQL. msql-mysql-modules
+A list about the Perl support for MySQL with msql-mysql-modules.
@item @email{msql-mysql-modules-digest-subscribe@@lists.mysql.com} msql-mysql-modules-digest
A digest version of the @code{msql-mysql-modules} list.
@end table
You subscribe or unsubscribe to all lists in the same way as described
-above. In your subscribe or unsubscribe message, just put the appropriate
+previously. In your subscribe or unsubscribe message, just put the appropriate
mailing list name rather than @code{mysql}. For example, to subscribe to or
unsubscribe from the @code{myodbc} list, send a message to
@email{myodbc-subscribe@@lists.mysql.com} or
@@ -2248,22 +2108,22 @@ If you can't get an answer for your questions from the mailing list, one
option is to pay for support from MySQL AB, which will put you
in direct contact with MySQL developers. @xref{Support}.
-The following table shows some MySQL mailing in other languages than
+The following table shows some MySQL mailing in languages other than
English. Note that these are not operated by MySQL AB, so we can't
guarantee the quality on these.
@table @code
@item @email{mysql-france-subscribe@@yahoogroups.com} A French mailing list
@item @email{list@@tinc.net} A Korean mailing list
-Email @code{subscribe mysql your@@email.address} to this list.
+E-mail @code{subscribe mysql your@@e-mail.address} to this list.
@item @email{mysql-de-request@@lists.4t2.com} A German mailing list
-Email @code{subscribe mysql-de your@@email.address} to this list.
+E-mail @code{subscribe mysql-de your@@e-mail.address} to this list.
You can find information about this mailing list at
-@uref{http://www.4t2.com/mysql}.
+@uref{http://www.4t2.com/mysql/}.
@item @email{mysql-br-request@@listas.linkway.com.br} A Portugese mailing list
-Email @code{subscribe mysql-br your@@email.address} to this list.
+E-mail @code{subscribe mysql-br your@@e-mail.address} to this list.
@item @email{mysql-alta@@elistas.net} A Spanish mailing list
-Email @code{subscribe mysql your@@email.address} to this list.
+E-mail @code{subscribe mysql your@@e-mail.address} to this list.
@end table
@@ -2272,7 +2132,7 @@ Email @code{subscribe mysql your@@email.address} to this list.
@cindex net etiquette
@cindex mailing lists, archive location
-@cindex searching, MySQL webpages
+@cindex searching, MySQL web pages
Before posting a bug report or question, please do the following:
@@ -2280,19 +2140,19 @@ Before posting a bug report or question, please do the following:
@item
Start by searching the MySQL online manual at:
@*
-@uref{http://www.mysql.com/documentation/manual.php}
+@uref{http://www.mysql.com/doc/}
@*
-We try to keep the manual up to date by updating it frequently with
+We try to keep the manual up to date by updating it frequently with
solutions to newly found problems!
@item
Search the MySQL mailing list archives:
@*
-@uref{http://www.mysql.com/documentation/}
+@uref{http://lists.mysql.com/}
@*
@item
You can also use @uref{http://www.mysql.com/search.html} to search all the
-Web pages (including the manual) that are located at
+web pages (including the manual) that are located at
@uref{http://www.mysql.com/}.
@end itemize
@@ -2322,7 +2182,7 @@ or at all.
We encourage everyone to use the @code{mysqlbug} script to generate a bug
report (or a report about any problem), if possible. @code{mysqlbug} can be
-found in the @file{scripts} directory in the source distribution, or, for a
+found in the @file{scripts} directory in the source distribution, or for a
binary distribution, in the @file{bin} directory under your MySQL
installation directory. If you are unable to use @code{mysqlbug}, you should
still include all the necessary information listed in this section.
@@ -2333,7 +2193,7 @@ missing, please include it with your message! Please read this section
carefully and make sure that all the information described here is included
in your report.
-@cindex bug reports, email address
+@cindex bug reports, e-mail address
The normal place to report bugs and problems is
@email{mysql@@lists.mysql.com}. If you can make a test case that clearly
demonstrates the bug, you should post it to the @email{bugs@@lists.mysql.com}
@@ -2341,15 +2201,18 @@ list. Note that on this list you should only post a full, repeatable bug
report using the @code{mysqlbug} script. If you are running on Windows,
you should include a description of the operating system and the
MySQL version. Preferably, you should test the problem using
-the latest stable or development version of MySQL before
+the latest stable or development version of MySQL Server before
posting! Anyone should be able to repeat the bug by just using
``@code{mysql test < script}'' on the included test case or run the
-shell or perl script that is included in the bug report. All bugs
+shell or Perl script that is included in the bug report. All bugs
posted on the @code{bugs} list will be corrected or documented in the next
-MySQL release! If there are only small code changes involved
+MySQL release! If only small code changes are needed
to correct this problem, we will also post a patch that fixes the
problem.
+If you have found a sensitive security bug in MySQL, you should send an
+e-mail to @email{security@@mysql.com}.
+
Remember that it is possible to respond to a message containing too much
information, but not to one containing too little. Often people omit facts
because they think they know the cause of a problem and assume that some
@@ -2361,20 +2224,20 @@ first time.
The most common errors are that people don't indicate the version number of
the MySQL distribution they are using, or don't indicate what
-platform they have MySQL installed on (including the platform
+platform they have the MySQL server installed on (including the platform
version number). This is highly relevant information, and in 99 cases out of
100 the bug report is useless without it! Very often we get questions like,
-``Why doesn't this work for me?'' then we find that the feature
+``Why doesn't this work for me?'' Then we find that the feature
requested wasn't implemented in that MySQL version, or that a bug
described in a report has been fixed already in newer MySQL
-versions. Sometimes the error is platform dependent; in such cases, it is
+versions. Sometimes the error is platform-dependent; in such cases, it is
next to impossible to fix anything without knowing the operating system and
the version number of the platform.
Remember also to provide information about your compiler, if it is related to
the problem. Often people find bugs in compilers and think the problem is
MySQL-related. Most compilers are under development all the time and
-become better version by version. To determine whether or not your
+become better version by version. To determine whether your
problem depends on your compiler, we need to know what compiler is used.
Note that every compiling problem should be regarded as a bug report and
reported accordingly.
@@ -2388,8 +2251,8 @@ problem. @xref{Reproduceable test case}.
If a program produces an error message, it is very important to include the
message in your report! If we try to search for something from the archives
using programs, it is better that the error message reported exactly matches
-the one that the program produces. (Even the case should be observed!)
-You should never try to remember what the error message was; instead, copy
+the one that the program produces. (Even the case should be observed!)
+You should never try to remember what the error message was; instead, copy
and paste the entire message into your report!
If you have a problem with MyODBC, you should try to generate a MyODBC
@@ -2397,11 +2260,11 @@ trace file. @xref{MyODBC bug report}.
Please remember that many of the people who will read your report will
do so using an 80-column display. When generating reports or examples
-using the @code{mysql} command line tool, you should therefore use
+using the @code{mysql} command-line tool, you should therefore use
the @code{--vertical} option (or the @code{\G} statement terminator)
for output that would exceed the available width for such a display
(for example, with the @code{EXPLAIN SELECT} statement; see the
-example below).
+example later in this section).
@cindex bug reports, criteria for
Please include the following information in your report:
@@ -2422,12 +2285,12 @@ The operating system name and version. For most operating systems, you can
get this information by executing the Unix command @code{uname -a}.
@item
-Sometimes the amount of memory (real and virtual) is relevant. If in doubt,
+Sometimes the amount of memory (real and virtual) is relevant. If in doubt,
include these values.
@item
-If you are using a source distribution of MySQL, the name and
-version number of the compiler used is needed. If you have a binary
+If you are using a source distribution of the MySQL software, the name and
+version number of the compiler used is needed. If you have a binary
distribution, the distribution name is needed.
@item
@@ -2454,7 +2317,7 @@ information you give about your situation, the more likely it is that someone
can help you! For example, the following is an example of a very good bug
report (it should of course be posted with the @code{mysqlbug} script):
-Example run using the @code{mysql} command line tool (note the use of the
+Example run using the @code{mysql} command-line tool (note the use of the
@code{\G} statement terminator for statements whose output width would
otherwise exceed that of an 80-column display device):
@@ -2473,11 +2336,11 @@ mysql> SHOW STATUS;
@end example
@item
-If a bug or problem occurs while running @strong{mysqld}, try to provide an
+If a bug or problem occurs while running @code{mysqld}, try to provide an
input script that will reproduce the anomaly. This script should include any
necessary source files. The more closely the script can reproduce your
-situation, the better. If you can make a repeatable test case, you should
-post this to @email{bugs@@lists.mysql.com} for a high priority treatment!
+situation, the better. If you can make a reproduceable test case, you should
+post this to @email{bugs@@lists.mysql.com} for a high-priority treatment!
If you can't provide a script, you should at least include the output
from @code{mysqladmin variables extended-status processlist} in your mail to
@@ -2490,12 +2353,12 @@ dump your tables using @code{mysqldump} and create a @file{README} file
that describes your problem.
Create a compressed archive of your files using
-@code{tar} and @code{gzip} or @code{zip}, and use @code{ftp} to transfer the
-archive to @uref{ftp://support.mysql.com/pub/mysql/secret/}. Then send a
+@code{tar} and @code{gzip} or @code{zip}, and use @code{ftp} to transfer the
+archive to @uref{ftp://support.mysql.com/pub/mysql/secret/}. Then send a
short description of the problem to @email{bugs@@lists.mysql.com}.
@item
-If you think that MySQL produces a strange result from a query,
+If you think that the MySQL server produces a strange result from a query,
include not only the result, but also your opinion of what the result
should be, and an account describing the basis for your opinion.
@@ -2504,11 +2367,11 @@ When giving an example of the problem, it's better to use the variable names,
table names, etc., that exist in your actual situation than to come up with
new names. The problem could be related to the name of a variable or table!
These cases are rare, perhaps, but it is better to be safe than sorry.
-After all, it should be easier for you to provide an example that uses your
+After all, it should be easier for you to provide an example that uses your
actual situation, and it is by all means better for us. In case you have data
-you don't want to show to others, you can use @code{ftp} to transfer it to
-@uref{ftp://support.mysql.com/pub/mysql/secret/}. If the data are really top
-secret and you don't want to show them even to us, then go ahead and provide
+you don't want to show to others, you can use @code{ftp} to transfer it to
+@uref{ftp://support.mysql.com/pub/mysql/secret/}. If the data is really top
+secret and you don't want to show it even to us, then go ahead and provide
an example using other names, but please regard this as the last choice.
@item
@@ -2530,9 +2393,9 @@ gives you trouble. @code{mysqlaccess} can be found in the @file{bin}
directory under your MySQL installation directory.
@item
-If you have a patch for a bug, that is good, but don't assume the patch is
+If you have a patch for a bug, that is good. But don't assume the patch is
all we need, or that we will use it, if you don't provide some necessary
-information, such as test cases showing the bug that your patch fixes. We
+information such as test cases showing the bug that your patch fixes. We
might find problems with your patch or we might not understand it at all; if
so, we can't use it.
@@ -2542,29 +2405,29 @@ situations that may occur. If we find a borderline case (even a rare one)
where the patch won't work, it may be useless.
@item
-Guesses about what the bug is, why it occurs, or what it depends on,
+Guesses about what the bug is, why it occurs, or what it depends on
are usually wrong. Even the MySQL team can't guess such things
without first using a debugger to determine the real cause of a bug.
@item
Indicate in your mail message that you have checked the reference manual
-and mail archive so others know that you have tried to solve the
+and mail archive so that others know you have tried to solve the
problem yourself.
@item
If you get a @code{parse error}, please check your syntax closely! If
you can't find something wrong with it, it's extremely likely that your
-current version of MySQL doesn't support the query you are
+current version of MySQL Server doesn't support the query you are
using. If you are using the current version and the manual at
-@uref{http://www.mysql.com/documentation/manual.php} doesn't cover the
-syntax you are using, MySQL doesn't support your query. In this
+@uref{http://www.mysql.com/doc/} doesn't cover the
+syntax you are using, MySQL Server doesn't support your query. In this
case, your only options are to implement the syntax yourself or e-mail
-@email{mysql-licensing@@mysql.com} and ask for an offer to implement it!
+@email{licensing@@mysql.com} and ask for an offer to implement it!
If the manual covers the syntax you are using, but you have an older version
-of MySQL, you should check the MySQL change history to see
-when the syntax was implemented. In this case, you have the option of
-upgrading to a newer version of MySQL. @xref{News}.
+of MySQL Server, you should check the MySQL change history to see
+when the syntax was implemented. In this case, you have the option of
+upgrading to a newer version of MySQL Server. @xref{News}.
@item
If you have a problem such that your data appears corrupt or you get
@@ -2574,20 +2437,20 @@ try repairing your tables with @code{myisamchk} or @code{CHECK TABLE} and
@item
If you often get corrupted tables you should try to find out when and why this
-happens! In this case, the @file{mysql-data-directory/'hostname'.err} file
+happens. In this case, the @file{mysql-data-directory/'hostname'.err} file
may contain some information about what happened. @xref{Error log}. Please
-include any relevant information from this file in your bug report! Normally
-@code{mysqld} should @strong{NEVER} crash a table if nothing killed it in the
+include any relevant information from this file in your bug report. Normally
+@code{mysqld} should @strong{never} crash a table if nothing killed it in the
middle of an update! If you can find the cause of @code{mysqld} dying,
-it's much easier for us to provide you with a fix for the problem!
+it's much easier for us to provide you with a fix for the problem.
@xref{What is crashing}.
@item
-If possible, download and install the most recent version of MySQL
-and check whether or not it solves your problem. All versions of
-MySQL are thoroughly tested and should work without problems! We
-believe in making everything as backward compatible as possible, and you
-should be able to switch MySQL versions in minutes!
+If possible, download and install the most recent version of MySQL Server
+and check whether it solves your problem. All versions of
+the MySQL software are thoroughly tested and should work without problems.
+We believe in making everything as backward-compatible as possible,
+and you should be able to switch MySQL versions without any hassle.
@xref{Which version}.
@end itemize
@@ -2596,22 +2459,22 @@ should be able to switch MySQL versions in minutes!
@cindex customer support, mailing address
@cindex mailing address, for customer support
If you are a support customer, please cross-post the bug report to
-@email{mysql-support@@mysql.com} for higher priority treatment, as well as to
+@email{mysql-support@@mysql.com} for higher-priority treatment, as well as to
the appropriate mailing list to see if someone else has experienced (and
perhaps solved) the problem.
-For information on reporting bugs in @strong{MyODBC}, see @ref{ODBC Problems}.
+For information on reporting bugs in @code{MyODBC}, see @ref{ODBC Problems}.
-For solutions to some common problems, see @xref{Problems}.
+For solutions to some common problems, see @ref{Problems}.
When answers are sent to you individually and not to the mailing list,
-it is considered good etiquette to summarize the answers and send the
+it is considered good etiquette to summarise the answers and send the
summary to the mailing list so that others may have the benefit of
responses you received that helped you solve your problem!
@node Answering questions, , Bug reports, Questions
-@subsubsection Guidelines for Answering Question on the Mailing List
+@subsubsection Guidelines for Answering Questions on the Mailing List
@cindex net etiquette
@cindex questions, answering
@@ -2624,784 +2487,125 @@ asked. Try to make your answer general enough that people other than the
original poster may benefit from it. When you post to the list, please make
sure that your answer is not a duplication of a previous answer.
-Try to summarize the essential part of the question in your reply; don't feel
+Try to summarise the essential part of the question in your reply; don't feel
obliged to quote the entire original message.
Please don't post mail messages from your browser with HTML mode turned on!
Many users don't read mail with a browser!
-@node Licensing and Support, Compatibility, MySQL Information Sources, Introduction
-@section MySQL Licensing and Support
-
-@cindex licensing terms
-@cindex support terms
-
-@menu
-* Licensing policy:: MySQL licensing policy
-* Copyright:: Copyrights used by MySQL
-* Licensing examples:: Example licensing situations
-* Cost:: MySQL licensing and support costs
-* Support:: Types of commercial support
-@end menu
-
-This section describes MySQL support and licensing
-arrangements:
-
-@itemize @bullet
-
-@item The copyrights under which MySQL is distributed
-(@pxref{Copyright})
-
-@item Sample situations illustrating when a license is required
-(@pxref{Licensing examples})
-
-@item Support costs (@pxref{Cost}) and support benefits
-(@pxref{Support})
-
-@item Commercial licensing costs
-@end itemize
-
-
-@node Licensing policy, Copyright, Licensing and Support, Licensing and Support
-@subsection MySQL Licensing Policy
-
-@cindex licensing policy
-@cindex technical support, licensing
-@cindex support, licensing
-@cindex General Public License, MySQL
-
-The formal terms of the GPL license can be found at @ref{GPL license}.
-Basically, our licensing policy and interpretation of the GPL is as follows:
-
-Note that older versions of MySQL are still using a more
-@uref{http://www.mysql.com/support/arrangements/mypl.html, strict license}.
-See the documentation for that version for more information. If you need a
-commercial MySQL license, because the GPL license doesn't suit your
-application, you can buy one at @uref{https://order.mysql.com/}.
-
-For normal internal use, MySQL costs nothing. You do not have
-to pay us if you do not want to.
-
-A license is required if:
-
-@itemize @minus
-@item
-You link a program, that is not free software, with code from the
-MySQL server or clients that has the GPL copyright. This
-happens for example when you use MySQL as an embedded server
-in your applications or when you add not free extensions to the
-MySQL server. In this case your application/code would also
-become GPL through the GPL license that acts as a virus. By licensing
-MySQL server from MySQL AB under a commercial
-license you will avoid this problem.
-See @uref{http://www.gnu.org/copyleft/gpl-faq.html}.
-@item
-You have a commercial application that ONLY works with MySQL
-and ships the application with the MySQL server. This is
-because we view this as linking even if it is done over the network.
-
-@item
-You have a distribution of MySQL and you don't provide the
-source code for your copy of the MySQL server, as defined in
-the GPL license.
-@end itemize
-
-A license is @strong{NOT} required if:
-
-@itemize @minus
-
-@item
-You do not need a license to include the client code in commercial
-programs. The client part of MySQL licensed with the
-LGPL @code{GNU Library General Public License}. The @code{mysql} command-line
-client includes code from the @code{readline} library that is under
-the @code{GPL}.
-
-@item
-If your use of MySQL does not require a license, but you
-like MySQL and want to encourage further development, you are
-certainly welcome to purchase a license or MySQL support anyway.
-
-@item
-If you use MySQL in a commercial context such that you profit by
-its use, we ask that you further the development of MySQL by
-purchasing some level of support. We feel that if MySQL helps
-your business, it is reasonable to ask that you help MySQL.
-(Otherwise, if you ask us support questions, you are not only using for
-free something into which we've put a lot a work, you're asking us to
-provide free support, too.)
-@end itemize
-
-For circumstances under which a MySQL license is required, you
-need a license per machine that runs the @code{mysqld} server. However,
-a multiple-CPU machine counts as a single machine, and there is no
-restriction on the number of MySQL servers that run on one
-machine, or on the number of clients concurrently connected to a server
-running on that machine!
-
-If you have any questions as to whether or not a license is required for
-your particular use of MySQL, please read this again and then
-contact us. @xref{Contact information}.
-
-If you require a MySQL license, the easiest way to pay for it
-is to use the license form on MySQL's secure server at
-@uref{https://order.mysql.com/}. Other forms of payment are
-discussed in @ref{Payment information}.
-
-
-@node Copyright, Licensing examples, Licensing policy, Licensing and Support
-@subsection Copyrights Used by MySQL
-
-@cindex copyrights
-
-@menu
-* Copyright changes:: Possible future copyright changes
-@end menu
-
-There are several different copyrights on the MySQL distribution:
-
-@enumerate
-@item
-The MySQL-specific source needed to build the
-@code{mysqlclient} library is licensed under the @code{LGPL} and
-programs in the @file{client} directory is GPL. Each file has a header
-that shows which copyright is used for that file.
-
-@item The client library and the (GNU @code{getopt}) library are covered
-by the ``GNU LIBRARY GENERAL PUBLIC LICENSE.'' @xref{LGPL license}.
-
-@item Some parts of the source (the @code{regexp} library) are covered
-by a Berkeley-style copyright.
-
-@item
-All the source in the server and the (GNU @code{readline}) library
-is covered by the ``GNU GENERAL PUBLIC LICENSE.'' @xref{GPL license}.
-This is also available as the file @file{COPYING} in the distributions.
-
-@end enumerate
-
-One goal is that the SQL client library should be free enough that it is
-possible to add MySQL support into commercial products
-without a license. For this reason, we chose the LGPL license for the
-client code.
-@cindex licensing, free
-@cindex free licensing
-
-This means that you can use MySQL for free with any program that uses
-any of the free software licenses. MySQL is also free for any end
-user for his own or company usage.
-
-However, if you use MySQL for something important to you, you may
-want to help secure its development by purchasing licenses or a support
-contract. @xref{Support}.
-
-
-@node Copyright changes, , Copyright, Copyright
-@subsubsection Copyright Changes
-
-Version 3.22 of MySQL is still using a more strict license.
-See the documentation for that version for more information.
-
-
-@node Licensing examples, Cost, Copyright, Licensing and Support
-@subsection Example Licensing Situations
-
-@menu
-* Products that use MySQL:: Selling products that use MySQL
-* ISP:: ISP MySQL services
-* Web server:: Running a web server using MySQL.
-@end menu
-
-@cindex licensing, examples
-@cindex selling products
-@cindex products, selling
-
-This section describes some situations illustrating whether or not you
-must license the MySQL server. Generally these examples
-involve providing MySQL as an integral part of a product.
-
-Note that a single MySQL license covers any number of CPUs and
-@code{mysqld} servers on a machine! There is no artificial limit on the
-number of clients that connect to the server in any way.
-
-
-@node Products that use MySQL, ISP, Licensing examples, Licensing examples
-@subsubsection Selling Products that use MySQL
-
-To determine whether or not you need a MySQL license when
-selling your application, you should ask whether the proper functioning
-of your application is dependent on the use of MySQL and
-whether you include the MySQL server with your product. There
-are several cases to consider:
-
-@itemize @bullet
-@item
-Does your application require MySQL to function properly?
-
-@item
-If your product requires MySQL, you need a license for any
-machine that runs the @code{mysqld} server. For example, if you've
-designed your application around MySQL, then you've really made
-a commercial product that requires the engine, so you need a license.
-
-@item
-If your application does not require MySQL, you do not need to obtain
-a license. For example, if using MySQL just adds some new optional
-features to your product (such as adding logging to a database if
-MySQL is used rather than logging to a text file), it should
-fall within normal use, and a license would not be required.
-
-@item
-In other words, you need a license if you sell a product designed
-specifically for use with MySQL or that requires the
-MySQL server to function at all. This is true whether or not
-you provide MySQL for your client as part of your product
-distribution.
-
-@item
-It also depends on what you're doing for the client. Do you plan to
-provide your client with detailed instructions on installing
-MySQL with your software? Then your product may be contingent
-on the use of MySQL; if so, you need to buy a license. If you
-are simply tying into a database that you expect already to have been
-installed by the time your software is purchased, then you probably
-don't need a license.
-
-@end itemize
-
-
-@node ISP, Web server, Products that use MySQL, Licensing examples
-@subsubsection ISP MySQL Services
-
-@cindex ISP services
-@cindex services, ISP
-@cindex services, web
-@cindex Internet Service Providers
-
-Internet Service Providers (ISPs) often host MySQL servers for
-their customers. With the GPL license this does not require a license.
-
-On the other hand, we do encourage people to use ISPs that have
-MySQL support, as this will give them the confidence that if
-they have some problem with their MySQL installation, their ISP
-will be able to solve the problem for them (in some cases with the help
-from the MySQL development team).
-
-All ISPs that want to keep themselves up-to-date should subscribe
-to our @code{announce} mailing list so that they can be aware of fatal issues
-that may be relevant for their MySQL installations.
-
-Note that if the ISP doesn't have a license for MySQL,
-it should give its customers at least read access to the source of
-the MySQL installation so that its customer can verify that
-it is patched correctly.
-
-
-@node Web server, , ISP, Licensing examples
-@subsubsection Running a Web Server Using MySQL
-
-@cindex web server, running
-@cindex running, a web server
-
-If you use MySQL in conjunction with a Web server on Unix, you
-don't have to pay for a license.
-
-This is true even if you run a commercial Web server that uses
-MySQL, because you are not selling an embedded MySQL
-version yourself. However, in this case we would like you to purchase
-MySQL support, because MySQL is helping your enterprise.
-
-
-@node Cost, Support, Licensing examples, Licensing and Support
-@subsection MySQL Licensing and Support Costs
-
-@cindex costs, licensing and support
-@cindex licensing costs
-@cindex support costs
-@cindex prices, licensing and support
-
-@menu
-* Payment information:: Payment information
-* Contact information:: Contact information
-@end menu
-
-Our current license prices are shown below. To make a purchase, please visit
-@uref{https://order.mysql.com/}.
-
-If you pay by credit card, the currency is EURO (European Union Euro) so the
-prices will differ slightly.
-
-@multitable @columnfractions .3 .3 .3
-@item @strong{Number of licenses} @tab @strong{Per copy}
-@item 1-9 @tab 230 EURO
-@item 10-24 @tab 138 EURO
-@item 25-49 @tab 117 EURO
-@item 50-99 @tab 102 EURO
-@item 100-249 @tab 91 EURO
-@item 250-499 @tab 76 EURO
-@item 500-999 @tab 66 EURO
-@end multitable
-
-For high volume (OEM) purchases, please contact
-@email{sales@@mysql.com}.
-
-For OEM purchases, you must act as the middle-man for eventual problems
-or extension requests from your users. We also require that OEM
-customers have at least an extended e-mail support contract. Note that
-OEM licenses only apply for products where the user doesn't have direct
-access to the MySQL server (embedded system). In other words,
-the MySQL server should only be used with the application
-that was supplied you.
-
-If you have a low-margin, high-volume product, you can always talk to us
-about other terms (for example, a percent of the sale price). If you do,
-please be informative about your product, pricing, market, and any other
-information that may be relevant.
-
-A full-price license is not a support agreement and includes very minimal
-support. This means that we try to answer any relevant questions. If the
-answer is in the documentation, we will direct you to the appropriate
-section. If you have not purchased a license or support, we probably will
-not answer at all.
-
-If you discover what we consider a real bug, we are likely to fix it in
-any case. But if you pay for support we will notify you about the fix
-status instead of just fixing it in a later release.
-
-More comprehensive support is sold separately. Descriptions of what each
-level of support includes are given in @ref{Support}. Costs for the various
-types of commercial support are shown below. Support level prices are in
-EURO (European Union Euro). One EURO is about 1.06 USD.
-
-@multitable @columnfractions .5 .5
-@item @strong{Type of support} @tab @strong{Cost per year}
-@item Basic e-mail support. @xref{Basic email support}. @tab EURO 200
-@item Extended e-mail support @xref{Extended email support}. @tab EURO 1000
-@item Login support @xref{Login support}. @tab EURO 2000
-@item Extended login support @xref{Extended login support}. @tab EURO 5000
-@item Telephone support @xref{Telephone support}. @tab EURO 12000
-@end multitable
-
-You may upgrade from any lower level of support to a higher level of
-support for the difference in price between the two support levels.
-
-We do also provide telephone support (mostly emergency support but also
-24/7 support). This support option doesn't however have a fixed price
-but is negotiated for case to case. If you are interested in this option
-you can email @email{sales@@mysql.com} and tell us about your needs.
-
-Note that as our sales staff is very busy, it may take some time until
-your request is handled. Our support staff does however always answer
-promptly to support questions!
-
-
-@node Payment information, Contact information, Cost, Cost
-@subsubsection Payment information
-
-@cindex payment information
-
-Currently we can take SWIFT payments, checks, or credit cards.
-
-Payment should be made to:
-
-@example
-Postgirot Bank AB
-105 06 STOCKHOLM, SWEDEN
-
-MySQL AB
-BOX 6434
-11382 STOCKHOLM, SWEDEN
-
-SWIFT address: PGSI SESS
-Account number: 96 77 06 - 3
-@end example
-
-Specify: license and/or support and your name and e-mail address.
-
-In Europe and Japan you can use EuroGiro (that should be less expensive) to the
-same account.
-
-If you want to pay by check, make it payable to ``MySQL Finland AB'' and
-mail it to the address below:
-
-@example
-MySQL AB
-BOX 6434, Torsgatan 21
-11382 STOCKHOLM, SWEDEN
-@end example
-
-If you want to pay by credit card over the Internet, you can use
-@uref{https://order.mysql.com/, MySQL AB's secure license form}.
-
-You can also print a copy of the license form, fill it in, and send it by fax
-to:
-
-+46-8-729 69 05
-
-If you want us to bill you, you can use the license form and write ``bill
-us'' in the comment field. You can also mail a message to
-@email{sales@@mysql.com} (@strong{not} @code{mysql@@lists.mysql.com}!)
-with your company information and ask us to bill you.
-
-
-@node Contact information, , Payment information, Cost
-@subsubsection Contact Information
-
-@cindex contact information
-@cindex licensing, contact information
-@cindex advertising, contact information
-@cindex employment, contact information
-@cindex partnering with MySQL
-@cindex employment with MySQL
-@cindex jobs at MySQL
-
-For commercial licensing, please contact the MySQL licensing
-team. The much preferred method is by e-mail to
-@email{licensing@@mysql.com}. Fax is also possible but handling of
-these may take much longer (Fax +46-8-729 69 05).
-
-If you represent a business that is interested in partnering with
-MySQL, please send e-mail to @email{partner@@mysql.com}.
-
-For timely, precise answers to technical questions about MySQL
-you should @uref{https://order.mysql.com/, order} one of our
-@uref{http://www.mysql.com/support/arrangements/types.html, support contracts}.
-MySQL support is provided by the MySQL developers so the
-standard is extremely high.
-
-If you are interested in placing a banner advertisement on our Web site,
-please send e-mail to @email{advertising@@mysql.com}.
-
-If you are interested in any of the jobs listed in our
-@uref{http://www.mysql.com/development/jobs/, jobs} section, please send e-mail
-to @email{jobs@@mysql.com}.
-
-For general discussion amongst our many users, please direct your attention to
-the appropriate @uref{http://www.mysql.com/documentation/lists.html, mailing
-list}.
-
-For general information inquires, please send e-mail to
-@email{info@@mysql.com}.
-
-For questions or comments about the workings or content of the Web site,
-please send e-mail to @email{webmaster@@mysql.com}.
-
+@node Compatibility, TODO, MySQL Information Sources, Introduction
+@section How Standards-compatible Is MySQL?
-@node Support, , Cost, Licensing and Support
-@subsection Types of Commercial Support
+@cindex compatibility, with ANSI SQL
+@cindex standards compatibility
+@cindex extensions, to ANSI SQL
+@cindex ANSI SQL92, extensions to
-@cindex support, types
-@cindex types, of support
-@cindex commercial support, types
+This section describes how MySQL relates to the ANSI SQL standards.
+MySQL Server has many extensions to the ANSI SQL standards, and here you
+will find out what they are and how to use them. You will also find
+information about functionality missing from MySQL Server, and how to work
+around some differences.
+
+Our goal is to not, without a very good reason, restrict MySQL Server usability
+for any usage. Even if we don't have the resources to do development
+for every possible use, we are always willing to help and offer
+suggestions to people who are trying to use MySQL Server in new territories.
+
+One of our main goals with the product is to continue to work toward
+ANSI 99 compliancy, but without sacrificing speed or reliability.
+We are not afraid to add extensions to SQL or support for non-SQL
+features if this greatly increases the usability of MySQL Server for a big
+part of our users. (The new @code{HANDLER} interface in MySQL Server 4.0
+is an example of this strategy. @xref{HANDLER, , @code{HANDLER}}.)
+
+We will continue to support transactional and non-transactional
+databases to satisfy both heavy web/logging usage and mission-critical
+24/7 usage.
+
+MySQL Server was designed from the start to work with medium size databases
+(10-100 million rows, or about 100 MB per table) on small computer
+systems. We will continue to extend MySQL Server to work even better
+with terabyte-size databases, as well as to make it possible
+to compile a reduced MySQL version that is more suitable for hand-held
+devices and embedded usage. The compact design of the MySQL server makes both
+of these directions possible without any conflicts in the source tree.
+
+We are currently not targeting realtime support or clustered databases
+(even if you can already do a lot of things with our replication
+services).
+
+We don't believe that one should have native XML support in the
+database, but will instead add the XML support our users request from
+us on the client side. We think it's better to keep the main server
+code as ``lean and clean'' as possible and instead develop libraries to
+deal with the complexity on the client side. This is part of the strategy
+mentioned previously of not sacrificing speed or reliability in the
+server.
@menu
-* Basic email support:: Basic email support
-* Extended email support:: Extended email support
-* Login support:: Login support
-* Extended login support:: Extended login support
-* Telephone support:: Telephone support
-* Table handler support:: Support for other table handlers
+* Standards:: What Standards Does MySQL Follow?
+* ANSI mode:: Running MySQL in ANSI Mode
+* Extensions to ANSI:: MySQL Extensions to ANSI SQL92
+* Differences from ANSI:: MySQL Differences Compared to ANSI SQL92
+* Bugs:: Known Errors and Design Deficiencies in MySQL
@end menu
-The following is true of all support options:
-
-@itemize @bullet
-@item
-The support is per year.
-@item
-We will fix, or provide a reasonable workaround for any repeatable bug.
-@item
-We will give a reasonable effort to find and fix any other MySQL related bug.
-@item
-The higher level of support contract the more effort we will put into finding
-a solution to your problems.
-@item
-The following is true for all support contracts except Basic email support:
-
-For non-bug related things, like helping you optimize your queries or
-your system, extending MySQL with new functionality, etc., we charge 200
-EURO/hour, which is deducted from your support contract. In other words,
-if you have login support (2000 EURO), you can expect us to work up to
-10 hours to help you with things like this.
-@end itemize
-
-
-@node Basic email support, Extended email support, Support, Support
-@subsubsection Basic E-mail Support
-
-@cindex email, technical support
-@cindex technical support, by email
-
-Basic e-mail support is a very inexpensive support option and should be
-thought of more as a way to support our development of MySQL
-than as a real support option. We at MySQL do give a lot of free
-support in all the different MySQL lists, and the money we get from
-basic e-mail support is largely used to make this possible.
-
-At this support level, the MySQL mailing lists are the preferred
-means of communication. Questions normally should be mailed to the primary
-mailing list (@email{mysql@@lists.mysql.com}) or one of the other regular
-lists (for example, @email{win32@@lists.mysql.com} for Windows-related
-MySQL questions), as someone else already may have experienced and
-solved the problem you have. @xref{Asking questions}.
-
-However, by purchasing basic e-mail support, you also have access to the
-support address @email{mysql-support@@mysql.com}, which is not available
-as part of the minimal support that you get by purchasing a MySQL
-license. This means that for especially critical questions, you can
-cross-post your message to @email{mysql-support@@mysql.com}. (If the
-message contains sensitive data, you should post only to
-@email{mysql-support@@mysql.com}.)
-
-@strong{REMEMBER!} to ALWAYS include your registration number and expiration
-date when you send a message to @email{mysql-support@@mysql.com}.
-
-Note that if you have encountered a critical, repeatable bug, and follow
-the rules outlined in the manual section of how to report bugs and send
-it to @email{bugs@@lists.mysql.com}, we promise to try to fix this as
-soon as possible, regardless of your support level! @xref{Bug reports}.
-
-Basic e-mail support includes the following types of service:
-
-@itemize @bullet
-@item
-If your question is already answered in the manual, we will inform you of the
-correct section in which you can find the answer. If the answer is not in
-the manual, we will point you in the right direction to solve your problem.
-
-@item
-We guarantee a timely answer for your e-mail messages. We can't guarantee
-that we can solve any problem, but at least you will receive an answer if we
-can contact you by e-mail.
-
-@item
-We will help with unexpected problems when you install MySQL from a
-binary distribution on supported platforms. This level of support does not
-cover installing MySQL from a source distribution. Supported
-platforms are those for which MySQL is known to work.
-@xref{Which OS}.
-
-@item
-We will help you with bugs and missing features. Any bugs that are found are
-fixed for the next MySQL release. If the bug is critical for
-you, we will mail you a patch for it as soon the bug is fixed. Critical
-bugs always have the highest priority for us, and we ensure that they are
-fixed as soon as possible.
-
-@item
-Your suggestions for the further development of MySQL will be
-taken into consideration. By taking email support you have already
-helped the further development of MySQL. If you want to have
-more input, upgrade to a higher level of support.
-
-@item
-If you want us to help optimize your system, you must upgrade to a
-higher level of support.
-@end itemize
-
-
-@node Extended email support, Login support, Basic email support, Support
-@subsubsection Extended E-mail Support
-
-@cindex extended email support
-
-Extended e-mail support includes everything in basic e-mail support with
-these additions:
-
-@itemize @bullet
-@item
-Your e-mail will be dealt with before mail from basic e-mail support users and
-non-registered users.
-
-@item
-Your suggestions for the further development of MySQL will
-receive strong consideration. Simple extensions that suit the basic
-goals of MySQL are implemented in a matter of days. By taking
-extended e-mail support you have already helped the further development
-of MySQL.
-
-@item
-Typical situations that are covered by extended e-mail support are:
-
-@itemize @minus
-@item
-We will answer and (within reason) solve questions that relate to possible
-bugs in MySQL. As soon as the bug is found and corrected, we
-will mail a patch for it.
-
-@item
-We will help with unexpected problems when you install MySQL from a
-source or binary distribution on supported platforms.
-
-@item
-We will answer questions about missing features and offer hints how to work
-around them.
-
-@item
-We will provide hints on optimizing @code{mysqld} for your situation.
-@end itemize
-
-@item
-You are allowed to influence the priority of items on the MySQL
-TODO List. @xref{TODO}. This will ensure that the features you really need
-will be implemented sooner than they might be otherwise.
-@end itemize
-
-
-@node Login support, Extended login support, Extended email support, Support
-@subsubsection Login Support
-
-@cindex login support
-
-Login support includes everything in extended e-mail support with
-these additions:
-
-@itemize @bullet
-@item
-Your e-mail will be dealt with even before e-mail from extended e-mail
-support users.
-
-@item
-Your suggestions for the further development of MySQL will
-be taken into very high consideration. Realistic extensions that can be
-implemented in a couple of hours and that suit the basic goals of
-MySQL will be implemented as soon as possible.
-@item
-If you have a very specific problem, we can try to log in on your system
-to solve the problem ``in place.''
+@node Standards, ANSI mode, Compatibility, Compatibility
+@subsection What Standards Does MySQL Follow?
-@item
-Like any database vendor, we can't guarantee that we can rescue any data from
-crashed tables, but if the worst happens, we will help you rescue as much as
-possible. MySQL has proven itself very reliable, but anything is
-possible due to circumstances beyond our control (for example, if your system
-crashes or someone kills the server by executing a @code{kill -9} command).
+Entry-level SQL92. ODBC levels 0-3.51.
-@item
-We will provide hints on optimizing your system and your queries.
+We are aiming toward supporting the full ANSI SQL99 standard,
+but without concessions to speed and quality of the code.
-@item
-You are allowed to call a MySQL developer (in moderation) and
-discuss your MySQL-related problems. This option is however
-only to be used as a last result during an emergency after we have
-failed to grasp the total problem with email. To make efficient
-use of our time we need to first get all facts about the problem,
-before talking on phone, to be able to work as efficiently as possible on
-solving the problem.
-@end itemize
+@node ANSI mode, Extensions to ANSI, Standards, Compatibility
+@subsection Running MySQL in ANSI Mode
-@node Extended login support, Telephone support, Login support, Support
-@subsubsection Extended Login Support
+@cindex running, ANSI mode
+@cindex ANSI mode, running
-Extended login support includes everything in login support with these
-additions:
+If you start @code{mysqld} with the @code{--ansi} option, the following
+behaviour of MySQL Server changes:
@itemize @bullet
@item
-Your e-mail has the highest possible priority.
-
-@item
-We will actively examine your system and help you optimize it and your
-queries. We may also optimize and/or extend MySQL to better
-suit your needs.
+@code{||} is string concatenation instead of @code{OR}.
@item
-You may also request special extensions just for you. For example:
-@example
-mysql> select MY_FUNC(col1,col2) from table;
-@end example
+You can have any number of spaces between a function name and the @samp{(}.
+This forces all function names to be treated as reserved words.
@item
-We will provide a binary distribution of all important MySQL
-releases for your system, as long as we can get an account on a
-similar system. In the worst case, we may require access to your system
-to be able to create a binary distribution.
+@samp{"} will be an identifier quote character (like the MySQL Server
+@samp{`} quote character) and not a string quote character.
@item
-If you can provide accommodations and pay for traveler fares, you can
-even get a MySQL developer to visit you and offer you help with
-your troubles. Extended login support entitles you to one personal
-encounter per year, but we are always very flexible towards our
-customers! If the visit takes 16 hours or more, the first 8 hours is
-without charge. For the hours above 8 hours, you will be charged with a
-rate that is at least 20 % less than our standard rates.
-@end itemize
-
-
-@node Telephone support, Table handler support, Extended login support, Support
-@subsubsection Telephone Support
-
-Telephone support includes everything in extended login support with
-these additions:
+@code{REAL} will be a synonym for @code{FLOAT} instead of a synonym for
+@code{DOUBLE}.
-@itemize @bullet
-@item
-We will provide you with a dynamic web page showing the current list of
-@code{MySQL} developers that you can phone when you have a critical
-problem.
@item
-For non critical problem, you can request a MySQL developer to
-phone back within 48 hours to discuss @code{MySQL} related issues.
+The default transaction isolation level is @code{SERIALIZABLE}.
+@xref{SET TRANSACTION}.
@end itemize
+This is the same as using
+@code{--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
+IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY}.
-@node Table handler support, , Telephone support, Support
-@subsubsection Support for other table handlers
-
-@cindex support, BDB Tables
-@cindex support, InnoDB Tables
-
-To get support for @code{BDB} tables, @code{InnoDB} tables you have
-to pay an additional 30% on the standard support price for each of
-the table handlers you would like to have support for.
-
-We at @code{MySQL AB} will help you create a proper bug report for the
-table handler and submit it to the developers for the specific table
-handler. We will also do our best to ensure that you will get a timely
-answer or solution from the developers of the table handler.
-
-Even if we are quite confident that we can solve most problems within a
-timely manner, we can't guarantee a quick solution for any problems you
-can get with the different table handlers. We will however do our best
-to help you get the problem solved.
-
-@node Compatibility, Comparisons, Licensing and Support, Introduction
-@section How Standards-compatible Is MySQL?
-
-@cindex compatibility, with ANSI SQL
-@cindex standards compatibility
-@cindex extensions, to ANSI SQL
-@cindex ANSI SQL92, extensions to
-
-@menu
-* Extensions to ANSI:: MySQL extensions to ANSI SQL92
-* Differences from ANSI:: MySQL differences compared to ANSI SQL92
-* ANSI mode:: Running MySQL in ANSI mode
-* Missing functions:: Functionality missing from MySQL
-* Standards:: What standards does MySQL follow?
-* Commit-rollback:: How to cope without @code{COMMIT}-@code{ROLLBACK}
-* Bugs:: Known errors and design deficiencies in MySQL
-@end menu
-
-This section describes how MySQL relates to the ANSI SQL standards.
-MySQL has many extensions to the ANSI SQL standards, and here you
-will find out what they are, and how to use them. You will also find
-information about functionality missing from MySQL, and how to work
-around some differences.
-
-
-@node Extensions to ANSI, Differences from ANSI, Compatibility, Compatibility
+@node Extensions to ANSI, Differences from ANSI, ANSI mode, Compatibility
@subsection MySQL Extensions to ANSI SQL92
-MySQL includes some extensions that you probably will not find in
+@cindex hints
+MySQL Server includes some extensions that you probably will not find in
other SQL databases. Be warned that if you use them, your code will not be
portable to other SQL servers. In some cases, you can write code that
includes MySQL extensions, but is still portable, by using comments
-of the form @code{/*! ... */}. In this case, MySQL will parse and
+of the form @code{/*! ... */}. In this case, MySQL Server will parse and
execute the code within the comment as it would any other MySQL
statement, but other SQL servers will ignore the extensions. For example:
@@ -3409,18 +2613,18 @@ statement, but other SQL servers will ignore the extensions. For example:
SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ...
@end example
-If you add a version number after the @code{'!'}, the syntax will only be
-executed if the MySQL version is equal to or newer than the used
+If you add a version number after the @code{'!'}, the syntax will be
+executed only if the MySQL version is equal to or newer than the used
version number:
@example
CREATE /*!32302 TEMPORARY */ TABLE (a int);
@end example
-The above means that if you have Version 3.23.02 or newer, then MySQL
-will use the @code{TEMPORARY} keyword.
+This means that if you have Version 3.23.02 or newer, MySQL
+Server will use the @code{TEMPORARY} keyword.
-MySQL extensions are listed below:
+The following is a list of MySQL extensions:
@itemize @bullet
@item
@@ -3432,7 +2636,7 @@ The field attributes @code{AUTO_INCREMENT}, @code{BINARY}, @code{NULL},
@code{UNSIGNED}, and @code{ZEROFILL}.
@item
-All string comparisons are case insensitive by default, with sort
+All string comparisons are case-insensitive by default, with sort
ordering determined by the current character set (ISO-8859-1 Latin1 by
default). If you don't like this, you should declare your columns with
the @code{BINARY} attribute or use the @code{BINARY} cast, which causes
@@ -3440,21 +2644,21 @@ comparisons to be done according to the ASCII order used on the
MySQL server host.
@item
-MySQL maps each database to a directory under the MySQL
+MySQL Server maps each database to a directory under the MySQL
data directory, and tables within a database to filenames in the database
directory.
This has a few implications:
-@cindex database names, case sensitivity
-@cindex table names, case sensitivity
-@cindex case sensitivity, of database names
-@cindex case sensitivity, of table names
+@cindex database names, case-sensitivity
+@cindex table names, case-sensitivity
+@cindex case-sensitivity, of database names
+@cindex case-sensitivity, of table names
@itemize @minus
@item
-Database names and table names are case sensitive in MySQL on
+Database names and table names are case-sensitive in MySQL Server on
operating systems that have case-sensitive filenames (like most Unix
systems). @xref{Name case sensitivity}.
@@ -3463,7 +2667,7 @@ Database, table, index, column, or alias names may begin with a digit
(but may not consist solely of digits).
@item
-You can use standard system commands to backup, rename, move, delete, and copy
+You can use standard system commands to back up, rename, move, delete, and copy
tables. For example, to rename a table, rename the @file{.MYD}, @file{.MYI},
and @file{.frm} files to which the table corresponds.
@end itemize
@@ -3472,7 +2676,7 @@ and @file{.frm} files to which the table corresponds.
In SQL statements, you can access tables from different databases
with the @code{db_name.tbl_name} syntax. Some SQL servers provide
the same functionality but call this @code{User space}.
-MySQL doesn't support tablespaces as in:
+MySQL Server doesn't support tablespaces as in:
@code{create table ralph.my_table...IN my_tablespace}.
@item
@@ -3497,7 +2701,7 @@ statement. @xref{CREATE TABLE, , @code{CREATE TABLE}}.
Use of @code{TEMPORARY} or @code{IF NOT EXISTS} with @code{CREATE TABLE}.
@item
-Use of @code{COUNT(DISTINCT list)} where 'list' is more than one element.
+Use of @code{COUNT(DISTINCT list)} where @code{list} is more than one element.
@item
Use of @code{CHANGE col_name}, @code{DROP col_name}, or @code{DROP
@@ -3549,7 +2753,7 @@ Strings may be enclosed by either @samp{"} or @samp{'}, not just by @samp{'}.
Use of the escape @samp{\} character.
@item
-The @code{SET OPTION} statement. @xref{SET OPTION, , @code{SET OPTION}}.
+The @code{SET} statement. @xref{SET OPTION, , @code{SET}}.
@item
You don't need to name all selected columns in the @code{GROUP BY} part.
@@ -3562,18 +2766,18 @@ One can specify @code{ASC} and @code{DESC} with @code{GROUP BY}.
@item
To make it easier for users who come from other SQL environments,
-MySQL supports aliases for many functions. For example, all
+MySQL Server supports aliases for many functions. For example, all
string functions support both ANSI SQL syntax and ODBC syntax.
@item
-MySQL understands the @code{||} and @code{&&} operators to mean
-logical OR and AND, as in the C programming language. In MySQL,
+MySQL Server understands the @code{||} and @code{&&} operators to mean
+logical OR and AND, as in the C programming language. In MySQL Server,
@code{||} and @code{OR} are synonyms, as are @code{&&} and @code{AND}.
-Because of this nice syntax, MySQL doesn't support
+Because of this nice syntax, MySQL Server doesn't support
the ANSI SQL @code{||} operator for string concatenation; use
@code{CONCAT()} instead. Because @code{CONCAT()} takes any number
of arguments, it's easy to convert use of the @code{||} operator to
-MySQL.
+MySQL Server.
@item
@code{CREATE DATABASE} or @code{DROP DATABASE}.
@@ -3606,12 +2810,12 @@ operators.
@item
@code{CONCAT()} or @code{CHAR()} with one argument or more than two
-arguments. (In MySQL, these functions can take any number of
+arguments. (In MySQL Server, these functions can take any number of
arguments.)
@item The @code{BIT_COUNT()}, @code{CASE}, @code{ELT()},
@code{FROM_DAYS()}, @code{FORMAT()}, @code{IF()}, @code{PASSWORD()},
-@code{ENCRYPT()}, @code{md5()}, @code{ENCODE()}, @code{DECODE()},
+@code{ENCRYPT()}, @code{MD5()}, @code{ENCODE()}, @code{DECODE()},
@code{PERIOD_ADD()}, @code{PERIOD_DIFF()}, @code{TO_DAYS()}, or
@code{WEEKDAY()} functions.
@@ -3631,7 +2835,7 @@ Use of @code{REPLACE} instead of @code{DELETE} + @code{INSERT}.
The @code{FLUSH}, @code{RESET} and @code{DO} statements.
@item
-The possibility to set variables in a statement with @code{:=}:
+The ability to set variables in a statement with @code{:=}:
@example
SELECT @@a:=SUM(total),@@b=COUNT(*),@@a/@@b AS avg FROM test_table;
SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
@@ -3640,19 +2844,15 @@ SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
@end itemize
-@node Differences from ANSI, ANSI mode, Extensions to ANSI, Compatibility
+@node Differences from ANSI, Bugs, Extensions to ANSI, Compatibility
@subsection MySQL Differences Compared to ANSI SQL92
-We try to make MySQL follow the ANSI SQL standard and the
-ODBC SQL standard, but in some cases MySQL does some things
+We try to make MySQL Server follow the ANSI SQL standard and the
+ODBC SQL standard, but in some cases MySQL Server does things
differently:
@itemize @bullet
@item
-@code{--} is only a comment if followed by a white space. @xref{Missing
-comments}.
-
-@item
For @code{VARCHAR} columns, trailing spaces are removed when the value is
stored. @xref{Bugs}.
@@ -3671,80 +2871,39 @@ This is because we don't think it's good to have to evaluate a lot of
extra conditions in this case.
@end itemize
-
-@node ANSI mode, Missing functions, Differences from ANSI, Compatibility
-@subsection Running MySQL in ANSI Mode
-
-@cindex running, ANSI mode
-@cindex ANSI mode, running
-
-If you start @code{mysqld} with the @code{--ansi} option, the following
-behavior of MySQL changes:
-
-@itemize @bullet
-@item
-@code{||} is string concatenation instead of @code{OR}.
-
-@item
-You can have any number of spaces between a function name and the @samp{(}.
-This forces all function names to be treated as reserved words.
-
-@item
-@samp{"} will be an identifier quote character (like the MySQL
-@samp{`} quote character) and not a string quote character.
-
-@item
-@code{REAL} will be a synonym for @code{FLOAT} instead of a synonym of
-@code{DOUBLE}.
-
-@item
-The default transaction isolation level is @code{SERIALIZABLE}.
-@xref{SET TRANSACTION}.
-@end itemize
-
-This is the same as using @code{--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY}.
-
-@node Missing functions, Standards, ANSI mode, Compatibility
-@subsection Functionality Missing from MySQL
-
-@cindex missing functionality
-@cindex functionality, missing
-
-The following functionality is missing in the current version of
-MySQL. For a prioritized list indicating when new extensions
-may be added to MySQL, you should consult
-@uref{http://www.mysql.com/documentation/manual.php?section=TODO, the
-online MySQL TODO list}. That is the latest version of the TODO
-list in this manual. @xref{TODO}.
-
@menu
-* Missing Sub-selects:: Sub-selects
-* Missing SELECT INTO TABLE:: @code{SELECT INTO TABLE}
-* Missing Transactions:: Transactions
-* Missing Triggers:: Triggers
-* Missing Foreign Keys:: Foreign Keys
-* Broken Foreign KEY:: Reasons NOT to Use Foreign Keys constraints
-* Missing Views:: Views
-* Missing comments:: @samp{--} as the start of a comment
+* ANSI diff Sub-selects:: Sub@code{SELECT}s
+* ANSI diff SELECT INTO TABLE:: @code{SELECT INTO TABLE}
+* ANSI diff Transactions:: Transactions and Atomic Operations
+* ANSI diff Triggers:: Stored Procedures and Triggers
+* ANSI diff Foreign Keys:: Foreign Keys
+* ANSI diff Views:: Views
+* ANSI diff comments:: @samp{--} as the Start of a Comment
@end menu
+For a prioritised list indicating when new extensions will be added to
+MySQL Server, you should consult the online MySQL TODO list at
+@uref{http://www.mysql.com/documentation/manual.php?section=TODO}.
+That is the latest version of the TODO list in this manual. @xref{TODO}.
-@node Missing Sub-selects, Missing SELECT INTO TABLE, Missing functions, Missing functions
-@subsubsection Sub-selects
-@cindex sub-selects
+@node ANSI diff Sub-selects, ANSI diff SELECT INTO TABLE, Differences from ANSI, Differences from ANSI
+@subsubsection Sub@code{SELECT}s
-MySQL currently only supports sub selects of the form @code{INSERT
-... SELECT ...} and @code{REPLACE ... SELECT ...}. You can however use
-the function @code{IN()} in other contexts.
+@cindex sub@code{SELECT}s
-In many cases you can rewrite the query without a sub-select:
+MySQL Server currently only supports nested queries of the form
+@code{INSERT ... SELECT ...} and @code{REPLACE ... SELECT ...}.
+You can, however, use the function @code{IN()} in other contexts.
+Subselects are currently being implemented in the 4.1 development tree.
+
+Meanwhile, you can often rewrite the query without a subselect:
@example
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
@end example
-This can be re-written as:
+This can be rewritten as:
@example
SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;
@@ -3753,21 +2912,23 @@ SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;
The queries:
@example
SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
-SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2 where table1.id=table2.id);
+SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2
+ WHERE table1.id=table2.id);
@end example
Can be rewritten as:
@example
-SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id IS NULL
+SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id
+ WHERE table2.id IS NULL;
@end example
For more complicated subqueries you can often create temporary tables
-to hold the subquery. In some cases, however this option will not
+to hold the subquery. In some cases, however, this option will not
work. The most frequently encountered of these cases arises with
@code{DELETE} statements, for which standard SQL does not support joins
-(except in sub-selects). For this situation there are two options
-available until subqueries are supported by MySQL.
+(except in subselects). For this situation there are two options
+available until subqueries are supported by MySQL Server.
The first option is to use a procedural programming language (such as
Perl or PHP) to submit a @code{SELECT} query to obtain the primary keys
@@ -3775,13 +2936,13 @@ for the records to be deleted, and then use these values to construct
the @code{DELETE} statement (@code{DELETE FROM ... WHERE ... IN (key1,
key2, ...)}).
-The second option is to use interactive SQL to contruct a set of
+The second option is to use interactive SQL to construct a set of
@code{DELETE} statements automatically, using the MySQL
extension @code{CONCAT()} (in lieu of the standard @code{||} operator).
For example:
@example
-SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', tab1.pkid, ';')
+SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';')
FROM tab1, tab2
WHERE tab1.col1 = tab2.col2;
@end example
@@ -3791,149 +2952,231 @@ the @code{mysql} command-line interpreter, piping its output back to a
second instance of the interpreter:
@example
-prompt> mysql --skip-column-names mydb < myscript.sql | mysql mydb
+shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
@end example
-MySQL 4.0 supports multi-table deletes that can be used to efficiently
-delete rows based on information from one table or even from many tables
-at the same time.
+MySQL Server 4.0 supports multi-table deletes that can be used to
+efficiently delete rows based on information from one table or even
+from many tables at the same time.
-@node Missing SELECT INTO TABLE, Missing Transactions, Missing Sub-selects, Missing functions
+
+@node ANSI diff SELECT INTO TABLE, ANSI diff Transactions, ANSI diff Sub-selects, Differences from ANSI
@subsubsection @code{SELECT INTO TABLE}
@findex SELECT INTO TABLE
-MySQL doesn't yet support the Oracle SQL extension:
-@code{SELECT ... INTO TABLE ...}. MySQL supports instead the
+MySQL Server doesn't yet support the Oracle SQL extension:
+@code{SELECT ... INTO TABLE ...}. MySQL Server supports instead the
ANSI SQL syntax @code{INSERT INTO ... SELECT ...}, which is basically
the same thing. @xref{INSERT SELECT}.
@example
-INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE
-tblTemp1.fldOrder_ID > 100;
+INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID
+ FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;
@end example
Alternatively, you can use @code{SELECT INTO OUTFILE...} or @code{CREATE
-TABLE ... SELECT} to solve your problem.
+TABLE ... SELECT}.
-@node Missing Transactions, Missing Triggers, Missing SELECT INTO TABLE, Missing functions
-@subsubsection Transactions
+@node ANSI diff Transactions, ANSI diff Triggers, ANSI diff SELECT INTO TABLE, Differences from ANSI
+@subsubsection Transactions and Atomic Operations
+@findex COMMIT
+@findex ROLLBACK
@cindex transactions, support
-
-As MySQL does nowadays support transactions, the following
-discussion is only valid if you are only using the non-transaction-safe
-table types. @xref{COMMIT}.
-
-The question is often asked, by the curious and the critical, ``Why is
-MySQL not a transactional database?'' or ``Why does MySQL
-not support transactions?''
-
-MySQL has made a conscious decision to support another paradigm
-for data integrity, ``atomic operations.'' It is our thinking and
-experience that atomic operations offer equal or even better integrity
-with much better performance. We, nonetheless, appreciate and understand
-the transactional database paradigm and plan, within the next few releases,
-to introduce transaction-safe tables on a per table basis. We will be
-giving our users the possibility to decide if they need the speed of
-atomic operations or if they need to use transactional features in their
-applications.
-
-How does one use the features of MySQL to maintain rigorous integrity
+@cindex transaction-safe tables
+@cindex tables, updating
+@cindex updating, tables
+@cindex @code{InnoDB} tables
+@cindex @code{BDB} tables
+@cindex @code{ACID}
+
+MySQL Server supports transactions with the @code{InnoDB} and @code{BDB}
+@code{Transactional table handlers}. @xref{Table types}.
+@code{InnoDB} provides @code{ACID} compliancy.
+
+However, the non-transactional table types in MySQL Server such as
+@code{MyISAM} follow another paradigm for data integrity called
+``@code{Atomic Operations}.'' Atomic operations often offer equal or
+even better integrity with much better performance.
+With MySQL Server supporting both paradigms, the user is able to decide if
+he needs the speed of atomic operations or if he need to use
+transactional features in his applications. This choice can be made
+on a per-table basis.
+
+How does one use the features of MySQL Server to maintain rigorous integrity
and how do these features compare with the transactional paradigm?
-First, in the transactional paradigm, if your applications are written
-in a way that is dependent on the calling of ``rollback'' instead of
-``commit'' in critical situations, then transactions are more
-convenient. Moreover, transactions ensure that unfinished updates or
+@enumerate
+@item
+In the transactional paradigm, if your applications are written in a
+way that is dependent on the calling of @code{ROLLBACK} instead of
+@code{COMMIT} in critical situations, transactions are more
+convenient. Transactions also ensure that unfinished updates or
corrupting activities are not committed to the database; the server is
given the opportunity to do an automatic rollback and your database is
saved.
-MySQL, in almost all cases, allows you to solve for potential
-problems by including simple checks before updates and by running simple
-scripts that check the databases for inconsistencies and automatically
-repair or warn if such occurs. Note that just by using the
-MySQL log or even adding one extra log, one can normally fix
-tables perfectly with no data integrity loss.
-
-Moreover, fatal transactional updates can be rewritten to be
-atomic. In fact,we will go so far as to say that all integrity problems
-that transactions solve can be done with @code{LOCK TABLES} or atomic updates,
-ensuring that you never will get an automatic abort from the database,
-which is a common problem with transactional databases.
-
-Not even transactions can prevent all loss if the server goes down. In
-such cases even a transactional system can lose data. The difference
-between different systems lies in just how small the time-lap is where
-they could lose data. No system is 100% secure, only ``secure
-enough.'' Even Oracle, reputed to be the safest of transactional
-databases, is reported to sometimes lose data in such situations.
-
-To be safe with MySQL, you only need to have backups and have
-the update logging turned on. With this you can recover from any
-situation that you could with any transactional database. It is, of
-course, always good to have backups, independent of which database you
-use.
+MySQL Server, in almost all cases, allows you to resolve potential problems
+by including simple checks before updates and by running simple scripts
+that check the databases for inconsistencies and automatically repair
+or warn if such an inconsistency occurs. Note that just by using the
+MySQL log or even adding one extra log, one can normally fix tables
+perfectly with no data integrity loss.
+
+@item
+More often than not, fatal transactional updates can be rewritten to be
+atomic. Generally speaking, all integrity problems that transactions
+solve can be done with @code{LOCK TABLES} or atomic updates, ensuring
+that you never will get an automatic abort from the database, which is
+a common problem with transactional databases.
+
+@item
+Even a transactional system can lose data if the server goes down.
+The difference between different systems lies in just how small the
+time-lap is where they could lose data. No system is 100% secure, only
+``secure enough.'' Even Oracle, reputed to be the safest of
+transactional databases, is reported to sometimes lose data in such
+situations.
+
+To be safe with MySQL Server, whether using transactional tables or not, you
+only need to have backups and have the update logging turned on. With
+this you can recover from any situation that you could with any
+other transactional database. It is, of course, always good to have
+backups, independent of which database you use.
+@end enumerate
The transactional paradigm has its benefits and its drawbacks. Many
-users and application developers depend on the ease with which they can
-code around problems where an abort appears to be, or is necessary, and they
-may have to do a little more work with MySQL to either think
-differently or write more. If you are new to the atomic operations
-paradigm, or more familiar or more comfortable with transactions, do not
-jump to the conclusion that MySQL has not addressed these
-issues. Reliability and integrity are foremost in our minds. Recent
-estimates indicate that there are more than 1,000,000 @code{mysqld} servers
-currently running, many of which are in production environments. We
-hear very, very seldom from our users that they have lost any data, and
-in almost all of those cases user error is involved. This is, in our
-opinion, the best proof of MySQL's stability and reliability.
-
-Lastly, in situations where integrity is of highest importance,
-MySQL's current features allow for transaction-level or better
-reliability and integrity. If you lock tables with @code{LOCK TABLES}, all
-updates will stall until any integrity checks are made. If you only obtain
-a read lock (as opposed to a write lock), then reads and inserts are
-still allowed to happen. The new inserted records will not be seen by
-any of the clients that have a @code{READ} lock until they release their read
-locks. With @code{INSERT DELAYED} you can queue inserts into a local queue,
-until the locks are released, without having the client wait for the insert
-to complete. @xref{INSERT DELAYED}.
-
-``Atomic,'' in the sense that we mean it, is nothing magical. It only means
-that you can be sure that while each specific update is running, no other
-user can interfere with it, and there will never be an automatic
-rollback (which can happen on transaction based systems if you are not
-very careful). MySQL also guarantees that there will not be
-any dirty reads. You can find some example of how to write atomic updates
-in the commit-rollback section. @xref{Commit-rollback}.
-
-We have thought quite a bit about integrity and performance, and we
-believe that our atomic operations paradigm allows for both high
-reliability and extremely high performance, on the order of three to
-five times the speed of the fastest and most optimally tuned of
-transactional databases. We didn't leave out transactions because they
-are hard to do. The main reason we went with atomic operations as
-opposed to transactions is that by doing this we could apply many speed
-optimizations that would not otherwise have been possible.
-
-Many of our users who have speed foremost in their minds are not at all
-concerned about transactions. For them transactions are not an
-issue. For those of our users who are concerned with or have wondered
-about transactions vis-a-vis MySQL, there is a ``MySQL
-way'' as we have outlined above. For those where safety is more
-important than speed, we recommend them to use the @code{BDB},
-or @code{InnoDB} tables for all their critical data. @xref{Table types}.
-
-One final note: We are currently working on a safe replication schema
-that we believe to be better than any commercial replication system we
-know of. This system will work most reliably under the atomic
-operations, non-transactional, paradigm. Stay tuned.
-
-
-@node Missing Triggers, Missing Foreign Keys, Missing Transactions, Missing functions
+users and application developers depend on the ease with which they
+can code around problems where an abort appears to be, or is necessary.
+However, even if you are new to the atomic operations paradigm, or more
+familiar with transactions, do consider the speed benefit that
+non-transactional tables can offer on the order of three to five times
+the speed of the fastest and most optimally tuned transactional tables.
+
+In situations where integrity is of highest importance, MySQL Server offers
+transaction-level or better reliability and integrity even for
+non-transactional tables.
+If you lock tables with @code{LOCK TABLES}, all updates will stall
+until any integrity checks are made. If you only obtain a read lock
+(as opposed to a write lock), reads and inserts are still allowed
+to happen. The new inserted records will not be seen by any of the
+clients that have a read lock until they release their read
+locks. With @code{INSERT DELAYED} you can queue inserts into a local
+queue, until the locks are released, without having the client wait
+for the insert to complete. @xref{INSERT DELAYED}.
+
+``Atomic,'' in the sense that we mean it, is nothing magical. It only
+means that you can be sure that while each specific update is running,
+no other user can interfere with it, and there will never be an
+automatic rollback (which can happen with transactional tables if you
+are not very careful). MySQL Server also guarantees that there will not be
+any dirty reads.
+
+Following are some techniques for working with non-transactional tables:
+
+@itemize @bullet
+@item
+Loops that need transactions normally can be coded with the help of
+@code{LOCK TABLES}, and you don't need cursors when you can update
+records on the fly.
+
+@item
+To avoid using @code{ROLLBACK}, you can use the following strategy:
+
+@enumerate
+@item
+Use @code{LOCK TABLES ...} to lock all the tables you want to access.
+@item
+Test conditions.
+@item
+Update if everything is okay.
+@item
+Use @code{UNLOCK TABLES} to release your locks.
+@end enumerate
+
+This is usually a much faster method than using transactions with
+possible @code{ROLLBACK}s, although not always. The only situation
+this solution doesn't handle is when someone kills the threads in the
+middle of an update. In this case, all locks will be released but some
+of the updates may not have been executed.
+
+@item
+You can also use functions to update records in a single operation.
+You can get a very efficient application by using the following
+techniques:
+
+@itemize @bullet
+@item Modify fields relative to their current value.
+@item Update only those fields that actually have changed.
+@end itemize
+
+For example, when we are doing updates to some customer information, we
+update only the customer data that has changed and test only that none of
+the changed data, or data that depends on the changed data, has changed
+compared to the original row. The test for changed data is done with the
+@code{WHERE} clause in the @code{UPDATE} statement. If the record wasn't
+updated, we give the client a message: "Some of the data you have changed
+has been changed by another user." Then we show the old row versus the new
+row in a window, so the user can decide which version of the customer record
+he should use.
+
+This gives us something that is similar to column locking but is actually
+even better because we only update some of the columns, using values that
+are relative to their current values. This means that typical @code{UPDATE}
+statements look something like these:
+
+@example
+UPDATE tablename SET pay_back=pay_back+'relative change';
+
+UPDATE customer
+ SET
+ customer_date='current_date',
+ address='new address',
+ phone='new phone',
+ money_he_owes_us=money_he_owes_us+'new_money'
+ WHERE
+ customer_id=id AND address='old address' AND phone='old phone';
+@end example
+
+As you can see, this is very efficient and works even if another client
+has changed the values in the @code{pay_back} or @code{money_he_owes_us}
+columns.
+
+@item
+@findex mysql_insert_id()
+@findex LAST_INSERT_ID()
+In many cases, users have wanted @code{ROLLBACK} and/or @code{LOCK
+TABLES} for the purpose of managing unique identifiers for some tables.
+This can be handled much more efficiently by using an
+@code{AUTO_INCREMENT} column and either the SQL function
+@code{LAST_INSERT_ID()} or the C API function @code{mysql_insert_id()}.
+@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
+
+@cindex rows, locking
+@cindex locking, row-level
+You can generally code around row-level locking. Some situations really
+need it, but they are very few. @code{InnoDB} tables support row-level
+locking. With MyISAM, you can use a flag column in the table and do
+something like the following:
+
+@example
+UPDATE tbl_name SET row_flag=1 WHERE id=ID;
+@end example
+
+MySQL returns 1 for the number of affected rows if the row was
+found and @code{row_flag} wasn't already 1 in the original row.
+
+You can think of it as though MySQL Server changed the preceding query to:
+
+@example
+UPDATE tbl_name SET row_flag=1 WHERE id=ID AND row_flag <> 1;
+@end example
+@end itemize
+
+
+@node ANSI diff Triggers, ANSI diff Foreign Keys, ANSI diff Transactions, Differences from ANSI
@subsubsection Stored Procedures and Triggers
@cindex stored procedures and triggers, defined
@@ -3941,7 +3184,7 @@ operations, non-transactional, paradigm. Stay tuned.
@cindex triggers, stored
A stored procedure is a set of SQL commands that can be compiled and stored
-in the server. Once this has been done, clients don't need to keep reissuing
+in the server. Once this has been done, clients don't need to keep re-issuing
the entire query but can refer to the stored procedure. This provides better
performance because the query has to be parsed only once, and less information
needs to be sent between the server and the client. You can also raise the
@@ -3953,14 +3196,12 @@ each time a record is deleted from a transaction table and that automatically
deletes the corresponding customer from a customer table when all his
transactions are deleted.
-The planned update language will be able to
-handle stored procedures, but without triggers. Triggers usually slow
-down everything, even queries for which they are not needed.
-
-To see when MySQL might get stored procedures, see @ref{TODO}.
+The planned update language will be able to handle stored procedures.
+Our aim is to have stored procedures implemented in MySQL Server around
+version 5.0. We are also looking at triggers.
-@node Missing Foreign Keys, Broken Foreign KEY, Missing Triggers, Missing functions
+@node ANSI diff Foreign Keys, ANSI diff Views, ANSI diff Triggers, Differences from ANSI
@subsubsection Foreign Keys
@cindex foreign keys
@@ -3972,156 +3213,140 @@ you want to get results from multiple tables from a @code{SELECT}
statement, you do this by joining tables:
@example
-SELECT * from table1,table2 where table1.id = table2.id;
+SELECT * FROM table1,table2 WHERE table1.id = table2.id;
@end example
@xref{JOIN, , @code{JOIN}}. @xref{example-Foreign keys}.
-The @code{FOREIGN KEY} syntax in MySQL exists only for compatibility
-with other SQL vendors' @code{CREATE TABLE} commands; it doesn't do
-anything. The @code{FOREIGN KEY} syntax without @code{ON DELETE ...} is
-mostly used for documentation purposes. Some ODBC applications may use this
-to produce automatic @code{WHERE} clauses, but this is usually easy to
-override. @code{FOREIGN KEY} is sometimes used as a constraint check, but
-this check is unnecessary in practice if rows are inserted into the tables in
-the right order. MySQL only supports these clauses because some
-applications require them to exist (regardless of whether or not they
-work).
-
-In MySQL, you can work around the problem of @code{ON DELETE
-...} not being implemented by adding the appropriate @code{DELETE} statement to
-an application when you delete records from a table that has a foreign key.
-In practice this is as quick (in some cases quicker) and much more portable
-than using foreign keys.
-
-In the near future we will extend the @code{FOREIGN KEY} implementation so
-that at least the information will be saved in the table specification file
-and may be retrieved by @code{mysqldump} and ODBC. At a later stage we will
-implement the foreign key constraints for application that can't easily be
-coded to avoid them.
-
-@menu
-* Broken Foreign KEY:: Reasons NOT to use foreign keys constraints
-@end menu
-
-
-@node Broken Foreign KEY, Missing Views, Missing Foreign Keys, Missing functions
-@subsubsection Reasons NOT to Use Foreign Keys constraints
+In MySQL Server 3.23.44 and up, @code{InnoDB} tables support checking of
+foreign key constraints. @xref{InnoDB}. For other table types, MySQL Server
+does parse the @code{FOREIGN KEY} syntax in @code{CREATE TABLE}
+commands, but without further action being taken.
-@cindex foreign keys, reasons not to use
+The @code{FOREIGN KEY} syntax without @code{ON DELETE ...} is mostly
+used for documentation purposes. Some ODBC applications may use this
+to produce automatic @code{WHERE} clauses, but this is usually easy to
+override. @code{FOREIGN KEY} is sometimes used as a constraint check,
+but this check is unnecessary in practice if rows are inserted into the
+tables in the right order.
+
+In MySQL Server, you can work around the problem of @code{ON DELETE ...} not
+being implemented by adding the appropriate @code{DELETE} statement to
+an application when you delete records from a table that has a foreign
+key. In practice this is as quick (in some cases quicker) and much more
+portable than using foreign keys.
+
+In MySQL Server 4.0 you can use multi-table delete to delete rows from many
+tables with one command. @xref{DELETE}.
+
+In the near future we will extend the @code{FOREIGN KEY} implementation
+so that the information will be saved in the table specification file
+and may be retrieved by @code{mysqldump} and ODBC. At a later stage we
+will implement the foreign key constraints for applications that can't
+easily be coded to avoid them.
+
+Do keep in mind that foreign keys are often misused, which can cause
+severe problems. Even when used properly, it is not a magic solution for
+the referential integrity problem, although it does make things easier
+in some cases.
-There are so many problems with foreign key constraints that we don't
-know where to start:
+Some advantages of foreign key enforcement:
@itemize @bullet
@item
-Foreign key constraints make life very complicated, because the foreign
-key definitions must be stored in a database and implementing them would
-destroy the whole ``nice approach'' of using files that can be moved,
-copied, and removed.
+Assuming proper design of the relations, foreign key constraints will
+make it more difficult for a programmer to introduce an inconsistency
+into the database.
@item
-The speed impact is terrible for @code{INSERT} and @code{UPDATE}
-statements, and in this case almost all @code{FOREIGN KEY} constraint
-checks are useless because you usually insert records in the right
-tables in the right order, anyway.
+Using cascading updates and deletes can simplify the client code.
@item
-There is also a need to hold locks on many more tables when updating one
-table, because the side effects can cascade through the entire database. It's
-MUCH faster to delete records from one table first and subsequently delete
-them from the other tables.
+Properly designed foreign key rules aid in documenting relations
+between tables.
+@end itemize
-@item
-You can no longer restore a table by doing a full delete from the table
-and then restoring all records (from a new source or from a backup).
+Disadvantages:
+@itemize @bullet
@item
-If you use foreign key constraints you can't dump and restore tables
-unless you do so in a very specific order.
+Mistakes, which are easy to make in designing key relations, can cause
+severe problems@-for example, circular rules, or the wrong combination
+of cascading deletes.
@item
-It's very easy to do ``allowed'' circular definitions that make the
-tables impossible to re-create each table with a single create statement,
-even if the definition works and is usable.
+A properly written application will make sure internally that it is
+not violating referential integrity constraints before proceding with
+a query. Thus, additional checks on the database level will only slow
+down performance for such an application.
@item
-It's very easy to overlook @code{FOREIGN KEY ... ON DELETE} rules when
-one codes an application. It's not unusual that one loses a lot of
-important information just because a wrong or misused @code{ON DELETE} rule.
+It is not uncommon for a DBA to make such a complex topology of
+relations that it becomes very difficult, and in some cases impossible,
+to back up or restore individual tables.
@end itemize
-The only nice aspect of @code{FOREIGN KEY} is that it gives ODBC and some
-other client programs the ability to see how a table is connected and to use
-this to show connection diagrams and to help in building applications.
-
-MySQL will soon store @code{FOREIGN KEY} definitions so that a
-client can ask for and receive an answer about how the original
-connection was made. The current @file{.frm} file format does not have
-any place for it. At a later stage we will implement the foreign key
-constraints for application that can't easily be coded to avoid them.
-
-@node Missing Views, Missing comments, Broken Foreign KEY, Missing functions
+@node ANSI diff Views, ANSI diff comments, ANSI diff Foreign Keys, Differences from ANSI
@subsubsection Views
@cindex views
-MySQL doesn't yet support views, but we plan to implement these
-to about 4.1.
+It is planned to implement views in MySQL Server around version 5.0.
Views are mostly useful for letting users access a set of relations as one
table (in read-only mode). Many SQL databases don't allow one to update
any rows in a view, but you have to do the updates in the separate tables.
-As MySQL is mostly used in applications and on web system where
+As MySQL Server is mostly used in applications and on web systems where
the application writer has full control on the database usage, most of
-our users haven't regarded views to be very important. (At least no one
-has been interested enough in this to be prepared to finance the
-implementation of views).
+our users haven't regarded views to be very important.
+(At least no one has been interested enough in this to be prepared to
+finance the implementation of views.)
-One doesn't need views in MySQL to restrict access to columns
-as MySQL has a very sophisticated privilege
-system. @xref{Privilege system}.
+One doesn't need views in MySQL Server to restrict access to columns,
+as MySQL Server has a very sophisticated privilege system.
+@xref{Privilege system}.
-@node Missing comments, , Missing Views, Missing functions
+@node ANSI diff comments, , ANSI diff Views, Differences from ANSI
@subsubsection @samp{--} as the Start of a Comment
@cindex comments, starting
@cindex starting, comments
-Some other SQL databases use @samp{--} to start comments. MySQL
-has @samp{#} as the start comment character, even if the @code{mysql}
-command-line tool removes all lines that start with @samp{--}.
-You can also use the C comment style @code{/* this is a comment */} with
-MySQL.
+Some other SQL databases use @samp{--} to start comments.
+MySQL Server has @samp{#} as the start comment character. You can also use
+the C comment style @code{/* this is a comment */} with MySQL Server.
@xref{Comments}.
-MySQL Version 3.23.3 and above supports the @samp{--} comment style
-only if the comment is followed by a space. This is because this
-degenerate comment style has caused many problems with automatically
-generated SQL queries that have used something like the following code,
-where we automatically insert the value of the payment for
+MySQL Server Version 3.23.3 and above support the @samp{--} comment style,
+provided the comment is followed by a space. This is because this
+comment style has caused many problems with automatically generated
+SQL queries that have used something like the following code, where
+we automatically insert the value of the payment for
@code{!payment!}:
@example
UPDATE tbl_name SET credit=credit-!payment!
@end example
-What do you think will happen when the value of @code{payment} is negative?
+Think about what happens if the value of @code{payment} is negative.
+Because @code{1--1} is legal in SQL, the consequences of allowing
+comments to start with @samp{--} are terrible.
+
+Using our implementation of this method of commenting in MySQL Server
+Version 3.23.3 and up, @code{1-- This is a comment} is actually safe.
-Because @code{1--1} is legal in SQL, we think it is terrible that
-@samp{--} means start comment.
+Another safe feature is that the @code{mysql} command-line client
+removes all lines that start with @samp{--}.
-In MySQL Version 3.23 you can, however, use:
-@code{1-- This is a comment}
-The following discussion only concerns you if you are running a MySQL
-version earlier than Version 3.23:
+The following information is relevant only if you are running a
+MySQL version earlier than 3.23.3:
-If you have a SQL program in a text file that contains @samp{--} comments
-you should use:
+If you have a SQL program in a text file that contains @samp{--}
+comments you should use:
@example
shell> replace " --" " #" < text-file-with-funny-comments.sql \
@@ -4148,149 +3373,8 @@ shell> replace " #" " --" -- text-file-with-funny-comments.sql
@end example
-@node Standards, Commit-rollback, Missing functions, Compatibility
-@subsection What Standards Does MySQL Follow?
-
-Entry level SQL92. ODBC levels 0-2.
-
-
-@node Commit-rollback, Bugs, Standards, Compatibility
-@subsection How to Cope Without @code{COMMIT}/@code{ROLLBACK}
-
-@findex COMMIT
-@findex ROLLBACK
-@cindex transaction-safe tables
-@cindex tables, updating
-@cindex updating, tables
-@cindex @code{BDB} tables
-@cindex @code{InnoDB} tables
-
-The following mostly applies only for @code{ISAM}, @code{MyISAM}, and
-@code{HEAP} tables. If you only use transaction-safe tables (@code{BDB},
-or @code{InnoDB} tables) in an an update, you can do
-@code{COMMIT} and @code{ROLLBACK} also with MySQL.
-@xref{COMMIT}.
-
-The problem with handling @code{COMMIT}-@code{ROLLBACK} efficiently with
-the above table types would require a completely different table layout
-than MySQL uses today. The table type would also need extra
-threads that do automatic cleanups on the tables, and the disk usage
-would be much higher. This would make these table types about 2-4 times
-slower than they are today.
-
-For the moment, we prefer implementing the SQL server language (something
-like stored procedures). With this you would very seldom really need
-@code{COMMIT}-@code{ROLLBACK.} This would also give much better performance.
-
-Loops that need transactions normally can be coded with the help of
-@code{LOCK TABLES}, and you don't need cursors when you can update records
-on the fly.
-
-We at TcX had a greater need for a real fast database than a 100%
-general database. Whenever we find a way to implement these features without
-any speed loss, we will probably do it. For the moment, there are many more
-important things to do. Check the TODO for how we prioritize things at
-the moment. (Customers with higher levels of support can alter this, so
-things may be reprioritized.)
-
-The current problem is actually @code{ROLLBACK}. Without
-@code{ROLLBACK}, you can do any kind of @code{COMMIT} action with
-@code{LOCK TABLES}. To support @code{ROLLBACK} with the above table
-types, MySQL would have to be changed to store all old records
-that were updated and revert everything back to the starting point if
-@code{ROLLBACK} was issued. For simple cases, this isn't that hard to do
-(the current @code{isamlog} could be used for this purpose), but it
-would be much more difficult to implement @code{ROLLBACK} for
-@code{ALTER/DROP/CREATE TABLE}.
-
-To avoid using @code{ROLLBACK}, you can use the following strategy:
-
-@enumerate
-@item
-Use @code{LOCK TABLES ...} to lock all the tables you want to access.
-@item
-Test conditions.
-@item
-Update if everything is okay.
-@item
-Use @code{UNLOCK TABLES} to release your locks.
-@end enumerate
-
-This is usually a much faster method than using transactions with possible
-@code{ROLLBACK}s, although not always. The only situation this solution
-doesn't handle is when someone kills the threads in the middle of an
-update. In this case, all locks will be released but some of the updates may
-not have been executed.
-
-You can also use functions to update records in a single operation.
-You can get a very efficient application by using the following techniques:
-
-@itemize @bullet
-@item Modify fields relative to their current value.
-@item Update only those fields that actually have changed.
-@end itemize
-
-For example, when we are doing updates to some customer information, we
-update only the customer data that has changed and test only that none of
-the changed data, or data that depend on the changed data, has changed
-compared to the original row. The test for changed data is done with the
-@code{WHERE} clause in the @code{UPDATE} statement. If the record wasn't
-updated, we give the client a message: "Some of the data you have changed
-have been changed by another user". Then we show the old row versus the new
-row in a window, so the user can decide which version of the customer record
-he should use.
-
-This gives us something that is similar to column locking but is actually
-even better, because we only update some of the columns, using values that
-are relative to their current values. This means that typical @code{UPDATE}
-statements look something like these:
-
-@example
-UPDATE tablename SET pay_back=pay_back+'relative change';
-
-UPDATE customer
- SET
- customer_date='current_date',
- address='new address',
- phone='new phone',
- money_he_owes_us=money_he_owes_us+'new_money'
- WHERE
- customer_id=id AND address='old address' AND phone='old phone';
-@end example
-
-As you can see, this is very efficient and works even if another client has
-changed the values in the @code{pay_back} or @code{money_he_owes_us} columns.
-
-@findex mysql_insert_id()
-@findex LAST_INSERT_ID()
-In many cases, users have wanted @code{ROLLBACK} and/or @code{LOCK
-TABLES} for the purpose of managing unique identifiers for some tables. This
-can be handled much more efficiently by using an @code{AUTO_INCREMENT} column
-and either the SQL function @code{LAST_INSERT_ID()} or the C API function
-@code{mysql_insert_id()}. @xref{mysql_insert_id, , @code{mysql_insert_id()}}.
-
-@cindex rows, locking
-At MySQL AB, we have never had any need for row-level locking
-because we have always been able to code around it. Some cases really need
-row locking, but they are very few. If you want row-level locking, you
-can use a flag column in the table and do something like this:
-
-@example
-UPDATE tbl_name SET row_flag=1 WHERE id=ID;
-@end example
-
-MySQL returns 1 for the number of affected rows if the row was
-found and @code{row_flag} wasn't already 1 in the original row.
-
-You can think of it as MySQL changed the above query to:
-
-@example
-UPDATE tbl_name SET row_flag=1 WHERE id=ID and row_flag <> 1;
-@end example
-
-
-@node Bugs, , Commit-rollback, Compatibility
-@subsection Known errors and design deficiencies in MySQL
+@node Bugs, , Differences from ANSI, Compatibility
+@subsection Known Errors and Design Deficiencies in MySQL
@cindex bugs, known
@cindex errors, known
@@ -4312,15 +3396,15 @@ see errors like the following in the MySQL error file:
@item
Don't execute @code{ALTER TABLE} on a @code{BDB} table on which you are
-running not completed multi-statement transactions. (The transaction
-will probably be ignored).
+running multi-statement transactions until all those transactions complete.
+(The transaction will probably be ignored.)
@item
-@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE} and @code{REPAIR TABLE} may
+@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE}, and @code{REPAIR TABLE} may
cause problems on tables for which you are using @code{INSERT DELAYED}.
@item
-Doing a @code{LOCK TABLE ..} and @code{FLUSH TABLES ..} doesn't
+Doing a @code{LOCK TABLE ...} and @code{FLUSH TABLES ...} doesn't
guarantee that there isn't a half-finished transaction in progress on the
table.
@@ -4332,34 +3416,37 @@ database if you are not using the @code{-A} option or if you are using
cache.
@item
-Th current replication protocol cannot deal with @code{LOAD DATA INFILE}
+The current replication protocol cannot deal with @code{LOAD DATA INFILE}
and line terminator characters of more than 1 character.
@end itemize
The following problems are known and will be fixed in due time:
@itemize @bullet
-@item
-For the moment @code{MATCH} only works with @code{SELECT} statements.
@item
When using @code{SET CHARACTER SET}, one can't use translated
-characters in database, table and column names.
+characters in database, table, and column names.
+
+@item
+If you have a @code{DECIMAL} column with a number stored in different
+formats (+01.00, 1.00, 01.00), @code{GROUP BY} may regard each value
+as a different value.
@item
@code{DELETE FROM merge_table} used without a @code{WHERE}
will only clear the mapping for the table, not delete everything in the
-mapped tables
+mapped tables.
@item
-You cannot build in another directory when using
+You cannot build the server in another directory when using
MIT-pthreads. Because this requires changes to MIT-pthreads, we are not
-likely to fix this.
+likely to fix this. @xref{MIT-pthreads}.
@item
@code{BLOB} values can't ``reliably'' be used in @code{GROUP BY} or
@code{ORDER BY} or @code{DISTINCT}. Only the first @code{max_sort_length}
-bytes (default 1024) are used when comparing @code{BLOB}bs in these cases.
+bytes (default 1024) are used when comparing @code{BLOB}s in these cases.
This can be changed with the @code{-O max_sort_length} option to
@code{mysqld}. A workaround for most cases is to use a substring:
@code{SELECT DISTINCT LEFT(blob,2048) FROM tbl_name}.
@@ -4370,20 +3457,21 @@ normally 64 bits long). It depends on the function which precision one
gets. The general rule is that bit functions are done with @code{BIGINT}
precision, @code{IF}, and @code{ELT()} with @code{BIGINT} or @code{DOUBLE}
precision and the rest with @code{DOUBLE} precision. One should try to
-avoid using bigger unsigned long long values than 63 bits
-(9223372036854775807) for anything else than bit fields!
+avoid using unsigned long long values if they resolve to be bigger than
+63 bits (9223372036854775807) for anything else than bit fields!
+MySQL Server 4.0 has better @code{BIGINT} handling than 3.23.
@item
All string columns, except @code{BLOB} and @code{TEXT} columns, automatically
have all trailing spaces removed when retrieved. For @code{CHAR} types this
is okay, and may be regarded as a feature according to ANSI SQL92. The bug is
-that in MySQL, @code{VARCHAR} columns are treated the same way.
+that in MySQL Server, @code{VARCHAR} columns are treated the same way.
@item
You can only have up to 255 @code{ENUM} and @code{SET} columns in one table.
@item
-@code{safe_mysqld} re-directs all messages from @code{mysqld} to the
+@code{safe_mysqld} redirects all messages from @code{mysqld} to the
@code{mysqld} log. One problem with this is that if you execute
@code{mysqladmin refresh} to close and reopen the log,
@code{stdout} and @code{stderr} are still redirected to the old log.
@@ -4393,7 +3481,7 @@ easily reclaim the space for the old log by deleting the old one and
executing @code{mysqladmin refresh}.
@item
-In the @code{UPDATE} statement, columns are updated from left to right. If
+In the @code{UPDATE} statement, columns are updated from left to right. If
you refer to an updated column, you will get the updated value instead of the
original value. For example:
@@ -4405,88 +3493,91 @@ This will update @code{KEY} with @code{2} instead of with @code{1}.
@item
You can't use temporary tables more than once in the same query.
-For example, the following doesn't work.
+For example, the following doesn't work:
@example
-select * from temporary_table, temporary_table as t2;
+mysql> SELECT * FROM temporary_table, temporary_table AS t2;
@end example
@item
-@code{RENAME} doesn't work with @code{TEMPORARY} tables.
+@code{RENAME} doesn't work with @code{TEMPORARY} tables or tables used in a
+@code{MERGE} table.
@item
-The optimizer may handle @code{DISTINCT} differently if you are using
+The optimiser may handle @code{DISTINCT} differently if you are using
'hidden' columns in a join or not. In a join, hidden columns are
counted as part of the result (even if they are not shown) while in
-normal queries hidden columns doesn't participate in the @code{DISTINCT}
+normal queries hidden columns don't participate in the @code{DISTINCT}
comparison. We will probably change this in the future to never compare
-the hidden columns when executing @code{DISTINCT}
+the hidden columns when executing @code{DISTINCT}.
An example of this is:
@example
-SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id
-DESC;
+SELECT DISTINCT mp3id FROM band_downloads
+ WHERE userid = 9 ORDER BY id DESC;
@end example
and
@example
-SELECT DISTINCT band_downloads.mp3id, FROM band_downloads,band_mp3
-WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id
-ORDER BY band_downloads.id DESC;
+SELECT DISTINCT band_downloads.mp3id
+ FROM band_downloads,band_mp3
+ WHERE band_downloads.userid = 9
+ AND band_mp3.id = band_downloads.mp3id
+ ORDER BY band_downloads.id DESC;
@end example
-In the second case you may in MySQL 3.23.x get two identical rows
-in the result set (because the hidden 'id' column may differ).
+In the second case you may in MySQL Server 3.23.x get two identical rows
+in the result set (because the hidden @code{id} column may differ).
-Note that the this only happens for queries where you don't have the
-ORDER BY columns in the result, something that is you are not allowed
+Note that this happens only for queries where you don't have the
+ORDER BY columns in the result, something that you are not allowed
to do in ANSI SQL.
@item
-Because MySQL allows you to work with table types that doesn't
-support transactions (and thus can't @code{rollback} data) some things
-behaves a little different in MySQL than in other SQL servers:
-(This is just to ensure that MySQL never need to do a rollback
-for a SQL command). This may be a little awkward at times as column
-Because MySQL allows you to work with table types that don't
+Because MySQL Server allows you to work with table types that don't
support transactions, and thus can't @code{rollback} data, some things
-behave a little differently in MySQL than in other SQL servers.
-This is just to ensure that MySQL never need to do a rollback
+behave a little differently in MySQL Server than in other SQL servers.
+This is just to ensure that MySQL Server never needs to do a rollback
for a SQL command. This may be a little awkward at times as column
values must be checked in the application, but this will actually give
-you a nice speed increase as it allows MySQL to do some
-optimizations that otherwise would be very hard to do.
+you a nice speed increase as it allows MySQL Server to do some
+optimisations that otherwise would be very hard to do.
-If you set a column to an incorrect value, MySQL will, instead of
+If you set a column to an incorrect value, MySQL Server will, instead of
doing a rollback, store the @code{best possible value} in the column:
@itemize @minus
@item
If you try to store a value outside the range in a numerical column,
-MySQL will instead store the smallest or biggest possible value in
+MySQL Server will instead store the smallest or biggest possible value in
the column.
@item
If you try to store a string that doesn't start with a number into a
-numerical column, MySQL will store 0 into it.
+numerical column, MySQL Server will store 0 into it.
@item
If you try to store @code{NULL} into a column that doesn't take
-@code{NULL} values, MySQL will store 0 or @code{''} (empty
-string) in it instead. (This behavior can, however, be changed with the
--DDONT_USE_DEFAULT_FIELDS compile option).
+@code{NULL} values, MySQL Server will store 0 or @code{''} (empty
+string) in it instead. (This behaviour can, however, be changed with the
+-DDONT_USE_DEFAULT_FIELDS compile option.)
@item
MySQL allows you to store some wrong date values into
-@code{DATE} and @code{DATETIME} columns. (Like 2000-02-31 or 2000-02-00).
-If the date is totally wrong, MySQL will store the special
+@code{DATE} and @code{DATETIME} columns (like 2000-02-31 or 2000-02-00).
+If the date is totally wrong, MySQL Server will store the special
0000-00-00 date value in the column.
@item
-If you set an @code{enum} to an unsupported value, it will be set to
-the error value 'empty string', with numeric value 0.
+If you set an @code{ENUM} column to an unsupported value, it will be set to
+the error value @code{empty string}, with numeric value 0.
+
+@item
+If you set a @code{SET} column to an unsupported value, the value will
+be ignored.
+
@end itemize
@item
@@ -4498,19 +3589,20 @@ Creation of a table of type @code{MERGE} doesn't check if the underlying
tables are of compatible types.
@item
-MySQL can't yet handle @code{NaN}, @code{-Inf} and @code{Inf}
+MySQL Server can't yet handle @code{NaN}, @code{-Inf}, and @code{Inf}
values in double. Using these will cause problems when trying to export
and import data. We should as an intermediate solution change @code{NaN} to
@code{NULL} (if possible) and @code{-Inf} and @code{Inf} to the
-Minimum respective maximum possible @code{double} value.
+minimum respective maximum possible @code{double} value.
@item
@code{LIMIT} on negative numbers are treated as big positive numbers.
+
@item
-If you use @code{ALTER TABLE} to first add an @code{UNIQUE} index to a
+If you use @code{ALTER TABLE} to first add a @code{UNIQUE} index to a
table used in a @code{MERGE} table and then use @code{ALTER TABLE} to
add a normal index on the @code{MERGE} table, the key order will be
-different for the tables if there was an old not-unique key in the
+different for the tables if there was an old key that was not unique in the
table. This is because @code{ALTER TABLE} puts @code{UNIQUE} keys before
normal keys to be able to detect duplicate keys as early as possible.
@end itemize
@@ -4530,14 +3622,14 @@ In the following case you can get a core dump:
Delayed insert handler has pending inserts to a table.
@item
-@code{LOCK table} with @code{WRITE}
+@code{LOCK table} with @code{WRITE}.
@item
-@code{FLUSH TABLES}
+@code{FLUSH TABLES}.
@end itemize
@item
-Before MySQL Version 3.23.2 an @code{UPDATE} that updated a key with
+Before MySQL Server Version 3.23.2 an @code{UPDATE} that updated a key with
a @code{WHERE} on the same key may have failed because the key was used to
search for records and the same row may have been found multiple times:
@@ -4551,58 +3643,519 @@ A workaround is to use:
mysql> UPDATE tbl_name SET KEY=KEY+1 WHERE KEY+0 > 100;
@end example
-This will work because MySQL will not use index on expressions in
+This will work because MySQL Server will not use an index on expressions in
the @code{WHERE} clause.
@item
-Before MySQL Version 3.23, all numeric types where treated as fixed-point
-fields. That means you had to specify how many decimals a floating-point
-field shall have. All results were returned with the correct number of
-decimals.
+Before MySQL Server Version 3.23, all numeric types where treated as
+fixed-point fields. That means you had to specify how many decimals
+a floating-point field shall have. All results were returned with the
+correct number of decimals.
@end itemize
For platform-specific bugs, see the sections about compiling and porting.
-@node Comparisons, TODO, Compatibility, Introduction
-@section How MySQL Compares to Other Databases
+@node TODO, Comparisons, Compatibility, Introduction
+@section MySQL and The Future (The TODO)
-@cindex databases, MySQL vs. others
-@cindex comparisons, MySQL vs. others
+@cindex ToDo list for MySQL
@menu
-* Compare mSQL:: How MySQL compares to @code{mSQL}
-* Compare PostgreSQL:: How MySQL compares with PostgreSQL
+* TODO MySQL 4.0:: Things That Should be in 4.0
+* TODO MySQL 4.1:: Things That Should be in 4.1
+* TODO future:: Things That Must be Done in the Near Future
+* TODO sometime:: Things That Have to be Done Sometime
+* TODO unplanned:: Things We Don't Plan To Do
@end menu
-This section compares MySQL to other popular databases.
+This section lists the features that we plan to implement in MySQL Server.
+
+Everything in this list is approximately in the order it will be done. If you
+want to affect the priority order, please register a license or support us and
+tell us what you want to have done more quickly. @xref{Licensing and Support}.
+
+The plan is that we in the future will support the full ANSI SQL99
+standard, but with a lot of useful extensions. The challenge is to do
+this without sacrificing the speed or compromising the code.
+
+
+@node TODO MySQL 4.0, TODO MySQL 4.1, TODO, TODO
+@subsection Things That Should be in 4.0
+
+All done. We now only do bug fixes MySQL 4.0.
+
+@node TODO MySQL 4.1, TODO future, TODO MySQL 4.0, TODO
+@subsection Things That Should be in 4.1
+
+The following features are planned for inclusion into MySQL 4.1.
+Note that because we have many developers that are working on different
+projects, there will also be many additional features. There is also a
+small chance that some of these features will be added to MySQL 4.0.
+Some of the work on MySQL 4.1 is already in progress.
+
+@itemize @bullet
+@item
+Subqueries.
+@example
+SELECT id FROM t WHERE grp IN (SELECT grp FROM g WHERE u > 100);
+@end example
+@item
+New table definition file format (@file{.frm} files). This will enable us
+to not run out of bits when adding more table options. One will still
+be able to use the old @file{.frm} file format with 4.0. All newly created
+tables will, however, use the new format.
+
+The new file format will enable us to add new column types, more options
+for keys, and possibly to store and retrieve @code{FOREIGN KEY} definitions.
+@item
+@code{SHOW COLUMNS FROM table_name} (used by @code{mysql} client to allow
+expansions of column names) should not open the table, only the
+definition file. This will require less memory and be much faster.
+@item
+Foreign keys for @code{MyISAM} tables, including cascading delete.
+@item
+Fail-safe replication.
+@item
+Replication should work with @code{RAND()} and user variables @code{@@var}.
+@item
+Online backup with very low performance penalty. The online backup will
+make it easy to add a new replication slave without taking down the
+master.
+@item
+Derived tables:
+@example
+SELECT a.col1, b.col2
+ FROM (SELECT MAX(col1) AS col1 FROM root_table) a,
+ other_table b
+ WHERE a.col1=b.col1;
+@end example
+
+This could be done by automatically creating temporary tables for the
+derived tables for the duration of the query.
+@item
+Allow @code{DELETE} on @code{MyISAM} tables to use the record cache.
+To do this, we need to update the threads record cache when we update
+the @file{.MYD} file.
+@item
+When using @code{SET CHARACTER SET} we should translate the whole query
+at once and not only strings. This will enable users to use the translated
+characters in database, table, and column names.
+@item
+Add @code{record_in_range()} method to @code{MERGE} tables to be
+able to choose the right index when there are many to choose from. We should
+also extend the info interface to get the key distribution for each index,
+if @code{analyze} is run on all subtables.
+@item
+Resolving the issue of @code{RENAME TABLE} on a table used in an active
+@code{MERGE} table possibly corrupting the table.
+@item
+A faster, smaller embedded MySQL library (compatible with the old one).
+@item
+Stable OpenSSL support (MySQL 4.0 supports rudimentary, not 100% tested,
+support for OpenSSL).
+@item
+Add support for sorting on @code{UNICODE}.
+@item
+Character set casts and syntax for handling multiple character sets.
+@item
+Help for all commands from the client.
+@item
+New faster client/server protocol which will support prepared statements,
+bound parameters, and bound result columns, binary transfer of data,
+warnings...
+@item
+Add database and real table name (in case of alias) to the MYSQL_FIELD
+structure.
+@item
+Add options to the client/server protocol to get progress notes
+for long running commands.
+@item
+Implement @code{RENAME DATABASE}. To make this safe for all table handlers,
+it should work as follows:
+@itemize @bullet
+@item
+Create the new database.
+@item
+For every table do a rename of the table to another database, as
+we do with the @code{RENAME} command.
+@item
+Drop the old database.
+@end itemize
+@item
+Add true @code{VARCHAR} support (there is already support for this in
+@code{MyISAM}).
+@item
+Optimise @code{BIT} type to take 1 bit (now @code{BIT} takes 1 char).
+@item
+New internal file interface change. This will make all file handling much
+more general and make it easier to add extensions like RAID.
+(the current implementation is a hack.)
+@item
+Better in-memory (@code{HEAP}) tables:
+@itemize @bullet
+@item
+Support for B-tree indexes
+@item
+Dynamic size rows
+@item
+Faster row handling (less copying)
+@end itemize
+@end itemize
+
+
+@node TODO future, TODO sometime, TODO MySQL 4.1, TODO
+@subsection Things That Must be Done in the Near Future
+
+@itemize @bullet
+@item
+Atomic multi-table updates:
+@example
+UPDATE items,month SET items.price=month.price
+WHERE items.id=month.id;
+@end example
+@item
+Don't allow more than a defined number of threads to run MyISAM recover
+at the same time.
+@item
+Change @code{INSERT ... SELECT} to optionally use concurrent inserts.
+@item
+Return the original field types() when doing @code{SELECT MIN(column)
+... GROUP BY}.
+@item
+Multiple result sets.
+@item
+Make it possible to specify @code{long_query_time} with a granularity
+in microseconds.
+@item
+Link the @code{myisampack} code into the server.
+@item
+Port of the MySQL code to QNX.
+@item
+Port of the MySQL code to BeOS.
+@item
+Port of the MySQL clients to LynxOS.
+@item
+Add a temporary key buffer cache during @code{INSERT/DELETE/UPDATE} so that we
+can gracefully recover if the index file gets full.
+@item
+If you perform an @code{ALTER TABLE} on a table that is symlinked to another
+disk, create temporary tables on this disk.
+@item
+Implement a @code{DATE/DATETIME} type that handles time zone information
+properly so that dealing with dates in different time zones is easier.
+@item
+FreeBSD and MIT-pthreads; do sleeping threads take CPU time?
+@item
+Check if locked threads take any CPU time.
+@item
+Fix configure so that one can compile all libraries (like @code{MyISAM})
+without threads.
+@item
+Add an option to periodically flush key pages for tables with delayed keys
+if they haven't been used in a while.
+@item
+Allow join on key parts (optimisation issue).
+@item
+@code{INSERT SQL_CONCURRENT} and @code{mysqld --concurrent-insert} to do
+a concurrent insert at the end of the file if the file is read-locked.
+@item
+Server-side cursors.
+@item
+Check if @code{lockd} works with modern Linux kernels; if not, we have
+to fix @code{lockd}! To test this, start @code{mysqld} with
+@code{--enable-locking} and run the different fork* test suits. They shouldn't
+give any errors if @code{lockd} works.
+@item
+Allow SQL variables in @code{LIMIT}, like in @code{LIMIT @@a,@@b}.
+@item
+Allow update of variables in @code{UPDATE} statements. For example:
+@code{UPDATE TABLE foo SET @@a=a+b,a=@@a, b=@@a+c}.
+@item
+Change when user variables are updated so that one can use them with
+@code{GROUP BY}, as in the following example:
+@code{SELECT id, @@a:=COUNT(*), SUM(sum_col)/@@a FROM table_name GROUP BY id}.
+@item
+Don't add automatic @code{DEFAULT} values to columns. Give an error when using
+an @code{INSERT} that doesn't contain a column that doesn't have a
+@code{DEFAULT}.
+@item
+Fix @file{libmysql.c} to allow two @code{mysql_query()} commands in a row
+without reading results or give a nice error message when one does this.
+@item
+Check why MIT-pthreads @code{ctime()} doesn't work on some FreeBSD systems.
+@item
+Add an @code{IMAGE} option to @code{LOAD DATA INFILE} to not update
+@code{TIMESTAMP} and @code{AUTO_INCREMENT} fields.
+@item
+Added @code{LOAD DATE INFILE ... UPDATE} syntax.
+@itemize @bullet
+@item
+For tables with primary keys, if the data contains the primary key,
+entries matching that primary key are updated from the remainder of the
+columns. However, columns @strong{missing} from the incoming data feed are not
+touched.
+@item
+For tables with primary keys that are missing some part of the key
+in the incoming data stream, or that have no primary key, the feed is
+treated as a @code{LOAD DATA INFILE ... REPLACE INTO} now.
+@end itemize
+@item
+Make @code{LOAD DATA INFILE} understand syntax like:
+@example
+LOAD DATA INFILE 'file_name.txt' INTO TABLE tbl_name
+ TEXT_FIELDS (text_field1, text_field2, text_field3)
+ SET table_field1=CONCAT(text_field1, text_field2),
+ table_field3=23
+ IGNORE text_field3
+@end example
+This can be used to skip over extra columns in the text file,
+or update columns based on expressions of the read data.
+@item
+@code{LOAD DATA INFILE 'file_name' INTO TABLE 'table_name' ERRORS TO err_table_name}.
+This would cause any errors and warnings to be logged into the
+@code{err_table_name} table. That table would have a structure like:
+
+@example
+line_number - line number in datafile
+error_message - the error/warning message
+and maybe
+data_line - the line from the datafile
+@end example
+@item
+Automatic output from @code{mysql} to Netscape.
+@item
+@code{LOCK DATABASES} (with various options.)
+@item
+Functions:
+ADD_TO_SET(value,set) and REMOVE_FROM_SET(value,set).
+@item
+Add use of @code{t1 JOIN t2 ON ...} and @code{t1 JOIN t2 USING ...}
+Currently, you can only use this syntax with @code{LEFT JOIN}.
+@item
+Many more variables for @code{show status}. Records reads and
+updates. Selects on 1 table and selects with joins. Mean number of
+tables in select. Number of @code{ORDER BY} and @code{GROUP BY} queries.
+@item
+If you abort @code{mysql} in the middle of a query, you should open
+another connection and kill the old running query.
+Alternatively, an attempt should be made to detect this in the server.
+@item
+Add a handler interface for table information so that you can use it as a system
+table. This would be a bit slow if you requested information about all tables,
+but very flexible. @code{SHOW INFO FROM tbl_name} for basic table information
+should be implemented.
+@item
+@code{NATURAL JOIN}.
+@item
+Allow @code{SELECT a FROM crash_me LEFT JOIN crash_me2 USING (a)}; in this
+case @code{a} is assumed to come from the @code{crash_me} table.
+@item
+Fix so that @code{ON} and @code{USING} works with the @code{JOIN}
+join type.
+@item
+Oracle-like @code{CONNECT BY PRIOR ...} to search hierarchy structures.
+@item
+@code{mysqladmin copy database new-database}; requires @code{COPY}
+command to be added to @code{mysqld}.
+@item
+Processlist should show number of queries/threads.
+@item
+@code{SHOW HOSTS} for printing information about the hostname cache.
+@item
+@code{DELETE} and @code{REPLACE} options to the @code{UPDATE} statement
+(this will delete rows when one gets a duplicate key error while updating).
+@item
+Change the format of @code{DATETIME} to store fractions of seconds.
+@item
+Add all missing ANSI92 and ODBC 3.0 types.
+@item
+Change table names from empty strings to @code{NULL} for calculated columns.
+@item
+Don't use @code{Item_copy_string} on numerical values to avoid
+number->string->number conversion in case of:
+@code{SELECT COUNT(*)*(id+0) FROM table_name GROUP BY id}
+@item
+Make it possible to use the new GNU regexp library instead of the current
+one (the GNU library should be much faster than the old one).
+@item
+Change so that @code{ALTER TABLE} doesn't abort clients
+that execute @code{INSERT DELAYED}.
+@item
+Fix so that when columns are referenced in an @code{UPDATE} clause,
+they contain the old values from before the update started.
+@item
+Add simulation of @code{pread()}/@code{pwrite()} on Windows to enable
+concurrent inserts.
+@item
+A logfile analyser that could parse out information about which tables
+are hit most often, how often multi-table joins are executed, etc. It
+should help users identify areas or table design that could be optimised
+to execute much more efficient queries.
+@item
+Add @code{SUM(DISTINCT)}.
+@item
+Add @code{ANY()}, @code{EVERY()}, and @code{SOME()} group functions. In
+ANSI SQL these work only on boolean columns, but we can extend these to
+work on any columns/expressions by applying: value == 0 -> FALSE and
+value <> 0 -> TRUE.
+@item
+Fix that the type for @code{MAX(column)} is the same as the column type:
+@example
+mysql> CREATE TABLE t1 (a DATE);
+mysql> INSERT INTO t1 VALUES (NOW());
+mysql> CREATE TABLE t2 SELECT MAX(a) FROM t1;
+mysql> SHOW COLUMNS FROM t2;
+@end example
+@item
+Come up with a nice syntax for a statement that will @code{UPDATE} the row
+if it exists and @code{INSERT} a new row if the row didn't exist
+(like @code{REPLACE} works with @code{INSERT} / @code{DELETE}).
+@end itemize
-This section has been written by the MySQL developers, so it
-should be read with that in mind. There are no factual errors contained
-in this section that we know of. If you find something which you believe
-to be an error, please contact us about it at @email{docs@@mysql.com}.
-For a list of all supported limits, functions, and types, see the
-@code{crash-me} Web page at
+@node TODO sometime, TODO unplanned, TODO future, TODO
+@subsection Things That Have to be Done Sometime
+
+@itemize @bullet
+@item
+Implement function: @code{get_changed_tables(timeout,table1,table2,...)}.
+@item
+Change reading through tables to use memmap when possible. Now only
+compressed tables use memmap.
+@item
+Make the automatic timestamp code nicer. Add timestamps to the update
+log with @code{SET TIMESTAMP=#;}.
+@item
+Use read/write mutex in some places to get more speed.
+@item
+Full foreign key support in for @code{MyISAM} tables, probably after
+the implementation of stored procedures with triggers.
+@item
+Simple views (first on one table, later on any expression).
+@item
+Automatically close some tables if a table, temporary table, or temporary files
+gets error 23 (not enough open files).
+@item
+When one finds a field=#, change all occurrences of field to #. Now this
+is only done for some simple cases.
+@item
+Change all const expressions with calculated expressions if possible.
+@item
+Optimise key = expression. At the moment only key = field or key =
+constant are optimised.
+@item
+Join some of the copy functions for nicer code.
+@item
+Change @file{sql_yacc.yy} to an inline parser to reduce its size and get
+better error messages (5 days).
+@item
+Change the parser to use only one rule per different number of arguments
+in function.
+@item
+Use of full calculation names in the order part (for ACCESS97).
+@item
+@code{MINUS}, @code{INTERSECT}, and @code{FULL OUTER JOIN}.
+(Currently @code{UNION} [in 4.0] and @code{LEFT OUTER JOIN} are supported.)
+@item
+@code{SQL_OPTION MAX_SELECT_TIME=#} to put a time limit on a query.
+@item
+Make the update log write to a database.
+@item
+Add to @code{LIMIT} to allow retrieval of data from the end of a result set.
+@item
+Alarm around client connect/read/write functions.
+@item
+Please note the changes to @code{safe_mysqld}: according to FSSTND (which
+Debian tries to follow) PID files should go into @file{/var/run/<progname>.pid}
+and log files into @file{/var/log}. It would be nice if you could put the
+"DATADIR" in the first declaration of "pidfile" and "log", so the
+placement of these files can be changed with a single statement.
+@item
+Allow a client to request logging.
+@item
+Add use of @code{zlib()} for @code{gzip}-ed files to @code{LOAD DATA INFILE}.
+@item
+Fix sorting and grouping of @code{BLOB} columns (partly solved now).
+@item
+Stored procedures. Triggers are also being looked at.
+@item
+A simple (atomic) update language that
+can be used to write loops and such in the MySQL server.
+@item
+Change to use semaphores when counting threads. One should first implement
+a semaphore library to MIT-pthreads.
+@item
+Don't assign a new @code{AUTO_INCREMENT} value when one sets a column to 0.
+Use @code{NULL} instead.
+@item
+Add full support for @code{JOIN} with parentheses.
+@item
+As an alternative for one thread/connection manage a pool of threads
+to handle the queries.
+@item
+Allow one to get more than one lock with @code{GET_LOCK}. When doing this,
+one must also handle the possible deadlocks this change will introduce.
+@end itemize
+
+Time is given according to amount of work, not real time.
+
+
+@node TODO unplanned, , TODO sometime, TODO
+@subsection Things We Don't Plan To Do
+
+@itemize @bullet
+@item
+Nothing; we aim toward full ANSI 92/ANSI 99 compliancy.
+@end itemize
+
+
+@node Comparisons, , TODO, Introduction
+@section How MySQL Compares to Other Databases
+
+@cindex databases, MySQL vs. others
+@cindex comparisons, MySQL vs. others
+
+Our users have successfully run their own benchmarks against a number
+of @code{Open Source} and traditional database servers.
+We are aware of tests against @code{Oracle} server, @code{DB/2} server,
+@code{Microsoft SQL Server}, and other commercial products.
+Due to legal reasons we are restricted from publishing some of those
+benchmarks in our reference manual.
+
+This section includes a comparison with @code{mSQL} for historical
+reasons and with @code{PostgreSQL} as it is also an @code{Open Source}
+database. If you have benchmark results that we can publish, please
+contact us at @email{benchmarks@@mysql.com}.
+
+For comparative lists of all supported functions and types as well
+as measured operational limits of many different database systems,
+see the @code{crash-me} web page at
@uref{http://www.mysql.com/information/crash-me.php}.
+@menu
+* Compare mSQL:: How MySQL compares to @code{mSQL}
+* Compare PostgreSQL:: How MySQL Compares to @code{PostgreSQL}
+@end menu
+
@node Compare mSQL, Compare PostgreSQL, Comparisons, Comparisons
@subsection How MySQL Compares to @code{mSQL}
+@cindex mSQL, MySQL vs mSQL, overview
@table @strong
@item Performance
For a true comparison of speed, consult the growing MySQL benchmark
suite. @xref{MySQL Benchmarks}.
-Because there is no thread creation overhead, a small parser, few features, and
-simple security, @code{mSQL} should be quicker at:
+Because there is no thread creation overhead, a small parser, few
+features, and simple security, @code{mSQL} should be quicker at:
@itemize @bullet
@item
-Tests that perform repeated connects and disconnects, running a very simple
-query during each connection.
+Tests that perform repeated connects and disconnects, running a very
+simple query during each connection.
@item
@code{INSERT} operations into very simple tables with few columns and keys.
@@ -4615,11 +4168,11 @@ query during each connection.
easy.)
@end itemize
-Because these operations are so simple, it is hard to be better at them when
-you have a higher startup overhead. After the connection is established,
-MySQL should perform much better.
+Because these operations are so simple, it is hard to be better at
+them when you have a higher startup overhead. After the connection
+is established, MySQL Server should perform much better.
-On the other hand, MySQL is much faster than @code{mSQL} (and
+On the other hand, MySQL Server is much faster than @code{mSQL} (and
most other SQL implementations) on the following:
@itemize @bullet
@@ -4627,11 +4180,11 @@ most other SQL implementations) on the following:
Complex @code{SELECT} operations.
@item
-Retrieving large results (MySQL has a better, faster, and safer
+Retrieving large results (MySQL Server has a better, faster, and safer
protocol).
@item
-Tables with variable-length strings, because MySQL has more efficient
+Tables with variable-length strings because MySQL Server has more efficient
handling and can have indexes on @code{VARCHAR} columns.
@item
@@ -4647,23 +4200,24 @@ Handling tables with large record lengths.
@code{SELECT} on large tables.
@item
-Handling many connections at the same time. MySQL is fully
+Handling many connections at the same time. MySQL Server is fully
multi-threaded. Each connection has its own thread, which means that
no thread has to wait for another (unless a thread is modifying
-a table another thread wants to access). In @code{mSQL}, once one connection
-is established, all others must wait until the first has finished, regardless
-of whether the connection is running a query that is short or long. When the
-first connection terminates, the next can be served, while all the others wait
-again, etc.
+a table another thread wants to access). In @code{mSQL}, once one
+connection is established, all others must wait until the first has
+finished, regardless of whether the connection is running a query
+that is short or long. When the first connection terminates, the
+next can be served, while all the others wait again, etc.
@item
Joins.
-@code{mSQL} can become pathologically slow if you change the order of tables
-in a @code{SELECT}. In the benchmark suite, a time more than 15000 times
-slower than MySQL was seen. This is due to @code{mSQL}'s lack of a
-join optimizer to order tables in the optimal order. However, if you put the
-tables in exactly the right order in @code{mSQL}2 and the @code{WHERE} is
-simple and uses index columns, the join will be relatively fast!
+@code{mSQL} can become pathologically slow if you change the order of
+tables in a @code{SELECT}. In the benchmark suite, a time more than
+15,000 times slower than MySQL Server was seen. This is due to @code{mSQL}'s
+lack of a join optimiser to order tables in the optimal order.
+However, if you put the tables in exactly the right order in
+@code{mSQL}2 and the @code{WHERE} is simple and uses index columns,
+the join will be relatively fast!
@xref{MySQL Benchmarks}.
@item
@@ -4681,15 +4235,16 @@ Using @code{TEXT} or @code{BLOB} columns.
@itemize @bullet
@item @code{GROUP BY} and @code{HAVING}.
@code{mSQL} does not support @code{GROUP BY} at all.
-MySQL supports a full @code{GROUP BY} with both @code{HAVING} and
+MySQL Server supports a full @code{GROUP BY} with both @code{HAVING} and
the following functions: @code{COUNT()}, @code{AVG()}, @code{MIN()},
-@code{MAX()}, @code{SUM()}, and @code{STD()}. @code{COUNT(*)} is optimized to
-return very quickly if the @code{SELECT} retrieves from one table, no other
-columns are retrieved, and there is no @code{WHERE} clause. @code{MIN()} and
-@code{MAX()} may take string arguments.
+@code{MAX()}, @code{SUM()}, and @code{STD()}. @code{COUNT(*)} is
+optimised to return very quickly if the @code{SELECT} retrieves from
+one table, no other columns are retrieved, and there is no
+@code{WHERE} clause. @code{MIN()} and @code{MAX()} may take string
+arguments.
@item @code{INSERT} and @code{UPDATE} with calculations.
-MySQL can do calculations in an @code{INSERT} or @code{UPDATE}.
+MySQL Server can do calculations in an @code{INSERT} or @code{UPDATE}.
For example:
@example
@@ -4697,81 +4252,79 @@ mysql> UPDATE SET x=x*10+y WHERE x<20;
@end example
@item Aliasing.
-MySQL has column aliasing.
+MySQL Server has column aliasing.
@item Qualifying column names.
-In MySQL, if a column name is unique among the tables used in a
+In MySQL Server, if a column name is unique among the tables used in a
query, you do not have to use the full qualifier.
@item @code{SELECT} with functions.
-MySQL has many functions (too many to list here; see @ref{Functions}).
+MySQL Server has many functions (too many to list here; see @ref{Functions}).
@end itemize
@item Disk Space Efficiency
That is, how small can you make your tables?
-MySQL has very precise types, so you can create tables that take
+MySQL Server has very precise types, so you can create tables that take
very little space. An example of a useful MySQL datatype is the
-@code{MEDIUMINT} that is 3 bytes long. If you have 100,000,000 records,
-saving even one byte per record is very important.
+@code{MEDIUMINT} that is 3 bytes long. If you have 100 million
+records, saving even 1 byte per record is very important.
@code{mSQL2} has a more limited set of column types, so it is
more difficult to get small tables.
@item Stability
-This is harder to judge objectively. For a discussion of MySQL
+This is harder to judge objectively. For a discussion of MySQL Server
stability, see @ref{Stability}.
We have no experience with @code{mSQL} stability, so we cannot say
anything about that.
@item Price
-Another important issue is the license. MySQL has a
-more flexible license than @code{mSQL}, and is also less expensive than
-@code{mSQL}. Whichever product you choose to use, remember to at least
-consider paying for a license or e-mail support. (You are required to get
-a license if you include MySQL with a product that you sell,
-of course.)
+Another important issue is the license. MySQL Server has a
+more flexible license than @code{mSQL}, and is also less expensive
+than @code{mSQL}. Whichever product you choose to use, remember to
+at least consider paying for a license or e-mail support.
@item Perl Interfaces
-MySQL has basically the same interfaces to Perl as @code{mSQL} with
+MySQL Server has basically the same interfaces to Perl as @code{mSQL} with
some added features.
@item JDBC (Java)
-MySQL currently has a lot of different JDBC drivers:
+MySQL Server currently has a lot of different JDBC drivers:
@itemize @bullet
@item
-The mm driver: A type 4 JDBC driver by Mark Matthews
+The mm driver: a type 4 JDBC driver by Mark Matthews
@email{mmatthew@@ecn.purdue.edu}. This is released under the LGPL.
@item
-The Resin driver. This is a commercial JDBC driver released under open
+The Resin driver: this is a commercial JDBC driver released under open
source. @uref{http://www.caucho.com/projects/jdbc-mysql/index.xtp}
@item
-The gwe driver: A Java interface by GWE technologies (not supported anymore).
+The gwe driver: a Java interface by GWE technologies (not supported anymore).
@item
-The jms driver: An improved gwe driver by Xiaokun Kelvin ZHU
+The jms driver: an improved gwe driver by Xiaokun Kelvin ZHU
@email{X.Zhu@@brad.ac.uk} (not supported anymore).
@item
-The twz driver: A type 4 JDBC driver by Terrence W. Zellers
+The twz driver: a type 4 JDBC driver by Terrence W. Zellers
@email{zellert@@voicenet.com}. This is commercial but is free for private
and educational use (not supported anymore).
@end itemize
The recommended driver is the mm driver. The Resin driver may also be
-good (at least the benchmarks looks good), but we haven't received that much
-information about this yet.
+good (at least the benchmarks look good), but we haven't received that
+much information about this yet.
-We know that @code{mSQL} has a JDBC driver, but we have too little experience
-with it to compare.
+We know that @code{mSQL} has a JDBC driver, but we have too little
+experience with it to compare.
@item Rate of Development
-MySQL has a very small team of developers, but we are quite
+MySQL Server has a small core team of developers, but we are quite
used to coding C and C++ very rapidly. Because threads, functions,
@code{GROUP BY}, and so on are still not implemented in @code{mSQL}, it
has a lot of catching up to do. To get some perspective on this, you
@@ -4781,17 +4334,17 @@ compare it with the News section of the MySQL Reference Manual
most rapidly.
@item Utility Programs
-Both @code{mSQL} and MySQL have many interesting third-party
+Both @code{mSQL} and MySQL Server have many interesting third-party
tools. Because it is very easy to port upward (from @code{mSQL} to
-MySQL), almost all the interesting applications that are available for
-@code{mSQL} are also available for MySQL.
+MySQL Server), almost all the interesting applications that are available for
+@code{mSQL} are also available for MySQL Server.
-MySQL comes with a simple @code{msql2mysql} program that fixes
-differences in spelling between @code{mSQL} and MySQL for the
+MySQL Server comes with a simple @code{msql2mysql} program that fixes
+differences in spelling between @code{mSQL} and MySQL Server for the
most-used C API functions.
For example, it changes instances of @code{msqlConnect()} to
@code{mysql_connect()}. Converting a client program from @code{mSQL} to
-MySQL usually takes a couple of minutes.
+MySQL Server usually requires only minor effort.
@end table
@menu
@@ -4808,7 +4361,7 @@ MySQL usually takes a couple of minutes.
@cindex converting, tools
@cindex tools, converting
-According to our experience, it would just take a few hours to convert tools
+According to our experience, it doesn't take long to convert tools
such as @code{msql-tcl} and @code{msqljava} that use the
@code{mSQL} C API so that they work with the MySQL C API.
@@ -4816,8 +4369,8 @@ The conversion procedure is:
@enumerate
@item
-Run the shell script @code{msql2mysql} on the source. This requires the
-@code{replace} program, which is distributed with MySQL.
+Run the shell script @code{msql2mysql} on the source. This requires
+the @code{replace} program, which is distributed with MySQL Server.
@item
Compile.
@@ -4830,25 +4383,27 @@ Differences between the @code{mSQL} C API and the MySQL C API are:
@itemize @bullet
@item
-MySQL uses a @code{MYSQL} structure as a connection type (@code{mSQL}
+MySQL Server uses a @code{MYSQL} structure as a connection type (@code{mSQL}
uses an @code{int}).
@item
@code{mysql_connect()} takes a pointer to a @code{MYSQL} structure as a
-parameter. It is easy to define one globally or to use @code{malloc()} to get
-one. @code{mysql_connect()} also takes two parameters for specifying the
-user and password. You may set these to @code{NULL, NULL} for default use.
+parameter. It is easy to define one globally or to use @code{malloc()}
+to get one. @code{mysql_connect()} also takes two parameters for
+specifying the user and password. You may set these to
+@code{NULL, NULL} for default use.
@item
-@code{mysql_error()} takes the @code{MYSQL} structure as a parameter. Just add
-the parameter to your old @code{msql_error()} code if you are porting old code.
+@code{mysql_error()} takes the @code{MYSQL} structure as a parameter.
+Just add the parameter to your old @code{msql_error()} code if you are
+porting old code.
@item
-MySQL returns an error number and a text error message for all
+MySQL Server returns an error number and a text error message for all
errors. @code{mSQL} returns only a text error message.
@item
-Some incompatibilities exist as a result of MySQL supporting
+Some incompatibilities exist as a result of MySQL Server supporting
multiple connections to the server from the same process.
@end itemize
@@ -4857,13 +4412,13 @@ multiple connections to the server from the same process.
@subsubsection How @code{mSQL} and MySQL Client/Server Communications Protocols Differ
@cindex communications protocols
-@cindex mSQL vs. MySQL
+@cindex mSQL vs. MySQL, protocol
-There are enough differences that it is impossible (or at least not easy)
-to support both.
+There are enough differences that it is impossible
+(or at least not easy) to support both.
The most significant ways in which the MySQL protocol differs
-from the @code{mSQL} protocol are listed below:
+from the @code{mSQL} protocol are listed here:
@itemize @bullet
@item
@@ -4871,15 +4426,15 @@ A message buffer may contain many result rows.
@item
The message buffers are dynamically enlarged if the query or the
-result is bigger than the current buffer, up to a configurable server and
-client limit.
+result is bigger than the current buffer, up to a configurable server
+and client limit.
@item
All packets are numbered to catch duplicated or missing packets.
@item
-All column values are sent in ASCII. The lengths of columns and rows are sent
-in packed binary coding (1, 2, or 3 bytes).
+All column values are sent in ASCII. The lengths of columns and rows
+are sent in packed binary coding (1, 2, or 3 bytes).
@item
MySQL can read in the result unbuffered (without having to store the
@@ -4893,10 +4448,6 @@ the connection.
If a connection is idle for 8 hours, the server closes the connection.
@end itemize
-@menu
-* Syntax differences:: How @code{mSQL} 2.0 SQL Syntax Differs from MySQL
-@end menu
-
@node Syntax differences, , Protocol differences, Compare mSQL
@subsubsection How @code{mSQL} 2.0 SQL Syntax Differs from MySQL
@@ -4905,23 +4456,25 @@ If a connection is idle for 8 hours, the server closes the connection.
@strong{Column types}
@table @code
-@item MySQL
+@item MySQL Server
Has the following additional types (among others;
@pxref{CREATE TABLE, , @code{CREATE TABLE}}):
@itemize @bullet
@item
+@c FIX bad lingo, needs rephrasing
@code{ENUM} type for one of a set of strings.
@item
+@c FIX bad lingo, needs rephrasing
@code{SET} type for many of a set of strings.
@item
@code{BIGINT} type for 64-bit integers.
@end itemize
@item
-MySQL also supports
+MySQL Server also supports
the following additional type attributes:
@itemize @bullet
@item
-@code{UNSIGNED} option for integer columns.
+@code{UNSIGNED} option for integer and floating-point columns.
@item
@code{ZEROFILL} option for integer columns.
@item
@@ -4932,8 +4485,8 @@ the following additional type attributes:
@code{DEFAULT} value for all columns.
@end itemize
@item mSQL2
-@code{mSQL} column types correspond to the MySQL types shown below:
-@multitable @columnfractions .15 .85
+@code{mSQL} column types correspond to the MySQL types shown in the following table:
+@multitable @columnfractions .15 .70
@item @code{mSQL} @strong{type} @tab @strong{Corresponding MySQL type}
@item @code{CHAR(len)} @tab @code{CHAR(len)}
@item @code{TEXT(len)} @tab @code{TEXT(len)}. @code{len} is the maximal length.
@@ -4951,7 +4504,7 @@ And @code{LIKE} works.
@strong{Index Creation}
@table @code
-@item MySQL
+@item MySQL Server
Indexes may be specified at table creation time with the @code{CREATE TABLE}
statement.
@item mSQL
@@ -4963,7 +4516,7 @@ Indexes must be created after the table has been created, with separate
@strong{To Insert a Unique Identifier into a Table}
@table @code
-@item MySQL
+@item MySQL Server
Use @code{AUTO_INCREMENT} as a column type
specifier.
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
@@ -4975,7 +4528,7 @@ Create a @code{SEQUENCE} on a table and select the @code{_seq} column.
@strong{To Obtain a Unique Identifier for a Row}
@table @code
-@item MySQL
+@item MySQL Server
Add a @code{PRIMARY KEY} or @code{UNIQUE} key to the table and use this.
New in Version 3.23.11: If the @code{PRIMARY} or @code{UNIQUE} key consists of only one
column and this is of type integer, one can also refer to it as
@@ -4989,7 +4542,7 @@ depending on many factors.
@strong{To Get the Time a Column Was Last Modified}
@table @code
-@item MySQL
+@item MySQL Server
Add a @code{TIMESTAMP} column to the table. This column is automatically set
to the current date and time for @code{INSERT} or @code{UPDATE} statements if
you don't give the column a value or if you give it a @code{NULL} value.
@@ -5002,20 +4555,20 @@ Use the @code{_timestamp} column.
@strong{@code{NULL} Value Comparisons}
@table @code
-@item MySQL
-MySQL follows
+@item MySQL Server
+MySQL Server follows
ANSI SQL, and a comparison with @code{NULL} is always @code{NULL}.
@item mSQL
In @code{mSQL}, @code{NULL = NULL} is TRUE. You
must change @code{=NULL} to @code{IS NULL} and @code{<>NULL} to
-@code{IS NOT NULL} when porting old code from @code{mSQL} to MySQL.
+@code{IS NOT NULL} when porting old code from @code{mSQL} to MySQL Server.
@end table
@noindent
@strong{String Comparisons}
@table @code
-@item MySQL
+@item MySQL Server
Normally, string comparisons are performed in case-independent fashion with
the sort order determined by the current character set (ISO-8859-1 Latin1 by
default). If you don't like this, declare your columns with the
@@ -5030,10 +4583,10 @@ sorting in ASCII order.
@strong{Case-insensitive Searching}
@table @code
-@item MySQL
+@item MySQL Server
@code{LIKE} is a case-insensitive or case-sensitive operator, depending on
the columns involved. If possible, MySQL uses indexes if the
-@code{LIKE} argument doesn't start with a wild-card character.
+@code{LIKE} argument doesn't start with a wildcard character.
@item mSQL
Use @code{CLIKE}.
@end table
@@ -5042,9 +4595,9 @@ Use @code{CLIKE}.
@strong{Handling of Trailing Spaces}
@table @code
-@item MySQL
+@item MySQL Server
Strips all spaces at the end of @code{CHAR} and @code{VARCHAR}
-columns. Use a @code{TEXT} column if this behavior is not desired.
+columns. Use a @code{TEXT} column if this behaviour is not desired.
@item mSQL
Retains trailing space.
@end table
@@ -5053,20 +4606,20 @@ Retains trailing space.
@strong{@code{WHERE} Clauses}
@table @code
-@item MySQL
-MySQL correctly prioritizes everything (@code{AND} is evaluated
-before @code{OR}). To get @code{mSQL} behavior in MySQL, use
-parentheses (as shown in an example below).
+@item MySQL Server
+MySQL correctly prioritises everything (@code{AND} is evaluated
+before @code{OR}). To get @code{mSQL} behaviour in MySQL Server, use
+parentheses (as shown in an example later in this section).
@item mSQL
Evaluates everything from left to right. This means that some logical
calculations with more than three arguments cannot be expressed in any
way. It also means you must change some queries when you upgrade to
-MySQL. You do this easily by adding parentheses. Suppose you
+MySQL Server. You do this easily by adding parentheses. Suppose you
have the following @code{mSQL} query:
@example
mysql> SELECT * FROM table WHERE a=1 AND b=2 OR a=3 AND b=4;
@end example
-To make MySQL evaluate this the way that @code{mSQL} would,
+To make MySQL Server evaluate this the way that @code{mSQL} would,
you must add parentheses:
@example
mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
@@ -5077,42 +4630,40 @@ mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
@strong{Access Control}
@table @code
-@item MySQL
+@item MySQL Server
Has tables to store grant (permission) options per user, host, and
database. @xref{Privileges}.
@item mSQL
Has a file @file{mSQL.acl} in which you can grant read/write privileges for
users.
-@item
@end table
@node Compare PostgreSQL, , Compare mSQL, Comparisons
-@subsection How MySQL Compares to PostgreSQL
+@subsection How MySQL Compares to @code{PostgreSQL}
@cindex PostgreSQL vs. MySQL, overview
When reading the following, please note that both products are continually
evolving. We at MySQL AB and the PostgreSQL developers are both working
-on making our respective database as good as possible, so we are both a
-serious choice to any commercial database.
+on making our respective databases as good as possible, so we are both a
+serious alternative to any commercial database.
The following comparison is made by us at MySQL AB. We have tried to be
-as accurate and fair as possible, but because we don't have a full
-knowledge of all PostgreSQL features while we know MySQL througly, we
-may have got some things wrong. We will however correct these when they
-come to our attention.
-
-We would first like to note that PostgreSQL and MySQL are both widely used
-products, but with different design goals, even if we are both striving to
-be ANSI SQL compatible. This means that for some applications MySQL is
-more suited, while for others PostgreSQL is more suited. When choosing
+as accurate and fair as possible, but although we know MySQL Server thoroughly,
+we don't have a full knowledge of all PostgreSQL features, so we may have
+got some things wrong. We will, however, correct these when they come to our
+attention.
+
+We would first like to note that PostgreSQL and MySQL Server are both widely used
+products, but with different design goals, even if we are both striving
+toward ANSI SQL compliancy. This means that for some applications MySQL Server
+is more suited, while for others PostgreSQL is more suited. When choosing
which database to use, you should first check if the database's feature set
-satisfies your application. If you need raw speed, MySQL is probably your
+satisfies your application. If you need raw speed, MySQL Server is probably your
best choice. If you need some of the extra features that only PostgreSQL
can offer, you should use @code{PostgreSQL}.
-@cindex PostgreSQL/MySQL, strategies
@menu
* MySQL-PostgreSQL goals:: MySQL and PostgreSQL development strategies
* MySQL-PostgreSQL features:: Featurewise Comparison of MySQL and PostgreSQL
@@ -5123,7 +4674,8 @@ can offer, you should use @code{PostgreSQL}.
@node MySQL-PostgreSQL goals, MySQL-PostgreSQL features, Compare PostgreSQL, Compare PostgreSQL
@subsubsection MySQL and PostgreSQL development strategies
-When adding things to MySQL we take pride to do an optimal, definite
+@cindex PostgreSQL vs. MySQL, strategies
+When adding things to MySQL Server we take pride to do an optimal, definite
solution. The code should be so good that we shouldn't have any need to
change it in the foreseeable future. We also do not like to sacrifice
speed for features but instead will do our utmost to find a solution
@@ -5136,26 +4688,26 @@ MySQL server.
We at MySQL AB believe in frequent releases to be able to push out new
features quickly to our users. Because of this we do a new small release
about every three weeks, and a major branch every year. All releases are
-throughly tested with our testing tools on a lot of different platforms.
+thoroughly tested with our testing tools on a lot of different platforms.
PostgreSQL is based on a kernel with lots of contributors. In this setup
-it makes sense to prioritize adding a lot of new features, instead of
-implementing them optimally, because one can always optimize things
+it makes sense to prioritise adding a lot of new features, instead of
+implementing them optimally, because one can always optimise things
later if there arises a need for this.
-Another big difference between MySQL and PostgreSQL is that
-nearly all of the code in the MySQL server are coded by developers that
+Another big difference between MySQL Server and PostgreSQL is that
+nearly all of the code in the MySQL server is coded by developers that
are employed by MySQL AB and are still working on the server code. The
-exceptions are the transaction engines, and the regexp library.
+exceptions are the transaction engines and the regexp library.
-This is in sharp contrast to the PostgreSQL code where the majority of
-the code is coded by a big group of people with different backgrounds.
+This is in sharp contrast to the PostgreSQL code, the majority of
+which is coded by a big group of people with different backgrounds.
It was only recently that the PostgreSQL developers announced that their
current developer group had finally had time to take a look at all
the code in the current PostgreSQL release.
-Both of the above development methods has it's own merits and drawbacks.
-We here at MySQL AB think of course that our model is better because our
+Both of the aforementioned development methods have their own merits and drawbacks.
+We here at MySQL AB think, of course, that our model is better because our
model gives better code consistency, more optimal and reusable code, and
in our opinion, fewer bugs. Because we are the authors of the MySQL server
code, we are better able to coordinate new features and releases.
@@ -5164,220 +4716,227 @@ code, we are better able to coordinate new features and releases.
@node MySQL-PostgreSQL features, MySQL-PostgreSQL benchmarks, MySQL-PostgreSQL goals, Compare PostgreSQL
@subsubsection Featurewise Comparison of MySQL and PostgreSQL
-@cindex PostgreSQL/MySQL, features
+@cindex PostgreSQL vs. MySQL, features
-On the @uref{http://www.mysql.com/information/crash-me.php, crash-me}
-page you can find a list of those database constructs and limits that
-one can detect automatically with a program. Note however that a lot of
-the numerical limits may be changed with startup options for respective
-database. The above web page is however extremely useful when you want to
-ensure that your applications works with many different databases or
-when you want to convert your application from one datbase to another.
+On the @code{crash-me} page
+(@uref{http://www.mysql.com/information/crash-me.php})
+you can find a list of those database constructs and limits that
+one can detect automatically with a program. Note, however, that a lot of
+the numerical limits may be changed with startup options for their respective
+databases. This web page is, however, extremely useful when you want to
+ensure that your applications work with many different databases or
+when you want to convert your application from one database to another.
-MySQL offers the following advantages over PostgreSQL:
+MySQL Server offers the following advantages over PostgreSQL:
@itemize @bullet
@item
-@code{MySQL} is generally much faster than PostgreSQL.
-@xref{MySQL-PostgreSQL benchmarks}.
+@code{MySQL} Server is generally much faster than PostgreSQL. MySQL
+4.0.1 also has a query cache that can boost up the query speed for
+mostly-read-only sites many times.
@item
-MySQL has a much larger user base than PostgreSQL, therefor the
-code is more tested and has historically been more stable than
-PostgreSQL. MySQL is the much more used in production
-environments than PostgreSQL, mostly thanks to that MySQL AB,
-formerly TCX DataKonsult AB, has provided top quality commercial support
-for MySQL from the day it was released, whereas until recently
-PostgreSQL was unsupported.
+MySQL has a much larger user base than PostgreSQL. Therefore, the code is
+tested more and has historically proven more stable than PostgreSQL.
+MySQL Server is used more in production environments than PostgreSQL,
+mostly thanks to the fact that MySQL AB, formerly TCX DataKonsult AB, has
+provided top-quality commercial support for MySQL Server from the day it
+was released, whereas until recently PostgreSQL was unsupported.
@item
-MySQL works better on Windows than PostgreSQL does. MySQL runs as a
-native Windows application (a service on NT/Win2000/WinXP), while
-PostgreSQL is run under the cygwin emulation. We have heard that
-PostgreSQL is not yet that stable on Windows but we haven't been able to
-verify this ourselves.
+MySQL Server works better on Windows than PostgreSQL does. MySQL Server
+runs as a native Windows application (a service on NT/2000/XP),
+while PostgreSQL is run under the @code{Cygwin} emulation. We have
+heard that PostgreSQL is not yet that stable on Windows but we haven't
+been able to verify this ourselves.
@item
MySQL has more APIs to other languages and is supported by more
existing programs than PostgreSQL. @xref{Contrib}.
@item
-MySQL works on 24/7 heavy duty systems. In most circumstances
-you never have to run any cleanups on MySQL. PostgreSQL doesn't
-yet support 24/7 systems because you have to run @code{VACUUM()}
+MySQL Server works on 24/7 heavy-duty systems. In most circumstances
+you never have to run any cleanups on MySQL Server. PostgreSQL doesn't
+yet support 24/7 systems because you have to run @code{VACUUM}
once in a while to reclaim space from @code{UPDATE} and @code{DELETE}
-commands and to perform statistics analyzes that are critical to get
-good performance with PostgreSQL. @code{VACUUM()} is also needed after
+commands and to perform statistics analyses that are critical to get
+good performance with PostgreSQL. @code{VACUUM} is also needed after
adding a lot of new rows to a table. On a busy system with lots of changes,
-@code{VACUUM()} must be run very frequently, in the worst cases even
-many times a day. During the @code{VACUUM()} run, which may take hours
-if the database is big, the database is from a production standpoint,
-practically dead. The PostgreSQL team has fixing this on their TODO,
-but we assume that this is not an easy thing to fix permanently.
+@code{VACUUM} must be run very frequently, in the worst cases even
+many times a day. During the @code{VACUUM} run, which may take hours
+if the database is big, the database is, from a production standpoint,
+practically dead. Please note: in PostgreSQL version 7.2, basic vacuuming
+no longer locks tables, thus allowing normal user access during the vacuum.
+A new @code{VACUUM FULL} command does old-style vacuum by locking the table
+and shrinking the on-disk copy of the table.
@item
-A working, tested replication feature used by sites like:
+MySQL replication has been thoroughly tested, and is used by sites like:
@itemize @minus
-@item Yahoo Finance (@uref{http://finance.yahoo.com})
+@item Yahoo Finance (@uref{http://finance.yahoo.com/})
@item Mobile.de (@uref{http://www.mobile.de/})
-@item Slashdot (@uref{http://www.slashdot.org})
+@item Slashdot (@uref{http://www.slashdot.org/})
@end itemize
@item
-Included in the MySQL distribution are two different testing suites,
-@file{mysql-test-run} and
-@uref{http://www.mysql.com/information/crash-me.php,crash-me}, as well
+Included in the MySQL distribution are two different testing suites,
+@file{mysql-test-run} and @code{crash-me}
+(@uref{http://www.mysql.com/information/crash-me.php}), as well
as a benchmark suite. The test system is actively updated with code to
-test each new feature and almost all repeatable bugs that have come to
-our attention. We test MySQL with these on a lot of platforms before
-every release. These tests are more sophisticated than anything we have
-seen from PostgreSQL, and they ensures that the MySQL is kept to a high
+test each new feature and almost all reproduceable bugs that have come to
+our attention. We test MySQL Server with these on a lot of platforms before
+every release. These tests are more sophisticated than anything we have
+seen from PostgreSQL, and they ensure that the MySQL Server is kept to a high
standard.
@item
-There are far more books in print about MySQL than about PostgreSQL.
-O'Reilly, Sams, Que, and New Riders are all major publishers with books
-about MySQL. All MySQL features are also documented in the MySQL on-line
-manual, because when a new feature is implemented, the MySQL developers
+There are far more books in print about MySQL Server than about PostgreSQL.
+O'Reilly, SAMS, Que, and New Riders are all major publishers with books
+about MySQL. All MySQL features are also documented in the MySQL online
+manual because when a new feature is implemented, the MySQL developers
are required to document it before it's included in the source.
@item
-MySQL supports more of the standard ODBC functions than @code{PostgreSQL}.
+MySQL Server supports more of the standard ODBC functions than @code{PostgreSQL}.
@item
-MySQL has a much more sophisticated @code{ALTER TABLE}.
+MySQL Server has a much more sophisticated @code{ALTER TABLE}.
@item
-MySQL has support for tables without transactions for applications that
-need all speed they can get. The tables may be memory based, @code{HEAP}
+MySQL Server has support for tables without transactions for applications that
+need all the speed they can get. The tables may be memory-based, @code{HEAP}
tables or disk based @code{MyISAM}. @xref{Table types}.
@item
-MySQL has support for two different table handlers that support
-transactions, @code{BerkeleyDB} and @code{InnoDB}. Because every
-transaction engine performs differently under different conditions, this
+MySQL Server has support for two different table handlers that support
+transactions, @code{InnoDB}, and @code{BerkeleyDB}. Because every
+transaction engine performs differently under different conditions, this
gives the application writer more options to find an optimal solution for
-his or her setup. @xref{Table types}.
+his or her setup, if need be per individual table. @xref{Table types}.
@item
@code{MERGE} tables gives you a unique way to instantly make a view over
a set of identical tables and use these as one. This is perfect for
-systems where you have log files that you order for example by month.
+systems where you have log files that you order, for example, by month.
@xref{MERGE}.
@item
The option to compress read-only tables, but still have direct access to
-the rows in the table, gives you better performance by minimizing disk
+the rows in the table, gives you better performance by minimising disk
reads. This is very useful when you are archiving things.
-@xref{myisampack}.
+@xref{myisampack, , @code{myisampack}}.
@item
-MySQL has internal support for fulltext search. @xref{Fulltext Search}.
+MySQL Server has internal support for full-text search. @xref{Fulltext Search}.
@item
-You can access many databases from the same connection (depending of course
+You can access many databases from the same connection (depending, of course,
on your privileges).
@item
-MySQL is coded from the start to be multi-threaded while PostgreSQL uses
-processes. Context switching and access to common storage areas is much
-faster between threads than between separate processes, this gives MySQL
-a big speed advantage in multi-user applications and also makes it easier
-for MySQL to take full advantage of symmetric multiprocessor (SMP) systems.
+MySQL Server is coded from the start to be multi-threaded, while
+PostgreSQL uses processes. Context switching and access to common
+storage areas is much faster between threads than between separate
+processes. This gives MySQL Server a big speed advantage in multi-user
+applications and also makes it easier for MySQL Server to take full
+advantage of symmetric multiprocessor (SMP) systems.
@item
-MySQL has a much more sophisticated privilege system than PostgreSQL.
-While PostgreSQL only supports @code{INSERT}, @code{SELECT}, and
-@code{UPDATE/DELETE} grants per user on a database or a table, MySQL allows
-you to define a full set of different privileges on database, table and
-column level. MySQL also allows you to specify the privilege on host and
-user combinations. @xref{GRANT}.
+MySQL Server has a much more sophisticated privilege system than
+PostgreSQL. While PostgreSQL only supports @code{INSERT},
+@code{SELECT}, and @code{UPDATE/DELETE} grants per user on a database or
+a table, MySQL Server allows you to define a full set of different
+privileges on the database, table, and column level. MySQL Server also
+allows you to specify the privilege on host and user combinations.
+@xref{GRANT}.
@item
-MySQL supports a compressed client/server protocol which improves
+MySQL Server supports a compressed client/server protocol which improves
performance over slow links.
@item
-MySQL employs a ``table handler'' concept, and is the only relational
-database we know of built around this concept. This allows different
-low-level table types to be swapped into the SQL engine, and each table
-type can be optimized for different performance characteristics.
+MySQL Server employs a ``table handler'' concept, and is the only relational
+database we know of built around this concept. This allows different
+low-level table types to be called from the SQL engine, and each table
+type can be optimised for different performance characteristics.
@item
-All MySQL table types (except @strong{InnoDB}) are implemented as files
-(one table per file), which makes it really easy to backup, move, delete
+All MySQL table types (except @code{InnoDB}) are implemented as files
+(one table per file), which makes it really easy to back up, move, delete,
and even symlink databases and tables, even when the server is down.
@item
-Tools to repair and optimize @strong{MyISAM} tables (the most common
+Tools to repair and optimise @code{MyISAM} tables (the most common
MySQL table type). A repair tool is only needed when a physical corruption
-of a data file happens, usually from a hardware failure. It allows a
+of a datafile happens, usually from a hardware failure. It allows a
majority of the data to be recovered.
@item
-Upgrading MySQL is painless. When you are upgrading MySQL, you don't need
-to dump/restore your data, as you have to do with most PostgreSQL upgrades.
+Upgrading MySQL Server is painless. When you are upgrading MySQL
+Server, you don't need to dump/restore your data, as you have to do with
+most PostgreSQL upgrades.
@end itemize
-Drawbacks with MySQL compared to PostgreSQL:
+Drawbacks with MySQL Server compared to PostgreSQL:
@itemize @bullet
@item
-The transaction support in MySQL is not yet as well tested as PostgreSQL's
-system.
+The transaction support in MySQL Server is not yet as well tested as
+PostgreSQL's system.
@item
-Because MySQL uses threads, which are not yet flawless on many OSes, one
-must either use binaries from @uref{http://www.mysql.com/downloads}, or
+Because MySQL Server uses threads, which are not yet flawless on many OSes, one
+must either use binaries from @uref{http://www.mysql.com/downloads/}, or
carefully follow our instructions on
@uref{http://www.mysql.com/doc/I/n/Installing_source.html} to get an
optimal binary that works in all cases.
@item
Table locking, as used by the non-transactional @code{MyISAM} tables, is
-in many cases faster than page locks, row locks or versioning. The
-drawback however is that if one doesn't take into account how table
+in many cases faster than page locks, row locks, or versioning. The
+drawback, however, is that if one doesn't take into account how table
locks work, a single long-running query can block a table for updates
-for a long time. This can usable be avoided when designing the
+for a long time. This can usually be avoided when designing the
application. If not, one can always switch the trouble table to use one
of the transactional table types. @xref{Table locking}.
@item
-With UDF (user defined functions) one can extend MySQL with both normal
+With UDF (user-defined functions) one can extend MySQL Server with both normal
SQL functions and aggregates, but this is not yet as easy or as flexible
as in PostgreSQL. @xref{Adding functions}.
@item
-Updates and deletes that run over multiple tables is harder to do in
-MySQL. This will, hoever, be fixed in MySQL 4.0 with multi-table
-@code{DELETE} and multi-table @code{UPDATE} and in MySQL 4.1
-with subselects.
+Updates that run over multiple tables are harder to do in MySQL Server.
+This will, however, be fixed in MySQL Server 4.0.2 with multi-table
+@code{UPDATE} and in MySQL Server 4.1 with subselects. In MySQL Server
+4.0 one can use multi-table deletes to delete from many tables at the
+same time. @xref{DELETE}.
@end itemize
-PostgreSQL currently offers the following advantages over MySQL:
+PostgreSQL currently offers the following advantages over MySQL Server:
Note that because we know the MySQL road map, we have included in the
-following table the version when MySQL should support this feature.
-Unfortunately we couldn't do this for previous comparison, because we
+following table the version when MySQL Server should support this feature.
+Unfortunately we couldn't do this for previous comparisons, because we
don't know the PostgreSQL roadmap.
-@multitable @columnfractions .70 .30
+@multitable @columnfractions .30 .30
@item @strong{Feature} @tab @strong{MySQL version}
@item Subselects @tab 4.1
-@item Foreign keys @tab 4.0 and 4.1
-@item Views @tab 4.2
-@item Stored procedures @tab 4.1
-@item Extensible type system @tab Not planned
+@item Foreign keys @tab 4.1
+@item Views @tab 5.0
+@item Stored procedures @tab 5.0
+@item Triggers @tab 5.0
@item Unions @tab 4.0
-@item Full join @tab 4.0 or 4.1
-@item Triggers @tab 4.1
-@item Constrainst @tab 4.1
-@item Cursors @tab 4.1 or 4.2
-@item Extensible index types like R-trees @tab R-trees are planned for 4.2
+@item Full join @tab 4.1
+@item Constraints @tab 4.1 or 5.0
+@item Cursors @tab 4.1 or 5.0
+@item R-trees @tab 4.1 (for MyISAM tables)
@item Inherited tables @tab Not planned
+@item Extensible type system @tab Not planned
@end multitable
-Other reasons to use PostgreSQL:
+Other reasons someone may consider using PostgreSQL:
@itemize @bullet
@item
@@ -5387,14 +4946,27 @@ Standard usage in PostgreSQL is closer to ANSI SQL in some cases.
One can speed up PostgreSQL by coding things as stored procedures.
@item
+For geographical data, R-trees make PostgreSQL better than MySQL Server.
+(note: MySQL version 4.1 will have R-trees for MyISAM tables).
+
+@item
+The PostgreSQL optimiser can do some optimisation that the current MySQL
+optimiser can't do. Most notable is doing joins when you don't have the
+proper keys in place and doing a join where you are using different keys
+combined with OR. The MySQL benchmark suite at
+@uref{http://www.mysql.com/information/benchmarks.html} shows you what
+kind of constructs you should watch out for when using different
+databases.
+
+@item
PostgreSQL has a bigger team of developers that contribute to the server.
@end itemize
-Drawbacks with PostgreSQL compared to MySQL:
+Drawbacks with PostgreSQL compared to MySQL Server:
@itemize @bullet
@item
-@code{VACUUM()} makes PostgreSQL hard to use in a 24/7 environment.
+@code{VACUUM} makes PostgreSQL hard to use in a 24/7 environment.
@item
Only transactional tables.
@@ -5406,128 +4978,124 @@ Much slower @code{INSERT}, @code{DELETE}, and @code{UPDATE}.
For a complete list of drawbacks, you should also examine the first table
in this section.
-@menu
-* MySQL-PostgreSQL benchmarks:: Benchmarking MySQL and PostgreSQL
-@end menu
-
@node MySQL-PostgreSQL benchmarks, , MySQL-PostgreSQL features, Compare PostgreSQL
@subsubsection Benchmarking MySQL and PostgreSQL
@cindex PostgreSQL vs. MySQL, benchmarks
-The only open source benchmark that we know of that can be used to
-benchmark MySQL and PostgreSQL (and other databases) is our own. It can
+The only @code{Open Source} benchmark that we know of that can be used to
+benchmark MySQL Server and PostgreSQL (and other databases) is our own. It can
be found at @uref{http://www.mysql.com/information/benchmarks.html}.
We have many times asked the PostgreSQL developers and some PostgreSQL
users to help us extend this benchmark to make it the definitive benchmark
for databases, but unfortunately we haven't gotten any feedback for this.
-We the MySQL developers have, because of this, spent a lot of hours to get
-maximum performance from PostgreSQL for the benchmarks, but because we
-don't know PostgreSQL intimately, we are sure that there are things that
-we have missed. We have on the benchmark page documented exactly how we
+We, the MySQL developers, have, because of this, spent a lot of hours to get
+maximum performance from PostgreSQL for the benchmarks, but because we
+don't know PostgreSQL intimately, we are sure that there are things that
+we have missed. We have on the benchmark page documented exactly how we
did run the benchmark so that it should be easy for anyone to repeat and
verify our results.
The benchmarks are usually run with and without the @code{--fast} option.
When run with @code{--fast} we are trying to use every trick the server can
do to get the code to execute as fast as possible. The idea is that the
-normal run should show how the server would work in a default setup and
-the @code{--fast} run shows how the server would do if the application
+normal run should show how the server would work in a default setup and
+the @code{--fast} run shows how the server would do if the application
developer would use extensions in the server to make his application run
faster.
-When running with PostgreSQL and @code{--fast} we do a @code{VACUUM()}
+When running with PostgreSQL and @code{--fast} we do a @code{VACUUM}
after every major table @code{UPDATE} and @code{DROP TABLE} to make the
database in perfect shape for the following @code{SELECT}s. The time for
-@code{VACUUM()} is measured separately.
+@code{VACUUM} is measured separately.
When running with PostgreSQL 7.1.1 we could, however, not run with
@code{--fast} because during the @code{INSERT} test, the postmaster (the
PostgreSQL deamon) died and the database was so corrupted that it was
impossible to restart postmaster. After this happened twice, we decided
-to postpone the @code{--fast} test until next PostgreSQL release. The
-details about the machine we run the benchmark can be found on the
+to postpone the @code{--fast} test until the next PostgreSQL release. The
+details about the machine we run the benchmark on can be found on the
benchmark page.
Before going to the other benchmarks we know of, we would like to give
-some background on benchmarks:
+some background on benchmarks.
-It's very easy to write a test that shows ANY database to be best
+It's very easy to write a test that shows @strong{any} database to be the best
database in the world, by just restricting the test to something the
-database is very good at and not test anything that the database is not
-good at. If one after this publishes the result with a single figure,
-things are even easier.
+database is very good at and not testing anything that the database is
+not good at. If one, after doing this, summarises the result as
+a single figure, things are even easier.
-This would be like us measuring the speed of MySQL compared to PostgreSQL
+This would be like us measuring the speed of MySQL Server compared to PostgreSQL
by looking at the summary time of the MySQL benchmarks on our web page.
-Based on this MySQL would be more than 40 times faster than PostgreSQL,
-something that is of course not true. We could make things even worse
-by just taking the test where PostgreSQL performs worst and claim that
-MySQL is more than 2000 times faster than PostgreSQL.
+Based on this MySQL Server would be more than 40 times faster than PostgreSQL,
+something that is, of course, not true. We could make things even worse
+by just taking the test where PostgreSQL performs worst and claim that
+MySQL Server is more than 2000 times faster than PostgreSQL.
-The case is that MySQL does a lot of optimizations that PostgreSQL
-doesn't do. This is of course also true the other way around. An SQL
-optimizer is a very complex thing, and a company could spend years on
-just making the optimizer faster and faster.
+The case is that MySQL does a lot of optimisations that PostgreSQL
+doesn't do. This is, of course, also true the other way around. An SQL
+optimiser is a very complex thing, and a company could spend years
+just making the optimiser faster and faster.
When looking at the benchmark results you should look for things that
you do in your application and just use these results to decide which
database would be best suited for your application. The benchmark
-results also shows things a particular database is not good at and should
+results also show things a particular database is not good at and should
give you a notion about things to avoid and what you may have to do in
other ways.
-We know of two benchmark tests that claims that PostgreSQL performs better
-than MySQL. These both where multi-user tests, a test that we here at
-MySQL AB haven't had time to write and include in the benchmark suite,
-mainly because it's a big task to do this in a manner that is fair against
+We know of two benchmark tests that claim that PostgreSQL performs better
+than MySQL Server. These both where multi-user tests, a test that we here at
+MySQL AB haven't had time to write and include in the benchmark suite,
+mainly because it's a big task to do this in a manner that is fair to
all databases.
-One is the benchmark paid for by Great Bridge, which you can read about at:
-@uref{http://www.greatbridge.com/about/press.php?content_id=4}.
-
-This is the probably worst benchmark we have ever seen anyone conduct. This
-was not only tuned to only test what PostgreSQL is absolutely best at, it
-was also totally unfair against every other database involved in the test.
+One is the benchmark paid for by Great Bridge, the company that for 16 months
+attempted to build a business based on PostgreSQL but now has ceased
+operations. This is probably the worst benchmark we have ever seen anyone
+conduct. This was not only tuned to only test what PostgreSQL is absolutely
+best at, but it was also totally unfair to every other database involved in
+the test.
-@strong{NOTE}: We know that not even some of the main PostgreSQL
-developers did like the way Great Bridge conducted the benchmark, so we
-don't blame them for the way the benchmark was made.
+@strong{Note}: We know that even some of the main PostgreSQL
+developers did not like the way Great Bridge conducted the benchmark, so we
+don't blame the PostgreSQL team for the way the benchmark was done.
-This benchmark has been condemned in a lot of postings and newsgroups so
-we will here just shortly repeat some things that where wrong with it.
+This benchmark has been condemned in a lot of postings and newsgroups, so
+here we will just briefly repeat some things that were wrong with it.
@itemize @bullet
@item
-The tests were run with an expensive commercial tool, that makes it
-impossible for an open source company like us to verify the benchmarks,
+The tests were run with an expensive commercial tool that makes it
+impossible for an @code{Open Source} company like us to verify the benchmarks,
or even check how the benchmarks were really done. The tool is not even
a true benchmark tool, but an application/setup testing tool. To refer
-this as a ``standard'' benchmark tool is to stretch the truth a long way.
+to this as a ``standard'' benchmark tool is to stretch the truth a long way.
@item
-Great Bridge admitted that they had optimized the PostgreSQL database
-(with @code{VACUUM()} before the test) and tuned the startup for the tests,
-something they hadn't done for any of the other databases involved. To
-say ``This process optimizes indexes and frees up disk space a bit. The
-optimized indexes boost performance by some margin.'' Our benchmarks
+Great Bridge admitted that they had optimised the PostgreSQL database
+(with @code{VACUUM} before the test) and tuned the startup for the tests,
+something they hadn't done for any of the other databases involved. They
+say ``This process optimises indexes and frees up disk space a bit. The
+optimised indexes boost performance by some margin.'' Our benchmarks
clearly indicate that the difference in running a lot of selects on a
-database with and without @code{VACUUM()} can easily differ by a factor
-of ten.
+database with and without @code{VACUUM} can easily differ by a factor
+of 10.
@item
The test results were also strange. The AS3AP test documentation
-mentions that the test does ``selections, simple joins, projections,
-aggregates, one-tuple updates, and bulk updates''.
-
-PostgreSQL is good at doing @code{SELECT}s and @code{JOIN}s (especially
-after a @code{VACUUM()}), but doesn't perform as well on @code{INSERT}s or
-@code{UPDATE}s. The benchmarks seem to indicate that only @code{SELECT}s
-were done (or very few updates). This could easily explain they good results
-for PostgreSQL in this test. The bad results for MySQL will be obvious a
+mentions that the test does ``selections, simple joins, projections,
+aggregates, one-tuple updates, and bulk updates.''
+
+PostgreSQL is good at doing @code{SELECT}s and @code{JOIN}s (especially
+after a @code{VACUUM}), but doesn't perform as well on @code{INSERT}s or
+@code{UPDATE}s. The benchmarks seem to indicate that only @code{SELECT}s
+were done (or very few updates). This could easily explain the good results
+for PostgreSQL in this test. The bad results for MySQL will be obvious a
bit down in this document.
@item
@@ -5539,80 +5107,80 @@ database itself.
@item
When running the database against Oracle and MS-SQL (Great Bridge has
-indirectly indicated that the databases they used in the test), they
-didn't use the native protocol but instead ODBC. Anyone that has ever
-used Oracle knows that all real application uses the native interface
+indirectly indicated the databases they used in the test), they
+didn't use the native protocol but instead ODBC. Anyone that has ever
+used Oracle knows that all real applications use the native interface
instead of ODBC. Doing a test through ODBC and claiming that the results
had anything to do with using the database in a real-world situation can't
be regarded as fair. They should have done two tests with and without ODBC
-to provide the right facts (after having got experts to tune all involved
-databases of course).
+to provide the right facts (after having gotten experts to tune all involved
+databases, of course).
@item
They refer to the TPC-C tests, but they don't mention anywhere that the
test they did was not a true TPC-C test and they were not even allowed to
call it a TPC-C test. A TPC-C test can only be conducted by the rules
-approved by the TPC Council (@uref{http://www.tpc.org}). Great Bridge
+approved by the TPC Council (@uref{http://www.tpc.org/}). Great Bridge
didn't do that. By doing this they have both violated the TPC trademark
-and miscredited their own benchmarks. The rules set by the TPC Council
+and miscredited their own benchmarks. The rules set by the TPC Council
are very strict to ensure that no one can produce false results or make
-unprovable statements. Apparently Great Bridge wasn't interested in
+unprovable statements. Apparently Great Bridge wasn't interested in
doing this.
@item
After the first test, we contacted Great Bridge and mentioned to them
-some of the obvious mistakes they had done with MySQL:
+some of the obvious mistakes they had done with MySQL Server:
@itemize @minus
@item
Running with a debug version of our ODBC driver
@item
-Running on a Linux system that wasn't optimized for threads
+Running on a Linux system that wasn't optimised for threads
@item
Using an old MySQL version when there was a recommended newer one available
@item
-Not starting MySQL with the right options for heavy multi-user use (the
-default installation of MySQL is tuned for minimal resource use).
+Not starting MySQL Server with the right options for heavy multi-user use (the
+default installation of MySQL Server is tuned for minimal resource use)
@end itemize
-Great Bridge did run a new test, with our optimized ODBC driver and with
-better startup options for MySQL, but refused to either use our updated
+Great Bridge did run a new test, with our optimised ODBC driver and with
+better startup options for MySQL Server, but refused to either use our updated
glibc library or our standard binary (used by 80% of our users), which was
statically linked with a fixed glibc library.
According to what we know, Great Bridge did nothing to ensure that the
other databases were set up correctly to run well in their test
-environment. We are sure however that they didn't contact Oracle or
-Microsoft to ask for their advice in this matter ;)
+environment. We are sure, however, that they didn't contact Oracle or
+Microsoft to ask for their advice in this matter. ;)
@item
The benchmark was paid for by Great Bridge, and they decided to publish
only partial, chosen results (instead of publishing it all).
@end itemize
-Tim Perdue, a long time PostgreSQL fan and a reluctant MySQL user
-published a comparison on
-@uref{http://www.phpbuilder.com/columns/tim20001112.php3,phpbuider}.
+Tim Perdue, a long-time PostgreSQL fan and a reluctant MySQL user,
+published a comparison on PHPbuilder
+(@uref{http://www.phpbuilder.com/columns/tim20001112.php3}).
When we became aware of the comparison, we phoned Tim Perdue about this
because there were a lot of strange things in his results. For example,
-he claimed that MySQL had a problem with five users in his tests, when we
+he claimed that MySQL Server had a problem with five users in his tests, when we
know that there are users with similar machines as his that are using
-MySQL with 2000 simultaneous connections doing 400 queries per second.
+MySQL Server with 2000 simultaneous connections doing 400 queries per second.
(In this case the limit was the web bandwidth, not the database.)
It sounded like he was using a Linux kernel that either had some
-problems with many threads, such as kernels before 2.4, which had a problem
+problems with many threads, such as kernels before 2.4, which had a problem
with many threads on multi-CPU machines. We have documented in this manual
how to fix this and Tim should be aware of this problem.
The other possible problem could have been an old glibc library and
that Tim didn't use a MySQL binary from our site, which is linked with
-a corrected glibc library, but had compiled a version of his own with.
-In any of the above cases, the symptom would have been exactly what Tim
+a corrected glibc library, but had compiled a version of his own.
+In any of these cases, the symptom would have been exactly what Tim
had measured.
We asked Tim if we could get access to his data so that we could repeat
@@ -5620,536 +5188,46 @@ the benchmark and if he could check the MySQL version on the machine to
find out what was wrong and he promised to come back to us about this.
He has not done that yet.
-Because of this we can't put any trust in this benchmark either :(
+Because of this we can't put any trust in this benchmark either. :(
-Over time things also changes and the above benchmarks are not that
-relevant anymore. MySQL now have a couple of different table handlers
+Over time things also change and the preceding benchmarks are not that
+relevant anymore. MySQL Server now has a couple of different table handlers
with different speed/concurrency tradeoffs. @xref{Table types}. It
would be interesting to see how the above tests would run with the
-different transactional table types in MySQL. PostgreSQL has of course
-also got new features since the test was made. As the above test are
+different transactional table types in MySQL Server. PostgreSQL
+has, of course,
+also got new features since the test was made. As these tests are
not publicly available there is no way for us to know how the
-database would preform in the same tests today.
+database would perform in the same tests today.
Conclusion:
The only benchmarks that exist today that anyone can download and run
-against MySQL and PostgreSQL is the MySQL benchmarks. We here at MySQL
-believe that open source databases should be tested with open source tools!
-This is the only way to ensure that no one does tests that nobody can
-reproduce and use this to claim that a database is better than another.
+against MySQL Server and PostgreSQL are the MySQL benchmarks.
+We here at MySQL AB
+believe that @code{Open Source} databases should be tested with @code{Open Source} tools!
+This is the only way to ensure that no one does tests that nobody can
+reproduce and use this to claim that one database is better than another.
Without knowing all the facts it's impossible to answer the claims of the
tester.
The thing we find strange is that every test we have seen about
PostgreSQL, that is impossible to reproduce, claims that PostgreSQL is
better in most cases while our tests, which anyone can reproduce,
-clearly shows otherwise. With this we don't want to say that PostgreSQL
-isn't good at many things (it is!) or that it isn't faster than MySQL
+clearly show otherwise. With this we don't want to say that PostgreSQL
+isn't good at many things (it is!) or that it isn't faster than MySQL Server
under certain conditions. We would just like to see a fair test where
-they are very good so that we could get some friendly competition going!
+PostgreSQL performs very well, so that we could get some friendly
+competition going!
-For more information about our benchmarks suite @xref{MySQL Benchmarks}.
+For more information about our benchmark suite, see @ref{MySQL Benchmarks}.
-We are working on an even better benchmark suite, including multi user
+We are working on an even better benchmark suite, including multi-user
tests, and a better documentation of what the individual tests really
do and how to add more tests to the suite.
-@node TODO, , Comparisons, Introduction
-@section MySQL and the future (The TODO)
-
-@cindex ToDo list for MySQL
-
-@menu
-* TODO MySQL 4.0:: Things that should be in Version 4.0
-* TODO future:: Things that must be done in the near future
-* TODO sometime:: Things that have to be done sometime
-* TODO unplanned:: Some things we don't have any plans to do
-@end menu
-
-This appendix lists the features that we plan to implement in MySQL.
-
-Everything in this list is approximately in the order it will be done. If you
-want to affect the priority order, please register a license or support us and
-tell us what you want to have done more quickly. @xref{Licensing and Support}.
-
-The plan is that we in the future will support the full ANSI SQL99
-standard, but with a lot of useful extensions. The challenge is to do
-this without sacrifying the speed or compromise the code.
-
-
-@node TODO MySQL 4.0, TODO future, TODO, TODO
-@subsection Things that should be in 4.0
-
-We plan to make MySQL Version 4.0 a ``quick'' release where we only
-add some new stuff to enable others to help us with developing new features
-into Version 4.1. The MySQL 4.0 version should only take us about
-a month to make after which we want to stabilize it and start working on
-Version 4.1. Version 4.0 should have the following new features:
-
-The news section for 4.0 includes a list of the features we have already
-implemented in the 4.0 tree. @xref{News-4.0.x}.
-
-@itemize @bullet
-@item
-New table definition file format (@code{.frm} files) This will enable us
-to not run out of bits when adding more table options. One will still
-be able to use the old @code{.frm} file format with 4.0. All newly created
-tables will, however, use the new format.
-
-The new file format will enable us to add new column types, more options
-for keys and @code{FOREIGN KEY} support.
-@item
-@code{mysqld} as a library. This will have the same interface as the
-standard MySQL client (with an extra function to just set up
-startup parameters) but will be faster (no TCP/IP or socket overhead),
-smaller and much easier to use for embedded products.
-
-One will be able to define at link time if one wants to use the
-client/server model or a stand-alone application just by defining which
-library to link with.
-
-The @code{mysqld} will support all standard MySQL features and
-one can use it in a threaded client to run different queries in each
-thread.
-@item
-Replication should work with @code{RAND()} and user variables @code{@@var}.
-@item
-Online backup with very low performance penalty. The online backup will
-make it easy to add a new replication slave without taking down the
-master.
-@item
-@code{DELETE FROM table_name} will return the number of deleted rows. For
-fast execution one should use @code{TRUNCATE table_name}.
-@item
-Allow @code{DELETE} on @code{MyISAM} tables to use the record cache.
-To do this, we need to update the threads record cache when we update
-the @code{.MYD} file.
-@item
-Better replication.
-@item
-More functions for full-text search.
-@xref{Fulltext Features to Appear in MySQL 4.0}.
-@item
-Character set casts and syntax for handling multiple character sets.
-@item
-Allow users to change startup options without taking down the server.
-@item
-Help for all commands from the client.
-@item
-Secure connections (with SSL).
-@item
-Extend the optimizer to be able to optimize some @code{ORDER BY key_name DESC}
-queries.
-@item
-@code{SHOW COLUMNS FROM table_name} (used by @code{mysql} client to allow
-expansions of column names) should not open the table, but only the
-definition file. This will require less memory and be much faster.
-@item
-New key cache
-@item
-When using @code{SET CHARACTER SET} we should translate the whole query
-at once and not only strings. This will enable users to use the translated
-characters in database, table and column names.
-@item
-Add a portable interface over @code{gethostbyaddr_r()} so that we can change
-@code{ip_to_hostname()} to not block other threads while doing DNS lookups.
-@item
-Add @code{record_in_range()} method to @code{MERGE} tables to be
-able to choose the right index when there is many to choose from. We should
-also extend the info interface to get the key distribution for each index,
-of @code{analyze} is run on all sub tables.
-@item
-@code{SET SQL_DEFAULT_TABLE_TYPE=[MyISAM | INNODB | BDB | HEAP]}.
-@end itemize
-
-
-@node TODO future, TODO sometime, TODO MySQL 4.0, TODO
-@subsection Things that must be done in the real near future
-
-@itemize @bullet
-@item
-Fail safe replication.
-@item
-Subqueries.
-@code{select id from t where grp in (select grp from g where u > 100)}
-@item
-Derived tables.
-@example
-select a.col1, b.col2 from (select max(col1) as col1 from root_table ) a,
-other_table b where a.col1=b.col1
-@end example
-
-This could be done by automatically creating temporary tables for the
-derived tables for the duration of the query.
-@item
-Add @code{PREPARE} of statements and sending of parameters to @code{mysqld}.
-@item
-Extend the server/client protocol to support warnings.
-@item
-Add options to the server/protocol protocol to get progress notes
-for long running commands.
-@item
-Add database and real table name (in case of alias) to the MYSQL_FIELD
-structure.
-@item
-Don't allow more than a defined number of threads to run MyISAM recover
-at the same time.
-@item
-Change @code{INSERT ... SELECT} to optionally use concurrent inserts.
-@item
-Implement @code{RENAME DATABASE}. To make this safe for all table handlers,
-it should work as follows:
-@itemize @bullet
-@item
-Create the new database.
-@item
-For every table do a rename of the table to another database, as
-we do with the @code{RENAME} command.
-@item
-Drop the old database.
-@end itemize
-@item
-Return the original field types() when doing @code{SELECT MIN(column)
-... GROUP BY}.
-@item
-Multiple result sets.
-@item
-Change the protocol to allow binary transfer of values. To do this
-efficiently, we need to add an API to allow binding of variables.
-@item
-Make it possible to specify @code{long_query_time} with a granularity
-in microseconds.
-@item
-Add a configurable prompt to the @code{mysql} command line client, with
-options like database in use, time and date...
-@item
-Add range checking to @code{MERGE} tables.
-@item
-Link the @code{myisampack} code into the server.
-@item
-Port of MySQL to BeOS.
-@item
-Port of the MySQL clients to LynxOS.
-@item
-Add a temporary key buffer cache during @code{INSERT/DELETE/UPDATE} so that we
-can gracefully recover if the index file gets full.
-@item
-If you perform an @code{ALTER TABLE} on a table that is symlinked to another
-disk, create temporary tables on this disk.
-@item
-Implement a @code{DATE/DATETIME} type that handles time zone information
-properly, so that dealing with dates in different time zones is easier.
-@item
-FreeBSD and MIT-pthreads; Do sleeping threads take CPU?
-@item
-Check if locked threads take any CPU.
-@item
-Fix configure so that one can compile all libraries (like @code{MyISAM})
-without threads.
-@item
-Add an option to periodically flush key pages for tables with delayed keys
-if they haven't been used in a while.
-@item
-Allow join on key parts (optimization issue).
-@item
-@code{INSERT SQL_CONCURRENT} and @code{mysqld --concurrent-insert} to do
-a concurrent insert at the end of the file if the file is read-locked.
-@item
-Remember @code{FOREIGN} key definitions in the @file{.frm} file.
-@item
-Cascading @code{DELETE}
-@item
-Server side cursors.
-@item
-Check if @code{lockd} works with modern Linux kernels; If not, we have
-to fix @code{lockd}! To test this, start @code{mysqld} with
-@code{--enable-locking} and run the different fork* test suits. They shouldn't
-give any errors if @code{lockd} works.
-@item
-Allow SQL variables in @code{LIMIT}, like in @code{LIMIT @@a,@@b}.
-@item
-Allow update of variables in @code{UPDATE} statements. For example:
-@code{UPDATE TABLE foo SET @@a=a+b,a=@@a, b=@@a+c}
-@item
-Change when user variables are updated so that one can use them with
-@code{GROUP BY}, as in the following example:
-@code{SELECT id, @@a:=count(*), sum(sum_col)/@@a FROM table_name GROUP BY id}.
-@item
-Don't add automatic @code{DEFAULT} values to columns. Give an error when using
-an @code{INSERT} that doesn't contain a column that doesn't have a
-@code{DEFAULT}.
-@item
-Caching of queries and results. This should be done as a separated
-module that examines each query and if this is query is in the cache
-the cached result should be returned. When one updates a table one
-should remove as few queries as possible from the cache.
-This should give a big speed bost on machines with much RAM where
-queries are often repeated (like WWW applications).
-One idea would be to only cache queries of type:
-@code{SELECT CACHED ...}
-@item
-Fix @file{libmysql.c} to allow two @code{mysql_query()} commands in a row
-without reading results or give a nice error message when one does this.
-@item
-Optimize @code{BIT} type to take 1 bit (now @code{BIT} takes 1 char).
-@item
-Check why MIT-pthreads @code{ctime()} doesn't work on some FreeBSD systems.
-@item
-Add an @code{IMAGE} option to @code{LOAD DATA INFILE} to not update
-@code{TIMESTAMP} and @code{AUTO_INCREMENT} fields.
-@item
-Added @code{LOAD DATE INFILE.. UPDATE} syntax.
-@itemize @bullet
-@item
-For tables with primary keys, if the data contains the primary key,
-entries matching that primary key are updated from the remainder of the
-columns. However, columns MISSING from the incoming data feed are not
-touched.
-@item
-For tables tables with primary keys that are missing some part of the key
-in the incoming data stream, or that have no primary key, the feed is
-treated as a @code{LOAD DATA INFILE ... REPLACE INTO} is now.
-@end itemize
-@item
-Make @code{LOAD DATA INFILE} understand syntax like:
-@example
-LOAD DATA INFILE 'file_name.txt' INTO TABLE tbl_name
-TEXT_FIELDS (text_field1, text_field2, text_field3)
-SET table_field1=concatenate(text_field1, text_field2), table_field3=23
-IGNORE text_field3
-
-This can be used to skip over extra columns in the text file, or update columns
-based on expressions of the read data...
-@end example
-@item
-@code{LOAD DATA INFILE 'file_name' INTO TABLE 'table_name' ERRORS TO err_table_name}
-This would cause any errors and warnings to be logged into the err_table_name
-table. That table would have a structure like:
-
-@example
-line_number - line number in data file
-error_message - the error/warning message
-and maybe
-data_line - the line from the data file
-@end example
-@item
-Add true @code{VARCHAR} support (There is already support for this in MyISAM).
-@item
-Automatic output from @code{mysql} to netscape.
-@item
-@code{LOCK DATABASES}. (with various options)
-@item
-Change sort to allocate memory in ``hunks'' to get better memory utilization.
-@item
-@code{DECIMAL} and @code{NUMERIC} types can't read exponential numbers;
-@code{Field_decimal::store(const char *from,uint len)} must be recoded
-to fix this.
-@item
-Functions:
-ADD_TO_SET(value,set) and REMOVE_FROM_SET(value,set)
-@item
-Add use of @code{t1 JOIN t2 ON ...} and @code{t1 JOIN t2 USING ...}
-Currently, you can only use this syntax with @code{LEFT JOIN}.
-@item
-Add full support for @code{unsigned long long} type.
-@item
-Many more variables for @code{show status}. Counts for:
-@code{INSERT}/@code{DELETE}/@code{UPDATE} statements. Records reads and
-updated. Selects on 1 table and selects with joins. Mean number of
-tables in select. Number of @code{ORDER BY} and @code{GROUP BY} queries.
-@item
-If you abort @code{mysql} in the middle of a query, you should open
-another connection and kill the old running query.
-Alternatively, an attempt should be made to detect this in the server.
-@item
-Add a handler interface for table information so you can use it as a system
-table. This would be a bit slow if you requested information about all tables,
-but very flexible. @code{SHOW INFO FROM tbl_name} for basic table information
-should be implemented.
-@item
-Add support for UNICODE.
-@item
-@code{NATURAL JOIN} and @code{UNION JOIN}
-@item
-Allow @code{select a from crash_me left join crash_me2 using (a)}; In this
-case a is assumed to come from the crash_me table.
-@item
-Fix that @code{ON} and @code{USING} works with the @code{JOIN}
-join type.
-@item
-Oracle like @code{CONNECT BY PRIOR ...} to search hierarchy structures.
-@item
-@code{mysqladmin copy database new-database}. -- Requires COPY command to be
-added to @code{mysqld}
-@item
-Processlist should show number of queries/thread.
-@item
-@code{SHOW HOSTS} for printing information about the hostname cache.
-@item
-@code{DELETE} and @code{REPLACE} options to the @code{UPDATE} statement
-(this will delete rows when one gets a duplicate key error while updating).
-@item
-Change the format of @code{DATETIME} to store fractions of seconds.
-@item
-Add all missing ANSI92 and ODBC 3.0 types.
-@item
-Change table names from empty strings to @code{NULL} for calculated columns.
-@item
-Don't use 'Item_copy_string' on numerical values to avoid
-number->string->number conversion in case of:
-@code{SELECT COUNT(*)*(id+0) FROM table_name GROUP BY id}
-@item
-Make it possible to use the new GNU regexp library instead of the current
-one (The GNU library should be much faster than the old one).
-@item
-Change that @code{ALTER TABLE} doesn't abort clients that executes
-@code{INSERT DELAYED}.
-@item
-Fix that when columns referenced in an @code{UPDATE} clause contains the old
-values before the update started.
-@item
-@code{myisamchk}, @code{REPAIR} and @code{OPTIMIZE TABLE} should be able
-to handle cases where the data and/or index files are symbolic links.
-@item
-Add simulation of @code{pread()}/@code{pwrite()} on Windows to enable
-concurrent inserts.
-@item
-A logfile analyzer that could parsed out information about which tables
-are hit most often, how often multi-table joins are executed, etc. It
-should help users identify areas or table design that could be optimized
-to execute much more efficient queries.
-@item
-Add @code{SUM(DISTINCT)}
-@item
-Add @code{ANY()},@code{EVERY()} and @code{SOME()} group functions. In
-ANSI SQL these only works on boolean columns, but we can extend these to
-work on any columns/expressions by applying: value == 0 -> FALSE and
-value <> 0 -> TRUE.
-@item
-Fix that the type for @code{MAX(column)} is the same as the column type.
-@example
-create table t1 (a DATE);
-insert into t1 values (now());
-create table t2 select max(a) from t1;
-show columns from t2;
-@end example
-@item
-Come up with a nice syntax for a statement that will @code{UPDATE} the row
-if it exists and @code{INSERT} a new row if the row didn't exist.
-(Like @code{REPLACE} works with @code{INSERT} / @code{DELETE})
-@end itemize
-
-
-@node TODO sometime, TODO unplanned, TODO future, TODO
-@subsection Things that have to be done sometime
-
-@itemize @bullet
-@item
-Implement function: @code{get_changed_tables(timeout,table1,table2,...)}
-@item
-Atomic multi-table updates, eg @code{update items,month set
-items.price=month.price where items.id=month.id;};
-@item
-Change reading through tables to use memmap when possible. Now only
-compressed tables use memmap.
-@item
-Add a new privilege @strong{'Show_priv'} for @code{SHOW} commands.
-@item
-Make the automatic timestamp code nicer. Add timestamps to the update
-log with @code{SET TIMESTAMP=#;}
-@item
-Use read/write mutex in some places to get more speed.
-@item
-Full foreign key support. One probably wants to implement a procedural
-language first.
-@item
-Simple views (first on one table, later on any expression).
-@item
-Automatically close some tables if a table, temporary table or temporary files
-gets error 23 (not enough open files).
-@item
-When one finds a field=#, change all occurrences of field to #. Now this
-is only done for some simple cases.
-@item
-Change all const expressions with calculated expressions if possible.
-@item
-Optimize key = expression. At the moment only key = field or key =
-constant are optimized.
-@item
-Join some of the copy functions for nicer code.
-@item
-Change @file{sql_yacc.yy} to an inline parser to reduce its size and get
-better error messages (5 days).
-@item
-Change the parser to use only one rule per different number of arguments
-in function.
-@item
-Use of full calculation names in the order part. (For ACCESS97)
-@item
-@code{UNION}, @code{MINUS}, @code{INTERSECT} and @code{FULL OUTER JOIN}.
-(Currently only @code{LEFT OUTER JOIN} is supported)
-@item
-Allow @code{UNIQUE} on fields that can be @code{NULL}.
-@item
-@code{SQL_OPTION MAX_SELECT_TIME=#} to put a time limit on a query.
-@item
-Make the update log to a database.
-@item
-Negative @code{LIMIT} to retrieve data from the end.
-@item
-Alarm around client connect/read/write functions.
-@item
-Please note the changes to @code{safe_mysqld}: according to FSSTND (which
-Debian tries to follow) PID files should go into @file{/var/run/<progname>.pid}
-and log files into @file{/var/log}. It would be nice if you could put the
-"DATADIR" in the first declaration of "pidfile" and "log", so the
-placement of these files can be changed with a single statement.
-@item
-Allow a client to request logging.
-@item
-Add use of @code{zlib()} for @code{gzip}-ed files to @code{LOAD DATA INFILE}.
-@item
-Fix sorting and grouping of @code{BLOB} columns (partly solved now).
-@item
-Stored procedures. This is currently not regarded to be very
-important as stored procedures are not very standardized yet.
-Another problem is that true stored procedures make it much harder for
-the optimizer and in many cases the result is slower than before
-We will, on the other hand, add a simple (atomic) update language that
-can be used to write loops and such in the MySQL server.
-@item
-Change to use semaphores when counting threads. One should first implement
-a semaphore library to MIT-pthreads.
-@item
-Don't assign a new @code{AUTO_INCREMENT} value when one sets a column to 0.
-Use @code{NULL} instead.
-@item
-Add full support for @code{JOIN} with parentheses.
-@item
-As an alternative for one thread / connection manage a pool of threads
-to handle the queries.
-@item
-Allow one to get more than one lock with @code{GET_LOCK}. When doing this,
-one must also handle the possible deadlocks this change will introduce.
-@end itemize
-
-Time is given according to amount of work, not real time.
-
-
-@node TODO unplanned, , TODO sometime, TODO
-@subsection Some things we don't have any plans to do
-
-@itemize @bullet
-@item
-Nothing; In the long run we plan to be fully ANSI 92 / ANSI 99 compliant.
-@end itemize
-
-
-
-
@node Installing, Tutorial, Introduction, Top
@chapter MySQL Installation
@@ -6162,6 +5240,7 @@ Nothing; In the long run we plan to be fully ANSI 92 / ANSI 99 compliant.
* Post-installation:: Post-installation setup and testing
* Upgrade:: Upgrading/Downgrading MySQL
* Operating System Specific Notes:: Operating System Specific Notes
+* Perl support:: Perl Installation Comments
@end menu
This chapter describes how to obtain and install MySQL:
@@ -6173,8 +5252,8 @@ For a list of sites from which you can obtain MySQL, see
@item
To see which platforms are supported, see @ref{Which OS}. Please note that
-not all supported system are equally good for running MySQL on them.
-On some it is much more robust and efficient than others - see @ref{Which OS}
+not all supported systems are equally good for running MySQL on them.
+On some it is much more robust and efficient than others@-see @ref{Which OS}
for details.
@item
@@ -6187,7 +5266,7 @@ use the binary distribution.
@item
Installation instructions for binary and source distributions are described
-in @ref{Installing binary} and @ref{Installing source}. Each set of
+in @ref{Installing binary}, and @ref{Installing source}. Each set of
instructions includes a section on system-specific problems you may run
into.
@@ -6220,7 +5299,7 @@ file. The MySQL RPMs are currently being built on a RedHat Version
and use @code{glibc}.
If you have problems with an RPM file, for example, if you receive the error
-``@code{Sorry, the host 'xxxx' could not be looked up}'', see
+``@code{Sorry, the host 'xxxx' could not be looked up}''@-see
@ref{Binary notes-Linux}.
The RPM files you may want to use are:
@@ -6247,7 +5326,7 @@ MySQL clients, such as the Perl modules.
@item @code{MySQL-VERSION.src.rpm}
-This contains the source code for all of the above packages. It can also
+This contains the source code for all of the previous packages. It can also
be used to try to build RPMs for other architectures (for example, Alpha
or SPARC).
@end itemize
@@ -6287,911 +5366,275 @@ installation chapter. @xref{Installing binary}.
@node Windows installation, , Linux-RPM, Quick Standard Installation
@subsection Installing MySQL on Windows
-The following instructions apply to precompiled binary distributions.
-If you download a source distribution, you will have to compile and install
-it yourself.
-
-If you don't have a copy of the MySQL distribution, you should
-first download one from @uref{http://www.mysql.com/downloads/mysql-3.23.html}.
-
-If you plan to connect to MySQL from some other program, you will
-probably also need the @strong{MyODBC} driver. You can find this at the
-@strong{MyODBC} download page
-(@uref{http://www.mysql.com/downloads/api-myodbc.html}).
-
-To install either distribution, unzip it in some empty directory and run the
-@code{Setup.exe} program.
-
-By default, MySQL-Windows is configured to be installed in
-@file{C:\mysql}. If you want to install MySQL elsewhere,
-install it in @file{C:\mysql} first, then move the installation to
-where you want it. If you do move MySQL, you must indicate
-where everything is located by supplying a @code{--basedir} option when
-you start the server. For example, if you have moved the MySQL
-distribution to @file{D:\programs\mysql}, you must start @code{mysqld}
-like this:
-
-@example
-C:\> D:\programs\mysql\bin\mysqld --basedir D:\programs\mysql
-@end example
-
-Use @code{mysqld --help} to display all the options that @code{mysqld}
-understands!
-
-With all newer MySQL versions, you can also create a
-@file{C:\my.cnf} file that holds any default options for the
-MySQL server. Copy the file @file{\mysql\my-xxxxx.cnf} to
-@file{C:\my.cnf} and edit it to suit your setup. Note that you should
-specify all paths with @samp{/} instead of @samp{\}. If you use
-@samp{\}, you need to specify it twice, because @samp{\} is the escape
-character in MySQL. @xref{Option files}.
-
-Starting with MySQL 3.23.38, the Windows distribution includes
-both the normal and the @strong{MySQL-Max} binaries. The main benefit
-of using the normal @code{mysqld.exe} binary is that it's a little
-faster and uses less resources.
-
-Here is a list of the different MySQL servers you can use:
-
-@multitable @columnfractions .25 .75
-@item @code{mysqld} @tab
-Compiled with full debugging and automatic memory allocation checking,
-symbolic links, BDB and InnoDB tables.
-@item @code{mysqld-opt} @tab
-Optimized binary with no support for transactional tables.
-@item @code{mysqld-nt} @tab
-Optimized binary for NT with support for named pipes. You can run this
-version on Win98, but in this case no named pipes are created and you must
-have TCP/IP installed.
-@item @code{mysqld-max} @tab
-Optimized binary with support for symbolic links, BDB and InnoDB tables.
-@item @code{mysqld-max-nt} @tab
-Like @code{mysqld-max}, but compiled with support for named pipes.
-@end multitable
-
-Starting from 3.23.50, named pipes are only enabled if mysqld is started with
-@code{--enable-named-pipe}.
-
-All of the above binaries are optimized for the Pentium Pro processor but
-should work on any Intel processor >= i386.
-
-NOTE: If you want to use InnoDB tables, there are certain startup
-options that must be specified in your @file{my.ini} file! @xref{InnoDB start}.
-
-
-@node General Installation Issues, Installing source, Quick Standard Installation, Installing
-@section General Installation Issues
-
-@c @node Methods of Installation, , ,
-@c @subsection Methods of Installation
-
-@c FIX: this needs to be written?
-
-@menu
-* Getting MySQL:: How to Get MySQL
-* Which OS:: Operating Systems Supported by MySQL
-* Which version:: Which MySQL Version to Use
-* Installation layouts:: Installation Layouts
-* Many versions:: How and When Updates Are Released
-* MySQL binaries:: MySQL Binaries Compiled by MySQL AB
-@end menu
-
-
-@node Getting MySQL, Which OS, General Installation Issues, General Installation Issues
-@subsection How to Get MySQL
-
-@cindex downloading
-@cindex MySQL version
-@cindex version, latest
-@cindex getting MySQL
-@cindex mirror sites
-@cindex URLS for downloading MySQL
-
-Check the @uref{http://www.mysql.com/, MySQL home page} for
-information about the current version and for downloading instructions.
-
-Our main download mirror is located at:
-
-@uref{http://download.sourceforge.net/mirrors/mysql/}
-
-If you are interested in becoming a MySQL mirror site, you may
-anonymously rsync with: @code{rsync://download.sourceforge.net/mysql/}. Please
-send e-mail to @email{webmaster@@mysql.com} notifying us of your mirror to be
-added to the list below.
-
-If you have problems downloading from our main site, try using one of the
-mirrors listed below.
-
-Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}.
-
-@c START_OF_MIRROR_LISTING
-
-@strong{Europe:}
-
-@itemize @bullet
-
-@item
-@c EMAIL: sl@iuinfo.tuwien.ac.at (Tony Sprinzl)
-@image{Flags/austria} Austria [Univ. of Technology/Vienna] @
-@uref{http://gd.tuwien.ac.at/db/mysql/, WWW}
-@uref{ftp://gd.tuwien.ac.at/db/mysql/, FTP}
-
-@c @item
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: delian@naturella.com (Delian Delchev)
-@c @image{Flags/bulgaria} Bulgaria [Naturella] @
-@c @uref{http://archive.nat.bg/pub/mirror/mysql/, WWW}
-@c @uref{ftp://ftp.ntrl.net/pub/mirror/mysql/, FTP}
-
-@item
-@c EMAIL: salle@online.bg (Admin)
-@image{Flags/bulgaria} Bulgaria [online.bg/Sofia] @
-@uref{http://mysql.online.bg/, WWW}
-@uref{ftp://mysql.online.bg/, FTP}
-
-@c @item
-@c Added: 990614
-@c Not ok 20000919; Out of date (Matt)
-@c EMAIL: vuksan@veus.hr (Vladimir Vuksan)
-@c @image{Flags/croatia} Croatia [HULK] @
-@c @uref{http://ftp.linux.hr/pub/mysql/, WWW}
-@c @uref{ftp://ftp.linux.hr/pub/mysql/, FTP}
-
-@item
-@c Added: 990614
-@c EMAIL: kas@informatics.muni.cz (Jan Kasprzak)
-@image{Flags/czech-republic} Czech Republic [Masaryk University in Brno] @
-@uref{http://mysql.linux.cz/index.html, WWW}
-@uref{ftp://ftp.fi.muni.cz/pub/mysql/, FTP}
-
-@item
-@c Added: 990920
-@c EMAIL: radek@sopik.cz (Radek Libovicky)
-@image{Flags/czech-republic} Czech Republic [www.sopik.cz] @
-@uref{http://www.mysql.cz/, WWW}
-
-@item
-@c Added: 000418
-@c EMAIL: feela@ipex.cz (Ondrej Feela Filip)
-@image{Flags/czech-republic} Czech Republic [www.gin.cz] @
-@uref{http://mysql.gin.cz/, WWW}
-@uref{ftp://ftp.gin.cz/pub/MIRRORS/www.mysql.com/, FTP}
-
-@item
-@c removed 991020 (no DNS entry). New name 991026. Added 991121
-@c Statistics at http://mirror.borsen.dk/
-@c EMAIL: guru@borsen.dk (Jesper Angelo)
-@image{Flags/denmark} Denmark [Borsen] @
-@uref{ http://mysql.borsen.dk/, WWW}
-
-@item
-@c EMAIL: mkp@socsci.auc.dk (Martin Kasper Petersen)
-@image{Flags/denmark} Denmark [SunSITE] @
-@uref{http://mirrors.sunsite.dk/mysql/, WWW}
-@uref{ftp://sunsite.dk/mirrors/mysql/, FTP}
-
-@c @item
-@c Tõnu does not work there anymore :-) 990720
-@c EMAIL: tonu@tradenet.ee (Tõnu Samuel)
-@c @image{Flags/estonia} Estonia [Tradenet] @
-@c @uref{http://mysql.tradenet.ee, WWW}
-
-@item
-@c EMAIL: tonu@spam.ee (Tõnu Samuel)
-@image{Flags/estonia} Estonia [OKinteractive] @
-@uref{http://mysql.mirror.ok.ee, WWW}
-
-@c @item
-@c Changed 990531
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: Steeve.Devergne@minet.net (Steeve Devergne)
-@c @image{Flags/france} France [minet] @
-@c @uref{http://www.minet.net/devel/mysql/, WWW}
-
-@item
-@c EMAIL: alex@mtesa.net (Alexandre Dupouy)
-@image{Flags/france} France [mtesa.net] @
-@uref{http://mysql.mtesa.net/, WWW}
-
-@item
-@c EMAIL: mrjack@fastorama.com (MrJacK)
-@image{Flags/france} France [fastorama.com, Chatenois] @
-@uref{http://mysql.fastorama.com/, WWW}
-@uref{ftp://ftp.fastorama.com/unix/mysql/, FTP}
-
-@c @item
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: Jaakko.Hyvatti@eunet.fi
-@c @image{Flags/finland} Finland [EUnet] @
-@c @uref{http://mysql.eunet.fi/, WWW}
-
-@c @item
-@c Added 990829
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: tomi.hakala@clinet.fi (Tomi Hakala)
-@c @image{Flags/finland} Finland [clinet] @
-@c @uref{ftp://ftp.clinet.fi/mirrors/ftp.mysql.org/pub/mysql/, FTP}
-
-@item
-@c Added 20001019
-@c EMAIL: d@d.tj (Dominique L . Bouix)
-@image{Flags/finland} Finland [tonnikala.net] @
-@uref{http://mysql.tonnikala.org/, WWW}
-
-@item
-@c Added 981208
-@c EMAIL: noel@uni-bonn.de (Noel Koethe)
-@image{Flags/germany} Germany [Kernelnotes.de, Bonn] @
-@uref{http://www.kernelnotes.de/mysql/, WWW}
-@uref{ftp://ftp.kernelnotes.de/pub/mirror/mysql.org/, FTP}
-
-@item
-@c EMAIL: th@rz.fh-wolfenbuettel.de (Thorsten Ludewig)
-@image{Flags/germany} Germany [Wolfenbuettel] @
-@uref{http://www.fh-wolfenbuettel.de/ftp/pub/database/mysql/, WWW}
-@uref{ftp://ftp.fh-wolfenbuettel.de/pub/database/mysql/, FTP}
-
-@c @item
-@c Ok 980114. Removed 981208 (down > 3 days) ok 981214
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: straub@gks.de (Hans-Peter Straub)
-@c @image{Flags/germany} Germany [Staufen] @
-@c @uref{http://mysql.staufen.de/, WWW}
-
-@c @item
-@c Added 990614
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: thomas.rohde@ecrc.de (Thomas Rohde)
-@c @image{Flags/germany} Germany [Cable & Wireless] @
-@c @uref{ftp://ftp.ecrc.net/pub/database/mysql/, FTP}
-
-@item
-@c Added 981208
-@c EMAIL: christias@noc.ntua.gr (Panagiotis Christias)
-@image{Flags/greece} Greece [NTUA, Athens] @
-@uref{http://www.ntua.gr/mysql/, WWW}
-@uref{ftp://ftp.ntua.gr/pub/databases/mysql/, FTP}
-
-@item
-@c EMAIL: torlasz@xenia.sote.hu (Laszlo L. Tornoc)
-@image{Flags/hungary} Hungary [Xenia] @
-@uref{http://mysql.sote.hu/, WWW}
-@uref{ftp://xenia.sote.hu/pub/mirrors/www.mysql.com/, FTP}
-
-@item
-@c EMAIL: hendlein@tiszanet.hu (Hendlein Peter)
-@image{Flags/hungary} Hungary [TiszaneT] @
-@uref{http://mysql.tiszanet.hu/, WWW}
-@uref{ftp://mysql.tiszanet.hu/pub/mirrors/mysql/, FTP}
-
-@item
-@c EMAIL: i.habencius@telnet.hu (Habencius Istvan)
-@image{Flags/hungary} Hungary [stop.hu] @
-@uref{http://mysql.mirror.stop.hu/, WWW}
-
-@item
-@c EMAIL: mirrors@gm.is (Tomas Edwardsson)
-@image{Flags/iceland} Iceland [GM] @
-@uref{http://mysql.gm.is/, WWW}
-@uref{ftp://ftp.gm.is/pub/mysql/, FTP}
-
-@c @item
-@c Out of date 990906
-@c EMAIL: bourbon@netvision.net.il (Zeev Suraski)
-@c @image{Flags/israel} Israel [Netvision] @
-@c @uref{http://mysql.netvision.net.il/, WWW}
-
-@c @item
-@c Not working 99.03.06
-@c EMAIL: maruzz@matrice.it (Giovanni Maruzzelli)
-@c @image{Flags/italy} Italy [Matrice] @
-@c @uref{http://www.matrice.it/risorse/mysql/, WWW}
-
-@item
-@c EMAIL: gabriele@feelinglinux.com (Giansante Gabriele)
-@image{Flags/italy} Italy [feelinglinux.com] @
-@uref{http://mysql.feelinglinux.com/, WWW}
-
+The MySQL server for Windows is available in two distribution types:
+@enumerate
@item
-@c EMAIL: irena@yacc.it
-@image{Flags/italy} Italy [Teta Srl] @
-@uref{http://www.teta.it/mysql/, WWW}
-
+The binary distribution contains a setup program which installs
+everything you need so that you can start the server immediately.
@item
-@c EMAIL: rudy@comm2000.it (Rudy)
-@image{Flags/italy} Italy [tzone.it] @
-@uref{http://mysql.tzone.it/, WWW}
+The source distribution contains all the code and support files
+for building the executables using the VC++ 6.0 compiler.
+@xref{Windows source build}.
+@end enumerate
-@c @item
-@c Added 991121
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: nick@iol.ie (Nick Hilliard)
-@c @image{Flags/ireland} Ireland [Ireland On-Line/Dublin] @
-@c @uref{http://mysql.iol.ie, WWW}
-@c @uref{ftp://ftp.iol.ie/pub/mysql, FTP}
+Generally speaking, you should use the binary distribution.
+You will need the following:
+@itemize @bullet
@item
-@c Added 20001031
-@c EMAIL: dave@esat.net (Dave Rynne)
-@image{Flags/ireland} Ireland [Esat Net] @
-@uref{http://ftp.esat.net/mirrors/download.sourceforge.net/pub/mirrors/mysql/, WWW}
-@uref{ftp://ftp.esat.net/mirrors/download.sourceforge.net/pub/mirrors/mysql/, FTP}
+A 32-bit Windows Operating System such as 9x, Me, NT, 2000, or XP.
+The NT family (NT, Windows 2000 and XP) permits running the MySQL server
+as a service. @xref{NT start}.
+If you want to use tables bigger than 4G, you should install MySQL
+on an NTFS or newer filesystem. Don't forget to use @code{MAX_ROWS} and
+@code{AVG_ROW_LENGTH} when you create the table. @xref{CREATE TABLE}.
@item
-@c Added 20010524
-@c EMAIL: arvids@parks.lv (Arvids)
-@image{Flags/latvia} Latvia [linux.lv] @
-@uref{ftp://ftp.linux.lv/pub/software/mysql/, FTP}
-
+TCP/IP protocol support.
@item
-@c Added 20001125
-@c EMAIL: mleicher@silverpoint.nl (Marcel Leicher)
-@image{Flags/netherlands} Netherlands [Silverpoint] @
-@uref{http://mysql.silverpoint.nl/, WWW}
+A copy of the MySQL binary or distribution for Windows, which
+can be downloaded from @uref{http://www.mysql.com/downloads/}.
+Note: The distribution files are supplied with a zipped format
+and we recommend the use of an adequate FTP client with resume
+feature to avoid corruption of files during the download process.
@item
-@c EMAIL: mysql@widexs.nl (Wouter de Jong)
-@image{Flags/netherlands} Netherlands [Widexs BV] @
-@uref{http://mysql.widexs.nl/, WWW}
-@uref{ftp://mysql.widexs.nl/pub/mysql/, FTP}
-
+A @code{ZIP} program to unpack the distribution file.
@item
-@c EMAIL: peter@proserve.nl (ProServe - Peter Batenburg)
-@image{Flags/netherlands} Netherlands [ProServe] @
-@uref{http://mysql.proserve.nl/, WWW}
-
+Enough space on the hard drive to unpack, install, and create the
+databases in accorandance with your requirements.
@item
-@c EMAIL: W.Sylwestrzak@icm.edu.pl (Wojtek Sylwestrzak)
-@c mirroring nightly at 05:25
-@image{Flags/poland} Poland [Sunsite] @
-@uref{http://sunsite.icm.edu.pl/mysql/, WWW}
-@uref{ftp://sunsite.icm.edu.pl/pub/unix/mysql/, FTP}
+If you plan to connect to the MySQL server via @code{ODBC}, you
+will also need the @code{MyODBC} driver. @xref{ODBC}.
+@end itemize
-@item
-@c EMAIL: admin@net.ncservice.com.pl (Marian Witkowski)
-@image{Flags/poland} Poland [ncservice.com/Gdansk] @
-@uref{http://mysql.service.net.pl/, WWW}
-@c @item
-@c EMAIL: melo@co.telenet.pt (Pedro Melo)
-@c Temp out of service (email from Pedro)
-@c @image{Flags/portugal} Portugal [IP] @
-@c @uref{http://mysql.ip.pt, WWW}
+@menu
+* Windows binary installation:: Installing the Binaries
+* Windows prepare environment:: Preparing the Windows MySQL Environment
+* Windows server first start:: Starting the Server for the First Time
+@end menu
-@c @item
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: support@leirianet.pt (Equipa de suporte do Leirianet)
-@c @image{Flags/portugal} Portugal [lerianet] @
-@c @uref{http://mysql.leirianet.pt, WWW}
-@c @uref{ftp://ftp.leirianet.pt/pub/mysql/,FTP}
+@node Windows binary installation, Windows prepare environment, Windows installation, Windows installation
+@subsubsection Installing the Binaries
+@enumerate
@item
-@c Added 20001031
-@c bofh@netc.pt (Bruno Rodrigues)
-@image{Flags/portugal} Portugal [Netc] @
-@uref{http://ftp.netc.pt/pub/mysql/, WWW}
-@uref{ftp://ftp.netc.pt/pub/mysql/, FTP}
-
+If you are working on an NT/2000/XP server, logon as a user with
+with administrator privileges.
@item
-@c EMAIL: keeper@roedu.net (Mihai RUSU)
-@image{Flags/romania} Romania [roedu.net/Bucharest] @
-@uref{ftp://ftp.roedu.net/pub/mirrors/ftp.mysql.com/, FTP}
+If you are doing an upgrade of an earlier MySQL installation,
+it is necessary to stop the server. If you are running the server
+as a service, use:
-@item
-@c EMAIL: kuzmin@dn.ru (Roma Kuzmin)
-@image{Flags/russia} Russia [DirectNet] @
-@uref{http://mysql.directnet.ru/, WWW}
-@uref{ftp://ftp.dn.ru/pub/MySQL/, FTP}
+@example
+C:\> NET STOP MySQL
+@end example
-@c @item
-@c down 990113
-@c EMAIL: nikkic@cityline.ru (Nikki Chumakov)
-@c @image{Flags/russia} Russia [Cityline] @
-@c @uref{ftp://mysql.cityline.ru/pub/mysql, FTP}
-@c @uref{http://mysql.cityline.ru, WWW}
-@c EMAIL: bar@izhcom.ru (Alexander I Barkov)
+Otherwise, use:
-@c @item
-@c Not ok 20000919; Non-existent (Matt)
-@c @image{Flags/russia} Russia [IZHCOM] @
-@c @uref{http://mysql.udm.net/, WWW}
-@c @uref{ftp://ftp.izhcom.ru/pub/mysql/,FTP}
+@example
+C:\mysql\bin> mysqladmin -u root shutdown
+@end example
@item
-@c Added 990507
-@c EMAIL: demon@gpad.ac.ru (Dima Sivachenko)
-@image{Flags/russia} Russia [Scientific Center/Chernogolovka] @
-@uref{ftp://ftp.chg.ru/pub/databases/mysql/, FTP}
-
-@c @item
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: sebi@dnttm.ro (Sebastian DEAC)
-@c @image{Flags/romania} Romania [Timisoara] @
-@c @uref{http://download.dnttm.ro/mysql, WWW}
-@c @uref{ftp://ftp.dnttm.ro/pub/mysql, FTP}
+On NT/2000/XP machines, if you want to change the server executable
+(e.g., -max or -nt), it is also necessary to remove the service:
-@c @item
-@c Not ok 20001123; Non-existent (Matt)
-@c EMAIL: tim@lbi.ro (Bogdan Surdu)
-@c @image{Flags/romania}
-@c Romania [Bucharest] @
-@c @uref{http://www.lbi.ro/MySQL/, WWW}
-@c @uref{ftp://ftp.lbi.ro/mirrors/ftp.tcx.se, FTP}
-
-@c @item
-@c Removed 20000521 because there is no mirror here.
-@c EMAIL: jips@masterd.es (Juan Ignacio Pérez Sacristán)
-@c @image{Flags/spain} Spain [MasterD]
-@c @uref{http://mysql.masterd.es, WWW}
+@example
+C:\mysql\bin> mysqld-max-nt --remove
+@end example
@item
-@c EMAIL: Patrik.Karen@sdi.slu.se (Patrik Karen)
-@c ftp -> remove old files
-@image{Flags/sweden} Sweden [Sunet] @
-@uref{http://ftp.sunet.se/pub/unix/databases/relational/mysql/, WWW}
-@uref{ftp://ftp.sunet.se/pub/unix/databases/relational/mysql/, FTP}
-
+Unzip the distribution file to a temporary directory.
@item
-@c EMAIL: archive@sunsite.cnlab-switch.ch (Thomas Lenggenhager)
-@image{Flags/switzerland} Switzerland [Sunsite] @
-@uref{http://sunsite.cnlab-switch.ch/ftp/mirror/mysql/, WWW}
-@uref{ftp://sunsite.cnlab-switch.ch/mirror/mysql/, FTP}
-
-@c @item
-@c Not ok 20000919; Non-existent (Matt)
-@c simon@oyster.co.uk (Simon Gornall)
-@c @image{Flags/great-britain} UK [Oyster/UK] @
-@c @uref{ftp://ftp.oyster.co.uk/pub/mysql, FTP}
-
+Run the @file{setup.exe} file to begin the installation process.
+If you want to install into another directory than the default
+@file{c:\mysql}, use the @code{Browse} button to specify your
+preferred directory.
@item
-@c EMAIL: keet@mordor.plig.net (Christiaan Keet)
-@image{Flags/great-britain} UK [PLiG/UK] @
-@uref{http://ftp.plig.org/pub/mysql/, WWW}
-@uref{ftp://ftp.plig.org/pub/mysql/, FTP}
-
-@c @item
-@c Not ok 20010808; Non-existent (Matt)
-@c EMAIL: sean@telekon.co.uk (Sean Gibson)
-@c @image{Flags/great-britain} UK [Telekon Internet/UK] @
-@c @uref{ftp://ftp.telekon.co.uk/pub/mysql/, FTP}
-
-@c @item
-@c lance@uklinux.net (Lance)
-@c @image{Flags/great-britain} UK [uklinux.net] @
-@c @uref{http://mirror.uklinux.net/mysql/, WWW}
-@c @uref{ftp://mirror.uklinux.net/pub/mysql/, FTP}
-
-@c @item
-@c unknown
-@c @image{Flags/great-britain} UK [MicroMuse] @
-@c @uref{ftp://ftp.micromuse.co.uk/pub/packages/unix/databases/mysql/, FTP}
+Finish the install process.
+@end enumerate
-@c @item
-@c Not ok 20000919; Old site (Matt)
-@c lmjm@icparc.ic.ac.uk (Lee McLoughlin)
-@c @image{Flags/great-britain} UK [SunSITE] @
-@c @uref{http://sunsite.org.uk/packages/mysql/, WWW}
-@c @uref{ftp://sunsite.org.uk/packages/mysql/, FTP}
-@item
-@c EMAIL: sander@paco.net (Alexander Ivanov)
-@image{Flags/ukraine} Ukraine [PACO] @
-@uref{http://mysql.paco.net.ua, WWW}
-@uref{ftp://mysql.paco.net.ua/, FTP}
+@node Windows prepare environment, Windows server first start, Windows binary installation, Windows installation
+@subsubsection Preparing the Windows MySQL Environment
-@item
-@c EMAIL: mizi@alkar.net (Alexander Ryumshin)
-@image{Flags/ukraine} Ukraine [ISP Alkar Teleport/Dnepropetrovsk] @
-@uref{http://mysql.dp.ua/, WWW}
+Starting with MySQL 3.23.38, the Windows distribution includes
+both the normal and the @strong{MySQL-Max} server binaries.
+Here is a list of the different MySQL servers you can use:
-@item
-@c EMAIL: bole@bolex.bolex.co.yu (Bosko Radivojevic)
-@image{Flags/yugoslavia} Yugoslavia [bolex.co.yu] @
-@uref{http://mysql.boa.org.yu/, WWW}
-@uref{ftp://ftp.linux.org.yu/pub/MySQL/, FTP}
+@multitable @columnfractions .20 .80
+@item @strong{Binary} @tab @strong{Description}
+@item @code{mysqld} @tab
+Compiled with full debugging and automatic memory allocation
+checking, symbolic links, InnoDB, and BDB tables.
+@item @code{mysqld-opt} @tab
+Optimised binary with no support for transactional tables.
+@item @code{mysqld-nt} @tab
+Optimised binary for NT/2000/XP with support for named pipes.
+You can run this version on Windows 9x/Me, but in this case no
+named pipes are created and you must have TCP/IP installed.
+@item @code{mysqld-max} @tab
+Optimised binary with support for symbolic links,
+InnoDB and BDB tables.
+@item @code{mysqld-max-nt} @tab
+Like @code{mysqld-max}, but compiled with support for named pipes.
+@end multitable
-@end itemize
+Starting from 3.23.50, named pipes are only enabled if one starts mysqld with
+@code{--enable-named-pipe}.
-@strong{North America:}
+All of the preceding binaries are optimised for the Pentium Pro
+processor but should work on any Intel processor >= i386.
+You will need to use an option file to specify your MySQL configuration
+under the following circumstances:
@itemize @bullet
-@c @item
-@c Not ok 990101 (only to 981007)
-@c EMAIL: sysop@polarcom.com (Seamus Venasse)
-@c @image{Flags/canada} Canada [Polaris Computing] @
-@c @uref{http://mysql.polaris.ca/, WWW}
-
-@item
-@c Ok 980109
-@c EMAIL: wojtek@tryc.on.ca (Wojtjeck Tryc)
-@image{Flags/canada} Canada [Tryc] @
-@uref{http://web.tryc.on.ca/mysql/, WWW}
-
-@c @item
-@c not updated 990218. Added again 990918
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: rhooper@cyberus.ca (Roy Hooper)
-@c @image{Flags/canada} Canada [Cyberus] @
-@c @uref{http://mysql.cyberus.ca/, WWW}
-@c @uref{ftp://mysql.cyberus.ca/, FTP}
-
-@item
-@c EMAIL: mleber@he.net (Mike Leber)
-@c Added 980312
-@image{Flags/usa} USA [Hurricane Electric/San Jose] @
-@uref{http://mysql.he.net/, WWW}
-
-@item
-@c EMAIL: ask@valueclick.com (Ask Bjoern Hansen)
-@c Added 20000925
-@image{Flags/usa} USA [ValueClick, Los Angeles CA] @
-@uref{http://mysql.valueclick.com/, WWW}
-@uref{ftp://mysql.valueclick.com/pub/mysql/Downloads/, FTP}
-
-@c @item
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: meltzer@icsnet.com (Jeffrey Meltzer)
-@c Added 000108
-@c @image{Flags/usa} USA [Meltzer/New York State] @
-@c @uref{ftp://ftp.meltzer.org/pub/mysql/, FTP}
-
-@c @item
-@c No such directory 990830
-@c EMAIL: tps@users.buoy.com (Tim Sailer)
-@c @image{Flags/usa} USA [Buoy/New York] @
-@c @uref{http://www.buoy.com/mysql/, WWW}
-
-@c @item
-@c EMAIL: db@hpnc.com (Douglas Bowyer)
-@c Added 980107, removed 981124 because of 'file not found'
-@c @image{Flags/usa} USA [Hypernet Communications/Dallas] @
-@c @uref{http://epsilon.hpnc.com/mysql, WWW}
-
-@c @item @c **********************************
-@c Not updated 980106
-@c EX: twh@iquest.net (Thomas Holt) who no longer works there
-@c @image{Flags/usa} USA [IQuest/Indiana] @
-@c @uref{http://mirrors.iquest.net/mysql/, WWW}
-
-@c @item @c **********************************
-@c Only a partial mirror so we exclude it from the list
-@c EX: lindberg@id.wustl.edu (Fred Lindberg)
-@c @image{Flags/usa} USA [Washington University/St. Louis] @
-@c @uref{ftp://ftp.id.wustl.edu/pub/database/mysql/, FTP}
-
-@c removed 991111 -> no answer
-@c @item
-@c EMAIL: andrew@netcasting.net (Andrew Sawyers)
-@c @image{Flags/usa} USA [Netcasting/West Coast] @
-@c @uref{ftp://ftp.netcasting.net/pub/mysql/, FTP}
-
-@c @item
-@c No mirror! 980809 David
-@c EMAIL: savages@savages.com (Shaun Savage)
-@c @image{Flags/usa} USA [Savages/Oregon] @
-@c @uref{http://mysql.savages.com, WWW}
-
-@c @item
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: paul@gina.net (Paul Vining)
-@c mirrors ftp.sunet.se
-@c @image{Flags/usa} USA [Gina net/Florida] @
-@c @uref{http://www.gina.net/mysql/, WWW}
-
-@c Out of date 2000-01-08 (Not updated since 1999-10)
-@c @item
-@c EMAIL: wswanson@pingzero.net (Wylie Swanson)
-@c mirrors mysql.org
-@c @image{Flags/usa} USA [pingzero/Los Angeles] @
-@c @uref{http://mysql.pingzero.net/, WWW}
-
@item
-@c EMAIL: ftpkeeper@mirror.sit.wisc.edu
-@image{Flags/usa} USA [Wisconsin University/Wisconsin] @
-@uref{http://mirror.sit.wisc.edu/mysql/, WWW}
-@uref{ftp://mirror.sit.wisc.edu/mirrors/mysql/, FTP}
-
-@c @item
-@c Not ok 20000919; Out of date (Matt)
-@c EMAIL: ftp-admin@digex.net
-@c @image{Flags/usa} USA [DIGEX] @
-@c @uref{ftp://ftp.digex.net/pub/packages/database/mysql/, FTP}
-
-@item
-@c EMAIL: andrew.sawyers@thelinuxstore.com
-@image{Flags/usa} USA [LinuxWired/Scottsdale, AZ] @
-@uref{http://mysql.linuxwired.net/, WWW}
-@uref{ftp://ftp.linuxwired.net/pub/mirrors/mysql/, FTP}
-
-@c @item
-@c EMAIL: dan@surfsouth.com (Dan Muntz)
-@c @image{Flags/usa} USA [Venoma.Org/Valdosta, GA] @
-@c @uref{http://mysql.venoma.org/, WWW}
-
+The installation or data directories are different from the default
+locations (@file{c:\mysql} and @file{c:\mysql\data}).
@item
-@c EMAIL: hkind@adgrafix.com (Hans Kind)
-@image{Flags/usa} USA [adgrafix.com/Boston, MA] @
-@uref{http://mysql.adgrafix.com/, WWW}
-
-@item
-@c EMAIL: Pjacob@netnumina.com (Philip Jacob)
-@image{Flags/usa} USA [netNumina/Cambridge, MA] @
-@uref{http://mysql.mirrors.netnumina.com/, WWW}
-
-@item
-@c EMAIL: hagler@ahaza.com (Mark Hagler)
-@image{Flags/usa} USA [Ahaza Systems/Seattle, WA] @
-@uref{http://mysql.mirrortree.com/, WWW}
-@uref{ftp://mysql.mirrortree.com/pub/mysql/, FTP}
-
-@end itemize
-
-@strong{South America:}
-
+You want to use one of these servers:
@itemize @bullet
-
-@item
-@c Added 20001102
-@c EMAIL: nico@bannerlandia.com (Nicolas Moldavsky)
-@image{Flags/argentina} Argentina [bannerlandia.com] @
-@uref{http://mysql.bannerlandia.com.ar/, WWW}
-@uref{ftp://mysql.bannerlandia.com.ar/mirrors/mysql/, FTP}
-
-@c @item
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: gaiser@matrix.com.br (Roberto Gaiser)
-@c @image{Flags/brazil} Brazil [Matrix] @
-@c @uref{http://mysql.matrix.com.br, WWW}
-
-@item
-@c jpabuyer@vision.cl
-@image{Flags/chile} Chile [Vision] @
-@uref{http://mysql.vision.cl/, WWW}
-
-@item
-@c EMAIL: bartschm@psi.com (Marcelo Bartsch)
-@image{Flags/chile} Chile [PSINet] @
-@uref{http://mysql.psinet.cl/, WWW}
-@uref{ftp://ftp.psinet.cl/pub/database/mysql/, FTP}
-
-@item
-@c EMAIL: jpabuyer@tecnoera.com (Juan Pablo Abuyeres)
-@image{Flags/chile} Chile [Tecnoera] @
-@uref{http://mysql.tecnoera.com/, WWW}
-
-@c @item
-@c Removed 990730
-@c @c EMAIL: dan@amerikanclaris.com (Danilo Lotina F.)
-@c @image{Flags/chile} Chile [Amerikanclaris] @
-@c @uref{http://www.labs.amerikanclaris.cl/mysql, WWW}
-@c @uref{ftp://ftp.amerikanclaris.cl/pub/mysql, FTP}
+@item mysqld.exe
+@item mysqld-max.exe
+@item mysqld-max-nt.exe
@end itemize
-
-@strong{Asia:}
-
-@itemize @bullet
-@c @item
-@c Host cannot be resolved for last week at least 20010809 Tonu
-@c EMAIL: mirnshi@263.net (Meng Lingbo)
-@c @image{Flags/china} China [Freecode] @
-@c @uref{http://www.freecode.net.cn/mirror/mysql/, WWW}
-
-@item
-@c EMAIL: yusun@atwell.co.jp (yu sun)
-@image{Flags/china} China [linuxforum.net] @
-@uref{http://www2.linuxforum.net/mirror/mysql/, WWW}
-
-@item
-@c EMAIL: vfong@hklpg.org (Vincent Fong)
-@image{Flags/china} China [HKLPG/Hong Kong] @
-@uref{http://mysql.hklpg.org, WWW}
-
-@item
-@c EMAIL: jason-wong@gremlins.com.hk (Gremlins Jason Wong)
-@image{Flags/china} China [Gremlins/Hong Kong] @
-@uref{http://mysql.gremlins.com.hk/, WWW}
-@uref{ftp://ftp.mirrors.gremlins.com.hk/mysql/, FTP}
-
-@item
-@c EMAIL: shell@linux.org.hk (Shell Hung)
-@image{Flags/china} China [shellhung.org/Hong Kong] @
-@uref{http://mysql.shellhung.org/, WWW}
-@uref{ftp://ftp.shellhung.org/pub/Mirror/mysql/, FTP}
-
-@c @item
-@c Not ok 20010308; Other content! (Tonu)
-@c EMAIL: xcyber@yahoo.com (xcyber)
-@c @image{Flags/china} China [xcyber.org/Hong Kong] @
-@c @uref{http://mysql.xcyber.org/, WWW}
-
-@c @item
-@c Not ok 20010330; Non-existent! (Matt)
-@c EMAIL: marquischan@hotmail.com (Marquis Chan)
-@c @image{Flags/china} China [TraLand.com/Hong Kong] @
-@c @uref{http://www.traland.com/mysql/, WWW}
-
-@c @item
-@c Not ok 20000919; Non-existent (Matt)
-@c EMAIL: george@netfirm.net (Hongsheng Zhu)
-@c @image{Flags/china} China [Netfirm] @
-@c @uref{http://mysql.netfirm.net, WWW}
-
-@item
-@c EMAIL: dnata@incaf.net (Denie Nataprawira)
-@image{Flags/indonesia} Indonesia [incaf.net] @
-@uref{http://mysql.incaf.net/, WWW}
-
-@item
-@c EMAIL: andika@piksi.itb.ac.id (Andika Triwidada)
-@image{Flags/indonesia} Indonesia [web.id] @
-@uref{http://mysql.itb.web.id/, WWW}
-@uref{ftp://mysql.itb.web.id/pub/MySQL/, FTP}
-
-@item
-@c Ok 980805
-@c EMAIL: takeshi@SoftAgency.co.jp
-@image{Flags/japan} Japan [Soft Agency] @
-@uref{http://www.softagency.co.jp/MySQL, WWW}
-
@item
-@c EMAIL: takafumi@u-aizu.ac.jp (Takafumi Hayashi)
-@image{Flags/japan} Japan [u-aizu.ac.jp/Aizu] @
-@uref{ftp://ftp.u-aizu.ac.jp/ftp/pub/dbms/mysql/mysql.com, FTP}
+You need to tune the server settings.
+@end itemize
-@c @item
-@c Ok 980109 Removed 990730
-@c EMAIL: satoshi@HappySize.co.jp (Satoshi TATSUOKA)
-@c @image{Flags/japan} Japan [HappySize] @
-@c @uref{http://www.happysize.co.jp/mysql/, WWW}
-@c @uref{ftp://ftp.happysize.co.jp/pub/mysql/, FTP}
+Normally you can use the @code{WinMySQLAdmin} tool to edit the
+option file @code{my.ini}. In this case you don't have to worry
+about the following section.
-@c @item
-@c Ok 981204
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: hiroyuki@nucba.ac.jp (hiroyuki kurimoto)
-@c @image{Flags/japan} Japan [Nagoya Syouka University] @
-@c @uref{http://mirror.nucba.ac.jp/mirror/mysql, WWW}
-@c @uref{ftp://mirror.nucba.ac.jp/mirror/mysql, FTP}
+There are two option files with the same function: @file{my.cnf} and
+@file{my.ini}. However, to avoid confusion, it's best if you use only
+of one them. Both files are plain text. The @file{my.cnf} file, if used,
+should be created in the root directory of the C drive. The @file{my.ini}
+file, if used, should be created in the Windows system directory. (This
+directory is typically something like @file{C:\WINDOWS} or @file{C:\WINNT}.
+You can determine its exact location from the value of the @code{windir}
+environment variable.) MySQL looks first for the @code{my.ini} file,
+then for the @file{my.cnf} file.
-@c @item
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: ahmlhs@nmsvr.chosun.com (Ho-sun Lee)
-@c @image{Flags/south-korea} South Korea [KREONet] @
-@c @uref{http://linux.kreonet.re.kr/mysql/, WWW}
+If your PC uses a boot loader where the C drive isn't the boot drive,
+your only option is to use the @file{my.ini} file. Also note that
+if you use the @code{WinMySQLAdmin} tool, it uses only the @file{my.ini}
+file. The @file{\mysql\bin} directory contains a help file with
+instructions for using this tool.
-@item
-@c EMAIL: jasper@webiiz.com (Kang, Tae-jin)
-@image{Flags/south-korea} South Korea [Webiiz] @
-@uref{http://mysql.webiiz.com/, WWW}
+Using @code{notepad.exe}, create the option file and edit the
+@code{[mysqld]} section to specify values for the @code{basedir} and
+@code{datadir} parameters:
-@item
-@c EMAIL: hollywar@holywar.net (Oh Junseon)
-@image{Flags/south-korea} South Korea [PanworldNet] @
-@uref{http://mysql.holywar.net/, WWW}
+@example
+[mysqld]
+# set basedir to installation path, e.g., c:/mysql
+basedir=the_install_path
+# set datadir to location of data directory,
+# e.g., c:/mysql/data or d:/mydata/data
+datadir=the_data_path
+@end example
-@c @item
-@c ftp -> remove old files
-@c EX: ahmlhs@nmsvr.chosun.com (Ho-sun Lee)
-@c @image{Flags/south-korea} South Korea [KREONet] @
-@c @uref{ftp://linux.kreonet.re.kr/pub/tools/db/mysql/, FTP}
+Note that Windows pathnames should be specified in option files using
+forward slashes rather than backslashes. If you do use backslashes, you
+must double them.
-@c @item
-@c Removed 990308
-@c EMAIL: terence@com5.net (Terence Chan)
-@c @image{Flags/singapore} Singapore [Com5 Productions] @
-@c @uref{http://mysql.com5.net, WWW}
-@c @uref{ftp://ftp.com5.net/pub/mysql, FTP}
+If you would like to use a data directory different from the default of
+@file{c:\mysql\data}, you must copy the entire contents of the
+@file{c:\mysql\data} directory to the new location.
-@item
-@c EMAIL: csy@hjc.edu.sg
-@image{Flags/singapore} Singapore [HJC] @
-@uref{http://mysql.hjc.edu.sg, WWW}
-@uref{ftp://ftp.hjc.edu.sg/mysql, FTP}
+If you want to use the @code{InnoDB} transactional tables, you
+need to manually create two new directories to hold the InnoDB
+data and log files@-e.g., @file{c:\ibdata} and @file{c:\iblogs}.
+You will also need to add some extra lines to the option
+file. @xref{InnoDB start}.
-@c @item
-@c Not ok 20000919; Old site (Matt)
-@c 991118: Removed because a user complained about that the page contains
-@c nothing about MySQL. 991119: Added again because it is a mirror again
-@c EMAIL: dean@ht.net.tw (Dean Lin)
-@c @image{Flags/taiwan} Taiwan [HT] @
-@c @uref{http://mysql.ht.net.tw, WWW}
+If you don't want to use @code{InnoDB} tables, add the
+@code{skip-innodb} option to the option file.
-@item
-@c EMAIL: linda@ttn.com.tw (Linda Hu)
-@image{Flags/taiwan} Taiwan [TTN] @
-@uref{http://mysql.ttn.net, WWW}
+Now you are ready to test starting the server.
-@c @item
-@c Ok 980321 No connect -> removed 990730
-@c EMAIL: tby@ccca.nctu.edu.tw (Bao-Yi Tuang)
-@c @image{Flags/taiwan} Taiwan [NCTU] @
-@c @uref{http://mysql.taconet.com.tw, WWW}
-@c @item
-@c Out of date 990905 (~2 months)
-@c @item @c **********************************
-@c Error 980106
-@c EX: WolfySu@acer.net (Wolfy Su)
-@c @image{Flags/taiwan} Taiwan [Acer] @
-@c @uref{http://mysql.acer.net/, WWW}
+@node Windows server first start, , Windows prepare environment, Windows installation
+@subsubsection Starting the Server for the First Time
-@c @item @c **********************************
-@c files to delete
-@c EX: service@wownet.net
-@c @image{Flags/taiwan} Taiwan [Wownet] @
-@c @uref{ftp://ftp.wownet.net/mysql/, FTP}
+Testing from a DOS command prompt is the best thing to do because
+the server displays status messages that appear in the DOS window.
+If something is wrong with your configuration, these messages will
+make it easier for you to identify and fix any problems.
-@c @item @c **********************************
-@c No contact 980106
-@c EX: serge@oneway.net
-@c @image{Flags/taiwan} Taiwan [Oneway] @
-@c @uref{ftp://ftp.oneway.com.tw/pub/mysql/, FTP}
+Make sure you are in the directory where the server is located, then
+enter this command:
-@item
-@c Added 20001031
-@c EMAIL: ijliao@php.nctu.edu.tw (Ying-Chieh Liao)
-@image{Flags/taiwan} Taiwan [nctu.edu/HsinChu] @
-@uref{http://mysql.nctu.edu.tw/, WWW}
+@example
+C:\mysql\bin> mysqld-max --standalone
+@end example
-@end itemize
+You should see the following messages as the server starts up:
-@c @strong{Australia:}
+@example
+InnoDB: The first specified datafile c:\ibdata\ibdata1 did not exist:
+InnoDB: a new database to be created!
+InnoDB: Setting file c:\ibdata\ibdata1 size to 209715200
+InnoDB: Database physically writes the file full: wait...
+InnoDB: Log file c:\iblogs\ib_logfile0 did not exist: new to be created
+InnoDB: Setting log file c:\iblogs\ib_logfile0 size to 31457280
+InnoDB: Log file c:\iblogs\ib_logfile1 did not exist: new to be created
+InnoDB: Setting log file c:\iblogs\ib_logfile1 size to 31457280
+InnoDB: Log file c:\iblogs\ib_logfile2 did not exist: new to be created
+InnoDB: Setting log file c:\iblogs\ib_logfile2 size to 31457280
+InnoDB: Doublewrite buffer not found: creating new
+InnoDB: Doublewrite buffer created
+InnoDB: creating foreign key constraint system tables
+InnoDB: foreign key constraint system tables created
+011024 10:58:25 InnoDB: Started
+@end example
+
+For further information about running MySQL on Windows,
+see @ref{Windows}.
-@c @itemize @bullet
-@c @item
-@c Added 980610
-@c EMAIL: jason@dstc.edu.au (Jason Andrade)
-@c @image{Flags/australia} Australia [AARNet/Queensland] @
-@c @uref{http://mysql.mirror.aarnet.edu.au/, WWW}
-@c @uref{ftp://mysql.mirror.aarnet.edu.au/, FTP}
-@c @item
-@c Added 980805. Removed 000102 'no such directory'
-@c EMAIL: sdd@ntccc.tas.gov.au (Scott Donovan)
-@c @image{Flags/australia} Australia [Tas] @
-@c @uref{http://ftp.tas.gov.au/mysql, WWW}
-@c @uref{ftp://ftp.tas.gov.au/pub/mysql, FTP}
+@node General Installation Issues, Installing source, Quick Standard Installation, Installing
+@section General Installation Issues
-@c @item
-@c Ok 980623
-@c Not ok 20000919; Old site (Matt)
-@c EMAIL: samh@bluep.com (Sam Hadzajlic)
-@c @image{Flags/australia} Australia [Blue Planet/Melbourne] @
-@c @uref{http://mysql.bluep.com/, WWW}
-@c removed because ftp was not working 990729 & 30
-@c @uref{ftp://mysql.bluep.com/pub/mirror1/mysql/, FTP}
+@c @node Methods of Installation, , ,
+@c @subsection Methods of Installation
-@c @item
-@c Added 990531
-@c EMAIL: gavin@itworks.com.au (Gavin Cameron)
-@c @image{Flags/australia} Australia [ITworks Consulting/Victoria] @
-@c @uref{http://mysql.itworks.com.au, WWW}
+@c FIX: this needs to be written?
-@c @item
-@c 980610 Only the toplevel dir!
-@c EMAIL: lucifer@maths.uq.edu.au (David Conran)
-@c @image{Flags/australia} Australia FTP @
-@c @uref{ftp://ftp.sage-au.org.au/pub/database/mysql, [Sage]}
-@c @end itemize
+@menu
+* Getting MySQL:: How to Get MySQL
+* Which OS:: Operating Systems Supported by MySQL
+* Which version:: Which MySQL Version to Use
+* Installation layouts:: Installation Layouts
+* Many versions:: How and When Updates Are Released
+* MySQL binaries:: MySQL Binaries Compiled by MySQL AB
+* Installing binary:: Installing a MySQL Binary Distribution
+@end menu
-@strong{Africa:}
-@itemize @bullet
+@node Getting MySQL, Which OS, General Installation Issues, General Installation Issues
+@subsection How to Get MySQL
-@item
-@c EMAIL: ftp-admin@mweb.com (Warren Baker)
-@image{Flags/south-africa1} South-Africa [Mweb] @
-@uref{http://www.mysql.mweb.co.za/, WWW}
+@cindex downloading
+@cindex MySQL version
+@cindex version, latest
+@cindex getting MySQL
+@cindex mirror sites
+@cindex URLS for downloading MySQL
-@item
-@c Ok 981010
-@c EMAIL: oskar@is.co.za (Oskar Pearson)
-@image{Flags/south-africa1} South Africa [The Internet Solution/Johannesburg] @
-@uref{ftp://ftp.is.co.za/linux/mysql/, FTP}
+Check the MySQL homepage (@uref{http://www.mysql.com/}) for
+information about the current version and for downloading instructions.
-@end itemize
+Our main mirror is located at @uref{http://mirrors.sunsite.dk/mysql/}.
-@c END_OF_MIRROR_LISTING
+For a complete upto-date list of MySQL web/download mirrors, see
+@uref{http://www.mysql.com/downloads/mirrors.html}.
+There you will also find information about becoming a MySQL mirror
+site and how to report a bad or out-of-date mirror.
@node Which OS, Which version, Getting MySQL, General Installation Issues
@@ -7219,17 +5662,18 @@ AIX 4.x with native threads. @xref{IBM-AIX}.
@item
Amiga.
@item
-BSDI 2.x with the included MIT-pthreads package. @xref{BSDI}.
+BSDI 2.x with the MIT-pthreads package. @xref{BSDI}.
@item
BSDI 3.0, 3.1 and 4.x with native threads. @xref{BSDI}.
@item
DEC Unix 4.x with native threads. @xref{Alpha-DEC-UNIX}.
@item
-FreeBSD 2.x with the included MIT-pthreads package. @xref{FreeBSD}.
+FreeBSD 2.x with the MIT-pthreads package. @xref{FreeBSD}.
@item
FreeBSD 3.x and 4.x with native threads. @xref{FreeBSD}.
@item
-HP-UX 10.20 with the included MIT-pthreads package. @xref{HP-UX 10.20}.
+HP-UX 10.20 with the DCE threads or the MIT-pthreads package.
+@xref{HP-UX 10.20}.
@item
HP-UX 11.x with the native threads. @xref{HP-UX 11.x}.
@item
@@ -7239,7 +5683,7 @@ Mac OS X Server. @xref{Mac OS X}.
@item
NetBSD 1.3/1.4 Intel and NetBSD 1.3 Alpha (Requires GNU make). @xref{NetBSD}.
@item
-OpenBSD > 2.5 with native therads. OpenBSD < 2.5 with the included
+OpenBSD > 2.5 with native threads. OpenBSD < 2.5 with the
MIT-pthreads package. @xref{OpenBSD}.
@item
OS/2 Warp 3, FixPack 29 and OS/2 Warp 4, FixPack 4. @xref{OS/2}.
@@ -7248,20 +5692,21 @@ SGI Irix 6.x with native threads. @xref{SGI-Irix}.
@item
Solaris 2.5 and above with native threads on SPARC and x86. @xref{Solaris}.
@item
-SunOS 4.x with the included MIT-pthreads package. @xref{Solaris}.
+SunOS 4.x with the MIT-pthreads package. @xref{Solaris}.
@item
-SCO OpenServer with a recent port of the FSU Pthreads package. @xref{SCO}.
+Caldera (SCO) OpenServer with a recent port of the FSU Pthreads package.
+@xref{Caldera}.
@item
-SCO UnixWare 7.0.1. @xref{SCO Unixware}.
+Caldera (SCO) UnixWare 7.0.1. @xref{Caldera Unixware}.
@item
Tru64 Unix
@item
-Win95, Win98, NT, and Win2000. @xref{Windows}.
+Windows 9x, Me, NT, 2000 and XP. @xref{Windows}.
@end itemize
Note that not all platforms are suited equally well for running
MySQL. How well a certain platform is suited for a high-load
-mission critical MySQL server is determined by the following
+mission-critical MySQL server is determined by the following
factors:
@itemize @bullet
@@ -7281,20 +5726,20 @@ CPU than the original process.
The ability of the kernel and/or the thread library to run many threads which
acquire/release a mutex over a short critical region frequently without
excessive context switches. In other words, if the implementation of
-@code{pthread_mutex_lock()} is too anxious to yield CPU, this will hurt
+@code{pthread_mutex_lock()} is too anxious to yield CPU time, this will hurt
MySQL tremendously. If this issue is not taken care of, adding extra CPUs
will actually make MySQL slower.
@item
-General file system stability/performance.
+General filesystem stability/performance.
@item
-Ability of the file system to deal with large files at all and deal with them
+Ability of the filesystem to deal with large files at all and deal with them
efficiently, if your tables are big.
@item
Our level of expertise here at MySQL AB with the platform. If we know
-a platform well, we introduce platform-specific optimizations/fixes enabled at
+a platform well, we introduce platform-specific optimisations/fixes enabled at
compile time. We can also provide advice on configuring your system optimally
for MySQL.
@@ -7304,16 +5749,16 @@ The amount of testing of similar configurations we have done internally.
@item
The number of users that have successfully run MySQL on that
platform in similar configurations. If this number is high, the chances of
-hitting some platform-specific surprise are much smaller.
+hitting some platform-specific surprises are much smaller.
@end itemize
-Based on the above criteria, the best platforms for running
-MySQL at this point are x86 with SuSE Linux 7.1, 2.4 kernel and
-ReiserFS (or any similar Linux distribution) and Sparc with Solaris 2.7
+Based on the preceding criteria, the best platforms for running
+MySQL at this point are x86 with SuSE Linux 7.1, 2.4 kernel, and
+ReiserFS (or any similar Linux distribution) and SPARC with Solaris 2.7
or 2.8. FreeBSD comes third, but we really hope it will join the top
club once the thread library is improved. We also hope that at some
point we will be able to include all other platforms on which
-MySQL compiles, runs ok, but not quite with the same level of
+MySQL compiles, runs okay, but not quite with the same level of
stability and performance, into the top category. This will require some
effort on our part in cooperation with the developers of the OS/library
components MySQL depends upon. If you are interested in making
@@ -7322,15 +5767,15 @@ development, and need more detailed instructions on what MySQL
needs to run better, send an e-mail to
@email{internals@@lists.mysql.com}.
-Please note that the comparison above is not to say that one OS is better or
+Please note that the preceding comparison is not to say that one OS is better or
worse than the other in general. We are talking about choosing a particular OS
-for a dedicated purpose - running MySQL, and compare platforms in that
+for a dedicated purpose@-running MySQL, and compare platforms in that
regard only. With this in mind, the result of this comparison
would be different if we included more issues into it. And in some cases,
the reason one OS is better than the other could simply be that we have put
-forth more effort into testing on and optimizing for that particular platform.
-We are just stating our observations to help you make a
-decision on which platform to use MySQL on in your setup.
+forth more effort into testing on and optimising for that particular platform.
+We are just stating our observations to help you decide on which
+platform to use MySQL on in your setup.
@node Which version, Installation layouts, Which OS, General Installation Issues
@@ -7347,12 +5792,12 @@ release or the last stable release:
@itemize @bullet
@item
-Normally, if you are beginning to use MySQL for the first time
-or trying to port it to some system for which there is no binary
-distribution, we recommend going with the stable release (currently
-Version @value{mysql_version}. Note that all MySQL releases are
-checked with the MySQL benchmarks and an extensive test suite
-before each release.
+Normally, if you are beginning to use MySQL for the first time or trying
+to port it to some system for which there is no binary distribution, we
+recommend going with the stable release (currently version 3.23). Note
+that all MySQL releases are checked with the MySQL benchmarks and an
+extensive test suite before each release (even the development
+releases).
@item
Otherwise, if you are running an old system and want to upgrade, but
@@ -7378,8 +5823,8 @@ to get even more flexibility).
@item
To be able to satisfy different user requirements, we are providing two
-different binary versions; One compiled with the non-transactional table
-handlers, (a small, fast binary), and one configured with the most
+different binary versions: one compiled with the non-transactional table
+handlers (a small, fast binary), and one configured with the most
important extended options like transaction-safe tables. Both versions
are compiled from the same source distribution. All native @code{MySQL}
clients can connect to both MySQL versions.
@@ -7392,13 +5837,13 @@ If you want to use the @code{MySQL-Max} RPM, you must first
install the standard @code{MySQL} RPM.
@item
-If you want to configure @code{mysqld} with some extra features that are
-NOT in the standard binary distributions. Here is a list of the most
+If you want to configure @code{mysqld} with some extra features that are
+not in the standard binary distributions. Here is a list of the most
common extra options that you may want to use:
@itemize @bullet
-@item @code{--with-berkeley-db}
@item @code{--with-innodb}
+@item @code{--with-berkeley-db}
@item @code{--with-raid}
@item @code{--with-libwrap}
@item @code{--with-named-z-lib (This is done for some of the binaries)}
@@ -7407,12 +5852,12 @@ common extra options that you may want to use:
@item
The default binary distribution is normally compiled with support
-for all characters sets and should work on a variety of processors from
+for all character sets and should work on a variety of processors from
the same processor family.
If you want a faster MySQL server you may want to recompile it
with support for only the character sets you need, use a better compiler
-(like @code{pgcc}) or use compiler options that are better optimized for your
+(like @code{pgcc}), or use compiler options that are better optimised for your
processor.
@item
@@ -7436,14 +5881,14 @@ numbers and a suffix. For example, a release name like
@itemize @bullet
@item
-The first number (@code{3}) describes the file format. All Version 3
+The first number (@code{3}) describes the file format. All Version 3
releases have the same file format.
@item
The second number (@code{21}) is the release level. Normally there are two to
choose from. One is the release/stable branch (currently @code{23}) and the
other is the development branch (currently @code{4.0}). Normally both are
-stable, but the development version may have quirks, missing documentation on
+stable, but the development version may have quirks, may be missing documentation on
new features, or may fail to compile on some systems.
@item
@@ -7456,7 +5901,7 @@ The suffix (@code{beta}) indicates the stability level of the release.
The possible suffixes are:
@itemize @minus
-@item
+@item
@code{alpha} indicates that the release contains some large section of
new code that hasn't been 100% tested. Known bugs (usually there are none)
should be documented in the News section. @xref{News}. There are also new
@@ -7502,7 +5947,7 @@ hundreds of megabytes of data.
@item The MySQL benchmark suite
This runs a range of common queries. It is also a test to see whether the
-latest batch of optimizations actually made the code faster.
+latest batch of optimisations actually made the code faster.
@xref{MySQL Benchmarks}.
@item The @code{crash-me} test
@@ -7530,7 +5975,7 @@ A binary distribution is installed by unpacking it at the installation
location you choose (typically @file{/usr/local/mysql}) and creates the
following directories in that location:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .15 .45
@item @strong{Directory} @tab @strong{Contents of directory}
@item @file{bin} @tab Client programs and the @code{mysqld} server
@item @file{data} @tab Log files, databases
@@ -7545,7 +5990,7 @@ A source distribution is installed after you configure and compile it. By
default, the installation step installs files under @file{/usr/local}, in the
following subdirectories:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .15 .45
@item @strong{Directory} @tab @strong{Contents of directory}
@item @file{bin} @tab Client programs and scripts
@item @file{include/mysql} @tab Include (header) files
@@ -7609,11 +6054,12 @@ versions, the second number in the version string is incremented. When the
file format changes, the first number is increased.
@item
-Stable tested releases are meant to appear about 1-2 times a year, but
+Stable-tested releases are meant to appear about 1-2 times a year, but
if small bugs are found, a release with only bug fixes will be released.
@item
-Working releases are meant to appear about every 1-8 weeks.
+Working releases/bug fixes to old releases are meant to appear about
+every 1-8 weeks.
@item
Binary distributions for some platforms will be made by us for major releases.
@@ -7622,12 +6068,12 @@ less frequently.
@item
We usually make patches available as soon as we have located and fixed
-small bugs.
+small bugs. They are posted to @email{bugs@@lists.mysql.com} and will
+be added to the next release.
@item
-For non-critical but annoying bugs, we will make patches available if they
-are sent to us. Otherwise we will combine many of them into a larger
-patch.
+For non-critical but annoying bugs, we will add them the MySQL source
+repository and they will be fixed in the next release.
@item
If there is, by any chance, a fatal bug in a release we will make a new
@@ -7635,15 +6081,19 @@ release as soon as possible. We would like other companies to do this,
too.
@end itemize
-The current stable release is Version 3.23; We have already moved active
+The current stable release is Version 3.23; we have already moved active
development to Version 4.0. Bugs will still be fixed in the stable version.
We don't believe in a complete freeze, as this also leaves out bug fixes
and things that ``must be done.'' ``Somewhat frozen'' means that we may
add small things that ``almost surely will not affect anything that's
already working.''
+MySQL uses a slightly different naming scheme from most other products.
+In general it's relatively safe to use any version that has been out for
+a couple of weeks without being replaced with a new version.
+@xref{Which version}.
-@node MySQL binaries, , Many versions, General Installation Issues
+@node MySQL binaries, Installing binary, Many versions, General Installation Issues
@subsection MySQL Binaries Compiled by MySQL AB
@cindex binary distributions
@@ -7665,6 +6115,9 @@ and are configured with the following compilers and options:
@item SunOS 5.6 i86pc with @code{gcc} 2.8.1
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex}
+@item Solaris 2.8 sparc with @code{gcc 2.95.3}
+@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex "--with-server-suffix=" --enable-thread-safe-client --enable-local-infile --enable-assembler --disable-shared}
+
@item Linux 2.0.33 i386 with @code{pgcc} 2.90.29 (@code{egcs} 1.0.3a)
@code{CFLAGS="-O3 -mpentium -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentium -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --with-extra-charsets=complex}
@@ -7677,7 +6130,7 @@ and are configured with the following compilers and options:
@item AIX 2 4 with @code{gcc} 2.7.2.2
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
-@item OSF1 V4.0 564 alpha with @code{gcc} 2.8.1
+@item OSF/1 V4.0 564 alpha with @code{gcc} 2.8.1
@code{CC=gcc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex}
@item Irix 6.3 IP32 with @code{gcc} 2.8.0
@@ -7688,20 +6141,241 @@ and are configured with the following compilers and options:
@item BSDI BSD/OS 2.1 i386 with @code{gcc} 2.7.2
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
+
+@item FreeBSD 4.4-stable i386 with @code{gcc} 2.95.3
+@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex "--with-server-suffix=" --enable-thread-safe-client --enable-local-infile --enable-assembler --with-named-z-libs=not-used --disable-shared}
@end table
-Anyone who has more optimal options for any of the configurations listed
-above can always mail them to the developer's mailing list at
+Anyone who has more optimal options for any of the preceding
+configurations listed can always mail them to the developer's mailing list at
@email{internals@@lists.mysql.com}.
RPM distributions prior to MySQL Version 3.22 are user-contributed.
-Beginning with Version 3.22, the RPMs are generated by us at
+Beginning with Version 3.22, the RPMs are generated by us at
MySQL AB.
If you want to compile a debug version of MySQL, you should add
-@code{--with-debug} or @code{--with-debug=full} to the above configure lines
+@code{--with-debug} or @code{--with-debug=full} to the preceding configure lines
and remove any @code{-fomit-frame-pointer} options.
+For the Windows distribution, please see @ref{Windows installation}.
+
+
+@node Installing binary, , MySQL binaries, General Installation Issues
+@subsection Installing a MySQL Binary Distribution
+
+@cindex installing, binary distribution
+@cindex binary distributions, installing
+
+See also @ref{Windows binary installation},
+@ref{Linux-RPM}, and @ref{Building clients}.
+
+You need the following tools to install a MySQL binary distribution:
+
+@itemize @bullet
+@item
+GNU @code{gunzip} to uncompress the distribution.
+
+@item
+A reasonable @code{tar} to unpack the distribution. GNU @code{tar} is
+known to work. Sun @code{tar} is known to have problems.
+@end itemize
+
+@cindex RPM, defined
+@cindex RedHat Package Manager
+An alternative installation method under Linux is to use RPM (RedHat Package
+Manager) distributions. @xref{Linux-RPM}.
+
+@c texi2html fails to split chapters if I use strong for all of this.
+If you run into problems, @strong{please always use @code{mysqlbug}} when
+posting questions to @email{mysql@@lists.mysql.com}. Even if the problem
+isn't a bug, @code{mysqlbug} gathers system information that will help others
+solve your problem. By not using @code{mysqlbug}, you lessen the likelihood
+of getting a solution to your problem! You will find @code{mysqlbug} in the
+@file{bin} directory after you unpack the distribution. @xref{Bug reports}.
+
+@cindex commands, for binary distribution
+The basic commands you must execute to install and use a MySQL
+binary distribution are:
+
+@example
+shell> groupadd mysql
+shell> useradd -g mysql mysql
+shell> cd /usr/local
+shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
+shell> ln -s full-path-to-mysql-VERSION-OS mysql
+shell> cd mysql
+shell> scripts/mysql_install_db
+shell> chown -R root .
+shell> chown -R mysql data
+shell> chgrp -R mysql .
+shell> bin/safe_mysqld --user=mysql &
+or
+shell> bin/mysqld_safe --user=mysql &
+if you are running MySQL 4.x
+@end example
+
+@cindex adding, new users
+@cindex new users, adding
+@cindex users, adding
+
+You can add new users using the @code{bin/mysql_setpermission} script if
+you install the @code{DBI} and @code{Msql-Mysql-modules} Perl modules.
+
+A more detailed description follows.
+
+To install a binary distribution, follow these steps, then proceed
+to @ref{Post-installation}, for post-installation setup and testing:
+
+@enumerate
+@item
+Pick the directory under which you want to unpack the distribution, and move
+into it. In the following example, we unpack the distribution under
+@file{/usr/local} and create a directory @file{/usr/local/mysql} into which
+MySQL is installed. (The following instructions, therefore, assume
+you have permission to create files in @file{/usr/local}. If that directory
+is protected, you will need to perform the installation as @code{root}.)
+
+@item
+Obtain a distribution file from one of the sites listed in
+@ref{Getting MySQL, , Getting MySQL}.
+
+MySQL binary distributions are provided as compressed @code{tar}
+archives and have names like @file{mysql-VERSION-OS.tar.gz}, where
+@code{VERSION} is a number (for example, @code{3.21.15}), and @code{OS}
+indicates the type of operating system for which the distribution is intended
+(for example, @code{pc-linux-gnu-i586}).
+
+@item
+If you see a binary distribution marked with the @code{-max} suffix, this
+means that the binary has support for transaction-safe tables and other
+features. @xref{mysqld-max, , @code{mysqld-max}}. Note that all binaries
+are built from the same MySQL source distribution.
+
+@item
+Add a user and group for @code{mysqld} to run as:
+
+@example
+shell> groupadd mysql
+shell> useradd -g mysql mysql
+@end example
+
+These commands add the @code{mysql} group and the @code{mysql} user. The
+syntax for @code{useradd} and @code{groupadd} may differ slightly on different
+versions of Unix. They may also be called @code{adduser} and @code{addgroup}.
+You may wish to call the user and group something else instead of @code{mysql}.
+
+@item
+Change into the intended installation directory:
+
+@example
+shell> cd /usr/local
+@end example
+
+@item
+Unpack the distribution and create the installation directory:
+
+@example
+shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
+shell> ln -s full-path-to-mysql-VERSION-OS mysql
+@end example
+
+The first command creates a directory named @file{mysql-VERSION-OS}. The
+second command makes a symbolic link to that directory. This lets you refer
+more easily to the installation directory as @file{/usr/local/mysql}.
+
+@item
+Change into the installation directory:
+
+@example
+shell> cd mysql
+@end example
+
+You will find several files and subdirectories in the @code{mysql} directory.
+The most important for installation purposes are the @file{bin} and
+@file{scripts} subdirectories.
+
+@table @file
+@item bin
+@tindex PATH environment variable
+@tindex environment variable, PATH
+This directory contains client programs and the server
+You should add the full pathname of this directory to your
+@code{PATH} environment variable so that your shell finds the MySQL
+programs properly. @xref{Environment variables}.
+
+@item scripts
+This directory contains the @code{mysql_install_db} script used to initialise
+the @code{mysql} database containing the grant tables that store the server
+access permissions.
+@end table
+
+@item
+If you would like to use @code{mysqlaccess} and have the MySQL
+distribution in some non-standard place, you must change the location where
+@code{mysqlaccess} expects to find the @code{mysql} client. Edit the
+@file{bin/mysqlaccess} script at approximately line 18. Search for a line
+that looks like this:
+
+@example
+$MYSQL = '/usr/local/bin/mysql'; # path to mysql executable
+@end example
+
+Change the path to reflect the location where @code{mysql} actually is
+stored on your system. If you do not do this, you will get a @code{Broken
+pipe} error when you run @code{mysqlaccess}.
+
+@item
+Create the MySQL grant tables (necessary only if you haven't
+installed MySQL before):
+@example
+shell> scripts/mysql_install_db
+@end example
+
+Note that MySQL versions older than Version 3.22.10 started the
+MySQL server when you run @code{mysql_install_db}. This is no
+longer true!
+
+@item
+Change ownership of binaries to @code{root} and ownership of the data
+directory to the user that you will run @code{mysqld} as:
+
+@example
+shell> chown -R root /usr/local/mysql/.
+shell> chown -R mysql /usr/local/mysql/data
+shell> chgrp -R mysql /usr/local/mysql/.
+@end example
+
+The first command changes the @code{owner} attribute of the files to the
+@code{root} user, the second one changes the @code{owner} attribute of the
+data directory to the @code{mysql} user, and the third one changes the
+@code{group} attribute to the @code{mysql} group.
+
+@item
+If you want to install support for the Perl @code{DBI}/@code{DBD} interface,
+see @ref{Perl support}.
+
+@item
+If you would like MySQL to start automatically when you boot your
+machine, you can copy @code{support-files/mysql.server} to the location where
+your system has its startup files. More information can be found in the
+@code{support-files/mysql.server} script itself and in
+@ref{Automatic start}.
+
+@end enumerate
+
+After everything has been unpacked and installed, you should initialise
+and test your distribution.
+
+You can start the MySQL server with the following command:
+
+@example
+shell> bin/safe_mysqld --user=mysql &
+@end example
+
+Now proceed to @ref{safe_mysqld, , @code{safe_mysqld}}, and
+@xref{Post-installation}.
+
@node Installing source, Post-installation, General Installation Issues, Installing
@section Installing a MySQL Source Distribution
@@ -7711,8 +6385,8 @@ and remove any @code{-fomit-frame-pointer} options.
@cindex installation overview
Before you proceed with the source installation, check first to see if our
-binary is available for your platform and if it will work for you. We
-put in a lot of effort into making sure that our binaries are built with the
+binary is available for your platform and if it will work for you. We
+put a lot of effort into making sure that our binaries are built with the
best possible options.
You need the following tools to build and install MySQL from source:
@@ -7733,8 +6407,8 @@ using @code{gcc}. @code{gcc} 2.7.x has a bug that makes it impossible
to compile some perfectly legal C++ files, such as
@file{sql/sql_base.cc}. If you only have @code{gcc} 2.7.x, you must
upgrade your @code{gcc} to be able to compile MySQL. @code{gcc}
-2.8.1 is also known to have problems on some platforms so it should be
-avoided if there exists a new compiler for the platform..
+2.8.1 is also known to have problems on some platforms, so it should be
+avoided if a new compiler exists for the platform.
@code{gcc} >= 2.95.2 is recommended when compiling MySQL
Version 3.23.x.
@@ -7745,27 +6419,29 @@ sometimes required. If you have problems, we recommend trying GNU
@code{make} 3.75 or newer.
@end itemize
-If you are using a recent version of @strong{gcc}, recent enough to understand
-@code{-fno-exceptions} option, it is @strong{VERY IMPORTANT} that you use
+If you are using a recent version of @code{gcc}, recent enough to understand the
+@code{-fno-exceptions} option, it is @strong{very important} that you use
it. Otherwise, you may compile a binary that crashes randomly. We also
-recommend that you use @code{-felide-contructors} and @code{-fno-rtti} along
+recommend that you use @code{-felide-constructors} and @code{-fno-rtti} along
with @code{-fno-exceptions}. When in doubt, do the following:
@example
-CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
+CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions \
+ -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler \
+ --with-mysqld-ldflags=-all-static
@end example
On most systems this will give you a fast and stable binary.
@c texi2html fails to split chapters if I use strong for all of this.
-If you run into problems, @strong{PLEASE ALWAYS USE @code{mysqlbug}} when
+If you run into problems, @strong{please always use @code{mysqlbug}} when
posting questions to @email{mysql@@lists.mysql.com}. Even if the problem
isn't a bug, @code{mysqlbug} gathers system information that will help others
solve your problem. By not using @code{mysqlbug}, you lessen the likelihood
of getting a solution to your problem! You will find @code{mysqlbug} in the
-@file{scripts} directory after you unpack the distribution.
+@file{scripts} directory after you unpack the distribution.
@xref{Bug reports}.
@menu
@@ -7775,6 +6451,7 @@ of getting a solution to your problem! You will find @code{mysqlbug} in the
* Installing source tree:: Installing from the Development Source Tree
* Compilation problems:: Problems Compiling?
* MIT-pthreads:: MIT-pthreads Notes
+* Windows source build:: Windows Source Distribution
@end menu
@@ -7798,14 +6475,17 @@ shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
+or
+shell> /usr/local/mysql/bin/mysqld_safe --user=mysql &
+if you are running MySQL 4.x.
@end example
-If you want have support for InnoDB tables, you should edit the
+If you want to have support for InnoDB tables, you should edit the
@code{/etc/my.cnf} file and remove the @code{#} character before the
-parameters that starts with @code{innodb_...}. @xref{Option
-files}. @xref{InnoDB start}.
+parameter that starts with @code{innodb_...}.
+@xref{Option files}, and @ref{InnoDB start}.
-If you start from a source RPM, then do the following:
+If you start from a source RPM, do the following:
@example
shell> rpm --rebuild MySQL-VERSION.src.rpm
@@ -7818,8 +6498,8 @@ you install the @code{DBI} and @code{Msql-Mysql-modules} Perl modules.
A more detailed description follows.
-To install a source distribution, follow the steps below, then proceed
-to @ref{Post-installation}, for post-installation initialization and testing:
+To install a source distribution, follow these steps, then proceed
+to @ref{Post-installation}, for post-installation initialisation and testing:
@enumerate
@item
@@ -7848,7 +6528,7 @@ shell> groupadd mysql
shell> useradd -g mysql mysql
@end example
-These commands add the @code{mysql} group, and the @code{mysql} user. The
+These commands add the @code{mysql} group and the @code{mysql} user. The
syntax for @code{useradd} and @code{groupadd} may differ slightly on different
versions of Unix. They may also be called @code{adduser} and @code{addgroup}.
You may wish to call the user and group something else instead of @code{mysql}.
@@ -7869,7 +6549,7 @@ shell> cd mysql-VERSION
@end example
Note that currently you must configure and build MySQL from
-this top-level directory. You can not build it in a different
+this top-level directory. You cannot build it in a different
directory.
@item
@@ -7917,7 +6597,7 @@ MySQL server when you run @code{mysql_install_db}. This is no
longer true!
@item
-Change ownership of binaries to @code{root} and ownership of the data
+Change ownership of binaries to @code{root} and ownership of the data
directory to the user that you will run @code{mysqld} as:
@example
@@ -7927,7 +6607,7 @@ shell> chgrp -R mysql /usr/local/mysql
@end example
The first command changes the @code{owner} attribute of the files to the
-@code{root} user, the second one changes the @code{owner} attribute of the
+@code{root} user, the second one changes the @code{owner} attribute of the
data directory to the @code{mysql} user, and the third one changes the
@code{group} attribute to the @code{mysql} group.
@@ -7939,23 +6619,23 @@ see @ref{Perl support}.
If you would like MySQL to start automatically when you boot your
machine, you can copy @code{support-files/mysql.server} to the location where
your system has its startup files. More information can be found in the
-@code{support-files/mysql.server} script itself and in
+@code{support-files/mysql.server} script itself and in
@ref{Automatic start}.
@end enumerate
-After everything has been installed, you should initialize and test your
+After everything has been installed, you should initialise and test your
distribution:
@example
shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
@end example
-If that command fails immediately with @code{mysqld daemon ended} then you can
+If that command fails immediately with @code{mysqld daemon ended}, you can
find some information in the file @file{mysql-data-directory/'hostname'.err}.
-The likely reason is that you already have another @code{mysqld} server
+The likely reason is that you already have another @code{mysqld} server
running. @xref{Multiple servers}.
-@xref{Post-installation}.
+Now proceed to @ref{Post-installation}.
@node Applying patches, configure options, Quick install, Installing source
@@ -7965,8 +6645,8 @@ running. @xref{Multiple servers}.
@cindex applying, patches
Sometimes patches appear on the mailing list or are placed in the
-@uref{http://www.mysql.com/Downloads/Patches, patches area} of the
-MySQL Web site.
+patches area of the MySQL web site
+(@uref{http://www.mysql.com/Downloads/Patches/}).
To apply a patch from the mailing list, save the message in which the patch
appears in a file, change into the top-level directory of your MySQL
@@ -7979,7 +6659,8 @@ shell> make clean
@end example
Patches from the FTP site are distributed as plain text files or as files
-compressed with @code{gzip}. Apply a plain patch as shown above for
+compressed with @code{gzip}. Apply a plain patch as shown
+previously for
mailing list patches. To apply a compressed patch, change into the
top-level directory of your MySQL source tree and run these
commands:
@@ -8012,7 +6693,7 @@ the version that is currently executing.
The @code{configure} script gives you a great deal of control over how
you configure your MySQL distribution. Typically you do this
-using options on the @code{configure} command line. You can also affect
+using options on the @code{configure} command-line. You can also affect
@code{configure} using certain environment variables. @xref{Environment
variables}. For a list of options supported by @code{configure}, run
this command:
@@ -8021,7 +6702,7 @@ this command:
shell> ./configure --help
@end example
-Some of the more commonly-used @code{configure} options are described below:
+Some of the more commonly-used @code{configure} options are described here:
@itemize @bullet
@item
@@ -8043,6 +6724,10 @@ warnings about @file{mysql.cc}. (If @code{make} stops, try @code{make -k}
to tell it to continue with the rest of the build even if errors occur.)
@item
+If you want to get an embedded MySQL library (@code{libmysqld.a}) you should
+use the @code{--with-embedded-server} option.
+
+@item
If you don't want your log files and database directories located under
@file{/usr/local/var}, use a @code{configure} command, something like one
of these:
@@ -8058,7 +6743,8 @@ installed under @file{/usr/local/mysql} rather than the default of
@file{/usr/local}. The second command preserves the default installation
prefix, but overrides the default location for database directories
(normally @file{/usr/local/var}) and changes it to
-@code{/usr/local/mysql/data}.
+@code{/usr/local/mysql/data}. After you have compiled MySQL, you can
+change these options with option files. @xref{Option files}.
@cindex changing socket location
@cindex socket location, changing
@@ -8073,7 +6759,7 @@ shell> ./configure --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
@end example
Note that the given file must be an absolute pathname!
-You can also later change the location @file{mysql.sock} by using the MySQL
+You can also later change the location @file{mysql.sock} by using the MySQL
option files. @xref{Problems with mysql.sock}.
@cindex compiling, statically
@@ -8107,41 +6793,51 @@ shell> CC=gcc CXX=gcc ./configure
@end example
When you use @code{gcc} as your C++ compiler, it will not attempt to link in
-@code{libg++} or @code{libstdc++}.
+@code{libg++} or @code{libstdc++}. This may be a good idea to do even if you
+have the above libraries installed, as some versions of these libraries have
+caused strange problems for MySQL users in the past.
-Here is some common environment variables to set depending on
+Here are some common environment variables to set depending on
the compiler you are using:
@tindex CXXFLAGS environment variable
@tindex environment variable, CXXFLAGS
-@multitable @columnfractions .20 .80
+@multitable @columnfractions .19 .81
+@item @strong{Compiler} @tab @strong{Recommended options}
@item gcc 2.7.2.1 @tab
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors"
@item egcs 1.0.3a @tab
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti"
@item gcc 2.95.2 @tab
-CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti"
+CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
+-felide-constructors -fno-exceptions -fno-rtti"
@item pgcc 2.90.29 or newer @tab
-CFLAGS="-O3 -mpentiumpro -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti"
+CFLAGS="-O3 -mpentiumpro -mstack-align-double" CXX=gcc \
+CXXFLAGS="-O3 -mpentiumpro -mstack-align-double -felide-constructors \
+-fno-exceptions -fno-rtti"
@end multitable
In most cases you can get a reasonably optimal MySQL binary by
-using the options from the above and adding the following options to the
-configure line:
+using the options from the preceding table and adding the following options to the
+configure line:
@example
---prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
+--prefix=/usr/local/mysql --enable-assembler \
+--with-mysqld-ldflags=-all-static
@end example
-The full configure line would in other words be something like the
+The full configure line would, in other words, be something like the
following for all recent gcc versions:
@example
-CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
+CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
+-felide-constructors -fno-exceptions -fno-rtti" ./configure \
+--prefix=/usr/local/mysql --enable-assembler \
+--with-mysqld-ldflags=-all-static
@end example
-The binaries we provide on the MySQL Web site at
-@uref{http://www.mysql.com} are all compiled with full optimization and
+The binaries we provide on the MySQL web site at
+@uref{http://www.mysql.com/} are all compiled with full optimisation and
should be perfect for most users. @xref{MySQL binaries}. There are some
things you can tweak to make an even faster binary, but this is only for
advanced users. @xref{Compile and link options}.
@@ -8186,21 +6882,22 @@ shell> ./configure --with-charset=CHARSET
@xref{Character sets}.
If you want to convert characters between the server and the client,
-you should take a look at the @code{SET OPTION CHARACTER SET} command.
-@xref{SET OPTION, , @code{SET OPTION}}.
+you should take a look at the @code{SET CHARACTER SET} command.
+@xref{SET OPTION, , @code{SET}}.
@cindex @code{myisamchk}
-@strong{Warning:} If you change character sets after having created any
+@strong{Warning}: If you change character sets after having created any
tables, you will have to run @code{myisamchk -r -q} on every table. Your
indexes may be sorted incorrectly otherwise. (This can happen if you
install MySQL, create some tables, then reconfigure
MySQL to use a different character set and reinstall it.)
With the option @code{--with-extra-charset=LIST} you can define
-which additional character sets should be incompiled in the server.
+which additional character sets should be compiled into the server.
-Here @code{LIST} is either a list of character set separated with space,
-@code{complex} to include all characters that can't be dynamically loaded
+Here @code{LIST} is either a list of character
+sets separated with spaces,
+@code{complex} to include all characters that can't be dynamically loaded,
or @code{all} to include all character sets into the binaries.
@item
@@ -8222,7 +6919,7 @@ applications. @xref{Threaded clients}.
@item
Options that pertain to particular systems can be found in the
-system-specific section of this manual.
+system-specific section of this manual.
@xref{Operating System Specific Notes}.
@end itemize
@@ -8234,7 +6931,7 @@ system-specific section of this manual.
@cindex BitKeeper tree
@cindex cvs tree
-@strong{CAUTION:} You should read this section only if you are interested
+@strong{Caution}: You should read this section only if you are interested
in helping us test our new code. If you just want to get MySQL up
and running on your system, you should use a standard release distribution
(either a source or binary distribution will do).
@@ -8243,15 +6940,16 @@ To obtain our most recent development source tree, use these instructions:
@enumerate
@item
-Download @strong{BitKeeper} from
+Download @code{BitKeeper} from
@uref{http://www.bitmover.com/cgi-bin/download.cgi}. You will need
-@strong{Bitkeeper} 2.0 or newer to access our repository.
+@code{Bitkeeper} 2.0 or newer to access our repository.
@item
Follow the instructions to install it.
@item
-After @strong{BitKeeper} is installed, use this command if you want to clone
+After @code{BitKeeper} is installed, first go to the directory you
+want to work from, and then use this command if you want to clone
the MySQL 3.23 branch:
@example
@@ -8264,34 +6962,40 @@ To clone the 4.0 branch, use this command instead:
shell> bk clone bk://work.mysql.com:7001 mysql-4.0
@end example
+In the preceding examples the source tree will be set up in the @file{mysql/}
+or @file{mysql-4.0/} subdirectory of your current directory.
+
The initial download of the source tree may take a while, depending on the
speed of your connection; be patient.
@item
-You will need GNU @code{autoconf}, @code{automake}, @code{libtool}, and
-@code{m4} to run the next set of commands.
-If you get some strange error during this stage, check that you really
-have @code{libtool} installed!
+You will need GNU @code{autoconf 2.52}, @code{automake 1.4},
+@code{libtool}, and @code{m4} to run the next set of commands.
+
+@code{automake} (1.5) doesn't yet work.
@example
-shell> cd mysql
-shell> bk -r edit
+shell> cd mysql-4.0
+shell> bk -r get -Sq
shell> aclocal; autoheader; autoconf; automake;
shell> ./configure # Add your favorite options here
shell> make
@end example
+If you get some strange error during this stage, check that you really
+have @code{libtool} installed!
+
A collection of our standard configure scripts is located in the
@file{BUILD/} subdirectory. If you are lazy, you can use
@file{BUILD/compile-pentium-debug}. To compile on a different architecture,
-modify the script removing flags that are Pentium-specific.
+modify the script by removing flags that are Pentium-specific.
@item
When the build is done, run @code{make install}. Be careful with this
on a production machine; the command may overwrite your live release
installation. If you have another installation of MySQL, we
recommand that you run @code{./configure} with different values for the
-@code{prefix}, @code{tcp-port}, and @code{unix-socket-path} options than
+@code{prefix}, @code{with-tcp-port}, and @code{unix-socket-path} options than
those used for your production server.
@item
@@ -8306,7 +7010,7 @@ crash trying to process our configuration files, please report that also.
However, if you execute @code{aclocal} and get a @code{command not found}
error or a similar problem, do not report it. Instead, make sure all
the necessary tools are installed and that your @code{PATH} variable is
-set correctly so your shell can find them.
+set correctly so that your shell can find them.
@item
After the initial @code{bk clone} operation to get the source tree, you
@@ -8317,13 +7021,13 @@ You can examine the change history for the tree with all the diffs by using
@code{bk sccstool}. If you see some funny diffs or code that you have a
question about, do not hesitate to send e-mail to
@email{internals@@lists.mysql.com}. Also, if you think you have a better idea
-on how to do something, send an email to the same address with a patch.
+on how to do something, send an e-mail to the same address with a patch.
@code{bk diffs} will produce a patch for you after you have made changes
to the source. If you do not have the time to code your idea, just send
a description.
@item
-@strong{BitKeeper} has a nice help utility that you can access via
+@code{BitKeeper} has a nice help utility that you can access via
@code{bk helptool}.
@end enumerate
@@ -8341,8 +7045,8 @@ a description.
All MySQL programs compile cleanly for us with no warnings on
Solaris using @code{gcc}. On other systems, warnings may occur due to
differences in system include files. See @ref{MIT-pthreads} for warnings
-that may occur when using MIT-pthreads. For other problems, check the list
-below.
+that may occur when using MIT-pthreads. For other problems, check
+the following list.
The solution to many problems involves reconfiguring. If you do need to
reconfigure, take note of the following:
@@ -8363,7 +7067,7 @@ when you reconfigure.
@item
Each time you run @code{configure}, you must run @code{make} again
to recompile. However, you may want to remove old object files from previous
-builds first, because they were compiled using different configuration options.
+builds first because they were compiled using different configuration options.
@end itemize
To prevent old configuration information or object files from being used,
@@ -8376,7 +7080,7 @@ shell> make clean
Alternatively, you can run @code{make distclean}.
-The list below describes some of the problems compiling MySQL
+The following list describes some of the problems when compiling MySQL
that have been found to occur most often:
@itemize @bullet
@@ -8388,7 +7092,7 @@ that have been found to occur most often:
@cindex virtual memory, problems while compiling
@cindex configure option, --with-low-memory
If you get errors when compiling @file{sql_yacc.cc}, such as the ones shown
-below, you have probably run out of memory or swap space:
+here, you have probably run out of memory or swap space:
@example
Internal compiler error: program cc1plus got fatal signal 11
@@ -8416,7 +7120,7 @@ configurations, and the @code{--with-low-memory} option usually fixes it.
@item
By default, @code{configure} picks @code{c++} as the compiler name and
GNU @code{c++} links with @code{-lg++}. If you are using @code{gcc},
-that behavior can cause problems during configuration such as this:
+that behaviour can cause problems during configuration such as this:
@cindex C++ compiler cannot create executables
@example
@@ -8446,7 +7150,11 @@ This works because @code{gcc} compiles C++ sources as well as @code{g++}
does, but does not link in @code{libg++} or @code{libstdc++} by default.
Another way to fix these problems, of course, is to install @code{g++},
-@code{libg++} and @code{libstdc++}.
+@code{libg++}, and @code{libstdc++}. We would however like to recommend
+you to not use @code{libg++} or @code{libstdc++} with MySQL as this will
+only increase the binary size of mysqld without giving you any benefits.
+Some versions of these libraries have also caused strange problems for
+MySQL users in the past.
@item
If your compile fails with errors, such as any of the following,
@@ -8507,7 +7215,7 @@ client/libmysql.c:273: parse error before `__attribute__'
@code{egcs} 1.0.3a instead.
@item
-If you get errors such as those shown below when compiling @code{mysqld},
+If you get errors such as those shown here when compiling @code{mysqld},
@code{configure} didn't correctly detect the type of the last argument to
@code{accept()}, @code{getsockname()}, or @code{getpeername()}:
@@ -8528,12 +7236,12 @@ To fix this, edit the @file{config.h} file (which is generated by
Change @code{XXX} to @code{size_t} or @code{int}, depending on your
operating system. (Note that you will have to do this each time you run
-@code{configure}, because @code{configure} regenerates @file{config.h}.)
+@code{configure} because @code{configure} regenerates @file{config.h}.)
@item
The @file{sql_yacc.cc} file is generated from @file{sql_yacc.yy}. Normally
the build process doesn't need to create @file{sql_yacc.cc}, because
-MySQL comes with an already-generated copy. However, if you do need
+MySQL comes with an already generated copy. However, if you do need
to re-create it, you might encounter this error:
@example
@@ -8551,7 +7259,7 @@ link your clients with the new client library. @xref{Debugging client}.
@end itemize
-@node MIT-pthreads, , Compilation problems, Installing source
+@node MIT-pthreads, Windows source build, Compilation problems, Installing source
@subsection MIT-pthreads Notes
@cindex MIT-pthreads
@@ -8559,7 +7267,7 @@ link your clients with the new client library. @xref{Debugging client}.
This section describes some of the issues involved in using MIT-pthreads.
-Note that on Linux you should NOT use MIT-pthreads but install LinuxThreads!
+Note that on Linux you should @strong{not} use MIT-pthreads but install LinuxThreads!
@xref{Linux}.
If your system does not provide native thread support, you will need to
@@ -8577,21 +7285,24 @@ shell> ./configure --with-mit-threads
@end example
Building in a non-source directory is not supported when using
-MIT-pthreads, because we want to minimize our changes to this code.
+MIT-pthreads because we want to minimise our changes to this code.
@item
-The checks that determine whether or not to use MIT-pthreads occur only
+The checks that determine whether to use MIT-pthreads occur only
during the part of the configuration process that deals with the server
code. If you have configured the distribution using @code{--without-server}
-to build only the client code, clients will not know whether or not
+to build only the client code, clients will not know whether
MIT-pthreads is being used and will use Unix socket connections by default.
-Because Unix sockets do not work under MIT-pthreads, this means you will need
-to use @code{-h} or @code{--host} when you run client programs.
+Because Unix sockets do not work under MIT-pthreads on some platforms, this
+means you will need to use @code{-h} or @code{--host} when you run client
+programs.
@item
When MySQL is compiled using MIT-pthreads, system locking is
disabled by default for performance reasons. You can tell the server to use
-system locking with the @code{--use-locking} option.
+system locking with the @code{--external-locking} option. This is only
+needed if you want to be able to run two MySQL server against the same
+data files (not recommended).
@item
Sometimes the pthread @code{bind()} command fails to bind to a socket without
@@ -8610,7 +7321,7 @@ a restart immediately.
@item
With MIT-pthreads, the @code{sleep()} system call isn't interruptible with
-@code{SIGINT} (break). This is only noticeable when you run
+@code{SIGINT} (break). This is only noticeable when you run
@code{mysqladmin --sleep}. You must wait for the @code{sleep()} call to
terminate before the interrupt is served and the process stops.
@@ -8643,6 +7354,75 @@ needed, but may be interesting for someone.)
@end itemize
+@node Windows source build, , MIT-pthreads, Installing source
+@subsection Windows Source Distribution
+
+You will need the following:
+
+@itemize @bullet
+@item
+VC++ 6.0 compiler (updated with 4 or 5 SP and Pre-processor package)
+The Pre-processor package is necessary for the macro assembler.
+More details at:
+@uref{http://msdn.microsoft.com/vstudio/sp/vs6sp5/faq.asp}.
+@item
+The MySQL source distribution for Windows, which can be downloaded
+from @uref{http://www.mysql.com/downloads/}.
+@end itemize
+
+Building MySQL
+
+@enumerate
+@item
+Create a work directory (e.g., workdir).
+@item
+Unpack the source distribution in the aforementioned directory.
+@item
+Start the VC++ 6.0 compiler.
+@item
+In the @code{File} menu, select @code{Open Workspace}.
+@item
+Open the @file{mysql.dsw} workspace you find on the work directory.
+@item
+From the @code{Build} menu,
+select the @code{Set Active Configuration} menu.
+@item
+Click over the screen selecting @code{mysqld - Win32 Debug}
+and click OK.
+@item
+Press @code{F7} to begin the build of the debug server, libs, and
+some client applications.
+@item
+When the compilation finishes, copy the libs and the executables
+to a separate directory.
+@item
+Compile the release versions that you want, in the same way.
+@item
+Create the directory for the MySQL stuff: e.g., @file{c:\mysql}
+@item
+From the workdir directory copy for the c:\mysql directory the
+following directories:
+
+@itemize @bullet
+@item Data
+@item Docs
+@item Share
+@end itemize
+
+@item
+Create the directory @file{c:\mysql\bin} and copy all the servers
+and clients that you compiled previously.
+@item
+If you want, also create the @file{lib} directory and copy the
+libs that you compiled previously.
+@item
+Do a clean using Visual Studio.
+@end enumerate
+
+Set up and start the server in the same way as for the binary
+Windows distribution. @xref{Windows prepare environment}.
+
+
@node Post-installation, Upgrade, Installing source, Installing
@section Post-installation Setup and Testing
@@ -8657,7 +7437,7 @@ needed, but may be interesting for someone.)
@end menu
Once you've installed MySQL (from either a binary or source
-distribution), you need to initialize the grant tables, start the server,
+distribution), you need to initialise the grant tables, start the server,
and make sure that the server works okay. You may also wish to arrange
for the server to be started and stopped automatically when your system
starts up and shuts down.
@@ -8683,7 +7463,7 @@ shell> ./bin/safe_mysqld --user=mysql &
This creates the @code{mysql} database which will hold all database
privileges, the @code{test} database which you can use to test
-MySQL and also privilege entries for the user that run
+MySQL, and also privilege entries for the user that run
@code{mysql_install_db} and a @code{root} user (without any passwords).
This also starts the @code{mysqld} server.
@@ -8698,7 +7478,7 @@ distribution. For a binary distribution, this is your installation directory
distribution, this is the main directory of your MySQL source tree.
@cindex testing, the server
-In the commands shown below in this section and in the following
+In the commands shown in this section and in the following
subsections, @code{BINDIR} is the path to the location in which programs
like @code{mysqladmin} and @code{safe_mysqld} are installed. For a
binary distribution, this is the @file{bin} directory within the
@@ -8710,7 +7490,7 @@ installed. For a binary distribution, this is the same as
@code{BINDIR}. For a source distribution, @code{EXECDIR} is probably
@file{/usr/local/libexec}.
-Testing is described in detail below:
+Testing is described in detail:
@cindex testing, installation
@enumerate
@@ -8735,7 +7515,7 @@ you are unsure of what to do, you can always run @code{mysql_install_db}.)
@code{mysql} database. A description of the initial privileges is given in
@ref{Default privileges}. Briefly, these privileges allow the MySQL
@code{root} user to do anything, and allow anybody to create or use databases
-with a name of @code{'test'} or starting with @code{'test_'}.
+with a name of @code{test} or starting with @code{test_}.
If you don't set up the grant tables, the following error will appear in the
log file when you start the server:
@@ -8745,13 +7525,13 @@ log file when you start the server:
mysqld: Can't find file: 'host.frm'
@end example
-The above may also happen with a binary MySQL distribution if you
+This may also happen with a binary MySQL distribution if you
don't start MySQL by executing exactly @code{./bin/safe_mysqld}!
@xref{safe_mysqld, , @code{safe_mysqld}}.
You might need to run @code{mysql_install_db} as @code{root}. However,
if you prefer, you can run the MySQL server as an unprivileged
-(non-@code{root}) user, provided that user can read and write files in
+(non-@code{root}) user, provided that the user can read and write files in
the database directory. Instructions for running MySQL as an
unprivileged user are given in @ref{Changing MySQL user, , Changing
MySQL user}.
@@ -8764,10 +7544,10 @@ script as it is provided in the MySQL distribution:
@itemize @bullet
@item
-You may want to edit @code{mysql_install_db} before running it, to change
-the initial privileges that are installed into the grant tables. This is
-useful if you want to install MySQL on a lot of machines with the
-same privileges. In this case you probably should need only to add a few
+You may want to edit @code{mysql_install_db} before running it, to change
+the initial privileges that are installed into the grant tables. This is
+useful if you want to install MySQL on a lot of machines with the
+same privileges. In this case you probably should need only to add a few
extra @code{INSERT} statements to the @code{mysql.user} and @code{mysql.db}
tables!
@@ -8807,15 +7587,14 @@ shell> BINDIR/mysqladmin variables
@end example
The output from @code{mysqladmin version} varies slightly depending on your
-platform and version of MySQL, but should be similar to that shown
-below:
+platform and version of MySQL, but should be similar to that shown here:
@example
shell> BINDIR/mysqladmin version
mysqladmin Ver 8.14 Distrib 3.23.32, for linux on i586
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
-and you are welcome to modify and redistribute it under the GPL license
+and you are welcome to modify and redistribute it under the GPL license.
Server version 3.23.32-debug
Protocol version 10
@@ -8824,7 +7603,10 @@ TCP port 3306
UNIX socket /tmp/mysql.sock
Uptime: 16 sec
-Threads: 1 Questions: 9 Slow queries: 0 Opens: 7 Flush tables: 2 Open tables: 0 Queries per second avg: 0.000 Memory in use: 132K Max memory used: 16773K
+Threads: 1 Questions: 9 Slow queries: 0
+Opens: 7 Flush tables: 2 Open tables: 0
+Queries per second avg: 0.000
+Memory in use: 132K Max memory used: 16773K
@end example
To get a feeling for what else you can do with @code{BINDIR/mysqladmin},
@@ -8856,7 +7638,7 @@ see @ref{Starting server}.
@item
Run some simple tests to verify that the server is working.
-The output should be similar to what is shown below:
+The output should be similar to what is shown here:
@example
shell> BINDIR/mysqlshow
@@ -8879,7 +7661,7 @@ Database: mysql
| user |
+--------------+
-shell> BINDIR/mysql -e "select host,db,user from db" mysql
+shell> BINDIR/mysql -e "SELECT host,db,user FROM db" mysql
+------+--------+------+
| host | db | user |
+------+--------+------+
@@ -8971,7 +7753,7 @@ example, for testing, or perhaps you simply want to run two installations at
the same time). Generally the problem that occurs when you try to run the
second server is that it tries to use the same socket and port as the old one.
In this case you will get the error message: @code{Can't start server: Bind on
-TCP/IP port: Address already in use} or @code{Can't start server : Bind on
+TCP/IP port: Address already in use} or @code{Can't start server: Bind on
unix socket...}. @xref{Installing many servers}.
@item You don't have write access to @file{/tmp}
@@ -8996,7 +7778,7 @@ shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysqld.sock
shell> export TMPDIR MYSQL_UNIX_PORT
@end example
-@xref{Problems with mysql.sock}.
+See @ref{Problems with mysql.sock}.
@file{some_tmp_dir} should be the path to some directory for which you
have write permission. @xref{Environment variables}.
@@ -9015,7 +7797,7 @@ If you are running RedHat Version 5.0 with a version of @code{glibc} older than
2.0.7-5, you should make sure you have installed all @code{glibc} patches!
There is a lot of information about this in the MySQL mail
archives. Links to the mail archives are available online at
-@uref{http://www.mysql.com/documentation/}.
+@uref{http://lists.mysql.com/}.
Also, see @ref{Linux}.
You can also start @code{mysqld} manually using the @code{--skip-grant-tables}
@@ -9038,11 +7820,11 @@ reload the grant tables.
@cindex server, starting problems
@cindex problems, starting the server
-If you are going to use tables that support transactions (BDB, InnoDB),
+If you are going to use tables that support transactions (InnoDB, BDB),
you should first create a my.cnf file and set startup options
for the table types you plan to use. @xref{Table types}.
-Generally, you start the @code{mysqld} server in one of three ways:
+Generally, you start the @code{mysqld} server in one of these ways:
@itemize @bullet
@item
@@ -9056,29 +7838,13 @@ for @code{mysqld} and then runs it with those options. @xref{safe_mysqld, ,
@code{safe_mysqld}}.
@item
-On NT you should install @code{mysqld} as a service as follows:
-@example
-bin\mysqld-nt --install # Install MySQL as a service
-@end example
-
-You can now start/stop @code{mysqld} as follows:
-@example
-NET START mysql
-NET STOP mysql
-@end example
-
-Note that in this case you can't use any other options for @code{mysqld}!
-
-You can remove the service as follows:
-@example
-bin\mysqld-nt --remove # remove MySQL as a service
-@end example
+For Windows NT/2000/XP, please see @ref{NT start}.
@item
By invoking @code{mysqld} directly.
@end itemize
-When the @code{mysqld} daemon starts up, it changes directory to the
+When the @code{mysqld} daemon starts up, it changes the directory to the
data directory. This is where it expects to write log files and the pid
(process ID) file, and where it expects to find databases.
@@ -9094,7 +7860,7 @@ defaults by specifying the correct pathnames as command-line arguments to
Normally you should need to tell @code{mysqld} only the base directory under
which MySQL is installed. You can do this with the @code{--basedir}
option. You can also use @code{--help} to check the effect of changing path
-options (note that @code{--help} @emph{must} be the final option of the
+options (note that @code{--help} @strong{must} be the final option of the
@code{mysqld} command). For example:
@example
@@ -9108,8 +7874,8 @@ Whichever method you use to start the server, if it fails to start up
correctly, check the log file to see if you can find out why. Log files
are located in the data directory (typically
@file{/usr/local/mysql/data} for a binary distribution,
-@file{/usr/local/var} for a source distribution,
-@file{\mysql\data\mysql.err} on Windows.) Look in the data directory for
+@file{/usr/local/var} for a source distribution, and
+@file{\mysql\data\mysql.err} on Windows). Look in the data directory for
files with names of the form @file{host_name.err} and
@file{host_name.log} where @code{host_name} is the name of your server
host. Then check the last few lines of these files:
@@ -9119,7 +7885,7 @@ shell> tail host_name.err
shell> tail host_name.log
@end example
-If you find something like the following in the log file:
+Look for something like the following in the log file:
@example
000729 14:50:10 bdb: Recovery function for LSN 1 27595 failed
000729 14:50:10 bdb: warning: ./test/t1.db: No such file or directory
@@ -9130,7 +7896,7 @@ This means that you didn't start @code{mysqld} with @code{--bdb-no-recover}
and Berkeley DB found something wrong with its log files when it
tried to recover your databases. To be able to continue, you should
move away the old Berkeley DB log file from the database directory to
-some other place, where you can later examine these. The log files are
+some other place, where you can later examine it. The log files are
named @file{log.0000000001}, where the number will increase over time.
If you are running @code{mysqld} with BDB table support and @code{mysqld} core
@@ -9153,7 +7919,7 @@ Can't start server : Bind on unix socket...
Use @code{ps} to make sure that you don't have another @code{mysqld} server
running. If you can't find another server running, you can try to execute
the command @code{telnet your-host-name tcp-ip-port-number} and press
-@code{RETURN} a couple of times. If you don't get an error message like
+Enter a couple of times. If you don't get an error message like
@code{telnet: Unable to connect to remote host: Connection refused},
something is using the TCP/IP port @code{mysqld} is trying to use.
See @ref{mysql_install_db} and @ref{Multiple servers}.
@@ -9171,6 +7937,13 @@ or
shell> mysqladmin -h 'your-host-name' variables
@end example
+If you get @code{Errcode 13}, which means @code{Permission denied}, when
+starting @code{mysqld} this means that you didn't have the right to
+read/create files in the MySQL database or log directory. In this case
+you should either start @code{mysqld} as the root user or change the
+permissions for the involved files and directories so that you have the
+right to use them.
+
If @code{safe_mysqld} starts the server but you can't connect to it,
you should make sure you have an entry in @file{/etc/hosts} that looks like
this:
@@ -9188,7 +7961,7 @@ to find the problem. @xref{Making trace files}.
If you are using InnoDB tables, refer to the InnoDB-specific startup
options. @xref{InnoDB start}.
-If you are using BDB (Berkeley DB) tables, you should familiarize
+If you are using BDB (Berkeley DB) tables, you should familiarise
yourself with the different BDB specific startup options. @xref{BDB start}.
@@ -9215,10 +7988,10 @@ shell> mysql.server stop
under the MySQL installation directory or in the @file{support-files}
directory of the MySQL source tree.
-Before @code{mysql.server} starts the server, it changes directory to
+Before @code{mysql.server} starts the server, it changes the directory to
the MySQL installation directory, then invokes @code{safe_mysqld}.
You might need to edit @code{mysql.server} if you have a binary distribution
-that you've installed in a non-standard location. Modify it to @code{cd}
+that you've installed in a non-standard location. Modify it to @code{cd}
into the proper directory before it runs @code{safe_mysqld}. If you want the
server to run as some specific user, add an appropriate @code{user} line
to the @file{/etc/my.cnf} file, as shown later in this section.
@@ -9228,7 +8001,7 @@ You can take down the server manually by executing @code{mysqladmin shutdown}.
You might want to add these start and stop commands to the appropriate places
in your @file{/etc/rc*} files when you start using MySQL for
-production applications. Note that if you modify @code{mysql.server}, then
+production applications. Note that if you modify @code{mysql.server}, and then
upgrade MySQL sometime, your modified version will be overwritten,
so you should make a copy of your edited version that you can reinstall.
@@ -9260,7 +8033,7 @@ The @code{mysql.server} script understands the following options:
The following table shows which option groups each of the startup scripts
read from option files:
-@multitable @columnfractions .20 .80
+@multitable @columnfractions .15 .35
@item @strong{Script} @tab @strong{Option groups}
@item @code{mysqld} @tab @code{mysqld} and @code{server}
@item @code{mysql.server} @tab @code{mysql.server}, @code{mysqld}, and @code{server}
@@ -9276,15 +8049,15 @@ read from option files:
@cindex upgrading
@cindex downgrading
-You can always move the MySQL form and data files between
+You can always move the MySQL form and datafiles between
different versions on the same architecture as long as you have the same
base version of MySQL. The current base version is
3. If you change the character set when running MySQL (which may
also change the sort order), you must run @code{myisamchk -r -q} on all
-tables. Otherwise your indexes may not be ordered correctly.
+tables. Otherwise, your indexes may not be ordered correctly.
If you are afraid of new versions, you can always rename your old
-@code{mysqld} to something like @code{mysqld}-'old-version-number'. If
+@code{mysqld} to something like @code{mysqld-old-version-number}. If
your new @code{mysqld} then does something unexpected, you can simply shut it
down and restart with your old @code{mysqld}!
@@ -9301,7 +8074,7 @@ If you get some problems that the new @code{mysqld} server doesn't want to
start or that you can't connect without a password, check that you don't
have some old @file{my.cnf} file from your old installation! You can
check this with: @code{program-name --print-defaults}. If this outputs
-anything other than the program name, you have an active @code{my.cnf}
+anything other than the program name, you have an active @file{my.cnf}
file that will affect things!
It is a good idea to rebuild and reinstall the @code{Msql-Mysql-modules}
@@ -9310,14 +8083,172 @@ particularly if you notice symptoms such as all your @code{DBI} scripts
dumping core after you upgrade MySQL.
@menu
+* Upgrading-from-3.23:: Upgrading from a 3.23 version to 4.0
* Upgrading-from-3.22:: Upgrading from a 3.22 version to 3.23
* Upgrading-from-3.21:: Upgrading from a 3.21 version to 3.22
* Upgrading-from-3.20:: Upgrading from a 3.20 version to 3.21
* Upgrading-to-arch:: Upgrading to another architecture
@end menu
+@cindex compatibility, between MySQL versions
+@cindex upgrading, 3.23 to 4.0
+@node Upgrading-from-3.23, Upgrading-from-3.22, Upgrade, Upgrade
+@subsection Upgrading From Version 3.23 to Version 4.0
+
+You can use your old datafiles without any modification with Version 4.0.
+If you want to move your data from a MySQL 4.0 server to an older server,
+you have to use @code{mysqldump}.
+
+Old clients should work with a Version 4.0 server without any problems.
+
+The following lists tell what you have to watch out for when upgrading to
+version 4.0;
+
+@itemize @bullet
+@item
+MySQL 4.0 has a lot of new privileges in the @code{mysql.user} table.
+@xref{GRANT}.
+
+To get these new privileges to work, one must run the
+@code{mysql_fix_privilege_tables} script. Until this script is run all
+users have the @code{SHOW DATABASES}, @code{CREATE TEMPORARY TABLES},
+and @code{LOCK TABLES} privileges. @code{SUPER} and @code{EXECUTE}
+privileges take their value from @code{PROCESS}.
+@code{REPLICATION SLAVE} and @code{REPLICATION CLIENT} take their
+values from @code{FILE}.
+
+If you have any scripts that creates new users, you may want to change
+them to use the new privileges. If you are not using @code{GRANT}
+commands in the scripts, this is a good time to change your scripts.
+
+In version 4.0.2 the option @code{--safe-show-database} is deprecated
+(and no longer does anything). @xref{Privileges options}.
+
+If you get access denied errors for new users in version 4.0.2, you
+should check if you need some of the new grants that you didn't need
+before. In particular, you will need @code{REPLICATION SLAVE}
+(instead of @code{FILE}) for new slaves.
+@item
+The startup parameters @code{myisam_max_extra_sort_file_size} and
+@code{myisam_max_extra_sort_file_size} are now given in bytes
+(was megabytes before 4.0.3).
+External system locking of MyISAM/ISAM files is now turned of by default.
+One can turn this on by doing @code{--external-locking}. (For most users
+this is never needed).
+@item
+The following startup variables/options have been renamed:
+@multitable @columnfractions .50 .50
+@item @strong{From} @tab @strong{to}.
+@item @code{myisam_bulk_insert_tree_size} @tab @code{bulk_insert_buffer_size}
+@item @code{query_cache_startup_type} @tab @code{query_cache_type}
+@item @code{record_buffer} @tab @code{read_buffer_size}
+@item @code{record_rnd_buffer} @tab @code{read_rnd_buffer_size}
+@item @code{sort_buffer} @tab @code{sort_buffer_size}
+@item @code{warnings} @tab @code{log-warnings}
+@end multitable
+
+The startup options @code{record_buffer}, @code{sort_buffer} and
+@code{warnings} will still work in MySQL 4.0 but are deprecated.
+@item
+The following SQL variables have changed name.
+@multitable @columnfractions .50 .50
+@item @strong{From} @tab @strong{to}.
+@item @code{SQL_BIG_TABLES} @tab @code{BIG_TABLES}
+@item @code{SQL_LOW_PRIORITY_UPDATES} @tab @code{LOW_PRIORITY_UPDATES}
+@item @code{SQL_MAX_JOIN_SIZE} @tab @code{MAX_JOIN_SIZE}
+@item @code{SQL_QUERY_CACHE_TYPE} @tab @code{QUERY_CACHE_TYPE}
+@end multitable
+The old names still work in MySQL 4.0 but are depricated.
+@item
+You have to use @code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER=#} instead of
+@code{SET SQL_SLAVE_SKIP_COUNTER=#}.
+@item
+Renamed mysqld startup options @code{--skip-locking} to
+@code{--skip-external-locking} and @code{--enable-locking} to
+@code{--external-locking}.
+@item
+@code{DOUBLE} and @code{FLOAT} columns now honour the
+@code{UNSIGNED} flag on storage (before, @code{UNSIGNED} was ignored for
+these columns).
+@item
+@code{ORDER BY column DESC} now always sorts @code{NULL} values
+first; in 3.23 this was not always consistent.
+@item
+@code{SHOW INDEX} has 2 columns more (@code{Null} and @code{Index_type})
+than it had in 3.23.
+@item
+@code{SIGNED} is a reserved word.
+@item
+The result of all bitwise operators @code{|}, @code{&}, @code{<<},
+@code{>>}, and @code{~} is now unsigned. This may cause problems if you
+are using them in a context where you want a signed result.
+@xref{Cast Functions}.
+@item
+@strong{Note}: when you use subtraction between integer values where
+one is of type @code{UNSIGNED}, the result will be unsigned! In other
+words, before upgrading to MySQL 4.0, you should check your application
+for cases where you are subtracting a value from an unsigned entity and
+want a negative answer or subtracting an unsigned value from an
+integer column. You can disable this behaviour by using the
+@code{--sql-mode=NO_UNSIGNED_SUBTRACTION} option when starting
+@code{mysqld}. @xref{Cast Functions}.
+@item
+To use @code{MATCH ... AGAINST (... IN BOOLEAN MODE)} with your tables,
+you need to rebuild them with @code{ALTER TABLE table_name TYPE=MyISAM},
+@strong{even} if they are of @code{MyISAM} type.
+@item
+@code{LOCATE()} and @code{INSTR()} are case-sensitive if one of the
+arguments is a binary string. Otherwise they are case-insensitive.
+@item
+@code{STRCMP()} now uses the current character set when doing comparisons,
+which means that the default comparison behaviour now is case-insensitive.
+@item
+@code{HEX(string)} now returns the characters in string converted to
+hexadecimal. If you want to convert a number to hexadecimal, you should
+ensure that you call @code{HEX()} with a numeric argument.
+@item
+In 3.23, @code{INSERT INTO ... SELECT} always had @code{IGNORE} enabled.
+In 4.0.1, MySQL will stop (and possibly roll back) in case of an error if you
+don't specify @code{IGNORE}.
+@item
+@file{safe_mysqld} is renamed to @file{mysqld_safe}.
+@item
+The old C API functions @code{mysql_drop_db}, @code{mysql_create_db}, and
+@code{mysql_connect} are not supported anymore, unless you compile
+MySQL with @code{CFLAGS=-DUSE_OLD_FUNCTIONS}. Instead of doing this,
+it is preferable to change the client to use the new 4.0 API.
+@item
+In the @code{MYSQL_FIELD} structure, @code{length} and @code{max_length} have
+changed from @code{unsigned int} to @code{unsigned long}. This should not
+cause any problems, except that they may generate warning messages when
+used as arguments in the @code{printf()} class of functions.
+@item
+You should use @code{TRUNCATE TABLE} when you want to delete all rows
+from a table and you don't care how many rows were deleted.
+(Because @code{TRUNCATE TABLE} is faster than @code{DELETE FROM table_name}).
+@item
+You will get an error if you have an active @code{LOCK TABLES} or
+transaction when trying to execute @code{TRUNCATE TABLE} or @code{DROP
+DATABASE}.
+@item
+You should use integers to store values in BIGINT columns (instead of using
+strings, as you did in MySQL 3.23). Using strings will still work, but using
+integers is more efficient.
+@item
+Format of @code{SHOW OPEN TABLE} has changed.
+@item
+Multi-threaded clients should use @code{mysql_thread_init()} and
+@code{mysql_thread_end()}. @xref{Threaded clients}.
+@item
+If you want to recompile the Perl DBD::mysql module, you must get
+Msql-Mysql-modules version 1.2218 or newer because the older DBD modules
+used the deprecated @code{drop_db()} call.
+@item
+@code{RAND(seed)} returns a different random number series in 4.0 than in
+3.23; this was done to further differentiate @code{RAND(seed)} and @code{RAND(seed+1)}.
+@end itemize
-@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrade, Upgrade
+@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade
@subsection Upgrading From Version 3.22 to Version 3.23
@cindex compatibility, between MySQL versions
@@ -9334,32 +8265,36 @@ or the Perl script @code{mysql_convert_table_format}.
Version 3.22 and 3.21 clients will work without any problems with a Version
3.23 server.
-The following lists tell what you have to watch out for when upgrading to
+The following list tells what you have to watch out for when upgrading to
Version 3.23:
@itemize @bullet
@item
-All tables that uses the @code{tis620} character set must be fixed
+All tables that use the @code{tis620} character set must be fixed
with @code{myisamchk -r} or @code{REPAIR TABLE}.
@item
If you do a @code{DROP DATABASE} on a symbolic linked database, both the
-link and the original database is deleted. (This didn't happen in 3.22
-because configure didn't detect the @code{readlink} system call).
+link and the original database are deleted. (This didn't happen in 3.22
+because configure didn't detect the @code{readlink} system call.)
@item
-@code{OPTIMIZE TABLE} now only works for @strong{MyISAM} tables.
-For other table types, you can use @code{ALTER TABLE} to optimize the table.
+@code{OPTIMIZE TABLE} now only works for @code{MyISAM} tables.
+For other table types, you can use @code{ALTER TABLE} to optimise the table.
During @code{OPTIMIZE TABLE} the table is now locked from other threads.
@item
The MySQL client @code{mysql} is now by default started with the
option @code{--no-named-commands (-g)}. This option can be disabled with
@code{--enable-named-commands (-G)}. This may cause incompatibility problems in
-some cases, for example in SQL scripts that use named commands without a
+some cases@-for example, in SQL scripts that use named commands without a
semicolon! Long format commands still work from the first line.
@item
+Date functions that work on parts of dates (like @code{MONTH()}) will now
+return 0 for @code{0000-00-00} dates. (MySQL 3.22 returned @code{NULL}.)
+
+@item
If you are using the @code{german} character sort order, you must repair
all your tables with @code{isamchk -r}, as we have made some changes in
the sort order!
@@ -9368,52 +8303,52 @@ the sort order!
The default return type of @code{IF} will now depend on both arguments
and not only the first argument.
-@item
+@item
@code{AUTO_INCREMENT} will not work with negative numbers. The reason
for this is that negative numbers caused problems when wrapping from -1 to 0.
-@code{AUTO_INCREMENT} is now for MyISAM tables handled at a lower level and
+@code{AUTO_INCREMENT} for MyISAM tables is no handled at a lower level and
is much faster than before. For MyISAM tables old numbers are also not reused
anymore, even if you delete some rows from the table.
-@item
-@code{CASE}, @code{DELAYED}, @code{ELSE}, @code{END}, @code{FULLTEXT},
-@code{INNER}, @code{RIGHT}, @code{THEN} and @code{WHEN} are now reserved words.
+@item
+@code{CASE}, @code{DELAYED}, @code{ELSE}, @code{END}, @code{FULLTEXT},
+@code{INNER}, @code{RIGHT}, @code{THEN}, and @code{WHEN} are now reserved words.
-@item
-@code{FLOAT(X)} is now a true floating-point type and not a value with a
+@item
+@code{FLOAT(X)} is now a true floating-point type and not a value with a
fixed number of decimals.
-@item
-When declaring @code{DECIMAL(length,dec)} the length argument no longer
+@item
+When declaring @code{DECIMAL(length,dec)} the length argument no longer
includes a place for the sign or the decimal point.
-@item
+@item
A @code{TIME} string must now be of one of the following formats:
@code{[[[DAYS] [H]H:]MM:]SS[.fraction]} or
-@code{[[[[[H]H]H]H]MM]SS[.fraction]}
+@code{[[[[[H]H]H]H]MM]SS[.fraction]}.
-@item
-@code{LIKE} now compares strings using the same character comparison rules
-as @code{'='}. If you require the old behavior, you can compile
+@item
+@code{LIKE} now compares strings using the same character comparison rules
+as @code{=}. If you require the old behaviour, you can compile
MySQL with the @code{CXXFLAGS=-DLIKE_CMP_TOUPPER} flag.
-@item
-@code{REGEXP} is now case insensitive for normal (not binary) strings.
+@item
+@code{REGEXP} is now case-insensitive for normal (not binary) strings.
-@item
+@item
When you check/repair tables you should use @code{CHECK TABLE}
-or @code{myisamchk} for @code{MyISAM} tables (@code{.MYI}) and
-@code{isamchk} for ISAM (@code{.ISM}) tables.
+or @code{myisamchk} for @code{MyISAM} tables (@file{.MYI}) and
+@code{isamchk} for ISAM (@file{.ISM}) tables.
-@item
+@item
If you want your @code{mysqldump} files to be compatible between
MySQL Version 3.22 and Version 3.23, you should not use the
@code{--opt} or @code{--full} option to @code{mysqldump}.
-@item
+@item
Check all your calls to @code{DATE_FORMAT()} to make sure there is a
-@samp{%} before each format character. (Later MySQL Version 3.22
-did allow this syntax.)
+@samp{%} before each format character.
+(MySQL Version 3.22 and later already allowed this syntax.)
@item
@code{mysql_fetch_fields_direct} is now a function (it was a macro) and
@@ -9422,8 +8357,8 @@ it returns a pointer to a @code{MYSQL_FIELD} instead of a
@item
@code{mysql_num_fields()} can no longer be used on a @code{MYSQL*} object (it's
-now a function that takes @code{MYSQL_RES*} as an argument. You should now
-use @code{mysql_field_count()} instead.
+now a function that takes @code{MYSQL_RES*} as an argument, so you should
+use @code{mysql_field_count()} instead).
@item
In MySQL Version 3.22, the output of @code{SELECT DISTINCT ...} was
@@ -9431,8 +8366,8 @@ almost always sorted. In Version 3.23, you must use @code{GROUP BY} or
@code{ORDER BY} to obtain sorted output.
@item
-@code{SUM()} now returns @code{NULL}, instead of 0, if there is no matching
-rows. This is according to ANSI SQL.
+@code{SUM()} now returns @code{NULL}, instead of 0, if
+there are no matching rows. This is according to ANSI SQL.
@item
An @code{AND} or @code{OR} with @code{NULL} values will now return
@@ -9449,7 +8384,7 @@ than the length argument.
@cindex compatibility, between MySQL versions
@cindex upgrading, 3.21 to 3.22
-Nothing that affects compatibility has changed between Version 3.21 and 3.22.
+Nothing that affects compatibility has changed between versions 3.21 and 3.22.
The only pitfall is that new tables that are created with @code{DATE} type
columns will use the new way to store the date. You can't access these new
fields from an old version of @code{mysqld}.
@@ -9490,13 +8425,13 @@ return any server error, only @code{CR_UNKNOWN_ERROR} (but it
works for client errors), and the server uses the old @code{password()}
checking rather than the new one.
-If you are @strong{NOT} using the @code{--old-protocol} option to
+If you are @strong{not} using the @code{--old-protocol} option to
@code{mysqld}, you will need to make the following changes:
@itemize @bullet
@item
All client code must be recompiled. If you are using ODBC, you must get
-the new @strong{MyODBC} 2.x driver.
+the new @code{MyODBC} 2.x driver.
@item
The script @code{scripts/add_long_password} must be run to convert the
@code{Password} field in the @code{mysql.user} table to @code{CHAR(16)}.
@@ -9529,7 +8464,7 @@ The new Perl @code{DBI}/@code{DBD} interface also supports the old
@code{mysqlperl} interface. The only change you have to make if you use
@code{mysqlperl} is to change the arguments to the @code{connect()} function.
The new arguments are: @code{host}, @code{database}, @code{user},
-@code{password} (the @code{user} and @code{password} arguments have changed
+and @code{password} (the @code{user} and @code{password} arguments have changed
places).
@xref{Perl DBI Class, , Perl @code{DBI} Class}.
@@ -9551,10 +8486,10 @@ There are some new reserved words. The most notable are @code{DATE},
@cindex upgrading, different architecture
-If you are using MySQL Version 3.23, you can copy the @code{.frm},
-@code{.MYI}, and @code{.MYD} files between different architectures that
+If you are using MySQL Version 3.23, you can copy the @file{.frm},
+@file{.MYI}, and @file{.MYD} files between different architectures that
support the same floating-point format. (MySQL takes care of any
-byte swapping issues.)
+byte-swapping issues.)
The MySQL @code{ISAM} data and index files (@file{.ISD} and
@file{*.ISM}, respectively) are architecture-dependent and in some cases
@@ -9612,7 +8547,7 @@ shell> gunzip < db_name.contents.gz | mysql db_name
You can also use @code{mysqldump} and @code{mysqlimport} to accomplish
the database transfer.
For big tables, this is much faster than simply using @code{mysqldump}.
-In the commands shown below, @code{DUMPDIR} represents the full pathname
+In the following commands, @code{DUMPDIR} represents the full pathname
of the directory you use to store the output from @code{mysqldump}.
First, create the directory for the output files and dump the database:
@@ -9632,7 +8567,7 @@ shell> cat DUMPDIR/*.sql | mysql db_name # create tables in database
shell> mysqlimport db_name DUMPDIR/*.txt # load data into tables
@end example
-Also, don't forget to copy the @code{mysql} database, because that's where the
+Also, don't forget to copy the @code{mysql} database because that's where the
grant tables (@code{user}, @code{db}, @code{host}) are stored. You may have
to run commands as the MySQL @code{root} user on the new machine
until you have the @code{mysql} database in place.
@@ -9642,7 +8577,7 @@ After you import the @code{mysql} database on the new machine, execute
information.
-@node Operating System Specific Notes, , Upgrade, Installing
+@node Operating System Specific Notes, Perl support, Upgrade, Installing
@section Operating System Specific Notes
@menu
@@ -9654,7 +8589,7 @@ information.
* Other Unix Notes:: Other Unix Notes
* OS/2:: OS/2 Notes
* BeOS:: BeOS Notes
-* Novell Netware:: Novell Netware Notes
+* Novell Netware:: Novell NetWare Notes
@end menu
@@ -9671,33 +8606,33 @@ information.
* Linux-IA64:: Linux IA64 Notes
@end menu
-The notes below regarding @strong{glibc} apply only to the situation
+The following notes regarding @code{glibc} apply only to the situation
when you build MySQL
yourself. If you are running Linux on an x86 machine, in most cases it is
much better for you to just use our binary. We link our binaries against
-the best patched version of @strong{glibc} we can come up with and with the
+the best patched version of @code{glibc} we can come up with and with the
best compiler options, in an attempt to make it suitable for a high-load
-server. So if you read the text below, and are in doubt about
+server. So if you read the following text, and are in doubt about
what you should do, try our binary first to see if it meets your needs, and
worry about your own build only after you have discovered that our binary is
not good enough. In that case, we would appreciate a note about it, so we
can build a better binary next time. For a typical user, even for setups with
-a lot of concurrent connections and/or tables exceeding 2GB limit, our
-binary in most cases is the best choice.
+a lot of concurrent connections and/or tables exceeding the 2G limit, our
+binary in most cases is the best choice.
MySQL uses LinuxThreads on Linux. If you are using an old
Linux version that doesn't have @code{glibc2}, you must install
-LinuxThreads before trying to compile MySQL. You can get
-LinuxThreads at @uref{http://www.mysql.com/Downloads/Linux}.
+LinuxThreads before trying to compile MySQL. You can get
+LinuxThreads at @uref{http://www.mysql.com/Downloads/Linux/}.
-@strong{NOTE:} We have seen some strange problems with Linux 2.2.14 and
-MySQL on SMP systems; If you have a SMP system, we recommend
-you to upgrade to Linux 2.4 ASAP! Your system will be faster and more
-stable by doing this!
+@strong{Note}: we have seen some strange problems with Linux 2.2.14 and
+MySQL on SMP systems. If you have a SMP system, we recommend
+you upgrade to Linux 2.4 as soon as possible! Your system will be
+faster and more stable by doing this!
Note that @code{glibc} versions before and including Version 2.1.1 have
a fatal bug in @code{pthread_mutex_timedwait} handling, which is used
-when you do @code{INSERT DELAYED}. We recommend you to not use
+when you do @code{INSERT DELAYED}. We recommend that you not use
@code{INSERT DELAYED} before upgrading glibc.
If you plan to have 1000+ concurrent connections, you will need to make
@@ -9705,24 +8640,24 @@ some changes to LinuxThreads, recompile it, and relink MySQL against
the new @file{libpthread.a}. Increase @code{PTHREAD_THREADS_MAX} in
@file{sysdeps/unix/sysv/linux/bits/local_lim.h} to 4096 and decrease
@code{STACK_SIZE} in @file{linuxthreads/internals.h} to 256 KB. The paths are
-relative to the root of @code{glibc} Note that MySQL will not be
-stable with around 600-1000 connections if @code{STACK_SIZE} is the default
+relative to the root of @code{glibc} Note that MySQL will not be
+stable with around 600-1000 connections if @code{STACK_SIZE} is the default
of 2 MB.
-If you have a problem with that MySQL can't open enough files,
+If MySQL can't open enough files,
or connections, it may be that you haven't configured Linux to handle
enough files.
-In Linux 2.2 and forwards, you can check the number of allocated
+In Linux 2.2 and onward, you can check the number of allocated
file handlers by doing:
@example
cat /proc/sys/fs/file-max
-cat /proc/sys/fs/dquot-max
+cat /proc/sys/fs/dquot-max
cat /proc/sys/fs/super-max
@end example
-If you have more than 16M of memory, you should add something like the
+If you have more than 16 MB of memory, you should add something like the
following in your boot script (@file{/etc/rc/boot.local} on SuSE):
@example
@@ -9731,8 +8666,8 @@ echo 8192 > /proc/sys/fs/dquot-max
echo 1024 > /proc/sys/fs/super-max
@end example
-You can also run the above from the command line as root, but in this case
-your old limits will be used next time your computer reboots.
+You can also run the preceding commands from the command-line as root, but in this case
+your old limits will be used the next time your computer reboots.
You should also add /etc/my.cnf:
@@ -9741,46 +8676,46 @@ You should also add /etc/my.cnf:
open-files-limit=8192
@end example
-The above should allow MySQL to create up to 8192 connections + files.
+This should allow MySQL to create up to 8192 connections + files.
The @code{STACK_SIZE} constant in LinuxThreads controls the spacing of thread
stacks in the address space. It needs to be large enough so that there will
be plenty of room for the stack of each individual thread, but small enough
-to keep the stack of some thread from running into the global @code{mysqld}
+to keep the stack of some threads from running into the global @code{mysqld}
data. Unfortunately, the Linux implementation of @code{mmap()}, as we have
experimentally discovered, will successfully unmap an already mapped region
if you ask it to map out an address already in use, zeroing out the data
on the entire page, instead of returning an error. So, the safety of
-@code{mysqld} or any other threaded application depends on the "gentleman"
-behavior of the code that creates threads. The user must take measures to
-make sure the number of running threads at any time is sufficiently low for
-thread stacks to stay away from the global heap. With @code{mysqld}, you
-should enforce this "gentleman" behavior by setting a reasonable value for
+@code{mysqld} or any other threaded application depends on the "gentleman"
+behaviour of the code that creates threads. The user must take measures to
+make sure the number of running threads at any time is sufficiently low for
+thread stacks to stay away from the global heap. With @code{mysqld}, you
+should enforce this "gentleman" behaviour by setting a reasonable value for
the @code{max_connections} variable.
If you build MySQL yourself and do not want to mess with patching
-LinuxThreads, you should set @code{max_connections} to a value no higher
-than 500. It should be even less if you have a large key buffer, large
-heap tables, or some other things that make @code{mysqld} allocate a lot
-of memory or if you are running a 2.2 kernel with a 2GB patch. If you are
+LinuxThreads, you should set @code{max_connections} to a value no higher
+than 500. It should be even less if you have a large key buffer, large
+heap tables, or some other things that make @code{mysqld} allocate a lot
+of memory, or if you are running a 2.2 kernel with a 2G patch. If you are
using our binary or RPM version 3.23.25 or later, you can safely set
-@code{max_connections} at 1500, assuming no large key buffer or heap tables
-with lots of data. The more you reduce @code{STACK_SIZE} in LinuxThreads
-the more threads you can safely create. We recommend the values between
+@code{max_connections} at 1500, assuming no large key buffer or heap tables
+with lots of data. The more you reduce @code{STACK_SIZE} in LinuxThreads
+the more threads you can safely create. We recommend the values between
128K and 256K.
-If you use a lot of concurrent connections, you may suffer from a "feature"
-in the 2.2 kernel that penalizes a process for forking or cloning a child
+If you use a lot of concurrent connections, you may suffer from a "feature"
+in the 2.2 kernel that penalises a process for forking or cloning a child
in an attempt to prevent a fork bomb attack. This will cause MySQL
not to scale well as you increase the number of concurrent clients. On
-single CPU systems, we have seen this manifested in a very slow thread
+single-CPU systems, we have seen this manifested in a very slow thread
creation, which means it may take a long time to connect to MySQL
(as long as 1 minute), and it may take just as long to shut it down. On
-multiple CPU systems, we have observed a gradual drop in query speed as
+multiple-CPU systems, we have observed a gradual drop in query speed as
the number of clients increases. In the process of trying to find a
solution, we have received a kernel patch from one of our users, who
-claimed it made a lot of difference for his site. The patch is available here
-(@uref{http://www.mysql.com/Downloads/Patches/linux-fork.patch}). We have
+claimed it made a lot of difference for his site. The patch is available at
+@uref{http://www.mysql.com/Downloads/Patches/linux-fork.patch}. We have
now done rather extensive testing of this patch on both development and
production systems. It has significantly
improved @code{MySQL} performance without causing any problems and we now
@@ -9791,12 +8726,12 @@ the current performance of your system, rather than patching your 2.2 kernel,
it might be easier to just upgrade to 2.4, which will also give you a nice
SMP boost in addition to fixing this fairness bug.
-We have tested MySQL on the 2.4 kernel on a 2 CPU machine and
-found MySQL scales MUCH better - there was virtually no slowdown
-on query throughput all the way up
-to 1000 clients, and MySQL scaling factor ( computed as the ratio of
+We have tested MySQL on the 2.4 kernel on a 2-CPU machine and
+found MySQL scales @strong{much} better@-there was virtually no slowdown
+on queries throughput all the way up
+to 1000 clients, and the MySQL scaling factor (computed as the ratio of
maximum throughput to the throughput with one client) was 180%.
-We have observed similar results on a 4-CPU system - virtually no
+We have observed similar results on a 4-CPU system@-virtually no
slowdown as the number of
clients was increased up to 1000, and 300% scaling factor. So for a high-load
SMP server we would definitely recommend the 2.4 kernel at this point. We
@@ -9815,23 +8750,25 @@ include them in the manual.
There is another issue that greatly hurts MySQL performance,
especially on SMP systems. The implementation of mutex in
-LinuxThreads in @strong{glibc-2.1} is very bad for programs with many
+LinuxThreads in @code{glibc-2.1} is very bad for programs with many
threads that only
hold the mutex for a short time. On an SMP system, ironic as it is, if
-you link MySQL against unmodified @strong{LinuxThreads},
+you link MySQL against unmodified @code{LinuxThreads},
removing processors from the machine improves MySQL performance
-in many cases. We have made a patch available for @strong{glibc 2.1.3},
-@uref{http://www.mysql.com/Downloads/Linux/linuxthreads-2.1-patch,linuxthreads-2.1-patch}
-to correct this behavior.
+in many cases. We have made a patch available for @code{glibc 2.1.3}
+to correct this behaviour
+(@uref{http://www.mysql.com/Downloads/Linux/linuxthreads-2.1-patch}).
-With @strong{glibc-2.2.2}
+With @code{glibc-2.2.2}
MySQL version 3.23.36 will use the adaptive mutex, which is much
-better than even the patched one in @strong{glibc-2.1.3}. Be warned, however,
-that under some conditions, the current mutex code in @strong{glibc-2.2.2}
+better than even the patched one in @code{glibc-2.1.3}. Be warned, however,
+that under some conditions, the current mutex code in @code{glibc-2.2.2}
overspins, which hurts MySQL performance. The chance of this
condition can be reduced by renicing @code{mysqld} process to the highest
-priority. We have also been able to correct the overspin behavior with
-a patch, available @uref{http://www.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch,here}. It combines the correction of overspin, maximum number of
+priority. We have also been able to correct the overspin behaviour with
+a patch, available at
+@uref{http://www.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch}.
+It combines the correction of overspin, maximum number of
threads, and stack spacing all in one. You will need to apply it in the
@code{linuxthreads} directory with
@code{patch -p0 </tmp/linuxthreads-2.2.2.patch}.
@@ -9877,16 +8814,18 @@ If you see a dead @code{mysqld} daemon process with @code{ps}, this usually
means that you have found a bug in MySQL or you have a corrupted
table. @xref{Crashing}.
-To get a core dump on Linux if @code{mysqld} dies with a SIGSEGV
-signal, you can start @code{mysqld} with the @code{--core-file} option. Note
+To get a core dump on Linux if @code{mysqld} dies with a @code{SIGSEGV} signal,
+you can start @code{mysqld} with the @code{--core-file} option. Note
that you also probably need to raise the @code{core file size} by adding
-@code{ulimit -c 1000000} to @code{safe_mysqld} or starting @code{safe_mysqld}
-with @code{--core-file-sizes=1000000}. @xref{safe_mysqld, , @code{safe_mysqld}}.
+@code{ulimit -c 1000000} to @code{safe_mysqld} or starting
+@code{safe_mysqld} with @code{--core-file-sizes=1000000}.
+@xref{safe_mysqld, , @code{safe_mysqld}}.
If you are linking your own MySQL client and get the error:
@example
-ld.so.1: ./my: fatal: libmysqlclient.so.4: open failed: No such file or directory
+ld.so.1: ./my: fatal: libmysqlclient.so.4:
+open failed: No such file or directory
@end example
When executing them, the problem can be avoided by one of the following
@@ -9914,7 +8853,13 @@ some problems compiling MySQL because the Linux header files are very
The following @code{configure} line should work with @code{fcc/FCC}:
@example
-CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=const -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO '-D_EXTERN_INLINE=static __inline'" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-low-memory
+CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE \
+-DCONST=const -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib \
+-K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=const \
+-Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO \
+'-D_EXTERN_INLINE=static __inline'" ./configure --prefix=/usr/local/mysql \
+--enable-assembler --with-mysqld-ldflags=-all-static --disable-shared \
+--with-low-memory
@end example
@@ -9926,6 +8871,13 @@ CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=const -
MySQL needs at least Linux Version 2.0.
+@strong{Warning}:
+We have reports from some MySQL users that they have got serious
+stability problems with MySQL with Linux kernel 2.2.14. If you are
+using this kernel you should upgrade to 2.2.19 (or newer) or to a 2.4
+kernel. If you have a multi-cpu box, then you should seriously consider
+using 2.4 as this will give you a significant speed boost.
+
The binary release is linked with @code{-static}, which means you do not
normally need to worry about which version of the system libraries you
have. You need not install LinuxThreads, either. A program linked with
@@ -9962,7 +8914,7 @@ You can solve this problem in one of the following ways:
Get a MySQL source distribution (an RPM or the @code{tar.gz}
distribution) and install this instead.
@item
-Execute @code{mysql_install_db --force}; This will not execute the
+Execute @code{mysql_install_db --force}; this will not execute the
@code{resolveip} test in @code{mysql_install_db}. The downside is that
you can't use host names in the grant tables; you must use IP numbers
instead (except for @code{localhost}). If you are using an old MySQL
@@ -10004,9 +8956,14 @@ kernel will fix this problem in the future.
MySQL requires @code{libc} Version 5.4.12 or newer. It's known to
work with @code{libc} 5.4.46. @code{glibc} Version 2.0.6 and later should
also work. There have been some problems with the @code{glibc} RPMs from
-RedHat, so if you have problems, check whether or not there are any updates!
+RedHat, so if you have problems, check whether there are any updates!
The @code{glibc} 2.0.7-19 and 2.0.7-29 RPMs are known to work.
+If you are using gcc 3.0 and above to compile MySQL, you must install
+the @code{libstdc++v3} library before compiling MySQL; if you don't do
+this you will get an error about a missing @code{__cxa_pure_virtual}
+symbol during linking!
+
On some older Linux distributions, @code{configure} may produce an error
like this:
@@ -10018,14 +8975,16 @@ See the Installation chapter in the Reference Manual.
Just do what the error message says and add an extra underscore to the
@code{_P} macro that has only one underscore, then try again.
-You may get some warnings when compiling; those shown below can be ignored:
+You may get some warnings when compiling; those shown here can be ignored:
@example
mysqld.cc -o objs-thread/mysqld.o
mysqld.cc: In function `void init_signals()':
-mysqld.cc:315: warning: assignment of negative value `-1' to `long unsigned int'
+mysqld.cc:315: warning: assignment of negative value `-1' to
+`long unsigned int'
mysqld.cc: In function `void * signal_hand(void *)':
-mysqld.cc:346: warning: assignment of negative value `-1' to `long unsigned int'
+mysqld.cc:346: warning: assignment of negative value `-1' to
+`long unsigned int'
@end example
In Debian GNU/Linux, if you want MySQL to start automatically when
@@ -10059,13 +9018,12 @@ You can avoid using @file{libg++.a} by running @code{configure} like this:
shell> CXX=gcc ./configure
@end example
-
@node Linux-SPARC, Linux-Alpha, Linux-x86, Linux
@subsubsection Linux SPARC Notes
In some implementations, @code{readdir_r()} is broken. The symptom is that
-@code{SHOW DATABASES} always returns an empty set. This can be fixed by
-removing @code{HAVE_READDIR_R} from @file{config.h} after configuring and
+@code{SHOW DATABASES} always returns an empty set. This can be fixed by
+removing @code{HAVE_READDIR_R} from @file{config.h} after configuring and
before compiling.
Some problems will require patching your Linux installation. The patch can
@@ -10073,7 +9031,7 @@ be found at
@uref{http://www.mysql.com/Downloads/patches/Linux-sparc-2.0.30.diff}.
This patch is against the Linux distribution @file{sparclinux-2.0.30.tar.gz}
that is available at @code{vger.rutgers.edu} (a version of Linux that was
-never merged with the official 2.0.30). You must also install LinuxThreads
+never merged with the official 2.0.30). You must also install LinuxThreads
Version 0.6 or newer.
@@ -10081,7 +9039,7 @@ Version 0.6 or newer.
@subsubsection Linux Alpha Notes
MySQL Version 3.23.12 is the first MySQL version that is
-tested on Linux-Alpha. If you plan to use MySQL on Linux-Alpha,
+tested on Linux-Alpha. If you plan to use MySQL on Linux-Alpha,
you should ensure that you have this version or newer.
We have tested MySQL on Alpha with our benchmarks and test suite,
@@ -10092,22 +9050,28 @@ When we compiled the standard MySQL binary we are using SuSE 6.4,
kernel 2.2.13-SMP, Compaq C compiler (V6.2-504) and Compaq C++ compiler
(V6.3-005) on a Comaq DS20 machine with an Alpha EV6 processor.
-You can find the above compilers at
-@uref{http://www.support.compaq.com/alpha-tools}). By using these compilers,
-instead of gcc, we get about 9-14 % better performance with MySQL.
+You can find the above compilers at
+@uref{http://www.support.compaq.com/alpha-tools/}). By using these compilers,
+instead of gcc, we get about 9-14% better performance with MySQL.
-Note that the configure line optimized the binary for the current CPU; This
+Note that the configure line optimised the binary for the current CPU; this
means you can only use our binary if you have an Alpha EV6 processor. We also
compile statically to avoid library problems.
@example
-CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
+CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" \
+./configure --prefix=/usr/local/mysql --disable-shared \
+--with-extra-charsets=complex --enable-thread-safe-client \
+--with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
@end example
If you want to use egcs the following configure line worked for us:
@example
-CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --disable-shared
+CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc \
+CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
+-fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql \
+--disable-shared
@end example
Some known problems when running MySQL on Linux-Alpha:
@@ -10115,11 +9079,11 @@ Some known problems when running MySQL on Linux-Alpha:
@itemize @bullet
@item
Debugging threaded applications like MySQL will not work with
-@code{gdb 4.18}. You should download and use gdb 5.0 instead!
+@code{gdb 4.18}. You should download and use gdb 5.1 instead!
@item
If you try linking @code{mysqld} statically when using @code{gcc}, the
-resulting image will core dump at start. In other words, @strong{DON'T}
+resulting image will core dump at start. In other words, @strong{don't}
use @code{--with-mysqld-ldflags=-all-static} with @code{gcc}.
@end itemize
@@ -10143,14 +9107,17 @@ work). You must also use the @code{egcs} C++ compiler
@node Linux-IA64, , Linux-MIPS, Linux
@subsubsection Linux IA64 Notes
-To get MySQL to compile on Linux Ia64, we use the following compile line:
+To get MySQL to compile on Linux IA64, we use the following compile line:
Using @code{gcc-2.96}:
@example
-CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex
+CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc \
+CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
+-fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql \
+"--with-comment=Official MySQL binary" --with-extra-charsets=complex
@end example
-On Ia64 the MySQL client binaries are using shared libraries. This means
+On IA64 the MySQL client binaries are using shared libraries. This means
that if you install our binary distribution in some other place than
@file{/usr/local/mysql} you need to either modify @file{/etc/ld.so.conf}
or add the path to the directory where you have @file{libmysqlclient.so}
@@ -10161,36 +9128,38 @@ to the @code{LD_LIBRARY_PATH} environment variable.
@node Windows, Solaris, Linux, Operating System Specific Notes
@subsection Windows Notes
-This section describes installation and use of MySQL on Windows.
-This information is also provided in the @file{README} file that comes
-with the MySQL Windows distribution.
+This section describes using MySQL on Windows. This information
+is also provided in the @file{README} file that comes with the
+MySQL Windows distribution. @xref{Windows installation}.
@menu
-* Win95 start:: Starting MySQL on Win95 / Win98
-* NT start:: Starting MySQL on NT / Win2000
+* Win95 start:: Starting MySQL on Windows 9x / Me
+* NT start:: Starting MySQL on Windows NT / 2000 / XP
* Windows running:: Running MySQL on Windows
* Windows and SSH:: Connecting to a remote MySQL from Windows with SSH
* Windows symbolic links:: Splitting data across different disks under Win32
-* Windows compiling:: Compiling MySQL clients on Windows.
+* Windows client compiling:: Compiling MySQL clients on Windows.
* Windows vs Unix:: MySQL-Windows compared to Unix MySQL
@end menu
@node Win95 start, NT start, Windows, Windows
-@subsubsection Starting MySQL on Windows 95 or Windows 98
+@subsubsection Starting MySQL on Windows 95, 98 or Me
MySQL uses TCP/IP to connect a client to a server. (This will
allow any machine on your network to connect to your MySQL
-server.) Because of this, you must install TCP/IP on your machine before
-starting MySQL. You can find TCP/IP on your Windows CD-ROM.
+server.) Because of this, you must install TCP/IP on your
+machine before starting MySQL. You can find TCP/IP on your
+Windows CD-ROM.
-Note that if you are using an old Win95 release (for example OSR2), it's
-likely that you have an old Winsock package! MySQL requires
-Winsock 2! You can get the newest Winsock from
-@uref{http://www.microsoft.com/}. Win98 has the new Winsock 2 library, so
-the above doesn't apply for Win98.
+Note that if you are using an old Windows 95 release (for example
+OSR2), it's likely that you have an old Winsock package;
+MySQL requires Winsock 2! You can get the newest Winsock from
+@uref{http://www.microsoft.com/}. Windows 98 has the new Winsock 2
+library, so the above doesn't apply there.
-To start the @code{mysqld} server, you should start an MS-DOS window and type:
+To start the @code{mysqld} server, you should start an MS-DOS
+window and type:
@example
C:\> C:\mysql\bin\mysqld
@@ -10204,104 +9173,130 @@ You can kill the MySQL server by executing:
C:\> C:\mysql\bin\mysqladmin -u root shutdown
@end example
-Note that Win95 and Win98 don't support creation of named pipes.
-On Win95 and Win98, you can only use named pipes to connect to a
-remote MySQL server running on a Windows NT server host.
-(The MySQL server must also support named pipes, of
-course. For example, using @code{mysqld-opt} under NT will not allow
-named pipe connections. You should use either @code{mysqld-nt} or
-@code{mysqld-max-nt}.)
+This calls the MySQL administation utility as user `root', which
+is the default Administrator in the MySQL grant system. Please
+note that the MySQL grant system is wholly independent from any
+login users under Windows.
+
+Note that Windows 95/98/Me don't support creation of named pipes.
+So on those platforms, you can only use named pipes to connect to a
+remote MySQL server running on a Windows NT/2000/XP server host.
+(The MySQL server must also support named pipes, of course.
+For example, using @code{mysqld-opt} under NT/2000/XP will not
+allow named pipe connections. You should use either
+@code{mysqld-nt} or @code{mysqld-max-nt}.)
If @code{mysqld} doesn't start, please check the
-@file{\mysql\data\mysql.err} file to see if the server wrote any message
-there to indicate the cause of the problem. You can also try to start
-the server with @code{mysqld --standalone}; In this case, you may get
-some useful information on the screen that may help solve the problem.
+@file{\mysql\data\mysql.err} file to see if the server wrote any
+message there to indicate the cause of the problem. You can also
+try to start the server with @code{mysqld --standalone}; in this
+case, you may get some useful information on the screen that may
+help solve the problem.
-The last option is to start @code{mysqld} with @code{--standalone
---debug}. In this case @code{mysqld} will write a log file
-@file{C:\mysqld.trace} that should contain the reason why @code{mysqld}
-doesn't start. @xref{Making trace files}.
+The last option is to start @code{mysqld} with
+@code{--standalone --debug}.
+In this case @code{mysqld} will write a log file
+@file{C:\mysqld.trace} that should contain the reason why
+@code{mysqld} doesn't start. @xref{Making trace files}.
+Use @code{mysqld --help} to display all the options that
+@code{mysqld} understands!
-@node NT start, Windows running, Win95 start, Windows
-@subsubsection Starting MySQL on Windows NT or Windows 2000
-The Win95/Win98 section also applies to MySQL on NT/Win2000, with
-the following differences:
+@node NT start, Windows running, Win95 start, Windows
+@subsubsection Starting MySQL on Windows NT, 2000 or XP
-To get MySQL to work with TCP/IP on NT, you must install
+To get MySQL to work with TCP/IP on Windows NT 4, you must install
service pack 3 (or newer)!
-Note that everything in the following that applies for NT also applies
-for Win2000!
-
-For NT/Win2000, the server name is @code{mysqld-nt}. Normally you
-should install MySQL as a service on NT/Win2000:
+Normally you should install MySQL as a service on Windows NT/2000/XP.
+In case the server was already running, first stop it using
+the following command:
@example
-C:\> C:\mysql\bin\mysqld-nt --install
+C:\mysql\bin> mysqladmin -u root shutdown
@end example
-or
+This calls the MySQL administation utility as user `@code{root}',
+which is the default @code{Administrator} in the MySQL grant system.
+Please note that the MySQL grant system is wholly independent from
+any login users under Windows.
+
+Now install the server service:
@example
-C:\> C:\mysql\bin\mysqld-max-nt --install
+C:\mysql\bin> mysqld-max-nt --install
@end example
-(Under Windows NT, you can actually install any of the server binaries
-as a service, but only those having names that end with @code{-nt.exe}
-provide support for named pipes.)
+If any options are required, they must be specified as
+``@code{Start parameters}'' in the Windows @code{Services}
+utility before you start the MySQL service.
+
+The @code{Services} utility
+(@code{Windows Service Control Manager}) can be found in the
+@code{Windows Control Panel} (under @code{Administrative Tools}
+on Windows 2000). It is advisable to close the Services utility
+while performing the @code{--install} or @code{--remove}
+operations, this prevents some odd errors.
-You can start and stop the MySQL service with these commands:
+For information about which server binary to run, see
+@ref{Windows prepare environment}.
+
+Please note that from MySQL version 3.23.44, you have the choice
+of set up the service as @code{Manual} instead (if you don't wish
+the service to be started automatically during the boot process):
@example
-C:\> NET START mysql
-C:\> NET STOP mysql
+C:\mysql\bin> mysqld-max-nt --install-manual
@end example
-Note that in this case you can't use any other options for @code{mysqld-nt}!
+The service is installed with the name @code{MySQL}. Once
+installed, it can be immediately started from the @code{Services}
+utility, or by using the command @code{NET START MySQL}.
-You can also run @code{mysqld-nt} as a stand-alone program on NT if you need
-to start @code{mysqld-nt} with any options! If you start @code{mysqld-nt}
-without options on NT, @code{mysqld-nt} tries to start itself as a service
-with the default service options. If you have stopped @code{mysqld-nt}, you
-have to start it with @code{NET START mysql}.
+Once running, @code{mysqld-max-nt} can be stopped using
+@code{mysqladmin}, from the Services utility or by using the
+command @code{NET STOP MySQL}.
-The service is installed with the name @code{MySQL}. Once installed, it must
-be started using the Services Control Manager (SCM) Utility found in the
-Control Panel, or by using the @code{NET START MySQL} command. If any options
-are desired, they must be specified as ``Startup parameters'' in the SCM utility
-before you start the MySQL service. Once running, @code{mysqld-nt}
-can be stopped using @code{mysqladmin}, or from the SCM utility or by using
-the command @code{NET STOP MySQL}. If you use SCM to stop @code{mysqld-nt},
-there is a strange message from SCM about @code{mysqld shutdown normally}.
-When run as a service, @code{mysqld-nt} has no access to a console and so no
-messages can be seen.
+When running as a service, the operating system will automatically stop
+the MySQL service on computer shutdown. In MySQL versions < 3.23.47,
+Windows only waited for a few seconds for the shutdown to complete, and
+killed the database server process if the time limit was exceeded
+(potentially causing problems). For instance, at the next startup the
+@code{InnoDB} table handler had to do crash recovery. Starting from
+MySQL version 3.23.48, the Windows will wait longer for the MySQL server
+shutdown to complete. If you notice this is not enough for your
+intallation, it is safest to run the MySQL server not as a service, but
+from the Command prompt, and shut it down with @code{mysqladmin shutdown}.
-On NT you can get the following service error messages:
+There is a problem that Windows NT (but not Windows 2000/XP) by default only
+waits 20 seconds for a service to shut down, and after that kills the
+service process. You can increase this default by opening the Registry
+Editor @file{\winnt\system32\regedt32.exe} and editing the value of
+@code{WaitToKillServiceTimeout} at
+@file{HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control}
+in the Registry tree. Specify the new larger value in milliseconds,
+for example 120000 to have Windows NT wait upto 120 seconds.
-@multitable @columnfractions .3 .7
-@item Permission Denied @tab Means that it cannot find @code{mysqld-nt.exe}.
-@item Cannot Register @tab Means that the path is incorrect.
-@item Failed to install service. @tab Means that the service is already installed or that the Service Control Manager is in bad state.
-@end multitable
+Please note that when run as a service, @code{mysqld-max-nt}
+has no access to a console and so no messages can be seen.
+Errors can be checked in @file{c:\mysql\data\mysql.err}.
-If you have problems installing @code{mysqld-nt} as a service, try starting
-it with the full path:
+If you have problems installing @code{mysqld-max-nt} as a
+service, try starting it with the full path:
@example
-C:\> C:\mysql\bin\mysqld-nt --install
+C:\> C:\mysql\bin\mysqld-max-nt --install
@end example
-If this doesn't work, you can get @code{mysqld-nt} to start properly by fixing
-the path in the registry!
+If this doesn't work, you can get @code{mysqld-max-nt} to
+start properly by fixing the path in the registry!
-If you don't want to start @code{mysqld-nt} as a service, you can start it as
-follows:
+If you don't want to start @code{mysqld-max-nt} as a service,
+you can start it as follows:
@example
-C:\> C:\mysql\bin\mysqld-nt --standalone
+C:\> C:\mysql\bin\mysqld-max-nt --standalone
@end example
or
@@ -10310,8 +9305,8 @@ or
C:\> C:\mysql\bin\mysqld --standalone --debug
@end example
-The last version gives you a debug trace in @file{C:\mysqld.trace}.
-@xref{Making trace files}.
+The last method gives you a debug trace in
+@file{C:\mysqld.trace}. @xref{Making trace files}.
@node Windows running, Windows and SSH, NT start, Windows
@@ -10320,29 +9315,33 @@ The last version gives you a debug trace in @file{C:\mysqld.trace}.
@cindex TCP/IP
@cindex named pipes
-MySQL supports TCP/IP on all Windows platforms and named pipes on NT.
-The default is to use named pipes for local connections on NT and TCP/IP for
-all other cases if the client has TCP/IP installed. The host name specifies
-which protocol is used:
+MySQL supports TCP/IP on all Windows platforms and named pipes on
+NT/2000/XP. The default is to use named pipes for local connections
+on NT/2000/XP and TCP/IP for all other cases if the client has TCP/IP
+installed. The host name specifies which protocol is used:
-@multitable @columnfractions .3 .7
-@strong{Host name} @tab @strong{Protocol}
-@item NULL (none) @tab On NT, try named pipes first; if that doesn't work, use TCP/IP. On Win95/Win98, TCP/IP is used.
+@multitable @columnfractions .15 .60
+@item @strong{Host name} @tab @strong{Protocol}
+@item NULL (none) @tab
+On NT/2000/XP, try named pipes first; if that doesn't work, use TCP/IP.
+On 9x/Me, TCP/IP is used.
@item . @tab Named pipes
-@item localhost @tab TCP/IP to current host
-@item hostname @tab TCP/IP
+@item localhost @tab
+TCP/IP to current host
+@item hostname @tab
+TCP/IP
@end multitable
You can force a MySQL client to use named pipes by specifying the
-@code{--pipe} option or by specifying @code{.} as the host name. Use the
+@code{--pipe} option or by specifying @code{.} as the host name. Use the
@code{--socket} option to specify the name of the pipe.
Note that starting from 3.23.50, named pipes are only enabled if mysqld is
-started with with @code{--enable-named-pipe}. This is because some users
+started with @code{--enable-named-pipe}. This is because some users
have experienced problems shutting down the MySQL server when one uses
named pipes.
-You can test whether or not MySQL is working by executing the
+You can test whether MySQL is working by executing the
following commands:
@example
@@ -10352,16 +9351,17 @@ C:\> C:\mysql\bin\mysqladmin version status proc
C:\> C:\mysql\bin\mysql test
@end example
-If @code{mysqld} is slow to answer to connections on Win95/Win98, there is
+If @code{mysqld} is slow to answer to connections on Windows 9x/Me, there is
probably a problem with your DNS. In this case, start @code{mysqld} with
@code{--skip-name-resolve} and use only @code{localhost} and IP numbers in
the MySQL grant tables. You can also avoid DNS when connecting to a
-@code{mysqld-nt} MySQL server running on NT by using the
+@code{mysqld-nt} MySQL server running on NT/2000/XP by using the
@code{--pipe} argument to specify use of named pipes. This works for most
MySQL clients.
There are two versions of the MySQL command-line tool:
-@multitable @columnfractions .25 .75
+@multitable @columnfractions .10 .60
+@item @strong{Binary} @tab @strong{Description}
@item @code{mysql} @tab Compiled on native Windows, which offers very limited text editing capabilities.
@item @code{mysqlc} @tab Compiled with the Cygnus GNU compiler and libraries, which offers @code{readline} editing.
@end multitable
@@ -10376,7 +9376,7 @@ more secure, you should set a password for all users and remove the row in
the @code{mysql.user} table that has @code{Host='localhost'} and
@code{User=''}.
-You should also add a password for the @code{root} user. The following
+You should also add a password for the @code{root} user. The following
example starts by removing the anonymous user that can be used by anyone
to access the @code{test} database, then sets a @code{root} user password:
@@ -10397,8 +9397,9 @@ C:\> mysqladmin --user=root --password=your_password shutdown
If you are using the old shareware version of MySQL Version
3.21 under Windows, the above command will fail with an error:
-@code{parse error near 'SET OPTION password'}. The fix is in to upgrade
-to the current MySQL version, which is freely available.
+@code{parse error near 'SET password'}. The solution for
+this is to download and upgrade to the latest MySQL version,
+which is now freely available.
With the current MySQL versions you can easily add new users
and change privileges with @code{GRANT} and @code{REVOKE} commands.
@@ -10413,7 +9414,7 @@ and change privileges with @code{GRANT} and @code{REVOKE} commands.
@cindex SSH
@cindex connecting, remotely with SSH
-Here is a note about how to connect to get a secure connection to remote
+Here is a note about how to connect to get a secure connection to remote
MySQL server with SSH (by David Carlson @email{dcarlson@@mplcomm.com}):
@itemize @bullet
@@ -10421,12 +9422,12 @@ MySQL server with SSH (by David Carlson @email{dcarlson@@mplcomm.com}):
Install an SSH client on your Windows machine. As a user, the best non-free
one I've found is from @code{SecureCRT} from @uref{http://www.vandyke.com/}.
Another option is @code{f-secure} from @uref{http://www.f-secure.com/}. You
-can also find some free ones on @strong{Google} at
+can also find some free ones on @code{Google} at
@uref{http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/}.
@item
-Start your Windows SSH client.
-Set @code{Host_Name = yourmysqlserver_URL_or_IP}.
+Start your Windows SSH client.
+Set @code{Host_Name = yourmysqlserver_URL_or_IP}.
Set @code{userid=your_userid} to log in to your server (probably not the same
as your MySQL login/password.
@@ -10445,14 +9446,14 @@ On your Windows machine, start some ODBC application (such as Access).
@item
Create a new file in Windows and link to MySQL using the ODBC
-driver the same way you normally do, EXCEPT type in @code{localhost}
-for the MySQL host server --- not @code{yourmysqlservername}.
+driver the same way you normally do, except type in @code{localhost}
+for the MySQL host server@-not @code{yourmysqlservername}.
@end itemize
-You should now have an ODBC connection to MySQL, encrypted using SSH.
+You should now have an ODBC connection to MySQL, encrypted using SSH.
-@node Windows symbolic links, Windows compiling, Windows and SSH, Windows
+@node Windows symbolic links, Windows client compiling, Windows and SSH, Windows
@subsubsection Splitting Data Across Different Disks on Windows
@cindex symbolic links
@@ -10480,7 +9481,7 @@ text @code{D:\data\foo\}. After that, all tables created in the database
Note that because of the speed penalty you get when opening every table,
we have not enabled this by default even if you have compiled
MySQL with support for this. To enable symlinks you should put
-in your @code{my.cnf} or @code{my.ini} file the following entry:
+in your @file{my.cnf} or @file{my.ini} file the following entry:
@example
[mysqld]
@@ -10492,7 +9493,7 @@ should instead use the @code{skip-symlink} option if you want to
disable this.
-@node Windows compiling, Windows vs Unix, Windows symbolic links, Windows
+@node Windows client compiling, Windows vs Unix, Windows symbolic links, Windows
@subsubsection Compiling MySQL Clients on Windows
@cindex compiling, on Windows
@@ -10516,7 +9517,7 @@ Note that as the mysqlclient libraries are compiled as threaded libraries,
you should also compile your code to be multi-threaded!
-@node Windows vs Unix, , Windows compiling, Windows
+@node Windows vs Unix, , Windows client compiling, Windows
@subsubsection MySQL-Windows Compared to Unix MySQL
@cindex Windows, versus Unix
@@ -10527,21 +9528,22 @@ of MySQL has the same features as the corresponding Unix version
with the following exceptions:
@table @strong
-@item Win95 and threads
-Win95 leaks about 200 bytes of main memory for each thread creation.
+@item Windows 95 and threads
+Windows 95 leaks about 200 bytes of main memory for each thread creation.
Each connection in MySQL creates a new thread, so you shouldn't
-run @code{mysqld} for an extended time on Win95 if your server handles
-many connections! WinNT and Win98 don't suffer from this bug.
+run @code{mysqld} for an extended time on Windows 95 if your server handles
+many connections! Other versions of Windows don't suffer from this bug.
@item Concurrent reads
MySQL depends on the @code{pread()} and @code{pwrite()} calls to be
able to mix @code{INSERT} and @code{SELECT}. Currently we use mutexes
to emulate @code{pread()}/@code{pwrite()}. We will, in the long run,
replace the file level interface with a virtual interface so that we can
-use the @code{readfile()}/@code{writefile()} interface on NT to get more speed.
+use the @code{readfile()}/@code{writefile()} interface on NT/2000/XP to
+get more speed.
The current implementation limits the number of open files MySQL
can use to 1024, which means that you will not be able to run as many
-concurrent threads on NT as on Unix.
+concurrent threads on NT/2000/XP as on Unix.
@item Blocking read
MySQL uses a blocking read for each connection.
@@ -10567,26 +9569,22 @@ connections.
We plan to fix this problem when our Windows developers have figured out a
nice workaround.
-@item UDF functions
-For the moment, MySQL-Windows does not support user-definable
-functions.
-
@item @code{DROP DATABASE}
You can't drop a database that is in use by some thread.
@item Killing MySQL from the task manager
You can't kill MySQL from the task manager or with the shutdown
-utility in Win95. You must take it down with @code{mysqladmin shutdown}.
+utility in Windows 95. You must take it down with @code{mysqladmin shutdown}.
@item Case-insensitive names
-Filenames are case insensitive on Windows, so database and table names
-are also case insensitive in MySQL for Windows. The only
+Filenames are case-insensitive on Windows, so database and table names
+are also case-insensitive in MySQL for Windows. The only
restriction is that database and table names must be specified using the same
case throughout a given statement. @xref{Name case sensitivity}.
@item The @samp{\} directory character
-Pathname components in Win95 are separated by the @samp{\} character, which is
-also the escape character in MySQL. If you are using @code{LOAD
+Pathname components in Windows 95 are separated by the @samp{\} character,
+which is also the escape character in MySQL. If you are using @code{LOAD
DATA INFILE} or @code{SELECT ... INTO OUTFILE}, you must double the @samp{\}
character:
@@ -10611,8 +9609,8 @@ error 2017: can't open named pipe to host: . pipe...
@end example
@tindex .my.cnf file
-This is because the release version of MySQL uses named pipes on NT
-by default. You can avoid this error by using the @code{--host=localhost}
+This is because the release version of MySQL uses named pipes on NT
+by default. You can avoid this error by using the @code{--host=localhost}
option to the new MySQL clients or create an option file
@file{C:\my.cnf} that contains the following information:
@@ -10643,12 +9641,18 @@ from usage by other threads. This has to do with the fact that on Windows,
you can't delete a file that is in use by another threads. (In the future,
we may find some way to work around this problem.)
-@item @code{DROP TABLE} on a table that is in use by a @code{MERGE} table will not work
-The @code{MERGE} handler does its table mapping hidden from MySQL.
-Because Windows doesn't allow you to drop files that are open, you first
-must flush all @code{MERGE} tables (with @code{FLUSH TABLES}) or drop the
-@code{MERGE} table before dropping the table. We will fix this at the same
-time we introduce @code{VIEW}s.
+@item
+@code{DROP TABLE} on a table that is in use by a @code{MERGE} table will
+not work on Windows because @code{MERGE} handler does the table mapping
+hidden from the upper layer of MySQL. Because Windows doesn't allow you
+to drop files that are open, you first must flush all @code{MERGE}
+tables (with @code{FLUSH TABLES}) or drop the @code{MERGE} table before
+dropping the table. We will fix this at the same time we introduce
+@code{VIEW}s.
+@item
+@code{DATA DIRECTORY} and @code{INDEX DIRECTORY} directives in
+@code{CREATE TABLE} is ignored on Windows, because Windows doesn't support
+symbolic links.
@end table
Here are some open issues for anyone who might want to help us with the Windows
@@ -10667,24 +9671,17 @@ client/server and don't need to access the server from other hosts.
Add some nice start and shutdown icons to the MySQL installation.
@item
-Create a tool to manage registry entries for the MySQL startup
-options. The registry entry reading is already coded into @file{mysqld.cc},
-but it should be recoded to be more parameter oriented. The tool should
-also be able to update the @file{C:\my.cnf} option file if the user prefers
-to use that instead of the registry.
-
-@item
When registering @code{mysqld} as a service with @code{--install} (on NT)
-it would be nice if you could also add default options on the command line.
+it would be nice if you could also add default options on the command-line.
For the moment, the workaround is to list the parameters in the
@file{C:\my.cnf} file instead.
@item
-It would be real nice to be able to kill @code{mysqld} from the task manager.
+It would be really nice to be able to kill @code{mysqld} from the task manager.
For the moment, you must use @code{mysqladmin shutdown}.
@item
-Port @code{readline} to Windows for use in the @code{mysql} command line tool.
+Port @code{readline} to Windows for use in the @code{mysql} command-line tool.
@item
GUI versions of the standard MySQL clients (@code{mysql},
@@ -10692,7 +9689,7 @@ GUI versions of the standard MySQL clients (@code{mysql},
@item
It would be nice if the socket read and write functions in @file{net.c} were
-interruptible. This would make it possible to kill open threads with
+interruptible. This would make it possible to kill open threads with
@code{mysqladmin kill} on Windows.
@item
@@ -10700,12 +9697,8 @@ interruptible. This would make it possible to kill open threads with
We would like to have @code{mysqld} use the current locale for the sort order.
@item
-Implement UDF functions with @code{.DLL}s.
-
-@item
Add macros to use the faster thread-safe increment/decrement methods
provided by Windows.
-
@end itemize
Other Windows-specific issues are described in the @file{README} file that
@@ -10726,7 +9719,8 @@ distribution unpacked! Solaris @code{tar} can't handle long file names, so
you may see an error like this when you unpack MySQL:
@example
-x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2,informix,ms-sql,mysql,oracle,solid,sybase, 0 bytes, 0 tape blocks
+x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2,\
+informix,ms-sql,mysql,oracle,solid,sybase, 0 bytes, 0 tape blocks
tar: directory checksum error
@end example
@@ -10767,7 +9761,7 @@ CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory --enable-assembler
@end example
-If you have a ultra sparc, you can get 4 % more performance by adding
+If you have an UltraSPARC, you can get 4% more performance by adding
"-mcpu=v8 -Wa,-xarch=v8plusa" to CFLAGS and CXXFLAGS.
If you have Sun Workshop (Fortre) 5.3 (or newer) compiler, you can
@@ -10779,7 +9773,7 @@ CXX=CC CXXFLAGS="-noex -xO4 -mt" \
./configure --prefix=/usr/local/mysql --enable-assembler
@end example
-In the MySQL benchmarks, we got a 6 % speedup on an Ultrasparc when
+In the MySQL benchmarks, we got a 6% speedup on an UltraSPARC when
using Sun Workshop 5.3 compared to using gcc with -mcpu flags.
If you get a problem with @code{fdatasync} or @code{sched_yield},
@@ -10804,7 +9798,7 @@ If you turn on @code{__STDC__} with the @code{-Xc} option, the Sun compiler
can't compile with the Solaris @file{pthread.h} header file. This is a Sun
bug (broken compiler or broken include file).
-If @code{mysqld} issues the error message shown below when you run it, you have
+If @code{mysqld} issues the error message shown here when you run it, you have
tried to compile MySQL with the Sun compiler without enabling the
multi-thread option (@code{-mt}):
@@ -10814,6 +9808,14 @@ libc internal error: _rmutex_unlock: rmutex not held
Add @code{-mt} to @code{CFLAGS} and @code{CXXFLAGS} and try again.
+If you are using the SFW version of gcc (which comes with Solaris 8),
+you must add @file{/opt/sfw/lib} to the environment variable
+@code{LD_LIBRARY_PATH} before running configure.
+
+If you are using the gcc available from @code{sunfreeware.com}, you may
+have many problems. You should recompile gcc and GNU binutils on the
+machine you will be running them from to avoid any problems.
+
If you get the following error when compiling MySQL with @code{gcc},
it means that your @code{gcc} is not configured for your version of Solaris:
@@ -10859,7 +9861,8 @@ If you are linking your own MySQL client, you might get the
following error when you try to execute it:
@example
-ld.so.1: ./my: fatal: libmysqlclient.so.#: open failed: No such file or directory
+ld.so.1: ./my: fatal: libmysqlclient.so.#:
+open failed: No such file or directory
@end example
The problem can be avoided by one of the following methods:
@@ -10879,13 +9882,6 @@ Add the pathname of the directory where @file{libmysqlclient.so} is located
to the @code{LD_RUN_PATH} environment variable before running your client.
@end itemize
-When using the @code{--with-libwrap} configure option, you must also
-include the libraries that @file{libwrap.a} needs:
-
-@example
---with-libwrap="/opt/NUtcpwrapper-7.6/lib/libwrap.a -lnsl -lsocket
-@end example
-
If you have problems with configure trying to link with @code{-lz} and
you don't have @code{zlib} installed, you have two options:
@@ -10906,6 +9902,9 @@ If you would like MySQL to start automatically, you can copy
@file{support-files/mysql.server} to @file{/etc/init.d} and create a
symbolic link to it named @file{/etc/rc3.d/S99mysql.server}.
+As Solaris doesn't support core files for @code{setuid()} applications,
+you can't get a core file from @code{mysqld} if you are using the
+@code{--user} option.
@menu
* Solaris 2.7:: Solaris 2.7/2.8 Notes
@@ -11006,7 +10005,8 @@ following @code{configure} command:
@example
CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
CXX=gcc \
-CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
+CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions \
+-fno-rtti -DHAVE_CURSES_H" \
./configure --prefix=/usr/local/mysql
@end example
@@ -11020,14 +10020,15 @@ it with a trace file or under @code{gdb}. @xref{Using gdb on mysqld}.
@node BSD Notes, Mac OS X, Solaris, Operating System Specific Notes
@subsection BSD Notes
+This section provides information for the various BSD flavours,
+as well as specific versions within those.
+
@menu
* FreeBSD:: FreeBSD Notes
* NetBSD:: NetBSD notes
-* OpenBSD:: OpenBSD Notes
-* OpenBSD 2.5:: OpenBSD 2.5 Notes
+* OpenBSD:: OpenBSD 2.5 Notes
* OpenBSD 2.8:: OpenBSD 2.8 Notes
-* BSDI:: BSD/OS Notes
-* BSDI2:: BSD/OS Version 2.x Notes
+* BSDI:: BSD/OS Version 2.x Notes
* BSDI3:: BSD/OS Version 3.x Notes
* BSDI4:: BSD/OS Version 4.x Notes
@end menu
@@ -11039,13 +10040,14 @@ it with a trace file or under @code{gdb}. @xref{Using gdb on mysqld}.
FreeBSD 3.x is recommended for running MySQL since the thread package
is much more integrated.
-The easiest and therefor the preferred way to install is to use the
-mysql-server and mysql-client ports available on @uref{http://www.freebsd.org}.
+The easiest and therefore the preferred way to install is to use the
+mysql-server and mysql-client ports available on
+@uref{http://www.freebsd.org/}.
Using these gives you:
@itemize @bullet
@item
-A working MySQL with all optimizations known to work on your version
+A working MySQL with all optimisations known to work on your version
of FreeBSD enabled.
@item
@@ -11067,17 +10069,32 @@ Versions 3 and up. It is possible to run with native threads on some late
The MySQL @file{Makefile}s require GNU make (@code{gmake}) to work. If
you want to compile MySQL you need to install GNU @code{make} first.
-Be sure to have your name resolver setup correct. Otherwise you may
+Be sure to have your name resolver setup correct. Otherwise, you may
experience resolver delays or failures when connecting to @code{mysqld}.
Make sure that the @code{localhost} entry in the @file{/etc/hosts} file is
-correct (otherwise you will have problems connecting to the database). The
+correct (otherwise, you will have problems connecting to the database). The
@file{/etc/hosts} file should start with a line:
@example
127.0.0.1 localhost localhost.your.domain
@end example
+The recommended way to compile and install MySQL on FreeBSD with
+gcc (2.95.2 and up) is:
+
+@example
+CC=gcc CFLAGS="-O2 -fno-strength-reduce" \
+CXX=gcc CXXFLAGS="-O2 -fno-rtti -fno-exceptions -felide-constructors \
+-fno-strength-reduce" \
+./configure --prefix=/usr/local/mysql --enable-assembler
+gmake
+gmake install
+./scripts/mysql_install_db
+cd /usr/local/mysql
+./bin/mysqld_safe &
+@end example
+
If you notice that @code{configure} will use MIT-pthreads, you should read
the MIT-pthreads notes. @xref{MIT-pthreads}.
@@ -11098,30 +10115,26 @@ appropriate class for this user in the password file if you are not
using the default (use: chpass mysqld-user-name). @xref{safe_mysqld, ,
@code{safe_mysqld}}.
+If you have a lot of memory you should consider rebuilding
+the kernel to allow MySQL to take more than 512M of RAM.
+Take a look at @code{option MAXDSIZ} in the LINT config
+file for more info.
+
If you get problems with the current date in MySQL, setting the
@code{TZ} variable will probably help. @xref{Environment variables}.
To get a secure and stable system you should only use FreeBSD kernels
-that are marked @code{-STABLE}.
+that are marked @code{-RELEASE}.
@node NetBSD, OpenBSD, FreeBSD, BSD Notes
@subsubsection NetBSD notes
-To compile on NetBSD you need GNU @code{make}. Otherwise the compile will
+To compile on NetBSD you need GNU @code{make}. Otherwise, the compile will
crash when @code{make} tries to run @code{lint} on C++ files.
-@node OpenBSD, OpenBSD 2.5, NetBSD, BSD Notes
-@subsubsection OpenBSD Notes
-
-@menu
-* OpenBSD 2.5:: OpenBSD 2.5 Notes
-* OpenBSD 2.8:: OpenBSD 2.8 Notes
-@end menu
-
-
-@node OpenBSD 2.5, OpenBSD 2.8, OpenBSD, BSD Notes
+@node OpenBSD, OpenBSD 2.8, NetBSD, BSD Notes
@subsubsection OpenBSD 2.5 Notes
On OpenBSD Version 2.5, you can compile MySQL with native threads
@@ -11132,7 +10145,7 @@ CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no
@end example
-@node OpenBSD 2.8, BSDI, OpenBSD 2.5, BSD Notes
+@node OpenBSD 2.8, BSDI, OpenBSD, BSD Notes
@subsubsection OpenBSD 2.8 Notes
Our users have reported that OpenBSD 2.8 has a threading bug which causes
@@ -11141,18 +10154,16 @@ but as of January 25th, 2001, it's only available in the ``-current'' branch.
The symptoms of this threading bug are: slow response, high load, high CPU
usage, and crashes.
+If you get an error like @code{Error in accept:: Bad file descriptor} or
+error 9 when trying to open tables or directories, the problem is probably
+that you haven't allocated enough file descriptors for MySQL.
-@node BSDI, BSDI2, OpenBSD 2.8, BSD Notes
-@subsubsection BSD/OS Notes
+In this case try starting @code{safe_mysqld} as root with the following
+options:
-@menu
-* BSDI2:: BSD/OS 2.x notes
-* BSDI3:: BSD/OS 3.x notes
-* BSDI4:: BSD/OS 4.x notes
-@end menu
+@code{--user=mysql --open-files-limit=2048}
-
-@node BSDI2, BSDI3, BSDI, BSD Notes
+@node BSDI, BSDI3, OpenBSD 2.8, BSD Notes
@subsubsection BSD/OS Version 2.x Notes
If you get the following error when compiling MySQL, your
@@ -11177,7 +10188,7 @@ If you get problems with the current date in MySQL, setting the
@code{TZ} variable will probably help. @xref{Environment variables}.
-@node BSDI3, BSDI4, BSDI2, BSD Notes
+@node BSDI3, BSDI4, BSDI, BSD Notes
@subsubsection BSD/OS Version 3.x Notes
Upgrade to BSD/OS Version 3.1. If that is not possible, install
@@ -11241,7 +10252,7 @@ before running make.
Note that the above means that you can't symbolic link a database directories
to another database directory or symbolic link a table to another database
-on BSDI! (Making a symbolic link to another disk is ok).
+on BSDI! (Making a symbolic link to another disk is okay).
@node Mac OS X, Other Unix Notes, BSD Notes, Operating System Specific Notes
@@ -11271,11 +10282,14 @@ Our binary for Mac OS X is compiled on Rhapsody 5.5 with the following
configure line:
@example
-CC=gcc CFLAGS="-O2 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O2 -fomit-frame-pointer" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex --disable-shared
+CC=gcc CFLAGS="-O2 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O2 \
+-fomit-frame-pointer" ./configure --prefix=/usr/local/mysql \
+"--with-comment=Official MySQL binary" --with-extra-charsets=complex \
+--disable-shared
@end example
You might want to also add aliases to your shell's resource file to
-access @code{mysql} and @code{mysqladmin} from the command line:
+access @code{mysql} and @code{mysqladmin} from the command-line:
@example
alias mysql '/usr/local/mysql/bin/mysql'
@@ -11293,10 +10307,10 @@ alias mysqladmin '/usr/local/mysql/bin/mysqladmin'
* IBM-AIX:: IBM-AIX notes
* SunOS:: SunOS 4 Notes
* Alpha-DEC-UNIX:: Alpha-DEC-UNIX Notes (Tru64)
-* Alpha-DEC-OSF1:: Alpha-DEC-OSF1 Notes
+* Alpha-DEC-OSF1:: Alpha-DEC-OSF/1 Notes
* SGI-Irix:: SGI Irix Notes
-* SCO:: SCO Notes
-* SCO Unixware:: SCO Unixware Version 7.0 Notes
+* Caldera:: Caldera Notes
+* Caldera Unixware:: Caldera Unixware Version 7.0 Notes
@end menu
@@ -11312,8 +10326,8 @@ file you must be running at least HP-UX 10.x to have access to HP's
software depot tools.
The HP version of MySQL was compiled on an HP 9000/8xx server
-under HP-UX 10.20, and uses MIT-pthreads. It is known to work well under
-this configuration. MySQL Version 3.22.26 and newer can also be
+under HP-UX 10.20, and uses MIT-pthreads. It is known to work well under
+this configuration. MySQL Version 3.22.26 and newer can also be
built with HP's native thread package.
Other configurations that may work:
@@ -11334,7 +10348,7 @@ HP 9000/7xx or 8xx running HP-UX 10.x where x < 2
HP 9000/7xx or 8xx running HP-UX 9.x
@end itemize
-To install the distribution, use one of the commands below, where
+To install the distribution, use one of the commands here, where
@code{/path/to/depot} is the full pathname of the depot file:
@itemize @bullet
@@ -11383,25 +10397,18 @@ There are a couple of small problems when compiling MySQL on
HP-UX. We recommend that you use @code{gcc} instead of the HP-UX native
compiler, because @code{gcc} produces better code!
-We recommend using gcc 2.95 on HP-UX. Don't use high optimization
+We recommend using gcc 2.95 on HP-UX. Don't use high optimisation
flags (like -O6) as this may not be safe on HP-UX.
-Note that MIT-pthreads can't be compiled with the HP-UX compiler
-because it can't compile @code{.S} (assembler) files.
-
-The following configure line should work:
+The following configure line should work with gcc 2.95:
@example
-CFLAGS="-DHPUX -I/opt/dce/include" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pthread --with-named-thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared
+CFLAGS="-I/opt/dce/include -fpic" \
+CXXFLAGS="-I/opt/dce/include -felide-constructors -fno-exceptions \
+-fno-rtti" CXX=gcc ./configure --with-pthread \
+--with-named-thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared
@end example
-If you are compiling @code{gcc} 2.95 yourself, you should NOT link it with
-the DCE libraries (@code{libdce.a} or @code{libcma.a}) if you want to compile
-MySQL with MIT-pthreads. If you mix the DCE and MIT-pthreads
-packages you will get a @code{mysqld} to which you cannot connect. Remove
-the DCE libraries while you compile @code{gcc} 2.95!
-
-
@node HP-UX 11.x, IBM-AIX, HP-UX 10.20, Other Unix Notes
@subsubsection HP-UX Version 11.x Notes
@@ -11415,7 +10422,7 @@ PHKL_22840 Streams cumulative
PHNE_22397 ARPA cumulative
@end example
-This will solve a problem that one gets @code{EWOULDBLOCK} from @code{recv()}
+This will solve the problem of getting @code{EWOULDBLOCK} from @code{recv()}
and @code{EBADF} from @code{accept()} in threaded applications.
If you are using @code{gcc} 2.95.1 on an unpatched HP-UX 11.x system,
@@ -11454,7 +10461,9 @@ the definition in @file{pthread.h}. Here's the diff:
After this, the following configure line should work:
@example
-CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" ./configure --prefix=/usr/local/mysql --disable-shared
+CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc \
+CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" \
+./configure --prefix=/usr/local/mysql --disable-shared
@end example
Here is some information that a HP-UX Version 11.x user sent us about compiling
@@ -11494,13 +10503,13 @@ MySQL with HP-UX:x compiler:
@itemize @bullet
@item
-I had to use the compile-time flag @code{-D_REENTRANT} to get the compiler
-to recognize the prototype for @code{localtime_r}. Alternatively I could have
-supplied the prototype for @code{localtime_r}. But I wanted to catch other
+I had to use the compile-time flag @code{-D_REENTRANT} to get the compiler
+to recognise the prototype for @code{localtime_r}. Alternatively I could have
+supplied the prototype for @code{localtime_r}. But I wanted to catch other
bugs without needing to run into them. I wasn't sure where I needed it, so I
added it to all flags.
@item
-The optimization flags used by MySQL (-O3) are not recognized by HP's
+The optimisation flags used by MySQL (-O3) are not recognised by HP's
compilers. I did not change the flags.
@end itemize
@@ -11508,7 +10517,8 @@ If you get the following error from @code{configure}
@example
checking for cc option to accept ANSI C... no
-configure: error: MySQL requires a ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.
+configure: error: MySQL requires a ANSI C compiler (and a C++ compiler).
+Try gcc. See the Installation chapter in the Reference Manual.
@end example
Check that you don't have the path to the K&R compiler before the path
@@ -11549,9 +10559,9 @@ you must also remove the @code{-qstrict} option (this is a limitation in
the IBM C compiler).
If you are using @code{gcc} or @code{egcs} to compile MySQL, you
-@strong{MUST} use the @code{-fno-exceptions} flag, as the exception
-handling in @code{gcc}/@code{egcs} is not thread safe! (This is tested with
-@code{egcs} 1.1.). There are also some known problems with IBM's assembler,
+@strong{must} use the @code{-fno-exceptions} flag, as the exception
+handling in @code{gcc}/@code{egcs} is not thread-safe! (This is tested with
+@code{egcs} 1.1.) There are also some known problems with IBM's assembler,
which may cause it to generate bad code when used with gcc.
We recommend the following @code{configure} line with @code{egcs} and
@@ -11566,25 +10576,25 @@ CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
The @code{-Wa,-many} is necessary for the compile to be successful. IBM is
aware of this problem but is in to hurry to fix it because of the workaround
-available. We don't know if the @code{-fno-exceptions} is required with
-@code{gcc 2.95}, but as MySQL doesn't use exceptions and the above
-option generates faster code, we recommend that you should always use this
+available. We don't know if the @code{-fno-exceptions} is required with
+@code{gcc 2.95}, but as MySQL doesn't use exceptions and the above
+option generates faster code, we recommend that you should always use this
option with @code{egcs / gcc}.
If you get a problem with assembler code try changing the -mcpu=xxx to
-match your cpu. Typically power2, power, or powerpc may need to be used,
+match your CPU. Typically power2, power, or powerpc may need to be used,
alternatively you might need to use 604 or 604e. I'm not positive but I
would think using "power" would likely be safe most of the time, even on
a power2 machine.
-If you don't know what your cpu is then do a "uname -m", this will give
+If you don't know what your CPU is then do a "uname -m", this will give
you back a string that looks like "000514676700", with a format of
xxyyyyyymmss where xx and ss are always 0's, yyyyyy is a unique system
id and mm is the id of the CPU Planar. A chart of these values can be
found at
-@uref{http://www.rs6000.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm}.
+@uref{http://publib.boulder.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm}.
This will give you a machine type and a machine model you can use to
-determine what type of cpu you have.
+determine what type of CPU you have.
If you have problems with signals (MySQL dies unexpectedly
under high load) you may have found an OS bug with threads and
@@ -11593,7 +10603,8 @@ configuring with:
@example
shell> CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
- CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -DDONT_USE_THR_ALARM" \
+ CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti \
+ -DDONT_USE_THR_ALARM" \
./configure --prefix=/usr/local/mysql --with-debug --with-low-memory
@end example
@@ -11677,7 +10688,7 @@ accept(int,sockadddr *, int *)'
You can safely ignore these warnings. They occur because @code{configure}
can detect only errors, not warnings.
-If you start the server directly from the command line, you may have problems
+If you start the server directly from the command-line, you may have problems
with it dying when you log out. (When you log out, your outstanding processes
receive a @code{SIGHUP} signal.) If so, try starting the server like this:
@@ -11700,7 +10711,8 @@ work:
CC="cc -pthread"
CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
CXX="cxx -pthread"
-CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
+CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host \
+-noexceptions -nortti"
export CC CFLAGS CXX CXXFLAGS
./configure \
--prefix=/usr/local/mysql \
@@ -11731,7 +10743,7 @@ scripts/mysql_install_db
@node Alpha-DEC-OSF1, SGI-Irix, Alpha-DEC-UNIX, Other Unix Notes
-@subsubsection Alpha-DEC-OSF1 Notes
+@subsubsection Alpha-DEC-OSF/1 Notes
If you have problems compiling and have DEC @code{CC} and @code{gcc}
installed, try running @code{configure} like this:
@@ -11755,8 +10767,8 @@ Note that the following problems with the @code{ld} program can be fixed
by downloading the latest DEC (Compaq) patch kit from:
@uref{http://ftp.support.compaq.com/public/unix/}.
-On OSF1 V4.0D and compiler "DEC C V5.6-071 on Digital Unix V4.0 (Rev. 878)"
-the compiler had some strange behavior (undefined @code{asm} symbols).
+On OSF/1 V4.0D and compiler "DEC C V5.6-071 on Digital Unix V4.0 (Rev. 878)"
+the compiler had some strange behaviour (undefined @code{asm} symbols).
@code{/bin/ld} also appears to be broken (problems with @code{_exit
undefined} errors occuring while linking @code{mysqld}). On this system, we
have managed to compile MySQL with the following @code{configure}
@@ -11770,14 +10782,17 @@ With the Digital compiler "C++ V6.1-029", the following should work:
@example
CC=cc -pthread
-CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host
+CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all \
+ -arch host
CXX=cxx -pthread
-CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host -noexceptions -nortti
+CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all \
+ -arch host -noexceptions -nortti
export CC CFLAGS CXX CXXFLAGS
-./configure --prefix=/usr/mysql/mysql --with-mysqld-ldflags=-all-static --disable-shared --with-named-thread-libs="-lmach -lexc -lc"
+./configure --prefix=/usr/mysql/mysql --with-mysqld-ldflags=-all-static \
+ --disable-shared --with-named-thread-libs="-lmach -lexc -lc"
@end example
-In some versions of OSF1, the @code{alloca()} function is broken. Fix
+In some versions of OSF/1, the @code{alloca()} function is broken. Fix
this by removing the line in @file{config.h} that defines @code{'HAVE_ALLOCA'}.
The @code{alloca()} function also may have an incorrect prototype in
@@ -11789,7 +10804,7 @@ The @code{alloca()} function also may have an incorrect prototype in
When using @code{gcc}, you can also try running @code{configure} like this:
@example
-shell> CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ....
+shell> CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ...
@end example
If you have problems with signals (MySQL dies unexpectedly
@@ -11818,12 +10833,12 @@ Please submit a full bug report.
To fix this you should change to the @code{sql} directory and do a ``cut
and paste'' of the last @code{gcc} line, but change @code{-O3} to
@code{-O0} (or add @code{-O0} immediately after @code{gcc} if you don't
-have any @code{-O} option on your compile line.) After this is done you
+have any @code{-O} option on your compile line). After this is done you
can just change back to the top-level directly and run @code{make}
again.
-@node SGI-Irix, SCO, Alpha-DEC-OSF1, Other Unix Notes
+@node SGI-Irix, Caldera, Alpha-DEC-OSF1, Other Unix Notes
@subsubsection SGI Irix Notes
If you are using Irix Version 6.5.3 or newer @code{mysqld} will only be able to
@@ -11842,11 +10857,11 @@ In some Irix implementations, the @code{alloca()} function is broken. If the
@code{mysqld} server dies on some @code{SELECT} statements, remove the lines
from @file{config.h} that define @code{HAVE_ALLOC} and @code{HAVE_ALLOCA_H}.
If @code{mysqladmin create} doesn't work, remove the line from @file{config.h}
-that defines @code{HAVE_READDIR_R}. You may have to remove the
+that defines @code{HAVE_READDIR_R}. You may have to remove the
@code{HAVE_TERM_H} line as well.
SGI recommends that you install all of the patches on this page as a set:
-http://support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html
+@uref{http://support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html}
At the very minimum, you should install the latest kernel rollup, the
latest @code{rld} rollup, and the latest @code{libc} rollup.
@@ -11866,12 +10881,13 @@ Type the following in the top-level directory of your MySQL source
tree:
@example
-shell> extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
+shell> extra/replace bool curses_bool < /usr/include/curses.h \
+> include/curses.h
shell> make
@end example
There have also been reports of scheduling problems. If only one thread is
-running, things go slow. Avoid this by starting another client. This may
+running, things go slow. Avoid this by starting another client. This may
lead to a 2-to-10-fold increase in execution speed thereafter for the other
thread. This is a poorly understood problem with Irix threads; you may have
to improvise to find solutions until this can be fixed.
@@ -11881,7 +10897,8 @@ If you are compiling with @code{gcc}, you can use the following
@example
CC=gcc CXX=gcc CXXFLAGS=-O3 \
-./configure --prefix=/usr/local/mysql --enable-thread-safe-client --with-named-thread-libs=-lpthread
+./configure --prefix=/usr/local/mysql --enable-thread-safe-client \
+--with-named-thread-libs=-lpthread
@end example
On Irix 6.5.11 with native Irix C and C++ compilers ver. 7.3.1.2, the
@@ -11890,14 +10907,15 @@ following is reported to work
@example
CC=cc CXX=CC CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \
-L/usr/local/lib' CXXFLAGS='-O3 -n32 -TARG:platform=IP22 \
--I/usr/local/include -L/usr/local/lib' ./configure --prefix=/usr/local/mysql \
---with-berkeley-db --with-innodb \
---with-libwrap=/usr/local --with-named-curses-libs=/usr/local/lib/libncurses.a
+-I/usr/local/include -L/usr/local/lib' ./configure \
+--prefix=/usr/local/mysql --with-innodb --with-berkeley-db \
+--with-libwrap=/usr/local \
+--with-named-curses-libs=/usr/local/lib/libncurses.a
@end example
-@node SCO, SCO Unixware, SGI-Irix, Other Unix Notes
-@subsubsection SCO Notes
+@node Caldera, Caldera Unixware, SGI-Irix, Other Unix Notes
+@subsubsection Caldera (SCO) Notes
The current port is tested only on a ``sco3.2v5.0.4'' and
``sco3.2v5.0.5'' system. There has also been a lot of progress on a
@@ -11912,19 +10930,14 @@ CC=gcc CXX=gcc ./configure ... (options)
@enumerate
@item
-For OpenServer 5.0.X you need to use GDS in Skunkware 95 (95q4c). This
-is necessary because GNU @code{gcc} 2.7.2 in Skunkware 97 does not have
-GNU @code{as}. You can also use @code{egcs} 1.1.2 or newer
-@uref{http://www.egcs.com/}. If you are using @code{egcs} 1.1.2 you have
-to execute the following command:
-
-@example
-shell> cp -p /usr/include/pthread/stdtypes.h /usr/local/lib/gcc-lib/i386-pc-sco3.2v5.0.5/egcs-2.91.66/include/pthread/
-@end example
+For OpenServer 5.0.X you need to use gcc-2.95.2p1 or newer from the
+Skunkware. http://www.caldera.com/skunkware/ and choose browser
+OpenServer packages or by ftp to ftp2.caldera.com in the
+pub/skunkware/osr5/devtools/gcc directory.
@item
You need the port of GCC 2.5.x for this product and the Development
-system. They are required on this version of SCO Unix. You cannot
+system. They are required on this version of Caldera (SCO) Unix. You cannot
just use the GCC Dev system.
@item
@@ -11935,8 +10948,8 @@ You can also get a precompiled package from
@uref{http://www.mysql.com/Downloads/SCO/FSU-threads-3.5c.tar.gz}.
@item
-FSU Pthreads can be compiled with SCO Unix 4.2 with tcpip. Or
-OpenServer 3.0 or Open Desktop 3.0 (OS 3.0 ODT 3.0), with the SCO
+FSU Pthreads can be compiled with Caldera (SCO) Unix 4.2 with tcpip. Or
+OpenServer 3.0 or Open Desktop 3.0 (OS 3.0 ODT 3.0), with the Caldera (SCO)
Development System installed using a good port of GCC 2.5.x ODT or OS
3.0 you will need a good port of GCC 2.5.x There are a lot of problems
without a good port. The port for this product requires the SCO Unix
@@ -11994,11 +11007,11 @@ shell> CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
You may get some problems with some include files. In this case, you can
find new SCO-specific include files at
@uref{http://www.mysql.com/Downloads/SCO/SCO-3.2v4.2-includes.tar.gz}.
-You should unpack this file in the @file{include} directory of your
+You should unpack this file in the @file{include} directory of your
MySQL source tree.
@end enumerate
-SCO development notes:
+Caldera (SCO) development notes:
@itemize @bullet
@item
@@ -12006,15 +11019,15 @@ MySQL should automatically detect FSU Pthreads and link @code{mysqld}
with @code{-lgthreads -lsocket -lgthreads}.
@item
-The SCO development libraries are re-entrant in FSU Pthreads. SCO claims
-that its libraries' functions are re-entrant, so they must be reentrant with
-FSU Pthreads. FSU Pthreads on OpenServer tries to use the SCO scheme to
-make re-entrant libraries.
+The Caldera (SCO) development libraries are re-entrant in FSU Pthreads.
+Caldera claim sthat its libraries' functions are re-entrant, so they must
+be reentrant with FSU Pthreads. FSU Pthreads on OpenServer tries to use
+the SCO scheme to make re-entrant libraries.
@item
-FSU Pthreads (at least the version at @uref{http://www.mysql.com/}) comes
-linked with GNU @code{malloc}. If you encounter problems with memory usage,
-make sure that @file{gmalloc.o} is included in @file{libgthreads.a} and
+FSU Pthreads (at least the version at @uref{http://www.mysql.com/}) comes
+linked with GNU @code{malloc}. If you encounter problems with memory usage,
+make sure that @file{gmalloc.o} is included in @file{libgthreads.a} and
@file{libgthreads.so}.
@item
@@ -12024,13 +11037,13 @@ In FSU Pthreads, the following system calls are pthreads-aware: @code{read()},
@item
The CSSA-2001-SCO.35.2 (the patch is listed in custom as
-erg711905-dscr_remap security patch (ver 2.0.0) breaks FSU threads and
-makes mysqld instable. You have to remove this one if you want to run
+erg711905-dscr_remap security patch (version 2.0.0) breaks FSU threads and
+makes mysqld unstable. You have to remove this one if you want to run
mysqld on an OpenServer 5.0.6 machine.
@end itemize
-If you want to install DBI on SCO, you have to edit the @file{Makefile} in
-DBI-xxx and each subdirectory.
+If you want to install DBI on Caldera (SCO), you have to edit the
+@file{Makefile} in DBI-xxx and each subdirectory.
Note that the following assumes gcc 2.95.2 or newer:
@@ -12060,8 +11073,8 @@ if they were compiled with @code{icc} or @code{cc}.
Perl works best when compiled with @code{cc}.
-@node SCO Unixware, , SCO, Other Unix Notes
-@subsubsection SCO Unixware Version 7.0 Notes
+@node Caldera Unixware, , Caldera, Other Unix Notes
+@subsubsection Caldera (SCO) Unixware Version 7.0 Notes
You must use a version of MySQL at least as recent as Version 3.22.13
because that version fixes some portability problems under Unixware.
@@ -12075,11 +11088,15 @@ CC=cc CXX=CC ./configure --prefix=/usr/local/mysql
If you want to use @code{gcc}, you must use @code{gcc} 2.95.2 or newer.
+Caldera provides libsocket.so.2 at
+@uref{ftp://stage.caldera.com/pub/security/tools} for
+pre-OSR506 security fixes. Also, the telnetd fix at
+@url{ftp://stage.caldera.com/pub/security/openserver/CSSA-2001-SCO.10/}
+as both libsocket.so.2 and libresolv.so.1 with instructions for
+installing on pre-OSR506 systems.
-@menu
-* OS/2:: OS/2 Notes
-@end menu
-
+It's probably a good idea to install the above patches before trying to
+compile/use MySQL.
@node OS/2, BeOS, Other Unix Notes, Operating System Specific Notes
@subsection OS/2 Notes
@@ -12119,11 +11136,11 @@ gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \
mv example.dll example.udf
@end example
-@strong{Note:} Due to limitations in OS/2, UDF module name stems must not
+@strong{Note}: Due to limitations in OS/2, UDF module name stems must not
exceed 8 characters. Modules are stored in the @file{/mysql2/udf}
directory; the @code{safe-mysqld.cmd} script will put this directory in
the @code{BEGINLIBPATH} environment variable. When using UDF modules,
-specified extensions are ignored --- it is assumed to be @file{.udf}.
+specified extensions are ignored@-it is assumed to be @file{.udf}.
For example, in Unix, the shared module might be named @file{example.so}
and you would load a function from it like this:
@@ -12143,7 +11160,7 @@ mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example";
@subsection BeOS Notes
We are really interested in getting MySQL to work on BeOS, but
-unfortunately we don't have any person who knows BeOS or has time to do
+unfortunately we don't have any person who knows BeOS or has time to do
a port.
We are interested in finding someone to do a port, and we will help them
@@ -12155,10 +11172,10 @@ in a while.
@node Novell Netware, , BeOS, Operating System Specific Notes
-@subsection Novell Netware Notes
+@subsection Novell NetWare Notes
-We are really interested in getting MySQL to work on Netware, but
-unfortunately we don't have any person who knows Netware or has time to do
+We are really interested in getting MySQL to work on NetWare, but
+unfortunately we don't have any person who knows NetWare or has time to do
a port.
We are interested in finding someone to do a port, and we will help them
@@ -12166,9 +11183,312 @@ with any technical questions they may have while doing the port.
+@node Perl support, , Operating System Specific Notes, Installing
+@section Perl Installation Comments
+
+@cindex Perl, installing
+@cindex installing, Perl
+
+@menu
+* Perl installation:: Installing Perl on Unix
+* ActiveState Perl:: Installing ActiveState Perl on Windows
+* Windows Perl:: Installing the MySQL Perl distribution on Windows
+* Perl support problems:: Problems using the Perl @code{DBI}/@code{DBD} interface
+@end menu
+
+
+@node Perl installation, ActiveState Perl, Perl support, Perl support
+@subsection Installing Perl on Unix
+
+Perl support for MySQL is provided by means of the
+@code{DBI}/@code{DBD} client interface. @xref{Perl}. The Perl
+@code{DBD}/@code{DBI} client code requires Perl Version 5.004 or later. The
+interface @strong{will not work} if you have an older version of Perl.
+
+MySQL Perl support also requires that you've installed
+MySQL client programming support. If you installed MySQL
+from RPM files, client programs are in the client RPM, but client programming
+support is in the developer RPM. Make sure you've installed the latter RPM.
+
+As of Version 3.22.8, Perl support is distributed separately from the main
+MySQL distribution. If you want to install Perl support, the files
+you will need can be obtained from
+@uref{http://www.mysql.com/Downloads/Contrib/}.
+
+The Perl distributions are provided as compressed @code{tar} archives and
+have names like @file{MODULE-VERSION.tar.gz}, where @code{MODULE} is the
+module name and @code{VERSION} is the version number. You should get the
+@code{Data-Dumper}, @code{DBI}, and @code{Msql-Mysql-modules} distributions
+and install them in that order. The installation procedure is shown here.
+The example shown is for the @code{Data-Dumper} module, but the procedure is
+the same for all three distributions:
+
+@enumerate
+@item
+Unpack the distribution into the current directory:
+@example
+shell> gunzip < Data-Dumper-VERSION.tar.gz | tar xvf -
+@end example
+This command creates a directory named @file{Data-Dumper-VERSION}.
+
+@item
+Change into the top-level directory of the unpacked distribution:
+@example
+shell> cd Data-Dumper-VERSION
+@end example
+
+@item
+Build the distribution and compile everything:
+@example
+shell> perl Makefile.PL
+shell> make
+shell> make test
+shell> make install
+@end example
+@end enumerate
+
+The @code{make test} command is important because it verifies that the
+module is working. Note that when you run that command during the
+@code{Msql-Mysql-modules} installation to exercise the interface code, the
+MySQL server must be running or the test will fail.
+
+It is a good idea to rebuild and reinstall the @code{Msql-Mysql-modules}
+distribution whenever you install a new release of MySQL,
+particularly if you notice symptoms such as all your @code{DBI} scripts
+dumping core after you upgrade MySQL.
+
+If you don't have the right to install Perl modules in the system directory
+or if you to install local Perl modules, the following reference may help
+you:
+
+@example
+@uref{http://www.iserver.com/support/contrib/perl5/modules.html}
+@end example
+
+Look under the heading
+@code{Installing New Modules that Require Locally Installed Modules}.
+
+
+@node ActiveState Perl, Windows Perl, Perl installation, Perl support
+@subsection Installing ActiveState Perl on Windows
+
+@cindex installing, Perl on Windows
+@cindex Perl, installing on Windows
+@cindex ActiveState Perl
+
+To install the MySQL @code{DBD} module with ActiveState Perl on
+Windows, you should do the following:
+
+@itemize @bullet
+@item
+Get ActiveState Perl from
+@uref{http://www.activestate.com/Products/ActivePerl/}
+and install it.
+
+@item
+Open a DOS shell.
+
+@item
+If required, set the HTTP_proxy variable. For example, you might try:
+
+@example
+set HTTP_proxy=my.proxy.com:3128
+@end example
+
+@item
+Start the PPM program:
+
+@example
+C:\> c:\perl\bin\ppm.pl
+@end example
+
+@item
+If you have not already done so, install @code{DBI}:
+
+@example
+ppm> install DBI
+@end example
+
+@item
+If this succeeds, run the following command:
+
+@example
+install \
+ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd
+@end example
+@end itemize
+
+The above should work at least with ActiveState Perl Version 5.6.
+
+If you can't get the above to work, you should instead install the
+@code{MyODBC} driver and connect to MySQL server through
+ODBC:
+
+@example
+use DBI;
+$dbh= DBI->connect("DBI:ODBC:$dsn","$user","$password") ||
+ die "Got error $DBI::errstr when connecting to $dsn\n";
+@end example
+
+
+@node Windows Perl, Perl support problems, ActiveState Perl, Perl support
+@subsection Installing the MySQL Perl Distribution on Windows
+
+The MySQL Perl distribution contains @code{DBI},
+@code{DBD:MySQL} and @code{DBD:ODBC}.
+
+@itemize @bullet
+@item
+Get the Perl distribution for Windows from
+@uref{http://www.mysql.com/download.html}.
+
+@item
+Unzip the distribution in @code{C:} so that you get a @file{C:\PERL} directory.
+
+@item
+Add the directory @file{C:\PERL\BIN} to your path.
+
+@item
+Add the directory @file{C:\PERL\BIN\MSWIN32-x86-thread} or
+@file{C:\PERL\BIN\MSWIN32-x86} to your path.
+
+@item
+Test that @code{perl} works by executing @code{perl -v} in a DOS shell.
+@end itemize
+
+
+@node Perl support problems, , Windows Perl, Perl support
+@subsection Problems Using the Perl @code{DBI}/@code{DBD} Interface
+
+@cindex problems, installing Perl
+@cindex Perl DBI/DBD, installation problems
+
+If Perl reports that it can't find the @file{../mysql/mysql.so} module,
+then the problem is probably that Perl can't locate the shared library
+@file{libmysqlclient.so}.
+
+You can fix this by any of the following methods:
+
+@itemize @bullet
+@item
+Compile the @code{Msql-Mysql-modules} distribution with @code{perl
+Makefile.PL -static -config} rather than @code{perl Makefile.PL}.
+
+@item
+Copy @code{libmysqlclient.so} to the directory where your other shared
+libraries are located (probably @file{/usr/lib} or @file{/lib}).
+
+@item
+On Linux you can add the pathname of the directory where
+@file{libmysqlclient.so} is located to the @file{/etc/ld.so.conf} file.
+
+@tindex LD_RUN_PATH environment variable
+@tindex Environment variable, LD_RUN_PATH
+@item
+Add the pathname of the directory where @file{libmysqlclient.so} is located
+to the @code{LD_RUN_PATH} environment variable.
+@end itemize
+
+If you get the following errors from @code{DBD-mysql},
+you are probably using @code{gcc} (or using an old binary compiled with
+@code{gcc}):
+
+@example
+/usr/bin/perl: can't resolve symbol '__moddi3'
+/usr/bin/perl: can't resolve symbol '__divdi3'
+@end example
+
+Add @code{-L/usr/lib/gcc-lib/... -lgcc} to the link command when the
+@file{mysql.so} library gets built (check the output from @code{make} for
+@file{mysql.so} when you compile the Perl client). The @code{-L} option
+should specify the pathname of the directory where @file{libgcc.a} is located
+on your system.
+
+Another cause of this problem may be that Perl and MySQL aren't both
+compiled with @code{gcc}. In this case, you can solve the mismatch by
+compiling both with @code{gcc}.
+
+If you get the following error from @code{Msql-Mysql-modules}
+when you run the tests:
+
+@example
+t/00base............install_driver(mysql) failed:
+Can't load '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
+../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol:
+uncompress at /usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
+@end example
+
+it means that you need to include the compression library, -lz, to the
+link line. This can be doing the following change in the file
+@file{lib/DBD/mysql/Install.pm}:
+
+@example
+$sysliblist .= " -lm";
+
+to
+
+$sysliblist .= " -lm -lz";
+@end example
+
+After this, you @strong{must} run 'make realclean' and then proceed with the
+installation from the beginning.
+
+If you want to use the Perl module on a system that doesn't support
+dynamic linking (like Caldera/SCO) you can generate a static version of
+Perl that includes @code{DBI} and @code{DBD-mysql}. The way this works
+is that you generate a version of Perl with the @code{DBI} code linked
+in and install it on top of your current Perl. Then you use that to
+build a version of Perl that additionally has the @code{DBD} code linked
+in, and install that.
+
+On Caldera (SCO), you must have the following environment variables set:
+
+@example
+shell> LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib
+or
+shell> LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
+/usr/progressive/lib:/usr/skunk/lib
+shell> LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
+/usr/progressive/lib:/usr/skunk/lib
+shell> MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:\
+/usr/skunk/man:
+@end example
+
+First, create a Perl that includes a statically linked @code{DBI} by running
+these commands in the directory where your @code{DBI} distribution is
+located:
+
+@example
+shell> perl Makefile.PL -static -config
+shell> make
+shell> make install
+shell> make perl
+@end example
+
+Then you must install the new Perl. The output of @code{make perl} will
+indicate the exact @code{make} command you will need to execute to perform
+the installation. On Caldera (SCO), this is
+@code{make -f Makefile.aperl inst_perl MAP_TARGET=perl}.
+
+Next, use the just-created Perl to create another Perl that also includes a
+statically-linked @code{DBD::mysql} by running these commands in the
+directory where your @code{Msql-Mysql-modules} distribution is located:
+
+@example
+shell> perl Makefile.PL -static -config
+shell> make
+shell> make install
+shell> make perl
+@end example
+
+Finally, you should install this new Perl. Again, the output of @code{make
+perl} indicates the command to use.
+
+
+
@node Tutorial, MySQL Database Administration, Installing, Top
-@chapter Introduction to MySQL: A MySQL Tutorial
+@chapter Tutorial Introduction
@cindex tutorial
@cindex terminal monitor, defined
@@ -12204,7 +11524,7 @@ shell> mysql --help
This chapter assumes that @code{mysql} is installed on your machine and that
a MySQL server is available to which you can connect. If this is
-not true, contact your MySQL administrator. (If @emph{you} are the
+not true, contact your MySQL administrator. (If @strong{you} are the
administrator, you will need to consult other sections of this manual.)
This chapter describes the entire process of setting up and using a
@@ -12294,16 +11614,16 @@ that's okay. At this point, it's more important to find out a little about
how to issue queries than to jump right in creating tables, loading data
into them, and retrieving data from them. This section describes the basic
principles of entering commands, using several queries you can try out to
-familiarize yourself with how @code{mysql} works.
+familiarise yourself with how @code{mysql} works.
Here's a simple command that asks the server to tell you its version number
-and the current date. Type it in as shown below following the @code{mysql>}
-prompt and hit the RETURN key:
+and the current date. Type it in as shown here following the @code{mysql>}
+prompt and press Enter:
@example
mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
-| version() | CURRENT_DATE |
+| VERSION() | CURRENT_DATE |
+--------------+--------------+
| 3.22.20a-log | 1999-03-19 |
+--------------+--------------+
@@ -12369,7 +11689,7 @@ Just end each one with a semicolon:
@example
mysql> SELECT VERSION(); SELECT NOW();
+--------------+
-| version() |
+| VERSION() |
+--------------+
| 3.22.20a-log |
+--------------+
@@ -12423,11 +11743,11 @@ Here, too, notice the prompt. It switches back to @code{mysql>} after you
type @code{\c}, providing feedback to indicate that @code{mysql} is ready
for a new command.
-The following table shows each of the prompts you may see and summarizes what
+The following table shows each of the prompts you may see and summarises what
they mean about the state that @code{mysql} is in:
@cindex prompts, meanings
-@multitable @columnfractions .10 .9
+@multitable @columnfractions .10 .80
@item @strong{Prompt} @tab @strong{Meaning}
@item @code{mysql>} @tab Ready for new command.
@item @code{@ @ @ @ ->} @tab Waiting for next line of multiple-line command.
@@ -12449,7 +11769,7 @@ mysql> SELECT USER()
If this happens to you (you think you've entered a statement but the only
response is a @code{->} prompt), most likely @code{mysql} is waiting for the
semicolon. If you don't notice what the prompt is telling you, you might sit
-there for a while before realizing what you need to do. Enter a semicolon to
+there for a while before realising what you need to do. Enter a semicolon to
complete the statement, and @code{mysql} will execute it:
@example
@@ -12478,7 +11798,7 @@ mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
">
@end example
-If you enter this @code{SELECT} statement, then hit RETURN and wait for the
+If you enter this @code{SELECT} statement, then press Enter and wait for the
result, nothing will happen. Instead of wondering why this
query takes so long, notice the clue provided by the @code{">} prompt. It
tells you that @code{mysql} expects to see the rest of an unterminated
@@ -12502,7 +11822,7 @@ is ready for a new command.
It's important to know what the @code{'>} and @code{">} prompts signify,
because if you mistakenly enter an unterminated string, any further lines you
-type will appear to be ignored by @code{mysql} --- including a line
+type will appear to be ignored by @code{mysql}@-including a line
containing @code{QUIT}! This can be quite confusing, especially if you
don't know that you need to supply the terminating quote before you can
cancel the current command.
@@ -12548,11 +11868,11 @@ to think of real-world situations in which a similar type of database might
be used. For example, a database like this could be used by a farmer to keep
track of livestock, or by a veterinarian to keep track of patient records.
A menagerie distribution containing some of the queries and sample data used
-in the following sections can be obtained from the MySQL Web site.
-It's available in either
-@uref{http://www.mysql.com/Downloads/Contrib/Examples/menagerie.tar.gz,compressed @code{tar} format}
-or
-@uref{http://www.mysql.com/Downloads/Contrib/Examples/menagerie.zip,Zip format}.
+in the following sections can be obtained from the MySQL web site.
+It's available in either compressed @code{tar} format
+(@uref{http://www.mysql.com/Downloads/Contrib/Examples/menagerie.tar.gz})
+or Zip format
+(@uref{http://www.mysql.com/Downloads/Contrib/Examples/menagerie.zip}).
Use the @code{SHOW} statement to find out what databases currently exist
on the server:
@@ -12574,6 +11894,9 @@ The list of databases is probably different on your machine, but the
privileges. The @code{test} database is often provided as a workspace for
users to try things out.
+Note that you may not see all databases if you don't have the
+@code{SHOW DATABASES} privilege. @xref{GRANT}.
+
If the @code{test} database exists, try to access it:
@example
@@ -12615,7 +11938,7 @@ yourself:
mysql> CREATE DATABASE menagerie;
@end example
-Under Unix, database names are case sensitive (unlike SQL keywords), so you
+Under Unix, database names are case-sensitive (unlike SQL keywords), so you
must always refer to your database as @code{menagerie}, not as
@code{Menagerie}, @code{MENAGERIE}, or some other variant. This is also true
for table names. (Under Windows, this restriction does not apply, although
@@ -12633,7 +11956,7 @@ Database changed
Your database needs to be created only once, but you must select it for use
each time you begin a @code{mysql} session. You can do this by issuing a
@code{USE} statement as shown above. Alternatively, you can select the
-database on the command line when you invoke @code{mysql}. Just specify its
+database on the command-line when you invoke @code{mysql}. Just specify its
name after any connection parameters that you might need to provide. For
example:
@@ -12643,10 +11966,10 @@ Enter password: ********
@end example
Note that @code{menagerie} is not your password on the command just shown.
-If you want to supply your password on the command line after the @code{-p}
+If you want to supply your password on the command-line after the @code{-p}
option, you must do so with no intervening space (for example, as
@code{-pmypassword}, not as @code{-p mypassword}). However, putting your
-password on the command line is not recommended, because doing so exposes it
+password on the command-line is not recommended, because doing so exposes it
to snooping by other users logged in on your machine.
@@ -12766,11 +12089,11 @@ the columns in your table or what types they are.
After creating your table, you need to populate it. The @code{LOAD DATA} and
@code{INSERT} statements are useful for this.
-Suppose your pet records can be described as shown below.
+Suppose your pet records can be described as shown here.
(Observe that MySQL expects dates in @code{YYYY-MM-DD} format;
-this may be different than what you are used to.)
+this may be different from what you are used to.)
-@multitable @columnfractions .16 .16 .16 .16 .16 .16
+@multitable @columnfractions .10 .10 .10 .05 .15 .15
@item @strong{name} @tab @strong{owner} @tab @strong{species} @tab @strong{sex} @tab @strong{birth} @tab @strong{death}
@item Fluffy @tab Harold @tab cat @tab f @tab 1993-02-04 @tab
@item Claws @tab Gwen @tab cat @tab m @tab 1994-03-17 @tab
@@ -12794,7 +12117,8 @@ use @code{NULL} values. To represent these in your text file, use
@code{\N}. For example, the record for Whistler the bird would look like
this (where the whitespace between values is a single tab character):
-@multitable @columnfractions .15 .15 .15 .15 .25 .15
+@multitable @columnfractions .10 .10 .10 .05 .15 .15
+@item @strong{name} @tab @strong{owner} @tab @strong{species} @tab @strong{sex} @tab @strong{birth} @tab @strong{death}
@item @code{Whistler} @tab @code{Gwen} @tab @code{bird} @tab @code{\N} @tab @code{1997-12-09} @tab @code{\N}
@end multitable
@@ -12891,7 +12215,7 @@ mysql> SELECT * FROM pet;
This form of @code{SELECT} is useful if you want to review your entire table,
for instance, after you've just loaded it with your initial dataset. As it
-happens, the output just shown reveals an error in your data file: Bowser
+happens, the output just shown reveals an error in your datafile: Bowser
appears to have been born after he died! Consulting your original pedigree
papers, you find that the correct birth year is 1989, not 1998.
@@ -12947,7 +12271,7 @@ mysql> SELECT * FROM pet WHERE name = "Bowser";
The output confirms that the year is correctly recorded now as 1989, not 1998.
-String comparisons are normally case insensitive, so you can specify the
+String comparisons are normally case-insensitive, so you can specify the
name as @code{"bowser"}, @code{"BOWSER"}, etc. The query result will be
the same.
@@ -13054,7 +12378,7 @@ mysql> SELECT owner FROM pet;
@findex DISTINCT
However, notice that the query simply retrieves the @code{owner} field from
-each record, and some of them appear more than once. To minimize the output,
+each record, and some of them appear more than once. To minimise the output,
retrieve each unique output record just once by adding the keyword
@code{DISTINCT}:
@@ -13121,6 +12445,12 @@ mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
@end example
+On character type columns, sorting@-like all other comparison
+operations@-is normally performed in a case-insensitive fashion.
+This means that the order will be undefined for columns that are identical
+except for their case. You can force a case-sensitive sort by using the
+BINARY cast: @code{ORDER BY BINARY(field)}.
+
To sort in reverse order, add the @code{DESC} (descending) keyword to the
name of the column you are sorting by:
@@ -13265,7 +12595,7 @@ mysql> SELECT name, birth, CURRENT_DATE,
@end example
A similar query can be used to determine age at death for animals that have
-died. You determine which animals these are by checking whether or not the
+died. You determine which animals these are by checking whether the
@code{death} value is @code{NULL}. Then, for those with non-@code{NULL}
values, compute the difference between the @code{death} and @code{birth}
values:
@@ -13282,7 +12612,7 @@ mysql> SELECT name, birth, death,
+--------+------------+------------+------+
@end example
-The query uses @code{death IS NOT NULL} rather than @code{death != NULL}
+The query uses @code{death IS NOT NULL} rather than @code{death <> NULL}
because @code{NULL} is a special value. This is explained later.
@xref{Working with NULL, , Working with @code{NULL}}.
@@ -13367,12 +12697,12 @@ The @code{NULL} value can be surprising until you get used to it.
Conceptually, @code{NULL} means missing value or unknown value and it
is treated somewhat differently than other values. To test for @code{NULL},
you cannot use the arithmetic comparison operators such as @code{=}, @code{<},
-or @code{!=}. To demonstrate this for yourself, try the following query:
+or @code{<>}. To demonstrate this for yourself, try the following query:
@example
-mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
+mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
-| 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL |
+| 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+
@@ -13390,12 +12720,18 @@ mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
@end example
+Note that two @code{NULL} are compared as equal is when you do an
+@code{GROUP BY}.
+
In MySQL, 0 or @code{NULL} means false and anything else means true.
The default truth value from a boolean operation is 1.
+When doing an @code{ORDER BY}, @code{NULL} values are always sorted first,
+even if you are using @code{DESC}.
+
This special treatment of @code{NULL} is why, in the previous section, it
was necessary to determine which animals are no longer alive using
-@code{death IS NOT NULL} instead of @code{death != NULL}.
+@code{death IS NOT NULL} instead of @code{death <> NULL}.
@node Pattern matching, Counting rows, Working with NULL, Retrieving data
@@ -13411,9 +12747,9 @@ by Unix utilities such as @code{vi}, @code{grep}, and @code{sed}.
SQL pattern matching allows you to use @samp{_} to match any single
character and @samp{%} to match an arbitrary number of characters (including
-zero characters). In MySQL, SQL patterns are case insensitive by
-default. Some examples are shown below. Note that you do not use @code{=}
-or @code{!=} when you use SQL patterns; use the @code{LIKE} or @code{NOT
+zero characters). In MySQL, SQL patterns are case-insensitive by
+default. Some examples are shown here. Note that you do not use @code{=}
+or @code{<>} when you use SQL patterns; use the @code{LIKE} or @code{NOT
LIKE} comparison operators instead.
To find names beginning with @samp{b}:
@@ -13490,12 +12826,6 @@ example, @samp{x*} matches any number of @samp{x} characters,
number of anything.
@item
-Regular expressions are case sensitive, but you can use a character class to
-match both lettercases if you wish. For example, @samp{[aA]} matches
-lowercase or uppercase @samp{a} and @samp{[a-zA-Z]} matches any letter in
-either case.
-
-@item
The pattern matches if it occurs anywhere in the value being tested.
(SQL patterns match only if they match the entire value.)
@@ -13506,7 +12836,7 @@ pattern.
@end itemize
To demonstrate how extended regular expressions work, the @code{LIKE} queries
-shown above are rewritten below to use @code{REGEXP}.
+shown previously are rewritten here to use @code{REGEXP}.
To find names beginning with @samp{b}, use @samp{^} to match the beginning of
the name:
@@ -13521,8 +12851,8 @@ mysql> SELECT * FROM pet WHERE name REGEXP "^b";
+--------+--------+---------+------+------------+------------+
@end example
-Prior to MySQL Version 3.23.4, @code{REGEXP} is case sensitive,
-and the previous query will return no rows. To match either lowercase or
+Prior to MySQL Version 3.23.4, @code{REGEXP} is case-sensitive,
+and the previous query will return no rows. To match either lowercase or
uppercase @samp{b}, use this query instead:
@example
@@ -13530,7 +12860,7 @@ mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
@end example
From MySQL 3.23.4 on, to force a @code{REGEXP} comparison to
-be case sensitive, use the @code{BINARY} keyword to make one of the
+be case-sensitive, use the @code{BINARY} keyword to make one of the
strings a binary string. This query will match only lowercase @samp{b}
at the beginning of a name:
@@ -13565,7 +12895,7 @@ mysql> SELECT * FROM pet WHERE name REGEXP "w";
@end example
Because a regular expression pattern matches if it occurs anywhere in the
-value, it is not necessary in the previous query to put a wild card on either
+value, it is not necessary in the previous query to put a wildcard on either
side of the pattern to get it to match the entire value like it would be if
you used a SQL pattern.
@@ -13647,7 +12977,7 @@ ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
with no GROUP columns is illegal if there is no GROUP BY clause
@end example
-@code{COUNT()} and @code{GROUP BY} are useful for characterizing your
+@code{COUNT()} and @code{GROUP BY} are useful for characterising your
data in various ways. The following examples show different ways to
perform animal census operations.
@@ -13759,7 +13089,7 @@ A date so you know when the event occurred.
A field to describe the event.
@item
-An event type field, if you want to be able to categorize events.
+An event type field, if you want to be able to categorise events.
@end itemize
Given these considerations, the @code{CREATE TABLE} statement for the
@@ -13773,14 +13103,15 @@ mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
As with the @code{pet} table, it's easiest to load the initial records
by creating a tab-delimited text file containing the information:
-@multitable @columnfractions .15 .15 .15 .55
+@multitable @columnfractions .10 .15 .10 .35
+@item @strong{name} @tab @strong{date} @tab @strong{type} @tab @strong{remark}
@item Fluffy @tab 1995-05-15 @tab litter @tab 4 kittens, 3 female, 1 male
@item Buffy @tab 1993-06-23 @tab litter @tab 5 puppies, 2 female, 3 male
@item Buffy @tab 1994-06-19 @tab litter @tab 3 puppies, 3 female
@item Chirpy @tab 1999-03-21 @tab vet @tab needed beak straightened
@item Slim @tab 1997-08-03 @tab vet @tab broken rib
-@item Bowser @tab 1991-10-12 @tab kennel
-@item Fang @tab 1991-10-12 @tab kennel
+@item Bowser @tab 1991-10-12 @tab kennel @tab
+@item Fang @tab 1991-10-12 @tab kennel @tab
@item Fang @tab 1998-08-28 @tab birthday @tab Gave him a new chew toy
@item Claws @tab 1998-03-17 @tab birthday @tab Gave him a new flea collar
@item Whistler @tab 1998-12-09 @tab birthday @tab First birthday
@@ -13803,7 +13134,9 @@ calculate the age of the mother, you need her birth date. Because that is
stored in the @code{pet} table, you need both tables for the query:
@example
-mysql> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age, remark
+mysql> SELECT pet.name,
+ -> (TO_DAYS(date) - TO_DAYS(birth))/365 AS age,
+ -> remark
-> FROM pet, event
-> WHERE pet.name = event.name AND type = "litter";
+--------+------+-----------------------------+
@@ -13917,8 +13250,8 @@ mysql> DESCRIBE pet;
@end example
@code{Field} indicates the column name, @code{Type} is the data type for
-the column, @code{Null} indicates whether or not the column can contain
-@code{NULL} values, @code{Key} indicates whether or not the column is
+the column, @code{NULL} indicates whether the column can contain
+@code{NULL} values, @code{Key} indicates whether the column is
indexed, and @code{Default} specifies the column's default value.
If you have indexes on a table,
@@ -13939,7 +13272,7 @@ article (item number) for certain traders (dealers). Supposing that each
trader has a single fixed price per article, then (@code{article},
@code{dealer}) is a primary key for the records.
-Start the command line tool @code{mysql} and select a database:
+Start the command-line tool @code{mysql} and select a database:
@example
mysql your-database-name
@@ -13987,7 +13320,8 @@ mysql> SELECT * FROM shop;
* example-user-variables:: Using user variables
* example-Foreign keys:: Using foreign keys
* Searching on two keys:: Searching on Two Keys
-* Calculating days:: Calculating visits per day
+* Calculating days:: Calculating Visits Per Day
+* example-AUTO_INCREMENT:: Using AUTO_INCREMENT
@end menu
@@ -14012,7 +13346,7 @@ SELECT MAX(article) AS article FROM shop
``Find number, dealer, and price of the most expensive article.''
-In ANSI SQL this is easily done with a sub-query:
+In ANSI SQL this is easily done with a subquery:
@example
SELECT article, dealer, price
@@ -14020,7 +13354,7 @@ FROM shop
WHERE price=(SELECT MAX(price) FROM shop)
@end example
-In MySQL (which does not yet have sub-selects), just do it in
+In MySQL (which does not yet have subselects), just do it in
two steps:
@enumerate
@@ -14075,7 +13409,7 @@ GROUP BY article
``For each article, find the dealer(s) with the most expensive price.''
-In ANSI SQL, I'd do it with a sub-query like this:
+In ANSI SQL, I'd do it with a subquery like this:
@example
SELECT article, dealer, price
@@ -14153,9 +13487,8 @@ For example, to find the articles with the highest and lowest price you
can do:
@example
-select @@min_price:=min(price),@@max_price:=max(price) from shop;
-select * from shop where price=@@min_price or price=@@max_price;
-
+mysql> SELECT @@min_price:=MIN(price),@@max_price:=MAX(price) FROM shop;
+mysql> SELECT * FROM shop WHERE price=@@min_price OR price=@@max_price;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
@@ -14171,48 +13504,52 @@ select * from shop where price=@@min_price or price=@@max_price;
@cindex foreign keys
@cindex keys, foreign
-You don't need foreign keys to join 2 tables.
+In MySQL 3.23.44 and up, @code{InnoDB} tables supports checking of
+foreign key constraints. @xref{InnoDB}.
+See also @ref{ANSI diff Foreign Keys}.
-The only thing MySQL doesn't do is @code{CHECK} to make sure that
-the keys you use really exist in the table(s) you're referencing and it
-doesn't automatically delete rows from table with a foreign key
+You don't actually need foreign keys to join 2 tables.
+The only thing MySQL currently doesn't do (in type types other than
+@code{InnoDB}), is @code{CHECK} to make sure that the keys you use
+really exist in the table(s) you're referencing and it
+doesn't automatically delete rows from a table with a foreign key
definition. If you use your keys like normal, it'll work just fine:
@example
-CREATE TABLE persons (
+CREATE TABLE person (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR(60) NOT NULL,
PRIMARY KEY (id)
);
-CREATE TABLE shirts (
+CREATE TABLE shirt (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
- owner SMALLINT UNSIGNED NOT NULL REFERENCES persons,
+ owner SMALLINT UNSIGNED NOT NULL REFERENCES person(id),
PRIMARY KEY (id)
);
-INSERT INTO persons VALUES (NULL, 'Antonio Paz');
+INSERT INTO person VALUES (NULL, 'Antonio Paz');
-INSERT INTO shirts VALUES
+INSERT INTO shirt VALUES
(NULL, 'polo', 'blue', LAST_INSERT_ID()),
(NULL, 'dress', 'white', LAST_INSERT_ID()),
(NULL, 't-shirt', 'blue', LAST_INSERT_ID());
-INSERT INTO persons VALUES (NULL, 'Lilliana Angelovska');
+INSERT INTO person VALUES (NULL, 'Lilliana Angelovska');
-INSERT INTO shirts VALUES
+INSERT INTO shirt VALUES
(NULL, 'dress', 'orange', LAST_INSERT_ID()),
(NULL, 'polo', 'red', LAST_INSERT_ID()),
(NULL, 'dress', 'blue', LAST_INSERT_ID()),
(NULL, 't-shirt', 'white', LAST_INSERT_ID());
-SELECT * FROM persons;
+SELECT * FROM person;
+----+---------------------+
| id | name |
+----+---------------------+
@@ -14220,7 +13557,7 @@ SELECT * FROM persons;
| 2 | Lilliana Angelovska |
+----+---------------------+
-SELECT * FROM shirts;
+SELECT * FROM shirt;
+----+---------+--------+-------+
| id | style | color | owner |
+----+---------+--------+-------+
@@ -14234,7 +13571,7 @@ SELECT * FROM shirts;
+----+---------+--------+-------+
-SELECT s.* FROM persons p, shirts s
+SELECT s.* FROM person p, shirt s
WHERE p.name LIKE 'Lilliana%'
AND s.owner = p.id
AND s.color <> 'white';
@@ -14256,9 +13593,9 @@ SELECT s.* FROM persons p, shirts s
@cindex searching, two keys
@cindex keys, searching on two
-MySQL doesn't yet optimize when you search on two different
-keys combined with @code{OR} (Searching on one key with different @code{OR}
-parts is optimized quite good):
+MySQL doesn't yet optimise when you search on two different
+keys combined with @code{OR} (searching on one key with different @code{OR}
+parts is optimised quite well):
@example
SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1'
@@ -14267,12 +13604,12 @@ OR field2_index = '1'
The reason is that we haven't yet had time to come up with an efficient
way to handle this in the general case. (The @code{AND} handling is,
-in comparison, now completely general and works very well).
+in comparison, now completely general and works very well.)
For the moment you can solve this very efficiently by using a
-@code{TEMPORARY} table. This type of optimization is also very good if
+@code{TEMPORARY} table. This type of optimisation is also very good if
you are using very complicated queries where the SQL server does the
-optimizations in the wrong order.
+optimisations in the wrong order.
@example
CREATE TEMPORARY TABLE tmp
@@ -14283,11 +13620,11 @@ SELECT * from tmp;
DROP TABLE tmp;
@end example
-The above way to solve this query is in effect an @code{UNION} of two queries.
-
+The above way to solve this query is in effect a @code{UNION} of two queries.
+@xref{UNION}.
-@node Calculating days, , Searching on two keys, Examples
-@subsection Calculating visits per day
+@node Calculating days, example-AUTO_INCREMENT, Searching on two keys, Examples
+@subsection Calculating Visits Per Day
@findex BIT_OR
@findex BIT_COUNT
@@ -14298,10 +13635,12 @@ The following shows an idea of how you can use the bit group functions
to calculate the number of days per month a user has visited a web page.
@example
-CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL, day INT(2) UNSIGNED ZEROFILL);
-INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),(2000,2,23),(2000,2,23);
-
-SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1 GROUP BY year,month;
+CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL,
+ day INT(2) UNSIGNED ZEROFILL);
+INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),
+ (2000,2,23),(2000,2,23);
+SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1
+ GROUP BY year,month;
Which returns:
@@ -14317,6 +13656,78 @@ The above calculates how many different days was used for a given
year/month combination, with automatic removal of duplicate entries.
+@node example-AUTO_INCREMENT, , Calculating days, Examples
+@subsection Using @code{AUTO_INCREMENT}
+
+@cindex AUTO_INCREMENT
+The @code{AUTO_INCREMENT} attribute can be used to generate an unique
+identity for new rows:
+
+@example
+CREATE TABLE animals (
+ id MEDIUMINT NOT NULL AUTO_INCREMENT,
+ name CHAR(30) NOT NULL,
+ PRIMARY KEY (id)
+ );
+INSERT INTO animals (name) VALUES ("dog"),("cat"),("penguin"),
+ ("lax"),("whale");
+SELECT * FROM animals;
+
+Which returns:
+
++----+---------+
+| id | name |
++----+---------+
+| 1 | dog |
+| 2 | cat |
+| 3 | penguin |
+| 4 | lax |
+| 5 | whale |
++----+---------+
+@end example
+
+You can retrieve the used @code{AUTO_INCREMENT} key with the
+@code{LAST_INSERT_ID()} SQL function or the @code{mysql_insert_id()} API
+function.
+Note: for a multi-row insert,
+@code{LAST_INSERT_ID()}/@code{mysql_insert_id()} will actually return the
+@code{AUTO_INCREMENT} key from the @strong{first} inserted row. This allows
+multi-row inserts to be reproduced on other servers.
+
+For MyISAM and BDB tables you can specify @code{AUTO_INCREMENT} on
+secondary column in a multi-column key. In this case the generated
+value for the autoincrement column is calculated as
+@code{MAX(auto_increment_column)+1) WHERE prefix=given-prefix}. This is
+useful when you want to put data into ordered groups.
+
+@example
+CREATE TABLE animals (
+ grp ENUM('fish','mammal','bird') NOT NULL,
+ id MEDIUMINT NOT NULL AUTO_INCREMENT,
+ name CHAR(30) NOT NULL,
+ PRIMARY KEY (grp,id)
+ );
+INSERT INTO animals (grp,name) VALUES("mammal","dog"),("mammal","cat"),
+ ("bird","penguin"),("fish","lax"),("mammal","whale");
+SELECT * FROM animals ORDER BY grp,id;
+
+Which returns:
+
++--------+----+---------+
+| grp | id | name |
++--------+----+---------+
+| fish | 1 | lax |
+| mammal | 1 | dog |
+| mammal | 2 | cat |
+| mammal | 3 | whale |
+| bird | 1 | penguin |
++--------+----+---------+
+@end example
+
+Note that in this case, the @code{AUTO_INCREMENT} value will be reused if you
+delete the row with the biggest @code{AUTO_INCREMENT} value in any group.
+
+
@node Batch mode, Twin, Examples, Tutorial
@section Using @code{mysql} in Batch Mode
@@ -14335,7 +13746,14 @@ tell @code{mysql} to read its input from the file:
shell> mysql < batch-file
@end example
-If you need to specify connection parameters on the command line, the
+If you are running @code{mysql} under windows and have some special
+characters in the file that causes problems, you can do:
+
+@example
+dos> mysql -e "source batch-file"
+@end example
+
+If you need to specify connection parameters on the command-line, the
command might look like this:
@example
@@ -14346,6 +13764,9 @@ Enter password: ********
When you use @code{mysql} this way, you are creating a script file, then
executing the script.
+If you want the script to continue even if you have errors, you should
+use the @code{--force} command-line option.
+
Why use a script? Here are a few reasons:
@itemize @bullet
@@ -14419,6 +13840,12 @@ If you want to get the interactive output format in batch mode, use
@code{mysql -t}. To echo to the output the commands that are executed, use
@code{mysql -vvv}.
+You can also use scripts in the @code{mysql} command-line prompt by
+using the @code{source} command:
+
+@example
+mysql> source filename;
+@end example
@node Twin, Apache, Batch mode, Tutorial
@section Queries from Twin Project
@@ -14442,12 +13869,9 @@ history collection. In addition, data are collected on medical and
environmental risk factors.
More information about Twin studies can be found at:
+@uref{http://www.imm.ki.se/TWIN/TWINUKW.HTM}
-@example
-@url{http://www.imm.ki.se/TWIN/TWINUKW.HTM}
-@end example
-
-The latter part of the project is administered with a Web interface
+The latter part of the project is administered with a web interface
written using Perl and MySQL.
Each night all data from the interviews are moved into a MySQL
@@ -14466,85 +13890,96 @@ The following query is used to determine who goes into the second part of the
project:
@example
-select
- concat(p1.id, p1.tvab) + 0 as tvid,
- concat(p1.christian_name, " ", p1.surname) as Name,
- p1.postal_code as Code,
- p1.city as City,
- pg.abrev as Area,
- if(td.participation = "Aborted", "A", " ") as A,
- p1.dead as dead1,
- l.event as event1,
- td.suspect as tsuspect1,
- id.suspect as isuspect1,
- td.severe as tsevere1,
- id.severe as isevere1,
- p2.dead as dead2,
- l2.event as event2,
- h2.nurse as nurse2,
- h2.doctor as doctor2,
- td2.suspect as tsuspect2,
- id2.suspect as isuspect2,
- td2.severe as tsevere2,
- id2.severe as isevere2,
+SELECT
+ CONCAT(p1.id, p1.tvab) + 0 AS tvid,
+ CONCAT(p1.christian_name, " ", p1.surname) AS Name,
+ p1.postal_code AS Code,
+ p1.city AS City,
+ pg.abrev AS Area,
+ IF(td.participation = "Aborted", "A", " ") AS A,
+ p1.dead AS dead1,
+ l.event AS event1,
+ td.suspect AS tsuspect1,
+ id.suspect AS isuspect1,
+ td.severe AS tsevere1,
+ id.severe AS isevere1,
+ p2.dead AS dead2,
+ l2.event AS event2,
+ h2.nurse AS nurse2,
+ h2.doctor AS doctor2,
+ td2.suspect AS tsuspect2,
+ id2.suspect AS isuspect2,
+ td2.severe AS tsevere2,
+ id2.severe AS isevere2,
l.finish_date
-from
- twin_project as tp
+FROM
+ twin_project AS tp
/* For Twin 1 */
- left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab
- left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab
- left join harmony as h on tp.id = h.id and tp.tvab = h.tvab
- left join lentus as l on tp.id = l.id and tp.tvab = l.tvab
+ LEFT JOIN twin_data AS td ON tp.id = td.id
+ AND tp.tvab = td.tvab
+ LEFT JOIN informant_data AS id ON tp.id = id.id
+ AND tp.tvab = id.tvab
+ LEFT JOIN harmony AS h ON tp.id = h.id
+ AND tp.tvab = h.tvab
+ LEFT JOIN lentus AS l ON tp.id = l.id
+ AND tp.tvab = l.tvab
/* For Twin 2 */
- left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab
- left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab
- left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab
- left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab,
- person_data as p1,
- person_data as p2,
- postal_groups as pg
-where
+ LEFT JOIN twin_data AS td2 ON p2.id = td2.id
+ AND p2.tvab = td2.tvab
+ LEFT JOIN informant_data AS id2 ON p2.id = id2.id
+ AND p2.tvab = id2.tvab
+ LEFT JOIN harmony AS h2 ON p2.id = h2.id
+ AND p2.tvab = h2.tvab
+ LEFT JOIN lentus AS l2 ON p2.id = l2.id
+ AND p2.tvab = l2.tvab,
+ person_data AS p1,
+ person_data AS p2,
+ postal_groups AS pg
+WHERE
/* p1 gets main twin and p2 gets his/her twin. */
/* ptvab is a field inverted from tvab */
- p1.id = tp.id and p1.tvab = tp.tvab and
- p2.id = p1.id and p2.ptvab = p1.tvab and
+ p1.id = tp.id AND p1.tvab = tp.tvab AND
+ p2.id = p1.id AND p2.ptvab = p1.tvab AND
/* Just the sceening survey */
- tp.survey_no = 5 and
+ tp.survey_no = 5 AND
/* Skip if partner died before 65 but allow emigration (dead=9) */
- (p2.dead = 0 or p2.dead = 9 or
- (p2.dead = 1 and
- (p2.death_date = 0 or
- (((to_days(p2.death_date) - to_days(p2.birthday)) / 365)
+ (p2.dead = 0 OR p2.dead = 9 OR
+ (p2.dead = 1 AND
+ (p2.death_date = 0 OR
+ (((TO_DAYS(p2.death_date) - TO_DAYS(p2.birthday)) / 365)
>= 65))))
- and
+ AND
(
/* Twin is suspect */
- (td.future_contact = 'Yes' and td.suspect = 2) or
+ (td.future_contact = 'Yes' AND td.suspect = 2) OR
/* Twin is suspect - Informant is Blessed */
- (td.future_contact = 'Yes' and td.suspect = 1 and id.suspect = 1) or
+ (td.future_contact = 'Yes' AND td.suspect = 1
+ AND id.suspect = 1) OR
/* No twin - Informant is Blessed */
- (ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = 'Yes') or
+ (ISNULL(td.suspect) AND id.suspect = 1
+ AND id.future_contact = 'Yes') OR
/* Twin broken off - Informant is Blessed */
(td.participation = 'Aborted'
- and id.suspect = 1 and id.future_contact = 'Yes') or
+ AND id.suspect = 1 AND id.future_contact = 'Yes') OR
/* Twin broken off - No inform - Have partner */
- (td.participation = 'Aborted' and ISNULL(id.suspect) and p2.dead = 0))
- and
+ (td.participation = 'Aborted' AND ISNULL(id.suspect)
+ AND p2.dead = 0))
+ AND
l.event = 'Finished'
/* Get at area code */
- and substring(p1.postal_code, 1, 2) = pg.code
+ AND SUBSTRING(p1.postal_code, 1, 2) = pg.code
/* Not already distributed */
- and (h.nurse is NULL or h.nurse=00 or h.doctor=00)
+ AND (h.nurse IS NULL OR h.nurse=00 OR h.doctor=00)
/* Has not refused or been aborted */
- and not (h.status = 'Refused' or h.status = 'Aborted'
- or h.status = 'Died' or h.status = 'Other')
-order by
+ AND NOT (h.status = 'Refused' OR h.status = 'Aborted'
+ OR h.status = 'Died' OR h.status = 'Other')
+ORDER BY
tvid;
@end example
Some explanations:
@table @asis
-@item @code{concat(p1.id, p1.tvab) + 0 as tvid}
+@item @code{CONCAT(p1.id, p1.tvab) + 0 AS tvid}
We want to sort on the concatenated @code{id} and @code{tvab} in
numerical order. Adding @code{0} to the result causes MySQL to
treat the result as a number.
@@ -14555,7 +13990,7 @@ This identifies a twin in a pair. It has a value of @code{1} or @code{2}.
@item column @code{ptvab}
This is an inverse of @code{tvab}. When @code{tvab} is @code{1} this is
@code{2}, and vice versa. It exists to save typing and to make it easier for
-MySQL to optimize the query.
+MySQL to optimise the query.
@end table
This query demonstrates, among other things, how to do lookups on a
@@ -14571,7 +14006,7 @@ On our production machine (A 200MHz UltraSPARC), this query returns
about 150-200 rows and takes less than one second.
The current number of records in the tables used above:
-@multitable @columnfractions .3 .5
+@multitable @columnfractions .25 .10
@item @strong{Table} @tab @strong{Rows}
@item @code{person_data} @tab 71074
@item @code{lentus} @tab 5291
@@ -14587,29 +14022,29 @@ The current number of records in the tables used above:
@subsection Show a Table on Twin Pair Status
Each interview ends with a status code called @code{event}. The query
-shown below is used to display a table over all twin pairs combined by
+shown here is used to display a table over all twin pairs combined by
event. This indicates in how many pairs both twins are finished, in how many
pairs one twin is finished and the other refused, and so on.
@example
-select
+SELECT
t1.event,
t2.event,
- count(*)
-from
- lentus as t1,
- lentus as t2,
- twin_project as tp
-where
+ COUNT(*)
+FROM
+ lentus AS t1,
+ lentus AS t2,
+ twin_project AS tp
+WHERE
/* We are looking at one pair at a time */
t1.id = tp.id
- and t1.tvab=tp.tvab
- and t1.id = t2.id
+ AND t1.tvab=tp.tvab
+ AND t1.id = t2.id
/* Just the sceening survey */
- and tp.survey_no = 5
+ AND tp.survey_no = 5
/* This makes each pair only appear once */
- and t1.tvab='1' and t2.tvab='2'
-group by
+ AND t1.tvab='1' AND t2.tvab='2'
+GROUP BY
t1.event, t2.event;
@end example
@@ -14620,9 +14055,9 @@ group by
@cindex Apache
-The Contrib section includes programs that let you authenticate your
-users from a MySQL database and also let you log your log files
-into a MySQL table. @xref{Contrib}.
+There are programs that let you authenticate your users from a MySQL
+database and also let you log your log files into a MySQL table.
+@xref{Portals}.
You can change the Apache logging format to be easily readable by
MySQL by putting the following into the Apache configuration file:
@@ -14643,8 +14078,8 @@ FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
-@node MySQL Database Administration, MySQL Optimization, Tutorial, Top
-@chapter MySQL Database Administration
+@node MySQL Database Administration, MySQL Optimisation, Tutorial, Top
+@chapter Database Administration
@menu
* Configuring MySQL:: Configuring MySQL
@@ -14652,7 +14087,7 @@ FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
* User Account Management:: MySQL User Account Management
* Disaster Prevention:: Disaster Prevention and Recovery
* Database Administration:: Database Administration Language Reference
-* Localization:: MySQL Localization and International Usage
+* Localisation:: MySQL Localisation and International Usage
* Server-Side Scripts:: MySQL Server-Side Scripts and Utilities
* Client-Side Scripts:: MySQL Client-Side Scripts and Utilities
* Log Files:: The MySQL Log Files
@@ -14663,22 +14098,35 @@ FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
@node Configuring MySQL, Privilege system, MySQL Database Administration, MySQL Database Administration
@section Configuring MySQL
+@c FIX: add section intro
+
@menu
-* Command-line options:: mysqld Command-line Options
-* Option files:: my.cnf Option Files
+* Command-line options:: @code{mysqld} Command-line Options
+* Option files:: @file{my.cnf} Option Files
* Installing many servers:: Installing Many Servers on the Same Machine
* Multiple servers:: Running Multiple MySQL Servers on the Same Machine
@end menu
@node Command-line options, Option files, Configuring MySQL, Configuring MySQL
-@subsection mysqld Command-line Options
+@subsection @code{mysqld} Command-line Options
@findex command-line options
@cindex options, command-line
@cindex mysqld options
+In most cases you should manage mysqld options through option files.
+@xref{Option files}.
+
+@code{mysqld} and @code{mysqld.server} reads options from the
+@code{mysqld} and @code{server} groups. @code{mysqld_safe} read options
+from the @code{mysqld}, @code{server}, @code{mysqld_safe} and
+@code{safe_mysqld} groups. An embedded MySQL server usually reads
+options from the @code{server}, @code{embedded} and
+@code{xxxxx_SERVER}, where @code{xxxxx} is the name of the application.
+
+
@code{mysqld} accepts the following command-line options:
@table @code
@@ -14686,7 +14134,7 @@ FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
Use ANSI SQL syntax instead of MySQL syntax. @xref{ANSI mode}.
@item -b, --basedir=path
-Path to installation directory. All paths are usually resolved relative to
+Path to installation directory. All paths are usually resolved relative to
this.
@item --big-tables
@@ -14703,36 +14151,42 @@ IP address to bind to.
Directory where character sets are. @xref{Character sets}.
@item --chroot=path
-Chroot @code{mysqld} daemon during startup. Recommended security measure. It will
-somewhat limit @code{LOAD DATA INFILE} and @code{SELECT ... INTO OUTFILE}
-though.
+Put @code{mysqld} daemon in chroot environment at startup. Recommended
+security measure. It somewhat limits @code{LOAD DATA INFILE} and
+@code{SELECT ... INTO OUTFILE} though.
@item --core-file
Write a core file if @code{mysqld} dies. For some systems you must also
-specify @code{--core-file-size} to @code{safe_mysqld}. @xref{safe_mysqld, ,
-@code{safe_mysqld}}.
+specify @code{--core-file-size} to @code{safe_mysqld}.
+@xref{safe_mysqld, ,@code{safe_mysqld}}.
+Note that on some systems, like Solaris, you will
+not get a core file if you are also using the @code{--user} option.
@item -h, --datadir=path
Path to the database root.
+@item --debug[...]=
+If MySQL is configured with @code{--with-debug}, you can use this
+option to get a trace file of what @code{mysqld} is doing.
+@xref{Making trace files}.
+
@item --default-character-set=charset
Set the default character set. @xref{Character sets}.
@item --default-table-type=type
Set the default table type for tables. @xref{Table types}.
-@item --debug[...]=
-If MySQL is configured with @code{--with-debug}, you can use this
-option to get a trace file of what @code{mysqld} is doing.
-@xref{Making trace files}.
-
@item --delay-key-write-for-all-tables
Don't flush key buffers between writes for any @code{MyISAM} table.
@xref{Server parameters}.
-@item --enable-locking
-Enable system locking. Note that if you use this option on a system
-which a not fully working lockd() (as on Linux) you will easily get
+@item --des-key-file=filename
+Read the default keys used by @code{DES_ENCRYPT()} and @code{DES_DECRYPT()}
+from this file.
+
+@item --enable-external-locking (was --enable-locking)
+Enable system locking. Note that if you use this option on a system on
+which @code{lockd} does not fully work (as on Linux), you will easily get
mysqld to deadlock.
@item --enable-named-pipe
@@ -14740,7 +14194,7 @@ Enable support for named pipes (only on NT/Win2000/XP).
@item -T, --exit-info
This is a bit mask of different flags one can use for debugging the
-mysqld server; One should not use this option if one doesn't know
+mysqld server; one should not use this option if one doesn't know
exactly what it does!
@item --flush
@@ -14780,10 +14234,10 @@ to the slow query log.
@item --low-priority-updates
Table-modifying operations (@code{INSERT}/@code{DELETE}/@code{UPDATE})
-will have lower priority than selects. It can also be done via
-@code{@{INSERT | REPLACE | UPDATE | DELETE@} LOW_PRIORITY ...} to lower
+will have lower priority than selects. It can also be done via
+@code{@{INSERT | REPLACE | UPDATE | DELETE@} LOW_PRIORITY ...} to lower
the priority of only one query, or by
-@code{SET OPTION SQL_LOW_PRIORITY_UPDATES=1} to change the priority in one
+@code{SET LOW_PRIORITY_UPDATES=1} to change the priority in one
thread. @xref{Table locking}.
@item --memlock
@@ -14792,25 +14246,27 @@ system supports the @code{mlockall()} system call (like Solaris). This
may help if you have a problem where the operating system is causing
@code{mysqld} to swap on disk.
-@item --myisam-recover [=option[,option...]]] where option is any combination
+@item --myisam-recover [=option[,option...]]]
+Option is any combination
of @code{DEFAULT}, @code{BACKUP}, @code{FORCE} or @code{QUICK}. You can
-also set this explicitely to @code{""} if you want to disable this
+also set this explicitly to @code{""} if you want to disable this
option. If this option is used, @code{mysqld} will on open check if the
-table is marked as crashed or if if the table wasn't closed properly.
+table is marked as crashed or if the table wasn't closed properly.
(The last option only works if you are running with
-@code{--skip-locking}). If this is the case @code{mysqld} will run
+@code{--skip-external-locking}.) If this is the case @code{mysqld} will run
check on the table. If the table was corrupted, @code{mysqld} will
attempt to repair it.
The following options affects how the repair works.
-@multitable @columnfractions .3 .7
-@item DEFAULT @tab The same as not giving any option to
+@multitable @columnfractions .15 .7
+@item @strong{Option} @tab @strong{Description}
+@item DEFAULT @tab The same as not giving any option to
@code{--myisam-recover}.
-@item BACKUP @tab If the data table was changed during recover, save a
- backup of the @file{table_name.MYD} data file as
+@item BACKUP @tab If the data table was changed during recover, save a
+ backup of the @file{table_name.MYD} datafile as
@file{table_name-datetime.BAK}.
-@item FORCE @tab Run recover even if we will loose more than one row
+@item FORCE @tab Run recover even if we will lose more than one row
from the .MYD file.
@item QUICK @tab Don't check the rows in the table if there isn't any
delete blocks.
@@ -14820,7 +14276,7 @@ Before a table is automatically repaired, MySQL will add a note
about this in the error log. If you want to be able to recover from most
things without user intervention, you should use the options
@code{BACKUP,FORCE}. This will force a repair of a table even if some rows
-would be deleted, but it will keep the old data file as a backup so that
+would be deleted, but it will keep the old datafile as a backup so that
you can later examine what happened.
@item --pid-file=path
@@ -14840,13 +14296,29 @@ Only use one thread (for debugging under Linux). @xref{Debugging server}.
Give a variable a value. @code{--help} lists variables. You can find a full
description for all variables in the @code{SHOW VARIABLES} section in this
manual. @xref{SHOW VARIABLES}. The tuning server parameters section includes
-information of how to optimize these. @xref{Server parameters}.
+information of how to optimise these. @xref{Server parameters}.
+
+In MySQL 4.0.2 one can set a variable directly with
+@code{--variable-name=option} and @code{set-variable} is not anymore needed
+in option files.
+
+If you want to restrict the maximum value a startup option can be set to
+with @code{SET}, you can define this by using the
+@code{--maximum-variable-name} command line option. @xref{SET OPTION}.
+
+Note that when setting a variable to a value, MySQL may automaticly
+correct it to stay within a given range and also adjusts the value a
+little to fix for the used algorithm.
@item --safe-mode
-Skip some optimize stages. Implies @code{--skip-delay-key-write}.
+Skip some optimise stages. Implies @code{--skip-delay-key-write}.
@item --safe-show-database
-Don't show databases for which the user doesn't have any privileges.
+With this option, the @code{SHOW DATABASES} command returns only those
+databases for which the user has some kind of privilege.
+From version 4.0.2 this option is deprecated and doesn't do anything
+(the option is enabled by default) as we now have the
+@code{SHOW DATABASES} privilege. @xref{GRANT}.
@item --safe-user-create
If this is enabled, a user can't create new users with the GRANT
@@ -14856,7 +14328,7 @@ command, if the user doesn't have @code{INSERT} privilege to the
@item --skip-concurrent-insert
Turn off the ability to select and insert at the same time on @code{MyISAM}
tables. (This is only to be used if you think you have found a bug in this
-feature).
+feature.)
@item --skip-delay-key-write
Ignore the @code{delay_key_write} option for all tables.
@@ -14864,7 +14336,7 @@ Ignore the @code{delay_key_write} option for all tables.
@item --skip-grant-tables
This option causes the server not to use the privilege system at all. This
-gives everyone @emph{full access} to all databases! (You can tell a running
+gives everyone @strong{full access} to all databases! (You can tell a running
server to start using the grant tables again by executing @code{mysqladmin
flush-privileges} or @code{mysqladmin reload}.)
@@ -14872,7 +14344,7 @@ flush-privileges} or @code{mysqladmin reload}.)
Never use host name cache for faster name-ip resolution, but query DNS server
on every connect instead. @xref{DNS}.
-@item --skip-locking
+@item --skip-external-locking (was --skip-locking)
Don't use system locking. To use @code{isamchk} or @code{myisamchk} you must
shut down the server. @xref{Stability}. Note that in MySQL Version
3.23 you can use @code{REPAIR} and @code{CHECK} to repair/check @code{MyISAM}
@@ -14883,8 +14355,8 @@ Hostnames are not resolved. All @code{Host} column values in the grant tables
must be IP numbers or @code{localhost}. @xref{DNS}.
@item --skip-networking
-Don't listen for TCP/IP connections at all. All interaction with
-@code{mysqld} must be made via Unix sockets. This option is highly
+Don't listen for TCP/IP connections at all. All interaction with
+@code{mysqld} must be made via Unix sockets. This option is highly
recommended for systems where only local requests are allowed. @xref{DNS}.
@item --skip-new
@@ -14902,12 +14374,15 @@ freeing. As this checking is very slow, you can avoid this, when you don't
need memory checking, by using this option.
@item --skip-show-database
-Don't allow 'SHOW DATABASE' commands, unless the user has @strong{process}
-privilege.
+Don't allow @code{SHOW DATABASES} command, unless the user has the
+@code{SHOW DATABASES} privilege. From version 4.0.2 you should no longer
+need this option, since access can now be granted specifically with the
+@code{SHOW DATABASES} privilege.
@item --skip-stack-trace
Don't write stack traces. This option is useful when you are running
-@code{mysqld} under a debugger. @xref{Debugging server}.
+@code{mysqld} under a debugger. On some systems you also have to use
+this option to get a core file. @xref{Debugging server}.
@item --skip-thread-priority
Disable using thread priorities for faster response time.
@@ -14925,28 +14400,38 @@ Option can be any combination of: @code{REAL_AS_FLOAT},
By specifying all of the above options is same as using --ansi.
With this option one can turn on only needed SQL modes. @xref{ANSI mode}.
-@item transaction-isolation= @{ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE @}
+@item --temp-pool
+Using this option will cause most temporary files created to use a small
+set of names, rather than a unique name for each new file. This is to
+work around a problem in the Linux kernel dealing with creating a bunch
+of new files with different names. With the old behaviour, Linux seems to
+'leak' memory, as it's being allocated to the directory entry cache
+instead of the disk cache.
+
+@item --transaction-isolation= @{ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE @}
Sets the default transaction isolation level. @xref{SET TRANSACTION}.
@item -t, --tmpdir=path
Path for temporary files. It may be useful if your default @code{/tmp}
directory resides on a partition too small to hold temporary tables.
-@item -u, --user=user_name
-Run @code{mysqld} daemon as user @code{user_name}. This option is
-@emph{mandatory} when starting @code{mysqld} as root.
+@item -u, --user= [user_name | userid]
+Run @code{mysqld} daemon as user @code{user_name} or @code{userid} (numeric).
+This option is @strong{mandatory} when starting @code{mysqld} as root.
@item -V, --version
Output version information and exit.
-@item -W, --warnings
-Print out warnings like @code{Aborted connection...} to the @code{.err} file.
+@item -W, --log-warnings (Was --warnings)
+Print out warnings like @code{Aborted connection...} to the @file{.err} file.
@xref{Communication errors}.
@end table
+One can change most values for a running server with the
+@code{SET} command. @xref{SET OPTION}.
@node Option files, Installing many servers, Command-line options, Configuring MySQL
-@subsection my.cnf Option Files
+@subsection @file{my.cnf} Option Files
@cindex default options
@cindex option files
@@ -14959,7 +14444,7 @@ server and for clients from option files.
MySQL reads default options from the following files on Unix:
@tindex .my.cnf file
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .35 .50
@item @strong{Filename} @tab @strong{Purpose}
@item @code{/etc/my.cnf} @tab Global options
@item @code{DATADIR/my.cnf} @tab Server-specific options
@@ -14977,11 +14462,10 @@ before it processes any command-line arguments.)
MySQL reads default options from the following files on Windows:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .35 .50
@item @strong{Filename} @tab @strong{Purpose}
@item @code{windows-system-directory\my.ini} @tab Global options
@item @code{C:\my.cnf} @tab Global options
-@item @code{C:\mysql\data\my.cnf} @tab Server-specific options
@end multitable
Note that on Windows, you should specify all paths with @code{/} instead of
@@ -14992,17 +14476,19 @@ Note that on Windows, you should specify all paths with @code{/} instead of
MySQL tries to read option files in the order listed above. If
multiple option files exist, an option specified in a file read later takes
precedence over the same option specified in a file read earlier. Options
-specified on the command line take precedence over options specified in any
+specified on the command-line take precedence over options specified in any
option file. Some options can be specified using environment variables.
-Options specified on the command line or in option files take precedence over
+Options specified on the command-line or in option files take precedence over
environment variable values. @xref{Environment variables}.
The following programs support option files: @code{mysql},
-@code{mysqladmin}, @code{mysqld}, @code{mysqldump}, @code{mysqlimport},
-@code{mysql.server}, @code{myisamchk}, and @code{myisampack}.
+@code{mysqladmin}, @code{mysqld}, @code{mysqld_safe}, @code{mysql.server},
+@code{mysqldump}, @code{mysqlimport}, @code{mysqlshow}, @code{mysqlcheck},
+@code{myisamchk}, and @code{myisampack}.
-You can use option files to specify any long option that a program supports!
-Run the program with @code{--help} to get a list of available options.
+Any long option that may be given on the command-line when running a MySQL
+program can be given in an option file as well (without the leading double
+dash). Run the program with @code{--help} to get a list of available options.
An option file can contain lines of the following forms:
@@ -15017,13 +14503,13 @@ apply to the named group until the end of the option file or another group
line is given.
@item option
-This is equivalent to @code{--option} on the command line.
+This is equivalent to @code{--option} on the command-line.
@item option=value
-This is equivalent to @code{--option=value} on the command line.
+This is equivalent to @code{--option=value} on the command-line.
@item set-variable = variable=value
-This is equivalent to @code{--set-variable variable=value} on the command line.
+This is equivalent to @code{--set-variable variable=value} on the command-line.
This syntax must be used to set a @code{mysqld} variable.
@end table
@@ -15083,14 +14569,15 @@ large systems. You can copy @file{my-xxxx.cnf} to your home directory
All MySQL clients that support option files support the
following options:
-@multitable @columnfractions .40 .60
+@multitable @columnfractions .45 .55
+@item @strong{Option} @tab @strong{Description}
@item --no-defaults @tab Don't read any option files.
@item --print-defaults @tab Print the program name and all options that it will get.
@item --defaults-file=full-path-to-default-file @tab Only use the given configuration file.
@item --defaults-extra-file=full-path-to-default-file @tab Read this configuration file after the global configuration file but before the user configuration file.
@end multitable
-Note that the above options must be first on the command line to work!
+Note that the above options must be first on the command-line to work!
@code{--print-defaults} may however be used directly after the
@code{--defaults-xxx-file} commands.
@@ -15154,35 +14641,34 @@ will automatically be directed to the new running server!
If you need to do this more permanently, you should create an option
file for each server. @xref{Option files}. In your startup script that
-is executed at boot time (mysql.server?) you should specify for both
-servers:
+is executed at boot time you should specify for both servers:
@code{safe_mysqld --default-file=path-to-option-file}
At least the following options should be different per server:
-@table @code
+@itemize
@item port=#
@item socket=path
@item pid-file=path
-@end table
+@end itemize
The following options should be different, if they are used:
-@table @code
+@itemize
@item log=path
@item log-bin=path
@item log-update=path
@item log-isam=path
@item bdb-logdir=path
-@end table
+@end itemize
If you want more performance, you can also specify the following differently:
-@table @code
+@itemize
@item tmpdir=path
@item bdb-tmpdir=path
-@end table
+@end itemize
@xref{Command-line options}.
@@ -15191,11 +14677,7 @@ start them with @code{./bin/safe_mysqld} then in most cases the only
option you need to add/change is the @code{socket} and @code{port}
argument to @code{safe_mysqld}.
-
-@menu
-* Multiple servers:: Running Multiple MySQL Servers on the Same Machine
-@end menu
-
+@xref{Multiple servers, ,Running Multiple MySQL Servers on the Same Machine}.
@node Multiple servers, , Installing many servers, Configuring MySQL
@subsection Running Multiple MySQL Servers on the Same Machine
@@ -15225,9 +14707,9 @@ shell> ./configure --with-tcp-port=port_number \
--prefix=/usr/local/mysql-3.22.9
@end example
-Here @code{port_number} and @code{file_name} should be different than the
+Here @code{port_number} and @code{file_name} should be different from the
default port number and socket file pathname, and the @code{--prefix} value
-should specify an installation directory different than the one under which
+should specify an installation directory different from the one under which
the existing MySQL installation is located.
You can check the socket used by any currently executing MySQL server
@@ -15246,7 +14728,7 @@ MySQL, including the socket name.
You don't have to recompile a new MySQL server just to start with
a different port and socket. You can change the port and socket to be used
-by specifying them at run time as options to @code{safe_mysqld}:
+by specifying them at runtime as options to @code{safe_mysqld}:
@example
shell> /path/to/safe_mysqld --socket=file_name --port=port_number
@@ -15262,16 +14744,16 @@ files to @code{safe_mysqld} with @code{--log}, @code{--log-update}, or
@code{--log-slow-queries}. Otherwise, both servers may be trying to
write to the same log file.
-@strong{WARNING}: Normally you should never have two servers that update
+@strong{Warning}: normally you should never have two servers that update
data in the same database! If your OS doesn't support fault-free system
locking, this may lead to unpleasant surprises!
If you want to use another database directory for the second server, you
can use the @code{--datadir=path} option to @code{safe_mysqld}.
-@strong{NOTE} also that starting several MySQL servers
+@strong{Note} also that starting several MySQL servers
(@code{mysqlds}) in different machines and letting them access one data
-directory over @code{NFS} is generally a @strong{BAD IDEA}! The problem
+directory over @code{NFS} is generally a @strong{bad idea}! The problem
is that the @code{NFS} will become the bottleneck with the speed. It is
not meant for such use. And last but not least, you would still have to
come up with a solution how to make sure that two or more @code{mysqlds}
@@ -15303,7 +14785,8 @@ If your are using the Perl @code{DBD::mysql} module you can read the options
from the MySQL option files. @xref{Option files}.
@example
-$dsn = "DBI:mysql:test;mysql_read_default_group=client;mysql_read_default_file=/usr/local/mysql/data/my.cnf"
+$dsn = "DBI:mysql:test;mysql_read_default_group=client;
+ mysql_read_default_file=/usr/local/mysql/data/my.cnf"
$dbh = DBI->connect($dsn, $user, $password);
@end example
@@ -15341,6 +14824,7 @@ system. This section describes how it works.
* General security:: General security
* Security:: How to make MySQL secure against crackers
* Privileges options:: Startup Options for @code{mysqld} Concerning Security
+* LOAD DATA LOCAL::
* What Privileges:: What the privilege system does
* Privileges:: How the privilege system works
* Privileges provided:: Privileges provided by MySQL
@@ -15374,11 +14858,12 @@ When running MySQL, follow these guidelines whenever possible:
@itemize @bullet
@item
-DON'T EVER GIVE ANYONE (EXCEPT THE MySQL ROOT USER) ACCESS TO THE
-@code{user} TABLE IN THE @code{mysql} DATABASE! The encrypted password
-is the real password in MySQL. If you know the password listed in
-the @code{user} table for a given user, you can easily log in as that
-user if you have access to the host listed for that account.
+@strong{Do not ever give anyone (except the mysql root user) access to the
+@code{user} table in the @code{mysql} database!} This is critical.
+@strong{The encrypted password is the real password in MySQL.}
+Anyone who knows the password which is listed in the @code{user} table
+and has access to the host listed for the account @strong{can easily log
+in as that user}.
@item
Learn the MySQL access privilege system. The @code{GRANT} and
@@ -15404,8 +14889,8 @@ command.
@item
Do not keep any plain-text passwords in your database. When your
computer becomes compromised, the intruder can take the full list of
-passwords and use them. Instead use @code{MD5()} or another one-way
-hashing function.
+passwords and use them. Instead use @code{MD5()}, @code{SHA1()} or
+another one-way hashing function.
@item
Do not choose passwords from dictionaries. There are special programs to
break them. Even passwords like ``xfish98'' are very bad. Much better is
@@ -15417,7 +14902,7 @@ for someone who does not know it.
@item
Invest in a firewall. This protects you from at least 50% of all types of
exploits in any software. Put MySQL behind the firewall or in
-a demilitarized zone (DMZ).
+a demilitarised zone (DMZ).
Checklist:
@itemize @minus
@@ -15441,7 +14926,7 @@ connection is refused, everything is OK; the port is blocked.
@item
Do not trust any data entered by your users. They can try to trick your
-code by entering special or escaped character sequences in Web forms,
+code by entering special or escaped character sequences in web forms,
URLs, or whatever application you have built. Be sure that your
application remains secure if a user enters something like ``@code{; DROP
DATABASE mysql;}''. This is an extreme example, but large security leaks
@@ -15461,10 +14946,10 @@ strips all non-numeric symbols from it.
Checklist:
@itemize @minus
@item
-All Web applications:
+All web applications:
@itemize @bullet
@item
-Try to enter @samp{'} and @samp{"} in all your Web forms. If you get any kind
+Try to enter @samp{'} and @samp{"} in all your web forms. If you get any kind
of MySQL error, investigate the problem right away.
@item
Try to modify any dynamic URLs by adding @code{%22} (@samp{"}), @code{%23}
@@ -15495,7 +14980,7 @@ that is based on the function of the same name in the MySQL C API.
@item
Users of MySQL C API:
@itemize @bullet
-@item Check out the @code{mysql_escape_string()} API call.
+@item Check out the @code{mysql_real_escape_string()} API call.
@end itemize
@item
Users of MySQL++:
@@ -15518,12 +15003,12 @@ Users of Java JDBC:
Do not transmit plain (unencrypted) data over the Internet. These data are
accessible to everyone who has the time and ability to intercept it and use
it for their own purposes. Instead, use an encrypted protocol such as SSL or
-SSH. MySQL supports internal SSL connections as of Version 3.23.9.
+SSH. MySQL supports internal SSL connections as of Version 4.0.0.
SSH port-forwarding can be used to create an encrypted (and compressed)
tunnel for the communication.
@item
Learn to use the @code{tcpdump} and @code{strings} utilities. For most cases,
-you can check whether or not MySQL data streams are unencrypted
+you can check whether MySQL data streams are unencrypted
by issuing a command like the following:
@example
@@ -15531,7 +15016,7 @@ shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
@end example
(This works under Linux and should work with small modifications under
-other systems). Warning: If you do not see data this doesn't always
+other systems.) Warning: If you do not see data this doesn't always
actually mean that it is encrypted. If you need high security, you should
consult with a security expert.
@end itemize
@@ -15555,12 +15040,15 @@ communication.
All other information is transferred as text that can be read by anyone
who is able to watch the connection. If you are concerned about this,
you can use the compressed protocol (in MySQL Version 3.22 and above)
-to make things much harder. To make things even more secure you should use
-@code{ssh}. You can find an open source @code{ssh} client at
-@uref{http://www.openssh.org}, and a commercial @code{ssh} client at
-@uref{http://www.ssh.com}. With this, you can get an encrypted TCP/IP
+to make things much harder. To make things even more secure you should use
+@code{ssh}. You can find an @code{Open Source} @code{ssh} client at
+@uref{http://www.openssh.org/}, and a commercial @code{ssh} client at
+@uref{http://www.ssh.com/}. With this, you can get an encrypted TCP/IP
connection between a MySQL server and a MySQL client.
+If you are using MySQL 4.0, you can also use internal OpenSSL support.
+@xref{Secure connections}.
+
To make a MySQL system secure, you should strongly consider the
following suggestions:
@@ -15568,7 +15056,7 @@ following suggestions:
@item
Use passwords for all MySQL users. Remember that anyone can log in
as any other person as simply as @code{mysql -u other_user db_name} if
-@code{other_user} has no password. It is common behavior with client/server
+@code{other_user} has no password. It is common behaviour with client/server
applications that the client may specify any user name. You can change the
password of all users by editing the @code{mysql_install_db} script before
you run it, or only the password for the MySQL @code{root} user like
@@ -15577,13 +15065,13 @@ this:
@example
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('new_password')
- WHERE user='root';
+ -> WHERE user='root';
mysql> FLUSH PRIVILEGES;
@end example
@item
Don't run the MySQL daemon as the Unix @code{root} user. This is
-very dangerous, because any user with @code{FILE} privileges will be able
+very dangerous, because any user with the @code{FILE} privilege will be able
to create files as @code{root} (for example, @code{~root/.bashrc}). To
prevent this, @code{mysqld} will refuse to run as @code{root} unless it
is specified directly using a @code{--user=root} option.
@@ -15605,12 +15093,11 @@ user=mysql
This will cause the server to start as the designated user whether you
start it manually or by using @code{safe_mysqld} or @code{mysql.server}.
-For more details, see @ref{Changing MySQL user, , Changing MySQL
-user}.
+For more details, see @ref{Changing MySQL user}.
@item
-Don't support symlinks to tables (This can be disabled with the
-@code{--skip-symlink} option. This is especially important if you run
+Don't support symlinks to tables (this can be disabled with the
+@code{--skip-symlink} option). This is especially important if you run
@code{mysqld} as root as anyone that has write access to the mysqld data
directories could then delete any file in the system!
@xref{Symbolic links to tables}.
@@ -15620,25 +15107,25 @@ Check that the Unix user that @code{mysqld} runs as is the only user with
read/write privileges in the database directories.
@item
-Don't give the @strong{process} privilege to all users. The output of
+Don't give the @code{PROCESS} privilege to all users. The output of
@code{mysqladmin processlist} shows the text of the currently executing
queries, so any user who is allowed to execute that command might be able to
see if another user issues an @code{UPDATE user SET
password=PASSWORD('not_secure')} query.
@code{mysqld} reserves an extra connection for users who have the
-@strong{process} privilege, so that a MySQL @code{root} user can log
+@code{PROCESS} privilege, so that a MySQL @code{root} user can log
in and check things even if all normal connections are in use.
@item
-Don't give the @strong{file} privilege to all users. Any user that has this
-privilege can write a file anywhere in the file system with the privileges of
+Don't give the @code{FILE} privilege to all users. Any user that has this
+privilege can write a file anywhere in the filesystem with the privileges of
the @code{mysqld} daemon! To make this a bit safer, all files generated with
@code{SELECT ... INTO OUTFILE} are readable to everyone, and you cannot
overwrite existing files.
-@tindex /etc/passwd
-The @strong{file} privilege may also be used to read any file accessible
+@tindex @file{/etc/passwd}
+The @code{FILE} privilege may also be used to read any file accessible
to the Unix user that the server runs as. This could be abused, for example,
by using @code{LOAD DATA} to load @file{/etc/passwd} into a table, which
can then be read with @code{SELECT}.
@@ -15647,7 +15134,7 @@ can then be read with @code{SELECT}.
If you don't trust your DNS, you should use IP numbers instead of
hostnames in the grant tables. In any case, you should be very careful
about creating grant table entries using hostname values that contain
-wild cards!
+wildcards!
@item
If you want to restrict the number of connections for a single user, you
@@ -15656,27 +15143,32 @@ can do this by setting the @code{max_user_connections} variable in
@end itemize
-
-@node Privileges options, What Privileges, Security, Privilege system
+@node Privileges options, LOAD DATA LOCAL, Security, Privilege system
@subsection Startup Options for @code{mysqld} Concerning Security
The following @code{mysqld} options affect security:
@table @code
+@item --local-infile[=(0|1)]
+If one uses @code{--local-infile=0} then one can't use @code{LOAD DATA LOCAL
+INFILE}.
+
@item --safe-show-database
-With this option,
-@code{SHOW DATABASES} returns only those databases for which the user has
-some kind of privilege.
+With this option, the @code{SHOW DATABASES} command returns only those
+databases for which the user has some kind of privilege.
+From version 4.0.2 this option is deprecated and doesn't do anything
+(the option is enabled by default) as we now have the
+@code{SHOW DATABASES} privilege. @xref{GRANT}.
@item --safe-user-create
If this is enabled, an user can't create new users with the @code{GRANT}
-command, if the user doesn't have @code{INSERT} privilege to the
+command, if the user doesn't have the @code{INSERT} privilege for the
@code{mysql.user} table. If you want to give a user access to just create
new users with those privileges that the user has right to grant, you should
give the user the following privilege:
@example
-GRANT INSERT(user) on mysql.user to 'user'@'hostname';
+mysql> GRANT INSERT(user) ON mysql.user TO 'user'@@'hostname';
@end example
This will ensure that the user can't change any privilege columns directly,
@@ -15684,7 +15176,7 @@ but has to use the @code{GRANT} command to give privileges to other users.
@item --skip-grant-tables
This option causes the server not to use the privilege system at all. This
-gives everyone @emph{full access} to all databases! (You can tell a running
+gives everyone @strong{full access} to all databases! (You can tell a running
server to start using the grant tables again by executing @code{mysqladmin
flush-privileges} or @code{mysqladmin reload}.)
@@ -15694,18 +15186,63 @@ tables must be IP numbers or @code{localhost}.
@item --skip-networking
Don't allow TCP/IP connections over the network. All connections to
-@code{mysqld} must be made via Unix sockets. This option is unsuitable for
-systems that use MIT-pthreads, because the MIT-pthreads package doesn't
-support Unix sockets.
+@code{mysqld} must be made via Unix sockets.
+This option is unsuitable when using a MySQL version prior to 3.23.27 with
+the MIT-pthreads package, because Unix sockets were not supported by
+MIT-pthreads at that time.
@item --skip-show-database
-With this option, the
-@code{SHOW DATABASES} statement doesn't return anything.
+Don't allow @code{SHOW DATABASES} command, unless the user has the
+@code{SHOW DATABASES} privilege. From version 4.0.2 you should no longer
+need this option, since access can now be granted specifically with the
+@code{SHOW DATABASES} privilege.
@end table
+@node LOAD DATA LOCAL, What Privileges, Privileges options, Privilege system
+@subsection Security issues with LOAD DATA LOCAL
+
+In MySQL 3.23.49 and MySQL 4.0.2, we added some new options to deal with
+possible security issues when it comes to @code{LOAD DATA LOCAL}.
+
+There are two possible problems with supporting this command:
-@node What Privileges, Privileges, Privileges options, Privilege system
+As the reading of the file is initiated from the server, one could
+theoretically create a patched MySQL server that could read any file on
+the client machine that the current user has read access to, when
+the client issues a query against the table.
+
+In a web environment where the clients are connecting from a web
+server, a user could use @code{LOAD DATA LOCAL} to read any files
+that the web server process has read access to (assuming a user could
+run any command against the SQL server).
+
+There are two separate fixes for this:
+
+If you don't configure MySQL with @code{--enable-local-infile}, then
+@code{LOAD DATA LOCAL} will be disabled by all clients, unless one
+calls @code{mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0)} in the client.
+@xref{mysql_options, , @code{mysql_options()}}.
+
+For the @code{mysql} command-line client, @code{LOAD DATA LOCAL} can be
+enabled by specifying the option @code{--local-infile[=1]}, or disabled
+with @code{--local-infile=0}.
+
+By default, all MySQL clients and libraries are compiled with
+@code{--enable-local-infile}, to be compatible with MySQL 3.23.48 and
+before.
+
+One can disable all @code{LOAD DATA LOCAL} commands in the MySQL server
+by starting @code{mysqld} with @code{--local-infile=0}.
+
+In the case that @code{LOAD DATA LOCAL INFILE} is disabled in the server or
+the client, you will get the error message (1148):
+
+@example
+The used command is not allowed with this MySQL version
+@end example
+
+@node What Privileges, Privileges, LOAD DATA LOCAL, Privilege system
@subsection What the Privilege System Does
@cindex system, privilege
@@ -15715,7 +15252,7 @@ With this option, the
The primary function of the MySQL privilege system is to
authenticate a user connecting from a given host, and to associate that user
with privileges on a database such as
-@strong{select}, @strong{insert}, @strong{update} and @strong{delete}.
+@code{SELECT}, @code{INSERT}, @code{UPDATE} and @code{DELETE}.
Additional functionality includes the ability to have an anonymous user and
to grant privileges for MySQL-specific functions such as @code{LOAD
@@ -15736,60 +15273,60 @@ privileges according to your identity and @strong{what you want to do}.
MySQL considers both your hostname and user name in identifying you
because there is little reason to assume that a given user name belongs to
the same person everywhere on the Internet. For example, the user
-@code{bill} who connects from @code{whitehouse.gov} need not be the same
-person as the user @code{bill} who connects from @code{microsoft.com}.
+@code{joe} who connects from @code{office.com} need not be the same
+person as the user @code{joe} who connects from @code{elsewhere.com}.
MySQL handles this by allowing you to distinguish users on different
-hosts that happen to have the same name: you can grant @code{bill} one set
-of privileges for connections from @code{whitehouse.gov}, and a different set
-of privileges for connections from @code{microsoft.com}.
+hosts that happen to have the same name: you can grant @code{joe} one set
+of privileges for connections from @code{office.com}, and a different set
+of privileges for connections from @code{elsewhere.com}.
MySQL access control involves two stages:
@itemize @bullet
@item
-Stage 1: The server checks whether or not you are even allowed to connect.
+Stage 1: The server checks whether you are even allowed to connect.
@item
Stage 2: Assuming you can connect, the server checks each request you issue
-to see whether or not you have sufficient privileges to perform it. For
+to see whether you have sufficient privileges to perform it. For
example, if you try to select rows from a table in a database or drop a table
-from the database, the server makes sure you have the @strong{select}
-privilege for the table or the @strong{drop} privilege for the database.
+from the database, the server makes sure you have the @code{SELECT}
+privilege for the table or the @code{DROP} privilege for the database.
@end itemize
The server uses the @code{user}, @code{db}, and @code{host} tables in the
@code{mysql} database at both stages of access control. The fields in these
-grant tables are shown below:
+grant tables are shown here:
-@multitable @columnfractions .2 .25 .25 .25
-@item @strong{Table name} @tab @code{user} @tab @code{db} @tab @code{host}
+@multitable @columnfractions .20 .20 .20 .20
+@item @strong{Table name} @tab @code{user} @tab @code{db} @tab @code{host}
-@item @strong{Scope fields} @tab @code{Host} @tab @code{Host} @tab @code{Host}
-@item @tab @code{User} @tab @code{Db} @tab @code{Db}
-@item @tab @code{Password} @tab @code{User} @tab
+@item @strong{Scope fields} @tab @code{Host} @tab @code{Host} @tab @code{Host}
+@item @tab @code{User} @tab @code{Db} @tab @code{Db}
+@item @tab @code{Password} @tab @code{User} @tab
@item @strong{Privilege fields} @tab @code{Select_priv} @tab @code{Select_priv} @tab @code{Select_priv}
-@item @tab @code{Insert_priv} @tab @code{Insert_priv} @tab @code{Insert_priv}
-@item @tab @code{Update_priv} @tab @code{Update_priv} @tab @code{Update_priv}
-@item @tab @code{Delete_priv} @tab @code{Delete_priv} @tab @code{Delete_priv}
-@item @tab @code{Index_priv} @tab @code{Index_priv} @tab @code{Index_priv}
-@item @tab @code{Alter_priv} @tab @code{Alter_priv} @tab @code{Alter_priv}
-@item @tab @code{Create_priv} @tab @code{Create_priv} @tab @code{Create_priv}
-@item @tab @code{Drop_priv} @tab @code{Drop_priv} @tab @code{Drop_priv}
-@item @tab @code{Grant_priv} @tab @code{Grant_priv} @tab @code{Grant_priv}
-@item @tab @code{References_priv} @tab @tab
-@item @tab @code{Reload_priv} @tab @tab
-@item @tab @code{Shutdown_priv} @tab @tab
-@item @tab @code{Process_priv} @tab @tab
-@item @tab @code{File_priv} @tab @tab
+@item @tab @code{Insert_priv} @tab @code{Insert_priv} @tab @code{Insert_priv}
+@item @tab @code{Update_priv} @tab @code{Update_priv} @tab @code{Update_priv}
+@item @tab @code{Delete_priv} @tab @code{Delete_priv} @tab @code{Delete_priv}
+@item @tab @code{Index_priv} @tab @code{Index_priv} @tab @code{Index_priv}
+@item @tab @code{Alter_priv} @tab @code{Alter_priv} @tab @code{Alter_priv}
+@item @tab @code{Create_priv} @tab @code{Create_priv} @tab @code{Create_priv}
+@item @tab @code{Drop_priv} @tab @code{Drop_priv} @tab @code{Drop_priv}
+@item @tab @code{Grant_priv} @tab @code{Grant_priv} @tab @code{Grant_priv}
+@item @tab @code{References_priv} @tab @tab
+@item @tab @code{Reload_priv} @tab @tab
+@item @tab @code{Shutdown_priv} @tab @tab
+@item @tab @code{Process_priv} @tab @tab
+@item @tab @code{File_priv} @tab @tab
@end multitable
For the second stage of access control (request verification), the server
may, if the request involves tables, additionally consult the
@code{tables_priv} and @code{columns_priv} tables. The fields in these
-tables are shown below:
+tables are shown here:
-@multitable @columnfractions .2 .25 .25
+@multitable @columnfractions .20 .20 .20
@item @strong{Table name} @tab @code{tables_priv} @tab @code{columns_priv}
@item @strong{Scope fields} @tab @code{Host} @tab @code{Host}
@@ -15819,11 +15356,11 @@ table entry with @code{Host}, @code{User}, and @code{Db} fields of
tables contain scope fields indicating tables or table/column combinations
to which each entry applies.
-@cindex case sensitivity, in access checking
+@cindex case-sensitivity, in access checking
For access-checking purposes, comparisons of @code{Host} values are
-case insensitive. @code{User}, @code{Password}, @code{Db}, and
-@code{Table_name} values are case sensitive.
-@code{Column_name} values are case insensitive in MySQL Version
+case-insensitive. @code{User}, @code{Password}, @code{Db}, and
+@code{Table_name} values are case-sensitive.
+@code{Column_name} values are case-insensitive in MySQL Version
3.22.12 or later.
Privilege fields indicate the privileges granted by a table entry, that is,
@@ -15831,35 +15368,40 @@ what operations can be performed. The server combines the information in the
various grant tables to form a complete description of a user's privileges.
The rules used to do this are described in @ref{Request access}.
-Scope fields are strings, declared as shown below; the default value for
+Scope fields are strings, declared as shown here; the default value for
each is the empty string:
-@multitable @columnfractions .15 .15 .7
-@item @strong{Field name} @tab @strong{Type}
-@item @code{Host} @tab @code{CHAR(60)}
-@item @code{User} @tab @code{CHAR(16)}
-@item @code{Password} @tab @code{CHAR(16)}
-@item @code{Db} @tab @code{CHAR(64)} @tab (@code{CHAR(60)} for the
+@multitable @columnfractions .20 .15 .65
+@item @strong{Field name} @tab @strong{Type} @tab @strong{Notes}
+@item @code{Host} @tab @code{CHAR(60)} @tab
+@item @code{User} @tab @code{CHAR(16)} @tab
+@item @code{Password} @tab @code{CHAR(16)} @tab
+@item @code{Db} @tab @code{CHAR(64)} @tab (@code{CHAR(60)} for the
@code{tables_priv} and @code{columns_priv} tables)
-@item @code{Table_name} @tab @code{CHAR(60)}
-@item @code{Column_name} @tab @code{CHAR(60)}
+@item @code{Table_name} @tab @code{CHAR(60)} @tab
+@item @code{Column_name} @tab @code{CHAR(60)} @tab
@end multitable
In the @code{user}, @code{db} and @code{host} tables,
-all privilege fields are declared as @code{ENUM('N','Y')} --- each can have a
+all privilege fields are declared as @code{ENUM('N','Y')}@-each can have a
value of @code{'N'} or @code{'Y'}, and the default value is @code{'N'}.
In the @code{tables_priv} and @code{columns_priv} tables, the privilege
fields are declared as @code{SET} fields:
-@multitable @columnfractions .2 .2 .6
-@item @strong{Table name} @tab @strong{Field name} @tab @strong{Possible set elements}
-@item @code{tables_priv} @tab @code{Table_priv} @tab @code{'Select', 'Insert',
-'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'}
-@item @code{tables_priv} @tab @code{Column_priv} @tab @code{'Select', 'Insert',
-'Update', 'References'}
-@item @code{columns_priv} @tab @code{Column_priv} @tab @code{'Select', 'Insert',
-'Update', 'References'}
+@multitable @columnfractions .15 .15 .55
+@item @strong{Table name}
+ @tab @strong{Field name}
+ @tab @strong{Possible set elements}
+@item @code{tables_priv}
+ @tab @code{Table_priv}
+ @tab @code{'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'}
+@item @code{tables_priv}
+ @tab @code{Column_priv}
+ @tab @code{'Select', 'Insert', 'Update', 'References'}
+@item @code{columns_priv}
+ @tab @code{Column_priv}
+ @tab @code{'Select', 'Insert', 'Update', 'References'}
@end multitable
Briefly, the server uses the grant tables like this:
@@ -15895,15 +15437,15 @@ the @code{db} table, but are more fine-grained: they apply at the
table and column levels rather than at the database level.
@end itemize
-Note that administrative privileges (@strong{reload}, @strong{shutdown},
+Note that administrative privileges (@code{RELOAD}, @code{SHUTDOWN},
etc.) are specified only in the @code{user} table. This is because
administrative operations are operations on the server itself and are not
database-specific, so there is no reason to list such privileges in the
other grant tables. In fact, only the @code{user} table need
-be consulted to determine whether or not you can perform an administrative
+be consulted to determine whether you can perform an administrative
operation.
-The @strong{file} privilege is specified only in the @code{user} table, too.
+The @code{FILE} privilege is specified only in the @code{user} table, too.
It is not an administrative privilege as such, but your ability to read or
write files on the server host is independent of the database you are
accessing.
@@ -15915,7 +15457,7 @@ starts up. Changes to the grant tables take effect as indicated in
When you modify the contents of the grant tables, it is a good idea to make
sure that your changes set up privileges the way you want. For help in
diagnosing problems, see @ref{Access denied}. For advice on security issues,
-@pxref{Security}.
+see @ref{Security}.
A useful
diagnostic tool is the @code{mysqlaccess} script, which Yves Carlier has
@@ -15938,33 +15480,41 @@ MySQL server reads the contents of these tables when it starts up
and under the circumstances indicated in @ref{Privilege changes}.
The names used in this manual to refer to the privileges provided by
-MySQL are shown below, along with the table column name associated
-with each privilege in the grant tables and the context in which the
-privilege applies:
+MySQL version 4.0.2 are shown here, along with the table column name
+associated with each privilege in the grant tables and the context in
+which the privilege applies:
-@multitable @columnfractions .15 .25 .6
+@c FIX agl 2002-06-13 Long items added, will need to re-measure colwidths!
+@multitable @columnfractions .15 .20 .35
@item @strong{Privilege} @tab @strong{Column} @tab @strong{Context}
-@item @strong{select} @tab @code{Select_priv} @tab tables
-@item @strong{insert} @tab @code{Insert_priv} @tab tables
-@item @strong{update} @tab @code{Update_priv} @tab tables
-@item @strong{delete} @tab @code{Delete_priv} @tab tables
-@item @strong{index} @tab @code{Index_priv} @tab tables
-@item @strong{alter} @tab @code{Alter_priv} @tab tables
-@item @strong{create} @tab @code{Create_priv} @tab databases, tables, or indexes
-@item @strong{drop} @tab @code{Drop_priv} @tab databases or tables
-@item @strong{grant} @tab @code{Grant_priv} @tab databases or tables
-@item @strong{references} @tab @code{References_priv} @tab databases or tables
-@item @strong{reload} @tab @code{Reload_priv} @tab server administration
-@item @strong{shutdown} @tab @code{Shutdown_priv} @tab server administration
-@item @strong{process} @tab @code{Process_priv} @tab server administration
-@item @strong{file} @tab @code{File_priv} @tab file access on server
+@item @code{ALTER} @tab @code{Alter_priv} @tab tables
+@item @code{DELETE} @tab @code{Delete_priv} @tab tables
+@item @code{INDEX} @tab @code{Index_priv} @tab tables
+@item @code{INSERT} @tab @code{Insert_priv} @tab tables
+@item @code{SELECT} @tab @code{Select_priv} @tab tables
+@item @code{UPDATE} @tab @code{Update_priv} @tab tables
+@item @code{CREATE} @tab @code{Create_priv} @tab databases, tables, or indexes
+@item @code{DROP} @tab @code{Drop_priv} @tab databases or tables
+@item @code{GRANT} @tab @code{Grant_priv} @tab databases or tables
+@item @code{REFERENCES} @tab @code{References_priv} @tab databases or tables
+@item @code{CREATE TEMPORARY TABLES} @tab @code{Create_tmp_table_priv} @tab server administration
+@item @code{EXECUTE} @tab @code{Execute_priv} @tab server administration
+@item @code{FILE} @tab @code{File_priv} @tab file access on server
+@item @code{LOCK TABLES} @tab @code{Lock_tables_priv} @tab server administration
+@item @code{PROCESS} @tab @code{Process_priv} @tab server administration
+@item @code{RELOAD} @tab @code{Reload_priv} @tab server administration
+@item @code{REPLICATION CLIENT} @tab @code{Repl_client_priv} @tab server administration
+@item @code{REPLICATION SLAVE} @tab @code{Repl_slave_priv} @tab server administration
+@item @code{SHOW DATABASES} @tab @code{Show_db_priv} @tab server administration
+@item @code{SHUTDOWN} @tab @code{Shutdown_priv} @tab server administration
+@item @code{SUPER} @tab @code{Super_priv} @tab server administration
@end multitable
-The @strong{select}, @strong{insert}, @strong{update}, and @strong{delete}
+The @code{SELECT}, @code{INSERT}, @code{UPDATE}, and @code{DELETE}
privileges allow you to perform operations on rows in existing tables in
a database.
-@code{SELECT} statements require the @strong{select} privilege only if they
+@code{SELECT} statements require the @code{SELECT} privilege only if they
actually retrieve rows from a table. You can execute certain @code{SELECT}
statements even without permission to access any of the databases on the
server. For example, you could use the @code{mysql} client as a simple
@@ -15975,37 +15525,38 @@ mysql> SELECT 1+1;
mysql> SELECT PI()*2;
@end example
-The @strong{index} privilege allows you to create or drop (remove) indexes.
+The @code{INDEX} privilege allows you to create or drop (remove) indexes.
-The @strong{alter} privilege allows you to use @code{ALTER TABLE}.
+The @code{ALTER} privilege allows you to use @code{ALTER TABLE}.
-The @strong{create} and @strong{drop} privileges allow you to create new
+The @code{CREATE} and @code{DROP} privileges allow you to create new
databases and tables, or to drop (remove) existing databases and tables.
-Note that if you grant the @strong{drop} privilege for the @code{mysql}
+Note that if you grant the @code{DROP} privilege for the @code{mysql}
database to a user, that user can drop the database in which the
MySQL access privileges are stored!
-The @strong{grant} privilege allows you to give to other users those
+The @code{GRANT} privilege allows you to give to other users those
privileges you yourself possess.
-The @strong{file} privilege gives you permission to read and write files on
+The @code{FILE} privilege gives you permission to read and write files on
the server using the @code{LOAD DATA INFILE} and @code{SELECT ... INTO
OUTFILE} statements. Any user to whom this privilege is granted can read or
write any file that the MySQL server can read or write.
The remaining privileges are used for administrative operations, which are
-performed using the @code{mysqladmin} program. The table below shows which
+performed using the @code{mysqladmin} program. The table here shows which
@code{mysqladmin} commands each administrative privilege allows you to
execute:
-@multitable @columnfractions .15 .85
+@multitable @columnfractions .15 .75
@item @strong{Privilege} @tab @strong{Commands permitted to privilege holders}
-@item @strong{reload} @tab @code{reload}, @code{refresh},
+@item @code{RELOAD} @tab @code{reload}, @code{refresh},
@code{flush-privileges}, @code{flush-hosts}, @code{flush-logs}, and
@code{flush-tables}
-@item @strong{shutdown} @tab @code{shutdown}
-@item @strong{process} @tab @code{processlist}, @code{kill}
+@item @code{SHUTDOWN} @tab @code{shutdown}
+@item @code{PROCESS} @tab @code{processlist}
+@item @code{SUPER} @tab @code{kill}
@end multitable
The @code{reload} command tells the server to re-read the grant tables. The
@@ -16019,10 +15570,10 @@ than @code{refresh}.
The @code{shutdown} command shuts down the server.
The @code{processlist} command displays information about the threads
-executing within the server. The @code{kill} command kills server threads.
-You can always display or kill your own threads, but you need the
-@strong{process} privilege to display or kill threads initiated by other
-users. @xref{KILL}.
+executing within the server. The @code{kill} command kills server
+threads. You can always display or kill your own threads, but you need
+the @code{PROCESS} privilege to display and @code{SUPER} privilege to
+kill threads initiated by other users. @xref{KILL}.
It is a good idea in general to grant privileges only to those users who need
them, but you should exercise particular caution in granting certain
@@ -16030,33 +15581,33 @@ privileges:
@itemize @bullet
@item
-The @strong{grant} privilege allows users to give away their privileges to
-other users. Two users with different privileges and with the @strong{grant}
+The @code{GRANT} privilege allows users to give away their privileges to
+other users. Two users with different privileges and with the @code{GRANT}
privilege are able to combine privileges.
@item
-The @strong{alter} privilege may be used to subvert the privilege system
+The @code{ALTER} privilege may be used to subvert the privilege system
by renaming tables.
@item
-The @strong{file} privilege can be abused to read any world-readable file on
+The @code{FILE} privilege can be abused to read any world-readable file on
the server into a database table, the contents of which can then be
accessed using @code{SELECT}. This includes the contents of all databases
hosted by the server!
@item
-The @strong{shutdown} privilege can be abused to deny service to other
+The @code{SHUTDOWN} privilege can be abused to deny service to other
users entirely, by terminating the server.
@item
-The @strong{process} privilege can be used to view the plain text of
+The @code{PROCESS} privilege can be used to view the plain text of
currently executing queries, including queries that set or change passwords.
@item
Privileges on the @code{mysql} database can be used to change passwords
and other access privilege information. (Passwords are stored
encrypted, so a malicious user cannot simply read them to know the plain
-text password). If they can access the @code{mysql.user} password
+text password.) If they can access the @code{mysql.user} password
column, they can use it to log into the MySQL server
for the given user. (With sufficient privileges, the same user can
replace a password with a different one.)
@@ -16099,12 +15650,12 @@ Alternate forms of the @code{-h}, @code{-u}, and @code{-p} options are
@code{--password=your_pass}. Note that there is @emph{no space} between
@code{-p} or @code{--password=} and the password following it.
-@strong{NOTE:} Specifying a password on the command line is not secure!
+@strong{Note}: Specifying a password on the command-line is not secure!
Any user on your system may then find out your password by typing a command
like: @code{ps auxww}. @xref{Option files}.
@code{mysql} uses default values for connection parameters that are missing
-from the command line:
+from the command-line:
@itemize @bullet
@item
@@ -16129,7 +15680,7 @@ shell> mysql
Other MySQL clients behave similarly.
On Unix systems, you can specify different default values to be used when you
-make a connection, so that you need not enter them on the command line each
+make a connection, so that you need not enter them on the command-line each
time you invoke a client program. This can be done in a couple of ways:
@itemize @bullet
@@ -16172,7 +15723,7 @@ Windows only). The password can be specified using @code{MYSQL_PWD}
@cindex testing, connection to the server
When you attempt to connect to a MySQL server, the server accepts or
-rejects the connection based on your identity and whether or not you can
+rejects the connection based on your identity and whether you can
verify your identity by supplying the correct password. If not, the server
denies access to you completely. Otherwise, the server accepts the
connection, then enters Stage 2 and waits for requests.
@@ -16201,7 +15752,7 @@ to indicate the local host.
@item
@cindex wildcards, in @code{mysql.user} table
-You can use the wild-card characters @samp{%} and @samp{_} in the @code{Host}
+You can use the wildcard characters @samp{%} and @samp{_} in the @code{Host}
field.
@item
@@ -16214,12 +15765,13 @@ You can find more information about this in the next chapter.
@cindex netmask notation, in @code{mysql.user} table
@item
-As of MySQL Version 3.23, for @code{Host} values specified as
-IP numbers, you can specify a netmask indicating how many address bits to
+As of MySQL Version 3.23, for @code{Host} values specified as
+IP numbers, you can specify a netmask indicating how many address bits to
use for the network number. For example:
@example
-GRANT ALL PRIVILEGES on db.* to david@@'192.58.197.0/255.255.255.0';
+mysql> GRANT ALL PRIVILEGES ON db.*
+ -> TO david@@'192.58.197.0/255.255.255.0';
@end example
This will allow everyone to connect from an IP where the following is true:
@@ -16233,7 +15785,7 @@ In the above example all IP:s in the interval 192.58.197.0 -
@item
@cindex anonymous user
-Wild-card characters are not allowed in the @code{User} field, but you can
+Wildcard characters are not allowed in the @code{User} field, but you can
specify a blank value, which matches any name. If the @code{user} table
entry that matches an incoming connection has a blank user name, the user is
considered to be the anonymous user (the user with no name), rather than the
@@ -16252,17 +15804,17 @@ MySQL does not store passwords in plaintext form for anyone to
see. Rather, the password supplied by a user who is attempting to
connect is encrypted (using the @code{PASSWORD()} function). The
encrypted password is then used when the client/server is checking if
-the password is correct (This is done without the encrypted password
+the password is correct. (This is done without the encrypted password
ever traveling over the connection.) Note that from MySQL's
point of view the encrypted password is the REAL password, so you should
not give anyone access to it! In particular, don't give normal users
read access to the tables in the @code{mysql} database!
-The examples below show how various combinations of @code{Host} and
+The examples here show how various combinations of @code{Host} and
@code{User} values in @code{user} table entries apply to incoming
connections:
-@multitable @columnfractions .25 .15 .60
+@multitable @columnfractions .35 .15 .50
@item @code{Host} @strong{value} @tab @code{User} @strong{value} @tab @strong{Connections matched by entry}
@item @code{'thomas.loc.gov'} @tab @code{'fred'} @tab @code{fred}, connecting from @code{thomas.loc.gov}
@item @code{'thomas.loc.gov'} @tab @code{''} @tab Any user, connecting from @code{thomas.loc.gov}
@@ -16275,14 +15827,14 @@ connections:
@item @code{'144.155.166.0/255.255.255.0'} @tab @code{'fred'} @tab Same as previous example
@end multitable
-Because you can use IP wild-card values in the @code{Host} field (for example,
+Because you can use IP wildcard values in the @code{Host} field (for example,
@code{'144.155.166.%'} to match every host on a subnet), there is the
possibility that someone might try to exploit this capability by naming a
host @code{144.155.166.somewhere.com}. To foil such attempts, MySQL
disallows matching on hostnames that start with digits and a dot. Thus, if
you have a host named something like @code{1.2.foo.com}, its name will never
match the @code{Host} column of the grant tables. Only an IP number can
-match an IP wild-card value.
+match an IP wildcard value.
An incoming connection may be matched by more than one entry in the
@code{user} table. For example, a connection from @code{thomas.loc.gov} by
@@ -16387,7 +15939,7 @@ tables.)
The @code{user} table grants privileges that are assigned to you on a global
basis and that apply no matter what the current database is. For example, if
-the @code{user} table grants you the @strong{delete} privilege, you can
+the @code{user} table grants you the @code{DELETE} privilege, you can
delete rows from any database on the server host! In other words,
@code{user} table privileges are superuser privileges. It is wise to grant
privileges in the @code{user} table only to superusers such as server or
@@ -16396,14 +15948,14 @@ in the @code{user} table set to @code{'N'} and grant privileges on a
database-specific basis only, using the @code{db} and @code{host} tables.
@cindex anonymous user
-@cindex wild cards, in @code{mysql.db} table
-@cindex wild cards, in @code{mysql.host} table
+@cindex wildcards, in @code{mysql.db} table
+@cindex wildcards, in @code{mysql.host} table
The @code{db} and @code{host} tables grant database-specific privileges.
Values in the scope fields may be specified as follows:
@itemize @bullet
@item
-The wild-card characters @samp{%} and @samp{_} can be used in the @code{Host}
+The wildcard characters @samp{%} and @samp{_} can be used in the @code{Host}
and @code{Db} fields of either table.
@item
@@ -16435,15 +15987,15 @@ values first and least-specific values last, and when the server looks for
matching entries, it uses the first match that it finds.
-@cindex wild cards, in @code{mysql.tables_priv} table
-@cindex wild cards, in @code{mysql.columns_priv} table
+@cindex wildcards, in @code{mysql.tables_priv} table
+@cindex wildcards, in @code{mysql.columns_priv} table
The @code{tables_priv} and @code{columns_priv} tables grant table- and
column-specific privileges. Values in the scope fields may be specified as
follows:
@itemize @bullet
@item
-The wild-card characters @samp{%} and @samp{_}
+The wildcard characters @samp{%} and @samp{_}
can be used in the @code{Host} field of either table.
@item
@@ -16451,30 +16003,30 @@ A @code{'%'} or blank @code{Host} value in either table means ``any host.''
@item
The @code{Db}, @code{Table_name} and @code{Column_name} fields cannot contain
-wild cards or be blank in either table.
+wildcards or be blank in either table.
@end itemize
The @code{tables_priv} and @code{columns_priv} tables are sorted on
the @code{Host}, @code{Db}, and @code{User} fields. This is similar to
@code{db} table sorting, although the sorting is simpler because
-only the @code{Host} field may contain wild cards.
+only the @code{Host} field may contain wildcards.
-The request verification process is described below. (If you are familiar
+The request verification process is described here. (If you are familiar
with the access-checking source code, you will notice that the description
here differs slightly from the algorithm used in the code. The description
is equivalent to what the code actually does; it differs only to make the
explanation simpler.)
-For administrative requests (@strong{shutdown}, @strong{reload}, etc.), the
+For administrative requests (@code{SHUTDOWN}, @code{RELOAD}, etc.), the
server checks only the @code{user} table entry, because that is the only table
that specifies administrative privileges. Access is granted if the entry
allows the requested operation and denied otherwise. For example, if you
want to execute @code{mysqladmin shutdown} but your @code{user} table entry
-doesn't grant the @strong{shutdown} privilege to you, access is denied
+doesn't grant the @code{SHUTDOWN} privilege to you, access is denied
without even checking the @code{db} or @code{host} tables. (They
contain no @code{Shutdown_priv} column, so there is no need to do so.)
-For database-related requests (@strong{insert}, @strong{update}, etc.), the
+For database-related requests (@code{INSERT}, @code{UPDATE}, etc.), the
server first checks the user's global (superuser) privileges by looking in
the @code{user} table entry. If the entry allows the requested operation,
access is granted. If the global privileges in the @code{user} table are
@@ -16500,7 +16052,7 @@ access to the database. In this case, a further lookup is done in the
@code{host} table to find a match on the @code{Host} and @code{Db} fields.
If no @code{host} table entry matches, access is denied. If there is a
match, the user's database-specific privileges are computed as the
-intersection (@emph{not} the union!) of the privileges in the @code{db} and
+intersection (@strong{not} the union!) of the privileges in the @code{db} and
@code{host} table entries, that is, the privileges that are @code{'Y'} in both
entries. (This way you can grant general privileges in the @code{db} table
entry and then selectively restrict them on a host-by-host basis using the
@@ -16516,7 +16068,7 @@ tables and adds those to the user's privileges. Access is allowed or denied
based on the result.
Expressed in boolean terms, the preceding description of how a user's
-privileges are calculated may be summarized like this:
+privileges are calculated may be summarised like this:
@example
global privileges
@@ -16530,7 +16082,7 @@ initially found to be insufficient for the requested operation, the server
adds those privileges to the database-, table-, and column-specific privileges
later. The reason is that a request might require more than one type of
privilege. For example, if you execute an @code{INSERT ... SELECT}
-statement, you need both @strong{insert} and @strong{select} privileges.
+statement, you need both @code{INSERT} and @code{SELECT} privileges.
Your privileges might be such that the @code{user} table entry grants one
privilege and the @code{db} table entry grants the other. In this case, you
have the necessary privileges to perform the request, but the server cannot
@@ -16545,7 +16097,7 @@ The @code{host} table can be used to maintain a list of secure servers.
At TcX, the @code{host} table contains a list of all machines on the local
network. These are granted all privileges.
-You can also use the @code{host} table to indicate hosts that are @emph{not}
+You can also use the @code{host} table to indicate hosts that are @strong{not}
secure. Suppose you have a machine @code{public.your.domain} that is located
in a public area that you do not consider secure. You can allow access to
all hosts on your network except that machine by using @code{host} table
@@ -16575,7 +16127,7 @@ actually set up the way you think they are.
@subsection Causes of @code{Access denied} Errors
If you encounter @code{Access denied} errors when you try to connect to the
-MySQL server, the list below indicates some courses of
+MySQL server, the following list indicates some courses of
action you can take to correct the problem:
@itemize @bullet
@@ -16631,8 +16183,8 @@ Access denied for user: 'root@@localhost' (Using password: YES)
It means that you are using a wrong password. @xref{Passwords}.
If you have forgot the root password, you can restart @code{mysqld} with
-@code{--skip-grant-tables} to change the password. You can find more
-about this option later on in this manual section.
+@code{--skip-grant-tables} to change the password.
+@xref{Resetting permissions}.
If you get the above error even if you haven't specified a password,
this means that you a wrong password in some @code{my.ini}
@@ -16669,9 +16221,10 @@ password} command.
@code{localhost} is a synonym for your local hostname, and is also the
default host to which clients try to connect if you specify no host
explicitly. However, connections to @code{localhost} do not work if you are
-running on a system that uses MIT-pthreads (@code{localhost} connections are
-made using Unix sockets, which are not supported by MIT-pthreads). To avoid
-this problem on such systems, you should use the @code{--host} option to name
+using a MySQL version prior to 3.23.27 that uses MIT-pthreads
+(@code{localhost} connections are made using Unix sockets, which were not
+supported by MIT-pthreads at that time). To avoid this problem on such
+systems, you should use the @code{--host} option to name
the server host explicitly. This will make a TCP/IP connection to the
@code{mysqld} server. In this case, you must have your real hostname in
@code{user} table entries on the server host. (This is true even if you are
@@ -16735,7 +16288,7 @@ hostname is an IP, even if you try to connect with a hostname:
@example
shell> mysqladmin -u root -pxxxx -h some-hostname ver
-Access denied for user: 'root@' (Using password: YES)
+Access denied for user: 'root@@' (Using password: YES)
@end example
This means that MySQL got some error when trying to resolve the
@@ -16776,9 +16329,9 @@ name (or vice-versa). For example, if you have an entry with host
your hostname is @code{'tcx.subnet.se'}, the entry will not work. Try adding
an entry to the @code{user} table that contains the IP number of your host as
the @code{Host} column value. (Alternatively, you could add an entry to the
-@code{user} table with a @code{Host} value that contains a wild card---for
+@code{user} table with a @code{Host} value that contains a wildcard---for
example, @code{'tcx.%'}. However, use of hostnames ending with @samp{%} is
-@emph{insecure} and is @emph{not} recommended!)
+@strong{insecure} and is @strong{not} recommended!)
@item
If @code{mysql -u user_name test} works but @code{mysql -u user_name
@@ -16794,7 +16347,7 @@ in the @code{user} table or the @code{db} table.
@item
If you can't figure out why you get @code{Access denied}, remove from the
@code{user} table all entries that have @code{Host} values containing
-wild cards (entries that contain @samp{%} or @samp{_}). A very common error
+wildcards (entries that contain @samp{%} or @samp{_}). A very common error
is to insert a new entry with @code{Host}=@code{'%'} and
@code{User}=@code{'some user'}, thinking that this will allow you to specify
@code{localhost} to connect from the same machine. The reason that this
@@ -16822,7 +16375,7 @@ applies to.
If you get the error when using the SQL commands @code{SELECT ...
INTO OUTFILE} or @code{LOAD DATA INFILE}, your entry in the @code{user} table
-probably doesn't have the @strong{file} privilege enabled.
+probably doesn't have the @code{FILE} privilege enabled.
@item
@cindex configuration files
@@ -16831,7 +16384,7 @@ probably doesn't have the @strong{file} privilege enabled.
Remember that client programs will use connection parameters specified
in configuration files or environment variables. @xref{Environment
variables}. If a client seems to be sending the wrong default
-connection parameters when you don't specify them on the command line,
+connection parameters when you don't specify them on the command-line,
check your environment and the @file{.my.cnf} file in your home
directory. You might also check the system-wide MySQL
configuration files, though it is far less likely that client connection
@@ -16845,7 +16398,7 @@ If you make changes to the grant tables directly (using an @code{INSERT} or
@code{UPDATE} statement) and your changes seem to be ignored, remember
that you must issue a @code{FLUSH PRIVILEGES} statement or execute a
@code{mysqladmin flush-privileges} command to cause the server to re-read
-the privilege tables. Otherwise your changes have no effect until the
+the privilege tables. Otherwise, your changes have no effect until the
next time the server is restarted. Remember that after you set the
@code{root} password with an @code{UPDATE} command, you won't need to
specify it until after you flush the privileges, because the server
@@ -16858,16 +16411,16 @@ connect to the server with @code{mysql -u user_name db_name} or @code{mysql
@code{mysql} client, there is a problem with your program and not with the
access privileges. (Note that there is no space between @code{-p} and the
password; you can also use the @code{--password=your_pass} syntax to specify
-the password. If you use the @code{-p} option alone, MySQL will
+the password. If you use the @code{-p} option alone, MySQL will
prompt you for the password.)
@item
For testing, start the @code{mysqld} daemon with the
@code{--skip-grant-tables} option. Then you can change the MySQL
-grant tables and use the @code{mysqlaccess} script to check whether or not
+grant tables and use the @code{mysqlaccess} script to check whether
your modifications have the desired effect. When you are satisfied with your
changes, execute @code{mysqladmin flush-privileges} to tell the @code{mysqld}
-server to start using the new grant tables. @strong{Note:} Reloading the
+server to start using the new grant tables. @strong{Note}: reloading the
grant tables overrides the @code{--skip-grant-tables} option. This allows
you to tell the server to begin using the grant tables again without bringing
it down and restarting it.
@@ -16892,14 +16445,18 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
@node User Account Management, Disaster Prevention, Privilege system, MySQL Database Administration
@section MySQL User Account Management
+@c FIX: add section intro
+
@menu
* GRANT:: @code{GRANT} and @code{REVOKE} Syntax
* User names:: MySQL User Names and Passwords
* Privilege changes:: When Privilege Changes Take Effect
* Default privileges:: Setting Up the Initial MySQL Privileges
* Adding users:: Adding New Users to MySQL
+* User resources:: Limiting user resources
* Passwords:: Setting Up Passwords
* Password security:: Keeping Your Password Secure
+* Secure connections:: Using Secure Connections
@end menu
@@ -16918,9 +16475,16 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
@example
GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
ON @{tbl_name | * | *.* | db_name.*@}
- TO user_name [IDENTIFIED BY 'password']
+ TO user_name [IDENTIFIED BY [PASSWORD] 'password']
[, user_name [IDENTIFIED BY 'password'] ...]
- [WITH GRANT OPTION]
+ [REQUIRE
+ [@{SSL| X509@}]
+ [CIPHER cipher [AND]]
+ [ISSUER issuer [AND]]
+ [SUBJECT subject]]
+ [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # |
+ MAX_UPDATES_PER_HOUR # |
+ MAX_CONNECTIONS_PER_HOUR #]]
REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
ON @{tbl_name | * | *.* | db_name.*@}
@@ -16958,23 +16522,48 @@ For examples of how @code{GRANT} works, see @ref{Adding users}.
For the @code{GRANT} and @code{REVOKE} statements, @code{priv_type} may be
specified as any of the following:
-@example
-ALL PRIVILEGES FILE RELOAD
-ALTER INDEX SELECT
-CREATE INSERT SHUTDOWN
-DELETE PROCESS UPDATE
-DROP REFERENCES USAGE
-@end example
+@c FIX agl 2002-06-13 New table, need to measure colwidths!
+@multitable @columnfractions .30 .70
+@item @code{ALL [PRIVILEGES]} @tab Sets all simple privileges except @code{WITH GRANT OPTION}
+@item @code{ALTER} @tab Allows usage of @code{ALTER TABLE}
+@item @code{CREATE} @tab Allows usage of @code{CREATE TABLE}
+@item @code{CREATE TEMPORARY TABLES} @tab Allows usage of @code{CREATE TEMPORARY TABLE}
+@item @code{DELETE} @tab Allows usage of @code{DELETE}
+@item @code{DROP} @tab Allows usage of @code{DROP TABLE}.
+@item @code{EXECUTE} @tab Allows the user to run stored procedures (for MySQL 5.0)
+@item @code{FILE} @tab Allows usage of @code{SELECT ... INTO OUTFILE} and @code{LOAD DATA INFILE}.
+@item @code{INDEX} @tab Allows usage of @code{CREATE INDEX} and @code{DROP INDEX}
+@item @code{INSERT} @tab Allows usage of @code{INSERT}
+@item @code{LOCK TABLES} @tab Allows usage of @code{LOCK TABLES} on tables for which on has the @code{SELECT} privilege.
+@item @code{PROCESS} @tab Allows usage of @code{SHOW FULL PROCESSLIST}
+@item @code{REFERENCES} @tab For the future
+@item @code{RELOAD} @tab Allows usage of @code{FLUSH}
+@item @code{REPLICATION CLIENT} @tab Gives the right to the user to ask where the slaves/masters are.
+@item @code{REPLICATION SLAVE} @tab Needed for the replication slaves (to read binlogs from master).
+@item @code{SELECT} @tab Allows usage of @code{SELECT}
+@item @code{SHOW DATABASES} @tab @code{SHOW DATABASES} shows all databases.
+@item @code{SHUTDOWN} @tab Allows usage of @code{mysqladmin shutdown}
+@item @code{SUPER} @tab Allows one connect (once) even if max_connections is reached and execute commands @code{CHANGE MASTER}, @code{KILL thread}, @code{mysqladmin debug}, @code{PURGE MASTER LOGS} and @code{SET GLOBAL}
+@item @code{UPDATE} @tab Allows usage of @code{UPDATE}
+@item @code{USAGE} @tab Synonym for ``no privileges.''
+@end multitable
+
+@code{USAGE} can be used when you want to create a user that has no privileges.
+
+The privileges @code{CREATE TEMPORARY TABLES}, @code{EXECUTE},
+@code{LOCK TABLES}, @code{REPLICATION ...}, @code{SHOW DATABASES} and
+@code{SUPER} are new for in version 4.0.2. To use these new privileges
+after upgrading to 4.0.2, you have to run the
+@code{mysql_fix_privilege_tables} script.
-@code{ALL} is a synonym for @code{ALL PRIVILEGES}. @code{REFERENCES} is not
-yet implemented. @code{USAGE} is currently a synonym for ``no privileges.''
-It can be used when you want to create a user that has no privileges.
+In older MySQL versions, the @code{PROCESS} privilege gives the same
+rights as the new @code{SUPER} privilege.
-To revoke the @strong{grant} privilege from a user, use a @code{priv_type}
+To revoke the @code{GRANT} privilege from a user, use a @code{priv_type}
value of @code{GRANT OPTION}:
@example
-REVOKE GRANT OPTION ON ... FROM ...;
+mysql> REVOKE GRANT OPTION ON ... FROM ...;
@end example
The only @code{priv_type} values you can specify for a table are @code{SELECT},
@@ -16988,30 +16577,35 @@ you use a @code{column_list} clause) are @code{SELECT}, @code{INSERT}, and
You can set global privileges by using @code{ON *.*} syntax. You can set
database privileges by using @code{ON db_name.*} syntax. If you specify
@code{ON *} and you have a current database, you will set the privileges for
-that database. (@strong{WARNING:} If you specify @code{ON *} and you
-@emph{don't} have a current database, you will affect the global privileges!)
+that database. (@strong{Warning}: if you specify @code{ON *} and you
+@strong{don't} have a current database, you will affect the global privileges!)
In order to accommodate granting rights to users from arbitrary hosts,
MySQL supports specifying the @code{user_name} value in the form
@code{user@@host}. If you want to specify a @code{user} string
containing special characters (such as @samp{-}), or a @code{host} string
-containing special characters or wild-card characters (such as @samp{%}), you
+containing special characters or wildcard characters (such as @samp{%}), you
can quote the user or host name (for example, @code{'test-user'@@'test-hostname'}).
-You can specify wild cards in the hostname. For example,
+You can specify wildcards in the hostname. For example,
@code{user@@"%.loc.gov"} applies to @code{user} for any host in the
@code{loc.gov} domain, and @code{user@@"144.155.166.%"} applies to @code{user}
for any host in the @code{144.155.166} class C subnet.
The simple form @code{user} is a synonym for @code{user@@"%"}.
-@strong{NOTE:} If you allow anonymous users to connect to the MySQL
-server (which is the default), you should also add all local users as
-@code{user@@localhost} because otherwise the anonymous user entry for the
-local host in the @code{mysql.user} table will be used when the user tries to
-log into the MySQL server from the local machine! Anonymous users
-are defined by inserting entries with @code{User=''} into the
-@code{mysql.user} table. You can verify if this applies to you by executing
-this query:
+
+MySQL doesn't support wildcards in user names. Anonymous users are
+defined by inserting entries with @code{User=''} into the
+@code{mysql.user} table or creating an user with an empty name with the
+@code{GRANT} command.
+
+@strong{Note}: if you allow anonymous users to connect to the MySQL
+server, you should also grant privileges to all local users as
+@code{user@@localhost} because otherwise the anonymous user entry for
+the local host in the @code{mysql.user} table will be used when the user
+tries to log into the MySQL server from the local machine!
+
+You can verify if this applies to you by executing this query:
@example
mysql> SELECT Host,User FROM mysql.user WHERE User='';
@@ -17024,7 +16618,7 @@ characters.
The privileges for a table or column are formed from the
logical OR of the privileges at each of the four privilege
levels. For example, if the @code{mysql.user} table specifies that a
-user has a global @strong{select} privilege, this can't be denied by an
+user has a global @code{SELECT} privilege, this can't be denied by an
entry at the database, table, or column level.
The privileges for a column can be calculated as follows:
@@ -17054,11 +16648,16 @@ password will be set to the password specified by the @code{IDENTIFIED BY}
clause, if one is given. If the user already had a password, it is replaced
by the new one.
-@strong{WARNING:} If you create a new user but do not specify an
+If you don't want to send the password in clear text you can use the
+@code{PASSWORD} option followed by a scrambled password from SQL
+function @code{PASSWORD()} or the C API function
+@code{make_scrambled_password(char *to, const char *password)}.
+
+@strong{Warning}: if you create a new user but do not specify an
@code{IDENTIFIED BY} clause, the user has no password. This is insecure.
Passwords can also be set with the @code{SET PASSWORD} command.
-@xref{SET OPTION, , @code{SET OPTION}}.
+@xref{SET OPTION, , @code{SET}}.
If you grant privileges for a database, an entry in the @code{mysql.db}
table is created if needed. When all privileges for the database have been
@@ -17070,24 +16669,30 @@ statement).
The @code{WITH GRANT OPTION} clause gives the user the ability to give
to other users any privileges the user has at the specified privilege level.
-You should be careful to whom you give the @strong{grant} privilege, as two
+You should be careful to whom you give the @code{GRANT} privilege, as two
users with different privileges may be able to join privileges!
+@code{MAX_QUERIES_PER_HOUR #}, @code{MAX_UPDATES_PER_HOUR #} and
+@code{MAX_CONNECTIONS_PER_HOUR #} are new in MySQL version 4.0.2.
+These options limit the number of queries/updates and logins the user can
+do during one hour. If @code{#} is 0 (default), then this means that there
+are no limitations for that user. @xref{User resources}.
+
You cannot grant another user a privilege you don't have yourself;
-the @strong{grant} privilege allows you to give away only those privileges
+the @code{GRANT} privilege allows you to give away only those privileges
you possess.
-Be aware that when you grant a user the @strong{grant} privilege at a
+Be aware that when you grant a user the @code{GRANT} privilege at a
particular privilege level, any privileges the user already possesses (or
is given in the future!) at that level are also grantable by that user.
-Suppose you grant a user the @strong{insert} privilege on a database. If
-you then grant the @strong{select} privilege on the database and specify
-@code{WITH GRANT OPTION}, the user can give away not only the @strong{select}
-privilege, but also @strong{insert}. If you then grant the @strong{update}
+Suppose you grant a user the @code{INSERT} privilege on a database. If
+you then grant the @code{SELECT} privilege on the database and specify
+@code{WITH GRANT OPTION}, the user can give away not only the @code{SELECT}
+privilege, but also @code{INSERT}. If you then grant the @code{UPDATE}
privilege to the user on the database, the user can give away the
-@strong{insert}, @strong{select} and @strong{update}.
+@code{INSERT}, @code{SELECT} and @code{UPDATE}.
-You should not grant @strong{alter} privileges to a normal user. If you
+You should not grant @code{ALTER} privileges to a normal user. If you
do that, the user can try to subvert the privilege system by renaming
tables!
@@ -17118,8 +16723,8 @@ and not only for an username.
@item
ANSI SQL doesn't have global or database-level privileges, and ANSI SQL
doesn't support all privilege types that MySQL supports.
-MySQL doesn't support the ANSI SQL @code{TRIGGER}, @code{EXECUTE} or
-@code{UNDER} privileges.
+MySQL doesn't support the ANSI SQL @code{TRIGGER} or @code{UNDER}
+privileges.
@item
ANSI SQL privileges are structured in a hierarchal manner. If you remove
@@ -17128,10 +16733,10 @@ MySQL the granted privileges are not automatically revoked, but
you have to revoke these yourself if needed.
@item
-If you in MySQL have the @code{INSERT} grant on only part of the
+In MySQL, if you have the @code{INSERT} privilege on only some of the
columns in a table, you can execute @code{INSERT} statements on the
-table; The columns for which you don't have the @code{INSERT} privilege
-will set to their default values. ANSI SQL requires you to have the
+table; the columns for which you don't have the @code{INSERT} privilege
+will be set to their default values. ANSI SQL requires you to have the
@code{INSERT} privilege on all columns.
@item
@@ -17142,6 +16747,7 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the
MySQL grant tables.
@end itemize
+For a description of using @code{REQUIRE}, see @ref{Secure connections}.
@node User names, Privilege changes, GRANT, User Account Management
@subsection MySQL User Names and Passwords
@@ -17185,7 +16791,7 @@ the MySQL server!
MySQL users and their privileges are normally created with the
@code{GRANT} command. @xref{GRANT}.
-When you login to a MySQL server with a command line client you
+When you login to a MySQL server with a command-line client you
should specify the password with @code{--password=your-password}.
@xref{Connecting}.
@@ -17206,7 +16812,7 @@ or the short form:
mysql -u monty -p database_name
@end example
-Note that in the last example the password is @strong{NOT} 'database_name'.
+Note that in the last example the password is @strong{not} 'database_name'.
If you want to use the @code{-p} option to supply a password you should do so
like this:
@@ -17232,7 +16838,7 @@ Modifications to the grant tables that you perform using @code{GRANT},
If you modify the grant tables manually (using @code{INSERT}, @code{UPDATE},
etc.), you should execute a @code{FLUSH PRIVILEGES} statement or run
@code{mysqladmin flush-privileges} or @code{mysqladmin reload} to tell the
-server to reload the grant tables. Otherwise your changes will have @emph{no
+server to reload the grant tables. Otherwise, your changes will have @emph{no
effect} until you restart the server. If you change the grant tables manually
but forget to reload the privileges, you will be wondering why your changes
don't seem to make any difference!
@@ -17248,10 +16854,11 @@ request.
@item
Database privilege changes take effect at the next @code{USE db_name}
command.
-@end itemize
-Global privilege changes and password changes take effect the next time the
-client connects.
+@item
+Global privilege changes and password changes take effect the next time
+the client connects.
+@end itemize
@node Default privileges, Adding users, Privilege changes, User Account Management
@@ -17269,7 +16876,7 @@ After installing MySQL, you set up the initial access privileges by
running @code{scripts/mysql_install_db}.
@xref{Quick install}.
The @code{mysql_install_db} script starts up the @code{mysqld}
-server, then initializes the grant tables to contain the following set
+server, then initialises the grant tables to contain the following set
of privileges:
@itemize @bullet
@@ -17277,7 +16884,7 @@ of privileges:
The MySQL @code{root} user is created as a superuser who can do
anything. Connections must be made from the local host.
-@strong{NOTE:}
+@strong{Note}:
The initial @code{root} password is empty, so anyone can connect as @code{root}
@emph{without a password} and be granted all privileges.
@@ -17293,7 +16900,7 @@ Other privileges are denied. For example, normal users can't use
@code{mysqladmin shutdown} or @code{mysqladmin processlist}.
@end itemize
-@strong{NOTE:} The default privileges are different for Windows.
+@strong{Note}: the default privileges are different for Windows.
@xref{Windows running}.
Because your installation is initially wide open, one of the first things you
@@ -17303,17 +16910,17 @@ password using the @code{PASSWORD()} function):
@example
shell> mysql -u root mysql
-mysql> UPDATE user SET Password=PASSWORD('new_password')
- WHERE user='root';
-mysql> FLUSH PRIVILEGES;
+mysql> SET PASSWORD FOR root@@localhost=PASSWORD('new_password');
@end example
-You can, in MySQL Version 3.22 and above, use the @code{SET PASSWORD}
-statement:
+If you know what you are doing, you can also directly manipulate the
+privilege tables:
@example
shell> mysql -u root mysql
-mysql> SET PASSWORD FOR root=PASSWORD('new_password');
+mysql> UPDATE user SET Password=PASSWORD('new_password')
+ -> WHERE user='root';
+mysql> FLUSH PRIVILEGES;
@end example
Another way to set the password is by using the @code{mysqladmin} command:
@@ -17342,7 +16949,7 @@ See the @code{scripts/mysql_install_db} script to see how it sets up
the default privileges. You can use this as a basis to see how to
add other users.
-If you want the initial privileges to be different than those just described
+If you want the initial privileges to be different from those just described
above, you can modify @code{mysql_install_db} before you run it.
@cindex grant tables, re-creating
@@ -17354,13 +16961,13 @@ the database directory, which is listed when you run @code{mysqld
--help}.) Then run the @code{mysql_install_db} script, possibly after
editing it first to have the privileges you want.
-@strong{NOTE:} For MySQL versions older than Version 3.22.10,
-you should NOT delete the @file{.frm} files. If you accidentally do this,
+@strong{Note}: for MySQL versions older than Version 3.22.10,
+you should not delete the @file{.frm} files. If you accidentally do this,
you should copy them back from your MySQL distribution before
running @code{mysql_install_db}.
-@node Adding users, Passwords, Default privileges, User Account Management
+@node Adding users, User resources, Default privileges, User Account Management
@subsection Adding New Users to MySQL
@findex GRANT statement
@@ -17375,27 +16982,26 @@ or by manipulating the MySQL grant tables directly. The
preferred method is to use @code{GRANT} statements, because they are
more concise and less error-prone. @xref{GRANT}.
-There is also a lot of contributed programs like @code{phpmyadmin} that
-can be used to create and administrate users. @xref{Contrib}.
+There are also a lot of contributed programs like @code{phpmyadmin}
+that can be used to create and administrate users. @xref{Portals}.
-The examples below show how to use the @code{mysql} client to set up new
+The following examples show how to use the @code{mysql} client to set up new
users. These examples assume that privileges are set up according to the
defaults described in the previous section. This means that to make changes,
you must be on the same machine where @code{mysqld} is running, you must
connect as the MySQL @code{root} user, and the @code{root} user must
-have the @strong{insert} privilege for the @code{mysql} database and the
-@strong{reload} administrative privilege. Also, if you have changed the
-@code{root} user password, you must specify it for the @code{mysql} commands
-below.
+have the @code{INSERT} privilege for the @code{mysql} database and the
+@code{RELOAD} administrative privilege. Also, if you have changed the
+@code{root} user password, you must specify it for the @code{mysql} commands here.
You can add new users by issuing @code{GRANT} statements:
@example
shell> mysql --user=root mysql
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@@localhost
- IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
+ -> IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@@"%"
- IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
+ -> IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO admin@@localhost;
mysql> GRANT USAGE ON *.* TO dummy@@localhost;
@end example
@@ -17415,7 +17021,7 @@ earlier in the @code{user} table sort order.
@item admin
A user who can connect from @code{localhost} without a password and who is
-granted the @strong{reload} and @strong{process} administrative privileges.
+granted the @code{RELOAD} and @code{PROCESS} administrative privileges.
This allows the user to execute the @code{mysqladmin reload},
@code{mysqladmin refresh}, and @code{mysqladmin flush-*} commands, as well as
@code{mysqladmin processlist} . No database-related privileges are granted.
@@ -17423,7 +17029,7 @@ This allows the user to execute the @code{mysqladmin reload},
@item dummy
A user who can connect without a password, but only from the local host. The
-global privileges are all set to @code{'N'} --- the @code{USAGE} privilege
+global privileges are all set to @code{'N'}@-the @code{USAGE} privilege
type allows you to create a user with no privileges. It is assumed that you
will grant database-specific privileges later.
@end table
@@ -17437,13 +17043,13 @@ tables:
@example
shell> mysql --user=root mysql
mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('some_pass'),
- 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+ -> 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user VALUES('%','monty',PASSWORD('some_pass'),
- 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+ -> 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user SET Host='localhost',User='admin',
- Reload_priv='Y', Process_priv='Y';
+ -> Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
- VALUES('localhost','dummy','');
+ -> VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;
@end example
@@ -17474,17 +17080,17 @@ commands:
@example
shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
- ON bankaccount.*
- TO custom@@localhost
- IDENTIFIED BY 'stupid';
+ -> ON bankaccount.*
+ -> TO custom@@localhost
+ -> IDENTIFIED BY 'stupid';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
- ON expenses.*
- TO custom@@whitehouse.gov
- IDENTIFIED BY 'stupid';
+ -> ON expenses.*
+ -> TO custom@@whitehouse.gov
+ -> IDENTIFIED BY 'stupid';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
- ON customer.*
- TO custom@@'%'
- IDENTIFIED BY 'stupid';
+ -> ON customer.*
+ -> TO custom@@'%'
+ -> IDENTIFIED BY 'stupid';
@end example
The reason that we do to grant statements for the user 'custom' is that
@@ -17498,25 +17104,25 @@ run these commands (note the @code{FLUSH PRIVILEGES} at the end):
@example
shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
- VALUES('localhost','custom',PASSWORD('stupid'));
+ -> VALUES('localhost','custom',PASSWORD('stupid'));
mysql> INSERT INTO user (Host,User,Password)
- VALUES('server.domain','custom',PASSWORD('stupid'));
+ -> VALUES('server.domain','custom',PASSWORD('stupid'));
mysql> INSERT INTO user (Host,User,Password)
- VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
+ -> VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
mysql> INSERT INTO db
- (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
- Create_priv,Drop_priv)
- VALUES
- ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
+ -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
+ -> Create_priv,Drop_priv)
+ -> VALUES
+ -> ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
- (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
- Create_priv,Drop_priv)
- VALUES
- ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
+ -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
+ -> Create_priv,Drop_priv)
+ -> VALUES
+ -> ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
- (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
- Create_priv,Drop_priv)
- VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y');
+ -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
+ -> Create_priv,Drop_priv)
+ -> VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;
@end example
@@ -17535,27 +17141,85 @@ domain, you can issue a @code{GRANT} statement like the following:
@example
mysql> GRANT ...
- ON *.*
- TO myusername@@"%.mydomainname.com"
- IDENTIFIED BY 'mypassword';
+ -> ON *.*
+ -> TO myusername@@"%.mydomainname.com"
+ -> IDENTIFIED BY 'mypassword';
@end example
To do the same thing by modifying the grant tables directly, do this:
@example
mysql> INSERT INTO user VALUES ('%.mydomainname.com', 'myusername',
- PASSWORD('mypassword'),...);
+ -> PASSWORD('mypassword'),...);
mysql> FLUSH PRIVILEGES;
@end example
You can also use @code{xmysqladmin}, @code{mysql_webadmin}, and even
@code{xmysql} to insert, change, and update values in the grant tables.
-You can find these utilities in the
-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory of the MySQL
-Website}.
+You can find these utilities in the Contrib directory of the
+MySQL web site (@uref{http://www.mysql.com/Downloads/Contrib/}).
+
+@node User resources, Passwords, Adding users, User Account Management
+@subsection Limiting user resources
+
+Starting from MySQL 4.0.2 one can limit certain resources per user.
+
+So far, the only available method of limiting usage of MySQL
+server resources has been setting the @code{max_user_connections}
+startup variable to a non-zero value. But this method is strictly
+global and does not allow for management of individual users, which
+could be of particular interest to Internet Service Providers.
+
+Therefore, management of three resources is introduced on the
+individual user level:
+
+@itemize @bullet
+@item Number of all queries per hour:
+All commands that could be run by a user.
+@item Number of all updates per hour:
+Any command that changes any table or database.
+@item Number of connections made per hour:
+New connections opened per hour.
+@end itemize
+
+A user in the aforementioned context is a single entry in the
+@code{user} table, which is uniquely identified by its @code{user}
+and @code{host} columns.
+
+All users are by default not limited in using the above resources,
+unless the limits are granted to them. These limits can be granted
+@strong{only} via global @code{GRANT (*.*)}, using this syntax:
+
+@example
+GRANT ... WITH MAX_QUERIES_PER_HOUR N1
+ MAX_UPDATES_PER_HOUR N2
+ MAX_CONNECTIONS_PER_HOUR N3;
+@end example
+
+One can specify any combination of the above resources.
+N1, N2 and N3 are integers and stands for count / hour.
+If user reaches any of the above limits withing one hour, his
+connection will be terminated or refused and the appropriate error
+message shall be issued.
-@node Passwords, Password security, Adding users, User Account Management
+Current usage values for a particular user can be flushed (set to zero)
+by issuing a @code{GRANT} statement with any of the above clauses,
+including a @code{GRANT} statement with the current values.
+
+Also, current values for all users will be flushed if privileges are
+reloaded (in the server or using @code{mysqladmin reload})
+or if the @code{FLUSH USER_RESOURCES} command is issued.
+
+The feature is enabled as soon as a single user is granted with any
+of the limiting @code{GRANT} clauses.
+
+As a prerequisite for enabling this feature, the @code{user} table in
+the @code{mysql} database must contain the additional columns, as
+defined in the table creation scripts @code{mysql_install_db} and
+@code{mysql_install_db.sh} in @file{scripts} subdirectory.
+
+@node Passwords, Password security, User resources, User Account Management
@subsection Setting Up Passwords
@findex PASSWORD()
@@ -17577,7 +17241,7 @@ passwords like this:
@example
shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
- VALUES('%','jeffrey','biscuit');
+ -> VALUES('%','jeffrey','biscuit');
mysql> FLUSH PRIVILEGES;
@end example
@@ -17604,7 +17268,7 @@ instead:
@example
mysql> INSERT INTO user (Host,User,Password)
- VALUES('%','jeffrey',PASSWORD('biscuit'));
+ -> VALUES('%','jeffrey',PASSWORD('biscuit'));
@end example
You must also use the @code{PASSWORD()} function when you use @code{SET
@@ -17629,19 +17293,19 @@ or
shell> mysqladmin -u jeffrey password biscuit
@end example
-@strong{NOTE:} @code{PASSWORD()} does not perform password encryption in the
+@strong{Note}: @code{PASSWORD()} does not perform password encryption in the
same way that Unix passwords are encrypted. You should not assume that if
your Unix password and your MySQL password are the same, that
@code{PASSWORD()} will result in the same encrypted value as is stored in the
Unix password file. @xref{User names}.
-@node Password security, , Passwords, User Account Management
+@node Password security, Secure connections, Passwords, User Account Management
@subsection Keeping Your Password Secure
It is inadvisable to specify your password in a way that exposes it to
discovery by other users. The methods you can use to specify your password
-when you run client programs are listed below, along with an assessment of
+when you run client programs are listed here, along with an assessment of
the risks of each method:
@itemize @bullet
@@ -17656,8 +17320,8 @@ with your other applications).
Use a @code{-pyour_pass} or @code{--password=your_pass} option on the command
line. This is convenient but insecure, because your password becomes visible
to system status programs (such as @code{ps}) that may be invoked by other
-users to display command lines. (MySQL clients typically overwrite
-the command-line argument with zeroes during their initialization sequence,
+users to display command-lines. (MySQL clients typically overwrite
+the command-line argument with zeroes during their initialisation sequence,
but there is still a brief interval during which the value is visible.)
@item
@@ -17675,7 +17339,7 @@ Enter password: ********
The @samp{*} characters represent your password.
It is more secure to enter your password this way than to specify it on the
-command line because it is not visible to other users. However, this method
+command-line because it is not visible to other users. However, this method
of entering a password is suitable only for programs that you run
interactively. If you want to invoke a client from a script that runs
non-interactively, there is no opportunity to enter the password from the
@@ -17712,10 +17376,189 @@ All in all, the safest methods are to have the client program prompt for the
password or to specify the password in a properly protected @file{.my.cnf}
file.
+@node Secure connections, , Password security, User Account Management
+@subsection Using Secure Connections
+
+@cindex OpenSSL
+@cindex SSL and X509 Basics
+
+@menu
+* Secure basics:: Basics
+* Secure requirements:: Requirements
+* Secure GRANT:: @code{GRANT} Options
+@end menu
+
+@node Secure basics, Secure requirements, Secure connections, Secure connections
+@subsubsection Basics
+
+MySQL has support for SSL encrypted connections. To understand how MySQL
+uses SSL, we need to explain some basics about SSL and X509. People who
+are already aware of it can skip this part.
+
+By default, MySQL uses unencrypted connections between client and
+server. This means that someone could watch all your traffic and look at
+the data being sent/received. Actually, they could even change the data
+while it is in transit between client and server. Sometimes you need to
+move really secret data over public networks and in such a case using an
+unencrypted connection is unacceptable.
+
+SSL is a protocol which uses different encryption algorithms to ensure
+that data which comes from public network can be trusted. It has
+mechanisms to detect any change, loss or replay of data. SSL also
+incorpores algorithms to recognise and provide identity verification
+using the X509 standard.
+
+@cindex What is encryption
+Encryption is the way to make any kind of data unreadable. In fact,
+today's practice requires many additional security elements from
+encryption algorithms. They should resist many kind of known attacks
+like just messing with order of encrypted messages or replaying data
+twice.
+
+@cindex What is X509/Certificate?
+X509 is a standard that makes it possible to identify someone in the
+Internet. It is most commonly used in e-commerce applications. In basic
+terms, there should be some company called "Certificate Authority" which
+assigns electronic certificates to anyone who needs them. Certificates
+rely on asymmetric encryption algorithms which have two encryption keys
+- public and secret. A certificate owner can prove his identity by
+showing his certificate to other party. A certificate consists of his
+owner's public key. Any data encrypted with this public key can only be
+decrypted using the corresponding secret key, which is held by the owner
+of the certificate.
+
+MySQL doesn't use encrypted on connections by default, because this
+would make the client/server protocol much slower. Any kind of
+additional functionality requires computer to do additional work and
+encrypting data is CPU-intensive operation require time and can delay
+MySQL main tasks. By default MySQL is tuned to be fast as possible.
+
+If you need more information about SSL/X509/encryption, you should use
+your favourite internet search engine and search for keywords you are
+interested in.
+
+@node Secure requirements, Secure GRANT, Secure basics, Secure connections
+@subsubsection Requirements
+
+To get secure connections to work with MySQL you must do the following:
+
+@enumerate
+@item
+Install the OpenSSL library. We have tested MySQL with OpenSSL 0.9.6.
+@uref{http://www.openssl.org/}.
+@item
+Configure MySQL with @code{--with-vio --with-openssl}.
+@item
+If you are using an old MySQL installation, you have to update your
+@code{mysql.user} table with some new columns. You can do this by
+running the @code{mysql_fix_privilege_tables.sh} script.
+@item
+You can check if a running mysqld server supports OpenSSL by
+examining if @code{SHOW VARIABLES LIKE 'have_openssl'} returns @code{YES}.
+@end enumerate
+
+
+@node Secure GRANT, , Secure requirements, Secure connections
+@subsubsection @code{GRANT} Options
+
+@cindex SSL related options
+@findex REQUIRE GRANT option
+@findex GRANT statemenet
+
+MySQL can check X509 certificate attributes in addition to the
+normal username/password scheme. All the usual options are still
+required (username, password, IP address mask, database/table name).
+
+There are different possibilities to limit connections:
+
+@itemize @bullet
+@item
+Without any SSL/X509 options, all kind of encrypted/unencrypted
+connections are allowed if username and password are valid.
+
+@item
+@code{REQUIRE SSL} option limits the server to allow only SSL
+encrypted connections. Note that this option can be omitted
+if there are any ACL records which allow non-SSL connections.
+
+@example
+mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost
+ -> IDENTIFIED BY "goodsecret" REQUIRE SSL;
+@end example
+
+@item
+@code{REQUIRE X509} means that client should have valid certificate
+but we do not care about the exact certificate, issuer or subject.
+The only restriction is that it should be possible to verify its
+signature with one of the CA certificates.
+
+@example
+mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost
+ -> IDENTIFIED BY "goodsecret" REQUIRE X509;
+@end example
+
+@item
+@code{REQUIRE ISSUER issuer} makes connection more restrictive: now
+client must present a valid X509 certificate issued by CA "issuer".
+Using X509 certificates always implies encryption, so the option "SSL"
+is not neccessary anymore.
+
+@example
+mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost
+ -> IDENTIFIED BY "goodsecret"
+ -> REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki,
+ "> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com";
+@end example
+
+@item
+@code{REQUIRE SUBJECT subject} requires clients to have valid X509
+certificate with subject "subject" on it. If client have valid
+certificate but having different "subject" then the connection is
+still not allowed.
+
+@example
+mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost
+ -> IDENTIFIED BY "goodsecret"
+ -> REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn,
+ "> O=MySQL demo client certificate,
+ "> CN=Tonu Samuel/Email=tonu@@mysql.com";
+@end example
+
+@item
+@code{REQUIRE CIPHER cipher} is needed to assure enough strong ciphers
+and keylengths will be used. SSL itself can be weak if old algorithms
+with short encryption keys are used. Using this option, we can ask for
+some exact cipher method to allow a connection.
+
+@example
+mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost
+ -> IDENTIFIED BY "goodsecret"
+ -> REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA";
+@end example
+
+Also it is allowed to combine these options with each other like this:
+
+@example
+mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost
+ -> IDENTIFIED BY "goodsecret"
+ -> REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn,
+ "> O=MySQL demo client certificate,
+ "> CN=Tonu Samuel/Email=tonu@@mysql.com"
+ -> AND ISSUER "C=FI, ST=Some-State, L=Helsinki,
+ "> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com"
+ -> AND CIPHER "EDH-RSA-DES-CBC3-SHA";
+@end example
+
+But it is not allowed to use any option twice. Only different
+options can be mixed.
+@end itemize
+
@node Disaster Prevention, Database Administration, User Account Management, MySQL Database Administration
@section Disaster Prevention and Recovery
+@c FIX: add section intro
+
@menu
* Backup:: Database Backups
* BACKUP TABLE:: @code{BACKUP TABLE} Syntax
@@ -17780,8 +17623,8 @@ you executed @code{mysqldump}.
If you have to restore something, try to recover your tables using
@code{REPAIR TABLE} or @code{myisamchk -r} first. That should work in
99.9% of all cases. If @code{myisamchk} fails, try the following
-procedure: (This will only work if you have started MySQL with
-@code{--log-update}. @xref{Update log}.):
+procedure (this will only work if you have started MySQL with
+@code{--log-update}, @pxref{Update log}):
@enumerate
@item
@@ -17813,23 +17656,23 @@ If you get performance problems in making backups on your system, you can
solve this by setting up replication and do the backups on the slave
instead of on the master. @xref{Replication Intro}.
-If you are using a Veritas file system, you can do:
+If you are using a Veritas filesystem, you can do:
@enumerate
-@item
-Execute in a client (perl ?) @code{FLUSH TABLES WITH READ LOCK}
+@item
+From a client (or Perl), execute: @code{FLUSH TABLES WITH READ LOCK}.
@item
-Fork a shell or execute in another client @code{mount vxfs snapshot}.
+From another shell, execute: @code{mount vxfs snapshot}.
@item
-Execute in the first client @code{UNLOCK TABLES}
+From the first client, execute: @code{UNLOCK TABLES}.
@item
-Copy files from snapshot
+Copy files from snapshot.
@item
-Unmount snapshot
+Unmount snapshot.
@end enumerate
@@ -17844,12 +17687,12 @@ Unmount snapshot
BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory'
@end example
-Make a copy of all the table files to the backup directory that are the
-minimum needed to restore it. Currenlty only works for @code{MyISAM}
-tables. For @code{MyISAM} table, copies @code{.frm} (definition) and
-@code{.MYD} (data) files. The index file can be rebuilt from those two.
+Copies to the backup directory the minimum number of table files needed
+to restore the table. Currently only works for @code{MyISAM} tables.
+For @code{MyISAM} tables, copies @file{.frm} (definition) and
+@file{.MYD} (data) files. The index file can be rebuilt from those two.
-Before using this command, please see @xref{Backup}.
+Before using this command, please see @ref{Backup}.
During the backup, read lock will be held for each table, one at time,
as they are being backed up. If you want to backup several tables as
@@ -17858,7 +17701,7 @@ lock for each table in the group.
The command returns a table with the following columns:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .15 .40
@item @strong{Column} @tab @strong{Value}
@item Table @tab Table name
@item Op @tab Always ``backup''
@@ -17889,7 +17732,7 @@ more keys you have, the longer it is going to take. Just as
The command returns a table with the following columns:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .15 .40
@item @strong{Column} @tab @strong{Value}
@item Table @tab Table name
@item Op @tab Always ``restore''
@@ -17909,7 +17752,7 @@ CHECK TABLE tbl_name[,tbl_name...] [option [option...]]
option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
@end example
-@code{CHECK TABLE} only works on @code{MyISAM} tables. On
+@code{CHECK TABLE} only works on @code{MyISAM} and @code{InnoDB} tables. On
@code{MyISAM} tables it's the same thing as running @code{myisamchk -m
table_name} on the table.
@@ -17918,7 +17761,7 @@ If you don't specify any option @code{MEDIUM} is used.
Checks the table(s) for errors. For @code{MyISAM} tables the key statistics
is updated. The command returns a table with the following columns:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .15 .40
@item @strong{Column} @tab @strong{Value}
@item Table @tab Table name.
@item Op @tab Always ``check''.
@@ -17935,17 +17778,17 @@ told MySQL that there wasn't any need to check the table.
The different check types stand for the following:
-@multitable @columnfractions .20 .80
+@multitable @columnfractions .15 .85
@item @strong{Type} @tab @strong{Meaning}
@item @code{QUICK} @tab Don't scan the rows to check for wrong links.
@item @code{FAST} @tab Only check tables which haven't been closed properly.
@item @code{CHANGED} @tab Only check tables which have been changed since last check or haven't been closed properly.
-@item @code{MEDIUM} @tab Scan rows to verify that deleted links are ok. This also calculates a key checksum for the rows and verifies this with a calcualted checksum for the keys.
-@item @code{EXTENDED} @tab Do a full key lookup for all keys for each row. This ensures that the table is 100 % consistent, but will take a long time!
+@item @code{MEDIUM} @tab Scan rows to verify that deleted links are okay. This also calculates a key checksum for the rows and verifies this with a calcualted checksum for the keys.
+@item @code{EXTENDED} @tab Do a full key lookup for all keys for each row. This ensures that the table is 100% consistent, but will take a long time!
@end multitable
-For dynamic sized @code{MyISAM} tables a started check will always
-do a @code{MEDIUM} check. For static size rows we skip the row scan
+For dynamically sized @code{MyISAM} tables a started check will always
+do a @code{MEDIUM} check. For static size rows we skip the row scan
for @code{QUICK} and @code{FAST} as the rows are very seldom corrupted.
You can combine check options as in:
@@ -17954,34 +17797,35 @@ You can combine check options as in:
CHECK TABLE test_table FAST QUICK;
@end example
-Which only would do a quick check on the table if it wasn't closed properly.
+Which would simply do a quick check on the table to see whether it was
+closed properly.
-@strong{NOTE:} that in some case @code{CHECK TABLE} will change the
+@strong{Note}: that in some case @code{CHECK TABLE} will change the
table! This happens if the table is marked as 'corrupted' or 'not
closed properly' but @code{CHECK TABLE} didn't find any problems in the
-table. In this case @code{CHECK TABLE} will mark the table as ok.
+table. In this case @code{CHECK TABLE} will mark the table as okay.
If a table is corrupted, then it's most likely that the problem is in
the indexes and not in the data part. All of the above check types
-checks the indexes throughly and should thus find most errors.
+checks the indexes thoroughly and should thus find most errors.
-If you just want to check a table that you assume is ok, you should use
-no check options or the @code{QUICK} option. The later should be used
+If you just want to check a table that you assume is okay, you should use
+no check options or the @code{QUICK} option. The latter should be used
when you are in a hurry and can take the very small risk that
-@code{QUICK} didn't find an error in the data file (In most cases
+@code{QUICK} didn't find an error in the datafile. (In most cases
MySQL should find, under normal usage, any error in the data
file. If this happens then the table will be marked as 'corrupted',
-in which case the table can't be used until it's repaired).
+in which case the table can't be used until it's repaired.)
@code{FAST} and @code{CHANGED} are mostly intended to be used from a
script (for example to be executed from cron) if you want to check your
table from time to time. In most cases you @code{FAST} is to be prefered
over @code{CHANGED}. (The only case when it isn't is when you suspect a
-bug you have found a bug in the @code{MyISAM} code.).
+bug you have found a bug in the @code{MyISAM} code.)
@code{EXTENDED} is only to be used after you have run a normal check but
still get strange errors from a table when MySQL tries to
-update a row or find a row by key (this is VERY unlikely to happen if a
+update a row or find a row by key (this is very unlikely if a
normal check has succeeded!).
Some things reported by check table, can't be corrected automatically:
@@ -17991,14 +17835,14 @@ Some things reported by check table, can't be corrected automatically:
@code{Found row where the auto_increment column has the value 0}.
This means that you have in the table a row where the
-@code{auto_increment} index column contains the value 0.
-(It's possible to create a row where the auto_increment column is 0 by
-explicitely setting the column to 0 with an @code{UPDATE} statement)
+@code{AUTO_INCREMENT} index column contains the value 0.
+(It's possible to create a row where the @code{AUTO_INCREMENT} column is 0 by
+explicitly setting the column to 0 with an @code{UPDATE} statement)
This isn't an error in itself, but could cause trouble if you decide to
dump the table and restore it or do an @code{ALTER TABLE} on the
-table. In this case the auto_increment column will change value,
-according to the rules of auto_increment columns, which could cause
+table. In this case the @code{AUTO_INCREMENT} column will change value,
+according to the rules of @code{AUTO_INCREMENT} columns, which could cause
problems like a duplicate key error.
To get rid of the warning, just execute an @code{UPDATE} statement
@@ -18012,7 +17856,7 @@ to set the column to some other value than 0.
@findex REPAIR TABLE
@example
-REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED]
+REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM]
@end example
@code{REPAIR TABLE} only works on @code{MyISAM} tables and is the same
@@ -18026,7 +17870,7 @@ try to find the reason for this! @xref{Crashing}. @xref{MyISAM table problems}.
@code{REPAIR TABLE} repairs a possible corrupted table. The command returns a
table with the following columns:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .15 .40
@item @strong{Column} @tab @strong{Value}
@item Table @tab Table name
@item Op @tab Always ``repair''
@@ -18045,10 +17889,14 @@ If @code{QUICK} is given then MySQL will try to do a
@code{REPAIR} of only the index tree.
If you use @code{EXTENDED} then MySQL will create the index row
-by row instead of creating one index at a time with sorting; This may be
+by row instead of creating one index at a time with sorting; this may be
better than sorting on fixed-length keys if you have long @code{char()}
keys that compress very good.
+As of @code{MySQL} 4.0.2 there is a @code{USE_FRM} mode for @code{REPAIR}.
+Use it if the @file{.MYI} file is missing or if its header is corrupted.
+In this mode MySQL will recreate the table, using information from the
+@file{.frm} file. This kind of repair cannot be done with @code{myisamchk}.
@node Table maintenance, Maintenance regimen, REPAIR TABLE, Disaster Prevention
@subsection Using @code{myisamchk} for Table Maintenance and Crash Recovery
@@ -18057,29 +17905,29 @@ Starting with MySQL Version 3.23.13, you can check MyISAM
tables with the @code{CHECK TABLE} command. @xref{CHECK TABLE}. You can
repair tables with the @code{REPAIR TABLE} command. @xref{REPAIR TABLE}.
-To check/repair MyISAM tables (@code{.MYI} and @code{.MYD}) you should
+To check/repair MyISAM tables (@file{.MYI} and @file{.MYD}) you should
use the @code{myisamchk} utility. To check/repair ISAM tables
-(@code{.ISM} and @code{.ISD}) you should use the @code{isamchk}
+(@file{.ISM} and @file{.ISD}) you should use the @code{isamchk}
utility. @xref{Table types}.
In the following text we will talk about @code{myisamchk}, but everything
also applies to the old @code{isamchk}.
You can use the @code{myisamchk} utility to get information about your
-database tables, check and repair them, or optimize them. The following
+database tables, check and repair them, or optimise them. The following
sections describe how to invoke @code{myisamchk} (including a
description of its options), how to set up a table maintenance schedule,
and how to use @code{myisamchk} to perform its various functions.
You can, in most cases, also use the command @code{OPTIMIZE TABLES} to
-optimize and repair tables, but this is not as fast or reliable (in case
+optimise and repair tables, but this is not as fast or reliable (in case
of real fatal errors) as @code{myisamchk}. On the other hand,
@code{OPTIMIZE TABLE} is easier to use and you don't have to worry about
flushing tables.
@xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.
Even that the repair in @code{myisamchk} is quite secure, it's always a
-good idea to make a backup BEFORE doing a repair (or anything that could
+good idea to make a backup @emph{before} doing a repair (or anything that could
make a lot of changes to a table)
@menu
@@ -18092,7 +17940,7 @@ make a lot of changes to a table)
* Crash recovery:: Using @code{myisamchk} for Crash Recovery
* Check:: How to Check Tables for Errors
* Repair:: How to Repair Tables
-* Optimization:: Table Optimization
+* Optimisation:: Table Optimisation
@end menu
@@ -18106,20 +17954,20 @@ shell> myisamchk [options] tbl_name
@end example
The @code{options} specify what you want @code{myisamchk} to do. They are
-described below. (You can also get a list of options by invoking
+described here. (You can also get a list of options by invoking
@code{myisamchk --help}.) With no options, @code{myisamchk} simply checks your
table. To get more information or to tell @code{myisamchk} to take corrective
-action, specify options as described below and in the following sections.
+action, specify options as described here and in the following sections.
@code{tbl_name} is the database table you want to check/repair. If you run
@code{myisamchk} somewhere other than in the database directory, you must
specify the path to the file, because @code{myisamchk} has no idea where your
-database is located. Actually, @code{myisamchk} doesn't care whether or not
+database is located. Actually, @code{myisamchk} doesn't care whether
the files you are working on are located in a database directory; you can
copy the files that correspond to a database table into another location and
perform recovery operations on them there.
-You can name several tables on the @code{myisamchk} command line if you
+You can name several tables on the @code{myisamchk} command-line if you
wish. You can also specify a name as an index file
name (with the @file{.MYI} suffix), which allows you to specify all
tables in a directory by using the pattern @file{*.MYI}.
@@ -18137,7 +17985,7 @@ by specifying the path to the directory:
shell> myisamchk /path/to/database_dir/*.MYI
@end example
-You can even check all tables in all databases by specifying a wild card
+You can even check all tables in all databases by specifying a wildcard
with the path to the MySQL data directory:
@example
@@ -18155,8 +18003,11 @@ If you want to check all tables and repair all tables that are corrupted,
you can use the following line:
@example
-myisamchk --silent --force --fast --update-state -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M /path/to/datadir/*/*.MYI
-isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M /path/to/datadir/*/*.ISM
+myisamchk --silent --force --fast --update-state -O key_buffer=64M \
+ -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M \
+ /path/to/datadir/*/*.MYI
+isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M \
+ -O read_buffer=1M -O write_buffer=1M /path/to/datadir/*/*.ISM
@end example
The above assumes that you have more than 64 M free.
@@ -18177,14 +18028,6 @@ tables while you are running @code{myisamchk}. In MySQL Version 3.23
the easiest way to avoid this problem is to use @code{CHECK TABLE}
instead of @code{myisamchk} to check tables.
-@menu
-* myisamchk general options:: General Options for @code{myisamchk}
-* myisamchk check options:: Check Options for @code{myisamchk}
-* myisamchk repair options:: Repair Options for myisamchk
-* myisamchk other options:: Other Options for @code{myisamchk}
-@end menu
-
-
@node myisamchk general options, myisamchk check options, myisamchk syntax, Table maintenance
@subsubsection General Options for @code{myisamchk}
@@ -18202,7 +18045,8 @@ Display a help message and exit.
@item -O var=option, --set-variable var=option
Set the value of a variable. The possible variables and their default values
for myisamchk can be examined with @code{myisamchk --help}:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .20 .10
+@item @strong{Variable} @tab @strong{Value}
@item key_buffer_size @tab 523264
@item read_buffer_size @tab 262136
@item write_buffer_size @tab 262136
@@ -18223,8 +18067,6 @@ through the key buffer is used in the following cases:
@item
If you use @code{--safe-recover}.
@item
-If you are using a @code{FULLTEXT} index.
-@item
If the temporary files needed to sort the keys would be more than twice
as big as when creating the key file directly. This is often the case
when you have big @code{CHAR}, @code{VARCHAR} or @code{TEXT} keys as the
@@ -18252,7 +18094,7 @@ Print the @code{myisamchk} version and exit.
@item -w or, --wait
Instead of giving an error if the table is locked, wait until the table
is unlocked before continuing. Note that if you are running @code{mysqld}
-on the table with @code{--skip-locking}, the table can only be locked
+on the table with @code{--skip-external-locking}, the table can only be locked
by another @code{myisamchk} command.
@end table
@@ -18269,7 +18111,7 @@ Check table for errors. This is the default operation if you are not
giving @code{myisamchk} any options that override this.
@item -e or --extend-check
-Check the table VERY thoroughly (which is quite slow if you have many
+Check the table very thoroughly (which is quite slow if you have many
indexes). This option should only be used in extreme cases. Normally,
@code{myisamchk} or @code{myisamchk --medium-check} should, in most
cases, be able to find out if there are any errors in the table.
@@ -18293,11 +18135,11 @@ Should, however, be good enough for most cases.
Store in the @file{.MYI} file when the table was checked and if the table crashed. This should be used to get full benefit of the
@code{--check-only-changed} option, but you shouldn't use this
option if the @code{mysqld} server is using the table and you are
-running @code{mysqld} with @code{--skip-locking}.
+running @code{mysqld} with @code{--skip-external-locking}.
@item -T or --read-only
Don't mark table as checked. This is useful if you use @code{myisamchk}
to check a table that is in use by some other application that doesn't
-use locking (like @code{mysqld --skip-locking}).
+use locking (like @code{mysqld --skip-external-locking}).
@end table
@@ -18312,9 +18154,9 @@ The following options are used if you start @code{myisamchk} with
@table @code
@item -D # or --data-file-length=#
-Max length of data file (when re-creating data file when it's 'full').
+Max length of datafile (when re-creating datafile when it's 'full').
@item -e or --extend-check
-Try to recover every possible row from the data file.
+Try to recover every possible row from the datafile.
Normally this will also find a lot of garbage rows. Don't use this option
if you are not totally desperate.
@item -f or --force
@@ -18335,13 +18177,13 @@ Can fix almost anything except unique keys that aren't unique
If you want to recover a table, this is the option to try first. Only if
myisamchk reports that the table can't be recovered by @code{-r}, you
should then try @code{-o}. (Note that in the unlikely case that @code{-r}
-fails, the data file is still intact.)
+fails, the datafile is still intact.)
If you have lots of memory, you should increase the size of
@code{sort_buffer_size}!
@item -o or --safe-recover
Uses an old recovery method (reads through all rows in order and updates
-all index trees based on the found rows); this is a magnitude slower
-than @code{-r}, but can handle a couple of very unlikely cases that
+all index trees based on the found rows); this is an order of magnitude
+slower than @code{-r}, but can handle a couple of very unlikely cases that
@code{-r} cannot handle. This recovery method also uses much less disk
space than @code{-r}. Normally one should always first repair with
@code{-r}, and only if this fails use @code{-o}.
@@ -18350,18 +18192,17 @@ If you have lots of memory, you should increase the size of
@code{key_buffer_size}!
@item -n or --sort-recover
Force @code{myisamchk} to use sorting to resolve the keys even if the
-temporary files should be very big. This will not have any effect if you have
-fulltext keys in the table.
+temporary files should be very big.
@item --character-sets-dir=...
Directory where character sets are stored.
@item --set-character-set=name
Change the character set used by the index
-@item .t or --tmpdir=path
+@item -t or --tmpdir=path
Path for storing temporary files. If this is not set, @code{myisamchk} will
use the environment variable @code{TMPDIR} for this.
@item -q or --quick
-Faster repair by not modifying the data file. One can give a second
+Faster repair by not modifying the datafile. One can give a second
@code{-q} to force @code{myisamchk} to modify the original datafile in case
of duplicate keys
@item -u or --unpack
@@ -18376,24 +18217,24 @@ Other actions that @code{myisamchk} can do, besides repair and check tables:
@table @code
@item -a or --analyze
-Analyze the distribution of keys. This improves join performance by
-enabling the join optimizer to better choose in which order it should
+Analyse the distribution of keys. This improves join performance by
+enabling the join optimiser to better choose in which order it should
join the tables and which keys it should use:
@code{myisamchk --describe --verbose table_name'} or using @code{SHOW KEYS} in
MySQL.
@item -d or --description
Prints some information about table.
@item -A or --set-auto-increment[=value]
-Force auto_increment to start at this or higher value. If no value is
-given, then sets the next auto_increment value to the highest used value
+Force @code{AUTO_INCREMENT} to start at this or higher value. If no value is
+given, then sets the next @code{AUTO_INCREMENT} value to the highest used value
for the auto key + 1.
@item -S or --sort-index
Sort the index tree blocks in high-low order.
-This will optimize seeks and will make table scanning by key faster.
+This will optimise seeks and will make table scanning by key faster.
@item -R or --sort-records=#
-Sorts records according to an index. This makes your data much more localized
+Sorts records according to an index. This makes your data much more localised
and may speed up ranged @code{SELECT} and @code{ORDER BY} operations on
-this index. (It may be VERY slow to do a sort the first time!)
+this index. (It may be very slow to do a sort the first time!)
To find out a table's index numbers, use @code{SHOW INDEX}, which shows a
table's indexes in the same order that @code{myisamchk} sees them. Indexes are
numbered beginning with 1.
@@ -18421,7 +18262,7 @@ shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
Using @code{-O sort=16M} should probably be enough for most cases.
Be aware that @code{myisamchk} uses temporary files in @code{TMPDIR}. If
-@code{TMPDIR} points to a memory file system, you may easily get out of
+@code{TMPDIR} points to a memory filesystem, you may easily get out of
memory errors. If this happens, set @code{TMPDIR} to point at some directory
with more space and restart @code{myisamchk}.
@@ -18439,7 +18280,7 @@ index file is truncated at start, so one usually ignore this space.
This space is needed on the same disk as the original index file!
@item
When using @code{--recover} or @code{--sort-recover}
-(but not when using @code{--safe-recover}, you will need space for a
+(but not when using @code{--safe-recover}), you will need space for a
sort buffer for:
@code{(largest_key + row_pointer_length)*number_of_rows * 2}.
You can check the length of the keys and the row_pointer_length with
@@ -18458,9 +18299,9 @@ If you have a problem with disk space during repair, you can try to use
@cindex crash, recovery
@cindex recovery, from crash
-If you run @code{mysqld} with @code{--skip-locking} (which is the default on
-some systems, like Linux), you can't reliably use @code{myisamchk} to
-check a table when @code{mysqld} is using the same table. If you
+If you run @code{mysqld} with @code{--skip-external-locking} (which is the
+default on some systems, like Linux), you can't reliably use @code{myisamchk}
+to check a table when @code{mysqld} is using the same table. If you
can be sure that no one is accessing the tables through @code{mysqld}
while you run @code{myisamchk}, you only have to do @code{mysqladmin
flush-tables} before you start checking the tables. If you can't
@@ -18469,19 +18310,21 @@ check the tables. If you run @code{myisamchk} while @code{mysqld} is updating
the tables, you may get a warning that a table is corrupt even if it
isn't.
-If you are not using @code{--skip-locking}, you can use @code{myisamchk}
-to check tables at any time. While you do this, all clients that try
-to update the table will wait until @code{myisamchk} is ready before
+If you are not using @code{--skip-external-locking}, you can use
+@code{myisamchk} to check tables at any time. While you do this, all clients
+that try to update the table will wait until @code{myisamchk} is ready before
continuing.
-If you use @code{myisamchk} to repair or optimize tables, you
-@strong{MUST} always ensure that the @code{mysqld} server is not using
-the table (this also applies if you are using @code{--skip-locking}).
+If you use @code{myisamchk} to repair or optimise tables, you
+@strong{must} always ensure that the @code{mysqld} server is not using
+the table (this also applies if you are using @code{--skip-external-locking}).
If you don't take down @code{mysqld} you should at least do a
@code{mysqladmin flush-tables} before you run @code{myisamchk}.
+Your tables @strong{may be corrupted} if the server and @code{myisamchk}
+access the tables simultaneously.
This chapter describes how to check for and deal with data corruption
-in MySQL databases. If your tables get corrupted a lot you should
+in MySQL databases. If your tables get corrupted frequently you should
try to find the reason for this! @xref{Crashing}.
The @code{MyISAM} table section contains reason for why a table could be
@@ -18491,15 +18334,15 @@ When performing crash recovery, it is important to understand that each table
@code{tbl_name} in a database corresponds to three files in the database
directory:
-@multitable @columnfractions .2 .8
+@multitable @columnfractions .20 .30
@item @strong{File} @tab @strong{Purpose}
@item @file{tbl_name.frm} @tab Table definition (form) file
-@item @file{tbl_name.MYD} @tab Data file
+@item @file{tbl_name.MYD} @tab Datafile
@item @file{tbl_name.MYI} @tab Index file
@end multitable
Each of these three file types is subject to corruption in various ways, but
-problems occur most often in data files and index files.
+problems occur most often in datafiles and index files.
@code{myisamchk} works by creating a copy of the @file{.MYD} (data) file
row by row. It ends the repair stage by removing the old @file{.MYD}
@@ -18529,7 +18372,7 @@ To check a MyISAM table, use the following commands:
@table @code
@item myisamchk tbl_name
This finds 99.99% of all errors. What it can't find is corruption that
-involves @strong{ONLY} the data file (which is very unusual). If you want
+involves @strong{only} the datafile (which is very unusual). If you want
to check a table, you should normally run @code{myisamchk} without options or
with either the @code{-s} or @code{--silent} option.
@@ -18542,7 +18385,7 @@ in the index tree.
@item myisamchk -e tbl_name
This does a complete and thorough check of all data (@code{-e} means
``extended check''). It does a check-read of every key for each row to verify
-that they indeed point to the correct row. This may take a LONG time on a
+that they indeed point to the correct row. This may take a long time on a
big table with many keys. @code{myisamchk} will normally stop after the first
error it finds. If you want to obtain more information, you can add the
@code{--verbose} (@code{-v}) option. This causes @code{myisamchk} to keep
@@ -18555,15 +18398,15 @@ print some informational statistics, too.
@end table
-@node Repair, Optimization, Check, Table maintenance
+@node Repair, Optimisation, Check, Table maintenance
@subsubsection How to Repair Tables
@cindex tables, repairing
@cindex repairing, tables
In the following section we only talk about using @code{myisamchk} on
-@code{MyISAM} tables (extensions @code{.MYI} and @code{.MYD}). If you
-are using @code{ISAM} tables (extensions @code{.ISM} and @code{.ISD}),
+@code{MyISAM} tables (extensions @file{.MYI} and @file{.MYD}). If you
+are using @code{ISAM} tables (extensions @file{.ISM} and @file{.ISD}),
you should use @code{isamchk} instead.
Starting with MySQL Version 3.23.14, you can repair MyISAM
@@ -18584,7 +18427,7 @@ Record file is crashed
@item
Got error ### from table handler
-To get more information about the error you can run @code{perror ###}. Here
+To get more information about the error you can run @code{perror ###}. Here
is the most common errors that indicates a problem with the table:
@example
@@ -18612,15 +18455,15 @@ ALTER TABLE table MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
In the other cases, you must repair your tables. @code{myisamchk}
can usually detect and fix most things that go wrong.
-The repair process involves up to four stages, described below. Before you
+The repair process involves up to four stages, described here. Before you
begin, you should @code{cd} to the database directory and check the
permissions of the table files. Make sure they are readable by the Unix user
that @code{mysqld} runs as (and to you, because you need to access the files
you are checking). If it turns out you need to modify files, they must also
be writable by you.
-If you are using MySQL Version 3.23.16 and above, you can (and
-should) use the @code{CHECK} and @code{REPAIR} commands to check and repair
+If you are using MySQL Version 3.23.16 and above, you can (and
+should) use the @code{CHECK} and @code{REPAIR} commands to check and repair
@code{MyISAM} tables. @xref{CHECK TABLE}. @xref{REPAIR TABLE}.
The manual section about table maintenance includes the options to
@@ -18629,7 +18472,7 @@ The manual section about table maintenance includes the options to
The following section is for the cases where the above command fails or
if you want to use the extended features that @code{isamchk}/@code{myisamchk} provides.
-If you are going to repair a table from the command line, you must first
+If you are going to repair a table from the command-line, you must first
take down the @code{mysqld} server. Note that when you do
@code{mysqladmin shutdown} on a remote server, the @code{mysqld} server
will still be alive for a while after @code{mysqladmin} returns, until
@@ -18654,24 +18497,24 @@ memory} errors), or if @code{myisamchk} crashes, go to Stage 3.
@noindent
@strong{Stage 2: Easy safe repair}
-NOTE: If you want repairing to go much faster, you should add: @code{-O
+Note: If you want repairing to go much faster, you should add: @code{-O
sort_buffer=# -O key_buffer=#} (where # is about 1/4 of the available
memory) to all @code{isamchk/myisamchk} commands.
First, try @code{myisamchk -r -q tbl_name} (@code{-r -q} means ``quick
recovery mode''). This will attempt to repair the index file without
-touching the data file. If the data file contains everything that it
+touching the datafile. If the datafile contains everything that it
should and the delete links point at the correct locations within the
-data file, this should work, and the table is fixed. Start repairing the
+datafile, this should work, and the table is fixed. Start repairing the
next table. Otherwise, use the following procedure:
@enumerate
@item
-Make a backup of the data file before continuing.
+Make a backup of the datafile before continuing.
@item
Use @code{myisamchk -r tbl_name} (@code{-r} means ``recovery mode''). This will
-remove incorrect records and deleted records from the data file and
+remove incorrect records and deleted records from the datafile and
reconstruct the index file.
@item
@@ -18693,7 +18536,7 @@ follows:
@enumerate
@item
-Move the data file to some safe place.
+Move the datafile to some safe place.
@item
Use the table description file to create new (empty) data and index files:
@@ -18709,7 +18552,7 @@ If your SQL version doesn't have @code{TRUNCATE TABLE}, use @code{DELETE FROM
table_name} instead.
@item
-Copy the old data file back onto the newly created data file.
+Copy the old datafile back onto the newly created datafile.
(Don't just move the old file back onto the new file; you want to retain
a copy in case something goes wrong.)
@end enumerate
@@ -18717,6 +18560,9 @@ a copy in case something goes wrong.)
Go back to Stage 2. @code{myisamchk -r -q} should work now. (This shouldn't
be an endless loop.)
+As of @code{MySQL} 4.0.2 you can also use @code{REPAIR ... USE_FRM}
+which performs the whole procedure automatically.
+
@noindent
@strong{Stage 4: Very difficult repair}
@@ -18732,19 +18578,19 @@ should start with @code{myisamchk -r}.
@item
If you don't have a backup but know exactly how the table was created, create
-a copy of the table in another database. Remove the new data file, then move
+a copy of the table in another database. Remove the new datafile, then move
the description and index files from the other database to your crashed
database. This gives you new description and index files, but leaves
-the data file alone. Go back to Stage 2 and attempt to reconstruct
+the datafile alone. Go back to Stage 2 and attempt to reconstruct
the index file.
@end enumerate
-@node Optimization, , Repair, Table maintenance
-@subsubsection Table Optimization
+@node Optimisation, , Repair, Table maintenance
+@subsubsection Table Optimisation
-@cindex tables, optimizing
-@cindex optimizing, tables
+@cindex tables, optimising
+@cindex optimising, tables
To coalesce fragmented records and eliminate wasted space resulting from
deleting or updating records, run @code{myisamchk} in recovery mode:
@@ -18753,9 +18599,9 @@ deleting or updating records, run @code{myisamchk} in recovery mode:
shell> myisamchk -r tbl_name
@end example
-You can optimize a table in the same way using the SQL @code{OPTIMIZE TABLE}
-statement. @code{OPTIMIZE TABLE} does a repair of the table, a key
-analyzes and also sorts the index tree to give faster key lookups.
+You can optimise a table in the same way using the SQL @code{OPTIMIZE TABLE}
+statement. @code{OPTIMIZE TABLE} does a repair of the table and a key
+analysis, and also sorts the index tree to give faster key lookups.
There is also no possibility of unwanted interaction between a utility
and the server, because the server does all the work when you use
@code{OPTIMIZE TABLE}. @xref{OPTIMIZE TABLE}.
@@ -18763,11 +18609,11 @@ and the server, because the server does all the work when you use
@code{myisamchk} also has a number of other options you can use to improve
the performance of a table:
-@table @code
-@item -S, --sort-index
-@item -R index_num, --sort-records=index_num
-@item -a, --analyze
-@end table
+@itemize
+@item @code{-S}, @code{--sort-index}
+@item @code{-R index_num}, @code{--sort-records=index_num}
+@item @code{-a}, @code{--analyze}
+@end itemize
For a full description of the option. @xref{myisamchk syntax}.
@@ -18825,7 +18671,7 @@ night on all tables that have been updated during the last 24 hours,
until you come to trust MySQL as much as we do.
@cindex tables, defragment
-Normally you don't need to maintain MySQL tables that much. If
+Normally you don't need to maintain MySQL tables that much. If
you are changing tables with dynamic size rows (tables with @code{VARCHAR},
@code{BLOB} or @code{TEXT} columns) or have tables with many deleted rows
you may want to from time to time (once a month?) defragment/reclaim space
@@ -18846,14 +18692,14 @@ myisamchk -r --silent --sort-index -O sort_buffer_size=16M */*.MYI
@cindex tables, information
To get a description of a table or statistics about it, use the commands shown
-below. We explain some of the information in more detail later:
+here. We explain some of the information in more detail later:
-@table @code
+@itemize @bullet
@item myisamchk -d tbl_name
Runs @code{myisamchk} in ``describe mode'' to produce a description of
your table. If you start the MySQL server using the
-@code{--skip-locking} option, @code{myisamchk} may report an error for a
-table that is updated while it runs. However, because @code{myisamchk}
+@code{--skip-external-locking} option, @code{myisamchk} may report an error
+for a table that is updated while it runs. However, because @code{myisamchk}
doesn't change the table in describe mode, there isn't any risk of
destroying data.
@@ -18867,7 +18713,7 @@ must read the whole table.
@item myisamchk -eiv tbl_name
This is like @code{-eis}, but tells you what is being done.
-@end table
+@end itemize
@cindex examples, @code{myisamchk} output
@cindex @code{myisamchk}, example output
@@ -18934,8 +18780,10 @@ Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 98% Packed: 17%
-Records: 1403698 M.recordlength: 226 Packed: 0%
-Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
+Records: 1403698 M.recordlength: 226
+Packed: 0%
+Recordspace used: 100% Empty space: 0%
+Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0
@@ -19010,10 +18858,10 @@ preceding examples:
@end example
Explanations for the types of information @code{myisamchk} produces are
-given below. The ``keyfile'' is the index file. ``Record'' and ``row''
+given here. The ``keyfile'' is the index file. ``Record'' and ``row''
are synonymous:
-@table @code
+@itemize @bullet
@item ISAM file
Name of the ISAM (index) file.
@@ -19021,31 +18869,31 @@ Name of the ISAM (index) file.
Version of ISAM format. Currently always 2.
@item Creation time
-When the data file was created.
+When the datafile was created.
@item Recover time
-When the index/data file was last reconstructed.
+When the index/datafile was last reconstructed.
@item Data records
How many records are in the table.
@item Deleted blocks
How many deleted blocks still have reserved space.
-You can optimize your table to minimize this space.
-@xref{Optimization}.
+You can optimise your table to minimise this space.
+@xref{Optimisation}.
-@item Datafile: Parts
+@item Data file: Parts
For dynamic record format, this indicates how many data blocks there are. For
-an optimized table without fragmented records, this is the same as @code{Data
+an optimised table without fragmented records, this is the same as @code{Data
records}.
@item Deleted data
How many bytes of non-reclaimed deleted data there are.
-You can optimize your table to minimize this space.
-@xref{Optimization}.
+You can optimise your table to minimise this space.
+@xref{Optimisation}.
-@item Datafile pointer
-The size of the data file pointer, in bytes. It is usually 2, 3, 4, or 5
+@item Data file pointer
+The size of the datafile pointer, in bytes. It is usually 2, 3, 4, or 5
bytes. Most tables manage with 2 bytes, but this cannot be controlled
from MySQL yet. For fixed tables, this is a record address. For
dynamic tables, this is a byte address.
@@ -19056,10 +18904,10 @@ bytes. Most tables manage with 2 bytes, but this is calculated
automatically by MySQL. It is always a block address.
@item Max datafile length
-How long the table's data file (@code{.MYD} file) can become, in bytes.
+How long the table's datafile (@file{.MYD} file) can become, in bytes.
@item Max keyfile length
-How long the table's key file (@code{.MYI} file) can become, in bytes.
+How long the table's key file (@file{.MYI} file) can become, in bytes.
@item Recordlength
How much space each record takes, in bytes.
@@ -19073,7 +18921,7 @@ Other possible values are @code{Compressed} and @code{Packed}.
A list of all keys in the table. For each key, some low-level information
is presented:
-@table @code
+@itemize @minus
@item Key
This key's number.
@@ -19087,7 +18935,7 @@ length of the indexed column, because you can index a prefix of a string
column.
@item Index
-@code{unique} or @code{multip.} (multiple). Indicates whether or not one value
+@code{unique} or @code{multip.} (multiple). Indicates whether one value
can exist multiple times in this index.
@item Type
@@ -19102,19 +18950,19 @@ The size of each index block. By default this is 1024, but the value may be
changed at compile time.
@item Rec/key
-This is a statistical value used by the optimizer. It tells how many
+This is a statistical value used by the optimiser. It tells how many
records there are per value for this key. A unique key always has a
value of 1. This may be updated after a table is loaded (or greatly
changed) with @code{myisamchk -a}. If this is not updated at all, a default
value of 30 is given.
-@end table
+@end itemize
@item
In the first example above, the 9th key is a multi-part key with two parts.
@item Keyblocks used
What percentage of the keyblocks are used. Because the table used in the
-examples had just been reorganized with @code{myisamchk}, the values are very
+examples had just been reorganised with @code{myisamchk}, the values are very
high (very near the theoretical maximum).
@item Packed
@@ -19140,17 +18988,17 @@ MySQL strips spaces from the end of strings. The @code{Packed}
value indicates the percentage of savings achieved by doing this.
@item Recordspace used
-What percentage of the data file is used.
+What percentage of the datafile is used.
@item Empty space
-What percentage of the data file is unused.
+What percentage of the datafile is unused.
@item Blocks/Record
Average number of blocks per record (that is, how many links a fragmented
-record is composed of). This is always 1 for fixed-format tables. This value
-should stay as close to 1.0 as possible. If it gets too big, you can
-reorganize the table with @code{myisamchk}.
-@xref{Optimization}.
+record is composed of). This is always 1.0 for fixed-format tables. This
+value should stay as close to 1.0 as possible. If it gets too big, you can
+reorganise the table with @code{myisamchk}.
+@xref{Optimisation}.
@item Recordblocks
How many blocks (links) are used. For fixed format, this is the same as the number
@@ -19160,10 +19008,10 @@ of records.
How many blocks (links) are deleted.
@item Recorddata
-How many bytes in the data file are used.
+How many bytes in the datafile are used.
@item Deleted data
-How many bytes in the data file are deleted (unused).
+How many bytes in the datafile are deleted (unused).
@item Lost space
If a record is updated to a shorter length, some space is lost. This is
@@ -19173,7 +19021,7 @@ the sum of all such losses, in bytes.
When the dynamic table format is used, record fragments are linked with
pointers (4 to 7 bytes each). @code{Linkdata} is the sum of the amount of
storage used by all such pointers.
-@end table
+@end itemize
If a table has been compressed with @code{myisampack}, @code{myisamchk
-d} prints additional information about each table column. See
@@ -19181,7 +19029,7 @@ If a table has been compressed with @code{myisampack}, @code{myisamchk
information and a description of what it means.
-@node Database Administration, Localization, Disaster Prevention, MySQL Database Administration
+@node Database Administration, Localisation, Disaster Prevention, MySQL Database Administration
@section Database Administration Language Reference
@@ -19189,6 +19037,7 @@ information and a description of what it means.
* OPTIMIZE TABLE:: @code{OPTIMIZE TABLE} Syntax
* ANALYZE TABLE:: @code{ANALYZE TABLE} Syntax
* FLUSH:: @code{FLUSH} Syntax
+* RESET:: @code{RESET} Syntax
* KILL:: @code{KILL} Syntax
* SHOW:: @code{SHOW} Syntax
@end menu
@@ -19211,13 +19060,14 @@ table or if you have made many changes to a table with variable-length rows
(tables that have @code{VARCHAR}, @code{BLOB}, or @code{TEXT} columns).
Deleted records are maintained in a linked list and subsequent @code{INSERT}
operations reuse old record positions. You can use @code{OPTIMIZE TABLE} to
-reclaim the unused space and to defragment the data file.
+reclaim the unused space and to defragment the datafile.
-For the moment @code{OPTIMIZE TABLE} only works on @strong{MyISAM} and
+For the moment, @code{OPTIMIZE TABLE} only works on @code{MyISAM} and
@code{BDB} tables. For @code{BDB} tables, @code{OPTIMIZE TABLE} is
-currently mapped to @code{ANALYZE TABLE}. @xref{ANALYZE TABLE}.
+currently mapped to @code{ANALYZE TABLE}.
+@xref{ANALYZE TABLE, , @code{ANALYZE TABLE}}.
-You can get optimize table to work on other table types by starting
+You can get @code{OPTIMIZE TABLE} to work on other table types by starting
@code{mysqld} with @code{--skip-new} or @code{--safe-mode}, but in this
case @code{OPTIMIZE TABLE} is just mapped to @code{ALTER TABLE}.
@@ -19232,8 +19082,8 @@ If the statistics are not up to date (and the repair couldn't be done
by sorting the index), update them.
@end itemize
-@code{OPTIMIZE TABLE} for @code{MyISAM} tables is equvialent of running
-@code{myisamchk --quick --check-changed-tables --sort-index --analyze}
+@code{OPTIMIZE TABLE} for a @code{MyISAM} table is equivalent to running
+@code{myisamchk --quick --check-only-changed --sort-index --analyze}
on the table.
Note that the table is locked during the time @code{OPTIMIZE TABLE} is
@@ -19249,8 +19099,8 @@ running!
ANALYZE TABLE tbl_name[,tbl_name...]
@end example
-Analyze and store the key distribution for the table. During the
-analyze the table is locked with a read lock. This works on
+Analyse and store the key distribution for the table. During the
+analysis, the table is locked with a read lock. This works on
@code{MyISAM} and @code{BDB} tables.
This is equivalent to running @code{myisamchk -a} on the table.
@@ -19261,7 +19111,7 @@ constant.
The command returns a table with the following columns:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .15 .40
@item @strong{Column} @tab @strong{Value}
@item Table @tab Table name
@item Op @tab Always ``analyze''
@@ -19273,10 +19123,10 @@ You can check the stored key distribution with the @code{SHOW INDEX} command.
@xref{SHOW DATABASE INFO}.
If the table hasn't changed since the last @code{ANALYZE TABLE} command,
-the table will not be analyzed again.
+the table will not be analysed again.
-@node FLUSH, KILL, ANALYZE TABLE, Database Administration
+@node FLUSH, RESET, ANALYZE TABLE, Database Administration
@subsection @code{FLUSH} Syntax
@findex FLUSH
@@ -19286,16 +19136,18 @@ the table will not be analyzed again.
@cindex caches, clearing
@example
-FLUSH flush_option [,flush_option]
+FLUSH flush_option [,flush_option] ...
@end example
You should use the @code{FLUSH} command if you want to clear some of the
internal caches MySQL uses. To execute @code{FLUSH}, you must have
-the @strong{RELOAD} privilege.
+the @code{RELOAD} privilege.
@code{flush_option} can be any of the following:
-@multitable @columnfractions .15 .85
+@multitable @columnfractions .25 .75
+@item @strong{Option} @tab @strong{Description}
+
@item @code{HOSTS} @tab Empties the host cache tables. You should flush the
host tables if some of your hosts change IP number or if you get the
error message @code{Host ... is blocked}. When more than
@@ -19303,8 +19155,11 @@ error message @code{Host ... is blocked}. When more than
connection to the MySQL server, MySQL assumes
something is wrong and blocks the host from further connection requests.
Flushing the host tables allows the host to attempt to connect
-again. @xref{Blocked host}.) You can start @code{mysqld} with
-@code{-O max_connection_errors=999999999} to avoid this error message.
+again. @xref{Blocked host}. You can start @code{mysqld} with
+@code{-O max_connect_errors=999999999} to avoid this error message.
+
+@item @code{DES_KEY_FILE} @tab Reloads the DES keys from the file that was
+specified with the @code{--des-key-file} option at server startup time.
@item @code{LOGS} @tab Closes and reopens all log files.
If you have specified the update log file or a binary log file without
@@ -19317,25 +19172,54 @@ signal to the @code{mysqld} server.
@item @code{PRIVILEGES} @tab Reloads the privileges from the grant tables in
the @code{mysql} database.
-@item @code{TABLES} @tab Closes all open tables and force all tables in use to be closed.
+@item @code{QUERY CACHE} @tab Defragment the query cache to better utilise its
+memory. This command will not remove any queries from the cache, unlike
+@code{RESET QUERY CACHE}.
+
+@item @code{TABLES} @tab Closes all open tables and force all tables in use to be closed. This also flushes the query cache.
-@item @code{[TABLE | TABLES] table_name [,table_name...]} @tab Flushes only the given tables.
+@item @code{[TABLE | TABLES] tbl_name [,tbl_name...]} @tab Flushes only the given tables.
-@item @code{TABLES WITH READ LOCK} @tab Closes all open tables and locks all tables for all databases with a read until one executes @code{UNLOCK TABLES}. This is very convenient way to get backups if you have a file system, like Veritas,that can take snapshots in time.
+@item @code{TABLES WITH READ LOCK} @tab Closes all open tables and locks all tables for all databases with a read until one executes @code{UNLOCK TABLES}. This is very convenient way to get backups if you have a filesystem, like Veritas,that can take snapshots in time.
@item @code{STATUS} @tab Resets most status variables to zero. This is something one should only use when debugging a query.
+
+@item @code{USER_RESOURCES} @tab Resets all user resources to zero. This will enable blocked users to login again. @xref{User resources}.
@end multitable
You can also access each of the commands shown above with the @code{mysqladmin}
utility, using the @code{flush-hosts}, @code{flush-logs}, @code{reload},
or @code{flush-tables} commands.
-Take also a look at the @code{RESET} command used with
-replication. @xref{Replication SQL}.
+Take also a look at the @code{RESET} command used with replication.
+@xref{RESET, , @code{RESET}}.
+
+@node RESET, KILL, FLUSH, Database Administration
+@subsection @code{RESET} Syntax
+
+@example
+RESET reset_option [,reset_option] ...
+@end example
+
+The @code{RESET} command is used to clear things. It also acts as an stronger
+version of the @code{FLUSH} command. @xref{FLUSH, , @code{FLUSH}}.
+
+To execute @code{RESET}, you must have the @code{RELOAD} privilege.
+
+@multitable @columnfractions .25 .75
+@item @strong{Option} @tab @strong{Description}
+
+@item @code{MASTER} @tab Deletes all binary logs listed in the index file, resetting the binlog
+index file to be empty. In pre-3.23.26 versions, @code{FLUSH MASTER} (Master)
+@item @code{SLAVE} @tab Makes the slave forget its replication position in the master
+logs. In pre 3.23.26 versions the command was called
+@code{FLUSH SLAVE}(Slave)
+@item @code{QUERY CACHE} @tab Removes all query results from the query cache.
+@end multitable
-@node KILL, SHOW, FLUSH, Database Administration
+@node KILL, SHOW, RESET, Database Administration
@subsection @code{KILL} Syntax
@findex KILL
@@ -19350,8 +19234,9 @@ Each connection to @code{mysqld} runs in a separate thread. You can see
which threads are running with the @code{SHOW PROCESSLIST} command and kill
a thread with the @code{KILL thread_id} command.
-If you have the @strong{process} privilege, you can see and kill all threads.
-Otherwise, you can see and kill only your own threads.
+If you have the @code{PROCESS} privilege, you can see all threads.
+If you have the @code{SUPER} privilege, you can kill all threads.
+Otherwise, you can only see and kill your own threads.
You can also use the @code{mysqladmin processlist} and @code{mysqladmin kill}
commands to examine and kill threads.
@@ -19389,12 +19274,6 @@ If the thread is waiting for free disk space in a @code{write} call, the
write is aborted with an disk full error message.
@end itemize
-
-@menu
-* SHOW:: @code{SHOW} Syntax
-@end menu
-
-
@node SHOW, , KILL, Database Administration
@subsection @code{SHOW} Syntax
@@ -19437,7 +19316,7 @@ or SHOW SLAVE STATUS
@code{SHOW} provides information about databases, tables, columns, or
status information about the server. If the @code{LIKE wild} part is
used, the @code{wild} string can be a string that uses the SQL @samp{%}
-and @samp{_} wild-card characters.
+and @samp{_} wildcard characters.
@menu
* SHOW DATABASE INFO:: Retrieving information about Database, Tables, Columns, and Indexes
@@ -19464,13 +19343,16 @@ mysql> SHOW INDEX FROM mytable FROM mydb;
mysql> SHOW INDEX FROM mydb.mytable;
@end example
-@code{SHOW DATABASES} lists the databases on the MySQL server
-host. You can also get this list using the @code{mysqlshow} command.
+@code{SHOW DATABASES} lists the databases on the MySQL server host.
+You can also get this list using the @code{mysqlshow} command line tool.
+In version 4.0.2 you will only see those databases for which you have some
+kind of privilege, if you don't have the global @code{SHOW DATABASES}
+privilege.
@code{SHOW TABLES} lists the tables in a given database. You can also
get this list using the @code{mysqlshow db_name} command.
-@strong{NOTE:} If a user doesn't have any privileges for a table, the table
+@strong{Note}: if a user doesn't have any privileges for a table, the table
will not show up in the output from @code{SHOW TABLES} or @code{mysqlshow
db_name}.
@@ -19480,7 +19362,7 @@ how many times the table is @code{cached} and @code{in_use}.
@code{SHOW COLUMNS} lists the columns in a given table. If you specify
the @code{FULL} option, you will also get the privileges you have for
-each column. If the column types are different than you expect them to
+each column. If the column types are different from what you expect them to
be based on a @code{CREATE TABLE} statement, note that MySQL
sometimes changes column types. @xref{Silent column changes}.
@@ -19497,12 +19379,12 @@ or @code{mysqlshow -k db_name tbl_name}.
resembles the @code{SQLStatistics} call in ODBC. The following columns
are returned:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .15 .55
@item @strong{Column} @tab @strong{Meaning}
@item @code{Table} @tab Name of the table.
@item @code{Non_unique} @tab 0 if the index can't contain duplicates.
@item @code{Key_name} @tab Name of the index.
-@item @code{Seq_in_index} @tab Column sequence number in index,
+@item @code{Seq_in_index} @tab Column sequence number in index,
starting with 1.
@item @code{Column_name} @tab Column name.
@item @code{Collation} @tab How the column is sorted in the index.
@@ -19510,18 +19392,21 @@ are returned:
@samp{A} (Ascending) or @code{NULL} (Not
sorted).
@item @code{Cardinality} @tab Number of unique values in the index.
- This is updated by running
+ This is updated by running
@code{isamchk -a}.
-@item @code{Sub_part} @tab Number of indexed characters if the
- column is only partly indexed.
+@item @code{Sub_part} @tab Number of indexed characters if the
+ column is only partly indexed.
@code{NULL} if the entire key is indexed.
-@item @code{Comment} @tab Various remarks. For now, it tells
- whether index is FULLTEXT or not.
+@item @code{Null} @tab Contains 'YES' if the column may contain @code{NULL}.
+@item @code{Index_type} @tab Index method used.
+@item @code{Comment} @tab Various remarks. For now, it tells
+in MySQL < 4.0.2 whether index is @code{FULLTEXT} or not.
@end multitable
Note that as the @code{Cardinality} is counted based on statistics
stored as integers, it's not necessarily accurate for small tables.
+The @code{Null} and @code{Index_type} columns were added in MySQL 4.0.2.
@node SHOW TABLE STATUS, SHOW STATUS, SHOW DATABASE INFO, SHOW
@subsubsection @code{SHOW TABLE STATUS}
@@ -19539,20 +19424,20 @@ STATUS}, but provides a lot of information about each table. You can
also get this list using the @code{mysqlshow --status db_name} command.
The following columns are returned:
-@multitable @columnfractions .30 .70
+@multitable @columnfractions .20 .70
@item @strong{Column} @tab @strong{Meaning}
@item @code{Name} @tab Name of the table.
@item @code{Type} @tab Type of table. @xref{Table types}.
@item @code{Row_format} @tab The row storage format (Fixed, Dynamic, or Compressed).
@item @code{Rows} @tab Number of rows.
@item @code{Avg_row_length} @tab Average row length.
-@item @code{Data_length} @tab Length of the data file.
-@item @code{Max_data_length} @tab Max length of the data file.
+@item @code{Data_length} @tab Length of the datafile.
+@item @code{Max_data_length} @tab Max length of the datafile.
@item @code{Index_length} @tab Length of the index file.
@item @code{Data_free} @tab Number of allocated but not used bytes.
@item @code{Auto_increment} @tab Next autoincrement value.
@item @code{Create_time} @tab When the table was created.
-@item @code{Update_time} @tab When the data file was last updated.
+@item @code{Update_time} @tab When the datafile was last updated.
@item @code{Check_time} @tab When the table was last checked.
@item @code{Create_options} @tab Extra options used with @code{CREATE TABLE}.
@item @code{Comment} @tab The comment used when creating the table (or some information why MySQL couldn't access the table information).
@@ -19568,7 +19453,7 @@ in the table comment.
@cindex @code{mysqladmin}
@code{SHOW STATUS} provides server status information
(like @code{mysqladmin extended-status}). The output resembles that shown
-below, though the format and numbers probably differ:
+here, though the format and numbers probably differ:
@example
+--------------------------+------------+
@@ -19634,21 +19519,22 @@ below, though the format and numbers probably differ:
@cindex variables, status
The status variables listed above have the following meaning:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .30 .70
@item @strong{Variable} @tab @strong{Meaning}
@item @code{Aborted_clients} @tab Number of connections aborted because the client died without closing the connection properly. @xref{Communication errors}.
@item @code{Aborted_connects} @tab Number of tries to connect to the MySQL server that failed. @xref{Communication errors}.
@item @code{Bytes_received} @tab Number of bytes received from all clients.
@item @code{Bytes_sent} @tab Number of bytes sent to all clients.
-@item @code{Com_xxxx} @tab Number of times the xxx commands has been executed.
+@item @code{Com_xxx} @tab Number of times each xxx command has been executed.
@item @code{Connections} @tab Number of connection attempts to the MySQL server.
@item @code{Created_tmp_disk_tables} @tab Number of implicit temporary tables on disk created while executing statements.
@item @code{Created_tmp_tables} @tab Number of implicit temporary tables in memory created while executing statements.
-@item @code{Created_tmp_files} @tab How many temporary files @code{mysqld} have created.
+@item @code{Created_tmp_files} @tab How many temporary files @code{mysqld} has created.
@item @code{Delayed_insert_threads} @tab Number of delayed insert handler threads in use.
@item @code{Delayed_writes} @tab Number of rows written with @code{INSERT DELAYED}.
@item @code{Delayed_errors} @tab Number of rows written with @code{INSERT DELAYED} for which some error occurred (probably @code{duplicate key}).
@item @code{Flush_commands} @tab Number of executed @code{FLUSH} commands.
+@item @code{Handler_commit} @tab Number of internal @code{COMMIT} commands.
@item @code{Handler_delete} @tab Number of times a row was deleted from a table.
@item @code{Handler_read_first} @tab Number of times the first entry was read from an index.
If this is high, it suggests that the server is doing a lot of full index scans, for example,
@@ -19658,12 +19544,14 @@ is high, it is a good indication that your queries and tables are properly index
@item @code{Handler_read_next} @tab Number of requests to read next row in key order. This
will be incremented if you are querying an index column with a range constraint. This also
will be incremented if you are doing an index scan.
+@item @code{Handler_read_prev} @tab Number of requests to read previous row in key order. This is mainly used to optimize @code{ORDER BY ... DESC}.
@item @code{Handler_read_rnd} @tab Number of requests to read a row based on a fixed position.
This will be high if you are doing a lot of queries that require sorting of the result.
@item @code{Handler_read_rnd_next} @tab Number of requests to read the next row in the datafile.
This will be high if you are doing a lot of table scans. Generally this suggests that your tables
are not properly indexed or that your queries are not written to take advantage of the indexes you
have.
+@item @code{Handler_rollback} @tab Number of internal @code{ROLLBACK} commands.
@item @code{Handler_update} @tab Number of requests to update a row in a table.
@item @code{Handler_write} @tab Number of requests to insert a row in a table.
@item @code{Key_blocks_used} @tab The number of used blocks in the key cache.
@@ -19678,6 +19566,7 @@ have.
@item @code{Open_files} @tab Number of files that are open.
@item @code{Open_streams} @tab Number of streams that are open (used mainly for logging).
@item @code{Opened_tables} @tab Number of tables that have been opened.
+@item @code{Rpl_status} @tab Status of failsafe replication. (Not yet in use).
@item @code{Select_full_join} @tab Number of joins without keys (If this is 0, you should carefully check the index of your tables).
@item @code{Select_full_range_join} @tab Number of joins where we used a range search on reference table.
@item @code{Select_range} @tab Number of joins where we used ranges on the first table. (It's normally not critical even if this is big.)
@@ -19686,17 +19575,19 @@ have.
@item @code{Questions} @tab Number of queries sent to the server.
@item @code{Slave_open_temp_tables} @tab Number of temporary tables currently
open by the slave thread
+@item @code{Slave_running} @tab Is @code{ON} if this is a slave that is connected to a master.
@item @code{Slow_launch_threads} @tab Number of threads that have taken more than @code{slow_launch_time} to create.
@item @code{Slow_queries} @tab Number of queries that have taken more than @code{long_query_time}. @xref{Slow query log}.
@item @code{Sort_merge_passes} @tab Number of merges passes the sort algoritm have had to do. If this value is large you should consider increasing @code{sort_buffer}.
@item @code{Sort_range} @tab Number of sorts that where done with ranges.
@item @code{Sort_rows} @tab Number of sorted rows.
@item @code{Sort_scan} @tab Number of sorts that where done by scanning the table.
+@item @code{ssl_xxx} @tab Variables used by SSL; Not yet implemented.
@item @code{Table_locks_immediate} @tab Number of times a table lock was
acquired immediately. Available after 3.23.33.
@item @code{Table_locks_waited} @tab Number of times a table lock could not
be acquired immediately and a wait was needed. If this is high, and you
-have performance problems, you should first optimize your queries, and then
+have performance problems, you should first optimise your queries, and then
either split your table(s) or use replication. Available after 3.23.33.
@item @code{Threads_cached} @tab Number of threads in the thread cache.
@item @code{Threads_connected} @tab Number of currently open connections.
@@ -19712,16 +19603,21 @@ Some comments about the above:
If @code{Opened_tables} is big, then your @code{table_cache}
variable is probably too small.
@item
-If @code{key_reads} is big, then your @code{key_buffer_size} variable is
+If @code{Key_reads} is big, then your @code{key_buffer_size} variable is
probably too small. The cache hit rate can be calculated with
-@code{key_reads}/@code{key_read_requests}.
+@code{Key_reads}/@code{Key_read_requests}.
@item
If @code{Handler_read_rnd} is big, then you probably have a lot of
queries that require MySQL to scan whole tables or you have
joins that don't use keys properly.
@item
If @code{Threads_created} is big, you may want to increase the
-@code{thread_cache_size} variable.
+@code{thread_cache_size} variable. The cache hit rate can be calculated
+with @code{Threads_created}/@code{Connections}.
+@item
+If @code{Created_tmp_disk_tables} is big, you may want to increase the
+@code{tmp_table_size} variable to get the temporary tables memory-based
+instead of disk based.
@end itemize
@@ -19729,7 +19625,7 @@ If @code{Threads_created} is big, you may want to increase the
@subsubsection @code{SHOW VARIABLES}
@example
-SHOW VARIABLES [LIKE wild]
+SHOW [GLOBAL | SESSION] VARIABLES [LIKE wild]
@end example
@code{SHOW VARIABLES} shows the values of some MySQL system
@@ -19738,106 +19634,126 @@ variables} command. If the default values are unsuitable, you can set most
of these variables using command-line options when @code{mysqld} starts up.
@xref{Command-line options}.
-The output resembles that shown below, though the format and numbers may
+The options @code{GLOBAL} and @code{SESSION} are new in MySQL 4.0.3.
+With @code{GLOBAL} you will get the variables that will be used for new
+connections to MySQL. With @code{SESSION} you will get the values that
+are in effect for the current connection. If you are not using either
+option, @code{SESSION} is used.
+
+You can change most options with the @code{SET} command.
+@xref{SET OPTION, , @code{SET}}.
+
+The output resembles that shown here, though the format and numbers may
differ somewhat:
@example
-+-------------------------+---------------------------+
-| Variable_name | Value |
-+-------------------------+---------------------------+
-| ansi_mode | OFF |
-| back_log | 50 |
-| basedir | /my/monty/ |
-| bdb_cache_size | 16777216 |
-| bdb_log_buffer_size | 32768 |
-| bdb_home | /my/monty/data/ |
-| bdb_max_lock | 10000 |
-| bdb_logdir | |
-| bdb_shared_data | OFF |
-| bdb_tmpdir | /tmp/ |
-| binlog_cache_size | 32768 |
-| concurrent_insert | ON |
-| connect_timeout | 5 |
-| datadir | /my/monty/data/ |
-| delay_key_write | ON |
-| delayed_insert_limit | 100 |
-| delayed_insert_timeout | 300 |
-| delayed_queue_size | 1000 |
-| flush | OFF |
-| flush_time | 0 |
-| have_bdb | YES |
-| have_innodb | YES |
-| have_raid | YES |
-| have_ssl | NO |
-| init_file | |
-| interactive_timeout | 28800 |
-| join_buffer_size | 131072 |
-| key_buffer_size | 16776192 |
-| language | /my/monty/share/english/ |
-| large_files_support | ON |
-| log | OFF |
-| log_update | OFF |
-| log_bin | OFF |
-| log_slave_updates | OFF |
-| long_query_time | 10 |
-| low_priority_updates | OFF |
-| lower_case_table_names | 0 |
-| max_allowed_packet | 1048576 |
-| max_binlog_cache_size | 4294967295 |
-| max_connections | 100 |
-| max_connect_errors | 10 |
-| max_delayed_threads | 20 |
-| max_heap_table_size | 16777216 |
-| max_join_size | 4294967295 |
-| max_sort_length | 1024 |
-| max_tmp_tables | 32 |
-| max_write_lock_count | 4294967295 |
-| myisam_recover_options | DEFAULT |
-| myisam_sort_buffer_size | 8388608 |
-| net_buffer_length | 16384 |
-| net_read_timeout | 30 |
-| net_retry_count | 10 |
-| net_write_timeout | 60 |
-| open_files_limit | 0 |
-| pid_file | /my/monty/data/donna.pid |
-| port | 3306 |
-| protocol_version | 10 |
-| record_buffer | 131072 |
-| query_buffer_size | 0 |
-| safe_show_database | OFF |
-| server_id | 0 |
-| skip_locking | ON |
-| skip_networking | OFF |
-| skip_show_database | OFF |
-| slow_launch_time | 2 |
-| socket | /tmp/mysql.sock |
-| sort_buffer | 2097116 |
-| table_cache | 64 |
-| table_type | MYISAM |
-| thread_cache_size | 4 |
-| thread_stack | 65536 |
-| tmp_table_size | 1048576 |
-| tmpdir | /tmp/ |
-| version | 3.23.29a-gamma-debug |
-| wait_timeout | 28800 |
-+-------------------------+---------------------------+
-@end example
-
-Each option is described below. Values for buffer sizes, lengths, and stack
++------------------------------+---------------------------+
+| Variable_name | Value |
++------------------------------+---------------------------+
+| ansi_mode | OFF |
+| back_log | 50 |
+| basedir | /my/monty/ |
+| bdb_cache_size | 16777216 |
+| bdb_log_buffer_size | 32768 |
+| bdb_home | /my/monty/data/ |
+| bdb_max_lock | 10000 |
+| bdb_logdir | |
+| bdb_shared_data | OFF |
+| bdb_tmpdir | /tmp/ |
+| binlog_cache_size | 32768 |
+| bulk_insert_buffer_size | 8388608 |
+| concurrent_insert | ON |
+| connect_timeout | 5 |
+| datadir | /my/monty/data/ |
+| delay_key_write | ON |
+| delayed_insert_limit | 100 |
+| delayed_insert_timeout | 300 |
+| delayed_queue_size | 1000 |
+| flush | OFF |
+| flush_time | 0 |
+| ft_min_word_len | 4 |
+| ft_max_word_len | 254 |
+| ft_max_word_len_for_sort | 20 |
+| ft_boolean_syntax | + -><()~* |
+| have_bdb | YES |
+| have_innodb | YES |
+| have_raid | YES |
+| have_openssl | NO |
+| init_file | |
+| interactive_timeout | 28800 |
+| join_buffer_size | 131072 |
+| key_buffer_size | 16776192 |
+| language | /my/monty/share/english/ |
+| large_files_support | ON |
+| log | OFF |
+| log_update | OFF |
+| log_bin | OFF |
+| log_slave_updates | OFF |
+| long_query_time | 10 |
+| low_priority_updates | OFF |
+| lower_case_table_names | 0 |
+| max_allowed_packet | 1048576 |
+| max_binlog_cache_size | 4294967295 |
+| max_connections | 100 |
+| max_connect_errors | 10 |
+| max_delayed_threads | 20 |
+| max_heap_table_size | 16777216 |
+| max_join_size | 4294967295 |
+| max_sort_length | 1024 |
+| max_tmp_tables | 32 |
+| max_write_lock_count | 4294967295 |
+| myisam_recover_options | DEFAULT |
+| myisam_sort_buffer_size | 8388608 |
+| net_buffer_length | 16384 |
+| net_read_timeout | 30 |
+| net_retry_count | 10 |
+| net_write_timeout | 60 |
+| open_files_limit | 0 |
+| pid_file | /my/monty/data/donna.pid |
+| port | 3306 |
+| protocol_version | 10 |
+| read_buffer_size | 131072 |
+| query_cache_limit | 1048576 |
+| query_cache_size | 16768060 |
+| query_cache_type | 1 |
+| safe_show_database | OFF |
+| server_id | 0 |
+| skip_locking | ON |
+| skip_networking | OFF |
+| skip_show_database | OFF |
+| slow_launch_time | 2 |
+| socket | /tmp/mysql.sock |
+| sort_buffer | 2097116 |
+| table_cache | 64 |
+| table_type | MYISAM |
+| thread_cache_size | 4 |
+| thread_stack | 65536 |
+| tmp_table_size | 1048576 |
+| tmpdir | /tmp/ |
+| version | 3.23.29a-gamma-debug |
+| wait_timeout | 28800 |
++------------------------------+---------------------------+
+@end example
+
+Each option is described here. Values for buffer sizes, lengths, and stack
sizes are given in bytes. You can specify values with a suffix of @samp{K}
or @samp{M} to indicate kilobytes or megabytes. For example, @code{16M}
indicates 16 megabytes. The case of suffix letters does not matter;
@code{16M} and @code{16m} are equivalent:
+@c FIX 2002-04-29 arjen / paul
+@c FIX Below should be a @multitable just like SHOW STATUS.
+@c FIX Has to wait till after O'Reilly printed edition is out the door.
+
@cindex variables, values
-@table @code
+@itemize
@item @code{ansi_mode}.
Is @code{ON} if @code{mysqld} was started with @code{--ansi}.
@xref{ANSI mode}.
@item @code{back_log}
The number of outstanding connection requests MySQL can have. This
-comes into play when the main MySQL thread gets @strong{VERY}
+comes into play when the main MySQL thread gets @strong{very}
many connection requests in a very short time. It then takes some time
(although very little) for the main thread to check the connection and start
a new thread. The @code{back_log} value indicates how many requests can be
@@ -19891,6 +19807,15 @@ statements for the binary log during a transaction. If you often use
big, multi-statement transactions you can increase this to get more
performance. @xref{COMMIT}.
+@item @code{bulk_insert_buffer_size} (was @code{myisam_bulk_insert_tree_size})
+MyISAM uses special tree-like cache to make bulk inserts (that is,
+@code{INSERT ... SELECT}, @code{INSERT ... VALUES (...), (...), ...}, and
+@code{LOAD DATA INFILE}) faster. This variable limits
+the size of the cache tree in bytes per thread. Setting it to 0
+will disable this optimization.
+@strong{Note}: this cache is only used when adding data to non-empty table.
+Default value is 8 MB.
+
@item @code{character_set}
The default character set.
@@ -19898,10 +19823,10 @@ The default character set.
The supported character sets.
@item @code{concurrent_inserts}
-If @code{ON} (the default), MySQL will allow you to use @code{INSERT}
-on @code{MyISAM} tables at the same time as you run @code{SELECT} queries
-on them. You can turn this option off by starting @code{mysqld} with @code{--safe}
-or @code{--skip-new}.
+If @code{ON} (the default), MySQL will allow you to use @code{INSERT} on
+@code{MyISAM} tables at the same time as you run @code{SELECT} queries
+on them. You can turn this option off by starting @code{mysqld} with
+@code{--safe} or @code{--skip-new}.
@cindex timeout
@item @code{connect_timeout}
@@ -19913,7 +19838,7 @@ The value of the @code{--datadir} option.
@item @code{delay_key_write}
If enabled (is on by default), MySQL will honor the
-@code{delay_key_write} option @code{CREATE TABLE}. This means that the
+@code{DELAY_KEY_WRITE} option for @code{CREATE TABLE}. This means that the
key buffer for tables with this option will not get flushed on every
index update, but only when a table is closed. This will speed up
writes on keys a lot, but you should add automatic checking of all tables
@@ -19944,18 +19869,44 @@ option.
@item @code{flush_time}
If this is set to a non-zero value, then every @code{flush_time} seconds all
tables will be closed (to free up resources and sync things to disk). We
-only recommend this option on Win95, Win98, or on systems where you have
+only recommend this option on Windows 9x/Me, or on systems where you have
very little resources.
-@item @code{have_bdb}
-@code{YES} if @code{mysqld} supports Berkeley DB tables. @code{DISABLED}
-if @code{--skip-bdb} is used.
+@item @code{ft_min_word_len}
+The minimum length of the word to be included in a @code{FULLTEXT} index.
+@strong{Note: @code{FULLTEXT} indexes must be rebuilt after changing
+this variable.} (This option is new for MySQL 4.0.)
+
+@item @code{ft_max_word_len}
+The maximum length of the word to be included in a @code{FULLTEXT} index.
+@strong{Note: @code{FULLTEXT} indexes must be rebuilt after changing
+this variable.} (This option is new for MySQL 4.0.)
+
+@item @code{ft_max_word_len_sort}
+The maximum length of the word in a @code{FULLTEXT} index
+to be used in fast index recreation method in @code{REPAIR},
+@code{CREATE INDEX}, or @code{ALTER TABLE}. Longer words are inserted the
+slow way. The rule of the thumb is as follows: with
+@code{ft_max_word_len_sort} increasing, @strong{MySQL} will create bigger
+temporary files (thus slowing the process down, due to disk I/O), and will put
+fewer keys in one sort block (again, decreasing the efficiency). When
+@code{ft_max_word_len_sort} is too small, instead, @strong{MySQL} will insert a
+lot of words into index the slow way, but short words will be inserted very
+quickly.
+
+@item @code{ft_boolean_syntax}
+List of operators supported by @code{MATCH ... AGAINST(... IN BOOLEAN MODE)}.
+@xref{Fulltext Search}.
+
@item @code{have_innodb}
@code{YES} if @code{mysqld} supports InnoDB tables. @code{DISABLED}
if @code{--skip-innodb} is used.
+@item @code{have_bdb}
+@code{YES} if @code{mysqld} supports Berkeley DB tables. @code{DISABLED}
+if @code{--skip-bdb} is used.
@item @code{have_raid}
@code{YES} if @code{mysqld} supports the @code{RAID} option.
-@item @code{have_ssl}
+@item @code{have_openssl}
@code{YES} if @code{mysqld} supports SSL (encryption) on the client/server
protocol.
@@ -19987,10 +19938,10 @@ Index blocks are buffered and are shared by all threads.
Increase this to get better index handling (for all reads and multiple
writes) to as much as you can afford; 64M on a 256M machine that mainly
runs MySQL is quite common. If you, however, make this too big
-(more than 50% of your total memory?) your system may start to page and
-become REALLY slow. Remember that because MySQL does not cache
-data read, that you will have to leave some room for the OS filesystem
-cache.
+(for instance more than 50% of your total memory) your system may start
+to page and become extremely slow. Remember that because MySQL does not
+cache data reads, you will have to leave some room for the OS
+filesystem cache.
You can check the performance of the key buffer by doing @code{show
status} and examine the variables @code{Key_read_requests},
@@ -19999,7 +19950,7 @@ status} and examine the variables @code{Key_read_requests},
The @code{Key_write/Key_write_requests} is usually near 1 if you are
using mostly updates/deletes but may be much smaller if you tend to
do updates that affect many at the same time or if you are
-using @code{delay_key_write}. @xref{SHOW}.
+using @code{delay_key_write}. @xref{SHOW, , @code{SHOW}}.
To get even more speed when writing many rows at the same time, use
@code{LOCK TABLES}. @xref{LOCK TABLES, , @code{LOCK TABLES}}.
@@ -20036,12 +19987,13 @@ names will be case-insensitive.
@xref{Name case sensitivity}.
@item @code{max_allowed_packet}
-The maximum size of one packet. The message buffer is initialized to
+The maximum size of one packet. The message buffer is initialised to
@code{net_buffer_length} bytes, but can grow up to @code{max_allowed_packet}
bytes when needed. This value by default is small, to catch big (possibly
wrong) packets. You must increase this value if you are using big
@code{BLOB} columns. It should be as big as the biggest @code{BLOB} you want
-to use. The current protocol limits @code{max_allowed_packet} to 16M.
+to use. The protocol limits for @code{max_allowed_packet} is 16M in MySQL
+3.23 and 2G in MySQL 4.0.
@item @code{max_binlog_cache_size}
If a multi-statement transaction requires more than this amount of memory,
@@ -20049,8 +20001,8 @@ one will get the error "Multi-statement transaction required more than
'max_binlog_cache_size' bytes of storage".
@item @code{max_binlog_size}
-Available after 3.23.33. If a write to the binary (replication) log exceeds
-the given value, rotate the logs. You cannot set it to less than 1024 bytes,
+Available after 3.23.33. If a write to the binary (replication) log exceeds
+the given value, rotate the logs. You cannot set it to less than 1024 bytes,
or more than 1 GB. Default is 1 GB.
@item @code{max_connections}
@@ -20102,18 +20054,18 @@ The buffer that is allocated when sorting the index when doing a
@code{ALTER TABLE}.
@item @code{myisam_max_extra_sort_file_size}.
-If the creating of the temporary file for fast index creation would be
-this much bigger than using the key cache, then prefer the key cache
-method. This is mainly used to force long character keys in large
+If the temporary file used for fast index creation would be bigger than
+using the key cache by the amount specified here, then prefer the key
+cache method. This is mainly used to force long character keys in large
tables to use the slower key cache method to create the index.
-@strong{NOTE} that this parameter is given in megabytes!
+@strong{Note} that this parameter is given in megabytes!
@item @code{myisam_max_sort_file_size}
The maximum size of the temporary file MySQL is allowed to use
while recreating the index (during @code{REPAIR}, @code{ALTER TABLE}
-or @code{LOAD DATA INFILE}. If the file size would be bigger than this,
+or @code{LOAD DATA INFILE}. If the file-size would be bigger than this,
the index will be created through the key cache (which is slower).
-@strong{NOTE} that this parameter is given in megabytes!
+@strong{Note} that this parameter is given in megabytes!
@item @code{net_buffer_length}
The communication buffer is reset to this size between queries. This
@@ -20125,7 +20077,7 @@ is automatically enlarged, up to @code{max_allowed_packet} bytes.)
@item @code{net_read_timeout}
Number of seconds to wait for more data from a connection before aborting
the read. Note that when we don't expect data from a connection, the timeout
-is defined by @code{write_timeout}. See also @code{slave_read_timeout}.
+is defined by @code{write_timeout}. See also @code{slave_net_timeout}.
@item @code{net_retry_count}
If a read on a communication port is interrupted, retry this many times
@@ -20153,25 +20105,39 @@ The value of the @code{--port} option.
@item @code{protocol_version}
The protocol version used by the MySQL server.
-@item @code{record_buffer}
+@item @code{read_buffer_size} (was @code{record_buffer})
Each thread that does a sequential scan allocates a buffer of this
size for each table it scans. If you do many sequential scans, you may
want to increase this value.
-@item @code{record_rnd_buffer}
-When reading rows in sorted order after a sort, the rows are read through this
-buffer to avoid a disk seeks. If not set, then it's set to the value of
-@code{record_buffer}.
-
-@item @code{query_buffer_size}
-The initial allocation of the query buffer. If most of your queries are
-long (like when inserting blobs), you should increase this!
+@item @code{record_rnd_buffer_size}
+When reading rows in sorted order after a sort, the rows are read
+through this buffer to avoid a disk seeks. Can improve @code{ORDER BY}
+by a lot if set to a high value. As this is a thread specific variable,
+one should not set this big globally, but just change this when running
+some specific big queries.
+
+@item @code{query_cache_limit}
+Don't cache results that are bigger than this. (Default 1M).
+
+@item @code{query_cache_size}
+The memory allocated to store results from old queries.
+If this is 0, the query cache is disabled (default).
+
+@item @code{query_cache_type}
+This may be set (only numeric) to
+@multitable @columnfractions .09 .14 .72
+@item @strong{Value} @tab @strong{Alias} @tab @strong{Comment}
+@item 0 @tab OFF @tab Don't cache or retrieve results.
+@item 1 @tab ON @tab Cache all results except @code{SELECT SQL_NO_CACHE ...} queries.
+@item 2 @tab DEMAND @tab Cache only @code{SELECT SQL_CACHE ...} queries.
+@end multitable
-@item @code{safe_show_databases}
+@item @code{safe_show_database}
Don't show databases for which the user doesn't have any database or
table privileges. This can improve security if you're concerned about
people being able to see what databases other users have. See also
-@code{skip_show_databases}.
+@code{skip_show_database}.
@item @code{server_id}
The value of the @code{--server-id} option.
@@ -20182,13 +20148,13 @@ Is OFF if @code{mysqld} uses external locking.
@item @code{skip_networking}
Is ON if we only allow local (socket) connections.
-@item @code{skip_show_databases}
+@item @code{skip_show_database}
This prevents people from doing @code{SHOW DATABASES} if they don't have
-the @code{PROCESS_PRIV} privilege. This can improve security if you're
+the @code{PROCESS} privilege. This can improve security if you're
concerned about people being able to see what databases other users
-have. See also @code{safe_show_databases}.
+have. See also @code{safe_show_database}.
-@item @code{slave_read_timeout}
+@item @code{slave_net_timeout}
Number of seconds to wait for more data from a master/slave connection
before aborting the read.
@@ -20208,22 +20174,16 @@ operations.
@item @code{table_cache}
The number of open tables for all threads. Increasing this value
increases the number of file descriptors that @code{mysqld} requires.
-MySQL needs two file descriptors for each unique open table.
-See below for comments on file descriptor limits. You can check if you
-need to increase the table cache by checking the @code{Opened_tables}
-variable. @xref{SHOW}. If this variable is big and you don't do
-@code{FLUSH TABLES} a lot (which just forces all tables to be closed and
-reopenend), then you should increase the value of this variable.
-
-Make sure that your operating system can handle the number of open file
-descriptors implied by the @code{table_cache} setting. If @code{table_cache}
-is set too high, MySQL may run out of file descriptors and refuse
-connections, fail to perform queries, and be very unreliable.
+You can check if you need to increase the table cache by checking the
+@code{Opened_tables} variable. @xref{SHOW, , @code{SHOW}}. If this variable
+is big and you don't do @code{FLUSH TABLES} a lot (which just forces all
+tables to be closed and reopenend), then you should increase the value of this
+variable.
-For information about how the table cache works, see @ref{Table cache}.
+For more information about the table cache, see @ref{Table cache}.
@item @code{table_type}
-The default table type
+The default table type.
@item @code{thread_cache_size}
How many threads we should keep in a cache for reuse. When a
@@ -20234,8 +20194,9 @@ is a new thread created. This variable can be increased to improve
performance if you have a lot of new connections. (Normally this doesn't
give a notable performance improvement if you have a good
thread implementation.) By examing the difference between
-the @code{Connections} and @code{Threads_created} you can see how efficient
-the current thread cache is for you.
+the @code{Connections} and @code{Threads_created} status variables
+(See @ref{SHOW STATUS} for details) you can see how efficient
+thread cache is.
@item @code{thread_concurrency}
On Solaris, @code{mysqld} will call @code{thr_setconcurrency()} with
@@ -20266,7 +20227,7 @@ The version number for the server.
@item @code{wait_timeout}
The number of seconds the server waits for activity on a connection before
closing it. See also @code{interactive_timeout}.
-@end table
+@end itemize
The manual section that describes tuning MySQL contains some
information of how to tune the above variables. @xref{Server parameters}.
@@ -20298,19 +20259,119 @@ subsystem)
@cindex threads, display
@cindex processes, display
-@code{SHOW PROCESSLIST} shows you which threads are running. You can
-also get this information using the @code{mysqladmin processlist}
-command. If you have the @strong{process} privilege, you can see all
-threads. Otherwise, you can see only your own threads. @xref{KILL, ,
-@code{KILL}}. If you don't use the @code{FULL} option, then only
-the first 100 characters of each query will be shown.
+@code{SHOW [FULL] PROCESSLIST} shows you which threads are running.
+You can also get this information using the @code{mysqladmin processlist}
+command. If you have the @code{SUPER} privilege, you can see all
+threads. Otherwise, you can see only your own threads.
+@xref{KILL, ,@code{KILL}}.
+If you don't use the @code{FULL} option, then only the first 100
+characters of each query will be shown.
This command is very useful if you get the 'too many connections' error
message and want to find out what's going on. MySQL reserves
-one extra connection for a client with the @code{Process_priv} privilege
+one extra connection for a client with the @code{SUPER} privilege
to ensure that you should always be able to login and check the system
(assuming you are not giving this privilege to all your users).
+Some states commonly seen in @code{mysqladmin processlist}
+
+@itemize @bullet
+@item @code{Checking table}
+The thread is performing [automatic] checking of the table.
+@item @code{Closing tables}
+Means that the thread is flushing the changed table data to disk and
+closing the used tables. This should be a fast operation. If not, then
+you should check that you don't have a full disk or that the disk is not
+in very heavy use.
+@item @code{Connect Out}
+Slave connecting to master.
+@item @code{Copying to tmp table on disk}
+The temporary result set was larger than @code{tmp_table_size} and the
+thread is now changing the in memory-based temporary table to a disk
+based one to save memory.
+@item @code{Creating tmp table}
+The thread is creating a temporary table to hold a part of the result for
+the query.
+@item @code{deleting from main table}
+When executing the first part of a multi-table delete and we are only
+deleting from the first table.
+@item @code{deleting from reference tables}
+When executing the second part of a multi-table delete and we are deleting
+the matched rows from the other tables.
+@item @code{Flushing tables}
+The thread is executing @code{FLUSH TABLES} and is waiting for all
+threads to close their tables.
+@item @code{Killed}
+Someone has sent a kill to the thread and it should abort next time it
+checks the kill flag. The flag is checked in each major loop in MySQL,
+but in some cases it may still take a short time for the thread to die.
+If the thread is locked by some other thread, the kill will take affect
+as soon as the other thread releases it's lock.
+@item @code{Sending data}
+The thread is processing rows for a @code{SELECT} statement and is
+also sending data to the client.
+@item @code{Sorting for group}
+The thread is doing a sort to satsify a @code{GROUP BY}.
+@item @code{Sorting for order}
+The thread is doing a sort to satsify a @code{ORDER BY}.
+@item @code{Opening tables}
+This simply means that the thread is trying to open a table. This is
+should be very fast procedure, unless something prevents opening. For
+example an @code{ALTER TABLE} or a @code{LOCK TABLE} can prevent opening
+a table until the command is finished.
+@item @code{Removing duplicates}
+The query was using @code{SELECT DISTINCT} in such a way that MySQL
+couldn't optimize that distinct away at an early stage. Because of this
+MySQL has to do an extra stage to remove all duplicated rows before
+sending the result to the client.
+@item @code{Reopen table}
+The thread got a lock for the table, but noticed after getting the lock
+that the underlying table structure changed. It has freed the lock,
+closed the table and is now trying to reopen it.
+@item @code{Repair by sorting}
+The repair code is using sorting to create indexes.
+@item @code{Repair with keycache}
+The repair code is using creating keys one by one through the key cache.
+This is much slower than @code{Repair by sorting}.
+@item @code{Searching rows for update}
+The thread is doing a first phase to find all matching rows before
+updating them. This has to be done if the @code{UPDATE} is changing
+the index that is used to find the involved rows.
+@item @code{Sleeping}
+The thread is wating for the client to send a new command to it.
+@item @code{System lock}
+The thread is waiting for getting to get a external system lock for the
+table. If you are not using multiple mysqld servers that are accessing
+the same tables, you can disable system locks with the
+@code{--skip-external-locking} option.
+@item @code{Upgrading lock}
+The @code{INSERT DELAYED} handler is trying to get a lock for the table
+to insert rows.
+@item @code{Updating}
+The thread is searching for rows to update and updating them.
+@item @code{User Lock}
+The thread is waiting on a @code{GET_LOCK()}.
+@item @code{Waiting for tables}
+The thread got a notification that the underlying structure for a table
+has changed and it needs to reopen the table to get the new structure.
+To be able to reopen the table it must however wait until all other
+threads have closed the table in question.
+
+This notification happens if another thread has used @code{FLUSH TABLES}
+or one of the following commands on the table in question: @code{FLUSH
+TABLES table_name}, @code{ALTER TABLE}, @code{RENAME TABLE},
+@code{REPAIR TABLE}, @code{ANALYZE TABLE} or @code{OPTIMIZE TABLE}.
+@item @code{waiting for handler insert}
+The @code{INSERT DELAYED} handler has processed all inserts and are
+waiting to get new ones.
+@end itemize
+
+Most states are very quick operations. If threads last in any of these
+states for many seconds, there may be a problem around that needs to be
+investigated.
+
+There are some other states that are not mentioned previously, but most of
+these are only useful to find bugs in @code{mysqld}.
@node SHOW GRANTS, SHOW CREATE TABLE, SHOW PROCESSLIST, SHOW
@subsubsection @code{SHOW GRANTS}
@@ -20336,7 +20397,7 @@ mysql> SHOW GRANTS FOR root@@localhost;
Shows a @code{CREATE TABLE} statement that will create the given table:
@example
-mysql> show create table t\G
+mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE t (
@@ -20349,23 +20410,24 @@ Create Table: CREATE TABLE t (
@code{SHOW CREATE TABLE} will quote table and column names according to
@code{SQL_QUOTE_SHOW_CREATE} option.
-@ref{SET OPTION, , @code{SET OPTION SQL_QUOTE_SHOW_CREATE}}.
+@ref{SET OPTION, , @code{SET SQL_QUOTE_SHOW_CREATE}}.
-@node Localization, Server-Side Scripts, Database Administration, MySQL Database Administration
-@section MySQL Localization and International Usage
+@node Localisation, Server-Side Scripts, Database Administration, MySQL Database Administration
+@section MySQL Localisation and International Usage
@menu
* Character sets:: The Character Set Used for Data and Sorting
* Languages:: Non-English Error Messages
* Adding character set:: Adding a New Character Set
-* Character arrays:: The character definition arrays
+* Character arrays:: The Character Definition Arrays
* String collating:: String Collating Support
* Multi-byte characters:: Multi-byte Character Support
+* Problems with character sets:: Problems With Character Sets
@end menu
-@node Character sets, Languages, Localization, Localization
+@node Character sets, Languages, Localisation, Localisation
@subsection The Character Set Used for Data and Sorting
@cindex character sets
@@ -20394,8 +20456,8 @@ character set configuration files listed in
@file{SHAREDIR/charsets/Index}. @xref{configure options}.
If you change the character set when running MySQL (which may
-also change the sort order), you must run myisamchk -r -q on all
-tables. Otherwise your indexes may not be ordered correctly.
+also change the sort order), you must run @code{myisamchk -r -q} on all
+tables. Otherwise, your indexes may not be ordered correctly.
When a client connects to a MySQL server, the server sends the
default character set in use to the client. The client will switch to
@@ -20403,11 +20465,11 @@ use this character set for this connection.
One should use @code{mysql_real_escape_string()} when escaping strings
for a SQL query. @code{mysql_real_escape_string()} is identical to the
-old @code{mysql_escape_string()} function, except that it takes the MYSQL
+old @code{mysql_escape_string()} function, except that it takes the @code{MYSQL}
connection handle as the first parameter.
If the client is compiled with different paths than where the server is
-installed and the user who configured MySQL didn't included all
+installed and the user who configured MySQL didn't include all
character sets in the MySQL binary, one must specify for
the client where it can find the additional character sets it will need
if the server runs with a different character set than the client.
@@ -20419,8 +20481,8 @@ One can specify this by putting in a MySQL option file:
character-sets-dir=/usr/local/mysql/share/mysql/charsets
@end example
-where the path points to where the dynamic MySQL character sets
-are stored.
+where the path points to the directory in which the dynamic MySQL character
+sets are stored.
One can force the client to use specific character set by specifying:
@@ -20431,8 +20493,37 @@ default-character-set=character-set-name
but normally this is never needed.
+@menu
+* German character set:: German character set
+@end menu
+
+@node German character set, , Character sets, Character sets
+@subsubsection German character set
-@node Languages, Adding character set, Character sets, Localization
+To get German sorting order, you should start @code{mysqld} with
+@code{--default-character-set=latin_de}. This will give you the following
+characteristics.
+
+When sorting and comparing string's the following mapping is done on the
+strings before doing the comparison:
+
+@example
+ä -> ae
+ö -> oe
+ü -> ue
+ß -> ss
+@end example
+
+All accented characters, are converted to their un-accented uppercase
+counterpart. All letters are converted to uppercase.
+
+When comparing strings with @code{LIKE} the one -> two character mapping
+is not done. All letters are converted to uppercase. Accent are removed
+from all letters except: @code{Ü}, @code{ü}, @code{Ö}, @code{ö},
+@code{Ä} and @code{ä}.
+
+
+@node Languages, Adding character set, Character sets, Localisation
@subsection Non-English Error Messages
@cindex error messages, languages
@@ -20474,7 +20565,7 @@ If you upgrade to a newer version of MySQL, remember to repeat
your changes with the new @file{errmsg.txt} file.
-@node Adding character set, Character arrays, Languages, Localization
+@node Adding character set, Character arrays, Languages, Localisation
@subsection Adding a New Character Set
@cindex character sets, adding
@@ -20502,7 +20593,7 @@ Assign an unique number to it.
@item
Create the file @file{sql/share/charsets/MYSET.conf}.
-(You can use @file{sql/share/charsets/latin1.conf} as a base for this).
+(You can use @file{sql/share/charsets/latin1.conf} as a base for this.)
The syntax for the file very simple:
@@ -20568,7 +20659,7 @@ The @code{configure} program uses this comment to include
the character set into the MySQL library automatically.
The strxfrm_multiply and mbmaxlen lines will be explained in
-the following sections. Only include them if you the string
+the following sections. Only include these if you need the string
collating functions or the multi-byte character set functions,
respectively.
@@ -20598,8 +20689,8 @@ If you want to have the character set included in the MySQL
distribution, mail a patch to @email{internals@@lists.mysql.com}.
-@node Character arrays, String collating, Adding character set, Localization
-@subsection The character definition arrays
+@node Character arrays, String collating, Adding character set, Localisation
+@subsection The Character Definition Arrays
@code{to_lower[]} and @code{to_upper[]} are simple arrays that hold the
lowercase and uppercase characters corresponding to each member of the
@@ -20612,7 +20703,7 @@ to_upper['a'] should contain 'A'
@code{sort_order[]} is a map indicating how characters should be ordered for
comparison and sorting purposes. For many character sets, this is the same as
-@code{to_upper[]} (which means sorting will be case insensitive).
+@code{to_upper[]} (which means sorting will be case-insensitive).
MySQL will sort characters based on the value of
@code{sort_order[character]}. For more complicated sorting rules, see
the discussion of string collating below. @xref{String collating}.
@@ -20620,7 +20711,7 @@ the discussion of string collating below. @xref{String collating}.
@code{ctype[]} is an array of bit values, with one element for one character.
(Note that @code{to_lower[]}, @code{to_upper[]}, and @code{sort_order[]}
are indexed by character value, but @code{ctype[]} is indexed by character
-value + 1. This is an old legacy to be able to handle EOF.)
+value + 1. This is an old legacy to be able to handle @code{EOF}.)
You can find the following bitmask definitions in @file{m_ctype.h}:
@@ -20646,7 +20737,7 @@ _U + _X = 01 + 0200 = 0201
@end example
-@node String collating, Multi-byte characters, Character arrays, Localization
+@node String collating, Multi-byte characters, Character arrays, Localisation
@subsection String Collating Support
@cindex collating, strings
@@ -20657,8 +20748,8 @@ with the simple @code{sort_order[]} table, you need to use the string
collating functions.
Right now the best documentation on this is the character sets that are
-already implemented. Look at the big5, czech, gbk, sjis, and tis160
-character sets for examples.
+already implemented. Look at the @code{big5}, @code{czech}, @code{gbk},
+@code{sjis}, and @code{tis160} character sets for examples.
You must specify the @code{strxfrm_multiply_MYSET=N} value in the
special comment at the top of the file. @code{N} should be set to
@@ -20666,7 +20757,7 @@ the maximum ratio the strings may grow during @code{my_strxfrm_MYSET} (it
must be a positive integer).
-@node Multi-byte characters, , String collating, Localization
+@node Multi-byte characters, Problems with character sets, String collating, Localisation
@subsection Multi-byte Character Support
@cindex characters, multi-byte
@@ -20685,16 +20776,51 @@ You must specify the @code{mbmaxlen_MYSET=N} value in the special
comment at the top of the source file. @code{N} should be set to the
size in bytes of the largest character in the set.
+@node Problems with character sets, , Multi-byte characters, Localisation
+@subsection Problems With Character Sets
+
+If you try to use a character set that is not compiled into your binary,
+you can run into a couple of different problems:
+
+@itemize @bullet
+@item
+Your program has a wrong path to where the character sets are stored.
+(Default @file{/usr/local/mysql/share/mysql/charsets}).
+This can be fixed by using the @code{--character-sets-dir}
+option to the program in question.
+@item
+The character set is a multi-byte-character set that can't be loaded
+dynamically. In this case you have to recompile the program with the
+support for the character set.
+@item
+The character set is a dynamic character set, but you don't have a
+configure file for it. In this case you should install the configure
+file for the character set from a new MySQL distribution.
+@item
+Your @file{Index} file doesn't contain the name for the character set.
+
+@example
+ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found
+(Errcode: 2)
+@end example
+
+In this case you should either get a new @code{Index} file or add
+by hand the name of any missing character sets.
+@end itemize
+
+For MyISAM tables, you can check the character set name and number for a
+table with @code{myisamchk -dvv table_name}.
+
-@node Server-Side Scripts, Client-Side Scripts, Localization, MySQL Database Administration
+@node Server-Side Scripts, Client-Side Scripts, Localisation, MySQL Database Administration
@section MySQL Server-Side Scripts and Utilities
@menu
* Server-Side Overview:: Overview of the Server-Side Scripts and Utilities
-* safe_mysqld:: safe_mysqld, the wrapper around mysqld
-* mysqld_multi:: mysqld_multi, program for managing multiple MySQL servers
-* myisampack:: myisampack, The MySQL Compressed Read-only Table Generator
-* mysqld-max:: mysqld-max, An extended mysqld server
+* safe_mysqld:: @code{safe_mysqld}, The Wrapper Around @code{mysqld}
+* mysqld_multi:: @code{mysqld_multi}, Program for Managing Multiple MySQL Servers
+* myisampack:: @code{myisampack}, The MySQL Compressed Read-only Table Generator
+* mysqld-max:: @code{mysqld-max}, An Extended @code{mysqld} Server
@end menu
@@ -20715,7 +20841,7 @@ All MySQL clients that communicate with the server using the
@tindex environment variable, @code{MYSQL_PWD}
@tindex @code{MYSQL_DEBUG} environment variable
@tindex environment variable, @code{MYSQL_DEBUG}
-@multitable @columnfractions .25 .75
+@multitable @columnfractions .25 .60
@item @strong{Name} @tab @strong{Description}
@item @code{MYSQL_UNIX_PORT} @tab The default socket; used for connections to @code{localhost}
@item @code{MYSQL_TCP_PORT} @tab The default TCP/IP port
@@ -20732,7 +20858,7 @@ Use of @code{MYSQL_PWD} is insecure.
@tindex @code{HOME} environment variable
@tindex environment variable, @code{HOME}
@cindex history file
-@cindex command line history
+@cindex command-line history
@tindex .mysql_history file
The @file{mysql} client uses the file named in the @code{MYSQL_HISTFILE}
environment variable to save the command-line history. The default value for
@@ -20747,13 +20873,13 @@ to get a full description of the program's different options. For example, try
You can override default options for all standard client programs with an
option file. @ref{Option files}.
-The list below briefly describes the MySQL programs:
+The following list briefly describes the MySQL programs:
@table @code
@cindex @code{myisamchk}
@item myisamchk
-Utility to describe, check, optimize, and repair MySQL tables.
+Utility to describe, check, optimise, and repair MySQL tables.
Because @code{myisamchk} has many functions, it is described in its own
chapter. @xref{MySQL Database Administration}.
@@ -20826,7 +20952,7 @@ shell> replace a b b a -- file1 file2 ...
@node safe_mysqld, mysqld_multi, Server-Side Overview, Server-Side Scripts
-@subsection safe_mysqld, the wrapper around mysqld
+@subsection @code{safe_mysqld}, The Wrapper Around @code{mysqld}
@cindex tools, safe_mysqld
@cindex scripts
@@ -20841,17 +20967,17 @@ If you don't use @code{--mysqld=#} or @code{--mysqld-version=#}
@code{safe_mysqld} will use an executable named @code{mysqld-max} if it
exists. If not, @code{safe_mysqld} will start @code{mysqld}.
This makes it very easy to test to use @code{mysqld-max} instead of
-@code{mysqld}; Just copy @code{mysqld-max} to where you have
+@code{mysqld}; just copy @code{mysqld-max} to where you have
@code{mysqld} and it will be used.
Normally one should never edit the @code{safe_mysqld} script, but
instead put the options to @code{safe_mysqld} in the
-@code{[safe_mysqld]} section in the @code{my.cnf}
+@code{[safe_mysqld]} section in the @file{my.cnf}
file. @code{safe_mysqld} will read all options from the @code{[mysqld]},
@code{[server]} and @code{[safe_mysqld]} sections from the option files.
@xref{Option files}.
-Note that all options on the command line to @code{safe_mysqld} are passed
+Note that all options on the command-line to @code{safe_mysqld} are passed
to @code{mysqld}. If you wants to use any options in @code{safe_mysqld} that
@code{mysqld} doesn't support, you must specify these in the option file.
@@ -20932,7 +21058,7 @@ edited version that you can reinstall.
@node mysqld_multi, myisampack, safe_mysqld, Server-Side Scripts
-@subsection mysqld_multi, program for managing multiple MySQL servers
+@subsection @code{mysqld_multi}, Program for Managing Multiple MySQL Servers
@cindex tools, mysqld_multi
@cindex scripts
@@ -20940,17 +21066,17 @@ edited version that you can reinstall.
@cindex @code{mysqld_multi}
@code{mysqld_multi} is meant for managing several @code{mysqld}
-processes running in different UNIX sockets and TCP/IP ports.
+processes running in different Unix sockets and TCP/IP ports.
The program will search for group(s) named [mysqld#] from my.cnf (or the
given --config-file=...), where # can be any positive number starting
from 1. These groups should be the same as the usual @code{[mysqld]}
-group (e.g. options to mysqld, see MySQL manual for detailed
-information about this group), but with those port, socket etc. options
+group (e.g., options to @code{mysqld}, see the MySQL manual for detailed
+information about this group), but with those port, socket, etc. options
that are wanted for each separate @code{mysqld} processes. The number in
the group name has another function; it can be used for starting,
stopping, or reporting some specific @code{mysqld} servers with this
-program. See the usage and options below for more information.
+program. See the usage and options here for more information.
@example
Usage: mysqld_multi [OPTIONS] @{start|stop|report@} [GNR,GNR,GNR...]
@@ -20959,7 +21085,7 @@ or mysqld_multi [OPTIONS] @{start|stop|report@} [GNR-GNR,GNR,GNR-GNR,...]
The GNR above means the group number. You can start, stop or report
any GNR, or several of them at the same time. (See --example) The GNRs
-list can be comma separated, or a dash combined, of which the latter
+list can be comma separated or combined with a dash, of which the latter
means that all the GNRs between GNR1-GNR2 will be affected. Without
GNR argument all the found groups will be either started, stopped, or
reported. Note that you must not have any white spaces in the GNR
@@ -20970,7 +21096,7 @@ list. Anything after a white space is ignored.
@table @code
@cindex config-file option
@item --config-file=...
-Alternative config file. NOTE: This will not affect this program's own
+Alternative config file. Note: This will not affect this program's own
options (group @code{[mysqld_multi]}), but only groups
[mysqld#]. Without this option everything will be searched from the
ordinary my.cnf file.
@@ -20982,7 +21108,7 @@ Give an example of a config file.
Print this help and exit.
@cindex log option
@item --log=...
-Log file. Full path to and the name for the log file. NOTE: If the file
+Log file. Full path to and the name for the log file. Note: If the file
exists, everything will be appended.
@cindex mysqladmin option
@item --mysqladmin=...
@@ -21003,9 +21129,9 @@ Password for user for @code{mysqladmin}.
@cindex tcp-ip option
@item --tcp-ip
Connect to the MySQL server(s) via the TCP/IP port instead of
-the UNIX socket. This affects stopping and reporting. If a socket file
+the Unix socket. This affects stopping and reporting. If a socket file
is missing, the server may still be running, but can be accessed only
-via the TCP/IP port. By default connecting is done via the UNIX socket.
+via the TCP/IP port. By default connecting is done via the Unix socket.
@cindex user option
@item --user=...
MySQL user for @code{mysqladmin}.
@@ -21032,17 +21158,17 @@ shell> mysql -u root -S /tmp/mysql.sock -proot_password -e
@xref{Privileges}.
@end example
You will have to do the above for each @code{mysqld} running in each
-data directory, that you have (just change the socket, -S=...)
+data directory, that you have (just change the socket, -S=...).
@item
@code{pid-file} is very important, if you are using @code{safe_mysqld}
-to start @code{mysqld} (e.g. --mysqld=safe_mysqld) Every @code{mysqld}
+to start @code{mysqld} (e.g., @code{--mysqld=safe_mysqld}) Every @code{mysqld}
should have its own @code{pid-file}. The advantage using
@code{safe_mysqld} instead of @code{mysqld} directly here is, that
@code{safe_mysqld} 'guards' every @code{mysqld} process and will restart
it, if a @code{mysqld} process fails due to signal kill -9, or
similar. (Like segmentation fault, which MySQL should never do,
of course ;) Please note that @code{safe_mysqld} script may require that
-you start it from a certain place. This means that you may have to CD to
+you start it from a certain place. This means that you may have to @code{cd} to
a certain directory, before you start the @code{mysqld_multi}. If
you have problems starting, please see the @code{safe_mysqld}
script. Check especially the lines:
@@ -21056,8 +21182,8 @@ release) if test -d /data/mysql -a -f ./share/mysql/english/errmsg.sys
@end example
The above test should be successful, or you may encounter problems.
@item
-Beware of the dangers starting multiple @code{mysqlds} in the same data
-directory. Use separate data directories, unless you @strong{KNOW} what
+Beware of the dangers starting multiple @code{mysqld}s in the same data
+directory. Use separate data directories, unless you @strong{know} what
you are doing!
@item
The socket file and the TCP/IP port must be different for every @code{mysqld}.
@@ -21068,23 +21194,23 @@ more flexibility. The order in which the @code{mysqlds} are started or
stopped depends on the order in which they appear in the config file.
@item
When you want to refer to a certain group using GNR with this program,
-just use the number in the end of the group name ( [mysqld# <== ).
+just use the number in the end of the group name ([mysqld# <== ).
@item
You may want to use option '--user' for @code{mysqld}, but in order to
do this you need to be root when you start the @code{mysqld_multi}
script. Having the option in the config file doesn't matter; you will
just get a warning, if you are not the superuser and the @code{mysqlds}
-are started under @strong{YOUR} UNIX account. @strong{IMPORTANT}: Make
+are started under @strong{your} Unix account. @strong{Important}: Make
sure that the @code{pid-file} and the data directory are
-read+write(+execute for the latter one) accessible for @strong{THAT}
-UNIX user, who the specific @code{mysqld} process is started
-as. @strong{DON'T} use the UNIX root account for this, unless you
-@strong{KNOW} what you are doing!
-@item
-@strong{MOST IMPORTANT}: Make sure that you understand the meanings of
-the options that are passed to the @code{mysqlds} and why @strong{WOULD
-YOU WANT} to have separate @code{mysqld} processes. Starting multiple
-@code{mysqlds} in one data directory @strong{WILL NOT} give you extra
+read+write(+execute for the latter one) accessible for @strong{that}
+Unix user, who the specific @code{mysqld} process is started
+as. @strong{Do not} use the Unix root account for this, unless you
+@strong{know} what you are doing!
+@item
+@strong{Most important}: Make sure that you understand the meanings of
+the options that are passed to the @code{mysqld}s and @strong{why one
+would want} to have separate @code{mysqld} processes. Starting multiple
+@code{mysqld}s in one data directory @strong{will not} give you extra
performance in a threaded system!
@end itemize
@@ -21139,7 +21265,7 @@ user = jani
@node myisampack, mysqld-max, mysqld_multi, Server-Side Scripts
-@subsection myisampack, The MySQL Compressed Read-only Table Generator
+@subsection @code{myisampack}, The MySQL Compressed Read-only Table Generator
@cindex compressed tables
@cindex tables, compressed
@@ -21157,22 +21283,22 @@ The information needed to decompress columns is read into memory when the
table is opened. This results in much better performance when accessing
individual records, because you only have to uncompress exactly one record, not
a much larger disk block as when using Stacker on MS-DOS.
-Usually, @code{myisampack} packs the data file 40%-70%.
+Usually, @code{myisampack} packs the datafile 40%-70%.
MySQL uses memory mapping (@code{mmap()}) on compressed tables and
falls back to normal read/write file usage if @code{mmap()} doesn't work.
-There are currently two limitations with @code{myisampack}:
+Please note the following:
@itemize @bullet
@item
-After packing, the table is read-only.
+After packing, the table is read-only. This is generally intended
+(such as when accessing packed tables on a CD). Also allowing writes
+to a packed table is on our TODO list but with low priority.
@item
-@code{myisampack} can also pack @code{BLOB} or @code{TEXT} columns. The
-older @code{pack_isam} could not do this.
+@code{myisampack} can also pack @code{BLOB} or @code{TEXT} columns.
+The older @code{pack_isam} (for @code{ISAM} tables) can not do this.
@end itemize
-Fixing these limitations is on our TODO list but with low priority.
-
@code{myisampack} is invoked like this:
@example
@@ -21205,9 +21331,9 @@ it finds that @file{tbl_name.TMD} exists. With @code{--force},
Display a help message and exit.
@item -j big_tbl_name, --join=big_tbl_name
-Join all tables named on the command line into a single table
+Join all tables named on the command-line into a single table
@code{big_tbl_name}. All tables that are to be combined
-MUST be identical (same column names and types, same indexes, etc.).
+@strong{must} be identical (same column names and types, same indexes, etc.).
@item -p #, --packlength=#
Specify the record length storage size, in bytes. The value should be 1, 2,
@@ -21236,13 +21362,13 @@ Display version information and exit.
@item -w, --wait
Wait and retry if table is in use. If the @code{mysqld} server was
-invoked with the @code{--skip-locking} option, it is not a good idea to
-invoke @code{myisampack} if the table might be updated during the
+invoked with the @code{--skip-external-locking} option, it is not a good idea
+to invoke @code{myisampack} if the table might be updated during the
packing process.
@end table
@cindex examples, compressed tables
-The sequence of commands shown below illustrates a typical table compression
+The sequence of commands shown here illustrates a typical table compression
session:
@example
@@ -21421,7 +21547,7 @@ Field Start Length Type Huff tree Bits
57 831 4 no zeros, zerofill(1) 2 9
@end example
-The information printed by @code{myisampack} is described below:
+The information printed by @code{myisampack} is described here:
@table @code
@item normal
@@ -21507,7 +21633,7 @@ The number of bits used in the Huffman tree.
After you have run @code{pack_isam}/@code{myisampack} you must run
@code{isamchk}/@code{myisamchk} to re-create the index. At this time you
can also sort the index blocks and create statistics needed for
-the MySQL optimizer to work more efficiently:
+the MySQL optimiser to work more efficiently:
@example
myisamchk -rq --analyze --sort-index table_name.MYI
@@ -21523,36 +21649,36 @@ If you want to unpack a packed table, you can do this with the
@node mysqld-max, , myisampack, Server-Side Scripts
-@subsection mysqld-max, An extended mysqld server
+@subsection @code{mysqld-max}, An Extended @code{mysqld} Server
@cindex @code{mysqld-max}
@code{mysqld-max} is the MySQL server (@code{mysqld}) configured with
the following configure options:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .30 .45
@item @strong{Option} @tab @strong{Comment}
@item --with-server-suffix=-max @tab Add a suffix to the @code{mysqld} version string.
-@item --with-bdb @tab Support for Berkeley DB (BDB) tables
@item --with-innodb @tab Support for InnoDB tables.
+@item --with-bdb @tab Support for Berkeley DB (BDB) tables
@item CFLAGS=-DUSE_SYMDIR @tab Symbolic links support for Windows.
@end multitable
You can find the MySQL-max binaries at
@uref{http://www.mysql.com/downloads/mysql-max-3.23.html}.
-The Windows MySQL 3.23 binary distribution includes both the
+The Windows MySQL binary distributions includes both the
standard @code{mysqld.exe} binary and the @code{mysqld-max.exe} binary.
@uref{http://www.mysql.com/downloads/mysql-3.23.html}.
@xref{Windows installation}.
-Note that as Berkeley DB and InnoDB are not available for all platforms,
+Note that as InnoDB and Berkeley DB are not available for all platforms,
some of the @code{Max} binaries may not have support for both of these.
You can check which table types are supported by doing the following
query:
@example
-mysql> show variables like "have_%";
+mysql> SHOW VARIABLES LIKE "have_%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
@@ -21560,20 +21686,20 @@ mysql> show variables like "have_%";
| have_innodb | NO |
| have_isam | YES |
| have_raid | NO |
-| have_ssl | NO |
+| have_openssl | NO |
+---------------+-------+
@end example
The meaning of the values are:
-@multitable @columnfractions .3 .7
-@item @strong{Value} @tab @strong{Meaning}.
-@item YES @tab The option is activated and usable.
-@item NO @tab MySQL is not compiled with support for this option.
-@item DISABLED @tab The xxxx option is disabled because one started @code{mysqld} with @code{--skip-xxxx} or because one didn't start @code{mysqld} with all needed options to enable the option. In this case the @code{hostname.err} file should contain a reason for why the option is disabled.
+@multitable @columnfractions .15 .85
+@item @strong{Value} @tab @strong{Meaning}
+@item @code{YES} @tab The option is activated and usable.
+@item @code{NO} @tab MySQL is not compiled with support for this option.
+@item @code{DISABLED} @tab The xxxx option is disabled because one started @code{mysqld} with @code{--skip-xxxx} or because one didn't start @code{mysqld} with all needed options to enable the option. In this case the @code{hostname.err} file should contain a reason for why the option is disabled.
@end multitable
-@strong{NOTE}: To be able to create InnoDB tables you @strong{MUST} edit
+@strong{Note}: To be able to create InnoDB tables you @strong{must} edit
your startup options to include at least the @code{innodb_data_file_path}
option. @xref{InnoDB start}.
@@ -21581,7 +21707,7 @@ To get better performance for BDB tables, you should add some configuration
options for these too. @xref{BDB start}.
@code{safe_mysqld} will automatically try to start any @code{mysqld} binary
-with the @code{-max} prefix. This makes it very easy to test out a
+with the @code{-max} suffix. This makes it very easy to test out a
another @code{mysqld} binary in an existing installation. Just
run @code{configure} with the options you want and then install the
new @code{mysqld} binary as @code{mysqld-max} in the same directory
@@ -21595,16 +21721,16 @@ feature. It just installs the @code{mysqld-max} executable and
The following table shows which table types our standard @strong{MySQL-Max}
binaries includes:
-@multitable @columnfractions .4 .3 .3
-@item @strong{System} @tab @strong{BDB} @tab @strong{InnoDB}
+@multitable @columnfractions .15 .10 .10
+@item @strong{System} @tab @code{BDB} @tab @code{InnoDB}
@item AIX 4.3 @tab N @tab Y
@item HP-UX 11.0 @tab N @tab Y
@item Linux-Alpha @tab N @tab Y
@item Linux-Intel @tab Y @tab Y
-@item Linux-Ia64 @tab N @tab Y
-@item Solaris-intel @tab N @tab Y
-@item Solaris-sparc @tab Y @tab Y
-@item SCO OSR5 @tab Y @tab Y
+@item Linux-IA64 @tab N @tab Y
+@item Solaris-Intel @tab N @tab Y
+@item Solaris-SPARC @tab Y @tab Y
+@item Caldera (SCO) OSR5 @tab Y @tab Y
@item UnixWare @tab Y @tab Y
@item Windows/NT @tab Y @tab Y
@end multitable
@@ -21616,13 +21742,13 @@ binaries includes:
@menu
* Client-Side Overview:: Overview of the Client-Side Scripts and Utilities
* mysql:: The Command-line Tool
-* mysqladmin:: mysqladmin, Administrating a MySQL Server
+* mysqladmin:: @code{mysqladmin}, Administrating a MySQL Server
* Using mysqlcheck:: Using @code{mysqlcheck} for Table Maintenance and Crash Recovery
-* mysqldump:: mysqldump, Dumping Table Structure and Data
-* mysqlhotcopy:: mysqlhotcopy, Copying MySQL Databases and Tables
-* mysqlimport:: mysqlimport, Importing Data from Text Files
+* mysqldump:: @code{mysqldump}, Dumping Table Structure and Data
+* mysqlhotcopy:: @code{mysqlhotcopy}, Copying MySQL Databases and Tables
+* mysqlimport:: @code{mysqlimport}, Importing Data from Text Files
* mysqlshow:: Showing Databases, Tables, and Columns
-* perror:: perror, Explaining Error Codes
+* perror:: @code{perror}, Explaining Error Codes
* Batch Commands:: How to Run SQL Commands from a Text File
@end menu
@@ -21644,7 +21770,7 @@ All MySQL clients that communicate with the server using the
@tindex environment variable, @code{MYSQL_PWD}
@tindex @code{MYSQL_DEBUG} environment variable
@tindex environment variable, @code{MYSQL_DEBUG}
-@multitable @columnfractions .25 .75
+@multitable @columnfractions .25 .60
@item @strong{Name} @tab @strong{Description}
@item @code{MYSQL_UNIX_PORT} @tab The default socket; used for connections to @code{localhost}
@item @code{MYSQL_TCP_PORT} @tab The default TCP/IP port
@@ -21661,7 +21787,7 @@ Use of @code{MYSQL_PWD} is insecure.
@tindex @code{HOME} environment variable
@tindex environment variable, @code{HOME}
@cindex history file
-@cindex command line history
+@cindex command-line history
@tindex .mysql_history file
The @file{mysql} client uses the file named in the @code{MYSQL_HISTFILE}
environment variable to save the command-line history. The default value for
@@ -21676,13 +21802,13 @@ to get a full description of the program's different options. For example, try
You can override default options for all standard client programs with an
option file. @ref{Option files}.
-The list below briefly describes the MySQL programs:
+The following list briefly describes the MySQL programs:
@table @code
@cindex @code{myisamchk}
@item myisamchk
-Utility to describe, check, optimize, and repair MySQL tables.
+Utility to describe, check, optimise, and repair MySQL tables.
Because @code{myisamchk} has many functions, it is described in its own
chapter. @xref{MySQL Database Administration}.
@@ -21755,10 +21881,10 @@ shell> replace a b b a -- file1 file2 ...
@node mysql, mysqladmin, Client-Side Overview, Client-Side Scripts
-@subsection The Command-line Tool
+@subsection @code{mysql}, The Command-line Tool
-@cindex command line tool
-@cindex tools, command line
+@cindex command-line tool
+@cindex tools, command-line
@cindex scripts
@cindex @code{mysql}
@@ -21780,11 +21906,11 @@ retrieve the result set.
Using @code{mysql} is very easy. Just start it as follows:
@code{mysql database} or @code{mysql --user=user_name --password=your_password database}. Type a SQL statement, end it with @samp{;}, @samp{\g}, or @samp{\G}
-and press RETURN/ENTER.
+and press Enter.
-@cindex @code{mysql} command line options
-@cindex command line options, @code{mysql}
-@cindex options, command line, @code{mysql}
+@cindex @code{mysql} command-line options
+@cindex command-line options, @code{mysql}
+@cindex options, command-line, @code{mysql}
@cindex startup parameters, @code{mysql}
@code{mysql} supports the following options:
@@ -21798,6 +21924,14 @@ Display this help and exit.
No automatic rehashing. One has to use 'rehash' to get table and field
completion. This gives a quicker start of mysql.
+@cindex @code{prompt}, @code{mysql} option
+@item --prompt=...
+Set the mysql prompt to specified format.
+
+@cindex @code{no-beep}, @code{mysql} option
+@item -b, --no-beep
+Turn off beep-on-error.
+
@cindex @code{batch}, @code{mysql} option
@item -B, --batch
Print results with a tab as separator, each row on a new line. Doesn't use
@@ -21817,7 +21951,7 @@ Debug log. Default is 'd:t:o,/tmp/mysql.trace'.
@cindex @code{database}, @code{mysql} option
@item -D, --database=...
-Database to use. This is mainly useful in the @code{my.cnf} file.
+Database to use. This is mainly useful in the @file{my.cnf} file.
@cindex @code{default-character-set}, @code{mysql} option
@item --default-character-set=...
@@ -21839,8 +21973,8 @@ Continue even if we get a SQL error.
@cindex @code{no-named-commands}, @code{mysql} option
@item -g, --no-named-commands
Named commands are disabled. Use \* form only, or use named commands
-only in the beginning of a line ending with a semicolon (;). Since
-Version 10.9, the client now starts with this option ENABLED by default!
+only in the beginning of a line ending with a semicolon (@samp{;}). Since
+Version 10.9, the client now starts with this option @strong{enabled} by default!
With the -g option, long format commands will still work from the first
line, however.
@@ -21895,12 +22029,12 @@ other database in the update log.
@item @code{--pager[=...]}
Output type. Default is your @code{ENV} variable @code{PAGER}. Valid
pagers are less, more, cat [> filename], etc. See interactive help (\h)
-also. This option does not work in batch mode. Pager works only in UNIX.
+also. This option does not work in batch mode. Pager works only in Unix.
@cindex @code{password}, @code{mysql} option
@item -p[password], --password[=...]
Password to use when connecting to server. If a password is not given on
-the command line, you will be prompted for it. Note that if you use the
+the command-line, you will be prompted for it. Note that if you use the
short form @code{-p} you can't have a space between the option and the
password.
@@ -21946,7 +22080,7 @@ User for login if not current user.
@item -U, --safe-updates[=#], --i-am-a-dummy[=#]
Only allow @code{UPDATE} and @code{DELETE} that uses keys. See below for
more information about this option. You can reset this option if you have
-it in your @code{my.cnf} file by using @code{--safe-updates=0}.
+it in your @file{my.cnf} file by using @code{--safe-updates=0}.
@cindex @code{verbose}, @code{mysql} option
@item -v, --verbose
@@ -21970,8 +22104,8 @@ You can also set the following variables with @code{-O} or
@cindex @code{net_buffer_length}
@cindex @code{select_limit}
@cindex @code{max_join_size}
-@multitable @columnfractions .3 .2 .5
-@item Variable Name @tab Default @tab Description
+@multitable @columnfractions .25 .10 .65
+@item @strong{Variable Name} @tab @strong{Default} @tab @strong{Description}
@item connect_timeout @tab 0 @tab Number of seconds before timeout connection.
@item max_allowed_packet @tab 16777216 @tab Max packetlength to send/receive from to server
@item net_buffer_length @tab 16384 @tab Buffer for TCP/IP and socket communication
@@ -21979,7 +22113,7 @@ You can also set the following variables with @code{-O} or
@item max_join_size @tab 1000000 @tab Automatic limit for rows in a join when using --i-am-a-dummy.
@end multitable
-If you type 'help' on the command line, @code{mysql} will print out the
+If you type 'help' on the command-line, @code{mysql} will print out the
commands that it supports:
@cindex commands, list of
@@ -21990,26 +22124,33 @@ MySQL commands:
help (\h) Display this text.
? (\h) Synonym for `help'.
clear (\c) Clear command.
-connect (\r) Reconnect to the server. Optional arguments are db and host.
+connect (\r) Reconnect to the server.
+ Optional arguments are db and host.
edit (\e) Edit command with $EDITOR.
-ego (\G) Send command to mysql server, display result vertically.
+ego (\G) Send command to mysql server,
+ display result vertically.
exit (\q) Exit mysql. Same as quit.
go (\g) Send command to mysql server.
nopager (\n) Disable pager, print to stdout.
notee (\t) Don't write into outfile.
-pager (\P) Set PAGER [to_pager]. Print the query results via PAGER.
+pager (\P) Set PAGER [to_pager].
+ Print the query results via PAGER.
print (\p) Print current command.
+prompt (\R) Change your mysql prompt.
quit (\q) Quit mysql.
rehash (\#) Rebuild completion hash.
-source (\.) Execute a SQL script file. Takes a file name as an argument.
+source (\.) Execute a SQL script file.
+ Takes a file name as an argument.
status (\s) Get status information from the server.
-tee (\T) Set outfile [to_outfile]. Append everything into given outfile.
-use (\u) Use another database. Takes database name as argument.
+tee (\T) Set outfile [to_outfile].
+ Append everything into given outfile.
+use (\u) Use another database.
+ Takes database name as argument.
@end example
-From the above, pager only works in UNIX.
+The @code{pager} command works only in Unix.
-@cindex status command
+@cindex @code{status} command
The @code{status} command gives you some information about the
connection and the server you are using. If you are running in the
@code{--safe-updates} mode, @code{status} will also print the values for
@@ -22029,7 +22170,7 @@ SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
@end example
where @code{#select_limit#} and @code{#max_join_size#} are variables that
-can be set from the @code{mysql} command line. @xref{SET OPTION, @code{SET}}.
+can be set from the @code{mysql} command-line. @xref{SET OPTION, @code{SET}}.
The effect of the above is:
@@ -22044,7 +22185,7 @@ UPDATE table_name SET not_key_column=# WHERE not_key_column=# LIMIT 1;
@item
All big results are automatically limited to @code{#select_limit#} rows.
@item
-@code{SELECT}'s that will probably need to examine more than
+@code{SELECT}s that will probably need to examine more than
@code{#max_join_size} row combinations will be aborted.
@end itemize
@@ -22056,7 +22197,7 @@ includes new lines, is often much easier to be read with vertical
output.
@example
-mysql> select * from mails where length(txt) < 300 limit 300,1\G
+mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 lIMIT 300,1\G
*************************** 1. row ***************************
msg_nro: 3068
date: 2000-03-01 23:29:50
@@ -22068,7 +22209,7 @@ mail_from: Monty
txt: >>>>> "Thimble" == Thimble Smith writes:
Thimble> Hi. I think this is a good idea. Is anyone familiar with UTF-8
-Thimble> or Unicode? Otherwise I'll put this on my TODO list and see what
+Thimble> or Unicode? Otherwise, I'll put this on my TODO list and see what
Thimble> happens.
Yes, please do that.
@@ -22080,36 +22221,35 @@ Monty
1 row in set (0.09 sec)
@end example
-@itemize @bullet
-@item
For logging, you can use the @code{tee} option. The @code{tee} can be
-started with option @code{--tee=...}, or from the command line
+started with option @code{--tee=...}, or from the command-line
interactively with command @code{tee}. All the data displayed on the
screen will also be appended into a given file. This can be very useful
for debugging purposes also. The @code{tee} can be disabled from the
-command line with command @code{notee}. Executing @code{tee} again
+command-line with command @code{notee}. Executing @code{tee} again
starts logging again. Without a parameter the previous file will be
used. Note that @code{tee} will flush the results into the file after
-each command, just before the command line appears again waiting for the
+each command, just before the command-line appears again waiting for the
next command.
-@item
-Browsing, or searching the results in the interactive mode in UNIX less,
+Browsing, or searching the results in the interactive mode in Unix less,
more, or any other similar program, is now possible with option
@code{--pager[=...]}. Without argument, @code{mysql} client will look
for environment variable PAGER and set @code{pager} to that.
-@code{pager} can be started from the interactive command line with
+@code{pager} can be started from the interactive command-line with
command @code{pager} and disabled with command @code{nopager}. The
command takes an argument optionally and the @code{pager} will be set to
that. Command @code{pager} can be called without an argument, but this
requires that the option @code{--pager} was used, or the @code{pager}
-will default to stdout. @code{pager} works only in UNIX, since it uses
+will default to stdout. @code{pager} works only in Unix, since it uses
the popen() function, which doesn't exist in Windows. In Windows, the
@code{tee} option can be used instead, although it may not be as handy
as @code{pager} can be in some situations.
+A few tips about @code{pager}:
+@itemize @bullet
@item
-A few tips about @code{pager}: You can use it to write to a file:
+You can use it to write to a file:
@example
mysql> pager cat > /tmp/log.txt
@end example
@@ -22118,6 +22258,8 @@ for the programs that you want to use with the @code{pager}:
@example
mysql> pager less -n -i -S
@end example
+
+@item
From the above do note the option '-S'. You may find it very useful when
browsing the results; try the option with horizontal output (end
commands with '\g', or ';') and with vertical output (end commands with
@@ -22129,32 +22271,113 @@ readable. You can swith the mode between on and off within the interactive
less with '-S'. See the 'h' for more help about less.
@item
-Last (unless you already understood this from the above examples ;) you
-can combine very complex ways to handle the results, for example the
+You can combine very complex ways to handle the results, for example the
following would send the results to two files in two different
directories, on two different hard-disks mounted on /dr1 and /dr2, yet
let the results still be seen on the screen via less:
@example
-mysql> pager cat | tee /dr1/tmp/res.txt | tee /dr2/tmp/res2.txt | less -n -i -S
+mysql> pager cat | tee /dr1/tmp/res.txt | \
+tee /dr2/tmp/res2.txt | less -n -i -S
@end example
-@item
+@end itemize
+
You can also combine the two functions above; have the @code{tee}
enabled, @code{pager} set to 'less' and you will be able to browse the
results in unix 'less' and still have everything appended into a file
-the same time. The difference between @code{UNIX tee} used with the
+the same time. The difference between Unix @code{tee} used with the
@code{pager} and the @code{mysql} client in-built @code{tee}, is that
-the in-built @code{tee} works even if you don't have the @code{UNIX tee}
+the in-built @code{tee} works even if you don't have the Unix @code{tee}
available. The in-built @code{tee} also logs everything that is printed
-on the screen, where the @code{UNIX tee} used with @code{pager} doesn't
+on the screen, where the Unix @code{tee} used with @code{pager} doesn't
log quite that much. Last, but not least, the interactive @code{tee} is
more handy to switch on and off, when you want to log something into a
file, but want to be able to turn the feature off sometimes.
-@end itemize
+
+@cindex @code{prompt} command
+From MySQL version 4.0.2 it is possible to change the prompt in the
+@code{mysql} command-line client.
+
+You can use the following prompt options:
+@c FIX these columnfractions have NOT been measured!
+@multitable @columnfractions .10 .50
+@item @strong{Option} @tab @strong{Description}
+@item \v @tab mysqld version
+@item \d @tab database in use
+@item \h @tab host connected to
+@item \p @tab port connected on
+@item \u @tab username
+@item \U @tab full username@@host
+@item \\ @tab @samp{\}
+@item \n @tab new line break
+@item \t @tab tab
+@item \ @tab space
+@item \_ @tab space
+@item \R @tab military hour time (0-23)
+@item \r @tab standard hour time (1-12)
+@item \m @tab minutes
+@item \y @tab two digit year
+@item \Y @tab four digit year
+@item \D @tab full date format
+@item \s @tab seconds
+@item \w @tab day of the week in three letter format (Mon, Tue, ...)
+@item \P @tab am/pm
+@item \o @tab month in number format
+@item \O @tab month in three letter format (Jan, Feb, ...)
+@item \c @tab counter that counts up for each command you do
+@end multitable
+
+@samp{\} followed by any other letter just becomes that letter.
+
+You may set the prompt in the following places:
+
+@table @strong
+@item Environment Variable
+You may set the @code{MYSQL_PS1} environment variable to a prompt string. For
+example:
+
+@example
+shell> export MYSQL_PS1="(\u@@\h) [\d]> "
+@end example
+
+@item @file{my.cnf}
+@item @file{.my.cnf}
+You may set the @code{prompt} option in any MySQL configuration file, in the
+@code{mysql} group. For example:
+
+@example
+[mysql]
+prompt=(\u@@\h) [\d]>\_
+@end example
+
+@item Command Line
+You may set the @code{--prompt} option on the command line to @code{mysql}.
+For example:
+
+@example
+shell> mysql --prompt="(\u@@\h) [\d]> "
+
+(user@@host) [database]>
+@end example
+
+@item Interactively
+You may also use the @code{prompt} (or @code{\R}) command to change your
+prompt interactively. For example:
+
+@example
+mysql> prompt (\u@@\h) [\d]>\_
+PROMPT set to '(\u@@\h) [\d]>\_'
+(user@@host) [database]>
+(user@@host) [database]> prompt
+Returning to default PROMPT of mysql>
+mysql>
+@end example
+
+@end table
@node mysqladmin, Using mysqlcheck, mysql, Client-Side Scripts
-@subsection mysqladmin, Administrating a MySQL Server
+@subsection @code{mysqladmin}, Administrating a MySQL Server
@cindex administration, server
@cindex server administration
@@ -22239,14 +22462,17 @@ shell> mysqladmin proc stat
+----+-------+-----------+----+-------------+------+-------+------+
| 6 | monty | localhost | | Processlist | 0 | | |
+----+-------+-----------+----+-------------+------+-------+------+
-Uptime: 10077 Threads: 1 Questions: 9 Slow queries: 0 Opens: 6 Flush tables: 1 Open tables: 2 Memory in use: 1092K Max memory used: 1116K
+Uptime: 10077 Threads: 1 Questions: 9 Slow queries: 0
+Opens: 6 Flush tables: 1 Open tables: 2
+Memory in use: 1092K Max memory used: 1116K
@end example
@cindex status command, results
The @code{mysqladmin status} command result has the following columns:
@cindex uptime
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .20 .65
+@item @strong{Column} @tab @strong{Description}
@item Uptime @tab Number of seconds the MySQL server has been up.
@cindex threads
@item Threads @tab Number of active threads (clients).
@@ -22267,7 +22493,7 @@ The @code{mysqladmin status} command result has the following columns:
@item Max memory used @tab Maximum memory allocated directly by the @code{mysqld} code (only available when MySQL is compiled with --with-debug=full).
@end multitable
-If you do @code{myslqadmin shutdown} on a socket (in other words, on a
+If you do @code{mysqladmin shutdown} on a socket (in other words, on a
the computer where @code{mysqld} is running), @code{mysqladmin} will
wait until the MySQL @code{pid-file} is removed to ensure that
the @code{mysqld} server has stopped properly.
@@ -22299,7 +22525,7 @@ So it can be used in a similar way as @code{mysqldump} when it
comes to what databases and tables you want to choose.
@code{mysqlcheck} does have a special feature compared to the other
-clients; the default behavior, checking tables (-c), can be changed by
+clients; the default behaviour, checking tables (-c), can be changed by
renaming the binary. So if you want to have a tool that repairs tables
by default, you should just copy @code{mysqlcheck} to your harddrive
with a new name, @code{mysqlrepair}, or alternatively make a symbolic
@@ -22307,7 +22533,7 @@ link to @code{mysqlrepair} and name the symbolic link as
@code{mysqlrepair}. If you invoke @code{mysqlrepair} now, it will repair
tables by default.
-The names that you can use to change @code{mysqlcheck} default behavior
+The names that you can use to change @code{mysqlcheck} default behaviour
are here:
@example
@@ -22328,7 +22554,7 @@ Instead of making one query for each table, execute all queries in 1
query separately for each database. Table names will be in a comma
separated list.
@item -a, --analyze
-Analyze given tables.
+Analyse given tables.
@item --auto-repair
If a checked table is corrupted, automatically fix it. Repairing will be
done after all tables have been checked, if corrupted ones were found.
@@ -22346,7 +22572,7 @@ Use compression in server/client protocol.
@item -?, --help
Display this help message and exit.
@item -B, --databases
-To check several databases. Note the difference in usage; In this case
+To check several databases. Note the difference in usage; in this case
no tables are given. All name arguments are regarded as database names.
@item --default-character-set=...
Set the default character set
@@ -22367,7 +22593,7 @@ Connect to host.
Faster than extended-check, but only finds 99.99 percent of all
errors. Should be good enough for most cases.
@item -o, --optimize
-Optimize table
+Optimise table
@item -p, --password[=...]
Password to use when connecting to server. If password is not given
it's solicited on the tty.
@@ -22398,7 +22624,7 @@ Output version information and exit.
@node mysqldump, mysqlhotcopy, Using mysqlcheck, Client-Side Scripts
-@subsection mysqldump, Dumping Table Structure and Data
+@subsection @code{mysqldump}, Dumping Table Structure and Data
@cindex dumping, databases
@cindex databases, dumping
@@ -22488,12 +22714,23 @@ is @code{localhost}.
Lock all tables before starting the dump. The tables are locked with
@code{READ LOCAL} to allow concurrent inserts in the case of @code{MyISAM}
tables.
+
+Please note that when dumping multiple databases, @code{--lock-tables}
+will lock tables for each database separately. So using this option will
+not guarantee your tables will be logically consistent between databases.
+Tables in different databases may be dumped in completely different
+states.
+@item -K, --disable-keys
+@code{/*!40000 ALTER TABLE tb_name DISABLE KEYS */;} and
+@code{/*!40000 ALTER TABLE tb_name ENABLE KEYS */;}
+will be put in the output. This will make loading the data into a MySQL
+4.0 server faster as the indexes are created after all data are inserted.
@item -n, --no-create-db
-'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the
+@code{CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;} will not be put in the
output. The above line will be added otherwise, if --databases or
--all-databases option was given.
@item -t, --no-create-info
-Don't write table creation information (The @code{CREATE TABLE} statement.)
+Don't write table creation information (the @code{CREATE TABLE} statement).
@item -d, --no-data
Don't write any row information for the table. This is very useful if you
just want to get a dump of the structure for a table!
@@ -22512,10 +22749,27 @@ used.)
@item -q, --quick
Don't buffer query, dump directly to stdout. Uses @code{mysql_use_result()}
to do this.
+@item -Q, --quote-names
+Quote table and column names within @samp{`} characters.
@item -r, --result-file=...
Direct output to a given file. This option should be used in MSDOS,
because it prevents new line '\n' from being converted to '\n\r' (new
line + carriage return).
+@item --single-transaction
+This option issues a @code{BEGIN} SQL command before dumping data from
+server. It is mostly useful with @code{InnoDB} tables and
+@code{READ_COMMITTED} transaction isolation level, as in this mode it
+will dump the consistent state of the database at the time then
+@code{BEGIN} was issued without blocking any applications.
+
+When using this option you should keep in mind that only transactional
+tables will be dumped in a consistent state, e.g., any @code{MyISAM} or
+@code{HEAP} tables dumped while using this option may still change
+state.
+
+The @code{--single-transaction} option was added in version 4.0.2.
+This option is mutually exclusive with the @code{--lock-tables} option
+as @code{LOCK TABLES} cancels a previous transaction.
@item -S /path/to/socket, --socket=/path/to/socket
The socket file to use when connecting to @code{localhost} (which is the
default host).
@@ -22524,9 +22778,12 @@ Overrides option --databases (-B).
@item -T, --tab=path-to-some-directory
Creates a @code{table_name.sql} file, that contains the SQL CREATE commands,
and a @code{table_name.txt} file, that contains the data, for each give table.
-@strong{NOTE}: This only works if @code{mysqldump} is run on the same
-machine as the @code{mysqld} daemon. The format of the @code{.txt} file
-is made according to the @code{--fields-xxx} and @code{--lines--xxx} options.
+The format of the @file{.txt} file is made according to the
+@code{--fields-xxx} and @code{--lines--xxx} options.
+@strong{Note}: This option only works if @code{mysqldump} is run on the same
+machine as the @code{mysqld} daemon, and the user/group that @code{mysqld}
+is running as (normally user @code{mysql}, group @code{mysql}) needs to have
+permission to create/write a file at the location you specify.
@item -u user_name, --user=user_name
The MySQL user name to use when connecting to the server. The
default value is your Unix login name.
@@ -22537,7 +22794,11 @@ Verbose mode. Print out more information on what the program does.
@item -V, --version
Print version information and exit.
@item -w, --where='where-condition'
-Dump only selected records. Note that QUOTES are mandatory:
+Dump only selected records. Note that quotes are mandatory:
+@item -X, --xml
+Dumps a database as well formed XML
+@item -x, --first-slave
+Locks all tables across all databases.
@example
"--where=user='jimf'" "-wuserid>1" "-wuserid<1"
@@ -22580,7 +22841,7 @@ mysqldump --opt database | mysql ---host=remote-host -C database
It is possible to dump several databases with one command:
@example
-mysqldump --databases database1 [database2 database3...] > my_databases.sql
+mysqldump --databases database1 [database2 ...] > my_databases.sql
@end example
If all the databases are wanted, one can use:
@@ -22591,14 +22852,14 @@ mysqldump --all-databases > all_databases.sql
@node mysqlhotcopy, mysqlimport, mysqldump, Client-Side Scripts
-@subsection mysqlhotcopy, Copying MySQL Databases and Tables
+@subsection @code{mysqlhotcopy}, Copying MySQL Databases and Tables
@cindex dumping, databases
@cindex databases, dumping
@cindex tables, dumping
@cindex backing up, databases
-@code{mysqlhotcopy} is a perl script that uses @code{LOCK TABLES},
+@code{mysqlhotcopy} is a Perl script that uses @code{LOCK TABLES},
@code{FLUSH TABLES} and @code{cp} or @code{scp} to quickly make a backup
of a database. It's the fastest way to make a backup of the database,
of single tables but it can only be run on the same machine where the
@@ -22617,11 +22878,11 @@ mysqlhotcopy db_name./regex/
@table @code
@item -?, --help
Display a help screen and exit
-@item -u, --user=#
+@item -u, --user=#
User for database login
@item -p, --password=#
Password to use when connecting to server
-@item -P, --port=#
+@item -P, --port=#
Port to use when connecting to local server
@item -S, --socket=#
Socket to use when connecting to local server
@@ -22659,13 +22920,13 @@ documentation for @code{mysqlhotcopy}.
from the option files.
To be able to execute @code{mysqlhotcopy} you need write access to the
-backup directory, @code{SELECT} privilege to the tables you are about to
-copy and the MySQL @code{Reload} privilege (to be able to
+backup directory, the @code{SELECT} privilege for the tables you are about to
+copy and the MySQL @code{RELOAD} privilege (to be able to
execute @code{FLUSH TABLES}).
@node mysqlimport, mysqlshow, mysqlhotcopy, Client-Side Scripts
-@subsection mysqlimport, Importing Data from Text Files
+@subsection @code{mysqlimport}, Importing Data from Text Files
@cindex importing, data
@cindex data, importing
@@ -22681,10 +22942,10 @@ directly to the same options to @code{LOAD DATA INFILE}.
@code{mysqlimport} is invoked like this:
@example
-shell> mysqlimport [options] database textfile1 [textfile2....]
+shell> mysqlimport [options] database textfile1 [textfile2 ...]
@end example
-For each text file named on the command line,
+For each text file named on the command-line,
@code{mysqlimport} strips any extension from the filename and uses the result
to determine which table to import the file's contents into. For example,
files named @file{patient.txt}, @file{patient.text}, and @file{patient} would
@@ -22732,8 +22993,8 @@ is @code{localhost}.
See the description for the @code{--replace} option.
@item -l, --lock-tables
-Lock @strong{ALL} tables for writing before processing any text files. This
-ensures that all tables are synchronized on the server.
+Lock @strong{all} tables for writing before processing any text files. This
+ensures that all tables are synchronised on the server.
@item -L, --local
Read input files from the client. By default, text files are assumed to be on
@@ -22842,12 +23103,12 @@ are shown.
Note that in newer MySQL versions, you only see those
database/tables/columns for which you have some privileges.
-If the last argument contains a shell or SQL wild-card (@code{*}, @code{?},
-@code{%} or @code{_}) then only what's matched by the wild card is shown.
+If the last argument contains a shell or SQL wildcard (@code{*}, @code{?},
+@code{%} or @code{_}) then only what's matched by the wildcard is shown.
This may cause some confusion when you try to display the columns for a
table with a @code{_} as in this case @code{mysqlshow} only shows you
the table names that match the pattern. This is easily fixed by
-adding an extra @code{%} last on the command line (as a separate
+adding an extra @code{%} last on the command-line (as a separate
argument).
@@ -22857,29 +23118,37 @@ argument).
@cindex error messages, displaying
@cindex perror
-@code{perror} can be used to print error message(s). @code{perror} can
-be invoked like this:
+@cindex errno
+@cindex Errcode
+
+For most system errors MySQL will, in addition to a internal text message,
+also print the system error code in one of the following styles:
+@code{message ... (errno: #)} or @code{message ... (Errcode: #)}.
+
+You can find out what the error code means by either examining the
+documentation for your system or use the @code{perror} utility.
+
+@code{perror} prints a description for a system error code, or an MyISAM/ISAM
+table handler error code.
+
+@code{perror} is invoked like this:
@example
shell> perror [OPTIONS] [ERRORCODE [ERRORCODE...]]
-For example:
+Example:
-shell> perror 64 79
+shell> perror 13 64
+Error code 13: Permission denied
Error code 64: Machine is not on the network
-Error code 79: Can not access a needed shared library
@end example
-@code{perror} can be used to display a description for a system error
-code, or an MyISAM/ISAM table handler error code. The error messages
-are mostly system dependent.
+Note that the error messages are mostly system dependent!
@node Batch Commands, , perror, Client-Side Scripts
@subsection How to Run SQL Commands from a Text File
-@c FIX add the 'source' command
-
The @code{mysql} client typically is used interactively, like this:
@example
@@ -22889,7 +23158,7 @@ shell> mysql database
However, it's also possible to put your SQL commands in a file and tell
@code{mysql} to read its input from that file. To do so, create a text
file @file{text_file} that contains the commands you wish to execute.
-Then invoke @code{mysql} as shown below:
+Then invoke @code{mysql} as shown here:
@example
shell> mysql database < text_file
@@ -22903,7 +23172,14 @@ line:
shell> mysql < text_file
@end example
-@xref{Client-Side Scripts}.
+If you are already running @code{mysql}, you can execute a SQL
+script file using the @code{source} command:
+
+@example
+mysql> source filename;
+@end example
+
+For more information about batch mode, @ref{Batch mode}.
@node Log Files, Replication, Client-Side Scripts, MySQL Database Administration
@@ -22914,7 +23190,8 @@ shell> mysql < text_file
MySQL has several different log files that can help you find
out what's going on inside @code{mysqld}:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .20 .80
+@item @strong{Log file} @tab @strong{Description}
@item The error log @tab Problems encountering starting, running or stopping @code{mysqld}.
@item The isam log @tab Logs all changes to the ISAM tables. Used only for debugging the isam code.
@item The query log @tab Established connections and executed queries.
@@ -22943,7 +23220,7 @@ switch to a new log) by executing @code{FLUSH LOGS}. @xref{FLUSH}.
@code{mysqld} writes all errors to the stderr, which the
@code{safe_mysqld} script redirects to a file called
@code{'hostname'.err}. (On Windows, @code{mysqld} writes this directly
-to @file{\mysql\data\mysql.err}).
+to @file{\mysql\data\mysql.err}.)
This contains information indicating when @code{mysqld} was started and
stopped and also any critical errors found when running. If @code{mysqld}
@@ -22976,7 +23253,7 @@ remove the @code{-l} option from @code{mysql.server} or change it to
@code{--log-bin}.
The entries in this log are written as @code{mysqld} receives the questions.
-This may be different than the order in which the statements are executed.
+This may be different from the order in which the statements are executed.
This is in contrast to the update log and the binary log which are written
after the query is executed, but before any locks are released.
@@ -22987,7 +23264,7 @@ after the query is executed, but before any locks are released.
@cindex update log
@cindex files, update log
-@strong{NOTE}: The update log is replaced by the binary
+@strong{Note}: the update log is replaced by the binary
log. @xref{Binary log}. With this you can do anything that you can do
with the update log.
@@ -23001,7 +23278,7 @@ extension, @code{mysqld} will create log file names like so:
time you execute @code{mysqladmin refresh}, execute @code{mysqladmin
flush-logs}, execute the @code{FLUSH LOGS} statement, or restart the server.
-@strong{NOTE:} For the above scheme to work, you should NOT create
+@strong{Note}: for the above scheme to work, you must not create
your own files with the same filename as the update log + some extensions
that may be regarded as a number, in the directory used by the update log!
@@ -23066,15 +23343,20 @@ file is written in the data directory.
If you supply an extension to @code{--log-bin=filename.extension}, the
extension will be silenty removed.
-To the binary log filename @code{mysqld} will append an extension that is a
-number that is incremented each time you execute @code{mysqladmin
-refresh}, execute @code{mysqladmin flush-logs}, execute the @code{FLUSH LOGS}
-statement or restart the server.
+To the binary log filename @code{mysqld} will append an extension that
+is a number that is incremented each time you execute @code{mysqladmin
+refresh}, execute @code{mysqladmin flush-logs}, execute the @code{FLUSH
+LOGS} statement or restart the server. A new binary log will also
+automatically be created when it reaches @code{max_bin_log_size}. You can
+delete all not active binary log files with the @code{RESET MASTER}
+command. @xref{RESET}.
You can use the following options to @code{mysqld} to affect what is logged
to the binary log:
-@multitable @columnfractions .4 .6
+@multitable @columnfractions .38 .62
+@item @strong{Option} @tab @strong{Description}
+
@item @code{binlog-do-db=database_name} @tab
Tells the master it should log updates for the specified database, and
exclude all others not explicitly mentioned.
@@ -23147,7 +23429,7 @@ more than @code{long_query_time} to execute. The time to get the initial
table locks are not counted as execution time.
The slow query log is logged after the query is executed and after all
-locks has been released. This may be different than the order in which
+locks has been released. This may be different from the order in which
the statements are executed.
If no file name is given, it defaults to the name of the host machine
@@ -23155,7 +23437,7 @@ suffixed with @code{-slow.log}. If a filename is given, but doesn't
contain a path, the file is written in the data directory.
The slow query log can be used to find queries that take a long time to
-execute and are thus candidates for optimization. With a large log, that
+execute and are thus candidates for optimisation. With a large log, that
can become a difficult task. You can pipe the slow query log through the
@code{mysqldumpslow} command to get a summary of the queries which
appear in the log.
@@ -23198,7 +23480,7 @@ The above command does the following:
@itemize @bullet
@item
If standard logging (@code{--log}) or slow query logging
-(@code{--log-slow-queries}) is used, closes and reopens the log file.
+(@code{--log-slow-queries}) is used, closes and reopens the log file
(@file{mysql.log} and @file{`hostname`-slow.log} as default).
@item
If update logging (@code{--log-update}) is used, closes the update log and
@@ -23231,18 +23513,22 @@ and then take a backup and remove @file{mysql.old}.
* Replication Implementation:: Replication Implementation Overview
* Replication HOWTO:: How To Set Up Replication
* Replication Features:: Replication Features and Known Problems
-* Replication Options:: Replication Options in my.cnf
+* Replication Options:: Replication Options in @file{my.cnf}
* Replication SQL:: SQL Commands Related to Replication
* Replication FAQ:: Replication FAQ
* Replication Problems:: Troubleshooting Replication
@end menu
-This chapter describes the various replication features in MySQL.
+This section describes the various replication features in MySQL.
It serves as a reference to the options available with replication.
-You will be introduced to replication and learn how to implement it.
-Towards the end, there are some frequently asked questions and descriptions
+You will be introduced to replication and learn how to implement it.
+Toward the end, there are some frequently asked questions and descriptions
of problems and how to solve them.
+We suggest that you visit our website at @uref{http://www.mysql.com/}
+often and read updates to this section. Replication is constantly being
+improved, and we update the manual frequently with the most current
+information.
@node Replication Intro, Replication Implementation, Replication, Replication
@subsection Introduction
@@ -23258,7 +23544,7 @@ Starting in Version 3.23.15, MySQL supports one-way replication
internally. One server acts as the master, while the other acts as the
slave. Note that one server could play the roles of master in one pair
and slave in the other. The master server keeps a binary log of updates
-(@xref{Binary log}.) and an index file to binary logs to keep track of
+(@pxref{Binary log}) and an index file to binary logs to keep track of
log rotation. The slave, upon connecting, informs the master where it
left off since the last successfully propagated update, catches up on
the updates, and then blocks and waits for the master to notify it of
@@ -23279,11 +23565,11 @@ master. @xref{Backup}.
MySQL replication is based on the server keeping track of all
changes to your database (updates, deletes, etc) in the binary
-log. (@xref{Binary log}.) and the slave server(s) reading the saved
+log (@pxref{Binary log}) and the slave server(s) reading the saved
queries from the master server's binary log so that the slave can
execute the same queries on its copy of the data.
-It is @strong{very important} to realize that the binary log is simply a
+It is @strong{very important} to realise that the binary log is simply a
record starting from a fixed point in time (the moment you enable binary
logging). Any slaves which you set up will need copies of all the data
from your master as it existed the moment that you enabled binary
@@ -23291,11 +23577,40 @@ logging on the master. If you start your slaves with data that doesn't
agree with what was on the master @strong{when the binary log was
started}, your slaves may fail.
-A future version (4.0) of MySQL will remove the need to keep a
-(possibly large) snapshot of data for new slaves that you might wish to
-set up through the live backup functionality with no locking required.
-However, at this time, it is necessary to block all writes either with a
-global read lock or by shutting down the master while taking a snapshot.
+Please see the following table for an indication of master-slave
+compatibility between different versions. With regard to version 4.0,
+we recommend using same version on both sides.
+
+@c FIX arjen 2002-07-17 new table, not yet measured for XML/DocBook.
+@multitable @columnfractions .10 .15 .15 .10 .10 .10
+@item @tab @tab @strong{Master} @tab @strong{Master} @tab @strong{Master} @tab @strong{Master}
+@item @tab @tab @strong{3.23.33 and up} @tab @strong{4.0.0} @tab @strong{4.0.1} @tab @strong{4.0.2}
+@item @strong{Slave} @tab @strong{3.23.33 and up} @tab yes @tab no @tab no @tab no
+@item @strong{Slave} @tab @strong{4.0.0} @tab no @tab yes @tab no @tab no
+@item @strong{Slave} @tab @strong{4.0.1} @tab yes @tab no @tab yes @tab no
+@item @strong{Slave} @tab @strong{4.0.2} @tab yes @tab no @tab no @tab yes
+@end multitable
+
+Starting from 4.0.0, one can use @code{LOAD DATA FROM MASTER} to set up
+a slave. Be aware that @code{LOAD DATA FROM MASTER} currently works only
+if all the tables on the master are @code{MyISAM} type, and will acquire a
+global read lock, so no writes are possible while the tables are being
+transferred from the master. This limitation is of a temporary nature, and is
+due to the fact that we have not yet implemented hot lock-free table backup.
+It will be removed in the future 4.0 branch versions once we implemented hot
+backup enabling @code{LOAD DATA FROM MASTER} to work without blocking master
+updates.
+
+Due to the above limitation, we recommend that at this point you use
+@code{LOAD DATA FROM MASTER} only if the dataset on the master is relatively
+small, or if a prolonged read lock on the master is acceptable. While the
+actual speed of @code{LOAD DATA FROM MASTER} may vary from system to system,
+a good rule for a rough estimate of how long it is going to take is 1 second
+per 1 MB of the datafile. You will get close to the estimate if both master
+and slave are equivalent to 700 MHz Pentium, are connected through
+100 MBit/s network, and your index file is about half the size of your data
+file. Of course, your mileage will vary from system to system, the above rule
+just gives you a rough order of magnitude estimate.
Once a slave is properly configured and running, it will simply connect
to the master and wait for updates to process. If the master goes away
@@ -23313,11 +23628,24 @@ The next section explains the master/slave setup process in more detail.
@node Replication HOWTO, Replication Features, Replication Implementation, Replication
@subsection How To Set Up Replication
-Below is a quick description of how to set up complete replication on
+Here is a quick description of how to set up complete replication on
your current MySQL server. It assumes you want to replicate all
your databases and have not configured replication before. You will need
to shutdown your master server briefly to complete the steps outlined
-below.
+here.
+
+While this method is the most straightforward way to set up a slave,
+it is not the only one. For example, if you already have a snapshot
+of the master, and
+the master already has server id set and binary logging enabled, you can
+set up a slave without shutting the master down or even blocking the updates.
+For more details, please see @ref{Replication FAQ}.
+
+If you want to become a real MySQL replication guru, we suggest that you
+begin by studying, pondering, and trying all commands
+mentioned in @ref{Replication SQL}. You should also familiarize yourself
+with replication startup options in @file{my.cnf} in
+@ref{Replication Options}.
@enumerate
@item
@@ -23331,15 +23659,16 @@ in the latest release.
@item
Set up special a replication user on the master with the @code{FILE}
-privilege and permission to connect from all the slaves. If the user is
-only doing replication (which is recommended), you don't need to grant any
-additional privileges.
+(in MySQL versions older than 4.0.2) or @code{REPLICATION SLAVE}
+privilege in newer MySQL versions. You must also have given permission
+to connect from all the slaves. If the user is only doing replication
+(which is recommended), you don't need to grant any additional privileges.
For example, to create a user named @code{repl} which can access your
master from any host, you might use this command:
@example
-GRANT FILE ON *.* TO repl@@"%" IDENTIFIED BY '<password>';
+mysql> GRANT FILE ON *.* TO repl@@"%" IDENTIFIED BY '<password>';
@end example
@item
@@ -23360,11 +23689,11 @@ directory location depends on your installation.
tar -cvf /tmp/mysql-snapshot.tar /path/to/data-dir
@end example
-Windows users can use WinZip or similar software to create an archive of
-the data directory.
+Windows users can use @code{WinZIP} or similar software to create an
+archive of the data directory.
@item
-In @code{my.cnf} on the master add @code{log-bin} and
+In @file{my.cnf} on the master add @code{log-bin} and
@code{server-id=unique number} to the @code{[mysqld]} section and
restart it. It is very important that the id of the slave is different from
the id of the master. Think of @code{server-id} as something similar
@@ -23381,7 +23710,7 @@ server-id=1
Restart MySQL on the master.
@item
-Add the following to @code{my.cnf} on the slave(s):
+Add the following to @file{my.cnf} on the slave(s):
@example
master-host=<hostname of the master>
@@ -23423,42 +23752,32 @@ Warning: one should set server_id to a non-0 value if master_host is set.
The server will not act as a slave.
@end example
-If you have forgot to do this for the master, the slaves will not be
+If you have forgotten to do this for the master, the slaves will not be
able to connect to the master.
If a slave is not able to replicate for any reason, you will find error
messages in the error log on the slave.
Once a slave is replicating, you will find a file called
-@code{master.info} in the same directory as your error log. The
-@code{master.info} file is used by the slave to keep track of how much
-of the master's binary log is has processed. @strong{Do not} remove or
+@file{master.info} in the same directory as your error log. The
+@file{master.info} file is used by the slave to keep track of how much
+of the master's binary log it has processed. @strong{Do not} remove or
edit the file, unless you really know what you are doing. Even in that case,
it is preferred that you use @code{CHANGE MASTER TO} command.
-
-@menu
-* Replication Features:: Replication Features and Known Problems
-* Replication Options:: Replication Options in my.cnf
-* Replication SQL:: SQL Commands Related to Replication
-* Replication FAQ:: Replication FAQ
-* Replication Problems:: Troubleshooting Replication
-@end menu
-
-
@node Replication Features, Replication Options, Replication HOWTO, Replication
@subsection Replication Features and Known Problems
@cindex options, replication
-@cindex @code{my.cnf} file
-@cindex files,@code{my.cnf}
+@cindex @file{my.cnf} file
+@cindex files,@file{my.cnf}
-Below is an explanation of what is supported and what is not:
+Here is an explanation of what is supported and what is not:
@itemize @bullet
@item
Replication will be done correctly with @code{AUTO_INCREMENT},
-@code{LAST_INSERT_ID}, and @code{TIMESTAMP} values.
+@code{LAST_INSERT_ID()}, and @code{TIMESTAMP} values.
@item
@code{RAND()} in updates does not replicate properly. Use
@code{RAND(some_non_rand_expr)} if you are replicating updates with
@@ -23470,37 +23789,39 @@ on the master and the slave. If not, you may get duplicate key errors on
the slave, because a key that is regarded as unique on the master may
not be that in the other character set.
@item
-@code{LOAD DATA INFILE} will be handled properly as long as the file
+In 3.23, @code{LOAD DATA INFILE} will be handled properly as long as the file
still resides on the master server at the time of update
-propagation. @code{LOAD LOCAL DATA INFILE} will be skipped.
+propagation. @code{LOAD LOCAL DATA INFILE} will be skipped. In 4.0, this
+limitation is not present - all forms of @code{LOAD DATA INFILE} are properly
+replicated.
@item
Update queries that use user variables are not replication-safe (yet).
@item
@code{FLUSH} commands are not stored in the binary log and are because
of this not replicated to the slaves. This is not normally a problem as
@code{FLUSH} doesn't change anything. This does however mean that if you
-update the @code{MySQL} privilege tables directly without using
-@code{GRANT} statement and you replicate the @code{MySQL} privilege
+update the MySQL privilege tables directly without using the
+@code{GRANT} statement and you replicate the @code{mysql} privilege
database, you must do a @code{FLUSH PRIVILEGES} on your slaves to put
the new privileges into effect.
@item
Temporary tables starting in 3.23.29 are replicated properly with the
exception of the case when you shut down slave server ( not just slave thread),
-you have some temporary tables open, and the are used in subsequent updates.
-To deal with this problem, to shut down the slave, do @code{SLAVE STOP}, then
+you have some temporary tables open, and they are used in subsequent updates.
+To deal with this problem shutting down the slave, do @code{SLAVE STOP},
check @code{Slave_open_temp_tables} variable to see if it is 0, then issue
@code{mysqladmin shutdown}. If the number is not 0, restart the slave thread
with @code{SLAVE START} and see
if you have better luck next time. There will be a cleaner solution, but it
has to wait until version 4.0.
-In earlier versions temporary tables are not being replicated properly - we
+In earlier versions temporary tables are not replicated properly - we
recommend that you either upgrade, or execute @code{SET SQL_LOG_BIN=0} on
your clients before all queries with temp tables.
@item
-MySQL only supports one master and many slaves. We will in 4.x
+MySQL only supports one master and many slaves. In 4.x, we will
add a voting algorithm to automatically change master if something goes
wrong with the current master. We will also introduce 'agent' processes
-to help doing load balancing by sending select queries to different
+to help do load balancing by sending select queries to different
slaves.
@item
Starting in Version 3.23.26, it is safe to connect servers in a circular
@@ -23526,9 +23847,9 @@ Note that the log format has changed in Version 3.23.26 so that
pre-3.23.26 slaves will not be able to read it.
@item
If the query on the slave gets an error, the slave thread will
-terminate, and a message will appear in the @code{.err} file. You should
+terminate, and a message will appear in the @file{.err} file. You should
then connect to the slave manually, fix the cause of the error (for
-example, non-existent table), and then run @code{SLAVE START} sql
+example, non-existent table), and then run the @code{SLAVE START} SQL
command (available starting in Version 3.23.16). In Version 3.23.15, you
will have to restart the server.
@item
@@ -23544,20 +23865,21 @@ if disk cache was not synced before the system died. Your system fault
tolerance will be greatly increased if you have a good UPS.
@item
If the master is listening on a non-standard port, you will also need to
-specify this with @code{master-port} parameter in @code{my.cnf} .
+specify this with @code{master-port} parameter in @file{my.cnf} .
@item
In Version 3.23.15, all of the tables and databases will be
replicated. Starting in Version 3.23.16, you can restrict replication to
a set of databases with @code{replicate-do-db} directives in
-@code{my.cnf} or just exclude a set of databases with
+@file{my.cnf} or just exclude a set of databases with
@code{replicate-ignore-db}. Note that up until Version 3.23.23, there was a bug
that did not properly deal with @code{LOAD DATA INFILE} if you did it in
a database that was excluded from replication.
@item
Starting in Version 3.23.16, @code{SET SQL_LOG_BIN = 0} will turn off
replication (binary) logging on the master, and @code{SET SQL_LOG_BIN =
-1} will turn in back on - you must have the process privilege to do
-this.
+1} will turn it back on -- you must have the @code{SUPER} (in MySQL
+4.0.2 and above) or @code{PROCESS} (in older MySQL versions) privilege
+to do this.
@item
Starting in Version 3.23.19, you can clean up stale replication leftovers when
something goes wrong and you want a clean start with @code{FLUSH MASTER}
@@ -23567,11 +23889,6 @@ what they do. The old @code{FLUSH} variants still work, though, for
compatibility.
@item
-Starting in Version 3.23.21, you can use @code{LOAD TABLE FROM MASTER} for
-network backup and to set up replication initially. We have recently
-received a number of bug reports concerning it that we are investigating, so
-we recommend that you use it only in testing until we make it more stable.
-@item
Starting in Version 3.23.23, you can change masters and adjust log position
with @code{CHANGE MASTER TO}.
@item
@@ -23584,26 +23901,69 @@ with a different name on the slave.
@item
Starting in Version 3.23.28, you can use @code{PURGE MASTER LOGS TO 'log-name'}
to get rid of old logs while the slave is running.
+@item
+Due to the non-transactional nature of MyISAM tables, it is possible to have
+a query that will only partially update a table and return an error code. This
+can happen, for example, on a multi-row insert that has one row violating a
+key constraint, or if a long update query is killed after updating some of the
+rows. If that happens on the master, the slave thread will exit and wait for
+the DBA to decide what to do about it unless the error code is legitimate and
+the query execution results in the same error code. If this error code
+validation behaviour is not desirable, some ( or all) errors could be masked
+out with @code{slave-skip-errors} option starting in Version 3.23.47.
+@item
+While individual tables can be excluded from replication with
+@code{replicate-do-table}/@code{replicate-ignore-table} or
+@code{replicate-wild-do-table}/@code{replicate-wild-ignore-table}, there
+are currently some design deficiencies that in some rather rare cases
+produce unexpected results. The replication protocol does not inform the
+slave explicitly which tables are going to be modified by the query -- so
+the slave has to parse the query to know this. To avoid redundant
+parsing for queries that will end up actually being executed, table
+exclusion is currently implemented by sending the query to the standard
+MySQL parser, which will short-circuit the query and report success if
+it detects that the table should be ignored. In addition to several
+inefficiencies, this approach is also more bug prone, and there are two
+known bugs as of Version 3.23.49 -- because the parser automatically opens
+the table when parsing some queries the ignored table has to exist on
+the slave. The other bug is that if the ignored table gets partially
+updated, the slave thread will not notice that the table actually should
+have been ignored and will suspend the replication process. While the
+above bugs are conceptually very simple to fix, we have not yet found a way
+to do this without a sigficant code change that would compromize the stability
+status of 3.23 branch. There exists a workaround for both if in the rare case
+it happens to affect your application -- use @code{slave-skip-errors}.
+
@end itemize
@node Replication Options, Replication SQL, Replication Features, Replication
-@subsection Replication Options in my.cnf
+@subsection Replication Options in @file{my.cnf}
-If you are using replication, we recommend you to use MySQL Version
+If you are using replication, we recommend that you use MySQL Version
3.23.30 or later. Older versions work, but they do have some bugs and are
-missing some features.
+missing some features. Some of the options mentioned here may not be available in
+your version if it is not the most recent one. For all options specific to
+the 4.0 branch, there is a note indicating so. Otherwise, if you discover
+that the option you are interested in is not available in your 3.23 version,
+and you really need it, please upgrade to the most recent 3.23 branch.
+
+Please be aware that 4.0 branch is still in alpha, so some things may not be
+working as smoothly as you would like. If you really would like to try
+the new features of 4.0, we recommend you do it in such a way that in
+case there is a problem your mission critical applications will not be
+disrupted.
On both master and slave you need to use the @code{server-id} option.
This sets an unique replication id. You should pick a unique value in the
range between 1 to 2^32-1 for each master and slave.
Example: @code{server-id=3}
-The following table has the options you can use for the @strong{MASTER}:
-
-@multitable @columnfractions .3 .7
+The following table describes the options you can use for the @code{MASTER}:
+@multitable @columnfractions .38 .62
@item @strong{Option} @tab @strong{Description}
+
@item @code{log-bin=filename} @tab
Write to a binary update log to the specified location. Note that if you
give it a parameter with an extension (for example,
@@ -23612,17 +23972,16 @@ not work right during replication if you do @code{FLUSH LOGS} . The
problem is fixed in Version 3.23.25. If you are using this kind of log
name, @code{FLUSH LOGS} will be ignored on binlog. To clear the log, run
@code{FLUSH MASTER}, and do not forget to run @code{FLUSH SLAVE} on all
-slaves. In Version 3.23.26 and in later versions you should use
+slaves. In Versions 3.23.26 and later, you should use
@code{RESET MASTER} and @code{RESET SLAVE}
@item @code{log-bin-index=filename} @tab
Because the user could issue the @code{FLUSH LOGS} command, we need to
know which log is currently active and which ones have been rotated out
and in what sequence. This information is stored in the binary log index file.
-The default is `hostname`.index. You can use this option if you want to
-be a rebel.
+The default is @file{`hostname`.index}. You should not need to change this.
-Example: @code{log-bin-index=db.index}.
+Example: @code{log-bin-index=db.index}
@item @code{sql-bin-update-same} @tab
If set, setting @code{SQL_LOG_BIN} to a value will automatically set
@@ -23630,66 +23989,107 @@ If set, setting @code{SQL_LOG_BIN} to a value will automatically set
@item @code{binlog-do-db=database_name} @tab
Tells the master that it should log updates to the binary log if the
-current database is 'database_name'. All others database are ignored.
-Note that if you use this you should ensure that you only do updates in
+current database is @code{database_name}. All other databases are ignored.
+Note that if you use this, you should ensure that you do updates only in
the current database.
-Example: @code{binlog-do-db=some_database}.
+Example: @code{binlog-do-db=sales}
@item @code{binlog-ignore-db=database_name} @tab
Tells the master that updates where the current database is
-'database_name' should not be stored in the binary log. Note that if
-you use this you should ensure that you only do updates in the current
+@code{database_name} should not be stored in the binary log. Note that if
+you use this, you should ensure that you do updates only in the current
database.
-Example: @code{binlog-ignore-db=some_database}
+Example: @code{binlog-ignore-db=accounting}
@end multitable
-The following table has the options you can use for the @strong{SLAVE}:
-
-@multitable @columnfractions .3 .7
+The following table describes the options you can use for the @code{SLAVE}:
+@multitable @columnfractions .38 .62
@item @strong{Option} @tab @strong{Description}
+
@item @code{master-host=host} @tab
Master hostname or IP address for replication. If not set, the slave
-thread will not be started.
+thread will not be started. Note that the setting of @code{master-host}
+will be ignored if there exists a valid @file{master.info} file. Probably a
+better name for this options would have been something like
+@code{bootstrap-master-host}, but it is too late to change now.
-Example: @code{master-host=db-master.mycompany.com}.
+Example: @code{master-host=db-master.mycompany.com}
@item @code{master-user=username} @tab
-The user the slave thread will us for authentication when connecting to
-the master. The user must have @code{FILE} privilege. If the master user
-is not set, user @code{test} is assumed.
+The username the slave thread will use for authentication when connecting to
+the master. The user must have the @code{FILE} privilege. If the master user
+is not set, user @code{test} is assumed. The value in @file{master.info} will
+take precedence if it can be read.
-Example: @code{master-user=scott}.
+Example: @code{master-user=scott}
@item @code{master-password=password} @tab
The password the slave thread will authenticate with when connecting to
-the master. If not set, an empty password is assumed.
+the master. If not set, an empty password is assumed.The value in
+@file{master.info} will take precedence if it can be read.
-Example: @code{master-password=tiger}.
+Example: @code{master-password=tiger}
@item @code{master-port=portnumber} @tab
The port the master is listening on. If not set, the compiled setting of
@code{MYSQL_PORT} is assumed. If you have not tinkered with
-@code{configure} options, this should be 3306.
+@code{configure} options, this should be 3306. The value in
+@file{master.info} will take precedence if it can be read.
-Example: @code{master-port=3306}.
+Example: @code{master-port=3306}
@item @code{master-connect-retry=seconds} @tab
The number of seconds the slave thread will sleep before retrying to
connect to the master in case the master goes down or the connection is
-lost. Default is 60.
+lost. Default is 60.
+
+Example: @code{master-connect-retry=60}
+
+@item @code{master-ssl} @tab
+Available after 4.0.0. Turn SSL on for replication. Be warned that is
+this is a relatively new feature.
+
+Example: @code{master-ssl}
-Example: @code{master-connect-retry=60}.
+@item @code{master-ssl-key} @tab
+Available after 4.0.0. Master SSL keyfile name. Only applies if you have
+enabled @code{master-ssl}.
+
+Example: @code{master-ssl-key=SSL/master-key.pem}
+
+@item @code{master-ssl-cert} @tab
+Available after 4.0.0. Master SSL certificate file name. Only applies if
+you have enabled @code{master-ssl}.
+
+
+Example: @code{master-ssl-key=SSL/master-cert.pem}
@item @code{master-info-file=filename} @tab
The location of the file that remembers where we left off on the master
-during the replication process. The default is master.info in the data
-directory. Sasha: The only reason I see for ever changing the default
-is the desire to be rebelious.
+during the replication process. The default is @file{master.info} in the data
+directory. You should not need to change this.
+
+Example: @code{master-info-file=master.info}
+
+@item @code{report-host} @tab
+Available after 4.0.0. Hostname or IP of the slave to be reported to to
+the master during slave registration. Will appear in the output of
+@code{SHOW SLAVE HOSTS}. Leave unset if you do not want the slave to
+register itself with the master. Note that it is not sufficient for the
+master to simply read the IP of the slave off the socket once the slave
+connects. Due to @code{NAT} and other routing issues, that IP may not be
+valid for connecting to the slave from the master or other hosts.
+
+Example: @code{report-host=slave1.mycompany.com}
-Example: @code{master-info-file=master.info}.
+@item @code{report-port} @tab
+Available after 4.0.0. Port for connecting to slave reported to the
+master during slave registration. Set it only if the slave is listening
+on a non-default port or if you have a special tunnel from the master or
+other clients to the slave. If not sure, leave this option unset.
@item @code{replicate-do-table=db_name.table_name} @tab
Tells the slave thread to restrict replication to the specified table.
@@ -23697,57 +24097,69 @@ To specify more than one table, use the directive multiple times, once
for each table. This will work for cross-database updates, in
contrast to @code{replicate-do-db}.
-Example: @code{replicate-do-table=some_db.some_table}.
+Example: @code{replicate-do-table=some_db.some_table}
@item @code{replicate-ignore-table=db_name.table_name} @tab
-Tells the slave thread to not replicate to the specified table. To
-specify more than one table to ignore, use the directive multiple times,
-once for each table. This will work for cross-datbase updates,
-in contrast to @code{replicate-ignore-db}.
+Tells the slave thread to not replicate any command that updates the
+specified table (even if any other tables may be update by the same
+command). To specify more than one table to ignore, use the directive
+multiple times, once for each table. This will work for cross-datbase
+updates, in contrast to @code{replicate-ignore-db}.
-Example: @code{replicate-ignore-table=db_name.some_table}.
+Example: @code{replicate-ignore-table=db_name.some_table}
@item @code{replicate-wild-do-table=db_name.table_name} @tab
-Tells the slave thread to restrict replication to the tables that match
-the specified wildcard pattern. To specify more than one table, use the
-directive multiple times, once for each table. This will work for
-cross-database updates.
+Tells the slave thread to restrict replication to queries where any of
+the updated tables match the specified wildcard pattern. To specify
+more than one table, use the directive multiple times, once for each
+table. This will work for cross-database updates.
-Example: @code{replicate-wild-do-table=foo%.bar%} will replicate only updates
-to tables in all databases that start with foo and whose table names
-start with bar.
+Example: @code{replicate-wild-do-table=foo%.bar%} will replicate only
+updates that uses a table in any databases that start with @code{foo}
+and whose table names start with @code{bar}.
@item @code{replicate-wild-ignore-table=db_name.table_name} @tab
-Tells the slave thread to not replicate to the tables that match the
-given wild card pattern. To specify more than one table to ignore, use
+Tells the slave thread to not replicate a query whare any table matches the
+given wildcard pattern. To specify more than one table to ignore, use
the directive multiple times, once for each table. This will work for
cross-database updates.
Example: @code{replicate-wild-ignore-table=foo%.bar%} will not do updates
-to tables in databases that start with foo and whose table names start
-with bar.
+to tables in databases that start with @code{foo} and whose table names start
+with @code{bar}.
@item @code{replicate-ignore-db=database_name} @tab
-Tells the slave thread to not replicate to the specified database. To
-specify more than one database to ignore, use the directive multiple
-times, once for each database. This option will not work if you use cross
-database updates. If you need cross database updates to work, make sure
-you have 3.23.28 or later, and use
-@code{replicate-wild-ignore-table=db_name.%}
-Example: @code{replicate-ignore-db=some_db}.
+Tells the slave thread to not replicate any command where the current
+database is @code{database_name}. To specify more than one database to
+ignore, use the directive multiple times, once for each database.
+You should not use this directive if you are using cross table updates
+and you don't want these update to be replicated.
+
+The main reason for this behavior is that it's hard from the command
+alone know if a query should be replicated or not; For example if you
+are using multi-table-delete or multi-table-update commands in MySQL 4.x
+that goes across multiple databases. It's also very fast to just check
+the current database, as this only has to be done once at connect time
+or when the database changes.
+
+If you need cross database updates to work, make sure you have 3.23.28
+or later, and use @code{replicate-wild-ignore-table=db_name.%}.
+
+Example: @code{replicate-ignore-db=some_db}
@item @code{replicate-do-db=database_name} @tab
-Tells the slave thread to restrict replication to the specified
-database. To specify more than one database, use the directive multiple
-times, once for each database. Note that this will only work if you do
-not use cross-database queries such as @code{UPDATE some_db.some_table
+Tells the slave thread to restrict replication to commands where
+the current database is @code{database_name}.
+To specify more than one database, use the directive multiple
+times, once for each database. Note that this will not replicate
+cross-database queries such as @code{UPDATE some_db.some_table
SET foo='bar'} while having selected a different or no database. If you
need cross database updates to work, make sure you have 3.23.28 or
-later, and use @code{replicate-wild-do-table=db_name.%}
+later, and use @code{replicate-wild-do-table=db_name.%}.
-Example: @code{replicate-do-db=some_db}.
+Example: @code{replicate-do-db=some_db}
@item @code{log-slave-updates} @tab
Tells the slave to log the updates from the slave thread to the binary
@@ -23755,32 +24167,33 @@ log. Off by default. You will need to turn it on if you plan to
daisy-chain the slaves.
@item @code{replicate-rewrite-db=from_name->to_name} @tab
-Updates to a database with a different name than the original
+Updates to a database with a different name than the original.
+
+Example: @code{replicate-rewrite-db=master_db_name->slave_db_name}
-Example: @code{replicate-rewrite-db=master_db_name->slave_db_name}.
+@item @code{slave-skip-errors= [err_code1,err_code2,... | all]} @tab
-@item @code{slave-skip-errors=err_code1,err_code2,..} @tab
Available only in 3.23.47 and later. Tells the slave thread to continue
replication when a query returns an error from the provided
list. Normally, replication will discontinue when an error is
-encountered giving the user a chance to resolve the inconsistency in the
+encountered, giving the user a chance to resolve the inconsistency in the
data manually. Do not use this option unless you fully understand why
-you are getting the errors. If there are no bugs in your
+you are getting the errors. If there are no bugs in your
replication setup and client programs, and no bugs in MySQL itself, you
-should never get an abort with error.Indiscriminate use of this option
+should never get an abort with error. Indiscriminate use of this option
will result in slaves being hopelessly out of sync with the master and
you having no idea how the problem happened.
For error codes, you should use the numbers provided by the error message in
your slave error log and in the output of @code{SHOW SLAVE STATUS}. Full list
of error messages can be found in the source distribution in
-@code{Docs/mysqld_error.txt}.
+@file{Docs/mysqld_error.txt}.
-You can ( but should not) also use a very non-recommended value of @code{all}
+You can (but should not) also use a very non-recommended value of @code{all}
which will ignore all error messages and keep barging along regardless.
Needless to say, if you use it, we make no promises regarding your data
integrity. Please do not complain if your data on the slave is not anywhere
-close to what it is on the master in this case - you have been warned.
+close to what it is on the master in this case -- you have been warned.
Example:
@@ -23790,7 +24203,7 @@ Example:
Tells the slave server not to start the slave on the startup. The user
can start it later with @code{SLAVE START}.
-@item @code{slave_read_timeout=#} @tab
+@item @code{slave_net_timeout=#} @tab
Number of seconds to wait for more data from the master before aborting
the read.
@end multitable
@@ -23803,10 +24216,10 @@ the read.
@cindex commands, replication
@cindex replication, commands
-Replication can be controlled through the SQL interface. Below is the
+Replication can be controlled through the SQL interface. Here is the
summary of commands:
-@multitable @columnfractions .30 .70
+@multitable @columnfractions .45 .55
@item @strong{Command} @tab @strong{Description}
@item @code{SLAVE START}
@@ -23816,21 +24229,22 @@ summary of commands:
@tab Stops the slave thread. (Slave)
@item @code{SET SQL_LOG_BIN=0}
- @tab Disables update logging if the user has process privilege.
+@tab Disables update logging if the user has the @code{SUPER} privilege.
Ignored otherwise. (Master)
@item @code{SET SQL_LOG_BIN=1}
- @tab Re-enables update logging if the user has process privilege.
+ @tab Re-enables update logging if the user has the @code{SUPER} privilege.
Ignored otherwise. (Master)
-@item @code{SET SQL_SLAVE_SKIP_COUNTER=n}
+@item @code{GLOBAL SET SQL_SLAVE_SKIP_COUNTER=n}
@tab Skip the next @code{n} events from the master. Only valid when
the slave thread is not running, otherwise, gives an error. Useful for
recovering from replication glitches.
@item @code{RESET MASTER}
@tab Deletes all binary logs listed in the index file, resetting the binlog
-index file to be empty. In pre-3.23.26 versions, @code{FLUSH MASTER} (Master)
+index file to be empty. In pre-3.23.26 versions, use @code{FLUSH MASTER}
+(Master)
@item @code{RESET SLAVE}
@tab Makes the slave forget its replication position in the master
@@ -23838,7 +24252,21 @@ logs. In pre 3.23.26 versions the command was called
@code{FLUSH SLAVE}(Slave)
@item @code{LOAD TABLE tblname FROM MASTER}
- @tab Downloads a copy of the table from master to the slave. (Slave)
+ @tab Downloads a copy of the table from master to the slave. Implemented
+ mainly for debugging of @code{LOAD DATA FROM MASTER}, but some ``gourmet''
+ users might find it useful for other things. Do not use it if you consider
+ yourself the average ``non-hacker'' type user. (Slave)
+
+@item @code{LOAD DATA FROM MASTER} @tab
+Available starting in 4.0.0. Takes a snapshot of the master and copies
+it to the slave. Updates the values of @code{MASTER_LOG_FILE} and
+@code{MASTER_LOG_POS} so that the slave will start replicating from the
+correct position. Will honor table and database exclusion rules
+specified with @code{replicate-*} options. So far works only with
+@code{MyISAM} tables and acquires a global read lock on the master while
+taking the snapshot. In the future it is planned to make it work with
+@code{InnoDB} tables and to remove the need for global read lock using
+the non-blocking online backup feature.
@item @code{CHANGE MASTER TO master_def_list}
@tab Changes the master parameters to the values specified in
@@ -23846,10 +24274,9 @@ logs. In pre 3.23.26 versions the command was called
is a comma-separated list of @code{master_def} where @code{master_def} is
one of the following: @code{MASTER_HOST}, @code{MASTER_USER},
@code{MASTER_PASSWORD}, @code{MASTER_PORT}, @code{MASTER_CONNECT_RETRY},
-@code{MASTER_LOG_FILE}, @code{MASTER_LOG_POS}. Example:
+@code{MASTER_LOG_FILE}, @code{MASTER_LOG_POS}. For example:
@example
-
CHANGE MASTER TO
MASTER_HOST='master2.mycompany.com',
MASTER_USER='replication',
@@ -23857,7 +24284,6 @@ CHANGE MASTER TO
MASTER_PORT=3306,
MASTER_LOG_FILE='master2-bin.001',
MASTER_LOG_POS=4;
-
@end example
You only need to specify the values that need to be changed. The values that
@@ -23868,19 +24294,53 @@ old values of log and position are not applicable anymore, and will
automatically be reset to an empty string and 0, respectively (the start
values). Note that if you restart the slave, it will remember its last master.
If this is not desirable, you should delete the @file{master.info} file before
-restarting, and the slave will read its master from @code{my.cnf} or the
-command line. (Slave)
+restarting, and the slave will read its master from @file{my.cnf} or the
+command-line.
+
+This command is useful for setting up a slave when you have the snapshot of
+the master and have recorded the log and the offset on the master that the
+snapshot corresponds to. You can run
+ @code{CHANGE MASTER TO MASTER_LOG_FILE='log_name_on_master',
+ MASTER_LOG_POS=log_offset_on_master} on the slave after restoring the
+snapshot.
+
+(Slave)
@item @code{SHOW MASTER STATUS} @tab Provides status information on the binlog of the master. (Master)
+@item @code{SHOW SLAVE HOSTS} @tab Available after 4.0.0. Gives a
+listing of slaves currently registered with the master (Master)
+
@item @code{SHOW SLAVE STATUS} @tab Provides status information on essential parameters of the slave thread. (Slave)
-@item @code{SHOW MASTER LOGS} @tab Only available starting in Version 3.23.28. Lists the binary logs on the master. You should use this command prior to @code{PURGE MASTER LOGS TO} to find out how far you should go.
+
+@item @code{SHOW MASTER LOGS} @tab Only available starting in Version
+3.23.28. Lists the binary logs on the master. You should use this
+command prior to @code{PURGE MASTER LOGS TO} to find out how far you
+should go. (Master)
+
+@item @code{SHOW BINLOG EVENTS [ IN 'logname' ] [ FROM pos ]
+ [ LIMIT [offset,] rows ] } @tab
+Shows the events in the binary update log. Primarily used for
+testing/debugging, but can also be used by regular clients that for some
+reason need to read the binary log contents. (Master)
+
+@item @code{SHOW NEW MASTER FOR SLAVE WITH MASTER_LOG_FILE='logfile' AND
+ MASTER_LOG_POS=pos AND
+MASTER_LOG_SEQ=log_seq AND MASTER_SERVER_ID=server_id} @tab
+This command is used when a slave of a possibly dead/unavailable master
+needs to be switched to replicate off another slave that has been
+replicating the same master. The command will return recalculated
+replication coordinates, and the output can be used in a subsequent
+@code{CHANGE MASTER TO} command. Normal users should never need to run
+this command. It is primarily reserved for internal use by the fail-safe
+replication code. We may later change the syntax if we find a more
+intuitive way to describe this operation.
@item @code{PURGE MASTER LOGS TO 'logname'}
@tab Available starting in Version 3.23.28. Deletes all the
replication logs that are listed in the log
-index as being prior to the specified log, and removed them from the
-log index, so that the given log now becomes first. Example:
+index as being prior to the specified log, and removes them from the
+log index, so that the given log now becomes the first. Example:
@example
PURGE MASTER LOGS TO 'mysql-bin.010'
@@ -23890,7 +24350,7 @@ This command will do nothing and fail with an error if you have an
active slave that is currently reading one of the logs you are trying to
delete. However, if you have a dormant slave, and happen to purge one of
the logs it wants to read, the slave will be unable to replicate once it
-comes up. The command is safe to run while slaves are replicating - you
+comes up. The command is safe to run while slaves are replicating -- you
do not need to stop them.
You must first check all the slaves with @code{SHOW SLAVE STATUS} to
@@ -23906,6 +24366,87 @@ last log on the list), backup all the logs you are about to delete
@node Replication FAQ, Replication Problems, Replication SQL, Replication
@subsection Replication FAQ
+@strong{Q}: How do I configure a slave if the master is already running
+and I do not want to stop it?
+
+@strong{A}: There are several options. If you have taken a backup of the
+master at some point and recorded the binlog name and offset ( from the
+output of @code{SHOW MASTER STATUS} ) corresponding to the snapshot, do
+the following:
+
+@itemize @bullet
+@item
+Make sure unique server id is assigned to the slave.
+@item
+Execute @code{CHANGE MASTER TO MASTER_HOST='master-host-name',
+ MASTER_USER='master-user-name', MASTER_PASSWORD='master-pass',
+ MASTER_LOG_FILE='recorded-log-name', MASTER_LOG_POS=recorded_log_pos}
+@item
+Execute @code{SLAVE START}
+@end itemize
+
+If you do not have a backup of the master already, here is a quick way to
+do it consistently:
+
+@itemize @bullet
+@item
+@code{FLUSH TABLES WITH READ LOCK}
+@item
+@code{gtar zcf /tmp/backup.tar.gz /var/lib/mysql} ( or a variation of this)
+@item
+@code{SHOW MASTER STATUS} - make sure to record the output - you will need it
+later
+@item
+@code{UNLOCK TABLES}
+@end itemize
+
+Afterwards, follow the instructions for the case when you have a snapshot and
+have recorded the log name and offset. You can use the same snapshot to set up
+several slaves. As long as the binary logs of the master are left intact, you
+can wait as long as several days or in some cases maybe a month to set up a
+slave once you have the snapshot of the master. In theory the waiting gap can
+be infinite. The two practical limitations is the diskspace of the master
+getting filled with old logs, and the amount of time it will take the slave to
+catch up.
+
+In version 4.0.0 and newer, you can also use @code{LOAD DATA FROM
+MASTER}. This is a convenient command that will take a snapshot,
+restore it to the slave, and adjust the log name and offset on the slave
+all at once. In the future, @code{LOAD DATA FROM MASTER} will be the
+recommended way to set up a slave. Be warned, howerver, that the read
+lock may be held for a long time if you use this command. It is not yet
+implemented as efficiently as we would like to have it. If you have
+large tables, the preferred method at this time is still with a local
+@code{tar} snapshot after executing @code{FLUSH TABLES WITH READ LOCK}.
+
+@strong{Q}: Does the slave need to be connected to the master all the time?
+
+@strong{A}: No, it does not. You can have the slave go down or stay
+disconnected for hours or even days, then reconnect, catch up on the
+updates, and then disconnect or go down for a while again. So you can,
+for example, use master-slave setup over a dial-up link that is up only
+for short periods of time. The implications of that are that at any
+given time the slave is not guaranteed to be in sync with the master
+unless you take some special measures. In the future, we will have the
+option to block the master until at least one slave is in sync.
+
+@strong{Q}: How do I force the master to block updates until the slave catches
+up?
+
+@strong{A}: Execute the following commands:
+
+@itemize @bullet
+@item
+Master: @code{FLUSH TABLES WITH READ LOCK}
+@item
+Master: @code{SHOW MASTER STATUS} - record the log name and the offset
+@item
+Slave: @code{SELECT MASTER_POS_WAIT('recorded_log_name', recorded_log_offset)}
+When the select returns, the slave is currently in sync with the master
+@item
+Master: @code{UNLOCK TABLES} - now the master will continue updates.
+@end itemize
+
@cindex @code{Binlog_Dump}
@strong{Q}: Why do I sometimes see more than one @code{Binlog_Dump} thread on
the master after I have restarted the slave?
@@ -23956,14 +24497,14 @@ restart the master, start slave threads, and then remove the old log files.
lock the master tables, let the slave catch up, then run @code{FLUSH
MASTER} on the master, and @code{FLUSH SLAVE} on the slave to reset the
logs, then restart new versions of the master and the slave. Note that
-the slave can stay down for some time - since the master is logging
+the slave can stay down for some time -- since the master is logging
all the updates, the slave will be able to catch up once it is up and
can connect.
After 3.23.26, we have locked the replication protocol for modifications, so
you can upgrade masters and slave on the fly to a newer 3.23 version and you
can have different versions of MySQL running on the slave and the
-master, as long as they are both newer than 3.23.26.
+master, as long as they are both newer than 3.23.26.
@cindex replication, two-way
@strong{Q}: What issues should I be aware of when setting up two-way
@@ -23976,7 +24517,7 @@ for client A to make an update to co-master 1, and in the meantime,
before it propagates to co-master 2, client B could make an update to
co-master 2 that will make the update of client A work differently than
it did on co-master 1. Thus when the update of client A will make it
-to co-master 2, it will produce tables that will be different than
+to co-master 2, it will produce tables that will be different from
what you have on co-master 1, even after all the updates from co-master
2 have also propagated. So you should not co-chain two servers in a
two-way replication relationship, unless you are sure that you updates
@@ -23984,12 +24525,12 @@ can safely happen in any order, or unless you take care of mis-ordered
updates somehow in the client code.
-You must also realize that two-way replication actually does not improve
+You must also realise that two-way replication actually does not improve
performance very much, if at all, as far as updates are concerned. Both
servers need to do the same amount of updates each, as you would have
one server do. The only difference is that there will be a little less
lock contention, because the updates originating on another server will
-be serialized in one slave thread. This benefit, though, might be
+be serialised in one slave thread. This benefit, though, might be
offset by network delays.
@cindex performance, improving
@@ -24010,8 +24551,8 @@ performance-enhancing replication?
@strong{A}:
If the part of your code that is responsible for database access has
-been properly abstracted/modularized, converting it to run with the
-replicated setup should be very smooth and easy - just change the
+been properly abstracted/modularised, converting it to run with the
+replicated setup should be very smooth and easy -- just change the
implementation of your database access to read from some slave or the
master, and to always write to the master. If your code does not have
this level of abstraction,
@@ -24041,13 +24582,13 @@ able to take advantage of one-master/many slaves solution. The
code will be a lot easier to maintain, and adding troubleshooting
options will be trivial. You will just need to modify one or two
functions, for example, to log how long each query took, or which
-query, among your many thousands, gave you an error. If you have written a lot of code already,
-you may want to automate the conversion task by using Monty's
-@code{replace} utility, which comes with the standard distribution of
-MySQL, or just write your own Perl script. Hopefully, your
-code follows some recognizable pattern. If not, then you are probably
-better off re-writing it anyway, or at least going through and manually
-beating it into a pattern.
+query, among your many thousands, gave you an error. If you have
+written a lot of code already, you may want to automate the conversion
+task by using Monty's @code{replace} utility, which comes with the
+standard distribution of MySQL, or just write your own Perl script.
+Hopefully, your code follows some recognisable pattern. If not, then
+you are probably better off rewriting it anyway, or at least going
+through and manually beating it into a pattern.
Note that, of course, you can use different names for the
functions. What is important is having unified interface for connecting
@@ -24070,7 +24611,7 @@ of your site, you need to know your query patterns, and empirically
(by benchmarking) determine the relationship between the throughput
on reads (reads per second, or @code{max_reads}) and on writes
@code{max_writes}) on a typical master and a typical slave. The
-example below will show you a rather simplified calculation of what you
+example here will show you a rather simplified calculation of what you
can get with replication for our imagined system.
Let's say our system load consists of 10% writes and 90% reads, and we
@@ -24136,9 +24677,9 @@ the slaves of the master change in case of failure. Some suggestions:
@item
To tell a slave to change the master use the @code{CHANGE MASTER TO} command.
@item
-A good way to keep your applications informed where the master is by
-having a dynamic DNS entry for the master. With @strong{bind} you can
-use @code{nsupdate} to dynamically update your DNS.
+A good way to keep your applications informed as to the location of the
+master is by having a dynamic DNS entry for the master.
+With @code{bind} you can use @file{nsupdate} to dynamically update your DNS.
@item
You should run your slaves with the @code{log-bin} option and without
@code{log-slave-updates}. This way the slave will be ready to become a
@@ -24179,7 +24720,7 @@ If the slave is running, did it establish connection with the master? Do
@code{State} column. If it says @code{connecting to master}, verify the
privileges for the replication user on the master, master host name, your
DNS setup, whether the master is actually running, whether it is reachable
-from the slave, and if all that seems ok, read the error logs.
+from the slave, and if all that seems okay, read the error logs.
@item
If the slave was running, but then stopped, look at SHOW SLAVE STATUS
output and check the error logs. It usually
@@ -24201,11 +24742,11 @@ be safe to make the update manually ( if needed) and then ignore the next
query from the master.
@item
If you have decided you can skip the next query, do
-@code{SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;} to skip a query that
-does not use auto_increment, or last_insert_id or
-@code{SET SQL_SLAVE_SKIP_COUNTER=2; SLAVE START;} otherwise. The reason
-auto_increment/last_insert_id queries are different is that they take
-two events in the binary log of the master.
+@code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;} to skip a query that
+does not use @code{AUTO_INCREMENT} or @code{LAST_INSERT_ID()}, or
+@code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; SLAVE START;} otherwise. The reason
+queries that use @code{AUTO_INCREMENT} or @code{LAST_INSERT_ID()}
+are different is that they take two events in the binary log of the master.
@item
If you are sure the slave started out perfectly in sync with the master,
@@ -24220,7 +24761,7 @@ version.
If all else fails, read the error logs. If they are big,
@code{grep -i slave /path/to/your-log.err} on the slave. There is no
generic pattern to search for on the master, as the only errors it logs
-are general system errors - if it can, it will send the error to the slave
+are general system errors -- if it can, it will send the error to the slave
when things go wrong.
@end itemize
@@ -24233,14 +24774,14 @@ bug report. Ideally, we would like to have a test case in the format found in
case like that, you can expect a patch within a day or two in most cases,
although, of course, you mileage may vary depending on a number of factors.
-Second best option is a just program with easily configurable connection
-arguments for the master and the slave that will demonstrate the problem on our
-systems. You can write one in Perl or in C, depending on which language you
-know better.
+The second best option is to write a simple program with easily configurable
+connection arguments for the master and the slave that will demonstrate
+the problem on our systems. You can write one in Perl or in C, depending
+on which language you know better.
If you have one of the above ways to demonstrate the bug, use
@code{mysqlbug} to prepare a bug report and send it to
-@email{bugs@@lists.mysql.com}. If you have a phantom - a problem that
+@email{bugs@@lists.mysql.com}. If you have a phantom -- a problem that
does occur but you cannot duplicate "at will":
@itemize @bullet
@@ -24250,7 +24791,7 @@ slave outside of the slave thread, the data will be out of sync, and you can
have unique key violations on updates, in which case the slave thread will
stop and wait for you to clean up the tables manually to bring them in sync.
@item
-Run slave with @code{log-slave-updates} and @code{log-bin} - this will keep
+Run slave with @code{log-slave-updates} and @code{log-bin} -- this will keep
a log of all updates on the slave.
@item
Save all evidence before resetting the replication. If we have no or only
@@ -24286,33 +24827,33 @@ isolate it into a separate test case first. Then report the problem to
-@node MySQL Optimization, Reference, MySQL Database Administration, Top
-@chapter MySQL Optimization
+@node MySQL Optimisation, Reference, MySQL Database Administration, Top
+@chapter MySQL Optimisation
@menu
-* Optimize Overview:: Optimization Overview
-* Query Speed:: Optimizing @code{SELECT}s and Other Queries
+* Optimise Overview:: Optimisation Overview
+* Query Speed:: Optimising @code{SELECT}s and Other Queries
* Locking Issues:: Locking Issues
-* Optimizing Database Structure:: Optimizing Database Structure
-* Optimizing the Server:: Optimizing the MySQL Server
+* Optimising Database Structure:: Optimising Database Structure
+* Optimising the Server:: Optimising the MySQL Server
* Disk issues:: Disk Issues
@end menu
-Optimization is a complicated task because it ultimately requires
+Optimisation is a complicated task because it ultimately requires
understanding of the whole system. While it may be possible to do some
-local optimizations with small knowledge of your system or application,
+local optimisations with small knowledge of your system or application,
the more optimal you want your system to become the more you will have
to know about it.
This chapter will try to explain and give some examples of different
-ways to optimize MySQL. Remember, however, that there are
+ways to optimise MySQL. Remember, however, that there are
always some (increasingly harder) additional ways to make the system
even faster.
-@node Optimize Overview, Query Speed, MySQL Optimization, MySQL Optimization
-@section Optimization Overview
+@node Optimise Overview, Query Speed, MySQL Optimisation, MySQL Optimisation
+@section Optimisation Overview
The most important part for getting a system fast is of course the basic
design. You also need to know what kinds of things your system will be
@@ -24323,14 +24864,14 @@ The most common bottlenecks are:
@item Disk seeks.
It takes time for the disk to find a piece of data. With modern disks in
1999, the mean time for this is usually lower than 10ms, so we can in
-theory do about 1000 seeks a second. This time improves slowly with new
-disks and is very hard to optimize for a single table. The way to
-optimize this is to spread the data on more than one disk.
+theory do about 100 seeks a second. This time improves slowly with new
+disks and is very hard to optimise for a single table. The way to
+optimise this is to spread the data on more than one disk.
@item Disk reading/writing.
When the disk is at the correct position we need to read the data. With
-modern disks in 1999, one disk delivers something like 10-20Mb/s. This
-is easier to optimize than seeks because you can read in parallel from
+modern disks in 1999, one disk delivers something like 10-20MB/s. This
+is easier to optimise than seeks because you can read in parallel from
multiple disks.
@item CPU cycles.
@@ -24355,26 +24896,51 @@ for most systems, but one should be aware of it.
@end menu
-@node Design Limitations, Portability, Optimize Overview, Optimize Overview
+@node Design Limitations, Portability, Optimise Overview, Optimise Overview
@subsection MySQL Design Limitations/Tradeoffs
@cindex design, limitations
@cindex limitations, design
-Because MySQL uses extremely fast table locking (multiple readers /
-single writers) the biggest remaining problem is a mix of a steady stream of
-inserts and slow selects on the same table.
+When using the MyISAM table handler, MySQL uses extremely fast table
+locking (multiple readers / single writers). The biggest problem with
+this table type is a if you have a mix of a steady stream of updates and
+slow selects on the same table. If this is a problem with some tables,
+you can use another table type for these. @xref{Table types}.
-We believe that for a huge number of systems the extremely fast
-performance in other cases make this choice a win. This case is usually
-also possible to solve by having multiple copies of the table, but it
-takes more effort and hardware.
+MySQL can work with both transactional and not transactional tables. To
+be able to work smoothly with not transactional tables (which can't
+rollback if something goes wrong), MySQL has the following rules:
+
+@cindex default values
+@itemize @bullet
+@item
+All columns has default values.
+@item
+If you insert a 'wrong' value in a column like a @code{NULL} in a
+@code{NOT NULL} column or a too big numerical value in a numerical
+column, MySQL will instead of giving an error instead set the column to
+the 'best possible value'. For numerical values this is 0, the smallest
+possible values or the largest possible value. For strings this is
+either the empty string or the longest possible string that can be in
+the column.
+@item
+All calculated expressions returns a value that can be used instead of
+signaling an error condition. For example 1/0 returns @code{NULL}
+@end itemize
-We are also working on some extensions to solve this problem for some
-common application niches.
+The reason for the above rules is that we can't check these conditions
+before the query starts to execute. If we encounter a problem after
+updating a few rows, we can't just rollback as the table type may not
+support this. We can't stop because in that case the update would be
+'half done' which is probably the worst possible scenario. In this case
+it's better to 'do the best you can' and then continue as if nothing
+happened.
+The above means that one should not use MySQL to check fields content,
+but one should do this in the application.
-@node Portability, Internal use, Design Limitations, Optimize Overview
+@node Portability, Internal use, Design Limitations, Optimise Overview
@subsection Portability
@cindex portability
@@ -24389,7 +24955,7 @@ application that is fast with many databases it becomes even harder!
To make a complex application portable you need to choose a number of
SQL servers that it should work with.
-You can use the MySQL crash-me program/web-page
+You can use the MySQL @code{crash-me} program/web-page
@uref{http://www.mysql.com/information/crash-me.php} to find functions,
types, and limits you can use with a selection of database
servers. Crash-me now tests far from everything possible, but it
@@ -24398,7 +24964,7 @@ is still comprehensive with about 450 things tested.
For example, you shouldn't have column names longer than 18 characters
if you want to be able to use Informix or DB2.
-Both the MySQL benchmarks and crash-me programs are very
+Both the MySQL benchmarks and @code{crash-me} programs are very
database-independent. By taking a look at how we have handled this, you
can get a feeling for what you have to do to write your application
database-independent. The benchmarks themselves can be found in the
@@ -24411,10 +24977,10 @@ from this benchmark.
As you can see in these results, all databases have some weak points. That
is, they have different design compromises that lead to different
-behavior.
+behaviour.
If you strive for database independence, you need to get a good feeling
-for each SQL server's bottlenecks. MySQL is VERY fast in
+for each SQL server's bottlenecks. MySQL is very fast in
retrieving and updating things, but will have a problem in mixing slow
readers/writers on the same table. Oracle, on the other hand, has a big
problem when you try to access rows that you have recently updated
@@ -24435,11 +25001,11 @@ MySQL-specific keywords to a query. The code inside
@code{/**/} will be treated as a comment (ignored) by most other SQL
servers.
-If REAL high performance is more important than exactness, as in some
-Web applications, a possibility is to create an application layer that
+If high performance is more important than exactness, as in some
+web applications, it is possibile to create an application layer that
caches all results to give you even higher performance. By letting
old results 'expire' after a while, you can keep the cache reasonably
-fresh. This is quite nice in case of extremely high load, in which case
+fresh. This provides a method to handle high load spikes, in which case
you can dynamically increase the cache and set the expire timeout higher
until things get back to normal.
@@ -24448,7 +25014,7 @@ of the initial size of the cache and how often the table should normally
be refreshed.
-@node Internal use, MySQL Benchmarks, Portability, Optimize Overview
+@node Internal use, MySQL Benchmarks, Portability, Optimise Overview
@subsection What Have We Used MySQL For?
@cindex uses, of MySQL
@@ -24472,8 +25038,8 @@ We solved this by storing all information per month in compressed
'transaction' tables. We have a set of simple macros (script) that
generates summary tables grouped by different criteria (product group,
customer id, store ...) from the transaction tables. The reports are
-Web pages that are dynamically generated by a small Perl script that
-parses a Web page, executes the SQL statements in it, and inserts the
+web pages that are dynamically generated by a small Perl script that
+parses a web page, executes the SQL statements in it, and inserts the
results. We would have used PHP or mod_perl instead but they were
not available at that time.
@@ -24513,7 +25079,7 @@ makes the machine feel very slow and unresponsive while big batches are
going. Hopefully this will be better handled in future Linux Kernels.
-@node MySQL Benchmarks, Custom Benchmarks, Internal use, Optimize Overview
+@node MySQL Benchmarks, Custom Benchmarks, Internal use, Optimise Overview
@subsection The MySQL Benchmark Suite
@cindex benchmark suite
@@ -24534,38 +25100,38 @@ multi-threaded tests to the benchmark suite.
For example, (run on the same NT 4.0 machine):
-@multitable @columnfractions .6 .2 .2
-@strong{Reading 2000000 rows by index} @tab @strong{Seconds} @tab @strong{Seconds}
-@item mysql @tab 367 @tab 249
-@item mysql_odbc @tab 464
-@item db2_odbc @tab 1206
-@item informix_odbc @tab 121126
-@item ms-sql_odbc @tab 1634
-@item oracle_odbc @tab 20800
-@item solid_odbc @tab 877
-@item sybase_odbc @tab 17614
+@multitable @columnfractions .35 .10 .10
+@item @strong{Reading 2000000 rows by index} @tab @strong{Seconds} @tab @strong{Seconds}
+@item mysql @tab 367 @tab 249
+@item mysql_odbc @tab 464 @tab
+@item db2_odbc @tab 1206 @tab
+@item informix_odbc @tab 121126 @tab
+@item ms-sql_odbc @tab 1634 @tab
+@item oracle_odbc @tab 20800 @tab
+@item solid_odbc @tab 877 @tab
+@item sybase_odbc @tab 17614 @tab
@end multitable
-@multitable @columnfractions .6 .2 .2
-@strong{Inserting (350768) rows} @tab @strong{Seconds} @tab @strong{Seconds}
-@item mysql @tab 381 @tab 206
-@item mysql_odbc @tab 619
-@item db2_odbc @tab 3460
-@item informix_odbc @tab 2692
-@item ms-sql_odbc @tab 4012
-@item oracle_odbc @tab 11291
-@item solid_odbc @tab 1801
-@item sybase_odbc @tab 4802
+@multitable @columnfractions .35 .10 .10
+@item @strong{Inserting (350768) rows} @tab @strong{Seconds} @tab @strong{Seconds}
+@item mysql @tab 381 @tab 206
+@item mysql_odbc @tab 619 @tab
+@item db2_odbc @tab 3460 @tab
+@item informix_odbc @tab 2692 @tab
+@item ms-sql_odbc @tab 4012 @tab
+@item oracle_odbc @tab 11291 @tab
+@item solid_odbc @tab 1801 @tab
+@item sybase_odbc @tab 4802 @tab
@end multitable
In the above test MySQL was run with a 8M index cache.
-We have gather some more benchmark results at
+We have gathered some more benchmark results at
@uref{http://www.mysql.com/information/benchmarks.html}.
Note that Oracle is not included because they asked to be removed. All
Oracle benchmarks have to be passed by Oracle! We believe that makes
-Oracle benchmarks @strong{VERY} biased because the above benchmarks are
+Oracle benchmarks @strong{very} biased because the above benchmarks are
supposed to show what a standard installation can do for a single
client.
@@ -24599,11 +25165,11 @@ How big a query can be
How big a @code{VARCHAR} column can be
@end itemize
-We can find the result from crash-me on a lot of different databases at
+We can find the result from @code{crash-me} on a lot of different databases at
@uref{http://www.mysql.com/information/crash-me.php}.
-@node Custom Benchmarks, , MySQL Benchmarks, Optimize Overview
+@node Custom Benchmarks, , MySQL Benchmarks, Optimise Overview
@subsection Using Your Own Benchmarks
@cindex benchmarks
@@ -24627,8 +25193,8 @@ It is very common that some problems only occur when the system is very
heavily loaded. We have had many customers who contact us when they
have a (tested) system in production and have encountered load problems. In
every one of these cases so far, it has been problems with basic design
-(table scans are NOT good at high load) or OS/Library issues. Most of
-this would be a @strong{LOT} easier to fix if the systems were not
+(table scans are @strong{not good} at high load) or OS/Library issues. Most of
+this would be a @strong{lot} easier to fix if the systems were not
already in production.
To avoid problems like this, you should put some effort into benchmarking
@@ -24639,8 +25205,8 @@ As the name suggests, it can bring your system down to its knees if you ask it,
so make sure to use it only on your development systems.
-@node Query Speed, Locking Issues, Optimize Overview, MySQL Optimization
-@section Optimizing @code{SELECT}s and Other Queries
+@node Query Speed, Locking Issues, Optimise Overview, MySQL Optimisation
+@section Optimising @code{SELECT}s and Other Queries
@cindex queries, speed of
@cindex permission checks, effect on speed
@@ -24650,17 +25216,17 @@ First, one thing that affects all queries: The more complex permission
system setup you have, the more overhead you get.
If you do not have any @code{GRANT} statements done, MySQL will
-optimize the permission checking somewhat. So if you have a very high
-volume it may be worth the time to avoid grants. Otherwise more
+optimise the permission checking somewhat. So if you have a very high
+volume it may be worth the time to avoid grants. Otherwise, more
permission check results in a larger overhead.
If your problem is with some explicit MySQL function, you can
always time this in the MySQL client:
@example
-mysql> select benchmark(1000000,1+1);
+mysql> SELECT BENCHMARK(1000000,1+1);
+------------------------+
-| benchmark(1000000,1+1) |
+| BENCHMARK(1000000,1+1) |
+------------------------+
| 0 |
+------------------------+
@@ -24670,22 +25236,23 @@ mysql> select benchmark(1000000,1+1);
The above shows that MySQL can execute 1,000,000 @code{+}
expressions in 0.32 seconds on a @code{PentiumII 400MHz}.
-All MySQL functions should be very optimized, but there may be
-some exceptions, and the @code{benchmark(loop_count,expression)} is a
+All MySQL functions should be very optimised, but there may be
+some exceptions, and the @code{BENCHMARK(loop_count,expression)} is a
great tool to find out if this is a problem with your query.
@menu
* EXPLAIN:: @code{EXPLAIN} Syntax (Get Information About a @code{SELECT})
* Estimating performance:: Estimating query performance
* SELECT speed:: Speed of @code{SELECT} queries
-* Where optimizations:: How MySQL optimizes @code{WHERE} clauses
-* DISTINCT optimization:: How MySQL Optimizes @code{DISTINCT}
-* LEFT JOIN optimization:: How MySQL optimizes @code{LEFT JOIN}
-* LIMIT optimization:: How MySQL optimizes @code{LIMIT}
+* Where optimisations:: How MySQL optimises @code{WHERE} clauses
+* DISTINCT optimisation:: How MySQL Optimises @code{DISTINCT}
+* LEFT JOIN optimisation:: How MySQL optimises @code{LEFT JOIN}
+* ORDER BY optimisation:: How MySQL Optimises @code{ORDER BY}
+* LIMIT optimisation:: How MySQL optimises @code{LIMIT}
* Insert speed:: Speed of @code{INSERT} queries
* Update speed:: Speed of @code{UPDATE} queries
* Delete speed:: Speed of @code{DELETE} queries
-* Tips:: Other Optimization Tips
+* Tips:: Other Optimisation Tips
@end menu
@@ -24693,7 +25260,7 @@ great tool to find out if this is a problem with your query.
@subsection @code{EXPLAIN} Syntax (Get Information About a @code{SELECT})
@findex EXPLAIN
-@findex SELECT, optimizing
+@findex SELECT, optimising
@example
EXPLAIN tbl_name
@@ -24709,8 +25276,8 @@ information about how tables are joined and in which order.
With the help of @code{EXPLAIN}, you can see when you must add indexes
to tables to get a faster @code{SELECT} that uses indexes to find the
-records. You can also see if the optimizer joins the tables in an optimal
-order. To force the optimizer to use a specific join order for a
+records. You can also see if the optimiser joins the tables in an optimal
+order. To force the optimiser to use a specific join order for a
@code{SELECT} statement, add a @code{STRAIGHT_JOIN} clause.
For non-simple joins, @code{EXPLAIN} returns a row of information for each
@@ -24748,12 +25315,12 @@ and check the query with @code{EXPLAIN} again. @xref{ALTER TABLE}.
To see what indexes a table has, use @code{SHOW INDEX FROM tbl_name}.
@item key
-The @code{key} column indicates the key that MySQL actually
+The @code{key} column indicates the key (index) that MySQL actually
decided to use. The key is @code{NULL} if no index was chosen. If
MySQL chooses the wrong index, you can probably force
MySQL to use another index by using @code{myisamchk --analyze},
@xref{myisamchk syntax}, or by using @code{USE INDEX/IGNORE INDEX}.
-@xref{JOIN}.
+@xref{SELECT}.
@item key_len
The @code{key_len} column indicates the length of the key that
@@ -24780,7 +25347,7 @@ MySQL will not continue searching for more rows for the current row
combination after it has found the first matching row.
@item Not exists
-MySQL was able to do a @code{LEFT JOIN} optimization on the
+MySQL was able to do a @code{LEFT JOIN} optimisation on the
query and will not examine more rows in this table for the previous row
combination after it finds one row that matches the @code{LEFT JOIN} criteria.
@@ -24837,7 +25404,7 @@ If you want to get your queries as fast as possible, you should look out for
@code{Using filesort} and @code{Using temporary}.
@end table
-The different join types are listed below, ordered from best to worst type:
+The different join types are listed here, ordered from best to worst type:
@cindex system table
@cindex tables, system
@@ -24852,7 +25419,7 @@ the @code{const} join type.
The table has at most one matching row, which will be read at the start
of the query. Because there is only one row, values from the column in
this row can be regarded as constants by the rest of the
-optimizer. @code{const} tables are very fast as they are read only once!
+optimiser. @code{const} tables are very fast as they are read only once!
@item eq_ref
One row will be read from this table for each combination of rows from
@@ -24877,7 +25444,7 @@ The @code{ref} column will be NULL for this type.
@item index
This is the same as @code{ALL}, except that only the index tree is
scanned. This is usually faster than @code{ALL}, as the index file is usually
-smaller than the data file.
+smaller than the datafile.
@item ALL
A full table scan will be done for each combination of rows from the
@@ -24895,10 +25462,10 @@ number is also used when you restrict queries with the @code{max_join_size}
variable.
@xref{Server parameters}.
-The following example shows how a @code{JOIN} can be optimized progressively
+The following example shows how a @code{JOIN} can be optimised progressively
using the information provided by @code{EXPLAIN}.
-Suppose you have the @code{SELECT} statement shown below, that you examine
+Suppose you have the @code{SELECT} statement shown here, that you examine
using @code{EXPLAIN}:
@example
@@ -24922,7 +25489,7 @@ For this example, assume that:
@item
The columns being compared have been declared as follows:
-@multitable @columnfractions .1 .2 .7
+@multitable @columnfractions .10 .15 .15
@item @strong{Table} @tab @strong{Column} @tab @strong{Column type}
@item @code{tt} @tab @code{ActualPC} @tab @code{CHAR(10)}
@item @code{tt} @tab @code{AssignedPC} @tab @code{CHAR(10)}
@@ -24932,9 +25499,9 @@ The columns being compared have been declared as follows:
@end multitable
@item
-The tables have the indexes shown below:
+The tables have the indexes shown here:
-@multitable @columnfractions .1 .9
+@multitable @columnfractions .10 .30
@item @strong{Table} @tab @strong{Index}
@item @code{tt} @tab @code{ActualPC}
@item @code{tt} @tab @code{AssignedPC}
@@ -24947,7 +25514,7 @@ The tables have the indexes shown below:
The @code{tt.ActualPC} values aren't evenly distributed.
@end itemize
-Initially, before any optimizations have been performed, the @code{EXPLAIN}
+Initially, before any optimisations have been performed, the @code{EXPLAIN}
statement produces the following information:
@example
@@ -25003,17 +25570,19 @@ do.CUSTNMBR} comparisons:
@example
mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
- MODIFY ClientID VARCHAR(15);
+ -> MODIFY ClientID VARCHAR(15);
@end example
-Now @code{EXPLAIN} produces the output shown below:
+Now @code{EXPLAIN} produces the output shown here:
@example
-table type possible_keys key key_len ref rows Extra
-et ALL PRIMARY NULL NULL NULL 74
-tt ref AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
-et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
-do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
+table type possible_keys key key_len ref rows Extra
+et ALL PRIMARY NULL NULL NULL 74
+tt ref AssignedPC, ActualPC 15 et.EMPLOYID 52 where used
+ ClientID,
+ ActualPC
+et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
+do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
@end example
This is almost as good as it can get.
@@ -25031,15 +25600,17 @@ shell> mysqladmin refresh
Now the join is perfect, and @code{EXPLAIN} produces this result:
@example
-table type possible_keys key key_len ref rows Extra
-tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used
-et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
-et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
-do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
+table type possible_keys key key_len ref rows Extra
+tt ALL AssignedPC NULL NULL NULL 3872 where used
+ ClientID,
+ ActualPC
+et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
+et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
+do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
@end example
Note that the @code{rows} column in the output from @code{EXPLAIN} is an
-educated guess from the MySQL join optimizer. To optimize a
+educated guess from the MySQL join optimiser. To optimise a
query, you should check if the numbers are even close to the truth. If not,
you may get better performance by using @code{STRAIGHT_JOIN} in your
@code{SELECT} statement and trying to list the tables in a different order in
@@ -25083,7 +25654,7 @@ go much slower until your applications is only bound by disk-seeks
the data grows. @xref{Server parameters}.
-@node SELECT speed, Where optimizations, Estimating performance, Query Speed
+@node SELECT speed, Where optimisations, Estimating performance, Query Speed
@subsection Speed of @code{SELECT} Queries
@findex SELECT speed
@@ -25091,7 +25662,7 @@ the data grows. @xref{Server parameters}.
@cindex speed, of queries
In general, when you want to make a slow @code{SELECT ... WHERE} faster, the
-first thing to check is whether or not you can add an index. @xref{MySQL
+first thing to check is whether you can add an index. @xref{MySQL
indexes, , MySQL indexes}. All references between different tables
should usually be done with indexes. You can use the @code{EXPLAIN} command
to determine which indexes are used for a @code{SELECT}.
@@ -25101,11 +25672,11 @@ Some general tips:
@itemize @bullet
@item
-To help MySQL optimize queries better, run @code{myisamchk
+To help MySQL optimise queries better, run @code{myisamchk
--analyze} on a table after it has been loaded with relevant data. This
updates a value for each index part that indicates the average number of
rows that have the same value. (For unique indexes, this is always 1,
-of course.). MySQL will use this to decide which index to
+of course.) MySQL will use this to decide which index to
choose when you connect two tables with 'a non-constant expression'.
You can check the result from the @code{analyze} run by doing @code{SHOW
INDEX FROM table_name} and examining the @code{Cardinality} column.
@@ -25120,21 +25691,21 @@ time for a large table!
@end itemize
-@node Where optimizations, DISTINCT optimization, SELECT speed, Query Speed
-@subsection How MySQL Optimizes @code{WHERE} Clauses
+@node Where optimisations, DISTINCT optimisation, SELECT speed, Query Speed
+@subsection How MySQL Optimises @code{WHERE} Clauses
@findex WHERE
-@cindex optimizations
+@cindex optimisations
-The @code{WHERE} optimizations are put in the @code{SELECT} part here because
-they are mostly used with @code{SELECT}, but the same optimizations apply for
+The @code{WHERE} optimisations are put in the @code{SELECT} part here because
+they are mostly used with @code{SELECT}, but the same optimisations apply for
@code{WHERE} in @code{DELETE} and @code{UPDATE} statements.
Also note that this section is incomplete. MySQL does many
-optimizations, and we have not had time to document them all.
+optimisations, and we have not had time to document them all.
-Some of the optimizations performed by MySQL are listed below:
+Some of the optimisations performed by MySQL are listed here:
@itemize @bullet
@item
@@ -25159,8 +25730,8 @@ Constant condition removal (needed because of constant folding):
Constant expressions used by indexes are evaluated only once.
@item
@code{COUNT(*)} on a single table without a @code{WHERE} is retrieved
-directly from the table information. This is also done for any @code{NOT NULL}
-expression when used with only one table.
+directly from the table information for MyISAM and HEAP tables. This is
+also done for any @code{NOT NULL} expression when used with only one table.
@item
Early detection of invalid constant expressions. MySQL quickly
detects that some @code{SELECT} statements are impossible and returns no rows.
@@ -25188,7 +25759,7 @@ All the following tables are used as constant tables:
@example
mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2
- WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
+ -> WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
@end example
@item
@@ -25209,7 +25780,7 @@ Each table index is queried, and the best index that spans fewer than 30% of
the rows is used. If no such index can be found, a quick table scan is used.
@item
In some cases, MySQL can read rows from the index without even
-consulting the data file. If all columns used from the index are numeric,
+consulting the datafile. If all columns used from the index are numeric,
then only the index tree is used to resolve the query.
@item
Before each record is output, those that do not match the @code{HAVING} clause
@@ -25222,11 +25793,11 @@ Some examples of queries that are very fast:
mysql> SELECT COUNT(*) FROM tbl_name;
mysql> SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
mysql> SELECT MAX(key_part2) FROM tbl_name
- WHERE key_part_1=constant;
+ -> WHERE key_part_1=constant;
mysql> SELECT ... FROM tbl_name
- ORDER BY key_part1,key_part2,... LIMIT 10;
+ -> ORDER BY key_part1,key_part2,... LIMIT 10;
mysql> SELECT ... FROM tbl_name
- ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;
+ -> ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;
@end example
The following queries are resolved using only the index tree (assuming
@@ -25235,7 +25806,7 @@ the indexed columns are numeric):
@example
mysql> SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
mysql> SELECT COUNT(*) FROM tbl_name
- WHERE key_part1=val1 AND key_part2=val2;
+ -> WHERE key_part1=val1 AND key_part2=val2;
mysql> SELECT key_part2 FROM tbl_name GROUP BY key_part1;
@end example
@@ -25243,17 +25814,19 @@ The following queries use indexing to retrieve the rows in sorted
order without a separate sorting pass:
@example
-mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... ;
-mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,... ;
+mysql> SELECT ... FROM tbl_name
+ -> ORDER BY key_part1,key_part2,... ;
+mysql> SELECT ... FROM tbl_name
+ -> ORDER BY key_part1 DESC,key_part2 DESC,... ;
@end example
-@node DISTINCT optimization, LEFT JOIN optimization, Where optimizations, Query Speed
-@subsection How MySQL Optimizes @code{DISTINCT}
+@node DISTINCT optimisation, LEFT JOIN optimisation, Where optimisations, Query Speed
+@subsection How MySQL Optimises @code{DISTINCT}
@findex DISTINCT
-@cindex optimizing, DISTINCT
+@cindex optimising, DISTINCT
@code{DISTINCT} is converted to a @code{GROUP BY} on all columns,
@code{DISTINCT} combined with @code{ORDER BY} will in many cases also
@@ -25274,12 +25847,12 @@ MySQL will stop reading from t2 (for that particular row in t1)
when the first row in t2 is found.
-@node LEFT JOIN optimization, LIMIT optimization, DISTINCT optimization, Query Speed
-@subsection How MySQL Optimizes @code{LEFT JOIN} and @code{RIGHT JOIN}
+@node LEFT JOIN optimisation, ORDER BY optimisation, DISTINCT optimisation, Query Speed
+@subsection How MySQL Optimises @code{LEFT JOIN} and @code{RIGHT JOIN}
@findex LEFT JOIN
-@cindex optimizing, LEFT JOIN
+@cindex optimising, LEFT JOIN
@code{A LEFT JOIN B} in MySQL is implemented as follows:
@@ -25296,12 +25869,12 @@ that are used in the @code{LEFT JOIN} condition.
All @code{LEFT JOIN} conditions are moved to the @code{WHERE} clause.
@item
-All standard join optimizations are done, with the exception that a table is
+All standard join optimisations are done, with the exception that a table is
always read after all tables it is dependent on. If there is a circular
dependence then MySQL will issue an error.
@item
-All standard @code{WHERE} optimizations are done.
+All standard @code{WHERE} optimisations are done.
@item
If there is a row in @code{A} that matches the @code{WHERE} clause, but there
@@ -25320,32 +25893,152 @@ matches the @code{LEFT JOIN} condition.
@code{RIGHT JOIN} is implemented analogously as @code{LEFT JOIN}.
The table read order forced by @code{LEFT JOIN} and @code{STRAIGHT JOIN}
-will help the join optimizer (which calculates in which order tables
+will help the join optimiser (which calculates in which order tables
should be joined) to do its work much more quickly, as there are fewer
table permutations to check.
Note that the above means that if you do a query of type:
@example
-SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
+SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key)
+ WHERE b.key=d.key
@end example
-MySQL will do a full scan on @code{b} as the @code{LEFT JOIN} will force
+MySQL will do a full scan on @code{b} as the @code{LEFT JOIN} will force
it to be read before @code{d}.
The fix in this case is to change the query to:
@example
-SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
+SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key)
+ WHERE b.key=d.key
+@end example
+
+
+@node ORDER BY optimisation, LIMIT optimisation, LEFT JOIN optimisation, Query Speed
+@subsection How MySQL Optimises @code{ORDER BY}
+
+In some cases MySQL can uses index to satisfy an @code{ORDER BY} or
+@code{GROUP BY} request without doing any extra sorting.
+
+The index can also be used even if the @code{ORDER BY} doesn't match the
+index exactly, as long as all the unused index parts and all the extra
+are @code{ORDER BY} columns are constants in the @code{WHERE}
+clause. The following queries will use the index to resolve the
+@code{ORDER BY} / @code{GROUP BY} part:
+
+@example
+SELECT * FROM t1 ORDER BY key_part1,key_part2,...
+SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2
+SELECT * FROM t1 WHERE key_part1=constant GROUP BY key_part2
+SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 DESC
+SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC,key_part2 DESC
@end example
+Some cases where MySQL can @strong{not} use indexes to resolve the @code{ORDER
+BY}: (Note that MySQL will still use indexes to find the rows that
+matches the @code{WHERE} clause):
+
+@itemize @bullet
+@item
+You are doing an @code{ORDER BY} on different keys:
+
+@code{SELECT * FROM t1 ORDER BY key1,key2}
+@item
+You are doing an @code{ORDER BY} using non-consecutive key parts.
+
+@code{SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2}
+
+@item
+You are mixing @code{ASC} and @code{DESC}.
+
+@code{SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 ASC}
+
+@item
+The key used to fetch the rows are not the same one that is used to
+do the @code{ORDER BY}:
+
+@code{SELECT * FROM t1 WHERE key2=constant ORDER BY key1}
+
+@item
+You are joining many tables and the columns you are doing an @code{ORDER
+BY} on are not all from the first not-const table that is used to
+retrieve rows (This is the first table in the @code{EXPLAIN} output which
+doesn't use a @code{const} row fetch method).
+
+@item
+You have different @code{ORDER BY} and @code{GROUP BY} expressions.
+
+@item
+The used table index is an index type that doesn't store rows in order.
+(Like the @code{HASH} index in @code{HEAP} tables).
+
+@item
+The index colum may contain @code{NULL} values and one is using
+@code{ORDER BY ... DESC}. This is because in SQL @code{NULL} values is
+always sorted before normal values, independent of you are using
+@code{DESC} or not.
+@end itemize
+
+
+In the cases where MySQL have to sort the result, it uses the following
+algorithm:
+
+@itemize @bullet
+@item
+Read all rows according to key or by table scanning.
+Rows that doesn't match the WHERE clause are skipped.
+@item
+Store the sort-key in a buffer (of size @code{sort_buffer}).
+@item
+When the buffer gets full, run a qsort on it and store the result
+in a temporary file. Save a pointer to the sorted block.
+(In the case where all rows fits into the sort buffer, no temporary
+file is created)
+@item
+Repeat the above until all rows have been read.
+@item
+Do a multi-merge of up to @code{MERGEBUFF} (7) regions to one block in
+another temporary file. Repeat until all blocks from the first file
+are in the second file.
+@item
+Repeat the following until there is less than @code{MERGEBUFF2} (15)
+blocks left.
+@item
+On the last multi-merge, only the pointer to the row (last part of
+the sort-key) is written to a result file.
+@item
+Now the code in @file{sql/records.cc} will be used to read through them
+in sorted order by using the row pointers in the result file. To
+optimize this, we read in a big block of row pointers, sort these and
+then we read the rows in the sorted order into a row buffer
+(@code{record_rnd_buffer}) .
+@end itemize
+
+You can with @code{EXPLAIN SELECT ... ORDER BY} check if MySQL can use
+indexes to resolve the query. If you get @code{Using filesort} in the
+@code{extra} column, then MySQL can't use indexes to resolve the
+@code{ORDER BY}. @xref{EXPLAIN}.
+
+If you want to have a higher @code{ORDER BY} speed, you should first
+see if you can get MySQL to use indexes instead of having to do an extra
+sorting phase. If this is not possible, then you can do:
+
+@itemize @bullet
+@item
+Increase the size of the @code{sort_buffer} variable.
+@item
+Increase the size of the @code{record_rnd_buffer} variable.
+@item
+Change @code{tmpdir} to point to a dedicated disk with lots of empty space.
+@end itemize
-@node LIMIT optimization, Insert speed, LEFT JOIN optimization, Query Speed
-@subsection How MySQL Optimizes @code{LIMIT}
+@node LIMIT optimisation, Insert speed, ORDER BY optimisation, Query Speed
+@subsection How MySQL Optimises @code{LIMIT}
@findex LIMIT
-@cindex optimizing, LIMIT
+@cindex optimising, LIMIT
In some cases MySQL will handle the query differently when you are
using @code{LIMIT #} and not using @code{HAVING}:
@@ -25366,20 +26059,20 @@ as soon as it finds @code{#} unique rows.
In some cases a @code{GROUP BY} can be resolved by reading the key in order
(or do a sort on the key) and then calculate summaries until the
key value changes. In this case @code{LIMIT #} will not calculate any
-unnecessary @code{GROUP BY}'s.
+unnecessary @code{GROUP BY}s.
@item
As soon as MySQL has sent the first @code{#} rows to the client, it
-will abort the query.
+will abort the query (If you are not using @code{SQL_CALC_FOUND_ROWS}).
@item
@code{LIMIT 0} will always quickly return an empty set. This is useful
to check the query and to get the column types of the result columns.
@item
-The size of temporary tables uses the @code{LIMIT #} to calculate how much
-space is needed to resolve the query.
+When the server uses temporary tables to resolve the query, the
+@code{LIMIT #} is used to calculate how much space is required.
@end itemize
-@node Insert speed, Update speed, LIMIT optimization, Query Speed
+@node Insert speed, Update speed, LIMIT optimisation, Query Speed
@subsection Speed of @code{INSERT} Queries
@findex INSERT
@@ -25416,14 +26109,16 @@ Some ways to speed up inserts:
@itemize @bullet
@item
If you are inserting many rows from the same client at the same time, use
-multiple value lists @code{INSERT} statements. This is much faster (many
-times in some cases) than using separate @code{INSERT} statements.
+multiple value lists @code{INSERT} statements. This is much faster (many times
+in some cases) than using separate @code{INSERT} statements. If you are adding
+data to non-empty table, you may tune up @code{bulk_insert_buffer_size}
+variable to make it even faster. @xref{SHOW VARIABLES}.
@item
If you are inserting a lot of rows from different clients, you can get
higher speed by using the @code{INSERT DELAYED} statement. @xref{INSERT,
, @code{INSERT}}.
@item
-Note that with @code{MyISAM} you can insert rows at the same time
+Note that with @code{MyISAM} tables you can insert rows at the same time
@code{SELECT}s are running if there are no deleted rows in the tables.
@item
When loading a table from a text file, use @code{LOAD DATA INFILE}. This
@@ -25465,10 +26160,21 @@ Execute a @code{FLUSH TABLES} statement or the shell command @code{mysqladmin
flush-tables}.
@end enumerate
-This procedure will be built into @code{LOAD DATA INFILE} in some future
-version of MySQL.
+Note that @code{LOAD DATA INFILE} also does the above optimization if
+you insert into an empty table; the main difference with the above
+procedure is that you can let myisamchk allocate much more temporary
+memory for the index creation that you may want MySQL to allocate for
+every index recreation.
+
+Since @strong{MySQL 4.0} you can also use
+@code{ALTER TABLE tbl_name DISABLE KEYS} instead of
+@code{myisamchk --keys-used=0 -rq /path/to/db/tbl_name} and
+@code{ALTER TABLE tbl_name ENABLE KEYS} instead of
+@code{myisamchk -r -q /path/to/db/tbl_name}. This way you can also skip
+@code{FLUSH TABLES} steps.
@item
-You can speed up insertions by locking your tables:
+You can speed up insertions that is done over multiple statements by
+locking your tables:
@example
mysql> LOCK TABLES a WRITE;
@@ -25483,6 +26189,9 @@ be as many index buffer flushes as there are different @code{INSERT}
statements. Locking is not needed if you can insert all rows with a single
statement.
+For transactional tables, you should use @code{BEGIN/COMMIT} instead of
+@code{LOCK TABLES} to get a speedup.
+
Locking will also lower the total time of multi-connection tests, but the
maximum wait time for some threads will go up (because they wait for
locks). For example:
@@ -25515,7 +26224,7 @@ To get some more speed for both @code{LOAD DATA INFILE} and
@node Update speed, Delete speed, Insert speed, Query Speed
@subsection Speed of @code{UPDATE} Queries
-Update queries are optimized as a @code{SELECT} query with the additional
+Update queries are optimised as a @code{SELECT} query with the additional
overhead of a write. The speed of the write is dependent on the size of
the data that is being updated and the number of indexes that are
updated. Indexes that are not changed will not be updated.
@@ -25542,10 +26251,10 @@ the index cache. @xref{Server parameters}.
@node Tips, , Delete speed, Query Speed
-@subsection Other Optimization Tips
+@subsection Other Optimisation Tips
-@cindex optimization, tips
-@cindex tips, optimization
+@cindex optimisation, tips
+@cindex tips, optimisation
Unsorted tips for faster systems:
@@ -25560,7 +26269,7 @@ Always check that all your queries really use the indexes you have created
in the tables. In MySQL you can do this with the @code{EXPLAIN}
command. @xref{EXPLAIN, Explain, Explain, manual}.
@item
-Try to avoid complex @code{SELECT} queries on tables that are updated a
+Try to avoid complex @code{SELECT} queries on MyISAM tables that are updated a
lot. This is to avoid problems with table locking.
@item
The new @code{MyISAM} tables can insert rows in a table without deleted
@@ -25569,14 +26278,14 @@ for you, you should consider methods where you don't have to delete rows
or run @code{OPTIMIZE TABLE} after you have deleted a lot of rows.
@item
Use @code{ALTER TABLE ... ORDER BY expr1,expr2...} if you mostly
-retrieve rows in expr1,expr2.. order. By using this option after big
+retrieve rows in expr1,expr2... order. By using this option after big
changes to the table, you may be able to get higher performance.
@item
In some cases it may make sense to introduce a column that is 'hashed'
based on information from other columns. If this column is short and
reasonably unique it may be much faster than a big index on many
columns. In MySQL it's very easy to use this extra column:
-@code{SELECT * FROM table_name WHERE hash=MD5(concat(col1,col2))
+@code{SELECT * FROM table_name WHERE hash=MD5(CONCAT(col1,col2))
AND col_1='constant' AND col_2='constant'}
@item
For tables that change a lot you should try to avoid all @code{VARCHAR}
@@ -25663,15 +26372,15 @@ is integrated in @code{mysqld}.
Use @code{AUTO_INCREMENT} columns to make unique values.
@item
Use @code{OPTIMIZE TABLE} once in a while to avoid fragmentation when
-using dynamic table format. @xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.
+using a dynamic table format. @xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.
@item
Use @code{HEAP} tables to get more speed when possible. @xref{Table
types}.
@item
-When using a normal Web server setup, images should be stored as
+When using a normal web server setup, images should be stored as
files. That is, store only a file reference in the database. The main
-reason for this is that a normal Web server is much better at caching
+reason for this is that a normal web server is much better at caching
files than database contents. So it it's much easier to get a fast
system if you are using files.
@item
@@ -25687,7 +26396,7 @@ Try to keep the names simple (use @code{name} instead of
@code{customer_name} in the customer table). To make your names portable
to other SQL servers you should keep them shorter than 18 characters.
@item
-If you need REALLY high speed, you should take a look at the low-level
+If you need really high speed, you should take a look at the low-level
interfaces for data storage that the different SQL servers support! For
example, by accessing the MySQL @code{MyISAM} directly, you could
get a speed increase of 2-5 times compared to using the SQL interface.
@@ -25697,7 +26406,7 @@ the application, and usually it should only be accessed by one process
above problems by introducing low-level @code{MyISAM} commands in the
MySQL server (this could be one easy way to get more
performance if needed). By carefully designing the database interface,
-it should be quite easy to support this types of optimization.
+it should be quite easy to support this types of optimisation.
@item
In many cases it's faster to access data from a database (using a live
connection) than accessing a text file, just because the database is
@@ -25717,7 +26426,7 @@ from the data, you should not lose anything by using @code{DELAY_KEY_WRITE}.
@end itemize
-@node Locking Issues, Optimizing Database Structure, Query Speed, MySQL Optimization
+@node Locking Issues, Optimising Database Structure, Query Speed, MySQL Optimisation
@section Locking Issues
@@ -25737,10 +26446,17 @@ from the data, you should not lose anything by using @code{DELAY_KEY_WRITE}.
You can find a discussion about different locking methods in the appendix.
@xref{Locking methods}.
-All locking in MySQL is deadlock-free. This is managed by always
+All locking in MySQL is deadlock-free, except for @code{InnoDB} and
+@code{BDB} type tables.
+This is managed by always
requesting all needed locks at once at the beginning of a query and always
locking the tables in the same order.
+@code{InnoDB} type tables automatically acquire their row locks and
+@code{BDB} type tables
+their page locks during the processing of SQL statements, not at the start
+of the transaction.
+
The locking method MySQL uses for @code{WRITE} locks works as follows:
@itemize @bullet
@@ -25773,14 +26489,14 @@ once in a while.
This can be done with the following code:
@example
mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
-mysql> insert into real_table select * from insert_table;
+mysql> INSERT INTO real_table SELECT * FROM insert_table;
mysql> TRUNCATE TABLE insert_table;
mysql> UNLOCK TABLES;
@end example
You can use the @code{LOW_PRIORITY} options with @code{INSERT},
@code{UPDATE} or @code{DELETE} or @code{HIGH_PRIORITY} with
-@code{SELECT} if you want to prioritize retrieval in some specific
+@code{SELECT} if you want to prioritise retrieval in some specific
cases. You can also start @code{mysqld} with @code{--low-priority-updates}
to get the same behaveour.
@@ -25800,16 +26516,18 @@ priority, which might help some applications.
The table locking code in MySQL is deadlock free.
MySQL uses table locking (instead of row locking or column
-locking) on all table types, except @code{BDB} tables, to achieve a very
-high lock speed. For large tables, table locking is MUCH better than
+locking) on all table types, except @code{InnoDB} and @code{BDB} tables,
+to achieve a very
+high lock speed. For large tables, table locking is much better than
row locking for most applications, but there are, of course, some
pitfalls.
-For @code{BDB} and @code{InnoDB} tables, MySQL only uses table
-locking if you explicitely lock the table with @code{LOCK TABLES} or
-execute a command that will modify every row in the table, like
-@code{ALTER TABLE}. For these table types we recommend you to not use
-@code{LOCK TABLES} at all.
+For @code{InnoDB} and @code{BDB} tables, MySQL only uses table
+locking if you explicitly lock the table with @code{LOCK TABLES}.
+For these table types we recommend you to not use
+@code{LOCK TABLES} at all, because @code{InnoDB} uses automatic
+row level locking and @code{BDB} uses page level locking to
+ensure transaction isolation.
In MySQL Version 3.23.7 and above, you can insert rows into
@code{MyISAM} tables at the same time other threads are reading from the
@@ -25878,8 +26596,8 @@ Start @code{mysqld} with a low value for @strong{max_write_lock_count} to give
@item
You can specify that all updates from a specific thread should be done with
-low priority by using the SQL command: @code{SET SQL_LOW_PRIORITY_UPDATES=1}.
-@xref{SET OPTION, , @code{SET OPTION}}.
+low priority by using the SQL command: @code{SET LOW_PRIORITY_UPDATES=1}.
+@xref{SET OPTION, , @code{SET}}.
@item
You can specify that a specific @code{SELECT} is very important with the
@@ -25901,8 +26619,8 @@ option to @code{DELETE} may help. @xref{DELETE, , @code{DELETE}}.
@end itemize
-@node Optimizing Database Structure, Optimizing the Server, Locking Issues, MySQL Optimization
-@section Optimizing Database Structure
+@node Optimising Database Structure, Optimising the Server, Locking Issues, MySQL Optimisation
+@section Optimising Database Structure
@menu
@@ -25911,13 +26629,13 @@ option to @code{DELETE} may help. @xref{DELETE, , @code{DELETE}}.
* MySQL indexes:: How MySQL Uses Indexes
* Indexes:: Column Indexes
* Multiple-column indexes:: Multiple-Column Indexes
+* Open tables:: Why So Many Open tables?
* Table cache:: How MySQL Opens and Closes Tables
* Creating many tables:: Drawbacks to Creating Large Numbers of Tables in the Same Database
-* Open tables:: Why So Many Open tables?
@end menu
-@node Design, Data size, Optimizing Database Structure, Optimizing Database Structure
+@node Design, Data size, Optimising Database Structure, Optimising Database Structure
@subsection Design Choices
@cindex design, choices
@@ -25953,20 +26671,20 @@ You lose a lot of space, as you must duplicate indexes from the nodes
Deletes will degenerate the table over time (as indexes in nodes are
usually not updated on delete).
@item
-It's harder to cache ONLY the index data.
+It's harder to cache only the index data.
@end itemize
-@node Data size, MySQL indexes, Design, Optimizing Database Structure
+@node Data size, MySQL indexes, Design, Optimising Database Structure
@subsection Get Your Data as Small as Possible
@cindex data, size
@cindex reducing, data size
-@cindex storage space, minimizing
+@cindex storage space, minimising
@cindex tables, improving performance
@cindex performance, improving
-One of the most basic optimization is to get your data (and indexes) to
+One of the most basic optimisation is to get your data (and indexes) to
take as little space on the disk (and in memory) as possible. This can
give huge improvements because disk reads are faster and normally less
main memory will be used. Indexing also takes less resources if
@@ -25976,13 +26694,13 @@ MySQL supports a lot of different table types and row formats.
Choosing the right table format may give you a big performance gain.
@xref{Table types}.
-You can get better performance on a table and minimize storage space
-using the techniques listed below:
+You can get better performance on a table and minimise storage space
+using the techniques listed here:
@itemize @bullet
@item
Use the most efficient (smallest) types possible. MySQL has
-many specialized types that save disk space and memory.
+many specialised types that save disk space and memory.
@item
Use the smaller integer types if possible to get smaller tables. For
@@ -26013,7 +26731,7 @@ Only create the indexes that you really need. Indexes are good for
retrieval but bad when you need to store things fast. If you mostly
access a table by searching on a combination of columns, make an index
on them. The first index part should be the most used column. If you are
-ALWAYS using many columns, you should use the column with more duplicates
+@strong{always} using many columns, you should use the column with more duplicates
first to get better compression of the index.
@item
@@ -26032,7 +26750,7 @@ can be used to find the relevant rows when scanning the table.
@end itemize
-@node MySQL indexes, Indexes, Data size, Optimizing Database Structure
+@node MySQL indexes, Indexes, Data size, Optimising Database Structure
@subsection How MySQL Uses Indexes
@cindex indexes, use of
@@ -26042,7 +26760,7 @@ fast. Without an index MySQL has to start with the first record
and then read through the whole table until it finds the relevant
rows. The bigger the table, the more this costs. If the table has an index
for the columns in question, MySQL can quickly get a position to
-seek to in the middle of the data file without having to look at all the
+seek to in the middle of the datafile without having to look at all the
data. If a table has 1000 rows, this is at least 100 times faster than
reading sequentially. Note that if you need to access almost all 1000
rows it is faster to read sequentially because we then avoid disk seeks.
@@ -26061,7 +26779,7 @@ Retrieve rows from other tables when performing joins.
@item
Find the @code{MAX()} or @code{MIN()} value for a specific indexed
-column. This is optimized by a preprocessor that checks if you are
+column. This is optimised by a preprocessor that checks if you are
using @code{WHERE} key_part_# = constant on all key parts < N. In this case
MySQL will do a single key lookup and replace the @code{MIN()}
expression with a constant. If all expressions are replaced with
@@ -26073,23 +26791,13 @@ SELECT MIN(key_part2),MAX(key_part2) FROM table_name where key_part1=10
@item
Sort or group a table if the sorting or grouping is done on a leftmost
-prefix of a usable key (for example, @code{ORDER BY key_part_1,key_part_2 }). The
-key is read in reverse order if all key parts are followed by @code{DESC}.
-
-The index can also be used even if the @code{ORDER BY} doesn't match the index
-exactly, as long as all the unused index parts and all the extra
-are @code{ORDER BY} columns are constants in the @code{WHERE} clause. The
-following queries will use the index to resolve the @code{ORDER BY} part:
-
-@example
-SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3;
-SELECT * FROM foo WHERE column=constant ORDER BY column, key_part1;
-SELECT * FROM foo WHERE key_part1=const GROUP BY key_part2;
-@end example
+prefix of a usable key (for example, @code{ORDER BY
+key_part_1,key_part_2 }). The key is read in reverse order if all key
+parts are followed by @code{DESC}. @xref{ORDER BY optimisation}.
@item
-In some cases a query can be optimized to retrieve values without
-consulting the data file. If all used columns for some table are numeric
+In some cases a query can be optimised to retrieve values without
+consulting the datafile. If all used columns for some table are numeric
and form a leftmost prefix for some key, the values may be retrieved
from the index tree for greater speed:
@@ -26107,21 +26815,21 @@ mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
If a multiple-column index exists on @code{col1} and @code{col2}, the
appropriate rows can be fetched directly. If separate single-column
-indexes exist on @code{col1} and @code{col2}, the optimizer tries to
+indexes exist on @code{col1} and @code{col2}, the optimiser tries to
find the most restrictive index by deciding which index will find fewer
rows and using that index to fetch the rows.
@cindex indexes, leftmost prefix of
@cindex leftmost prefix of indexes
If the table has a multiple-column index, any leftmost prefix of the
-index can be used by the optimizer to find rows. For example, if you
+index can be used by the optimiser to find rows. For example, if you
have a three-column index on @code{(col1,col2,col3)}, you have indexed
search capabilities on @code{(col1)}, @code{(col1,col2)}, and
@code{(col1,col2,col3)}.
MySQL can't use a partial index if the columns don't form a
leftmost prefix of the index. Suppose you have the @code{SELECT}
-statements shown below:
+statements shown here:
@example
mysql> SELECT * FROM tbl_name WHERE col1=val1;
@@ -26139,12 +26847,12 @@ leftmost prefixes of @code{(col1,col2,col3)}.
@cindex indexes, and @code{LIKE}
@cindex wildcards, and @code{LIKE}
MySQL also uses indexes for @code{LIKE} comparisons if the argument
-to @code{LIKE} is a constant string that doesn't start with a wild-card
+to @code{LIKE} is a constant string that doesn't start with a wildcard
character. For example, the following @code{SELECT} statements use indexes:
@example
-mysql> select * from tbl_name where key_col LIKE "Patrick%";
-mysql> select * from tbl_name where key_col LIKE "Pat%_ck%";
+mysql> SELECT * FROM tbl_name WHERE key_col LIKE "Patrick%";
+mysql> SELECT * FROM tbl_name WHERE key_col LIKE "Pat%_ck%";
@end example
In the first statement, only rows with @code{"Patrick" <= key_col <
@@ -26153,14 +26861,20 @@ In the first statement, only rows with @code{"Patrick" <= key_col <
The following @code{SELECT} statements will not use indexes:
@example
-mysql> select * from tbl_name where key_col LIKE "%Patrick%";
-mysql> select * from tbl_name where key_col LIKE other_col;
+mysql> SELECT * FROM tbl_name WHERE key_col LIKE "%Patrick%";
+mysql> SELECT * FROM tbl_name WHERE key_col LIKE other_col;
@end example
-In the first statement, the @code{LIKE} value begins with a wild-card
+In the first statement, the @code{LIKE} value begins with a wildcard
character. In the second statement, the @code{LIKE} value is not a
constant.
+MySQL 4.0 does another optimization on @code{LIKE}. If you use
+@code{... LIKE "%string%"} and @code{string} is longer than 3 characters,
+MySQL will use the @code{Turbo Boyer-Moore} algorithm to initialise the
+pattern for the string and then use this pattern to perform the search
+quicker.
+
@findex IS NULL, and indexes
@cindex indexes, and @code{IS NULL}
Searching using @code{column_name IS NULL} will use indexes if column_name
@@ -26169,10 +26883,10 @@ is an index.
MySQL normally uses the index that finds the least number of rows. An
index is used for columns that you compare with the following operators:
@code{=}, @code{>}, @code{>=}, @code{<}, @code{<=}, @code{BETWEEN}, and a
-@code{LIKE} with a non-wild-card prefix like @code{'something%'}.
+@code{LIKE} with a non-wildcard prefix like @code{'something%'}.
Any index that doesn't span all @code{AND} levels in the @code{WHERE} clause
-is not used to optimize the query. In other words: To be able to use an
+is not used to optimise the query. In other words: To be able to use an
index, a prefix of the index must be used in every @code{AND} group.
The following @code{WHERE} clauses use indexes:
@@ -26180,7 +26894,7 @@ The following @code{WHERE} clauses use indexes:
... WHERE index_part1=1 AND index_part2=2 AND other_column=3
... WHERE index=1 OR A=10 AND index=2 /* index = 1 OR index = 2 */
... WHERE index_part1='hello' AND index_part_3=5
- /* optimized like "index_part1='hello'" */
+ /* optimised like "index_part1='hello'" */
... WHERE index1=1 and index2=2 or index1=3 and index3=3;
/* Can use index on index1 but not on index2 or index 3 */
@end example
@@ -26188,8 +26902,9 @@ The following @code{WHERE} clauses use indexes:
These @code{WHERE} clauses do @strong{NOT} use indexes:
@example
... WHERE index_part2=1 AND index_part3=2 /* index_part_1 is not used */
-... WHERE index=1 OR A=10 /* Index is not used in both AND parts */
-... WHERE index_part1=1 OR index_part2=10 /* No index spans all rows */
+... WHERE index=1 OR A=10 /* Index is not used in
+ both AND parts */
+... WHERE index_part1=1 OR index_part2=10 /* No index spans all rows */
@end example
Note that in some cases MySQL will not use an index, even if one
@@ -26198,24 +26913,17 @@ would be available. Some of the cases where this happens are:
@itemize @bullet
@item
If the use of the index would require MySQL to access more
-than 30 % of the rows in the table. (In this case a table scan is
-probably much faster, as this will require us to do much fewer seeks).
+than 30% of the rows in the table. (In this case a table scan is
+probably much faster, as this will require us to do much fewer seeks.)
Note that if such a query uses @code{LIMIT} to only retrieve
part of the rows, MySQL will use an index anyway, as it can
much more quickly find the few rows to return in the result.
+@item
+If the index range may contain @code{NULL} values and you are using
+@code{ORDER BY ... DESC}
@end itemize
-
-@menu
-* Indexes:: Column Indexes
-* Multiple-column indexes:: Multiple-Column Indexes
-* Table cache:: How MySQL Opens and Closes Tables
-* Creating many tables:: Drawbacks to Creating Large Numbers of Tables in the Same Database
-* Open tables:: Why So Many Open tables?
-@end menu
-
-
-@node Indexes, Multiple-column indexes, MySQL indexes, Optimizing Database Structure
+@node Indexes, Multiple-column indexes, MySQL indexes, Optimising Database Structure
@subsection Column Indexes
@cindex indexes, columns
@@ -26239,13 +26947,13 @@ index a column prefix looks like this:
KEY index_name (col_name(length))
@end example
-The example below creates an index for the first 10 characters of the
+The example here creates an index for the first 10 characters of the
@code{name} column:
@example
mysql> CREATE TABLE test (
- name CHAR(200) NOT NULL,
- KEY index_name (name(10)));
+ -> name CHAR(200) NOT NULL,
+ -> KEY index_name (name(10)));
@end example
For @code{BLOB} and @code{TEXT} columns, you must index a prefix of the
@@ -26258,7 +26966,7 @@ created only from @code{VARCHAR} and @code{TEXT} columns.
Indexing always happens over the entire column and partial indexing is not
supported. See @ref{Fulltext Search} for details.
-@node Multiple-column indexes, Table cache, Indexes, Optimizing Database Structure
+@node Multiple-column indexes, Open tables, Indexes, Optimising Database Structure
@subsection Multiple-Column Indexes
@cindex multi-column indexes
@@ -26267,7 +26975,7 @@ supported. See @ref{Fulltext Search} for details.
MySQL can create indexes on multiple columns. An index may
consist of up to 15 columns. (On @code{CHAR} and @code{VARCHAR} columns you
-can also use a prefix of the column as a part of an index).
+can also use a prefix of the column as a part of an index.)
A multiple-column index can be considered a sorted array containing values
that are created by concatenating the values of the indexed columns.
@@ -26280,11 +26988,11 @@ Suppose a table is created using the following specification:
@example
mysql> CREATE TABLE test (
- id INT NOT NULL,
- last_name CHAR(30) NOT NULL,
- first_name CHAR(30) NOT NULL,
- PRIMARY KEY (id),
- INDEX name (last_name,first_name));
+ -> id INT NOT NULL,
+ -> last_name CHAR(30) NOT NULL,
+ -> first_name CHAR(30) NOT NULL,
+ -> PRIMARY KEY (id),
+ -> INDEX name (last_name,first_name));
@end example
Then the index @code{name} is an index over @code{last_name} and
@@ -26297,13 +27005,13 @@ Therefore, the @code{name} index will be used in the following queries:
mysql> SELECT * FROM test WHERE last_name="Widenius";
mysql> SELECT * FROM test WHERE last_name="Widenius"
- AND first_name="Michael";
+ -> AND first_name="Michael";
mysql> SELECT * FROM test WHERE last_name="Widenius"
- AND (first_name="Michael" OR first_name="Monty");
+ -> AND (first_name="Michael" OR first_name="Monty");
mysql> SELECT * FROM test WHERE last_name="Widenius"
- AND first_name >="M" AND first_name < "N";
+ -> AND first_name >="M" AND first_name < "N";
@end example
However, the @code{name} index will NOT be used in the following queries:
@@ -26312,15 +27020,38 @@ However, the @code{name} index will NOT be used in the following queries:
mysql> SELECT * FROM test WHERE first_name="Michael";
mysql> SELECT * FROM test WHERE last_name="Widenius"
- OR first_name="Michael";
+ -> OR first_name="Michael";
@end example
For more information on the manner in which MySQL uses indexes to
improve query performance, see @ref{MySQL indexes, , MySQL
indexes}.
+@node Open tables, Table cache, Multiple-column indexes, Optimising Database Structure
+@subsection Why So Many Open tables?
+
+@cindex tables, open
+@cindex open tables
+
+When you run @code{mysqladmin status}, you'll see something like this:
+
+@example
+Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
+@end example
+
+This can be somewhat perplexing if you only have 6 tables.
+
+MySQL is multi-threaded, so it may have many queries on the same table
+simultaneously. To minimise the problem with two threads having
+different states on the same file, the table is opened independently by
+each concurrent thread. This takes some memory but will normaly increase
+performance. Wth ISAM and MyISAM tables this also requires one extra file
+descriptor for the datafile. With these table types the index file
+descriptor is shared between all threads.
+
+You can read more about this topic in the next section. @xref{Table cache}.
-@node Table cache, Creating many tables, Multiple-column indexes, Optimizing Database Structure
+@node Table cache, Creating many tables, Open tables, Optimising Database Structure
@subsection How MySQL Opens and Closes Tables
@findex table_cache
@@ -26345,11 +27076,37 @@ at least @code{200 * n}, where @code{n} is the maximum number of tables
in a join. You also need to reserve some extra file descriptors for
temporary tables and files.
-The cache of open tables can grow to a maximum of @code{table_cache}
-(default 64; this can be changed with the @code{-O table_cache=#}
-option to @code{mysqld}). A table is never closed, except when the
-cache is full and another thread tries to open a table or if you use
-@code{mysqladmin refresh} or @code{mysqladmin flush-tables}.
+Make sure that your operating system can handle the number of open file
+descriptors implied by the @code{table_cache} setting. If
+@code{table_cache} is set too high, MySQL may run out of file
+descriptors and refuse connections, fail to perform queries, and be very
+unreliable. You also have to take into account that the MyISAM table
+handler needs two file descriptors for each unique open table. You can
+in increase the number of file descriptors available for MySQL with
+the @code{--open-files-limit=#} startup option. @xref{Not enough file
+handles}.
+
+The cache of open tables will be keept at a level of @code{table_cache}
+entries (default 64; this can be changed with the @code{-O
+table_cache=#} option to @code{mysqld}). Note that in MySQL may
+temporarly open even more tables to be able to execute queries.
+
+A not used table is closed and removed from the table cache under the
+following circumstances:
+
+@itemize @bullet
+@item
+When the cache is full and a thread tries to open a table that is not in
+the cache.
+@item
+When the cache contains more than @code{table_cache} entries and
+a thread is no longer using a table.
+@item
+When someone executes @code{mysqladmin refresh} or
+@code{mysqladmin flush-tables}.
+@item
+When someone executes 'FLUSH TABLES'
+@end itemize
When the table cache fills up, the server uses the following procedure
to locate a cache entry to use:
@@ -26376,13 +27133,20 @@ use of the table takes only one file descriptor. The extra descriptor
for the first open is used for the index file; this descriptor is shared
among all threads.
+If you are opening a table with the @code{HANDLER table_name OPEN}
+statement, a dedicated table object is allocated for the thread.
+This table object is not shared by other threads an will not be closed
+until the thread calls @code{HANDLER table_name CLOSE} or the thread dies.
+@xref{HANDLER, , @code{HANDLER}}. When this happens, the table is put
+back in the table_cache (if it isn't full).
+
You can check if your table cache is too small by checking the mysqld
-variable @code{opened_tables}. If this is quite big, even if you
+variable @code{Opened_tables}. If this is quite big, even if you
haven't done a lot of @code{FLUSH TABLES}, you should increase your table
-cache. @xref{SHOW STATUS}.
+cache. @xref{SHOW STATUS, , @code{SHOW STATUS}}.
-@node Creating many tables, Open tables, Table cache, Optimizing Database Structure
+@node Creating many tables, , Table cache, Optimising Database Structure
@subsection Drawbacks to Creating Large Numbers of Tables in the Same Database
@cindex tables, too many
@@ -26394,30 +27158,8 @@ every table that has to be opened, another must be closed. You can reduce
this overhead by making the table cache larger.
-@node Open tables, , Creating many tables, Optimizing Database Structure
-@subsection Why So Many Open tables?
-
-@cindex tables, open
-@cindex open tables
-
-When you run @code{mysqladmin status}, you'll see something like this:
-
-@example
-Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
-@end example
-
-This can be somewhat perplexing if you only have 6 tables.
-
-MySQL is multithreaded, so it may have many queries on the same
-table simultaneously. To minimize the problem with two threads having
-different states on the same file, the table is opened independently by
-each concurrent thread. This takes some memory and one extra file
-descriptor for the data file. The index file descriptor is shared
-between all threads.
-
-
-@node Optimizing the Server, Disk issues, Optimizing Database Structure, MySQL Optimization
-@section Optimizing the MySQL Server
+@node Optimising the Server, Disk issues, Optimising Database Structure, MySQL Optimisation
+@section Optimising the MySQL Server
@menu
@@ -26430,11 +27172,11 @@ between all threads.
@end menu
-@node System, Server parameters, Optimizing the Server, Optimizing the Server
+@node System, Server parameters, Optimising the Server, Optimising the Server
@subsection System/Compile Time and Startup Parameter Tuning
-@cindex compiling, optimizing
-@cindex system optimization
+@cindex compiling, optimising
+@cindex system optimisation
@cindex startup parameters, tuning
We start with the system level things since some of these decisions have
@@ -26444,13 +27186,13 @@ nice to have a feeling about how much one could gain by changing things
at this level.
The default OS to use is really important! To get the most use of
-multiple CPU machines one should use Solaris (because the threads works
+multiple-CPU machines one should use Solaris (because the threads works
really nice) or Linux (because the 2.2 kernel has really good SMP
-support). Also on 32-bit machines Linux has a 2G file size limit by
+support). Also on 32-bit machines Linux has a 2G file-size limit by
default. Hopefully this will be fixed soon when new filesystems are
released (XFS/Reiserfs). If you have a desperate need for files bigger
than 2G on Linux-intel 32 bit, you should get the LFS patch for the ext2
-file system.
+filesystem.
Because we have not run MySQL in production on that many platforms, we
advice you to test your intended platform before choosing it, if possible.
@@ -26463,29 +27205,29 @@ If you have enough RAM, you could remove all swap devices. Some
operating systems will use a swap device in some contexts even if you
have free memory.
@item
-Use the @code{--skip-locking} MySQL option to avoid external
+Use the @code{--skip-external-locking} MySQL option to avoid external
locking. Note that this will not impact MySQL's functionality as
long as you only run one server. Just remember to take down the server (or
lock relevant parts) before you run @code{myisamchk}. On some system
this switch is mandatory because the external locking does not work in any
case.
-The @code{--skip-locking} option is on by default when compiling with
+The @code{--skip-external-locking} option is on by default when compiling with
MIT-pthreads, because @code{flock()} isn't fully supported by
MIT-pthreads on all platforms. It's also on default for Linux
as Linux file locking are not yet safe.
-The only case when you can't use @code{--skip-locking} is if you run
+The only case when you can't use @code{--skip-external-locking} is if you run
multiple MySQL @emph{servers} (not clients) on the same data,
or run @code{myisamchk} on the table without first flushing and locking
the @code{mysqld} server tables first.
You can still use @code{LOCK TABLES}/@code{UNLOCK TABLES} even if you
-are using @code{--skip-locking}
+are using @code{--skip-external-locking}
@end itemize
-@node Server parameters, Compile and link options, System, Optimizing the Server
+@node Server parameters, Compile and link options, System, Optimising the Server
@subsection Tuning Server Parameters
@cindex parameters, server
@@ -26508,44 +27250,43 @@ like this:
@example
Possible variables for option --set-variable (-O) are:
-back_log current value: 5
-bdb_cache_size current value: 1048540
-binlog_cache_size current_value: 32768
-connect_timeout current value: 5
-delayed_insert_timeout current value: 300
-delayed_insert_limit current value: 100
-delayed_queue_size current value: 1000
-flush_time current value: 0
-interactive_timeout current value: 28800
-join_buffer_size current value: 131072
-key_buffer_size current value: 1048540
-lower_case_table_names current value: 0
-long_query_time current value: 10
-max_allowed_packet current value: 1048576
-max_binlog_cache_size current_value: 4294967295
-max_connections current value: 100
-max_connect_errors current value: 10
-max_delayed_threads current value: 20
-max_heap_table_size current value: 16777216
-max_join_size current value: 4294967295
-max_sort_length current value: 1024
-max_tmp_tables current value: 32
-max_write_lock_count current value: 4294967295
+back_log current value: 5
+bdb_cache_size current value: 1048540
+binlog_cache_size current value: 32768
+connect_timeout current value: 5
+delayed_insert_timeout current value: 300
+delayed_insert_limit current value: 100
+delayed_queue_size current value: 1000
+flush_time current value: 0
+interactive_timeout current value: 28800
+join_buffer_size current value: 131072
+key_buffer_size current value: 1048540
+lower_case_table_names current value: 0
+long_query_time current value: 10
+max_allowed_packet current value: 1048576
+max_binlog_cache_size current value: 4294967295
+max_connections current value: 100
+max_connect_errors current value: 10
+max_delayed_threads current value: 20
+max_heap_table_size current value: 16777216
+max_join_size current value: 4294967295
+max_sort_length current value: 1024
+max_tmp_tables current value: 32
+max_write_lock_count current value: 4294967295
myisam_sort_buffer_size current value: 8388608
-net_buffer_length current value: 16384
-net_retry_count current value: 10
-net_read_timeout current value: 30
-net_write_timeout current value: 60
-query_buffer_size current value: 0
-record_buffer current value: 131072
-record_rnd_buffer current value: 131072
-slow_launch_time current value: 2
-sort_buffer current value: 2097116
-table_cache current value: 64
-thread_concurrency current value: 10
-tmp_table_size current value: 1048576
-thread_stack current value: 131072
-wait_timeout current value: 28800
+net_buffer_length current value: 16384
+net_retry_count current value: 10
+net_read_timeout current value: 30
+net_write_timeout current value: 60
+read_buffer_size current value: 131072
+record_rnd_buffer_size current value: 131072
+slow_launch_time current value: 2
+sort_buffer current value: 2097116
+table_cache current value: 64
+thread_concurrency current value: 10
+tmp_table_size current value: 1048576
+thread_stack current value: 131072
+wait_timeout current value: 28800
@end example
If there is a @code{mysqld} server currently running, you can see what
@@ -26575,7 +27316,7 @@ with a moderate number of clients, you should use something like this:
@example
shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \
- -O sort_buffer=4M -O record_buffer=1M &
+ -O sort_buffer=4M -O read_buffer_size=1M &
@end example
If you have only 128M and only a few tables, but you still do a lot of
@@ -26589,14 +27330,14 @@ If you have little memory and lots of connections, use something like this:
@example
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \
- -O record_buffer=100k &
+ -O read_buffer_size=100k &
@end example
or even:
@example
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \
- -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &
+ -O table_cache=32 -O read_buffer_size=8k -O net_buffer_length=1K &
@end example
If you are doing a @code{GROUP BY} or @code{ORDER BY} on files that are
@@ -26605,9 +27346,9 @@ much bigger than your available memory you should increase the value of
is done.
When you have installed MySQL, the @file{support-files} directory will
-contain some different @code{my.cnf} example files, @file{my-huge.cnf},
+contain some different @file{my.cnf} example files, @file{my-huge.cnf},
@file{my-large.cnf}, @file{my-medium.cnf}, and @file{my-small.cnf}, you can
-use as a base to optimize your system.
+use as a base to optimise your system.
If there are very many connections, ``swapping problems'' may occur unless
@code{mysqld} has been configured to use very little memory for each
@@ -26624,11 +27365,11 @@ shell> mysqld -O key_buffer=32m --help
@end example
Make sure that the @code{--help} option is last; otherwise, the effect of any
-options listed after it on the command line will not be reflected in the
+options listed after it on the command-line will not be reflected in the
output.
-@node Compile and link options, Memory use, Server parameters, Optimizing the Server
+@node Compile and link options, Memory use, Server parameters, Optimising the Server
@subsection How Compiling and Linking Affects the Speed of MySQL
@cindex linking, speed
@@ -26653,15 +27394,15 @@ use the compiler option that you want the resulting code to be working on
all x586 type processors (like AMD).
By just using a better compiler and/or better compiler options you can
-get a 10-30 % speed increase in your application. This is particularly
+get a 10-30% speed increase in your application. This is particularly
important if you compile the SQL server yourself!
We have tested both the Cygnus CodeFusion and Fujitsu compilers, but
when we tested them, neither was sufficiently bug free to allow
-MySQL to be compiled with optimizations on.
+MySQL to be compiled with optimisations on.
When you compile MySQL you should only include support for the
-character sets that you are going to use. (Option @code{--with-charset=xxx}).
+character sets that you are going to use. (Option @code{--with-charset=xxx}.)
The standard MySQL binary distributions are compiled with support
for all character sets.
@@ -26679,32 +27420,36 @@ performance.
@item
If you strip your @code{mysqld} binary with @code{strip libexec/mysqld},
-the resulting binary can be up to 4 % faster.
+the resulting binary can be up to 4% faster.
@item
If you connect using TCP/IP rather than Unix sockets, the result is 7.5%
slower on the same computer. (If you are connection to @code{localhost},
-MySQL will, by default, use sockets).
+MySQL will, by default, use sockets.)
@item
If you connect using TCP/IP from another computer over a 100M Ethernet,
-things will be 8-11 % slower.
+things will be 8-11% slower.
@item
-If you compile with @code{--with-debug=full}, then you will loose 20 %
+When running our benchmark tests using secure connections (all data
+encrypted with internal SSL support) things were 55% slower.
+
+@item
+If you compile with @code{--with-debug=full}, then you will lose 20%
for most queries, but some queries may take substantially longer (The
-MySQL benchmarks ran 35 % slower)
-If you use @code{--with-debug}, then you will only loose 15 %.
+MySQL benchmarks ran 35% slower)
+If you use @code{--with-debug}, then you will only lose 15%.
By starting a @code{mysqld} version compiled with @code{--with-debug=full}
with @code{--skip-safemalloc} the end result should be close to when
configuring with @code{--with-debug}.
@item
-On a Sun SPARCstation 20, SunPro C++ 4.2 is 5 % faster than @code{gcc} 2.95.2.
+On a Sun SPARCstation 20, SunPro C++ 4.2 is 5% faster than @code{gcc} 2.95.2.
@item
-Compiling with @code{gcc} 2.95.2 for ultrasparc with the option
-@code{-mcpu=v8 -Wa,-xarch=v8plusa} gives 4 % more performance.
+Compiling with @code{gcc} 2.95.2 for UltraSPARC with the option
+@code{-mcpu=v8 -Wa,-xarch=v8plusa} gives 4% more performance.
@item
On Solaris 2.5.1, MIT-pthreads is 8-12% slower than Solaris native
@@ -26712,12 +27457,12 @@ threads on a single processor. With more load/CPUs the difference should
get bigger.
@item
-Running with @code{--log-bin} makes @strong{[MySQL} 1 % slower.
+Running with @code{--log-bin} makes @strong{[MySQL} 1% slower.
@item
Compiling on Linux-x86 using gcc without frame pointers
@code{-fomit-frame-pointer} or @code{-fomit-frame-pointer -ffixed-ebp}
-@code{mysqld} 1-4% faster.
+makes @code{mysqld} 1-4% faster.
@end itemize
The MySQL-Linux distribution provided by MySQL AB used
@@ -26729,19 +27474,19 @@ binary by compiling with @code{pgcc}. The standard MySQL
Linux binary is linked statically to get it faster and more portable.
-@node Memory use, DNS, Compile and link options, Optimizing the Server
+@node Memory use, DNS, Compile and link options, Optimising the Server
@subsection How MySQL Uses Memory
@cindex memory use
-The list below indicates some of the ways that the @code{mysqld} server
+The following list indicates some of the ways that the @code{mysqld} server
uses memory. Where applicable, the name of the server variable relevant
to the memory use is given:
@itemize @bullet
@item
The key buffer (variable @code{key_buffer_size}) is shared by all
-threads; Other buffers used by the server are allocated as
+threads; other buffers used by the server are allocated as
needed. @xref{Server parameters}.
@item
@@ -26784,8 +27529,8 @@ automatically changing the in-memory (HEAP) table to a disk-based
(MyISAM) table as necessary. To work around this problem, you can
increase the temporary table size by setting the @code{tmp_table_size}
option to @code{mysqld}, or by setting the SQL option
-@code{SQL_BIG_TABLES} in the client program. @xref{SET OPTION, ,
-@code{SET OPTION}}. In MySQL Version 3.20, the maximum size of the
+@code{BIG_TABLES} in the client program. @xref{SET OPTION, ,
+@code{SET}}. In MySQL Version 3.20, the maximum size of the
temporary table was @code{record_buffer*16}, so if you are using this
version, you have to increase the value of @code{record_buffer}. You can
also start @code{mysqld} with the @code{--big-tables} option to always
@@ -26804,7 +27549,7 @@ unexpectedly large strings (this is done with @code{malloc()} and
@code{free()}).
@item
-Each index file is opened once and the data file is opened once for each
+Each index file is opened once and the datafile is opened once for each
concurrently running thread. For each concurrent thread, a table structure,
column structures for each column, and a buffer of size @code{3 * n} is
allocated (where @code{n} is the maximum row length, not counting @code{BLOB}
@@ -26838,7 +27583,7 @@ checking available swap with @code{swap -s}. We have tested
be no memory leaks.
-@node DNS, SET OPTION, Memory use, Optimizing the Server
+@node DNS, SET OPTION, Memory use, Optimising the Server
@subsection How MySQL uses DNS
@cindex DNS
@@ -26873,18 +27618,92 @@ If you don't want to allow connections over @code{TCP/IP}, you can do this
by starting @code{mysqld} with @code{--skip-networking}.
-@node SET OPTION, , DNS, Optimizing the Server
+@node SET OPTION, , DNS, Optimising the Server
@subsection @code{SET} Syntax
@findex SET OPTION
@example
-SET [OPTION] SQL_VALUE_OPTION= value, ...
+SET [GLOBAL | SESSION] sql_variable=expression, [[GLOBAL | SESSION] sql_variable=expression...]
+@end example
+
+@code{SET} sets various options that affect the operation of the
+server or your client.
+
+The following examples shows the different syntaxes one can use to set
+variables:
+
+In old MySQL versions we allowed the use of the @code{SET OPTION} syntax,
+but this syntax is now deprecated.
+
+In MySQL 4.0.3 we added the @code{GLOBAL} and @code{SESSION} options
+and access to most important startup variables.
+
+@code{LOCAL} can be used as a synonym for @code{SESSION}.
+
+If you set several variables on the same command line, the last used
+@code{GLOBAL | SESSION} mode is used.
+
+@example
+SET sort_buffer_size=10000;
+SET @@@@local.sort_buffer_size=10000;
+SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000;
+SET @@@@sort_buffer_size=1000000;
+SET @@@@global.sort_buffer_size=1000000, @@@@local.sort_buffer_size=1000000;
+@end example
+
+The @code{@@@@variable_name} syntax is supported to make MySQL syntax
+compatible with some other databases.
+
+The different system variables one can set are described in the system
+variable section of this manual. @xref{System Variables}.
+
+If you are using @code{SESSION} (the default) the option you set remains
+in effect until the current session ends, or until you set the option to
+a different value. If you use @code{GLOBAL}, which require the
+@code{SUPER} privilege, the option is remembered and used for new
+connections until the server restarts. If you want to make an option
+permanent, you should set it in one of the MySQL option
+files. @xref{Option files}.
+
+To avoid wrong usage MySQL will give an error if you use @code{SET
+GLOBAL} with a variable that can only be used with @code{SET SESSION} or if
+you are not using @code{SET GLOBAL} with a global variable.
+
+If you want to set a @code{SESSION} variable to the @code{GLOBAL} value or a
+@code{GLOBAL} value to the MySQL default value, you can set it to
+@code{DEFAULT}.
+
+@example
+SET max_join_size=DEFAULT;
+@end example
+
+This is idential to:
+
+@example
+SET @@@@session.max_join_size=@@@@global.max_join_size;
@end example
-@code{SET OPTION} sets various options that affect the operation of the
-server or your client. Any option you set remains in effect until the
-current session ends, or until you set the option to a different value.
+If you want to restrict the maximum value a startup option can be set to
+with the @code{SET} command, you can specify this by using the
+@code{--maximum-variable-name} command line option. @xref{Command-line
+options}.
+
+You can get a list of most variables with @code{SHOW VARIABLES}.
+@xref{SHOW VARIABLES}. You can get the value for a specific value with
+the @code{@@@@[global.|local.]variable_name} syntax:
+@example
+SHOW VARIABLES like "max_join_size";
+SHOW GLOBAL VARIABLES like "max_join_size";
+SELECT @@@@max_join_size, @@@@global.max_join_size;
+@end example
+
+Here follows a description of the variables that uses a the variables
+that uses a non-standard @code{SET} syntax and some of the other
+variables. The other variable definitions can be found in the system
+variable section, among the startup options or in the description of
+@code{SHOW VARIABLES}. @xref{System Variables}. @xref{Command-line
+options}. @xref{SHOW VARIABLES}.
@table @code
@item CHARACTER SET character_set_name | DEFAULT
@@ -26917,12 +27736,13 @@ mysql> SET PASSWORD FOR bob@@"%.loc.gov" = PASSWORD("newpass");
or
-mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' and host="%.loc.gov";
+mysql> UPDATE mysql.user SET password=PASSWORD("newpass")
+ -> WHERE user="bob' AND host="%.loc.gov";
@end example
@item SQL_AUTO_IS_NULL = 0 | 1
If set to @code{1} (default) then one can find the last inserted row
-for a table with an auto_increment row with the following construct:
+for a table with an @code{AUTO_INCREMENT} column with the following construct:
@code{WHERE auto_increment_column IS NULL}. This is used by some
ODBC programs like Access.
@@ -26935,13 +27755,14 @@ that when you change from not @code{AUTOCOMMIT} mode to
@code{AUTOCOMMIT} mode, MySQL will do an automatic
@code{COMMIT} on any open transactions.
-@item SQL_BIG_TABLES = 0 | 1
+@item BIG_TABLES = 0 | 1
@cindex table is full
If set to @code{1}, all temporary tables are stored on disk rather than in
memory. This will be a little slower, but you will not get the error
@code{The table tbl_name is full} for big @code{SELECT} operations that
require a large temporary table. The default value for a new connection is
@code{0} (that is, use in-memory temporary tables).
+This option was before named @code{SQL_BIG_TABLES}.
@item SQL_BIG_SELECTS = 0 | 1
If set to @code{0}, MySQL will abort if a @code{SELECT} is attempted
@@ -26952,17 +27773,18 @@ that probably will take a very long time. This is useful when an inadvisable
@code{1} (which will allow all @code{SELECT} statements).
@item SQL_BUFFER_RESULT = 0 | 1
-@code{SQL_BUFFER_RESULT} will force the result from @code{SELECT}'s
+@code{SQL_BUFFER_RESULT} will force the result from @code{SELECT}s
to be put into a temporary table. This will help MySQL free the
table locks early and will help in cases where it takes a long time to
send the result set to the client.
-@item SQL_LOW_PRIORITY_UPDATES = 0 | 1
+@item LOW_PRIORITY_UPDATES = 0 | 1
If set to @code{1}, all @code{INSERT}, @code{UPDATE}, @code{DELETE}, and
and @code{LOCK TABLE WRITE} statements wait until there is no pending
@code{SELECT} or @code{LOCK TABLE READ} on the affected table.
+This option was before named @code{SQL_LOW_PRIORITY_UPDATES}.
-@item SQL_MAX_JOIN_SIZE = value | DEFAULT
+@item MAX_JOIN_SIZE = value | DEFAULT
Don't allow @code{SELECT}s that will probably need to examine more than
@code{value} row combinations. By setting this value, you can catch
@code{SELECT}s where keys are not used properly and that would probably
@@ -26971,6 +27793,22 @@ the @code{SQL_BIG_SELECTS} flag. If you set the @code{SQL_BIG_SELECTS}
flag again, the @code{SQL_MAX_JOIN_SIZE} variable will be ignored.
You can set a default value for this variable by starting @code{mysqld} with
@code{-O max_join_size=#}.
+This option was before named @code{SQL_MAX_JOIN_SIZE}.
+
+Note that if the result of the query is already in the query cache, the
+above check will not be made. Instead, MySQL will send the result to the
+client. Since the query result is already computed and it will not burden
+the server to send the result to the client.
+
+@item QUERY_CACHE_TYPE = OFF | ON | DEMAND
+@item QUERY_CACHE_TYPE = 0 | 1 | 2
+Set query cache setting for this thread.
+@multitable @columnfractions .20 .70
+@item @strong{Option} @tab @strong{Description}
+@item 0 or OFF @tab Don't cache or retrieve results.
+@item 1 or ON @tab Cache all results except @code{SELECT SQL_NO_CACHE ...} queries.
+@item 2 or DEMAND @tab Cache only @code{SELECT SQL_CACHE ...} queries.
+@end multitable
@item SQL_SAFE_UPDATES = 0 | 1
If set to @code{1}, MySQL will abort if an @code{UPDATE} or
@@ -26987,12 +27825,12 @@ can be restored by using a @code{SQL_SELECT_LIMIT} value of @code{DEFAULT}.
@item SQL_LOG_OFF = 0 | 1
If set to @code{1}, no logging will be done to the standard log for this
-client, if the client has the @strong{process} privilege. This does not
+client, if the client has the @code{SUPER} privilege. This does not
affect the update log!
@item SQL_LOG_UPDATE = 0 | 1
If set to @code{0}, no logging will be done to the update log for the client,
-if the client has the @strong{process} privilege. This does not affect the
+if the client has the @code{SUPER} privilege. This does not affect the
standard log!
@item SQL_QUOTE_SHOW_CREATE = 0 | 1
@@ -27004,7 +27842,7 @@ for replication of tables with fancy column names to work.
@item TIMESTAMP = timestamp_value | DEFAULT
Set the time for this client. This is used to get the original timestamp if
you use the update log to restore rows. @code{timestamp_value} should be a
-UNIX Epoch timestamp, not a MySQL timestamp.
+Unix epoch timestamp, not a MySQL timestamp.
@item LAST_INSERT_ID = #
Set the value to be returned from @code{LAST_INSERT_ID()}. This is stored in
@@ -27017,15 +27855,7 @@ command when inserting an @code{AUTO_INCREMENT} value. This is mainly used
with the update log.
@end table
-
-@menu
-* SET TRANSACTION:: @code{SET TRANSACTION} Syntax
-@end menu
-
-
-
-
-@node Disk issues, , Optimizing the Server, MySQL Optimization
+@node Disk issues, , Optimising the Server, MySQL Optimisation
@section Disk Issues
@cindex disk issues
@@ -27038,7 +27868,7 @@ problems gets more and more apparent when the data starts to grow so
large that effective caching becomes impossible. For large databases,
where you access data more or less randomly, you can be sure that you
will need at least one disk seek to read and a couple of disk seeks to
-write things. To minimize this problem, use disks with low seek times.
+write things. To minimise this problem, use disks with low seek times.
@item
Increase the number of available disk spindles (and thereby reduce
@@ -27047,7 +27877,7 @@ the disks.
@table @strong
@item Using symbolic links
-This means that you symlink the index and/or data file(s) from the
+This means that you symlink the index and/or datafile(s) from the
normal data directory to another disk (that may also be striped). This
makes both the seek and read times better (if the disks are not used for
other things). @xref{Symbolic links}.
@@ -27065,7 +27895,7 @@ stripe-sizes. @xref{Custom Benchmarks}.
Note that the speed difference for striping is @strong{very} dependent
on the parameters. Depending on how you set the striping parameters and
number of disks you may get a difference in orders of magnitude. Note that
-you have to choose to optimize for random or sequential access.
+you have to choose to optimise for random or sequential access.
@end table
@item
@@ -27082,13 +27912,13 @@ and logs) on a RAID 0+1 or RAID N disk. RAID N can be a problem if you
have many writes because of the time to update the parity bits.
@item
-You may also set the parameters for the file system that the database
-uses. One easy change is to mount the file system with the noatime
+You may also set the parameters for the filesystem that the database
+uses. One easy change is to mount the filesystem with the noatime
option. That makes it skip the updating of the last access time in the
inode and by this will avoid some disk seeks.
@item
-On Linux, you can get much more performance (up to 100 % under load is
+On Linux, you can get much more performance (up to 100% under load is
not uncommon) by using hdpram to configure your disk's interface! The
following should be quite good hdparm options for MySQL (and
probably many other applications):
@@ -27105,14 +27935,14 @@ filesystem corruption may result. Backup everything before experimenting!
@item
On many operating systems you can mount the disks with the 'async' flag to
-set the file system to be updated asynchronously. If your computer is
+set the filesystem to be updated asynchronously. If your computer is
reasonable stable, this should give you more performance without sacrificing
too much reliability. (This flag is on by default on Linux.)
@item
If you don't need to know when a file was last accessed (which is not
-really useful on a database server), you can mount your file systems
-with the noatime flag.
+really useful on a database server), you can mount your filesystems
+with the @code{noatime} flag.
@end itemize
@menu
@@ -27132,8 +27962,8 @@ You might want to do this, for example, to move a database to a file
system with more free space or increase the speed of your system by
spreading your tables to different disk.
-The recommended may to do this, is to just symlink databases to different
-disk and only symlink tables as a last resort.
+The recommended way to do this, is to just symlink databases to a
+different disk and only symlink tables as a last resort.
@cindex databases, symbolic links
@menu
@@ -27193,18 +28023,18 @@ databases on different disks. @xref{Windows symbolic links}.
@cindex databases, symbolic links
Before MySQL 4.0 you should not symlink tables, if you are not
-very carefully with them. The problem is that if you run @code{ALTER
+very careful with them. The problem is that if you run @code{ALTER
TABLE}, @code{REPAIR TABLE} or @code{OPTIMIZE TABLE} on a symlinked
table, the symlinks will be removed and replaced by the original
files. This happens because the above command works by creating a
temporary file in the database directory and when the command is
complete, replace the original file with the temporary file.
-You should not symlink tables on system that doesn't have a fully
+You should not symlink tables on systems that don't have a fully
working @code{realpath()} call. (At least Linux and Solaris support
@code{realpath()})
-In MySQL 4.0 symlinks is only fully supported for @code{MyISAM}
+In MySQL 4.0 symlinks are only fully supported for @code{MyISAM}
tables. For other table types you will probably get strange problems
when doing any of the above mentioned commands.
@@ -27217,7 +28047,7 @@ In the data directory you will always have the table definition file
and the data/index files.
@item
-You can symlink the index file and the data file to different directories
+You can symlink the index file and the datafile to different directories
independent of the other.
@item
@@ -27233,7 +28063,7 @@ will be created in the same directory where the data/index file is.
@item
When you drop a table that is using symlinks, both the symlink and the
file the symlink points to is dropped. This is a good reason to why you
-should NOT run @code{mysqld} as root and not allow persons to have write
+should @strong{not} run @code{mysqld} as root and not allow persons to have write
access to the MySQL database directories.
@item
@@ -27267,11 +28097,16 @@ Things that are not yet supported:
@end itemize
-
-
-@node Reference, Table types, MySQL Optimization, Top
+@node Reference, Table types, MySQL Optimisation, Top
@chapter MySQL Language Reference
+MySQL has a very complex, but intuitive and easy to learn SQL
+interface. This chapter describes the various commands, types, and functions
+you will need to know in order to use MySQL efficiently and
+effectively. This chapter also serves as a reference to all functionality
+included in MySQL. In order to use this chapter effectively, you
+may find it useful to refer to the various indexes.
+
@menu
* Language Structure:: Language Structure
* Column types:: Column types
@@ -27281,15 +28116,9 @@ Things that are not yet supported:
* Basic User Commands:: Basic MySQL User Utility Commands
* Transactional Commands:: MySQL Transactional and Locking Commands
* Fulltext Search:: MySQL Full-text Search
+* Query Cache:: MySQL Query Cache
@end menu
-MySQL has a very complex, but intuitive and easy to learn SQL
-interface. This chapter describes the various commands, types, and functions
-you will need to know in order to use MySQL efficiently and
-effectively. This chapter also serves as a reference to all functionality
-included in MySQL. In order to use this chapter effectively, you
-may find it useful to refer to the various indexes.
-
@node Language Structure, Column types, Reference, Reference
@section Language Structure
@@ -27297,8 +28126,9 @@ may find it useful to refer to the various indexes.
@menu
* Literals:: Literals: How to Write Strings and Numbers
* Legal names:: Database, Table, Index, Column, and Alias Names
-* Name case sensitivity:: Case Sensitivity in Names
+* Name case sensitivity:: Case-Sensitivity in Names
* Variables:: User Variables
+* System Variables:: System Variables
* Comments:: Comment Syntax
* Reserved words:: Is MySQL Picky About Reserved Words?
@end menu
@@ -27340,7 +28170,7 @@ if you run in ANSI mode). Examples:
Within a string, certain sequences have special meaning. Each of these
sequences begins with a backslash (@samp{\}), known as the @emph{escape
-character}. MySQL recognizes the following escape sequences:
+character}. MySQL recognises the following escape sequences:
@c these aren't really functions, but that's probably the most reasonable index
@table @code
@@ -27384,28 +28214,28 @@ A tab character.
@findex (Control-Z) \z
@item \z
ASCII(26) (Control-Z). This character can be encoded to allow you to
-go around the problem that ASCII(26) stands for END-OF-FILE on Windows.
+work around the problem that ASCII(26) stands for END-OF-FILE on Windows.
(ASCII(26) will cause problems if you try to use
-@code{mysql database < filename}).
+@code{mysql database < filename}.)
@findex \\ (escape)
@findex escape (\\)
@item \\
A backslash (@samp{\}) character.
-@findex % (wild card character)
-@findex Wild card character (%)
+@findex % (wildcard character)
+@findex Wildcard character (%)
@item \%
A @samp{%} character. This is used to search for literal instances of
@samp{%} in contexts where @samp{%} would otherwise be interpreted
-as a wild-card character. @xref{String comparison functions}.
+as a wildcard character. @xref{String comparison functions}.
-@findex _ (wild card character)
-@findex Wild card character (_)
+@findex _ (wildcard character)
+@findex Wildcard character (_)
@item \_
A @samp{_} character. This is used to search for literal instances of
@samp{_} in contexts where @samp{_} would otherwise be interpreted
-as a wild-card character. @xref{String comparison functions}.
+as a wildcard character. @xref{String comparison functions}.
@end table
Note that if you use @samp{\%} or @samp{\_} in some string contexts, these
@@ -27432,7 +28262,7 @@ and need not be doubled or escaped. In the same way, @samp{"} inside a
string quoted with @samp{'} needs no special treatment.
@end itemize
-The @code{SELECT} statements shown below demonstrate how quoting and
+The @code{SELECT} statements shown here demonstrate how quoting and
escaping work:
@example
@@ -27457,8 +28287,9 @@ lines |
@cindex quoting binary data
-If you want to insert binary data into a @code{BLOB} column, the following
-characters must be represented by escape sequences:
+If you want to insert binary data into a string column (such as a
+@code{BLOB}), the following characters must be represented by escape
+sequences:
@table @code
@item NUL
ASCII 0. You should represent this by @samp{\0} (a backslash and an ASCII @samp{0} character).
@@ -27472,10 +28303,10 @@ ASCII 34, double quote. Represent this by @samp{\"}.
@cindex quoting
@cindex @code{BLOB}, inserting binary data
-@findex mysql_escape_string()
+@findex mysql_real_escape_string()
@findex DBI->quote
If you write C code, you can use the C API function
-@code{mysql_escape_string()} to escape characters for the @code{INSERT}
+@code{mysql_real_escape_string()} to escape characters for the @code{INSERT}
statement. @xref{C API function overview}. In Perl, you can use the
@code{quote} method of the @code{DBI} package to convert special
characters to the proper escape sequences. @xref{Perl DBI Class, , Perl
@@ -27484,6 +28315,11 @@ characters to the proper escape sequences. @xref{Perl DBI Class, , Perl
You should use an escape function on any string that might contain any of the
special characters listed above!
+Alternatively, many MySQL APIs provide some sort of placeholder capability
+that allows you to insert special markers into a query string, and then bind
+data values to them when you issue the query. In this case, the API takes
+case of escaping special characters in the values for you automatically.
+
@node Number syntax, Hexadecimal values, String syntax, Literals
@subsubsection Numbers
@@ -27523,19 +28359,24 @@ as the equivalent floating-point number.
@tindex hexadecimal values
-MySQL supports hexadecimal values. In number context these act
+MySQL supports hexadecimal values. In numeric context these act
like an integer (64-bit precision). In string context these act like a binary
string where each pair of hex digits is converted to a character:
@example
+mysql> SELECT x'FF'
+ -> 255
mysql> SELECT 0xa+0;
- -> 10
-mysql> select 0x5061756c;
- -> Paul
+ -> 10
+mysql> SELECT 0x5061756c;
+ -> Paul
@end example
-Hexadecimal strings are often used by ODBC to give values for BLOB columns.
-
+The @code{x'hexstring'} syntax (new in 4.0) is based on ANSI SQL and the
+@code{0x} syntax is based on ODBC. Hexadecimal strings are often used by
+ODBC to supply values for @code{BLOB} columns.
+You can convert a string or a number to hexadecimal with the @code{HEX()}
+function.
@node NULL values, , Hexadecimal values, Literals
@subsubsection @code{NULL} Values
@@ -27562,11 +28403,6 @@ or export formats (@code{LOAD DATA INFILE}, @code{SELECT ... INTO OUTFILE}).
@cindex columns, names
@cindex aliases, names
-@menu
-* Name case sensitivity:: Case sensitivity in names
-@end menu
-
-
Database, table, index, column, and alias names all follow the same rules in
MySQL.
@@ -27581,7 +28417,7 @@ in ANSI mode. @xref{ANSI mode}.
@multitable @columnfractions .15 .15 .70
@item @strong{Identifier} @tab @strong{Max length} @tab @strong{Allowed characters}
-@item Database @tab 64 @tab Any character that is allowed in a directory name except @samp{/} or @samp{.}.
+@item Database @tab 64 @tab Any character that is allowed in a directory name except @samp{/}, @samp{\} or @samp{.}.
@item Table @tab 64 @tab Any character that is allowed in a file name, except @samp{/} or @samp{.}.
@item Column @tab 64 @tab All characters.
@item Alias @tab 255 @tab All characters.
@@ -27594,10 +28430,12 @@ Note that if the identifier is a restricted word or contains special characters
you must always quote it with @code{`} when you use it:
@example
-SELECT * from `select` where `select`.id > 100;
+mysql> SELECT * FROM `select` WHERE `select`.id > 100;
@end example
-In previous versions of MySQL, the name rules are as follows:
+@xref{Reserved words}.
+
+In MySQL versions prior to 3.23.6, the name rules are as follows:
@itemize @bullet
@item
@@ -27609,8 +28447,8 @@ to @code{mysqld}.
@item
A name may start with any character that is legal in a name. In particular,
-a name may start with a number (this differs from many other database
-systems!). However, a name cannot consist @emph{only} of numbers.
+a name may start with a digit (this differs from many other database
+systems!). However, a name cannot consist @emph{only} of digits.
@item
You cannot use the @samp{.} character in names because it is used to extend the
@@ -27623,7 +28461,7 @@ expression @code{1e + 1} or as the number @code{1e+1}.
In MySQL you can refer to a column using any of the following forms:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .30 .70
@item @strong{Column reference} @tab @strong{Meaning}
@item @code{col_name} @tab Column @code{col_name}
from whichever table used in the query contains a column of that name.
@@ -27659,18 +28497,20 @@ programs prefix table names with a @samp{.} character.
@cindex names, case-sensitivity
@cindex case-sensitivity, in names
-@cindex database names, case sensitivity
-@cindex table names, case sensitivity
-@cindex column names, case sensitivity
-@cindex alias names, case sensitivity
+@cindex database names, case-sensitivity
+@cindex table names, case-sensitivity
+@cindex column names, case-sensitivity
+@cindex alias names, case-sensitivity
In MySQL, databases and tables correspond to directories and files
-within those directories. Consequently, the case sensitivity of the
-underlying operating system determines the case sensitivity of database and
-table names. This means database and table names are case sensitive in Unix
-and case insensitive in Windows. @xref{Extensions to ANSI}.
-
-@strong{NOTE:} Although database and table names are case insensitive for
+within those directories. Consequently, the case-sensitivity of the
+underlying operating system determines the case-sensitivity of database and
+table names. This means database and table names are case-insensitive in
+Windows, and case-sensitive in most varieties of Unix (Mac OS X being an
+exception).
+@xref{Extensions to ANSI}.
+
+@strong{Note}: although database and table names are case-insensitive for
Windows, you should not refer to a given database or table using different
cases within the same query. The following query would not work because it
refers to a table both as @code{my_table} and as @code{MY_TABLE}:
@@ -27679,19 +28519,17 @@ refers to a table both as @code{my_table} and as @code{MY_TABLE}:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
@end example
-Column names are case insensitive in all cases.
+Column names and column aliases are case-insensitive in all cases.
-Aliases on tables are case sensitive. The following query would not work
+Aliases on tables are case-sensitive. The following query would not work
because it refers to the alias both as @code{a} and as @code{A}:
@example
mysql> SELECT col_name FROM tbl_name AS a
- WHERE a.col_name = 1 OR A.col_name = 2;
+ -> WHERE a.col_name = 1 OR A.col_name = 2;
@end example
-Aliases on columns are case insensitive.
-
-If you have a problem remembering the used cases for a table names,
+If you have trouble remembering the lettercase for database and table names,
adopt a consistent convention, such as always creating databases and
tables using lowercase names.
@@ -27704,15 +28542,21 @@ table names to lower case on storage and lookup. Note that if you
change this option, you need to first convert your old table names to
lower case before starting @code{mysqld}.
+If you move @code{MyISAM} files from a Windows to a *nix disk, you may
+in some cases need to use the @file{mysql_fix_extensions} tool to fix-up
+the case of the file extensions in each specified database directory
+(lowercase @file{.frm}, uppercase @file{.MYI} and @file{.MYD}).
+@file{mysql_fix_extensions} can be found in the @file{script} subdirectory.
-@node Variables, Comments, Name case sensitivity, Language Structure
+
+@node Variables, System Variables, Name case sensitivity, Language Structure
@subsection User Variables
@cindex variables, user
@cindex user variables
@cindex names, variables
-MySQL supports thread-specific variables with the
+MySQL supports connection-specific user variables with the
@code{@@variablename} syntax. A variable name may consist of
alphanumeric characters from the current character set and also
@samp{_}, @samp{$}, and @samp{.} . The default character set is
@@ -27720,7 +28564,7 @@ ISO-8859-1 Latin1; this may be changed with the
@code{--default-character-set} option to @code{mysqld}. @xref{Character
sets}.
-Variables don't have to be initialized. They contain @code{NULL} by default
+Variables don't have to be initialised. They contain @code{NULL} by default
and can store an integer, real, or string value. All variables for
a thread are automatically freed when the thread exits.
@@ -27731,11 +28575,13 @@ SET @@variable= @{ integer expression | real expression | string expression @}
[,@@variable= ...].
@end example
-You can also set a variable in an expression with the @code{@@variable:=expr}
-syntax:
+You can also assign a value to a variable in statements other than @code{SET}.
+However, in this case the assignment operator is @code{:=} rather than
+@code{=}, because @code{=} is reserved for comparisons in non-@code{SET}
+statements:
@example
-select @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
+mysql> SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
+----------------------+------+------+------+
| @@t1:=(@@t2:=1)+@@t3:=4 | @@t1 | @@t2 | @@t3 |
+----------------------+------+------+------+
@@ -27743,34 +28589,202 @@ select @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
+----------------------+------+------+------+
@end example
-(We had to use the @code{:=} syntax here, because @code{=} was reserved for
-comparisons.)
-
User variables may be used where expressions are allowed. Note that
-this does not currently include use in contexts where a number is explicitly
+this does not currently include contexts where a number is explicitly
required, such as in the @code{LIMIT} clause of a @code{SELECT} statement,
or the @code{IGNORE number LINES} clause of a @code{LOAD DATA} statement.
-@strong{NOTE:} In a @code{SELECT} statement, each expression is only
-evaluated when it's sent to the client. This means that in the @code{HAVING},
+@strong{Note}: in a @code{SELECT} statement, each expression is evaluated
+only when it's sent to the client. This means that in the @code{HAVING},
@code{GROUP BY}, or @code{ORDER BY} clause, you can't refer to an expression
that involves variables that are set in the @code{SELECT} part. For example,
the following statement will NOT work as expected:
@example
-SELECT (@@aa:=id) AS a, (@@aa+3) AS b FROM table_name HAVING b=5;
+mysql> SELECT (@@aa:=id) AS a, (@@aa+3) AS b FROM table_name HAVING b=5;
@end example
The reason is that @code{@@aa} will not contain the value of the current
row, but the value of @code{id} for the previous accepted row.
+@node System Variables, Comments, Variables, Language Structure
+@subsection System Variables
-@menu
-* Comments:: Comment Syntax
-* Reserved words:: Is MySQL Picky About Reserved Words?
-@end menu
+@cindex variables, System
+@cindex system variables
+
+Starting from MySQL 4.0.3 we provide better access to a lot of system
+and connection variables. One can change most of them without having to take
+down the server.
+
+There are two kind of system variables: Thread (or connection) specific
+variables that are unique to the current connection and global variables
+that are either used to configure global events or used as initial
+variables for a new connection.
+
+When mysqld starts all global variables are initialised from command
+line arguments and option files. You can change the used value with the
+@code{SET GLOBAL} command. When a new thread is created the thread
+specific variables are initialised from the global variables and they
+will not change even if one issues a new @code{SET GLOBAL} command.
+
+To set the value for a @code{GLOBAL} variable, you should use one
+of the following syntaxes:
+(Here we use @code{sort_buffer_size} as an example variable)
+
+@example
+SET GLOBAL sort_buffer_size=value;
+SET @@@@global.sort_buffer_size=value;
+@end example
-@node Comments, Reserved words, Variables, Language Structure
+To set the value for @code{SESSION} variable, you can use on of the
+following syntaxes:
+
+@example
+SET SESSION sort_buffer_size=value;
+SET @@@@session.sort_buffer_size=value;
+SET sort_buffer_size=value;
+@end example
+
+If you don't specify @code{GLOBAL} or @code{SESSION} then @code{SESSION}
+is used. @xref{SET OPTION}.
+
+@code{LOCAL} is a synonym for @code{SESSION}.
+
+To retrieve the value for a @code{GLOBAL} variable you can use one of the
+following commands:
+
+@example
+SELECT @@@@global.sort_buffer_size;
+SHOW GLOBAL VARIABLES like 'sort_buffer_size';
+@end example
+
+To retrieve the value for a @code{SESSION} variable you can use one of the
+following commands:
+
+@example
+SELECT @@@@session.sort_buffer_size;
+SHOW SESSION VARIABLES like 'sort_buffer_size';
+@end example
+
+When you @strong{retrieve} a variable value with the
+@code{@@@@variable_name} syntax and you don't specify @code{GLOBAL} or
+@code{SESSION} then MySQL will return the thread specific
+(@code{SESSION}) value if it exists. If not, MySQL will return the
+global value.
+
+The reason for requiring @code{GLOBAL} for setting @code{GLOBAL} only
+variables but not for retrieving them is to ensure that we don't later
+run into problems if we later would introduce a thread specific variable
+with the same name or remove a thread specific variable. In this case
+you could accidently change the state for the whole server and not
+just for your own connection.
+
+The following is a full list of all variables that you change and retrieve
+and if you can use @code{GLOBAL} or @code{SESSION} with them.
+
+@multitable @columnfractions .50 .25 .25
+@item @strong{Variable name} @tab @strong{Value type} @tab @strong{Type}
+@item autocommit @tab bool @tab SESSION
+@item big_tables @tab bool @tab SESSION
+@item binlog_cache_size @tab num @tab GLOBAL
+@item bulk_insert_buffer_size @tab num @tab GLOBAL | SESSION
+@item concurrent_insert @tab bool @tab GLOBAL
+@item connect_timeout @tab num @tab GLOBAL
+@item convert_character_set @tab string @tab SESSION
+@item delay_key_write @tab bool @tab GLOBAL
+@item delayed_insert_limit @tab num @tab GLOBAL
+@item delayed_insert_timeout @tab num @tab GLOBAL
+@item delayed_queue_size @tab num @tab GLOBAL
+@item flush @tab bool @tab GLOBAL
+@item flush_time @tab num @tab GLOBAL
+@item identity @tab num @tab SESSION
+@item insert_id @tab bool @tab SESSION
+@item interactive_timeout @tab num @tab GLOBAL | SESSION
+@item join_buffer_size @tab num @tab GLOBAL | SESSION
+@item key_buffer_size @tab num @tab GLOBAL
+@item last_insert_id @tab bool @tab SESSION
+@item local_infile @tab bool @tab GLOBAL
+@item log_warnings @tab bool @tab GLOBAL
+@item long_query_time @tab num @tab GLOBAL | SESSION
+@item low_priority_updates @tab bool @tab GLOBAL | SESSION
+@item max_allowed_packet @tab num @tab GLOBAL | SESSION
+@item max_binlog_cache_size @tab num @tab GLOBAL
+@item max_binlog_size @tab num @tab GLOBAL
+@item max_connect_errors @tab num @tab GLOBAL
+@item max_connections @tab num @tab GLOBAL
+@item max_delayed_threads @tab num @tab GLOBAL
+@item max_heap_table_size @tab num @tab GLOBAL | SESSION
+@item max_join_size @tab num @tab GLOBAL | SESSION
+@item max_sort_length @tab num @tab GLOBAL | SESSION
+@item max_tmp_tables @tab num @tab GLOBAL
+@item max_user_connections @tab num @tab GLOBAL
+@item max_write_lock_count @tab num @tab GLOBAL
+@item myisam_max_extra_sort_file_size @tab num @tab GLOBAL | SESSION
+@item myisam_max_sort_file_size @tab num @tab GLOBAL | SESSION
+@item myisam_sort_buffer_size @tab num @tab GLOBAL | SESSION
+@item net_buffer_length @tab num @tab GLOBAL | SESSION
+@item net_read_timeout @tab num @tab GLOBAL | SESSION
+@item net_write_timeout @tab num @tab GLOBAL | SESSION
+@item query_cache_limit @tab num @tab GLOBAL
+@item query_cache_size @tab num @tab GLOBAL
+@item query_cache_type @tab enum @tab GLOBAL
+@item read_buffer_size @tab num @tab GLOBAL | SESSION
+@item read_rnd_buffer_size num @tab GLOBAL | SESSION
+@item rpl_recovery_rank @tab num @tab GLOBAL
+@item safe_show_database @tab bool @tab GLOBAL
+@item server_id @tab num @tab GLOBAL
+@item slave_net_timeout @tab num @tab GLOBAL
+@item slow_launch_time @tab num @tab GLOBAL
+@item sort_buffer_size @tab num @tab GLOBAL | SESSION
+@item sql_auto_is_null @tab bool @tab SESSION
+@item sql_big_selects @tab bool @tab SESSION
+@item sql_big_tables @tab bool @tab SESSION
+@item sql_buffer_result @tab bool @tab SESSION
+@item sql_log_binlog @tab bool @tab SESSION
+@item sql_log_off @tab bool @tab SESSION
+@item sql_log_update @tab bool @tab SESSION
+@item sql_low_priority_updates @tab bool @tab GLOBAL | SESSION
+@item sql_max_join_size @tab num @tab GLOBAL | SESSION
+@item sql_quote_show_create @tab bool @tab SESSION
+@item sql_safe_updates @tab bool @tab SESSION
+@item sql_select_limit @tab bool @tab SESSION
+@item sql_slave_skip_counter @tab num @tab GLOBAL
+@item sql_warnings @tab bool @tab SESSION
+@item table_cache @tab num @tab GLOBAL
+@item table_type @tab enum @tab GLOBAL | SESSION
+@item thread_cache_size @tab num @tab GLOBAL
+@item timestamp @tab bool @tab SESSION
+@item tmp_table_size @tab enum @tab GLOBAL | SESSION
+@item tx_isolation @tab enum @tab GLOBAL | SESSION
+@item version @tab string @tab GLOBAL
+@item wait_timeout @tab num @tab GLOBAL | SESSION
+@end multitable
+
+Variables that are marked with @code{num} can be given a numerical
+value. Variables that are marked with @code{bool} can be set to 0, 1,
+@code{ON} or @code{OFF}. Variables that are of type @code{enum} should
+normally be set to one of the available values for the variable, but can
+also be set to the number that correspond to the enum value. (The first
+enum value is 0).
+
+Here is a description of some of the variables:
+
+@multitable @columnfractions 0.30 0.70
+@item @strong{Variable} @tab @strong{Description}
+@item identity @tab Alias for last_insert_id (Sybase compatiblity)
+@item sql_low_priority_updates @tab Alias for low_priority_updates
+@item sql_max_join_size @tab Alias for max_join_size
+@item version @tab Alias for VERSION() (Sybase (?) compatability)
+@end multitable
+
+A description of the other variable definitions can be found in the
+startup options section, the description of @code{SHOW VARIABLES} and in
+the @code{SET} section. @xref{Command-line
+options}. @xref{SHOW VARIABLES}. @xref{SET OPTION}.
+
+
+@node Comments, Reserved words, System Variables, Language Structure
@subsection Comment Syntax
@findex Comment syntax
@@ -27782,10 +28796,10 @@ to end of line} and @code{/* in-line or multiple-line */} comment
styles:
@example
-mysql> select 1+1; # This comment continues to the end of line
-mysql> select 1+1; -- This comment continues to the end of line
-mysql> select 1 /* this is an in-line comment */ + 1;
-mysql> select 1+
+mysql> SELECT 1+1; # This comment continues to the end of line
+mysql> SELECT 1+1; -- This comment continues to the end of line
+mysql> SELECT 1 /* this is an in-line comment */ + 1;
+mysql> SELECT 1+
/*
this is a
multiple-line comment
@@ -27793,8 +28807,8 @@ multiple-line comment
1;
@end example
-Note that the @code{--} comment style requires you to have at least one space
-after the @code{--}!
+Note that the @code{--} (double-dash) comment style requires you to have at
+least one space after the second dash!
Although the server understands the comment syntax just described,
there are some limitations on the way that the @code{mysql} client
@@ -27804,7 +28818,7 @@ parses @code{/* ... */} comments:
@item
Single-quote and double-quote characters are taken to indicate the beginning
of a quoted string, even within a comment. If the quote is not matched by a
-second quote within the comment, the parser doesn't realize the comment has
+second quote within the comment, the parser doesn't realise the comment has
ended. If you are running @code{mysql} interactively, you can tell that it
has gotten confused like this because the prompt changes from @code{mysql>}
to @code{'>} or @code{">}.
@@ -27818,8 +28832,8 @@ These limitations apply both when you run @code{mysql} interactively
and when you put commands in a file and tell @code{mysql} to read its
input from that file with @code{mysql < some-file}.
-MySQL doesn't support the @samp{--} ANSI SQL comment style.
-@xref{Missing comments}.
+MySQL supports the @samp{--} ANSI SQL comment style only if the second dash
+is followed by a space. @xref{ANSI diff comments}.
@node Reserved words, , Comments, Language Structure
@@ -27832,93 +28846,199 @@ A common problem stems from trying to create a table with column names that
use the names of datatypes or functions built into MySQL, such as
@code{TIMESTAMP} or @code{GROUP}. You're allowed to do it (for example,
@code{ABS} is an allowed column name), but whitespace is not allowed between
-a function name and the @samp{(} when using functions whose names are also
-column names.
+a function name and the immediately following @samp{(} when using functions
+whose names are also column names.
The following words are explicitly reserved in MySQL. Most of
them are forbidden by ANSI SQL92 as column and/or table names
-(for example, @code{group}).
+(for example, @code{GROUP}).
A few are reserved because MySQL needs them and is
(currently) using a @code{yacc} parser:
-@c This is fixed by including the symbols table from lex.h here and then running
-@c fix-mysql-reserved-words in emacs (or let David do it):
-@c (defun fix-mysql-reserved-words ()
-@c (interactive)
-@c (let ((cnt 0))
-@c (insert "\n@item ")
-@c (while (looking-at "[ \t]*{ +\"\\([^\"]+\\)\"[ \t]*,.*\n")
-@c (replace-match "@code{\\1}")
-@c (incf cnt)
-@c (if (> cnt 3)
-@c (progn
-@c (setf cnt 0)
-@c (insert "\n@item "))
-@c (insert " @tab ")))))
-@c But remove the non alphanumeric entries by hand first.
-@c Updated after 3.23.4 990928 by David
-
-@multitable @columnfractions .25 .25 .25 .25
-@item @code{action} @tab @code{add} @tab @code{aggregate} @tab @code{all}
-@item @code{alter} @tab @code{after} @tab @code{and} @tab @code{as}
-@item @code{asc} @tab @code{avg} @tab @code{avg_row_length} @tab @code{auto_increment}
-@item @code{between} @tab @code{bigint} @tab @code{bit} @tab @code{binary}
-@item @code{blob} @tab @code{bool} @tab @code{both} @tab @code{by}
-@item @code{cascade} @tab @code{case} @tab @code{char} @tab @code{character}
-@item @code{change} @tab @code{check} @tab @code{checksum} @tab @code{column}
-@item @code{columns} @tab @code{comment} @tab @code{constraint} @tab @code{create}
-@item @code{cross} @tab @code{current_date} @tab @code{current_time} @tab @code{current_timestamp}
-@item @code{data} @tab @code{database} @tab @code{databases} @tab @code{date}
-@item @code{datetime} @tab @code{day} @tab @code{day_hour} @tab @code{day_minute}
-@item @code{day_second} @tab @code{dayofmonth} @tab @code{dayofweek} @tab @code{dayofyear}
-@item @code{dec} @tab @code{decimal} @tab @code{default} @tab @code{delayed}
-@item @code{delay_key_write} @tab @code{delete} @tab @code{desc} @tab @code{describe}
-@item @code{distinct} @tab @code{distinctrow} @tab @code{double} @tab @code{drop}
-@item @code{end} @tab @code{else} @tab @code{escape} @tab @code{escaped}
-@item @code{enclosed} @tab @code{enum} @tab @code{explain} @tab @code{exists}
-@item @code{fields} @tab @code{file} @tab @code{first} @tab @code{float}
-@item @code{float4} @tab @code{float8} @tab @code{flush} @tab @code{foreign}
-@item @code{from} @tab @code{for} @tab @code{full} @tab @code{function}
-@item @code{global} @tab @code{grant} @tab @code{grants} @tab @code{group}
-@item @code{having} @tab @code{heap} @tab @code{high_priority} @tab @code{hour}
-@item @code{hour_minute} @tab @code{hour_second} @tab @code{hosts} @tab @code{identified}
-@item @code{ignore} @tab @code{in} @tab @code{index} @tab @code{infile}
-@item @code{inner} @tab @code{insert} @tab @code{insert_id} @tab @code{int}
-@item @code{integer} @tab @code{interval} @tab @code{int1} @tab @code{int2}
-@item @code{int3} @tab @code{int4} @tab @code{int8} @tab @code{into}
-@item @code{if} @tab @code{is} @tab @code{isam} @tab @code{join}
-@item @code{key} @tab @code{keys} @tab @code{kill} @tab @code{last_insert_id}
-@item @code{leading} @tab @code{left} @tab @code{length} @tab @code{like}
-@item @code{lines} @tab @code{limit} @tab @code{load} @tab @code{local}
-@item @code{lock} @tab @code{logs} @tab @code{long} @tab @code{longblob}
-@item @code{longtext} @tab @code{low_priority} @tab @code{max} @tab @code{max_rows}
-@item @code{match} @tab @code{mediumblob} @tab @code{mediumtext} @tab @code{mediumint}
-@item @code{middleint} @tab @code{min_rows} @tab @code{minute} @tab @code{minute_second}
-@item @code{modify} @tab @code{month} @tab @code{monthname} @tab @code{myisam}
-@item @code{natural} @tab @code{numeric} @tab @code{no} @tab @code{not}
-@item @code{null} @tab @code{on} @tab @code{optimize} @tab @code{option}
-@item @code{optionally} @tab @code{or} @tab @code{order} @tab @code{outer}
-@item @code{outfile} @tab @code{pack_keys} @tab @code{partial} @tab @code{password}
-@item @code{precision} @tab @code{primary} @tab @code{procedure} @tab @code{process}
-@item @code{processlist} @tab @code{privileges} @tab @code{read} @tab @code{real}
-@item @code{references} @tab @code{reload} @tab @code{regexp} @tab @code{rename}
-@item @code{replace} @tab @code{restrict} @tab @code{returns} @tab @code{revoke}
-@item @code{rlike} @tab @code{row} @tab @code{rows} @tab @code{second}
-@item @code{select} @tab @code{set} @tab @code{show} @tab @code{shutdown}
-@item @code{smallint} @tab @code{soname} @tab @code{sql_big_tables} @tab @code{sql_big_selects}
-@item @code{sql_low_priority_updates} @tab @code{sql_log_off} @tab @code{sql_log_update} @tab @code{sql_select_limit}
-@item @code{sql_small_result} @tab @code{sql_big_result} @tab @code{sql_warnings} @tab @code{straight_join}
-@item @code{starting} @tab @code{status} @tab @code{string} @tab @code{table}
-@item @code{tables} @tab @code{temporary} @tab @code{terminated} @tab @code{text}
-@item @code{then} @tab @code{time} @tab @code{timestamp} @tab @code{tinyblob}
-@item @code{tinytext} @tab @code{tinyint} @tab @code{trailing} @tab @code{to}
-@item @code{type} @tab @code{use} @tab @code{using} @tab @code{unique}
-@item @code{unlock} @tab @code{unsigned} @tab @code{update} @tab @code{usage}
-@item @code{values} @tab @code{varchar} @tab @code{variables} @tab @code{varying}
-@item @code{varbinary} @tab @code{with} @tab @code{write} @tab @code{when}
-@item @code{where} @tab @code{year} @tab @code{year_month} @tab @code{zerofill}
+@c START_OF_RESERVED_WORDS
+
+@c Reserved word list updated Tue Jul 23 20:41:20 2002 by monty.
+@c To regenerate, use Support/update-reserved-words.pl.
+
+@multitable @columnfractions .33 .33 .34
+@item @strong{Word}
+ @tab @strong{Word}
+ @tab @strong{Word}
+@item @code{ADD}
+ @tab @code{ALL}
+ @tab @code{ALTER}
+@item @code{ANALYZE}
+ @tab @code{AND}
+ @tab @code{AS}
+@item @code{ASC}
+ @tab @code{AUTO_INCREMENT}
+ @tab @code{BDB}
+@item @code{BERKELEYDB}
+ @tab @code{BETWEEN}
+ @tab @code{BIGINT}
+@item @code{BINARY}
+ @tab @code{BLOB}
+ @tab @code{BOTH}
+@item @code{BY}
+ @tab @code{CASCADE}
+ @tab @code{CASE}
+@item @code{CHANGE}
+ @tab @code{CHAR}
+ @tab @code{CHARACTER}
+@item @code{COLUMN}
+ @tab @code{COLUMNS}
+ @tab @code{CONSTRAINT}
+@item @code{CREATE}
+ @tab @code{CROSS}
+ @tab @code{CURRENT_DATE}
+@item @code{CURRENT_TIME}
+ @tab @code{CURRENT_TIMESTAMP}
+ @tab @code{DATABASE}
+@item @code{DATABASES}
+ @tab @code{DAY_HOUR}
+ @tab @code{DAY_MINUTE}
+@item @code{DAY_SECOND}
+ @tab @code{DEC}
+ @tab @code{DECIMAL}
+@item @code{DEFAULT}
+ @tab @code{DELAYED}
+ @tab @code{DELETE}
+@item @code{DESC}
+ @tab @code{DESCRIBE}
+ @tab @code{DISTINCT}
+@item @code{DISTINCTROW}
+ @tab @code{DOUBLE}
+ @tab @code{DROP}
+@item @code{ELSE}
+ @tab @code{ENCLOSED}
+ @tab @code{ESCAPED}
+@item @code{EXISTS}
+ @tab @code{EXPLAIN}
+ @tab @code{FIELDS}
+@item @code{FLOAT}
+ @tab @code{FOR}
+ @tab @code{FOREIGN}
+@item @code{FROM}
+ @tab @code{FULLTEXT}
+ @tab @code{FUNCTION}
+@item @code{GRANT}
+ @tab @code{GROUP}
+ @tab @code{HAVING}
+@item @code{HIGH_PRIORITY}
+ @tab @code{HOUR_MINUTE}
+ @tab @code{HOUR_SECOND}
+@item @code{IF}
+ @tab @code{IGNORE}
+ @tab @code{IN}
+@item @code{INDEX}
+ @tab @code{INFILE}
+ @tab @code{INNER}
+@item @code{INNODB}
+ @tab @code{INSERT}
+ @tab @code{INT}
+@item @code{INTEGER}
+ @tab @code{INTERVAL}
+ @tab @code{INTO}
+@item @code{IS}
+ @tab @code{JOIN}
+ @tab @code{KEY}
+@item @code{KEYS}
+ @tab @code{KILL}
+ @tab @code{LEADING}
+@item @code{LEFT}
+ @tab @code{LIKE}
+ @tab @code{LIMIT}
+@item @code{LINES}
+ @tab @code{LOAD}
+ @tab @code{LOCK}
+@item @code{LONG}
+ @tab @code{LONGBLOB}
+ @tab @code{LONGTEXT}
+@item @code{LOW_PRIORITY}
+ @tab @code{MASTER_SERVER_ID}
+ @tab @code{MATCH}
+@item @code{MEDIUMBLOB}
+ @tab @code{MEDIUMINT}
+ @tab @code{MEDIUMTEXT}
+@item @code{MIDDLEINT}
+ @tab @code{MINUTE_SECOND}
+ @tab @code{MRG_MYISAM}
+@item @code{NATURAL}
+ @tab @code{NOT}
+ @tab @code{NULL}
+@item @code{NUMERIC}
+ @tab @code{ON}
+ @tab @code{OPTIMIZE}
+@item @code{OPTION}
+ @tab @code{OPTIONALLY}
+ @tab @code{OR}
+@item @code{ORDER}
+ @tab @code{OUTER}
+ @tab @code{OUTFILE}
+@item @code{PARTIAL}
+ @tab @code{PRECISION}
+ @tab @code{PRIMARY}
+@item @code{PRIVILEGES}
+ @tab @code{PROCEDURE}
+ @tab @code{PURGE}
+@item @code{READ}
+ @tab @code{REAL}
+ @tab @code{REFERENCES}
+@item @code{REGEXP}
+ @tab @code{RENAME}
+ @tab @code{REPLACE}
+@item @code{REQUIRE}
+ @tab @code{RESTRICT}
+ @tab @code{RETURNS}
+@item @code{REVOKE}
+ @tab @code{RIGHT}
+ @tab @code{RLIKE}
+@item @code{SELECT}
+ @tab @code{SET}
+ @tab @code{SHOW}
+@item @code{SMALLINT}
+ @tab @code{SONAME}
+ @tab @code{SQL_BIG_RESULT}
+@item @code{SQL_CALC_FOUND_ROWS}
+ @tab @code{SQL_SMALL_RESULT}
+ @tab @code{SSL}
+@item @code{STARTING}
+ @tab @code{STRAIGHT_JOIN}
+ @tab @code{STRIPED}
+@item @code{TABLE}
+ @tab @code{TABLES}
+ @tab @code{TERMINATED}
+@item @code{THEN}
+ @tab @code{TINYBLOB}
+ @tab @code{TINYINT}
+@item @code{TINYTEXT}
+ @tab @code{TO}
+ @tab @code{TRAILING}
+@item @code{UNION}
+ @tab @code{UNIQUE}
+ @tab @code{UNLOCK}
+@item @code{UNSIGNED}
+ @tab @code{UPDATE}
+ @tab @code{USAGE}
+@item @code{USE}
+ @tab @code{USER_RESOURCES}
+ @tab @code{USING}
+@item @code{VALUES}
+ @tab @code{VARBINARY}
+ @tab @code{VARCHAR}
+@item @code{VARYING}
+ @tab @code{WHEN}
+ @tab @code{WHERE}
+@item @code{WITH}
+ @tab @code{WRITE}
+ @tab @code{XOR}
+@item @code{YEAR_MONTH}
+ @tab @code{ZEROFILL}
+ @tab
@end multitable
+@c END_OF_RESERVED_WORDS
+
The following symbols (from the table above) are disallowed by ANSI SQL
but allowed by MySQL as column/table names. This is because some
of these names are very natural names and a lot of people have already
@@ -27945,7 +29065,7 @@ used them.
MySQL supports a number of column types, which may be grouped into
three categories: numeric types, date and time types, and string (character)
types. This section first gives an overview of the types available and
-summarizes the storage requirements for each column type, then provides a
+summarises the storage requirements for each column type, then provides a
more detailed description of the properties of the types in each category.
The overview is intentionally brief. The more detailed descriptions should
be consulted for additional information about particular column types, such
@@ -27981,6 +29101,10 @@ that are optional.
Note that if you specify @code{ZEROFILL} for a column, MySQL will
automatically add the @code{UNSIGNED} attribute to the column.
+@strong{Warning}: you should be aware that when you use subtraction
+between integer values where one is of type @code{UNSIGNED}, the result
+will be unsigned! @xref{Cast Functions}.
+
@table @code
@tindex TINYINT
@item TINYINT[(M)] [UNSIGNED] [ZEROFILL]
@@ -27988,6 +29112,12 @@ automatically add the @code{UNSIGNED} attribute to the column.
A very small integer. The signed range is @code{-128} to @code{127}. The
unsigned range is @code{0} to @code{255}.
+@tindex BOOL
+@tindex BIT
+@item BIT
+@itemx BOOL
+These are synonyms for @code{TINYINT(1)}.
+
@tindex SMALLINT
@item SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
@@ -28018,23 +29148,35 @@ A large integer. The signed range is @code{-9223372036854775808} to
@code{9223372036854775807}. The unsigned range is @code{0} to
@code{18446744073709551615}.
-Some things you should be aware about @code{BIGINT} columns:
+Some things you should be aware of with respect to @code{BIGINT} columns:
@itemize @bullet
@item
@cindex rounding errors
-As all arithmetic is done using signed @code{BIGINT} or @code{DOUBLE}
+All arithmetic is done using signed @code{BIGINT} or @code{DOUBLE}
values, so you shouldn't use unsigned big integers larger than
@code{9223372036854775807} (63 bits) except with bit functions! If you
do that, some of the last digits in the result may be wrong because of
rounding errors when converting the @code{BIGINT} to a @code{DOUBLE}.
+
+MySQL 4.0 can handle @code{BIGINT} in the following cases:
+@itemize @bullet
+@item
+Use integers to store big unsigned values in a @code{BIGINT} column.
+@item
+In @code{MIN(big_int_column)} and @code{MAX(big_int_column)}.
+@item
+When using operators (@code{+}, @code{-}, @code{*}, etc.) where
+both operands are integers.
+@end itemize
+
@item
You can always store an exact integer value in a @code{BIGINT} column by
-storing it as a string, as there is in this case there will be no
-intermediate double representation.
+storing it as a string. In this case, MySQL will perform a string-to-number
+conversion that involves no intermediate double representation.
@item
@samp{-}, @samp{+}, and @samp{*} will use @code{BIGINT} arithmetic when
-both arguments are @code{INTEGER} values! This means that if you
+both arguments are integer values! This means that if you
multiply two big integers (or results from functions that return
integers) you may get unexpected results when the result is larger than
@code{9223372036854775807}.
@@ -28043,20 +29185,20 @@ integers) you may get unexpected results when the result is larger than
@cindex floating-point number
@tindex FLOAT
@tindex FLOAT(precision)
-@item FLOAT(precision) [ZEROFILL]
+@item FLOAT(precision) [UNSIGNED] [ZEROFILL]
-A floating-point number. Cannot be unsigned. @code{precision} can be
+A floating-point number. @code{precision} can be
@code{<=24} for a single-precision floating-point number and between 25
and 53 for a double-precision floating-point number. These types are like
the @code{FLOAT} and @code{DOUBLE} types described immediately below.
@code{FLOAT(X)} has the same range as the corresponding @code{FLOAT} and
-@code{DOUBLE} types, but the display size and number of decimals is undefined.
+@code{DOUBLE} types, but the display size and number of decimals are undefined.
In MySQL Version 3.23, this is a true floating-point value. In
earlier MySQL versions, @code{FLOAT(precision)} always has 2 decimals.
Note that using @code{FLOAT} may give you some unexpected problems as
-all calculation in MySQL is done with double precision.
+all calculations in MySQL are done with double precision.
@xref{No matching rows}.
@cindex ODBC compatibility
@@ -28065,56 +29207,61 @@ This syntax is provided for ODBC compatibility.
@tindex FLOAT
@tindex FLOAT(M,D)
-@item FLOAT[(M,D)] [ZEROFILL]
+@item FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
-A small (single-precision) floating-point number. Cannot be unsigned.
-Allowable values are @code{@w{-3.402823466E+38}} to
-@code{@w{-1.175494351E-38}}, @code{0}, and @code{@w{1.175494351E-38}} to
-@code{3.402823466E+38}. The M is the display width and D is the
-number of decimals. @code{FLOAT} without an argument or with an argument of
-<= 24 stands for a single-precision floating-point number.
+A small (single-precision) floating-point number. Allowable values are
+@code{@w{-3.402823466E+38}} to @code{@w{-1.175494351E-38}}, @code{0},
+and @code{@w{1.175494351E-38}} to @code{3.402823466E+38}. If
+@code{UNSIGNED} is specified, negative values are disallowed. The @code{M}
+is the display width and @code{D} is the number of decimals. @code{FLOAT}
+without arguments or @code{FLOAT(X)} where @code{X} <= 24 stands for a
+single-precision floating-point number.
@tindex DOUBLE
@tindex FLOAT(precision)
-@item DOUBLE[(M,D)] [ZEROFILL]
+@item DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
-A normal-size (double-precision) floating-point number. Cannot be
-unsigned. Allowable values are @code{@w{-1.7976931348623157E+308}} to
+A normal-size (double-precision) floating-point number.
+Allowable values are @code{@w{-1.7976931348623157E+308}} to
@code{@w{-2.2250738585072014E-308}}, @code{0}, and
-@code{2.2250738585072014E-308} to @code{1.7976931348623157E+308}. The M
-is the display width and D is the number of decimals. @code{DOUBLE}
-without an argument or @code{FLOAT(X)} where 25 <= X <= 53 stands for a
-double-precision floating-point number.
+@code{2.2250738585072014E-308} to @code{1.7976931348623157E+308}. If
+@code{UNSIGNED} is specified, negative values are disallowed. The
+@code{M} is the display width and @code{D} is the number of decimals.
+@code{DOUBLE} without arguments or @code{FLOAT(X)} where 25 <= @code{X}
+<= 53 stands for a double-precision floating-point number.
@tindex DOUBLE PRECISION
@tindex REAL
-@item DOUBLE PRECISION[(M,D)] [ZEROFILL]
-@itemx REAL[(M,D)] [ZEROFILL]
+@item DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL]
+@itemx REAL[(M,D)] [UNSIGNED] [ZEROFILL]
These are synonyms for @code{DOUBLE}.
@tindex DECIMAL
-@item DECIMAL[(M[,D])] [ZEROFILL]
+@item DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
-An unpacked floating-point number. Cannot be unsigned. Behaves like a
+An unpacked floating-point number. Behaves like a
@code{CHAR} column: ``unpacked'' means the number is stored as a string,
using one character for each digit of the value. The decimal point and,
-for negative numbers, the @samp{-} sign, are not counted in M (but space
-for these are reserved). If @code{D} is 0, values will have no decimal
+for negative numbers, the @samp{-} sign, are not counted in @code{M} (but
+space for these is reserved). If @code{D} is 0, values will have no decimal
point or fractional part. The maximum range of @code{DECIMAL} values is
the same as for @code{DOUBLE}, but the actual range for a given
@code{DECIMAL} column may be constrained by the choice of @code{M} and
-@code{D}.
+@code{D}. If @code{UNSIGNED} is specified, negative values are disallowed.
-If @code{D} is left out it's set to 0. If @code{M} is left out it's set to 10.
+If @code{D} is omitted, the default is 0. If @code{M} is omitted, the
+default is 10.
-Note that in MySQL Version 3.22 the @code{M} argument had to
-includes the space needed for the sign and the decimal point.
+Prior to MySQL Version 3.23, the @code{M} argument must include the space
+needed for the sign and the decimal point.
+@tindex DEC
@tindex NUMERIC
-@item NUMERIC(M,D) [ZEROFILL]
+@item DEC[(M[,D])] [UNSIGNED] [ZEROFILL]
+@itemx NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL]
-This is a synonym for @code{DECIMAL}.
+These are synonyms for @code{DECIMAL}.
@tindex DATE
@item DATE
@@ -28148,14 +29295,14 @@ recent operation if you don't give it a value yourself. You can also set it
to the current date and time by assigning it a @code{NULL} value. @xref{Date
and time types}.
-A @code{TIMESTAMP} is always stored in 4 bytes. The @code{M} argument only
-affects how the @code{TIMESTAMP} column is displayed.
+The @code{M} argument affects only how a @code{TIMESTAMP} column is displayed;
+its values always are stored using 4 bytes each.
-Note that @code{TIMESTAMP(X)} columns where X is 8 or 14 are reported to
-be numbers while other @code{TIMESTAMP(X)} columns are reported to be
+Note that @code{TIMESTAMP(M)} columns where @code{M} is 8 or 14 are reported to
+be numbers while other @code{TIMESTAMP(M)} columns are reported to be
strings. This is just to ensure that one can reliably dump and restore
the table with these types!
-@xref{DATETIME}.
+@xref{DATETIME, , @code{DATETIME}}.
@tindex TIME
@item TIME
@@ -28163,7 +29310,7 @@ the table with these types!
A time. The range is @code{'-838:59:59'} to @code{'838:59:59'}.
MySQL displays @code{TIME} values in @code{'HH:MM:SS'} format, but
allows you to assign values to @code{TIME} columns using either strings or
-numbers. @xref{TIME}.
+numbers. @xref{TIME, , @code{TIME}}.
@tindex YEAR
@item YEAR[(2|4)]
@@ -28173,7 +29320,7 @@ are @code{1901} to @code{2155}, @code{0000} in the 4-digit year format,
and 1970-2069 if you use the 2-digit format (70-69). MySQL displays
@code{YEAR} values in @code{YYYY} format, but allows you to assign values to
@code{YEAR} columns using either strings or numbers. (The @code{YEAR} type is
-new in MySQL Version 3.22.). @xref{YEAR}.
+unavailable prior to MySQL Version 3.22.) @xref{YEAR, , @code{YEAR}}.
@tindex NATIONAL CHAR
@tindex NCHAR
@@ -28182,14 +29329,15 @@ new in MySQL Version 3.22.). @xref{YEAR}.
@item [NATIONAL] CHAR(M) [BINARY]
A fixed-length string that is always right-padded with spaces to the
-specified length when stored. The range of @code{M} is 1 to 255 characters.
+specified length when stored. The range of @code{M} is 0 to 255 characters
+(1 to 255 prior to MySQL Version 3.23).
Trailing spaces are removed when the value is retrieved. @code{CHAR} values
are sorted and compared in case-insensitive fashion according to the
default character set unless the @code{BINARY} keyword is given.
-@code{NATIONAL CHAR} (short form @code{NCHAR}) is the ANSI SQL way to
-define that a CHAR column should use the default CHARACTER set. This is
-the default in MySQL.
+@code{NATIONAL CHAR} (or its equivalent short form, @code{NCHAR}) is the
+ANSI SQL way to define that a @code{CHAR} column should use the default
+CHARACTER set. This is the default in MySQL.
@code{CHAR} is a shorthand for @code{CHARACTER}.
@@ -28198,26 +29346,22 @@ MySQL allows you to create a column of type
some old applications that depend on the existence of a column but that do not
actually use the value. This is also quite nice when you need a
column that only can take 2 values: A @code{CHAR(0)}, that is not defined
-as @code{NOT NULL}, will only occupy one bit and can only take 2 values:
-@code{NULL} or @code{""}. @xref{CHAR}.
+as @code{NOT NULL}, will occupy only one bit and can take only 2 values:
+@code{NULL} or @code{""}. @xref{CHAR, , @code{CHAR}}.
-@tindex BOOL
-@tindex BIT
-@item BIT
-@itemx BOOL
-@itemx CHAR
-These three are synonyms for @code{CHAR(1)}.
+@item CHAR
+This is a synonym for @code{CHAR(1)}.
@tindex CHARACTER VARYING
@tindex CHAR VARYING
@tindex VARCHAR
@item [NATIONAL] VARCHAR(M) [BINARY]
-A variable-length string. @strong{NOTE:} Trailing spaces are removed when
+A variable-length string. @strong{Note}: trailing spaces are removed when
the value is stored (this differs from the ANSI SQL specification). The range
-of @code{M} is 1 to 255 characters. @code{VARCHAR} values are sorted and
-compared in case-insensitive fashion unless the @code{BINARY} keyword is
-given. @xref{Silent column changes}.
+of @code{M} is 0 to 255 characters (1 to 255 prior to MySQL Version 4.0.2).
+@code{VARCHAR} values are sorted and compared in case-insensitive fashion
+unless the @code{BINARY} keyword is given. @xref{Silent column changes}.
@code{VARCHAR} is a shorthand for @code{CHARACTER VARYING}.
@xref{CHAR}.
@@ -28302,16 +29446,16 @@ types the precision and scale can be (and usually is) specified; for
example:
@example
- salary DECIMAL(9,2)
+ salary DECIMAL(5,2)
@end example
-In this example, @code{9} (@code{precision}) represents the number of
+In this example, @code{5} (@code{precision}) represents the number of
significant decimal digits that will be stored for values, and @code{2}
(@code{scale}) represents the number of digits that will be stored
following the decimal point. In this case, therefore, the range of
values that can be stored in the @code{salary} column is from
-@code{-9999999.99} to @code{9999999.99}.
-(MySQL can actually store numbers up to @code{9999999.99} in this column
+@code{-99.99} to @code{99.99}.
+(MySQL can actually store numbers up to @code{999.99} in this column
because it doesn't have to store the sign for positive numbers)
In ANSI/ISO SQL92, the syntax @code{DECIMAL(p)} is equivalent to
@@ -28343,10 +29487,10 @@ MySQL stores the value representing the corresponding end
point of that range.
As an extension to the ANSI/ISO SQL92 standard, MySQL also
-supports the integral types @code{TINYINT}, @code{MEDIUMINT}, and
+supports the integer types @code{TINYINT}, @code{MEDIUMINT}, and
@code{BIGINT} as listed in the tables above. Another extension is
supported by MySQL for optionally specifying the display width
-of an integral value in parentheses following the base keyword for the
+of an integer value in parentheses following the base keyword for the
type (for example, @code{INT(4)}). This optional width specification is
used to left-pad the display of values whose width is less than the
width specified for the column, but does not constrain the range of
@@ -28361,11 +29505,16 @@ problems when MySQL generates temporary tables for some
complicated joins, as in these cases MySQL trusts that the
data did fit into the original column width.
-All integral types can have an optional (non-standard) attribute
+All integer types can have an optional (non-standard) attribute
@code{UNSIGNED}. Unsigned values can be used when you want to allow
only positive numbers in a column and you need a little bigger numeric
range for the column.
+As of MySQL 4.0.2, floating-point types also can be @code{UNSIGNED}.
+As with integer types, this attribute prevents negative values from
+being stored in the column. Unlike the integer types, the upper range
+of column values remains the same.
+
The @code{FLOAT} type is used to represent approximate numeric data
types. The ANSI/ISO SQL92 standard allows an optional specification of
the precision (but not the range of the exponent) in bits following the
@@ -28385,7 +29534,7 @@ digits when the value is stored.
The @code{REAL} and @code{DOUBLE PRECISION} types do not accept
precision specifications. As an extension to the ANSI/ISO SQL92
-standard, MySQL recognizes @code{DOUBLE} as a synonym for the
+standard, MySQL recognises @code{DOUBLE} as a synonym for the
@code{DOUBLE PRECISION} type. In contrast with the standard's
requirement that the precision for @code{REAL} be smaller than that used
for @code{DOUBLE PRECISION}, MySQL implements both as 8-byte
@@ -28474,10 +29623,10 @@ When MySQL encounters a value for a date or time type that is
out of range or otherwise illegal for the type (see the start of this
section), it converts the value to the ``zero'' value for that type.
(The exception is that out-of-range @code{TIME} values are clipped to
-the appropriate endpoint of the @code{TIME} range.) The table below
+the appropriate endpoint of the @code{TIME} range.) The following table
shows the format of the ``zero'' value for each type:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .15 .55
@item @strong{Column type} @tab @strong{``Zero'' value}
@item @code{DATETIME} @tab @code{'0000-00-00 00:00:00'}
@item @code{DATE} @tab @code{'0000-00-00'}
@@ -28492,8 +29641,8 @@ explicitly using the values shown in the table. You can also do this
using the values @code{'0'} or @code{0}, which are easier to write.
@item
-``Zero'' date or time values used through @strong{MyODBC} are converted
-automatically to @code{NULL} in @strong{MyODBC} Version 2.50.12 and above,
+``Zero'' date or time values used through @code{MyODBC} are converted
+automatically to @code{NULL} in @code{MyODBC} Version 2.50.12 and above,
because ODBC can't handle such values.
@end itemize
@@ -28584,7 +29733,7 @@ You explicitly set the @code{TIMESTAMP} column to @code{NULL}.
@code{TIMESTAMP} columns other than the first may also be set to the current
date and time. Just set the column to @code{NULL} or to @code{NOW()}.
-You can set any @code{TIMESTAMP} column to a value different than the current
+You can set any @code{TIMESTAMP} column to a value different from the current
date and time by setting it explicitly to the desired value. This is true
even for the first @code{TIMESTAMP} column. You can use this property if,
for example, you want a @code{TIMESTAMP} to be set to the current date and
@@ -28594,7 +29743,7 @@ later:
@itemize @bullet
@item
Let MySQL set the column when the row is created.
-This will initialize it to the current date and time.
+This will initialise it to the current date and time.
@item
When you perform subsequent updates to other columns in the row, set
@@ -28602,7 +29751,7 @@ the @code{TIMESTAMP} column explicitly to its current value.
@end itemize
On the other hand, you may find it just as easy to use a @code{DATETIME}
-column that you initialize to @code{NOW()} when the row is created and
+column that you initialise to @code{NOW()} when the row is created and
leave alone for subsequent updates.
@code{TIMESTAMP} values may range from the beginning of 1970 to sometime in
@@ -28610,11 +29759,11 @@ the year 2037, with a resolution of one second. Values are displayed as
numbers.
The format in which MySQL retrieves and displays @code{TIMESTAMP}
-values depends on the display size, as illustrated by the table below. The
+values depends on the display size, as illustrated by the following table. The
`full' @code{TIMESTAMP} format is 14 digits, but @code{TIMESTAMP} columns may
be created with shorter display sizes:
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .20 .25
@item @strong{Column type} @tab @strong{Display format}
@item @code{TIMESTAMP(14)} @tab @code{YYYYMMDDHHMMSS}
@item @code{TIMESTAMP(12)} @tab @code{YYMMDDHHMMSS}
@@ -28705,7 +29854,7 @@ as though padded with leading zeros to the closest length.
@cindex strings, non-delimited
Values specified as non-delimited strings are interpreted using their length
as given. If the string is 8 or 14 characters long, the year is assumed to
-be given by the first 4 characters. Otherwise the year is assumed to be
+be given by the first 4 characters. Otherwise, the year is assumed to be
given by the first 2 characters. The string is interpreted from left to
right to find year, month, day, hour, minute, and second values, for as many
parts as are present in the string. This means you should not use strings
@@ -28785,6 +29934,15 @@ will be converted to @code{'0000-00-00'} because @code{'45'} is not a legal
month.
@item
+The MySQL server only performs basic checking on the validity of a date:
+days @code{00-31}, months @code{00-12}, years @code{1000-9999}.
+Any date not within this range will revert to @code{0000-00-00}.
+Please note that this still allows you to store invalid dates such as
+@code{2002-04-31}. It allows web applications to store data from a form
+without further checking. To ensure a date is valid, perform a check in
+your application.
+
+@item
Year values specified as two digits are ambiguous, because the century is
unknown. MySQL interprets 2-digit year values using the following
rules:
@@ -28817,7 +29975,7 @@ You can specify @code{TIME} values in a variety of formats:
@itemize @bullet
@item
As a string in @code{'D HH:MM:SS.fraction'} format. (Note that
-MySQL doesn't yet store the fraction for the time column). One
+MySQL doesn't yet store the fraction for the time column.) One
can also use one of the following ``relaxed'' syntax:
@code{HH:MM:SS.fraction}, @code{HH:MM:SS}, @code{HH:MM}, @code{D HH:MM:SS},
@@ -28847,14 +30005,14 @@ seconds values that are less than @code{10}. @code{'8:3:2'} is the same as
@code{'08:03:02'}.
Be careful about assigning ``short'' @code{TIME} values to a @code{TIME}
-column. Without semicolon, MySQL interprets values using the
-assumption that the rightmost digits represent seconds. (MySQL
-interprets @code{TIME} values as elapsed time rather than as time of
-day.) For example, you might think of @code{'1112'} and @code{1112} as
+column. Without colons, MySQL interprets values using the
+assumption that the rightmost digits represent seconds. (MySQL
+interprets @code{TIME} values as elapsed time rather than as time of
+day.) For example, you might think of @code{'1112'} and @code{1112} as
meaning @code{'11:12:00'} (12 minutes after 11 o'clock), but
MySQL interprets them as @code{'00:11:12'} (11 minutes, 12 seconds).
Similarly, @code{'12'} and @code{12} are interpreted as @code{'00:00:12'}.
-@code{TIME} values with semicolon, instead, are always treated as
+@code{TIME} values with colons, by contrast, are always treated as
time of the day. That is @code{'11:12'} will mean @code{'11:12:00'},
not @code{'00:11:12'}.
@@ -28900,9 +30058,9 @@ As a two-digit number in the range @code{1} to @code{99}. Values in the
ranges @code{1} to @code{69} and @code{70} to @code{99} are converted to
@code{YEAR} values in the ranges @code{2001} to @code{2069} and @code{1970}
to @code{1999}. Note that the range for two-digit numbers is slightly
-different than the range for two-digit strings, because you cannot specify zero
+different from the range for two-digit strings, because you cannot specify zero
directly as a number and have it be interpreted as @code{2000}. You
-@emph{must} specify it as a string @code{'0'} or @code{'00'} or it will be
+@strong{must} specify it as a string @code{'0'} or @code{'00'} or it will be
interpreted as @code{0000}.
@item
@@ -28959,14 +30117,14 @@ SQL specification.)
If you assign a value to a @code{CHAR} or @code{VARCHAR} column that
exceeds the column's maximum length, the value is truncated to fit.
-The table below illustrates the differences between the two types of columns
+The following table illustrates the differences between the two types of columns
by showing the result of storing various string values into @code{CHAR(4)}
and @code{VARCHAR(4)} columns:
@c Need to use @(space) to make sure second column values retain spacing
@c in output for table below.
-@multitable @columnfractions .2 .15 .2 .2 .25
+@multitable @columnfractions .15 .15 .20 .15 .20
@item @strong{Value} @tab @code{CHAR(4)} @tab @strong{Storage required} @tab @code{VARCHAR(4)} @tab @strong{Storage required}
@item @code{''} @tab @code{'@ @ @ @ '} @tab 4 bytes @tab @code{''} @tab 1 byte
@item @code{'ab'} @tab @code{'ab@ @ '} @tab 4 bytes @tab @code{'ab'} @tab 3 bytes
@@ -29039,7 +30197,7 @@ when values are stored, as there is for @code{VARCHAR} columns.
@code{BLOB} and @code{TEXT} columns cannot have @code{DEFAULT} values.
@end itemize
-@strong{MyODBC} defines @code{BLOB} values as @code{LONGVARBINARY} and
+@code{MyODBC} defines @code{BLOB} values as @code{LONGVARBINARY} and
@code{TEXT} values as @code{LONGVARCHAR}.
Because @code{BLOB} and @code{TEXT} values may be extremely long, you
@@ -29053,8 +30211,8 @@ object. The standard way to do this is with the @code{SUBSTRING}
function. For example:
@example
-mysql> select comment from tbl_name,substring(comment,20) as substr
- ORDER BY substr;
+mysql> SELECT comment FROM tbl_name,SUBSTRING(comment,20) AS substr
+ -> ORDER BY substr;
@end example
If you don't do this, only the first @code{max_sort_length} bytes of the
@@ -29064,10 +30222,8 @@ column are used when sorting. The default value of @code{max_sort_length} is
@code{TEXT} values by specifying the column position or by using an alias:
@example
-mysql> select id,substring(blob_col,1,100) from tbl_name
- GROUP BY 2;
-mysql> select id,substring(blob_col,1,100) as b from tbl_name
- GROUP BY b;
+mysql> SELECT id,SUBSTRING(blob_col,1,100) FROM tbl_name GROUP BY 2;
+mysql> SELECT id,SUBSTRING(blob_col,1,100) AS b FROM tbl_name GROUP BY b;
@end example
@item
@@ -29100,7 +30256,9 @@ certain circumstances:
@item
If you insert an invalid value into an @code{ENUM} (that is, a string not
present in the list of allowed values), the empty string is inserted
-instead as a special error value.
+instead as a special error value. This string can be distinguished from a
+'normal' empty string by the fact that this string has the numerical value
+0. More about this later.
@item
If an @code{ENUM} is declared @code{NULL}, @code{NULL} is also a legal value
@@ -29130,9 +30288,9 @@ The index of the @code{NULL} value is @code{NULL}.
@end itemize
For example, a column specified as @code{ENUM("one", "two", "three")} can
-have any of the values shown below. The index of each value is also shown:
+have any of the values shown here. The index of each value is also shown:
-@multitable @columnfractions .2 .8
+@multitable @columnfractions .10 .10
@item @strong{Value} @tab @strong{Index}
@item @code{NULL} @tab @code{NULL}
@item @code{""} @tab 0
@@ -29143,6 +30301,9 @@ have any of the values shown below. The index of each value is also shown:
An enumeration can have a maximum of 65535 elements.
+Starting from 3.23.51 trailing spaces are automatically deleted from
+@code{ENUM} values when the table is created.
+
Lettercase is irrelevant when you assign values to an @code{ENUM} column.
However, values retrieved from the column later have lettercase matching the
values that were used to specify the allowable values at table creation time.
@@ -29159,6 +30320,8 @@ If you store a number into an @code{ENUM}, the number is treated as an
index, and the value stored is the enumeration member with that index.
(However, this will not work with @code{LOAD DATA}, which treats all
input as strings.)
+It's not advisable to store numbers in an @code{ENUM} string because
+it will make things confusing.
@code{ENUM} values are sorted according to the order in which the enumeration
members were listed in the column specification. (In other words,
@@ -29197,6 +30360,9 @@ any of these values:
A @code{SET} can have a maximum of 64 different members.
+Starting from 3.23.51 trailing spaces are automatically deleted from
+@code{SET} values when the table is created.
+
MySQL stores @code{SET} values numerically, with the low-order bit
of the stored value corresponding to the first set member. If you retrieve a
@code{SET} value in a numeric context, the value retrieved has bits set
@@ -29213,7 +30379,7 @@ set members in the column value. Suppose a column is specified as
@code{SET("a","b","c","d")}. Then the members have the following bit
values:
-@multitable @columnfractions .2 .2 .6
+@multitable @columnfractions .15 .20 .20
@item @code{SET} @strong{member} @tab @strong{Decimal value} @tab @strong{Binary value}
@item @code{a} @tab @code{1} @tab @code{0001}
@item @code{b} @tab @code{2} @tab @code{0010}
@@ -29234,6 +30400,9 @@ specified at table creation time. For example, if a column is specified as
@code{SET("a","b","c","d")}, then @code{"a,d"}, @code{"d,a"}, and
@code{"d,a,a,d,d"} will all appear as @code{"a,d"} when retrieved.
+If you set a @code{SET} column to an unsupported value, the value will
+be ignored.
+
@code{SET} values are sorted numerically. @code{NULL} values sort before
non-@code{NULL} @code{SET} values.
@@ -29289,11 +30458,11 @@ and convert results back to floating-point values only when necessary.
@cindex columns, other types
To make it easier to use code written for SQL implementations from other
-vendors, MySQL maps column types as shown in the table below. These
+vendors, MySQL maps column types as shown in the following table. These
mappings make it easier to move table definitions from other database engines
to MySQL:
-@multitable @columnfractions .4 .6
+@multitable @columnfractions .25 .30
@item @strong{Other vendor type} @tab @strong{MySQL type}
@item @code{BINARY(NUM)} @tab @code{CHAR(NUM) BINARY}
@item @code{CHAR VARYING(NUM)} @tab @code{VARCHAR(NUM)}
@@ -29323,14 +30492,14 @@ MySQL types.
@cindex columns, storage requirements
The storage requirements for each of the column types supported by
-MySQL are listed below by category.
+MySQL are listed by category.
@cindex numeric types
@cindex types, numeric
@subsubheading Storage requirements for numeric types
-@multitable @columnfractions .5 .5
+@multitable @columnfractions .35 .65
@item @strong{Column type} @tab @strong{Storage required}
@item @code{TINYINT} @tab 1 byte
@item @code{SMALLINT} @tab 2 bytes
@@ -29354,7 +30523,7 @@ MySQL are listed below by category.
@subsubheading Storage requirements for date and time types
-@multitable @columnfractions .5 .5
+@multitable @columnfractions .35 .65
@item @strong{Column type} @tab @strong{Storage required}
@item @code{DATE} @tab 3 bytes
@item @code{DATETIME} @tab 8 bytes
@@ -29365,7 +30534,7 @@ MySQL are listed below by category.
@subsubheading Storage requirements for string types
-@multitable @columnfractions .5 .5
+@multitable @columnfractions .35 .65
@item @strong{Column type} @tab @strong{Storage required}
@item @code{CHAR(M)} @tab @code{M} bytes, @code{1 <= M <= 255}
@item @code{VARCHAR(M)} @tab @code{L}+1 bytes, where @code{L <= M} and
@@ -29430,8 +30599,8 @@ An expression that contains @code{NULL} always produces a @code{NULL} value
unless otherwise indicated in the documentation for the operators and
functions involved in the expression.
-@strong{NOTE:} There must be no whitespace between a function name and the
-parenthesis following it. This helps the MySQL parser distinguish
+@strong{Note}: there must be no whitespace between a function name and the
+parentheses following it. This helps the MySQL parser distinguish
between function calls and references to tables or columns that happen to
have the same name as a function. Spaces around arguments are permitted,
though.
@@ -29446,7 +30615,7 @@ For the sake of brevity, examples display the output from the @code{mysql}
program in abbreviated form. So this:
@example
-mysql> select MOD(29,9);
+mysql> SELECT MOD(29,9);
1 rows in set (0.00 sec)
+-----------+
@@ -29459,7 +30628,7 @@ mysql> select MOD(29,9);
is displayed like this:
@example
-mysql> select MOD(29,9);
+mysql> SELECT MOD(29,9);
-> 2
@end example
@@ -29468,7 +30637,9 @@ mysql> select MOD(29,9);
* String functions:: String functions
* Numeric Functions:: Numeric Functions
* Date and time functions:: Date and time functions
+* Cast Functions:: Cast Functions
* Other Functions:: Other Functions
+* Group by functions:: Functions for Use with @code{GROUP BY} Clauses
@end menu
@@ -29476,15 +30647,15 @@ mysql> select MOD(29,9);
@subsection Non-Type-Specific Operators and Functions
@menu
-* Parenthesis:: Parenthesis
+* Parentheses:: Parentheses
* Comparison Operators:: Comparison Operators
* Logical Operators:: Logical Operators
* Control flow functions:: Control Flow Functions
@end menu
-@node Parenthesis, Comparison Operators, Non-typed Operators, Non-typed Operators
-@subsubsection Parenthesis
+@node Parentheses, Comparison Operators, Non-typed Operators, Non-typed Operators
+@subsubsection Parentheses
@findex () (parentheses)
@findex parentheses ( and )
@@ -29496,19 +30667,19 @@ mysql> select MOD(29,9);
( ... )
@end example
-Use parenthesis to force the order of evaluation in an expression. For
+Use parentheses to force the order of evaluation in an expression. For
example:
@example
-mysql> select 1+2*3;
+mysql> SELECT 1+2*3;
-> 7
-mysql> select (1+2)*3;
+mysql> SELECT (1+2)*3;
-> 9
@end example
-@node Comparison Operators, Logical Operators, Parenthesis, Non-typed Operators
+@node Comparison Operators, Logical Operators, Parentheses, Non-typed Operators
@subsubsection Comparison Operators
@findex comparison operators
@@ -29556,7 +30727,7 @@ By default, string comparisons are done in case-independent fashion using the
current character set (ISO-8859-1 Latin1 by default, which also works
excellently for English).
-The examples below illustrate conversion of strings to numbers for comparison
+The following examples illustrate conversion of strings to numbers for comparison
operations:
@example
@@ -29576,15 +30747,15 @@ mysql> SELECT 0 = 'x6';
@item =
Equal:
@example
-mysql> select 1 = 0;
+mysql> SELECT 1 = 0;
-> 0
-mysql> select '0' = 0;
+mysql> SELECT '0' = 0;
-> 1
-mysql> select '0.0' = 0;
+mysql> SELECT '0.0' = 0;
-> 1
-mysql> select '0.01' = 0;
+mysql> SELECT '0.01' = 0;
-> 0
-mysql> select '.01' = 0.01;
+mysql> SELECT '.01' = 0.01;
-> 1
@end example
@@ -29596,11 +30767,11 @@ mysql> select '.01' = 0.01;
@itemx !=
Not equal:
@example
-mysql> select '.01' <> '0.01';
+mysql> SELECT '.01' <> '0.01';
-> 1
-mysql> select .01 <> '0.01';
+mysql> SELECT .01 <> '0.01';
-> 0
-mysql> select 'zapp' <> 'zappp';
+mysql> SELECT 'zapp' <> 'zappp';
-> 1
@end example
@@ -29609,7 +30780,7 @@ mysql> select 'zapp' <> 'zappp';
@item <=
Less than or equal:
@example
-mysql> select 0.1 <= 2;
+mysql> SELECT 0.1 <= 2;
-> 1
@end example
@@ -29618,7 +30789,7 @@ mysql> select 0.1 <= 2;
@item <
Less than:
@example
-mysql> select 2 < 2;
+mysql> SELECT 2 < 2;
-> 0
@end example
@@ -29627,7 +30798,7 @@ mysql> select 2 < 2;
@item >=
Greater than or equal:
@example
-mysql> select 2 >= 2;
+mysql> SELECT 2 >= 2;
-> 1
@end example
@@ -29636,16 +30807,16 @@ mysql> select 2 >= 2;
@item >
Greater than:
@example
-mysql> select 2 > 2;
+mysql> SELECT 2 > 2;
-> 0
@end example
@cindex @code{NULL}, testing for null
@findex <=> (Equal to)
@item <=>
-Null safe equal:
+NULL safe equal:
@example
-mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
+mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
-> 1 1 0
@end example
@@ -29654,14 +30825,40 @@ mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
@findex IS NOT NULL
@item IS NULL
@itemx IS NOT NULL
-Test whether or not a value is or is not @code{NULL}:
+Test whether a value is or is not @code{NULL}:
@example
-mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL;
+mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
-> 0 0 1
-mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
+mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
-> 1 1 0
@end example
+@cindex ODBC compatibility
+@cindex compatibility, with ODBC
+To be able to work good with other programs, MySQL supports the following
+extra features when using @code{IS NULL}:
+
+@itemize @bullet
+@item
+You can find the last inserted row with:
+
+@example
+SELECT * FROM tbl_name WHERE auto_col IS NULL
+@end example
+
+This can be disabled by setting @code{SQL_AUTO_IS_NULL=0}. @xref{SET OPTION}.
+@item
+For @code{NOT NULL} @code{DATE} and @code{DATETIME} columns you can find
+the special date @code{0000-00-00} by using:
+
+@example
+SELECT * FROM tbl_name WHERE date_column IS NULL
+@end example
+
+This is needed to get some ODBC applications to work (as ODBC doesn't
+support a @code{0000-00-00} date)
+@end itemize
+
@findex BETWEEN ... AND
@item expr BETWEEN min AND max
If @code{expr} is greater than or equal to @code{min} and @code{expr} is
@@ -29689,16 +30886,20 @@ Otherwise, a floating-point (real) comparison is done.
@end itemize
@example
-mysql> select 1 BETWEEN 2 AND 3;
+mysql> SELECT 1 BETWEEN 2 AND 3;
-> 0
-mysql> select 'b' BETWEEN 'a' AND 'c';
+mysql> SELECT 'b' BETWEEN 'a' AND 'c';
-> 1
-mysql> select 2 BETWEEN 2 AND '3';
+mysql> SELECT 2 BETWEEN 2 AND '3';
-> 1
-mysql> select 2 BETWEEN 2 AND 'x-3';
+mysql> SELECT 2 BETWEEN 2 AND 'x-3';
-> 0
@end example
+@findex NOT BETWEEN
+@item expr NOT BETWEEN min AND max
+Same as @code{NOT (expr BETWEEN min AND max)}.
+
@findex IN
@item expr IN (value,...)
Returns @code{1} if @code{expr} is any of the values in the @code{IN} list,
@@ -29710,9 +30911,9 @@ is a case-sensitive string expression, the string comparison is performed in
case-sensitive fashion:
@example
-mysql> select 2 IN (0,3,5,'wefwf');
+mysql> SELECT 2 IN (0,3,5,'wefwf');
-> 0
-mysql> select 'wefwf' IN (0,3,5,'wefwf');
+mysql> SELECT 'wefwf' IN (0,3,5,'wefwf');
-> 1
@end example
@@ -29725,9 +30926,9 @@ Same as @code{NOT (expr IN (value,...))}.
If @code{expr} is @code{NULL}, @code{ISNULL()} returns @code{1}, otherwise
it returns @code{0}:
@example
-mysql> select ISNULL(1+1);
+mysql> SELECT ISNULL(1+1);
-> 0
-mysql> select ISNULL(1/0);
+mysql> SELECT ISNULL(1/0);
-> 1
@end example
@@ -29740,9 +30941,9 @@ false!
Returns first non-@code{NULL} element in list:
@example
-mysql> select COALESCE(NULL,1);
+mysql> SELECT COALESCE(NULL,1);
-> 1
-mysql> select COALESCE(NULL,NULL,NULL);
+mysql> SELECT COALESCE(NULL,NULL,NULL);
-> NULL
@end example
@@ -29754,21 +30955,21 @@ and so on. All arguments are treated as integers. It is required that
to work correctly. This is because a binary search is used (very fast):
@example
-mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
+mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
-> 3
-mysql> select INTERVAL(10, 1, 10, 100, 1000);
+mysql> SELECT INTERVAL(10, 1, 10, 100, 1000);
-> 2
-mysql> select INTERVAL(22, 23, 30, 44, 200);
+mysql> SELECT INTERVAL(22, 23, 30, 44, 200);
-> 0
@end example
@end table
-If you are comparing case sensitive string with any of the standard
-operators (@code{=}, @code{<>}..., but not @code{LIKE}) end space will
-be ignored.
+If you are comparing case-insensitive strings with any of the standard
+operators (@code{=}, @code{<>}..., but not @code{LIKE}) trailing whitespace
+(spaces, tabs and newlines) will be ignored.
@example
-mysql> select "a" ="A ";
+mysql> SELECT "a" ="A \n";
-> 1
@end example
@@ -29776,10 +30977,10 @@ mysql> select "a" ="A ";
@node Logical Operators, Control flow functions, Comparison Operators, Non-typed Operators
@subsubsection Logical Operators
-@findex Logical functions
-@findex Functions, logical
+@findex Logical operators
+@findex Operators, logical
-All logical functions return @code{1} (TRUE), @code{0} (FALSE) or
+All logical operators evaluate to @code{1} (TRUE), @code{0} (FALSE) or
@code{NULL} (unknown, which is in most cases the same as FALSE):
@table @code
@@ -29787,34 +30988,34 @@ All logical functions return @code{1} (TRUE), @code{0} (FALSE) or
@findex ! (logical NOT)
@item NOT
@itemx !
-Logical NOT. Returns @code{1} if the argument is @code{0}, otherwise returns
-@code{0}.
-Exception: @code{NOT NULL} returns @code{NULL}:
+Logical NOT. Evaluates to @code{1} if the operand is @code{0}, otherwise
+evaluates to @code{0}.
+Exception: @code{NOT NULL} evaluates to @code{NULL}:
@example
-mysql> select NOT 1;
+mysql> SELECT NOT 1;
-> 0
-mysql> select NOT NULL;
+mysql> SELECT NOT NULL;
-> NULL
-mysql> select ! (1+1);
+mysql> SELECT ! (1+1);
-> 0
-mysql> select ! 1+1;
+mysql> SELECT ! 1+1;
-> 1
@end example
-The last example returns @code{1} because the expression evaluates
+The last example produces @code{1} because the expression evaluates
the same way as @code{(!1)+1}.
@findex OR, logical
@findex || (logical OR)
@item OR
@itemx ||
-Logical OR. Returns @code{1} if either argument is not @code{0} and not
+Logical OR. Evaluates to @code{1} if either operand is not @code{0} and not
@code{NULL}:
@example
-mysql> select 1 || 0;
+mysql> SELECT 1 || 0;
-> 1
-mysql> select 0 || 0;
+mysql> SELECT 0 || 0;
-> 0
-mysql> select 1 || NULL;
+mysql> SELECT 1 || NULL;
-> 1
@end example
@@ -29823,14 +31024,33 @@ mysql> select 1 || NULL;
@findex && (logical AND)
@item AND
@itemx &&
-Logical AND. Returns @code{0} if either argument is @code{0} or @code{NULL},
-otherwise returns @code{1}:
+Logical AND. For non-@code{NULL} operands, evaluates to @code{1} if both
+operands are non-zero and to @code{0} otherwise.
+Produces @code{NULL} if either operand is @code{NULL}:
@example
-mysql> select 1 && NULL;
+mysql> SELECT 1 && 1;
+ -> 1
+mysql> SELECT 1 && 0;
-> 0
-mysql> select 1 && 0;
+mysql> SELECT 1 && NULL;
+ -> NULL
+@end example
+
+@findex XOR, logical
+@item XOR
+Logical XOR. For non-@code{NULL} operands, evaluates to @code{1} if only one
+of the operators is non-zero.
+Produces @code{NULL} if either operand is @code{NULL}:
+@example
+mysql> SELECT 1 XOR 1;
-> 0
+mysql> SELECT 1 XOR 0;
+ -> 1
+mysql> SELECT 1 XOR NULL;
+ -> NULL
@end example
+
+@code{a XOR b} is equal to @code{(a AND (NOT b)) OR ((NOT a) and b)}.
@end table
@@ -29848,13 +31068,13 @@ If @code{expr1} is not @code{NULL}, @code{IFNULL()} returns @code{expr1},
else it returns @code{expr2}. @code{IFNULL()} returns a numeric or string
value, depending on the context in which it is used:
@example
-mysql> select IFNULL(1,0);
+mysql> SELECT IFNULL(1,0);
-> 1
-mysql> select IFNULL(NULL,10);
+mysql> SELECT IFNULL(NULL,10);
-> 10
-mysql> select IFNULL(1/0,10);
+mysql> SELECT IFNULL(1/0,10);
-> 10
-mysql> select IFNULL(1/0,'yes');
+mysql> SELECT IFNULL(1/0,'yes');
-> 'yes'
@end example
@@ -29863,9 +31083,9 @@ mysql> select IFNULL(1/0,'yes');
If @code{expr1 = expr2} is true, return @code{NULL} else return @code{expr1}.
This is the same as @code{CASE WHEN x = y THEN NULL ELSE x END}:
@example
-mysql> select NULLIF(1,1);
+mysql> SELECT NULLIF(1,1);
-> NULL
-mysql> select NULLIF(1,2);
+mysql> SELECT NULLIF(1,2);
-> 1
@end example
@@ -29880,11 +31100,11 @@ If @code{expr1} is TRUE (@code{expr1 <> 0} and @code{expr1 <> NULL}) then
in which it is used:
@example
-mysql> select IF(1>2,2,3);
+mysql> SELECT IF(1>2,2,3);
-> 3
-mysql> select IF(1<2,'yes','no');
+mysql> SELECT IF(1<2,'yes','no');
-> 'yes'
-mysql> select IF(strcmp('test','test1'),'no','yes');
+mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
-> 'no'
@end example
@@ -29893,9 +31113,9 @@ testing floating-point or string values, you should do so using a comparison
operation:
@example
-mysql> select IF(0.1,1,0);
+mysql> SELECT IF(0.1,1,0);
-> 0
-mysql> select IF(0.1<>0,1,0);
+mysql> SELECT IF(0.1<>0,1,0);
-> 1
@end example
@@ -29909,15 +31129,15 @@ The default return type of @code{IF()} (which may matter when it is
stored into a temporary table) is calculated in MySQL Version
3.23 as follows:
-@multitable @columnfractions .55 .45
+@multitable @columnfractions .50 .20
@item @strong{Expression} @tab @strong{Return value}
@item expr2 or expr3 returns string @tab string
@item expr2 or expr3 returns a floating-point value @tab floating-point
@item expr2 or expr3 returns an integer @tab integer
@end multitable
-If expr2 and expr3 are strings, then the result is case sensitive if
-both strings are case sensitive. (Starting from 3.23.51)
+If expr2 and expr3 are strings, then the result is case-sensitive if
+both strings are case-sensitive. (Starting from 3.23.51)
@findex CASE
@item CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
@@ -29930,11 +31150,12 @@ value, then the result after @code{ELSE} is returned. If there is no
@code{ELSE} part then @code{NULL} is returned:
@example
-mysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END;
+mysql> SELECT CASE 1 WHEN 1 THEN "one"
+ WHEN 2 THEN "two" ELSE "more" END;
-> "one"
mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END;
-> "true"
-mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
+mysql> SELECT CASE BINARY "B" WHEN "a" THEN 1 WHEN "b" THEN 2 END;
-> NULL
@end example
@end table
@@ -29965,11 +31186,11 @@ Returns the ASCII code value of the leftmost character of the string
@code{NULL} if @code{str} is @code{NULL}:
@example
-mysql> select ASCII('2');
+mysql> SELECT ASCII('2');
-> 50
-mysql> select ASCII(2);
+mysql> SELECT ASCII(2);
-> 50
-mysql> select ASCII('dx');
+mysql> SELECT ASCII('dx');
-> 100
@end example
@@ -29977,15 +31198,15 @@ See also the @code{ORD()} function.
@findex ORD()
@item ORD(str)
-If the leftmost character of the string str is a multi-byte character,
-returns the code of multi-byte character by returning the ASCII code value
-of the character in the format of:
+If the leftmost character of the string @code{str} is a multi-byte character,
+returns the code for that character, calculated from the ASCII code values
+of its constituent characters using this formula:
@code{((first byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]}.
If the leftmost character is not a multi-byte character, returns the same
-value as the like @code{ASCII()} function does:
+value that the @code{ASCII()} function does:
@example
-mysql> select ORD('2');
+mysql> SELECT ORD('2');
-> 50
@end example
@@ -30001,13 +31222,13 @@ signed number. Otherwise, @code{N} is treated as unsigned. @code{CONV} works
with 64-bit precision:
@example
-mysql> select CONV("a",16,2);
+mysql> SELECT CONV("a",16,2);
-> '1010'
-mysql> select CONV("6E",18,8);
+mysql> SELECT CONV("6E",18,8);
-> '172'
-mysql> select CONV(-17,10,-18);
+mysql> SELECT CONV(-17,10,-18);
-> '-H'
-mysql> select CONV(10+"10"+'10'+0xa,10,10);
+mysql> SELECT CONV(10+"10"+'10'+0xa,10,10);
-> '40'
@end example
@@ -30018,7 +31239,7 @@ Returns a string representation of the binary value of @code{N}, where
@code{CONV(N,10,2)}. Returns @code{NULL} if @code{N} is @code{NULL}:
@example
-mysql> select BIN(12);
+mysql> SELECT BIN(12);
-> '1100'
@end example
@@ -30029,19 +31250,28 @@ Returns a string representation of the octal value of @code{N}, where
Returns @code{NULL} if @code{N} is @code{NULL}:
@example
-mysql> select OCT(12);
+mysql> SELECT OCT(12);
-> '14'
@end example
@findex HEX()
-@item HEX(N)
-Returns a string representation of the hexadecimal value of @code{N}, where
-@code{N} is a longlong (@code{BIGINT}) number. This is equivalent to
-@code{CONV(N,10,16)}. Returns @code{NULL} if @code{N} is @code{NULL}:
+@item HEX(N_or_S)
+
+If N_OR_S is a number, returns a string representation of the hexadecimal
+value of @code{N}, where @code{N} is a longlong (@code{BIGINT}) number.
+This is equivalent to @code{CONV(N,10,16)}.
+
+If N_OR_S is a string, returns a hexadecimal string of N_OR_S where each
+character in N_OR_S is converted to 2 hexadecimal digits. This is the
+invers of the @code{0xff} strings.
@example
-mysql> select HEX(255);
+mysql> SELECT HEX(255);
-> 'FF'
+mysql> SELECT HEX("abc");
+ -> 616263
+mysql> SELECT 0x616263;
+ -> "abc"
@end example
@findex CHAR()
@@ -30051,9 +31281,9 @@ consisting of the characters given by the ASCII code values of those
integers. @code{NULL} values are skipped:
@example
-mysql> select CHAR(77,121,83,81,'76');
+mysql> SELECT CHAR(77,121,83,81,'76');
-> 'MySQL'
-mysql> select CHAR(77,77.3,'77.3');
+mysql> SELECT CHAR(77,77.3,'77.3');
-> 'MMM'
@end example
@@ -30064,11 +31294,11 @@ Returns the string that results from concatenating the arguments. Returns
A numeric argument is converted to the equivalent string form:
@example
-mysql> select CONCAT('My', 'S', 'QL');
+mysql> SELECT CONCAT('My', 'S', 'QL');
-> 'MySQL'
-mysql> select CONCAT('My', NULL, 'QL');
+mysql> SELECT CONCAT('My', NULL, 'QL');
-> NULL
-mysql> select CONCAT(14.3);
+mysql> SELECT CONCAT(14.3);
-> '14.3'
@end example
@@ -30084,9 +31314,9 @@ separator argument. The separator will be added between the strings to be
concatenated:
@example
-mysql> select CONCAT_WS(",","First name","Second name","Last Name");
+mysql> SELECT CONCAT_WS(",","First name","Second name","Last Name");
-> 'First name,Second name,Last Name'
-mysql> select CONCAT_WS(",","First name",NULL,"Last Name");
+mysql> SELECT CONCAT_WS(",","First name",NULL,"Last Name");
-> 'First name,Last Name'
@end example
@@ -30101,14 +31331,23 @@ mysql> select CONCAT_WS(",","First name",NULL,"Last Name");
Returns the length of the string @code{str}:
@example
-mysql> select LENGTH('text');
+mysql> SELECT LENGTH('text');
-> 4
-mysql> select OCTET_LENGTH('text');
+mysql> SELECT OCTET_LENGTH('text');
-> 4
@end example
-Note that for @code{CHAR_LENGTH()}, multi-byte characters are only counted
-once.
+Note that for @code{CHAR_LENGTH()} and @code{CHARACTER_LENGTH()}, multi-byte
+characters are only counted once.
+
+@findex BIT_LENGTH()
+@item BIT_LENGTH(str)
+Returns the length of the string @code{str} in bits:
+
+@example
+mysql> SELECT BIT_LENGTH('text');
+ -> 32
+@end example
@findex LOCATE()
@findex POSITION()
@@ -30118,13 +31357,15 @@ Returns the position of the first occurrence of substring @code{substr}
in string @code{str}. Returns @code{0} if @code{substr} is not in @code{str}:
@example
-mysql> select LOCATE('bar', 'foobarbar');
+mysql> SELECT LOCATE('bar', 'foobarbar');
-> 4
-mysql> select LOCATE('xbar', 'foobar');
+mysql> SELECT LOCATE('xbar', 'foobar');
-> 0
@end example
-This function is multi-byte safe.
+This function is multi-byte safe. In MySQL 3.23 this function is case
+sensitive, while in 4.0 it's only case-sensitive if either argument is
+a binary string.
@findex LOCATE()
@item LOCATE(substr,str,pos)
@@ -30133,11 +31374,13 @@ string @code{str}, starting at position @code{pos}.
Returns @code{0} if @code{substr} is not in @code{str}:
@example
-mysql> select LOCATE('bar', 'foobarbar',5);
+mysql> SELECT LOCATE('bar', 'foobarbar',5);
-> 7
@end example
-This function is multi-byte safe.
+This function is multi-byte safe. In MySQL 3.23 this function is case
+sensitive, while in 4.0 it's only case-sensitive if either argument is
+a binary string.
@findex INSTR()
@item INSTR(str,substr)
@@ -30146,13 +31389,15 @@ string @code{str}. This is the same as the two-argument form of
@code{LOCATE()}, except that the arguments are swapped:
@example
-mysql> select INSTR('foobarbar', 'bar');
+mysql> SELECT INSTR('foobarbar', 'bar');
-> 4
-mysql> select INSTR('xbar', 'foobar');
+mysql> SELECT INSTR('xbar', 'foobar');
-> 0
@end example
-This function is multi-byte safe.
+This function is multi-byte safe. In MySQL 3.23 this function is case
+sensitive, while in 4.0 it's only case-sensitive if either argument is
+a binary string.
@findex LPAD()
@item LPAD(str,len,padstr)
@@ -30161,7 +31406,7 @@ until @code{str} is @code{len} characters long. If @code{str} is longer
than @code{len'} then it will be shortened to @code{len} characters.
@example
-mysql> select LPAD('hi',4,'??');
+mysql> SELECT LPAD('hi',4,'??');
-> '??hi'
@end example
@@ -30173,7 +31418,7 @@ Returns the string @code{str}, right-padded with the string
@code{len} characters.
@example
-mysql> select RPAD('hi',5,'?');
+mysql> SELECT RPAD('hi',5,'?');
-> 'hi???'
@end example
@@ -30182,7 +31427,7 @@ mysql> select RPAD('hi',5,'?');
Returns the leftmost @code{len} characters from the string @code{str}:
@example
-mysql> select LEFT('foobarbar', 5);
+mysql> SELECT LEFT('foobarbar', 5);
-> 'fooba'
@end example
@@ -30193,7 +31438,7 @@ This function is multi-byte safe.
Returns the rightmost @code{len} characters from the string @code{str}:
@example
-mysql> select RIGHT('foobarbar', 4);
+mysql> SELECT RIGHT('foobarbar', 4);
-> 'rbar'
@end example
@@ -30209,7 +31454,7 @@ starting at position @code{pos}.
The variant form that uses @code{FROM} is ANSI SQL92 syntax:
@example
-mysql> select SUBSTRING('Quadratically',5,6);
+mysql> SELECT SUBSTRING('Quadratically',5,6);
-> 'ratica'
@end example
@@ -30221,9 +31466,9 @@ This function is multi-byte safe.
Returns a substring from string @code{str} starting at position @code{pos}:
@example
-mysql> select SUBSTRING('Quadratically',5);
+mysql> SELECT SUBSTRING('Quadratically',5);
-> 'ratically'
-mysql> select SUBSTRING('foobarbar' FROM 4);
+mysql> SELECT SUBSTRING('foobarbar' FROM 4);
-> 'barbar'
@end example
@@ -30239,9 +31484,9 @@ If @code{count} is negative, everything to the right of the final delimiter
(counting from the right) is returned:
@example
-mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
+mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
-> 'www.mysql'
-mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
+mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
-> 'mysql.com'
@end example
@@ -30252,7 +31497,7 @@ This function is multi-byte safe.
Returns the string @code{str} with leading space characters removed:
@example
-mysql> select LTRIM(' barbar');
+mysql> SELECT LTRIM(' barbar');
-> 'barbar'
@end example
@@ -30261,7 +31506,7 @@ mysql> select LTRIM(' barbar');
Returns the string @code{str} with trailing space characters removed:
@example
-mysql> select RTRIM('barbar ');
+mysql> SELECT RTRIM('barbar ');
-> 'barbar'
@end example
@@ -30275,13 +31520,13 @@ removed. If none of the specifiers @code{BOTH}, @code{LEADING} or
specified, spaces are removed:
@example
-mysql> select TRIM(' bar ');
+mysql> SELECT TRIM(' bar ');
-> 'bar'
-mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
+mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
-> 'barxxx'
-mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
+mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
-> 'bar'
-mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
+mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
-> 'barx'
@end example
@@ -30298,9 +31543,9 @@ in the given string. All international alpha characters outside the A-Z range
are treated as vowels:
@example
-mysql> select SOUNDEX('Hello');
+mysql> SELECT SOUNDEX('Hello');
-> 'H400'
-mysql> select SOUNDEX('Quadratically');
+mysql> SELECT SOUNDEX('Quadratically');
-> 'Q36324'
@end example
@@ -30309,7 +31554,7 @@ mysql> select SOUNDEX('Quadratically');
Returns a string consisting of @code{N} space characters:
@example
-mysql> select SPACE(6);
+mysql> SELECT SPACE(6);
-> ' '
@end example
@@ -30319,7 +31564,7 @@ Returns the string @code{str} with all all occurrences of the string
@code{from_str} replaced by the string @code{to_str}:
@example
-mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
+mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
-> 'WwWwWw.mysql.com'
@end example
@@ -30332,7 +31577,7 @@ times. If @code{count <= 0}, returns an empty string. Returns @code{NULL} if
@code{str} or @code{count} are @code{NULL}:
@example
-mysql> select REPEAT('MySQL', 3);
+mysql> SELECT REPEAT('MySQL', 3);
-> 'MySQLMySQLMySQL'
@end example
@@ -30341,7 +31586,7 @@ mysql> select REPEAT('MySQL', 3);
Returns the string @code{str} with the order of the characters reversed:
@example
-mysql> select REVERSE('abc');
+mysql> SELECT REVERSE('abc');
-> 'cba'
@end example
@@ -30354,7 +31599,7 @@ Returns the string @code{str}, with the substring beginning at position
@code{newstr}:
@example
-mysql> select INSERT('Quadratic', 3, 4, 'What');
+mysql> SELECT INSERT('Quadratic', 3, 4, 'What');
-> 'QuWhattic'
@end example
@@ -30368,9 +31613,9 @@ or greater than the number of arguments. @code{ELT()} is the complement of
@code{FIELD()}:
@example
-mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
+mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
-> 'ej'
-mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
+mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
-> 'foo'
@end example
@@ -30382,9 +31627,9 @@ Returns @code{0} if @code{str} is not found.
@code{FIELD()} is the complement of @code{ELT()}:
@example
-mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
+mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 2
-mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
+mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 0
@end example
@@ -30394,7 +31639,7 @@ Returns a value @code{1} to @code{N} if the string @code{str} is in the list
@code{strlist} consisting of @code{N} substrings. A string list is a string
composed of substrings separated by @samp{,} characters. If the first
argument is a constant string and the second is a column of type @code{SET},
-the @code{FIND_IN_SET()} function is optimized to use bit arithmetic!
+the @code{FIND_IN_SET()} function is optimised to use bit arithmetic!
Returns @code{0} if @code{str} is not in @code{strlist} or if @code{strlist}
is the empty string. Returns @code{NULL} if either argument is @code{NULL}.
This function will not work properly if the first argument contains a
@@ -30430,7 +31675,7 @@ with 'separator' (default ',') and only 'number_of_bits' (default 64) of
'bits' is used:
@example
-mysql> select EXPORT_SET(5,'Y','N',',',4)
+mysql> SELECT EXPORT_SET(5,'Y','N',',',4)
-> Y,N,Y,N
@end example
@@ -30443,7 +31688,7 @@ according to the current character set mapping (the default is ISO-8859-1
Latin1):
@example
-mysql> select LCASE('QUADRATICALLY');
+mysql> SELECT LCASE('QUADRATICALLY');
-> 'quadratically'
@end example
@@ -30458,7 +31703,7 @@ according to the current character set mapping (the default is ISO-8859-1
Latin1):
@example
-mysql> select UCASE('Hej');
+mysql> SELECT UCASE('Hej');
-> 'HEJ'
@end example
@@ -30469,14 +31714,14 @@ This function is multi-byte safe.
@item LOAD_FILE(file_name)
Reads the file and returns the file contents as a string. The file
must be on the server, you must specify the full pathname to the
-file, and you must have the @strong{file} privilege. The file must
+file, and you must have the @code{FILE} privilege. The file must
be readable by all and be smaller than @code{max_allowed_packet}.
If the file doesn't exist or can't be read due to one of the above reasons,
the function returns @code{NULL}:
@example
-mysql> UPDATE table_name
+mysql> UPDATE tbl_name
SET blob_column=LOAD_FILE("/tmp/picture")
WHERE id=1;
@end example
@@ -30508,7 +31753,7 @@ a binary string. This only affects comparisons.
@menu
* String comparison functions:: String Comparison Functions
-* Case Sensitivity Operators:: Case Sensitivity
+* Case Sensitivity Operators:: Case-Sensitivity
@end menu
@node String comparison functions, Case Sensitivity Operators, String functions, String functions
@@ -30517,10 +31762,10 @@ a binary string. This only affects comparisons.
@findex string comparison functions
@findex functions, string comparison
-@cindex case sensitivity, in string comparisons
-@cindex string comparisons, case sensitivity
+@cindex case-sensitivity, in string comparisons
+@cindex string comparisons, case-sensitivity
-Normally, if any expression in a string comparison is case sensitive, the
+Normally, if any expression in a string comparison is case-sensitive, the
comparison is performed in case-sensitive fashion.
@table @code
@@ -30528,49 +31773,51 @@ comparison is performed in case-sensitive fashion.
@item expr LIKE pat [ESCAPE 'escape-char']
Pattern matching using
SQL simple regular expression comparison. Returns @code{1} (TRUE) or @code{0}
-(FALSE). With @code{LIKE} you can use the following two wild-card characters
+(FALSE). With @code{LIKE} you can use the following two wildcard characters
in the pattern:
-@multitable @columnfractions .1 .9
+@multitable @columnfractions .10 .60
+@item @strong{Char} @tab @strong{Description}
@item @code{%} @tab Matches any number of characters, even zero characters
@item @code{_} @tab Matches exactly one character
@end multitable
@example
-mysql> select 'David!' LIKE 'David_';
+mysql> SELECT 'David!' LIKE 'David_';
-> 1
-mysql> select 'David!' LIKE '%D%v%';
+mysql> SELECT 'David!' LIKE '%D%v%';
-> 1
@end example
-To test for literal instances of a wild-card character, precede the character
+To test for literal instances of a wildcard character, precede the character
with the escape character. If you don't specify the @code{ESCAPE} character,
@samp{\} is assumed:
-@multitable @columnfractions .1 .9
+@multitable @columnfractions .10 .60
+@item @strong{String} @tab @strong{Description}
@item @code{\%} @tab Matches one @code{%} character
@item @code{\_} @tab Matches one @code{_} character
@end multitable
@example
-mysql> select 'David!' LIKE 'David\_';
+mysql> SELECT 'David!' LIKE 'David\_';
-> 0
-mysql> select 'David_' LIKE 'David\_';
+mysql> SELECT 'David_' LIKE 'David\_';
-> 1
@end example
To specify a different escape character, use the @code{ESCAPE} clause:
@example
-mysql> select 'David_' LIKE 'David|_' ESCAPE '|';
+mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
-> 1
@end example
The following two statements illustrate that string comparisons are
-case insensitive unless one of the operands is a binary string:
+case-insensitive unless one of the operands is a binary string:
@example
-mysql> select 'abc' LIKE 'ABC';
+mysql> SELECT 'abc' LIKE 'ABC';
-> 1
mysql> SELECT 'abc' LIKE BINARY 'ABC';
-> 0
@@ -30580,7 +31827,7 @@ mysql> SELECT 'abc' LIKE BINARY 'ABC';
extension to the ANSI SQL @code{LIKE}.)
@example
-mysql> select 10 LIKE '1%';
+mysql> SELECT 10 LIKE '1%';
-> 1
@end example
@@ -30608,18 +31855,18 @@ returns @code{0}. @code{RLIKE} is a synonym for @code{REGEXP}, provided for
@code{mSQL} compatibility. Note: Because MySQL uses the C escape
syntax in strings (for example, @samp{\n}), you must double any @samp{\} that
you use in your @code{REGEXP} strings. As of MySQL Version 3.23.4,
-@code{REGEXP} is case insensitive for normal (not binary) strings:
+@code{REGEXP} is case-insensitive for normal (not binary) strings:
@example
-mysql> select 'Monty!' REGEXP 'm%y%%';
+mysql> SELECT 'Monty!' REGEXP 'm%y%%';
-> 0
-mysql> select 'Monty!' REGEXP '.*';
+mysql> SELECT 'Monty!' REGEXP '.*';
-> 1
-mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line';
+mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
-> 1
-mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A";
+mysql> SELECT "a" REGEXP "A", "a" REGEXP BINARY "A";
-> 1 0
-mysql> select "a" REGEXP "^[a-d]";
+mysql> SELECT "a" REGEXP "^[a-d]";
-> 1
@end example
@@ -30640,30 +31887,28 @@ argument is smaller than the second according to the current sort order,
and @code{1} otherwise:
@example
-mysql> select STRCMP('text', 'text2');
+mysql> SELECT STRCMP('text', 'text2');
-> -1
-mysql> select STRCMP('text2', 'text');
+mysql> SELECT STRCMP('text2', 'text');
-> 1
-mysql> select STRCMP('text', 'text');
+mysql> SELECT STRCMP('text', 'text');
-> 0
@end example
@findex MATCH ... AGAINST()
@item MATCH (col1,col2,...) AGAINST (expr)
+@itemx MATCH (col1,col2,...) AGAINST (expr IN BOOLEAN MODE)
@code{MATCH ... AGAINST()} is used for full-text search and returns
relevance - similarity measure between the text in columns
@code{(col1,col2,...)} and the query @code{expr}. Relevance is a
positive floating-point number. Zero relevance means no similarity.
-For @code{MATCH ... AGAINST()} to work, a @strong{FULLTEXT} index
-must be created first. @xref{CREATE TABLE, , @code{CREATE TABLE}}.
-@code{MATCH ... AGAINST()} is available in MySQL Version
-3.23.23 or later. For details and usage examples
-@pxref{Fulltext Search}.
+@code{MATCH ... AGAINST()} is available in MySQL version
+3.23.23 or later. @code{IN BOOLEAN MODE} extension was added in version
+4.0.1. For details and usage examples, see @ref{Fulltext Search}.
@end table
-
@node Case Sensitivity Operators, , String comparison functions, String functions
-@subsubsection Case Sensitivity
+@subsubsection Case-Sensitivity
@findex casts
@@ -30674,15 +31919,17 @@ must be created first. @xref{CREATE TABLE, , @code{CREATE TABLE}}.
@findex BINARY
@item @code{BINARY}
The @code{BINARY} operator casts the string following it to a binary string.
-This is an easy way to force a column comparison to be case sensitive even
+This is an easy way to force a column comparison to be case-sensitive even
if the column isn't defined as @code{BINARY} or @code{BLOB}:
@example
-mysql> select "a" = "A";
+mysql> SELECT "a" = "A";
-> 1
-mysql> select BINARY "a" = "A";
+mysql> SELECT BINARY "a" = "A";
-> 0
@end example
+@code{BINARY string} is a shorthand for @code{CAST(string AS BINARY)}.
+@xref{Cast Functions}.
@code{BINARY} was introduced in MySQL Version 3.23.0.
Note that in some context MySQL will not be able to use the
@@ -30712,9 +31959,13 @@ make string comparison even more flexible.
@node Arithmetic functions, Mathematical functions, Numeric Functions, Numeric Functions
@subsubsection Arithmetic Operations
+@cindex operators, cast
The usual arithmetic operators are available. Note that in the case of
@samp{-}, @samp{+}, and @samp{*}, the result is calculated with
@code{BIGINT} (64-bit) precision if both arguments are integers!
+If one of the argument is an unsigned integer, and the other argument
+is also an integer, the result will be an unsigned integer.
+@xref{Cast Functions}.
@cindex operations, arithmetic
@cindex arithmetic expressions
@@ -30724,7 +31975,7 @@ The usual arithmetic operators are available. Note that in the case of
@item +
Addition:
@example
-mysql> select 3+5;
+mysql> SELECT 3+5;
-> 8
@end example
@@ -30733,7 +31984,7 @@ mysql> select 3+5;
@item -
Subtraction:
@example
-mysql> select 3-5;
+mysql> SELECT 3-5;
-> -2
@end example
@@ -30742,30 +31993,31 @@ mysql> select 3-5;
@item *
Multiplication:
@example
-mysql> select 3*5;
+mysql> SELECT 3*5;
-> 15
-mysql> select 18014398509481984*18014398509481984.0;
+mysql> SELECT 18014398509481984*18014398509481984.0;
-> 324518553658426726783156020576256.0
-mysql> select 18014398509481984*18014398509481984;
+mysql> SELECT 18014398509481984*18014398509481984;
-> 0
@end example
-The result of the last expression is incorrect because the result of the integer
-multiplication exceeds the 64-bit range of @code{BIGINT} calculations.
+The result of the last expression is incorrect because the result of the
+integer multiplication exceeds the 64-bit range of @code{BIGINT}
+calculations.
@findex / (division)
@findex division (/)
@item /
Division:
@example
-mysql> select 3/5;
+mysql> SELECT 3/5;
-> 0.60
@end example
Division by zero produces a @code{NULL} result:
@example
-mysql> select 102/(1-1);
+mysql> SELECT 102/(1-1);
-> NULL
@end example
@@ -30788,7 +32040,7 @@ All mathematical functions return @code{NULL} in case of an error.
@item -
Unary minus. Changes the sign of the argument:
@example
-mysql> select - 2;
+mysql> SELECT - 2;
-> -2
@end example
@@ -30800,9 +32052,9 @@ may have the value of @code{-2^63}!
@item ABS(X)
Returns the absolute value of @code{X}:
@example
-mysql> select ABS(2);
+mysql> SELECT ABS(2);
-> 2
-mysql> select ABS(-32);
+mysql> SELECT ABS(-32);
-> 32
@end example
@@ -30813,11 +32065,11 @@ This function is safe to use with @code{BIGINT} values.
Returns the sign of the argument as @code{-1}, @code{0}, or @code{1}, depending
on whether @code{X} is negative, zero, or positive:
@example
-mysql> select SIGN(-32);
+mysql> SELECT SIGN(-32);
-> -1
-mysql> select SIGN(0);
+mysql> SELECT SIGN(0);
-> 0
-mysql> select SIGN(234);
+mysql> SELECT SIGN(234);
-> 1
@end example
@@ -30829,11 +32081,11 @@ mysql> select SIGN(234);
Modulo (like the @code{%} operator in C).
Returns the remainder of @code{N} divided by @code{M}:
@example
-mysql> select MOD(234, 10);
+mysql> SELECT MOD(234, 10);
-> 4
-mysql> select 253 % 7;
+mysql> SELECT 253 % 7;
-> 1
-mysql> select MOD(29,9);
+mysql> SELECT MOD(29,9);
-> 2
@end example
@@ -30843,9 +32095,9 @@ This function is safe to use with @code{BIGINT} values.
@item FLOOR(X)
Returns the largest integer value not greater than @code{X}:
@example
-mysql> select FLOOR(1.23);
+mysql> SELECT FLOOR(1.23);
-> 1
-mysql> select FLOOR(-1.23);
+mysql> SELECT FLOOR(-1.23);
-> -2
@end example
@@ -30855,9 +32107,9 @@ Note that the return value is converted to a @code{BIGINT}!
@item CEILING(X)
Returns the smallest integer value not less than @code{X}:
@example
-mysql> select CEILING(1.23);
+mysql> SELECT CEILING(1.23);
-> 2
-mysql> select CEILING(-1.23);
+mysql> SELECT CEILING(-1.23);
-> -1
@end example
@@ -30867,18 +32119,18 @@ Note that the return value is converted to a @code{BIGINT}!
@item ROUND(X)
Returns the argument @code{X}, rounded to the nearest integer:
@example
-mysql> select ROUND(-1.23);
+mysql> SELECT ROUND(-1.23);
-> -1
-mysql> select ROUND(-1.58);
+mysql> SELECT ROUND(-1.58);
-> -2
-mysql> select ROUND(1.58);
+mysql> SELECT ROUND(1.58);
-> 2
@end example
-Note that the behavior of @code{ROUND()} when the argument
+Note that the behaviour of @code{ROUND()} when the argument
is half way between two integers depends on the C library
implementation. Some round to the nearest even number,
-always up, always down, or always towards zero. If you need
+always up, always down, or always toward zero. If you need
one kind of rounding, you should use a well-defined function
like @code{TRUNCATE()} or @code{FLOOR()} instead.
@@ -30889,9 +32141,9 @@ If @code{D} is @code{0}, the result will have no decimal point or fractional
part:
@example
-mysql> select ROUND(1.298, 1);
+mysql> SELECT ROUND(1.298, 1);
-> 1.3
-mysql> select ROUND(1.298, 0);
+mysql> SELECT ROUND(1.298, 0);
-> 1
@end example
@@ -30900,32 +32152,32 @@ mysql> select ROUND(1.298, 0);
Returns the value of @code{e} (the base of natural logarithms) raised to
the power of @code{X}:
@example
-mysql> select EXP(2);
+mysql> SELECT EXP(2);
-> 7.389056
-mysql> select EXP(-2);
+mysql> SELECT EXP(-2);
-> 0.135335
@end example
@findex LOG()
@item LOG(X)
Returns the natural logarithm of @code{X}:
@example
-mysql> select LOG(2);
+mysql> SELECT LOG(2);
-> 0.693147
-mysql> select LOG(-2);
+mysql> SELECT LOG(-2);
-> NULL
@end example
-If you want the log of a number @code{X} to some arbitary base @code{B}, use
+If you want the log of a number @code{X} to some arbitrary base @code{B}, use
the formula @code{LOG(X)/LOG(B)}.
@findex LOG10()
@item LOG10(X)
Returns the base-10 logarithm of @code{X}:
@example
-mysql> select LOG10(2);
+mysql> SELECT LOG10(2);
-> 0.301030
-mysql> select LOG10(100);
+mysql> SELECT LOG10(100);
-> 2.000000
-mysql> select LOG10(-100);
+mysql> SELECT LOG10(-100);
-> NULL
@end example
@@ -30935,9 +32187,9 @@ mysql> select LOG10(-100);
@itemx POWER(X,Y)
Returns the value of @code{X} raised to the power of @code{Y}:
@example
-mysql> select POW(2,2);
+mysql> SELECT POW(2,2);
-> 4.000000
-mysql> select POW(2,-2);
+mysql> SELECT POW(2,-2);
-> 0.250000
@end example
@@ -30945,9 +32197,9 @@ mysql> select POW(2,-2);
@item SQRT(X)
Returns the non-negative square root of @code{X}:
@example
-mysql> select SQRT(4);
+mysql> SELECT SQRT(4);
-> 2.000000
-mysql> select SQRT(20);
+mysql> SELECT SQRT(20);
-> 4.472136
@end example
@@ -30956,7 +32208,7 @@ mysql> select SQRT(20);
Returns the value of PI. The default shown number of decimals is 5, but
MySQL internally uses the full double precession for PI.
@example
-mysql> select PI();
+mysql> SELECT PI();
-> 3.141593
mysql> SELECT PI()+0.000000000000000000;
-> 3.141592653589793116
@@ -30966,7 +32218,7 @@ mysql> SELECT PI()+0.000000000000000000;
@item COS(X)
Returns the cosine of @code{X}, where @code{X} is given in radians:
@example
-mysql> select COS(PI());
+mysql> SELECT COS(PI());
-> -1.000000
@end example
@@ -30974,7 +32226,7 @@ mysql> select COS(PI());
@item SIN(X)
Returns the sine of @code{X}, where @code{X} is given in radians:
@example
-mysql> select SIN(PI());
+mysql> SELECT SIN(PI());
-> 0.000000
@end example
@@ -30982,7 +32234,7 @@ mysql> select SIN(PI());
@item TAN(X)
Returns the tangent of @code{X}, where @code{X} is given in radians:
@example
-mysql> select TAN(PI()+1);
+mysql> SELECT TAN(PI()+1);
-> 1.557408
@end example
@@ -30992,11 +32244,11 @@ Returns the arc cosine of @code{X}, that is, the value whose cosine is
@code{X}. Returns @code{NULL} if @code{X} is not in the range @code{-1} to
@code{1}:
@example
-mysql> select ACOS(1);
+mysql> SELECT ACOS(1);
-> 0.000000
-mysql> select ACOS(1.0001);
+mysql> SELECT ACOS(1.0001);
-> NULL
-mysql> select ACOS(0);
+mysql> SELECT ACOS(0);
-> 1.570796
@end example
@@ -31006,9 +32258,9 @@ Returns the arc sine of @code{X}, that is, the value whose sine is
@code{X}. Returns @code{NULL} if @code{X} is not in the range @code{-1} to
@code{1}:
@example
-mysql> select ASIN(0.2);
+mysql> SELECT ASIN(0.2);
-> 0.201358
-mysql> select ASIN('foo');
+mysql> SELECT ASIN('foo');
-> 0.000000
@end example
@@ -31017,9 +32269,9 @@ mysql> select ASIN('foo');
Returns the arc tangent of @code{X}, that is, the value whose tangent is
@code{X}:
@example
-mysql> select ATAN(2);
+mysql> SELECT ATAN(2);
-> 1.107149
-mysql> select ATAN(-2);
+mysql> SELECT ATAN(-2);
-> -1.107149
@end example
@@ -31031,9 +32283,9 @@ similar to calculating the arc tangent of @code{Y / X}, except that the
signs of both arguments are used to determine the quadrant of the
result:
@example
-mysql> select ATAN(-2,2);
+mysql> SELECT ATAN(-2,2);
-> -0.785398
-mysql> select ATAN2(PI(),0);
+mysql> SELECT ATAN2(PI(),0);
-> 1.570796
@end example
@@ -31041,9 +32293,9 @@ mysql> select ATAN2(PI(),0);
@item COT(X)
Returns the cotangent of @code{X}:
@example
-mysql> select COT(12);
+mysql> SELECT COT(12);
-> -1.57267341
-mysql> select COT(0);
+mysql> SELECT COT(0);
-> NULL
@end example
@@ -31053,17 +32305,18 @@ mysql> select COT(0);
Returns a random floating-point value in the range @code{0} to @code{1.0}.
If an integer argument @code{N} is specified, it is used as the seed value:
@example
-mysql> select RAND();
- -> 0.5925
-mysql> select RAND(20);
- -> 0.1811
-mysql> select RAND(20);
- -> 0.1811
-mysql> select RAND();
- -> 0.2079
-mysql> select RAND();
- -> 0.7888
+mysql> SELECT RAND();
+ -> 0.9233482386203
+mysql> SELECT RAND(20);
+ -> 0.15888261251047
+mysql> SELECT RAND(20);
+ -> 0.15888261251047
+mysql> SELECT RAND();
+ -> 0.63553050033332
+mysql> SELECT RAND();
+ -> 0.70100469486881
@end example
+
You can't use a column with @code{RAND()} values in an @code{ORDER BY}
clause, because @code{ORDER BY} would evaluate the column multiple times.
In MySQL Version 3.23, you can, however, do:
@@ -31075,6 +32328,10 @@ table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000}.
Note that a @code{RAND()} in a @code{WHERE} clause will be re-evaluated
every time the @code{WHERE} is executed.
+@code{RAND()} is not meant to be a perfect random generator, but instead a
+fast way to generate ad hoc random numbers that will be portable between
+platforms for the same MySQL version.
+
@findex LEAST()
@item LEAST(X,Y,...)
With two or more arguments, returns the smallest (minimum-valued) argument.
@@ -31098,11 +32355,11 @@ In other cases, the arguments are compared as case-insensitive strings:
@end itemize
@example
-mysql> select LEAST(2,0);
+mysql> SELECT LEAST(2,0);
-> 0
-mysql> select LEAST(34.0,3.0,5.0,767.0);
+mysql> SELECT LEAST(34.0,3.0,5.0,767.0);
-> 3.0
-mysql> select LEAST("B","A","C");
+mysql> SELECT LEAST("B","A","C");
-> "A"
@end example
In MySQL versions prior to Version 3.22.5, you can use @code{MIN()}
@@ -31113,11 +32370,11 @@ instead of @code{LEAST}.
Returns the largest (maximum-valued) argument.
The arguments are compared using the same rules as for @code{LEAST}:
@example
-mysql> select GREATEST(2,0);
+mysql> SELECT GREATEST(2,0);
-> 2
-mysql> select GREATEST(34.0,3.0,5.0,767.0);
+mysql> SELECT GREATEST(34.0,3.0,5.0,767.0);
-> 767.0
-mysql> select GREATEST("B","A","C");
+mysql> SELECT GREATEST("B","A","C");
-> "C"
@end example
In MySQL versions prior to Version 3.22.5, you can use @code{MAX()}
@@ -31127,7 +32384,7 @@ instead of @code{GREATEST}.
@item DEGREES(X)
Returns the argument @code{X}, converted from radians to degrees:
@example
-mysql> select DEGREES(PI());
+mysql> SELECT DEGREES(PI());
-> 180.000000
@end example
@@ -31135,7 +32392,7 @@ mysql> select DEGREES(PI());
@item RADIANS(X)
Returns the argument @code{X}, converted from degrees to radians:
@example
-mysql> select RADIANS(90);
+mysql> SELECT RADIANS(90);
-> 1.570796
@end example
@@ -31144,13 +32401,13 @@ mysql> select RADIANS(90);
Returns the number @code{X}, truncated to @code{D} decimals. If @code{D}
is @code{0}, the result will have no decimal point or fractional part:
@example
-mysql> select TRUNCATE(1.223,1);
+mysql> SELECT TRUNCATE(1.223,1);
-> 1.2
-mysql> select TRUNCATE(1.999,1);
+mysql> SELECT TRUNCATE(1.999,1);
-> 1.9
-mysql> select TRUNCATE(1.999,0);
+mysql> SELECT TRUNCATE(1.999,0);
-> 1
-mysql> select TRUNCATE(-1.999,1);
+mysql> SELECT TRUNCATE(-1.999,1);
-> -1.9
@end example
@@ -31159,7 +32416,7 @@ Starting from MySQL 3.23.51 all numbers are rounded towards zero.
If @code{D} is negative, then the whole part of the number is zeroed out:
@example
-mysql> select truncate(122,-2);
+mysql> SELECT TRUNCATE(122,-2);
-> 100
@end example
@@ -31169,16 +32426,15 @@ result:
@cindex rounding errors
@example
-mysql> select TRUNCATE(10.28*100,0);
+mysql> SELECT TRUNCATE(10.28*100,0);
-> 1027
@end example
-The above happens because 10.28 is actually stored as something like
+The above happens because 10.28 is actually stored as something like
10.2799999999999999.
@end table
-
-@node Date and time functions, Other Functions, Numeric Functions, Functions
+@node Date and time functions, Cast Functions, Numeric Functions, Functions
@subsection Date and Time Functions
@findex date and time functions
@@ -31188,11 +32444,11 @@ See @ref{Date and time types} for a description of the range of values
each type has and the valid formats in which date and time values may be
specified.
-Here is an example that uses date functions. The query below selects
+Here is an example that uses date functions. The following query selects
all records with a @code{date_col} value from within the last 30 days:
@example
-mysql> SELECT something FROM table
+mysql> SELECT something FROM tbl_name
WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
@end example
@@ -31205,7 +32461,7 @@ for @code{date} (@code{1} = Sunday, @code{2} = Monday, ... @code{7} =
Saturday). These index values correspond to the ODBC standard:
@example
-mysql> select DAYOFWEEK('1998-02-03');
+mysql> SELECT DAYOFWEEK('1998-02-03');
-> 3
@end example
@@ -31215,9 +32471,9 @@ Returns the weekday index for
@code{date} (@code{0} = Monday, @code{1} = Tuesday, ... @code{6} = Sunday):
@example
-mysql> select WEEKDAY('1997-10-04 22:23:00');
+mysql> SELECT WEEKDAY('1997-10-04 22:23:00');
-> 5
-mysql> select WEEKDAY('1997-11-05');
+mysql> SELECT WEEKDAY('1997-11-05');
-> 2
@end example
@@ -31227,7 +32483,7 @@ Returns the day of the month for @code{date}, in the range @code{1} to
@code{31}:
@example
-mysql> select DAYOFMONTH('1998-02-03');
+mysql> SELECT DAYOFMONTH('1998-02-03');
-> 3
@end example
@@ -31237,7 +32493,7 @@ Returns the day of the year for @code{date}, in the range @code{1} to
@code{366}:
@example
-mysql> select DAYOFYEAR('1998-02-03');
+mysql> SELECT DAYOFYEAR('1998-02-03');
-> 34
@end example
@@ -31246,7 +32502,7 @@ mysql> select DAYOFYEAR('1998-02-03');
Returns the month for @code{date}, in the range @code{1} to @code{12}:
@example
-mysql> select MONTH('1998-02-03');
+mysql> SELECT MONTH('1998-02-03');
-> 2
@end example
@@ -31255,7 +32511,7 @@ mysql> select MONTH('1998-02-03');
Returns the name of the weekday for @code{date}:
@example
-mysql> select DAYNAME("1998-02-05");
+mysql> SELECT DAYNAME("1998-02-05");
-> 'Thursday'
@end example
@@ -31264,7 +32520,7 @@ mysql> select DAYNAME("1998-02-05");
Returns the name of the month for @code{date}:
@example
-mysql> select MONTHNAME("1998-02-05");
+mysql> SELECT MONTHNAME("1998-02-05");
-> 'February'
@end example
@@ -31274,7 +32530,7 @@ Returns the quarter of the year for @code{date}, in the range @code{1}
to @code{4}:
@example
-mysql> select QUARTER('98-04-01');
+mysql> SELECT QUARTER('98-04-01');
-> 2
@end example
@@ -31290,22 +32546,25 @@ second argument is @code{0}, on Monday if the second argument is
@code{1}:
@example
-mysql> select WEEK('1998-02-20');
+mysql> SELECT WEEK('1998-02-20');
-> 7
-mysql> select WEEK('1998-02-20',0);
+mysql> SELECT WEEK('1998-02-20',0);
-> 7
-mysql> select WEEK('1998-02-20',1);
+mysql> SELECT WEEK('1998-02-20',1);
-> 8
-mysql> select WEEK('1998-12-31',1);
+mysql> SELECT WEEK('1998-12-31',1);
-> 53
@end example
+Note: in Version 4.0, @code{WEEK(#,0)} was changed to match the
+calendar in the USA.
+
@findex YEAR()
@item YEAR(date)
Returns the year for @code{date}, in the range @code{1000} to @code{9999}:
@example
-mysql> select YEAR('98-02-03');
+mysql> SELECT YEAR('98-02-03');
-> 1998
@end example
@@ -31317,7 +32576,7 @@ different from the year in the date argument for the first and the last
week of the year:
@example
-mysql> select YEARWEEK('1987-01-01');
+mysql> SELECT YEARWEEK('1987-01-01');
-> 198653
@end example
@@ -31326,7 +32585,7 @@ mysql> select YEARWEEK('1987-01-01');
Returns the hour for @code{time}, in the range @code{0} to @code{23}:
@example
-mysql> select HOUR('10:05:03');
+mysql> SELECT HOUR('10:05:03');
-> 10
@end example
@@ -31335,7 +32594,7 @@ mysql> select HOUR('10:05:03');
Returns the minute for @code{time}, in the range @code{0} to @code{59}:
@example
-mysql> select MINUTE('98-02-03 10:05:03');
+mysql> SELECT MINUTE('98-02-03 10:05:03');
-> 5
@end example
@@ -31344,7 +32603,7 @@ mysql> select MINUTE('98-02-03 10:05:03');
Returns the second for @code{time}, in the range @code{0} to @code{59}:
@example
-mysql> select SECOND('10:05:03');
+mysql> SELECT SECOND('10:05:03');
-> 3
@end example
@@ -31353,10 +32612,10 @@ mysql> select SECOND('10:05:03');
Adds @code{N} months to period @code{P} (in the format @code{YYMM} or
@code{YYYYMM}). Returns a value in the format @code{YYYYMM}.
-Note that the period argument @code{P} is @emph{not} a date value:
+Note that the period argument @code{P} is @strong{not} a date value:
@example
-mysql> select PERIOD_ADD(9801,2);
+mysql> SELECT PERIOD_ADD(9801,2);
-> 199803
@end example
@@ -31365,11 +32624,11 @@ mysql> select PERIOD_ADD(9801,2);
Returns the number of months between periods @code{P1} and @code{P2}.
@code{P1} and @code{P2} should be in the format @code{YYMM} or @code{YYYYMM}.
-Note that the period arguments @code{P1} and @code{P2} are @emph{not}
+Note that the period arguments @code{P1} and @code{P2} are @strong{not}
date values:
@example
-mysql> select PERIOD_DIFF(9802,199703);
+mysql> SELECT PERIOD_DIFF(9802,199703);
-> 11
@end example
@@ -31389,7 +32648,7 @@ Version 3.22. @code{ADDDATE()} and @code{SUBDATE()} are synonyms for
In MySQL Version 3.23, you can use @code{+} and @code{-} instead of
@code{DATE_ADD()} and @code{DATE_SUB()} if the expression on the right side is
-a date or datetime column. (See example)
+a date or datetime column. (See example below.)
@code{date} is a @code{DATETIME} or @code{DATE} value specifying the starting
date. @code{expr} is an expression specifying the interval value to be added
@@ -31403,7 +32662,7 @@ interval from the date.
The following table shows how the @code{type} and @code{expr} arguments
are related:
-@multitable @columnfractions .5 .5
+@multitable @columnfractions .25 .45
@item @code{type} @strong{value} @tab @strong{Expected} @code{expr} @strong{format}
@item @code{SECOND} @tab @code{SECONDS}
@item @code{MINUTE} @tab @code{MINUTES}
@@ -31424,7 +32683,7 @@ MySQL allows any punctuation delimiter in the @code{expr} format.
Those shown in the table are the suggested delimiters. If the @code{date}
argument is a @code{DATE} value and your calculations involve only
@code{YEAR}, @code{MONTH}, and @code{DAY} parts (that is, no time parts), the
-result is a @code{DATE} value. Otherwise the result is a @code{DATETIME}
+result is a @code{DATE} value. Otherwise, the result is a @code{DATETIME}
value:
@example
@@ -31435,19 +32694,19 @@ mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
-> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
- INTERVAL 1 SECOND);
+ -> INTERVAL 1 SECOND);
-> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
- INTERVAL 1 DAY);
+ -> INTERVAL 1 DAY);
-> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
- INTERVAL "1:1" MINUTE_SECOND);
+ -> INTERVAL "1:1" MINUTE_SECOND);
-> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
- INTERVAL "1 1:1:1" DAY_SECOND);
+ -> INTERVAL "1 1:1:1" DAY_SECOND);
-> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
- INTERVAL "-1 10" DAY_HOUR);
+ -> INTERVAL "-1 10" DAY_HOUR);
-> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
-> 1997-12-02
@@ -31470,9 +32729,9 @@ contains a time part, the date value will be automatically converted to a
datetime value:
@example
-mysql> select date_add("1999-01-01", interval 1 day);
+mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 DAY);
-> 1999-01-02
-mysql> select date_add("1999-01-01", interval 1 hour);
+mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 HOUR);
-> 1999-01-01 01:00:00
@end example
@@ -31482,12 +32741,12 @@ has a day that is larger than the maximum day for the new month, the day is
adjusted to the maximum days in the new month:
@example
-mysql> select DATE_ADD('1998-01-30', Interval 1 month);
+mysql> SELECT DATE_ADD('1998-01-30', INTERVAL 1 MONTH);
-> 1998-02-28
@end example
Note from the preceding example that the word @code{INTERVAL} and the
-@code{type} keyword are not case sensitive.
+@code{type} keyword are not case-sensitive.
@findex EXTRACT()
@item EXTRACT(type FROM date)
@@ -31511,9 +32770,9 @@ Given a date @code{date}, returns a daynumber (the number of days since year
0):
@example
-mysql> select TO_DAYS(950501);
+mysql> SELECT TO_DAYS(950501);
-> 728779
-mysql> select TO_DAYS('1997-10-07');
+mysql> SELECT TO_DAYS('1997-10-07');
-> 729669
@end example
@@ -31526,7 +32785,7 @@ days that were lost when the calendar was changed.
Given a daynumber @code{N}, returns a @code{DATE} value:
@example
-mysql> select FROM_DAYS(729669);
+mysql> SELECT FROM_DAYS(729669);
-> '1997-10-07'
@end example
@@ -31538,7 +32797,8 @@ the days that were lost when the calendar was changed.
@item DATE_FORMAT(date,format)
Formats the @code{date} value according to the @code{format} string. The
following specifiers may be used in the @code{format} string:
-@multitable @columnfractions .1 .6
+@multitable @columnfractions .10 .65
+@item @strong{Specifier} @tab @strong{Description}
@item @code{%M} @tab Month name (@code{January}..@code{December})
@item @code{%W} @tab Weekday name (@code{Sunday}..@code{Saturday})
@item @code{%D} @tab Day of the month with English suffix (@code{1st}, @code{2nd}, @code{3rd}, etc.)
@@ -31565,27 +32825,27 @@ following specifiers may be used in the @code{format} string:
@item @code{%s} @tab Seconds (@code{00}..@code{59})
@item @code{%p} @tab @code{AM} or @code{PM}
@item @code{%w} @tab Day of the week (@code{0}=Sunday..@code{6}=Saturday)
-@item @code{%U} @tab Week (@code{0}..@code{53}), where Sunday is the first day of the week
-@item @code{%u} @tab Week (@code{0}..@code{53}), where Monday is the first day of the week
-@item @code{%V} @tab Week (@code{1}..@code{53}), where Sunday is the first day of the week. Used with '%X'
-@item @code{%v} @tab Week (@code{1}..@code{53}), where Monday is the first day of the week. Used with '%x'
+@item @code{%U} @tab Week (@code{00}..@code{53}), where Sunday is the first day of the week
+@item @code{%u} @tab Week (@code{00}..@code{53}), where Monday is the first day of the week
+@item @code{%V} @tab Week (@code{01}..@code{53}), where Sunday is the first day of the week. Used with '%X'
+@item @code{%v} @tab Week (@code{01}..@code{53}), where Monday is the first day of the week. Used with '%x'
@item @code{%%} @tab A literal @samp{%}.
@end multitable
All other characters are just copied to the result without interpretation:
@example
-mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
+mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-> 'Saturday October 1997'
-mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
+mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
-mysql> select DATE_FORMAT('1997-10-04 22:23:00',
+mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%D %y %a %d %m %b %j');
-> '4th 97 Sat 04 10 Oct 277'
-mysql> select DATE_FORMAT('1997-10-04 22:23:00',
+mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
-mysql> select DATE_FORMAT('1999-01-01', '%X %V');
+mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
-> '1998 52'
@end example
@@ -31609,9 +32869,9 @@ format, depending on whether the function is used in a string or numeric
context:
@example
-mysql> select CURDATE();
+mysql> SELECT CURDATE();
-> '1997-12-15'
-mysql> select CURDATE() + 0;
+mysql> SELECT CURDATE() + 0;
-> 19971215
@end example
@@ -31624,9 +32884,9 @@ format, depending on whether the function is used in a string or numeric
context:
@example
-mysql> select CURTIME();
+mysql> SELECT CURTIME();
-> '23:50:26'
-mysql> select CURTIME() + 0;
+mysql> SELECT CURTIME() + 0;
-> 235026
@end example
@@ -31641,34 +32901,43 @@ or @code{YYYYMMDDHHMMSS} format, depending on whether the function is used in
a string or numeric context:
@example
-mysql> select NOW();
+mysql> SELECT NOW();
-> '1997-12-15 23:50:26'
-mysql> select NOW() + 0;
+mysql> SELECT NOW() + 0;
-> 19971215235026
@end example
+Note that @code{NOW()} is only evaluated once per query, namely at the
+start of query execution. This means that multiple references to
+@code{NOW()} within a single query will always give the same time.
+
@findex UNIX_TIMESTAMP()
@item UNIX_TIMESTAMP()
@itemx UNIX_TIMESTAMP(date)
If called with no argument, returns a Unix timestamp (seconds since
-@code{'1970-01-01 00:00:00'} GMT). If @code{UNIX_TIMESTAMP()} is called with
-a @code{date} argument, it returns the value of the argument as seconds since
-@code{'1970-01-01 00:00:00'} GMT. @code{date} may be a @code{DATE} string,
-a @code{DATETIME} string, a @code{TIMESTAMP}, or a number in the format
+@code{'1970-01-01 00:00:00'} GMT) as an unsigned integer. If
+@code{UNIX_TIMESTAMP()} is called with a @code{date} argument, it
+returns the value of the argument as seconds since @code{'1970-01-01
+00:00:00'} GMT. @code{date} may be a @code{DATE} string, a
+@code{DATETIME} string, a @code{TIMESTAMP}, or a number in the format
@code{YYMMDD} or @code{YYYYMMDD} in local time:
@example
-mysql> select UNIX_TIMESTAMP();
+mysql> SELECT UNIX_TIMESTAMP();
-> 882226357
-mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
+mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
-> 875996580
@end example
When @code{UNIX_TIMESTAMP} is used on a @code{TIMESTAMP} column, the function
-will receive the value directly, with no implicit
+will return the internal timestamp value directly, with no implicit
``string-to-unix-timestamp'' conversion.
-If you give @code{UNIX_TIMESTAMP()} a wrong or out-of-range date, it will
-return 0.
+If you pass an out-of-range date to @code{UNIX_TIMESTAMP()} it will
+return 0, but please note that only basic checking is performed
+(year 1970-2037, month 01-12, day 01-31).
+
+If you want to subtract @code{UNIX_TIMESTAMP()} columns, you may want to
+cast the result to signed integers. @xref{Cast Functions}.
@findex FROM_UNIXTIME()
@item FROM_UNIXTIME(unix_timestamp)
@@ -31677,9 +32946,9 @@ Returns a representation of the @code{unix_timestamp} argument as a value in
whether the function is used in a string or numeric context:
@example
-mysql> select FROM_UNIXTIME(875996580);
+mysql> SELECT FROM_UNIXTIME(875996580);
-> '1997-10-04 22:23:00'
-mysql> select FROM_UNIXTIME(875996580) + 0;
+mysql> SELECT FROM_UNIXTIME(875996580) + 0;
-> 19971004222300
@end example
@@ -31690,9 +32959,9 @@ the @code{format} string. @code{format} may contain the same specifiers as
those listed in the entry for the @code{DATE_FORMAT()} function:
@example
-mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
+mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
'%Y %D %M %h:%i:%s %x');
- -> '1997 23rd December 03:43:30 x'
+ -> '1997 23rd December 03:43:30 1997'
@end example
@findex SEC_TO_TIME()
@@ -31702,9 +32971,9 @@ as a value in @code{'HH:MM:SS'} or @code{HHMMSS} format, depending on whether
the function is used in a string or numeric context:
@example
-mysql> select SEC_TO_TIME(2378);
+mysql> SELECT SEC_TO_TIME(2378);
-> '00:39:38'
-mysql> select SEC_TO_TIME(2378) + 0;
+mysql> SELECT SEC_TO_TIME(2378) + 0;
-> 3938
@end example
@@ -31713,15 +32982,112 @@ mysql> select SEC_TO_TIME(2378) + 0;
Returns the @code{time} argument, converted to seconds:
@example
-mysql> select TIME_TO_SEC('22:23:00');
+mysql> SELECT TIME_TO_SEC('22:23:00');
-> 80580
-mysql> select TIME_TO_SEC('00:39:38');
+mysql> SELECT TIME_TO_SEC('00:39:38');
-> 2378
@end example
@end table
+@node Cast Functions, Other Functions, Date and time functions, Functions
+@subsection Cast Functions
+
+The syntax of the @code{CAST} function is:
+
+@findex CAST
+@findex CONVERT
+
+@example
+CAST(expression AS type)
+
+or
+
+CONVERT(expression,type)
+@end example
+
+Where type is one of:
+@itemize @bullet
+@item
+@code{BINARY}
+@item
+@code{DATE}
+@item
+@code{DATETIME}
+@item
+@code{SIGNED @{INTEGER@}}
+@item
+@code{TIME}
+@item
+@code{UNSIGNED @{INTEGER@}}
+@end itemize
+
+@code{CAST()} is ANSI SQL99 syntax and @code{CONVERT()} is ODBC syntax.
+
+The cast function is mainly useful when you want to create a column with
+a specific type in a @code{CREATE ... SELECT}:
+
+@example
+CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE);
+@end example
+
+@code{CAST(string AS BINARY} is the same thing as @code{BINARY string}.
+
+To cast a string to a numeric value, you don't normally have to do
+anything; just use the string value as it would be a number:
+
+@example
+mysql> SELECT 1+'1';
+ -> 2
+@end example
+
+MySQL supports arithmetic with both signed and unsigned 64-bit values.
+If you are using an numerical operations (like @code{+}) and one of the
+operands are @code{unsigned integer}, then the result will be unsigned.
+You can override this by using the @code{SIGNED} and @code{UNSIGNED}
+cast operators, which will cast the operation to a signed or
+unsigned 64-bit integer, respectively.
+
+@example
+mysql> SELECT CAST(1-2 AS UNSIGNED)
+ -> 18446744073709551615
+mysql> SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED);
+ -> -1
+@end example
+
+Note that if either operation is a floating-point value (In this context
+@code{DECIMAL()} is regarded as a floating-point value) the result will
+be a floating-point value and is not affected by the above rule.
+
+@example
+mysql> SELECT CAST(1 AS UNSIGNED) -2.0
+ -> -1.0
+@end example
+
+If you are using a string in an arithmetic operation, this is converted
+to a floating-point number.
+
+The @code{CAST()} and @code{CONVERT()} functions were added in MySQL 4.0.2.
+
+The handing of unsigned values was changed in MySQL 4.0 to be able to
+support @code{BIGINT} values properly. If you have some code that you
+want to run in both MySQL 4.0 and 3.23 (in which case you probably can't
+use the CAST function), you can use the following trick to get a signed
+result when subtracting two unsigned integer columns:
+
+@example
+SELECT (unsigned_column_1+0.0)-(unsigned_column_2+0.0);
+@end example
+
+The idea is that the columns are converted to floating-point before doing
+the subtraction.
+
+If you get a problem with @code{UNSIGNED} columns in your old MySQL
+application when porting to MySQL 4.0, you can use the
+@code{--sql-mode=NO_UNSIGNED_SUBTRACTION} option when starting
+@code{mysqld}. Note however that as long as you use this, you will not
+be able to make efficient use of the @code{UNSIGNED BIGINT} column type.
-@node Other Functions, , Date and time functions, Functions
+@node Other Functions, Group by functions, Cast Functions, Functions
@subsection Other Functions
@menu
@@ -31745,50 +33111,75 @@ these operators have a maximum range of 64 bits.
@findex | (bitwise OR)
@findex OR, bitwise
@item |
-Bitwise OR:
+Bitwise OR
@example
-mysql> select 29 | 15;
+mysql> SELECT 29 | 15;
-> 31
@end example
+The result is an unsigned 64-bit integer.
+
@findex & (bitwise AND)
@findex AND, bitwise
@item &
-Bitwise AND:
+Bitwise AND
@example
-mysql> select 29 & 15;
+mysql> SELECT 29 & 15;
-> 13
@end example
+The result is an unsigned 64-bit integer.
+
+@findex ^ (bitwise XOR)
+@findex XOR, bitwise
+@item ^
+Bitwise XOR
+@example
+mysql> SELECT 1 ^ 1;
+ -> 0
+mysql> SELECT 1 ^ 0;
+ -> 1
+mysql> SELECT 11 ^ 3;
+ -> 8
+@end example
+
+The result is an unsigned 64-bit integer.
+
@findex << (left shift)
@item <<
Shifts a longlong (@code{BIGINT}) number to the left:
@example
-mysql> select 1 << 2;
+mysql> SELECT 1 << 2;
-> 4
@end example
+The result is an unsigned 64-bit integer.
+
@findex >> (right shift)
@item >>
Shifts a longlong (@code{BIGINT}) number to the right:
@example
-mysql> select 4 >> 2;
+mysql> SELECT 4 >> 2;
-> 1
@end example
+The result is an unsigned 64-bit integer.
+
@findex ~
@item ~
Invert all bits:
@example
-mysql> select 5 & ~1;
+mysql> SELECT 5 & ~1;
-> 4
@end example
+The result is an unsigned 64-bit integer.
+
@findex BIT_COUNT()
@item BIT_COUNT(N)
Returns the number of bits that are set in the argument @code{N}:
@example
-mysql> select BIT_COUNT(29);
+mysql> SELECT BIT_COUNT(29);
-> 4
@end example
@end table
@@ -31806,7 +33197,7 @@ mysql> select BIT_COUNT(29);
Returns the current database name:
@example
-mysql> select DATABASE();
+mysql> SELECT DATABASE();
-> 'test'
@end example
@@ -31821,16 +33212,16 @@ If there is no current database, @code{DATABASE()} returns the empty string.
Returns the current MySQL user name:
@example
-mysql> select USER();
+mysql> SELECT USER();
-> 'davida@@localhost'
@end example
In MySQL Version 3.22.11 or later, this includes the client hostname
as well as the user name. You can extract just the user name part like this
-(which works whether or not the value includes a hostname part):
+(which works whether the value includes a hostname part):
@example
-mysql> select substring_index(USER(),"@@",1);
+mysql> SELECT SUBSTRING_INDEX(USER(),"@@",1);
-> 'davida'
@end example
@@ -31841,7 +33232,7 @@ the function that is used for encrypting MySQL passwords for storage
in the @code{Password} column of the @code{user} grant table:
@example
-mysql> select PASSWORD('badpwd');
+mysql> SELECT PASSWORD('badpwd');
-> '7f84554057dd964b'
@end example
@@ -31861,7 +33252,7 @@ Encrypt @code{str} using the Unix @code{crypt()} system call. The
(As of MySQL Version 3.22.16, @code{salt} may be longer than two characters.):
@example
-mysql> select ENCRYPT("hello");
+mysql> SELECT ENCRYPT("hello");
-> 'VxuFAJXVARROc'
@end example
@@ -31869,7 +33260,7 @@ If @code{crypt()} is not available on your system, @code{ENCRYPT()} always
returns @code{NULL}.
@code{ENCRYPT()} ignores all but the first 8 characters of @code{str}, at
-least on some systems. This will be determined by the behavior of the
+least on some systems. This will be determined by the behaviour of the
underlying @code{crypt()} system call.
@findex ENCODE()
@@ -31888,15 +33279,153 @@ password. @code{crypt_str} should be a string returned from
@findex MD5()
@item MD5(string)
-Calculates a MD5 checksum for the string. Value is returned as a 32 long
-hex number that may, for example, be used as a hash key:
+Calculates an MD5 128 bit checksum for the string. The value is returned
+as a 32 digit hex number that may, for example, be used as a hash key:
@example
-mysql> select MD5("testing");
+mysql> SELECT MD5("testing");
-> 'ae2b1fca515949e5d54fb22b8ed95575'
@end example
-This is an "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
+This is the "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
+
+@findex SHA1()
+@findex SHA()
+@item SHA1(string)
+@itemx SHA(string)
+Calculates an SHA1 160 bit checksum for the string, as described in
+RFC 3174 (Secure Hash Algorithm). The value is returned as a 40 digit
+hex number, or @code{NULL} in case the input argument was @code{NULL}.
+One of the possible uses for this function is as a hash key. You can
+also use it as cryptographically safe function for storing passwords.
+
+@example
+mysql> SELECT SHA1("abc");
+ -> 'a9993e364706816aba3e25717850c26c9cd0d89d'
+@end example
+
+@code{SHA1()} was added in version 4.0.2, and can be considered
+a cryptographically more secure equivalent of @code{MD5()}.
+@code{SHA()} is synonym for @code{SHA1()}.
+
+@findex AES_ENCRYPT()
+@findex AES_DECRYPT()
+@item AES_ENCRYPT(string,key_string)
+@itemx AES_DECRYPT(string,key_string)
+These functions allow encryption/decryption of data using the official
+AES (Advanced Encryption Standard) algorithm, previously known as Rijndael.
+Encoding with 128 bit key length is used, but you can extend it up to
+256 bit by patching the source. We chose 128 bits because it is much
+faster and it is usually secure enough.
+
+The input arguments may be any length. If either argument is @code{NULL},
+the result of this function is also @code{NULL}.
+
+As AES is a block level algorithm, padding is used to encode uneven length
+strings and so the result string length may be calculated as
+16*(trunc(string_length/16)+1).
+
+If @code{AES_DECRYPT()} detects invalid data or incorrect padding, it
+will return @code{NULL}. However, it is possible for @code{AES_DECRYPT()}
+to return a non-@code{NULL} value (possibly garbage) if the input data or
+the key was invalid.
+
+You can use the AES functions to store data in an encrypted form by
+modifying your queries:
+@example
+INSERT INTO t VALUES (1,AES_ENCRYPT("text","password"));
+@end example
+
+You can get even more security by avoiding transferring the key over the
+connection for each query, which can be accomplished by storing it in a
+server side variable at connection time:
+@example
+SELECT @@password:="my password";
+INSERT INTO t VALUES (1,AES_ENCRYPT("text",@@password));
+@end example
+
+@code{AES_ENCRYPT()} and @code{AES_DECRYPT()} were added in version 4.0.2,
+and can be considered the most cryptographically secure encryption
+functions currently available in MySQL.
+
+@findex DES_ENCRYPT()
+@item DES_ENCRYPT(string_to_encrypt [, (key_number | key_string) ] )
+
+Encrypts the string with the given key using the DES algorithm.
+
+Note that this function only works if you have configured MySQL with
+SSL support. @xref{Secure connections}.
+
+The encryption key to use is chosen the following way:
+
+@multitable @columnfractions .25 .65
+@item @strong{Argument} @tab @strong{Description}
+@item Only one argument @tab
+The first key from @code{des-key-file} is used.
+@item key number @tab
+The given key (0-9) from the @code{des-key-file} is used.
+@item string @tab
+The given @code{key_string} will be used to crypt @code{string_to_encrypt}.
+@end multitable
+
+The return string will be a binary string where the first character
+will be @code{CHAR(128 | key_number)}.
+
+The 128 is added to make it easier to recognize an encrypted key.
+If you use a string key, @code{key_number} will be 127.
+
+On error, this function returns @code{NULL}.
+
+The string length for the result will be
+@code{new_length= org_length + (8-(org_length % 8))+1}.
+
+The @code{des-key-file} has the following format:
+
+@example
+key_number des_key_string
+key_number des_key_string
+@end example
+
+Each @code{key_number} must be a number in the range from 0 to 9. Lines in
+the file may be in any order. @code{des_key_string} is the string that
+will be used to encrypt the message. Between the number and the key there
+should be at least one space. The first key is the default key that will
+be used if you don't specify any key argument to @code{DES_ENCRYPT()}
+
+You can tell MySQL to read new key values from the key file with the
+@code{FLUSH DES_KEY_FILE} command. This requires the @code{Reload_priv}
+privilege.
+
+One benefit of having a set of default keys is that it gives applications
+a way to check for existence of encrypted column values, without giving
+the end user the right to decrypt those values.
+
+@example
+mysql> SELECT customer_address FROM customer_table WHERE
+ crypted_credit_card = DES_ENCRYPT("credit_card_number");
+@end example
+
+@findex DES_DECRYPT()
+@item DES_DECRYPT(string_to_decrypt [, key_string])
+
+Decrypts a string encrypted with @code{DES_ENCRYPT()}.
+
+Note that this function only works if you have configured MySQL with
+SSL support. @xref{Secure connections}.
+
+If no @code{key_string} argument is given, @code{DES_DECRYPT()} examines
+the first byte of the encrypted string to determine the DES key number
+that was used to encrypt the original string, then reads the key
+from the @code{des-key-file} to decrypt the message. For this to work
+the user must have the @code{SUPER} privilege.
+
+If you pass this function a @code{key_string} argument, that string
+is used as the key for decrypting the message.
+
+If the @code{string_to_decrypt} doesn't look like an encrypted string, MySQL
+will return the given @code{string_to_decrypt}.
+
+On error, this function returns @code{NULL}.
@findex LAST_INSERT_ID([expr])
@item LAST_INSERT_ID([expr])
@@ -31905,7 +33434,7 @@ Returns the last automatically generated value that was inserted into an
@xref{mysql_insert_id,, @code{mysql_insert_id()}}.
@example
-mysql> select LAST_INSERT_ID();
+mysql> SELECT LAST_INSERT_ID();
-> 195
@end example
@@ -31921,35 +33450,35 @@ the same @code{INSERT} statement against some other server.
@cindex sequence emulation
If @code{expr} is given as an argument to @code{LAST_INSERT_ID()}, then
-the value of the argument is returned by the function, is set as the
-next value to be returned by @code{LAST_INSERT_ID()} and used as the next
-auto_increment value. This can be used to simulate sequences:
+the value of the argument is returned by the function, and is set as the
+next value to be returned by @code{LAST_INSERT_ID()}. This can be used
+to simulate sequences:
First create the table:
@example
-mysql> create table sequence (id int not null);
-mysql> insert into sequence values (0);
+mysql> CREATE TABLE sequence (id INT NOT NULL);
+mysql> INSERT INTO sequence VALUES (0);
@end example
Then the table can be used to generate sequence numbers like this:
@example
-mysql> update sequence set id=LAST_INSERT_ID(id+1);
+mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
@end example
You can generate sequences without calling @code{LAST_INSERT_ID()}, but the
utility of using the function this way is that the ID value is maintained in
-the server as the last automatically generated value. You can retrieve the
-new ID as you would read any normal @code{AUTO_INCREMENT} value in
-MySQL. For example, @code{LAST_INSERT_ID()} (without an argument)
-will return the new ID. The C API function @code{mysql_insert_id()}
-can also be used to get the value.
+the server as the last automatically generated value (multi-user safe).
+You can retrieve the new ID as you would read any normal
+@code{AUTO_INCREMENT} value in MySQL. For example, @code{LAST_INSERT_ID()}
+(without an argument) will return the new ID. The C API function
+@code{mysql_insert_id()} can also be used to get the value.
-Note that as @code{mysql_insert_id()} is only updated after
-@code{INSERT} and @code{UPDATE} statements, you can't use this function
-to retrieve the value for @code{LAST_INSERT_ID(expr)} after executing
-other SQL statements like @code{SELECT} or @code{SET}.
+Note that as @code{mysql_insert_id()} is only updated after @code{INSERT}
+and @code{UPDATE} statements, so you can't use the C API function to
+retrieve the value for @code{LAST_INSERT_ID(expr)} after executing other
+SQL statements like @code{SELECT} or @code{SET}.
@findex FORMAT()
@@ -31959,11 +33488,11 @@ to @code{D} decimals. If @code{D} is @code{0}, the result will have no
decimal point or fractional part:
@example
-mysql> select FORMAT(12332.123456, 4);
+mysql> SELECT FORMAT(12332.123456, 4);
-> '12,332.1235'
-mysql> select FORMAT(12332.1,4);
+mysql> SELECT FORMAT(12332.1,4);
-> '12,332.1000'
-mysql> select FORMAT(12332.2,0);
+mysql> SELECT FORMAT(12332.2,0);
-> '12,332'
@end example
@@ -31972,7 +33501,7 @@ mysql> select FORMAT(12332.2,0);
Returns a string indicating the MySQL server version:
@example
-mysql> select VERSION();
+mysql> SELECT VERSION();
-> '3.23.13-log'
@end example
@@ -31985,7 +33514,7 @@ Returns the connection id (@code{thread_id}) for the connection.
Every connection has its own unique id:
@example
-mysql> select CONNECTION_ID();
+mysql> SELECT CONNECTION_ID();
-> 1
@end example
@@ -32004,13 +33533,15 @@ the same name; clients that agree on a given lock string name can use the
string to perform cooperative advisory locking:
@example
-mysql> select GET_LOCK("lock1",10);
+mysql> SELECT GET_LOCK("lock1",10);
+ -> 1
+mysql> SELECT IS_FREE_LOCK("lock2");
-> 1
-mysql> select GET_LOCK("lock2",10);
+mysql> SELECT GET_LOCK("lock2",10);
-> 1
-mysql> select RELEASE_LOCK("lock2");
+mysql> SELECT RELEASE_LOCK("lock2");
-> 1
-mysql> select RELEASE_LOCK("lock1");
+mysql> SELECT RELEASE_LOCK("lock1");
-> NULL
@end example
@@ -32030,6 +33561,13 @@ been released.
The @code{DO} statement is convinient to use with @code{RELEASE_LOCK()}.
@xref{DO}.
+@findex IS_FREE_LOCK()
+@item IS_FREE_LOCK(str)
+Checks if the the lock named @code{str} is free to use (i.e., not locked).
+Returns @code{1} if the lock is free (no one is using the lock),
+@code{0} if the lock is in use, and
+@code{NULL} on errors (like incorrect arguments).
+
@findex BENCHMARK()
@item BENCHMARK(count,expr)
The @code{BENCHMARK()} function executes the expression @code{expr}
@@ -32038,9 +33576,9 @@ processes the expression. The result value is always @code{0}. The intended
use is in the @code{mysql} client, which reports query execution times:
@example
-mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
+mysql> SELECT BENCHMARK(1000000,ENCODE("hello","goodbye"));
+----------------------------------------------+
-| BENCHMARK(1000000,encode("hello","goodbye")) |
+| BENCHMARK(1000000,ENCODE("hello","goodbye")) |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
@@ -32054,39 +33592,222 @@ server machine is.
@findex INET_NTOA()
@item INET_NTOA(expr)
-Returns the network address (4 or 8 byte) for the numeric expression:
+Given a numeric network address (4 or 8 byte), returns the dotted-quad
+representation of the address as a string:
@example
-mysql> select INET_NTOA(3520061480);
+mysql> SELECT INET_NTOA(3520061480);
-> "209.207.224.40"
@end example
@findex INET_ATON()
@item INET_ATON(expr)
-Returns an integer that represents the numeric value for a network address.
+Given the dotted-quad representation of a network address as a string,
+returns an integer that represents the numeric value of the address.
Addresses may be 4 or 8 byte addresses:
@example
-mysql> select INET_ATON("209.207.224.40");
+mysql> SELECT INET_ATON("209.207.224.40");
-> 3520061480
@end example
-The generated number is always in network byte order; For example the
+The generated number is always in network byte order; for example the
above number is calculated as @code{209*256^3 + 207*256^2 + 224*256 +40}.
@findex MASTER_POS_WAIT()
@item MASTER_POS_WAIT(log_name, log_pos)
-Blocks until the slave reaches the specified position in the master log during
-replication. If master information is not initialized, returns NULL. If the
-slave is not running, will block and wait until it is started and goes to or
-past
-the specified position. If the slave is already past the specified position,
-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
-control of master-slave synchronization, but was originally written to
-facilitate replication testing.
+Blocks until the slave reaches the specified position in the master
+log during replication. If master information is not initialised,
+returns @code{NULL}. If the slave is not running, will block and wait
+until it is started and goes to or past the specified position. If the
+slave is already past the specified position, returns immediately. The
+return value is the number of log events it had to wait to get to the
+specified position, or @code{NULL} in case of error. Useful for control
+of master-slave synchronisation, but was originally written to facilitate
+replication testing.
+
+@findex FOUND_ROWS()
+@findex LIMIT
+@item FOUND_ROWS()
+Returns the number of rows that the last @code{SELECT SQL_CALC_FOUND_ROWS ...}
+command would have returned, if wasn't restricted with @code{LIMIT}.
+
+@example
+mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
+ WHERE id > 100 LIMIT 10;
+mysql> SELECT FOUND_ROWS();
+@end example
+
+The second @code{SELECT} will return a number indicating how many rows the
+first @code{SELECT} would have returned had it been written without the
+@code{LIMIT} clause.
+
+Note that if you are using @code{SELECT SQL_CALC_FOUND_ROWS ...} MySQL has
+to calculate all rows in the result set. However, this is faster than
+if you would not use @code{LIMIT}, as the result set need not be sent
+to the client.
+
+@code{SQL_CALC_FOUND_ROWS} is available starting at MySQL version 4.0.0.
+@end table
+
+
+@node Group by functions, , Other Functions, Functions
+@subsection Functions for Use with @code{GROUP BY} Clauses
+
+@findex GROUP BY functions
+@findex functions, GROUP BY
+
+If you use a group function in a statement containing no @code{GROUP BY}
+clause, it is equivalent to grouping on all rows.
+
+@table @code
+@findex COUNT()
+@item COUNT(expr)
+Returns a count of the number of non-@code{NULL} values in the rows
+retrieved by a @code{SELECT} statement:
+
+@example
+mysql> SELECT student.student_name,COUNT(*)
+ -> FROM student,course
+ -> WHERE student.student_id=course.student_id
+ -> GROUP BY student_name;
+
+@end example
+
+@code{COUNT(*)} is somewhat different in that it returns a count of
+the number of rows retrieved, whether they contain @code{NULL}
+values.
+
+@code{COUNT(*)} is optimised to
+return very quickly if the @code{SELECT} retrieves from one table, no
+other columns are retrieved, and there is no @code{WHERE} clause.
+For example:
+
+@example
+mysql> SELECT COUNT(*) FROM student;
+@end example
+
+@findex COUNT(DISTINCT)
+@findex DISTINCT
+@item COUNT(DISTINCT expr,[expr...])
+Returns a count of the number of different non-@code{NULL} values:
+
+@example
+mysql> SELECT COUNT(DISTINCT results) FROM student;
+@end example
+
+In MySQL you can get the number of distinct expression
+combinations that don't contain NULL by giving a list of expressions.
+In ANSI SQL you would have to do a concatenation of all expressions
+inside @code{COUNT(DISTINCT ...)}.
+
+@findex AVG()
+@item AVG(expr)
+Returns the average value of @code{expr}:
+
+@example
+mysql> SELECT student_name, AVG(test_score)
+ -> FROM student
+ -> GROUP BY student_name;
+@end example
+
+@findex MIN()
+@findex MAX()
+@item MIN(expr)
+@itemx MAX(expr)
+Returns the minimum or maximum value of @code{expr}. @code{MIN()} and
+@code{MAX()} may take a string argument; in such cases they return the
+minimum or maximum string value. @xref{MySQL indexes}.
+
+@example
+mysql> SELECT student_name, MIN(test_score), MAX(test_score)
+ -> FROM student
+ -> GROUP BY student_name;
+@end example
+
+@findex SUM()
+@item SUM(expr)
+Returns the sum of @code{expr}. Note that if the return set has no rows,
+it returns NULL!
+
+@findex STD()
+@findex STDDEV()
+@cindex Oracle compatibility
+@cindex compatibility, with Oracle
+@item STD(expr)
+@itemx STDDEV(expr)
+Returns the standard deviation of @code{expr}. This is an extension to
+ANSI SQL. The @code{STDDEV()} form of this function is provided for Oracle
+compatibility.
+
+@findex BIT_OR()
+@item BIT_OR(expr)
+Returns the bitwise @code{OR} of all bits in @code{expr}. The calculation is
+performed with 64-bit (@code{BIGINT}) precision.
+
+@findex BIT_AND()
+@item BIT_AND(expr)
+Returns the bitwise @code{AND} of all bits in @code{expr}. The calculation is
+performed with 64-bit (@code{BIGINT}) precision.
@end table
+@cindex @code{GROUP BY}, extensions to ANSI SQL
+MySQL has extended the use of @code{GROUP BY}. You can use columns or
+calculations in the @code{SELECT} expressions that don't appear in
+the @code{GROUP BY} part. This stands for @emph{any possible value for this
+group}. You can use this to get better performance by avoiding sorting and
+grouping on unnecessary items. For example, you don't need to group on
+@code{customer.name} in the following query:
+
+@example
+mysql> SELECT order.custid,customer.name,MAX(payments)
+ -> FROM order,customer
+ -> WHERE order.custid = customer.custid
+ -> GROUP BY order.custid;
+@end example
+
+In ANSI SQL, you would have to add @code{customer.name} to the @code{GROUP
+BY} clause. In MySQL, the name is redundant if you don't run in
+ANSI mode.
+
+@strong{Don't use this feature} if the columns you omit from the
+@code{GROUP BY} part aren't unique in the group! You will get
+unpredictable results.
+
+In some cases, you can use @code{MIN()} and @code{MAX()} to obtain a specific
+column value even if it isn't unique. The following gives the value of
+@code{column} from the row containing the smallest value in the @code{sort}
+column:
+
+@example
+SUBSTR(MIN(CONCAT(RPAD(sort,6,' '),column)),7)
+@end example
+
+@xref{example-Maximum-column-group-row}.
+
+@cindex @code{ORDER BY}, aliases in
+@cindex aliases, in @code{ORDER BY} clauses
+@cindex @code{GROUP BY}, aliases in
+@cindex aliases, in @code{GROUP BY} clauses
+@cindex expression aliases
+@cindex aliases, for expressions
+Note that if you are using MySQL Version 3.22 (or earlier) or if
+you are trying to follow ANSI SQL, you can't use expressions in @code{GROUP
+BY} or @code{ORDER BY} clauses. You can work around this limitation by
+using an alias for the expression:
+
+@example
+mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name
+ -> GROUP BY id,val ORDER BY val;
+@end example
+
+In MySQL Version 3.23 you can do:
+
+@example
+mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();
+@end example
+
+
@node Data Manipulation, Data Definition, Functions, Reference
@section Data Manipulation: @code{SELECT}, @code{INSERT}, @code{UPDATE}, @code{DELETE}
@@ -32094,8 +33815,9 @@ facilitate replication testing.
@menu
* SELECT:: @code{SELECT} Syntax
+* HANDLER:: @code{HANDLER} Syntax
* INSERT:: @code{INSERT} Syntax
-* INSERT DELAYED:: @code{INSERT DELAYED} syntax
+* INSERT DELAYED:: @code{INSERT DELAYED} Syntax
* UPDATE:: @code{UPDATE} Syntax
* DELETE:: @code{DELETE} Syntax
* TRUNCATE:: @code{TRUNCATE} Syntax
@@ -32104,26 +33826,27 @@ facilitate replication testing.
* DO:: @code{DO} Syntax
@end menu
-@node SELECT, INSERT, Data Manipulation, Data Manipulation
+@node SELECT, HANDLER, Data Manipulation, Data Manipulation
@subsection @code{SELECT} Syntax
@findex SELECT
@c help SELECT
@example
-SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
- [HIGH_PRIORITY]
+SELECT [STRAIGHT_JOIN]
+ [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
+ [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL]
select_expression,...
[INTO @{OUTFILE | DUMPFILE@} 'file_name' export_options]
[FROM table_references
- [WHERE where_definition]
- [GROUP BY @{unsigned_integer | col_name | formula@} [ASC | DESC], ...]
- [HAVING where_definition]
- [ORDER BY @{unsigned_integer | col_name | formula@} [ASC | DESC] ,...]
- [LIMIT [offset,] rows]
- [PROCEDURE procedure_name]
- [FOR UPDATE | LOCK IN SHARE MODE]]
+ [WHERE where_definition]
+ [GROUP BY @{unsigned_integer | col_name | formula@} [ASC | DESC], ...
+ [HAVING where_definition]
+ [ORDER BY @{unsigned_integer | col_name | formula@} [ASC | DESC] ,...]
+ [LIMIT [offset,] rows]
+ [PROCEDURE procedure_name]
+ [FOR UPDATE | LOCK IN SHARE MODE]]
@end example
@c help end
@@ -32151,14 +33874,38 @@ is used as the expression's column name and can be used with
@code{ORDER BY} or @code{HAVING} clauses. For example:
@example
-mysql> select concat(last_name,', ',first_name) AS full_name
- from mytable ORDER BY full_name;
+mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name
+ FROM mytable ORDER BY full_name;
@end example
@item
+It is not allowed to use a column alias in a @code{WHERE} clause,
+because the column value may not yet be determined when the
+@code{WHERE} clause is executed.
+@xref{Problems with alias}.
+
+@item
+@findex AS
+@findex USE INDEX
+@findex IGNORE INDEX
+@findex USE KEY
+@findex IGNORE KEY
The @code{FROM table_references} clause indicates the tables from which to
retrieve rows. If you name more than one table, you are performing a
join. For information on join syntax, see @ref{JOIN, , @code{JOIN}}.
+For each table specified, you may optionally specify an alias.
+@example
+table_name [[AS] alias] [USE INDEX (key_list)] [IGNORE INDEX (key_list)]
+@end example
+As of MySQL Version 3.23.12, you can give hints about which
+index MySQL should use when retrieving information from a
+table. This is useful if @code{EXPLAIN} shows that MySQL is
+using the wrong index. By specifying @code{USE INDEX (key_list)}, you
+can tell MySQL to use only one of the specified indexes to
+find rows in the table. The alternative syntax @code{IGNORE INDEX
+(key_list)} can be used to tell MySQL to not use some
+particular index.
+@code{USE/IGNORE KEY} are synonyms for @code{USE/IGNORE INDEX}.
@item
You can refer to a column as @code{col_name}, @code{tbl_name.col_name}, or
@@ -32174,10 +33921,10 @@ forms.
A table reference may be aliased using @code{tbl_name [AS] alias_name}:
@example
-mysql> select t1.name, t2.salary from employee AS t1, info AS t2
- where t1.name = t2.name;
-mysql> select t1.name, t2.salary from employee t1, info t2
- where t1.name = t2.name;
+mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
+ -> WHERE t1.name = t2.name;
+mysql> SELECT t1.name, t2.salary FROM employee t1, info t2
+ -> WHERE t1.name = t2.name;
@end example
@item
@@ -32186,12 +33933,12 @@ Columns selected for output may be referred to in @code{ORDER BY} and
positions. Column positions begin with 1:
@example
-mysql> select college, region, seed from tournament
- ORDER BY region, seed;
-mysql> select college, region AS r, seed AS s from tournament
- ORDER BY r, s;
-mysql> select college, region, seed from tournament
- ORDER BY 2, 3;
+mysql> SELECT college, region, seed FROM tournament
+ -> ORDER BY region, seed;
+mysql> SELECT college, region AS r, seed AS s FROM tournament
+ -> ORDER BY r, s;
+mysql> SELECT college, region, seed FROM tournament
+ -> ORDER BY 2, 3;
@end example
To sort in reverse order, add the @code{DESC} (descending) keyword to the
@@ -32206,37 +33953,43 @@ MySQL support. @xref{Functions}.
@item
The @code{HAVING} clause can refer to any column or alias named in the
@code{select_expression}. It is applied last, just before items are sent to
-the client, with no optimization. Don't use @code{HAVING} for items that
+the client, with no optimisation. Don't use @code{HAVING} for items that
should be in the @code{WHERE} clause. For example, do not write this:
@example
-mysql> select col_name from tbl_name HAVING col_name > 0;
+mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;
@end example
Write this instead:
@example
-mysql> select col_name from tbl_name WHERE col_name > 0;
+mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;
@end example
In MySQL Version 3.22.5 or later, you can also write queries like this:
@example
-mysql> select user,max(salary) from users
- group by user HAVING max(salary)>10;
+mysql> SELECT user,MAX(salary) FROM users
+ -> GROUP BY user HAVING MAX(salary)>10;
@end example
In older MySQL versions, you can write this instead:
@example
-mysql> select user,max(salary) AS sum from users
- group by user HAVING sum>10;
+mysql> SELECT user,MAX(salary) AS sum FROM users
+ -> group by user HAVING sum>10;
@end example
@item
-@code{SQL_SMALL_RESULT}, @code{SQL_BIG_RESULT}, @code{SQL_BUFFER_RESULT},
-@code{STRAIGHT_JOIN}, and @code{HIGH_PRIORITY} are MySQL extensions
-to ANSI SQL92.
+The options @code{DISTINCT}, @code{DISTINCTROW} and @code{ALL} specify
+whether duplicate rows should be returned. The default is (@code{ALL}),
+all matching rows are returned. @code{DISTINCT} and @code{DISTINCTROW}
+are synonyms and specify that duplicate rows in the result set should
+be removed.
+
+@item
+All options beginning with @code{SQL_}, @code{STRAIGHT_JOIN}, and
+@code{HIGH_PRIORITY} are MySQL extensions to ANSI SQL.
@item
@code{HIGH_PRIORITY} will give the @code{SELECT} higher priority than
@@ -32247,7 +34000,7 @@ statement that is waiting for the table to be free.
@item
@code{SQL_BIG_RESULT} can be used with @code{GROUP BY} or @code{DISTINCT}
-to tell the optimizer that the result set will have many rows. In this case,
+to tell the optimiser that the result set will have many rows. In this case,
MySQL will directly use disk-based temporary tables if needed.
MySQL will also, in this case, prefer sorting to doing a
temporary table with a key on the @code{GROUP BY} elements.
@@ -32259,12 +34012,27 @@ in cases where it takes a long time to send the result set to the client.
@item
@code{SQL_SMALL_RESULT}, a MySQL-specific option, can be used
-with @code{GROUP BY} or @code{DISTINCT} to tell the optimizer that the
+with @code{GROUP BY} or @code{DISTINCT} to tell the optimiser that the
result set will be small. In this case, MySQL will use fast
temporary tables to store the resulting table instead of using sorting. In
MySQL Version 3.23 this shouldn't normally be needed.
@item
+@code{SQL_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
+@code{SQL_CACHE} tells MySQL to store the query result in the query cache
+if you are using @code{QUERY_CACHE_TYPE=2} (@code{DEMAND}).
+@xref{Query Cache}.
+
+@item
+@code{SQL_NO_CACHE} tells MySQL to not allow the query result to be stored
+in the query cache. @xref{Query Cache}.
+
+@item
@cindex @code{GROUP BY}, extensions to ANSI SQL
If you use @code{GROUP BY}, the output rows will be sorted according to the
@code{GROUP BY} as if you would have had an @code{ORDER BY} over all the fields
@@ -32283,28 +34051,36 @@ read the @code{GROUP BY} description.
@xref{Group by functions}.
@item
-@code{STRAIGHT_JOIN} forces the optimizer to join the tables in the order in
+@cindex hints
+@code{STRAIGHT_JOIN} forces the optimiser to join the tables in the order in
which they are listed in the @code{FROM} clause. You can use this to speed up
-a query if the optimizer joins the tables in non-optimal order.
+a query if the optimiser joins the tables in non-optimal order.
@xref{EXPLAIN, , @code{EXPLAIN}}.
@item
The @code{LIMIT} clause can be used to constrain the number of rows returned
by the @code{SELECT} statement. @code{LIMIT} takes one or two numeric
-arguments.
+arguments. The arguments must be integer constants.
If two arguments are given, the first specifies the offset of the first row to
return, the second specifies the maximum number of rows to return.
The offset of the initial row is 0 (not 1):
@example
-mysql> select * from table LIMIT 5,10; # Retrieve rows 6-15
+mysql> SELECT * FROM table LIMIT 5,10; # Retrieve rows 6-15
+@end example
+
+To retrieve all rows from a certain offset upto the end of the result set,
+you can use -1 for the second parameter:
+
+@example
+mysql> SELECT * FROM table LIMIT 95,-1; # Retrieve rows 96-last.
@end example
If one argument is given, it indicates the maximum number of rows to return:
@example
-mysql> select * from table LIMIT 5; # Retrieve first 5 rows
+mysql> SELECT * FROM table LIMIT 5; # Retrieve first 5 rows
@end example
In other words, @code{LIMIT n} is equivalent to @code{LIMIT 0,n}.
@@ -32315,7 +34091,7 @@ The @code{SELECT ... INTO OUTFILE 'file_name'} form of @code{SELECT} writes
the selected rows to a file. The file is created on the server host and
cannot already exist (among other things, this prevents database tables and
files such as @file{/etc/passwd} from being destroyed). You must have the
-@strong{file} privilege on the server host to use this form of @code{SELECT}.
+@code{FILE} privilege on the server host to use this form of @code{SELECT}.
@code{SELECT ... INTO OUTFILE} is mainly intended to let you very
quickly dump a table on the server machine. If you want to create the
@@ -32342,7 +34118,7 @@ the @code{ESCAPED BY} character:
Additionally, @code{ASCII 0} is converted to @code{ESCAPED BY} followed by 0
(@code{ASCII 48}).
-The reason for the above is that you MUST escape any @code{FIELDS
+The reason for the above is that you @strong{must} escape any @code{FIELDS
TERMINATED BY}, @code{ESCAPED BY}, or @code{LINES TERMINATED BY}
characters to reliably be able to read the file back. @code{ASCII 0} is
escaped to make it easier to view with some pagers.
@@ -32382,9 +34158,10 @@ the examined rows will be write locked.
@menu
* JOIN:: @code{JOIN} Syntax
+* UNION:: @code{UNION} Syntax
@end menu
-@node JOIN, , SELECT, SELECT
+@node JOIN, UNION, SELECT, SELECT
@subsubsection @code{JOIN} Syntax
@findex JOIN
@@ -32418,6 +34195,7 @@ table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
@end example
Where @code{table_reference} is defined as:
+@findex AS
@example
table_name [[AS] alias] [USE INDEX (key_list)] [IGNORE INDEX (key_list)]
@end example
@@ -32448,8 +34226,8 @@ A table reference may be aliased using @code{tbl_name AS alias_name} or
@code{tbl_name alias_name}:
@example
-mysql> select t1.name, t2.salary from employee AS t1, info AS t2
- where t1.name = t2.name;
+mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
+ -> WHERE t1.name = t2.name;
@end example
@item
@@ -32463,15 +34241,15 @@ If there is no matching record for the right table in the @code{ON} or
records in a table that have no counterpart in another table:
@example
-mysql> select table1.* from table1
- LEFT JOIN table2 ON table1.id=table2.id
- where table2.id is NULL;
+mysql> SELECT table1.* FROM table1
+ -> LEFT JOIN table2 ON table1.id=table2.id
+ -> WHERE table2.id IS NULL;
@end example
This example finds all rows in @code{table1} with an @code{id} value that is
not present in @code{table2} (that is, all rows in @code{table1} with no
corresponding row in @code{table2}). This assumes that @code{table2.id} is
-declared @code{NOT NULL}, of course. @xref{LEFT JOIN optimization}.
+declared @code{NOT NULL}, of course. @xref{LEFT JOIN optimisation}.
@item
The @code{USING} @code{(column_list)} clause names a list of columns that must
@@ -32495,16 +34273,26 @@ with a @code{USING} clause that names all columns that exist in both
tables.
@item
+@cindex hints
+@code{INNER JOIN} and @code{,} (comma) are semantically equivalent.
+Both do a full join between the tables used. Normally, you specify
+how the tables should be linked in the WHERE condition.
+
+@item
@code{RIGHT JOIN} works analogously as @code{LEFT JOIN}. To keep code
portable across databases, it's recommended to use @code{LEFT JOIN}
instead of @code{RIGHT JOIN}.
@item
+@cindex hints
@code{STRAIGHT_JOIN} is identical to @code{JOIN}, except that the left table
is always read before the right table. This can be used for those (few)
-cases where the join optimizer puts the tables in the wrong order.
+cases where the join optimiser puts the tables in the wrong order.
@item
+@cindex hints
+@findex USE INDEX
+@findex IGNORE INDEX
As of MySQL Version 3.23.12, you can give hints about which
index MySQL should use when retrieving information from a
table. This is useful if @code{EXPLAIN} shows that MySQL is
@@ -32513,26 +34301,154 @@ can tell MySQL to use only one of the specified indexes to
find rows in the table. The alternative syntax @code{IGNORE INDEX
(key_list)} can be used to tell MySQL to not use some
particular index.
+@findex USE KEY
+@findex IGNORE KEY
+@code{USE/IGNORE KEY} are synonyms for @code{USE/IGNORE INDEX}.
@end itemize
Some examples:
@example
-mysql> select * from table1,table2 where table1.id=table2.id;
-mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id;
-mysql> select * from table1 LEFT JOIN table2 USING (id);
-mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id
- LEFT JOIN table3 ON table2.id=table3.id;
-mysql> select * from table1 USE INDEX (key1,key2) WHERE key1=1 and key2=2 AND
- key3=3;
-mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND
- key3=3;
+mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id;
+mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;
+mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id);
+mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id
+ -> LEFT JOIN table3 ON table2.id=table3.id;
+mysql> SELECT * FROM table1 USE INDEX (key1,key2)
+ -> WHERE key1=1 AND key2=2 AND key3=3;
+mysql> SELECT * FROM table1 IGNORE INDEX (key3)
+ -> WHERE key1=1 AND key2=2 AND key3=3;
+@end example
+
+@xref{LEFT JOIN optimisation, , @code{LEFT JOIN} optimisation}.
+
+
+@node UNION, , JOIN, SELECT
+@subsubsection @code{UNION} Syntax
+
+@findex UNION
+
+@example
+SELECT ...
+UNION [ALL]
+SELECT ...
+ [UNION
+ SELECT ...]
+@end example
+
+@code{UNION} is implemented in MySQL 4.0.0.
+
+@code{UNION} is used to combine the result from many @code{SELECT}
+statements into one result set.
+
+The columns listed in the select_expression portion of the @code{SELECT}
+should have the same type. The column names used in the first
+@code{SELECT} query will be used as the column names for the results
+returned.
+
+The @code{SELECT} commands are normal select commands, but with the following
+restrictions:
+
+@itemize @bullet
+@item
+Only the last @code{SELECT} command can have @code{INTO OUTFILE}.
+@end itemize
+
+If you don't use the keyword @code{ALL} for the @code{UNION}, all
+returned rows will be unique, as if you had done a @code{DISTINCT} for
+the total result set. If you specify @code{ALL}, then you will get all
+matching rows from all the used @code{SELECT} statements.
+
+If you want to use an @code{ORDER BY} for the total @code{UNION} result,
+you should use parentheses:
+
+@example
+(SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
+UNION
+(SELECT a FROM table_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10)
+ORDER BY a;
+@end example
+
+@findex HANDLER
+@node HANDLER, INSERT, SELECT, Data Manipulation
+@subsection @code{HANDLER} Syntax
+
+@example
+HANDLER tbl_name OPEN [ AS alias ]
+HANDLER tbl_name READ index_name @{ = | >= | <= | < @} (value1,value2,...)
+ [ WHERE ... ] [LIMIT ... ]
+HANDLER tbl_name READ index_name @{ FIRST | NEXT | PREV | LAST @}
+ [ WHERE ... ] [LIMIT ... ]
+HANDLER tbl_name READ @{ FIRST | NEXT @}
+ [ WHERE ... ] [LIMIT ... ]
+HANDLER tbl_name CLOSE
@end example
-@xref{LEFT JOIN optimization, , @code{LEFT JOIN} optimization}.
+The @code{HANDLER} statement provides direct access to the @code{MyISAM} table
+handler interface.
+
+The first form of @code{HANDLER} statement opens a table, making
+it accessible via subsequent @code{HANDLER ... READ} statements.
+This table object is not shared by other threads and will not be closed
+until the thread calls @code{HANDLER tbl_name CLOSE} or the thread dies.
+
+@c FIX The sentence below needs to be rewritten. The reference to "the condition" is not clear.
+@c FIX Also all mentions of the LIMIT clause need to be clarified in various sentences below.
+
+The second form fetches one row (or more, specified by @code{LIMIT} clause)
+where the index specified complies to the condition and @code{WHERE}
+condition is met. If the index consists of several parts (spans over
+several columns) the values are specified in comma-separated list,
+providing values only for few first columns is possible.
+
+The third form fetches one row (or more, specified by @code{LIMIT} clause)
+from the table in index order, matching @code{WHERE} condition.
+
+The fourth form (without index specification) fetches one row (or more, specified
+by @code{LIMIT} clause) from the table in natural row order (as stored
+in datafile) matching @code{WHERE} condition. It is faster than
+@code{HANDLER tbl_name READ index_name} when a full table scan is desired.
+
+@code{HANDLER ... CLOSE} closes a table that was opened with
+@code{HANDLER ... OPEN}.
+@code{HANDLER} is a somewhat low-level statement. For example, it does
+not provide consistency. That is, @code{HANDLER ... OPEN} does @strong{NOT}
+take a snapshot of the table, and does @strong{NOT} lock the table. This
+means that after a @code{HANDLER ... OPEN} is issued, table data can be
+modified (by this or any other thread) and these modifications may appear
+only partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV} scans.
-@node INSERT, INSERT DELAYED, SELECT, Data Manipulation
+The reasons to use this interface instead of normal SQL are:
+
+@itemize @bullet
+@item
+It's faster than @code{SELECT} because:
+@itemize @bullet
+@item
+A designated table handler is allocated for the thread in @code{HANDLER open}.
+@item
+There is less parsing involved.
+@item
+No optimizer and no query checking overhead.
+@item
+The used table doesn't have to be locked between two handler requests.
+@item
+The handler interface doesn't have to provide a consistent look of the
+data (for example dirty-reads are allow), which allows the table handler
+to do optimizations that SQL doesn't normally allow.
+@end itemize
+@item
+It makes it much easier to port applications that uses an ISAM like
+interface to MySQL.
+@item
+It allows one to traverse a database in a manner that is not easy
+(in some case impossible) to do with SQL. The handler interface is
+more natural way to look at data when working with applications that
+provide an interactive user interfaces to the database.
+@end itemize
+
+@node INSERT, INSERT DELAYED, HANDLER, Data Manipulation
@subsection @code{INSERT} Syntax
@findex INSERT
@@ -32540,13 +34456,13 @@ mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND
@example
INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
- VALUES (expression,...),(...),...
+ VALUES ((expression | DEFAULT),...),(...),...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name
- SET col_name=expression, col_name=expression, ...
+ SET col_name=(expression | DEFAULT), ...
@end example
@@ -32570,11 +34486,23 @@ If you specify no column list for @code{INSERT ... VALUES} or @code{INSERT
the columns in the table, use @code{DESCRIBE tbl_name} to find out.
@item
+@cindex default values
Any column not explicitly given a value is set to its default value. For
example, if you specify a column list that doesn't name all the columns in
the table, unnamed columns are set to their default values. Default value
assignment is described in @ref{CREATE TABLE, , @code{CREATE TABLE}}.
+You can also use the keyword @code{DEFAULT} to set a column to it's
+defaults value. (New in MySQL 4.0.3). This makes it easier to write
+insert statements as you don't have to use a field-name list just because
+you don't want to set a value for a few columns.
+
+MySQL always has a default value for all fields. This is something
+that is imposed on MySQL to be able to work with both transactional
+and not transactional tables.
+
+Our view is that checking of fields content should be done in the
+application and not in the database server.
@item
An @code{expression} may refer to any column that was set earlier in a value
list. For example, you can say this:
@@ -32623,7 +34551,7 @@ with the @code{mysql_insert_id} function.
If you use @code{INSERT ... SELECT} or an @code{INSERT ... VALUES}
statement with multiple value lists, you can use the C API function
@code{mysql_info()} to get information about the query. The format of the
-information string is shown below:
+information string is shown here:
@example
Records: 100 Duplicates: 0 Warnings: 0
@@ -32691,7 +34619,7 @@ The target table of the @code{INSERT} statement cannot appear in the
forbidden in ANSI SQL to @code{SELECT} from the same table into which you are
inserting. (The problem is that the @code{SELECT} possibly would
find records that were inserted earlier during the same run. When using
-sub-select clauses, the situation could easily be very confusing!)
+subselect clauses, the situation could easily be very confusing!)
@item
@code{AUTO_INCREMENT} columns work as usual.
@@ -32703,7 +34631,7 @@ the query. @xref{INSERT}.
@item
To ensure that the update log/binary log can be used to re-create the
original tables, MySQL will not allow concurrent inserts during
-@code{INSERT .... SELECT}.
+@code{INSERT ... SELECT}.
@end itemize
You can of course also use @code{REPLACE} instead of @code{INSERT} to
@@ -32711,7 +34639,7 @@ overwrite old rows.
@node INSERT DELAYED, UPDATE, INSERT, Data Manipulation
-@subsection @code{INSERT DELAYED} syntax
+@subsection @code{INSERT DELAYED} Syntax
@findex INSERT DELAYED
@findex DELAYED
@@ -32733,7 +34661,7 @@ Version 3.22.15. It is a MySQL extension to ANSI SQL92.
@code{INSERT DELAYED} only works with @code{ISAM} and @code{MyISAM}
tables. Note that as @code{MyISAM} tables supports concurrent
@code{SELECT} and @code{INSERT}, if there is no free blocks in the
-middle of the data file, you very seldom need to use @code{INSERT
+middle of the datafile, you very seldom need to use @code{INSERT
DELAYED} with @code{MyISAM}. @xref{MyISAM}.
When you use @code{INSERT DELAYED}, the client will get an OK at once
@@ -32761,7 +34689,7 @@ thread is created to process all @code{DELAYED} statements for the table, if
no such handler already exists.
@item
-The thread checks whether or not the handler has acquired a @code{DELAYED}
+The thread checks whether the handler has acquired a @code{DELAYED}
lock already; if not, it tells the handler thread to do so. The
@code{DELAYED} lock can be obtained even if other threads have a @code{READ}
or @code{WRITE} lock on the table. However, the handler will wait for all
@@ -32788,7 +34716,7 @@ the first row is inserted.
@item
After every @code{delayed_insert_limit} rows are written, the handler checks
-whether or not any @code{SELECT} statements are still pending. If so, it
+whether any @code{SELECT} statements are still pending. If so, it
allows these to execute before continuing.
@cindex delayed_insert_limit
@@ -32814,7 +34742,6 @@ table before exiting. During this time it will not accept any new
@code{INSERT} commands from another thread. If you execute an @code{INSERT
DELAYED} command after this, a new handler thread will be created.
-@item
Note that the above means that @code{INSERT DELAYED} commands have higher
priority than normal @code{INSERT} commands if there is an @code{INSERT
DELAYED} handler already running! Other update commands will have to wait
@@ -32825,7 +34752,7 @@ thread (with @code{KILL thread_id}), or someone executes @code{FLUSH TABLES}.
The following status variables provide information about @code{INSERT
DELAYED} commands:
-@multitable @columnfractions .35 .65
+@multitable @columnfractions .30 .55
@item @strong{Variable} @tab @strong{Meaning}
@item @code{Delayed_insert_threads} @tab Number of handler threads
@item @code{Delayed_writes} @tab Number of rows written with @code{INSERT DELAYED}
@@ -32850,7 +34777,7 @@ DELAYED} when you are really sure you need it!
@example
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
- SET col_name1=expr1, [col_name2=expr2, ...]
+ SET col_name1=expr1 [, col_name2=expr2, ...]
[WHERE where_definition]
[LIMIT #]
@end example
@@ -32858,7 +34785,7 @@ UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
@code{UPDATE} updates columns in existing table rows with new values.
The @code{SET} clause indicates which columns to modify and the values
they should be given. The @code{WHERE} clause, if given, specifies
-which rows should be updated. Otherwise all rows are updated. If the
+which rows should be updated. Otherwise, all rows are updated. If the
@code{ORDER BY} clause is specified, the rows will be updated in the
order that is specified.
@@ -32904,40 +34831,96 @@ only a given number of rows are changed.
@findex DELETE
@example
-DELETE [LOW_PRIORITY] FROM tbl_name
- [WHERE where_definition]
- [LIMIT rows]
+DELETE [LOW_PRIORITY | QUICK] FROM table_name
+ [WHERE where_definition]
+ [ORDER BY ...]
+ [LIMIT rows]
+
+or
+
+DELETE [LOW_PRIORITY | QUICK] table_name[.*] [,table_name[.*] ...]
+ FROM table-references
+ [WHERE where_definition]
+
+or
+
+DELETE [LOW_PRIORITY | QUICK]
+ FROM table_name[.*], [table_name[.*] ...]
+ USING table-references
+ [WHERE where_definition]
@end example
-@code{DELETE} deletes rows from @code{tbl_name} that satisfy the condition
+@code{DELETE} deletes rows from @code{table_name} that satisfy the condition
given by @code{where_definition}, and returns the number of records deleted.
If you issue a @code{DELETE} with no @code{WHERE} clause, all rows are
deleted. If you do this in @code{AUTOCOMMIT} mode, this works as
-@code{TRUNCATE}. @xref{TRUNCATE}. One problem with this is that
-@code{DELETE} will return zero as the number of affected records, but
-this will be fixed in 4.0.
+@code{TRUNCATE}. @xref{TRUNCATE, , @code{TRUNCATE}}. In MySQL 3.23,
+@code{DELETE} without a @code{WHERE} clause will return zero as the number
+of affected records.
If you really want to know how many records are deleted when you are deleting
all rows, and are willing to suffer a speed penalty, you can use a
@code{DELETE} statement of this form:
@example
-mysql> DELETE FROM tbl_name WHERE 1>0;
+mysql> DELETE FROM table_name WHERE 1>0;
@end example
-Note that this is MUCH slower than @code{DELETE FROM tbl_name} with no
+Note that this is much slower than @code{DELETE FROM table_name} with no
@code{WHERE} clause, because it deletes rows one at a time.
If you specify the keyword @code{LOW_PRIORITY}, execution of the
@code{DELETE} is delayed until no other clients are reading from the table.
-Deleted records are maintained in a linked list and subsequent @code{INSERT}
-operations reuse old record positions. To reclaim unused space and reduce
-file sizes, use the @code{OPTIMIZE TABLE} statement or the @code{myisamchk}
-utility to reorganize tables. @code{OPTIMIZE TABLE} is easier, but
-@code{myisamchk} is faster.
-See @ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} and @ref{Optimization}.
+If you specify the word @code{QUICK} then the table handler will not
+merge index leaves during delete, which may speed up certain kind of
+deletes.
+
+In @code{MyISAM} tables, deleted records are maintained in a linked list and
+subsequent @code{INSERT} operations reuse old record positions. To
+reclaim unused space and reduce file-sizes, use the @code{OPTIMIZE
+TABLE} statement or the @code{myisamchk} utility to reorganise tables.
+@code{OPTIMIZE TABLE} is easier, but @code{myisamchk} is faster. See
+@ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} and @ref{Optimisation}.
+
+The first multi-table delete format is supported starting from MySQL 4.0.0.
+The second multi-table delete format is supported starting from MySQL 4.0.2.
+
+The idea is that only matching rows from the tables listed
+@strong{before} the @code{FROM} or before the @code{USING} clause are
+deleted. The effect is that you can delete rows from many tables at the
+same time and also have additional tables that are used for searching.
+
+The @code{.*} after the table names is there just to be compatible with
+@code{Access}:
+
+@example
+DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
+
+or
+
+DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
+@end example
+
+In the above case we delete matching rows just from tables @code{t1} and
+@code{t2}.
+
+@code{ORDER BY} and using multiple tables in the @code{DELETE} statement
+is supported in MySQL 4.0.
+
+If an @code{ORDER BY} clause is used, the rows will be deleted in that order.
+This is really only useful in conjunction with @code{LIMIT}. For example:
+
+@example
+DELETE FROM somelog
+WHERE user = 'jcole'
+ORDER BY timestamp
+LIMIT 1
+@end example
+
+This will delete the oldest entry (by @code{timestamp}) where the row matches
+the @code{WHERE} clause.
The MySQL-specific @code{LIMIT rows} option to @code{DELETE} tells
the server the maximum number of rows to be deleted before control is
@@ -32956,16 +34939,19 @@ the @code{LIMIT} value.
TRUNCATE TABLE table_name
@end example
-Is in 3.23 and the same thing as @code{DELETE FROM table_name}. @xref{DELETE}.
-The differences are:
+In 3.23 @code{TRUNCATE TABLE} is mapped to
+@code{COMMIT ; DELETE FROM table_name}. @xref{DELETE}.
+
+@code{TRUNCATE TABLE} differs from @code{DELETE FROM ...}
+in the following ways:
@itemize @bullet
@item
-Implemented as a drop and re-create of the table, which makes this
-much faster when deleting many rows.
+Truncate operations drop and re-create the table, which is much faster
+than deleting rows one by one.
@item
-Not transaction-safe; @code{TRUNCATE TABLE} will automatically end the current
-transaction as if @code{COMMIT} would have been called.
+Not transaction-safe; you will get an error if you have an active
+transaction or an active table lock.
@item
Doesn't return the number of deleted rows.
@item
@@ -32976,7 +34962,6 @@ files have become corrupted.
@code{TRUNCATE} is an Oracle SQL extension.
-
@node REPLACE, LOAD DATA, TRUNCATE, Data Manipulation
@subsection @code{REPLACE} Syntax
@@ -32995,20 +34980,26 @@ or REPLACE [LOW_PRIORITY | DELAYED]
@end example
@code{REPLACE} works exactly like @code{INSERT}, except that if an old
-record in the table has the same value as a new record on a unique index,
-the old record is deleted before the new record is inserted.
-@xref{INSERT, , @code{INSERT}}.
+record in the table has the same value as a new record on a @code{UNIQUE}
+index or @code{PRIMARY KEY}, the old record is deleted before the new
+record is inserted.
+@xref{INSERT, ,@code{INSERT}}.
In other words, you can't access the values of the old row from a
-@code{REPLACE} statement. In some old MySQL version it looked
-like you could do this, but that was a bug that has been corrected.
+@code{REPLACE} statement. In some old MySQL versions it appeared that
+you could do this, but that was a bug that has been corrected.
-When one uses a @code{REPLACE} command, @code{mysql_affected_rows()}
-will return 2 if the new row replaced and old row. This is because in
-this case one row was inserted and then the duplicate was deleted.
+When you use a @code{REPLACE} command, @code{mysql_affected_rows()}
+will return 2 if the new row replaced an old row. This is because
+one row was inserted and then the duplicate was deleted.
-The above makes it easy to check if @code{REPLACE} added or replaced a
-row.
+This fact makes it easy to determine whether @code{REPLACE} added
+or replaced a row: check whether the affected-rows value is 1 (added)
+or 2 (replaced).
+
+Note that unless you use a @code{UNIQUE} index or @code{PRIMARY KEY},
+using a @code{REPLACE} command makes no sense, since it would just do
+an @code{INSERT}.
@node LOAD DATA, DO, REPLACE, Data Manipulation
@@ -33039,9 +35030,13 @@ MySQL Version 3.22.6 or later.)
For security reasons, when reading text files located on the server, the
files must either reside in the database directory or be readable by all.
Also, to use @code{LOAD DATA INFILE} on server files, you must have the
-@strong{file} privilege on the server host.
+@code{FILE} privilege on the server host.
@xref{Privileges provided}.
+In MySQL 3.23.49 and MySQL 4.0.2 @code{LOCAL} will only work if you have
+not started @code{mysqld} with @code{--local-infile=0} or if you
+have not enabled your client to support @code{LOCAL}. @xref{LOAD DATA LOCAL}.
+
If you specify the keyword @code{LOW_PRIORITY}, execution of the
@code{LOAD DATA} statement is delayed until no other clients are reading
from the table.
@@ -33055,7 +35050,7 @@ the table at the same time.
Using @code{LOCAL} will be a bit slower than letting the server access the
files directly, because the contents of the file must travel from the client
host to the server host. On the other hand, you do not need the
-@strong{file} privilege to load local files.
+@code{FILE} privilege to load local files.
@c old version
If you are using MySQL before Version 3.23.24 you can't read from a
@@ -33064,9 +35059,9 @@ example the output from gunzip), use @code{LOAD DATA LOCAL INFILE}
instead.
@cindex @code{mysqlimport}
-You can also load data files by using the @code{mysqlimport} utility; it
+You can also load datafiles by using the @code{mysqlimport} utility; it
operates by sending a @code{LOAD DATA INFILE} command to the server. The
-@code{--local} option causes @code{mysqlimport} to read data files from the
+@code{--local} option causes @code{mysqlimport} to read datafiles from the
client host. You can specify the @code{--compress} option to get better
performance over slow networks if the client and server support the
compressed protocol.
@@ -33109,7 +35104,7 @@ file is ignored.
If you load data from a local file using the @code{LOCAL} keyword, the server
has no way to stop transmission of the file in the middle of the operation,
-so the default bahavior is the same as if @code{IGNORE} is specified.
+so the default behaviour is the same as if @code{IGNORE} is specified.
If you use @code{LOAD DATA INFILE} on an empty @code{MyISAM} table,
all non-unique indexes are created in a separate batch (like in @code{REPAIR}).
@@ -33186,7 +35181,7 @@ The @code{IGNORE number LINES} option can be used to ignore a header of
column names at the start of the file:
@example
-mysql> LOAD DATA INFILE "/tmp/file_name" into table test IGNORE 1 LINES;
+mysql> LOAD DATA INFILE "/tmp/file_name" INTO TABLE test IGNORE 1 LINES;
@end example
When you use @code{SELECT ... INTO OUTFILE} in tandem with @code{LOAD
@@ -33199,24 +35194,24 @@ fields delimited by commas:
@example
mysql> SELECT * INTO OUTFILE 'data.txt'
- FIELDS TERMINATED BY ','
- FROM ...;
+ -> FIELDS TERMINATED BY ','
+ -> FROM ...;
@end example
To read the comma-delimited file back in, the correct statement would be:
@example
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
- FIELDS TERMINATED BY ',';
+ -> FIELDS TERMINATED BY ',';
@end example
-If instead you tried to read in the file with the statement shown below, it
+If instead you tried to read in the file with the statement shown here, it
wouldn't work because it instructs @code{LOAD DATA INFILE} to look for
tabs between fields:
@example
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
- FIELDS TERMINATED BY '\t';
+ -> FIELDS TERMINATED BY '\t';
@end example
The likely result is that each input line would be interpreted as
@@ -33225,14 +35220,14 @@ a single field.
@code{LOAD DATA INFILE} can be used to read files obtained from
external sources, too. For example, a file in dBASE format will have
fields separated by commas and enclosed in double quotes. If lines in
-the file are terminated by newlines, the command shown below
+the file are terminated by newlines, the command shown here
illustrates the field and line handling options you would use to load
the file:
@example
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
- FIELDS TERMINATED BY ',' ENCLOSED BY '"'
- LINES TERMINATED BY '\n';
+ -> FIELDS TERMINATED BY ',' ENCLOSED BY '"'
+ -> LINES TERMINATED BY '\n';
@end example
Any of the field or line handling options may specify an empty string
@@ -33248,17 +35243,17 @@ For example, to read a file of jokes, that are separated with a line
of @code{%%}, into a SQL table you can do:
@example
-create table jokes (a int not null auto_increment primary key, joke text
-not null);
-load data infile "/tmp/jokes.txt" into table jokes fields terminated by ""
-lines terminated by "\n%%\n" (joke);
+CREATE TABLE jokes (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, joke TEXT
+NOT NULL);
+LOAD DATA INFILE "/tmp/jokes.txt" INTO TABLE jokes FIELDS TERMINATED BY ""
+LINES TERMINATED BY "\n%%\n" (joke);
@end example
@code{FIELDS [OPTIONALLY] ENCLOSED BY} controls quoting of fields. For
output (@code{SELECT ... INTO OUTFILE}), if you omit the word
@code{OPTIONALLY}, all fields are enclosed by the @code{ENCLOSED BY}
character. An example of such output (using a comma as the field
-delimiter) is shown below:
+delimiter) is shown here:
@example
"1","a string","100.20"
@@ -33282,7 +35277,7 @@ field value are escaped by prefixing them with the @code{ESCAPED BY}
character. Also note that if you specify an empty @code{ESCAPED BY}
value, it is possible to generate output that cannot be read properly by
@code{LOAD DATA INFILE}. For example, the output just shown above would
-appear as shown below if the escape character is empty. Observe that the
+appear as shown here if the escape character is empty. Observe that the
second field in the fourth line contains a comma following the quote, which
(erroneously) appears to terminate the field:
@@ -33294,14 +35289,14 @@ second field in the fourth line contains a comma following the quote, which
@end example
For input, the @code{ENCLOSED BY} character, if present, is stripped from the
-ends of field values. (This is true whether or not @code{OPTIONALLY} is
+ends of field values. (This is true whether @code{OPTIONALLY} is
specified; @code{OPTIONALLY} has no effect on input interpretation.)
Occurrences of the @code{ENCLOSED BY} character preceded by the
@code{ESCAPED BY} character are interpreted as part of the current field
value. In addition, duplicated @code{ENCLOSED BY} characters occurring
within fields are interpreted as single @code{ENCLOSED BY} characters if the
field itself starts with that character. For example, if @code{ENCLOSED BY
-'"'} is specified, quotes are handled as shown below:
+'"'} is specified, quotes are handled as shown here:
@example
"The ""BIG"" boss" -> The "BIG" boss
@@ -33427,7 +35422,7 @@ If you wish to load only some of a table's columns, specify a field list:
@example
mysql> LOAD DATA INFILE 'persondata.txt'
- INTO TABLE persondata (col1,col2,...);
+ -> INTO TABLE persondata (col1,col2,...);
@end example
You must also specify a field list if the order of the fields in the input
@@ -33474,7 +35469,7 @@ specified as strings!
@findex mysql_info()
If you are using the C API, you can get information about the query by
calling the API function @code{mysql_info()} when the @code{LOAD DATA INFILE}
-query finishes. The format of the information string is shown below:
+query finishes. The format of the information string is shown here:
@example
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
@@ -33584,10 +35579,11 @@ tables, because normally each table corresponds to a @file{.MYD} file, a
The @code{DROP DATABASE} command removes from the given database
directory all files with the following extensions:
-@multitable @columnfractions .25 .25 .25 .25
-@item .BAK @tab .DAT @tab .HSH @tab .ISD
-@item .ISM @tab .ISM @tab .MRG @tab .MYD
-@item .MYI @tab .db @tab .frm
+@multitable @columnfractions .10 .10 .10 .10
+@item @strong{Ext} @tab @strong{Ext} @tab @strong{Ext} @tab @strong{Ext}
+@item .BAK @tab .DAT @tab .HSH @tab .ISD
+@item .ISM @tab .ISM @tab .MRG @tab .MYD
+@item .MYI @tab .db @tab .frm @tab
@end multitable
All subdirectories that consists of 2 digits (@code{RAID} directories)
@@ -33600,16 +35596,6 @@ exist.
@cindex @code{mysqladmin}
You can also drop databases with @code{mysqladmin}. @xref{Client-Side Scripts}.
-
-@menu
-* CREATE TABLE:: @code{CREATE TABLE} Syntax
-* ALTER TABLE:: @code{ALTER TABLE} Syntax
-* RENAME TABLE:: @code{RENAME TABLE} Syntax
-* DROP TABLE:: @code{DROP TABLE} Syntax
-* CREATE INDEX:: @code{CREATE INDEX} Syntax
-* DROP INDEX:: @code{DROP INDEX} Syntax
-@end menu
-
@node CREATE TABLE, ALTER TABLE, DROP DATABASE, Data Definition
@subsection @code{CREATE TABLE} Syntax
@@ -33631,7 +35617,7 @@ create_definition:
or INDEX [index_name] (index_col_name,...)
or UNIQUE [INDEX] [index_name] (index_col_name,...)
or FULLTEXT [INDEX] [index_name] (index_col_name,...)
- or [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
+ or [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...)
[reference_definition]
or CHECK (expr)
@@ -33677,21 +35663,22 @@ reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
table_options:
- TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MYISAM @}
+ TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM @}
or AUTO_INCREMENT = #
or AVG_ROW_LENGTH = #
or CHECKSUM = @{0 | 1@}
or COMMENT = "string"
or MAX_ROWS = #
or MIN_ROWS = #
-or PACK_KEYS = @{0 | 1@}
+or PACK_KEYS = @{0 | 1 | DEFAULT@}
or PASSWORD = "string"
or DELAY_KEY_WRITE = @{0 | 1@}
or ROW_FORMAT= @{ default | dynamic | fixed | compressed @}
or RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=# RAID_CHUNKSIZE=#
or UNION = (table_name,[table_name...])
-or DATA DIRECTORY="directory"
-or INDEX DIRECTORY="directory"
+or INSERT_METHOD= @{NO | FIRST | LAST @}
+or DATA DIRECTORY="absolute path to directory"
+or INDEX DIRECTORY="absolute path to directory"
select_statement:
[IGNORE | REPLACE] SELECT ... (Some legal select statement)
@@ -33703,7 +35690,7 @@ allowable table names are given in @ref{Legal names}. An error occurs if
there is no current database or if the table already exists.
In MySQL Version 3.22 or later, the table name can be specified as
-@code{db_name.tbl_name}. This works whether or not there is a current
+@code{db_name.tbl_name}. This works whether there is a current
database.
In MySQL Version 3.23, you can use the @code{TEMPORARY} keyword when
@@ -33711,7 +35698,9 @@ you create a table. A temporary table will automatically be deleted if a
connection dies and the name is per connection. This means that two different
connections can both use the same temporary table name without conflicting
with each other or with an existing table of the same name. (The existing table
-is hidden until the temporary table is deleted).
+is hidden until the temporary table is deleted.). In MySQL 4.0.2 one must
+have the @code{CREATE TEMPORARY TABLES} privilege to be able to create
+temporary tables.
In MySQL Version 3.23 or later, you can use the keywords
@code{IF NOT EXISTS} so that an error does not occur if the table already
@@ -33721,10 +35710,10 @@ identical.
Each table @code{tbl_name} is represented by some files in the database
directory. In the case of MyISAM-type tables you will get:
-@multitable @columnfractions .2 .8
+@multitable @columnfractions .20 .30
@item @strong{File} @tab @strong{Purpose}
@item @code{tbl_name.frm} @tab Table definition (form) file
-@item @code{tbl_name.MYD} @tab Data file
+@item @code{tbl_name.MYD} @tab Datafile
@item @code{tbl_name.MYI} @tab Index file
@end multitable
@@ -33751,13 +35740,16 @@ If you delete the row containing the maximum value for an
with @code{DELETE FROM table_name} (without a @code{WHERE}) in
@code{AUTOCOMMIT} mode, the sequence starts over for all table types.
-@strong{NOTE:} There can be only one @code{AUTO_INCREMENT} column per
+@strong{Note}: there can be only one @code{AUTO_INCREMENT} column per
table, and it must be indexed. MySQL Version 3.23 will also only
-work properly if the auto_increment column only has positive
+work properly if the @code{AUTO_INCREMENT} column only has positive
values. Inserting a negative number is regarded as inserting a very large
positive number. This is done to avoid precision problems when
numbers 'wrap' over from positive to negative and also to ensure that one
-doesn't accidentally get an auto_increment column that contains 0.
+doesn't accidentally get an @code{AUTO_INCREMENT} column that contains 0.
+
+In MyISAM and BDB tables you can specify @code{AUTO_INCREMENT} secondary
+column in a multi-column key. @xref{example-AUTO_INCREMENT}.
@cindex ODBC compatibility
@cindex compatibility, with ODBC
@@ -33787,6 +35779,10 @@ as setting it to @code{NULL}, because @code{0} is a valid @code{TIMESTAMP}
value.
@item
+@cindex default values
+A @code{DEFAULT} value has to be a constant, it can not be a function or
+an expression.
+
If no @code{DEFAULT} value is specified for a column, MySQL
automatically assigns one.
@@ -33809,8 +35805,10 @@ column in a table, the default value is the current date and time.
@xref{Date and time types}.
@item
-For string types other than @code{ENUM}, the default value is the empty string.
-For @code{ENUM}, the default is the first enumeration value.
+For string types other than @code{ENUM}, the default value is the empty
+string. For @code{ENUM}, the default is the first enumeration value (if
+you haven't explicitly specified another default value with the
+@code{DEFAULT} directive).
@end itemize
Default values must be constants. This means, for example, that you cannot
@@ -33856,7 +35854,7 @@ table using @code{SHOW INDEX FROM tbl_name}.
@item
@cindex @code{NULL} values, and indexes
@cindex indexes, and @code{NULL} values
-Only the @code{MyISAM} table type supports indexes on columns that can have
+Only the @code{MyISAM}, @code{InnoDB}, and @code{BDB} table types support indexes on columns that can have
@code{NULL} values. In other cases you must declare such columns
@code{NOT NULL} or an error results.
@@ -33875,7 +35873,7 @@ Only the @code{MyISAM} table type supports indexing on @code{BLOB} and
@code{TEXT} columns. When putting an index on a @code{BLOB} or @code{TEXT}
column you MUST always specify the length of the index:
@example
-CREATE TABLE test (blob_col BLOB, index(blob_col(10)));
+CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
@end example
@item
@@ -33892,11 +35890,11 @@ Indexing always happens over the entire column, partial indexing is not
supported. See @ref{Fulltext Search} for details of operation.
@item
-The @code{FOREIGN KEY}, @code{CHECK}, and @code{REFERENCES} clauses don't
-actually do anything. The syntax for them is provided only for compatibility,
-to make it easier to port code from other SQL servers and to run applications
-that create tables with references.
-@xref{Missing functions}.
+In MySQL Version 3.23.44 or later, @code{InnoDB} tables support checking of
+foreign key constraints. @xref{InnoDB}.
+For other table types, MySQL Server does parse the @code{FOREIGN KEY},
+@code{CHECK}, and @code{REFERENCES} syntax in @code{CREATE TABLE} commands,
+but without further action being taken. @xref{ANSI diff Foreign Keys}.
@item
Each @code{NULL} column takes one bit extra, rounded up to the nearest byte.
@@ -33917,12 +35915,14 @@ implemented in MySQL Version 3.23 and above.
The different table types are:
-@multitable @columnfractions .20 .80
-@item BDB or Berkeley_db @tab Transaction-safe tables with page locking. @xref{BDB}.
+@multitable @columnfractions .25 .70
+@item @strong{Table type} @tab @strong{Description}
+@item BDB or BerkeleyDB @tab Transaction-safe tables with page locking. @xref{BDB}.
@item HEAP @tab The data for this table is only stored in memory. @xref{HEAP}.
@item ISAM @tab The original table handler. @xref{ISAM}.
@item InnoDB @tab Transaction-safe tables with row locking. @xref{InnoDB}.
@item MERGE @tab A collection of MyISAM tables used as one table. @xref{MERGE}.
+@item MRG_MyISAM @tab An alias for MERGE tables
@item MyISAM @tab The new binary portable table handler that is replacing ISAM. @xref{MyISAM}.
@end multitable
@xref{Table types}.
@@ -33933,21 +35933,22 @@ specified. For example, if @code{TYPE=BDB} is specified, and that distribution
of MySQL does not support @code{BDB} tables, the table will be created
as @code{MyISAM} instead.
-The other table options are used to optimize the behavior of the
+The other table options are used to optimise the behaviour of the
table. In most cases, you don't have to specify any of them.
The options work for all table types, if not otherwise indicated:
-@multitable @columnfractions .20 .80
-@item @code{AUTO_INCREMENT} @tab The next auto_increment value you want to set for your table (MyISAM).
+@multitable @columnfractions .25 .70
+@item @strong{Option} @tab @strong{Description}
+@item @code{AUTO_INCREMENT} @tab The next @code{AUTO_INCREMENT} value you want to set for your table (MyISAM).
@item @code{AVG_ROW_LENGTH} @tab An approximation of the average row length for your table. You only need to set this for large tables with variable size records.
@item @code{CHECKSUM} @tab Set this to 1 if you want MySQL to maintain a checksum for all rows (makes the table a little slower to update but makes it easier to find corrupted tables) (MyISAM).
@item @code{COMMENT} @tab A 60-character comment for your table.
@item @code{MAX_ROWS} @tab Max number of rows you plan to store in the table.
@item @code{MIN_ROWS} @tab Minimum number of rows you plan to store in the table.
-@item @code{PACK_KEYS} @tab Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM).
-@item @code{PASSWORD} @tab Encrypt the @code{.frm} file with a password. This option doesn't do anything in the standard MySQL version.
+@item @code{PACK_KEYS} @tab Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM). Setting this to 0 will disable all packing of keys. Setting this to @code{DEFAULT} (MySQL 4.0) will tell the table handler to only pack long @code{CHAR}/@code{VARCHAR} columns.
+@item @code{PASSWORD} @tab Encrypt the @file{.frm} file with a password. This option doesn't do anything in the standard MySQL version.
@item @code{DELAY_KEY_WRITE} @tab Set this to 1 if want to delay key table updates until the table is closed (MyISAM).
-@item @code{ROW_FORMAT} @tab Defines how the rows should be stored. Currently you can only use the DYNAMIC and STATIC options for MyISAM tables.
+@item @code{ROW_FORMAT} @tab Defines how the rows should be stored. Currently this option only works with MyISAM tables, which supports the @code{DYNAMIC} and @code{FIXED} row formats. @xref{MyISAM table formats}.
@end multitable
When you use a @code{MyISAM} table, MySQL uses the product of
@@ -33966,13 +35967,13 @@ many numbers that are the same. Prefix compression means that every
key needs one extra byte to indicate how many bytes of the previous key are
the same for the next key (note that the pointer to the row is stored
in high-byte-first-order directly after the key, to improve
-compression.) This means that if you have many equal keys on two rows
+compression). This means that if you have many equal keys on two rows
in a row, all following 'same' keys will usually only take 2 bytes
(including the pointer to the row). Compare this to the ordinary case
where the following keys will take storage_size_for_key +
pointer_size (usually 4). On the other hand, if all keys are
totally different, you will lose 1 byte per key, if the key isn't a
-key that can have @code{NULL} values (In this case the packed key length will
+key that can have @code{NULL} values. (In this case the packed key length will
be stored in the same byte that is used to mark if a key is @code{NULL}.)
@item
@@ -33981,9 +35982,9 @@ MySQL will create new fields for all elements in the
@code{SELECT}. For example:
@example
-mysql> CREATE TABLE test (a int not null auto_increment,
- primary key (a), key(b))
- TYPE=MyISAM SELECT b,c from test2;
+mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
+ -> PRIMARY KEY (a), KEY(b))
+ -> TYPE=MyISAM SELECT b,c FROM test2;
@end example
This will create a @code{MyISAM} table with three columns, a, b, and c.
@@ -33992,24 +35993,24 @@ the right side of the table, not overlapped onto it. Take the following
example:
@example
-mysql> select * from foo;
+mysql> SELECT * FROM foo;
+---+
| n |
+---+
| 1 |
-+---+
++---+
-mysql> create table bar (m int) select n from foo;
+mysql> CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
-
-mysql> select * from bar;
+
+mysql> SELECT * FROM bar;
+------+---+
| m | n |
+------+---+
| NULL | 1 |
+------+---+
-1 row in set (0.00 sec)
+1 row in set (0.00 sec)
@end example
For each row in table @code{foo}, a row is inserted in @code{bar} with
@@ -34021,52 +36022,63 @@ possible. If you want to have indexes in the created table, you should
specify these before the @code{SELECT} statement:
@example
-mysql> create table bar (unique (n)) select n from foo;
+mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
@end example
-If any errors occur while copying the data to the table, it will
-automatically be deleted.
+If any errors occur while copying the data to the table, it will
+automatically be deleted.
To ensure that the update log/binary log can be used to re-create the
original tables, MySQL will not allow concurrent inserts during
-@code{CREATE TABLE .... SELECT}.
+@code{CREATE TABLE ... SELECT}.
@item
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 don't support big files. You can get also more speed
-from the I/O bottleneck by putting @code{RAID} directories on different
-physical disks. @code{RAID_TYPE} will work on 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).
+the MyISAM datafile (not the index file) on operating systems that
+don't support big files. Note that this option is not recommended for
+filesystem that supports big files!
+
+You can get more speed from the I/O bottleneck by putting @code{RAID}
+directories on different physical disks. @code{RAID_TYPE} will work on
+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,
@code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named 00,
01, 02 in the database directory. In each of these directories
@code{MyISAM} will create a @code{table_name.MYD}. When writing data
-to the data file, the @code{RAID} handler will map the first
+to the datafile, the @code{RAID} handler will map the first
@code{RAID_CHUNKSIZE} *1024 bytes to the first file, the next
@code{RAID_CHUNKSIZE} *1024 bytes to the next file and so on.
@item
@code{UNION} is used when you want to use a collection of identical
-tables as one. This only works with MERGE tables. @xref{MERGE}.
+tables as one. This only works with @code{MERGE} tables.
+@xref{MERGE, , @code{MERGE}}.
For the moment you need to have @code{SELECT}, @code{UPDATE}, and
@code{DELETE} privileges on the tables you map to a @code{MERGE} table.
All mapped tables must be in the same database as the @code{MERGE} table.
+
+@item
+If you want to insert data in a @code{MERGE} table, you have to specify with
+@code{INSERT_METHOD} into with table the row should be inserted.
+@xref{MERGE}. This option was introduced in MySQL 4.0.0.
+
@item
In the created table the @code{PRIMARY} key will be placed first, followed
by all @code{UNIQUE} keys and then the normal keys. This helps the
-MySQL optimizer to prioritize which key to use and also more quickly
+MySQL optimiser to prioritise which key to use and also more quickly
detect duplicated @code{UNIQUE} keys.
@item
By using @code{DATA DIRECTORY="directory"} or @code{INDEX
DIRECTORY="directory"} you can specify where the table handler should
-put it's table and index files. This only works for @code{MyISAM} tables
-in @code{MySQL} 4.0, when you are not using the @code{--skip-symlink}
-option. @xref{Symbolic links to tables}.
+put it's table and index files. Note that the directory should be a full
+path to the directory (not relative path).
+This only works for @code{MyISAM} tables in @code{MySQL} 4.0, when you
+are not using the @code{--skip-symlink} option. @xref{Symbolic links to
+tables}.
@end itemize
@@ -34113,7 +36125,7 @@ MySQL maps certain column types used by other SQL database vendors
to MySQL types. @xref{Other-vendor column types}.
@end itemize
-If you want to see whether or not MySQL used a column type other
+If you want to see whether MySQL used a column type other
than the one you specified, issue a @code{DESCRIBE tbl_name} statement after
creating or altering your table.
@@ -34141,10 +36153,13 @@ alter_specification:
[reference_definition]
or ALTER [COLUMN] col_name @{SET DEFAULT literal | DROP DEFAULT@}
or CHANGE [COLUMN] old_col_name create_definition
- or MODIFY [COLUMN] create_definition
+ [FIRST | AFTER column_name]
+ or MODIFY [COLUMN] create_definition [FIRST | AFTER column_name]
or DROP [COLUMN] col_name
or DROP PRIMARY KEY
or DROP INDEX index_name
+ or DISABLE KEYS
+ or ENABLE KEYS
or RENAME [TO] new_tbl_name
or ORDER BY col
or table_options
@@ -34176,11 +36191,14 @@ Note that if you use any other option to @code{ALTER TABLE} than
if the data wouldn't strictly need to be copied (like when you change the
name of a column). We plan to fix this in the future, but as one doesn't
normally do @code{ALTER TABLE} that often this isn't that high on our TODO.
+For MyISAM tables, you can speed up the index recreation part (which is the
+slowest part of the recreation process) by setting the
+@code{myisam_sort_buffer_size} variable to a high value.
@itemize @bullet
@item
-To use @code{ALTER TABLE}, you need @strong{ALTER}, @strong{INSERT},
-and @strong{CREATE} privileges on the table.
+To use @code{ALTER TABLE}, you need @code{ALTER}, @code{INSERT},
+and @code{CREATE} privileges on the table.
@item
@code{IGNORE} is a MySQL extension to ANSI SQL92.
@@ -34255,8 +36273,10 @@ MySQL tries to convert data to the new type as well as possible.
@item
In MySQL Version 3.22 or later, you can use @code{FIRST} or
-@code{ADD ... AFTER col_name} to add a column at a specific position within
-a table row. The default is to add the column last.
+@code{ADD ... AFTER col_name} to add a column at a specific position
+within a table row. The default is to add the column last.
+From MySQL Version 4.0.1, you can also use the @code{FIRST} and
+@code{AFTER} keywords in @code{CHANGE} or @code{MODIFY}.
@findex ALTER COLUMN
@item
@@ -34301,7 +36321,7 @@ specific order. Note that the table will not remain in this order after
inserts and deletes. In some cases, it may make sorting easier for
MySQL if the table is in order by the column that you wish to
order it by later. This option is mainly useful when you know that you
-are mostly going to query the rows in a certain order; By using this
+are mostly going to query the rows in a certain order; by using this
option after big changes to the table, you may be able to get higher
performance.
@@ -34312,6 +36332,15 @@ indexes are created in a separate batch (like in @code{REPAIR}).
This should make @code{ALTER TABLE} much faster when you have many indexes.
@item
+Since @strong{MySQL 4.0} the above feature can be activated explicitly.
+@code{ALTER TABLE ... DISABLE KEYS} makes MySQL to stop updating
+non-unique indexes for @code{MyISAM} table.
+@code{ALTER TABLE ... ENABLE KEYS} then should be used to recreate missing
+indexes. As MySQL does it with special algorithm which is much
+faster then inserting keys one by one, disabling keys could give a
+considerable speedup on bulk inserts.
+
+@item
@findex mysql_info()
With the C API function @code{mysql_info()}, you can find out how many
records were copied, and (when @code{IGNORE} is used) how many records were
@@ -34324,11 +36353,11 @@ The @code{FOREIGN KEY}, @code{CHECK}, and @code{REFERENCES} clauses don't
actually do anything. The syntax for them is provided only for compatibility,
to make it easier to port code from other SQL servers and to run applications
that create tables with references.
-@xref{Missing functions}.
+@xref{Differences from ANSI}.
@end itemize
Here is an example that shows some of the uses of @code{ALTER TABLE}. We
-begin with a table @code{t1} that is created as shown below:
+begin with a table @code{t1} that is created as shown here:
@example
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
@@ -34398,7 +36427,7 @@ column, the numbers will start from 1 again.
@findex RENAME TABLE
@example
-RENAME TABLE tbl_name TO new_table_name[, tbl_name2 TO new_table_name2,...]
+RENAME TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2,...]
@end example
The rename is done atomically, which means that no other thread can
@@ -34423,18 +36452,19 @@ As long as two databases are on the same disk you can also rename
from one database to another:
@example
-RENAME TABLE current_database.table_name TO other_database.table_name;
+RENAME TABLE current_db.tbl_name TO other_db.tbl_name;
@end example
When you execute @code{RENAME}, you can't have any locked tables or
active transactions. You must also have the @code{ALTER} and @code{DROP}
-privilege on the original table and @code{CREATE} and @code{INSERT}
-privilege on the new table.
+privileges on the original table, and the @code{CREATE} and @code{INSERT}
+privileges on the new table.
-If MySQL encounters any errors in a multiple table rename, it
+If MySQL encounters any errors in a multiple-table rename, it
will do a reverse rename for all renamed tables to get everything back
to the original state.
+@code{RENAME TABLE} was added in MySQL 3.23.23.
@node DROP TABLE, CREATE INDEX, RENAME TABLE, Data Definition
@subsection @code{DROP TABLE} Syntax
@@ -34455,8 +36485,8 @@ exist.
@code{RESTRICT} and @code{CASCADE} are allowed to make porting easier.
For the moment they don't do anything.
-@strong{NOTE}: @code{DROP TABLE} is not transaction-safe and will
-automatically commit any active transactions.
+@strong{Note}: @code{DROP TABLE} will
+automatically commit current active transaction.
@node CREATE INDEX, DROP INDEX, DROP TABLE, Data Definition
@@ -34469,7 +36499,8 @@ automatically commit any active transactions.
@cindex multi-part index
@example
-CREATE [UNIQUE|FULLTEXT] INDEX index_name ON tbl_name (col_name[(length)],... )
+CREATE [UNIQUE|FULLTEXT] INDEX index_name
+ ON tbl_name (col_name[(length)],... )
@end example
The @code{CREATE INDEX} statement doesn't do anything in MySQL prior
@@ -34488,8 +36519,8 @@ columns.
For @code{CHAR} and @code{VARCHAR} columns, indexes can be created that
use only part of a column, using @code{col_name(length)} syntax. (On
-@code{BLOB} and @code{TEXT} columns the length is required). The
-statement shown below creates an index using the first 10 characters of
+@code{BLOB} and @code{TEXT} columns the length is required.) The
+statement shown here creates an index using the first 10 characters of
the @code{name} column:
@example
@@ -34557,20 +36588,20 @@ is issued:
@example
mysql> USE db1;
-mysql> SELECT count(*) FROM mytable; # selects from db1.mytable
+mysql> SELECT COUNT(*) FROM mytable; # selects from db1.mytable
mysql> USE db2;
-mysql> SELECT count(*) FROM mytable; # selects from db2.mytable
+mysql> SELECT COUNT(*) FROM mytable; # selects from db2.mytable
@end example
Making a particular database current by means of the @code{USE} statement
-does not preclude you from accessing tables in other databases. The example
-below accesses the @code{author} table from the @code{db1} database and the
+does not preclude you from accessing tables in other databases. The following example
+accesses the @code{author} table from the @code{db1} database and the
@code{editor} table from the @code{db2} database:
@example
mysql> USE db1;
mysql> SELECT author_name,editor_name FROM author,db2.editor
- WHERE author.editor_id = db2.editor.editor_id;
+ -> WHERE author.editor_id = db2.editor.editor_id;
@end example
@cindex Sybase compatibility
@@ -34593,9 +36624,9 @@ The @code{USE} statement is provided for Sybase compatibility.
@code{DESCRIBE} provides information about a table's columns. @code{col_name}
may be a column name or a string containing the SQL @samp{%} and @samp{_}
-wild-card characters.
+wildcard characters.
-If the column types are different than you expect them to be based on a
+If the column types are different from what you expect them to be based on a
@code{CREATE TABLE} statement, note that MySQL sometimes
changes column types. @xref{Silent column changes}.
@@ -34628,8 +36659,8 @@ By default, MySQL runs in @code{autocommit} mode. This means that
as soon as you execute an update, MySQL will store the update on
disk.
-If you are using transactions safe tables (like @code{BDB},
-@code{InnoDB}, you can put MySQL into
+If you are using transactions safe tables (like @code{InnoDB},
+@code{BDB}, you can put MySQL into
non-@code{autocommit} mode with the following command:
@example
@@ -34667,10 +36698,11 @@ rolled back are not stored. @xref{Binary log}.
The following commands automatically end a transaction (as if you had done
a @code{COMMIT} before executing the command):
-@multitable @columnfractions .33 .33 .33
-@item @code{ALTER TABLE} @tab @code{BEGIN} @tab @code{CREATE INDEX}
-@item @code{DROP DATABASE} @tab @code{DROP TABLE} @tab @code{RENAME TABLE}
-@item @code{TRUNCATE}
+@multitable @columnfractions .25 .25 .25
+@item @strong{Command} @tab @strong{Command} @tab @strong{Command}
+@item @code{ALTER TABLE} @tab @code{BEGIN} @tab @code{CREATE INDEX}
+@item @code{DROP DATABASE} @tab @code{DROP TABLE} @tab @code{RENAME TABLE}
+@item @code{TRUNCATE} @tab @tab
@end multitable
You can change the isolation level for transactions with
@@ -34696,6 +36728,12 @@ are locked by the current thread are automatically unlocked when the
thread issues another @code{LOCK TABLES}, or when the connection to the
server is closed.
+To use @code{LOCK TABLES} in MySQL 4.0.2 you need the global
+@code{LOCK TABLES} privilege and a @code{SELECT} privilege on the
+involved tables. In MySQL 3.23 you need to have @code{SELECT},
+@code{insert}, @code{DELETE} and @code{UPDATE} privileges for the
+tables.
+
The main reasons to use @code{LOCK TABLES} are for emulating transactions
or getting more speed when updating tables. This is explained in more
detail later.
@@ -34753,7 +36791,7 @@ tables to transactions safe tables.
You can safely kill a thread that is waiting for a table lock with
@code{KILL}. @xref{KILL}.
-Note that you should @strong{NOT} lock any tables that you are using with
+Note that you should @strong{not} lock any tables that you are using with
@code{INSERT DELAYED}. This is because that in this case the @code{INSERT}
is done by a separate thread.
@@ -34775,16 +36813,16 @@ MySQL will not flush the key cache for the locked tables until
each SQL statement). This speeds up inserting/updateing/deletes on
@code{MyISAM} tables.
@item
-If you are using a table handler in MySQL that doesn't support
-transactions, you must use @code{LOCK TABLES} if you want to ensure that
-no other thread comes between a @code{SELECT} and an @code{UPDATE}. The
-example shown below requires @code{LOCK TABLES} in order to execute safely:
+If you are using a table handler in MySQL that doesn't support
+transactions, you must use @code{LOCK TABLES} if you want to ensure that
+no other thread comes between a @code{SELECT} and an @code{UPDATE}. The
+example shown here requires @code{LOCK TABLES} in order to execute safely:
@example
mysql> LOCK TABLES trans READ, customer WRITE;
-mysql> select sum(value) from trans where customer_id= some_id;
-mysql> update customer set total_value=sum_from_previous_statement
- where customer_id=some_id;
+mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;
+mysql> UPDATE customer SET total_value=sum_from_previous_statement
+ -> WHERE customer_id=some_id;
mysql> UNLOCK TABLES;
@end example
@@ -34807,7 +36845,7 @@ See @ref{Internal locking}, for more information on locking policy.
You can lock all tables in all databases with read locks with the
@code{FLUSH TABLES WITH READ LOCK} command. @xref{FLUSH}. This is very
-convenient way to get backups if you have a file system, like Veritas,
+convenient way to get backups if you have a filesystem, like Veritas,
that can take snapshots in time.
@strong{NOTE}: @code{LOCK TABLES} is not transaction-safe and will
@@ -34818,50 +36856,50 @@ tables.
@node SET TRANSACTION, , LOCK TABLES, Transactional Commands
@subsection @code{SET TRANSACTION} Syntax
+@findex SET TRANSACTION
@findex ISOLATION LEVEL
@example
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
-[READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]
+@{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE @}
@end example
Sets the transaction isolation level for the global, whole session or
the next transaction.
-The default behavior is to set the isolation level for the next (not started)
-transaction.
-
-If you set the @code{GLOBAL} privilege it will affect all new created threads.
-You will need the @code{PROCESS} privilege to do do this.
-
-Setting the @code{SESSION} privilege will affect the following and all
-future transactions.
+The default behaviour is to set the isolation level for the next (not
+started) transaction. If you use the @code{GLOBAL} keyword, the statement
+sets the default transaction level globally for all new connections
+created from that point on. You will need the @code{SUPER}
+privilege to do do this. Using the @code{SESSION} keyword sets the
+default transaction level for all future transactions performed on the
+current connection.
-You can set the default isolation level for @code{mysqld} with
+You can set the default global isolation level for @code{mysqld} with
@code{--transaction-isolation=...}. @xref{Command-line options}.
-
-@node Fulltext Search, , Transactional Commands, Reference
+@node Fulltext Search, Query Cache, Transactional Commands, Reference
@section MySQL Full-text Search
@cindex searching, full-text
@cindex full-text search
@cindex FULLTEXT
-Since Version 3.23.23, MySQL has support for full-text indexing
-and searching. Full-text indexes in MySQL are an index of type
-@code{FULLTEXT}. @code{FULLTEXT} indexes can be created from @code{VARCHAR}
-and @code{TEXT} columns at @code{CREATE TABLE} time or added later with
-@code{ALTER TABLE} or @code{CREATE INDEX}. For large datasets, adding
-@code{FULLTEXT} index with @code{ALTER TABLE} (or @code{CREATE INDEX}) would
-be much faster than inserting rows into the empty table with a @code{FULLTEXT}
-index.
+As of Version 3.23.23, MySQL has support for full-text indexing
+and searching. Full-text indexes in MySQL are an index of type
+@code{FULLTEXT}. @code{FULLTEXT} indexes can be created from @code{VARCHAR}
+and @code{TEXT} columns at @code{CREATE TABLE} time or added later with
+@code{ALTER TABLE} or @code{CREATE INDEX}. For large datasets, it will be
+much faster to load your data into a table that has no @code{FULLTEXT}
+index, then create the index with @code{ALTER TABLE} (or @code{CREATE
+INDEX}). Loading data into a table that already has a @code{FULLTEXT}
+index will be slower.
-Full-text search is performed with the @code{MATCH} function.
+Full-text searching is performed with the @code{MATCH()} function.
@example
mysql> CREATE TABLE articles (
- -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> title VARCHAR(200),
-> body TEXT,
-> FULLTEXT (title,body)
@@ -34869,39 +36907,52 @@ mysql> CREATE TABLE articles (
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO articles VALUES
- -> (0,'MySQL Tutorial', 'DBMS stands for DataBase Management ...'),
+ -> (0,'MySQL Tutorial', 'DBMS stands for DataBase ...'),
-> (0,'How To Use MySQL Efficiently', 'After you went through a ...'),
- -> (0,'Optimizing MySQL','In this tutorial we will show how to ...'),
- -> (0,'1001 MySQL Trick','1. Never run mysqld as root. 2. Normalize ...'),
- -> (0,'MySQL vs. YourSQL', 'In the following database comparison we ...'),
- -> (0,'MySQL Security', 'When configured properly, MySQL could be ...');
-Query OK, 5 rows affected (0.00 sec)
-Records: 5 Duplicates: 0 Warnings: 0
-
-mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');
-+----+-------------------+---------------------------------------------+
-| id | title | body |
-+----+-------------------+---------------------------------------------+
-| 5 | MySQL vs. YourSQL | In the following database comparison we ... |
-| 1 | MySQL Tutorial | DBMS stands for DataBase Management ... |
-+----+-------------------+---------------------------------------------+
+ -> (0,'Optimising MySQL','In this tutorial we will show ...'),
+ -> (0,'1001 MySQL Trick','1. Never run mysqld as root. 2. ...'),
+ -> (0,'MySQL vs. YourSQL', 'In the following database comparison ...'),
+ -> (0,'MySQL Security', 'When configured properly, MySQL ...');
+Query OK, 6 rows affected (0.00 sec)
+Records: 6 Duplicates: 0 Warnings: 0
+
+mysql> SELECT * FROM articles
+ -> WHERE MATCH (title,body) AGAINST ('database');
++----+-------------------+------------------------------------------+
+| id | title | body |
++----+-------------------+------------------------------------------+
+| 5 | MySQL vs. YourSQL | In the following database comparison ... |
+| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
++----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)
@end example
-The function @code{MATCH} matches a natural language query @code{AGAINST}
-a text collection (which is simply the set of columns covered by a
-@code{FULLTEXT} index). For every row in a table it returns relevance -
-a similarity measure between the text in that row (in the columns that are
-part of the collection) and the query. When it is used in a @code{WHERE}
-clause (see example above) the rows returned are automatically sorted with
-relevance decreasing. Relevance is a non-negative floating-point number.
-Zero relevance means no similarity. Relevance is computed based on the
-number of words in the row, the number of unique words in that row, the
-total number of words in the collection, and the number of documents (rows)
-that contain a particular word.
+The @code{MATCH()} function performs a natural language search for a string
+against a text collection (a set of of one or more columns included in
+a @code{FULLTEXT} index). The search string is given as the argument to
+@code{AGAINST()}. The search is performed in case-insensitive fashion.
+For every row in the table, @code{MATCH()} returns a relevance value,
+that is, a similarity measure between the search string and the text in
+that row in the columns named in the @code{MATCH()} list.
+
+When @code{MATCH()} is used in a @code{WHERE} clause (see example above)
+the rows returned are automatically sorted with highest relevance first.
+Relevance values are non-negative floating-point numbers. Zero relevance
+means no similarity. Relevance is computed based on the number of words
+in the row, the number of unique words in that row, the total number of
+words in the collection, and the number of documents (rows) that contain
+a particular word.
-The above is a basic example of using @code{MATCH} function. Rows are
-returned with relevance decreasing.
+It is also possible to perform a boolean mode search. This is explained
+later in the section.
+
+The preceding example is a basic illustration showing how to use the
+@code{MATCH()} function. Rows are returned in order of decreasing
+relevance.
+
+The next example shows how to retrieve the relevance values explicitly.
+As neither @code{WHERE} nor @code{ORDER BY} clauses are present, returned
+rows are not ordered.
@example
mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles;
@@ -34915,38 +36966,36 @@ mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles;
| 5 | 0 |
| 6 | 0 |
+----+-----------------------------------------+
-5 rows in set (0.00 sec)
+6 rows in set (0.00 sec)
@end example
-This example shows how to retrieve the relevances. As neither @code{WHERE}
-nor @code{ORDER BY} clauses are present, returned rows are not ordered.
+The following example is more complex. The query returns the relevance
+and still sorts the rows in order of decreasing relevance. To achieve
+this result, you should specify @code{MATCH()} twice. This will cause no
+additional overhead, because the MySQL optimiser will notice that the
+two @code{MATCH()} calls are identical and invoke the full-text search
+code only once.
@example
-mysql> SELECT id, body, MATCH (title,body) AGAINST (
- -> 'Security implications of running MySQL as root') AS score
+mysql> SELECT id, body, MATCH (title,body) AGAINST
+ -> ('Security implications of running MySQL as root') AS score
-> FROM articles WHERE MATCH (title,body) AGAINST
-> ('Security implications of running MySQL as root');
-+----+-----------------------------------------------+-----------------+
-| id | body | score |
-+----+-----------------------------------------------+-----------------+
-| 4 | 1. Never run mysqld as root. 2. Normalize ... | 1.5055546709332 |
-| 6 | When configured properly, MySQL could be ... | 1.31140957288 |
-+----+-----------------------------------------------+-----------------+
++----+-------------------------------------+-----------------+
+| id | body | score |
++----+-------------------------------------+-----------------+
+| 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 |
+| 6 | When configured properly, MySQL ... | 1.31140957288 |
++----+-------------------------------------+-----------------+
2 rows in set (0.00 sec)
@end example
-This is more complex example - the query returns the relevance and still
-sorts the rows with relevance decreasing. To achieve it one should specify
-@code{MATCH} twice. Note, that this will cause no additional overhead, as
-MySQL optimizer will notice that these two @code{MATCH} calls are
-identical and will call full-text search code only once.
-
-MySQL uses a very simple parser to split text into words. A
-``word'' is any sequence of letters, numbers, @samp{'}, and @samp{_}. Any
-``word'' that is present in the stopword list or just too short (3
-characters or less) is ignored.
+MySQL uses a very simple parser to split text into words. A ``word''
+is any sequence of characters consisting of letters, numbers, @samp{'},
+and @samp{_}. Any ``word'' that is present in the stopword list or is just
+too short (3 characters or less) is ignored.
-Every correct word in the collection and in the query is weighted,
+Every correct word in the collection and in the query is weighted
according to its significance in the query or collection. This way, a
word that is present in many documents will have lower weight (and may
even have a zero weight), because it has lower semantic value in this
@@ -34956,7 +37005,7 @@ relevance of the row.
Such a technique works best with large collections (in fact, it was
carefully tuned this way). For very small tables, word distribution
-does not reflect adequately their semantical value, and this model
+does not reflect adequately their semantic value, and this model
may sometimes produce bizarre results.
@example
@@ -34964,143 +37013,427 @@ mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL');
Empty set (0.00 sec)
@end example
-Search for the word @code{MySQL} produces no results in the above example.
-Word @code{MySQL} is present in more than half of rows, and as such, is
-effectively treated as a stopword (that is, with semantical value zero).
-It is, really, the desired behavior - a natural language query should not
-return every second row in 1GB table.
+The search for the word @code{MySQL} produces no results in the above
+example, because that word is present in more than half the rows. As such,
+it is effectively treated as a stopword (that is, a word with zero semantic
+value). This is the most desirable behaviour -- a natural language query
+should not return every second row from a 1GB table.
A word that matches half of rows in a table is less likely to locate relevant
documents. In fact, it will most likely find plenty of irrelevant documents.
We all know this happens far too often when we are trying to find something on
-the Internet with a search engine. It is with this reasoning that such rows
-have been assigned a low semantical value in @strong{this particular dataset}.
+the Internet with a search engine. It is with this reasoning that such rows
+have been assigned a low semantic value in @strong{this particular dataset}.
+
+As of Version 4.0.1, MySQL can also perform boolean full-text searches using
+the @code{IN BOOLEAN MODE} modifier.
+
+@example
+mysql> SELECT * FROM articles WHERE MATCH (title,body)
+ -> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
++----+------------------------------+-------------------------------------+
+| id | title | body |
++----+------------------------------+-------------------------------------+
+| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
+| 2 | How To Use MySQL Efficiently | After you went through a ... |
+| 3 | Optimising MySQL | In this tutorial we will show ... |
+| 4 | 1001 MySQL Trick | 1. Never run mysqld as root. 2. ... |
+| 6 | MySQL Security | When configured properly, MySQL ... |
++----+------------------------------+-------------------------------------+
+@end example
+
+This query retrieved all the rows that contain the word @code{MySQL}
+(note: the 50% threshold is not used), but that do @strong{not} contain
+the word @code{YourSQL}. Note that a boolean mode search does not
+auto-magically sort rows in order of decreasing relevance. You can
+see this from result of the preceding query, where the row with the
+highest relevance (the one that contains @code{MySQL} twice) is listed
+last, not first. A boolean full-text search can also work even without
+a @code{FULLTEXT} index, although it would be @strong{slow}.
+
+The boolean full-text search capability supports the following operators:
+
+@table @code
+@item +
+A leading plus sign indicates that this word @strong{must be}
+present in every row returned.
+@item -
+A leading minus sign indicates that this word @strong{must not be}
+present in any row returned.
+@item
+By default (when neither plus nor minus is specified) the word is optional,
+but the rows that contain it will be rated higher. This mimicks the
+behaviour of @code{MATCH() ... AGAINST()} without the @code{IN BOOLEAN
+MODE} modifier.
+@item < >
+These two operators are used to change a word's contribution to the
+relevance value that is assigned to a row. The @code{<} operator
+decreases the contribution and the @code{>} operator increases it.
+See the example below.
+@item ( )
+Parentheses are used to group words into subexpressions.
+@item ~
+A leading tilde acts as a negation operator, causing the word's
+contribution to the row relevance to be negative. It's useful for marking
+noise words. A row that contains such a word will be rated lower than
+others, but will not be excluded altogether, as it would be with the
+@code{-} operator.
+@item *
+An asterisk is the truncation operator. Unlike the other operators, it
+should be @strong{appended} to the word, not prepended.
+@item "
+The phrase, that is enclosed in double quotes @code{"}, matches only
+rows that contain this phrase @strong{literally, as it was typed}.
+@end table
+
+And here are some examples:
+
+@table @code
+@item apple banana
+find rows that contain at least one of these words.
+@item +apple +juice
+... both words.
+@item +apple macintosh
+... word ``apple'', but rank it higher if it also contain ``macintosh''.
+@item +apple -macintosh
+... word ``apple'' but not ``macintosh''.
+@item +apple +(>pie <strudel)
+... ``apple'' and ``pie'', or ``apple'' and ``strudel'' (in any
+order), but rank ``apple pie'' higher than ``apple strudel''.
+@item apple*
+... ``apple'', ``apples'', ``applesauce'', and ``applet''.
+@item "some words"
+... ``some words of wisdom'', but not ``some noise words''.
+@end table
@menu
-* Fulltext restrictions:: Fulltext restrictions
+* Fulltext Restrictions:: Full-text Restrictions
* Fulltext Fine-tuning:: Fine-tuning MySQL Full-text Search
-* Fulltext Features to Appear in MySQL 4.0:: New Features of Full-text Search to Appear in MySQL 4.0
* Fulltext TODO:: Full-text Search TODO
@end menu
-
-@node Fulltext restrictions, Fulltext Fine-tuning, Fulltext Search, Fulltext Search
-@subsection Fulltext restrictions
+@node Fulltext Restrictions, Fulltext Fine-tuning, Fulltext Search, Fulltext Search
+@subsection Full-text Restrictions
@itemize @bullet
@item
-All parameters to the @code{MATCH} function must be columns from the
-same table that is part of the same fulltext index.
+All parameters to the @code{MATCH()} function must be columns from the
+same table that is part of the same @code{FULLTEXT} index, unless the
+@code{MATCH()} is @code{IN BOOLEAN MODE}.
+@item
+The @code{MATCH()} column list must exactly match the column list in some
+@code{FULLTEXT} index definition for the table, unless this @code{MATCH()}
+is @code{IN BOOLEAN MODE}.
@item
-The argument to @code{AGAINST} must be a constant string.
+The argument to @code{AGAINST()} must be a constant string.
@end itemize
-@node Fulltext Fine-tuning, Fulltext Features to Appear in MySQL 4.0, Fulltext restrictions, Fulltext Search
+@node Fulltext Fine-tuning, Fulltext TODO, Fulltext Restrictions, Fulltext Search
@subsection Fine-tuning MySQL Full-text Search
-Unfortunately, full-text search has no user-tunable parameters yet,
-although adding some is very high on the TODO. However, if you have a
-MySQL source distribution (@xref{Installing source}.), you can
-somewhat alter the full-text search behavior.
+Unfortunately, full-text search has few user-tunable parameters yet,
+although adding some is very high on the TODO. If you have a
+MySQL source distribution (@pxref{Installing source}), you can
+exert more control over full-text searching behaviour.
Note that full-text search was carefully tuned for the best searching
-effectiveness. Modifying the default behavior will, in most cases,
+effectiveness. Modifying the default behaviour will, in most cases,
only make the search results worse. Do not alter the MySQL sources
unless you know what you are doing!
@itemize @bullet
@item
-Minimal length of word to be indexed is defined in
-@code{myisam/ftdefs.h} file by the line
-@example
-#define MIN_WORD_LEN 4
-@end example
-Change it to the value you prefer, recompile MySQL, and rebuild
-your @code{FULLTEXT} indexes.
+The minimum length of words to be indexed is defined by the MySQL
+variable @code{ft_min_word_len}. @xref{SHOW VARIABLES}.
+Change it to the value you prefer, and rebuild your @code{FULLTEXT} indexes.
+(This variable is only available from MySQL version 4.0.)
@item
-The stopword list is defined in @code{myisam/ft_static.c}
-Modify it to your taste, recompile MySQL and rebuild
+The stopword list is defined in @file{myisam/ft_static.c}
+Modify it to your taste, recompile MySQL, and rebuild
your @code{FULLTEXT} indexes.
@item
-The 50% threshold is caused by the particular weighting scheme chosen. To
-disable it, change the following line in @code{myisam/ftdefs.h}:
+The 50% threshold is determined by the particular weighting scheme chosen.
+To disable it, change the following line in @file{myisam/ftdefs.h}:
@example
#define GWS_IN_USE GWS_PROB
@end example
-to
+To:
@example
#define GWS_IN_USE GWS_FREQ
@end example
-and recompile MySQL.
+Then recompile MySQL.
There is no need to rebuild the indexes in this case.
+@strong{Note}: by doing this you @strong{severely} decrease MySQL's ability
+to provide adequate relevance values for the @code{MATCH()} function.
+If you really need to search for such common words, it would be better to
+search using @code{IN BOOLEAN MODE} instead, which does not observe the 50%
+threshold.
+
+@item
+Sometimes the search engine maintainer would like to change the operators used
+for boolean full-text searches. These are defined by the
+@code{ft_boolean_syntax} variable. @xref{SHOW VARIABLES}.
+Still, this variable is read-only, its value is set in
+@file{myisam/ft_static.c}.
@end itemize
+@node Fulltext TODO, , Fulltext Fine-tuning, Fulltext Search
+@subsection Full-text Search TODO
-@node Fulltext Features to Appear in MySQL 4.0, Fulltext TODO, Fulltext Fine-tuning, Fulltext Search
-@subsection New Features of Full-text Search to Appear in MySQL 4.0
+@itemize @bullet
+@item Make all operations with @code{FULLTEXT} index @strong{faster}.
+@item Proximity operators
+@item Support for "always-index words". They could be any strings
+the user wants to treat as words, examples are "C++", "AS/400", "TCP/IP", etc.
+@item Support for full-text search in @code{MERGE} tables.
+@item Support for multi-byte charsets.
+@item Make stopword list to depend of the language of the data.
+@item Stemming (dependent of the language of the data, of course).
+@item Generic user-suppliable UDF preparser.
+@item Make the model more flexible (by adding some adjustable
+parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}).
+@end itemize
-This section includes a list of the fulltext features that are already
-implemented in the 4.0 tree. It explains
-@strong{More functions for full-text search} entry of @ref{TODO MySQL 4.0}.
-@itemize @bullet
-@item @code{REPAIR TABLE} with @code{FULLTEXT} indexes,
-@code{ALTER TABLE} with @code{FULLTEXT} indexes, and
-@code{OPTIMIZE TABLE} with @code{FULLTEXT} indexes are now
-up to 100 times faster.
+@node Query Cache, , Fulltext Search, Reference
+@section MySQL Query Cache
-@item @code{MATCH ... AGAINST} is going to supports the following
-@strong{boolean operators}:
+@cindex Query Cache
+@cindex @code{SELECT}, Query Cache
+
+From version 4.0.1, @code{MySQL server} features a @code{Query Cache}.
+When in use, the query cache stores the text of a @code{SELECT} query
+together with the corresponding result that was sent to the client.
+If an identical query is later received, the server will retrieve
+the results from the query cache rather than parsing and executing the
+same query again.
+
+@strong{NOTE:} The query cache does not return stale data. When data
+is modified, any relevant entries in the query cache are flushed.
+
+The query cache is extremely useful in an environment where (some)
+tables don't change very often and you have a lot of identical queries.
+This is a typical situation for many web servers that use a lot of
+dynamic content.
+
+Below is some performance data for the query cache. (These results were
+generated by running the MySQL benchmark suite on a Linux Alpha
+2 x 500 MHz with 2GB RAM and a 64MB query cache):
@itemize @bullet
-@item @code{+}word means the that word @strong{must} be present in every
-row returned.
-@item @code{-}word means the that word @strong{must not} be present in every
-row returned.
-@item @code{<} and @code{>} can be used to decrease and increase word
-weight in the query.
-@item @code{~} can be used to assign a @strong{negative} weight to a noise
-word.
-@item @code{*} is a truncation operator.
+@item
+If all of the queries you're performing are simple (such as selecting a
+row from a table with one row); but still differ so that the queries can
+not be cached, the overhead for having the query cache active is 13%.
+This could be regarded as the worst case scenario. However, in real life,
+queries are much more complicated than our simple example so the overhead
+is normally significantly lower.
+@item
+Searches after one row in a one row table is 238% faster.
+This can be regarded as close to the minimum speedup to be expected for
+a query that is cached.
+@item
+If you want to disable the query cache code set @code{query_cache_size=0}.
+By disabling the query cache code there is no noticeable overhead.
+(query cache can be excluded from code with help of configure option
+@code{--without-query-cache})
@end itemize
-Boolean search utilizes a more simplistic way of calculating the relevance,
-that does not have a 50% threshold.
+@menu
+* Query Cache How:: How The Query Cache Operates
+* Query Cache Configuration:: Query Cache Configuration
+* Query Cache in SELECT:: Query Cache Options in @code{SELECT}
+* Query Cache Status and Maintenance:: Query Cache Status and Maintenance
+@end menu
-@item Searches are now up to 2 times faster due to optimized search algorithm.
-@item Utility program @code{ft_dump} added for low-level @code{FULLTEXT}
-index operations (querying/dumping/statistics).
+@node Query Cache How, Query Cache Configuration, Query Cache, Query Cache
+@subsection How The Query Cache Operates
-@end itemize
+Queries are compared before parsing, thus
+@example
+SELECT * FROM TABLE
+@end example
-@node Fulltext TODO, , Fulltext Features to Appear in MySQL 4.0, Fulltext Search
-@subsection Full-text Search TODO
+and
-@itemize @bullet
-@item Make all operations with @code{FULLTEXT} index @strong{faster}.
-@item Support for braces @code{()} in boolean full-text search.
-@item Phrase search, proximity operators
-@item Boolean search can work without @code{FULLTEXT} index
-(yes, @strong{very} slow).
-@item Support for "always-index words". They could be any strings
-the user wants to treat as words, examples are "C++", "AS/400", "TCP/IP", etc.
-@item Support for full-text search in @code{MERGE} tables.
-@item Support for multi-byte charsets.
-@item Make stopword list to depend of the language of the data.
-@item Stemming (dependent of the language of the data, of course).
-@item Generic user-supplyable UDF (?) preparser.
-@item Make the model more flexible (by adding some adjustable
-parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}).
+@example
+Select * from table
+@end example
+
+are regarded as different queries for query cache, so queries need
+to be exactly the same (byte for byte) to be seen as identical.
+In addition, a query may be seen as different if for instance one
+client is using a new communication protocol format or another
+character set than another client.
+
+Queries that uses different databases, uses different protocol versions
+or the uses different default character sets are considered different
+queries and cached separately.
+
+The cache does work for @code{SELECT CALC_ROWS ...} and
+@code{SELECT FOUND_ROWS() ...} type queries because the number of
+found rows is also stored in the cache.
+
+If a table changes (@code{INSERT}, @code{UPDATE}, @code{DELETE},
+@code{TRUNCATE}, @code{ALTER} or @code{DROP TABLE|DATABASE}),
+then all cached queries that used this table (possibly through a
+@code{MRG_MyISAM} table!) become invalid and are removed from the cache.
+
+Transactional @code{InnoDB} tables that have been changed will be invalidated
+when a @code{COMMIT} is performed.
+
+A query cannot be cached if it contains one of the functions:
+@multitable @columnfractions .33 .33 .34
+@item @strong{Function}
+ @tab @strong{Function}
+ @tab @strong{Function}
+@item @code{User-Defined Functions}
+ @tab @code{CONNECTION_ID}
+ @tab @code{FOUND_ROWS}
+@item @code{GET_LOCK}
+ @tab @code{RELEASE_LOCK}
+ @tab @code{LOAD_FILE}
+@item @code{MASTER_POS_WAIT}
+ @tab @code{NOW}
+ @tab @code{SYSDATE}
+@item @code{CURRENT_TIMESTAMP}
+ @tab @code{CURDATE}
+ @tab @code{CURRENT_DATE}
+@item @code{CURTIME}
+ @tab @code{CURRENT_TIME}
+ @tab @code{DATABASE}
+@item @code{ENCRYPT} (with one parameter)
+ @tab @code{LAST_INSERT_ID}
+ @tab @code{RAND}
+@item @code{UNIX_TIMESTAMP} (without parameters)
+ @tab @code{USER}
+ @tab @code{BENCHMARK}
+@end multitable
+
+Nor can a query be cached if it contains user variables,
+if it is of the form @code{SELECT ... IN SHARE MODE} or
+of the form @code{SELECT * FROM AUTOINCREMENT_FIELD IS NULL}
+(to retrieve last insert id - ODBC work around).
+
+However, @code{FOUND ROWS()} will return the correct value,
+even if the preceding query was fetched from the cache.
+
+Queries that don't use any tables or if the user has a column privilege for
+any of the involved tables are not cached.
+
+Before a query is fetched from the query cache, MySQL will check that
+the user has SELECT privilege to all the involved databases and
+tables. If this is not the case, the cached result will not be used.
+
+@node Query Cache Configuration, Query Cache in SELECT, Query Cache How, Query Cache
+@subsection Query Cache Configuration
+
+The query cache adds a few @code{MySQL} system variables for
+@code{mysqld} which may be set in a configuration file, on the
+command-line when starting @code{mysqld}.
+
+@itemize
+@item @code{query_cache_limit}
+Don't cache results that are bigger than this. (Default 1M).
+
+@item @code{query_cache_size}
+The memory allocated to store results from old queries.
+If this is 0, the query cache is disabled (default).
+
+@item @code{query_cache_type}
+This may be set (only numeric) to
+@multitable @columnfractions .10 .75
+@item @strong{Option} @tab @strong{Description}
+@item 0 @tab (OFF, don't cache or retrieve results)
+@item 1 @tab (ON, cache all results except @code{SELECT SQL_NO_CACHE ...} queries)
+@item 2 @tab (DEMAND, cache only @code{SELECT SQL_CACHE ...} queries)
+@end multitable
@end itemize
+Inside a thread (connection), the behaviour of the query cache can be
+changed from the default. The syntax is as follows:
+
+@code{QUERY_CACHE_TYPE = OFF | ON | DEMAND}
+@code{QUERY_CACHE_TYPE = 0 | 1 | 2}
+
+@multitable @columnfractions .20 .70
+@item @strong{Option} @tab @strong{Description}
+@item 0 or OFF @tab Don't cache or retrieve results.
+@item 1 or ON @tab Cache all results except @code{SELECT SQL_NO_CACHE ...} queries.
+@item 2 or DEMAND @tab Cache only @code{SELECT SQL_CACHE ...} queries.
+@end multitable
+
+
+@node Query Cache in SELECT, Query Cache Status and Maintenance, Query Cache Configuration, Query Cache
+@subsection Query Cache Options in @code{SELECT}
+
+There are two possible query cache related parameters that may be
+specified in a @code{SELECT} query:
+
+@findex SQL_CACHE
+@findex SQL_NO_CACHE
+
+@multitable @columnfractions .20 .80
+@item @strong{Option} @tab @strong{Description}
+@item @code{SQL_CACHE}
+ @tab If @code{QUERY_CACHE_TYPE} is @code{DEMAND}, allow the query to be cached.
+ If @code{QUERY_CACHE_TYPE} is @code{ON}, this is the default.
+ If @code{QUERY_CACHE_TYPE} is @code{OFF}, do nothing.
+@item @code{SQL_NO_CACHE}
+ @tab Make this query non-cachable, don't allow this query to be stored in the cache.
+@end multitable
+
+
+@node Query Cache Status and Maintenance, , Query Cache in SELECT, Query Cache
+@subsection Query Cache Status and Maintenance
+
+With the @code{FLUSH QUERY CACHE} command you can defragment the query
+cache to better utilise its memory. This command will not remove any
+queries from the cache.
+@code{FLUSH TABLES} also flushes the query cache.
+
+The @code{RESET QUERY CACHE} command removes all query results from the
+query cache.
+
+You can monitor query cache performance in @code{SHOW STATUS}:
+
+@multitable @columnfractions .30 .50
+@item @strong{Variable} @tab @strong{Description}
+@item @code{Qcache_queries_in_cache}
+ @tab Number of queries registered in the cache.
+@item @code{Qcache_inserts}
+ @tab Number of queries added to the cache.
+@item @code{Qcache_hits}
+ @tab Number of cache hits.
+@item @code{Qcache_not_cached}
+ @tab Number of non-cached queries
+ (not cachable, or due to @code{QUERY_CACHE_TYPE}).
+@item @code{Qcache_free_memory}
+ @tab Amount of free memory for query cache.
+@item @code{Qcache_total_blocks}
+ @tab Total number of blocks in query cache.
+@item @code{Qcache_free_blocks}
+ @tab Number of free memory blocks in query cache.
+@end multitable
+Total number of queries =
+@code{Qcache_inserts} + @code{Qcache_hits} + @code{Qcache_not_cached}.
+
+The query cache uses variable length blocks, so @code{Qcache_total_blocks}
+and @code{Qcache_free_blocks} may indicate query cache memory fragmentation.
+After @code{FLUSH QUERY CACHE} only a single (big) free block remains.
+
+Note: Every query needs a minimum of two blocks (one for the query text
+and one or more for the query results). Also, every table that is used
+by a query needs one block, but if two or more queries use same table
+only one block needs to be allocated.
@node Table types, Clients, Reference, Top
@@ -35108,7 +37441,7 @@ parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}).
@cindex table types, choosing
@cindex @code{BDB} table type
-@cindex @code{Berkeley_db} table type
+@cindex @code{BerkeleyDB} table type
@cindex @code{HEAP} table type
@cindex @code{ISAM} table type
@cindex @code{InnoDB} table type
@@ -35119,12 +37452,12 @@ parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}).
As of MySQL Version 3.23.6, you can choose between three basic
table formats (@code{ISAM}, @code{HEAP} and @code{MyISAM}. Newer
-MySQL may support additional table type (@code{BDB},
-or @code{InnoDB}), depending on how you compile it.
-
+MySQL may support additional table type (@code{InnoDB},
+or @code{BDB}), depending on how you compile it.
+
When you create a new table, you can tell MySQL which table
type it should use for the table. MySQL will always create a
-@code{.frm} file to hold the table and column definitions. Depending on
+@file{.frm} file to hold the table and column definitions. Depending on
the table type, the index and data will be stored in other files.
Note that to use @code{InnoDB} tables you have to use at least
@@ -35135,7 +37468,7 @@ trying to use a table type that is not compiled-in or activated,
MySQL will instead create a table of type @code{MyISAM}. This
is a very useful feature when you want to copy tables between different
SQL servers that supports different table types (like copying tables to
-a slave that is optimized for speed by not having transactional tables).
+a slave that is optimised for speed by not having transactional tables).
This automatic table changing can however also be very confusing for new
MySQL users. We plan to fix this by introducing warnings in
MySQL 4.0 and giving a warning when a table type is automatically
@@ -35145,7 +37478,7 @@ You can convert tables between different types with the @code{ALTER
TABLE} statement. @xref{ALTER TABLE, , @code{ALTER TABLE}}.
Note that MySQL supports two different kinds of
-tables. Transaction-safe tables (@code{BDB}, @code{InnoDB}
+tables: transaction-safe tables (@code{InnoDB} and @code{BDB})
and not transaction-safe tables (@code{HEAP}, @code{ISAM},
@code{MERGE}, and @code{MyISAM}).
@@ -35182,38 +37515,39 @@ You can combine TST and NTST tables in the same statements to get the best
of both worlds.
@menu
-* MyISAM:: MyISAM tables
-* MERGE:: MERGE tables
-* ISAM:: ISAM tables
-* HEAP:: HEAP tables
-* BDB:: BDB or Berkeley_db tables
-* InnoDB:: InnoDB tables
+* MyISAM:: @code{MyISAM} tables
+* MERGE:: @code{MERGE} tables
+* ISAM:: @code{ISAM} tables
+* HEAP:: @code{HEAP} tables
+* InnoDB:: @code{InnoDB} tables
+* BDB:: @code{BDB} or @code{BerkeleyDB} tables
@end menu
@node MyISAM, MERGE, Table types, Table types
-@section MyISAM Tables
+@section @code{MyISAM} Tables
@code{MyISAM} is the default table type in MySQL Version 3.23. It's
based on the @code{ISAM} code and has a lot of useful extensions.
-The index is stored in a file with the @code{.MYI} (MYIndex) extension,
-and the data is stored in a file with the @code{.MYD} (MYData) extension.
+The index is stored in a file with the @file{.MYI} (MYIndex) extension,
+and the data is stored in a file with the @file{.MYD} (MYData) extension.
You can check/repair @code{MyISAM} tables with the @code{myisamchk}
-utility. @xref{Crash recovery}. You can compress @code{MyISAM} tables with
-@code{myisampack} to take up much less space. @xref{myisampack}.
+utility. @xref{Crash recovery}. You can compress @code{MyISAM} tables with
+@code{myisampack} to take up much less space.
+@xref{myisampack, , @code{myisampack}}.
The following is new in @code{MyISAM}:
@itemize @bullet
@item
-There is a flag in the @code{MyISAM} file that indicates whether or not
+There is a flag in the @code{MyISAM} file that indicates whether
the table was closed correctly. If @code{mysqld} is started with
@code{--myisam-recover}, @code{MyISAM} tables will automatically be
checked and/or repaired on open if the table wasn't closed properly.
@item
You can @code{INSERT} new rows in a table that doesn't have free blocks
-in the middle of the data file, at the same time other threads are
+in the middle of the datafile, at the same time other threads are
reading from the table (concurrent insert). An free block can come from
an update of a dynamic length row with much data to a row with less data
or when deleting rows. When all free blocks are used up, all future
@@ -35230,7 +37564,7 @@ mainstream machines). The only area of machines that may not support
binary compatibility are embedded systems (because they sometimes have
peculiar processors).
-There is no big speed penalty in storing data low byte first; The bytes
+There is no big speed penalty in storing data low byte first; the bytes
in a table row is normally unaligned and it doesn't take that much more
power to read an unaligned byte in order than in reverse order. The
actual fetch-column-value code is also not time critical compared to
@@ -35242,14 +37576,14 @@ compression.
Internal handling of one @code{AUTO_INCREMENT} column. @code{MyISAM}
will automatically update this on @code{INSERT/UPDATE}. The
@code{AUTO_INCREMENT} value can be reset with @code{myisamchk}. This
-will make @code{AUTO_INCREMENT} columns faster (at least 10 %) and old
+will make @code{AUTO_INCREMENT} columns faster (at least 10%) and old
numbers will not be reused as with the old @code{ISAM}. Note that when an
@code{AUTO_INCREMENT} is defined on the end of a multi-part-key the old
-behavior is still present.
+behaviour is still present.
@item
When inserted in sorted order (as when you are using an @code{AUTO_INCREMENT}
column) the key tree will be split so that the high node only contains one
-key. This will improve the space utilization in the key tree.
+key. This will improve the space utilisation in the key tree.
@item
@code{BLOB} and @code{TEXT} columns can be indexed.
@item
@@ -35260,7 +37594,7 @@ Maximum key length is 500 bytes by default (can be changed by
recompiling). In cases of keys longer than 250 bytes, a bigger key
block size than the default of 1024 bytes is used for this key.
@item
-Maximum number of keys/table is 32 as default. This can be enlarged to 64
+Maximum number of keys/table is 32 as default. This can be enlarged to 64
without having to recompile @code{myisamchk}.
@item
@code{myisamchk} will mark tables as checked if one runs it with
@@ -35286,7 +37620,7 @@ will be able to use in the near future:
@itemize @bullet
@item
-Support for a true @code{VARCHAR} type; A @code{VARCHAR} column starts
+Support for a true @code{VARCHAR} type; a @code{VARCHAR} column starts
with a length stored in 2 bytes.
@item
Tables with @code{VARCHAR} may have fixed or dynamic record length.
@@ -35302,37 +37636,38 @@ can't search on a @code{UNIQUE} computed index, however.)
Note that index files are usually much smaller with @code{MyISAM} than with
@code{ISAM}. This means that @code{MyISAM} will normally use less
-system resources than @code{ISAM}, but will need more CPU when inserting
+system resources than @code{ISAM}, but will need more CPU time when inserting
data into a compressed index.
-The following options to @code{mysqld} can be used to change the behavior of
+The following options to @code{mysqld} can be used to change the behaviour of
@code{MyISAM} tables. @xref{SHOW VARIABLES}.
@multitable @columnfractions .40 .60
-@item @strong{Option} @tab @strong{Meaning}
-@item @code{--myisam-recover=#} @tab Automatic recover of crashed tables.
+@item @strong{Option} @tab @strong{Description}
+@item @code{--myisam-recover=#} @tab Automatic recovery of crashed tables.
@item @code{-O myisam_sort_buffer_size=#} @tab Buffer used when recovering tables.
@item @code{--delay-key-write-for-all-tables} @tab Don't flush key buffers between writes for any MyISAM table
-@item @code{-O myisam_max_extra_sort_file_size=#} @tab Used to help MySQL to decide when to use the slow but safe key cache index create method. @strong{NOTE} that this parameter is given in megabytes!
-@item @code{-O myisam_max_sort_file_size=#} @tab Don't use the fast sort index method to created index if the temporary file would get bigger than this.
-@strong{NOTE} that this paramter is given in megabytes!
+@item @code{-O myisam_max_extra_sort_file_size=#} @tab Used to help MySQL to decide when to use the slow but safe key cache index create method. @strong{Note} that this parameter is given in megabytes!
+@item @code{-O myisam_max_sort_file_size=#} @tab Don't use the fast sort index method to created index if the temporary file would get bigger than this. @strong{Note} that this paramter is given in megabytes!
+@item @code{-O bulk_insert_buffer_size=#} @tab Size of tree cache used in bulk insert optimisation. @strong{Note} that this is a limit @strong{per thread}!
@end multitable
The automatic recovery is activated if you start @code{mysqld} with
@code{--myisam-recover=#}. @xref{Command-line options}.
On open, the table is checked if it's marked as crashed or if the open
count variable for the table is not 0 and you are running with
-@code{--skip-locking}. If either of the above is true the following happens.
+@code{--skip-external-locking}. If either of the above is true the following
+happens.
@itemize @bullet
@item
The table is checked for errors.
@item
If we found an error, try to do a fast repair (with sorting and without
-re-creating the data file) of the table.
+re-creating the datafile) of the table.
@item
-If the repair fails because of an error in the data file (for example a
-duplicate key error), we try again, but this time we re-create the data file.
+If the repair fails because of an error in the datafile (for example a
+duplicate key error), we try again, but this time we re-create the datafile.
@item
If the repair fails, retry once more with the old repair option method
(write row by row without sorting) which should be able to repair any
@@ -35364,8 +37699,8 @@ backup media.
@menu
* Key space:: Space needed for keys
-* MyISAM table formats:: MyISAM table formats
-* MyISAM table problems:: MyISAM table problems.
+* MyISAM table formats:: @code{MyISAM} Table Formats
+* MyISAM table problems:: @code{MyISAM} Table Problems
@end menu
@@ -35395,12 +37730,19 @@ high-byte first.
@node MyISAM table formats, MyISAM table problems, Key space, MyISAM
-@subsection MyISAM Table Formats
+@subsection @code{MyISAM} Table Formats
-@strong{MyISAM} supports 3 different table types. Two of them are chosen
+@code{MyISAM} supports 3 different table types. Two of them are chosen
automatically depending on the type of columns you are using. The third,
compressed tables, can only be created with the @code{myisampack} tool.
+When you @code{CREATE} or @code{ALTER} a table you can for tables that
+doesn't have @code{BLOB}s force the table format to @code{DYNAMIC} or
+@code{FIXED} with the @code{ROW_FORMAT=#} table option. In the future
+you will be able to compress/decompress tables by specifying
+@code{ROW_FORMAT=compressed | default} to @code{ALTER TABLE}.
+@xref{CREATE TABLE}.
+
@menu
* Static format:: Static (Fixed-length) table characteristics
* Dynamic format:: Dynamic table characteristics
@@ -35440,7 +37782,7 @@ Easy to cache.
Easy to reconstruct after a crash, because records are located in fixed
positions.
@item
-Doesn't have to be reorganized (with @code{myisamchk}) unless a huge number of
+Doesn't have to be reorganised (with @code{myisamchk}) unless a huge number of
records are deleted and you want to return free disk space to the operating
system.
@item
@@ -35527,7 +37869,7 @@ This is a read-only type that is generated with the optional
All MySQL distributions, even those that existed before MySQL
went GPL, can read tables that were compressed with @code{myisampack}.
@item
-Compressed tables take very little disk space. This minimizes disk usage, which
+Compressed tables take very little disk space. This minimises disk usage, which
is very nice when using slow disks (like CD-ROMs).
@item
Each record is compressed separately (very little access overhead). The
@@ -35555,28 +37897,27 @@ converted to @code{ENUM}.
A column may use a combination of the above compressions.
@end itemize
@item
-Can handle fixed- or dynamic-length records, but not @code{BLOB} or @code{TEXT}
-columns.
+Can handle fixed- or dynamic-length records.
@item
Can be uncompressed with @code{myisamchk}.
@end itemize
@node MyISAM table problems, , MyISAM table formats, MyISAM
-@subsection MyISAM table problems.
+@subsection @code{MyISAM} Table Problems
The file format that MySQL uses to store data has been extensively
tested, but there are always circumstances that may cause database tables
to become corrupted.
@menu
-* Corrupted MyISAM tables:: Corrupted MyISAM tables.
+* Corrupted MyISAM tables:: Corrupted @code{MyISAM} Tables
* MyISAM table close:: Clients is using or hasn't closed the table properly
@end menu
@node Corrupted MyISAM tables, MyISAM table close, MyISAM table problems, MyISAM table problems
-@subsubsection Corrupted MyISAM tables.
+@subsubsection Corrupted @code{MyISAM} Tables
Even if the MyISAM table format is very reliable (all changes to a table
is written before the SQL statements returns) , you can still get
@@ -35614,7 +37955,7 @@ You can also repair a table, when @code{mysqld} is not running with
the @code{myisamchk} command. @code{myisamchk syntax}.
If your tables get corrupted a lot you should try to find the reason for
-this! @xref{Crashing}.
+this! @xref{Crashing}.
In this case the most important thing to know is if the table got
corrupted if the @code{mysqld} died (one can easily verify this by
@@ -35626,7 +37967,7 @@ case of this. @xref{Reproduceable test case}.
@node MyISAM table close, , Corrupted MyISAM tables, MyISAM table problems
@subsubsection Clients is using or hasn't closed the table properly
-Each @code{MyISAM} @code{.MYI} file has in the header a counter that can
+Each @code{MyISAM} @file{.MYI} file has in the header a counter that can
be used to check if a table has been closed properly.
If you get the following warning from @code{CHECK TABLE} or @code{myisamchk}:
@@ -35637,7 +37978,7 @@ If you get the following warning from @code{CHECK TABLE} or @code{myisamchk}:
this means that this counter has come out of sync. This doesn't mean
that the table is corrupted, but means that you should at least do a
-check on the table to verify that it's ok.
+check on the table to verify that it's okay.
The counter works as follows:
@@ -35652,7 +37993,7 @@ When the last instance of a table is closed (because of a @code{FLUSH} or
because there isn't room in the table cache) the counter is
decremented if the table has been updated at any point.
@item
-When you repair the table or check the table and it was ok,
+When you repair the table or check the table and it was okay,
the counter is reset to 0.
@item
To avoid problems with interaction with other processes that may do a
@@ -35666,9 +38007,9 @@ In other words, the only ways this can go out of sync are:
The @code{MyISAM} tables are copied without a @code{LOCK} and
@code{FLUSH TABLES}.
@item
-MySQL has crashed between an update and the final close
-(Note that the table may still be ok, as MySQL always issues writes
-for everything between each statement).
+MySQL has crashed between an update and the final close.
+(Note that the table may still be okay, as MySQL always issues writes
+for everything between each statement.)
@item
Someone has done a @code{myisamchk --repair} or @code{myisamchk
--update-state}on a table that was in use by @code{mysqld}.
@@ -35677,13 +38018,13 @@ Many @code{mysqld} servers are using the table and one has done a
@code{REPAIR} or @code{CHECK} of the table while it was in use by
another server. In this setup the @code{CHECK} is safe to do (even if
you will get the warning from other servers), but @code{REPAIR} should
-be avoided as it currently replaces the data file with a new one, which
+be avoided as it currently replaces the datafile with a new one, which
is not signaled to the other servers.
@end itemize
@node MERGE, ISAM, MyISAM, Table types
-@section MERGE Tables
+@section @code{MERGE} Tables
@cindex tables, merging
@cindex MERGE tables, defined
@@ -35691,29 +38032,29 @@ is not signaled to the other servers.
@code{MERGE} tables are new in MySQL Version 3.23.25. The code
is still in gamma, but should be resonable stable.
-A @code{MERGE} table is a collection of identical @code{MyISAM} tables
-that can be used as one. You can only @code{SELECT}, @code{DELETE}, and
-@code{UPDATE} from the collection of tables. If you @code{DROP} the
-@code{MERGE} table, you are only dropping the @code{MERGE}
-specification.
+A @code{MERGE} table (also known as a @code{MRG_MyISAM} table) is a
+collection of identical @code{MyISAM} tables that can be used as one.
+You can only @code{SELECT}, @code{DELETE}, and @code{UPDATE} from the
+collection of tables. If you @code{DROP} the @code{MERGE} table, you
+are only dropping the @code{MERGE} specification.
Note that @code{DELETE FROM merge_table} used without a @code{WHERE}
will only clear the mapping for the table, not delete everything in the
-mapped tables. (We plan to fix this in 4.0).
+mapped tables. (We plan to fix this in 4.1).
With identical tables we mean that all tables are created with identical
-column and key information. You can't put a MERGE over tables where the
-columns are packed differently, doesn't have exactly the same columns or
-have the keys in different order. Some of the tables can however be
-compressed with @code{myisampack}. @xref{myisampack}.
-
-When you create a @code{MERGE} table, you will get a @code{.frm} table
-definition file and a @code{.MRG} table list file. The @code{.MRG} just
-contains a list of the index files (@code{.MYI} files) that should
+column and key information. You can't merge tables in which the
+columns are packed differently, doesn't have exactly the same columns,
+or have the keys in different order. However, some of the tables can be
+compressed with @code{myisampack}. @xref{myisampack, , @code{myisampack}}.
+
+When you create a @code{MERGE} table, you will get a @file{.frm} table
+definition file and a @file{.MRG} table list file. The @file{.MRG} just
+contains a list of the index files (@file{.MYI} files) that should
be used as one. All used tables must be in the same database as the
@code{MERGE} table itself.
-For the moment you need to have @code{SELECT}, @code{UPDATE}, and
+For the moment, you need to have @code{SELECT}, @code{UPDATE}, and
@code{DELETE} privileges on the tables you map to a @code{MERGE} table.
@code{MERGE} tables can help you solve the following problems:
@@ -35732,11 +38073,11 @@ kind of benefits.)
@item
Do more efficient searches. If you know exactly what you are looking
after, you can search in just one of the split tables for some queries
-and use @strong{MERGE} table for others. You can even have many
+and use @code{MERGE} table for others. You can even have many
different @code{MERGE} tables active, with possible overlapping files.
@item
More efficient repairs. It's easier to repair the individual files that
-are mapped to a @code{MERGE} file than trying to repair a real big file.
+are mapped to a @code{MERGE} file than trying to repair a really big file.
@item
Instant mapping of many files as one. A @code{MERGE} table uses the
index of the individual tables. It doesn't need to maintain an index of
@@ -35748,25 +38089,27 @@ If you have a set of tables that you join to a big table on demand or
batch, you should instead create a @code{MERGE} table on them on demand.
This is much faster and will save a lot of disk space.
@item
-Go around the file size limit for the operating system.
+Go around the file-size limit for the operating system.
@item
-You can create an alias/synonym for a table by just using MERGE over one
-table. There shouldn't be any really notable performance impacts of doing this
-(only a couple of indirect calls and memcpy's for each read).
+You can create an alias/synonym for a table by just using @code{MERGE}
+over one table. There shouldn't be any really notable performance
+impacts of doing this (only a couple of indirect calls and @code{memcpy()}
+calls for each read).
@end itemize
The disadvantages with @code{MERGE} tables are:
@itemize @bullet
@item
-You can't use @code{INSERT} on @code{MERGE} tables, as MySQL
-can't know in which of the tables we should insert the row.
-@item
You can only use identical @code{MyISAM} tables for a @code{MERGE} table.
+@c @item
+@c @code{AUTO_INCREMENT} columns are not automatically updated on @code{INSERT}.
+@item
+@code{REPLACE} doesn't work.
@item
@code{MERGE} tables uses more file descriptors. If you are using a
-@strong{MERGE} that maps over 10 tables and 10 users are using this, you
-are using 10*10 + 10 file descriptors. (10 data files for 10 users
+@code{MERGE} that maps over 10 tables and 10 users are using this, you
+are using 10*10 + 10 file descriptors. (10 datafiles for 10 users
and 10 shared index files.)
@item
Key reads are slower. When you do a read on a key, the @code{MERGE}
@@ -35785,6 +38128,14 @@ mapped by a @code{MERGE} table that is 'open'. If you do this, the
get unexpected results.
@end itemize
+When you create a @code{MERGE} table you have to specify with
+@code{UNION(list-of-tables)} which tables you want to use as
+one. Optionally you can specify with @code{INSERT_METHOD} if you want
+insert for the @code{MERGE} table to happen in the first or last table
+in the @code{UNION} list. If you don't specify @code{INSERT_METHOD} or
+specify @code{NO}, then all @code{INSERT} commands on the @code{MERGE}
+table will return an error.
+
The following example shows you how to use @code{MERGE} tables:
@example
@@ -35792,14 +38143,15 @@ CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20));
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20));
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2");
-CREATE TABLE total (a INT NOT NULL, message CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2);
+CREATE TABLE total (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20))
+ TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
@end example
-Note that we didn't create a @code{UNIQUE} or @code{PRIMARY KEY} in the
-@code{total} table as the key isn't going to be unique in the @code{total}
-table.
+@c Note that we didn't create a @code{UNIQUE} or @code{PRIMARY KEY} in the
+@c @code{total} table as the key isn't going to be unique in the @code{total}
+@c table.
-Note that you can also manipulate the @code{.MRG} file directly from
+Note that you can also manipulate the @file{.MRG} file directly from
the outside of the MySQL server:
@example
@@ -35811,7 +38163,7 @@ shell> mysqladmin flush-tables
Now you can do things like:
@example
-mysql> select * from total;
+mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
@@ -35824,6 +38176,10 @@ mysql> select * from total;
+---+---------+
@end example
+Note that the @code{a} column, though declared as @code{PRIMARY KEY},
+is not really unique, as @code{MERGE} table cannot enforce uniqueness
+over a set of underlying @code{MyISAM} tables.
+
To remap a @code{MERGE} table you can do one of the following:
@itemize @bullet
@@ -35832,22 +38188,70 @@ To remap a @code{MERGE} table you can do one of the following:
@item
Use @code{ALTER TABLE table_name UNION(...)}
@item
-Change the @code{.MRG} file and issue a @code{FLUSH TABLE} on the
+Change the @file{.MRG} file and issue a @code{FLUSH TABLE} on the
@code{MERGE} table and all underlying tables to force the handler to
read the new definition file.
@end itemize
+@menu
+* MERGE table problems:: MERGE Table Problems
+@end menu
+
+@node MERGE table problems, , MERGE, MERGE
+@subsection @code{MERGE} Table Problems
+
+The following are the known problems with @code{MERGE} tables:
+
+@itemize @bullet
+@item
+A @code{MERGE} table cannot maintain @code{UNIQUE} constraints over the
+whole table. When you do @code{INSERT}, the data goes into the first or
+last table (according to @code{INSERT_METHOD=xxx}) and this @code{MyISAM}
+table ensures that the data are unique, but it knows nothing about
+others @code{MyISAM} tables.
+@item
+@code{DELETE FROM merge_table} used without a @code{WHERE}
+will only clear the mapping for the table, not delete everything in the
+mapped tables.
+@item
+@code{RENAME TABLE} on a table used in an active @code{MERGE} table may
+corrupt the table. This will be fixed in MySQL 4.0.x.
+@item
+Creation of a table of type @code{MERGE} doesn't check if the underlying
+tables are of compatible types. If you use @code{MERGE} tables in this
+fashion, you are very likely to run into strange problems.
+@item
+If you use @code{ALTER TABLE} to first add an @code{UNIQUE} index to a
+table used in a @code{MERGE} table and then use @code{ALTER TABLE} to
+add a normal index on the @code{MERGE} table, the key order will be
+different for the tables if there was an old non-unique key in the
+table. This is because @code{ALTER TABLE} puts @code{UNIQUE} keys before
+normal keys to be able to detect duplicate keys as early as possible.
+@item
+The range optimiser can't yet use @code{MERGE} table efficiently and may
+sometimes produce non-optimal joins. This will be fixed in MySQL 4.0.x.
+@item
+@code{DROP TABLE} on a table that is in use by a @code{MERGE} table will
+not work on Windows because the @code{MERGE} handler does the table mapping
+hidden from the upper layer of MySQL. Because Windows doesn't allow you
+to drop files that are open, you first must flush all @code{MERGE}
+tables (with @code{FLUSH TABLES}) or drop the @code{MERGE} table before
+dropping the table. We will fix this at the same time we introduce
+@code{VIEW}s.
+@end itemize
+
@node ISAM, HEAP, MERGE, Table types
-@section ISAM Tables
+@section @code{ISAM} Tables
@cindex tables, ISAM
-You can also use the deprecated ISAM table type. This will disappear
-rather soon because @code{MyISAM} is a better implementation of the same
-thing. ISAM uses a @code{B-tree} index. The index is stored in a file
-with the @code{.ISM} extension, and the data is stored in a file with the
-@code{.ISD} extension. You can check/repair ISAM tables with the
-@code{isamchk} utility. @xref{Crash recovery}.
+You can also use the deprecated @code{ISAM} table type. This will disappear
+rather soon (probably in MySQL 4.1) because @code{MyISAM} is a better
+implementation of the same thing. @code{ISAM} uses a @code{B-tree} index. The
+index is stored in a file with the @file{.ISM} extension, and the data
+is stored in a file with the @file{.ISD} extension. You can
+check/repair @code{ISAM} tables with the @code{isamchk} utility. @xref{Crash
+recovery}.
@code{ISAM} has the following features/properties:
@@ -35864,7 +38268,7 @@ tables. @xref{MyISAM}. The major differences compared to @code{MyISAM}
tables are:
@itemize @bullet
-@item ISAM tables are not binary portable across OS/Platforms.
+@item @code{ISAM} tables are not binary portable across OS/Platforms.
@item Can't handle tables > 4G.
@item Only support prefix compression on strings.
@item Smaller key limits.
@@ -35880,9 +38284,10 @@ TABLE} statement:
mysql> ALTER TABLE tbl_name TYPE = MYISAM;
@end example
+The embedded MySQL versions doesn't support @code{ISAM} tables.
-@node HEAP, BDB, ISAM, Table types
-@section HEAP Tables
+@node HEAP, InnoDB, ISAM, Table types
+@section @code{HEAP} Tables
@cindex tables, @code{HEAP}
@@ -35890,14 +38295,14 @@ mysql> ALTER TABLE tbl_name TYPE = MYISAM;
makes them very fast, but if MySQL crashes you will lose all
data stored in them. @code{HEAP} is very useful for temporary tables!
-The MySQL internal HEAP tables use 100% dynamic hashing
+The MySQL internal @code{HEAP} tables use 100% dynamic hashing
without overflow areas. There is no extra space needed for free lists.
@code{HEAP} tables also don't have problems with delete + inserts, which
normally is common with hashed tables:
@example
-mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) as down
- FROM log_table GROUP BY ip;
+mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) AS down
+ -> FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;
@end example
@@ -35943,7 +38348,7 @@ To free memory, you should execute @code{DELETE FROM heap_table},
@code{TRUNCATE heap_table} or @code{DROP TABLE heap_table}.
@item
MySQL cannot find out approximately how many rows there
-are between two values (this is used by the range optimizer to decide which
+are between two values (this is used by the range optimiser to decide which
index to use). This may affect some queries if you change a @code{MyISAM}
table to a @code{HEAP} table.
@item
@@ -35961,336 +38366,93 @@ SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2)
@code{sizeof(char*)} is 4 on 32-bit machines and 8 on 64-bit machines.
-@node BDB, InnoDB, HEAP, Table types
-@section BDB or Berkeley_DB Tables
-
-@cindex tables, @code{BDB}
-@cindex tables, @code{Berkeley DB}
+@node InnoDB, BDB, HEAP, Table types
+@section @code{InnoDB} Tables
@menu
-* BDB overview:: Overview of BDB Tables
-* BDB install:: Installing BDB
-* BDB start:: BDB startup options
-* BDB characteristic:: Some characteristic of @code{BDB} tables:
-* BDB TODO:: Some things we need to fix for BDB in the near future:
-* BDB portability:: Operating systems supported by @strong{BDB}
-* BDB errors:: Errors You May Get When Using BDB Tables
+* InnoDB overview:: InnoDB Tables Overview
+* InnoDB start:: InnoDB Startup Options
+* InnoDB init:: Creating InnoDB Tablespace
+* Using InnoDB tables:: Creating InnoDB Tables
+* Adding and removing:: Adding and Removing InnoDB Data and Log Files
+* Backing up:: Backing up and Recovering an InnoDB Database
+* Moving:: Moving an InnoDB Database to Another Machine
+* InnoDB transaction model:: InnoDB Transaction Model.
+* Implementation:: Implementation of Multi-versioning
+* Table and index:: Table and Index Structures
+* File space management:: File Space Management and Disk I/O
+* Error handling:: Error Handling
+* InnoDB restrictions:: Restrictions on InnoDB Tables
+* InnoDB contact information:: InnoDB Contact Information.
@end menu
-@node BDB overview, BDB install, BDB, BDB
-@subsection Overview of BDB Tables
-
-Support for BDB tables is included in the MySQL source distribution
-starting from Version 3.23.34 and is activated in the MySQL-Max
-binary.
-
-BerkeleyDB, available at @uref{http://www.sleepycat.com/} has provided
-MySQL with a transactional table handler. By using BerkeleyDB
-tables, your tables may have a greater chance of surviving crashes, and also
-provides @code{COMMIT} and @code{ROLLBACK} on transactions. The
-MySQL source distribution comes with a BDB distribution that has a
-couple of small patches to make it work more smoothly with MySQL.
-You can't use a non-patched @code{BDB} version with MySQL.
-
-We at MySQL AB are working in close cooperation with Sleepycat to
-keep the quality of the MySQL/BDB interface high.
-
-When it comes to supporting BDB tables, we are committed to help our
-users to locate the problem and help creating a reproducable test case
-for any problems involving BDB tables. Any such test case will be
-forwarded to Sleepycat who in turn will help us find and fix the
-problem. As this is a two stage operation, any problems with BDB tables
-may take a little longer for us to fix than for other table handlers.
-However, as the BerkeleyDB code itself has been used by many other
-applications than MySQL, we don't envision any big problems with
-this. @xref{Table handler support}.
-
-
-@node BDB install, BDB start, BDB overview, BDB
-@subsection Installing BDB
-
-If you have downloaded a binary version of MySQL that includes
-support for BerkeleyDB, simply follow the instructions for installing a
-binary version of MySQL.
-@xref{Installing binary}. @xref{mysqld-max, , @code{mysqld-max}}.
-
-To compile MySQL with Berkeley DB support, download MySQL
-Version 3.23.34 or newer and configure @code{MySQL} with the
-@code{--with-berkeley-db} option. @xref{Installing source}.
-
-@example
-cd /path/to/source/of/mysql-3.23.34
-./configure --with-berkeley-db
-@end example
-
-Please refer to the manual provided with the @code{BDB} distribution for
-more updated information.
-
-Even though Berkeley DB is in itself very tested and reliable,
-the MySQL interface is still considered beta quality.
-We are actively improving and optimizing it to get it stable very
-soon.
-
-
-@node BDB start, BDB characteristic, BDB install, BDB
-@subsection BDB startup options
-
-If you are running with @code{AUTOCOMMIT=0} then your changes in @code{BDB}
-tables will not be updated until you execute @code{COMMIT}. Instead of commit
-you can execute @code{ROLLBACK} to forget your changes. @xref{COMMIT}.
-
-If you are running with @code{AUTOCOMMIT=1} (the default), your changes
-will be committed immediately. You can start an extended transaction with
-the @code{BEGIN WORK} SQL command, after which your changes will not be
-committed until you execute @code{COMMIT} (or decide to @code{ROLLBACK}
-the changes).
-
-The following options to @code{mysqld} can be used to change the behavior of
-BDB tables:
-
-@multitable @columnfractions .30 .70
-@item @strong{Option} @tab @strong{Meaning}
-@item @code{--bdb-home=directory} @tab Base directory for BDB tables. This should be the same directory you use for --datadir.
-@item @code{--bdb-lock-detect=#} @tab Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM, or YOUNGEST).
-@item @code{--bdb-logdir=directory} @tab Berkeley DB log file directory.
-@item @code{--bdb-no-sync} @tab Don't synchronously flush logs.
-@item @code{--bdb-no-recover} @tab Don't start Berkeley DB in recover mode.
-@item @code{--bdb-shared-data} @tab Start Berkeley DB in multi-process mode (Don't use @code{DB_PRIVATE} when initializing Berkeley DB)
-@item @code{--bdb-tmpdir=directory} @tab Berkeley DB tempfile name.
-@item @code{--skip-bdb} @tab Don't use berkeley db.
-@item @code{-O bdb_max_lock=1000} @tab Set the maximum number of locks possible. @xref{SHOW VARIABLES}.
-@end multitable
-
-If you use @code{--skip-bdb}, MySQL will not initialize the
-Berkeley DB library and this will save a lot of memory. Of course,
-you cannot use @code{BDB} tables if you are using this option.
-
-Normally you should start @code{mysqld} without @code{--bdb-no-recover} if you
-intend to use BDB tables. This may, however, give you problems when you
-try to start @code{mysqld} if the BDB log files are corrupted. @xref{Starting
-server}.
-
-With @code{bdb_max_lock} you can specify the maximum number of locks
-(10000 by default) you can have active on a BDB table. You should
-increase this if you get errors of type @code{bdb: Lock table is out of
-available locks} or @code{Got error 12 from ...} when you have do long
-transactions or when @code{mysqld} has to examine a lot of rows to
-calculate the query.
-
-You may also want to change @code{binlog_cache_size} and
-@code{max_binlog_cache_size} if you are using big multi-line transactions.
-@xref{COMMIT}.
-
-
-@node BDB characteristic, BDB TODO, BDB start, BDB
-@subsection Some characteristic of @code{BDB} tables:
-
-@itemize @bullet
-@item
-To be able to rollback transactions BDB maintain log files. For maximum
-performance you should place these on another disk than your databases
-by using the @code{--bdb_log_dir} options.
-@item
-MySQL performs a checkpoint each time a new BDB log
-file is started, and removes any log files that are not needed for
-current transactions. One can also run @code{FLUSH LOGS} at any time
-to checkpoint the Berkeley DB tables.
-
-For disaster recovery, one should use table backups plus
-MySQL's binary log. @xref{Backup}.
-
-@strong{Warning}: If you delete old log files that are in use, BDB will
-not be able to do recovery at all and you may lose data if something
-goes wrong.
-@item
-MySQL requires a @code{PRIMARY KEY} in each BDB table to be
-able to refer to previously read rows. If you don't create one,
-MySQL will create an maintain a hidden @code{PRIMARY KEY} for
-you. The hidden key has a length of 5 bytes and is incremented for each
-insert attempt.
-@item
-If all columns you access in a @code{BDB} table are part of the same index or
-part of the primary key, then MySQL can execute the query
-without having to access the actual row. In a @code{MyISAM} table the
-above holds only if the columns are part of the same index.
-@item
-The @code{PRIMARY KEY} will be faster than any other key, as the
-@code{PRIMARY KEY} is stored together with the row data. As the other keys are
-stored as the key data + the @code{PRIMARY KEY}, it's important to keep the
-@code{PRIMARY KEY} as short as possible to save disk and get better speed.
-@item
-@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If
-you don't use @code{LOCK TABLE}, MYSQL will issue an internal
-multiple-write lock on the table to ensure that the table will be
-properly locked if another thread issues a table lock.
-@item
-Internal locking in @code{BDB} tables is done on page level.
-@item
-@code{SELECT COUNT(*) FROM table_name} is slow as @code{BDB} tables doesn't
-maintain a count of the number of rows in the table.
-@item
-Scanning is slower than with @code{MyISAM} tables as one has data in BDB
-tables stored in B-trees and not in a separate data file.
-@item
-The application must always be prepared to handle cases where
-any change of a @code{BDB} table may make an automatic rollback and any
-read may fail with a deadlock error.
-@item
-Keys are not compressed to previous keys as with ISAM or MyISAM
-tables. In other words, the key information will take a little more
-space in @code{BDB} tables compared to MyISAM tables which don't use
-@code{PACK_KEYS=0}.
-@item
-There is often holes in the BDB table to allow you to insert new rows in
-the middle of the key tree. This makes BDB tables somewhat larger than
-MyISAM tables.
-@item
-The optimizer needs to know an approximation of the number of rows in
-the table. MySQL solves this by counting inserts and
-maintaining this in a separate segment in each BDB table. If you don't
-do a lot of @code{DELETE} or @code{ROLLBACK}:s this number should be
-accurate enough for the MySQL optimizer, but as MySQL
-only store the number on close, it may be wrong if MySQL dies
-unexpectedly. It should not be fatal even if this number is not 100 %
-correct. One can update the number of rows by executing @code{ANALYZE
-TABLE} or @code{OPTIMIZE TABLE}. @xref{ANALYZE TABLE} . @xref{OPTIMIZE
-TABLE}.
-@item
-If you get full disk with a @code{BDB} table, you will get an error
-(probably error 28) and the transaction should roll back. This is in
-contrast with @code{MyISAM} and @code{ISAM} tables where @code{mysqld} will
-wait for enough free disk before continuing.
-@end itemize
-
-
-@node BDB TODO, BDB portability, BDB characteristic, BDB
-@subsection Some things we need to fix for BDB in the near future:
-
-@itemize @bullet
-@item
-It's very slow to open many BDB tables at the same time. If you are
-going to use BDB tables, you should not have a very big table cache (>
-256 ?) and you should use @code{--no-auto-rehash} with the @code{mysql}
-client. We plan to partly fix this in 4.0.
-@item
-@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB
-tables.
-@item
-Optimize performance.
-@item
-Change to not use page locks at all when we are scanning tables.
-@end itemize
-
-
-@node BDB portability, BDB errors, BDB TODO, BDB
-@subsection Operating systems supported by @strong{BDB}
-If you after having built MySQL with support for BDB tables get
-the following error in the log file when you start @code{mysqld}:
-
-@example
-bdb: architecture lacks fast mutexes: applications cannot be threaded
-Can't init dtabases
-@end example
-
-This means that @code{BDB} tables are not supported for your architecture.
-In this case you have to rebuild MySQL without BDB table support.
-
-NOTE: The following list is not complete; We will update this as we get
-more information about this.
-
-Currently we know that BDB tables works with the following operating
-system.
-
-@itemize @bullet
-@item
-Linux 2.x intel
-@item
-Solaris sparc
-@item
-SCO OpenServer
-@item
-SCO UnixWare 7.0.1
-@end itemize
-
-It doesn't work with the following operating systems:
-
-@itemize @bullet
-@item
-Linux 2.x Alpha
-@item
-Max OS X
-@end itemize
-
-
-@node BDB errors, , BDB portability, BDB
-@subsection Errors You May Get When Using BDB Tables
-
-@itemize @bullet
-@item
-If you get the following error in the @code{hostname.err log} when
-starting @code{mysqld}:
-
-@example
-bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version #
-@end example
-it means that the new @code{BDB} version doesn't support the old log
-file format. In this case you have to delete all @code{BDB} log BDB
-from your database directory (the files that has the format
-@code{log.XXXXXXXXXX} ) and restart @code{mysqld}. We would also
-recommend you to do a @code{mysqldump --opt} of your old @code{BDB}
-tables, delete the old table and restore the dump.
-@item
-If you are running in not @code{auto_commit} mode and delete a table you
-are using by another thread you may get the following error messages in
-the MySQL error file:
-
-@example
-001119 23:43:56 bdb: Missing log fileid entry
-001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: Invalid
-@end example
-
-This is not fatal but we don't recommend that you delete tables if you are
-not in @code{auto_commit} mode, until this problem is fixed (the fix is
-not trivial).
-@end itemize
+@node InnoDB overview, InnoDB start, InnoDB, InnoDB
+@subsection InnoDB Tables Overview
+@cindex transactions, support
+@cindex transaction-safe tables
+@cindex ACID
+
+InnoDB provides MySQL with a transaction-safe (@code{ACID} compliant)
+table handler with commit, rollback, and crash recovery capabilities.
+InnoDB does locking on row level and also provides an Oracle-style
+consistent
+non-locking read in @code{SELECT}s. These features increase
+multiuser concurrency and performance. There is no need for
+lock escalation in InnoDB,
+because row level locks in InnoDB fit in very small space.
+InnoDB tables support @code{FOREIGN KEY} constraints
+as the first table type in MySQL.
-@node InnoDB, , BDB, Table types
-@section InnoDB Tables
+InnoDB has been designed for maximum performance
+when processing
+large data volumes. Its CPU efficiency is probably not
+matched by any other disk-based relational database engine.
-@menu
-* InnoDB overview:: InnoDB tables overview
-* InnoDB start:: InnoDB startup options
-* InnoDB init:: Creating InnoDB table space.
-* Using InnoDB tables:: Creating InnoDB tables
-* Adding and removing:: Adding and removing InnoDB data and log files
-* Backing up:: Backing up and recovering an InnoDB database
-* Moving:: Moving an InnoDB database to another machine
-* InnoDB transaction model:: InnoDB transaction model.
-* Implementation:: Implementation of multiversioning
-* Table and index:: Table and index structures
-* File space management:: File space management and disk i/o
-* Error handling:: Error handling
-* InnoDB restrictions:: Some restrictions on InnoDB tables
-* InnoDB contact information:: InnoDB contact information.
-@end menu
+Technically, InnoDB is a complete database backend placed under MySQL.
+InnoDB has its own buffer pool for caching data and indexes in main
+memory. InnoDB stores its tables and indexes in a tablespace, which
+may consist of several files. This is different from, for example,
+MyISAM tables where each table is stored as a separate file.
+InnoDB tables can be of any size also on those operating
+systems where file-size is limited to 2 GB.
+You can find the latest information about InnoDB at
+@uref{http://www.innodb.com/}. The most up-to-date version of the
+InnoDB manual is always placed there, and you can also order
+commercial licenses and support for InnoDB.
-@node InnoDB overview, InnoDB start, InnoDB, InnoDB
-@subsection InnoDB tables overview
+InnoDB is currently (October 2001) used in production at
+several large database sites requiring high performance.
+The famous Internet news site Slashdot.org runs on
+InnoDB. Mytrix, Inc. stores over 1 TB of data in
+InnoDB, and another site handles an average
+load of 800 inserts/updates per second in InnoDB.
InnoDB tables are included in the MySQL source distribution
-starting from 3.23.34a and are activated in the @strong{MySQL -max}
-binary.
+starting from 3.23.34a and are activated in the MySQL -Max
+binary. For Windows the -Max binaries are contained in the
+standard distribution.
If you have downloaded a binary version of MySQL that includes
-support for InnoDB (mysqld-max), simply follow the instructions for
-installing a binary version of MySQL. @xref{Installing binary}.
+support for InnoDB, simply follow the instructions of the
+MySQL manual
+for installing a binary version of MySQL. If you already have
+MySQL-3.23 installed, then the simplest way to install
+MySQL -Max is to replace the server executable @file{mysqld}
+with the corresponding executable in the -Max distribution.
+MySQL and MySQL -Max differ only in the server executable.
+@xref{Installing binary}.
@xref{mysqld-max, , @code{mysqld-max}}.
-To compile MySQL with InnoDB support, download MySQL-3.23.37 or newer
-and configure MySQL with the @code{--with-innodb} option.
+To compile MySQL with InnoDB support,
+download MySQL-3.23.34a or newer version from
+@uref{http://www.mysql.com/}
+and configure MySQL with the
+@code{--with-innodb} option. See the
+MySQL manual
+about installing a MySQL source distribution.
@xref{Installing source}.
@example
@@ -36298,181 +38460,344 @@ cd /path/to/source/of/mysql-3.23.37
./configure --with-innodb
@end example
-To get InnoDB to work you have to specify where the data for InnoDB
-tables should be stored by specifying the @code{innodb_data_file_path}
-option on the command line or in an MySQL option file. @xref{InnoDB
-start}. If you have configured MySQL for InnoDB but you have not
-specified the above option, @code{mysqld} will print at start:
+To use InnoDB you have to specify InnoDB startup options in
+your @file{my.cnf} or @file{my.ini} file. The minimal way
+to modify it is to add to the @code{[mysqld]} section the line
@example
-Can't initialize InnoDB as 'innodb_data_file_path' is not set
+innodb_data_file_path=ibdata:30M
@end example
-InnoDB provides MySQL with a transaction-safe table handler with
-commit, rollback, and crash recovery capabilities. InnoDB does
-locking on row level, and also provides an Oracle-style consistent
-non-locking read in @code{SELECTS}, which increases transaction
-concurrency. There is not need for lock escalation in InnoDB,
-because row level locks in InnoDB fit in very small space.
-
-InnoDB has been designed for maximum performance when processing
-large data volumes. Its CPU efficiency is probably not
-matched by any other disk-based relational database engine.
-
-You can find the latest information about InnoDB at
-@uref{http://www.innodb.com}. The most up-to-date version of the
-InnoDB manual is always placed there, and you can also order commercial
-support for InnoDB.
-
-Technically, InnoDB is a database backend placed under MySQL. InnoDB
-has its own buffer pool for caching data and indexes in main
-memory. InnoDB stores its tables and indexes in a tablespace, which
-may consist of several files. This is different from, for example,
-@code{MyISAM} tables where each table is stored as a separate file.
+but to get good performance it is best that you specify options
+as recommended. @xref{InnoDB start}.
InnoDB is distributed under the GNU GPL License Version 2 (of June 1991).
In the source distribution of MySQL, InnoDB appears as a subdirectory.
@node InnoDB start, InnoDB init, InnoDB overview, InnoDB
-@subsection InnoDB startup options
-
-Beginning from MySQL-3.23.37 the prefix of the options is changed
-from @code{innobase_...} to @code{innodb_...}.
-
-To use InnoDB tables you @strong{MUST} specify configuration parameters
-in the MySQL configuration file in the @code{[mysqld]} section of
-the configuration file @file{my.cnf}. @xref{Option files}.
-
-The only required parameter to use InnoDB is @code{innodb_data_file_path},
-but you should set others if you want to get a better performance.
-
-Suppose you have a Windows NT machine with 128 MB RAM and a single 10 GB
-hard disk. Below is an example of possible configuration parameters in
-@file{my.cnf} for InnoDB:
+@subsection InnoDB Startup Options
+
+
+To use InnoDB tables in MySQL-Max-3.23 you MUST specify configuration
+parameters
+in the @code{[mysqld]} section of
+the configuration file @file{my.cnf}, or on Windows optionally in
+@file{my.ini}.
+
+At the minimum, in 3.23 you must specify @code{innodb_data_file_path}
+where you specify the names and the sizes of datafiles. If you do
+not mention @code{innodb_data_home_dir} in @file{my.cnf} the default
+is to create these files to the @code{datadir} of MySQL.
+If you specify @code{innodb_data_home_dir} as an empty string,
+then you can give absolute paths to your data files in
+@code{innodb_data_file_path}.
+In MySQL-4.0 you do not need to specify even
+@code{innodb_data_file_path}: the default for it is to create
+an auto-extending 10 MB file @file{ibdata1} to the @code{datadir}
+of MySQL. (In MySQL-4.0.0 and 4.0.1 the datafile is 64 MB and not
+auto-extending.)
+
+But to get good performance you MUST explicitly set the InnoDB parameters
+listed in the following examples.
+
+Starting from versions 3.23.50 and 4.0.2 InnoDB allows the last
+datafile on the @code{innodb_data_file_path} line
+to be specified as @strong{auto-extending}. The syntax for
+@code{innodb_data_file_path} is then the following:
+@example
+pathtodatafile:sizespecification;pathtodatafile:sizespecification;...
+... ;pathtodatafile:sizespecification[:autoextend[:max:sizespecification]]
+@end example
+If you specify the last datafile with the autoextend option, InnoDB
+will extend the last datafile if it runs out of free space in the
+tablespace. The increment is 8 MB at a time. An example:
+@example
+innodb_data_home_dir =
+innodb_data_file_path = /ibdata/ibdata1:100M:autoextend
+@end example
+instructs InnoDB to create just a single datafile whose initial size is
+100 MB and which is extended in 8 MB blocks when space runs out.
+If the disk becomes full you may want to add another data
+file to another disk, for example. Then you have to look the size
+of @file{ibdata1}, round the size downward to
+the closest multiple of 1024 * 1024 bytes (= 1 MB), and specify
+the rounded size of @file{ibdata1} explicitly in
+@code{innodb_data_file_path}.
+After that you can add another datafile:
+@example
+innodb_data_home_dir =
+innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
+@end example
+Be cautious on filesystems where the maximum file-size is 2 GB!
+InnoDB is not aware of the OS maximum file-size. On those filesystems
+you might want to specify the max size for the datafile:
+@example
+innodb_data_home_dir =
+innodb_data_file_path = /ibdata/ibdata1:100M:autoextend:max:2000M
+@end example
+
+@strong{A simple @file{my.cnf} example.} Suppose you have a computer
+with 128 MB RAM and one hard disk. Below is an example of
+possible configuration parameters in @file{my.cnf} or
+@file{my.ini} for InnoDB. We assume you are running
+MySQL-Max-3.23.50 or later, or MySQL-4.0.2 or later.
+This example suits most users, both on Unix and Windows,
+who do not want to distribute InnoDB datafiles and
+log files on several disks. This creates an
+auto-extending data file @file{ibdata1} and two InnoDB log files
+@file{ib_logfile0} and @file{ib_logfile1} to the
+@code{datadir} of MySQL (typically @file{/mysql/data}).
+Also the small archived InnoDB log file
+@file{ib_arch_log_0000000000} ends up in the @code{datadir}.
@example
-innodb_data_file_path = ibdata1:2000M;ibdata2:2000M
-innodb_data_home_dir = c:\ibdata
-set-variable = innodb_mirrored_log_groups=1
-innodb_log_group_home_dir = c:\iblogs
-set-variable = innodb_log_files_in_group=3
-set-variable = innodb_log_file_size=30M
+[mysqld]
+# You can write your other MySQL server options here
+# ...
+# Data file(s) must be able to
+# hold your data and indexes.
+# Make sure you have enough
+# free disk space.
+innodb_data_file_path = ibdata1:10M:autoextend
+# Set buffer pool size to
+# 50 - 80 % of your computer's
+# memory
+set-variable = innodb_buffer_pool_size=70M
+set-variable = innodb_additional_mem_pool_size=10M
+# Set the log file size to about
+# 25 % of the buffer pool size
+set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
+# Set ..flush_log_at_trx_commit
+# to 0 if you can afford losing
+# some last transactions
innodb_flush_log_at_trx_commit=1
-innodb_log_arch_dir = c:\iblogs
-innodb_log_archive=0
-set-variable = innodb_buffer_pool_size=80M
-set-variable = innodb_additional_mem_pool_size=10M
-set-variable = innodb_file_io_threads=4
-set-variable = innodb_lock_wait_timeout=50
@end example
-Note that data files must be < 4G, and < 2G on
-some file systems! The total size of data files has
-to be >= 10 MB.
-InnoDB does not create directories:
-you have to create them yourself.
-
-Suppose you have a Linux machine with 512 MB RAM and
-three 20 GB hard disks (at directory paths @file{/},
-@file{/dr2} and @file{/dr3}).
-Below is an example of possible configuration parameters in @file{my.cnf} for
-InnoDB:
+@strong{Check that the MySQL server has the rights to create files} in
+@code{datadir}.
+
+Note that datafiles must be < 2G in some file systems!
+The combined size of the log files must be < 4G. The combined
+size of datafiles must be >= 10 MB.
+
+When you for the first time create an InnoDB database, it is
+best that you start the MySQL server from the command prompt.
+Then InnoDB will print the information about the database
+creation to the screen, and you see what is happening.
+See below next section what the printout should look like.
+For example, in Windows you can start @file{mysqld-max.exe} with:
+
+@example
+your-path-to-mysqld>mysqld-max --console
+@end example
+
+@strong{Where to put @file{my.cnf} or @file{my.ini} in Windows?}
+The rules for Windows are the following:
+@itemize bullet
+@item Only one of @file{my.cnf} or @file{my.ini} should be created.
+@item The @file{my.cnf} file should be placed in the root
+directory of the drive @file{C:}.
+@item The @file{my.ini} file should be placed in the WINDIR directory, e.g,
+@file{C:\WINDOWS} or @file{C:\WINNT}. You can use the @code{SET}
+command of MS-DOS to print the value of WINDIR.
+@item If your PC uses a boot loader where the @file{C:} drive
+is not the boot drive, then your only option is to use the @file{my.ini} file.
+@end itemize
+
+@strong{Where to specify options in Unix?}
+On Unix @file{mysqld} reads options from the following files, if they exist,
+in the following order:
+@itemize bullet
+@item @file{/etc/my.cnf} Global options.
+@item @file{COMPILATION_DATADIR/my.cnf} Server-specific options.
+@item @file{defaults-extra-file} The file specified with
+@code{--defaults-extra-file=...}.
+@item @file{~/.my.cnf} User-specific options.
+@end itemize
+@file{COMPILATION_DATADIR} is the MySQL data directory which was
+specified as a @code{./configure} option when @file{mysqld}
+was compiled
+(typically @file{/usr/local/mysql/data} for a binary installation or @file{/usr/local/var} for a source installation).
+
+If you are not sure from where @file{mysqld} reads its @file{my.cnf}
+or @file{my.ini}, you can give the path as the first command-line
+option to the server:
+@code{mysqld --defaults-file=your_path_to_my_cnf}.
+
+InnoDB forms the directory path to a datafile by textually catenating
+@code{innodb_data_home_dir} to a datafile name or path in
+@code{innodb_data_file_path}, adding a possible slash or
+backslash in between if needed. If the keyword
+@code{innodb_data_home_dir} is not mentioned in
+@file{my.cnf} at all, the default for it is the
+'dot' directory @file{./} which means the @code{datadir} of MySQL.
+
+@strong{An advanced @file{my.cnf} example.} Suppose you have a Linux computer
+with 2 GB RAM and three 60 GB hard disks
+(at directory paths @file{/}, @file{/dr2} and
+@file{/dr3}). Below is an example of possible
+configuration parameters in @file{my.cnf} for InnoDB.
+
+@strong{Note that InnoDB does not create directories: you
+have to create them yourself.} Use the Unix or MS-DOS
+@code{mkdir} command to create the data and log group home directories.
@example
-innodb_data_file_path = ibdata/ibdata1:2000M;dr2/ibdata/ibdata2:2000M
-innodb_data_home_dir = /
-set-variable = innodb_mirrored_log_groups=1
-innodb_log_group_home_dir = /dr3
+[mysqld]
+# You can write your other MySQL server options here
+# ...
+innodb_data_home_dir =
+# Data files must be able to
+# hold your data and indexes
+innodb_data_file_path = /ibdata/ibdata1:2000M;/dr2/ibdata/ibdata2:2000M:autoextend
+# Set buffer pool size to
+# 50 - 80 % of your computer's
+# memory, but make sure on Linux
+# x86 total memory usage is
+# < 2 GB
+set-variable = innodb_buffer_pool_size=1G
+set-variable = innodb_additional_mem_pool_size=20M
+innodb_log_group_home_dir = /dr3/iblogs
+# .._log_arch_dir must be the same
+# as .._log_group_home_dir
+innodb_log_arch_dir = /dr3/iblogs
set-variable = innodb_log_files_in_group=3
-set-variable = innodb_log_file_size=50M
+# Set the log file size to about
+# 15 % of the buffer pool size
+set-variable = innodb_log_file_size=150M
set-variable = innodb_log_buffer_size=8M
+# Set ..flush_log_at_trx_commit to
+# 0 if you can afford losing
+# some last transactions
innodb_flush_log_at_trx_commit=1
-innodb_log_arch_dir = /dr3/iblogs
-innodb_log_archive=0
-set-variable = innodb_buffer_pool_size=400M
-set-variable = innodb_additional_mem_pool_size=20M
-set-variable = innodb_file_io_threads=4
set-variable = innodb_lock_wait_timeout=50
+#innodb_flush_method=fdatasync
+#set-variable = innodb_thread_concurrency=5
@end example
-Note that we have placed the two data files on different disks.
-The reason for the name @code{innodb_data_file_path} is that
-you can also specify paths to your data files, and
-@code{innodb_data_home_dir} is just textually catenated
-before your data file paths, adding a possible slash or
-backslash in between. InnoDB will fill the tablespace
-formed by the data files from bottom up. In some cases it will
+Note that we have placed the two datafiles on different disks.
+InnoDB will fill the tablespace
+formed by the datafiles from bottom up. In some cases it will
improve the performance of the database if all data is not placed
on the same physical disk. Putting log files on a different disk from
data is very often beneficial for performance.
+You can also use @strong{raw disk partitions} (raw devices)
+as datafiles. In some Unixes
+they speed up I/O. See the manual section on InnoDB file space management
+about how to specify them in @file{my.cnf}.
+
+@strong{Warning}: on Linux x86 you must be careful you @strong{do not set memory usage
+too high}. glibc will allow the process heap to grow over thread stacks,
+which will crash your server. It is a risk if the value of
+@example
+innodb_buffer_pool_size + key_buffer +
+max_connections * (sort_buffer + read_buffer_size) + max_connections * 2 MB
+@end example
+is close to 2 GB or exceeds 2 GB. Each thread will use a stack
+(often 2 MB, but in MySQL AB binaries only 256 kB) and in the worst case also
+@code{sort_buffer + read_buffer_size}
+additional memory.
+
+@strong{How to tune other @file{mysqld} server parameters?}
+Typical values which suit most users are:
+@example
+skip-locking
+set-variable = max_connections=200
+set-variable = read_buffer_size=1M
+set-variable = sort_buffer=1M
+# Set key_buffer to 5 - 50%
+# of your RAM depending on how
+# much you use MyISAM tables, but
+# keep key_buffer + InnoDB
+# buffer pool size < 80% of
+# your RAM
+set-variable = key_buffer=...
+@end example
+
+Note that some parameters are given using the numeric @file{my.cnf}
+parameter format: @code{set-variable = innodb... = 123}, others
+(string and boolean parameters) with another format:
+@code{innodb_... = ... }.
+
The meanings of the configuration parameters are the following:
-@multitable @columnfractions .30 .70
-@item @code{innodb_data_home_dir} @tab
-The common part of the directory path for all InnoDB data files.
-@item @code{innodb_data_file_path} @tab
-Paths to individual data files and their sizes. The full directory path
-to each data file is acquired by concatenating innodb_data_home_dir to
-the paths specified here. The file sizes are specified in megabytes,
-hence the 'M' after the size specification above. Do not set a file size
-bigger than 4000M, and on most operating systems not bigger than 2000M.
+@multitable @columnfractions .35 .65
+@item @strong{Option} @tab @strong{Description}
+@item @code{innodb_data_home_dir} @tab
+The common part of the directory path for all InnoDB datafiles.
+If you do not mentioned this option in @file{my.cnf}
+the default is the @code{datadir} of MySQL.
+You can specify this also as an empty string, in which case you
+can use absolute file paths in @code{innodb_data_file_path}.
+@item @code{innodb_data_file_path} @tab
+Paths to individual datafiles and their sizes. The full directory path
+to each datafile is acquired by concatenating innodb_data_home_dir to
+the paths specified here. The file-sizes are specified in megabytes,
+hence the 'M' after the size specification above.
InnoDB also understands the abbreviation 'G', 1G meaning 1024M.
+Starting from
+3.23.44 you can set the file-size bigger than 4 GB on those
+operating systems which support big files.
+On some operating systems files must be < 2 GB.
The sum of the sizes of the files must be at least 10 MB.
-@item @code{innodb_mirrored_log_groups} @tab
+@item @code{innodb_mirrored_log_groups} @tab
Number of identical copies of log groups we
keep for the database. Currently this should be set to 1.
-@item @code{innodb_log_group_home_dir} @tab
+@item @code{innodb_log_group_home_dir} @tab
Directory path to InnoDB log files.
-@item @code{innodb_log_files_in_group} @tab
+@item @code{innodb_log_files_in_group} @tab
Number of log files in the log group. InnoDB writes to the files in a
circular fashion. Value 3 is recommended here.
-@item @code{innodb_log_file_size} @tab
+@item @code{innodb_log_file_size} @tab
Size of each log file in a log group in megabytes. Sensible values range
-from 1M to the size of the buffer pool specified below. The bigger the
-value, the less checkpoint flush activity is needed in the buffer pool,
-saving disk i/o. But bigger log files also mean that recovery will be
-slower in case of a crash. File size restriction as for a data file.
-@item @code{innodb_log_buffer_size} @tab
+from 1M to 1/nth of the size of the buffer pool specified below,
+where n is the number of log files in the group. The
+bigger the value,
+the less checkpoint flush activity is needed in the buffer pool,
+saving disk I/O. But bigger log files also mean that recovery will be
+slower in case of a crash. The combined size of log files must
+be < 4 GB on 32-bit computers.
+@item @code{innodb_log_buffer_size} @tab
The size of the buffer which InnoDB uses to write log to the log files
-on disk. Sensible values range from 1M to half the combined size of log
-files. A big log buffer allows large transactions to run without a need
+on disk. Sensible values range from 1M to 8M.
+A big log buffer allows large transactions to run without a need
to write the log to disk until the transaction commit. Thus, if you have
-big transactions, making the log buffer big will save disk i/o.
-@item @code{innodb_flush_log_at_trx_commit} @tab
+big transactions, making the log buffer big will save disk I/O.
+@item @code{innodb_flush_log_at_trx_commit} @tab
Normally this is set to 1, meaning that at a transaction commit the log
is flushed to disk, and the modifications made by the transaction become
permanent, and survive a database crash. If you are willing to
compromise this safety, and you are running small transactions, you may
-set this to 0 to reduce disk i/o to the logs.
-@item @code{innodb_log_arch_dir} @tab
+set this to 0 to reduce disk I/O to the logs.
+@item @code{innodb_log_arch_dir} @tab
The directory where fully written log files would be archived if we used
log archiving. The value of this parameter should currently be set the
same as @code{innodb_log_group_home_dir}.
-@item @code{innodb_log_archive} @tab
+@item @code{innodb_log_archive} @tab
This value should currently be set to 0. As recovery from a backup is
done by MySQL using its own log files, there is currently no need to
archive InnoDB log files.
-@item @code{innodb_buffer_pool_size} @tab
+@item @code{innodb_buffer_pool_size} @tab
The size of the memory buffer InnoDB uses to cache data and indexes of
-its tables. The bigger you set this the less disk i/o is needed to
+its tables. The bigger you set this the less disk I/O is needed to
access data in tables. On a dedicated database server you may set this
-parameter up to 90 % of the machine physical memory size. Do not set it
+parameter up to 80% of the machine physical memory size. Do not set it
too large, though, because competition of the physical memory may cause
paging in the operating system.
-@item @code{innodb_additional_mem_pool_size} @tab
+@item @code{innodb_additional_mem_pool_size} @tab
Size of a memory pool InnoDB uses to store data dictionary information
and other internal data structures. A sensible value for this might be
2M, but the more tables you have in your application the more you will
need to allocate here. If InnoDB runs out of memory in this pool, it
will start to allocate memory from the operating system, and write
warning messages to the MySQL error log.
-@item @code{innodb_file_io_threads} @tab
-Number of file i/o threads in InnoDB. Normally, this should be 4, but
-on Windows NT disk i/o may benefit from a larger number.
-@item @code{innodb_lock_wait_timeout} @tab
+@item @code{innodb_file_io_threads} @tab
+Number of file I/O threads in InnoDB. Normally, this should be 4, but
+on Windows disk I/O may benefit from a larger number.
+@item @code{innodb_lock_wait_timeout} @tab
Timeout in seconds an InnoDB transaction may wait for a lock before
being rolled back. InnoDB automatically detects transaction deadlocks
in its own lock table and rolls back the transaction. If you use
@@ -36485,39 +38810,41 @@ resolve the situation.
The default value for this is @code{fdatasync}.
Another option is @code{O_DSYNC}.
@end multitable
-
+
@node InnoDB init, Using InnoDB tables, InnoDB start, InnoDB
-@subsection Creating InnoDB table space
+@subsection Creating InnoDB Tablespace
Suppose you have installed MySQL and have edited @file{my.cnf} so that
it contains the necessary InnoDB configuration parameters.
Before starting MySQL you should check that the directories you have
-specified for InnoDB data files and log files exist and that you have
+specified for InnoDB datafiles and log files exist and that you have
access rights to those directories. InnoDB
cannot create directories, only files. Check also you have enough disk space
for the data and log files.
-When you now start MySQL, InnoDB will start creating your data files
+When you now start MySQL, InnoDB will start creating your datafiles
and log files. InnoDB will print something like the following:
@example
~/mysqlm/sql > mysqld
-InnoDB: The first specified data file /home/heikki/data/ibdata1 did not exist:
+InnoDB: The first specified datafile /home/heikki/data/ibdata1
+did not exist:
InnoDB: a new database to be created!
InnoDB: Setting file /home/heikki/data/ibdata1 size to 134217728
InnoDB: Database physically writes the file full: wait...
-InnoDB: Data file /home/heikki/data/ibdata2 did not exist: new to be created
+InnoDB: datafile /home/heikki/data/ibdata2 did not exist:
+new to be created
InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000
InnoDB: Database physically writes the file full: wait...
-InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist: new to be c
-reated
+InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist:
+new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile0 size to 5242880
-InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist: new to be c
-reated
+InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist:
+new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile1 size to 5242880
-InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist: new to be c
-reated
+InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist:
+new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile2 size to 5242880
InnoDB: Started
mysqld: ready for connections
@@ -36535,7 +38862,7 @@ InnoDB: Starting shutdown...
InnoDB: Shutdown completed
@end example
-You can now look at the data files and logs directories and you
+You can now look at the datafiles and logs directories and you
will see the files created. The log directory will also contain
a small file named @file{ib_arch_log_0000000000}. That file
resulted from the database creation, after which InnoDB switched off
@@ -36554,10 +38881,26 @@ mysqld: ready for connections
@node Error creating InnoDB, , InnoDB init, InnoDB init
-@subsubsection If something goes wrong in database creation
+@subsubsection If Something Goes Wrong in Database Creation
+
+If InnoDB prints an operating system error in a file operation,
+usually the problem is one of the following:
+
+@itemize @bullet
+@item You did not create InnoDB data or log directories.
+@item @file{mysqld} does not have the rights to create files in those
+directories.
+@item @file{mysqld} does not read the right @file{my.cnf} or @file{my.ini}
+file, and consequently does not see the options you specified.
+@item The disk is full or a disk quota is exceeded.
+@item You have created a subdirectory whose name is equal to a datafile
+you specified.
+@item There is a syntax error in @code{innodb_data_home_dir}
+or @code{innodb_data_file_path}.
+@end itemize
If something goes wrong in an InnoDB database creation, you should
-delete all files created by InnoDB. This means all data files, all log
+delete all files created by InnoDB. This means all datafiles, all log
files, the small archived log file, and in the case you already did
create some InnoDB tables, delete also the corresponding @file{.frm}
files for these tables from the MySQL database
@@ -36565,7 +38908,7 @@ directories. Then you can try the InnoDB database creation again.
@node Using InnoDB tables, Adding and removing, InnoDB init, InnoDB
-@subsection Creating InnoDB tables
+@subsection Creating InnoDB Tables
Suppose you have started the MySQL client with the command
@code{mysql test}.
@@ -36577,7 +38920,7 @@ CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) TYPE = InnoDB;
@end example
This SQL command will create a table and an index on column @code{A}
-into the InnoDB tablespace consisting of the data files you specified
+into the InnoDB tablespace consisting of the datafiles you specified
in @file{my.cnf}. In addition MySQL will create a file
@file{CUSTOMER.frm} to the MySQL database directory @file{test}.
Internally, InnoDB will add to its own data dictionary an entry
@@ -36596,20 +38939,12 @@ SHOW TABLE STATUS FROM test LIKE 'CUSTOMER'
@end example
Note that the statistics @code{SHOW} gives about InnoDB tables
-are only approximate: they are used in SQL optimization. Table and
+are only approximate: they are used in SQL optimisation. Table and
index reserved sizes in bytes are accurate, though.
-NOTE: @code{DROP DATABASE} does not currently work for InnoDB tables!
-You must drop the tables individually. Also take care not to delete or
-add @file{.frm} files to your InnoDB database manually: use
-@code{CREATE TABLE} and @code{DROP TABLE} commands.
-InnoDB has its own internal data dictionary, and you will get problems
-if the MySQL @file{.frm} files are out of 'sync' with the InnoDB
-internal data dictionary.
-
-@subsubsection Converting MyISAM tables to InnoDB
+@subsubsection Converting MyISAM Tables to InnoDB
-InnoDB does not have a special optimization for separate index creation.
+InnoDB does not have a special optimisation for separate index creation.
Therefore it does not pay to export and import the table and create indexes
afterwards.
The fastest way to alter a table to InnoDB is to do the inserts
@@ -36621,15 +38956,15 @@ To get better control over the insertion process, it may be good to insert
big tables in pieces:
@example
-INSERT INTO newtable SELECT * FROM oldtable WHERE yourkey > something
- AND yourkey <= somethingelse;
+INSERT INTO newtable SELECT * FROM oldtable
+ WHERE yourkey > something AND yourkey <= somethingelse;
@end example
After all data has been inserted you can rename the tables.
During the conversion of big tables you should set the InnoDB
-buffer pool size big
-to reduce disk i/o. Not bigger than 80 % of the physical memory, though.
+buffer pool size big
+to reduce disk I/O. Not bigger than 80% of the physical memory, though.
You should set InnoDB log files big, and also the log buffer large.
Make sure you do not run out of tablespace: InnoDB tables take a lot
@@ -36637,7 +38972,7 @@ more space than MyISAM tables. If an @code{ALTER TABLE} runs out
of space, it will start a rollback, and that can take hours if it is
disk-bound.
In inserts InnoDB uses the insert buffer to merge secondary index records
-to indexes in batches. That saves a lot of disk i/o. In rollback no such
+to indexes in batches. That saves a lot of disk I/O. In rollback no such
mechanism is used, and the rollback can take 30 times longer than the
insertion.
@@ -36645,20 +38980,137 @@ In the case of a runaway rollback, if you do not have valuable data in your
database,
it is better that you kill the database process and delete all InnoDB data
and log files and all InnoDB table @file{.frm} files, and start
-your job again, rather than wait for millions of disk i/os to complete.
-
+your job again, rather than wait for millions of disk I/Os to complete.
+
+@subsubsection Foreign Key Constraints
+
+Starting from version 3.23.43b InnoDB features foreign key constraints.
+InnoDB is the first MySQL table type which allows you to define foreign key
+constraints to guard the integrity of your data.
+
+The syntax of a foreign key constraint definition in InnoDB:
+@example
+FOREIGN KEY (index_col_name, ...)
+ REFERENCES table_name (index_col_name, ...)
+ [ON DELETE CASCADE | ON DELETE SET NULL]
+@end example
+Both tables have to be InnoDB type and @strong{there must be an index
+where the foreign key and the referenced key are listed as the first
+columns}. InnoDB does not auto-create indexes on foreign keys or
+referenced keys: you have to create them explicitly.
+
+Corresponding columns in the foreign key
+and the referenced key must have similar internal data types
+inside InnoDB so that they can be compared without a type
+conversion.
+The @strong{size and the signedness of integer types has to be the same}.
+The length of string types need not be the same.
+
+Starting from version 3.23.50 you can also associate the
+@code{ON DELETE CASCADE} or @code{ON DELETE SET NULL}
+clause with the foreign key constraint.
+
+If @code{ON DELETE CASCADE} is specified, and a row in the parent
+table is deleted, then InnoDB automatically deletes also all those rows
+in the child table whose foreign key values are equal to
+the referenced key value in the parent row. If @code{ON DELETE SET NULL}
+is specified, the child rows are automatically updated so that the
+columns in the foreign key are set to the SQL NULL value.
+
+Starting from version 3.23.50, InnoDB does not check foreign key
+constraints on those foreign key or referenced key values
+which contain a NULL column.
+
+Starting from version 3.23.50 the InnoDB parser allows you to
+use backquotes (`) around table and column names in the above
+definition but the InnoDB parser is not yet aware of possible
+variable @code{lower_case_table_names} you give in @file{my.cnf}.
+
+An example:
+@example
+CREATE TABLE parent(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
+CREATE TABLE child(id INT, parent_id INT, INDEX par_ind (parent_id),
+ FOREIGN KEY (parent_id) REFERENCES parent(id)
+ ON DELETE SET NULL
+) TYPE=INNODB;
+@end example
+
+If MySQL gives the error number 1005 from a @code{CREATE TABLE}
+statement, and the error message string refers to errno 150, then
+the table creation failed because a foreign key constraint was not
+correctly formed.
+Similarly, if an @code{ALTER TABLE} fails and it refers to errno
+150, that means a foreign key definition would be incorrectly
+formed for the altered table.
+
+Starting from version 3.23.50 InnoDB allows you to add a new
+foreign key constraint to a table through
+@example
+ALTER TABLE yourtablename
+ ADD CONSTRAINT FOREIGN KEY (...) REFERENCES anothertablename(...)
+@end example
+Remember to create the required indexes first, though.
+
+In InnoDB versions < 3.23.50 @code{ALTER TABLE}
+or @code{CREATE INDEX}
+should not be used in connection with tables which have foreign
+key constraints or which are referenced in foreign key constraints:
+Any @code{ALTER TABLE} removes all foreign key
+constrainst defined for the table. You should not use
+@code{ALTER TABLE} to the referenced table either, but
+use @code{DROP TABLE} and @code{CREATE TABLE} to modify the
+schema. When MySQL does an @code{ALTER TABLE} it may internally
+use @code{RENAME TABLE}, and that will confuse the
+foreign key costraints which refer to the table.
+A @code{CREATE INDEX} statement is in MySQL
+processed as an @code{ALTER TABLE}, and these
+restrictions apply also to it.
+
+When doing foreign key checks InnoDB sets shared row
+level locks on child or parent records it has to look at.
+InnoDB checks foreign key constraints immediately: the check
+is not deferred to transaction commit.
+
+InnoDB allows you to drop any table even though that
+would break the foreign key constraints which reference
+the table. When you drop a table the constraints which
+were defined in its create statement are also dropped.
+
+If you re-create a table which was dropped, it has to have
+a definition which conforms to the foreign key constraints
+referencing it. It must have the right column names and types,
+and it must have indexes on the referenced keys, as stated above.
+If these are not satisfied, MySQL returns error number 1005
+and refers to errno 150 in the error message string.
+
+Starting from version 3.23.50 InnoDB returns the foreign key
+definitions of a table when you call
+@example
+SHOW CREATE TABLE yourtablename
+@end example
+Then also @file{mysqldump} produces correct definitions
+of tables to the dump file, and does not forget about the
+foreign keys.
+
+You can also list the foreign key constraints for a table
+@code{T} with
+@example
+SHOW TABLE STATUS FROM yourdatabasename LIKE 'T'
+@end example
+The foreign key constraints are listed in the table comment of
+the output.
@node Adding and removing, Backing up, Using InnoDB tables, InnoDB
-@subsection Adding and removing InnoDB data and log files
+@subsection Adding and Removing InnoDB Data and Log Files
-You cannot increase the size of an InnoDB data file. To add more into
-your tablespace you have to add a new data file. To do this you have to
-shut down your MySQL database, edit the @file{my.cnf} file, adding a
-new file to @code{innodb_data_file_path}, and then start MySQL
-again.
+From version 3.23.50 and 4.0.2 you can specify the last InnoDB datafile
+to @code{autoextend}. Alternatively, you can increase to your tablespace
+by specifying an additional datafile. To do this you have to shut down
+the MySQL server, edit the @file{my.cnf} file adding a new datafile
+to @code{innodb_data_file_path}, and then start the MySQL server again.
-Currently you cannot remove a data file from InnoDB. To decrease the
-size of your database you have to use @code{mysqldump} to dump
+Currently you cannot remove a datafile from InnoDB. To decrease the
+size of your database you have to use @file{mysqldump} to dump
all your tables, create a new database, and import your tables to the
new database.
@@ -36672,16 +39124,28 @@ you at the startup that it is creating new log files.
@node Backing up, Moving, Adding and removing, InnoDB
-@subsection Backing up and recovering an InnoDB database
+@subsection Backing up and Recovering an InnoDB Database
The key to safe database management is taking regular backups.
-To take a 'binary' backup of your database you have to do the following:
+
+InnoDB Hot Backup is an online backup tool you can use to
+backup your InnoDB database while it is running. InnoDB
+Hot Backup does not require you to shut down your database
+and it does not set any locks or disturb your normal
+database processing. InnoDB Hot Backup is a non-free
+additional tool which is not included in the standard
+MySQL distribution. See the InnoDB Hot Backup homepage
+@uref{http://www.innodb.com/hotbackup.html}
+for detailed information and screenshots.
+
+If you are able to shut down your MySQL server, then to take
+a 'binary' backup of your database you have to do the following:
@itemize @bullet
@item
Shut down your MySQL database and make sure it shuts down without errors.
@item
-Copy all your data files into a safe place.
+Copy all your datafiles into a safe place.
@item
Copy all your InnoDB log files to a safe place.
@item
@@ -36691,9 +39155,6 @@ Copy all the @file{.frm} files for your InnoDB tables into a
safe place.
@end itemize
-There is currently no on-line or incremental backup tool available for
-InnoDB, though they are in the TODO list.
-
In addition to taking the binary backups described above,
you should also regularly take dumps of your tables with
@file{mysqldump}. The reason to this is that a binary file
@@ -36707,7 +39168,7 @@ A good idea is to take the dumps at the same time you take a binary
backup of your database. You have to shut out all clients from your
database to get a consistent snapshot of all your tables into your
dumps. Then you can take the binary backup, and you will then have
-a consistent snapshot of your database in two formats.
+a consistent snapshot of your database in two formats.
To be able to recover your InnoDB database to the present from the
binary backup described above, you have to run your MySQL database
@@ -36784,24 +39245,24 @@ has to make a checkpoint and often this involves flushing of
modified database pages to disk.
The above explains why making your log files very big may save
-disk i/o in checkpointing. It can make sense to set
+disk I/O in checkpointing. It can make sense to set
the total size of the log files as big as the buffer pool or even bigger.
The drawback in big log files is that crash recovery can last longer
because there will be more log to apply to the database.
@node Moving, InnoDB transaction model, Backing up, InnoDB
-@subsection Moving an InnoDB database to another machine
+@subsection Moving an InnoDB Database to Another Machine
InnoDB data and log files are binary-compatible on all platforms
-if the floating point number format on the machines is the same.
+if the floating-point number format on the machines is the same.
You can move an InnoDB database simply by copying all the relevant
files, which we already listed in the previous section on backing up
-a database. If the floating point formats on the machines are
+a database. If the floating-point formats on the machines are
different but you have not used @code{FLOAT} or @code{DOUBLE}
data types in your tables then the procedure is the same: just copy
the relevant files. If the formats are different and your tables
-contain floating point data, you have to use @file{mysqldump}
+contain floating-point data, you have to use @file{mysqldump}
and @file{mysqlimport} to move those tables.
A performance tip is to switch off the auto commit when you import
@@ -36812,10 +39273,10 @@ a table.
@node InnoDB transaction model, Implementation, Moving, InnoDB
-@subsection InnoDB transaction model
+@subsection InnoDB Transaction Model
In the InnoDB transaction model the goal has been to combine the best
-sides of a multiversioning database to traditional two-phase locking.
+properties of a multi-versioning database to traditional two-phase locking.
InnoDB does locking on row level and runs queries by default
as non-locking consistent reads, in the style of Oracle.
The lock table in InnoDB is stored so space-efficiently that lock
@@ -36824,7 +39285,7 @@ to lock every row in the database, or any random subset of the rows,
without InnoDB running out of memory.
In InnoDB all user activity happens inside transactions. If the
-auto commit mode is used in MySQL, then each SQL statement
+auto-commit mode is used in MySQL, then each SQL statement
will form a single transaction. If the auto commit mode is
switched off, then we can think that a user always has a transaction
open. If he issues
@@ -36838,19 +39299,19 @@ on the other hand cancels all modifications made by the current
transaction.
@menu
-* InnoDB consistent read:: Consistent read
-* InnoDB locking reads:: Locking reads
-* InnoDB Next-key locking:: Next-key locking: avoiding the phantom problem
-* InnoDB Locks set:: Locks set by different SQL statements in InnoDB
-* InnoDB Deadlock detection:: Deadlock detection and rollback
-* InnoDB Consistent read example:: An example of how the consistent read works in InnoDB
+* InnoDB consistent read:: Consistent Read
+* InnoDB locking reads:: Locking Reads
+* InnoDB Next-key locking:: Next-key Locking: Avoiding the Phantom Problem
+* InnoDB Locks set:: Locks Set by Different SQL Statements in InnoDB
+* InnoDB Deadlock detection:: Deadlock Detection and Rollback
+* InnoDB Consistent read example:: An Example of How the Consistent Read Works in InnoDB
@end menu
@node InnoDB consistent read, InnoDB locking reads, InnoDB transaction model, InnoDB transaction model
-@subsubsection Consistent read
+@subsubsection Consistent Read
-A consistent read means that InnoDB uses its multiversioning to
+A consistent read means that InnoDB uses its multi-versioning to
present to a query a snapshot of the database at a point in time.
The query will see the changes made by exactly those transactions that
committed before that point of time, and no changes made by later
@@ -36874,7 +39335,7 @@ on the table.
@node InnoDB locking reads, InnoDB Next-key locking, InnoDB consistent read, InnoDB transaction model
-@subsubsection Locking reads
+@subsubsection Locking Reads
A consistent read is not convenient in some circumstances.
Suppose you want to add a new row into your table @code{CHILD},
@@ -36932,7 +39393,7 @@ on the rows.
@node InnoDB Next-key locking, InnoDB Locks set, InnoDB locking reads, InnoDB transaction model
-@subsubsection Next-key locking: avoiding the phantom problem
+@subsubsection Next-key Locking: Avoiding the Phantom Problem
In row level locking InnoDB uses an algorithm called next-key locking.
InnoDB does the row level locking so that when it searches or
@@ -36976,7 +39437,7 @@ after the last record in the index. Just that happens in the previous
example: the locks set by InnoDB will prevent any insert to
the table where @code{ID} would be bigger than 100.
-You can use the next-key locking to implement a uniqueness
+You can use next-key locking to implement a uniqueness
check in your application: if you read your data in share mode
and do not see a duplicate for a row you are going to insert,
then you can safely insert your row and know that the next-key
@@ -36985,9 +39446,8 @@ anyone meanwhile inserting a duplicate for your row. Thus the next-key
locking allows you to 'lock' the non-existence of something in your
table.
-
@node InnoDB Locks set, InnoDB Deadlock detection, InnoDB Next-key locking, InnoDB transaction model
-@subsubsection Locks set by different SQL statements in InnoDB
+@subsubsection Locks Set by Different SQL Statements in InnoDB
@itemize @bullet
@item
@@ -37028,19 +39488,26 @@ lock on every record the search encounters.
@code{DELETE FROM ... WHERE ...} : sets an exclusive next-key
lock on every record the search encounters.
@item
+If a @code{FOREIGN KEY} constraint is defined on a table,
+any insert, update, or delete which requires checking of the constraint
+condition sets shared record level locks on the records it
+looks at to check the constraint. Also in the case where the
+constraint fails, InnoDB sets these locks.
+@item
@code{LOCK TABLES ... } : sets table locks. In the implementation
the MySQL layer of code sets these locks. The automatic deadlock detection
of InnoDB cannot detect deadlocks where such table locks are involved:
-see the next section below. See also section 13 'InnoDB restrictions'
-about the following: since MySQL does know about row level locks,
+see the following section.
+Also, since MySQL does know about row level locks,
it is possible that you
get a table lock on a table where another user currently has row level
locks. But that does not put transaction integerity into danger.
+@xref{InnoDB restrictions}.
@end itemize
@node InnoDB Deadlock detection, InnoDB Consistent read example, InnoDB Locks set, InnoDB transaction model
-@subsubsection Deadlock detection and rollback
+@subsubsection Deadlock Detection and Rollback
InnoDB automatically detects a deadlock of transactions and rolls
back the transaction whose lock request was the last one to build
@@ -37059,7 +39526,7 @@ stores row locks in a format where it cannot afterwards know which was
set by which SQL statement.
@node InnoDB Consistent read example, , InnoDB Deadlock detection, InnoDB transaction model
-@subsubsection An example of how the consistent read works in InnoDB
+@subsubsection An Example of How the Consistent Read Works in InnoDB
When you issue a consistent read, that is, an ordinary @code{SELECT}
statement, InnoDB will give your transaction a timepoint according
@@ -37070,12 +39537,12 @@ not see the row deleted. Similarly with inserts and updates.
You can advance your timepoint by committing your transaction
and then doing another @code{SELECT}.
-This is called multiversioned concurrency control.
+This is called multi-versioned concurrency control.
@example
User A User B
- set autocommit=0; set autocommit=0;
+ SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
time
| SELECT * FROM t;
| empty set
@@ -37091,33 +39558,76 @@ v SELECT * FROM t;
COMMIT;
SELECT * FROM t;
- ----------------------
- | 1 | 2 |
- ----------------------
+ ---------------------
+ | 1 | 2 |
+ ---------------------
@end example
Thus user A sees the row inserted by B only when B has committed the
insert, and A has committed his own transaction so that the timepoint
-is advanced past the the commit of B.
+is advanced past the commit of B.
-If you want to see the 'freshest' state of the database, you should use
-a locking read:
+If you want to see the ``freshest'' state of the database, you should
+use a locking read:
@example
SELECT * FROM t LOCK IN SHARE MODE;
@end example
+@subsubsection How to cope with deadlocks?
+
+Deadlocks are a classic problem in transactional databases,
+but they are not dangerous unless they are so frequent
+that you cannot run certain transactions at all.
+Normally you have to write your applications so
+that they are always prepared to re-issue a
+transaction if it gets rolled back because of a deadlock.
+
+InnoDB uses automatic row level locking. You can get
+deadlocks even in the case of transactions which just
+insert or delete a single row. That is because
+these operations are not really 'atomic': they
+automatically set locks on the (possibly several) index
+records of the row inserted/deleted.
+
+You can cope with deadlocks and reduce the number of
+them with the following tricks:
+
+@itemize @bullet
+@item
+Always be prepared to re-issue a transaction if it fails
+in a deadlock. Deadlocks are not dangerous. Just try again.
+@item
+Commit your transactions often. Small transactions are less
+prone to collide.
+@item
+Access your tables and rows in a fixed order. Then
+transactions will form nice queues, and do not deadlock.
+@item
+Use less locking: if you can afford a @code{SELECT} to return
+data from an old snapshot, do not add the clause
+@code{FOR UPDATE} or @code{LOCK IN SHARE MODE} to it.
+@item
+If nothing helps, serialize your transactions with table level
+locks: @code{LOCK TABLES t1 WRITE, t2 READ, ... ;
+[do something with tables t1 and t2 here]; UNLOCK TABLES.}
+Table level locks make you transactions to queue nicely,
+and deadlocks are avoided. Note that @code{LOCK TABLES} implicitly
+starts a transaction, just like the command @code{BEGIN},
+and @code{UNLOCK TABLES} implicitly ends the transaction in a
+@code{COMMIT}.
+@end itemize
-@subsection Performance tuning tips
+@subsection Performance Tuning Tips
@strong{1.}
If the Unix @file{top} or the Windows @file{Task Manager} shows that
-the CPU usage percentage with your workload is less than 70 %,
+the CPU usage percentage with your workload is less than 70%,
your workload is probably
disk-bound. Maybe you are making too many transaction commits, or the
buffer pool is too small.
Making the buffer pool bigger can help, but do not set
-it bigger than 80 % of physical memory.
+it bigger than 80% of physical memory.
@strong{2.}
Wrap several modifications into one transaction. InnoDB must
@@ -37156,22 +39666,22 @@ to @code{O_DSYNC}, though O_DSYNC seems to be slower on most systems.
Put before your plain SQL import file line
@example
-set autocommit=0;
+SET AUTOCOMMIT=0;
@end example
and after it
@example
-commit;
+COMMIT;
@end example
If you use the @file{mysqldump} option @code{--opt}, you will get dump
files which are fast to import also to an InnoDB table, even without wrapping
-them to the above @code{set autocommit=0; ... commit;} wrappers.
+them to the above @code{SET AUTOCOMMIT=0; ... COMMIT;} wrappers.
@strong{8.}
Beware of big rollbacks of mass inserts: InnoDB uses the insert buffer
-to save disk i/o in inserts, but in a corresponding rollback no such
+to save disk I/O in inserts, but in a corresponding rollback no such
mechanism is used. A disk-bound rollback can take 30 times the time
of the corresponding insert. Killing the database process will not
help because the rollback will start again at the database startup. The
@@ -37181,9 +39691,8 @@ InnoDB database.
@strong{9.}
Beware also of other big disk-bound operations.
-Use @code{DROP TABLE}
-or @code{TRUNCATE} (from MySQL-4.0 up) to empty a table, not
-@code{DELETE FROM yourtable}.
+Use @code{DROP TABLE} or @code{TRUNCATE} (from MySQL-4.0 up) to empty a
+table, not @code{DELETE FROM yourtable}.
@strong{10.}
Use the multi-line @code{INSERT} to reduce
@@ -37201,20 +39710,29 @@ This tip is of course valid for inserts into any table type, not just InnoDB.
Starting from version 3.23.41 InnoDB includes the InnoDB
Monitor which prints information on the InnoDB internal state.
When swithed on, InnoDB Monitor
-will make the MySQL server to print data to the standard
-output about once every 10 seconds. This data is useful in
+will make the MySQL server @file{mysqld} to print data
+(note: the MySQL client will not print anything)
+to the standard
+output about once every 15 seconds. This data is useful in
performance tuning.
+On Windows you must start @code{mysqld-max}
+from a MS-DOS prompt
+with the @code{--standalone --console}
+options to direct the output to the MS-DOS prompt
+window.
+
+There is a separate @code{innodb_lock_monitor} which
+prints the same information as @code{innodb_monitor}
+plus information on locks set by each transaction.
The printed information includes data on:
@itemize @bullet
@item
-table and record locks held by each active transaction,
-@item
lock waits of a transactions,
@item
semaphore waits of threads,
@item
-pending file i/o requests,
+pending file I/O requests,
@item
buffer pool statistics, and
@item
@@ -37263,8 +39781,8 @@ RECORD LOCKS space id 0 page no 12758 n bits 104 table test/mytable index
PRIMARY trx id 0 582333343 lock_mode X
Record lock, heap no 2 PHYSICAL RECORD: n_fields 74; 1-byte offs FALSE;
info bits 0
- 0: len 4; hex 0001a801; asc ;; 1: len 6; hex 000022b5b39f; asc ";; 2: len 7;
-hex 000002001e03ec; asc ;; 3: len 4; hex 00000001;
+ 0: len 4; hex 0001a801; asc ;; 1: len 6; hex 000022b5b39f; asc ";;
+ 2: len 7; hex 000002001e03ec; asc ;; 3: len 4; hex 00000001;
...
-----------------------------------------------
CURRENT SEMAPHORES RESERVED AND SEMAPHORE WAITS
@@ -37274,8 +39792,9 @@ Sorry, cannot give mutex list info in non-debug version!
Sorry, cannot give rw-lock list info in non-debug version!
-----------------------------------------------------
SYNC ARRAY INFO: reservation count 6041054, signal count 2913432
-4a239430 waited for by thread 49627477 op. S-LOCK file NOT KNOWN line 0
-Mut ex 0 sp 5530989 r 62038708 sys 2155035; rws 0 8257574 8025336; rwx 0 1121090 1848344
+4a239430 waited for by thread 49627477 op. S-LOCK file NOT KNOWN line 0
+Mut ex 0 sp 5530989 r 62038708 sys 2155035;
+rws 0 8257574 8025336; rwx 0 1121090 1848344
-----------------------------------------------------
CURRENT PENDING FILE I/O'S
--------------------------
@@ -37298,11 +39817,11 @@ Total of 0 reserved aio slots
-----------
BUFFER POOL
-----------
-LRU list length 8034
-Free list length 0
-Flush list length 999
+LRU list length 8034
+Free list length 0
+Flush list length 999
Buffer pool size in pages 8192
-Pending reads 39
+Pending reads 39
Pending writes: LRU 0, flush list 0, single page 0
Pages read 31383918, created 51310, written 2985115
----------------------------
@@ -37322,32 +39841,32 @@ may have lock contention. The output can also help to
trace reasons for transaction deadlocks.
@item
Section SYNC INFO will report reserved semaphores
-if you compile InnoDB with <code>UNIV_SYNC_DEBUG</code>
-defined in <tt>univ.i</tt>.
+if you compile InnoDB with @code{UNIV_SYNC_DEBUG}
+defined in @file{univ.i}.
@item
Section SYNC ARRAY INFO reports threads waiting
for a semaphore and statistics on how many times
threads have needed a spin or a wait on a mutex or
a rw-lock semaphore. A big number of threads waiting
-for semaphores may be a result of disk i/o, or
+for semaphores may be a result of disk I/O, or
contention problems inside InnoDB. Contention can be
due to heavy parallelism of queries, or problems in
operating system thread scheduling.
@item
Section CURRENT PENDING FILE I/O'S lists pending
-file i/o requests. A large number of these indicates
-that the workload is disk i/o -bound.
+file I/O requests. A large number of these indicates
+that the workload is disk I/O-bound.
@item
Section BUFFER POOL gives you statistics
on pages read and written. You can calculate from these
-numbers how many data file i/o's your queries are
+numbers how many datafile I/Os your queries are
currently doing.
@end itemize
@node Implementation, Table and index, InnoDB transaction model, InnoDB
-@subsection Implementation of multiversioning
+@subsection Implementation of Multi-versioning
-Since InnoDB is a multiversioned database, it must keep information
+Since InnoDB is a multi-versioned database, it must keep information
of old versions of rows in the tablespace. This information is stored
in a data structure we call a rollback segment after an analogous
data structure in Oracle.
@@ -37376,7 +39895,9 @@ a snapshot that in a consistent read could need the information
in the update undo log to build an earlier version of a database
row.
-You must remember to commit your transactions regularly. Otherwise
+You must remember to commit your transactions regularly,
+also those transactions which only issue consistent reads.
+Otherwise
InnoDB cannot discard data from the update undo logs, and the
rollback segment may grow too big, filling up your tablespace.
@@ -37385,7 +39906,7 @@ is typically smaller than the corresponding inserted or updated
row. You can use this information to calculate the space need
for your rollback segment.
-In our multiversioning scheme a row is not physically removed from
+In our multi-versioning scheme a row is not physically removed from
the database immediately when you delete it with an SQL statement.
Only when InnoDB can discard the update undo log record written for
the deletion, it can also physically remove the corresponding row and
@@ -37395,7 +39916,19 @@ time as the SQL statement which did the deletion.
@node Table and index, File space management, Implementation, InnoDB
-@subsection Table and index structures
+@subsection Table and Index Structures
+
+MySQL stores its data dictionary information of tables
+in @file{.frm}
+files in database directories. But every InnoDB type table
+also has its own entry in InnoDB internal data dictionaries
+inside the tablespace. When MySQL drops a table or a database,
+it has to delete both a @file{.frm} file or files, and
+the corresponding entries inside the InnoDB data dictionary.
+This is the reason why you cannot move InnoDB tables between
+databases simply by moving the @file{.frm} files, and why
+@code{DROP DATABASE} did not work for InnoDB type tables
+in MySQL versions <= 3.23.43.
Every InnoDB table has a special index called the clustered index
where the data of the rows is stored. If you define a
@@ -37413,7 +39946,7 @@ Accessing a row through the clustered index is fast, because
the row data will be on the same page where the index search
leads us. In many databases the data is traditionally stored on a different
page from the index record. If a table is large, the clustered
-index architecture often saves a disk i/o when compared to the
+index architecture often saves a disk I/O when compared to the
traditional solution.
The records in non-clustered indexes (we also call them secondary indexes),
@@ -37423,15 +39956,15 @@ index. Note that if the primary key is long, the secondary indexes
will use more space.
@menu
-* InnoDB physical structure:: Physical structure of an index
-* InnoDB Insert buffering:: Insert buffering
-* InnoDB Adaptive hash:: Adaptive hash indexes
-* InnoDB Physical record:: Physical record structure
+* InnoDB physical structure:: Physical Structure of an Index
+* InnoDB Insert buffering:: Insert Buffering
+* InnoDB Adaptive hash:: Adaptive Hash Indexes
+* InnoDB Physical record:: Physical Record Structure
@end menu
@node InnoDB physical structure, InnoDB Insert buffering, Table and index, Table and index
-@subsubsection Physical structure of an index
+@subsubsection Physical Structure of an Index
All indexes in InnoDB are B-trees where the index records are
stored in the leaf pages of the tree. The default size of an index
@@ -37447,7 +39980,7 @@ InnoDB will try to contract the index tree to free the page.
@node InnoDB Insert buffering, InnoDB Adaptive hash, InnoDB physical structure, Table and index
-@subsubsection Insert buffering
+@subsubsection Insert Buffering
It is a common situation in a database application that the
primary key is a unique identifier and new rows are inserted in the
@@ -37456,7 +39989,7 @@ clustered index do not require random reads from a disk.
On the other hand, secondary indexes are usually non-unique and
insertions happen in a relatively random order into secondary indexes.
-This would cause a lot of random disk i/o's without a special mechanism
+This would cause a lot of random disk I/Os without a special mechanism
used in InnoDB.
If an index record should be inserted to a non-unique secondary index,
@@ -37469,13 +40002,13 @@ pool, and insertions can be made to it very fast.
The insert buffer is periodically merged to the secondary index
trees in the database. Often we can merge several insertions on the
-same page in of the index tree, and hence save disk i/o's.
+same page in of the index tree, and hence save disk I/Os.
It has been measured that the insert buffer can speed up insertions
to a table up to 15 times.
@node InnoDB Adaptive hash, InnoDB Physical record, InnoDB Insert buffering, Table and index
-@subsubsection Adaptive hash indexes
+@subsubsection Adaptive Hash Indexes
If a database fits almost entirely in main memory, then the fastest way
to perform queries on it is to use hash indexes. InnoDB has an
@@ -37499,7 +40032,7 @@ databases.
@node InnoDB Physical record, , InnoDB Adaptive hash, Table and index
-@subsubsection Physical record structure
+@subsubsection Physical Record Structure
@itemize @bullet
@item
@@ -37522,16 +40055,16 @@ If the total length of the fields in a record is < 128 bytes, then
the pointer is 1 byte, else 2 bytes.
@end itemize
-@subsubsection How an auto-increment column works in InnoDB
+@subsubsection How an Auto-increment Column Works in InnoDB
After a database startup, when a user first does an insert to a
table @code{T}
where an auto-increment column has been defined, and the user does not provide
an explicit value for the column, then InnoDB executes @code{SELECT
MAX(auto-inc-column) FROM T}, and assigns that value incremented
-by one to the the column and the auto-increment counter of the table.
+by one to the column and the auto-increment counter of the table.
We say that
-the auto-increment counter for table @code{T} has been initialized.
+the auto-increment counter for table @code{T} has been initialised.
InnoDB follows the same procedure in initializing the auto-increment counter
for a freshly created table.
@@ -37540,7 +40073,7 @@ Note that if the user specifies in an insert the value 0 to the auto-increment
column, then InnoDB treats the row like the value would not have been
specified.
-After the auto-increment counter has been initialized, if a user inserts
+After the auto-increment counter has been initialised, if a user inserts
a row where he explicitly specifies the column value, and the value is bigger
than the current counter value, then the counter is set to the specified
column value. If the user does not explicitly specify a value, then InnoDB
@@ -37551,33 +40084,33 @@ bypasses locking and transaction handling. Therefore you may also get
gaps in the number sequence if you roll back transactions which have
got numbers from the counter.
-The behavior of auto-increment is not defined if a user gives a negative
+The behaviour of auto-increment is not defined if a user gives a negative
value to the column or if the value becomes bigger than the maximum
integer that can be stored in the specified integer type.
@node File space management, Error handling, Table and index, InnoDB
-@subsection File space management and disk i/o
+@subsection File Space Management and Disk I/O
@menu
-* InnoDB Disk i/o:: Disk i/o
-* InnoDB File space:: File space management
-* InnoDB File Defragmenting:: Defragmenting a table
+* InnoDB Disk I/O:: Disk I/O
+* InnoDB File space:: File Space Management
+* InnoDB File Defragmenting:: Defragmenting a Table
@end menu
-@node InnoDB Disk i/o, InnoDB File space, File space management, File space management
-@subsubsection Disk i/o
+@node InnoDB Disk I/O, InnoDB File space, File space management, File space management
+@subsubsection Disk I/O
-In disk i/o InnoDB uses asynchronous i/o. On Windows NT
-it uses the native asynchronous i/o provided by the operating system.
-On Unix, InnoDB uses simulated asynchronous i/o built
-into InnoDB: InnoDB creates a number of i/o threads to take care
-of i/o operations, such as read-ahead. In a future version we will
+In disk I/O InnoDB uses asynchronous I/O. On Windows NT
+it uses the native asynchronous I/O provided by the operating system.
+On Unix, InnoDB uses simulated asynchronous I/O built
+into InnoDB: InnoDB creates a number of I/O threads to take care
+of I/O operations, such as read-ahead. In a future version we will
add support for simulated aio on Windows NT and native aio on those
versions of Unix which have one.
-On Windows NT InnoDB uses non-buffered i/o. That means that the disk
+On Windows NT InnoDB uses non-buffered I/O. That means that the disk
pages InnoDB reads or writes are not buffered in the operating system
file cache. This saves some memory bandwidth.
@@ -37587,51 +40120,51 @@ It adds safety to crash recovery after an operating system crash
or a power outage, and improves performance on most Unix flavors
by reducing the need for fsync operations.
-Doublewrite means that InnoDB before writing pages to a data file
+Doublewrite means that InnoDB before writing pages to a datafile
first writes them to a contiguous tablespace area called the
doublewrite buffer. Only after the write and the flush to the doublewrite
buffer has completed, InnoDB writes the pages to their proper
-positions in the data file. If the operating system crashes in the
+positions in the datafile. If the operating system crashes in the
middle of a page write, InnoDB will in recovery find a good
copy of the page from the doublewrite buffer.
Starting from 3.23.41
-you can also use a raw disk partition as a data file, though this has
-not been tested yet. When you create a new data file you have
+you can also use a raw disk partition as a datafile, though this has
+not been tested yet. When you create a new datafile you have
to put the keyword @code{newraw} immediately after the data
-file size in @code{innodb_data_file_path}. The partition must be
+file-size in @code{innodb_data_file_path}. The partition must be
>= than you specify as the size. Note that 1M in InnoDB is
1024 x 1024 bytes, while in disk specifications 1 MB usually means
1000 000 bytes.
@example
-innodb_data_file_path=hdd1:3Gnewraw;hdd2:2Gnewraw
+innodb_data_file_path=hdd1:5Gnewraw;hdd2:2Gnewraw
@end example
-When you start the database again you MUST change the keyword
-to @code{raw}. Otherwise InnoDB will write over your
+When you start the database again you @strong{must} change the keyword
+to @code{raw}. Otherwise, InnoDB will write over your
partition!
@example
-innodb_data_file_path=hdd1:3Graw;hdd2:2Graw
+innodb_data_file_path=hdd1:5Graw;hdd2:2Graw
@end example
-Using a raw disk you can on some Unixes perform non-buffered i/o.
+By using a raw disk you can on some Unixes perform unbuffered I/O.
There are two read-ahead heuristics in InnoDB: sequential read-ahead
and random read-ahead. In sequential read-ahead InnoDB notices that
the access pattern to a segment in the tablespace is sequential.
Then InnoDB will post in advance a batch of reads of database pages to the
-i/o system. In random read-ahead InnoDB notices that some area
+I/O system. In random read-ahead InnoDB notices that some area
in a tablespace seems to be in the process of being
fully read into the buffer pool. Then InnoDB posts the remaining
-reads to the i/o system.
+reads to the I/O system.
-@node InnoDB File space, InnoDB File Defragmenting, InnoDB Disk i/o, File space management
-@subsubsection File space management
+@node InnoDB File space, InnoDB File Defragmenting, InnoDB Disk I/O, File space management
+@subsubsection File Space Management
-The data files you define in the configuration file form the tablespace
+The datafiles you define in the configuration file form the tablespace
of InnoDB. The files are simply catenated to form the tablespace,
there is no striping in use.
Currently you cannot directly instruct where the space is allocated
@@ -37661,10 +40194,9 @@ allocated to segments as a whole, but only as individual pages.
When you issue a query @code{SHOW TABLE STATUS FROM ... LIKE ...}
to ask for available free space in the tablespace, InnoDB will
-report you the space which is certainly usable in totally free extents
-of the tablespace. InnoDB always reserves some extents for
-clean-up and other internal purposes; these reserved extents are not
-included in the free space.
+report the extents which are definitely free in the tablespace.
+InnoDB always reserves some extents for clean-up and other internal
+purposes; these reserved extents are not included in the free space.
When you delete data from a table, InnoDB will contract the corresponding
B-tree indexes. It depends on the pattern of deletes if that frees
@@ -37677,7 +40209,7 @@ consistent read.
@node InnoDB File Defragmenting, , InnoDB File space, File space management
-@subsubsection Defragmenting a table
+@subsubsection Defragmenting a Table
If there are random insertions or deletions
in the indexes of a table, the indexes
@@ -37695,19 +40227,19 @@ Note that a @code{MyISAM} table must fit in a single file
on your operating system.
If the insertions to and index are always ascending and
-records are deleted only from the end, then the the file space management
+records are deleted only from the end, then the file space management
algorithm of InnoDB guarantees that fragmentation in the index will
not occur.
@node Error handling, InnoDB restrictions, File space management, InnoDB
-@subsection Error handling
+@subsection Error Handling
The error handling in InnoDB is not always the same as
specified in the ANSI SQL standards. According to the ANSI
standard, any error during an SQL statement should cause the
rollback of that statement. InnoDB sometimes rolls back only
-part of the statement.
+part of the statement, or the whole transaction.
The following list specifies the error handling of InnoDB.
@itemize @bullet
@@ -37716,9 +40248,9 @@ If you run out of file space in the tablespace,
you will get the MySQL @code{'Table is full'} error
and InnoDB rolls back the SQL statement.
@item
-A transaction deadlock or a timeout in a lock wait will give
-@code{'Table handler error 1000000'} and InnoDB rolls back
-the SQL statement.
+A transaction deadlock or a timeout in a lock wait make InnoDB
+to roll back
+the whole transaction.
@item
A duplicate key error only rolls back the insert of that particular row,
even in a statement like @code{INSERT INTO ... SELECT ...}.
@@ -37734,13 +40266,20 @@ they roll back the corresponding SQL statement.
@node InnoDB restrictions, InnoDB contact information, Error handling, InnoDB
-@subsection Some restrictions on InnoDB tables
+@subsection Restrictions on InnoDB Tables
@itemize @bullet
-@item @code{SHOW TABLE STATUS} does not give accurate statistics
+@item
+@strong{Warning}: do @strong{NOT} convert MySQL system tables from
+MyISAM TO InnoDB tables! This is not supported; if you do this MySQL
+will not restart until you restore the old system tables from a backup
+or re-generate them with the mysql_install_db script.
+
+@item
+@code{SHOW TABLE STATUS} does not give accurate statistics
on InnoDB tables, except for the physical size reserved by the table.
-The row count is only a rough estimate used in SQL optimization.
+The row count is only a rough estimate used in SQL optimisation.
@item
If you try to create an unique index on a prefix of a column you will get an
@@ -37750,7 +40289,7 @@ error:
CREATE TABLE T (A CHAR(20), B INT, UNIQUE (A(5))) TYPE = InnoDB;
@end example
-If you create a non unique index on a prefix of a column, InnoDB will
+If you create a non-unique index on a prefix of a column, InnoDB will
create an index over the whole column.
@item
@code{INSERT DELAYED} is not supported for InnoDB tables.
@@ -37762,7 +40301,7 @@ of other users which have row level locks on the same table. Thus
your operations on the table may have to wait if they collide with
these locks of other users. Also a deadlock is possible. However,
this does not endanger transaction integrity, because the row level
-locks set by InnoDB will always take care of the integrity.
+locks set by InnoDB will always take care of the integrity.
Also, a table lock prevents other transactions from acquiring more
row level locks (in a conflicting lock mode) on the table.
@item
@@ -37774,23 +40313,19 @@ A table cannot contain more than 1000 columns.
deletes all rows, one by one, which is not that fast. In future versions
of MySQL you can use @code{TRUNCATE} which is fast.
@item
-Before dropping a database with InnoDB tables one has to drop
-the individual InnoDB tables first.
-@item
The default database page size in InnoDB is 16 kB. By recompiling the
code one can set it from 8 kB to 64 kB.
The maximun row length is slightly less than half of a database page
in versions <= 3.23.40 of InnoDB. Starting from source
release 3.23.41 BLOB and
TEXT columns are allowed to be < 4 GB, the total row length must also be
-< 4 GB. InnoDB does not store fields whose size is <= 30 bytes on separate
+< 4 GB. InnoDB does not store fields whose size is <= 128 bytes on separate
pages. After InnoDB has modified the row by storing long fields on
-separate pages, the remaining length of the row must be slightly less
-than half a database page.
+separate pages, the remaining length of the row must be less
+than half a database page. The maximun key length is 7000 bytes.
@item
-The maximum data or log file size is 2 GB or 4 GB depending on how large
-files your operating system supports. Support for > 4 GB files will
-be added to InnoDB in a future version.
+On some operating systems datafiles must be < 2 GB. The combined
+size of log files must be < 4 GB.
@item
The maximum tablespace size is 4 billion database pages. This is also
the maximum size for a table. The minimum tablespace size is 10 MB.
@@ -37798,15 +40333,15 @@ the maximum size for a table. The minimum tablespace size is 10 MB.
@node InnoDB contact information, , InnoDB restrictions, InnoDB
-@subsection InnoDB contact information
+@subsection InnoDB Contact Information
Contact information of Innobase Oy, producer of the InnoDB engine.
-Website: @uref{http://www.innodb.com}. Email:
-@email{Heikki.Tuuri@@innodb.com}
+Web site: @uref{http://www.innodb.com/}.
+E-mail: @email{Heikki.Tuuri@@innodb.com}
@example
phone: 358-9-6969 3250 (office) 358-40-5617367 (mobile)
-InnoDB Oy Inc.
+Innobase Oy Inc.
World Trade Center Helsinki
Aleksanterinkatu 17
P.O.Box 800
@@ -37815,6 +40350,323 @@ Finland
@end example
+@node BDB, , InnoDB, Table types
+@section @code{BDB} or @code{BerkeleyDB} Tables
+
+@cindex tables, @code{BDB}
+@cindex tables, @code{Berkeley DB}
+
+@menu
+* BDB overview:: Overview of BDB Tables
+* BDB install:: Installing BDB
+* BDB start:: BDB startup options
+* BDB characteristics:: Characteristics of @code{BDB} tables:
+* BDB TODO:: Things we need to fix for BDB in the near future:
+* BDB portability:: Operating systems supported by @code{BDB}
+* BDB restrictions:: Restrictions on BDB Tables
+* BDB errors:: Errors That May Occur When Using BDB Tables
+@end menu
+
+@node BDB overview, BDB install, BDB, BDB
+@subsection Overview of BDB Tables
+
+Support for BDB tables is included in the MySQL source distribution
+starting from Version 3.23.34 and is activated in the MySQL-Max
+binary.
+
+BerkeleyDB, available at @uref{http://www.sleepycat.com/} has provided
+MySQL with a transactional table handler. By using BerkeleyDB
+tables, your tables may have a greater chance of surviving crashes, and also
+provides @code{COMMIT} and @code{ROLLBACK} on transactions. The
+MySQL source distribution comes with a BDB distribution that has a
+couple of small patches to make it work more smoothly with MySQL.
+You can't use a non-patched @code{BDB} version with MySQL.
+
+We at MySQL AB are working in close cooperation with Sleepycat to
+keep the quality of the MySQL/BDB interface high.
+
+When it comes to supporting BDB tables, we are committed to help our
+users to locate the problem and help creating a reproducable test case
+for any problems involving BDB tables. Any such test case will be
+forwarded to Sleepycat who in turn will help us find and fix the
+problem. As this is a two stage operation, any problems with BDB tables
+may take a little longer for us to fix than for other table handlers.
+However, as the BerkeleyDB code itself has been used by many other
+applications than MySQL, we don't envision any big problems with
+this. @xref{Support}.
+
+
+@node BDB install, BDB start, BDB overview, BDB
+@subsection Installing BDB
+
+If you have downloaded a binary version of MySQL that includes
+support for BerkeleyDB, simply follow the instructions for installing a
+binary version of MySQL.
+@xref{Installing binary}. @xref{mysqld-max, , @code{mysqld-max}}.
+
+To compile MySQL with Berkeley DB support, download MySQL
+Version 3.23.34 or newer and configure @code{MySQL} with the
+@code{--with-berkeley-db} option. @xref{Installing source}.
+
+@example
+cd /path/to/source/of/mysql-3.23.34
+./configure --with-berkeley-db
+@end example
+
+Please refer to the manual provided with the @code{BDB} distribution for
+more updated information.
+
+Even though Berkeley DB is in itself very tested and reliable,
+the MySQL interface is still considered beta quality.
+We are actively improving and optimising it to get it stable very
+soon.
+
+
+@node BDB start, BDB characteristics, BDB install, BDB
+@subsection BDB startup options
+
+If you are running with @code{AUTOCOMMIT=0} then your changes in @code{BDB}
+tables will not be updated until you execute @code{COMMIT}. Instead of commit
+you can execute @code{ROLLBACK} to forget your changes. @xref{COMMIT}.
+
+If you are running with @code{AUTOCOMMIT=1} (the default), your changes
+will be committed immediately. You can start an extended transaction with
+the @code{BEGIN WORK} SQL command, after which your changes will not be
+committed until you execute @code{COMMIT} (or decide to @code{ROLLBACK}
+the changes).
+
+The following options to @code{mysqld} can be used to change the behaviour of
+BDB tables:
+
+@multitable @columnfractions .25 .55
+@item @strong{Option} @tab @strong{Description}
+@item @code{--bdb-home=directory} @tab Base directory for BDB tables. This should be the same directory you use for --datadir.
+@item @code{--bdb-lock-detect=#} @tab Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM, or YOUNGEST).
+@item @code{--bdb-logdir=directory} @tab Berkeley DB log file directory.
+@item @code{--bdb-no-sync} @tab Don't synchronously flush logs.
+@item @code{--bdb-no-recover} @tab Don't start Berkeley DB in recover mode.
+@item @code{--bdb-shared-data} @tab Start Berkeley DB in multi-process mode (Don't use @code{DB_PRIVATE} when initialising Berkeley DB)
+@item @code{--bdb-tmpdir=directory} @tab Berkeley DB tempfile name.
+@item @code{--skip-bdb} @tab Don't use berkeley db.
+@item @code{-O bdb_max_lock=1000} @tab Set the maximum number of locks possible. @xref{SHOW VARIABLES}.
+@end multitable
+
+If you use @code{--skip-bdb}, MySQL will not initialise the
+Berkeley DB library and this will save a lot of memory. Of course,
+you cannot use @code{BDB} tables if you are using this option.
+
+Normally you should start @code{mysqld} without @code{--bdb-no-recover} if you
+intend to use BDB tables. This may, however, give you problems when you
+try to start @code{mysqld} if the BDB log files are corrupted. @xref{Starting
+server}.
+
+With @code{bdb_max_lock} you can specify the maximum number of locks
+(10000 by default) you can have active on a BDB table. You should
+increase this if you get errors of type @code{bdb: Lock table is out of
+available locks} or @code{Got error 12 from ...} when you have do long
+transactions or when @code{mysqld} has to examine a lot of rows to
+calculate the query.
+
+You may also want to change @code{binlog_cache_size} and
+@code{max_binlog_cache_size} if you are using big multi-line transactions.
+@xref{COMMIT, , @code{COMMIT}}.
+
+
+@node BDB characteristics, BDB TODO, BDB start, BDB
+@subsection Characteristics of @code{BDB} tables:
+
+@itemize @bullet
+@item
+To be able to rollback transactions BDB maintain log files. For maximum
+performance you should place these on another disk than your databases
+by using the @code{--bdb_log_dir} options.
+@item
+MySQL performs a checkpoint each time a new BDB log
+file is started, and removes any log files that are not needed for
+current transactions. One can also run @code{FLUSH LOGS} at any time
+to checkpoint the Berkeley DB tables.
+
+For disaster recovery, one should use table backups plus
+MySQL's binary log. @xref{Backup}.
+
+@strong{Warning}: If you delete old log files that are in use, BDB will
+not be able to do recovery at all and you may lose data if something
+goes wrong.
+@item
+MySQL requires a @code{PRIMARY KEY} in each BDB table to be
+able to refer to previously read rows. If you don't create one,
+MySQL will create an maintain a hidden @code{PRIMARY KEY} for
+you. The hidden key has a length of 5 bytes and is incremented for each
+insert attempt.
+@item
+If all columns you access in a @code{BDB} table are part of the same index or
+part of the primary key, then MySQL can execute the query
+without having to access the actual row. In a @code{MyISAM} table the
+above holds only if the columns are part of the same index.
+@item
+The @code{PRIMARY KEY} will be faster than any other key, as the
+@code{PRIMARY KEY} is stored together with the row data. As the other keys are
+stored as the key data + the @code{PRIMARY KEY}, it's important to keep the
+@code{PRIMARY KEY} as short as possible to save disk and get better speed.
+@item
+@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If
+you don't use @code{LOCK TABLE}, MySQL will issue an internal
+multiple-write lock on the table to ensure that the table will be
+properly locked if another thread issues a table lock.
+@item
+Internal locking in @code{BDB} tables is done on page level.
+@item
+@code{SELECT COUNT(*) FROM table_name} is slow as @code{BDB} tables doesn't
+maintain a count of the number of rows in the table.
+@item
+Scanning is slower than with @code{MyISAM} tables as one has data in BDB
+tables stored in B-trees and not in a separate datafile.
+@item
+The application must always be prepared to handle cases where
+any change of a @code{BDB} table may make an automatic rollback and any
+read may fail with a deadlock error.
+@item
+Keys are not compressed to previous keys as with ISAM or MyISAM
+tables. In other words, the key information will take a little more
+space in @code{BDB} tables compared to MyISAM tables which don't use
+@code{PACK_KEYS=0}.
+@item
+There is often holes in the BDB table to allow you to insert new rows in
+the middle of the key tree. This makes BDB tables somewhat larger than
+MyISAM tables.
+@item
+The optimiser needs to know an approximation of the number of rows in
+the table. MySQL solves this by counting inserts and
+maintaining this in a separate segment in each BDB table. If you don't
+issue a lot of @code{DELETE} or @code{ROLLBACK} statements, this number
+should be accurate enough for the MySQL optimiser, but as MySQL
+only stores the number on close, it may be incorrect if MySQL dies
+unexpectedly. It should not be fatal even if this number is not 100%
+correct. One can update the number of rows by executing @code{ANALYZE
+TABLE} or @code{OPTIMIZE TABLE}. @xref{ANALYZE TABLE} . @xref{OPTIMIZE
+TABLE}.
+@item
+If you get full disk with a @code{BDB} table, you will get an error
+(probably error 28) and the transaction should roll back. This is in
+contrast with @code{MyISAM} and @code{ISAM} tables where @code{mysqld} will
+wait for enough free disk before continuing.
+@end itemize
+
+
+@node BDB TODO, BDB portability, BDB characteristics, BDB
+@subsection Things we need to fix for BDB in the near future:
+
+@itemize @bullet
+@item
+It's very slow to open many BDB tables at the same time. If you are
+going to use BDB tables, you should not have a very big table cache
+(like >256) and you should use @code{--no-auto-rehash} with the @code{mysql}
+client. We plan to partly fix this in 4.0.
+@item
+@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB
+tables.
+@item
+Optimise performance.
+@item
+Change to not use page locks at all when we are scanning tables.
+@end itemize
+
+
+@node BDB portability, BDB restrictions, BDB TODO, BDB
+@subsection Operating systems supported by @code{BDB}
+
+If you after having built MySQL with support for BDB tables get
+the following error in the log file when you start @code{mysqld}:
+
+@example
+bdb: architecture lacks fast mutexes: applications cannot be threaded
+Can't init dtabases
+@end example
+
+This means that @code{BDB} tables are not supported for your architecture.
+In this case you have to rebuild MySQL without BDB table support.
+
+Note: The following list is not complete; we will update it as we
+receive more information about this.
+
+Currently we know that BDB tables works with the following operating
+system.
+
+@itemize @bullet
+@item
+Linux 2.x intel
+@item
+Solaris SPARC
+@item
+Caldera (SCO) OpenServer
+@item
+Caldera (SCO) UnixWare 7.0.1
+@end itemize
+
+It doesn't work with the following operating systems:
+
+@itemize @bullet
+@item
+Linux 2.x Alpha
+@item
+Max OS X
+@end itemize
+
+@node BDB restrictions, BDB errors, BDB portability, BDB
+@subsection Restrictions on BDB Tables
+
+Here follows the restrictions you have when using BDB tables:
+
+@itemize @bullet
+@item
+BDB tables store in the .db file the path to the file as it was created
+This was done to be able to detect locks in a multi-user
+environment that supports symlinks).
+
+The effect of this is that BDB tables are not movable between directories!
+@item
+When taking backups of BDB tables, you have to either use
+@code{mysqldump} or take a backup of all @code{table_name.db} files and
+the BDB log files. The BDB log files are the files in the base data
+directory named @code{log.XXXXXX} (6 digits);
+The BDB table handler stores unfinished transactions in the log files
+and requires these to be present when @code{mysqld} starts.
+@end itemize
+
+@node BDB errors, , BDB restrictions, BDB
+@subsection Errors That May Occur When Using BDB Tables
+
+@itemize @bullet
+@item
+If you get the following error in the @code{hostname.err log} when
+starting @code{mysqld}:
+
+@example
+bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version #
+@end example
+it means that the new @code{BDB} version doesn't support the old log
+file format. In this case you have to delete all @code{BDB} log BDB
+from your database directory (the files that has the format
+@code{log.XXXXXXXXXX} ) and restart @code{mysqld}. We would also
+recommend you to do a @code{mysqldump --opt} of your old @code{BDB}
+tables, delete the old table and restore the dump.
+@item
+If you are running in not @code{auto_commit} mode and delete a table you
+are using by another thread you may get the following error messages in
+the MySQL error file:
+
+@example
+001119 23:43:56 bdb: Missing log fileid entry
+001119 23:43:56 bdb: txn_abort: Log undo failed for LSN:
+ 1 3644744: Invalid
+@end example
+
+This is not fatal but we don't recommend that you delete tables if you are
+not in @code{auto_commit} mode, until this problem is fixed (the fix is
+not trivial).
+@end itemize
+
+
@node Clients, Extending MySQL, Table types, Top
@@ -37840,7 +40692,7 @@ Finland
This chapter describes the APIs available for MySQL, where to get
them, and how to use them. The C API is the most extensively covered, as it
-was developed by the MySQL team, and is the basis for most of the
+was developed by the MySQL team, and is the basis for most of the
other APIs.
@@ -37850,12 +40702,12 @@ other APIs.
@cindex PHP API
PHP is a server-side, HTML-embedded scripting language that may be used to
-create dynamic Web pages. It contains support for accessing several
+create dynamic web pages. It contains support for accessing several
databases, including MySQL. PHP may be run as a separate program
-or compiled as a module for use with the Apache Web server.
+or compiled as a module for use with the Apache web server.
-The distribution and documentation are available at the
-@uref{http://www.php.net/, PHP web site}.
+The distribution and documentation are available at the PHP web site
+(@uref{http://www.php.net/}).
@menu
* PHP problems:: Common problems with MySQL and PHP
@@ -37866,7 +40718,7 @@ The distribution and documentation are available at the
@itemize @bullet
@item Error: "Maximum Execution Time Exceeded"
-This is a PHP limit; Go into the @file{php3.ini} file and set the maximum
+This is a PHP limit; go into the @file{php3.ini} file and set the maximum
execution time up from 30 seconds to something higher, as needed.
It is also not a bad idea to double the ram allowed per script to 16MB instead of
8 MB.
@@ -37911,10 +40763,10 @@ without change. You need a DataBase Driver (DBD) defined for each
database type. For MySQL, this driver is called
@code{DBD::mysql}.
-For more information on the Perl5 DBI, please visit the @code{DBI} Web
+For more information on the Perl5 DBI, please visit the @code{DBI} web
page and read the documentation:
@example
-@uref{http://www.symbolstone.org/technology/perl/DBI/index.html}
+@uref{http://dbi.perl.org/}
@end example
For more information on Object Oriented Programming
(OOP) as defined in Perl5, see the Perl OOP page:
@@ -37937,7 +40789,8 @@ Installation instructions for MySQL Perl support are given in
@noindent
@strong{Portable DBI Methods}
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .25 .60
+@item @strong{Method} @tab @strong{Description}
@item @code{connect} @tab Establishes a connection to a database server.
@item @code{disconnect} @tab Disconnects from the database server.
@item @code{prepare} @tab Prepares a SQL statement for execution.
@@ -37960,7 +40813,8 @@ Installation instructions for MySQL Perl support are given in
@noindent
@strong{MySQL-specific Methods}
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .25 .60
+@item @strong{Method} @tab @strong{Description}
@item @code{insertid} @tab The latest @code{AUTO_INCREMENT} value.
@item @code{is_blob} @tab Which columns are @code{BLOB} values.
@item @code{is_key} @tab Which columns are keys.
@@ -38096,7 +40950,7 @@ affected. If no rows are affected, @code{execute} returns @code{"0E0"},
which Perl treats as zero but regards as true. If an error occurs,
@code{execute} returns @code{undef}. For @code{SELECT} statements,
@code{execute} only starts the SQL query in the database; you need to use one
-of the @code{fetch_*} methods described below to retrieve the data.
+of the @code{fetch_*} methods described here to retrieve the data.
Example:
@example
$rv = $sth->execute
@@ -38117,7 +40971,7 @@ $rv = $dbh->do($statement)
or die "Can't execute $statement: $dbh- >errstr\n";
@end example
-Generally the 'do' statement is MUCH faster (and is preferable)
+Generally the 'do' statement is much faster (and is preferable)
than prepare/execute for statements that don't contain parameters.
@findex DBI->quote()
@@ -38209,9 +41063,11 @@ $rv = $sth->rows;
@findex DBI->@{NULLABLE@}
@findex NULLABLE DBI method
@item NULLABLE
-Returns a reference to an array of boolean values; for each element of
-the array, a value of TRUE indicates that this
-column may contain @code{NULL} values.
+Returns a reference to an array of values that indicate whether columns may
+contain @code{NULL} values.
+The possible values for each array element are 0 or the empty string if the
+column cannot be @code{NULL}, 1 if it can, and 2 if the column's @code{NULL}
+status is unknown.
Example:
@example
$null_possible = $sth->@{NULLABLE@};
@@ -38261,7 +41117,7 @@ handle (and any future children of the handle). Setting @code{$trace_level}
to 2 provides detailed trace information. Setting @code{$trace_level} to 0
disables tracing. Trace output goes to the standard error output by
default. If @code{$trace_filename} is specified, the file is opened in
-append mode and output for @emph{all} traced handles is written to that
+append mode and output for @strong{all} traced handles is written to that
file. Example:
@example
DBI->trace(2); # trace everything
@@ -38283,11 +41139,11 @@ environment variable. Setting it to a numeric value is equivalent to calling
@noindent
@strong{MySQL-specific Methods}
-The methods shown below are MySQL-specific and not part of the
+The methods shown here are MySQL-specific and not part of the
@code{DBI} standard. Several of them are now deprecated:
@code{is_blob}, @code{is_key}, @code{is_num}, @code{is_pri_key},
@code{is_not_null}, @code{length}, @code{max_length}, and @code{table}.
-Where @code{DBI}-standard alternatives exist, they are noted below:
+Where @code{DBI}-standard alternatives exist, they are noted here:
@table @code
@findex DBI->@{insertid@}
@@ -38424,10 +41280,7 @@ You can also use the @code{pod2man}, @code{pod2html}, etc., tools to
translate to other formats.
You can find the latest @code{DBI} information at
-the @code{DBI} Web page:
-@example
-@uref{http://www.symbolstone.org/technology/perl/DBI/index.html}
-@end example
+the @code{DBI} web page: @uref{http://dbi.perl.org/}.
@node ODBC, C, Perl, Clients
@@ -38442,51 +41295,48 @@ the @code{DBI} Web page:
* ODBC administrator:: How to fill in the various fields in the ODBC administrator program
* MyODBC connect parameters:: Connect parameters for MyODBC
* ODBC Problems:: How to report problems with MySQL ODBC
-* MyODBC clients:: Programs known to work with @strong{MyODBC}
+* MyODBC clients:: Programs known to work with @code{MyODBC}
* ODBC and last_insert_id:: How to get the value of an @code{AUTO_INCREMENT} column in ODBC
* MyODBC bug report:: Reporting problems with MyODBC
@end menu
-MySQL provides support for ODBC by means of the @strong{MyODBC}
-program. This chapter will teach you how to install @strong{MyODBC},
+MySQL provides support for ODBC by means of the @code{MyODBC}
+program. This chapter will teach you how to install @code{MyODBC},
and how to use it. Here, you will also find a list of common programs that
-are known to work with @strong{MyODBC}.
+are known to work with @code{MyODBC}.
@node Installing MyODBC, ODBC administrator, ODBC, ODBC
@subsection How To Install MyODBC
-@strong{MyODBC} is a 32-bit ODBC (2.50) level 0 (with level 1 and level
-2 features) driver for connecting an ODBC-aware application to
-MySQL. @strong{MyODBC} works on Windows95, Windows98, NT, and
-on most Unix platforms.
+@code{MyODBC} is a 32-bit ODBC (2.50) level 0 (with level 1 and
+level 2 features) driver for connecting an ODBC-aware application
+to MySQL. @code{MyODBC} works on Windows 9x/Me/NT/2000/XP
+and most Unix platforms.
-@strong{MyODBC} is in public domain, and you can find the newest version
-at @uref{http://www.mysql.com/downloads/api-myodbc.html}.
+@code{MyODBC} is in public domain, and you can find the newest
+version at @uref{http://www.mysql.com/downloads/api-myodbc.html}.
-If you have problem with @strong{MyODBC} and your program also works
-with OLEDB, you should try the OLEDB driver that you can find in the
-Contrib section. @xref{Contrib}.
+If you have problem with @code{MyODBC} and your program also works
+with OLEDB, you should try the OLEDB driver.
-Normally you only need to install @strong{MyODBC} on Windows machines.
-You only need @strong{MyODBC} for Unix if you have a program like
+Normally you only need to install @code{MyODBC} on Windows machines.
+You only need @code{MyODBC} for Unix if you have a program like
ColdFusion that is running on the Unix machine and uses ODBC to connect
to the databases.
-If you want to install @strong{MyODBC} on a Unix box, you will also need
-an @strong{ODBC} manager. @strong{MyODBC} is known to work with
-most of the Unix ODBC managers. You can find a list at these in the
-@strong{ODBC}-related links section on the MySQL useful links page.
-@xref{Useful Links}.
+If you want to install @code{MyODBC} on a Unix box, you will also need
+an @code{ODBC} manager. @code{MyODBC} is known to work with
+most of the Unix ODBC managers. @xref{Portals}.
-To install @strong{MyODBC} on Windows, you should download the
-appropriate @strong{MyODBC} .zip file (for Windows or NT/Win2000),
-unpack it with @code{WINZIP}, or some similar program, and execute the
-@code{SETUP.EXE} file.
+To install @code{MyODBC} on Windows, you should download the
+appropriate @code{MyODBC} @file{.zip} file,
+unpack it with @code{WinZIP} or some similar program,
+and execute the @file{SETUP.EXE} file.
-On Windows/NT you may get the following error when trying to install
-@strong{MyODBC}:
+On Windows/NT/XP you may get the following error when trying to install
+@code{MyODBC}:
@example
An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart
@@ -38501,14 +41351,14 @@ cases you can continue by just pressing @code{Ignore} to copy the rest
of the MyODBC files and the final installation should still work. If
this doesn't work, the solution is to reboot your computer in ``safe
mode`` (Choose this by pressing F8 just before your machine starts
-Windows during rebooting), install @strong{MyODBC}, and reboot to normal
+Windows during rebooting), install @code{MyODBC}, and reboot to normal
mode.
@itemize @bullet
@item
To make a connection to a Unix box from a Windows box, with an ODBC
application (one that doesn't support MySQL natively), you must
-first install @strong{MyODBC} on the Windows machine.
+first install @code{MyODBC} on the Windows machine.
@item
The user and Windows machine must have the access privileges to the
MySQL server on the Unix machine. This is set up with the
@@ -38520,7 +41370,7 @@ You must create an ODBC DSN entry as follows:
@item
Open the Control Panel on the Windows machine.
@item
-Double-click the ODBC Data Sources 32 bits icon.
+Double-click the ODBC Data Sources 32-bit icon.
@item
Click the tab User DSN.
@item
@@ -38597,38 +41447,38 @@ is used.
If you specify the option @code{Read options from C:\my.cnf}, the groups
@code{client} and @code{odbc} will be read from the @file{C:\my.cnf} file.
You can use all options that are usable by @code{mysql_options()}.
-@xref{mysql_options, , @code{mysql_options}}.
+@xref{mysql_options, , @code{mysql_options()}}.
@node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC
@subsection Connect parameters for MyODBC
-One can specify the following parameters for @strong{MyODBC} on
-the @code{[Servername]} section of an @code{ODBC.INI} file or
+One can specify the following parameters for @code{MyODBC} on
+the @code{[Servername]} section of an @file{ODBC.INI} file or
through the @code{InConnectionString} argument in the
@code{SQLDriverConnect()} call.
-@multitable @columnfractions .2 .2 .6
+@multitable @columnfractions .15 .20 .65
@item @strong{Parameter} @tab @strong{Default value} @tab @strong{Comment}
@item user @tab ODBC (on Windows) @tab The username used to connect to MySQL.
@item server @tab localhost @tab The hostname of the MySQL server.
@item database @tab @tab The default database
-@item option @tab 0 @tab A integer by which you can specify how @strong{MyODBC} should work. See below.
+@item option @tab 0 @tab A integer by which you can specify how @code{MyODBC} should work. See below.
@item port @tab 3306 @tab The TCP/IP port to use if @code{server} is not @code{localhost}.
@item stmt @tab @tab A statement that will be executed when connection to @code{MySQL}.
@item password @tab @tab The password for the @code{server} @code{user} combination.
@item socket @tab @tab The socket or Windows pipe to connect to.
@end multitable
-The option argument is used to tell @strong{MyODBC} that the client isn't 100%
+The option argument is used to tell @code{MyODBC} that the client isn't 100%
ODBC compliant. On Windows, one normally sets the option flag by
toggling the different options on the connection screen but one can also
set this in the opton argument. The following options are listed in the
-same order as they appear in the @strong{MyODBC} connect screen:
+same order as they appear in the @code{MyODBC} connect screen:
-@multitable @columnfractions .1 .9
-@item @strong{Bit} @tab @strong{Meaning}
-@item 1 @tab The client can't handle that @strong{MyODBC} returns the real width of a column.
+@multitable @columnfractions .10 .90
+@item @strong{Bit} @tab @strong{Description}
+@item 1 @tab The client can't handle that @code{MyODBC} returns the real width of a column.
@item 2 @tab The client can't handle that MySQL returns the true value of affected rows. If this flag is set then MySQL returns 'found rows' instead. One must have MySQL 3.21.14 or newer to get this to work.
@item 4 @tab Make a debug log in c:\myodbc.log. This is the same as putting @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in @file{AUTOEXEC.BAT}
@item 8 @tab Don't set any packet limit for results and parameters.
@@ -38636,15 +41486,15 @@ same order as they appear in the @strong{MyODBC} connect screen:
@item 32 @tab Simulate a ODBC 1.0 driver in some context.
@item 64 @tab Ignore use of database name in 'database.table.column'.
@item 128 @tab Force use of ODBC manager cursors (experimental).
-@item 256 @tab Disable the use of extended fetch (experimental)
+@item 256 @tab Disable the use of extended fetch (experimental).
@item 512 @tab Pad CHAR fields to full column length.
@item 1024 @tab SQLDescribeCol() will return fully qualifed column names
@item 2048 @tab Use the compressed server/client protocol
@item 4096 @tab Tell server to ignore space after function name and before @code{'('} (needed by PowerBuilder). This will make all function names keywords!
@item 8192 @tab Connect with named pipes to a @code{mysqld} server running on NT.
-@item 16384 @tab Change LONGLONG columns to INT columns (Some applications can't handle LONGLONG).
+@item 16384 @tab Change LONGLONG columns to INT columns (some applications can't handle LONGLONG).
@item 32768 @tab Return 'user' as Table_qualifier and Table_owner from SQLTables (experimental)
-@item 65536 @tab Read parameters from the @code{client} and @code{odbc} groups from @file{my.cnf}
+@item 65536 @tab Read parameters from the @code{client} and @code{odbc} groups from @file{my.cnf}
@item 131072 @tab Add some extra safety checks (should not bee needed but...)
@end multitable
@@ -38653,22 +41503,22 @@ example setting option to 12 (4+8) gives you debugging without package
limits!
The default @file{MYODBC.DLL} is compiled for optimal performance. If
-you want to to debug @strong{MyODBC} (for example to enable tracing),
-you should instead use @code{MYODBCD.DLL}. To install this file, copy
-@file{MYODBCD.DLL} over the installed @code{MYODBC.DLL} file.
+you want to to debug @code{MyODBC} (for example to enable tracing),
+you should instead use @file{MYODBCD.DLL}. To install this file, copy
+@file{MYODBCD.DLL} over the installed @file{MYODBC.DLL} file.
@node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC
@subsection How to Report Problems with MyODBC
-@strong{MyODBC} has been tested with Access, Admndemo.exe, C++-Builder,
+@code{MyODBC} has been tested with Access, Admndemo.exe, C++-Builder,
Borland Builder 4, Centura Team Developer (formerly Gupta SQL/Windows),
ColdFusion (on Solaris and NT with svc pack 5), Crystal Reports,
DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes
4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32
bit, VC++, and Visual Basic.
-If you know of any other applications that work with @strong{MyODBC}, please
+If you know of any other applications that work with @code{MyODBC}, please
send mail to @email{myodbc@@lists.mysql.com} about this!
With some programs you may get an error like:
@@ -38692,8 +41542,8 @@ try to figure out why things go wrong.
@node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC
@subsection Programs Known to Work with MyODBC
-Most programs should work with @strong{MyODBC}, but for each of those
-listed below, we have tested it ourselves or received confirmation from
+Most programs should work with @code{MyODBC}, but for each of those
+listed here, we have tested it ourselves or received confirmation from
some user that it works:
@table @asis
@@ -38707,7 +41557,7 @@ To make Access work:
@item
If you are using Access 2000, you should get and install the newest
(version 2.6 or above) Microsoft MDAC (@code{Microsoft Data Access
-Components}) from @uref{http://www.microsoft.com/data}. This will fix
+Components}) from @uref{http://www.microsoft.com/data/}. This will fix
the following bug in Access: when you export data to MySQL, the
table and column names aren't specified. Another way to around this bug
is to upgrade to MyODBC Version 2.50.33 and MySQL Version
@@ -38723,19 +41573,37 @@ Note that if you are using MySQL Version 3.22, you must to apply the
MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around
this problem.
@item
-Set the ``Return matching rows'' MyODBC option field when connecting to
-MySQL.
-@item
-You should have a primary key in the table. If not, new or updated rows
-may show up as @code{#Deleted#}.
+For all Access versions, you should enable the MyODBC option flag
+@code{Return matching rows}. For Access 2.0, you should additionally enable
+@code{Simulate ODBC 1.0}.
@item
You should have a timestamp in all tables you want to be able to update.
For maximum portability @code{TIMESTAMP(14)} or simple @code{TIMESTAMP}
is recommended instead of other @code{TIMESTAMP(X)} variations.
@item
-Only use double float fields. Access fails when comparing with single floats.
-The symptom usually is that new or updated rows may show up as @code{#Deleted#}
-or that you can't find or update rows.
+You should have a primary key in the table. If not, new or updated rows
+may show up as @code{#DELETED#}.
+@item
+Only use @code{DOUBLE} float fields. Access fails when comparing with
+single floats. The symptom usually is that new or updated rows may show
+up as @code{#DELETED#} or that you can't find or update rows.
+@item
+If you are linking a table through MyODBC, which has @code{BIGINT} as
+one of the column, then the results will be displayed as @code{#DELETED}. The
+work around solution is:
+@itemize @bullet
+@item
+Have one more dummy column with @code{TIMESTAMP} as the data type, preferably
+@code{TIMESTAMP(14)}.
+@item
+Check the @code{'Change BIGINT columns to INT'} in connection options dialog in
+ODBC DSN Administrator
+@item
+Delete the table link from access and re-create it.
+@end itemize
+
+It still displays the previous records as @code{#DELETED#}, but newly
+added/updated records will be displayed properly.
@item
If you still get the error @code{Another user has changed your data} after
adding a @code{TIMESTAMP} column, the following trick may help you:
@@ -38746,6 +41614,10 @@ set the @code{DefaultValue} property for the @code{TIMESTAMP} column to
@code{NOW()}. It may be a good idea to hide the @code{TIMESTAMP} column
from view so your users are not confused.
@item
+In some cases, Access may generate illegal SQL queries that
+MySQL can't understand. You can fix this by selecting
+@code{"Query|SQLSpecific|Pass-Through"} from the Access menu.
+@item
Access on NT will report @code{BLOB} columns as @code{OLE OBJECTS}. If
you want to have @code{MEMO} columns instead, you should change the
column to @code{TEXT} with @code{ALTER TABLE}.
@@ -38753,29 +41625,19 @@ column to @code{TEXT} with @code{ALTER TABLE}.
Access can't always handle @code{DATE} columns properly. If you have a problem
with these, change the columns to @code{DATETIME}.
@item
-In some cases, Access may generate illegal SQL queries that
-MySQL can't understand. You can fix this by selecting
-@code{"Query|SQLSpecific|Pass-Through"} from the Access menu.
-@item
-If you have in Access a column defined as BYTE, Access will try to export this
-as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. This will give you
-problems if you have values > 127 in the column!
-@item
-If you are using Access 7.0, You should use the option flag @code{Return
-matching rows}.
-@item
-If you are using Access 2.0, You should use the option flags @code{Return
-matching rows} and @code{Simulate ODBC 1.0}.
+If you have in Access a column defined as @code{BYTE}, Access will try
+to export this as @code{TINYINT} instead of @code{TINYINT UNSIGNED}.
+This will give you problems if you have values > 127 in the column!
@end itemize
@cindex ADO program
@item ADO
-When you are coding with the ADO API and @strong{MyODBC} you need to put
+When you are coding with the ADO API and @code{MyODBC} you need to put
attention in some default properties that aren't supported by the
MySQL server. For example, using the @code{CursorLocation
Property} as @code{adUseServer} will return for the @code{RecordCount
Property} a result of -1. To have the right value, you need to set this
-property to @code{adUseClient}, like is showing in the VB code below:
+property to @code{adUseClient}, like is showing in the VB code here:
@example
Dim myconn As New ADODB.Connection
@@ -38815,10 +41677,10 @@ your tables are big!
The following information is taken from the ColdFusion documentation:
Use the following information to configure ColdFusion Server for Linux
-to use the unixODBC driver with @strong{MyODBC} for MySQL data
-sources. Allaire has verified that @strong{MyODBC} Version 2.50.26
+to use the unixODBC driver with @code{MyODBC} for MySQL data
+sources. Allaire has verified that @code{MyODBC} Version 2.50.26
works with MySQL Version 3.22.27 and ColdFusion for Linux. (Any
-newer version should also work.) You can download @strong{MyODBC} at
+newer version should also work.) You can download @code{MyODBC} at
@uref{http://www.mysql.com/downloads/api-myodbc.html}
@cindex ColdFusion program
@@ -38826,10 +41688,10 @@ ColdFusion Version 4.5.1 allows you to us the ColdFusion Administrator
to add the MySQL data source. However, the driver is not
included with ColdFusion Version 4.5.1. Before the MySQL driver
will appear in the ODBC datasources drop-down list, you must build and
-copy the @strong{MyODBC} driver to
+copy the @code{MyODBC} driver to
@file{/opt/coldfusion/lib/libmyodbc.so}.
-The Contrib directory contains the program mydsn-xxx.zip which allows
+The Contrib directory contains the program @file{mydsn-xxx.zip} which allows
you to build and remove the DSN registry file for the MyODBC driver
on Coldfusion applications.
@@ -38839,7 +41701,7 @@ You have to change it to output @code{VARCHAR} rather than @code{ENUM}, as
it exports the latter in a manner that causes MySQL grief.
@cindex Excel
@item Excel
-Works. Some tips:
+Works. A few tips:
@itemize @bullet
@item
If you have problems with dates, try to select them as strings using the
@@ -38848,7 +41710,7 @@ If you have problems with dates, try to select them as strings using the
select CONCAT(rise_time), CONCAT(set_time)
from sunrise_sunset;
@end example
-Values retrieved as strings this way should be correctly recognized
+Values retrieved as strings this way should be correctly recognised
as time values by Excel97.
The purpose of @code{CONCAT()} in this example is to fool ODBC into thinking
@@ -38872,7 +41734,7 @@ For example, create a db with a table containing 2 columns of text:
@item
Insert rows using the @code{mysql} client command-line tool.
@item
-Create a DSN file using the MyODBC driver, for example, my for the db above.
+Create a DSN file using the ODBC manager, for example, @file{my} for the db above.
@item
Open the Word application.
@item
@@ -38908,11 +41770,11 @@ Click OK and you see the rows in your Word document.
Test program for ODBC.
@cindex Delphi program
@item Delphi
-You must use BDE Version 3.2 or newer. Set the `Don't optimize column width'
+You must use BDE Version 3.2 or newer. Set the @code{Don't optimize column width}
option field when connecting to MySQL.
Also, here is some potentially useful Delphi code that sets up both an
-ODBC entry and a BDE entry for @strong{MyODBC} (the BDE entry requires a BDE
+ODBC entry and a BDE entry for @code{MyODBC} (the BDE entry requires a BDE
Alias Editor that is free at a Delphi Super Page near
you. (Thanks to Bryan Brunton @email{bryan@@flesherfab.com} for this):
@@ -38957,7 +41819,7 @@ fReg:= TRegistry.Create;
@item C++ Builder
Tested with BDE Version 3.0. The only known problem is that when the table
schema changes, query fields are not updated. BDE, however, does not seem
-to recognize primary keys, only the index PRIMARY, though this has not
+to recognise primary keys, only the index PRIMARY, though this has not
been a problem.
@item Vision
@@ -39021,28 +41883,28 @@ SELECT * FROM tbl_name WHERE auto IS NULL;
@cindex problems, ODBC
@cindex MyODBC, reporting problems
-If you encounter difficulties with @strong{MyODBC}, you should start by
+If you encounter difficulties with @code{MyODBC}, you should start by
making a log file from the ODBC manager (the log you get when requesting
-logs from ODBCADMIN) and a @strong{MyODBC} log.
+logs from ODBCADMIN) and a @code{MyODBC} log.
-To get a @strong{MyODBC} log, you need to do the following:
+To get a @code{MyODBC} log, you need to do the following:
@enumerate
@item
-Ensure that you are using @code{myodbcd.dll} and not @code{myodbc.dll}.
-The easiest way to do this is to get @code{myodbcd.dll} from the MyODBC
-distribution and copy it over the @code{myodbc.dll}, which is probably
-in your @code{C:\windows\system32} or @code{C:\winnt\system32} directory.
+Ensure that you are using @file{myodbcd.dll} and not @file{myodbc.dll}.
+The easiest way to do this is to get @file{myodbcd.dll} from the MyODBC
+distribution and copy it over the @file{myodbc.dll}, which is probably
+in your @file{C:\windows\system32} or @file{C:\winnt\system32} directory.
Note that you probably want to restore the old myodbc.dll file when you
-have finished testing, as this is a lot faster than @code{myodbcd.dll}.
+have finished testing, as this is a lot faster than @file{myodbcd.dll}.
@item
-Tag the `Trace MyODBC' option flag in the @strong{MyODBC} connect/configure
+Tag the `Trace MyODBC' option flag in the @code{MyODBC} connect/configure
screen. The log will be written to file @file{C:\myodbc.log}.
If the trace option is not remembered when you are going back to the
above screen, it means that you are not using the @code{myodbcd.dll}
-driver (see above).
+driver (see the item above).
@item
Start your application and try to get it to fail.
@end enumerate
@@ -39061,7 +41923,7 @@ send the whole MyODBC or ODBC log file!
If you are unable to find out what's wrong, the last option is to
make an archive (tar or zip) that contains a MyODBC trace file, the ODBC
log file, and a README file that explains the problem. You can send this
-to @uref{ftp://support.mysql.com/pub/mysql/secret}. Only we at
+to @uref{ftp://support.mysql.com/pub/mysql/secret/}. Only we at
MySQL AB will have access to the files you upload, and we will
be very discrete with the data!
@@ -39085,10 +41947,12 @@ likely it is that we can fix the problem!
* C API datatypes:: C API Datatypes
* C API function overview:: C API Function Overview
* C API functions:: C API Function Descriptions
-* C Thread functions::
+* C Thread functions:: C Thread Functions
+* C Embedded Server func:: C Embedded Server Function Descriptions
* C API problems:: Common questions and problems when using the C API
* Building clients:: Building Client Programs
* Threaded clients:: How to Make a Threaded Client
+* libmysqld:: libmysqld, the Embedded MySQL Server Library
@end menu
The C API code is distributed with MySQL. It is included in the
@@ -39128,8 +41992,10 @@ The MySQL server shrinks each communication buffer to
the buffer associated with a connection is not decreased until the connection
is closed, at which time client memory is reclaimed.
-For programming with threads, consult the 'how to make a thread-safe
-client' chapter. @xref{Threaded clients}.
+For programming with threads, see @ref{Threaded clients}.
+For creating a stand-alone application which includes the
+"server" and "client" in the same program (and does not
+communicate with an external MySQL server), see @ref{libmysqld}.
@node C API datatypes, C API function overview, C, C
@@ -39159,7 +42025,7 @@ values may contain null bytes internally.) Rows are obtained by calling
@tindex MYSQL_FIELD C type
@item MYSQL_FIELD
This structure contains information about a field, such as the field's
-name, type, and size. Its members are described in more detail below.
+name, type, and size. Its members are described in more detail here.
You may obtain the @code{MYSQL_FIELD} structures for each field by
calling @code{mysql_fetch_field()} repeatedly. Field values are not part of
this structure; they are contained in a @code{MYSQL_ROW} structure.
@@ -39187,7 +42053,7 @@ printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));
@end table
@noindent
-The @code{MYSQL_FIELD} structure contains the members listed below:
+The @code{MYSQL_FIELD} structure contains the members listed here:
@table @code
@item char * name
@@ -39205,8 +42071,8 @@ only if you use @code{mysql_list_fields()}.
The type of the field.
The @code{type} value may be one of the following:
-@multitable @columnfractions .3 .55
-@item @strong{Type value} @tab @strong{Type meaning}
+@multitable @columnfractions .35 .55
+@item @strong{Type value} @tab @strong{Type description}
@item @code{FIELD_TYPE_TINY} @tab @code{TINYINT} field
@item @code{FIELD_TYPE_SHORT} @tab @code{SMALLINT} field
@item @code{FIELD_TYPE_LONG} @tab @code{INTEGER} field
@@ -39228,7 +42094,7 @@ The @code{type} value may be one of the following:
@item @code{FIELD_TYPE_CHAR} @tab Deprecated; use @code{FIELD_TYPE_TINY} instead
@end multitable
-You can use the @code{IS_NUM()} macro to test whether or not a field has a
+You can use the @code{IS_NUM()} macro to test whether a field has a
numeric type. Pass the @code{type} value to @code{IS_NUM()} and it
will evaluate to TRUE if the field is numeric:
@@ -39251,8 +42117,8 @@ value of this variable is zero.
Different bit-flags for the field. The @code{flags} value may have zero
or more of the following bits set:
-@multitable @columnfractions .3 .55
-@item @strong{Flag value} @tab @strong{Flag meaning}
+@multitable @columnfractions .35 .55
+@item @strong{Flag value} @tab @strong{Flag description}
@item @code{NOT_NULL_FLAG} @tab Field can't be @code{NULL}
@item @code{PRI_KEY_FLAG} @tab Field is part of a primary key
@item @code{UNIQUE_KEY_FLAG} @tab Field is part of a unique key
@@ -39263,18 +42129,19 @@ or more of the following bits set:
@item @code{AUTO_INCREMENT_FLAG} @tab Field has the @code{AUTO_INCREMENT}
attribute
@item @code{ENUM_FLAG} @tab Field is an @code{ENUM} (deprecated)
+@item @code{SET_FLAG} @tab Field is a @code{SET} (deprecated)
@item @code{BLOB_FLAG} @tab Field is a @code{BLOB} or @code{TEXT} (deprecated)
@item @code{TIMESTAMP_FLAG} @tab Field is a @code{TIMESTAMP} (deprecated)
@end multitable
-Use of the @code{BLOB_FLAG}, @code{ENUM_FLAG}, and @code{TIMESTAMP_FLAG}
-flags is deprecated because they indicate the type of a field rather
-than an attribute of its type. It is preferable to test
-@code{field->type} against @code{FIELD_TYPE_BLOB},
-@code{FIELD_TYPE_ENUM}, or @code{FIELD_TYPE_TIMESTAMP} instead.
+Use of the @code{BLOB_FLAG}, @code{ENUM_FLAG}, @code{SET_FLAG}, and
+@code{TIMESTAMP_FLAG} flags is deprecated because they indicate the type of
+a field rather than an attribute of its type. It is preferable to test
+@code{field->type} against @code{FIELD_TYPE_BLOB}, @code{FIELD_TYPE_ENUM},
+@code{FIELD_TYPE_SET}, or @code{FIELD_TYPE_TIMESTAMP} instead.
@noindent
-The example below illustrates a typical use of the @code{flags} value:
+The following example illustrates a typical use of the @code{flags} value:
@example
if (field->flags & NOT_NULL_FLAG)
@@ -39284,7 +42151,8 @@ if (field->flags & NOT_NULL_FLAG)
You may use the following convenience macros to determine the boolean
status of the @code{flags} value:
-@multitable @columnfractions .3 .5
+@multitable @columnfractions .25 .55
+@item @strong{Flag status} @tab @strong{Description}
@item @code{IS_NOT_NULL(flags)} @tab True if this field is defined as @code{NOT NULL}
@item @code{IS_PRI_KEY(flags)} @tab True if this field is a primary key
@item @code{IS_BLOB(flags)} @tab True if this field is a @code{BLOB} or @code{TEXT} (deprecated; test @code{field->type} instead)
@@ -39301,15 +42169,23 @@ The number of decimals for numeric fields.
@cindex C API, functions
@cindex functions, C API
-The functions available in the C API are listed below and are described in
-greater detail in the next section.
+The functions available in the C API are listed here and are described in
+greater detail in a later section.
@xref{C API functions}.
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .32 .68
+@item @strong{Function} @tab @strong{Description}
+
@item @strong{mysql_affected_rows()} @tab
Returns the number of rows changed/deleted/inserted by the last @code{UPDATE},
@code{DELETE}, or @code{INSERT} query.
+@item @strong{mysql_change_user()} @tab
+Changes user and database on an open connection.
+
+@item @strong{mysql_character_set_name()} @tab
+Returns the name of the default character set for the connection.
+
@item @strong{mysql_close()} @tab
Closes a server connection.
@@ -39317,12 +42193,6 @@ Closes a server connection.
Connects to a MySQL server. This function is deprecated; use
@code{mysql_real_connect()} instead.
-@item @strong{mysql_change_user()} @tab
-Changes user and database on an open connection.
-
-@item @strong{mysql_character_set_name()} @tab
-Returns the name of the default character set for the connection.
-
@item @strong{mysql_create_db()} @tab
Creates a database. This function is deprecated; use the SQL command
@code{CREATE DATABASE} instead.
@@ -39341,7 +42211,7 @@ Drops a database. This function is deprecated; use the SQL command
Makes the server write debug information to the log.
@item @strong{mysql_eof()} @tab
-Determines whether or not the last row of a result set has been read.
+Determines whether the last row of a result set has been read.
This function is deprecated; @code{mysql_errno()} or @code{mysql_error()}
may be used instead.
@@ -39351,10 +42221,6 @@ Returns the error number for the most recently invoked MySQL function.
@item @strong{mysql_error()} @tab
Returns the error message for the most recently invoked MySQL function.
-@item @strong{mysql_real_escape_string()} @tab
-Escapes special characters in a string for use in a SQL statement taking
-into account the current charset of the connection.
-
@item @strong{mysql_escape_string()} @tab
Escapes special characters in a string for use in a SQL statement.
@@ -39402,7 +42268,7 @@ Returns the server version number.
Returns information about the most recently executed query.
@item @strong{mysql_init()} @tab
-Gets or initializes a @code{MYSQL} structure.
+Gets or initialises a @code{MYSQL} structure.
@item @strong{mysql_insert_id()} @tab
Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous
@@ -39433,7 +42299,7 @@ Returns the number of rows in a result set.
Sets connect options for @code{mysql_connect()}.
@item @strong{mysql_ping()} @tab
-Checks whether or not the connection to the server is working, reconnecting
+Checks whether the connection to the server is working, reconnecting
as necessary.
@item @strong{mysql_query()} @tab
@@ -39442,6 +42308,10 @@ Executes a SQL query specified as a null-terminated string.
@item @strong{mysql_real_connect()} @tab
Connects to a MySQL server.
+@item @strong{mysql_real_escape_string()} @tab
+Escapes special characters in a string for use in a SQL statement, taking
+into account the current charset of the connection.
+
@item @strong{mysql_real_query()} @tab
Executes a SQL query specified as a counted string.
@@ -39470,14 +42340,14 @@ Retrieves a complete result set to the client.
@item @strong{mysql_thread_id()} @tab
Returns the current thread ID.
-@item @strong{mysql_thread_save()} @tab
+@item @strong{mysql_thread_safe()} @tab
Returns 1 if the clients are compiled as thread-safe.
@item @strong{mysql_use_result()} @tab
Initiates a row-by-row result set retrieval.
@end multitable
-To connect to the server, call @code{mysql_init()} to initialize a
+To connect to the server, call @code{mysql_init()} to initialise a
connection handler, then call @code{mysql_real_connect()} with that
handler (along with other information such as the hostname, user name,
and password). Upon connection, @code{mysql_real_connect()} sets the
@@ -39508,7 +42378,7 @@ retrieve the entire result set all at once by calling
@code{mysql_store_result()}. This function acquires from the server all the
rows returned by the query and stores them in the client. The second way is
for the client to initiate a row-by-row result set retrieval by calling
-@code{mysql_use_result()}. This function initializes the retrieval, but does
+@code{mysql_use_result()}. This function initialises the retrieval, but does
not actually get any rows from the server.
In both cases, you access rows by calling @code{mysql_fetch_row()}. With
@@ -39542,7 +42412,7 @@ faster). Disadvantages are that you must process each row quickly to avoid
tying up the server, you don't have random access to rows within the result
set (you can only access rows sequentially), and you don't know how many rows
are in the result set until you have retrieved them all. Furthermore, you
-@emph{must} retrieve all the rows even if you determine in mid-retrieval that
+@strong{must} retrieve all the rows even if you determine in mid-retrieval that
you've found the information you were looking for.
The API makes it possible for clients to respond appropriately to
@@ -39551,7 +42421,7 @@ not the query is a @code{SELECT}. You can do this by calling
@code{mysql_store_result()} after each @code{mysql_query()} (or
@code{mysql_real_query()}). If the result set call succeeds, the query
was a @code{SELECT} and you can read the rows. If the result set call
-fails, call @code{mysql_field_count()} to determine whether or not a
+fails, call @code{mysql_field_count()} to determine whether a
result was actually to be expected. If @code{mysql_field_count()}
returns zero, the query returned no data (indicating that it was an
@code{INSERT}, @code{UPDATE}, @code{DELETE}, etc.), and was not
@@ -39582,10 +42452,10 @@ when an error occurred and what it was.
@menu
* mysql_affected_rows:: @code{mysql_affected_rows()}
-* mysql_close:: @code{mysql_close()}
-* mysql_connect:: @code{mysql_connect()}
* mysql_change_user:: @code{mysql_change_user()}
* mysql_character_set_name:: @code{mysql_character_set_name()}
+* mysql_close:: @code{mysql_close()}
+* mysql_connect:: @code{mysql_connect()}
* mysql_create_db:: @code{mysql_create_db()}
* mysql_data_seek:: @code{mysql_data_seek()}
* mysql_debug:: @code{mysql_debug()}
@@ -39635,7 +42505,7 @@ when an error occurred and what it was.
* mysql_use_result:: @code{mysql_use_result()}
@end menu
-In the descriptions below, a parameter or return value of @code{NULL} means
+In the descriptions here, a parameter or return value of @code{NULL} means
@code{NULL} in the sense of the C programming language, not a
MySQL @code{NULL} value.
@@ -39665,7 +42535,7 @@ A string representation of the error may be obtained by calling
@code{mysql_error()}.
-@node mysql_affected_rows, mysql_close, C API functions, C API functions
+@node mysql_affected_rows, mysql_change_user, C API functions, C API functions
@subsubsection @code{mysql_affected_rows()}
@findex @code{mysql_affected_rows()}
@@ -39712,63 +42582,7 @@ old row. This is because in this case one row was inserted and then the
duplicate was deleted.
-@node mysql_close, mysql_connect, mysql_affected_rows, C API functions
-@subsubsection @code{mysql_close()}
-
-@findex @code{mysql_close()}
-
-@code{void mysql_close(MYSQL *mysql)}
-
-@subsubheading Description
-Closes a previously opened connection. @code{mysql_close()} also deallocates
-the connection handle pointed to by @code{mysql} if the handle was allocated
-automatically by @code{mysql_init()} or @code{mysql_connect()}.
-
-@subsubheading Return Values
-
-None.
-
-@subsubheading Errors
-
-None.
-
-
-@node mysql_connect, mysql_change_user, mysql_close, C API functions
-@subsubsection @code{mysql_connect()}
-
-@findex @code{mysql_connect()}
-
-@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)}
-
-@subsubheading Description
-
-This function is deprecated. It is preferable to use
-@code{mysql_real_connect()} instead.
-
-@code{mysql_connect()} attempts to establish a connection to a MySQL
-database engine running on @code{host}. @code{mysql_connect()} must complete
-successfully before you can execute any of the other API functions, with the
-exception of @code{mysql_get_client_info()}.
-
-The meanings of the parameters are the same as for the corresponding
-parameters for @code{mysql_real_connect()} with the difference that the
-connection parameter may be @code{NULL}. In this case the C API
-allocates memory for the connection structure automatically and frees it
-when you call @code{mysql_close()}. The disadvantage of this approach is
-that you can't retrieve an error message if the connection fails. (To
-get error information from @code{mysql_errno()} or @code{mysql_error()},
-you must provide a valid @code{MYSQL} pointer.)
-
-@subsubheading Return Values
-
-Same as for @code{mysql_real_connect()}.
-
-@subsubheading Errors
-
-Same as for @code{mysql_real_connect()}.
-
-
-@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions
+@node mysql_change_user, mysql_character_set_name, mysql_affected_rows, C API functions
@subsubsection @code{mysql_change_user()}
@findex @code{mysql_change_user()}
@@ -39792,7 +42606,7 @@ this case the user and database are not changed
The @code{db} parameter may be set to @code{NULL} if you don't want to have a
default database.
-@subsubheading Return values
+@subsubheading Return Values
Zero for success. Non-zero if an error occurred.
@@ -39832,7 +42646,7 @@ if (mysql_change_user(&mysql, "user", "password", "new_database"))
@end example
-@node mysql_character_set_name, mysql_create_db, mysql_change_user, C API functions
+@node mysql_character_set_name, mysql_close, mysql_change_user, C API functions
@subsubsection @code{mysql_character_set_name()}
@findex @code{mysql_character_set_name()}
@@ -39851,7 +42665,63 @@ The default character set
None.
-@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions
+@node mysql_close, mysql_connect, mysql_character_set_name, C API functions
+@subsubsection @code{mysql_close()}
+
+@findex @code{mysql_close()}
+
+@code{void mysql_close(MYSQL *mysql)}
+
+@subsubheading Description
+Closes a previously opened connection. @code{mysql_close()} also deallocates
+the connection handle pointed to by @code{mysql} if the handle was allocated
+automatically by @code{mysql_init()} or @code{mysql_connect()}.
+
+@subsubheading Return Values
+
+None.
+
+@subsubheading Errors
+
+None.
+
+
+@node mysql_connect, mysql_create_db, mysql_close, C API functions
+@subsubsection @code{mysql_connect()}
+
+@findex @code{mysql_connect()}
+
+@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)}
+
+@subsubheading Description
+
+This function is deprecated. It is preferable to use
+@code{mysql_real_connect()} instead.
+
+@code{mysql_connect()} attempts to establish a connection to a MySQL
+database engine running on @code{host}. @code{mysql_connect()} must complete
+successfully before you can execute any of the other API functions, with the
+exception of @code{mysql_get_client_info()}.
+
+The meanings of the parameters are the same as for the corresponding
+parameters for @code{mysql_real_connect()} with the difference that the
+connection parameter may be @code{NULL}. In this case the C API
+allocates memory for the connection structure automatically and frees it
+when you call @code{mysql_close()}. The disadvantage of this approach is
+that you can't retrieve an error message if the connection fails. (To
+get error information from @code{mysql_errno()} or @code{mysql_error()},
+you must provide a valid @code{MYSQL} pointer.)
+
+@subsubheading Return Values
+
+Same as for @code{mysql_real_connect()}.
+
+@subsubheading Errors
+
+Same as for @code{mysql_real_connect()}.
+
+
+@node mysql_create_db, mysql_data_seek, mysql_connect, C API functions
@subsubsection @code{mysql_create_db()}
@findex @code{mysql_create_db()}
@@ -39901,7 +42771,7 @@ if(mysql_create_db(&mysql, "my_database"))
@findex @code{mysql_data_seek()}
-@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)}
+@code{void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)}
@subsubheading Description
Seeks to an arbitrary row in a query result set. This requires that the
@@ -39925,7 +42795,7 @@ None.
@findex @code{mysql_debug()}
-@code{void mysql_debug(char *debug)}
+@code{void mysql_debug(const char *debug)}
@subsubheading Description
Does a @code{DBUG_PUSH} with the given string. @code{mysql_debug()} uses the
@@ -39942,7 +42812,7 @@ None.
@subsubheading Example
-The call shown below causes the client library to generate a trace file in
+The call shown here causes the client library to generate a trace file in
@file{/tmp/client.trace} on the client machine:
@example
@@ -39999,10 +42869,10 @@ if(mysql_drop_db(&mysql, "my_database"))
@subsubheading Description
-Instructs the server to write some debug information to the log. The
-connected user must have the @strong{process} privilege for this to work.
+Instructs the server to write some debug information to the log. For
+this to work, the connected user must have the @code{SUPER} privilege.
-@subsubheading Return values
+@subsubheading Return Values
Zero if the command was successful. Non-zero if an error occurred.
@@ -40031,14 +42901,16 @@ An unknown error occurred.
This function is deprecated. @code{mysql_errno()} or @code{mysql_error()}
may be used instead.
-@code{mysql_eof()} determines whether or not the last row of a result
+@code{mysql_eof()} determines whether the last row of a result
set has been read.
If you acquire a result set from a successful call to
@code{mysql_store_result()}, the client receives the entire set in one
-operation. In this case, a @code{NULL} return from @code{mysql_fetch_row()}
-always means the end of the result set has been reached and it is
-unnecessary to call @code{mysql_eof()}.
+operation. In this case, a @code{NULL} return from
+@code{mysql_fetch_row()} always means the end of the result set has been
+reached and it is unnecessary to call @code{mysql_eof()}. When used
+with @code{mysql_store_result()}, @code{mysql_eof()} will always return
+true.
On the other hand, if you use @code{mysql_use_result()} to initiate a result
set retrieval, the rows of the set are obtained from the server one by one as
@@ -40170,12 +43042,11 @@ None.
You should use @code{mysql_real_escape_string()} instead!
-This is identical to @code{mysql_real_escape_string()} except that it
-takes the connection as the first
-argument. @code{mysql_real_escape_string()} will escape the string
-according to the current character set while
-@code{mysql_escape_string()} does not respect the current charset
-setting.
+This function is identical to @code{mysql_real_escape_string()} except
+that @code{mysql_real_escape_string()} takes a connection handler as
+its first argument and escapes the string according to the current
+character set. @code{mysql_escape_string()} does not take a connection
+argument and does not respect the current charset setting.
@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions
@@ -40311,8 +43182,8 @@ for(i = 0; i < num_fields; i++)
Returns the lengths of the columns of the current row within a result set.
If you plan to copy field values, this length information is also useful for
-optimization, because you can avoid calling @code{strlen()}. In addition, if
-the result set contains binary data, you @emph{must} use this function to
+optimisation, because you can avoid calling @code{strlen()}. In addition, if
+the result set contains binary data, you @strong{must} use this function to
determine the size of the data, because @code{strlen()} returns incorrect
results for any field containing null characters.
@@ -40377,7 +43248,7 @@ The lengths of the field values in the row may be obtained by calling
@code{mysql_fetch_lengths()}. Empty fields and fields containing
@code{NULL} both have length 0; you can distinguish these by checking
the pointer for the field value. If the pointer is @code{NULL}, the field
-is @code{NULL}; otherwise the field is empty.
+is @code{NULL}; otherwise, the field is empty.
@subsubheading Return Values
@@ -40431,10 +43302,10 @@ Returns the number of columns for the most recent query on the connection.
The normal use of this function is when @code{mysql_store_result()}
returned @code{NULL} (and thus you have no result set pointer).
In this case, you can call @code{mysql_field_count()} to
-determine whether or not @code{mysql_store_result()} should have produced a
+determine whether @code{mysql_store_result()} should have produced a
non-empty result. This allows the client program to take proper action
-without knowing whether or not the query was a @code{SELECT} (or
-@code{SELECT}-like) statement. The example shown below illustrates how this
+without knowing whether the query was a @code{SELECT} (or
+@code{SELECT}-like) statement. The example shown here illustrates how this
may be done.
@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.
@@ -40484,7 +43355,7 @@ else // query succeeded, process any data returned by it
An alternative is to replace the @code{mysql_field_count(&mysql)} call with
@code{mysql_errno(&mysql)}. In this case, you are checking directly for an
error from @code{mysql_store_result()} rather than inferring from the value
-of @code{mysql_field_count()} whether or not the statement was a
+of @code{mysql_field_count()} whether the statement was a
@code{SELECT}.
@@ -40495,7 +43366,6 @@ of @code{mysql_field_count()} whether or not the statement was a
@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)}
-* Threaded clients:: How to Make a Threaded Client
@subsubheading Description
Sets the field cursor to the given offset. The next call to
@@ -40643,9 +43513,9 @@ None.
@subsubheading Description
Retrieves a string providing information about the most recently executed
-query, but only for the statements listed below. For other statements,
+query, but only for the statements listed here. For other statements,
@code{mysql_info()} returns @code{NULL}. The format of the string varies
-depending on the type of query, as described below. The numbers are
+depending on the type of query, as described here. The numbers are
illustrative only; the string will contain values appropriate for the query.
@table @code
@@ -40684,16 +43554,16 @@ None.
@subsubheading Description
-Allocates or initializes a @code{MYSQL} object suitable for
+Allocates or initialises a @code{MYSQL} object suitable for
@code{mysql_real_connect()}. If @code{mysql} is a @code{NULL} pointer, the
-function allocates, initializes, and returns a new object. Otherwise the
-object is initialized and the address of the object is returned. If
+function allocates, initialises, and returns a new object. Otherwise, the
+object is initialised and the address of the object is returned. If
@code{mysql_init()} allocates a new object, it will be freed when
@code{mysql_close()} is called to close the connection.
@subsubheading Return Values
-An initialized @code{MYSQL*} handle. @code{NULL} if there was
+An initialised @code{MYSQL*} handle. @code{NULL} if there was
insufficient memory to allocate a new object.
@subsubheading Errors
@@ -40778,7 +43648,7 @@ An unknown error occurred.
Returns a result set consisting of database names on the server that match
the simple regular expression specified by the @code{wild} parameter.
-@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may
+@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all databases. Calling
@code{mysql_list_dbs()} is similar to executing the query @code{SHOW
databases [LIKE wild]}.
@@ -40816,7 +43686,7 @@ An unknown error occurred.
Returns a result set consisting of field names in the given table that match
the simple regular expression specified by the @code{wild} parameter.
-@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may
+@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all fields. Calling
@code{mysql_list_fields()} is similar to executing the query @code{SHOW
COLUMNS FROM tbl_name [LIKE wild]}.
@@ -40888,7 +43758,7 @@ An unknown error occurred.
Returns a result set consisting of table names in the current database that
match the simple regular expression specified by the @code{wild} parameter.
-@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may
+@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all tables. Calling
@code{mysql_list_tables()} is similar to executing the query @code{SHOW
tables [LIKE wild]}.
@@ -40937,11 +43807,11 @@ Note that you can get the number of columns either from a pointer to a result
set or to a connection handle. You would use the connection handle if
@code{mysql_store_result()} or @code{mysql_use_result()} returned
@code{NULL} (and thus you have no result set pointer). In this case, you can
-call @code{mysql_field_count()} to determine whether or not
+call @code{mysql_field_count()} to determine whether
@code{mysql_store_result()} should have produced a non-empty result. This
allows the client program to take proper action without knowing whether or
not the query was a @code{SELECT} (or @code{SELECT}-like) statement. The
-example shown below illustrates how this may be done.
+example shown here illustrates how this may be done.
@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.
@@ -40987,7 +43857,7 @@ else // query succeeded, process any data returned by it
@}
@end example
-An alternative (if you KNOW that your query should have returned a result set)
+An alternative (if you know that your query should have returned a result set)
is to replace the @code{mysql_errno(&mysql)} call with a check if
@code{mysql_field_count(&mysql)} is = 0. This will only happen if something
went wrong.
@@ -41028,7 +43898,7 @@ None.
@subsubheading Description
-Can be used to set extra connect options and affect behavior for a connection.
+Can be used to set extra connect options and affect behaviour for a connection.
This function may be called multiple times to set several options.
@code{mysql_options()} should be called after @code{mysql_init()} and before
@@ -41040,10 +43910,11 @@ argument is the value for the option. If the option is an integer, then
Possible options values:
-@multitable @columnfractions .25 .25 .5
+@multitable @columnfractions .42 .20 .38
@item @strong{Option} @tab @strong{Argument type} @tab @strong{Function}
@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Connect timeout in seconds.
@item @code{MYSQL_OPT_COMPRESS} @tab Not used @tab Use the compressed client/server protocol.
+@item @code{MYSQL_OPT_LOCAL_INFILE} @tab optional pointer to uint @tab If no pointer is given or if pointer points to an @code{unsigned int != 0} the command @code{LOAD LOCAL INFILE} is enabled.
@item @code{MYSQL_OPT_NAMED_PIPE} @tab Not used @tab Use named pipes to connect to a MySQL server on NT.
@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Command to execute when connecting to the MySQL server. Will automatically be re-executed when reconnecting.
@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Read options from the named option file instead of from @file{my.cnf}.
@@ -41055,24 +43926,26 @@ Note that the group @code{client} is always read if you use
The specified group in the option file may contain the following options:
-@multitable @columnfractions .3 .7
-@item @code{connect_timeout} @tab Connect timeout in seconds. On Linux this timeout is also used for waiting for the first answer from the server.
+@multitable @columnfractions .25 .60
+@item @strong{Option} @tab @strong{Description}
+@item @code{connect-timeout} @tab Connect timeout in seconds. On Linux this timeout is also used for waiting for the first answer from the server.
@item @code{compress} @tab Use the compressed client/server protocol.
@item @code{database} @tab Connect to this database if no database was specified in the connect command.
@item @code{debug} @tab Debug options.
+@item @code{disable-local-infile} @tab Disable use of @code{LOAD DATA LOCAL}.
@item @code{host} @tab Default host name.
@item @code{init-command} @tab Command to execute when connecting to MySQL server. Will automatically be re-executed when reconnecting.
@item @code{interactive-timeout} @tab Same as specifying @code{CLIENT_INTERACTIVE} to @code{mysql_real_connect()}. @xref{mysql_real_connect}.
+@item @code{local-infile[=(0|1)]} @tab If no argument or argument != 0 then enable use of @code{LOAD DATA LOCAL}.
@item @code{password} @tab Default password.
@item @code{pipe} @tab Use named pipes to connect to a MySQL server on NT.
@item @code{port} @tab Default port number.
@item @code{return-found-rows} @tab Tell @code{mysql_info()} to return found rows instead of updated rows when using @code{UPDATE}.
@item @code{socket} @tab Default socket number.
-@item
@item @code{user} @tab Default user.
@end multitable
-Note that @code{timeout} has been replaced by @code{connect_timeout}, but
+Note that @code{timeout} has been replaced by @code{connect-timeout}, but
@code{timeout} will still work for a while.
For more information about option files, see @ref{Option files}.
@@ -41097,7 +43970,7 @@ if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
@end example
The above requests the client to use the compressed client/server protocol and
-read the additional options from the @code{odbc} section in the @code{my.cnf}
+read the additional options from the @code{odbc} section in the @file{my.cnf}
file.
@@ -41110,11 +43983,11 @@ file.
@subsubheading Description
-Checks whether or not the connection to the server is working. If it has gone
+Checks whether the connection to the server is working. If it has gone
down, an automatic reconnection is attempted.
This function can be used by clients that remain idle for a long while,
-to check whether or not the server has closed the connection and reconnect
+to check whether the server has closed the connection and reconnect
if necessary.
@subsubheading Return Values
@@ -41152,7 +44025,7 @@ query string.)
If you want to know if the query should return a result set or not, you can
use @code{mysql_field_count()} to check for this.
-@xref{mysql_field_count, , @code{mysql_field_count}}.
+@xref{mysql_field_count, , @code{mysql_field_count()}}.
@subsubheading Return Values
@@ -41178,9 +44051,9 @@ An unknown error occurred.
@findex @code{mysql_real_connect()}
@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
- const char *user, const char *passwd, const char *db,
- unsigned int port, const char *unix_socket,
- unsigned int client_flag)}
+ const char *user, const char *passwd, const char *db,
+ unsigned int port, const char *unix_socket,
+ unsigned int client_flag)}
@subsubheading Description
@@ -41196,9 +44069,9 @@ The parameters are specified as follows:
@item
The first parameter should be the address of an existing @code{MYSQL}
structure. Before calling @code{mysql_real_connect()} you must call
-@code{mysql_init()} to initialize the @code{MYSQL} structure. You can
+@code{mysql_init()} to initialise the @code{MYSQL} structure. You can
change a lot of connect options with the @code{mysql_options()}
-call. @xref{mysql_options}.
+call. @xref{mysql_options, @code{mysql_options()}}.
@item
The value of @code{host} may be either a hostname or an IP address. If
@@ -41221,7 +44094,7 @@ allows the database administrator to set up the MySQL privilege
system in such a way that users get different privileges depending on whether
or not they have specified a password.
-NOTE: Do not attempt to encrypt the password before calling
+Note: Do not attempt to encrypt the password before calling
@code{mysql_real_connect()}; password encryption is handled automatically by
the client API.
@@ -41244,15 +44117,14 @@ parameter determines the type of the connection.
The value of @code{client_flag} is usually 0, but can be set to a combination
of the following flags in very special circumstances:
-@multitable @columnfractions .25 .7
-@item @strong{Flag name} @tab @strong{Flag meaning}
-@code{mysqld} to be more ODBC-friendly.
+@multitable @columnfractions .30 .65
+@item @strong{Flag name} @tab @strong{Flag description}
@item @code{CLIENT_COMPRESS} @tab Use compression protocol.
@item @code{CLIENT_FOUND_ROWS} @tab Return the number of found (matched) rows, not the number of affected rows.
@item @code{CLIENT_IGNORE_SPACE} @tab Allow spaces after function names. Makes all functions names reserved words.
@item @code{CLIENT_INTERACTIVE} @tab Allow @code{interactive_timeout} seconds (instead of @code{wait_timeout} seconds) of inactivity before closing the connection.
@item @code{CLIENT_NO_SCHEMA} @tab Don't allow the @code{db_name.tbl_name.col_name} syntax. This is for ODBC. It causes the parser to generate an error if you use that syntax, which is useful for trapping bugs in some ODBC programs.
-@item @code{CLIENT_ODBC} @tab The client is an ODBC client. This changes
+@item @code{CLIENT_ODBC} @tab The client is an ODBC client. This changes @code{mysqld} to be more ODBC-friendly.
@item @code{CLIENT_SSL} @tab Use SSL (encrypted protocol).
@end multitable
@end itemize
@@ -41321,7 +44193,7 @@ if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
@end example
By using @code{mysql_options()} the MySQL library will read the
-@code{[client]} and @code{your_prog_name} sections in the @code{my.cnf}
+@code{[client]} and @code{your_prog_name} sections in the @file{my.cnf}
file which will ensure that your program will work, even if someone has
set up MySQL in some non-standard way.
@@ -41336,7 +44208,7 @@ try reconnecting to the server before giving up.
@findex @code{mysql_real_escape_string()}
-@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)}
+@code{unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)}
@subsubheading Description
@@ -41397,7 +44269,7 @@ None.
@findex @code{mysql_real_query()}
-@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)}
+@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)}
@subsubheading Description
@@ -41406,7 +44278,7 @@ Executes the SQL query pointed to by @code{query}, which should be a string
You should not add a terminating semicolon (@samp{;}) or @code{\g} to the
statement.
-You @emph{must} use @code{mysql_real_query()} rather than
+You @strong{must} use @code{mysql_real_query()} rather than
@code{mysql_query()} for queries that contain binary data, because binary data
may contain the @samp{\0} character. In addition, @code{mysql_real_query()}
is faster than @code{mysql_query()} because it does not call @code{strlen()} on
@@ -41414,7 +44286,7 @@ the query string.
If you want to know if the query should return a result set or not, you can
use @code{mysql_field_count()} to check for this.
-@xref{mysql_field_count, @code{mysql_field_count}}.
+@xref{mysql_field_count, @code{mysql_field_count()}}.
@subsubheading Return Values
@@ -41444,7 +44316,7 @@ An unknown error occurred.
@subsubheading Description
Asks the MySQL server to reload the grant tables. The
-connected user must have the @strong{reload} privilege.
+connected user must have the @code{RELOAD} privilege.
This function is deprecated. It is preferable to use @code{mysql_query()}
to issue a SQL @code{FLUSH PRIVILEGES} statement instead.
@@ -41563,7 +44435,7 @@ An unknown error occurred.
@subsubheading Description
Asks the database server to shut down. The connected user must have
-@strong{shutdown} privileges.
+@code{SHUTDOWN} privileges.
@subsubheading Return Values
@@ -41636,16 +44508,16 @@ checking if @code{mysql_store_result()} returns 0 (more about this later one).
If you want to know if the query should return a result set or not, you can
use @code{mysql_field_count()} to check for this.
-@xref{mysql_field_count, @code{mysql_field_count}}.
+@xref{mysql_field_count, @code{mysql_field_count()}}.
@code{mysql_store_result()} reads the entire result of a query to the client,
allocates a @code{MYSQL_RES} structure, and places the result into this
structure.
-@code{mysql_store_results()} returns a null pointer if the query didn't return
+@code{mysql_store_result()} returns a null pointer if the query didn't return
a result set (if the query was, for example, an @code{INSERT} statement).
-@code{mysql_store_results()} also returns a null pointer if reading of the
+@code{mysql_store_result()} also returns a null pointer if reading of the
result set failed. You can check if you got an error by checking if
@code{mysql_error()} doesn't return a null pointer, if
@code{mysql_errno()} returns <> 0, or if @code{mysql_field_count()}
@@ -41741,9 +44613,9 @@ This will tie up the server and prevent other threads from updating any
tables from which the data is being fetched.
When using @code{mysql_use_result()}, you must execute
-@code{mysql_fetch_row()} until a @code{NULL} value is returned, otherwise the
+@code{mysql_fetch_row()} until a @code{NULL} value is returned, otherwise, the
unfetched rows will be returned as part of the result set for your next
-query. The C API will give the error @code{Commands out of sync; You can't
+query. The C API will give the error @code{Commands out of sync; you can't
run this command now} if you forget to do this!
You may not use @code{mysql_data_seek()}, @code{mysql_row_seek()},
@@ -41776,78 +44648,195 @@ The connection to the server was lost during the query.
An unknown error occurred.
@end table
-@node C Thread functions, C API problems, C API functions, C
+@node C Thread functions, C Embedded Server func, C API functions, C
@subsection C Threaded Function Descriptions
You need to use the following functions when you want to create a
threaded client. @xref{Threaded clients}.
@menu
-* my_init::
-* my_thread_init()::
-* my_thread_end()::
+* my_init:: @code{my_init()}
+* mysql_thread_init:: @code{mysql_thread_init()}
+* mysql_thread_end:: @code{mysql_thread_end()}
+* mysql_thread_safe:: @code{mysql_thread_safe()}
@end menu
-@node my_init, my_thread_init(), C Thread functions, C Thread functions
+@node my_init, mysql_thread_init, C Thread functions, C Thread functions
@subsubsection @code{my_init()}
@findex @code{my_init()}
+@code{void my_init(void)}
+
@subsubheading Description
This function needs to be called once in the program before calling any
-MySQL function. This initializes some global variables that MySQL
-needs. If you are using a thread safe client library, this will also
-call @code{my_thread_init()} for this thread.
+MySQL function. This initialises some global variables that MySQL
+needs. If you are using a thread-safe client library, this will also
+call @code{mysql_thread_init()} for this thread.
-This is automatically called by @code{mysql_init()}
-and @code{mysql_connect()}.
+This is automatically called by @code{mysql_init()},
+@code{mysql_server_init()} and @code{mysql_connect()}.
@subsubheading Return Values
-none.
+None.
+
+@node mysql_thread_init, mysql_thread_end, my_init, C Thread functions
+@subsubsection @code{mysql_thread_init()}
-@node my_thread_init(), my_thread_end(), my_init, C Thread functions
-@subsubsection @code{my_thread_init()}
+@findex @code{mysql_thread_init()}
-@findex @code{my_thread_init()}
+@code{my_bool mysql_thread_init(void)}
@subsubheading Description
-This function needs to be called for each created thread to initialize
+This function needs to be called for each created thread to initialise
thread specific variables.
This is automatically called by @code{my_init()} and @code{mysql_connect()}.
@subsubheading Return Values
-none.
+None.
+
+@node mysql_thread_end, mysql_thread_safe, mysql_thread_init, C Thread functions
+@subsubsection @code{mysql_thread_end()}
-@node my_thread_end(), , my_thread_init(), C Thread functions
-@subsubsection @code{my_thread_end()}
+@findex @code{mysql_thread_end()}
-@findex @code{my_thread_end()}
+@code{void mysql_thread_end(void)}
@subsubheading Description
This function needs to be called before calling @code{pthread_exit()} to
-freed memory allocated by @code{my_thread_init()}.
+free memory allocated by @code{mysql_thread_init()}.
+
+Note that this function @strong{is not invoked automatically} by the client
+library. It must be called explicitly to avoid a memory leak.
+
+@subsubheading Return Values
+
+None.
+
+@node mysql_thread_safe, , mysql_thread_end, C Thread functions
+@subsubsection @code{mysql_thread_safe()}
+
+@findex @code{mysql_thread_safe()}
+
+@code{unsigned int mysql_thread_safe(void)}
+
+@subsubheading Description
+
+This function indicates whether the client is compiled as thread-safe.
-Note that this function is NOT invoked automatically by the client
-library!
+@subsubheading Return Values
+
+1 is the client is thread-safe, 0 otherwise.
+
+@node C Embedded Server func, C API problems, C Thread functions, C
+@subsection C Embedded Server Function Descriptions
+
+You must use the following functions if you want to allow your
+application to be linked against the embedded MySQL server library.
+@xref{libmysqld}.
+
+If the program is linked with @code{-lmysqlclient} instead of
+@code{-lmysqld}, these functions do nothing. This makes it
+possible to choose between using the embedded MySQL server and
+a stand-alone server without modifying any code.
+
+@menu
+* mysql_server_init:: @code{mysql_server_init()}
+* mysql_server_end:: @code{mysql_server_end()}
+@end menu
+
+@node mysql_server_init, mysql_server_end, C Embedded Server func, C Embedded Server func
+@subsubsection @code{mysql_server_init()}
+
+@findex @code{mysql_server_init()}
+
+@code{int mysql_server_init(int argc, char **argv, char **groups)}
+
+@subsubheading Description
+
+This function @strong{must} be called once in the program before
+calling any other MySQL function. It starts up the server and
+initialises any subsystems (@code{mysys}, InnoDB, etc.) that the
+server uses. If this function is not called, the program will
+crash. If you are using the DBUG package that comes with MySQL,
+you should call this after you have called @code{MY_INIT()}.
+
+The @code{argc} and @code{argv} arguments are analogous to the
+arguments to @code{main()}. The first element of @code{argv}
+is ignored (it typically contains the program name). For
+convenience, @code{argc} may be @code{0} (zero) if there are no
+command-line arguments for the server.
+
+The @code{NULL}-terminated list of strings in @code{groups}
+selects which groups in the option files will be active.
+@xref{Option files}. For convenience, @code{groups} may be
+@code{NULL}, in which case the @code{[server]} and @code{[emedded]} groups
+will be active.
+
+@subsubheading Example
+
+@example
+#include <mysql.h>
+#include <stdlib.h>
+
+static char *server_args[] = @{
+ "this_program", /* this string is not used */
+ "--datadir=.",
+ "--set-variable=key_buffer_size=32M"
+@};
+static char *server_groups[] = @{
+ "embedded",
+ "server",
+ "this_program_SERVER",
+ (char *)NULL
+@};
+
+int main(void) @{
+ mysql_server_init(sizeof(server_args) / sizeof(char *),
+ server_args, server_groups);
+
+ /* Use any MySQL API functions here */
+
+ mysql_server_end();
+
+ return EXIT_SUCCESS;
+@}
+@end example
@subsubheading Return Values
-none.
+0 if okay, 1 if an error occurred.
-@node C API problems, Building clients, C Thread functions, C
+@node mysql_server_end, , mysql_server_init, C Embedded Server func
+@subsubsection @code{mysql_server_end()}
+
+@findex @code{mysql_server_end()}
+
+@code{void mysql_server_end(void)}
+
+@subsubheading Description
+
+This function @strong{must} be called once in the program after
+all other MySQL functions. It shuts down the embedded server.
+
+@subsubheading Return Values
+
+None.
+
+@node C API problems, Building clients, C Embedded Server func, C
@subsection Common questions and problems when using the C API
@tindex @code{mysql_query()}
@tindex @code{mysql_store_result()}
@menu
-* NULL mysql_store_result:: Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL?}
+* NULL mysql_store_result:: Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL}?
* Query results:: What Results Can I Get From a Query?
* Getting unique ID:: How Can I Get the Unique ID for the Last Inserted Row?
* C API linking problems:: Problems Linking with the C API
@@ -41855,7 +44844,7 @@ none.
@node NULL mysql_store_result, Query results, C API problems, C API problems
-@subsubsection Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL?}
+@subsubsection Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL}?
It is possible for @code{mysql_store_result()} to return @code{NULL}
following a successful call to @code{mysql_query()}. When this happens, it
@@ -41874,7 +44863,7 @@ The query returned no data (for example, it was an @code{INSERT},
@code{UPDATE}, or @code{DELETE}).
@end itemize
-You can always check whether or not the statement should have produced a
+You can always check whether the statement should have produced a
non-empty result by calling @code{mysql_field_count()}. If
@code{mysql_field_count()} returns zero, the result is empty and the last
query was a statement that does not return values (for example, an
@@ -41886,14 +44875,6 @@ example.
You can test for an error by calling @code{mysql_error()} or
@code{mysql_errno()}.
-@cindex queries, C API results
-@menu
-* Query results:: What Results Can I Get From a Query?
-* Getting unique ID:: How Can I Get the Unique ID for the Last Inserted Row?
-* C API linking problems:: Problems Linking with the C API
-@end menu
-
-
@node Query results, Getting unique ID, NULL mysql_store_result, C API problems
@subsubsection What Results Can I Get From a Query?
@@ -42004,7 +44985,7 @@ adding @code{-lm} to the end of the compile/link line.
@cindex programs, client
If you compile MySQL clients that you've written yourself or that
-you obtain from a third party, they must be linked using the
+you obtain from a third-party, they must be linked using the
@code{-lmysqlclient -lz} option on the link command. You may also need to
specify a @code{-L} option to tell the linker where to find the library. For
example, if the library is installed in @file{/usr/local/mysql/lib}, use
@@ -42016,32 +44997,32 @@ For clients that use MySQL header files, you may need to specify a
files.
-@node Threaded clients, , Building clients, C
+@node Threaded clients, libmysqld, Building clients, C
@subsection How to Make a Threaded Client
@cindex clients, threaded
@cindex threaded clients
-The client library is almost thread safe. The biggest problem is
+The client library is almost thread-safe. The biggest problem is
that the subroutines in @file{net.c} that read from sockets are not
interrupt safe. This was done with the thought that you might want to
have your own alarm that can break a long read to a server. If you
install interrupt handlers for the @code{SIGPIPE} interrupt,
-the socket handling should be thread safe.
+the socket handling should be thread-safe.
-In the older binaries we distribute on our Web site, the client
-libraries are not normally compiled with the thread-safe option (the
-Windows binaries are by default compiled to be thread safe).
-Newer binary distributions should have both a normal and a
-thread-safe client library.
+In the older binaries we distribute on our web site
+(@uref{http://www.mysql.com/}), the client libraries are not normally
+compiled with the thread-safe option (the Windows binaries are by
+default compiled to be thread-safe). Newer binary distributions should
+have both a normal and a thread-safe client library.
To get a threaded client where you can interrupt the client from other
threads and set timeouts when talking with the MySQL server, you should
-use the @code{-lmysys}, @code{-lstring}, and @code{-ldbug} libraries and
+use the @code{-lmysys}, @code{-lmystrings}, and @code{-ldbug} libraries and
the @code{net_serv.o} code that the server uses.
-If you don't need interrupts or timeouts, you can just compile a thread
-safe client library @code{(mysqlclient_r)} and use this. @xref{C,,
+If you don't need interrupts or timeouts, you can just compile a
+thread-safe client library @code{(mysqlclient_r)} and use this. @xref{C,,
MySQL C API}. In this case you don't have to worry about the
@code{net_serv.o} object file or the other MySQL libraries.
@@ -42052,13 +45033,13 @@ interrupts, you can make great use of the routines in the
@code{my_init()} first! @xref{C Thread functions}.
All functions except @code{mysql_real_connect()} are by default
-thread safe. The following notes describe how to compile a thread safe
+thread-safe. The following notes describe how to compile a thread-safe
client library and use it in a thread-safe manner. (The notes below for
@code{mysql_real_connect()} actually apply to @code{mysql_connect()} as
well, but because @code{mysql_connect()} is deprecated, you should be
using @code{mysql_real_connect()} anyway.)
-To make @code{mysql_real_connect()} thread safe, you must recompile the
+To make @code{mysql_real_connect()} thread-safe, you must recompile the
client library with this command:
@example
@@ -42066,13 +45047,13 @@ shell> ./configure --enable-thread-safe-client
@end example
This will create a thread-safe client library @code{libmysqlclient_r}.
-@code{--enable-thread-safe-client}. This library is thread safe per
-connection. You can let two threads share the same connection as long
-as you do the following:
+(Assuming your OS has a thread-safe @code{gethostbyname_r()} function.)
+This library is thread-safe per connection. You can let two threads
+share the same connection with the following caveats:
@itemize @bullet
@item
-Two threads can't send a query to the MySQL at the same time on
+Two threads can't send a query to the MySQL server at the same time on
the same connection. In particular, you have to ensure that between a
@code{mysql_query()} and @code{mysql_store_result()} no other thread is using
the same connection.
@@ -42081,9 +45062,9 @@ Many threads can access different result sets that are retrieved with
@code{mysql_store_result()}.
@item
If you use @code{mysql_use_result}, you have to ensure that no other thread
-is asking anything on the same connection until the result set is closed.
+is using the same connection until the result set is closed.
However, it really is best for threaded clients that share the same
-connection to use @code{mysql_use_result()}.
+connection to use @code{mysql_store_result()}.
@item
If you want to use multiple threads on the same connection, you must
have a mutex lock around your @code{mysql_query()} and
@@ -42097,18 +45078,18 @@ establish and release a mutex lock.
@end itemize
You need to know the following if you have a thread that is calling
-MySQL functions, but that thread has not created the connection to the
+MySQL functions which did not create the connection to the
MySQL database:
When you call @code{mysql_init()} or @code{mysql_connect()}, MySQL will
create a thread specific variable for the thread that is used by the
debug library (among other things).
-If you have in a thread call a MySQL function, before a thread has
+If you call a MySQL function, before the thread has
called @code{mysql_init()} or @code{mysql_connect()}, the thread will
not have the necessary thread specific variables in place and you are
likely to end up with a core dump sooner or later.
-
+
The get things to work smoothly you have to do the following:
@enumerate
@@ -42116,18 +45097,350 @@ The get things to work smoothly you have to do the following:
Call @code{my_init()} at the start of your program if it calls
any other MySQL function before calling @code{mysql_real_connect()}.
@item
-Call @code{my_thread_init()} in the thread handler before calling
+Call @code{mysql_thread_init()} in the thread handler before calling
any MySQL function.
@item
-In the thread, call @code{my_thread_end()} before calling
+In the thread, call @code{mysql_thread_end()} before calling
@code{pthread_exit()}. This will free the memory used by MySQL thread
specific variables.
@end enumerate
You may get some errors because of undefined symbols when linking your
-client with @code{mysqlclient_r}. In most cases this is because you haven't
+client with @code{libmysqlclient_r}. In most cases this is because you haven't
included the thread libraries on the link/compile line.
+@node libmysqld, , Threaded clients, C
+@subsection libmysqld, the Embedded MySQL Server Library
+
+@cindex libmysqld
+@cindex embedded MySQL server library
+
+@menu
+* libmysqld overview:: Overview of the Embedded MySQL Server Library
+* libmysqld compiling:: Compiling Programs with @code{libmysqld}
+* libmysqld restrictions:: Restrictions when Using the Embedded MySQL Server
+* libmysqld options:: Using Option Files with the Embedded Server
+* libmysqld TODO:: Things left to do in Embedded Server (TODO)
+* libmysqld example:: A Simple Embedded Server Example
+* libmysqld licensing:: Licensing the Embedded Server
+@end menu
+
+@node libmysqld overview, libmysqld compiling, libmysqld, libmysqld
+@subsubsection Overview of the Embedded MySQL Server Library
+
+The embedded MySQL server library makes it possible to run a
+full-featured MySQL server inside the client application. The
+main benefits are increased speed and more simple management for
+embedded applications.
+
+The API is identical for the embedded MySQL version and the
+client/server version. To change an old threaded application to use the
+embedded library, you normally only have to add calls to the following
+functions:
+
+@multitable @columnfractions .25 .70
+@item @strong{Function} @tab @strong{When to call}
+@item @code{mysql_server_init()} @tab Should be called before any other MySQL function is called, preferably early in the @code{main()} function.
+@item @code{mysql_server_end()} @tab Should be called before your program exits.
+@item @code{mysql_thread_init()} @tab Should be called in each thread you create that will access MySQL.
+@item @code{mysql_thread_end()} @tab Should be called before calling @code{pthread_exit()}
+@end multitable
+
+Then you must link your code with @code{libmysqld.a} instead of @code{libmysqlclient.a}.
+
+The above @code{mysql_server_xxx} functions are also included in
+@code{libmysqlclient.a} to allow you to change between the embedded and the
+client/server version by just linking your application with the right
+library. @xref{mysql_server_init}.
+
+
+@node libmysqld compiling, libmysqld restrictions, libmysqld overview, libmysqld
+@subsubsection Compiling Programs with @code{libmysqld}
+
+To get a @code{libmysqld} library you should configure MySQL with the
+@code{--with-embedded-server} option.
+
+When you link your program with @code{libmysqld}, you must also include
+the system-specific @code{pthread} libraries and some libraries that
+the MySQL server uses. You can get the full list of libraries by executing
+@code{mysql_config --libmysqld-libs}.
+
+The correct flags for compiling and linking a threaded program
+must be used, even if you do not directly call any thread
+functions in your code.
+
+@node libmysqld restrictions, libmysqld options, libmysqld compiling, libmysqld
+@subsubsection Restrictions when using the Embedded MySQL Server
+
+The embedded server has the following limitations:
+
+@itemize @bullet
+@item
+No support for ISAM tables. (This is mainly done to make the library smaller)
+@item
+No UDF functions.
+@item
+No stack trace on core dump.
+@item
+No internal RAID support. (This is not normally needed as most OS has
+nowadays support for big files).
+@item
+You can set this up as a server or a master (no replication).
+@item
+You can't connect to the embedded server from an outside process with
+sockets or TCP/IP.
+@end itemize
+
+Some of these limitations can be changed by editing the @file{mysql_embed.h}
+include file and recompiling MySQL.
+
+@node libmysqld options, libmysqld TODO, libmysqld restrictions, libmysqld
+@subsubsection Using Option Files with the Embedded Server
+
+@cindex defaults, embedded
+
+The following is the recommended way to use option files to make it easy
+to switch between a client/server application and one where MySQL is
+embedded. @xref{Option files}.
+
+@itemize @bullet
+@item
+Put common options in the @code{[server]} section. These will be read by
+both MySQL versions.
+@item
+Put client/server specific options in the @code{[mysqld]} section.
+@item
+Put embedded MySQL specific options in the @code{[embedded]} section.
+@item
+Put application specific options in a @code{[ApplicationName_SERVER]}
+section.
+@end itemize
+
+@node libmysqld TODO, libmysqld example, libmysqld options, libmysqld
+@subsubsection Things left to do in Embedded Server (TODO)
+
+@cindex TODO, embedded server
+
+@itemize @bullet
+@item
+Currently we only provide a static version of the @code{mysqld} library,
+in the future we will also provide a shared library for this.
+@item
+We are going to provide options to leave out some parts of MySQL to make
+the library smaller.
+@item
+There is still a lot of speed optimisation to do.
+@item
+Errors are written to stderr. We will add an option to specify a
+filename for these.
+@item
+We have to change InnoDB to not be so verbose when using in the embedded
+version.
+@end itemize
+
+
+@node libmysqld example, libmysqld licensing, libmysqld TODO, libmysqld
+@subsubsection A Simple Embedded Server Example
+
+This example program and makefile should work without any
+changes on a Linux or FreeBSD system. For other operating
+systems, minor changes will be needed. This example is
+designed to give enough details to understand the problem,
+without the clutter that is a necessary part of a real
+application.
+
+To try out the example, create an @file{test_libmysqld} directory
+at the same level as the mysql-4.0 source directory. Save
+the @file{test_libmysqld.c} source and the @file{GNUmakefile} in the
+directory, and run GNU @file{make} from inside the @file{test_libmysqld}
+directory.
+
+@file{test_libmysqld.c}
+@example
+/*
+ * A simple example client, using the embedded MySQL server library
+ */
+
+#include <mysql.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+MYSQL *db_connect(const char *dbname);
+void db_disconnect(MYSQL *db);
+void db_do_query(MYSQL *db, const char *query);
+
+const char *server_groups[] = @{
+ "test_libmysqld_SERVER", "embedded", "server", NULL
+@};
+
+int
+main(int argc, char **argv)
+@{
+ MYSQL *one, *two;
+
+ /* mysql_server_init() must be called before any other mysql
+ * functions.
+ *
+ * You can use mysql_server_init(0, NULL, NULL), and it will
+ * initialise the server using groups = @{
+ * "server", "embedded", NULL
+ * @}.
+ *
+ * In your $HOME/.my.cnf file, you probably want to put:
+
+[test_libmysqld_SERVER]
+language = /path/to/source/of/mysql/sql/share/english
+
+ * You could, of course, modify argc and argv before passing
+ * them to this function. Or you could create new ones in any
+ * way you like. But all of the arguments in argv (except for
+ * argv[0], which is the program name) should be valid options
+ * for the MySQL server.
+ *
+ * If you link this client against the normal mysqlclient
+ * library, this function is just a stub that does nothing.
+ */
+ mysql_server_init(argc, argv, (char **)server_groups);
+
+ one = db_connect("test");
+ two = db_connect(NULL);
+
+ db_do_query(one, "SHOW TABLE STATUS");
+ db_do_query(two, "SHOW DATABASES");
+
+ mysql_close(two);
+ mysql_close(one);
+
+ /* This must be called after all other mysql functions */
+ mysql_server_end();
+
+ exit(EXIT_SUCCESS);
+@}
+
+static void
+die(MYSQL *db, char *fmt, ...)
+@{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)putc('\n', stderr);
+ if (db)
+ db_disconnect(db);
+ exit(EXIT_FAILURE);
+@}
+
+MYSQL *
+db_connect(const char *dbname)
+@{
+ MYSQL *db = mysql_init(NULL);
+ if (!db)
+ die(db, "mysql_init failed: no memory");
+ /*
+ * Notice that the client and server use separate group names.
+ * This is critical, because the server will not accept the
+ * client's options, and vice versa.
+ */
+ mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test_libmysqld_CLIENT");
+ if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
+ die(db, "mysql_real_connect failed: %s", mysql_error(db));
+
+ return db;
+@}
+
+void
+db_disconnect(MYSQL *db)
+@{
+ mysql_close(db);
+@}
+
+void
+db_do_query(MYSQL *db, const char *query)
+@{
+ if (mysql_query(db, query) != 0)
+ goto err;
+
+ if (mysql_field_count(db) > 0)
+ @{
+ MYSQL_RES *res;
+ MYSQL_ROW row, end_row;
+ int num_fields;
+
+ if (!(res = mysql_store_result(db)))
+ goto err;
+ num_fields = mysql_num_fields(res);
+ while ((row = mysql_fetch_row(res)))
+ @{
+ (void)fputs(">> ", stdout);
+ for (end_row = row + num_fields; row < end_row; ++row)
+ (void)printf("%s\t", row ? (char*)*row : "NULL");
+ (void)fputc('\n', stdout);
+ @}
+ (void)fputc('\n', stdout);
+ @}
+ else
+ (void)printf("Affected rows: %lld\n", mysql_affected_rows(db));
+
+ return;
+
+err:
+ die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
+@}
+@end example
+
+@file{GNUmakefile}
+@example
+# This assumes the MySQL software is installed in /usr/local/mysql
+inc := /usr/local/mysql/include/mysql
+lib := /usr/local/mysql/lib
+
+# If you have not installed the MySQL software yet, try this instead
+#inc := $(HOME)/mysql-4.0/include
+#lib := $(HOME)/mysql-4.0/libmysqld
+
+CC := gcc
+CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
+CFLAGS := -g -W -Wall
+LDFLAGS := -static
+# You can change -lmysqld to -lmysqlclient to use the
+# client/server library
+LDLIBS = -L$(lib) -lmysqld -lz -lm -lcrypt
+
+ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
+# FreeBSD
+LDFLAGS += -pthread
+else
+# Assume Linux
+LDLIBS += -lpthread
+endif
+
+# This works for simple one-file test programs
+sources := $(wildcard *.c)
+objects := $(patsubst %c,%o,$(sources))
+targets := $(basename $(sources))
+
+all: $(targets)
+
+clean:
+ rm -f $(targets) $(objects) *.core
+@end example
+
+@node libmysqld licensing, , libmysqld example, libmysqld
+@subsubsection Licensing the Embedded Server
+
+The MySQL source code is covered by the GNU GPL license
+(@pxref{GPL license}). One result of this is that any program
+which includes, by linking with @code{libmysqld}, the MySQL
+source code must be released as free software (under a license
+compatible with the GPL).
+
+We encourage everyone to promote free software by releasing
+code under the GPL or a compatible license. For those who
+are not able to do this, another option is to purchase a
+commercial licence for the MySQL code from MySQL AB.
+For details, please see @ref{MySQL licenses}.
+
@node Cplusplus, Java, C, Clients
@section MySQL C++ APIs
@@ -42138,8 +45451,8 @@ included the thread libraries on the link/compile line.
@cindex C++ APIs
-Two APIs are available in the MySQL
-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}.
+Two APIs are available in the MySQL Contrib directory
+(@uref{http://www.mysql.com/Downloads/Contrib/}).
@node Borland C++, , Cplusplus, Cplusplus
@@ -42149,7 +45462,7 @@ Two APIs are available in the MySQL
You can compile the MySQL Windows source with Borland C++ 5.02.
(The Windows source includes only projects for Microsoft VC++, for
-Borland C++ you have to do the project files yourself).
+Borland C++ you have to do the project files yourself.)
One known problem with Borland C++ is that it uses a different structure
alignment than VC++. This means that you will run into problems if you
@@ -42187,22 +45500,19 @@ documentation for MySQL-specific features.
@cindex Python APIs
-The MySQL @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}
+The MySQL Contrib directory
+(@uref{http://www.mysql.com/Downloads/Contrib/})
contains a Python interface written by Joseph Skinner.
-You can also use the Python interface to iODBC to access a
-MySQL server.
-@uref{http://starship.skyport.net/~lemburg/,mxODBC}
-
@node Tcl, Eiffel, Python, Clients
@section MySQL Tcl APIs
@cindex Tcl APIs
-@uref{http://www.binevolve.com/~tdarugar/tcl-sql/, Tcl at binevolve}.
-The
-@uref{http://www.mysql.com/Downloads/Contrib,Contrib directory} contains a Tcl
+@uref{http://www.binevolve.com/~tdarugar/tcl-sql/} (Tcl at binevolve).
+The Contrib directory
+(@uref{http://www.mysql.com/Downloads/Contrib/}) contains a Tcl
interface that is based on msqltcl 1.50.
@@ -42212,26 +45522,310 @@ interface that is based on msqltcl 1.50.
@cindex Eiffel Wrapper
@cindex wrappers, Eiffel
-The MySQL @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}
+The MySQL Contrib directory
+(@uref{http://www.mysql.com/Downloads/Contrib/})
contains an Eiffel wrapper written by Michael Ravits.
-You can also find this at:
-@url{http://www.netpedia.net/hosting/newplayer/}
-
-
-
@node Extending MySQL, Problems, Clients, Top
@chapter Extending MySQL
@menu
+* MySQL internals:: MySQL Internals
* Adding functions:: Adding New Functions to MySQL
* Adding procedures:: Adding New Procedures to MySQL
-* MySQL internals:: MySQL Internals
@end menu
-@node Adding functions, Adding procedures, Extending MySQL, Extending MySQL
+@node MySQL internals, Adding functions, Extending MySQL, Extending MySQL
+@section MySQL Internals
+
+@cindex internals
+@cindex threads
+
+This chapter describes a lot of things that you need to know when
+working on the MySQL code. If you plan to contribute to MySQL
+development, want to have access to the bleeding-edge in-between
+versions code, or just want to keep track of development, follow the
+instructions in @ref{Installing source tree}.
+If you are interested in MySQL internals, you should also subscribe
+to our @code{internals} mailing list. This list is relatively low
+traffic. For details on how to subscribe, please see
+@ref{Mailing-list}.
+All developers at MySQL AB are on the @code{internals} list and we
+help other people who are working on the MySQL code. Feel free to
+use this list both to ask questions about the code and to send
+patches that you would like to contribute to the MySQL project!
+
+@menu
+* MySQL threads:: MySQL threads
+* MySQL test suite:: MySQL test suite
+@end menu
+
+
+@node MySQL threads, MySQL test suite, MySQL internals, MySQL internals
+@subsection MySQL Threads
+
+The MySQL server creates the following threads:
+
+@itemize @bullet
+
+@item
+The TCP/IP connection thread handles all connection requests and
+creates a new dedicated thread to handle the authentication and
+SQL query processing for each connection.
+
+@item
+On Windows NT there is a named pipe handler thread that does the same work as
+the TCP/IP connection thread on named pipe connect requests.
+
+@item
+The signal thread handles all signals. This thread also normally handles
+alarms and calls @code{process_alarm()} to force timeouts on connections
+that have been idle too long.
+
+@item
+If @code{mysqld} is compiled with @code{-DUSE_ALARM_THREAD}, a dedicated
+thread that handles alarms is created. This is only used on some systems where
+there are problems with @code{sigwait()} or if one wants to use the
+@code{thr_alarm()} code in ones application without a dedicated signal
+handling thread.
+
+@item
+If one uses the @code{--flush_time=#} option, a dedicated thread is created
+to flush all tables at the given interval.
+
+@item
+Every connection has its own thread.
+
+@item
+Every different table on which one uses @code{INSERT DELAYED} gets its
+own thread.
+
+@item
+If you use @code{--master-host}, a slave replication thread will be
+started to read and apply updates from the master.
+@end itemize
+
+@code{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED},
+and replication threads.
+
+
+@node MySQL test suite, , MySQL threads, MySQL internals
+@subsection MySQL Test Suite
+
+@cindex mysqltest, MySQL Test Suite
+@cindex testing mysqld, mysqltest
+
+Until recently, our main full-coverage test suite was based on proprietary
+customer data and for that reason has not been publicly available. The only
+publicly available part of our testing process consisted of the @code{crash-me}
+test, a Perl DBI/DBD benchmark found in the @code{sql-bench} directory, and
+miscellaneous tests located in @code{tests} directory. The lack of a
+standardised publicly available test suite has made it difficult for our users,
+as well developers, to do regression tests on the MySQL code. To
+address this problem, we have created a new test system that is included in
+the source and binary distributions starting in Version 3.23.29.
+
+The current set of test cases doesn't test everything in MySQL, but it
+should catch most obvious bugs in the SQL processing code, OS/library
+issues, and is quite thorough in testing replication. Our eventual goal
+is to have the tests cover 100% of the code. We welcome contributions
+to our test suite. You may especially want to contribute tests that
+examine the functionality critical to your system, as this will ensure
+that all future MySQL releases will work well with your
+applications.
+
+@menu
+* running mysqltest:: Running the MySQL Test Suite
+* extending mysqltest:: Extending the MySQL Test Suite
+* Reporting mysqltest bugs:: Reporting Bugs in the MySQL Test Suite
+@end menu
+
+
+@node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite
+@subsubsection Running the MySQL Test Suite
+
+The test system consist of a test language interpreter
+(@code{mysqltest}), a shell script to run all
+tests(@code{mysql-test-run}), the actual test cases written in a special
+test language, and their expected results. To run the test suite on
+your system after a build, type @code{make test} or
+@code{mysql-test/mysql-test-run} from the source root. If you have
+installed a binary distribution, @code{cd} to the install root
+(eg. @code{/usr/local/mysql}), and do @code{scripts/mysql-test-run}.
+All tests should succeed. If not, you should try to find out why and
+report the problem if this is a bug in MySQL.
+@xref{Reporting mysqltest bugs}.
+
+If you have a copy of @code{mysqld} running on the machine where you want to
+run the test suite you do not have to stop it, as long as it is not using
+ports @code{9306} and @code{9307}. If one of those ports is taken, you should
+edit @code{mysql-test-run} and change the values of the master and/or slave
+port to one that is available.
+
+You can run one individual test case with
+@code{mysql-test/mysql-test-run test_name}.
+
+If one test fails, you should test running @code{mysql-test-run} with
+the @code{--force} option to check if any other tests fails.
+
+
+@node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite
+@subsubsection Extending the MySQL Test Suite
+
+You can use the @code{mysqltest} language to write your own test cases.
+Unfortunately, we have not yet written full documentation for it - we plan to
+do this shortly. You can, however, look at our current test cases and use
+them as an example. The following points should help you get started:
+
+@itemize @bullet
+@item
+The tests are located in @code{mysql-test/t/*.test}
+
+@item
+A test case consists of @code{;} terminated statements and is similar to the
+input of @code{mysql} command-line client. A statement by default is a query
+to be sent to MySQL server, unless it is recognised as internal
+command (eg. @code{sleep}).
+
+@item
+All queries that produce results@-e.g., @code{SELECT}, @code{SHOW},
+@code{EXPLAIN}, etc., must be preceded with @code{@@/path/to/result/file}. The
+file must contain the expected results. An easy way to generate the result
+file is to run @code{mysqltest -r < t/test-case-name.test} from
+@code{mysql-test} directory, and then edit the generated result files, if
+needed, to adjust them to the expected output. In that case, be very careful
+about not adding or deleting any invisible characters - make sure to only
+change the text and/or delete lines. If you have to insert a line, make sure
+the fields are separated with a hard tab, and there is a hard tab at the end.
+You may want to use @code{od -c} to make sure your text editor has not messed
+anything up during edit. We, of course, hope that you will never have to edit
+the output of @code{mysqltest -r} as you only have to do it when you find a
+bug.
+
+@item
+To be consistent with our setup, you should put your result files in
+@code{mysql-test/r} directory and name them @code{test_name.result}. If the
+test produces more than one result, you should use @code{test_name.a.result},
+@code{test_name.b.result}, etc.
+
+@item
+If a statement returns an error, you should on the line before the statement
+specify with the @code{--error error-number}. The error number can be
+a list of possible error numbers separated with @code{','}.
+
+@item
+If you are writing a replication test case, you should on the first line of
+the test file, put @code{source include/master-slave.inc;}. To switch between
+master and slave, use @code{connection master;} and @code{connection slave;}.
+If you need to do something on an alternate connection, you can do
+@code{connection master1;} for the master, and @code{connection slave1;} for
+the slave.
+
+@item
+If you need to do something in a loop, you can use something like this:
+@example
+let $1=1000;
+while ($1)
+@{
+ # do your queries here
+ dec $1;
+@}
+@end example
+
+@item
+To sleep between queries, use the @code{sleep} command. It supports fractions
+of a second, so you can do @code{sleep 1.3;}, for example, to sleep 1.3
+seconds.
+
+@item
+To run the slave with additional options for your test case, put them
+in the command-line format in @code{mysql-test/t/test_name-slave.opt}. For
+the master, put them in @code{mysql-test/t/test_name-master.opt}.
+
+@item
+If you have a question about the test suite, or have a test case to contribute,
+e-mail to @email{internals@@lists.mysql.com}. As the list does not accept
+attachments, you should ftp all the relevant files to:
+@uref{ftp://support.mysql.com/pub/mysql/Incoming/}
+
+@end itemize
+
+
+@node Reporting mysqltest bugs, , extending mysqltest, MySQL test suite
+@subsubsection Reporting Bugs in the MySQL Test Suite
+
+If your MySQL version doesn't pass the test suite you should
+do the following:
+
+@itemize @bullet
+@item
+Don't send a bug report before you have found out as much as possible of
+what when wrong! When you do it, please use the @code{mysqlbug} script
+so that we can get information about your system and @code{MySQL}
+version. @xref{Bug reports}.
+@item
+Make sure to include the output of @code{mysql-test-run}, as well as
+contents of all @code{.reject} files in @code{mysql-test/r} directory.
+@item
+If a test in the test suite fails, check if the test fails also when run
+by its own:
+
+@example
+cd mysql-test
+mysql-test-run --local test-name
+@end example
+
+If this fails, then you should configure MySQL with
+@code{--with-debug} and run @code{mysql-test-run} with the
+@code{--debug} option. If this also fails send the trace file
+@file{var/tmp/master.trace} to ftp://support.mysql.com/pub/mysql/secret
+so that we can examine it. Please remember to also include a full
+description of your system, the version of the mysqld binary and how you
+compiled it.
+
+@item
+Try also to run @code{mysql-test-run} with the @code{--force} option to
+see if there is any other test that fails.
+
+@item
+If you have compiled MySQL yourself, check our manual for how
+to compile MySQL on your platform or, preferable, use one of
+the binaries we have compiled for you at
+@uref{http://www.mysql.com/downloads/}. All our standard binaries should
+pass the test suite !
+
+@item
+If you get an error, like @code{Result length mismatch} or @code{Result
+content mismatch} it means that the output of the test didn't match
+exactly the expected output. This could be a bug in MySQL or
+that your mysqld version produces slight different results under some
+circumstances.
+
+Failed test results are put in a file with the same base name as the
+result file with the @code{.reject} extension. If your test case is
+failing, you should do a diff on the two files. If you cannot see how
+they are different, examine both with @code{od -c} and also check their
+lengths.
+
+@item
+If a test fails totally, you should check the logs file in the
+@code{mysql-test/var/log} directory for hints of what went wrong.
+
+@item
+If you have compiled MySQL with debugging you can try to debug this
+by running @code{mysql-test-run} with the @code{--gdb} and/or @code{--debug}
+options.
+@xref{Making trace files}.
+
+If you have not compiled MySQL for debugging you should probably
+do that. Just specify the @code{--with-debug} options to @code{configure}!
+@xref{Installing source}.
+@end itemize
+
+
+@node Adding functions, Adding procedures, MySQL internals, Extending MySQL
@section Adding New Functions to MySQL
@cindex functions, new
@@ -42305,12 +45899,12 @@ function that works like native (built in) MySQL functions such as
@code{CREATE FUNCTION} saves the function's name, type, and shared library
name in the @code{mysql.func} system table. You must have the
-@strong{insert} and @strong{delete} privileges for the @code{mysql} database
+@code{INSERT} and @code{DELETE} privileges for the @code{mysql} database
to create and drop functions.
All active functions are reloaded each time the server starts, unless
you start @code{mysqld} with the @code{--skip-grant-tables} option. In
-this case, UDF initialization is skipped and UDFs are unavailable.
+this case, UDF initialisation is skipped and UDFs are unavailable.
(An active function is one that has been loaded with @code{CREATE FUNCTION}
and not removed with @code{DROP FUNCTION}.)
@@ -42319,6 +45913,10 @@ functions}. For the UDF mechanism to work, functions must be written in C or
C++, your operating system must support dynamic loading and you must have
compiled @code{mysqld} dynamically (not statically).
+Note that to make @code{AGGREGATE} work, you must have a
+@code{mysql.func} table that contains the column @code{type}. If this
+is not the case, you should run the script
+@code{mysql_fix_privilege_tables} to get this fixed.
@node Adding UDF, Adding native function, CREATE FUNCTION, Adding functions
@@ -42329,10 +45927,11 @@ compiled @code{mysqld} dynamically (not statically).
@cindex functions, user-definable, adding
@menu
-* UDF calling sequences:: UDF calling sequences
-* UDF arguments:: Argument processing
-* UDF return values:: Return values and error handling
-* UDF compiling:: Compiling and installing user-definable functions
+* UDF calling:: UDF Calling Sequences
+* UDF aggr. calling :: UDF Calling Sequences for aggregate functions
+* UDF arguments:: Argument Processing
+* UDF return values:: Return Values and Error Handling
+* UDF compiling:: Compiling and Installing User-definable Functions
@end menu
@@ -42349,7 +45948,7 @@ you are using @code{--with-mysqld-ldflags=-all-static} If you want to
use an UDF that needs to access symbols from @code{mysqld} (like the
@code{methaphone} example in @file{sql/udf_example.cc} that uses
@code{default_charset_info}), you must link the program with
-@code{-rdynamic}. (see @code{man dlopen}).
+@code{-rdynamic} (see @code{man dlopen}).
For each function that you want to use in SQL statements, you should define
corresponding C (or C++) functions. In the discussion below, the name
@@ -42364,9 +45963,9 @@ The C/C++ functions that you write to implement the interface for
@item @code{xxx()} (required)
The main function. This is where the function result is computed.
The correspondence between the SQL type and return type of your C/C++
-function is shown below:
+function is shown here:
-@multitable @columnfractions .2 .8
+@multitable @columnfractions .15 .15
@item @strong{SQL type} @tab @strong{C/C++ type}
@item @code{STRING} @tab @code{char *}
@item @code{INTEGER} @tab @code{long long}
@@ -42374,7 +45973,7 @@ function is shown below:
@end multitable
@item @code{xxx_init()} (optional)
-The initialization function for @code{xxx()}. It can be used to:
+The initialisation function for @code{xxx()}. It can be used to:
@itemize @bullet
@item
@@ -42390,36 +45989,68 @@ Specify the maximum length of the result.
@item
Specify (for @code{REAL} functions) the maximum number of decimals.
@item
-Specify whether or not the result can be @code{NULL}.
+Specify whether the result can be @code{NULL}.
@end itemize
@item @code{xxx_deinit()} (optional)
-The deinitialization function for @code{xxx()}. It should deallocate any
-memory allocated by the initialization function.
+The deinitialisation function for @code{xxx()}. It should deallocate any
+memory allocated by the initialisation function.
@end table
When a SQL statement invokes @code{XXX()}, MySQL calls the
-initialization function @code{xxx_init()} to let it perform any required
+initialisation function @code{xxx_init()} to let it perform any required
setup, such as argument checking or memory allocation. If @code{xxx_init()}
returns an error, the SQL statement is aborted with an error message and the
-main and deinitialization functions are not called. Otherwise, the main
+main and deinitialisation functions are not called. Otherwise, the main
function @code{xxx()} is called once for each row. After all rows have been
-processed, the deinitialization function @code{xxx_deinit()} is called so it
+processed, the deinitialisation function @code{xxx_deinit()} is called so it
can perform any required cleanup.
-All functions must be thread safe (not just the main function,
-but the initialization and deinitialization functions as well). This means
+For aggregate functions (like @code{SUM()}), you must also provide the
+following functions:
+
+@table @asis
+@item @code{xxx_reset()} (required)
+Reset sum and insert the argument as the initial value for a new group.
+@item @code{xxx_add()} (required)
+Add the argument to the old sum.
+@end table
+
+When using aggregate UDF functions MySQL works the following way:
+
+@enumerate
+@item
+Call @code{xxx_init()} to let the aggregate function allocate the memory it
+will need to store results.
+@item
+Sort the table according to the @code{GROUP BY} expression.
+@item
+For the first row in a new group, call the @code{xxx_reset()} function.
+@item
+For each new row that belongs in the same group, call the
+@code{xxx_add()} function.
+@item
+When the group changes or after the last row has been processed,
+call @code{xxx()} to get the result for the aggregate.
+@item
+Repeat 3-5 until all rows has been processed
+@item
+Call @code{xxx_deinit()} to let the UDF free any memory it has allocated.
+@end enumerate
+
+All functions must be thread-safe (not just the main function,
+but the initialisation and deinitialisation functions as well). This means
that you are not allowed to allocate any global or static variables that
change! If you need memory, you should allocate it in @code{xxx_init()}
and free it in @code{xxx_deinit()}.
-@node UDF calling sequences, UDF arguments, Adding UDF, Adding UDF
-@subsubsection UDF Calling Sequences
+@node UDF calling, UDF aggr. calling , Adding UDF, Adding UDF
+@subsubsection UDF Calling Sequences for simple functions
-@cindex calling sequences, UDF
+@cindex calling sequences for simple functions, UDF
-The main function should be declared as shown below. Note that the return
+The main function should be declared as shown here. Note that the return
type and parameters differ, depending on whether you will declare the SQL
function @code{XXX()} to return @code{STRING}, @code{INTEGER}, or @code{REAL}
in the @code{CREATE FUNCTION} statement:
@@ -42429,8 +46060,8 @@ For @code{STRING} functions:
@example
char *xxx(UDF_INIT *initid, UDF_ARGS *args,
- char *result, unsigned long *length,
- char *is_null, char *error);
+ char *result, unsigned long *length,
+ char *is_null, char *error);
@end example
@noindent
@@ -42449,7 +46080,7 @@ double xxx(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
@end example
-The initialization and deinitialization functions are declared like this:
+The initialisation and deinitialisation functions are declared like this:
@example
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
@@ -42460,7 +46091,7 @@ void xxx_deinit(UDF_INIT *initid);
The @code{initid} parameter is passed to all three functions. It points to a
@code{UDF_INIT} structure that is used to communicate information between
functions. The @code{UDF_INIT} structure members are listed below. The
-initialization function should fill in any members that it wishes to change.
+initialisation function should fill in any members that it wishes to change.
(To use the default for a member, leave it unchanged.):
@table @code
@@ -42483,6 +46114,10 @@ digits. For real functions, the default is 13 plus the number of decimals
indicated by @code{initid->decimals}. (For numeric functions, the length
includes any sign or decimal point characters.)
+If you want to return a blob, you can set this to 65K or 16M; this
+memory is not allocated but used to decide which column type to use if
+there is a need to temporary store the data.
+
@item char *ptr
A pointer that the function can use for its own purposes. For example,
functions can use @code{initid->ptr} to communicate allocated memory
@@ -42498,18 +46133,73 @@ or deallocate the memory.
@end table
-@node UDF arguments, UDF return values, UDF calling sequences, Adding UDF
+@node UDF aggr. calling , UDF arguments, UDF calling, Adding UDF
+@subsubsection UDF Calling Sequences for aggregate functions
+
+@cindex calling sequences for aggregate functions, UDF
+
+Here follows a description of the different functions you need to define
+when you want to create an aggregate UDF function.
+
+@example
+char *xxx_reset(UDF_INIT *initid, UDF_ARGS *args,
+ char *is_null, char *error);
+@end example
+
+This function is called when MySQL finds the first row in a new group.
+In the function you should reset any internal summary variables and then set
+the given argument as the first argument in the group.
+
+In many cases this is implemented internally by reseting all variables
+and then calling @code{xxx_add()}.
+
+@example
+char *xxx_add(UDF_INIT *initid, UDF_ARGS *args,
+ char *is_null, char *error);
+@end example
+
+This function is called for all rows that belongs to the same group,
+except for the first row. In this you should add the value in UDF_ARGS
+to your internal summary variable.
+
+The @code{xxx()} function should be declared identical as when you
+define a simple UDF function. @xref{UDF calling}.
+
+This function is called when all rows in the group has been processed.
+You should normally never access the @code{args} variable here but
+return your value based on your internal summary variables.
+
+All argument processing in @code{xxx_reset()} and @code{xxx_add()}
+should be done identically as for normal UDF functions. @xref{UDF
+arguments}.
+
+The return value handling in @code{xxx()} should be done identically as
+for a normal UDF. @xref{UDF return values}.
+
+The pointer argument to @code{is_null} and @code{error} is the same for
+all calls to @code{xxx_reset()}, @code{xxx_add()} and @code{xxx()}.
+You can use this to remember that you got an error or if the @code{xxx()}
+function should return @code{NULL}. Note that you should not store a string
+into @code{*error}! This is just a 1 byte flag!
+
+@code{is_null} is reset for each group (before calling @code{xxx_reset()}.
+@code{error} is never reset.
+
+If @code{isnull} or @code{error} are set after @code{xxx()} then MySQL
+will return @code{NULL} as the result for the group function.
+
+@node UDF arguments, UDF return values, UDF aggr. calling , Adding UDF
@subsubsection Argument Processing
@cindex argument processing
@cindex processing, arguments
-The @code{args} parameter points to a @code{UDF_ARGS} structure that thas the
-members listed below:
+The @code{args} parameter points to a @code{UDF_ARGS} structure that has the
+members listed here:
@table @code
@item unsigned int arg_count
-The number of arguments. Check this value in the initialization function
+The number of arguments. Check this value in the initialisation function
if you want your function to be called with a particular number of arguments.
For example:
@@ -42527,7 +46217,7 @@ The types for each argument. The possible type values are
@code{STRING_RESULT}, @code{INT_RESULT}, and @code{REAL_RESULT}.
To make sure that arguments are of a given type and return an
-error if they are not, check the @code{arg_type} array in the initialization
+error if they are not, check the @code{arg_type} array in the initialisation
function. For example:
@example
@@ -42540,7 +46230,7 @@ if (args->arg_type[0] != STRING_RESULT ||
@end example
As an alternative to requiring your function's arguments to be of particular
-types, you can use the initialization function to set the @code{arg_type}
+types, you can use the initialisation function to set the @code{arg_type}
elements to the types you want. This causes MySQL to coerce
arguments to those types for each call to @code{xxx()}. For example, to
specify coercion of the first two arguments to string and integer, do this in
@@ -42552,7 +46242,7 @@ args->arg_type[1] = INT_RESULT;
@end example
@item char **args
-@code{args->args} communicates information to the initialization function
+@code{args->args} communicates information to the initialisation function
about the general nature of the arguments your function was called with. For a
constant argument @code{i}, @code{args->args[i]} points to the argument
value. (See below for instructions on how to access the value properly.)
@@ -42595,12 +46285,13 @@ real_val = *((double*) args->args[i]);
@end itemize
@item unsigned long *lengths
-For the initialization function, the @code{lengths} array indicates the
-maximum string length for each argument. For each invocation of the main
-function, @code{lengths} contains the actual lengths of any string arguments
-that are passed for the row currently being processed. For arguments of
-types @code{INT_RESULT} or @code{REAL_RESULT}, @code{lengths} still contains
-the maximum length of the argument (as for the initialization function).
+For the initialisation function, the @code{lengths} array indicates the
+maximum string length for each argument. You should not change these.
+For each invocation of the main function, @code{lengths} contains the
+actual lengths of any string arguments that are passed for the row
+currently being processed. For arguments of types @code{INT_RESULT} or
+@code{REAL_RESULT}, @code{lengths} still contains the maximum length of
+the argument (as for the initialisation function).
@end table
@@ -42612,7 +46303,7 @@ the maximum length of the argument (as for the initialization function).
@cindex errors, handling for UDFs
@cindex handling, errors
-The initialization function should return @code{0} if no error occurred and
+The initialisation function should return @code{0} if no error occurred and
@code{1} otherwise. If an error occurs, @code{xxx_init()} should store a
null-terminated error message in the @code{message} parameter. The message
will be returned to the client. The message buffer is
@@ -42623,7 +46314,8 @@ terminal screen.
The return value of the main function @code{xxx()} is the function value, for
@code{long long} and @code{double} functions. A string functions should
return a pointer to the result and store the length of the string in the
-@code{length} arguments. @code{result} is a buffer at least 255 bytes long.
+@code{length} arguments.
+
Set these to the contents and length of the return value. For example:
@example
@@ -42631,12 +46323,16 @@ memcpy(result, "result string", 13);
*length = 13;
@end example
-If your string functions that needs to return a string longer than 255
-bytes, you must allocate the space for it with @code{malloc()} in your
+The @code{result} buffer that is passed to the calc function is 255 byte
+big. If your result fits in this, you don't have to worry about memory
+allocation for results.
+
+If your string function needs to return a string longer than 255 bytes,
+you must allocate the space for it with @code{malloc()} in your
@code{xxx_init()} function or your @code{xxx()} function and free it in
your @code{xxx_deinit()} function. You can store the allocated memory
in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by
-future @code{xxx()} calls. @xref{UDF calling sequences}.
+future @code{xxx()} calls. @xref{UDF calling}.
To indicate a return value of @code{NULL} in the main function, set
@code{is_null} to @code{1}:
@@ -42655,7 +46351,7 @@ parameter to @code{1}:
If @code{xxx()} sets @code{*error} to @code{1} for any row, the function
value is @code{NULL} for the current row and for any subsequent rows
processed by the statement in which @code{XXX()} was invoked. (@code{xxx()}
-will not even be called for subsequent rows.) @strong{NOTE:} In
+will not even be called for subsequent rows.) @strong{Note}: in
MySQL versions prior to 3.22.10, you should set both @code{*error}
and @code{*is_null}:
@@ -42736,7 +46432,10 @@ mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so";
mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
-mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
+mysql> CREATE FUNCTION reverse_lookup
+ -> RETURNS STRING SONAME "udf_example.so";
+mysql> CREATE AGGREGATE FUNCTION avgcost
+ -> RETURNS REAL SONAME "udf_example.so";
@end example
Functions can be deleted using @code{DROP FUNCTION}:
@@ -42747,24 +46446,25 @@ mysql> DROP FUNCTION myfunc_double;
mysql> DROP FUNCTION myfunc_int;
mysql> DROP FUNCTION lookup;
mysql> DROP FUNCTION reverse_lookup;
+mysql> DROP FUNCTION avgcost;
@end example
The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the
system table @code{func} in the @code{mysql} database. The function's name,
type and shared library name are saved in the table. You must have the
-@strong{insert} and @strong{delete} privileges for the @code{mysql} database
+@code{INSERT} and @code{DELETE} privileges for the @code{mysql} database
to create and drop functions.
You should not use @code{CREATE FUNCTION} to add a function that has already
been created. If you need to reinstall a function, you should remove it with
@code{DROP FUNCTION} and then reinstall it with @code{CREATE FUNCTION}. You
would need to do this, for example, if you recompile a new version of your
-function, so that @code{mysqld} gets the new version. Otherwise the server
+function, so that @code{mysqld} gets the new version. Otherwise, the server
will continue to use the old version.
Active functions are reloaded each time the server starts, unless you start
@code{mysqld} with the @code{--skip-grant-tables} option. In this case, UDF
-initialization is skipped and UDFs are unavailable. (An active function is
+initialisation is skipped and UDFs are unavailable. (An active function is
one that has been loaded with @code{CREATE FUNCTION} and not removed with
@code{DROP FUNCTION}.)
@@ -42776,7 +46476,7 @@ one that has been loaded with @code{CREATE FUNCTION} and not removed with
@cindex native functions, adding
@cindex functions, native, adding
-The procedure for adding a new native function is described below. Note
+The procedure for adding a new native function is described here. Note
that you cannot add native functions to a binary distribution because
the procedure involves modifying MySQL source code. You must
compile MySQL yourself from a source distribution. Also note
@@ -42839,7 +46539,7 @@ can take a look at @code{Item_func_mod::fix_length_and_dec} for a
typical example of how to do this.
@end enumerate
-All functions must be thread safe (In other words, don't use any global or
+All functions must be thread-safe (in other words, don't use any global or
static variables in the functions without protecting them with mutexes).
If you want to return @code{NULL}, from @code{::val()}, @code{::val_int()}
@@ -42862,7 +46562,7 @@ absolutely necessary!
@end itemize
-@node Adding procedures, MySQL internals, Adding functions, Extending MySQL
+@node Adding procedures, , Adding functions, Extending MySQL
@section Adding New Procedures to MySQL
@cindex procedures, adding
@@ -42876,8 +46576,9 @@ can be done on row-by-row or @code{GROUP BY} level.
We have created an example procedure in MySQL Version 3.23 to
show you what can be done.
-Additionally we recommend you to take a look at 'mylua', which you can find in the Contrib directory. @xref{Contrib}. Which this you can use the LUA
-language to load a procedure at runtime into @code{mysqld}.
+Additionally we recommend you to take a look at @code{mylua}.
+With this you can use the LUA language to load a procedure at
+runtime into @code{mysqld}.
@menu
* procedure analyse:: Procedure analyse
@@ -42924,292 +46625,7 @@ You can find all information about procedures by examining the following files:
@end itemize
-@node MySQL internals, , Adding procedures, Extending MySQL
-@section MySQL Internals
-
-@cindex internals
-@cindex threads
-
-This chapter describes a lot of things that you need to know when
-working on the MySQL code. If you plan to contribute to MySQL
-development, want to have access to the bleeding-edge in-between
-versions code, or just want to keep track of development, follow the
-instructions in @xref{Installing source tree}. If you are interested in MySQL
-internals, you should also subscribe to @email{internals@@lists.mysql.com}.
-This is a relatively low traffic list, in comparison with
-@email{mysql@@lists.mysql.com}.
-
-@menu
-* MySQL threads:: MySQL threads
-* MySQL test suite:: MySQL test suite
-@end menu
-
-
-@node MySQL threads, MySQL test suite, MySQL internals, MySQL internals
-@subsection MySQL Threads
-
-The MySQL server creates the following threads:
-
-@itemize @bullet
-
-@item
-The TCP/IP connection thread handles all connection requests and
-creates a new dedicated thread to handle the authentication and
-and SQL query processing for each connection.
-
-@item
-On Windows NT there is a named pipe handler thread that does the same work as
-the TCP/IP connection thread on named pipe connect requests.
-
-@item
-The signal thread handles all signals. This thread also normally handles
-alarms and calls @code{process_alarm()} to force timeouts on connections
-that have been idle too long.
-
-@item
-If @code{mysqld} is compiled with @code{-DUSE_ALARM_THREAD}, a dedicated
-thread that handles alarms is created. This is only used on some systems where
-there are problems with @code{sigwait()} or if one wants to use the
-@code{thr_alarm()} code in ones application without a dedicated signal
-handling thread.
-
-@item
-If one uses the @code{--flush_time=#} option, a dedicated thread is created
-to flush all tables at the given interval.
-
-@item
-Every connection has its own thread.
-
-@item
-Every different table on which one uses @code{INSERT DELAYED} gets its
-own thread.
-
-@item
-If you use @code{--master-host}, a slave replication thread will be
-started to read and apply updates from the master.
-@end itemize
-
-@code{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED},
-and replication threads.
-
-
-@node MySQL test suite, , MySQL threads, MySQL internals
-@subsection MySQL Test Suite
-
-@cindex mysqltest, MySQL Test Suite
-@cindex testing mysqld, mysqltest
-
-Until recently, our main full-coverage test suite was based on proprietary
-customer data and for that reason has not been publicly available. The only
-publicly available part of our testing process consisted of the @code{crash-me}
-test, a Perl DBI/DBD benchmark found in the @code{sql-bench} directory, and
-miscellaneous tests located in @code{tests} directory. The lack of a
-standardized publicly available test suite has made it difficult for our users,
-as well developers, to do regression tests on the MySQL code. To
-address this problem, we have created a new test system that is included in
-the source and binary distributions starting in Version 3.23.29.
-
-The current set of test cases doesn't test everything in MySQL, but it
-should catch most obvious bugs in the SQL processing code, OS/library
-issues, and is quite thorough in testing replication. Our eventual goal
-is to have the tests cover 100% of the code. We welcome contributions
-to our test suite. You may especially want to contribute tests that
-examine the functionality critical to your system, as this will ensure
-that all future MySQL releases will work well with your
-applications.
-
-@menu
-* running mysqltest:: Running the MySQL Test Suite
-* extending mysqltest:: Extending the MySQL Test Suite
-* Reporting mysqltest bugs:: Reporting Bugs in the MySQL Test Suite
-@end menu
-
-
-@node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite
-@subsubsection Running the MySQL Test Suite
-
-The test system consist of a test language interpreter
-(@code{mysqltest}), a shell script to run all
-tests(@code{mysql-test-run}), the actual test cases written in a special
-test language, and their expected results. To run the test suite on
-your system after a build, type @code{make test} or
-@code{mysql-test/mysql-test-run} from the source root. If you have
-installed a binary distribution, @code{cd} to the install root
-(eg. @code{/usr/local/mysql}), and do @code{scripts/mysql-test-run}.
-All tests should succeed. If not, you should try to find out why and
-report the problem if this is a bug in MySQL.
-@xref{Reporting mysqltest bugs}.
-
-If you have a copy of @code{mysqld} running on the machine where you want to
-run the test suite you do not have to stop it, as long as it is not using
-ports @code{9306} and @code{9307}. If one of those ports is taken, you should
-edit @code{mysql-test-run} and change the values of the master and/or slave
-port to one that is available.
-
-You can run one individual test case with
-@code{mysql-test/mysql-test-run test_name}.
-
-If one test fails, you should test running @code{mysql-test-run} with
-the @code{--force} option to check if any other tests fails.
-
-
-@node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite
-@subsubsection Extending the MySQL Test Suite
-
-You can use the @code{mysqltest} language to write your own test cases.
-Unfortunately, we have not yet written full documentation for it - we plan to
-do this shortly. You can, however, look at our current test cases and use
-them as an example. The following points should help you get started:
-
-@itemize @bullet
-@item
-The tests are located in @code{mysql-test/t/*.test}
-
-@item
-A test case consists of @code{;} terminated statements and is similar to the
-input of @code{mysql} command line client. A statement by default is a query
-to be sent to MySQL server, unless it is recognized as internal
-command ( eg. @code{sleep} ).
-
-@item
-All queries that produce results, e.g. @code{SELECT}, @code{SHOW},
-@code{EXPLAIN}, etc., must be preceded with @code{@@/path/to/result/file}. The
-file must contain the expected results. An easy way to generate the result
-file is to run @code{mysqltest -r < t/test-case-name.test} from
-@code{mysql-test} directory, and then edit the generated result files, if
-needed, to adjust them to the expected output. In that case, be very careful
-about not adding or deleting any invisible characters - make sure to only
-change the text and/or delete lines. If you have to insert a line, make sure
-the fields are separated with a hard tab, and there is a hard tab at the end.
-You may want to use @code{od -c} to make sure your text editor has not messed
-anything up during edit. We, of course, hope that you will never have to edit
-the output of @code{mysqltest -r} as you only have to do it when you find a
-bug.
-
-@item
-To be consistent with our setup, you should put your result files in
-@code{mysql-test/r} directory and name them @code{test_name.result}. If the
-test produces more than one result, you should use @code{test_name.a.result},
-@code{test_name.b.result}, etc.
-
-@item
-If a statement returns an error, you should on the line before the statement
-specify with the @code{--error error-number}. The error number can be
-a list of possible error numbers separated with @code{','}.
-
-@item
-If you are writing a replication test case, you should on the first line of
-the test file, put @code{source include/master-slave.inc;}. To switch between
-master and slave, use @code{connection master;} and @code{connection slave;}.
-If you need to do something on an alternate connection, you can do
-@code{connection master1;} for the master, and @code{connection slave1;} for
-the slave.
-
-@item
-If you need to do something in a loop, you can use something like this:
-@example
-let $1=1000;
-while ($1)
-@{
- # do your queries here
- dec $1;
-@}
-@end example
-
-@item
-To sleep between queries, use the @code{sleep} command. It supports fractions
-of a second, so you can do @code{sleep 1.3;}, for example, to sleep 1.3
-seconds.
-
-@item
-To run the slave with additional options for your test case, put them
-in the command-line format in @code{mysql-test/t/test_name-slave.opt}. For
-the master, put them in @code{mysql-test/t/test_name-master.opt}.
-
-@item
-If you have a question about the test suite, or have a test case to contribute,
-e-mail to @email{internals@@lists.mysql.com}. As the list does not accept
-attachments, you should ftp all the relevant files to:
-@url{ftp://support.mysql.com/pub/mysql/Incoming}
-
-@end itemize
-
-
-@node Reporting mysqltest bugs, , extending mysqltest, MySQL test suite
-@subsubsection Reporting Bugs in the MySQL Test Suite
-
-If your MySQL version doesn't pass the test suite you should
-do the following:
-
-@itemize @bullet
-@item
-Don't send a bug report before you have found out as much as possible of
-what when wrong! When you do it, please use the @code{mysqlbug} script
-so that we can get information about your system and @code{MySQL}
-version. @xref{Bug reports}.
-@item
-Make sure to include the output of @code{mysql-test-run}, as well as
-contents of all @code{.reject} files in @code{mysql-test/r} directory.
-@item
-If a test in the test suite fails, check if the test fails also when run
-by its own:
-
-@example
-cd mysql-test
-mysql-test-run --local test-name
-@end example
-
-If this fails, then you should configure MySQL with
-@code{--with-debug} and run @code{mysql-test-run} with the
-@code{--debug} option. If this also fails send the trace file
-@file{var/tmp/master.trace} to ftp://support.mysql.com/pub/mysql/secret
-so that we can examine it. Please remember to also include a full
-description of your system, the version of the mysqld binary and how you
-compiled it.
-
-@item
-Try also to run @code{mysql-test-run} with the @code{--force} option to
-see if there is any other test that fails.
-
-@item
-If you have compiled MySQL yourself, check our manual for how
-to compile MySQL on your platform or, preferable, use one of
-the binaries we have compiled for you at
-@uref{http://www.mysql.com/downloads/}. All our standard binaries should
-pass the test suite !
-
-@item
-If you get an error, like @code{Result length mismatch} or @code{Result
-content mismatch} it means that the output of the test didn't match
-exactly the expected output. This could be a bug in MySQL or
-that your mysqld version produces slight different results under some
-circumstances.
-
-Failed test results are put in a file with the same base name as the
-result file with the @code{.reject} extension. If your test case is
-failing, you should do a diff on the two files. If you cannot see how
-they are different, examine both with @code{od -c} and also check their
-lengths.
-
-@item
-If a test fails totally, you should check the logs file in the
-@code{mysql-test/var/log} directory for hints of what went wrong.
-
-@item
-If you have compiled MySQL with debugging you can try to debug this
-by running @code{mysql-test-run} with the @code{--gdb} and/or @code{--debug}
-options.
-@xref{Making trace files}.
-
-If you have not compiled MySQL for debugging you should probably
-do that. Just specify the @code{--with-debug} options to @code{configure}!
-@xref{Installing source}.
-@end itemize
-
-
-
-
-@node Problems, Users, Extending MySQL, Top
+@node Problems, Contrib, Extending MySQL, Top
@appendix Problems and Common Errors
@cindex problems, common errors
@@ -43217,7 +46633,7 @@ do that. Just specify the @code{--with-debug} options to @code{configure}!
@menu
* What is crashing:: How to determine what is causing problems
-* Common errors:: Some common errors when using MySQL
+* Common errors:: Common Errors When Using MySQL
* Installation Issues:: Installation Related Issues
* Administration Issues:: Administration Related Issues
* Query Issues:: Query Related Issues
@@ -43254,7 +46670,7 @@ The machine doesn't answer to a remote machine's pings.
Different, unrelated programs don't behave correctly.
@item
If your system rebooted unexpectedly (a faulty user level program should
-NEVER be able to take down your system).
+@strong{never} be able to take down your system).
@end itemize
In this case you should start by checking all your cables and run some
@@ -43313,7 +46729,7 @@ If a program fails, it's always useful to know:
@item
Has the program in question made a segmentation fault (core dumped)?
@item
-Is the program taking the whole CPU? Check with @code{top}. Let the
+Is the program taking up the whole CPU? Check with @code{top}. Let the
program run for a while, it may be evaluating something heavy.
@item
If it's the @code{mysqld} server that is causing problems, can you
@@ -43329,7 +46745,7 @@ described in this manual. @xref{Asking questions}.
@node Common errors, Installation Issues, What is crashing, Problems
-@appendixsec Some Common Errors When Using MySQL
+@appendixsec Common Errors When Using MySQL
@cindex errors, list of
@@ -43348,12 +46764,12 @@ described in this manual. @xref{Asking questions}.
* Commands out of sync:: @code{Commands out of sync} error in client
* Ignoring user:: @code{Ignoring user} error
* Cannot find table:: @code{Table 'xxx' doesn't exist} error
-* Cannot initialize character set:: @code{Can@'t initialize character set xxx} error.
+* Cannot initialize character set:: @code{Can't initialize character set xxx} error
* Not enough file handles:: File Not Found
@end menu
-This section lists some errors that users frequently get. You will find
+This section lists some errors that users frequently get. You will find
descriptions of the errors, and how to solve the problem here.
@@ -43383,22 +46799,29 @@ Another common reason to receive the @code{MySQL server has gone away} error
is because you have issued a ``close'' on your MySQL connection
and then tried to run a query on the closed connection.
-You can check that the MySQL hasn't died by executing
-@code{mysqladmin version} and examining the uptime.
-
If you have a script, you just have to issue the query again for the client
to do an automatic reconnection.
You normally can get the following error codes in this case
(which one you get is OS-dependent):
-@multitable @columnfractions .3 .7
+@multitable @columnfractions .35 .65
+@item @strong{Error code} @tab @strong{Description}
@item @code{CR_SERVER_GONE_ERROR} @tab The client couldn't send a question to the
server.
@item @code{CR_SERVER_LOST} @tab The client didn't get an error when writing
to the server, but it didn't get a full answer (or any answer) to the question.
@end multitable
+You will also get this error if someone has kills the running thread with
+@code{kill #threadid#}.
+
+You can check that the MySQL hasn't died by executing @code{mysqladmin
+version} and examining the uptime. If the problem is that mysqld
+crashed you should concentrate one finding the reason for the crash.
+You should in this case start by checking if issuing the query again
+will kill MySQL again. @xref{Crashing}.
+
You can also get these errors if you send a query to the server that is
incorrect or too large. If @code{mysqld} gets a packet that is too large
or out of order, it assumes that something has gone wrong with the client and
@@ -43409,9 +46832,29 @@ starting @code{mysqld} with the @code{-O max_allowed_packet=#} option
use more memory only when you issue a big query or when @code{mysqld} must
return a big result row!
+If you want to make a bug report regarding this problem, be sure that
+you include the following information:
+
+@itemize @bullet
+@item
+Include information if MySQL died or not. (You can find this in the
+@code{hostname.err file}. @xref{Crashing}.
+@item
+If a specific query kills @code{mysqld} and the involved tables where
+checked with @code{CHECK TABLE} before you did the query, can you do
+a test case for this? @xref{Reproduceable test case}.
+@item
+What is the value of the @code{wait_timeout} variable in the MySQL server ?
+@code{mysqladmin variables} gives you the value of this
+@item
+Have you tried to run @code{mysqld} with @code{--log} and check if the
+issued query appears in the log ?
+@end itemize
+
+@xref{Asking questions}.
@node Can not connect to server, Blocked host, Gone away, Common errors
-@appendixsubsec @code{Can't connect to [local] MySQL server} error
+@appendixsubsec @code{Can't connect to [local] MySQL server} Error
A MySQL client on Unix can connect to the @code{mysqld} server in two
different ways: Unix sockets, which connect through a file in the file
@@ -43421,14 +46864,14 @@ be used when connecting to a server on the same computer. Unix sockets
are used if you don't specify a hostname or if you specify the special
hostname @code{localhost}.
-On Windows you can connect only with TCP/IP if the @code{mysqld} server
-is running on Win95/Win98. If mysqld is running on NT and started with
-@code{enable-named-pipe}, you can also connect with named pipes. The
-name of the named pipe is MySQL. If you don't give a hostname when
-connecting to @code{mysqld}, a MySQL client will first try to connect to
-the named pipe, and if this doesn't work it will connect to the TCP/IP
-port. You can force the use of named pipes on Windows by using @code{.}
-as the hostname.
+On Windows, if the @code{mysqld} server is running on 9x/Me, you can
+connect only via TCP/IP. If the server is running on NT/2000/XP and
+mysqld is started with @code{--enable-named-pipe}, you
+can also connect with named pipes. The name of the named pipe is MySQL.
+If you don't give a hostname when connecting to @code{mysqld}, a MySQL
+client will first try to connect to the named pipe, and if this doesn't
+work it will connect to the TCP/IP port. You can force the use of named
+pipes on Windows by using @code{.} as the hostname.
The error (2002) @code{Can't connect to ...} normally means that there
isn't a MySQL server running on the system or that you are
@@ -43467,7 +46910,7 @@ error might occur:
You are running on a system that uses MIT-pthreads.
If you are running on a system that doesn't have native threads,
@code{mysqld} uses the MIT-pthreads package. @xref{Which OS}. However,
-all MIT-pthreads versions doesn't support Unix sockets. On a system
+not all MIT-pthreads versions support Unix sockets. On a system
without sockets support you must always specify the hostname explicitly
when connecting to the server. Try using this command to check the
connection to the server:
@@ -43508,7 +46951,7 @@ problem is :
@itemize @bullet
@item
Check if the server is up by doing @code{telnet your-host-name
-tcp-ip-port-number} and press @code{RETURN} a couple of times. If there
+tcp-ip-port-number} and press Enter a couple of times. If there
is a MySQL server running on this port you should get a
responses that includes the version number of the running MySQL
server. If you get an error like @code{telnet: Unable to connect to
@@ -43566,7 +47009,7 @@ If you need more connections than the default (100), then you should restart
Note that @code{mysqld} actually allows (@code{max_connections}+1)
clients to connect. The last connection is reserved for a user with the
-@strong{process} privilege. By not giving this privilege to normal
+@code{SUPER} privilege. By not giving this privilege to normal
users (they shouldn't need this), an administrator with this privilege
can log in and use @code{SHOW PROCESSLIST} to find out what could be
wrong. @xref{SHOW}.
@@ -43633,16 +47076,36 @@ When a MySQL client or the @code{mysqld} server gets a packet bigger
than @code{max_allowed_packet} bytes, it issues a @code{Packet too large}
error and closes the connection.
-If you are using the @code{mysql} client, you may specify a bigger buffer by
-starting the client with @code{mysql --set-variable=max_allowed_packet=8M}.
+In MySQL 3.23 the biggest possible packet is 16M (due to limits in the
+client/server protocol). In MySQL 4.0.1 and up, this is only limited by
+the amount on memory you have on your server (up to a theoretical
+maximum of 2G).
-If you are using other clients that do not allow you to specify the maximum
-packet size (such as @code{DBI}), you need to set the packet size when you
-start the server. You cau use a command-line option to @code{mysqld} to set
-@code{max_allowed_packet} to a larger size. For example, if you are
-expecting to store the full length of a @code{BLOB} into a table, you'll need
-to start the server with the @code{--set-variable=max_allowed_packet=16M}
-option.
+A communication packet is a single SQL statement sent to the MySQL server
+or a single row that is sent to the client.
+
+When a MySQL client or the @code{mysqld} server gets a packet bigger
+than @code{max_allowed_packet} bytes, it issues a @code{Packet too
+large} error and closes the connection. With some clients, you may also
+get @code{Lost connection to MySQL server during query} error if the
+communication packet is too big.
+
+Note that both the client and the server has it's own
+@code{max_allowed_packet} variable. If you want to handle big packets,
+you have to increase this variable both in the client and in the server.
+
+It's safe to increase this variable as memory is only allocated when
+needed; this variable is more a precaution to catch wrong packets
+between the client/server and also to ensure that you don't accidently
+use big packets so that you run out of memory.
+
+If you are using the @code{mysql} client, you may specify a bigger
+buffer by starting the client with @code{mysql --set-variable=max_allowed_packet=8M}. Other clients have different methods to set this variable.
+
+You can use the option file to set @code{max_allowed_packet} to a larger
+size in @code{mysqld}. For example, if you are expecting to store the
+full length of a @code{MEDIUMBLOB} into a table, you'll need to start
+the server with the @code{set-variable=max_allowed_packet=16M} option.
You can also get strange problems with large packets if you are using
big blobs, but you haven't given @code{mysqld} access to enough memory
@@ -43731,19 +47194,51 @@ than you have alloacated for @code{mysqld}. @xref{Packet too large}.
@cindex table is full
-This error occurs in older MySQL versions when an in-memory temporary
-table becomes larger than @code{tmp_table_size} bytes. To avoid this
-problem, you can use the @code{-O tmp_table_size=#} option to
-@code{mysqld} to increase the temporary table size or use the SQL
-option @code{SQL_BIG_TABLES} before you issue the problematic
-query. @xref{SET OPTION, , @code{SET OPTION}}.
+There is a couple of different cases when you can get this error:
+
+@itemize @bullet
+@item
+You are using an older MySQL version (before 3.23.0) when an in-memory
+temporary table becomes larger than @code{tmp_table_size} bytes.
+To avoid this problem, you can use the @code{-O tmp_table_size=#} option
+to make @code{mysqld} increase the temporary table size or use the SQL
+option @code{BIG_TABLES} before you issue the problematic query.
+@xref{SET OPTION, ,@code{SET}}.
You can also start @code{mysqld} with the @code{--big-tables} option.
-This is exactly the same as using @code{SQL_BIG_TABLES} for all queries.
+This is exactly the same as using @code{BIG_TABLES} for all queries.
In MySQL Version 3.23, in-memory temporary tables will automatically be
converted to a disk-based @code{MyISAM} table after the table size gets
bigger than @code{tmp_table_size}.
+@item
+You are using @code{InnoDB} tables and run out of room in the
+@code{InnoDB} tablespace. In this case the solution is to extend the
+@code{InnoDB} tablespace.
+@item
+You are using @code{ISAM} or @code{MyISAM} tables on an OS that only
+supports files of 2G in size and you have hit this limit for the data
+or index file.
+@item
+You are using @code{MyISAM} tables and the needed data or index size is
+bigger than what MySQL has allocated pointers for. (If you don't specify
+@code{MAX_ROWS} to @code{CREATE TABLE} MySQL will only allocate pointers
+to hold 4G of data).
+
+You can check the maximum data/index sizes by doing
+@example
+SHOW TABLE STATUS FROM database LIKE 'table_name';
+@end example
+or using @code{myisamchk -dv database/table_name}.
+
+If this is the problem, you can fix it by doing something like:
+@example
+ALTER TABLE table_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;
+@end example
+You only have to specify @code{AVG_ROW_LENGTH} for tables with BLOB/TEXT
+fields as in this case MySQL can't optimise the space required based
+only on the number of rows.
+@end itemize
@node Cannot create, Commands out of sync, Full table, Common errors
@@ -43784,7 +47279,7 @@ Error code 28: No space left on device
@cindex commands out of sync
-If you get @code{Commands out of sync; You can't run this command now}
+If you get @code{Commands out of sync; you can't run this command now}
in your client code, you are calling client functions in the wrong order!
This can happen, for example, if you are using @code{mysql_use_result()} and
@@ -43798,7 +47293,7 @@ a @code{mysql_use_result()} or @code{mysql_store_result()} in between.
If you get the following error:
-@code{Found wrong password for user: 'some_user@@some_host'; Ignoring user}
+@code{Found wrong password for user: 'some_user@@some_host'; ignoring user}
this means that when @code{mysqld} was started or when it reloaded the
permissions tables, it found an entry in the @code{user} table with
@@ -43829,8 +47324,8 @@ You have specified a password in the @code{user} table without using the
function:
@example
-mysql> update user set password=PASSWORD('your password')
- where user='XXX';
+mysql> UPDATE user SET password=PASSWORD('your password')
+ -> WHERE user='XXX';
@end example
@end itemize
@@ -43843,8 +47338,8 @@ find file: 'xxx' (errno: 2)}, this means that no table exists
in the current database with the name @code{xxx}.
Note that as MySQL uses directories and files to store databases and
-tables, the database and table names are @strong{case sensitive}!
-(On Windows the databases and tables names are not case sensitive, but all
+tables, the database and table names are @strong{case-sensitive}!
+(On Windows the databases and tables names are not case-sensitive, but all
references to a given table within a query must use the same case!)
You can check which tables you have in the current database with
@@ -43852,7 +47347,7 @@ You can check which tables you have in the current database with
@node Cannot initialize character set, Not enough file handles, Cannot find table, Common errors
-@appendixsubsec @code{Can@'t initialize character set xxx} error.
+@appendixsubsec @code{Can't initialize character set xxx} error
@cindex multibyte character sets
@@ -43866,7 +47361,7 @@ This means one of the following things:
@itemize @bullet
@item
-The character set is a multi-byte character set and you have not support
+The character set is a multi-byte character set and you have no support
for the character set in the client.
In this case you need to recompile the client with
@@ -43879,8 +47374,8 @@ all multi-byte character sets. @xref{Character sets}.
@item
The character set is a simple character set which is not compiled into
-@code{mysqld} and the character set definition files is not in the place
-where the client expect to find them.
+@code{mysqld} and the character set definition files are not in the place
+where the client expects to find them.
In this case you need to:
@@ -43890,10 +47385,10 @@ Recompile the client with support for the character set.
@xref{configure options}.
@item
Specify to the client where the character set definition files are. For many
-client you can do this with the
+clients you can do this with the
@code{--character-sets-dir=path-to-charset-dir} option.
@item
-Copy the character definition files to the path where the client expect them
+Copy the character definition files to the path where the client expects them
to be.
@end itemize
@end itemize
@@ -43944,8 +47439,8 @@ number 256 to affect the number of file descriptors available to
@code{ulimit} (and @code{open-files-limit}) can increase the number of
file descriptors, but only up to the limit imposed by the operating
system. There is also a 'hard' limit that can only be overrided if you
-start @code{safe_mysqld} or @code{mysqld} as root (Just remember that
-you need to also use the @code{--user=..} option in this case). If you
+start @code{safe_mysqld} or @code{mysqld} as root (just remember that
+you need to also use the @code{--user=...} option in this case). If you
need to increase the OS limit on the number of file descriptors
available to each process, consult the documentation for your operating
system.
@@ -43985,10 +47480,10 @@ symbols that start with @code{mysql_}, like the following:
@end example
you should be able to solve this by adding @code{-Lpath-to-the-mysql-library
--lmysqlclient} @strong{LAST} on your link line.
+-lmysqlclient} @strong{last} on your link line.
If you get @code{undefined reference} errors for the @code{uncompress}
-or @code{compress} function, add @code{-lz} @strong{LAST} on your link
+or @code{compress} function, add @code{-lz} @strong{last} on your link
line and try again!
If you get @code{undefined reference} errors for functions that should
@@ -44004,7 +47499,7 @@ mf_format.o(.text+0x201): undefined reference to `__lxstat'
@end example
it usually means that your library is compiled on a system that is not
-100 % compatible with yours. In this case you should download the
+100% compatible with yours. In this case you should download the
latest MySQL source distribution and compile this yourself.
@xref{Installing source}.
@@ -44093,7 +47588,7 @@ as a Unix user other than @code{root}; just specify the @code{-u root} option
to the client program.
Note that accessing MySQL as @code{root}, by supplying @code{-u
-root} on the command line, has @emph{nothing} to do with MySQL running
+root} on the command-line, has @strong{nothing} to do with MySQL running
as the Unix @code{root} user, or, indeed, as another Unix user. The access
permissions and user names of MySQL are completely separate from
Unix user names. The only connection with Unix user names is that if you
@@ -44125,7 +47620,7 @@ ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)
@tindex Environment variable, UMASK
then the environment variable @code{UMASK} might be set incorrectly when
@code{mysqld} starts up. The default umask value is @code{0660}. You can
-change this behavior by starting @code{safe_mysqld} as follows:
+change this behaviour by starting @code{safe_mysqld} as follows:
@example
shell> UMASK=384 # = 600 in octal
@@ -44136,7 +47631,7 @@ shell> /path/to/safe_mysqld &
@tindex UMASK_DIR environment variable
@tindex Environment variable, UMASK_DIR
By default MySQL will create database and @code{RAID}
-directories with permission type 0700. You can modify this behavior by
+directories with permission type 0700. You can modify this behaviour by
setting the @code{UMASK_DIR} variable. If you set this, new
directories are created with the combined @code{UMASK} and
@code{UMASK_DIR}. For example, if you want to give group access to
@@ -44161,7 +47656,7 @@ with a zero.
@menu
* Crashing:: What To Do If MySQL Keeps Crashing
-* Resetting permissions:: How to Reset a Forgotten Password
+* Resetting permissions:: How to Reset a Forgotten Root Password
* Full disk:: How MySQL Handles a Full Disk
* Temporary files:: Where MySQL Stores Temporary Files
* Problems with mysql.sock:: How to Protect @file{/tmp/mysql.sock} from Being Deleted
@@ -44191,7 +47686,7 @@ Many crashes of MySQL are caused by corrupted index / data
files. MySQL will update the data on disk, with the
@code{write()} system call, after every SQL statement and before the
client is notified about the result. (This is not true if you are running
-with @code{delayed_key_writes}, in which case only the data is written.)
+with @code{delay_key_write}, in which case only the data is written.)
This means that the data is safe even if @code{mysqld} crashes, as the OS will
ensure that the not flushed data is written to disk. You can force
MySQL to sync everything to disk after every SQL command by
@@ -44211,11 +47706,11 @@ Someone is manipulating the data/index files outside of @strong{mysqld}
without locking the table properly.
@item
If you are running many @code{mysqld} servers on the same data on a
-system that doesn't support good file system locks (normally handled by
+system that doesn't support good filesystem locks (normally handled by
the @code{lockd} daemon ) or if you are running
-multiple servers with @code{--skip-locking}
+multiple servers with @code{--skip-external-locking}
@item
-You have a crashed index/data file that contains very wrong data that
+You have a crashed index/datafile that contains very wrong data that
got @code{mysqld} confused.
@item
You have found a bug in the data storage code. This isn't that likely,
@@ -44225,11 +47720,16 @@ repaired copy of the table!
@end itemize
Because it is very difficult to know why something is crashing, first try to
-check whether or not things that work for others crash for you. Please try
+check whether things that work for others crash for you. Please try
the following things:
@itemize @bullet
@item
+Cleaned up @code{NULL} handling for default values in @code{DESCRIBE
+table_name}.
+@item
+Fixed @code{truncate()} to round up negative values to the nearest integer.
+@item
Take down the @code{mysqld} daemon with @code{mysqladmin shutdown}, run
@code{myisamchk --silent --force */*.MYI} on all tables, and restart the
@code{mysqld} daemon. This will ensure that you are running from a clean
@@ -44237,7 +47737,7 @@ state. @xref{MySQL Database Administration}.
@item
Use @code{mysqld --log} and try to determine from the information in the log
-whether or not some specific query kills the server. About 95% of all bugs are
+whether some specific query kills the server. About 95% of all bugs are
related to a particular query! Normally this is one of the last queries in
the log file just before MySQL restarted. @xref{Query log}.
If you can repeatadly kill MySQL with one of the queries, even
@@ -44277,12 +47777,12 @@ what is happening.
Have you applied the latest patches for your operating system?
@item
-Use the @code{--skip-locking} option to @code{mysqld}. On some systems, the
-@code{lockd} lock manager does not work properly; the @code{--skip-locking}
-option tells @code{mysqld} not to use external locking. (This means that you
-cannot run 2 @code{mysqld} servers on the same data and that you must be
-careful if you use @code{myisamchk}, but it may be instructive to try the
-option as a test.)
+Use the @code{--skip-external-locking} option to @code{mysqld}. On some
+systems, the @code{lockd} lock manager does not work properly; the
+@code{--skip-external-locking} option tells @code{mysqld} not to use external
+locking. (This means that you cannot run 2 @code{mysqld} servers on the same
+data and that you must be careful if you use @code{myisamchk}, but it may be
+instructive to try the option as a test.)
@item
Have you tried @code{mysqladmin -u root processlist} when @code{mysqld}
@@ -44352,43 +47852,68 @@ it helps!
@node Resetting permissions, Full disk, Crashing, Administration Issues
-@appendixsubsec How to Reset a Forgotten Password
+@appendixsubsec How to Reset a Forgotten Root Password
@cindex passwords, forgotten
@cindex passwords, resetting
@cindex root user, password resetting
-If you have forgotten the @code{root} user password for MySQL, you
-can restore it with the following procedure:
+If you never set a @code{root} password for MySQL, then the server will
+not require a password at all for connecting as @code{root}. It is
+recommended to always set a password for each user. @xref{Security}.
+
+If you have set a @code{root} password, but forgot what it was, you can
+set a new password with the following procedure:
@enumerate
@item
Take down the @code{mysqld} server by sending a @code{kill} (not @code{kill
--9}) to the @code{mysqld} server. The pid is stored in a @code{.pid}
+-9}) to the @code{mysqld} server. The pid is stored in a @file{.pid}
file, which is normally in the MySQL database directory:
-
@example
-kill `cat /mysql-data-directory/hostname.pid`
+shell> kill `cat /mysql-data-directory/hostname.pid`
@end example
-
-You must be either the Unix @code{root} user or the same user the server
+You must be either the Unix @code{root} user or the same user @code{mysqld}
runs as to do this.
-
@item
Restart @code{mysqld} with the @code{--skip-grant-tables} option.
@item
-Connect to the @code{mysqld} server with @code{mysql -h hostname mysql} and change
-the password with a @code{GRANT} command. @xref{GRANT,,@code{GRANT}}.
-You can also do this with
-@code{mysqladmin -h hostname -u user password 'new password'}
+Set a new password with the @code{mysqladmin password} command:
+@example
+shell> mysqladmin -u root password 'mynewpassword'
+@end example
@item
-Load the privilege tables with: @code{mysqladmin -h hostname
-flush-privileges} or with the SQL command @code{FLUSH PRIVILEGES}.
+Now you can either stop @code{mysqld} and restart it normally,
+or just load the privilege tables with:
+@example
+shell> mysqladmin -h hostname flush-privileges
+@end example
+@item
+After this, you should be able to connect using the new password.
@end enumerate
-Note that after you started @code{mysqld} with @code{--skip-grant-tables},
-any usage of @code{GRANT} commands will give you an @code{Unknown command}
-error until you have executed @code{FLUSH PRIVILEGES}.
+Alternatively, you can set the new password using the @code{mysql} client:
+@enumerate
+@item
+Take down and restart @code{mysqld} with the @code{--skip-grant-tables}
+option as described above.
+@item
+Connect to the @code{mysqld} server with:
+@example
+shell> mysql -u root mysql
+@end example
+@item
+Issue the following commands in the @code{mysql} client:
+@example
+mysql> UPDATE user SET Password=PASSWORD('mynewpassword')
+ -> WHERE User='root';
+mysql> FLUSH PRIVILEGES;
+@end example
+@item
+After this, you should be able to connect using the new password.
+@item
+You can now stop @code{mysqld} and restart it normally.
+@end enumerate
@node Full disk, Temporary files, Resetting permissions, Administration Issues
@@ -44402,7 +47927,7 @@ When a disk-full condition occurs, MySQL does the following:
@itemize @bullet
@item
-It checks once every minute to see whether or not there is enough space to
+It checks once every minute to see whether there is enough space to
write the current row. If there is enough space, it continues as if nothing had
happened.
@item
@@ -44444,16 +47969,16 @@ unchanged).
MySQL uses the value of the @code{TMPDIR} environment variable as
the pathname of the directory in which to store temporary files. If you don't
have @code{TMPDIR} set, MySQL uses the system default, which is
-normally @file{/tmp} or @file{/usr/tmp}. If the file system containing your
+normally @file{/tmp} or @file{/usr/tmp}. If the filesystem containing your
temporary file directory is too small, you should edit @code{safe_mysqld} to
-set @code{TMPDIR} to point to a directory in a file system where you have
+set @code{TMPDIR} to point to a directory in a filesystem where you have
enough space! You can also set the temporary directory using the
@code{--tmpdir} option to @code{mysqld}.
MySQL creates all temporary files as hidden files. This ensures
that the temporary files will be removed if @code{mysqld} is terminated. The
disadvantage of using hidden files is that you will not see a big temporary
-file that fills up the file system in which the temporary file directory is
+file that fills up the filesystem in which the temporary file directory is
located.
When sorting (@code{ORDER BY} or @code{GROUP BY}), MySQL normally
@@ -44476,21 +48001,21 @@ the original table.
@node Problems with mysql.sock, Timezone problems, Temporary files, Administration Issues
-@appendixsubsec How to Protect or change the MySQL socket file @file{/tmp/mysql.sock}
+@appendixsubsec How to Protect or Change the MySQL Socket File @file{/tmp/mysql.sock}
@cindex @code{mysql.sock}, protection
@cindex deletion, @code{mysql.sock}
If you have problems with the fact that anyone can delete the
MySQL communication socket @file{/tmp/mysql.sock}, you can,
-on most versions of Unix, protect your @file{/tmp} file system by setting
+on most versions of Unix, protect your @file{/tmp} filesystem by setting
the @code{sticky} bit on it. Log in as @code{root} and do the following:
@example
shell> chmod +t /tmp
@end example
-This will protect your @file{/tmp} file system so that files can be deleted
+This will protect your @file{/tmp} filesystem so that files can be deleted
only by their owners or the superuser (@code{root}).
You can check if the @code{sticky} bit is set by executing @code{ls -ld /tmp}.
@@ -44515,7 +48040,7 @@ socket=path-for-socket-file
@end example
@xref{Option files}.
@item
-Specifying this on the command line to @code{safe_mysqld} and most
+Specifying this on the command-line to @code{safe_mysqld} and most
clients with the @code{--socket=path-for-socket-file} option.
@item
Specify the path to the socket in the @code{MYSQL_UNIX_PORT} environment
@@ -44552,24 +48077,25 @@ the server runs, for example, in @code{safe_mysqld} or @code{mysql.server}.
@menu
-* Case sensitivity:: Case Sensitivity in Searches
+* Case sensitivity:: Case-Sensitivity in Searches
* Using DATE:: Problems Using @code{DATE} Columns
* Problems with NULL:: Problems with @code{NULL} Values
* Problems with alias:: Problems with @code{alias}
* Deleting from related tables:: Deleting Rows from Related Tables
* No matching rows:: Solving Problems with No Matching Rows
+* Problems with float:: Problems with floating-point comparison
@end menu
@node Case sensitivity, Using DATE, Query Issues, Query Issues
-@appendixsubsec Case Sensitivity in Searches
+@appendixsubsec Case-Sensitivity in Searches
-@cindex case sensitivity, in searches
+@cindex case-sensitivity, in searches
@cindex searching, and case-sensitivity
@cindex Chinese
@cindex Big5 Chinese character encoding
By default, MySQL searches are case-insensitive (although there are
-some character sets that are never case insensitive, such as @code{czech}).
+some character sets that are never case-insensitive, such as @code{czech}).
That means that if you search with @code{col_name LIKE 'a%'}, you will get all
column values that start with @code{A} or @code{a}. If you want to make this
search case-sensitive, use something like @code{INSTR(col_name, "A")=1} to
@@ -44622,8 +48148,8 @@ makes sense as a date.
The special date @code{'0000-00-00'} can be stored and retrieved as
@code{'0000-00-00'.} When using a @code{'0000-00-00'} date through
-@strong{MyODBC}, it will automatically be converted to @code{NULL} in
-@strong{MyODBC} Version 2.50.12 and above, because ODBC can't handle this kind of
+@code{MyODBC}, it will automatically be converted to @code{NULL} in
+@code{MyODBC} Version 2.50.12 and above, because ODBC can't handle this kind of
date.
Because MySQL performs the conversions described above, the following
@@ -44639,7 +48165,7 @@ mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00');
mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505;
-mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
+mysql> SELECT MOD(idate,100) FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505';
@end example
@@ -44654,7 +48180,7 @@ mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;
a string and performs a string comparison. It does not convert
@code{'19970505'} to a date and perform a date comparison.
-Note that MySQL does no checking whether or not the date is
+Note that MySQL does no checking whether the date is
correct. If you store an incorrect date, such as @code{'1998-2-31'}, the
wrong date will be stored. If the date cannot be converted to any reasonable
value, a @code{0} is stored in the @code{DATE} field. This is mainly a speed
@@ -44671,7 +48197,7 @@ the server.
The concept of the @code{NULL} value is a common source of confusion for
newcomers to SQL, who often think that @code{NULL} is the same thing as an
-empty string @code{''}. This is not the case! For example, the following
+empty string @code{""}. This is not the case! For example, the following
statements are completely different:
@example
@@ -44711,10 +48237,12 @@ mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = "";
@end example
-In MySQL, as in many other SQL servers, you can't index
-columns that can have @code{NULL} values. You must declare such columns
-@code{NOT NULL}. Conversely, you cannot insert @code{NULL} into an indexed
-column.
+Note that you can only add an index on a column that can have @code{NULL}
+values if you are using MySQL Version 3.23.2 or newer and are using the
+@code{MyISAM} or @code{InnoDB} table type.
+In earlier versions and with other table types, you must declare such
+columns @code{NOT NULL}. This also means you cannot then insert
+@code{NULL} into an indexed column.
@findex LOAD DATA INFILE
When reading data with @code{LOAD DATA INFILE}, empty columns are updated
@@ -44777,9 +48305,9 @@ decide which rows from the result set should be used.
@cindex rows, deleting
@cindex tables, deleting rows
-As MySQL doesn't support sub-selects or use of more than one table
-in the @code{DELETE} statement, you should use the following approach to
-delete rows from 2 related tables:
+As MySQL doesn't yet support subselects, nor the use of more than one
+table in the @code{DELETE} statement (prior to Version 4.0), you should
+use the following approach to delete rows from 2 related tables:
@enumerate
@item
@@ -44800,7 +48328,7 @@ id's per query if the @code{related_column} is an index. If the
number of arguments in the @code{IN} clause.
-@node No matching rows, , Deleting from related tables, Query Issues
+@node No matching rows, Problems with float, Deleting from related tables, Query Issues
@appendixsubsec Solving Problems with No Matching Rows
@cindex no matching rows
@@ -44828,16 +48356,10 @@ the table that was last removed from the query.
@item
If you are comparing @code{FLOAT} or @code{DOUBLE} columns with numbers that
-have decimals, you can't use @code{=}! This problem is common in most
-computer languages because floating-point values are not exact values:
-
-@example
-mysql> SELECT * FROM table_name WHERE float_column=3.5;
- ->
-mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;
-@end example
-
-In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this!
+have decimals, you can't use @code{'='}. This problem is common in most
+computer languages because floating-point values are not exact values.
+In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this.
+@xref{Problems with float}.
@item
If you still can't figure out what's wrong, create a minimal test that can
@@ -44855,6 +48377,134 @@ shell> mysql test2 < query.sql
Post the test file using @code{mysqlbug} to @email{mysql@@lists.mysql.com}.
@end enumerate
+@node Problems with float, , No matching rows, Query Issues
+@appendixsubsec Problems with Floating-Point Comparison
+
+floating-point numbers cause confusion sometimes, because these numbers
+are not stored as exact values inside computer architecture. What one
+can see on the screen usually is not the exact value of the number.
+
+Field types @code{FLOAT}, @code{DOUBLE} and @code{DECIMAL} are such.
+
+@example
+CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2));
+INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
+(2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
+(2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
+(4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
+(5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
+(6, 0.00, 0.00), (6, -51.40, 0.00);
+
+mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b
+ -> FROM t1 GROUP BY i HAVING a <> b;
++------+--------+-------+
+| i | a | b |
++------+--------+-------+
+| 1 | 21.40 | 21.40 |
+| 2 | 76.80 | 76.80 |
+| 3 | 7.40 | 7.40 |
+| 4 | 15.40 | 15.40 |
+| 5 | 7.20 | 7.20 |
+| 6 | -51.40 | 0.00 |
++------+--------+-------+
+@end example
+
+The result is correct. Although the first five records look like they
+shouldn't pass the comparison test, they may do so because the
+difference between the numbers show up around tenth decimal, or so
+depending on computer architecture.
+
+The problem cannot be solved by using ROUND() (or similar function),
+because the result is still a floating-point number. Example:
+
+@example
+mysql> SELECT i, ROUND(SUM(d1), 2) AS a, ROUND(SUM(d2), 2) AS b
+ -> FROM t1 GROUP BY i HAVING a <> b;
++------+--------+-------+
+| i | a | b |
++------+--------+-------+
+| 1 | 21.40 | 21.40 |
+| 2 | 76.80 | 76.80 |
+| 3 | 7.40 | 7.40 |
+| 4 | 15.40 | 15.40 |
+| 5 | 7.20 | 7.20 |
+| 6 | -51.40 | 0.00 |
++------+--------+-------+
+@end example
+
+This is what the numbers in row 'a' look like:
+@example
+mysql> SELECT i, ROUND(SUM(d1), 2)*1.0000000000000000 AS a,
+ -> ROUND(SUM(d2), 2) AS b FROM t1 GROUP BY i HAVING a <> b;
++------+----------------------+-------+
+| i | a | b |
++------+----------------------+-------+
+| 1 | 21.3999999999999986 | 21.40 |
+| 2 | 76.7999999999999972 | 76.80 |
+| 3 | 7.4000000000000004 | 7.40 |
+| 4 | 15.4000000000000004 | 15.40 |
+| 5 | 7.2000000000000002 | 7.20 |
+| 6 | -51.3999999999999986 | 0.00 |
++------+----------------------+-------+
+@end example
+
+Depending on the computer architecture you may or may not see similar results.
+Each CPU may evaluate floating-point numbers differently. For example in
+some machines you may get 'right' results by multiplaying both arguments
+with 1, an example follows.
+
+@strong{WARNING: NEVER TRUST THIS METHOD IN YOUR APPLICATION, THIS IS
+AN EXAMPLE OF A WRONG METHOD!!!}
+
+@example
+mysql> SELECT i, ROUND(SUM(d1), 2)*1 AS a, ROUND(SUM(d2), 2)*1 AS b
+ -> FROM t1 GROUP BY i HAVING a <> b;
++------+--------+------+
+| i | a | b |
++------+--------+------+
+| 6 | -51.40 | 0.00 |
++------+--------+------+
+@end example
+
+The reason why the above example seems to be working is that on the
+particular machine where the test was done, the CPU floating-point
+arithmetics happens to round the numbers to same, but there is no
+rule that any CPU should do so, so it cannot be trusted.
+
+The correct way to do floating-point number comparison is to first
+decide on what is the wanted tolerance between the numbers and then do
+the comparsion against the tolerance number. For example, if we agree on
+that floating-point numbers should be regarded the same, if they are
+same with precision of one of ten thousand (0.0001), the comparsion
+should be done like this:
+
+@example
+mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
+ -> GROUP BY i HAVING ABS(a - b) > 0.0001;
++------+--------+------+
+| i | a | b |
++------+--------+------+
+| 6 | -51.40 | 0.00 |
++------+--------+------+
+1 row in set (0.00 sec)
+@end example
+
+And vice versa, if we wanted to get rows where the numbers are the same,
+the test would be:
+
+@example
+mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
+ -> GROUP BY i HAVING ABS(a - b) < 0.0001;
++------+-------+-------+
+| i | a | b |
++------+-------+-------+
+| 1 | 21.40 | 21.40 |
+| 2 | 76.80 | 76.80 |
+| 3 | 7.40 | 7.40 |
+| 4 | 15.40 | 15.40 |
+| 5 | 7.20 | 7.20 |
++------+-------+-------+
+@end example
@node Table Definition Issues, , Query Issues, Problems
@appendixsec Table Definition Related Issues
@@ -44929,9 +48579,9 @@ SELECT col_name1, col_name3, col_name2 FROM tbl_name;
will return columns in the order @code{col_name1}, @code{col_name3}, @code{col_name2}.
-You should @strong{NEVER}, in an application, use @code{SELECT *} and
+You should @strong{never}, in an application, use @code{SELECT *} and
retrieve the columns based on their position, because the order in which
-columns are returned @strong{CANNOT} be guaranteed over time. A simple
+columns are returned @strong{cannot} be guaranteed over time. A simple
change to your database may cause your application to fail rather
dramatically.
@@ -44959,14 +48609,14 @@ The following are a list of the limitations with @code{TEMPORARY TABLES}.
@itemize @bullet
@item
-A temporary table can only be of type @code{HEAP}, @code{ISAM} or
-@code{MyISAM}.
+A temporary table can only be of type @code{HEAP}, @code{ISAM},
+@code{MyISAM} or @code{InnoDB}.
@item
You can't use temporary tables more than once in the same query.
For example, the following doesn't work.
@example
-select * from temporary_table, temporary_table as t2;
+mysql> SELECT * FROM temporary_table, temporary_table AS t2;
@end example
We plan to fix the above in 4.0.
@@ -44980,469 +48630,7 @@ We plan to fix the above in 4.0.
-@node Users, MySQL customer usage, Problems, Top
-@appendix Some MySQL Users
-
-@cindex users, of MySQL
-@cindex news sites
-
-This appendix lists some users of MySQL that have given us permission
-to list them in our documentation. It is by far not a complete list, but
-should give you a general idea of who uses MySQL and what it can
-be used for.
-
-@appendixsec General News Sites
-
-@itemize @bullet
-
-@item @uref{http://www.yahoo.com/, Yahoo!}
-
-@item @uref{http://slashdot.org/, Slashdot: A pro-Linux/tech news and comment/discussion site}
-
-@item @uref{http://www.linux.com/, All about Linux}
-
-@item @uref{http://www.linuxtoday.com/, Linuxtoday}
-
-@item @uref{http://www.32bitsonline.com/, 32Bits Online: because there's
-more than one way to compute}
-
-@item @uref{http://www.freshmeat.net/, Freshmeat: News about new versions of computer-related stuff}
-
-@end itemize
-
-@cindex search engines, web
-@cindex web search engines
-@appendixsec Some Web Search Engines
-
-@itemize @bullet
-
-@item @uref{http://www.aaa.com.au, AAA Matilda Web Search}
-
-@item @uref{http://www.whatsnu.com/, What's New}
-
-@item @uref{http://www.aladin.de/, Aladin}
-
-@item @uref{http://www.columbus-finder.de/, Columbus Finder}
-
-@item @uref{http://www.spider.de/, Spider}
-
-@item @uref{http://www.blitzsuche.de/, Blitzsuche}
-
-@item @uref{http://www.indoseek.co.id, Indoseek Indonesia}
-
-@item @uref{http://www.yaboo.dk/, Yaboo - Yet Another BOOkmarker}
-
-
-@item @uref{http://www.ozsearch.com.au, OzSearch Internet Guide}
-
-@item @uref{http://www.splatsearch.com/, Splat! Search}
-
-@item @uref{http://osdls.library.arizona.edu/, The Open Source Digital Library System Project}
-@end itemize
-
-@appendixsec Some Information Search Engines Concentrated on Some Area
-
-@itemize @bullet
-
-@item @uref{http://www.spylog.ru/, SpyLOG ; A very popular Web counter site}
-
-@item @uref{http://www.tucows.com/, TuCows Network; Free Software archive}
-
-@item @uref{http://www.jobvertise.com,Jobvertise: Post and search for jobs}
-
-@item @uref{http://www.musicdatabase.com, The Music Database}
-
-@item @uref{http://www.soccersearch.com, Football (Soccer) search page}
-
-@item @uref{http://www.headrush.net/takedown, TAKEDOWN - wrestling}
-
-@item @uref{http://www.lyrics.net, The International Lyrics Network}
-
-@item @uref{http://TheMatrix.com/~matrix/band_search.phtml, Musicians looking for other musicians (Free Service)}
-
-@item @uref{http://www.addall.com/AddBooks/Stores.html,AddALL books searching and price comparison}
-
-@item @uref{http://www.herbaria.harvard.edu/Data/Gray/gray.html,Harvard's Gray Herbarium Index of Plant Names}
-
-@item @uref{http://www.game-developer.com/,The Game Development Search Engine}
-
-@item @uref{www.theinnkeeper.com, The Innkeeper Vacation Guides}
-
-@item @uref{http://www.macgamedatabase.com/, The Mac Game Database uses PHP and MySQL}
-@c From: Marc Antony Vose <suzerain@suzerain.com>
-
-@item @uref{http://www.csse.monash.edu.au/publications/, Research
-Publications at Monash University in Australia}
-
-@item @uref{http://www.ipielle.emr.it/bts/index.html,
-Occupational Health & Safety Web site database (a project for the ECC)}
-@c c.presutti@ipielle.emr.it
-
-@item @uref{http://data.mch.mcgill.ca/, Bioinformatics databases at the
-Montreal Children's Hospital using MySQL}
-@c saeed@www.debelle.mcgill.ca
-@end itemize
-
-@cindex online magazines
-@cindex magazines, online
-@appendixsec Online Magazines
-
-@itemize @bullet
-@item @uref{http://www.spoiler.com, Spoiler Webzine}.
-An online magazine featuring music, literature, arts, and design content.
-@item @uref{http://www.linux-magazin.de/newsflash/, Daily news about Linux in German language}
-@item @uref{http://www.betazine.com,Betazine - The Ultimate Online Beta Tester's Magazine}
-@item @uref{http://www.currents.net/ccinfo/aboutcc.html,Computer Currents Magazine}
-@end itemize
-
-@cindex web sites
-@appendixsec Web Sites that Use MySQL as a Backend
-
-@itemize @bullet
-
-@item @uref{http://liftoff.msfc.nasa.gov, NASA}
-@item @uref{http://kids.msfc.nasa.gov, NASA KIDS}
-@item @uref{http://science.nasa.gov, Sience@@NASA}
-
-@item @uref{http://www.handy.de/, handy.de}
-
-@item @uref{http://lindev.jmc.tju.edu/qwor, Qt Widget and Object Repository}
-
-@item @uref{http://www.samba-choro.com.br, Brazilian samba site (in Portuguese)}
-
-@item @uref{http://pgss.iss.uw.edu.pl/en_index.ISS, Polish General Social Survey}
-
-@item @uref{http://www.expo2000.com, Expo2000} World-wide distribution of
-tickets for this event is implemented using MySQL and tcl/tk. More than
-5000 travel agencies all over the world have access to it.
-
-@item @uref{http://www.freevote.com/, FreeVote.com is a free voting
-service with millions of users.}
-
-@item @uref{http://f1.tauzero.se, Forza Motorsport}
-
-@item @uref{http://www.dreamhost.com/, DreamHost Web Hosting}
-
-@end itemize
-
-@cindex services
-@appendixsec Some Domain/Internet/Web and Related Services
-
-@itemize @bullet
-
-@item @uref{http://www.wix.com/mysql-hosting, Registry of Web providers that
-support MySQL}
-
-@item @uref{http://www.yi.org/, Dynamic DNS Services}
-
-@item @uref{http://www.dynodns.net/, Dynamic domain name service}
-
-@item @uref{http://www.ods.org/, Open DNS Project; free dynamic DNS service}
-
-@c @item @uref{http://dynodns.net, Free dynamic DNS implementation}
-@c EMAIL: A Moore <amoore@mooresystems.com>
-
-@item @uref{http://www.hn.org/, Hammernode; Public DNS Servers}
-
-@item @uref{http://www.fdns.net/, Free 3rd level domains}
-
-@item @uref{http://worldcommunity.com/, Online Database}
-
-@item @uref{http://www.bigbiz.com, BigBiz Internet Services}
-
-@item @uref{http://virt.circle.net, The Virt Gazette}
-
-@item @uref{http://www.california.com, Global InfoNet Inc}
-
-@item @uref{http://www.webhosters.com, WebHosters - A Guide to WWW Providers}
-
-@item @uref{http://online.dn.ru, Internet information server}
-
-@item @uref{http://www.stopbit.com, A technology news site}
-
-@item @uref{http://www.worldnetla.net, WorldNet Communications - An Internet Services Provider}
-
-@item @uref{http://www.netizen.com.au/, Netizen: Australian-based Web consultancy}
-
-@item @uref{http://www.trainingpages.co.uk, Search site for training courses in the UK}
-
-@item @uref{http://chat.nitco.com, Gannon Chat (GPL). Written in Perl and Javascript}
-
-@item @uref{http://www.addurls.com/,A general links directory}
-
-@item @uref{http://www.bookmarktracker.com, A Web-based bookmark management service}
-
-@item @uref{http://www.cdrom.com,Walnut Creek CDROM}
-
-@item @uref{http://www.wwwthreads.org/, WWWThreads; Interactive discussion Forums}
-
-@item @uref{http://pvmon.portici.enea.it/Meteo, In Italian; Storage data from meteo station}
-
-@item @uref{http://www.buysell.net/, Online "Person To Person" Auction}
-
-@item @uref{http://tips.pair.com,Tips on Web development}
-
-@item @uref{http://www.mailfriends.com, Mailfriends.com is a FREE service for
-everybody who wants to find friends over the internet.}
-
-@item @uref{http://www.uninova.com/cgi-bin/wctelnets?list, Web Page Telnet BBS List}
-
-@item @uref{http://www.uninova.com/cnc.html,UniNova Digital Postcards}
-
-@c @item @uref{http://cabinboy.powersurfr.com, An Internet RFC search engine}
-
-@item @uref{http://www.dslreports.com, DSL-provider search with reviews}.
-Made with MySQL and Modperl, all pages are generated dynamically out of
-the MySQL database
-@end itemize
-
-@cindex PHP, web sites
-@appendixsec Web Sites that Use @code{PHP} and MySQL
-
-@itemize @bullet
-@c @item @uref{http://www.wh200th.com, White House 200th Anniversary site}
-
-@item @uref{http://support.jgaa.com/, Jgaa's Internet - Official Support Site}
-
-@item @uref{http://io.incluso.com, Ionline - online publication:} MySQL,
-PHP, Java, Web programming, DB development
-
-@item @uref{http://www.baboo.com, BaBoo(Browse and bookmark). Free Web-based bookmark manager and Calendar}
-
-@item @uref{http://www.courses.pjc.cc.fl.us/Schedule/index.php, Course
-Schedule System at Pensacola Junior College}
-
-@item @uref{http://www.fccj.org, Florida Community College at Jacksonville}
-
-@item @uref{http://www.32bit.com/, 32bit.com; An extensive shareware / freeware archive}
-
-@item @uref{http://www.jokes2000.com/, Jokes 2000}
-@c Added 990604; EMAIL: ah@dybdahl.dk
-
-
-@item @uref{http://www.burken.nu/ , Burken.NU} Burken is a webhotel that
-provides scripts, among other things, for remote users, like counters,
-guestbooks etc.
-@c Added 990608; EMAIL: spacedmp@SpaceDump.Burken.NU (Anders Olausson)
-
-@item @uref{http://tips.pair.com, tips.pair.com} Contains tips on html,
-javascript, 2d/3d graphics, and PHP3/MySQL. All pages are generated from
-a database.
-@c Added 990614; EMAIL: downey@image.dk (Rune Madsen)
-
-@item @uref{http://www.softwarezrus.com/, Softwarezrus.com}
-Ecommerce site that is selling computers.
-@end itemize
-
-@cindex consultants, list of
-@appendixsec Some MySQL Consultants
-
-@itemize @bullet
-
-@item @uref{http://www.ayni.com, Ayni AG}
-
-@item @uref{http://worldcommunity.com/, Online Database}
-
-@item @uref{http://www2.dataguard.no/,DataGuard (Uses MySQL and PHP)}
-
-@item @uref{http://wwits.net/programs/mysql.phtml, WWITS (Uses MySQL and PHP)}
-
-@item @uref{http://www.worldcommunity.com/, WCN - The World Community Network}
-
-@item @uref{http://www.chipcastle.com, Chip Castle Dot Com Inc}
-@c Added 990603 EMAIL: chip@chipcastle.com (Chip Castle)
-
-@item @uref{http://www.cyber.com.au/, Cybersource Pty. Ltd}
-
-@item @uref{http://www.spring.de, Spring infotainment gmbh & co. kg}
-@c added 990905 "Oliver Pischke" <opischke@spring.de>
-
-@item @uref{http://www.wamdesign.com/, Develops Web sites using MySQL}
-@c Added 990905; max@wamdesign.com
-
-@item @uref{http://www.berkeleyconsultants.com, Berkeley Consultants Group}
-
-@item @uref{http://www.jammconsulting.com/, JAMM Consulting Inc.}
-
-@end itemize
-
-@appendixsec Programming
-
-@cindex web pages, miscellaneous
-@appendixsec Uncategorized Pages
-
-@itemize @bullet
-
-@item @uref{http://www.feature-showcase.com/htmls/demo_mysql.sql,
-AZC.COM's Feature Showcase}
-
-@item @uref{http://www.teach.org.uk/subjects/trainingcourse/g.html, Course Search}
-
-@item @uref{http://www.northerbys.com, Northerbys Online Auctions}
-
-@item @uref{http://www.schiphol.nl/flights/home.htm, Amsterdam Airport Schiphol}
-
-@item @uref{http://TheMatrix.com/seventhsin/query.phtml, CD database}
-
-@item @uref{http://TheMatrix.com/~flmm/GEAR.html, Used Audio Gear Database}
-
-@item @uref{http://www.kiss.de/musik-mueller, Musical note-sheets}
-
-@item @uref{http://www.bagism.com, Bagism - A John Lennon fan page}
-
-@item @uref{http://www.selftaught.com/, US Folk art broker}
-
-@item @uref{http://organizer.net/, Mail reading on the Web}
-
-@item @uref{http://www.mypage.org/, Free home pages on www.somecoolname.mypage.org}
-
-@item @uref{http://www.schulweb.de/, Der Server f@"ur Schulen im Web (In German)}
-
-@item @uref{http://www.ald.net/, Auldhaefen Online Services}
-
-@item @uref{http://www.cary.net/, CaryNET Information Center}
-
-@item @uref{http://www.dataden.com/, Dataden Computer Systems}
-
-@item @uref{http://andree.grm.se/, Andr@'emuseet (In Swedish)}
-
-@item @uref{http://www.him.net/, HOMESITE Internet Marketing}
-
-@item @uref{http://www.jade-v.com/techinfo.html, Jade-V Network Services }
-
-@item @uref{http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml,
-Weather World 2010 Technical Credits} @*
-
-@item @uref{http://gimp.foebud.org/registry/doc/, About The Gimp plugin registry}
-
-@item @uref{http://www.fast-inc.com/Products/Archiver/database.html, Java tool
-Archiver technical detail (Slightly optimistic about MySQL
-ANSI-92 compliance)}
-
-@item @uref{http://www.gamesdomain.com/cheats/usrcheat.phtml, Games Domain Cheats Database}
-
-@item @uref{http://www.kcilink.com/poweredby/, The "Powered By" Page (Kcilink)}
-
-@item @uref{http://www.netcasting.net/index.whtml, Netcasting}
-
-@item @uref{http://homepages.tig.com.au/~mjj/nbltips, NBL (Australian National Basketball League) tipping}
-
-@item @uref{http://www.cgishop.com/, CGI shop}
-
-@item @uref{http://www.whirlycott.com/, Whirlycott: Website Design}
-
-@item @uref{http://www.mtp.dk, Museum Tusculanum Press}
-
-@item @uref{http://csdgi.historie.ku.dk/biblio, Centro Siciliano di Documentazione}
-
-@item @uref{http://caribou.dyn.ml.org:8000, Quake statistics database}
-
-@item @uref{http://www.astroforum.ch, Astroforum: Astrologie and related things (in German)}
-
-@item @uref{http://www.opendebate.com, OpenDebate - Interactive Polls & Open Discussion}
-
-@item @uref{http://vermeer.organik.uni-erlangen.de/dissertationen/, Online chemical dissertation server}
-
-@item @uref{http://www.freschinfo.com, FreSch! The Free Scholarship Search Service}
-
-@item @uref{http://www.nada.kth.se/~staffanu/pinball, Stockholm Pinball Locator}
-
-@item @uref{http://www.hek.com, HEK A construction company}
-
-@item @uref{http://www.nbi.nl, Elsevier Bussines Information}
-
-@item @uref{http://vaccination.medicallink.se/, Medical Links (Using ColdFusion and MySQL)}
-
-@item @uref{http://www.joblink-usa.com, Search for jobs & people at JobLink-USA}
-
-@item @uref{http://www.skydive.net/competfs, Competition Formation Skydiving}
-
-@item @uref{http://www.galaxy-net.net/Galaxy-NET Telecommunications, E-commerce and internal accounting}
-
-@item @uref{http://www.borsen.dk/, Denmark's leading business daily newspaper B@o{}rsen}
-
-@item @uref{http://tmmm.simplenet.com/indb/, The Internet NES Database}
-
-@item @uref{http://www.russia.cz, Travel agency in Prague in 3 languages}
-
-@item @uref{http://www.linkstation.de, Linkstation}
-
-@item @uref{http://www.peoplestaff.com, Searchable online database at Peoplestaff}
-
-@item @uref{http://www.dreamhorse.com, A searchable database system for horse classified ads}
-
-@item @uref{http://pootpoot.com/,The Poot site}
-
-@item @uref{http://grateful.net/hw_html/,"Playin' in the LAN"; a network monitoring suite}
-
-@c Update from Christopher Milton <cmilton@bwn.net> 1999-12-21
-@item @uref{http://www.usapa.army.mil,U.S. Army Publishing Agency}
-
-@item @uref{http://www.nekretnine.co.yu/,Realestate handling in Yugoslavia}
-
-@item @uref{http://demo.cpsoft.com/pims/devFAQ.html, PIMS; a Patient Information Management System}
-
-@item @uref{http://cpsoft.com,Pilkington Software Inc}
-
-@item @uref{http://www.no-quarter.org/,A Vietnam Veteran's Memorial (The Wall) database}
-
-@item @uref{http://www.gamers-union.com/,Gamer's Union specializes in auctions of used & out-of-print gaming material}
-
-@item @uref{http://www.montereyhigh.com/office/dbul.php3, A daily bulletin at Monterey High school}
-
-@item @uref{http://www.myEastside.com,Community-owned site serving Lake
-Washington's Eastside residents and businesses}
-
-@item @uref{http://bowling-france.net/,French bowling site}
-@end itemize
-
-Send any additions to this list to @email{webmaster@@mysql.com}.
-
-@page
-
-
-
-
-@node MySQL customer usage, Contrib, Users, Top
-@appendix MySQL customer usage
-
-@cindex MySQL usage
-
-The section 'Some MySQL Users' contains a lot of different links to
-MySQL users but doesn't provide that much information about how
-they are using MySQL. @xref{Users}. This manual section is to
-give you an idea of how other MySQL users are using
-MySQL to solve their problems.
-
-This manual section is very new and we plan to add more stories here
-shortly. If you are interested in contributing of how you use
-MySQL in a unique environment or have success store about how you
-use MySQL, you can write to @code{docs@@mysql.com} with
-subject @code{Success:}. Note that as we are very busy it may take some
-time before you get some feedback for your story.
-
-@itemize @bullet
-@item
-@strong{Peter Zaitsev of Spylog.ru} writes:
-I think you might be interested in my database size. The whole database
-is currently on 15 servers and I think it's about 60.000 of tables
-containing about 5.000.000.000 of rows. My mostly loaded server
-currently holds about 10.000 of tables with 1.000.000.000 of rows in it.
-Hugest tables have about 50.000.000 of rows, and this value will raise
-as soon as I'll move to 2.4 kernel with large files. Currently I have to
-delete much of logs for large sites to hold table sizes in 2Gb.
-
-@item
-@strong{Texas Instruments} is using MySQL for handling tables
-that contain up to 2,000 million rows in a validation regression database.
-@end itemize
-
-@page
-
-
-
-
-@node Contrib, Credits, MySQL customer usage, Top
+@node Contrib, Credits, Problems, Top
@appendix Contributed Programs
@cindex contributed programs
@@ -45451,14 +48639,24 @@ that contain up to 2,000 million rows in a validation regression database.
Many users of MySQL have contributed @emph{very} useful support
tools and add-ons.
-@ifclear web
-A list of what is available at @uref{http://www.mysql.com/Downloads/Contrib/}
-(or any mirror) is shown below.
+A list of what is available at
+@uref{http://www.mysql.com/Downloads/Contrib/}
+(or any mirror) is shown here.
+
+Please visit our Software Portal at
+@uref{http://www.mysql.com/portal/software/}.
+The community facilities there also allow for your input!
+
If you want to build MySQL support for the Perl @code{DBI}/@code{DBD}
interface, you should fetch the @code{Data-Dumper}, @code{DBI}, and
@code{Msql-Mysql-modules} files and install them.
@xref{Perl support}.
-@end ifclear
+
+Note: The programs listed here can be freely downloaded and used.
+They are copyrighted by their respective owners.
+Please see individual product documentation for more details on licensing and terms.
+MySQL AB assumes no liability for the correctness of the information in this
+chapter or for the proper operation of the programs listed herein.
@appendixsec APIs
@@ -45466,26 +48664,26 @@ interface, you should fetch the @code{Data-Dumper}, @code{DBI}, and
@itemize @bullet
@item Perl Modules
@itemize @minus
-@item @uref{http://www.mysql.com/Downloads/Contrib/Data-Dumper-2.101.tar.gz, Data-Dumper-2.101.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Data-Dumper-2.101.tar.gz}
Perl @code{Data-Dumper} module. Useful with @code{DBI}/@code{DBD} support for
older Perl installations.
-@item @uref{http://www.mysql.com/Downloads/Contrib/DBI-1.15.tar.gz, DBI-1.15.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/DBI-1.18.tar.gz}
Perl @code{DBI} module.
-@item @uref{http://www.mysql.com/Downloads/Contrib/KAMXbase1.2.tar.gz,KAMXbase1.2.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/KAMXbase1.2.tar.gz}
Convert between @file{.dbf} files and MySQL tables. Perl
module written by Pratap Pereira @email{pereira@@ee.eng.ohio-state.edu},
extended by Kevin A. McGrail @email{kmcgrail@@digital1.peregrinehw.com}.
This converter can handle MEMO fields.
-@item @uref{http://www.mysql.com/Downloads/Contrib/Msql-Mysql-modules-1.2216.tar.gz, Msql-Mysql-modules-1.2216.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Msql-Mysql-modules-1.2218.tar.gz}
Perl @code{DBD} module to access mSQL and MySQL databases.
-@item @uref{http://www.mysql.com/Downloads/Contrib/Data-ShowTable-3.3.tar.gz, Data-ShowTable-3.3.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Data-ShowTable-3.3.tar.gz}
Perl @code{Data-ShowTable} module. Useful with @code{DBI}/@code{DBD} support.
-@item @uref{http://www.mysql.com/Downloads/Contrib/HandySQL-1.1.tar.gz, HandySQL-1.1.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/HandySQL-1.1.tar.gz}
HandySQL is a MySQL access module. It offers a C interface embedded in Perl and is
approximately 20% faster than regular DBI.
@@ -45494,12 +48692,12 @@ approximately 20% faster than regular DBI.
@cindex JDBC
@item JDBC
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-1.2c.tar.gz, mm.mysql.jdbc-1.2c.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-1.2c.tar.gz}
The mm JDBC driver for MySQL. This is a production release
and is actively developed. By Mark Matthews
(@email{mmatthew@@ecn.purdue.edu}).
-@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-2.0pre5.tar.gz, mm.mysql.jdbc-2.0pre5.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-2.0pre5.tar.gz}
The mm JDBC driver for MySQL. This is a pre-release beta version
and is actively developed. By Mark Matthews
(@email{mmatthew@@ecn.purdue.edu}).
@@ -45508,17 +48706,17 @@ license. Please check @uref{http://www.worldserver.com/mm.mysql/} for
the latest drivers (and other JDBC information) because these drivers may be out of date.
@item @uref{http://www.caucho.com/projects/jdbc-mysql/index.xtp}
-The Resin commercial JDBC driver, which is released under open source.
+The Resin commercial JDBC driver, which is released under @code{Open Source}.
It claims to be faster than the mm driver, but we haven't received that much
information about this yet.
-@item @uref{http://www.mysql.com/Downloads/Contrib/twz1jdbcForMysql-1.0.4-GA.tar.gz, twz1jdbcForMysql-1.0.4-GA.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/twz1jdbcForMysql-1.0.4-GA.tar.gz}
The twz driver: A type 4 JDBC driver by Terrence W. Zellers
@email{zellert@@voicenet.com}. This is commercial but is free for
private and educational use. (Not supported anymore.)
@c no answer from server 990830
@c You can always find the latest driver at @uref{http://www.voicenet.com/~zellert/tjFM/}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/pmdamysql.tgz,pmdamysql.tgz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/pmdamysql.tgz}
A MySQL PMDA. Provides MySQL server status and configuration
variables.
@end itemize
@@ -45526,15 +48724,15 @@ variables.
@cindex OLEDB
@item OLEDB
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB.exe, MyOLEDB.exe}
-OLEDB handler for MySQL. By SWsoft.
-@item @uref{http://www.mysql.com/Downloads/Win32/MySamples.zip, MySamples.zip}
-Examples and documentation for MyOLEDB. By SWsoft.
-@item @uref{http://www.mysql.com/Downloads/Win32/Myoledb.zip, Myoledb.zip}
-Source for MyOLEDB. By SWsoft.
-@item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB.chm, MyOLEDB.chm}
+@item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB3.exe}
+MyOLEDB 3.0 installation package from SWSoft.
+@item @uref{http://www.mysql.com/Downloads/Win32/mysql-oledb-3.0.0.zip}
+Source for MyOLEDB 3.0.
+@item @uref{http://www.mysql.com/Downloads/Win32/MySamples.zip}
+Examples and documentation for MyOLEDB.
+@item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB.chm}
Help files for MyOLEDB.
-@item @uref{http://www.mysql.com/Downloads/Win32/libmyodbc.zip, libmyodbc.zip}
+@item @uref{http://www.mysql.com/Downloads/Win32/libmyodbc.zip}
Static MyODBC library used for build MyOLEDB. Based on MyODBC code.
@end itemize
@@ -45542,83 +48740,83 @@ Static MyODBC library used for build MyOLEDB. Based on MyODBC code.
@item C++
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-c++-0.02.tar.gz, mysql-c++-0.02.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-c++-0.02.tar.gz}
MySQL C++ wrapper library. By Roland Haenel,
@email{rh@@ginster.net}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MyDAO.tar.gz, MyDAO}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MyDAO.tar.gz}
MySQL C++ API. By Satish @email{spitfire@@pn3.vsnl.net.in}. Inspired
by Roland Haenel's C++ API and Ed Carp's MyC library.
-@item @uref{http://www.mysql.com/download_mysql++.html, mysql++}
-MySQL C++ API (More than just a wrapper library.) Originally by
+@item @uref{http://www.mysql.com/download_mysql++.html}
+MySQL C++ API (more than just a wrapper library). Originally by
@email{kevina@@clark.net}. Nowadays maintained by Sinisa at MySQL AB.
-@item @uref{http://nelsonjr.homepage.com/NJrAPI,NJrAPI}
+@item @uref{http://nelsonjr.homepage.com/NJrAPI/}
A C++ database independent library that supports MySQL.
@end itemize
@cindex Delphi
@item Delphi
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/delphi-interface.gz, delphi-interface.gz}
-Delphi interface to @code{libmysql.dll}, by Blestan Tabakov,
-@email{root@@tdg.bis.bg}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/DelphiMySQL2.zip, DelphiMySQL2.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/DelphiMySQL2.zip}
Delphi interface to @code{libmysql.dll}, by @email{bsilva@@umesd.k12.or.us}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/Udmysel.pas, Udmysql.pas}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Udmysql.pas}
A wrapper for libmysql.dll for usage in Delphi. By Reiner Sombrowsky.
-@item @uref{http://www.fichtner.net/delphi/mysql.delphi.phtml, A Delphi interface to MySQL.}
-With source code. By Matthias Fichtner.
+@item @uref{http://www.fichtner.net/delphi/mysql.delphi.phtml}
+A Delphi Interface to MySQL, with source code. By Matthias Fichtner.
-@item @uref{http://www.productivity.org/projects/tmysql/, @strong{TmySQL}
-A library to use MySQL with Delphi}.
+@item @uref{http://www.productivity.org/projects/tmysql/}
+@code{TmySQL}, a library to use MySQL with Delphi.
-@item @uref{http://www.geocities.com/CapeCanaveral/2064/mysql.html, Delphi TDataset-component}.
-@item
-@item @uref{http://www.mysql.com/Downloads/Contrib/Win32/SBMySQL50Share.exe, Delphi 5 Shareware MySQL Dataset Components}
+@item @uref{https://sourceforge.net/projects/zeoslib/}
+Zeos Library is a set of delphi native datasets and database
+components for MySql, PostgreSql, Interbase, MS SQL, Oracle,
+DB/2. Also it includes development tools such as Database
+Explorer and Database Designer.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/Win32/SBMySQL50Share.exe}
+Delphi 5 Shareware MySQL Dataset Components.
@end itemize
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz, mysql-ruby-2.2.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz}
MySQL Ruby module. By TOMITA Masahiro @email{tommy@@tmtm.org}
-@uref{http://www.netlab.co.jp/ruby/. Ruby} is an Object-Oriented Interpreter Language.
+Ruby is an Object-Oriented Interpreter Language
+(@uref{http://www.netlab.co.jp/ruby/}).
-@item @uref{http://www.mysql.com/Downloads/Contrib/JdmMysqlDriver-0.1.0.tar.gz,JdmMysqlDriver-0.1.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/JdmMysqlDriver-0.1.0.tar.gz}
A VisualWorks 3.0 Smalltalk driver for MySQL. By
@email{joshmiller@@earthlink.net}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/Db.py, Db.py}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Db.py}
Python module with caching. By @email{gandalf@@rosmail.com}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLmodule-1.4.tar.gz, MySQLmodule-1.4.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLmodule-1.4.tar.gz}
Python interface for MySQL. By Joseph Skinner @email{joe@@earthlight.co.nz}. Modified by Joerg Senekowitsch @email{senekow@@ibm.net}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-python-0.3.0.tar.gz, MySQL-python-0.3.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-python-0.3.0.tar.gz}
MySQLdb Python is an DB-API v2.0-compliant interface to MySQL. Transactions
are supported if the server and tables support them. It is
thread-safe, and contains a compatibility module for older code
written for the no-longer-maintained MySQLmodule interface.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mex_12.tar.gz, mysql_mex_1_12.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mex_12.tar.gz}
An interface program for the Matlab program by MathWorks. The interface
is done by Kimmo Uutela and John Fisher (not by Mathworks).
-Check @uref{http://boojum.hut.fi/~kuutela/mysqlmex.html,mysqlmex.html}
+Check @uref{http://boojum.hut.fi/~kuutela/mysqlmex.html}
for more information.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltcl-1.53.tar.gz, mysqltcl-1.53.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltcl-1.53.tar.gz}
Tcl interface for MySQL. Based on @file{msqltcl-1.50.tar.gz}.
-Updated by Tobias Ritzau, @email{tobri@@ida.liu.se}.
+For version 2.0 and more info, see @uref{http://www.xdobry.de/mysqltcl/}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MyC-0.1.tar.gz, MyC-0.1.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MyC-0.1.tar.gz}
A Visual Basic-like API, by Ed Carp.
-@item @uref{http://www.mysql.com/Downloads/Contrib/sqlscreens-1.0.1.tar.gz, sqlscreens-1.0.1.tar.gz}
-Tcl/Tk code to generate database screens. By Jean-Francois Dockes.
-
-@item @uref{http://www.mysql.com/Downloads/Contrib/Vdb-dflts-2.1.tar.gz, Vdb-dflts-2.1.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Vdb-dflts-2.1.tar.gz}
This is a new version of a set of library utilities intended
to provide a generic interface to SQL database engines such that your
application becomes a 3-tiered application. The advantage is that you
@@ -45626,60 +48824,60 @@ can easily switch between and move to other database engines by
implementing one file for the new backend without making any
changes to your applications. By @email{damian@@cablenet.net}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/DbFramework-1.10.tar.gz, DbFramework-1.10.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/DbFramework-1.10.tar.gz}
DbFramework is a collection of classes for manipulating MySQL
databases. The classes are loosely based on the CDIF Data Model
Subject Area. By Paul Sharpe @email{paul@@miraclefish.com}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/pike-mysql-1.4.tar.gz, pike-mysql-1.4.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/pike-mysql-1.4.tar.gz}
MySQL module for pike. For use with the Roxen web server.
-@item @uref{http://www.mysql.com/Downloads/Contrib/squile.tar.gz, squile.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/squile.tar.gz}
Module for @code{guile} that allows @code{guile} to interact with SQL
databases. By Hal Roberts.
-@item @uref{http://www.mysql.com/Downloads/Contrib/stk-mysql.tar.gz, stk-mysql.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/stk-mysql.tar.gz}
Interface for Stk. Stk is the Tk widgets with Scheme underneath instead of Tcl.
By Terry Jones.
-@item @uref{http://www.mysql.com/Downloads/Contrib/eiffel-wrapper-1.0.tar.gz,eiffel-wrapper-1.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/eiffel-wrapper-1.0.tar.gz}
Eiffel wrapper by Michael Ravits.
-@item @uref{http://www.mysql.com/Downloads/Contrib/SQLmy0.06.tgz,SQLmy0.06.tgz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/SQLmy0.06.tgz}
FlagShip Replaceable Database Driver (RDD) for MySQL. By Alejandro
Fernandez Herrero.
-@uref{http://www.fship.com/rdds.html, Flagship RDD home page}
+The Flagship RDD homepage is at @uref{http://www.fship.com/rdds.html}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mydsn-1.0.zip,mydsn-1.0.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mydsn-1.0.zip}
Binary and source for @code{mydsn.dll}. mydsn should be used to build
and remove the DSN registry file for the MyODBC driver in Coldfusion
applications. By Miguel Angel Solórzano.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-ADA95_API.zip, MySQL-ADA95_API.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-ADA95_API.zip}
An ADA95 interface to the MySQL API. By Francois Fabien.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MyTool-DLL_for_VB_and_MySQL.zip, MyTool-DLL_for_VB_and_MySQL.zip}
-A DLL with MySQL C API for Visual Basic.
+@item @uref{http://www.mysql.com/Downloads/Contrib/MyTool-DLL_for_VB_and_MySQL.zip}
+A DLL with MySQL C API for Visual Basic.
By Ken Menzel @email{kenm@@icarz.com}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MYSQLX.EXE, MYSQL.EXE}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MYSQLX.EXE}
MySQL ActiveX Object for directly accessing your MySQL
-servers from IIS/ASP, VB, VC++ skipping the slower ODBC methods. Fully
-updatable, multithreaded with full support for all MySQL fieldtypes
+servers from IIS/ASP, VB, VC++ skipping the slower ODBC methods. Fully
+updatable, multi-threaded with full support for all MySQL fieldtypes
(version 2001.1.1). By SciBit @uref{http://www.scibit.com/}.
-@item @uref{http://www.fastflow.it/mylua/, MyLUA home page}
-How to use the LUA language to write MySQL @code{PROCEDURE} that can
-be loaded runtime.
+@item @uref{http://www.fastflow.it/mylua/}
+MyLUA home page; how to use the LUA language to write MySQL
+@code{PROCEDURE} that can be loaded runtime.
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/lua-4.0.tar.gz, Lua 4.0}
+@item @uref{http://www.mysql.com/Downloads/Contrib/lua-4.0.tar.gz}
LUA 4.0
-@item @uref{http://www.mysql.com/Downloads/Contrib/mylua-3.23.32.1.tar.gz, mylua-3.23.32.1.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mylua-3.23.32.1.tar.gz}
Patch for MySQL 3.23.32 to use LUA 4.0. By Cristian Giussani.
@end itemize
-@item @uref{http://www.mysql.com/Downloads/Contrib/patched_myodbc.zip, patched_myodbc.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/patched_myodbc.zip}
Patch (for Omniform 4.0 support) to the MyODBC driver.
By Thomas Thaele @email{tthaele@@papenmeier.de}
@@ -45690,59 +48888,61 @@ By Thomas Thaele @email{tthaele@@papenmeier.de}
@itemize @bullet
@item Graphical clients
@itemize @minus
-@item @uref{http://www.ideit.com/products/dbvis/, DbVisualizer}.
-Freeware JDBC client to graphically visualize the data and structure
-of several databases simultaneously. By Innovative-IT Development AB.
-
-@item @uref{http://www.mysql.com/downloads/gui-clients.html, MySQLGUI}
-The MySQL GUI client homepage. By Sinisa at MySQL AB.
-
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_navigator_0.9.0.tar.gz, MySQL navigator 0.9}
-MySQL Navigator is a MySQL database server GUI client program. The purpose
-of MySQL Navigator is to provide a useful client interface to MySQL
-database servers, whilst supporting multiple operating systems and
-languages. You can currently import/export database, enter queries, get
-result sets, edit scripts, run scripts, add, alter, and delete users,
-and retrieve client and server information. Uses QT 2.2. GPL
-@uref{http://sql.kldp.org/mysql, Home page for MySQL Navigator}.
-
-@item @uref{http://www.mysql.com/Downloads/Win32/secman.zip, MySQL Security GUI}
-A user and security management GUI for MySQL on Windows.
+@item @uref{http://www.ideit.com/products/dbvis/}
+DbVisualizer, a freeware JDBC client to graphically visualise
+the data and structure of several databases simultaneously.
+By Innovative-IT Development AB.
+
+@item @uref{http://www.mysql.com/downloads/gui-clients.html}
+MySQLGUI, the MySQL GUI client homepage. By Sinisa at MySQL AB.
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_navigator_0.9.0.tar.gz}
+MySQL Navigator is a MySQL database server GUI client program, distributed
+under GPL license. The purpose of MySQL Navigator is to provide a useful
+client interface to MySQL database servers, whilst supporting multiple
+operating systems and languages. You can currently import/export database,
+enter queries, get result sets, edit scripts, run scripts, add, alter, and
+delete users, and retrieve client and server information. Uses QT 2.2.
+The homepage for MySQL Navigator is at @uref{http://sql.kldp.org/mysql/}.
+
+@item @uref{http://www.mysql.com/Downloads/Win32/secman.zip}
+A user and security management GUI for MySQL on Windows.
By Martin Jeremic.
-@uref{http://jsoft.webjump.com/, Home page for MySQL Security GUI}.
+The homepage for MySQL Security GUI is at @uref{http://jsoft.webjump.com/}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1.tar.gz, kmysqladmin-0.4.1.tar.gz}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.src.rpm, kmysqladmin-0.4.1-1.src.rpm}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.i386.rpm, kmysqladmin-0.4.1-1.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1.tar.gz}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.src.rpm}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.i386.rpm}
An administration tool for the MySQL server using QT / KDE. Tested
only on Linux.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-admin-using-java+swing.tar.gz, Java client using Swing} By Fredy Fischer, @email{se-afs@@dial.eunet.ch}.
-You can always find the latest version
-@uref{http://www.trash.net/~ffischer/admin/index.html, here}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-admin-using-java+swing.tar.gz}
+Java client using Swing, by Fredy Fischer (@email{se-afs@@dial.eunet.ch}).
+You can always find the latest version at
+@uref{http://www.trash.net/~ffischer/admin/}.
-@item @uref{http://www.mysql.com/Downloads/Win32/MySQL-Maker-1.0.zip,MySQL-Maker 1.0}.
+@item @uref{http://www.mysql.com/Downloads/Win32/MySQL-Maker-1.0.zip}.
Shareware MySQL client for Windows. It's a WYSIWYG tool which allows
you to create, change and delete databases and tables.
You can change field - structure and add, change and delete data in
these tables directly without ODBC-driver.
-@uref{http://www.presult.de/presult/frames/fs_mysqlmaker.html, MySQL Maker homepage}
+The MySQL Maker homepage is at @uref{http://www.presult.de/presult/frames/fs_mysqlmaker.html}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlwinadmn.zip, mysqlwinadmn.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlwinadmn.zip}
Windows GUI (binary only) to administrate a database, by David B. Mansel,
@email{david@@zhadum.org}.
-@item @uref{http://home.online.no/~runeberg/myqa, MyQA}
-is a Linux-based query client for the MySQL database server. MyQA
+@item @uref{http://home.online.no/~runeberg/myqa/}
+MyQA is a Linux-based query client for the MySQL database server. MyQA
lets you enter SQL queries, execute them, and view the results, all in a
graphical user interface. The GUI is roughly similar to that of the
'Query Analyzer' client that comes with MS SQL Server.
-@item @uref{http://members.xoom.com/_opex_/mysqlmanager/index.html, MySQL Manager}
-a graphical MySQL server manager for MySQL server written in Java, for Windows
-
+@item @uref{http://www.opex.atnet.ru/mysqlmanager/}
+MySQL Manager is a graphical MySQL server manager for MySQL server
+written in Java.
-@item @uref{http://www.mysql.com/Downloads/Win32/netadmin.zip, netadmin.zip}
+@item @uref{http://www.mysql.com/Downloads/Win32/netadmin.zip}
An administrator tool for MySQL on Windows 95/98 and Windows NT
4.0. Only tested with MySQL Versions 3.23.5 - 3.23.7. Written
using the Tmysql components.
@@ -45751,68 +48951,74 @@ You can write queries and show tables, indexes, table syntax, and
administrate user, host, and database and so on. This is beta and
still has some bugs. You can test the program with all features. Please
send bugs and hints to Marco Suess @email{ms@@it-netservice.de}. Original
-URL @url{http://www.it-netservice.de/pages/software/index.html}.
+URL @uref{http://www.it-netservice.de/pages/software/}.
-@item @uref{http://www.mysql.com/Downloads/Win32/netadmin2.zip, netadmin2.zip}
+@item @uref{http://www.mysql.com/Downloads/Win32/netadmin2.zip}
New version of netadmin. See above for details.
-@item @uref{http://www.mysql.com/Downloads/Win32/ARTADMIN203.EXE,Atronic's MySQL client for Windows 2.0.3.0}.
-Home page for this can be found at: @uref{http://www.artronic.hr}.
+@item @uref{http://www.mysql.com/Downloads/Win32/ARTADMIN203.EXE}
+Atronic's MySQL client for Windows 2.0.3.0.
+The home page for this can be found at @uref{http://www.artronic.hr/}.
-@item @uref{http://www.mysql.com/Downloads/Win32/mysqlfront.zip, mysqlfront}
-Home page: @uref{http://www.mysqlfront.de/}.
-Win32-Client for accessing and managing dbs, tables, table-data, indexes,
-import-/export-files. (Freeware). By Ansgar Becker.
+@item @uref{http://www.mysql.com/Downloads/Win32/W9xstop.zip}
+Utility from Artronic to stop MySQL on win9x.
-@item @uref{http://www.mysql.com/Downloads/Win32/W9xstop.zip,Utility from Artronic to stop MySQL on win9x}.
+@item @uref{http://bardo.hyperlink.cz/mysqlmon/}
+A light weight GUI client for Windows.
-@item @uref{http://bardo.hyperlink.cz/mysqlmon,a light weight GUI client for Windows}.
+@item @uref{http://www.mysqlfront.de/}
+MySQLfront is a very nice Windows client with lots of useful features.
+By Angsar Becker.
-@item @uref{http://dbtools.vila.bol.com.br/, Dbtools}
-A tool to manage MySQL databases. Currently only for Windows.
+@item @uref{http://www.dbtools.com.br/}
+Dbtools, a tool to manage MySQL databases. Currently only for Windows.
Some features:
@itemize @bullet
@item Manage servers, databases, tables, columns, indexes, and users
@item Import wizard to import structure and data from MS Access, MS Excel, Dbase, FoxPro, Paradox, and ODBC Databases.
-@item @uref{http://www.mysql.com/Downloads/Contrib/KMYENG113.zip,KMYENG113.zip}
-An administrator GUI for MySQL. Works only on windows, no source.
+@item @uref{http://www.mysql.com/Downloads/Contrib/KMYENG113.zip}
+An administrator GUI for MySQL. Works only on Windows, no source.
Available in English and Japanese. By Mitunobu Kaneko.
Home page: @uref{http://sql.jnts.ne.jp/}
@end itemize
-@item @uref{http://www.mysql.com/Downloads/Contrib/xmysqladmin-1.0.tar.gz, xmysqladmin-1.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/xmysqladmin-1.0.tar.gz}
An X-based front end to the MySQL database engine. It allows reloads,
status check, process control, myisamchk, grant/revoke privileges,
creating databases, dropping databases, create, alter, browse, and drop
tables. Originally by Gilbert Therrien, @email{gilbert@@ican.net} but
now in public domain and supported by MySQL AB.
-@item @uref{http://www.mysql.com/Downloads/Contrib/xmysql-1.9.tar.gz, xmysql-1.9.tar.gz}.
-@item @uref{http://web.wt.net/~dblhack, xmysql home page}
-A front end to the MySQL database engine. It allows for simple
+@item @uref{http://www.mysql.com/Downloads/Contrib/xmysql-1.9.tar.gz}.
+xmysqlA front end to the MySQL database engine. It allows for simple
queries and table maintenance, as well as batch queries. By Rick
Mehalick, @email{dblhack@@wt.net}.
-Requires @uref{http://bragg.phys.uwm.edu/xforms,xforms 0.88} to work.
-@item @uref{http://www.tamos.net/sw/dbMetrix,dbMetrix}
-An open source client for exploring databases and executing SQL. Supports
-MySQL, Oracle, PostgreSQL, and mSQL.
-@item @uref{http://www.multimania.com/bbrox/GtkSQL,GtkSQL}
-A query tool for MySQL and PostgreSQL.
-@item @uref{http://dbman.linux.cz/,dbMan}
-A query tool written in Perl. Uses DBI and Tk.
-@item @uref{http://www.mysql.com/Downloads/Win32/Msc201.EXE, Mascon 202}
-@item @uref{http://www.mysql.com/Downloads/Win32/FrMsc202.EXE, Free Mascon 202}
+The xmysql homepage is at @uref{http://web.wt.net/~dblhack/}
+Requires @uref{http://bragg.phys.uwm.edu/xforms/} (xforms 0.88) to work.
+
+@item @uref{http://www.tamos.net/sw/dbMetrix/}
+dbMatrix is an @code{Open Source} client for exploring databases and executing
+SQL. Supports MySQL, Oracle, PostgreSQL, and mSQL.
+
+@item @uref{http://www.multimania.com/bbrox/GtkSQL/}
+GtkSQL is a query tool for MySQL and PostgreSQL.
+
+@item @uref{http://dbman.linux.cz/}
+dbMan is a query tool written in Perl. Uses DBI and Tk.
+
+@item @uref{http://www.mysql.com/Downloads/Win32/Msc201.EXE} (Mascon 202)
+@item @uref{http://www.mysql.com/Downloads/Win32/FrMsc202.EXE} (Free Mascon 202)
Mascon is a powerful Win32 GUI for the administering MySQL server
databases. Mascon's features include visual table design, connections to
multiple servers, data and blob editing of tables, security setting, SQL
color coding, dump functionality and much more.
-@uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon home page}.
-@item @uref{http://www.virtualbeer.net/dbui/,DBUI}
+The Mascon homepage is at @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp}.
+@item @uref{http://www.virtualbeer.net/dbui/}
DBUI is a Gtk graphical database editor.
-@item @uref{http://www.rtlabs.com/, MacSQL}
-GUI for MySQL, ODBC, and JDBC databases for the Mac OS.
-@item @uref{http://www.caleb.com.au/, JRetriever}
+@item @uref{http://www.rtlabs.com/}
+MacSQL is a GUI for MySQL, ODBC, and JDBC databases for the Mac OS.
+@item @uref{http://www.caleb.com.au/}
JRetriever is a generic database front-end tool for JDBC compliant
databases written with Java 2. JRetriever displays database
tables/views in a Windows explorer-like front end. Users can retrieve
@@ -45820,18 +49026,18 @@ data either by clicking on the table folder or by composing their own SQL
statements with our built-in SQL editor. The tool has been tested with
Oracle 8 and MySQL as the back-end databases. It requires JDK 1.3 from
JavaSoft.
-@item @uref{http://www.jetools.com/products/databrowser/, DataBrowser}
+@item @uref{http://www.jetools.com/products/databrowser/}
The DataBrowser is a cross-database, cross-platform data access tool. It is more
-user friendly than tools like SQL Plus, psql (command line based tools). It is more
+user friendly than tools like SQL Plus, psql (command-line based tools). It is more
flexible than TOAD, ISQL, PGAccess which are GUI's that are limitied to a single
platform or database.
-@item @uref{http://www.intrex.net/amit/software/, SQLC}
+@item @uref{http://www.intrex.net/amit/software/}
The SQL Console is a standalone java application that allows you to connect to a
SQL database system and issue SQL queries and updates. It has an easy-to use
graphical user interface. The SQL Console uses JDBC to connect to the database
systems and, therefore, with proper JDBC drivers, you can use this utility to
-connect to some of the most popular database systems.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mmc.zip, MySQL MMC}
+connect to some of the most popular database systems.
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mmc.zip}
MySQL MMC is a GUI Management Tool developed using kdevelop
with a very good interface completely like Microsoft
Enterprise Tool (for SQL Server) or Sybase Central. We
@@ -45843,53 +49049,53 @@ by Query Analysis.
@cindex Web clients
@item Web Clients
@itemize @minus
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladmin-atif-1.0.tar.gz, mysqladmin-atif-1.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladmin-atif-1.0.tar.gz}
WWW MySQL administrator for the @code{user,} @code{db} and
@code{host} tables. By Tim Sailer, modified by Atif Ghaffar
@email{aghaffar@@artemedia.ch}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-webadmin-1.0a8-rz.tar.gz, mysql-webadmin-1.0a8-rz.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-webadmin-1.0a8-rz.tar.gz}
A tool written in PHP-FI to administrate MySQL databases
-remotely over the web within a Web-Browser. By Peter Kuppelwieser,
+remotely over the web within a web-browser. By Peter Kuppelwieser,
@email{peter.kuppelwieser@@kantea.it}. Updated by Wim Bonis,
@email{bonis@@kiss.de}. Not maintained anymore!
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm.tar.gz, mysqladm.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm.tar.gz}
MySQL Web Database Administration written in Perl. By Tim Sailer.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm-2.tar.gz, mysqladm-2.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm-2.tar.gz}
Updated version of @file{mysqladm.tar.gz}, by High Tide.
-@item @uref{http://www.mysql.com/Downloads/Contrib/billowmysql.zip, billowmysql.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/billowmysql.zip}
Updated version of @file{mysqladm.tar.gz}, by Ying Gao. You can get the
-newest version from @uref{http://civeng.com/sqldemo/, the home site}.
+newest version from @uref{http://civeng.com/sqldemo/} (the home site).
-@item @uref{http://www.mysql.com/Downloads/Contrib/myadmin-0.4.tar.gz, myadmin-0.4.tar.gz}.
-@item @uref{http://myadmin.cheapnet.net/, MyAdmin home page}
-A Web-based MySQL administrator by Mike Machado.
+@item @uref{http://www.mysql.com/Downloads/Contrib/myadmin-0.4.tar.gz}.
+MyAdmin is a web-based MySQL administrator by Mike Machado.
+TheMyAdmin homepage is at @uref{http://myadmin.cheapnet.net/}
-@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin_2.0.1.tar.gz,phpMyAdmin_2.0.1.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin_2.2.0.tar.gz}
A set of PHP3-scripts to adminstrate MySQL over the WWW.
-@item @uref{http://www.phpwizard.net/projects/phpMyAdmin/, phpMyAdmin home page}
-A PHP3 tool in the spirit of mysql-webadmin, by Tobias Ratschiller, tobias@@dnet.it.
+@item @uref{http://www.phpwizard.net/projects/phpMyAdmin/}
+phpMyAdmin is a PHP3 tool in the spirit of mysql-webadmin, by Tobias Ratschiller, tobias@@dnet.it.
-@item @uref{http://www.mysql.com/Downloads/Contrib/useradm.tar.gz, useradm.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/useradm.tar.gz}
MySQL administrator in PHP. By Ofni Thomas
@email{othomas@@vaidsystems.com}.
-@item @uref{http://gossamer-threads.com/perl/mysqlman/mysql.cgi, MySQLMan}
-Similar functionality as phpmyadmin, but written with Perl and using
-html templates. By Alex Krohn.
+@item @uref{http://gossamer-threads.com/perl/mysqlman/mysql.cgi}
+MySQLMan has similar functionality to phpmyadmin, but written with
+Perl and using html templates. By Alex Krohn.
@end itemize
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-editor.tar.gz,mysql-editor.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-editor.tar.gz}
This cgi scripts in Perl enables you to edit content of Mysql
database. By Tomas Zeman.
-@item
-@uref{http://worldcommunity.com/opensource/futuresql, FutureSQL Web Database Administration Tool}.
-FutureSQL by Peter F. Brown, is a free, open source rapid application
-development Web database administration tool, written in Perl,
+
+@item @uref{http://worldcommunity.com/opensource/futuresql/}
+FutureSQL by Peter F. Brown, is a free, @code{Open Source} rapid application
+development web database administration tool, written in Perl,
using MySQL. It uses @code{DBI:DBD} and @code{CGI.pm}.
FutureSQL allows one to easily set up config files to view, edit, delete,
@@ -45904,12 +49110,13 @@ and "post-processing" on both fields, records, and operations.
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/mod_mysql_include_1.0.tar.gz, mod_mysql_include_1.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mod_mysql_include_1.0.tar.gz}
Apache module to include HTML from MySQL queries into your pages,
and run update queries. Originally written to implement a simple fast
low-overhead banner-rotation system. By Sasha Pachev.
-@item @uref{http://htcheck.sourceforge.net, htCheck} - URL checker with
+@item @uref{http://htcheck.sourceforge.net/}
+htCheck is a URL checker with
MySQL backend. Spidered URLs can later be queried using SQL to retrieve
various kinds of information, eg. broken links. Written by Gabriele Bartolini.
@@ -45920,35 +49127,35 @@ Update, Delete) from an html form. You can build a complete forms
interface to a SQL database (query, add, update, delete) without any
programming! By Marc Beneteau, @email{marc@@odbsoft.com}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/sqlhtml.tar.gz, sqlhtml.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/sqlhtml.tar.gz}
SQL/HTML is an HTML database manager for MySQL using @code{DBI} 1.06.
-@item @uref{http://www.mysql.com/Downloads/Contrib/udmsearch-3.0.23.tar.gz, UdmSearch 3.0.23 (stable version)}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mnogosearch-3.1.12.tar.gz, mnogosearch 3.1.12 (development but recommended version)}.
-@item @uref{http://search.mnoGo.ru, UdmSearch home page}
+@item @uref{http://www.mysql.com/Downloads/Contrib/udmsearch-3.0.23.tar.gz} (UdmSearch 3.0.23, stable version).
+@item @uref{http://www.mysql.com/Downloads/Contrib/mnogosearch-3.1.12.tar.gz} (mnogosearch 3.1.12, development but recommended version)
+@item @uref{http://search.mnoGo.ru/} (UdmSearch home page)
A SQL-based search engine for Internet. By
Alexander I. Barkov @email{bar@@izhcom.ru}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.doc, wmtcl.doc}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.lex, wmtcl.lex}
+@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.doc}
+@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.lex}
With this you can write HTML files with inclusions of Tcl code. By
@email{vvs@@scil.npi.msu.su}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.lsm, www-sql-0.5.7.lsm}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.tar.gz, www-sql-0.5.7.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.lsm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.tar.gz}
A CGI program that parses an HTML file containing special tags, parses
them, and inserts data from a MySQL database.
-@item @uref{http://www.mysql.com/Downloads/Contrib/genquery.zip, genquery.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/genquery.zip}
Perl SQL database interface package for html.
-@item @uref{http://www.mysql.com/Downloads/Contrib/cgi++-0.8.tar.gz, cgi++-0.8.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/cgi++-0.8.tar.gz}
A macro-processor to simply writing CGI/Database programs in C++ by Sasha Pachev.
-@item @uref{http://www.mysql.com/Downloads/Contrib/webboard-1.0.zip, WebBoard 1.0}
-EU-Industries Internet-Message-Board.
+@item @uref{http://www.mysql.com/Downloads/Contrib/webboard-1.0.zip}
+WebBoard 1.0, EU-Industries Internet-Message-Board.
-@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz, DBIx-TextIndex-0.02.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz}
Full-text searching with Perl on @code{BLOB}/@code{TEXT} columns by Daniel Koch.
@end itemize
@@ -45957,9 +49164,8 @@ Full-text searching with Perl on @code{BLOB}/@code{TEXT} columns by Daniel Koch.
@appendixsec Performance Benchmarking Tools
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/super-smack/super-smack-1.0.tar.gz,
- super-smack}
-Multi-threaded benchmarking tool for MySQL and
+@item @uref{http://www.mysql.com/Downloads/super-smack/super-smack-1.0.tar.gz}
+super-smack is a multi-threaded benchmarking tool for MySQL and
@strong{PostgreSQL}. Written in C++. Easy to extend to support other
databases that have C/C++ client libraries. By Sasha Pachev.
@end itemize
@@ -45969,61 +49175,56 @@ databases that have C/C++ client libraries. By Sasha Pachev.
@appendixsec Authentication Tools
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/ascend-radius-mysql-0.7.2.patch.gz,ascend-radius-mysql-0.7.2.patch.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/ascend-radius-mysql-0.7.2.patch.gz}
This is an authentication and logging patch using MySQL for
Ascend-Radius. By @email{takeshi@@SoftAgency.co.jp}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/icradius-0.10.tar.gz, icradius 0.10}
-@uref{http://www.mysql.com/Downloads/Contrib/icradius.README, icradius readme file}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/icradius-0.10.tar.gz} (icradius 0.10)
+@uref{http://www.mysql.com/Downloads/Contrib/icradius.README} (icradius readme)
-@item @uref{http://www.mysql.com/Downloads/Contrib/checkpassword-0.81-mysql-0.6.6.patch.gz,
-checkpassword-0.81-mysql-0.6.6.patch.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/checkpassword-0.81-mysql-0.6.6.patch.gz}
MySQL authentication patch for QMAIL and checkpassword. These are
useful for management user (mail, pop account) by MySQL.
By @email{takeshi@@SoftAgency.co.jp}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/jradius-diff.gz, jradius-diff.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/jradius-diff.gz}
MySQL support for Livingston's Radius 2.01. Authentication and
Accounting. By Jose de Leon, @email{jdl@@thevision.net}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mod_auth_mysql-2.20.tar.gz, mod_auth_mysql-2.20.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mod_auth_mysql-2.20.tar.gz}
Apache authentication module for MySQL. By Zeev Suraski,
@email{bourbon@@netvision.net.il}.
@c @strong{Please} register this module at:
-@c @url{http://bourbon.netvision.net.il/mysql/mod_auth_mysql/register.html}. The
+@c @uref{http://bourbon.netvision.net.il/mysql/mod_auth_mysql/register.html}. The
@c registering information is only used for statistical purposes and will
@c encourage further development of this module!
-@item @uref{http://www.mysql.com/Downloads/Contrib/mod_log_mysql-1.05.tar.gz, mod_log_mysql-1.05.tar.gz}
-MySQL logging module for Apache. By Zeev Suraski,
-@email{bourbon@@netvision.net.il}.
-
-@item @uref{http://www.mysql.com/Downloads/Contrib/mypasswd-2.0.tar.gz, mypasswd-2.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mypasswd-2.0.tar.gz}
Extra for @code{mod_auth_mysql}. This is a little tool that allows you
to add/change user records storing group and/or password entries in
MySQL tables. By Harry Brueckner, @email{brueckner@@respublica.de}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd.README, mysql-passwd.README}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd-1.2.tar.gz, mysql-passwd-1.2.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd.README}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd-1.2.tar.gz}
Extra for @code{mod_auth_mysql}. This is a two-part system for use with
@code{mod_auth_mysql}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/pam_mysql.tar.gz, pam_mysql.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/pam_mysql.tar.gz}
This module authenticates users via @code{pam}, using MySQL.
-@item @uref{http://www.mysql.com/Downloads/Contrib/nsapi_auth_mysql.tar, nsapi_auth_mysql.tar}
+@item @uref{http://www.mysql.com/Downloads/Contrib/nsapi_auth_mysql.tar}
Netscape Web Server API (NSAPI) functions to authenticate (BASIC) users
against MySQL tables. By Yuan John Jiang.
-@item @uref{http://www.mysql.com/Downloads/Contrib/qmail-1.03-mysql-0.6.6.patch.gz,qmail-1.03-mysql-0.6.6.patch.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/qmail-1.03-mysql-0.6.6.patch.gz}
Patch for qmail to authenticate users from a MySQL table.
By @email{takeshi@@SoftAgency.co.jp}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/proftpd-1.2.0rc2-fix-mysql.patch, proftpd-1.2.0rc2-fix-mysql.patch}
+@item @uref{http://www.mysql.com/Downloads/Contrib/proftpd-1.2.0rc2-fix-mysql.patch}
Patch for proftpd1.2.0rc2. By @email{takeshi@@SoftAgency.co.jp}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/pwcheck_mysql-0.1.tar.gz,pwcheck_mysql-0.1.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/pwcheck_mysql-0.1.tar.gz}
An authentication module for the Cyrus IMAP server. By Aaron Newsome.
@@ -46033,34 +49234,35 @@ An authentication module for the Cyrus IMAP server. By Aaron Newsome.
@appendixsec Converters
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/mssql2mysql.txt, mssql2mysql.txt}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mssql2mysql.txt}
Converter from MS-SQL to MySQL. By Michael Kofler.
-@uref{http://www.kofler.cc/mysql/mssql2mysql.html, mssql2mysql home page}.
+The mssql2mysql home page is at
+@uref{http://www.kofler.cc/mysql/mssql2mysql.html}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.14.tar.gz, dbf2mysql-1.14.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.14.tar.gz}
Convert between @file{.dbf} files and MySQL tables. By Maarten
Boekhold (@email{boekhold@@cindy.et.tudelft.nl}), William Volkman, and
Michael Widenius. This converter includes rudimentary read-only support
for MEMO fields.
-@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.13.tgz, dbf2mysql-1.13.tgz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.13.tgz}
Convert between @file{.dbf} files and MySQL tables. By Maarten
Boekhold, @email{boekhold@@cindy.et.tudelft.nl}, and Michael Widenius.
This converter can't handle MEMO fields.
-@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql.zip, dbf2mysql.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql.zip}
Convert between FoxPro @file{.dbf} files and MySQL tables on Windows.
By Alexander Eltsyn, @email{ae@@nica.ru} or @email{ae@@usa.net}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2sql.zip, dbf2sql.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2sql.zip}
Short and simple prg that can help you transport your data from foxpro
table into MySQL table. By Danko Josic.
-@item @uref{http://www.mysql.com/Downloads/Contrib/dump2h-1.20.gz, dump2h-1.20.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/dump2h-1.20.gz}
Convert from @code{mysqldump} output to a C header file. By Harry Brueckner,
@email{brueckner@@mail.respublica.de}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/exportsql.txt, exportsql.txt}
+@item @uref{http://www.mysql.com/Downloads/Contrib/exportsql.txt}
A script that is similar to @code{access_to_mysql.txt}, except that this
one is fully configurable, has better type conversion (including
detection of @code{TIMESTAMP} fields), provides warnings and suggestions
@@ -46068,30 +49270,31 @@ while converting, quotes @strong{all} special characters in text and
binary data, and so on. It will also convert to @code{mSQL} v1 and v2,
and is free of charge for anyone. See
@uref{http://www.cynergi.net/exportsql/} for the latest version. By
-Pedro Freire, @email{support@@cynergi.net}. NOTE: Doesn't work with
+Pedro Freire, @email{support@@cynergi.net}. Note: Doesn't work with
Access2!
-@item @uref{http://www.mysql.com/Downloads/Contrib/access_to_mysql.txt, access_to_mysql.txt}
+
+@item @uref{http://www.mysql.com/Downloads/Contrib/access_to_mysql.txt}
Paste this function into an Access module of a database that has the
tables you want to export. See also @code{exportsql}. By Brian Andrews.
-NOTE: Doesn't work with Access2!
+Note: Doesn't work with Access2!
-@item @uref{http://www.mysql.com/Downloads/Contrib/importsql.txt, importsql.txt}
+@item @uref{http://www.mysql.com/Downloads/Contrib/importsql.txt}
A script that does the exact reverse of @code{exportsql.txt}. That is,
it imports data from MySQL into an Access database via
ODBC. This is very handy when combined with exportsql, because it lets you
-use Access for all DB design and administration, and synchronize with
+use Access for all DB design and administration, and synchronise with
your actual MySQL server either way. Free of charge. See
@uref{http://www.netdive.com/freebies/importsql/} for any updates.
Created by Laurent Bossavit of NetDIVE.
-@strong{NOTE:} Doesn't work with Access2!
+@strong{Note}: doesn't work with Access2!
-@item @uref{http://www.mysql.com/Downloads/Contrib/mdb2sql.bas, mdb2sql.bas}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mdb2sql.bas}
Converter from Access97 to MySQL by Moshe Gurvich.
-@item @uref{http://www.mysql.com/Downloads/Contrib/msql2mysqlWrapper-1.0.tgz, msql2mysqlWrapper 1.0}
+@item @uref{http://www.mysql.com/Downloads/Contrib/msql2mysqlWrapper-1.0.tgz}
A C wrapper from @code{mSQL} to MySQL. By @email{alfred@@sb.net}
-@item @uref{http://www.mysql.com/Downloads/Contrib/sqlconv.pl, sqlconv.pl}
+@item @uref{http://www.mysql.com/Downloads/Contrib/sqlconv.pl}
A simple script that can be used to copy fields from one MySQL table
to another in bulk. Basically, you can run @code{mysqldump} and pipe it to
the @code{sqlconv.pl} script. The script will parse through the
@@ -46100,14 +49303,15 @@ inserted into a new table. An example is when you want to create a new
table for a different site you are working on, but the table is just a
bit different (that is - fields in different order, etc.).
By Steve Shreeve.
-@item @uref{http://www.mysql.com/Downloads/Contrib/oracledump, oracledump}
+@item @uref{http://www.mysql.com/Downloads/Contrib/oracledump}
Perl program to convert Oracle databases to MySQL. Has same
output format as mysqldump. By Johan Andersson.
-@item @uref{http://www.mysql.com/Downloads/Contrib/excel2mysql.pl, excel2mysql.pl}
-Perl program to import Excel spreadsheets into a MySQL database. By Stephen Hurd @email{shurd@@sk.sympatico.ca}
+@item @uref{http://www.mysql.com/Downloads/Contrib/excel2mysql}
+Perl program to import Excel spreadsheets into a MySQL database.
+By Stephen Hurd @email{shurd@@sk.sympatico.ca}
-@item @uref{http://www.mysql.com/Downloads/Contrib/T2S_100.ZIP, T2S_100.ZIP}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/T2S_100.ZIP}.
Windows program to convert text files to MySQL databases. By
Asaf Azulay.
@@ -46116,15 +49320,15 @@ Asaf Azulay.
@appendixsec Using MySQL with Other Products
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/emacs-sql-mode.tar.gz, emacs-sql-mode.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/emacs-sql-mode.tar.gz}
Raw port of a SQL mode for XEmacs. Supports completion. Original by
Peter D. Pezaris @email{pez@@atlantic2.sbi.com} and partial
MySQL port by David Axmark.
-@item @uref{http://www.mysql.com/Downloads/Win32/myaccess97_1_4.zip, MyAccess97 1.4}.
-@item @uref{http://www.mysql.com/Downloads/Win32/myaccess2000_1_4.zip, MyAccess2000 1.4}.
+@item @uref{http://www.mysql.com/Downloads/Win32/myaccess97_1_4.zip} (MyAccess97 1.4)
+@item @uref{http://www.mysql.com/Downloads/Win32/myaccess2000_1_4.zip} (MyAccess2000 1.4)
-MyAccess is an AddIn for MS Access 97/2000 that allows you to manage
+MyAccess is an AddIn for MS Access 97/2000 that allows you to manage
MySQL databases from within Access. Main functions are:
@itemize @minus
@item Create/Modify Tables
@@ -46135,67 +49339,66 @@ MySQL databases from within Access. Main functions are:
@item Show a "Database Definition Report
@end itemize
-Written by Hubertus Hiden. @uref{http://www.accessmysql.com, MyAccess homepage}.
+Written by Hubertus Hiden.
+The MyAccess homepage is at @uref{http://www.accessmysql.com/}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/radius-0.3.tar.gz, radius-0.3.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/radius-0.3.tar.gz}
Patches for @code{radiusd} to make it support MySQL. By Wim Bonis,
@email{bonis@@kiss.de}.
@end itemize
-@cindex tools, useful
-@appendixsec Useful Tools
+@cindex utilities
+@appendixsec Utilities
@itemize @bullet
-@item @uref{http://worldcommunity.com/opensource/utilities/mysql_backup.html, MySQL Backup}.
-
-A backup script for MySQL. By Peter F. Brown.
+@item @uref{http://worldcommunity.com/opensource/utilities/mysql_backup.html}
+MySQL Backup is a backup script for MySQL. By Peter F. Brown.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mytop, mytop}
-@item @uref{http://public.yahoo.com/~jzawodn/mytop/, mytop home page}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mytop}
+@item @uref{http://public.yahoo.com/~jzawodn/mytop/} (mytop home page)
mytop is a Perl program that allows you to monitor MySQL servers by
viewing active threads, queries, and overall server performance
numbers. By Jeremy D. Zawodny.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_watchdog.pl, mysql_watchdog.pl}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_watchdog.pl}
Monitor the MySQL daemon for possible lockups. By Yermo Lamers,
@email{yml@@yml.com}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltop.tar.gz, mysqltop.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltop.tar.gz}
Sends a query in a fixed time interval to the server and shows the
resulting table. By Thomas Wana.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tar.gz,mysql_structure_dumper.tar.gz}
-Prints out the structure of the all tables in a database. By Thomas Wana.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tgz, structure_dumper.tgz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tgz}
Prints the structure of every table in a database. By Thomas Wana.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlsync, mysqlsync-1.0-alpha.tar.gz}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlsync}.
A Perl script to keep remote copies of a MySQL database in sync with a
central master copy. By Mark Jeftovic. @email{markjr@@easydns.com}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLTutor-0.2.tar.gz, MySQLTutor}.
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLTutor-0.2.tar.gz}.
MySQLTutor. A MySQL tutorial for beginners.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB.zip, MySQLDB.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB-readme.html}.
A COM library for MySQL by Alok Singh.
-@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB-readme.html, MySQLDB-readme.html}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_replicate.pl, mysql_replicate.pl}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_replicate.pl}
Perl program that handles replication. By @email{elble@@icculus.nsg.nwu.edu}
-@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz, DBIx-TextIndex-0.02.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz}
Perl script that uses reverse indexing to handle text searching.
By Daniel Koch.
-@item @uref{http://www.mysql.com/Downloads/Contrib/dbcheck, dbcheck}
+@item @uref{http://www.mysql.com/Downloads/Contrib/dbcheck}
Perl script that takes a backup of tables before running isamchk on them.
By Elizabeth.
@item @uref{http://www.mysql.com/Downloads/Contrib/mybackup}.
-@item @uref{http://www.mswanson.com/mybackup, mybackup home page}
+@item @uref{http://www.mswanson.com/mybackup} (mybackup home page)
Wrapper for mysqldump to backup all databases. By Marc Swanson.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mdu.pl.gz,mdu.pl.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mdu.pl.gz}
Prints the storage usage of a MySQL database.
@end itemize
@@ -46204,55 +49407,55 @@ Prints the storage usage of a MySQL database.
@appendixsec RPMs for Common Tools (Most Are for RedHat 6.1)
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Data-ShowTable-3.3-2.i386.rpm,perl-Data-ShowTable-3.3-2.i386.rpm}
-@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Msql-Mysql-modules-1.2210-2.i386.rpm,perl-Msql-Mysql-modules-1.2210-2.i386.rpm}
-@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-3.0.13-1.i386.rpm,php-pg-3.0.13-1.i386.rpm}
-@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-manual-3.0.13-1.i386.rpm,php-pg-manual-3.0.13-1.i386.rpm}
-@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-mysql-3.0.13-1.i386.rpm,php-pg-mysql-3.0.13-1.i386.rpm}
-@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin-2.0.5-1.noarch.rpm,phpMyAdmin-2.0.5-1.noarch.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Data-ShowTable-3.3-2.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Msql-Mysql-modules-1.2210-2.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-3.0.13-1.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-manual-3.0.13-1.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-mysql-3.0.13-1.i386.rpm}
+@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin-2.0.5-1.noarch.rpm}
@end itemize
@cindex functions, useful
@appendixsec Useful Functions
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/mysnprintf.c,mysnprintf.c}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mysnprintf.c}
sprintf() function for SQL queries that can escape blobs. By Chunhua Liu.
@end itemize
-@appendixsec Windows programs
+@appendixsec Windows Programs
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/LaunchMySQL.zip, LaunchMySQL.zip}
+@item @uref{http://www.mysql.com/Downloads/Contrib/LaunchMySQL.zip}
The program launches the MySQL server, shuts it down, and
display status information. By Bill Thompson
@end itemize
-@appendixsec Uncategorized
+@appendixsec Uncategorised
@itemize @bullet
-@item @uref{http://www.mysql.com/Downloads/Contrib/findres.pl, findres.pl}
+@item @uref{http://www.mysql.com/Downloads/Contrib/findres.pl}
Find reserved words in tables. By Nem W Schlecht.
-@item @uref{http://www.mysql.com/Downloads/Contrib/handicap.tar.gz, handicap.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/handicap.tar.gz}
Performance handicapping system for yachts. Uses PHP. By
@email{rhill@@stobyn.ml.org}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/hylalog-1.0.tar.gz, hylalog-1.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/hylalog-1.0.tar.gz}
Store @code{hylafax} outgoing faxes in a MySQL database. By Sinisa
Milivojevic, @email{sinisa@@mysql.com}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/mrtg-mysql-1.0.tar.gz, mrtg-mysql-1.0.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/mrtg-mysql-1.0.tar.gz}
MySQL status plotting with MRTG, by Luuk de Boer, @email{luuk@@wxs.nl}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/wuftpd-2.4.2.18-mysql_support.2.tar.gz, wuftpd-2.4.2.18-mysql_support.2.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/wuftpd-2.4.2.18-mysql_support.2.tar.gz}
Patches to add logging to MySQL for WU-ftpd. By Zeev Suraski,
@email{bourbon@@netvision.net.il}.
-@item @uref{http://www.mysql.com/Downloads/Contrib/wu-ftpd-2.6.0-mysql.4.tar.gz,wu-ftpd-2.6.0-mysql.4.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/wu-ftpd-2.6.0-mysql.4.tar.gz}
Patches to add logging to MySQL for WU-ftpd 2.6.0. By
@email{takeshi@@SoftAgency.co.jp}, based on Zeev Suraski wuftpd patches.
-@item @uref{http://www.mysql.com/Downloads/Contrib/Old-Versions, Old-Versions}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Old-Versions}
Previous versions of things found here that you probably won't be
interested in.
@end itemize
@@ -46279,14 +49482,15 @@ helped to make MySQL what it is today.
@node Developers, Contributors, Credits, Credits
@appendixsec Developers at MySQL AB
-These are the developers that are or have been employed by MySQL AB
-to work on MySQL, roughly in the order they started to work with us.
-Following each developer is a small list of the tasks that the developer is
-responsible for, or the accomplishments they have made.
+These are the developers that are or have been employed by @code{MySQL AB}
+to work on the @code{MySQL} database software, roughly in the order they
+started to work with us. Following each developer is a small list of the
+tasks that the developer is responsible for, or the accomplishments they
+have made.
@table @asis
@item Michael (Monty) Widenius
-Has written the following parts of MySQL:
+Has written the following parts of the MySQL database software:
@itemize @bullet
@item
All the main code in @code{mysqld}.
@@ -46301,17 +49505,17 @@ handlers with index compression and different record formats).
The @code{HEAP} library. A memory table system with our superior full dynamic
hashing. In use since 1981 and published around 1984.
@item
-The @code{replace} program (look into it, it's COOL!).
+The @code{replace} program (take a look at it, it's @strong{COOL}!).
@item
-@strong{MyODBC}, the ODBC driver for Windows95.
+@code{MyODBC}, the ODBC driver for Windows95.
@item
-Fixing bugs in MIT-pthreads to get it to work for MySQL. And
+Fixing bugs in MIT-pthreads to get it to work for MySQL Server. And
also Unireg, a curses-based application tool with many utilities.
@item
Porting of @code{mSQL} tools like @code{msqlperl}, @code{DBD}/@code{DBI}, and
@code{DB2mysql}.
@item
-Most of crash-me and the foundation for the MySQL benchmarks.
+Most of @code{crash-me} and the foundation for the MySQL benchmarks.
@end itemize
@item David Axmark
@@ -46320,20 +49524,20 @@ Most of crash-me and the foundation for the MySQL benchmarks.
Coordinator and initial main writer of the @strong{Reference Manual},
including enhancements to @code{texi2html}.
@item
-Automatic Web site updating from the manual.
+Automatic web site updating from the manual.
@item
Initial Autoconf, Automake, and Libtool support.
@item
-The licensing stuff.
+Licensing.
@item
Parts of all the text files. (Nowadays only the @file{README} is
left. The rest ended up in the manual.)
@item
Lots of testing of new features.
@item
-Our in-house ``free'' software lawyer.
+Our in-house Free Software legal expert.
@item
-Mailing list maintainer (who never has the time to do it right...)
+Mailing list maintainer (who never has the time to do it right...).
@item
Our original portability code (more than 10 years old now). Nowadays
only some parts of @code{mysys} are left.
@@ -46349,7 +49553,7 @@ that new feature to work.
@item
A lot of extensions to the @code{mysql} client.
@item
-@code{procedure analyse()}
+@code{PROCEDURE ANALYSE()}
@end itemize
@item Sinisa Milivojevic
@@ -46357,11 +49561,37 @@ A lot of extensions to the @code{mysql} client.
@item
Compression (with @code{zlib}) in the client/server protocol.
@item
-Perfect hashing for the lexical analyzer phase.
+Perfect hashing for the lexical analyser phase.
+@item
+Multi-row @code{INSERT}
+@item
+@code{mysqldump} -e option
+@item
+@code{LOAD DATA LOCAL INFILE}
+@item
+@code{SQL_CALC_FOUND_ROWS} @code{SELECT} option
+@item
+@code{--max-user-connections=...} option
+@item
+@code{net_read} and @code{net_write_timeout}
+@item
+@code{GRANT}/@code{REVOKE} and @code{SHOW GRANTS FOR}
+@item
+New client-server protocol for 4.0
+@item
+@code{UNION}.
+@item
+Multi-table @code{DELETE}/@code{UPDATE}
+@item
+derived tables
@item
-The MySQLGUI client.
+user resources management
@item
-Maintainer of mysql++.
+OLAP functionality
+@item
+The @code{MySQLGUI} client.
+@item
+Maintainer of @code{MySQL++}.
@end itemize
@item Tonu Samuel
@@ -46369,14 +49599,14 @@ Maintainer of mysql++.
@item
Our security expert.
@item
-Vio interface (The foundation for the encrypted client/server protocol).
+VIO interface (the foundation for the encrypted client/server protocol).
@item
-MySQL Filesystem (A way to use MySQL databases as files
+MySQL Filesystem (a way to use MySQL databases as files
and directories).
@item
-The CASE Expression.
+The @code{CASE} expression.
@item
-The MD5() and COALESCE() functions.
+The @code{MD5()} and @code{COALESCE()} functions.
@item
@code{RAID} support for @code{MyISAM} tables.
@end itemize
@@ -46406,6 +49636,8 @@ Our webmaster.
@item Miguel Solorzano
@itemize @bullet
@item
+Win32 development.
+@item
Winmysqladmin.
@end itemize
@@ -46437,32 +49669,21 @@ Proofreading and editing this fine manual.
@code{DELETE ... ORDER BY ...}.
@end itemize
-@item John Dean
-@itemize @bullet
-@item
-The new MySQL GUI client.
-@end itemize
-
@item Indrek Siitan
@itemize @bullet
@item
Designer/programmer of our web interface.
@end itemize
-@end table
-
-The following non-developers are also working in/with MySQL AB:
-@table @asis
-@item
-Hans Kierkegaard - Responsible for MySQL license handling.
-@item
-Antti Halonen - Sales manager.
+@item Jorge del Conde
+@itemize @bullet
@item
-Jonas Norrman - Handles licensing questions sent to @email{info@@mysql.com}.
+@code{MyCC} @code{MySQL Control Center}.
@item
-Erik Granberg - Handles MySQL partners (and a lot of other stuff).
+Web portals.
@item
-Allan Larsson (The BOSS for TCX DataKonsult AB).
+Win32 development.
+@end itemize
@end table
@@ -46471,8 +49692,10 @@ Allan Larsson (The BOSS for TCX DataKonsult AB).
@cindex contributors, list of
-Contributors to the MySQL distribution are listed here, in
-somewhat random order:
+While @code{MySQL AB} owns all copyrights in the @code{MySQL server}
+and the @code{MySQL manual}, we wish to recognise those who have made
+contributions of one kind or another to the @code{MySQL distribution}.
+Contributors are listed here, in somewhat random order:
@table @asis
@item Paul DuBois
@@ -46491,18 +49714,19 @@ record format.
Win32 port with Borland compiler. @code{mysqlshutdown.exe} and
@code{mysqlwatch.exe}
@item David J. Hughes
-For the effort to make a shareware SQL database. We at TcX started with
-@code{mSQL}, but found that it couldn't satisfy our purposes so instead we
-wrote a SQL interface to our application builder Unireg. @code{mysqladmin}
-and @code{mysql} are programs that were largely influenced by their
-@code{mSQL} counterparts. We have put a lot of effort into making the
-MySQL syntax a superset of @code{mSQL}. Many of the API's ideas are
-borrowed from @code{mSQL} to make it easy to port free @code{mSQL} programs
-to MySQL. MySQL doesn't contain any code from @code{mSQL}.
+For the effort to make a shareware SQL database. At TcX, the predecessor
+of MySQL AB, we started with @code{mSQL}, but found that it couldn't
+satisfy our purposes so instead we wrote a SQL interface to our
+application builder Unireg. @code{mysqladmin} and @code{mysql} client are
+programs that were largely influenced by their @code{mSQL} counterparts.
+We have put a lot of effort into making the MySQL syntax a superset of
+@code{mSQL}. Many of the API's ideas are borrowed from @code{mSQL} to
+make it easy to port free @code{mSQL} programs to the MySQL API.
+The MySQL software doesn't contain any code from @code{mSQL}.
Two files in the distribution (@file{client/insert_test.c} and
@file{client/select_test.c}) are based on the corresponding (non-copyrighted)
files in the @code{mSQL} distribution, but are modified as examples showing
-the changes necessary to convert code from @code{mSQL} to MySQL.
+the changes necessary to convert code from @code{mSQL} to MySQL Server.
(@code{mSQL} is copyrighted David J. Hughes.)
@item Fred Fish
For his excellent C debugging and trace library. Monty has made a number
@@ -46517,9 +49741,9 @@ From whom we got an excellent compiler (@code{gcc}), the @code{libc} library
and the @code{readline} library (for the @code{mysql} client).
@item Free Software Foundation & The XEmacs development team
For a really great editor/environment used by almost everybody at
-TcX/MySQL AB/detron.
+MySQL AB/TcX/detron.
@item Patrick Lynch
-For helping us acquire @code{http://www.mysql.com/}.
+For helping us acquire @uref{http://www.mysql.com/}.
@item Fred Lindberg
For setting up qmail to handle the MySQL mailing list and for the
incredible help we got in managing the MySQL mailing lists.
@@ -46533,9 +49757,9 @@ For the @code{DBD} (Perl) interface.
@item Tim Bunce
Author of @code{mysqlhotcopy}.
@item Andreas Koenig @email{a.koenig@@mind.de}
-For the Perl interface to MySQL.
+For the Perl interface for MySQL Server.
@item Eugene Chan @email{eugene@@acenet.com.sg}
-For porting PHP to MySQL.
+For porting PHP for MySQL Server.
@item Michael J. Miller Jr. @email{mke@@terrapin.turbolift.com}
For the first MySQL manual. And a lot of spelling/language
fixes for the FAQ (that turned into the MySQL manual a long
@@ -46543,7 +49767,7 @@ time ago).
@item Yan Cailin
First translator of the MySQL Reference Manual into simplified
chinese in early 2000 on which the Big5 and HK coded
-(@uref{http://mysql.hitstar.com, mysql.hitstar.com}) versions were
+(@uref{http://mysql.hitstar.com/}) versions were
based. @uref{http://linuxdb.yeah.net, Personal home page at
linuxdb.yeah.net}.
@item Giovanni Maruzzelli @email{maruzz@@matrice.it}
@@ -46554,7 +49778,7 @@ software developed by Chris Provenzano, the University of California,
Berkeley, and contributors. We are currently using version 1_60_beta6
patched by Monty (see @file{mit-pthreads/Changes-mysql}).
@item Xavier Leroy @email{Xavier.Leroy@@inria.fr}
-The author of LinuxThreads (used by MySQL on Linux).
+The author of LinuxThreads (used by the MySQL Server on Linux).
@item Zarko Mocnik @email{zarko.mocnik@@dem.si}
Sorting for Slovenian language and the @file{cset.tar.gz} module that makes
it easier to add other character sets.
@@ -46566,15 +49790,14 @@ answering on the MySQL mailing list.
@item Yves Carlier @email{Yves.Carlier@@rug.ac.be}
@code{mysqlaccess}, a program to show the access rights for a user.
@item Rhys Jones @email{rhys@@wales.com} (And GWE Technologies Limited)
-For the JDBC, a module to extract data from MySQL with a Java
-client.
+For the JDBC, a module to extract data from a MySQL Database with a Java client.
@item Dr Xiaokun Kelvin ZHU @email{X.Zhu@@brad.ac.uk}
Further development of the JDBC driver and other MySQL-related
Java tools.
@item James Cooper @email{pixel@@organic.com}
For setting up a searchable mailing list archive at his site.
@item Rick Mehalick @email{Rick_Mehalick@@i-o.com}
-For @code{xmysql}, a graphical X client for MySQL.
+For @code{xmysql}, a graphical X client for MySQL Server.
@item Doug Sisk @email{sisk@@wix.com}
For providing RPM packages of MySQL for RedHat Linux.
@item Diemand Alexander V. @email{axeld@@vial.ethz.ch}
@@ -46598,7 +49821,7 @@ Spanish error messages.
Norwegian error messages and testing of Version 3.21.#.
@item Timur I. Bakeyev @email{root@@timur.tatarstan.ru}
Russian error messages.
-@item @email{brenno@@dewinter.com} && Filippo Grassilli @email{phil@@hyppo.com}
+@item @email{brenno@@dewinter.com} & Filippo Grassilli @email{phil@@hyppo.com}
Italian error messages.
@item Dirk Munzinger @email{dirk@@trinity.saar.de}
German error messages.
@@ -46625,7 +49848,7 @@ Active mailing list member.
@item Luuk de Boer @email{luuk@@wxs.nl}
Ported (and extended) the benchmark suite to @code{DBI}/@code{DBD}. Have
been of great help with @code{crash-me} and running benchmarks. Some new
-date functions. The mysql_setpermissions script.
+date functions. The @code{mysql_setpermissions} script.
@item Jay Flaherty @email{fty@@mediapulse.com}
Big parts of the Perl @code{DBI}/@code{DBD} section in the manual.
@item Paul Southworth @email{pauls@@etext.org}, Ray Loyzaga @email{yar@@cs.su.oz.au}
@@ -46640,11 +49863,11 @@ Help to set up InstallShield for MySQL-Win32.
@item Jethro Wright III @email{jetman@@li.net}
The @file{libmysql.dll} library.
@item James Pereria @email{jpereira@@iafrica.com}
-Mysqlmanager, a Win32 GUI tool for administrating MySQL.
+Mysqlmanager, a Win32 GUI tool for administrating MySQL Server.
@item Curt Sampson @email{cjs@@portal.ca}
Porting of MIT-pthreads to NetBSD/Alpha and NetBSD 1.3/i386.
@item Antony T. Curtis @email{antony.curtis@@olcs.net}
-Porting of MySQL to OS/2.
+Porting of the MySQL Database software to OS/2.
@item Martin Ramsch @email{m.ramsch@@computer.org}
Examples in the MySQL Tutorial.
@item Steve Harvey
@@ -46656,7 +49879,13 @@ MySQL server.
Configure updates for Tru64, large file support and better TCP wrappers
support.
@item John Birrell
-Emulation of pthread_mutex() for OS/2.
+Emulation of @code{pthread_mutex()} for OS/2.
+@item Benjamin Pflugmann
+Extended @code{MERGE} tables to handle @code{INSERTS}. Active member
+on the MySQL mailing lists.
+@item Guilhem Bichot
+Fixed handling of exponents for @code{DECIMAL}.
+Author of @code{mysql_tableinfo}.
@end table
Other contributors, bugfinders, and testers: James H. Thompson, Maurizio
@@ -46711,13 +49940,14 @@ ODBC and VisualC++ interface questions.
@cindex contributing companies, list of
-The following companies has helped us finance development of
-MySQL by either paying us for developing a new feature,
-developed a MySQL feature themselves or by giving us hardware for
-MySQL development.
+While @code{MySQL AB} owns all copyrights in the @code{MySQL server}
+and the @code{MySQL manual}, we wish to recognise the following companies,
+which helped us finance the development of the @code{MySQL server},
+such as by paying us for developing a new feature or giving us hardware
+for development of the @code{MySQL server}.
@table @asis
-@item VA Linux / Andover.net
+@item VA Linux / Andover.net
Funded replication.
@item NuSphere
Editing of the MySQL manual.
@@ -46730,14 +49960,14 @@ Contributed to Development on Linux/Alpha.
@item SWSoft
Development on the embedded @code{mysqld} version.
@item FutureQuest
-@code{--skip-show-variables}
+@code{--skip-show-database}
@end table
@node News, Porting, Credits, Top
-@appendix MySQL change history
+@appendix MySQL Change History
@cindex ChangeLog
@cindex changes, log
@@ -46746,12 +49976,14 @@ Development on the embedded @code{mysqld} version.
This appendix lists the changes from version to version in the MySQL
source code.
-Note that we tend to update the manual at the same time we make changes to
-MySQL. If you find a version listed below that you can't
-find on the
-@uref{http://www.mysql.com/downloads/,MySQL download page},
+Note that we tend to update the manual at the same time we make changes to
+MySQL. If you find a version listed here that you can't
+find on the MySQL download page
+(@uref{http://www.mysql.com/downloads/}),
this means that the version has not yet been released!
+@c Please don't add a new version here without also updating ../configure.in!
+
@menu
* News-4.0.x:: Changes in release 4.0.x (Development; Alpha)
* News-3.23.x:: Changes in release 3.23.x (Stable)
@@ -46765,49 +49997,479 @@ this means that the version has not yet been released!
@node News-4.0.x, News-3.23.x, News, News
@appendixsec Changes in release 4.0.x (Development; Alpha)
-We have now started to work on MySQL 4.0. We will update this
-section as we add new features, so that others can follow our development.
+We are now working actively on MySQL 4.0 and will only provide critical
+bug fixes for MySQL 3.23. We will update this section as we add new
+features, so that others can follow our development.
Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
+@cindex changes, version 4.0
+
@menu
-* News-4.0.0:: Changes in release 4.0.0
+* News-4.0.3:: Changes in release 4.0.3
+* News-4.0.2:: Changes in release 4.0.2 (01 July 2002)
+* News-4.0.1:: Changes in release 4.0.1 (23 Dec 2001)
+* News-4.0.0:: Changes in release 4.0.0 (Oct 2001: Alpha)
@end menu
+@node News-4.0.3, News-4.0.2, News-4.0.x, News-4.0.x
+@appendixsubsec Changes in release 4.0.3
+@itemize @bullet
+@item
+Allow @code{DEFAULT} with @code{INSERT} statement.
+@item
+The startup parameters @code{myisam_max_extra_sort_file_size} and
+@code{myisam_max_extra_sort_file_size} are now given in bytes, not megabytes.
+@item
+External system locking of MyISAM/ISAM files is now turned off by default.
+One can turn this one by doing @code{--external-locking}. (For most users
+this is never needed).
+@item
+Fixed core dump bug with @code{INSERT ... SET db_name.table_name.colname=''}.
+@item
+Fixed client hangup bug when using some SQL commands with wrong syntax.
+@item
+Fixed a timing bug in @code{DROP DATABASE}
+@item
+New @code{SET [GLOBAL | SESSION]} syntax to change thread specific and global
+server variables at runtime.
+@item
+Renamed variable @code{query_cache_startup_type} to @code{query_cache_type},
+@code{myisam_bulk_insert_tree_size} to @code{bulk_insert_buffer_size},
+@code{record_buffer} to @code{read_buffer_size} and
+@code{record_rnd_buffer} to @code{record_rnd_buffer_size}.
+@item
+Renamed some sql variables, but old names will still work until 5.0.
+@xref{Upgrading-from-3.23}.
+@item
+Renamed @code{--skip-locking} to @code{--skip-external-locking}.
+@item
+Removed not used variable @code{query_buffer_size}.
+@item
+Fixed a bug that made the pager option in the @code{mysql} client
+non-functional.
+@item
+Added full @code{AUTO_INCREMENT} support to @code{MERGE} tables.
+@end itemize
-@node News-4.0.0, , News-4.0.x, News-4.0.x
-@appendixsubsec Changes in release 4.0.0
+@node News-4.0.2, News-4.0.1, News-4.0.3, News-4.0.x
+@appendixsubsec Changes in release 4.0.2 (01 July 2002)
+
+@itemize @bullet
+@item
+Changed @code{--chroot=path} option to execute @code{chroot()} immediately
+after all options have been parsed.
+@item
+Don't allow database names that contain @samp{\}.
+@item
+@code{lower_case_table_names} now also affects created and dropped databases.
+@item
+Added @code{XOR} operator (logical and bitwise @code{XOR}) with @code{^}
+as a synonym for bitwise @code{XOR}.
+@item
+Added function @code{IS_FREE_LOCK("lock_name")}.
+Based on code contributed by Hartmut Holzgraefe @email{hartmut@@six.de}.
+@item
+Removed @code{mysql_ssl_clear()} from C API, as it was not needed.
+@item
+@code{DECIMAL} and @code{NUMERIC} types can now read exponential numbers.
+@item
+Added @code{SHA1()} function to calculate 160 bit hash value as described
+in RFC 3174 (Secure Hash Algorithm). This function can be considered a
+cryptographically more secure equivalent of @code{MD5()}.
+@xref{Miscellaneous functions}.
+@item
+Added @code{AES_ENCRYPT()} and @code{AES_DECRYPT()} functions to perform
+encryption according to AES standard (Rijndael).
+@xref{Miscellaneous functions}.
+@item
+Added @code{--single-transaction} option to @code{mysqldump}, allowing a
+consistent dump of @code{InnoDB} tables.
+@xref{mysqldump}.
+@item
+Fixed bug in @code{innodb_log_group_home_dir} in @code{SHOW VARIABLES}.
+@item
+Fixed a bug in optimiser with merge tables when non-unique values are
+used in summing up (causing crashes).
+@item
+Fixed a bug in optimiser when a range specified makes index grouping
+impossible (causing crashes).
+@item
+Fixed a rare bug when @code{FULLTEXT} index is present and no tables are used.
+@item
+Added privileges @code{CREATE TEMPORARY TABLES}, @code{EXECUTE},
+@code{LOCK TABLES}, @code{REPLICATION CLIENT}, @code{REPLICATION SLAVE},
+@code{SHOW DATABASES} and @code{SUPER}. To use these, you must have
+run the @code{mysql_fix_privilege_tables} script after upgrading.
+@item
+Fixed query cache align data bug.
+@item
+Fixed mutex bug in replication when reading from master fails.
+@item
+Added missing mutex in @code{TRUNCATE TABLE}; This fixes some core
+dump/hangup problems when using @code{TRUNCATE TABLE}.
+@item
+Fixed bug in multi-table @code{DELETE} when optimiser uses only indices.
+@item
+Fixed that @code{ALTER TABLE table_name RENAME new_table_name} is as fast
+as @code{RENAME TABLE}.
+@item
+Fixed bug in @code{GROUP BY} with two or more fields, where at least one
+field can contain @code{NULL} values.
+@item
+Use @code{Turbo Boyer-Moore} algorithm to speed up @code{LIKE "%keyword%"}
+searches.
+@item
+Fixed bug in @code{DROP DATABASE} with symlink.
+@item
+Fixed crash in @code{REPAIR ... USE_FRM}.
+@item
+Fixed bug in @code{EXPLAIN} with @code{LIMIT offset != 0}.
+@item
+Fixed bug in phrase operator @code{"..."} in boolean full-text search.
+@item
+Fixed bug that caused duplicated rows when using truncation operator
+@code{*} in boolean full-text search.
+@item
+Fixed bug in truncation operator of boolean full-text search (wrong results
+when there are only @code{+word*}s in the query).
+@item
+Fixed bug in boolean full-text search that caused a crash when an identical
+@code{MATCH} expression that did not use an index appeared twice.
+@item
+Query cache is now automatically disabled in @code{mysqldump}.
+@item
+Fixed problem on Windows 98 that made sending of results very slow.
+@item
+Boolean full-text search weighting scheme changed to something more reasonable.
+@item
+Fixed bug in boolean full-text search that caused MySQL to ignore queries of
+@code{ft_min_word_len} characters.
+@item
+Boolean full-text search now supports ``phrase searches''.
+@item
+New configure option @code{--without-query-cache}.
+@item
+Memory allocation strategy for ``root memory'' changed. Block size now grows
+with number of allocated blocks.
+@item
+@code{INET_NTOA()} now returns @code{NULL} if you give it an argument that
+is too large (greater than the value corresponding to @code{255.255.255.255}).
+@item
+Fix @code{SQL_CALC_FOUND_ROWS} to work with @code{UNION}s. It will work only
+if the first @code{SELECT} has this option and if there is global @code{LIMIT}
+for the entire statement. For the moment, this requires using parentheses for
+individual @code{SELECT} queries within the statement.
+@item
+Fixed bug in @code{SQL_CALC_FOUND_ROWS} and LIMIT.
+@item
+Don't give an error for @code{CREATE TABLE ...(... VARCHAR(0))}.
+@item
+Fixed @code{SIGINT} and @code{SIGQUIT} problems in @file{mysql.cc} on Linux
+with some @code{glibc} versions.
+@item
+Fixed bug in @file{convert.cc}, which is caused by having an incorrect
+@code{net_store_length()} linked in the @code{CONVERT::store()} method.
+@item
+@code{DOUBLE} and @code{FLOAT} columns now honor the @code{UNSIGNED} flag
+on storage.
+@item
+@code{InnoDB} now retains foreign key constraints through @code{ALTER TABLE}
+and @code{CREATE/DROP INDEX}.
+@item
+@code{InnoDB} now allows foreign key constraints to be added through the
+@code{ALTER TABLE} syntax.
+@item
+@code{InnoDB} tables can now be set to automatically grow in size (autoextend).
+@item
+Added @code{--ignore-lines=n} option to @code{mysqlimport}. This has the
+same effect as the @code{IGNORE n LINES} clause for @code{LOAD DATA}.
+@item
+Fixed bug in @code{UNION} with last offset being transposed to total result
+set.
+@item
+@code{REPAIR ... USE_FRM} added.
+@item
+Fixed that @code{DEFAULT_SELECT_LIMIT} is always imposed on @code{UNION}
+result set.
+@item
+Fixed that some @code{SELECT} options can appear only in the first
+@code{SELECT}.
+@item
+Fixed bug with @code{LIMIT} with @code{UNION}, where last select is in
+the braces.
+@item
+Fixed that full-text works fine with @code{UNION} operations.
+@item
+Fixed bug with indexless boolean full-text search.
+@item
+Fixed bug that sometimes appeared when full-text search was used
+with ``const'' tables.
+@item
+Fixed incorrect error value when doing a @code{SELECT} with an empty
+@code{HEAP} table.
+@item
+Use @code{ORDER BY column DESC} now sorts @code{NULL} values first.
+@item
+Fixed bug in @code{WHERE key_name='constant' ORDER BY key_name DESC}.
+@item
+Fixed bug in @code{SELECT DISTINCT ... ORDER BY DESC} optimisation.
+@item
+Fixed bug in @code{... HAVING 'GROUP_FUNCTION'(xxx) IS [NOT] NULL}.
+@item
+Fixed bug in truncation operator for boolean full-text search.
+@item
+Allow value of @code{--user=#} option for @code{mysqld} to be specified
+as a numeric user ID.
+@item
+Fixed a bug where @code{SQL_CALC_ROWS} returned an incorrect value when used
+with one table and @code{ORDER BY} and with @code{InnoDB} tables.
+@item
+Fixed that @code{SELECT 0 LIMIT 0} doesn't hang thread.
+@item
+Fixed some problems with @code{USE/IGNORE INDEX} when using
+many keys with the same start column.
+@item
+Don't use table scan with @code{BerkeleyDB} and @code{InnoDB} tables when
+we can use an index that covers the whole row.
+@item
+Optimised @code{InnoDB} sort-buffer handling to take less memory.
+@item
+Fixed bug in multi-table @code{DELETE} and @code{InnoDB} tables.
+@item
+Fixed problem with @code{TRUNCATE} and @code{InnoDB} tables that produced the
+error @code{Can't execute the given command because you have active locked
+tables or an active transaction}.
+@item
+Added @code{NO_UNSIGNED_SUBTRACTION} to the set of flags that may be
+specified with the @code{--sql-mode} option for @code{mysqld}. It disables
+unsigned arithmetic rules when it comes to subtraction. (This will make
+MySQL 4.0 behave more closely to 3.23 with @code{UNSIGNED} columns).
+@item
+The result returned for all bit functions (@code{|}, @code{<<}, ...) is now of
+type @code{unsigned integer}.
+@item
+Added detection of @code{nan} values in @code{MyISAM} to make it possible to
+repair tables with @code{nan} in float or double columns.
+@item
+Fixed new bug in @code{myisamchk} where it didn't correctly update number of
+``parts'' in the @code{MyISAM} index file.
+@item
+Changed to use @code{autoconf} 2.52 (from @code{autoconf} 2.13).
+@item
+Fixed optimisation problem where the MySQL Server was in ``preparing'' state
+for a long time when selecting from an empty table which had contained
+a lot of rows.
+@item
+Fixed bug in complicated join with @code{const} tables. This fix also
+improves performance a bit when referring to another table from a
+@code{const} table.
+@item
+First pre-version of multi-table @code{UPDATE} statement.
+@item
+Fixed bug in multi-table @code{DELETE}.
+@item
+Fixed bug in @code{SELECT CONCAT(argument_list) ... GROUP BY 1}.
+@item
+@code{INSERT ... SELECT} did a full rollback in case of an error. Fixed
+so that we only roll back the last statement in the current transaction.
+@item
+Fixed bug with empty expression for boolean full-text search.
+@item
+Fixed core dump bug in updating full-text key from/to @code{NULL}.
+@item
+ODBC compatibility: Added @code{BIT_LENGTH()} function.
+@item
+Fixed core dump bug in @code{GROUP BY BINARY column}.
+@item
+Added support for @code{NULL} keys in @code{HEAP} tables.
+@item
+Use index for @code{ORDER BY} in queries of type:
+@code{SELECT * FROM t WHERE key_part1=1 ORDER BY key_part1 DESC,key_part2 DESC}
+@item
+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}
+statement. For more information, read @ref{Cast Functions}.
+@item
+@code{CREATE ... SELECT} on @code{DATE} and @code{TIME} functions now
+create columns of the expected type.
+@item
+Changed order in which keys are created in tables.
+@item
+Added new columns @code{Null} and @code{Index_type} to @code{SHOW INDEX}
+output.
+@item
+Added @code{--no-beep} and @code{--prompt} options to @code{mysql} command-line client.
+@item
+New feature: management of user resources.
+@example
+GRANT ... WITH MAX_QUERIES_PER_HOUR N1
+ MAX_UPDATES_PER_HOUR N2
+ MAX_CONNECTIONS_PER_HOUR N3;
+@end example
+@xref{User resources}.
+
+@item
+Added @code{mysql_secure_installation} to the @file{scripts/} directory.
+@end itemize
-@cindex changes, version 4.0
+
+@node News-4.0.1, News-4.0.0, News-4.0.2, News-4.0.x
+@appendixsubsec Changes in release 4.0.1 (23 Dec 2001)
@itemize @bullet
@item
-Multi-table @code{DELETE}.
+Fixed bug when @code{HANDLER} was used with some unsupported table type.
@item
-Don't support old client protocols prior to MySQL 3.21 any more.
+@code{mysqldump} now puts @code{ALTER TABLE tbl_name DISABLE KEYS} and
+@code{ALTER TABLE tbl_name ENABLE KEYS} in the sql dump.
@item
-Don't include the old C API functions @code{mysql_drop_db},
-@code{mysql_create_db} and @code{mysql_connect}, unless compiled with
-@code{USE_OLD_FUNCTIONS}.
+Added @code{mysql_fix_extensions} script.
@item
-Renamed @code{safe_mysqld} to @code{mysqld_safe}.
+Fixed stack overrun problem with @code{LOAD DATA FROM MASTER} on OSF/1.
@item
-Allow @code{IN} as a synonym for @code{FROM} in @code{SHOW} commands.
+Fixed shutdown problem on HP-UX.
@item
-@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}.
+Added @code{DES_ENCRYPT()} and @code{DES_DECRYPT()} functions.
@item
-Added support for symbolic links to @code{MyISAM} tables. Symlink handling is
-now enabled by default for Windows.
+Added @code{FLUSH DES_KEY_FILE} statement.
@item
-@code{LOAD DATA FROM MASTER} ``auto-magically'' sets up a slave.
+Added @code{--des-key-file} option to @code{mysqld}.
+@item
+@code{HEX(string)} now returns the characters in @code{string} converted to
+hexadecimal.
+@item
+Fixed problem with @code{GRANT} when using @code{lower_case_table_names == 1}.
+@item
+Changed @code{SELECT ... IN SHARE MODE} to
+@code{SELECT ... LOCK IN SHARE MODE} (as in MySQL 3.23).
+@item
+A new query cache to cache results from identical @code{SELECT} queries.
+@item
+Fixed core dump bug on 64-bit machines when it got an incorrect communication
+packet.
+@item
+@code{MATCH ... AGAINST(... IN BOOLEAN MODE)} can now work
+without @code{FULLTEXT} index.
+@item
+Fixed slave to replicate from 3.23 master.
+@item
+Miscellaneous replication fixes/cleanup.
+@item
+Got shutdown to work on Mac OS X.
+@item
+Added @file{myisam/ft_dump} utility for low-level inspection
+of @code{FULLTEXT} indexes.
+@item
+Fixed bug in @code{DELETE ... WHERE ... MATCH ...}.
+@item
+Added support for @code{MATCH ... AGAINST(... IN BOOLEAN MODE)}.
+@strong{Note: you must rebuild your tables with
+@code{ALTER TABLE tablename TYPE=MyISAM} to be
+able to use boolean full-text search}.
+@item
+@code{LOCATE()} and @code{INSTR()} are now case-sensitive if either
+argument is a binary string.
+@item
+Changed @code{RAND()} initialisation so that @code{RAND(N)} and
+@code{RAND(N+1)} are more distinct.
+@item
+Fixed core dump bug in @code{UPDATE ... ORDER BY}.
+@item
+Changed @code{INSERT INTO ... SELECT} to stop on errors by default.
+@item
+Ignore @code{DATA DIRECTORY} and @code{INDEX DIRECTORY} directives on Windows.
+@item
+Added boolean full-text search code. It should be considered early alpha.
+@item
+Extended @code{MODIFY} and @code{CHANGE} in @code{ALTER TABLE} to accept
+the @code{FIRST} and @code{AFTER} keywords.
+@item
+Indexes are now used with @code{ORDER BY} on a whole @code{InnoDB} table.
+@end itemize
+
+
+@node News-4.0.0, , News-4.0.1, News-4.0.x
+@appendixsubsec Changes in release 4.0.0 (Oct 2001: Alpha)
+
+@itemize @bullet
+@item
+Added @code{--xml} option to @code{mysql} for producing XML output.
+@item
+Added full-text variables @code{ft_min_word_len}, @code{ft_max_word_len}, and
+@code{ft_max_word_len_for_sort}.
+@item
+Added documentation for @code{libmysqld}, the embedded MySQL server
+library. Also added example programs (a @code{mysql} client and
+@code{mysqltest} test program) which use @code{libmysqld}.
+@item
+Removed all Gemini hooks from MySQL server.
+@item
+Removed @code{my_thread_init()} and @code{my_thread_end()}
+from @file{mysql_com.h}, and added @code{mysql_thread_init()} and
+@code{mysql_thread_end()} to @file{mysql.h}.
+@item
+Support for communication packets > 16M. In 4.0.1 we will extend
+@code{MyISAM} to be able to handle these.
+@item
+Secure connections (with SSL).
+@item
+Unsigned @code{BIGINT} constants now work. @code{MIN()} and @code{MAX()}
+now handle signed and unsigned @code{BIGINT} numbers correctly.
+@item
+New character set @code{latin_de} which provides correct German sorting.
+@item
+@code{STRCMP()} now uses the current character set when doing comparisons,
+which means that the default comparison behaviour now is case-insensitive.
+@item
+@code{TRUNCATE TABLE} and @code{DELETE FROM tbl_name} are now separate
+functions. One bonus is that @code{DELETE FROM tbl_name} now returns
+the number of deleted rows, rather than zero.
+@item
+@code{DROP DATABASE} now executes a @code{DROP TABLE} on all tables in
+the database, which fixes a problem with @code{InnoDB} tables.
+@item
+Added support for @code{UNION}.
+@item
+@code{DELETE} can now operate on multiple tables.
@item
A new @code{HANDLER} interface to @code{MyISAM} tables.
@item
+Added support for @code{INSERT} on @code{MERGE} tables. Patch from
+Benjamin Pflugmann.
+@item
+Changed @code{WEEK(#,0)} to match the calendar in the USA.
+@item
@code{COUNT(DISTINCT)} is about 30% faster.
@item
-@code{FULLTEXT} index creation now is much faster.
+Speed up all internal list handling.
+@item
+Speed up @code{IS NULL}, @code{ISNULL()} and some other internal primitives.
+@item
+Full-text index creation now is much faster.
+@item
+Tree-like cache to speed up bulk inserts and
+@code{myisam_bulk_insert_tree_size} variable.
+@item
+Searching on packed (@code{CHAR}/@code{VARCHAR}) keys is now much faster.
+@item
+Optimised queries of type:
+@code{SELECT DISTINCT * from tbl_name ORDER by key_part1 LIMIT #}.
@item
-Searching on packed (@code{CHAR}/@code{VARCHAR}) keys now is much faster.
+@code{SHOW CREATE TABLE} now shows all table attributes.
+@item
+@code{ORDER BY ... DESC} can now use keys.
+@item
+@code{LOAD DATA FROM MASTER} ``auto-magically'' sets up a slave.
+@item
+Renamed @code{safe_mysqld} to @code{mysqld_safe} to make this name more
+in line with other MySQL scripts/commands.
+@item
+Added support for symbolic links to @code{MyISAM} tables. Symlink handling is
+now enabled by default for Windows.
@item
Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it
possible to know how many rows a query would have returned
@@ -46821,8 +50483,28 @@ Added @code{IDENTITY} as a synonym for @code{AUTO_INCREMENT} (like Sybase).
@item
Added @code{ORDER BY} syntax to @code{UPDATE} and @code{DELETE}.
@item
-Optimized queries of type:
-@code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #}
+@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}.
+@item
+Added @code{ALTER TABLE tbl_name DISABLE KEYS} and
+@code{ALTER TABLE tbl_name ENABLE KEYS} commands.
+@item
+Allow use of @code{IN} as a synonym for @code{FROM} in @code{SHOW} commands.
+@item
+Implemented ``repair by sort'' for @code{FULLTEXT} indexes.
+@code{REPAIR TABLE}, @code{ALTER TABLE}, and @code{OPTIMIZE TABLE}
+for tables with @code{FULLTEXT} indexes are now up to 100 times faster.
+@item
+Allow ANSI SQL syntax @code{X'hexadecimal-number'}.
+@item
+Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK}.
+@item
+Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimisation.
+@item
+Added @code{--master-data} and @code{--no-autocommit} options to
+@code{mysqldump}. (Thanks to Brian Aker for this.)
+@item
+Added script @code{mysql_explain_log.sh} to distribution.
+(Thanks to mobile.de).
@end itemize
@@ -46836,19 +50518,19 @@ present in previous versions. We have added three new
table types:
@table @asis
-@item @strong{MyISAM}
+@item @code{MyISAM}
A new ISAM library which is tuned for SQL and supports large files.
-@item @strong{BerkeleyDB} or @strong{BDB}
-Uses the Berkeley DB library from Sleepycat Software to implement
-transaction-safe tables.
-@item @strong{InnoDB}
+@item @code{BerkeleyDB} or @code{BDB}
+Uses the Berkeley DB library from Sleepycat Software to implement
+transaction-safe tables.
+@item @code{InnoDB}
A transaction-safe table handler that supports row level locking, and many
Oracle-like features.
@end table
-Note that only MyISAM is available in the standard binary distribution.
+Note that only @code{MyISAM} is available in the standard binary distribution.
-The 3.23 release also includes support for database replication between
+The 3.23 release also includes support for database replication between
a master and many slaves, full-text indexing, and much more.
All new features are being developed in the 4.0 version. Only
@@ -46862,51 +50544,51 @@ you don't use these features, you should be quite safe with
MySQL 3.23!
Note that the above doesn't mean that replication or Berkeley DB don't
-work; We have done a lot of testing of all code, including replication
+work. We have done a lot of testing of all code, including replication
and BDB without finding any problems. It only means that not as many
users use this code as the rest of the code and because of this we are
not yet 100% confident in this code.
@menu
* News-3.23.52:: Changes in release 3.23.52
-* News-3.23.51:: Changes in release 3.23.51
-* News-3.23.50:: Changes in release 3.23.50
+* News-3.23.51:: Changes in release 3.23.51 (31 May 2002)
+* News-3.23.50:: Changes in release 3.23.50 (21 Apr 2002)
* News-3.23.49:: Changes in release 3.23.49
-* News-3.23.48:: Changes in release 3.23.48
-* News-3.23.47:: Changes in release 3.23.47
-* News-3.23.46:: Changes in release 3.23.46
-* News-3.23.45:: Changes in release 3.23.45
-* News-3.23.44:: Changes in release 3.23.44
+* News-3.23.48:: Changes in release 3.23.48 (07 Feb 2002)
+* News-3.23.47:: Changes in release 3.23.47 (27 Dec 2001)
+* News-3.23.46:: Changes in release 3.23.46 (29 Nov 2001)
+* News-3.23.45:: Changes in release 3.23.45 (22 Nov 2001)
+* News-3.23.44:: Changes in release 3.23.44 (31 Oct 2001)
* News-3.23.43:: Changes in release 3.23.43
-* News-3.23.42:: Changes in release 3.23.42
-* News-3.23.41:: Changes in release 3.23.41
+* News-3.23.42:: Changes in release 3.23.42 (08 Sep 2001)
+* News-3.23.41:: Changes in release 3.23.41 (11 Aug 2001)
* News-3.23.40:: Changes in release 3.23.40
-* News-3.23.39:: Changes in release 3.23.39
-* News-3.23.38:: Changes in release 3.23.38
-* News-3.23.37:: Changes in release 3.23.37
-* News-3.23.36:: Changes in release 3.23.36
-* News-3.23.35:: Changes in release 3.23.35
+* News-3.23.39:: Changes in release 3.23.39 (12 Jun 2001)
+* News-3.23.38:: Changes in release 3.23.38 (09 May 2001)
+* News-3.23.37:: Changes in release 3.23.37 (17 Apr 2001)
+* News-3.23.36:: Changes in release 3.23.36 (27 Mar 2001)
+* News-3.23.35:: Changes in release 3.23.35 (15 Mar 2001)
* News-3.23.34a:: Changes in release 3.23.34a
-* News-3.23.34:: Changes in release 3.23.34
-* News-3.23.33:: Changes in release 3.23.33
-* News-3.23.32:: Changes in release 3.23.32
-* News-3.23.31:: Changes in release 3.23.31
-* News-3.23.30:: Changes in release 3.23.30
-* News-3.23.29:: Changes in release 3.23.29
-* News-3.23.28:: Changes in release 3.23.28
-* News-3.23.27:: Changes in release 3.23.27
+* News-3.23.34:: Changes in release 3.23.34 (10 Mar 2001)
+* News-3.23.33:: Changes in release 3.23.33 (09 Feb 2001)
+* News-3.23.32:: Changes in release 3.23.32 (22 Jan 2001: Stable)
+* News-3.23.31:: Changes in release 3.23.31 (17 Jan 2001)
+* News-3.23.30:: Changes in release 3.23.30 (04 Jan 2001)
+* News-3.23.29:: Changes in release 3.23.29 (16 Dec 2000)
+* News-3.23.28:: Changes in release 3.23.28 (22 Nov 2000: Gamma)
+* News-3.23.27:: Changes in release 3.23.27 (24 Oct 2000)
* News-3.23.26:: Changes in release 3.23.26
* News-3.23.25:: Changes in release 3.23.25
-* News-3.23.24:: Changes in release 3.23.24
+* News-3.23.24:: Changes in release 3.23.24 (08 Sep 2000)
* News-3.23.23:: Changes in release 3.23.23
-* News-3.23.22:: Changes in release 3.23.22
+* News-3.23.22:: Changes in release 3.23.22 (31 Jul 2000)
* News-3.23.21:: Changes in release 3.23.21
* News-3.23.20:: Changes in release 3.23.20
* News-3.23.19:: Changes in release 3.23.19
* News-3.23.18:: Changes in release 3.23.18
* News-3.23.17:: Changes in release 3.23.17
* News-3.23.16:: Changes in release 3.23.16
-* News-3.23.15:: Changes in release 3.23.15
+* News-3.23.15:: Changes in release 3.23.15 (May 2000: Beta)
* News-3.23.14:: Changes in release 3.23.14
* News-3.23.13:: Changes in release 3.23.13
* News-3.23.12:: Changes in release 3.23.12
@@ -46921,7 +50603,7 @@ not yet 100% confident in this code.
* News-3.23.3:: Changes in release 3.23.3
* News-3.23.2:: Changes in release 3.23.2
* News-3.23.1:: Changes in release 3.23.1
-* News-3.23.0:: Changes in release 3.23.0
+* News-3.23.0:: Changes in release 3.23.0 (Sep 1999: Alpha)
@end menu
@node News-3.23.52, News-3.23.51, News-3.23.x, News-3.23.x
@@ -46943,7 +50625,7 @@ active database.
Fixed a bug in range optimiser (causing crashes).
@item
Fixed possible problem in replication when doing @code{DROP DATABASE} on a
-database with InnoDB tables.
+database with @code{InnoDB} tables.
@item
Fixed that @code{mysql_info()} returns 0 for 'Duplicates' when using
@code{INSERT DELAYED IGNORE}.
@@ -46953,70 +50635,69 @@ options in @file{configure.in} to fix a failure under high load.
@end itemize
@node News-3.23.51, News-3.23.50, News-3.23.52, News-3.23.x
-@appendixsubsec Changes in release 3.23.51
+@appendixsubsec Changes in release 3.23.51 (31 May 2002)
+
@itemize @bullet
@item
-Cleaned up @code{NULL} handling for default values in @code{DESCRIBE
-table_name}.
-@item
-Fixed @code{truncate()} to round up negative values to the nearest integer.
-@item
-Remove end space from @code{enum} values. (This fixed a problem with
-@code{SHOW CREATE TABLE}).
+Remove end space from @code{ENUM} values. (This fixed a problem with
+@code{SHOW CREATE TABLE}.)
@item
Fixed bug in @code{CONCAT_WS()} that cut the result.
@item
-Changed name of variables @code{Com_show_master_stat} to
+Changed name of server variables @code{Com_show_master_stat} to
@code{Com_show_master_status} and @code{Com_show_slave_stat} to
@code{Com_show_slave_status}.
@item
Changed handling of @code{gethostbyname()} to make the client library
-threadsafe even if @code{gethostbyname_r} doesn't exists.
+thread-safe even if @code{gethostbyname_r} doesn't exist.
@item
Fixed core-dump problem when giving a wrong password string to @code{GRANT}.
@item
Fixed bug in @code{DROP DATABASE} with symlinked directory.
@item
-Fixed optimization problem with @code{DATETIME} and value outside
+Fixed optimisation problem with @code{DATETIME} and value outside
@code{DATETIME} range.
@item
-Removed BDB documentation.
+Removed Sleepycat's BDB doc files from the source tree, as they're not
+needed (MySQL covers BDB in its own documentation).
@item
-Fixed mit-pthreads to compile with glibc 2.2 (needed for @code{make dist}).
+Fixed MIT-pthreads to compile with @code{glibc} 2.2 (needed for
+@code{make dist}).
@item
Fixed the @code{FLOAT(X+1,X)} is not converted to @code{FLOAT(X+2,X)}.
(This also affected @code{DECIMAL}, @code{DOUBLE} and @code{REAL} types)
@item
-Fixed the result from @code{IF()} is case in-sensitive if the 2 and
+Fixed the result from @code{IF()} is case in-sensitive if the second and
third arguments are case sensitive.
@item
-Fixed core dump problem on OSF in @code{gethostbyname_r}.
+Fixed core dump problem on OSF/1 in @code{gethostbyname_r}.
@item
-Fixed that underflowed decimal fields is not zero filled.
+Fixed that underflowed decimal fields are not zero filled.
@item
If we get an overflow when inserting @code{'+11111'} for
-@code{decimal(5,0) unsigned} columns, we will just drop the sign.
+@code{DECIMAL(5,0) UNSIGNED} columns, we will just drop the sign.
@item
-Fixed optimization bug with @code{ISNULL(expression_which_cannot_be_null)} and
+Fixed optimisation bug with @code{ISNULL(expression_which_cannot_be_null)} and
@code{ISNULL(constant_expression)}.
@item
-Fixed host lookup bug in the glibc library that we used with the 3.23.50
+Fixed host lookup bug in the @code{glibc} library that we used with the 3.23.50
Linux-x86 binaries.
@end itemize
@node News-3.23.50, News-3.23.49, News-3.23.51, News-3.23.x
-@appendixsubsec Changes in release 3.23.50
+@appendixsubsec Changes in release 3.23.50 (21 Apr 2002)
+
@itemize @bullet
@item
-Fixed problem with @code{crash-me} and gcc 3.0.4.
+Fixed problem with @code{crash-me} and @code{gcc} 3.0.4.
@item
Fixed that @code{@@@@unknown_variable} doesn't hang server.
@item
Added @code{@@@@VERSION} as a synonym for @code{VERSION()}.
@item
-@code{SHOW VARIABLES LIKE 'xxx'} is now case insensitive.
+@code{SHOW VARIABLES LIKE 'xxx'} is now case-insensitive.
@item
-Fixed timeout for @code{GET_LOCK()} on HPUX with DCE threads.
+Fixed timeout for @code{GET_LOCK()} on HP-UX with DCE threads.
@item
Fixed memory allocation bug in the glibc library used to build Linux
binaries, which caused mysqld to die in 'free()'.
@@ -47033,6 +50714,9 @@ and @code{CREATE/DROP INDEX}.
@item
@code{InnoDB} tables can now be set to automatically grow in size (autoextend).
@item
+Our Linux RPMS and binaries are now compiled with @code{gcc} 3.0.4, which
+should make them a bit faster.
+@item
Fixed some buffer overflow problems when reading startup parameters.
@item
Because of problems on shutdown we have now disabled named pipes on
@@ -47055,16 +50739,16 @@ Fixed problem with @code{SHOW CREATE TABLE} and @code{PRIMARY KEY} when using
@item
Fixed that one can use @code{SET PASSWORD} for the anonymous user.
@item
-Fixed core-dump bug when reading client groups from option files using
+Fixed core dump bug when reading client groups from option files using
@code{mysql_options()}.
@item
Memory leak (16 bytes per every @strong{corrupted} table) closed.
@item
Fixed binary builds to use @code{--enable-local-infile}.
@item
-Update source to work with new @code{bison} version.
+Update source to work with new version of @code{bison}.
@item
-Updated shell scripts to new agree with new POSIX standard.
+Updated shell scripts to now agree with new POSIX standard.
@item
Fixed bug where @code{DATE_FORMAT()} returned empty string when used
with @code{GROUP BY}.
@@ -47072,70 +50756,77 @@ with @code{GROUP BY}.
@node News-3.23.49, News-3.23.48, News-3.23.50, News-3.23.x
@appendixsubsec Changes in release 3.23.49
+
@itemize @bullet
@item
-Don't give warning for statement that is only a comment; This is needed for
+Don't give warning for a statement that is only a comment; this is needed for
@code{mysqldump --disable-keys} to work.
@item
Fixed unlikely caching bug when doing a join without keys. In this case
-the last used column for a table always returned @code{NULL}.
+the last used field for a table always returned @code{NULL}.
@item
Added options to make @code{LOAD DATA LOCAL INFILE} more secure.
@item
-MySQL binary release 3.23.48 for Linux contained a new glibc library, which
-has serious problems under high load and RedHat 7.2. The 3.23.49 binary
+MySQL binary release 3.23.48 for Linux contained a new @code{glibc} library,
+which has serious problems under high load and RedHat 7.2. The 3.23.49 binary
release doesn't have this problem.
@item
Fixed shutdown problem on NT.
@end itemize
@node News-3.23.48, News-3.23.47, News-3.23.49, News-3.23.x
-@appendixsubsec Changes in release 3.23.48
+@appendixsubsec Changes in release 3.23.48 (07 Feb 2002)
+
@itemize @bullet
@item
+Added @code{--xml} option to @code{mysqldump} for producing XML output.
+@item
Changed to use @code{autoconf} 2.52 (from @code{autoconf} 2.13)
@item
Fixed bug in complicated join with @code{const} tables.
@item
-Added internal safety checks for InnoDB.
+Added internal safety checks for @code{InnoDB}.
@item
-Some InnoDB variables was always shown in @code{SHOW VARIABLES} as
-@code{OFF} on high-byte-first systems (like sparc).
+Some @code{InnoDB} variables were always shown in @code{SHOW VARIABLES} as
+@code{OFF} on high-byte-first systems (like SPARC).
@item
-Fixed problem with one thread using an InnoDB table and another
+Fixed problem with one thread using an @code{InnoDB} table and another
thread doing an @code{ALTER TABLE} on the same table. Before that,
-mysqld could crash with an assertion failure in row0row.c, line 474.
+@code{mysqld} could crash with an assertion failure in @file{row0row.c},
+line 474.
@item
-Tuned the InnoDB SQL optimizer to favor more often index searches
+Tuned the @code{InnoDB} SQL optimiser to favor index searches more often
over table scans.
@item
-Fixed a performance problem with InnoDB tables when several large SELECT
-queries are run concurrently on a multiprocessor Linux computer. Large
-CPU-bound SELECT queries will now also generally run faster on all
-platforms.
+Fixed a performance problem with @code{InnoDB} tables when several large
+@code{SELECT} queries are run concurrently on a multiprocessor Linux
+computer. Large CPU-bound @code{SELECT} queries will now also generally
+run faster on all platforms.
@item
-If MySQL binlogging is used, InnoDB now prints after crash recovery the
-latest MySQL binlog name and the offset InnoDB was able to recover
-to. This is useful, for example, when resynchronizing a master and a
+If MySQL binlogging is used, @code{InnoDB} now prints after crash recovery the
+latest MySQL binlog name and the offset @code{InnoDB} was able to recover
+to. This is useful, for example, when resynchronising a master and a
slave database in replication.
@item
-Added better error messages to help in installation problems of InnoDB tables.
+Added better error messages to help in installation problems of @code{InnoDB}
+tables.
@item
-One can now recover also MySQL temporary tables which have become
-orphaned inside the InnoDB tablespace.
+It is now possible to recover MySQL temporary tables that have become
+orphaned inside the @code{InnoDB} tablespace.
@item
-InnoDB now prevents a @code{FOREIGN KEY} declaration where the signedness
-is not the same in the referencing and referenced integer columns.
+@code{InnoDB} now prevents a @code{FOREIGN KEY} declaration where the
+signedness is not the same in the referencing and referenced integer columns.
@item
Calling @code{SHOW CREATE TABLE} or @code{SHOW TABLE STATUS} could cause
-memory corruption and make mysqld to crash. Especially at risk was
-@code{mysqldump}, because it calls frequently @code{SHOW CREATE TABLE}.
+memory corruption and make @code{mysqld} crash. Especially at risk was
+@code{mysqldump}, because it frequently calls @code{SHOW CREATE TABLE}.
@item
-If inserts to several tables containing an auto-inc column were wrapped
-inside one @code{LOCK TABLES}, InnoDB asserted in lock0lock.c.
+If inserts to several tables containing an @code{AUTO_INCREMENT} column were
+wrapped inside one @code{LOCK TABLES}, @code{InnoDB} asserted in
+@file{lock0lock.c}.
@item
-In 3.23.47 we allowed several @code{NULLS} in a @code{UNIQUE} secondary
-index for an InnoDB table. But @code{CHECK TABLE} was not relaxed: it
+In 3.23.47 we allowed several @code{NULL} values in a @code{UNIQUE} secondary
+index for an @code{InnoDB} table. But @code{CHECK TABLE} was not relaxed: it
reports the table as corrupt. @code{CHECK TABLE} no longer complains in
this situation.
@item
@@ -47143,49 +50834,51 @@ this situation.
@end itemize
@node News-3.23.47, News-3.23.46, News-3.23.48, News-3.23.x
-@appendixsubsec Changes in release 3.23.47
+@appendixsubsec Changes in release 3.23.47 (27 Dec 2001)
+
@itemize @bullet
@item
-Fixed in when using the following construct:
-@code{SELECT ... WHERE key=@@var_name OR $key=@@var_name2}
+Fixed bug when using the following construct:
+@code{SELECT ... WHERE key=@@var_name OR key=@@var_name2}
@item
-Restrict InnoDB keys to 500 bytes.
+Restrict @code{InnoDB} keys to 500 bytes.
@item
-InnoDB now supports @code{NULL} in keys.
+@code{InnoDB} now supports @code{NULL} in keys.
@item
-Fixed shutdown problem on HPUX. (Introduced in 3.23.46)
+Fixed shutdown problem on HP-UX. (Introduced in 3.23.46)
@item
-Fixed core-dump bug in replication when using SELECT RELEASE_LOCK();
+Fixed core dump bug in replication when using @code{SELECT RELEASE_LOCK()}.
@item
Added new command: @code{DO expression,[expression]}
@item
-Added @code{slave-skip-errors} option
+Added @code{slave-skip-errors} option.
@item
Added statistics variables for all MySQL commands. (@code{SHOW STATUS} is
-now much longer).
+now much longer.)
@item
-Fixed default values for InnoDB tables.
+Fixed default values for @code{InnoDB} tables.
@item
Fixed that @code{GROUP BY expr DESC} works.
@item
Fixed bug when using @code{t1 LEFT JOIN t2 ON t2.key=constant}.
@item
-@code{mysql_config} now also work with binary (relocated) distributions.
+@code{mysql_config} now also works with binary (relocated) distributions.
@end itemize
@node News-3.23.46, News-3.23.45, News-3.23.47, News-3.23.x
-@appendixsubsec Changes in release 3.23.46
+@appendixsubsec Changes in release 3.23.46 (29 Nov 2001)
+
@itemize @bullet
@item
-Fixed problem with aliased temporary tables replication
+Fixed problem with aliased temporary table replication.
@item
-InnoDB and BDB tables will now use index when doing an @code{ORDER BY}
-on the whole table.
+@code{InnoDB} and @code{BDB} tables will now use index when doing an
+@code{ORDER BY} on the whole table.
@item
Fixed bug where one got an empty set instead of a DEADLOCK error when using
-BDB tables.
+@code{BDB} tables.
@item
-One can now kill @code{ANALYZE},@code{REPAIR} and @code{OPTIMIZE TABLE} when
+One can now kill @code{ANALYZE}, @code{REPAIR}, and @code{OPTIMIZE TABLE} when
the thread is waiting to get a lock on the table.
@item
Fixed race condition in @code{ANALYZE TABLE}.
@@ -47193,8 +50886,8 @@ Fixed race condition in @code{ANALYZE TABLE}.
Fixed bug when joining with caching (unlikely to happen).
@item
Fixed race condition when using the binary log and @code{INSERT DELAYED}
-which could cause the binary log to have rows that was not yet written
-to MyISAM tables.
+which could cause the binary log to have rows that were not yet written
+to @code{MyISAM} tables.
@item
Changed caching of binary log to make replication slightly faster.
@item
@@ -47202,25 +50895,28 @@ Fixed bug in replication on Mac OS X.
@end itemize
@node News-3.23.45, News-3.23.44, News-3.23.46, News-3.23.x
-@appendixsubsec Changes in release 3.23.45
+@appendixsubsec Changes in release 3.23.45 (22 Nov 2001)
+
@itemize @bullet
@item
-@code{(UPDATE|DELETE) ...WHERE MATCH} bugfix
+@code{(UPDATE|DELETE) ...WHERE MATCH} bugfix.
@item
shutdown should now work on Darwin (Mac OS X).
@item
-Fixed core-dump when repairing corrupted packed MyISAM files.
+Fixed core dump when repairing corrupted packed @code{MyISAM} files.
@item
@code{--core-file} now works on Solaris.
@item
-Fix a bug which could cause InnoDB to complain if it cannot find free blocks
-from the buffer cache during recovery.
+Fix a bug which could cause @code{InnoDB} to complain if it cannot find
+free blocks from the buffer cache during recovery.
@item
-Fixed bug in InnoDB insert buffer B-tree handling that could cause crashes.
+Fixed bug in @code{InnoDB} insert buffer B-tree handling that could cause
+crashes.
@item
-Fixed bug in InnoDB lock timeout handling.
+Fixed bug in @code{InnoDB} lock timeout handling.
@item
-Fixed core dump bug in @code{ALTER TABLE} on a @code{TEMPORARY} InnoDB table.
+Fixed core dump bug in @code{ALTER TABLE} on a @code{TEMPORARY} @code{InnoDB}
+table.
@item
Fixed bug in @code{OPTIMIZE TABLE} that reset index cardinality if it
was up to date.
@@ -47228,23 +50924,24 @@ was up to date.
Fixed problem with @code{t1 LEFT_JOIN t2 ... WHERE t2.date_column IS NULL} when
date_column was declared as @code{NOT NULL}.
@item
-Fixed bug with BDB tables and keys on @code{BLOB}'s.
+Fixed bug with @code{BDB} tables and keys on @code{BLOB} columns.
@item
-Fixed bug in @code{MERGE} tables on OS with 32 bit file pointers.
+Fixed bug in @code{MERGE} tables on OS with 32-bit file pointers.
@item
Fixed bug in @code{TIME_TO_SEC()} when using negative values.
@end itemize
@node News-3.23.44, News-3.23.43, News-3.23.45, News-3.23.x
-@appendixsubsec Changes in release 3.23.44
+@appendixsubsec Changes in release 3.23.44 (31 Oct 2001)
+
@itemize @bullet
@item
Fixed @code{Rows_examined} count in slow query log.
@item
-Fixed bug when using a reference to a @code{AVG()} column in @code{HAVING}.
+Fixed bug when using a reference to an @code{AVG()} column in @code{HAVING}.
@item
Fixed that date functions that require correct dates, like
-@code{DAYOFYEAR(column)} will return @code{NULL} for @code{0000-00-00} dates.
+@code{DAYOFYEAR(column)}, will return @code{NULL} for @code{0000-00-00} dates.
@item
Fixed bug in const-propagation when comparing columns of different
types. (@code{SELECT * FROM date_col="2001-01-01" and date_col=time_col})
@@ -47252,25 +50949,26 @@ types. (@code{SELECT * FROM date_col="2001-01-01" and date_col=time_col})
Fixed bug that caused error message @code{Can't write, because of unique
constraint} with some @code{GROUP BY} queries.
@item
-Fixed problem with sjis character strings used within quoted table names.
+Fixed problem with @code{sjis} character strings used within quoted table
+names.
@item
-Fixed coredump when using @code{CREATE ... FULLTEXT} keys with other table
-handlers than MyISAM.
+Fixed core dump when using @code{CREATE ... FULLTEXT} keys with other table
+handlers than @code{MyISAM}.
@item
-Don't use @code{signal()} on windows because this appears to not be
-100 % reliable.
+Don't use @code{signal()} on Windows because this appears to not be
+100% reliable.
@item
-Fixed bug when doing @code{WHERE column_name=NULL} on an indexed column
+Fixed bug when doing @code{WHERE col_name=NULL} on an indexed column
that had @code{NULL} values.
@item
-Fixed bug when doing @code{LEFT JOIN ... ON (column_name = constant) WHERE column_name = constant}.
+Fixed bug when doing @code{LEFT JOIN ... ON (col_name = constant) WHERE col_name = constant}.
@item
When using replications, aborted queries that contained @code{%} could cause
a core dump.
@item
-@code{TCP_NODELAY} was not used on some systems. (Speed problem).
+@code{TCP_NODELAY} was not used on some systems. (Speed problem.)
@item
-Applied portability fixes for OS/2 (Patch by Yuri Dario).
+Applied portability fixes for OS/2. (Patch by Yuri Dario.)
@end itemize
The following changes are for @code{InnoDB} tables:
@@ -47283,27 +50981,27 @@ Foreign keys checking is now done for @code{InnoDB} tables.
@item
@code{DROP DATABASE} now works also for @code{InnoDB} tables.
@item
-@code{InnoDB} now supports data files and raw disk partitions bigger
-than 4 GB on those operating systems which have big files.
+@code{InnoDB} now supports datafiles and raw disk partitions bigger
+than 4 GB on those operating systems that have big files.
@item
@code{InnoDB} calculates better table cardinality estimates for the
-MySQL optimizer.
+MySQL optimiser.
@item
-Accent characters in the default character set latin1 are ordered
+Accent characters in the default character set @code{latin1} are ordered
according to the MySQL ordering.
-NOTE: if you are using latin1 and have inserted characters whose code is >
-127 to an indexed CHAR column, you should run CHECK TABLE on your table when
-you upgrade to 3.23.44, and drop and reimport the table if CHECK TABLE
-reports an error!
+Note: if you are using @code{latin1} and have inserted characters whose
+code is greater than 127 into an indexed @code{CHAR} column, you should
+run @code{CHECK TABLE} on your table when you upgrade to 3.23.44, and
+drop and reimport the table if @code{CHECK TABLE} reports an error!
@item
-A new @file{my.cnf} parameter @code{innodb_thread_concurrency} helps in
+A new @file{my.cnf} parameter, @code{innodb_thread_concurrency}, helps in
performance tuning in heavily concurrent environments.
@item
-A new @code{my.cnf} parameter @code{innodb_fast_shutdown} speeds up
+A new @file{my.cnf} parameter, @code{innodb_fast_shutdown}, speeds up
server shutdown.
@item
-A new @code{my.cnf} parameter @code{innodb_force_recovery} helps to save
+A new @file{my.cnf} parameter, @code{innodb_force_recovery}, helps to save
your data in case the disk image of the database becomes corrupt.
@item
@code{innodb_monitor} has been improved and a new
@@ -47311,66 +51009,70 @@ your data in case the disk image of the database becomes corrupt.
@item
Increased maximum key length from 500 to 7000 bytes.
@item
-Fixed a bug in replication of auto-inc columns with multiline inserts.
+Fixed a bug in replication of @code{AUTO_INCREMENT} columns with
+multiple-line inserts.
@item
Fixed a bug when the case of letters changes in an update of an indexed
secondary column.
@item
-Fixed a hang when there are > 24 data files.
+Fixed a hang when there are > 24 datafiles.
@item
Fixed a crash when @code{MAX(col)} is selected from an empty table, and
-col is a not the first column in a multi-column index.
+@code{col} is not the first column in a multi-column index.
@item
Fixed a bug in purge which could cause crashes.
@end itemize
@node News-3.23.43, News-3.23.42, News-3.23.44, News-3.23.x
@appendixsubsec Changes in release 3.23.43
+
@itemize @bullet
@item
Fixed a bug in @code{INSERT DELAYED} and @code{FLUSH TABLES} introduced
in 3.23.42.
@item
-Fixed unlikely bug, which returned not matching rows, in SELECT with
+Fixed unlikely bug, which returned non-matching rows, in @code{SELECT} with
many tables and multi-column indexes and 'range' type.
@item
-Fixed a unlikely core-dump bug when doing @code{EXPLAIN SELECT} when using
+Fixed an unlikely core dump bug when doing @code{EXPLAIN SELECT} when using
many tables and @code{ORDER BY}.
@item
Fixed bug in @code{LOAD DATA FROM MASTER} when using table with
@code{CHECKSUM=1}.
@item
Added unique error message when one gets a DEADLOCK during a transaction with
-BDB tables.
+@code{BDB} tables.
@item
Fixed problem with @code{BDB} tables and @code{UNIQUE} columns defined
as @code{NULL}.
@item
-Fixed problem with @code{myisampack} when using pre-space filled CHAR columns.
+Fixed problem with @code{myisampack} when using pre-space filled @code{CHAR}
+columns.
@item
-Applied patch from Yuri Dario for OS2.
+Applied patch from Yuri Dario for OS/2.
@item
-Fixed bug in @code{--safe-user-create}
+Fixed bug in @code{--safe-user-create}.
@end itemize
@node News-3.23.42, News-3.23.41, News-3.23.43, News-3.23.x
-@appendixsubsec Changes in release 3.23.42
+@appendixsubsec Changes in release 3.23.42 (08 Sep 2001)
+
@itemize @bullet
@item
Fixed problem when using @code{LOCK TABLES} and @code{BDB} tables.
@item
-Fixed problem with @code{REPAIR TABLE} on MyISAM tables with row lengths
-between 65517 - 65520 bytes
+Fixed problem with @code{REPAIR TABLE} on @code{MyISAM} tables with row
+lengths in the range from 65517 to 65520 bytes.
@item
Fixed rare hang when doing @code{mysqladmin shutdown} when there was
a lot of activity in other threads.
@item
Fixed problem with @code{INSERT DELAYED} where delay thread could be
-hanging on @code{upgrading locks} without any apparent reasons.
+hanging on @code{upgrading locks} with no apparent reason.
@item
Fixed problem with @code{myisampack} and @code{BLOB}.
@item
-Fixes problem when one edited @code{.MRG} tables by hand.
+Fixed problem when one edited @file{.MRG} tables by hand.
(Patch from Benjamin Pflugmann).
@item
Enforce that all tables in a @code{MERGE} table come from the same
@@ -47380,22 +51082,21 @@ Fixed bug with @code{LOAD DATA INFILE} and transactional tables.
@item
Fix bug when using @code{INSERT DELAYED} with wrong column definition.
@item
-Fixed coredump during @code{REPAIR} of some particularly broken tables.
+Fixed core dump during @code{REPAIR} of some particularly broken tables.
@item
Fixed bug in @code{InnoDB} and @code{AUTO_INCREMENT} columns.
@item
Fixed bug in @code{InnoDB} and @code{RENAME TABLE} columns.
@item
-Fixed critical bug in @code{InnoDB} and @code{BLOB} columns. If one has
+Fixed critical bug in @code{InnoDB} and @code{BLOB} columns. If you have
used @code{BLOB} columns larger than 8000 bytes in an @code{InnoDB}
-table, one must dump the table with @code{mysqldump}, drop it and
+table, it is necessary to dump the table with @code{mysqldump}, drop it and
restore it from the dump.
@item
Applied large patch for OS/2 from Yuri Dario.
@item
Fixed problem with @code{InnoDB} when one could get the error @code{Can't
-execute the given command...} even when one didn't have an active
-transaction.
+execute the given command...} even when no transaction was active.
@item
Applied some minor fixes that concern Gemini.
@item
@@ -47403,33 +51104,33 @@ Use real arithmetic operations even in integer context if not
all arguments are integers. (Fixes uncommon bug in some integer
contexts).
@item
-Don't force everything to lower cases on Windows. (To fix problem
+Don't force everything to lowercase on Windows. (To fix problem
with Windows and @code{ALTER TABLE}). Now @code{--lower_case_names}
also works on Unix.
@item
-Fixed that automatic rollback that is done when thread end doesn't lock
+Fixed that automatic rollback is done when thread end doesn't lock
other threads.
@end itemize
@node News-3.23.41, News-3.23.40, News-3.23.42, News-3.23.x
-@appendixsubsec Changes in release 3.23.41
+@appendixsubsec Changes in release 3.23.41 (11 Aug 2001)
@itemize @bullet
@item
-Added option @code{--sql-mode=option[,option[,option]]}.
+Added @code{--sql-mode=option[,option[,option]]} option to @code{mysqld}.
@xref{Command-line options}.
@item
Fixed possible problem with @code{shutdown} on Solaris where the
@file{.pid} file wasn't deleted.
@item
-InnoDB now supports < 4 GB rows. The former limit was 8000 bytes.
+@code{InnoDB} now supports < 4 GB rows. The former limit was 8000 bytes.
@item
The @code{doublewrite} file flush method is used in @code{InnoDB}.
-It reduces the need for Unix fsync calls to a fraction and
+It reduces the need for Unix @code{fsync()} calls to a fraction and
improves performance on most Unix flavors.
@item
You can now use the @code{InnoDB} Monitor to print a lot of @code{InnoDB} state
-information, including locks, to the standard output; useful in
+information, including locks, to the standard output. This is useful in
performance tuning.
@item
Several bugs which could cause hangs in @code{InnoDB} have been fixed.
@@ -47439,18 +51140,18 @@ Split @code{record_buffer} to @code{record_buffer} and
versions, if @code{record_rnd_buffer} is not set, then it takes the
value of @code{record_buffer}.
@item
-Fixed optimizing bug in @code{ORDER BY} where some @code{ORDER BY} parts
+Fixed optimising bug in @code{ORDER BY} where some @code{ORDER BY} parts
where wrongly removed.
@item
Fixed overflow bug with @code{ALTER TABLE} and @code{MERGE} tables.
@item
Added prototypes for @code{my_thread_init()} and @code{my_thread_end()} to
-@file{mysql_com.h}
+@file{mysql_com.h}
@item
-Added option @code{--safe-user-create} to @code{mysqld}.
+Added @code{--safe-user-create} option to @code{mysqld}.
@item
-Fixed bug in @code{SELECT DISTINCT ... HAVING} that casued error message
-@code{Can't find record in '#...}
+Fixed bug in @code{SELECT DISTINCT ... HAVING} that caused error message
+@code{Can't find record in #...}
@end itemize
@@ -47459,23 +51160,24 @@ Fixed bug in @code{SELECT DISTINCT ... HAVING} that casued error message
@itemize @bullet
@item
-Fixed problem with @code{--low-priority-updates} and @code{INSERT}'s.
+Fixed problem with @code{--low-priority-updates} and @code{INSERT} statements.
@item
Fixed bug in slave thread when under some rare circumstances it could
get 22 bytes ahead on the offset in the master.
@item
-Added @code{slave_wait_timeout} for replication.
+Added @code{slave_net_timeout} for replication.
@item
Fixed problem with @code{UPDATE} and @code{BDB} tables.
@item
Fixed hard bug in @code{BDB} tables when using key parts.
@item
-Fixed problem when using the @code{GRANT FILE ON database.* ...}; Previously
+Fixed problem when using @code{GRANT FILE ON database.* ...}; previously
we added the @code{DROP} privilege for the database.
@item
-Fixed @code{DELETE FROM table_name ... LIMIT 0} and
-@code{UPDATE FROM table_name ... LIMIT 0} acted as though the @code{LIMIT}
-clause was not present (they deleted or updated all selected rows).
+Fixed @code{DELETE FROM tbl_name ... LIMIT 0} and
+@code{UPDATE FROM tbl_name ... LIMIT 0}, which acted as though the
+@code{LIMIT} clause was not present (they deleted or updated all selected
+rows).
@item
@code{CHECK TABLE} now checks if an @code{AUTO_INCREMENT} column contains
the value 0.
@@ -47488,30 +51190,30 @@ Fixed parser to allow floats of type @code{1.0e1} (no sign after @code{e}).
Option @code{--force} to @code{myisamchk} now also updates states.
@item
Added option @code{--warnings} to @code{mysqld}. Now @code{mysqld}
-only prints the error @code{Aborted connection} if this option is used.
+prints the error @code{Aborted connection} only if this option is used.
@item
Fixed problem with @code{SHOW CREATE TABLE} when you didn't have a
@code{PRIMARY KEY}.
@item
-Properly fixed the rename of @code{innodb_unix_file_flush_method} to
+Properly fixed the rename of @code{innodb_unix_file_flush_method} variable to
@code{innodb_flush_method}.
@item
-Fixed bug when converting @code{UNSIGNED BIGINT} to @code{DOUBLE}. This caused
+Fixed bug when converting @code{BIGINT UNSIGNED} to @code{DOUBLE}. This caused
a problem when doing comparisons with @code{BIGINT} values outside of the
signed range.
@item
Fixed bug in @code{BDB} tables when querying empty tables.
@item
Fixed a bug when using @code{COUNT(DISTINCT)} with @code{LEFT JOIN} and
-there wasn't any matching rows.
+there weren't any matching rows.
@item
Removed all documentation referring to the @code{GEMINI} table
-type. @code{GEMINI} is not released under an Open Source license.
+type. @code{GEMINI} is not released under an @code{Open Source} license.
@end itemize
@node News-3.23.39, News-3.23.38, News-3.23.40, News-3.23.x
-@appendixsubsec Changes in release 3.23.39
+@appendixsubsec Changes in release 3.23.39 (12 Jun 2001)
@itemize @bullet
@item
@@ -47520,15 +51222,15 @@ and adding an @code{AUTO_INCREMENT} column.
@item
@code{CREATE ... SELECT} now creates non-unique indexes delayed.
@item
-Fixed problem where @code{LOCK TABLES table_name READ} followed by
+Fixed problem where @code{LOCK TABLES tbl_name READ} followed by
@code{FLUSH TABLES} put an exclusive lock on the table.
@item
-@code{REAL} @@variables with was represented with 2 digits when
+@code{REAL @@variable} values were represented with only 2 digits when
converted to strings.
@item
-Fixed problem that client 'hung' when @code{LOAD TABLE FROM MASTER} failed.
+Fixed problem that client ``hung'' when @code{LOAD TABLE FROM MASTER} failed.
@item
-Running @code{myisamchk --fast --force} will no longer repair tables
+@code{myisamchk --fast --force} will no longer repair tables
that only had the open count wrong.
@item
Added functions to handle symbolic links to make life easier in 4.0.
@@ -47546,7 +51248,7 @@ Extended argument length in option files from 256 to 512 chars.
Fixed problem with shutdown when @code{INSERT DELAYED} was waiting for
a @code{LOCK TABLE}.
@item
-Fixed coredump bug in @code{InnoDB} when tablespace was full.
+Fixed core dump bug in @code{InnoDB} when tablespace was full.
@item
Fixed problem with @code{MERGE} tables and big tables (> 4G) when using
@code{ORDER BY}.
@@ -47554,18 +51256,18 @@ Fixed problem with @code{MERGE} tables and big tables (> 4G) when using
@node News-3.23.38, News-3.23.37, News-3.23.39, News-3.23.x
-@appendixsubsec Changes in release 3.23.38
+@appendixsubsec Changes in release 3.23.38 (09 May 2001)
@itemize @bullet
@item
Fixed a bug when @code{SELECT} from @code{MERGE} table
sometimes results in incorrectly ordered rows.
@item
-Fixed a bug in @code{REPLACE()} when using the ujis character set.
+Fixed a bug in @code{REPLACE()} when using the @code{ujis} character set.
@item
-Applied Sleepycat BDB patches 3.2.9.1 and 3.2.9.2.
+Applied Sleepycat @code{BDB} patches 3.2.9.1 and 3.2.9.2.
@item
-Added option @code{--skip-stack-trace} to @code{mysqld}.
+Added @code{--skip-stack-trace} option to @code{mysqld}.
@item
@code{CREATE TEMPORARY} now works with @code{InnoDB} tables.
@item
@@ -47583,8 +51285,8 @@ Fixed bug when too many rows where removed when using
@item
Added @code{Rows_examined} to slow query log.
@item
-Fixed problems with function returning empty string when using
-together with a group functions and a @code{WHERE} that didn't match any rows.
+Fixed problems with function returning empty string when used together with
+a group function and a @code{WHERE} that didn't match any rows.
@item
New program @code{mysqlcheck}.
@item
@@ -47593,39 +51295,39 @@ Added database name to output for administrative commands like @code{CHECK},
@item
Lots of portability fixes for @code{InnoDB}.
@item
-Changed optimizer so that queries like
-@code{SELECT * FROM table_name,table_name2 ... ORDER BY key_part1 LIMIT #}
+Changed optimiser so that queries like
+@code{SELECT * FROM tbl_name,tbl_name2 ... ORDER BY key_part1 LIMIT #}
will use index on @code{key_part1} instead of @code{filesort}.
@item
Fixed bug when doing
@code{LOCK TABLE to_table WRITE,...; INSERT INTO to_table... SELECT ...}
when @code{to_table} was empty.
@item
-Fixed bug with @code{LOCK TABLE} and BDB tables.
+Fixed bug with @code{LOCK TABLE} and @code{BDB} tables.
@end itemize
@node News-3.23.37, News-3.23.36, News-3.23.38, News-3.23.x
-@appendixsubsec Changes in release 3.23.37
+@appendixsubsec Changes in release 3.23.37 (17 Apr 2001)
@itemize @bullet
@item
-Fixed a bug when using @code{MATCH} in @code{HAVING} clause.
+Fixed a bug when using @code{MATCH()} in @code{HAVING} clause.
@item
Fixed a bug when using @code{HEAP} tables with @code{LIKE}.
@item
-Added @code{--mysql-version} to @code{safe_mysqld}
+Added @code{--mysql-version} option to @code{safe_mysqld}
@item
Changed @code{INNOBASE} to @code{InnoDB} (because the @code{INNOBASE}
name was already used). All @code{configure} options and @code{mysqld}
-start options are now using @code{innodb} instead of @code{innobase}. This
-means that you have to change any configuration files where you have used
-@code{innobase} options before upgrading to this version!
+start options now use @code{innodb} instead of @code{innobase}. This
+means that before upgrading to this version, you have to change any
+configuration files where you have used @code{innobase} options!
@item
Fixed bug when using indexes on @code{CHAR(255) NULL} columns.
@item
Slave thread will now be started even if @code{master-host} is not set, as
-long as @code{server-id} is set and valid @code{master.info} is present
+long as @code{server-id} is set and valid @file{master.info} is present.
@item
Partial updates (terminated with kill) are now logged with a special error
code to the binary log. Slave will refuse to execute them if the error code
@@ -47634,9 +51336,9 @@ with @code{SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START} after a manual sanity
check/correction of data integrity.
@item
Fixed bug that erroneously logged a drop of internal temporary table
-on thread termination to the binary log - bug affected replication.
+on thread termination to the binary log -- this bug affected replication.
@item
-Fixed a bug in @code{REGEXP()} on 64-bit machines.
+Fixed a bug in @code{REGEXP} on 64-bit machines.
@item
@code{UPDATE} and @code{DELETE} with @code{WHERE unique_key_part IS NULL}
didn't update/delete all rows.
@@ -47646,7 +51348,7 @@ Disabled @code{INSERT DELAYED} for tables that support transactions.
Fixed bug when using date functions on @code{TEXT}/@code{BLOB} column
with wrong date format.
@item
-UDFs now also work on Windows. (Patch by Ralph Mason)
+UDFs now also work on Windows. (Patch by Ralph Mason.)
@item
Fixed bug in @code{ALTER TABLE} and @code{LOAD DATA INFILE} that disabled
key-sorting. These commands should now be faster in most cases.
@@ -47655,16 +51357,16 @@ Fixed performance bug where reopened tables (tables that had been
waiting for @code{FLUSH} or @code{REPAIR}) would not use indexes for the
next query.
@item
-Fixed problem with @code{ALTER TABLE} to Innobase tables on FreeBSD.
+Fixed problem with @code{ALTER TABLE} to @code{InnoDB} tables on FreeBSD.
@item
Added @code{mysqld} variables @code{myisam_max_sort_file_size} and
@code{myisam_max_extra_sort_file_size}.
@item
-Initialize signals early to avoid problem with signals in Innobase.
+Initialise signals early to avoid problem with signals in @code{InnoDB}.
@item
Applied patch for the @code{tis620} character set to make comparisons
case-independent and to fix a bug in @code{LIKE} for this character set.
-@strong{NOTE}: All tables that uses the @code{tis620} character set must be
+@strong{Note}: All tables that uses the @code{tis620} character set must be
fixed with @code{myisamchk -r} or @code{REPAIR TABLE} !
@item
Added @code{--skip-safemalloc} option to @code{mysqld}.
@@ -47672,21 +51374,21 @@ Added @code{--skip-safemalloc} option to @code{mysqld}.
@node News-3.23.36, News-3.23.35, News-3.23.37, News-3.23.x
-@appendixsubsec Changes in release 3.23.36
+@appendixsubsec Changes in release 3.23.36 (27 Mar 2001)
@itemize @bullet
@item
-Fixed a bug that allowed you to use database names containing a @samp{.}
+Fixed a bug that allowed use of database names containing a @samp{.}
character. This fixes a serious security issue when @code{mysqld} is run
as root.
@item
-Fixed bug when thread creation failed (could happen when doing a LOT
+Fixed bug when thread creation failed (could happen when doing a @strong{lot}
of connections in a short time).
@item
Fixed some problems with @code{FLUSH TABLES} and @code{TEMPORARY} tables.
-(Problem with freeing the key cache and error @code{Can't reopen table...}).
+(Problem with freeing the key cache and error @code{Can't reopen table...}.)
@item
-Fixed a problem in Innobase with other character sets than @code{latin1}
+Fixed a problem in @code{InnoDB} with other character sets than @code{latin1}
and another problem when using many columns.
@item
Fixed bug that caused a core dump when using a very complex query involving
@@ -47696,24 +51398,24 @@ Added @code{SET TRANSACTION ISOLATION LEVEL ...}
@item
Added @code{SELECT ... FOR UPDATE}.
@item
-Fixed bug where the number of affected rows was not returned when @code{MySQL}
+Fixed bug where the number of affected rows was not returned when MySQL
was compiled without transaction support.
@item
Fixed a bug in @code{UPDATE} where keys weren't always used to find the
rows to be updated.
@item
-Fixed a bug in @code{CONCAT_WS()} where it returned wrong results.
+Fixed a bug in @code{CONCAT_WS()} where it returned incorrect results.
@item
Changed @code{CREATE ... INSERT} and @code{INSERT ... SELECT} to not
allow concurrent inserts as this could make the binary log hard to repeat.
-(Concurrent inserts are enabled if you are not using the binary or update log).
+(Concurrent inserts are enabled if you are not using the binary or update log.)
@item
-Changed some macros to be able to use fast mutex with glibc 2.2.
+Changed some macros to be able to use fast mutex with @code{glibc} 2.2.
@end itemize
@node News-3.23.35, News-3.23.34a, News-3.23.36, News-3.23.x
-@appendixsubsec Changes in release 3.23.35
+@appendixsubsec Changes in release 3.23.35 (15 Mar 2001)
@itemize @bullet
@item
@@ -47727,7 +51429,7 @@ Setting and using user variables in @code{SELECT DISTINCT} didn't work.
@item
Tuned @code{SHOW ANALYZE} for small tables.
@item
-Fixed handling of arguments in the benchmark script @file{run-all-tests}.
+Fixed handling of arguments in the benchmark script @code{run-all-tests}.
@end itemize
@@ -47736,13 +51438,13 @@ Fixed handling of arguments in the benchmark script @file{run-all-tests}.
@itemize @bullet
@item
-Added extra files to the distribution to allow @code{INNOBASE} support
+Added extra files to the distribution to allow @code{INNOBASE} support
to be compiled.
@end itemize
@node News-3.23.34, News-3.23.33, News-3.23.34a, News-3.23.x
-@appendixsubsec Changes in release 3.23.34
+@appendixsubsec Changes in release 3.23.34 (10 Mar 2001)
@itemize @bullet
@item
@@ -47751,14 +51453,14 @@ to the MySQL source distribution.
@item
Updated the documentation about @code{GEMINI} tables.
@item
-Fixed a bug in @code{INSERT DELAYED} that caused threads to hang when
+Fixed a bug in @code{INSERT DELAYED} that caused threads to hang when
inserting @code{NULL} into an @code{AUTO_INCREMENT} column.
@item
Fixed a bug in @code{CHECK TABLE} / @code{REPAIR TABLE} that could cause
a thread to hang.
@item
@code{REPLACE} will not replace a row that conflicts with an
-@code{auto_increment} generated key.
+@code{AUTO_INCREMENT} generated key.
@item
@code{mysqld} now only sets @code{CLIENT_TRANSACTIONS} in
@code{mysql->server_capabilities} if the server supports a
@@ -47771,17 +51473,18 @@ Improved error diagnostic for slave thread exit.
@item
Fixed bug in @code{ALTER TABLE ... ORDER BY}.
@item
-Added option @code{max_user_connections} to @code{mysqld}.
+Added @code{max_user_connections} variable to @code{mysqld}.
@item
Limit query length for replication by @code{max_allowed_packet}, not the
arbitrary limit of 4 MB.
@item
Allow space around @code{=} in argument to @code{--set-variable}.
@item
-Fixed problem in automatic repair that could leave some threads in state
+Fixed problem in automatic repair that could leave some threads in state
@code{Waiting for table}.
@item
-@code{SHOW CREATE TABLE} now dumps the @code{UNION()} for @code{MERGE} tables.
+@code{SHOW CREATE TABLE} now displays the @code{UNION()} for @code{MERGE}
+tables.
@item
@code{ALTER TABLE} now remembers the old @code{UNION()} definition.
@item
@@ -47792,9 +51495,9 @@ Fixed bug in bidirectional replication.
Fixed bug in the @code{BDB} table handler that occurred when using an index
on multi-part key where a key part may be @code{NULL}.
@item
-Fixed @code{MAX()} optimization on sub-key for @code{BDB} tables.
+Fixed @code{MAX()} optimisation on sub-key for @code{BDB} tables.
@item
-Fixed problem where garbage results were returned when using @code{BDB}
+Fixed problem where garbage results were returned when using @code{BDB}
tables and @code{BLOB} or @code{TEXT} fields when joining many tables.
@item
Fixed a problem with @code{BDB} tables and @code{TEXT} columns.
@@ -47805,27 +51508,27 @@ Fixed that @code{mysqlbinlog} writes the timestamp value for each query.
This ensures that one gets same values for date functions like @code{NOW()}
when using @code{mysqlbinlog} to pipe the queries to another server.
@item
-Allow one to use @code{--skip-gemini}, @code{--skip-bdb} and
-@code{--skip-innobase} to @code{mysqld} even if these databases are not
-compiled in @code{mysqld}.
+Allow @code{--skip-gemini}, @code{--skip-bdb}, and @code{--skip-innodb}
+options to be specified when invoking @code{mysqld}, even if these table
+handlers are not compiled in to @code{mysqld}.
@item
One can now do @code{GROUP BY ... DESC}.
@item
-Fixed a deadlock in the @code{SET} code, when one ran @code{SET @@foo=bar},
+Fixed a deadlock in the @code{SET} code, when one ran @code{SET @@foo=bar},
where @code{bar} is a column reference, an error was not properly generated.
@end itemize
@node News-3.23.33, News-3.23.32, News-3.23.34, News-3.23.x
-@appendixsubsec Changes in release 3.23.33
+@appendixsubsec Changes in release 3.23.33 (09 Feb 2001)
@itemize @bullet
@item
-Fixed that DNS lookups are not using the same mutex as the hostname
+Fixed DNS lookups not to use the same mutex as the hostname
cache. This will enable known hosts to be quickly resolved even if a
DNS lookup takes a long time.
@item
-Added @code{--character-sets-dir} to @code{myisampack}.
+Added @code{--character-sets-dir} option to @code{myisampack}.
@item
Removed warnings when running @code{REPAIR TABLE ... EXTENDED}.
@item
@@ -47837,23 +51540,24 @@ Added @code{SEQUENCE()} as an example UDF function.
Changed @code{mysql_install_db} to use @code{BINARY} for @code{CHAR}
columns in the privilege tables.
@item
-Changed @code{TRUNCATE table_name} to @code{TRUNCATE TABLE table_name}
+Changed @code{TRUNCATE tbl_name} to @code{TRUNCATE TABLE tbl_name}
to use the same syntax as Oracle. Until 4.0 we will also allow
-@code{TRUNCATE table_name} to not crash old code.
+@code{TRUNCATE tbl_name} to not crash old code.
@item
-Fixed 'no found rows' bug in @code{MyISAM} tables when a @code{BLOB} was
+Fixed ``no found rows'' bug in @code{MyISAM} tables when a @code{BLOB} was
first part of a multi-part key.
@item
Fixed bug where @code{CASE} didn't work with @code{GROUP BY}.
@item
-Added option @code{--sort-recover} to @code{myisamchk}.
+Added @code{--sort-recover} option to @code{myisamchk}.
@item
@code{myisamchk -S} and @code{OPTIMIZE TABLE} now work on Windows.
@item
Fixed bug when using @code{DISTINCT} on results from functions that referred
to a group function, like:
@example
-SELECT a, DISTINCT SEC_TO_TIME(sum(a)) from table_name GROUP BY a, b;
+SELECT a, DISTINCT SEC_TO_TIME(SUM(a))
+FROM tbl_name GROUP BY a, b;
@end example
@item
Fixed buffer overrun in @code{libmysqlclient} library.
@@ -47866,7 +51570,7 @@ Added @code{Table_locks_immediate} and @code{Table_locks_waited} status
variables.
@item
Fixed bug in replication that broke slave server start with existing
-@code{master.info}. This fixes a bug introduced in 3.23.32.
+@file{master.info}. This fixes a bug introduced in 3.23.32.
@item
Added @code{SET SQL_SLAVE_SKIP_COUNTER=n} command to recover from
replication glitches without a full database copy.
@@ -47874,16 +51578,16 @@ replication glitches without a full database copy.
Added @code{max_binlog_size} variable; the binary log will be rotated
automatically when the size crosses the limit.
@item
-Added @code{Last_error}, @code{Last_errno}, and @code{Slave_skip_counter} to
-@code{SHOW SLAVE STATUS}.
+Added @code{Last_error}, @code{Last_errno}, and @code{Slave_skip_counter}
+variables to @code{SHOW SLAVE STATUS}.
@item
Fixed bug in @code{MASTER_POS_WAIT()} function.
@item
-Execute coredump handler on @code{SIGILL}, and @code{SIGBUS} in addition to
+Execute core dump handler on @code{SIGILL}, and @code{SIGBUS} in addition to
@code{SIGSEGV}.
@item
On x86 Linux, print the current query and thread (connection) id, if
-available, in the coredump handler.
+available, in the core dump handler.
@item
Fixed several timing bugs in the test suite.
@item
@@ -47895,31 +51599,31 @@ suite.
@item
Fixed creation of @code{MERGE} tables on Windows.
@item
-Portability fixes for OpenBSD and OS2.
+Portability fixes for OpenBSD and OS/2.
@item
Added @code{--temp-pool} option to @code{mysqld}. Using this option
will cause most temporary files created to use a small set of names,
rather than a unique name for each new file. This is to work around a
problem in the Linux kernel dealing with creating a bunch of new files
-with different names. With the old behavior, Linux seems to "leak"
+with different names. With the old behaviour, Linux seems to "leak"
memory, as it's being allocated to the directory entry cache instead of
the disk cache.
@end itemize
@node News-3.23.32, News-3.23.31, News-3.23.33, News-3.23.x
-@appendixsubsec Changes in release 3.23.32
+@appendixsubsec Changes in release 3.23.32 (22 Jan 2001: Stable)
@itemize @bullet
@item
-Changed code to get around compiler bug in Compaq C++ on OSF1, that broke
+Changed code to get around compiler bug in Compaq C++ on OSF/1, that broke
@code{BACKUP}, @code{RESTORE}, @code{CHECK}, @code{REPAIR}, and
@code{ANALYZE TABLE}.
@item
Added option @code{FULL} to @code{SHOW COLUMNS}. Now we show the
privilege list for the columns only if this option is given.
@item
-Fixed bug in @code{SHOW LOGS} when there weren't any BDB logs.
+Fixed bug in @code{SHOW LOGS} when there weren't any @code{BDB} logs.
@item
Fixed a timing problem in replication that could delay sending an update
to the client until a new update was done.
@@ -47935,14 +51639,14 @@ Added missing @file{my_config.h} to RPM distribution.
@item
@code{TRIM("foo" from "foo")} didn't return an empty string.
@item
-Added @code{--with-version-suffix} to @code{configure}.
+Added @code{--with-version-suffix} option to @code{configure}.
@item
-Fixed coredump when client aborted connection without @code{mysql_close()}.
+Fixed core dump when client aborted connection without @code{mysql_close()}.
@item
Fixed a bug in @code{RESTORE TABLE} when trying to restore from a non-existent
directory.
@item
-Fixed a bug which caused a core dump on the slave when replicating
+Fixed a bug which caused a core dump on the slave when replicating
@code{SET PASSWORD}.
@item
Added @code{MASTER_POS_WAIT()}.
@@ -47950,17 +51654,17 @@ Added @code{MASTER_POS_WAIT()}.
@node News-3.23.31, News-3.23.30, News-3.23.32, News-3.23.x
-@appendixsubsec Changes in release 3.23.31
+@appendixsubsec Changes in release 3.23.31 (17 Jan 2001)
@itemize @bullet
@item
-The test suite now tests all reachable BDB interface code. During
+The test suite now tests all reachable @code{BDB} interface code. During
testing we found and fixed many errors in the interface code.
@item
Using @code{HAVING} on an empty table could produce one result row when
it shouldn't.
@item
-Fixed that the MySQL RPM is not dependent on Perl5 anymore.
+Fixed the MySQL RPM not to depend on Perl5 anymore.
@item
Fixed some problems with @code{HEAP} tables on Windows.
@item
@@ -47976,7 +51680,7 @@ Fixed problem when using @code{DECIMAL()} keys on negative numbers.
@code{HOUR()} (and some other @code{TIME} functions) on a @code{CHAR} column
always returned @code{NULL}.
@item
-Fixed security bug in something (please upgrade if you are using a earlier
+Fixed security bug in something (please upgrade if you are using an earlier
MySQL 3.23 version).
@item
Fixed buffer overflow bug when writing a certain error message.
@@ -47984,19 +51688,19 @@ Fixed buffer overflow bug when writing a certain error message.
Added usage of @code{setrlimit()} on Linux to get
@code{-O --open-files-limit=#} to work on Linux.
@item
-Added new @code{mysqld} variable: @code{bdb_version}.
+Added @code{bdb_version} variable to @code{mysqld}.
@item
Fixed bug when using expression of type:
@example
SELECT ... FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=t2.a
@end example
-In this case the test in the @code{WHERE} clause was wrongly optimized away.
+In this case the test in the @code{WHERE} clause was wrongly optimised away.
@item
Fixed bug in @code{MyISAM} when deleting keys with possible @code{NULL}
values, but the first key-column was not a prefix-compressed text column.
@item
-Fixed @code{mysql.server} to read the @code{mysql.server} option section
-instead of @code{mysql_server}.
+Fixed @code{mysql.server} to read the @code{[mysql.server]} option file group
+rather than the @code{[mysql_server]} group.
@item
Fixed @code{safe_mysqld} and @code{mysql.server} to also read the
@code{server} option section.
@@ -48006,7 +51710,7 @@ Added @code{Threads_created} status variable to @code{mysqld}.
@node News-3.23.30, News-3.23.29, News-3.23.31, News-3.23.x
-@appendixsubsec Changes in release 3.23.30
+@appendixsubsec Changes in release 3.23.30 (04 Jan 2001)
@itemize @bullet
@item
@@ -48024,24 +51728,24 @@ on 32-bit systems.
Changed @code{BDB} tables to not use internal subtransactions and reuse
open files to get more speed.
@item
-Added option @code{--mysqld=#} to @code{safe_mysqld}.
+Added @code{--mysqld=#} option to @code{safe_mysqld}.
@item
Allow hex constants in the @code{--fields-*-by} and
@code{--lines-terminated-by} options to @code{mysqldump} and
@code{mysqlimport}. By Paul DuBois.
@item
-Added option @code{--safe-show-database} to @code{mysqld}.
+Added @code{--safe-show-database} option to @code{mysqld}.
@item
Added @code{have_bdb}, @code{have_gemini}, @code{have_innobase},
-@code{have_raid} and @code{have_ssl} to @code{SHOW VARIABLES} to make it
+@code{have_raid} and @code{have_openssl} to @code{SHOW VARIABLES} to make it
easy to test for supported extensions.
@item
-Added option @code{--open-files-limit} to @code{mysqld}.
+Added @code{--open-files-limit} option to @code{mysqld}.
@item
-Changed option @code{--open-files} to @code{--open-files-limit} in
+Changed @code{--open-files} option to @code{--open-files-limit} in
@code{safe_mysqld}.
@item
-Fixed a bug where some rows were not found with @code{HEAP} tables
+Fixed a bug where some rows were not found with @code{HEAP} tables
that had many keys.
@item
Fixed that @code{--bdb-no-sync} works.
@@ -48049,12 +51753,12 @@ Fixed that @code{--bdb-no-sync} works.
Changed @code{--bdb-recover} to @code{--bdb-no-recover} as recover should
be on by default.
@item
-Changed the default number of BDB locks to 10000.
+Changed the default number of @code{BDB} locks to 10000.
@item
Fixed a bug from 3.23.29 when allocating the shared structure needed
-for BDB tables.
+for @code{BDB} tables.
@item
-Changed @file{mysqld_multi.sh} to use configure variables. Patch by
+Changed @code{mysqld_multi.sh} to use configure variables. Patch by
Christopher McCrory.
@item
Added fixing of include files for Solaris 2.8.
@@ -48069,7 +51773,7 @@ Fixed bug when running two simultaneous @code{SHOW LOGS} queries.
@node News-3.23.29, News-3.23.28, News-3.23.30, News-3.23.x
-@appendixsubsec Changes in release 3.23.29
+@appendixsubsec Changes in release 3.23.29 (16 Dec 2000)
@itemize @bullet
@item
@@ -48078,14 +51782,14 @@ support. By Albert Chin-A-Young.
@item
Fixed bug in @code{<=>} operator.
@item
-Fixed bug in @code{REPLACE} with BDB tables.
+Fixed bug in @code{REPLACE} with @code{BDB} tables.
@item
@code{LPAD()} and @code{RPAD()} will shorten the result string if it's longer
than the length argument.
@item
Added @code{SHOW LOGS} command.
@item
-Remove not used BDB logs on shutdown.
+Remove unused @code{BDB} logs on shutdown.
@item
When creating a table, put @code{PRIMARY} keys first, followed by
@code{UNIQUE} keys.
@@ -48108,14 +51812,14 @@ type table.
Changed the default server-id to 1 for masters and 2 for slaves
to make it easier to use the binary log.
@item
-Renamed variable @code{bdb_lock_max} to @code{bdb_max_lock}.
+Renamed @code{bdb_lock_max} variable to @code{bdb_max_lock}.
@item
-Added support for @code{auto_increment} on sub-fields for BDB tables.
+Added support for @code{AUTO_INCREMENT} on sub-fields for @code{BDB} tables.
@item
-Added @code{ANALYZE} of BDB tables.
+Added @code{ANALYZE} of @code{BDB} tables.
@item
-In BDB tables, we now store the number of rows; This helps to optimize queries
-when we need an approximation of the number of rows.
+In @code{BDB} tables, we now store the number of rows; this helps to optimise
+queries when we need an approximation of the number of rows.
@item
If we get an error in a multi-row statement, we now only rollback the
last statement, not the entire transaction.
@@ -48123,23 +51827,23 @@ last statement, not the entire transaction.
If you do a @code{ROLLBACK} when you have updated a non-transactional table
you will get an error as a warning.
@item
-Added option @code{--bdb-shared-data} to @code{mysqld}.
+Added @code{--bdb-shared-data} option to @code{mysqld}.
@item
-Added status variable @code{Slave_open_temp_tables}.
+Added @code{Slave_open_temp_tables} status variable to @code{mysqld}
@item
-Added variables @code{binlog_cache_size} and @code{max_binlog_cache_size} to
+Added @code{binlog_cache_size} and @code{max_binlog_cache_size} variables to
@code{mysqld}.
@item
@code{DROP TABLE}, @code{RENAME TABLE}, @code{CREATE INDEX} and
@code{DROP INDEX} are now transaction endpoints.
@item
-If you do a @code{DROP DATABASE} on a symbolic linked database, both
+If you do a @code{DROP DATABASE} on a symbolically linked database, both
the link and the original database is deleted.
@item
-Fixed that @code{DROP DATABASE} works on OS/2.
+Fixed @code{DROP DATABASE} to work on OS/2.
@item
Fixed bug when doing a @code{SELECT DISTINCT ... table1 LEFT JOIN
-table2 ...} when table2 was empty.
+table2 ...} when @code{table2} was empty.
@item
Added @code{--abort-slave-event-count} and
@code{--disconnect-slave-event-count} options to @code{mysqld} for
@@ -48148,18 +51852,18 @@ debugging and testing of replication.
Fixed replication of temporary tables. Handles everything except
slave server restart.
@item
-@code{SHOW KEYS} now shows whether or not key is @code{FULLTEXT}.
+@code{SHOW KEYS} now shows whether key is @code{FULLTEXT}.
@item
-New script @file{mysqld_multi}. @xref{mysqld_multi, , @code{mysqld_multi}}.
+New script @code{mysqld_multi}. @xref{mysqld_multi, , @code{mysqld_multi}}.
@item
-Added new script, @file{mysql-multi.server.sh}. Thanks to
-Tim Bunce @email{Tim.Bunce@@ig.co.uk} for modifying @file{mysql.server} to
+Added new script, @code{mysql-multi.server.sh}. Thanks to
+Tim Bunce @email{Tim.Bunce@@ig.co.uk} for modifying @code{mysql.server} to
easily handle hosts running many @code{mysqld} processes.
@item
-@file{safe_mysqld}, @file{mysql.server}, and @file{mysql_install_db} have
-been modified to use @code{mysql_print_defaults} instead of various hacks
-to read the @file{my.cnf} files. In addition, the handling of various
-paths has been made more consistent with how @code{mysqld} handles them
+@code{safe_mysqld}, @code{mysql.server}, and @code{mysql_install_db} have
+been modified to use @code{mysql_print_defaults} instead of various hacks
+to read the @file{my.cnf} files. In addition, the handling of various
+paths has been made more consistent with how @code{mysqld} handles them
by default.
@item
Automatically remove Berkeley DB transaction logs that no longer are in
@@ -48171,7 +51875,7 @@ Added a warning if number of rows changes on @code{REPAIR}/@code{OPTIMIZE}.
@item
Applied patches for OS/2 by @code{Yuri Dario}.
@item
-@code{FLUSH TABLES table_name} didn't always flush the index tree
+@code{FLUSH TABLES tbl_name} didn't always flush the index tree
to disk properly.
@item
@code{--bootstrap} is now run in a separate thread. This fixes a problem
@@ -48179,7 +51883,7 @@ that caused @code{mysql_install_db} to core dump on some Linux machines.
@item
Changed @code{mi_create()} to use less stack space.
@item
-Fixed bug with optimizer trying to over-optimize @code{MATCH} when used
+Fixed bug with optimiser trying to over-optimise @code{MATCH()} when used
with @code{UNIQUE} key.
@item
Changed @code{crash-me} and the MySQL benchmarks to also work
@@ -48190,15 +51894,15 @@ porting easier.
@item
Reset status variable which could cause problem if one used @code{--slow-log}.
@item
-Added variable @code{connect_timeout} to @code{mysql} and @code{mysqladmin}.
+Added @code{connect_timeout} variable to @code{mysql} and @code{mysqladmin}.
@item
-Added @code{connect_timeout} as an alias for @code{timeout} for option files
+Added @code{connect-timeout} as an alias for @code{timeout} for option files
read by @code{mysql_options()}.
@end itemize
@node News-3.23.28, News-3.23.27, News-3.23.29, News-3.23.x
-@appendixsubsec Changes in release 3.23.28
+@appendixsubsec Changes in release 3.23.28 (22 Nov 2000: Gamma)
@itemize @bullet
@item
@@ -48211,7 +51915,7 @@ and the interactive help for more information.
Fixed crash when automatic repair of @code{MyISAM} table failed.
@item
Fixed a major performance bug in the table locking code when one
-constantly had a LOT of @code{SELECT}, @code{UPDATE} and @code{INSERT}
+constantly had a lot of @code{SELECT}, @code{UPDATE} and @code{INSERT}
statements running. The symptom was that the @code{UPDATE} and
@code{INSERT} queries were locked for a long time while new @code{SELECT}
statements were executed before the updates.
@@ -48221,8 +51925,8 @@ When reading @code{options_files} with @code{mysql_options()} the
@item
One can now specify @code{interactive-timeout} in the option file that
is read by @code{mysql_options()}. This makes it possible to force
-programs that run for a long time (like @code{mysqlhotcopy}) to use
-@code{interactive_timeout} instead of @code{wait_timeout}.
+programs that run for a long time (like @code{mysqlhotcopy}) to use the
+@code{interactive_timeout} time instead of the @code{wait_timeout} time.
@item
Added to the slow query log the time and the user name for each logged
query. If you are using @code{--log-long-format} then also queries that
@@ -48241,11 +51945,11 @@ Fixed a bug when using a multi-part keys where the first part was of type
@item
Fixed a bug where @code{SELECT DISTINCT * ... LIMIT #} only returned one row.
@item
-Fixed a bug in the assembler code in @code{strstr()} for sparc and cleaned up
+Fixed a bug in the assembler code in @code{strstr()} for SPARC and cleaned up
the @file{global.h} header file to avoid a problem with bad aliasing with
the compiler submitted with RedHat 7.0. (Reported by Trond Eivind Glomsrød)
@item
-The option @code{--skip-networking} now works properly on NT.
+The @code{--skip-networking} option now works properly on NT.
@item
Fixed a long outstanding bug in the @code{ISAM} tables when a row with a length
of more than 65K was shortened by a single byte.
@@ -48253,15 +51957,16 @@ of more than 65K was shortened by a single byte.
Fixed a bug in @code{MyISAM} when running multiple updating processes on
the same table.
@item
-Allow one to use @code{FLUSH TABLE tablename}.
+Allow one to use @code{FLUSH TABLE tbl_name}.
@item
Added @code{--replicate-ignore-table}, @code{--replicate-do-table},
- @code{--replicate-wild-ignore-table}, @code{--replicate-wild-do-table}.
+@code{--replicate-wild-ignore-table}, and @code{--replicate-wild-do-table}
+options to @code{mysqld}.
@item
Changed all log files to use our own @code{IO_CACHE} mechanism instead of
@code{FILE} to avoid OS problems when there are many files open.
@item
-Added options @code{--open-files} and @code{--timezone} to @code{safe_mysqld}.
+Added @code{--open-files} and @code{--timezone} options to @code{safe_mysqld}.
@item
Fixed a fatal bug in @code{CREATE TEMPORARY TABLE ... SELECT ...}.
@item
@@ -48279,9 +51984,9 @@ Fixed a bug where we didn't allow an index name after the
Added @code{TRUNCATE table_name} as a synonym for
@code{DELETE FROM table_name}.
@item
-Fixed a bug in a BDB key compare function when comparing part keys.
+Fixed a bug in a @code{BDB} key compare function when comparing part keys.
@item
-Added variable @code{bdb_lock_max} to @code{mysqld}.
+Added @code{bdb_lock_max} variable to @code{mysqld}.
@item
Added more tests to the benchmark suite.
@item
@@ -48301,11 +52006,11 @@ Added @code{PURGE MASTER LOGS TO}.
Added @code{SHOW MASTER LOGS}.
@item
Added @code{--safemalloc-mem-limit} option to @code{mysqld} to simulate memory
-shortage when compiled @code{--with-debug=full}.
+shortage when compiled with the @code{--with-debug=full} option.
@item
-Fixed several coredumps in out-of-memory conditions.
+Fixed several core dumps in out-of-memory conditions.
@item
-@code{SHOW SLAVE STATUS} was using an uninitialized mutex if the slave had
+@code{SHOW SLAVE STATUS} was using an uninitialised mutex if the slave had
not been started yet.
@item
Fixed bug in @code{ELT()} and @code{MAKE_SET()} when the query used
@@ -48320,20 +52025,20 @@ new table with the rows in a specific order.
@node News-3.23.27, News-3.23.26, News-3.23.28, News-3.23.x
-@appendixsubsec Changes in release 3.23.27
+@appendixsubsec Changes in release 3.23.27 (24 Oct 2000)
@itemize @bullet
@item
-Fixed a bug where the automatic repair of MyISAM tables sometimes failed
-when the data file was corrupt.
+Fixed a bug where the automatic repair of @code{MyISAM} tables sometimes failed
+when the datafile was corrupt.
@item
Fixed a bug in @code{SHOW CREATE} when using @code{AUTO_INCREMENT} columns.
@item
-Changed BDB tables to use new compare function in Berkeley DB 3.2.3.
+Changed @code{BDB} tables to use new compare function in Berkeley DB 3.2.3.
@item
-You can now use Unix sockets with @code{mit-pthreads}.
+You can now use Unix sockets with MIT-pthreads.
@item
-Added the latin5 (turkish) character set.
+Added the @code{latin5} (turkish) character set.
@item
Small portability fixes.
@end itemize
@@ -48344,18 +52049,21 @@ Small portability fixes.
@itemize @bullet
@item
+Renamed @code{FLUSH MASTER} and @code{FLUSH SLAVE} to @code{RESET MASTER}
+and @code{RESET SLAVE}.
+@item
Fixed @code{<>} to work properly with @code{NULL}.
@item
Fixed a problem with @code{SUBSTRING_INDEX()} and @code{REPLACE()}.
(Patch by Alexander Igonitchev)
@item
-Fix @code{CREATE TEMPORARY TABLE IF NOT EXISTS} not to give an error
+Fix @code{CREATE TEMPORARY TABLE IF NOT EXISTS} not to produce an error
if the table exists.
@item
-If you don't create a @code{PRIMARY KEY} in a BDB table, a hidden
+If you don't create a @code{PRIMARY KEY} in a @code{BDB} table, a hidden
@code{PRIMARY KEY} will be created.
@item
-Added read-only-key optimization to BDB tables.
+Added read-only-key optimisation to @code{BDB} tables.
@item
@code{LEFT JOIN} in some cases preferred a full table scan when there was
no @code{WHERE} clause.
@@ -48370,14 +52078,14 @@ Automatic repair of @code{MyISAM} tables if you start @code{mysqld} with
@item
Removed the @code{TYPE=} keyword from @code{CHECK} and
@code{REPAIR}. Allow @code{CHECK} options to be combined. (You can still
-use @code{TYPE=} but this usage is deprecated.)
+use @code{TYPE=}, but this usage is deprecated.)
@item
-Fixed mutex bug in the binary replication log - long update queries could
+Fixed mutex bug in the binary replication log -- long update queries could
be read only in part by the slave if it did it at the wrong time, which
was not fatal, but resulted in a performance-degrading reconnect and
a scary message in the error log.
@item
-Changed the format of the binary log - added magic number, server
+Changed the format of the binary log -- added magic number, server
version, binlog version. Added server id and query error code for each
query event.
@item
@@ -48393,17 +52101,17 @@ Added @code{--skip-slave-start} option to @code{mysqld}.
Updates that generated an error code (such as @code{INSERT INTO foo(some_key)
values (1),(1)}) erroneously terminated the slave thread.
@item
-Added optimization of queries where @code{DISTINCT} is only used on columns
+Added optimisation of queries where @code{DISTINCT} is only used on columns
from some of the tables.
@item
Allow floating-point numbers where there is no sign after the exponent
-(like 1e1).
+(like @code{1e1}).
@item
@code{SHOW GRANTS} didn't always show all column grants.
@item
-Added @code{--default-extra-file=#} to all MySQL clients.
+Added @code{--default-extra-file=#} option to all MySQL clients.
@item
-Columns referenced in @code{INSERT} statements now are initialized properly.
+Columns referenced in @code{INSERT} statements now are initialised properly.
@item
@code{UPDATE} didn't always work when used with a range on a timestamp that
was part of the key that was used to find rows.
@@ -48422,12 +52130,13 @@ on a patch from John Jones.
@item
Fixed that @code{databasename} works as second argument to @code{mysqlhotcopy}.
@item
-@code{UMASK} and @code{UMASK_DIR} can now be specified in octal.
+The values for the @code{UMASK} and @code{UMASK_DIR} environment variables
+now can be specified in octal by beginning the value with a zero.
@item
Added @code{RIGHT JOIN}. This makes @code{RIGHT} a reserved word.
@item
Added @code{@@@@IDENTITY} as a synonym for @code{LAST_INSERT_ID()}.
-(This is for Visual Basic compatibility.)
+(This is for MSSQL compatibility.)
@item
Fixed a bug in @code{myisamchk} and @code{REPAIR} when using @code{FULLTEXT}
index.
@@ -48442,17 +52151,17 @@ Fixed a bug in @code{MyISAM} with packed multi-part keys.
@item
Fixed crash when using @code{CHECK TABLE} on Windows.
@item
-Fixed a bug where @code{FULLTEXT} index always used the koi8_ukr
+Fixed a bug where @code{FULLTEXT} index always used the @code{koi8_ukr}
character set.
@item
Fixed privilege checking for @code{CHECK TABLE}.
@item
-The @code{MyISAM} repair/reindex code didn't use the @code{--tempdir}
+The @code{MyISAM} repair/reindex code didn't use the @code{--tmpdir}
option for its temporary files.
@item
-Added @code{BACKUP TABLE/RESTORE TABLE}.
+Added @code{BACKUP TABLE} and @code{RESTORE TABLE}.
@item
-Fixed coredump on @code{CHANGE MASTER TO} when the slave did not have
+Fixed core dump on @code{CHANGE MASTER TO} when the slave did not have
the master to start with.
@item
Fixed incorrect @code{Time} in the processlist for @code{Connect} of
@@ -48463,7 +52172,7 @@ The slave now logs when it connects to the master.
Fixed a core dump bug when doing @code{FLUSH MASTER} if you didn't specify
a filename argument to @code{--log-bin}.
@item
-Added missing @file{ha_berkeley.x} files to the MySQL Windows
+Added missing @file{ha_berkeley.x} files to the MySQL Windows distribution.
@item
Fixed some mutex bugs in the log code that could cause thread blocks if new
log files couldn't be created.
@@ -48476,7 +52185,7 @@ in memory on systems with the @code{mlockall()} call (like in Solaris).
@code{HEAP} tables didn't use keys properly. (Bug from 3.23.23.)
@item
Added better support for @code{MERGE} tables (keys, mapping, creation,
-documentation...). @xref{MERGE}.
+documentation...). @xref{MERGE, , @code{MERGE}}.
@item
Fixed bug in @code{mysqldump} from 3.23 which caused some @code{CHAR} columns
not to be quoted.
@@ -48491,12 +52200,12 @@ Added a pre-alloced block to root_malloc to get fewer mallocs.
@item
Added a lot of new statistics variables.
@item
-Fixed @code{ORDER BY} bug with BDB tables.
+Fixed @code{ORDER BY} bug with @code{BDB} tables.
@item
Removed warning that @code{mysqld} couldn't remove the @file{.pid} file
under Windows.
@item
-Changed @code{--log-isam} to log @strong{MyISAM} tables instead of isam
+Changed @code{--log-isam} to log @code{MyISAM} tables instead of isam
tables.
@item
Fixed @code{CHECK TABLE} to work on Windows.
@@ -48506,27 +52215,27 @@ Added file mutexes to make @code{pwrite()} safe on Windows.
@node News-3.23.24, News-3.23.23, News-3.23.25, News-3.23.x
-@appendixsubsec Changes in release 3.23.24
+@appendixsubsec Changes in release 3.23.24 (08 Sep 2000)
@itemize @bullet
@item
-Added @code{mysqld} variable @code{created_tmp_disk_tables}.
+Added @code{created_tmp_disk_tables} variable to @code{mysqld}.
@item
To make it possible to reliably dump and restore tables with
@code{TIMESTAMP(X)} columns, MySQL now reports columns with @code{X}
other than 14 or 8 to be strings.
@item
-Changed sort order for latin1 as it was before MySQL Version 3.23.23.
-Any table with @code{CHAR} columns that may have characters with ASCII
-values greater than 128 that was created or modified with 3.23.22 must
-be repaired!
+Changed sort order for @code{latin1} as it was before MySQL Version 3.23.23.
+Any table that was created or modified with 3.23.22 must be repaired if it has
+@code{CHAR} columns that may contain characters with ASCII values greater than
+128!
@item
Fixed small memory leak introduced from 3.23.22 when creating a
temporary table.
@item
-Fixed problem with BDB tables and reading on a unique (not primary) key.
+Fixed problem with @code{BDB} tables and reading on a unique (not primary) key.
@item
-Restored the win1251 character set (it's now only marked deprecated).
+Restored the @code{win1251} character set (it's now only marked deprecated).
@end itemize
@@ -48535,11 +52244,11 @@ Restored the win1251 character set (it's now only marked deprecated).
@itemize @bullet
@item
-Changed sort order for 'German'; All tables created with 'German' sortorder
+Changed sort order for 'German'; all tables created with 'German' sortorder
must be repaired with @code{REPAIR TABLE} or @code{myisamchk} before use!
@item
-Added option @code{--core-file} to @code{mysqld} to get a core file on
-Linux if @code{mysqld} dies on the SIGSEGV signal.
+Added @code{--core-file} option to @code{mysqld} to get a core file on
+Linux if @code{mysqld} dies on the @code{SIGSEGV} signal.
@item
MySQL client @code{mysql} now starts with option
@code{--no-named-commands} (@code{-g}) by default. This option can be
@@ -48551,7 +52260,7 @@ still work from the first line.
Fixed a problem when using many pending @code{DROP TABLE} statements at
the same time.
@item
-Optimizer didn't use keys properly when using @code{LEFT JOIN} on an
+Optimiser didn't use keys properly when using @code{LEFT JOIN} on an
empty table.
@item
Added shorter help text when invoking @code{mysqld} with incorrect options.
@@ -48561,21 +52270,21 @@ Fixed non-fatal @code{free()} bug in @code{mysqlimport}.
Fixed bug in @code{MyISAM} index handling of
@code{DECIMAL}/@code{NUMERIC} keys.
@item
-Fixed a bug in concurrent insert in @code{MyISAM} tables; In some contexts,
+Fixed a bug in concurrent insert in @code{MyISAM} tables. In some contexts,
usage of @code{MIN(key_part)} or @code{MAX(key_part)} returned an empty set.
@item
Updated @code{mysqlhotcopy} to use the new @code{FLUSH TABLES table_list}
syntax. Only tables which are being backed up are flushed now.
@item
-Changed behavior of @code{--enable-thread-safe-client} so
+Changed behaviour of @code{--enable-thread-safe-client} so
that both non-threaded (@code{-lmysqlclient}) and threaded
(@code{-lmysqlclient_r}) libraries are built. Users who linked
against a threaded @code{-lmysqlclient} will need to link against
-@code{libmysqlclient_r} now.
+@code{-lmysqlclient_r} now.
@item
-Added atomic @code{RENAME} command.
+Added atomic @code{RENAME TABLE} command.
@item
-Don't count entries with @code{NULL} in @code{COUNT(DISTINCT ...)}.
+Don't count @code{NULL} values in @code{COUNT(DISTINCT ...)}.
@item
Changed @code{ALTER TABLE}, @code{LOAD DATA INFILE} on empty tables and
@code{INSERT ... SELECT ...} on empty tables to create non-unique indexes
@@ -48596,33 +52305,34 @@ Fixed a lock in our thr_rwlock code, which could make selects that run
at the same time as concurrent inserts crash. This only affects systems
that don't have the @code{pthread_rwlock_rdlock} code.
@item
-When deleting rows with a non-unique key in a HEAP table, all rows weren't
-always deleted.
+When deleting rows with a non-unique key in a @code{HEAP} table, all rows
+weren't always deleted.
@item
-Fixed bug in range optimizer for HEAP tables for searches on a part index.
+Fixed bug in range optimiser for @code{HEAP} tables for searches on a part
+index.
@item
-Fixed that @code{SELECT} on part keys works with BDB tables.
+Fixed @code{SELECT} on part keys to work with @code{BDB} tables.
@item
-Fixed @code{INSERT INTO bdb_table ... SELECT} to work with BDB tables.
+Fixed @code{INSERT INTO bdb_table ... SELECT} to work with @code{BDB} tables.
@item
@code{CHECK TABLE} now updates key statistics for the table.
@item
@code{ANALYZE TABLE} will now only update tables that have been changed
-since thee last @code{ANALYZE}. Note that this is a new feature and tables
-will not be marked to be analyzed until they are updated in any way with
+since the last @code{ANALYZE}. Note that this is a new feature and tables
+will not be marked to be analysed until they are updated in any way with
3.23.23 or newer. For older tables, you have to do @code{CHECK TABLE}
to update the key distribution.
@item
Fixed some minor privilege problems with @code{CHECK}, @code{ANALYZE},
@code{REPAIR} and @code{SHOW CREATE} commands.
@item
-Added @code{CHANGE MASTER TO} command.
+Added @code{CHANGE MASTER TO} statement.
@item
Added @code{FAST}, @code{QUICK} @code{EXTENDED} check types to
@code{CHECK TABLES}.
@item
Changed @code{myisamchk} so that @code{--fast} and
-@code{--check-changed-tables} are also honored with @code{--sort-index} and
+@code{--check-only-changed} are also honored with @code{--sort-index} and
@code{--analyze}.
@item
Fixed fatal bug in @code{LOAD TABLE FROM MASTER} that did not lock the
@@ -48635,13 +52345,13 @@ More variables in @code{SHOW SLAVE STATUS} and @code{SHOW MASTER STATUS}.
@item
@code{SLAVE STOP} now will not return until the slave thread actually exits.
@item
-Full text search via the @code{MATCH} function and @code{FULLTEXT} index type.
-(For MyISAM files). This makes @code{FULLTEXT} a reserved word.
+Full-text search via the @code{MATCH()} function and @code{FULLTEXT} index type
+(for @code{MyISAM} files). This makes @code{FULLTEXT} a reserved word.
@end itemize
@node News-3.23.22, News-3.23.21, News-3.23.23, News-3.23.x
-@appendixsubsec Changes in release 3.23.22
+@appendixsubsec Changes in release 3.23.22 (31 Jul 2000)
@itemize @bullet
@item
@@ -48652,24 +52362,24 @@ Fixed that @code{MASTER} and @code{COLLECTION} are not reserved words.
@item
The log generated by @code{--slow-query-log} didn't contain the whole queries.
@item
-Fixed that open transactions in BDB tables are rolled back if the
+Fixed that open transactions in @code{BDB} tables are rolled back if the
connection is closed unexpectedly.
@item
Added workaround for a bug in @code{gcc} 2.96 (intel) and @code{gcc} 2.9
-(Ia64) in @code{gen_lex_hash.c}.
+(IA64) in @code{gen_lex_hash.c}.
@item
Fixed memory leak in the client library when using @code{host=} in the
-@code{my.cnf} file.
+@file{my.cnf} file.
@item
-Optimized functions that manipulate the hours/minutes/seconds.
+Optimised functions that manipulate the hours/minutes/seconds.
@item
Fixed bug when comparing the result of @code{DATE_ADD()}/@code{DATE_SUB()}
against a number.
@item
-Changed the meaning of @code{-F, --fast} for @code{myisamchk}. Added option
-@code{-C, --check-only-changed} to @code{myisamchk}.
+Changed the meaning of @code{-F, --fast} for @code{myisamchk}. Added
+@code{-C, --check-only-changed} option to @code{myisamchk}.
@item
-Added @code{ANALYZE table_name} to update key statistics for tables.
+Added @code{ANALYZE tbl_name} to update key statistics for tables.
@item
Changed binary items @code{0x...} to be regarded as integers by default.
@item
@@ -48689,10 +52399,10 @@ Added @code{SHOW MASTER STATUS} and @code{SHOW SLAVE STATUS}.
@itemize @bullet
@item
-Added @code{mysql_character_set_name(MYSQL *mysql)} function to the
+Added @code{mysql_character_set_name()} function to the
MySQL C API.
@item
-Made the update log @code{ASCII 0} safe.
+Made the update log ASCII 0 safe.
@item
Added the @code{mysql_config} script.
@item
@@ -48701,25 +52411,25 @@ partly indexed.
@item
One would get a core dump if the log file was not readable by the MySQL user.
@item
-Changed @code{mysqladmin} to use the @code{CREATE DATABASE}/@code{DROP
-DATABASE} commands instead of the old deprecated API calls.
+Changed @code{mysqladmin} to use @code{CREATE DATABASE} and @code{DROP
+DATABASE} statements instead of the old deprecated API calls.
@item
Fixed @code{chown} warning in @code{safe_mysqld}.
@item
Fixed a bug in @code{ORDER BY} that was introduced in 3.23.19.
@item
-Only optimize the @code{DELETE FROM tbl_name} to do a drop+create of
-the table if we are in @code{AUTOCOMMIT} mode. (Needed for BDB tables).
+Only optimise the @code{DELETE FROM tbl_name} to do a drop+create of
+the table if we are in @code{AUTOCOMMIT} mode (needed for @code{BDB} tables).
@item
Added extra checks to avoid index corruption when the @code{ISAM}/@code{MyISAM}
-index files gets full during an @code{INSERT}/@code{UPDATE}.
+index files get full during an @code{INSERT}/@code{UPDATE}.
@item
@code{myisamchk} didn't correctly update row checksum when used with
-@code{-ro} (This only gave an warning in subsequent runs).
+@code{-ro} (this only gave a warning in subsequent runs).
@item
Fixed bug in @code{REPAIR TABLE} so that it works with tables without indexes.
@item
-Fixed buffer overrun in @code{DROP DATABASE}
+Fixed buffer overrun in @code{DROP DATABASE}.
@item
@code{LOAD TABLE FROM MASTER} is sufficiently bug-free to announce it as
a feature.
@@ -48733,7 +52443,7 @@ a feature.
@itemize @bullet
@item
-Fixed bug in 3.23.19; @code{DELETE FROM tbl_name} removed the .frm file.
+Fixed bug in 3.23.19; @code{DELETE FROM tbl_name} removed the @file{.frm} file.
@item
Added @code{SHOW CREATE TABLE}.
@end itemize
@@ -48745,7 +52455,7 @@ Added @code{SHOW CREATE TABLE}.
@itemize @bullet
@item
Changed copyright for all files to GPL for the server code and utilities and
-LGPL for the client libraries.
+to LGPL for the client libraries.
@item
Fixed bug where all rows matching weren't updated on a @code{MyISAM} table
when doing update based on key on a table with many keys and some key changed
@@ -48755,11 +52465,11 @@ The Linux MySQL RPM's and binaries are now statically linked with
a linuxthread version that has faster mutex handling when used with
MySQL.
@item
-@code{ORDER BY} can now uses @code{REF} keys to find subset the rows
-that needs to be sorted.
+@code{ORDER BY} can now use @code{REF} keys to find subsets of the rows
+that need to be sorted.
@item
-Changed name of @code{print_defaults} to @code{my_print_defaults} to avoid
-name confusion.
+Changed name of @code{print_defaults} program to @code{my_print_defaults}
+to avoid name confusion.
@item
Fixed @code{NULLIF()} to work according to ANSI SQL99.
@item
@@ -48769,14 +52479,18 @@ parameters to @code{mysqld}.
Fixed bug that destroyed index when doing @code{myisamchk --sort-records}
on a table with prefix compressed index.
@item
-Added pack_isam and myisampack to the standard MySQL distribution.
+Added @code{pack_isam} and @code{myisampack} to the standard MySQL
+distribution.
@item
Added the syntax @code{BEGIN WORK} (the same as @code{BEGIN}).
@item
Fixed core dump bug when using @code{ORDER BY} on a @code{CONV()} expression.
-@item Added @code{LOAD TABLE FROM MASTER}
-@item Added @code{FLUSH MASTER} and @code{FLUSH SLAVE}
-@item Fixed big/little endian problem in the replication
+@item
+Added @code{LOAD TABLE FROM MASTER}.
+@item
+Added @code{FLUSH MASTER} and @code{FLUSH SLAVE}.
+@item
+Fixed big/little endian problem in the replication.
@end itemize
@@ -48787,18 +52501,18 @@ Fixed core dump bug when using @code{ORDER BY} on a @code{CONV()} expression.
@item
Fixed a problem from 3.23.17 when choosing character set on the client side.
@item
-Added @code{FLUSH TABLES WITH READ LOCK} to make a global lock suitable to
-make a copy of MySQL data files.
+Added @code{FLUSH TABLES WITH READ LOCK} to make a global lock suitable for
+making a copy of MySQL datafiles.
@item
@code{CREATE TABLE ... SELECT ... PROCEDURE} now works.
@item
-Internal temporary tables will now uses compressed index when using
+Internal temporary tables will now use compressed index when using
@code{GROUP BY} on @code{VARCHAR/CHAR} columns.
@item
Fixed a problem when locking the same table with both a @code{READ} and a
@code{WRITE} lock.
@item
-Fixed problem with myisamchk and @code{RAID} tables.
+Fixed problem with @code{myisamchk} and @code{RAID} tables.
@end itemize
@@ -48807,18 +52521,18 @@ Fixed problem with myisamchk and @code{RAID} tables.
@itemize @bullet
@item
-Fixed a bug in @code{find_in_set()} when the first argument was @code{NULL}.
+Fixed a bug in @code{FIND_IN_SET()} when the first argument was @code{NULL}.
@item
Added table locks to Berkeley DB.
@item
Fixed a bug with @code{LEFT JOIN} and @code{ORDER BY} where the first
table had only one matching row.
@item
-Added 4 sample @code{my.cnf} example files in the @file{support-files}
+Added 4 sample @file{my.cnf} example files in the @file{support-files}
directory.
@item
-Fixed @code{duplicated key} problem when doing big @code{GROUP BY}'s.
-(This bug was probably introduced in 3.23.15).
+Fixed @code{duplicated key} problem when doing big @code{GROUP BY} operations.
+(This bug was probably introduced in 3.23.15.)
@item
Changed syntax for @code{INNER JOIN} to match ANSI SQL.
@item
@@ -48835,19 +52549,20 @@ Fixed that @code{USE INDEX} works with @code{PRIMARY} keys.
@item
Added @code{BEGIN} statement to start a transaction in @code{AUTOCOMMIT} mode.
@item
-Added symbolic links support for Windows.
+Added support for symbolic links for Windows.
@item
-Changed protocol to let client know if the server is in AUTOCOMMIT mode
-and if there is a pending transaction. If there is a pending transaction
+Changed protocol to let client know if the server is in @code{AUTOCOMMIT} mode
+and if there is a pending transaction. If there is a pending transaction,
the client library will give an error before reconnecting to the server to
let the client know that the server did a rollback.
-The protocol is still backward compatible with old clients
+The protocol is still backward-compatible with old clients.
@item
@code{KILL} now works on a thread that is locked on a 'write' to a dead client.
@item
Fixed memory leak in the replication slave thread.
@item
-Added new option @code{log-slave-updates} to allow daisy-chaining the slaves.
+Added new @code{log-slave-updates} option to @code{mysqld}, to allow
+daisy-chaining the slaves.
@item
Fixed compile error on FreeBSD and other systems where @code{pthread_t}
is not the same as @code{int}.
@@ -48857,7 +52572,7 @@ Fixed master shutdown aborting the slave thread.
Fixed a race condition in @code{INSERT DELAYED} code when doing
@code{ALTER TABLE}.
@item
-Added deadlock detection sanity checks to @code{INSERT DELAYED}
+Added deadlock detection sanity checks to @code{INSERT DELAYED}.
@end itemize
@@ -48866,7 +52581,9 @@ Added deadlock detection sanity checks to @code{INSERT DELAYED}
@itemize @bullet
@item
-Added option @code{TYPE=QUICK} to @code{CHECK} and @code{REPAIR}.
+Added @code{SLAVE START} and @code{SLAVE STOP} statements.
+@item
+Added @code{TYPE=QUICK} option to @code{CHECK} and to @code{REPAIR}.
@item
Fixed bug in @code{REPAIR TABLE} when the table was in use by other threads.
@item
@@ -48883,23 +52600,23 @@ Put @code{CREATE TEMPORARY TABLE} commands in the update log.
@item
Fixed bug in handling of masked IP numbers in the privilege tables.
@item
-Fixed bug with @code{delayed_key_writes} tables and @code{CHECK TABLE}.
+Fixed bug with @code{delay_key_write} tables and @code{CHECK TABLE}.
@item
Added @code{replicate-do-db} and @code{replicate-ignore-db} options to
-restrict which databases get replicated
+@code{mysqld}, to restrict which databases get replicated.
@item
-Added @code{SQL_LOG_BIN} option
+Added @code{SQL_LOG_BIN} option.
@end itemize
@node News-3.23.15, News-3.23.14, News-3.23.16, News-3.23.x
-@appendixsubsec Changes in release 3.23.15
+@appendixsubsec Changes in release 3.23.15 (May 2000: Beta)
@itemize @bullet
@item
To start @code{mysqld} as @code{root}, you must now use the @code{--user=root} option.
@item
-Added interface to Berkeley DB. (This is not yet functional; Play with it at
+Added interface to Berkeley DB. (This is not yet functional; play with it at
your own risk!)
@item
Replication between master and slaves.
@@ -48923,9 +52640,9 @@ Don't write @code{INSERT DELAYED} to update log if @code{SQL_LOG_UPDATE=0}.
@item
Fixed problem with @code{REPLACE} on @code{HEAP} tables.
@item
-Added possible character sets and time zone to @code{SHOW VARIABLES}.
+Added possible character sets and time zone to @code{SHOW VARIABLES} output.
@item
-Fixed bug in locking code that could result it locking problems with
+Fixed bug in locking code that could result in locking problems with
concurrent inserts under high load.
@item
Fixed a problem with @code{DELETE} of many rows on a table with
@@ -48937,30 +52654,30 @@ Fixed a bug in reconnect (at the client side) where it didn't free memory
properly in some contexts.
@item
Fixed problems in update log when using @code{LAST_INSERT_ID()} to update
-a table with an auto_increment key.
+a table with an @code{AUTO_INCREMENT} key.
@item
-Added function @code{NULLIF()}.
+Added @code{NULLIF()} function.
@item
Fixed bug when using @code{LOAD DATA INFILE} on a table with
@code{BLOB/TEXT} columns.
@item
-Optimised MyISAM to be faster when inserting keys in sorted order.
+Optimised @code{MyISAM} to be faster when inserting keys in sorted order.
@item
@code{EXPLAIN SELECT ...} now also prints out whether MySQL needs to
create a temporary table or use file sorting when resolving the @code{SELECT}.
@item
-Added optimization to skip @code{ORDER BY} parts where the part is a
+Added optimisation to skip @code{ORDER BY} parts where the part is a
constant expression in the @code{WHERE} part. Indexes can now be used
even if the @code{ORDER BY} doesn't match the index exactly, as long as
-all the not used index parts and all the extra @code{ORDER BY}
+all the unused index parts and all the extra @code{ORDER BY}
columns are constants in the @code{WHERE} clause. @xref{MySQL indexes}.
@item
-@code{UPDATE} and @code{DELETE} on a whole unique key in the @code{WHERE} part,
-is now faster than before.
+@code{UPDATE} and @code{DELETE} on a whole unique key in the @code{WHERE} part
+are now faster than before.
@item
-Changed @code{RAID_CHUNKSIZE} to be in 1024 byte increments.
+Changed @code{RAID_CHUNKSIZE} to be in 1024-byte increments.
@item
-Fixed coredump in LOAD_FILE(NULL).
+Fixed core dump in @code{LOAD_FILE(NULL)}.
@end itemize
@@ -48969,6 +52686,8 @@ Fixed coredump in LOAD_FILE(NULL).
@itemize @bullet
@item
+Added @code{mysql_real_escape_string()} function to the MySQL C API.
+@item
Fixed a bug in @code{CONCAT()} where one of the arguments was a function
that returned a modified argument.
@item
@@ -48986,7 +52705,8 @@ Fixed that @code{DROP TABLE} is logged in the update log.
Fixed problem when searching on @code{DECIMAL()} key field
where the column data contained leading zeros.
@item
-Fix bug in @code{myisamchk} when the auto_increment isn't the first key.
+Fix bug in @code{myisamchk} when the @code{AUTO_INCREMENT} column isn't
+the first key.
@item
Allow @code{DATETIME} in ISO8601 format: 2000-03-12T12:00:00
@item
@@ -48995,17 +52715,18 @@ character sets (you can choose which when starting @code{mysqld}).
@item
Added command @code{REPAIR TABLE}.
@item
-Added C API function @code{mysql_thread_safe()}.
+Added @code{mysql_thread_safe()} function to the MySQL C API.
@item
Added the @code{UMASK_DIR} environment variable.
@item
-Added function @code{CONNECTION_ID()}.
+Added @code{CONNECTION_ID()} function to return the client connection thread
+ID.
@item
When using @code{=} on @code{BLOB} or @code{VARCHAR BINARY} keys, where
only a part of the column was indexed, the whole column of the result
row wasn't compared.
@item
-Fix for sjis character set and @code{ORDER BY}.
+Fix for @code{sjis} character set and @code{ORDER BY}.
@item
When running in ANSI mode, don't allow columns to be used that aren't in
the @code{GROUP BY} part.
@@ -49018,16 +52739,17 @@ the @code{GROUP BY} part.
@itemize @bullet
@item
Fixed problem when doing locks on the same table more than 2 times in
-the same @code{LOCK TABLE} command; This fixed the problem one got when running
+the same @code{LOCK TABLE} command; this fixed the problem one got when running
the test-ATIS test with @code{--fast} or @code{--check-only-changed}.
@item
-Added option @code{SQL_BUFFER_RESULT} to @code{SELECT}.
+Added @code{SQL_BUFFER_RESULT} option to @code{SELECT}.
@item
Removed end space from double/float numbers in results from temporary
tables.
+@item
Added @code{CHECK TABLE} command.
@item
-Added changes for MyISAM in 3.23.12 that didn't get into the source
+Added changes for @code{MyISAM} in 3.23.12 that didn't get into the source
distribution because of CVS problems.
@item
Fixed bug so that @code{mysqladmin shutdown} will wait for the local server
@@ -49035,8 +52757,8 @@ to close down.
@item
Fixed a possible endless loop when calculating timestamp.
@item
-Added @code{print_defaults} to the @file{.rpm} files. Removed @code{mysqlbug}
-from the client @file{.rpm} file.
+Added @code{print_defaults} program to the @file{.rpm} files. Removed
+@code{mysqlbug} from the client @file{.rpm} file.
@end itemize
@@ -49048,7 +52770,8 @@ from the client @file{.rpm} file.
Fixed bug in @code{MyISAM} involving @code{REPLACE ... SELECT ...} which could
give a corrupted table.
@item
-Fixed bug in @code{myisamchk} where it wrongly reset the auto_increment value.
+Fixed bug in @code{myisamchk} where it incorrectly reset the
+@code{AUTO_INCREMENT} value.
@item
LOTS of patches for Linux Alpha. MySQL now appears to be relatively
stable on Alpha.
@@ -49061,21 +52784,21 @@ addition, the new code is MUCH faster.
@item
Added patches to make MySQL compile on Mac OS X.
@item
-Added option @code{IF NOT EXISTS} to @code{CREATE DATABASE}.
+Added @code{IF NOT EXISTS} clause to @code{CREATE DATABASE}.
@item
-Added options @code{--all-databases} and @code{--databases} to @code{mysqldump}
+Added @code{--all-databases} and @code{--databases} options to @code{mysqldump}
to allow dumping of many databases at the same time.
@item
Fixed bug in compressed @code{DECIMAL()} index in @code{MyISAM} tables.
@item
Fixed bug when storing 0 into a timestamp.
@item
-When doing @code{mysqladmin shutdown} on a local connection, @code{mysqladmin} now
-waits until the pidfile is gone before terminating.
+When doing @code{mysqladmin shutdown} on a local connection, @code{mysqladmin}
+now waits until the PID file is gone before terminating.
@item
Fixed core dump with some @code{COUNT(DISTINCT ...)} queries.
@item
-Fixed that @code{myisamchk} works properly with RAID:ed tables.
+Fixed that @code{myisamchk} works properly with RAID tables.
@item
Fixed problem with @code{LEFT JOIN} and @code{key_field IS NULL}.
@item
@@ -49083,7 +52806,7 @@ Fixed bug in @code{net_clear()} which could give the error @code{Aborted
connection} in the MySQL clients.
@item
Added options @code{USE INDEX (key_list)} and @code{IGNORE INDEX (key_list)} as
-join parameters in @code{SELECT}.
+parameters in @code{SELECT}.
@item
@code{DELETE} and @code{RENAME} should now work on @code{RAID} tables.
@end itemize
@@ -49096,12 +52819,12 @@ join parameters in @code{SELECT}.
@item
Allow the @code{ALTER TABLE tbl_name ADD (field_list)} syntax.
@item
-Fixed problem with optimizer that could sometimes use wrong keys.
+Fixed problem with optimiser that could sometimes use incorrect keys.
@item
Fixed that @code{GRANT/REVOKE ALL PRIVILEGES} doesn't affect
@code{GRANT OPTION}.
@item
-Removed extra @code{)} from the output of @code{SHOW GRANTS}
+Removed extra @samp{)} from the output of @code{SHOW GRANTS}.
@item
Fixed problem when storing numbers in timestamps.
@item
@@ -49109,24 +52832,24 @@ Fix problem with timezones that have half hour offsets.
@item
Allow the syntax @code{UNIQUE INDEX} in @code{CREATE} statements.
@item
-@code{mysqlhotcopy} - fast on-line hot-backup utility for local
+@code{mysqlhotcopy} - fast online hot-backup utility for local
MySQL databases. By Tim Bunce.
@item
New more secure @code{mysqlaccess}. Thanks to Steve Harvey for this.
@item
-Added options @code{--i-am-a-dummy} and @code{--safe-updates} to @code{mysql}.
+Added @code{--i-am-a-dummy} and @code{--safe-updates} options to @code{mysql}.
@item
-Added variables @code{select_limit} and @code{max_join_size} to @code{mysql}.
+Added @code{select_limit} and @code{max_join_size} variables to @code{mysql}.
@item
-Added sql variables: @code{SQL_MAX_JOIN_SIZE} and @code{SQL_SAFE_UPDATES}.
+Added @code{SQL_MAX_JOIN_SIZE} and @code{SQL_SAFE_UPDATES} options.
@item
Added @code{READ LOCAL} lock that doesn't lock the table for concurrent
-inserts. (This is used by @code{mysqldump}).
+inserts. (This is used by @code{mysqldump}.)
@item
Changed that @code{LOCK TABLES ... READ} doesn't anymore allow concurrent
inserts.
@item
-Added option @code{--skip-delay-key-write} to @code{mysqld}.
+Added @code{--skip-delay-key-write} option to @code{mysqld}.
@item
Fixed security problem in the protocol regarding password checking.
@item
@@ -49143,7 +52866,7 @@ to make things safe for old clients.
@itemize @bullet
@item
-Fixed bug in 3.23.9 where memory wasn't properly freed when doing
+Fixed bug in 3.23.9 where memory wasn't properly freed when using
@code{LOCK TABLES}.
@end itemize
@@ -49157,15 +52880,15 @@ Fixed problem that affected queries that did arithmetic on group functions.
@item
Fixed problem with timestamps and @code{INSERT DELAYED}.
@item
-Fixed that @code{date_column BETWEEN const_date AND const_date} works.
+Fixed that @code{date_col BETWEEN const_date AND const_date} works.
@item
Fixed problem when only changing a 0 to @code{NULL} in a table with
@code{BLOB/TEXT} columns.
@item
-Fixed bug in range optimizer when using many key parts and or on the middle
+Fixed bug in range optimiser when using many key parts and or on the middle
key parts: @code{WHERE K1=1 and K3=2 and (K2=2 and K4=4 or K2=3 and K4=5)}
@item
-Added command @code{source} to @code{mysql} to allow reading of batch files
+Added @code{source} command to @code{mysql} to allow reading of batch files
inside the @code{mysql} client. Original patch by Matthew Vanecek.
@item
Fixed critical problem with the @code{WITH GRANT OPTION} option.
@@ -49173,39 +52896,40 @@ Fixed critical problem with the @code{WITH GRANT OPTION} option.
Don't give an unnecessary @code{GRANT} error when using tables from many
databases in the same query.
@item
-Added VIO wrapper (needed for SSL support ; By Andrei Errapart and
+Added VIO wrapper (needed for SSL support; by Andrei Errapart and
Tõnu Samuel).
@item
-Fixed optimizer problem on @code{SELECT} when using many overlapping indexes.
+Fixed optimiser problem on @code{SELECT} when using many overlapping indexes.
MySQL should now be able to choose keys even better when there
is many keys to choose from.
@item
-Changed optimizer to prefer a range key instead of a ref key when the
+Changed optimiser to prefer a range key instead of a ref key when the
range key can uses more columns than the ref key (which only can use
-columns with =). For example, the following type of queries should now
+columns with @code{=}). For example, the following type of queries should now
be faster: @code{SELECT * from key_part_1=const and key_part_2 > const2}
@item
Fixed bug that a change of all @code{VARCHAR} columns to @code{CHAR} columns
didn't change row type from dynamic to fixed.
@item
Disabled floating-point exceptions for FreeBSD to fix core dump when
-doing @code{SELECT floor(pow(2,63))}.
+doing @code{SELECT FLOOR(POW(2,63))}.
@item
-Changed @code{mysqld} startup option @code{--delay-key-write} to
-@code{--delay-key-write-for-all-tables}
+Renamed @code{mysqld} startup option from @code{--delay-key-write} to
+@code{--delay-key-write-for-all-tables}.
@item
Added @code{read-next-on-key} to @code{HEAP} tables. This should fix all
-problems with @code{HEAP} tables when using not @code{UNIQUE} keys.
+problems with @code{HEAP} tables when using non-@code{UNIQUE} keys.
@item
-Added print of default arguments options to all clients.
+Added option to print default arguments to all clients.
@item
-Added @code{--log-slow-queries} to @code{mysqld} to log all queries that take a
-long time to a separate log file with a time of how long the query took.
+Added @code{--log-slow-queries} option to @code{mysqld} to log all queries
+that take a long time to a separate log file with a time indicating how
+long the query took.
@item
-Fixed core dump when doing @code{WHERE key_column=RAND(...)}
+Fixed core dump when doing @code{WHERE key_col=RAND(...)}.
@item
-Fixed optimization bug in @code{SELECT ... LEFT JOIN ... key_column IS NULL},
-when @code{key_column} could contain @code{NULL} values.
+Fixed optimisation bug in @code{SELECT ... LEFT JOIN ... key_col IS NULL},
+when @code{key_col} could contain @code{NULL} values.
@item
Fixed problem with 8-bit characters as separators in @code{LOAD DATA INFILE}.
@end itemize
@@ -49218,9 +52942,9 @@ Fixed problem with 8-bit characters as separators in @code{LOAD DATA INFILE}.
@item
Fixed problem when handling indexfiles larger than 8G.
@item
-Added latest patches to mit-pthreads for NetBSD.
+Added latest patches to MIT-pthreads for NetBSD.
@item
-Fixed problem with timezones that are < GMT -11.
+Fixed problem with timezones that are < GMT - 11.
@item
Fixed a bug when deleting packed keys in @code{NISAM}.
@item
@@ -49230,16 +52954,16 @@ Fixed bug when doing a join on a text key which didn't cover the whole key.
@item
Option @code{--delay-key-write} didn't enable delayed key writing.
@item
-Fixed update of @code{TEXT} column which only involved case changes.
+Fixed update of @code{TEXT} column which involved only case changes.
@item
Fixed that @code{INSERT DELAYED} doesn't update timestamps that are given.
@item
Added function @code{YEARWEEK()} and options @code{x}, @code{X}, @code{v} and
@code{V} to @code{DATE_FORMAT()}.
@item
-Fixed problem with @code{MAX(indexed_column)} and HEAP tables.
+Fixed problem with @code{MAX(indexed_column)} and @code{HEAP} tables.
@item
-Fixed problem with @code{BLOB NULL} keys and @code{LIKE} "prefix%".
+Fixed problem with @code{BLOB NULL} keys and @code{LIKE "prefix%"}.
@item
Fixed problem with @code{MyISAM} and fixed-length rows < 5 bytes.
@item
@@ -49267,12 +52991,12 @@ Fixed a bug in @code{MyISAM} with keys > 250 characters.
In @code{MyISAM} one can now do an @code{INSERT} at the same time as other
threads are reading from the table.
@item
-Added variable @code{max_write_lock_count} to @code{mysqld} to force a
+Added @code{max_write_lock_count} variable to @code{mysqld} to force a
@code{READ} lock after a certain number of @code{WRITE} locks.
@item
-Inverted flag @code{delayed_key_write} on @code{show variables}.
+Inverted flag @code{delay_key_write} on @code{show variables}.
@item
-Renamed variable @code{concurrency} to @code{thread_concurrency}.
+Renamed @code{concurrency} variable to @code{thread_concurrency}.
@item
The following functions are now multi-byte-safe:
@code{LOCATE(substr,str)}, @code{POSITION(substr IN str)},
@@ -49284,7 +53008,7 @@ FROM pos)}, @code{SUBSTRING_INDEX(str,delim,count)}, @code{RTRIM(str)},
@code{TRIM([[BOTH | TRAILING] [remstr] FROM] str)},
@code{REPLACE(str,from_str,to_str)}, @code{REVERSE(str)},
@code{INSERT(str,pos,len,newstr)}, @code{LCASE(str)}, @code{LOWER(str)},
-@code{UCASE(str)} and @code{UPPER(str)}; Patch by Wei He.
+@code{UCASE(str)} and @code{UPPER(str)}; patch by Wei He.
@item
Fix core dump when releasing a lock from a non-existent table.
@item
@@ -49294,14 +53018,14 @@ Added option @code{FULL} to @code{SHOW PROCESSLIST}.
@item
Added option @code{--verbose} to @code{mysqladmin}.
@item
-Fixed problem when automatically converting HEAP to MyISAM.
+Fixed problem when automatically converting @code{HEAP} to @code{MyISAM}.
@item
-Fixed bug in HEAP tables when doing insert + delete + insert + scan the
+Fixed bug in @code{HEAP} tables when doing insert + delete + insert + scan the
table.
@item
Fixed bugs on Alpha with @code{REPLACE()} and @code{LOAD DATA INFILE}.
@item
-Added @code{mysqld} variable @code{interactive_timeout}.
+Added @code{interactive_timeout} variable to @code{mysqld}.
@item
Changed the argument to @code{mysql_data_seek()} from @code{ulong} to
@code{ulonglong}.
@@ -49313,28 +53037,28 @@ Changed the argument to @code{mysql_data_seek()} from @code{ulong} to
@itemize @bullet
@item
-Added @code{mysqld} option @code{-O lower_case_table_names=@{0|1@}} to allow
+Added @code{-O lower_case_table_names=@{0|1@}} option to @code{mysqld} to allow
users to force table names to lowercase.
@item
Added @code{SELECT ... INTO DUMPFILE}.
@item
-Added @code{mysqld} option @code{--ansi} to make some functions @code{ANSI SQL}
-compatible.
+Added @code{--ansi} option to @code{mysqld} to make some functions
+ANSI SQL compatible.
@item
-Temporary tables now starts with @code{#sql}.
+Temporary table names now start with @code{#sql}.
@item
Added quoting of identifiers with @code{`} (@code{"} in @code{--ansi} mode).
@item
-Changed to use snprintf() when printing floats to avoid some buffer
+Changed to use @code{snprintf()} when printing floats to avoid some buffer
overflows on FreeBSD.
@item
-Made @code{[floor()} overflow safe on FreeBSD.
+Made @code{FLOOR()} overflow safe on FreeBSD.
@item
-Added option @code{--quote-names} to @code{mysqldump}
+Added @code{--quote-names} option to @code{mysqldump}.
@item
Fixed bug that one could make a part of a @code{PRIMARY KEY NOT NULL}.
@item
-Fixed @code{encrypt()} to be thread safe and not reuse buffer.
+Fixed @code{encrypt()} to be thread-safe and not reuse buffer.
@item
Added @code{mysql_odbc_escape_string()} function to support big5 characters in
MyODBC.
@@ -49344,11 +53068,11 @@ but will make table handling faster and better.
@item
Added patch by Sasha for user-defined variables.
@item
-Changed that @code{FLOAT} and @code{DOUBLE} (without any length modifiers) are
-not anymore fixed decimal point numbers.
+Changed that @code{FLOAT} and @code{DOUBLE} (without any length modifiers)
+no longer are fixed decimal point numbers.
@item
Changed the meaning of @code{FLOAT(X)}: Now this is the same as @code{FLOAT} if
-X <= 24 and a @code{DOUBLE} if 24 < X <= 53.
+@code{X} <= 24 and a @code{DOUBLE} if 24 < @code{X} <= 53.
@item
@code{DECIMAL(X)} is now an alias for @code{DECIMAL(X,0)} and @code{DECIMAL}
is now an alias for @code{DECIMAL(10,0)}. The same goes for @code{NUMERIC}.
@@ -49373,7 +53097,8 @@ Fixed some Y2K problems in the new date handling in 3.23.
@item
Fixed problem with @code{SELECT DISTINCT ... ORDER BY RAND()}.
@item
-Added patches by Sergei A. Golubchik for text searching on the MyISAM level.
+Added patches by Sergei A. Golubchik for text searching on the @code{MyISAM}
+level.
@item
Fixed cache overflow problem when using full joins without keys.
@item
@@ -49381,16 +53106,17 @@ Fixed some configure issues.
@item
Some small changes to make parsing faster.
@item
-@code{ALTER TABLE} + adding a column after the last field didn't work.
+Adding a column after the last field with @code{ALTER TABLE} didn't work.
@item
-Fixed problem when using an auto_increment column in two keys
+Fixed problem when using an @code{AUTO_INCREMENT} column in two keys
@item
-One can now with MyISAM have the auto_increment part as a sub part:
-@code{CREATE TABLE foo (a int not null auto_increment, b char(5), primary key (b,a))}
+With @code{MyISAM}, you now can have an @code{AUTO_INCREMENT} column as a key
+sub part:
+@code{CREATE TABLE foo (a INT NOT NULL AUTO_INCREMENT, b CHAR(5), PRIMARY KEY (b,a))}
@item
-Fixed bug in MyISAM with packed char keys that could be @code{NULL}.
+Fixed bug in @code{MyISAM} with packed char keys that could be @code{NULL}.
@item
-@code{AS} on fieldname with @code{CREATE TABLE table_name SELECT ...} didn't
+@code{AS} on field name with @code{CREATE TABLE table_name SELECT ...} didn't
work.
@item
Allow use of @code{NATIONAL} and @code{NCHAR} when defining character columns.
@@ -49399,7 +53125,7 @@ This is the same as not using @code{BINARY}.
Don't allow @code{NULL} columns in a @code{PRIMARY KEY} (only in @code{UNIQUE}
keys).
@item
-Clear @code{LAST_INSERT_ID} if one uses this in ODBC:
+Clear @code{LAST_INSERT_ID()} if one uses this in ODBC:
@code{WHERE auto_increment_column IS NULL}. This seems to fix some problems
with Access.
@item
@@ -49407,9 +53133,9 @@ with Access.
searching after the last inserted row with @code{WHERE
auto_increment_column IS NULL}.
@item
-Added new @code{mysqld} variable @code{concurrency} for Solaris.
+Added new variable @code{concurrency} to @code{mysqld} for Solaris.
@item
-Added option @code{--relative} to @code{mysqladmin} to make
+Added @code{--relative} option to @code{mysqladmin} to make
@code{extended-status} more useful to monitor changes.
@item
Fixed bug when using @code{COUNT(DISTINCT ...)} on an empty table.
@@ -49429,7 +53155,7 @@ Fixed problem with @code{UDF} functions.
@itemize @bullet
@item
-Inserting a @code{DATETIME} into a @code{TIME} column will not anymore
+Inserting a @code{DATETIME} into a @code{TIME} column no longer will
try to store 'days' in it.
@item
Fixed problem with storage of float/double on little endian machines.
@@ -49437,13 +53163,13 @@ Fixed problem with storage of float/double on little endian machines.
@item
Added connect timeout on TCP/IP connections.
@item
-Fixed problem with @code{LIKE} "%" on an index that may have @code{NULL} values.
+Fixed problem with @code{LIKE "%"} on an index that may have @code{NULL} values.
@item
@code{REVOKE ALL PRIVILEGES} didn't revoke all privileges.
@item
Allow creation of temporary tables with same name as the original table.
@item
-When granting a user a grant option for a database, he couldn't grant
+When granting a user a @code{GRANT} option for a database, he couldn't grant
privileges to other users.
@item
New command: @code{SHOW GRANTS FOR user} (by Sinisa).
@@ -49455,9 +53181,9 @@ Fixed privilege check for @code{LOAD DATA REPLACE}.
@item
Automatic fixing of broken include files on Solaris 2.7
@item
-Some configure issues to fix problems with big file system detection.
+Some configure issues to fix problems with big filesystem detection.
@item
-@code{REGEXP} is now case insensitive if you use non-binary strings.
+@code{REGEXP} is now case-insensitive if you use non-binary strings.
@end itemize
@@ -49468,13 +53194,13 @@ Some configure issues to fix problems with big file system detection.
@item
Added patches for MIT-pthreads on NetBSD.
@item
-Fixed range bug in MyISAM.
+Fixed range bug in @code{MyISAM}.
@item
@code{ASC} is now the default again for @code{ORDER BY}.
@item
Added @code{LIMIT} to @code{UPDATE}.
@item
-New client function: @code{mysql_change_user()}.
+Added @code{mysql_change_user()} function to the MySQL C API.
@item
Added character set to @code{SHOW VARIABLES}.
@item
@@ -49485,7 +53211,7 @@ an empty value list to insert a row in which each column is set to its
default value.
@item
Changed @code{SUBSTRING(text FROM pos)} to conform to ANSI SQL. (Before this
-construct returned the rightmost 'pos' characters).
+construct returned the rightmost @code{pos} characters.)
@item
@code{SUM()} with @code{GROUP BY} returned 0 on some systems.
@item
@@ -49508,32 +53234,32 @@ New function @code{COALESCE()}.
@itemize @bullet
@item
-Fixed range optimizer bug: @code{SELECT * FROM table_name WHERE
+Fixed range optimiser bug: @code{SELECT * FROM table_name WHERE
key_part1 >= const AND (key_part2 = const OR key_part2 = const)}. The
bug was that some rows could be duplicated in the result.
@item
Running @code{myisamchk} without @code{-a} updated the index
-distribution wrong.
+distribution incorrectly.
@item
-@code{SET SQL_LOW_PRIORITY_UPDATES=1} gave parse error before.
+@code{SET SQL_LOW_PRIORITY_UPDATES=1} was causing a parse error.
@item
-You can now update indexes columns that are used in the @code{WHERE} clause.
+You can now update index columns that are used in the @code{WHERE} clause.
@code{UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100}
@item
Date handling should now be a bit faster.
@item
-Added handling of fuzzy dates (dates where day or month is 0):
-(Like: 1999-01-00)
+Added handling of fuzzy dates (dates where day or month is 0), such as
+@code{'1999-01-00'}.
@item
-Fixed optimization of @code{SELECT ... WHERE key_part1=const1 AND
-key_part_2=const2 AND key_part1=const4 AND key_part2=const4} ; Indextype
+Fixed optimisation of @code{SELECT ... WHERE key_part1=const1 AND
+key_part_2=const2 AND key_part1=const4 AND key_part2=const4}; indextype
should be @code{range} instead of @code{ref}.
@item
-Fixed @code{egcs} 1.1.2 optimizer bug (when using @code{BLOB}s) on Linux Alpha.
+Fixed @code{egcs} 1.1.2 optimiser bug (when using @code{BLOB}s) on Linux Alpha.
@item
Fixed problem with @code{LOCK TABLES} combined with @code{DELETE FROM table}.
@item
-MyISAM tables now allow keys on @code{NULL} and @code{BLOB/TEXT} columns.
+@code{MyISAM} tables now allow keys on @code{NULL} and @code{BLOB/TEXT} columns.
@item
The following join is now much faster:
@code{SELECT ... FROM t1 LEFT JOIN t2 ON ... WHERE t2.not_null_column IS NULL}.
@@ -49544,20 +53270,20 @@ Changed handling of 'const_item' to allow handling of @code{ORDER BY RAND()}.
@item
Indexes are now used for @code{WHERE key_column = function}.
@item
-Indexes are now used for @code{WHERE key_column = column_name} even if
+Indexes are now used for @code{WHERE key_column = col_name} even if
the columns are not identically packed.
@item
-Indexes are now used for @code{WHERE column_name IS NULL}.
+Indexes are now used for @code{WHERE col_name IS NULL}.
@item
Changed heap tables to be stored in low_byte_first order (to make it easy
-to convert to MyISAM tables)
+to convert to @code{MyISAM} tables)
@item
-Automatic change of HEAP temporary tables to MyISAM tables in case of
-'table is full' errors.
+Automatic change of @code{HEAP} temporary tables to @code{MyISAM} tables
+in case of 'table is full' errors.
@item
-Added option @code{--init-file=file_name} to @code{mysqld}.
+Added @code{--init-file=file_name} option to @code{mysqld}.
@item
-@code{COUNT(DISTINCT value, [value, ...])}
+Added @code{COUNT(DISTINCT value, [value, ...])}.
@item
@code{CREATE TEMPORARY TABLE} now creates a temporary table, in its own
namespace, that is automatically deleted if connection is dropped.
@@ -49580,17 +53306,17 @@ Fixed some compilation problems.
@node News-3.23.0, , News-3.23.1, News-3.23.x
-@appendixsubsec Changes in release 3.23.0
+@appendixsubsec Changes in release 3.23.0 (Sep 1999: Alpha)
@itemize @bullet
@item
A new table handler library (@code{MyISAM}) with a lot of new features.
-@xref{MyISAM}.
+@xref{MyISAM, , @code{MyISAM}}.
@item
You can create in-memory @code{HEAP} tables which are extremely fast for
lookups.
@item
-Support for big files (63 bit) on OSes that support big files.
+Support for big files (63-bit) on OSes that support big files.
@item
New function @code{LOAD_FILE(filename)} to get the contents of a file as a
string value.
@@ -49601,22 +53327,22 @@ between tables.
@item
Added the ODBC 3.0 @code{EXTRACT(interval FROM datetime)} function.
@item
-Columns defined as @code{FLOAT(X)} is not rounded on storage and may be
+Columns defined as @code{FLOAT(X)} are not rounded on storage and may be
in scientific notation (1.0 E+10) when retrieved.
@item
@code{REPLACE} is now faster than before.
@item
Changed @code{LIKE} character comparison to behave as @code{=};
-This means that @code{'e' LIKE '@'e'} (if the line doesn't display
-correctly, the latter 'e' means a French 'e' with a dot above) is now true.
+This means that @code{'e' LIKE '@'e'} is now true. (If the line doesn't
+display correctly, the latter 'e' is a French 'e' with a dot above.)
@item
@code{SHOW TABLE STATUS} returns a lot of information about the tables.
@item
Added @code{LIKE} to the @code{SHOW STATUS} command.
@item
-Added privilege column to @code{SHOW COLUMNS}.
+Added @code{Privileges} column to @code{SHOW COLUMNS}.
@item
-Added columns @code{packed} and @code{comment} to @code{SHOW INDEX}.
+Added @code{Packed} and @code{Comment} columns to @code{SHOW INDEX}.
@item
Added comments to tables (with @code{CREATE TABLE ... COMMENT "xxx"}).
@item
@@ -49636,28 +53362,29 @@ Allow creation of @code{CHAR(0)} columns.
An example procedure is added: @code{analyse}, file: @file{sql_analyse.c}.
This will describe the data in your query. Try the following:
@example
-SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
+SELECT ... FROM ...
+WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
@end example
This procedure is extremely useful when you want to check the data in your
table!
@item
-@code{BINARY} cast to force a string to be compared case sensitively.
+@code{BINARY} cast to force a string to be compared in case-sensitive fashion.
@item
-Added option @code{--skip-show-database} to @code{mysqld}.
+Added @code{--skip-show-database} option to @code{mysqld}.
@item
-Check if a row has changed in an @code{UPDATE} now also works with
-@code{BLOB}/@code{TEXT} columns.
+Check whether a row has changed in an @code{UPDATE} now also works
+with @code{BLOB}/@code{TEXT} columns.
@item
Added the @code{INNER} join syntax. @strong{NOTE}: This made @code{INNER}
a reserved word!
@item
-Added support for netmasks to the hostname in the MySQL tables.
+Added support for netmasks to the hostname in the MySQL grant tables.
You can specify a netmask using the @code{IP/NETMASK} syntax.
@item
If you compare a @code{NOT NULL DATE/DATETIME} column with @code{IS
NULL}, this is changed to a compare against @code{0} to satisfy some ODBC
-applications. (By @email{shreeve@@uci.edu}).
+applications. (By @email{shreeve@@uci.edu}.)
@item
@code{NULL IN (...)} now returns @code{NULL} instead of @code{0}. This will
ensure that @code{null_column NOT IN (...)} doesn't match
@@ -49668,16 +53395,17 @@ Fix storage of floating-point values in @code{TIME} columns.
Changed parsing of @code{TIME} strings to be more strict. Now the
fractional second part is detected (and currently skipped). The
following formats are supported:
-@table @code
+@itemize
@item [[DAYS] [H]H:]MM:]SS[.fraction]
@item [[[[[H]H]H]H]MM]SS[.fraction]
-@end table
+@end itemize
@item
-Detect (and ignore) second fraction part from @code{DATETIME}.
+Detect (and ignore) fractional second part from @code{DATETIME}.
@item
Added the @code{LOW_PRIORITY} attribute to @code{LOAD DATA INFILE}.
@item
-The default index name now uses the same case as the used column name.
+The default index name now uses the same case as the column name on which the
+index name is based.
@item
Changed default number of connections to 100.
@item
@@ -49686,13 +53414,13 @@ Use bigger buffers when using @code{LOAD DATA INFILE}.
@code{DECIMAL(x,y)} now works according to ANSI SQL.
@item
Added aggregate UDF functions. Thanks to Andreas F. Bobak
-@email{bobak@@relog.ch} for this!
+(@email{bobak@@relog.ch}) for this!
@item
@code{LAST_INSERT_ID()} is now updated for @code{INSERT INTO ... SELECT}.
@item
-Some small changes to the join table optimizer to make some joins faster.
+Some small changes to the join table optimiser to make some joins faster.
@item
-@code{SELECT DISTINCT} is much faster; It uses the new @code{UNIQUE}
+@code{SELECT DISTINCT} is much faster; it uses the new @code{UNIQUE}
functionality in @code{MyISAM}. One difference compared to MySQL Version 3.22
is that the output of @code{DISTINCT} is not sorted anymore.
@item
@@ -49700,40 +53428,40 @@ All C client API macros are now functions to make shared libraries more
reliable. Because of this, you can no longer call @code{mysql_num_fields()} on
a @code{MYSQL} object, you must use @code{mysql_field_count()} instead.
@item
-Added use of @code{LIBWRAP}; Patch by Henning P . Schmiedehausen.
+Added use of @code{LIBWRAP}; patch by Henning P. Schmiedehausen.
@item
Don't allow @code{AUTO_INCREMENT} for other than numerical columns.
@item
Using @code{AUTO_INCREMENT} will now automatically make the column
@code{NOT NULL}.
@item
-Show @code{NULL} as the default value for AUTO_INCREMENT columns.
+Show @code{NULL} as the default value for @code{AUTO_INCREMENT} columns.
@item
-Added @code{SQL_BIG_RESULT}; @code{SQL_SMALL_RESULT} is now default.
+Added @code{SQL_BIG_RESULT}; @code{SQL_SMALL_RESULT} is now default.
@item
Added a shared library RPM. This enhancement was contributed by David
-Fox (dsfox@@cogsci.ucsd.edu).
+Fox (@email{dsfox@@cogsci.ucsd.edu}).
@item
-Added a @code{--enable-large-files/--disable-large-files} switch to
-@code{configure}. See @file{configure.in} for some systems where this is
+Added @code{--enable-large-files} and @code{--disable-large-files} switches
+to @code{configure}. See @file{configure.in} for some systems where this is
automatically turned off because of broken implementations.
@item
Upgraded @code{readline} to 4.0.
@item
New @code{CREATE TABLE} options: @code{PACK_KEYS} and @code{CHECKSUM}.
@item
-Added @code{mysqld} option @code{--default-table-type}.
+Added @code{--default-table-type} option to @code{mysqld}.
@end itemize
@node News-3.22.x, News-3.21.x, News-3.23.x, News
-@appendixsec Changes in release 3.22.x (Older; Still supported)
+@appendixsec Changes in release 3.22.x (Older; still supported)
@cindex changes, version 3.22
The 3.22 version has faster and safer connect code than version 3.21, as well
-as a lot of new nice enhancements. The reason for not including these changes
-As there aren't really any MAJOR changes, upgrading from 3.21 to 3.22 should
+as a lot of new nice enhancements.
+As there aren't really any major changes, upgrading from 3.21 to 3.22 should
be very easy and painless. @xref{Upgrading-from-3.21}.
@menu
@@ -49753,10 +53481,10 @@ be very easy and painless. @xref{Upgrading-from-3.21}.
* News-3.22.22:: Changes in release 3.22.22
* News-3.22.21:: Changes in release 3.22.21
* News-3.22.20:: Changes in release 3.22.20
-* News-3.22.19:: Changes in release 3.22.19
+* News-3.22.19:: Changes in release 3.22.19 (Mar 1999: Stable)
* News-3.22.18:: Changes in release 3.22.18
* News-3.22.17:: Changes in release 3.22.17
-* News-3.22.16:: Changes in release 3.22.16
+* News-3.22.16:: Changes in release 3.22.16 (Feb 1999: Gamma)
* News-3.22.15:: Changes in release 3.22.15
* News-3.22.14:: Changes in release 3.22.14
* News-3.22.13:: Changes in release 3.22.13
@@ -49765,13 +53493,13 @@ be very easy and painless. @xref{Upgrading-from-3.21}.
* News-3.22.10:: Changes in release 3.22.10
* News-3.22.9:: Changes in release 3.22.9
* News-3.22.8:: Changes in release 3.22.8
-* News-3.22.7:: Changes in release 3.22.7
+* News-3.22.7:: Changes in release 3.22.7 (Sep 1998: Beta)
* News-3.22.6:: Changes in release 3.22.6
* News-3.22.5:: Changes in release 3.22.5
* News-3.22.4:: Changes in release 3.22.4
* News-3.22.3:: Changes in release 3.22.3
* News-3.22.2:: Changes in release 3.22.2
-* News-3.22.1:: Changes in release 3.22.1
+* News-3.22.1:: Changes in release 3.22.1 (Jun 1998: Alpha)
* News-3.22.0:: Changes in release 3.22.0
@end menu
@@ -49797,7 +53525,7 @@ on a table with only one row.
@itemize @bullet
@item
-Fixed problem with @code{GROUP BY} on @code{TINYBLOB} columns; This
+Fixed problem with @code{GROUP BY} on @code{TINYBLOB} columns; this
caused bugzilla to not show rows in some queries.
@item
Had to do total recompile of the Windows binary version as VC++ didn't
@@ -49810,7 +53538,7 @@ compile all relevant files for 3.22.33 :(
@itemize @bullet
@item
-Fixed problems in Windows when locking tables with @code{LOCK TABLE}
+Fixed problems in Windows when locking tables with @code{LOCK TABLE}.
@item
Quicker kill of @code{SELECT DISTINCT} queries.
@end itemize
@@ -49825,7 +53553,7 @@ Fixed problem when storing numbers in timestamps.
@item
Fix problem with timezones that have half hour offsets.
@item
-@code{mysqlhotcopy} - fast on-line hot-backup utility for local MySQL
+Added @code{mysqlhotcopy}, a fast online hot-backup utility for local MySQL
databases. By Tim Bunce.
@item
New more secure @code{mysqlaccess}. Thanks to Steve Harvey for this.
@@ -49853,10 +53581,10 @@ A few small fixes for the Windows version.
@itemize @bullet
@item
-Fixed optimizer problem on @code{SELECT} when using many overlapping indexes.
+Fixed optimiser problem on @code{SELECT} when using many overlapping indexes.
@item
Disabled floating-point exceptions for FreeBSD to fix core dump when
-doing @code{SELECT floor(pow(2,63))}.
+doing @code{SELECT FLOOR(POW(2,63))}.
@item
Added print of default arguments options to all clients.
@item
@@ -49874,7 +53602,7 @@ Fixed non-critical Y2K problem when writing short date to log files.
Upgraded the configure and include files to match the latest 3.23 version.
This should increase portability and make it easier to build shared libraries.
@item
-Added latest patches to mit-pthreads for NetBSD.
+Added latest patches to MIT-pthreads for NetBSD.
@item
Fixed problem with timezones that are < GMT -11.
@item
@@ -49916,9 +53644,9 @@ Fixed problem with @code{AVG()} and @code{STD()} with @code{NULL} values.
@item
Fixed prototype in @file{my_ctype.h} when using other character sets.
@item
-Some configure issues to fix problems with big file system detection.
+Some configure issues to fix problems with big filesystem detection.
@item
-Fixed problem when sorting on big blob columns.
+Fixed problem when sorting on big @code{BLOB} columns.
@item
@code{ROUND()} will now work on Windows.
@end itemize
@@ -49929,26 +53657,28 @@ Fixed problem when sorting on big blob columns.
@itemize @bullet
@item
-Fixed core dump with empty @code{BLOB/TEXT} column to @code{REVERSE()}.
+Fixed core dump with empty @code{BLOB/TEXT} column argument to
+@code{REVERSE()}.
@item
Extended @code{/*! */} with version numbers.
@item
Changed @code{SUBSTRING(text FROM pos)} to conform to ANSI SQL. (Before this
-construct returned the rightmost 'pos' characters).
+construct returned the rightmost 'pos' characters.)
@item
Fixed problem with @code{LOCK TABLES} combined with @code{DELETE FROM table}
@item
-Fixed problem that INSERT ... SELECT didn't use SQL_BIG_TABLES.
+Fixed problem that @code{INSERT ... SELECT} didn't use @code{BIG_TABLES}.
@item
@code{SET SQL_LOW_PRIORITY_UPDATES=#} didn't work.
@item
Password wasn't updated correctly if privileges didn't change on:
@code{GRANT ... IDENTIFIED BY}
@item
-Fixed range optimizer bug in
-@code{SELECT * FROM table_name WHERE key_part1 >= const AND (key_part2 = const OR key_part2 = const)}
+Fixed range optimiser bug in
+@code{SELECT * FROM table_name WHERE key_part1 >= const AND (key_part2 = const
+OR key_part2 = const)}.
@item
-Fixed bug in compression key handling in ISAM.
+Fixed bug in compression key handling in @code{ISAM}.
@end itemize
@@ -49968,7 +53698,7 @@ Fixed some small problems with the installation.
@item
@code{DATA} is not a reserved word anymore.
@item
-Fixed optimizer bug with tables with only one row.
+Fixed optimiser bug with tables with only one row.
@item
Fixed bug when using @code{LOCK TABLES table_name READ; FLUSH TABLES;}
@item
@@ -50045,7 +53775,7 @@ another thread.
@item
Fixed bug in @code{LEFT JOIN} involving empty tables.
@item
-Changed the @code{mysql.db} column from @code{char(32)} to @code{char(60)}.
+Changed the @code{mysql.db} column from @code{CHAR(32)} to @code{CHAR(60)}.
@item
@code{MODIFY} and @code{DELAYED} are not reserved words anymore.
@item
@@ -50055,7 +53785,7 @@ Fixed a problem with @code{Host '...' is not allowed to connect to this MySQL
server} after one had inserted a new MySQL user with a @code{GRANT}
command.
@item
-Changed to use @code{TCP_NODELAY} also on Linux (Should give faster TCP/IP
+Changed to use @code{TCP_NODELAY} also on Linux (should give faster TCP/IP
connections).
@end itemize
@@ -50074,7 +53804,7 @@ The update log didn't have newlines on some operating systems.
@node News-3.22.19, News-3.22.18, News-3.22.20, News-3.22.x
-@appendixsubsec Changes in release 3.22.19
+@appendixsubsec Changes in release 3.22.19 (Mar 1999: Stable)
@itemize @bullet
@item
@@ -50092,8 +53822,8 @@ columns.
@itemize @bullet
@item
-Fixes a fatal problem in 3.22.17 on Linux; After @code{shutdown}
-all threads didn't die properly.
+Fixes a fatal problem in 3.22.17 on Linux; after @code{shutdown}
+not all threads died properly.
@item
Added option @code{-O flush_time=#} to @code{mysqld}. This is mostly
useful on Windows and tells how often MySQL should close all
@@ -50120,7 +53850,7 @@ Using @code{LEFT JOIN} on tables that had circular dependencies caused
@node News-3.22.16, News-3.22.15, News-3.22.17, News-3.22.x
-@appendixsubsec Changes in release 3.22.16
+@appendixsubsec Changes in release 3.22.16 (Feb 1999: Gamma)
@itemize @bullet
@item
@@ -50136,7 +53866,7 @@ rows. Fixed.
Extended @code{ENCRYPT()} to take longer salt strings than 2 characters.
@item
@code{longlong2str} is now much faster than before. For @code{Intel x86}
-platforms, this function is written in optimized assembler.
+platforms, this function is written in optimised assembler.
@item
Added the @code{MODIFY} keyword to @code{ALTER TABLE}.
@end itemize
@@ -50152,7 +53882,7 @@ were flushed.
@item
Name change of some variables in @code{SHOW STATUS}.
@item
-Fixed problem with @code{ORDER BY} with 'only index' optimization when there
+Fixed problem with @code{ORDER BY} with 'only index' optimisation when there
were multiple key definitions for a used column.
@item
@code{DATE} and @code{DATETIME} columns are now up to 5 times faster than
@@ -50201,7 +53931,7 @@ Added a patch for @code{localtime_r()} on Windows so that it will not crash
anymore if your date is > 2039, but instead will return a time of all zero.
@item
Names for
-user-defined functions are no longer case sensitive.
+user-defined functions are no longer case-sensitive.
@item
Added escape of @code{^Z} (ASCII 26) to @code{\Z} as @code{^Z} doesn't
work with pipes on Windows.
@@ -50272,19 +54002,20 @@ Fix for @code{isamchk} for tables which need big temporary files.
@itemize @bullet
@item
-@strong{IMPORTANT}: You must run the @code{mysql_fix_privilege_tables} script
+@strong{Important}: You must run the @code{mysql_fix_privilege_tables} script
when you upgrade to this version! This is needed because of the new
@code{GRANT} system. If you don't do this, you will get @code{Access
-denied} when you try to use @code{ALTER TABLE}, @code{CREATE INDEX} or
+denied} when you try to use @code{ALTER TABLE}, @code{CREATE INDEX}, or
@code{DROP INDEX}.
@item
@code{GRANT} to allow/deny users table and column access.
@item
-Changed @code{USER()} to return @code{user@@host}
+Changed @code{USER()} to return a value in @code{user@@host} format.
+Formerly it returned only @code{user}.
@item
Changed the syntax for how to set @code{PASSWORD} for another user.
@item
-New command @code{FLUSH STATUS} that sets most status variables to zero.
+New command @code{FLUSH STATUS} that resets most status variables to zero.
@item
New status variables: @code{aborted_threads}, @code{aborted_connects}.
@item
@@ -50333,7 +54064,7 @@ Changed @code{+}, @code{-} (sign and minus), @code{*}, @code{/}, @code{%},
Fixed a bug in @code{ALTER TABLE} that caused @code{mysqld} to crash.
@item
MySQL now always reports the conflicting key values when a
-duplicate key entry occurs. (Before this was only reported for @code{INSERT}).
+duplicate key entry occurs. (Before this was only reported for @code{INSERT}.)
@item
New syntax: @code{INSERT INTO tbl_name SET col_name=value, col_name=value, ...}
@item
@@ -50352,12 +54083,12 @@ Added @code{maybe_null} to the UDF structure.
@item
Added option @code{IGNORE} to @code{INSERT} statements with many rows.
@item
-Fixed some problems with sorting of the koi8 character sets; Users of koi8
-@strong{MUST} run @code{isamchk -rq} on each table that has an index on
-a @code{CHAR} or @code{VARCHAR} column.
+Fixed some problems with sorting of the @code{koi8} character sets; users of
+@code{koi8} @strong{must} run @code{isamchk -rq} on each table that has an
+index on a @code{CHAR} or @code{VARCHAR} column.
@item
-New script @code{mysql_setpermission}, by Luuk de Boer, allows one
-to easily create new users with permissions for specific databases.
+New script @code{mysql_setpermission}, by Luuk de Boer. It allows easy
+creation of new users with permissions for specific databases.
@item
Allow use of hexadecimal strings (0x...) when specifying a constant string
(like in the column separators with @code{LOAD DATA INFILE}).
@@ -50384,16 +54115,16 @@ New SQL command: @code{FLUSH [ TABLES | HOSTS | LOGS | PRIVILEGES ] [, ...]}
New SQL command: @code{KILL} @code{thread_id}.
@item
Added casts and changed include files to make MySQL easier to
-compile on AIX and DEC OSF1 4.x
+compile on AIX and DEC OSF/1 4.x
@item
Fixed conversion problem when using @code{ALTER TABLE} from a @code{INT}
to a short @code{CHAR()} column.
@item
-Added @code{SELECT HIGH_PRIORITY}; This will get a lock for the
+Added @code{SELECT HIGH_PRIORITY}; this will get a lock for the
@code{SELECT} even if there is a thread waiting for another
@code{SELECT} to get a @code{WRITE LOCK}.
@item
-Moved wild_compare to string class to be able to use @code{LIKE} on
+Moved @code{wild_compare()} to string class to be able to use @code{LIKE} on
@code{BLOB}/@code{TEXT} columns with @code{\0}.
@item
Added @code{ESCAPE} option to @code{LIKE}.
@@ -50402,7 +54133,7 @@ Added a lot more output to @code{mysqladmin debug}.
@item
You can now start @code{mysqld} on Windows with the @code{--flush} option.
This will flush all tables to disk after each update. This makes things
-much safer on NT/Win98 but also @strong{MUCH} slower.
+much safer on the Windows platforms but also @strong{much} slower.
@end itemize
@@ -50413,10 +54144,10 @@ much safer on NT/Win98 but also @strong{MUCH} slower.
@item
Czech character sets should now work much better. You must also install
@uref{http://www.mysql.com/Downloads/Patches/czech-3.22.8-patch}.
-This patch should also be installed if you are using a character set with
-uses @code{my_strcoll()}! The patch should always be safe to install (for any system),
-but as this patch changes ISAM internals it's not yet in the default
-distribution.
+This patch should also be installed if you are using a character set which
+uses @code{my_strcoll()}! The patch should always be safe to install (for any
+system), but as this patch changes @code{ISAM} internals it's not yet in the
+default distribution.
@item
@code{DATE_ADD()} and @code{DATE_SUB()} didn't work with group functions.
@item
@@ -50448,7 +54179,7 @@ Added patches for UNIXWARE 7.
@node News-3.22.7, News-3.22.6, News-3.22.8, News-3.22.x
-@appendixsubsec Changes in release 3.22.7
+@appendixsubsec Changes in release 3.22.7 (Sep 1998: Beta)
@itemize @bullet
@item
@@ -50469,12 +54200,13 @@ Upgraded @code{libtool} to get the configure more portable.
Fixed slow @code{UPDATE} and @code{DELETE} operations when using
@code{DATETIME} or @code{DATE} keys.
@item
-Changed optimizer to make it better at deciding when to do a full join
+Changed optimiser to make it better at deciding when to do a full join
and when using keys.
@item
You can now use @code{mysqladmin proc} to display information about your own
-threads. Only users with the @strong{Process_priv} privilege can get
+threads. Only users with the @code{PROCESS} privilege can get
information about all threads.
+(In 4.0.2 one needs the @code{SUPER} privilege for this.)
@item
Added handling of formats @code{YYMMDD}, @code{YYYYMMDD},
@code{YYMMDDHHMMSS} for numbers when using @code{DATETIME} and
@@ -50489,7 +54221,7 @@ and INSERT_ID's in the update log.
@item
Added @code{--where} option to @code{mysqldump} (patch by Jim Faucette).
@item
-The lexical analyzer now uses ``perfect hashing'' for faster parsing of SQL
+The lexical analyser now uses ``perfect hashing'' for faster parsing of SQL
statements.
@end itemize
@@ -50505,7 +54237,7 @@ For the @code{LOAD DATA INFILE} statement, you can now use the new @code{LOCAL}
keyword to read the file from the client. @code{mysqlimport} will
automatically use @code{LOCAL} when importing with the TCP/IP protocol.
@item
-Fixed small optimize problem when updating keys.
+Fixed small optimise problem when updating keys.
@item
Changed makefiles to support shared libraries.
@item
@@ -50555,7 +54287,7 @@ New better compressed server/client protocol.
You can now store values in the range @code{-838:59:59} <= x <=
@code{838:59:59} in a @code{TIME} column.
@item
-@strong{WARNING: INCOMPATIBLE CHANGE!!}
+@strong{Warning: incompatible change!!}
If you set a @code{TIME} column to too short a value, MySQL now
assumes the value is given as: @code{[[[D ]HH:]MM:]SS} instead of
@code{HH[:MM[:SS]]}.
@@ -50564,13 +54296,13 @@ assumes the value is given as: @code{[[[D ]HH:]MM:]SS} instead of
and hours up to 32767.
@item
Added new option
-@code{SET OPTION SQL_LOG_UPDATE=@{0|1@}} to allow users with
-the @strong{process} privilege to bypass the update log.
+@code{SET SQL_LOG_UPDATE=@{0|1@}} to allow users with
+the @code{PROCESS} privilege to bypass the update log.
(Modified patch from Sergey A Mukhin @email{violet@@rosnet.net}.)
@item
Fixed fatal bug in @code{LPAD()}.
@item
-Initialize line buffer in @file{mysql.cc} to make @code{BLOB} reading from
+Initialise line buffer in @file{mysql.cc} to make @code{BLOB} reading from
pipes safer.
@item
Added @code{-O max_connect_errors=#} option to @code{mysqld}.
@@ -50583,7 +54315,7 @@ Added @code{--low-priority-updates} option to @code{mysqld}, to give
table-modifying operations (@code{INSERT}, @code{REPLACE}, @code{UPDATE},
@code{DELETE}) lower priority than retrievals. You can now use
@code{@{INSERT | REPLACE | UPDATE | DELETE@} LOW_PRIORITY ...} You can
-also use @code{SET OPTION SQL_LOW_PRIORITY_UPDATES=@{0|1@}} to change
+also use @code{SET SQL_LOW_PRIORITY_UPDATES=@{0|1@}} to change
the priority for one thread. One side effect is that @code{LOW_PRIORITY}
is now a reserved word. :(
@item
@@ -50605,13 +54337,13 @@ trailing @samp{;}.
@item
Fix for corrupted fixed-format output generated by @code{SELECT INTO OUTFILE}.
@item
-@strong{WARNING: INCOMPATIBLE CHANGE!!}
+@strong{Warning: incompatible change!}
Added Oracle @code{GREATEST()} and @code{LEAST()} functions. You must now use
these instead of the @code{MAX()} and @code{MIN()} functions to get the
largest/smallest value from a list of values. These can now handle @code{REAL},
@code{BIGINT} and string (@code{CHAR} or @code{VARCHAR}) values.
@item
-@strong{WARNING: INCOMPATIBLE CHANGE!!}
+@strong{Warning: incompatible change!}
@code{DAYOFWEEK()} had offset 0 for Sunday. Changed the offset to 1.
@item
Give an error for queries that mix @code{GROUP BY} columns and fields when
@@ -50620,7 +54352,7 @@ there is no @code{GROUP BY} specification.
Added @code{--vertical} option to @code{mysql}, for printing results in
vertical mode.
@item
-Index-only optimization; some queries are now resolved using
+Index-only optimisation; some queries are now resolved using
only indexes. Until MySQL 4.0, this works only for numeric columns.
@xref{MySQL indexes, , MySQL indexes}.
@item
@@ -50661,12 +54393,12 @@ Added function @code{SUBSTRING()} with 2 arguments.
If you created a table with a record length smaller than 5, you couldn't
delete rows from the table.
@item
-Added optimization to remove const reference tables from @code{ORDER BY} and
+Added optimisation to remove const reference tables from @code{ORDER BY} and
@code{GROUP BY}.
@item
@code{mysqld} now automatically disables system locking on Linux and Windows,
and for systems that use MIT-pthreads. You can force the use of locking
-with the @code{--enable-locking} option.
+with the @code{--enable-external-locking} option.
@item
Added @code{--console} option to @code{mysqld}, to force a console window
(for error messages) when using Windows.
@@ -50719,7 +54451,7 @@ a chroot environment (by Nikki Chumakov @email{nikkic@@cityline.ru}).
Trailing spaces are now ignored when comparing case-sensitive strings;
this should fix some problems with ODBC and flag 512!
@item
-Fixed a core-dump bug in the range optimizer.
+Fixed a core dump bug in the range optimiser.
@item
Added @code{--one-thread} option to @code{mysqld}, for debugging with
LinuxThreads (or @code{glibc}). (This replaces the @code{-T32} flag)
@@ -50741,7 +54473,7 @@ All bug fixes from MySQL Version 3.21.32.
@node News-3.22.1, News-3.22.0, News-3.22.2, News-3.22.x
-@appendixsubsec Changes in release 3.22.1
+@appendixsubsec Changes in release 3.22.1 (Jun 1998: Alpha)
@itemize @bullet
@item
@@ -50776,7 +54508,7 @@ matched and updated, and how many ``warnings'' occurred when doing the update.
Fixed incorrect result from @code{FORMAT(-100,2)}.
@item
@code{ENUM} and @code{SET} columns were compared in binary (case-sensitive)
-fashion; changed to be case insensitive.
+fashion; changed to be case-insensitive.
@end itemize
@@ -50785,7 +54517,7 @@ fashion; changed to be case insensitive.
@itemize @bullet
@item
-New (backward compatible) connect protocol that allows you to
+New (backward-compatible) connect protocol that allows you to
specify the database to use when connecting, to get much faster
connections to a specific database.
@@ -50801,7 +54533,7 @@ Each connection is handled by its own thread, rather than by the
master @code{accept()} thread. This fixes permanently the telnet bug
that was a topic on the mail list some time ago.
@item
-All TCP/IP connections are now checked with backward resolution of
+All TCP/IP connections are now checked with backward-resolution of
the hostname to get better security. @code{mysqld} now has a local hostname
resolver cache so connections should actually be faster than before,
even with this feature.
@@ -50840,7 +54572,7 @@ Re-arranged @code{SELECT} code to handle some very specific queries
involving group functions (like @code{COUNT(*)}) without a @code{GROUP BY} but
with @code{HAVING}. The following now works:
@example
-mysql> SELECT count(*) as C FROM table HAVING C > 1;
+mysql> SELECT COUNT(*) as C FROM table HAVING C > 1;
@end example
@item
Changed the protocol for field functions to be faster and avoid some
@@ -50850,15 +54582,15 @@ Added @code{-T32} option to @code{mysqld}, for running all queries under the
main thread. This makes it possible to debug @code{mysqld} under Linux with
@code{gdb}!
@item
-Added optimization of @code{not_null_column IS NULL} (needed for some Access
+Added optimisation of @code{not_null_column IS NULL} (needed for some Access
queries).
@item
-Allow @code{STRAIGHT_JOIN} to be used between two tables to force the optimizer
+Allow @code{STRAIGHT_JOIN} to be used between two tables to force the optimiser
to join them in a specific order.
@item
String functions now return @code{VARCHAR} rather than @code{CHAR} and
the column type is now @code{VARCHAR} for fields saved as @code{VARCHAR}.
-This should make the @strong{MyODBC} driver better, but may break some old
+This should make the @code{MyODBC} driver better, but may break some old
MySQL clients that don't handle @code{FIELD_TYPE_VARCHAR} the same
way as @code{FIELD_TYPE_CHAR}.
@item
@@ -50967,7 +54699,7 @@ index file and cause error 126 or 138.
@item
Fixed fatal bug in @code{refresh()} when running with the
-@code{--skip-locking} option. There was a ``very small'' time gap after
+@code{--skip-external-locking} option. There was a ``very small'' time gap after
a @code{mysqladmin refresh} when a table could be corrupted if one
thread updated a table while another thread did @code{mysqladmin
refresh} and another thread started a new update ont the same table
@@ -50981,7 +54713,7 @@ returned a row in some contexts (bug only in 3.21.31).
@code{GROUP BY} + @code{ORDER BY} returned one empty row when no rows where
found.
@item
-Fixed a bug in the range optimizer that wrote
+Fixed a bug in the range optimiser that wrote
@code{Use_count: Wrong count for ...} in the error log file.
@end itemize
@@ -51013,7 +54745,7 @@ it more easily in the future.
@item
@code{mysql} now returns an exit code > 0 if the query returned an error.
@item
-Saving of command line history to file in @code{mysql} client.
+Saving of command-line history to file in @code{mysql} client.
By Tommy Larsen @email{tommy@@mix.hive.no}.
@item
Fixed problem with empty lines that were ignored in @file{mysql.cc}.
@@ -51041,8 +54773,8 @@ columns.
Sorting on a function which made a division / 0 produced a wrong set
in some cases.
@item
-Fixed @code{SELECT} problem with @code{LEFT()} when using the czech character
-set.
+Fixed @code{SELECT} problem with @code{LEFT()} when using the @code{czech}
+character set.
@item
Fixed problem in @code{isamchk}; it couldn't repair a packed table in a very
unusual case.
@@ -51068,12 +54800,12 @@ Fixed permission problem with @code{umask()} and creating new databases.
@item
Fixed permission problem on result file with @code{SELECT ... INTO OUTFILE ...}
@item
-Fixed problem in range optimizer (core dump) for a very complex query.
+Fixed problem in range optimiser (core dump) for a very complex query.
@item
Fixed problem when using @code{MIN(integer)} or @code{MAX(integer)} in
@code{GROUP BY}.
@item
-Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha).
+Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha.)
@item
Fixed bug in @code{WEEK("XXXX-xx-01")}.
@end itemize
@@ -51099,19 +54831,19 @@ Fixed bug in record caches; for some queries, you could get
Added user level lock functions @code{GET_LOCK(string,timeout)},
@code{RELEASE_LOCK(string)}.
@item
-Added @code{opened_tables} to @code{show status}.
+Added @code{Opened_tables} to @code{show status}.
@item
Changed connect timeout to 3 seconds to make it somewhat harder
for crackers to kill @code{mysqld} through telnet + TCP/IP.
@item
-Fixed bug in range optimizer when using
+Fixed bug in range optimiser when using
@code{WHERE key_part_1 >= something AND key_part_2 <= something_else}.
@item
Changed @code{configure} for detection of FreeBSD 3.0 9803xx and above
@item
-@code{WHERE} with string_column_key = constant_string didn't always find
-all rows if the column had many values differing only with characters of
-the same sort value (like e and @'e).
+@code{WHERE} with @code{string_col_key = constant_string} didn't always
+find all rows if the column had many values differing only with
+characters of the same sort value (like e and @'e).
@item
Strings keys looked up with 'ref' were not compared in case-sensitive fashion.
@item
@@ -51143,10 +54875,10 @@ An @code{ENUM} field that is not declared @code{NOT NULL} has @code{NULL} as
the default value.
(Previously, the default value was the first enumeration value.)
@item
-Fixed bug in the join optimizer code when using many part keys
-on the same key: @code{INDEX (Organization,Surname(35),Initials(35))}.
+Fixed bug in the join optimiser code when using many part keys
+on the same key: @code{INDEX (Organisation,Surname(35),Initials(35))}.
@item
-Added some tests to the table order optimizer to get some cases with
+Added some tests to the table order optimiser to get some cases with
@code{SELECT ... FROM many_tables} much faster.
@item
Added a retry loop around @code{accept()} to possibly fix some problems on some
@@ -51184,7 +54916,7 @@ Dynamic loadable functions. Based on source from Alexis Mikhailov.
You couldn't delete from a table if no one had done a @code{SELECT} on the
table.
@item
-Fixed problem with range optimizer with many @code{OR} operators on key parts
+Fixed problem with range optimiser with many @code{OR} operators on key parts
inside each other.
@item
Recoded @code{MIN()} and @code{MAX()} to work properly with strings and
@@ -51197,9 +54929,9 @@ part.
@item
Added Italian error messages from @email{brenno@@dewinter.com}.
@item
-@code{configure} now works better on OSF1 (tested on 4.0D).
+@code{configure} now works better on OSF/1 (tested on 4.0D).
@item
-Added hooks to allow @code{LIKE} optimization with international character
+Added hooks to allow @code{LIKE} optimisation with international character
support.
@item
Upgraded @code{DBI} to 0.93.
@@ -51220,8 +54952,8 @@ The following symbols are now reserved words:
Setting a @code{TIMESTAMP} to @code{NULL} in @code{LOAD DATA INFILE ...} didn't
set the current time for the @code{TIMESTAMP}.
@item
-Fix @code{BETWEEN} to recognize binary strings. Now @code{BETWEEN} is
-case sensitive.
+Fix @code{BETWEEN} to recognise binary strings. Now @code{BETWEEN} is
+case-sensitive.
@item
Added @code{--skip-thread-priority} option to @code{mysqld}, for systems
where @code{mysqld}'s thread scheduling doesn't work properly (BSDI 3.1).
@@ -51231,10 +54963,10 @@ Added ODBC functions @code{DAYNAME()} and @code{MONTHNAME()}.
Added function @code{TIME_FORMAT()}. This works like @code{DATE_FORMAT()},
but takes a time string (@code{'HH:MM:DD'}) as argument.
@item
-Fixed unlikely(?) key optimizer bug when using @code{OR}s of key parts
+Fixed unlikely(?) key optimiser bug when using @code{OR}s of key parts
inside @code{AND}s.
@item
-Added command @code{variables} to @code{mysqladmin}.
+Added @code{variables} command to @code{mysqladmin}.
@item
A lot of small changes to the binary releases.
@item
@@ -51258,35 +54990,35 @@ Starting with this version, all MySQL distributions will be
configured, compiled and tested with @code{crash-me} and the benchmarks on
the following platforms: SunOS 5.6 sun4u, SunOS 5.5.1 sun4u, SunOS 4.14 sun4c,
SunOS 5.6 i86pc, Irix 6.3 mips5k, HP-UX 10.20 hppa, AIX 4.2.1 ppc,
-OSF1 V4.0 alpha, FreeBSD 2.2.2 i86pc and BSDI 3.1 i386.
+OSF/1 V4.0 alpha, FreeBSD 2.2.2 i86pc and BSDI 3.1 i386.
@item
Fix @code{COUNT(*)} problems when the @code{WHERE} clause didn't match any
records. (Bug from 3.21.17.)
@item
Removed that @code{NULL = NULL} is true. Now you must use @code{IS NULL}
-or @code{IS NOT NULL} to test whether or not a value is @code{NULL}.
+or @code{IS NOT NULL} to test whether a value is @code{NULL}.
(This is according to ANSI SQL but may break
old applications that are ported from @code{mSQL}.)
-You can get the old behavior by compiling with @code{-DmSQL_COMPLIANT}.
+You can get the old behaviour by compiling with @code{-DmSQL_COMPLIANT}.
@item
Fixed bug that core dumped when using many @code{LEFT OUTER JOIN} clauses.
@item
Fixed bug in @code{ORDER BY} on string formula with possible @code{NULL} values.
@item
-Fixed problem in range optimizer when using <= on sub index.
+Fixed problem in range optimiser when using @code{<=} on sub index.
@item
Added functions @code{DAYOFYEAR()}, @code{DAYOFMONTH()}, @code{MONTH()},
@code{YEAR()}, @code{WEEK()}, @code{QUARTER()}, @code{HOUR()}, @code{MINUTE()},
@code{SECOND()} and @code{FIND_IN_SET()}.
@item
-Added command @code{SHOW VARIABLES}.
+Added @code{SHOW VARIABLES} command.
@item
Added support of ``long constant strings'' from ANSI SQL:
@example
mysql> SELECT 'first ' 'second'; -> 'first second'
@end example
@item
-Upgraded mSQL-Mysql-modules to 1.1825.
+Upgraded Msql-Mysql-modules to 1.1825.
@item
Upgraded @code{mysqlaccess} to 2.02.
@item
@@ -51312,10 +55044,10 @@ Configure changes for some operating systems.
@itemize @bullet
@item
-Fixed optimizer bug when using
+Fixed optimiser bug when using
@code{WHERE data_field = date_field2 AND date_field2 = constant}.
@item
-Added command @code{SHOW STATUS}.
+Added @code{SHOW STATUS} command.
@item
Removed @file{manual.ps} from the source distribution to make it smaller.
@end itemize
@@ -51348,8 +55080,8 @@ from 2G to 4G.
@itemize @bullet
@item
-Upgraded @code{DBD} to 1823. This version implements @code{mysql_use_result} in
-@code{DBD-Mysql}.
+Upgraded @code{DBD} to 1.1823. This version implements @code{mysql_use_result}
+in @code{DBD-Mysql}.
@item
Benchmarks updated for empress (by Luuk).
@item
@@ -51417,7 +55149,7 @@ restart if one thread was reading data that another thread modified.
@item
@code{LIMIT offset,count} didn't work in @code{INSERT ... SELECT}.
@item
-Optimized key block caching. This will be quicker than the old algorithm when
+Optimised key block caching. This will be quicker than the old algorithm when
using bigger key caches.
@end itemize
@@ -51431,7 +55163,7 @@ Added ODBC 2.0 & 3.0 functions @code{POWER()}, @code{SPACE()},
@code{COT()}, @code{DEGREES()}, @code{RADIANS()}, @code{ROUND(2 arg)}
and @code{TRUNCATE()}.
@item
-@strong{WARNING: INCOMPATIBLE CHANGE!!} @code{LOCATE()} parameters were
+@strong{Warning: Incompatible change!} @code{LOCATE()} parameters were
swapped according to ODBC standard. Fixed.
@item
Added function @code{TIME_TO_SEC()}.
@@ -51450,14 +55182,14 @@ be compatible with @code{mysqldump}.
@itemize @bullet
@item
-@strong{WARNING: INCOMPATIBLE CHANGE!!} @code{mysqlperl} is now from
+@strong{Warning: Incompatible change!} @code{mysqlperl} is now from
Msql-Mysql-modules. This means that @code{connect()} now takes
@code{host}, @code{database}, @code{user}, @code{password} arguments! The old
version took @code{host}, @code{database}, @code{password}, @code{user}.
@item
Allow @code{DATE '1997-01-01'}, @code{TIME '12:10:10'} and
@code{TIMESTAMP '1997-01-01 12:10:10'} formats required by ANSI SQL.
-@strong{WARNING: INCOMPATIBLE CHANGE!!} This has the unfortunate
+@strong{Warning: Incompatible change!} This has the unfortunate
side-effect that you no longer can have columns named @code{DATE}, @code{TIME}
or @code{TIMESTAMP}. :( Old columns can still be accessed through
@code{tablename.columnname}!)
@@ -51477,13 +55209,13 @@ is now the recommended way to connect to MySQL from Perl.
New portable benchmark suite with @code{DBD}, with test results from
@code{mSQL} 2.0.3, MySQL, PostgreSQL 6.2.1 and Solid server 2.2.
@item
-@code{crash-me} is now included with the benchmarks; This is a Perl program
+@code{crash-me} is now included with the benchmarks; this is a Perl program
designed to find as many limits as possible in a SQL server. Tested with
@code{mSQL}, PostgreSQL, Solid and MySQL.
@item
-Fixed bug in range-optimizer that crashed MySQL on some queries.
+Fixed bug in range-optimiser that crashed MySQL on some queries.
@item
-Table and column name completion for @code{mysql} command line tool, by Zeev
+Table and column name completion for @code{mysql} command-line tool, by Zeev
Suraski and Andi Gutmans.
@item
Added new command @code{REPLACE} that works like @code{INSERT} but
@@ -51551,7 +55283,7 @@ Fixed slow sorting when sorting on key field when using
@item
Sorting on calculated @code{DOUBLE} values sorted on integer results instead.
@item
-@code{mysql} no longer needs a database argument.
+@code{mysql} no longer requires a database argument.
@item
Changed the place where @code{HAVING} should be. According to ANSI, it should
be after @code{GROUP BY} but before @code{ORDER BY}. MySQL Version 3.20
@@ -51628,14 +55360,14 @@ Added @code{ENCRYPT()} function by Zeev Suraski.
Fixed better @code{FOREIGN KEY} syntax skipping. New reserved words:
@code{MATCH}, @code{FULL}, @code{PARTIAL}.
@item
-@code{mysqld} now allows IP number and hostname to the @code{--bind-address}
+@code{mysqld} now allows IP number and hostname for the @code{--bind-address}
option.
@item
-Added @code{SET OPTION CHARACTER SET cp1251_koi8} to enable conversions of
-data to/from cp1251_koi8.
+Added @code{SET CHARACTER SET cp1251_koi8} to enable conversions of
+data to and from the @code{cp1251_koi8} character set.
@item
-Lots of changes for Win95 port. In theory, this version should now be
-easily portable to Win95.
+Lots of changes for Windows 95 port. In theory, this version should now be
+easily portable to Windows 95.
@item
Changed the @code{CREATE COLUMN} syntax of @code{NOT NULL} columns to be after
the @code{DEFAULT} value, as specified in the ANSI SQL standard. This will
@@ -51650,7 +55382,7 @@ NULL}.
@item
Added @code{CHAR} and @code{BIT} as synonyms for @code{CHAR(1)}.
@item
-Fixed core dump when updating as a user who has only @strong{select} privilege.
+Fixed core dump when updating as a user who has only @code{SELECT} privilege.
@item
@code{INSERT ... SELECT ... GROUP BY} didn't work in some cases. An
@code{Invalid use of group function} error occurred.
@@ -51723,7 +55455,7 @@ Fixed some @code{configure} issues.
Made the locking code a bit safer. Fixed very unlikely
deadlock situation.
@item
-Fixed a couple of bugs in the range optimizer. Now the new range benchmark
+Fixed a couple of bugs in the range optimiser. Now the new range benchmark
@code{test-select} works.
@end itemize
@@ -51741,7 +55473,7 @@ Fixed bug in range calculation that could return empty
set when searching on multiple key with only one entry (very rare).
@item
Most things ported to FSU Pthreads, which should allow MySQL to
-run on SCO. @xref{SCO}.
+run on Caldera (SCO). @xref{Caldera}.
@end itemize
@@ -51773,7 +55505,7 @@ Fixed bug with @code{GROUP BY} and @code{SELECT} on key with many values.
@code{mysql_use_result()}. This affected at least some cases of
@code{mysqldump --quick}.
@item
-Fixed bug in optimization of @code{WHERE const op field}.
+Fixed bug in optimisation of @code{WHERE const op field}.
@item
Fixed problem when sorting on @code{NULL} fields.
@item
@@ -51783,7 +55515,7 @@ Added @code{--pid-file=#} option to @code{mysqld}.
@item
Added date formatting to @code{FROM_UNIXTIME()}, originally by Zeev Suraski.
@item
-Fixed bug in @code{BETWEEN} in range optimizer (Did only test = of the first
+Fixed bug in @code{BETWEEN} in range optimiser (did only test = of the first
argument).
@item
Added machine-dependent files for MIT-pthreads i386-SCO. There is probably
@@ -51805,7 +55537,7 @@ Added more secure password handling.
Added new client function @code{mysql_errno()}, to get the error number of
the error message. This makes error checking in the client much easier.
This makes the new server incompatible with the 3.20.x server when running
-without @code{--old-protocol}. The client code is backward compatible.
+without @code{--old-protocol}. The client code is backward-compatible.
More information can be found in the @file{README} file!
@item
Fixed some problems when using very long, illegal names.
@@ -51834,13 +55566,13 @@ Should now work with FreeBSD 3.0 if used with
@file{FreeBSD-3.0-libc_r-1.0.diff},
which can be found at @uref{http://www.mysql.com/Downloads/Patches/}.
@item
-Added new option @code{-O tmp_table_size=#} to @code{mysqld}.
+Added new @code{-O tmp_table_size=#} option to @code{mysqld}.
@item
New function @code{FROM_UNIXTIME(timestamp)} which returns a date string in
-'YYYY-MM-DD HH:MM:DD' format.
+@code{'YYYY-MM-DD HH:MM:DD'} format.
@item
New function @code{SEC_TO_TIME(seconds)} which returns a string in
-'HH:MM:SS' format.
+@code{'HH:MM:SS'} format.
@item
New function @code{SUBSTRING_INDEX()}, originally by Zeev Suraski.
@end itemize
@@ -51851,7 +55583,7 @@ New function @code{SUBSTRING_INDEX()}, originally by Zeev Suraski.
@itemize @bullet
@item
-Should now configure and compile on OSF1 4.0 with the DEC compiler.
+Should now configure and compile on OSF/1 4.0 with the DEC compiler.
@item
Configuration and compilation on BSD/OS 3.0 works, but due to some bugs in
BSD/OS 3.0, @code{mysqld} doesn't work on it yet.
@@ -51873,7 +55605,7 @@ Fixed some possible buffer overflows if filenames that are too long are used.
@code{mysqld} doesn't accept hostnames that start with digits followed by a
@code{'.'}, because the hostname may look like an IP number.
@item
-Added @code{--skip-networking} option to @code{mysqld}, to only allow socket
+Added @code{--skip-networking} option to @code{mysqld}, to allow only socket
connections. (This will not work with MIT-pthreads!)
@item
Added check of too long table names for alias.
@@ -51891,7 +55623,7 @@ Added @code{-O join_cache_size=#} option to @code{mysqld}.
@item
Added @code{-O max_join_size=#} option to @code{mysqld}, to be able to set a
limit how big queries (in this case big = slow) one should be able to handle
-without specifying @code{SET OPTION SQL_BIG_SELECTS=1}. A # = is about 10
+without specifying @code{SET SQL_BIG_SELECTS=1}. A # = is about 10
examined records. The default is ``unlimited''.
@item
When comparing a @code{TIME}, @code{DATE}, @code{DATETIME} or @code{TIMESTAMP}
@@ -51925,7 +55657,7 @@ Changed the default sort buffer size from 2M to 1M.
@itemize @bullet
@item
-The range optimizer is coded, but only 85% tested. It can be enabled with
+The range optimiser is coded, but only 85% tested. It can be enabled with
@code{--new}, but it crashes core a lot yet...
@item
More portable. Should compile on AIX and alpha-digital.
@@ -51949,7 +55681,7 @@ memory. Also added more checks to handle ``out of memory'' problems.
multiple threads.
@item
When the maximum connection limit is reached, one extra connection by a user
-with the @strong{PROCESS_ACL} privilege is granted.
+with the @strong{process_acl} privilege is granted.
@item
Added @code{-O backlog=#} option to @code{mysqld}.
@item
@@ -51977,7 +55709,7 @@ Fixed bug that you couldn't use @code{tbl_name.field_name} in @code{UPDATE}.
Fixed @code{SELECT DISTINCT} when using 'hidden group'. For example:
@example
mysql> SELECT DISTINCT MOD(some_field,10) FROM test
- GROUP BY some_field;
+ -> GROUP BY some_field;
@end example
Note: @code{some_field} is normally in the @code{SELECT} part. ANSI SQL should
require it.
@@ -52002,7 +55734,7 @@ Added @code{--log-update} option to @code{mysqld}, to get a log suitable for
incremental updates.
@item
New command @code{EXPLAIN SELECT ...} to get information about how the
-optimizer will do the join.
+optimiser will do the join.
@item
For easier client code, the client should no longer use
@code{FIELD_TYPE_TINY_BLOB}, @code{FIELD_TYPE_MEDIUM_BLOB},
@@ -52047,12 +55779,12 @@ will also work with @code{NULL} values.
@item
Full @code{WHERE} with expressions.
@item
-New range optimizer that can resolve ranges when some keypart prefix is
+New range optimiser that can resolve ranges when some keypart prefix is
constant. Example:
@example
mysql> SELECT * FROM tbl_name
- WHERE key_part_1="customer"
- AND key_part_2>=10 AND key_part_2<=10;
+ -> WHERE key_part_1="customer"
+ -> AND key_part_2>=10 AND key_part_2<=10;
@end example
@end itemize
@@ -52124,12 +55856,12 @@ The test of using @code{MYSQL_PWD} was reversed. Now @code{MYSQL_PWD} is
enabled as default in the default release.
@item
Fixed conversion bug which caused @code{mysqld} to core dump with
-Arithmetic error on Sparc-386.
+Arithmetic error on SPARC-386.
@item
Added @code{--unbuffered} option to @code{mysql}, for new @code{mysqlaccess}.
@item
When using overlapping (unnecessary) keys and join over many tables,
-the optimizer could get confused and return 0 records.
+the optimiser could get confused and return 0 records.
@end itemize
@@ -52161,7 +55893,7 @@ works.
@item
A couple of bugs fixed in @code{SELECT ... GROUP BY}.
@item
-Fixed memory overrun bug in @code{WHERE} with many unoptimizable brace levels.
+Fixed memory overrun bug in @code{WHERE} with many unoptimisable brace levels.
@item
Fixed some small bugs in the grant code.
@item
@@ -52175,12 +55907,12 @@ Inserts of timestamps with values didn't always work.
@item
Added some tests to @code{safe_mysqld} to make it ``safer''.
@item
-@code{LIKE} was case sensitive in some places and case insensitive in others.
-Now @code{LIKE} is always case insensitive.
+@code{LIKE} was case-sensitive in some places and case-insensitive in others.
+Now @code{LIKE} is always case-insensitive.
@item
@file{mysql.cc}: Allow @code{'#'} anywhere on the line.
@item
-New command @code{SET OPTION SQL_SELECT_LIMIT=#}. See the FAQ for more details.
+New command @code{SET SQL_SELECT_LIMIT=#}. See the FAQ for more details.
@item
New version of the @code{mysqlaccess} script.
@item
@@ -52212,10 +55944,10 @@ bugs that appear during the build with it.
Changed @file{libmysql.c} to prefer @code{getpwuid()} instead of
@code{cuserid()}.
@item
-Fixed bug in @code{SELECT} optimizer when using many tables with the same
+Fixed bug in @code{SELECT} optimiser when using many tables with the same
column used as key to different tables.
@item
-Added new latin2 and Russian KOI8 character tables.
+Added new @code{latin2} and Russian @code{KOI8} character tables.
@item
Added support for a dummy @code{GRANT} command to satisfy Powerbuilder.
@end itemize
@@ -52269,7 +56001,7 @@ Fixed adding an @code{AUTO_INCREMENT} key with @code{ALTER_TABLE}.
Added new @code{DATETIME} type (by Giovanni Maruzzelli
@email{maruzz@@matrice.it}).
@item
-Fixed that define @code{DONT_USE_DEFAULT_FIELDS} works.
+Fixed that defining @code{DONT_USE_DEFAULT_FIELDS} works.
@item
Changed to use a thread to handle alarms instead of signals on Solaris to
avoid race conditions.
@@ -52421,9 +56153,9 @@ New commands: @code{ALTER TABLE}, @code{SELECT ... INTO OUTFILE} and
@item
New function: @code{NOW()}.
@item
-Added new field @strong{file_priv} to @code{mysql/user} table.
+Added new field @code{File_priv} to @code{mysql/user} table.
@item
-New script @code{add_file_priv} which adds the new field @strong{file_priv}
+New script @code{add_file_priv} which adds the new field @code{File_priv}
to the @code{user} table. This script must be executed if you want to
use the new @code{SELECT ... INTO} and @code{LOAD DATA INFILE ...} commands
with a version of MySQL earlier than 3.20.7.
@@ -52435,7 +56167,7 @@ New files @file{NEW} and @file{BUGS}.
Changed @file{select_test.c} and @file{insert_test.c} to include
@file{config.h}.
@item
-Added command @code{status} to @code{mysqladmin} for short logging.
+Added @code{status} command to @code{mysqladmin} for short logging.
@item
Increased maximum number of keys to 16 and maximum number of key parts to 15.
@item
@@ -52473,7 +56205,7 @@ You must use @code{mysql_real_query()} to send the query.
Added API function @code{mysql_get_client_info()}.
@item
@code{mysqld} now uses the @code{N_MAX_KEY_LENGTH} from @file{nisam.h} as
-the maximum allowed key length.
+the maximum allowable key length.
@item
The following now works:
@example
@@ -52486,7 +56218,7 @@ Previously, this resulted in the error:
when encountering ASCII 0, tab, newline or @code{'\'} while writing
tab-separated output.
This is to allow printing of binary data in a portable format.
-To get the old behavior, use @code{-r} (or @code{--raw}).
+To get the old behaviour, use @code{-r} (or @code{--raw}).
@item
Added german error messages (60 of 80 error messages translated).
@item
@@ -52495,10 +56227,10 @@ returns an array of column lengths (of type @code{uint}).
@item
Fixed bug with @code{IS NULL} in @code{WHERE} clause.
@item
-Changed the optimizer a little to get better results when searching on a key
+Changed the optimiser a little to get better results when searching on a key
part.
@item
-Added @code{SELECT} option @code{STRAIGHT_JOIN} to tell the optimizer that
+Added @code{SELECT} option @code{STRAIGHT_JOIN} to tell the optimiser that
it should join tables in the given order.
@item
Added support for comments starting with @code{'--'} in @file{mysql.cc}
@@ -52509,15 +56241,15 @@ which are not used in the group part. This makes it efficient to implement
lookups. The column that is used should be a constant for each group because
the value is calculated only once for the first row that is found for a group.
@example
-mysql> SELECT id,lookup.text,sum(*) FROM test,lookup
- WHERE test.id=lookup.id GROUP BY id;
+mysql> SELECT id,lookup.text,SUM(*) FROM test,lookup
+ -> WHERE test.id=lookup.id GROUP BY id;
@end example
@item
Fixed bug in @code{SUM(function)} (could cause a core dump).
@item
Changed @code{AUTO_INCREMENT} placement in the SQL query:
@example
-INSERT into table (auto_field) values (0);
+INSERT INTO table (auto_field) VALUES (0);
@end example
inserted 0, but it should insert an @code{AUTO_INCREMENT} value.
@item
@@ -52540,7 +56272,7 @@ New math functions:
The @code{configure} source now compiles a thread-free client library
@code{-lmysqlclient}. This is the only library that needs to be linked
with client applications. When using the binary releases, you must
-link with @code{-lmysql -lmysys -ldbug -lstrings} as before.
+link with @code{-lmysql -lmysys -ldbug -lmystrings} as before.
@item
New @code{readline} library from @code{bash-2.0}.
@item
@@ -52577,7 +56309,7 @@ Fixed core dump bug in @code{sql_acl} (core on new connection).
Removed @code{host}, @code{user} and @code{db} tables from database @code{test}
in the distribution.
@item
-@code{FIELD_TYPE_CHAR} can now be signed (-128 - 127) or unsigned (0 - 255)
+@code{FIELD_TYPE_CHAR} can now be signed (-128 to 127) or unsigned (0 to 255)
Previously, it was always unsigned.
@item
Bug fixes in @code{CONCAT()} and @code{WEEKDAY()}.
@@ -52587,8 +56319,8 @@ compiler.
@item
SQL functions must now have a @code{'('} immediately after the function name
(no intervening space).
-For example, @code{'user('} is regarded as beginning a function call, and
-@code{'user ('} is regarded as an identifier @code{user} followed by a
+For example, @code{'USER('} is regarded as beginning a function call, and
+@code{'USER ('} is regarded as an identifier @code{USER} followed by a
@code{'('}, not as a function call.
@end itemize
@@ -52658,7 +56390,7 @@ information is kept here for historical purposes only.
@itemize @bullet
@item
-Some new functions, some more optimization on joins.
+Some new functions, some more optimisation on joins.
@item
Should now compile clean on Linux (2.0.x).
@item
@@ -52726,10 +56458,21 @@ Fixed @code{DISTINCT} with calculated columns.
@node Porting, Environment variables, News, Top
-@appendix Comments on porting to other systems
+@appendix Porting to Other Systems
@cindex porting, to other systems
+This appendix will help you port MySQL to other operationg systems.
+Do check the list of currently supported operating systems first.
+@xref{Which OS}.
+If you have created a new port of MySQL, please let us know so that
+we can list it here and on our web site (@uref{http://www.mysql.com/}),
+recommending it to other users.
+
+Note: If you create a new port of MySQL, you are free to copy and
+distribute it under the GPL license, but it does not make you a
+copyright holder of MySQL.
+
A working Posix thread library is needed for the server. On Solaris 2.5
we use Sun PThreads (the native thread support in 2.4 and earlier
versions are not good enough) and on Linux we use LinuxThreads by Xavier
@@ -52737,13 +56480,13 @@ Leroy, @email{Xavier.Leroy@@inria.fr}.
The hard part of porting to a new Unix variant without good native
thread support is probably to port MIT-pthreads. See
-@file{mit-pthreads/README} and
-@uref{http://www.humanfactor.com/pthreads/, Programming POSIX Threads}.
+@file{mit-pthreads/README} and Programming POSIX Threads
+(@uref{http://www.humanfactor.com/pthreads/}).
The MySQL distribution includes a patched version of
-Provenzano's Pthreads from MIT (see
-@uref{http://www.mit.edu:8001/people/proven/pthreads.html, MIT Pthreads
-web page}). This can be used for some operating systems that do not
+Provenzano's Pthreads from MIT (see the MIT Pthreads web page at
+@uref{http://www.mit.edu:8001/people/proven/pthreads.html}).
+This can be used for some operating systems that do not
have POSIX threads.
It is also possible to use another user level thread package named
@@ -52755,7 +56498,7 @@ See the @file{thr_lock.c} and @file{thr_alarm.c} programs in the @file{mysys}
directory for some tests/examples of these problems.
Both the server and the client need a working C++ compiler (we use @code{gcc}
-and have tried SparcWorks). Another compiler that is known to work is the
+and have tried SPARCworks). Another compiler that is known to work is the
Irix @code{cc}.
To compile only the client use @code{./configure --without-server}.
@@ -52788,15 +56531,15 @@ If you run into problems with a new port, you may have to do some debugging
of MySQL!
@xref{Debugging server}.
-@strong{NOTE:} Before you start debugging @code{mysqld}, first get the test
+@strong{Note}: before you start debugging @code{mysqld}, first get the test
programs @code{mysys/thr_alarm} and @code{mysys/thr_lock} to work. This
will ensure that your thread installation has even a remote chance to work!
@menu
* Debugging server:: Debugging a MySQL server
* Debugging client:: Debugging a MySQL client
-* The DBUG package:: The DBUG package
-* Locking methods:: Locking methods
+* The DBUG package:: The DBUG Package
+* Locking methods:: Locking ethods
* RTS-threads:: Comments about RTS threads
* Thread packages:: Differences between different thread packages
@end menu
@@ -52812,12 +56555,12 @@ will ensure that your thread installation has even a remote chance to work!
If you are using some functionality that is very new in MySQL,
you can try to run @code{mysqld} with the @code{--skip-new} (which will disable all
new, potentially unsafe functionality) or with @code{--safe-mode} which
-disables a lot of optimization that may cause problems.
+disables a lot of optimisation that may cause problems.
@xref{Crashing}.
If @code{mysqld} doesn't want to start, you should check that you don't have
-any @code{my.cnf} files that interfere with your setup!
-You can check your @code{my.cnf} arguments with @code{mysqld --print-defaults}
+any @file{my.cnf} files that interfere with your setup!
+You can check your @file{my.cnf} arguments with @code{mysqld --print-defaults}
and avoid using them by starting with @code{mysqld --no-defaults ...}.
If @code{mysqld} starts to eat up CPU or memory or if it ``hangs'', you
@@ -52832,7 +56575,7 @@ may help solve some problems. This command also provides some useful
information even if you haven't compiled MySQL for debugging!
If the problem is that some tables are getting slower and slower you
-should try to optimize the table with @code{OPTIMIZE TABLE} or
+should try to optimise the table with @code{OPTIMIZE TABLE} or
@code{myisamchk}. @xref{MySQL Database Administration}. You should also
check the slow queries with @code{EXPLAIN}.
@@ -52841,7 +56584,7 @@ problems that may be unique to your environment.
@xref{Operating System Specific Notes}.
@menu
-* Compiling for debugging:: Compiling MYSQL for debugging.
+* Compiling for debugging:: Compiling MYSQL for debugging
* Making trace files:: Creating trace files
* Using gdb on mysqld:: Debugging mysqld under gdb
* Using stack trace:: Using a stack trace
@@ -52851,12 +56594,12 @@ problems that may be unique to your environment.
@node Compiling for debugging, Making trace files, Debugging server, Debugging server
-@appendixsubsec Compiling MYSQL for debugging.
+@appendixsubsec Compiling MYSQL for Debugging
If you have some very specific problem, you can always try to debug
MySQL. To do this you must configure MySQL with the
@code{--with-debug} or the @code{--with-debug=full} option. You can check
-whether or not MySQL was compiled with debugging by doing:
+whether MySQL was compiled with debugging by doing:
@code{mysqld --help}. If the @code{--debug} flag is listed with the
options then you have debugging enabled. @code{mysqladmin ver} also
lists the @code{mysqld} version as @code{mysql ... --debug} in this case.
@@ -52864,7 +56607,9 @@ lists the @code{mysqld} version as @code{mysql ... --debug} in this case.
If you are using gcc or egcs, the recommended configure line is:
@example
-CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex
+CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors \
+ -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql \
+ --with-debug --with-extra-charsets=complex
@end example
This will avoid problems with the @code{libstdc++} library and with C++
@@ -52903,7 +56648,7 @@ default compiled with support for trace files.
@node Making trace files, Using gdb on mysqld, Compiling for debugging, Debugging server
-@appendixsubsec Creating trace files
+@appendixsubsec Creating Trace Files
If the @code{mysqld} server doesn't start or if you can cause the
@code{mysqld} server to crash quickly, you can try to create a trace
@@ -52927,11 +56672,11 @@ In a DOS window do:
mysqld --debug --standalone
@end example
-After this you can use the @code{mysql.exe} command line tool in a
+After this you can use the @code{mysql.exe} command-line tool in a
second DOS window to reproduce the problem. You can take down the above
@code{mysqld} server with @code{mysqladmin shutdown}.
-Note that the trace file will get very @emph{BIG}!
+Note that the trace file will get @strong{very big}!
If you want to have a smaller trace file, you can use something like:
@code{mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace}
@@ -52943,7 +56688,7 @@ If you make a bug report about this, please only send the lines from the
trace file to the appropriate mailing list where something seems to go
wrong! If you can't locate the wrong place, you can ftp the trace file,
together with a full bug report, to
-@uref{ftp://support.mysql.com/pub/mysql/secret} so that a MySQL
+@uref{ftp://support.mysql.com/pub/mysql/secret/} so that a MySQL
developer can take a look a this.
The trace file is made with the @strong{DBUG} package by Fred Fish.
@@ -52955,12 +56700,14 @@ The trace file is made with the @strong{DBUG} package by Fred Fish.
@cindex gdb, using
-On most system you can also start @code{mysqld} from @code{gdb} to get
+On most systems you can also start @code{mysqld} from @code{gdb} to get
more information if @code{mysqld} crashes.
With some older @code{gdb} versions on Linux you must use @code{run
--one-thread} if you want to be able to debug @code{mysqld} threads. In
-this case you can only have one thread active at a time.
+this case you can only have one thread active at a time. We recommend you
+to upgrade to gdb 5.1 ASAP as thread debugging works much better with this
+version!
When running @code{mysqld} under gdb, you should disable the stack trace
with @code{--skip-stack-trace} to be able to catch segfaults within gdb.
@@ -53035,12 +56782,12 @@ setting the @code{DBI_TRACE} environment variable.
@node Using stack trace, Using log files, Using gdb on mysqld, Debugging server
-@appendixsubsec Using a stack trace
+@appendixsubsec Using a Stack Trace
On some operating systems, the error log will contain a stack trace if
@code{mysqld} dies unexpectedly. You can use this to find out where (and
maybe why) @code{mysqld} died. @xref{Error log}. To get a stack trace,
-you should NOT compile @code{mysqld} with the @code{-fomit-frame-pointer}
+you must not compile @code{mysqld} with the @code{-fomit-frame-pointer}
option to gcc. @xref{Compiling for debugging}.
If the error file contains something like the following:
@@ -53104,10 +56851,10 @@ repeat the problem! @xref{Bug reports}.
@node Using log files, Reproduceable test case, Using stack trace, Debugging server
-@appendixsubsec Using log files to find cause of errors in mysqld
+@appendixsubsec Using Log Files to Find Cause of Errors in mysqld
Note that before starting @code{mysqld} with @code{--log} you should
-check all your tables with @code{myisamchk}.
+check all your tables with @code{myisamchk}.
@xref{MySQL Database Administration}.
If @code{mysqld} dies or hangs, you should start @code{mysqld} with
@@ -53118,7 +56865,7 @@ If you are using @code{--log} without a file name, the log is stored in
the database directory as 'hostname'.log In most cases it's the last
query in the log file that killed @code{mysqld}, but if possible you
should verify this by restarting @code{mysqld} and executing the found
-query from the @code{mysql} command line tools. If this works, you
+query from the @code{mysql} command-line tools. If this works, you
should also test all complicated queries that didn't complete.
You can also try the command @code{EXPLAIN} on all @code{SELECT}
@@ -53133,14 +56880,13 @@ If you find the text @code{mysqld restarted} in the error log file
that causes @code{mysqld} to fail. If this happens you should check all
your tables with @code{myisamchk} (@pxref{MySQL Database Administration}),
and test the queries in the MySQL log files to see if one doesn't
-work. If you find such a query, try first upgrading to the newest
+work. If you find such a query, try first upgrading to the newest
MySQL version. If this doesn't help and you can't find anything
in the @code{mysql} mail archive, you should report the bug to
@email{mysql@@lists.mysql.com}. Links to mail archives are available
-online at the @uref{http://www.mysql.com/documentation/, MySQL
-documentation page}.
+online at @uref{http://lists.mysql.com/}.
-If you have started @code{mysqld} with @code{--with-myisam-recover},
+If you have started @code{mysqld} with @code{myisam-recover},
MySQL will automatically check and try to repair @code{MyISAM}
tables if they are marked as 'not closed properly' or 'crashed'. If
this happens, MySQL will write an entry in the
@@ -53151,12 +56897,12 @@ died unexpectedly just before, then something is wrong and needs to
be investigated further. @xref{Command-line options}.
It's of course not a good sign if @code{mysqld} did died unexpectedly,
-but in this case one shouldn't investigate the @code{Checking table...}
+but in this case one shouldn't investigate the @code{Checking table...}
messages but instead try to find out why @code{mysqld} died.
@node Reproduceable test case, , Using log files, Debugging server
-@appendixsubsec Making a test case when you experience table corruption
+@appendixsubsec Making a Test Case When You Experience Table Corruption
If you get corrupted tables or if @code{mysqld} always fails after some
update commands, you can test if this bug is reproducible by doing the
@@ -53194,7 +56940,7 @@ the name @code{hostname-bin.#}.
If the tables are corrupted again or you can get @code{mysqld} to die with the
above command, you have found reproducible bug that should be easy to
fix! FTP the tables and the binary log to
-@uref{ftp://support.mysql.com/pub/mysql/secret} and send a mail to
+@uref{ftp://support.mysql.com/pub/mysql/secret/} and send a mail to
@email{bugs@@lists.mysql.com} or (if you are a support customer) to
@email{support@@mysql.com} about the problem and the MySQL team
will fix it as soon as possible.
@@ -53211,8 +56957,8 @@ update statements if you want to narrow down the problem.
@cindex clients, debugging
To be able to debug a MySQL client with the integrated debug package,
-you should configure MySQL with @code{--with-debug}.
-@xref{configure options}.
+you should configure MySQL with @code{--with-debug} or
+@code{--with-debug=full}. @xref{configure options}.
@tindex MYSQL_DEBUG environment variable
@tindex Environment variable, MYSQL_DEBUG
@@ -53245,7 +56991,7 @@ MySQL installation with new MySQL library.
@node The DBUG package, Locking methods, Debugging client, Porting
-@appendixsec The DBUG package.
+@appendixsec The DBUG Package
@cindex DBUG package
@@ -53276,9 +57022,10 @@ an optional "," and comma-separated list of modifiers:
flag[,modifier,modifier,...,modifier]
@end example
-The currently recognized flag characters are:
+The currently recognised flag characters are:
-@multitable @columnfractions .1 .9
+@multitable @columnfractions .05 .95
+@item @strong{Flag} @tab @strong{Description}
@item d @tab Enable output from DBUG_<N> macros for the current state. May be followed by a list of keywords which selects output only for the DBUG macros with that keyword. An empty list of keywords implies output for all macros.
@item D @tab Delay after each debugger output line. The argument is the number of tenths of seconds to delay, subject to machine capabilities. That is, @code{-#D,20} is delay two seconds.
@item f @tab Limit debugging and/or tracing, and profiling to the list of named functions. Note that a null list will disable all functions. The appropriate "d" or "t" flags must still be given, this flag only limits their actions if they are enabled.
@@ -53298,7 +57045,7 @@ The currently recognized flag characters are:
@end multitable
Some examples of debug control strings which might appear on a shell
-command line (the "-#" is typically used to introduce a control string
+command-line (the "-#" is typically used to introduce a control string
to an application program) are:
@example
@@ -53320,20 +57067,20 @@ In MySQL, common tags to print (with the @code{d} option) are:
@cindex methods, locking
Currently MySQL only supports table locking for
-@code{ISAM}/@code{MyISAM} and @code{HEAP} tables and page level locking
-for @code{BDB} tables. @xref{Internal locking}. With @code{MyISAM}
-tables one can freely mix @code{INSERT} and @code{SELECT} without locks
-(@code{Versioning}).
-
-Starting in version 3.23.33, you can analyze the table lock contention
+@code{ISAM}/@code{MyISAM} and @code{HEAP} tables,
+page-level locking for @code{BDB} tables and
+row-level locking for @code{InnoDB} tables.
+@xref{Internal locking}.
+With @code{MyISAM} tables one can freely mix @code{INSERT} and
+@code{SELECT} without locks (@code{Versioning}).
+
+Starting in version 3.23.33, you can analyse the table lock contention
on your system by checking @code{Table_locks_waited} and
@code{Table_locks_immediate} environment variables.
-Some database users claim that MySQL cannot support near the
-number of concurrent users because it lacks row-level locking. This
-may be true for some specific applications, but is not generally
-true. As always this depends totally on what the application does and what
-is the access/update pattern of the data.
+To decide if you want to use a table type with row-level locking,
+you will want to look at what the application does and what the
+select/update pattern of the data is.
Pros for row locking:
@@ -53341,7 +57088,7 @@ Pros for row locking:
@item
Fewer lock conflicts when accessing different rows in many threads.
@item
-Less changes for rollbacks.
+Fewer changes for rollbacks.
@item
Makes it possible to lock a single row a long time.
@end itemize
@@ -53352,7 +57099,7 @@ Cons:
@item
Takes more memory than page level or table locks.
@item
-Is slower than page level or table locks when used one a big part of the table,
+Is slower than page level or table locks when used on a big part of the table,
because one has to do many more locks.
@item
Is definitely much worse than other locks if you do often do @code{GROUP
@@ -53370,15 +57117,15 @@ following cases:
@item
Mostly reads
@item
-Read and updates on strict keys; This is where one updates or deletes
+Read and updates on strict keys; this is where one updates or deletes
a row that can be fetched with one key read:
@example
UPDATE table_name SET column=value WHERE unique_key#
DELETE FROM table_name WHERE unique_key=#
@end example
@item
-@code{SELECT} combined with @code{INSERT} (and very few @code{UPDATE}'s
-and @code{DELETE}'s.
+@code{SELECT} combined with @code{INSERT} (and very few @code{UPDATE}s
+and @code{DELETE}s.
@item
Many scans / @code{GROUP BY} on the whole table without any writers.
@end itemize
@@ -53392,23 +57139,23 @@ on when one started to access it. Other names for this are time travel,
copy on write or copy on demand.
Copy on demand is in many case much better than page or row level
-locking; The worst case does, however, use much more memory than
+locking; the worst case does, however, use much more memory than
when using normal locks.
-Instead of using row level locks one can use application level locks.
-(Like get_lock/release_lock in MySQL). This works of course
+Instead of using row level locks one can use application level locks
+(like get_lock/release_lock in MySQL). This works of course
only in well-behaved applications.
In many cases one can do an educated guess which locking type is best
for the application but generally it's very hard to say that a given
-lock type is better than another; Everything depends on the application
+lock type is better than another; everything depends on the application
and different part of the application may require different lock types.
Here are some tips about locking in MySQL:
On web application most applications do lots of selects, very few
deletes, updates mainly on keys and inserts in some specific tables.
-The base MySQL setup is VERY tuned for this.
+The base MySQL setup is very well tuned for this.
Concurrent users is not a problem if one doesn't mix updates and selects
that needs to examine many rows in the same table.
@@ -53421,10 +57168,11 @@ a single lock is much faster than updates without locks). Splitting
thing to different tables will also helps.
If you get speed problems with the table locks in MySQL, you
-may be able to solve these to convert some of your tables to @code{BDB} tables.
-@xref{BDB}.
+may be able to solve these by converting some of your tables to @code{InnoDB}
+or @code{BDB} tables.
+@xref{InnoDB}. @xref{BDB}.
-The optimization section in the manual covers a lot of different aspects of
+The optimisation section in the manual covers a lot of different aspects of
how to tune ones application. @xref{Tips}.
@@ -53547,7 +57295,7 @@ threads have to wait for data. If the user thread packages are
integrated in the standard libs (FreeBSD and BSDI threads) the thread
package requires less overhead than thread packages that have to map all
unsafe calls (MIT-pthreads, FSU Pthreads and RTS threads). In some
-environments (for example, SCO), all system calls are thread safe so the
+environments (for example, SCO), all system calls are thread-safe so the
mapping can be done very easily (FSU Pthreads on SCO). Downside: All
mapped calls take a little time and it's quite tricky to be able to
handle all situations. There are usually also some system calls that are
@@ -53565,8 +57313,8 @@ somewhat expensive.
Kernel threads. Thread switching is handled by the thread library or the
kernel and is very fast. Everything is done in one process, but on some
systems, @code{ps} may show the different threads. If one thread aborts, the
-whole process aborts. Most system calls are thread safe and should
-require very little overhead. Solaris, HP-UX, AIX and OSF1 have kernel
+whole process aborts. Most system calls are thread-safe and should
+require very little overhead. Solaris, HP-UX, AIX and OSF/1 have kernel
threads.
@end itemize
@@ -53579,7 +57327,7 @@ really ``thread aware''.
@node Environment variables, Regexp, Porting, Top
-@appendix Environment Variables
+@appendix Environment Variables
@cindex environment variables, list of
@@ -53587,13 +57335,13 @@ Here is a list of all the environment variables that are used directly or
indirectly by MySQL. Most of these can also be found in other
places in this manual.
-Note that any options on the command line will take precedence over
+Note that any options on the command-line will take precedence over
values specified in configuration files and environment variables, and
values in configuration files take precedence over values in environment
variables.
In many cases it's preferable to use a configure file instead of environment
-variables to modify the behavior of MySQL. @xref{Option files}.
+variables to modify the behaviour of MySQL. @xref{Option files}.
@tindex CCX environment variable
@tindex Environment variable, CCX
@@ -53617,6 +57365,8 @@ variables to modify the behavior of MySQL. @xref{Option files}.
@tindex Environment variable, MYSQL_HISTFILE
@tindex MYSQL_HOST environment variable
@tindex Environment variable, MYSQL_HOST
+@tindex MYSQL_PS1 environment variable
+@tindex Environment variable, MYSQL_PS1
@tindex MYSQL_PWD environment variable
@tindex Environment variable, MYSQL_PWD
@tindex MYSQL_TCP_PORT environment variable
@@ -53636,7 +57386,8 @@ variables to modify the behavior of MySQL. @xref{Option files}.
@tindex USER environment variable
@tindex Environment variable, USER
-@multitable @columnfractions .2 .8
+@multitable @columnfractions .25 .70
+@item @strong{Variable} @tab @strong{Description}
@item @code{CCX} @tab Set this to your C++ compiler when running configure.
@item @code{CC} @tab Set this to your C compiler when running configure.
@item @code{CFLAGS} @tab Flags for your C compiler when running configure.
@@ -53647,7 +57398,8 @@ variables to modify the behavior of MySQL. @xref{Option files}.
@item @code{LD_RUN_PATH} @tab Used to specify where your @code{libmysqlclient.so} is.
@item @code{MYSQL_DEBUG} @tab Debug-trace options when debugging.
@item @code{MYSQL_HISTFILE} @tab The path to the @code{mysql} history file.
-@item @code{MYSQL_HOST} @tab Default host name used by the @code{mysql} command-line prompt.
+@item @code{MYSQL_HOST} @tab Default host name used by the @code{mysql} command-line client.
+@item @code{MYSQL_PS1} @tab Command prompt to use in the @code{mysql} command-line client. @xref{mysql}.
@item @code{MYSQL_PWD} @tab The default password when connecting to @code{mysqld}. Note that use of this is insecure!
@item @code{MYSQL_TCP_PORT} @tab The default TCP/IP port.
@item @code{MYSQL_UNIX_PORT} @tab The default socket; used for connections to @code{localhost}.
@@ -53662,8 +57414,8 @@ variables to modify the behavior of MySQL. @xref{Option files}.
-@node Regexp, Unireg, Environment variables, Top
-@appendix Description of MySQL regular expression syntax
+@node Regexp, GPL license, Environment variables, Top
+@appendix MySQL Regular Expressions
@cindex regex
@cindex regular expression syntax, described
@@ -53699,57 +57451,57 @@ characters/constructs:
@item ^
Match the beginning of a string.
@example
-mysql> select "fo\nfo" REGEXP "^fo$"; -> 0
-mysql> select "fofo" REGEXP "^fo"; -> 1
+mysql> SELECT "fo\nfo" REGEXP "^fo$"; -> 0
+mysql> SELECT "fofo" REGEXP "^fo"; -> 1
@end example
@item $
Match the end of a string.
@example
-mysql> select "fo\no" REGEXP "^fo\no$"; -> 1
-mysql> select "fo\no" REGEXP "^fo$"; -> 0
+mysql> SELECT "fo\no" REGEXP "^fo\no$"; -> 1
+mysql> SELECT "fo\no" REGEXP "^fo$"; -> 0
@end example
@item .
Match any character (including newline).
@example
-mysql> select "fofo" REGEXP "^f.*"; -> 1
-mysql> select "fo\nfo" REGEXP "^f.*"; -> 1
+mysql> SELECT "fofo" REGEXP "^f.*"; -> 1
+mysql> SELECT "fo\nfo" REGEXP "^f.*"; -> 1
@end example
@item a*
Match any sequence of zero or more @code{a} characters.
@example
-mysql> select "Ban" REGEXP "^Ba*n"; -> 1
-mysql> select "Baaan" REGEXP "^Ba*n"; -> 1
-mysql> select "Bn" REGEXP "^Ba*n"; -> 1
+mysql> SELECT "Ban" REGEXP "^Ba*n"; -> 1
+mysql> SELECT "Baaan" REGEXP "^Ba*n"; -> 1
+mysql> SELECT "Bn" REGEXP "^Ba*n"; -> 1
@end example
@item a+
Match any sequence of one or more @code{a} characters.
@example
-mysql> select "Ban" REGEXP "^Ba+n"; -> 1
-mysql> select "Bn" REGEXP "^Ba+n"; -> 0
+mysql> SELECT "Ban" REGEXP "^Ba+n"; -> 1
+mysql> SELECT "Bn" REGEXP "^Ba+n"; -> 0
@end example
@item a?
Match either zero or one @code{a} character.
@example
-mysql> select "Bn" REGEXP "^Ba?n"; -> 1
-mysql> select "Ban" REGEXP "^Ba?n"; -> 1
-mysql> select "Baan" REGEXP "^Ba?n"; -> 0
+mysql> SELECT "Bn" REGEXP "^Ba?n"; -> 1
+mysql> SELECT "Ban" REGEXP "^Ba?n"; -> 1
+mysql> SELECT "Baan" REGEXP "^Ba?n"; -> 0
@end example
@item de|abc
Match either of the sequences @code{de} or @code{abc}.
@example
-mysql> select "pi" REGEXP "pi|apa"; -> 1
-mysql> select "axe" REGEXP "pi|apa"; -> 0
-mysql> select "apa" REGEXP "pi|apa"; -> 1
-mysql> select "apa" REGEXP "^(pi|apa)$"; -> 1
-mysql> select "pi" REGEXP "^(pi|apa)$"; -> 1
-mysql> select "pix" REGEXP "^(pi|apa)$"; -> 0
+mysql> SELECT "pi" REGEXP "pi|apa"; -> 1
+mysql> SELECT "axe" REGEXP "pi|apa"; -> 0
+mysql> SELECT "apa" REGEXP "pi|apa"; -> 1
+mysql> SELECT "apa" REGEXP "^(pi|apa)$"; -> 1
+mysql> SELECT "pi" REGEXP "^(pi|apa)$"; -> 1
+mysql> SELECT "pix" REGEXP "^(pi|apa)$"; -> 0
@end example
@item (abc)*
Match zero or more instances of the sequence @code{abc}.
@example
-mysql> select "pi" REGEXP "^(pi)*$"; -> 1
-mysql> select "pip" REGEXP "^(pi)*$"; -> 0
-mysql> select "pipi" REGEXP "^(pi)*$"; -> 1
+mysql> SELECT "pi" REGEXP "^(pi)*$"; -> 1
+mysql> SELECT "pip" REGEXP "^(pi)*$"; -> 0
+mysql> SELECT "pipi" REGEXP "^(pi)*$"; -> 1
@end example
@item @{1@}
@itemx @{2,3@}
@@ -53785,12 +57537,12 @@ literal @code{-} character, it must be written first or last. So
a defined meaning inside a @code{[]} pair has no special meaning and
matches only itself.
@example
-mysql> select "aXbc" REGEXP "[a-dXYZ]"; -> 1
-mysql> select "aXbc" REGEXP "^[a-dXYZ]$"; -> 0
-mysql> select "aXbc" REGEXP "^[a-dXYZ]+$"; -> 1
-mysql> select "aXbc" REGEXP "^[^a-dXYZ]+$"; -> 0
-mysql> select "gheis" REGEXP "^[^a-dXYZ]+$"; -> 1
-mysql> select "gheisa" REGEXP "^[^a-dXYZ]+$"; -> 0
+mysql> SELECT "aXbc" REGEXP "[a-dXYZ]"; -> 1
+mysql> SELECT "aXbc" REGEXP "^[a-dXYZ]$"; -> 0
+mysql> SELECT "aXbc" REGEXP "^[a-dXYZ]+$"; -> 1
+mysql> SELECT "aXbc" REGEXP "^[^a-dXYZ]+$"; -> 0
+mysql> SELECT "gheis" REGEXP "^[^a-dXYZ]+$"; -> 1
+mysql> SELECT "gheisa" REGEXP "^[^a-dXYZ]+$"; -> 0
@end example
@item [[.characters.]]
The sequence of characters of that collating element. The sequence is a
@@ -53814,7 +57566,8 @@ Within a bracket expression, the name of a character class enclosed in
@code{[:} and @code{:]} stands for the list of all characters belonging
to that class. Standard character class names are:
-@multitable @columnfractions .33 .33 .33
+@multitable @columnfractions .10 .10 .10
+@item @strong{Name} @tab @strong{Name} @tab @strong{Name}
@item alnum @tab digit @tab punct
@item alpha @tab graph @tab space
@item blank @tab lower @tab upper
@@ -53825,8 +57578,8 @@ These stand for the character classes defined in the @code{ctype(3)} manual
page. A locale may provide others. A character class may not be used as an
endpoint of a range.
@example
-mysql> select "justalnums" REGEXP "[[:alnum:]]+"; -> 1
-mysql> select "!!" REGEXP "[[:alnum:]]+"; -> 0
+mysql> SELECT "justalnums" REGEXP "[[:alnum:]]+"; -> 1
+mysql> SELECT "!!" REGEXP "[[:alnum:]]+"; -> 0
@end example
@item [[:<:]]
@@ -53837,90 +57590,20 @@ is neither preceded nor followed by word characters. A word character is
an alnum character (as defined by @code{ctype(3)}) or an underscore
(@code{_}).
@example
-mysql> select "a word a" REGEXP "[[:<:]]word[[:>:]]"; -> 1
-mysql> select "a xword a" REGEXP "[[:<:]]word[[:>:]]"; -> 0
+mysql> SELECT "a word a" REGEXP "[[:<:]]word[[:>:]]"; -> 1
+mysql> SELECT "a xword a" REGEXP "[[:<:]]word[[:>:]]"; -> 0
@end example
@end table
@example
-mysql> select "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1
+mysql> SELECT "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1
@end example
-@node Unireg, GPL license, Regexp, Top
-@appendix What is Unireg?
-
-@cindex Unireg, described
-@cindex interface builder
-
-Unireg is our tty interface builder, but it uses a low-level connection
-to our ISAM (which is used by MySQL) and because of this it is
-very quick. It has existed since 1979 (on Unix in C since ~1986).
-
-Unireg has the following components:
-
-@itemize @bullet
-@item
-One table viewer with updates/browsing.
-@item
-Multi table viewer (with one scrolling region).
-@item
-Table creator. (With lots of column tags you can't create with MySQL)
-This is WYSIWYG (for a tty). You design a screen and Unireg prompts for
-the column specification.
-@item
-Report generator.
-@item
-A lot of utilities (quick import/export of tables to/from text files,
-analysis of table contents...).
-@item
-Powerful multi-table updates (which we use a lot) with a BASIC-like
-language with LOTS of functions.
-@item
-Dynamic languages (at present in Swedish and Finnish). If somebody wants
-an English version there are a few files that would have to be translated.
-@item
-The ability to run updates interactively or in a batch.
-@item
-Emacs-like key definitions with keyboard macros.
-@item
-All this in a binary of 800K.
-@item
-The @code{convform} utility. Converts @file{.frm} and text files between
-different character sets.
-@item
-The @code{myisampack} utility. Packs an ISAM table (makes it 50-80%
-smaller). The table can be read by MySQL like an ordinary
-table. Only one record has to be decompressed per access. Cannot handle
-@code{BLOB} or @code{TEXT} columns or updates (yet).
-@end itemize
-
-We update most of our production databases with the Unireg interface and
-serve web pages through MySQL (and in some extreme cases the Unireg
-report generator).
-
-Unireg takes about 3M of disk space and works on at least the following
-platforms: SunOS 4.x, Solaris, Linux, HP-UX, ICL Unix, DNIX, SCO and
-MS-DOS.
-
-Unireg is currently only available in Swedish and Finnish.
-
-The price tag for Unireg is 10,000 Swedish kr (about $1500 US), but this
-includes support. Unireg is distributed as a binary. (But all the ISAM
-sources can be found in MySQL). Usually we compile the binary for the
-customer at their site.
-
-All new development is concentrated to MySQL.
-
-@page
-@c This node name is special
-
-
-
-@node GPL license, LGPL license, Unireg, Top
-@appendix GNU GENERAL PUBLIC LICENSE
+@node GPL license, LGPL license, Regexp, Top
+@appendix GNU General Public License
@cindex GPL, General Public License
@cindex GPL, GNU General Public License
@@ -54087,7 +57770,7 @@ source code, which must be distributed under the terms of Sections
@item
Accompany it with a written offer, valid for at least three
-years, to give any third party, for a charge no more than your
+years, to give any third-party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
@@ -54320,11 +58003,13 @@ Public License instead of this License.
-@node LGPL license, Placeholder, GPL license, Top
-@appendix GNU LESSER GENERAL PUBLIC LICENSE
+@node LGPL license, Function Index, GPL license, Top
+@appendix GNU Lesser General Public License
-@cindex LGPL, Lesser General Public License
+@cindex LGPL, Library General Public License
@cindex LGPL, GNU Library General Public License
+@cindex LGPL, Lesser General Public License
+@cindex LGPL, GNU Lesser General Public License
@center Version 2.1, February 1999
@@ -54614,7 +58299,7 @@ Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
+whether they are linked directly with the Library itself.
@item
As an exception to the Sections above, you may also combine or
@@ -54648,7 +58333,7 @@ to use the modified definitions.)
@item
Use a suitable shared library mechanism for linking with the Library. A
-suitable mechanism is one that (1) uses at run time a copy of the
+suitable mechanism is one that (1) uses at runtime a copy of the
library already present on the user's computer system, rather than
copying library functions into the executable, and (2) will operate
properly with a modified version of the library, if the user installs
@@ -54891,690 +58576,7 @@ That's all there is to it!
-@node Placeholder, Function Index, LGPL license, Top
-@appendix Pieces of the manual in transit
-
-@menu
-* Installing binary:: Installing a MySQL Binary Distribution
-* Perl support:: Perl Installation Comments
-* Group by functions:: Functions for Use with @code{GROUP BY} Clauses
-@end menu
-
-
-@node Installing binary, Perl support, Placeholder, Placeholder
-@appendixsec Installing a MySQL Binary Distribution
-
-@cindex installing, binary distribution
-@cindex binary distributions, installing
-
-@menu
-* Linux-RPM:: Linux RPM files
-* Building clients:: Building client programs
-@end menu
-
-You need the following tools to install a MySQL binary distribution:
-
-@itemize @bullet
-@item
-GNU @code{gunzip} to uncompress the distribution.
-
-@item
-A reasonable @code{tar} to unpack the distribution. GNU @code{tar} is
-known to work. Sun @code{tar} is known to have problems.
-@end itemize
-
-@cindex RPM, defined
-@cindex RedHat Package Manager
-An alternative installation method under Linux is to use RPM (RedHat Package
-Manager) distributions. @xref{Linux-RPM}.
-
-@c texi2html fails to split chapters if I use strong for all of this.
-If you run into problems, @strong{PLEASE ALWAYS USE} @code{mysqlbug} when
-posting questions to @email{mysql@@lists.mysql.com}. Even if the problem
-isn't a bug, @code{mysqlbug} gathers system information that will help others
-solve your problem. By not using @code{mysqlbug}, you lessen the likelihood
-of getting a solution to your problem! You will find @code{mysqlbug} in the
-@file{bin} directory after you unpack the distribution. @xref{Bug reports}.
-
-@cindex commands, for binary distribution
-The basic commands you must execute to install and use a MySQL
-binary distribution are:
-
-@example
-shell> groupadd mysql
-shell> useradd -g mysql mysql
-shell> cd /usr/local
-shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
-shell> ln -s mysql-VERSION-OS mysql
-shell> cd mysql
-shell> scripts/mysql_install_db
-shell> chown -R root /usr/local/mysql
-shell> chown -R mysql /usr/local/mysql/data
-shell> chgrp -R mysql /usr/local/mysql
-shell> chown -R root /usr/local/mysql/bin
-shell> bin/safe_mysqld --user=mysql &
-@end example
-
-@cindex adding, new users
-@cindex new users, adding
-@cindex users, adding
-
-You can add new users using the @code{bin/mysql_setpermission} script if
-you install the @code{DBI} and @code{Msql-Mysql-modules} Perl modules.
-
-A more detailed description follows.
-
-To install a binary distribution, follow the steps below, then proceed
-to @ref{Post-installation}, for post-installation setup and testing:
-
-@enumerate
-@item
-Pick the directory under which you want to unpack the distribution, and move
-into it. In the example below, we unpack the distribution under
-@file{/usr/local} and create a directory @file{/usr/local/mysql} into which
-MySQL is installed. (The following instructions therefore assume
-you have permission to create files in @file{/usr/local}. If that directory
-is protected, you will need to perform the installation as @code{root}.)
-
-@item
-Obtain a distribution file from one of the sites listed in
-@ref{Getting MySQL, , Getting MySQL}.
-
-MySQL binary distributions are provided as compressed @code{tar}
-archives and have names like @file{mysql-VERSION-OS.tar.gz}, where
-@code{VERSION} is a number (for example, @code{3.21.15}), and @code{OS}
-indicates the type of operating system for which the distribution is intended
-(for example, @code{pc-linux-gnu-i586}).
-
-@item
-If you see a binary distribution marked with the @code{-max} prefix, this
-means that the binary has support for transaction-safe tables and other
-features. @xref{mysqld-max, , @code{mysqld-max}}. Note that all binaries
-are built from the same MySQL source distribution.
-
-@item
-Add a user and group for @code{mysqld} to run as:
-
-@example
-shell> groupadd mysql
-shell> useradd -g mysql mysql
-@end example
-
-These commands add the @code{mysql} group and the @code{mysql} user. The
-syntax for @code{useradd} and @code{groupadd} may differ slightly on different
-versions of Unix. They may also be called @code{adduser} and @code{addgroup}.
-You may wish to call the user and group something else instead of @code{mysql}.
-
-@item
-Change into the intended installation directory:
-
-@example
-shell> cd /usr/local
-@end example
-
-@item
-Unpack the distribution and create the installation directory:
-
-@example
-shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
-shell> ln -s mysql-VERSION-OS mysql
-@end example
-
-The first command creates a directory named @file{mysql-VERSION-OS}. The
-second command makes a symbolic link to that directory. This lets you refer
-more easily to the installation directory as @file{/usr/local/mysql}.
-
-@item
-Change into the installation directory:
-
-@example
-shell> cd mysql
-@end example
-
-You will find several files and subdirectories in the @code{mysql} directory.
-The most important for installation purposes are the @file{bin} and
-@file{scripts} subdirectories.
-
-@table @file
-@item bin
-@tindex PATH environment variable
-@tindex environment variable, PATH
-This directory contains client programs and the server
-You should add the full pathname of this directory to your
-@code{PATH} environment variable so that your shell finds the MySQL
-programs properly. @xref{Environment variables}.
-
-@item scripts
-This directory contains the @code{mysql_install_db} script used to initialize
-the @code{mysql} database containing the grant tables that store the server
-access permissions.
-@end table
-
-@item
-If you would like to use @code{mysqlaccess} and have the MySQL
-distribution in some non-standard place, you must change the location where
-@code{mysqlaccess} expects to find the @code{mysql} client. Edit the
-@file{bin/mysqlaccess} script at approximately line 18. Search for a line
-that looks like this:
-
-@example
-$MYSQL = '/usr/local/bin/mysql'; # path to mysql executable
-@end example
-
-Change the path to reflect the location where @code{mysql} actually is
-stored on your system. If you do not do this, you will get a @code{Broken
-pipe} error when you run @code{mysqlaccess}.
-
-@item
-Create the MySQL grant tables (necessary only if you haven't
-installed MySQL before):
-@example
-shell> scripts/mysql_install_db
-@end example
-
-Note that MySQL versions older than Version 3.22.10 started the
-MySQL server when you run @code{mysql_install_db}. This is no
-longer true!
-
-@item
-Change ownership of binaries to @code{root} and ownership of the data
-directory to the user that you will run @code{mysqld} as:
-
-@example
-shell> chown -R root /usr/local/mysql
-shell> chown -R mysql /usr/local/mysql/data
-shell> chgrp -R mysql /usr/local/mysql
-@end example
-
-The first command changes the @code{owner} attribute of the files to the
-@code{root} user, the second one changes the @code{owner} attribute of the
-data directory to the @code{mysql} user, and the third one changes the
-@code{group} attribute to the @code{mysql} group.
-
-@item
-If you want to install support for the Perl @code{DBI}/@code{DBD} interface,
-see @ref{Perl support}.
-
-@item
-If you would like MySQL to start automatically when you boot your
-machine, you can copy @code{support-files/mysql.server} to the location where
-your system has its startup files. More information can be found in the
-@code{support-files/mysql.server} script itself and in
-@ref{Automatic start}.
-
-@end enumerate
-
-After everything has been unpacked and installed, you should initialize
-and test your distribution.
-
-You can start the MySQL server with the following command:
-
-@example
-shell> bin/safe_mysqld --user=mysql &
-@end example
-
-@xref{safe_mysqld, , @code{safe_mysqld}}.
-
-@xref{Post-installation}.
-
-
-
-
-
-
-
-@node Perl support, Group by functions, Installing binary, Placeholder
-@appendixsec Perl Installation Comments
-
-@cindex Perl, installing
-@cindex installing, Perl
-
-@menu
-* Perl installation:: Installing Perl on Unix
-* ActiveState Perl:: Installing ActiveState Perl on Windows
-* Windows Perl:: Installing the MySQL Perl distribution on Windows
-* Perl support problems:: Problems using the Perl @code{DBI}/@code{DBD} interface
-@end menu
-
-
-@node Perl installation, ActiveState Perl, Perl support, Perl support
-@appendixsubsec Installing Perl on Unix
-
-Perl support for MySQL is provided by means of the
-@code{DBI}/@code{DBD} client interface. @xref{Perl}. The Perl
-@code{DBD}/@code{DBI} client code requires Perl Version 5.004 or later. The
-interface @strong{will not work} if you have an older version of Perl.
-
-MySQL Perl support also requires that you've installed
-MySQL client programming support. If you installed MySQL
-from RPM files, client programs are in the client RPM, but client programming
-support is in the developer RPM. Make sure you've installed the latter RPM.
-
-As of Version 3.22.8, Perl support is distributed separately from the main
-MySQL distribution. If you want to install Perl support, the files
-you will need can be obtained from
-@uref{http://www.mysql.com/Downloads/Contrib/}.
-
-The Perl distributions are provided as compressed @code{tar} archives and
-have names like @file{MODULE-VERSION.tar.gz}, where @code{MODULE} is the
-module name and @code{VERSION} is the version number. You should get the
-@code{Data-Dumper}, @code{DBI}, and @code{Msql-Mysql-modules} distributions
-and install them in that order. The installation procedure is shown below.
-The example shown is for the @code{Data-Dumper} module, but the procedure is
-the same for all three distributions:
-
-@enumerate
-@item
-Unpack the distribution into the current directory:
-@example
-shell> gunzip < Data-Dumper-VERSION.tar.gz | tar xvf -
-@end example
-This command creates a directory named @file{Data-Dumper-VERSION}.
-
-@item
-Change into the top-level directory of the unpacked distribution:
-@example
-shell> cd Data-Dumper-VERSION
-@end example
-
-@item
-Build the distribution and compile everything:
-@example
-shell> perl Makefile.PL
-shell> make
-shell> make test
-shell> make install
-@end example
-@end enumerate
-
-The @code{make test} command is important because it verifies that the
-module is working. Note that when you run that command during the
-@code{Msql-Mysql-modules} installation to exercise the interface code, the
-MySQL server must be running or the test will fail.
-
-It is a good idea to rebuild and reinstall the @code{Msql-Mysql-modules}
-distribution whenever you install a new release of MySQL,
-particularly if you notice symptoms such as all your @code{DBI} scripts
-dumping core after you upgrade MySQL.
-
-If you don't have the right to install Perl modules in the system directory
-or if you to install local Perl modules, the following reference may help
-you:
-
-@example
-@uref{http://www.iserver.com/support/contrib/perl5/modules.html}
-@end example
-
-Look under the heading
-@code{Installing New Modules that Require Locally Installed Modules}.
-
-
-@node ActiveState Perl, Windows Perl, Perl installation, Perl support
-@appendixsubsec Installing ActiveState Perl on Windows
-
-@cindex installing, Perl on Windows
-@cindex Perl, installing on Windows
-@cindex ActiveState Perl
-
-To install the MySQL @code{DBD} module with ActiveState Perl on
-Windows, you should do the following:
-
-@itemize @bullet
-@item
-Get ActiveState Perl from
-@uref{http://www.activestate.com/Products/ActivePerl/index.html}
-and install it.
-
-@item
-Open a DOS shell.
-
-@item
-If required, set the HTTP_proxy variable. For example, you might try:
-
-@example
-set HTTP_proxy=my.proxy.com:3128
-@end example
-
-@item
-Start the PPM program:
-
-@example
-C:\> c:\perl\bin\ppm.pl
-@end example
-
-@item
-If you have not already done so, install @code{DBI}:
-
-@example
-ppm> install DBI
-@end example
-
-@item
-If this succeeds, run the following command:
-
-@example
-install ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd
-@end example
-@end itemize
-
-The above should work at least with ActiveState Perl Version 5.6.
-
-If you can't get the above to work, you should instead install the
-@strong{MyODBC} driver and connect to MySQL server through
-ODBC:
-
-@example
-use DBI;
-$dbh= DBI->connect("DBI:ODBC:$dsn","$user","$password") ||
- die "Got error $DBI::errstr when connecting to $dsn\n";
-@end example
-
-
-@node Windows Perl, Perl support problems, ActiveState Perl, Perl support
-@appendixsubsec Installing the MySQL Perl Distribution on Windows
-
-The MySQL Perl distribution contains @code{DBI},
-@code{DBD:MySQL} and @code{DBD:ODBC}.
-
-@itemize @bullet
-@item
-Get the Perl distribution for Windows from
-@uref{http://www.mysql.com/download.html}.
-
-@item
-Unzip the distribution in @code{C:} so that you get a @file{C:\PERL} directory.
-
-@item
-Add the directory @file{C:\PERL\BIN} to your path.
-
-@item
-Add the directory @file{C:\PERL\BIN\MSWIN32-x86-thread} or
-@file{C:\PERL\BIN\MSWIN32-x86} to your path.
-
-@item
-Test that @code{perl} works by executing @code{perl -v} in a DOS shell.
-@end itemize
-
-
-@node Perl support problems, , Windows Perl, Perl support
-@appendixsubsec Problems Using the Perl @code{DBI}/@code{DBD} Interface
-
-@cindex problems, installing Perl
-@cindex Perl DBI/DBD, installation problems
-
-If Perl reports that it can't find the @file{../mysql/mysql.so} module,
-then the problem is probably that Perl can't locate the shared library
-@file{libmysqlclient.so}.
-
-You can fix this by any of the following methods:
-
-@itemize @bullet
-@item
-Compile the @code{Msql-Mysql-modules} distribution with @code{perl
-Makefile.PL -static -config} rather than @code{perl Makefile.PL}.
-
-@item
-Copy @code{libmysqlclient.so} to the directory where your other shared
-libraries are located (probably @file{/usr/lib} or @file{/lib}).
-
-@item
-On Linux you can add the pathname of the directory where
-@file{libmysqlclient.so} is located to the @file{/etc/ld.so.conf} file.
-
-@tindex LD_RUN_PATH environment variable
-@tindex Environment variable, LD_RUN_PATH
-@item
-Add the pathname of the directory where @file{libmysqlclient.so} is located
-to the @code{LD_RUN_PATH} environment variable.
-@end itemize
-
-If you get the following errors from @code{DBD-mysql},
-you are probably using @code{gcc} (or using an old binary compiled with
-@code{gcc}):
-
-@example
-/usr/bin/perl: can't resolve symbol '__moddi3'
-/usr/bin/perl: can't resolve symbol '__divdi3'
-@end example
-
-Add @code{-L/usr/lib/gcc-lib/... -lgcc} to the link command when the
-@file{mysql.so} library gets built (check the output from @code{make} for
-@file{mysql.so} when you compile the Perl client). The @code{-L} option
-should specify the pathname of the directory where @file{libgcc.a} is located
-on your system.
-
-Another cause of this problem may be that Perl and MySQL aren't both
-compiled with @code{gcc}. In this case, you can solve the mismatch by
-compiling both with @code{gcc}.
-
-If you get the following error from @code{Msql-Mysql-modules}
-when you run the tests:
-
-@example
-t/00base............install_driver(mysql) failed: Can't load '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql: ../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: uncompress at /usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
-@end example
-
-it means that you need to include the compression library, -lz, to the
-link line. This can be doing the following change in the file
-@file{lib/DBD/mysql/Install.pm}:
-
-@example
-$sysliblist .= " -lm";
-
-to
-
-$sysliblist .= " -lm -lz";
-@end example
-
-After this, you MUST run 'make realclean' and then proceed with the
-installation from the beginning.
-
-If you want to use the Perl module on a system that doesn't support dynamic
-linking (like SCO) you can generate a static version of Perl that includes
-@code{DBI} and @code{DBD-mysql}. The way this works is that you generate a
-version of Perl with the @code{DBI} code linked in and install it on top of
-your current Perl. Then you use that to build a version of Perl that
-additionally has the @code{DBD} code linked in, and install that.
-
-On SCO, you must have the following environment variables set:
-
-@example
-shell> LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib
-or
-shell> LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
-shell> LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
-shell> MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:/usr/skunk/man:
-@end example
-
-First, create a Perl that includes a statically linked @code{DBI} by running
-these commands in the directory where your @code{DBI} distribution is
-located:
-
-@example
-shell> perl Makefile.PL -static -config
-shell> make
-shell> make install
-shell> make perl
-@end example
-
-Then you must install the new Perl. The output of @code{make perl} will
-indicate the exact @code{make} command you will need to execute to perform
-the installation. On SCO, this is @code{make -f Makefile.aperl inst_perl
-MAP_TARGET=perl}.
-
-Next, use the just-created Perl to create another Perl that also includes a
-statically-linked @code{DBD::mysql} by running these commands in the
-directory where your @code{Msql-Mysql-modules} distribution is located:
-
-@example
-shell> perl Makefile.PL -static -config
-shell> make
-shell> make install
-shell> make perl
-@end example
-
-Finally, you should install this new Perl. Again, the output of @code{make
-perl} indicates the command to use.
-
-
-@node Group by functions, , Perl support, Placeholder
-@appendixsec Functions for Use with @code{GROUP BY} Clauses
-
-@findex GROUP BY functions
-@findex functions, GROUP BY
-
-If you use a group function in a statement containing no @code{GROUP BY}
-clause, it is equivalent to grouping on all rows.
-
-@table @code
-@findex COUNT()
-@item COUNT(expr)
-Returns a count of the number of non-@code{NULL} values in the rows
-retrieved by a @code{SELECT} statement:
-
-@example
-mysql> select student.student_name,COUNT(*)
- from student,course
- where student.student_id=course.student_id
- GROUP BY student_name;
-
-@end example
-
-@code{COUNT(*)} is somewhat different in that it returns a count of
-the number of rows retrieved, whether or not they contain @code{NULL}
-values.
-
-@code{COUNT(*)} is optimized to
-return very quickly if the @code{SELECT} retrieves from one table, no
-other columns are retrieved, and there is no @code{WHERE} clause.
-For example:
-
-@example
-mysql> select COUNT(*) from student;
-@end example
-
-@findex COUNT(DISTINCT)
-@findex DISTINCT
-@item COUNT(DISTINCT expr,[expr...])
-Returns a count of the number of different non-@code{NULL} values:
-
-@example
-mysql> select COUNT(DISTINCT results) from student;
-@end example
-
-In MySQL you can get the number of distinct expression
-combinations that don't contain NULL by giving a list of expressions.
-In ANSI SQL you would have to do a concatenation of all expressions
-inside @code{CODE(DISTINCT ..)}.
-
-@findex AVG()
-@item AVG(expr)
-Returns the average value of @code{expr}:
-
-@example
-mysql> select student_name, AVG(test_score)
- from student
- GROUP BY student_name;
-@end example
-
-@findex MIN()
-@findex MAX()
-@item MIN(expr)
-@itemx MAX(expr)
-Returns the minimum or maximum value of @code{expr}. @code{MIN()} and
-@code{MAX()} may take a string argument; in such cases they return the
-minimum or maximum string value. @xref{MySQL indexes}.
-
-@example
-mysql> select student_name, MIN(test_score), MAX(test_score)
- from student
- GROUP BY student_name;
-@end example
-
-@findex SUM()
-@item SUM(expr)
-Returns the sum of @code{expr}. Note that if the return set has no rows,
-it returns NULL!
-
-@findex STD()
-@findex STDDEV()
-@cindex Oracle compatibility
-@cindex compatibility, with Oracle
-@item STD(expr)
-@itemx STDDEV(expr)
-Returns the standard deviation of @code{expr}. This is an extension to
-ANSI SQL. The @code{STDDEV()} form of this function is provided for Oracle
-compatibility.
-
-@findex BIT_OR()
-@item BIT_OR(expr)
-Returns the bitwise @code{OR} of all bits in @code{expr}. The calculation is
-performed with 64-bit (@code{BIGINT}) precision.
-
-@findex BIT_AND()
-@item BIT_AND(expr)
-Returns the bitwise @code{AND} of all bits in @code{expr}. The calculation is
-performed with 64-bit (@code{BIGINT}) precision.
-@end table
-
-@cindex @code{GROUP BY}, extensions to ANSI SQL
-MySQL has extended the use of @code{GROUP BY}. You can use columns or
-calculations in the @code{SELECT} expressions that don't appear in
-the @code{GROUP BY} part. This stands for @emph{any possible value for this
-group}. You can use this to get better performance by avoiding sorting and
-grouping on unnecessary items. For example, you don't need to group on
-@code{customer.name} in the following query:
-
-@example
-mysql> select order.custid,customer.name,max(payments)
- from order,customer
- where order.custid = customer.custid
- GROUP BY order.custid;
-@end example
-
-In ANSI SQL, you would have to add @code{customer.name} to the @code{GROUP
-BY} clause. In MySQL, the name is redundant if you don't run in
-ANSI mode.
-
-@strong{Don't use this feature} if the columns you omit from the
-@code{GROUP BY} part aren't unique in the group! You will get
-unpredictable results.
-
-In some cases, you can use @code{MIN()} and @code{MAX()} to obtain a specific
-column value even if it isn't unique. The following gives the value of
-@code{column} from the row containing the smallest value in the @code{sort}
-column:
-
-@example
-substr(MIN(concat(rpad(sort,6,' '),column)),7)
-@end example
-
-@xref{example-Maximum-column-group-row}.
-
-@cindex @code{ORDER BY}, aliases in
-@cindex aliases, in @code{ORDER BY} clauses
-@cindex @code{GROUP BY}, aliases in
-@cindex aliases, in @code{GROUP BY} clauses
-@cindex expression aliases
-@cindex aliases, for expressions
-Note that if you are using MySQL Version 3.22 (or earlier) or if
-you are trying to follow ANSI SQL, you can't use expressions in @code{GROUP
-BY} or @code{ORDER BY} clauses. You can work around this limitation by
-using an alias for the expression:
-
-@example
-mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name
- GROUP BY id,val ORDER BY val;
-@end example
-
-In MySQL Version 3.23 you can do:
-
-@example
-mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();
-@end example
-
-
-@node Function Index, Concept Index, Placeholder, Top
+@node Function Index, Concept Index, LGPL license, Top
@unnumbered SQL command, type and function index
@printindex fn
diff --git a/Docs/mirrors.texi b/Docs/mirrors.texi
new file mode 100644
index 00000000000..651963c57c3
--- /dev/null
+++ b/Docs/mirrors.texi
@@ -0,0 +1,446 @@
+@strong{Europe:}
+
+@itemize @bullet
+
+@item
+@image{Flags/armenia} Armenia [AbideWeb Technologies] @@
+WWW (@uref{http://mysql.abideweb.com/})
+FTP (@uref{ftp://mysql.abideweb.com/mirrors/MySQL/})
+
+@item
+@image{Flags/austria} Austria [Univ. of Technology/Vienna] @@
+WWW (@uref{http://gd.tuwien.ac.at/db/mysql/})
+FTP (@uref{ftp://gd.tuwien.ac.at/db/mysql/})
+
+@item
+@image{Flags/belgium} Belgium [BELNET] @@
+WWW (@uref{http://mysql.belnet.be/})
+FTP (@uref{ftp://ftp.belnet.be/mirror/ftp.mysql.com/pub/mysql/})
+
+@item
+@image{Flags/bulgaria} Bulgaria [online.bg/Sofia] @@
+WWW (@uref{http://mysql.online.bg/})
+FTP (@uref{ftp://mysql.online.bg/})
+
+@item
+@image{Flags/czech-republic} Czech Republic [Masaryk University in Brno] @@
+WWW (@uref{http://mysql.linux.cz/})
+FTP (@uref{ftp://ftp.fi.muni.cz/pub/mysql/})
+
+@item
+@image{Flags/czech-republic} Czech Republic [www.gin.cz] @@
+WWW (@uref{http://mysql.gin.cz/})
+FTP (@uref{ftp://ftp.gin.cz/pub/MIRRORS/www.mysql.com/})
+
+@item
+@image{Flags/czech-republic} Czech Republic [www.sopik.cz] @@
+WWW (@uref{http://www.mysql.cz/})
+
+@item
+@image{Flags/denmark} Denmark [Borsen] @@
+WWW (@uref{http://mysql.borsen.dk/})
+
+@item
+@image{Flags/denmark} Denmark [Cybercity Internet] @@
+WWW (@uref{http://mysql.mirrors.cybercity.dk/})
+
+@item
+@image{Flags/denmark} Denmark [SunSITE] @@
+WWW (@uref{http://mirrors.sunsite.dk/mysql/})
+FTP (@uref{ftp://sunsite.dk/mirrors/mysql/})
+
+@item
+@image{Flags/estonia} Estonia [OK Interactive] @@
+WWW (@uref{http://mysql.mirror.ok.ee/})
+
+@item
+@image{Flags/finland} Finland [KPNQwest] @@
+WWW (@uref{http://mysql.kpnqwest.fi/})
+
+@item
+@image{Flags/finland} Finland [Mediatraffic] @@
+WWW (@uref{http://mysql.mediatraffic.fi/})
+
+@item
+@image{Flags/finland} Finland [tonnikala.net] @@
+WWW (@uref{http://mysql.tonnikala.org/})
+
+@item
+@image{Flags/france} France [free.fr] @@
+WWW (@uref{http://mysql-mirror.free.fr/})
+FTP (@uref{ftp://ftp.free.fr/pub/MySQL/})
+
+@item
+@image{Flags/france} France [mir2.ovh.net/] @@
+WWW (@uref{http://mir2.ovh.net/ftp.mysql.com/})
+FTP (@uref{ftp://mir1.ovh.net/ftp.mysql.com/})
+
+@item
+@image{Flags/france} France [Netsample] @@
+WWW (@uref{http://www.mysql.netsample.com/})
+
+@item
+@image{Flags/france} France [Universite Paris 10] @@
+WWW (@uref{http://ftp.u-paris10.fr/mysql.com})
+FTP (@uref{ftp://ftp.u-paris10.fr/mysql.com})
+
+@item
+@image{Flags/germany} Germany [GWDG] @@
+WWW (@uref{http://ftp.gwdg.de/pub/misc/mysql/})
+FTP (@uref{ftp://ftp.gwdg.de/pub/misc/mysql/})
+
+@item
+@image{Flags/germany} Germany [SunSITE Central Europe] @@
+WWW (@uref{http://sunsite.informatik.rwth-aachen.de/mysql/})
+FTP (@uref{ftp://sunsite.informatik.rwth-aachen.de/pub/mirror/www.mysql.com/})
+
+@item
+@image{Flags/germany} Germany [Tiscali] @@
+WWW (@uref{http://filepile.tiscali.de/mirror/mysql/})
+FTP (@uref{ftp://filepile.tiscali.de/mirror/mysql/})
+
+@item
+@image{Flags/germany} Germany [Wolfenbuettel] @@
+WWW (@uref{http://www.fh-wolfenbuettel.de/ftp/pub/database/mysql/})
+FTP (@uref{ftp://ftp.fh-wolfenbuettel.de/pub/database/mysql/})
+
+@item
+@image{Flags/greece} Greece [NTUA, Athens] @@
+WWW (@uref{http://www.ntua.gr/mysql/})
+FTP (@uref{ftp://ftp.ntua.gr/pub/databases/mysql/})
+
+@item
+@image{Flags/hungary} Hungary [stop.hu] @@
+WWW (@uref{http://mysql.mirror.stop.hu/})
+
+@item
+@image{Flags/hungary} Hungary [TiszaneT] @@
+WWW (@uref{http://mysql.tiszanet.hu/})
+FTP (@uref{ftp://mysql.tiszanet.hu/pub/mirrors/mysql/})
+
+@item
+@image{Flags/hungary} Hungary [Xenia] @@
+WWW (@uref{http://mysql.sote.hu/})
+FTP (@uref{ftp://xenia.sote.hu/pub/mirrors/www.mysql.com/})
+
+@item
+@image{Flags/iceland} Iceland [Tvíund] @@
+WWW (@uref{http://mysql.tviund.is/})
+
+@item
+@image{Flags/ireland} Ireland [Esat Net] @@
+WWW (@uref{http://ftp.esat.net/mirrors/download.sourceforge.net/pub/mirrors/mysql/})
+FTP (@uref{ftp://ftp.esat.net/mirrors/download.sourceforge.net/pub/mirrors/mysql/})
+
+@item
+@image{Flags/ireland} Ireland [MD NMTB Media] @@
+WWW (@uref{http://mirrors.nmtbmedia.com/mysql/})
+
+@item
+@image{Flags/israel} Israel [fresh.co.il] @@
+WWW (@uref{http://mysql.fresh.co.il/})
+
+@item
+@image{Flags/italy} Italy [feelinglinux.com] @@
+WWW (@uref{http://mysql.feelinglinux.com/})
+
+@item
+@image{Flags/italy} Italy [Teta Srl] @@
+WWW (@uref{http://www.teta.it/mysql/})
+
+@item
+@image{Flags/italy} Italy [tzone.it] @@
+WWW (@uref{http://mysql.tzone.it/})
+
+@item
+@image{Flags/latvia} Latvia [linux.lv] @@
+FTP (@uref{ftp://ftp.linux.lv/pub/software/mysql/})
+
+@item
+@image{Flags/netherlands} Netherlands [OMS-Net] @@
+WWW (@uref{http://mysql.oms-net.nl/})
+
+@item
+@image{Flags/netherlands} Netherlands [ProServe] @@
+WWW (@uref{http://mysql.proserve.nl/})
+
+@item
+@image{Flags/netherlands} Netherlands [WideXS BV] @@
+WWW (@uref{http://mysql.mirror.widexs.nl/})
+FTP (@uref{ftp://mirror.widexs.nl/pub/mysql/})
+
+@item
+@image{Flags/norway} Norway [Brainpeddlers AS] @@
+WWW (@uref{http://mysql.brainpeddlers.com/})
+
+@item
+@image{Flags/poland} Poland [ncservice.com/Gdansk] @@
+WWW (@uref{http://mysql.service.net.pl/})
+
+@item
+@image{Flags/poland} Poland [SunSITE] @@
+WWW (@uref{http://sunsite.icm.edu.pl/mysql/})
+FTP (@uref{ftp://sunsite.icm.edu.pl/pub/unix/mysql/})
+
+@item
+@image{Flags/portugal} Portugal [Instituto Supertior Técnico] @@
+WWW (@uref{http://darkstar.ist.utl.pt/mysql/})
+FTP (@uref{ftp://darkstar.ist.utl.pt/pub/mysql/})
+
+@item
+@image{Flags/portugal} Portugal [Netvisão] @@
+WWW (@uref{http://mysql.netvisao.pt/})
+FTP (@uref{ftp://mirrors2.netvisao.pt/pub/mysql/})
+
+@item
+@image{Flags/portugal} Portugal [VIZZAVI] @@
+WWW (@uref{http://ftp.vizzavi.pt/pub/mysql/})
+FTP (@uref{ftp://ftp.vizzavi.pt/pub/mysql/})
+
+@item
+@image{Flags/romania} Romania [roedu.net/Bucharest] @@
+FTP (@uref{ftp://ftp.roedu.net/pub/mirrors/ftp.mysql.com/})
+
+@item
+@image{Flags/russia} Russia [DirectNet] @@
+WWW (@uref{http://mysql.directnet.ru/})
+FTP (@uref{ftp://ftp.dn.ru/pub/MySQL/})
+
+@item
+@image{Flags/russia} Russia [Scientific Center/Chernogolovka] @@
+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
+@image{Flags/sweden} Sweden [Sunet] @@
+WWW (@uref{http://ftp.sunet.se/pub/unix/databases/relational/mysql/})
+FTP (@uref{ftp://ftp.sunet.se/pub/unix/databases/relational/mysql/})
+
+@item
+@image{Flags/switzerland} Switzerland [SunSITE] @@
+WWW (@uref{http://sunsite.cnlab-switch.ch/ftp/mirror/mysql/})
+FTP (@uref{ftp://sunsite.cnlab-switch.ch/mirror/mysql/})
+
+@item
+@image{Flags/turkey} Turkey [proGEN] @@
+WWW (@uref{http://mysql.progen.com.tr/})
+
+@item
+@image{Flags/turkey} Turkey [Turkish National Academic Network & Information Center] @@
+WWW (@uref{http://mysql.ulak.net.tr/})
+
+@item
+@image{Flags/great-britain} UK [PLiG/UK] @@
+WWW (@uref{http://ftp.plig.org/pub/mysql/})
+FTP (@uref{ftp://ftp.plig.org/pub/mysql/})
+
+@item
+@image{Flags/ukraine} Ukraine [ISP Alkar Teleport/Dnepropetrovsk] @@
+WWW (@uref{http://mysql.dp.ua/})
+FTP (@uref{ftp://ftp.tlk-l.net/pub/mirrors/mysql.com/})
+
+@item
+@image{Flags/ukraine} Ukraine [PACO] @@
+WWW (@uref{http://mysql.paco.net.ua/})
+FTP (@uref{ftp://mysql.paco.net.ua/})
+
+@item
+@image{Flags/yugoslavia} Yugoslavia [Open Source Network of Yugoslavia] @@
+WWW (@uref{http://mysql.boa.org.yu/})
+FTP (@uref{ftp://ftp.linux.org.yu/pub/MySQL/})
+
+@end itemize
+
+@strong{North America:}
+
+@itemize @bullet
+
+@item
+@image{Flags/canada} Canada [Tryc] @@
+WWW (@uref{http://web.tryc.on.ca/mysql/})
+
+@item
+@image{Flags/mexico} Mexico [UAM] @@
+WWW (@uref{http://mysql.azc.uam.mx/})
+FTP (@uref{ftp://mysql.azc.uam.mx/mirrors/mysql/})
+
+@item
+@image{Flags/mexico} Mexico [UNAM] @@
+WWW (@uref{http://mysql.unam.mx/})
+FTP (@uref{ftp://mysql.unam.mx/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [adgrafix.com / Boston, MA] @@
+WWW (@uref{http://mysql.adgrafix.com/})
+
+@item
+@image{Flags/usa} USA [Argonne National Laboratory / Chicago, IL] @@
+FTP (@uref{ftp://mirror.mcs.anl.gov/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [Hurricane Electric / San Jose, CA] @@
+WWW (@uref{http://mysql.he.net/})
+
+@item
+@image{Flags/usa} USA [netNumina / Cambridge, MA] @@
+WWW (@uref{http://mysql.mirrors.netnumina.com/})
+
+@item
+@image{Flags/usa} USA [NIXC / Vienna, VA] @@
+WWW (@uref{http://mysql.nixc.net/})
+FTP (@uref{ftp://mysql.nixc.net/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [Oregon State University / Corvallis, OR] @@
+WWW (@uref{http://mysql.orst.edu/})
+FTP (@uref{ftp://ftp.orst.edu/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [University of Wisconsin / Wisconsin] @@
+WWW (@uref{http://mirror.sit.wisc.edu/mysql/})
+FTP (@uref{ftp://mirror.sit.wisc.edu/mirrors/mysql/})
+
+@item
+@image{Flags/usa} USA [UUNet] @@
+WWW (@uref{http://mysql.secsup.org/})
+FTP (@uref{ftp://mysql.secsup.org/pub/software/mysql/})
+
+@end itemize
+
+@strong{South America:}
+
+@itemize @bullet
+
+@item
+@image{Flags/argentina} Argentina [bannerlandia.com] @@
+WWW (@uref{http://mysql.bannerlandia.com.ar/})
+FTP (@uref{ftp://mysql.bannerlandia.com.ar/mirrors/mysql/})
+
+@item
+@image{Flags/chile} Chile [PSINet] @@
+WWW (@uref{http://mysql.psinet.cl/})
+FTP (@uref{ftp://ftp.psinet.cl/pub/database/mysql/})
+
+@item
+@image{Flags/chile} Chile [Tecnoera] @@
+WWW (@uref{http://mysql.tecnoera.com/})
+
+@item
+@image{Flags/chile} Chile [Vision] @@
+WWW (@uref{http://mysql.vision.cl/})
+
+@item
+@image{Flags/costa-rica} Costa Rica [Ogmios Communications] @@
+WWW (@uref{http://mysql.ogmios.co.cr/})
+FTP (@uref{ftp://mysql.ogmios.co.cr/pub/mysql/})
+
+@end itemize
+
+@strong{Asia:}
+
+@itemize @bullet
+
+@item
+@image{Flags/china} China [HKLPG/Hong Kong] @@
+WWW (@uref{http://mysql.hklpg.org/})
+
+@item
+@image{Flags/china} China [linuxforum.net] @@
+FTP (@uref{http://www2.linuxforum.net/mirror/mysql/})
+
+@item
+@image{Flags/china} China [shellhung.org/Hong Kong] @@
+WWW (@uref{http://mysql.shellhung.org/})
+FTP (@uref{ftp://ftp.shellhung.org/pub/Mirror/mysql/})
+
+@item
+@image{Flags/indonesia} Indonesia [CBN] @@
+WWW (@uref{http://mysql.cbn.net.id/})
+
+@item
+@image{Flags/indonesia} Indonesia [incaf.net] @@
+WWW (@uref{http://mysql.incaf.net/})
+FTP (@uref{ftp://mysql.incaf.net/})
+
+@item
+@image{Flags/indonesia} Indonesia [M-Web] @@
+WWW (@uref{http://mysql.mweb.net.id/})
+FTP (@uref{ftp://mysql.mweb.net.id/pub/database/mysql/})
+
+@item
+@image{Flags/indonesia} Indonesia [web.id] @@
+WWW (@uref{http://mysql.itb.web.id/})
+FTP (@uref{ftp://mysql.itb.web.id/pub/MySQL/})
+
+@item
+@image{Flags/japan} Japan [Soft Agency] @@
+WWW (@uref{http://www.softagency.co.jp/MySQL/})
+
+@item
+@image{Flags/japan} Japan [u-aizu.ac.jp/Aizu] @@
+FTP (@uref{ftp://ftp.u-aizu.ac.jp/ftp/pub/dbms/mysql/mysql.com/})
+
+@item
+@image{Flags/philippines} Philippines [Ateneo de Zamboanga University] @@
+WWW (@uref{http://mysql.adzu.edu.ph/})
+
+@item
+@image{Flags/singapore} Singapore [HJC] @@
+WWW (@uref{http://mysql.hjc.edu.sg/})
+FTP (@uref{ftp://ftp.hjc.edu.sg/mysql/})
+
+@item
+@image{Flags/south-korea} South Korea [HolyNet] @@
+WWW (@uref{http://mysql.holywar.net/})
+
+@item
+@image{Flags/south-korea} South Korea [Webiiz] @@
+WWW (@uref{http://mysql.webiiz.com/})
+
+@item
+@image{Flags/taiwan} Taiwan [I-SHOU University] @@
+WWW (@uref{http://mysql.isu.edu.tw/})
+
+@item
+@image{Flags/taiwan} Taiwan [nctu.edu/HsinChu] @@
+WWW (@uref{http://mysql.nctu.edu.tw/})
+
+@item
+@image{Flags/taiwan} Taiwan [TTN] @@
+WWW (@uref{http://mysql.ttn.net/})
+
+@end itemize
+
+@strong{Australia:}
+
+@itemize @bullet
+
+@item
+@image{Flags/australia} Australia [InterActive Consulting] @@
+WWW (@uref{http://mysql.oranged.to})
+
+@item
+@image{Flags/australia} Australia [planetmirror.com] @@
+WWW (@uref{http://mysql.planetmirror.com/})
+FTP (@uref{ftp://planetmirror.com/pub/mysql/})
+
+@item
+@image{Flags/new-zealand} New Zealand [Cubalan] @@
+WWW (@uref{http://mysql.soa.co.nz/})
+
+@end itemize
+
+@strong{Africa:}
+
+@itemize @bullet
+
+@item
+@image{Flags/south-africa} South African Republic [The Internet Solution/Johannesburg] @@
+FTP (@uref{ftp://ftp.is.co.za/linux/mysql/})
+
+@end itemize
+
diff --git a/Docs/my_sys.txt b/Docs/my_sys.txt
new file mode 100644
index 00000000000..85ffc13ecb4
--- /dev/null
+++ b/Docs/my_sys.txt
@@ -0,0 +1,140 @@
+Functions i mysys: (For flags se my_sys.h)
+
+ int my_copy _A((const char *from,const char *to,myf MyFlags));
+ - Copy file
+
+ int my_delete _A((const char *name,myf MyFlags));
+ - Delete file
+
+ int my_getwd _A((string buf,uint size,myf MyFlags));
+ int my_setwd _A((const char *dir,myf MyFlags));
+ - Get and set working directory
+
+ string my_tempnam _A((const char *pfx,myf MyFlags));
+ - Make a uniq temp file name by using dir and adding something after
+ pfx to make name uniq. Name is made by adding a uniq 6 length-string
+ and TMP_EXT after pfx.
+ Returns pointer to malloced area for filename. Should be freed by
+ free().
+
+ File my_open _A((const char *FileName,int Flags,myf MyFlags));
+ File my_create _A((const char *FileName,int CreateFlags,
+ int AccsesFlags, myf MyFlags));
+ int my_close _A((File Filedes,myf MyFlags));
+ uint my_read _A((File Filedes,byte *Buffer,uint Count,myf MyFlags));
+ uint my_write _A((File Filedes,const byte *Buffer,uint Count,
+ myf MyFlags));
+ ulong my_seek _A((File fd,ulong pos,int whence,myf MyFlags));
+ ulong my_tell _A((File fd,myf MyFlags));
+ - Use instead of open,open-with-create-flag, close read and write
+ to get automatic error-messages (flag: MYF_WME) and only have
+ to test for != 0 if error (flag: MY_NABP).
+
+ int my_rename _A((const char *from,const char *to,myf MyFlags));
+ - Rename file
+
+ FILE *my_fopen _A((const char *FileName,int Flags,myf MyFlags));
+ FILE *my_fdopen _A((File Filedes,int Flags,myf MyFlags));
+ int my_fclose _A((FILE *fd,myf MyFlags));
+ uint my_fread _A((FILE *stream,byte *Buffer,uint Count,myf MyFlags));
+ uint my_fwrite _A((FILE *stream,const byte *Buffer,uint Count,
+ myf MyFlags));
+ ulong my_fseek _A((FILE *stream,ulong pos,int whence,myf MyFlags));
+ ulong my_ftell _A((FILE *stream,myf MyFlags));
+ - Same read-interface for streams as for files
+
+ gptr _mymalloc _A((uint uSize,const char *sFile,
+ uint uLine, myf MyFlag));
+ gptr _myrealloc _A((string pPtr,uint uSize,const char *sFile,
+ uint uLine, myf MyFlag));
+ void _myfree _A((gptr pPtr,const char *sFile,uint uLine));
+ int _sanity _A((const char *sFile,unsigned int uLine));
+ gptr _myget_copy_of_memory _A((const byte *from,uint length,
+ const char *sFile, uint uLine,
+ myf MyFlag));
+ - malloc(size,myflag) is mapped to this functions if not compiled
+ with -DSAFEMALLOC
+
+ void TERMINATE _A((void));
+ - Writes malloc-info on stdout if compiled with -DSAFEMALLOC.
+
+ int my_chsize _A((File fd,ulong newlength,myf MyFlags));
+ - Change size of file
+
+ void my_error _D((int nr,myf MyFlags, ...));
+ - Writes message using error number (se mysys/errors.h) on
+ stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called.
+
+ void my_message _A((const char *str,myf MyFlags));
+ - Writes message-string on
+ stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called.
+
+ void my_init _A((void ));
+ - Start each program (in main) with this.
+ void my_end _A((int infoflag));
+ - Gives info about program.
+ - If infoflag & MY_CHECK_ERROR prints if some files are left open
+ - If infoflag & MY_GIVE_INFO prints timing info and malloc info
+ about prog.
+
+ int my_redel _A((const char *from, const char *to, int MyFlags));
+ - Delete from before rename of to to from. Copyes state from old
+ file to new file. If MY_COPY_TIME is set sets old time.
+
+ int my_copystat _A((const char *from, const char *to, int MyFlags));
+ - Copye state from old file to new file.
+ If MY_COPY_TIME is set sets copy also time.
+
+ string my_filename _A((File fd));
+ - Give filename of open file.
+
+ int dirname _A((string to,const char *name));
+ - Copy name of directory from filename.
+
+ int test_if_hard_path _A((const char *dir_name));
+ - Test if dirname is a hard path (Starts from root)
+
+ void convert_dirname _A((string name));
+ - Convert dirname acording to system.
+ - In MSDOS changes all caracters to capitals and changes '/' to
+ '\'
+ string fn_ext _A((const char *name));
+ - Returns pointer to extension in filename
+ string fn_format _A((string to,const char *name,const char *dsk,
+ const char *form,int flag));
+ format a filename with replace of library and extension and
+ converts between different systems.
+ params to and name may be identicall
+ function dosn't change name if name != to
+ Flag may be: 1 force replace filnames library with 'dsk'
+ 2 force replace extension with 'form' */
+ 4 force Unpack filename (replace ~ with home)
+ 8 Pack filename as short as possibly for output to
+ user.
+ All open requests should allways use at least:
+ "open(fn_format(temp_buffe,name,"","",4),...)" to unpack home and
+ convert filename to system-form.
+
+ string fn_same _A((string toname,const char *name,int flag));
+ - Copys directory and extension from name to toname if neaded.
+ copy can be forced by same flags that in fn_format.
+
+ int wild_compare _A((const char *str,const char *wildstr));
+ - Compare if str matches wildstr. Wildstr can contain "*" and "?"
+ as match-characters.
+ Returns 0 if match.
+
+ void get_date _A((string to,int timeflag));
+ - Get current date in a form ready for printing.
+
+ void soundex _A((string out_pntr, string in_pntr))
+ - Makes in_pntr to a 5 chars long string. All words that sounds
+ alike have the same string.
+
+ int init_key_cache _A((ulong use_mem,ulong leave_this_much_mem));
+ - Use cacheing of keys in MISAM, PISAM, and ISAM.
+ KEY_CACHE_SIZE is a good size.
+ - Remember to lock databases for optimal cacheing
+
+ void end_key_cache _A((void));
+ - End key-cacheing.
diff --git a/Docs/mysqld_error.txt b/Docs/mysqld_error.txt
index b8f0ba72ba5..db663e3d1f5 100644
--- a/Docs/mysqld_error.txt
+++ b/Docs/mysqld_error.txt
@@ -168,7 +168,7 @@
#define ER_NO_SUCH_INDEX 1082
"Table '%-.64s' has no index like the one used in CREATE INDEX. Recreate the table",
#define ER_WRONG_FIELD_TERMINATORS 1083
-"Field separator argument is not what is expected. Check the manual","
+"Field separator argument is not what is expected. Check the manual",
#define ER_BLOBS_AND_NO_TERMINATED 1084
"You can't use fixed rowlength with BLOBs. Please use 'fields terminated by'.",
#define ER_TEXTFILE_NOT_READABLE 1085
@@ -180,7 +180,7 @@
#define ER_ALTER_INFO 1088
"Records: %ld Duplicates: %ld",
#define ER_WRONG_SUB_KEY 1089
-"Incorrect sub part key. The used key part isn't a string or the used length is longer than the key part",
+"Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the table handler doesn't support unique sub keys",
#define ER_CANT_REMOVE_ALL_FIELDS 1090
"You can't delete all columns with ALTER TABLE. Use DROP TABLE instead",
#define ER_CANT_DROP_FIELD_OR_KEY 1091
@@ -353,3 +353,105 @@
"This version of MySQL is not compiled with RAID support",
#define ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE 1175
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
+#define ER_KEY_DOES_NOT_EXITS 1176
+"Key '%-.64s' doesn't exist in table '%-.64s'",
+#define ER_CHECK_NO_SUCH_TABLE 1177
+"Can't open table",
+#define ER_CHECK_NOT_IMPLEMENTED 1178
+"The handler for the table doesn't support check/repair",
+#define ER_CANT_DO_THIS_DURING_AN_TRANSACTION 1179
+"You are not allowed to execute this command in a transaction",
+#define ER_ERROR_DURING_COMMIT 1180
+"Got error %d during COMMIT",
+#define ER_ERROR_DURING_ROLLBACK 1181
+"Got error %d during ROLLBACK",
+#define ER_ERROR_DURING_FLUSH_LOGS 1182
+"Got error %d during FLUSH_LOGS",
+#define ER_ERROR_DURING_CHECKPOINT 1183
+"Got error %d during CHECKPOINT",
+#define ER_NEW_ABORTING_CONNECTION 1184
+"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)",
+#define ER_DUMP_NOT_IMPLEMENTED 1185
+"The handler for the table does not support binary table dump",
+#define ER_FLUSH_MASTER_BINLOG_CLOSED 1186
+"Binlog closed, cannot RESET MASTER",
+#define ER_INDEX_REBUILD 1187
+"Failed rebuilding the index of dumped table '%-.64s'",
+#define ER_MASTER 1188
+"Error from master: '%-.64s'",
+#define ER_MASTER_NET_READ 1189
+"Net error reading from master",
+#define ER_MASTER_NET_WRITE 1190
+"Net error writing to master",
+#define ER_FT_MATCHING_KEY_NOT_FOUND 1191
+"Can't find FULLTEXT index matching the column list",
+#define ER_LOCK_OR_ACTIVE_TRANSACTION 1192
+"Can't execute the given command because you have active locked tables or an active transaction",
+#define ER_UNKNOWN_SYSTEM_VARIABLE 1193
+"Unknown system variable '%-.64s'",
+#define ER_CRASHED_ON_USAGE 1194
+"Table '%-.64s' is marked as crashed and should be repaired",
+#define ER_CRASHED_ON_REPAIR 1195
+"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
+#define ER_WARNING_NOT_COMPLETE_ROLLBACK 1196
+"Warning: Some non-transactional changed tables couldn't be rolled back",
+#define ER_TRANS_CACHE_FULL 1197
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
+#define ER_SLAVE_MUST_STOP 1198
+"This operation cannot be performed with a running slave, run SLAVE STOP first",
+#define ER_SLAVE_NOT_RUNNING 1199
+"This operation requires a running slave, configure slave and do SLAVE START",
+#define ER_BAD_SLAVE 1200
+"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
+#define ER_MASTER_INFO 1201
+"Could not initialize master info structure, check permisions on master.info",
+#define ER_SLAVE_THREAD 1202
+"Could not create slave thread, check system resources",
+#define ER_TOO_MANY_USER_CONNECTIONS 1203
+"User %-.64s has already more than 'max_user_connections' active connections",
+#define ER_SET_CONSTANTS_ONLY 1204
+"You may only use constant expressions with SET",
+#define ER_LOCK_WAIT_TIMEOUT 1205
+"Lock wait timeout exceeded; Try restarting transaction",
+#define ER_LOCK_TABLE_FULL 1206
+"The total number of locks exceeds the lock table size",
+#define ER_READ_ONLY_TRANSACTION 1207
+"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+#define ER_DROP_DB_WITH_READ_LOCK 1208
+"DROP DATABASE not allowed while thread is holding global read lock",
+#define ER_CREATE_DB_WITH_READ_LOCK 1209
+"CREATE DATABASE not allowed while thread is holding global read lock",
+#define ER_WRONG_ARGUMENTS 1210
+"Wrong arguments to %s",
+#define ER_NO_PERMISSION_TO_CREATE_USER 1211
+"%-.32s@%-.64s is not allowed to create new users",
+#define ER_UNION_TABLES_IN_DIFFERENT_DIR 1212
+"Incorrect table definition; All MERGE tables must be in the same database",
+#define ER_LOCK_DEADLOCK 1213
+"Deadlock found when trying to get lock; Try restarting transaction",
+#define ER_TABLE_CANT_HANDLE_FULLTEXT 1214
+"The used table type doesn't support FULLTEXT indexes",
+#define ER_CANNOT_ADD_FOREIGN 1215
+"Cannot add foreign key constraint",
+#define ER_NO_REFERENCED_ROW 1216
+"Cannot add a child row: a foreign key constraint fails",
+#define ER_ROW_IS_REFERENCED 1217
+"Cannot delete a parent row: a foreign key constraint fails",
+#define ER_CONNECT_TO_MASTER 1218
+"Error connecting to master: %-.128s",
+#define ER_QUERY_ON_MASTER 1219
+"Error running query on master: %-.128s",
+#define ER_ERROR_WHEN_EXECUTING_COMMAND 1220
+"Error when executing command %s: %-.128s",
+#define ER_WRONG_USAGE 1221
+"Wrong usage of %s and %s",
+#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1222
+"The used SELECT statements have a different number of columns",
+#define ER_CANT_UPDATE_WITH_READLOCK 1223
+"Can't execute the query because you have a conflicting read lock",
+#define ER_MIXING_NOT_ALLOWED 1224
+"Mixing of transactional and non-transactional tables is disabled",
+#define ER_DUP_ARGUMENT 1225
+"Option '%s' used twice in statement",
+#define ER_USER_LIMIT_REACHED 1226
+"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
diff --git a/Docs/section.Infolinks.texi b/Docs/section.Infolinks.texi
new file mode 100644
index 00000000000..828722e0e56
--- /dev/null
+++ b/Docs/section.Infolinks.texi
@@ -0,0 +1,880 @@
+@c FIX AGL 20011108 Extracted from manual.texi.
+@c Contains links to MySQL related info (books, articles). To web portals!
+
+
+@node MySQL-Books, General-SQL, Questions, MySQL Information Sources
+@subsection Books About MySQL
+
+For the latest book information, with user comments, please visit
+@uref{http://www.mysql.com/portal/books/html/}.
+
+While this manual is still the right place for up to date technical
+information, its primary goal is to contain everything there is to know
+about MySQL. It is sometimes nice to have a bound book to read
+in bed or while you travel. Here is a list of books about MySQL and
+related subjects (in English).
+
+By purchasing a book through these hyperlinks provided herein, you are
+contributing to the development of MySQL.
+
+@emph{MySQL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0735709211&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab New Riders
+@item Author @tab Paul DuBois
+@item Pub Date @tab 1st Edition December 1999
+@item ISBN @tab 0735709211
+@item Pages @tab 800
+@item Price @tab $49.99 US
+@item Downloadable examples @tab
+ @uref{http://www.kitebird.com/mysql-book/} (@code{samp_db} distribution)
+@item Errata @tab
+@uref{http://www.kitebird.com/mysql-book/errata.html}
+@end multitable
+
+Foreword by Michael ``Monty'' Widenius, MySQL Moderator.
+@*
+
+In @emph{MySQL}, Paul DuBois provides you with a comprehensive guide to
+one of the most popular relational database systems. Paul has
+contributed to the online documentation for MySQL and is an
+active member of the MySQL community. The principal MySQL
+developer, Monty Widenius, and a network of his fellow developers
+reviewed the manuscript, and provided Paul with the kind of insight
+no one else could supply.
+@*
+
+Instead of merely giving you a general overview of MySQL, Paul
+teaches you how to make the most of its capabilities. Through two
+sample database applications that run throughout the book, he
+gives you solutions to problems you're sure to face. He helps you
+integrate MySQL efficiently with third-party tools, such as PHP
+and Perl, enabling you to generate dynamic Web pages through
+database queries. He teaches you to write programs that access
+MySQL databases, and also provides a comprehensive set of
+references to column types, operators, functions, SQL syntax,
+MySQL programming, C API, Perl @code{DBI}, and PHP API.
+@emph{MySQL} simply gives you the kind of information you won't find
+anywhere else.
+@*
+
+If you use MySQL, this book provides you with:
+@itemize @bullet
+@item
+An introduction to MySQL and SQL.
+@item
+Coverage of MySQL's data types and how to use them.
+@item
+Thorough treatment of how to write client programs in C.
+@item
+A guide to using the Perl @code{DBI} and PHP APIs for developing
+command-line and Web-based applications.
+@item
+Tips on administrative issues such as user accounts, backup,
+crash recovery, and security.
+@item
+Help in choosing an ISP for MySQL access.
+@item
+A comprehensive reference for MySQL's data types, operators,
+functions, and SQL statements and utilities.
+@item
+Complete reference guides for MySQL's C API, the Perl @code{DBI} API,
+and PHP's MySQL-related functions.
+@end itemize
+@*
+
+@emph{MySQL & mSQL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1565924347&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab O'Reilly
+@item Authors @tab Randy Jay Yarger, George Reese & Tim King
+@item Pub Date @tab 1st Edition July 1999
+@item ISBN @tab 1-56592-434-7, Order Number: 4347
+@item Pages @tab 506
+@item Price @tab $34.95
+@end multitable
+
+This book teaches you how to use MySQL and @code{mSQL}, two popular
+and robust database products that support key subsets of SQL on both Linux
+and Unix systems. Anyone who knows basic C, Java, Perl, or Python can
+write a program to interact with a database, either as a stand-alone
+application or through a Web page. This book takes you through the
+whole process, from installation and configuration to programming
+interfaces and basic administration. Includes plenty of tutorial
+material.
+@*
+
+@emph{Sams' Teach Yourself MySQL in 21 Days}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0672319144&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Sams
+@item Authors @tab Mark Maslakowski and Tony Butcher
+@item Pub Date @tab June 2000
+@item ISBN @tab 0672319144
+@item Pages @tab 650
+@item Price @tab $39.99
+@end multitable
+
+Sams' @emph{Teach Yourself MySQL in 21 Days} is for intermediate Linux users
+who want to move into databases. A large share of the audience is Web
+developers who need a database to store large amounts of information that
+can be retrieved via the Web.
+
+Sams' @emph{Teach Yourself MySQL in 21 Days} is a practical, step-by-step
+tutorial. The reader will learn to design and employ this open source
+database technology into his or her website using practical, hands-on
+examples to follow.
+@*
+
+@emph{E-Commerce Solutions with MySQL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0761524452&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Prima Communications, Inc.
+@item Authors @tab N/A
+@item Pub Date @tab January 2000
+@item ISBN @tab 0761524452
+@item Pages @tab 500
+@item Price @tab $39.99
+@end multitable
+
+No description available.
+@*
+
+@emph{MySQL and PHP from Scratch}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0789724405&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Que
+@item Authors @tab N/A
+@item Pub Date @tab September 2000
+@item ISBN @tab 0789724405
+@item Pages @tab 550
+@item Price @tab $34.99
+@end multitable
+
+This book puts together information on installing, setting up, and
+troubleshooting Apache, MySQL, PHP3, and IMP into one complete
+volume. You also learn how each piece is part of a whole by learning,
+step-by-step, how to create a web-based e-mail system. Learn to run
+the equivalent of Active Server Pages (ASP) using PHP3, set up an
+e-commerce site using a database and the Apache web server, and create
+a data entry system (such as sales, product quality tracking, customer
+preferences, etc) that no installation in the PC.
+@*
+
+@emph{Professional MySQL Programming}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=1861005164} (Barnes and Noble)
+@item Publisher @tab Wrox Press, Inc.
+@item Authors @tab N/A
+@item Pub Date @tab Late 2001
+@item ISBN @tab 1861005164
+@item Pages @tab 1000
+@item Price @tab $49.99
+@end multitable
+
+No description available.
+@*
+
+@emph{Professional Linux Programming}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1861003013&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Wrox Press, Inc.
+@item Authors @tab N/A
+@item Pub Date @tab September 2000
+@item ISBN @tab 1861003013
+@item Pages @tab 1155
+@item Price @tab $47.99
+@end multitable
+
+In this follow-up to the best-selling @emph{Beginning Linux Programming},
+you will learn from the authors' real-world knowledge and experience of
+developing software for Linux; you'll be taken through the development
+of a sample 'DVD Store' application, with 'theme' chapters addressing
+different aspects of its implementation. Meanwhile, individual
+``take-a-break'' chapters cover important topics that go beyond the
+bounds of the central theme. All focus on the practical aspects of
+programming, showing how crucial it is to choose the right tools for
+the job, use them as they should be used, and get things right first
+time.
+@*
+
+@emph{PHP and MySQL Web Development}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0672317842&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Sams
+@item Authors @tab Luke Welling, Laura Thomson
+@item Pub Date @tab March 2001
+@item ISBN @tab 0672317842
+@item Pages @tab 700
+@item Price @tab $49.99
+@end multitable
+
+@emph{PHP and MySQL Web Development} introduces you to the advantages
+of implementing both MySQL and PHP. These advantages are detailed
+through the provision of both statistics and several case studies. A
+practical web application is developed throughout the book, providing
+you with the tools necessary to implement a functional online
+database. Each function is developed separately, allowing you the
+choice to incorporate only those parts that you would like to
+implement. Programming concepts of the PHP language are highlighted,
+including functions which tie MySQL support into a PHP script and
+advanced topics regarding table manipulation.
+@*
+
+@strong{Books recommended by the MySQL Developers}
+
+@emph{SQL-99 Complete, Really}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0879305681&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab CMP Books
+@item Authors @tab Peter Gulutzan, Trudy Pelzer
+@item Pub Date @tab April 1999
+@item ISBN @tab 0879305681
+@item Pages @tab 1104
+@item Price @tab $55.96
+@end multitable
+
+This book contains complete descriptions of the new standards for
+syntax, data structures, and retrieval processes of SQL databases. As
+an example-based reference manual, it includes all of the CLI
+functions, information, schema tables, and status codes, as well as a
+working SQL database provided on the companion disk.
+@*
+
+@emph{C, A reference manual}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0133262243&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Prentice Hall
+@item Authors @tab Samuel P. Harbison, Guy L. Steele
+@item Pub Date @tab September 1994
+@item ISBN @tab 0133262243
+@item Pages @tab 480
+@item Price @tab $35.99
+@end multitable
+
+A new and improved revision of the bestselling C language
+reference. This manual introduces the notion of "Clean C", writing C
+code that can be compiled as a C++ program, C programming style that
+emphasizes correctness, portability, maintainability, and
+incorporates the ISO C Amendment 1 (1994) which specifies new
+facilities for writing portable, international programs in C.
+@*
+
+@emph{C++ for Real Programmers}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0120499428&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Academic Press, Incorporated
+@item Authors @tab Jeff Alger, Jim Keogh
+@item Pub Date @tab February 1998
+@item ISBN @tab 0120499428
+@item Pages @tab 388
+@item Price @tab $39.95
+@end multitable
+
+@emph{C++ For Real Programmers} bridges the gap between C++ as described
+in beginner and intermediate-level books and C++ as it is practiced by
+experts. Numerous valuable techniques are described, organised into
+three simple themes: indirection, class hierarchies, and memory
+management. It also provides in-depth coverage of template creation,
+exception handling, pointers and optimisation techniques. The focus of
+the book is on ANSI C++ and, as such, is compiler independent.
+
+@emph{C++ For Real Programmers} is a revision of
+@emph{Secrets of the C++ Masters} and includes a new appendix comparing C++
+with Java. The book comes with a 3.5" disk for Windows with source code.
+@*
+
+@emph{Algorithms in C}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0201514257&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Addison Wesley Longman, Inc.
+@item Authors @tab Robert Sedgewick
+@item Pub Date @tab April 1990
+@item ISBN @tab 0201514257
+@item Pages @tab 648
+@item Price @tab $45.75
+@end multitable
+
+@emph{Algorithms in C} describes a variety of algorithms in a number of
+areas of interest, including: sorting, searching, string-processing, and
+geometric, graph and mathematical algorithms. The book emphasizes
+fundamental techniques, providing readers with the tools to confidently
+implement, run, and debug useful algorithms.
+@*
+
+@emph{Multithreaded Programming with Pthreads}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0136807291&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Prentice Hall
+@item Authors @tab Bil Lewis, Daniel J. Berg
+@item Pub Date @tab October 1997
+@item ISBN @tab 0136807291
+@item Pages @tab 432
+@item Price @tab $34.95
+@end multitable
+
+Based on the best-selling @emph{Threads Primer},
+@emph{Multithreaded Programming with Pthreads} gives you a solid
+understanding of Posix threads: what they are, how they work, when to use
+them, and how to optimise them. It retains the clarity and humor of
+@emph{Threads Primer}, but includes expanded comparisons to Win32 and OS/2
+implementations. Code examples tested on all of the major UNIX platforms
+are featured along with detailed explanations of how and why they use threads.
+@*
+
+@emph{Programming the PERL DBI: Database Programming with PERL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1565926994&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab O'Reilly & Associates, Incorporated
+@item Authors @tab Alligator Descartes, Tim Bunce
+@item Pub Date @tab February 2000
+@item ISBN @tab 1565926994
+@item Pages @tab 400
+@item Price @tab $27.96
+@end multitable
+
+@emph{Programming the Perl DBI} is coauthored by Alligator Descartes, one
+of the most active members of the DBI community, and by Tim Bunce, the
+inventor of DBI. For the uninitiated, the book explains the architecture
+of DBI and shows you how to write DBI-based programs. For the experienced
+DBI dabbler, this book explains DBI's nuances and the peculiarities of each
+individual DBD.
+
+The book includes:
+@itemize @bullet
+@item
+An introduction to DBI and its design.
+@item
+How to construct queries and bind parameters.
+@item
+Working with database, driver, and statement handles.
+@item
+Debugging techniques.
+@item
+Coverage of each existing DBD.
+@item
+A complete reference to DBI.
+@end itemize
+@*
+
+
+@node General-SQL, Useful Links, MySQL-Books, MySQL Information Sources
+@subsection General SQL Information and Tutorials
+
+The MySQL book portal is split into different sections to make it easy
+to locate books for various purposes.
+@uref{http://www.mysql.com/portal/books/html/}
+
+Tutorials can be found at:
+@uref{http://www.mysql.com/portal/development/html/development-61-1.html}
+
+@node Useful Links, , General-SQL, MySQL Information Sources
+@subsection Useful MySQL-related Links
+
+The MySQL development portal is the ultimate source of MySQL related
+links. @uref{http://www.mysql.com/portal/development/html/}
+
+Apart from the following links, you can find and download a lot of
+MySQL programs, tools and APIs in the Contrib directory
+(@uref{http://www.mysql.com/Downloads/Contrib/}).
+@cindex @code{Contrib} directory
+
+@cindex URLs to MySQL information
+@cindex MySQL related information URLs
+@subheading Tutorials and Manuals
+
+@table @asis
+@item @uref{http://michael.bacarella.com/research/mysqlmyths.html} (MySQL Myths Debunked)
+MySQL used in the real world.
+
+@item @uref{http://www.4t2.com/mysql/}
+Information about the German MySQL mailing list.
+
+@item @uref{http://www2.rent-a-database.de/mysql/}
+MySQL handbook in German.
+
+@item @uref{http://www.bitmover.com:8888/home/bk/mysql/}
+Web access to the MySQL BitKeeper repository.
+
+@item @uref{http://www.analysisandsolutions.com/code/mybasic.htm}
+Beginners MySQL Tutorial on how to install and set up
+MySQL on a Windows machine.
+
+@item @uref{http://www.devshed.com/Server_Side/MySQL/}
+A lot of MySQL tutorials.
+
+@item @uref{http://mysql.hitstar.com/}
+MySQL manual in Chinese.
+
+@item @uref{http://www.linuxplanet.com/linuxplanet/tutorials/1046/1/}
+Setting Up a MySQL-based website.
+
+@item @uref{http://www.hotwired.com/webmonkey/backend/tutorials/tutorial1.html}
+MySQL-Perl tutorial.
+
+@item @uref{http://www.iserver.com/support/contrib/perl5/modules.html}
+Installing new Perl modules that require locally installed modules.
+
+@item @uref{http://www.hotwired.com/webmonkey/databases/tutorials/tutorial4.html}
+PHP/MySQL Tutorial.
+
+@item @uref{http://www.useractive.com/}
+Hands on tutorial for MySQL.
+@end table
+
+@subheading MySQL Discussion Forums
+
+@table @asis
+@item @uref{http://www.weberdev.com/}
+Examples using MySQL; (check Top 20)
+
+@item @uref{http://futurerealm.com/forum/futureforum.htm}
+FutureForum Web Discussion Software.
+@end table
+
+@subheading Porting MySQL/Using MySQL on Different Systems
+
+@table @asis
+@item @uref{http://www.entropy.ch/software/macosx/mysql/}
+Binary of MySQL for Mac OS X Client. Includes information of how to
+build and use MySQL on Mac OS X.
+
+@item @uref{http://xclave.macnn.com/MySQL/}
+The Mac OS Xclave. Running MySQL on Mac OS X.
+
+@item @uref{http://www.prnet.de/RegEx/mysql.html}
+MySQL for Mac OS X Server.
+
+@item @uref{http://www.latencyzero.com/macosx/mysql.html}
+Building MySQL for Mac OS X.
+
+@item @uref{http://www.essencesw.com/Software/mysqllib.html}
+New Client libraries for the Mac OS Classic (Macintosh).
+
+@item @uref{http://www.lilback.com/macsql/}
+Client libraries for Mac OS Classic (Macintosh).
+
+@item @uref{http://sixk.maniasys.com/index_en.html}
+MySQL for Amiga
+@end table
+
+@subheading Perl-related Links
+
+@table @asis
+@item @uref{http://dbimysql.photoflux.com/}
+Perl DBI with MySQL FAQ.
+@end table
+
+@c FIX We should get longer descriptions for things in this category!
+@subheading Commercial Applications that Support MySQL
+
+@table @asis
+@item @uref{http://www.supportwizard.com/}
+SupportWizard; Interactive helpdesk on the Web. This product includes a
+licensed copy of MySQL.
+
+@item @uref{http://www.sonork.com/}
+Sonork, Instant Messenger that is not only Internet oriented. It's
+focused on private networks and on small to medium companies. Client
+is free, server is free for up to 5 seats.
+
+@item @uref{http://www.stweb.org/}
+StWeb - Stratos Web and Application server - An easy-to-use, cross
+platform, Internet/Intranet development and deployment system for
+development of web-enabled applications. The standard version of StWeb
+has a native interface to MySQL database.
+
+@item @uref{http://www.rightnowtech.com/}
+Right Now Web; Web automation for customer service.
+
+@item @uref{http://www.icaap.org/Bazaar/}
+Bazaar; Interactive Discussion Forums with Web interface.
+
+@cindex PhoneSweep
+@item @uref{http://www.phonesweep.com/}
+PhoneSweepT is the world's first commercial Telephone Scanner. Many break-ins
+in recent years have come not through the Internet, but through unauthorised
+dial-up modems. PhoneSweep lets you find these modems by repeatedly placing
+phone calls to every phone number that your organisation
+controls. PhoneSweep has a built-in expert system that can recognise
+more than 250 different kinds of remote-access programs, including
+Carbon Copy(TM), pcANYWHERE(TM), and Windows NT RAS. All information is stored
+in the SQL database. It then generates a comprehensive report detailing
+which services were discovered on which dial-up numbers in your organisation.
+@end table
+
+@subheading SQL Clients and Report Writers
+
+@table @asis
+@item @uref{http://www.urbanresearch.com/software/utils/urbsql/} (urSQL)
+SQL Editor and Query Utility. Custom syntax highlighting, editable
+results grid, exportable result-sets, basic MySQL admin functions,
+Etc.. For Windows.
+
+@item @uref{http://www.edatanew.com/} (MySQL Data Manager)
+MySQL Data Manager * is platform independent web client
+(written in perl) for MySQL server over TCP/IP.
+
+@item @uref{http://ksql.sourceforge.net/}
+KDE MySQL client.
+
+@item @uref{http://www.ecker-software.de/}
+A Windows GUI client by David Ecker.
+
+@item @uref{http://www.icaap.org/software/kiosk/}
+Kiosk; a MySQL client for database management. Written in Perl.
+Will be a part of Bazaar.
+
+@item @uref{http://www.casestudio.com/}
+Db design tool that supports MySQL 3.23.
+
+@item @uref{http://home.skif.net/~voland/zeos/eng/}
+Zeos - A client that supports MySQL, Interbase and PostgreSQL.
+
+@item @uref{http://www.geocities.com/SiliconValley/Ridge/4280/GenericReportWriter/grwhome.html}
+A free report writer in Java
+
+@item @uref{http://www.javaframework.de/}
+MySQLExport - Export of MySQL create statements and data in a lot of
+different formats (SQL, HTML, CVS, text, ZIP, GZIP...).
+
+@item @uref{http://dlabs.4t2.com/}
+M2D, a MySQL Administration client for Windows. M2D supports
+administration of MySQL databases, creation of new databases and
+tables, editing, and more.
+
+@item @uref{http://dlabs.4t2.com/}
+Dexter, a small server written in Perl which can be used as a proxy server for
+MySQL or as a database extender.
+
+@item @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp}
+Mascon is a powerful Win32 GUI for administering MySQL databases.
+
+@item @uref{http://www.rtlabs.com/}
+MacSQL Monitor. GUI for MySQL, ODBC, and JDBC databases for the Mac OS.
+@end table
+
+@subheading Distributions that Include MySQL
+
+@c FIX add the rest (at least a couple more Linuxes)
+
+@table @asis
+@item @uref{http://www.suse.com/}
+SuSE Linux (6.1 and above)
+
+@item @uref{http://www.redhat.com/}
+RedHat Linux (7.0 and above)
+
+@item @uref{http://distro.conectiva.com.br/}
+Conectiva Linux (4.0 and above)
+@end table
+
+@subheading Web Development Tools that Support MySQL
+
+@table @asis
+@item @uref{http://www.php.net/}
+PHP: A server-side HTML-embedded scripting language.
+
+@item @uref{http://www.midgard-project.org/}
+The Midgard Application Server; a powerful Web development environment
+based on MySQL and PHP.
+
+@cindex dbServ
+@item @uref{http://www.dbServ.de/}
+dbServ is an extension to a web server to integrate database output into
+your HTML code. You may use any HTML function in your output. Only the
+client will stop you. It works as standalone server or as Java servlet.
+
+@item @uref{http://www.chilisoft.com/}
+Platform independent ASP from Chili!Soft
+
+@item @uref{http://www.voicenet.com/~zellert/tjFM/}
+A JDBC driver for MySQL.
+
+@item @uref{http://www.wernhart.priv.at/php/}
+MySQL + PHP demos.
+
+@item @uref{http://www.dbwww.com/}
+ForwardSQL: HTML interface to manipulate MySQL databases.
+
+@item @uref{http://www.daa.com.au/~james/www-sql/}
+WWW-SQL: Display database information.
+
+@item @uref{http://www.heitml.com/}
+HeiTML: A server-side extension of HTML and a 4GL language at the same time.
+
+@item @uref{http://hawkeye.net/}
+Hawkeye Internet Server Suite.
+
+@item @uref{http://www.webgroove.com/}
+WebGroove Script: HTML compiler and server-side scripting language.
+
+@item @uref{http://www.ihtml.com/}
+A server-side website scripting language.
+
+@item @uref{ftp://ftp.igc.apc.org/pub/myodbc/README}
+How to use MySQL with ColdFusion on Solaris.
+
+@item @uref{http://calistra.com/MySQL/}
+Calistra's ODBC MySQL Administrator.
+
+@item @uref{http://phpclub.net/}
+PHPclub - Tips and tricks for PHP.
+
+@item @uref{http://www.widgetchuck.com/}
+The Widgetchuck; Website Tools and Gadgets
+
+@item @uref{http://www.adcycle.com/}
+AdCycle - advertising management software.
+
+@cindex pwPage
+@item @uref{http://sourceforge.net/projects/pwpage/}
+pwPage - provides an extremely fast and simple approach to the creation
+of database forms. That is, if a database table exists and an HTML page
+has been constructed using a few simple guidelines, pwPage can be
+immediately used for table data selections, insertions, updates, deletions
+and selectable table content reviewing.
+
+@item @uref{http://www.omnis-software.com/products/studio/studio.html}
+OMNIS Studio is a rapid application development (RAD) tool.
+@end table
+
+@subheading Database Design Tools with MySQL Support
+
+@table @asis
+@item @uref{http://www.mysql.com/documentation/dezign/}
+"DeZign for databases" is a database development tool that uses an
+entity relationship diagram (ERD).
+@end table
+
+@subheading Web Servers with MySQL Tools
+
+@table @asis
+@item @uref{ftp://ftp.kcilink.com/pub/}
+mod_auth_mysql, An Apache authentication module.
+
+@item @uref{http://www.roxen.com/}
+The Roxen Challenger Web server.
+@end table
+
+@subheading Extensions for Other Programs
+
+@table @asis
+@item @uref{http://www.seawood.org/msql_bind/}
+MySQL support for BIND (The Internet Domain Name Server).
+
+@item @uref{http://www.inet-interactive.com/sendmail/}
+MySQL support for Sendmail and Procmail.
+@end table
+
+@subheading Using MySQL with Other Programs
+
+@table @asis
+@item @uref{http://www.iserver.com/support/addonhelp/database/mysql/msaccess.html}
+Using MySQL with Access.
+
+@item @uref{http://www.iserver.com/support/contrib/perl5/modules.html}
+Installing new Perl modules that require locally installed modules.
+@end table
+
+@subheading ODBC-related Links
+
+@table @asis
+@item @uref{http://www.iodbc.org/}
+Popular iODBC Driver Manager (libiodbc) now available as Open Source.
+
+@item @uref{http://users.ids.net/~bjepson/freeODBC/}
+The FreeODBC Pages.
+
+@item @uref{http://genix.net/unixODBC/}
+The unixODBC Project goals are to develop and promote unixODBC to be the
+definitive standard for ODBC on the Linux platform. This is to include GUI
+support for KDE.
+
+@item @uref{http://www.sw-soft.com/products/BtrieveODBC/}
+A MySQL-based ODBC driver for Btrieve.
+@end table
+
+@subheading @strong{API}-related Links
+
+@table @asis
+@item @uref{http://www.jppp.com/}
+Partially implemented TDataset-compatible components for MySQL.
+
+@item @uref{http://www.riverstyx.net/qpopmysql/}
+qpopmysql - A patch to allow POP3 authentication from a MySQL
+database. There's also a link to Paul Khavkine's patch for Procmail to
+allow any MTA to deliver to users in a MySQL database.
+
+@item @uref{http://www.essencesw.com/Software/mysqllib.html}
+New Client libraries for the Mac OS Classic (Macintosh).
+
+@item @uref{http://www.lilback.com/macsql/}
+Client libraries for the Macintosh.
+
+@item @uref{http://www.essencesw.com/Plugins/mysqlplug.html}
+Plugin for REALbasic (for Macintosh)
+
+@item @uref{http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html}
+A library that emulates BSD sockets and pthreads on Macintosh. This can
+be used if you want to compile the MySQL client library on Mac.
+It could probably even be sued to port MySQL to Macintosh, but we
+don't know of anyone that has tried that.
+
+@cindex SCMDB
+@item @uref{http://www.dedecker.net/jessie/scmdb/}
+SCMDB - an add-on for SCM that ports the MySQL C library to scheme
+(SCM). With this library scheme developers can make connections to a
+MySQL database and use embedded SQL in their programs.
+@end table
+
+@subheading Other MySQL-related Links
+
+@table @asis
+@item @uref{http://www.satisoft.com/} (SAT)
+The Small Application Toolkit (SAT) is a collection of utilities
+intended to simplify the development of small, multi-user, GUI based
+applications in a (Microsoft -or- X) Windows Client / Unix Server
+environment.
+
+@item @uref{http://www.wix.com/mysql-hosting/}
+Registry of Web providers who support MySQL.
+
+@item @uref{http://www.softagency.co.jp/mysql/index.en.html}
+Links about using MySQL in Japan/Asia.
+
+@item @uref{http://abattoir.cc.ndsu.nodak.edu/~nem/mysql/udf/}
+MySQL UDF Registry.
+
+@item @uref{http://www.open.com.au/products.html}
+Commercial Web defect tracking system.
+
+@item @uref{http://www.stonekeep.com/pts/}
+PTS: Project Tracking System.
+
+@item @uref{http://tomato.nvgc.vt.edu/~hroberts/mot/}
+Job and software tracking system.
+
+@item @uref{http://www.cynergi.net/exportsql/}
+ExportSQL: A script to export data from Access95+.
+
+@item @uref{http://SAL.KachinaTech.COM/H/1/MYSQL.html}
+SAL (Scientific Applications on Linux) MySQL entry.
+
+@item @uref{http://www.infotech-nj.com/itech/index.shtml}
+A consulting company which mentions MySQL in the right company.
+
+@item @uref{http://www.pmpcs.com/}
+PMP Computer Solutions. Database developers using MySQL and
+@code{mSQL}.
+
+@item @uref{http://www.dedserius.com/y2kmatrix/}
+Y2K tester.
+@end table
+
+@subheading SQL and Database Interfaces
+
+@table @asis
+@item @uref{http://java.sun.com/products/jdbc/}
+The JDBC database access API.
+
+@item @uref{http://www.gagme.com/mysql/}
+Patch for @code{mSQL} Tcl.
+
+@item @uref{http://www.amsoft.ru/easysql/}
+EasySQL: An ODBC-like driver manager.
+
+@item @uref{http://www.lightlink.com/hessling/rexxsql.html}
+A REXX interface to SQL databases.
+
+@c @item @uref{http://www.mytcl.cx/}
+@c Tcl interface based on tcl-sql with many bugfixes.
+
+@item @uref{http://www.binevolve.com/~tdarugar/tcl-sql/}
+Tcl interface for MySQL.
+
+@item @uref{http://www.contrib.andrew.cmu.edu/~shadow/sql.html}
+SQL Reference Page with a lot of interesting links.
+
+@end table
+
+@subheading Examples of MySQL Use
+
+@table @asis
+@c Added 990601
+@c EMAIL: thuss@little6.com (Todd Huss)
+@item @uref{http://www.little6.com/about/linux/}
+Little6 Inc., An online contract and job finding site that is powered by
+MySQL, PHP3, and Linux.
+
+@c Added 990521
+@c EMAIL: info@worldrecords.com (Jim Rota)
+@item @uref{http://www.worldrecords.com/}
+World Records - A search engine for information about music that uses
+MySQL and PHP.
+
+@item @uref{http://www.webtechniques.com/archives/1998/01/note/}
+A Contact Database using MySQL and PHP.
+
+@item @uref{http://modems.rosenet.net/mysql/}
+Web based interface and Community Calendar with PHP.
+
+@item @uref{http://www.odbsoft.com/cook/sources.htm}
+Perl package to generate html from a SQL table structure and for generating
+SQL statements from an html form.
+
+@item @uref{http://www.gusnet.cx/proj/telsql/}
+Basic telephone database using @code{DBI}/@code{DBD}.
+
+@item @uref{http://tecfa.unige.ch/guides/java/staf2x/ex/jdbc/coffee-break/}
+JDBC examples by Daniel K. Schneider.
+
+@item @uref{http://www.ooc.com/}
+Object Oriented Concepts Inc; CORBA applications with examples in source.
+
+@c EMAIL: paul@sword.damocles.com (Paul Bannister)
+@item @uref{http://www.stopbit.com/}
+Stopbit - A technology news site using MySQL and PHP.
+
+@item @uref{http://www.penguinservices.com/scripts/}
+Online shopping cart system.
+
+@c Added 990928 from editor@city-gallery.com
+@cindex Old Photo Album
+@item @uref{http://www.city-gallery.com/album/}
+Old Photo Album - The album is a collaborative popular history of photography
+project that generates all pages from data stored in a MySQL
+database. Pages are dynamically generated through a php3 interface to the
+database content. Users contribute images and descriptions. Contributed
+images are stored on the web server to avoid storing them in the database
+as BLOBs. All other information is stored on the shared MySQL server.
+@end table
+
+@subheading General Database Links
+
+@table @asis
+@item @uref{http://black.hole-in-the.net/guy/webdb/}
+Homepage of the webdb-l (Web Databases) mailing list.
+
+@item @uref{http://www.symbolstone.org/technology/perl/DBI/}
+Perl @code{DBI}/@code{DBD} modules homepage.
+
+@item @uref{http://www.student.uni-koeln.de/cygwin/}
+Cygwin tools. Unix on top of Windows.
+
+@cindex Tek-Tips forums
+@cindex forums, Tek-Tips
+@item @uref{http://www.tek-tips.com/}
+Tek-Tips Forums are 800+ independent peer-to-peer non-commercial support
+forums for Computer Professionals. Features include automatic e-mail
+notification of responses, a links library, and member confidentiality
+guaranteed.
+
+@item @uref{http://www.public.asu.edu/~peterjn/btree/}
+B-Trees: Balanced Tree Data Structures.
+
+@item @uref{http://www.fit.qut.edu.au/~maire/baobab/lecture/sld001.htm}
+A lecture about B-Trees.
+@end table
+
+
diff --git a/Docs/section.Testimonials.texi b/Docs/section.Testimonials.texi
new file mode 100644
index 00000000000..e757a6a92d0
--- /dev/null
+++ b/Docs/section.Testimonials.texi
@@ -0,0 +1,31 @@
+@c FIX AGL 20011108 Extracted from manual.texi.
+@c Should only be on website with new submits by webform.
+
+
+@node MySQL Testimonials, Contrib, Users, Top
+@appendix MySQL Testimonials
+
+@cindex MySQL Testimonials
+
+The section 'MySQL Users' contains a lot of different links to
+MySQL users but doesn't provide that much information about how
+they are using MySQL. @xref{Users}. This section gives you an idea
+of how other MySQL users are using MySQL to solve their problems.
+
+Please note that all new stories are added on the MySQL website,
+@uref{http://www.mysql.com/}.
+Do let us know about @emph{your} success story too!
+
+@itemize @bullet
+@item
+@strong{Peter Zaitsev of Spylog.ru} writes:
+I think you might be interested in my database size. The whole database
+is currently on 15 servers and I think it's about 60.000 of tables
+containing about 5.000.000.000 of rows. My mostly loaded server
+currently holds about 10.000 of tables with 1.000.000.000 of rows in it.
+Hugest tables have about 50.000.000 of rows, and this value will raise
+as soon as I'll move to 2.4 kernel with large files. Currently I have to
+delete much of logs for large sites to hold table sizes in 2Gb.
+
+@item
+
diff --git a/Docs/section.Users.texi b/Docs/section.Users.texi
new file mode 100644
index 00000000000..3c8d219fa16
--- /dev/null
+++ b/Docs/section.Users.texi
@@ -0,0 +1,414 @@
+@c FIX AGL 20011108 Extracted from manual.texi.
+@c Should only be on website.
+
+
+@node Users, Contrib, Problems, Top
+@appendix MySQL Users
+
+@cindex users, of MySQL
+@cindex news sites
+
+This appendix lists users of MySQL that have given us permission
+to list them in our documentation. It is by far not a complete list, but
+should give you a general idea of who uses MySQL and what it can
+be used for.
+
+@appendixsec General News Sites
+
+@itemize @bullet
+
+@item @uref{http://www.yahoo.com/} (Yahoo!)
+
+@item @uref{http://slashdot.org/} (Slashdot: A pro-Linux/tech news and comment/discussion site)
+
+@item @uref{http://www.linux.com/} (All about Linux)
+
+@item @uref{http://www.linuxtoday.com/} (Linuxtoday)
+
+@item @uref{http://www.32bitsonline.com/} (32Bits Online: because there's
+more than one way to compute)
+
+@item @uref{http://www.freshmeat.net/} (Freshmeat: News about new versions of computer-related stuff)
+
+@end itemize
+
+@cindex search engines, web
+@cindex web search engines
+@appendixsec Web Search Engines
+
+@itemize @bullet
+
+@item @uref{http://www.aaa.com.au/} (AAA Matilda Web Search)
+@item @uref{http://www.whatsnu.com/} (What's New)
+@item @uref{http://www.aladin.de/} (Aladin)
+@item @uref{http://www.columbus-finder.de/} (Columbus Finder)
+@item @uref{http://www.spider.de/} (Spider)
+@item @uref{http://www.blitzsuche.de/} (Blitzsuche)
+@item @uref{http://www.indoseek.co.id/} (Indoseek Indonesia)
+@item @uref{http://www.yaboo.dk/} (Yaboo - Yet Another BOOkmarker)
+@item @uref{http://www.ozsearch.com.au/} (OzSearch Internet Guide)
+@item @uref{http://www.splatsearch.com/} (Splat! Search)
+@item @uref{http://osdls.library.arizona.edu/} (The Open Source Digital Library System Project)
+@end itemize
+
+@appendixsec Information Search Engines Specialising in a Particular Area
+
+@itemize @bullet
+
+@item @uref{http://www.spylog.ru/} (SpyLOG ; A very popular Web counter site)
+
+@item @uref{http://www.tucows.com/} (TuCows Network; Free Software archive)
+
+@item @uref{http://www.jobvertise.com/} (Jobvertise: Post and search for jobs)
+
+@item @uref{http://www.musicdatabase.com/} (The Music Database)
+
+@item @uref{http://www.soccersearch.com/} (Football -Soccer- search page)
+
+@item @uref{http://www.headrush.net/takedown} (TAKEDOWN - wrestling)
+
+@item @uref{http://www.lyrics.net/} (The International Lyrics Network)
+
+@item @uref{http://TheMatrix.com/~matrix/band_search.phtml} (Musicians looking for other musicians; free service)
+
+@item @uref{http://www.addall.com/AddBooks/Stores.html} (AddALL books searching and price comparison)
+
+@item @uref{http://www.herbaria.harvard.edu/Data/Gray/gray.html} (Harvard's Gray Herbarium Index of Plant Names)
+
+@item @uref{http://www.game-developer.com/} (The Game Development Search Engine)
+
+@item @uref{http://www.theinnkeeper.com/} (The Innkeeper Vacation Guides)
+
+@item @uref{http://www.macgamedatabase.com/} (The Mac Game Database uses PHP and MySQL)
+@c From: Marc Antony Vose <suzerain@suzerain.com>
+
+@item @uref{http://www.csse.monash.edu.au/publications/} (Research
+Publications at Monash University in Australia)
+
+@item @uref{http://www.ipielle.emr.it/bts/}
+(Occupational Health & Safety Website database; a project for the ECC)
+@c c.presutti@ipielle.emr.it
+
+@item @uref{http://data.mch.mcgill.ca/} (Bioinformatics databases at the
+Montreal Children's Hospital using MySQL)
+@c saeed@www.debelle.mcgill.ca
+@end itemize
+
+@cindex online magazines
+@cindex magazines, online
+@appendixsec Online Magazines
+
+@itemize @bullet
+@item @uref{http://www.spoiler.com/} (Spoiler Webzine)
+An online magazine featuring music, literature, arts, and design content.
+@item @uref{http://www.linux-magazin.de/newsflash/} (Daily news about Linux in German language)
+@item @uref{http://www.betazine.com/} (Betazine - The Ultimate Online Beta Tester's Magazine)
+@item @uref{http://www.currents.net/ccinfo/aboutcc.html} (Computer Currents Magazine)
+@end itemize
+
+@cindex websites
+@appendixsec Websites that Use MySQL as a Backend
+
+@itemize @bullet
+
+@item @uref{http://liftoff.msfc.nasa.gov/} (NASA)
+@item @uref{http://kids.msfc.nasa.gov/} (NASA KIDS)
+@item @uref{http://science.nasa.gov/} (Sience@@NASA)
+
+@item @uref{http://www.handy.de/} (handy.de)
+
+@item @uref{http://lindev.jmc.tju.edu/qwor/} (Qt Widget and Object Repository)
+
+@item @uref{http://www.samba-choro.com.br/} (Brazilian samba site; in Portuguese)
+
+@item @uref{http://pgss.iss.uw.edu.pl/en_index.ISS} (Polish General Social Survey)
+
+@item @uref{http://www.expo2000.com/} Expo2000 - world-wide distribution of
+tickets for this event is implemented using MySQL and Tcl/Tk. More than
+5000 travel agencies all over the world have access to it.
+
+@item @uref{http://www.freevote.com/} FreeVote.com is a free voting
+service with millions of users.
+
+@item @uref{http://f1.tauzero.se/} (Forza Motorsport)
+
+@item @uref{http://www.dreamhost.com/} (DreamHost Web Hosting)
+
+@end itemize
+
+@cindex services
+@appendixsec Domain/Internet/Web and Related Services
+
+@itemize @bullet
+
+@item @uref{http://www.wix.com/mysql-hosting/} (Registry of Web providers that
+support MySQL)
+
+@item @uref{http://www.yi.org/} (Dynamic DNS Services)
+
+@item @uref{http://www.dynodns.net/} (Dynamic domain name service)
+
+@item @uref{http://www.ods.org/} (Open DNS Project; free dynamic DNS service)
+
+@c @item @uref{http://dynodns.net/} (Free dynamic DNS implementation)
+@c EMAIL: A Moore <amoore@mooresystems.com>
+
+@item @uref{http://www.hn.org/} (Hammernode; Public DNS Servers)
+
+@item @uref{http://www.fdns.net/} (Free 3rd level domains)
+
+@item @uref{http://worldcommunity.com/} (Online Database)
+
+@item @uref{http://www.bigbiz.com/} (BigBiz Internet Services)
+
+@item @uref{http://virt.circle.net/} (The Virt Gazette)
+
+@item @uref{http://www.california.com/} (Global InfoNet Inc)
+
+@item @uref{http://www.webhosters.com/} (WebHosters - A Guide to WWW Providers)
+
+@item @uref{http://online.dn.ru/} (Internet information server)
+
+@item @uref{http://www.worldnetla.net/} (WorldNet Communications - An Internet Services Provider)
+
+@item @uref{http://www.netizen.com.au/} (Netizen: Australian-based Web consultancy)
+
+@item @uref{http://www.trainingpages.co.uk/} (Search site for training courses in the UK)
+
+@item @uref{http://chat.nitco.com/} (Gannon Chat; GPL. Written in Perl and Javascript)
+
+@item @uref{http://www.addurls.com/} (A general links directory)
+
+@item @uref{http://www.bookmarktracker.com/} (A Web-based bookmark management service)
+
+@item @uref{http://www.cdrom.com/} (Walnut Creek CDROM)
+
+@item @uref{http://www.wwwthreads.org/} (WWWThreads; Interactive discussion Forums)
+
+@item @uref{http://pvmon.portici.enea.it/Meteo/} (In Italian; Storage data from meteo station)
+
+@item @uref{http://www.buysell.net/} (Online "Person To Person" Auction)
+
+@item @uref{http://tips.pair.com/} (Tips on Web development)
+
+@item @uref{http://www.mailfriends.com/} (Mailfriends.com is a FREE service for
+everybody who wants to find friends over the internet)
+
+@item @uref{http://www.uninova.com/cgi-bin/wctelnets?list} (Web Page Telnet BBS List)
+
+@item @uref{http://www.uninova.com/cnc.html} (UniNova Digital Postcards)
+
+@c @item @uref{http://cabinboy.powersurfr.com/} (An Internet RFC search engine)
+
+@item @uref{http://www.dslreports.com/} (DSL-provider search with reviews)
+Made with MySQL and Modperl, all pages are generated dynamically out of
+the MySQL database
+@end itemize
+
+@cindex PHP, websites
+@appendixsec Websites that Use @code{PHP} and MySQL
+
+@itemize @bullet
+@c @item @uref{http://www.wh200th.com/} (White House 200th Anniversary site)
+
+@item @uref{http://support.jgaa.com/} (Jgaa's Internet - Official Support Site)
+
+@item @uref{http://io.incluso.com/} (Ionline - online publication) MySQL,
+PHP, Java, Web programming, DB development
+
+@item @uref{http://www.baboo.com/} (BaBoo - Browse and Bookmark. Free Web-based bookmark manager and Calendar)
+
+@item @uref{http://www.courses.pjc.cc.fl.us/Schedule/}
+(Course Schedule System at Pensacola Junior College)
+
+@item @uref{http://www.fccj.org/} (Florida Community College at Jacksonville)
+
+@item @uref{http://www.32bit.com/} (32bit.com; An extensive shareware / freeware archive)
+
+@item @uref{http://www.jokes2000.com/} (Jokes 2000)
+@c Added 990604; EMAIL: ah@dybdahl.dk
+
+@item @uref{http://www.burken.nu/}
+Burken is a webhotel that provides scripts, among other things,
+for remote users, like counters, guestbooks etc.
+@c Added 990608; EMAIL: spacedmp@SpaceDump.Burken.NU (Anders Olausson)
+
+@item @uref{http://tips.pair.com/}
+Contains tips on html, javascript, 2d/3d graphics, and PHP3/MySQL.
+All pages are generated from a database.
+@c Added 990614; EMAIL: downey@image.dk (Rune Madsen)
+
+@item @uref{http://www.softwarezrus.com/}
+Ecommerce site that is selling computers.
+@end itemize
+
+@cindex consultants, list of
+@appendixsec MySQL Consultants
+
+@itemize @bullet
+
+@item @uref{http://www.ayni.com/} (Ayni AG)
+
+@item @uref{http://worldcommunity.com/} (Online Database)
+
+@item @uref{http://www2.dataguard.no/} (DataGuard; Uses MySQL and PHP)
+
+@item @uref{http://wwits.net/programs/mysql.phtml} (WWITS; uses MySQL and PHP)
+
+@item @uref{http://www.worldcommunity.com/} (WCN - The World Community Network)
+
+@item @uref{http://www.chipcastle.com/} (Chip Castle Dot Com Inc)
+@c Added 990603 EMAIL: chip@chipcastle.com (Chip Castle)
+
+@item @uref{http://www.cyber.com.au/} (Cybersource Pty. Ltd)
+
+@item @uref{http://www.spring.de/} (Spring infotainment gmbh & co. kg)
+@c added 990905 "Oliver Pischke" <opischke@spring.de>
+
+@item @uref{http://www.wamdesign.com/} (Wam Design develops websites using MySQL)
+@c Added 990905; max@wamdesign.com
+
+@item @uref{http://www.berkeleyconsultants.com/} (Berkeley Consultants Group)
+
+@item @uref{http://www.jammconsulting.com/} (JAMM Consulting Inc)
+
+@end itemize
+
+@c Commented out by Arjen 011018, section is empty!
+@c appendixsec Programming
+
+@cindex web pages, miscellaneous
+@appendixsec Uncategorised Pages
+
+@itemize @bullet
+
+@item @uref{http://www.feature-showcase.com/htmls/demo_mysql.sql} (AZC.COM's Feature Showcase)
+
+@item @uref{http://www.teach.org.uk/subjects/trainingcourse/g.html} (Course Search)
+
+@item @uref{http://www.northerbys.com/} (Northerbys Online Auctions)
+
+@item @uref{http://www.schiphol.nl/flights/home.htm} (Amsterdam Airport Schiphol)
+
+@item @uref{http://TheMatrix.com/seventhsin/query.phtml} (CD database)
+
+@item @uref{http://TheMatrix.com/~flmm/GEAR.html} (Used Audio Gear Database)
+
+@item @uref{http://www.kiss.de/musik-mueller/} (Musical note-sheets)
+
+@item @uref{http://www.bagism.com/} (Bagism; A John Lennon fan page)
+
+@item @uref{http://www.selftaught.com/} (US Folk art broker)
+
+@item @uref{http://organizer.net/} (Mail reading on the Web)
+
+@item @uref{http://www.mypage.org/} (Free home pages on www.somecoolname.mypage.org)
+
+@item @uref{http://www.schulweb.de/} (Der Server f@"ur Schulen im Web - in German)
+
+@item @uref{http://www.ald.net/} (Auldhaefen Online Services)
+
+@item @uref{http://www.cary.net/} (CaryNET Information Center)
+
+@item @uref{http://www.dataden.com/} (Dataden Computer Systems)
+
+@item @uref{http://andree.grm.se/} (Andr@'emuseet; in Swedish)
+
+@item @uref{http://www.him.net/} (HOMESITE Internet Marketing)
+
+@item @uref{http://www.jade-v.com/techinfo.html} (Jade-V Network Services)
+
+@item @uref{http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml}
+Weather World 2010 Technical Credits
+
+@item @uref{http://gimp.foebud.org/registry/doc/}
+About The Gimp plugin registry
+
+@item @uref{http://www.fast-inc.com/Products/Archiver/database.html}
+Java tool; archiver technical detail (Slightly optimistic about MySQL
+ANSI-92 compliance)
+
+@item @uref{http://www.gamesdomain.com/cheats/usrcheat.phtml} (Games Domain Cheats Database)
+
+@item @uref{http://www.kcilink.com/poweredby/} (The "Powered By" Page; Kcilink)
+
+@item @uref{http://www.netcasting.net/index.whtml} (Netcasting)
+
+@item @uref{http://homepages.tig.com.au/~mjj/nbltips} (NBL: Australian National Basketball League; tipping)
+
+@item @uref{http://www.cgishop.com/} (CGI shop)
+
+@item @uref{http://www.whirlycott.com/} (Whirlycott: Website Design)
+
+@item @uref{http://www.mtp.dk/} (Museum Tusculanum Press)
+
+@item @uref{http://csdgi.historie.ku.dk/biblio/} (Centro Siciliano di Documentazione)
+
+@item @uref{http://caribou.dyn.ml.org:8000/} (Quake statistics database)
+
+@item @uref{http://www.astroforum.ch/} (Astroforum: Astrologie and related things; in German)
+
+@item @uref{http://www.opendebate.com/} (OpenDebate - Interactive Polls & Open Discussion)
+
+@item @uref{http://vermeer.organik.uni-erlangen.de/dissertationen/} (Online chemical dissertation server)
+
+@item @uref{http://www.freschinfo.com/} (FreSch! The Free Scholarship Search Service)
+
+@item @uref{http://www.nada.kth.se/~staffanu/pinball/} (Stockholm Pinball Locator)
+
+@item @uref{http://www.hek.com/} (HEK - a construction company)
+
+@item @uref{http://www.ebi.nl/} (Elsevier Business Information)
+
+@item @uref{http://vaccination.medicallink.se/} (Medical Links; using ColdFusion and MySQL)
+
+@item @uref{http://www.joblink-usa.com/} (Search for jobs & people at JobLink-USA)
+
+@item @uref{http://www.skydive.net/competfs/} (Competition Formation Skydiving)
+
+@item @uref{http://www.galaxy-net.net/} (Galaxy-NET Telecommunications; E-commerce and internal accounting)
+
+@item @uref{http://www.borsen.dk/} (Denmark's leading business daily newspaper B@o{}rsen)
+
+@item @uref{http://tmmm.simplenet.com/indb/} (The Internet NES Database)
+
+@item @uref{http://www.russia.cz/} (Travel agency in Prague in 3 languages)
+
+@item @uref{http://www.linkstation.de/} (Linkstation)
+
+@item @uref{http://www.peoplestaff.com/} (Searchable online database at Peoplestaff)
+
+@item @uref{http://www.dreamhorse.com/} (A searchable database system for horse classified ads)
+
+@item @uref{http://pootpoot.com/} (The Poot site)
+
+@item @uref{http://grateful.net/hw_html/} ("Playin' in the LAN"; a network monitoring suite)
+
+@c Update from Christopher Milton <cmilton@bwn.net> 1999-12-21
+@item @uref{http://www.usapa.army.mil/} (U.S. Army Publishing Agency)
+
+@item @uref{http://www.nekretnine.co.yu/} (Realestate handling in Yugoslavia)
+
+@item @uref{http://demo.cpsoft.com/pims/devFAQ.html} (PIMS; a Patient Information Management System)
+
+@item @uref{http://cpsoft.com/} (Pilkington Software Inc)
+
+@item @uref{http://www.no-quarter.org/} (A Vietnam Veteran's Memorial - The Wall - database)
+
+@item @uref{http://www.gamers-union.com/} (Gamer's Union specializes in auctions of used & out-of-print gaming material)
+
+@item @uref{http://www.montereyhigh.com/office/dbul.php3} (A daily bulletin at Monterey High school)
+
+@item @uref{http://www.myEastside.com/} (Community-owned site serving Lake
+Washington's Eastside residents and businesses)
+
+@item @uref{http://bowling-france.net/} (French bowling site)
+@end itemize
+
+Send any additions to this list to @email{webmaster@@mysql.com}.
+
+@page
+
+
+
+
diff --git a/Docs/template.texi b/Docs/template.texi
new file mode 100644
index 00000000000..36633da6269
--- /dev/null
+++ b/Docs/template.texi
@@ -0,0 +1,522 @@
+\input texinfo @c -*-texinfo-*-
+@c Copyright 1995-2002 MySQL AB
+@c
+@c This manual is NOT distributed under a GPL style license.
+@c Use of the manual is subject to the following terms:
+@c - Conversion to other formats is allowed, but the actual
+@c content may not be altered or edited in any way.
+@c - You may create a printed copy for your own personal use.
+@c - For all other uses, such as selling printed copies or
+@c using (parts of) the manual in another publication,
+@c prior written agreement from MySQL AB is required.
+@c
+@c Please e-mail docs@mysql.com for more information or if
+@c you are interested in doing a translation.
+@c
+@c *********************************************************
+@c
+@c %**start of header
+
+@setfilename mysql.info
+
+@c We want the types in the same index
+@syncodeindex tp fn
+
+@c Get version information. This file is generated by the Makefile!!
+@include include.texi
+
+@ifclear tex-debug
+@c This removes the black squares in the right margin
+@finalout
+@end ifclear
+
+@c Set background for HTML
+@set _body_tags BGCOLOR=silver TEXT=#000000 LINK=#101090 VLINK=#7030B0
+@c Set some style elements for the manual in HTML form. 'suggested'
+@c natural language colors: aqua, black, blue, fuchsia, gray, green,
+@c lime, maroon, navy, olive, purple, red, silver, teal, white, and
+@c yellow. From Steeve Buehler <ahr@YogElements.com>
+@set _extra_head <style> code {color:purple} tt {color:green} samp {color:navy} pre {color:maroon} </style>
+
+@settitle MySQL Reference Manual for version @value{mysql_version}.
+
+@c We want single-sided heading format, with chapters on new pages. To
+@c get double-sided format change 'on' below to 'odd'
+@setchapternewpage on
+
+@paragraphindent 0
+
+@c %**end of header
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* mysql: (mysql). MySQL documentation.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@titlepage
+@sp 10
+@center @titlefont{MySQL Reference Manual}
+@sp 10
+@center Copyright @copyright{} 1995-2002 MySQL AB
+@c blank page after title page makes page 1 be a page front.
+@c also makes the back of the title page blank.
+@page
+@end titlepage
+
+@c Short contents, blank page, long contents.
+@c until i can figure out the blank page, no short contents.
+@c @shortcontents
+@c @page
+@c @page
+@contents
+
+@c This should be added. The HTML conversion also needs a MySQL version
+@c number somewhere.
+
+@iftex
+@c change this to double if you want formatting for double-sided
+@c printing
+@headings single
+
+@oddheading @thischapter @| @| @thispage
+@evenheading @thispage @| @| MySQL Technical Reference for Version @value{mysql_version}
+
+@end iftex
+
+
+@node Top, Introduction, (dir), (dir)
+
+@ifinfo
+This is a manual for the MySQL Database System.
+This version is about the @value{mysql_version} version of MySQL Server.
+You can find a specific manual for any older version of MySQL Server
+in the binary or source distribution for that version.
+@end ifinfo
+
+@node Introduction, Installing, Top, Top
+@chapter General Information About MySQL
+
+
+
+
+
+@node GPL license, LGPL license, Regexp, Top
+@appendix GNU GENERAL PUBLIC LICENSE
+
+@cindex GPL, General Public License
+@cindex GPL, GNU General Public License
+
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@appendixsec Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software---to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+@iftex
+@appendixsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center GNU GENERAL PUBLIC LICENSE
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate 0
+@item
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The ``Program'', below,
+refers to any such program or work, and a ``work based on the Program''
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term ``modification''.) Each licensee is addressed as ``you''.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+@item
+You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+@item
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+@item
+If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+@enumerate a
+@item
+Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+@item
+Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+@item
+Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+@end enumerate
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+@item
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and ``any
+later version'', you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+@item
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@appendixsec How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the program's name and a brief idea of what it does.}
+Copyright (C) @var{yyyy} @var{name of author}
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+@smallexample
+Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{show c}; they could even be mouse-clicks or menu items---whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. Here is a sample; alter the names:
+
+@example
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end example
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+
+
+@node Function Index, Concept Index, LGPL license, Top
+@unnumbered SQL command, type and function index
+
+@printindex fn
+
+@page
+
+
+@node Concept Index, , Function Index, Top
+@unnumbered Concept Index
+
+@printindex cp
+
+
+
+
+
+@bye
+
diff --git a/Docs/world.sql b/Docs/world.sql
new file mode 100644
index 00000000000..7ddd3787ec6
--- /dev/null
+++ b/Docs/world.sql
@@ -0,0 +1,5386 @@
+-- MySQL dump 8.19
+--
+-- Host: localhost Database: world
+---------------------------------------------------------
+-- Server version 4.0.1-alpha-Max
+
+--
+-- Table structure for table 'City'
+--
+
+CREATE TABLE City (
+ ID int(11) NOT NULL auto_increment,
+ name char(35) NOT NULL default '',
+ Country char(3) NOT NULL default '',
+ District char(20) NOT NULL default '',
+ Population int(11) NOT NULL default '0',
+ PRIMARY KEY (ID)
+) TYPE=MyISAM;
+
+/*!40000 ALTER TABLE City DISABLE KEYS */;
+
+--
+-- Dumping data for table 'City'
+--
+
+
+INSERT INTO City VALUES (1,'Kabul','AFG','Kabol',1780000);
+INSERT INTO City VALUES (2,'Qandahar','AFG','Qandahar',237500);
+INSERT INTO City VALUES (3,'Herat','AFG','Herat',186800);
+INSERT INTO City VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800);
+INSERT INTO City VALUES (5,'Amsterdam','NLD','Noord-Holland',731200);
+INSERT INTO City VALUES (6,'Rotterdam','NLD','Zuid-Holland',593321);
+INSERT INTO City VALUES (7,'Haag','NLD','Zuid-Holland',440900);
+INSERT INTO City VALUES (8,'Utrecht','NLD','Utrecht',234323);
+INSERT INTO City VALUES (9,'Eindhoven','NLD','Noord-Brabant',201843);
+INSERT INTO City VALUES (10,'Tilburg','NLD','Noord-Brabant',193238);
+INSERT INTO City VALUES (11,'Groningen','NLD','Groningen',172701);
+INSERT INTO City VALUES (12,'Breda','NLD','Noord-Brabant',160398);
+INSERT INTO City VALUES (13,'Apeldoorn','NLD','Gelderland',153491);
+INSERT INTO City VALUES (14,'Nijmegen','NLD','Gelderland',152463);
+INSERT INTO City VALUES (15,'Enschede','NLD','Overijssel',149544);
+INSERT INTO City VALUES (16,'Haarlem','NLD','Noord-Holland',148772);
+INSERT INTO City VALUES (17,'Almere','NLD','Flevoland',142465);
+INSERT INTO City VALUES (18,'Arnhem','NLD','Gelderland',138020);
+INSERT INTO City VALUES (19,'Zaanstad','NLD','Noord-Holland',135621);
+INSERT INTO City VALUES (20,'´s-Hertogenbosch','NLD','Noord-Brabant',129170);
+INSERT INTO City VALUES (21,'Amersfoort','NLD','Utrecht',126270);
+INSERT INTO City VALUES (22,'Maastricht','NLD','Limburg',122087);
+INSERT INTO City VALUES (23,'Dordrecht','NLD','Zuid-Holland',119811);
+INSERT INTO City VALUES (24,'Leiden','NLD','Zuid-Holland',117196);
+INSERT INTO City VALUES (25,'Haarlemmermeer','NLD','Noord-Holland',110722);
+INSERT INTO City VALUES (26,'Zoetermeer','NLD','Zuid-Holland',110214);
+INSERT INTO City VALUES (27,'Emmen','NLD','Drenthe',105853);
+INSERT INTO City VALUES (28,'Zwolle','NLD','Overijssel',105819);
+INSERT INTO City VALUES (29,'Ede','NLD','Gelderland',101574);
+INSERT INTO City VALUES (30,'Delft','NLD','Zuid-Holland',95268);
+INSERT INTO City VALUES (31,'Heerlen','NLD','Limburg',95052);
+INSERT INTO City VALUES (32,'Alkmaar','NLD','Noord-Holland',92713);
+INSERT INTO City VALUES (33,'Willemstad','ANT','Curaçao',2345);
+INSERT INTO City VALUES (34,'Tirana','ALB','Tirana',270000);
+INSERT INTO City VALUES (35,'Alger','DZA','Alger',2168000);
+INSERT INTO City VALUES (36,'Oran','DZA','Oran',609823);
+INSERT INTO City VALUES (37,'Constantine','DZA','Constantine',443727);
+INSERT INTO City VALUES (38,'Annaba','DZA','Annaba',222518);
+INSERT INTO City VALUES (39,'Batna','DZA','Batna',183377);
+INSERT INTO City VALUES (40,'Sétif','DZA','Sétif',179055);
+INSERT INTO City VALUES (41,'Sidi Bel Abbès','DZA','Sidi Bel Abbès',153106);
+INSERT INTO City VALUES (42,'Skikda','DZA','Skikda',128747);
+INSERT INTO City VALUES (43,'Biskra','DZA','Biskra',128281);
+INSERT INTO City VALUES (44,'Blida (el-Boulaida)','DZA','Blida',127284);
+INSERT INTO City VALUES (45,'Béjaïa','DZA','Béjaïa',117162);
+INSERT INTO City VALUES (46,'Mostaganem','DZA','Mostaganem',115212);
+INSERT INTO City VALUES (47,'Tébessa','DZA','Tébessa',112007);
+INSERT INTO City VALUES (48,'Tlemcen (Tilimsen)','DZA','Tlemcen',110242);
+INSERT INTO City VALUES (49,'Béchar','DZA','Béchar',107311);
+INSERT INTO City VALUES (50,'Tiaret','DZA','Tiaret',100118);
+INSERT INTO City VALUES (51,'Ech-Chleff (el-Asnam)','DZA','Chlef',96794);
+INSERT INTO City VALUES (52,'Ghardaïa','DZA','Ghardaïa',89415);
+INSERT INTO City VALUES (53,'Tafuna','ASM','Tutuila',5200);
+INSERT INTO City VALUES (54,'Fagatogo','ASM','Tutuila',2323);
+INSERT INTO City VALUES (55,'Andorra la Vella','AND','Andorra la Vella',21189);
+INSERT INTO City VALUES (56,'Luanda','AGO','Luanda',2022000);
+INSERT INTO City VALUES (57,'Huambo','AGO','Huambo',163100);
+INSERT INTO City VALUES (58,'Lobito','AGO','Benguela',130000);
+INSERT INTO City VALUES (59,'Benguela','AGO','Benguela',128300);
+INSERT INTO City VALUES (60,'Namibe','AGO','Namibe',118200);
+INSERT INTO City VALUES (61,'South Hill','AIA','–',961);
+INSERT INTO City VALUES (62,'The Valley','AIA','–',595);
+INSERT INTO City VALUES (63,'Saint John´s','ATG','St John',24000);
+INSERT INTO City VALUES (64,'Dubai','ARE','Dubai',669181);
+INSERT INTO City VALUES (65,'Abu Dhabi','ARE','Abu Dhabi',398695);
+INSERT INTO City VALUES (66,'Sharja','ARE','Sharja',320095);
+INSERT INTO City VALUES (67,'al-Ayn','ARE','Abu Dhabi',225970);
+INSERT INTO City VALUES (68,'Ajman','ARE','Ajman',114395);
+INSERT INTO City VALUES (69,'Buenos Aires','ARG','Distrito Federal',2982146);
+INSERT INTO City VALUES (70,'La Matanza','ARG','Buenos Aires',1266461);
+INSERT INTO City VALUES (71,'Córdoba','ARG','Córdoba',1157507);
+INSERT INTO City VALUES (72,'Rosario','ARG','Santa Fé',907718);
+INSERT INTO City VALUES (73,'Lomas de Zamora','ARG','Buenos Aires',622013);
+INSERT INTO City VALUES (74,'Quilmes','ARG','Buenos Aires',559249);
+INSERT INTO City VALUES (75,'Almirante Brown','ARG','Buenos Aires',538918);
+INSERT INTO City VALUES (76,'La Plata','ARG','Buenos Aires',521936);
+INSERT INTO City VALUES (77,'Mar del Plata','ARG','Buenos Aires',512880);
+INSERT INTO City VALUES (78,'San Miguel de Tucumán','ARG','Tucumán',470809);
+INSERT INTO City VALUES (79,'Lanús','ARG','Buenos Aires',469735);
+INSERT INTO City VALUES (80,'Merlo','ARG','Buenos Aires',463846);
+INSERT INTO City VALUES (81,'General San Martín','ARG','Buenos Aires',422542);
+INSERT INTO City VALUES (82,'Salta','ARG','Salta',367550);
+INSERT INTO City VALUES (83,'Moreno','ARG','Buenos Aires',356993);
+INSERT INTO City VALUES (84,'Santa Fé','ARG','Santa Fé',353063);
+INSERT INTO City VALUES (85,'Avellaneda','ARG','Buenos Aires',353046);
+INSERT INTO City VALUES (86,'Tres de Febrero','ARG','Buenos Aires',352311);
+INSERT INTO City VALUES (87,'Morón','ARG','Buenos Aires',349246);
+INSERT INTO City VALUES (88,'Florencio Varela','ARG','Buenos Aires',315432);
+INSERT INTO City VALUES (89,'San Isidro','ARG','Buenos Aires',306341);
+INSERT INTO City VALUES (90,'Tigre','ARG','Buenos Aires',296226);
+INSERT INTO City VALUES (91,'Malvinas Argentinas','ARG','Buenos Aires',290335);
+INSERT INTO City VALUES (92,'Vicente López','ARG','Buenos Aires',288341);
+INSERT INTO City VALUES (93,'Berazategui','ARG','Buenos Aires',276916);
+INSERT INTO City VALUES (94,'Corrientes','ARG','Corrientes',258103);
+INSERT INTO City VALUES (95,'San Miguel','ARG','Buenos Aires',248700);
+INSERT INTO City VALUES (96,'Bahía Blanca','ARG','Buenos Aires',239810);
+INSERT INTO City VALUES (97,'Esteban Echeverría','ARG','Buenos Aires',235760);
+INSERT INTO City VALUES (98,'Resistencia','ARG','Chaco',229212);
+INSERT INTO City VALUES (99,'José C. Paz','ARG','Buenos Aires',221754);
+INSERT INTO City VALUES (100,'Paraná','ARG','Entre Rios',207041);
+INSERT INTO City VALUES (101,'Godoy Cruz','ARG','Mendoza',206998);
+INSERT INTO City VALUES (102,'Posadas','ARG','Misiones',201273);
+INSERT INTO City VALUES (103,'Guaymallén','ARG','Mendoza',200595);
+INSERT INTO City VALUES (104,'Santiago del Estero','ARG','Santiago del Estero',189947);
+INSERT INTO City VALUES (105,'San Salvador de Jujuy','ARG','Jujuy',178748);
+INSERT INTO City VALUES (106,'Hurlingham','ARG','Buenos Aires',170028);
+INSERT INTO City VALUES (107,'Neuquén','ARG','Neuquén',167296);
+INSERT INTO City VALUES (108,'Ituzaingó','ARG','Buenos Aires',158197);
+INSERT INTO City VALUES (109,'San Fernando','ARG','Buenos Aires',153036);
+INSERT INTO City VALUES (110,'Formosa','ARG','Formosa',147636);
+INSERT INTO City VALUES (111,'Las Heras','ARG','Mendoza',145823);
+INSERT INTO City VALUES (112,'La Rioja','ARG','La Rioja',138117);
+INSERT INTO City VALUES (113,'San Fernando del Valle de Cata','ARG','Catamarca',134935);
+INSERT INTO City VALUES (114,'Río Cuarto','ARG','Córdoba',134355);
+INSERT INTO City VALUES (115,'Comodoro Rivadavia','ARG','Chubut',124104);
+INSERT INTO City VALUES (116,'Mendoza','ARG','Mendoza',123027);
+INSERT INTO City VALUES (117,'San Nicolás de los Arroyos','ARG','Buenos Aires',119302);
+INSERT INTO City VALUES (118,'San Juan','ARG','San Juan',119152);
+INSERT INTO City VALUES (119,'Escobar','ARG','Buenos Aires',116675);
+INSERT INTO City VALUES (120,'Concordia','ARG','Entre Rios',116485);
+INSERT INTO City VALUES (121,'Pilar','ARG','Buenos Aires',113428);
+INSERT INTO City VALUES (122,'San Luis','ARG','San Luis',110136);
+INSERT INTO City VALUES (123,'Ezeiza','ARG','Buenos Aires',99578);
+INSERT INTO City VALUES (124,'San Rafael','ARG','Mendoza',94651);
+INSERT INTO City VALUES (125,'Tandil','ARG','Buenos Aires',91101);
+INSERT INTO City VALUES (126,'Yerevan','ARM','Yerevan',1248700);
+INSERT INTO City VALUES (127,'Gjumri','ARM','Širak',211700);
+INSERT INTO City VALUES (128,'Vanadzor','ARM','Lori',172700);
+INSERT INTO City VALUES (129,'Oranjestad','ABW','–',29034);
+INSERT INTO City VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO City VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO City VALUES (132,'Brisbane','AUS','Queensland',1291117);
+INSERT INTO City VALUES (133,'Perth','AUS','West Australia',1096829);
+INSERT INTO City VALUES (134,'Adelaide','AUS','South Australia',978100);
+INSERT INTO City VALUES (135,'Canberra','AUS','Capital Region',322723);
+INSERT INTO City VALUES (136,'Gold Coast','AUS','Queensland',311932);
+INSERT INTO City VALUES (137,'Newcastle','AUS','New South Wales',270324);
+INSERT INTO City VALUES (138,'Central Coast','AUS','New South Wales',227657);
+INSERT INTO City VALUES (139,'Wollongong','AUS','New South Wales',219761);
+INSERT INTO City VALUES (140,'Hobart','AUS','Tasmania',126118);
+INSERT INTO City VALUES (141,'Geelong','AUS','Victoria',125382);
+INSERT INTO City VALUES (142,'Townsville','AUS','Queensland',109914);
+INSERT INTO City VALUES (143,'Cairns','AUS','Queensland',92273);
+INSERT INTO City VALUES (144,'Baku','AZE','Baki',1787800);
+INSERT INTO City VALUES (145,'Gäncä','AZE','Gäncä',299300);
+INSERT INTO City VALUES (146,'Sumqayit','AZE','Sumqayit',283000);
+INSERT INTO City VALUES (147,'Mingäçevir','AZE','Mingäçevir',93900);
+INSERT INTO City VALUES (148,'Nassau','BHS','New Providence',172000);
+INSERT INTO City VALUES (149,'al-Manama','BHR','al-Manama',148000);
+INSERT INTO City VALUES (150,'Dhaka','BGD','Dhaka',3612850);
+INSERT INTO City VALUES (151,'Chittagong','BGD','Chittagong',1392860);
+INSERT INTO City VALUES (152,'Khulna','BGD','Khulna',663340);
+INSERT INTO City VALUES (153,'Rajshahi','BGD','Rajshahi',294056);
+INSERT INTO City VALUES (154,'Narayanganj','BGD','Dhaka',202134);
+INSERT INTO City VALUES (155,'Rangpur','BGD','Rajshahi',191398);
+INSERT INTO City VALUES (156,'Mymensingh','BGD','Dhaka',188713);
+INSERT INTO City VALUES (157,'Barisal','BGD','Barisal',170232);
+INSERT INTO City VALUES (158,'Tungi','BGD','Dhaka',168702);
+INSERT INTO City VALUES (159,'Jessore','BGD','Khulna',139710);
+INSERT INTO City VALUES (160,'Comilla','BGD','Chittagong',135313);
+INSERT INTO City VALUES (161,'Nawabganj','BGD','Rajshahi',130577);
+INSERT INTO City VALUES (162,'Dinajpur','BGD','Rajshahi',127815);
+INSERT INTO City VALUES (163,'Bogra','BGD','Rajshahi',120170);
+INSERT INTO City VALUES (164,'Sylhet','BGD','Sylhet',117396);
+INSERT INTO City VALUES (165,'Brahmanbaria','BGD','Chittagong',109032);
+INSERT INTO City VALUES (166,'Tangail','BGD','Dhaka',106004);
+INSERT INTO City VALUES (167,'Jamalpur','BGD','Dhaka',103556);
+INSERT INTO City VALUES (168,'Pabna','BGD','Rajshahi',103277);
+INSERT INTO City VALUES (169,'Naogaon','BGD','Rajshahi',101266);
+INSERT INTO City VALUES (170,'Sirajganj','BGD','Rajshahi',99669);
+INSERT INTO City VALUES (171,'Narsinghdi','BGD','Dhaka',98342);
+INSERT INTO City VALUES (172,'Saidpur','BGD','Rajshahi',96777);
+INSERT INTO City VALUES (173,'Gazipur','BGD','Dhaka',96717);
+INSERT INTO City VALUES (174,'Bridgetown','BRB','St Michael',6070);
+INSERT INTO City VALUES (175,'Antwerpen','BEL','Antwerpen',446525);
+INSERT INTO City VALUES (176,'Gent','BEL','East Flanderi',224180);
+INSERT INTO City VALUES (177,'Charleroi','BEL','Hainaut',200827);
+INSERT INTO City VALUES (178,'Liège','BEL','Liège',185639);
+INSERT INTO City VALUES (179,'Bruxelles [Brussel]','BEL','Bryssel',133859);
+INSERT INTO City VALUES (180,'Brugge','BEL','West Flanderi',116246);
+INSERT INTO City VALUES (181,'Schaerbeek','BEL','Bryssel',105692);
+INSERT INTO City VALUES (182,'Namur','BEL','Namur',105419);
+INSERT INTO City VALUES (183,'Mons','BEL','Hainaut',90935);
+INSERT INTO City VALUES (184,'Belize City','BLZ','Belize City',55810);
+INSERT INTO City VALUES (185,'Belmopan','BLZ','Cayo',7105);
+INSERT INTO City VALUES (186,'Cotonou','BEN','Atlantique',536827);
+INSERT INTO City VALUES (187,'Porto-Novo','BEN','Ouémé',194000);
+INSERT INTO City VALUES (188,'Djougou','BEN','Atacora',134099);
+INSERT INTO City VALUES (189,'Parakou','BEN','Borgou',103577);
+INSERT INTO City VALUES (190,'Saint George','BMU','Saint George´s',1800);
+INSERT INTO City VALUES (191,'Hamilton','BMU','Hamilton',1200);
+INSERT INTO City VALUES (192,'Thimphu','BTN','Thimphu',22000);
+INSERT INTO City VALUES (193,'Santa Cruz de la Sierra','BOL','Santa Cruz',935361);
+INSERT INTO City VALUES (194,'La Paz','BOL','La Paz',758141);
+INSERT INTO City VALUES (195,'El Alto','BOL','La Paz',534466);
+INSERT INTO City VALUES (196,'Cochabamba','BOL','Cochabamba',482800);
+INSERT INTO City VALUES (197,'Oruro','BOL','Oruro',223553);
+INSERT INTO City VALUES (198,'Sucre','BOL','Chuquisaca',178426);
+INSERT INTO City VALUES (199,'Potosí','BOL','Potosí',140642);
+INSERT INTO City VALUES (200,'Tarija','BOL','Tarija',125255);
+INSERT INTO City VALUES (201,'Sarajevo','BIH','Federaatio',360000);
+INSERT INTO City VALUES (202,'Banja Luka','BIH','Republika Srpska',143079);
+INSERT INTO City VALUES (203,'Zenica','BIH','Federaatio',96027);
+INSERT INTO City VALUES (204,'Gaborone','BWA','Gaborone',213017);
+INSERT INTO City VALUES (205,'Francistown','BWA','Francistown',101805);
+INSERT INTO City VALUES (206,'São Paulo','BRA','São Paulo',9968485);
+INSERT INTO City VALUES (207,'Rio de Janeiro','BRA','Rio de Janeiro',5598953);
+INSERT INTO City VALUES (208,'Salvador','BRA','Bahia',2302832);
+INSERT INTO City VALUES (209,'Belo Horizonte','BRA','Minas Gerais',2139125);
+INSERT INTO City VALUES (210,'Fortaleza','BRA','Ceará',2097757);
+INSERT INTO City VALUES (211,'Brasília','BRA','Distrito Federal',1969868);
+INSERT INTO City VALUES (212,'Curitiba','BRA','Paraná',1584232);
+INSERT INTO City VALUES (213,'Recife','BRA','Pernambuco',1378087);
+INSERT INTO City VALUES (214,'Porto Alegre','BRA','Rio Grande do Sul',1314032);
+INSERT INTO City VALUES (215,'Manaus','BRA','Amazonas',1255049);
+INSERT INTO City VALUES (216,'Belém','BRA','Pará',1186926);
+INSERT INTO City VALUES (217,'Guarulhos','BRA','São Paulo',1095874);
+INSERT INTO City VALUES (218,'Goiânia','BRA','Goiás',1056330);
+INSERT INTO City VALUES (219,'Campinas','BRA','São Paulo',950043);
+INSERT INTO City VALUES (220,'São Gonçalo','BRA','Rio de Janeiro',869254);
+INSERT INTO City VALUES (221,'Nova Iguaçu','BRA','Rio de Janeiro',862225);
+INSERT INTO City VALUES (222,'São Luís','BRA','Maranhão',837588);
+INSERT INTO City VALUES (223,'Maceió','BRA','Alagoas',786288);
+INSERT INTO City VALUES (224,'Duque de Caxias','BRA','Rio de Janeiro',746758);
+INSERT INTO City VALUES (225,'São Bernardo do Campo','BRA','São Paulo',723132);
+INSERT INTO City VALUES (226,'Teresina','BRA','Piauí',691942);
+INSERT INTO City VALUES (227,'Natal','BRA','Rio Grande do Norte',688955);
+INSERT INTO City VALUES (228,'Osasco','BRA','São Paulo',659604);
+INSERT INTO City VALUES (229,'Campo Grande','BRA','Mato Grosso do Sul',649593);
+INSERT INTO City VALUES (230,'Santo André','BRA','São Paulo',630073);
+INSERT INTO City VALUES (231,'João Pessoa','BRA','Paraíba',584029);
+INSERT INTO City VALUES (232,'Jaboatão dos Guararapes','BRA','Pernambuco',558680);
+INSERT INTO City VALUES (233,'Contagem','BRA','Minas Gerais',520801);
+INSERT INTO City VALUES (234,'São José dos Campos','BRA','São Paulo',515553);
+INSERT INTO City VALUES (235,'Uberlândia','BRA','Minas Gerais',487222);
+INSERT INTO City VALUES (236,'Feira de Santana','BRA','Bahia',479992);
+INSERT INTO City VALUES (237,'Ribeirão Preto','BRA','São Paulo',473276);
+INSERT INTO City VALUES (238,'Sorocaba','BRA','São Paulo',466823);
+INSERT INTO City VALUES (239,'Niterói','BRA','Rio de Janeiro',459884);
+INSERT INTO City VALUES (240,'Cuiabá','BRA','Mato Grosso',453813);
+INSERT INTO City VALUES (241,'Juiz de Fora','BRA','Minas Gerais',450288);
+INSERT INTO City VALUES (242,'Aracaju','BRA','Sergipe',445555);
+INSERT INTO City VALUES (243,'São João de Meriti','BRA','Rio de Janeiro',440052);
+INSERT INTO City VALUES (244,'Londrina','BRA','Paraná',432257);
+INSERT INTO City VALUES (245,'Joinville','BRA','Santa Catarina',428011);
+INSERT INTO City VALUES (246,'Belford Roxo','BRA','Rio de Janeiro',425194);
+INSERT INTO City VALUES (247,'Santos','BRA','São Paulo',408748);
+INSERT INTO City VALUES (248,'Ananindeua','BRA','Pará',400940);
+INSERT INTO City VALUES (249,'Campos dos Goytacazes','BRA','Rio de Janeiro',398418);
+INSERT INTO City VALUES (250,'Mauá','BRA','São Paulo',375055);
+INSERT INTO City VALUES (251,'Carapicuíba','BRA','São Paulo',357552);
+INSERT INTO City VALUES (252,'Olinda','BRA','Pernambuco',354732);
+INSERT INTO City VALUES (253,'Campina Grande','BRA','Paraíba',352497);
+INSERT INTO City VALUES (254,'São José do Rio Preto','BRA','São Paulo',351944);
+INSERT INTO City VALUES (255,'Caxias do Sul','BRA','Rio Grande do Sul',349581);
+INSERT INTO City VALUES (256,'Moji das Cruzes','BRA','São Paulo',339194);
+INSERT INTO City VALUES (257,'Diadema','BRA','São Paulo',335078);
+INSERT INTO City VALUES (258,'Aparecida de Goiânia','BRA','Goiás',324662);
+INSERT INTO City VALUES (259,'Piracicaba','BRA','São Paulo',319104);
+INSERT INTO City VALUES (260,'Cariacica','BRA','Espírito Santo',319033);
+INSERT INTO City VALUES (261,'Vila Velha','BRA','Espírito Santo',318758);
+INSERT INTO City VALUES (262,'Pelotas','BRA','Rio Grande do Sul',315415);
+INSERT INTO City VALUES (263,'Bauru','BRA','São Paulo',313670);
+INSERT INTO City VALUES (264,'Porto Velho','BRA','Rondônia',309750);
+INSERT INTO City VALUES (265,'Serra','BRA','Espírito Santo',302666);
+INSERT INTO City VALUES (266,'Betim','BRA','Minas Gerais',302108);
+INSERT INTO City VALUES (267,'Jundíaí','BRA','São Paulo',296127);
+INSERT INTO City VALUES (268,'Canoas','BRA','Rio Grande do Sul',294125);
+INSERT INTO City VALUES (269,'Franca','BRA','São Paulo',290139);
+INSERT INTO City VALUES (270,'São Vicente','BRA','São Paulo',286848);
+INSERT INTO City VALUES (271,'Maringá','BRA','Paraná',286461);
+INSERT INTO City VALUES (272,'Montes Claros','BRA','Minas Gerais',286058);
+INSERT INTO City VALUES (273,'Anápolis','BRA','Goiás',282197);
+INSERT INTO City VALUES (274,'Florianópolis','BRA','Santa Catarina',281928);
+INSERT INTO City VALUES (275,'Petrópolis','BRA','Rio de Janeiro',279183);
+INSERT INTO City VALUES (276,'Itaquaquecetuba','BRA','São Paulo',270874);
+INSERT INTO City VALUES (277,'Vitória','BRA','Espírito Santo',270626);
+INSERT INTO City VALUES (278,'Ponta Grossa','BRA','Paraná',268013);
+INSERT INTO City VALUES (279,'Rio Branco','BRA','Acre',259537);
+INSERT INTO City VALUES (280,'Foz do Iguaçu','BRA','Paraná',259425);
+INSERT INTO City VALUES (281,'Macapá','BRA','Amapá',256033);
+INSERT INTO City VALUES (282,'Ilhéus','BRA','Bahia',254970);
+INSERT INTO City VALUES (283,'Vitória da Conquista','BRA','Bahia',253587);
+INSERT INTO City VALUES (284,'Uberaba','BRA','Minas Gerais',249225);
+INSERT INTO City VALUES (285,'Paulista','BRA','Pernambuco',248473);
+INSERT INTO City VALUES (286,'Limeira','BRA','São Paulo',245497);
+INSERT INTO City VALUES (287,'Blumenau','BRA','Santa Catarina',244379);
+INSERT INTO City VALUES (288,'Caruaru','BRA','Pernambuco',244247);
+INSERT INTO City VALUES (289,'Santarém','BRA','Pará',241771);
+INSERT INTO City VALUES (290,'Volta Redonda','BRA','Rio de Janeiro',240315);
+INSERT INTO City VALUES (291,'Novo Hamburgo','BRA','Rio Grande do Sul',239940);
+INSERT INTO City VALUES (292,'Caucaia','BRA','Ceará',238738);
+INSERT INTO City VALUES (293,'Santa Maria','BRA','Rio Grande do Sul',238473);
+INSERT INTO City VALUES (294,'Cascavel','BRA','Paraná',237510);
+INSERT INTO City VALUES (295,'Guarujá','BRA','São Paulo',237206);
+INSERT INTO City VALUES (296,'Ribeirão das Neves','BRA','Minas Gerais',232685);
+INSERT INTO City VALUES (297,'Governador Valadares','BRA','Minas Gerais',231724);
+INSERT INTO City VALUES (298,'Taubaté','BRA','São Paulo',229130);
+INSERT INTO City VALUES (299,'Imperatriz','BRA','Maranhão',224564);
+INSERT INTO City VALUES (300,'Gravataí','BRA','Rio Grande do Sul',223011);
+INSERT INTO City VALUES (301,'Embu','BRA','São Paulo',222223);
+INSERT INTO City VALUES (302,'Mossoró','BRA','Rio Grande do Norte',214901);
+INSERT INTO City VALUES (303,'Várzea Grande','BRA','Mato Grosso',214435);
+INSERT INTO City VALUES (304,'Petrolina','BRA','Pernambuco',210540);
+INSERT INTO City VALUES (305,'Barueri','BRA','São Paulo',208426);
+INSERT INTO City VALUES (306,'Viamão','BRA','Rio Grande do Sul',207557);
+INSERT INTO City VALUES (307,'Ipatinga','BRA','Minas Gerais',206338);
+INSERT INTO City VALUES (308,'Juazeiro','BRA','Bahia',201073);
+INSERT INTO City VALUES (309,'Juazeiro do Norte','BRA','Ceará',199636);
+INSERT INTO City VALUES (310,'Taboão da Serra','BRA','São Paulo',197550);
+INSERT INTO City VALUES (311,'São José dos Pinhais','BRA','Paraná',196884);
+INSERT INTO City VALUES (312,'Magé','BRA','Rio de Janeiro',196147);
+INSERT INTO City VALUES (313,'Suzano','BRA','São Paulo',195434);
+INSERT INTO City VALUES (314,'São Leopoldo','BRA','Rio Grande do Sul',189258);
+INSERT INTO City VALUES (315,'Marília','BRA','São Paulo',188691);
+INSERT INTO City VALUES (316,'São Carlos','BRA','São Paulo',187122);
+INSERT INTO City VALUES (317,'Sumaré','BRA','São Paulo',186205);
+INSERT INTO City VALUES (318,'Presidente Prudente','BRA','São Paulo',185340);
+INSERT INTO City VALUES (319,'Divinópolis','BRA','Minas Gerais',185047);
+INSERT INTO City VALUES (320,'Sete Lagoas','BRA','Minas Gerais',182984);
+INSERT INTO City VALUES (321,'Rio Grande','BRA','Rio Grande do Sul',182222);
+INSERT INTO City VALUES (322,'Itabuna','BRA','Bahia',182148);
+INSERT INTO City VALUES (323,'Jequié','BRA','Bahia',179128);
+INSERT INTO City VALUES (324,'Arapiraca','BRA','Alagoas',178988);
+INSERT INTO City VALUES (325,'Colombo','BRA','Paraná',177764);
+INSERT INTO City VALUES (326,'Americana','BRA','São Paulo',177409);
+INSERT INTO City VALUES (327,'Alvorada','BRA','Rio Grande do Sul',175574);
+INSERT INTO City VALUES (328,'Araraquara','BRA','São Paulo',174381);
+INSERT INTO City VALUES (329,'Itaboraí','BRA','Rio de Janeiro',173977);
+INSERT INTO City VALUES (330,'Santa Bárbara d´Oeste','BRA','São Paulo',171657);
+INSERT INTO City VALUES (331,'Nova Friburgo','BRA','Rio de Janeiro',170697);
+INSERT INTO City VALUES (332,'Jacareí','BRA','São Paulo',170356);
+INSERT INTO City VALUES (333,'Araçatuba','BRA','São Paulo',169303);
+INSERT INTO City VALUES (334,'Barra Mansa','BRA','Rio de Janeiro',168953);
+INSERT INTO City VALUES (335,'Praia Grande','BRA','São Paulo',168434);
+INSERT INTO City VALUES (336,'Marabá','BRA','Pará',167795);
+INSERT INTO City VALUES (337,'Criciúma','BRA','Santa Catarina',167661);
+INSERT INTO City VALUES (338,'Boa Vista','BRA','Roraima',167185);
+INSERT INTO City VALUES (339,'Passo Fundo','BRA','Rio Grande do Sul',166343);
+INSERT INTO City VALUES (340,'Dourados','BRA','Mato Grosso do Sul',164716);
+INSERT INTO City VALUES (341,'Santa Luzia','BRA','Minas Gerais',164704);
+INSERT INTO City VALUES (342,'Rio Claro','BRA','São Paulo',163551);
+INSERT INTO City VALUES (343,'Maracanaú','BRA','Ceará',162022);
+INSERT INTO City VALUES (344,'Guarapuava','BRA','Paraná',160510);
+INSERT INTO City VALUES (345,'Rondonópolis','BRA','Mato Grosso',155115);
+INSERT INTO City VALUES (346,'São José','BRA','Santa Catarina',155105);
+INSERT INTO City VALUES (347,'Cachoeiro de Itapemirim','BRA','Espírito Santo',155024);
+INSERT INTO City VALUES (348,'Nilópolis','BRA','Rio de Janeiro',153383);
+INSERT INTO City VALUES (349,'Itapevi','BRA','São Paulo',150664);
+INSERT INTO City VALUES (350,'Cabo de Santo Agostinho','BRA','Pernambuco',149964);
+INSERT INTO City VALUES (351,'Camaçari','BRA','Bahia',149146);
+INSERT INTO City VALUES (352,'Sobral','BRA','Ceará',146005);
+INSERT INTO City VALUES (353,'Itajaí','BRA','Santa Catarina',145197);
+INSERT INTO City VALUES (354,'Chapecó','BRA','Santa Catarina',144158);
+INSERT INTO City VALUES (355,'Cotia','BRA','São Paulo',140042);
+INSERT INTO City VALUES (356,'Lages','BRA','Santa Catarina',139570);
+INSERT INTO City VALUES (357,'Ferraz de Vasconcelos','BRA','São Paulo',139283);
+INSERT INTO City VALUES (358,'Indaiatuba','BRA','São Paulo',135968);
+INSERT INTO City VALUES (359,'Hortolândia','BRA','São Paulo',135755);
+INSERT INTO City VALUES (360,'Caxias','BRA','Maranhão',133980);
+INSERT INTO City VALUES (361,'São Caetano do Sul','BRA','São Paulo',133321);
+INSERT INTO City VALUES (362,'Itu','BRA','São Paulo',132736);
+INSERT INTO City VALUES (363,'Nossa Senhora do Socorro','BRA','Sergipe',131351);
+INSERT INTO City VALUES (364,'Parnaíba','BRA','Piauí',129756);
+INSERT INTO City VALUES (365,'Poços de Caldas','BRA','Minas Gerais',129683);
+INSERT INTO City VALUES (366,'Teresópolis','BRA','Rio de Janeiro',128079);
+INSERT INTO City VALUES (367,'Barreiras','BRA','Bahia',127801);
+INSERT INTO City VALUES (368,'Castanhal','BRA','Pará',127634);
+INSERT INTO City VALUES (369,'Alagoinhas','BRA','Bahia',126820);
+INSERT INTO City VALUES (370,'Itapecerica da Serra','BRA','São Paulo',126672);
+INSERT INTO City VALUES (371,'Uruguaiana','BRA','Rio Grande do Sul',126305);
+INSERT INTO City VALUES (372,'Paranaguá','BRA','Paraná',126076);
+INSERT INTO City VALUES (373,'Ibirité','BRA','Minas Gerais',125982);
+INSERT INTO City VALUES (374,'Timon','BRA','Maranhão',125812);
+INSERT INTO City VALUES (375,'Luziânia','BRA','Goiás',125597);
+INSERT INTO City VALUES (376,'Macaé','BRA','Rio de Janeiro',125597);
+INSERT INTO City VALUES (377,'Teófilo Otoni','BRA','Minas Gerais',124489);
+INSERT INTO City VALUES (378,'Moji-Guaçu','BRA','São Paulo',123782);
+INSERT INTO City VALUES (379,'Palmas','BRA','Tocantins',121919);
+INSERT INTO City VALUES (380,'Pindamonhangaba','BRA','São Paulo',121904);
+INSERT INTO City VALUES (381,'Francisco Morato','BRA','São Paulo',121197);
+INSERT INTO City VALUES (382,'Bagé','BRA','Rio Grande do Sul',120793);
+INSERT INTO City VALUES (383,'Sapucaia do Sul','BRA','Rio Grande do Sul',120217);
+INSERT INTO City VALUES (384,'Cabo Frio','BRA','Rio de Janeiro',119503);
+INSERT INTO City VALUES (385,'Itapetininga','BRA','São Paulo',119391);
+INSERT INTO City VALUES (386,'Patos de Minas','BRA','Minas Gerais',119262);
+INSERT INTO City VALUES (387,'Camaragibe','BRA','Pernambuco',118968);
+INSERT INTO City VALUES (388,'Bragança Paulista','BRA','São Paulo',116929);
+INSERT INTO City VALUES (389,'Queimados','BRA','Rio de Janeiro',115020);
+INSERT INTO City VALUES (390,'Araguaína','BRA','Tocantins',114948);
+INSERT INTO City VALUES (391,'Garanhuns','BRA','Pernambuco',114603);
+INSERT INTO City VALUES (392,'Vitória de Santo Antão','BRA','Pernambuco',113595);
+INSERT INTO City VALUES (393,'Santa Rita','BRA','Paraíba',113135);
+INSERT INTO City VALUES (394,'Barbacena','BRA','Minas Gerais',113079);
+INSERT INTO City VALUES (395,'Abaetetuba','BRA','Pará',111258);
+INSERT INTO City VALUES (396,'Jaú','BRA','São Paulo',109965);
+INSERT INTO City VALUES (397,'Lauro de Freitas','BRA','Bahia',109236);
+INSERT INTO City VALUES (398,'Franco da Rocha','BRA','São Paulo',108964);
+INSERT INTO City VALUES (399,'Teixeira de Freitas','BRA','Bahia',108441);
+INSERT INTO City VALUES (400,'Varginha','BRA','Minas Gerais',108314);
+INSERT INTO City VALUES (401,'Ribeirão Pires','BRA','São Paulo',108121);
+INSERT INTO City VALUES (402,'Sabará','BRA','Minas Gerais',107781);
+INSERT INTO City VALUES (403,'Catanduva','BRA','São Paulo',107761);
+INSERT INTO City VALUES (404,'Rio Verde','BRA','Goiás',107755);
+INSERT INTO City VALUES (405,'Botucatu','BRA','São Paulo',107663);
+INSERT INTO City VALUES (406,'Colatina','BRA','Espírito Santo',107354);
+INSERT INTO City VALUES (407,'Santa Cruz do Sul','BRA','Rio Grande do Sul',106734);
+INSERT INTO City VALUES (408,'Linhares','BRA','Espírito Santo',106278);
+INSERT INTO City VALUES (409,'Apucarana','BRA','Paraná',105114);
+INSERT INTO City VALUES (410,'Barretos','BRA','São Paulo',104156);
+INSERT INTO City VALUES (411,'Guaratinguetá','BRA','São Paulo',103433);
+INSERT INTO City VALUES (412,'Cachoeirinha','BRA','Rio Grande do Sul',103240);
+INSERT INTO City VALUES (413,'Codó','BRA','Maranhão',103153);
+INSERT INTO City VALUES (414,'Jaraguá do Sul','BRA','Santa Catarina',102580);
+INSERT INTO City VALUES (415,'Cubatão','BRA','São Paulo',102372);
+INSERT INTO City VALUES (416,'Itabira','BRA','Minas Gerais',102217);
+INSERT INTO City VALUES (417,'Itaituba','BRA','Pará',101320);
+INSERT INTO City VALUES (418,'Araras','BRA','São Paulo',101046);
+INSERT INTO City VALUES (419,'Resende','BRA','Rio de Janeiro',100627);
+INSERT INTO City VALUES (420,'Atibaia','BRA','São Paulo',100356);
+INSERT INTO City VALUES (421,'Pouso Alegre','BRA','Minas Gerais',100028);
+INSERT INTO City VALUES (422,'Toledo','BRA','Paraná',99387);
+INSERT INTO City VALUES (423,'Crato','BRA','Ceará',98965);
+INSERT INTO City VALUES (424,'Passos','BRA','Minas Gerais',98570);
+INSERT INTO City VALUES (425,'Araguari','BRA','Minas Gerais',98399);
+INSERT INTO City VALUES (426,'São José de Ribamar','BRA','Maranhão',98318);
+INSERT INTO City VALUES (427,'Pinhais','BRA','Paraná',98198);
+INSERT INTO City VALUES (428,'Sertãozinho','BRA','São Paulo',98140);
+INSERT INTO City VALUES (429,'Conselheiro Lafaiete','BRA','Minas Gerais',97507);
+INSERT INTO City VALUES (430,'Paulo Afonso','BRA','Bahia',97291);
+INSERT INTO City VALUES (431,'Angra dos Reis','BRA','Rio de Janeiro',96864);
+INSERT INTO City VALUES (432,'Eunápolis','BRA','Bahia',96610);
+INSERT INTO City VALUES (433,'Salto','BRA','São Paulo',96348);
+INSERT INTO City VALUES (434,'Ourinhos','BRA','São Paulo',96291);
+INSERT INTO City VALUES (435,'Parnamirim','BRA','Rio Grande do Norte',96210);
+INSERT INTO City VALUES (436,'Jacobina','BRA','Bahia',96131);
+INSERT INTO City VALUES (437,'Coronel Fabriciano','BRA','Minas Gerais',95933);
+INSERT INTO City VALUES (438,'Birigui','BRA','São Paulo',94685);
+INSERT INTO City VALUES (439,'Tatuí','BRA','São Paulo',93897);
+INSERT INTO City VALUES (440,'Ji-Paraná','BRA','Rondônia',93346);
+INSERT INTO City VALUES (441,'Bacabal','BRA','Maranhão',93121);
+INSERT INTO City VALUES (442,'Cametá','BRA','Pará',92779);
+INSERT INTO City VALUES (443,'Guaíba','BRA','Rio Grande do Sul',92224);
+INSERT INTO City VALUES (444,'São Lourenço da Mata','BRA','Pernambuco',91999);
+INSERT INTO City VALUES (445,'Santana do Livramento','BRA','Rio Grande do Sul',91779);
+INSERT INTO City VALUES (446,'Votorantim','BRA','São Paulo',91777);
+INSERT INTO City VALUES (447,'Campo Largo','BRA','Paraná',91203);
+INSERT INTO City VALUES (448,'Patos','BRA','Paraíba',90519);
+INSERT INTO City VALUES (449,'Ituiutaba','BRA','Minas Gerais',90507);
+INSERT INTO City VALUES (450,'Corumbá','BRA','Mato Grosso do Sul',90111);
+INSERT INTO City VALUES (451,'Palhoça','BRA','Santa Catarina',89465);
+INSERT INTO City VALUES (452,'Barra do Piraí','BRA','Rio de Janeiro',89388);
+INSERT INTO City VALUES (453,'Bento Gonçalves','BRA','Rio Grande do Sul',89254);
+INSERT INTO City VALUES (454,'Poá','BRA','São Paulo',89236);
+INSERT INTO City VALUES (455,'Águas Lindas de Goiás','BRA','Goiás',89200);
+INSERT INTO City VALUES (456,'London','GBR','England',7285000);
+INSERT INTO City VALUES (457,'Birmingham','GBR','England',1013000);
+INSERT INTO City VALUES (458,'Glasgow','GBR','Scotland',619680);
+INSERT INTO City VALUES (459,'Liverpool','GBR','England',461000);
+INSERT INTO City VALUES (460,'Edinburgh','GBR','Scotland',450180);
+INSERT INTO City VALUES (461,'Sheffield','GBR','England',431607);
+INSERT INTO City VALUES (462,'Manchester','GBR','England',430000);
+INSERT INTO City VALUES (463,'Leeds','GBR','England',424194);
+INSERT INTO City VALUES (464,'Bristol','GBR','England',402000);
+INSERT INTO City VALUES (465,'Cardiff','GBR','Wales',321000);
+INSERT INTO City VALUES (466,'Coventry','GBR','England',304000);
+INSERT INTO City VALUES (467,'Leicester','GBR','England',294000);
+INSERT INTO City VALUES (468,'Bradford','GBR','England',289376);
+INSERT INTO City VALUES (469,'Belfast','GBR','North Ireland',287500);
+INSERT INTO City VALUES (470,'Nottingham','GBR','England',287000);
+INSERT INTO City VALUES (471,'Kingston upon Hull','GBR','England',262000);
+INSERT INTO City VALUES (472,'Plymouth','GBR','England',253000);
+INSERT INTO City VALUES (473,'Stoke-on-Trent','GBR','England',252000);
+INSERT INTO City VALUES (474,'Wolverhampton','GBR','England',242000);
+INSERT INTO City VALUES (475,'Derby','GBR','England',236000);
+INSERT INTO City VALUES (476,'Swansea','GBR','Wales',230000);
+INSERT INTO City VALUES (477,'Southampton','GBR','England',216000);
+INSERT INTO City VALUES (478,'Aberdeen','GBR','Scotland',213070);
+INSERT INTO City VALUES (479,'Northampton','GBR','England',196000);
+INSERT INTO City VALUES (480,'Dudley','GBR','England',192171);
+INSERT INTO City VALUES (481,'Portsmouth','GBR','England',190000);
+INSERT INTO City VALUES (482,'Newcastle upon Tyne','GBR','England',189150);
+INSERT INTO City VALUES (483,'Sunderland','GBR','England',183310);
+INSERT INTO City VALUES (484,'Luton','GBR','England',183000);
+INSERT INTO City VALUES (485,'Swindon','GBR','England',180000);
+INSERT INTO City VALUES (486,'Southend-on-Sea','GBR','England',176000);
+INSERT INTO City VALUES (487,'Walsall','GBR','England',174739);
+INSERT INTO City VALUES (488,'Bournemouth','GBR','England',162000);
+INSERT INTO City VALUES (489,'Peterborough','GBR','England',156000);
+INSERT INTO City VALUES (490,'Brighton','GBR','England',156124);
+INSERT INTO City VALUES (491,'Blackpool','GBR','England',151000);
+INSERT INTO City VALUES (492,'Dundee','GBR','Scotland',146690);
+INSERT INTO City VALUES (493,'West Bromwich','GBR','England',146386);
+INSERT INTO City VALUES (494,'Reading','GBR','England',148000);
+INSERT INTO City VALUES (495,'Oldbury/Smethwick (Warley)','GBR','England',145542);
+INSERT INTO City VALUES (496,'Middlesbrough','GBR','England',145000);
+INSERT INTO City VALUES (497,'Huddersfield','GBR','England',143726);
+INSERT INTO City VALUES (498,'Oxford','GBR','England',144000);
+INSERT INTO City VALUES (499,'Poole','GBR','England',141000);
+INSERT INTO City VALUES (500,'Bolton','GBR','England',139020);
+INSERT INTO City VALUES (501,'Blackburn','GBR','England',140000);
+INSERT INTO City VALUES (502,'Newport','GBR','Wales',139000);
+INSERT INTO City VALUES (503,'Preston','GBR','England',135000);
+INSERT INTO City VALUES (504,'Stockport','GBR','England',132813);
+INSERT INTO City VALUES (505,'Norwich','GBR','England',124000);
+INSERT INTO City VALUES (506,'Rotherham','GBR','England',121380);
+INSERT INTO City VALUES (507,'Cambridge','GBR','England',121000);
+INSERT INTO City VALUES (508,'Watford','GBR','England',113080);
+INSERT INTO City VALUES (509,'Ipswich','GBR','England',114000);
+INSERT INTO City VALUES (510,'Slough','GBR','England',112000);
+INSERT INTO City VALUES (511,'Exeter','GBR','England',111000);
+INSERT INTO City VALUES (512,'Cheltenham','GBR','England',106000);
+INSERT INTO City VALUES (513,'Gloucester','GBR','England',107000);
+INSERT INTO City VALUES (514,'Saint Helens','GBR','England',106293);
+INSERT INTO City VALUES (515,'Sutton Coldfield','GBR','England',106001);
+INSERT INTO City VALUES (516,'York','GBR','England',104425);
+INSERT INTO City VALUES (517,'Oldham','GBR','England',103931);
+INSERT INTO City VALUES (518,'Basildon','GBR','England',100924);
+INSERT INTO City VALUES (519,'Worthing','GBR','England',100000);
+INSERT INTO City VALUES (520,'Chelmsford','GBR','England',97451);
+INSERT INTO City VALUES (521,'Colchester','GBR','England',96063);
+INSERT INTO City VALUES (522,'Crawley','GBR','England',97000);
+INSERT INTO City VALUES (523,'Gillingham','GBR','England',92000);
+INSERT INTO City VALUES (524,'Solihull','GBR','England',94531);
+INSERT INTO City VALUES (525,'Rochdale','GBR','England',94313);
+INSERT INTO City VALUES (526,'Birkenhead','GBR','England',93087);
+INSERT INTO City VALUES (527,'Worcester','GBR','England',95000);
+INSERT INTO City VALUES (528,'Hartlepool','GBR','England',92000);
+INSERT INTO City VALUES (529,'Halifax','GBR','England',91069);
+INSERT INTO City VALUES (530,'Woking/Byfleet','GBR','England',92000);
+INSERT INTO City VALUES (531,'Southport','GBR','England',90959);
+INSERT INTO City VALUES (532,'Maidstone','GBR','England',90878);
+INSERT INTO City VALUES (533,'Eastbourne','GBR','England',90000);
+INSERT INTO City VALUES (534,'Grimsby','GBR','England',89000);
+INSERT INTO City VALUES (535,'Saint Helier','GBR','Jersey',27523);
+INSERT INTO City VALUES (536,'Douglas','GBR','–',23487);
+INSERT INTO City VALUES (537,'Road Town','VGB','Tortola',8000);
+INSERT INTO City VALUES (538,'Bandar Seri Begawan','BRN','Brunei and Muara',21484);
+INSERT INTO City VALUES (539,'Sofija','BGR','Grad Sofija',1122302);
+INSERT INTO City VALUES (540,'Plovdiv','BGR','Plovdiv',342584);
+INSERT INTO City VALUES (541,'Varna','BGR','Varna',299801);
+INSERT INTO City VALUES (542,'Burgas','BGR','Burgas',195255);
+INSERT INTO City VALUES (543,'Ruse','BGR','Ruse',166467);
+INSERT INTO City VALUES (544,'Stara Zagora','BGR','Haskovo',147939);
+INSERT INTO City VALUES (545,'Pleven','BGR','Lovec',121952);
+INSERT INTO City VALUES (546,'Sliven','BGR','Burgas',105530);
+INSERT INTO City VALUES (547,'Dobric','BGR','Varna',100399);
+INSERT INTO City VALUES (548,'Šumen','BGR','Varna',94686);
+INSERT INTO City VALUES (549,'Ouagadougou','BFA','Kadiogo',824000);
+INSERT INTO City VALUES (550,'Bobo-Dioulasso','BFA','Houet',300000);
+INSERT INTO City VALUES (551,'Koudougou','BFA','Boulkiemdé',105000);
+INSERT INTO City VALUES (552,'Bujumbura','BDI','Bujumbura',300000);
+INSERT INTO City VALUES (553,'George Town','CYM','Grand Cayman',19600);
+INSERT INTO City VALUES (554,'Santiago de Chile','CHL','Santiago',4703954);
+INSERT INTO City VALUES (555,'Puente Alto','CHL','Santiago',386236);
+INSERT INTO City VALUES (556,'Viña del Mar','CHL','Valparaíso',312493);
+INSERT INTO City VALUES (557,'Valparaíso','CHL','Valparaíso',293800);
+INSERT INTO City VALUES (558,'Talcahuano','CHL','Bíobío',277752);
+INSERT INTO City VALUES (559,'Antofagasta','CHL','Antofagasta',251429);
+INSERT INTO City VALUES (560,'San Bernardo','CHL','Santiago',241910);
+INSERT INTO City VALUES (561,'Temuco','CHL','La Araucanía',233041);
+INSERT INTO City VALUES (562,'Concepción','CHL','Bíobío',217664);
+INSERT INTO City VALUES (563,'Rancagua','CHL','O´Higgins',212977);
+INSERT INTO City VALUES (564,'Arica','CHL','Tarapacá',189036);
+INSERT INTO City VALUES (565,'Talca','CHL','Maule',187557);
+INSERT INTO City VALUES (566,'Chillán','CHL','Bíobío',178182);
+INSERT INTO City VALUES (567,'Iquique','CHL','Tarapacá',177892);
+INSERT INTO City VALUES (568,'Los Angeles','CHL','Bíobío',158215);
+INSERT INTO City VALUES (569,'Puerto Montt','CHL','Los Lagos',152194);
+INSERT INTO City VALUES (570,'Coquimbo','CHL','Coquimbo',143353);
+INSERT INTO City VALUES (571,'Osorno','CHL','Los Lagos',141468);
+INSERT INTO City VALUES (572,'La Serena','CHL','Coquimbo',137409);
+INSERT INTO City VALUES (573,'Calama','CHL','Antofagasta',137265);
+INSERT INTO City VALUES (574,'Valdivia','CHL','Los Lagos',133106);
+INSERT INTO City VALUES (575,'Punta Arenas','CHL','Magallanes',125631);
+INSERT INTO City VALUES (576,'Copiapó','CHL','Atacama',120128);
+INSERT INTO City VALUES (577,'Quilpué','CHL','Valparaíso',118857);
+INSERT INTO City VALUES (578,'Curicó','CHL','Maule',115766);
+INSERT INTO City VALUES (579,'Ovalle','CHL','Coquimbo',94854);
+INSERT INTO City VALUES (580,'Coronel','CHL','Bíobío',93061);
+INSERT INTO City VALUES (581,'San Pedro de la Paz','CHL','Bíobío',91684);
+INSERT INTO City VALUES (582,'Melipilla','CHL','Santiago',91056);
+INSERT INTO City VALUES (583,'Avarua','COK','Rarotonga',11900);
+INSERT INTO City VALUES (584,'San José','CRI','San José',339131);
+INSERT INTO City VALUES (585,'Djibouti','DJI','Djibouti',383000);
+INSERT INTO City VALUES (586,'Roseau','DMA','St George',16243);
+INSERT INTO City VALUES (587,'Santo Domingo de Guzmán','DOM','Distrito Nacional',1609966);
+INSERT INTO City VALUES (588,'Santiago de los Caballeros','DOM','Santiago',365463);
+INSERT INTO City VALUES (589,'La Romana','DOM','La Romana',140204);
+INSERT INTO City VALUES (590,'San Pedro de Macorís','DOM','San Pedro de Macorís',124735);
+INSERT INTO City VALUES (591,'San Francisco de Macorís','DOM','Duarte',108485);
+INSERT INTO City VALUES (592,'San Felipe de Puerto Plata','DOM','Puerto Plata',89423);
+INSERT INTO City VALUES (593,'Guayaquil','ECU','Guayas',2070040);
+INSERT INTO City VALUES (594,'Quito','ECU','Pichincha',1573458);
+INSERT INTO City VALUES (595,'Cuenca','ECU','Azuay',270353);
+INSERT INTO City VALUES (596,'Machala','ECU','El Oro',210368);
+INSERT INTO City VALUES (597,'Santo Domingo de los Colorados','ECU','Pichincha',202111);
+INSERT INTO City VALUES (598,'Portoviejo','ECU','Manabí',176413);
+INSERT INTO City VALUES (599,'Ambato','ECU','Tungurahua',169612);
+INSERT INTO City VALUES (600,'Manta','ECU','Manabí',164739);
+INSERT INTO City VALUES (601,'Duran [Eloy Alfaro]','ECU','Guayas',152514);
+INSERT INTO City VALUES (602,'Ibarra','ECU','Imbabura',130643);
+INSERT INTO City VALUES (603,'Quevedo','ECU','Los Ríos',129631);
+INSERT INTO City VALUES (604,'Milagro','ECU','Guayas',124177);
+INSERT INTO City VALUES (605,'Loja','ECU','Loja',123875);
+INSERT INTO City VALUES (606,'Ríobamba','ECU','Chimborazo',123163);
+INSERT INTO City VALUES (607,'Esmeraldas','ECU','Esmeraldas',123045);
+INSERT INTO City VALUES (608,'Cairo','EGY','Kairo',6789479);
+INSERT INTO City VALUES (609,'Alexandria','EGY','Aleksandria',3328196);
+INSERT INTO City VALUES (610,'Giza','EGY','Giza',2221868);
+INSERT INTO City VALUES (611,'Shubra al-Khayma','EGY','al-Qalyubiya',870716);
+INSERT INTO City VALUES (612,'Port Said','EGY','Port Said',469533);
+INSERT INTO City VALUES (613,'Suez','EGY','Suez',417610);
+INSERT INTO City VALUES (614,'al-Mahallat al-Kubra','EGY','al-Gharbiya',395402);
+INSERT INTO City VALUES (615,'Tanta','EGY','al-Gharbiya',371010);
+INSERT INTO City VALUES (616,'al-Mansura','EGY','al-Daqahliya',369621);
+INSERT INTO City VALUES (617,'Luxor','EGY','Luxor',360503);
+INSERT INTO City VALUES (618,'Asyut','EGY','Asyut',343498);
+INSERT INTO City VALUES (619,'Bahtim','EGY','al-Qalyubiya',275807);
+INSERT INTO City VALUES (620,'Zagazig','EGY','al-Sharqiya',267351);
+INSERT INTO City VALUES (621,'al-Faiyum','EGY','al-Faiyum',260964);
+INSERT INTO City VALUES (622,'Ismailia','EGY','Ismailia',254477);
+INSERT INTO City VALUES (623,'Kafr al-Dawwar','EGY','al-Buhayra',231978);
+INSERT INTO City VALUES (624,'Assuan','EGY','Assuan',219017);
+INSERT INTO City VALUES (625,'Damanhur','EGY','al-Buhayra',212203);
+INSERT INTO City VALUES (626,'al-Minya','EGY','al-Minya',201360);
+INSERT INTO City VALUES (627,'Bani Suwayf','EGY','Bani Suwayf',172032);
+INSERT INTO City VALUES (628,'Qina','EGY','Qina',171275);
+INSERT INTO City VALUES (629,'Sawhaj','EGY','Sawhaj',170125);
+INSERT INTO City VALUES (630,'Shibin al-Kawm','EGY','al-Minufiya',159909);
+INSERT INTO City VALUES (631,'Bulaq al-Dakrur','EGY','Giza',148787);
+INSERT INTO City VALUES (632,'Banha','EGY','al-Qalyubiya',145792);
+INSERT INTO City VALUES (633,'Warraq al-Arab','EGY','Giza',127108);
+INSERT INTO City VALUES (634,'Kafr al-Shaykh','EGY','Kafr al-Shaykh',124819);
+INSERT INTO City VALUES (635,'Mallawi','EGY','al-Minya',119283);
+INSERT INTO City VALUES (636,'Bilbays','EGY','al-Sharqiya',113608);
+INSERT INTO City VALUES (637,'Mit Ghamr','EGY','al-Daqahliya',101801);
+INSERT INTO City VALUES (638,'al-Arish','EGY','Shamal Sina',100447);
+INSERT INTO City VALUES (639,'Talkha','EGY','al-Daqahliya',97700);
+INSERT INTO City VALUES (640,'Qalyub','EGY','al-Qalyubiya',97200);
+INSERT INTO City VALUES (641,'Jirja','EGY','Sawhaj',95400);
+INSERT INTO City VALUES (642,'Idfu','EGY','Qina',94200);
+INSERT INTO City VALUES (643,'al-Hawamidiya','EGY','Giza',91700);
+INSERT INTO City VALUES (644,'Disuq','EGY','Kafr al-Shaykh',91300);
+INSERT INTO City VALUES (645,'San Salvador','SLV','San Salvador',415346);
+INSERT INTO City VALUES (646,'Santa Ana','SLV','Santa Ana',139389);
+INSERT INTO City VALUES (647,'Mejicanos','SLV','San Salvador',138800);
+INSERT INTO City VALUES (648,'Soyapango','SLV','San Salvador',129800);
+INSERT INTO City VALUES (649,'San Miguel','SLV','San Miguel',127696);
+INSERT INTO City VALUES (650,'Nueva San Salvador','SLV','La Libertad',98400);
+INSERT INTO City VALUES (651,'Apopa','SLV','San Salvador',88800);
+INSERT INTO City VALUES (652,'Asmara','ERI','Maekel',431000);
+INSERT INTO City VALUES (653,'Madrid','ESP','Madrid',2879052);
+INSERT INTO City VALUES (654,'Barcelona','ESP','Katalonia',1503451);
+INSERT INTO City VALUES (655,'Valencia','ESP','Valencia',739412);
+INSERT INTO City VALUES (656,'Sevilla','ESP','Andalusia',701927);
+INSERT INTO City VALUES (657,'Zaragoza','ESP','Aragonia',603367);
+INSERT INTO City VALUES (658,'Málaga','ESP','Andalusia',530553);
+INSERT INTO City VALUES (659,'Bilbao','ESP','Baskimaa',357589);
+INSERT INTO City VALUES (660,'Las Palmas de Gran Canaria','ESP','Canary Islands',354757);
+INSERT INTO City VALUES (661,'Murcia','ESP','Murcia',353504);
+INSERT INTO City VALUES (662,'Palma de Mallorca','ESP','Balears',326993);
+INSERT INTO City VALUES (663,'Valladolid','ESP','Castilla and León',319998);
+INSERT INTO City VALUES (664,'Córdoba','ESP','Andalusia',311708);
+INSERT INTO City VALUES (665,'Vigo','ESP','Galicia',283670);
+INSERT INTO City VALUES (666,'Alicante [Alacant]','ESP','Valencia',272432);
+INSERT INTO City VALUES (667,'Gijón','ESP','Asturia',267980);
+INSERT INTO City VALUES (668,'L´Hospitalet de Llobregat','ESP','Katalonia',247986);
+INSERT INTO City VALUES (669,'Granada','ESP','Andalusia',244767);
+INSERT INTO City VALUES (670,'A Coruña (La Coruña)','ESP','Galicia',243402);
+INSERT INTO City VALUES (671,'Vitoria-Gasteiz','ESP','Baskimaa',217154);
+INSERT INTO City VALUES (672,'Santa Cruz de Tenerife','ESP','Canary Islands',213050);
+INSERT INTO City VALUES (673,'Badalona','ESP','Katalonia',209635);
+INSERT INTO City VALUES (674,'Oviedo','ESP','Asturia',200453);
+INSERT INTO City VALUES (675,'Móstoles','ESP','Madrid',195351);
+INSERT INTO City VALUES (676,'Elche [Elx]','ESP','Valencia',193174);
+INSERT INTO City VALUES (677,'Sabadell','ESP','Katalonia',184859);
+INSERT INTO City VALUES (678,'Santander','ESP','Cantabria',184165);
+INSERT INTO City VALUES (679,'Jerez de la Frontera','ESP','Andalusia',182660);
+INSERT INTO City VALUES (680,'Pamplona [Iruña]','ESP','Navarra',180483);
+INSERT INTO City VALUES (681,'Donostia-San Sebastián','ESP','Baskimaa',179208);
+INSERT INTO City VALUES (682,'Cartagena','ESP','Murcia',177709);
+INSERT INTO City VALUES (683,'Leganés','ESP','Madrid',173163);
+INSERT INTO City VALUES (684,'Fuenlabrada','ESP','Madrid',171173);
+INSERT INTO City VALUES (685,'Almería','ESP','Andalusia',169027);
+INSERT INTO City VALUES (686,'Terrassa','ESP','Katalonia',168695);
+INSERT INTO City VALUES (687,'Alcalá de Henares','ESP','Madrid',164463);
+INSERT INTO City VALUES (688,'Burgos','ESP','Castilla and León',162802);
+INSERT INTO City VALUES (689,'Salamanca','ESP','Castilla and León',158720);
+INSERT INTO City VALUES (690,'Albacete','ESP','Kastilia-La Mancha',147527);
+INSERT INTO City VALUES (691,'Getafe','ESP','Madrid',145371);
+INSERT INTO City VALUES (692,'Cádiz','ESP','Andalusia',142449);
+INSERT INTO City VALUES (693,'Alcorcón','ESP','Madrid',142048);
+INSERT INTO City VALUES (694,'Huelva','ESP','Andalusia',140583);
+INSERT INTO City VALUES (695,'León','ESP','Castilla and León',139809);
+INSERT INTO City VALUES (696,'Castellón de la Plana [Castell','ESP','Valencia',139712);
+INSERT INTO City VALUES (697,'Badajoz','ESP','Extremadura',136613);
+INSERT INTO City VALUES (698,'[San Cristóbal de] la Laguna','ESP','Canary Islands',127945);
+INSERT INTO City VALUES (699,'Logroño','ESP','La Rioja',127093);
+INSERT INTO City VALUES (700,'Santa Coloma de Gramenet','ESP','Katalonia',120802);
+INSERT INTO City VALUES (701,'Tarragona','ESP','Katalonia',113016);
+INSERT INTO City VALUES (702,'Lleida (Lérida)','ESP','Katalonia',112207);
+INSERT INTO City VALUES (703,'Jaén','ESP','Andalusia',109247);
+INSERT INTO City VALUES (704,'Ourense (Orense)','ESP','Galicia',109120);
+INSERT INTO City VALUES (705,'Mataró','ESP','Katalonia',104095);
+INSERT INTO City VALUES (706,'Algeciras','ESP','Andalusia',103106);
+INSERT INTO City VALUES (707,'Marbella','ESP','Andalusia',101144);
+INSERT INTO City VALUES (708,'Barakaldo','ESP','Baskimaa',98212);
+INSERT INTO City VALUES (709,'Dos Hermanas','ESP','Andalusia',94591);
+INSERT INTO City VALUES (710,'Santiago de Compostela','ESP','Galicia',93745);
+INSERT INTO City VALUES (711,'Torrejón de Ardoz','ESP','Madrid',92262);
+INSERT INTO City VALUES (712,'Cape Town','ZAF','Western Cape',2352121);
+INSERT INTO City VALUES (713,'Soweto','ZAF','Gauteng',904165);
+INSERT INTO City VALUES (714,'Johannesburg','ZAF','Gauteng',756653);
+INSERT INTO City VALUES (715,'Port Elizabeth','ZAF','Eastern Cape',752319);
+INSERT INTO City VALUES (716,'Pretoria','ZAF','Gauteng',658630);
+INSERT INTO City VALUES (717,'Inanda','ZAF','KwaZulu-Natal',634065);
+INSERT INTO City VALUES (718,'Durban','ZAF','KwaZulu-Natal',566120);
+INSERT INTO City VALUES (719,'Vanderbijlpark','ZAF','Gauteng',468931);
+INSERT INTO City VALUES (720,'Kempton Park','ZAF','Gauteng',442633);
+INSERT INTO City VALUES (721,'Alberton','ZAF','Gauteng',410102);
+INSERT INTO City VALUES (722,'Pinetown','ZAF','KwaZulu-Natal',378810);
+INSERT INTO City VALUES (723,'Pietermaritzburg','ZAF','KwaZulu-Natal',370190);
+INSERT INTO City VALUES (724,'Benoni','ZAF','Gauteng',365467);
+INSERT INTO City VALUES (725,'Randburg','ZAF','Gauteng',341288);
+INSERT INTO City VALUES (726,'Umlazi','ZAF','KwaZulu-Natal',339233);
+INSERT INTO City VALUES (727,'Bloemfontein','ZAF','Free State',334341);
+INSERT INTO City VALUES (728,'Vereeniging','ZAF','Gauteng',328535);
+INSERT INTO City VALUES (729,'Wonderboom','ZAF','Gauteng',283289);
+INSERT INTO City VALUES (730,'Roodepoort','ZAF','Gauteng',279340);
+INSERT INTO City VALUES (731,'Boksburg','ZAF','Gauteng',262648);
+INSERT INTO City VALUES (732,'Klerksdorp','ZAF','North West',261911);
+INSERT INTO City VALUES (733,'Soshanguve','ZAF','Gauteng',242727);
+INSERT INTO City VALUES (734,'Newcastle','ZAF','KwaZulu-Natal',222993);
+INSERT INTO City VALUES (735,'East London','ZAF','Eastern Cape',221047);
+INSERT INTO City VALUES (736,'Welkom','ZAF','Free State',203296);
+INSERT INTO City VALUES (737,'Kimberley','ZAF','Northern Cape',197254);
+INSERT INTO City VALUES (738,'Uitenhage','ZAF','Eastern Cape',192120);
+INSERT INTO City VALUES (739,'Chatsworth','ZAF','KwaZulu-Natal',189885);
+INSERT INTO City VALUES (740,'Mdantsane','ZAF','Eastern Cape',182639);
+INSERT INTO City VALUES (741,'Krugersdorp','ZAF','Gauteng',181503);
+INSERT INTO City VALUES (742,'Botshabelo','ZAF','Free State',177971);
+INSERT INTO City VALUES (743,'Brakpan','ZAF','Gauteng',171363);
+INSERT INTO City VALUES (744,'Witbank','ZAF','Mpumalanga',167183);
+INSERT INTO City VALUES (745,'Oberholzer','ZAF','Gauteng',164367);
+INSERT INTO City VALUES (746,'Germiston','ZAF','Gauteng',164252);
+INSERT INTO City VALUES (747,'Springs','ZAF','Gauteng',162072);
+INSERT INTO City VALUES (748,'Westonaria','ZAF','Gauteng',159632);
+INSERT INTO City VALUES (749,'Randfontein','ZAF','Gauteng',120838);
+INSERT INTO City VALUES (750,'Paarl','ZAF','Western Cape',105768);
+INSERT INTO City VALUES (751,'Potchefstroom','ZAF','North West',101817);
+INSERT INTO City VALUES (752,'Rustenburg','ZAF','North West',97008);
+INSERT INTO City VALUES (753,'Nigel','ZAF','Gauteng',96734);
+INSERT INTO City VALUES (754,'George','ZAF','Western Cape',93818);
+INSERT INTO City VALUES (755,'Ladysmith','ZAF','KwaZulu-Natal',89292);
+INSERT INTO City VALUES (756,'Addis Abeba','ETH','Addis Abeba',2495000);
+INSERT INTO City VALUES (757,'Dire Dawa','ETH','Dire Dawa',164851);
+INSERT INTO City VALUES (758,'Nazret','ETH','Oromia',127842);
+INSERT INTO City VALUES (759,'Gonder','ETH','Amhara',112249);
+INSERT INTO City VALUES (760,'Dese','ETH','Amhara',97314);
+INSERT INTO City VALUES (761,'Mekele','ETH','Tigray',96938);
+INSERT INTO City VALUES (762,'Bahir Dar','ETH','Amhara',96140);
+INSERT INTO City VALUES (763,'Stanley','FLK','East Falkland',1636);
+INSERT INTO City VALUES (764,'Suva','FJI','Central',77366);
+INSERT INTO City VALUES (765,'Quezon','PHL','National Capital Reg',2173831);
+INSERT INTO City VALUES (766,'Manila','PHL','National Capital Reg',1581082);
+INSERT INTO City VALUES (767,'Kalookan','PHL','National Capital Reg',1177604);
+INSERT INTO City VALUES (768,'Davao','PHL','Southern Mindanao',1147116);
+INSERT INTO City VALUES (769,'Cebu','PHL','Central Visayas',718821);
+INSERT INTO City VALUES (770,'Zamboanga','PHL','Western Mindanao',601794);
+INSERT INTO City VALUES (771,'Pasig','PHL','National Capital Reg',505058);
+INSERT INTO City VALUES (772,'Valenzuela','PHL','National Capital Reg',485433);
+INSERT INTO City VALUES (773,'Las Piñas','PHL','National Capital Reg',472780);
+INSERT INTO City VALUES (774,'Antipolo','PHL','Southern Tagalog',470866);
+INSERT INTO City VALUES (775,'Taguig','PHL','National Capital Reg',467375);
+INSERT INTO City VALUES (776,'Cagayan de Oro','PHL','Northern Mindanao',461877);
+INSERT INTO City VALUES (777,'Parañaque','PHL','National Capital Reg',449811);
+INSERT INTO City VALUES (778,'Makati','PHL','National Capital Reg',444867);
+INSERT INTO City VALUES (779,'Bacolod','PHL','Western Visayas',429076);
+INSERT INTO City VALUES (780,'General Santos','PHL','Southern Mindanao',411822);
+INSERT INTO City VALUES (781,'Marikina','PHL','National Capital Reg',391170);
+INSERT INTO City VALUES (782,'Dasmariñas','PHL','Southern Tagalog',379520);
+INSERT INTO City VALUES (783,'Muntinlupa','PHL','National Capital Reg',379310);
+INSERT INTO City VALUES (784,'Iloilo','PHL','Western Visayas',365820);
+INSERT INTO City VALUES (785,'Pasay','PHL','National Capital Reg',354908);
+INSERT INTO City VALUES (786,'Malabon','PHL','National Capital Reg',338855);
+INSERT INTO City VALUES (787,'San José del Monte','PHL','Central Luzon',315807);
+INSERT INTO City VALUES (788,'Bacoor','PHL','Southern Tagalog',305699);
+INSERT INTO City VALUES (789,'Iligan','PHL','Central Mindanao',285061);
+INSERT INTO City VALUES (790,'Calamba','PHL','Southern Tagalog',281146);
+INSERT INTO City VALUES (791,'Mandaluyong','PHL','National Capital Reg',278474);
+INSERT INTO City VALUES (792,'Butuan','PHL','Caraga',267279);
+INSERT INTO City VALUES (793,'Angeles','PHL','Central Luzon',263971);
+INSERT INTO City VALUES (794,'Tarlac','PHL','Central Luzon',262481);
+INSERT INTO City VALUES (795,'Mandaue','PHL','Central Visayas',259728);
+INSERT INTO City VALUES (796,'Baguio','PHL','CAR',252386);
+INSERT INTO City VALUES (797,'Batangas','PHL','Southern Tagalog',247588);
+INSERT INTO City VALUES (798,'Cainta','PHL','Southern Tagalog',242511);
+INSERT INTO City VALUES (799,'San Pedro','PHL','Southern Tagalog',231403);
+INSERT INTO City VALUES (800,'Navotas','PHL','National Capital Reg',230403);
+INSERT INTO City VALUES (801,'Cabanatuan','PHL','Central Luzon',222859);
+INSERT INTO City VALUES (802,'San Fernando','PHL','Central Luzon',221857);
+INSERT INTO City VALUES (803,'Lipa','PHL','Southern Tagalog',218447);
+INSERT INTO City VALUES (804,'Lapu-Lapu','PHL','Central Visayas',217019);
+INSERT INTO City VALUES (805,'San Pablo','PHL','Southern Tagalog',207927);
+INSERT INTO City VALUES (806,'Biñan','PHL','Southern Tagalog',201186);
+INSERT INTO City VALUES (807,'Taytay','PHL','Southern Tagalog',198183);
+INSERT INTO City VALUES (808,'Lucena','PHL','Southern Tagalog',196075);
+INSERT INTO City VALUES (809,'Imus','PHL','Southern Tagalog',195482);
+INSERT INTO City VALUES (810,'Olongapo','PHL','Central Luzon',194260);
+INSERT INTO City VALUES (811,'Binangonan','PHL','Southern Tagalog',187691);
+INSERT INTO City VALUES (812,'Santa Rosa','PHL','Southern Tagalog',185633);
+INSERT INTO City VALUES (813,'Tagum','PHL','Southern Mindanao',179531);
+INSERT INTO City VALUES (814,'Tacloban','PHL','Eastern Visayas',178639);
+INSERT INTO City VALUES (815,'Malolos','PHL','Central Luzon',175291);
+INSERT INTO City VALUES (816,'Mabalacat','PHL','Central Luzon',171045);
+INSERT INTO City VALUES (817,'Cotabato','PHL','Central Mindanao',163849);
+INSERT INTO City VALUES (818,'Meycauayan','PHL','Central Luzon',163037);
+INSERT INTO City VALUES (819,'Puerto Princesa','PHL','Southern Tagalog',161912);
+INSERT INTO City VALUES (820,'Legazpi','PHL','Bicol',157010);
+INSERT INTO City VALUES (821,'Silang','PHL','Southern Tagalog',156137);
+INSERT INTO City VALUES (822,'Ormoc','PHL','Eastern Visayas',154297);
+INSERT INTO City VALUES (823,'San Carlos','PHL','Ilocos',154264);
+INSERT INTO City VALUES (824,'Kabankalan','PHL','Western Visayas',149769);
+INSERT INTO City VALUES (825,'Talisay','PHL','Central Visayas',148110);
+INSERT INTO City VALUES (826,'Valencia','PHL','Northern Mindanao',147924);
+INSERT INTO City VALUES (827,'Calbayog','PHL','Eastern Visayas',147187);
+INSERT INTO City VALUES (828,'Santa Maria','PHL','Central Luzon',144282);
+INSERT INTO City VALUES (829,'Pagadian','PHL','Western Mindanao',142515);
+INSERT INTO City VALUES (830,'Cadiz','PHL','Western Visayas',141954);
+INSERT INTO City VALUES (831,'Bago','PHL','Western Visayas',141721);
+INSERT INTO City VALUES (832,'Toledo','PHL','Central Visayas',141174);
+INSERT INTO City VALUES (833,'Naga','PHL','Bicol',137810);
+INSERT INTO City VALUES (834,'San Mateo','PHL','Southern Tagalog',135603);
+INSERT INTO City VALUES (835,'Panabo','PHL','Southern Mindanao',133950);
+INSERT INTO City VALUES (836,'Koronadal','PHL','Southern Mindanao',133786);
+INSERT INTO City VALUES (837,'Marawi','PHL','Central Mindanao',131090);
+INSERT INTO City VALUES (838,'Dagupan','PHL','Ilocos',130328);
+INSERT INTO City VALUES (839,'Sagay','PHL','Western Visayas',129765);
+INSERT INTO City VALUES (840,'Roxas','PHL','Western Visayas',126352);
+INSERT INTO City VALUES (841,'Lubao','PHL','Central Luzon',125699);
+INSERT INTO City VALUES (842,'Digos','PHL','Southern Mindanao',125171);
+INSERT INTO City VALUES (843,'San Miguel','PHL','Central Luzon',123824);
+INSERT INTO City VALUES (844,'Malaybalay','PHL','Northern Mindanao',123672);
+INSERT INTO City VALUES (845,'Tuguegarao','PHL','Cagayan Valley',120645);
+INSERT INTO City VALUES (846,'Ilagan','PHL','Cagayan Valley',119990);
+INSERT INTO City VALUES (847,'Baliuag','PHL','Central Luzon',119675);
+INSERT INTO City VALUES (848,'Surigao','PHL','Caraga',118534);
+INSERT INTO City VALUES (849,'San Carlos','PHL','Western Visayas',118259);
+INSERT INTO City VALUES (850,'San Juan del Monte','PHL','National Capital Reg',117680);
+INSERT INTO City VALUES (851,'Tanauan','PHL','Southern Tagalog',117539);
+INSERT INTO City VALUES (852,'Concepcion','PHL','Central Luzon',115171);
+INSERT INTO City VALUES (853,'Rodriguez (Montalban)','PHL','Southern Tagalog',115167);
+INSERT INTO City VALUES (854,'Sariaya','PHL','Southern Tagalog',114568);
+INSERT INTO City VALUES (855,'Malasiqui','PHL','Ilocos',113190);
+INSERT INTO City VALUES (856,'General Mariano Alvarez','PHL','Southern Tagalog',112446);
+INSERT INTO City VALUES (857,'Urdaneta','PHL','Ilocos',111582);
+INSERT INTO City VALUES (858,'Hagonoy','PHL','Central Luzon',111425);
+INSERT INTO City VALUES (859,'San Jose','PHL','Southern Tagalog',111009);
+INSERT INTO City VALUES (860,'Polomolok','PHL','Southern Mindanao',110709);
+INSERT INTO City VALUES (861,'Santiago','PHL','Cagayan Valley',110531);
+INSERT INTO City VALUES (862,'Tanza','PHL','Southern Tagalog',110517);
+INSERT INTO City VALUES (863,'Ozamis','PHL','Northern Mindanao',110420);
+INSERT INTO City VALUES (864,'Mexico','PHL','Central Luzon',109481);
+INSERT INTO City VALUES (865,'San Jose','PHL','Central Luzon',108254);
+INSERT INTO City VALUES (866,'Silay','PHL','Western Visayas',107722);
+INSERT INTO City VALUES (867,'General Trias','PHL','Southern Tagalog',107691);
+INSERT INTO City VALUES (868,'Tabaco','PHL','Bicol',107166);
+INSERT INTO City VALUES (869,'Cabuyao','PHL','Southern Tagalog',106630);
+INSERT INTO City VALUES (870,'Calapan','PHL','Southern Tagalog',105910);
+INSERT INTO City VALUES (871,'Mati','PHL','Southern Mindanao',105908);
+INSERT INTO City VALUES (872,'Midsayap','PHL','Central Mindanao',105760);
+INSERT INTO City VALUES (873,'Cauayan','PHL','Cagayan Valley',103952);
+INSERT INTO City VALUES (874,'Gingoog','PHL','Northern Mindanao',102379);
+INSERT INTO City VALUES (875,'Dumaguete','PHL','Central Visayas',102265);
+INSERT INTO City VALUES (876,'San Fernando','PHL','Ilocos',102082);
+INSERT INTO City VALUES (877,'Arayat','PHL','Central Luzon',101792);
+INSERT INTO City VALUES (878,'Bayawan (Tulong)','PHL','Central Visayas',101391);
+INSERT INTO City VALUES (879,'Kidapawan','PHL','Central Mindanao',101205);
+INSERT INTO City VALUES (880,'Daraga (Locsin)','PHL','Bicol',101031);
+INSERT INTO City VALUES (881,'Marilao','PHL','Central Luzon',101017);
+INSERT INTO City VALUES (882,'Malita','PHL','Southern Mindanao',100000);
+INSERT INTO City VALUES (883,'Dipolog','PHL','Western Mindanao',99862);
+INSERT INTO City VALUES (884,'Cavite','PHL','Southern Tagalog',99367);
+INSERT INTO City VALUES (885,'Danao','PHL','Central Visayas',98781);
+INSERT INTO City VALUES (886,'Bislig','PHL','Caraga',97860);
+INSERT INTO City VALUES (887,'Talavera','PHL','Central Luzon',97329);
+INSERT INTO City VALUES (888,'Guagua','PHL','Central Luzon',96858);
+INSERT INTO City VALUES (889,'Bayambang','PHL','Ilocos',96609);
+INSERT INTO City VALUES (890,'Nasugbu','PHL','Southern Tagalog',96113);
+INSERT INTO City VALUES (891,'Baybay','PHL','Eastern Visayas',95630);
+INSERT INTO City VALUES (892,'Capas','PHL','Central Luzon',95219);
+INSERT INTO City VALUES (893,'Sultan Kudarat','PHL','ARMM',94861);
+INSERT INTO City VALUES (894,'Laoag','PHL','Ilocos',94466);
+INSERT INTO City VALUES (895,'Bayugan','PHL','Caraga',93623);
+INSERT INTO City VALUES (896,'Malungon','PHL','Southern Mindanao',93232);
+INSERT INTO City VALUES (897,'Santa Cruz','PHL','Southern Tagalog',92694);
+INSERT INTO City VALUES (898,'Sorsogon','PHL','Bicol',92512);
+INSERT INTO City VALUES (899,'Candelaria','PHL','Southern Tagalog',92429);
+INSERT INTO City VALUES (900,'Ligao','PHL','Bicol',90603);
+INSERT INTO City VALUES (901,'Tórshavn','FRO','Streymoyar',14542);
+INSERT INTO City VALUES (902,'Libreville','GAB','Estuaire',419000);
+INSERT INTO City VALUES (903,'Serekunda','GMB','Kombo St Mary',102600);
+INSERT INTO City VALUES (904,'Banjul','GMB','Banjul',42326);
+INSERT INTO City VALUES (905,'Tbilisi','GEO','Tbilisi',1235200);
+INSERT INTO City VALUES (906,'Kutaisi','GEO','Imereti',240900);
+INSERT INTO City VALUES (907,'Rustavi','GEO','Kvemo Kartli',155400);
+INSERT INTO City VALUES (908,'Batumi','GEO','Adzaria [Atšara]',137700);
+INSERT INTO City VALUES (909,'Sohumi','GEO','Abhasia [Aphazeti]',111700);
+INSERT INTO City VALUES (910,'Accra','GHA','Greater Accra',1070000);
+INSERT INTO City VALUES (911,'Kumasi','GHA','Ashanti',385192);
+INSERT INTO City VALUES (912,'Tamale','GHA','Northern',151069);
+INSERT INTO City VALUES (913,'Tema','GHA','Greater Accra',109975);
+INSERT INTO City VALUES (914,'Sekondi-Takoradi','GHA','Western',103653);
+INSERT INTO City VALUES (915,'Gibraltar','GIB','–',27025);
+INSERT INTO City VALUES (916,'Saint George´s','GRD','St George',4621);
+INSERT INTO City VALUES (917,'Nuuk','GRL','Kitaa',13445);
+INSERT INTO City VALUES (918,'Les Abymes','GLP','Grande-Terre',62947);
+INSERT INTO City VALUES (919,'Basse-Terre','GLP','Basse-Terre',12433);
+INSERT INTO City VALUES (920,'Tamuning','GUM','–',9500);
+INSERT INTO City VALUES (921,'Agaña','GUM','–',1139);
+INSERT INTO City VALUES (922,'Ciudad de Guatemala','GTM','Guatemala',823301);
+INSERT INTO City VALUES (923,'Mixco','GTM','Guatemala',209791);
+INSERT INTO City VALUES (924,'Villa Nueva','GTM','Guatemala',101295);
+INSERT INTO City VALUES (925,'Quetzaltenango','GTM','Quetzaltenango',90801);
+INSERT INTO City VALUES (926,'Conakry','GIN','Conakry',1090610);
+INSERT INTO City VALUES (927,'Bissau','GNB','Bissau',241000);
+INSERT INTO City VALUES (928,'Georgetown','GUY','Georgetown',254000);
+INSERT INTO City VALUES (929,'Port-au-Prince','HTI','Ouest',884472);
+INSERT INTO City VALUES (930,'Carrefour','HTI','Ouest',290204);
+INSERT INTO City VALUES (931,'Delmas','HTI','Ouest',240429);
+INSERT INTO City VALUES (932,'Le-Cap-Haïtien','HTI','Nord',102233);
+INSERT INTO City VALUES (933,'Tegucigalpa','HND','Distrito Central',813900);
+INSERT INTO City VALUES (934,'San Pedro Sula','HND','Cortés',383900);
+INSERT INTO City VALUES (935,'La Ceiba','HND','Atlántida',89200);
+INSERT INTO City VALUES (936,'Kowloon and New Kowloon','HKG','Kowloon and New Kowl',1987996);
+INSERT INTO City VALUES (937,'Victoria','HKG','Hongkong',1312637);
+INSERT INTO City VALUES (938,'Longyearbyen','SJM','Länsimaa',1438);
+INSERT INTO City VALUES (939,'Jakarta','IDN','Jakarta Raya',9604900);
+INSERT INTO City VALUES (940,'Surabaya','IDN','East Java',2663820);
+INSERT INTO City VALUES (941,'Bandung','IDN','West Java',2429000);
+INSERT INTO City VALUES (942,'Medan','IDN','Sumatera Utara',1843919);
+INSERT INTO City VALUES (943,'Palembang','IDN','Sumatera Selatan',1222764);
+INSERT INTO City VALUES (944,'Tangerang','IDN','West Java',1198300);
+INSERT INTO City VALUES (945,'Semarang','IDN','Central Java',1104405);
+INSERT INTO City VALUES (946,'Ujung Pandang','IDN','Sulawesi Selatan',1060257);
+INSERT INTO City VALUES (947,'Malang','IDN','East Java',716862);
+INSERT INTO City VALUES (948,'Bandar Lampung','IDN','Lampung',680332);
+INSERT INTO City VALUES (949,'Bekasi','IDN','West Java',644300);
+INSERT INTO City VALUES (950,'Padang','IDN','Sumatera Barat',534474);
+INSERT INTO City VALUES (951,'Surakarta','IDN','Central Java',518600);
+INSERT INTO City VALUES (952,'Banjarmasin','IDN','Kalimantan Selatan',482931);
+INSERT INTO City VALUES (953,'Pekan Baru','IDN','Riau',438638);
+INSERT INTO City VALUES (954,'Denpasar','IDN','Bali',435000);
+INSERT INTO City VALUES (955,'Yogyakarta','IDN','Yogyakarta',418944);
+INSERT INTO City VALUES (956,'Pontianak','IDN','Kalimantan Barat',409632);
+INSERT INTO City VALUES (957,'Samarinda','IDN','Kalimantan Timur',399175);
+INSERT INTO City VALUES (958,'Jambi','IDN','Jambi',385201);
+INSERT INTO City VALUES (959,'Depok','IDN','West Java',365200);
+INSERT INTO City VALUES (960,'Cimahi','IDN','West Java',344600);
+INSERT INTO City VALUES (961,'Balikpapan','IDN','Kalimantan Timur',338752);
+INSERT INTO City VALUES (962,'Manado','IDN','Sulawesi Utara',332288);
+INSERT INTO City VALUES (963,'Mataram','IDN','Nusa Tenggara Barat',306600);
+INSERT INTO City VALUES (964,'Pekalongan','IDN','Central Java',301504);
+INSERT INTO City VALUES (965,'Tegal','IDN','Central Java',289744);
+INSERT INTO City VALUES (966,'Bogor','IDN','West Java',285114);
+INSERT INTO City VALUES (967,'Ciputat','IDN','West Java',270800);
+INSERT INTO City VALUES (968,'Pondokgede','IDN','West Java',263200);
+INSERT INTO City VALUES (969,'Cirebon','IDN','West Java',254406);
+INSERT INTO City VALUES (970,'Kediri','IDN','East Java',253760);
+INSERT INTO City VALUES (971,'Ambon','IDN','Molukit',249312);
+INSERT INTO City VALUES (972,'Jember','IDN','East Java',218500);
+INSERT INTO City VALUES (973,'Cilacap','IDN','Central Java',206900);
+INSERT INTO City VALUES (974,'Cimanggis','IDN','West Java',205100);
+INSERT INTO City VALUES (975,'Pematang Siantar','IDN','Sumatera Utara',203056);
+INSERT INTO City VALUES (976,'Purwokerto','IDN','Central Java',202500);
+INSERT INTO City VALUES (977,'Ciomas','IDN','West Java',187400);
+INSERT INTO City VALUES (978,'Tasikmalaya','IDN','West Java',179800);
+INSERT INTO City VALUES (979,'Madiun','IDN','East Java',171532);
+INSERT INTO City VALUES (980,'Bengkulu','IDN','Bengkulu',146439);
+INSERT INTO City VALUES (981,'Karawang','IDN','West Java',145000);
+INSERT INTO City VALUES (982,'Banda Aceh','IDN','Aceh',143409);
+INSERT INTO City VALUES (983,'Palu','IDN','Sulawesi Tengah',142800);
+INSERT INTO City VALUES (984,'Pasuruan','IDN','East Java',134019);
+INSERT INTO City VALUES (985,'Kupang','IDN','Nusa Tenggara Timur',129300);
+INSERT INTO City VALUES (986,'Tebing Tinggi','IDN','Sumatera Utara',129300);
+INSERT INTO City VALUES (987,'Percut Sei Tuan','IDN','Sumatera Utara',129000);
+INSERT INTO City VALUES (988,'Binjai','IDN','Sumatera Utara',127222);
+INSERT INTO City VALUES (989,'Sukabumi','IDN','West Java',125766);
+INSERT INTO City VALUES (990,'Waru','IDN','East Java',124300);
+INSERT INTO City VALUES (991,'Pangkal Pinang','IDN','Sumatera Selatan',124000);
+INSERT INTO City VALUES (992,'Magelang','IDN','Central Java',123800);
+INSERT INTO City VALUES (993,'Blitar','IDN','East Java',122600);
+INSERT INTO City VALUES (994,'Serang','IDN','West Java',122400);
+INSERT INTO City VALUES (995,'Probolinggo','IDN','East Java',120770);
+INSERT INTO City VALUES (996,'Cilegon','IDN','West Java',117000);
+INSERT INTO City VALUES (997,'Cianjur','IDN','West Java',114300);
+INSERT INTO City VALUES (998,'Ciparay','IDN','West Java',111500);
+INSERT INTO City VALUES (999,'Lhokseumawe','IDN','Aceh',109600);
+INSERT INTO City VALUES (1000,'Taman','IDN','East Java',107000);
+INSERT INTO City VALUES (1001,'Depok','IDN','Yogyakarta',106800);
+INSERT INTO City VALUES (1002,'Citeureup','IDN','West Java',105100);
+INSERT INTO City VALUES (1003,'Pemalang','IDN','Central Java',103500);
+INSERT INTO City VALUES (1004,'Klaten','IDN','Central Java',103300);
+INSERT INTO City VALUES (1005,'Salatiga','IDN','Central Java',103000);
+INSERT INTO City VALUES (1006,'Cibinong','IDN','West Java',101300);
+INSERT INTO City VALUES (1007,'Palangka Raya','IDN','Kalimantan Tengah',99693);
+INSERT INTO City VALUES (1008,'Mojokerto','IDN','East Java',96626);
+INSERT INTO City VALUES (1009,'Purwakarta','IDN','West Java',95900);
+INSERT INTO City VALUES (1010,'Garut','IDN','West Java',95800);
+INSERT INTO City VALUES (1011,'Kudus','IDN','Central Java',95300);
+INSERT INTO City VALUES (1012,'Kendari','IDN','Sulawesi Tenggara',94800);
+INSERT INTO City VALUES (1013,'Jaya Pura','IDN','West Irian',94700);
+INSERT INTO City VALUES (1014,'Gorontalo','IDN','Sulawesi Utara',94058);
+INSERT INTO City VALUES (1015,'Majalaya','IDN','West Java',93200);
+INSERT INTO City VALUES (1016,'Pondok Aren','IDN','West Java',92700);
+INSERT INTO City VALUES (1017,'Jombang','IDN','East Java',92600);
+INSERT INTO City VALUES (1018,'Sunggal','IDN','Sumatera Utara',92300);
+INSERT INTO City VALUES (1019,'Batam','IDN','Riau',91871);
+INSERT INTO City VALUES (1020,'Padang Sidempuan','IDN','Sumatera Utara',91200);
+INSERT INTO City VALUES (1021,'Sawangan','IDN','West Java',91100);
+INSERT INTO City VALUES (1022,'Banyuwangi','IDN','East Java',89900);
+INSERT INTO City VALUES (1023,'Tanjung Pinang','IDN','Riau',89900);
+INSERT INTO City VALUES (1024,'Mumbai (Bombay)','IND','Maharashtra',10500000);
+INSERT INTO City VALUES (1025,'Delhi','IND','Delhi',7206704);
+INSERT INTO City VALUES (1026,'Calcutta [Kolkata]','IND','West Bengali',4399819);
+INSERT INTO City VALUES (1027,'Chennai (Madras)','IND','Tamil Nadu',3841396);
+INSERT INTO City VALUES (1028,'Hyderabad','IND','Andhra Pradesh',2964638);
+INSERT INTO City VALUES (1029,'Ahmedabad','IND','Gujarat',2876710);
+INSERT INTO City VALUES (1030,'Bangalore','IND','Karnataka',2660088);
+INSERT INTO City VALUES (1031,'Kanpur','IND','Uttar Pradesh',1874409);
+INSERT INTO City VALUES (1032,'Nagpur','IND','Maharashtra',1624752);
+INSERT INTO City VALUES (1033,'Lucknow','IND','Uttar Pradesh',1619115);
+INSERT INTO City VALUES (1034,'Pune','IND','Maharashtra',1566651);
+INSERT INTO City VALUES (1035,'Surat','IND','Gujarat',1498817);
+INSERT INTO City VALUES (1036,'Jaipur','IND','Rajasthan',1458483);
+INSERT INTO City VALUES (1037,'Indore','IND','Madhya Pradesh',1091674);
+INSERT INTO City VALUES (1038,'Bhopal','IND','Madhya Pradesh',1062771);
+INSERT INTO City VALUES (1039,'Ludhiana','IND','Punjab',1042740);
+INSERT INTO City VALUES (1040,'Vadodara (Baroda)','IND','Gujarat',1031346);
+INSERT INTO City VALUES (1041,'Kalyan','IND','Maharashtra',1014557);
+INSERT INTO City VALUES (1042,'Madurai','IND','Tamil Nadu',977856);
+INSERT INTO City VALUES (1043,'Haora (Howrah)','IND','West Bengali',950435);
+INSERT INTO City VALUES (1044,'Varanasi (Benares)','IND','Uttar Pradesh',929270);
+INSERT INTO City VALUES (1045,'Patna','IND','Bihar',917243);
+INSERT INTO City VALUES (1046,'Srinagar','IND','Jammu and Kashmir',892506);
+INSERT INTO City VALUES (1047,'Agra','IND','Uttar Pradesh',891790);
+INSERT INTO City VALUES (1048,'Coimbatore','IND','Tamil Nadu',816321);
+INSERT INTO City VALUES (1049,'Thane (Thana)','IND','Maharashtra',803389);
+INSERT INTO City VALUES (1050,'Allahabad','IND','Uttar Pradesh',792858);
+INSERT INTO City VALUES (1051,'Meerut','IND','Uttar Pradesh',753778);
+INSERT INTO City VALUES (1052,'Vishakhapatnam','IND','Andhra Pradesh',752037);
+INSERT INTO City VALUES (1053,'Jabalpur','IND','Madhya Pradesh',741927);
+INSERT INTO City VALUES (1054,'Amritsar','IND','Punjab',708835);
+INSERT INTO City VALUES (1055,'Faridabad','IND','Haryana',703592);
+INSERT INTO City VALUES (1056,'Vijayawada','IND','Andhra Pradesh',701827);
+INSERT INTO City VALUES (1057,'Gwalior','IND','Madhya Pradesh',690765);
+INSERT INTO City VALUES (1058,'Jodhpur','IND','Rajasthan',666279);
+INSERT INTO City VALUES (1059,'Nashik (Nasik)','IND','Maharashtra',656925);
+INSERT INTO City VALUES (1060,'Hubli-Dharwad','IND','Karnataka',648298);
+INSERT INTO City VALUES (1061,'Solapur (Sholapur)','IND','Maharashtra',604215);
+INSERT INTO City VALUES (1062,'Ranchi','IND','Jharkhand',599306);
+INSERT INTO City VALUES (1063,'Bareilly','IND','Uttar Pradesh',587211);
+INSERT INTO City VALUES (1064,'Guwahati (Gauhati)','IND','Assam',584342);
+INSERT INTO City VALUES (1065,'Shambajinagar (Aurangabad)','IND','Maharashtra',573272);
+INSERT INTO City VALUES (1066,'Cochin (Kochi)','IND','Kerala',564589);
+INSERT INTO City VALUES (1067,'Rajkot','IND','Gujarat',559407);
+INSERT INTO City VALUES (1068,'Kota','IND','Rajasthan',537371);
+INSERT INTO City VALUES (1069,'Thiruvananthapuram (Trivandrum','IND','Kerala',524006);
+INSERT INTO City VALUES (1070,'Pimpri-Chinchwad','IND','Maharashtra',517083);
+INSERT INTO City VALUES (1071,'Jalandhar (Jullundur)','IND','Punjab',509510);
+INSERT INTO City VALUES (1072,'Gorakhpur','IND','Uttar Pradesh',505566);
+INSERT INTO City VALUES (1073,'Chandigarh','IND','Chandigarh',504094);
+INSERT INTO City VALUES (1074,'Mysore','IND','Karnataka',480692);
+INSERT INTO City VALUES (1075,'Aligarh','IND','Uttar Pradesh',480520);
+INSERT INTO City VALUES (1076,'Guntur','IND','Andhra Pradesh',471051);
+INSERT INTO City VALUES (1077,'Jamshedpur','IND','Jharkhand',460577);
+INSERT INTO City VALUES (1078,'Ghaziabad','IND','Uttar Pradesh',454156);
+INSERT INTO City VALUES (1079,'Warangal','IND','Andhra Pradesh',447657);
+INSERT INTO City VALUES (1080,'Raipur','IND','Chhatisgarh',438639);
+INSERT INTO City VALUES (1081,'Moradabad','IND','Uttar Pradesh',429214);
+INSERT INTO City VALUES (1082,'Durgapur','IND','West Bengali',425836);
+INSERT INTO City VALUES (1083,'Amravati','IND','Maharashtra',421576);
+INSERT INTO City VALUES (1084,'Calicut (Kozhikode)','IND','Kerala',419831);
+INSERT INTO City VALUES (1085,'Bikaner','IND','Rajasthan',416289);
+INSERT INTO City VALUES (1086,'Bhubaneswar','IND','Orissa',411542);
+INSERT INTO City VALUES (1087,'Kolhapur','IND','Maharashtra',406370);
+INSERT INTO City VALUES (1088,'Kataka (Cuttack)','IND','Orissa',403418);
+INSERT INTO City VALUES (1089,'Ajmer','IND','Rajasthan',402700);
+INSERT INTO City VALUES (1090,'Bhavnagar','IND','Gujarat',402338);
+INSERT INTO City VALUES (1091,'Tiruchirapalli','IND','Tamil Nadu',387223);
+INSERT INTO City VALUES (1092,'Bhilai','IND','Chhatisgarh',386159);
+INSERT INTO City VALUES (1093,'Bhiwandi','IND','Maharashtra',379070);
+INSERT INTO City VALUES (1094,'Saharanpur','IND','Uttar Pradesh',374945);
+INSERT INTO City VALUES (1095,'Ulhasnagar','IND','Maharashtra',369077);
+INSERT INTO City VALUES (1096,'Salem','IND','Tamil Nadu',366712);
+INSERT INTO City VALUES (1097,'Ujjain','IND','Madhya Pradesh',362266);
+INSERT INTO City VALUES (1098,'Malegaon','IND','Maharashtra',342595);
+INSERT INTO City VALUES (1099,'Jamnagar','IND','Gujarat',341637);
+INSERT INTO City VALUES (1100,'Bokaro Steel City','IND','Jharkhand',333683);
+INSERT INTO City VALUES (1101,'Akola','IND','Maharashtra',328034);
+INSERT INTO City VALUES (1102,'Belgaum','IND','Karnataka',326399);
+INSERT INTO City VALUES (1103,'Rajahmundry','IND','Andhra Pradesh',324851);
+INSERT INTO City VALUES (1104,'Nellore','IND','Andhra Pradesh',316606);
+INSERT INTO City VALUES (1105,'Udaipur','IND','Rajasthan',308571);
+INSERT INTO City VALUES (1106,'New Bombay','IND','Maharashtra',307297);
+INSERT INTO City VALUES (1107,'Bhatpara','IND','West Bengali',304952);
+INSERT INTO City VALUES (1108,'Gulbarga','IND','Karnataka',304099);
+INSERT INTO City VALUES (1109,'New Delhi','IND','Delhi',301297);
+INSERT INTO City VALUES (1110,'Jhansi','IND','Uttar Pradesh',300850);
+INSERT INTO City VALUES (1111,'Gaya','IND','Bihar',291675);
+INSERT INTO City VALUES (1112,'Kakinada','IND','Andhra Pradesh',279980);
+INSERT INTO City VALUES (1113,'Dhule (Dhulia)','IND','Maharashtra',278317);
+INSERT INTO City VALUES (1114,'Panihati','IND','West Bengali',275990);
+INSERT INTO City VALUES (1115,'Nanded (Nander)','IND','Maharashtra',275083);
+INSERT INTO City VALUES (1116,'Mangalore','IND','Karnataka',273304);
+INSERT INTO City VALUES (1117,'Dehra Dun','IND','Uttaranchal',270159);
+INSERT INTO City VALUES (1118,'Kamarhati','IND','West Bengali',266889);
+INSERT INTO City VALUES (1119,'Davangere','IND','Karnataka',266082);
+INSERT INTO City VALUES (1120,'Asansol','IND','West Bengali',262188);
+INSERT INTO City VALUES (1121,'Bhagalpur','IND','Bihar',253225);
+INSERT INTO City VALUES (1122,'Bellary','IND','Karnataka',245391);
+INSERT INTO City VALUES (1123,'Barddhaman (Burdwan)','IND','West Bengali',245079);
+INSERT INTO City VALUES (1124,'Rampur','IND','Uttar Pradesh',243742);
+INSERT INTO City VALUES (1125,'Jalgaon','IND','Maharashtra',242193);
+INSERT INTO City VALUES (1126,'Muzaffarpur','IND','Bihar',241107);
+INSERT INTO City VALUES (1127,'Nizamabad','IND','Andhra Pradesh',241034);
+INSERT INTO City VALUES (1128,'Muzaffarnagar','IND','Uttar Pradesh',240609);
+INSERT INTO City VALUES (1129,'Patiala','IND','Punjab',238368);
+INSERT INTO City VALUES (1130,'Shahjahanpur','IND','Uttar Pradesh',237713);
+INSERT INTO City VALUES (1131,'Kurnool','IND','Andhra Pradesh',236800);
+INSERT INTO City VALUES (1132,'Tiruppur (Tirupper)','IND','Tamil Nadu',235661);
+INSERT INTO City VALUES (1133,'Rohtak','IND','Haryana',233400);
+INSERT INTO City VALUES (1134,'South Dum Dum','IND','West Bengali',232811);
+INSERT INTO City VALUES (1135,'Mathura','IND','Uttar Pradesh',226691);
+INSERT INTO City VALUES (1136,'Chandrapur','IND','Maharashtra',226105);
+INSERT INTO City VALUES (1137,'Barahanagar (Baranagar)','IND','West Bengali',224821);
+INSERT INTO City VALUES (1138,'Darbhanga','IND','Bihar',218391);
+INSERT INTO City VALUES (1139,'Siliguri (Shiliguri)','IND','West Bengali',216950);
+INSERT INTO City VALUES (1140,'Raurkela','IND','Orissa',215489);
+INSERT INTO City VALUES (1141,'Ambattur','IND','Tamil Nadu',215424);
+INSERT INTO City VALUES (1142,'Panipat','IND','Haryana',215218);
+INSERT INTO City VALUES (1143,'Firozabad','IND','Uttar Pradesh',215128);
+INSERT INTO City VALUES (1144,'Ichalkaranji','IND','Maharashtra',214950);
+INSERT INTO City VALUES (1145,'Jammu','IND','Jammu and Kashmir',214737);
+INSERT INTO City VALUES (1146,'Ramagundam','IND','Andhra Pradesh',214384);
+INSERT INTO City VALUES (1147,'Eluru','IND','Andhra Pradesh',212866);
+INSERT INTO City VALUES (1148,'Brahmapur','IND','Orissa',210418);
+INSERT INTO City VALUES (1149,'Alwar','IND','Rajasthan',205086);
+INSERT INTO City VALUES (1150,'Pondicherry','IND','Pondicherry',203065);
+INSERT INTO City VALUES (1151,'Thanjavur','IND','Tamil Nadu',202013);
+INSERT INTO City VALUES (1152,'Bihar Sharif','IND','Bihar',201323);
+INSERT INTO City VALUES (1153,'Tuticorin','IND','Tamil Nadu',199854);
+INSERT INTO City VALUES (1154,'Imphal','IND','Manipur',198535);
+INSERT INTO City VALUES (1155,'Latur','IND','Maharashtra',197408);
+INSERT INTO City VALUES (1156,'Sagar','IND','Madhya Pradesh',195346);
+INSERT INTO City VALUES (1157,'Farrukhabad-cum-Fatehgarh','IND','Uttar Pradesh',194567);
+INSERT INTO City VALUES (1158,'Sangli','IND','Maharashtra',193197);
+INSERT INTO City VALUES (1159,'Parbhani','IND','Maharashtra',190255);
+INSERT INTO City VALUES (1160,'Nagar Coil','IND','Tamil Nadu',190084);
+INSERT INTO City VALUES (1161,'Bijapur','IND','Karnataka',186939);
+INSERT INTO City VALUES (1162,'Kukatpalle','IND','Andhra Pradesh',185378);
+INSERT INTO City VALUES (1163,'Bally','IND','West Bengali',184474);
+INSERT INTO City VALUES (1164,'Bhilwara','IND','Rajasthan',183965);
+INSERT INTO City VALUES (1165,'Ratlam','IND','Madhya Pradesh',183375);
+INSERT INTO City VALUES (1166,'Avadi','IND','Tamil Nadu',183215);
+INSERT INTO City VALUES (1167,'Dindigul','IND','Tamil Nadu',182477);
+INSERT INTO City VALUES (1168,'Ahmadnagar','IND','Maharashtra',181339);
+INSERT INTO City VALUES (1169,'Bilaspur','IND','Chhatisgarh',179833);
+INSERT INTO City VALUES (1170,'Shimoga','IND','Karnataka',179258);
+INSERT INTO City VALUES (1171,'Kharagpur','IND','West Bengali',177989);
+INSERT INTO City VALUES (1172,'Mira Bhayandar','IND','Maharashtra',175372);
+INSERT INTO City VALUES (1173,'Vellore','IND','Tamil Nadu',175061);
+INSERT INTO City VALUES (1174,'Jalna','IND','Maharashtra',174985);
+INSERT INTO City VALUES (1175,'Burnpur','IND','West Bengali',174933);
+INSERT INTO City VALUES (1176,'Anantapur','IND','Andhra Pradesh',174924);
+INSERT INTO City VALUES (1177,'Allappuzha (Alleppey)','IND','Kerala',174666);
+INSERT INTO City VALUES (1178,'Tirupati','IND','Andhra Pradesh',174369);
+INSERT INTO City VALUES (1179,'Karnal','IND','Haryana',173751);
+INSERT INTO City VALUES (1180,'Burhanpur','IND','Madhya Pradesh',172710);
+INSERT INTO City VALUES (1181,'Hisar (Hissar)','IND','Haryana',172677);
+INSERT INTO City VALUES (1182,'Tiruvottiyur','IND','Tamil Nadu',172562);
+INSERT INTO City VALUES (1183,'Mirzapur-cum-Vindhyachal','IND','Uttar Pradesh',169336);
+INSERT INTO City VALUES (1184,'Secunderabad','IND','Andhra Pradesh',167461);
+INSERT INTO City VALUES (1185,'Nadiad','IND','Gujarat',167051);
+INSERT INTO City VALUES (1186,'Dewas','IND','Madhya Pradesh',164364);
+INSERT INTO City VALUES (1187,'Murwara (Katni)','IND','Madhya Pradesh',163431);
+INSERT INTO City VALUES (1188,'Ganganagar','IND','Rajasthan',161482);
+INSERT INTO City VALUES (1189,'Vizianagaram','IND','Andhra Pradesh',160359);
+INSERT INTO City VALUES (1190,'Erode','IND','Tamil Nadu',159232);
+INSERT INTO City VALUES (1191,'Machilipatnam (Masulipatam)','IND','Andhra Pradesh',159110);
+INSERT INTO City VALUES (1192,'Bhatinda (Bathinda)','IND','Punjab',159042);
+INSERT INTO City VALUES (1193,'Raichur','IND','Karnataka',157551);
+INSERT INTO City VALUES (1194,'Agartala','IND','Tripura',157358);
+INSERT INTO City VALUES (1195,'Arrah (Ara)','IND','Bihar',157082);
+INSERT INTO City VALUES (1196,'Satna','IND','Madhya Pradesh',156630);
+INSERT INTO City VALUES (1197,'Lalbahadur Nagar','IND','Andhra Pradesh',155500);
+INSERT INTO City VALUES (1198,'Aizawl','IND','Mizoram',155240);
+INSERT INTO City VALUES (1199,'Uluberia','IND','West Bengali',155172);
+INSERT INTO City VALUES (1200,'Katihar','IND','Bihar',154367);
+INSERT INTO City VALUES (1201,'Cuddalore','IND','Tamil Nadu',153086);
+INSERT INTO City VALUES (1202,'Hugli-Chinsurah','IND','West Bengali',151806);
+INSERT INTO City VALUES (1203,'Dhanbad','IND','Jharkhand',151789);
+INSERT INTO City VALUES (1204,'Raiganj','IND','West Bengali',151045);
+INSERT INTO City VALUES (1205,'Sambhal','IND','Uttar Pradesh',150869);
+INSERT INTO City VALUES (1206,'Durg','IND','Chhatisgarh',150645);
+INSERT INTO City VALUES (1207,'Munger (Monghyr)','IND','Bihar',150112);
+INSERT INTO City VALUES (1208,'Kanchipuram','IND','Tamil Nadu',150100);
+INSERT INTO City VALUES (1209,'North Dum Dum','IND','West Bengali',149965);
+INSERT INTO City VALUES (1210,'Karimnagar','IND','Andhra Pradesh',148583);
+INSERT INTO City VALUES (1211,'Bharatpur','IND','Rajasthan',148519);
+INSERT INTO City VALUES (1212,'Sikar','IND','Rajasthan',148272);
+INSERT INTO City VALUES (1213,'Hardwar (Haridwar)','IND','Uttaranchal',147305);
+INSERT INTO City VALUES (1214,'Dabgram','IND','West Bengali',147217);
+INSERT INTO City VALUES (1215,'Morena','IND','Madhya Pradesh',147124);
+INSERT INTO City VALUES (1216,'Noida','IND','Uttar Pradesh',146514);
+INSERT INTO City VALUES (1217,'Hapur','IND','Uttar Pradesh',146262);
+INSERT INTO City VALUES (1218,'Bhusawal','IND','Maharashtra',145143);
+INSERT INTO City VALUES (1219,'Khandwa','IND','Madhya Pradesh',145133);
+INSERT INTO City VALUES (1220,'Yamuna Nagar','IND','Haryana',144346);
+INSERT INTO City VALUES (1221,'Sonipat (Sonepat)','IND','Haryana',143922);
+INSERT INTO City VALUES (1222,'Tenali','IND','Andhra Pradesh',143726);
+INSERT INTO City VALUES (1223,'Raurkela Civil Township','IND','Orissa',140408);
+INSERT INTO City VALUES (1224,'Kollam (Quilon)','IND','Kerala',139852);
+INSERT INTO City VALUES (1225,'Kumbakonam','IND','Tamil Nadu',139483);
+INSERT INTO City VALUES (1226,'Ingraj Bazar (English Bazar)','IND','West Bengali',139204);
+INSERT INTO City VALUES (1227,'Timkur','IND','Karnataka',138903);
+INSERT INTO City VALUES (1228,'Amroha','IND','Uttar Pradesh',137061);
+INSERT INTO City VALUES (1229,'Serampore','IND','West Bengali',137028);
+INSERT INTO City VALUES (1230,'Chapra','IND','Bihar',136877);
+INSERT INTO City VALUES (1231,'Pali','IND','Rajasthan',136842);
+INSERT INTO City VALUES (1232,'Maunath Bhanjan','IND','Uttar Pradesh',136697);
+INSERT INTO City VALUES (1233,'Adoni','IND','Andhra Pradesh',136182);
+INSERT INTO City VALUES (1234,'Jaunpur','IND','Uttar Pradesh',136062);
+INSERT INTO City VALUES (1235,'Tirunelveli','IND','Tamil Nadu',135825);
+INSERT INTO City VALUES (1236,'Bahraich','IND','Uttar Pradesh',135400);
+INSERT INTO City VALUES (1237,'Gadag Betigeri','IND','Karnataka',134051);
+INSERT INTO City VALUES (1238,'Proddatur','IND','Andhra Pradesh',133914);
+INSERT INTO City VALUES (1239,'Chittoor','IND','Andhra Pradesh',133462);
+INSERT INTO City VALUES (1240,'Barrackpur','IND','West Bengali',133265);
+INSERT INTO City VALUES (1241,'Bharuch (Broach)','IND','Gujarat',133102);
+INSERT INTO City VALUES (1242,'Naihati','IND','West Bengali',132701);
+INSERT INTO City VALUES (1243,'Shillong','IND','Meghalaya',131719);
+INSERT INTO City VALUES (1244,'Sambalpur','IND','Orissa',131138);
+INSERT INTO City VALUES (1245,'Junagadh','IND','Gujarat',130484);
+INSERT INTO City VALUES (1246,'Rae Bareli','IND','Uttar Pradesh',129904);
+INSERT INTO City VALUES (1247,'Rewa','IND','Madhya Pradesh',128981);
+INSERT INTO City VALUES (1248,'Gurgaon','IND','Haryana',128608);
+INSERT INTO City VALUES (1249,'Khammam','IND','Andhra Pradesh',127992);
+INSERT INTO City VALUES (1250,'Bulandshahr','IND','Uttar Pradesh',127201);
+INSERT INTO City VALUES (1251,'Navsari','IND','Gujarat',126089);
+INSERT INTO City VALUES (1252,'Malkajgiri','IND','Andhra Pradesh',126066);
+INSERT INTO City VALUES (1253,'Midnapore (Medinipur)','IND','West Bengali',125498);
+INSERT INTO City VALUES (1254,'Miraj','IND','Maharashtra',125407);
+INSERT INTO City VALUES (1255,'Raj Nandgaon','IND','Chhatisgarh',125371);
+INSERT INTO City VALUES (1256,'Alandur','IND','Tamil Nadu',125244);
+INSERT INTO City VALUES (1257,'Puri','IND','Orissa',125199);
+INSERT INTO City VALUES (1258,'Navadwip','IND','West Bengali',125037);
+INSERT INTO City VALUES (1259,'Sirsa','IND','Haryana',125000);
+INSERT INTO City VALUES (1260,'Korba','IND','Chhatisgarh',124501);
+INSERT INTO City VALUES (1261,'Faizabad','IND','Uttar Pradesh',124437);
+INSERT INTO City VALUES (1262,'Etawah','IND','Uttar Pradesh',124072);
+INSERT INTO City VALUES (1263,'Pathankot','IND','Punjab',123930);
+INSERT INTO City VALUES (1264,'Gandhinagar','IND','Gujarat',123359);
+INSERT INTO City VALUES (1265,'Palghat (Palakkad)','IND','Kerala',123289);
+INSERT INTO City VALUES (1266,'Veraval','IND','Gujarat',123000);
+INSERT INTO City VALUES (1267,'Hoshiarpur','IND','Punjab',122705);
+INSERT INTO City VALUES (1268,'Ambala','IND','Haryana',122596);
+INSERT INTO City VALUES (1269,'Sitapur','IND','Uttar Pradesh',121842);
+INSERT INTO City VALUES (1270,'Bhiwani','IND','Haryana',121629);
+INSERT INTO City VALUES (1271,'Cuddapah','IND','Andhra Pradesh',121463);
+INSERT INTO City VALUES (1272,'Bhimavaram','IND','Andhra Pradesh',121314);
+INSERT INTO City VALUES (1273,'Krishnanagar','IND','West Bengali',121110);
+INSERT INTO City VALUES (1274,'Chandannagar','IND','West Bengali',120378);
+INSERT INTO City VALUES (1275,'Mandya','IND','Karnataka',120265);
+INSERT INTO City VALUES (1276,'Dibrugarh','IND','Assam',120127);
+INSERT INTO City VALUES (1277,'Nandyal','IND','Andhra Pradesh',119813);
+INSERT INTO City VALUES (1278,'Balurghat','IND','West Bengali',119796);
+INSERT INTO City VALUES (1279,'Neyveli','IND','Tamil Nadu',118080);
+INSERT INTO City VALUES (1280,'Fatehpur','IND','Uttar Pradesh',117675);
+INSERT INTO City VALUES (1281,'Mahbubnagar','IND','Andhra Pradesh',116833);
+INSERT INTO City VALUES (1282,'Budaun','IND','Uttar Pradesh',116695);
+INSERT INTO City VALUES (1283,'Porbandar','IND','Gujarat',116671);
+INSERT INTO City VALUES (1284,'Silchar','IND','Assam',115483);
+INSERT INTO City VALUES (1285,'Berhampore (Baharampur)','IND','West Bengali',115144);
+INSERT INTO City VALUES (1286,'Purnea (Purnia)','IND','Jharkhand',114912);
+INSERT INTO City VALUES (1287,'Bankura','IND','West Bengali',114876);
+INSERT INTO City VALUES (1288,'Rajapalaiyam','IND','Tamil Nadu',114202);
+INSERT INTO City VALUES (1289,'Titagarh','IND','West Bengali',114085);
+INSERT INTO City VALUES (1290,'Halisahar','IND','West Bengali',114028);
+INSERT INTO City VALUES (1291,'Hathras','IND','Uttar Pradesh',113285);
+INSERT INTO City VALUES (1292,'Bhir (Bid)','IND','Maharashtra',112434);
+INSERT INTO City VALUES (1293,'Pallavaram','IND','Tamil Nadu',111866);
+INSERT INTO City VALUES (1294,'Anand','IND','Gujarat',110266);
+INSERT INTO City VALUES (1295,'Mango','IND','Jharkhand',110024);
+INSERT INTO City VALUES (1296,'Santipur','IND','West Bengali',109956);
+INSERT INTO City VALUES (1297,'Bhind','IND','Madhya Pradesh',109755);
+INSERT INTO City VALUES (1298,'Gondiya','IND','Maharashtra',109470);
+INSERT INTO City VALUES (1299,'Tiruvannamalai','IND','Tamil Nadu',109196);
+INSERT INTO City VALUES (1300,'Yeotmal (Yavatmal)','IND','Maharashtra',108578);
+INSERT INTO City VALUES (1301,'Kulti-Barakar','IND','West Bengali',108518);
+INSERT INTO City VALUES (1302,'Moga','IND','Punjab',108304);
+INSERT INTO City VALUES (1303,'Shivapuri','IND','Madhya Pradesh',108277);
+INSERT INTO City VALUES (1304,'Bidar','IND','Karnataka',108016);
+INSERT INTO City VALUES (1305,'Guntakal','IND','Andhra Pradesh',107592);
+INSERT INTO City VALUES (1306,'Unnao','IND','Uttar Pradesh',107425);
+INSERT INTO City VALUES (1307,'Barasat','IND','West Bengali',107365);
+INSERT INTO City VALUES (1308,'Tambaram','IND','Tamil Nadu',107187);
+INSERT INTO City VALUES (1309,'Abohar','IND','Punjab',107163);
+INSERT INTO City VALUES (1310,'Pilibhit','IND','Uttar Pradesh',106605);
+INSERT INTO City VALUES (1311,'Valparai','IND','Tamil Nadu',106523);
+INSERT INTO City VALUES (1312,'Gonda','IND','Uttar Pradesh',106078);
+INSERT INTO City VALUES (1313,'Surendranagar','IND','Gujarat',105973);
+INSERT INTO City VALUES (1314,'Qutubullapur','IND','Andhra Pradesh',105380);
+INSERT INTO City VALUES (1315,'Beawar','IND','Rajasthan',105363);
+INSERT INTO City VALUES (1316,'Hindupur','IND','Andhra Pradesh',104651);
+INSERT INTO City VALUES (1317,'Gandhidham','IND','Gujarat',104585);
+INSERT INTO City VALUES (1318,'Haldwani-cum-Kathgodam','IND','Uttaranchal',104195);
+INSERT INTO City VALUES (1319,'Tellicherry (Thalassery)','IND','Kerala',103579);
+INSERT INTO City VALUES (1320,'Wardha','IND','Maharashtra',102985);
+INSERT INTO City VALUES (1321,'Rishra','IND','West Bengali',102649);
+INSERT INTO City VALUES (1322,'Bhuj','IND','Gujarat',102176);
+INSERT INTO City VALUES (1323,'Modinagar','IND','Uttar Pradesh',101660);
+INSERT INTO City VALUES (1324,'Gudivada','IND','Andhra Pradesh',101656);
+INSERT INTO City VALUES (1325,'Basirhat','IND','West Bengali',101409);
+INSERT INTO City VALUES (1326,'Uttarpara-Kotrung','IND','West Bengali',100867);
+INSERT INTO City VALUES (1327,'Ongole','IND','Andhra Pradesh',100836);
+INSERT INTO City VALUES (1328,'North Barrackpur','IND','West Bengali',100513);
+INSERT INTO City VALUES (1329,'Guna','IND','Madhya Pradesh',100490);
+INSERT INTO City VALUES (1330,'Haldia','IND','West Bengali',100347);
+INSERT INTO City VALUES (1331,'Habra','IND','West Bengali',100223);
+INSERT INTO City VALUES (1332,'Kanchrapara','IND','West Bengali',100194);
+INSERT INTO City VALUES (1333,'Tonk','IND','Rajasthan',100079);
+INSERT INTO City VALUES (1334,'Champdani','IND','West Bengali',98818);
+INSERT INTO City VALUES (1335,'Orai','IND','Uttar Pradesh',98640);
+INSERT INTO City VALUES (1336,'Pudukkottai','IND','Tamil Nadu',98619);
+INSERT INTO City VALUES (1337,'Sasaram','IND','Bihar',98220);
+INSERT INTO City VALUES (1338,'Hazaribag','IND','Jharkhand',97712);
+INSERT INTO City VALUES (1339,'Palayankottai','IND','Tamil Nadu',97662);
+INSERT INTO City VALUES (1340,'Banda','IND','Uttar Pradesh',97227);
+INSERT INTO City VALUES (1341,'Godhra','IND','Gujarat',96813);
+INSERT INTO City VALUES (1342,'Hospet','IND','Karnataka',96322);
+INSERT INTO City VALUES (1343,'Ashoknagar-Kalyangarh','IND','West Bengali',96315);
+INSERT INTO City VALUES (1344,'Achalpur','IND','Maharashtra',96216);
+INSERT INTO City VALUES (1345,'Patan','IND','Gujarat',96109);
+INSERT INTO City VALUES (1346,'Mandasor','IND','Madhya Pradesh',95758);
+INSERT INTO City VALUES (1347,'Damoh','IND','Madhya Pradesh',95661);
+INSERT INTO City VALUES (1348,'Satara','IND','Maharashtra',95133);
+INSERT INTO City VALUES (1349,'Meerut Cantonment','IND','Uttar Pradesh',94876);
+INSERT INTO City VALUES (1350,'Dehri','IND','Bihar',94526);
+INSERT INTO City VALUES (1351,'Delhi Cantonment','IND','Delhi',94326);
+INSERT INTO City VALUES (1352,'Chhindwara','IND','Madhya Pradesh',93731);
+INSERT INTO City VALUES (1353,'Bansberia','IND','West Bengali',93447);
+INSERT INTO City VALUES (1354,'Nagaon','IND','Assam',93350);
+INSERT INTO City VALUES (1355,'Kanpur Cantonment','IND','Uttar Pradesh',93109);
+INSERT INTO City VALUES (1356,'Vidisha','IND','Madhya Pradesh',92917);
+INSERT INTO City VALUES (1357,'Bettiah','IND','Bihar',92583);
+INSERT INTO City VALUES (1358,'Purulia','IND','Jharkhand',92574);
+INSERT INTO City VALUES (1359,'Hassan','IND','Karnataka',90803);
+INSERT INTO City VALUES (1360,'Ambala Sadar','IND','Haryana',90712);
+INSERT INTO City VALUES (1361,'Baidyabati','IND','West Bengali',90601);
+INSERT INTO City VALUES (1362,'Morvi','IND','Gujarat',90357);
+INSERT INTO City VALUES (1363,'Raigarh','IND','Chhatisgarh',89166);
+INSERT INTO City VALUES (1364,'Vejalpur','IND','Gujarat',89053);
+INSERT INTO City VALUES (1365,'Baghdad','IRQ','Baghdad',4336000);
+INSERT INTO City VALUES (1366,'Mosul','IRQ','Ninawa',879000);
+INSERT INTO City VALUES (1367,'Irbil','IRQ','Irbil',485968);
+INSERT INTO City VALUES (1368,'Kirkuk','IRQ','al-Tamim',418624);
+INSERT INTO City VALUES (1369,'Basra','IRQ','Basra',406296);
+INSERT INTO City VALUES (1370,'al-Sulaymaniya','IRQ','al-Sulaymaniya',364096);
+INSERT INTO City VALUES (1371,'al-Najaf','IRQ','al-Najaf',309010);
+INSERT INTO City VALUES (1372,'Karbala','IRQ','Karbala',296705);
+INSERT INTO City VALUES (1373,'al-Hilla','IRQ','Babil',268834);
+INSERT INTO City VALUES (1374,'al-Nasiriya','IRQ','DhiQar',265937);
+INSERT INTO City VALUES (1375,'al-Amara','IRQ','Maysan',208797);
+INSERT INTO City VALUES (1376,'al-Diwaniya','IRQ','al-Qadisiya',196519);
+INSERT INTO City VALUES (1377,'al-Ramadi','IRQ','al-Anbar',192556);
+INSERT INTO City VALUES (1378,'al-Kut','IRQ','Wasit',183183);
+INSERT INTO City VALUES (1379,'Baquba','IRQ','Diyala',114516);
+INSERT INTO City VALUES (1380,'Teheran','IRN','Teheran',6758845);
+INSERT INTO City VALUES (1381,'Mashhad','IRN','Khorasan',1887405);
+INSERT INTO City VALUES (1382,'Esfahan','IRN','Esfahan',1266072);
+INSERT INTO City VALUES (1383,'Tabriz','IRN','East Azerbaidzan',1191043);
+INSERT INTO City VALUES (1384,'Shiraz','IRN','Fars',1053025);
+INSERT INTO City VALUES (1385,'Karaj','IRN','Teheran',940968);
+INSERT INTO City VALUES (1386,'Ahvaz','IRN','Khuzestan',804980);
+INSERT INTO City VALUES (1387,'Qom','IRN','Qom',777677);
+INSERT INTO City VALUES (1388,'Kermanshah','IRN','Kermanshah',692986);
+INSERT INTO City VALUES (1389,'Urmia','IRN','West Azerbaidzan',435200);
+INSERT INTO City VALUES (1390,'Zahedan','IRN','Sistan va Baluchesta',419518);
+INSERT INTO City VALUES (1391,'Rasht','IRN','Gilan',417748);
+INSERT INTO City VALUES (1392,'Hamadan','IRN','Hamadan',401281);
+INSERT INTO City VALUES (1393,'Kerman','IRN','Kerman',384991);
+INSERT INTO City VALUES (1394,'Arak','IRN','Markazi',380755);
+INSERT INTO City VALUES (1395,'Ardebil','IRN','Ardebil',340386);
+INSERT INTO City VALUES (1396,'Yazd','IRN','Yazd',326776);
+INSERT INTO City VALUES (1397,'Qazvin','IRN','Qazvin',291117);
+INSERT INTO City VALUES (1398,'Zanjan','IRN','Zanjan',286295);
+INSERT INTO City VALUES (1399,'Sanandaj','IRN','Kordestan',277808);
+INSERT INTO City VALUES (1400,'Bandar-e-Abbas','IRN','Hormozgan',273578);
+INSERT INTO City VALUES (1401,'Khorramabad','IRN','Lorestan',272815);
+INSERT INTO City VALUES (1402,'Eslamshahr','IRN','Teheran',265450);
+INSERT INTO City VALUES (1403,'Borujerd','IRN','Lorestan',217804);
+INSERT INTO City VALUES (1404,'Abadan','IRN','Khuzestan',206073);
+INSERT INTO City VALUES (1405,'Dezful','IRN','Khuzestan',202639);
+INSERT INTO City VALUES (1406,'Kashan','IRN','Esfahan',201372);
+INSERT INTO City VALUES (1407,'Sari','IRN','Mazandaran',195882);
+INSERT INTO City VALUES (1408,'Gorgan','IRN','Golestan',188710);
+INSERT INTO City VALUES (1409,'Najafabad','IRN','Esfahan',178498);
+INSERT INTO City VALUES (1410,'Sabzevar','IRN','Khorasan',170738);
+INSERT INTO City VALUES (1411,'Khomeynishahr','IRN','Esfahan',165888);
+INSERT INTO City VALUES (1412,'Amol','IRN','Mazandaran',159092);
+INSERT INTO City VALUES (1413,'Neyshabur','IRN','Khorasan',158847);
+INSERT INTO City VALUES (1414,'Babol','IRN','Mazandaran',158346);
+INSERT INTO City VALUES (1415,'Khoy','IRN','West Azerbaidzan',148944);
+INSERT INTO City VALUES (1416,'Malayer','IRN','Hamadan',144373);
+INSERT INTO City VALUES (1417,'Bushehr','IRN','Bushehr',143641);
+INSERT INTO City VALUES (1418,'Qaemshahr','IRN','Mazandaran',143286);
+INSERT INTO City VALUES (1419,'Qarchak','IRN','Teheran',142690);
+INSERT INTO City VALUES (1420,'Qods','IRN','Teheran',138278);
+INSERT INTO City VALUES (1421,'Sirjan','IRN','Kerman',135024);
+INSERT INTO City VALUES (1422,'Bojnurd','IRN','Khorasan',134835);
+INSERT INTO City VALUES (1423,'Maragheh','IRN','East Azerbaidzan',132318);
+INSERT INTO City VALUES (1424,'Birjand','IRN','Khorasan',127608);
+INSERT INTO City VALUES (1425,'Ilam','IRN','Ilam',126346);
+INSERT INTO City VALUES (1426,'Bukan','IRN','West Azerbaidzan',120020);
+INSERT INTO City VALUES (1427,'Masjed-e-Soleyman','IRN','Khuzestan',116883);
+INSERT INTO City VALUES (1428,'Saqqez','IRN','Kordestan',115394);
+INSERT INTO City VALUES (1429,'Gonbad-e Qabus','IRN','Mazandaran',111253);
+INSERT INTO City VALUES (1430,'Saveh','IRN','Qom',111245);
+INSERT INTO City VALUES (1431,'Mahabad','IRN','West Azerbaidzan',107799);
+INSERT INTO City VALUES (1432,'Varamin','IRN','Teheran',107233);
+INSERT INTO City VALUES (1433,'Andimeshk','IRN','Khuzestan',106923);
+INSERT INTO City VALUES (1434,'Khorramshahr','IRN','Khuzestan',105636);
+INSERT INTO City VALUES (1435,'Shahrud','IRN','Semnan',104765);
+INSERT INTO City VALUES (1436,'Marv Dasht','IRN','Fars',103579);
+INSERT INTO City VALUES (1437,'Zabol','IRN','Sistan va Baluchesta',100887);
+INSERT INTO City VALUES (1438,'Shahr-e Kord','IRN','Chaharmahal va Bakht',100477);
+INSERT INTO City VALUES (1439,'Bandar-e Anzali','IRN','Gilan',98500);
+INSERT INTO City VALUES (1440,'Rafsanjan','IRN','Kerman',98300);
+INSERT INTO City VALUES (1441,'Marand','IRN','East Azerbaidzan',96400);
+INSERT INTO City VALUES (1442,'Torbat-e Heydariyeh','IRN','Khorasan',94600);
+INSERT INTO City VALUES (1443,'Jahrom','IRN','Fars',94200);
+INSERT INTO City VALUES (1444,'Semnan','IRN','Semnan',91045);
+INSERT INTO City VALUES (1445,'Miandoab','IRN','West Azerbaidzan',90100);
+INSERT INTO City VALUES (1446,'Qomsheh','IRN','Esfahan',89800);
+INSERT INTO City VALUES (1447,'Dublin','IRL','Leinster',481854);
+INSERT INTO City VALUES (1448,'Cork','IRL','Munster',127187);
+INSERT INTO City VALUES (1449,'Reykjavík','ISL','Höfuðborgarsvæði',109184);
+INSERT INTO City VALUES (1450,'Jerusalem','ISR','Jerusalem',633700);
+INSERT INTO City VALUES (1451,'Tel Aviv-Jaffa','ISR','Tel Aviv',348100);
+INSERT INTO City VALUES (1452,'Haifa','ISR','Haifa',265700);
+INSERT INTO City VALUES (1453,'Rishon Le Ziyyon','ISR','Ha Merkaz',188200);
+INSERT INTO City VALUES (1454,'Beerseba','ISR','Ha Darom',163700);
+INSERT INTO City VALUES (1455,'Holon','ISR','Tel Aviv',163100);
+INSERT INTO City VALUES (1456,'Petah Tiqwa','ISR','Ha Merkaz',159400);
+INSERT INTO City VALUES (1457,'Ashdod','ISR','Ha Darom',155800);
+INSERT INTO City VALUES (1458,'Netanya','ISR','Ha Merkaz',154900);
+INSERT INTO City VALUES (1459,'Bat Yam','ISR','Tel Aviv',137000);
+INSERT INTO City VALUES (1460,'Bene Beraq','ISR','Tel Aviv',133900);
+INSERT INTO City VALUES (1461,'Ramat Gan','ISR','Tel Aviv',126900);
+INSERT INTO City VALUES (1462,'Ashqelon','ISR','Ha Darom',92300);
+INSERT INTO City VALUES (1463,'Rehovot','ISR','Ha Merkaz',90300);
+INSERT INTO City VALUES (1464,'Roma','ITA','Latium',2643581);
+INSERT INTO City VALUES (1465,'Milano','ITA','Lombardia',1300977);
+INSERT INTO City VALUES (1466,'Napoli','ITA','Campania',1002619);
+INSERT INTO City VALUES (1467,'Torino','ITA','Piemonte',903705);
+INSERT INTO City VALUES (1468,'Palermo','ITA','Sisilia',683794);
+INSERT INTO City VALUES (1469,'Genova','ITA','Liguria',636104);
+INSERT INTO City VALUES (1470,'Bologna','ITA','Emilia-Romagna',381161);
+INSERT INTO City VALUES (1471,'Firenze','ITA','Toscana',376662);
+INSERT INTO City VALUES (1472,'Catania','ITA','Sisilia',337862);
+INSERT INTO City VALUES (1473,'Bari','ITA','Apulia',331848);
+INSERT INTO City VALUES (1474,'Venezia','ITA','Veneto',277305);
+INSERT INTO City VALUES (1475,'Messina','ITA','Sisilia',259156);
+INSERT INTO City VALUES (1476,'Verona','ITA','Veneto',255268);
+INSERT INTO City VALUES (1477,'Trieste','ITA','Friuli-Venezia Giuli',216459);
+INSERT INTO City VALUES (1478,'Padova','ITA','Veneto',211391);
+INSERT INTO City VALUES (1479,'Taranto','ITA','Apulia',208214);
+INSERT INTO City VALUES (1480,'Brescia','ITA','Lombardia',191317);
+INSERT INTO City VALUES (1481,'Reggio di Calabria','ITA','Calabria',179617);
+INSERT INTO City VALUES (1482,'Modena','ITA','Emilia-Romagna',176022);
+INSERT INTO City VALUES (1483,'Prato','ITA','Toscana',172473);
+INSERT INTO City VALUES (1484,'Parma','ITA','Emilia-Romagna',168717);
+INSERT INTO City VALUES (1485,'Cagliari','ITA','Sardinia',165926);
+INSERT INTO City VALUES (1486,'Livorno','ITA','Toscana',161673);
+INSERT INTO City VALUES (1487,'Perugia','ITA','Umbria',156673);
+INSERT INTO City VALUES (1488,'Foggia','ITA','Apulia',154891);
+INSERT INTO City VALUES (1489,'Reggio nell´ Emilia','ITA','Emilia-Romagna',143664);
+INSERT INTO City VALUES (1490,'Salerno','ITA','Campania',142055);
+INSERT INTO City VALUES (1491,'Ravenna','ITA','Emilia-Romagna',138418);
+INSERT INTO City VALUES (1492,'Ferrara','ITA','Emilia-Romagna',132127);
+INSERT INTO City VALUES (1493,'Rimini','ITA','Emilia-Romagna',131062);
+INSERT INTO City VALUES (1494,'Syrakusa','ITA','Sisilia',126282);
+INSERT INTO City VALUES (1495,'Sassari','ITA','Sardinia',120803);
+INSERT INTO City VALUES (1496,'Monza','ITA','Lombardia',119516);
+INSERT INTO City VALUES (1497,'Bergamo','ITA','Lombardia',117837);
+INSERT INTO City VALUES (1498,'Pescara','ITA','Abruzzit',115698);
+INSERT INTO City VALUES (1499,'Latina','ITA','Latium',114099);
+INSERT INTO City VALUES (1500,'Vicenza','ITA','Veneto',109738);
+INSERT INTO City VALUES (1501,'Terni','ITA','Umbria',107770);
+INSERT INTO City VALUES (1502,'Forlì','ITA','Emilia-Romagna',107475);
+INSERT INTO City VALUES (1503,'Trento','ITA','Trentino-Alto Adige',104906);
+INSERT INTO City VALUES (1504,'Novara','ITA','Piemonte',102037);
+INSERT INTO City VALUES (1505,'Piacenza','ITA','Emilia-Romagna',98384);
+INSERT INTO City VALUES (1506,'Ancona','ITA','Marche',98329);
+INSERT INTO City VALUES (1507,'Lecce','ITA','Apulia',98208);
+INSERT INTO City VALUES (1508,'Bolzano','ITA','Trentino-Alto Adige',97232);
+INSERT INTO City VALUES (1509,'Catanzaro','ITA','Calabria',96700);
+INSERT INTO City VALUES (1510,'La Spezia','ITA','Liguria',95504);
+INSERT INTO City VALUES (1511,'Udine','ITA','Friuli-Venezia Giuli',94932);
+INSERT INTO City VALUES (1512,'Torre del Greco','ITA','Campania',94505);
+INSERT INTO City VALUES (1513,'Andria','ITA','Apulia',94443);
+INSERT INTO City VALUES (1514,'Brindisi','ITA','Apulia',93454);
+INSERT INTO City VALUES (1515,'Giugliano in Campania','ITA','Campania',93286);
+INSERT INTO City VALUES (1516,'Pisa','ITA','Toscana',92379);
+INSERT INTO City VALUES (1517,'Barletta','ITA','Apulia',91904);
+INSERT INTO City VALUES (1518,'Arezzo','ITA','Toscana',91729);
+INSERT INTO City VALUES (1519,'Alessandria','ITA','Piemonte',90289);
+INSERT INTO City VALUES (1520,'Cesena','ITA','Emilia-Romagna',89852);
+INSERT INTO City VALUES (1521,'Pesaro','ITA','Marche',88987);
+INSERT INTO City VALUES (1522,'Dili','TMP','Dili',47900);
+INSERT INTO City VALUES (1523,'Wien','AUT','Wien',1608144);
+INSERT INTO City VALUES (1524,'Graz','AUT','Steiermark',240967);
+INSERT INTO City VALUES (1525,'Linz','AUT','North Austria',188022);
+INSERT INTO City VALUES (1526,'Salzburg','AUT','Salzburg',144247);
+INSERT INTO City VALUES (1527,'Innsbruck','AUT','Tiroli',111752);
+INSERT INTO City VALUES (1528,'Klagenfurt','AUT','Kärnten',91141);
+INSERT INTO City VALUES (1529,'Spanish Town','JAM','St. Catherine',110379);
+INSERT INTO City VALUES (1530,'Kingston','JAM','St. Andrew',103962);
+INSERT INTO City VALUES (1531,'Portmore','JAM','St. Andrew',99799);
+INSERT INTO City VALUES (1532,'Tokyo','JPN','Tokyo-to',7980230);
+INSERT INTO City VALUES (1533,'Jokohama [Yokohama]','JPN','Kanagawa',3339594);
+INSERT INTO City VALUES (1534,'Osaka','JPN','Osaka',2595674);
+INSERT INTO City VALUES (1535,'Nagoya','JPN','Aichi',2154376);
+INSERT INTO City VALUES (1536,'Sapporo','JPN','Hokkaido',1790886);
+INSERT INTO City VALUES (1537,'Kioto','JPN','Kyoto',1461974);
+INSERT INTO City VALUES (1538,'Kobe','JPN','Hyogo',1425139);
+INSERT INTO City VALUES (1539,'Fukuoka','JPN','Fukuoka',1308379);
+INSERT INTO City VALUES (1540,'Kawasaki','JPN','Kanagawa',1217359);
+INSERT INTO City VALUES (1541,'Hiroshima','JPN','Hiroshima',1119117);
+INSERT INTO City VALUES (1542,'Kitakyushu','JPN','Fukuoka',1016264);
+INSERT INTO City VALUES (1543,'Sendai','JPN','Miyagi',989975);
+INSERT INTO City VALUES (1544,'Chiba','JPN','Chiba',863930);
+INSERT INTO City VALUES (1545,'Sakai','JPN','Osaka',797735);
+INSERT INTO City VALUES (1546,'Kumamoto','JPN','Kumamoto',656734);
+INSERT INTO City VALUES (1547,'Okayama','JPN','Okayama',624269);
+INSERT INTO City VALUES (1548,'Sagamihara','JPN','Kanagawa',586300);
+INSERT INTO City VALUES (1549,'Hamamatsu','JPN','Shizuoka',568796);
+INSERT INTO City VALUES (1550,'Kagoshima','JPN','Kagoshima',549977);
+INSERT INTO City VALUES (1551,'Funabashi','JPN','Chiba',545299);
+INSERT INTO City VALUES (1552,'Higashiosaka','JPN','Osaka',517785);
+INSERT INTO City VALUES (1553,'Hachioji','JPN','Tokyo-to',513451);
+INSERT INTO City VALUES (1554,'Niigata','JPN','Niigata',497464);
+INSERT INTO City VALUES (1555,'Amagasaki','JPN','Hyogo',481434);
+INSERT INTO City VALUES (1556,'Himeji','JPN','Hyogo',475167);
+INSERT INTO City VALUES (1557,'Shizuoka','JPN','Shizuoka',473854);
+INSERT INTO City VALUES (1558,'Urawa','JPN','Saitama',469675);
+INSERT INTO City VALUES (1559,'Matsuyama','JPN','Ehime',466133);
+INSERT INTO City VALUES (1560,'Matsudo','JPN','Chiba',461126);
+INSERT INTO City VALUES (1561,'Kanazawa','JPN','Ishikawa',455386);
+INSERT INTO City VALUES (1562,'Kawaguchi','JPN','Saitama',452155);
+INSERT INTO City VALUES (1563,'Ichikawa','JPN','Chiba',441893);
+INSERT INTO City VALUES (1564,'Omiya','JPN','Saitama',441649);
+INSERT INTO City VALUES (1565,'Utsunomiya','JPN','Tochigi',440353);
+INSERT INTO City VALUES (1566,'Oita','JPN','Oita',433401);
+INSERT INTO City VALUES (1567,'Nagasaki','JPN','Nagasaki',432759);
+INSERT INTO City VALUES (1568,'Yokosuka','JPN','Kanagawa',430200);
+INSERT INTO City VALUES (1569,'Kurashiki','JPN','Okayama',425103);
+INSERT INTO City VALUES (1570,'Gifu','JPN','Gifu',408007);
+INSERT INTO City VALUES (1571,'Hirakata','JPN','Osaka',403151);
+INSERT INTO City VALUES (1572,'Nishinomiya','JPN','Hyogo',397618);
+INSERT INTO City VALUES (1573,'Toyonaka','JPN','Osaka',396689);
+INSERT INTO City VALUES (1574,'Wakayama','JPN','Wakayama',391233);
+INSERT INTO City VALUES (1575,'Fukuyama','JPN','Hiroshima',376921);
+INSERT INTO City VALUES (1576,'Fujisawa','JPN','Kanagawa',372840);
+INSERT INTO City VALUES (1577,'Asahikawa','JPN','Hokkaido',364813);
+INSERT INTO City VALUES (1578,'Machida','JPN','Tokyo-to',364197);
+INSERT INTO City VALUES (1579,'Nara','JPN','Nara',362812);
+INSERT INTO City VALUES (1580,'Takatsuki','JPN','Osaka',361747);
+INSERT INTO City VALUES (1581,'Iwaki','JPN','Fukushima',361737);
+INSERT INTO City VALUES (1582,'Nagano','JPN','Nagano',361391);
+INSERT INTO City VALUES (1583,'Toyohashi','JPN','Aichi',360066);
+INSERT INTO City VALUES (1584,'Toyota','JPN','Aichi',346090);
+INSERT INTO City VALUES (1585,'Suita','JPN','Osaka',345750);
+INSERT INTO City VALUES (1586,'Takamatsu','JPN','Kagawa',332471);
+INSERT INTO City VALUES (1587,'Koriyama','JPN','Fukushima',330335);
+INSERT INTO City VALUES (1588,'Okazaki','JPN','Aichi',328711);
+INSERT INTO City VALUES (1589,'Kawagoe','JPN','Saitama',327211);
+INSERT INTO City VALUES (1590,'Tokorozawa','JPN','Saitama',325809);
+INSERT INTO City VALUES (1591,'Toyama','JPN','Toyama',325790);
+INSERT INTO City VALUES (1592,'Kochi','JPN','Kochi',324710);
+INSERT INTO City VALUES (1593,'Kashiwa','JPN','Chiba',320296);
+INSERT INTO City VALUES (1594,'Akita','JPN','Akita',314440);
+INSERT INTO City VALUES (1595,'Miyazaki','JPN','Miyazaki',303784);
+INSERT INTO City VALUES (1596,'Koshigaya','JPN','Saitama',301446);
+INSERT INTO City VALUES (1597,'Naha','JPN','Okinawa',299851);
+INSERT INTO City VALUES (1598,'Aomori','JPN','Aomori',295969);
+INSERT INTO City VALUES (1599,'Hakodate','JPN','Hokkaido',294788);
+INSERT INTO City VALUES (1600,'Akashi','JPN','Hyogo',292253);
+INSERT INTO City VALUES (1601,'Yokkaichi','JPN','Mie',288173);
+INSERT INTO City VALUES (1602,'Fukushima','JPN','Fukushima',287525);
+INSERT INTO City VALUES (1603,'Morioka','JPN','Iwate',287353);
+INSERT INTO City VALUES (1604,'Maebashi','JPN','Gumma',284473);
+INSERT INTO City VALUES (1605,'Kasugai','JPN','Aichi',282348);
+INSERT INTO City VALUES (1606,'Otsu','JPN','Shiga',282070);
+INSERT INTO City VALUES (1607,'Ichihara','JPN','Chiba',279280);
+INSERT INTO City VALUES (1608,'Yao','JPN','Osaka',276421);
+INSERT INTO City VALUES (1609,'Ichinomiya','JPN','Aichi',270828);
+INSERT INTO City VALUES (1610,'Tokushima','JPN','Tokushima',269649);
+INSERT INTO City VALUES (1611,'Kakogawa','JPN','Hyogo',266281);
+INSERT INTO City VALUES (1612,'Ibaraki','JPN','Osaka',261020);
+INSERT INTO City VALUES (1613,'Neyagawa','JPN','Osaka',257315);
+INSERT INTO City VALUES (1614,'Shimonoseki','JPN','Yamaguchi',257263);
+INSERT INTO City VALUES (1615,'Yamagata','JPN','Yamagata',255617);
+INSERT INTO City VALUES (1616,'Fukui','JPN','Fukui',254818);
+INSERT INTO City VALUES (1617,'Hiratsuka','JPN','Kanagawa',254207);
+INSERT INTO City VALUES (1618,'Mito','JPN','Ibaragi',246559);
+INSERT INTO City VALUES (1619,'Sasebo','JPN','Nagasaki',244240);
+INSERT INTO City VALUES (1620,'Hachinohe','JPN','Aomori',242979);
+INSERT INTO City VALUES (1621,'Takasaki','JPN','Gumma',239124);
+INSERT INTO City VALUES (1622,'Shimizu','JPN','Shizuoka',239123);
+INSERT INTO City VALUES (1623,'Kurume','JPN','Fukuoka',235611);
+INSERT INTO City VALUES (1624,'Fuji','JPN','Shizuoka',231527);
+INSERT INTO City VALUES (1625,'Soka','JPN','Saitama',222768);
+INSERT INTO City VALUES (1626,'Fuchu','JPN','Tokyo-to',220576);
+INSERT INTO City VALUES (1627,'Chigasaki','JPN','Kanagawa',216015);
+INSERT INTO City VALUES (1628,'Atsugi','JPN','Kanagawa',212407);
+INSERT INTO City VALUES (1629,'Numazu','JPN','Shizuoka',211382);
+INSERT INTO City VALUES (1630,'Ageo','JPN','Saitama',209442);
+INSERT INTO City VALUES (1631,'Yamato','JPN','Kanagawa',208234);
+INSERT INTO City VALUES (1632,'Matsumoto','JPN','Nagano',206801);
+INSERT INTO City VALUES (1633,'Kure','JPN','Hiroshima',206504);
+INSERT INTO City VALUES (1634,'Takarazuka','JPN','Hyogo',205993);
+INSERT INTO City VALUES (1635,'Kasukabe','JPN','Saitama',201838);
+INSERT INTO City VALUES (1636,'Chofu','JPN','Tokyo-to',201585);
+INSERT INTO City VALUES (1637,'Odawara','JPN','Kanagawa',200171);
+INSERT INTO City VALUES (1638,'Kofu','JPN','Yamanashi',199753);
+INSERT INTO City VALUES (1639,'Kushiro','JPN','Hokkaido',197608);
+INSERT INTO City VALUES (1640,'Kishiwada','JPN','Osaka',197276);
+INSERT INTO City VALUES (1641,'Hitachi','JPN','Ibaragi',196622);
+INSERT INTO City VALUES (1642,'Nagaoka','JPN','Niigata',192407);
+INSERT INTO City VALUES (1643,'Itami','JPN','Hyogo',190886);
+INSERT INTO City VALUES (1644,'Uji','JPN','Kyoto',188735);
+INSERT INTO City VALUES (1645,'Suzuka','JPN','Mie',184061);
+INSERT INTO City VALUES (1646,'Hirosaki','JPN','Aomori',177522);
+INSERT INTO City VALUES (1647,'Ube','JPN','Yamaguchi',175206);
+INSERT INTO City VALUES (1648,'Kodaira','JPN','Tokyo-to',174984);
+INSERT INTO City VALUES (1649,'Takaoka','JPN','Toyama',174380);
+INSERT INTO City VALUES (1650,'Obihiro','JPN','Hokkaido',173685);
+INSERT INTO City VALUES (1651,'Tomakomai','JPN','Hokkaido',171958);
+INSERT INTO City VALUES (1652,'Saga','JPN','Saga',170034);
+INSERT INTO City VALUES (1653,'Sakura','JPN','Chiba',168072);
+INSERT INTO City VALUES (1654,'Kamakura','JPN','Kanagawa',167661);
+INSERT INTO City VALUES (1655,'Mitaka','JPN','Tokyo-to',167268);
+INSERT INTO City VALUES (1656,'Izumi','JPN','Osaka',166979);
+INSERT INTO City VALUES (1657,'Hino','JPN','Tokyo-to',166770);
+INSERT INTO City VALUES (1658,'Hadano','JPN','Kanagawa',166512);
+INSERT INTO City VALUES (1659,'Ashikaga','JPN','Tochigi',165243);
+INSERT INTO City VALUES (1660,'Tsu','JPN','Mie',164543);
+INSERT INTO City VALUES (1661,'Sayama','JPN','Saitama',162472);
+INSERT INTO City VALUES (1662,'Yachiyo','JPN','Chiba',161222);
+INSERT INTO City VALUES (1663,'Tsukuba','JPN','Ibaragi',160768);
+INSERT INTO City VALUES (1664,'Tachikawa','JPN','Tokyo-to',159430);
+INSERT INTO City VALUES (1665,'Kumagaya','JPN','Saitama',157171);
+INSERT INTO City VALUES (1666,'Moriguchi','JPN','Osaka',155941);
+INSERT INTO City VALUES (1667,'Otaru','JPN','Hokkaido',155784);
+INSERT INTO City VALUES (1668,'Anjo','JPN','Aichi',153823);
+INSERT INTO City VALUES (1669,'Narashino','JPN','Chiba',152849);
+INSERT INTO City VALUES (1670,'Oyama','JPN','Tochigi',152820);
+INSERT INTO City VALUES (1671,'Ogaki','JPN','Gifu',151758);
+INSERT INTO City VALUES (1672,'Matsue','JPN','Shimane',149821);
+INSERT INTO City VALUES (1673,'Kawanishi','JPN','Hyogo',149794);
+INSERT INTO City VALUES (1674,'Hitachinaka','JPN','Tokyo-to',148006);
+INSERT INTO City VALUES (1675,'Niiza','JPN','Saitama',147744);
+INSERT INTO City VALUES (1676,'Nagareyama','JPN','Chiba',147738);
+INSERT INTO City VALUES (1677,'Tottori','JPN','Tottori',147523);
+INSERT INTO City VALUES (1678,'Tama','JPN','Ibaragi',146712);
+INSERT INTO City VALUES (1679,'Iruma','JPN','Saitama',145922);
+INSERT INTO City VALUES (1680,'Ota','JPN','Gumma',145317);
+INSERT INTO City VALUES (1681,'Omuta','JPN','Fukuoka',142889);
+INSERT INTO City VALUES (1682,'Komaki','JPN','Aichi',139827);
+INSERT INTO City VALUES (1683,'Ome','JPN','Tokyo-to',139216);
+INSERT INTO City VALUES (1684,'Kadoma','JPN','Osaka',138953);
+INSERT INTO City VALUES (1685,'Yamaguchi','JPN','Yamaguchi',138210);
+INSERT INTO City VALUES (1686,'Higashimurayama','JPN','Tokyo-to',136970);
+INSERT INTO City VALUES (1687,'Yonago','JPN','Tottori',136461);
+INSERT INTO City VALUES (1688,'Matsubara','JPN','Osaka',135010);
+INSERT INTO City VALUES (1689,'Musashino','JPN','Tokyo-to',134426);
+INSERT INTO City VALUES (1690,'Tsuchiura','JPN','Ibaragi',134072);
+INSERT INTO City VALUES (1691,'Joetsu','JPN','Niigata',133505);
+INSERT INTO City VALUES (1692,'Miyakonojo','JPN','Miyazaki',133183);
+INSERT INTO City VALUES (1693,'Misato','JPN','Saitama',132957);
+INSERT INTO City VALUES (1694,'Kakamigahara','JPN','Gifu',131831);
+INSERT INTO City VALUES (1695,'Daito','JPN','Osaka',130594);
+INSERT INTO City VALUES (1696,'Seto','JPN','Aichi',130470);
+INSERT INTO City VALUES (1697,'Kariya','JPN','Aichi',127969);
+INSERT INTO City VALUES (1698,'Urayasu','JPN','Chiba',127550);
+INSERT INTO City VALUES (1699,'Beppu','JPN','Oita',127486);
+INSERT INTO City VALUES (1700,'Niihama','JPN','Ehime',127207);
+INSERT INTO City VALUES (1701,'Minoo','JPN','Osaka',127026);
+INSERT INTO City VALUES (1702,'Fujieda','JPN','Shizuoka',126897);
+INSERT INTO City VALUES (1703,'Abiko','JPN','Chiba',126670);
+INSERT INTO City VALUES (1704,'Nobeoka','JPN','Miyazaki',125547);
+INSERT INTO City VALUES (1705,'Tondabayashi','JPN','Osaka',125094);
+INSERT INTO City VALUES (1706,'Ueda','JPN','Nagano',124217);
+INSERT INTO City VALUES (1707,'Kashihara','JPN','Nara',124013);
+INSERT INTO City VALUES (1708,'Matsusaka','JPN','Mie',123582);
+INSERT INTO City VALUES (1709,'Isesaki','JPN','Gumma',123285);
+INSERT INTO City VALUES (1710,'Zama','JPN','Kanagawa',122046);
+INSERT INTO City VALUES (1711,'Kisarazu','JPN','Chiba',121967);
+INSERT INTO City VALUES (1712,'Noda','JPN','Chiba',121030);
+INSERT INTO City VALUES (1713,'Ishinomaki','JPN','Miyagi',120963);
+INSERT INTO City VALUES (1714,'Fujinomiya','JPN','Shizuoka',119714);
+INSERT INTO City VALUES (1715,'Kawachinagano','JPN','Osaka',119666);
+INSERT INTO City VALUES (1716,'Imabari','JPN','Ehime',119357);
+INSERT INTO City VALUES (1717,'Aizuwakamatsu','JPN','Fukushima',119287);
+INSERT INTO City VALUES (1718,'Higashihiroshima','JPN','Hiroshima',119166);
+INSERT INTO City VALUES (1719,'Habikino','JPN','Osaka',118968);
+INSERT INTO City VALUES (1720,'Ebetsu','JPN','Hokkaido',118805);
+INSERT INTO City VALUES (1721,'Hofu','JPN','Yamaguchi',118751);
+INSERT INTO City VALUES (1722,'Kiryu','JPN','Gumma',118326);
+INSERT INTO City VALUES (1723,'Okinawa','JPN','Okinawa',117748);
+INSERT INTO City VALUES (1724,'Yaizu','JPN','Shizuoka',117258);
+INSERT INTO City VALUES (1725,'Toyokawa','JPN','Aichi',115781);
+INSERT INTO City VALUES (1726,'Ebina','JPN','Kanagawa',115571);
+INSERT INTO City VALUES (1727,'Asaka','JPN','Saitama',114815);
+INSERT INTO City VALUES (1728,'Higashikurume','JPN','Tokyo-to',111666);
+INSERT INTO City VALUES (1729,'Ikoma','JPN','Nara',111645);
+INSERT INTO City VALUES (1730,'Kitami','JPN','Hokkaido',111295);
+INSERT INTO City VALUES (1731,'Koganei','JPN','Tokyo-to',110969);
+INSERT INTO City VALUES (1732,'Iwatsuki','JPN','Saitama',110034);
+INSERT INTO City VALUES (1733,'Mishima','JPN','Shizuoka',109699);
+INSERT INTO City VALUES (1734,'Handa','JPN','Aichi',108600);
+INSERT INTO City VALUES (1735,'Muroran','JPN','Hokkaido',108275);
+INSERT INTO City VALUES (1736,'Komatsu','JPN','Ishikawa',107937);
+INSERT INTO City VALUES (1737,'Yatsushiro','JPN','Kumamoto',107661);
+INSERT INTO City VALUES (1738,'Iida','JPN','Nagano',107583);
+INSERT INTO City VALUES (1739,'Tokuyama','JPN','Yamaguchi',107078);
+INSERT INTO City VALUES (1740,'Kokubunji','JPN','Tokyo-to',106996);
+INSERT INTO City VALUES (1741,'Akishima','JPN','Tokyo-to',106914);
+INSERT INTO City VALUES (1742,'Iwakuni','JPN','Yamaguchi',106647);
+INSERT INTO City VALUES (1743,'Kusatsu','JPN','Shiga',106232);
+INSERT INTO City VALUES (1744,'Kuwana','JPN','Mie',106121);
+INSERT INTO City VALUES (1745,'Sanda','JPN','Hyogo',105643);
+INSERT INTO City VALUES (1746,'Hikone','JPN','Shiga',105508);
+INSERT INTO City VALUES (1747,'Toda','JPN','Saitama',103969);
+INSERT INTO City VALUES (1748,'Tajimi','JPN','Gifu',103171);
+INSERT INTO City VALUES (1749,'Ikeda','JPN','Osaka',102710);
+INSERT INTO City VALUES (1750,'Fukaya','JPN','Saitama',102156);
+INSERT INTO City VALUES (1751,'Ise','JPN','Mie',101732);
+INSERT INTO City VALUES (1752,'Sakata','JPN','Yamagata',101651);
+INSERT INTO City VALUES (1753,'Kasuga','JPN','Fukuoka',101344);
+INSERT INTO City VALUES (1754,'Kamagaya','JPN','Chiba',100821);
+INSERT INTO City VALUES (1755,'Tsuruoka','JPN','Yamagata',100713);
+INSERT INTO City VALUES (1756,'Hoya','JPN','Tokyo-to',100313);
+INSERT INTO City VALUES (1757,'Nishio','JPN','Chiba',100032);
+INSERT INTO City VALUES (1758,'Tokai','JPN','Aichi',99738);
+INSERT INTO City VALUES (1759,'Inazawa','JPN','Aichi',98746);
+INSERT INTO City VALUES (1760,'Sakado','JPN','Saitama',98221);
+INSERT INTO City VALUES (1761,'Isehara','JPN','Kanagawa',98123);
+INSERT INTO City VALUES (1762,'Takasago','JPN','Hyogo',97632);
+INSERT INTO City VALUES (1763,'Fujimi','JPN','Saitama',96972);
+INSERT INTO City VALUES (1764,'Urasoe','JPN','Okinawa',96002);
+INSERT INTO City VALUES (1765,'Yonezawa','JPN','Yamagata',95592);
+INSERT INTO City VALUES (1766,'Konan','JPN','Aichi',95521);
+INSERT INTO City VALUES (1767,'Yamatokoriyama','JPN','Nara',95165);
+INSERT INTO City VALUES (1768,'Maizuru','JPN','Kyoto',94784);
+INSERT INTO City VALUES (1769,'Onomichi','JPN','Hiroshima',93756);
+INSERT INTO City VALUES (1770,'Higashimatsuyama','JPN','Saitama',93342);
+INSERT INTO City VALUES (1771,'Kimitsu','JPN','Chiba',93216);
+INSERT INTO City VALUES (1772,'Isahaya','JPN','Nagasaki',93058);
+INSERT INTO City VALUES (1773,'Kanuma','JPN','Tochigi',93053);
+INSERT INTO City VALUES (1774,'Izumisano','JPN','Osaka',92583);
+INSERT INTO City VALUES (1775,'Kameoka','JPN','Kyoto',92398);
+INSERT INTO City VALUES (1776,'Mobara','JPN','Chiba',91664);
+INSERT INTO City VALUES (1777,'Narita','JPN','Chiba',91470);
+INSERT INTO City VALUES (1778,'Kashiwazaki','JPN','Niigata',91229);
+INSERT INTO City VALUES (1779,'Tsuyama','JPN','Okayama',91170);
+INSERT INTO City VALUES (1780,'Sanaa','YEM','Sanaa',503600);
+INSERT INTO City VALUES (1781,'Aden','YEM','Aden',398300);
+INSERT INTO City VALUES (1782,'Taizz','YEM','Taizz',317600);
+INSERT INTO City VALUES (1783,'Hodeida','YEM','Hodeida',298500);
+INSERT INTO City VALUES (1784,'al-Mukalla','YEM','Hadramawt',122400);
+INSERT INTO City VALUES (1785,'Ibb','YEM','Ibb',103300);
+INSERT INTO City VALUES (1786,'Amman','JOR','Amman',1000000);
+INSERT INTO City VALUES (1787,'al-Zarqa','JOR','al-Zarqa',389815);
+INSERT INTO City VALUES (1788,'Irbid','JOR','Irbid',231511);
+INSERT INTO City VALUES (1789,'al-Rusayfa','JOR','al-Zarqa',137247);
+INSERT INTO City VALUES (1790,'Wadi al-Sir','JOR','Amman',89104);
+INSERT INTO City VALUES (1791,'Flying Fish Cove','CXR','–',700);
+INSERT INTO City VALUES (1792,'Beograd','YUG','Central Serbia',1204000);
+INSERT INTO City VALUES (1793,'Novi Sad','YUG','Vojvodina',179626);
+INSERT INTO City VALUES (1794,'Niš','YUG','Central Serbia',175391);
+INSERT INTO City VALUES (1795,'Priština','YUG','Kosovo and Metohija',155496);
+INSERT INTO City VALUES (1796,'Kragujevac','YUG','Central Serbia',147305);
+INSERT INTO City VALUES (1797,'Podgorica','YUG','Montenegro',135000);
+INSERT INTO City VALUES (1798,'Subotica','YUG','Vojvodina',100386);
+INSERT INTO City VALUES (1799,'Prizren','YUG','Kosovo and Metohija',92303);
+INSERT INTO City VALUES (1800,'Phnom Penh','KHM','Phnom Penh',570155);
+INSERT INTO City VALUES (1801,'Battambang','KHM','Battambang',129800);
+INSERT INTO City VALUES (1802,'Siem Reap','KHM','Siem Reap',105100);
+INSERT INTO City VALUES (1803,'Douala','CMR','Littoral',1448300);
+INSERT INTO City VALUES (1804,'Yaoundé','CMR','Centre',1372800);
+INSERT INTO City VALUES (1805,'Garoua','CMR','Nord',177000);
+INSERT INTO City VALUES (1806,'Maroua','CMR','Extrême-Nord',143000);
+INSERT INTO City VALUES (1807,'Bamenda','CMR','Nord-Ouest',138000);
+INSERT INTO City VALUES (1808,'Bafoussam','CMR','Ouest',131000);
+INSERT INTO City VALUES (1809,'Nkongsamba','CMR','Littoral',112454);
+INSERT INTO City VALUES (1810,'Montréal','CAN','Québec',1016376);
+INSERT INTO City VALUES (1811,'Calgary','CAN','Alberta',768082);
+INSERT INTO City VALUES (1812,'Toronto','CAN','Ontario',688275);
+INSERT INTO City VALUES (1813,'North York','CAN','Ontario',622632);
+INSERT INTO City VALUES (1814,'Winnipeg','CAN','Manitoba',618477);
+INSERT INTO City VALUES (1815,'Edmonton','CAN','Alberta',616306);
+INSERT INTO City VALUES (1816,'Mississauga','CAN','Ontario',608072);
+INSERT INTO City VALUES (1817,'Scarborough','CAN','Ontario',594501);
+INSERT INTO City VALUES (1818,'Vancouver','CAN','British Colombia',514008);
+INSERT INTO City VALUES (1819,'Etobicoke','CAN','Ontario',348845);
+INSERT INTO City VALUES (1820,'London','CAN','Ontario',339917);
+INSERT INTO City VALUES (1821,'Hamilton','CAN','Ontario',335614);
+INSERT INTO City VALUES (1822,'Ottawa','CAN','Ontario',335277);
+INSERT INTO City VALUES (1823,'Laval','CAN','Québec',330393);
+INSERT INTO City VALUES (1824,'Surrey','CAN','British Colombia',304477);
+INSERT INTO City VALUES (1825,'Brampton','CAN','Ontario',296711);
+INSERT INTO City VALUES (1826,'Windsor','CAN','Ontario',207588);
+INSERT INTO City VALUES (1827,'Saskatoon','CAN','Saskatchewan',193647);
+INSERT INTO City VALUES (1828,'Kitchener','CAN','Ontario',189959);
+INSERT INTO City VALUES (1829,'Markham','CAN','Ontario',189098);
+INSERT INTO City VALUES (1830,'Regina','CAN','Saskatchewan',180400);
+INSERT INTO City VALUES (1831,'Burnaby','CAN','British Colombia',179209);
+INSERT INTO City VALUES (1832,'Québec','CAN','Québec',167264);
+INSERT INTO City VALUES (1833,'York','CAN','Ontario',154980);
+INSERT INTO City VALUES (1834,'Richmond','CAN','British Colombia',148867);
+INSERT INTO City VALUES (1835,'Vaughan','CAN','Ontario',147889);
+INSERT INTO City VALUES (1836,'Burlington','CAN','Ontario',145150);
+INSERT INTO City VALUES (1837,'Oshawa','CAN','Ontario',140173);
+INSERT INTO City VALUES (1838,'Oakville','CAN','Ontario',139192);
+INSERT INTO City VALUES (1839,'Saint Catharines','CAN','Ontario',136216);
+INSERT INTO City VALUES (1840,'Longueuil','CAN','Québec',127977);
+INSERT INTO City VALUES (1841,'Richmond Hill','CAN','Ontario',116428);
+INSERT INTO City VALUES (1842,'Thunder Bay','CAN','Ontario',115913);
+INSERT INTO City VALUES (1843,'Nepean','CAN','Ontario',115100);
+INSERT INTO City VALUES (1844,'Cape Breton','CAN','Nova Scotia',114733);
+INSERT INTO City VALUES (1845,'East York','CAN','Ontario',114034);
+INSERT INTO City VALUES (1846,'Halifax','CAN','Nova Scotia',113910);
+INSERT INTO City VALUES (1847,'Cambridge','CAN','Ontario',109186);
+INSERT INTO City VALUES (1848,'Gloucester','CAN','Ontario',107314);
+INSERT INTO City VALUES (1849,'Abbotsford','CAN','British Colombia',105403);
+INSERT INTO City VALUES (1850,'Guelph','CAN','Ontario',103593);
+INSERT INTO City VALUES (1851,'Saint John´s','CAN','Newfoundland',101936);
+INSERT INTO City VALUES (1852,'Coquitlam','CAN','British Colombia',101820);
+INSERT INTO City VALUES (1853,'Saanich','CAN','British Colombia',101388);
+INSERT INTO City VALUES (1854,'Gatineau','CAN','Québec',100702);
+INSERT INTO City VALUES (1855,'Delta','CAN','British Colombia',95411);
+INSERT INTO City VALUES (1856,'Sudbury','CAN','Ontario',92686);
+INSERT INTO City VALUES (1857,'Kelowna','CAN','British Colombia',89442);
+INSERT INTO City VALUES (1858,'Barrie','CAN','Ontario',89269);
+INSERT INTO City VALUES (1859,'Praia','CPV','São Tiago',94800);
+INSERT INTO City VALUES (1860,'Almaty','KAZ','Almaty Qalasy',1129400);
+INSERT INTO City VALUES (1861,'Qaraghandy','KAZ','Qaraghandy',436900);
+INSERT INTO City VALUES (1862,'Shymkent','KAZ','South Kazakstan',360100);
+INSERT INTO City VALUES (1863,'Taraz','KAZ','Taraz',330100);
+INSERT INTO City VALUES (1864,'Astana','KAZ','Astana',311200);
+INSERT INTO City VALUES (1865,'Öskemen','KAZ','East Kazakstan',311000);
+INSERT INTO City VALUES (1866,'Pavlodar','KAZ','Pavlodar',300500);
+INSERT INTO City VALUES (1867,'Semey','KAZ','East Kazakstan',269600);
+INSERT INTO City VALUES (1868,'Aqtöbe','KAZ','Aqtöbe',253100);
+INSERT INTO City VALUES (1869,'Qostanay','KAZ','Qostanay',221400);
+INSERT INTO City VALUES (1870,'Petropavl','KAZ','North Kazakstan',203500);
+INSERT INTO City VALUES (1871,'Oral','KAZ','West Kazakstan',195500);
+INSERT INTO City VALUES (1872,'Temirtau','KAZ','Qaraghandy',170500);
+INSERT INTO City VALUES (1873,'Qyzylorda','KAZ','Qyzylorda',157400);
+INSERT INTO City VALUES (1874,'Aqtau','KAZ','Mangghystau',143400);
+INSERT INTO City VALUES (1875,'Atyrau','KAZ','Atyrau',142500);
+INSERT INTO City VALUES (1876,'Ekibastuz','KAZ','Pavlodar',127200);
+INSERT INTO City VALUES (1877,'Kökshetau','KAZ','North Kazakstan',123400);
+INSERT INTO City VALUES (1878,'Rudnyy','KAZ','Qostanay',109500);
+INSERT INTO City VALUES (1879,'Taldyqorghan','KAZ','Almaty',98000);
+INSERT INTO City VALUES (1880,'Zhezqazghan','KAZ','Qaraghandy',90000);
+INSERT INTO City VALUES (1881,'Nairobi','KEN','Nairobi',2290000);
+INSERT INTO City VALUES (1882,'Mombasa','KEN','Coast',461753);
+INSERT INTO City VALUES (1883,'Kisumu','KEN','Nyanza',192733);
+INSERT INTO City VALUES (1884,'Nakuru','KEN','Rift Valley',163927);
+INSERT INTO City VALUES (1885,'Machakos','KEN','Eastern',116293);
+INSERT INTO City VALUES (1886,'Eldoret','KEN','Rift Valley',111882);
+INSERT INTO City VALUES (1887,'Meru','KEN','Eastern',94947);
+INSERT INTO City VALUES (1888,'Nyeri','KEN','Central',91258);
+INSERT INTO City VALUES (1889,'Bangui','CAF','Bangui',524000);
+INSERT INTO City VALUES (1890,'Shanghai','CHN','Shanghai',9696300);
+INSERT INTO City VALUES (1891,'Peking','CHN','Peking',7472000);
+INSERT INTO City VALUES (1892,'Chongqing','CHN','Chongqing',6351600);
+INSERT INTO City VALUES (1893,'Tianjin','CHN','Tianjin',5286800);
+INSERT INTO City VALUES (1894,'Wuhan','CHN','Hubei',4344600);
+INSERT INTO City VALUES (1895,'Harbin','CHN','Heilongjiang',4289800);
+INSERT INTO City VALUES (1896,'Shenyang','CHN','Liaoning',4265200);
+INSERT INTO City VALUES (1897,'Kanton [Guangzhou]','CHN','Guangdong',4256300);
+INSERT INTO City VALUES (1898,'Chengdu','CHN','Sichuan',3361500);
+INSERT INTO City VALUES (1899,'Nanking [Nanjing]','CHN','Jiangsu',2870300);
+INSERT INTO City VALUES (1900,'Changchun','CHN','Jilin',2812000);
+INSERT INTO City VALUES (1901,'Xi´an','CHN','Shaanxi',2761400);
+INSERT INTO City VALUES (1902,'Dalian','CHN','Liaoning',2697000);
+INSERT INTO City VALUES (1903,'Qingdao','CHN','Shandong',2596000);
+INSERT INTO City VALUES (1904,'Jinan','CHN','Shandong',2278100);
+INSERT INTO City VALUES (1905,'Hangzhou','CHN','Zhejiang',2190500);
+INSERT INTO City VALUES (1906,'Zhengzhou','CHN','Henan',2107200);
+INSERT INTO City VALUES (1907,'Shijiazhuang','CHN','Hebei',2041500);
+INSERT INTO City VALUES (1908,'Taiyuan','CHN','Shanxi',1968400);
+INSERT INTO City VALUES (1909,'Kunming','CHN','Yunnan',1829500);
+INSERT INTO City VALUES (1910,'Changsha','CHN','Hunan',1809800);
+INSERT INTO City VALUES (1911,'Nanchang','CHN','Jiangxi',1691600);
+INSERT INTO City VALUES (1912,'Fuzhou','CHN','Fujian',1593800);
+INSERT INTO City VALUES (1913,'Lanzhou','CHN','Gansu',1565800);
+INSERT INTO City VALUES (1914,'Guiyang','CHN','Guizhou',1465200);
+INSERT INTO City VALUES (1915,'Ningbo','CHN','Zhejiang',1371200);
+INSERT INTO City VALUES (1916,'Hefei','CHN','Anhui',1369100);
+INSERT INTO City VALUES (1917,'Urumtši [Ürümqi]','CHN','Xinxiang',1310100);
+INSERT INTO City VALUES (1918,'Anshan','CHN','Liaoning',1200000);
+INSERT INTO City VALUES (1919,'Fushun','CHN','Liaoning',1200000);
+INSERT INTO City VALUES (1920,'Nanning','CHN','Guangxi',1161800);
+INSERT INTO City VALUES (1921,'Zibo','CHN','Shandong',1140000);
+INSERT INTO City VALUES (1922,'Qiqihar','CHN','Heilongjiang',1070000);
+INSERT INTO City VALUES (1923,'Jilin','CHN','Jilin',1040000);
+INSERT INTO City VALUES (1924,'Tangshan','CHN','Hebei',1040000);
+INSERT INTO City VALUES (1925,'Baotou','CHN','Inner Mongolia',980000);
+INSERT INTO City VALUES (1926,'Shenzhen','CHN','Guangdong',950500);
+INSERT INTO City VALUES (1927,'Hohhot','CHN','Inner Mongolia',916700);
+INSERT INTO City VALUES (1928,'Handan','CHN','Hebei',840000);
+INSERT INTO City VALUES (1929,'Wuxi','CHN','Jiangsu',830000);
+INSERT INTO City VALUES (1930,'Xuzhou','CHN','Jiangsu',810000);
+INSERT INTO City VALUES (1931,'Datong','CHN','Shanxi',800000);
+INSERT INTO City VALUES (1932,'Yichun','CHN','Heilongjiang',800000);
+INSERT INTO City VALUES (1933,'Benxi','CHN','Liaoning',770000);
+INSERT INTO City VALUES (1934,'Luoyang','CHN','Henan',760000);
+INSERT INTO City VALUES (1935,'Suzhou','CHN','Jiangsu',710000);
+INSERT INTO City VALUES (1936,'Xining','CHN','Qinghai',700200);
+INSERT INTO City VALUES (1937,'Huainan','CHN','Anhui',700000);
+INSERT INTO City VALUES (1938,'Jixi','CHN','Heilongjiang',683885);
+INSERT INTO City VALUES (1939,'Daqing','CHN','Heilongjiang',660000);
+INSERT INTO City VALUES (1940,'Fuxin','CHN','Liaoning',640000);
+INSERT INTO City VALUES (1941,'Amoy [Xiamen]','CHN','Fujian',627500);
+INSERT INTO City VALUES (1942,'Liuzhou','CHN','Guangxi',610000);
+INSERT INTO City VALUES (1943,'Shantou','CHN','Guangdong',580000);
+INSERT INTO City VALUES (1944,'Jinzhou','CHN','Liaoning',570000);
+INSERT INTO City VALUES (1945,'Mudanjiang','CHN','Heilongjiang',570000);
+INSERT INTO City VALUES (1946,'Yinchuan','CHN','Ningxia',544500);
+INSERT INTO City VALUES (1947,'Changzhou','CHN','Jiangsu',530000);
+INSERT INTO City VALUES (1948,'Zhangjiakou','CHN','Hebei',530000);
+INSERT INTO City VALUES (1949,'Dandong','CHN','Liaoning',520000);
+INSERT INTO City VALUES (1950,'Hegang','CHN','Heilongjiang',520000);
+INSERT INTO City VALUES (1951,'Kaifeng','CHN','Henan',510000);
+INSERT INTO City VALUES (1952,'Jiamusi','CHN','Heilongjiang',493409);
+INSERT INTO City VALUES (1953,'Liaoyang','CHN','Liaoning',492559);
+INSERT INTO City VALUES (1954,'Hengyang','CHN','Hunan',487148);
+INSERT INTO City VALUES (1955,'Baoding','CHN','Hebei',483155);
+INSERT INTO City VALUES (1956,'Hunjiang','CHN','Jilin',482043);
+INSERT INTO City VALUES (1957,'Xinxiang','CHN','Henan',473762);
+INSERT INTO City VALUES (1958,'Huangshi','CHN','Hubei',457601);
+INSERT INTO City VALUES (1959,'Haikou','CHN','Hainan',454300);
+INSERT INTO City VALUES (1960,'Yantai','CHN','Shandong',452127);
+INSERT INTO City VALUES (1961,'Bengbu','CHN','Anhui',449245);
+INSERT INTO City VALUES (1962,'Xiangtan','CHN','Hunan',441968);
+INSERT INTO City VALUES (1963,'Weifang','CHN','Shandong',428522);
+INSERT INTO City VALUES (1964,'Wuhu','CHN','Anhui',425740);
+INSERT INTO City VALUES (1965,'Pingxiang','CHN','Jiangxi',425579);
+INSERT INTO City VALUES (1966,'Yingkou','CHN','Liaoning',421589);
+INSERT INTO City VALUES (1967,'Anyang','CHN','Henan',420332);
+INSERT INTO City VALUES (1968,'Panzhihua','CHN','Sichuan',415466);
+INSERT INTO City VALUES (1969,'Pingdingshan','CHN','Henan',410775);
+INSERT INTO City VALUES (1970,'Xiangfan','CHN','Hubei',410407);
+INSERT INTO City VALUES (1971,'Zhuzhou','CHN','Hunan',409924);
+INSERT INTO City VALUES (1972,'Jiaozuo','CHN','Henan',409100);
+INSERT INTO City VALUES (1973,'Wenzhou','CHN','Zhejiang',401871);
+INSERT INTO City VALUES (1974,'Zhangjiang','CHN','Guangdong',400997);
+INSERT INTO City VALUES (1975,'Zigong','CHN','Sichuan',393184);
+INSERT INTO City VALUES (1976,'Shuangyashan','CHN','Heilongjiang',386081);
+INSERT INTO City VALUES (1977,'Zaozhuang','CHN','Shandong',380846);
+INSERT INTO City VALUES (1978,'Yakeshi','CHN','Inner Mongolia',377869);
+INSERT INTO City VALUES (1979,'Yichang','CHN','Hubei',371601);
+INSERT INTO City VALUES (1980,'Zhenjiang','CHN','Jiangsu',368316);
+INSERT INTO City VALUES (1981,'Huaibei','CHN','Anhui',366549);
+INSERT INTO City VALUES (1982,'Qinhuangdao','CHN','Hebei',364972);
+INSERT INTO City VALUES (1983,'Guilin','CHN','Guangxi',364130);
+INSERT INTO City VALUES (1984,'Liupanshui','CHN','Guizhou',363954);
+INSERT INTO City VALUES (1985,'Panjin','CHN','Liaoning',362773);
+INSERT INTO City VALUES (1986,'Yangquan','CHN','Shanxi',362268);
+INSERT INTO City VALUES (1987,'Jinxi','CHN','Liaoning',357052);
+INSERT INTO City VALUES (1988,'Liaoyuan','CHN','Jilin',354141);
+INSERT INTO City VALUES (1989,'Lianyungang','CHN','Jiangsu',354139);
+INSERT INTO City VALUES (1990,'Xianyang','CHN','Shaanxi',352125);
+INSERT INTO City VALUES (1991,'Tai´an','CHN','Shandong',350696);
+INSERT INTO City VALUES (1992,'Chifeng','CHN','Inner Mongolia',350077);
+INSERT INTO City VALUES (1993,'Shaoguan','CHN','Guangdong',350043);
+INSERT INTO City VALUES (1994,'Nantong','CHN','Jiangsu',343341);
+INSERT INTO City VALUES (1995,'Leshan','CHN','Sichuan',341128);
+INSERT INTO City VALUES (1996,'Baoji','CHN','Shaanxi',337765);
+INSERT INTO City VALUES (1997,'Linyi','CHN','Shandong',324720);
+INSERT INTO City VALUES (1998,'Tonghua','CHN','Jilin',324600);
+INSERT INTO City VALUES (1999,'Siping','CHN','Jilin',317223);
+INSERT INTO City VALUES (2000,'Changzhi','CHN','Shanxi',317144);
+INSERT INTO City VALUES (2001,'Tengzhou','CHN','Shandong',315083);
+INSERT INTO City VALUES (2002,'Chaozhou','CHN','Guangdong',313469);
+INSERT INTO City VALUES (2003,'Yangzhou','CHN','Jiangsu',312892);
+INSERT INTO City VALUES (2004,'Dongwan','CHN','Guangdong',308669);
+INSERT INTO City VALUES (2005,'Ma´anshan','CHN','Anhui',305421);
+INSERT INTO City VALUES (2006,'Foshan','CHN','Guangdong',303160);
+INSERT INTO City VALUES (2007,'Yueyang','CHN','Hunan',302800);
+INSERT INTO City VALUES (2008,'Xingtai','CHN','Hebei',302789);
+INSERT INTO City VALUES (2009,'Changde','CHN','Hunan',301276);
+INSERT INTO City VALUES (2010,'Shihezi','CHN','Xinxiang',299676);
+INSERT INTO City VALUES (2011,'Yancheng','CHN','Jiangsu',296831);
+INSERT INTO City VALUES (2012,'Jiujiang','CHN','Jiangxi',291187);
+INSERT INTO City VALUES (2013,'Dongying','CHN','Shandong',281728);
+INSERT INTO City VALUES (2014,'Shashi','CHN','Hubei',281352);
+INSERT INTO City VALUES (2015,'Xintai','CHN','Shandong',281248);
+INSERT INTO City VALUES (2016,'Jingdezhen','CHN','Jiangxi',281183);
+INSERT INTO City VALUES (2017,'Tongchuan','CHN','Shaanxi',280657);
+INSERT INTO City VALUES (2018,'Zhongshan','CHN','Guangdong',278829);
+INSERT INTO City VALUES (2019,'Shiyan','CHN','Hubei',273786);
+INSERT INTO City VALUES (2020,'Tieli','CHN','Heilongjiang',265683);
+INSERT INTO City VALUES (2021,'Jining','CHN','Shandong',265248);
+INSERT INTO City VALUES (2022,'Wuhai','CHN','Inner Mongolia',264081);
+INSERT INTO City VALUES (2023,'Mianyang','CHN','Sichuan',262947);
+INSERT INTO City VALUES (2024,'Luzhou','CHN','Sichuan',262892);
+INSERT INTO City VALUES (2025,'Zunyi','CHN','Guizhou',261862);
+INSERT INTO City VALUES (2026,'Shizuishan','CHN','Ningxia',257862);
+INSERT INTO City VALUES (2027,'Neijiang','CHN','Sichuan',256012);
+INSERT INTO City VALUES (2028,'Tongliao','CHN','Inner Mongolia',255129);
+INSERT INTO City VALUES (2029,'Tieling','CHN','Liaoning',254842);
+INSERT INTO City VALUES (2030,'Wafangdian','CHN','Liaoning',251733);
+INSERT INTO City VALUES (2031,'Anqing','CHN','Anhui',250718);
+INSERT INTO City VALUES (2032,'Shaoyang','CHN','Hunan',247227);
+INSERT INTO City VALUES (2033,'Laiwu','CHN','Shandong',246833);
+INSERT INTO City VALUES (2034,'Chengde','CHN','Hebei',246799);
+INSERT INTO City VALUES (2035,'Tianshui','CHN','Gansu',244974);
+INSERT INTO City VALUES (2036,'Nanyang','CHN','Henan',243303);
+INSERT INTO City VALUES (2037,'Cangzhou','CHN','Hebei',242708);
+INSERT INTO City VALUES (2038,'Yibin','CHN','Sichuan',241019);
+INSERT INTO City VALUES (2039,'Huaiyin','CHN','Jiangsu',239675);
+INSERT INTO City VALUES (2040,'Dunhua','CHN','Jilin',235100);
+INSERT INTO City VALUES (2041,'Yanji','CHN','Jilin',230892);
+INSERT INTO City VALUES (2042,'Jiangmen','CHN','Guangdong',230587);
+INSERT INTO City VALUES (2043,'Tongling','CHN','Anhui',228017);
+INSERT INTO City VALUES (2044,'Suihua','CHN','Heilongjiang',227881);
+INSERT INTO City VALUES (2045,'Gongziling','CHN','Jilin',226569);
+INSERT INTO City VALUES (2046,'Xiantao','CHN','Hubei',222884);
+INSERT INTO City VALUES (2047,'Chaoyang','CHN','Liaoning',222394);
+INSERT INTO City VALUES (2048,'Ganzhou','CHN','Jiangxi',220129);
+INSERT INTO City VALUES (2049,'Huzhou','CHN','Zhejiang',218071);
+INSERT INTO City VALUES (2050,'Baicheng','CHN','Jilin',217987);
+INSERT INTO City VALUES (2051,'Shangzi','CHN','Heilongjiang',215373);
+INSERT INTO City VALUES (2052,'Yangjiang','CHN','Guangdong',215196);
+INSERT INTO City VALUES (2053,'Qitaihe','CHN','Heilongjiang',214957);
+INSERT INTO City VALUES (2054,'Gejiu','CHN','Yunnan',214294);
+INSERT INTO City VALUES (2055,'Jiangyin','CHN','Jiangsu',213659);
+INSERT INTO City VALUES (2056,'Hebi','CHN','Henan',212976);
+INSERT INTO City VALUES (2057,'Jiaxing','CHN','Zhejiang',211526);
+INSERT INTO City VALUES (2058,'Wuzhou','CHN','Guangxi',210452);
+INSERT INTO City VALUES (2059,'Meihekou','CHN','Jilin',209038);
+INSERT INTO City VALUES (2060,'Xuchang','CHN','Henan',208815);
+INSERT INTO City VALUES (2061,'Liaocheng','CHN','Shandong',207844);
+INSERT INTO City VALUES (2062,'Haicheng','CHN','Liaoning',205560);
+INSERT INTO City VALUES (2063,'Qianjiang','CHN','Hubei',205504);
+INSERT INTO City VALUES (2064,'Baiyin','CHN','Gansu',204970);
+INSERT INTO City VALUES (2065,'Bei´an','CHN','Heilongjiang',204899);
+INSERT INTO City VALUES (2066,'Yixing','CHN','Jiangsu',200824);
+INSERT INTO City VALUES (2067,'Laizhou','CHN','Shandong',198664);
+INSERT INTO City VALUES (2068,'Qaramay','CHN','Xinxiang',197602);
+INSERT INTO City VALUES (2069,'Acheng','CHN','Heilongjiang',197595);
+INSERT INTO City VALUES (2070,'Dezhou','CHN','Shandong',195485);
+INSERT INTO City VALUES (2071,'Nanping','CHN','Fujian',195064);
+INSERT INTO City VALUES (2072,'Zhaoqing','CHN','Guangdong',194784);
+INSERT INTO City VALUES (2073,'Beipiao','CHN','Liaoning',194301);
+INSERT INTO City VALUES (2074,'Fengcheng','CHN','Jiangxi',193784);
+INSERT INTO City VALUES (2075,'Fuyu','CHN','Jilin',192981);
+INSERT INTO City VALUES (2076,'Xinyang','CHN','Henan',192509);
+INSERT INTO City VALUES (2077,'Dongtai','CHN','Jiangsu',192247);
+INSERT INTO City VALUES (2078,'Yuci','CHN','Shanxi',191356);
+INSERT INTO City VALUES (2079,'Honghu','CHN','Hubei',190772);
+INSERT INTO City VALUES (2080,'Ezhou','CHN','Hubei',190123);
+INSERT INTO City VALUES (2081,'Heze','CHN','Shandong',189293);
+INSERT INTO City VALUES (2082,'Daxian','CHN','Sichuan',188101);
+INSERT INTO City VALUES (2083,'Linfen','CHN','Shanxi',187309);
+INSERT INTO City VALUES (2084,'Tianmen','CHN','Hubei',186332);
+INSERT INTO City VALUES (2085,'Yiyang','CHN','Hunan',185818);
+INSERT INTO City VALUES (2086,'Quanzhou','CHN','Fujian',185154);
+INSERT INTO City VALUES (2087,'Rizhao','CHN','Shandong',185048);
+INSERT INTO City VALUES (2088,'Deyang','CHN','Sichuan',182488);
+INSERT INTO City VALUES (2089,'Guangyuan','CHN','Sichuan',182241);
+INSERT INTO City VALUES (2090,'Changshu','CHN','Jiangsu',181805);
+INSERT INTO City VALUES (2091,'Zhangzhou','CHN','Fujian',181424);
+INSERT INTO City VALUES (2092,'Hailar','CHN','Inner Mongolia',180650);
+INSERT INTO City VALUES (2093,'Nanchong','CHN','Sichuan',180273);
+INSERT INTO City VALUES (2094,'Jiutai','CHN','Jilin',180130);
+INSERT INTO City VALUES (2095,'Zhaodong','CHN','Heilongjiang',179976);
+INSERT INTO City VALUES (2096,'Shaoxing','CHN','Zhejiang',179818);
+INSERT INTO City VALUES (2097,'Fuyang','CHN','Anhui',179572);
+INSERT INTO City VALUES (2098,'Maoming','CHN','Guangdong',178683);
+INSERT INTO City VALUES (2099,'Qujing','CHN','Yunnan',178669);
+INSERT INTO City VALUES (2100,'Ghulja','CHN','Xinxiang',177193);
+INSERT INTO City VALUES (2101,'Jiaohe','CHN','Jilin',176367);
+INSERT INTO City VALUES (2102,'Puyang','CHN','Henan',175988);
+INSERT INTO City VALUES (2103,'Huadian','CHN','Jilin',175873);
+INSERT INTO City VALUES (2104,'Jiangyou','CHN','Sichuan',175753);
+INSERT INTO City VALUES (2105,'Qashqar','CHN','Xinxiang',174570);
+INSERT INTO City VALUES (2106,'Anshun','CHN','Guizhou',174142);
+INSERT INTO City VALUES (2107,'Fuling','CHN','Sichuan',173878);
+INSERT INTO City VALUES (2108,'Xinyu','CHN','Jiangxi',173524);
+INSERT INTO City VALUES (2109,'Hanzhong','CHN','Shaanxi',169930);
+INSERT INTO City VALUES (2110,'Danyang','CHN','Jiangsu',169603);
+INSERT INTO City VALUES (2111,'Chenzhou','CHN','Hunan',169400);
+INSERT INTO City VALUES (2112,'Xiaogan','CHN','Hubei',166280);
+INSERT INTO City VALUES (2113,'Shangqiu','CHN','Henan',164880);
+INSERT INTO City VALUES (2114,'Zhuhai','CHN','Guangdong',164747);
+INSERT INTO City VALUES (2115,'Qingyuan','CHN','Guangdong',164641);
+INSERT INTO City VALUES (2116,'Aqsu','CHN','Xinxiang',164092);
+INSERT INTO City VALUES (2117,'Jining','CHN','Inner Mongolia',163552);
+INSERT INTO City VALUES (2118,'Xiaoshan','CHN','Zhejiang',162930);
+INSERT INTO City VALUES (2119,'Zaoyang','CHN','Hubei',162198);
+INSERT INTO City VALUES (2120,'Xinghua','CHN','Jiangsu',161910);
+INSERT INTO City VALUES (2121,'Hami','CHN','Xinxiang',161315);
+INSERT INTO City VALUES (2122,'Huizhou','CHN','Guangdong',161023);
+INSERT INTO City VALUES (2123,'Jinmen','CHN','Hubei',160794);
+INSERT INTO City VALUES (2124,'Sanming','CHN','Fujian',160691);
+INSERT INTO City VALUES (2125,'Ulanhot','CHN','Inner Mongolia',159538);
+INSERT INTO City VALUES (2126,'Korla','CHN','Xinxiang',159344);
+INSERT INTO City VALUES (2127,'Wanxian','CHN','Sichuan',156823);
+INSERT INTO City VALUES (2128,'Rui´an','CHN','Zhejiang',156468);
+INSERT INTO City VALUES (2129,'Zhoushan','CHN','Zhejiang',156317);
+INSERT INTO City VALUES (2130,'Liangcheng','CHN','Shandong',156307);
+INSERT INTO City VALUES (2131,'Jiaozhou','CHN','Shandong',153364);
+INSERT INTO City VALUES (2132,'Taizhou','CHN','Jiangsu',152442);
+INSERT INTO City VALUES (2133,'Suzhou','CHN','Anhui',151862);
+INSERT INTO City VALUES (2134,'Yichun','CHN','Jiangxi',151585);
+INSERT INTO City VALUES (2135,'Taonan','CHN','Jilin',150168);
+INSERT INTO City VALUES (2136,'Pingdu','CHN','Shandong',150123);
+INSERT INTO City VALUES (2137,'Ji´an','CHN','Jiangxi',148583);
+INSERT INTO City VALUES (2138,'Longkou','CHN','Shandong',148362);
+INSERT INTO City VALUES (2139,'Langfang','CHN','Hebei',148105);
+INSERT INTO City VALUES (2140,'Zhoukou','CHN','Henan',146288);
+INSERT INTO City VALUES (2141,'Suining','CHN','Sichuan',146086);
+INSERT INTO City VALUES (2142,'Yulin','CHN','Guangxi',144467);
+INSERT INTO City VALUES (2143,'Jinhua','CHN','Zhejiang',144280);
+INSERT INTO City VALUES (2144,'Liu´an','CHN','Anhui',144248);
+INSERT INTO City VALUES (2145,'Shuangcheng','CHN','Heilongjiang',142659);
+INSERT INTO City VALUES (2146,'Suizhou','CHN','Hubei',142302);
+INSERT INTO City VALUES (2147,'Ankang','CHN','Shaanxi',142170);
+INSERT INTO City VALUES (2148,'Weinan','CHN','Shaanxi',140169);
+INSERT INTO City VALUES (2149,'Longjing','CHN','Jilin',139417);
+INSERT INTO City VALUES (2150,'Da´an','CHN','Jilin',138963);
+INSERT INTO City VALUES (2151,'Lengshuijiang','CHN','Hunan',137994);
+INSERT INTO City VALUES (2152,'Laiyang','CHN','Shandong',137080);
+INSERT INTO City VALUES (2153,'Xianning','CHN','Hubei',136811);
+INSERT INTO City VALUES (2154,'Dali','CHN','Yunnan',136554);
+INSERT INTO City VALUES (2155,'Anda','CHN','Heilongjiang',136446);
+INSERT INTO City VALUES (2156,'Jincheng','CHN','Shanxi',136396);
+INSERT INTO City VALUES (2157,'Longyan','CHN','Fujian',134481);
+INSERT INTO City VALUES (2158,'Xichang','CHN','Sichuan',134419);
+INSERT INTO City VALUES (2159,'Wendeng','CHN','Shandong',133910);
+INSERT INTO City VALUES (2160,'Hailun','CHN','Heilongjiang',133565);
+INSERT INTO City VALUES (2161,'Binzhou','CHN','Shandong',133555);
+INSERT INTO City VALUES (2162,'Linhe','CHN','Inner Mongolia',133183);
+INSERT INTO City VALUES (2163,'Wuwei','CHN','Gansu',133101);
+INSERT INTO City VALUES (2164,'Duyun','CHN','Guizhou',132971);
+INSERT INTO City VALUES (2165,'Mishan','CHN','Heilongjiang',132744);
+INSERT INTO City VALUES (2166,'Shangrao','CHN','Jiangxi',132455);
+INSERT INTO City VALUES (2167,'Changji','CHN','Xinxiang',132260);
+INSERT INTO City VALUES (2168,'Meixian','CHN','Guangdong',132156);
+INSERT INTO City VALUES (2169,'Yushu','CHN','Jilin',131861);
+INSERT INTO City VALUES (2170,'Tiefa','CHN','Liaoning',131807);
+INSERT INTO City VALUES (2171,'Huai´an','CHN','Jiangsu',131149);
+INSERT INTO City VALUES (2172,'Leiyang','CHN','Hunan',130115);
+INSERT INTO City VALUES (2173,'Zalantun','CHN','Inner Mongolia',130031);
+INSERT INTO City VALUES (2174,'Weihai','CHN','Shandong',128888);
+INSERT INTO City VALUES (2175,'Loudi','CHN','Hunan',128418);
+INSERT INTO City VALUES (2176,'Qingzhou','CHN','Shandong',128258);
+INSERT INTO City VALUES (2177,'Qidong','CHN','Jiangsu',126872);
+INSERT INTO City VALUES (2178,'Huaihua','CHN','Hunan',126785);
+INSERT INTO City VALUES (2179,'Luohe','CHN','Henan',126438);
+INSERT INTO City VALUES (2180,'Chuzhou','CHN','Anhui',125341);
+INSERT INTO City VALUES (2181,'Kaiyuan','CHN','Liaoning',124219);
+INSERT INTO City VALUES (2182,'Linqing','CHN','Shandong',123958);
+INSERT INTO City VALUES (2183,'Chaohu','CHN','Anhui',123676);
+INSERT INTO City VALUES (2184,'Laohekou','CHN','Hubei',123366);
+INSERT INTO City VALUES (2185,'Dujiangyan','CHN','Sichuan',123357);
+INSERT INTO City VALUES (2186,'Zhumadian','CHN','Henan',123232);
+INSERT INTO City VALUES (2187,'Linchuan','CHN','Jiangxi',121949);
+INSERT INTO City VALUES (2188,'Jiaonan','CHN','Shandong',121397);
+INSERT INTO City VALUES (2189,'Sanmenxia','CHN','Henan',120523);
+INSERT INTO City VALUES (2190,'Heyuan','CHN','Guangdong',120101);
+INSERT INTO City VALUES (2191,'Manzhouli','CHN','Inner Mongolia',120023);
+INSERT INTO City VALUES (2192,'Lhasa','CHN','Tibet',120000);
+INSERT INTO City VALUES (2193,'Lianyuan','CHN','Hunan',118858);
+INSERT INTO City VALUES (2194,'Kuytun','CHN','Xinxiang',118553);
+INSERT INTO City VALUES (2195,'Puqi','CHN','Hubei',117264);
+INSERT INTO City VALUES (2196,'Hongjiang','CHN','Hunan',116188);
+INSERT INTO City VALUES (2197,'Qinzhou','CHN','Guangxi',114586);
+INSERT INTO City VALUES (2198,'Renqiu','CHN','Hebei',114256);
+INSERT INTO City VALUES (2199,'Yuyao','CHN','Zhejiang',114065);
+INSERT INTO City VALUES (2200,'Guigang','CHN','Guangxi',114025);
+INSERT INTO City VALUES (2201,'Kaili','CHN','Guizhou',113958);
+INSERT INTO City VALUES (2202,'Yan´an','CHN','Shaanxi',113277);
+INSERT INTO City VALUES (2203,'Beihai','CHN','Guangxi',112673);
+INSERT INTO City VALUES (2204,'Xuangzhou','CHN','Anhui',112673);
+INSERT INTO City VALUES (2205,'Quzhou','CHN','Zhejiang',112373);
+INSERT INTO City VALUES (2206,'Yong´an','CHN','Fujian',111762);
+INSERT INTO City VALUES (2207,'Zixing','CHN','Hunan',110048);
+INSERT INTO City VALUES (2208,'Liyang','CHN','Jiangsu',109520);
+INSERT INTO City VALUES (2209,'Yizheng','CHN','Jiangsu',109268);
+INSERT INTO City VALUES (2210,'Yumen','CHN','Gansu',109234);
+INSERT INTO City VALUES (2211,'Liling','CHN','Hunan',108504);
+INSERT INTO City VALUES (2212,'Yuncheng','CHN','Shanxi',108359);
+INSERT INTO City VALUES (2213,'Shanwei','CHN','Guangdong',107847);
+INSERT INTO City VALUES (2214,'Cixi','CHN','Zhejiang',107329);
+INSERT INTO City VALUES (2215,'Yuanjiang','CHN','Hunan',107004);
+INSERT INTO City VALUES (2216,'Bozhou','CHN','Anhui',106346);
+INSERT INTO City VALUES (2217,'Jinchang','CHN','Gansu',105287);
+INSERT INTO City VALUES (2218,'Fu´an','CHN','Fujian',105265);
+INSERT INTO City VALUES (2219,'Suqian','CHN','Jiangsu',105021);
+INSERT INTO City VALUES (2220,'Shishou','CHN','Hubei',104571);
+INSERT INTO City VALUES (2221,'Hengshui','CHN','Hebei',104269);
+INSERT INTO City VALUES (2222,'Danjiangkou','CHN','Hubei',103211);
+INSERT INTO City VALUES (2223,'Fujin','CHN','Heilongjiang',103104);
+INSERT INTO City VALUES (2224,'Sanya','CHN','Hainan',102820);
+INSERT INTO City VALUES (2225,'Guangshui','CHN','Hubei',102770);
+INSERT INTO City VALUES (2226,'Huangshan','CHN','Anhui',102628);
+INSERT INTO City VALUES (2227,'Xingcheng','CHN','Liaoning',102384);
+INSERT INTO City VALUES (2228,'Zhucheng','CHN','Shandong',102134);
+INSERT INTO City VALUES (2229,'Kunshan','CHN','Jiangsu',102052);
+INSERT INTO City VALUES (2230,'Haining','CHN','Zhejiang',100478);
+INSERT INTO City VALUES (2231,'Pingliang','CHN','Gansu',99265);
+INSERT INTO City VALUES (2232,'Fuqing','CHN','Fujian',99193);
+INSERT INTO City VALUES (2233,'Xinzhou','CHN','Shanxi',98667);
+INSERT INTO City VALUES (2234,'Jieyang','CHN','Guangdong',98531);
+INSERT INTO City VALUES (2235,'Zhangjiagang','CHN','Jiangsu',97994);
+INSERT INTO City VALUES (2236,'Tong Xian','CHN','Peking',97168);
+INSERT INTO City VALUES (2237,'Ya´an','CHN','Sichuan',95900);
+INSERT INTO City VALUES (2238,'Jinzhou','CHN','Liaoning',95761);
+INSERT INTO City VALUES (2239,'Emeishan','CHN','Sichuan',94000);
+INSERT INTO City VALUES (2240,'Enshi','CHN','Hubei',93056);
+INSERT INTO City VALUES (2241,'Bose','CHN','Guangxi',93009);
+INSERT INTO City VALUES (2242,'Yuzhou','CHN','Henan',92889);
+INSERT INTO City VALUES (2243,'Kaiyuan','CHN','Yunnan',91999);
+INSERT INTO City VALUES (2244,'Tumen','CHN','Jilin',91471);
+INSERT INTO City VALUES (2245,'Putian','CHN','Fujian',91030);
+INSERT INTO City VALUES (2246,'Linhai','CHN','Zhejiang',90870);
+INSERT INTO City VALUES (2247,'Xilin Hot','CHN','Inner Mongolia',90646);
+INSERT INTO City VALUES (2248,'Shaowu','CHN','Fujian',90286);
+INSERT INTO City VALUES (2249,'Junan','CHN','Shandong',90222);
+INSERT INTO City VALUES (2250,'Huaying','CHN','Sichuan',89400);
+INSERT INTO City VALUES (2251,'Pingyi','CHN','Shandong',89373);
+INSERT INTO City VALUES (2252,'Huangyan','CHN','Zhejiang',89288);
+INSERT INTO City VALUES (2253,'Bishkek','KGZ','Bishkek shaary',589400);
+INSERT INTO City VALUES (2254,'Osh','KGZ','Osh',222700);
+INSERT INTO City VALUES (2255,'Bikenibeu','KIR','South Tarawa',5055);
+INSERT INTO City VALUES (2256,'Bairiki','KIR','South Tarawa',2226);
+INSERT INTO City VALUES (2257,'Santafé de Bogotá','COL','Santafé de Bogotá',6260862);
+INSERT INTO City VALUES (2258,'Cali','COL','Valle',2077386);
+INSERT INTO City VALUES (2259,'Medellín','COL','Antioquia',1861265);
+INSERT INTO City VALUES (2260,'Barranquilla','COL','Atlántico',1223260);
+INSERT INTO City VALUES (2261,'Cartagena','COL','Bolívar',805757);
+INSERT INTO City VALUES (2262,'Cúcuta','COL','Norte de Santander',606932);
+INSERT INTO City VALUES (2263,'Bucaramanga','COL','Santander',515555);
+INSERT INTO City VALUES (2264,'Ibagué','COL','Tolima',393664);
+INSERT INTO City VALUES (2265,'Pereira','COL','Risaralda',381725);
+INSERT INTO City VALUES (2266,'Santa Marta','COL','Magdalena',359147);
+INSERT INTO City VALUES (2267,'Manizales','COL','Caldas',337580);
+INSERT INTO City VALUES (2268,'Bello','COL','Antioquia',333470);
+INSERT INTO City VALUES (2269,'Pasto','COL','Nariño',332396);
+INSERT INTO City VALUES (2270,'Neiva','COL','Huila',300052);
+INSERT INTO City VALUES (2271,'Soledad','COL','Atlántico',295058);
+INSERT INTO City VALUES (2272,'Armenia','COL','Quindío',288977);
+INSERT INTO City VALUES (2273,'Villavicencio','COL','Meta',273140);
+INSERT INTO City VALUES (2274,'Soacha','COL','Cundinamarca',272058);
+INSERT INTO City VALUES (2275,'Valledupar','COL','Cesar',263247);
+INSERT INTO City VALUES (2276,'Montería','COL','Córdoba',248245);
+INSERT INTO City VALUES (2277,'Itagüí','COL','Antioquia',228985);
+INSERT INTO City VALUES (2278,'Palmira','COL','Valle',226509);
+INSERT INTO City VALUES (2279,'Buenaventura','COL','Valle',224336);
+INSERT INTO City VALUES (2280,'Floridablanca','COL','Santander',221913);
+INSERT INTO City VALUES (2281,'Sincelejo','COL','Sucre',220704);
+INSERT INTO City VALUES (2282,'Popayán','COL','Cauca',200719);
+INSERT INTO City VALUES (2283,'Barrancabermeja','COL','Santander',178020);
+INSERT INTO City VALUES (2284,'Dos Quebradas','COL','Risaralda',159363);
+INSERT INTO City VALUES (2285,'Tuluá','COL','Valle',152488);
+INSERT INTO City VALUES (2286,'Envigado','COL','Antioquia',135848);
+INSERT INTO City VALUES (2287,'Cartago','COL','Valle',125884);
+INSERT INTO City VALUES (2288,'Girardot','COL','Cundinamarca',110963);
+INSERT INTO City VALUES (2289,'Buga','COL','Valle',110699);
+INSERT INTO City VALUES (2290,'Tunja','COL','Boyacá',109740);
+INSERT INTO City VALUES (2291,'Florencia','COL','Caquetá',108574);
+INSERT INTO City VALUES (2292,'Maicao','COL','La Guajira',108053);
+INSERT INTO City VALUES (2293,'Sogamoso','COL','Boyacá',107728);
+INSERT INTO City VALUES (2294,'Giron','COL','Santander',90688);
+INSERT INTO City VALUES (2295,'Moroni','COM','Njazidja',36000);
+INSERT INTO City VALUES (2296,'Brazzaville','COG','Brazzaville',950000);
+INSERT INTO City VALUES (2297,'Pointe-Noire','COG','Kouilou',500000);
+INSERT INTO City VALUES (2298,'Kinshasa','COD','Kinshasa',5064000);
+INSERT INTO City VALUES (2299,'Lubumbashi','COD','Shaba',851381);
+INSERT INTO City VALUES (2300,'Mbuji-Mayi','COD','East Kasai',806475);
+INSERT INTO City VALUES (2301,'Kolwezi','COD','Shaba',417810);
+INSERT INTO City VALUES (2302,'Kisangani','COD','Haute-Zaïre',417517);
+INSERT INTO City VALUES (2303,'Kananga','COD','West Kasai',393030);
+INSERT INTO City VALUES (2304,'Likasi','COD','Shaba',299118);
+INSERT INTO City VALUES (2305,'Bukavu','COD','South Kivu',201569);
+INSERT INTO City VALUES (2306,'Kikwit','COD','Bandundu',182142);
+INSERT INTO City VALUES (2307,'Tshikapa','COD','West Kasai',180860);
+INSERT INTO City VALUES (2308,'Matadi','COD','Bas-Zaïre',172730);
+INSERT INTO City VALUES (2309,'Mbandaka','COD','Equateur',169841);
+INSERT INTO City VALUES (2310,'Mwene-Ditu','COD','East Kasai',137459);
+INSERT INTO City VALUES (2311,'Boma','COD','Bas-Zaïre',135284);
+INSERT INTO City VALUES (2312,'Uvira','COD','South Kivu',115590);
+INSERT INTO City VALUES (2313,'Butembo','COD','North Kivu',109406);
+INSERT INTO City VALUES (2314,'Goma','COD','North Kivu',109094);
+INSERT INTO City VALUES (2315,'Kalemie','COD','Shaba',101309);
+INSERT INTO City VALUES (2316,'Bantam','CCK','Home Island',503);
+INSERT INTO City VALUES (2317,'West Island','CCK','West Island',167);
+INSERT INTO City VALUES (2318,'Pyongyang','PRK','Pyongyang-si',2484000);
+INSERT INTO City VALUES (2319,'Hamhung','PRK','Hamgyong N',709730);
+INSERT INTO City VALUES (2320,'Chongjin','PRK','Hamgyong P',582480);
+INSERT INTO City VALUES (2321,'Nampo','PRK','Nampo-si',566200);
+INSERT INTO City VALUES (2322,'Sinuiju','PRK','Pyongan P',326011);
+INSERT INTO City VALUES (2323,'Wonsan','PRK','Kangwon',300148);
+INSERT INTO City VALUES (2324,'Phyongsong','PRK','Pyongan N',272934);
+INSERT INTO City VALUES (2325,'Sariwon','PRK','Hwanghae P',254146);
+INSERT INTO City VALUES (2326,'Haeju','PRK','Hwanghae N',229172);
+INSERT INTO City VALUES (2327,'Kanggye','PRK','Chagang',223410);
+INSERT INTO City VALUES (2328,'Kimchaek','PRK','Hamgyong P',179000);
+INSERT INTO City VALUES (2329,'Hyesan','PRK','Yanggang',178020);
+INSERT INTO City VALUES (2330,'Kaesong','PRK','Kaesong-si',171500);
+INSERT INTO City VALUES (2331,'Seoul','KOR','Seoul',9981619);
+INSERT INTO City VALUES (2332,'Pusan','KOR','Pusan',3804522);
+INSERT INTO City VALUES (2333,'Inchon','KOR','Inchon',2559424);
+INSERT INTO City VALUES (2334,'Taegu','KOR','Taegu',2548568);
+INSERT INTO City VALUES (2335,'Taejon','KOR','Taejon',1425835);
+INSERT INTO City VALUES (2336,'Kwangju','KOR','Kwangju',1368341);
+INSERT INTO City VALUES (2337,'Ulsan','KOR','Kyongsangnam',1084891);
+INSERT INTO City VALUES (2338,'Songnam','KOR','Kyonggi',869094);
+INSERT INTO City VALUES (2339,'Puchon','KOR','Kyonggi',779412);
+INSERT INTO City VALUES (2340,'Suwon','KOR','Kyonggi',755550);
+INSERT INTO City VALUES (2341,'Anyang','KOR','Kyonggi',591106);
+INSERT INTO City VALUES (2342,'Chonju','KOR','Chollabuk',563153);
+INSERT INTO City VALUES (2343,'Chongju','KOR','Chungchongbuk',531376);
+INSERT INTO City VALUES (2344,'Koyang','KOR','Kyonggi',518282);
+INSERT INTO City VALUES (2345,'Ansan','KOR','Kyonggi',510314);
+INSERT INTO City VALUES (2346,'Pohang','KOR','Kyongsangbuk',508899);
+INSERT INTO City VALUES (2347,'Chang-won','KOR','Kyongsangnam',481694);
+INSERT INTO City VALUES (2348,'Masan','KOR','Kyongsangnam',441242);
+INSERT INTO City VALUES (2349,'Kwangmyong','KOR','Kyonggi',350914);
+INSERT INTO City VALUES (2350,'Chonan','KOR','Chungchongnam',330259);
+INSERT INTO City VALUES (2351,'Chinju','KOR','Kyongsangnam',329886);
+INSERT INTO City VALUES (2352,'Iksan','KOR','Chollabuk',322685);
+INSERT INTO City VALUES (2353,'Pyongtaek','KOR','Kyonggi',312927);
+INSERT INTO City VALUES (2354,'Kumi','KOR','Kyongsangbuk',311431);
+INSERT INTO City VALUES (2355,'Uijongbu','KOR','Kyonggi',276111);
+INSERT INTO City VALUES (2356,'Kyongju','KOR','Kyongsangbuk',272968);
+INSERT INTO City VALUES (2357,'Kunsan','KOR','Chollabuk',266569);
+INSERT INTO City VALUES (2358,'Cheju','KOR','Cheju',258511);
+INSERT INTO City VALUES (2359,'Kimhae','KOR','Kyongsangnam',256370);
+INSERT INTO City VALUES (2360,'Sunchon','KOR','Chollanam',249263);
+INSERT INTO City VALUES (2361,'Mokpo','KOR','Chollanam',247452);
+INSERT INTO City VALUES (2362,'Yong-in','KOR','Kyonggi',242643);
+INSERT INTO City VALUES (2363,'Wonju','KOR','Kang-won',237460);
+INSERT INTO City VALUES (2364,'Kunpo','KOR','Kyonggi',235233);
+INSERT INTO City VALUES (2365,'Chunchon','KOR','Kang-won',234528);
+INSERT INTO City VALUES (2366,'Namyangju','KOR','Kyonggi',229060);
+INSERT INTO City VALUES (2367,'Kangnung','KOR','Kang-won',220403);
+INSERT INTO City VALUES (2368,'Chungju','KOR','Chungchongbuk',205206);
+INSERT INTO City VALUES (2369,'Andong','KOR','Kyongsangbuk',188443);
+INSERT INTO City VALUES (2370,'Yosu','KOR','Chollanam',183596);
+INSERT INTO City VALUES (2371,'Kyongsan','KOR','Kyongsangbuk',173746);
+INSERT INTO City VALUES (2372,'Paju','KOR','Kyonggi',163379);
+INSERT INTO City VALUES (2373,'Yangsan','KOR','Kyongsangnam',163351);
+INSERT INTO City VALUES (2374,'Ichon','KOR','Kyonggi',155332);
+INSERT INTO City VALUES (2375,'Asan','KOR','Chungchongnam',154663);
+INSERT INTO City VALUES (2376,'Koje','KOR','Kyongsangnam',147562);
+INSERT INTO City VALUES (2377,'Kimchon','KOR','Kyongsangbuk',147027);
+INSERT INTO City VALUES (2378,'Nonsan','KOR','Chungchongnam',146619);
+INSERT INTO City VALUES (2379,'Kuri','KOR','Kyonggi',142173);
+INSERT INTO City VALUES (2380,'Chong-up','KOR','Chollabuk',139111);
+INSERT INTO City VALUES (2381,'Chechon','KOR','Chungchongbuk',137070);
+INSERT INTO City VALUES (2382,'Sosan','KOR','Chungchongnam',134746);
+INSERT INTO City VALUES (2383,'Shihung','KOR','Kyonggi',133443);
+INSERT INTO City VALUES (2384,'Tong-yong','KOR','Kyongsangnam',131717);
+INSERT INTO City VALUES (2385,'Kongju','KOR','Chungchongnam',131229);
+INSERT INTO City VALUES (2386,'Yongju','KOR','Kyongsangbuk',131097);
+INSERT INTO City VALUES (2387,'Chinhae','KOR','Kyongsangnam',125997);
+INSERT INTO City VALUES (2388,'Sangju','KOR','Kyongsangbuk',124116);
+INSERT INTO City VALUES (2389,'Poryong','KOR','Chungchongnam',122604);
+INSERT INTO City VALUES (2390,'Kwang-yang','KOR','Chollanam',122052);
+INSERT INTO City VALUES (2391,'Miryang','KOR','Kyongsangnam',121501);
+INSERT INTO City VALUES (2392,'Hanam','KOR','Kyonggi',115812);
+INSERT INTO City VALUES (2393,'Kimje','KOR','Chollabuk',115427);
+INSERT INTO City VALUES (2394,'Yongchon','KOR','Kyongsangbuk',113511);
+INSERT INTO City VALUES (2395,'Sachon','KOR','Kyongsangnam',113494);
+INSERT INTO City VALUES (2396,'Uiwang','KOR','Kyonggi',108788);
+INSERT INTO City VALUES (2397,'Naju','KOR','Chollanam',107831);
+INSERT INTO City VALUES (2398,'Namwon','KOR','Chollabuk',103544);
+INSERT INTO City VALUES (2399,'Tonghae','KOR','Kang-won',95472);
+INSERT INTO City VALUES (2400,'Mun-gyong','KOR','Kyongsangbuk',92239);
+INSERT INTO City VALUES (2401,'Athenai','GRC','Attika',772072);
+INSERT INTO City VALUES (2402,'Thessaloniki','GRC','Central Macedonia',383967);
+INSERT INTO City VALUES (2403,'Pireus','GRC','Attika',182671);
+INSERT INTO City VALUES (2404,'Patras','GRC','West Greece',153344);
+INSERT INTO City VALUES (2405,'Peristerion','GRC','Attika',137288);
+INSERT INTO City VALUES (2406,'Herakleion','GRC','Crete',116178);
+INSERT INTO City VALUES (2407,'Kallithea','GRC','Attika',114233);
+INSERT INTO City VALUES (2408,'Larisa','GRC','Thessalia',113090);
+INSERT INTO City VALUES (2409,'Zagreb','HRV','Grad Zagreb',706770);
+INSERT INTO City VALUES (2410,'Split','HRV','Split-Dalmatia',189388);
+INSERT INTO City VALUES (2411,'Rijeka','HRV','Primorje-Gorski Kota',167964);
+INSERT INTO City VALUES (2412,'Osijek','HRV','Osijek-Baranja',104761);
+INSERT INTO City VALUES (2413,'La Habana','CUB','La Habana',2256000);
+INSERT INTO City VALUES (2414,'Santiago de Cuba','CUB','Santiago de Cuba',433180);
+INSERT INTO City VALUES (2415,'Camagüey','CUB','Camagüey',298726);
+INSERT INTO City VALUES (2416,'Holguín','CUB','Holguín',249492);
+INSERT INTO City VALUES (2417,'Santa Clara','CUB','Villa Clara',207350);
+INSERT INTO City VALUES (2418,'Guantánamo','CUB','Guantánamo',205078);
+INSERT INTO City VALUES (2419,'Pinar del Río','CUB','Pinar del Río',142100);
+INSERT INTO City VALUES (2420,'Bayamo','CUB','Granma',141000);
+INSERT INTO City VALUES (2421,'Cienfuegos','CUB','Cienfuegos',132770);
+INSERT INTO City VALUES (2422,'Victoria de las Tunas','CUB','Las Tunas',132350);
+INSERT INTO City VALUES (2423,'Matanzas','CUB','Matanzas',123273);
+INSERT INTO City VALUES (2424,'Manzanillo','CUB','Granma',109350);
+INSERT INTO City VALUES (2425,'Sancti-Spíritus','CUB','Sancti-Spíritus',100751);
+INSERT INTO City VALUES (2426,'Ciego de Ávila','CUB','Ciego de Ávila',98505);
+INSERT INTO City VALUES (2427,'al-Salimiya','KWT','Hawalli',130215);
+INSERT INTO City VALUES (2428,'Jalib al-Shuyukh','KWT','Hawalli',102178);
+INSERT INTO City VALUES (2429,'Kuwait','KWT','al-Asima',28859);
+INSERT INTO City VALUES (2430,'Nicosia','CYP','Nicosia',195000);
+INSERT INTO City VALUES (2431,'Limassol','CYP','Limassol',154400);
+INSERT INTO City VALUES (2432,'Vientiane','LAO','Viangchan',531800);
+INSERT INTO City VALUES (2433,'Savannakhet','LAO','Savannakhet',96652);
+INSERT INTO City VALUES (2434,'Riga','LVA','Riika',764328);
+INSERT INTO City VALUES (2435,'Daugavpils','LVA','Daugavpils',114829);
+INSERT INTO City VALUES (2436,'Liepaja','LVA','Liepaja',89439);
+INSERT INTO City VALUES (2437,'Maseru','LSO','Maseru',297000);
+INSERT INTO City VALUES (2438,'Beirut','LBN','Beirut',1100000);
+INSERT INTO City VALUES (2439,'Tripoli','LBN','al-Shamal',240000);
+INSERT INTO City VALUES (2440,'Monrovia','LBR','Montserrado',850000);
+INSERT INTO City VALUES (2441,'Tripoli','LBY','Tripoli',1682000);
+INSERT INTO City VALUES (2442,'Bengasi','LBY','Bengasi',804000);
+INSERT INTO City VALUES (2443,'Misrata','LBY','Misrata',121669);
+INSERT INTO City VALUES (2444,'al-Zawiya','LBY','al-Zawiya',89338);
+INSERT INTO City VALUES (2445,'Schaan','LIE','Schaan',5346);
+INSERT INTO City VALUES (2446,'Vaduz','LIE','Vaduz',5043);
+INSERT INTO City VALUES (2447,'Vilnius','LTU','Vilna',577969);
+INSERT INTO City VALUES (2448,'Kaunas','LTU','Kaunas',412639);
+INSERT INTO City VALUES (2449,'Klaipeda','LTU','Klaipeda',202451);
+INSERT INTO City VALUES (2450,'Šiauliai','LTU','Šiauliai',146563);
+INSERT INTO City VALUES (2451,'Panevezys','LTU','Panevezys',133695);
+INSERT INTO City VALUES (2452,'Luxembourg [Luxemburg/Lëtzebuerg]','LUX','Luxembourg',80700);
+INSERT INTO City VALUES (2453,'El-Aaiún','ESH','El-Aaiún',169000);
+INSERT INTO City VALUES (2454,'Macao','MAC','Macau',437500);
+INSERT INTO City VALUES (2455,'Antananarivo','MDG','Antananarivo',675669);
+INSERT INTO City VALUES (2456,'Toamasina','MDG','Toamasina',127441);
+INSERT INTO City VALUES (2457,'Antsirabé','MDG','Antananarivo',120239);
+INSERT INTO City VALUES (2458,'Mahajanga','MDG','Mahajanga',100807);
+INSERT INTO City VALUES (2459,'Fianarantsoa','MDG','Fianarantsoa',99005);
+INSERT INTO City VALUES (2460,'Skopje','MKD','Skopje',444299);
+INSERT INTO City VALUES (2461,'Blantyre','MWI','Blantyre',478155);
+INSERT INTO City VALUES (2462,'Lilongwe','MWI','Lilongwe',435964);
+INSERT INTO City VALUES (2463,'Male','MDV','Maale',71000);
+INSERT INTO City VALUES (2464,'Kuala Lumpur','MYS','Wilayah Persekutuan',1297526);
+INSERT INTO City VALUES (2465,'Ipoh','MYS','Perak',382853);
+INSERT INTO City VALUES (2466,'Johor Baharu','MYS','Johor',328436);
+INSERT INTO City VALUES (2467,'Petaling Jaya','MYS','Selangor',254350);
+INSERT INTO City VALUES (2468,'Kelang','MYS','Selangor',243355);
+INSERT INTO City VALUES (2469,'Kuala Terengganu','MYS','Terengganu',228119);
+INSERT INTO City VALUES (2470,'Pinang','MYS','Pulau Pinang',219603);
+INSERT INTO City VALUES (2471,'Kota Bharu','MYS','Kelantan',219582);
+INSERT INTO City VALUES (2472,'Kuantan','MYS','Pahang',199484);
+INSERT INTO City VALUES (2473,'Taiping','MYS','Perak',183261);
+INSERT INTO City VALUES (2474,'Seremban','MYS','Negeri Sembilan',182869);
+INSERT INTO City VALUES (2475,'Kuching','MYS','Sarawak',148059);
+INSERT INTO City VALUES (2476,'Sibu','MYS','Sarawak',126381);
+INSERT INTO City VALUES (2477,'Sandakan','MYS','Sabah',125841);
+INSERT INTO City VALUES (2478,'Alor Setar','MYS','Kedah',124412);
+INSERT INTO City VALUES (2479,'Selayang Baru','MYS','Selangor',124228);
+INSERT INTO City VALUES (2480,'Sungai Petani','MYS','Kedah',114763);
+INSERT INTO City VALUES (2481,'Shah Alam','MYS','Selangor',102019);
+INSERT INTO City VALUES (2482,'Bamako','MLI','Bamako',809552);
+INSERT INTO City VALUES (2483,'Birkirkara','MLT','Outer Harbour',21445);
+INSERT INTO City VALUES (2484,'Valletta','MLT','Inner Harbour',7073);
+INSERT INTO City VALUES (2485,'Casablanca','MAR','Casablanca',2940623);
+INSERT INTO City VALUES (2486,'Rabat','MAR','Rabat-Salé-Zammour-Z',623457);
+INSERT INTO City VALUES (2487,'Marrakech','MAR','Marrakech-Tensift-Al',621914);
+INSERT INTO City VALUES (2488,'Fès','MAR','Fès-Boulemane',541162);
+INSERT INTO City VALUES (2489,'Tanger','MAR','Tanger-Tétouan',521735);
+INSERT INTO City VALUES (2490,'Salé','MAR','Rabat-Salé-Zammour-Z',504420);
+INSERT INTO City VALUES (2491,'Meknès','MAR','Meknès-Tafilalet',460000);
+INSERT INTO City VALUES (2492,'Oujda','MAR','Oriental',365382);
+INSERT INTO City VALUES (2493,'Kénitra','MAR','Gharb-Chrarda-Béni H',292600);
+INSERT INTO City VALUES (2494,'Tétouan','MAR','Tanger-Tétouan',277516);
+INSERT INTO City VALUES (2495,'Safi','MAR','Doukkala-Abda',262300);
+INSERT INTO City VALUES (2496,'Agadir','MAR','Souss Massa-Draâ',155244);
+INSERT INTO City VALUES (2497,'Mohammedia','MAR','Casablanca',154706);
+INSERT INTO City VALUES (2498,'Khouribga','MAR','Chaouia-Ouardigha',152090);
+INSERT INTO City VALUES (2499,'Beni-Mellal','MAR','Tadla-Azilal',140212);
+INSERT INTO City VALUES (2500,'Témara','MAR','Rabat-Salé-Zammour-Z',126303);
+INSERT INTO City VALUES (2501,'El Jadida','MAR','Doukkala-Abda',119083);
+INSERT INTO City VALUES (2502,'Nador','MAR','Oriental',112450);
+INSERT INTO City VALUES (2503,'Ksar el Kebir','MAR','Tanger-Tétouan',107065);
+INSERT INTO City VALUES (2504,'Settat','MAR','Chaouia-Ouardigha',96200);
+INSERT INTO City VALUES (2505,'Taza','MAR','Taza-Al Hoceima-Taou',92700);
+INSERT INTO City VALUES (2506,'El Araich','MAR','Tanger-Tétouan',90400);
+INSERT INTO City VALUES (2507,'Dalap-Uliga-Darrit','MHL','Majuro',28000);
+INSERT INTO City VALUES (2508,'Fort-de-France','MTQ','Fort-de-France',94050);
+INSERT INTO City VALUES (2509,'Nouakchott','MRT','Nouakchott',667300);
+INSERT INTO City VALUES (2510,'Nouâdhibou','MRT','Dakhlet Nouâdhibou',97600);
+INSERT INTO City VALUES (2511,'Port-Louis','MUS','Port-Louis',138200);
+INSERT INTO City VALUES (2512,'Beau Bassin-Rose Hill','MUS','Plaines Wilhelms',100616);
+INSERT INTO City VALUES (2513,'Vacoas-Phoenix','MUS','Plaines Wilhelms',98464);
+INSERT INTO City VALUES (2514,'Mamoutzou','MYT','Mamoutzou',12000);
+INSERT INTO City VALUES (2515,'Ciudad de México','MEX','Distrito Federal',8591309);
+INSERT INTO City VALUES (2516,'Guadalajara','MEX','Jalisco',1647720);
+INSERT INTO City VALUES (2517,'Ecatepec de Morelos','MEX','México',1620303);
+INSERT INTO City VALUES (2518,'Puebla','MEX','Puebla',1346176);
+INSERT INTO City VALUES (2519,'Nezahualcóyotl','MEX','México',1224924);
+INSERT INTO City VALUES (2520,'Juárez','MEX','Chihuahua',1217818);
+INSERT INTO City VALUES (2521,'Tijuana','MEX','Baja California',1212232);
+INSERT INTO City VALUES (2522,'León','MEX','Guanajuato',1133576);
+INSERT INTO City VALUES (2523,'Monterrey','MEX','Nuevo León',1108499);
+INSERT INTO City VALUES (2524,'Zapopan','MEX','Jalisco',1002239);
+INSERT INTO City VALUES (2525,'Naucalpan de Juárez','MEX','México',857511);
+INSERT INTO City VALUES (2526,'Mexicali','MEX','Baja California',764902);
+INSERT INTO City VALUES (2527,'Culiacán','MEX','Sinaloa',744859);
+INSERT INTO City VALUES (2528,'Acapulco de Juárez','MEX','Guerrero',721011);
+INSERT INTO City VALUES (2529,'Tlalnepantla de Baz','MEX','México',720755);
+INSERT INTO City VALUES (2530,'Mérida','MEX','Yucatán',703324);
+INSERT INTO City VALUES (2531,'Chihuahua','MEX','Chihuahua',670208);
+INSERT INTO City VALUES (2532,'San Luis Potosí','MEX','San Luis Potosí',669353);
+INSERT INTO City VALUES (2533,'Guadalupe','MEX','Nuevo León',668780);
+INSERT INTO City VALUES (2534,'Toluca','MEX','México',665617);
+INSERT INTO City VALUES (2535,'Aguascalientes','MEX','Aguascalientes',643360);
+INSERT INTO City VALUES (2536,'Querétaro','MEX','Querétaro de Arteaga',639839);
+INSERT INTO City VALUES (2537,'Morelia','MEX','Michoacán de Ocampo',619958);
+INSERT INTO City VALUES (2538,'Hermosillo','MEX','Sonora',608697);
+INSERT INTO City VALUES (2539,'Saltillo','MEX','Coahuila de Zaragoza',577352);
+INSERT INTO City VALUES (2540,'Torreón','MEX','Coahuila de Zaragoza',529093);
+INSERT INTO City VALUES (2541,'Centro (Villahermosa)','MEX','Tabasco',519873);
+INSERT INTO City VALUES (2542,'San Nicolás de los Garza','MEX','Nuevo León',495540);
+INSERT INTO City VALUES (2543,'Durango','MEX','Durango',490524);
+INSERT INTO City VALUES (2544,'Chimalhuacán','MEX','México',490245);
+INSERT INTO City VALUES (2545,'Tlaquepaque','MEX','Jalisco',475472);
+INSERT INTO City VALUES (2546,'Atizapán de Zaragoza','MEX','México',467262);
+INSERT INTO City VALUES (2547,'Veracruz','MEX','Veracruz',457119);
+INSERT INTO City VALUES (2548,'Cuautitlán Izcalli','MEX','México',452976);
+INSERT INTO City VALUES (2549,'Irapuato','MEX','Guanajuato',440039);
+INSERT INTO City VALUES (2550,'Tuxtla Gutiérrez','MEX','Chiapas',433544);
+INSERT INTO City VALUES (2551,'Tultitlán','MEX','México',432411);
+INSERT INTO City VALUES (2552,'Reynosa','MEX','Tamaulipas',419776);
+INSERT INTO City VALUES (2553,'Benito Juárez','MEX','Quintana Roo',419276);
+INSERT INTO City VALUES (2554,'Matamoros','MEX','Tamaulipas',416428);
+INSERT INTO City VALUES (2555,'Xalapa','MEX','Veracruz',390058);
+INSERT INTO City VALUES (2556,'Celaya','MEX','Guanajuato',382140);
+INSERT INTO City VALUES (2557,'Mazatlán','MEX','Sinaloa',380265);
+INSERT INTO City VALUES (2558,'Ensenada','MEX','Baja California',369573);
+INSERT INTO City VALUES (2559,'Ahome','MEX','Sinaloa',358663);
+INSERT INTO City VALUES (2560,'Cajeme','MEX','Sonora',355679);
+INSERT INTO City VALUES (2561,'Cuernavaca','MEX','Morelos',337966);
+INSERT INTO City VALUES (2562,'Tonalá','MEX','Jalisco',336109);
+INSERT INTO City VALUES (2563,'Valle de Chalco Solidaridad','MEX','México',323113);
+INSERT INTO City VALUES (2564,'Nuevo Laredo','MEX','Tamaulipas',310277);
+INSERT INTO City VALUES (2565,'Tepic','MEX','Nayarit',305025);
+INSERT INTO City VALUES (2566,'Tampico','MEX','Tamaulipas',294789);
+INSERT INTO City VALUES (2567,'Ixtapaluca','MEX','México',293160);
+INSERT INTO City VALUES (2568,'Apodaca','MEX','Nuevo León',282941);
+INSERT INTO City VALUES (2569,'Guasave','MEX','Sinaloa',277201);
+INSERT INTO City VALUES (2570,'Gómez Palacio','MEX','Durango',272806);
+INSERT INTO City VALUES (2571,'Tapachula','MEX','Chiapas',271141);
+INSERT INTO City VALUES (2572,'Nicolás Romero','MEX','México',269393);
+INSERT INTO City VALUES (2573,'Coatzacoalcos','MEX','Veracruz',267037);
+INSERT INTO City VALUES (2574,'Uruapan','MEX','Michoacán de Ocampo',265211);
+INSERT INTO City VALUES (2575,'Victoria','MEX','Tamaulipas',262686);
+INSERT INTO City VALUES (2576,'Oaxaca de Juárez','MEX','Oaxaca',256848);
+INSERT INTO City VALUES (2577,'Coacalco de Berriozábal','MEX','México',252270);
+INSERT INTO City VALUES (2578,'Pachuca de Soto','MEX','Hidalgo',244688);
+INSERT INTO City VALUES (2579,'General Escobedo','MEX','Nuevo León',232961);
+INSERT INTO City VALUES (2580,'Salamanca','MEX','Guanajuato',226864);
+INSERT INTO City VALUES (2581,'Santa Catarina','MEX','Nuevo León',226573);
+INSERT INTO City VALUES (2582,'Tehuacán','MEX','Puebla',225943);
+INSERT INTO City VALUES (2583,'Chalco','MEX','México',222201);
+INSERT INTO City VALUES (2584,'Cárdenas','MEX','Tabasco',216903);
+INSERT INTO City VALUES (2585,'Campeche','MEX','Campeche',216735);
+INSERT INTO City VALUES (2586,'La Paz','MEX','México',213045);
+INSERT INTO City VALUES (2587,'Othón P. Blanco (Chetumal)','MEX','Quintana Roo',208014);
+INSERT INTO City VALUES (2588,'Texcoco','MEX','México',203681);
+INSERT INTO City VALUES (2589,'La Paz','MEX','Baja California Sur',196708);
+INSERT INTO City VALUES (2590,'Metepec','MEX','México',194265);
+INSERT INTO City VALUES (2591,'Monclova','MEX','Coahuila de Zaragoza',193657);
+INSERT INTO City VALUES (2592,'Huixquilucan','MEX','México',193156);
+INSERT INTO City VALUES (2593,'Chilpancingo de los Bravo','MEX','Guerrero',192509);
+INSERT INTO City VALUES (2594,'Puerto Vallarta','MEX','Jalisco',183741);
+INSERT INTO City VALUES (2595,'Fresnillo','MEX','Zacatecas',182744);
+INSERT INTO City VALUES (2596,'Ciudad Madero','MEX','Tamaulipas',182012);
+INSERT INTO City VALUES (2597,'Soledad de Graciano Sánchez','MEX','San Luis Potosí',179956);
+INSERT INTO City VALUES (2598,'San Juan del Río','MEX','Querétaro',179300);
+INSERT INTO City VALUES (2599,'San Felipe del Progreso','MEX','México',177330);
+INSERT INTO City VALUES (2600,'Córdoba','MEX','Veracruz',176952);
+INSERT INTO City VALUES (2601,'Tecámac','MEX','México',172410);
+INSERT INTO City VALUES (2602,'Ocosingo','MEX','Chiapas',171495);
+INSERT INTO City VALUES (2603,'Carmen','MEX','Campeche',171367);
+INSERT INTO City VALUES (2604,'Lázaro Cárdenas','MEX','Michoacán de Ocampo',170878);
+INSERT INTO City VALUES (2605,'Jiutepec','MEX','Morelos',170428);
+INSERT INTO City VALUES (2606,'Papantla','MEX','Veracruz',170123);
+INSERT INTO City VALUES (2607,'Comalcalco','MEX','Tabasco',164640);
+INSERT INTO City VALUES (2608,'Zamora','MEX','Michoacán de Ocampo',161191);
+INSERT INTO City VALUES (2609,'Nogales','MEX','Sonora',159103);
+INSERT INTO City VALUES (2610,'Huimanguillo','MEX','Tabasco',158335);
+INSERT INTO City VALUES (2611,'Cuautla','MEX','Morelos',153132);
+INSERT INTO City VALUES (2612,'Minatitlán','MEX','Veracruz',152983);
+INSERT INTO City VALUES (2613,'Poza Rica de Hidalgo','MEX','Veracruz',152678);
+INSERT INTO City VALUES (2614,'Ciudad Valles','MEX','San Luis Potosí',146411);
+INSERT INTO City VALUES (2615,'Navolato','MEX','Sinaloa',145396);
+INSERT INTO City VALUES (2616,'San Luis Río Colorado','MEX','Sonora',145276);
+INSERT INTO City VALUES (2617,'Pénjamo','MEX','Guanajuato',143927);
+INSERT INTO City VALUES (2618,'San Andrés Tuxtla','MEX','Veracruz',142251);
+INSERT INTO City VALUES (2619,'Guanajuato','MEX','Guanajuato',141215);
+INSERT INTO City VALUES (2620,'Navojoa','MEX','Sonora',140495);
+INSERT INTO City VALUES (2621,'Zitácuaro','MEX','Michoacán de Ocampo',137970);
+INSERT INTO City VALUES (2622,'Boca del Río','MEX','Veracruz-Llave',135721);
+INSERT INTO City VALUES (2623,'Allende','MEX','Guanajuato',134645);
+INSERT INTO City VALUES (2624,'Silao','MEX','Guanajuato',134037);
+INSERT INTO City VALUES (2625,'Macuspana','MEX','Tabasco',133795);
+INSERT INTO City VALUES (2626,'San Juan Bautista Tuxtepec','MEX','Oaxaca',133675);
+INSERT INTO City VALUES (2627,'San Cristóbal de las Casas','MEX','Chiapas',132317);
+INSERT INTO City VALUES (2628,'Valle de Santiago','MEX','Guanajuato',130557);
+INSERT INTO City VALUES (2629,'Guaymas','MEX','Sonora',130108);
+INSERT INTO City VALUES (2630,'Colima','MEX','Colima',129454);
+INSERT INTO City VALUES (2631,'Dolores Hidalgo','MEX','Guanajuato',128675);
+INSERT INTO City VALUES (2632,'Lagos de Moreno','MEX','Jalisco',127949);
+INSERT INTO City VALUES (2633,'Piedras Negras','MEX','Coahuila de Zaragoza',127898);
+INSERT INTO City VALUES (2634,'Altamira','MEX','Tamaulipas',127490);
+INSERT INTO City VALUES (2635,'Túxpam','MEX','Veracruz',126475);
+INSERT INTO City VALUES (2636,'San Pedro Garza García','MEX','Nuevo León',126147);
+INSERT INTO City VALUES (2637,'Cuauhtémoc','MEX','Chihuahua',124279);
+INSERT INTO City VALUES (2638,'Manzanillo','MEX','Colima',124014);
+INSERT INTO City VALUES (2639,'Iguala de la Independencia','MEX','Guerrero',123883);
+INSERT INTO City VALUES (2640,'Zacatecas','MEX','Zacatecas',123700);
+INSERT INTO City VALUES (2641,'Tlajomulco de Zúñiga','MEX','Jalisco',123220);
+INSERT INTO City VALUES (2642,'Tulancingo de Bravo','MEX','Hidalgo',121946);
+INSERT INTO City VALUES (2643,'Zinacantepec','MEX','México',121715);
+INSERT INTO City VALUES (2644,'San Martín Texmelucan','MEX','Puebla',121093);
+INSERT INTO City VALUES (2645,'Tepatitlán de Morelos','MEX','Jalisco',118948);
+INSERT INTO City VALUES (2646,'Martínez de la Torre','MEX','Veracruz',118815);
+INSERT INTO City VALUES (2647,'Orizaba','MEX','Veracruz',118488);
+INSERT INTO City VALUES (2648,'Apatzingán','MEX','Michoacán de Ocampo',117849);
+INSERT INTO City VALUES (2649,'Atlixco','MEX','Puebla',117019);
+INSERT INTO City VALUES (2650,'Delicias','MEX','Chihuahua',116132);
+INSERT INTO City VALUES (2651,'Ixtlahuaca','MEX','México',115548);
+INSERT INTO City VALUES (2652,'El Mante','MEX','Tamaulipas',112453);
+INSERT INTO City VALUES (2653,'Lerdo','MEX','Durango',112272);
+INSERT INTO City VALUES (2654,'Almoloya de Juárez','MEX','México',110550);
+INSERT INTO City VALUES (2655,'Acámbaro','MEX','Guanajuato',110487);
+INSERT INTO City VALUES (2656,'Acuña','MEX','Coahuila de Zaragoza',110388);
+INSERT INTO City VALUES (2657,'Guadalupe','MEX','Zacatecas',108881);
+INSERT INTO City VALUES (2658,'Huejutla de Reyes','MEX','Hidalgo',108017);
+INSERT INTO City VALUES (2659,'Hidalgo','MEX','Michoacán de Ocampo',106198);
+INSERT INTO City VALUES (2660,'Los Cabos','MEX','Baja California Sur',105199);
+INSERT INTO City VALUES (2661,'Comitán de Domínguez','MEX','Chiapas',104986);
+INSERT INTO City VALUES (2662,'Cunduacán','MEX','Tabasco',104164);
+INSERT INTO City VALUES (2663,'Río Bravo','MEX','Tamaulipas',103901);
+INSERT INTO City VALUES (2664,'Temapache','MEX','Veracruz',102824);
+INSERT INTO City VALUES (2665,'Chilapa de Alvarez','MEX','Guerrero',102716);
+INSERT INTO City VALUES (2666,'Hidalgo del Parral','MEX','Chihuahua',100881);
+INSERT INTO City VALUES (2667,'San Francisco del Rincón','MEX','Guanajuato',100149);
+INSERT INTO City VALUES (2668,'Taxco de Alarcón','MEX','Guerrero',99907);
+INSERT INTO City VALUES (2669,'Zumpango','MEX','México',99781);
+INSERT INTO City VALUES (2670,'San Pedro Cholula','MEX','Puebla',99734);
+INSERT INTO City VALUES (2671,'Lerma','MEX','México',99714);
+INSERT INTO City VALUES (2672,'Tecomán','MEX','Colima',99296);
+INSERT INTO City VALUES (2673,'Las Margaritas','MEX','Chiapas',97389);
+INSERT INTO City VALUES (2674,'Cosoleacaque','MEX','Veracruz',97199);
+INSERT INTO City VALUES (2675,'San Luis de la Paz','MEX','Guanajuato',96763);
+INSERT INTO City VALUES (2676,'José Azueta','MEX','Guerrero',95448);
+INSERT INTO City VALUES (2677,'Santiago Ixcuintla','MEX','Nayarit',95311);
+INSERT INTO City VALUES (2678,'San Felipe','MEX','Guanajuato',95305);
+INSERT INTO City VALUES (2679,'Tejupilco','MEX','México',94934);
+INSERT INTO City VALUES (2680,'Tantoyuca','MEX','Veracruz',94709);
+INSERT INTO City VALUES (2681,'Salvatierra','MEX','Guanajuato',94322);
+INSERT INTO City VALUES (2682,'Tultepec','MEX','México',93364);
+INSERT INTO City VALUES (2683,'Temixco','MEX','Morelos',92686);
+INSERT INTO City VALUES (2684,'Matamoros','MEX','Coahuila de Zaragoza',91858);
+INSERT INTO City VALUES (2685,'Pánuco','MEX','Veracruz',90551);
+INSERT INTO City VALUES (2686,'El Fuerte','MEX','Sinaloa',89556);
+INSERT INTO City VALUES (2687,'Tierra Blanca','MEX','Veracruz',89143);
+INSERT INTO City VALUES (2688,'Weno','FSM','Chuuk',22000);
+INSERT INTO City VALUES (2689,'Palikir','FSM','Pohnpei',8600);
+INSERT INTO City VALUES (2690,'Chisinau','MDA','Chisinau',719900);
+INSERT INTO City VALUES (2691,'Tiraspol','MDA','Dnjestria',194300);
+INSERT INTO City VALUES (2692,'Balti','MDA','Balti',153400);
+INSERT INTO City VALUES (2693,'Bender (Tîghina)','MDA','Bender (Tîghina)',125700);
+INSERT INTO City VALUES (2694,'Monte-Carlo','MCO','–',13154);
+INSERT INTO City VALUES (2695,'Monaco-Ville','MCO','–',1234);
+INSERT INTO City VALUES (2696,'Ulan Bator','MNG','Ulaanbaatar',773700);
+INSERT INTO City VALUES (2697,'Plymouth','MSR','Plymouth',2000);
+INSERT INTO City VALUES (2698,'Maputo','MOZ','Maputo',1018938);
+INSERT INTO City VALUES (2699,'Matola','MOZ','Maputo',424662);
+INSERT INTO City VALUES (2700,'Beira','MOZ','Sofala',397368);
+INSERT INTO City VALUES (2701,'Nampula','MOZ','Nampula',303346);
+INSERT INTO City VALUES (2702,'Chimoio','MOZ','Manica',171056);
+INSERT INTO City VALUES (2703,'Naçala-Porto','MOZ','Nampula',158248);
+INSERT INTO City VALUES (2704,'Quelimane','MOZ','Zambézia',150116);
+INSERT INTO City VALUES (2705,'Mocuba','MOZ','Zambézia',124700);
+INSERT INTO City VALUES (2706,'Tete','MOZ','Tete',101984);
+INSERT INTO City VALUES (2707,'Xai-Xai','MOZ','Gaza',99442);
+INSERT INTO City VALUES (2708,'Gurue','MOZ','Zambézia',99300);
+INSERT INTO City VALUES (2709,'Maxixe','MOZ','Inhambane',93985);
+INSERT INTO City VALUES (2710,'Rangoon (Yangon)','MMR','Rangoon [Yangon]',3361700);
+INSERT INTO City VALUES (2711,'Mandalay','MMR','Mandalay',885300);
+INSERT INTO City VALUES (2712,'Moulmein (Mawlamyine)','MMR','Mon',307900);
+INSERT INTO City VALUES (2713,'Pegu (Bago)','MMR','Pegu [Bago]',190900);
+INSERT INTO City VALUES (2714,'Bassein (Pathein)','MMR','Irrawaddy [Ayeyarwad',183900);
+INSERT INTO City VALUES (2715,'Monywa','MMR','Sagaing',138600);
+INSERT INTO City VALUES (2716,'Sittwe (Akyab)','MMR','Rakhine',137600);
+INSERT INTO City VALUES (2717,'Taunggyi (Taunggye)','MMR','Shan',131500);
+INSERT INTO City VALUES (2718,'Meikhtila','MMR','Mandalay',129700);
+INSERT INTO City VALUES (2719,'Mergui (Myeik)','MMR','Tenasserim [Tanintha',122700);
+INSERT INTO City VALUES (2720,'Lashio (Lasho)','MMR','Shan',107600);
+INSERT INTO City VALUES (2721,'Prome (Pyay)','MMR','Pegu [Bago]',105700);
+INSERT INTO City VALUES (2722,'Henzada (Hinthada)','MMR','Irrawaddy [Ayeyarwad',104700);
+INSERT INTO City VALUES (2723,'Myingyan','MMR','Mandalay',103600);
+INSERT INTO City VALUES (2724,'Tavoy (Dawei)','MMR','Tenasserim [Tanintha',96800);
+INSERT INTO City VALUES (2725,'Pagakku (Pakokku)','MMR','Magwe [Magway]',94800);
+INSERT INTO City VALUES (2726,'Windhoek','NAM','Khomas',169000);
+INSERT INTO City VALUES (2727,'Yangor','NRU','–',4050);
+INSERT INTO City VALUES (2728,'Yaren','NRU','–',559);
+INSERT INTO City VALUES (2729,'Kathmandu','NPL','Central',591835);
+INSERT INTO City VALUES (2730,'Biratnagar','NPL','Eastern',157764);
+INSERT INTO City VALUES (2731,'Pokhara','NPL','Western',146318);
+INSERT INTO City VALUES (2732,'Lalitapur','NPL','Central',145847);
+INSERT INTO City VALUES (2733,'Birgunj','NPL','Central',90639);
+INSERT INTO City VALUES (2734,'Managua','NIC','Managua',959000);
+INSERT INTO City VALUES (2735,'León','NIC','León',123865);
+INSERT INTO City VALUES (2736,'Chinandega','NIC','Chinandega',97387);
+INSERT INTO City VALUES (2737,'Masaya','NIC','Masaya',88971);
+INSERT INTO City VALUES (2738,'Niamey','NER','Niamey',420000);
+INSERT INTO City VALUES (2739,'Zinder','NER','Zinder',120892);
+INSERT INTO City VALUES (2740,'Maradi','NER','Maradi',112965);
+INSERT INTO City VALUES (2741,'Lagos','NGA','Lagos',1518000);
+INSERT INTO City VALUES (2742,'Ibadan','NGA','Oyo & Osun',1432000);
+INSERT INTO City VALUES (2743,'Ogbomosho','NGA','Oyo & Osun',730000);
+INSERT INTO City VALUES (2744,'Kano','NGA','Kano & Jigawa',674100);
+INSERT INTO City VALUES (2745,'Oshogbo','NGA','Oyo & Osun',476800);
+INSERT INTO City VALUES (2746,'Ilorin','NGA','Kwara & Kogi',475800);
+INSERT INTO City VALUES (2747,'Abeokuta','NGA','Ogun',427400);
+INSERT INTO City VALUES (2748,'Port Harcourt','NGA','Rivers & Bayelsa',410000);
+INSERT INTO City VALUES (2749,'Zaria','NGA','Kaduna',379200);
+INSERT INTO City VALUES (2750,'Ilesha','NGA','Oyo & Osun',378400);
+INSERT INTO City VALUES (2751,'Onitsha','NGA','Anambra & Enugu & Eb',371900);
+INSERT INTO City VALUES (2752,'Iwo','NGA','Oyo & Osun',362000);
+INSERT INTO City VALUES (2753,'Ado-Ekiti','NGA','Ondo & Ekiti',359400);
+INSERT INTO City VALUES (2754,'Abuja','NGA','Federal Capital Dist',350100);
+INSERT INTO City VALUES (2755,'Kaduna','NGA','Kaduna',342200);
+INSERT INTO City VALUES (2756,'Mushin','NGA','Lagos',333200);
+INSERT INTO City VALUES (2757,'Maiduguri','NGA','Borno & Yobe',320000);
+INSERT INTO City VALUES (2758,'Enugu','NGA','Anambra & Enugu & Eb',316100);
+INSERT INTO City VALUES (2759,'Ede','NGA','Oyo & Osun',307100);
+INSERT INTO City VALUES (2760,'Aba','NGA','Imo & Abia',298900);
+INSERT INTO City VALUES (2761,'Ife','NGA','Oyo & Osun',296800);
+INSERT INTO City VALUES (2762,'Ila','NGA','Oyo & Osun',264000);
+INSERT INTO City VALUES (2763,'Oyo','NGA','Oyo & Osun',256400);
+INSERT INTO City VALUES (2764,'Ikerre','NGA','Ondo & Ekiti',244600);
+INSERT INTO City VALUES (2765,'Benin City','NGA','Edo & Delta',229400);
+INSERT INTO City VALUES (2766,'Iseyin','NGA','Oyo & Osun',217300);
+INSERT INTO City VALUES (2767,'Katsina','NGA','Katsina',206500);
+INSERT INTO City VALUES (2768,'Jos','NGA','Plateau & Nassarawa',206300);
+INSERT INTO City VALUES (2769,'Sokoto','NGA','Sokoto & Kebbi & Zam',204900);
+INSERT INTO City VALUES (2770,'Ilobu','NGA','Oyo & Osun',199000);
+INSERT INTO City VALUES (2771,'Offa','NGA','Kwara & Kogi',197200);
+INSERT INTO City VALUES (2772,'Ikorodu','NGA','Lagos',184900);
+INSERT INTO City VALUES (2773,'Ilawe-Ekiti','NGA','Ondo & Ekiti',184500);
+INSERT INTO City VALUES (2774,'Owo','NGA','Ondo & Ekiti',183500);
+INSERT INTO City VALUES (2775,'Ikirun','NGA','Oyo & Osun',181400);
+INSERT INTO City VALUES (2776,'Shaki','NGA','Oyo & Osun',174500);
+INSERT INTO City VALUES (2777,'Calabar','NGA','Cross River',174400);
+INSERT INTO City VALUES (2778,'Ondo','NGA','Ondo & Ekiti',173600);
+INSERT INTO City VALUES (2779,'Akure','NGA','Ondo & Ekiti',162300);
+INSERT INTO City VALUES (2780,'Gusau','NGA','Sokoto & Kebbi & Zam',158000);
+INSERT INTO City VALUES (2781,'Ijebu-Ode','NGA','Ogun',156400);
+INSERT INTO City VALUES (2782,'Effon-Alaiye','NGA','Oyo & Osun',153100);
+INSERT INTO City VALUES (2783,'Kumo','NGA','Bauchi & Gombe',148000);
+INSERT INTO City VALUES (2784,'Shomolu','NGA','Lagos',147700);
+INSERT INTO City VALUES (2785,'Oka-Akoko','NGA','Ondo & Ekiti',142900);
+INSERT INTO City VALUES (2786,'Ikare','NGA','Ondo & Ekiti',140800);
+INSERT INTO City VALUES (2787,'Sapele','NGA','Edo & Delta',139200);
+INSERT INTO City VALUES (2788,'Deba Habe','NGA','Bauchi & Gombe',138600);
+INSERT INTO City VALUES (2789,'Minna','NGA','Niger',136900);
+INSERT INTO City VALUES (2790,'Warri','NGA','Edo & Delta',126100);
+INSERT INTO City VALUES (2791,'Bida','NGA','Niger',125500);
+INSERT INTO City VALUES (2792,'Ikire','NGA','Oyo & Osun',123300);
+INSERT INTO City VALUES (2793,'Makurdi','NGA','Benue',123100);
+INSERT INTO City VALUES (2794,'Lafia','NGA','Plateau & Nassarawa',122500);
+INSERT INTO City VALUES (2795,'Inisa','NGA','Oyo & Osun',119800);
+INSERT INTO City VALUES (2796,'Shagamu','NGA','Ogun',117200);
+INSERT INTO City VALUES (2797,'Awka','NGA','Anambra & Enugu & Eb',111200);
+INSERT INTO City VALUES (2798,'Gombe','NGA','Bauchi & Gombe',107800);
+INSERT INTO City VALUES (2799,'Igboho','NGA','Oyo & Osun',106800);
+INSERT INTO City VALUES (2800,'Ejigbo','NGA','Oyo & Osun',105900);
+INSERT INTO City VALUES (2801,'Agege','NGA','Lagos',105000);
+INSERT INTO City VALUES (2802,'Ise-Ekiti','NGA','Ondo & Ekiti',103400);
+INSERT INTO City VALUES (2803,'Ugep','NGA','Cross River',102600);
+INSERT INTO City VALUES (2804,'Epe','NGA','Lagos',101000);
+INSERT INTO City VALUES (2805,'Alofi','NIU','–',682);
+INSERT INTO City VALUES (2806,'Kingston','NFK','–',800);
+INSERT INTO City VALUES (2807,'Oslo','NOR','Oslo',508726);
+INSERT INTO City VALUES (2808,'Bergen','NOR','Hordaland',230948);
+INSERT INTO City VALUES (2809,'Trondheim','NOR','Sør-Trøndelag',150166);
+INSERT INTO City VALUES (2810,'Stavanger','NOR','Rogaland',108848);
+INSERT INTO City VALUES (2811,'Bærum','NOR','Akershus',101340);
+INSERT INTO City VALUES (2812,'Abidjan','CIV','Abidjan',2500000);
+INSERT INTO City VALUES (2813,'Bouaké','CIV','Bouaké',329850);
+INSERT INTO City VALUES (2814,'Yamoussoukro','CIV','Yamoussoukro',130000);
+INSERT INTO City VALUES (2815,'Daloa','CIV','Daloa',121842);
+INSERT INTO City VALUES (2816,'Korhogo','CIV','Korhogo',109445);
+INSERT INTO City VALUES (2817,'al-Sib','OMN','Masqat',155000);
+INSERT INTO City VALUES (2818,'Salala','OMN','Zufar',131813);
+INSERT INTO City VALUES (2819,'Bawshar','OMN','Masqat',107500);
+INSERT INTO City VALUES (2820,'Suhar','OMN','al-Batina',90814);
+INSERT INTO City VALUES (2821,'Masqat','OMN','Masqat',51969);
+INSERT INTO City VALUES (2822,'Karachi','PAK','Sindh',9269265);
+INSERT INTO City VALUES (2823,'Lahore','PAK','Punjab',5063499);
+INSERT INTO City VALUES (2824,'Faisalabad','PAK','Punjab',1977246);
+INSERT INTO City VALUES (2825,'Rawalpindi','PAK','Punjab',1406214);
+INSERT INTO City VALUES (2826,'Multan','PAK','Punjab',1182441);
+INSERT INTO City VALUES (2827,'Hyderabad','PAK','Sindh',1151274);
+INSERT INTO City VALUES (2828,'Gujranwala','PAK','Punjab',1124749);
+INSERT INTO City VALUES (2829,'Peshawar','PAK','Nothwest Border Prov',988005);
+INSERT INTO City VALUES (2830,'Quetta','PAK','Baluchistan',560307);
+INSERT INTO City VALUES (2831,'Islamabad','PAK','Islamabad',524500);
+INSERT INTO City VALUES (2832,'Sargodha','PAK','Punjab',455360);
+INSERT INTO City VALUES (2833,'Sialkot','PAK','Punjab',417597);
+INSERT INTO City VALUES (2834,'Bahawalpur','PAK','Punjab',403408);
+INSERT INTO City VALUES (2835,'Sukkur','PAK','Sindh',329176);
+INSERT INTO City VALUES (2836,'Jhang','PAK','Punjab',292214);
+INSERT INTO City VALUES (2837,'Sheikhupura','PAK','Punjab',271875);
+INSERT INTO City VALUES (2838,'Larkana','PAK','Sindh',270366);
+INSERT INTO City VALUES (2839,'Gujrat','PAK','Punjab',250121);
+INSERT INTO City VALUES (2840,'Mardan','PAK','Nothwest Border Prov',244511);
+INSERT INTO City VALUES (2841,'Kasur','PAK','Punjab',241649);
+INSERT INTO City VALUES (2842,'Rahim Yar Khan','PAK','Punjab',228479);
+INSERT INTO City VALUES (2843,'Sahiwal','PAK','Punjab',207388);
+INSERT INTO City VALUES (2844,'Okara','PAK','Punjab',200901);
+INSERT INTO City VALUES (2845,'Wah','PAK','Punjab',198400);
+INSERT INTO City VALUES (2846,'Dera Ghazi Khan','PAK','Punjab',188100);
+INSERT INTO City VALUES (2847,'Mirpur Khas','PAK','Sind',184500);
+INSERT INTO City VALUES (2848,'Nawabshah','PAK','Sind',183100);
+INSERT INTO City VALUES (2849,'Mingora','PAK','Nothwest Border Prov',174500);
+INSERT INTO City VALUES (2850,'Chiniot','PAK','Punjab',169300);
+INSERT INTO City VALUES (2851,'Kamoke','PAK','Punjab',151000);
+INSERT INTO City VALUES (2852,'Mandi Burewala','PAK','Punjab',149900);
+INSERT INTO City VALUES (2853,'Jhelum','PAK','Punjab',145800);
+INSERT INTO City VALUES (2854,'Sadiqabad','PAK','Punjab',141500);
+INSERT INTO City VALUES (2855,'Jacobabad','PAK','Sind',137700);
+INSERT INTO City VALUES (2856,'Shikarpur','PAK','Sind',133300);
+INSERT INTO City VALUES (2857,'Khanewal','PAK','Punjab',133000);
+INSERT INTO City VALUES (2858,'Hafizabad','PAK','Punjab',130200);
+INSERT INTO City VALUES (2859,'Kohat','PAK','Nothwest Border Prov',125300);
+INSERT INTO City VALUES (2860,'Muzaffargarh','PAK','Punjab',121600);
+INSERT INTO City VALUES (2861,'Khanpur','PAK','Punjab',117800);
+INSERT INTO City VALUES (2862,'Gojra','PAK','Punjab',115000);
+INSERT INTO City VALUES (2863,'Bahawalnagar','PAK','Punjab',109600);
+INSERT INTO City VALUES (2864,'Muridke','PAK','Punjab',108600);
+INSERT INTO City VALUES (2865,'Pak Pattan','PAK','Punjab',107800);
+INSERT INTO City VALUES (2866,'Abottabad','PAK','Nothwest Border Prov',106000);
+INSERT INTO City VALUES (2867,'Tando Adam','PAK','Sind',103400);
+INSERT INTO City VALUES (2868,'Jaranwala','PAK','Punjab',103300);
+INSERT INTO City VALUES (2869,'Khairpur','PAK','Sind',102200);
+INSERT INTO City VALUES (2870,'Chishtian Mandi','PAK','Punjab',101700);
+INSERT INTO City VALUES (2871,'Daska','PAK','Punjab',101500);
+INSERT INTO City VALUES (2872,'Dadu','PAK','Sind',98600);
+INSERT INTO City VALUES (2873,'Mandi Bahauddin','PAK','Punjab',97300);
+INSERT INTO City VALUES (2874,'Ahmadpur East','PAK','Punjab',96000);
+INSERT INTO City VALUES (2875,'Kamalia','PAK','Punjab',95300);
+INSERT INTO City VALUES (2876,'Khuzdar','PAK','Baluchistan',93100);
+INSERT INTO City VALUES (2877,'Vihari','PAK','Punjab',92300);
+INSERT INTO City VALUES (2878,'Dera Ismail Khan','PAK','Nothwest Border Prov',90400);
+INSERT INTO City VALUES (2879,'Wazirabad','PAK','Punjab',89700);
+INSERT INTO City VALUES (2880,'Nowshera','PAK','Nothwest Border Prov',89400);
+INSERT INTO City VALUES (2881,'Koror','PLW','Koror',12000);
+INSERT INTO City VALUES (2882,'Ciudad de Panamá','PAN','Panamá',471373);
+INSERT INTO City VALUES (2883,'San Miguelito','PAN','San Miguelito',315382);
+INSERT INTO City VALUES (2884,'Port Moresby','PNG','National Capital Dis',247000);
+INSERT INTO City VALUES (2885,'Asunción','PRY','Asunción',557776);
+INSERT INTO City VALUES (2886,'Ciudad del Este','PRY','Alto Paraná',133881);
+INSERT INTO City VALUES (2887,'San Lorenzo','PRY','Central',133395);
+INSERT INTO City VALUES (2888,'Lambaré','PRY','Central',99681);
+INSERT INTO City VALUES (2889,'Fernando de la Mora','PRY','Central',95287);
+INSERT INTO City VALUES (2890,'Lima','PER','Lima',6464693);
+INSERT INTO City VALUES (2891,'Arequipa','PER','Arequipa',762000);
+INSERT INTO City VALUES (2892,'Trujillo','PER','La Libertad',652000);
+INSERT INTO City VALUES (2893,'Chiclayo','PER','Lambayeque',517000);
+INSERT INTO City VALUES (2894,'Callao','PER','Callao',424294);
+INSERT INTO City VALUES (2895,'Iquitos','PER','Loreto',367000);
+INSERT INTO City VALUES (2896,'Chimbote','PER','Ancash',336000);
+INSERT INTO City VALUES (2897,'Huancayo','PER','Junín',327000);
+INSERT INTO City VALUES (2898,'Piura','PER','Piura',325000);
+INSERT INTO City VALUES (2899,'Cusco','PER','Cusco',291000);
+INSERT INTO City VALUES (2900,'Pucallpa','PER','Ucayali',220866);
+INSERT INTO City VALUES (2901,'Tacna','PER','Tacna',215683);
+INSERT INTO City VALUES (2902,'Ica','PER','Ica',194820);
+INSERT INTO City VALUES (2903,'Sullana','PER','Piura',147361);
+INSERT INTO City VALUES (2904,'Juliaca','PER','Puno',142576);
+INSERT INTO City VALUES (2905,'Huánuco','PER','Huanuco',129688);
+INSERT INTO City VALUES (2906,'Ayacucho','PER','Ayacucho',118960);
+INSERT INTO City VALUES (2907,'Chincha Alta','PER','Ica',110016);
+INSERT INTO City VALUES (2908,'Cajamarca','PER','Cajamarca',108009);
+INSERT INTO City VALUES (2909,'Puno','PER','Puno',101578);
+INSERT INTO City VALUES (2910,'Ventanilla','PER','Callao',101056);
+INSERT INTO City VALUES (2911,'Castilla','PER','Piura',90642);
+INSERT INTO City VALUES (2912,'Adamstown','PCN','–',42);
+INSERT INTO City VALUES (2913,'Garapan','MNP','Saipan',9200);
+INSERT INTO City VALUES (2914,'Lisboa','PRT','Lisboa',563210);
+INSERT INTO City VALUES (2915,'Porto','PRT','Porto',273060);
+INSERT INTO City VALUES (2916,'Amadora','PRT','Lisboa',122106);
+INSERT INTO City VALUES (2917,'Coímbra','PRT','Coímbra',96100);
+INSERT INTO City VALUES (2918,'Braga','PRT','Braga',90535);
+INSERT INTO City VALUES (2919,'San Juan','PRI','San Juan',434374);
+INSERT INTO City VALUES (2920,'Bayamón','PRI','Bayamón',224044);
+INSERT INTO City VALUES (2921,'Ponce','PRI','Ponce',186475);
+INSERT INTO City VALUES (2922,'Carolina','PRI','Carolina',186076);
+INSERT INTO City VALUES (2923,'Caguas','PRI','Caguas',140502);
+INSERT INTO City VALUES (2924,'Arecibo','PRI','Arecibo',100131);
+INSERT INTO City VALUES (2925,'Guaynabo','PRI','Guaynabo',100053);
+INSERT INTO City VALUES (2926,'Mayagüez','PRI','Mayagüez',98434);
+INSERT INTO City VALUES (2927,'Toa Baja','PRI','Toa Baja',94085);
+INSERT INTO City VALUES (2928,'Warszawa','POL','Mazowieckie',1615369);
+INSERT INTO City VALUES (2929,'Lódz','POL','Lodzkie',800110);
+INSERT INTO City VALUES (2930,'Kraków','POL','Malopolskie',738150);
+INSERT INTO City VALUES (2931,'Wroclaw','POL','Dolnoslaskie',636765);
+INSERT INTO City VALUES (2932,'Poznan','POL','Wielkopolskie',576899);
+INSERT INTO City VALUES (2933,'Gdansk','POL','Pomorskie',458988);
+INSERT INTO City VALUES (2934,'Szczecin','POL','Zachodnio-Pomorskie',416988);
+INSERT INTO City VALUES (2935,'Bydgoszcz','POL','Kujawsko-Pomorskie',386855);
+INSERT INTO City VALUES (2936,'Lublin','POL','Lubelskie',356251);
+INSERT INTO City VALUES (2937,'Katowice','POL','Slaskie',345934);
+INSERT INTO City VALUES (2938,'Bialystok','POL','Podlaskie',283937);
+INSERT INTO City VALUES (2939,'Czestochowa','POL','Slaskie',257812);
+INSERT INTO City VALUES (2940,'Gdynia','POL','Pomorskie',253521);
+INSERT INTO City VALUES (2941,'Sosnowiec','POL','Slaskie',244102);
+INSERT INTO City VALUES (2942,'Radom','POL','Mazowieckie',232262);
+INSERT INTO City VALUES (2943,'Kielce','POL','Swietokrzyskie',212383);
+INSERT INTO City VALUES (2944,'Gliwice','POL','Slaskie',212164);
+INSERT INTO City VALUES (2945,'Torun','POL','Kujawsko-Pomorskie',206158);
+INSERT INTO City VALUES (2946,'Bytom','POL','Slaskie',205560);
+INSERT INTO City VALUES (2947,'Zabrze','POL','Slaskie',200177);
+INSERT INTO City VALUES (2948,'Bielsko-Biala','POL','Slaskie',180307);
+INSERT INTO City VALUES (2949,'Olsztyn','POL','Warminsko-Mazurskie',170904);
+INSERT INTO City VALUES (2950,'Rzeszów','POL','Podkarpackie',162049);
+INSERT INTO City VALUES (2951,'Ruda Slaska','POL','Slaskie',159665);
+INSERT INTO City VALUES (2952,'Rybnik','POL','Slaskie',144582);
+INSERT INTO City VALUES (2953,'Walbrzych','POL','Dolnoslaskie',136923);
+INSERT INTO City VALUES (2954,'Tychy','POL','Slaskie',133178);
+INSERT INTO City VALUES (2955,'Dabrowa Górnicza','POL','Slaskie',131037);
+INSERT INTO City VALUES (2956,'Plock','POL','Mazowieckie',131011);
+INSERT INTO City VALUES (2957,'Elblag','POL','Warminsko-Mazurskie',129782);
+INSERT INTO City VALUES (2958,'Opole','POL','Opolskie',129553);
+INSERT INTO City VALUES (2959,'Gorzów Wielkopolski','POL','Lubuskie',126019);
+INSERT INTO City VALUES (2960,'Wloclawek','POL','Kujawsko-Pomorskie',123373);
+INSERT INTO City VALUES (2961,'Chorzów','POL','Slaskie',121708);
+INSERT INTO City VALUES (2962,'Tarnów','POL','Malopolskie',121494);
+INSERT INTO City VALUES (2963,'Zielona Góra','POL','Lubuskie',118182);
+INSERT INTO City VALUES (2964,'Koszalin','POL','Zachodnio-Pomorskie',112375);
+INSERT INTO City VALUES (2965,'Legnica','POL','Dolnoslaskie',109335);
+INSERT INTO City VALUES (2966,'Kalisz','POL','Wielkopolskie',106641);
+INSERT INTO City VALUES (2967,'Grudziadz','POL','Kujawsko-Pomorskie',102434);
+INSERT INTO City VALUES (2968,'Slupsk','POL','Pomorskie',102370);
+INSERT INTO City VALUES (2969,'Jastrzebie-Zdrój','POL','Slaskie',102294);
+INSERT INTO City VALUES (2970,'Jaworzno','POL','Slaskie',97929);
+INSERT INTO City VALUES (2971,'Jelenia Góra','POL','Dolnoslaskie',93901);
+INSERT INTO City VALUES (2972,'Malabo','GNQ','Bioko',40000);
+INSERT INTO City VALUES (2973,'Doha','QAT','Doha',355000);
+INSERT INTO City VALUES (2974,'Paris','FRA','Île-de-France',2125246);
+INSERT INTO City VALUES (2975,'Marseille','FRA','Provence-Alpes-Côte',798430);
+INSERT INTO City VALUES (2976,'Lyon','FRA','Rhône-Alpes',445452);
+INSERT INTO City VALUES (2977,'Toulouse','FRA','Midi-Pyrénées',390350);
+INSERT INTO City VALUES (2978,'Nice','FRA','Provence-Alpes-Côte',342738);
+INSERT INTO City VALUES (2979,'Nantes','FRA','Pays de la Loire',270251);
+INSERT INTO City VALUES (2980,'Strasbourg','FRA','Alsace',264115);
+INSERT INTO City VALUES (2981,'Montpellier','FRA','Languedoc-Roussillon',225392);
+INSERT INTO City VALUES (2982,'Bordeaux','FRA','Aquitaine',215363);
+INSERT INTO City VALUES (2983,'Rennes','FRA','Haute-Normandie',206229);
+INSERT INTO City VALUES (2984,'Le Havre','FRA','Champagne-Ardenne',190905);
+INSERT INTO City VALUES (2985,'Reims','FRA','Nord-Pas-de-Calais',187206);
+INSERT INTO City VALUES (2986,'Lille','FRA','Rhône-Alpes',184657);
+INSERT INTO City VALUES (2987,'St-Étienne','FRA','Bretagne',180210);
+INSERT INTO City VALUES (2988,'Toulon','FRA','Provence-Alpes-Côte',160639);
+INSERT INTO City VALUES (2989,'Grenoble','FRA','Rhône-Alpes',153317);
+INSERT INTO City VALUES (2990,'Angers','FRA','Pays de la Loire',151279);
+INSERT INTO City VALUES (2991,'Dijon','FRA','Bourgogne',149867);
+INSERT INTO City VALUES (2992,'Brest','FRA','Bretagne',149634);
+INSERT INTO City VALUES (2993,'Le Mans','FRA','Pays de la Loire',146105);
+INSERT INTO City VALUES (2994,'Clermont-Ferrand','FRA','Auvergne',137140);
+INSERT INTO City VALUES (2995,'Amiens','FRA','Picardie',135501);
+INSERT INTO City VALUES (2996,'Aix-en-Provence','FRA','Provence-Alpes-Côte',134222);
+INSERT INTO City VALUES (2997,'Limoges','FRA','Limousin',133968);
+INSERT INTO City VALUES (2998,'Nîmes','FRA','Languedoc-Roussillon',133424);
+INSERT INTO City VALUES (2999,'Tours','FRA','Centre',132820);
+INSERT INTO City VALUES (3000,'Villeurbanne','FRA','Rhône-Alpes',124215);
+INSERT INTO City VALUES (3001,'Metz','FRA','Lorraine',123776);
+INSERT INTO City VALUES (3002,'Besançon','FRA','Franche-Comté',117733);
+INSERT INTO City VALUES (3003,'Caen','FRA','Basse-Normandie',113987);
+INSERT INTO City VALUES (3004,'Orléans','FRA','Centre',113126);
+INSERT INTO City VALUES (3005,'Mulhouse','FRA','Alsace',110359);
+INSERT INTO City VALUES (3006,'Rouen','FRA','Haute-Normandie',106592);
+INSERT INTO City VALUES (3007,'Boulogne-Billancourt','FRA','Île-de-France',106367);
+INSERT INTO City VALUES (3008,'Perpignan','FRA','Languedoc-Roussillon',105115);
+INSERT INTO City VALUES (3009,'Nancy','FRA','Lorraine',103605);
+INSERT INTO City VALUES (3010,'Roubaix','FRA','Nord-Pas-de-Calais',96984);
+INSERT INTO City VALUES (3011,'Argenteuil','FRA','Île-de-France',93961);
+INSERT INTO City VALUES (3012,'Tourcoing','FRA','Nord-Pas-de-Calais',93540);
+INSERT INTO City VALUES (3013,'Montreuil','FRA','Île-de-France',90674);
+INSERT INTO City VALUES (3014,'Cayenne','GUF','Cayenne',50699);
+INSERT INTO City VALUES (3015,'Faaa','PYF','Tahiti',25888);
+INSERT INTO City VALUES (3016,'Papeete','PYF','Tahiti',25553);
+INSERT INTO City VALUES (3017,'Saint-Denis','REU','Saint-Denis',131480);
+INSERT INTO City VALUES (3018,'Bucuresti','ROM','Bukarest',2016131);
+INSERT INTO City VALUES (3019,'Iasi','ROM','Iasi',348070);
+INSERT INTO City VALUES (3020,'Constanta','ROM','Constanta',342264);
+INSERT INTO City VALUES (3021,'Cluj-Napoca','ROM','Cluj',332498);
+INSERT INTO City VALUES (3022,'Galati','ROM','Galati',330276);
+INSERT INTO City VALUES (3023,'Timisoara','ROM','Timis',324304);
+INSERT INTO City VALUES (3024,'Brasov','ROM','Brasov',314225);
+INSERT INTO City VALUES (3025,'Craiova','ROM','Dolj',313530);
+INSERT INTO City VALUES (3026,'Ploiesti','ROM','Prahova',251348);
+INSERT INTO City VALUES (3027,'Braila','ROM','Braila',233756);
+INSERT INTO City VALUES (3028,'Oradea','ROM','Bihor',222239);
+INSERT INTO City VALUES (3029,'Bacau','ROM','Bacau',209235);
+INSERT INTO City VALUES (3030,'Pitesti','ROM','Arges',187170);
+INSERT INTO City VALUES (3031,'Arad','ROM','Arad',184408);
+INSERT INTO City VALUES (3032,'Sibiu','ROM','Sibiu',169611);
+INSERT INTO City VALUES (3033,'Târgu Mures','ROM','Mures',165153);
+INSERT INTO City VALUES (3034,'Baia Mare','ROM','Maramures',149665);
+INSERT INTO City VALUES (3035,'Buzau','ROM','Buzau',148372);
+INSERT INTO City VALUES (3036,'Satu Mare','ROM','Satu Mare',130059);
+INSERT INTO City VALUES (3037,'Botosani','ROM','Botosani',128730);
+INSERT INTO City VALUES (3038,'Piatra Neamt','ROM','Neamt',125070);
+INSERT INTO City VALUES (3039,'Râmnicu Vâlcea','ROM','Vâlcea',119741);
+INSERT INTO City VALUES (3040,'Suceava','ROM','Suceava',118549);
+INSERT INTO City VALUES (3041,'Drobeta-Turnu Severin','ROM','Mehedinti',117865);
+INSERT INTO City VALUES (3042,'Târgoviste','ROM','Dâmbovita',98980);
+INSERT INTO City VALUES (3043,'Focsani','ROM','Vrancea',98979);
+INSERT INTO City VALUES (3044,'Târgu Jiu','ROM','Gorj',98524);
+INSERT INTO City VALUES (3045,'Tulcea','ROM','Tulcea',96278);
+INSERT INTO City VALUES (3046,'Resita','ROM','Caras-Severin',93976);
+INSERT INTO City VALUES (3047,'Kigali','RWA','Kigali',286000);
+INSERT INTO City VALUES (3048,'Stockholm','SWE','Lisboa',750348);
+INSERT INTO City VALUES (3049,'Gothenburg [Göteborg]','SWE','West Götanmaan län',466990);
+INSERT INTO City VALUES (3050,'Malmö','SWE','Skåne län',259579);
+INSERT INTO City VALUES (3051,'Uppsala','SWE','Uppsala län',189569);
+INSERT INTO City VALUES (3052,'Linköping','SWE','East Götanmaan län',133168);
+INSERT INTO City VALUES (3053,'Västerås','SWE','Västmanlands län',126328);
+INSERT INTO City VALUES (3054,'Örebro','SWE','Örebros län',124207);
+INSERT INTO City VALUES (3055,'Norrköping','SWE','East Götanmaan län',122199);
+INSERT INTO City VALUES (3056,'Helsingborg','SWE','Skåne län',117737);
+INSERT INTO City VALUES (3057,'Jönköping','SWE','Jönköpings län',117095);
+INSERT INTO City VALUES (3058,'Umeå','SWE','Västerbottens län',104512);
+INSERT INTO City VALUES (3059,'Lund','SWE','Skåne län',98948);
+INSERT INTO City VALUES (3060,'Borås','SWE','West Götanmaan län',96883);
+INSERT INTO City VALUES (3061,'Sundsvall','SWE','Västernorrlands län',93126);
+INSERT INTO City VALUES (3062,'Gävle','SWE','Gävleborgs län',90742);
+INSERT INTO City VALUES (3063,'Jamestown','SHN','Saint Helena',1500);
+INSERT INTO City VALUES (3064,'Basseterre','KNA','St George Basseterre',11600);
+INSERT INTO City VALUES (3065,'Castries','LCA','Castries',2301);
+INSERT INTO City VALUES (3066,'Kingstown','VCT','St George',17100);
+INSERT INTO City VALUES (3067,'Saint-Pierre','SPM','Saint-Pierre',5808);
+INSERT INTO City VALUES (3068,'Berlin','DEU','Berliini',3386667);
+INSERT INTO City VALUES (3069,'Hamburg','DEU','Hamburg',1704735);
+INSERT INTO City VALUES (3070,'Munich [München]','DEU','Baijeri',1194560);
+INSERT INTO City VALUES (3071,'Köln','DEU','Nordrhein-Westfalen',962507);
+INSERT INTO City VALUES (3072,'Frankfurt am Main','DEU','Hessen',643821);
+INSERT INTO City VALUES (3073,'Essen','DEU','Nordrhein-Westfalen',599515);
+INSERT INTO City VALUES (3074,'Dortmund','DEU','Nordrhein-Westfalen',590213);
+INSERT INTO City VALUES (3075,'Stuttgart','DEU','Baden-Württemberg',582443);
+INSERT INTO City VALUES (3076,'Düsseldorf','DEU','Nordrhein-Westfalen',568855);
+INSERT INTO City VALUES (3077,'Bremen','DEU','Bremen',540330);
+INSERT INTO City VALUES (3078,'Duisburg','DEU','Nordrhein-Westfalen',519793);
+INSERT INTO City VALUES (3079,'Hannover','DEU','Niedersachsen',514718);
+INSERT INTO City VALUES (3080,'Leipzig','DEU','Saksi',489532);
+INSERT INTO City VALUES (3081,'Nürnberg','DEU','Baijeri',486628);
+INSERT INTO City VALUES (3082,'Dresden','DEU','Saksi',476668);
+INSERT INTO City VALUES (3083,'Bochum','DEU','Nordrhein-Westfalen',392830);
+INSERT INTO City VALUES (3084,'Wuppertal','DEU','Nordrhein-Westfalen',368993);
+INSERT INTO City VALUES (3085,'Bielefeld','DEU','Nordrhein-Westfalen',321125);
+INSERT INTO City VALUES (3086,'Mannheim','DEU','Baden-Württemberg',307730);
+INSERT INTO City VALUES (3087,'Bonn','DEU','Nordrhein-Westfalen',301048);
+INSERT INTO City VALUES (3088,'Gelsenkirchen','DEU','Nordrhein-Westfalen',281979);
+INSERT INTO City VALUES (3089,'Karlsruhe','DEU','Baden-Württemberg',277204);
+INSERT INTO City VALUES (3090,'Wiesbaden','DEU','Hessen',268716);
+INSERT INTO City VALUES (3091,'Münster','DEU','Nordrhein-Westfalen',264670);
+INSERT INTO City VALUES (3092,'Mönchengladbach','DEU','Nordrhein-Westfalen',263697);
+INSERT INTO City VALUES (3093,'Chemnitz','DEU','Saksi',263222);
+INSERT INTO City VALUES (3094,'Augsburg','DEU','Baijeri',254867);
+INSERT INTO City VALUES (3095,'Halle/Saale','DEU','Anhalt Sachsen',254360);
+INSERT INTO City VALUES (3096,'Braunschweig','DEU','Niedersachsen',246322);
+INSERT INTO City VALUES (3097,'Aachen','DEU','Nordrhein-Westfalen',243825);
+INSERT INTO City VALUES (3098,'Krefeld','DEU','Nordrhein-Westfalen',241769);
+INSERT INTO City VALUES (3099,'Magdeburg','DEU','Anhalt Sachsen',235073);
+INSERT INTO City VALUES (3100,'Kiel','DEU','Schleswig-Holstein',233795);
+INSERT INTO City VALUES (3101,'Oberhausen','DEU','Nordrhein-Westfalen',222349);
+INSERT INTO City VALUES (3102,'Lübeck','DEU','Schleswig-Holstein',213326);
+INSERT INTO City VALUES (3103,'Hagen','DEU','Nordrhein-Westfalen',205201);
+INSERT INTO City VALUES (3104,'Rostock','DEU','Mecklenburg-Vorpomme',203279);
+INSERT INTO City VALUES (3105,'Freiburg im Breisgau','DEU','Baden-Württemberg',202455);
+INSERT INTO City VALUES (3106,'Erfurt','DEU','Thüringen',201267);
+INSERT INTO City VALUES (3107,'Kassel','DEU','Hessen',196211);
+INSERT INTO City VALUES (3108,'Saarbrücken','DEU','Saarland',183836);
+INSERT INTO City VALUES (3109,'Mainz','DEU','Rheinland-Pfalz',183134);
+INSERT INTO City VALUES (3110,'Hamm','DEU','Nordrhein-Westfalen',181804);
+INSERT INTO City VALUES (3111,'Herne','DEU','Nordrhein-Westfalen',175661);
+INSERT INTO City VALUES (3112,'Mülheim an der Ruhr','DEU','Nordrhein-Westfalen',173895);
+INSERT INTO City VALUES (3113,'Solingen','DEU','Nordrhein-Westfalen',165583);
+INSERT INTO City VALUES (3114,'Osnabrück','DEU','Niedersachsen',164539);
+INSERT INTO City VALUES (3115,'Ludwigshafen am Rhein','DEU','Rheinland-Pfalz',163771);
+INSERT INTO City VALUES (3116,'Leverkusen','DEU','Nordrhein-Westfalen',160841);
+INSERT INTO City VALUES (3117,'Oldenburg','DEU','Niedersachsen',154125);
+INSERT INTO City VALUES (3118,'Neuss','DEU','Nordrhein-Westfalen',149702);
+INSERT INTO City VALUES (3119,'Heidelberg','DEU','Baden-Württemberg',139672);
+INSERT INTO City VALUES (3120,'Darmstadt','DEU','Hessen',137776);
+INSERT INTO City VALUES (3121,'Paderborn','DEU','Nordrhein-Westfalen',137647);
+INSERT INTO City VALUES (3122,'Potsdam','DEU','Brandenburg',128983);
+INSERT INTO City VALUES (3123,'Würzburg','DEU','Baijeri',127350);
+INSERT INTO City VALUES (3124,'Regensburg','DEU','Baijeri',125236);
+INSERT INTO City VALUES (3125,'Recklinghausen','DEU','Nordrhein-Westfalen',125022);
+INSERT INTO City VALUES (3126,'Göttingen','DEU','Niedersachsen',124775);
+INSERT INTO City VALUES (3127,'Bremerhaven','DEU','Bremen',122735);
+INSERT INTO City VALUES (3128,'Wolfsburg','DEU','Niedersachsen',121954);
+INSERT INTO City VALUES (3129,'Bottrop','DEU','Nordrhein-Westfalen',121097);
+INSERT INTO City VALUES (3130,'Remscheid','DEU','Nordrhein-Westfalen',120125);
+INSERT INTO City VALUES (3131,'Heilbronn','DEU','Baden-Württemberg',119526);
+INSERT INTO City VALUES (3132,'Pforzheim','DEU','Baden-Württemberg',117227);
+INSERT INTO City VALUES (3133,'Offenbach am Main','DEU','Hessen',116627);
+INSERT INTO City VALUES (3134,'Ulm','DEU','Baden-Württemberg',116103);
+INSERT INTO City VALUES (3135,'Ingolstadt','DEU','Baijeri',114826);
+INSERT INTO City VALUES (3136,'Gera','DEU','Thüringen',114718);
+INSERT INTO City VALUES (3137,'Salzgitter','DEU','Niedersachsen',112934);
+INSERT INTO City VALUES (3138,'Cottbus','DEU','Brandenburg',110894);
+INSERT INTO City VALUES (3139,'Reutlingen','DEU','Baden-Württemberg',110343);
+INSERT INTO City VALUES (3140,'Fürth','DEU','Baijeri',109771);
+INSERT INTO City VALUES (3141,'Siegen','DEU','Nordrhein-Westfalen',109225);
+INSERT INTO City VALUES (3142,'Koblenz','DEU','Rheinland-Pfalz',108003);
+INSERT INTO City VALUES (3143,'Moers','DEU','Nordrhein-Westfalen',106837);
+INSERT INTO City VALUES (3144,'Bergisch Gladbach','DEU','Nordrhein-Westfalen',106150);
+INSERT INTO City VALUES (3145,'Zwickau','DEU','Saksi',104146);
+INSERT INTO City VALUES (3146,'Hildesheim','DEU','Niedersachsen',104013);
+INSERT INTO City VALUES (3147,'Witten','DEU','Nordrhein-Westfalen',103384);
+INSERT INTO City VALUES (3148,'Schwerin','DEU','Mecklenburg-Vorpomme',102878);
+INSERT INTO City VALUES (3149,'Erlangen','DEU','Baijeri',100750);
+INSERT INTO City VALUES (3150,'Kaiserslautern','DEU','Rheinland-Pfalz',100025);
+INSERT INTO City VALUES (3151,'Trier','DEU','Rheinland-Pfalz',99891);
+INSERT INTO City VALUES (3152,'Jena','DEU','Thüringen',99779);
+INSERT INTO City VALUES (3153,'Iserlohn','DEU','Nordrhein-Westfalen',99474);
+INSERT INTO City VALUES (3154,'Gütersloh','DEU','Nordrhein-Westfalen',95028);
+INSERT INTO City VALUES (3155,'Marl','DEU','Nordrhein-Westfalen',93735);
+INSERT INTO City VALUES (3156,'Lünen','DEU','Nordrhein-Westfalen',92044);
+INSERT INTO City VALUES (3157,'Düren','DEU','Nordrhein-Westfalen',91092);
+INSERT INTO City VALUES (3158,'Ratingen','DEU','Nordrhein-Westfalen',90951);
+INSERT INTO City VALUES (3159,'Velbert','DEU','Nordrhein-Westfalen',89881);
+INSERT INTO City VALUES (3160,'Esslingen am Neckar','DEU','Baden-Württemberg',89667);
+INSERT INTO City VALUES (3161,'Honiara','SLB','Honiara',50100);
+INSERT INTO City VALUES (3162,'Lusaka','ZMB','Lusaka',1317000);
+INSERT INTO City VALUES (3163,'Ndola','ZMB','Copperbelt',329200);
+INSERT INTO City VALUES (3164,'Kitwe','ZMB','Copperbelt',288600);
+INSERT INTO City VALUES (3165,'Kabwe','ZMB','Central',154300);
+INSERT INTO City VALUES (3166,'Chingola','ZMB','Copperbelt',142400);
+INSERT INTO City VALUES (3167,'Mufulira','ZMB','Copperbelt',123900);
+INSERT INTO City VALUES (3168,'Luanshya','ZMB','Copperbelt',118100);
+INSERT INTO City VALUES (3169,'Apia','WSM','Upolu',35900);
+INSERT INTO City VALUES (3170,'Serravalle','SMR','Serravalle/Dogano',4802);
+INSERT INTO City VALUES (3171,'San Marino','SMR','San Marino',2294);
+INSERT INTO City VALUES (3172,'São Tomé','STP','Aqua Grande',49541);
+INSERT INTO City VALUES (3173,'Riyadh','SAU','Riyadh',3324000);
+INSERT INTO City VALUES (3174,'Jedda','SAU','Mekka',2046300);
+INSERT INTO City VALUES (3175,'Mekka','SAU','Mekka',965700);
+INSERT INTO City VALUES (3176,'Medina','SAU','Medina',608300);
+INSERT INTO City VALUES (3177,'al-Dammam','SAU','al-Sharqiya',482300);
+INSERT INTO City VALUES (3178,'al-Taif','SAU','Mekka',416100);
+INSERT INTO City VALUES (3179,'Tabuk','SAU','Tabuk',292600);
+INSERT INTO City VALUES (3180,'Burayda','SAU','al-Qasim',248600);
+INSERT INTO City VALUES (3181,'al-Hufuf','SAU','al-Sharqiya',225800);
+INSERT INTO City VALUES (3182,'al-Mubarraz','SAU','al-Sharqiya',219100);
+INSERT INTO City VALUES (3183,'Khamis Mushayt','SAU','Asir',217900);
+INSERT INTO City VALUES (3184,'Hail','SAU','Hail',176800);
+INSERT INTO City VALUES (3185,'al-Kharj','SAU','Riad',152100);
+INSERT INTO City VALUES (3186,'al-Khubar','SAU','al-Sharqiya',141700);
+INSERT INTO City VALUES (3187,'Jubayl','SAU','al-Sharqiya',140800);
+INSERT INTO City VALUES (3188,'Hafar al-Batin','SAU','al-Sharqiya',137800);
+INSERT INTO City VALUES (3189,'al-Tuqba','SAU','al-Sharqiya',125700);
+INSERT INTO City VALUES (3190,'Yanbu','SAU','Medina',119800);
+INSERT INTO City VALUES (3191,'Abha','SAU','Asir',112300);
+INSERT INTO City VALUES (3192,'Ara´ar','SAU','al-Khudud al-Samaliy',108100);
+INSERT INTO City VALUES (3193,'al-Qatif','SAU','al-Sharqiya',98900);
+INSERT INTO City VALUES (3194,'al-Hawiya','SAU','Mekka',93900);
+INSERT INTO City VALUES (3195,'Unayza','SAU','Qasim',91100);
+INSERT INTO City VALUES (3196,'Najran','SAU','Najran',91000);
+INSERT INTO City VALUES (3197,'Pikine','SEN','Cap-Vert',855287);
+INSERT INTO City VALUES (3198,'Dakar','SEN','Cap-Vert',785071);
+INSERT INTO City VALUES (3199,'Thiès','SEN','Thiès',248000);
+INSERT INTO City VALUES (3200,'Kaolack','SEN','Kaolack',199000);
+INSERT INTO City VALUES (3201,'Ziguinchor','SEN','Ziguinchor',192000);
+INSERT INTO City VALUES (3202,'Rufisque','SEN','Cap-Vert',150000);
+INSERT INTO City VALUES (3203,'Saint-Louis','SEN','Saint-Louis',132400);
+INSERT INTO City VALUES (3204,'Mbour','SEN','Thiès',109300);
+INSERT INTO City VALUES (3205,'Diourbel','SEN','Diourbel',99400);
+INSERT INTO City VALUES (3206,'Victoria','SYC','Mahé',41000);
+INSERT INTO City VALUES (3207,'Freetown','SLE','Western',850000);
+INSERT INTO City VALUES (3208,'Singapore','SGP','–',4017733);
+INSERT INTO City VALUES (3209,'Bratislava','SVK','Bratislava',448292);
+INSERT INTO City VALUES (3210,'Košice','SVK','Východné Slovensko',241874);
+INSERT INTO City VALUES (3211,'Prešov','SVK','Východné Slovensko',93977);
+INSERT INTO City VALUES (3212,'Ljubljana','SVN','Osrednjeslovenska',270986);
+INSERT INTO City VALUES (3213,'Maribor','SVN','Podravska',115532);
+INSERT INTO City VALUES (3214,'Mogadishu','SOM','Banaadir',997000);
+INSERT INTO City VALUES (3215,'Hargeysa','SOM','Woqooyi Galbeed',90000);
+INSERT INTO City VALUES (3216,'Kismaayo','SOM','Jubbada Hoose',90000);
+INSERT INTO City VALUES (3217,'Colombo','LKA','Western',645000);
+INSERT INTO City VALUES (3218,'Dehiwala','LKA','Western',203000);
+INSERT INTO City VALUES (3219,'Moratuwa','LKA','Western',190000);
+INSERT INTO City VALUES (3220,'Jaffna','LKA','Northern',149000);
+INSERT INTO City VALUES (3221,'Kandy','LKA','Central',140000);
+INSERT INTO City VALUES (3222,'Sri Jayawardenepura Kotte','LKA','Western',118000);
+INSERT INTO City VALUES (3223,'Negombo','LKA','Western',100000);
+INSERT INTO City VALUES (3224,'Omdurman','SDN','Khartum',1271403);
+INSERT INTO City VALUES (3225,'Khartum','SDN','Khartum',947483);
+INSERT INTO City VALUES (3226,'Sharq al-Nil','SDN','Khartum',700887);
+INSERT INTO City VALUES (3227,'Port Sudan','SDN','al-Bahr al-Ahmar',308195);
+INSERT INTO City VALUES (3228,'Kassala','SDN','Kassala',234622);
+INSERT INTO City VALUES (3229,'Obeid','SDN','Kurdufan al-Shamaliy',229425);
+INSERT INTO City VALUES (3230,'Nyala','SDN','Darfur al-Janubiya',227183);
+INSERT INTO City VALUES (3231,'Wad Madani','SDN','al-Jazira',211362);
+INSERT INTO City VALUES (3232,'al-Qadarif','SDN','al-Qadarif',191164);
+INSERT INTO City VALUES (3233,'Kusti','SDN','al-Bahr al-Abyad',173599);
+INSERT INTO City VALUES (3234,'al-Fashir','SDN','Darfur al-Shamaliya',141884);
+INSERT INTO City VALUES (3235,'Juba','SDN','Bahr al-Jabal',114980);
+INSERT INTO City VALUES (3236,'Helsinki [Helsingfors]','FIN','Newmaa',555474);
+INSERT INTO City VALUES (3237,'Espoo','FIN','Newmaa',213271);
+INSERT INTO City VALUES (3238,'Tampere','FIN','Pirkanmaa',195468);
+INSERT INTO City VALUES (3239,'Vantaa','FIN','Newmaa',178471);
+INSERT INTO City VALUES (3240,'Turku [Åbo]','FIN','Varsinais-Suomi',172561);
+INSERT INTO City VALUES (3241,'Oulu','FIN','Pohjois-Pohjanmaa',120753);
+INSERT INTO City VALUES (3242,'Lahti','FIN','Päijät-Häme',96921);
+INSERT INTO City VALUES (3243,'Paramaribo','SUR','Paramaribo',112000);
+INSERT INTO City VALUES (3244,'Mbabane','SWZ','Hhohho',61000);
+INSERT INTO City VALUES (3245,'Zürich','CHE','Zürich',336800);
+INSERT INTO City VALUES (3246,'Geneve','CHE','Geneve',173500);
+INSERT INTO City VALUES (3247,'Basel','CHE','Basel-Stadt',166700);
+INSERT INTO City VALUES (3248,'Bern','CHE','Bern',122700);
+INSERT INTO City VALUES (3249,'Lausanne','CHE','Vaud',114500);
+INSERT INTO City VALUES (3250,'Damascus','SYR','Damascus',1347000);
+INSERT INTO City VALUES (3251,'Aleppo','SYR','Aleppo',1261983);
+INSERT INTO City VALUES (3252,'Hims','SYR','Hims',507404);
+INSERT INTO City VALUES (3253,'Hama','SYR','Hama',343361);
+INSERT INTO City VALUES (3254,'Latakia','SYR','Latakia',264563);
+INSERT INTO City VALUES (3255,'al-Qamishliya','SYR','al-Hasaka',144286);
+INSERT INTO City VALUES (3256,'Dayr al-Zawr','SYR','Dayr al-Zawr',140459);
+INSERT INTO City VALUES (3257,'Jaramana','SYR','Damaskos',138469);
+INSERT INTO City VALUES (3258,'Duma','SYR','Damaskos',131158);
+INSERT INTO City VALUES (3259,'al-Raqqa','SYR','al-Raqqa',108020);
+INSERT INTO City VALUES (3260,'Idlib','SYR','Idlib',91081);
+INSERT INTO City VALUES (3261,'Dushanbe','TJK','Karotegin',524000);
+INSERT INTO City VALUES (3262,'Khujand','TJK','Khujand',161500);
+INSERT INTO City VALUES (3263,'Taipei','TWN','Taipei',2641312);
+INSERT INTO City VALUES (3264,'Kaohsiung','TWN','Kaohsiung',1475505);
+INSERT INTO City VALUES (3265,'Taichung','TWN','Taichung',940589);
+INSERT INTO City VALUES (3266,'Tainan','TWN','Tainan',728060);
+INSERT INTO City VALUES (3267,'Panchiao','TWN','Taipei',523850);
+INSERT INTO City VALUES (3268,'Chungho','TWN','Taipei',392176);
+INSERT INTO City VALUES (3269,'Keelung (Chilung)','TWN','Keelung',385201);
+INSERT INTO City VALUES (3270,'Sanchung','TWN','Taipei',380084);
+INSERT INTO City VALUES (3271,'Hsinchuang','TWN','Taipei',365048);
+INSERT INTO City VALUES (3272,'Hsinchu','TWN','Hsinchu',361958);
+INSERT INTO City VALUES (3273,'Chungli','TWN','Taoyuan',318649);
+INSERT INTO City VALUES (3274,'Fengshan','TWN','Kaohsiung',318562);
+INSERT INTO City VALUES (3275,'Taoyuan','TWN','Taoyuan',316438);
+INSERT INTO City VALUES (3276,'Chiayi','TWN','Chiayi',265109);
+INSERT INTO City VALUES (3277,'Hsintien','TWN','Taipei',263603);
+INSERT INTO City VALUES (3278,'Changhwa','TWN','Changhwa',227715);
+INSERT INTO City VALUES (3279,'Yungho','TWN','Taipei',227700);
+INSERT INTO City VALUES (3280,'Tucheng','TWN','Taipei',224897);
+INSERT INTO City VALUES (3281,'Pingtung','TWN','Pingtung',214727);
+INSERT INTO City VALUES (3282,'Yungkang','TWN','Tainan',193005);
+INSERT INTO City VALUES (3283,'Pingchen','TWN','Taoyuan',188344);
+INSERT INTO City VALUES (3284,'Tali','TWN','Taichung',171940);
+INSERT INTO City VALUES (3285,'Taiping','TWN','',165524);
+INSERT INTO City VALUES (3286,'Pate','TWN','Taoyuan',161700);
+INSERT INTO City VALUES (3287,'Fengyuan','TWN','Taichung',161032);
+INSERT INTO City VALUES (3288,'Luchou','TWN','Taipei',160516);
+INSERT INTO City VALUES (3289,'Hsichuh','TWN','Taipei',154976);
+INSERT INTO City VALUES (3290,'Shulin','TWN','Taipei',151260);
+INSERT INTO City VALUES (3291,'Yuanlin','TWN','Changhwa',126402);
+INSERT INTO City VALUES (3292,'Yangmei','TWN','Taoyuan',126323);
+INSERT INTO City VALUES (3293,'Taliao','TWN','',115897);
+INSERT INTO City VALUES (3294,'Kueishan','TWN','',112195);
+INSERT INTO City VALUES (3295,'Tanshui','TWN','Taipei',111882);
+INSERT INTO City VALUES (3296,'Taitung','TWN','Taitung',111039);
+INSERT INTO City VALUES (3297,'Hualien','TWN','Hualien',108407);
+INSERT INTO City VALUES (3298,'Nantou','TWN','Nantou',104723);
+INSERT INTO City VALUES (3299,'Lungtan','TWN','Taipei',103088);
+INSERT INTO City VALUES (3300,'Touliu','TWN','Yünlin',98900);
+INSERT INTO City VALUES (3301,'Tsaotun','TWN','Nantou',96800);
+INSERT INTO City VALUES (3302,'Kangshan','TWN','Kaohsiung',92200);
+INSERT INTO City VALUES (3303,'Ilan','TWN','Ilan',92000);
+INSERT INTO City VALUES (3304,'Miaoli','TWN','Miaoli',90000);
+INSERT INTO City VALUES (3305,'Dar es Salaam','TZA','Dar es Salaam',1747000);
+INSERT INTO City VALUES (3306,'Dodoma','TZA','Dodoma',189000);
+INSERT INTO City VALUES (3307,'Mwanza','TZA','Mwanza',172300);
+INSERT INTO City VALUES (3308,'Zanzibar','TZA','Zanzibar West',157634);
+INSERT INTO City VALUES (3309,'Tanga','TZA','Tanga',137400);
+INSERT INTO City VALUES (3310,'Mbeya','TZA','Mbeya',130800);
+INSERT INTO City VALUES (3311,'Morogoro','TZA','Morogoro',117800);
+INSERT INTO City VALUES (3312,'Arusha','TZA','Arusha',102500);
+INSERT INTO City VALUES (3313,'Moshi','TZA','Kilimanjaro',96800);
+INSERT INTO City VALUES (3314,'Tabora','TZA','Tabora',92800);
+INSERT INTO City VALUES (3315,'København','DNK','København',495699);
+INSERT INTO City VALUES (3316,'Århus','DNK','Århus',284846);
+INSERT INTO City VALUES (3317,'Odense','DNK','Fyn',183912);
+INSERT INTO City VALUES (3318,'Aalborg','DNK','Nordjylland',161161);
+INSERT INTO City VALUES (3319,'Frederiksberg','DNK','Frederiksberg',90327);
+INSERT INTO City VALUES (3320,'Bangkok','THA','Bangkok',6320174);
+INSERT INTO City VALUES (3321,'Nonthaburi','THA','Nonthaburi',292100);
+INSERT INTO City VALUES (3322,'Nakhon Ratchasima','THA','Nakhon Ratchasima',181400);
+INSERT INTO City VALUES (3323,'Chiang Mai','THA','Chiang Mai',171100);
+INSERT INTO City VALUES (3324,'Udon Thani','THA','Udon Thani',158100);
+INSERT INTO City VALUES (3325,'Hat Yai','THA','Songkhla',148632);
+INSERT INTO City VALUES (3326,'Khon Kaen','THA','Khon Kaen',126500);
+INSERT INTO City VALUES (3327,'Pak Kret','THA','Nonthaburi',126055);
+INSERT INTO City VALUES (3328,'Nakhon Sawan','THA','Nakhon Sawan',123800);
+INSERT INTO City VALUES (3329,'Ubon Ratchathani','THA','Ubon Ratchathani',116300);
+INSERT INTO City VALUES (3330,'Songkhla','THA','Songkhla',94900);
+INSERT INTO City VALUES (3331,'Nakhon Pathom','THA','Nakhon Pathom',94100);
+INSERT INTO City VALUES (3332,'Lomé','TGO','Maritime',375000);
+INSERT INTO City VALUES (3333,'Fakaofo','TKL','Fakaofo',300);
+INSERT INTO City VALUES (3334,'Nuku´alofa','TON','Tongatapu',22400);
+INSERT INTO City VALUES (3335,'Chaguanas','TTO','Caroni',56601);
+INSERT INTO City VALUES (3336,'Port-of-Spain','TTO','Port-of-Spain',43396);
+INSERT INTO City VALUES (3337,'N´Djaména','TCD','Chari-Baguirmi',530965);
+INSERT INTO City VALUES (3338,'Moundou','TCD','Logone Occidental',99500);
+INSERT INTO City VALUES (3339,'Praha','CZE','Hlavní mesto Praha',1181126);
+INSERT INTO City VALUES (3340,'Brno','CZE','Jizní Morava',381862);
+INSERT INTO City VALUES (3341,'Ostrava','CZE','Severní Morava',320041);
+INSERT INTO City VALUES (3342,'Plzen','CZE','Zapadní Cechy',166759);
+INSERT INTO City VALUES (3343,'Olomouc','CZE','Severní Morava',102702);
+INSERT INTO City VALUES (3344,'Liberec','CZE','Severní Cechy',99155);
+INSERT INTO City VALUES (3345,'Ceské Budejovice','CZE','Jizní Cechy',98186);
+INSERT INTO City VALUES (3346,'Hradec Králové','CZE','Východní Cechy',98080);
+INSERT INTO City VALUES (3347,'Ústí nad Labem','CZE','Severní Cechy',95491);
+INSERT INTO City VALUES (3348,'Pardubice','CZE','Východní Cechy',91309);
+INSERT INTO City VALUES (3349,'Tunis','TUN','Tunis',690600);
+INSERT INTO City VALUES (3350,'Sfax','TUN','Sfax',257800);
+INSERT INTO City VALUES (3351,'Ariana','TUN','Ariana',197000);
+INSERT INTO City VALUES (3352,'Ettadhamen','TUN','Ariana',178600);
+INSERT INTO City VALUES (3353,'Sousse','TUN','Sousse',145900);
+INSERT INTO City VALUES (3354,'Kairouan','TUN','Kairouan',113100);
+INSERT INTO City VALUES (3355,'Biserta','TUN','Biserta',108900);
+INSERT INTO City VALUES (3356,'Gabès','TUN','Gabès',106600);
+INSERT INTO City VALUES (3357,'Istanbul','TUR','Istanbul',8787958);
+INSERT INTO City VALUES (3358,'Ankara','TUR','Ankara',3038159);
+INSERT INTO City VALUES (3359,'Izmir','TUR','Izmir',2130359);
+INSERT INTO City VALUES (3360,'Adana','TUR','Adana',1131198);
+INSERT INTO City VALUES (3361,'Bursa','TUR','Bursa',1095842);
+INSERT INTO City VALUES (3362,'Gaziantep','TUR','Gaziantep',789056);
+INSERT INTO City VALUES (3363,'Konya','TUR','Konya',628364);
+INSERT INTO City VALUES (3364,'Mersin (Içel)','TUR','Içel',587212);
+INSERT INTO City VALUES (3365,'Antalya','TUR','Antalya',564914);
+INSERT INTO City VALUES (3366,'Diyarbakir','TUR','Diyarbakir',479884);
+INSERT INTO City VALUES (3367,'Kayseri','TUR','Kayseri',475657);
+INSERT INTO City VALUES (3368,'Eskisehir','TUR','Eskisehir',470781);
+INSERT INTO City VALUES (3369,'Sanliurfa','TUR','Sanliurfa',405905);
+INSERT INTO City VALUES (3370,'Samsun','TUR','Samsun',339871);
+INSERT INTO City VALUES (3371,'Malatya','TUR','Malatya',330312);
+INSERT INTO City VALUES (3372,'Gebze','TUR','Kocaeli',264170);
+INSERT INTO City VALUES (3373,'Denizli','TUR','Denizli',253848);
+INSERT INTO City VALUES (3374,'Sivas','TUR','Sivas',246642);
+INSERT INTO City VALUES (3375,'Erzurum','TUR','Erzurum',246535);
+INSERT INTO City VALUES (3376,'Tarsus','TUR','Adana',246206);
+INSERT INTO City VALUES (3377,'Kahramanmaras','TUR','Kahramanmaras',245772);
+INSERT INTO City VALUES (3378,'Elâzig','TUR','Elâzig',228815);
+INSERT INTO City VALUES (3379,'Van','TUR','Van',219319);
+INSERT INTO City VALUES (3380,'Sultanbeyli','TUR','Istanbul',211068);
+INSERT INTO City VALUES (3381,'Izmit (Kocaeli)','TUR','Kocaeli',210068);
+INSERT INTO City VALUES (3382,'Manisa','TUR','Manisa',207148);
+INSERT INTO City VALUES (3383,'Batman','TUR','Batman',203793);
+INSERT INTO City VALUES (3384,'Balikesir','TUR','Balikesir',196382);
+INSERT INTO City VALUES (3385,'Sakarya (Adapazari)','TUR','Sakarya',190641);
+INSERT INTO City VALUES (3386,'Iskenderun','TUR','Hatay',153022);
+INSERT INTO City VALUES (3387,'Osmaniye','TUR','Osmaniye',146003);
+INSERT INTO City VALUES (3388,'Çorum','TUR','Çorum',145495);
+INSERT INTO City VALUES (3389,'Kütahya','TUR','Kütahya',144761);
+INSERT INTO City VALUES (3390,'Hatay (Antakya)','TUR','Hatay',143982);
+INSERT INTO City VALUES (3391,'Kirikkale','TUR','Kirikkale',142044);
+INSERT INTO City VALUES (3392,'Adiyaman','TUR','Adiyaman',141529);
+INSERT INTO City VALUES (3393,'Trabzon','TUR','Trabzon',138234);
+INSERT INTO City VALUES (3394,'Ordu','TUR','Ordu',133642);
+INSERT INTO City VALUES (3395,'Aydin','TUR','Aydin',128651);
+INSERT INTO City VALUES (3396,'Usak','TUR','Usak',128162);
+INSERT INTO City VALUES (3397,'Edirne','TUR','Edirne',123383);
+INSERT INTO City VALUES (3398,'Çorlu','TUR','Tekirdag',123300);
+INSERT INTO City VALUES (3399,'Isparta','TUR','Isparta',121911);
+INSERT INTO City VALUES (3400,'Karabük','TUR','Karabük',118285);
+INSERT INTO City VALUES (3401,'Kilis','TUR','Kilis',118245);
+INSERT INTO City VALUES (3402,'Alanya','TUR','Antalya',117300);
+INSERT INTO City VALUES (3403,'Kiziltepe','TUR','Mardin',112000);
+INSERT INTO City VALUES (3404,'Zonguldak','TUR','Zonguldak',111542);
+INSERT INTO City VALUES (3405,'Siirt','TUR','Siirt',107100);
+INSERT INTO City VALUES (3406,'Viransehir','TUR','Sanliurfa',106400);
+INSERT INTO City VALUES (3407,'Tekirdag','TUR','Tekirdag',106077);
+INSERT INTO City VALUES (3408,'Karaman','TUR','Karaman',104200);
+INSERT INTO City VALUES (3409,'Afyon','TUR','Afyon',103984);
+INSERT INTO City VALUES (3410,'Aksaray','TUR','Aksaray',102681);
+INSERT INTO City VALUES (3411,'Ceyhan','TUR','Adana',102412);
+INSERT INTO City VALUES (3412,'Erzincan','TUR','Erzincan',102304);
+INSERT INTO City VALUES (3413,'Bismil','TUR','Diyarbakir',101400);
+INSERT INTO City VALUES (3414,'Nazilli','TUR','Aydin',99900);
+INSERT INTO City VALUES (3415,'Tokat','TUR','Tokat',99500);
+INSERT INTO City VALUES (3416,'Kars','TUR','Kars',93000);
+INSERT INTO City VALUES (3417,'Inegöl','TUR','Bursa',90500);
+INSERT INTO City VALUES (3418,'Bandirma','TUR','Balikesir',90200);
+INSERT INTO City VALUES (3419,'Ashgabat','TKM','Ahal',540600);
+INSERT INTO City VALUES (3420,'Chärjew','TKM','Lebap',189200);
+INSERT INTO City VALUES (3421,'Dashhowuz','TKM','Dashhowuz',141800);
+INSERT INTO City VALUES (3422,'Mary','TKM','Mary',101000);
+INSERT INTO City VALUES (3423,'Cockburn Town','TCA','Grand Turk',4800);
+INSERT INTO City VALUES (3424,'Funafuti','TUV','Funafuti',4600);
+INSERT INTO City VALUES (3425,'Kampala','UGA','Central',890800);
+INSERT INTO City VALUES (3426,'Kyiv','UKR','Kiova',2624000);
+INSERT INTO City VALUES (3427,'Harkova [Harkiv]','UKR','Harkova',1500000);
+INSERT INTO City VALUES (3428,'Dnipropetrovsk','UKR','Dnipropetrovsk',1103000);
+INSERT INTO City VALUES (3429,'Donetsk','UKR','Donetsk',1050000);
+INSERT INTO City VALUES (3430,'Odesa','UKR','Odesa',1011000);
+INSERT INTO City VALUES (3431,'Zaporizzja','UKR','Zaporizzja',848000);
+INSERT INTO City VALUES (3432,'Lviv','UKR','Lviv',788000);
+INSERT INTO City VALUES (3433,'Kryvyi Rig','UKR','Dnipropetrovsk',703000);
+INSERT INTO City VALUES (3434,'Mykolajiv','UKR','Mykolajiv',508000);
+INSERT INTO City VALUES (3435,'Mariupol','UKR','Donetsk',490000);
+INSERT INTO City VALUES (3436,'Lugansk','UKR','Lugansk',469000);
+INSERT INTO City VALUES (3437,'Vinnytsja','UKR','Vinnytsja',391000);
+INSERT INTO City VALUES (3438,'Makijivka','UKR','Donetsk',384000);
+INSERT INTO City VALUES (3439,'Herson','UKR','Herson',353000);
+INSERT INTO City VALUES (3440,'Sevastopol','UKR','Krim',348000);
+INSERT INTO City VALUES (3441,'Simferopol','UKR','Krim',339000);
+INSERT INTO City VALUES (3442,'Pultava [Poltava]','UKR','Pultava',313000);
+INSERT INTO City VALUES (3443,'Tšernigiv','UKR','Tšernigiv',313000);
+INSERT INTO City VALUES (3444,'Tšerkasy','UKR','Tšerkasy',309000);
+INSERT INTO City VALUES (3445,'Gorlivka','UKR','Donetsk',299000);
+INSERT INTO City VALUES (3446,'Zytomyr','UKR','Zytomyr',297000);
+INSERT INTO City VALUES (3447,'Sumy','UKR','Sumy',294000);
+INSERT INTO City VALUES (3448,'Dniprodzerzynsk','UKR','Dnipropetrovsk',270000);
+INSERT INTO City VALUES (3449,'Kirovograd','UKR','Kirovograd',265000);
+INSERT INTO City VALUES (3450,'Hmelnytskyi','UKR','Hmelnytskyi',262000);
+INSERT INTO City VALUES (3451,'Tšernivtsi','UKR','Tšernivtsi',259000);
+INSERT INTO City VALUES (3452,'Rivne','UKR','Rivne',245000);
+INSERT INTO City VALUES (3453,'Krementšuk','UKR','Pultava',239000);
+INSERT INTO City VALUES (3454,'Ivano-Frankivsk','UKR','Ivano-Frankivsk',237000);
+INSERT INTO City VALUES (3455,'Ternopil','UKR','Ternopil',236000);
+INSERT INTO City VALUES (3456,'Lutsk','UKR','Volynia',217000);
+INSERT INTO City VALUES (3457,'Bila Tserkva','UKR','Kiova',215000);
+INSERT INTO City VALUES (3458,'Kramatorsk','UKR','Donetsk',186000);
+INSERT INTO City VALUES (3459,'Melitopol','UKR','Zaporizzja',169000);
+INSERT INTO City VALUES (3460,'Kertš','UKR','Krim',162000);
+INSERT INTO City VALUES (3461,'Nikopol','UKR','Dnipropetrovsk',149000);
+INSERT INTO City VALUES (3462,'Berdjansk','UKR','Zaporizzja',130000);
+INSERT INTO City VALUES (3463,'Pavlograd','UKR','Dnipropetrovsk',127000);
+INSERT INTO City VALUES (3464,'Sjeverodonetsk','UKR','Lugansk',127000);
+INSERT INTO City VALUES (3465,'Slovjansk','UKR','Donetsk',127000);
+INSERT INTO City VALUES (3466,'Uzgorod','UKR','Taka-Karpatia',127000);
+INSERT INTO City VALUES (3467,'Altševsk','UKR','Lugansk',119000);
+INSERT INTO City VALUES (3468,'Lysytšansk','UKR','Lugansk',116000);
+INSERT INTO City VALUES (3469,'Jevpatorija','UKR','Krim',112000);
+INSERT INTO City VALUES (3470,'Kamjanets-Podilskyi','UKR','Hmelnytskyi',109000);
+INSERT INTO City VALUES (3471,'Jenakijeve','UKR','Donetsk',105000);
+INSERT INTO City VALUES (3472,'Krasnyi Lutš','UKR','Lugansk',101000);
+INSERT INTO City VALUES (3473,'Stahanov','UKR','Lugansk',101000);
+INSERT INTO City VALUES (3474,'Oleksandrija','UKR','Kirovograd',99000);
+INSERT INTO City VALUES (3475,'Konotop','UKR','Sumy',96000);
+INSERT INTO City VALUES (3476,'Kostjantynivka','UKR','Donetsk',95000);
+INSERT INTO City VALUES (3477,'Berdytšiv','UKR','Zytomyr',90000);
+INSERT INTO City VALUES (3478,'Izmajil','UKR','Odesa',90000);
+INSERT INTO City VALUES (3479,'Šostka','UKR','Sumy',90000);
+INSERT INTO City VALUES (3480,'Uman','UKR','Tšerkasy',90000);
+INSERT INTO City VALUES (3481,'Brovary','UKR','Kiova',89000);
+INSERT INTO City VALUES (3482,'Mukatševe','UKR','Taka-Karpatia',89000);
+INSERT INTO City VALUES (3483,'Budapest','HUN','Budapest',1811552);
+INSERT INTO City VALUES (3484,'Debrecen','HUN','Hajdú-Bihar',203648);
+INSERT INTO City VALUES (3485,'Miskolc','HUN','Borsod-Abaúj-Zemplén',172357);
+INSERT INTO City VALUES (3486,'Szeged','HUN','Csongrád',158158);
+INSERT INTO City VALUES (3487,'Pécs','HUN','Baranya',157332);
+INSERT INTO City VALUES (3488,'Györ','HUN','Györ-Moson-Sopron',127119);
+INSERT INTO City VALUES (3489,'Nyiregyháza','HUN','Szabolcs-Szatmár-Ber',112419);
+INSERT INTO City VALUES (3490,'Kecskemét','HUN','Bács-Kiskun',105606);
+INSERT INTO City VALUES (3491,'Székesfehérvár','HUN','Fejér',105119);
+INSERT INTO City VALUES (3492,'Montevideo','URY','Montevideo',1236000);
+INSERT INTO City VALUES (3493,'Nouméa','NCL','–',76293);
+INSERT INTO City VALUES (3494,'Auckland','NZL','Auckland',381800);
+INSERT INTO City VALUES (3495,'Christchurch','NZL','Canterbury',324200);
+INSERT INTO City VALUES (3496,'Manukau','NZL','Auckland',281800);
+INSERT INTO City VALUES (3497,'North Shore','NZL','Auckland',187700);
+INSERT INTO City VALUES (3498,'Waitakere','NZL','Auckland',170600);
+INSERT INTO City VALUES (3499,'Wellington','NZL','Wellington',166700);
+INSERT INTO City VALUES (3500,'Dunedin','NZL','Dunedin',119600);
+INSERT INTO City VALUES (3501,'Hamilton','NZL','Hamilton',117100);
+INSERT INTO City VALUES (3502,'Lower Hutt','NZL','Wellington',98100);
+INSERT INTO City VALUES (3503,'Toskent','UZB','Toskent Shahri',2117500);
+INSERT INTO City VALUES (3504,'Namangan','UZB','Namangan',370500);
+INSERT INTO City VALUES (3505,'Samarkand','UZB','Samarkand',361800);
+INSERT INTO City VALUES (3506,'Andijon','UZB','Andijon',318600);
+INSERT INTO City VALUES (3507,'Buhoro','UZB','Buhoro',237100);
+INSERT INTO City VALUES (3508,'Karsi','UZB','Qashqadaryo',194100);
+INSERT INTO City VALUES (3509,'Nukus','UZB','Karakalpakistan',194100);
+INSERT INTO City VALUES (3510,'Kükon','UZB','Fargona',190100);
+INSERT INTO City VALUES (3511,'Fargona','UZB','Fargona',180500);
+INSERT INTO City VALUES (3512,'Circik','UZB','Toskent',146400);
+INSERT INTO City VALUES (3513,'Margilon','UZB','Fargona',140800);
+INSERT INTO City VALUES (3514,'Ürgenc','UZB','Khorazm',138900);
+INSERT INTO City VALUES (3515,'Angren','UZB','Toskent',128000);
+INSERT INTO City VALUES (3516,'Cizah','UZB','Cizah',124800);
+INSERT INTO City VALUES (3517,'Navoi','UZB','Navoi',116300);
+INSERT INTO City VALUES (3518,'Olmalik','UZB','Toskent',114900);
+INSERT INTO City VALUES (3519,'Termiz','UZB','Surkhondaryo',109500);
+INSERT INTO City VALUES (3520,'Minsk','BLR','Horad Minsk',1674000);
+INSERT INTO City VALUES (3521,'Gomel','BLR','Gomel',475000);
+INSERT INTO City VALUES (3522,'Mogiljov','BLR','Mogiljov',356000);
+INSERT INTO City VALUES (3523,'Vitebsk','BLR','Vitebsk',340000);
+INSERT INTO City VALUES (3524,'Grodno','BLR','Grodno',302000);
+INSERT INTO City VALUES (3525,'Brest','BLR','Brest',286000);
+INSERT INTO City VALUES (3526,'Bobruisk','BLR','Mogiljov',221000);
+INSERT INTO City VALUES (3527,'Baranovitši','BLR','Brest',167000);
+INSERT INTO City VALUES (3528,'Borisov','BLR','Minsk',151000);
+INSERT INTO City VALUES (3529,'Pinsk','BLR','Brest',130000);
+INSERT INTO City VALUES (3530,'Orša','BLR','Vitebsk',124000);
+INSERT INTO City VALUES (3531,'Mozyr','BLR','Gomel',110000);
+INSERT INTO City VALUES (3532,'Novopolotsk','BLR','Vitebsk',106000);
+INSERT INTO City VALUES (3533,'Lida','BLR','Grodno',101000);
+INSERT INTO City VALUES (3534,'Soligorsk','BLR','Minsk',101000);
+INSERT INTO City VALUES (3535,'Molodetšno','BLR','Minsk',97000);
+INSERT INTO City VALUES (3536,'Mata-Utu','WLF','Wallis',1137);
+INSERT INTO City VALUES (3537,'Port-Vila','VUT','Shefa',33700);
+INSERT INTO City VALUES (3538,'Città del Vaticano','VAT','–',455);
+INSERT INTO City VALUES (3539,'Caracas','VEN','Distrito Federal',1975294);
+INSERT INTO City VALUES (3540,'Maracaíbo','VEN','Zulia',1304776);
+INSERT INTO City VALUES (3541,'Barquisimeto','VEN','Lara',877239);
+INSERT INTO City VALUES (3542,'Valencia','VEN','Carabobo',794246);
+INSERT INTO City VALUES (3543,'Ciudad Guayana','VEN','Bolívar',663713);
+INSERT INTO City VALUES (3544,'Petare','VEN','Miranda',488868);
+INSERT INTO City VALUES (3545,'Maracay','VEN','Aragua',444443);
+INSERT INTO City VALUES (3546,'Barcelona','VEN','Anzoátegui',322267);
+INSERT INTO City VALUES (3547,'Maturín','VEN','Monagas',319726);
+INSERT INTO City VALUES (3548,'San Cristóbal','VEN','Táchira',319373);
+INSERT INTO City VALUES (3549,'Ciudad Bolívar','VEN','Bolívar',301107);
+INSERT INTO City VALUES (3550,'Cumaná','VEN','Sucre',293105);
+INSERT INTO City VALUES (3551,'Mérida','VEN','Mérida',224887);
+INSERT INTO City VALUES (3552,'Cabimas','VEN','Zulia',221329);
+INSERT INTO City VALUES (3553,'Barinas','VEN','Barinas',217831);
+INSERT INTO City VALUES (3554,'Turmero','VEN','Aragua',217499);
+INSERT INTO City VALUES (3555,'Baruta','VEN','Miranda',207290);
+INSERT INTO City VALUES (3556,'Puerto Cabello','VEN','Carabobo',187722);
+INSERT INTO City VALUES (3557,'Santa Ana de Coro','VEN','Falcón',185766);
+INSERT INTO City VALUES (3558,'Los Teques','VEN','Miranda',178784);
+INSERT INTO City VALUES (3559,'Punto Fijo','VEN','Falcón',167215);
+INSERT INTO City VALUES (3560,'Guarenas','VEN','Miranda',165889);
+INSERT INTO City VALUES (3561,'Acarigua','VEN','Portuguesa',158954);
+INSERT INTO City VALUES (3562,'Puerto La Cruz','VEN','Anzoátegui',155700);
+INSERT INTO City VALUES (3563,'Ciudad Losada','VEN','',134501);
+INSERT INTO City VALUES (3564,'Guacara','VEN','Carabobo',131334);
+INSERT INTO City VALUES (3565,'Valera','VEN','Trujillo',130281);
+INSERT INTO City VALUES (3566,'Guanare','VEN','Portuguesa',125621);
+INSERT INTO City VALUES (3567,'Carúpano','VEN','Sucre',119639);
+INSERT INTO City VALUES (3568,'Catia La Mar','VEN','Distrito Federal',117012);
+INSERT INTO City VALUES (3569,'El Tigre','VEN','Anzoátegui',116256);
+INSERT INTO City VALUES (3570,'Guatire','VEN','Miranda',109121);
+INSERT INTO City VALUES (3571,'Calabozo','VEN','Guárico',107146);
+INSERT INTO City VALUES (3572,'Pozuelos','VEN','Anzoátegui',105690);
+INSERT INTO City VALUES (3573,'Ciudad Ojeda','VEN','Zulia',99354);
+INSERT INTO City VALUES (3574,'Ocumare del Tuy','VEN','Miranda',97168);
+INSERT INTO City VALUES (3575,'Valle de la Pascua','VEN','Guárico',95927);
+INSERT INTO City VALUES (3576,'Araure','VEN','Portuguesa',94269);
+INSERT INTO City VALUES (3577,'San Fernando de Apure','VEN','Apure',93809);
+INSERT INTO City VALUES (3578,'San Felipe','VEN','Yaracuy',90940);
+INSERT INTO City VALUES (3579,'El Limón','VEN','Aragua',90000);
+INSERT INTO City VALUES (3580,'Moscow','RUS','Moscow (City)',8389200);
+INSERT INTO City VALUES (3581,'St Petersburg','RUS','Pietari',4694000);
+INSERT INTO City VALUES (3582,'Novosibirsk','RUS','Novosibirsk',1398800);
+INSERT INTO City VALUES (3583,'Nizni Novgorod','RUS','Nizni Novgorod',1357000);
+INSERT INTO City VALUES (3584,'Jekaterinburg','RUS','Sverdlovsk',1266300);
+INSERT INTO City VALUES (3585,'Samara','RUS','Samara',1156100);
+INSERT INTO City VALUES (3586,'Omsk','RUS','Omsk',1148900);
+INSERT INTO City VALUES (3587,'Kazan','RUS','Tatarstan',1101000);
+INSERT INTO City VALUES (3588,'Ufa','RUS','Baškortostan',1091200);
+INSERT INTO City VALUES (3589,'Tšeljabinsk','RUS','Tšeljabinsk',1083200);
+INSERT INTO City VALUES (3590,'Rostov-na-Donu','RUS','Rostov-na-Donu',1012700);
+INSERT INTO City VALUES (3591,'Perm','RUS','Perm',1009700);
+INSERT INTO City VALUES (3592,'Volgograd','RUS','Volgograd',993400);
+INSERT INTO City VALUES (3593,'Voronez','RUS','Voronez',907700);
+INSERT INTO City VALUES (3594,'Krasnojarsk','RUS','Krasnojarsk',875500);
+INSERT INTO City VALUES (3595,'Saratov','RUS','Saratov',874000);
+INSERT INTO City VALUES (3596,'Toljatti','RUS','Samara',722900);
+INSERT INTO City VALUES (3597,'Uljanovsk','RUS','Uljanovsk',667400);
+INSERT INTO City VALUES (3598,'Izevsk','RUS','Udmurtia',652800);
+INSERT INTO City VALUES (3599,'Krasnodar','RUS','Krasnodar',639000);
+INSERT INTO City VALUES (3600,'Jaroslavl','RUS','Jaroslavl',616700);
+INSERT INTO City VALUES (3601,'Habarovsk','RUS','Habarovsk',609400);
+INSERT INTO City VALUES (3602,'Vladivostok','RUS','Primorje',606200);
+INSERT INTO City VALUES (3603,'Irkutsk','RUS','Irkutsk',593700);
+INSERT INTO City VALUES (3604,'Barnaul','RUS','Altai',580100);
+INSERT INTO City VALUES (3605,'Novokuznetsk','RUS','Kemerovo',561600);
+INSERT INTO City VALUES (3606,'Penza','RUS','Penza',532200);
+INSERT INTO City VALUES (3607,'Rjazan','RUS','Rjazan',529900);
+INSERT INTO City VALUES (3608,'Orenburg','RUS','Orenburg',523600);
+INSERT INTO City VALUES (3609,'Lipetsk','RUS','Lipetsk',521000);
+INSERT INTO City VALUES (3610,'Nabereznyje Tšelny','RUS','Tatarstan',514700);
+INSERT INTO City VALUES (3611,'Tula','RUS','Tula',506100);
+INSERT INTO City VALUES (3612,'Tjumen','RUS','Tjumen',503400);
+INSERT INTO City VALUES (3613,'Kemerovo','RUS','Kemerovo',492700);
+INSERT INTO City VALUES (3614,'Astrahan','RUS','Astrahan',486100);
+INSERT INTO City VALUES (3615,'Tomsk','RUS','Tomsk',482100);
+INSERT INTO City VALUES (3616,'Kirov','RUS','Kirov',466200);
+INSERT INTO City VALUES (3617,'Ivanovo','RUS','Ivanovo',459200);
+INSERT INTO City VALUES (3618,'Tšeboksary','RUS','Tšuvassia',459200);
+INSERT INTO City VALUES (3619,'Brjansk','RUS','Brjansk',457400);
+INSERT INTO City VALUES (3620,'Tver','RUS','Tver',454900);
+INSERT INTO City VALUES (3621,'Kursk','RUS','Kursk',443500);
+INSERT INTO City VALUES (3622,'Magnitogorsk','RUS','Tšeljabinsk',427900);
+INSERT INTO City VALUES (3623,'Kaliningrad','RUS','Kaliningrad',424400);
+INSERT INTO City VALUES (3624,'Nizni Tagil','RUS','Sverdlovsk',390900);
+INSERT INTO City VALUES (3625,'Murmansk','RUS','Murmansk',376300);
+INSERT INTO City VALUES (3626,'Ulan-Ude','RUS','Burjatia',370400);
+INSERT INTO City VALUES (3627,'Kurgan','RUS','Kurgan',364700);
+INSERT INTO City VALUES (3628,'Arkangeli','RUS','Arkangeli',361800);
+INSERT INTO City VALUES (3629,'Sotši','RUS','Krasnodar',358600);
+INSERT INTO City VALUES (3630,'Smolensk','RUS','Smolensk',353400);
+INSERT INTO City VALUES (3631,'Orjol','RUS','Orjol',344500);
+INSERT INTO City VALUES (3632,'Stavropol','RUS','Stavropol',343300);
+INSERT INTO City VALUES (3633,'Belgorod','RUS','Belgorod',342000);
+INSERT INTO City VALUES (3634,'Kaluga','RUS','Kaluga',339300);
+INSERT INTO City VALUES (3635,'Vladimir','RUS','Vladimir',337100);
+INSERT INTO City VALUES (3636,'Mahatškala','RUS','Dagestan',332800);
+INSERT INTO City VALUES (3637,'Tšerepovets','RUS','Vologda',324400);
+INSERT INTO City VALUES (3638,'Saransk','RUS','Mordva',314800);
+INSERT INTO City VALUES (3639,'Tambov','RUS','Tambov',312000);
+INSERT INTO City VALUES (3640,'Vladikavkaz','RUS','North Ossetia-Alania',310100);
+INSERT INTO City VALUES (3641,'Tšita','RUS','Tšita',309900);
+INSERT INTO City VALUES (3642,'Vologda','RUS','Vologda',302500);
+INSERT INTO City VALUES (3643,'Veliki Novgorod','RUS','Novgorod',299500);
+INSERT INTO City VALUES (3644,'Komsomolsk-na-Amure','RUS','Habarovsk',291600);
+INSERT INTO City VALUES (3645,'Kostroma','RUS','Kostroma',288100);
+INSERT INTO City VALUES (3646,'Volzski','RUS','Volgograd',286900);
+INSERT INTO City VALUES (3647,'Taganrog','RUS','Rostov-na-Donu',284400);
+INSERT INTO City VALUES (3648,'Petroskoi','RUS','Karjala',282100);
+INSERT INTO City VALUES (3649,'Bratsk','RUS','Irkutsk',277600);
+INSERT INTO City VALUES (3650,'Dzerzinsk','RUS','Nizni Novgorod',277100);
+INSERT INTO City VALUES (3651,'Surgut','RUS','Hanti-Mansia',274900);
+INSERT INTO City VALUES (3652,'Orsk','RUS','Orenburg',273900);
+INSERT INTO City VALUES (3653,'Sterlitamak','RUS','Baškortostan',265200);
+INSERT INTO City VALUES (3654,'Angarsk','RUS','Irkutsk',264700);
+INSERT INTO City VALUES (3655,'Joškar-Ola','RUS','Marinmaa',249200);
+INSERT INTO City VALUES (3656,'Rybinsk','RUS','Jaroslavl',239600);
+INSERT INTO City VALUES (3657,'Prokopjevsk','RUS','Kemerovo',237300);
+INSERT INTO City VALUES (3658,'Niznevartovsk','RUS','Hanti-Mansia',233900);
+INSERT INTO City VALUES (3659,'Naltšik','RUS','Kabardi-Balkaria',233400);
+INSERT INTO City VALUES (3660,'Syktyvkar','RUS','Komi',229700);
+INSERT INTO City VALUES (3661,'Severodvinsk','RUS','Arkangeli',229300);
+INSERT INTO City VALUES (3662,'Bijsk','RUS','Altai',225000);
+INSERT INTO City VALUES (3663,'Niznekamsk','RUS','Tatarstan',223400);
+INSERT INTO City VALUES (3664,'Blagoveštšensk','RUS','Amur',222000);
+INSERT INTO City VALUES (3665,'Šahty','RUS','Rostov-na-Donu',221800);
+INSERT INTO City VALUES (3666,'Staryi Oskol','RUS','Belgorod',213800);
+INSERT INTO City VALUES (3667,'Zelenograd','RUS','Moscow (City)',207100);
+INSERT INTO City VALUES (3668,'Balakovo','RUS','Saratov',206000);
+INSERT INTO City VALUES (3669,'Novorossijsk','RUS','Krasnodar',203300);
+INSERT INTO City VALUES (3670,'Pihkova','RUS','Pihkova',201500);
+INSERT INTO City VALUES (3671,'Zlatoust','RUS','Tšeljabinsk',196900);
+INSERT INTO City VALUES (3672,'Jakutsk','RUS','Saha (Jakutia)',195400);
+INSERT INTO City VALUES (3673,'Podolsk','RUS','Moskova',194300);
+INSERT INTO City VALUES (3674,'Petropavlovsk-Kamtšatski','RUS','Kamtšatka',194100);
+INSERT INTO City VALUES (3675,'Kamensk-Uralski','RUS','Sverdlovsk',190600);
+INSERT INTO City VALUES (3676,'Engels','RUS','Saratov',189000);
+INSERT INTO City VALUES (3677,'Syzran','RUS','Samara',186900);
+INSERT INTO City VALUES (3678,'Grozny','RUS','Tšetšenia',186000);
+INSERT INTO City VALUES (3679,'Novotšerkassk','RUS','Rostov-na-Donu',184400);
+INSERT INTO City VALUES (3680,'Berezniki','RUS','Perm',181900);
+INSERT INTO City VALUES (3681,'Juzno-Sahalinsk','RUS','Sahalin',179200);
+INSERT INTO City VALUES (3682,'Volgodonsk','RUS','Rostov-na-Donu',178200);
+INSERT INTO City VALUES (3683,'Abakan','RUS','Hakassia',169200);
+INSERT INTO City VALUES (3684,'Maikop','RUS','Adygea',167300);
+INSERT INTO City VALUES (3685,'Miass','RUS','Tšeljabinsk',166200);
+INSERT INTO City VALUES (3686,'Armavir','RUS','Krasnodar',164900);
+INSERT INTO City VALUES (3687,'Ljubertsy','RUS','Moskova',163900);
+INSERT INTO City VALUES (3688,'Rubtsovsk','RUS','Altai',162600);
+INSERT INTO City VALUES (3689,'Kovrov','RUS','Vladimir',159900);
+INSERT INTO City VALUES (3690,'Nahodka','RUS','Primorje',157700);
+INSERT INTO City VALUES (3691,'Ussurijsk','RUS','Primorje',157300);
+INSERT INTO City VALUES (3692,'Salavat','RUS','Baškortostan',156800);
+INSERT INTO City VALUES (3693,'Mytištši','RUS','Moskova',155700);
+INSERT INTO City VALUES (3694,'Kolomna','RUS','Moskova',150700);
+INSERT INTO City VALUES (3695,'Elektrostal','RUS','Moskova',147000);
+INSERT INTO City VALUES (3696,'Murom','RUS','Vladimir',142400);
+INSERT INTO City VALUES (3697,'Kolpino','RUS','Pietari',141200);
+INSERT INTO City VALUES (3698,'Norilsk','RUS','Krasnojarsk',140800);
+INSERT INTO City VALUES (3699,'Almetjevsk','RUS','Tatarstan',140700);
+INSERT INTO City VALUES (3700,'Novomoskovsk','RUS','Tula',138100);
+INSERT INTO City VALUES (3701,'Dimitrovgrad','RUS','Uljanovsk',137000);
+INSERT INTO City VALUES (3702,'Pervouralsk','RUS','Sverdlovsk',136100);
+INSERT INTO City VALUES (3703,'Himki','RUS','Moskova',133700);
+INSERT INTO City VALUES (3704,'Balašiha','RUS','Moskova',132900);
+INSERT INTO City VALUES (3705,'Nevinnomyssk','RUS','Stavropol',132600);
+INSERT INTO City VALUES (3706,'Pjatigorsk','RUS','Stavropol',132500);
+INSERT INTO City VALUES (3707,'Korolev','RUS','Moskova',132400);
+INSERT INTO City VALUES (3708,'Serpuhov','RUS','Moskova',132000);
+INSERT INTO City VALUES (3709,'Odintsovo','RUS','Moskova',127400);
+INSERT INTO City VALUES (3710,'Orehovo-Zujevo','RUS','Moskova',124900);
+INSERT INTO City VALUES (3711,'Kamyšin','RUS','Volgograd',124600);
+INSERT INTO City VALUES (3712,'Novotšeboksarsk','RUS','Tšuvassia',123400);
+INSERT INTO City VALUES (3713,'Tšerkessk','RUS','Karatšai-Tšerkessia',121700);
+INSERT INTO City VALUES (3714,'Atšinsk','RUS','Krasnojarsk',121600);
+INSERT INTO City VALUES (3715,'Magadan','RUS','Magadan',121000);
+INSERT INTO City VALUES (3716,'Mitšurinsk','RUS','Tambov',120700);
+INSERT INTO City VALUES (3717,'Kislovodsk','RUS','Stavropol',120400);
+INSERT INTO City VALUES (3718,'Jelets','RUS','Lipetsk',119400);
+INSERT INTO City VALUES (3719,'Seversk','RUS','Tomsk',118600);
+INSERT INTO City VALUES (3720,'Noginsk','RUS','Moskova',117200);
+INSERT INTO City VALUES (3721,'Velikije Luki','RUS','Pihkova',116300);
+INSERT INTO City VALUES (3722,'Novokuibyševsk','RUS','Samara',116200);
+INSERT INTO City VALUES (3723,'Neftekamsk','RUS','Baškortostan',115700);
+INSERT INTO City VALUES (3724,'Leninsk-Kuznetski','RUS','Kemerovo',113800);
+INSERT INTO City VALUES (3725,'Oktjabrski','RUS','Baškortostan',111500);
+INSERT INTO City VALUES (3726,'Sergijev Posad','RUS','Moskova',111100);
+INSERT INTO City VALUES (3727,'Arzamas','RUS','Nizni Novgorod',110700);
+INSERT INTO City VALUES (3728,'Kiseljovsk','RUS','Kemerovo',110000);
+INSERT INTO City VALUES (3729,'Novotroitsk','RUS','Orenburg',109600);
+INSERT INTO City VALUES (3730,'Obninsk','RUS','Kaluga',108300);
+INSERT INTO City VALUES (3731,'Kansk','RUS','Krasnojarsk',107400);
+INSERT INTO City VALUES (3732,'Glazov','RUS','Udmurtia',106300);
+INSERT INTO City VALUES (3733,'Solikamsk','RUS','Perm',106000);
+INSERT INTO City VALUES (3734,'Sarapul','RUS','Udmurtia',105700);
+INSERT INTO City VALUES (3735,'Ust-Ilimsk','RUS','Irkutsk',105200);
+INSERT INTO City VALUES (3736,'Štšolkovo','RUS','Moskova',104900);
+INSERT INTO City VALUES (3737,'Mezduretšensk','RUS','Kemerovo',104400);
+INSERT INTO City VALUES (3738,'Usolje-Sibirskoje','RUS','Irkutsk',103500);
+INSERT INTO City VALUES (3739,'Elista','RUS','Kalmykia',103300);
+INSERT INTO City VALUES (3740,'Novošahtinsk','RUS','Rostov-na-Donu',101900);
+INSERT INTO City VALUES (3741,'Votkinsk','RUS','Udmurtia',101700);
+INSERT INTO City VALUES (3742,'Kyzyl','RUS','Tyva',101100);
+INSERT INTO City VALUES (3743,'Serov','RUS','Sverdlovsk',100400);
+INSERT INTO City VALUES (3744,'Zelenodolsk','RUS','Tatarstan',100200);
+INSERT INTO City VALUES (3745,'Zeleznodoroznyi','RUS','Moskova',100100);
+INSERT INTO City VALUES (3746,'Kinešma','RUS','Ivanovo',100000);
+INSERT INTO City VALUES (3747,'Kuznetsk','RUS','Penza',98200);
+INSERT INTO City VALUES (3748,'Uhta','RUS','Komi',98000);
+INSERT INTO City VALUES (3749,'Jessentuki','RUS','Stavropol',97900);
+INSERT INTO City VALUES (3750,'Tobolsk','RUS','Tjumen',97600);
+INSERT INTO City VALUES (3751,'Neftejugansk','RUS','Hanti-Mansia',97400);
+INSERT INTO City VALUES (3752,'Bataisk','RUS','Rostov-na-Donu',97300);
+INSERT INTO City VALUES (3753,'Nojabrsk','RUS','Yamalin Nenetsia',97300);
+INSERT INTO City VALUES (3754,'Balašov','RUS','Saratov',97100);
+INSERT INTO City VALUES (3755,'Zeleznogorsk','RUS','Kursk',96900);
+INSERT INTO City VALUES (3756,'Zukovski','RUS','Moskova',96500);
+INSERT INTO City VALUES (3757,'Anzero-Sudzensk','RUS','Kemerovo',96100);
+INSERT INTO City VALUES (3758,'Bugulma','RUS','Tatarstan',94100);
+INSERT INTO City VALUES (3759,'Zeleznogorsk','RUS','Krasnojarsk',94000);
+INSERT INTO City VALUES (3760,'Novouralsk','RUS','Sverdlovsk',93300);
+INSERT INTO City VALUES (3761,'Puškin','RUS','Pietari',92900);
+INSERT INTO City VALUES (3762,'Vorkuta','RUS','Komi',92600);
+INSERT INTO City VALUES (3763,'Derbent','RUS','Dagestan',92300);
+INSERT INTO City VALUES (3764,'Kirovo-Tšepetsk','RUS','Kirov',91600);
+INSERT INTO City VALUES (3765,'Krasnogorsk','RUS','Moskova',91000);
+INSERT INTO City VALUES (3766,'Klin','RUS','Moskova',90000);
+INSERT INTO City VALUES (3767,'Tšaikovski','RUS','Perm',90000);
+INSERT INTO City VALUES (3768,'Novyi Urengoi','RUS','Yamalin Nenetsia',89800);
+INSERT INTO City VALUES (3769,'Ho Chi Minh City','VNM','Ho Chi Minh City',3980000);
+INSERT INTO City VALUES (3770,'Hanoi','VNM','Hanoi',1410000);
+INSERT INTO City VALUES (3771,'Haiphong','VNM','Haiphong',783133);
+INSERT INTO City VALUES (3772,'Da Nang','VNM','Quang Nam-Da Nang',382674);
+INSERT INTO City VALUES (3773,'Biên Hoa','VNM','Dong Nai',282095);
+INSERT INTO City VALUES (3774,'Nha Trang','VNM','Khanh Hoa',221331);
+INSERT INTO City VALUES (3775,'Hue','VNM','Thua Thien-Hue',219149);
+INSERT INTO City VALUES (3776,'Can Tho','VNM','Can Tho',215587);
+INSERT INTO City VALUES (3777,'Cam Pha','VNM','Quang Binh',209086);
+INSERT INTO City VALUES (3778,'Nam Dinh','VNM','Nam Ha',171699);
+INSERT INTO City VALUES (3779,'Quy Nhon','VNM','Binh Dinh',163385);
+INSERT INTO City VALUES (3780,'Vung Tau','VNM','Ba Ria-Vung Tau',145145);
+INSERT INTO City VALUES (3781,'Rach Gia','VNM','Kien Giang',141132);
+INSERT INTO City VALUES (3782,'Long Xuyen','VNM','An Giang',132681);
+INSERT INTO City VALUES (3783,'Thai Nguyen','VNM','Bac Thai',127643);
+INSERT INTO City VALUES (3784,'Hong Gai','VNM','Quang Ninh',127484);
+INSERT INTO City VALUES (3785,'Phan Thiêt','VNM','Binh Thuan',114236);
+INSERT INTO City VALUES (3786,'Cam Ranh','VNM','Khanh Hoa',114041);
+INSERT INTO City VALUES (3787,'Vinh','VNM','Nghe An',112455);
+INSERT INTO City VALUES (3788,'My Tho','VNM','Tien Giang',108404);
+INSERT INTO City VALUES (3789,'Da Lat','VNM','Lam Dong',106409);
+INSERT INTO City VALUES (3790,'Buon Ma Thuot','VNM','Dac Lac',97044);
+INSERT INTO City VALUES (3791,'Tallinn','EST','Harjumaa',403981);
+INSERT INTO City VALUES (3792,'Tartu','EST','Tartumaa',101246);
+INSERT INTO City VALUES (3793,'New York','USA','New York',8008278);
+INSERT INTO City VALUES (3794,'Los Angeles','USA','California',3694820);
+INSERT INTO City VALUES (3795,'Chicago','USA','Illinois',2896016);
+INSERT INTO City VALUES (3796,'Houston','USA','Texas',1953631);
+INSERT INTO City VALUES (3797,'Philadelphia','USA','Pennsylvania',1517550);
+INSERT INTO City VALUES (3798,'Phoenix','USA','Arizona',1321045);
+INSERT INTO City VALUES (3799,'San Diego','USA','California',1223400);
+INSERT INTO City VALUES (3800,'Dallas','USA','Texas',1188580);
+INSERT INTO City VALUES (3801,'San Antonio','USA','Texas',1144646);
+INSERT INTO City VALUES (3802,'Detroit','USA','Michigan',951270);
+INSERT INTO City VALUES (3803,'San Jose','USA','California',894943);
+INSERT INTO City VALUES (3804,'Indianapolis','USA','Indiana',791926);
+INSERT INTO City VALUES (3805,'San Francisco','USA','California',776733);
+INSERT INTO City VALUES (3806,'Jacksonville','USA','Florida',735167);
+INSERT INTO City VALUES (3807,'Columbus','USA','Ohio',711470);
+INSERT INTO City VALUES (3808,'Austin','USA','Texas',656562);
+INSERT INTO City VALUES (3809,'Baltimore','USA','Maryland',651154);
+INSERT INTO City VALUES (3810,'Memphis','USA','Tennessee',650100);
+INSERT INTO City VALUES (3811,'Milwaukee','USA','Wisconsin',596974);
+INSERT INTO City VALUES (3812,'Boston','USA','Massachusetts',589141);
+INSERT INTO City VALUES (3813,'Washington','USA','District of Columbia',572059);
+INSERT INTO City VALUES (3814,'Nashville-Davidson','USA','Tennessee',569891);
+INSERT INTO City VALUES (3815,'El Paso','USA','Texas',563662);
+INSERT INTO City VALUES (3816,'Seattle','USA','Washington',563374);
+INSERT INTO City VALUES (3817,'Denver','USA','Colorado',554636);
+INSERT INTO City VALUES (3818,'Charlotte','USA','North Carolina',540828);
+INSERT INTO City VALUES (3819,'Fort Worth','USA','Texas',534694);
+INSERT INTO City VALUES (3820,'Portland','USA','Oregon',529121);
+INSERT INTO City VALUES (3821,'Oklahoma City','USA','Oklahoma',506132);
+INSERT INTO City VALUES (3822,'Tucson','USA','Arizona',486699);
+INSERT INTO City VALUES (3823,'New Orleans','USA','Louisiana',484674);
+INSERT INTO City VALUES (3824,'Las Vegas','USA','Nevada',478434);
+INSERT INTO City VALUES (3825,'Cleveland','USA','Ohio',478403);
+INSERT INTO City VALUES (3826,'Long Beach','USA','California',461522);
+INSERT INTO City VALUES (3827,'Albuquerque','USA','New Mexico',448607);
+INSERT INTO City VALUES (3828,'Kansas City','USA','Missouri',441545);
+INSERT INTO City VALUES (3829,'Fresno','USA','California',427652);
+INSERT INTO City VALUES (3830,'Virginia Beach','USA','Virginia',425257);
+INSERT INTO City VALUES (3831,'Atlanta','USA','Georgia',416474);
+INSERT INTO City VALUES (3832,'Sacramento','USA','California',407018);
+INSERT INTO City VALUES (3833,'Oakland','USA','California',399484);
+INSERT INTO City VALUES (3834,'Mesa','USA','Arizona',396375);
+INSERT INTO City VALUES (3835,'Tulsa','USA','Oklahoma',393049);
+INSERT INTO City VALUES (3836,'Omaha','USA','Nebraska',390007);
+INSERT INTO City VALUES (3837,'Minneapolis','USA','Minnesota',382618);
+INSERT INTO City VALUES (3838,'Honolulu','USA','Hawaii',371657);
+INSERT INTO City VALUES (3839,'Miami','USA','Florida',362470);
+INSERT INTO City VALUES (3840,'Colorado Springs','USA','Colorado',360890);
+INSERT INTO City VALUES (3841,'Saint Louis','USA','Missouri',348189);
+INSERT INTO City VALUES (3842,'Wichita','USA','Kansas',344284);
+INSERT INTO City VALUES (3843,'Santa Ana','USA','California',337977);
+INSERT INTO City VALUES (3844,'Pittsburgh','USA','Pennsylvania',334563);
+INSERT INTO City VALUES (3845,'Arlington','USA','Texas',332969);
+INSERT INTO City VALUES (3846,'Cincinnati','USA','Ohio',331285);
+INSERT INTO City VALUES (3847,'Anaheim','USA','California',328014);
+INSERT INTO City VALUES (3848,'Toledo','USA','Ohio',313619);
+INSERT INTO City VALUES (3849,'Tampa','USA','Florida',303447);
+INSERT INTO City VALUES (3850,'Buffalo','USA','New York',292648);
+INSERT INTO City VALUES (3851,'Saint Paul','USA','Minnesota',287151);
+INSERT INTO City VALUES (3852,'Corpus Christi','USA','Texas',277454);
+INSERT INTO City VALUES (3853,'Aurora','USA','Colorado',276393);
+INSERT INTO City VALUES (3854,'Raleigh','USA','North Carolina',276093);
+INSERT INTO City VALUES (3855,'Newark','USA','New Jersey',273546);
+INSERT INTO City VALUES (3856,'Lexington-Fayette','USA','Kentucky',260512);
+INSERT INTO City VALUES (3857,'Anchorage','USA','Alaska',260283);
+INSERT INTO City VALUES (3858,'Louisville','USA','Kentucky',256231);
+INSERT INTO City VALUES (3859,'Riverside','USA','California',255166);
+INSERT INTO City VALUES (3860,'Saint Petersburg','USA','Florida',248232);
+INSERT INTO City VALUES (3861,'Bakersfield','USA','California',247057);
+INSERT INTO City VALUES (3862,'Stockton','USA','California',243771);
+INSERT INTO City VALUES (3863,'Birmingham','USA','Alabama',242820);
+INSERT INTO City VALUES (3864,'Jersey City','USA','New Jersey',240055);
+INSERT INTO City VALUES (3865,'Norfolk','USA','Virginia',234403);
+INSERT INTO City VALUES (3866,'Baton Rouge','USA','Louisiana',227818);
+INSERT INTO City VALUES (3867,'Hialeah','USA','Florida',226419);
+INSERT INTO City VALUES (3868,'Lincoln','USA','Nebraska',225581);
+INSERT INTO City VALUES (3869,'Greensboro','USA','North Carolina',223891);
+INSERT INTO City VALUES (3870,'Plano','USA','Texas',222030);
+INSERT INTO City VALUES (3871,'Rochester','USA','New York',219773);
+INSERT INTO City VALUES (3872,'Glendale','USA','Arizona',218812);
+INSERT INTO City VALUES (3873,'Akron','USA','Ohio',217074);
+INSERT INTO City VALUES (3874,'Garland','USA','Texas',215768);
+INSERT INTO City VALUES (3875,'Madison','USA','Wisconsin',208054);
+INSERT INTO City VALUES (3876,'Fort Wayne','USA','Indiana',205727);
+INSERT INTO City VALUES (3877,'Fremont','USA','California',203413);
+INSERT INTO City VALUES (3878,'Scottsdale','USA','Arizona',202705);
+INSERT INTO City VALUES (3879,'Montgomery','USA','Alabama',201568);
+INSERT INTO City VALUES (3880,'Shreveport','USA','Louisiana',200145);
+INSERT INTO City VALUES (3881,'Augusta-Richmond County','USA','Georgia',199775);
+INSERT INTO City VALUES (3882,'Lubbock','USA','Texas',199564);
+INSERT INTO City VALUES (3883,'Chesapeake','USA','Virginia',199184);
+INSERT INTO City VALUES (3884,'Mobile','USA','Alabama',198915);
+INSERT INTO City VALUES (3885,'Des Moines','USA','Iowa',198682);
+INSERT INTO City VALUES (3886,'Grand Rapids','USA','Michigan',197800);
+INSERT INTO City VALUES (3887,'Richmond','USA','Virginia',197790);
+INSERT INTO City VALUES (3888,'Yonkers','USA','New York',196086);
+INSERT INTO City VALUES (3889,'Spokane','USA','Washington',195629);
+INSERT INTO City VALUES (3890,'Glendale','USA','California',194973);
+INSERT INTO City VALUES (3891,'Tacoma','USA','Washington',193556);
+INSERT INTO City VALUES (3892,'Irving','USA','Texas',191615);
+INSERT INTO City VALUES (3893,'Huntington Beach','USA','California',189594);
+INSERT INTO City VALUES (3894,'Modesto','USA','California',188856);
+INSERT INTO City VALUES (3895,'Durham','USA','North Carolina',187035);
+INSERT INTO City VALUES (3896,'Columbus','USA','Georgia',186291);
+INSERT INTO City VALUES (3897,'Orlando','USA','Florida',185951);
+INSERT INTO City VALUES (3898,'Boise City','USA','Idaho',185787);
+INSERT INTO City VALUES (3899,'Winston-Salem','USA','North Carolina',185776);
+INSERT INTO City VALUES (3900,'San Bernardino','USA','California',185401);
+INSERT INTO City VALUES (3901,'Jackson','USA','Mississippi',184256);
+INSERT INTO City VALUES (3902,'Little Rock','USA','Arkansas',183133);
+INSERT INTO City VALUES (3903,'Salt Lake City','USA','Utah',181743);
+INSERT INTO City VALUES (3904,'Reno','USA','Nevada',180480);
+INSERT INTO City VALUES (3905,'Newport News','USA','Virginia',180150);
+INSERT INTO City VALUES (3906,'Chandler','USA','Arizona',176581);
+INSERT INTO City VALUES (3907,'Laredo','USA','Texas',176576);
+INSERT INTO City VALUES (3908,'Henderson','USA','Nevada',175381);
+INSERT INTO City VALUES (3909,'Arlington','USA','Virginia',174838);
+INSERT INTO City VALUES (3910,'Knoxville','USA','Tennessee',173890);
+INSERT INTO City VALUES (3911,'Amarillo','USA','Texas',173627);
+INSERT INTO City VALUES (3912,'Providence','USA','Rhode Island',173618);
+INSERT INTO City VALUES (3913,'Chula Vista','USA','California',173556);
+INSERT INTO City VALUES (3914,'Worcester','USA','Massachusetts',172648);
+INSERT INTO City VALUES (3915,'Oxnard','USA','California',170358);
+INSERT INTO City VALUES (3916,'Dayton','USA','Ohio',166179);
+INSERT INTO City VALUES (3917,'Garden Grove','USA','California',165196);
+INSERT INTO City VALUES (3918,'Oceanside','USA','California',161029);
+INSERT INTO City VALUES (3919,'Tempe','USA','Arizona',158625);
+INSERT INTO City VALUES (3920,'Huntsville','USA','Alabama',158216);
+INSERT INTO City VALUES (3921,'Ontario','USA','California',158007);
+INSERT INTO City VALUES (3922,'Chattanooga','USA','Tennessee',155554);
+INSERT INTO City VALUES (3923,'Fort Lauderdale','USA','Florida',152397);
+INSERT INTO City VALUES (3924,'Springfield','USA','Massachusetts',152082);
+INSERT INTO City VALUES (3925,'Springfield','USA','Missouri',151580);
+INSERT INTO City VALUES (3926,'Santa Clarita','USA','California',151088);
+INSERT INTO City VALUES (3927,'Salinas','USA','California',151060);
+INSERT INTO City VALUES (3928,'Tallahassee','USA','Florida',150624);
+INSERT INTO City VALUES (3929,'Rockford','USA','Illinois',150115);
+INSERT INTO City VALUES (3930,'Pomona','USA','California',149473);
+INSERT INTO City VALUES (3931,'Metairie','USA','Louisiana',149428);
+INSERT INTO City VALUES (3932,'Paterson','USA','New Jersey',149222);
+INSERT INTO City VALUES (3933,'Overland Park','USA','Kansas',149080);
+INSERT INTO City VALUES (3934,'Santa Rosa','USA','California',147595);
+INSERT INTO City VALUES (3935,'Syracuse','USA','New York',147306);
+INSERT INTO City VALUES (3936,'Kansas City','USA','Kansas',146866);
+INSERT INTO City VALUES (3937,'Hampton','USA','Virginia',146437);
+INSERT INTO City VALUES (3938,'Lakewood','USA','Colorado',144126);
+INSERT INTO City VALUES (3939,'Vancouver','USA','Washington',143560);
+INSERT INTO City VALUES (3940,'Irvine','USA','California',143072);
+INSERT INTO City VALUES (3941,'Aurora','USA','Illinois',142990);
+INSERT INTO City VALUES (3942,'Moreno Valley','USA','California',142381);
+INSERT INTO City VALUES (3943,'Pasadena','USA','California',141674);
+INSERT INTO City VALUES (3944,'Hayward','USA','California',140030);
+INSERT INTO City VALUES (3945,'Brownsville','USA','Texas',139722);
+INSERT INTO City VALUES (3946,'Bridgeport','USA','Connecticut',139529);
+INSERT INTO City VALUES (3947,'Hollywood','USA','Florida',139357);
+INSERT INTO City VALUES (3948,'Warren','USA','Michigan',138247);
+INSERT INTO City VALUES (3949,'Torrance','USA','California',137946);
+INSERT INTO City VALUES (3950,'Eugene','USA','Oregon',137893);
+INSERT INTO City VALUES (3951,'Pembroke Pines','USA','Florida',137427);
+INSERT INTO City VALUES (3952,'Salem','USA','Oregon',136924);
+INSERT INTO City VALUES (3953,'Pasadena','USA','Texas',133936);
+INSERT INTO City VALUES (3954,'Escondido','USA','California',133559);
+INSERT INTO City VALUES (3955,'Sunnyvale','USA','California',131760);
+INSERT INTO City VALUES (3956,'Savannah','USA','Georgia',131510);
+INSERT INTO City VALUES (3957,'Fontana','USA','California',128929);
+INSERT INTO City VALUES (3958,'Orange','USA','California',128821);
+INSERT INTO City VALUES (3959,'Naperville','USA','Illinois',128358);
+INSERT INTO City VALUES (3960,'Alexandria','USA','Virginia',128283);
+INSERT INTO City VALUES (3961,'Rancho Cucamonga','USA','California',127743);
+INSERT INTO City VALUES (3962,'Grand Prairie','USA','Texas',127427);
+INSERT INTO City VALUES (3963,'East Los Angeles','USA','California',126379);
+INSERT INTO City VALUES (3964,'Fullerton','USA','California',126003);
+INSERT INTO City VALUES (3965,'Corona','USA','California',124966);
+INSERT INTO City VALUES (3966,'Flint','USA','Michigan',124943);
+INSERT INTO City VALUES (3967,'Paradise','USA','Nevada',124682);
+INSERT INTO City VALUES (3968,'Mesquite','USA','Texas',124523);
+INSERT INTO City VALUES (3969,'Sterling Heights','USA','Michigan',124471);
+INSERT INTO City VALUES (3970,'Sioux Falls','USA','South Dakota',123975);
+INSERT INTO City VALUES (3971,'New Haven','USA','Connecticut',123626);
+INSERT INTO City VALUES (3972,'Topeka','USA','Kansas',122377);
+INSERT INTO City VALUES (3973,'Concord','USA','California',121780);
+INSERT INTO City VALUES (3974,'Evansville','USA','Indiana',121582);
+INSERT INTO City VALUES (3975,'Hartford','USA','Connecticut',121578);
+INSERT INTO City VALUES (3976,'Fayetteville','USA','North Carolina',121015);
+INSERT INTO City VALUES (3977,'Cedar Rapids','USA','Iowa',120758);
+INSERT INTO City VALUES (3978,'Elizabeth','USA','New Jersey',120568);
+INSERT INTO City VALUES (3979,'Lansing','USA','Michigan',119128);
+INSERT INTO City VALUES (3980,'Lancaster','USA','California',118718);
+INSERT INTO City VALUES (3981,'Fort Collins','USA','Colorado',118652);
+INSERT INTO City VALUES (3982,'Coral Springs','USA','Florida',117549);
+INSERT INTO City VALUES (3983,'Stamford','USA','Connecticut',117083);
+INSERT INTO City VALUES (3984,'Thousand Oaks','USA','California',117005);
+INSERT INTO City VALUES (3985,'Vallejo','USA','California',116760);
+INSERT INTO City VALUES (3986,'Palmdale','USA','California',116670);
+INSERT INTO City VALUES (3987,'Columbia','USA','South Carolina',116278);
+INSERT INTO City VALUES (3988,'El Monte','USA','California',115965);
+INSERT INTO City VALUES (3989,'Abilene','USA','Texas',115930);
+INSERT INTO City VALUES (3990,'North Las Vegas','USA','Nevada',115488);
+INSERT INTO City VALUES (3991,'Ann Arbor','USA','Michigan',114024);
+INSERT INTO City VALUES (3992,'Beaumont','USA','Texas',113866);
+INSERT INTO City VALUES (3993,'Waco','USA','Texas',113726);
+INSERT INTO City VALUES (3994,'Macon','USA','Georgia',113336);
+INSERT INTO City VALUES (3995,'Independence','USA','Missouri',113288);
+INSERT INTO City VALUES (3996,'Peoria','USA','Illinois',112936);
+INSERT INTO City VALUES (3997,'Inglewood','USA','California',112580);
+INSERT INTO City VALUES (3998,'Springfield','USA','Illinois',111454);
+INSERT INTO City VALUES (3999,'Simi Valley','USA','California',111351);
+INSERT INTO City VALUES (4000,'Lafayette','USA','Louisiana',110257);
+INSERT INTO City VALUES (4001,'Gilbert','USA','Arizona',109697);
+INSERT INTO City VALUES (4002,'Carrollton','USA','Texas',109576);
+INSERT INTO City VALUES (4003,'Bellevue','USA','Washington',109569);
+INSERT INTO City VALUES (4004,'West Valley City','USA','Utah',108896);
+INSERT INTO City VALUES (4005,'Clarksville','USA','Tennessee',108787);
+INSERT INTO City VALUES (4006,'Costa Mesa','USA','California',108724);
+INSERT INTO City VALUES (4007,'Peoria','USA','Arizona',108364);
+INSERT INTO City VALUES (4008,'South Bend','USA','Indiana',107789);
+INSERT INTO City VALUES (4009,'Downey','USA','California',107323);
+INSERT INTO City VALUES (4010,'Waterbury','USA','Connecticut',107271);
+INSERT INTO City VALUES (4011,'Manchester','USA','New Hampshire',107006);
+INSERT INTO City VALUES (4012,'Allentown','USA','Pennsylvania',106632);
+INSERT INTO City VALUES (4013,'McAllen','USA','Texas',106414);
+INSERT INTO City VALUES (4014,'Joliet','USA','Illinois',106221);
+INSERT INTO City VALUES (4015,'Lowell','USA','Massachusetts',105167);
+INSERT INTO City VALUES (4016,'Provo','USA','Utah',105166);
+INSERT INTO City VALUES (4017,'West Covina','USA','California',105080);
+INSERT INTO City VALUES (4018,'Wichita Falls','USA','Texas',104197);
+INSERT INTO City VALUES (4019,'Erie','USA','Pennsylvania',103717);
+INSERT INTO City VALUES (4020,'Daly City','USA','California',103621);
+INSERT INTO City VALUES (4021,'Citrus Heights','USA','California',103455);
+INSERT INTO City VALUES (4022,'Norwalk','USA','California',103298);
+INSERT INTO City VALUES (4023,'Gary','USA','Indiana',102746);
+INSERT INTO City VALUES (4024,'Berkeley','USA','California',102743);
+INSERT INTO City VALUES (4025,'Santa Clara','USA','California',102361);
+INSERT INTO City VALUES (4026,'Green Bay','USA','Wisconsin',102313);
+INSERT INTO City VALUES (4027,'Cape Coral','USA','Florida',102286);
+INSERT INTO City VALUES (4028,'Arvada','USA','Colorado',102153);
+INSERT INTO City VALUES (4029,'Pueblo','USA','Colorado',102121);
+INSERT INTO City VALUES (4030,'Sandy','USA','Utah',101853);
+INSERT INTO City VALUES (4031,'Athens-Clarke County','USA','Georgia',101489);
+INSERT INTO City VALUES (4032,'Cambridge','USA','Massachusetts',101355);
+INSERT INTO City VALUES (4033,'Westminster','USA','Colorado',100940);
+INSERT INTO City VALUES (4034,'San Buenaventura','USA','California',100916);
+INSERT INTO City VALUES (4035,'Portsmouth','USA','Virginia',100565);
+INSERT INTO City VALUES (4036,'Livonia','USA','Michigan',100545);
+INSERT INTO City VALUES (4037,'Burbank','USA','California',100316);
+INSERT INTO City VALUES (4038,'Clearwater','USA','Florida',99936);
+INSERT INTO City VALUES (4039,'Midland','USA','Texas',98293);
+INSERT INTO City VALUES (4040,'Davenport','USA','Iowa',98256);
+INSERT INTO City VALUES (4041,'Mission Viejo','USA','California',98049);
+INSERT INTO City VALUES (4042,'Miami Beach','USA','Florida',97855);
+INSERT INTO City VALUES (4043,'Sunrise Manor','USA','Nevada',95362);
+INSERT INTO City VALUES (4044,'New Bedford','USA','Massachusetts',94780);
+INSERT INTO City VALUES (4045,'El Cajon','USA','California',94578);
+INSERT INTO City VALUES (4046,'Norman','USA','Oklahoma',94193);
+INSERT INTO City VALUES (4047,'Richmond','USA','California',94100);
+INSERT INTO City VALUES (4048,'Albany','USA','New York',93994);
+INSERT INTO City VALUES (4049,'Brockton','USA','Massachusetts',93653);
+INSERT INTO City VALUES (4050,'Roanoke','USA','Virginia',93357);
+INSERT INTO City VALUES (4051,'Billings','USA','Montana',92988);
+INSERT INTO City VALUES (4052,'Compton','USA','California',92864);
+INSERT INTO City VALUES (4053,'Gainesville','USA','Florida',92291);
+INSERT INTO City VALUES (4054,'Fairfield','USA','California',92256);
+INSERT INTO City VALUES (4055,'Arden-Arcade','USA','California',92040);
+INSERT INTO City VALUES (4056,'San Mateo','USA','California',91799);
+INSERT INTO City VALUES (4057,'Visalia','USA','California',91762);
+INSERT INTO City VALUES (4058,'Boulder','USA','Colorado',91238);
+INSERT INTO City VALUES (4059,'Cary','USA','North Carolina',91213);
+INSERT INTO City VALUES (4060,'Santa Monica','USA','California',91084);
+INSERT INTO City VALUES (4061,'Fall River','USA','Massachusetts',90555);
+INSERT INTO City VALUES (4062,'Kenosha','USA','Wisconsin',89447);
+INSERT INTO City VALUES (4063,'Elgin','USA','Illinois',89408);
+INSERT INTO City VALUES (4064,'Odessa','USA','Texas',89293);
+INSERT INTO City VALUES (4065,'Carson','USA','California',89089);
+INSERT INTO City VALUES (4066,'Charleston','USA','South Carolina',89063);
+INSERT INTO City VALUES (4067,'Charlotte Amalie','VIR','St Thomas',13000);
+INSERT INTO City VALUES (4068,'Harare','ZWE','Harare',1410000);
+INSERT INTO City VALUES (4069,'Bulawayo','ZWE','Bulawayo',621742);
+INSERT INTO City VALUES (4070,'Chitungwiza','ZWE','Harare',274912);
+INSERT INTO City VALUES (4071,'Mount Darwin','ZWE','Harare',164362);
+INSERT INTO City VALUES (4072,'Mutare','ZWE','Manicaland',131367);
+INSERT INTO City VALUES (4073,'Gweru','ZWE','Midlands',128037);
+INSERT INTO City VALUES (4074,'Gaza','PSE','Gaza',353632);
+INSERT INTO City VALUES (4075,'Khan Yunis','PSE','Khan Yunis',123175);
+INSERT INTO City VALUES (4076,'Hebron','PSE','Hebron',119401);
+INSERT INTO City VALUES (4077,'Jabaliya','PSE','North Gaza',113901);
+INSERT INTO City VALUES (4078,'Nablus','PSE','Nablus',100231);
+INSERT INTO City VALUES (4079,'Rafah','PSE','Rafah',92020);
+
+/*!40000 ALTER TABLE City ENABLE KEYS */;
+
+--
+-- Table structure for table 'Country'
+--
+
+CREATE TABLE Country (
+ Code char(3) NOT NULL default '',
+ Name char(52) NOT NULL default '',
+ Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+ Region char(26) NOT NULL default '',
+ SurfaceArea float(10,2) NOT NULL default '0.00',
+ IndepYear smallint(6) default NULL,
+ Population int(11) NOT NULL default '0',
+ LifeExpectancy float(3,1) default NULL,
+ GNP float(10,2) default NULL,
+ GNPOld float(10,2) default NULL,
+ LocalName char(45) NOT NULL default '',
+ GovernmentForm char(45) NOT NULL default '',
+ HeadOfState char(60) default NULL,
+ Capital int(11) default NULL,
+ Code2 char(2) NOT NULL default '',
+ PRIMARY KEY (Code)
+) TYPE=MyISAM;
+
+/*!40000 ALTER TABLE Country DISABLE KEYS */;
+
+--
+-- Dumping data for table 'Country'
+--
+
+
+INSERT INTO Country VALUES ('AFG','Afghanistan','Asia','Southern and Central Asia',652090.00,1919,22720000,45.9,5976.00,NULL,'Afganistan/Afqanestan','Islamic Emirate','Mohammad Omar',1,'AF');
+INSERT INTO Country VALUES ('NLD','Netherlands','Europe','Western Europe',41526.00,1581,15864000,78.3,371362.00,360478.00,'Nederland','Constitutional Monarchy','Beatrix',5,'NL');
+INSERT INTO Country VALUES ('ANT','Netherlands Antilles','North America','Caribbean',800.00,0,217000,74.7,1941.00,NULL,'Nederlandse Antillen','Nonmetropolitan Territory of The Netherlands','Beatrix',33,'AN');
+INSERT INTO Country VALUES ('ALB','Albania','Europe','Southern Europe',28748.00,1912,3401200,71.6,3205.00,2500.00,'Shqipëria','Republic','Rexhep Mejdani',34,'AL');
+INSERT INTO Country VALUES ('DZA','Algeria','Africa','Northern Africa',2381741.00,1962,31471000,69.7,49982.00,46966.00,'Al-Jaza’ir/Algérie','Republic','Abdelaziz Bouteflika',35,'DZ');
+INSERT INTO Country VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
+INSERT INTO Country VALUES ('AND','Andorra','Europe','Southern Europe',468.00,1278,78000,83.5,1630.00,NULL,'Andorra','Parliamentary Coprincipality','',55,'AD');
+INSERT INTO Country VALUES ('AGO','Angola','Africa','Central Africa',1246700.00,1975,12878000,38.3,6648.00,7984.00,'Angola','Republic','José Eduardo dos Santos',56,'AO');
+INSERT INTO Country VALUES ('AIA','Anguilla','North America','Caribbean',96.00,0,8000,76.1,63.20,NULL,'Anguilla','Dependent Territory of the UK','Elisabeth II',62,'AI');
+INSERT INTO Country VALUES ('ATG','Antigua and Barbuda','North America','Caribbean',442.00,1981,68000,70.5,612.00,584.00,'Antigua and Barbuda','Constitutional Monarchy','Elisabeth II',63,'AG');
+INSERT INTO Country VALUES ('ARE','United Arab Emirates','Asia','Middle East',83600.00,1971,2441000,74.1,37966.00,36846.00,'Al-Imarat al-´Arabiya al-Muttahida','Emirate Federation','Zayid bin Sultan al-Nahayan',65,'AE');
+INSERT INTO Country VALUES ('ARG','Argentina','South America','South America',2780400.00,1816,37032000,75.1,340238.00,323310.00,'Argentina','Federal Republic','Fernando de la Rúa',69,'AR');
+INSERT INTO Country VALUES ('ARM','Armenia','Asia','Middle East',29800.00,1991,3520000,66.4,1813.00,1627.00,'Hajastan','Republic','Robert Kotšarjan',126,'AM');
+INSERT INTO Country VALUES ('ABW','Aruba','North America','Caribbean',193.00,0,103000,78.4,828.00,793.00,'Aruba','Nonmetropolitan Territory of The Netherlands','Beatrix',129,'AW');
+INSERT INTO Country VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO Country VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+INSERT INTO Country VALUES ('BHS','Bahamas','North America','Caribbean',13878.00,1973,307000,71.1,3527.00,3347.00,'The Bahamas','Constitutional Monarchy','Elisabeth II',148,'BS');
+INSERT INTO Country VALUES ('BHR','Bahrain','Asia','Middle East',694.00,1971,617000,73.0,6366.00,6097.00,'Al-Bahrayn','Monarchy (Emirate)','Hamad ibn Isa al-Khalifa',149,'BH');
+INSERT INTO Country VALUES ('BGD','Bangladesh','Asia','Southern and Central Asia',143998.00,1971,129155000,60.2,32852.00,31966.00,'Bangladesh','Republic','Shahabuddin Ahmad',150,'BD');
+INSERT INTO Country VALUES ('BRB','Barbados','North America','Caribbean',430.00,1966,270000,73.0,2223.00,2186.00,'Barbados','Constitutional Monarchy','Elisabeth II',174,'BB');
+INSERT INTO Country VALUES ('BEL','Belgium','Europe','Western Europe',30518.00,1830,10239000,77.8,249704.00,243948.00,'België/Belgique','Constitutional Monarchy, Federation','Albert II',179,'BE');
+INSERT INTO Country VALUES ('BLZ','Belize','North America','Central America',22696.00,1981,241000,70.9,630.00,616.00,'Belize','Constitutional Monarchy','Elisabeth II',185,'BZ');
+INSERT INTO Country VALUES ('BEN','Benin','Africa','Western Africa',112622.00,1960,6097000,50.2,2357.00,2141.00,'Bénin','Republic','Mathieu Kérékou',187,'BJ');
+INSERT INTO Country VALUES ('BMU','Bermuda','North America','North America',53.00,0,65000,76.9,2328.00,2190.00,'Bermuda','Dependent Territory of the UK','Elisabeth II',191,'BM');
+INSERT INTO Country VALUES ('BTN','Bhutan','Asia','Southern and Central Asia',47000.00,1910,2124000,52.4,372.00,383.00,'Druk-Yul','Monarchy','Jigme Singye Wangchuk',192,'BT');
+INSERT INTO Country VALUES ('BOL','Bolivia','South America','South America',1098581.00,1825,8329000,63.7,8571.00,7967.00,'Bolivia','Republic','Hugo Bánzer Suárez',194,'BO');
+INSERT INTO Country VALUES ('BIH','Bosnia and Herzegovina','Europe','Southern Europe',51197.00,1992,3972000,71.5,2841.00,NULL,'Bosna i Hercegovina','Federal Republic','Ante Jelavic',201,'BA');
+INSERT INTO Country VALUES ('BWA','Botswana','Africa','Southern Africa',581730.00,1966,1622000,39.3,4834.00,4935.00,'Botswana','Republic','Festus G. Mogae',204,'BW');
+INSERT INTO Country VALUES ('BRA','Brazil','South America','South America',8547403.00,1822,170115000,62.9,776739.00,804108.00,'Brasil','Federal Republic','Fernando Henrique Cardoso',211,'BR');
+INSERT INTO Country VALUES ('GBR','United Kingdom','Europe','British Islands',242900.00,1066,59623400,77.7,1378330.00,1296830.00,'United Kingdom','Constitutional Monarchy','Elisabeth II',456,'GB');
+INSERT INTO Country VALUES ('VGB','Virgin Islands, British','North America','Caribbean',151.00,0,21000,75.4,612.00,573.00,'British Virgin Islands','Dependent Territory of the UK','Elisabeth II',537,'VG');
+INSERT INTO Country VALUES ('BRN','Brunei','Asia','Southeast Asia',5765.00,1984,328000,73.6,11705.00,12460.00,'Brunei Darussalam','Monarchy (Sultanate)','Haji Hassan al-Bolkiah',538,'BN');
+INSERT INTO Country VALUES ('BGR','Bulgaria','Europe','Eastern Europe',110994.00,1908,8190900,70.9,12178.00,10169.00,'Balgarija','Republic','Petar Stojanov',539,'BG');
+INSERT INTO Country VALUES ('BFA','Burkina Faso','Africa','Western Africa',274000.00,1960,11937000,46.7,2425.00,2201.00,'Burkina Faso','Republic','Blaise Compaoré',549,'BF');
+INSERT INTO Country VALUES ('BDI','Burundi','Africa','Eastern Africa',27834.00,1962,6695000,46.2,903.00,982.00,'Burundi/Uburundi','Republic','Pierre Buyoya',552,'BI');
+INSERT INTO Country VALUES ('CYM','Cayman Islands','North America','Caribbean',264.00,0,38000,78.9,1263.00,1186.00,'Cayman Islands','Dependent Territory of the UK','Elisabeth II',553,'KY');
+INSERT INTO Country VALUES ('CHL','Chile','South America','South America',756626.00,1810,15211000,75.7,72949.00,75780.00,'Chile','Republic','Ricardo Lagos Escobar',554,'CL');
+INSERT INTO Country VALUES ('COK','Cook Islands','Oceania','Polynesia',236.00,0,20000,71.1,100.00,NULL,'The Cook Islands','Nonmetropolitan Territory of New Zealand','Elisabeth II',583,'CK');
+INSERT INTO Country VALUES ('CRI','Costa Rica','North America','Central America',51100.00,1821,4023000,75.8,10226.00,9757.00,'Costa Rica','Republic','Miguel Ángel Rodríguez Echeverría',584,'CR');
+INSERT INTO Country VALUES ('DJI','Djibouti','Africa','Eastern Africa',23200.00,1977,638000,50.8,382.00,373.00,'Djibouti/Jibuti','Republic','Ismail Omar Guelleh',585,'DJ');
+INSERT INTO Country VALUES ('DMA','Dominica','North America','Caribbean',751.00,1978,71000,73.4,256.00,243.00,'Dominica','Republic','Vernon Shaw',586,'DM');
+INSERT INTO Country VALUES ('DOM','Dominican Republic','North America','Caribbean',48511.00,1844,8495000,73.2,15846.00,15076.00,'República Dominicana','Republic','Hipólito Mejía Domínguez',587,'DO');
+INSERT INTO Country VALUES ('ECU','Ecuador','South America','South America',283561.00,1822,12646000,71.1,19770.00,19769.00,'Ecuador','Republic','Gustavo Noboa Bejarano',594,'EC');
+INSERT INTO Country VALUES ('EGY','Egypt','Africa','Northern Africa',1001449.00,1922,68470000,63.3,82710.00,75617.00,'Misr','Republic','Hosni Mubarak',608,'EG');
+INSERT INTO Country VALUES ('SLV','El Salvador','North America','Central America',21041.00,1841,6276000,69.7,11863.00,11203.00,'El Salvador','Republic','Francisco Guillermo Flores Pérez',645,'SV');
+INSERT INTO Country VALUES ('ERI','Eritrea','Africa','Eastern Africa',117600.00,1993,3850000,55.8,650.00,755.00,'Ertra','Republic','Isayas Afewerki [Isaias Afwerki]',652,'ER');
+INSERT INTO Country VALUES ('ESP','Spain','Europe','Southern Europe',505992.00,1492,39441700,78.8,553233.00,532031.00,'España','Constitutional Monarchy','Juan Carlos I',653,'ES');
+INSERT INTO Country VALUES ('ZAF','South Africa','Africa','Southern Africa',1221037.00,1910,40377000,51.1,116729.00,129092.00,'South Africa','Republic','Thabo Mbeki',716,'ZA');
+INSERT INTO Country VALUES ('ETH','Ethiopia','Africa','Eastern Africa',1104300.00,-1000,62565000,45.2,6353.00,6180.00,'YeItyop´iya','Republic','Negasso Gidada',756,'ET');
+INSERT INTO Country VALUES ('FLK','Falkland Islands','South America','South America',12173.00,0,2000,NULL,0.00,NULL,'Falkland Islands','Dependent Territory of the UK','Elisabeth II',763,'FK');
+INSERT INTO Country VALUES ('FJI','Fiji Islands','Oceania','Melanesia',18274.00,1970,817000,67.9,1536.00,2149.00,'Fiji Islands','Republic','Josefa Iloilo',764,'FJ');
+INSERT INTO Country VALUES ('PHL','Philippines','Asia','Southeast Asia',300000.00,1946,75967000,67.5,65107.00,82239.00,'Pilipinas','Republic','Gloria Macapagal-Arroyo',766,'PH');
+INSERT INTO Country VALUES ('FRO','Faroe Islands','Europe','Nordic Countries',1399.00,0,43000,78.4,0.00,NULL,'Føroyar','Part of Denmark','Margrethe II',901,'FO');
+INSERT INTO Country VALUES ('GAB','Gabon','Africa','Central Africa',267668.00,1960,1226000,50.1,5493.00,5279.00,'Le Gabon','Republic','Omar Bongo',902,'GA');
+INSERT INTO Country VALUES ('GMB','Gambia','Africa','Western Africa',11295.00,1965,1305000,53.2,320.00,325.00,'The Gambia','Republic','Yahya Jammeh',904,'GM');
+INSERT INTO Country VALUES ('GEO','Georgia','Asia','Middle East',69700.00,1991,4968000,64.5,6064.00,5924.00,'Sakartvelo','Republic','Eduard Ševardnadze',905,'GE');
+INSERT INTO Country VALUES ('GHA','Ghana','Africa','Western Africa',238533.00,1957,20212000,57.4,7137.00,6884.00,'Ghana','Republic','John Kufuor',910,'GH');
+INSERT INTO Country VALUES ('GIB','Gibraltar','Europe','Southern Europe',6.00,0,25000,79.0,258.00,NULL,'Gibraltar','Dependent Territory of the UK','Elisabeth II',915,'GI');
+INSERT INTO Country VALUES ('GRD','Grenada','North America','Caribbean',344.00,1974,94000,64.5,318.00,NULL,'Grenada','Constitutional Monarchy','Elisabeth II',916,'GD');
+INSERT INTO Country VALUES ('GRL','Greenland','North America','North America',2166090.00,0,56000,68.1,0.00,NULL,'Kalaallit Nunaat/Grønland','Part of Denmark','Margrethe II',917,'GL');
+INSERT INTO Country VALUES ('GLP','Guadeloupe','North America','Caribbean',1705.00,0,456000,77.0,3501.00,NULL,'Guadeloupe','Overseas Department of France','Jacques Chirac',919,'GP');
+INSERT INTO Country VALUES ('GUM','Guam','Oceania','Micronesia',549.00,0,168000,77.8,1197.00,1136.00,'Guam','US Territory','George W. Bush',921,'GU');
+INSERT INTO Country VALUES ('GTM','Guatemala','North America','Central America',108889.00,1821,11385000,66.2,19008.00,17797.00,'Guatemala','Republic','Alfonso Portillo Cabrera',922,'GT');
+INSERT INTO Country VALUES ('GIN','Guinea','Africa','Western Africa',245857.00,1958,7430000,45.6,2352.00,2383.00,'Guinée','Republic','Lansana Conté',926,'GN');
+INSERT INTO Country VALUES ('GNB','Guinea-Bissau','Africa','Western Africa',36125.00,1974,1213000,49.0,293.00,272.00,'Guiné-Bissau','Republic','Kumba Ialá',927,'GW');
+INSERT INTO Country VALUES ('GUY','Guyana','South America','South America',214969.00,1966,861000,64.0,722.00,743.00,'Guyana','Republic','Bharrat Jagdeo',928,'GY');
+INSERT INTO Country VALUES ('HTI','Haiti','North America','Caribbean',27750.00,1804,8222000,49.2,3459.00,3107.00,'Haïti/Dayti','Republic','Jean-Bertrand Aristide',929,'HT');
+INSERT INTO Country VALUES ('HND','Honduras','North America','Central America',112088.00,1838,6485000,69.9,5333.00,4697.00,'Honduras','Republic','Carlos Roberto Flores Facussé',933,'HN');
+INSERT INTO Country VALUES ('HKG','Hong Kong','Asia','Eastern Asia',1075.00,0,6782000,79.5,166448.00,173610.00,'Xianggang/Hong Kong','Special Administrative Region of China','Jiang Zemin',937,'HK');
+INSERT INTO Country VALUES ('SJM','Svalbard and Jan Mayen','Europe','Nordic Countries',62422.00,0,3200,NULL,0.00,NULL,'Svalbard og Jan Mayen','Dependent Territory of Norway','Harald V',938,'SJ');
+INSERT INTO Country VALUES ('IDN','Indonesia','Asia','Southeast Asia',1904569.00,1945,212107000,68.0,84982.00,215002.00,'Indonesia','Republic','Abdurrahman Wahid',939,'ID');
+INSERT INTO Country VALUES ('IND','India','Asia','Southern and Central Asia',3287263.00,1947,1013662000,62.5,447114.00,430572.00,'Bharat/India','Federal Republic','Kocheril Raman Narayanan',1109,'IN');
+INSERT INTO Country VALUES ('IRQ','Iraq','Asia','Middle East',438317.00,1932,23115000,66.5,11500.00,NULL,'Al-´Iraq','Republic','Saddam Hussein al-Takriti',1365,'IQ');
+INSERT INTO Country VALUES ('IRN','Iran','Asia','Southern and Central Asia',1648195.00,1906,67702000,69.7,195746.00,160151.00,'Iran','Islamic Republic','Ali Mohammad Khatami-Ardakani',1380,'IR');
+INSERT INTO Country VALUES ('IRL','Ireland','Europe','British Islands',70273.00,1921,3775100,76.8,75921.00,73132.00,'Ireland/Éire','Republic','Mary McAleese',1447,'IE');
+INSERT INTO Country VALUES ('ISL','Iceland','Europe','Nordic Countries',103000.00,1944,279000,79.4,8255.00,7474.00,'Ísland','Republic','Ólafur Ragnar Grímsson',1449,'IS');
+INSERT INTO Country VALUES ('ISR','Israel','Asia','Middle East',21056.00,1948,6217000,78.6,97477.00,98577.00,'Yisra’el/Isra’il','Republic','Moshe Katzav',1450,'IL');
+INSERT INTO Country VALUES ('ITA','Italy','Europe','Southern Europe',301316.00,1861,57680000,79.0,1161755.00,1145372.00,'Italia','Republic','Carlo Azeglio Ciampi',1464,'IT');
+INSERT INTO Country VALUES ('TMP','East Timor','Asia','Southeast Asia',14874.00,0,885000,46.0,0.00,NULL,'Timor Timur','Administrated by the UN','José Alexandre Gusmão',1522,'TP');
+INSERT INTO Country VALUES ('AUT','Austria','Europe','Western Europe',83859.00,1918,8091800,77.7,211860.00,206025.00,'Österreich','Federal Republic','Thomas Klestil',1523,'AT');
+INSERT INTO Country VALUES ('JAM','Jamaica','North America','Caribbean',10990.00,1962,2583000,75.2,6871.00,6722.00,'Jamaica','Constitutional Monarchy','Elisabeth II',1530,'JM');
+INSERT INTO Country VALUES ('JPN','Japan','Asia','Eastern Asia',377829.00,-660,126714000,80.7,3787042.00,4192638.00,'Nihon/Nippon','Constitutional Monarchy','Akihito',1532,'JP');
+INSERT INTO Country VALUES ('YEM','Yemen','Asia','Middle East',527968.00,1918,18112000,59.8,6041.00,5729.00,'Al-Yaman','Republic','Ali Abdallah Salih',1780,'YE');
+INSERT INTO Country VALUES ('JOR','Jordan','Asia','Middle East',88946.00,1946,5083000,77.4,7526.00,7051.00,'Al-Urdunn','Constitutional Monarchy','Abdullah II',1786,'JO');
+INSERT INTO Country VALUES ('CXR','Christmas Island','Oceania','Australia and New Zealand',135.00,0,2500,NULL,0.00,NULL,'Christmas Island','Territory of Australia','Elisabeth II',1791,'CX');
+INSERT INTO Country VALUES ('YUG','Yugoslavia','Europe','Southern Europe',102173.00,1918,10640000,72.4,17000.00,NULL,'Jugoslavija','Federal Republic','Vojislav Koštunica',1792,'YU');
+INSERT INTO Country VALUES ('KHM','Cambodia','Asia','Southeast Asia',181035.00,1953,11168000,56.5,5121.00,5670.00,'Kâmpuchéa','Constitutional Monarchy','Norodom Sihanouk',1800,'KH');
+INSERT INTO Country VALUES ('CMR','Cameroon','Africa','Central Africa',475442.00,1960,15085000,54.8,9174.00,8596.00,'Cameroun/Cameroon','Republic','Paul Biya',1804,'CM');
+INSERT INTO Country VALUES ('CAN','Canada','North America','North America',9970610.00,1867,31147000,79.4,598862.00,625626.00,'Canada','Constitutional Monarchy, Federation','Elisabeth II',1822,'CA');
+INSERT INTO Country VALUES ('CPV','Cape Verde','Africa','Western Africa',4033.00,1975,428000,68.9,435.00,420.00,'Cabo Verde','Republic','António Mascarenhas Monteiro',1859,'CV');
+INSERT INTO Country VALUES ('KAZ','Kazakstan','Asia','Southern and Central Asia',2724900.00,1991,16223000,63.2,24375.00,23383.00,'Qazaqstan','Republic','Nursultan Nazarbajev',1864,'KZ');
+INSERT INTO Country VALUES ('KEN','Kenya','Africa','Eastern Africa',580367.00,1963,30080000,48.0,9217.00,10241.00,'Kenya','Republic','Daniel arap Moi',1881,'KE');
+INSERT INTO Country VALUES ('CAF','Central African Republic','Africa','Central Africa',622984.00,1960,3615000,44.0,1054.00,993.00,'Centrafrique/Bê-Afrîka','Republic','Ange-Félix Patassé',1889,'CF');
+INSERT INTO Country VALUES ('CHN','China','Asia','Eastern Asia',9572900.00,-1523,1277558000,71.4,982268.00,917719.00,'Zhongquo','People\'sRepublic','Jiang Zemin',1891,'CN');
+INSERT INTO Country VALUES ('KGZ','Kyrgyzstan','Asia','Southern and Central Asia',199900.00,1991,4699000,63.4,1626.00,1767.00,'Kyrgyzstan','Republic','Askar Akajev',2253,'KG');
+INSERT INTO Country VALUES ('KIR','Kiribati','Oceania','Micronesia',726.00,1979,83000,59.8,40.70,NULL,'Kiribati','Republic','Teburoro Tito',2256,'KI');
+INSERT INTO Country VALUES ('COL','Colombia','South America','South America',1138914.00,1810,42321000,70.3,102896.00,105116.00,'Colombia','Republic','Andrés Pastrana Arango',2257,'CO');
+INSERT INTO Country VALUES ('COM','Comoros','Africa','Eastern Africa',1862.00,1975,578000,60.0,4401.00,4361.00,'Komori/Comores','Republic','Azali Assoumani',2295,'KM');
+INSERT INTO Country VALUES ('COG','Congo','Africa','Central Africa',342000.00,1960,2943000,47.4,2108.00,2287.00,'Congo','Republic','Denis Sassou-Nguesso',2296,'CG');
+INSERT INTO Country VALUES ('COD','Congo, The Democratic Republic of the','Africa','Central Africa',2344858.00,1960,51654000,48.8,6964.00,2474.00,'République Démocratique du Congo','Republic','Joseph Kabila',2298,'CD');
+INSERT INTO Country VALUES ('CCK','Cocos (Keeling) Islands','Oceania','Australia and New Zealand',14.00,0,600,NULL,0.00,NULL,'Cocos (Keeling) Islands','Territory of Australia','Elisabeth II',2317,'CC');
+INSERT INTO Country VALUES ('PRK','North Korea','Asia','Eastern Asia',120538.00,1948,24039000,70.7,5332.00,NULL,'Choson Minjujuui In´min Konghwaguk (Bukhan)','Socialistic Republic','Kim Jong-il',2318,'KP');
+INSERT INTO Country VALUES ('KOR','South Korea','Asia','Eastern Asia',99434.00,1948,46844000,74.4,320749.00,442544.00,'Taehan Min’guk (Namhan)','Republic','Kim Dae-jung',2331,'KR');
+INSERT INTO Country VALUES ('GRC','Greece','Europe','Southern Europe',131626.00,1830,10545700,78.4,120724.00,119946.00,'Elláda','Republic','Kostis Stefanopoulos',2401,'GR');
+INSERT INTO Country VALUES ('HRV','Croatia','Europe','Southern Europe',56538.00,1991,4473000,73.7,20208.00,19300.00,'Hrvatska','Republic','Štipe Mesic',2409,'HR');
+INSERT INTO Country VALUES ('CUB','Cuba','North America','Caribbean',110861.00,1902,11201000,76.2,17843.00,18862.00,'Cuba','Socialistic Republic','Fidel Castro Ruz',2413,'CU');
+INSERT INTO Country VALUES ('KWT','Kuwait','Asia','Middle East',17818.00,1961,1972000,76.1,27037.00,30373.00,'Al-Kuwayt','Constitutional Monarchy (Emirate)','Jabir al-Ahmad al-Jabir al-Sabah',2429,'KW');
+INSERT INTO Country VALUES ('CYP','Cyprus','Asia','Middle East',9251.00,1960,754700,76.7,9333.00,8246.00,'Kýpros/Kibris','Republic','Glafkos Klerides',2430,'CY');
+INSERT INTO Country VALUES ('LAO','Laos','Asia','Southeast Asia',236800.00,1953,5433000,53.1,1292.00,1746.00,'Lao','Republic','Khamtay Siphandone',2432,'LA');
+INSERT INTO Country VALUES ('LVA','Latvia','Europe','Baltic Countries',64589.00,1991,2424200,68.4,6398.00,5639.00,'Latvija','Republic','Vaira Vike-Freiberga',2434,'LV');
+INSERT INTO Country VALUES ('LSO','Lesotho','Africa','Southern Africa',30355.00,1966,2153000,50.8,1061.00,1161.00,'Lesotho','Constitutional Monarchy','Letsie III',2437,'LS');
+INSERT INTO Country VALUES ('LBN','Lebanon','Asia','Middle East',10400.00,1941,3282000,71.3,17121.00,15129.00,'Lubnan','Republic','Émile Lahoud',2438,'LB');
+INSERT INTO Country VALUES ('LBR','Liberia','Africa','Western Africa',111369.00,1847,3154000,51.0,2012.00,NULL,'Liberia','Republic','Charles Taylor',2440,'LR');
+INSERT INTO Country VALUES ('LBY','Libyan Arab Jamahiriya','Africa','Northern Africa',1759540.00,1951,5605000,75.5,44806.00,40562.00,'Libiya','Socialistic State','Muammar al-Qadhafi',2441,'LY');
+INSERT INTO Country VALUES ('LIE','Liechtenstein','Europe','Western Europe',160.00,1806,32300,78.8,1119.00,1084.00,'Liechtenstein','Constitutional Monarchy','Hans-Adam II',2446,'LI');
+INSERT INTO Country VALUES ('LTU','Lithuania','Europe','Baltic Countries',65301.00,1991,3698500,69.1,10692.00,9585.00,'Lietuva','Republic','Valdas Adamkus',2447,'LT');
+INSERT INTO Country VALUES ('LUX','Luxembourg','Europe','Western Europe',2586.00,1867,435700,77.1,16321.00,15519.00,'Luxembourg/Lëtzebuerg','Constitutional Monarchy','Henri',2452,'LU');
+INSERT INTO Country VALUES ('ESH','Western Sahara','Africa','Northern Africa',266000.00,0,293000,49.8,60.00,NULL,'As-Sahrawiya','Occupied by Marocco','Mohammed Abdel Aziz',2453,'EH');
+INSERT INTO Country VALUES ('MAC','Macao','Asia','Eastern Asia',18.00,0,473000,81.6,5749.00,5940.00,'Macau/Aomen','Special Administrative Region of China','Jiang Zemin',2454,'MO');
+INSERT INTO Country VALUES ('MDG','Madagascar','Africa','Eastern Africa',587041.00,1960,15942000,55.0,3750.00,3545.00,'Madagasikara/Madagascar','Federal Republic','Didier Ratsiraka',2455,'MG');
+INSERT INTO Country VALUES ('MKD','Macedonia','Europe','Southern Europe',25713.00,1991,2024000,73.8,1694.00,1915.00,'Makedonija','Republic','Boris Trajkovski',2460,'MK');
+INSERT INTO Country VALUES ('MWI','Malawi','Africa','Eastern Africa',118484.00,1964,10925000,37.6,1687.00,2527.00,'Malawi','Republic','Bakili Muluzi',2462,'MW');
+INSERT INTO Country VALUES ('MDV','Maldives','Asia','Southern and Central Asia',298.00,1965,286000,62.2,199.00,NULL,'Dhivehi Raajje/Maldives','Republic','Maumoon Abdul Gayoom',2463,'MV');
+INSERT INTO Country VALUES ('MYS','Malaysia','Asia','Southeast Asia',329758.00,1957,22244000,70.8,69213.00,97884.00,'Malaysia','Constitutional Monarchy, Federation','Salahuddin Abdul Aziz Shah Alhaj',2464,'MY');
+INSERT INTO Country VALUES ('MLI','Mali','Africa','Western Africa',1240192.00,1960,11234000,46.7,2642.00,2453.00,'Mali','Republic','Alpha Oumar Konaré',2482,'ML');
+INSERT INTO Country VALUES ('MLT','Malta','Europe','Southern Europe',316.00,1964,380200,77.9,3512.00,3338.00,'Malta','Republic','Guido de Marco',2484,'MT');
+INSERT INTO Country VALUES ('MAR','Morocco','Africa','Northern Africa',446550.00,1956,28351000,69.1,36124.00,33514.00,'Al-Maghrib','Constitutional Monarchy','Mohammed VI',2486,'MA');
+INSERT INTO Country VALUES ('MHL','Marshall Islands','Oceania','Micronesia',181.00,1990,64000,65.5,97.00,NULL,'Marshall Islands/Majol','Republic','Kessai Note',2507,'MH');
+INSERT INTO Country VALUES ('MTQ','Martinique','North America','Caribbean',1102.00,0,395000,78.3,2731.00,2559.00,'Martinique','Overseas Department of France','Jacques Chirac',2508,'MQ');
+INSERT INTO Country VALUES ('MRT','Mauritania','Africa','Western Africa',1025520.00,1960,2670000,50.8,998.00,1081.00,'Muritaniya/Mauritanie','Republic','Maaouiya Ould Sid´Ahmad Taya',2509,'MR');
+INSERT INTO Country VALUES ('MUS','Mauritius','Africa','Eastern Africa',2040.00,1968,1158000,71.0,4251.00,4186.00,'Mauritius','Republic','Cassam Uteem',2511,'MU');
+INSERT INTO Country VALUES ('MYT','Mayotte','Africa','Eastern Africa',373.00,0,149000,59.5,0.00,NULL,'Mayotte','Territorial Collectivity of France','Jacques Chirac',2514,'YT');
+INSERT INTO Country VALUES ('MEX','Mexico','North America','Central America',1958201.00,1810,98881000,71.5,414972.00,401461.00,'México','Federal Republic','Vicente Fox Quesada',2515,'MX');
+INSERT INTO Country VALUES ('FSM','Micronesia, Federated States of','Oceania','Micronesia',702.00,1990,119000,68.6,212.00,NULL,'Micronesia','Federal Republic','Leo A. Falcam',2689,'FM');
+INSERT INTO Country VALUES ('MDA','Moldova','Europe','Eastern Europe',33851.00,1991,4380000,64.5,1579.00,1872.00,'Moldova','Republic','Vladimir Voronin',2690,'MD');
+INSERT INTO Country VALUES ('MCO','Monaco','Europe','Western Europe',1.50,1861,34000,78.8,776.00,NULL,'Monaco','Constitutional Monarchy','Rainier III',2695,'MC');
+INSERT INTO Country VALUES ('MNG','Mongolia','Asia','Eastern Asia',1566500.00,1921,2662000,67.3,1043.00,933.00,'Mongol Uls','Republic','Natsagiin Bagabandi',2696,'MN');
+INSERT INTO Country VALUES ('MSR','Montserrat','North America','Caribbean',102.00,0,11000,78.0,109.00,NULL,'Montserrat','Dependent Territory of the UK','Elisabeth II',2697,'MS');
+INSERT INTO Country VALUES ('MOZ','Mozambique','Africa','Eastern Africa',801590.00,1975,19680000,37.5,2891.00,2711.00,'Moçambique','Republic','Joaquím A. Chissano',2698,'MZ');
+INSERT INTO Country VALUES ('MMR','Myanmar','Asia','Southeast Asia',676578.00,1948,45611000,54.9,180375.00,171028.00,'Myanma Pye','Republic','kenraali Than Shwe',2710,'MM');
+INSERT INTO Country VALUES ('NAM','Namibia','Africa','Southern Africa',824292.00,1990,1726000,42.5,3101.00,3384.00,'Namibia','Republic','Sam Nujoma',2726,'NA');
+INSERT INTO Country VALUES ('NRU','Nauru','Oceania','Micronesia',21.00,1968,12000,60.8,197.00,NULL,'Naoero/Nauru','Republic','Bernard Dowiyogo',2728,'NR');
+INSERT INTO Country VALUES ('NPL','Nepal','Asia','Southern and Central Asia',147181.00,1769,23930000,57.8,4768.00,4837.00,'Nepal','Constitutional Monarchy','Gyanendra Bir Bikram',2729,'NP');
+INSERT INTO Country VALUES ('NIC','Nicaragua','North America','Central America',130000.00,1838,5074000,68.7,1988.00,2023.00,'Nicaragua','Republic','Arnoldo Alemán Lacayo',2734,'NI');
+INSERT INTO Country VALUES ('NER','Niger','Africa','Western Africa',1267000.00,1960,10730000,41.3,1706.00,1580.00,'Niger','Republic','Mamadou Tandja',2738,'NE');
+INSERT INTO Country VALUES ('NGA','Nigeria','Africa','Western Africa',923768.00,1960,111506000,51.6,65707.00,58623.00,'Nigeria','Federal Republic','Olusegun Obasanjo',2754,'NG');
+INSERT INTO Country VALUES ('NIU','Niue','Oceania','Polynesia',260.00,0,2000,NULL,0.00,NULL,'Niue','Nonmetropolitan Territory of New Zealand','Elisabeth II',2805,'NU');
+INSERT INTO Country VALUES ('NFK','Norfolk Island','Oceania','Australia and New Zealand',36.00,0,2000,NULL,0.00,NULL,'Norfolk Island','Territory of Australia','Elisabeth II',2806,'NF');
+INSERT INTO Country VALUES ('NOR','Norway','Europe','Nordic Countries',323877.00,1905,4478500,78.7,145895.00,153370.00,'Norge','Constitutional Monarchy','Harald V',2807,'NO');
+INSERT INTO Country VALUES ('CIV','Côte d’Ivoire','Africa','Western Africa',322463.00,1960,14786000,45.2,11345.00,10285.00,'Côte d’Ivoire','Republic','Laurent Gbagbo',2814,'CI');
+INSERT INTO Country VALUES ('OMN','Oman','Asia','Middle East',309500.00,1951,2542000,71.8,16904.00,16153.00,'´Uman','Monarchy (Sultanate)','Qabus ibn Sa´id',2821,'OM');
+INSERT INTO Country VALUES ('PAK','Pakistan','Asia','Southern and Central Asia',796095.00,1947,156483000,61.1,61289.00,58549.00,'Pakistan','Republic','Mohammad Rafiq Tarar',2831,'PK');
+INSERT INTO Country VALUES ('PLW','Palau','Oceania','Micronesia',459.00,1994,19000,68.6,105.00,NULL,'Belau/Palau','Republic','Kuniwo Nakamura',2881,'PW');
+INSERT INTO Country VALUES ('PAN','Panama','North America','Central America',75517.00,1903,2856000,75.5,9131.00,8700.00,'Panamá','Republic','Mireya Elisa Moscoso Rodríguez',2882,'PA');
+INSERT INTO Country VALUES ('PNG','Papua New Guinea','Oceania','Melanesia',462840.00,1975,4807000,63.1,4988.00,6328.00,'Papua New Guinea/Papua Niugini','Constitutional Monarchy','Elisabeth II',2884,'PG');
+INSERT INTO Country VALUES ('PRY','Paraguay','South America','South America',406752.00,1811,5496000,73.7,8444.00,9555.00,'Paraguay','Republic','Luis Ángel González Macchi',2885,'PY');
+INSERT INTO Country VALUES ('PER','Peru','South America','South America',1285216.00,1821,25662000,70.0,64140.00,65186.00,'Perú/Piruw','Republic','Valentin Paniagua Corazao',2890,'PE');
+INSERT INTO Country VALUES ('PCN','Pitcairn','Oceania','Polynesia',49.00,0,50,NULL,0.00,NULL,'Pitcairn','Dependent Territory of the UK','Elisabeth II',2912,'PN');
+INSERT INTO Country VALUES ('MNP','Northern Mariana Islands','Oceania','Micronesia',464.00,0,78000,75.5,0.00,NULL,'Northern Mariana Islands','Commonwealth of the US','George W. Bush',2913,'MP');
+INSERT INTO Country VALUES ('PRT','Portugal','Europe','Southern Europe',91982.00,1143,9997600,75.8,105954.00,102133.00,'Portugal','Republic','Jorge Sampãio',2914,'PT');
+INSERT INTO Country VALUES ('PRI','Puerto Rico','North America','Caribbean',8875.00,0,3869000,75.6,34100.00,32100.00,'Puerto Rico','Commonwealth of the US','George W. Bush',2919,'PR');
+INSERT INTO Country VALUES ('POL','Poland','Europe','Eastern Europe',323250.00,1918,38653600,73.2,151697.00,135636.00,'Polska','Republic','Aleksander Kwasniewski',2928,'PL');
+INSERT INTO Country VALUES ('GNQ','Equatorial Guinea','Africa','Central Africa',28051.00,1968,453000,53.6,283.00,542.00,'Guinea Ecuatorial','Republic','Teodoro Obiang Nguema Mbasogo',2972,'GQ');
+INSERT INTO Country VALUES ('QAT','Qatar','Asia','Middle East',11000.00,1971,599000,72.4,9472.00,8920.00,'Qatar','Monarchy','Hamad ibn Khalifa al-Thani',2973,'QA');
+INSERT INTO Country VALUES ('FRA','France','Europe','Western Europe',551500.00,843,59225700,78.8,1424285.00,1392448.00,'France','Republic','Jacques Chirac',2974,'FR');
+INSERT INTO Country VALUES ('GUF','French Guiana','South America','South America',90000.00,0,181000,76.1,681.00,NULL,'Guyane française','Overseas Department of France','Jacques Chirac',3014,'GF');
+INSERT INTO Country VALUES ('PYF','French Polynesia','Oceania','Polynesia',4000.00,0,235000,74.8,818.00,781.00,'Polynésie française','Nonmetropolitan Territory of France','Jacques Chirac',3016,'PF');
+INSERT INTO Country VALUES ('REU','Réunion','Africa','Eastern Africa',2510.00,0,699000,72.7,8287.00,7988.00,'Réunion','Overseas Department of France','Jacques Chirac',3017,'RE');
+INSERT INTO Country VALUES ('ROM','Romania','Europe','Eastern Europe',238391.00,1878,22455500,69.9,38158.00,34843.00,'România','Republic','Ion Iliescu',3018,'RO');
+INSERT INTO Country VALUES ('RWA','Rwanda','Africa','Eastern Africa',26338.00,1962,7733000,39.3,2036.00,1863.00,'Rwanda/Urwanda','Republic','Paul Kagame',3047,'RW');
+INSERT INTO Country VALUES ('SWE','Sweden','Europe','Nordic Countries',449964.00,836,8861400,79.6,226492.00,227757.00,'Sverige','Constitutional Monarchy','Carl XVI Gustaf',3048,'SE');
+INSERT INTO Country VALUES ('SHN','Saint Helena','Africa','Western Africa',314.00,0,6000,76.8,0.00,NULL,'Saint Helena','Dependent Territory of the UK','Elisabeth II',3063,'SH');
+INSERT INTO Country VALUES ('KNA','Saint Kitts and Nevis','North America','Caribbean',261.00,1983,38000,70.7,299.00,NULL,'Saint Kitts and Nevis','Constitutional Monarchy','Elisabeth II',3064,'KN');
+INSERT INTO Country VALUES ('LCA','Saint Lucia','North America','Caribbean',622.00,1979,154000,72.3,571.00,NULL,'Saint Lucia','Constitutional Monarchy','Elisabeth II',3065,'LC');
+INSERT INTO Country VALUES ('VCT','Saint Vincent and the Grenadines','North America','Caribbean',388.00,1979,114000,72.3,285.00,NULL,'Saint Vincent and the Grenadines','Constitutional Monarchy','Elisabeth II',3066,'VC');
+INSERT INTO Country VALUES ('SPM','Saint Pierre and Miquelon','North America','North America',242.00,0,7000,77.6,0.00,NULL,'Saint-Pierre-et-Miquelon','Territorial Collectivity of France','Jacques Chirac',3067,'PM');
+INSERT INTO Country VALUES ('DEU','Germany','Europe','Western Europe',357022.00,1955,82164700,77.4,2133367.00,2102826.00,'Deutschland','Federal Republic','Johannes Rau',3068,'DE');
+INSERT INTO Country VALUES ('SLB','Solomon Islands','Oceania','Melanesia',28896.00,1978,444000,71.3,182.00,220.00,'Solomon Islands','Constitutional Monarchy','Elisabeth II',3161,'SB');
+INSERT INTO Country VALUES ('ZMB','Zambia','Africa','Eastern Africa',752618.00,1964,9169000,37.2,3377.00,3922.00,'Zambia','Republic','Frederick Chiluba',3162,'ZM');
+INSERT INTO Country VALUES ('WSM','Samoa','Oceania','Polynesia',2831.00,1962,180000,69.2,141.00,157.00,'Samoa','Parlementary Monarchy','Malietoa Tanumafili II',3169,'WS');
+INSERT INTO Country VALUES ('SMR','San Marino','Europe','Southern Europe',61.00,885,27000,81.1,510.00,NULL,'San Marino','Republic',NULL,3171,'SM');
+INSERT INTO Country VALUES ('STP','Sao Tome and Principe','Africa','Central Africa',964.00,1975,147000,65.3,6.00,NULL,'São Tomé e Príncipe','Republic','Miguel Trovoada',3172,'ST');
+INSERT INTO Country VALUES ('SAU','Saudi Arabia','Asia','Middle East',2149690.00,1932,21607000,67.8,137635.00,146171.00,'Al-´Arabiya as-Sa´udiya','Monarchy','Fahd ibn Abdul-Aziz al-Sa´ud',3173,'SA');
+INSERT INTO Country VALUES ('SEN','Senegal','Africa','Western Africa',196722.00,1960,9481000,62.2,4787.00,4542.00,'Sénégal/Sounougal','Republic','Abdoulaye Wade',3198,'SN');
+INSERT INTO Country VALUES ('SYC','Seychelles','Africa','Eastern Africa',455.00,1976,77000,70.4,536.00,539.00,'Sesel/Seychelles','Republic','France-Albert René',3206,'SC');
+INSERT INTO Country VALUES ('SLE','Sierra Leone','Africa','Western Africa',71740.00,1961,4854000,45.3,746.00,858.00,'Sierra Leone','Republic','Ahmed Tejan Kabbah',3207,'SL');
+INSERT INTO Country VALUES ('SGP','Singapore','Asia','Southeast Asia',618.00,1965,3567000,80.1,86503.00,96318.00,'Singapore/Singapura/Xinjiapo/Singapur','Republic','Sellapan Rama Nathan',3208,'SG');
+INSERT INTO Country VALUES ('SVK','Slovakia','Europe','Eastern Europe',49012.00,1993,5398700,73.7,20594.00,19452.00,'Slovensko','Republic','Rudolf Schuster',3209,'SK');
+INSERT INTO Country VALUES ('SVN','Slovenia','Europe','Southern Europe',20256.00,1991,1987800,74.9,19756.00,18202.00,'Slovenija','Republic','Milan Kucan',3212,'SI');
+INSERT INTO Country VALUES ('SOM','Somalia','Africa','Eastern Africa',637657.00,1960,10097000,46.2,935.00,NULL,'Soomaaliya','Republic','Abdiqassim Salad Hassan',3214,'SO');
+INSERT INTO Country VALUES ('LKA','Sri Lanka','Asia','Southern and Central Asia',65610.00,1948,18827000,71.8,15706.00,15091.00,'Sri Lanka/Ilankai','Republic','Chandrika Kumaratunga',3217,'LK');
+INSERT INTO Country VALUES ('SDN','Sudan','Africa','Northern Africa',2505813.00,1956,29490000,56.6,10162.00,NULL,'As-Sudan','Islamic Republic','Omar Hassan Ahmad al-Bashir',3225,'SD');
+INSERT INTO Country VALUES ('FIN','Finland','Europe','Nordic Countries',338145.00,1917,5171300,77.4,121914.00,119833.00,'Suomi','Republic','Tarja Halonen',3236,'FI');
+INSERT INTO Country VALUES ('SUR','Suriname','South America','South America',163265.00,1975,417000,71.4,870.00,706.00,'Suriname','Republic','Ronald Venetiaan',3243,'SR');
+INSERT INTO Country VALUES ('SWZ','Swaziland','Africa','Southern Africa',17364.00,1968,1008000,40.4,1206.00,1312.00,'kaNgwane','Monarchy','Mswati III',3244,'SZ');
+INSERT INTO Country VALUES ('CHE','Switzerland','Europe','Western Europe',41284.00,1499,7160400,79.6,264478.00,256092.00,'Schweiz/Suisse/Svizzera/Svizra','Federation','Adolf Ogi',3248,'CH');
+INSERT INTO Country VALUES ('SYR','Syria','Asia','Middle East',185180.00,1941,16125000,68.5,65984.00,64926.00,'Suriya','Republic','Bashar al-Assad',3250,'SY');
+INSERT INTO Country VALUES ('TJK','Tajikistan','Asia','Southern and Central Asia',143100.00,1991,6188000,64.1,1990.00,1056.00,'Toçikiston','Republic','Emomali Rahmonov',3261,'TJ');
+INSERT INTO Country VALUES ('TWN','Taiwan, Province of China','Asia','Eastern Asia',36188.00,1945,22256000,76.4,256254.00,263451.00,'T’ai-wan','Republic','Chen Shui-bian',3263,'TW');
+INSERT INTO Country VALUES ('TZA','Tanzania','Africa','Eastern Africa',883749.00,1961,33517000,52.3,8005.00,7388.00,'Tanzania','Republic','Benjamin William Mkapa',3306,'TZ');
+INSERT INTO Country VALUES ('DNK','Denmark','Europe','Nordic Countries',43094.00,800,5330000,76.5,174099.00,169264.00,'Danmark','Constitutional Monarchy','Margrethe II',3315,'DK');
+INSERT INTO Country VALUES ('THA','Thailand','Asia','Southeast Asia',513115.00,1350,61399000,68.6,116416.00,153907.00,'Prathet Thai','Constitutional Monarchy','Bhumibol Adulyadej',3320,'TH');
+INSERT INTO Country VALUES ('TGO','Togo','Africa','Western Africa',56785.00,1960,4629000,54.7,1449.00,1400.00,'Togo','Republic','Gnassingbé Eyadéma',3332,'TG');
+INSERT INTO Country VALUES ('TKL','Tokelau','Oceania','Polynesia',12.00,0,2000,NULL,0.00,NULL,'Tokelau','Nonmetropolitan Territory of New Zealand','Elisabeth II',3333,'TK');
+INSERT INTO Country VALUES ('TON','Tonga','Oceania','Polynesia',650.00,1970,99000,67.9,146.00,170.00,'Tonga','Monarchy','Taufa\'ahau Tupou IV',3334,'TO');
+INSERT INTO Country VALUES ('TTO','Trinidad and Tobago','North America','Caribbean',5130.00,1962,1295000,68.0,6232.00,5867.00,'Trinidad and Tobago','Republic','Arthur N. R. Robinson',3336,'TT');
+INSERT INTO Country VALUES ('TCD','Chad','Africa','Central Africa',1284000.00,1960,7651000,50.5,1208.00,1102.00,'Tchad/Tshad','Republic','Idriss Déby',3337,'TD');
+INSERT INTO Country VALUES ('CZE','Czech Republic','Europe','Eastern Europe',78866.00,1993,10278100,74.5,55017.00,52037.00,'¸esko','Republic','Václav Havel',3339,'CZ');
+INSERT INTO Country VALUES ('TUN','Tunisia','Africa','Northern Africa',163610.00,1956,9586000,73.7,20026.00,18898.00,'Tunis/Tunisie','Republic','Zine al-Abidine Ben Ali',3349,'TN');
+INSERT INTO Country VALUES ('TUR','Turkey','Asia','Middle East',774815.00,1923,66591000,71.0,210721.00,189122.00,'Türkiye','Republic','Ahmet Necdet Sezer',3358,'TR');
+INSERT INTO Country VALUES ('TKM','Turkmenistan','Asia','Southern and Central Asia',488100.00,1991,4459000,60.9,4397.00,2000.00,'Türkmenostan','Republic','Saparmurad Nijazov',3419,'TM');
+INSERT INTO Country VALUES ('TCA','Turks and Caicos Islands','North America','Caribbean',430.00,0,17000,73.3,96.00,NULL,'The Turks and Caicos Islands','Dependent Territory of the UK','Elisabeth II',3423,'TC');
+INSERT INTO Country VALUES ('TUV','Tuvalu','Oceania','Polynesia',26.00,1978,12000,66.3,6.00,NULL,'Tuvalu','Constitutional Monarchy','Elisabeth II',3424,'TV');
+INSERT INTO Country VALUES ('UGA','Uganda','Africa','Eastern Africa',241038.00,1962,21778000,42.9,6313.00,6887.00,'Uganda','Republic','Yoweri Museveni',3425,'UG');
+INSERT INTO Country VALUES ('UKR','Ukraine','Europe','Eastern Europe',603700.00,1991,50456000,66.0,42168.00,49677.00,'Ukrajina','Republic','Leonid Kutšma',3426,'UA');
+INSERT INTO Country VALUES ('HUN','Hungary','Europe','Eastern Europe',93030.00,1918,10043200,71.4,48267.00,45914.00,'Magyarország','Republic','Ferenc Mádl',3483,'HU');
+INSERT INTO Country VALUES ('URY','Uruguay','South America','South America',175016.00,1828,3337000,75.2,20831.00,19967.00,'Uruguay','Republic','Jorge Batlle Ibáñez',3492,'UY');
+INSERT INTO Country VALUES ('NCL','New Caledonia','Oceania','Melanesia',18575.00,0,214000,72.8,3563.00,NULL,'Nouvelle-Calédonie','Nonmetropolitan Territory of France','Jacques Chirac',3493,'NC');
+INSERT INTO Country VALUES ('NZL','New Zealand','Oceania','Australia and New Zealand',270534.00,1907,3862000,77.8,54669.00,64960.00,'New Zealand/Aotearoa','Constitutional Monarchy','Elisabeth II',3499,'NZ');
+INSERT INTO Country VALUES ('UZB','Uzbekistan','Asia','Southern and Central Asia',447400.00,1991,24318000,63.7,14194.00,21300.00,'Uzbekiston','Republic','Islam Karimov',3503,'UZ');
+INSERT INTO Country VALUES ('BLR','Belarus','Europe','Eastern Europe',207600.00,1991,10236000,68.0,13714.00,NULL,'Belarus','Republic','Aljaksandr Lukašenka',3520,'BY');
+INSERT INTO Country VALUES ('WLF','Wallis and Futuna','Oceania','Polynesia',200.00,0,15000,NULL,0.00,NULL,'Wallis-et-Futuna','Nonmetropolitan Territory of France','Jacques Chirac',3536,'WF');
+INSERT INTO Country VALUES ('VUT','Vanuatu','Oceania','Melanesia',12189.00,1980,190000,60.6,261.00,246.00,'Vanuatu','Republic','John Bani',3537,'VU');
+INSERT INTO Country VALUES ('VAT','Holy See (Vatican City State)','Europe','Southern Europe',0.40,1929,1000,NULL,9.00,NULL,'Santa Sede/Città del Vaticano','Independent Church State','Johannes Paavali II',3538,'VA');
+INSERT INTO Country VALUES ('VEN','Venezuela','South America','South America',912050.00,1811,24170000,73.1,95023.00,88434.00,'Venezuela','Federal Republic','Hugo Chávez Frías',3539,'VE');
+INSERT INTO Country VALUES ('RUS','Russian Federation','Europe','Eastern Europe',17075400.00,1991,146934000,67.2,276608.00,442989.00,'Rossija','Federal Republic','Vladimir Putin',3580,'RU');
+INSERT INTO Country VALUES ('VNM','Vietnam','Asia','Southeast Asia',331689.00,1945,79832000,69.3,21929.00,22834.00,'Viêt Nam','Socialistic Republic','Trân Duc Luong',3770,'VN');
+INSERT INTO Country VALUES ('EST','Estonia','Europe','Baltic Countries',45227.00,1991,1439200,69.5,5328.00,3371.00,'Eesti','Republic','Lennart Meri',3791,'EE');
+INSERT INTO Country VALUES ('USA','United States','North America','North America',9363520.00,1776,278357000,77.1,8510700.00,8110900.00,'United States','Federal Republic','George W. Bush',3813,'US');
+INSERT INTO Country VALUES ('VIR','Virgin Islands, U.S.','North America','Caribbean',347.00,0,93000,78.1,0.00,NULL,'Virgin Islands of the United States','US Territory','George W. Bush',4067,'VI');
+INSERT INTO Country VALUES ('ZWE','Zimbabwe','Africa','Eastern Africa',390757.00,1980,11669000,37.8,5951.00,8670.00,'Zimbabwe','Republic','Robert G. Mugabe',4068,'ZW');
+INSERT INTO Country VALUES ('PSE','Palestine','Asia','Middle East',6257.00,0,3101000,71.4,4173.00,NULL,'Filastin','Autonomous Area','Yasser (Yasir) Arafat',4074,'PS');
+INSERT INTO Country VALUES ('ATA','Antarctica','Antarctica','Antarctica',13120000.00,0,0,NULL,0.00,NULL,'–','Co-administrated','',NULL,'AQ');
+INSERT INTO Country VALUES ('BVT','Bouvet Island','Antarctica','Antarctica',59.00,0,0,NULL,0.00,NULL,'Bouvetøya','Dependent Territory of Norway','Harald V',NULL,'BV');
+INSERT INTO Country VALUES ('IOT','British Indian Ocean Territory','Africa','Eastern Africa',78.00,0,0,NULL,0.00,NULL,'British Indian Ocean Territory','Dependent Territory of the UK','Elisabeth II',NULL,'IO');
+INSERT INTO Country VALUES ('SGS','South Georgia and the South Sandwich Islands','Antarctica','Antarctica',3903.00,0,0,NULL,0.00,NULL,'South Georgia and the South Sandwich Islands','Dependent Territory of the UK','Elisabeth II',NULL,'GS');
+INSERT INTO Country VALUES ('HMD','Heard Island and McDonald Islands','Antarctica','Antarctica',359.00,0,0,NULL,0.00,NULL,'Heard and McDonald Islands','Territory of Australia','Elisabeth II',NULL,'HM');
+INSERT INTO Country VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO Country VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
+
+/*!40000 ALTER TABLE Country ENABLE KEYS */;
+
+--
+-- Table structure for table 'CountryLanguage'
+--
+
+CREATE TABLE CountryLanguage (
+ Country char(3) NOT NULL default '',
+ Language char(30) NOT NULL default '',
+ IsOfficial enum('T','F') NOT NULL default 'F',
+ Percentage float(3,1) NOT NULL default '0.0',
+ PRIMARY KEY (Country,Language)
+) TYPE=MyISAM;
+
+/*!40000 ALTER TABLE CountryLanguage DISABLE KEYS */;
+
+--
+-- Dumping data for table 'CountryLanguage'
+--
+
+
+INSERT INTO CountryLanguage VALUES ('AFG','Pashto','T',52.4);
+INSERT INTO CountryLanguage VALUES ('NLD','Dutch','T',95.6);
+INSERT INTO CountryLanguage VALUES ('ANT','Papiamento','T',86.2);
+INSERT INTO CountryLanguage VALUES ('ALB','Albaniana','T',97.9);
+INSERT INTO CountryLanguage VALUES ('DZA','Arabic','T',86.0);
+INSERT INTO CountryLanguage VALUES ('ASM','Samoan','T',90.6);
+INSERT INTO CountryLanguage VALUES ('AND','Spanish','F',44.6);
+INSERT INTO CountryLanguage VALUES ('AGO','Ovimbundu','F',37.2);
+INSERT INTO CountryLanguage VALUES ('AIA','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('ATG','Creole English','F',95.7);
+INSERT INTO CountryLanguage VALUES ('ARE','Arabic','T',42.0);
+INSERT INTO CountryLanguage VALUES ('ARG','Spanish','T',96.8);
+INSERT INTO CountryLanguage VALUES ('ARM','Armenian','T',93.4);
+INSERT INTO CountryLanguage VALUES ('ABW','Papiamento','F',76.7);
+INSERT INTO CountryLanguage VALUES ('AUS','English','T',81.2);
+INSERT INTO CountryLanguage VALUES ('AZE','Azerbaijani','T',89.0);
+INSERT INTO CountryLanguage VALUES ('BHS','Creole English','F',89.7);
+INSERT INTO CountryLanguage VALUES ('BHR','Arabic','T',67.7);
+INSERT INTO CountryLanguage VALUES ('BGD','Bengali','T',97.7);
+INSERT INTO CountryLanguage VALUES ('BRB','Bajan','F',95.1);
+INSERT INTO CountryLanguage VALUES ('BEL','Dutch','T',59.2);
+INSERT INTO CountryLanguage VALUES ('BLZ','English','T',50.8);
+INSERT INTO CountryLanguage VALUES ('BEN','Fon','F',39.8);
+INSERT INTO CountryLanguage VALUES ('BMU','English','T',100.0);
+INSERT INTO CountryLanguage VALUES ('BTN','Dzongkha','T',50.0);
+INSERT INTO CountryLanguage VALUES ('BOL','Spanish','T',87.7);
+INSERT INTO CountryLanguage VALUES ('BIH','Serbo-Croatian','T',99.2);
+INSERT INTO CountryLanguage VALUES ('BWA','Tswana','F',75.5);
+INSERT INTO CountryLanguage VALUES ('BRA','Portuguese','T',97.5);
+INSERT INTO CountryLanguage VALUES ('GBR','English','T',97.3);
+INSERT INTO CountryLanguage VALUES ('VGB','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('BRN','Malay','T',45.5);
+INSERT INTO CountryLanguage VALUES ('BGR','Bulgariana','T',83.2);
+INSERT INTO CountryLanguage VALUES ('BFA','Mossi','F',50.2);
+INSERT INTO CountryLanguage VALUES ('BDI','Kirundi','T',98.1);
+INSERT INTO CountryLanguage VALUES ('CYM','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('CHL','Spanish','T',89.7);
+INSERT INTO CountryLanguage VALUES ('COK','Maori','T',0.0);
+INSERT INTO CountryLanguage VALUES ('CRI','Spanish','T',97.5);
+INSERT INTO CountryLanguage VALUES ('DJI','Somali','F',43.9);
+INSERT INTO CountryLanguage VALUES ('DMA','Creole English','F',100.0);
+INSERT INTO CountryLanguage VALUES ('DOM','Spanish','T',98.0);
+INSERT INTO CountryLanguage VALUES ('ECU','Spanish','T',93.0);
+INSERT INTO CountryLanguage VALUES ('EGY','Arabic','T',98.8);
+INSERT INTO CountryLanguage VALUES ('SLV','Spanish','T',100.0);
+INSERT INTO CountryLanguage VALUES ('ERI','Tigrinja','T',49.1);
+INSERT INTO CountryLanguage VALUES ('ESP','Spanish','T',74.4);
+INSERT INTO CountryLanguage VALUES ('ZAF','Zulu','T',22.7);
+INSERT INTO CountryLanguage VALUES ('ETH','Oromo','F',31.0);
+INSERT INTO CountryLanguage VALUES ('FLK','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('FJI','Fijian','T',50.8);
+INSERT INTO CountryLanguage VALUES ('PHL','Pilipino','T',29.3);
+INSERT INTO CountryLanguage VALUES ('FRO','Faroese','T',100.0);
+INSERT INTO CountryLanguage VALUES ('GAB','Fang','F',35.8);
+INSERT INTO CountryLanguage VALUES ('GMB','Malinke','F',34.1);
+INSERT INTO CountryLanguage VALUES ('GEO','Georgiana','T',71.7);
+INSERT INTO CountryLanguage VALUES ('GHA','Akan','F',52.4);
+INSERT INTO CountryLanguage VALUES ('GIB','English','T',88.9);
+INSERT INTO CountryLanguage VALUES ('GRD','Creole English','F',100.0);
+INSERT INTO CountryLanguage VALUES ('GRL','Greenlandic','T',87.5);
+INSERT INTO CountryLanguage VALUES ('GLP','Creole French','F',95.0);
+INSERT INTO CountryLanguage VALUES ('GUM','English','T',37.5);
+INSERT INTO CountryLanguage VALUES ('GTM','Spanish','T',64.7);
+INSERT INTO CountryLanguage VALUES ('GIN','Ful','F',38.6);
+INSERT INTO CountryLanguage VALUES ('GNB','Crioulo','F',36.4);
+INSERT INTO CountryLanguage VALUES ('GUY','Creole English','F',96.4);
+INSERT INTO CountryLanguage VALUES ('HTI','Haiti Creole','F',100.0);
+INSERT INTO CountryLanguage VALUES ('HND','Spanish','T',97.2);
+INSERT INTO CountryLanguage VALUES ('HKG','Canton Chinese','F',88.7);
+INSERT INTO CountryLanguage VALUES ('SJM','Norwegian','T',0.0);
+INSERT INTO CountryLanguage VALUES ('IDN','Javanese','F',39.4);
+INSERT INTO CountryLanguage VALUES ('IND','Hindi','T',39.9);
+INSERT INTO CountryLanguage VALUES ('IRQ','Arabic','T',77.2);
+INSERT INTO CountryLanguage VALUES ('IRN','Persian','T',45.7);
+INSERT INTO CountryLanguage VALUES ('IRL','English','T',98.4);
+INSERT INTO CountryLanguage VALUES ('ISL','Icelandic','T',95.7);
+INSERT INTO CountryLanguage VALUES ('ISR','Hebrew','T',63.1);
+INSERT INTO CountryLanguage VALUES ('ITA','Italian','T',94.1);
+INSERT INTO CountryLanguage VALUES ('TMP','Sunda','F',0.0);
+INSERT INTO CountryLanguage VALUES ('AUT','German','T',92.0);
+INSERT INTO CountryLanguage VALUES ('JAM','Creole English','F',94.2);
+INSERT INTO CountryLanguage VALUES ('JPN','Japanese','T',99.1);
+INSERT INTO CountryLanguage VALUES ('YEM','Arabic','T',99.6);
+INSERT INTO CountryLanguage VALUES ('JOR','Arabic','T',97.9);
+INSERT INTO CountryLanguage VALUES ('CXR','Chinese','F',0.0);
+INSERT INTO CountryLanguage VALUES ('YUG','Serbo-Croatian','T',75.2);
+INSERT INTO CountryLanguage VALUES ('KHM','Khmer','T',88.6);
+INSERT INTO CountryLanguage VALUES ('CMR','Fang','F',19.7);
+INSERT INTO CountryLanguage VALUES ('CAN','English','T',60.4);
+INSERT INTO CountryLanguage VALUES ('CPV','Crioulo','F',100.0);
+INSERT INTO CountryLanguage VALUES ('KAZ','Kazakh','T',46.0);
+INSERT INTO CountryLanguage VALUES ('KEN','Kikuyu','F',20.9);
+INSERT INTO CountryLanguage VALUES ('CAF','Gbaya','F',23.8);
+INSERT INTO CountryLanguage VALUES ('CHN','Chinese','T',92.0);
+INSERT INTO CountryLanguage VALUES ('KGZ','Kirgiz','T',59.7);
+INSERT INTO CountryLanguage VALUES ('KIR','Kiribati','T',98.9);
+INSERT INTO CountryLanguage VALUES ('COL','Spanish','T',99.0);
+INSERT INTO CountryLanguage VALUES ('COM','Comorian','T',75.0);
+INSERT INTO CountryLanguage VALUES ('COG','Kongo','F',51.5);
+INSERT INTO CountryLanguage VALUES ('COD','Luba','F',18.0);
+INSERT INTO CountryLanguage VALUES ('CCK','Malay','F',0.0);
+INSERT INTO CountryLanguage VALUES ('PRK','Korean','T',99.9);
+INSERT INTO CountryLanguage VALUES ('KOR','Korean','T',99.9);
+INSERT INTO CountryLanguage VALUES ('GRC','Greek','T',98.5);
+INSERT INTO CountryLanguage VALUES ('HRV','Serbo-Croatian','T',95.9);
+INSERT INTO CountryLanguage VALUES ('CUB','Spanish','T',100.0);
+INSERT INTO CountryLanguage VALUES ('KWT','Arabic','T',78.1);
+INSERT INTO CountryLanguage VALUES ('CYP','Greek','T',74.1);
+INSERT INTO CountryLanguage VALUES ('LAO','Lao','T',67.2);
+INSERT INTO CountryLanguage VALUES ('LVA','Latvian','T',55.1);
+INSERT INTO CountryLanguage VALUES ('LSO','Sotho','T',85.0);
+INSERT INTO CountryLanguage VALUES ('LBN','Arabic','T',93.0);
+INSERT INTO CountryLanguage VALUES ('LBR','Kpelle','F',19.5);
+INSERT INTO CountryLanguage VALUES ('LBY','Arabic','T',96.0);
+INSERT INTO CountryLanguage VALUES ('LIE','German','T',89.0);
+INSERT INTO CountryLanguage VALUES ('LTU','Lithuanian','T',81.6);
+INSERT INTO CountryLanguage VALUES ('LUX','Luxembourgish','T',64.4);
+INSERT INTO CountryLanguage VALUES ('ESH','Arabic','T',100.0);
+INSERT INTO CountryLanguage VALUES ('MAC','Canton Chinese','F',85.6);
+INSERT INTO CountryLanguage VALUES ('MDG','Malagasy','T',98.9);
+INSERT INTO CountryLanguage VALUES ('MKD','Macedonian','T',66.5);
+INSERT INTO CountryLanguage VALUES ('MWI','Chichewa','T',58.3);
+INSERT INTO CountryLanguage VALUES ('MDV','Dhivehi','T',100.0);
+INSERT INTO CountryLanguage VALUES ('MYS','Malay','T',58.4);
+INSERT INTO CountryLanguage VALUES ('MLI','Bambara','F',31.8);
+INSERT INTO CountryLanguage VALUES ('MLT','Maltese','T',95.8);
+INSERT INTO CountryLanguage VALUES ('MAR','Arabic','T',65.0);
+INSERT INTO CountryLanguage VALUES ('MHL','Marshallese','T',96.8);
+INSERT INTO CountryLanguage VALUES ('MTQ','Creole French','F',96.6);
+INSERT INTO CountryLanguage VALUES ('MRT','Hassaniya','F',81.7);
+INSERT INTO CountryLanguage VALUES ('MUS','Creole French','F',70.6);
+INSERT INTO CountryLanguage VALUES ('MYT','Mahoré','F',41.9);
+INSERT INTO CountryLanguage VALUES ('MEX','Spanish','T',92.1);
+INSERT INTO CountryLanguage VALUES ('FSM','Trukese','F',41.6);
+INSERT INTO CountryLanguage VALUES ('MDA','Romanian','T',61.9);
+INSERT INTO CountryLanguage VALUES ('MCO','French','T',41.9);
+INSERT INTO CountryLanguage VALUES ('MNG','Mongolian','T',78.8);
+INSERT INTO CountryLanguage VALUES ('MSR','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('MOZ','Makua','F',27.8);
+INSERT INTO CountryLanguage VALUES ('MMR','Burmese','T',69.0);
+INSERT INTO CountryLanguage VALUES ('NAM','Ovambo','F',50.7);
+INSERT INTO CountryLanguage VALUES ('NRU','Nauru','T',57.5);
+INSERT INTO CountryLanguage VALUES ('NPL','Nepali','T',50.4);
+INSERT INTO CountryLanguage VALUES ('NIC','Spanish','T',97.6);
+INSERT INTO CountryLanguage VALUES ('NER','Hausa','F',53.1);
+INSERT INTO CountryLanguage VALUES ('NGA','Joruba','F',21.4);
+INSERT INTO CountryLanguage VALUES ('NIU','Niue','F',0.0);
+INSERT INTO CountryLanguage VALUES ('NFK','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('NOR','Norwegian','T',96.6);
+INSERT INTO CountryLanguage VALUES ('CIV','Akan','F',30.0);
+INSERT INTO CountryLanguage VALUES ('OMN','Arabic','T',76.7);
+INSERT INTO CountryLanguage VALUES ('PAK','Punjabi','F',48.2);
+INSERT INTO CountryLanguage VALUES ('PLW','Palau','T',82.2);
+INSERT INTO CountryLanguage VALUES ('PAN','Spanish','T',76.8);
+INSERT INTO CountryLanguage VALUES ('PNG','Papuan Languages','F',78.1);
+INSERT INTO CountryLanguage VALUES ('PRY','Spanish','T',55.1);
+INSERT INTO CountryLanguage VALUES ('PER','Spanish','T',79.8);
+INSERT INTO CountryLanguage VALUES ('PCN','Pitcairnese','F',0.0);
+INSERT INTO CountryLanguage VALUES ('MNP','Philippene Languages','F',34.1);
+INSERT INTO CountryLanguage VALUES ('PRT','Portuguese','T',99.0);
+INSERT INTO CountryLanguage VALUES ('PRI','Spanish','T',51.3);
+INSERT INTO CountryLanguage VALUES ('POL','Polish','T',97.6);
+INSERT INTO CountryLanguage VALUES ('GNQ','Fang','F',84.8);
+INSERT INTO CountryLanguage VALUES ('QAT','Arabic','T',40.7);
+INSERT INTO CountryLanguage VALUES ('FRA','French','T',93.6);
+INSERT INTO CountryLanguage VALUES ('GUF','Creole French','F',94.3);
+INSERT INTO CountryLanguage VALUES ('PYF','Tahitian','F',46.4);
+INSERT INTO CountryLanguage VALUES ('REU','Creole French','F',91.5);
+INSERT INTO CountryLanguage VALUES ('ROM','Romanian','T',90.7);
+INSERT INTO CountryLanguage VALUES ('RWA','Rwanda','T',100.0);
+INSERT INTO CountryLanguage VALUES ('SWE','Swedish','T',89.5);
+INSERT INTO CountryLanguage VALUES ('SHN','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('KNA','Creole English','F',100.0);
+INSERT INTO CountryLanguage VALUES ('LCA','Creole French','F',80.0);
+INSERT INTO CountryLanguage VALUES ('VCT','Creole English','F',99.1);
+INSERT INTO CountryLanguage VALUES ('SPM','French','T',0.0);
+INSERT INTO CountryLanguage VALUES ('DEU','German','T',91.3);
+INSERT INTO CountryLanguage VALUES ('SLB','Malenasian Languages','F',85.6);
+INSERT INTO CountryLanguage VALUES ('ZMB','Bemba','F',29.7);
+INSERT INTO CountryLanguage VALUES ('WSM','Samoan-English','F',52.0);
+INSERT INTO CountryLanguage VALUES ('SMR','Italian','T',100.0);
+INSERT INTO CountryLanguage VALUES ('STP','Crioulo','F',86.3);
+INSERT INTO CountryLanguage VALUES ('SAU','Arabic','T',95.0);
+INSERT INTO CountryLanguage VALUES ('SEN','Wolof','T',48.1);
+INSERT INTO CountryLanguage VALUES ('SYC','Seselwa','F',91.3);
+INSERT INTO CountryLanguage VALUES ('SLE','Mende','F',34.8);
+INSERT INTO CountryLanguage VALUES ('SGP','Chinese','T',77.1);
+INSERT INTO CountryLanguage VALUES ('SVK','Slovak','T',85.6);
+INSERT INTO CountryLanguage VALUES ('SVN','Slovene','T',87.9);
+INSERT INTO CountryLanguage VALUES ('SOM','Somali','T',98.3);
+INSERT INTO CountryLanguage VALUES ('LKA','Singali','T',60.3);
+INSERT INTO CountryLanguage VALUES ('SDN','Arabic','T',49.4);
+INSERT INTO CountryLanguage VALUES ('FIN','Finnish','T',92.7);
+INSERT INTO CountryLanguage VALUES ('SUR','Sranantonga','F',81.0);
+INSERT INTO CountryLanguage VALUES ('SWZ','Swazi','T',89.9);
+INSERT INTO CountryLanguage VALUES ('CHE','German','T',63.6);
+INSERT INTO CountryLanguage VALUES ('SYR','Arabic','T',90.0);
+INSERT INTO CountryLanguage VALUES ('TJK','Tadzhik','T',62.2);
+INSERT INTO CountryLanguage VALUES ('TWN','Min','F',66.7);
+INSERT INTO CountryLanguage VALUES ('TZA','Nyamwesi','F',21.1);
+INSERT INTO CountryLanguage VALUES ('DNK','Danish','T',93.5);
+INSERT INTO CountryLanguage VALUES ('THA','Thai','T',52.6);
+INSERT INTO CountryLanguage VALUES ('TGO','Ewe','T',23.2);
+INSERT INTO CountryLanguage VALUES ('TKL','Tokelau','F',0.0);
+INSERT INTO CountryLanguage VALUES ('TON','Tongan','T',98.3);
+INSERT INTO CountryLanguage VALUES ('TTO','English','F',93.5);
+INSERT INTO CountryLanguage VALUES ('TCD','Sara','F',27.7);
+INSERT INTO CountryLanguage VALUES ('CZE','Czech','T',81.2);
+INSERT INTO CountryLanguage VALUES ('TUN','Arabic','T',69.9);
+INSERT INTO CountryLanguage VALUES ('TUR','Turkish','T',87.6);
+INSERT INTO CountryLanguage VALUES ('TKM','Turkmenian','T',76.7);
+INSERT INTO CountryLanguage VALUES ('TCA','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('TUV','Tuvalu','T',92.5);
+INSERT INTO CountryLanguage VALUES ('UGA','Ganda','F',18.1);
+INSERT INTO CountryLanguage VALUES ('UKR','Ukrainian','T',64.7);
+INSERT INTO CountryLanguage VALUES ('HUN','Hungarian','T',98.5);
+INSERT INTO CountryLanguage VALUES ('URY','Spanish','T',95.7);
+INSERT INTO CountryLanguage VALUES ('NCL','Malenasian Languages','F',45.4);
+INSERT INTO CountryLanguage VALUES ('NZL','English','T',87.0);
+INSERT INTO CountryLanguage VALUES ('UZB','Uzbek','T',72.6);
+INSERT INTO CountryLanguage VALUES ('BLR','Belorussian','T',65.6);
+INSERT INTO CountryLanguage VALUES ('WLF','Wallis','F',0.0);
+INSERT INTO CountryLanguage VALUES ('VUT','Bislama','T',56.6);
+INSERT INTO CountryLanguage VALUES ('VAT','Italian','T',0.0);
+INSERT INTO CountryLanguage VALUES ('VEN','Spanish','T',96.9);
+INSERT INTO CountryLanguage VALUES ('RUS','Russian','T',86.6);
+INSERT INTO CountryLanguage VALUES ('VNM','Vietnamese','T',86.8);
+INSERT INTO CountryLanguage VALUES ('EST','Estonian','T',65.3);
+INSERT INTO CountryLanguage VALUES ('USA','English','T',86.2);
+INSERT INTO CountryLanguage VALUES ('VIR','English','T',81.7);
+INSERT INTO CountryLanguage VALUES ('UMI','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('ZWE','Shona','F',72.1);
+INSERT INTO CountryLanguage VALUES ('PSE','Arabic','F',95.9);
+INSERT INTO CountryLanguage VALUES ('AFG','Dari','T',32.1);
+INSERT INTO CountryLanguage VALUES ('NLD','Fries','F',3.7);
+INSERT INTO CountryLanguage VALUES ('ANT','English','F',7.8);
+INSERT INTO CountryLanguage VALUES ('ALB','Greek','F',1.8);
+INSERT INTO CountryLanguage VALUES ('DZA','Berberi','F',14.0);
+INSERT INTO CountryLanguage VALUES ('ASM','English','T',3.1);
+INSERT INTO CountryLanguage VALUES ('AND','Catalan','T',32.3);
+INSERT INTO CountryLanguage VALUES ('AGO','Mbundu','F',21.6);
+INSERT INTO CountryLanguage VALUES ('ATG','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('ARE','Hindi','F',0.0);
+INSERT INTO CountryLanguage VALUES ('ARG','Italian','F',1.7);
+INSERT INTO CountryLanguage VALUES ('ARM','Azerbaijani','F',2.6);
+INSERT INTO CountryLanguage VALUES ('ABW','English','F',9.5);
+INSERT INTO CountryLanguage VALUES ('AUS','Italian','F',2.2);
+INSERT INTO CountryLanguage VALUES ('AZE','Russian','F',3.0);
+INSERT INTO CountryLanguage VALUES ('BHS','Creole French','F',10.3);
+INSERT INTO CountryLanguage VALUES ('BHR','English','F',0.0);
+INSERT INTO CountryLanguage VALUES ('BGD','Chakma','F',0.4);
+INSERT INTO CountryLanguage VALUES ('BRB','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('BEL','French','T',32.6);
+INSERT INTO CountryLanguage VALUES ('BLZ','Spanish','F',31.6);
+INSERT INTO CountryLanguage VALUES ('BEN','Joruba','F',12.2);
+INSERT INTO CountryLanguage VALUES ('BTN','Nepali','F',34.8);
+INSERT INTO CountryLanguage VALUES ('BOL','Ketšua','T',8.1);
+INSERT INTO CountryLanguage VALUES ('BWA','Shona','F',12.3);
+INSERT INTO CountryLanguage VALUES ('BRA','German','F',0.5);
+INSERT INTO CountryLanguage VALUES ('GBR','Kymri','F',0.9);
+INSERT INTO CountryLanguage VALUES ('BRN','Malay-English','F',28.8);
+INSERT INTO CountryLanguage VALUES ('BGR','Turkish','F',9.4);
+INSERT INTO CountryLanguage VALUES ('BFA','Ful','F',9.7);
+INSERT INTO CountryLanguage VALUES ('BDI','French','T',0.0);
+INSERT INTO CountryLanguage VALUES ('CHL','Araucan','F',9.6);
+INSERT INTO CountryLanguage VALUES ('COK','English','F',0.0);
+INSERT INTO CountryLanguage VALUES ('CRI','Creole English','F',2.0);
+INSERT INTO CountryLanguage VALUES ('DJI','Afar','F',34.8);
+INSERT INTO CountryLanguage VALUES ('DMA','Creole French','F',0.0);
+INSERT INTO CountryLanguage VALUES ('DOM','Creole French','F',2.0);
+INSERT INTO CountryLanguage VALUES ('ECU','Ketšua','F',7.0);
+INSERT INTO CountryLanguage VALUES ('EGY','Sinaberberi','F',0.0);
+INSERT INTO CountryLanguage VALUES ('SLV','Nahua','F',0.0);
+INSERT INTO CountryLanguage VALUES ('ERI','Tigre','F',31.7);
+INSERT INTO CountryLanguage VALUES ('ESP','Catalan','F',16.9);
+INSERT INTO CountryLanguage VALUES ('ZAF','Xhosa','T',17.7);
+INSERT INTO CountryLanguage VALUES ('ETH','Amhara','F',30.0);
+INSERT INTO CountryLanguage VALUES ('FJI','Hindi','F',43.7);
+INSERT INTO CountryLanguage VALUES ('PHL','Cebuano','F',23.3);
+INSERT INTO CountryLanguage VALUES ('FRO','Danish','T',0.0);
+INSERT INTO CountryLanguage VALUES ('GAB','Punu-sira-nzebi','F',17.1);
+INSERT INTO CountryLanguage VALUES ('GMB','Ful','F',16.2);
+INSERT INTO CountryLanguage VALUES ('GEO','Russian','F',8.8);
+INSERT INTO CountryLanguage VALUES ('GHA','Mossi','F',15.8);
+INSERT INTO CountryLanguage VALUES ('GIB','Arabic','F',7.4);
+INSERT INTO CountryLanguage VALUES ('GRL','Danish','T',12.5);
+INSERT INTO CountryLanguage VALUES ('GLP','French','T',0.0);
+INSERT INTO CountryLanguage VALUES ('GUM','Chamorro','T',29.6);
+INSERT INTO CountryLanguage VALUES ('GTM','Quiché','F',10.1);
+INSERT INTO CountryLanguage VALUES ('GIN','Malinke','F',23.2);
+INSERT INTO CountryLanguage VALUES ('GNB','Ful','F',16.6);
+INSERT INTO CountryLanguage VALUES ('GUY','Caribbean','F',2.2);
+INSERT INTO CountryLanguage VALUES ('HTI','French','T',0.0);
+INSERT INTO CountryLanguage VALUES ('HND','Garifuna','F',1.3);
+INSERT INTO CountryLanguage VALUES ('HKG','English','T',2.2);
+INSERT INTO CountryLanguage VALUES ('SJM','Russian','F',0.0);
+INSERT INTO CountryLanguage VALUES ('IDN','Sunda','F',15.8);
+INSERT INTO CountryLanguage VALUES ('IND','Bengali','F',8.2);
+INSERT INTO CountryLanguage VALUES ('IRQ','Kurdish','F',19.0);
+INSERT INTO CountryLanguage VALUES ('IRN','Azerbaijani','F',16.8);
+INSERT INTO CountryLanguage VALUES ('IRL','Irish','T',1.6);
+INSERT INTO CountryLanguage VALUES ('ISL','English','F',0.0);
+INSERT INTO CountryLanguage VALUES ('ISR','Arabic','T',18.0);
+INSERT INTO CountryLanguage VALUES ('ITA','Sardinian','F',2.7);
+INSERT INTO CountryLanguage VALUES ('TMP','Portuguese','T',0.0);
+INSERT INTO CountryLanguage VALUES ('AUT','Serbo-Croatian','F',2.2);
+INSERT INTO CountryLanguage VALUES ('JAM','Hindi','F',1.9);
+INSERT INTO CountryLanguage VALUES ('JPN','Korean','F',0.5);
+INSERT INTO CountryLanguage VALUES ('YEM','Soqutri','F',0.0);
+INSERT INTO CountryLanguage VALUES ('JOR','Circassian','F',1.0);
+INSERT INTO CountryLanguage VALUES ('CXR','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('YUG','Albaniana','F',16.5);
+INSERT INTO CountryLanguage VALUES ('KHM','Vietnamese','F',5.5);
+INSERT INTO CountryLanguage VALUES ('CMR','Bamileke-bamum','F',18.6);
+INSERT INTO CountryLanguage VALUES ('CAN','French','T',23.4);
+INSERT INTO CountryLanguage VALUES ('CPV','Portuguese','T',0.0);
+INSERT INTO CountryLanguage VALUES ('KAZ','Russian','F',34.7);
+INSERT INTO CountryLanguage VALUES ('KEN','Luhya','F',13.8);
+INSERT INTO CountryLanguage VALUES ('CAF','Banda','F',23.5);
+INSERT INTO CountryLanguage VALUES ('CHN','Zhuang','F',1.4);
+INSERT INTO CountryLanguage VALUES ('KGZ','Russian','T',16.2);
+INSERT INTO CountryLanguage VALUES ('KIR','Tuvalu','F',0.5);
+INSERT INTO CountryLanguage VALUES ('COL','Chibcha','F',0.4);
+INSERT INTO CountryLanguage VALUES ('COM','Comorian-French','F',12.9);
+INSERT INTO CountryLanguage VALUES ('COG','Teke','F',17.3);
+INSERT INTO CountryLanguage VALUES ('COD','Kongo','F',16.0);
+INSERT INTO CountryLanguage VALUES ('CCK','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('PRK','Chinese','F',0.1);
+INSERT INTO CountryLanguage VALUES ('KOR','Chinese','F',0.1);
+INSERT INTO CountryLanguage VALUES ('GRC','Turkish','F',0.9);
+INSERT INTO CountryLanguage VALUES ('HRV','Slovene','F',0.0);
+INSERT INTO CountryLanguage VALUES ('KWT','English','F',0.0);
+INSERT INTO CountryLanguage VALUES ('CYP','Turkish','T',22.4);
+INSERT INTO CountryLanguage VALUES ('LAO','Mon-khmer','F',16.5);
+INSERT INTO CountryLanguage VALUES ('LVA','Russian','F',32.5);
+INSERT INTO CountryLanguage VALUES ('LSO','Zulu','F',15.0);
+INSERT INTO CountryLanguage VALUES ('LBN','Armenian','F',5.9);
+INSERT INTO CountryLanguage VALUES ('LBR','Bassa','F',13.7);
+INSERT INTO CountryLanguage VALUES ('LBY','Berberi','F',1.0);
+INSERT INTO CountryLanguage VALUES ('LIE','Italian','F',2.5);
+INSERT INTO CountryLanguage VALUES ('LTU','Russian','F',8.1);
+INSERT INTO CountryLanguage VALUES ('LUX','Portuguese','F',13.0);
+INSERT INTO CountryLanguage VALUES ('MAC','Portuguese','T',2.3);
+INSERT INTO CountryLanguage VALUES ('MDG','French','T',0.0);
+INSERT INTO CountryLanguage VALUES ('MKD','Albaniana','F',22.9);
+INSERT INTO CountryLanguage VALUES ('MWI','Lomwe','F',18.4);
+INSERT INTO CountryLanguage VALUES ('MDV','English','F',0.0);
+INSERT INTO CountryLanguage VALUES ('MYS','Chinese','F',9.0);
+INSERT INTO CountryLanguage VALUES ('MLI','Ful','F',13.9);
+INSERT INTO CountryLanguage VALUES ('MLT','English','T',2.1);
+INSERT INTO CountryLanguage VALUES ('MAR','Berberi','F',33.0);
+INSERT INTO CountryLanguage VALUES ('MHL','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('MTQ','French','T',0.0);
+INSERT INTO CountryLanguage VALUES ('MRT','Wolof','F',6.6);
+INSERT INTO CountryLanguage VALUES ('MUS','Bhojpuri','F',21.1);
+INSERT INTO CountryLanguage VALUES ('MYT','French','T',20.3);
+INSERT INTO CountryLanguage VALUES ('MEX','Náhuatl','F',1.8);
+INSERT INTO CountryLanguage VALUES ('FSM','Pohnpei','F',23.8);
+INSERT INTO CountryLanguage VALUES ('MDA','Russian','F',23.2);
+INSERT INTO CountryLanguage VALUES ('MCO','Monegasque','F',16.1);
+INSERT INTO CountryLanguage VALUES ('MNG','Kazakh','F',5.9);
+INSERT INTO CountryLanguage VALUES ('MOZ','Tsonga','F',12.4);
+INSERT INTO CountryLanguage VALUES ('MMR','Shan','F',8.5);
+INSERT INTO CountryLanguage VALUES ('NAM','Nama','F',12.4);
+INSERT INTO CountryLanguage VALUES ('NRU','Kiribati','F',17.9);
+INSERT INTO CountryLanguage VALUES ('NPL','Maithili','F',11.9);
+INSERT INTO CountryLanguage VALUES ('NIC','Miskito','F',1.6);
+INSERT INTO CountryLanguage VALUES ('NER','Songhai-zerma','F',21.2);
+INSERT INTO CountryLanguage VALUES ('NGA','Hausa','F',21.1);
+INSERT INTO CountryLanguage VALUES ('NIU','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('NOR','English','F',0.5);
+INSERT INTO CountryLanguage VALUES ('CIV','Gur','F',11.7);
+INSERT INTO CountryLanguage VALUES ('OMN','Balochi','F',0.0);
+INSERT INTO CountryLanguage VALUES ('PAK','Pashto','F',13.1);
+INSERT INTO CountryLanguage VALUES ('PLW','Philippene Languages','F',9.2);
+INSERT INTO CountryLanguage VALUES ('PAN','Creole English','F',14.0);
+INSERT INTO CountryLanguage VALUES ('PNG','Malenasian Languages','F',20.0);
+INSERT INTO CountryLanguage VALUES ('PRY','Guaraní','T',40.1);
+INSERT INTO CountryLanguage VALUES ('PER','Ketšua','T',16.4);
+INSERT INTO CountryLanguage VALUES ('MNP','Chamorro','F',30.0);
+INSERT INTO CountryLanguage VALUES ('PRI','English','F',47.4);
+INSERT INTO CountryLanguage VALUES ('POL','German','F',1.3);
+INSERT INTO CountryLanguage VALUES ('GNQ','Bubi','F',8.7);
+INSERT INTO CountryLanguage VALUES ('QAT','Urdu','F',0.0);
+INSERT INTO CountryLanguage VALUES ('FRA','Arabic','F',2.5);
+INSERT INTO CountryLanguage VALUES ('GUF','Indian Languages','F',1.9);
+INSERT INTO CountryLanguage VALUES ('PYF','French','T',40.8);
+INSERT INTO CountryLanguage VALUES ('REU','Chinese','F',2.8);
+INSERT INTO CountryLanguage VALUES ('ROM','Hungarian','F',7.2);
+INSERT INTO CountryLanguage VALUES ('RWA','French','T',0.0);
+INSERT INTO CountryLanguage VALUES ('SWE','Finnish','F',2.4);
+INSERT INTO CountryLanguage VALUES ('KNA','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('LCA','English','T',20.0);
+INSERT INTO CountryLanguage VALUES ('VCT','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('DEU','Turkish','F',2.6);
+INSERT INTO CountryLanguage VALUES ('SLB','Papuan Languages','F',8.6);
+INSERT INTO CountryLanguage VALUES ('ZMB','Tongan','F',11.0);
+INSERT INTO CountryLanguage VALUES ('WSM','Samoan','T',47.5);
+INSERT INTO CountryLanguage VALUES ('STP','French','F',0.7);
+INSERT INTO CountryLanguage VALUES ('SEN','Ful','F',21.7);
+INSERT INTO CountryLanguage VALUES ('SYC','English','T',3.8);
+INSERT INTO CountryLanguage VALUES ('SLE','Temne','F',31.8);
+INSERT INTO CountryLanguage VALUES ('SGP','Malay','T',14.1);
+INSERT INTO CountryLanguage VALUES ('SVK','Hungarian','F',10.5);
+INSERT INTO CountryLanguage VALUES ('SVN','Serbo-Croatian','F',7.9);
+INSERT INTO CountryLanguage VALUES ('SOM','Arabic','T',0.0);
+INSERT INTO CountryLanguage VALUES ('LKA','Tamil','T',19.6);
+INSERT INTO CountryLanguage VALUES ('SDN','Dinka','F',11.5);
+INSERT INTO CountryLanguage VALUES ('FIN','Swedish','T',5.7);
+INSERT INTO CountryLanguage VALUES ('SUR','Hindi','F',0.0);
+INSERT INTO CountryLanguage VALUES ('SWZ','Zulu','F',2.0);
+INSERT INTO CountryLanguage VALUES ('CHE','French','T',19.2);
+INSERT INTO CountryLanguage VALUES ('SYR','Kurdish','F',9.0);
+INSERT INTO CountryLanguage VALUES ('TJK','Uzbek','F',23.2);
+INSERT INTO CountryLanguage VALUES ('TWN','Mandarin Chinese','T',20.1);
+INSERT INTO CountryLanguage VALUES ('TZA','Swahili','T',8.8);
+INSERT INTO CountryLanguage VALUES ('DNK','Turkish','F',0.8);
+INSERT INTO CountryLanguage VALUES ('THA','Lao','F',26.9);
+INSERT INTO CountryLanguage VALUES ('TGO','Kabyé','T',13.8);
+INSERT INTO CountryLanguage VALUES ('TKL','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('TON','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('TTO','Hindi','F',3.4);
+INSERT INTO CountryLanguage VALUES ('TCD','Arabic','T',12.3);
+INSERT INTO CountryLanguage VALUES ('CZE','Moravian','F',12.9);
+INSERT INTO CountryLanguage VALUES ('TUN','Arabic-French','F',26.3);
+INSERT INTO CountryLanguage VALUES ('TUR','Kurdish','F',10.6);
+INSERT INTO CountryLanguage VALUES ('TKM','Uzbek','F',9.2);
+INSERT INTO CountryLanguage VALUES ('TUV','Kiribati','F',7.5);
+INSERT INTO CountryLanguage VALUES ('UGA','Nkole','F',10.7);
+INSERT INTO CountryLanguage VALUES ('UKR','Russian','F',32.9);
+INSERT INTO CountryLanguage VALUES ('HUN','Romani','F',0.5);
+INSERT INTO CountryLanguage VALUES ('NCL','French','T',34.3);
+INSERT INTO CountryLanguage VALUES ('NZL','Maori','F',4.3);
+INSERT INTO CountryLanguage VALUES ('UZB','Russian','F',10.9);
+INSERT INTO CountryLanguage VALUES ('BLR','Russian','T',32.0);
+INSERT INTO CountryLanguage VALUES ('WLF','Futuna','F',0.0);
+INSERT INTO CountryLanguage VALUES ('VUT','English','T',28.3);
+INSERT INTO CountryLanguage VALUES ('VEN','Goajiro','F',0.4);
+INSERT INTO CountryLanguage VALUES ('RUS','Tatar','F',3.2);
+INSERT INTO CountryLanguage VALUES ('VNM','Tho','F',1.8);
+INSERT INTO CountryLanguage VALUES ('EST','Russian','F',27.8);
+INSERT INTO CountryLanguage VALUES ('USA','Spanish','F',7.5);
+INSERT INTO CountryLanguage VALUES ('VIR','Spanish','F',13.3);
+INSERT INTO CountryLanguage VALUES ('ZWE','Ndebele','F',16.2);
+INSERT INTO CountryLanguage VALUES ('PSE','Hebrew','F',4.1);
+INSERT INTO CountryLanguage VALUES ('AFG','Uzbek','F',8.8);
+INSERT INTO CountryLanguage VALUES ('NLD','Arabic','F',0.9);
+INSERT INTO CountryLanguage VALUES ('ANT','Dutch','T',0.0);
+INSERT INTO CountryLanguage VALUES ('ALB','Macedonian','F',0.1);
+INSERT INTO CountryLanguage VALUES ('ASM','Tongan','F',3.1);
+INSERT INTO CountryLanguage VALUES ('AND','Portuguese','F',10.8);
+INSERT INTO CountryLanguage VALUES ('AGO','Kongo','F',13.2);
+INSERT INTO CountryLanguage VALUES ('ARG','Indian Languages','F',0.3);
+INSERT INTO CountryLanguage VALUES ('ABW','Spanish','F',7.4);
+INSERT INTO CountryLanguage VALUES ('AUS','Greek','F',1.6);
+INSERT INTO CountryLanguage VALUES ('AZE','Lezgian','F',2.3);
+INSERT INTO CountryLanguage VALUES ('BGD','Marma','F',0.2);
+INSERT INTO CountryLanguage VALUES ('BEL','Italian','F',2.4);
+INSERT INTO CountryLanguage VALUES ('BLZ','Maya Languages','F',9.6);
+INSERT INTO CountryLanguage VALUES ('BEN','Adja','F',11.1);
+INSERT INTO CountryLanguage VALUES ('BTN','Asami','F',15.2);
+INSERT INTO CountryLanguage VALUES ('BOL','Aimará','T',3.2);
+INSERT INTO CountryLanguage VALUES ('BWA','San','F',3.5);
+INSERT INTO CountryLanguage VALUES ('BRA','Italian','F',0.4);
+INSERT INTO CountryLanguage VALUES ('GBR','Gaeli','F',0.1);
+INSERT INTO CountryLanguage VALUES ('BRN','Chinese','F',9.3);
+INSERT INTO CountryLanguage VALUES ('BGR','Romani','F',3.7);
+INSERT INTO CountryLanguage VALUES ('BFA','Gurma','F',5.7);
+INSERT INTO CountryLanguage VALUES ('BDI','Swahili','F',0.0);
+INSERT INTO CountryLanguage VALUES ('CHL','Aimará','F',0.5);
+INSERT INTO CountryLanguage VALUES ('CRI','Chibcha','F',0.3);
+INSERT INTO CountryLanguage VALUES ('DJI','Arabic','T',10.6);
+INSERT INTO CountryLanguage VALUES ('ERI','Afar','F',4.3);
+INSERT INTO CountryLanguage VALUES ('ESP','Galecian','F',6.4);
+INSERT INTO CountryLanguage VALUES ('ZAF','Afrikaans','T',14.3);
+INSERT INTO CountryLanguage VALUES ('ETH','Tigrinja','F',7.2);
+INSERT INTO CountryLanguage VALUES ('PHL','Ilocano','F',9.3);
+INSERT INTO CountryLanguage VALUES ('GAB','Mpongwe','F',14.6);
+INSERT INTO CountryLanguage VALUES ('GMB','Wolof','F',12.6);
+INSERT INTO CountryLanguage VALUES ('GEO','Armenian','F',6.8);
+INSERT INTO CountryLanguage VALUES ('GHA','Ewe','F',11.9);
+INSERT INTO CountryLanguage VALUES ('GUM','Philippene Languages','F',19.7);
+INSERT INTO CountryLanguage VALUES ('GTM','Cakchiquel','F',8.9);
+INSERT INTO CountryLanguage VALUES ('GIN','Susu','F',11.0);
+INSERT INTO CountryLanguage VALUES ('GNB','Balante','F',14.6);
+INSERT INTO CountryLanguage VALUES ('GUY','Arawakan','F',1.4);
+INSERT INTO CountryLanguage VALUES ('HND','Creole English','F',0.2);
+INSERT INTO CountryLanguage VALUES ('HKG','Fukien','F',1.9);
+INSERT INTO CountryLanguage VALUES ('IDN','Malay','T',12.1);
+INSERT INTO CountryLanguage VALUES ('IND','Telugu','F',7.8);
+INSERT INTO CountryLanguage VALUES ('IRQ','Azerbaijani','F',1.7);
+INSERT INTO CountryLanguage VALUES ('IRN','Kurdish','F',9.1);
+INSERT INTO CountryLanguage VALUES ('ISR','Russian','F',8.9);
+INSERT INTO CountryLanguage VALUES ('ITA','Friuli','F',1.2);
+INSERT INTO CountryLanguage VALUES ('AUT','Turkish','F',1.5);
+INSERT INTO CountryLanguage VALUES ('JPN','Chinese','F',0.2);
+INSERT INTO CountryLanguage VALUES ('JOR','Armenian','F',1.0);
+INSERT INTO CountryLanguage VALUES ('YUG','Hungarian','F',3.4);
+INSERT INTO CountryLanguage VALUES ('KHM','Chinese','F',3.1);
+INSERT INTO CountryLanguage VALUES ('CMR','Duala','F',10.9);
+INSERT INTO CountryLanguage VALUES ('CAN','Chinese','F',2.5);
+INSERT INTO CountryLanguage VALUES ('KAZ','Ukrainian','F',5.0);
+INSERT INTO CountryLanguage VALUES ('KEN','Luo','F',12.8);
+INSERT INTO CountryLanguage VALUES ('CAF','Mandjia','F',14.8);
+INSERT INTO CountryLanguage VALUES ('CHN','Mantšu','F',0.9);
+INSERT INTO CountryLanguage VALUES ('KGZ','Uzbek','F',14.1);
+INSERT INTO CountryLanguage VALUES ('COL','Creole English','F',0.1);
+INSERT INTO CountryLanguage VALUES ('COM','Comorian-madagassi','F',5.5);
+INSERT INTO CountryLanguage VALUES ('COG','Mboshi','F',11.4);
+INSERT INTO CountryLanguage VALUES ('COD','Mongo','F',13.5);
+INSERT INTO CountryLanguage VALUES ('LAO','Thai','F',7.8);
+INSERT INTO CountryLanguage VALUES ('LVA','Belorussian','F',4.1);
+INSERT INTO CountryLanguage VALUES ('LSO','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('LBN','French','F',0.0);
+INSERT INTO CountryLanguage VALUES ('LBR','Grebo','F',8.9);
+INSERT INTO CountryLanguage VALUES ('LIE','Turkish','F',2.5);
+INSERT INTO CountryLanguage VALUES ('LTU','Polish','F',7.0);
+INSERT INTO CountryLanguage VALUES ('LUX','Italian','F',4.6);
+INSERT INTO CountryLanguage VALUES ('MAC','Mandarin Chinese','F',1.2);
+INSERT INTO CountryLanguage VALUES ('MKD','Turkish','F',4.0);
+INSERT INTO CountryLanguage VALUES ('MWI','Yao','F',13.2);
+INSERT INTO CountryLanguage VALUES ('MYS','Tamil','F',3.9);
+INSERT INTO CountryLanguage VALUES ('MLI','Senufo and Minianka','F',12.0);
+INSERT INTO CountryLanguage VALUES ('MRT','Tukulor','F',5.4);
+INSERT INTO CountryLanguage VALUES ('MUS','French','F',3.4);
+INSERT INTO CountryLanguage VALUES ('MYT','Malagasy','F',16.1);
+INSERT INTO CountryLanguage VALUES ('MEX','Yucatec','F',1.1);
+INSERT INTO CountryLanguage VALUES ('FSM','Mortlock','F',7.6);
+INSERT INTO CountryLanguage VALUES ('MDA','Ukrainian','F',8.6);
+INSERT INTO CountryLanguage VALUES ('MCO','Italian','F',16.1);
+INSERT INTO CountryLanguage VALUES ('MNG','Dorbet','F',2.7);
+INSERT INTO CountryLanguage VALUES ('MOZ','Sena','F',9.4);
+INSERT INTO CountryLanguage VALUES ('MMR','Karen','F',6.2);
+INSERT INTO CountryLanguage VALUES ('NAM','Kavango','F',9.7);
+INSERT INTO CountryLanguage VALUES ('NRU','Chinese','F',8.5);
+INSERT INTO CountryLanguage VALUES ('NPL','Bhojpuri','F',7.5);
+INSERT INTO CountryLanguage VALUES ('NIC','Creole English','F',0.5);
+INSERT INTO CountryLanguage VALUES ('NER','Tamashek','F',10.4);
+INSERT INTO CountryLanguage VALUES ('NGA','Ibo','F',18.1);
+INSERT INTO CountryLanguage VALUES ('NOR','Danish','F',0.4);
+INSERT INTO CountryLanguage VALUES ('CIV','Malinke','F',11.4);
+INSERT INTO CountryLanguage VALUES ('PAK','Sindhi','F',11.8);
+INSERT INTO CountryLanguage VALUES ('PLW','English','T',3.2);
+INSERT INTO CountryLanguage VALUES ('PAN','Guaymí','F',5.3);
+INSERT INTO CountryLanguage VALUES ('PRY','Portuguese','F',3.2);
+INSERT INTO CountryLanguage VALUES ('PER','Aimará','T',2.3);
+INSERT INTO CountryLanguage VALUES ('MNP','Chinese','F',7.1);
+INSERT INTO CountryLanguage VALUES ('POL','Ukrainian','F',0.6);
+INSERT INTO CountryLanguage VALUES ('FRA','Portuguese','F',1.2);
+INSERT INTO CountryLanguage VALUES ('PYF','Chinese','F',2.9);
+INSERT INTO CountryLanguage VALUES ('REU','Comorian','F',2.8);
+INSERT INTO CountryLanguage VALUES ('ROM','Romani','T',0.7);
+INSERT INTO CountryLanguage VALUES ('SWE','Southern Slavic Languages','F',1.3);
+INSERT INTO CountryLanguage VALUES ('DEU','Southern Slavic Languages','F',1.4);
+INSERT INTO CountryLanguage VALUES ('SLB','Polynesian Languages','F',3.8);
+INSERT INTO CountryLanguage VALUES ('ZMB','Nyanja','F',7.8);
+INSERT INTO CountryLanguage VALUES ('WSM','English','T',0.6);
+INSERT INTO CountryLanguage VALUES ('SEN','Serer','F',12.5);
+INSERT INTO CountryLanguage VALUES ('SYC','French','T',1.3);
+INSERT INTO CountryLanguage VALUES ('SLE','Limba','F',8.3);
+INSERT INTO CountryLanguage VALUES ('SGP','Tamil','T',7.4);
+INSERT INTO CountryLanguage VALUES ('SVK','Romani','F',1.7);
+INSERT INTO CountryLanguage VALUES ('SVN','Hungarian','F',0.5);
+INSERT INTO CountryLanguage VALUES ('LKA','Mixed Languages','F',19.6);
+INSERT INTO CountryLanguage VALUES ('SDN','Nubian Languages','F',8.1);
+INSERT INTO CountryLanguage VALUES ('FIN','Russian','F',0.4);
+INSERT INTO CountryLanguage VALUES ('CHE','Italian','T',7.7);
+INSERT INTO CountryLanguage VALUES ('TJK','Russian','F',9.7);
+INSERT INTO CountryLanguage VALUES ('TWN','Hakka','F',11.0);
+INSERT INTO CountryLanguage VALUES ('TZA','Hehet','F',6.9);
+INSERT INTO CountryLanguage VALUES ('DNK','Arabic','F',0.7);
+INSERT INTO CountryLanguage VALUES ('THA','Chinese','F',12.1);
+INSERT INTO CountryLanguage VALUES ('TGO','Watyi','F',10.3);
+INSERT INTO CountryLanguage VALUES ('TTO','Creole English','F',2.9);
+INSERT INTO CountryLanguage VALUES ('TCD','Mayo-kebbi','F',11.5);
+INSERT INTO CountryLanguage VALUES ('CZE','Slovak','F',3.1);
+INSERT INTO CountryLanguage VALUES ('TUN','Arabic-French-English','F',3.2);
+INSERT INTO CountryLanguage VALUES ('TUR','Arabic','F',1.4);
+INSERT INTO CountryLanguage VALUES ('TKM','Russian','F',6.7);
+INSERT INTO CountryLanguage VALUES ('TUV','English','T',0.0);
+INSERT INTO CountryLanguage VALUES ('UGA','Kiga','F',8.3);
+INSERT INTO CountryLanguage VALUES ('UKR','Romanian','F',0.7);
+INSERT INTO CountryLanguage VALUES ('HUN','German','F',0.4);
+INSERT INTO CountryLanguage VALUES ('NCL','Polynesian Languages','F',11.6);
+INSERT INTO CountryLanguage VALUES ('UZB','Tadzhik','F',4.4);
+INSERT INTO CountryLanguage VALUES ('BLR','Ukrainian','F',1.3);
+INSERT INTO CountryLanguage VALUES ('VUT','French','T',14.2);
+INSERT INTO CountryLanguage VALUES ('VEN','Warrau','F',0.1);
+INSERT INTO CountryLanguage VALUES ('RUS','Ukrainian','F',1.3);
+INSERT INTO CountryLanguage VALUES ('VNM','Thai','F',1.6);
+INSERT INTO CountryLanguage VALUES ('EST','Ukrainian','F',2.8);
+INSERT INTO CountryLanguage VALUES ('USA','French','F',0.7);
+INSERT INTO CountryLanguage VALUES ('VIR','French','F',2.5);
+INSERT INTO CountryLanguage VALUES ('ZWE','English','T',2.2);
+INSERT INTO CountryLanguage VALUES ('AFG','Turkmenian','F',1.9);
+INSERT INTO CountryLanguage VALUES ('NLD','Turkish','F',0.8);
+INSERT INTO CountryLanguage VALUES ('AND','French','F',6.2);
+INSERT INTO CountryLanguage VALUES ('AGO','Luimbe-nganguela','F',5.4);
+INSERT INTO CountryLanguage VALUES ('ABW','Dutch','T',5.3);
+INSERT INTO CountryLanguage VALUES ('AUS','Canton Chinese','F',1.1);
+INSERT INTO CountryLanguage VALUES ('AZE','Armenian','F',2.0);
+INSERT INTO CountryLanguage VALUES ('BGD','Garo','F',0.1);
+INSERT INTO CountryLanguage VALUES ('BEL','Arabic','F',1.6);
+INSERT INTO CountryLanguage VALUES ('BLZ','Garifuna','F',6.8);
+INSERT INTO CountryLanguage VALUES ('BEN','Aizo','F',8.7);
+INSERT INTO CountryLanguage VALUES ('BOL','Guaraní','F',0.1);
+INSERT INTO CountryLanguage VALUES ('BWA','Khoekhoe','F',2.5);
+INSERT INTO CountryLanguage VALUES ('BRA','Japanese','F',0.4);
+INSERT INTO CountryLanguage VALUES ('BRN','English','F',3.1);
+INSERT INTO CountryLanguage VALUES ('BGR','Macedonian','F',2.6);
+INSERT INTO CountryLanguage VALUES ('BFA','Busansi','F',3.5);
+INSERT INTO CountryLanguage VALUES ('CHL','Rapa nui','F',0.2);
+INSERT INTO CountryLanguage VALUES ('CRI','Chinese','F',0.2);
+INSERT INTO CountryLanguage VALUES ('ERI','Hadareb','F',3.8);
+INSERT INTO CountryLanguage VALUES ('ESP','Basque','F',1.6);
+INSERT INTO CountryLanguage VALUES ('ZAF','Northsotho','F',9.1);
+INSERT INTO CountryLanguage VALUES ('ETH','Gurage','F',4.7);
+INSERT INTO CountryLanguage VALUES ('PHL','Hiligaynon','F',9.1);
+INSERT INTO CountryLanguage VALUES ('GAB','Mbete','F',13.8);
+INSERT INTO CountryLanguage VALUES ('GMB','Diola','F',9.2);
+INSERT INTO CountryLanguage VALUES ('GEO','Azerbaijani','F',5.5);
+INSERT INTO CountryLanguage VALUES ('GHA','Ga-adangme','F',7.8);
+INSERT INTO CountryLanguage VALUES ('GUM','Korean','F',3.3);
+INSERT INTO CountryLanguage VALUES ('GTM','Kekchí','F',4.9);
+INSERT INTO CountryLanguage VALUES ('GIN','Kissi','F',6.0);
+INSERT INTO CountryLanguage VALUES ('GNB','Portuguese','T',8.1);
+INSERT INTO CountryLanguage VALUES ('HND','Miskito','F',0.2);
+INSERT INTO CountryLanguage VALUES ('HKG','Hakka','F',1.6);
+INSERT INTO CountryLanguage VALUES ('IDN','Madura','F',4.3);
+INSERT INTO CountryLanguage VALUES ('IND','Marathi','F',7.4);
+INSERT INTO CountryLanguage VALUES ('IRQ','Assyrian','F',0.8);
+INSERT INTO CountryLanguage VALUES ('IRN','Gilaki','F',5.3);
+INSERT INTO CountryLanguage VALUES ('ITA','French','F',0.5);
+INSERT INTO CountryLanguage VALUES ('AUT','Hungarian','F',0.4);
+INSERT INTO CountryLanguage VALUES ('JPN','English','F',0.1);
+INSERT INTO CountryLanguage VALUES ('YUG','Romani','F',1.4);
+INSERT INTO CountryLanguage VALUES ('KHM','Tšam','F',2.4);
+INSERT INTO CountryLanguage VALUES ('CMR','Ful','F',9.6);
+INSERT INTO CountryLanguage VALUES ('CAN','Italian','F',1.7);
+INSERT INTO CountryLanguage VALUES ('KAZ','German','F',3.1);
+INSERT INTO CountryLanguage VALUES ('KEN','Kamba','F',11.2);
+INSERT INTO CountryLanguage VALUES ('CAF','Ngbaka','F',7.5);
+INSERT INTO CountryLanguage VALUES ('CHN','Hui','F',0.8);
+INSERT INTO CountryLanguage VALUES ('KGZ','Ukrainian','F',1.7);
+INSERT INTO CountryLanguage VALUES ('COL','Arawakan','F',0.1);
+INSERT INTO CountryLanguage VALUES ('COM','Comorian-Arabic','F',1.6);
+INSERT INTO CountryLanguage VALUES ('COG','Mbete','F',4.8);
+INSERT INTO CountryLanguage VALUES ('COD','Rwanda','F',10.3);
+INSERT INTO CountryLanguage VALUES ('LAO','Lao-Soung','F',5.2);
+INSERT INTO CountryLanguage VALUES ('LVA','Ukrainian','F',2.9);
+INSERT INTO CountryLanguage VALUES ('LBR','Gio','F',7.9);
+INSERT INTO CountryLanguage VALUES ('LTU','Belorussian','F',1.4);
+INSERT INTO CountryLanguage VALUES ('LUX','French','T',4.2);
+INSERT INTO CountryLanguage VALUES ('MAC','English','F',0.5);
+INSERT INTO CountryLanguage VALUES ('MKD','Romani','F',2.3);
+INSERT INTO CountryLanguage VALUES ('MWI','Ngoni','F',6.7);
+INSERT INTO CountryLanguage VALUES ('MYS','Iban','F',2.8);
+INSERT INTO CountryLanguage VALUES ('MLI','Soninke','F',8.7);
+INSERT INTO CountryLanguage VALUES ('MRT','Soninke','F',2.7);
+INSERT INTO CountryLanguage VALUES ('MUS','Hindi','F',1.2);
+INSERT INTO CountryLanguage VALUES ('MEX','Zapotec','F',0.6);
+INSERT INTO CountryLanguage VALUES ('FSM','Kosrean','F',7.3);
+INSERT INTO CountryLanguage VALUES ('MDA','Gagauzi','F',3.2);
+INSERT INTO CountryLanguage VALUES ('MCO','English','F',6.5);
+INSERT INTO CountryLanguage VALUES ('MNG','Bajad','F',1.9);
+INSERT INTO CountryLanguage VALUES ('MOZ','Lomwe','F',7.8);
+INSERT INTO CountryLanguage VALUES ('MMR','Rakhine','F',4.5);
+INSERT INTO CountryLanguage VALUES ('NAM','Afrikaans','F',9.5);
+INSERT INTO CountryLanguage VALUES ('NRU','Tuvalu','F',8.5);
+INSERT INTO CountryLanguage VALUES ('NPL','Tharu','F',5.4);
+INSERT INTO CountryLanguage VALUES ('NIC','Sumo','F',0.2);
+INSERT INTO CountryLanguage VALUES ('NER','Ful','F',9.7);
+INSERT INTO CountryLanguage VALUES ('NGA','Ful','F',11.3);
+INSERT INTO CountryLanguage VALUES ('NOR','Swedish','F',0.3);
+INSERT INTO CountryLanguage VALUES ('CIV','Kru','F',10.5);
+INSERT INTO CountryLanguage VALUES ('PAK','Saraiki','F',9.8);
+INSERT INTO CountryLanguage VALUES ('PLW','Chinese','F',1.6);
+INSERT INTO CountryLanguage VALUES ('PAN','Cuna','F',2.0);
+INSERT INTO CountryLanguage VALUES ('PRY','German','F',0.9);
+INSERT INTO CountryLanguage VALUES ('MNP','Korean','F',6.5);
+INSERT INTO CountryLanguage VALUES ('POL','Belorussian','F',0.5);
+INSERT INTO CountryLanguage VALUES ('FRA','Italian','F',0.4);
+INSERT INTO CountryLanguage VALUES ('REU','Malagasy','F',1.4);
+INSERT INTO CountryLanguage VALUES ('ROM','German','F',0.4);
+INSERT INTO CountryLanguage VALUES ('SWE','Arabic','F',0.8);
+INSERT INTO CountryLanguage VALUES ('DEU','Italian','F',0.7);
+INSERT INTO CountryLanguage VALUES ('ZMB','Lozi','F',6.4);
+INSERT INTO CountryLanguage VALUES ('SEN','Diola','F',5.0);
+INSERT INTO CountryLanguage VALUES ('SLE','Kono-vai','F',5.1);
+INSERT INTO CountryLanguage VALUES ('SVK','Czech and Moravian','F',1.1);
+INSERT INTO CountryLanguage VALUES ('SDN','Beja','F',6.4);
+INSERT INTO CountryLanguage VALUES ('FIN','Estonian','F',0.2);
+INSERT INTO CountryLanguage VALUES ('CHE','Romansh','T',0.6);
+INSERT INTO CountryLanguage VALUES ('TWN','Ami','F',0.6);
+INSERT INTO CountryLanguage VALUES ('TZA','Haya','F',5.9);
+INSERT INTO CountryLanguage VALUES ('DNK','German','F',0.5);
+INSERT INTO CountryLanguage VALUES ('THA','Malay','F',3.6);
+INSERT INTO CountryLanguage VALUES ('TGO','Kotokoli','F',5.7);
+INSERT INTO CountryLanguage VALUES ('TCD','Kanem-bornu','F',9.0);
+INSERT INTO CountryLanguage VALUES ('CZE','Polish','F',0.6);
+INSERT INTO CountryLanguage VALUES ('TKM','Kazakh','F',2.0);
+INSERT INTO CountryLanguage VALUES ('UGA','Soga','F',8.2);
+INSERT INTO CountryLanguage VALUES ('UKR','Bulgariana','F',0.3);
+INSERT INTO CountryLanguage VALUES ('HUN','Serbo-Croatian','F',0.2);
+INSERT INTO CountryLanguage VALUES ('UZB','Kazakh','F',3.8);
+INSERT INTO CountryLanguage VALUES ('BLR','Polish','F',0.6);
+INSERT INTO CountryLanguage VALUES ('RUS','Chuvash','F',0.9);
+INSERT INTO CountryLanguage VALUES ('VNM','Muong','F',1.5);
+INSERT INTO CountryLanguage VALUES ('EST','Belorussian','F',1.4);
+INSERT INTO CountryLanguage VALUES ('USA','German','F',0.7);
+INSERT INTO CountryLanguage VALUES ('ZWE','Nyanja','F',2.2);
+INSERT INTO CountryLanguage VALUES ('AFG','Balochi','F',0.9);
+INSERT INTO CountryLanguage VALUES ('AGO','Nyaneka-nkhumbi','F',5.4);
+INSERT INTO CountryLanguage VALUES ('AUS','Arabic','F',1.0);
+INSERT INTO CountryLanguage VALUES ('BGD','Khasi','F',0.1);
+INSERT INTO CountryLanguage VALUES ('BEL','German','T',1.0);
+INSERT INTO CountryLanguage VALUES ('BEN','Bariba','F',8.7);
+INSERT INTO CountryLanguage VALUES ('BWA','Ndebele','F',1.3);
+INSERT INTO CountryLanguage VALUES ('BRA','Indian Languages','F',0.2);
+INSERT INTO CountryLanguage VALUES ('BFA','Dagara','F',3.1);
+INSERT INTO CountryLanguage VALUES ('ERI','Bilin','F',3.0);
+INSERT INTO CountryLanguage VALUES ('ZAF','English','T',8.5);
+INSERT INTO CountryLanguage VALUES ('ETH','Somali','F',4.1);
+INSERT INTO CountryLanguage VALUES ('PHL','Bicol','F',5.7);
+INSERT INTO CountryLanguage VALUES ('GMB','Soninke','F',7.6);
+INSERT INTO CountryLanguage VALUES ('GEO','Osseetti','F',2.4);
+INSERT INTO CountryLanguage VALUES ('GHA','Gurma','F',3.3);
+INSERT INTO CountryLanguage VALUES ('GUM','Japanese','F',2.0);
+INSERT INTO CountryLanguage VALUES ('GTM','Mam','F',2.7);
+INSERT INTO CountryLanguage VALUES ('GIN','Kpelle','F',4.6);
+INSERT INTO CountryLanguage VALUES ('GNB','Malinke','F',6.9);
+INSERT INTO CountryLanguage VALUES ('HKG','Chiu chau','F',1.4);
+INSERT INTO CountryLanguage VALUES ('IDN','Minangkabau','F',2.4);
+INSERT INTO CountryLanguage VALUES ('IND','Tamil','F',6.3);
+INSERT INTO CountryLanguage VALUES ('IRQ','Persian','F',0.8);
+INSERT INTO CountryLanguage VALUES ('IRN','Luri','F',4.3);
+INSERT INTO CountryLanguage VALUES ('ITA','German','F',0.5);
+INSERT INTO CountryLanguage VALUES ('AUT','Slovene','F',0.4);
+INSERT INTO CountryLanguage VALUES ('JPN','Philippene Languages','F',0.1);
+INSERT INTO CountryLanguage VALUES ('YUG','Slovak','F',0.7);
+INSERT INTO CountryLanguage VALUES ('CMR','Tikar','F',7.4);
+INSERT INTO CountryLanguage VALUES ('CAN','German','F',1.6);
+INSERT INTO CountryLanguage VALUES ('KAZ','Uzbek','F',2.3);
+INSERT INTO CountryLanguage VALUES ('KEN','Kalenjin','F',10.8);
+INSERT INTO CountryLanguage VALUES ('CAF','Sara','F',6.4);
+INSERT INTO CountryLanguage VALUES ('CHN','Miao','F',0.7);
+INSERT INTO CountryLanguage VALUES ('KGZ','Tatar','F',1.3);
+INSERT INTO CountryLanguage VALUES ('COL','Caribbean','F',0.1);
+INSERT INTO CountryLanguage VALUES ('COM','Comorian-Swahili','F',0.5);
+INSERT INTO CountryLanguage VALUES ('COG','Punu','F',2.9);
+INSERT INTO CountryLanguage VALUES ('COD','Zande','F',6.1);
+INSERT INTO CountryLanguage VALUES ('LVA','Polish','F',2.1);
+INSERT INTO CountryLanguage VALUES ('LBR','Kru','F',7.2);
+INSERT INTO CountryLanguage VALUES ('LTU','Ukrainian','F',1.1);
+INSERT INTO CountryLanguage VALUES ('LUX','German','T',2.3);
+INSERT INTO CountryLanguage VALUES ('MKD','Serbo-Croatian','F',2.0);
+INSERT INTO CountryLanguage VALUES ('MYS','English','F',1.6);
+INSERT INTO CountryLanguage VALUES ('MLI','Tamashek','F',7.3);
+INSERT INTO CountryLanguage VALUES ('MRT','Ful','F',1.2);
+INSERT INTO CountryLanguage VALUES ('MUS','Tamil','F',0.8);
+INSERT INTO CountryLanguage VALUES ('MEX','Mixtec','F',0.6);
+INSERT INTO CountryLanguage VALUES ('FSM','Yap','F',5.8);
+INSERT INTO CountryLanguage VALUES ('MDA','Bulgariana','F',1.6);
+INSERT INTO CountryLanguage VALUES ('MNG','Buryat','F',1.7);
+INSERT INTO CountryLanguage VALUES ('MOZ','Shona','F',6.5);
+INSERT INTO CountryLanguage VALUES ('MMR','Mon','F',2.4);
+INSERT INTO CountryLanguage VALUES ('NAM','Herero','F',8.0);
+INSERT INTO CountryLanguage VALUES ('NRU','English','T',7.5);
+INSERT INTO CountryLanguage VALUES ('NPL','Tamang','F',4.9);
+INSERT INTO CountryLanguage VALUES ('NER','Kanuri','F',4.4);
+INSERT INTO CountryLanguage VALUES ('NGA','Ibibio','F',5.6);
+INSERT INTO CountryLanguage VALUES ('NOR','Saame','F',0.0);
+INSERT INTO CountryLanguage VALUES ('CIV','[South]Mande','F',7.7);
+INSERT INTO CountryLanguage VALUES ('PAK','Urdu','T',7.6);
+INSERT INTO CountryLanguage VALUES ('PAN','Embera','F',0.6);
+INSERT INTO CountryLanguage VALUES ('MNP','English','T',4.8);
+INSERT INTO CountryLanguage VALUES ('FRA','Spanish','F',0.4);
+INSERT INTO CountryLanguage VALUES ('REU','Tamil','F',0.0);
+INSERT INTO CountryLanguage VALUES ('ROM','Ukrainian','F',0.3);
+INSERT INTO CountryLanguage VALUES ('SWE','Spanish','F',0.6);
+INSERT INTO CountryLanguage VALUES ('DEU','Greek','F',0.4);
+INSERT INTO CountryLanguage VALUES ('ZMB','Chewa','F',5.7);
+INSERT INTO CountryLanguage VALUES ('SEN','Malinke','F',3.8);
+INSERT INTO CountryLanguage VALUES ('SLE','Bullom-sherbro','F',3.8);
+INSERT INTO CountryLanguage VALUES ('SVK','Ukrainian and Russian','F',0.6);
+INSERT INTO CountryLanguage VALUES ('SDN','Nuer','F',4.9);
+INSERT INTO CountryLanguage VALUES ('FIN','Saame','F',0.0);
+INSERT INTO CountryLanguage VALUES ('TWN','Atayal','F',0.4);
+INSERT INTO CountryLanguage VALUES ('TZA','Makonde','F',5.9);
+INSERT INTO CountryLanguage VALUES ('DNK','English','F',0.3);
+INSERT INTO CountryLanguage VALUES ('THA','Khmer','F',1.3);
+INSERT INTO CountryLanguage VALUES ('TGO','Ane','F',5.7);
+INSERT INTO CountryLanguage VALUES ('TCD','Ouaddai','F',8.7);
+INSERT INTO CountryLanguage VALUES ('CZE','German','F',0.5);
+INSERT INTO CountryLanguage VALUES ('UGA','Teso','F',6.0);
+INSERT INTO CountryLanguage VALUES ('UKR','Hungarian','F',0.3);
+INSERT INTO CountryLanguage VALUES ('HUN','Romanian','F',0.1);
+INSERT INTO CountryLanguage VALUES ('UZB','Karakalpak','F',2.0);
+INSERT INTO CountryLanguage VALUES ('RUS','Bashkir','F',0.7);
+INSERT INTO CountryLanguage VALUES ('VNM','Chinese','F',1.4);
+INSERT INTO CountryLanguage VALUES ('EST','Finnish','F',0.7);
+INSERT INTO CountryLanguage VALUES ('USA','Italian','F',0.6);
+INSERT INTO CountryLanguage VALUES ('AGO','Chokwe','F',4.2);
+INSERT INTO CountryLanguage VALUES ('AUS','Vietnamese','F',0.8);
+INSERT INTO CountryLanguage VALUES ('BGD','Santhali','F',0.1);
+INSERT INTO CountryLanguage VALUES ('BEL','Turkish','F',0.9);
+INSERT INTO CountryLanguage VALUES ('BEN','Somba','F',6.7);
+INSERT INTO CountryLanguage VALUES ('BFA','Dyula','F',2.6);
+INSERT INTO CountryLanguage VALUES ('ERI','Saho','F',3.0);
+INSERT INTO CountryLanguage VALUES ('ZAF','Tswana','F',8.1);
+INSERT INTO CountryLanguage VALUES ('ETH','Sidamo','F',3.2);
+INSERT INTO CountryLanguage VALUES ('PHL','Waray-waray','F',3.8);
+INSERT INTO CountryLanguage VALUES ('GEO','Abhyasi','F',1.7);
+INSERT INTO CountryLanguage VALUES ('GHA','Joruba','F',1.3);
+INSERT INTO CountryLanguage VALUES ('GIN','Yalunka','F',2.9);
+INSERT INTO CountryLanguage VALUES ('GNB','Mandyako','F',4.9);
+INSERT INTO CountryLanguage VALUES ('IDN','Batakki','F',2.2);
+INSERT INTO CountryLanguage VALUES ('IND','Urdu','F',5.1);
+INSERT INTO CountryLanguage VALUES ('IRN','Mazandarani','F',3.6);
+INSERT INTO CountryLanguage VALUES ('ITA','Albaniana','F',0.2);
+INSERT INTO CountryLanguage VALUES ('AUT','Polish','F',0.2);
+INSERT INTO CountryLanguage VALUES ('JPN','Ainu','F',0.0);
+INSERT INTO CountryLanguage VALUES ('YUG','Macedonian','F',0.5);
+INSERT INTO CountryLanguage VALUES ('CMR','Mandara','F',5.7);
+INSERT INTO CountryLanguage VALUES ('CAN','Polish','F',0.7);
+INSERT INTO CountryLanguage VALUES ('KAZ','Tatar','F',2.0);
+INSERT INTO CountryLanguage VALUES ('KEN','Gusii','F',6.1);
+INSERT INTO CountryLanguage VALUES ('CAF','Mbum','F',6.4);
+INSERT INTO CountryLanguage VALUES ('CHN','Uighur','F',0.6);
+INSERT INTO CountryLanguage VALUES ('KGZ','Kazakh','F',0.8);
+INSERT INTO CountryLanguage VALUES ('COG','Sango','F',2.6);
+INSERT INTO CountryLanguage VALUES ('COD','Ngala and Bangi','F',5.8);
+INSERT INTO CountryLanguage VALUES ('LVA','Lithuanian','F',1.2);
+INSERT INTO CountryLanguage VALUES ('LBR','Mano','F',7.2);
+INSERT INTO CountryLanguage VALUES ('MYS','Dusun','F',1.1);
+INSERT INTO CountryLanguage VALUES ('MLI','Songhai','F',6.9);
+INSERT INTO CountryLanguage VALUES ('MRT','Zenaga','F',1.2);
+INSERT INTO CountryLanguage VALUES ('MUS','Marathi','F',0.7);
+INSERT INTO CountryLanguage VALUES ('MEX','Otomí','F',0.4);
+INSERT INTO CountryLanguage VALUES ('FSM','Wolea','F',3.7);
+INSERT INTO CountryLanguage VALUES ('MNG','Dariganga','F',1.4);
+INSERT INTO CountryLanguage VALUES ('MOZ','Tswa','F',6.0);
+INSERT INTO CountryLanguage VALUES ('MMR','Chin','F',2.2);
+INSERT INTO CountryLanguage VALUES ('NAM','Caprivi','F',4.7);
+INSERT INTO CountryLanguage VALUES ('NPL','Newari','F',3.7);
+INSERT INTO CountryLanguage VALUES ('NGA','Kanuri','F',4.1);
+INSERT INTO CountryLanguage VALUES ('PAK','Balochi','F',3.0);
+INSERT INTO CountryLanguage VALUES ('PAN','Arabic','F',0.6);
+INSERT INTO CountryLanguage VALUES ('MNP','Carolinian','F',4.8);
+INSERT INTO CountryLanguage VALUES ('FRA','Turkish','F',0.4);
+INSERT INTO CountryLanguage VALUES ('ROM','Serbo-Croatian','F',0.1);
+INSERT INTO CountryLanguage VALUES ('SWE','Norwegian','F',0.5);
+INSERT INTO CountryLanguage VALUES ('DEU','Polish','F',0.3);
+INSERT INTO CountryLanguage VALUES ('ZMB','Nsenga','F',4.3);
+INSERT INTO CountryLanguage VALUES ('SEN','Soninke','F',1.3);
+INSERT INTO CountryLanguage VALUES ('SLE','Ful','F',3.8);
+INSERT INTO CountryLanguage VALUES ('SDN','Zande','F',2.7);
+INSERT INTO CountryLanguage VALUES ('TWN','Paiwan','F',0.3);
+INSERT INTO CountryLanguage VALUES ('TZA','Nyakusa','F',5.4);
+INSERT INTO CountryLanguage VALUES ('DNK','Swedish','F',0.3);
+INSERT INTO CountryLanguage VALUES ('THA','Kuy','F',1.1);
+INSERT INTO CountryLanguage VALUES ('TGO','Moba','F',5.4);
+INSERT INTO CountryLanguage VALUES ('TCD','Hadjarai','F',6.7);
+INSERT INTO CountryLanguage VALUES ('CZE','Silesiana','F',0.4);
+INSERT INTO CountryLanguage VALUES ('UGA','Lango','F',5.9);
+INSERT INTO CountryLanguage VALUES ('UKR','Belorussian','F',0.3);
+INSERT INTO CountryLanguage VALUES ('HUN','Slovak','F',0.1);
+INSERT INTO CountryLanguage VALUES ('UZB','Tatar','F',1.8);
+INSERT INTO CountryLanguage VALUES ('RUS','Chechen','F',0.6);
+INSERT INTO CountryLanguage VALUES ('VNM','Khmer','F',1.4);
+INSERT INTO CountryLanguage VALUES ('USA','Chinese','F',0.6);
+INSERT INTO CountryLanguage VALUES ('AGO','Luvale','F',3.6);
+INSERT INTO CountryLanguage VALUES ('AUS','Serbo-Croatian','F',0.6);
+INSERT INTO CountryLanguage VALUES ('BGD','Tripuri','F',0.1);
+INSERT INTO CountryLanguage VALUES ('BEN','Ful','F',5.6);
+INSERT INTO CountryLanguage VALUES ('ZAF','Southsotho','F',7.6);
+INSERT INTO CountryLanguage VALUES ('ETH','Walaita','F',2.8);
+INSERT INTO CountryLanguage VALUES ('PHL','Pampango','F',3.0);
+INSERT INTO CountryLanguage VALUES ('GIN','Loma','F',2.3);
+INSERT INTO CountryLanguage VALUES ('IDN','Bugi','F',2.2);
+INSERT INTO CountryLanguage VALUES ('IND','Gujarati','F',4.8);
+INSERT INTO CountryLanguage VALUES ('IRN','Balochi','F',2.3);
+INSERT INTO CountryLanguage VALUES ('ITA','Slovene','F',0.2);
+INSERT INTO CountryLanguage VALUES ('AUT','Czech','F',0.2);
+INSERT INTO CountryLanguage VALUES ('CMR','Maka','F',4.9);
+INSERT INTO CountryLanguage VALUES ('CAN','Spanish','F',0.7);
+INSERT INTO CountryLanguage VALUES ('KEN','Meru','F',5.5);
+INSERT INTO CountryLanguage VALUES ('CHN','Yi','F',0.6);
+INSERT INTO CountryLanguage VALUES ('KGZ','Tadzhik','F',0.8);
+INSERT INTO CountryLanguage VALUES ('COD','Rundi','F',3.8);
+INSERT INTO CountryLanguage VALUES ('LBR','Loma','F',5.8);
+INSERT INTO CountryLanguage VALUES ('MOZ','Chuabo','F',5.7);
+INSERT INTO CountryLanguage VALUES ('MMR','Kachin','F',1.4);
+INSERT INTO CountryLanguage VALUES ('NAM','San','F',1.9);
+INSERT INTO CountryLanguage VALUES ('NPL','Hindi','F',3.0);
+INSERT INTO CountryLanguage VALUES ('NGA','Edo','F',3.3);
+INSERT INTO CountryLanguage VALUES ('PAK','Hindko','F',2.4);
+INSERT INTO CountryLanguage VALUES ('SLE','Kuranko','F',3.4);
+INSERT INTO CountryLanguage VALUES ('SDN','Bari','F',2.5);
+INSERT INTO CountryLanguage VALUES ('TZA','Chaga and Pare','F',4.9);
+INSERT INTO CountryLanguage VALUES ('DNK','Norwegian','F',0.3);
+INSERT INTO CountryLanguage VALUES ('TGO','Naudemba','F',4.1);
+INSERT INTO CountryLanguage VALUES ('TCD','Tandjile','F',6.5);
+INSERT INTO CountryLanguage VALUES ('CZE','Romani','F',0.3);
+INSERT INTO CountryLanguage VALUES ('UGA','Lugbara','F',4.7);
+INSERT INTO CountryLanguage VALUES ('UKR','Polish','F',0.1);
+INSERT INTO CountryLanguage VALUES ('RUS','Mordva','F',0.5);
+INSERT INTO CountryLanguage VALUES ('VNM','Nung','F',1.1);
+INSERT INTO CountryLanguage VALUES ('USA','Tagalog','F',0.4);
+INSERT INTO CountryLanguage VALUES ('AGO','Ambo','F',2.4);
+INSERT INTO CountryLanguage VALUES ('AUS','German','F',0.6);
+INSERT INTO CountryLanguage VALUES ('ZAF','Tsonga','F',4.3);
+INSERT INTO CountryLanguage VALUES ('PHL','Pangasinan','F',1.8);
+INSERT INTO CountryLanguage VALUES ('IDN','Banja','F',1.8);
+INSERT INTO CountryLanguage VALUES ('IND','Kannada','F',3.9);
+INSERT INTO CountryLanguage VALUES ('IRN','Arabic','F',2.2);
+INSERT INTO CountryLanguage VALUES ('ITA','Romani','F',0.2);
+INSERT INTO CountryLanguage VALUES ('AUT','Romanian','F',0.2);
+INSERT INTO CountryLanguage VALUES ('CMR','Masana','F',3.9);
+INSERT INTO CountryLanguage VALUES ('CAN','Portuguese','F',0.7);
+INSERT INTO CountryLanguage VALUES ('KEN','Nyika','F',4.8);
+INSERT INTO CountryLanguage VALUES ('CHN','Tujia','F',0.5);
+INSERT INTO CountryLanguage VALUES ('COD','Teke','F',2.7);
+INSERT INTO CountryLanguage VALUES ('LBR','Malinke','F',5.1);
+INSERT INTO CountryLanguage VALUES ('MOZ','Ronga','F',3.7);
+INSERT INTO CountryLanguage VALUES ('MMR','Kayah','F',0.4);
+INSERT INTO CountryLanguage VALUES ('NAM','German','F',0.9);
+INSERT INTO CountryLanguage VALUES ('NGA','Tiv','F',2.3);
+INSERT INTO CountryLanguage VALUES ('PAK','Brahui','F',1.2);
+INSERT INTO CountryLanguage VALUES ('SLE','Yalunka','F',3.4);
+INSERT INTO CountryLanguage VALUES ('SDN','Fur','F',2.1);
+INSERT INTO CountryLanguage VALUES ('TZA','Luguru','F',4.9);
+INSERT INTO CountryLanguage VALUES ('TGO','Gurma','F',3.4);
+INSERT INTO CountryLanguage VALUES ('TCD','Gorane','F',6.2);
+INSERT INTO CountryLanguage VALUES ('CZE','Hungarian','F',0.2);
+INSERT INTO CountryLanguage VALUES ('UGA','Gisu','F',4.5);
+INSERT INTO CountryLanguage VALUES ('RUS','Kazakh','F',0.4);
+INSERT INTO CountryLanguage VALUES ('VNM','Miao','F',0.9);
+INSERT INTO CountryLanguage VALUES ('USA','Polish','F',0.3);
+INSERT INTO CountryLanguage VALUES ('AGO','Luchazi','F',2.4);
+INSERT INTO CountryLanguage VALUES ('ZAF','Swazi','F',2.5);
+INSERT INTO CountryLanguage VALUES ('PHL','Maguindanao','F',1.4);
+INSERT INTO CountryLanguage VALUES ('IDN','Bali','F',1.7);
+INSERT INTO CountryLanguage VALUES ('IND','Malajalam','F',3.6);
+INSERT INTO CountryLanguage VALUES ('IRN','Bakhtyari','F',1.7);
+INSERT INTO CountryLanguage VALUES ('CAN','Punjabi','F',0.7);
+INSERT INTO CountryLanguage VALUES ('KEN','Masai','F',1.6);
+INSERT INTO CountryLanguage VALUES ('CHN','Mongolian','F',0.4);
+INSERT INTO CountryLanguage VALUES ('COD','Boa','F',2.3);
+INSERT INTO CountryLanguage VALUES ('MOZ','Marendje','F',3.5);
+INSERT INTO CountryLanguage VALUES ('NGA','Ijo','F',1.8);
+INSERT INTO CountryLanguage VALUES ('SDN','Chilluk','F',1.7);
+INSERT INTO CountryLanguage VALUES ('TZA','Shambala','F',4.3);
+INSERT INTO CountryLanguage VALUES ('UGA','Acholi','F',4.4);
+INSERT INTO CountryLanguage VALUES ('RUS','Avarian','F',0.4);
+INSERT INTO CountryLanguage VALUES ('VNM','Man','F',0.7);
+INSERT INTO CountryLanguage VALUES ('USA','Korean','F',0.3);
+INSERT INTO CountryLanguage VALUES ('ZAF','Venda','F',2.2);
+INSERT INTO CountryLanguage VALUES ('PHL','Maranao','F',1.3);
+INSERT INTO CountryLanguage VALUES ('IND','Orija','F',3.3);
+INSERT INTO CountryLanguage VALUES ('IRN','Turkmenian','F',1.6);
+INSERT INTO CountryLanguage VALUES ('CAN','Ukrainian','F',0.6);
+INSERT INTO CountryLanguage VALUES ('KEN','Turkana','F',1.4);
+INSERT INTO CountryLanguage VALUES ('CHN','Tibetan','F',0.4);
+INSERT INTO CountryLanguage VALUES ('COD','Chokwe','F',1.8);
+INSERT INTO CountryLanguage VALUES ('MOZ','Nyanja','F',3.3);
+INSERT INTO CountryLanguage VALUES ('NGA','Bura','F',1.6);
+INSERT INTO CountryLanguage VALUES ('SDN','Lotuko','F',1.5);
+INSERT INTO CountryLanguage VALUES ('TZA','Gogo','F',3.9);
+INSERT INTO CountryLanguage VALUES ('UGA','Rwanda','F',3.2);
+INSERT INTO CountryLanguage VALUES ('RUS','Mari','F',0.4);
+INSERT INTO CountryLanguage VALUES ('USA','Vietnamese','F',0.2);
+INSERT INTO CountryLanguage VALUES ('ZAF','Ndebele','F',1.5);
+INSERT INTO CountryLanguage VALUES ('IND','Punjabi','F',2.8);
+INSERT INTO CountryLanguage VALUES ('CAN','Dutch','F',0.5);
+INSERT INTO CountryLanguage VALUES ('CHN','Puyi','F',0.2);
+INSERT INTO CountryLanguage VALUES ('TZA','Ha','F',3.5);
+INSERT INTO CountryLanguage VALUES ('RUS','Udmur','F',0.3);
+INSERT INTO CountryLanguage VALUES ('USA','Japanese','F',0.2);
+INSERT INTO CountryLanguage VALUES ('IND','Asami','F',1.5);
+INSERT INTO CountryLanguage VALUES ('CAN','Eskimo Languages','F',0.1);
+INSERT INTO CountryLanguage VALUES ('CHN','Dong','F',0.2);
+INSERT INTO CountryLanguage VALUES ('RUS','Belorussian','F',0.3);
+INSERT INTO CountryLanguage VALUES ('USA','Portuguese','F',0.2);
+
+/*!40000 ALTER TABLE CountryLanguage ENABLE KEYS */;
+
diff --git a/Makefile.am b/Makefile.am
index 35db77c684e..87d1c7b5b71 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,17 +20,23 @@ AUTOMAKE_OPTIONS = foreign
# These are built from source in the Docs directory
EXTRA_DIST = INSTALL-SOURCE README \
- COPYING COPYING.LIB MIRRORS
+ COPYING COPYING.LIB
SUBDIRS = include @docs_dirs@ @readline_dir@ \
- @thread_dirs@ @sql_client_dirs@ \
- @sql_server_dirs@ scripts tests man \
- @bench_dirs@ support-files os2
+ @thread_dirs@ pstack @sql_client_dirs@ \
+ @sql_server_dirs@ @libmysqld_dirs@ scripts man \
+ tests BUILD os2 \
+ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@
# Relink after clean
-CLEANFILES = linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources linked_include_sources
+linked_sources = linked_client_sources linked_server_sources \
+ linked_libmysql_sources linked_libmysql_r_sources \
+ linked_libmysqld_sources linked_libmysqldex_sources \
+ linked_include_sources
+
+CLEANFILES = $(linked_sources)
# This is just so that the linking is done early.
-config.h: linked_include_sources linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources
+config.h: $(linked_sources)
linked_include_sources:
cd include; $(MAKE) link_sources
@@ -48,6 +54,14 @@ linked_libmysql_r_sources: linked_libmysql_sources
cd libmysql_r; $(MAKE) link_sources
echo timestamp > linked_libmysql_r_sources
+linked_libmysqld_sources:
+ cd libmysqld; $(MAKE) link_sources
+ echo timestamp > linked_libmysqld_sources
+
+linked_libmysqldex_sources:
+ cd libmysqld/examples; $(MAKE) link_sources
+ echo timestamp > linked_libmysqldex_sources
+
#avoid recursive make calls in sql directory
linked_server_sources:
cd sql; rm -f mini_client_errors.c;@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
@@ -60,9 +74,12 @@ init-db: all
bin-dist: all
$(top_builddir)/scripts/make_binary_distribution
+tags:
+ support-files/build-tags
.PHONY: init-db bin-dist
# Test installation
test:
cd mysql-test ; ./mysql-test-run
+
diff --git a/README b/README
index b1f4ab52369..29851358765 100644
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
This is a release of MySQL, a GPL (free) SQL database server (more
licence information in the PUBLIC file and in the reference manual).
-Please read the Upgrading section in the manual if emigration from
-3.20.# to 3.21.#. Otherwise it wont work!!
+Please read the "Upgrading from..." section in the manual first, if you are
+migrating from older versions of MySQL!
The latest information about MySQL can be found at:
http://www.mysql.com
@@ -24,13 +24,11 @@ For examples of SQL and benchmarking information see the bench
directory.
The manual mentioned above can be found in the Docs directory. The
-manual is available in the following formats: as text in
-Docs/manual.txt, as HTML in Docs/manual_toc.html, as GNU Info in
+manual is available in the following formats: as plain ASCII text in
+Docs/manual.txt, in HTML format in Docs/manual_toc.html, as GNU Info in
Docs/mysql.info and as PostScript in Docs/manual.ps.
-For a contributed user manual see http://www.turbolift.com/mysql.
-
-MySQL is brought to you by the MySQL team at MySQL AB
+MySQL is brought to you by the MySQL team at MySQL AB
For a list of developers and other contributors, see the Credits appendix
in the manual.
@@ -48,7 +46,7 @@ and start your editor with a form in which you can describe your
problem. Bug reports might be silently ignored by the MySQL
maintainers if there is not a good reason included in the report as to
why mysqlbug has not been used. A report that says 'MySQL does not
-work for me. Why?' is not consider a valid bug report.
+work for me. Why?' is not considered a valid bug report.
-The mysqlbug script can be found in the 'scripts' directory in the
-distribution, that is 'there-you-installed-mysql/scripts'.
+The mysqlbug script can be found in the 'scripts' directory of the
+distribution, that is '<where-you-installed-mysql>/scripts'.
diff --git a/SSL/NOTES b/SSL/NOTES
new file mode 100644
index 00000000000..413c724c583
--- /dev/null
+++ b/SSL/NOTES
@@ -0,0 +1,376 @@
+Quick notes:
+--------------------------------------------
+[tonu@x153 mysql-4.0]$ cat /etc/my.cnf
+[mysqld]
+ssl-ca=SSL/cacert.pem
+ssl-cert=SSL/server-cert.pem
+ssl-key=SSL/server-key.pem
+
+[mysql]
+ssl-ca=SSL/cacert.pem
+ssl-cert=SSL/client-cert.pem
+ssl-key=SSL/client-key.pem
+
+[mysqldump]
+ssl-ca=SSL/cacert.pem
+ssl-cert=SSL/client-cert.pem
+ssl-key=SSL/client-key.pem
+
+[tonu@x153 mysql-4.0]$
+--------------------------------------------
+To remove passwords from keyfiles:
+[tonu@x153 SSL]$ openssl rsa -inform pem < server-req.pem > server-key.pem
+read RSA key
+Enter PEM pass phrase:
+writing RSA key
+[tonu@x153 SSL]$
+--------------------------------------------
+To run server:
+
+sql/mysqld --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/server-cert.pem --ssl-key=SSL/server-key.pem --skip-grant --debug='d:t:O,-' > /tmp/mysqld.trace
+--------------------------------------------
+To run client:
+
+client/mysql --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/server-cert.pem --ssl-key=SSL/server-key.pem --debug='d:t:O,/tmp/client.trace' -h 127.0.0.1
+--------------------------------------------
+openssl s_client -host 127.0.0.1 -port 1111 -debug -verify 1 -cert ../SSL/client-cert.pem -key ../SSL/client-key.pem -CAfile ../SSL/cacert.pem -pause -showcerts -state
+
+--------------------------------------------
+openssl s_server -port 1111 -cert ../SSL/server-cert.pem -key ../SSL/server-key.pem
+
+
+
+
+--------------------------------------------
+
+CA stuff:
+
+[tonu@x153 bin]$ pwd
+/usr/local/ssl/bin
+[tonu@x153 bin]$
+[tonu@x153 bin]$ ./CA.sh
+[tonu@x153 bin]$ ./CA.sh -h
+usage: CA -newcert|-newreq|-newca|-sign|-verify
+[tonu@x153 bin]$
+[root@x153 bin]# ./CA.sh -newca
+CA certificate filename (or enter to create)
+
+Making CA certificate ...
+Using configuration from /usr/lib/ssl/openssl.cnf
+Generating a 1024 bit RSA private key
+.++++++
+................++++++
+writing new private key to './demoCA/private/./cakey.pem'
+Enter PEM pass phrase:
+Verifying password - Enter PEM pass phrase:
+phrase is too short, needs to be at least 4 chars
+Enter PEM pass phrase:
+Verifying password - Enter PEM pass phrase:
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+ountry Name (2 letter code) [AU]:FI
+State or Province Name (full name) [Some-State]:
+Locality Name (eg, city) []:Helsinki
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL Finland AB
+Organizational Unit Name (eg, section) []:
+Common Name (eg, YOUR name) []:Tonu Samuel
+Email Address []:tonu@mysql.com
+[root@x153 bin]#
+[root@x153 bin]# ls -la demoCA/
+total 13
+drwxr-xr-x 6 root root 232 Jun 24 18:50 ./
+drwxr-xr-x 3 root root 2136 Jun 24 18:41 ../
+-rw-r--r-- 1 root root 1241 Jun 24 18:50 cacert.pem
+drwxr-xr-x 2 root root 48 Jun 24 18:41 certs/
+drwxr-xr-x 2 root root 48 Jun 24 18:41 crl/
+-rw-r--r-- 1 root root 0 Jun 24 18:44 index.txt
+drwxr-xr-x 2 root root 48 Jun 24 18:41 newcerts/
+drwxr-xr-x 2 root root 80 Jun 24 18:44 private/
+-rw-r--r-- 1 root root 3 Jun 24 18:44 serial
+[root@x153 bin]#
+[root@x153 bin]# ls -la demoCA/private/
+total 5
+drwxr-xr-x 2 root root 80 Jun 24 18:44 ./
+drwxr-xr-x 6 root root 232 Jun 24 18:50 ../
+-rw-r--r-- 1 root root 963 Jun 24 18:50 cakey.pem
+[root@x153 bin]#
+[root@x153 bin]# ./CA.sh -newreq
+Using configuration from /usr/lib/ssl/openssl.cnf
+Generating a 1024 bit RSA private key
+..................++++++
+........................++++++
+writing new private key to 'newreq.pem'
+Enter PEM pass phrase: <- new key password, not CA
+Verifying password - Enter PEM pass phrase:
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:EE
+State or Province Name (full name) [Some-State]:
+Locality Name (eg, city) []:Tallinn
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:Noname
+Organizational Unit Name (eg, section) []:
+Common Name (eg, YOUR name) []:Mr Noname
+Email Address []:a@b.c
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:
+An optional company name []:
+Request (and private key) is in newreq.pem
+[root@x153 bin]#
+[root@x153 bin]# ls -la newreq.pem
+-rw-r--r-- 1 root root 1623 Jun 24 18:54 newreq.pem
+[root@x153 bin]#
+[root@x153 bin]# ./CA.sh -sign
+Using configuration from /usr/lib/ssl/openssl.cnf
+Enter PEM pass phrase: <- CA's one!
+Check that the request matches the signature
+Signature ok
+The Subjects Distinguished Name is as follows
+countryName :PRINTABLE:'EE'
+stateOrProvinceName :PRINTABLE:'Some-State'
+localityName :PRINTABLE:'Tallinn'
+organizationName :PRINTABLE:'Noname'
+commonName :PRINTABLE:'Mr Noname'
+emailAddress :IA5STRING:'a@b.c'
+Certificate is to be certified until Jun 24 15:50:23 2002 GMT (365 days)
+Sign the certificate? [y/n]:y
+
+
+1 out of 1 certificate requests certified, commit? [y/n]y
+Write out database with 1 new entries
+Data Base Updated
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com
+ Validity
+ Not Before: Jun 24 15:50:23 2001 GMT
+ Not After : Jun 24 15:50:23 2002 GMT
+ Subject: C=EE, ST=Some-State, L=Tallinn, O=Noname, CN=Mr Noname/Email=a@b.c
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:ab:3b:7d:5b:6c:93:f6:46:1a:2c:46:73:6f:89:
+ 8a:99:bb:e9:6b:94:0d:74:aa:aa:c4:5c:a2:61:cf:
+ 56:bb:a1:a9:5a:37:c4:4e:b2:ec:5c:18:3a:a4:8d:
+ af:3d:23:66:7c:85:7f:d1:f2:e3:fc:16:a7:4c:a2:
+ d6:45:06:92:75:d8:a2:3b:f9:aa:77:da:26:b9:87:
+ e0:df:50:54:e4:36:9f:35:87:39:8e:a6:7c:3e:a8:
+ e4:49:1a:76:c2:6f:73:0b:22:93:2a:04:67:0d:7d:
+ ae:34:5c:fe:7c:29:b8:a2:fe:1e:ef:d1:0c:4d:dd:
+ 5b:7a:67:b0:0a:22:88:a0:af
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 83:D1:0D:52:0F:DE:61:2D:A6:10:20:B8:46:0C:77:D5:D2:D0:BE:20
+ X509v3 Authority Key Identifier:
+ keyid:A5:0A:D6:72:B5:DF:E4:C2:2B:7B:07:5E:D3:4D:52:07:E1:83:6B:7F
+ DirName:/C=FI/ST=Some-State/L=Helsinki/O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@mysql.com
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+ 60:85:f7:d0:54:2a:67:88:0e:37:a6:a8:8e:fd:a0:c9:a1:d7:
+ c6:fc:4c:2e:59:8d:88:6d:69:0a:b8:b2:67:5f:81:94:39:0e:
+ ab:67:fc:8b:62:de:85:f6:b3:8c:2d:1a:e3:dc:28:fc:f5:99:
+ 39:f0:3d:50:ca:88:c0:8e:f8:c2:02:5d:34:19:63:9f:c4:a2:
+ f6:a8:81:c9:8d:6d:bd:c4:42:4a:0c:49:5a:cc:24:ea:65:80:
+ dd:79:20:89:9e:ea:6b:80:7a:86:f9:bb:6d:24:3c:80:13:5b:
+ e6:16:fc:3d:8d:f6:16:ea:33:25:c6:90:20:81:a4:b0:15:2e:
+ 9c:1c
+-----BEGIN CERTIFICATE-----
+MIIDfjCCAuegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
+EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
+ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
+SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTU1MDIzWhcNMDIwNjI0
+MTU1MDIzWjBvMQswCQYDVQQGEwJFRTETMBEGA1UECBMKU29tZS1TdGF0ZTEQMA4G
+A1UEBxMHVGFsbGlubjEPMA0GA1UEChMGTm9uYW1lMRIwEAYDVQQDEwlNciBOb25h
+bWUxFDASBgkqhkiG9w0BCQEWBWFAYi5jMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQCrO31bbJP2RhosRnNviYqZu+lrlA10qqrEXKJhz1a7oalaN8ROsuxcGDqk
+ja89I2Z8hX/R8uP8FqdMotZFBpJ12KI7+ap32ia5h+DfUFTkNp81hzmOpnw+qORJ
+GnbCb3MLIpMqBGcNfa40XP58Kbii/h7v0QxN3Vt6Z7AKIoigrwIDAQABo4IBETCC
+AQ0wCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFIPRDVIP3mEtphAguEYMd9XS0L4gMIGyBgNV
+HSMEgaowgaeAFKUK1nK13+TCK3sHXtNNUgfhg2t/oYGLpIGIMIGFMQswCQYDVQQG
+EwJGSTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEBxMISGVsc2lua2kxGTAX
+BgNVBAoTEE15U1FMIEZpbmxhbmQgQUIxFDASBgNVBAMTC1RvbnUgU2FtdWVsMR0w
+GwYJKoZIhvcNAQkBFg50b251QG15c3FsLmNvbYIBADANBgkqhkiG9w0BAQQFAAOB
+gQBghffQVCpniA43pqiO/aDJodfG/EwuWY2IbWkKuLJnX4GUOQ6rZ/yLYt6F9rOM
+LRrj3Cj89Zk58D1QyojAjvjCAl00GWOfxKL2qIHJjW29xEJKDElazCTqZYDdeSCJ
+nuprgHqG+bttJDyAE1vmFvw9jfYW6jMlxpAggaSwFS6cHA==
+-----END CERTIFICATE-----
+Signed certificate is in newcert.pem
+[root@x153 bin]# ls -la demoCA/newcerts/
+total 5
+drwxr-xr-x 2 root root 72 Jun 24 18:58 ./
+drwxr-xr-x 6 root root 296 Jun 24 18:58 ../
+-rw-r--r-- 1 root root 3533 Jun 24 18:58 01.pem
+[root@x153 bin]#
+[root@x153 mysql-4.0]# ./sql/mysqld --ssl-cert=SSL/server-cert.pem --ssl-ca=SSL/cacert.pem --ssl-ke
+y=SSL/server-req.pem -L /home/tonu/mysql-4.0/sql/share/english/ -u root
+Enter PEM pass phrase:
+./sql/mysqld: ready for connections
+[tonu@x153 mysql-4.0]$ client/mysql --ssl-key=SSL/client-req.pem --ssl-ca=SSL/cacert.pem --ssl-cert
+=SSL/client-cert.pem
+Enter PEM pass phrase:
+ERROR:
+
+[tonu@x153 mysql-4.0]$
+
+
+
+
+-8<------------------------
+SSL encrypts data between MySQL server and client.
+
+You need openssl (formerly SSLeay) for MySQL SSL support. Development
+and testing was done on openssl version 0.9.3a
+
+To compile MySQL one must do:
+./configure --with-openssl=/usr
+
+or
+
+./configure --with-openssl=yes
+
+There are sample keys and certificates included with MySQL tarball in
+directory ./SSL. They are meant to be for quick start and
+testing only. Using them in production environment means same as not
+using encryption. This is because private keys are publicly
+accessible for everyone. You must use openssl distribution for new key
+and certificate generation for both client and server.
+
+----------- for manual: ---------------------
+*New API calls:*
+
+mysql_ssl_set() - Set SSL properties (key, certificate,
+certificates authority certificate). Must be called before
+mysql_real_connect();
+mysql_ssl_clear() - Clear and free resources occupied by
+mysql_ssl_set() API call.
+char *mysql_ssl_cipher(MYSQL *) - returns cipher in use. For example
+"DES-CDC3-SHA" means that you have combined triple DES symmetric
+algorithm and SHA
+hashing algorithm.
+
+
+*New command line switches:*
+--ssl Use SSL for connection (automatically set with
+other flags. This means one can use encrypted connection without strong
+cryptological authentication. Normally one must use all switches
+together including ssl-key, ssl-cert and ssl-ca and never mind about
+--ssl because this is assumed by defult if any of them (--ssl-...)
+included.
+--ssl-key X509 key in PEM format (implies --ssl)
+--ssl-cert X509 cert in PEM format (implies --ssl)
+--ssl-ca CA file in PEM format (check OpenSSL docs,
+implies --ssl)
+--ssl-capath CA directory (check OpenSSL docs, implies --ssl
+ ----------------
+ This is about using SSL in MySQL privilege system. My idea is to make
+ possible use of x509 certificates and keys instead of MySQL native
+ passwords
+Some basic theory about crypt, SSL and x509:
+x509 is standard for certificates. SSL is standard for secure
+communication. Certificates are issued by someone anyone can trust. This
+trusted party is called "Certificate Authority" or "CA". This is
+someone, we MUST trust. Everyone must have some "fingerprint" of CA (so
+called "CA certificate" or "CA cert") using which one can verify
+authenticity of other
+certificates issued by this CA. CA uses his power to give certificates
+to persons (they can be physical (like "monty") or logical (like some
+process). Person is identified by "subject" like
+"/C=EE/ST=Harjumaa/L=Tallinn/O=MySQL client bogus certificate/CN=Tonu
+Samuel/Email=<EMAIL: PROTECTED>". and signed cryptologically. This sign can be
+verified using CA-cert. So, if we trust CA, then we can trust identity
+of user.
+There can be many CA-s (usually not but who knows). Also there can be
+some users we don`t trust or have different privileges. This means we
+must have one table to hold CA-certs and other table to hold so called
+"subjects" (users). I think it`s a good idea to use existing structure
+of host/user/db/field and add some x509 relationship. Then we can
+use usual simple user/host pair or x509 subject/CA pair.
+So I think user must grant rights using old method GRANT blabla ON
+blabla TO blabla IDENTIFIED BY blabla
+or new way:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla
+IDENTIFIED BY X509 SUBJECT "/C=EE/ST=Harjumaa/L=Tallinn/O=MySQL client
+bogus certificate/CN=Tonu Samuel/Email=<EMAIL: PROTECTED>" AND ISSUER
+"/C=EE/ST=Harjumaa/L=Tallinn/O=TCX AB/CN=Tonu
+Samuel/Email=<EMAIL: PROTECTED>";
+-----------8<---------------------------
+Please note the difference in Subject and Issuer. This command requests
+user to authenticate itself with exact subject and exact certificate
+issuer. Next possibility is just have any certificate of some good CA:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY X509 ISSUER
+"/C=EE/ST=Harjumaa/L=Tallinn/O=TCX
+AB/CN=Tonu Samuel/Email=<EMAIL: PROTECTED>";
+-----------8<---------------------------
+or if any registered CA is good enough (usual case when only one CA is
+registered)
+but we care about exact user, then something like:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY X509 SUBJECT
+"/C=EE/ST=Harjumaa/L=Tallinn/O=MySQL client
+bogus certificate/CN=Tonu Samuel/Email=<EMAIL: PROTECTED>";
+-----------8<---------------------------
+And case if user must authenticate itself but we don`t care about exact
+person until he have some certificate issued by CA registered in our
+system:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY X509;
+-----------8<---------------------------
+Then additionally we need one exception. Let`s assume we need SSL
+encryption
+for preventing eavesdropping but we don`t care who it is at all. We need
+privilege to exclude all non-SSL users but we accept anyone using SSL.
+How
+this must be done in GRANT syntax? Maybe:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla
+IDENTIFIED BY blabla AND USING SSL
+-----------8<---------------------------
+But maybe we want to add in future possibility to check different
+algorithms and key lengths? Something like:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY blabla AND USING SSL WITH
+CIPHER "DES-CBC3-SHA" OR "DES-CBC3-MD5"
+-----------8<---------------------------
+Also we need some command to include/exclude CA certificates. This must
+be some commands like INSERT/DELETE/UPDATE/REPLACE to do it.
+All examples is given for clarify my problem. I asking for help because
+I don`t know
+any similar command in other SQL-s.
+------------8<------------------------
+
+So, at moment SSL communications is ready and working. I don`t have this
+command iterface at moment yet and this can be changed a lot if someone
+can suggest good idea or reason to change them. We are ready to listen
+every opinion.
+About Kerberos: I just don`t know much about it. I have to read this
+again before I can comment. I never used it itself and forgot most of
+theory. Sorry. Anyway now the problem/need is known and I will put
+thinking about this in personal TODO.
+
+
diff --git a/SSL/cacert.pem b/SSL/cacert.pem
new file mode 100644
index 00000000000..862e07114c5
--- /dev/null
+++ b/SSL/cacert.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDaDCCAtGgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
+EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
+ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
+SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTU0MzE4WhcNMDIwNjI0
+MTU0MzE4WjCBhTELMAkGA1UEBhMCRkkxEzARBgNVBAgTClNvbWUtU3RhdGUxETAP
+BgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQKExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYD
+VQQDEwtUb251IFNhbXVlbDEdMBsGCSqGSIb3DQEJARYOdG9udUBteXNxbC5jb20w
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJz9FCvWX8c+Xr6mxzfZvPainIPT
+ODNsQ0f2kAs0epP+peUn4LHxLybp2dkUHTtJLXyUyk7cXfnUd+0fRazK2/Vz48bZ
+swGwg9Rhg3P02Ku+CMWYulHzN6uVRzfrDUSkDoky2DGL3A6B8P4JRc2qcr+kjhh5
+6r1VJlXs9N3DqeEdAgMBAAGjgeUwgeIwHQYDVR0OBBYEFKUK1nK13+TCK3sHXtNN
+Ugfhg2t/MIGyBgNVHSMEgaowgaeAFKUK1nK13+TCK3sHXtNNUgfhg2t/oYGLpIGI
+MIGFMQswCQYDVQQGEwJGSTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEBxMI
+SGVsc2lua2kxGTAXBgNVBAoTEE15U1FMIEZpbmxhbmQgQUIxFDASBgNVBAMTC1Rv
+bnUgU2FtdWVsMR0wGwYJKoZIhvcNAQkBFg50b251QG15c3FsLmNvbYIBADAMBgNV
+HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAI+YJKoa+IP3WYr8iLcVk5j7lZ9D
+GS8reuALafnE7VX1xMlXP5EnJjT7YYYmtiB2tYj7+eQ+ajRXWWyY5NtO5ob+dm8z
+OBX43v08C5vNSAFpwZWTutzb0nSd8kOABGJ04MBDJZk8QNkTfU6C7c3ZJ/gW8Guv
+I+cxfz6oCYEfKLBN
+-----END CERTIFICATE-----
diff --git a/SSL/client-cert.pem b/SSL/client-cert.pem
new file mode 100644
index 00000000000..cab2a635d9f
--- /dev/null
+++ b/SSL/client-cert.pem
@@ -0,0 +1,67 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3 (0x3)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com
+ Validity
+ Not Before: Jun 24 16:03:20 2001 GMT
+ Not After : Jun 24 16:03:20 2002 GMT
+ Subject: C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@mysql.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:e8:d4:52:cd:4e:bb:96:16:3a:f0:89:6b:90:4c:
+ db:e0:30:75:5a:02:72:62:bf:ed:da:be:09:e8:80:
+ db:80:54:30:d6:75:ed:e3:10:a5:15:44:5b:29:91:
+ 12:fe:0c:b7:76:4d:e9:5f:56:5c:45:3c:ad:b2:71:
+ 2d:6a:7a:cb:bc:04:80:08:74:d6:7d:f6:7c:5c:76:
+ db:35:c4:f6:f5:d8:d4:89:9f:9d:cc:3f:4e:3f:73:
+ c1:3e:41:7e:4e:09:bf:ea:1a:d9:a2:13:0d:d1:0c:
+ da:d8:f4:9b:b8:54:21:17:ae:d7:b3:02:61:87:a9:
+ 01:ff:f4:fe:9c:7a:fc:67:43
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ BC:FB:BB:8F:C4:85:BA:5F:A8:F2:C3:3D:C9:0F:DB:16:E7:13:BC:B2
+ X509v3 Authority Key Identifier:
+ keyid:A5:0A:D6:72:B5:DF:E4:C2:2B:7B:07:5E:D3:4D:52:07:E1:83:6B:7F
+ DirName:/C=FI/ST=Some-State/L=Helsinki/O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@mysql.com
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+ 1c:e0:87:2c:2f:b3:a4:39:44:7f:96:7b:2f:c9:1f:91:84:0b:
+ 9f:d0:0a:f8:40:70:d0:dd:bd:91:0a:c6:d5:ac:8f:51:77:9c:
+ 35:28:e8:b6:5f:57:9e:5c:b5:9b:ae:5d:3d:7c:05:45:2e:89:
+ 3a:03:e1:f2:00:cb:c1:ed:3e:48:3b:5f:4e:50:d2:b4:a5:36:
+ 0f:1a:dc:79:49:1e:03:2f:27:c1:e4:62:d6:ef:3f:ab:2e:ab:
+ dd:e5:bc:cb:20:a3:dd:ab:81:69:26:9c:03:42:1b:4c:b7:aa:
+ 57:6d:2a:de:c0:5e:6e:74:d0:83:90:ec:ad:bb:ba:f0:cc:cf:
+ 41:3d
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAwqgAwIBAgIBAzANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
+EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
+ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
+SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTYwMzIwWhcNMDIwNjI0
+MTYwMzIwWjCBkTELMAkGA1UEBhMCRUUxEzARBgNVBAgTClNvbWUtU3RhdGUxEDAO
+BgNVBAcTB1RhbGxpbm4xJjAkBgNVBAoTHU15U1FMIGRlbW8gY2xpZW50IGNlcnRp
+ZmljYXRlMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqGSIb3DQEJARYOdG9u
+dUBteXNxbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjUUs1Ou5YW
+OvCJa5BM2+AwdVoCcmK/7dq+CeiA24BUMNZ17eMQpRVEWymREv4Mt3ZN6V9WXEU8
+rbJxLWp6y7wEgAh01n32fFx22zXE9vXY1Imfncw/Tj9zwT5Bfk4Jv+oa2aITDdEM
+2tj0m7hUIReu17MCYYepAf/0/px6/GdDAgMBAAGjggERMIIBDTAJBgNVHRMEAjAA
+MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
+BgNVHQ4EFgQUvPu7j8SFul+o8sM9yQ/bFucTvLIwgbIGA1UdIwSBqjCBp4AUpQrW
+crXf5MIrewde001SB+GDa3+hgYukgYgwgYUxCzAJBgNVBAYTAkZJMRMwEQYDVQQI
+EwpTb21lLVN0YXRlMREwDwYDVQQHEwhIZWxzaW5raTEZMBcGA1UEChMQTXlTUUwg
+RmlubGFuZCBBQjEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
+DnRvbnVAbXlzcWwuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBABzghywvs6Q5RH+W
+ey/JH5GEC5/QCvhAcNDdvZEKxtWsj1F3nDUo6LZfV55ctZuuXT18BUUuiToD4fIA
+y8HtPkg7X05Q0rSlNg8a3HlJHgMvJ8HkYtbvP6suq93lvMsgo92rgWkmnANCG0y3
+qldtKt7AXm500IOQ7K27uvDMz0E9
+-----END CERTIFICATE-----
diff --git a/SSL/client-key.pem b/SSL/client-key.pem
new file mode 100644
index 00000000000..7672939b60a
--- /dev/null
+++ b/SSL/client-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDo1FLNTruWFjrwiWuQTNvgMHVaAnJiv+3avgnogNuAVDDWde3j
+EKUVRFspkRL+DLd2TelfVlxFPK2ycS1qesu8BIAIdNZ99nxcdts1xPb12NSJn53M
+P04/c8E+QX5OCb/qGtmiEw3RDNrY9Ju4VCEXrtezAmGHqQH/9P6cevxnQwIDAQAB
+AoGBANxd4cUaaOfkQILbvigE5vMpSlkYCcW3XNv1lJEwLREoHlVNpwuL/IPFf/c2
+rWAxDw/1LBYlOg36IXjMMC0g7mRHHoJhdJaFLGdlfclYQvqQ+8JAsAv6UNC63+pn
+B5sZOxOuoj7lYN+D9mFVD4qTo3eTUYEOvvmS1j3hCsD2nNNBAkEA+lJUs7Y3KjCF
+COZ7XQCkC47rVzkdZ5ey1Z+vVw5SrnUvj6n9i0NEax1jX6JPIhPU7+x90KFkt0ki
+pKHd7UQ04wJBAO4caWNnYvmIorCRDy9Q/iAAow5WC6fQlkSlBIe3lRme6Ne8Yxaq
+BzlSGYu1ndPkTGEa9PFNNCJm7RtvCBFx8iECQQCkdUzi2Rc7J69vnoV0H8SnN1mU
+75hLBBZhVU1MY8OcjK8XsvY59ZLQ0PkFzswwtljS3Ev4suBJrsoM4a+9f29DAkEA
+5NTrN3vZc6SrbXLLHBcDUrAqBBIPe4SLlYbdVqzInunILeS/eb2H2b+cC1dMSaHj
+AYONmQUwMEuoXTAUmede4QJARK6jEslg/ev8BtMvITP2b6pRCb1w8lOtT5u5Bwnc
+NpI3suqSQSQPtRSWQYcdyxrKr2TQEZU7h8R9bVB4b0qAmQ==
+-----END RSA PRIVATE KEY-----
diff --git a/SSL/client-req.pem b/SSL/client-req.pem
new file mode 100644
index 00000000000..ef11a22165f
--- /dev/null
+++ b/SSL/client-req.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,8CE2AB38FB50D4B9
+
+rrnYZLUKlzV4U7+wqe5CWzTd4RLJb5h4M77aBRQfuHGejSaRsskN2ffpO8uQEAYM
+WTJSRC+NO+jDMBZhzt1ktWqCs8d6l6azHoBybIrMJsbUhwybm+OiOfp23RrbNoS/
+S4fsgNdAAGhsRvKDdsItCyYvdH8nTzn+g9r/z2V4tOOXd6MYuT42XA6Uz2tis2SZ
+GWEGa7mAweApzSiibE+pzjPS+fdX4E12n6NCVYLhn1JuvzVva/KFSebs4Wh75miC
+WvRgkt/5eDQn+vkV67hE3I6p9pPcLh1+PMfaQ25U8VM/r7ejnVFWm7teGH6GKPKJ
+cU+PYfblyWcgtiO/fwfGMIqSyNtHj/C3VFVie5D1MTJzBopiPGEcfz00LjBccjjh
+j1meTRVN8pMZTgkxlnIFwbU6TPPvx8a9urFVQIJ4z8r2EMvYh5Cqpq87+lH9Pn0C
+vzCl78Tz5QLghXNnMbbdD2aPP0PwPEXgh86iZxo06g85n0l26WUzYJlWzBYD4DrF
+SbnEUAftTujEOm6MqJNLpJN6UPOtq/HvSaHl1bykGK+zU4gqHj0ur03HlF0l4xNg
+OfsoNsJV+O9RUUJ0+D5eqUALJjN8TCV1wNMXOVzr/ue3QCVdlWVfZY4RPffwK9Yp
+Fh52T7a2v+shhqZUQNtFDAg50Ac7deUthSWNmi5N680POnJg9KdtBdMhYLa1j3rP
+D9oasSK0ugevHuQ6wUiD/95CzZlJXE9K4kTTYmaRk5MTWXhFQxdqHZo1v+pGtaNI
+f+/E7q7BiNesSt31U/vkX0Tm3oJ1dgOnS8M2uxiYiKH2mJ/E32tZKw==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIIB0jCCATsCAQAwgZExCzAJBgNVBAYTAkVFMRMwEQYDVQQIEwpTb21lLVN0YXRl
+MRAwDgYDVQQHEwdUYWxsaW5uMSYwJAYDVQQKEx1NeVNRTCBkZW1vIGNsaWVudCBj
+ZXJ0aWZpY2F0ZTEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
+DnRvbnVAbXlzcWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo1FLN
+TruWFjrwiWuQTNvgMHVaAnJiv+3avgnogNuAVDDWde3jEKUVRFspkRL+DLd2Telf
+VlxFPK2ycS1qesu8BIAIdNZ99nxcdts1xPb12NSJn53MP04/c8E+QX5OCb/qGtmi
+Ew3RDNrY9Ju4VCEXrtezAmGHqQH/9P6cevxnQwIDAQABoAAwDQYJKoZIhvcNAQEE
+BQADgYEAvENK1JAQfC8xnrFGw2IxfUmUwlRidiRtYTgtVfTr7vA+m4WaaKioni6E
+PQXjcvl6kfyRoxc4qWsGi3T7QM2RnvCtbwR2NGSIKX1cBTS31RMr12NSAeXn6Twz
+ZwSZ55EHj9N2hArTPNlVjxvDQX3D6/ZBi6JnHAxXigzDqhArgjU=
+-----END CERTIFICATE REQUEST-----
diff --git a/SSL/run-client b/SSL/run-client
new file mode 100755
index 00000000000..f3b29eb273b
--- /dev/null
+++ b/SSL/run-client
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+cmd () {
+ echo $*
+ $*
+}
+
+client/mysql --port=4407 --socket=/tmp/test.mysql.sock --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/client-cert.pem --ssl-key=SSL/client-key.pem --debug='d:t:O,/tmp/client.trace' -h 127.0.0.1 -u root
+#--execute="select version();show status"
+
diff --git a/SSL/run-server b/SSL/run-server
new file mode 100755
index 00000000000..e90a7644b83
--- /dev/null
+++ b/SSL/run-server
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+cmd () {
+ echo $*
+ $*
+}
+
+cmd sql/mysqld --port=4407 --socket=/tmp/test.mysql.sock --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/server-cert.pem --ssl-key=SSL/server-key.pem --debug='d:t:O,/tmp/mysqld.trace' -uroot >& /tmp/mysqld.output
+
diff --git a/SSL/server-cert.pem b/SSL/server-cert.pem
new file mode 100644
index 00000000000..069063a9de9
--- /dev/null
+++ b/SSL/server-cert.pem
@@ -0,0 +1,67 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com
+ Validity
+ Not Before: Jun 24 16:02:28 2001 GMT
+ Not After : Jun 24 16:02:28 2002 GMT
+ Subject: C=EE, ST=Some-State, L=Tallinn, O=MySQL server demo certificate, CN=Tonu Samuel/Email=tonu@mysql.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:9e:ac:8d:d8:1d:9c:b2:fd:88:96:2c:ba:42:53:
+ fa:5d:bd:85:8a:e5:ca:d3:0f:c0:01:3c:f2:92:46:
+ 4f:d9:80:ae:2a:89:cf:ef:e8:d4:65:fc:f6:f5:3a:
+ 26:4c:29:db:06:fa:34:a1:87:f3:97:b5:3c:94:f1:
+ 84:05:ac:ad:57:25:d9:02:db:00:71:e0:a9:aa:b4:
+ 1d:29:36:5e:a9:a4:0d:f2:45:b9:83:74:2b:45:f3:
+ e2:23:bc:e7:5c:e6:11:b6:f6:dd:c4:ac:ed:65:42:
+ 2c:39:47:2a:c9:eb:5f:45:03:10:ab:23:bc:ca:5c:
+ 82:9a:b7:b3:6d:67:18:d2:c7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 94:68:BF:DA:F6:E2:09:EF:3A:C8:27:AE:D7:B7:02:F0:DC:4B:C1:3B
+ X509v3 Authority Key Identifier:
+ keyid:A5:0A:D6:72:B5:DF:E4:C2:2B:7B:07:5E:D3:4D:52:07:E1:83:6B:7F
+ DirName:/C=FI/ST=Some-State/L=Helsinki/O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@mysql.com
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+ 8c:1a:90:70:f6:1a:70:0e:c9:28:93:74:e2:2b:b8:2a:d0:ce:
+ 40:15:e8:af:44:f8:89:16:20:f5:c2:b9:ed:aa:4e:3c:40:e2:
+ 9c:62:aa:48:98:ac:17:84:ef:35:72:59:43:09:35:17:c5:9a:
+ 3e:3d:ef:97:bf:57:f2:2a:f6:56:5d:a4:7c:68:58:b9:d6:9b:
+ 0f:57:0e:55:22:17:b0:b7:77:27:4f:da:b3:88:c1:6d:d6:8f:
+ 31:ec:0d:a2:25:60:66:2f:0f:86:8a:d6:08:b8:71:b1:b5:70:
+ 60:04:56:96:ff:bd:5e:ed:94:bc:44:bd:24:e0:2f:90:e5:23:
+ 51:4e
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAwqgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
+EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
+ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
+SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTYwMjI4WhcNMDIwNjI0
+MTYwMjI4WjCBkTELMAkGA1UEBhMCRUUxEzARBgNVBAgTClNvbWUtU3RhdGUxEDAO
+BgNVBAcTB1RhbGxpbm4xJjAkBgNVBAoTHU15U1FMIHNlcnZlciBkZW1vIGNlcnRp
+ZmljYXRlMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqGSIb3DQEJARYOdG9u
+dUBteXNxbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ6sjdgdnLL9
+iJYsukJT+l29hYrlytMPwAE88pJGT9mAriqJz+/o1GX89vU6Jkwp2wb6NKGH85e1
+PJTxhAWsrVcl2QLbAHHgqaq0HSk2XqmkDfJFuYN0K0Xz4iO851zmEbb23cSs7WVC
+LDlHKsnrX0UDEKsjvMpcgpq3s21nGNLHAgMBAAGjggERMIIBDTAJBgNVHRMEAjAA
+MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
+BgNVHQ4EFgQUlGi/2vbiCe86yCeu17cC8NxLwTswgbIGA1UdIwSBqjCBp4AUpQrW
+crXf5MIrewde001SB+GDa3+hgYukgYgwgYUxCzAJBgNVBAYTAkZJMRMwEQYDVQQI
+EwpTb21lLVN0YXRlMREwDwYDVQQHEwhIZWxzaW5raTEZMBcGA1UEChMQTXlTUUwg
+RmlubGFuZCBBQjEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
+DnRvbnVAbXlzcWwuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAIwakHD2GnAOySiT
+dOIruCrQzkAV6K9E+IkWIPXCue2qTjxA4pxiqkiYrBeE7zVyWUMJNRfFmj4975e/
+V/Iq9lZdpHxoWLnWmw9XDlUiF7C3dydP2rOIwW3WjzHsDaIlYGYvD4aK1gi4cbG1
+cGAEVpb/vV7tlLxEvSTgL5DlI1FO
+-----END CERTIFICATE-----
diff --git a/SSL/server-key.pem b/SSL/server-key.pem
new file mode 100644
index 00000000000..44137ca1c94
--- /dev/null
+++ b/SSL/server-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCerI3YHZyy/YiWLLpCU/pdvYWK5crTD8ABPPKSRk/ZgK4qic/v
+6NRl/Pb1OiZMKdsG+jShh/OXtTyU8YQFrK1XJdkC2wBx4KmqtB0pNl6ppA3yRbmD
+dCtF8+IjvOdc5hG29t3ErO1lQiw5RyrJ619FAxCrI7zKXIKat7NtZxjSxwIDAQAB
+AoGAA51gudyq1jUKaIlqUNqC6KHJqglkHnzMXfrad9ScOxNAZH2xPADs3cnuglWp
+y7BkaftHOarUNM+PKsF5xXtSk5F9UUV+7h2FtPZYUshUgn5hkGZP12otxJMP0cpg
+Yt6brQxuOIe/r/Kt5r3nKpp4pyFLX2fGWQq7pSjdkgSZSOECQQDJ9MgbCXd81yde
+eo3+YmUPBEQ9d7mivQsyPHMOHLPJKR42N4npdR1zLDBYK5lFzJeQH1y0Uce3O8eL
+hM8hkA1XAkEAySKvNTaosbLhShkRazQyQQJYJg0F/93lkQ33ou4crru7Mvi2OZK9
+B3BGAmNpSv6ZOZYjM0aE8lGlTaoYJ9GQEQJAGJDyFnfcVQ9G9rMpupv1dxIpyuBZ
+cHZWelHoHPtY00txJV80I3Xfkzb42oDTMC5m8V0fRb/870kSSOJq38ZKGQJBAIgq
+wxLzfiFPSNYxQmmhXKRGQgcAqh8eylv5aL0VFrX0wjcvya4QeYifqcXUJ2RuGK2z
+xwDfrQGf5Jk/njrW1QECQAUofd1l9DLDifRP1j9sjUdwz0fvqQ0o6sbt39PBl1ot
+IHdc3nf9z0ft+KOG1CT/M9jYo9SzE9Z6IfwmHxxpY0s=
+-----END RSA PRIVATE KEY-----
diff --git a/SSL/server-req.pem b/SSL/server-req.pem
new file mode 100644
index 00000000000..4cd6610e735
--- /dev/null
+++ b/SSL/server-req.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,6CBD09E71246DC01
+
+byRzq5+j3r8FX2kQerTUZT5Bw/N6zrN3cmH6NHGJcrqD+vcPdtWf+Rk+mpNXgSQn
+ldkfmniU/htzJ0cUV+KE229Qx10Hx9mIJIbf0Y/rBCUBuaXWVrQB36W9w3rkNPFA
+EEuRMkreOJF42RD16+NBJv+RcHIGzGejXecJKUGF5DKlN0U8YHXnkXTQl54kIdr0
+H7rTrvJygwPk9/ik0M9/vmwduAMvTaHDmvgeolpMlJkxwz8vYkbUnFFJZhB6XNCb
+1w3lJ0EmRJicK5BnZmCEmgt8xiv0PAtg00jBbwddQbn1reAyViBtBT9iXdusHXS5
+Po63rSt7r3MO8aetcMQ6FkklH+ChuS/vFoNY57AwrzF4uEI4GSoZP0ESrRC5Ar5W
+Lzg/HrQAWbPCRlb6Jj3db1woRzFS8joOashROsZdeV/5P4Emhc6J7QMTvB1OHAhQ
+ugOJazJtxjg0DN8+9cM1wtHI7N89PLHhOg13LZNLeeehzIlPwKI2JLqXUc6oR407
+i+S7GCqu7wU+if0Enux8Dj7yrvnTUiqVCL2dyKTS3sBq0Cm2UhbecHclor13y6no
+y1o50TKKD6Zig2hZmSpqKznMxGMVIT36BE0aOMQUmk+aVnRuROclwTTL0ZNLzA+g
+QRTRfQ6iNMf34ypqAMdAMPzDGLPycKuFdxVQxFEVaM2/mrdWFwVAqFsLvzyGvdrh
+nkNyRgTWR/pfH9b3mXLqf6gMPNs764WhFIcZIDk9a4XBBUm2YDb2CxDzDCo/EUMA
+jvIiU0Jt132SEHHF/wAka6d2DnwZ3vexRp6Tebv/uy9IlMLPE+68dw==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIIB0jCCATsCAQAwgZExCzAJBgNVBAYTAkVFMRMwEQYDVQQIEwpTb21lLVN0YXRl
+MRAwDgYDVQQHEwdUYWxsaW5uMSYwJAYDVQQKEx1NeVNRTCBzZXJ2ZXIgZGVtbyBj
+ZXJ0aWZpY2F0ZTEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
+DnRvbnVAbXlzcWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCerI3Y
+HZyy/YiWLLpCU/pdvYWK5crTD8ABPPKSRk/ZgK4qic/v6NRl/Pb1OiZMKdsG+jSh
+h/OXtTyU8YQFrK1XJdkC2wBx4KmqtB0pNl6ppA3yRbmDdCtF8+IjvOdc5hG29t3E
+rO1lQiw5RyrJ619FAxCrI7zKXIKat7NtZxjSxwIDAQABoAAwDQYJKoZIhvcNAQEE
+BQADgYEAlrUnGX4LYIiVjztHA4gUcOSVeEHCci2qEUq+7yY1JhAw54YDa2MLTTwa
+cH+rXLHjN0MTNfv9tRxdSX+trk3pyvhgFjssD100dJkF83RfVv2tKg9kscVOGQp7
+MkwOnJjfAjQBlTbTOQM46BTjv2FgvsppkO3ViryI//YxKvj/628=
+-----END CERTIFICATE REQUEST-----
diff --git a/VC++Files/InstallShield/Script Files/Setup.dbg b/VC++Files/InstallShield/Script Files/Setup.dbg
new file mode 100644
index 00000000000..0c6d4e6b708
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.dbg
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.ino b/VC++Files/InstallShield/Script Files/Setup.ino
new file mode 100644
index 00000000000..204d8ea0f36
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.ino
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.ins b/VC++Files/InstallShield/Script Files/Setup.ins
new file mode 100644
index 00000000000..759009b5c84
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.ins
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.obs b/VC++Files/InstallShield/Script Files/Setup.obs
new file mode 100644
index 00000000000..5fcfcb62c4e
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.obs
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.rul b/VC++Files/InstallShield/Script Files/Setup.rul
new file mode 100644
index 00000000000..df143b493c4
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.rul
@@ -0,0 +1,640 @@
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// IIIIIII SSSSSS
+// II SS InstallShield (R)
+// II SSSSSS (c) 1996-1997, InstallShield Software Corporation
+// II SS (c) 1990-1996, InstallShield Corporation
+// IIIIIII SSSSSS All Rights Reserved.
+//
+//
+// This code is generated as a starting setup template. You should
+// modify it to provide all necessary steps for your setup.
+//
+//
+// File Name: Setup.rul
+//
+// Description: InstallShield script
+//
+// Comments: This template script performs a basic setup on a
+// Windows 95 or Windows NT 4.0 platform. With minor
+// modifications, this template can be adapted to create
+// new, customized setups.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+ // Include header file
+#include "sdlang.h"
+#include "sddialog.h"
+
+////////////////////// string defines ////////////////////////////
+
+#define UNINST_LOGFILE_NAME "Uninst.isu"
+
+//////////////////// installation declarations ///////////////////
+
+ // ----- DLL prototypes -----
+
+
+ // your DLL prototypes
+
+
+ // ---- script prototypes -----
+
+ // generated
+ prototype ShowDialogs();
+ prototype MoveFileData();
+ prototype HandleMoveDataError( NUMBER );
+ prototype ProcessBeforeDataMove();
+ prototype ProcessAfterDataMove();
+ prototype SetupRegistry();
+ prototype SetupFolders();
+ prototype CleanUpInstall();
+ prototype SetupInstall();
+ prototype SetupScreen();
+ prototype CheckRequirements();
+ prototype DialogShowSdWelcome();
+ prototype DialogShowSdShowInfoList();
+ prototype DialogShowSdAskDestPath();
+ prototype DialogShowSdSetupType();
+ prototype DialogShowSdComponentDialog2();
+ prototype DialogShowSdFinishReboot();
+
+ // your prototypes
+
+
+ // ----- global variables ------
+
+ // generated
+ BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup;
+ STRING svDir;
+ STRING svName, svCompany, svSerial;
+ STRING szAppPath;
+ STRING svSetupType;
+
+
+ // your global variables
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// MAIN PROGRAM
+//
+// The setup begins here by hiding the visible setup
+// window. This is done to allow all the titles, images, etc. to
+// be established before showing the main window. The following
+// logic then performs the setup in a series of steps.
+//
+///////////////////////////////////////////////////////////////////////////////
+program
+ Disable( BACKGROUND );
+
+ CheckRequirements();
+
+ SetupInstall();
+
+ SetupScreen();
+
+ if (ShowDialogs()<0) goto end_install;
+
+ if (ProcessBeforeDataMove()<0) goto end_install;
+
+ if (MoveFileData()<0) goto end_install;
+
+ if (ProcessAfterDataMove()<0) goto end_install;
+
+ if (SetupRegistry()<0) goto end_install;
+
+ if (SetupFolders()<0) goto end_install;
+
+
+ end_install:
+
+ CleanUpInstall();
+
+ // If an unrecoverable error occurred, clean up the partial installation.
+ // Otherwise, exit normally.
+
+ if (bInstallAborted) then
+ abort;
+ endif;
+
+endprogram
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ShowDialogs //
+// //
+// Purpose: This function manages the display and navigation //
+// the standard dialogs that exist in a setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ShowDialogs()
+ NUMBER nResult;
+ begin
+
+ Dlg_Start:
+ // beginning of dialogs label
+
+ Dlg_SdWelcome:
+ nResult = DialogShowSdWelcome();
+ if (nResult = BACK) goto Dlg_Start;
+
+ Dlg_SdShowInfoList:
+ nResult = DialogShowSdShowInfoList();
+ if (nResult = BACK) goto Dlg_SdWelcome;
+
+ Dlg_SdAskDestPath:
+ nResult = DialogShowSdAskDestPath();
+ if (nResult = BACK) goto Dlg_SdShowInfoList;
+
+ Dlg_SdSetupType:
+ nResult = DialogShowSdSetupType();
+ if (nResult = BACK) goto Dlg_SdAskDestPath;
+
+ Dlg_SdComponentDialog2:
+ if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then
+ goto Dlg_SdSetupType;
+ endif;
+ nResult = DialogShowSdComponentDialog2();
+ if (nResult = BACK) goto Dlg_SdSetupType;
+
+ return 0;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessBeforeDataMove //
+// //
+// Purpose: This function performs any necessary operations prior to the //
+// actual data move operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessBeforeDataMove()
+ STRING svLogFile;
+ NUMBER nResult;
+ begin
+
+ InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY );
+
+ svLogFile = UNINST_LOGFILE_NAME;
+
+ nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 );
+ if (nResult < 0) then
+ MessageBox( @ERROR_UNINSTSETUP, WARNING );
+ endif;
+
+ szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir
+
+ if ((bIs32BitSetup) && (bIsShellExplorer)) then
+ RegDBSetItem( REGDB_APPPATH, szAppPath );
+ RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY );
+ RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME );
+ endif;
+
+ // TODO : update any items you want to process before moving the data
+ //
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: MoveFileData //
+// //
+// Purpose: This function handles the data movement for //
+// the setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function MoveFileData()
+ NUMBER nResult, nDisk;
+ begin
+
+ nDisk = 1;
+ SetStatusWindow( 0, "" );
+ Disable( DIALOGCACHE );
+ Enable( STATUS );
+ StatusUpdate( ON, 100 );
+ nResult = ComponentMoveData( MEDIA, nDisk, 0 );
+
+ HandleMoveDataError( nResult );
+
+ Disable( STATUS );
+
+ return nResult;
+
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: HandleMoveDataError //
+// //
+// Purpose: This function handles the error (if any) during the move data //
+// operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function HandleMoveDataError( nResult )
+ STRING szErrMsg, svComponent , svFileGroup , svFile;
+ begin
+
+ svComponent = "";
+ svFileGroup = "";
+ svFile = "";
+
+ switch (nResult)
+ case 0:
+ return 0;
+ default:
+ ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult );
+ szErrMsg = @ERROR_MOVEDATA + "\n\n" +
+ @ERROR_COMPONENT + " " + svComponent + "\n" +
+ @ERROR_FILEGROUP + " " + svFileGroup + "\n" +
+ @ERROR_FILE + " " + svFile;
+ SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult );
+ bInstallAborted = TRUE;
+ return nResult;
+ endswitch;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessAfterDataMove //
+// //
+// Purpose: This function performs any necessary operations needed after //
+// all data has been moved. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessAfterDataMove()
+ begin
+
+ // TODO : update self-registered files and other processes that
+ // should be performed after the data has been moved.
+
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupRegistry //
+// //
+// Purpose: This function makes the registry entries for this setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupRegistry()
+ NUMBER nResult;
+
+ begin
+
+ // TODO : Add all your registry entry keys here
+ //
+ //
+ // RegDBCreateKeyEx, RegDBSetKeyValueEx....
+ //
+
+ nResult = CreateRegistrySet( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Function: SetupFolders
+//
+// Purpose: This function creates all the folders and shortcuts for the
+// setup. This includes program groups and items for Windows 3.1.
+//
+///////////////////////////////////////////////////////////////////////////////
+function SetupFolders()
+ NUMBER nResult;
+
+ begin
+
+
+ // TODO : Add all your folder (program group) along with shortcuts (program items)
+ //
+ //
+ // CreateProgramFolder, AddFolderIcon....
+ //
+
+ nResult = CreateShellObjects( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CleanUpInstall //
+// //
+// Purpose: This cleans up the setup. Anything that should //
+// be released or deleted at the end of the setup should //
+// be done here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CleanUpInstall()
+ begin
+
+
+ if (bInstallAborted) then
+ return 0;
+ endif;
+
+ DialogShowSdFinishReboot();
+
+ if (BATCH_INSTALL) then // ensure locked files are properly written
+ CommitSharedFiles(0);
+ endif;
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupInstall //
+// //
+// Purpose: This will setup the installation. Any general initialization //
+// needed for the installation should be performed here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupInstall()
+ begin
+
+ Enable( CORECOMPONENTHANDLING );
+
+ bInstallAborted = FALSE;
+
+ if (bIs32BitSetup) then
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME;
+ else
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names
+ endif;
+
+ TARGETDIR = svDir;
+
+ SdProductName( @PRODUCT_NAME );
+
+ Enable( DIALOGCACHE );
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupScreen //
+// //
+// Purpose: This function establishes the screen look. This includes //
+// colors, fonts, and text to be displayed. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupScreen()
+ begin
+
+ Enable( FULLWINDOWMODE );
+ Enable( INDVFILESTATUS );
+ SetTitle( @TITLE_MAIN, 24, WHITE );
+
+ SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.
+
+ Enable( BACKGROUND );
+
+ Delay( 1 );
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CheckRequirements //
+// //
+// Purpose: This function checks all minimum requirements for the //
+// application being installed. If any fail, then the user //
+// is informed and the setup is terminated. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CheckRequirements()
+ NUMBER nvDx, nvDy, nvResult;
+ STRING svResult;
+
+ begin
+
+ bWinNT = FALSE;
+ bIsShellExplorer = FALSE;
+
+ // Check screen resolution.
+ GetExtents( nvDx, nvDy );
+
+ if (nvDy < 480) then
+ MessageBox( @ERROR_VGARESOLUTION, WARNING );
+ abort;
+ endif;
+
+ // set 'setup' operation mode
+ bIs32BitSetup = TRUE;
+ GetSystemInfo( ISTYPE, nvResult, svResult );
+ if (nvResult = 16) then
+ bIs32BitSetup = FALSE; // running 16-bit setup
+ return 0; // no additional information required
+ endif;
+
+ // --- 32-bit testing after this point ---
+
+ // Determine the target system's operating system.
+ GetSystemInfo( OS, nvResult, svResult );
+
+ if (nvResult = IS_WINDOWSNT) then
+ // Running Windows NT.
+ bWinNT = TRUE;
+
+ // Check to see if the shell being used is EXPLORER shell.
+ if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
+ if (nvResult >= 4) then
+ bIsShellExplorer = TRUE;
+ endif;
+ endif;
+
+ elseif (nvResult = IS_WINDOWS95 ) then
+ bIsShellExplorer = TRUE;
+
+ endif;
+
+end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdWelcome //
+// //
+// Purpose: This function handles the standard welcome dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdWelcome()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdWelcome( szTitle, szMsg );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdShowInfoList //
+// //
+// Purpose: This function displays the general information list dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdShowInfoList()
+ NUMBER nResult;
+ LIST list;
+ STRING szTitle, szMsg, szFile;
+ begin
+
+ szFile = SUPPORTDIR ^ "infolist.txt";
+
+ list = ListCreate( STRINGLIST );
+ ListReadFromFile( list, szFile );
+ szTitle = "";
+ szMsg = " ";
+ nResult = SdShowInfoList( szTitle, szMsg, list );
+
+ ListDestroy( list );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdAskDestPath //
+// //
+// Purpose: This function asks the user for the destination directory. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdAskDestPath()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );
+
+ TARGETDIR = svDir;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdSetupType //
+// //
+// Purpose: This function displays the standard setup type dialog. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdSetupType()
+ NUMBER nResult, nType;
+ STRING szTitle, szMsg;
+ begin
+
+ switch (svSetupType)
+ case "Typical":
+ nType = TYPICAL;
+ case "Custom":
+ nType = CUSTOM;
+ case "Compact":
+ nType = COMPACT;
+ case "":
+ svSetupType = "Typical";
+ nType = TYPICAL;
+ endswitch;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SetupType( szTitle, szMsg, "", nType, 0 );
+
+ switch (nResult)
+ case COMPACT:
+ svSetupType = "Compact";
+ case TYPICAL:
+ svSetupType = "Typical";
+ case CUSTOM:
+ svSetupType = "Custom";
+ endswitch;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdComponentDialog2 //
+// //
+// Purpose: This function displays the custom component dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdComponentDialog2()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ if ((svSetupType != "Custom") && (svSetupType != "")) then
+ return 0;
+ endif;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdFinishReboot //
+// //
+// Purpose: This function will show the last dialog of the product. //
+// It will allow the user to reboot and/or show some readme text. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdFinishReboot()
+ NUMBER nResult, nDefOptions;
+ STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
+ NUMBER bOpt1, bOpt2;
+ begin
+
+ if (!BATCH_INSTALL) then
+ bOpt1 = FALSE;
+ bOpt2 = FALSE;
+ szMsg1 = "";
+ szMsg2 = "";
+ szOption1 = "";
+ szOption2 = "";
+ nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 );
+ return 0;
+ endif;
+
+ nDefOptions = SYS_BOOTMACHINE;
+ szTitle = "";
+ szMsg1 = "";
+ szMsg2 = "";
+ nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 );
+
+ return nResult;
+ end;
+
+ // --- include script file section ---
+
+#include "sddialog.rul"
+
+
diff --git a/VC++Files/bdb/bdb.dsp b/VC++Files/bdb/bdb.dsp
new file mode 100644
index 00000000000..bed306fc3d0
--- /dev/null
+++ b/VC++Files/bdb/bdb.dsp
@@ -0,0 +1,707 @@
+# Microsoft Developer Studio Project File - Name="bdb" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=bdb - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "bdb.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "bdb.mak" CFG="bdb - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "bdb - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "bdb - Win32 Max" (based on "Win32 (x86) Static Library")
+!MESSAGE "bdb - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "bdb - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../bdb/build_win32" /I "../bdb/include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\bdb.lib"
+
+!ELSEIF "$(CFG)" == "bdb - Win32 Max"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "bdb___Win32_Max"
+# PROP BASE Intermediate_Dir "bdb___Win32_Max"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "bdb___Win32_Max"
+# PROP Intermediate_Dir "bdb___Win32_Max"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../bdb/build_win32" /I "../bdb/include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT BASE CPP /Fr
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../bdb/build_win32" /I "../bdb/include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /Fo"mysys___Win32_Max/" /Fd"mysys___Win32_Max/" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_debug\bdb.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\bdb.lib"
+
+!ELSEIF "$(CFG)" == "bdb - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "bdb___Win32_Release"
+# PROP BASE Intermediate_Dir "bdb___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "bdb___Win32_Release"
+# PROP Intermediate_Dir "bdb___Win32_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../bdb/build_win32" /I "../bdb/include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /Fo"mysys___Win32_Max/" /Fd"mysys___Win32_Max/" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../bdb/build_win32" /I "../bdb/include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /Fo"mysys___Win32_Max/" /Fd"mysys___Win32_Max/" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\bdb.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\bdb.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "bdb - Win32 Debug"
+# Name "bdb - Win32 Max"
+# Name "bdb - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\btree\bt_compare.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_curadj.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_cursor.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_put.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_reclaim.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_recno.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_rsearch.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_search.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_split.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_upgrade.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_verify.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\btree_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\crdel_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\crdel_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_app.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_except.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_lock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_log.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_mpool.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_txn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_am.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_byteorder.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_cam.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_dispatch.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_dup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_err.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_getlong.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_iface.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_join.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_log2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_meta.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_overflow.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_pr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_reclaim.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_ret.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\db_salloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\db_shash.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_upg.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_upg_opd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_vrfy.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_vrfyutil.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbm\dbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_recover.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_dup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_func.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_meta.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_page.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_reclaim.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_upgrade.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_verify.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hsearch\hsearch.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_conflict.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_deadlock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_util.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_archive.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_compare.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_findckp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_get.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_put.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_register.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_bh.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fget.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fput.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fset.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_register.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_sync.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_trickle.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mutex\mut_tas.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mutex\mutex.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_abs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_dir.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_errno.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_fid.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_finit.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_fsync.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_handle.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_map.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_oflags.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_root.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_rpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_rw.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_seek.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_sleep.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_spin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_tmpdir.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_type.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_unlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_files.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_upgrade.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_verify.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\clib\strcasecmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\util_log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\util_sig.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xa\xa.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xa\xa_db.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xa\xa_map.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/client/mysql.dsp b/VC++Files/client/mysql.dsp
new file mode 100644
index 00000000000..4c9819bacde
--- /dev/null
+++ b/VC++Files/client/mysql.dsp
@@ -0,0 +1,101 @@
+# Microsoft Developer Studio Project File - Name="mysql" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysql - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysql.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysql.mak" CFG="mysql - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysql - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysql - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysql - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /WX /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_release/mysql.exe" /libpath:"..\lib_release\\"
+# SUBTRACT LINK32 /incremental:yes
+
+!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "mysql___"
+# PROP BASE Intermediate_Dir "mysql___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysql.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysql - Win32 Release"
+# Name "mysql - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mysql.cpp
+
+!IF "$(CFG)" == "mysql - Win32 Release"
+
+# ADD CPP /Zi /O2
+
+!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/client/mysqladmin.dsp b/VC++Files/client/mysqladmin.dsp
new file mode 100644
index 00000000000..278bcdae8b0
--- /dev/null
+++ b/VC++Files/client/mysqladmin.dsp
@@ -0,0 +1,91 @@
+# Microsoft Developer Studio Project File - Name="mysqladmin" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqladmin - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqladmin.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqladmin.mak" CFG="mysqladmin - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqladmin - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqladmin - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqladmin - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqladmin.exe" /libpath:"..\lib_release\\"
+
+!ELSEIF "$(CFG)" == "mysqladmin - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "mysqladm"
+# PROP BASE Intermediate_Dir "mysqladm"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqladmin.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqladmin - Win32 Release"
+# Name "mysqladmin - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mysqladmin.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/client/mysqlclient.dsp b/VC++Files/client/mysqlclient.dsp
new file mode 100644
index 00000000000..5e3fbcd060e
--- /dev/null
+++ b/VC++Files/client/mysqlclient.dsp
@@ -0,0 +1,510 @@
+# Microsoft Developer Studio Project File - Name="mysqlclient" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=mysqlclient - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlclient.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlclient.mak" CFG="mysqlclient - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlclient - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "mysqlclient - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlclient - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\mysqlclient.lib"
+
+!ELSEIF "$(CFG)" == "mysqlclient - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_TLS" /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\mysqlclient.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlclient - Win32 Release"
+# Name "mysqlclient - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\mysys\array.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bmove.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bmove_upp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\charset.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\completion_hash.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\completion_hash.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\dbug\dbug.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\default.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\errmsg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\errors.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\get_password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\is_prefix.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\libmysql.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\list.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_cache.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_casecnv.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_dirname.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_fn_ext.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_format.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_iocache.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_iocache2.c
+
+!IF "$(CFG)" == "mysqlclient - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqlclient - Win32 Debug"
+
+# ADD CPP /Od
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_loadpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_pack.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_path.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_tempfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_unixpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_wcomp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mulalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_div.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_error.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_fopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_fstream.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_gethostbyname.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_getopt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_getwd.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_lib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_malloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_messnc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_net.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_once.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_pread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_pthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_read.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_realloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_seek.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_symlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_symlink2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_tempnam.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_thr_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_vsnprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_wincond.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_winthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_write.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysys_priv.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\net.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\password.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\readline.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\safemalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\select_test.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_string.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strcend.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strcont.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strend.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\string.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strmake.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strnlen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strnmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strtoll.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strtoull.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strxmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strxnmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\thr_mutex.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\typelib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\vio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosocket.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viossl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosslfactories.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/client/mysqlclient.dsw b/VC++Files/client/mysqlclient.dsw
new file mode 100644
index 00000000000..9c08bbf0407
--- /dev/null
+++ b/VC++Files/client/mysqlclient.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "mysqlclient"=".\mysqlclient.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/client/mysqldump.dsp b/VC++Files/client/mysqldump.dsp
new file mode 100644
index 00000000000..448ba126153
--- /dev/null
+++ b/VC++Files/client/mysqldump.dsp
@@ -0,0 +1,101 @@
+# Microsoft Developer Studio Project File - Name="mysqldump" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqldump - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldump.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldump.mak" CFG="mysqldump - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqldump - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqldump - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqldump - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqldump.exe" /libpath:"..\lib_release\\"
+
+!ELSEIF "$(CFG)" == "mysqldump - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "mysqldum"
+# PROP BASE Intermediate_Dir "mysqldum"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_debug/mysqldump.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqldump - Win32 Release"
+# Name "mysqldump - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mysqldump.c
+
+!IF "$(CFG)" == "mysqldump - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldump - Win32 Debug"
+
+# ADD CPP /W3
+# SUBTRACT CPP /YX
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/client/mysqlimport.dsp b/VC++Files/client/mysqlimport.dsp
new file mode 100644
index 00000000000..5de3b68dd4e
--- /dev/null
+++ b/VC++Files/client/mysqlimport.dsp
@@ -0,0 +1,92 @@
+# Microsoft Developer Studio Project File - Name="mysqlimport" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqlimport - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlimport.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlimport.mak" CFG="mysqlimport - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlimport - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqlimport - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlimport - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlimport.exe" /libpath:"..\lib_release\\"
+# SUBTRACT LINK32 /incremental:yes
+
+!ELSEIF "$(CFG)" == "mysqlimport - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "mysqlimp"
+# PROP BASE Intermediate_Dir "mysqlimp"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlimport.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlimport - Win32 Release"
+# Name "mysqlimport - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mysqlimport.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/client/mysqlshow.dsp b/VC++Files/client/mysqlshow.dsp
new file mode 100644
index 00000000000..329f128d1b6
--- /dev/null
+++ b/VC++Files/client/mysqlshow.dsp
@@ -0,0 +1,91 @@
+# Microsoft Developer Studio Project File - Name="mysqlshow" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqlshow - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlshow.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlshow.mak" CFG="mysqlshow - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlshow - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqlshow - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlshow - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlshow.exe" /libpath:"..\lib_release\\"
+
+!ELSEIF "$(CFG)" == "mysqlshow - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "mysqlsho"
+# PROP BASE Intermediate_Dir "mysqlsho"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_debug/mysqlshow.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlshow - Win32 Release"
+# Name "mysqlshow - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mysqlshow.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/dbug/dbug.dsp b/VC++Files/dbug/dbug.dsp
new file mode 100644
index 00000000000..11721da98d6
--- /dev/null
+++ b/VC++Files/dbug/dbug.dsp
@@ -0,0 +1,98 @@
+# Microsoft Developer Studio Project File - Name="dbug" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=dbug - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "dbug.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "dbug.mak" CFG="dbug - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dbug - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "dbug - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "dbug - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\dbug.lib"
+
+!ELSEIF "$(CFG)" == "dbug - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\dbug.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "dbug - Win32 Release"
+# Name "dbug - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\dbug.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\factorial.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sanity.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/dbug/dbug.dsw b/VC++Files/dbug/dbug.dsw
new file mode 100644
index 00000000000..a0cd4da7891
--- /dev/null
+++ b/VC++Files/dbug/dbug.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "dbug"=".\dbug.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/heap/heap.dsp b/VC++Files/heap/heap.dsp
new file mode 100644
index 00000000000..c21c3139519
--- /dev/null
+++ b/VC++Files/heap/heap.dsp
@@ -0,0 +1,195 @@
+# Microsoft Developer Studio Project File - Name="heap" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=heap - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "heap.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "heap.mak" CFG="heap - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "heap - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "heap - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "heap - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\heap.lib"
+
+!ELSEIF "$(CFG)" == "heap - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\heap.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "heap - Win32 Release"
+# Name "heap - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\_check.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_rectest.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\heapdef.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_block.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_clear.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_close.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_extra.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_hash.c
+
+!IF "$(CFG)" == "heap - Win32 Release"
+
+!ELSEIF "$(CFG)" == "heap - Win32 Debug"
+
+# SUBTRACT CPP /YX
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_info.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_panic.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rfirst.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rkey.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rlast.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rnext.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rprev.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rrnd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_rsame.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_scan.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_update.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hp_write.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/innobase/innobase.dsp b/VC++Files/innobase/innobase.dsp
new file mode 100644
index 00000000000..c3084bfa799
--- /dev/null
+++ b/VC++Files/innobase/innobase.dsp
@@ -0,0 +1,466 @@
+# Microsoft Developer Studio Project File - Name="innobase" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=innobase - Win32 Max
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "innobase.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "innobase.mak" CFG="innobase - Win32 Max"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "innobase - Win32 Max" (based on "Win32 (x86) Static Library")
+!MESSAGE "innobase - Win32 Max nt" (based on "Win32 (x86) Static Library")
+!MESSAGE "innobase - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "innobase - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "innobase - Win32 Max"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "innobase___Win32_Max"
+# PROP BASE Intermediate_Dir "innobase___Win32_Max"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "innobase___Win32_Max"
+# PROP Intermediate_Dir "innobase___Win32_Max"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\innobase-nt.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\innodb.lib"
+
+!ELSEIF "$(CFG)" == "innobase - Win32 Max nt"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "innobase___Win32_Max_nt"
+# PROP BASE Intermediate_Dir "innobase___Win32_Max_nt"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "innobase___Win32_Max_nt"
+# PROP Intermediate_Dir "innobase___Win32_Max_nt"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\innobase-nt.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\innodb-nt.lib"
+
+!ELSEIF "$(CFG)" == "innobase - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "innobase___Win32_Debug"
+# PROP BASE Intermediate_Dir "innobase___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "innobase___Win32_Debug"
+# PROP Intermediate_Dir "innobase___Win32_Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /GX /Z7 /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\innobase-nt.lib"
+# ADD LIB32 /nologo /out:"..\lib_debug\innodb.lib"
+
+!ELSEIF "$(CFG)" == "innobase - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "innobase___Win32_Release"
+# PROP BASE Intermediate_Dir "innobase___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "innobase___Win32_Release"
+# PROP Intermediate_Dir "innobase___Win32_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\innodb.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\innodb.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "innobase - Win32 Max"
+# Name "innobase - Win32 Max nt"
+# Name "innobase - Win32 Debug"
+# Name "innobase - Win32 Release"
+# Begin Source File
+
+SOURCE=.\btr\btr0btr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btr\btr0cur.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btr\btr0pcur.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btr\btr0sea.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\buf\buf0buf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\buf\buf0flu.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\buf\buf0lru.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\buf\buf0rea.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\com\com0com.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\com\com0shm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\data\data0data.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\data\data0type.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dict\dict0boot.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dict\dict0crea.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dict\dict0dict.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dict\dict0load.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dict\dict0mem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dyn\dyn0dyn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\eval\eval0eval.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\eval\eval0proc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\fil\fil0fil.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\fsp\fsp0fsp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\fut\fut0fut.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\fut\fut0lst.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha\ha0ha.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha\hash0hash.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ibuf\ibuf0ibuf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\pars\lexyy.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock0lock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log0log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log0recv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mach\mach0data.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mem\mem0mem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mem\mem0pool.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mtr\mtr0log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mtr\mtr0mtr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\odbc\odbc0odbc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os0file.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os0proc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os0shm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os0sync.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os0thread.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\page\page0cur.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\page\page0page.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\pars\pars0grm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\pars\pars0opt.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\pars\pars0pars.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\pars\pars0sym.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\que\que0que.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\read\read0read.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rem\rem0cmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rem\rem0rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0ins.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0mysql.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0purge.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0row.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0sel.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0uins.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0umod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0undo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0upd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\row\row0vers.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\srv\srv0que.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\srv\srv0srv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\srv\srv0start.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sync\sync0arr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sync\sync0ipm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sync\sync0rw.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sync\sync0sync.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr\thr0loc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trx\trx0purge.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trx\trx0rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trx\trx0roll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trx\trx0rseg.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trx\trx0sys.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trx\trx0trx.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trx\trx0undo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\usr\usr0sess.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ut\ut0byte.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ut\ut0dbg.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ut\ut0mem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ut\ut0rnd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ut\ut0ut.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/isam/isam.dsp b/VC++Files/isam/isam.dsp
new file mode 100644
index 00000000000..32832919654
--- /dev/null
+++ b/VC++Files/isam/isam.dsp
@@ -0,0 +1,206 @@
+# Microsoft Developer Studio Project File - Name="isam" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=isam - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "isam.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "isam.mak" CFG="isam - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "isam - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "isam - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "isam - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\isam.lib"
+
+!ELSEIF "$(CFG)" == "isam - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_Debug\isam.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "isam - Win32 Release"
+# Name "isam - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\_cache.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_dbug.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_dynrec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_key.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_locking.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_packrec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_page.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_search.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\_statrec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\changed.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\close.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\create.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\extra.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\info.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\panic.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\range.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfirst.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rkey.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rlast.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rnext.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rprev.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rrnd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rsame.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rsamepos.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\static.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\update.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\write.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/isam/isam.dsw b/VC++Files/isam/isam.dsw
new file mode 100644
index 00000000000..6874c8cf4c3
--- /dev/null
+++ b/VC++Files/isam/isam.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "isam"=".\isam.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/isamchk/isamchk.dsp b/VC++Files/isamchk/isamchk.dsp
new file mode 100644
index 00000000000..7b9c03f23f4
--- /dev/null
+++ b/VC++Files/isamchk/isamchk.dsp
@@ -0,0 +1,98 @@
+# Microsoft Developer Studio Project File - Name="isamchk" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=isamchk - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "isamchk.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "isamchk.mak" CFG="isamchk - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "isamchk - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "isamchk - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "isamchk - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../isam" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x41d /d "NDEBUG"
+# ADD RSC /l 0x41d /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /machine:I386 /out:"../client_release/isamchk.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "isamchk - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "isamchk_"
+# PROP BASE Intermediate_Dir "isamchk_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /ZI /Od /I "../include" /I "../isam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x41d /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/isamchk.exe" /pdbtype:sept
+# SUBTRACT LINK32 /verbose /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "isamchk - Win32 Release"
+# Name "isamchk - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\isam\isamchk.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\isam\sort.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysql/libmySQL.dsp b/VC++Files/libmysql/libmySQL.dsp
new file mode 100644
index 00000000000..14587260d60
--- /dev/null
+++ b/VC++Files/libmysql/libmySQL.dsp
@@ -0,0 +1,476 @@
+# Microsoft Developer Studio Project File - Name="libmySQL" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libmySQL - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libmySQL.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libmySQL.mak" CFG="libmySQL - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libmySQL - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libmySQL - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libmySQL - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "." /I "..\include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /D "USE_OLD_FUNCTIONS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"../lib_release/libmySQL.dll" /libpath:"." /libpath:"..\lib_release"
+# SUBTRACT LINK32 /pdb:none
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Desc=Move DLL export lib
+PostBuild_Cmds=copy release\libmysql.lib ..\lib_release
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "libmySQL - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "." /I "..\include" /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "USE_OLD_FUNCTIONS" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlib.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"../lib_debug/libmySQL.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug"
+# SUBTRACT LINK32 /pdb:none
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Desc=Move DLL export lib
+PostBuild_Cmds=copy debug\libmysql.lib ..\lib_debug
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "libmySQL - Win32 Release"
+# Name "libmySQL - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\mysys\array.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bmove.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bmove_upp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\charset.c
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\dbug\dbug.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\default.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\errmsg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\errors.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\get_password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\is_prefix.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libmysql.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Libmysql.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\list.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_casecnv.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_dirname.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_fn_ext.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_format.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_loadpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_pack.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_unixpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_wcomp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mulalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_div.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_error.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_fopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_fstream.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_gethostbyname.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_getwd.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_lib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_malloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_messnc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_net.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_once.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_pthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_read.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_realloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_symlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_symlink2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_tempnam.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_thr_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_vsnprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_wincond.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_winthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_write.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\mysys_priv.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\net.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\safemalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\select_test.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\sql_string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\sql_string.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strcend.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strcont.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strend.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\string.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strmake.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strnlen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strnmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strxmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strxnmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\thr_mutex.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\typelib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\vio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosocket.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viossl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosslfactories.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysql/libmysql.dsw b/VC++Files/libmysql/libmysql.dsw
new file mode 100644
index 00000000000..fe121fa65cc
--- /dev/null
+++ b/VC++Files/libmysql/libmysql.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "libmySQL"=".\libmySQL.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/libmysqld/examples/test_libmysqld.dsp b/VC++Files/libmysqld/examples/test_libmysqld.dsp
new file mode 100644
index 00000000000..35d9689266d
--- /dev/null
+++ b/VC++Files/libmysqld/examples/test_libmysqld.dsp
@@ -0,0 +1,66 @@
+# Microsoft Developer Studio Project File - Name="test_libmysqld" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=test_libmysqld - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "test_libmysqld.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "test_libmysqld.mak" CFG="test_libmysqld - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "test_libmysqld - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "DBUG_OFF" /FR /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBCMTD" /out:"Release/mysql-server.exe"
+# Begin Target
+
+# Name "test_libmysqld - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\client\mysql.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\lib_release\libmysqld.lib
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysqld/libmysqld.dsp b/VC++Files/libmysqld/libmysqld.dsp
new file mode 100644
index 00000000000..34574dd4f2f
--- /dev/null
+++ b/VC++Files/libmysqld/libmysqld.dsp
@@ -0,0 +1,405 @@
+# Microsoft Developer Studio Project File - Name="libmysqld" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libmysqld - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libmysqld.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libmysqld.mak" CFG="libmysqld - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libmysqld - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libmysqld - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libmysqld - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /FR /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib /nologo /dll /machine:I386 /out:"../lib_release/libmysqld.dll" /implib:"../lib_release/libmysqld.lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "libmysqld - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "libmysqld___Win32_Debug"
+# PROP BASE Intermediate_Dir "libmysqld___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MT /W3 /Gm /Zi /Od /I "../include" /I "../sql" /I "../regex" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\merge.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\bdb.lib ..\lib_debug\innodb.lib ..\lib_debug\vio.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBCMTD" /out:"../lib_debug/libmysqld.dll" /implib:"../lib_debug/libmysqld.lib" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "libmysqld - Win32 Release"
+# Name "libmysqld - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\sql\convert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\derror.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\errmsg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field_conv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\filesort.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\get_password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_berkeley.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_heap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_innodb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_isammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hash_filo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hostname.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\init.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_buff.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_cmpfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_create.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_func.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_strfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_timefunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_uniq.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\key.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\lib_load.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\lib_sql.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\libmysqld.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libmysqld.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\lock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log_event.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mf_iocache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mini_client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_pkg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_serv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_ft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_range.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\procedure.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\records.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\repl_failsafe.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\slave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_acl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_analyse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_base.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_cache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_class.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_crypt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_db.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_delete.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_do.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_insert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_lex.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_list.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_manager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_map.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_parse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_rename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_repl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_select.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_show.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_udf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_union.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_yacc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\thr_malloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\time.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\uniques.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\unireg.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysqltest/myTest.dsp b/VC++Files/libmysqltest/myTest.dsp
new file mode 100644
index 00000000000..74f7b8ae48e
--- /dev/null
+++ b/VC++Files/libmysqltest/myTest.dsp
@@ -0,0 +1,91 @@
+# Microsoft Developer Studio Project File - Name="myTest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=myTest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myTest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myTest.mak" CFG="myTest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myTest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "myTest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myTest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /W3 /O2 /I "..\include" /D "NDEBUG" /D "DBUG_UFF" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\lib_release"
+
+!ELSEIF "$(CFG)" == "myTest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "..\include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"..\lib_debug"
+
+!ENDIF
+
+# Begin Target
+
+# Name "myTest - Win32 Release"
+# Name "myTest - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\Mytest.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysqltest/mytest.c b/VC++Files/libmysqltest/mytest.c
new file mode 100644
index 00000000000..9c6818ecf6c
--- /dev/null
+++ b/VC++Files/libmysqltest/mytest.c
@@ -0,0 +1,170 @@
+/*C4*/
+/****************************************************************/
+/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
+/* Date: 02/18/1998 */
+/* mytest.c : do some testing of the libmySQL.DLL.... */
+/* */
+/* History: */
+/* 02/18/1998 jw3 also sprach zarathustra.... */
+/****************************************************************/
+
+
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <mysql.h>
+
+#define DEFALT_SQL_STMT "SELECT * FROM db"
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+
+/********************************************************
+**
+** main :-
+**
+********************************************************/
+
+int
+main( int argc, char * argv[] )
+{
+
+ char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ;
+ const char *pszT;
+ int i, j, k, l, x ;
+ MYSQL * myData ;
+ MYSQL_RES * res ;
+ MYSQL_FIELD * fd ;
+ MYSQL_ROW row ;
+
+ //....just curious....
+ printf( "sizeof( MYSQL ) == %d\n", sizeof( MYSQL ) ) ;
+ if ( argc == 2 )
+ {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ if (!strcmp(szDB,"--debug"))
+ {
+ strcpy( szDB, "mysql" ) ;
+ printf("Some mysql struct information (size and offset):\n");
+ printf("net:\t%3d %3d\n",sizeof(myData->net),offsetof(MYSQL,net));
+ printf("host:\t%3d %3d\n",sizeof(myData->host),offsetof(MYSQL,host));
+ printf("port:\t%3d %3d\n",sizeof(myData->port),offsetof(MYSQL,port));
+ printf("protocol_version:\t%3d %3d\n",sizeof(myData->protocol_version),
+ offsetof(MYSQL,protocol_version));
+ printf("thread_id:\t%3d %3d\n",sizeof(myData->thread_id),
+ offsetof(MYSQL,thread_id));
+ printf("affected_rows:\t%3d %3d\n",sizeof(myData->affected_rows),
+ offsetof(MYSQL,affected_rows));
+ printf("packet_length:\t%3d %3d\n",sizeof(myData->packet_length),
+ offsetof(MYSQL,packet_length));
+ printf("status:\t%3d %3d\n",sizeof(myData->status),
+ offsetof(MYSQL,status));
+ printf("fields:\t%3d %3d\n",sizeof(myData->fields),
+ offsetof(MYSQL,fields));
+ printf("field_alloc:\t%3d %3d\n",sizeof(myData->field_alloc),
+ offsetof(MYSQL,field_alloc));
+ printf("free_me:\t%3d %3d\n",sizeof(myData->free_me),
+ offsetof(MYSQL,free_me));
+ printf("options:\t%3d %3d\n",sizeof(myData->options),
+ offsetof(MYSQL,options));
+ puts("");
+ }
+ }
+ else if ( argc > 2 ) {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, argv[ 2 ] ) ;
+ }
+ else {
+ strcpy( szDB, "mysql" ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ }
+ //....
+
+ if ( (myData = mysql_init((MYSQL*) 0)) &&
+ mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
+ NULL, 0 ) )
+ {
+ if ( mysql_select_db( myData, szDB ) < 0 ) {
+ printf( "Can't select the %s database !\n", szDB ) ;
+ mysql_close( myData ) ;
+ return 2 ;
+ }
+ }
+ else {
+ printf( "Can't connect to the mysql server on port %d !\n",
+ MYSQL_PORT ) ;
+ mysql_close( myData ) ;
+ return 1 ;
+ }
+ //....
+ if ( ! mysql_query( myData, szSQL ) ) {
+ res = mysql_store_result( myData ) ;
+ i = (int) mysql_num_rows( res ) ; l = 1 ;
+ printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
+ //....we can get the field-specific characteristics here....
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ //....
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Record #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ mysql_free_result( res ) ;
+ }
+ else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
+ //....
+ puts( "==== Diagnostic info ====" ) ;
+ pszT = mysql_get_client_info() ;
+ printf( "Client info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_host_info( myData ) ;
+ printf( "Host info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_server_info( myData ) ;
+ printf( "Server info: %s\n", pszT ) ;
+ //....
+ res = mysql_list_processes( myData ) ; l = 1 ;
+ if (res)
+ {
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Process #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ }
+ else
+ {
+ printf("Got error %s when retreiving processlist\n",mysql_error(myData));
+ }
+ //....
+ res = mysql_list_tables( myData, "%" ) ; l = 1 ;
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Table #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ //....
+ pszT = mysql_stat( myData ) ;
+ puts( pszT ) ;
+ //....
+ mysql_close( myData ) ;
+ return 0 ;
+
+}
diff --git a/VC++Files/libmysqltest/mytest.dsw b/VC++Files/libmysqltest/mytest.dsw
new file mode 100644
index 00000000000..621899eb4d0
--- /dev/null
+++ b/VC++Files/libmysqltest/mytest.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "myTest"=".\myTest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/merge/merge.dsp b/VC++Files/merge/merge.dsp
new file mode 100644
index 00000000000..70c0ce87d6b
--- /dev/null
+++ b/VC++Files/merge/merge.dsp
@@ -0,0 +1,134 @@
+# Microsoft Developer Studio Project File - Name="merge" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=merge - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "merge.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "merge.mak" CFG="merge - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "merge - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "merge - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "merge - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\merge.lib"
+
+!ELSEIF "$(CFG)" == "merge - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\merge.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "merge - Win32 Release"
+# Name "merge - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mrg_close.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_extra.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_info.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_locking.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_panic.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_rrnd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_rsame.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mrg_update.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/merge/merge.dsw b/VC++Files/merge/merge.dsw
new file mode 100644
index 00000000000..a2d5ccb2ff2
--- /dev/null
+++ b/VC++Files/merge/merge.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "merge"=".\merge.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/myisam/myisam.dsp b/VC++Files/myisam/myisam.dsp
new file mode 100644
index 00000000000..8346cddbc54
--- /dev/null
+++ b/VC++Files/myisam/myisam.dsp
@@ -0,0 +1,284 @@
+# Microsoft Developer Studio Project File - Name="myisam" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=myisam - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myisam.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myisam.mak" CFG="myisam - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myisam - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "myisam - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myisam - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\myisam.lib"
+
+!ELSEIF "$(CFG)" == "myisam - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /Fo".\Debug/" /Fd".\Debug/" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_Debug\myisam.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "myisam - Win32 Release"
+# Name "myisam - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\ft_boolean_search.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ft_nlq_search.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ft_parser.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ft_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ft_stem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ft_stopwords.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ft_update.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_cache.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_changed.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_check.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_checksum.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_close.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_dbug.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_delete_all.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_delete_table.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_dynrec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_extra.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_info.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_key.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_locking.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_packrec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_page.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_panic.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_range.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rfirst.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rkey.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rlast.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rnext.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rnext_same.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rprev.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rrnd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rsame.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_rsamepos.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_scan.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_search.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_statrec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_unique.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_update.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mi_write.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sort.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\ft_eval.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\myisamdef.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/myisamchk/myisamchk.dsp b/VC++Files/myisamchk/myisamchk.dsp
new file mode 100644
index 00000000000..7f0459d21d0
--- /dev/null
+++ b/VC++Files/myisamchk/myisamchk.dsp
@@ -0,0 +1,104 @@
+# Microsoft Developer Studio Project File - Name="myisamchk" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=myisamchk - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myisamchk.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myisamchk.mak" CFG="myisamchk - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myisamchk - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "myisamchk - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myisamchk - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../myisam" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FR /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib setargv.obj /nologo /subsystem:console /machine:I386 /out:"../client_release/myisamchk.exe"
+
+!ELSEIF "$(CFG)" == "myisamchk - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../myisam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/myisamchk.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "myisamchk - Win32 Release"
+# Name "myisamchk - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\myisam\myisamchk.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/myisamlog/myisamlog.dsp b/VC++Files/myisamlog/myisamlog.dsp
new file mode 100644
index 00000000000..efc43914759
--- /dev/null
+++ b/VC++Files/myisamlog/myisamlog.dsp
@@ -0,0 +1,105 @@
+# Microsoft Developer Studio Project File - Name="myisamlog" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=myisamlog - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myisamlog.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myisamlog.mak" CFG="myisamlog - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myisamlog - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "myisamlog - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myisamlog - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../myisam" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FR /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib setargv.obj /nologo /subsystem:console /pdb:"release/myisamchk.pdb" /machine:I386 /out:"../client_release/myisamlog.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "myisamlog - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../myisam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /pdb:"debug/myisamchk.pdb" /debug /machine:I386 /out:"../client_debug/myisamlog.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "myisamlog - Win32 Release"
+# Name "myisamlog - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\myisam\myisamlog.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/myisammrg/myisammrg.dsp b/VC++Files/myisammrg/myisammrg.dsp
new file mode 100644
index 00000000000..e91d1f4e696
--- /dev/null
+++ b/VC++Files/myisammrg/myisammrg.dsp
@@ -0,0 +1,173 @@
+# Microsoft Developer Studio Project File - Name="myisammrg" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=myisammrg - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myisammrg.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myisammrg.mak" CFG="myisammrg - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myisammrg - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "myisammrg - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myisammrg - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\myisammrg.lib"
+
+!ELSEIF "$(CFG)" == "myisammrg - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /Fo".\Debug/" /Fd".\Debug/" /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_Debug\myisammrg.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "myisammrg - Win32 Release"
+# Name "myisammrg - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\myrg_close.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_extra.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_info.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_locking.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_panic.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_queue.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_rfirst.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_rkey.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_rlast.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_rnext.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_rprev.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_rrnd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_rsame.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_update.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_write.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\mymrgdef.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/myisampack/myisampack.dsp b/VC++Files/myisampack/myisampack.dsp
new file mode 100644
index 00000000000..5ea392e1b41
--- /dev/null
+++ b/VC++Files/myisampack/myisampack.dsp
@@ -0,0 +1,107 @@
+# Microsoft Developer Studio Project File - Name="myisampack" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=myisampack - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myisampack.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myisampack.mak" CFG="myisampack - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myisampack - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "myisampack - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myisampack - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../myisam" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FR /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib setargv.obj /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "myisampack - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../myisam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "myisampack - Win32 Release"
+# Name "myisampack - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\myisampack.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\myisampack.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/mysql.dsp b/VC++Files/mysql.dsp
new file mode 100644
index 00000000000..41f2538a7e5
--- /dev/null
+++ b/VC++Files/mysql.dsp
@@ -0,0 +1,80 @@
+# Microsoft Developer Studio Project File - Name="mysql" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=mysql - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysql.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysql.mak" CFG="mysql - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysql - Win32 Release" (based on "Win32 (x86) External Target")
+!MESSAGE "mysql - Win32 Debug" (based on "Win32 (x86) External Target")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "mysql - Win32 Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Cmd_Line "NMAKE /f mysql.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "mysql.exe"
+# PROP BASE Bsc_Name "mysql.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Cmd_Line "NMAKE /f mysql.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "mysql.exe"
+# PROP Bsc_Name "mysql.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Cmd_Line "NMAKE /f mysql.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "mysql.exe"
+# PROP BASE Bsc_Name "mysql.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Cmd_Line "NMAKE /f mysql.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "mysql.exe"
+# PROP Bsc_Name "mysql.bsc"
+# PROP Target_Dir ""
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysql - Win32 Release"
+# Name "mysql - Win32 Debug"
+
+!IF "$(CFG)" == "mysql - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
+
+!ENDIF
+
+# End Target
+# End Project
diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw
new file mode 100644
index 00000000000..6a7ec7a57dd
--- /dev/null
+++ b/VC++Files/mysql.dsw
@@ -0,0 +1,782 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "MySqlManager"=".\mysqlmanager\MySqlManager.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "bdb"=".\bdb\bdb.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "dbug"=".\dbug\dbug.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "heap"=".\heap\heap.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "innobase"=".\innobase\innobase.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "isam"=".\isam\isam.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "isamchk"=".\isamchk\isamchk.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name isam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "libmySQL"=".\libmysql\libmySQL.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "libmysqld"=".\libmysqld\libmysqld.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name bdb
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name heap
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name innobase
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisammrg
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name regex
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name vio
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name merge
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "merge"=".\merge\merge.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "myTest"=".\libmysqltest\myTest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name libmySQL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "myisam"=".\myisam\myisam.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "myisamchk"=".\myisamchk\myisamchk.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "myisamlog"=".\myisamlog\myisamlog.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "myisammrg"=".\myisammrg\myisammrg.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "myisampack"=".\myisampack\myisampack.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysql"=".\client\mysql.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqladmin"=".\client\mysqladmin.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqlbinlog"=".\mysqlbinlog\mysqlbinlog.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqlcheck"=".\mysqlcheck\mysqlcheck.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqlclient"=".\client\mysqlclient.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqld"=".\sql\mysqld.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name heap
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name isam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name merge
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name regex
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysql
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysqladmin
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysqldump
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysqlimport
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name MySqlManager
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysqlshow
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myTest
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name thr_test
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name replace
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisammrg
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name innobase
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name bdb
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name vio
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqldemb"=".\mysqldemb\mysqldemb.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "mysqldump"=".\client\mysqldump.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqlimport"=".\client\mysqlimport.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqlserver"=".\mysqlserver\mysqlserver.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name bdb
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name heap
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name innobase
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name merge
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisammrg
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysqldemb
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name regex
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqlshow"=".\client\mysqlshow.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "mysqlshutdown"=".\mysqlshutdown\mysqlshutdown.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "mysqlwatch"=".\mysqlwatch\mysqlwatch.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "mysys"=".\mysys\mysys.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "pack_isam"=".\pack_isam\pack_isam.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name isam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "perror"=".\perror\perror.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "regex"=".\regex\regex.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "replace"=".\replace\replace.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "strings"=".\strings\strings.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "test1"=".\test1\test1.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name libmySQL
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "test_libmysqld"=".\libmysqld\examples\test_libmysqld.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name libmysqld
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "thr_insert_test"=".\thr_insert_test\thr_insert_test.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name mysqlclient
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "thr_test"=".\thr_test\thr_test.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "vio"=".\vio\vio.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zlib"=".\zlib\zlib.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/mysqlbinlog/mysqlbinlog.dsp b/VC++Files/mysqlbinlog/mysqlbinlog.dsp
new file mode 100644
index 00000000000..a62253b2a2c
--- /dev/null
+++ b/VC++Files/mysqlbinlog/mysqlbinlog.dsp
@@ -0,0 +1,103 @@
+# Microsoft Developer Studio Project File - Name="mysqlbinlog" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqlbinlog - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlbinlog.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlbinlog.mak" CFG="mysqlbinlog - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlbinlog - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqlbinlog - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlbinlog - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlbinlog.exe" /libpath:"..\lib_release\\"
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "mysqlbinlog - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlbinlog.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlbinlog - Win32 Release"
+# Name "mysqlbinlog - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\mysqlbinlog.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/mysqlcheck/mysqlcheck.dsp b/VC++Files/mysqlcheck/mysqlcheck.dsp
new file mode 100644
index 00000000000..d4b4f5652b7
--- /dev/null
+++ b/VC++Files/mysqlcheck/mysqlcheck.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="mysqlcheck" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqlcheck - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlcheck.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlcheck.mak" CFG="mysqlcheck - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlcheck - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqlcheck - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlcheck - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlcheck.exe" /libpath:"..\lib_release\\"
+
+!ELSEIF "$(CFG)" == "mysqlcheck - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlcheck.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlcheck - Win32 Release"
+# Name "mysqlcheck - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\client\mysqlcheck.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/mysqldemb/mysqldemb.dsp b/VC++Files/mysqldemb/mysqldemb.dsp
new file mode 100644
index 00000000000..a637c486574
--- /dev/null
+++ b/VC++Files/mysqldemb/mysqldemb.dsp
@@ -0,0 +1,392 @@
+# Microsoft Developer Studio Project File - Name="mysqldemb" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=mysqldemb - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldemb.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldemb.mak" CFG="mysqldemb - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqldemb - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "mysqldemb - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqldemb - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "mysqldemb - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqldemb - Win32 Release"
+# Name "mysqldemb - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\sql\convert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\derror.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\errmsg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field_conv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\filesort.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\get_password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_berkeley.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_heap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_innodb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_isammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hash_filo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hostname.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\init.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_buff.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_cmpfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_create.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_func.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_strfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_timefunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_uniq.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\key.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysqld\lib_load.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysqld\lib_sql.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysqld\libmysqld.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\lock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log_event.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mf_iocache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mini_client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_pkg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_serv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_ft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_range.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\procedure.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\records.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\repl_failsafe.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\slave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_acl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_analyse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_base.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_cache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_class.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_crypt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_db.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_delete.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_do.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_insert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_lex.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_list.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_manager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_map.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_parse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_rename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_repl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_select.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_show.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_udf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_union.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_yacc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\thr_malloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\time.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\uniques.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\unireg.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/mysqlmanager/MySqlManager.dsp b/VC++Files/mysqlmanager/MySqlManager.dsp
new file mode 100644
index 00000000000..56e1b4a5bf2
--- /dev/null
+++ b/VC++Files/mysqlmanager/MySqlManager.dsp
@@ -0,0 +1,252 @@
+# Microsoft Developer Studio Project File - Name="MySqlManager" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=MySqlManager - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "MySqlManager.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "MySqlManager.mak" CFG="MySqlManager - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "MySqlManager - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "MySqlManager - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "MySqlManager - Win32 Release"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /GX /O1 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX /Yc /Yu
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
+# ADD LINK32 /nologo /subsystem:windows /machine:I386 /out:"../client_release/MySqlManager.exe"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ELSEIF "$(CFG)" == "MySqlManager - Win32 Debug"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /GX /Zi /Od /I "../include" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /o "NUL" /win32
+# SUBTRACT MTL /mktyplib203
+# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /subsystem:windows /incremental:no /debug /machine:I386 /out:"../client_debug/MySqlManager.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "MySqlManager - Win32 Release"
+# Name "MySqlManager - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\ChildFrm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MainFrm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MySqlManager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MySqlManager.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\MySqlManagerDoc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MySqlManagerView.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegisterServer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\ToolSql.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ToolSqlQuery.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ToolSqlResults.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ToolSqlStatus.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\ChildFrm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MainFrm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MySqlManager.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MySqlManagerDoc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MySqlManagerView.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegisterServer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ToolSqlQuery.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ToolSqlResults.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ToolSqlStatus.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\res\bitmap1.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap3.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bmp00001.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bmp00002.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\database.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\fontd.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\fontu.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\MySqlManager.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\MySqlManager.rc2
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\MySqlManagerDoc.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\query_ex.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Toolbar.bmp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/mysqlmanager/mysqlmanager.dsw b/VC++Files/mysqlmanager/mysqlmanager.dsw
new file mode 100644
index 00000000000..02ec9a86dc5
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanager.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "MySqlManager"=.\MySqlManager.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/mysqlserver/mysqlserver.dsp b/VC++Files/mysqlserver/mysqlserver.dsp
new file mode 100644
index 00000000000..dda50cd5538
--- /dev/null
+++ b/VC++Files/mysqlserver/mysqlserver.dsp
@@ -0,0 +1,84 @@
+# Microsoft Developer Studio Project File - Name="mysqlserver" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=mysqlserver - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlserver.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlserver.mak" CFG="mysqlserver - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlserver - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "mysqlserver - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlserver - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "mysqlserver - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlserver - Win32 Release"
+# Name "mysqlserver - Win32 Debug"
+# End Target
+# End Project
diff --git a/VC++Files/mysqlshutdown/myshutdown.dsp b/VC++Files/mysqlshutdown/myshutdown.dsp
new file mode 100644
index 00000000000..390921f599c
--- /dev/null
+++ b/VC++Files/mysqlshutdown/myshutdown.dsp
@@ -0,0 +1,101 @@
+# Microsoft Developer Studio Project File - Name="myshutdown" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=myshutdown - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myshutdown.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myshutdown.mak" CFG="myshutdown - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myshutdown - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "myshutdown - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myshutdown - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+
+!ELSEIF "$(CFG)" == "myshutdown - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "myshutdown - Win32 Release"
+# Name "myshutdown - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/mysqlshutdown/mysqlshutdown.c b/VC++Files/mysqlshutdown/mysqlshutdown.c
new file mode 100644
index 00000000000..e770149604d
--- /dev/null
+++ b/VC++Files/mysqlshutdown/mysqlshutdown.c
@@ -0,0 +1,198 @@
+/****************************************************************************
+ MySqlShutdown - shutdown MySQL on system shutdown (Win95/98)
+ ----------------------------------------------------------------------------
+ Revision History :
+ Version Author Date Description
+ 001.00 Irena 21-12-99
+*****************************************************************************/
+#include <windows.h>
+
+//-----------------------------------------------------------------------
+// Local data
+//-----------------------------------------------------------------------
+static char szAppName[] = "MySqlShutdown";
+static HINSTANCE hInstance;
+
+#define MYWM_NOTIFYICON (WM_APP+100)
+
+//-----------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------
+LRESULT CALLBACK MainWindowProc (HWND, UINT, WPARAM, LPARAM);
+
+//-----------------------------------------------------------------------
+// Local functions
+//-----------------------------------------------------------------------
+static BOOL InitAppClass (HINSTANCE hInstance);
+
+BOOL TrayMessageAdd(HWND hWnd, DWORD dwMessage)
+{
+ BOOL res;
+ HICON hIcon =LoadIcon (hInstance, "MySql");
+ char *szTip="MySql Shutdown";
+ NOTIFYICONDATA tnd;
+
+ tnd.cbSize = sizeof(NOTIFYICONDATA);
+ tnd.hWnd = hWnd;
+ tnd.uID = 101;
+
+ tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
+ tnd.uCallbackMessage = MYWM_NOTIFYICON;
+ tnd.hIcon = hIcon;
+ strcpy(tnd.szTip, szTip);
+ res = Shell_NotifyIcon(dwMessage, &tnd);
+
+ if (hIcon) DestroyIcon(hIcon);
+
+ return res;
+}
+
+//-----------------------------------------------------------------------
+// Name: WinMain
+// Purpose: Main application entry point
+//-----------------------------------------------------------------------
+
+int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
+{ HWND hWnd;
+ MSG Msg;
+
+ hInstance=hInst;
+ // Register application class if needed
+ if (InitAppClass (hInstance) == FALSE) return (0);
+
+
+ hWnd = CreateWindow (szAppName, "MySql",
+ WS_OVERLAPPEDWINDOW|WS_MINIMIZE,
+ 0, 0,
+ GetSystemMetrics(SM_CXSCREEN)/4,
+ GetSystemMetrics(SM_CYSCREEN)/4,
+ 0, 0, hInstance, NULL);
+
+ if(!hWnd)
+ {
+ return (0);
+ }
+ ShowWindow (hWnd, SW_HIDE);
+ UpdateWindow (hWnd);
+ while (GetMessage (&Msg, 0, 0, 0))
+ { TranslateMessage (&Msg);
+ DispatchMessage (&Msg);
+ }
+ return ((int) (Msg.wParam));
+}
+
+//-----------------------------------------------------------------------
+// Name: InitAppClass
+// Purpose: Register the main application window class
+//-----------------------------------------------------------------------
+static BOOL InitAppClass (HINSTANCE hInstance)
+{
+ WNDCLASS cls;
+
+ if (GetClassInfo (hInstance, szAppName, &cls) == 0)
+ {
+ cls.style = CS_HREDRAW | CS_VREDRAW ;;
+ cls.lpfnWndProc = (WNDPROC) MainWindowProc;
+ cls.cbClsExtra = 0;
+ cls.cbWndExtra = sizeof(HWND);
+ cls.hInstance = hInstance;
+ cls.hIcon = LoadIcon (hInstance, "MySql");
+ cls.hCursor = LoadCursor (NULL, IDC_ARROW);
+ cls.hbrBackground = GetStockObject (WHITE_BRUSH) ;
+ cls.lpszMenuName = 0; //szAppName;
+ cls.lpszClassName = szAppName;
+ return RegisterClass (&cls);
+ }
+ return (TRUE);
+}
+//-----------------------------------------------------------------------
+// Name: MainWindowProc
+// Purpose: Window procedure for main application window.
+//-----------------------------------------------------------------------
+LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT Msg,WPARAM wParam, LPARAM lParam)
+{
+ static RECT rect ;
+ HDC hdc ;
+ PAINTSTRUCT ps ;
+ static BOOL bShutdown=FALSE;
+
+ switch (Msg)
+ {
+ case WM_CREATE:
+ TrayMessageAdd(hWnd, NIM_ADD);
+ return TRUE;
+/***************
+ case WM_SYSCOMMAND:
+ if(wParam==SC_CLOSE)
+ { HANDLE hEventShutdown;
+
+ bShutdown=TRUE;
+ InvalidateRect(hWnd,NULL,TRUE);
+ ShowWindow (hWnd, SW_NORMAL);
+ UpdateWindow(hWnd);
+ hEventShutdown=OpenEvent(EVENT_MODIFY_STATE, 0, "MySqlShutdown");
+ if(hEventShutdown)
+ {
+ SetEvent(hEventShutdown);
+ CloseHandle(hEventShutdown);
+ Sleep(1000);
+ MessageBox(hWnd,"Shutdown", "MySql", MB_OK);
+ }
+ TrayMessageAdd(hWnd, NIM_DELETE);
+ }
+ break;
+**************/
+ case WM_DESTROY:
+ TrayMessageAdd(hWnd, NIM_DELETE);
+ PostQuitMessage (0);
+ return 0;
+ case WM_SIZE:
+ GetClientRect (hWnd, &rect) ;
+ return 0 ;
+
+ case WM_PAINT:
+ hdc = BeginPaint (hWnd, &ps) ;
+ if(bShutdown)
+ DrawText (hdc, "MySql shutdown in progress...",
+ -1, &rect, DT_WORDBREAK) ;
+ EndPaint (hWnd, &ps) ;
+ return 0 ;
+ case WM_QUERYENDSESSION: //Shutdown MySql
+ { HANDLE hEventShutdown;
+
+ bShutdown=TRUE;
+ InvalidateRect(hWnd,NULL,TRUE);
+ ShowWindow (hWnd, SW_NORMAL);
+ UpdateWindow(hWnd);
+ hEventShutdown=OpenEvent(EVENT_MODIFY_STATE, 0, "MySqlShutdown");
+ if(hEventShutdown)
+ {
+ SetEvent(hEventShutdown);
+ CloseHandle(hEventShutdown);
+ Sleep(1000);
+ MessageBox(hWnd,"Shutdown", "MySql", MB_OK);
+ }
+ }
+ return 1;
+
+ case MYWM_NOTIFYICON:
+ switch (lParam)
+ {
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ ShowWindow(hWnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hWnd); // make us come to the front
+ break;
+ default:
+ break;
+ }
+ break;
+
+ }
+ return DefWindowProc (hWnd, Msg, wParam, lParam);
+}
+
+
+// ----------------------- The end ------------------------------------------
+
+
diff --git a/VC++Files/mysqlshutdown/mysqlshutdown.dsp b/VC++Files/mysqlshutdown/mysqlshutdown.dsp
new file mode 100644
index 00000000000..1489a5547ed
--- /dev/null
+++ b/VC++Files/mysqlshutdown/mysqlshutdown.dsp
@@ -0,0 +1,119 @@
+# Microsoft Developer Studio Project File - Name="mysqlshutdown" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=mysqlshutdown - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlshutdown.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlshutdown.mak" CFG="mysqlshutdown - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlshutdown - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "mysqlshutdown - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlshutdown - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /W3 /GX- /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"../client_release/mysqlshutdown.exe"
+
+!ELSEIF "$(CFG)" == "mysqlshutdown - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "mysqlshutdown___Win32_Debug"
+# PROP BASE Intermediate_Dir "mysqlshutdown___Win32_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /W3 /GX- /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"../client_release/mysqlshutdown.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"../client_debug/mysqlshutdown.exe"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlshutdown - Win32 Release"
+# Name "mysqlshutdown - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\mysqlshutdown.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysqlshutdown.rc
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\mysql.ico
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/mysqlwatch/mysqlwatch.c b/VC++Files/mysqlwatch/mysqlwatch.c
new file mode 100644
index 00000000000..2aba6814869
--- /dev/null
+++ b/VC++Files/mysqlwatch/mysqlwatch.c
@@ -0,0 +1,745 @@
+/****************************************************************************
+ MySqlWatch - WinNT service program MySQL
+ - Re-start MySql server in case of failure
+*****************************************************************************/
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <process.h>
+#include <tchar.h>
+
+
+// name of the executable
+#define SZAPPNAME "mysqlwatch"
+// internal name of the service
+#define SZSERVICENAME "MySqlWatch"
+// displayed name of the service
+#define SZSERVICEDISPLAYNAME "MySqlWatch"
+// list of service dependencies - "dep1\0dep2\0\0"
+#define SZDEPENDENCIES ""
+
+
+
+VOID ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
+VOID ServiceStop(void);
+BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
+void AddToMessageLog(LPTSTR lpszMsg);
+
+// internal variables
+SERVICE_STATUS ssStatus; // current status of the service
+SERVICE_STATUS_HANDLE sshStatusHandle;
+DWORD dwErr = 0;
+BOOL bDebug = FALSE;
+TCHAR szErr[256];
+
+// internal function prototypes
+void WINAPI service_ctrl(DWORD dwCtrlCode);
+void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
+void CmdInstallService(void);
+void CmdRemoveService(void);
+void CmdDebugService(int argc, char **argv);
+BOOL WINAPI ControlHandler ( DWORD dwCtrlType );
+LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
+
+//
+// FUNCTION: main
+//
+// PURPOSE: entrypoint for service
+//
+// PARAMETERS:
+// argc - number of command line arguments
+// argv - array of command line arguments
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+// main() either performs the command line task, or
+// call StartServiceCtrlDispatcher to register the
+// main service thread. When the this call returns,
+// the service has stopped, so exit.
+//
+void main(int argc, char **argv)
+{
+ SERVICE_TABLE_ENTRY dispatchTable[] =
+ {
+ { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
+ { NULL, NULL }
+ };
+
+ if ( (argc > 1) &&
+ ((*argv[1] == '-') || (*argv[1] == '/')) )
+ {
+ if ( stricmp( "install", argv[1]+1 ) == 0 )
+ {
+ CmdInstallService();
+ }
+ else if ( stricmp( "remove", argv[1]+1 ) == 0 )
+ {
+ CmdRemoveService();
+ }
+ else if ( stricmp( "debug", argv[1]+1 ) == 0 )
+ {
+ bDebug = TRUE;
+ CmdDebugService(argc, argv);
+ }
+ else
+ {
+ goto dispatch;
+ }
+ exit(0);
+ }
+
+ // if it doesn't match any of the above parameters
+ // the service control manager may be starting the service
+ // so we must call StartServiceCtrlDispatcher
+ dispatch:
+ // this is just to be friendly
+ printf( "%s -install to install the service\n", SZAPPNAME );
+ printf( "%s -remove to remove the service\n", SZAPPNAME );
+ printf( "%s -debug <params> to run as a console app for debugging\n", SZAPPNAME );
+ printf( "\nStartServiceCtrlDispatcher being called.\n" );
+ printf( "This may take several seconds. Please wait.\n" );
+
+ if (!StartServiceCtrlDispatcher(dispatchTable))
+ AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
+}
+
+
+
+//
+// FUNCTION: service_main
+//
+// PURPOSE: To perform actual initialization of the service
+//
+// PARAMETERS:
+// dwArgc - number of command line arguments
+// lpszArgv - array of command line arguments
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+// This routine performs the service initialization and then calls
+// the user defined ServiceStart() routine to perform majority
+// of the work.
+//
+void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
+{
+
+ // register our service control handler:
+ //
+ sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
+
+ if (!sshStatusHandle)
+ goto cleanup;
+
+ // SERVICE_STATUS members that don't change in example
+ //
+ ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ ssStatus.dwServiceSpecificExitCode = 0;
+
+
+ // report the status to the service control manager.
+ //
+ if (!ReportStatusToSCMgr(
+ SERVICE_START_PENDING, // service state
+ NO_ERROR, // exit code
+ 3000)) // wait hint
+ goto cleanup;
+
+
+ ServiceStart( dwArgc, lpszArgv );
+
+cleanup:
+
+ // try to report the stopped status to the service control manager.
+ //
+ if (sshStatusHandle)
+ ReportStatusToSCMgr(
+ SERVICE_STOPPED,
+ dwErr,
+ 0);
+
+ return;
+}
+
+
+
+//
+// FUNCTION: service_ctrl
+//
+// PURPOSE: This function is called by the SCM whenever
+// ControlService() is called on this service.
+//
+// PARAMETERS:
+// dwCtrlCode - type of control requested
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+//
+void WINAPI service_ctrl(DWORD dwCtrlCode)
+{
+ // Handle the requested control code.
+ //
+ switch(dwCtrlCode)
+ {
+ // Stop the service.
+ //
+ case SERVICE_CONTROL_STOP:
+ ssStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ ServiceStop();
+ break;
+
+ // Update the service status.
+ //
+ case SERVICE_CONTROL_INTERROGATE:
+ break;
+
+ // invalid control code
+ //
+ default:
+ break;
+
+ }
+
+ ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
+
+}
+
+
+
+//
+// FUNCTION: ReportStatusToSCMgr()
+//
+// PURPOSE: Sets the current status of the service and
+// reports it to the Service Control Manager
+//
+// PARAMETERS:
+// dwCurrentState - the state of the service
+// dwWin32ExitCode - error code to report
+// dwWaitHint - worst case estimate to next checkpoint
+//
+// RETURN VALUE:
+// TRUE - success
+// FALSE - failure
+//
+// COMMENTS:
+//
+BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
+ DWORD dwWin32ExitCode,
+ DWORD dwWaitHint)
+{
+ static DWORD dwCheckPoint = 1;
+ BOOL fResult = TRUE;
+
+
+ if ( !bDebug ) // when debugging we don't report to the SCM
+ {
+ if (dwCurrentState == SERVICE_START_PENDING)
+ ssStatus.dwControlsAccepted = 0;
+ else
+ ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+ ssStatus.dwCurrentState = dwCurrentState;
+ ssStatus.dwWin32ExitCode = dwWin32ExitCode;
+ ssStatus.dwWaitHint = dwWaitHint;
+
+ if ( ( dwCurrentState == SERVICE_RUNNING ) ||
+ ( dwCurrentState == SERVICE_STOPPED ) )
+ ssStatus.dwCheckPoint = 0;
+ else
+ ssStatus.dwCheckPoint = dwCheckPoint++;
+
+
+ // Report the status of the service to the service control manager.
+ //
+ if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) {
+ AddToMessageLog(TEXT("SetServiceStatus"));
+ }
+ }
+ return fResult;
+}
+
+
+
+//
+// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
+//
+// PURPOSE: Allows any thread to log an error message
+//
+// PARAMETERS:
+// lpszMsg - text for message
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+//
+void AddToMessageLog(LPTSTR lpszMsg)
+{
+ TCHAR szMsg[256];
+ HANDLE hEventSource;
+ LPTSTR lpszStrings[2];
+
+
+ if ( !bDebug )
+ {
+ dwErr = GetLastError();
+
+ // Use event logging to log the error.
+ //
+ hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
+
+ _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
+ lpszStrings[0] = szMsg;
+ lpszStrings[1] = lpszMsg;
+
+ if (hEventSource != NULL) {
+ ReportEvent(hEventSource, // handle of event source
+ EVENTLOG_ERROR_TYPE, // event type
+ 0, // event category
+ 0, // event ID
+ NULL, // current user's SID
+ 2, // strings in lpszStrings
+ 0, // no bytes of raw data
+ lpszStrings, // array of error strings
+ NULL); // no raw data
+
+ DeregisterEventSource(hEventSource);
+ }
+ }
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////
+//
+// The following code handles service installation and removal
+//
+
+
+//
+// FUNCTION: CmdInstallService()
+//
+// PURPOSE: Installs the service
+//
+// PARAMETERS:
+// none
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+//
+void CmdInstallService()
+{
+ SC_HANDLE schService;
+ SC_HANDLE schSCManager;
+
+ TCHAR szPath[512];
+
+ if ( GetModuleFileName( NULL, szPath, 512 ) == 0 )
+ {
+ _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
+ return;
+ }
+
+ schSCManager = OpenSCManager(
+ NULL, // machine (NULL == local)
+ NULL, // database (NULL == default)
+ SC_MANAGER_ALL_ACCESS // access required
+ );
+ if ( schSCManager )
+ {
+ schService = CreateService(
+ schSCManager, // SCManager database
+ TEXT(SZSERVICENAME), // name of service
+ TEXT(SZSERVICEDISPLAYNAME), // name to display
+ SERVICE_ALL_ACCESS, // desired access
+ SERVICE_WIN32_OWN_PROCESS, // service type
+ SERVICE_DEMAND_START, // start type
+ SERVICE_ERROR_NORMAL, // error control type
+ szPath, // service's binary
+ NULL, // no load ordering group
+ NULL, // no tag identifier
+ TEXT(SZDEPENDENCIES), // dependencies
+ NULL, // LocalSystem account
+ NULL); // no password
+
+ if ( schService )
+ {
+ _tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
+ CloseServiceHandle(schService);
+ }
+ else
+ {
+ _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
+ }
+
+ CloseServiceHandle(schSCManager);
+ }
+ else
+ _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
+}
+
+
+
+//
+// FUNCTION: CmdRemoveService()
+//
+// PURPOSE: Stops and removes the service
+//
+// PARAMETERS:
+// none
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+//
+void CmdRemoveService()
+{
+ SC_HANDLE schService;
+ SC_HANDLE schSCManager;
+
+ schSCManager = OpenSCManager(
+ NULL, // machine (NULL == local)
+ NULL, // database (NULL == default)
+ SC_MANAGER_ALL_ACCESS // access required
+ );
+ if ( schSCManager )
+ {
+ schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
+
+ if (schService)
+ {
+ // try to stop the service
+ if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) )
+ {
+ _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
+ Sleep( 1000 );
+
+ while( QueryServiceStatus( schService, &ssStatus ) )
+ {
+ if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
+ {
+ _tprintf(TEXT("."));
+ Sleep( 1000 );
+ }
+ else
+ break;
+ }
+
+ if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
+ _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
+ else
+ _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
+
+ }
+
+ // now remove the service
+ if( DeleteService(schService) )
+ _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
+ else
+ _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
+
+
+ CloseServiceHandle(schService);
+ }
+ else
+ _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
+
+ CloseServiceHandle(schSCManager);
+ }
+ else
+ _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
+}
+
+
+
+
+
+//
+// FUNCTION: CmdRestartService()
+//
+// PURPOSE: Stops and removes the service
+//
+// PARAMETERS:
+// none
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+//
+void CmdRestartService(char *szServiceName)
+{
+ SC_HANDLE schService;
+ SC_HANDLE schSCManager;
+
+ schSCManager = OpenSCManager(
+ NULL, // machine (NULL == local)
+ NULL, // database (NULL == default)
+ SC_MANAGER_ALL_ACCESS // access required
+ );
+ if ( schSCManager )
+ {
+ schService = OpenService(schSCManager, TEXT(szServiceName), SERVICE_ALL_ACCESS);
+ if (schService)
+ {
+ if(! ControlService( schService, SERVICE_CONTROL_INTERROGATE, &ssStatus ) )
+ //if(QueryServiceStatus( schService, &ssStatus )==0)
+ {
+ if(GetLastError()==ERROR_SERVICE_NOT_ACTIVE)
+ {
+
+ //AddToMessageLog(TEXT("Start service..."));
+ StartService( schService, 0,NULL);
+ }
+ else
+ { ;
+ //AddToMessageLog(TEXT("QueryService..."));
+ //AddToMessageLog(TEXT(GetLastErrorText(szErr,256)));
+ }
+ }
+ CloseServiceHandle(schService);
+ }
+ else
+ { _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
+ AddToMessageLog(TEXT("OpenService..."));
+ AddToMessageLog(TEXT(GetLastErrorText(szErr,256)));
+
+ }
+ CloseServiceHandle(schSCManager);
+ }
+ else
+ { _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
+ AddToMessageLog(TEXT("OpenSCMManager.."));
+
+ }
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////
+//
+// The following code is for running the service as a console app
+//
+
+
+//
+// FUNCTION: CmdDebugService(int argc, char ** argv)
+//
+// PURPOSE: Runs the service as a console application
+//
+// PARAMETERS:
+// argc - number of command line arguments
+// argv - array of command line arguments
+//
+// RETURN VALUE:
+// none
+//
+// COMMENTS:
+//
+void CmdDebugService(int argc, char ** argv)
+{
+ DWORD dwArgc;
+ LPTSTR *lpszArgv;
+
+#ifdef UNICODE
+ lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
+#else
+ dwArgc = (DWORD) argc;
+ lpszArgv = argv;
+#endif
+
+ _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
+
+ SetConsoleCtrlHandler( ControlHandler, TRUE );
+
+ ServiceStart( dwArgc, lpszArgv );
+}
+
+
+//
+// FUNCTION: ControlHandler ( DWORD dwCtrlType )
+//
+// PURPOSE: Handled console control events
+//
+// PARAMETERS:
+// dwCtrlType - type of control event
+//
+// RETURN VALUE:
+// True - handled
+// False - unhandled
+//
+// COMMENTS:
+//
+BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
+{
+ switch( dwCtrlType )
+ {
+ case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate
+ case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
+ _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
+ ServiceStop();
+ return TRUE;
+ break;
+
+ }
+ return FALSE;
+}
+
+//
+// FUNCTION: GetLastErrorText
+//
+// PURPOSE: copies error message text to string
+//
+// PARAMETERS:
+// lpszBuf - destination buffer
+// dwSize - size of buffer
+//
+// RETURN VALUE:
+// destination buffer
+//
+// COMMENTS:
+//
+LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
+{
+ DWORD dwRet;
+ LPTSTR lpszTemp = NULL;
+
+ dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ NULL,
+ GetLastError(),
+ LANG_NEUTRAL,
+ (LPTSTR)&lpszTemp,
+ 0,
+ NULL );
+
+ // supplied buffer is not long enough
+ if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
+ lpszBuf[0] = TEXT('\0');
+ else
+ {
+ lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
+ _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
+ }
+
+ if ( lpszTemp )
+ LocalFree((HLOCAL) lpszTemp );
+
+ return lpszBuf;
+}
+
+//-------------------------------------------------
+// this event is signalled when the
+// service should end
+//-------------------------------------------------
+HANDLE hServerStopEvent = NULL;
+
+
+//-------------------------------------------------
+// FUNCTION: ServiceStart
+//
+// PURPOSE: Actual code of the service
+// that does the work.
+//-------------------------------------------------
+void ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
+{
+ DWORD dwWait,dwTimeout=1000*60*1;
+
+ if (!ReportStatusToSCMgr(
+ SERVICE_START_PENDING, // service state
+ NO_ERROR, // exit code
+ 3000)) // wait hint
+ goto cleanup;
+
+ // create the event object. The control handler function signals
+ // this event when it receives the "stop" control code.
+ //
+ hServerStopEvent = CreateEvent(
+ NULL, // no security attributes
+ TRUE, // manual reset event
+ FALSE, // not-signalled
+ NULL); // no name
+
+ if ( hServerStopEvent == NULL) goto cleanup;
+
+
+ // report the status to the service control manager.
+ //
+ if (!ReportStatusToSCMgr(
+ SERVICE_START_PENDING, // service state
+ NO_ERROR, // exit code
+ 3000)) // wait hint
+ goto cleanup;
+
+
+
+ // report the status to the service control manager.
+ //
+ if (!ReportStatusToSCMgr(
+ SERVICE_START_PENDING, // service state
+ NO_ERROR, // exit code
+ 3000)) // wait hint
+ goto cleanup;
+
+
+
+ // report the status to the service control manager.
+ //
+ if (!ReportStatusToSCMgr(
+ SERVICE_RUNNING, // service state
+ NO_ERROR, // exit code
+ 0)) // wait hint
+ goto cleanup;
+
+ //
+ // End of initialization
+ // Service is now running, perform work until shutdown
+ //
+
+ while ( 1 )
+ {
+
+ dwWait = WaitForSingleObject( hServerStopEvent, dwTimeout);
+ if(dwWait==WAIT_FAILED)
+ {
+ AddToMessageLog(TEXT("Error in WaitForSingleObject"));
+ break;
+ }
+ else if(dwWait==WAIT_TIMEOUT)
+ {
+ CmdRestartService("MySql");
+ }
+ else
+ { break; //shutdown
+ }
+
+ }
+
+ cleanup:
+
+ if (hServerStopEvent)
+ CloseHandle(hServerStopEvent);
+
+}
+
+
+//-------------------------------------------------
+// FUNCTION: ServiceStop
+//
+// PURPOSE: Stops the service
+//-------------------------------------------------
+void ServiceStop()
+{
+ if ( hServerStopEvent )
+ SetEvent(hServerStopEvent);
+}
+//-the end ----------------------------------------
diff --git a/VC++Files/mysqlwatch/mysqlwatch.dsp b/VC++Files/mysqlwatch/mysqlwatch.dsp
new file mode 100644
index 00000000000..004f444e09b
--- /dev/null
+++ b/VC++Files/mysqlwatch/mysqlwatch.dsp
@@ -0,0 +1,70 @@
+# Microsoft Developer Studio Project File - Name="mysqlwatch" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqlwatch - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlwatch.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlwatch.mak" CFG="mysqlwatch - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlwatch - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /W3 /GX- /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlwatch.exe"
+# Begin Target
+
+# Name "mysqlwatch - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\mysqlwatch.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/mysys/mysys.dsp b/VC++Files/mysys/mysys.dsp
new file mode 100644
index 00000000000..7a0087b68d6
--- /dev/null
+++ b/VC++Files/mysys/mysys.dsp
@@ -0,0 +1,518 @@
+# Microsoft Developer Studio Project File - Name="mysys" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=mysys - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysys.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysys.mak" CFG="mysys - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysys - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "mysys - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "mysys - Win32 Max" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysys - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\mysys.lib"
+
+!ELSEIF "$(CFG)" == "mysys - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Zi /Od /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\mysys.lib"
+
+!ELSEIF "$(CFG)" == "mysys - Win32 Max"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "mysys___Win32_Max"
+# PROP BASE Intermediate_Dir "mysys___Win32_Max"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "mysys___Win32_Max"
+# PROP Intermediate_Dir "mysys___Win32_Max"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\mysys.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\mysys-max.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysys - Win32 Release"
+# Name "mysys - Win32 Debug"
+# Name "mysys - Win32 Max"
+# Begin Source File
+
+SOURCE=.\array.c
+
+!IF "$(CFG)" == "mysys - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysys - Win32 Debug"
+
+# ADD CPP /FR
+
+!ELSEIF "$(CFG)" == "mysys - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\charset.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\checksum.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\default.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\errors.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\list.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\md5.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_brkhant.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_cache.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_casecnv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_dirname.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_fn_ext.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_format.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_getdate.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_iocache.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_iocache2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_keycache.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_loadpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_pack.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_path.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_qsort.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_qsort2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_radix.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_same.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_sort.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_soundex.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_strip.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_tempfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_wcomp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_wfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mulalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_aes.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_alarm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_append.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_bit.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_bitmap.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_chsize.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_clock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_copy.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_div.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_error.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_fopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_fstream.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_gethostbyname.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_getopt.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_getwd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_lib.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_lock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_lockmem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_lread.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_lwrite.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_malloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_messnc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_mkdir.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_net.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_once.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_pread.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_pthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_quick.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_read.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_realloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_redel.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_seek.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_static.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_symlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_symlink2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_tempnam.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_thr_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_vsnprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_wincond.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_winsem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_winthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_write.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysys_priv.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ptr_cmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\queues.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\raid.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rijndael.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\safemalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sha1.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\string.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_alarm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_lock.c
+
+!IF "$(CFG)" == "mysys - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysys - Win32 Debug"
+
+# ADD CPP /D "EXTRA_DEBUG"
+
+!ELSEIF "$(CFG)" == "mysys - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_mutex.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_rwlock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\tree.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\typelib.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/mysys/mysys.dsw b/VC++Files/mysys/mysys.dsw
new file mode 100644
index 00000000000..d5064051fc9
--- /dev/null
+++ b/VC++Files/mysys/mysys.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "mysys"=".\mysys.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/pack_isam/pack_isam.dsp b/VC++Files/pack_isam/pack_isam.dsp
new file mode 100644
index 00000000000..036dcd9a2ca
--- /dev/null
+++ b/VC++Files/pack_isam/pack_isam.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="pack_isam" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=pack_isam - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pack_isam.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pack_isam.mak" CFG="pack_isam - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pack_isam - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "pack_isam - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pack_isam - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../isam" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /machine:I386 /out:"../client_release/pack_isam.exe"
+
+!ELSEIF "$(CFG)" == "pack_isam - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../isam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /debug /machine:I386 /out:"../client_debug/pack_isam.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "pack_isam - Win32 Release"
+# Name "pack_isam - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\pack_isam.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/perror/perror.dsp b/VC++Files/perror/perror.dsp
new file mode 100644
index 00000000000..2b720ace3e7
--- /dev/null
+++ b/VC++Files/perror/perror.dsp
@@ -0,0 +1,109 @@
+# Microsoft Developer Studio Project File - Name="perror" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=perror - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "perror.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "perror.mak" CFG="perror - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "perror - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "perror - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "perror - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/perror.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "perror - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /incremental:no /debug /machine:I386 /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "perror - Win32 Release"
+# Name "perror - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\extra\perror.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/regex/regex.dsp b/VC++Files/regex/regex.dsp
new file mode 100644
index 00000000000..5ee617c58b7
--- /dev/null
+++ b/VC++Files/regex/regex.dsp
@@ -0,0 +1,114 @@
+# Microsoft Developer Studio Project File - Name="regex" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=regex - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "regex.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "regex.mak" CFG="regex - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "regex - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "regex - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "regex - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "./" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\regex.lib"
+
+!ELSEIF "$(CFG)" == "regex - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /I "./" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\regex.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "regex - Win32 Release"
+# Name "regex - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\debug.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\regcomp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\regerror.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\regexec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\regfree.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\reginit.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\split.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/regex/regex.dsw b/VC++Files/regex/regex.dsw
new file mode 100644
index 00000000000..102e07af409
--- /dev/null
+++ b/VC++Files/regex/regex.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "regex"=".\regex.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/replace/replace.dsp b/VC++Files/replace/replace.dsp
new file mode 100644
index 00000000000..54584151418
--- /dev/null
+++ b/VC++Files/replace/replace.dsp
@@ -0,0 +1,92 @@
+# Microsoft Developer Studio Project File - Name="replace" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=replace - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "replace.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "replace.mak" CFG="replace - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "replace - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "replace - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "replace - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x40b /d "NDEBUG"
+# ADD RSC /l 0x40b /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /machine:I386 /out:"../client_release/replace.exe"
+
+!ELSEIF "$(CFG)" == "replace - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x40b /d "_DEBUG"
+# ADD RSC /l 0x40b /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /machine:I386 /out:"../client_debug/replace.exe" /pdbtype:sept
+# SUBTRACT LINK32 /debug
+
+!ENDIF
+
+# Begin Target
+
+# Name "replace - Win32 Release"
+# Name "replace - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\extra\replace.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp
new file mode 100644
index 00000000000..a84af8adedc
--- /dev/null
+++ b/VC++Files/sql/mysqld.dsp
@@ -0,0 +1,1280 @@
+# Microsoft Developer Studio Project File - Name="mysqld" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqld - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqld.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqld.mak" CFG="mysqld - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqld - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqld - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqld - Win32 nt" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqld - Win32 Max nt" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqld - Win32 Max" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x410 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-opt.exe"
+# SUBTRACT LINK32 /debug
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../regex" /I "../bdb/build_win32" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# ADD BASE RSC /l 0x410 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\vio.lib ..\lib_debug\isam.lib ..\lib_debug\merge.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\bdb.lib ..\lib_debug\innodb.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqld.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "mysqld__"
+# PROP BASE Intermediate_Dir "mysqld__"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "NT"
+# PROP Intermediate_Dir "NT"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G5 /MT /W3 /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__WIN32__" /D "DBUG_OFF" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x410 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\dbug.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-nt.exe"
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "mysqld___Win32_Max_nt"
+# PROP BASE Intermediate_Dir "mysqld___Win32_Max_nt"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "mysqld___Win32_Max_nt"
+# PROP Intermediate_Dir "mysqld___Win32_Max_nt"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-nt.exe"
+# SUBTRACT BASE LINK32 /pdb:none /debug
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib ..\lib_release\innodb-nt.lib ..\lib_release\bdb.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-max-nt.exe"
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "mysqld___Win32_Max"
+# PROP BASE Intermediate_Dir "mysqld___Win32_Max"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "mysqld___Win32_Max"
+# PROP Intermediate_Dir "mysqld___Win32_Max"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"../client_release/mysqld-opt.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-max.exe"
+# SUBTRACT LINK32 /debug
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqld - Win32 Release"
+# Name "mysqld - Win32 Debug"
+# Name "mysqld - Win32 nt"
+# Name "mysqld - Win32 Max nt"
+# Name "mysqld - Win32 Max"
+# Begin Source File
+
+SOURCE=.\convert.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\derror.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\field.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\field_conv.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\filesort.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_berkeley.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_heap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_innodb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_isam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_isammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_myisam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_myisammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\handler.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash_filo.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash_filo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\hostname.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\init.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_buff.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_cmpfunc.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_create.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_func.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_strfunc.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_sum.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_timefunc.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_uniq.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\key.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\log.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\log_event.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_iocache.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\mini_client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mini_client_errors.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysqld.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\net_pkg.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\net_serv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\nt_servc.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\nt_servc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\opt_ft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\opt_range.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\opt_range.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OPT_SUM.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\password.c
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\procedure.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\records.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\repl_failsafe.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\slave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_acl.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_analyse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_base.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_cache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_class.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_crypt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_crypt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_db.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_delete.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_do.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_insert.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_lex.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_list.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_load.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_manager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_map.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_parse.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_rename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_repl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_select.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_show.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_string.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_table.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_test.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_udf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_union.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_update.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_yacc.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_malloc.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\time.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\uniques.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\unireg.cpp
+
+!IF "$(CFG)" == "mysqld - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
+
+!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/sql/mysqldmax.dsp b/VC++Files/sql/mysqldmax.dsp
new file mode 100644
index 00000000000..4d24d033c51
--- /dev/null
+++ b/VC++Files/sql/mysqldmax.dsp
@@ -0,0 +1,1003 @@
+# Microsoft Developer Studio Project File - Name="mysqldmax" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqldmax - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldmax.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldmax.mak" CFG="mysqldmax - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqldmax - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqldmax - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqldmax - Win32 nt" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "HAVE_INNOBASE_DB" /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innobase-opt.lib ..\lib_release\libdb32s.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../client_release/mysqld-max-opt.exe"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /ZI /Od /I "../include" /I "../regex" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "HAVE_INNOBASE_DB" /FR /FD /c
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\isam.lib ..\lib_debug\merge.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_release\innobase-opt.lib ..\lib_release\libdb32s.lib /nologo /subsystem:console /incremental:no /pdb:"debug/mysqld.pdb" /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../client_debug/mysqld-max.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "nt"
+# PROP BASE Intermediate_Dir "nt"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "nt"
+# PROP Intermediate_Dir "nt"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "HAVE_INNOBASE_DB" /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib ..\lib_release\innobase-nt.lib ..\lib_release\libdb32s.lib /nologo /subsystem:console /pdb:"NT/mysqld-nt.pdb" /map:"NT/mysqld-nt.map" /machine:I386 /nodefaultlib:"LIBC" /out:"../client_release/mysqld-max-nt.exe"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqldmax - Win32 Release"
+# Name "mysqldmax - Win32 Debug"
+# Name "mysqldmax - Win32 nt"
+# Begin Source File
+
+SOURCE=.\convert.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\derror.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\field.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\field_conv.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\filesort.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_berkeley.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_heap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_innobase.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_isam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_isammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_myisam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ha_myisammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\handler.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash_filo.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash_filo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\hostname.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\init.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_buff.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_cmpfunc.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_create.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_func.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_strfunc.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_sum.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_timefunc.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\item_uniq.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\key.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\log.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\log_event.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\md5.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mf_iocache.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\mini_client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mini_client_errors.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysqld.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\net_pkg.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\net_serv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\nt_servc.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\nt_servc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\opt_ft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\opt_range.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\opt_range.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\opt_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\password.c
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\procedure.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\records.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\slave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_acl.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_analyse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_base.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_cache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_class.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_crypt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_crypt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_db.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_delete.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_insert.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_lex.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_list.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_load.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_manager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_map.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_parse.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_rename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_repl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_select.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_show.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_string.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_table.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_test.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_update.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\sql_yacc.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_malloc.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\time.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\unireg.cpp
+
+!IF "$(CFG)" == "mysqldmax - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 Debug"
+
+# ADD CPP /G5
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\violite.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/sql/old/mysqld.dsw b/VC++Files/sql/old/mysqld.dsw
new file mode 100644
index 00000000000..ed820ed7a90
--- /dev/null
+++ b/VC++Files/sql/old/mysqld.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "mysqld"=".\mysqld.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/strings/backup/strings.dsp b/VC++Files/strings/backup/strings.dsp
new file mode 100644
index 00000000000..45b22c52e21
--- /dev/null
+++ b/VC++Files/strings/backup/strings.dsp
@@ -0,0 +1,244 @@
+# Microsoft Developer Studio Project File - Name="strings" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=strings - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak" CFG="strings - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "strings - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "strings - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\strings.lib"
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\strings.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "strings - Win32 Release"
+# Name "strings - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\atof.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bcmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bmove512.c
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=.\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strings.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(OutDir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(Outdir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtol.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoull.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strxmov.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(OutDir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(Outdir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strxnmov.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/strings/backup/strings.dsw b/VC++Files/strings/backup/strings.dsw
new file mode 100644
index 00000000000..e3777b8e7d5
--- /dev/null
+++ b/VC++Files/strings/backup/strings.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "strings"=".\strings.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/strings/noMASM/strings.dsp b/VC++Files/strings/noMASM/strings.dsp
new file mode 100644
index 00000000000..a84fb1b7835
--- /dev/null
+++ b/VC++Files/strings/noMASM/strings.dsp
@@ -0,0 +1,246 @@
+# Microsoft Developer Studio Project File - Name="strings" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=strings - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak" CFG="strings - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "strings - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "strings - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\strings.lib"
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\strings.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "strings - Win32 Release"
+# Name "strings - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\atof.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bcmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bmove.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bmove512.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bmove_upp.c
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=.\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\is_prefix.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strappend.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strcend.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strcont.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strend.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strmake.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strnlen.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strnmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtol.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoull.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strxmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strxnmov.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/strings/strings.dsp b/VC++Files/strings/strings.dsp
new file mode 100644
index 00000000000..52655947790
--- /dev/null
+++ b/VC++Files/strings/strings.dsp
@@ -0,0 +1,248 @@
+# Microsoft Developer Studio Project File - Name="strings" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=strings - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak" CFG="strings - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "strings - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "strings - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\strings.lib"
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\strings.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "strings - Win32 Release"
+# Name "strings - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\atof.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bcmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bmove512.c
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=.\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strings.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtol.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoull.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strxmov.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strxnmov.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/test1/test1.dsp b/VC++Files/test1/test1.dsp
new file mode 100644
index 00000000000..ffa5fd4d7ed
--- /dev/null
+++ b/VC++Files/test1/test1.dsp
@@ -0,0 +1,101 @@
+# Microsoft Developer Studio Project File - Name="test1" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=test1 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "test1.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "test1.mak" CFG="test1 - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "test1 - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "test1 - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "test1 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /W3 /O2 /I "../include" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "test1 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\lib_debug"
+# SUBTRACT LINK32 /incremental:no
+
+!ENDIF
+
+# Begin Target
+
+# Name "test1 - Win32 Release"
+# Name "test1 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mysql_thr.c
+
+!IF "$(CFG)" == "test1 - Win32 Release"
+
+# ADD CPP /MT
+
+!ELSEIF "$(CFG)" == "test1 - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/thr_insert_test/thr_insert_test.dsp b/VC++Files/thr_insert_test/thr_insert_test.dsp
new file mode 100644
index 00000000000..91274e6817a
--- /dev/null
+++ b/VC++Files/thr_insert_test/thr_insert_test.dsp
@@ -0,0 +1,109 @@
+# Microsoft Developer Studio Project File - Name="thr_insert_test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=thr_insert_test - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "thr_insert_test.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "thr_insert_test.mak" CFG="thr_insert_test - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "thr_insert_test - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "thr_insert_test - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "thr_insert_test - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/hr_insert_test.exe" /libpath:"..\lib_release\\"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "thr_insert_test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:"debug/mysqldump.pdb" /debug /machine:I386 /out:"../client_debug/thr_insert_test.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "thr_insert_test - Win32 Release"
+# Name "thr_insert_test - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\tests\thr_insert_test.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/thr_test/thr_test.dsp b/VC++Files/thr_test/thr_test.dsp
new file mode 100644
index 00000000000..495d7280808
--- /dev/null
+++ b/VC++Files/thr_test/thr_test.dsp
@@ -0,0 +1,103 @@
+# Microsoft Developer Studio Project File - Name="thr_test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=thr_test - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "thr_test.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "thr_test.mak" CFG="thr_test - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "thr_test - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "thr_test - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "thr_test - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x40b /d "NDEBUG"
+# ADD RSC /l 0x40b /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# SUBTRACT LINK32 /nodefaultlib
+
+!ELSEIF "$(CFG)" == "thr_test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x40b /d "_DEBUG"
+# ADD RSC /l 0x40b /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "thr_test - Win32 Release"
+# Name "thr_test - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\thr_test.c
+
+!IF "$(CFG)" == "thr_test - Win32 Release"
+
+# ADD CPP /G5
+
+!ELSEIF "$(CFG)" == "thr_test - Win32 Debug"
+
+# ADD CPP /FAcs
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/vio/vio.dsp b/VC++Files/vio/vio.dsp
new file mode 100644
index 00000000000..7c6ecb47e5d
--- /dev/null
+++ b/VC++Files/vio/vio.dsp
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="vio" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=vio - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "vio.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "vio.mak" CFG="vio - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "vio - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "vio - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "vio - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\vio.lib"
+
+!ELSEIF "$(CFG)" == "vio - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Zi /Od /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\vio.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "vio - Win32 Release"
+# Name "vio - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\vio.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\viosocket.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\viossl.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\viosslfactories.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/winmysqladmin/db.cpp b/VC++Files/winmysqladmin/db.cpp
new file mode 100644
index 00000000000..6e796856a7e
--- /dev/null
+++ b/VC++Files/winmysqladmin/db.cpp
@@ -0,0 +1,80 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "db.h"
+#include "main.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+Tdbfrm *dbfrm;
+//---------------------------------------------------------------------------
+__fastcall Tdbfrm::Tdbfrm(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall Tdbfrm::SpeedButton2Click(TObject *Sender)
+{
+ Close();
+}
+//---------------------------------------------------------------------------
+void __fastcall Tdbfrm::SpeedButton1Click(TObject *Sender)
+{
+ if (VerDBName())
+ {
+ if (!Form1->CreatingDB())
+ {
+ Form1->OutRefresh();
+ Edit1->Text = "";
+ Application->MessageBox("The database was created", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ }
+ }
+
+
+
+
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall Tdbfrm::VerDBName()
+{
+ String temp = Edit1->Text;
+ if (Edit1->Text.IsEmpty())
+ {
+ Application->MessageBox("The name of the Database is Empty", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+
+ if (temp.Length() > 64)
+ {
+ Application->MessageBox("The name of the Database can't have more than 64 characters ", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+
+ for (int j = 1; j <= temp.Length(); j++)
+ {
+ if (temp[j] == ' ')
+ {
+ Application->MessageBox("The name of the Database can't have blank spaces ", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ else if (temp[j] == '/')
+ {
+ Application->MessageBox("The name of the Database can't have frontslash (/)", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ else if (temp[j] == '\\')
+ {
+ Application->MessageBox("The name of the Database can't have backslash (\\)", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ else if (temp[j] == '.')
+ {
+ Application->MessageBox("The name of the Database can't have periods", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ }
+ return true;
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/winmysqladmin/db.h b/VC++Files/winmysqladmin/db.h
new file mode 100644
index 00000000000..f7ab87351ea
--- /dev/null
+++ b/VC++Files/winmysqladmin/db.h
@@ -0,0 +1,32 @@
+//---------------------------------------------------------------------------
+#ifndef dbH
+#define dbH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <ExtCtrls.hpp>
+#include <Graphics.hpp>
+#include <Buttons.hpp>
+//---------------------------------------------------------------------------
+class Tdbfrm : public TForm
+{
+__published: // IDE-managed Components
+ TImage *Image1;
+ TLabel *Label1;
+ TLabel *Label2;
+ TEdit *Edit1;
+ TSpeedButton *SpeedButton1;
+ TSpeedButton *SpeedButton2;
+ void __fastcall SpeedButton2Click(TObject *Sender);
+ void __fastcall SpeedButton1Click(TObject *Sender);
+private: // User declarations
+ bool __fastcall VerDBName();
+public: // User declarations
+ __fastcall Tdbfrm(TComponent* Owner);
+};
+//---------------------------------------------------------------------------
+extern PACKAGE Tdbfrm *dbfrm;
+//---------------------------------------------------------------------------
+#endif
diff --git a/VC++Files/winmysqladmin/images/Goahead.ico b/VC++Files/winmysqladmin/images/Goahead.ico
new file mode 100644
index 00000000000..8241c90e2a2
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Goahead.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/HELP.ICO b/VC++Files/winmysqladmin/images/HELP.ICO
new file mode 100644
index 00000000000..d0cd6d68cce
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/HELP.ICO
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/INFO.ICO b/VC++Files/winmysqladmin/images/INFO.ICO
new file mode 100644
index 00000000000..e3afa8cf52c
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/INFO.ICO
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Info.bmp b/VC++Files/winmysqladmin/images/Info.bmp
new file mode 100644
index 00000000000..58f729fb1fd
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Info.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/MYINI.ICO b/VC++Files/winmysqladmin/images/MYINI.ICO
new file mode 100644
index 00000000000..428ed8e92b0
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/MYINI.ICO
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Myini.bmp b/VC++Files/winmysqladmin/images/Myini.bmp
new file mode 100644
index 00000000000..e743a1b9b32
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Myini.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Noentry.ico b/VC++Files/winmysqladmin/images/Noentry.ico
new file mode 100644
index 00000000000..27f2211f56c
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Noentry.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/SETUP.BMP b/VC++Files/winmysqladmin/images/SETUP.BMP
new file mode 100644
index 00000000000..c5794e5ac00
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/SETUP.BMP
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Setup 16.bmp b/VC++Files/winmysqladmin/images/Setup 16.bmp
new file mode 100644
index 00000000000..e17b06155fb
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Setup 16.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Table.ico b/VC++Files/winmysqladmin/images/Table.ico
new file mode 100644
index 00000000000..4469a915b7f
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Table.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Working.ico b/VC++Files/winmysqladmin/images/Working.ico
new file mode 100644
index 00000000000..72faedbbfc5
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Working.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/database.ico b/VC++Files/winmysqladmin/images/database.ico
new file mode 100644
index 00000000000..9689aa88361
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/database.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/find.ico b/VC++Files/winmysqladmin/images/find.ico
new file mode 100644
index 00000000000..2e0f96c52f9
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/find.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/green.ico b/VC++Files/winmysqladmin/images/green.ico
new file mode 100644
index 00000000000..ef53cd87994
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/green.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/help.bmp b/VC++Files/winmysqladmin/images/help.bmp
new file mode 100644
index 00000000000..76c6a90d2d8
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/help.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/initsetup.cpp b/VC++Files/winmysqladmin/images/initsetup.cpp
new file mode 100644
index 00000000000..d0dd15b059c
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/initsetup.cpp
@@ -0,0 +1,42 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "initsetup.h"
+#include "main.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TForm2 *Form2;
+//---------------------------------------------------------------------------
+__fastcall TForm2::TForm2(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn1Click(TObject *Sender)
+{
+if ((Edit1->Text).IsEmpty() || (Edit2->Text).IsEmpty())
+ Application->MessageBox("Fill the User name and Password text boxs ", "Winmysqladmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ {
+ if(Form1->ForceConnection())
+ if(Form1->ForceMySQLInit())
+ {
+ Form1->CreateMyIniFile();
+ Form1->CreatingShortCut();
+ }
+ Close();
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn2Click(TObject *Sender)
+{
+ Close();
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::SpeedButton1Click(TObject *Sender)
+{
+ Application->HelpCommand(HELP_FINDER,0);
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/winmysqladmin/images/killdb.ico b/VC++Files/winmysqladmin/images/killdb.ico
new file mode 100644
index 00000000000..9689aa88361
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/killdb.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/logo.ico b/VC++Files/winmysqladmin/images/logo.ico
new file mode 100644
index 00000000000..9409cad72b6
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/logo.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/multitrg.ico b/VC++Files/winmysqladmin/images/multitrg.ico
new file mode 100644
index 00000000000..76ffbe29c77
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/multitrg.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/mysql-07.bmp b/VC++Files/winmysqladmin/images/mysql-07.bmp
new file mode 100644
index 00000000000..dcae23b8813
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/mysql-07.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/mysql-17.bmp b/VC++Files/winmysqladmin/images/mysql-17.bmp
new file mode 100644
index 00000000000..0291c804006
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/mysql-17.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/mysql.BMP b/VC++Files/winmysqladmin/images/mysql.BMP
new file mode 100644
index 00000000000..ed5c7f9051f
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/mysql.BMP
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/red.ico b/VC++Files/winmysqladmin/images/red.ico
new file mode 100644
index 00000000000..b28288d576e
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/red.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/red22.BMP b/VC++Files/winmysqladmin/images/red22.BMP
new file mode 100644
index 00000000000..a35052afa01
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/red22.BMP
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/see.bmp b/VC++Files/winmysqladmin/images/see.bmp
new file mode 100644
index 00000000000..72fb2c50ec6
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/see.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/initsetup.cpp b/VC++Files/winmysqladmin/initsetup.cpp
new file mode 100644
index 00000000000..0a25b8cb79c
--- /dev/null
+++ b/VC++Files/winmysqladmin/initsetup.cpp
@@ -0,0 +1,40 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "initsetup.h"
+#include "main.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TForm2 *Form2;
+//---------------------------------------------------------------------------
+__fastcall TForm2::TForm2(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn1Click(TObject *Sender)
+{
+ if ((Edit1->Text).IsEmpty() || (Edit2->Text).IsEmpty())
+ Application->MessageBox("Fill the User name and Password text boxs ", "Winmysqladmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ {
+ Form1->GetServerFile();
+ Form1->CreateMyIniFile();
+ Form1->CreatingShortCut();
+
+ Close();
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn2Click(TObject *Sender)
+{
+ Close();
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::SpeedButton1Click(TObject *Sender)
+{
+ Application->HelpCommand(HELP_FINDER,0);
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/winmysqladmin/initsetup.h b/VC++Files/winmysqladmin/initsetup.h
new file mode 100644
index 00000000000..28f575198e3
--- /dev/null
+++ b/VC++Files/winmysqladmin/initsetup.h
@@ -0,0 +1,38 @@
+//---------------------------------------------------------------------------
+#ifndef initsetupH
+#define initsetupH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <Buttons.hpp>
+#include <ExtCtrls.hpp>
+#include <Graphics.hpp>
+//---------------------------------------------------------------------------
+class TForm2 : public TForm
+{
+__published: // IDE-managed Components
+ TImage *Image1;
+ TLabel *Label1;
+ TLabel *Label4;
+ TPanel *Panel1;
+ TLabel *Label5;
+ TLabel *Label6;
+ TLabel *Label2;
+ TEdit *Edit1;
+ TEdit *Edit2;
+ TBitBtn *BitBtn1;
+ TSpeedButton *SpeedButton1;
+ TBitBtn *BitBtn2;
+ void __fastcall BitBtn1Click(TObject *Sender);
+ void __fastcall BitBtn2Click(TObject *Sender);
+ void __fastcall SpeedButton1Click(TObject *Sender);
+private: // User declarations
+public: // User declarations
+ __fastcall TForm2(TComponent* Owner);
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TForm2 *Form2;
+//---------------------------------------------------------------------------
+#endif
diff --git a/VC++Files/winmysqladmin/main.cpp b/VC++Files/winmysqladmin/main.cpp
new file mode 100644
index 00000000000..6ca29659255
--- /dev/null
+++ b/VC++Files/winmysqladmin/main.cpp
@@ -0,0 +1,2529 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "main.h"
+#include "initsetup.h"
+#include "db.h"
+
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+#include <shellapi.h>
+#include <registry.hpp>
+#include <winsvc.h>
+#include <winsock.h>
+#include <shlobj.h>
+#include <IniFiles.hpp>
+#include <dir.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <deque.h>
+#include <vector.h>
+#include <fstream.h>
+#include <iostream.h>
+#include <iterator.h>
+#include <sstream.h>
+#include "mysql.h"
+#include <Printers.hpp>
+
+TForm1 *Form1;
+bool i_start, NT;
+bool IsForce = false;
+bool IsVariables = false;
+bool IsProcess = false ;
+bool IsDatabases = false;
+bool new_line = 0;
+bool ya = true;
+bool yy = true;
+bool rinit = false;
+AnsiString vpath;
+AnsiString vip;
+MYSQL_RES *res_1;
+static unsigned long q = 0;
+bool preport = false;
+bool treport = false;
+bool ereport = false;
+AnsiString mainroot;
+bool IsMySQLNode = false;
+MYSQL *MySQL;
+//---------------------------------------------------------------------------
+__fastcall TForm1::TForm1(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FormCreate(TObject *Sender)
+{
+ i_start = true;
+ IsConnect = false;
+ if (ParamCount() > 0){
+ if (ParamStr(1) == "-h" || ParamStr(1) == "h" ) {
+ ShowHelp(); Application->Terminate(); }
+ else if (ParamStr(1) == "-w" || ParamStr(1) == "w") {
+ i_start = false; ContinueLoad(); }
+ }
+ else {
+ ContinueLoad(); Hide(); GetServerOptions(); }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::DrawItem(TMessage& Msg)
+{
+ IconDrawItem((LPDRAWITEMSTRUCT)Msg.LParam);
+ TForm::Dispatch(&Msg);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::MyNotify(TMessage& Msg)
+{
+ POINT MousePos;
+
+ switch(Msg.LParam) {
+ case WM_RBUTTONUP:
+ if (GetCursorPos(&MousePos)){
+ PopupMenu1->PopupComponent = Form1; SetForegroundWindow(Handle);
+ PopupMenu1->Popup(MousePos.x, MousePos.y);}
+ else Show();
+ break;
+ case WM_LBUTTONUP:
+ if (GetCursorPos(&MousePos)){
+ PopupMenu1->PopupComponent = Form1; SetForegroundWindow(Handle);
+ PopupMenu1->Popup(MousePos.x, MousePos.y); }
+
+ ToggleState();
+ break;
+ default:
+ break; }
+
+ TForm::Dispatch(&Msg);
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TrayMessage(DWORD dwMessage)
+{
+ NOTIFYICONDATA tnd;
+ PSTR pszTip;
+
+ pszTip = TipText();
+
+ tnd.cbSize = sizeof(NOTIFYICONDATA);
+ tnd.hWnd = Handle;
+ tnd.uID = IDC_MYICON;
+ tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+ tnd.uCallbackMessage = MYWM_NOTIFY;
+
+ if (dwMessage == NIM_MODIFY){
+ tnd.hIcon = IconHandle();
+ if (pszTip)lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
+ else tnd.szTip[0] = '\0'; }
+ else { tnd.hIcon = NULL; tnd.szTip[0] = '\0'; }
+
+ return (Shell_NotifyIcon(dwMessage, &tnd));
+}
+//---------------------------------------------------------------------------
+HANDLE __fastcall TForm1::IconHandle(void)
+{
+
+ if (!NT){
+ if (MySQLSignal()){Image3->Visible = false; Image2->Visible = true;
+ return (Image2->Picture->Icon->Handle); }
+ else {Image2->Visible = false; Image3->Visible = true;
+ return (Image3->Picture->Icon->Handle); }
+ }
+ else {
+ if (TheServiceStatus()){Image3->Visible = false; Image2->Visible = true;
+ return (Image2->Picture->Icon->Handle); }
+
+ else if (MySQLSignal()){Image3->Visible = false; Image2->Visible = true;
+ return (Image2->Picture->Icon->Handle); }
+ else {Image2->Visible = false; Image3->Visible = true;
+ return (Image3->Picture->Icon->Handle); }
+ }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ToggleState(void)
+{
+
+ TrayMessage(NIM_MODIFY);
+ if (!NT){
+ if (MySQLSignal()){SSW9->Caption = "ShutDown the Server";
+ Image3->Visible = false; Image2->Visible = true; }
+ else {SSW9->Caption = "Start the Server";
+ Image2->Visible = false; Image3->Visible = true; }
+ }
+ else {
+ if (TheServiceStart()) {
+ Standa->Enabled = false;
+ if (TheServiceStatus()) {RService->Enabled = false;
+ StopS->Enabled = true;
+ StopS->Caption = "Stop the Service";
+ Image3->Visible = false;
+ Image2->Visible = true; }
+ else {RService->Enabled = true;
+ StopS->Enabled = true;
+ RService->Caption = "Remove the Service";
+ StopS->Caption = "Start the Service";
+ Image2->Visible = false;
+ Image3->Visible = true; }
+ }
+ else {
+ Standa->Enabled = true;
+ StopS->Enabled = false;
+ if (MySQLSignal()) {
+ RService->Enabled = false;
+ Standa->Caption = "ShutDown the Server Standalone";
+ Image3->Visible = false;
+ Image2->Visible = true; }
+
+ else {
+ RService->Enabled = true;
+ RService->Caption = "Install the Service";
+ Standa->Caption = "Start the Server Standalone";
+ Image2->Visible = false;
+ Image3->Visible = true; }
+
+ }
+
+
+ }
+
+}
+//---------------------------------------------------------------------------
+PSTR __fastcall TForm1::TipText(void)
+{
+ char* status = StatusLine->SimpleText.c_str();
+ return status;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::WMQueryEndSession(TWMQueryEndSession &msg)
+{
+
+
+ if (!NT) {
+
+ if (MySQLSignal()){
+ StatusLine->SimpleText = "Shutdown in progress.....";
+ Show(); Shutd(); msg.Result = 1; }
+ else {
+ StatusLine->SimpleText = "The Server already is down......";
+ Show(); msg.Result = 1; Close(); }
+ }
+ else {
+
+ Show();
+ if (!TheServiceStart()) { if (MySQLSignal()) Shutd(); }
+ msg.Result = 1;
+ }
+
+}
+
+//---------------------------------------------------------------------------
+LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi)
+{
+ HICON hIcon;
+
+ hIcon = (HICON)LoadImage(g_hinst, MAKEINTRESOURCE(lpdi->CtlID), IMAGE_ICON,
+ 16, 16, 0);
+ if (!hIcon)
+ return(false);
+
+ DrawIconEx(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top, hIcon,
+ 16, 16, 0, NULL, DI_NORMAL);
+
+ return(true);
+}
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheComputer()
+{
+ AnsiString theword;
+ DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
+ char szBuf[MAX_COMPUTERNAME_LENGTH + 1];
+ szBuf[0] = '\0';
+
+ GetComputerName(szBuf, &dwSize);
+ theword = (AnsiString) szBuf;
+ delete [] szBuf;
+ return theword;
+
+}
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheOS()
+{
+ AnsiString theword;
+ OSVERSIONINFO info;
+ info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&info);
+
+ switch (info.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32s:
+ NT = false;
+ theword = "Win32s detected";
+ break;
+ case VER_PLATFORM_WIN32_WINDOWS:
+ NT = false;
+ theword = "Win 95 or Win 98 detected";
+ break;
+ case VER_PLATFORM_WIN32_NT:
+ NT = true;
+ theword = "Windows NT detected";
+ break;
+ }
+ return theword;
+}
+///---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheUser()
+{
+ AnsiString theword;
+ DWORD dwSize = 0;
+
+ GetUserName(NULL, &dwSize);
+
+ char *szBuf = new char[dwSize];
+ szBuf[0] = '\0';
+
+ GetUserName(szBuf, &dwSize);
+ theword = (AnsiString) szBuf;
+ delete [] szBuf;
+ return theword;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::TakeIP(void)
+{
+ WORD wVersionRequested;
+ WSADATA WSAData;
+ wVersionRequested = MAKEWORD(1,1);
+ WSAStartup(wVersionRequested,&WSAData);
+
+ hostent *P;
+ char s[128];
+ in_addr in;
+ char *P2;
+ gethostname(s, 128);
+ P = gethostbyname(s);
+
+ Memo2->Lines->Clear();
+ Memo2->Lines->Add((AnsiString)P->h_name);
+ mainroot = P->h_name;
+ in.S_un.S_un_b.s_b1 = P->h_addr_list[0][0];
+ in.S_un.S_un_b.s_b2 = P->h_addr_list[0][1];
+ in.S_un.S_un_b.s_b3 = P->h_addr_list[0][2];
+ in.S_un.S_un_b.s_b4 = P->h_addr_list[0][3];
+ P2 = inet_ntoa(in);
+ vip = P2;
+ mainroot += " ( " + (AnsiString)P2 + " )";
+ Memo2->Lines->Add(P2);
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetmemStatus(void)
+{
+ MEMORYSTATUS ms;
+ ms.dwLength = sizeof(MEMORYSTATUS);
+ GlobalMemoryStatus(&ms);
+
+ Edit2->Text = AnsiString((double)ms.dwTotalPhys / 1024000.0) + " MB RAM";
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ShowHelp(void)
+{
+ Application->MessageBox("Usage: WinMySQLadmin.EXE [OPTIONS]\n\n-w Run the tool without start the Server.\n-h Shows this message and exit ", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ContinueLoad(void)
+{
+ OS->Text = TheOS();
+ Localhost->Text = TheComputer();
+ Localuser->Text = TheUser();
+ GetmemStatus();
+ ClearBox();
+ TakeIP();
+ MyODBC();
+
+
+ IsMyIniUp();
+
+ if (!NT) { WinNT->Enabled = false; NtVer->Enabled = false; Win9->Enabled = true; }
+ else { WinNT->Enabled = true; Win9->Enabled = false; }
+
+ if (i_start)
+ {
+ // NT never is started from the prompt
+ if ((!NT) && (!MySQLSignal())) mysqldstart();
+ {
+ TrayMessage(NIM_MODIFY);
+ SeekErrFile();
+ }
+ }
+ Hide();
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::MyODBC(void)
+{
+
+ TRegistry *Registry = new TRegistry();
+ Memo3->Lines->Clear();
+
+ try
+ {
+ Registry->RootKey = HKEY_LOCAL_MACHINE;
+ // the basic data of myodbc
+ if (Registry->OpenKey("Software\\ODBC\\ODBCINST.INI\\MySQL", false))
+ {
+ Memo3->Lines->Add("Driver Version\t" + Registry->ReadString("DriverODBCVer"));
+ Memo3->Lines->Add("Driver\t\t" + Registry->ReadString("Driver"));
+ Memo3->Lines->Add("API Level\t\t" + Registry->ReadString("APILevel"));
+ Memo3->Lines->Add("Setup\t\t" + Registry->ReadString("Setup"));
+ Memo3->Lines->Add("SQL Level\t" + Registry->ReadString("SQLLevel"));
+ }
+ else
+ Memo3->Lines->Add("Not Found");
+
+ }
+ catch (...)
+ {
+ delete Registry;
+ }
+ Memo3->Enabled = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::IsMyIniUp(void)
+{
+ // we see if the my.ini is Up
+ AnsiString asFileName = FileSearch("my.ini", TheWinDir());
+ if (asFileName.IsEmpty())
+ {
+ IsForce = true;
+ i_start = false;
+ QuickSearch();
+ }
+ else
+ {
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ FillMyIni();
+ GetBaseDir();
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::QuickSearch(void)
+{
+ AnsiString asFileName = FileSearch("mysql.exe", "c:/mysql/bin");
+ if (!asFileName.IsEmpty())
+ BaseDir->Text = "c:/mysql";
+}
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheWinDir()
+{
+ AnsiString WinDir;
+ UINT BufferSize = GetWindowsDirectory(NULL,0);
+ WinDir.SetLength(BufferSize+1);
+ GetWindowsDirectory(WinDir.c_str(),BufferSize);
+ char* dirw = WinDir.c_str();
+ return dirw ;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FillMyIni(void)
+{
+ Memo1->Lines->LoadFromFile(TheWinDir() + "\\my.ini");
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetBaseDir(void)
+{
+
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+ char file[_MAX_FNAME];
+ char ext[_MAX_EXT];
+
+
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ BaseDir->Text = pIniFile->ReadString("mysqld","basedir","") ;
+ AnsiString lx = pIniFile->ReadString("WinMySQLadmin","Server","") ;
+ _splitpath((lx).c_str(),drive,dir,file,ext);
+ AnsiString lw = (AnsiString) file + ext;
+
+ if ( lw == "mysqld-shareware.exe") {ShareVer->Checked = true;}
+ if ( lw == "mysqld.exe") {MysqldVer->Checked = true;}
+ if ( lw == "mysqld-opt.exe") {OptVer->Checked = true;}
+ if ( lw == "mysqld-nt.exe") {NtVer->Checked = true;}
+
+ delete pIniFile;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::Showme1Click(TObject *Sender)
+{
+ if(Showme1->Caption == "Show me") { TrayMessage(NIM_DELETE);
+ Showme1->Caption = "Hide me"; Show(); }
+ else { TrayMessage(NIM_ADD); TrayMessage(NIM_MODIFY);
+ Showme1->Caption = "Show me"; Hide(); }
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::MySQLSignal()
+{
+ HANDLE hEventShutdown;
+ hEventShutdown=OpenEvent(EVENT_MODIFY_STATE, 0, "MySqlShutdown");
+
+ if(hEventShutdown)
+ {
+ CloseHandle(hEventShutdown);
+ return true;
+ }
+ else
+ {
+ CloseHandle(hEventShutdown);
+ return false;
+ }
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::mysqldstart()
+{
+ memset(&pi, 0, sizeof(pi));
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.dwFlags |= STARTF_USESHOWWINDOW;
+ si.wShowWindow |= SW_SHOWNORMAL;
+
+
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ if (NT)
+ vpath = pIniFile->ReadString("WinMySQLadmin","Server","") + " --standalone\0" ;
+ else
+ vpath = pIniFile->ReadString("WinMySQLadmin","Server","") + "\0" ;
+
+ if ( ! CreateProcess(0,vpath.c_str(), 0, 0, 0, 0, 0, 0, &si,&pi))
+ {
+ TrayMessage(NIM_MODIFY);
+ return false;
+ }
+ else
+ {
+ TrayMessage(NIM_MODIFY);
+ return true;
+
+ }
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::SeekErrFile()
+{
+ Memo4->Enabled = true;
+ Memo4->Lines->Clear();
+ AnsiString asFileName = FileSearch("mysql.err", BaseDir->Text + "/data");
+ if (!asFileName.IsEmpty())
+ {
+ FName = BaseDir->Text + "/data/mysql.err";
+ ifstream in((FName).c_str());
+ in.seekg(0, ios::end);
+ string s, line;
+ deque<string> v;
+ deque<string> lines;
+ streampos sp = in.tellg();
+ if (sp <= 1000)
+ in.seekg(0, ios::beg);
+ else
+ {
+ in.seekg(0, ios::beg);
+ in.seekg((sp - 1000));
+ }
+
+ do {
+ lines.push_back(line);
+ }while (getline(in, line));
+
+
+ if( lines.size() <= 15)
+ {
+ deque<string>::reverse_iterator r;
+ for(r = lines.rbegin(); r != lines.rend() ; r++)
+ {
+ if (ereport)
+ Memo5->Lines->Add((*r).c_str());
+ Memo4->Lines->Add((*r).c_str());
+
+ }
+ }
+ else
+ {
+ int k = 0;
+ deque<string>::reverse_iterator r;
+ for(r = lines.rbegin(); r != lines.rend(); r++)
+ {
+ if (ereport)
+ Memo5->Lines->Add((*r).c_str());
+ Memo4->Lines->Add((*r).c_str());
+ if (++k >= 15) { break;}
+ }
+ }
+ in.close();
+ return true;
+ }
+ else
+ return false;
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::Timer1Timer(TObject *Sender)
+{
+ Showme1->Caption = "Show me";
+ TrayMessage(NIM_ADD);
+ TrayMessage(NIM_MODIFY);
+ Hide();
+ if (IsForce) {Form2->Show();}
+ Timer1->Enabled = false;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetServerFile()
+{
+
+ AnsiString FileName;
+
+ if(!NT) {
+ FileName = FileSearch("mysqld-opt.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld-shareware.exe", ExtractFilePath(Application->ExeName));
+
+ if (!FileName.IsEmpty()){
+ if ( FileName == "mysqld-opt.exe") {OptVer->Checked = true;}
+ if ( FileName == "mysqld.exe") {MysqldVer->Checked= true;}
+ if ( FileName == "mysqld-shareware.exe") {ShareVer->Checked= true;} }
+
+ }
+ else {
+
+ FileName = FileSearch("mysqld-nt.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld-shareware.exe", ExtractFilePath(Application->ExeName));
+
+ if (!FileName.IsEmpty()) {
+ if ( FileName == "mysqld-nt.exe") {NtVer->Checked = true;}
+ if ( FileName == "mysqld.exe") {MysqldVer->Checked= true;}
+ if ( FileName == "mysqld-shareware.exe") {ShareVer->Checked= true;} }
+
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CreateMyIniFile(void)
+{
+ char szFileName[6];
+ int iFileHandle;
+ AnsiString jk;
+
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ strcpy(szFileName,"\\my.ini");
+ iFileHandle = FileCreate(TheWinDir() + szFileName );
+
+ jk = "#This File was made using the WinMySQLadmin 1.0 Tool\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#" + Now() + "\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#Uncomment or Add only the keys that you know how works.\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#Read the MySQL Manual for instructions\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+
+ jk = "[mysqld]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "basedir=" + TheDir() + "\n";
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#bind-address=" + vip + "\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#datadir=" + TheDir() + "/data\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#language=" + TheDir() + "/share/your language directory\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#delay-key-write-for-all-tables\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#log-long-format\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#slow query log=#\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#tmpdir=#\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#ansi\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#new\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#port=3306\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#safe\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-name-resolve\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-networking\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-new\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-host-cache\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = key_buffer=16M\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = max_allowed_packet=1M\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = thread_stack=128K\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = flush_time=1800\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[mysqldump]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#quick\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = max_allowed_packet=16M\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[mysql]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#no-auto-rehash\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[isamchk]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable= key=16M\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[WinMySQLadmin]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+
+ if (ShareVer->Checked) { jk = "Server=" + TheDir() + "/bin/mysqld-shareware.exe\n\n";}
+ if (MysqldVer->Checked) {jk = "Server=" + TheDir() + "/bin/mysqld.exe\n\n";}
+ if (OptVer->Checked) {jk = "Server=" + TheDir() + "/bin/mysqld-opt.exe\n\n";}
+ if (NtVer->Checked) {jk = "Server=" + TheDir() + "/bin/mysqld-nt.exe\n\n";}
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "user=" + Form2->Edit1->Text + "\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "password=" + Form2->Edit2->Text + "\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ FileClose(iFileHandle);
+ FillMyIni();
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::CreatingShortCut()
+{
+ // Where is The Start Menu in this Machine ?
+ LPITEMIDLIST pidl;
+ LPMALLOC pShellMalloc;
+ char szDir[MAX_PATH + 16];
+ AnsiString file;
+ AnsiString jk = "\\WinMySQLadmin.lnk" ;
+
+ if(SUCCEEDED(SHGetMalloc(&pShellMalloc)))
+ {
+ if(SUCCEEDED(SHGetSpecialFolderLocation(NULL,
+ CSIDL_STARTUP, &pidl)))
+ {
+ if(!SHGetPathFromIDList(pidl, szDir))
+ {
+ pShellMalloc->Release();
+ pShellMalloc->Free(pidl);
+ return false;
+ }
+
+ pShellMalloc->Free(pidl);
+ }
+
+ pShellMalloc->Release();
+ StrCat(szDir, jk.c_str());
+ }
+
+ // the create
+
+ IShellLink* pLink;
+ IPersistFile* pPersistFile;
+
+ if(SUCCEEDED(CoInitialize(NULL)))
+ {
+ if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IShellLink, (void **) &pLink)))
+ {
+
+ pLink->SetPath((ExtractFilePath(Application->ExeName) + "WinMySQLadmin.exe").c_str());
+ pLink->SetDescription("WinMySQLadmin Tool");
+ pLink->SetShowCmd(SW_SHOW);
+
+ if(SUCCEEDED(pLink->QueryInterface(IID_IPersistFile,
+ (void **)&pPersistFile)))
+ {
+
+ WideString strShortCutLocation(szDir);
+ pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE);
+ pPersistFile->Release();
+ }
+ pLink->Release();
+ }
+
+ CoUninitialize();
+ }
+
+
+ return true;
+}
+
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheDir()
+{
+ AnsiString buffer;
+ char s[_MAX_PATH + 1];
+
+ StrCopy(s, ( BaseDir->Text).c_str()) ;
+
+ for (int i = 0; s[i] != NULL; i++)
+ if (s[i] != '\\')
+ buffer += s[i];
+ else
+ buffer += "/";
+
+ return buffer;
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
+{
+ Application->HelpCommand(HELP_FINDER,0);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Timer2Timer(TObject *Sender)
+{
+ ToggleState();
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceStart()
+{
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS | GENERIC_WRITE);
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ thatok = true;
+ else
+ thatok = false;
+ }
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServicePause()
+{
+
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ // stop the service
+ if (IsConnect)
+ {
+ mysql_kill(MySQL,mysql_thread_id(MySQL));
+ StatusLine->SimpleText = "";
+ q = 0;
+ }
+
+
+ SERVICE_STATUS ss;
+ thatok = ControlService(myService,
+ SERVICE_CONTROL_STOP,
+ &ss);
+
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceResume()
+{
+
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ // start the service
+
+ thatok = StartService(myService, 0, NULL);
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceStatus()
+{
+ bool thatok;
+ bool k;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ SERVICE_STATUS ss;
+ DWORD dwState = 0xFFFFFFFF;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ memset(&ss, 0, sizeof(ss));
+ k = QueryServiceStatus(myService,&ss);
+ if (k)
+ {
+ dwState = ss.dwCurrentState;
+ if (dwState == SERVICE_RUNNING)
+ thatok = true;
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceCreate()
+
+{
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ char *szFullPath = vpath.c_str();
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ { myService = CreateService(
+ scm,
+ SERVICE_NAME,
+ SERVICE_NAME,
+ SERVICE_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS,
+ SERVICE_AUTO_START ,
+ SERVICE_ERROR_NORMAL,
+ szFullPath,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ if (myService)
+ thatok = true;
+ else
+ thatok = false;
+
+ }
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Swin9Click(TObject *Sender)
+{
+ if(Application->MessageBox("Shutdown this tool", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ Close();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SSW9Click(TObject *Sender)
+{
+ if (MySQLSignal())
+ {
+ if(Application->MessageBox("Shutdown the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+
+ if (Shutd())
+ {
+ IsConnect = false;
+ IsVariables = false;
+ IsProcess = false;
+ IsDatabases = false;
+ ya = false;
+ ClearBox();
+ Sleep(500);
+ TrayMessage(NIM_MODIFY);
+
+ }
+ else
+ Application->MessageBox("Fails to Shutdown the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Start the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (mysqldstart())
+ {
+ TrayMessage(NIM_MODIFY);
+ ya = true;
+ }
+ else
+ Application->MessageBox("Fails to Start the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::ShutDownBoth1Click(TObject *Sender)
+{
+ if (MySQLSignal())
+ {
+ if(Application->MessageBox("Shutdown the MySQL Server and this tool ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+
+ if (Shutd())
+ Close();
+ else
+ {
+ Application->MessageBox("Fails to Shutdown the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+
+ }
+ }
+ }
+ else
+ if(Application->MessageBox("Shutdown this tool ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ Close();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::ShutDownthisTool1Click(TObject *Sender)
+{
+ if(Application->MessageBox("Shutdown this tool ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ Close();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::StopSClick(TObject *Sender)
+{
+ AnsiString theWarning;
+ theWarning = "Are you sure to stop the Service ?\n\nAll the connections will be loss !" ;
+ if (TheServiceStatus())
+ {
+ if(Application->MessageBox(theWarning.c_str(), "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (TheServicePause())
+ {
+ TrayMessage(NIM_MODIFY);
+ IsConnect = false;
+ IsVariables = false;
+ IsProcess = false;
+ IsDatabases = false;
+ ya = false;
+ ClearBox();
+
+ }
+ else
+ Application->MessageBox("Fails to stop the Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Start the Service Manager for the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (TheServiceResume())
+ {
+ ya = true;
+ TrayMessage(NIM_MODIFY);
+ }
+ else
+ Application->MessageBox("Fails to start the Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::RServiceClick(TObject *Sender)
+{
+ if (TheServiceStart())
+ {
+ if(Application->MessageBox("Remove the MySQL Server service ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (!TheServiceRemove())
+ Application->MessageBox("Fails to Remove The MySQL Server Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Install the MySQL Server service ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (!TheServerPath())
+ Application->MessageBox("Please create first the my.ini setup", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else
+ {
+ if (!TheServiceCreate())
+ Application->MessageBox("Fails to Install The MySQL Server Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::StandaClick(TObject *Sender)
+{
+ if (MySQLSignal())
+ {
+ if(Application->MessageBox("Shutdown the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (Shutd())
+ {
+ IsConnect = false;
+ IsVariables = false;
+ IsProcess = false;
+ IsDatabases = false;
+ ya = false;
+ ClearBox();
+ Sleep(500);
+ TrayMessage(NIM_MODIFY);
+
+ }
+ else
+ Application->MessageBox("Fails to Shutdown the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Start the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (mysqldstart())
+ {
+ StatusLine->SimpleText = "";
+ TrayMessage(NIM_MODIFY);
+
+ }
+ else
+ Application->MessageBox("Fails to Start the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::Shutd()
+{
+ // from Irena
+ HANDLE hEventShutdown;
+ hEventShutdown=OpenEvent(EVENT_MODIFY_STATE, 0, "MySqlShutdown");
+
+ if (IsConnect)
+ {
+ mysql_kill(MySQL,mysql_thread_id(MySQL));
+ mysql_shutdown(MySQL);
+ StatusLine->SimpleText = "";
+
+ }
+
+ q = 0;
+
+
+ if(hEventShutdown)
+ {
+ SetEvent(hEventShutdown);
+ CloseHandle(hEventShutdown);
+ TrayMessage(NIM_MODIFY);
+ IsConnect = false;
+ return true;
+ }
+ else
+ {
+ TrayMessage(NIM_MODIFY);
+ return false;
+ }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ClearBox(void)
+{
+
+ st22->Text = "";
+ st23->Text = "";
+ st24->Text = "";
+ st25->Text = "";
+ st26->Text = "";
+ st27->Text = "";
+ st28->Text = "";
+ st29->Text = "";
+ Edit3->Text = "";
+ Edit4->Text = "";
+ Edit5->Text = "";
+ Edit6->Text = "";
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceRemove()
+{
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ if(DeleteService(myService))
+ {
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ thatok = true;
+ }
+ else
+ {
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ thatok = false;
+ }
+
+ }
+ else
+ {
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ thatok = false;
+ }
+ }
+ else
+ {
+ thatok = false;
+ CloseServiceHandle(scm);
+ }
+
+ return thatok;
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServerPath()
+{
+
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ vpath = pIniFile->ReadString("WinMySQLadmin","Server","") ;
+ delete pIniFile;
+ if (vpath.IsEmpty())
+ return false;
+ else
+ return true;
+
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button5Click(TObject *Sender)
+{
+ if (!SeekErrFile())
+ Application->MessageBox("Fails to find mysql.err", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::IsMySQLInit(void)
+{
+ AnsiString theCommand;
+ char *host = NULL,*password=0,*user=0 ;
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ AnsiString MyUser = pIniFile->ReadString("WinMySQLadmin","user","") ;
+ AnsiString MyPass = pIniFile->ReadString("WinMySQLadmin","password","") ;
+
+ delete pIniFile;
+
+
+ if (!MyUser.IsEmpty() && MyUser.Length() && !MyPass.IsEmpty() && MyPass.Length())
+ {
+ if (!IsConnect)
+ {
+
+ MySQL = mysql_init(MySQL);
+ if (mysql_real_connect(MySQL, "localhost",(MyUser).c_str(), (MyPass).c_str() , 0, 0, NULL, 0))
+ IsConnect = true;
+ else
+ {
+ if(mysql_real_connect(MySQL,host,user,password , 0, 0, NULL, 0))
+ {
+ IsConnect = true;
+ theCommand = "GRANT ALL PRIVILEGES ON *.* TO ";
+ theCommand += "'" + MyUser + "' @localhost IDENTIFIED BY ";
+ theCommand += "'" + MyPass + "' with GRANT OPTION";
+ char* los = theCommand.c_str();
+ if(!mysql_query(MySQL, los ))
+ StatusLine->SimpleText = " ";
+ }
+
+ }
+
+ }
+
+ }
+ else
+ {
+ if (!IsConnect)
+ {
+ MySQL = mysql_init(MySQL);
+ if(mysql_real_connect(MySQL,host,user,password , 0, 0, NULL, 0))
+ IsConnect = true;
+ }
+ }
+}
+
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Timer3Timer(TObject *Sender)
+{
+ if ((NT) && TheServiceStatus()) {IsMySQLInit(); }
+
+ if ((NT) && !TheServiceStatus() && MySQLSignal()) {IsMySQLInit(); }
+
+ if (!(NT) && MySQLSignal()) {IsMySQLInit(); }
+
+ if (IsConnect)
+ {
+ GetServerStatus();
+ if (!IsMySQLNode)
+ GetMainRoot();
+ Extended->Enabled = true;
+ if (!IsProcess && !GetProcess())
+ StatusLine->SimpleText = "";
+ if (!IsVariables && !GetVariables())
+ StatusLine->SimpleText = "";
+ Timer3->Interval = 10000;
+ }
+ else
+ Extended->Enabled = false;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetServerStatus(void)
+{
+
+ GetExtendedStatus();
+ Edit3->Text = mysql_get_server_info(MySQL);
+ Edit4->Text = mysql_get_host_info(MySQL);
+ Edit5->Text = mysql_get_client_info();
+ Edit6->Text = mysql_get_proto_info(MySQL);
+
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetProcess()
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 0;
+ int therow = 1;
+ new_line=1;
+
+ StringGrid2->RowCount= 2;
+
+ if (!(res=mysql_list_processes(MySQL)))
+ {
+ return false;
+ }
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+ StringGrid2->Cells[0][0] = "PID";
+ StringGrid2->Cells[1][0] = "User";
+ StringGrid2->Cells[2][0] = "Host";
+ StringGrid2->Cells[3][0] = "DB";
+ StringGrid2->Cells[4][0] = "Command";
+ StringGrid2->Cells[5][0] = "Time";
+ StringGrid2->Cells[6][0] = "State";
+ StringGrid2->Cells[7][0] = "Info";
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ if (k <= 6 )
+ {
+ StringGrid2->Cells[k][therow] = row[i];
+ k++;
+ }
+ else
+ {
+
+ StringGrid2->Cells[(k)][therow] = row[i];
+ k = 0;
+ therow++ ;
+ StringGrid2->RowCount++;
+
+ }
+
+ }
+
+ }
+
+ StringGrid2->RowCount--;
+ mysql_free_result(res);
+ StringGrid5->RowCount--;
+ IsProcess = true;
+ return true;
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetVariables()
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 1;
+ new_line=1;
+ bool left = true;
+ AnsiString report;
+ StringGrid1->RowCount = 2;
+ if (mysql_query(MySQL,"show variables") ||
+ !(res=mysql_store_result(MySQL)))
+ {
+ return false;
+ }
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ StringGrid1->Cells[0][0] = "Variable Name";
+ StringGrid1->Cells[1][0] = "Value";
+
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ if (left)
+ {
+ if (treport)
+ report = GetString(row[i]);
+ StringGrid1->Cells[0][k++] = row[i];
+ left = false;
+ }
+ else
+ {
+ if (treport)
+ Memo5->Lines->Add(report + row[i]);
+ StringGrid1->RowCount++;
+ StringGrid1->Cells[1][--k] = row[i];
+ k++;
+ left = true;
+ }
+
+ }
+
+ }
+
+ StringGrid1->RowCount--;
+ mysql_free_result(res);
+ IsVariables = true;
+ return true;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::nice_time(AnsiString buff)
+{
+
+ unsigned long sec;
+ unsigned long tmp;
+ AnsiString mytime;
+
+ sec = StrToInt(buff);
+
+ if (sec >= 3600L*24)
+ {
+ tmp=sec/(3600L*24);
+ sec-=3600L*24*tmp;
+
+ mytime = IntToStr(tmp);
+ if (tmp > 1)
+ mytime+= " days ";
+ else
+ mytime+= " day ";
+
+ }
+
+ if (sec >= 3600L)
+ {
+ tmp=sec/3600L;
+ sec-=3600L*tmp;
+ mytime += IntToStr(tmp);
+ if (tmp > 1)
+ mytime+= " hours ";
+ else
+ mytime+= " hour ";
+ }
+ if (sec >= 60)
+ {
+ tmp=sec/60;
+ sec-=60*tmp;
+ mytime += IntToStr(tmp);
+ mytime+= " min ";
+
+ }
+ mytime += IntToStr(sec);
+ mytime+= " sec ";
+ st29->Text = mytime ;
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::Button11Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (GetVariables())
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button10Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (GetProcess())
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button6Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_HOSTS))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button7Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_LOG))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button8Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_TABLES))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button2Click(TObject *Sender)
+{
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ AnsiString asFileName = FileSearch("my.ini", TheWinDir());
+ if (asFileName.IsEmpty())
+ Application->MessageBox("Don't found my.ini file on the Win Directory", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ FillMyIni();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button3Click(TObject *Sender)
+{
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ if (!Memo1->GetTextLen())
+ Application->MessageBox("The Memo Box is Empty", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ {
+ if(Application->MessageBox("Are you sure to write the modifications into My.ini file.", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ Memo1->Lines->SaveToFile(TheWinDir() + "\\my.ini");
+
+ Memo1->Lines->Clear();
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ if (NtVer->Checked)
+ pIniFile->WriteString("WinMySQLadmin","Server",TheDir() + "/bin/mysqld-nt.exe");
+ if (MysqldVer->Checked == true)
+ pIniFile->WriteString("WinMySQLadmin","Server", TheDir() + "/bin/mysqld.exe");
+ if (ShareVer->Checked)
+ pIniFile->WriteString("WinMySQLadmin","Server",TheDir() + "/bin/mysqld-shareware.exe");
+ if (OptVer->Checked)
+ pIniFile->WriteString("WinMySQLadmin","Server", TheDir() + "/bin/mysqld-opt.exe");
+ FillMyIni();
+ Application->MessageBox("My.ini was modificated", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ }
+
+ }
+ delete pIniFile;
+ Memo1->Lines->Clear();
+ FillMyIni();
+
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button1Click(TObject *Sender)
+{
+ if(CreatingShortCut())
+ Application->MessageBox("The ShortCut on Start Menu was created", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ Application->MessageBox("Fails the Operation of Create the ShortCut", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
+{
+ BROWSEINFO info;
+ char szDir[MAX_PATH];
+ char szDisplayName[MAX_PATH];
+ LPITEMIDLIST pidl;
+ LPMALLOC pShellMalloc;
+
+
+ if(SHGetMalloc(&pShellMalloc) == NO_ERROR)
+ {
+
+ memset(&info, 0x00,sizeof(info));
+ info.hwndOwner = Handle;
+ info.pidlRoot = 0;
+ info.pszDisplayName = szDisplayName;
+ info.lpszTitle = "Search MySQL Base Directory";
+ info.ulFlags = BIF_RETURNONLYFSDIRS;
+ info.lpfn = 0;
+
+ pidl = SHBrowseForFolder(&info);
+
+ if(pidl)
+ {
+
+ if(SHGetPathFromIDList(pidl, szDir)) {BaseDir->Text = szDir; }
+
+ pShellMalloc->Free(pidl);
+ }
+ pShellMalloc->Release();
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button4Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ Memo3->Lines->Add(mysql_stat(MySQL));
+ }
+}
+//---------------------------------------------------------------------------
+
+
+void __fastcall TForm1::SpeedButton3Click(TObject *Sender)
+{
+ if(Showme1->Caption == "Show me") { TrayMessage(NIM_DELETE);
+ Showme1->Caption = "Hide me"; Show(); }
+ else { TrayMessage(NIM_ADD); TrayMessage(NIM_MODIFY);
+ Showme1->Caption = "Show me"; Hide(); }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::ExtendedClick(TObject *Sender)
+{
+if (ya)
+ {
+ Extended->Caption = "Start Extended Server Status";
+ ya = false;
+ ClearBox();
+ }
+else
+ {
+ Extended->Caption = "Stop Extended Server Status";
+ ya = true;
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetServerOptions(void)
+{
+AnsiString FileName;
+FileName = FileSearch("mysqld-opt.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {OptVer->Enabled = false; }
+
+FileName = FileSearch("mysqld-shareware.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {ShareVer->Enabled = false; }
+
+FileName = FileSearch("mysqld.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {MysqldVer->Enabled = false; }
+
+FileName = FileSearch("mysqld-nt.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {NtVer->Enabled = false; }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetReportServer(void)
+{
+
+ AnsiString strspace;
+ Memo5->Lines->Clear();
+ Memo5->Lines->Add("This Report was made using the WinMySQLadmin 1.0 Tool");
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add(Now());
+ Memo5->Lines->Add("");
+
+ preport = true;
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add("Server Status Values");
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add(GetString("Server Info") + mysql_get_server_info(MySQL));
+ Memo5->Lines->Add(GetString("Host Info") + mysql_get_host_info(MySQL));
+ Memo5->Lines->Add(GetString("Client Info") + mysql_get_client_info());
+ Memo5->Lines->Add(GetString("Proto Info") + mysql_get_proto_info(MySQL));
+ GetExtendedStatus();
+ preport = false;
+ treport = true;
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add("Variables Values");
+ Memo5->Lines->Add("");
+ GetVariables();
+ treport = false;
+ ereport = true;
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add("Last Lines from Err File");
+ Memo5->Lines->Add("");
+ SeekErrFile();
+ ereport = false;
+
+}
+
+void __fastcall TForm1::SpeedButton4Click(TObject *Sender)
+{
+ if(IsConnect)
+ GetReportServer();
+ else
+ Application->MessageBox("The Server must be connected", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton5Click(TObject *Sender)
+{
+ AnsiString PathName;
+ SaveFileDialog->FileName = PathName;
+ if (SaveFileDialog->Execute() ){
+ PathName= SaveFileDialog->FileName;
+ Caption = ExtractFileName(PathName);
+ Memo5->Lines->SaveToFile(PathName);
+ Memo5->Modified = false;
+ }
+}
+//---------------------------------------------------------------------------
+String __fastcall TForm1::GetString(String k)
+{
+ int i = 35 - k.Length();
+ for (int y = 1 ; y <= i ;y++ )
+ k+= " ";
+ return k ;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::SpeedButton6Click(TObject *Sender)
+{
+ PrinterSetupDialog1->Execute();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton7Click(TObject *Sender)
+{
+ AnsiString PathName;
+ if (PrintDialog1->Execute()){
+ try {
+ Memo5->Print(PathName);
+ }
+ catch(...){
+ Printer()->EndDoc();
+ throw;
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton8Click(TObject *Sender)
+{
+ Memo5->CutToClipboard();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton9Click(TObject *Sender)
+{
+ Memo5->CopyToClipboard();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton10Click(TObject *Sender)
+{
+
+ Memo5->PasteFromClipboard();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton11Click(TObject *Sender)
+{
+ Memo5->ClearSelection();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton12Click(TObject *Sender)
+{
+ Memo5->SelectAll();
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetMainRoot()
+{
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ AnsiString command;
+
+ CleanGrid();
+ CleanGridI();
+ TakeIP();
+
+ MySQLNode = DBView->Items->Add(NULL, mainroot.UpperCase());
+ MySQLNode->ImageIndex = 0;
+
+ if (!(res=mysql_list_dbs(MySQL,"%"))) { return false; }
+ while ((row=mysql_fetch_row(res)) != 0) {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ MySQLDbs = DBView->Items->AddChild(MySQLNode, row[i]);
+ MySQLDbs->ImageIndex = 1;
+ MySQLDbs->SelectedIndex = 1;
+
+
+ }
+
+ }
+
+ mysql_free_result(res);
+ MySQLNode->Expanded = true;
+
+
+
+
+ IsMySQLNode = true;
+ return true;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::DeleteDatabaseSClick(TObject *Sender)
+{
+ AnsiString alert;
+ if (IsConnect)
+ {
+ if(DBView->Selected == MySQLNode )
+ Application->MessageBox("Invalid database row selected.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else if ( DBView->Selected == NULL )
+ Application->MessageBox("Invalid database row selected.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else
+ {
+ if (DBView->Selected->Text.UpperCase() == "MYSQL")
+ Application->MessageBox("You cann't use this tool to drop the MySQL Database.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else {
+ alert = "Are you sure to drop the < ";
+ alert+= DBView->Selected->Text.c_str();
+ alert+= " > database.";
+ if(Application->MessageBox(alert.c_str(), "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ char* lese = DBView->Selected->Text.c_str();
+ if (!mysql_drop_db(MySQL, lese ))
+ {
+ DBView->Items->Clear();
+ GetMainRoot();
+ }
+ else
+ Application->MessageBox("Fails to drop the Database.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ }
+ }
+ else
+ Application->MessageBox("The Server must be connected", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+}
+//---------------------------------------------------------------------------
+ bool __fastcall TForm1::IsDatabase(String Name)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ AnsiString command;
+
+
+ CleanTree();
+ command = "use ";
+ command+= Name.c_str();
+ char* das = command.c_str();
+ char* lis = Name.c_str();
+ if (mysql_query(MySQL, das ) ||
+ !(res=mysql_list_tables(MySQL,"%")))
+ return false;
+
+ MySQLNodeT = TableView->Items->Add(NULL, lis);
+ MySQLNodeT->ImageIndex = 1;
+ MySQLNodeT->SelectedIndex = 1;
+ while ((row=mysql_fetch_row(res)) != 0) {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ MySQLTbs = TableView->Items->AddChild(MySQLNodeT, row[i]);
+ MySQLTbs->ImageIndex = 2;
+ MySQLTbs->SelectedIndex = 2;
+ }
+ MySQLNodeT->Expanded = true;
+ }
+ mysql_free_result(res);
+ return true;
+}
+//---------------------------------------------------------------------------
+
+
+void __fastcall TForm1::DBViewClick(TObject *Sender)
+{
+
+ if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNode && DBView->Selected != NULL )
+ {
+ IsDatabase(DBView->Selected->Text);
+
+ }
+ else
+ {
+ CleanTree();
+ }
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::TableViewClick(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNodeT )
+ {
+ IsTable(TableView->Selected->Text);
+ IsIndex(TableView->Selected->Text);
+
+ }
+ else
+ {
+ CleanGrid();
+ CleanGridI();
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+ bool __fastcall TForm1::IsTable(String Name)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 0;
+ int therow = 1;
+ new_line=1;
+ AnsiString command;
+ AnsiString commandt;
+
+ CleanGrid();
+ CleanGridI();
+ command = "use ";
+ command+= DBView->Selected->Text.c_str();
+ char* las = command.c_str();
+
+ commandt = "desc ";
+ commandt+= Name.c_str();
+ char* les = commandt.c_str();
+
+ if (mysql_query(MySQL, las ))
+ return false;
+
+ if (mysql_query(MySQL, les ) ||
+ !(res=mysql_store_result(MySQL)))
+ return false ;
+
+ StringGrid4->Cells[0][0] = "Field";
+ StringGrid4->Cells[1][0] = "Type";
+ StringGrid4->Cells[2][0] = "Null";
+ StringGrid4->Cells[3][0] = "Key";
+ StringGrid4->Cells[4][0] = "Default";
+ StringGrid4->Cells[5][0] = "Extra";
+ StringGrid4->Cells[6][0] = "Previleges";
+
+
+ int thecounter;
+ String u = GetNumberServer();
+ if ( u == "3.22")
+ {
+ StringGrid3->ColCount = 7;
+ thecounter = 4;
+ }
+ else
+ thecounter = 5;
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ if (k <= thecounter )
+ {
+ StringGrid4->Cells[k][therow] = row[i];
+ k++;
+ }
+ else
+ {
+ StringGrid4->Cells[(k)][therow] = row[i];
+ k = 0;
+ therow++ ;
+ StringGrid4->RowCount++;
+ }
+ }
+
+ }
+ StringGrid4->RowCount--;
+ mysql_free_result(res);
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::TableViewChange(TObject *Sender, TTreeNode *Node)
+{
+if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNodeT )
+ {
+ IsTable(TableView->Selected->Text);
+ IsIndex(TableView->Selected->Text);
+
+ }
+ else
+ {
+ CleanGrid();
+ CleanGridI();
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::DBViewChange(TObject *Sender, TTreeNode *Node)
+{
+ if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNode )
+ {
+ IsDatabase(DBView->Selected->Text);
+
+ }
+ else
+ {
+ CleanTree();
+ }
+ }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::RefreshSClick(TObject *Sender)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ AnsiString command;
+
+ if (IsConnect)
+ {
+ IsMySQLNode = false;
+ CleanTree();
+ DBView->Items->Clear();
+
+ TakeIP();
+
+ MySQLNode = DBView->Items->Add(NULL, mainroot.UpperCase());
+ MySQLNode->ImageIndex = 0;
+
+ if (!(res=mysql_list_dbs(MySQL,"%"))) { /*do nothing;*/ }
+ while ((row=mysql_fetch_row(res)) != 0) {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ MySQLDbs = DBView->Items->AddChild(MySQLNode, row[i]);
+ MySQLDbs->ImageIndex = 1;
+ MySQLDbs->SelectedIndex = 1;
+
+ }
+
+ }
+
+ mysql_free_result(res);
+
+ IsMySQLNode = true;
+
+ MySQLNode->Expanded = true;
+
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::CreateDatabaseSClick(TObject *Sender)
+{
+
+ if (IsConnect)
+ {
+ dbfrm->Show();
+
+ }
+ else
+ ShowMessage("Precisa estar conectado");
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CleanTree(void)
+{
+ StringGrid4->RowCount= 2;
+ StringGrid4->Cells[0][1] = "";
+ StringGrid4->Cells[1][1] = "";
+ StringGrid4->Cells[2][1] = "";
+ StringGrid4->Cells[3][1] = "";
+ StringGrid4->Cells[4][1] = "";
+ StringGrid4->Cells[5][1] = "";
+ TableView->Items->Clear();
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CleanGrid(void)
+{
+ StringGrid4->RowCount= 2;
+ StringGrid4->Cells[0][1] = "";
+ StringGrid4->Cells[1][1] = "";
+ StringGrid4->Cells[2][1] = "";
+ StringGrid4->Cells[3][1] = "";
+ StringGrid4->Cells[4][1] = "";
+ StringGrid4->Cells[5][1] = "";
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::CreatingDB()
+{
+
+ if (mysql_create_db(MySQL, dbfrm->Edit1->Text.c_str()))
+ return true;
+ else
+ return false;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::OutRefresh(void)
+{
+ RefreshSClick(dbfrm->SpeedButton1);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FlushHosts1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_HOSTS))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::FlushLogs1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_LOG))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::FlushTables1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_TABLES))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+ bool __fastcall TForm1::IsIndex(String Name)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 0;
+ int therow = 1;
+ new_line=1;
+ AnsiString command;
+ AnsiString commandt;
+ i = 0;
+ CleanGridI();
+ command = "use ";
+ command+= DBView->Selected->Text.c_str();
+ char* las = command.c_str();
+
+ commandt = "show index from ";
+ commandt+= Name.c_str();
+ char* les = commandt.c_str();
+
+ if (mysql_query(MySQL, las ))
+ return false;
+
+ if (mysql_query(MySQL, les ) ||
+ !(res=mysql_store_result(MySQL)))
+ return false ;
+
+ StringGrid3->RowCount= 2;
+ StringGrid3->Cells[0][0] = "Table";
+ StringGrid3->Cells[1][0] = "Non_unique";
+ StringGrid3->Cells[2][0] = "Key_name";
+ StringGrid3->Cells[3][0] = "Seq_in_index";
+ StringGrid3->Cells[4][0] = "Col_name";
+ StringGrid3->Cells[5][0] = "Collation";
+ StringGrid3->Cells[6][0] = "Card.";
+ StringGrid3->Cells[7][0] = "Sub_part";
+ StringGrid3->Cells[8][0] = "Packed";
+ StringGrid3->Cells[9][0] = "Comment";
+
+ int thecounter;
+ String u = GetNumberServer();
+
+ if ( u == "3.22")
+ {
+ StringGrid3->ColCount = 8;
+ thecounter = 6;
+ }
+ else
+ thecounter = 8;
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ if (k <= thecounter )
+ {
+ StringGrid3->Cells[k][therow] = row[i];
+ k++;
+ }
+ else
+ {
+ StringGrid3->Cells[(k)][therow] = row[i];
+ k = 0;
+ therow++ ;
+ StringGrid3->RowCount++;
+ }
+ }
+
+ }
+ if (i)
+ StringGrid3->RowCount--;
+ mysql_free_result(res);
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CleanGridI(void)
+{
+ StringGrid3->RowCount= 2;
+ StringGrid3->Cells[0][1] = "";
+ StringGrid3->Cells[1][1] = "";
+ StringGrid3->Cells[2][1] = "";
+ StringGrid3->Cells[3][1] = "";
+ StringGrid3->Cells[4][1] = "";
+ StringGrid3->Cells[5][1] = "";
+ StringGrid3->Cells[6][1] = "";
+ StringGrid3->Cells[7][1] = "";
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::CreatingTable(String TheTable)
+{
+
+ if (!mysql_query(MySQL, TheTable.c_str()))
+ return true;
+ else
+ return false;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetExtendedStatus()
+{
+ if (!ya && !preport)
+ return true;
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 1;
+ new_line=1;
+ bool left = true;
+ bool open_tables = false;
+ bool open_files = false;
+ bool uptime = false;
+ bool running_threads = false;
+ bool open_streams = false;
+ bool slow_queries = false;
+ bool opened_tables = false;
+ bool questions = false;
+
+ AnsiString report;
+ if (yy)
+ StringGrid5->RowCount = 2;
+
+ if (mysql_query(MySQL,"show status") ||
+ !(res=mysql_store_result(MySQL)))
+ {
+ return false;
+ }
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ StringGrid5->Cells[0][0] = "Variable Name";
+ StringGrid5->Cells[1][0] = "Value";
+
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ if (left)
+ {
+ if (preport)
+ report = GetString(row[i]);
+ if ( (String) row[i] == "Open_tables")
+ open_tables = true;
+ else
+ open_tables = false;
+ if ( (String) row[i] == "Open_files")
+ open_files = true;
+ else
+ open_files = false;
+ if ((String) row[i] == "Uptime")
+ uptime = true;
+ else
+ uptime = false;
+
+ if ( (String) row[i] == "Opened_tables")
+ opened_tables = true;
+ else
+ opened_tables = false;
+
+ if ( (String) row[i] == "Threads_running" || (String) row[i] == "Running_threads")
+ running_threads = true;
+ else
+ running_threads = false;
+
+ if ( (String) row[i] == "Open_streams")
+ open_streams = true;
+ else
+ open_streams = false;
+
+ if ( (String) row[i] == "Slow_queries")
+ slow_queries = true;
+ else
+ slow_queries = false;
+
+ if ( (String) row[i] == "Questions")
+ questions = true;
+ else
+ questions = false;
+
+ if (yy)
+ StringGrid5->Cells[0][k++] = row[i];
+
+ left = false;
+ }
+ else
+ {
+ if (preport)
+ Memo5->Lines->Add(report + row[i]);
+ if (open_tables)
+ st22->Text = row[i];
+ if (open_files)
+ st23->Text = row[i];
+ if (uptime)
+ nice_time(row[i]);
+ if (running_threads)
+ st27->Text = row[i];
+ if (open_streams)
+ st24->Text = row[i];
+ if (slow_queries)
+ st28->Text = row[i];
+ if (opened_tables)
+ st25->Text = row[i];
+ if (questions){
+ q++;
+ st26->Text = StrToInt64(row[i]) - q; }
+
+ if (yy){
+ StringGrid5->RowCount++;
+ StringGrid5->Cells[1][--k] = row[i];
+ k++; }
+
+ left = true;
+ }
+
+ }
+
+ }
+
+
+ if (rinit)
+ StringGrid5->RowCount--;
+ mysql_free_result(res);
+ yy = false;
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::SpeedButton13Click(TObject *Sender)
+{
+ yy = true;
+ // rinit = true;
+}
+//---------------------------------------------------------------------------
+String __fastcall TForm1::GetNumberServer()
+{
+ String TheVersion;
+
+ TheVersion = mysql_get_server_info(MySQL) ;
+ TheVersion.SetLength(4);
+ return TheVersion;
+
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::KillProcess1Click(TObject *Sender)
+{
+
+ if (IsConnect)
+ KillPID();
+ else
+ Application->MessageBox("The Server must be connected", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::KillPID()
+{
+ String s = "Are you sure to kill the process PID no. ";
+ s+= StringGrid2->Cells[0][StringGrid2->Row];
+ s+= " of the USER ";
+ s+= StringGrid2->Cells[1][StringGrid2->Row];
+ unsigned long xx = mysql_thread_id(MySQL);
+ unsigned long yy = StrToInt(StringGrid2->Cells[0][StringGrid2->Row]);
+ if ( xx != yy)
+ {
+ if(Application->MessageBox(s.c_str(), "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (!mysql_kill(MySQL,yy))
+ {
+ GetProcess();
+ return true;
+ }
+ }
+ }
+ else
+ {
+ Application->MessageBox("From here you can't kill the PID of this tool", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ return true;
+ }
+ return true;
+}
+void __fastcall TForm1::FlushThreads1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_THREADS))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
diff --git a/VC++Files/winmysqladmin/main.h b/VC++Files/winmysqladmin/main.h
new file mode 100644
index 00000000000..dcb8ad60d7b
--- /dev/null
+++ b/VC++Files/winmysqladmin/main.h
@@ -0,0 +1,314 @@
+//---------------------------------------------------------------------------
+#ifndef mainH
+#define mainH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <Buttons.hpp>
+#include <ComCtrls.hpp>
+#include <ExtCtrls.hpp>
+#include <Graphics.hpp>
+#include <Grids.hpp>
+#include <ImgList.hpp>
+#include <Menus.hpp>
+#include <Dialogs.hpp>
+#include <string.h>
+
+#define MYWM_NOTIFY (WM_APP+100)
+#define IDC_MYICON 1006
+extern HINSTANCE g_hinst;
+LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi);
+//---------------------------------------------------------------------------
+class TForm1 : public TForm
+{
+__published: // IDE-managed Components
+ TStatusBar *StatusLine;
+ TPanel *Panel1;
+ TImage *Image1;
+ TLabel *Label1;
+ TLabel *Label2;
+ TLabel *Label3;
+ TLabel *Label8;
+ TImage *Image3;
+ TImage *Image2;
+ TPageControl *PageControl1;
+ TTabSheet *TabSheet1;
+ TSpeedButton *SpeedButton1;
+ TGroupBox *GroupBox1;
+ TLabel *Label4;
+ TLabel *Label5;
+ TLabel *Label6;
+ TLabel *Label14;
+ TLabel *Label17;
+ TEdit *Localhost;
+ TEdit *Localuser;
+ TEdit *OS;
+ TMemo *Memo2;
+ TEdit *Edit2;
+ TGroupBox *GroupBox2;
+ TMemo *Memo3;
+ TGroupBox *GroupBox3;
+ TLabel *Label13;
+ TLabel *Label15;
+ TLabel *Label16;
+ TLabel *Label7;
+ TLabel *Label47;
+ TLabel *Label44;
+ TLabel *Label42;
+ TLabel *Label45;
+ TEdit *Edit3;
+ TEdit *Edit4;
+ TEdit *Edit5;
+ TEdit *Edit6;
+ TEdit *st29;
+ TEdit *st27;
+ TEdit *st25;
+ TEdit *st28;
+ TTabSheet *TabSheet2;
+ TTabSheet *TabSheet3;
+ TLabel *Label18;
+ TSpeedButton *SpeedButton2;
+ TEdit *BaseDir;
+ TMemo *Memo1;
+ TRadioGroup *RadioGroup1;
+ TRadioButton *ShareVer;
+ TRadioButton *MysqldVer;
+ TRadioButton *OptVer;
+ TRadioButton *NtVer;
+ TButton *Button2;
+ TButton *Button3;
+ TButton *Button1;
+ TTabSheet *TabSheet4;
+ TMemo *Memo4;
+ TButton *Button5;
+ TTabSheet *TabSheet5;
+ TStringGrid *StringGrid1;
+ TButton *Button11;
+ TTabSheet *TabSheet6;
+ TStringGrid *StringGrid2;
+ TButton *Button10;
+ TPopupMenu *PopupMenu1;
+ TMenuItem *Showme1;
+ TMenuItem *N1;
+ TMenuItem *Win9;
+ TMenuItem *Swin9;
+ TMenuItem *N3;
+ TMenuItem *SSW9;
+ TMenuItem *N4;
+ TMenuItem *ShutDownBoth1;
+ TMenuItem *N2;
+ TMenuItem *WinNT;
+ TMenuItem *ShutDownthisTool1;
+ TMenuItem *N5;
+ TMenuItem *StopS;
+ TMenuItem *N6;
+ TMenuItem *RService;
+ TMenuItem *N7;
+ TMenuItem *Standa;
+ TImageList *ImageList1;
+ TTimer *Timer1;
+ TTimer *Timer2;
+ TTimer *Timer3;
+ TSpeedButton *SpeedButton3;
+ TSpeedButton *Extended;
+ TLabel *Label9;
+ TEdit *st26;
+ TLabel *Label43;
+ TEdit *st24;
+ TLabel *Label41;
+ TEdit *st23;
+ TLabel *Label40;
+ TEdit *st22;
+ TLabel *Label39;
+ TTabSheet *TabSheet8;
+ TSaveDialog *SaveFileDialog;
+ TPrinterSetupDialog *PrinterSetupDialog1;
+ TPrintDialog *PrintDialog1;
+ TRichEdit *Memo5;
+ TGroupBox *GroupBox5;
+ TSpeedButton *SpeedButton4;
+ TSpeedButton *SpeedButton5;
+ TSpeedButton *SpeedButton7;
+ TSpeedButton *SpeedButton6;
+ TGroupBox *GroupBox6;
+ TSpeedButton *SpeedButton8;
+ TSpeedButton *SpeedButton9;
+ TSpeedButton *SpeedButton10;
+ TSpeedButton *SpeedButton11;
+ TSpeedButton *SpeedButton12;
+ TTabSheet *TabSheet9;
+ TImageList *ImageList2;
+ TPopupMenu *PopupMenu2;
+ TMenuItem *CreateDatabaseS;
+ TMenuItem *DeleteDatabaseS;
+ TMenuItem *RefreshS;
+ TMenuItem *N8;
+ TMenuItem *N9;
+ TMenuItem *N10;
+ TGroupBox *GroupBox7;
+ TTreeView *DBView;
+ TGroupBox *GroupBox8;
+ TTreeView *TableView;
+ TGroupBox *GroupBox9;
+ TStringGrid *StringGrid4;
+ TMenuItem *FlushHosts1;
+ TMenuItem *N11;
+ TMenuItem *FlushLogs1;
+ TMenuItem *N12;
+ TMenuItem *FlushTables1;
+ TGroupBox *GroupBox10;
+ TStringGrid *StringGrid3;
+ TImage *Image5;
+ TStringGrid *StringGrid5;
+ TSpeedButton *SpeedButton13;
+ TPopupMenu *PopupMenu4;
+ TMenuItem *KillProcess1;
+ TMenuItem *N13;
+ TMenuItem *FlushThreads1;
+ void __fastcall FormCreate(TObject *Sender);
+ void __fastcall Showme1Click(TObject *Sender);
+ void __fastcall Timer1Timer(TObject *Sender);
+ void __fastcall SpeedButton1Click(TObject *Sender);
+ void __fastcall Timer2Timer(TObject *Sender);
+ void __fastcall Swin9Click(TObject *Sender);
+ void __fastcall SSW9Click(TObject *Sender);
+ void __fastcall ShutDownBoth1Click(TObject *Sender);
+ void __fastcall ShutDownthisTool1Click(TObject *Sender);
+ void __fastcall StopSClick(TObject *Sender);
+ void __fastcall RServiceClick(TObject *Sender);
+ void __fastcall StandaClick(TObject *Sender);
+ void __fastcall Button5Click(TObject *Sender);
+ void __fastcall Timer3Timer(TObject *Sender);
+ void __fastcall Button11Click(TObject *Sender);
+ void __fastcall Button10Click(TObject *Sender);
+ void __fastcall Button6Click(TObject *Sender);
+ void __fastcall Button7Click(TObject *Sender);
+ void __fastcall Button8Click(TObject *Sender);
+
+ void __fastcall Button2Click(TObject *Sender);
+ void __fastcall Button3Click(TObject *Sender);
+ void __fastcall Button1Click(TObject *Sender);
+ void __fastcall SpeedButton2Click(TObject *Sender);
+ void __fastcall Button4Click(TObject *Sender);
+ void __fastcall SpeedButton3Click(TObject *Sender);
+ void __fastcall ExtendedClick(TObject *Sender);
+ void __fastcall SpeedButton4Click(TObject *Sender);
+ void __fastcall SpeedButton5Click(TObject *Sender);
+ void __fastcall SpeedButton6Click(TObject *Sender);
+ void __fastcall SpeedButton7Click(TObject *Sender);
+ void __fastcall SpeedButton8Click(TObject *Sender);
+ void __fastcall SpeedButton9Click(TObject *Sender);
+ void __fastcall SpeedButton10Click(TObject *Sender);
+ void __fastcall SpeedButton11Click(TObject *Sender);
+ void __fastcall SpeedButton12Click(TObject *Sender);
+ void __fastcall DeleteDatabaseSClick(TObject *Sender);
+ void __fastcall DBViewClick(TObject *Sender);
+ void __fastcall TableViewClick(TObject *Sender);
+ void __fastcall TableViewChange(TObject *Sender, TTreeNode *Node);
+ void __fastcall DBViewChange(TObject *Sender, TTreeNode *Node);
+
+ void __fastcall RefreshSClick(TObject *Sender);
+ void __fastcall CreateDatabaseSClick(TObject *Sender);
+ void __fastcall FlushHosts1Click(TObject *Sender);
+ void __fastcall FlushLogs1Click(TObject *Sender);
+ void __fastcall FlushTables1Click(TObject *Sender);
+ void __fastcall SpeedButton13Click(TObject *Sender);
+ void __fastcall KillProcess1Click(TObject *Sender);
+ void __fastcall FlushThreads1Click(TObject *Sender);
+
+
+
+
+
+
+
+private: // User declarations
+ void __fastcall DrawItem(TMessage& Msg);
+ void __fastcall MyNotify(TMessage& Msg);
+ bool __fastcall TrayMessage(DWORD dwMessage);
+ HANDLE __fastcall IconHandle(void);
+ void __fastcall ToggleState(void);
+ PSTR __fastcall TipText(void);
+ void __fastcall WMQueryEndSession(TWMQueryEndSession &msg);
+ AnsiString __fastcall TheComputer();
+ AnsiString __fastcall TheUser();
+ AnsiString __fastcall TheOS();
+ void __fastcall TakeIP(void);
+ void __fastcall GetmemStatus(void);
+ void __fastcall ShowHelp(void);
+ void __fastcall ContinueLoad(void);
+ void __fastcall MyODBC(void);
+ void __fastcall IsMyIniUp(void);
+ void __fastcall QuickSearch(void);
+ AnsiString __fastcall TheWinDir();
+ void __fastcall FillMyIni(void);
+ void __fastcall GetBaseDir(void);
+ bool __fastcall MySQLSignal();
+ bool __fastcall mysqldstart();
+ bool __fastcall SeekErrFile();
+ AnsiString __fastcall TheDir();
+ bool __fastcall TheServiceStart();
+ bool __fastcall TheServicePause();
+ bool __fastcall TheServiceResume();
+ bool __fastcall TheServiceStatus();
+ bool __fastcall TheServiceCreate();
+ bool __fastcall TheServiceRemove();
+ bool __fastcall Shutd();
+ void __fastcall ClearBox(void);
+ bool __fastcall TheServerPath();
+ void __fastcall GetServerOptions(void);
+ void __fastcall GetReportServer(void);
+
+
+ TFileStream *MyFile;
+ String FName;
+
+ void __fastcall IsMySQLInit(void);
+ void __fastcall GetServerStatus(void);
+ bool __fastcall GetExtendedStatus();
+ bool __fastcall GetProcess();
+ bool __fastcall GetVariables();
+ bool __fastcall nice_time(AnsiString buff);
+ String __fastcall GetString(String k);
+ String __fastcall GetNumberServer();
+ // pointers for database screen
+ TTreeNode *MySQLNode, *MySQLDbs, *MySQLNodeT, *MySQLTbs;
+
+ bool __fastcall GetMainRoot();
+ bool __fastcall IsDatabase(String Name);
+ bool __fastcall IsTable(String Name);
+ void __fastcall CleanTree(void);
+ void __fastcall CleanGrid(void);
+ bool __fastcall IsIndex(String Name);
+ void __fastcall CleanGridI(void);
+ bool __fastcall KillPID();
+
+
+
+public: // User declarations
+ __fastcall TForm1(TComponent* Owner);
+ void __fastcall GetServerFile(void);
+ void __fastcall CreateMyIniFile(void);
+ bool __fastcall CreatingShortCut();
+ bool __fastcall CreatingDB();
+ void __fastcall OutRefresh(void);
+ bool __fastcall CreatingTable(String TheTable);
+
+ bool IsConnect ;
+
+
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ BEGIN_MESSAGE_MAP
+ MESSAGE_HANDLER(WM_DRAWITEM,TMessage,DrawItem)
+ MESSAGE_HANDLER(MYWM_NOTIFY,TMessage,MyNotify)
+ MESSAGE_HANDLER(WM_QUERYENDSESSION,TWMQueryEndSession,WMQueryEndSession)
+ END_MESSAGE_MAP(TForm)
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TForm1 *Form1;
+//---------------------------------------------------------------------------
+#endif
diff --git a/VC++Files/winmysqladmin/mysql.h b/VC++Files/winmysqladmin/mysql.h
new file mode 100644
index 00000000000..e83babb8fa8
--- /dev/null
+++ b/VC++Files/winmysqladmin/mysql.h
@@ -0,0 +1,293 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA */
+
+/* defines for the libmysql library */
+
+#ifndef _mysql_h
+#define _mysql_h
+
+#ifndef MYSQL_SERVER
+#ifdef __cplusplus
+extern "C" {
+#endif
+#endif
+
+#ifndef _global_h /* If not standard header */
+#include <sys/types.h>
+typedef char my_bool;
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__WIN__)
+#define __WIN__
+#endif
+#if !defined(__WIN__)
+#define STDCALL
+#else
+#define STDCALL __stdcall
+#endif
+typedef char * gptr;
+
+#ifndef ST_USED_MEM_DEFINED
+#define ST_USED_MEM_DEFINED
+typedef struct st_used_mem { /* struct for once_alloc */
+ struct st_used_mem *next; /* Next block in use */
+ unsigned int left; /* memory left in block */
+ unsigned int size; /* size of block */
+} USED_MEM;
+typedef struct st_mem_root {
+ USED_MEM *free;
+ USED_MEM *used;
+ unsigned int min_malloc;
+ unsigned int block_size;
+ void (*error_handler)(void);
+} MEM_ROOT;
+#endif
+
+#ifndef my_socket_defined
+#ifdef __WIN__
+#define my_socket SOCKET
+#else
+typedef int my_socket;
+#endif
+#endif
+#endif
+#include "mysql_com.h"
+#include "mysql_version.h"
+
+extern unsigned int mysql_port;
+extern char *mysql_unix_port;
+
+#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
+#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
+#define IS_BLOB(n) ((n) & BLOB_FLAG)
+#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR)
+
+typedef struct st_mysql_field {
+ char *name; /* Name of column */
+ char *table; /* Table of column if column was a field */
+ char *def; /* Default value (set by mysql_list_fields) */
+ enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
+ unsigned int length; /* Width of column */
+ unsigned int max_length; /* Max width of selected set */
+ unsigned int flags; /* Div flags */
+ unsigned int decimals; /* Number of decimals in field */
+} MYSQL_FIELD;
+
+typedef char **MYSQL_ROW; /* return data as array of strings */
+typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */
+
+#if defined(NO_CLIENT_LONG_LONG)
+typedef unsigned long my_ulonglong;
+#elif defined (__WIN__)
+typedef unsigned __int64 my_ulonglong;
+#else
+typedef unsigned long long my_ulonglong;
+#endif
+
+#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
+
+typedef struct st_mysql_rows {
+ struct st_mysql_rows *next; /* list of rows */
+ MYSQL_ROW data;
+} MYSQL_ROWS;
+
+typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
+
+typedef struct st_mysql_data {
+ my_ulonglong rows;
+ unsigned int fields;
+ MYSQL_ROWS *data;
+ MEM_ROOT alloc;
+} MYSQL_DATA;
+
+struct st_mysql_options {
+ unsigned int connect_timeout,client_flag;
+ my_bool compress,named_pipe;
+ unsigned int port;
+ char *host,*init_command,*user,*password,*unix_socket,*db;
+ char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
+ my_bool use_ssl; /* if to use SSL or not */
+ char *ssl_key; /* PEM key file */
+ char *ssl_cert; /* PEM cert file */
+ char *ssl_ca; /* PEM CA file */
+ char *ssl_capath; /* PEM directory of CA-s? */
+};
+
+enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
+ MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND,
+ MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
+ MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME};
+
+enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
+ MYSQL_STATUS_USE_RESULT};
+
+typedef struct st_mysql {
+ NET net; /* Communication parameters */
+ gptr connector_fd; /* ConnectorFd for SSL */
+ char *host,*user,*passwd,*unix_socket,*server_version,*host_info,
+ *info,*db;
+ unsigned int port,client_flag,server_capabilities;
+ unsigned int protocol_version;
+ unsigned int field_count;
+ unsigned int server_status;
+ unsigned long thread_id; /* Id for connection in server */
+ my_ulonglong affected_rows;
+ my_ulonglong insert_id; /* id if insert on table with NEXTNR */
+ my_ulonglong extra_info; /* Used by mysqlshow */
+ unsigned long packet_length;
+ enum mysql_status status;
+ MYSQL_FIELD *fields;
+ MEM_ROOT field_alloc;
+ my_bool free_me; /* If free in mysql_close */
+ my_bool reconnect; /* set to 1 if automatic reconnect */
+ struct st_mysql_options options;
+ char scramble_buff[9];
+ struct charset_info_st *charset;
+ unsigned int server_language;
+} MYSQL;
+
+
+typedef struct st_mysql_res {
+ my_ulonglong row_count;
+ unsigned int field_count, current_field;
+ MYSQL_FIELD *fields;
+ MYSQL_DATA *data;
+ MYSQL_ROWS *data_cursor;
+ MEM_ROOT field_alloc;
+ MYSQL_ROW row; /* If unbuffered read */
+ MYSQL_ROW current_row; /* buffer to current row */
+ unsigned long *lengths; /* column lengths of current row */
+ MYSQL *handle; /* for unbuffered reads */
+ my_bool eof; /* Used my mysql_fetch_row */
+} MYSQL_RES;
+
+/* Functions to get information from the MYSQL and MYSQL_RES structures */
+/* Should definitely be used if one uses shared libraries */
+
+my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);
+unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
+my_bool STDCALL mysql_eof(MYSQL_RES *res);
+MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res,
+ unsigned int fieldnr);
+MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res);
+MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res);
+unsigned int STDCALL mysql_field_tell(MYSQL_RES *res);
+
+unsigned int STDCALL mysql_field_count(MYSQL *mysql);
+my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
+my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
+unsigned int STDCALL mysql_errno(MYSQL *mysql);
+char * STDCALL mysql_error(MYSQL *mysql);
+char * STDCALL mysql_info(MYSQL *mysql);
+unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
+const char * STDCALL mysql_character_set_name(MYSQL *mysql);
+
+MYSQL * STDCALL mysql_init(MYSQL *mysql);
+#ifdef HAVE_OPENSSL
+int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
+ const char *cert, const char *ca,
+ const char *capath);
+char * STDCALL mysql_ssl_cipher(MYSQL *mysql);
+int STDCALL mysql_ssl_clear(MYSQL *mysql);
+#endif /* HAVE_OPENSSL */
+MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
+ const char *user, const char *passwd);
+my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
+ const char *passwd, const char *db);
+#if MYSQL_VERSION_ID >= 32200
+MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
+ const char *user,
+ const char *passwd,
+ const char *db,
+ unsigned int port,
+ const char *unix_socket,
+ unsigned int clientflag);
+#else
+MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
+ const char *user,
+ const char *passwd,
+ unsigned int port,
+ const char *unix_socket,
+ unsigned int clientflag);
+#endif
+void STDCALL mysql_close(MYSQL *sock);
+int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
+int STDCALL mysql_query(MYSQL *mysql, const char *q);
+int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
+ unsigned int length);
+int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
+int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
+int STDCALL mysql_shutdown(MYSQL *mysql);
+int STDCALL mysql_dump_debug_info(MYSQL *mysql);
+int STDCALL mysql_refresh(MYSQL *mysql,
+ unsigned int refresh_options);
+int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
+int STDCALL mysql_ping(MYSQL *mysql);
+char * STDCALL mysql_stat(MYSQL *mysql);
+char * STDCALL mysql_get_server_info(MYSQL *mysql);
+char * STDCALL mysql_get_client_info(void);
+char * STDCALL mysql_get_host_info(MYSQL *mysql);
+unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql);
+MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
+MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
+MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
+ const char *wild);
+MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql);
+MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
+MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
+int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
+ const char *arg);
+void STDCALL mysql_free_result(MYSQL_RES *result);
+void STDCALL mysql_data_seek(MYSQL_RES *result,
+ my_ulonglong offset);
+MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET);
+MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
+ MYSQL_FIELD_OFFSET offset);
+MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
+unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result);
+MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result);
+unsigned long STDCALL mysql_escape_string(char *to,const char *from,
+ unsigned long from_length);
+unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
+ char *to,const char *from,
+ unsigned long length);
+void STDCALL mysql_debug(const char *debug);
+char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
+ char *to,
+ unsigned long to_length,
+ const char *from,
+ unsigned long from_length,
+ void *param,
+ char *
+ (*extend_buffer)
+ (void *, char *to,
+ unsigned long *length));
+void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
+unsigned int STDCALL mysql_thread_safe(void);
+
+
+#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
+
+/* new api functions */
+
+#define HAVE_MYSQL_REAL_CONNECT
+
+#ifndef MYSQL_SERVER
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
diff --git a/VC++Files/winmysqladmin/mysql_com.h b/VC++Files/winmysqladmin/mysql_com.h
new file mode 100644
index 00000000000..2a1471f735d
--- /dev/null
+++ b/VC++Files/winmysqladmin/mysql_com.h
@@ -0,0 +1,242 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA */
+
+/*
+** Common definition between mysql server & client
+*/
+
+#ifndef _mysql_com_h
+#define _mysql_com_h
+
+
+#define NAME_LEN 64 /* Field/table name length */
+#define HOSTNAME_LENGTH 60
+#define USERNAME_LENGTH 16
+
+#define LOCAL_HOST "localhost"
+#define LOCAL_HOST_NAMEDPIPE "."
+
+#if defined(__EMX__) || defined(__OS2__)
+#undef MYSQL_UNIX_ADDR
+#define MYSQL_OS2_ADDR "\\socket\\MySQL"
+#define MYSQL_UNIX_ADDR MYSQL_OS2_ADDR
+#endif
+#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
+#define MYSQL_NAMEDPIPE "MySQL"
+#define MYSQL_SERVICENAME "MySql"
+#endif /* __WIN__ */
+
+enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
+ COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,COM_REFRESH,
+ COM_SHUTDOWN,COM_STATISTICS,
+ COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
+ COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
+ COM_CHANGE_USER, COM_BINLOG_DUMP,
+ COM_TABLE_DUMP};
+
+#define NOT_NULL_FLAG 1 /* Field can't be NULL */
+#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
+#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */
+#define MULTIPLE_KEY_FLAG 8 /* Field is part of a key */
+#define BLOB_FLAG 16 /* Field is a blob */
+#define UNSIGNED_FLAG 32 /* Field is unsigned */
+#define ZEROFILL_FLAG 64 /* Field is zerofill */
+#define BINARY_FLAG 128
+/* The following are only sent to new clients */
+#define ENUM_FLAG 256 /* field is an enum */
+#define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */
+#define TIMESTAMP_FLAG 1024 /* Field is a timestamp */
+#define SET_FLAG 2048 /* field is a set */
+#define PART_KEY_FLAG 16384 /* Intern; Part of some key */
+#define GROUP_FLAG 32768 /* Intern: Group field */
+#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */
+
+#define REFRESH_GRANT 1 /* Refresh grant tables */
+#define REFRESH_LOG 2 /* Start on new log file */
+#define REFRESH_TABLES 4 /* close all tables */
+#define REFRESH_HOSTS 8 /* Flush host cache */
+#define REFRESH_STATUS 16 /* Flush status variables */
+#define REFRESH_THREADS 32 /* Flush status variables */
+#define REFRESH_SLAVE 64 /* Reset master info and restart slave
+ thread */
+#define REFRESH_MASTER 128 /* Remove all bin logs in the index
+ and truncate the index */
+
+/* The following can't be set with mysql_refresh() */
+#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
+#define REFRESH_FAST 32768 /* Intern flag */
+
+#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
+#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
+#define CLIENT_LONG_FLAG 4 /* Get all column flags */
+#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */
+#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */
+#define CLIENT_COMPRESS 32 /* Can use compression protocol */
+#define CLIENT_ODBC 64 /* Odbc client */
+#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */
+#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */
+#define CLIENT_CHANGE_USER 512 /* Support the mysql_change_user() */
+#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */
+#define CLIENT_SSL 2048 /* Switch to SSL after handshake */
+#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */
+#define CLIENT_TRANSACTIONS 8196 /* Client knows about transactions */
+
+#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
+#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
+
+#define MYSQL_ERRMSG_SIZE 200
+#define NET_READ_TIMEOUT 30 /* Timeout on read */
+#define NET_WRITE_TIMEOUT 60 /* Timeout on write */
+#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
+
+#ifndef Vio_defined
+#define Vio_defined
+#ifdef HAVE_VIO
+class Vio; /* Fill Vio class in C++ */
+#else
+struct st_vio; /* Only C */
+typedef struct st_vio Vio;
+#endif
+#endif
+
+typedef struct st_net {
+ Vio* vio;
+ my_socket fd; /* For Perl DBI/dbd */
+ int fcntl;
+ unsigned char *buff,*buff_end,*write_pos,*read_pos;
+ char last_error[MYSQL_ERRMSG_SIZE];
+ unsigned int last_errno,max_packet,timeout,pkt_nr;
+ unsigned char error;
+ my_bool return_errno,compress;
+ my_bool no_send_ok; /* needed if we are doing several
+ queries in one command ( as in LOAD TABLE ... FROM MASTER ),
+ and do not want to confuse the client with OK at the wrong time
+ */
+ unsigned long remain_in_buf,length, buf_length, where_b;
+ unsigned int *return_status;
+ unsigned char reading_or_writing;
+ char save_char;
+} NET;
+
+#define packet_error ((unsigned int) -1)
+
+enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG,
+ FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE,
+ FIELD_TYPE_NULL, FIELD_TYPE_TIMESTAMP,
+ FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24,
+ FIELD_TYPE_DATE, FIELD_TYPE_TIME,
+ FIELD_TYPE_DATETIME, FIELD_TYPE_YEAR,
+ FIELD_TYPE_NEWDATE,
+ FIELD_TYPE_ENUM=247,
+ FIELD_TYPE_SET=248,
+ FIELD_TYPE_TINY_BLOB=249,
+ FIELD_TYPE_MEDIUM_BLOB=250,
+ FIELD_TYPE_LONG_BLOB=251,
+ FIELD_TYPE_BLOB=252,
+ FIELD_TYPE_VAR_STRING=253,
+ FIELD_TYPE_STRING=254
+};
+
+#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */
+#define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */
+
+extern unsigned long max_allowed_packet;
+extern unsigned long net_buffer_length;
+
+#define net_new_transaction(net) ((net)->pkt_nr=0)
+
+int my_net_init(NET *net, Vio* vio);
+void net_end(NET *net);
+void net_clear(NET *net);
+int net_flush(NET *net);
+int my_net_write(NET *net,const char *packet,unsigned long len);
+int net_write_command(NET *net,unsigned char command,const char *packet,
+ unsigned long len);
+int net_real_write(NET *net,const char *packet,unsigned long len);
+unsigned int my_net_read(NET *net);
+
+struct rand_struct {
+ unsigned long seed1,seed2,max_value;
+ double max_value_dbl;
+};
+
+ /* The following is for user defined functions */
+
+enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT};
+
+typedef struct st_udf_args
+{
+ unsigned int arg_count; /* Number of arguments */
+ enum Item_result *arg_type; /* Pointer to item_results */
+ char **args; /* Pointer to argument */
+ unsigned long *lengths; /* Length of string arguments */
+ char *maybe_null; /* Set to 1 for all maybe_null args */
+} UDF_ARGS;
+
+ /* This holds information about the result */
+
+typedef struct st_udf_init
+{
+ my_bool maybe_null; /* 1 if function can return NULL */
+ unsigned int decimals; /* for real functions */
+ unsigned int max_length; /* For string functions */
+ char *ptr; /* free pointer for function data */
+ my_bool const_item; /* 0 if result is independent of arguments */
+} UDF_INIT;
+
+ /* Constants when using compression */
+#define NET_HEADER_SIZE 4 /* standard header size */
+#define COMP_HEADER_SIZE 3 /* compression header extra size */
+
+ /* Prototypes to password functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void randominit(struct rand_struct *,unsigned long seed1,
+ unsigned long seed2);
+double rnd(struct rand_struct *);
+void make_scrambled_password(char *to,const char *password);
+void get_salt_from_password(unsigned long *res,const char *password);
+void make_password_from_salt(char *to, unsigned long *hash_res);
+char *scramble(char *to,const char *message,const char *password,
+ my_bool old_ver);
+my_bool check_scramble(const char *, const char *message,
+ unsigned long *salt,my_bool old_ver);
+char *get_tty_password(char *opt_message);
+void hash_password(unsigned long *result, const char *password);
+#ifdef __cplusplus
+}
+#endif
+
+/* Some other useful functions */
+
+void my_init(void);
+void load_defaults(const char *conf_file, const char **groups,
+ int *argc, char ***argv);
+
+#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */
+
+#ifdef __WIN__
+#define socket_errno WSAGetLastError()
+#else
+#define socket_errno errno
+#endif
+
+#endif
diff --git a/VC++Files/winmysqladmin/mysql_version.h b/VC++Files/winmysqladmin/mysql_version.h
new file mode 100644
index 00000000000..1f868704fe8
--- /dev/null
+++ b/VC++Files/winmysqladmin/mysql_version.h
@@ -0,0 +1,20 @@
+/* Copyright Abandoned 1996,1999 TCX DataKonsult AB & Monty Program KB & Detron HB
+ This file is public domain and comes with NO WARRANTY of any kind */
+
+/* Version numbers for protocol & mysqld */
+
+#ifdef _CUSTOMCONFIG_
+ #include <custom_conf.h>
+#else
+#define PROTOCOL_VERSION 10
+#define MYSQL_SERVER_VERSION "3.23.22-beta"
+#define FRM_VER 6
+#define MYSQL_VERSION_ID 32322
+#define MYSQL_PORT 3306
+#define MYSQL_UNIX_ADDR "/tmp/mysql.sock"
+
+/* mysqld compile time options */
+#ifndef MYSQL_CHARSET
+#define MYSQL_CHARSET "latin1"
+#endif
+#endif
diff --git a/VC++Files/winmysqladmin/winmysqladmin.cpp b/VC++Files/winmysqladmin/winmysqladmin.cpp
new file mode 100644
index 00000000000..591b7518fa3
--- /dev/null
+++ b/VC++Files/winmysqladmin/winmysqladmin.cpp
@@ -0,0 +1,38 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+HINSTANCE g_hinst;
+USERES("winmysqladmin.res");
+USEFORM("main.cpp", Form1);
+USEFORM("initsetup.cpp", Form2);
+USEFORM("db.cpp", dbfrm);
+USELIB("lib\mysqlclient.lib");
+USELIB("lib\myisammrg.lib");
+USELIB("lib\heap.lib");
+USELIB("lib\isam.lib");
+USELIB("lib\merge.lib");
+USELIB("lib\myisam.lib");
+USELIB("lib\mysys.lib");
+USELIB("lib\regex.lib");
+USELIB("lib\strings.lib");
+USELIB("lib\zlib.lib");
+//---------------------------------------------------------------------------
+WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
+{
+ try
+ {
+ Application->Initialize();
+ Application->HelpFile = "C:\\mysql\\bin\\WINMYSQLADMIN.HLP";
+ Application->Title = "WinMySQLadmin 1.0";
+ Application->CreateForm(__classid(TForm1), &Form1);
+ Application->CreateForm(__classid(TForm2), &Form2);
+ Application->CreateForm(__classid(Tdbfrm), &dbfrm);
+ Application->Run();
+ }
+ catch (Exception &exception)
+ {
+ Application->ShowException(&exception);
+ }
+ return 0;
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/zlib/contrib/asm386/zlibvc.dsp b/VC++Files/zlib/contrib/asm386/zlibvc.dsp
new file mode 100644
index 00000000000..a70d4d4a6b0
--- /dev/null
+++ b/VC++Files/zlib/contrib/asm386/zlibvc.dsp
@@ -0,0 +1,651 @@
+# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602
+
+CFG=zlibvc - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zlibvc.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\
+ "Win32 (ALPHA) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\
+ "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\
+ "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\Release"
+# PROP BASE Intermediate_Dir ".\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\Release"
+# PROP Intermediate_Dir ".\Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\Debug"
+# PROP BASE Intermediate_Dir ".\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\Debug"
+# PROP Intermediate_Dir ".\Debug"
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "_DEBUG"
+# ADD RSC /l 0x40c /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlibvc__"
+# PROP BASE Intermediate_Dir "zlibvc__"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zlibvc__"
+# PROP Intermediate_Dir "zlibvc__"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
+# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlibvc_0"
+# PROP BASE Intermediate_Dir "zlibvc_0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zlibvc_0"
+# PROP Intermediate_Dir "zlibvc_0"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlibvc_1"
+# PROP BASE Intermediate_Dir "zlibvc_1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zlibvc_1"
+# PROP Intermediate_Dir "zlibvc_1"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "zlibvc - Win32 Release"
+# Name "zlibvc - Win32 Debug"
+# Name "zlibvc - Win32 ReleaseAxp"
+# Name "zlibvc - Win32 ReleaseWithoutAsm"
+# Name "zlibvc - Win32 ReleaseWithoutCrtdll"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\adler32.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_ADLER=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\compress.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_COMPR=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\crc32.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_CRC32=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\deflate.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_DEFLA=\
+ ".\deflate.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\gvmat32c.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\gzio.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_GZIO_=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\infblock.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFBL=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\infcodes.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFCO=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inffast.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\inffast.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFFA=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inffast.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\inflate.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFLA=\
+ ".\infblock.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\inftrees.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFTR=\
+ ".\inftrees.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\infutil.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFUT=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\trees.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_TREES=\
+ ".\deflate.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\uncompr.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_UNCOM=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\unzip.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\zip.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlib.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlibvc.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\zutil.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_ZUTIL=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# Begin Source File
+
+SOURCE=.\deflate.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infblock.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infcodes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inffast.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inftrees.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infutil.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zconf.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zutil.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/zlib/contrib/asm386/zlibvc.dsw b/VC++Files/zlib/contrib/asm386/zlibvc.dsw
new file mode 100644
index 00000000000..493cd870365
--- /dev/null
+++ b/VC++Files/zlib/contrib/asm386/zlibvc.dsw
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/zlib/zlib.dsp b/VC++Files/zlib/zlib.dsp
new file mode 100644
index 00000000000..b46afad005c
--- /dev/null
+++ b/VC++Files/zlib/zlib.dsp
@@ -0,0 +1,185 @@
+# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=zlib - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zlib - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "zlib - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "zlib - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\zlib.lib"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Zi /Od /D "_DEBUG" /D "__WIN32__" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\zlib.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "zlib - Win32 Release"
+# Name "zlib - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\adler32.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\deflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\deflate.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\gzio.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\infblock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\infblock.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infcodes.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\infcodes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inffast.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\inffast.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inffixed.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\inftrees.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\inftrees.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infutil.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\infutil.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\trees.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\trees.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\uncompr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\zconf.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zutil.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\zutil.h
+# End Source File
+# End Target
+# End Project
diff --git a/acconfig.h b/acconfig.h
index 3cea5bf4b73..f52c38b2fdc 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -91,6 +91,9 @@
/* Using Innobase DB */
#undef HAVE_INNOBASE_DB
+/* Using old ISAM tables */
+#undef HAVE_ISAM
+
/* Define if we have GNU readline */
#undef HAVE_LIBREADLINE
@@ -121,6 +124,9 @@
/* sigwait with one argument */
#undef HAVE_NONPOSIX_SIGWAIT
+/* ORBIT */
+#undef HAVE_ORBIT
+
/* pthread_attr_setscope */
#undef HAVE_PTHREAD_ATTR_SETSCOPE
@@ -142,6 +148,9 @@
/* crypt */
#undef HAVE_CRYPT
+/* If we want to have query cache */
+#undef HAVE_QUERY_CACHE
+
/* Solaris define gethostbyaddr_r with 7 arguments. glibc2 defines
this with 8 arguments */
#undef HAVE_SOLARIS_STYLE_GETHOST
@@ -170,9 +179,15 @@
/* new UNIXWARE7 threads that are not yet posix */
#undef HAVE_UNIXWARE7_POSIX
+/* OpenSSL */
+#undef HAVE_OPENSSL
+
/* READLINE: */
#undef HAVE_USG_SIGHOLD
+/* Virtual IO */
+#undef HAVE_VIO
+
/* Handling of large files on Solaris 2.6 */
#undef _LARGEFILE_SOURCE
@@ -248,6 +263,9 @@
#undef USE_MB
#undef USE_MB_IDENT
+/* the pstack backtrace library */
+#undef USE_PSTACK
+
/* Use MySQL RAID */
#undef USE_RAID
diff --git a/acinclude.m4 b/acinclude.m4
index b8d46b25db2..2b6c8cbc390 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -634,6 +634,209 @@ fi
AC_MSG_RESULT($ac_cv_conv_longlong_to_float)
])
+AC_DEFUN(MYSQL_CHECK_CPU,
+[AC_CACHE_CHECK([if compiler supports optimizations for current cpu],
+mysql_cv_cpu,[
+
+ac_save_CFLAGS="$CFLAGS"
+if test -r /proc/cpuinfo ; then
+ cpuinfo="cat /proc/cpuinfo"
+ cpu_family=`$cpuinfo | grep 'cpu family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+ cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+fi
+if test "$cpu_vendor" = "AuthenticAMD"; then
+ if test $cpu_family -ge 6; then
+ cpu_set="athlon pentiumpro k5 pentium i486 i386";
+ elif test $cpu_family -eq 5; then
+ cpu_set="k5 pentium i486 i386";
+ elif test $cpu_family -eq 4; then
+ cpu_set="i486 i386"
+ else
+ cpu_set="i386"
+ fi
+elif test "$cpu_vendor" = "GenuineIntel"; then
+ if test $cpu_family -ge 6; then
+ cpu_set="pentiumpro pentium i486 i386";
+ elif test $cpu_family -eq 5; then
+ cpu_set="pentium i486 i386";
+ elif test $cpu_family -eq 4; then
+ cpu_set="i486 i386"
+ else
+ cpu_set="i386"
+ fi
+fi
+
+for ac_arg in $cpu_set;
+do
+ CFLAGS="$ac_save_CFLAGS -mcpu=$ac_arg -march=$ac_arg -DCPU=$ac_arg"
+ AC_TRY_COMPILE([],[int i],mysql_cv_cpu=$ac_arg; break;, mysql_cv_cpu="unknown")
+done
+
+if test "$mysql_cv_cpu" = "unknown"
+then
+ CFLAGS="$ac_save_CFLAGS"
+ AC_MSG_RESULT(none)
+else
+ AC_MSG_RESULT($mysql_cv_cpu)
+fi
+]]))
+
+AC_DEFUN(MYSQL_CHECK_VIO, [
+ AC_ARG_WITH([vio],
+ [ --with-vio Include the Virtual IO support],
+ [vio="$withval"],
+ [vio=no])
+
+ if test "$vio" = "yes"
+ then
+ vio_dir="vio"
+ vio_libs="../vio/libvio.la"
+ AC_DEFINE(HAVE_VIO)
+ else
+ vio_dir=""
+ vio_libs=""
+ fi
+ AC_SUBST([vio_dir])
+ AC_SUBST([vio_libs])
+])
+
+AC_DEFUN(MYSQL_FIND_OPENSSL, [
+ for d in /usr/ssl/include /usr/local/ssl/include /usr/include/openssl \
+/usr/include/ssl /opt/ssl/include /opt/openssl/include \
+/usr/local/ssl/include/openssl /usr/local/include/openssl ; do
+ if test -f $d/ssl.h ; then
+ OPENSSL_INCLUDE=$d
+ fi
+ done
+
+ for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
+/usr/lib /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do
+ if test -f $d/libssl.a ; then
+ OPENSSL_LIB=$d
+ fi
+ done
+
+ if test -z "$OPENSSL_LIB" -o -z "$OPENSSL_INCLUDE" ; then
+ echo "Could not find an installation of OpenSSL"
+ if test -n "$OPENSSL_LIB" ; then
+ if test "$IS_LINUX" = "true"; then
+ echo "Looks like you've forgotted to install OpenSSL development RPM"
+ fi
+ fi
+ exit 1
+ fi
+
+])
+
+AC_DEFUN(MYSQL_CHECK_OPENSSL, [
+AC_MSG_CHECKING(for OpenSSL)
+ AC_ARG_WITH([openssl],
+ [ --with-openssl Include the OpenSSL support],
+ [openssl="$withval"],
+ [openssl=no])
+
+ openssl_libs=""
+ openssl_includes=""
+ if test "$openssl" = "yes"
+ then
+ MYSQL_FIND_OPENSSL
+ #force VIO use
+ vio_dir="vio"
+ vio_libs="../vio/libvio.la"
+ AC_DEFINE(HAVE_VIO)
+ AC_MSG_RESULT(yes)
+ openssl_libs="-L$OPENSSL_LIB -lssl -lcrypto"
+ openssl_includes="-I$OPENSSL_INCLUDE"
+ AC_DEFINE(HAVE_OPENSSL)
+
+ # openssl-devel-0.9.6 requires dlopen() and we can't link staticly
+ # on many platforms (We should actually test this here, but it's quite
+ # hard) to do as we are doing libtool for linking.
+ using_static=""
+ case "$CLIENT_EXTRA_LDFLAGS $MYSQLD_EXTRA_LDFLAGS" in
+ *-all-static*) using_static="yes" ;;
+ esac
+ if test $using_static = "yes"
+ then
+ echo "You can't use the --all-static link option when using openssl."
+ exit 1
+ fi
+ AC_MSG_RESULT(no)
+ fi
+ NON_THREADED_CLIENT_LIBS="$NON_THREADED_CLIENT_LIBS $openssl_libs"
+ AC_SUBST(openssl_libs)
+ AC_SUBST(openssl_includes)
+])
+
+
+AC_DEFUN(MYSQL_CHECK_MYSQLFS, [
+ AC_ARG_WITH([mysqlfs],
+ [
+ --with-mysqlfs Include the corba-based MySQL file system],
+ [mysqlfs="$withval"],
+ [mysqlfs=no])
+
+dnl Call MYSQL_CHECK_ORBIT even if mysqlfs == no, so that @orbit_*@
+dnl get substituted.
+ MYSQL_CHECK_ORBIT
+
+ AC_MSG_CHECKING(if we should build MySQLFS)
+ fs_dirs=""
+ if test "$mysqlfs" = "yes"
+ then
+ if test -n "$orbit_exec_prefix"
+ then
+ fs_dirs=fs
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT(disabled because ORBIT, the CORBA ORB, was not found)
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+ AC_SUBST([fs_dirs])
+])
+
+AC_DEFUN(MYSQL_CHECK_ORBIT, [
+AC_MSG_CHECKING(for ORBit)
+orbit_config_path=`which orbit-config`
+if test -n "$orbit_config_path"
+then
+ orbit_exec_prefix=`orbit-config --exec-prefix`
+ orbit_includes=`orbit-config --cflags server`
+ orbit_libs=`orbit-config --libs server`
+ orbit_idl="$orbit_exec_prefix/bin/orbit-idl"
+ AC_MSG_RESULT(found!)
+ AC_DEFINE(HAVE_ORBIT)
+else
+ orbit_exec_prefix=
+ orbit_includes=
+ orbit_libs=
+ orbit_idl=
+ AC_MSG_RESULT(not found)
+fi
+AC_SUBST(orbit_includes)
+AC_SUBST(orbit_libs)
+AC_SUBST(orbit_idl)
+])
+
+AC_DEFUN([MYSQL_CHECK_ISAM], [
+ AC_ARG_WITH([isam], [
+ --without-isam Disable the ISAM table type],
+ [with_isam="$withval"],
+ [with_isam=yes])
+
+ isam_libs=
+ if test X"$with_isam" = X"yes"
+ then
+ AC_DEFINE(HAVE_ISAM)
+ isam_libs="\$(top_builddir)/isam/libnisam.a\
+ \$(top_builddir)/merge/libmerge.a"
+ fi
+ AC_SUBST(isam_libs)
+])
+
+
dnl ---------------------------------------------------------------------------
dnl Macro: MYSQL_CHECK_BDB
dnl Sets HAVE_BERKELEY_DB if inst library is found
@@ -906,9 +1109,9 @@ dnl ---------------------------------------------------------------------------
AC_DEFUN([MYSQL_CHECK_INNODB], [
AC_ARG_WITH([innodb],
[
- --with-innodb Use Innodb],
+ --without-innodb Do not include the InnoDB table handler],
[innodb="$withval"],
- [innodb=no])
+ [innodb=yes])
AC_MSG_CHECKING([for Innodb])
@@ -979,48 +1182,7 @@ dnl END OF MYSQL_CHECK_INNODB SECTION
dnl ---------------------------------------------------------------------------
dnl ---------------------------------------------------------------------------
-dnl Macro: MYSQL_CHECK_GEMINI
-dnl Sets HAVE_GEMINI_DB if --with-gemini is used
-dnl ---------------------------------------------------------------------------
-
-AC_DEFUN([MYSQL_CHECK_GEMINI], [
- AC_ARG_WITH([gemini],
- [
- --with-gemini[=DIR] Use Gemini DB located in DIR],
- [gemini="$withval"],
- [gemini=no])
-
- AC_MSG_CHECKING([for Gemini DB])
-dnl SORT OUT THE SUPPLIED ARGUMENTS TO DETERMINE WHAT TO DO
-dnl echo "DBG_GEM1: gemini='$gemini'"
- have_gemini_db=no
- gemini_includes=
- gemini_libs=
- case "$gemini" in
- no)
- AC_MSG_RESULT([Not using Gemini DB])
- ;;
- yes | default | *)
- have_gemini_db="yes"
- gemini_includes="-I../gemini/incl -I../gemini"
- gemini_libs="\
- ../gemini/api/libapi.a\
- ../gemini/db/libdb.a\
- ../gemini/dbut/libdbut.a"
- AC_MSG_RESULT([Using Gemini DB])
- ;;
- esac
-
- AC_SUBST(gemini_includes)
- AC_SUBST(gemini_libs)
-])
-
-dnl ---------------------------------------------------------------------------
-dnl END OF MYSQL_CHECK_GEMINI SECTION
-dnl ---------------------------------------------------------------------------
-
-dnl ---------------------------------------------------------------------------
dnl Got this from the GNU tar 1.13.11 distribution
dnl by Paul Eggert <eggert@twinsun.com>
dnl ---------------------------------------------------------------------------
@@ -1048,10 +1210,12 @@ AC_DEFUN(AC_SYS_LARGEFILE_FLAGS,
changequote(, )dnl
hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
changequote([, ])dnl
- if test "$GCC" = yes; then
- ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__
- fi
- ;;
+ if test "$GCC" = yes; then
+ if $CC -v 2>&1 | grep 'version 2.95' > /dev/null 2>&1; then
+ ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__
+ fi
+ fi
+ ;;
# IRIX 6.2 and later require cc -n32.
changequote(, )dnl
irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*)
diff --git a/bdb/include/btree_ext.h b/bdb/include/btree_ext.h
deleted file mode 100644
index 8a9866e0b5a..00000000000
--- a/bdb/include/btree_ext.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _btree_ext_h_
-#define _btree_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __bam_cmp __P((DB *, const DBT *, PAGE *,
- u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *));
-int __bam_defcmp __P((DB *, const DBT *, const DBT *));
-size_t __bam_defpfx __P((DB *, const DBT *, const DBT *));
-int __bam_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __bam_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __bam_mswap __P((PAGE *));
-void __bam_cprint __P((DBC *));
-int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int));
-int __ram_ca_delete __P((DB *, db_pgno_t));
-int __bam_ca_di __P((DBC *, db_pgno_t, u_int32_t, int));
-int __bam_ca_dup __P((DBC *,
- u_int32_t, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t));
-int __bam_ca_undodup __P((DB *,
- u_int32_t, db_pgno_t, u_int32_t, u_int32_t));
-int __bam_ca_rsplit __P((DBC *, db_pgno_t, db_pgno_t));
-int __bam_ca_split __P((DBC *,
- db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int));
-void __bam_ca_undosplit __P((DB *,
- db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t));
-int __bam_c_init __P((DBC *, DBTYPE));
-int __bam_c_refresh __P((DBC *));
-int __bam_c_count __P((DBC *, db_recno_t *));
-int __bam_c_dup __P((DBC *, DBC *));
-int __bam_c_rget __P((DBC *, DBT *, u_int32_t));
-int __bam_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-int __bam_ditem __P((DBC *, PAGE *, u_int32_t));
-int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int));
-int __bam_dpages __P((DBC *, EPG *));
-int __bam_db_create __P((DB *));
-int __bam_db_close __P((DB *));
-int __bam_set_flags __P((DB *, u_int32_t *flagsp));
-int __ram_set_flags __P((DB *, u_int32_t *flagsp));
-int __bam_open __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __bam_metachk __P((DB *, const char *, BTMETA *));
-int __bam_read_root __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __bam_iitem __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t));
-u_int32_t __bam_partsize __P((u_int32_t, DBT *, PAGE *, u_int32_t));
-int __bam_build __P((DBC *, u_int32_t,
- DBT *, PAGE *, u_int32_t, u_int32_t));
-int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *));
-int __bam_pg_alloc_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_pg_free_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_split_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_rsplit_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_adj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_cadjust_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_cdel_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_repl_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_root_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_curadj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_rcuradj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_reclaim __P((DB *, DB_TXN *));
-int __ram_open __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __ram_c_del __P((DBC *));
-int __ram_c_get
- __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
-int __ram_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
-int __ram_ca __P((DBC *, ca_recno_arg));
-int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int));
-int __ram_writeback __P((DB *));
-int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *));
-int __bam_adjust __P((DBC *, int32_t));
-int __bam_nrecs __P((DBC *, db_recno_t *));
-db_recno_t __bam_total __P((PAGE *));
-int __bam_search __P((DBC *,
- const DBT *, u_int32_t, int, db_recno_t *, int *));
-int __bam_stkrel __P((DBC *, u_int32_t));
-int __bam_stkgrow __P((DB_ENV *, BTREE_CURSOR *));
-int __bam_split __P((DBC *, void *));
-int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t));
-int __bam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
-int __bam_traverse __P((DBC *, db_lockmode_t,
- db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *));
-int __bam_stat_callback __P((DB *, PAGE *, void *, int *));
-int __bam_key_range __P((DB *,
- DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
-int __bam_30_btreemeta __P((DB *, char *, u_int8_t *));
-int __bam_31_btreemeta
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __bam_31_lbtree
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *,
- db_pgno_t, u_int32_t));
-int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
- u_int32_t));
-int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
- u_int32_t));
-int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, PAGE *,
- db_pgno_t, u_int32_t, int, int, u_int32_t));
-int __bam_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t,
- u_int32_t));
-int __bam_vrfy_subtree __P((DB *, VRFY_DBINFO *, db_pgno_t, void *,
- void *, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *));
-int __bam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t,
- PAGE *, void *, int (*)(void *, const void *), DBT *,
- u_int32_t));
-int __bam_salvage_walkdupint __P((DB *, VRFY_DBINFO *, PAGE *,
- DBT *, void *, int (*)(void *, const void *), u_int32_t));
-int __bam_meta2pgset __P((DB *, VRFY_DBINFO *, BTMETA *,
- u_int32_t, DB *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _btree_ext_h_ */
diff --git a/bdb/include/clib_ext.h b/bdb/include/clib_ext.h
deleted file mode 100644
index efd0796afe3..00000000000
--- a/bdb/include/clib_ext.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _clib_ext_h_
-#define _clib_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-#ifndef HAVE_GETCWD
-char *getcwd __P((char *, size_t));
-#endif
-#ifndef HAVE_GETOPT
-int getopt __P((int, char * const *, const char *));
-#endif
-#ifndef HAVE_MEMCMP
-int memcmp __P((const void *, const void *, size_t));
-#endif
-#ifndef HAVE_MEMCPY
-void *memcpy __P((void *, const void *, size_t));
-#endif
-#ifndef HAVE_MEMMOVE
-void *memmove __P((void *, const void *, size_t));
-#endif
-#ifndef HAVE_RAISE
-int raise __P((int));
-#endif
-#ifndef HAVE_SNPRINTF
-int snprintf __P((char *, size_t, const char *, ...));
-#endif
-int strcasecmp __P((const char *, const char *));
-#ifndef HAVE_STRERROR
-char *strerror __P((int));
-#endif
-#ifndef HAVE_VSNPRINTF
-int vsnprintf();
-#endif
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _clib_ext_h_ */
diff --git a/bdb/include/common_ext.h b/bdb/include/common_ext.h
deleted file mode 100644
index a36d62cac4a..00000000000
--- a/bdb/include/common_ext.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _common_ext_h_
-#define _common_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __db_byteorder __P((DB_ENV *, int));
-int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
-int __db_fcchk
- __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
-int __db_ferr __P((const DB_ENV *, const char *, int));
-int __db_pgerr __P((DB *, db_pgno_t));
-int __db_pgfmt __P((DB *, db_pgno_t));
-int __db_eopnotsup __P((const DB_ENV *));
-#ifdef DIAGNOSTIC
-void __db_assert __P((const char *, const char *, int));
-#endif
-int __db_panic_msg __P((DB_ENV *));
-int __db_panic __P((DB_ENV *, int));
-void __db_err __P((const DB_ENV *, const char *, ...));
-void __db_real_err
- __P((const DB_ENV *, int, int, int, const char *, va_list));
-void __db_logmsg __P((const DB_ENV *,
- DB_TXN *, const char *, u_int32_t, const char *, ...));
-void __db_real_log __P((const DB_ENV *,
- DB_TXN *, const char *, u_int32_t, const char *, va_list ap));
-int __db_unknown_flag __P((DB_ENV *, char *, u_int32_t));
-int __db_unknown_type __P((DB_ENV *, char *, u_int32_t));
-#ifdef DIAGNOSTIC
-int __db_missing_txn_err __P((DB_ENV *));
-#endif
-int __db_getlong
- __P((DB *, const char *, char *, long, long, long *));
-int __db_getulong
- __P((DB *, const char *, char *, u_long, u_long, u_long *));
-u_int32_t __db_log2 __P((u_int32_t));
-int __db_util_logset __P((const char *, char *));
-void __db_util_siginit __P((void));
-int __db_util_interrupted __P((void));
-void __db_util_sigresend __P((void));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _common_ext_h_ */
diff --git a/bdb/include/env_ext.h b/bdb/include/env_ext.h
deleted file mode 100644
index 0e7313fde9d..00000000000
--- a/bdb/include/env_ext.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _env_ext_h_
-#define _env_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-void __db_shalloc_init __P((void *, size_t));
-int __db_shalloc_size __P((size_t, size_t));
-int __db_shalloc __P((void *, size_t, size_t, void *));
-void __db_shalloc_free __P((void *, void *));
-size_t __db_shalloc_count __P((void *));
-size_t __db_shsizeof __P((void *));
-void __db_shalloc_dump __P((void *, FILE *));
-int __db_tablesize __P((u_int32_t));
-void __db_hashinit __P((void *, u_int32_t));
-int __dbenv_init __P((DB_ENV *));
-int __db_mi_env __P((DB_ENV *, const char *));
-int __db_mi_open __P((DB_ENV *, const char *, int));
-int __db_env_config __P((DB_ENV *, int));
-int __dbenv_open __P((DB_ENV *, const char *, u_int32_t, int));
-int __dbenv_remove __P((DB_ENV *, const char *, u_int32_t));
-int __dbenv_close __P((DB_ENV *, u_int32_t));
-int __db_appname __P((DB_ENV *, APPNAME,
- const char *, const char *, u_int32_t, DB_FH *, char **));
-int __db_apprec __P((DB_ENV *, u_int32_t));
-int __db_e_attach __P((DB_ENV *, u_int32_t *));
-int __db_e_detach __P((DB_ENV *, int));
-int __db_e_remove __P((DB_ENV *, int));
-int __db_e_stat __P((DB_ENV *, REGENV *, REGION *, int *));
-int __db_r_attach __P((DB_ENV *, REGINFO *, size_t));
-int __db_r_detach __P((DB_ENV *, REGINFO *, int));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _env_ext_h_ */
diff --git a/bdb/include/hash_ext.h b/bdb/include/hash_ext.h
deleted file mode 100644
index babb77a7902..00000000000
--- a/bdb/include/hash_ext.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _hash_ext_h_
-#define _hash_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __ham_metachk __P((DB *, const char *, HMETA *));
-int __ham_open __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __ham_c_init __P((DBC *));
-int __ham_c_count __P((DBC *, db_recno_t *));
-int __ham_c_dup __P((DBC *, DBC *));
-u_int32_t __ham_call_hash __P((DBC *, u_int8_t *, int32_t));
-int __ham_init_dbt __P((DB_ENV *,
- DBT *, u_int32_t, void **, u_int32_t *));
-int __ham_c_update
- __P((DBC *, u_int32_t, int, int));
-int __ham_get_clist __P((DB *,
- db_pgno_t, u_int32_t, DBC ***));
-int __ham_c_chgpg
- __P((DBC *, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t));
-int __ham_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __ham_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __ham_mswap __P((void *));
-int __ham_add_dup __P((DBC *, DBT *, u_int32_t, db_pgno_t *));
-int __ham_dup_convert __P((DBC *));
-int __ham_make_dup __P((DB_ENV *,
- const DBT *, DBT *d, void **, u_int32_t *));
-void __ham_move_offpage __P((DBC *, PAGE *, u_int32_t, db_pgno_t));
-void __ham_dsearch __P((DBC *, DBT *, u_int32_t *, int *));
-int __ham_cprint __P((DB *));
-u_int32_t __ham_func2 __P((DB *, const void *, u_int32_t));
-u_int32_t __ham_func3 __P((DB *, const void *, u_int32_t));
-u_int32_t __ham_func4 __P((DB *, const void *, u_int32_t));
-u_int32_t __ham_func5 __P((DB *, const void *, u_int32_t));
-int __ham_get_meta __P((DBC *));
-int __ham_release_meta __P((DBC *));
-int __ham_dirty_meta __P((DBC *));
-int __ham_db_create __P((DB *));
-int __ham_db_close __P((DB *));
-int __ham_item __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_reset __P((DBC *));
-void __ham_item_init __P((DBC *));
-int __ham_item_last __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_first __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_prev __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_next __P((DBC *, db_lockmode_t, db_pgno_t *));
-void __ham_putitem __P((PAGE *p, const DBT *, int));
-void __ham_reputpair
- __P((PAGE *p, u_int32_t, u_int32_t, const DBT *, const DBT *));
-int __ham_del_pair __P((DBC *, int));
-int __ham_replpair __P((DBC *, DBT *, u_int32_t));
-void __ham_onpage_replace __P((PAGE *, size_t, u_int32_t, int32_t,
- int32_t, DBT *));
-int __ham_split_page __P((DBC *, u_int32_t, u_int32_t));
-int __ham_add_el __P((DBC *, const DBT *, const DBT *, int));
-void __ham_copy_item __P((size_t, PAGE *, u_int32_t, PAGE *));
-int __ham_add_ovflpage __P((DBC *, PAGE *, int, PAGE **));
-int __ham_get_cpage __P((DBC *, db_lockmode_t));
-int __ham_next_cpage __P((DBC *, db_pgno_t, int));
-int __ham_lock_bucket __P((DBC *, db_lockmode_t));
-void __ham_dpair __P((DB *, PAGE *, u_int32_t));
-int __ham_insdel_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_newpage_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_replace_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_splitdata_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_copypage_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_metagroup_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_groupalloc_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_curadj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_chgpg_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_reclaim __P((DB *, DB_TXN *txn));
-int __ham_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
- int __ham_traverse __P((DB *, DBC *, db_lockmode_t,
- int (*)(DB *, PAGE *, void *, int *), void *));
-int __ham_30_hashmeta __P((DB *, char *, u_int8_t *));
-int __ham_30_sizefix __P((DB *, DB_FH *, char *, u_int8_t *));
-int __ham_31_hashmeta
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __ham_31_hash
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __ham_vrfy_meta __P((DB *, VRFY_DBINFO *, HMETA *,
- db_pgno_t, u_int32_t));
-int __ham_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
- u_int32_t));
-int __ham_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t,
- u_int32_t));
-int __ham_vrfy_hashing __P((DB *,
- u_int32_t, HMETA *, u_int32_t, db_pgno_t, u_int32_t,
- u_int32_t (*) __P((DB *, const void *, u_int32_t))));
-int __ham_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *,
- void *, int (*)(void *, const void *), u_int32_t));
-int __ham_meta2pgset __P((DB *, VRFY_DBINFO *, HMETA *, u_int32_t,
- DB *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _hash_ext_h_ */
diff --git a/bdb/include/lock_ext.h b/bdb/include/lock_ext.h
deleted file mode 100644
index 7ed9b1c695b..00000000000
--- a/bdb/include/lock_ext.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _lock_ext_h_
-#define _lock_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __lock_downgrade __P((DB_ENV *,
- DB_LOCK *, db_lockmode_t, u_int32_t));
-int __lock_addfamilylocker __P((DB_ENV *, u_int32_t, u_int32_t));
-int __lock_freefamilylocker __P((DB_LOCKTAB *, u_int32_t));
-void __lock_freelocker __P((DB_LOCKTAB *,
- DB_LOCKREGION *, DB_LOCKER *, u_int32_t));
-int __lock_getlocker __P((DB_LOCKTAB *,
- u_int32_t, u_int32_t, int, DB_LOCKER **));
-int __lock_getobj __P((DB_LOCKTAB *,
- const DBT *, u_int32_t, int, DB_LOCKOBJ **));
-int __lock_promote __P((DB_LOCKTAB *, DB_LOCKOBJ *, int));
-void __lock_printlock __P((DB_LOCKTAB *, struct __db_lock *, int));
-int __lock_set_lk_conflicts __P((DB_ENV *, u_int8_t *, int));
-int __lock_set_lk_detect __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max_locks __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max_lockers __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max_objects __P((DB_ENV *, u_int32_t));
-void __lock_dbenv_create __P((DB_ENV *));
-void __lock_dbenv_close __P((DB_ENV *));
-int __lock_open __P((DB_ENV *));
-int __lock_close __P((DB_ENV *));
-void __lock_region_destroy __P((DB_ENV *, REGINFO *));
-void __lock_dump_region __P((DB_ENV *, char *, FILE *));
-int __lock_cmp __P((const DBT *, DB_LOCKOBJ *));
-int __lock_locker_cmp __P((u_int32_t, DB_LOCKER *));
-u_int32_t __lock_ohash __P((const DBT *));
-u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
-u_int32_t __lock_locker_hash __P((u_int32_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _lock_ext_h_ */
diff --git a/bdb/include/log_ext.h b/bdb/include/log_ext.h
deleted file mode 100644
index 985c5d7745b..00000000000
--- a/bdb/include/log_ext.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _log_ext_h_
-#define _log_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __log_open __P((DB_ENV *));
-int __log_find __P((DB_LOG *, int, int *, logfile_validity *));
-int __log_valid __P((DB_LOG *, u_int32_t, int, logfile_validity *));
-int __log_close __P((DB_ENV *));
-int __log_lastckp __P((DB_ENV *, DB_LSN *));
-int __log_findckp __P((DB_ENV *, DB_LSN *));
-int __log_get __P((DB_LOG *, DB_LSN *, DBT *, u_int32_t, int));
-void __log_dbenv_create __P((DB_ENV *));
-int __log_put __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t));
-int __log_name __P((DB_LOG *,
- u_int32_t, char **, DB_FH *, u_int32_t));
-int __log_register_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __log_reopen_file __P((DB_ENV *,
- char *, int32_t, u_int8_t *, db_pgno_t));
-int __log_add_logid __P((DB_ENV *, DB_LOG *, DB *, int32_t));
-int __db_fileid_to_db __P((DB_ENV *, DB **, int32_t, int));
-void __log_close_files __P((DB_ENV *));
-void __log_rem_logid __P((DB_LOG *, DB *, int32_t));
-int __log_lid_to_fname __P((DB_LOG *, int32_t, FNAME **));
-int __log_filelist_update
- __P((DB_ENV *, DB *, int32_t, const char *, int *));
-int __log_file_lock __P((DB *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _log_ext_h_ */
diff --git a/bdb/include/mp_ext.h b/bdb/include/mp_ext.h
deleted file mode 100644
index 9f2b8c61f45..00000000000
--- a/bdb/include/mp_ext.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _mp_ext_h_
-#define _mp_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __memp_alloc __P((DB_MPOOL *,
- REGINFO *, MPOOLFILE *, size_t, roff_t *, void *));
-int __memp_bhwrite
- __P((DB_MPOOL *, MPOOLFILE *, BH *, int *, int *));
-int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
-int __memp_pgwrite
- __P((DB_MPOOL *, DB_MPOOLFILE *, BH *, int *, int *));
-int __memp_pg __P((DB_MPOOLFILE *, BH *, int));
-void __memp_bhfree __P((DB_MPOOL *, BH *, int));
-void __memp_set_unlink __P((DB_MPOOLFILE *));
-void __memp_clear_unlink __P((DB_MPOOLFILE *));
-int __memp_fopen __P((DB_MPOOL *, MPOOLFILE *, const char *,
- u_int32_t, int, size_t, int, DB_MPOOL_FINFO *, DB_MPOOLFILE **));
-void __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *));
-int __memp_fremove __P((DB_MPOOLFILE *));
-char * __memp_fn __P((DB_MPOOLFILE *));
-char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *));
-void __memp_dbenv_create __P((DB_ENV *));
-int __memp_open __P((DB_ENV *));
-int __memp_close __P((DB_ENV *));
-void __mpool_region_destroy __P((DB_ENV *, REGINFO *));
-void __memp_dump_region __P((DB_ENV *, char *, FILE *));
-int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _mp_ext_h_ */
diff --git a/bdb/include/os_ext.h b/bdb/include/os_ext.h
deleted file mode 100644
index ae9e3d304f2..00000000000
--- a/bdb/include/os_ext.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _os_ext_h_
-#define _os_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __os_abspath __P((const char *));
-int __os_strdup __P((DB_ENV *, const char *, void *));
-int __os_calloc __P((DB_ENV *, size_t, size_t, void *));
-int __os_malloc __P((DB_ENV *, size_t, void *(*)(size_t), void *));
-int __os_realloc __P((DB_ENV *,
- size_t, void *(*)(void *, size_t), void *));
-void __os_free __P((void *, size_t));
-void __os_freestr __P((void *));
-void *__ua_memcpy __P((void *, const void *, size_t));
-int __os_dirlist __P((DB_ENV *, const char *, char ***, int *));
-void __os_dirfree __P((char **, int));
-int __os_get_errno __P((void));
-void __os_set_errno __P((int));
-int __os_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
-int __os_finit __P((DB_ENV *, DB_FH *, size_t, int));
-int __os_fpinit __P((DB_ENV *, DB_FH *, db_pgno_t, int, int));
-int __os_fsync __P((DB_ENV *, DB_FH *));
-int __os_openhandle __P((DB_ENV *, const char *, int, int, DB_FH *));
-int __os_closehandle __P((DB_FH *));
-int __os_r_sysattach __P((DB_ENV *, REGINFO *, REGION *));
-int __os_r_sysdetach __P((DB_ENV *, REGINFO *, int));
-int __os_mapfile __P((DB_ENV *,
- char *, DB_FH *, size_t, int, void **));
-int __os_unmapfile __P((DB_ENV *, void *, size_t));
-u_int32_t __db_oflags __P((int));
-int __db_omode __P((const char *));
-int __os_open __P((DB_ENV *, const char *, u_int32_t, int, DB_FH *));
-int __os_shmname __P((DB_ENV *, const char *, char **));
-int __os_r_attach __P((DB_ENV *, REGINFO *, REGION *));
-int __os_r_detach __P((DB_ENV *, REGINFO *, int));
-int __os_rename __P((DB_ENV *, const char *, const char *));
-int __os_isroot __P((void));
-char *__db_rpath __P((const char *));
-int __os_io __P((DB_ENV *, DB_IO *, int, size_t *));
-int __os_read __P((DB_ENV *, DB_FH *, void *, size_t, size_t *));
-int __os_write __P((DB_ENV *, DB_FH *, void *, size_t, size_t *));
-int __os_seek __P((DB_ENV *,
- DB_FH *, size_t, db_pgno_t, u_int32_t, int, DB_OS_SEEK));
-int __os_sleep __P((DB_ENV *, u_long, u_long));
-int __os_spin __P((void));
-void __os_yield __P((DB_ENV*, u_long));
-int __os_exists __P((const char *, int *));
-int __os_ioinfo __P((DB_ENV *, const char *,
- DB_FH *, u_int32_t *, u_int32_t *, u_int32_t *));
-int __os_tmpdir __P((DB_ENV *, u_int32_t));
-int __os_unlink __P((DB_ENV *, const char *));
-int __os_region_unlink __P((DB_ENV *, const char *));
-#if defined(DB_WIN32)
-int __os_win32_errno __P((void));
-#endif
-int __os_fpinit __P((DB_ENV *, DB_FH *, db_pgno_t, int, int));
-int __os_is_winnt __P((void));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _os_ext_h_ */
diff --git a/bdb/include/qam_ext.h b/bdb/include/qam_ext.h
deleted file mode 100644
index f6e95110c0e..00000000000
--- a/bdb/include/qam_ext.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _qam_ext_h_
-#define _qam_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __qam_position
- __P((DBC *, db_recno_t *, qam_position_mode, int *));
-int __qam_pitem
- __P((DBC *, QPAGE *, u_int32_t, db_recno_t, DBT *));
-int __qam_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-int __qam_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-int __qam_c_dup __P((DBC *, DBC *));
-int __qam_c_init __P((DBC *));
-int __qam_mswap __P((PAGE *));
-int __qam_pgin_out __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __qam_fprobe __P((DB *, db_pgno_t, void *, qam_probe_mode, int));
-int __qam_fclose __P((DB *, db_pgno_t));
-int __qam_fremove __P((DB *, db_pgno_t));
-int __qam_sync __P((DB *, u_int32_t));
-int __qam_gen_filelist __P(( DB *, QUEUE_FILELIST **));
-int __qam_db_create __P((DB *));
-int __qam_db_close __P((DB *));
-int __db_prqueue __P((DB *, u_int32_t));
-int __qam_remove __P((DB *, const char *,
- const char *, DB_LSN *, int (**)(DB *, void*), void **));
-int __qam_rename __P((DB *,
- const char *, const char *, const char *));
-int __qam_open __P((DB *, const char *, db_pgno_t, int, u_int32_t));
-int __qam_metachk __P((DB *, const char *, QMETA *));
-int __qam_inc_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_incfirst_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_mvptr_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_del_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_delext_recover __P((DB_ENV *,
- DBT *, DB_LSN *, db_recops, void *));
-int __qam_add_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_delete_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_rename_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
-int __qam_31_qammeta __P((DB *, char *, u_int8_t *));
-int __qam_32_qammeta __P((DB *, char *, u_int8_t *));
-int __qam_vrfy_meta __P((DB *, VRFY_DBINFO *, QMETA *,
- db_pgno_t, u_int32_t));
-int __qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *,
- db_pgno_t, u_int32_t));
-int __qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _qam_ext_h_ */
diff --git a/bdb/include/tcl_ext.h b/bdb/include/tcl_ext.h
deleted file mode 100644
index 9baf7e4fdcf..00000000000
--- a/bdb/include/tcl_ext.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _tcl_ext_h_
-#define _tcl_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int bdb_HCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-#if DB_DBM_HSEARCH != 0
-int bdb_NdbmOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBM **));
-#endif
-#if DB_DBM_HSEARCH != 0
-int bdb_DbmCommand
- __P((Tcl_Interp *, int, Tcl_Obj * CONST*, int, DBM *));
-#endif
-int ndbm_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int bdb_RandCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-int tcl_Mutex __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *,
- DBTCL_INFO *));
-int db_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int dbc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int env_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int tcl_EnvRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- DB_ENV *, DBTCL_INFO *));
-int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
- Tcl_Obj *));
-int tcl_EnvTest __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-DBTCL_INFO *_NewInfo __P((Tcl_Interp *,
- void *, char *, enum INFOTYPE));
-void *_NameToPtr __P((CONST char *));
-char *_PtrToName __P((CONST void *));
-DBTCL_INFO *_PtrToInfo __P((CONST void *));
-DBTCL_INFO *_NameToInfo __P((CONST char *));
-void _SetInfoData __P((DBTCL_INFO *, void *));
-void _DeleteInfo __P((DBTCL_INFO *));
-int _SetListElem __P((Tcl_Interp *,
- Tcl_Obj *, void *, int, void *, int));
-int _SetListElemInt __P((Tcl_Interp *, Tcl_Obj *, void *, int));
-int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *,
- db_recno_t, u_char *, int));
-int _GetGlobPrefix __P((char *, char **));
-int _ReturnSetup __P((Tcl_Interp *, int, char *));
-int _ErrorSetup __P((Tcl_Interp *, int, char *));
-void _ErrorFunc __P((CONST char *, char *));
-int _GetLsn __P((Tcl_Interp *, Tcl_Obj *, DB_LSN *));
-void _debug_check __P((void));
-int tcl_LockDetect __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LockGet __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LockStat __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LockVec __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogArchive __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogCompare __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*));
-int tcl_LogFile __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogFlush __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogGet __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogPut __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogRegister __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogStat __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogUnregister __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-void _MpInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
-int tcl_MpSync __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-int tcl_MpTrickle __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_Mp __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
-int tcl_MpStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-void _TxnInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
-int tcl_TxnCheckpoint __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_Txn __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
-int tcl_TxnStat __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int txn_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _tcl_ext_h_ */
diff --git a/bdb/include/txn_ext.h b/bdb/include/txn_ext.h
deleted file mode 100644
index ee6922d701c..00000000000
--- a/bdb/include/txn_ext.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _txn_ext_h_
-#define _txn_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __txn_xa_begin __P((DB_ENV *, DB_TXN *));
-int __txn_end __P((DB_TXN *, int));
-int __txn_activekids __P((DB_ENV *, u_int32_t, DB_TXN *));
-int __txn_regop_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __txn_xa_regop_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __txn_ckp_recover
-__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __txn_child_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-void __txn_dbenv_create __P((DB_ENV *));
-int __txn_open __P((DB_ENV *));
-int __txn_close __P((DB_ENV *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _txn_ext_h_ */
diff --git a/bdb/include/xa_ext.h b/bdb/include/xa_ext.h
deleted file mode 100644
index cc16ba18337..00000000000
--- a/bdb/include/xa_ext.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _xa_ext_h_
-#define _xa_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __db_xa_create __P((DB *));
-int __db_rmid_to_env __P((int rmid, DB_ENV **envp));
-int __db_xid_to_txn __P((DB_ENV *, XID *, size_t *));
-int __db_map_rmid __P((int, DB_ENV *));
-int __db_unmap_rmid __P((int));
-int __db_map_xid __P((DB_ENV *, XID *, size_t));
-void __db_unmap_xid __P((DB_ENV *, XID *, size_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _xa_ext_h_ */
diff --git a/build-tags b/build-tags
deleted file mode 100755
index 90b957eb3bc..00000000000
--- a/build-tags
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /bin/sh
-
-if [ ! -f configure.in ] ; then
- echo "$0 must be run from MySQL source root"
- exit 1
-fi
-
-rm -f TAGS
-find -not -path \*SCCS\* -and \
- \( -name \*.cc -or -name \*.h -or -name \*.yy -or -name \*.c \) \
- -print -exec etags -o TAGS --append {} \;
diff --git a/client/Makefile.am b/client/Makefile.am
index 1710e573d20..cccb612af98 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -16,13 +16,13 @@
# This file is public domain and comes with NO WARRANTY of any kind
-INCLUDES = -I$(srcdir)/../include \
+INCLUDES = -I$(srcdir)/../include $(openssl_includes) \
-I../include -I$(srcdir)/.. -I$(top_srcdir) \
-I..
LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la
bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
- mysqldump mysqlimport mysqltest mysqlbinlog
+ mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen
noinst_PROGRAMS = insert_test select_test thread_test
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h
@@ -41,6 +41,8 @@ mysqltest_SOURCES= mysqltest.c
mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlbinlog_SOURCES = mysqlbinlog.cc
mysqlbinlog_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
+mysqlmanagerc_SOURCES = mysqlmanagerc.c
+mysqlmanagerc_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
sql_src=log_event.h log_event.cc
# Fix for mit-threads
diff --git a/client/client_priv.h b/client/client_priv.h
index 56eaf311070..acf9455bf9c 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -1,27 +1,28 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Common defines for all clients */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql.h>
+#include <mysql_embed.h>
#include <errmsg.h>
-#include <getopt.h>
+#include <my_getopt.h>
/* We have to define 'enum options' identical in all files to keep OS2 happy */
@@ -30,4 +31,10 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS,
OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE,
OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES,
- OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_LOCAL_INFILE};
+ OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_AUTO_REHASH,
+ OPT_LINE_NUMBERS, OPT_COLUMN_NAMES, OPT_CONNECT_TIMEOUT,
+ OPT_MAX_ALLOWED_PACKET, OPT_NET_BUFFER_LENGTH,
+ OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL,
+ OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
+ OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE,
+ OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION };
diff --git a/client/completion_hash.cc b/client/completion_hash.cc
index 006427f0295..ff5d0b28e41 100644
--- a/client/completion_hash.cc
+++ b/client/completion_hash.cc
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Quick & light hash implementation for tab completion purposes
*
@@ -22,7 +21,7 @@
* Small portability changes by Monty. Changed also to use my_malloc/my_free
*/
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#undef SAFEMALLOC // Speed things up
#include <my_sys.h>
@@ -47,10 +46,12 @@ int completion_hash_init(HashTable *ht, uint nSize)
ht->arBuckets = (Bucket **) my_malloc(nSize* sizeof(Bucket *),
MYF(MY_ZEROFILL | MY_WME));
- if (!ht->arBuckets) {
+ if (!ht->arBuckets)
+ {
ht->initialized = 0;
return FAILURE;
}
+ init_alloc_root(&ht->mem_root, 8192, 0);
ht->pHashFunction = hashpjw;
ht->nTableSize = nSize;
ht->initialized = 1;
@@ -78,8 +79,7 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
if (!memcmp(p->arKey, arKey, nKeyLength)) {
entry *n;
- n = (entry *) my_malloc(sizeof(entry),
- MYF(MY_WME));
+ n = (entry *) alloc_root(&ht->mem_root,sizeof(entry));
n->pNext = p->pData;
n->str = str;
p->pData = n;
@@ -91,20 +91,16 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
p = p->pNext;
}
- p = (Bucket *) my_malloc(sizeof(Bucket),MYF(MY_WME));
-
- if (!p) {
+ if (!(p = (Bucket *) alloc_root(&ht->mem_root, sizeof(Bucket))))
return FAILURE;
- }
+
p->arKey = arKey;
p->nKeyLength = nKeyLength;
p->h = h;
- p->pData = (entry*) my_malloc(sizeof(entry),MYF(MY_WME));
- if (!p->pData) {
- my_free((gptr) p,MYF(0));
+ if (!(p->pData = (entry*) alloc_root(&ht->mem_root, sizeof(entry))))
return FAILURE;
- }
+
p->pData->str = str;
p->pData->pNext = 0;
p->count = 1;
@@ -209,24 +205,7 @@ Bucket *find_longest_match(HashTable *ht, char *str, uint length,
void completion_hash_clean(HashTable *ht)
{
- uint i;
- entry *e, *t;
- Bucket *b, *tmp;
-
- for (i=0; i<ht->nTableSize; i++) {
- b = ht->arBuckets[i];
- while (b) {
- e = b->pData;
- while (e) {
- t = e;
- e = e->pNext;
- my_free((gptr) t,MYF(0));
- }
- tmp = b;
- b = b->pNext;
- my_free((gptr) tmp,MYF(0));
- }
- }
+ free_root(&ht->mem_root,MYF(0));
bzero((char*) ht->arBuckets,ht->nTableSize*sizeof(Bucket *));
}
@@ -241,9 +220,7 @@ void completion_hash_free(HashTable *ht)
void add_word(HashTable *ht,char *str)
{
int i;
- int length= (int) strlen(str);
-
- for (i=1; i<=length; i++) {
+ char *pos=str;
+ for (i=1; *pos; i++, pos++)
completion_hash_update(ht, str, i, str);
- }
}
diff --git a/client/completion_hash.h b/client/completion_hash.h
index 583a42bbbe5..c0853fddfe7 100644
--- a/client/completion_hash.h
+++ b/client/completion_hash.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
-
+
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
-
+
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -22,26 +22,29 @@
#define FAILURE 1
#include <sys/types.h>
+#include <my_sys.h>
typedef struct _entry {
char *str;
struct _entry *pNext;
} entry;
-typedef struct bucket {
- uint h; /* Used for numeric indexing */
- char *arKey;
- uint nKeyLength;
- uint count;
- entry *pData;
- struct bucket *pNext;
+typedef struct bucket
+{
+ uint h; /* Used for numeric indexing */
+ char *arKey;
+ uint nKeyLength;
+ uint count;
+ entry *pData;
+ struct bucket *pNext;
} Bucket;
typedef struct hashtable {
- uint nTableSize;
- uint initialized;
- uint(*pHashFunction) (char *arKey, uint nKeyLength);
- Bucket **arBuckets;
+ uint nTableSize;
+ uint initialized;
+ MEM_ROOT mem_root;
+ uint(*pHashFunction) (char *arKey, uint nKeyLength);
+ Bucket **arBuckets;
} HashTable;
extern int completion_hash_init(HashTable *ht, uint nSize);
@@ -54,4 +57,4 @@ extern void completion_hash_clean(HashTable *ht);
extern int completion_hash_exists(HashTable *ht, char *arKey, uint nKeyLength);
extern void completion_hash_free(HashTable *ht);
-#endif /* _HASH_ */
+#endif /* _HASH_ */
diff --git a/client/connect_test.c b/client/connect_test.c
index 661d448fdb0..fd81ad635ad 100644
--- a/client/connect_test.c
+++ b/client/connect_test.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <stdlib.h>
diff --git a/client/errmsg.c b/client/errmsg.c
index 67cfe874f77..6cb28f3f53e 100644
--- a/client/errmsg.c
+++ b/client/errmsg.c
@@ -1,24 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Error messages for MySQL clients */
/* error messages for the demon is in share/language/errmsg.sys */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "errmsg.h"
@@ -45,7 +44,13 @@ const char *client_errors[]=
"Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
"Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
"Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
+ "Got packet bigger than 'max_allowed_packet'",
+ "Embedded server",
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:"
+
};
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
@@ -73,7 +78,12 @@ const char *client_errors[]=
"Não pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
- "Obteve pacote maior do que 'max_allowed_packet'"
+ "Obteve pacote maior do que 'max_allowed_packet'",
+ "Embedded server",
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:"
};
#else /* ENGLISH */
@@ -99,7 +109,12 @@ const char *client_errors[]=
"Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
+ "Got packet bigger than 'max_allowed_packet'",
+ "Embedded server",
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:"
};
#endif
diff --git a/client/get_password.c b/client/get_password.c
index 25069a14b75..9928d24de32 100644
--- a/client/get_password.c
+++ b/client/get_password.c
@@ -1,25 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Ask for a password from tty
** This is an own file to avoid conflicts with curses
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "mysql.h"
#include <m_string.h>
@@ -72,7 +71,7 @@ char *get_tty_password(char *opt_message)
char *pos=to,*end=to+sizeof(to)-1;
int i=0;
DBUG_ENTER("get_tty_password");
- fprintf(stdout,opt_message ? opt_message : "Enter password: ");
+ fprintf(stderr,opt_message ? opt_message : "Enter password: ");
for (;;)
{
char tmp;
@@ -125,8 +124,8 @@ static void get_password(char *to,uint length,int fd,bool echo)
{
if (echo)
{
- fputs("\b \b",stdout);
- fflush(stdout);
+ fputs("\b \b",stderr);
+ fflush(stderr);
}
pos--;
continue;
@@ -138,8 +137,8 @@ static void get_password(char *to,uint length,int fd,bool echo)
continue;
if (echo)
{
- fputc('*',stdout);
- fflush(stdout);
+ fputc('*',stderr);
+ fflush(stderr);
}
*(pos++) = tmp;
}
@@ -172,10 +171,10 @@ char *get_tty_password(char *opt_message)
memset(passbuff, 0, _PASSWORD_LEN);
#endif
#else
- if (isatty(fileno(stdout)))
+ if (isatty(fileno(stderr)))
{
- fputs(opt_message ? opt_message : "Enter password: ",stdout);
- fflush(stdout);
+ fputs(opt_message ? opt_message : "Enter password: ",stderr);
+ fflush(stderr);
}
#if defined(HAVE_TERMIOS_H)
tcgetattr(fileno(stdin), &org);
@@ -184,7 +183,7 @@ char *get_tty_password(char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
- get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
+ get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stderr)));
tcsetattr(fileno(stdin), TCSADRAIN, &org);
#elif defined(HAVE_TERMIO_H)
ioctl(fileno(stdin), (int) TCGETA, &org);
@@ -193,7 +192,7 @@ char *get_tty_password(char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME]= 0;
ioctl(fileno(stdin),(int) TCSETA, &tmp);
- get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
+ get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
ioctl(fileno(stdin),(int) TCSETA, &org);
#else
gtty(fileno(stdin), &org);
@@ -201,11 +200,11 @@ char *get_tty_password(char *opt_message)
tmp.sg_flags &= ~ECHO;
tmp.sg_flags |= RAW;
stty(fileno(stdin), &tmp);
- get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
+ get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
stty(fileno(stdin), &org);
#endif
- if (isatty(fileno(stdout)))
- fputc('\n',stdout);
+ if (isatty(fileno(stderr)))
+ fputc('\n',stderr);
#endif /* HAVE_GETPASS */
DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
diff --git a/client/insert_test.c b/client/insert_test.c
index 640935d63b2..42691df6875 100644
--- a/client/insert_test.c
+++ b/client/insert_test.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <stdlib.h>
@@ -34,19 +33,13 @@ int main(int argc, char **argv)
exit(1);
}
- if (!(sock = mysql_connect(&mysql,NULL,0,0)))
+ if (!(sock = mysql_real_connect(&mysql,NULL,NULL,NULL,argv[1],0,NULL,0)))
{
fprintf(stderr,"Couldn't connect to engine!\n%s\n",mysql_error(&mysql));
perror("");
exit(1);
}
- if (mysql_select_db(sock,argv[1]))
- {
- fprintf(stderr,"Couldn't select database %s!\n%s\n",argv[1],
- mysql_error(sock));
- }
-
num = atoi(argv[2]);
count = 0;
while (count < num)
diff --git a/client/list_test.c b/client/list_test.c
index 718cc45e012..06bf16d2751 100644
--- a/client/list_test.c
+++ b/client/list_test.c
@@ -1,34 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __WIN__
#include <windows.h>
diff --git a/client/my_readline.h b/client/my_readline.h
index 547587bc19d..2e716eec4cf 100644
--- a/client/my_readline.h
+++ b/client/my_readline.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* readline for batch mode */
diff --git a/client/mysql.cc b/client/mysql.cc
index 32547a4d138..6de6a97a22a 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2002 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,21 +20,27 @@
* Written by:
* Michael 'Monty' Widenius
* Andi Gutmans <andi@zend.com>
- * Zeev Suraski <zeev@zend.com>
- * Jani Tolonen <jani@mysql.com>
+ * Zeev Suraski <zeev@zend.com>
+ * Jani Tolonen <jani@mysql.com>
+ * Matt Wagner <matt@mysql.com>
+ * Jeremy Cole <jcole@mysql.com>
+ * Tonu Samuel <tonu@mysql.com>
+ * Harrison Fisk <hcfisk@buffalo.edu>
*
**/
#include "client_priv.h"
#include <m_ctype.h>
+#include <stdarg.h>
#include <my_dir.h>
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ // Skip warnings in getopt.h
#endif
#include "my_readline.h"
#include <signal.h>
+#include <violite.h>
-const char *VER="11.18";
+const char *VER= "12.11";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -71,7 +77,6 @@ extern "C" {
#endif
#undef bcmp // Fix problem with new readline
-#undef bzero
#if defined( __WIN__) || defined(OS2)
#include <conio.h>
#else
@@ -94,6 +99,8 @@ extern "C" {
#include "completion_hash.h"
+#define PROMPT_CHAR '\\'
+
typedef struct st_status
{
int exit_status;
@@ -110,25 +117,39 @@ enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
typedef enum enum_info_type INFO_TYPE;
static MYSQL mysql; /* The connection */
-static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
- connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
- no_rehash=0,skip_updates=0,safe_updates=0,one_database=0,
- opt_compress=0, using_opt_local_infile=0,
- vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
- opt_nopager=1, opt_outfile=0, no_named_cmds=1;
+static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
+ connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
+ rehash=1,skip_updates=0,safe_updates=0,one_database=0,
+ opt_compress=0, using_opt_local_infile=0,
+ vertical=0, line_numbers=1, column_names=1,opt_html=0,
+ opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
+ tty_password= 0, opt_nobeep=0;
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static my_string opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
- *default_charset;
+ *current_prompt=0, *default_charset;
static char *histfile;
static String glob_buffer,old_buffer;
+static String processed_prompt;
+static char *full_username=0,*part_username=0,*default_prompt=0;
static int wait_time = 5;
static STATUS status;
static ulong select_limit,max_join_size,opt_connect_timeout=0;
+static char mysql_charsets_dir[FN_REFLEN+1];
+static const char *xmlmeta[] = {
+ "&", "&amp;",
+ "<", "&lt;",
+ 0, 0
+};
+static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
+ "Aug","Sep","Oct","Nov","Dec"};
static char default_pager[FN_REFLEN];
-char pager[FN_REFLEN], outfile[FN_REFLEN];
-FILE *PAGER, *OUTFILE;
+static char pager[FN_REFLEN], outfile[FN_REFLEN];
+static FILE *PAGER, *OUTFILE;
+static MEM_ROOT hash_mem_root;
+static uint prompt_counter;
#include "sslopt-vars.h"
@@ -149,7 +170,8 @@ static int com_quit(String *str,char*),
com_connect(String *str,char*), com_status(String *str,char*),
com_use(String *str,char*), com_source(String *str, char*),
com_rehash(String *str, char*), com_tee(String *str, char*),
- com_notee(String *str, char*);
+ com_notee(String *str, char*), com_shell(String *str, char *),
+ com_prompt(String *str, char*);
#ifndef __WIN__
static int com_nopager(String *str, char*), com_pager(String *str, char*),
@@ -161,10 +183,14 @@ static int sql_connect(char *host,char *database,char *user,char *password,
uint silent);
static int put_info(const char *str,INFO_TYPE info,uint error=0);
static void safe_put_field(const char *pos,ulong length);
+static void xmlencode_print(const char *src, uint length);
static void init_pager();
static void end_pager();
-static void init_tee();
+static int init_tee(char *);
static void end_tee();
+static const char* construct_prompt();
+static void init_username();
+static void add_int_to_prompt(int toadd);
/* A structure which contains information on the commands this program
can understand. */
@@ -199,11 +225,15 @@ static COMMANDS commands[] = {
"Set PAGER [to_pager]. Print the query results via PAGER." },
#endif
{ "print", 'p', com_print, 0, "Print current command." },
+ { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."},
{ "quit", 'q', com_quit, 0, "Quit mysql." },
{ "rehash", '#', com_rehash, 0, "Rebuild completion hash." },
{ "source", '.', com_source, 1,
"Execute a SQL script file. Takes a file name as an argument."},
{ "status", 's', com_status, 0, "Get status information from the server."},
+#ifndef __WIN__
+ { "system", '!', com_shell, 1, "Execute a system shell command."},
+#endif
{ "tee", 'T', com_tee, 1,
"Set outfile [to_outfile]. Append everything into given outfile." },
{ "use", 'u', com_use, 1,
@@ -232,6 +262,8 @@ static COMMANDS commands[] = {
};
static const char *load_default_groups[]= { "mysql","client",0 };
+static const char *server_default_groups[]=
+{ "server", "embedded", "mysql_SERVER", 0 };
#ifdef HAVE_READLINE
extern "C" void add_history(char *command); /* From readline directory */
@@ -245,6 +277,7 @@ static bool add_line(String &buffer,char *line,char *in_string);
static void remove_cntrl(String &buffer);
static void print_table_data(MYSQL_RES *result);
static void print_table_data_html(MYSQL_RES *result);
+static void print_table_data_xml(MYSQL_RES *result);
static void print_tab_data(MYSQL_RES *result);
static void print_table_data_vertically(MYSQL_RES *result);
static ulong start_timer(void);
@@ -262,6 +295,12 @@ int main(int argc,char *argv[])
DBUG_ENTER("main");
DBUG_PROCESS(argv[0]);
+ default_prompt = my_strdup(getenv("MYSQL_PS1") ?
+ getenv("MYSQL_PS1") :
+ "mysql> ",MYF(MY_WME));
+ current_prompt = my_strdup(default_prompt,MYF(MY_WME));
+ prompt_counter=0;
+
strmov(outfile, "\0"); // no (default) outfile, unless given at least once
strmov(pager, "stdout"); // the default, if --pager wasn't given
{
@@ -278,7 +317,7 @@ int main(int argc,char *argv[])
status.add_to_history=1;
status.exit_status=1;
load_defaults("my",load_default_groups,&argc,&argv);
- if (get_options(argc,(char **) argv))
+ if (get_options(argc, (char **) argv))
{
my_end(0);
exit(1);
@@ -288,7 +327,10 @@ int main(int argc,char *argv[])
!(status.line_buff=batch_readline_init(max_allowed_packet+512,stdin)))
exit(1);
glob_buffer.realloc(512);
- completion_hash_init(&ht,50);
+ mysql_server_init(0, NULL, (char**) server_default_groups);
+ completion_hash_init(&ht, 128);
+ init_alloc_root(&hash_mem_root, 16384, 0);
+ bzero((char*) &mysql, sizeof(mysql));
if (sql_connect(current_host,current_db,current_user,opt_password,
opt_silent))
{
@@ -301,7 +343,7 @@ int main(int argc,char *argv[])
signal(SIGINT, mysql_end); // Catch SIGINT to clean up
/*
- ** Run in interactive mode like the ingres/postgres monitor
+ Run in interactive mode like the ingres/postgres monitor
*/
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
@@ -313,9 +355,9 @@ int main(int argc,char *argv[])
#ifdef HAVE_READLINE
initialize_readline(my_progname);
- if (!status.batch && !quick && !opt_html)
+ if (!status.batch && !quick && !opt_html && !opt_xml)
{
- /*read-history from file, default ~/.mysql_history*/
+ /* read-history from file, default ~/.mysql_history*/
if (getenv("MYSQL_HISTFILE"))
histfile=my_strdup(getenv("MYSQL_HISTFILE"),MYF(MY_WME));
else if (getenv("HOME"))
@@ -348,10 +390,16 @@ int main(int argc,char *argv[])
sig_handler mysql_end(int sig)
{
- if (connected)
- mysql_close(&mysql);
+ mysql_close(&mysql);
+#ifdef HAVE_OPENSSL
+ my_free(opt_ssl_key,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_cert,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_ca,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_capath,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_cipher,MYF(MY_ALLOW_ZERO_PTR));
+#endif
#ifdef HAVE_READLINE
- if (!status.batch && !quick && ! opt_html)
+ if (!status.batch && !quick && !opt_html && !opt_xml)
{
/* write-history */
if (verbose)
@@ -360,88 +408,178 @@ sig_handler mysql_end(int sig)
}
batch_readline_end(status.line_buff);
completion_hash_free(&ht);
+ free_root(&hash_mem_root,MYF(0));
+
#endif
if (sig >= 0)
put_info(sig ? "Aborted" : "Bye", INFO_RESULT);
glob_buffer.free();
old_buffer.free();
+ processed_prompt.free();
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ mysql_server_end();
my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(status.exit_status);
}
-static struct option long_options[] =
+
+static struct my_option my_long_options[] =
{
- {"i-am-a-dummy", optional_argument, 0, 'U'},
- {"batch", no_argument, 0, 'B'},
- {"character-sets-dir",required_argument, 0, OPT_CHARSETS_DIR},
- {"compress", no_argument, 0, 'C'},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"auto-rehash", OPT_AUTO_REHASH,
+ "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.",
+ (gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"no-auto-rehash", 'A',
+ "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"batch", 'B',
+ "Print results with a tab as separator, each row on new line. Doesn't use history file.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are.", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set.", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", optional_argument, 0, '#'},
+ {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option,
+ (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"database", required_argument, 0, 'D'},
- {"debug-info", no_argument, 0, 'T'},
- {"default-character-set", required_argument,0, OPT_DEFAULT_CHARSET},
- {"enable-named-commands", no_argument, 0, 'G'},
- {"execute", required_argument, 0, 'e'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"html", no_argument, 0, 'H'},
- {"host", required_argument, 0, 'h'},
- {"ignore-spaces", no_argument, 0, 'i'},
- {"local-infile", optional_argument, 0, OPT_LOCAL_INFILE},
- {"no-auto-rehash",no_argument, 0, 'A'},
- {"no-named-commands", no_argument, 0, 'g'},
+ {"database", 'D', "Database to use.", (gptr*) &current_db,
+ (gptr*) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"execute", 'e', "Execute command and quit. (Output like with --batch).", 0,
+ 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"vertical", 'E', "Print the output of a query (rows) vertically.",
+ (gptr*) &vertical, (gptr*) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"force", 'f', "Continue even if we get an sql error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"no-named-commands", 'g',
+ "Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"named-commands", 'G',
+ "Enable named commands. Named commands mean this program's internal commands; see mysql> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default.",
+ (gptr*) &named_cmds, (gptr*) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"ignore-space", 'i', "Ignore space after function names.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-beep", 'b', "Turn off beep on error.", (gptr*) &opt_nobeep,
+ (gptr*) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"html", 'H', "Produce HTML output.", (gptr*) &opt_html, (gptr*) &opt_html,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"xml", 'X', "Produce XML output", (gptr*) &opt_xml, (gptr*) &opt_xml, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
+ (gptr*) &line_numbers, (gptr*) &line_numbers, 0, GET_BOOL,
+ NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef __WIN__
- {"no-pager", no_argument, 0, OPT_NOPAGER},
- {"nopager", no_argument, 0, OPT_NOPAGER}, /* we are kind */
- {"pager", optional_argument, 0, OPT_PAGER},
+ {"no-pager", OPT_NOPAGER,
+ "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"no-tee", no_argument, 0, OPT_NOTEE},
- {"notee", no_argument, 0, OPT_NOTEE}, /* we are kind */
- {"tee", required_argument, 0, OPT_TEE},
- {"one-database", no_argument, 0, 'o'},
- {"password", optional_argument, 0, 'p'},
+ {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"unbuffered", 'n', "Flush buffer after each query.", (gptr*) &unbuffered,
+ (gptr*) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
+ (gptr*) &column_names, (gptr*) &column_names, 0, GET_BOOL,
+ NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"skip-column-names", 'N',
+ "Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"one-database", 'o',
+ "Only update the default database. This is useful for skipping updates to other database in the update log.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef __WIN__
+ {"pager", OPT_PAGER,
+ "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"quick", no_argument, 0, 'q'},
- {"set-variable", required_argument, 0, 'O'},
- {"raw", no_argument, 0, 'r'},
- {"safe-updates", optional_argument, 0, 'U'},
- {"silent", no_argument, 0, 's'},
- {"skip-column-names",no_argument, 0, 'N'},
- {"skip-line-numbers",no_argument, 0, 'L'},
- {"socket", required_argument, 0, 'S'},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
+ (gptr*) &current_prompt, (gptr*) &current_prompt, 0, GET_STR_ALLOC,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"quick", 'q',
+ "Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file. ",
+ (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"raw", 'r', "Write fields without conversion. Used with --batch",
+ (gptr*) &opt_raw_data, (gptr*) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"silent", 's', "Be more silent.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
- {"table", no_argument, 0, 't'},
+ {"table", 't', "Output in table format.", (gptr*) &output_tables,
+ (gptr*) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"tee", OPT_TEE,
+ "Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &current_user,
+ (gptr*) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"unbuffered", no_argument, 0, 'n'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"vertical", no_argument, 0, 'E'},
- {"wait", optional_argument, 0, 'w'},
- {0, 0, 0, 0}
-};
-
-
-CHANGEABLE_VAR changeable_vars[] = {
- { "connect_timeout", (long*) &opt_connect_timeout, 0, 0, 3600*12, 0, 1},
- { "max_allowed_packet", (long*) &max_allowed_packet,16*1024L*1024L,4096,
- 24*1024L*1024L, MALLOC_OVERHEAD,1024},
- { "net_buffer_length",(long*) &net_buffer_length,16384,1024,16*1024*1024L,
- MALLOC_OVERHEAD,1024},
- { "select_limit", (long*) &select_limit, 1000L, 1, ~0L, 0, 1},
- { "max_join_size", (long*) &max_join_size, 1000000L, 1, ~0L, 0, 1},
- { 0, 0, 0, 0, 0, 0, 0}
+ {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
+ (gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, OPT_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write more. (-v -v -v gives the table output format)", 0,
+ 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout,
+ (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
+ 0, 1},
+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
+ (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG,
+ REQUIRED_ARG, 16 *1024L*1024L, 4096, 512*1024L*1024L, MALLOC_OVERHEAD,
+ 1024, 0},
+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
+ (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
+ {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit,
+ (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0},
+ {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size,
+ (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1,
+ 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -451,298 +589,166 @@ static void usage(int version)
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
if (version)
return;
- puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB");
- puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
- printf("Usage: %s [OPTIONS] [database]\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n\
- -A, --no-auto-rehash No automatic rehashing. One has to use 'rehash' to\n\
- get table and field completion. This gives a quicker\n\
- start of mysql and disables rehashing on reconnect.\n\
- -B, --batch Print results with a tab as separator, each row on\n\
- a new line. Doesn't use history file.\n\
- --character-sets-dir=...\n\
- Directory where character sets are located.\n\
- -C, --compress Use compression in server/client protocol.\n");
-#ifndef DBUG_OFF
printf("\
- -#, --debug[=...] Debug log. Default is '%s'.\n",default_dbug_option);
-#endif
- printf("\
- -D, --database=.. Database to use.\n\
- --default-character-set=...\n\
- Set the default character set.\n\
- -e, --execute=... Execute command and quit. (Output like with --batch)\n\
- -E, --vertical Print the output of a query (rows) vertically.\n\
- -f, --force Continue even if we get an sql error.\n\
- -g, --no-named-commands\n\
- Named commands are disabled. Use \\* form only, or\n\
- use named commands only in the beginning of a line\n\
- ending with a semicolon (;) Since version 10.9 the\n\
- client now starts with this option ENABLED by\n\
- default! Disable with '-G'. Long format commands\n\
- still work from the first line.\n\
- -G, --enable-named-commands\n\
- Named commands are enabled. Opposite to -g.\n\
- -i, --ignore-spaces Ignore spaces after function names.\n\
- -h, --host=... Connect to host.\n\
- -H, --html Produce HTML output.\n\
- --local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\n\
- -L, --skip-line-numbers\n\
- Don't write line number for errors.\n");
-#ifndef __WIN__
- printf("\
- --no-pager Disable pager and print to stdout. See interactive\n\
- help (\\h) also.\n");
-#endif
- printf("\
- --no-tee Disable outfile. See interactive help (\\h) also.\n\
- -n, --unbuffered Flush buffer after each query.\n\
- -N, --skip-column-names\n\
- Don't write column names in results.\n\
- -O, --set-variable var=option\n\
- Give a variable an value. --help lists variables.\n\
- -o, --one-database Only update the default database. This is useful\n\
- for skipping updates to other database in the update\n\
- log.\n");
-#ifndef __WIN__
- printf("\
- --pager[=...] Pager to use to display results. If you don't supply\n\
- an option the default pager is taken from your ENV\n\
- variable PAGER (%s).\n\
- Valid pagers are less, more, cat [> filename], etc.\n\
- See interactive help (\\h) also. This option does\n\
- not work in batch mode.\n", getenv("PAGER") ? getenv("PAGER") : "");
-#endif
- printf("\
- -p[password], --password[=...]\n\
- Password to use when connecting to server\n\
- If password is not given it's asked from the tty.\n");
+Copyright (C) 2002 MySQL AB\n\
+This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n");
+ printf("Usage: %s [OPTIONS] [database]\n", my_progname);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
+}
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case OPT_CHARSETS_DIR:
+ strmov(mysql_charsets_dir, argument);
+ charsets_dir = mysql_charsets_dir;
+ break;
+ case OPT_LOCAL_INFILE:
+ using_opt_local_infile=1;
+ opt_local_infile= test(!argument || atoi(argument)>0);
+ break;
+ case OPT_TEE:
+ if (argument == disabled_my_option)
+ {
+ if (opt_outfile)
+ end_tee();
+ }
+ else
+ opt_outfile= init_tee(argument);
+ break;
+ case OPT_NOTEE:
+ printf("WARNING: option deprecated; use --disable-tee instead.\n");
+ if (opt_outfile)
+ end_tee();
+ break;
+ case OPT_PAGER:
+ opt_nopager= 0;
+ if (argument)
+ strmov(pager, argument);
+ else
+ strmov(pager, default_pager);
+ strmov(default_pager, pager);
+ break;
+ case OPT_NOPAGER:
+ printf("WARNING: option deprecated; use --disable-pager instead.\n");
+ opt_nopager= 1;
+ break;
+ case 'A':
+ rehash= 0;
+ break;
+ case 'N':
+ column_names= 0;
+ break;
+ case 'e':
+ status.batch= 1;
+ status.add_to_history= 0;
+ batch_readline_end(status.line_buff); // If multiple -e
+ if (!(status.line_buff= batch_readline_command(argument)))
+ return 1;
+ ignore_errors= 0;
+ break;
+ case 'o':
+ if (argument == disabled_my_option)
+ one_database= 0;
+ else
+ one_database= skip_updates= 1;
+ break;
+ case 'p':
+ if (argument == disabled_my_option)
+ argument= (char*) ""; // Don't require password
+ if (argument)
+ {
+ char *start= argument;
+ my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ opt_password= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; // Destroy argument
+ if (*start)
+ start[1]=0 ;
+ }
+ else
+ tty_password= 1;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+ info_flag= 1;
+ break;
+ case 's':
+ if (argument == disabled_my_option)
+ opt_silent= 0;
+ else
+ opt_silent++;
+ break;
+ case 'v':
+ if (argument == disabled_my_option)
+ verbose= 0;
+ else
+ verbose++;
+ break;
+ case 'B':
+ if (!status.batch)
+ {
+ status.batch= 1;
+ status.add_to_history= 0;
+ opt_silent++; // more silent
+ }
+ break;
+ case 'W':
#ifdef __WIN__
- puts(" -W, --pipe Use named pipes to connect to server");
+ opt_mysql_unix_port= my_strdup(MYSQL_NAMEDPIPE, MYF(0));
#endif
- printf("\n\
- -P, --port=... Port number to use for connection.\n\
- -q, --quick Don't cache result, print it row by row. This may\n\
- slow down the server if the output is suspended.\n\
- Doesn't use history file.\n\
- -r, --raw Write fields without conversion. Used with --batch\n\
- -s, --silent Be more silent.\n\
- -S --socket=... Socket file to use for connection.\n");
-#include "sslopt-usage.h"
- printf("\
- -t, --table Output in table format.\n\
- -T, --debug-info Print some debug info at exit.\n\
- --tee=... Append everything into outfile. See interactive help\n\
- (\\h) also. Does not work in batch mode.\n");
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -U, --safe-updates[=#], --i-am-a-dummy[=#]\n\
- Only allow UPDATE and DELETE that uses keys.\n\
- -v, --verbose Write more. (-v -v -v gives the table output format)\n\
- -V, --version Output version information and exit.\n\
- -w, --wait Wait and retry if connection is down.\n");
- print_defaults("my",load_default_groups);
-
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (uint i=0 ; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- (ulong) *changeable_vars[i].varptr);
+ break;
+ case 'V':
+ usage(1);
+ exit(0);
+ case 'I':
+ case '?':
+ usage(0);
+ exit(0);
+#include "sslopt-case.h"
+ }
+ return 0;
}
static int get_options(int argc, char **argv)
{
- int c,option_index=0;
- bool tty_password=0;
+ char *tmp, *pagpoint;
+ int ho_error;
+
+ tmp= (char *) getenv("MYSQL_HOST");
+ if (tmp)
+ current_host= my_strdup(tmp, MYF(MY_WME));
- set_all_changeable_vars(changeable_vars);
- while ((c=getopt_long(argc,argv,
- (char*) "?ABCD:LfgGHinNoqrstTU::vVw::WEe:h:O:P:S:u:#::p::",
- long_options, &option_index)) != EOF)
+ pagpoint= getenv("PAGER");
+ if (!((char*) (pagpoint)))
{
- switch(c) {
- case OPT_DEFAULT_CHARSET:
- default_charset= optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir= optarg;
- break;
- case OPT_TEE:
- if (!opt_outfile && strlen(optarg))
- {
- strmov(outfile, optarg);
- opt_outfile=1;
- init_tee();
- }
- break;
- case OPT_NOTEE:
- if (opt_outfile)
- end_tee();
- opt_outfile=0;
- break;
- case OPT_PAGER:
- opt_nopager=0;
- if (optarg)
- strmov(pager, optarg);
- else
- {
- char *pagpoint = getenv("PAGER");
- if (!((char*) (pagpoint)))
- {
- strmov(pager, "stdout");
- opt_nopager=1;
- }
- else
- strmov(pager, pagpoint);
- }
- strmov(default_pager, pager);
- break;
- case OPT_NOPAGER:
- opt_nopager=1;
- break;
- case 'D':
- my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
- current_db=my_strdup(optarg,MYF(MY_WME));
- break;
- case 'e':
- status.batch=1;
- status.add_to_history=0;
- batch_readline_end(status.line_buff); // If multiple -e
- if (!(status.line_buff=batch_readline_command(optarg)))
- return 1;
- ignore_errors=0;
- break;
- case 'f':
- ignore_errors=1;
- break;
- case 'h':
- my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
- current_host=my_strdup(optarg,MYF(MY_WME));
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
- current_user= my_strdup(optarg,MYF(MY_WME));
- break;
-#endif
- case 'U':
- if (!optarg)
- safe_updates=1;
- else
- safe_updates=atoi(optarg) != 0;
- break;
- case 'o':
- one_database=skip_updates=1;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage(0);
- return(1);
- }
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; // Destroy argument
- if (*start)
- start[1]=0;
- }
- else
- tty_password=1;
- break;
- case 't':
- output_tables=1;
- break;
- case 'r':
- opt_raw_data=1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : default_dbug_option);
- info_flag=1;
- break;
- case 'q': quick=1; break;
- case 's': opt_silent++; break;
- case 'T': info_flag=1; break;
- case 'n': unbuffered=1; break;
- case 'v': verbose++; break;
- case 'E': vertical=1; break;
- case 'w':
- wait_flag=1;
- if(optarg) wait_time = atoi(optarg) ;
- break;
- case 'A': no_rehash=1; break;
- case 'G': no_named_cmds=0; break;
- case 'g': no_named_cmds=1; break;
- case 'H': opt_html=1; break;
- case 'i': connect_flag|= CLIENT_IGNORE_SPACE; break;
- case 'B':
- if (!status.batch)
- {
- status.batch=1;
- status.add_to_history=0;
- opt_silent++; // more silent
- }
- break;
- case 'C':
- opt_compress=1;
- break;
- case OPT_LOCAL_INFILE:
- using_opt_local_infile=1;
- opt_local_infile= test(!optarg || atoi(optarg)>0);
- break;
- case 'L':
- skip_line_numbers=1;
- break;
- case 'N':
- skip_column_names=1;
- break;
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'S':
- my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
- opt_mysql_unix_port= my_strdup(optarg,MYF(0));
- break;
- case 'W':
-#ifdef __WIN__
- opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0));
-#endif
- break;
- case 'V': usage(1); exit(0);
- case 'I':
- case '?':
- usage(0);
- exit(0);
-#include "sslopt-case.h"
- default:
- tee_fprintf(stderr,"illegal option: -%c\n",opterr);
- usage(0);
- exit(1);
- }
+ strmov(pager, "stdout");
+ opt_nopager= 1;
}
+ else
+ strmov(pager, pagpoint);
+ strmov(default_pager, pager);
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (status.batch) /* disable pager and outfile in this case */
{
strmov(default_pager, "stdout");
strmov(pager, "stdout");
- opt_nopager=1;
- opt_outfile=0;
+ opt_nopager= 1;
+ opt_outfile= 0;
}
if (default_charset)
{
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- argc-=optind;
- argv+=optind;
if (argc > 1)
{
usage(0);
@@ -750,17 +756,11 @@ static int get_options(int argc, char **argv)
}
if (argc == 1)
{
- my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
- current_db= my_strdup(*argv,MYF(MY_WME));
- }
- if (!current_host)
- { /* If we don't have a hostname have a look at MYSQL_HOST */
- char *tmp=(char *) getenv("MYSQL_HOST");
- if (tmp)
- current_host = my_strdup(tmp,MYF(MY_WME));
+ my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
+ current_db= my_strdup(*argv, MYF(MY_WME));
}
if (tty_password)
- opt_password=get_tty_password(NullS);
+ opt_password= get_tty_password(NullS);
return(0);
}
@@ -789,7 +789,7 @@ static int read_lines(bool execute_commands)
#if defined( __WIN__) || defined(OS2)
if (opt_outfile && glob_buffer.is_empty())
fflush(OUTFILE);
- tee_fputs(glob_buffer.is_empty() ? "mysql> " :
+ tee_fputs(glob_buffer.is_empty() ? construct_prompt() :
!in_string ? " -> " :
in_string == '\'' ?
" '> " : " \"> ",stdout);
@@ -800,12 +800,12 @@ static int read_lines(bool execute_commands)
{
if (glob_buffer.is_empty())
fflush(OUTFILE);
- fputs(glob_buffer.is_empty() ? "mysql> " :
+ fputs(glob_buffer.is_empty() ? construct_prompt() :
!in_string ? " -> " :
in_string == '\'' ?
" '> " : " \"> ", OUTFILE);
}
- line=readline((char*) (glob_buffer.is_empty() ? "mysql> " :
+ line=readline((char*) (glob_buffer.is_empty() ? construct_prompt() :
!in_string ? " -> " :
in_string == '\'' ?
" '> " : " \"> "));
@@ -823,9 +823,11 @@ static int read_lines(bool execute_commands)
line[0] == 0))
continue; // Skip comment lines
- /* Check if line is a mysql command line */
- /* (We want to allow help, print and clear anywhere at line start */
- if (execute_commands && (!no_named_cmds || glob_buffer.is_empty())
+ /*
+ Check if line is a mysql command line
+ (We want to allow help, print and clear anywhere at line start
+ */
+ if (execute_commands && (named_cmds || glob_buffer.is_empty())
&& !in_string && (com=find_command(line,0)))
{
if ((*com->func)(&glob_buffer,line) > 0)
@@ -1007,20 +1009,20 @@ static bool add_line(String &buffer,char *line,char *in_string)
return 0;
}
-/* **************************************************************** */
-/* */
-/* Interface to Readline Completion */
-/* */
-/* **************************************************************** */
+/*****************************************************************
+ Interface to Readline Completion
+******************************************************************/
#ifdef HAVE_READLINE
static char *new_command_generator(char *text, int);
static char **new_mysql_completion (char *text, int start, int end);
-/* Tell the GNU Readline library how to complete. We want to try to complete
- on command names if this is the first word in the line, or on filenames
- if not. */
+/*
+ Tell the GNU Readline library how to complete. We want to try to complete
+ on command names if this is the first word in the line, or on filenames
+ if not.
+*/
char **no_completion (char *text __attribute__ ((unused)),
char *word __attribute__ ((unused)))
@@ -1039,11 +1041,12 @@ static void initialize_readline (char *name)
rl_completion_entry_function=(Function *) no_completion;
}
-/* Attempt to complete on the contents of TEXT. START and END show the
- region of TEXT that contains the word to complete. We can use the
- entire line in case we want to do some simple parsing. Return the
- array of matches, or NULL if there aren't any. */
-
+/*
+ Attempt to complete on the contents of TEXT. START and END show the
+ region of TEXT that contains the word to complete. We can use the
+ entire line in case we want to do some simple parsing. Return the
+ array of matches, or NULL if there aren't any.
+*/
static char **new_mysql_completion (char *text,
int start __attribute__((unused)),
@@ -1063,67 +1066,72 @@ static char *new_command_generator(char *text,int state)
static entry *e;
static uint i;
- if (!state) {
+ if (!state)
textlen=(uint) strlen(text);
- }
- if (textlen>0) { /* lookup in the hash */
- if (!state) {
+ if (textlen>0)
+ { /* lookup in the hash */
+ if (!state)
+ {
uint len;
b = find_all_matches(&ht,text,(uint) strlen(text),&len);
- if (!b) {
+ if (!b)
return NullS;
- }
e = b->pData;
}
- while (e) {
+ if (e)
+ {
ptr= strdup(e->str);
e = e->pNext;
return ptr;
}
- } else { /* traverse the entire hash, ugly but works */
+ }
+ else
+ { /* traverse the entire hash, ugly but works */
- if (!state) {
- i=0;
+ if (!state)
+ {
/* find the first used bucket */
- while (i<ht.nTableSize) {
- if (ht.arBuckets[i]) {
+ for (i=0 ; i < ht.nTableSize ; i++)
+ {
+ if (ht.arBuckets[i])
+ {
b = ht.arBuckets[i];
e = b->pData;
break;
}
- i++;
}
}
ptr= NullS;
- while (e && !ptr) { /* find valid entry in bucket */
- if ((uint) strlen(e->str)==b->nKeyLength) {
+ while (e && !ptr)
+ { /* find valid entry in bucket */
+ if ((uint) strlen(e->str) == b->nKeyLength)
ptr = strdup(e->str);
- }
/* find the next used entry */
e = e->pNext;
- if (!e) { /* find the next used bucket */
+ if (!e)
+ { /* find the next used bucket */
b = b->pNext;
- if (!b) {
- i++;
- while (i<ht.nTableSize) {
- if (ht.arBuckets[i]) {
+ if (!b)
+ {
+ for (i++ ; i<ht.nTableSize; i++)
+ {
+ if (ht.arBuckets[i])
+ {
b = ht.arBuckets[i];
e = b->pData;
break;
}
- i++;
}
- } else {
- e = b->pData;
}
+ else
+ e = b->pData;
}
}
- if (ptr) {
+ if (ptr)
return ptr;
- }
}
return NullS;
}
@@ -1131,10 +1139,11 @@ static char *new_command_generator(char *text,int state)
/* Build up the completion hash */
-static void build_completion_hash(bool skip_rehash,bool write_info)
+static void build_completion_hash(bool rehash, bool write_info)
{
COMMANDS *cmd=commands;
- static MYSQL_RES *databases=0,*tables=0,*fields;
+ MYSQL_RES *databases=0,*tables=0;
+ MYSQL_RES *fields;
static char ***field_names= 0;
MYSQL_ROW database_row,table_row;
MYSQL_FIELD *sql_field;
@@ -1145,35 +1154,42 @@ static void build_completion_hash(bool skip_rehash,bool write_info)
if (status.batch || quick || !current_db)
DBUG_VOID_RETURN; // We don't need completion in batches
- completion_hash_clean(&ht);
if (tables)
{
mysql_free_result(tables);
tables=0;
}
- if (databases) {
- mysql_free_result(databases);
- databases=0;
- }
/* hash SQL commands */
while (cmd->name) {
add_word(&ht,(char*) cmd->name);
cmd++;
}
- if (skip_rehash)
+ if (!rehash)
DBUG_VOID_RETURN;
+ /* Free old used memory */
+ if (field_names)
+ field_names=0;
+ completion_hash_clean(&ht);
+ free_root(&hash_mem_root,MYF(0));
+
/* hash MySQL functions (to be implemented) */
/* hash all database names */
- if (mysql_query(&mysql,"show databases")==0) {
+ if (mysql_query(&mysql,"show databases") == 0)
+ {
if (!(databases = mysql_store_result(&mysql)))
put_info(mysql_error(&mysql),INFO_INFO);
else
{
while ((database_row=mysql_fetch_row(databases)))
- add_word(&ht,(char*) database_row[0]);
+ {
+ char *str=strdup_root(&hash_mem_root, (char*) database_row[0]);
+ if (str)
+ add_word(&ht,(char*) str);
+ }
+ mysql_free_result(databases);
}
}
/* hash all table names */
@@ -1191,22 +1207,13 @@ You can turn off this feature to get a quicker startup with -A\n\n");
}
while ((table_row=mysql_fetch_row(tables)))
{
- if (!completion_hash_exists(&ht,(char*) table_row[0],
- (uint) strlen((const char*) table_row[0])))
- add_word(&ht,table_row[0]);
+ char *str=strdup_root(&hash_mem_root, (char*) table_row[0]);
+ if (str &&
+ !completion_hash_exists(&ht,(char*) str, (uint) strlen(str)))
+ add_word(&ht,str);
}
}
}
- if (field_names) {
- for (i=0; field_names[i]; i++) {
- for (j=0; field_names[i][j]; j++) {
- my_free(field_names[i][j],MYF(0));
- }
- my_free((gptr) field_names[i],MYF(0));
- }
- my_free((gptr) field_names,MYF(0));
- }
- field_names=0;
/* hash all field names, both with the table prefix and without it */
if (!tables) /* no tables */
@@ -1214,36 +1221,37 @@ You can turn off this feature to get a quicker startup with -A\n\n");
DBUG_VOID_RETURN;
}
mysql_data_seek(tables,0);
- field_names = (char ***) my_malloc(sizeof(char **) *
- (uint) (mysql_num_rows(tables)+1),
- MYF(MY_WME));
- if (!field_names)
+ if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) *
+ (uint) (mysql_num_rows(tables)+1))))
+ {
+ mysql_free_result(tables);
DBUG_VOID_RETURN;
+ }
i=0;
while ((table_row=mysql_fetch_row(tables)))
{
if ((fields=mysql_list_fields(&mysql,(const char*) table_row[0],NullS)))
{
num_fields=mysql_num_fields(fields);
- field_names[i] = (char **) my_malloc(sizeof(char *)*(num_fields*2+1),
- MYF(0));
- if (!field_names[i])
- {
- continue;
- }
+ if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
+ sizeof(char *) *
+ (num_fields*2+1))))
+ break;
field_names[i][num_fields*2]='\0';
j=0;
while ((sql_field=mysql_fetch_field(fields)))
{
sprintf(buf,"%s.%s",table_row[0],sql_field->name);
- field_names[i][j] = my_strdup(buf,MYF(0));
+ field_names[i][j] = strdup_root(&hash_mem_root,buf);
add_word(&ht,field_names[i][j]);
- field_names[i][num_fields+j] = my_strdup(sql_field->name,MYF(0));
+ field_names[i][num_fields+j] = strdup_root(&hash_mem_root,
+ sql_field->name);
if (!completion_hash_exists(&ht,field_names[i][num_fields+j],
(uint) strlen(field_names[i][num_fields+j])))
add_word(&ht,field_names[i][num_fields+j]);
j++;
}
+ mysql_free_result(fields);
}
else
{
@@ -1253,20 +1261,18 @@ You can turn off this feature to get a quicker startup with -A\n\n");
}
i++;
}
+ mysql_free_result(tables);
field_names[i]=0; // End pointer
DBUG_VOID_RETURN;
}
-
/* for gnu readline */
#ifndef HAVE_INDEX
-#ifdef __cplusplus
extern "C" {
-#endif
-extern char *index(const char *,pchar c),*rindex(const char *,pchar);
+extern char *index(const char *,int c),*rindex(const char *,int);
-char *index(const char *s,pchar c)
+char *index(const char *s,int c)
{
for (;;)
{
@@ -1275,7 +1281,7 @@ char *index(const char *s,pchar c)
}
}
-char *rindex(const char *s,pchar c)
+char *rindex(const char *s,int c)
{
reg3 char *t;
@@ -1283,19 +1289,19 @@ char *rindex(const char *s,pchar c)
do if (*s == (char) c) t = (char*) s; while (*s++);
return (char*) t;
}
-#ifdef __cplusplus
}
#endif
-#endif
#endif /* HAVE_READLINE */
+
static int reconnect(void)
{
if (!status.batch)
{
put_info("No connection. Trying to reconnect...",INFO_INFO);
(void) com_connect((String *) 0, 0);
- if(!no_rehash) com_rehash(NULL, NULL);
+ if (rehash)
+ com_rehash(NULL, NULL);
}
if (!connected)
return put_info("Can't connect to the server\n",INFO_ERROR);
@@ -1314,7 +1320,7 @@ com_help (String *buffer __attribute__((unused)),
reg1 int i;
put_info("\nMySQL commands:",INFO_INFO);
- if (no_named_cmds)
+ if (!named_cmds)
put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO);
for (i = 0; commands[i].name; i++)
{
@@ -1342,10 +1348,10 @@ com_clear(String *buffer,char *line __attribute__((unused)))
/*
-** Execute command
-** Returns: 0 if ok
-** -1 if not fatal error
-** 1 if fatal error
+ Execute command
+ Returns: 0 if ok
+ -1 if not fatal error
+ 1 if fatal error
*/
@@ -1363,7 +1369,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
old_buffer.copy();
}
- /* Remove garbage for nicer messages */
+ /* Remove garbage for nicer messages */
LINT_INIT(buff[0]);
remove_cntrl(*buffer);
@@ -1443,6 +1449,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
init_pager();
if (opt_html)
print_table_data_html(result);
+ else if (opt_xml)
+ print_table_data_xml(result);
else if (vertical)
print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables)
@@ -1479,7 +1487,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
static void init_pager()
{
-#if !defined( __WIN__) && !defined( OS2)
+#if !defined( __WIN__) && !defined( OS2) && (!defined(HAVE_mit_thread) || !defined(THREAD))
if (!opt_nopager)
{
if (!(PAGER= popen(pager, "w")))
@@ -1495,25 +1503,31 @@ static void init_pager()
static void end_pager()
{
-#if !defined( __WIN__) && !defined( OS2)
+#if !defined( __WIN__) && !defined( OS2) && !(defined(HAVE_mit_thread) && defined(THREAD))
if (!opt_nopager)
pclose(PAGER);
#endif
}
-static void init_tee()
+
+static int init_tee(char* newfile)
{
- if (!(OUTFILE= my_fopen(outfile, O_APPEND | O_WRONLY, MYF(MY_WME))))
- {
- opt_outfile=0;
- init_pager();
- return;
- }
+ FILE* new_outfile;
+ if (!(new_outfile= my_fopen(newfile, O_APPEND | O_WRONLY, MYF(MY_WME))))
+ return 0;
+ if (opt_outfile)
+ end_tee();
+ OUTFILE = new_outfile;
+ strmake(outfile,newfile,FN_REFLEN-1);
+ tee_fprintf(stdout, "Logging to file '%s'\n", outfile);
+ return 1;
}
+
static void end_tee()
{
my_fclose(OUTFILE, MYF(0));
+ opt_outfile= 0;
return;
}
@@ -1562,7 +1576,7 @@ print_table_data(MYSQL_RES *result)
separator.copy("+",1);
while ((field = mysql_fetch_field(result)))
{
- uint length=skip_column_names ? 0 : (uint) strlen(field->name);
+ uint length= column_names ? (uint) strlen(field->name) : 0;
if (quick)
length=max(length,field->length);
else
@@ -1574,7 +1588,7 @@ print_table_data(MYSQL_RES *result)
separator.append('+');
}
tee_puts(separator.c_ptr(), PAGER);
- if (!skip_column_names)
+ if (column_names)
{
mysql_field_seek(result,0);
(void) tee_fputs("|", PAGER);
@@ -1588,18 +1602,19 @@ print_table_data(MYSQL_RES *result)
tee_puts(separator.c_ptr(), PAGER);
}
- while ((cur = mysql_fetch_row(result)))
+ while ((cur= mysql_fetch_row(result)))
{
(void) tee_fputs("|", PAGER);
- mysql_field_seek(result,0);
- for (uint off=0 ; off < mysql_num_fields(result); off++)
+ mysql_field_seek(result, 0);
+ for (uint off= 0; off < mysql_num_fields(result); off++)
{
- const char *str=cur[off] ? cur[off] : "NULL";
- field = mysql_fetch_field(result);
- uint length=field->max_length;
+ const char *str= cur[off] ? cur[off] : "NULL";
+ field= mysql_fetch_field(result);
+ uint length= field->max_length;
if (length > MAX_COLUMN_LENGTH)
{
- tee_fputs(str,PAGER); tee_fputs(" |",PAGER);
+ tee_fputs(str, PAGER);
+ tee_fputs(" |", PAGER);
}
else
tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
@@ -1619,7 +1634,7 @@ print_table_data_html(MYSQL_RES *result)
mysql_field_seek(result,0);
(void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
- if (!skip_column_names)
+ if (column_names)
{
while((field = mysql_fetch_field(result)))
{
@@ -1645,6 +1660,38 @@ print_table_data_html(MYSQL_RES *result)
}
+static void
+print_table_data_xml(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ MYSQL_FIELD *fields;
+
+ mysql_field_seek(result,0);
+
+ tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
+ xmlencode_print(glob_buffer.ptr(), strlen(glob_buffer.ptr()));
+ tee_fputs("\">", PAGER);
+
+ fields = mysql_fetch_fields(result);
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("\n <row>\n", PAGER);
+ for (uint i=0; i < mysql_num_fields(result); i++)
+ {
+ ulong *lengths=mysql_fetch_lengths(result);
+ tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ xmlencode_print(cur[i], lengths[i]);
+ tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ }
+ (void) tee_fputs(" </row>\n", PAGER);
+ }
+ (void) tee_fputs("</resultset>\n", PAGER);
+}
+
static void
print_table_data_vertically(MYSQL_RES *result)
@@ -1677,6 +1724,36 @@ print_table_data_vertically(MYSQL_RES *result)
}
+static const char
+*array_value(const char **array, char key)
+{
+ int x;
+ for (x= 0; array[x]; x+= 2)
+ if (*array[x] == key)
+ return array[x + 1];
+ return 0;
+}
+
+
+static void
+xmlencode_print(const char *src, uint length)
+{
+ if (!src)
+ tee_fputs("NULL", PAGER);
+ else
+ {
+ for (const char *p = src; *p && length; *p++, length--)
+ {
+ const char *t;
+ if ((t = array_value(xmlmeta, *p)))
+ tee_fputs(t, PAGER);
+ else
+ tee_putc(*p, PAGER);
+ }
+ }
+}
+
+
static void
safe_put_field(const char *pos,ulong length)
{
@@ -1706,7 +1783,7 @@ safe_put_field(const char *pos,ulong length)
tee_fputs("\\n", PAGER); // This too
else if (*pos == '\\')
tee_fputs("\\\\", PAGER);
- else
+ else
tee_putc(*pos, PAGER);
}
}
@@ -1720,7 +1797,7 @@ print_tab_data(MYSQL_RES *result)
MYSQL_FIELD *field;
ulong *lengths;
- if (opt_silent < 2 && !skip_column_names)
+ if (opt_silent < 2 && column_names)
{
int first=0;
while ((field = mysql_fetch_field(result)))
@@ -1738,7 +1815,7 @@ print_tab_data(MYSQL_RES *result)
for (uint off=1 ; off < mysql_num_fields(result); off++)
{
(void) tee_fputs("\t", PAGER);
- safe_put_field(cur[off],lengths[off]);
+ safe_put_field(cur[off], lengths[off]);
}
(void) tee_fputs("\n", PAGER);
}
@@ -1757,54 +1834,52 @@ com_tee(String *buffer, char *line __attribute__((unused)))
{
if (!strlen(outfile))
{
- printf("No previous outfile available, you must give the filename!\n");
- opt_outfile=0;
+ printf("No previous outfile available, you must give a filename!\n");
return 0;
}
- }
- else
- {
- while (isspace(*param))
- param++;
- end= strend(param);
- while (end > file_name && (isspace(end[-1]) || iscntrl(end[-1])))
- end--;
- end[0]= 0;
- if ((*(end - 1) == '"' && *param == '"') ||
- (*(end - 1) == '\'' && *param == '\''))
+ else if (opt_outfile)
{
- *--end= 0;
- param++;
+ tee_fprintf(stdout, "Currently logging to file '%s'\n", outfile);
+ return 0;
}
- strmake(file_name, param, sizeof(file_name) - 1);
- strmov(outfile, file_name);
+ else
+ param = outfile; //resume using the old outfile
}
+
+ /* eliminate the spaces before the parameters */
+ while (isspace(*param))
+ param++;
+ end= strmake(file_name, param, sizeof(file_name) - 1);
+ /* remove end space from command line */
+ while (end > file_name && (isspace(end[-1]) || iscntrl(end[-1])))
+ end--;
+ end[0]= 0;
if (!strlen(outfile))
{
printf("No outfile specified!\n");
return 0;
}
+ opt_outfile= init_tee(file_name);
if (opt_outfile)
- end_tee();
- init_tee();
- opt_outfile= 1;
- tee_fprintf(stdout, "Logging to file '%s'\n", outfile);
+ tee_fprintf(stdout, "Logging to file '%s'\n", outfile);
+ else
+ tee_fprintf(stdout, "Error logging to file '%s'\n",file_name);
return 0;
}
+
static int
com_notee(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
if (opt_outfile)
end_tee();
- opt_outfile=0;
tee_fprintf(stdout, "Outfile disabled.\n");
return 0;
}
/*
-** Sorry, this command is not available in Windows.
+ Sorry, this command is not available in Windows.
*/
#ifndef __WIN__
@@ -1860,7 +1935,7 @@ com_nopager(String *buffer __attribute__((unused)),
/*
-** Sorry, you can't send the result to an editor in Win32
+ Sorry, you can't send the result to an editor in Win32
*/
#ifndef __WIN__
@@ -1920,11 +1995,36 @@ com_rehash(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
#ifdef HAVE_READLINE
- build_completion_hash(0,0);
+ build_completion_hash(1, 0);
#endif
return 0;
}
+
+#ifndef __WIN__
+static int
+com_shell(String *buffer, char *line __attribute__((unused)))
+{
+ char *shell_cmd;
+ if (!(shell_cmd = strchr(line, ' ')))
+ {
+ put_info("Usage: \\! shell-command", INFO_ERROR);
+ return -1;
+ }
+ /*
+ The output of the shell command does not
+ get directed to the pager or the outfile
+ */
+ if (system(shell_cmd) == -1)
+ {
+ put_info(strerror(errno), INFO_ERROR, errno);
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+
static int
com_print(String *buffer,char *line __attribute__((unused)))
{
@@ -1941,7 +2041,7 @@ static int
com_connect(String *buffer, char *line)
{
char *tmp,buff[256];
- bool save_rehash=no_rehash;
+ bool save_rehash= rehash;
int error;
if (buffer)
@@ -1963,13 +2063,13 @@ com_connect(String *buffer, char *line)
}
}
else
- no_rehash=1; // Quick re-connect
+ rehash= 0; // Quick re-connect
buffer->length(0); // command used
}
else
- no_rehash=1;
+ rehash= 0;
error=sql_connect(current_host,current_db,current_user,opt_password,0);
- no_rehash=save_rehash;
+ rehash= save_rehash;
if (connected)
{
@@ -2055,7 +2155,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
if (!current_db || cmp_database(current_db,tmp))
{
if (one_database)
- skip_updates=1;
+ skip_updates= 1;
else
{
/*
@@ -2077,12 +2177,12 @@ com_use(String *buffer __attribute__((unused)), char *line)
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
current_db=my_strdup(tmp,MYF(MY_WME));
#ifdef HAVE_READLINE
- build_completion_hash(no_rehash,1);
+ build_completion_hash(rehash, 1);
#endif
}
}
else
- skip_updates=0;
+ skip_updates= 0;
put_info("Database changed",INFO_INFO);
return 0;
}
@@ -2092,11 +2192,8 @@ static int
sql_real_connect(char *host,char *database,char *user,char *password,
uint silent)
{
- if (connected)
- { /* if old is open, close it first */
- mysql_close(&mysql);
- connected= 0;
- }
+ mysql_close(&mysql);
+ connected= 0;
mysql_init(&mysql);
if (opt_connect_timeout)
{
@@ -2111,7 +2208,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
+ opt_ssl_capath, opt_ssl_cipher);
#endif
if (safe_updates)
{
@@ -2121,8 +2218,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
select_limit,max_join_size);
mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
}
- if (!mysql_real_connect(&mysql,host,user,password,
- database,opt_mysql_port,opt_mysql_unix_port,
+ if (!mysql_real_connect(&mysql, host, user, password,
+ database, opt_mysql_port, opt_mysql_unix_port,
connect_flag))
{
if (!silent ||
@@ -2138,7 +2235,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
connected=1;
mysql.reconnect=info_flag ? 1 : 0; // We want to know if this happens
#ifdef HAVE_READLINE
- build_completion_hash(no_rehash,1);
+ build_completion_hash(rehash, 1);
#endif
return 0;
}
@@ -2183,7 +2280,7 @@ static int
com_status(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
- char *status;
+ const char *status;
tee_puts("--------------", stdout);
usage(1); /* Print version */
if (connected)
@@ -2199,6 +2296,13 @@ com_status(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "Current user:\t\t%s\n",cur[1]);
(void) mysql_fetch_row(result); // Read eof
}
+#ifdef HAVE_OPENSSL
+ if (mysql.net.vio->ssl_ && SSL_get_cipher(mysql.net.vio->ssl_))
+ tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n",
+ SSL_get_cipher(mysql.net.vio->ssl_));
+ else
+#endif /* HAVE_OPENSSL */
+ tee_puts("SSL:\t\t\tNot in use", stdout);
}
else
{
@@ -2232,11 +2336,11 @@ com_status(String *buffer __attribute__((unused)),
if ((status=mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
{
- char *pos,buff[40];
ulong sec;
- pos=strchr(status,' ');
- *pos++=0;
- tee_fprintf(stdout, "%s\t\t\t", status); /* print label */
+ char buff[40];
+ const char *pos= strchr(status,' ');
+ /* print label */
+ tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status), status);
if ((status=str2int(pos,10,0,LONG_MAX,(long*) &sec)))
{
nice_time((double) sec,buff,0);
@@ -2270,7 +2374,7 @@ static int
put_info(const char *str,INFO_TYPE info_type,uint error)
{
static int inited=0;
-
+
if (status.batch)
{
if (info_type == INFO_ERROR)
@@ -2279,7 +2383,7 @@ put_info(const char *str,INFO_TYPE info_type,uint error)
fprintf(stderr,"ERROR");
if (error)
(void) fprintf(stderr," %d",error);
- if (status.query_start_line && ! skip_line_numbers)
+ if (status.query_start_line && line_numbers)
{
(void) fprintf(stderr," at line %lu",status.query_start_line);
if (status.file_name)
@@ -2307,7 +2411,8 @@ put_info(const char *str,INFO_TYPE info_type,uint error)
}
if (info_type == INFO_ERROR)
{
- putchar('\007'); /* This should make a bell */
+ if (!opt_nobeep)
+ putchar('\007'); /* This should make a bell */
vidattr(A_STANDOUT);
if (error)
(void) tee_fprintf(stderr, "ERROR %d: ", error);
@@ -2389,9 +2494,11 @@ void tee_putc(int c, FILE *file)
#include <time.h>
#else
#include <sys/times.h>
+#ifdef _SC_CLK_TCK // For mit-pthreads
#undef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
#endif
+#endif
static ulong start_timer(void)
{
@@ -2450,6 +2557,180 @@ static void mysql_end_timer(ulong start_time,char *buff)
strmov(strend(buff),")");
}
+static const char* construct_prompt()
+{
+ //erase the old prompt
+ processed_prompt.free();
+ //get the date struct
+ time_t lclock = time(NULL);
+ struct tm *t = localtime(&lclock);
+ //parse thru the settings for the prompt
+ for (char *c = current_prompt; *c ; *c++)
+ {
+ if (*c != PROMPT_CHAR)
+ processed_prompt.append(*c);
+ else
+ {
+ switch (*++c) {
+ case '\0':
+ //stop it from going beyond if ends with %
+ c--;
+ break;
+ case 'c':
+ add_int_to_prompt(++prompt_counter);
+ break;
+ case 'v':
+ processed_prompt.append(mysql_get_server_info(&mysql));
+ break;
+ case 'd':
+ processed_prompt.append(current_db ? current_db : "(none)");
+ break;
+ case 'h':
+ {
+ const char *prompt=mysql_get_host_info(&mysql);
+ if (strstr(prompt, "Localhost"))
+ processed_prompt.append("localhost");
+ else
+ {
+ const char *end=strcend(prompt,' ');
+ processed_prompt.append(prompt, (uint) (end-prompt));
+ }
+ break;
+ }
+ case 'p':
+ if (strstr(mysql_get_host_info(&mysql),"TCP/IP") ||
+ ! mysql.unix_socket)
+ add_int_to_prompt(mysql.port);
+ else
+ processed_prompt.append(strrchr(mysql.unix_socket,'/')+1);
+ break;
+ case 'U':
+ if (!full_username)
+ init_username();
+ processed_prompt.append(full_username);
+ break;
+ case 'u':
+ if (!full_username)
+ init_username();
+ processed_prompt.append(part_username);
+ break;
+ case PROMPT_CHAR:
+ processed_prompt.append(PROMPT_CHAR);
+ break;
+ case 'n':
+ processed_prompt.append('\n');
+ break;
+ case ' ':
+ case '_':
+ processed_prompt.append(' ');
+ break;
+ case 'R':
+ add_int_to_prompt(t->tm_hour);
+ break;
+ case 'r':
+ int getHour;
+ getHour = t->tm_hour % 12;
+ if (getHour == 0)
+ getHour=12;
+ add_int_to_prompt(getHour);
+ break;
+ case 'm':
+ if (t->tm_min < 10)
+ processed_prompt.append('0');
+ add_int_to_prompt(t->tm_min);
+ break;
+ case 'y':
+ int getYear;
+ getYear = t->tm_year % 100;
+ if (getYear < 10)
+ processed_prompt.append('0');
+ add_int_to_prompt(getYear);
+ break;
+ case 'Y':
+ add_int_to_prompt(t->tm_year+1900);
+ break;
+ case 'D':
+ char* dateTime;
+ time_t lclock;
+ lclock = time(NULL);
+ dateTime = ctime(&lclock);
+ processed_prompt.append(strtok(dateTime,"\n"));
+ break;
+ case 's':
+ add_int_to_prompt(t->tm_sec);
+ break;
+ case 'w':
+ processed_prompt.append(day_names[t->tm_wday]);
+ break;
+ case 'P':
+ processed_prompt.append(t->tm_hour < 12 ? "am" : "pm");
+ break;
+ case 'o':
+ add_int_to_prompt(t->tm_mon+1);
+ break;
+ case 'O':
+ processed_prompt.append(month_names[t->tm_mon]);
+ break;
+ case '\'':
+ processed_prompt.append("'");
+ break;
+ case '"':
+ processed_prompt.append('"');
+ break;
+ case 'S':
+ processed_prompt.append(';');
+ break;
+ case 't':
+ processed_prompt.append('\t');
+ break;
+ default:
+ processed_prompt.append(c);
+ }
+ }
+ }
+ processed_prompt.append('\0');
+ return processed_prompt.ptr();
+}
+
+
+static void add_int_to_prompt(int toadd)
+{
+ char buffer[16];
+ int10_to_str(toadd,buffer,10);
+ processed_prompt.append(buffer);
+}
+
+static void init_username()
+{
+ my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
+
+ MYSQL_RES *result;
+ LINT_INIT(result);
+ if (!mysql_query(&mysql,"select USER()") &&
+ (result=mysql_use_result(&mysql)))
+ {
+ MYSQL_ROW cur=mysql_fetch_row(result);
+ full_username=my_strdup(cur[0],MYF(MY_WME));
+ part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME));
+ (void) mysql_fetch_row(result); // Read eof
+ }
+}
+
+static int com_prompt(String *buffer, char *line)
+{
+ char *ptr=strchr(line, ' ');
+ prompt_counter = 0;
+ my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ current_prompt=my_strdup(ptr ? ptr+1 : default_prompt,MYF(MY_WME));
+ if (!ptr)
+ tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt);
+ else
+ tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
+ return 0;
+}
+
+#ifndef EMBEDDED_LIBRARY
/* Keep sql_string library happy */
gptr sql_alloc(unsigned int Size)
@@ -2461,3 +2742,4 @@ void sql_element_free(void *ptr)
{
my_free((gptr) ptr,MYF(0));
}
+#endif /* EMBEDDED_LIBRARY */
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index 0dd8cfb1bd0..d890a096542 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -23,24 +23,29 @@
#include <my_pthread.h> /* because of signal() */
#endif
-#define ADMIN_VERSION "8.23"
-#define MAX_MYSQL_VAR 64
+#define ADMIN_VERSION "8.36"
+#define MAX_MYSQL_VAR 128
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
+char *host= NULL, *user= 0, *opt_password= 0;
char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH];
char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN];
ulonglong last_values[MAX_MYSQL_VAR];
static int interval=0;
static my_bool option_force=0,interrupted=0,new_line=0,
- opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0;
+ opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0,
+ tty_password=0;
static uint tcp_port = 0, option_wait = 0, option_silent=0;
static ulong opt_connect_timeout, opt_shutdown_timeout;
static my_string unix_port=0;
-/* When using extended-status relatively, ex_val_max_len is the estimated
- maximum length for any relative value printed by extended-status. The
- idea is to try to keep the length of output as short as possible. */
+/*
+ When using extended-status relatively, ex_val_max_len is the estimated
+ maximum length for any relative value printed by extended-status. The
+ idea is to try to keep the length of output as short as possible.
+*/
+
static uint ex_val_max_len[MAX_MYSQL_VAR];
static my_bool ex_status_printed = 0; /* First output is not relative. */
static uint ex_var_count, max_var_length, max_val_length;
@@ -49,8 +54,7 @@ static uint ex_var_count, max_var_length, max_val_length;
static void print_version(void);
static void usage(void);
-static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *password,uint wait);
+static my_bool sql_connect(MYSQL *mysql, uint wait);
static int execute_commands(MYSQL *mysql,int argc, char **argv);
static int drop_db(MYSQL *mysql,const char *db);
static sig_handler endprog(int signal_number);
@@ -97,158 +101,158 @@ static const char *command_names[]= {
static TYPELIB command_typelib=
{ array_elements(command_names)-1,"commands", command_names};
-static struct option long_options[] = {
- {"compress", no_argument, 0, 'C'},
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR},
- {"debug", optional_argument, 0, '#'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"password", optional_argument, 0, 'p'},
+static struct my_option my_long_options[] =
+{
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Don't ask for confirmation on drop database; with multiple commands, continue even if an error occurs.",
+ (gptr*) &option_force, (gptr*) &option_force, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are.", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host", (gptr*) &host, (gptr*) &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"relative", no_argument, 0, 'r'},
- {"set-variable", required_argument, 0, 'O'},
- {"silent", no_argument, 0, 's'},
- {"socket", required_argument, 0, 'S'},
- {"sleep", required_argument, 0, 'i'},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &tcp_port,
+ (gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"relative", 'r',
+ "Show difference between current and previous values when used with -i. Currently works only with extended-status.",
+ (gptr*) &opt_relative, (gptr*) &opt_relative, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Silently exit if one can't connect to server",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &unix_port, (gptr*) &unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"sleep", 'i', "Execute commands again and again with a sleep between.",
+ (gptr*) &interval, (gptr*) &interval, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
#include "sslopt-longopts.h"
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"vertical", no_argument, 0, 'E'},
- {"wait", optional_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"verbose", 'v', "Write more information.", (gptr*) &opt_verbose,
+ (gptr*) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"vertical", 'E',
+ "Print output vertically. Is similar to --relative, but prints output vertically.",
+ (gptr*) &opt_vertical, (gptr*) &opt_vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"wait", 'w', "Wait and retry if connection is down", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout,
+ (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 3600*12, 0,
+ 3600*12, 0, 1, 0},
+ {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (gptr*) &opt_shutdown_timeout,
+ (gptr*) &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
+ SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-static CHANGEABLE_VAR changeable_vars[] = {
- { "connect_timeout", (long*) &opt_connect_timeout, 0, 0, 3600*12, 0, 1},
- { "shutdown_timeout", (long*) &opt_shutdown_timeout, SHUTDOWN_DEF_TIMEOUT, 0,
- 3600*12, 0, 1},
- { 0, 0, 0, 0, 0, 0, 0}
-};
static const char *load_default_groups[]= { "mysqladmin","client",0 };
-int main(int argc,char *argv[])
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c, error = 0,option_index=0;
- MYSQL mysql;
- char *host = NULL,*opt_password=0,*user=0,**commands;
- my_bool tty_password=0;
- MY_INIT(argv[0]);
- mysql_init(&mysql);
- load_defaults("my",load_default_groups,&argc,&argv);
- set_all_changeable_vars( changeable_vars );
+ int error = 0;
- while ((c=getopt_long(argc,argv,
- (char*) "h:i:p::u:#::P:sS:Ct:fq?vVw::WrEO:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'C':
- opt_compress=1;
- break;
- case 'h':
- host = optarg;
- break;
- case 'q': /* Allow old 'q' option */
- case 'f':
- option_force++;
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password=1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- user= my_strdup(optarg,MYF(0));
- break;
-#endif
- case 'i':
- interval=atoi(optarg);
- break;
- case 'P':
- tcp_port= (unsigned int) atoi(optarg);
- break;
- case 'r':
- opt_relative = 1;
- break;
- case 'E':
- opt_vertical = 1;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage();
- return(1);
- }
- break;
- case 's':
- option_silent++;
- break;
- case 'S':
- unix_port= optarg;
- break;
- case 'W':
+ switch(optid) {
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 's':
+ option_silent++;
+ break;
+ case 'W':
#ifdef __WIN__
- unix_port=MYSQL_NAMEDPIPE;
+ unix_port=MYSQL_NAMEDPIPE;
#endif
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/mysqladmin.trace");
- break;
- case 'V':
- print_version();
- exit(0);
- break;
- case 'v':
- opt_verbose=1;
- break;
- case 'w':
- if (optarg)
- {
- if ((option_wait=atoi(optarg)) <= 0)
- option_wait=1;
- }
- else
- option_wait= ~0;
- break;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/mysqladmin.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+ case 'w':
+ if (argument)
+ {
+ if ((option_wait=atoi(argument)) <= 0)
+ option_wait=1;
+ }
+ else
+ option_wait= ~0;
+ break;
#include "sslopt-case.h"
- default:
- fprintf(stderr,"Illegal option character '%c'\n",opterr);
- /* Fall throught */
- case '?':
- case 'I': /* Info */
- error++;
- break;
- case OPT_CHARSETS_DIR:
+ case '?':
+ case 'I': /* Info */
+ error++;
+ break;
+ case OPT_CHARSETS_DIR:
#if MYSQL_VERSION_ID > 32300
- charsets_dir = optarg;
+ charsets_dir = argument;
#endif
- break;
- }
+ break;
}
- argc -= optind;
- commands = argv + optind;
- if (error || argc == 0)
+ if (error)
{
usage();
exit(1);
}
+ return 0;
+}
+
+
+int main(int argc,char *argv[])
+{
+ int error, ho_error;
+ MYSQL mysql;
+ char **commands, **save_argv;
+
+ MY_INIT(argv[0]);
+ mysql_init(&mysql);
+ load_defaults("my",load_default_groups,&argc,&argv);
+ save_argv = argv; /* Save for free_defaults */
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ if (argc == 0)
+ {
+ usage();
+ exit(1);
+ }
+ commands = argv;
if (tty_password)
opt_password = get_tty_password(NullS);
@@ -265,9 +269,9 @@ int main(int argc,char *argv[])
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
+ opt_ssl_capath, opt_ssl_cipher);
#endif /* HAVE_OPENSSL */
- if (sql_connect(&mysql,host,user,opt_password,option_wait))
+ if (sql_connect(&mysql, option_wait))
error = 1;
else
{
@@ -284,7 +288,7 @@ int main(int argc,char *argv[])
if (option_wait && !interrupted)
{
mysql_close(&mysql);
- if (!sql_connect(&mysql,host,user,opt_password,option_wait))
+ if (!sql_connect(&mysql, option_wait))
{
sleep(1); /* Don't retry too rapidly */
continue; /* Retry */
@@ -307,7 +311,7 @@ int main(int argc,char *argv[])
}
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(user,MYF(MY_ALLOW_ZERO_PTR));
- free_defaults(argv);
+ free_defaults(save_argv);
my_end(0);
exit(error ? 1 : 0);
return 0;
@@ -320,15 +324,14 @@ static sig_handler endprog(int signal_number __attribute__((unused)))
}
-static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *password,uint wait)
+static my_bool sql_connect(MYSQL *mysql, uint wait)
{
my_bool info=0;
for (;;)
{
- if (mysql_real_connect(mysql,host,user,password,NullS,tcp_port,unix_port,
- 0))
+ if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port,
+ unix_port, 0))
{
if (info)
{
@@ -337,13 +340,13 @@ static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
}
return 0;
}
-
+
if (!wait)
{
if (!option_silent)
{
if (!host)
- host=LOCAL_HOST;
+ host= (char*) LOCAL_HOST;
my_printf_error(0,"connect to server at '%s' failed\nerror: '%s'",
MYF(ME_BELL), host, mysql_error(mysql));
if (mysql_errno(mysql) == CR_CONNECTION_ERROR)
@@ -400,7 +403,7 @@ static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
- char *status;
+ const char *status;
for (; argc > 0 ; argv++,argc--)
{
@@ -439,8 +442,10 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
char pidfile[FN_REFLEN];
my_bool got_pidfile=0;
- /* Only wait for pidfile on local connections */
- /* If pidfile doesn't exist, continue without pid file checking */
+ /*
+ Only wait for pidfile on local connections
+ If pidfile doesn't exist, continue without pid file checking
+ */
if (mysql->unix_socket)
got_pidfile= !get_pidfile(mysql, pidfile);
if (mysql_shutdown(mysql))
@@ -583,7 +588,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
MYSQL_ROW row;
new_line=1;
- if (mysql_query(mysql,"show variables") ||
+ if (mysql_query(mysql,"show /*!40003 GLOBAL */ variables") ||
!(res=mysql_store_result(mysql)))
{
my_printf_error(0,"unable to show variables; error: '%s'",MYF(ME_BELL),
@@ -649,7 +654,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
else
print_top(res);
-
+
ex_status_printed = 1; /* From now on the output will be relative */
mysql_free_result(res);
break;
@@ -745,7 +750,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
else
puts("Slave stopped");
break;
-
+
case ADMIN_PING:
mysql->reconnect=0; /* We want to know of reconnects */
if (!mysql_ping(mysql))
@@ -788,52 +793,14 @@ static void print_version(void)
static void usage(void)
{
- uint i;
print_version();
puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Administration program for the mysqld daemon.");
printf("Usage: %s [OPTIONS] command command....\n", my_progname);
- printf("\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
- -f, --force Don't ask for confirmation on drop database; with\n\
- multiple commands, continue even if an error occurs\n\
- -?, --help Display this help and exit\n\
- --character-sets-dir=...\n\
- Set the character set directory\n\
- -C, --compress Use compression in server/client protocol\n\
- -h, --host=# Connect to host\n\
- -p, --password[=...] Password to use when connecting to server\n\
- If password is not given it's asked from the tty\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P --port=... Port number to use for connection\n\
- -i, --sleep=sec Execute commands again and again with a sleep between\n\
- -r, --relative Show difference between current and previous values\n\
- when used with -i. Currently works only with\n\
- extended-status\n\
- -E, --vertical Print output vertically. Is similar to --relative,\n\
- but prints output vertically.\n\
- -s, --silent Silently exit if one can't connect to server\n\
- -S, --socket=... Socket file to use for connection\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user\n");
-#endif
- printf("\
- -v, --verbose Write more information\n\
- -V, --version Output version information and exit\n\
- -w, --wait[=retries] Wait and retry if connection is down\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
print_defaults("my",load_default_groups);
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0 ; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- (ulong) *changeable_vars[i].varptr);
-
puts("\nWhere command is a one or more of: (Commands may be shortened)\n\
create databasename Create a new database\n\
drop databasename Delete a database and all its tables\n\
@@ -928,7 +895,7 @@ static void print_header(MYSQL_RES *result)
putchar('|');
while ((field = mysql_fetch_field(result)))
{
- printf(" %-*s|",field->max_length+1,field->name);
+ printf(" %-*s|",(int) field->max_length+1,field->name);
}
putchar('\n');
print_top(result);
@@ -983,11 +950,11 @@ static void print_relative_row(MYSQL_RES *result, MYSQL_ROW cur, uint row)
mysql_field_seek(result, 0);
field = mysql_fetch_field(result);
- printf("| %-*s|", field->max_length + 1, cur[0]);
+ printf("| %-*s|", (int) field->max_length + 1, cur[0]);
field = mysql_fetch_field(result);
tmp = cur[1] ? strtoull(cur[1], NULL, 0) : (ulonglong) 0;
- printf(" %-*s|\n", field->max_length + 1,
+ printf(" %-*s|\n", (int) field->max_length + 1,
llstr((tmp - last_values[row]), buff));
last_values[row] = tmp;
}
@@ -1000,7 +967,7 @@ static void print_relative_row_vert(MYSQL_RES *result __attribute__((unused)),
uint length;
ulonglong tmp;
char buff[22];
-
+
if (!row)
putchar('|');
@@ -1079,7 +1046,7 @@ static void truncate_names()
*ptr++='+';
*ptr=0;
puts(top_line);
-
+
for (i = 0 ; i < ex_var_count; i++)
{
uint sfx=1,j;
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index ac2f3e4efda..4109fbd76d4 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1,36 +1,30 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
#define MYSQL_CLIENT
#undef MYSQL_SERVER
#include "client_priv.h"
#include <time.h>
#include "log_event.h"
-#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
+#define BIN_LOG_HEADER_SIZE 4
+#define PROBE_HEADER_LEN (BIN_LOG_HEADER_SIZE+EVENT_LEN_OFFSET+4)
-#ifndef OS2
-extern "C"
-{
- int simple_command(MYSQL *mysql,enum enum_server_command command,
- const char *arg, uint length, my_bool skipp_check);
- uint net_safe_read(MYSQL* mysql);
-}
-#endif
+
+#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
char server_version[SERVER_VERSION_LENGTH];
uint32 server_id = 0;
@@ -46,26 +40,10 @@ static FILE *result_file;
static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace";
#endif
-static struct option long_options[] =
-{
-#ifndef DBUG_OFF
- {"debug", optional_argument, 0, '#'},
-#endif
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"offset", required_argument, 0, 'o'},
- {"password", required_argument, 0, 'p'},
- {"port", required_argument, 0, 'P'},
- {"position", required_argument, 0, 'j'},
- {"result-file", required_argument, 0, 'r'},
- {"short-form", no_argument, 0, 's'},
- {"table", required_argument, 0, 't'},
- {"user", required_argument, 0, 'u'},
- {"version", no_argument, 0, 'V'},
-};
-
void sql_print_error(const char *format,...);
+static bool one_database = 0;
+static const char* database;
static bool short_form = 0;
static ulonglong offset = 0;
static const char* host = "localhost";
@@ -86,6 +64,44 @@ static void dump_remote_table(NET* net, const char* db, const char* table);
static void die(const char* fmt, ...);
static MYSQL* safe_connect();
+static struct my_option my_long_options[] =
+{
+#ifndef DBUG_OFF
+ {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option,
+ (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"database", 'd', "List entries for just this database (local log only)",
+ (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Get the binlog from server", (gptr*) &host, (gptr*) &host,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"offset", 'o', "Skip the first N entries", (gptr*) &offset, (gptr*) &offset,
+ 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p', "Password to connect to remote server",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Use port to connect to the remote server",
+ (gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0,
+ 0, 0, 0},
+ {"position", 'j', "Start reading the binlog at position N",
+ (gptr*) &position, (gptr*) &position, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"result-file", 'r', "Direct output to a given file", 0, 0, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"short-form", 's', "Just show the queries, no extra info",
+ (gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"table", 't', "Get raw table dump using COM_TABLE_DUMB", (gptr*) &table,
+ (gptr*) &table, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "Connect to the remote server as username",
+ (gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
void sql_print_error(const char *format,...)
{
@@ -110,38 +126,23 @@ static void die(const char* fmt, ...)
static void print_version()
{
- printf("%s Ver 1.6 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE);
+ printf("%s Ver 2.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
static void usage()
{
print_version();
- puts("By Sasha, for your professional use\n\
-This software comes with NO WARRANTY: see the file PUBLIC for details\n");
+ puts("By Monty and Sasha, for your professional use\n\
+This software comes with NO WARRANTY: This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n");
printf("\
Dumps a MySQL binary log in a format usable for viewing or for pipeing to\n\
the mysql command line client\n\n");
- printf("Usage: %s [options] log-files\n",my_progname);
- puts("Options:");
-#ifndef DBUG_OFF
- printf("-#, --debug[=...] Output debug log. (%s)\n",
- default_dbug_option);
-#endif
- printf("\
--?, --help Display this help and exit\n\
--s, --short-form Just show the queries, no extra info\n\
--o, --offset=N Skip the first N entries\n\
--h, --host=server Get the binlog from server\n\
--P, --port=port Use port to connect to the remote server\n\
--u, --user=username Connect to the remote server as username\n\
--p, --password=password Password to connect to remote server\n\
--r, --result-file=file Direct output to a given file\n\
--j, --position=N Start reading the binlog at position N\n\
--t, --table=name Get raw table dump using COM_TABLE_DUMB\n\
--V, --version Print version and exit.\n\
-");
+ printf("Usage: %s [options] log-files\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
}
static void dump_remote_file(NET* net, const char* fname)
@@ -174,76 +175,56 @@ static void dump_remote_file(NET* net, const char* fname)
fflush(result_file);
}
-static int parse_args(int *argc, char*** argv)
-{
- int c, opt_index = 0;
- result_file = stdout;
- while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p:P:r:t:?V", long_options,
- &opt_index)) != EOF)
- {
- switch(c)
- {
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
#ifndef DBUG_OFF
- case '#':
- DBUG_PUSH(optarg ? optarg : default_dbug_option);
- break;
+ case '#':
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+ break;
#endif
- case 's':
- short_form = 1;
- break;
-
- case 'o':
- offset = strtoull(optarg,(char**) 0, 10);
- break;
-
- case 'j':
- position = strtoull(optarg,(char**) 0, 10);
- break;
-
- case 'h':
- use_remote = 1;
- host = my_strdup(optarg, MYF(0));
- break;
-
- case 'P':
- use_remote = 1;
- port = atoi(optarg);
- break;
-
- case 'p':
- use_remote = 1;
- pass = my_strdup(optarg, MYF(0));
- break;
-
- case 'r':
- if (!(result_file = my_fopen(optarg, O_WRONLY | O_BINARY, MYF(MY_WME))))
- exit(1);
- break;
-
- case 'u':
- use_remote = 1;
- user = my_strdup(optarg, MYF(0));
- break;
-
- case 't':
- table = my_strdup(optarg, MYF(0));
- break;
-
- case 'V':
- print_version();
- exit(0);
+ case 'd':
+ one_database = 1;
+ break;
+ case 'h':
+ use_remote = 1;
+ break;
+ case 'P':
+ use_remote = 1;
+ break;
+ case 'p':
+ use_remote = 1;
+ pass = my_strdup(argument, MYF(0));
+ break;
+ case 'r':
+ if (!(result_file = my_fopen(argument, O_WRONLY | O_BINARY, MYF(MY_WME))))
+ exit(1);
+ break;
+ case 'u':
+ use_remote = 1;
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ default:
+ usage();
+ exit(0);
+ }
+ return 0;
+}
- case '?':
- default:
- usage();
- exit(0);
- }
- }
+static int parse_args(int *argc, char*** argv)
+{
+ int ho_error;
- (*argc)-=optind;
- (*argv)+=optind;
+ result_file = stdout;
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
return 0;
}
@@ -254,7 +235,7 @@ static MYSQL* safe_connect()
if(!local_mysql)
die("Failed on mysql_init");
- if(!mysql_real_connect(local_mysql, host, user, pass, 0, port, 0, 0))
+ if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, 0, 0))
die("failed on connect: %s", mysql_error(local_mysql));
return local_mysql;
@@ -262,7 +243,7 @@ static MYSQL* safe_connect()
static void dump_log_entries(const char* logname)
{
- if(use_remote)
+ if (use_remote)
dump_remote_log_entries(logname);
else
dump_local_log_entries(logname);
@@ -274,29 +255,76 @@ static void dump_remote_table(NET* net, const char* db, const char* table)
char * p = buf;
uint table_len = (uint) strlen(table);
uint db_len = (uint) strlen(db);
- if(table_len + db_len > sizeof(buf) - 2)
+ if (table_len + db_len > sizeof(buf) - 2)
die("Buffer overrun");
-
+
*p++ = db_len;
memcpy(p, db, db_len);
p += db_len;
*p++ = table_len;
memcpy(p, table, table_len);
-
- if(simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
+
+ if (simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
die("Error sending the table dump command");
- for(;;)
+ for (;;)
{
uint packet_len = my_net_read(net);
- if(packet_len == 0) break; // end of file
- if(packet_len == packet_error)
+ if (packet_len == 0) break; // end of file
+ if (packet_len == packet_error)
die("Error reading packet in table dump");
my_fwrite(result_file, (byte*)net->read_pos, packet_len, MYF(MY_WME));
fflush(result_file);
}
}
+static int check_master_version(MYSQL* mysql)
+{
+ MYSQL_RES* res = 0;
+ MYSQL_ROW row;
+ const char* version;
+ int old_format = 0;
+
+ if (mysql_query(mysql, "SELECT VERSION()") ||
+ !(res = mysql_store_result(mysql)))
+ {
+ mysql_close(mysql);
+ die("Error checking master version: %s",
+ mysql_error(mysql));
+ }
+ if (!(row = mysql_fetch_row(res)))
+ {
+ mysql_free_result(res);
+ mysql_close(mysql);
+ die("Master returned no rows for SELECT VERSION()");
+ return 1;
+ }
+ if (!(version = row[0]))
+ {
+ mysql_free_result(res);
+ mysql_close(mysql);
+ die("Master reported NULL for the version");
+ }
+
+ switch (*version) {
+ case '3':
+ old_format = 1;
+ break;
+ case '4':
+ case '5':
+ old_format = 0;
+ break;
+ default:
+ sql_print_error("Master reported unrecognized MySQL version '%s'",
+ version);
+ mysql_free_result(res);
+ mysql_close(mysql);
+ return 1;
+ }
+ mysql_free_result(res);
+ return old_format;
+}
+
static void dump_remote_log_entries(const char* logname)
{
@@ -304,37 +332,41 @@ static void dump_remote_log_entries(const char* logname)
char last_db[FN_REFLEN+1] = "";
uint len;
NET* net = &mysql->net;
- if(!position) position = 4; // protect the innocent from spam
- if (position < 4)
+ int old_format;
+ old_format = check_master_version(mysql);
+
+ if (!position)
+ position = BIN_LOG_HEADER_SIZE; // protect the innocent from spam
+ if (position < BIN_LOG_HEADER_SIZE)
{
- position = 4;
+ position = BIN_LOG_HEADER_SIZE;
// warn the guity
- sql_print_error("Warning: The position in the binary log can't be less than 4.\nStarting from position 4\n");
+ sql_print_error("Warning: The position in the binary log can't be less than %d.\nStarting from position %d\n", BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE);
}
int4store(buf, position);
- int2store(buf + 4, binlog_flags);
+ int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
len = (uint) strlen(logname);
int4store(buf + 6, 0);
memcpy(buf + 10, logname,len);
- if(simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
+ if (simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
die("Error sending the log dump command");
-
- for(;;)
+
+ for (;;)
{
+ const char *error;
len = net_safe_read(mysql);
if (len == packet_error)
die("Error reading packet from server: %s", mysql_error(mysql));
- if(len == 1 && net->read_pos[0] == 254)
+ if (len == 1 && net->read_pos[0] == 254)
break; // end of data
DBUG_PRINT("info",( "len= %u, net->read_pos[5] = %d\n",
len, net->read_pos[5]));
- Log_event * ev = Log_event::read_log_event(
- (const char*) net->read_pos + 1 ,
- len - 1);
- if(ev)
+ Log_event *ev = Log_event::read_log_event((const char*) net->read_pos + 1 ,
+ len - 1, &error, old_format);
+ if (ev)
{
ev->print(result_file, short_form, last_db);
- if(ev->get_type_code() == LOAD_EVENT)
+ if (ev->get_type_code() == LOAD_EVENT)
dump_remote_file(net, ((Load_log_event*)ev)->fname);
delete ev;
}
@@ -343,12 +375,33 @@ static void dump_remote_log_entries(const char* logname)
}
}
+
+static int check_header(IO_CACHE* file)
+{
+ byte buf[PROBE_HEADER_LEN];
+ int old_format=0;
+
+ my_off_t pos = my_b_tell(file);
+ my_b_seek(file, (my_off_t)0);
+ if (my_b_read(file, buf, sizeof(buf)))
+ die("Failed reading header");
+ if (buf[EVENT_TYPE_OFFSET+4] == START_EVENT)
+ {
+ uint event_len;
+ event_len = uint4korr(buf + EVENT_LEN_OFFSET + 4);
+ old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN);
+ }
+ my_b_seek(file, pos);
+ return old_format;
+}
+
static void dump_local_log_entries(const char* logname)
{
File fd = -1;
IO_CACHE cache,*file= &cache;
ulonglong rec_count = 0;
char last_db[FN_REFLEN+1] = "";
+ bool old_format = 0;
if (logname && logname[0] != '-')
{
@@ -357,12 +410,14 @@ static void dump_local_log_entries(const char* logname)
if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0,
MYF(MY_WME | MY_NABP)))
exit(1);
+ old_format = check_header(file);
}
else
{
if (init_io_cache(file, fileno(result_file), 0, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
exit(1);
+ old_format = check_header(file);
if (position)
{
/* skip 'position' characters from stdout */
@@ -371,7 +426,7 @@ static void dump_local_log_entries(const char* logname)
for (length= (my_off_t) position ; length > 0 ; length-=tmp)
{
tmp=min(length,sizeof(buff));
- if (my_b_read(file,buff, (uint) tmp))
+ if (my_b_read(file, buff, (uint) tmp))
exit(1);
}
}
@@ -381,19 +436,19 @@ static void dump_local_log_entries(const char* logname)
if (!position)
{
- char magic[4];
+ char magic[BIN_LOG_HEADER_SIZE];
if (my_b_read(file, (byte*) magic, sizeof(magic)))
die("I/O error reading binlog magic number");
- if(memcmp(magic, BINLOG_MAGIC, 4))
+ if (memcmp(magic, BINLOG_MAGIC, 4))
die("Bad magic number; The file is probably not a MySQL binary log");
}
-
+
for (;;)
{
char llbuff[21];
my_off_t old_off = my_b_tell(file);
- Log_event* ev = Log_event::read_log_event(file);
+ Log_event* ev = Log_event::read_log_event(file, old_format);
if (!ev)
{
if (file->error)
@@ -405,6 +460,37 @@ Could not read entry at offset %s : Error in log format or read error",
}
if (rec_count >= offset)
{
+ // see if we should skip this event (only care about queries for now)
+ if (one_database)
+ {
+ if (ev->get_type_code() == QUERY_EVENT)
+ {
+ //const char * log_dbname = ev->get_db();
+ const char * log_dbname = ((Query_log_event*)ev)->db;
+ //printf("entry: %llu, database: %s\n", rec_count, log_dbname);
+
+ if ((log_dbname != NULL) && (strcmp(log_dbname, database)))
+ {
+ //printf("skipping, %s is not %s\n", log_dbname, database);
+ rec_count++;
+ delete ev;
+ continue; // next
+ }
+#ifndef DBUG_OFF
+ else
+ {
+ printf("no skip\n");
+ }
+#endif
+ }
+#ifndef DBUG_OFF
+ else
+ {
+ const char * query_type = ev->get_type_str();
+ printf("not query -- %s\n", query_type);
+ }
+#endif
+ }
if (!short_form)
fprintf(result_file, "# at %s\n",llstr(old_off,llbuff));
@@ -413,7 +499,7 @@ Could not read entry at offset %s : Error in log format or read error",
rec_count++;
delete ev;
}
- if(fd >= 0)
+ if (fd >= 0)
my_close(fd, MYF(MY_WME));
end_io_cache(file);
}
@@ -424,34 +510,30 @@ int main(int argc, char** argv)
MY_INIT(argv[0]);
parse_args(&argc, (char***)&argv);
- if(!argc && !table)
+ if (!argc && !table)
{
usage();
return -1;
}
- if(use_remote)
- {
+ if (use_remote)
mysql = safe_connect();
- }
if (table)
{
- if(!use_remote)
+ if (!use_remote)
die("You must specify connection parameter to get table dump");
- char* db = (char*)table;
+ char* db = (char*) table;
char* tbl = (char*) strchr(table, '.');
- if(!tbl)
+ if (!tbl)
die("You must use database.table syntax to specify the table");
*tbl++ = 0;
dump_remote_table(&mysql->net, db, tbl);
}
else
{
- while(--argc >= 0)
- {
+ while (--argc >= 0)
dump_log_entries(*(argv++));
- }
}
if (result_file != stdout)
my_fclose(result_file, MYF(0));
@@ -470,3 +552,5 @@ int main(int argc, char** argv)
#else
#include "log_event.cc"
#endif
+
+FIX_GCC_LINKING_PROBLEM
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 7c556a1cee6..948f9ca8477 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
-#define CHECK_VERSION "1.02"
+#define CHECK_VERSION "2.4"
#include "client_priv.h"
#include <m_ctype.h>
@@ -33,7 +33,8 @@ static MYSQL mysql_connection, *sock = 0;
static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
opt_compress = 0, opt_databases = 0, opt_fast = 0,
opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
- opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0;
+ opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
+ tty_password = 0;
static uint verbose = 0, opt_mysql_port=0;
static my_string opt_mysql_unix_port = 0;
static char *opt_password = 0, *current_user = 0, *default_charset = 0,
@@ -43,45 +44,97 @@ DYNAMIC_ARRAY tables4repair;
enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE};
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"all-databases", no_argument, 0, 'A'},
- {"all-in-1", no_argument, 0, '1'},
- {"auto-repair", no_argument, 0, OPT_AUTO_REPAIR},
- {"analyze", no_argument, 0, 'a'},
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR},
- {"check", no_argument, 0, 'c'},
- {"check-only-changed", no_argument, 0, 'C'},
- {"compress", no_argument, 0, OPT_COMPRESS},
- {"databases", no_argument, 0, 'B'},
- {"debug", optional_argument, 0, '#'},
- {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
- {"fast", no_argument, 0, 'F'},
- {"force", no_argument, 0, 'f'},
- {"extended", no_argument, 0, 'e'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"medium-check", no_argument, 0, 'm'},
- {"optimize", no_argument, 0, 'o'},
- {"password", optional_argument, 0, 'p'},
+ {"all-databases", 'A',
+ "Check all the databases. This will be same as --databases with all databases selected.",
+ (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"analyze", 'a', "Analyze given tables.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"all-in-1", '1',
+ "Instead of making one query for each table, execute all queries in 1 query separately for each database. Table names will be in a comma separeted list.",
+ (gptr*) &opt_all_in_1, (gptr*) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"auto-repair", OPT_AUTO_REPAIR,
+ "If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
+ (gptr*) &opt_auto_repair, (gptr*) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"check", 'c', "Check table for errors", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"check-only-changed", 'C',
+ "Check only tables that have changed since last check or haven't been closed properly.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"databases", 'B',
+ "To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
+ (gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fast",'F', "Check only tables that hasn't been closed properly",
+ (gptr*) &opt_fast, (gptr*) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"force", 'f', "Continue even if we get an sql-error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"extended", 'e',
+ "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will run an extended repair on the table, which may not only take a long time to execute, but may produce a lot of garbage rows also!",
+ (gptr*) &opt_extended, (gptr*) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host",'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"medium-check", 'm',
+ "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's solicited on the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"quick", no_argument, 0, 'q'},
- {"repair", no_argument, 0, 'r'},
- {"silent", no_argument, 0, 's'},
- {"socket", required_argument, 0, 'S'},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"quick", 'q',
+ "If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table.",
+ (gptr*) &opt_quick, (gptr*) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"repair", 'r',
+ "Can fix almost anything except unique keys that aren't unique.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Print only error messages.", (gptr*) &opt_silent,
+ (gptr*) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
- {"tables", no_argument, 0, OPT_TABLES},
+ {"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &current_user,
+ (gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-
+
static const char *load_default_groups[] = { "mysqlcheck", "client", 0 };
@@ -130,78 +183,78 @@ static void usage(void)
printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
my_progname);
printf("OR %s [OPTIONS] --all-databases\n", my_progname);
- printf("\
- -A, --all-databases Check all the databases. This will be same as\n\
- --databases with all databases selected\n\
- -1, --all-in-1 Instead of making one query for each table, execute\n\
- all queries in 1 query separately for each database.\n\
- Table names will be in a comma separeted list.\n\
- -a, --analyze Analyze given tables.\n\
- --auto-repair If a checked table is corrupted, automatically fix\n\
- it. Repairing will be done after all tables have\n\
- been checked, if corrupted ones were found.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename'\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -c, --check Check table for errors\n\
- -C, --check-only-changed\n\
- Check only tables that have changed since last check\n\
- or haven't been closed properly.\n\
- --compress Use compression in server/client protocol.\n\
- -?, --help Display this help message and exit.\n\
- -B, --databases To check several databases. Note the difference in\n\
- usage; In this case no tables are given. All name\n\
- arguments are regarded as databasenames.\n\
- --default-character-set=...\n\
- Set the default character set\n\
- -F, --fast Check only tables that hasn't been closed properly\n\
- -f, --force Continue even if we get an sql-error.\n\
- -e, --extended If you are using this option with CHECK TABLE,\n\
- it will ensure that the table is 100 percent\n\
- consistent, but will take a long time.\n\n");
-printf("\
- If you are using this option with REPAIR TABLE,\n\
- it will run an extended repair on the table, which\n\
- may not only take a long time to execute, but\n\
- may produce a lot of garbage rows also!\n\
- -h, --host=... Connect to host.\n\
- -m, --medium-check Faster than extended-check, but only finds 99.99 percent\n\
- of all errors. Should be good enough for most cases.\n\
- -o, --optimize Optimize table\n\
- -p, --password[=...] Password to use when connecting to server.\n\
- If password is not given it's solicited on the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P, --port=... Port number to use for connection.\n\
- -q, --quick If you are using this option with CHECK TABLE, it\n\
- prevents the check from scanning the rows to check\n\
- for wrong links. This is the fastest check.\n\n\
- If you are using this option with REPAIR TABLE, it\n\
- will try to repair only the index tree. This is\n\
- the fastest repair method for a table.\n\
- -r, --repair Can fix almost anything except unique keys that aren't\n\
- unique.\n\
- -s, --silent Print only error messages.\n\
- -S, --socket=... Socket file to use for connection.\n\
- --tables Overrides option --databases (-B).\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -v, --verbose Print info about the various stages.\n\
- -V, --version Output version information and exit.\n");
print_defaults("my", load_default_groups);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
} /* usage */
-
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'a':
+ what_to_do = DO_ANALYZE;
+ break;
+ case 'c':
+ what_to_do = DO_CHECK;
+ break;
+ case 'C':
+ what_to_do = DO_CHECK;
+ opt_check_only_changed = 1;
+ break;
+ case 'I': /* Fall through */
+ case '?':
+ usage();
+ exit(0);
+ case 'm':
+ what_to_do = DO_CHECK;
+ opt_medium_check = 1;
+ break;
+ case 'o':
+ what_to_do = DO_OPTIMIZE;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start = argument;
+ my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ opt_password = my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1] = 0; /* Cut length of argument */
+ }
+ else
+ tty_password = 1;
+ break;
+ case 'r':
+ what_to_do = DO_REPAIR;
+ break;
+ case 'W':
+#ifdef __WIN__
+ opt_mysql_unix_port = MYSQL_NAMEDPIPE;
+#endif
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case OPT_TABLES:
+ opt_databases = 0;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'V': print_version(); exit(0);
+#include "sslopt-case.h"
+ }
+ return 0;
+}
+
+
static int get_options(int *argc, char ***argv)
{
- int c, option_index;
- my_bool tty_password = 0;
+ int ho_error;
if (*argc == 1)
{
@@ -210,119 +263,10 @@ static int get_options(int *argc, char ***argv)
}
load_defaults("my", load_default_groups, argc, argv);
- while ((c = getopt_long(*argc, *argv, "#::p::h:u:P:S:BaAcCdeFfmqorsvVw:?I1",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
- what_to_do = DO_ANALYZE;
- break;
- case '1':
- opt_all_in_1 = 1;
- break;
- case 'A':
- opt_alldbs = 1;
- break;
- case OPT_AUTO_REPAIR:
- opt_auto_repair = 1;
- break;
- case OPT_DEFAULT_CHARSET:
- default_charset = optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir = optarg;
- break;
- case 'c':
- what_to_do = DO_CHECK;
- break;
- case 'C':
- what_to_do = DO_CHECK;
- opt_check_only_changed = 1;
- break;
- case 'e':
- opt_extended = 1;
- break;
- case OPT_COMPRESS:
- opt_compress = 1;
- break;
- case 'B':
- opt_databases = 1;
- break;
- case 'F':
- opt_fast = 1;
- break;
- case 'f':
- ignore_errors = 1;
- break;
- case 'I': /* Fall through */
- case '?':
- usage();
- exit(0);
- case 'h':
- my_free(current_host, MYF(MY_ALLOW_ZERO_PTR));
- current_host = my_strdup(optarg, MYF(MY_WME));
- break;
- case 'm':
- what_to_do = DO_CHECK;
- opt_medium_check = 1;
- break;
- case 'o':
- what_to_do = DO_OPTIMIZE;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- current_user = optarg;
- break;
-#endif
- case 'p':
- if (optarg)
- {
- char *start = optarg;
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
- opt_password = my_strdup(optarg, MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1] = 0; /* Cut length of argument */
- }
- else
- tty_password = 1;
- break;
- case 'P':
- opt_mysql_port = (unsigned int) atoi(optarg);
- break;
- case 'q':
- opt_quick = 1;
- break;
- case 'r':
- what_to_do = DO_REPAIR;
- break;
- case 'S':
- opt_mysql_unix_port = optarg;
- break;
- case 's':
- opt_silent = 1;
- break;
- case 'W':
-#ifdef __WIN__
- opt_mysql_unix_port = MYSQL_NAMEDPIPE;
-#endif
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case OPT_TABLES:
- opt_databases = 0;
- break;
- case 'v':
- verbose++;
- break;
- case 'V': print_version(); exit(0);
- default:
- fprintf(stderr, "%s: Illegal option character '%c'\n", my_progname,
- opterr);
-#include "sslopt-case.h"
- }
- }
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (!what_to_do)
{
int pnlen = strlen(my_progname);
@@ -343,8 +287,6 @@ static int get_options(int *argc, char ***argv)
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- (*argc) -= optind;
- (*argv) += optind;
if (*argc > 0 && opt_alldbs)
{
printf("You should give only options, no arguments at all, with option\n");
@@ -411,7 +353,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
for (i = 0; i < tables; i++)
tot_length += strlen(*(table_names + i)) + 1;
-
+
if (!(table_names_comma_sep = (char *)
my_malloc((sizeof(char) * tot_length) + 1, MYF(MY_WME))))
return 1;
@@ -444,7 +386,7 @@ static int process_all_tables_in_db(char *database)
if (!(mysql_query(sock, "SHOW TABLES") ||
(res = mysql_store_result(sock))))
return 1;
-
+
if (opt_all_in_1)
{
char *tables, *end;
@@ -453,7 +395,7 @@ static int process_all_tables_in_db(char *database)
while ((row = mysql_fetch_row(res)))
tot_length += strlen(row[0]) + 1;
mysql_data_seek(res, 0);
-
+
if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+1, MYF(MY_WME))))
{
mysql_free_result(res);
@@ -521,10 +463,10 @@ static int handle_request_for_tables(char *tables, uint length)
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
return 1;
- sprintf(query, "%s TABLE %s %s", op, tables, options);
+ sprintf(query, "%s TABLE `%s` %s", op, tables, options);
if (mysql_query(sock, query))
{
- sprintf(message, "when executing '%s TABLE ... %s", op, options);
+ sprintf(message, "when executing '%s TABLE `%s` %s", op, tables,options);
DBerror(sock, message);
return 1;
}
@@ -590,7 +532,7 @@ static int dbConnect(char *host, char *user, char *passwd)
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
+ opt_ssl_capath, opt_ssl_cipher);
#endif
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
@@ -646,7 +588,7 @@ int main(int argc, char **argv)
if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
- if (opt_auto_repair &&
+ if (opt_auto_repair &&
my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
{
first_error = 1;
diff --git a/client/mysqldump.c b/client/mysqldump.c
index d7d54a13c57..54bfbef004b 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -33,9 +33,10 @@
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
** and adapted to mysqldump 05/11/01 by Jani Tolonen
+** Added --single-transaction option 06/06/2002 by Peter Zaitsev
*/
-#define DUMP_VERSION "8.22"
+#define DUMP_VERSION "9.06"
#include <my_global.h>
#include <my_sys.h>
@@ -46,7 +47,6 @@
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
-#include <getopt.h>
/* Exit codes */
@@ -64,6 +64,9 @@
#define SHOW_EXTRA 5
#define QUOTE_CHAR '`'
+/* Size of buffer for dump's select query */
+#define QUERY_LENGTH 1536
+
static char *add_load_option(char *ptr, const char *object,
const char *statement);
@@ -73,7 +76,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0,
ignore=0,opt_drop=0,opt_keywords=0,opt_lock=0,opt_compress=0,
opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0,
opt_alldbs=0,opt_create_db=0,opt_first_slave=0,
- opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0;
+ opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0,
+ tty_password=0,opt_single_transaction=0;
static MYSQL mysql_connection,*sock=0;
static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
@@ -87,72 +91,158 @@ static DYNAMIC_STRING extended_row;
#include "sslopt-vars.h"
FILE *md_result_file;
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"all-databases", no_argument, 0, 'A'},
- {"all", no_argument, 0, 'a'},
- {"add-drop-table", no_argument, 0, OPT_DROP},
- {"add-locks", no_argument, 0, OPT_LOCKS},
- {"allow-keywords", no_argument, 0, OPT_KEYWORDS},
- {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
- {"complete-insert", no_argument, 0, 'c'},
- {"compress", no_argument, 0, 'C'},
- {"databases", no_argument, 0, 'B'},
- {"debug", optional_argument, 0, '#'},
- {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
- {"delayed-insert", no_argument, 0, OPT_DELAYED},
- {"disable-keys", no_argument, 0, 'K'},
- {"extended-insert", no_argument, 0, 'e'},
- {"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
- {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC},
- {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
- {"fields-escaped-by", required_argument, 0, (int) OPT_ESC},
- {"first-slave", no_argument, 0, 'x'},
- {"flush-logs", no_argument, 0, 'F'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"lines-terminated-by", required_argument, 0, (int) OPT_LTB},
- {"lock-tables", no_argument, 0, 'l'},
- {"master-data", no_argument, 0, OPT_MASTER_DATA},
- {"no-autocommit", no_argument, 0, OPT_AUTOCOMMIT},
- {"no-create-db", no_argument, 0, 'n'},
- {"no-create-info", no_argument, 0, 't'},
- {"no-data", no_argument, 0, 'd'},
- {"opt", no_argument, 0, OPT_OPTIMIZE},
- {"password", optional_argument, 0, 'p'},
+ {"all-databases", 'A',
+ "Dump all the databases. This will be same as --databases with all databases selected.",
+ (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"all", 'a', "Include all MySQL specific create options.",
+ (gptr*) &create_options, (gptr*) &create_options, 0, GET_BOOL, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
+ (gptr*) &opt_drop, (gptr*) &opt_drop, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"add-locks", OPT_LOCKS, "Add locks around insert statements.",
+ (gptr*) &opt_lock, (gptr*) &opt_lock, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"allow-keywords", OPT_KEYWORDS,
+ "Allow creation of column names that are keywords.", (gptr*) &opt_keywords,
+ (gptr*) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag,
+ (gptr*) &cFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"databases", 'B',
+ "To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output.",
+ (gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set.", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED.",
+ (gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"disable-keys", 'K',
+ "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys,
+ (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"extended-insert", 'e',
+ "Allows utilization of the new, much faster INSERT syntax.",
+ (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"fields-terminated-by", OPT_FTB,
+ "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated,
+ (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-enclosed-by", OPT_ENC,
+ "Fields in the importfile are enclosed by ...", (gptr*) &enclosed,
+ (gptr*) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ {"fields-optionally-enclosed-by", OPT_O_ENC,
+ "Fields in the i.file are opt. enclosed by ...", (gptr*) &opt_enclosed,
+ (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
+ (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"first-slave", 'x', "Locks all tables across all databases.",
+ (gptr*) &opt_first_slave, (gptr*) &opt_first_slave, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"flush-logs", 'F', "Flush logs file in server before starting dump.",
+ (gptr*) &flush_logs, (gptr*) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"force", 'f', "Continue even if we get an sql-error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
+ (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables,
+ (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-data", OPT_MASTER_DATA,
+ "This will cause the master position and filename to be appended to your output. This will automagically enable --first-slave.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-autocommit", OPT_AUTOCOMMIT,
+ "Wrap tables with autocommit/commit statements.",
+ (gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"single-transaction", OPT_TRANSACTION,
+ "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.",
+ (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"no-create-db", 'n',
+ "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}",
+ (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"no-create-info", 't', "Don't write table creation info.",
+ (gptr*) &tFlag, (gptr*) &tFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-data", 'd', "No row information.", (gptr*) &dFlag, (gptr*) &dFlag, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"opt", OPT_OPTIMIZE,
+ "Same as --add-drop-table --add-locks --all --quick --extended-insert --lock-tables --disable-keys",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's solicited on the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"quick", no_argument, 0, 'q'},
- {"quote-names", no_argument, 0, 'Q'},
- {"result-file", required_argument, 0, 'r'},
- {"set-variable", required_argument, 0, 'O'},
- {"socket", required_argument, 0, 'S'},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"quick", 'q', "Don't buffer query, dump directly to stdout.",
+ (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quote-names",'Q', "Quote table and column names with a `",
+ (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"result-file", 'r',
+ "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\n\\r' (newline + carriage return).",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
- {"tab", required_argument, 0, 'T'},
- {"tables", no_argument, 0, OPT_TABLES},
+ {"tab",'T',
+ "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
+ (gptr*) &path, (gptr*) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tables", OPT_TABLES, "Overrides option --databases (-B).",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.",
+ (gptr*) &current_user, (gptr*) &current_user, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"where", required_argument, 0, 'w'},
- {"xml", no_argument, 0, 'X'},
- {0, 0, 0, 0}
+ {"verbose", 'v', "Print info about the various stages.",
+ (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version",'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"where", 'w', "Dump only selected records; QUOTES mandatory!",
+ (gptr*) &where, (gptr*) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
+ (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0,
+ GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, 512*1024L*1024L,
+ MALLOC_OVERHEAD, 1024, 0},
+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
+ (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0,
+ GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
+ MALLOC_OVERHEAD-1024, 1024, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static const char *load_default_groups[]= { "mysqldump","client",0 };
-CHANGEABLE_VAR md_changeable_vars[] = {
- { "max_allowed_packet", (long*) &max_allowed_packet,24*1024*1024,4096,
- 16*1024L*1024L,MALLOC_OVERHEAD,1024},
- { "net_buffer_length", (long*) &net_buffer_length,1024*1024L-1025,4096,
- 16*1024L*1024L,MALLOC_OVERHEAD+1024,1024},
- { 0, 0, 0, 0, 0, 0, 0}
-};
-
static void safe_exit(int error);
static void write_header(FILE *sql_file, char *db_name);
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
@@ -175,7 +265,6 @@ static void print_version(void)
static void usage(void)
{
- uint i;
print_version();
puts("By Igor Romanenko, Monty, Jani & Sinisa");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
@@ -184,101 +273,9 @@ static void usage(void)
printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
my_progname);
printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
- printf("\n\
- -A, --all-databases Dump all the databases. This will be same as\n\
- --databases with all databases selected.\n\
- -a, --all Include all MySQL specific create options.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`.\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -?, --help Display this help message and exit.\n\
- -B, --databases To dump several databases. Note the difference in\n\
- usage; In this case no tables are given. All name\n\
- arguments are regarded as databasenames.\n\
- 'USE db_name;' will be included in the output\n\
- -c, --complete-insert Use complete insert statements.\n\
- -C, --compress Use compression in server/client protocol.\n\
- --default-character-set=...\n\
- Set the default character set\n\
- -e, --extended-insert Allows utilization of the new, much faster\n\
- INSERT syntax.\n\
- --add-drop-table Add a 'drop table' before each create.\n\
- --add-locks Add locks around insert statements.\n\
- --allow-keywords Allow creation of column names that are keywords.\n\
- --delayed-insert Insert rows with INSERT DELAYED.\n\
- --master-data This will cause the master position and filename to \n\
- be appended to your output. This will automagically \n\
- enable --first-slave.\n\
- -F, --flush-logs Flush logs file in server before starting dump.\n\
- -f, --force Continue even if we get an sql-error.\n\
- -h, --host=... Connect to host.\n");
-puts("\
- -l, --lock-tables Lock all tables for read.\n\
- --no-autocommit Wrap tables with autocommit/commit statements.\n\
- -K, --disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\
- and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */;\n\
- will be put in the output.\n\
- -n, --no-create-db 'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'\n\
- will not be put in the output. The above line will\n\
- be added otherwise, if --databases or\n\
- --all-databases option was given.\n\
- -t, --no-create-info Don't write table creation info.\n\
- -d, --no-data No row information.\n\
- -O, --set-variable var=option\n\
- give a variable a value. --help lists variables\n\
- --opt Same as --add-drop-table --add-locks --all --quick\n\
- --extended-insert --lock-tables --disable-keys\n\
- -p, --password[=...] Password to use when connecting to server.\n\
- If password is not given it's solicited on the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P, --port=... Port number to use for connection.\n\
- -q, --quick Don't buffer query, dump directly to stdout.\n\
- -Q, --quote-names Quote table and column names with `\n\
- -r, --result-file=... Direct output to a given file. This option should be\n\
- used in MSDOS, because it prevents new line '\\n'\n\
- from being converted to '\\n\\r' (newline + carriage\n\
- return).\n\
- -S, --socket=... Socket file to use for connection.\n\
- --tables Overrides option --databases (-B).\n");
-#include "sslopt-usage.h"
- printf("\
- -T, --tab=... Creates tab separated textfile for each table to\n\
- given path. (creates .sql and .txt files).\n\
- NOTE: This only works if mysqldump is run on\n\
- the same machine as the mysqld daemon.\n");
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -v, --verbose Print info about the various stages.\n\
- -V, --version Output version information and exit.\n\
- -w, --where= dump only selected records; QUOTES mandatory!\n\
- -X, --xml dump a database as well formed XML\n\
- -x, --first-slave Locks all tables across all databases.\n\
- EXAMPLES: \"--where=user=\'jimf\'\" \"-wuserid>1\" \"-wuserid<1\"\n\
- Use -T (--tab=...) with --fields-...\n\
- --fields-terminated-by=...\n\
- Fields in the textfile are terminated by ...\n\
- --fields-enclosed-by=...\n\
- Fields in the importfile are enclosed by ...\n\
- --fields-optionally-enclosed-by=...\n\
- Fields in the i.file are opt. enclosed by ...\n\
- --fields-escaped-by=...\n\
- Fields in the i.file are escaped by ...\n\
- --lines-terminated-by=...\n\
- Lines in the i.file are terminated by ...\n\
-");
print_defaults("my",load_default_groups);
-
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0 ; md_changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- md_changeable_vars[i].name,
- (ulong) *md_changeable_vars[i].varptr);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
} /* usage */
@@ -300,181 +297,92 @@ static void write_header(FILE *sql_file, char *db_name)
} /* write_header */
-static int get_options(int *argc,char ***argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index;
- my_bool tty_password=0;
-
- md_result_file=stdout;
- load_defaults("my",load_default_groups,argc,argv);
- set_all_changeable_vars(md_changeable_vars);
- while ((c=getopt_long(*argc,*argv,
- "#::p::h:u:O:P:r:S:T:EBaAcCdefFKlnqQtvVw:?IxX",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case OPT_MASTER_DATA:
- opt_master_data=1;
- opt_first_slave=1;
- break;
- case OPT_AUTOCOMMIT:
- opt_autocommit=1;
- break;
- case 'a':
- create_options=1;
- break;
- case 'e':
- extended_insert=1;
- break;
- case 'A':
- opt_alldbs=1;
- break;
- case OPT_DEFAULT_CHARSET:
- default_charset= optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir= optarg;
- break;
- case 'f':
- ignore_errors=1;
- break;
- case 'F':
- flush_logs=1;
- break;
- case 'h':
- my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
- current_host=my_strdup(optarg,MYF(MY_WME));
- break;
- case 'K':
- opt_disable_keys=1;
- break;
- case 'n':
- opt_create_db = 1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- current_user=optarg;
- break;
-#endif
- case 'O':
- if (set_changeable_var(optarg, md_changeable_vars))
- {
- usage();
- return(1);
- }
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password=1;
- break;
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'r':
- if (!(md_result_file = my_fopen(optarg, O_WRONLY | O_BINARY,
- MYF(MY_WME))))
- exit(1);
- break;
- case 'S':
- opt_mysql_unix_port= optarg;
- break;
- case 'W':
+ switch(optid) {
+ case OPT_MASTER_DATA:
+ opt_master_data=1;
+ opt_first_slave=1;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 'r':
+ if (!(md_result_file = my_fopen(argument, O_WRONLY | O_BINARY,
+ MYF(MY_WME))))
+ exit(1);
+ break;
+ case 'W':
#ifdef __WIN__
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
#endif
- break;
- case 'T':
- path= optarg;
- opt_disable_keys=0;
- break;
- case 'B':
- opt_databases = 1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'c': cFlag=1; break;
- case 'C':
- opt_compress=1;
- break;
- case 'd': dFlag=1; break;
- case 'l': lock_tables=1; break;
- case 'q': quick=1; break;
- case 'Q': opt_quoted=1; break;
- case 't': tFlag=1; break;
- case 'v': verbose=1; break;
- case 'V': print_version(); exit(0);
- case 'w':
- where=optarg;
- break;
- case 'X':
- opt_xml = 1;
- opt_disable_keys=0;
- break;
- case 'x':
- opt_first_slave=1;
- break;
- default:
- fprintf(stderr,"%s: Illegal option character '%c'\n",my_progname,opterr);
- /* Fall throught */
- case 'I':
- case '?':
- usage();
- exit(0);
- case (int) OPT_FTB:
- fields_terminated= optarg;
- break;
- case (int) OPT_LTB:
- lines_terminated= optarg;
- break;
- case (int) OPT_ENC:
- enclosed= optarg;
- break;
- case (int) OPT_O_ENC:
- opt_enclosed= optarg;
- break;
- case (int) OPT_ESC:
- escaped= optarg;
- break;
- case (int) OPT_DROP:
- opt_drop=1;
- break;
- case (int) OPT_KEYWORDS:
- opt_keywords=1;
- break;
- case (int) OPT_LOCKS:
- opt_lock=1;
- break;
- case (int) OPT_OPTIMIZE:
- extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=
- opt_disable_keys=1;
- break;
- case (int) OPT_DELAYED:
- opt_delayed=1;
- break;
- case (int) OPT_TABLES:
- opt_databases=0;
- break;
+ break;
+ case 'T':
+ opt_disable_keys=0;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case 'V': print_version(); exit(0);
+ case 'X':
+ opt_xml = 1;
+ opt_disable_keys=0;
+ break;
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ case (int) OPT_OPTIMIZE:
+ extended_insert=opt_drop=opt_lock=quick=create_options=opt_disable_keys=
+ lock_tables=1;
+ if (opt_single_transaction) lock_tables=0;
+ break;
+ case (int) OPT_TABLES:
+ opt_databases=0;
+ break;
#include "sslopt-case.h"
- }
}
+ return 0;
+}
+
+
+static int get_options(int *argc, char ***argv)
+{
+ int ho_error;
+
+ md_result_file= stdout;
+ load_defaults("my",load_default_groups,argc,argv);
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (opt_delayed)
opt_lock=0; /* Can't have lock with delayed */
if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
fields_terminated))
{
- fprintf(stderr, "%s: You must use option --tab with --fields-...\n", my_progname);
+ fprintf(stderr,
+ "%s: You must use option --tab with --fields-...\n", my_progname);
return(1);
}
+
+ if (opt_single_transaction && lock_tables)
+ {
+ fprintf(stderr, "%s: You can't use --lock-tables and --single-transaction at the same time.\n", my_progname);
+ return(1);
+ }
if (enclosed && opt_enclosed)
{
@@ -498,8 +406,6 @@ static int get_options(int *argc,char ***argv)
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- (*argc)-=optind;
- (*argv)+=optind;
if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
{
usage();
@@ -663,8 +569,7 @@ static uint getTableStructure(char *table, char* db)
if (path)
{
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
- strmov(tmp_path,path);
- convert_dirname(tmp_path);
+ convert_dirname(tmp_path,path,NullS);
sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
O_WRONLY, MYF(MY_WME));
if (!sql_file) /* If file couldn't be opened */
@@ -741,8 +646,7 @@ static uint getTableStructure(char *table, char* db)
if (path)
{
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
- strmov(tmp_path,path);
- convert_dirname(tmp_path);
+ convert_dirname(tmp_path,path,NullS);
sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
O_WRONLY, MYF(MY_WME));
if (!sql_file) /* If file couldn't be opened */
@@ -899,8 +803,6 @@ static uint getTableStructure(char *table, char* db)
fputs(";\n", sql_file);
}
}
- if (opt_disable_keys)
- fprintf(sql_file,"\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",table_name);
if (cFlag)
{
strpos=strmov(strpos,") VALUES ");
@@ -969,7 +871,7 @@ static char *field_escape(char *to,const char *from,uint length)
*/
static void dumpTable(uint numFields, char *table)
{
- char query[1024], *end, buff[256],table_buff[NAME_LEN+3];
+ char query[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
MYSQL_RES *res;
MYSQL_FIELD *field;
MYSQL_ROW row;
@@ -980,14 +882,14 @@ static void dumpTable(uint numFields, char *table)
if (path)
{
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
- strmov(tmp_path,path);
- convert_dirname(tmp_path);
+ convert_dirname(tmp_path,path,NullS);
my_load_path(tmp_path, tmp_path, NULL);
fn_format(filename, table, tmp_path, ".txt", 4);
my_delete(filename, MYF(0)); /* 'INTO OUTFILE' doesn't work, if
filename wasn't deleted */
to_unix_path(filename);
- sprintf(query, "SELECT * INTO OUTFILE '%s'", filename);
+ sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s'",
+ filename);
end= strend(query);
if (replace)
end= strmov(end, " REPLACE");
@@ -1018,7 +920,8 @@ static void dumpTable(uint numFields, char *table)
if (!opt_xml)
fprintf(md_result_file,"\n--\n-- Dumping data for table '%s'\n--\n",
table);
- sprintf(query, "SELECT * FROM %s", quote_name(table,table_buff));
+ sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s",
+ quote_name(table,table_buff));
if (where)
{
if (!opt_xml)
@@ -1026,7 +929,7 @@ static void dumpTable(uint numFields, char *table)
strxmov(strend(query), " WHERE ",where,NullS);
}
if (!opt_xml)
- fputs("\n\n", md_result_file);
+ fputs("\n", md_result_file);
if (mysql_query(sock, query))
{
DBerror(sock, "when retrieving data from server");
@@ -1051,6 +954,9 @@ static void dumpTable(uint numFields, char *table)
return;
}
+ if (opt_disable_keys)
+ fprintf(md_result_file,"/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
+ quote_name(table, table_buff));
if (opt_lock)
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n",
quote_name(table,table_buff));
@@ -1198,7 +1104,7 @@ static void dumpTable(uint numFields, char *table)
fputs(");\n", md_result_file);
}
- /*XML - close table tag and supress regular output*/
+ /* XML - close table tag and supress regular output */
if (opt_xml)
fprintf(md_result_file, "\t</%s>\n", table);
else if (extended_insert && row_break)
@@ -1216,11 +1122,11 @@ static void dumpTable(uint numFields, char *table)
safe_exit(EX_CONSCHECK);
return;
}
- if (opt_disable_keys)
- fprintf(md_result_file,"\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
- quote_name(table,table_buff));
if (opt_lock)
fputs("UNLOCK TABLES;\n", md_result_file);
+ if (opt_disable_keys)
+ fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
+ quote_name(table,table_buff));
if (opt_autocommit)
fprintf(md_result_file, "commit;\n");
mysql_free_result(res);
@@ -1301,7 +1207,7 @@ static int dump_databases(char **db_names)
int result=0;
for ( ; *db_names ; db_names++)
{
- /*XML edit - add database element*/
+ /* XML edit - add database element */
if (opt_xml)
fprintf(md_result_file, "<%s>\n", *db_names);
if (dump_all_tables_in_db(*db_names))
@@ -1454,9 +1360,6 @@ int main(int argc, char **argv)
MYSQL_RES *master;
MY_INIT(argv[0]);
- /*
- ** Check out the args
- */
if (get_options(&argc, &argv))
{
my_end(0);
@@ -1478,14 +1381,29 @@ int main(int argc, char **argv)
return(first_error);
}
}
+ else if (opt_single_transaction)
+ {
+ /* There is no sense to start transaction if all tables are locked */
+ if (mysql_query(sock, "BEGIN"))
+ {
+ my_printf_error(0, "Error: Couldn't execute 'BEGIN': %s",
+ MYF(0), mysql_error(sock));
+ my_end(0);
+ return(first_error);
+ }
+ }
if (opt_alldbs)
dump_all_databases();
- /* Only one database and selected table(s) */
else if (argc > 1 && !opt_databases)
+ {
+ /* Only one database and selected table(s) */
dump_selected_tables(*argv, (argv + 1), (argc - 1));
- /* One or more databases, all tables */
+ }
else
+ {
+ /* One or more databases, all tables */
dump_databases(argv);
+ }
if (opt_first_slave)
{
@@ -1493,14 +1411,13 @@ int main(int argc, char **argv)
{
if (mysql_query(sock, "SHOW MASTER STATUS") ||
!(master = mysql_store_result(sock)))
- {
my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s",
MYF(0), mysql_error(sock));
- }
else
{
row = mysql_fetch_row(master);
- if(row[0] && row[1]) {
+ if (row[0] && row[1])
+ {
fprintf(md_result_file,
"\n--\n-- Position to start replication from\n--\n\n");
fprintf(md_result_file,
@@ -1512,15 +1429,25 @@ int main(int argc, char **argv)
}
}
if (mysql_query(sock, "FLUSH MASTER"))
- {
my_printf_error(0, "Error: Couldn't execute 'FLUSH MASTER': %s",
MYF(0), mysql_error(sock));
- }
if (mysql_query(sock, "UNLOCK TABLES"))
- {
my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s",
MYF(0), mysql_error(sock));
- }
+ }
+ else if (opt_single_transaction) /* Just to make it beautiful enough */
+ {
+ /*
+ In case we were locking all tables, we did not start transaction
+ so there is no need to commit it.
+ */
+
+ /* This should just free locks as we did not change anything */
+ if (mysql_query(sock, "COMMIT"))
+ {
+ my_printf_error(0, "Error: Couldn't execute 'COMMIT': %s",
+ MYF(0), mysql_error(sock));
+ }
}
dbDisconnect(current_host);
fputs("\n", md_result_file);
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index d1140c74358..1933ea41bcf 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -25,7 +25,7 @@
** * *
** *************************
*/
-#define IMPORT_VERSION "2.8"
+#define IMPORT_VERSION "3.4"
#include "client_priv.h"
#include "mysql_version.h"
@@ -37,53 +37,98 @@ static char *add_load_option(char *ptr,const char *object,
const char *statement);
static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
- replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0;
-
+ replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0,
+ opt_low_priority= 0, tty_password= 0;
static MYSQL mysql_connection;
static char *opt_password=0, *current_user=0,
*current_host=0, *current_db=0, *fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
- *escaped=0, opt_low_priority=0, *opt_columns=0,
- *default_charset;
+ *escaped=0, *opt_columns=0, *default_charset;
static uint opt_mysql_port=0;
static my_string opt_mysql_unix_port=0;
+static my_string opt_ignore_lines=0;
#include "sslopt-vars.h"
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR},
- {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
- {"columns", required_argument, 0, 'c'},
- {"compress", no_argument, 0, 'C'},
- {"debug", optional_argument, 0, '#'},
- {"delete", no_argument, 0, 'd'},
- {"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
- {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC},
- {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
- {"fields-escaped-by", required_argument, 0, (int) OPT_ESC},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"ignore", no_argument, 0, 'i'},
- {"lines-terminated-by", required_argument, 0, (int) OPT_LTB},
- {"local", no_argument, 0, 'L'},
- {"lock-tables", no_argument, 0, 'l'},
- {"low-priority", no_argument, 0, (int) OPT_LOW_PRIORITY},
- {"password", optional_argument, 0, 'p'},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set.", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"columns", 'c',
+ "Use only these columns to import the data to. Give the column names in a comma separated list. This is same as giving columns to LOAD DATA INFILE.",
+ (gptr*) &opt_columns, (gptr*) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'", 0, 0, 0,
+ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"delete", 'd', "First delete all rows from table.", (gptr*) &opt_delete,
+ (gptr*) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-terminated-by", OPT_FTB,
+ "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated,
+ (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-enclosed-by", OPT_ENC,
+ "Fields in the importfile are enclosed by ...", (gptr*) &enclosed,
+ (gptr*) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-optionally-enclosed-by", OPT_O_ENC,
+ "Fields in the i.file are opt. enclosed by ...", (gptr*) &opt_enclosed,
+ (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
+ (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"force", 'f', "Continue even if we get an sql-error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"ignore", 'i', "If duplicate unique key was found, keep old row.",
+ (gptr*) &ignore, (gptr*) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
+ (gptr*) &opt_ignore_lines, (gptr*) &opt_ignore_lines, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
+ (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"local", 'L', "Read all files through the client", (gptr*) &opt_local_file,
+ (gptr*) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"lock-tables", 'l', "Lock all tables for write.", (gptr*) &lock_tables,
+ (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"low-priority", OPT_LOW_PRIORITY,
+ "Use LOW_PRIORITY when updating the table", (gptr*) &opt_low_priority,
+ (gptr*) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"replace", no_argument, 0, 'r'},
- {"silent", no_argument, 0, 's'},
- {"socket", required_argument, 0, 'S'},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"replace", 'r', "If duplicate unique key was found, replace old row.",
+ (gptr*) &replace, (gptr*) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.", (gptr*) &silent, (gptr*) &silent, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &current_user,
+ (gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"verbose", 'v', "Print info about the various stages.", (gptr*) &verbose,
+ (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -110,155 +155,57 @@ read the text file directly. In other cases the client will open the text\n\
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
- printf("\n\
- -#, --debug[=...] Output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help Displays this help and exits.\n\
- --default-character-set=...\n\
- Set the default character set.\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -c, --columns=... Use only these columns to import the data to.\n\
- Give the column names in a comma separated list.\n\
- This is same as giving columns to LOAD DATA INFILE.\n\
- -C, --compress Use compression in server/client protocol\n\
- -d, --delete First delete all rows from table.\n\
- -f, --force Continue even if we get an sql-error.\n\
- -h, --host=... Connect to host.\n\
- -i, --ignore If duplicate unique key was found, keep old row.\n\
- -l, --lock-tables Lock all tables for write.\n\
- -L, --local Read all files through the client\n\
- --low-priority Use LOW_PRIORITY when updating the table\n\
- -p, --password[=...] Password to use when connecting to server.\n\
- If password is not given it's asked from the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P, --port=... Port number to use for connection.\n\
- -r, --replace If duplicate unique key was found, replace old row.\n\
- -s, --silent Be more silent.\n\
- -S, --socket=... Socket file to use for connection.\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -v, --verbose Print info about the various stages.\n\
- -V, --version Output version information and exit.\n\
- --fields-terminated-by=...\n\
- Fields in the textfile are terminated by ...\n\
- --fields-enclosed-by=...\n\
- Fields in the importfile are enclosed by ...\n\
- --fields-optionally-enclosed-by=...\n\
- Fields in the i.file are opt. enclosed by ...\n\
- --fields-escaped-by=...\n\
- Fields in the i.file are escaped by ...\n\
- --lines-terminated-by=...\n\
- Lines in the i.file are terminated by ...\n\
-");
print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
}
-static int get_options(int *argc, char ***argv)
-{
- int c, option_index;
- my_bool tty_password=0;
- while ((c=getopt_long(*argc,*argv,
- (char*) "#::p::c:h:u:P:S:CdfilLrsvV?IW",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'c':
- opt_columns= optarg;
- break;
- case 'C':
- opt_compress=1;
- break;
- case OPT_DEFAULT_CHARSET:
- default_charset= optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir= optarg;
- break;
- case 'd':
- opt_delete= 1;
- break;
- case 'f':
- ignore_errors= 1;
- break;
- case 'h':
- current_host= optarg;
- break;
- case 'i':
- ignore= 1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- current_user= optarg;
- break;
-#endif
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password= 1;
- break;
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'r':
- replace= 1;
- break;
- case 's':
- silent= 1;
- break;
- case 'S':
- opt_mysql_unix_port= optarg;
- break;
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password= 1;
+ break;
#ifdef __WIN__
- case 'W':
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
- opt_local_file=1;
- break;
+ case 'W':
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_local_file=1;
+ break;
#endif
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'l': lock_tables= 1; break;
- case 'L': opt_local_file=1; break;
- case 'v': verbose= 1; break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- case (int) OPT_FTB:
- fields_terminated= optarg;
- break;
- case (int) OPT_LTB:
- lines_terminated= optarg;
- break;
- case (int) OPT_ENC:
- enclosed= optarg;
- break;
- case (int) OPT_O_ENC:
- opt_enclosed= optarg;
- break;
- case (int) OPT_ESC:
- escaped= optarg;
- break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case 'V': print_version(); exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
#include "sslopt-case.h"
- }
}
+ return 0;
+}
+
+
+static int get_options(int *argc, char ***argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (enclosed && opt_enclosed)
{
fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
@@ -274,8 +221,6 @@ static int get_options(int *argc, char ***argv)
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- (*argc)-=optind;
- (*argv)+=optind;
if (*argc < 2)
{
usage();
@@ -345,6 +290,8 @@ static int write_to_table(char *filename, MYSQL *sock)
" OPTIONALLY ENCLOSED BY");
end= add_load_option(end, escaped, " ESCAPED BY");
end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
+ if (opt_ignore_lines)
+ end= strmov(strmov(strmov(end, " IGNORE "), opt_ignore_lines), " LINES");
if (opt_columns)
end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
*end= '\0';
diff --git a/client/mysqlmanager-pwgen.c b/client/mysqlmanager-pwgen.c
new file mode 100644
index 00000000000..57d91b52f49
--- /dev/null
+++ b/client/mysqlmanager-pwgen.c
@@ -0,0 +1,161 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define MANAGER_PWGEN_VERSION "1.4"
+
+#include <my_global.h>
+#include <m_ctype.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <mysql_version.h>
+#include <errno.h>
+#include <my_getopt.h>
+#include <md5.h>
+
+const char* outfile=0,*user="root";
+
+static struct my_option my_long_options[] =
+{
+ {"output-file", 'o', "Write the output to the file with the given name",
+ (gptr*) &outfile, (gptr*) &outfile, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"user", 'u', "Put given user in the password file", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this message and exit", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Display version info", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ DBUG_ENTER("die");
+ va_start(args, fmt);
+ if (fmt)
+ {
+ fprintf(stderr, "%s: ", my_progname);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ }
+ va_end(args);
+ exit(1);
+}
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,
+ MANAGER_PWGEN_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+void usage()
+{
+ print_version();
+ printf("MySQL AB, by Sasha\n");
+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
+ printf("Generates a password file to be used by mysqltest.\n\n");
+ printf("Usage: %s [OPTIONS]\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case '?':
+ usage();
+ exit(0);
+ case 'V':
+ print_version();
+ exit(0);
+ }
+ return 0;
+}
+
+
+int parse_args(int argc, char** argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
+void get_pass(char* pw, int len)
+{
+ FILE* fp;
+ char* pw_end=pw+len;
+ /*
+ /dev/random is more secure than rand() because the seed is easy to
+ predict, so we resort to rand() only if /dev/random is not available
+ */
+ if ((fp=fopen("/dev/random","r")))
+ {
+ fread(pw,len,1,fp);
+ fclose(fp);
+ while (pw<pw_end)
+ {
+ char tmp= 'a'+((uint)*pw % 26);
+ *pw++= tmp;
+ }
+ }
+ else
+ {
+ srand(time(NULL));
+ while (pw<pw_end)
+ {
+ char tmp= 'a'+((uint)*pw % 26);
+ *pw++= tmp;
+ }
+ }
+ *pw_end=0;
+}
+
+
+int main(int argc, char** argv)
+{
+ FILE* fp;
+ my_MD5_CTX context;
+ uchar digest[16];
+ char pw[17];
+ uint i;
+
+ MY_INIT(argv[0]);
+ parse_args(argc,argv);
+ if (!outfile)
+ die("Missing --output-file");
+
+ if (!(fp=fopen(outfile,"w")))
+ die("Could not open '%s'(errno=%d)",outfile,errno);
+ get_pass(pw,sizeof(pw)-1);
+ my_MD5Init(&context);
+ my_MD5Update(&context,(uchar*) pw,sizeof(pw)-1);
+ my_MD5Final(digest,&context);
+ fprintf(fp,"%s:",user);
+ for (i=0;i<sizeof(digest);i++)
+ fprintf(fp,"%02x",digest[i]);
+ fprintf(fp,"\n");
+ fclose(fp);
+ printf("%s\n",pw);
+ return 0;
+}
diff --git a/client/mysqlmanagerc.c b/client/mysqlmanagerc.c
new file mode 100644
index 00000000000..0001a0266e6
--- /dev/null
+++ b/client/mysqlmanagerc.c
@@ -0,0 +1,174 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define MANAGER_CLIENT_VERSION "1.4"
+
+#include <my_global.h>
+#include <mysql.h>
+#include <mysql_version.h>
+#include <mysqld_error.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <my_getopt.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifndef MYSQL_MANAGER_PORT
+#define MYSQL_MANAGER_PORT 9305
+#endif
+
+static void die(const char* fmt, ...);
+
+const char* user="root",*host="localhost";
+char* pass=0;
+my_bool quiet=0;
+uint port=MYSQL_MANAGER_PORT;
+static const char *load_default_groups[]= { "mysqlmanagerc",0 };
+char** default_argv;
+MYSQL_MANAGER *manager;
+FILE* fp, *fp_out;
+
+static struct my_option my_long_options[] =
+{
+ {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p', "Password to use when connecting to server.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &port,
+ (gptr*) &port, 0, GET_UINT, REQUIRED_ARG, MYSQL_MANAGER_PORT, 0, 0, 0, 0,
+ 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quiet", 'q', "Suppress all normal output.", (gptr*) &quiet, (gptr*) &quiet,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ DBUG_ENTER("die");
+ va_start(args, fmt);
+ if (fmt)
+ {
+ fprintf(stderr, "%s: ", my_progname);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ }
+ va_end(args);
+ exit(1);
+}
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,
+ MANAGER_CLIENT_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+void usage()
+{
+ print_version();
+ printf("MySQL AB, by Sasha\n");
+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
+ printf("Command-line client for MySQL manager daemon.\n\n");
+ printf("Usage: %s [OPTIONS] < command_file\n", my_progname);
+ my_print_help(my_long_options);
+ printf(" --no-defaults Don't read default options from any options file.\n");
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ my_bool tty_password=0;
+
+ switch (optid) {
+ case 'p':
+ if (argument)
+ {
+ my_free(pass, MYF(MY_ALLOW_ZERO_PTR));
+ pass= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ load_defaults("my",load_default_groups,&argc,&argv);
+ default_argv= argv;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
+
+int main(int argc, char** argv)
+{
+ MY_INIT(argv[0]);
+ fp=stdin;
+ fp_out=stdout;
+ parse_args(argc,argv);
+ if (!(manager=mysql_manager_init(0)))
+ die("Failed in mysql_manager_init()");
+ if (!mysql_manager_connect(manager,host,user,pass,port))
+ die("Could not connect to MySQL manager: %s (%d)",manager->last_error,
+ manager->last_errno);
+ for (;!feof(fp);)
+ {
+ char buf[4096];
+ if (!fgets(buf,sizeof(buf),fp))
+ break;
+ if (!quiet)
+ fprintf(fp_out,"<<%s",buf);
+ if (mysql_manager_command(manager,buf,strlen(buf)))
+ die("Error in command: %s (%d)",manager->last_error,manager->last_errno);
+ while (!manager->eof)
+ {
+ if (mysql_manager_fetch_line(manager,buf,sizeof(buf)))
+ die("Error fetching result line: %s (%d)", manager->last_error,
+ manager->last_errno);
+ if (!quiet)
+ fprintf(fp_out,">>%s\n",buf);
+ }
+ }
+ mysql_manager_close(manager);
+ return 0;
+}
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 199318abc2f..81b4d2ab4f7 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -1,24 +1,25 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Show databases, tables or columns */
-#define SHOW_VERSION "8.3"
+#define SHOW_VERSION "9.4"
-#include <global.h>
+#include <my_global.h>
+#include "client_priv.h"
#include <my_sys.h>
#include <m_string.h>
#include "mysql.h"
@@ -26,10 +27,10 @@
#include "mysqld_error.h"
#include <signal.h>
#include <stdarg.h>
-#include <getopt.h>
+#include "sslopt-vars.h"
static my_string host=0,opt_password=0,user=0;
-static my_bool opt_show_keys=0,opt_compress=0,opt_status=0;
+static my_bool opt_show_keys=0,opt_compress=0,opt_status=0, tty_password=0;
static uint opt_verbose=0;
static void get_options(int *argc,char ***argv);
@@ -48,7 +49,6 @@ static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur);
static const char *load_default_groups[]= { "mysqlshow","client",0 };
static my_string opt_mysql_unix_port=0;
-#include "sslopt-vars.h"
int main(int argc, char **argv)
{
@@ -87,7 +87,7 @@ int main(int argc, char **argv)
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
+ opt_ssl_capath, opt_ssl_cipher);
#endif
if (!(mysql_real_connect(&mysql,host,user,opt_password,
argv[0],opt_mysql_port,opt_mysql_unix_port,
@@ -121,32 +121,52 @@ int main(int argc, char **argv)
return 0; /* No compiler warnings */
}
-
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"character-sets-dir", required_argument, 0, 'c'},
- {"compress", no_argument, 0, 'C'},
- {"debug", optional_argument, 0, '#'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"status", no_argument, 0, 'i'},
- {"keys", no_argument, 0, 'k'},
- {"password", optional_argument, 0, 'p'},
- {"port", required_argument, 0, 'P'},
+ {"character-sets-dir", 'c', "Directory where character sets are",
+ (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"status", 'i', "Shows a lot of extra information about each table.",
+ (gptr*) &opt_status, (gptr*) &opt_status, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"keys", 'k', "Show keys for table", (gptr*) &opt_show_keys,
+ (gptr*) &opt_show_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"socket", required_argument, 0, 'S'},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"verbose", 'v',
+ "More verbose output; You can use this multiple times to get even more verbose output.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-
-
+
+
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION,
@@ -160,33 +180,6 @@ static void usage(void)
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Shows the structure of a mysql database (databases,tables and columns)\n");
printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname);
- printf("\n\
- -#, --debug=... output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help display this help and exit\n\
- -c, --character-sets-dir=...\n\
- Directory where character sets are\n\
- -C, --compress Use compression in server/client protocol\n\
- -h, --host=... connect to host\n\
- -i, --status Shows a lot of extra information about each table\n\
- -k, --keys show keys for table\n\
- -p, --password[=...] password to use when connecting to server\n\
- If password is not given it's asked from the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P --port=... Port number to use for connection\n\
- -S --socket=... Socket file to use for connection\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# user for login if not current user\n");
-#endif
- printf("\
- -v, --verbose more verbose output; You can use this multiple times\n\
- to get even more verbose output.\n\
- -V, --version output version information and exit\n");
-
puts("\n\
If last argument contains a shell or SQL wildcard (*,?,% or _) then only\n\
what\'s matched by the wildcard is shown.\n\
@@ -195,85 +188,61 @@ If no table is given then all matching tables in database are shown\n\
If no column is given then all matching columns and columntypes in table\n\
are shown");
print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
}
-
-static void
-get_options(int *argc,char ***argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index;
- my_bool tty_password=0;
-
- while ((c=getopt_long(*argc,*argv,"c:h:p::u:#::P:S:Ck?vVWi",long_options,
- &option_index)) != EOF)
- {
- switch(c) {
- case 'C':
- opt_compress=1;
- break;
- case 'c':
- charsets_dir= optarg;
- break;
- case 'v':
- opt_verbose++;
- break;
- case 'h':
- host = optarg;
- break;
- case 'i':
- opt_status=1;
- break;
- case 'k':
- opt_show_keys=1;
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password=1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- user=optarg;
- break;
-#endif
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'S':
- opt_mysql_unix_port= optarg;
- break;
- case 'W':
+ switch(optid) {
+ case 'v':
+ opt_verbose++;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 'W':
#ifdef __WIN__
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
#endif
- break;
+ break;
#include "sslopt-case.h"
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'V':
- print_version();
- exit(0);
- break;
- default:
- fprintf(stderr,"Illegal option character '%c'\n",opterr);
- /* Fall throught */
- case '?':
- case 'I': /* Info */
- usage();
- exit(0);
- }
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+ case '?':
+ case 'I': /* Info */
+ usage();
+ exit(0);
}
- (*argc)-=optind;
- (*argv)+=optind;
+ return 0;
+}
+
+
+static void
+get_options(int *argc,char ***argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (tty_password)
opt_password=get_tty_password(NullS);
return;
@@ -713,7 +682,7 @@ static void print_res_header(MYSQL_RES *result)
putchar('|');
while ((field = mysql_fetch_field(result)))
{
- printf(" %-*s|",field->max_length+1,field->name);
+ printf(" %-*s|",(int) field->max_length+1,field->name);
}
putchar('\n');
print_res_top(result);
diff --git a/client/mysqltest.c b/client/mysqltest.c
index cfb7fe1aeaf..72c5c6bee5a 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,20 +15,19 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* mysqltest test tool
- * See man page for more information.
+ * See the manual for more information
+ * TODO: document better how mysqltest works
*
* Written by:
* Sasha Pachev <sasha@mysql.com>
* Matt Wagner <matt@mysql.com>
* Monty
+ * Jani
**/
/**********************************************************************
TODO:
-- Print also the queries that returns a result to the log file; This makes
- it much easier to find out what's wrong.
-
- Do comparison line by line, instead of doing a full comparison of
the text file. This will save space as we don't need to keep many
results in memory. It will also make it possible to do simple
@@ -43,25 +42,21 @@
**********************************************************************/
-#define MTEST_VERSION "1.10"
+#define MTEST_VERSION "1.24"
-#include <global.h>
+#include <my_global.h>
+#include <mysql_embed.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql.h>
#include <mysql_version.h>
+#include <mysqld_error.h>
#include <m_ctype.h>
-#ifdef OS2
-#include <config-os2.h>
-#else
- #include <my_config.h>
-#endif
#include <my_dir.h>
#include <hash.h>
-#include <mysqld_error.h>
#include <stdio.h>
#include <stdlib.h>
-#include <getopt.h>
+#include <my_getopt.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -79,17 +74,40 @@
#define MAX_EXPECTED_ERRORS 10
#define QUERY_SEND 1
#define QUERY_REAP 2
-#define CON_RETRY_SLEEP 1 /* how long to sleep before trying to connect again*/
-#define MAX_CON_TRIES 2 /* sometimes in a test the client starts before
- * the server - to solve the problem, we try again
- * after some sleep if connection fails the first
- * time */
+#ifndef MYSQL_MANAGER_PORT
+#define MYSQL_MANAGER_PORT 23546
+#endif
+
+/*
+ Sometimes in a test the client starts before
+ the server - to solve the problem, we try again
+ after some sleep if connection fails the first
+ time
+*/
+#define CON_RETRY_SLEEP 2
+#define MAX_CON_TRIES 5
+
+#ifndef OS2
+#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
+#else
+#defile SLAVE_POLL_INTERVAL 0.3
+#endif
+
+enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
+ OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT};
-static int record = 0, verbose = 0, silent = 0, opt_sleep=0;
+static int record = 0, opt_sleep=0;
static char *db = 0, *pass=0;
-const char* user = 0, *host = 0, *unix_sock = 0;
-static int port = 0, opt_big_test=0;
+const char* user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./";
+static int port = 0;
+static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0,
+ tty_password= 0;
static uint start_lineno, *lineno;
+const char* manager_user="root",*manager_host=0;
+char *manager_pass=0;
+int manager_port=MYSQL_MANAGER_PORT;
+int manager_wait_timeout=3;
+MYSQL_MANAGER* manager=0;
static char **default_argv;
static const char *load_default_groups[]= { "mysqltest","client",0 };
@@ -106,7 +124,7 @@ static int block_stack[BLOCK_STACK_DEPTH];
static int block_ok_stack[BLOCK_STACK_DEPTH];
-static uint global_expected_errno[MAX_EXPECTED_ERRORS];
+static uint global_expected_errno[MAX_EXPECTED_ERRORS], global_expected_errors;
DYNAMIC_ARRAY q_lines;
@@ -127,27 +145,31 @@ typedef struct
int read_lines,current_line;
} PARSER;
+MYSQL_RES *last_result=0;
+
PARSER parser;
MASTER_POS master_pos;
-int* block_ok; /* set to 0 if the current block should not be executed */
+int *block_ok; /* set to 0 if the current block should not be executed */
int false_block_depth = 0;
-const char* result_file = 0; /* if set, all results are concated and
- compared against this file*/
+/* if set, all results are concated and compared against this file */
+const char *result_file = 0;
typedef struct
{
- char* name;
+ char *name;
int name_len;
- char* str_val;
+ char *str_val;
int str_val_len;
int int_val;
int alloced_len;
int int_dirty; /* do not update string if int is updated until first read */
+ int alloced;
} VAR;
VAR var_reg[10];
/*Perl/shell-like variable registers */
HASH var_hash;
+int disable_query_log=0, disable_result_log=0;
struct connection cons[MAX_CONS];
struct connection* cur_con, *next_con, *cons_end;
@@ -169,6 +191,11 @@ Q_DIRTY_CLOSE, Q_REPLACE,
Q_PING, Q_EVAL,
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
+Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
+Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
+Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
+Q_WAIT_FOR_SLAVE_TO_STOP,
+Q_REQUIRE_VERSION,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
Q_COMMENT_WITH_COMMAND
@@ -181,6 +208,7 @@ struct st_query
int first_word_len;
my_bool abort_on_error, require_file;
uint expected_errno[MAX_EXPECTED_ERRORS];
+ uint expected_errors;
char record_file[FN_REFLEN];
enum enum_commands type;
};
@@ -200,6 +228,11 @@ const char *command_names[] = {
"ping", "eval",
"rpl_probe", "enable_rpl_parse",
"disable_rpl_parse", "eval_result",
+ "enable_query_log", "disable_query_log",
+ "enable_result_log", "disable_result_log",
+ "server_start", "server_stop",
+ "require_manager", "wait_for_slave_to_stop",
+ "require_version",
0
};
@@ -207,21 +240,23 @@ TYPELIB command_typelib= {array_elements(command_names),"",
command_names};
DYNAMIC_STRING ds_res;
-static void die(const char* fmt, ...);
+static void die(const char *fmt, ...);
static void init_var_hash();
static byte* get_var_key(const byte* rec, uint* len,
my_bool __attribute__((unused)) t);
-static VAR* var_init(VAR* v, const char* name, int name_len, const char* val,
+static VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
int val_len);
static void var_free(void* v);
-int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname);
-void reject_dump(const char* record_file, char* buf, int size);
+int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname);
+void reject_dump(const char *record_file, char *buf, int size);
int close_connection(struct st_query* q);
-VAR* var_get(const char* var_name, const char** var_name_end, int raw);
-int eval_expr(VAR* v, const char* p, const char** p_end);
+VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw,
+ my_bool ignore_not_existing);
+int eval_expr(VAR* v, const char *p, const char** p_end);
+static int read_server_arguments(const char *name);
/* Definitions for replace */
@@ -236,13 +271,15 @@ struct st_replace;
struct st_replace *init_replace(my_string *from, my_string *to, uint count,
my_string word_end_chars);
uint replace_strings(struct st_replace *rep, my_string *start,
- uint *max_length, my_string from);
+ uint *max_length, const char *from);
+void free_replace();
static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
void free_pointer_array(POINTER_ARRAY *pa);
static int initialize_replace_buffer(void);
static void free_replace_buffer(void);
-static void do_eval(DYNAMIC_STRING* query_eval, const char* query);
-void str_to_file(const char* fname, char* str, int size);
+static void do_eval(DYNAMIC_STRING* query_eval, const char *query);
+void str_to_file(const char *fname, char *str, int size);
+int do_server_op(struct st_query* q,const char *op);
struct st_replace *glob_replace;
static char *out_buff;
@@ -250,13 +287,25 @@ static uint out_length;
static int eval_result = 0;
/* Disable functions that only exist in MySQL 4.0 */
-#if MYSQL_VERSION_ID < 40000
-static void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
-static void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
-static int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
-static int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
+#if MYSQL_VERSION_ID < 40000 || defined(EMBEDDED_LIBRARY)
+void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
+void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
+int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
+int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
#endif
+#define MAX_SERVER_ARGS 20
+
+static int embedded_server_arg_count=0;
+static char *embedded_server_args[MAX_SERVER_ARGS];
+
+static const char *embedded_server_groups[] = {
+ "server",
+ "embedded",
+ "mysqltest_SERVER",
+ NullS
+};
+
static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
{
@@ -264,7 +313,7 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
register char c;
register int escaped = 0;
VAR* v;
-
+
for(p = query; (c = *p); ++p)
{
switch(c)
@@ -277,7 +326,7 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
}
else
{
- if(!(v = var_get(p, &p, 0)))
+ if(!(v = var_get(p, &p, 0, 0)))
die("Bad variable in eval");
dynstr_append_mem(query_eval, v->str_val, v->str_val_len);
}
@@ -301,6 +350,8 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
static void close_cons()
{
DBUG_ENTER("close_cons");
+ if (last_result)
+ mysql_free_result(last_result);
for (--next_con; next_con >= cons; --next_con)
{
mysql_close(&next_con->mysql);
@@ -311,21 +362,27 @@ static void close_cons()
static void close_files()
{
- do
+ DBUG_ENTER("close_files");
+ for (; cur_file != file_stack ; cur_file--)
{
if (*cur_file != stdin && *cur_file)
my_fclose(*cur_file,MYF(0));
- } while (cur_file-- != file_stack);
+ }
+ DBUG_VOID_RETURN;
}
static void free_used_memory()
{
uint i;
DBUG_ENTER("free_used_memory");
+#ifndef EMBEDDED_LIBRARY
+ if (manager)
+ mysql_manager_close(manager);
+#endif
close_cons();
close_files();
hash_free(&var_hash);
-
+
for (i=0 ; i < q_lines.elements ; i++)
{
struct st_query **q= dynamic_element(&q_lines, i, struct st_query**);
@@ -337,10 +394,13 @@ static void free_used_memory()
if(var_reg[i].alloced_len)
my_free(var_reg[i].str_val, MYF(MY_WME));
}
+ while (embedded_server_arg_count > 1)
+ my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
delete_dynamic(&q_lines);
dynstr_free(&ds_res);
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(default_argv);
+ mysql_server_end();
my_end(MY_CHECK_ERROR);
DBUG_VOID_RETURN;
}
@@ -362,6 +422,8 @@ static void die(const char* fmt, ...)
exit(1);
}
+/* Note that we will get some memory leaks when calling this! */
+
static void abort_not_supported_test()
{
DBUG_ENTER("abort_not_supported_test");
@@ -416,13 +478,22 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
DYNAMIC_STRING res_ds;
DBUG_ENTER("dyn_string_cmp");
- if (!my_stat(fname, &stat_info, MYF(MY_WME)))
+ if (!test_if_hard_path(fname))
+ {
+ strxmov(eval_file, opt_basedir, fname, NullS);
+ fn_format(eval_file, eval_file,"","",4);
+ }
+ else
+ fn_format(eval_file, fname,"","",4);
+
+ if (!my_stat(eval_file, &stat_info, MYF(MY_WME)))
die(NullS);
if (!eval_result && stat_info.st_size != ds->length)
DBUG_RETURN(2);
if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
die(NullS);
- if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0)
+
+ if ((fd = my_open(eval_file, O_RDONLY, MYF(MY_WME))) < 0)
die(NullS);
if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP)))
die(NullS);
@@ -443,18 +514,18 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
res_ptr = tmp;
res_len = stat_info.st_size;
}
-
+
res = (memcmp(res_ptr, ds->str, res_len)) ? 1 : 0;
-
+
err:
if(res && eval_result)
str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr,
res_len);
-
+
my_free((gptr) tmp, MYF(0));
my_close(fd, MYF(MY_WME));
dynstr_free(&res_ds);
-
+
DBUG_RETURN(res);
}
@@ -486,55 +557,58 @@ static int check_result(DYNAMIC_STRING* ds, const char* fname,
return error;
}
-VAR* var_get(const char* var_name, const char** var_name_end, int raw)
+VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw,
+ my_bool ignore_not_existing)
{
int digit;
VAR* v;
- if (*var_name++ != '$')
- {
- --var_name;
+ DBUG_ENTER("var_get");
+ DBUG_PRINT("enter",("var_name: %s",var_name));
+
+ if (*var_name != '$')
goto err;
- }
- digit = *var_name - '0';
+ digit = *++var_name - '0';
if (!(digit < 10 && digit >= 0))
{
const char* save_var_name = var_name, *end;
end = (var_name_end) ? *var_name_end : 0;
- while (isvar(*var_name))
- {
- if(end && var_name == end)
- break;
+ while (isvar(*var_name) && var_name != end)
++var_name;
- }
- if(var_name == save_var_name)
+ if (var_name == save_var_name)
+ {
+ if (ignore_not_existing)
+ DBUG_RETURN(0);
die("Empty variable");
-
- if(!(v = (VAR*)hash_search(&var_hash, save_var_name,
+ }
+
+ if (!(v = (VAR*) hash_search(&var_hash, save_var_name,
var_name - save_var_name)))
- {
- if (end)
- *(char*)end = 0;
- die("Variable '%s' used uninitialized", save_var_name);
- }
- --var_name;
+ {
+ if (ignore_not_existing)
+ DBUG_RETURN(0);
+ if (end)
+ *(char*) end = 0;
+ die("Variable '%s' used uninitialized", save_var_name);
+ }
+ --var_name; /* Point at last character */
}
else
- v = var_reg + digit;
-
+ v = var_reg + digit;
+
if (!raw && v->int_dirty)
{
sprintf(v->str_val, "%d", v->int_val);
v->int_dirty = 0;
v->str_val_len = strlen(v->str_val);
}
- if(var_name_end)
+ if (var_name_end)
*var_name_end = var_name ;
- return v;
+ DBUG_RETURN(v);
err:
if (var_name_end)
*var_name_end = 0;
die("Unsupported variable name: %s", var_name);
- return 0;
+ DBUG_RETURN(0);
}
static VAR* var_obtain(char* name, int len)
@@ -565,15 +639,23 @@ int var_set(char* var_name, char* var_name_end, char* var_val,
}
else
v = var_reg + digit;
-
+
return eval_expr(v, var_val, (const char**)&var_val_end);
}
int open_file(const char* name)
{
+ char buff[FN_REFLEN];
+ if (!test_if_hard_path(name))
+ {
+ strxmov(buff, opt_basedir, name, NullS);
+ name=buff;
+ }
+ fn_format(buff,name,"","",4);
+
if (*cur_file && cur_file == file_stack_end)
die("Source directives are nesting too deep");
- if (!(*(cur_file+1) = my_fopen(name, O_RDONLY, MYF(MY_WME))))
+ if (!(*(cur_file+1) = my_fopen(buff, O_RDONLY, MYF(MY_WME))))
die(NullS);
cur_file++;
*++lineno=1;
@@ -581,6 +663,132 @@ int open_file(const char* name)
return 0;
}
+/* ugly long name, but we are following the convention */
+int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused)))
+{
+ MYSQL* mysql = &cur_con->mysql;
+#ifndef OS2
+ struct timeval t;
+#endif
+ for (;;)
+ {
+ MYSQL_RES* res;
+ MYSQL_ROW row;
+ int done;
+ LINT_INIT(res);
+
+ if (mysql_query(mysql,"show status like 'Slave_running'")
+ || !(res=mysql_store_result(mysql)))
+ die("Query failed while probing slave for stop: %s",
+ mysql_error(mysql));
+ if (!(row=mysql_fetch_row(res)) || !row[1])
+ {
+ mysql_free_result(res);
+ die("Strange result from query while probing slave for stop");
+ }
+ done = !strcmp(row[1],"OFF");
+ mysql_free_result(res);
+ if (done)
+ break;
+#ifndef OS2
+ t.tv_sec=0;
+ t.tv_usec=SLAVE_POLL_INTERVAL;
+ select(0,0,0,0,&t); /* sleep */
+#else
+ DosSleep(OS2_SLAVE_POLL_INTERVAL);
+#endif
+ }
+
+ return 0;
+}
+
+int do_require_manager(struct st_query* a __attribute__((unused)))
+{
+ if (!manager)
+ abort_not_supported_test();
+ return 0;
+}
+
+#ifndef EMBEDDED_LIBRARY
+int do_server_start(struct st_query* q)
+{
+ return do_server_op(q,"start");
+}
+
+int do_server_stop(struct st_query* q)
+{
+ return do_server_op(q,"stop");
+}
+
+int do_server_op(struct st_query* q,const char* op)
+{
+ char* p=q->first_argument;
+ char com_buf[256],*com_p;
+ if (!manager)
+ {
+ die("Manager is not initialized, manager commands are not possible");
+ }
+ com_p=strmov(com_buf,op);
+ com_p=strmov(com_p,"_exec ");
+ if (!*p)
+ die("Missing server name in server_%s\n",op);
+ while (*p && !isspace(*p))
+ {
+ *com_p++=*p++;
+ }
+ *com_p++=' ';
+ com_p=int10_to_str(manager_wait_timeout,com_p,10);
+ *com_p++ = '\n';
+ *com_p=0;
+ if (mysql_manager_command(manager,com_buf,(int)(com_p-com_buf)))
+ die("Error in command: %s(%d)",manager->last_error,manager->last_errno);
+ while (!manager->eof)
+ {
+ if (mysql_manager_fetch_line(manager,com_buf,sizeof(com_buf)))
+ die("Error fetching result line: %s(%d)", manager->last_error,
+ manager->last_errno);
+ }
+
+ return 0;
+}
+#endif
+
+int do_require_version(struct st_query* q)
+{
+ MYSQL* mysql = &cur_con->mysql;
+ MYSQL_RES* res;
+ MYSQL_ROW row;
+ char* p=q->first_argument, *ver_arg;
+ uint ver_arg_len,ver_len;
+ LINT_INIT(res);
+
+ if (!*p)
+ die("Missing version argument in require_version\n");
+ ver_arg = p;
+ while (*p && !isspace(*p))
+ p++;
+ *p = 0;
+ ver_arg_len = p - ver_arg;
+
+ if (mysql_query(mysql, "select version()") ||
+ !(res=mysql_store_result(mysql)))
+ die("Query failed while check server version: %s",
+ mysql_error(mysql));
+ if (!(row=mysql_fetch_row(res)) || !row[0])
+ {
+ mysql_free_result(res);
+ die("Strange result from query while checking version");
+ }
+ ver_len = strlen(row[0]);
+ if (ver_len < ver_arg_len || memcmp(row[0],ver_arg,ver_arg_len))
+ {
+ mysql_free_result(res);
+ abort_not_supported_test();
+ }
+ mysql_free_result(res);
+ return 0;
+}
+
int do_source(struct st_query* q)
{
char* p=q->first_argument, *name;
@@ -601,7 +809,7 @@ int var_query_set(VAR* v, const char* p, const char** p_end)
MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql;
LINT_INIT(res);
-
+
while (end > p && *end != '`')
--end;
if (p == end)
@@ -624,17 +832,29 @@ int var_query_set(VAR* v, const char* p, const char** p_end)
return 0;
}
+void var_copy(VAR* dest, VAR* src)
+{
+ dest->int_val=src->int_val;
+ dest->int_dirty=src->int_dirty;
+ if (dest->alloced_len < src->alloced_len &&
+ !(dest->str_val=my_realloc(dest->str_val,src->alloced_len+1,
+ MYF(MY_WME))))
+ die("Out of memory");
+ dest->str_val_len=src->str_val_len;
+ memcpy(dest->str_val,src->str_val,src->str_val_len+1);
+}
+
int eval_expr(VAR* v, const char* p, const char** p_end)
{
VAR* vp;
if (*p == '$')
+ {
+ if ((vp = var_get(p,p_end,0,0)))
{
- if ((vp = var_get(p,p_end,0)))
- {
- memcpy(v, vp, sizeof(*v));
- return 0;
- }
+ var_copy(v, vp);
+ return 0;
}
+ }
else if(*p == '`')
{
return var_query_set(v, p, p_end);
@@ -648,9 +868,9 @@ int eval_expr(VAR* v, const char* p, const char** p_end)
v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
- v->str_val ? my_realloc(v->str_val, v->alloced_len,
+ v->str_val ? my_realloc(v->str_val, v->alloced_len+1,
MYF(MY_WME)) :
- my_malloc(v->alloced_len, MYF(MY_WME))))
+ my_malloc(v->alloced_len+1, MYF(MY_WME))))
die("Out of memory");
}
v->str_val_len = new_val_len;
@@ -671,7 +891,7 @@ int do_inc(struct st_query* q)
{
char* p=q->first_argument;
VAR* v;
- v = var_get(p, 0, 1);
+ v = var_get(p, 0, 1, 0);
v->int_val++;
v->int_dirty = 1;
return 0;
@@ -681,7 +901,7 @@ int do_dec(struct st_query* q)
{
char* p=q->first_argument;
VAR* v;
- v = var_get(p, 0, 1);
+ v = var_get(p, 0, 1, 0);
v->int_val--;
v->int_dirty = 1;
return 0;
@@ -704,6 +924,7 @@ int do_system(struct st_query* q)
if (system(expr_buf) && q->abort_on_error)
die("system command '%s' failed", expr_buf);
}
+ var_free(&v);
return 0;
}
@@ -719,6 +940,7 @@ int do_echo(struct st_query* q)
write(1, v.str_val, v.str_val_len);
}
write(1, "\n", 1);
+ var_free(&v);
return 0;
}
@@ -734,27 +956,26 @@ int do_sync_with_master(struct st_query* q)
rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
-
+
if(*p)
offset = atoi(p);
-
+
sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
master_pos.pos + offset);
if(mysql_query(mysql, query_buf))
die("At line %u: failed in %s: %d: %s", start_lineno, query_buf,
mysql_errno(mysql), mysql_error(mysql));
- if(!(res = mysql_store_result(mysql)))
+ if(!(last_result = res = mysql_store_result(mysql)))
die("line %u: mysql_store_result() retuned NULL", start_lineno);
if(!(row = mysql_fetch_row(res)))
die("line %u: empty result in %s", start_lineno, query_buf);
if(!row[0])
die("Error on slave while syncing with master");
- mysql_free_result(res);
-
+ mysql_free_result(res); last_result=0;
if(rpl_parse)
mysql_enable_rpl_parse(mysql);
-
+
return 0;
}
@@ -767,22 +988,22 @@ int do_save_master_pos()
rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
-
+
if(mysql_query(mysql, "show master status"))
die("At line %u: failed in show master status: %d: %s", start_lineno,
mysql_errno(mysql), mysql_error(mysql));
- if(!(res = mysql_store_result(mysql)))
+ if(!(last_result =res = mysql_store_result(mysql)))
die("line %u: mysql_store_result() retuned NULL", start_lineno);
if(!(row = mysql_fetch_row(res)))
die("line %u: empty result in show master status", start_lineno);
strncpy(master_pos.file, row[0], sizeof(master_pos.file));
master_pos.pos = strtoul(row[1], (char**) 0, 10);
- mysql_free_result(res);
-
+ mysql_free_result(res); last_result=0;
+
if(rpl_parse)
mysql_enable_rpl_parse(mysql);
-
+
return 0;
}
@@ -804,20 +1025,20 @@ int do_let(struct st_query* q)
return var_set(var_name, var_name_end, var_val_start, q->end);
}
-int do_rpl_probe(struct st_query* __attribute__((unused)) q)
+int do_rpl_probe(struct st_query* q __attribute__((unused)))
{
if(mysql_rpl_probe(&cur_con->mysql))
die("Failed in mysql_rpl_probe(): %s", mysql_error(&cur_con->mysql));
return 0;
}
-int do_enable_rpl_parse(struct st_query* __attribute__((unused)) q)
+int do_enable_rpl_parse(struct st_query* q __attribute__((unused)))
{
mysql_enable_rpl_parse(&cur_con->mysql);
return 0;
}
-int do_disable_rpl_parse(struct st_query* __attribute__((unused)) q)
+int do_disable_rpl_parse(struct st_query* q __attribute__((unused)))
{
mysql_disable_rpl_parse(&cur_con->mysql);
return 0;
@@ -887,10 +1108,11 @@ static void get_file_name(char *filename, struct st_query* q)
}
-static void get_ints(uint *to,struct st_query* q)
+static uint get_ints(uint *to,struct st_query* q)
{
char* p=q->first_argument;
long val;
+ uint count=0;
DBUG_ENTER("get_ints");
if (!*p)
@@ -898,25 +1120,28 @@ static void get_ints(uint *to,struct st_query* q)
for (; (p=str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val)) ; p++)
{
+ count++;
*to++= (uint) val;
if (*p != ',')
break;
}
*to++=0; /* End of data */
- DBUG_VOID_RETURN;
+ DBUG_RETURN(count);
}
/*
Get a string; Return ptr to end of string
Strings may be surrounded by " or '
+
+ If string is a '$variable', return the value of the variable.
*/
-static void get_string(char **to_ptr, char **from_ptr,
- struct st_query* q)
+static char *get_string(char **to_ptr, char **from_ptr,
+ struct st_query* q)
{
reg1 char c,sep;
- char *to= *to_ptr, *from= *from_ptr;
+ char *to= *to_ptr, *from= *from_ptr, *start=to;
DBUG_ENTER("get_string");
/* Find separator */
@@ -966,9 +1191,22 @@ static void get_string(char **to_ptr, char **from_ptr,
while (isspace(*from)) /* Point to next string */
from++;
- *to++ =0; /* End of string marker */
- *to_ptr= to;
+ *to =0; /* End of string marker */
+ *to_ptr= to+1; /* Store pointer to end */
*from_ptr= from;
+
+ /* Check if this was a variable */
+ if (*start == '$')
+ {
+ const char *end= to;
+ VAR *var=var_get(start, &end, 0, 1);
+ if (var && to == (char*) end+1)
+ {
+ DBUG_PRINT("info",("var: %s -> %s", start, var->str_val));
+ DBUG_RETURN(var->str_val); /* return found variable value */
+ }
+ }
+ DBUG_RETURN(start);
}
@@ -976,6 +1214,8 @@ static void get_string(char **to_ptr, char **from_ptr,
Get arguments for replace. The syntax is:
replace from to [from to ...]
Where each argument may be quoted with ' or "
+ A argument may also be a variable, in which case the value of the
+ variable is replaced.
*/
static void get_replace(struct st_query *q)
@@ -987,6 +1227,9 @@ static void get_replace(struct st_query *q)
POINTER_ARRAY to_array,from_array;
DBUG_ENTER("get_replace");
+ if (glob_replace)
+ free_replace();
+
bzero((char*) &to_array,sizeof(to_array));
bzero((char*) &from_array,sizeof(from_array));
if (!*from)
@@ -995,12 +1238,11 @@ static void get_replace(struct st_query *q)
while (*from)
{
char *to=buff;
- get_string(&buff, &from, q);
+ to=get_string(&buff, &from, q);
if (!*from)
die("Wrong number of arguments to replace in %s\n", q->query);
insert_pointer_name(&from_array,to);
- to=buff;
- get_string(&buff, &from, q);
+ to=get_string(&buff, &from, q);
insert_pointer_name(&to_array,to);
}
for (i=1,pos=word_end_chars ; i < 256 ; i++)
@@ -1016,6 +1258,7 @@ static void get_replace(struct st_query *q)
free_pointer_array(&from_array);
free_pointer_array(&to_array);
my_free(start, MYF(0));
+ DBUG_VOID_RETURN;
}
void free_replace()
@@ -1068,19 +1311,19 @@ int close_connection(struct st_query* q)
p++;
*p = 0;
- for(con = cons; con < next_con; con++)
+ for (con = cons; con < next_con; con++)
{
if (!strcmp(con->name, name))
{
- if(q->type == Q_DIRTY_CLOSE)
+ if (q->type == Q_DIRTY_CLOSE)
+ {
+ if (con->mysql.net.vio)
{
- if(con->mysql.net.vio)
- {
- vio_delete(con->mysql.net.vio);
- con->mysql.net.vio = 0;
- }
+ vio_delete(con->mysql.net.vio);
+ con->mysql.net.vio = 0;
}
-
+ }
+
mysql_close(&con->mysql);
DBUG_RETURN(0);
}
@@ -1090,7 +1333,8 @@ int close_connection(struct st_query* q)
}
-/* this one now is a hack - we may want to improve in in the
+/*
+ This one now is a hack - we may want to improve in in the
future to handle quotes. For now we assume that anything that is not
a comma, a space or ) belongs to the argument. space is a chopper, comma or
) are delimiters/terminators
@@ -1112,6 +1356,37 @@ char* safe_get_param(char* str, char** arg, const char* msg)
DBUG_RETURN(str);
}
+#ifndef EMBEDDED_LIBRARY
+void init_manager()
+{
+ if (!(manager=mysql_manager_init(0)))
+ die("Failed in mysql_manager_init()");
+ if (!mysql_manager_connect(manager,manager_host,manager_user,
+ manager_pass,manager_port))
+ die("Could not connect to MySQL manager: %s(%d)",manager->last_error,
+ manager->last_errno);
+
+}
+#endif
+
+int safe_connect(MYSQL* con, const char* host, const char* user,
+ const char* pass,
+ const char* db, int port, const char* sock)
+{
+ int con_error = 1;
+ int i;
+ for (i = 0; i < MAX_CON_TRIES; ++i)
+ {
+ if (mysql_real_connect(con, host,user, pass, db, port, sock, 0))
+ {
+ con_error = 0;
+ break;
+ }
+ sleep(CON_RETRY_SLEEP);
+ }
+ return con_error;
+}
+
int do_connect(struct st_query* q)
{
@@ -1120,8 +1395,9 @@ int do_connect(struct st_query* q)
char* p=q->first_argument;
char buff[FN_REFLEN];
int con_port;
- int i, con_error;
-
+ int con_error;
+ int free_con_sock = 0;
+
DBUG_ENTER("do_connect");
DBUG_PRINT("enter",("connect: %s",p));
@@ -1140,43 +1416,60 @@ int do_connect(struct st_query* q)
}
else
{
+ VAR* var_port, *var_sock;
p = safe_get_param(p, &con_port_str, "missing connection port");
- con_port=atoi(con_port_str);
+ if (*con_port_str == '$')
+ {
+ if (!(var_port = var_get(con_port_str, 0, 0, 0)))
+ die("Unknown variable '%s'", con_port_str+1);
+ con_port = var_port->int_val;
+ }
+ else
+ con_port=atoi(con_port_str);
p = safe_get_param(p, &con_sock, "missing connection socket");
+ if (*con_sock == '$')
+ {
+ if (!(var_sock = var_get(con_sock, 0, 0, 0)))
+ die("Unknown variable '%s'", con_sock+1);
+ if (!(con_sock = (char*)my_malloc(var_sock->str_val_len+1, MYF(0))))
+ die("Out of memory");
+ free_con_sock = 1;
+ memcpy(con_sock, var_sock->str_val, var_sock->str_val_len);
+ con_sock[var_sock->str_val_len] = 0;
+ }
}
+
if (next_con == cons_end)
die("Connection limit exhausted - increase MAX_CONS in mysqltest.c");
if (!mysql_init(&next_con->mysql))
die("Failed on mysql_init()");
- if (con_sock)
+ if (opt_compress)
+ mysql_options(&next_con->mysql,MYSQL_OPT_COMPRESS,NullS);
+ mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
+
+ if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR)
con_sock=fn_format(buff, con_sock, TMPDIR, "",0);
if (!con_db[0])
con_db=db;
- con_error = 1;
- for (i = 0; i < MAX_CON_TRIES; ++i)
- {
- if(mysql_real_connect(&next_con->mysql, con_host,
- con_user, con_pass,
- con_db, con_port, con_sock, 0))
- {
- con_error = 0;
- break;
- }
- sleep(CON_RETRY_SLEEP);
- }
-
- if(con_error)
+ /* Special database to allow one to connect without a database name */
+ if (con_db && !strcmp(con_db,"*NO-ONE*"))
+ con_db=0;
+ if ((con_error = safe_connect(&next_con->mysql, con_host,
+ con_user, con_pass,
+ con_db, con_port, con_sock ? con_sock: 0)))
die("Could not open connection '%s': %s", con_name,
mysql_error(&next_con->mysql));
if (!(next_con->name = my_strdup(con_name, MYF(MY_WME))))
die(NullS);
cur_con = next_con++;
-
+ if (free_con_sock)
+ my_free(con_sock, MYF(MY_WME));
DBUG_RETURN(0);
}
+
int do_done(struct st_query* q)
{
q->type = Q_END_BLOCK;
@@ -1187,10 +1480,10 @@ int do_done(struct st_query* q)
parser.current_line = *--cur_block;
}
else
- {
- ++parser.current_line;
- --cur_block;
- }
+ {
+ ++parser.current_line;
+ --cur_block;
+ }
return 0;
}
@@ -1199,32 +1492,33 @@ int do_while(struct st_query* q)
char* p=q->first_argument;
const char* expr_start, *expr_end;
VAR v;
- var_init(&v,0,0,0,0);
if (cur_block == block_stack_end)
- die("Nesting too deeply");
+ die("Nesting too deeply");
if (!*block_ok)
- {
- ++false_block_depth;
- *++block_ok = 0;
- *cur_block++ = parser.current_line++;
- return 0;
- }
-
+ {
+ ++false_block_depth;
+ *++block_ok = 0;
+ *cur_block++ = parser.current_line++;
+ return 0;
+ }
+
expr_start = strchr(p, '(');
if (!expr_start)
die("missing '(' in while");
expr_end = strrchr(expr_start, ')');
if (!expr_end)
die("missing ')' in while");
+ var_init(&v,0,0,0,0);
eval_expr(&v, ++expr_start, &expr_end);
*cur_block++ = parser.current_line++;
if (!v.int_val)
- {
- *++block_ok = 0;
- false_block_depth++;
- }
+ {
+ *++block_ok = 0;
+ false_block_depth++;
+ }
else
*++block_ok = 1;
+ var_free(&v);
return 0;
}
@@ -1237,45 +1531,42 @@ int safe_copy_unescape(char* dest, char* src, int size)
size--; /* just to make life easier */
- for(; p_dest - size < dest && p_src - size < src
- && (c = *p_src) != '\n' && c; ++p_src )
- {
- switch(state)
- {
- case ST_NORMAL:
- if (c == '\\')
- {
- state = ST_ESCAPED;
- }
- else
- *p_dest++ = c;
- break;
- case ST_ESCAPED:
- if ((val = hex_val(c)) > 0)
- {
- *p_dest = val;
- state = ST_HEX2;
- }
- else
- {
- state = ST_NORMAL;
- *p_dest++ = c;
- }
- break;
- case ST_HEX2:
- if ((val = hex_val(c)) > 0)
- {
- *p_dest = (*p_dest << 4) + val;
- p_dest++;
- }
- else
- *p_dest++ = c;
+ for (; p_dest - size < dest && p_src - size < src &&
+ (c = *p_src) != '\n' && c; ++p_src)
+ {
+ switch(state) {
+ case ST_NORMAL:
+ if (c == '\\')
+ state = ST_ESCAPED;
+ else
+ *p_dest++ = c;
+ break;
+ case ST_ESCAPED:
+ if ((val = hex_val(c)) > 0)
+ {
+ *p_dest = val;
+ state = ST_HEX2;
+ }
+ else
+ {
+ state = ST_NORMAL;
+ *p_dest++ = c;
+ }
+ break;
+ case ST_HEX2:
+ if ((val = hex_val(c)) > 0)
+ {
+ *p_dest = (*p_dest << 4) + val;
+ p_dest++;
+ }
+ else
+ *p_dest++ = c;
- state = ST_NORMAL;
- break;
+ state = ST_NORMAL;
+ break;
- }
}
+ }
*p_dest = 0;
return (p_dest - dest);
@@ -1300,15 +1591,11 @@ int read_line(char* buf, int size)
{
if ((*cur_file) != stdin)
my_fclose(*cur_file,MYF(0));
-
+ cur_file--;
+ lineno--;
if (cur_file == file_stack)
return 1;
- else
- {
- cur_file--;
- lineno--;
- continue;
- }
+ continue;
}
switch(state) {
@@ -1439,8 +1726,11 @@ int read_query(struct st_query** q_ptr)
q->first_word_len = 0;
memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
sizeof(global_expected_errno));
+ q->expected_errors=global_expected_errors;
q->abort_on_error = global_expected_errno[0] == 0;
bzero((gptr) global_expected_errno,sizeof(global_expected_errno));
+ global_expected_errors=0;
+
q->type = Q_UNKNOWN;
q->query_buf=q->query=0;
if (read_line(read_query_buf, sizeof(read_query_buf)))
@@ -1469,6 +1759,7 @@ int read_query(struct st_query** q_ptr)
expected_errno = expected_errno * 10 + *p - '0';
q->expected_errno[0] = expected_errno;
q->expected_errno[1] = 0;
+ q->expected_errors=1;
}
}
@@ -1498,27 +1789,73 @@ int read_query(struct st_query** q_ptr)
}
-struct option long_options[] =
-{
- {"debug", optional_argument, 0, '#'},
- {"database", required_argument, 0, 'D'},
- {"big-test", no_argument, 0, 'B'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"password", optional_argument, 0, 'p'},
- {"port", required_argument, 0, 'P'},
- {"quiet", no_argument, 0, 'q'},
- {"record", no_argument, 0, 'r'},
- {"result-file", required_argument, 0, 'R'},
- {"silent", no_argument, 0, 'q'},
- {"sleep", required_argument, 0, 'T'},
- {"socket", required_argument, 0, 'S'},
- {"test-file", required_argument, 0, 'x'},
- {"tmpdir", required_argument, 0, 't'},
- {"user", required_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+static struct my_option my_long_options[] =
+{
+#ifndef DBUG_OFF
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"basedir", 'b', "Basedir for tests", (gptr*) &opt_basedir,
+ (gptr*) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"big-test", 'B', "Define BIG_TEST to 1", (gptr*) &opt_big_test,
+ (gptr*) &opt_big_test, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use the compressed server/client protocol",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"manager-user", OPT_MANAGER_USER, "Undocumented: Used for debugging",
+ (gptr*) &manager_user, (gptr*) &manager_user, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"manager-host", OPT_MANAGER_HOST, "Undocumented: Used for debugging",
+ (gptr*) &manager_host, (gptr*) &manager_host, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"manager-password", OPT_MANAGER_PASSWD, "Undocumented: Used for debugging",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"manager-port", OPT_MANAGER_PORT, "Undocumented: Used for debugging",
+ (gptr*) &manager_port, (gptr*) &manager_port, 0, GET_INT, REQUIRED_ARG,
+ MYSQL_MANAGER_PORT, 0, 0, 0, 0, 0},
+ {"manager-wait-timeout", OPT_MANAGER_WAIT_TIMEOUT,
+ "Undocumented: Used for debugging", (gptr*) &manager_wait_timeout,
+ (gptr*) &manager_wait_timeout, 0, GET_INT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0},
+ {"password", 'p', "Password to use when connecting to server.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &port,
+ (gptr*) &port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"quiet", 's', "Suppress all normal output.", (gptr*) &silent,
+ (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"record", 'r', "Record output of test_file into result file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"result-file", 'R', "Read/Store result from/in this file.",
+ (gptr*) &result_file, (gptr*) &result_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"server-arg", 'A', "Send enbedded server this as a paramenter",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"server-file", 'F', "Read embedded server arguments from file",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Suppress all normal output. Synonym for --quiet.",
+ (gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sleep", 'T', "Sleep always this many seconds on sleep commands",
+ (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &unix_sock, (gptr*) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"test-file", 'x', "Read test from/in this file (default stdin).",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 't', "Temporary directory where sockets are put",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write more.", (gptr*) &verbose, (gptr*) &verbose, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -1531,115 +1868,97 @@ static void print_version(void)
void usage()
{
print_version();
- printf("MySQL AB, by Sasha, Matt & Monty\n");
+ printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Runs a test against the mysql server and compares output with a results file.\n\n");
printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n");
-#ifndef DBUG_OFF
- puts("\
- -#, --debug=[...] Output debug log. Often this is 'd:t:o,filename`");
-#endif
- printf("\
- -h, --host=... Connect to host.\n\
- -u, --user=... User for login.\n\
- -p[password], --password[=...]\n\
- Password to use when connecting to server.\n\
- -B, --big-test Define BIG_TEST to 1\n\
- -D, --database=... Database to use.\n\
- -P, --port=... Port number to use for connection.\n\
- -S, --socket=... Socket file to use for connection.\n\
- -t, --tmpdir=... Temporary directory where sockets are put\n\
- -T, --sleep=# Sleep always this many seconds on sleep commands\n\
- -r, --record Record output of test_file into result file.\n\
- -R, --result-file=... Read/Store result from/in this file.\n\
- -x, --test-file=... Read test from/in this file (default stdin).\n\
- -v, --verbose Write more.\n\
- -q, --quiet, --silent Suppress all normal output.\n\
- -V, --version Output version information and exit.\n\
- --no-defaults Don't read default options from any options file.\n\n");
+ my_print_help(my_long_options);
+ printf(" --no-defaults Don't read default options from any options file.\n");
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace");
+ break;
+ case 'r':
+ record = 1;
+ break;
+ case (int)OPT_MANAGER_PASSWD:
+ my_free(manager_pass,MYF(MY_ALLOW_ZERO_PTR));
+ manager_pass=my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ break;
+ case 'x':
+ {
+ char buff[FN_REFLEN];
+ if (!test_if_hard_path(argument))
+ {
+ strxmov(buff, opt_basedir, argument, NullS);
+ argument= buff;
+ }
+ fn_format(buff, argument, "", "", 4);
+ if (!(*++cur_file = my_fopen(buff, O_RDONLY, MYF(MY_WME))))
+ die("Could not open %s: errno = %d", argument, errno);
+ break;
+ }
+ case 'p':
+ if (argument)
+ {
+ my_free(pass, MYF(MY_ALLOW_ZERO_PTR));
+ pass= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ }
+ else
+ tty_password= 1;
+ break;
+ case 't':
+ strnmov(TMPDIR, argument, sizeof(TMPDIR));
+ break;
+ case 'A':
+ if (!embedded_server_arg_count)
+ {
+ embedded_server_arg_count=1;
+ embedded_server_args[0]= (char*) "";
+ }
+ embedded_server_args[embedded_server_arg_count++]=
+ my_strdup(argument, MYF(MY_FAE));
+ if (embedded_server_arg_count == MAX_SERVER_ARGS ||
+ !embedded_server_args[embedded_server_arg_count-1])
+ {
+ die("Can't use server argument");
+ }
+ break;
+ case 'F':
+ if (read_server_arguments(argument))
+ die(NullS);
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(1);
+ }
+ return 0;
}
+
int parse_args(int argc, char **argv)
{
- int c, option_index = 0;
- my_bool tty_password=0;
+ int ho_error;
load_defaults("my",load_default_groups,&argc,&argv);
default_argv= argv;
- while((c = getopt_long(argc, argv, "h:p::u:BP:D:S:R:x:t:T:#:?rvVq",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:O,/tmp/mysqltest.trace");
- break;
- case 'v':
- verbose = 1;
- break;
- case 'r':
- record = 1;
- break;
- case 'u':
- user = optarg;
- break;
- case 'R':
- result_file = optarg;
- break;
- case 'x':
- if (!(*cur_file = my_fopen(optarg, O_RDONLY, MYF(MY_WME))))
- die("Could not open %s: errno = %d", optarg, errno);
- break;
- case 'p':
- if (optarg)
- {
- my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
- pass=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- }
- else
- tty_password=1;
- break;
- case 'B':
- opt_big_test=1;
- break;
- case 'P':
- port = atoi(optarg);
- break;
- case 'S':
- unix_sock = optarg;
- break;
- case 'D':
- db = optarg;
- break;
- case 'h':
- host = optarg;
- break;
- case 'q':
- silent = 1;
- break;
- case 't':
- strnmov(TMPDIR,optarg,sizeof(TMPDIR));
- break;
- case 'T':
- opt_sleep=atoi(optarg);
- break;
- case 'V':
- print_version();
- exit(0);
- case '?':
- usage();
- exit(1); /* Unknown option */
- default:
- usage();
- exit(1);
- }
- }
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
- argc-=optind;
- argv+=optind;
if (argc > 1)
{
usage();
@@ -1665,9 +1984,17 @@ char* safe_str_append(char* buf, const char* str, int size)
void str_to_file(const char* fname, char* str, int size)
{
int fd;
- if ((fd = my_open(fname, O_WRONLY | O_CREAT | O_TRUNC,
+ char buff[FN_REFLEN];
+ if (!test_if_hard_path(fname))
+ {
+ strxmov(buff, opt_basedir, fname, NullS);
+ fname=buff;
+ }
+ fn_format(buff,fname,"","",4);
+
+ if ((fd = my_open(buff, O_WRONLY | O_CREAT | O_TRUNC,
MYF(MY_WME | MY_FFNF))) < 0)
- die("Could not open %s: errno = %d", fname, errno);
+ die("Could not open %s: errno = %d", buff, errno);
if (my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP)))
die("write failed");
my_close(fd, MYF(0));
@@ -1679,6 +2006,23 @@ void reject_dump(const char* record_file, char* buf, int size)
str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size);
}
+
+/* Append the string to ds, with optional replace */
+
+static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
+ int len)
+{
+ if (glob_replace)
+ {
+ len=(int) replace_strings(glob_replace, &out_buff, &out_length, val);
+ if (len == -1)
+ die("Out of memory in replace\n");
+ val=out_buff;
+ }
+ dynstr_append_mem(ds, val, len);
+}
+
+
/*
* flags control the phased/stages of query execution to be performed
* if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on
@@ -1701,54 +2045,82 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
int query_len;
DBUG_ENTER("run_query");
- if(q->type != Q_EVAL)
- {
- query = q->query;
- query_len = strlen(query);
- }
+ if (q->type != Q_EVAL)
+ {
+ query = q->query;
+ query_len = strlen(query);
+ }
else
- {
- init_dynamic_string(&eval_query, "", 16384, 65536);
- do_eval(&eval_query, q->query);
- query = eval_query.str;
- query_len = eval_query.length;
- }
-
- if ( q->record_file[0])
+ {
+ init_dynamic_string(&eval_query, "", 16384, 65536);
+ do_eval(&eval_query, q->query);
+ query = eval_query.str;
+ query_len = eval_query.length;
+ }
+
+ if (q->record_file[0])
{
init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds = &ds_tmp;
}
else
ds= &ds_res;
-
+
if ((flags & QUERY_SEND) && mysql_send_query(mysql, query, query_len))
- die("At line %u: unable to send query '%s'", start_lineno, query);
- if(!(flags & QUERY_REAP))
- return 0;
-
+ die("At line %u: unable to send query '%s'(mysql_errno=%d,errno=%d)",
+ start_lineno, query,
+ mysql_errno(mysql), errno);
+ if ((flags & QUERY_SEND) && !disable_query_log)
+ {
+ replace_dynstr_append_mem(ds,query, query_len);
+ dynstr_append_mem(ds,";\n",2);
+ }
+ if (!(flags & QUERY_REAP))
+ DBUG_RETURN(0);
+
if (mysql_read_query_result(mysql) ||
- (!(res = mysql_store_result(mysql)) && mysql_field_count(mysql)))
+ (!(last_result = res = mysql_store_result(mysql)) &&
+ mysql_field_count(mysql)))
{
if (q->require_file)
+ {
abort_not_supported_test();
+ }
if (q->abort_on_error)
die("At line %u: query '%s' failed: %d: %s", start_lineno, query,
mysql_errno(mysql), mysql_error(mysql));
else
{
- for (i=0 ; q->expected_errno[i] ; i++)
+ for (i=0 ; (uint) i < q->expected_errors ; i++)
{
if ((q->expected_errno[i] == mysql_errno(mysql)))
+ {
+ if (i == 0 && q->expected_errors == 1)
+ {
+ /* Only log error if there is one possible error */
+ replace_dynstr_append_mem(ds,mysql_error(mysql),
+ strlen(mysql_error(mysql)));
+ dynstr_append_mem(ds,"\n",1);
+ }
+ /* Don't log error if we may not get an error */
+ else if (q->expected_errno[0] != 0)
+ dynstr_append(ds,"Got one of the listed errors\n");
goto end; /* Ok */
+ }
}
if (i)
{
+ replace_dynstr_append_mem(ds, mysql_error(mysql),
+ strlen(mysql_error(mysql)));
+ dynstr_append_mem(ds,"\n",1);
verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
q->query, mysql_errno(mysql), q->expected_errno[0]);
error=1;
goto end;
}
+ replace_dynstr_append_mem(ds,mysql_error(mysql),
+ strlen(mysql_error(mysql)));
+ dynstr_append_mem(ds,"\n",1);
verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql),
mysql_error(mysql));
/*
@@ -1773,51 +2145,45 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
goto end;
}
- if (!res) goto end;
+ if (!res)
+ goto end;
- fields = mysql_fetch_fields(res);
- num_fields = mysql_num_fields(res);
- for( i = 0; i < num_fields; i++)
+ if (!disable_result_log)
{
- if (i)
- dynstr_append_mem(ds, "\t", 1);
- dynstr_append(ds, fields[i].name);
- }
-
- dynstr_append_mem(ds, "\n", 1);
+ fields = mysql_fetch_fields(res);
+ num_fields = mysql_num_fields(res);
+ for (i = 0; i < num_fields; i++)
+ {
+ if (i)
+ dynstr_append_mem(ds, "\t", 1);
+ dynstr_append(ds, fields[i].name);
+ }
+ dynstr_append_mem(ds, "\n", 1);
- while((row = mysql_fetch_row(res)))
- {
- lengths = mysql_fetch_lengths(res);
- for(i = 0; i < num_fields; i++)
+ while ((row = mysql_fetch_row(res)))
{
- val = (char*)row[i];
- len = lengths[i];
-
- if (!val)
+ lengths = mysql_fetch_lengths(res);
+ for(i = 0; i < num_fields; i++)
{
- val = (char*)"NULL";
- len = 4;
- }
+ val = (char*)row[i];
+ len = lengths[i];
- if (i)
- dynstr_append_mem(ds, "\t", 1);
- if (glob_replace)
- {
- len=(int) replace_strings(glob_replace, &out_buff, &out_length, val);
- if (len == -1)
- die("Out of memory in replace\n");
- val=out_buff;
+ if (!val)
+ {
+ val = (char*)"NULL";
+ len = 4;
+ }
+
+ if (i)
+ dynstr_append_mem(ds, "\t", 1);
+ replace_dynstr_append_mem(ds, val, len);
}
- dynstr_append_mem(ds, val, len);
+ dynstr_append_mem(ds, "\n", 1);
}
-
- dynstr_append_mem(ds, "\n", 1);
+ if (glob_replace)
+ free_replace();
}
- if (glob_replace)
- free_replace();
-
if (record)
{
if (!q->record_file[0] && !result_file)
@@ -1831,7 +2197,9 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
}
end:
- if (res) mysql_free_result(res);
+ if (res)
+ mysql_free_result(res);
+ last_result=0;
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
if(q->type == Q_EVAL)
@@ -1874,23 +2242,27 @@ static VAR* var_init(VAR* v, const char* name, int name_len, const char* val,
{
int val_alloc_len;
VAR* tmp_var;
- if(!name_len && name)
+ if (!name_len && name)
name_len = strlen(name);
- if(!val_len && val)
+ if (!val_len && val)
val_len = strlen(val) ;
val_alloc_len = val_len + 16; /* room to grow */
- if(!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
- + name_len, MYF(MY_WME))))
+ if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
+ + name_len, MYF(MY_WME))))
die("Out of memory");
-
- tmp_var->name = (name) ? (char*)tmp_var + sizeof(*tmp_var) : 0;
- if(!(tmp_var->str_val = my_malloc(val_alloc_len, MYF(MY_WME))))
+ tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
+ tmp_var->alloced = (v == 0);
+
+ if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME))))
die("Out of memory");
-
+
memcpy(tmp_var->name, name, name_len);
- if(val)
- memcpy(tmp_var->str_val, val, val_len + 1);
+ if (val)
+ {
+ memcpy(tmp_var->str_val, val, val_len);
+ tmp_var->str_val[val_len]=0;
+ }
tmp_var->name_len = name_len;
tmp_var->str_val_len = val_len;
tmp_var->alloced_len = val_alloc_len;
@@ -1902,7 +2274,8 @@ static VAR* var_init(VAR* v, const char* name, int name_len, const char* val,
static void var_free(void* v)
{
my_free(((VAR*) v)->str_val, MYF(MY_WME));
- my_free((char*) v, MYF(MY_WME));
+ if (((VAR*)v)->alloced)
+ my_free((char*) v, MYF(MY_WME));
}
@@ -1910,9 +2283,9 @@ static void var_from_env(const char* name, const char* def_val)
{
const char* tmp;
VAR* v;
- if(!(tmp = getenv(name)))
+ if (!(tmp = getenv(name)))
tmp = def_val;
-
+
v = var_init(0, name, 0, tmp, 0);
hash_insert(&var_hash, (byte*)v);
}
@@ -1920,14 +2293,18 @@ static void var_from_env(const char* name, const char* def_val)
static void init_var_hash()
{
+ VAR* v;
if (hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed");
var_from_env("MASTER_MYPORT", "9306");
var_from_env("SLAVE_MYPORT", "9307");
var_from_env("MYSQL_TEST_DIR", "/tmp");
var_from_env("BIG_TEST", opt_big_test ? "1" : "0");
+ v=var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "63",0);
+ hash_insert(&var_hash, (byte*)v);
}
+
int main(int argc, char** argv)
{
int error = 0;
@@ -1935,6 +2312,9 @@ int main(int argc, char** argv)
my_bool require_file=0, q_send_flag=0;
char save_file[FN_REFLEN];
MY_INIT(argv[0]);
+ {
+ DBUG_ENTER("main");
+ DBUG_PROCESS(argv[0]);
save_file[0]=0;
TMPDIR[0]=0;
@@ -1942,7 +2322,7 @@ int main(int argc, char** argv)
cons_end = cons + MAX_CONS;
next_con = cons + 1;
cur_con = cons;
-
+
memset(file_stack, 0, sizeof(file_stack));
memset(&master_pos, 0, sizeof(master_pos));
file_stack_end = file_stack + MAX_INCLUDE_DEPTH;
@@ -1959,20 +2339,30 @@ int main(int argc, char** argv)
*block_ok = 1;
init_dynamic_string(&ds_res, "", 0, 65536);
parse_args(argc, argv);
+ if (mysql_server_init(embedded_server_arg_count,
+ embedded_server_args,
+ (char**) embedded_server_groups))
+ die("Can't initialize MySQL server");
init_var_hash();
- if (!*cur_file)
- *cur_file = stdin;
+ if (cur_file == file_stack)
+ *++cur_file = stdin;
*lineno=1;
-
+#ifndef EMBEDDED_LIBRARY
+ if (manager_host)
+ init_manager();
+#endif
if (!( mysql_init(&cur_con->mysql)))
die("Failed in mysql_init()");
+ if (opt_compress)
+ mysql_options(&cur_con->mysql,MYSQL_OPT_COMPRESS,NullS);
+ mysql_options(&cur_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
+
cur_con->name = my_strdup("default", MYF(MY_WME));
if (!cur_con->name)
die("Out of memory");
- if (!mysql_real_connect(&cur_con->mysql, host,
- user, pass, db, port, unix_sock,
- 0))
+ if (safe_connect(&cur_con->mysql, host,
+ user, pass, db, port, unix_sock))
die("Failed in mysql_real_connect(): %s", mysql_error(&cur_con->mysql));
while (!read_query(&q))
@@ -1990,10 +2380,21 @@ int main(int argc, char** argv)
case Q_DIRTY_CLOSE:
close_connection(q); break;
case Q_RPL_PROBE: do_rpl_probe(q); break;
- case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
- case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
+ case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
+ case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
+ case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
+ case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
+ case Q_ENABLE_RESULT_LOG: disable_result_log=0; break;
+ case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
case Q_SOURCE: do_source(q); break;
case Q_SLEEP: do_sleep(q); break;
+ case Q_REQUIRE_VERSION: do_require_version(q); break;
+ case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(q); break;
+ case Q_REQUIRE_MANAGER: do_require_manager(q); break;
+#ifndef EMBEDDED_LIBRARY
+ case Q_SERVER_START: do_server_start(q); break;
+ case Q_SERVER_STOP: do_server_stop(q); break;
+#endif
case Q_INC: do_inc(q); break;
case Q_DEC: do_dec(q); break;
case Q_ECHO: do_echo(q); break;
@@ -2002,14 +2403,16 @@ int main(int argc, char** argv)
case Q_EVAL_RESULT: eval_result = 1; break;
case Q_EVAL:
if (q->query == q->query_buf)
- q->query += q->first_word_len;
+ q->query= q->first_argument;
/* fall through */
case Q_QUERY:
case Q_REAP:
{
- int flags = QUERY_REAP; /* we read the result always regardless
- * of the mode for both full query and
- * read-result only ( reap) */
+ /*
+ We read the result always regardless of the mode for both full
+ query and read-result only (reap)
+ */
+ int flags = QUERY_REAP;
if (q->type != Q_REAP) /* for a full query, enable the send stage */
flags |= QUERY_SEND;
if (q_send_flag)
@@ -2036,19 +2439,20 @@ int main(int argc, char** argv)
/* fix up query pointer if this is * first iteration for this line */
if (q->query == q->query_buf)
q->query += q->first_word_len;
- error |= run_query(&cur_con->mysql, q, QUERY_SEND);
- /* run query can execute a query partially, depending on the flags
- * QUERY_SEND flag without QUERY_REAP tells it to just send the
- * query and read the result some time later when reap instruction
- * is given on this connection
+ /*
+ run_query() can execute a query partially, depending on the flags
+ QUERY_SEND flag without QUERY_REAP tells it to just send the
+ query and read the result some time later when reap instruction
+ is given on this connection.
*/
+ error |= run_query(&cur_con->mysql, q, QUERY_SEND);
break;
case Q_RESULT:
get_file_name(save_file,q);
require_file=0;
break;
case Q_ERROR:
- get_ints(global_expected_errno,q);
+ global_expected_errors=get_ints(global_expected_errno,q);
break;
case Q_REQUIRE:
get_file_name(save_file,q);
@@ -2092,7 +2496,7 @@ int main(int argc, char** argv)
dynstr_free(&ds_res);
if (!silent) {
- if(error)
+ if (error)
printf("not ok\n");
else
printf("ok\n");
@@ -2101,8 +2505,54 @@ int main(int argc, char** argv)
free_used_memory();
exit(error ? 1 : 0);
return error ? 1 : 0; /* Keep compiler happy */
+ }
}
+/*
+ Read arguments for embedded server and put them into
+ embedded_server_args_count and embedded_server_args[]
+*/
+
+
+static int read_server_arguments(const char* name)
+{
+ char argument[1024],buff[FN_REFLEN], *str=0;
+ FILE *file;
+
+ if (!test_if_hard_path(name))
+ {
+ strxmov(buff, opt_basedir, name, NullS);
+ name=buff;
+ }
+ fn_format(buff,name,"","",4);
+
+ if (!embedded_server_arg_count)
+ {
+ embedded_server_arg_count=1;
+ embedded_server_args[0]= (char*) ""; /* Progname */
+ }
+ if (!(file=my_fopen(buff, O_RDONLY | O_BINARY, MYF(MY_WME))))
+ return 1;
+ while (embedded_server_arg_count < MAX_SERVER_ARGS &&
+ (str=fgets(argument,sizeof(argument), file)))
+ {
+ *(strend(str)-1)=0; /* Remove end newline */
+ if (!(embedded_server_args[embedded_server_arg_count]=
+ (char*) my_strdup(str,MYF(MY_WME))))
+ {
+ my_fclose(file,MYF(0));
+ return 1;
+ }
+ embedded_server_arg_count++;
+ }
+ my_fclose(file,MYF(0));
+ if (str)
+ {
+ fprintf(stderr,"Too many arguments in option file: %s\n",name);
+ return 1;
+ }
+ return 0;
+}
/****************************************************************************
* Handle replacement of strings
@@ -2760,7 +3210,7 @@ static uint replace_len(my_string str)
/* Replace strings; Return length of result string */
uint replace_strings(REPLACE *rep, my_string *start,uint *max_length,
- my_string from)
+ const char *from)
{
reg1 REPLACE *rep_pos;
reg2 REPLACE_STRING *rep_str;
diff --git a/client/password.c b/client/password.c
index 0fd5861873a..9b154603b98 100644
--- a/client/password.c
+++ b/client/password.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* password checking routines */
/*****************************************************************************
@@ -35,7 +34,7 @@
This saves a hashed number as a string in the password field.
*****************************************************************************/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "mysql.h"
diff --git a/client/readline.cc b/client/readline.cc
index f0312b089e5..f5fbfd8cd0c 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* readline for batch mode */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "my_readline.h"
@@ -120,20 +119,11 @@ static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str)
}
-static void free_line_buffer(LINE_BUFFER *buffer)
-{
- if (buffer->buffer)
- {
- my_free((gptr) buffer->buffer,MYF(0));
- buffer->buffer=0;
- }
-}
-
-
-/* Fill the buffer retaining the last n bytes at the beginning of the
- newly filled buffer (for backward context). Returns the number of new
- bytes read from disk. */
-
+/*
+ Fill the buffer retaining the last n bytes at the beginning of the
+ newly filled buffer (for backward context). Returns the number of new
+ bytes read from disk.
+*/
static uint fill_buffer(LINE_BUFFER *buffer)
{
diff --git a/client/select_test.c b/client/select_test.c
index 049f2b908be..ee2a9192865 100644
--- a/client/select_test.c
+++ b/client/select_test.c
@@ -1,20 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
diff --git a/client/showdb_test.c b/client/showdb_test.c
index f4c25999fe5..df2b3037c00 100644
--- a/client/showdb_test.c
+++ b/client/showdb_test.c
@@ -1,34 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
#ifdef __WIN__
#include <windows.h>
#endif
diff --git a/client/sql_string.cc b/client/sql_string.cc
index 4b9ebef21f1..3c5e481eaad 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program file is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
@@ -21,7 +20,7 @@
#pragma implementation // gcc: Class implementation
#endif
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
diff --git a/client/sql_string.h b/client/sql_string.h
index 74dbc4cc6bd..cffe78936a0 100644
--- a/client/sql_string.h
+++ b/client/sql_string.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
diff --git a/client/ssl_test.c b/client/ssl_test.c
index d1ec1776696..279c1e95fdc 100644
--- a/client/ssl_test.c
+++ b/client/ssl_test.c
@@ -1,34 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
#ifdef __WIN__
#include <windows.h>
#endif
diff --git a/client/thimble.cc b/client/thimble.cc
index 6d1e8a85559..94b75d8fb35 100644
--- a/client/thimble.cc
+++ b/client/thimble.cc
@@ -1,8 +1,24 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "my_global.h"
+#include "my_my_global.h"
static void spawn_stern_thread(pthread_t *t);
static int act_goofy(void);
@@ -89,5 +105,3 @@ static void *be_stern(void *v __attribute__((unused)))
fputs("You are NOTHING!\n", stderr);
return NULL;
}
-
-
diff --git a/client/thread_test.c b/client/thread_test.c
index dbe2acee8db..2900ab712e2 100644
--- a/client/thread_test.c
+++ b/client/thread_test.c
@@ -1,25 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#ifndef THREAD
-int main(void)
+int main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
printf("This test must be compiled with multithread support to work\n");
exit(1);
@@ -29,9 +28,9 @@ int main(void)
#include <my_sys.h>
#include <my_pthread.h>
#include "mysql.h"
-#include <getopt.h>
+#include <my_getopt.h>
-static my_bool version,verbose;
+static my_bool version, verbose, tty_password= 0;
static uint thread_count,number_of_tests=1000,number_of_threads=2;
static pthread_cond_t COND_thread_count;
static pthread_mutex_t LOCK_thread_count;
@@ -85,23 +84,39 @@ end:
}
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, '?'},
- {"database", required_argument, 0, 'D'},
- {"host", required_argument, 0, 'h'},
- {"password", optional_argument, 0, 'p'},
- {"user", required_argument, 0, 'u'},
- {"version", no_argument, 0, 'V'},
- {"verbose", no_argument, 0, 'v'},
- {"query", required_argument, 0, 'Q'},
- {"port", required_argument, 0, 'P'},
- {"socket", required_argument, 0, 'S'},
- {"test-count",required_argument, 0, 'c'},
- {"thread-count",required_argument, 0, 't'},
- {0, 0, 0, 0}
+ {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"database", 'D', "Database to use", (gptr*) &database, (gptr*) &database,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host", (gptr*) &host, (gptr*) &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login if not current user", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write some progress indicators", (gptr*) &verbose,
+ (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"query", 'Q', "Query to execute in each threads", (gptr*) &query,
+ (gptr*) &query, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection", (gptr*) &tcp_port,
+ (gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection", (gptr*) &unix_socket,
+ (gptr*) &unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"test-count", 'c', "Run test count times (default %d)",
+ (gptr*) &number_of_tests, (gptr*) &number_of_tests, 0, GET_UINT,
+ REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"thread-count", 't', "Number of threads to start",
+ (gptr*) &number_of_threads, (gptr*) &number_of_threads, 0, GET_UINT,
+ REQUIRED_ARG, 2, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static const char *load_default_groups[]= { "client",0 };
static void usage()
@@ -111,103 +126,55 @@ static void usage()
return;
puts("This software comes with ABSOLUTELY NO WARRANTY.\n");
printf("Usage: %s [OPTIONS] [database]\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit\n\
- -c #, --test-count=# Run test count times (default %d)\n",number_of_tests);
- printf("\
- -D, --database=.. Database to use\n\
- -h, --host=... Connect to host\n\
- -p[password], --password[=...]\n\
- Password to use when connecting to server\n\
- If password is not given it's asked from the tty.\n");
- printf("\n\
- -P --port=... Port number to use for connection\n\
- -Q, --query=... Query to execute in each threads\n\
- -S --socket=... Socket file to use for connection\n");
- printf("\
- -t --thread-count=# Number of threads to start (default: %d) \n\
- -u, --user=# User for login if not current user\n\
- -v, --verbose Write some progress indicators\n\
- -V, --version Output version information and exit\n",
- number_of_threads);
+ my_print_help(my_long_options);
print_defaults("my",load_default_groups);
-
+ my_print_variables(my_long_options);
printf("\nExample usage:\n\n\
%s -Q 'select * from mysql.user' -c %d -t %d\n",
my_progname, number_of_tests, number_of_threads);
}
-static void get_options(int argc, char **argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index=0,error=0;
- bool tty_password=0;
- load_defaults("my",load_default_groups,&argc,&argv);
-
- while ((c=getopt_long(argc,argv, "c:D:h:p::VQ:P:S:t:?I",
- long_options, &option_index)) != EOF)
- {
- switch (c) {
- case 'c':
- number_of_tests=atoi(optarg);
- break;
- case 'D':
- my_free(database,MYF(MY_ALLOW_ZERO_PTR));
- database=my_strdup(optarg,MYF(MY_WME));
- break;
- case 'h':
- host = optarg;
- break;
- case 'Q': /* Allow old 'q' option */
- query= optarg;
- break;
- case 'p':
- if (optarg)
- {
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
- password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- }
- else
- tty_password=1;
- break;
- case 'u':
- my_free(user,MYF(MY_ALLOW_ZERO_PTR));
- user= my_strdup(optarg,MYF(0));
- break;
- case 'P':
- tcp_port= (unsigned int) atoi(optarg);
- break;
- case 'S':
- my_free(unix_socket,MYF(MY_ALLOW_ZERO_PTR));
- unix_socket= my_strdup(optarg,MYF(0));
- break;
- case 't':
- number_of_threads=atoi(optarg);
- break;
- case 'v':
- verbose=1;
- break;
- case 'V':
- version=1;
- usage();
- exit(0);
- break;
- default:
- fprintf(stderr,"Illegal option character '%c'\n",opterr);
- /* Fall through */
- case '?':
- case 'I': /* Info */
- error++;
- break;
+ switch (optid) {
+ case 'p':
+ if (argument)
+ {
+ my_free(password, MYF(MY_ALLOW_ZERO_PTR));
+ password= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
}
- }
- if (error || argc != optind)
- {
+ else
+ tty_password= 1;
+ break;
+ case 'V':
+ version= 1;
+ usage();
+ exit(0);
+ break;
+ case '?':
+ case 'I': /* Info */
usage();
exit(1);
+ break;
}
+ return 0;
+}
+
+
+static void get_options(int argc, char **argv)
+{
+ int ho_error;
+
+ load_defaults("my",load_default_groups,&argc,&argv);
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
free_defaults(argv);
if (tty_password)
password=get_tty_password(NullS);
diff --git a/client/violite.c b/client/violite.c
deleted file mode 100644
index 224ba051d82..00000000000
--- a/client/violite.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#include <global.h>
-
-#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
-
-#include <errno.h>
-#include <assert.h>
-#include <violite.h>
-#include <my_sys.h>
-#include <my_net.h>
-#include <m_string.h>
-
-#if defined(__EMX__)
-#include <sys/ioctl.h>
-#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
-#undef HAVE_FCNTL
-#endif /* defined(__EMX__) */
-
-#if defined(MSDOS) || defined(__WIN__)
-#ifdef __WIN__
-#undef errno
-#undef EINTR
-#undef EAGAIN
-#define errno WSAGetLastError()
-#define EINTR WSAEINTR
-#define EAGAIN WSAEINPROGRESS
-#endif /* __WIN__ */
-#define O_NONBLOCK 1 /* For emulation of fcntl() */
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK EAGAIN
-#endif
-
-#ifndef __WIN__
-#define HANDLE void *
-#endif
-
-struct st_vio
-{
- my_socket sd; /* my_socket - real or imaginary */
- HANDLE hPipe;
- my_bool localhost; /* Are we from localhost? */
- int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- my_bool fcntl_set; /* Have we done any fcntl yet?*/
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
- enum enum_vio_type type; /* Type of connection */
- char desc[30]; /* String description */
-};
-
-typedef void *vio_ptr;
-typedef char *vio_cstring;
-
-/*
- * Helper to fill most of the Vio* with defaults.
- */
-
-static void vio_reset(Vio* vio, enum enum_vio_type type,
- my_socket sd, HANDLE hPipe,
- my_bool localhost)
-{
- bzero((char*) vio, sizeof(*vio));
- vio->type = type;
- vio->sd = sd;
- vio->hPipe = hPipe;
- vio->localhost= localhost;
-}
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
-{
- Vio *vio;
- DBUG_ENTER("vio_new");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
- {
- vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc, "socket (%d)", vio->sd);
- }
- DBUG_RETURN(vio);
-}
-
-
-#ifdef __WIN__
-
-Vio *vio_new_win32pipe(HANDLE hPipe)
-{
- Vio *vio;
- DBUG_ENTER("vio_new_handle");
- if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
- {
- vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
- strmov(vio->desc, "named pipe");
- }
- DBUG_RETURN(vio);
-}
-
-#endif
-
-void vio_delete(Vio * vio)
-{
- /* It must be safe to delete null pointers. */
- /* This matches the semantics of C++'s delete operator. */
- if (vio)
- {
- vio_close(vio);
- my_free((gptr) vio,MYF(0));
- }
-}
-
-int vio_errno(Vio *vio)
-{
- return errno; /* On Win32 this mapped to WSAGetLastError() */
-}
-
-
-int vio_read(Vio * vio, gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_read");
- DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
- assert(vio->sd >= 0);
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
- DBUG_RETURN(length);
- }
- r = recv(vio->sd, buf, size,0);
-#else
- errno=0; /* For linux */
- r = read(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("error", ("Got error %d during read",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_write(Vio * vio, const gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_write");
- DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
- assert(vio->sd >= 0);
-#ifdef __WIN__
- if ( vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
- DBUG_RETURN(length);
- }
- r = send(vio->sd, buf, size,0);
-#else
- r = write(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("error", ("Got error on write: %d",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_blocking(Vio * vio, my_bool set_blocking_mode)
-{
- int r=0;
- DBUG_ENTER("vio_blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN__) && !defined(__EMX__)
-#if !defined(NO_FCNTL_NONBLOCK)
-
- if (vio->sd >= 0)
- {
- int old_fcntl=vio->fcntl_mode;
- if (!vio->fcntl_set)
- {
- vio->fcntl_set = TRUE;
- old_fcntl=vio->fcntl_mode = fcntl(vio->sd, F_GETFL);
- }
- if (set_blocking_mode)
- vio->fcntl_mode &= ~O_NONBLOCK; /*clear bit */
- else
- vio->fcntl_mode |= O_NONBLOCK; /*set bit */
- if (old_fcntl != vio->fcntl_mode)
- r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
- }
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN__) && !defined(__EMX__) */
-#ifndef __EMX__
- if (vio->type != VIO_TYPE_NAMEDPIPE)
-#endif
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (!vio->fcntl_set)
- {
- vio->fcntl_set = TRUE;
- old_fnctl=vio->fcntl_mode=0;
- }
- if (set_blocking_mode)
- {
- arg = 0;
- vio->fcntl_mode &= ~O_NONBLOCK; /*clear bit */
- }
- else
- {
- arg = 1;
- vio->fcntl_mode |= O_NONBLOCK; /*set bit */
- }
- if (old_fcntl != vio->fcntl_mode)
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif /* !defined(__WIN__) && !defined(__EMX__) */
- DBUG_RETURN(r);
-}
-
-my_bool
-vio_is_blocking(Vio * vio)
-{
- my_bool r;
- DBUG_ENTER("vio_is_blocking");
- r = !(vio->fcntl_mode & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int) r));
- DBUG_RETURN(r);
-}
-
-
-int vio_fastsend(Vio * vio, my_bool onoff)
-{
- int r=0;
- DBUG_ENTER("vio_fastsend");
- DBUG_PRINT("enter", ("onoff:%d", (int) onoff));
- assert(vio->sd >= 0);
-
-#ifdef IPTOS_THROUGHPUT
- {
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
- sizeof(nodelay))) {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int vio_keepalive(Vio* vio, my_bool set_keep_alive)
-{
- int r=0;
- uint opt = 0;
- DBUG_ENTER("vio_keepalive");
- DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- assert(vio->sd >= 0);
- if (set_keep_alive)
- opt = 1;
- r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_should_retry(Vio * vio)
-{
- int en = errno;
- return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
-}
-
-
-int vio_close(Vio * vio)
-{
- int r;
- DBUG_ENTER("vio_close");
- assert(vio->sd >= 0); /* Vill also work on PIPE:s */
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIO(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else
-#endif /* __WIN__ */
- {
- r=0;
- if (shutdown(vio->sd,2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("error", ("close() failed, error: %d",errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio_reset(vio,VIO_CLOSED,-1,0,TRUE); /* For debugging */
- DBUG_RETURN(r);
-}
-
-
-const char *vio_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_peer_addr(Vio * vio, char *buf)
-{
- DBUG_ENTER("vio_peer_addr");
- DBUG_PRINT("enter", ("sd=%d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(vio->remote.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-void vio_in_addr(Vio *vio, struct in_addr *in)
-{
- DBUG_ENTER("vio_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in)); /* This should never be executed */
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-#endif /* HAVE_VIO */
diff --git a/config.guess b/config.guess
index a3369c0f908..7c3ea484210 100755
--- a/config.guess
+++ b/config.guess
@@ -563,6 +563,15 @@ EOF
F301:UNIX_System_V:*:*)
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ if test "${UNAME_MACHINE}" = "c86pc"; then
+ UNAME_MACHINE=pc
+ fi
+ echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+ exit 0;;
+ *:QNX:*:*)
+ echo i386-pc-qnx
+ exit 0;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
diff --git a/config.sub b/config.sub
index 70716b4e206..5f082e14a35 100755
--- a/config.sub
+++ b/config.sub
@@ -111,7 +111,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- linux-gnu*)
+ nto-qnx* | linux-gnu*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -636,6 +636,20 @@ case $basic_machine in
basic_machine=i960-intel
os=-nindy
;;
+ ntox86)
+ basic_machine=i386${os:--unknown}
+ os=-nto-qnx
+ ;;
+ nto*le | not*be)
+ basic_machine=${basic_machine%%be}
+ basic_machine=${basic_machine%%le}
+ basic_machine=${basic_machine##nto}${os:--unknown}
+ os=-nto-qnx
+ ;;
+ nto*)
+ basic_machine=${basic_machine##nto}${os:--unknown}
+ os=-nto-qnx
+ ;;
mon960)
basic_machine=i960-intel
os=-mon960
diff --git a/configure.in b/configure.in
index 460c5e73abe..48252847f53 100644
--- a/configure.in
+++ b/configure.in
@@ -4,13 +4,13 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
-AM_INIT_AUTOMAKE(mysql, 3.23.52)
+AM_INIT_AUTOMAKE(mysql, 4.0.3-beta)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
DOT_FRM_VERSION=6
# See the libtool docs for information on how to do shared lib versions.
-SHARED_LIB_VERSION=10:0:0
+SHARED_LIB_VERSION=11:0:0
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4
@@ -318,7 +318,7 @@ then
# mysqld doesn't use run-time-type-checking, so we disable it.
CXXFLAGS="$CXXFLAGS -fno-implicit-templates -fno-exceptions -fno-rtti"
- # If you are using 'gcc' 3.0 (not g++) to compile C++ programs,
+ # If you are using 'gcc' 3.0 (not g++) to compile C++ programs on Linux,
# we will gets some problems when linking static programs.
# The following code is used to fix this problem.
@@ -326,8 +326,7 @@ then
then
if $CXX -v 2>&1 | grep 'version 3' > /dev/null 2>&1
then
- CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW"
- CXXLDFLAGS="$CXXLDFLAGS -Wl,--defsym -Wl,__cxa_pure_virtual=0"
+ CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL"
fi
fi
fi
@@ -367,6 +366,7 @@ AC_PATH_PROG(HOSTNAME, hostname, hostname)
# Check for a GNU tar named 'gtar', or 'gnutar' (MacOS X) and
# fall back to 'tar' otherwise and hope that it's a GNU tar as well
AC_CHECK_PROGS(TAR, gnutar gtar tar)
+
dnl We use a path for perl so the script startup works
dnl We make sure to use perl, not perl5, in hopes that the RPMs will
dnl not depend on the perl5 binary being installed (probably a bug in RPM)
@@ -452,9 +452,12 @@ fi
NOINST_LDFLAGS=
-
AC_ARG_WITH(other-libc,
- [ --with-other-libc=/path/to/other/libc/dir Link against libc and other standard libraries installed in the specified non-standard location overriding default. Originally added to be able to link against glibc 2.2 without making the user upgrade the standard libc installation ],
+ [ --with-other-libc=DIR Link against libc and other standard libraries
+ installed in the specified non-standard location
+ overriding default. Originally added to be able to
+ link against glibc 2.2 without making the user
+ upgrade the standard libc installation.],
[
other_libc_include="$withval/include"
other_libc_lib="$withval/lib"
@@ -505,7 +508,6 @@ AC_SUBST(NOINST_LDFLAGS)
AC_ARG_WITH(server-suffix,
[ --with-server-suffix Append value to the version string.],
- # I heard that 'cut' isn't portable. Isn't there a better way?
[ MYSQL_SERVER_SUFFIX=`echo "$withval" | sed -e 's/^\(...................................\)..*$/\1/'` ],
[ MYSQL_SERVER_SUFFIX= ]
)
@@ -630,15 +632,13 @@ AC_ARG_WITH(mysqld-user,
)
AC_SUBST(MYSQLD_USER)
-# If we should allove LOAD DATA LOCAL
+# If we should allow LOAD DATA LOCAL
AC_MSG_CHECKING(if we should should enable LOAD DATA LOCAL by default)
AC_ARG_ENABLE(local-infile,
- [ --enable-local-infile
- Enable LOAD DATA LOCAL INFILE (default: disabled)],
+ [ --enable-local-infile Enable LOAD DATA LOCAL INFILE (default: disabled)],
[ ENABLED_LOCAL_INFILE=$enableval ],
[ ENABLED_LOCAL_INFILE=no ]
)
-
if test "$ENABLED_LOCAL_INFILE" = "yes"
then
AC_MSG_RESULT([yes])
@@ -689,6 +689,9 @@ AC_CHECK_FUNC(bind, , AC_CHECK_LIB(bind, bind))
AC_CHECK_LIB(crypt, crypt)
AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT))
+# For sem_xxx functions on Solaris 2.6
+AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4))
+
# For compress in zlib
MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib)
@@ -697,7 +700,7 @@ MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib)
#--------------------------------------------------------------------
AC_ARG_WITH(libwrap,
-[ --with-libwrap[=DIR] Compile in libwrap (tcp_wrappers) support],[
+[ --with-libwrap[=DIR] Compile in libwrap (tcp_wrappers) support],[
case "$with_libwrap" in
no) : ;;
yes|*)
@@ -766,7 +769,46 @@ int main()
if test -z "$atom_ops"; then atom_ops="no"; fi
AC_MSG_RESULT($atom_ops)
+
+ AC_ARG_WITH(pstack,
+ [ --with-pstack Use the pstack backtrace library],
+ [ USE_PSTACK=$withval ],
+ [ USE_PSTACK=no ])
+ pstack_libs=
+ pstack_dirs=
+ if test "$USE_PSTACK" = yes -a "$IS_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" -a "$with_mit_threads" = "no"
+ then
+ have_libiberty= have_libbfd=
+ my_save_LIBS="$LIBS"
+dnl I have no idea if this is a good test - can not find docs for libiberty
+ AC_CHECK_LIB([iberty], [fdmatch],
+ [have_libiberty=yes
+ AC_CHECK_LIB([bfd], [bfd_openr], [have_libbfd=yes], , [-liberty])])
+ LIBS="$my_save_LIBS"
+
+ if test x"$have_libiberty" = xyes -a x"$have_libbfd" = xyes
+ then
+ pstack_dirs='$(top_srcdir)'/pstack
+ pstack_libs="../pstack/libpstack.a -lbfd -liberty"
+ # We must link staticly when using pstack
+ with_mysqld_ldflags="-all-static"
+ AC_SUBST([pstack_dirs])
+ AC_SUBST([pstack_libs])
+ AC_DEFINE([USE_PSTACK])
+dnl This check isn't needed, but might be nice to give some feedback....
+dnl AC_CHECK_HEADER(libiberty.h,
+dnl have_libiberty_h=yes,
+dnl have_libiberty_h=no)
+ else
+ USE_PSTACK="no"
+ fi
+ else
+ USE_PSTACK="no"
+ fi
fi
+AM_CONDITIONAL(COMPILE_PSTACK, test "$USE_PSTACK" = "yes")
+AC_MSG_CHECKING([if we should use pstack])
+AC_MSG_RESULT([$USE_PSTACK])
# Check for gtty if termio.h doesn't exists
if test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no"
@@ -952,7 +994,7 @@ then
AC_TRY_COMPILE([#include <sched.h>], [int a = sched_get_priority_min(1);], ,
AC_MSG_ERROR([Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file. See the Installation chapter in the Reference Manual]))
# RedHat 5.0 does not work with dynamic linking of this. -static also
- # gives a spped increase in linux so it does not hurt on other systems.
+ # gives a speed increase in linux so it does not hurt on other systems.
with_named_thread="-lpthread"
else
AC_MSG_RESULT("Not found")
@@ -960,15 +1002,16 @@ then
if test "$IS_LINUX" = "true"
then
AC_MSG_ERROR([This is a linux system and Linuxthreads was not
-found. On linux Linuxthreads should be used. So install Linuxthreads
-(or a new glibc) and try again. See the Installation chapter in the
-Reference Manual.])
+found. On linux Linuxthreads should be used. Please install Linuxthreads
+(or a new glibc) and try again. See the Installation chapter in the
+Reference Manual for more information.])
else
AC_MSG_CHECKING("DEC threads")
if test -f /usr/shlib/libpthread.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a
then
with_named_thread="-lpthread -lmach -lexc"
- #with_named_thread="-lpthread -lmach -lexc -lc"
+ CFLAGS="$CFLAGS -D_REENTRANT"
+ CXXFLAGS="$CXXFLAGS -D_REENTRANT"
AC_DEFINE(HAVE_DEC_THREADS)
AC_MSG_RESULT("yes")
else
@@ -1195,11 +1238,14 @@ then
fi
fi
+TOOLS_LIBS="$NON_THREADED_CLIENT_LIBS"
+
# Should we use named pthread library ?
AC_MSG_CHECKING("named thread libs:")
if test "$with_named_thread" != "no"
then
LIBS="$with_named_thread $LIBS $with_named_thread"
+ TOOLS_LIBS="$with_named_thread $TOOLS_LIBS $with_named_thread"
with_posix_threads="yes"
with_mit_threads="no"
AC_MSG_RESULT("$with_named_thread")
@@ -1218,7 +1264,9 @@ else
then
AC_MSG_CHECKING("for pthread_create in -lpthread");
ac_save_LIBS="$LIBS"
+ ac_save_TOOLS_LIBS="$TOOLS_LIBS"
LIBS="$LIBS -lpthread"
+ TOOLS_LIBS="$TOOLS_LIBS -lpthread"
AC_TRY_LINK(
[#include <pthread.h>],
[ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ],
@@ -1227,6 +1275,7 @@ else
if test "$with_posix_threads" = "no"
then
LIBS=" $ac_save_LIBS -lpthreads"
+ TOOLS_LIBS=" $ac_save_TOOLS_LIBS -lpthreads"
AC_MSG_CHECKING("for pthread_create in -lpthreads");
AC_TRY_LINK(
[#include <pthread.h>],
@@ -1237,6 +1286,7 @@ else
then
# This is for FreeBSD
LIBS="$ac_save_LIBS -pthread"
+ TOOLS_LIBS="$ac_save_TOOLS_LIBS -pthread"
AC_MSG_CHECKING("for pthread_create in -pthread");
AC_TRY_LINK(
[#include <pthread.h>],
@@ -1247,6 +1297,7 @@ else
then
with_mit_threads="yes"
LIBS="$ac_save_LIBS"
+ TOOLS_LIBS="$ac_save_TOOLS_LIBS"
fi
fi
fi
@@ -1311,6 +1362,7 @@ else
DEBUG_OPTIMIZE_CXX=""
OPTIMIZE_CXXFLAGS="-O"
fi
+
AC_ARG_WITH(debug,
[ --without-debug Build a production version without debugging code],
[with_debug=$withval],
@@ -1477,7 +1529,7 @@ AC_SUBST(MAKE_SHELL)
AC_CHECK_HEADERS(varargs.h stdarg.h dirent.h locale.h ndir.h sys/dir.h \
sys/file.h sys/ndir.h sys/ptem.h sys/pte.h sys/select.h sys/stream.h \
sys/mman.h curses.h termcap.h termio.h termbits.h asm/termbits.h grp.h \
-paths.h)
+paths.h semaphore.h)
# Already-done: strcasecmp
AC_CHECK_FUNCS(lstat putenv select setenv setlocale strcoll tcgetattr)
@@ -1543,13 +1595,17 @@ ac_save_CXXFLAGS="$CXXFLAGS"
AC_CACHE_CHECK([style of gethost* routines], mysql_cv_gethost_style,
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
-# Do not treat warnings as errors if we are linking agaist other libc
+
+# Do not treat warnings as errors if we are linking against other libc
# this is to work around gcc not being permissive on non-system includes
# with respect to ANSI C++
-if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
+# We also remove the -fbranch-probabilities option as this will give warnings
+# about not profiled code, which confuses configure
+if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
then
- CXXFLAGS="$CXXFLAGS -Werror"
+ CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed 's/-fbranch-probabilities//'`
fi
+
AC_TRY_COMPILE(
[#undef inline
#if !defined(SCO) && !defined(__osf__) && !defined(_REENTRANT)
@@ -1694,7 +1750,7 @@ then
AC_DEFINE(HAVE_READDIR_R)
fi
-# Check definition av posix sigwait()
+# Check definition of posix sigwait()
AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait,
AC_TRY_LINK(
[#if !defined(SCO) && !defined(__osf__)
@@ -1717,7 +1773,7 @@ fi
if test "$mysql_cv_sigwait" != "POSIX"
then
unset mysql_cv_sigwait
-# Check definition av posix sigwait()
+# Check definition of posix sigwait()
AC_CACHE_CHECK("style of sigwait", mysql_cv_sigwait,
AC_TRY_LINK(
[#if !defined(SCO) && !defined(__osf__)
@@ -1777,6 +1833,59 @@ AC_ARG_WITH(server,
[with_server=yes]
)
+AC_ARG_WITH(embedded-server,
+ [ --with-embedded-server Build the embedded server (libmysqld).],
+ [with_embedded_server=$withval],
+ [with_embedded_server=no]
+)
+
+AC_ARG_WITH(query_cache,
+ [ --without-query-cache Do not build query cache.],
+ [with_query_cache=$withval],
+ [with_query_cache=yes]
+)
+
+if test "$with_query_cache" = "yes"
+then
+ AC_DEFINE(HAVE_QUERY_CACHE)
+fi
+
+AC_ARG_WITH(extra-tools,
+ [ --without-extra-tools Skip building utilites in the tools directory.],
+ [with_tools=$withval],
+ [with_tools=yes]
+)
+
+tools_dirs=""
+if test "$with_tools" = "yes"
+then
+ if test "$THREAD_SAFE_CLIENT" = "no"
+ then
+ echo "Warning: extra-tools disabled because --enable-thread-safe-client wasn't used"
+ else
+ tools_dirs="tools"
+ fi
+fi
+AC_SUBST(tools_dirs)
+
+#MYSQL_CHECK_CPU
+MYSQL_CHECK_MYSQLFS
+MYSQL_CHECK_VIO
+MYSQL_CHECK_OPENSSL
+
+libmysqld_dirs=
+if test "$with_embedded_server" = "yes"
+then
+ libmysqld_dirs=libmysqld
+ # We can't build embedded library without building the server, because
+ # we depend on libmysys, libmystrings, libmyisam, etc.
+ with_server=yes
+fi
+# XXX: We need to add @libmysqld_extra_libs@ (or whatever) so that
+# mysql_config --libmysqld-libs will print out something like
+# -L/path/to/lib/mysql -lmysqld -lmyisam -lmysys -lmystrings -ldbug ...
+AC_SUBST([libmysqld_dirs])
+
# Shall we build the docs?
AC_ARG_WITH(docs,
[ --without-docs Skip building of the documentation.],
@@ -1833,17 +1942,20 @@ dnl If the character set uses strcoll or other special handling,
dnl you must also create strings/ctype-$charset_name.c
AC_DIVERT_PUSH(0)
-CHARSETS_AVAILABLE="big5 cp1251 cp1257 croat czech danish dec8 dos estonia euc_kr gb2312 gbk german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr latin1 latin2 latin5 swe7 usa7 win1250 win1251 win1251ukr ujis sjis tis620"
+CHARSETS_AVAILABLE="big5 cp1251 cp1257
+ croat czech danish dec8 dos estonia euc_kr gb2312 gbk
+ german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr
+ latin1 latin1_de latin2 latin5 sjis swe7 tis620 ujis
+ usa7 win1250 win1251ukr"
+CHARSETS_DEPRECATED="win1251"
DEFAULT_CHARSET=latin1
AC_DIVERT_POP
-dnl win1251 is deprecated - it's available, but not listed here in the help
+dnl fix this later..
+dnl [ --with-charset=CHARSET Use CHARSET by default (one of: $CHARSETS_AVAILABLE; Default is $DEFAULT_CHARSET)],
+
AC_ARG_WITH(charset,
- [ --with-charset=CHARSET Use CHARSET by default (one of: big5 cp1251 cp1257
- croat czech danish dec8 dos estonia euc_kr gb2312 gbk
- german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr
- latin1 latin2 latin5 swe7 usa7 win1250 win1251ukr
- ujis sjis tis620; Default is latin1)],
+ [ --with-charset=CHARSET Use CHARSET by default (Default is latin1)],
[default_charset="$withval"],
[default_charset="$DEFAULT_CHARSET"])
@@ -1864,7 +1976,7 @@ elif test "$extra_charsets" = complex; then
CHARSETS=`echo $CHARSETS` # get rid of line breaks
else
if test "$extra_charsets" = all; then
- CHARSETS="$CHARSETS_AVAILABLE"
+ CHARSETS="$CHARSETS_AVAILABLE $CHARSETS_DEPRECATED"
else
CHARSETS=`echo $extra_charsets | sed -e 's/,/ /g'`
fi
@@ -1885,7 +1997,7 @@ CHARSETS=$TMP_CHARSETS
for cs in $CHARSETS
do
charset_okay=0
- for charset in $CHARSETS_AVAILABLE
+ for charset in $CHARSETS_AVAILABLE $CHARSETS_DEPRECATED
do
if test $cs = $charset; then charset_okay=1; fi
done
@@ -2065,9 +2177,9 @@ EOF
AC_MSG_RESULT([default: $default_charset; compiled in: $CHARSETS])
+MYSQL_CHECK_ISAM
MYSQL_CHECK_BDB
MYSQL_CHECK_INNODB
-MYSQL_CHECK_GEMINI
# If we have threads generate some library functions and test programs
sql_server_dirs=
@@ -2098,21 +2210,28 @@ AC_SUBST(linked_client_targets)
if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
then
AC_DEFINE(THREAD)
-fi
-
-if test "$with_server" = "yes"
-then
# Avoid _PROGRAMS names
THREAD_LPROGRAMS="test_thr_alarm test_thr_lock"
AC_SUBST(THREAD_LPROGRAMS)
THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o"
AC_SUBST(THREAD_LOBJECTS)
- sql_server_dirs="strings dbug mysys extra regex isam merge myisam myisammrg heap sql"
- server_scripts="safe_mysqld mysql_install_db"
+ server_scripts="mysqld_safe mysql_install_db"
+ sql_server_dirs="strings dbug mysys extra regex"
+
+
+ #
+ # Configuration for optional table handlers
+ #
+
+ if test X"$have_isam" != Xno
+ then
+ sql_server_dirs="$sql_server_dirs isam merge"
+ fi
+
if test X"$have_berkeley_db" != Xno; then
if test X"$have_berkeley_db" != Xyes; then
# we must build berkeley db from source
- sql_server_dirs="$have_berkeley_db $sql_server_dirs"
+ sql_server_dirs="$sql_server_dirs $have_berkeley_db"
echo "CONFIGURING FOR BERKELEY DB"
bdb_conf_flags=
@@ -2179,7 +2298,7 @@ EOF
if test X"$have_innodb" = Xyes
then
- sql_server_dirs="innobase $sql_server_dirs"
+ sql_server_dirs="$sql_server_dirs innobase"
echo "CONFIGURING FOR INNODB"
if test ! -d "innobase"; then
# This should only happen when doing a VPATH build
@@ -2196,21 +2315,11 @@ EOF
echo "END OF INNODB CONFIGURATION"
fi
+ #
+ # END of configuration for optional table handlers
+ #
+ sql_server_dirs="$sql_server_dirs myisam myisammrg heap vio sql"
- if test "X$have_gemini_db" = "Xyes"; then
- sql_server_dirs="gemini $sql_server_dirs"
- echo "CONFIGURING FOR GEMINI DB"
- (cd gemini && sh ./configure) \
- || AC_MSG_ERROR([could not configure Gemini DB])
-
- echo "END OF GEMINI DB CONFIGURATION"
-
- AC_DEFINE(HAVE_GEMINI_DB)
- fi
-fi
-
-if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
-then
if test "$with_posix_threads" = "no" -o "$with_mit_threads" = "yes"
then
# MIT user level threads
@@ -2258,17 +2367,21 @@ AC_SUBST(server_scripts)
# Some usefull subst
AC_SUBST(CC)
AC_SUBST(GXX)
+#Remove TOOLS_LIBS, because this is included in LIBRARIES
+#AC_SUBST(TOOLS_LIBS)
# Output results
AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \
strings/Makefile regex/Makefile heap/Makefile \
bdb/Makefile \
myisam/Makefile myisammrg/Makefile \
- man/Makefile os2/Makefile os2/include/Makefile os2/include/sys/Makefile \
- readline/Makefile libmysql_r/Makefile libmysql/Makefile client/Makefile \
- sql/Makefile sql/share/Makefile \
+ os2/Makefile os2/include/Makefile os2/include/sys/Makefile \
+ man/Makefile BUILD/Makefile readline/Makefile vio/Makefile \
+ libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile \
+ libmysql/Makefile client/Makefile os2/Makefile \
+ pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile \
merge/Makefile dbug/Makefile scripts/Makefile \
- include/Makefile sql-bench/Makefile \
+ include/Makefile sql-bench/Makefile tools/Makefile \
tests/Makefile Docs/Makefile support-files/Makefile \
mysql-test/Makefile \
include/mysql_version.h
@@ -2283,8 +2396,9 @@ echo "latest release, upcoming features, and other information to make your"
echo "work or play with MySQL more productive. There you can also find"
echo "information about mailing lists for MySQL discussion."
echo
-echo "Remember to check the platform specific part in the reference manual for"
-echo "hints about installing on your platfrom. See the Docs directory."
+echo "Remember to check the platform specific part of the reference manual for"
+echo "hints about installing MySQL on your platform. Also have a look at the"
+echo "files in the Docs directory."
echo
# The following text is checked in ./Do-compile to se that the configure ends.
echo "Thank you for choosing MySQL!"
diff --git a/dbug/dbug.c b/dbug/dbug.c
index cfe4ca161c6..3f6c9b2f980 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -21,7 +21,8 @@
* all copies and derivative works. Thank you. *
* *
* The author makes no warranty of any kind with respect to this *
- * product and explicitly disclaims any implied warranties of mer- *
+ * product and explicitly disclaims any implied warranties of mer- *ct_lex.table_list.first=0;
+ thd->lex.selec
* chantability or fitness for any particular purpose. *
* *
******************************************************************************
@@ -58,7 +59,7 @@
* seismo!bpa!sjuvax!bbanerje
*
* Michael Widenius:
- * DBUG_DUMP - To dump a pice of memory.
+ * DBUG_DUMP - To dump a block of memory.
* PUSH_FLAG "O" - To be used insted of "o" if we don't
* want flushing (for slow systems)
* PUSH_FLAG "A" - as 'O', but we will append to the out file instead
@@ -69,7 +70,7 @@
#ifdef DBUG_OFF
#undef DBUG_OFF
#endif
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <errno.h>
#if defined(MSDOS) || defined(__WIN__)
@@ -705,9 +706,16 @@ char ***_sframep_ __attribute__((unused)))
if (!_no_db_)
{
int save_errno=errno;
+ /*
+ Sasha: the test below is so we could call functions with DBUG_ENTER
+ before my_thread_init(). I needed this because I suspected corruption
+ of a block allocated by my_thread_init() itself, so I wanted to use
+ my_malloc()/my_free() in my_thread_init()/my_thread_end()
+ */
+ if (!(state=code_state()))
+ return;
if (!init_done)
_db_push_ (_DBUG_START_CONDITION_);
- state=code_state();
*_sfunc_ = state->func;
*_sfile_ = state->file;
@@ -787,10 +795,10 @@ uint *_slevel_)
if (!_no_db_)
{
int save_errno=errno;
+ if (!(state=code_state()))
+ return;
if (!init_done)
_db_push_ ("");
- if (!(state=code_state()))
- return; /* Only happens at end of program */
if (stack->flags & (TRACE_ON | DEBUG_ON | PROFILE_ON))
{
if (!state->locked)
@@ -855,6 +863,9 @@ uint _line_,
const char *keyword)
{
CODE_STATE *state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!state)
+ return;
state->u_line = _line_;
state->u_keyword = (char*) keyword;
}
@@ -890,7 +901,9 @@ void _db_doprnt_ (const char *format,...)
{
va_list args;
CODE_STATE *state;
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return;
va_start(args,format);
@@ -942,7 +955,9 @@ uint length)
int pos;
char dbuff[90];
CODE_STATE *state;
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return;
if (_db_keyword_ ((char*) keyword))
{
@@ -1224,7 +1239,9 @@ const char *keyword)
if (!init_done)
_db_push_ ("");
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return FALSE;
result = FALSE;
if (DEBUGGING &&
state->level <= stack -> maxdepth &&
@@ -1928,7 +1945,7 @@ static void dbug_flush(CODE_STATE *state)
{
if (!(freopen(stack->name,"a",_db_fp_)))
{
- (void) fprintf(stderr, ERR_OPEN, _db_process_);
+ (void) fprintf(stderr, ERR_OPEN, _db_process_, stack->name);
fflush(stderr);
_db_fp_ = stdout;
stack -> out_file = _db_fp_;
diff --git a/dbug/dbug_analyze.c b/dbug/dbug_analyze.c
index bcee5230527..de228c64aa5 100644
--- a/dbug/dbug_analyze.c
+++ b/dbug/dbug_analyze.c
@@ -49,7 +49,7 @@
* if invoked with -v flag.
*/
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
static char *my_name;
diff --git a/dbug/example1.c b/dbug/example1.c
index 932e269cc4c..e468f065796 100644
--- a/dbug/example1.c
+++ b/dbug/example1.c
@@ -1,5 +1,5 @@
-#include <global.h>
+#include <my_global.h>
main (argc, argv)
int argc;
diff --git a/dbug/example2.c b/dbug/example2.c
index 482691a8a74..5e5f14f0e7e 100644
--- a/dbug/example2.c
+++ b/dbug/example2.c
@@ -1,5 +1,5 @@
-#include <global.h>
+#include <my_global.h>
int debug = 0;
diff --git a/dbug/example3.c b/dbug/example3.c
index b504edf2e61..f177c07425d 100644
--- a/dbug/example3.c
+++ b/dbug/example3.c
@@ -1,5 +1,5 @@
-#include <global.h>
+#include <my_global.h>
main (argc, argv)
int argc;
diff --git a/dbug/factorial.c b/dbug/factorial.c
index 0dda5c7459e..56197aef29e 100644
--- a/dbug/factorial.c
+++ b/dbug/factorial.c
@@ -2,7 +2,7 @@
#undef DBUG_OFF
#endif
-#include <global.h>
+#include <my_global.h>
int factorial (
register int value)
diff --git a/dbug/main.c b/dbug/main.c
index 863b4d319c2..da56c00feb3 100644
--- a/dbug/main.c
+++ b/dbug/main.c
@@ -2,7 +2,7 @@
#undef DBUG_OFF
#endif
-#include <global.h> /* This includes dbug.h */
+#include <my_global.h> /* This includes dbug.h */
int main (argc, argv)
int argc;
diff --git a/dbug/sanity.c b/dbug/sanity.c
index d287a468028..df43fc14ba9 100644
--- a/dbug/sanity.c
+++ b/dbug/sanity.c
@@ -1,6 +1,6 @@
/* Declarate _sanity() if not declared in main program */
-#include <global.h>
+#include <my_global.h>
extern int _sanity(const char *file,uint line);
diff --git a/div/deadlock_test.c b/div/deadlock_test.c
index be6d940cf1b..65a0df5c215 100644
--- a/div/deadlock_test.c
+++ b/div/deadlock_test.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -126,7 +126,7 @@ static void permute_aux(int *order, int num_queries, int* fixed)
}
/*printf("num_free = %d\n", num_free); */
-
+
if(num_free <= 1)
{
count++;
@@ -156,7 +156,7 @@ static void run_query_batch(int* order, int num_queries)
dump_result(q->mysql, q->query);
}
printf("\n");
-
+
}
static void safe_net_read(NET* net, char* query)
@@ -167,8 +167,8 @@ static void safe_net_read(NET* net, char* query)
die("Error running query '%s'", query);
if(net->read_pos[0] == 255)
die("Error running query '%s'", query);
-}
-
+}
+
static void safe_query(MYSQL* mysql, char* query, int read_ok)
{
@@ -230,7 +230,7 @@ int main()
permute(order, num_queries);
printf("count = %d\n", count);
-
+
mysql_close(&lock);
mysql_close(&sel);
mysql_close(&del_ins);
diff --git a/extra/Makefile.am b/extra/Makefile.am
index ee6c2ba92f2..25633a386e2 100644
--- a/extra/Makefile.am
+++ b/extra/Makefile.am
@@ -18,7 +18,7 @@ INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include -I..
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
../dbug/libdbug.a ../strings/libmystrings.a
bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \
-resolve_stack_dump
+resolve_stack_dump mysql_install
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
__math.h time.h __time.h unistd.h __unistd.h types.h \
diff --git a/extra/comp_err.c b/extra/comp_err.c
index f7b68ff0891..806fb5052b4 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Saves all errmesg in a header file, updated by me, in a compact file */
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c
index 316d91ef7b3..c0f8a54f432 100644
--- a/extra/my_print_defaults.c
+++ b/extra/my_print_defaults.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** print_default.c:
@@ -22,73 +21,79 @@
** Written by Monty
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
-#include <getopt.h>
+#include <my_getopt.h>
const char *config_file="my"; /* Default config file */
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"config-file", required_argument, 0, 'c'},
- {"defaults-file", required_argument, 0, 'c'},
- {"defaults-extra-file", required_argument, 0, 'e'},
- {"extra-file", required_argument, 0, 'e'},
- {"no-defaults", no_argument, 0, 'n'},
- {"help", no_argument, 0, '?'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"config-file", 'c', "The config file to be used",
+ (gptr*) &config_file, (gptr*) &config_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"defaults-file", 'c', "Synonym for --config-file",
+ (gptr*) &config_file, (gptr*) &config_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"defaults-extra-file", 'e',
+ "Read this file after the global /etc config file and before the config file in the users home directory.",
+ (gptr*) &defaults_extra_file, (gptr*) &defaults_extra_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"extra-file", 'e',
+ "Synonym for --defaults-extra-file",
+ (gptr*) &defaults_extra_file, (gptr*) &defaults_extra_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-defaults", 'n', "Return an empty string (useful for scripts)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help message and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void usage(my_bool version)
{
- printf("%s Ver 1.3 for %s at %s\n",my_progname,SYSTEM_TYPE,
+ printf("%s Ver 1.5 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
if (version)
return;
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Prints all arguments that is give to some program using the default files");
- printf("Usage: %s [OPTIONS] groups\n",my_progname);
- printf("\n\
- -c, --config-file=#, --defaults-file=#\n\
- The config file to use (default '%s')\n\
- -e, --extra-file=#, --defaults-extra-file=#\n\
- Read this file after the global /etc config file and\n\
- before the config file in the users home directory.\n\
- -n, --no-defaults Return an empty string (useful for scripts)\n\
- -?, --help Display this help message and exit.\n\
- -V, --version Output version information and exit.\n",
- config_file);
- printf("\nExample usage: %s --config-file=my client mysql\n",my_progname);
+ printf("Usage: %s [OPTIONS] groups\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+ printf("\nExample usage:\n%s --config-file=my client mysql\n", my_progname);
}
-static int get_options(int *argc,char ***argv)
-{
- int c,option_index;
- while ((c=getopt_long(*argc,*argv,"nc:e:V?I",
- long_options, &option_index)) != EOF)
- {
- switch (c) {
- case 'c':
- config_file=optarg;
- break;
- case 'e':
- defaults_extra_file=optarg; /* Used by the load_defaults */
- break;
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
case 'n':
- exit(0);
+ exit(0);
case 'I':
case '?':
- usage(0);
- exit(0);
+ usage(0);
+ exit(0);
case 'V':
- usage(1);
- exit(0);
- }
+ usage(1);
+ exit(0);
}
- (*argc)-=optind;
- (*argv)+=optind;
+ return 0;
+}
+
+
+static int get_options(int *argc,char ***argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (*argc < 1)
{
usage(0);
diff --git a/extra/mysql_install.c b/extra/mysql_install.c
index dfd71895647..e2783f906b9 100644
--- a/extra/mysql_install.c
+++ b/extra/mysql_install.c
@@ -18,24 +18,212 @@
/* Install or upgrade MySQL server. By Sasha Pachev <sasha@mysql.com>
*/
-#define INSTALL_VERSION "1.0"
+#define INSTALL_VERSION "1.2"
#define DONT_USE_RAID
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql_version.h>
#include <errno.h>
-#include <getopt.h>
+#include <my_getopt.h>
-struct option long_options[] =
+#define ANSWERS_CHUNCK 32
+
+int have_gui=0;
+
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'V'},
- {0, 0,0,0}
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+/* For now, not much exciting here, but we'll add more once
+ we add GUI support
+ */
+typedef struct
+{
+ FILE* out;
+ FILE* in;
+ const char* question;
+ int default_ind;
+ DYNAMIC_ARRAY answers;
+} QUESTION_WIDGET;
+
+static void usage();
+static void die(const char* fmt, ...);
+static void print_version(void);
+static char get_answer_char(int ans_ind);
+static int ask_user(const char* question,int default_ind, ...);
+static void add_answer(QUESTION_WIDGET* w, const char* ans);
+static void display_question(QUESTION_WIDGET* w);
+static int init_question_widget(QUESTION_WIDGET* w, const char* question,
+ int default_ind);
+static void end_question_widget(QUESTION_WIDGET* w);
+static int get_answer(QUESTION_WIDGET* w);
+static char answer_from_char(char c);
+static void invalid_answer(QUESTION_WIDGET* w);
+
+enum {IMODE_STANDARD=0,IMODE_CUSTOM,IMODE_UPGRAGE} install_mode
+ = IMODE_STANDARD;
+
+static char get_answer_char(int ans_ind)
+{
+ return 'a' + ans_ind;
+}
+
+static void invalid_answer(QUESTION_WIDGET* w)
+{
+ if (!have_gui)
+ {
+ fprintf(w->out, "ERROR: invalid answer, try again...\a\n");
+ }
+}
+
+static char answer_from_char(char c)
+{
+ return c - 'a';
+}
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "%s: ", my_progname);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ exit(1);
+}
+
+static void display_question(QUESTION_WIDGET* w)
+{
+ if (!have_gui)
+ {
+ uint i,num_answers=w->answers.elements;
+ DYNAMIC_ARRAY* answers = &w->answers;
+ fprintf(w->out,"\n%s\n\n",w->question);
+
+ for (i=0; i<num_answers; i++)
+ {
+ char* ans;
+ get_dynamic(answers,(gptr)&ans,i);
+ fprintf(w->out,"%c - %s\n",get_answer_char(i),ans);
+ }
+ fprintf(w->out,"q - Abort Install/Upgrade\n\n");
+ }
+}
+
+static void add_answer(QUESTION_WIDGET* w, const char* ans)
+{
+ insert_dynamic(&w->answers,(gptr)&ans);
+}
+
+static int init_question_widget(QUESTION_WIDGET* w, const char* question,
+ int default_ind)
+{
+ if (have_gui)
+ {
+ w->in = w->out = 0;
+ }
+ else
+ {
+ w->out = stdout;
+ w->in = stdin;
+ }
+ w->question = question;
+ w->default_ind = default_ind;
+ if (my_init_dynamic_array(&w->answers,sizeof(char*),
+ ANSWERS_CHUNCK,ANSWERS_CHUNCK))
+ die("Out of memory");
+ return 0;
+}
+
+static void end_question_widget(QUESTION_WIDGET* w)
+{
+ delete_dynamic(&w->answers);
+}
+
+static int get_answer(QUESTION_WIDGET* w)
+{
+ if (!have_gui)
+ {
+ char buf[32];
+ int ind;
+ char c;
+ if (!fgets(buf,sizeof(buf),w->in))
+ die("Failed fgets on input stream");
+ switch ((c=tolower(*buf)))
+ {
+ case '\n':
+ return w->default_ind;
+ case 'q':
+ die("Install/Upgrade aborted");
+ default:
+ ind = answer_from_char(c);
+ if (ind >= 0 && ind < (int)w->answers.elements)
+ return ind;
+ }
+ }
+ return -1;
+}
+
+static int ask_user(const char* question,int default_ind, ...)
+{
+ va_list args;
+ char* opt;
+ QUESTION_WIDGET w;
+ int ans;
+
+ va_start(args,default_ind);
+ init_question_widget(&w,question,default_ind);
+ for (;(opt=va_arg(args,char*));)
+ {
+ add_answer(&w,opt);
+ }
+ for (;;)
+ {
+ display_question(&w);
+ if ((ans = get_answer(&w)) >= 0)
+ break;
+ invalid_answer(&w);
+ }
+ end_question_widget(&w);
+ va_end(args);
+ return ans;
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch(optid) {
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+
+static int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,INSTALL_VERSION,
@@ -49,12 +237,20 @@ static void usage()
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Install or upgrade MySQL server.\n\n");
printf("Usage: %s [OPTIONS] \n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n\
- -h, --host=... Connect to host.\n\
- -V, --version Output version information and exit.\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
}
+int main(int argc, char** argv)
+{
+ MY_INIT(argv[0]);
+ parse_args(argc,argv);
+ install_mode = ask_user("Please select install/upgrade mode",
+ install_mode, "Standard Install",
+ "Custom Install", "Upgrade",0);
+ printf("mode=%d\n", install_mode);
+ return 0;
+}
diff --git a/extra/perror.c b/extra/perror.c
index 6cb86eedf27..4d05adf29aa 100644
--- a/extra/perror.c
+++ b/extra/perror.c
@@ -1,48 +1,57 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Return error-text for system error messages and nisam messages */
-#define PERROR_VERSION "2.7"
+#define PERROR_VERSION "2.9"
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <errno.h>
-#include <getopt.h>
+#include <my_getopt.h>
+static my_bool verbose, print_all_codes;
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, '?'},
- {"info", no_argument, 0, 'I'},
- {"all", no_argument, 0, 'a'},
- {"silent", no_argument, 0, 's'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"info", 'I', "Synonym for --help", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SYS_ERRLIST
+ {"all", 'a', "Print all the error messages and the number.",
+ (gptr*) &print_all_codes, (gptr*) &print_all_codes, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+ {"silent", 's', "Only print the error message", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Print error code and message (default).", (gptr*) &verbose,
+ (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"version", 'V', "Displays version information and exits.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
typedef struct ha_errors {
int errcode;
const char *msg;
} HA_ERRORS;
-static int verbose=1,print_all_codes=0;
static HA_ERRORS ha_errlist[]=
{
@@ -100,57 +109,40 @@ static void usage(void)
printf("Print a description for a system error code or a error code from\na MyISAM/ISAM/BDB table handler.\n");
printf("If you want to get the error for a negative error code, you should use\n-- before the first error code to tell perror that there was no more options.\n\n");
printf("Usage: %s [OPTIONS] [ERRORCODE [ERRORCODE...]]\n",my_progname);
- printf("\n\
- -?, --help Displays this help and exits.\n\
- -I, --info Synonym for the above.");
-#ifdef HAVE_SYS_ERRLIST
- printf("\n\
- -a, --all Print all the error messages and the number.");
-#endif
- printf("\n\
- -s, --silent Only print the error message\n\
- -v, --verbose Print error code and message (default).\n\
- -V, --version Displays version information and exits.\n");
-}
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case 's':
+ verbose=0;
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ break;
+ }
+ return 0;
+}
static int get_options(int *argc,char ***argv)
{
- int c,option_index;
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
- while ((c=getopt_long(*argc,*argv,"asvVI?",long_options,
- &option_index)) != EOF)
- {
- switch (c) {
-#ifdef HAVE_SYS_ERRLIST
- case 'a':
- print_all_codes=1;
- break;
-#endif
- case 'v':
- verbose=1;
- break;
- case 's':
- verbose=0;
- break;
- case 'V':
- print_version();
- exit(0);
- break;
- case 'I':
- case '?':
- usage();
- exit(0);
- break;
- default:
- fprintf(stderr,"%s: Illegal option character '%c'\n",
- my_progname,opterr);
- return(1);
- break;
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
if (!*argc && !print_all_codes)
{
usage();
@@ -231,4 +223,3 @@ int main(int argc,char *argv[])
exit(error);
return error;
}
-
diff --git a/extra/replace.c b/extra/replace.c
index ef3abda5cc5..41312f5e3d4 100644
--- a/extra/replace.c
+++ b/extra/replace.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Replace strings in textfile
This program replace strings in a file or on stdin/stdout.
@@ -38,7 +37,7 @@
*/
#define DONT_USE_RAID
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c
index a08845b8de3..c54f17a186e 100644
--- a/extra/resolve_stack_dump.c
+++ b/extra/resolve_stack_dump.c
@@ -1,37 +1,36 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Resolve numeric stack dump produced by mysqld 3.23.30 and later
versions into symbolic names. By Sasha Pachev <sasha@mysql.com>
*/
#define DONT_USE_RAID
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql_version.h>
#include <errno.h>
-#include <getopt.h>
+#include <my_getopt.h>
#define INIT_SYM_TABLE 4096
#define INC_SYM_TABLE 4096
#define MAX_SYM_SIZE 128
-#define DUMP_VERSION "1.2"
+#define DUMP_VERSION "1.4"
#define HEX_INVALID (uchar)255
typedef ulong my_long_addr_t ; /* at some point, we need to fix configure
@@ -49,15 +48,21 @@ static char* dump_fname = 0, *sym_fname = 0;
static DYNAMIC_ARRAY sym_table; /* how do you like this , static DYNAMIC ? */
static FILE* fp_dump, *fp_sym = 0, *fp_out;
-struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'V'},
- {"symbols-file", required_argument, 0, 's'},
- {"numeric-dump-file", required_argument, 0, 'n'},
- {0, 0,0,0}
+ {"help", 'h', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"symbols-file", 's', "Use specified symbols file.", (gptr*) &sym_fname,
+ (gptr*) &sym_fname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"numeric-dump-file", 'n', "Read the dump from specified file.",
+ (gptr*) &dump_fname, (gptr*) &dump_fname, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void verify_sort();
static void print_version(void)
@@ -72,12 +77,10 @@ static void usage()
printf("MySQL AB, by Sasha Pachev\n");
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Resolve numeric stack strace dump into symbols.\n\n");
- printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n\
- -s, --symbols-file=... Use specified symbols file.\n\
- -n, --numeric-dump-file=... Read the dump from specified file.\n\
- -V, --version Output version information and exit.\n");
+ printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n",
+ my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
printf("\n\
The symbols-file should include the output from: 'nm --numeric-sort mysqld'.\n\
The numeric-dump-file should contain a numeric stack trace from mysqld.\n\
@@ -98,40 +101,33 @@ static void die(const char* fmt, ...)
}
-static int parse_args(int argc, char **argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
{
- int c, option_index = 0;
+ switch(optid) {
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
- while((c = getopt_long(argc, argv, "?Vn:s:",
- long_options, &option_index)) != EOF)
- {
- switch(c)
- {
- case 'n':
- dump_fname = optarg;
- break;
- case 's':
- sym_fname = optarg;
- break;
- case 'V':
- print_version();
- exit(0);
- case '?':
- usage();
- exit(0);
- default:
- usage();
- exit(1);
- }
- }
- argc-=optind;
- argv+=optind;
+static int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
/*
The following code is to make the command compatible with the old
version that required one to use the -n and -s options
- */
+ */
if (argc == 2)
{
@@ -163,26 +159,26 @@ static void open_files()
{
fp_out = stdout;
fp_dump = stdin;
-
- if(dump_fname && !(fp_dump = my_fopen(dump_fname, O_RDONLY, MYF(MY_WME))))
+
+ if (dump_fname && !(fp_dump = my_fopen(dump_fname, O_RDONLY, MYF(MY_WME))))
die("Could not open %s", dump_fname);
/* if name not given, assume stdin*/
- if(!sym_fname)
+ if (!sym_fname)
die("Please run nm --numeric-sort on mysqld binary that produced stack \
trace dump and specify the path to it with -s or --symbols-file");
- if(!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME))))
+ if (!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME))))
die("Could not open %s", sym_fname);
-
+
}
static uchar hex_val(char c)
{
uchar l;
- if(isdigit(c))
+ if (isdigit(c))
return c - '0';
l = tolower(c);
- if(l < 'a' || l > 'f')
+ if (l < 'a' || l > 'f')
return HEX_INVALID;
return (uchar)10 + ((uchar)c - (uchar)'a');
}
@@ -192,10 +188,10 @@ static my_long_addr_t read_addr(char** buf)
uchar c;
char* p = *buf;
my_long_addr_t addr = 0;
-
+
while((c = hex_val(*p++)) != HEX_INVALID)
addr = (addr << 4) + c;
-
+
*buf = p;
return addr;
}
@@ -205,25 +201,18 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
char* p, *p_end;
se->addr = (uchar*)read_addr(&buf);
- if(!se->addr)
+ if (!se->addr)
return -1;
- while(isspace(*buf++))
- /* empty */;
-
- while(isspace(*buf++))
- /* empty - skip more space */;
+ while (isspace(*buf++)) ;
+
+ while (isspace(*buf++)) ; /* skip more space */
--buf;
/* now we are on the symbol */
- for(p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
- *buf != '\n' && *buf; ++buf,++p )
- {
- if(p < p_end)
- *p = *buf;
- else
- break;
- }
+ for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
+ *buf != '\n' && *buf && p < p_end; ++buf,++p)
+ *p = *buf;
*p = 0;
- if(!strcmp(se->symbol, "gcc2_compiled."))
+ if (!strcmp(se->symbol, "gcc2_compiled."))
return -1;
return 0;
}
@@ -231,18 +220,18 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
static void init_sym_table()
{
char buf[512];
- if(my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
- INC_SYM_TABLE))
+ if (my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
+ INC_SYM_TABLE))
die("Failed in my_init_dynamic_array() -- looks like out of memory problem");
- while(fgets(buf, sizeof(buf), fp_sym))
- {
- SYM_ENTRY se;
- if(init_sym_entry(&se, buf))
- continue;
- if(insert_dynamic(&sym_table, (gptr)&se))
- die("insert_dynamic() failed - looks like we are out of memory");
- }
+ while (fgets(buf, sizeof(buf), fp_sym))
+ {
+ SYM_ENTRY se;
+ if (init_sym_entry(&se, buf))
+ continue;
+ if (insert_dynamic(&sym_table, (gptr)&se))
+ die("insert_dynamic() failed - looks like we are out of memory");
+ }
verify_sort();
}
@@ -256,67 +245,69 @@ static void verify_sort()
{
uint i;
uchar* last = 0;
-
- for(i = 0; i < sym_table.elements; i++)
- {
- SYM_ENTRY se;
- get_dynamic(&sym_table, (gptr)&se, i);
- if(se.addr < last)
- die("sym table does not appear to be sorted, did you forget \
+
+ for (i = 0; i < sym_table.elements; i++)
+ {
+ SYM_ENTRY se;
+ get_dynamic(&sym_table, (gptr)&se, i);
+ if (se.addr < last)
+ die("sym table does not appear to be sorted, did you forget \
--numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last);
- last = se.addr;
- }
+ last = se.addr;
+ }
}
+
static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
{
uint i;
get_dynamic(&sym_table, (gptr)se, 0);
- if(addr < se->addr)
+ if (addr < se->addr)
return 0;
-
- for(i = 1; i < sym_table.elements; i++)
+
+ for (i = 1; i < sym_table.elements; i++)
+ {
+ get_dynamic(&sym_table, (gptr)se, i);
+ if (addr < se->addr)
{
- get_dynamic(&sym_table, (gptr)se, i);
- if(addr < se->addr)
- {
- get_dynamic(&sym_table, (gptr)se, i - 1);
- return se;
- }
+ get_dynamic(&sym_table, (gptr)se, i - 1);
+ return se;
}
+ }
return se;
}
+
static void do_resolve()
{
char buf[1024], *p;
- while(fgets(buf, sizeof(buf), fp_dump))
+ while (fgets(buf, sizeof(buf), fp_dump))
+ {
+ p = buf;
+ while(isspace(*p))
+ ++p;
+
+ if (*p++ == '0' && *p++ == 'x')
{
- p = buf;
- while(isspace(*p))
- ++p;
- /* skip space */;
-
- if(*p++ == '0' && *p++ == 'x')
- {
- SYM_ENTRY se ;
- uchar* addr = (uchar*)read_addr(&p);
- if(resolve_addr(addr, &se))
- fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
- (int) (addr - se.addr));
- else
- fprintf(fp_out, "%p (?)\n", addr);
-
- }
+ SYM_ENTRY se ;
+ uchar* addr = (uchar*)read_addr(&p);
+ if (resolve_addr(addr, &se))
+ fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
+ (int) (addr - se.addr));
else
- {
- fputs(buf, fp_out);
- continue;
- }
+ fprintf(fp_out, "%p (?)\n", addr);
+
}
+ else
+ {
+ fputs(buf, fp_out);
+ continue;
+ }
+ }
}
+
int main(int argc, char** argv)
{
MY_INIT(argv[0]);
@@ -327,4 +318,3 @@ int main(int argc, char** argv)
clean_up();
return 0;
}
-
diff --git a/extra/resolveip.c b/extra/resolveip.c
index ba2db0a4d65..e380d920e9f 100644
--- a/extra/resolveip.c
+++ b/extra/resolveip.c
@@ -16,7 +16,7 @@
/* Resolves IP's to hostname and hostnames to IP's */
-#define RESOLVE_VERSION "2.0"
+#define RESOLVE_VERSION "2.2"
#include <my_global.h>
#include <m_ctype.h>
@@ -30,22 +30,26 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <my_net.h>
-#include <getopt.h>
+#include <my_getopt.h>
#if !defined(_AIX) && !defined(HAVE_UNIXWARE7_THREADS) && !defined(HAVE_UNIXWARE7_POSIX) && !defined(h_errno)
extern int h_errno;
#endif
-static int silent=0;
+static my_bool silent;
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, '?'},
- {"info", no_argument, 0, 'I'},
- {"silent", no_argument, 0, 's'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"help", '?', "Displays this help and exits.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"info", 'I', "Synonym for --help",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.", (gptr*) &silent, (gptr*) &silent,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Displays version information and exits.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -62,41 +66,36 @@ static void usage(void)
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Get hostname based on IP-address or IP-address based on hostname.\n");
printf("Usage: %s [OPTIONS] hostname or IP-address\n",my_progname);
- printf("\n\
- -?, --help Displays this help and exits.\n\
- -I, --info Synonym for the above.\n\
- -s, --silent Be more silent.\n\
- -V, --version Displays version information and exits.\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case 'V': print_version(); exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
}
/*static my_string load_default_groups[]= { "resolveip","client",0 }; */
static int get_options(int *argc,char ***argv)
{
- int c,option_index;
+ int ho_error;
/* load_defaults("my",load_default_groups,argc,argv); */
- while ((c=getopt_long(*argc,*argv,"?IsV",
- long_options, &option_index)) != EOF)
- {
- switch (c) {
- case 's':
- silent=1;
- break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- default:
- fprintf(stderr,"%s: Illegal option character '%c'\n",
- my_progname,opterr);
- return(1);
- break;
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (*argc == 0)
{
usage();
diff --git a/fs/CorbaFS.idl b/fs/CorbaFS.idl
new file mode 100644
index 00000000000..8fe089bd13c
--- /dev/null
+++ b/fs/CorbaFS.idl
@@ -0,0 +1,38 @@
+// -----------------------------------------------------------------------------
+// CorbaDS Module - Implement Kernel functionality in korbit
+// -----------------------------------------------------------------------------
+//
+// Main source of information:
+// http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html
+//
+module CorbaFS {
+
+ struct dirent
+ {
+ long inode; // inode number
+ string name; // file name (null-terminated)
+ };
+
+ typedef sequence<dirent> DirEntSeq;
+ typedef sequence<octet> Buffer;
+
+ interface Inode {
+ void getStatus(out unsigned short mode, out unsigned long uid, out unsigned long gid,
+ out unsigned long size, out unsigned long inodeNum, out unsigned short numLinks,
+ out long atime, out long mtime, out long ctime);
+ void readpage(out Buffer buffer, in long size, in long offset);
+ void release();
+ };
+
+ interface FileSystem {
+ Inode getInode(in string path);
+
+ // DirectoryInode getStatus implementation must have S_IFDIR in the S_IFMT
+ // field of the mode value.
+ DirEntSeq readdir(in string path);
+
+ // SymlinkInode getStatus implementation must have S_IFLNK in the S_IFMT
+ // field of the mode value.
+ string readlink(in string filename);
+ };
+};
diff --git a/fs/Makefile.am b/fs/Makefile.am
new file mode 100644
index 00000000000..33d1acd913d
--- /dev/null
+++ b/fs/Makefile.am
@@ -0,0 +1,93 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#called from the top level Makefile
+
+CFLAGS = $(ORBIT_CFLAGS) -g
+LFLAGS = $(ORBIT_LIBS)
+orbit_idl = @orbit_idl@
+orbit_includes = @orbit_includes@
+orbit_libs = @orbit_libs@
+
+DISTCLEANFILES = CorbaFS-common.* CorbaFS-stubs.* CorbaFS-skels.* CorbaFS.h
+
+MYSQLDATAdir = $(localstatedir)
+MYSQLSHAREdir = $(pkgdatadir)
+MYSQLBASEdir= $(prefix)
+INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include \
+ -I$(srcdir)/../regex \
+ -I$(srcdir) -I../include -I.. -I. \
+ -I$(srcdir) -I../include -I.. -I. \
+ $(orbit_includes)
+WRAPLIBS= @WRAPLIBS@
+libexec_PROGRAMS = mysqlcorbafsd
+noinst_PROGRAMS =mysqlfs_test
+LDADD = ../libmysql/libmysqlclient.la $(orbit_libs)
+mysqlcorbafsd_LDADD = $(LDADD) $(CXXLDFLAGS)
+noinst_HEADERS =
+mysqlfs_test_SOURCES = mysqlcorbafs_test.c CorbaFS-common.c CorbaFS-stubs.c libmysqlfs.c
+mysqlcorbafsd_SOURCES = mysqlcorbafs.c CorbaFS-skels.c database.c CorbaFS-common.c libmysqlfs.c
+
+DEFS = -DMYSQL_SERVER \
+ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+ -DDATADIR="\"$(MYSQLDATAdir)\"" \
+ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+ @DEFS@
+# Don't put lex_hash.h in BUILT_SOURCES as this will give infinite recursion
+BUILT_SOURCES = CorbaFS-common.c CorbaFS-stubs.c CorbaFS-skels.c CorbaFS.h
+EXTRA_DIST = $(BUILT_SOURCES)
+#YFLAGS = -d
+
+OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
+ __math.h time.h __time.h unistd.h __unistd.h types.h \
+ xtypes.h ac-types.h posix.h string.h __string.h \
+ errno.h socket.h inet.h dirent.h netdb.h \
+ cleanup.h cond.h debug_out.h fd.h kernel.h mutex.h \
+ prio_queue.h pthread_attr.h pthread_once.h queue.h\
+ sleep.h specific.h version.h pwd.h timers.h uio.h \
+ cdefs.h machdep.h signal.h __signal.h util.h lex.h \
+ wait.h
+
+link_sources:
+ rm -f mini_client_errors.c
+ @LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
+
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
+
+idltargets : CorbaFS.idl
+ $(ORBIT_IDL) CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+# individual rules
+
+CorbaFS-stubs.c : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+CorbaFS-common.c : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+CorbaFS-skels.c : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+#CorbaFS-client.c : CorbaFS.h
+
+#CorbaFS-server.c : CorbaFS.h
+
+CorbaFS.h : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
diff --git a/fs/README b/fs/README
new file mode 100644
index 00000000000..5d86da3a7e4
--- /dev/null
+++ b/fs/README
@@ -0,0 +1,58 @@
+MySQL Filesystem
+Tõnu Samuel - tonu@mysql.com
+Some additional information is available on http://no.spam.ee/~tonu/mysqlfs.html
+
+WARNING: Experimental code and known to crash computer.
+
+Instructions, how to get this stuff working:
+1. Make sure you have ORBit, includeing development libraries installed. They should be version 0.5.3 or later.
+- I am lazy man and use default ones included with my RedHat:
+ [root@localhost /root]# rpm -qa | grep ORBit
+ ORBit-0.5.3-2
+ ORBit-devel-0.5.3-2
+ [root@localhost /root]#
+
+2. Prepare kernel to include korbit:
+- Get Linux 2.4.1 kernel source. (very possibly this patch works on 2.4.0 without modifications too)
+- unpack it
+- apply patch named "korbit-kernel-2.4.1-patch" on it.
+- make menuconfig
+- In section "Networking options":
+ ...
+ [*] Kernel ORB (EXPERIMENTAL)
+ ...
+ <M> CORBA User-space FileSystem (EXPERIMENTAL)
+ ...
+- make dep ; make bzlilo ; make modules ; make modules_install
+- reboot
+- Execute: insmod /lib/modules/$(uname -r)/kernel/net/korbit/modules/CorbaFS/client/corba-corbafs-client.o
+ You should see "gethostname() = localhost". Look at known bug 3 in the end of this doc.
+
+3. Make sure MySQL server is working on your system
+- On my RedHat 7.0 I execute "/etc/init.d/mysqld start"
+
+4. Prepare MySQL FS daemon
+- Get MySQL 4.0 from repository OR get MySQL FS source from http://no.spam.ee/~tonu/mysqlfs.html
+- unpack it. In MySQL 4.0 source this is located in directory named "fs". cd into it.
+- make
+- Execute command "./RunServer"
+
+5. mount MySQL server to disk tree
+- Execute command "mkdir /mnt/mysql"
+- Execute command "mount -t corbafs -o `cat /tmp/mysqlcorbafs.ior` none /mnt/mysql/"
+- Check you SQL server content by executing "ls -la /mnt/mysql/"
+
+Known bugs:
+
+1. User bugs. fix user ;)
+
+2. MySQL FS daemon will crash or will be stopped when cobrafs is mounted, then there is no way
+to unmount disks anymore. This is korbit business to handle such cases and I had no time to dig
+into korbit code.
+
+3. host name returned by gethostname() should be "localhost" or korbit will crash. Also "localhost"
+must be first string after 127.0.0.1 in /etc/hosts
+
+
+
+
diff --git a/fs/RunServer.sh b/fs/RunServer.sh
new file mode 100755
index 00000000000..22d152bb20b
--- /dev/null
+++ b/fs/RunServer.sh
@@ -0,0 +1,2 @@
+.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 --debug='d:t:o,~/mysqlfsd.trace' $*
+#.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 $*
diff --git a/fs/database.c b/fs/database.c
new file mode 100644
index 00000000000..0ff12e433ee
--- /dev/null
+++ b/fs/database.c
@@ -0,0 +1,628 @@
+/* Copyright (C) 2000 db AB & db Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Database functions
+ *
+ * Using these functions we emulate filesystem behaviour on top of SQL
+ * database.
+ * Written by Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
+ *
+ * FIXME:
+ * - Direct handling of database handlers without SQL parsing overhead
+ * - connection pool
+ * - configurable function name/file name mappings
+ */
+
+
+#include "libmysqlfs.h"
+#include "mysqlcorbafs.h"
+#include <unistd.h>
+#include <string.h>
+#include <my_sys.h>
+
+DYNAMIC_ARRAY field_array;
+
+/*
+ * ** dbConnect -- connects to the host and selects DB.
+ * ** Also checks whether the tablename is a valid table name.
+ * */
+int db_connect(char *host, char *user,char *passwd)
+{
+ DBUG_ENTER("db_connect");
+ DBUG_PRINT("enter",("host: '%s', user: '%s', passwd: '%s'", host, user, passwd));
+
+ if (verbose)
+ {
+ fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
+ }
+ mysql_init(&connection);
+ if (opt_compress)
+ mysql_options(&connection,MYSQL_OPT_COMPRESS,NullS);
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ mysql_ssl_set(&connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath);
+#endif
+ if (!(sock= mysql_real_connect(&connection,host,user,passwd,
+ NULL,opt_mysql_port,opt_mysql_unix_port,0)))
+ {
+ DBerror(&connection, "when trying to connect");
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+} /* dbConnect */
+
+
+/*
+ * ** dbDisconnect -- disconnects from the host.
+ * */
+void db_disconnect(char *host)
+{
+ DBUG_ENTER("db_disconnect");
+ DBUG_PRINT("enter",("host: '%s'", host));
+ if (verbose)
+ fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
+ mysql_close(sock);
+ DBUG_VOID_RETURN;
+} /* dbDisconnect */
+
+#define OUTPUT(x) strcpy(buffptr,x); buffptr+=strlen(x);
+#define OUTPUT_TOP(x) strcpy(topptr,x); topptr+=strlen(x);
+#define OUTPUT_MIDDLE(x) strcpy(midptr,x); midptr+=strlen(x);
+#define OUTPUT_BOTTOM(x) strcpy(botptr,x); botptr+=strlen(x);
+#define OUTPUT_HEADER(x) strcpy(hdrptr,x); hdrptr+=strlen(x);
+
+void db_show_result(MYSQL* sock, char *b, struct format *f)
+{
+ MYSQL_ROW row;
+ MYSQL_RES *result;
+ MYSQL_FIELD *field;
+ char *buffptr;
+ char topseparator[BUFLEN]="";
+ char middleseparator[BUFLEN]="";
+ char bottomseparator[BUFLEN]="";
+ char header[BUFLEN]="";
+ char *topptr=topseparator;
+ char *midptr=middleseparator;
+ char *botptr=bottomseparator;
+ char *hdrptr=header;
+ uint i,count, length;
+
+ DBUG_ENTER("db_show_result");
+ DBUG_PRINT("enter",("b: '%s', f '%x'", b, f));
+
+ result=mysql_store_result(sock);
+
+ buffptr=b;
+ OUTPUT(f->tablestart)
+
+ OUTPUT_TOP(f->leftuppercorner);
+ OUTPUT_MIDDLE(f->leftcross);
+ OUTPUT_BOTTOM(f->leftdowncorner);
+ OUTPUT_HEADER(f->headerrowstart);
+
+
+ count=mysql_num_fields(result);
+// while ((field = mysql_fetch_field(result)))
+ for(i=0 ; i < count ; ++i)
+ {
+ field = mysql_fetch_field(result);
+ length=(uint) strlen(field->name);
+ OUTPUT_HEADER(f->headercellstart);
+
+ length=max(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+
+ memset(topptr,'=',field->max_length);
+ memset(midptr,'-',field->max_length);
+ memset(botptr,'=',field->max_length);
+
+ sprintf(hdrptr,"%-*s",field->max_length,field->name);
+ //num_flag[off]= IS_NUM(field->type);
+
+ topptr+=field->max_length;
+ midptr+=field->max_length;
+ botptr+=field->max_length;
+ hdrptr+=field->max_length;
+
+ if(i<count-1) {
+ OUTPUT_TOP(f->topcross);
+ OUTPUT_MIDDLE(f->middlecross);
+ OUTPUT_BOTTOM(f->bottomcross);
+ OUTPUT_HEADER(f->headercellseparator);
+ }
+ }
+ OUTPUT_TOP(f->rightuppercorner);
+ OUTPUT_MIDDLE(f->rightcross);
+ OUTPUT_BOTTOM(f->rightdowncorner);
+
+ OUTPUT_HEADER(f->headercellend);
+ OUTPUT_HEADER(f->headerrowend);
+
+ OUTPUT(topseparator);
+ OUTPUT(header);
+ OUTPUT(middleseparator);
+ while(row=mysql_fetch_row(result)) {
+ mysql_field_seek(result,0);
+
+ OUTPUT(f->contentrowstart);
+ for(i=0 ; i < mysql_field_count(sock); ++i) {
+ field = mysql_fetch_field(result);
+ OUTPUT(f->contentcellstart);
+ sprintf(buffptr,"%-*s",field->max_length,row[i]);
+ buffptr+=field->max_length;
+
+ if(i==mysql_field_count(sock))
+ {
+ OUTPUT(f->contentcellend);
+ } else {
+ OUTPUT(f->contentcellseparator);
+ }
+ }
+ OUTPUT(f->contentrowend);
+ }
+ OUTPUT(bottomseparator);
+ OUTPUT(f->tableend);
+
+ mysql_free_result(result);
+ DBUG_VOID_RETURN;
+}
+
+
+int db_function(char *b,const char *server, const char *database,const char *table,const char *field, const char *value, const char* path, struct func_st *function)
+{
+ char buff[BUFLEN];
+ int i;
+ DBUG_ENTER("db_function");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s', field: '%s', path: '%s'", b, database, table, field,path));
+
+ if(*database) {
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ }
+
+ sprintf(buff,"%s",function->function);
+ search_and_replace("$database",database,buff);
+ search_and_replace("$table",table,buff);
+ search_and_replace("$field",field,buff);
+ search_and_replace("$value",value,buff);
+ DBUG_PRINT("info",("path: '%s'",path));
+ DBUG_PRINT("info",("sum: '%d'",(database[0] ? strlen(database)+1 : 0) +(table[0] ? strlen(table)+1 : 0) +(field[0] ? strlen(field)+1 : 0) +(value[0] ? strlen(value)+1 : 0) +1));
+ search_and_replace("$*",path+
+ (server[0] ? strlen(server)+1 : 0) +
+ (database[0] ? strlen(database)+1 : 0) +
+ (table[0] ? strlen(table)+1 : 0) +
+ (field[0] ? strlen(field)+1 : 0) +
+ (value[0] ? strlen(value)+1 : 0) +
+ function->length +
+ 1,buff);
+ DBUG_PRINT("info",("Executing constructed function query: '%s'", buff));
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ sprintf(b,"ERROR %d: %s",mysql_error(sock),mysql_error(sock));
+ DBUG_VOID_RETURN;
+ }
+
+ db_show_result(sock, b, &Human);
+ DBUG_PRINT("info",("Returning: %s", b));
+ DBUG_RETURN(1);
+}
+
+int db_show_field(char *b,const char *database,const char *table, const char *field,const char *value, const char *param)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+ my_string *ptr;
+ DBUG_ENTER("db_show_field");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s', field: '%s' value: '%s'", b, database, table, field, value));
+
+ /* We cant output fields when one of these variables is missing */
+ if (!(database[0] && table[0] && field[0]))
+ DBUG_RETURN(-1);
+
+ my_init_dynamic_array(&field_array, sizeof(buff), 4096, 1024);
+
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ delete_dynamic(&field_array);
+ DBUG_RETURN(-1);
+ }
+
+ if(param) {
+ sprintf(buff,"%s",param);
+ } else {
+ sprintf(buff,"select %s from %s where %s='%s' LIMIT 1",field,table,field,value);
+ }
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ delete_dynamic(&field_array);
+ DBUG_RETURN(-1);
+ }
+
+
+ db_show_result(sock,b,&Human);
+/* if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i][BUFLEN],row[0]);
+ DBUG_PRINT("info",("field %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+// ptr = (*dynamic_element(&field_array,i,row[0]));
+ i++;
+ }
+ }
+// fix_filenames((char *)b);
+ mysql_free_result(result);
+ */
+ delete_dynamic(&field_array);
+ DBUG_RETURN(i);
+
+}
+int db_show_fields(char *b,const char *database,const char *table)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ MYSQL_FIELD *field;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("show_fields");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ if(result=mysql_list_fields(sock,buff,NULL)) {
+
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("field %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+int db_show_primary_keys(char *b,const char *database, const char *table)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ char buff2[BUFLEN];
+ unsigned int i;
+
+ DBUG_ENTER("db_show_primary_keys");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to '%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ sprintf(buff,"show keys from %s",table);
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ DBUG_RETURN(0);
+ }
+ buff2[0]='\0';
+ if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result)) {
+ if(!strcasecmp(row[2],"PRIMARY")) {
+ strcat(buff2,row[4]);
+ strcat(buff2,",\"_\",");
+ }
+ }
+ buff2[strlen(buff2)-5]='\0';
+ if(!buff2[0])
+ DBUG_RETURN(-1); // No PRIMARY keys in table
+ DBUG_PRINT("info",("Keys: %s<- \n", buff2));
+ } else
+ DBUG_RETURN(-1); // No keys in table
+
+ sprintf(buff,"SELECT CONCAT(%s) AS X FROM %s LIMIT 256",buff2,table);
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ DBUG_RETURN(0);
+ }
+ i=0;
+ if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ fix_filenames(&b[i*BUFLEN]);
+ DBUG_PRINT("info",("primarykey %s at %x, %i", &b[i*BUFLEN],&b[i*BUFLEN],i));
+ if(i++ >= MAXDIRS)
+ break;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+
+int db_show_keys(char *b,const char *database, const char *table)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("show_keys");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ sprintf(buff,"show keys from %s",table);
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ DBUG_RETURN(0);
+ }
+ if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("Key %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+
+int db_show_tables(char *b,const char *database)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("db_show_tables");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s'", b, database));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to '%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+
+ if(result=mysql_list_tables(sock,NULL)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("table %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+/*
+ * Finds all servers we are connected to
+ * and stores them in array supplied.
+ * returns count of servers
+ */
+int
+db_show_servers(char *b,int size)
+{
+ char* bufptr;
+ char* buff[BUFLEN*2];
+ DBUG_ENTER("db_show_servers");
+ DBUG_PRINT("enter",("buffer: '%s', size: '%d'", b, size));
+ bufptr=mysql_get_host_info(sock);
+ // FIXME: Actually we need to escape prohibited symbols in filenames
+ fix_filenames(bufptr);
+ strcpy(b,bufptr);
+ DBUG_RETURN(1);
+}
+
+/*
+ * Finds all databases in server
+ * and stores them in array supplied.
+ * returns count of databases
+ */
+int
+db_show_databases(char *b,int size)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("db_show_databases");
+ DBUG_PRINT("enter",("buffer: '%s', size: '%d'", b, size));
+ result=mysql_list_dbs(sock,NULL);
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("database %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+void db_load_formats()
+{
+
+ /* In future we should read these variables
+ * from configuration file/database here */
+
+ /* HTML output */
+ HTML.tablestart="<table>\n";
+
+ HTML.headerrowstart="<tr>";
+ HTML.headercellstart="<th>";
+ HTML.headercellseparator="</th><th>";
+ HTML.headercellend="</th>";
+ HTML.headerrowend="</tr>\n";
+ HTML.headerformat=0;
+
+ HTML.leftuppercorner="";
+ HTML.rightuppercorner="";
+ HTML.leftdowncorner="";
+ HTML.rightdowncorner="";
+ HTML.topcross="";
+ HTML.middlecross="";
+ HTML.bottomcross="";
+ HTML.leftcross="";
+ HTML.rightcross="";
+ HTML.bottomcross="";
+
+ HTML.contentrowstart="<tr>";
+ HTML.contentcellstart="<td>";
+ HTML.contentcellseparator="</td><td>";
+ HTML.contentcellend="</td>";
+ HTML.contentrowend="</tr>\n";
+ HTML.headerformat=0;
+
+ HTML.footerrowstart="";
+ HTML.footercellstart="";
+ HTML.footercellseparator="";
+ HTML.footercellend="";
+ HTML.footerrowend="\n";
+ HTML.footerformat=0;
+
+ HTML.tableend="</table>\n";
+
+/* Nice to look mysql client like output */
+
+ Human.tablestart="\n";
+
+ Human.headerrowstart="| ";
+ Human.headercellstart="";
+ Human.headercellseparator=" | ";
+ Human.headercellend=" |";
+ Human.headerrowend="\n";
+ Human.headerformat=1;
+
+ Human.leftuppercorner="/=";
+ Human.rightuppercorner="=\\\n";
+ Human.leftdowncorner="\\=";
+ Human.rightdowncorner="=/\n";
+ Human.leftcross="+-";
+ Human.rightcross="-+\n";
+ Human.topcross="=T=";
+ Human.middlecross="-+-";
+ Human.bottomcross="=`=";
+
+ Human.contentrowstart="| ";
+ Human.contentcellstart="";
+ Human.contentcellseparator=" | ";
+ Human.contentcellend=" |";
+ Human.contentrowend="\n";
+ Human.contentformat=1;
+
+ Human.footerrowstart="";
+ Human.footercellstart="";
+ Human.footercellseparator="";
+ Human.footercellend="";
+ Human.footerrowend="\n";
+ Human.footerformat=1;
+
+ Human.tableend="\n";
+
+/* Comma-separated format. For machine reading */
+
+ /* XML */
+
+/*
+ tee_fprintf(PAGER,"<?xml version=\"1.0\"?>\n\n<resultset statement=\"%s\">", statement);
+ (void) tee_fputs("\n <row>\n", PAGER);
+ data=(char*) my_malloc(lengths[i]*5+1, MYF(MY_WME));
+ tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ xmlencode(data, cur[i]);
+ tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ </row>\n" </resultset>\n*/
+}
+
+gptr db_load_functions()
+{
+ char *functions[]={
+ "database",".tables","SHOW TABLES","0",
+ "table",".status","SHOW TABLE STATUS FROM $table","0",
+ "table",".count","SELECT COUNT(*) FROM $table","0",
+ "table",".table","SELECT * FROM $table","0",
+ "table",".check","CHECK TABLE $table","0",
+ "table",".repair","REPAIR TABLE $table","0",
+ "key",".min","SELECT MIN($key) FROM $table","0",
+ "key",".max","SELECT MAX($key) FROM $table","0",
+ "key",".avg","SELECT AVG($key) FROM $table","0",
+ "server",".uptime","SHOW STATUS like 'Uptime'","0",
+ "server",".version","SELECT VERSION()","0",
+ "server",".execute","$*","1",
+ "root",".connect","CONNECT $*","0",
+ NULL,NULL,NULL,NULL
+ };
+ char buff[BUFLEN];
+ int i=0;
+ struct func_st func;
+ DBUG_ENTER("db_load_functions");
+ my_init_dynamic_array(&functions_array, sizeof(struct func_st), 4096, 1024);
+ while(functions[i]) {
+ strcpy(func.type_s, functions[i]); /* Type in string: "table"` */
+ strcpy(func.filename, functions[i+1]); /* Name like it appears on FS: "count" */
+ strcpy(func.function, functions[i+2]); /* Query: "SELECT COUNT(*) FROM `%table`" */
+ func.continuous= atoi(functions[i+3]); /* Query: "If command can be continued" */
+
+ if(!strcasecmp(func.type_s,"server"))
+ func.type=SERVER_FUNCTION;
+ else if(!strcasecmp(func.type_s,"table"))
+ func.type=TABLE_FUNCTION;
+ else if(!strcasecmp(func.type_s,"key"))
+ func.type=KEY_FUNCTION;
+ else if(!strcasecmp(func.type_s,"database"))
+ func.type=DATABASE_FUNCTION;
+ else if(!strcasecmp(func.type_s,"field"))
+ func.type=FIELD_FUNCTION;
+ else if(!strcasecmp(func.type_s,"root"))
+ func.type=ROOT_FUNCTION;
+ else func.type=NONE_FUNCTION;
+
+ func.length=strlen(func.filename); /* Filename length */
+ DBUG_PRINT("info",("func.type_s: %s",func.type_s));
+ DBUG_PRINT("info",("func.filename: %s",func.filename));
+ DBUG_PRINT("info",("func.function: %s",func.function));
+ DBUG_PRINT("info",("func.type: %d",func.type));
+ DBUG_PRINT("info",("func.continuous: %d",func.continuous));
+ DBUG_PRINT("info",("i: %d",i));
+ insert_dynamic(&functions_array,(gptr)&func);
+ i+=4;
+ }
+ DBUG_RETURN((gptr)&functions_array);
+}
diff --git a/fs/dump.sql b/fs/dump.sql
new file mode 100644
index 00000000000..c61669cecb5
--- /dev/null
+++ b/fs/dump.sql
@@ -0,0 +1,28 @@
+# MySQL dump 8.12
+#
+# Host: localhost Database: mysqlfs
+#--------------------------------------------------------
+# Server version 3.23.33
+
+#
+# Table structure for table 'functions'
+#
+
+CREATE TABLE functions (
+ type enum('server','database','table','field','key') NOT NULL default 'server',
+ name char(20) NOT NULL default '',
+ sql char(128) NOT NULL default '',
+ PRIMARY KEY (type,name)
+) TYPE=MyISAM;
+
+#
+# Dumping data for table 'functions'
+#
+
+INSERT INTO functions VALUES ('server','uptime','SHOW STATUS like \'Uptime\'');
+INSERT INTO functions VALUES ('server','version','SELECT VERSION()');
+INSERT INTO functions VALUES ('table','count','SELECT COUNT(*) FROM `%table`');
+INSERT INTO functions VALUES ('key','min','SELECT MIN(%key) FROM `%table`');
+INSERT INTO functions VALUES ('key','max','SELECT MAX(%key) FROM `%table`');
+INSERT INTO functions VALUES ('key','avg','SELECT AVG(%key) FROM `%table`');
+
diff --git a/fs/korbit-kernel-2.4.1-patch b/fs/korbit-kernel-2.4.1-patch
new file mode 100644
index 00000000000..d97b1dac344
--- /dev/null
+++ b/fs/korbit-kernel-2.4.1-patch
@@ -0,0 +1,35661 @@
+diff -urN linux-2.4.1/.cvsignore linux-2.4.1-korbit/.cvsignore
+--- linux-2.4.1/.cvsignore Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/.cvsignore Thu Feb 1 11:46:48 2001
+@@ -0,0 +1 @@
++makekorbit.sh
+diff -urN linux-2.4.1/KORBit.Announce linux-2.4.1-korbit/KORBit.Announce
+--- linux-2.4.1/KORBit.Announce Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/KORBit.Announce Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,62 @@
++From sabre@nondot.org Fri Dec 8 15:15:43 2000
++Date: Fri, 8 Dec 2000 17:10:47 -0600 (CST)
++From: Chris Lattner <sabre@nondot.org>
++To: linux-kernel@vger.kernel.org, orbit-list@gnome.org
++Cc: korbit-cvs@lists.sourceforge.net
++Subject: ANNOUNCE: Linux Kernel ORB: kORBit
++
++
++This email is here to announce the availability of a port of ORBit (the
++GNOME ORB) to the Linux kernel. This ORB, named kORBit, is available from
++our sourceforge web site (http://korbit.sourceforge.net/). A kernel ORB
++allows you to write kernel extensions in CORBA and have the kernel call
++into them, or to call into the kernel through CORBA. This opens the door
++to a wide range of experiments/hacks:
++
++* We can now write device drivers in perl, and let them run on the iMAC
++ across the hall from you. :)
++* Through the use of a LD_PRELOAD'd syscall wrapper library, you can
++ forward system calls through CORBA to an arbitrary local/remote machine.
++* CORBA servers are implemented as Linux kernel modules, so they may be
++ dynamically loaded or unloaded from a running system at any time. CORBA
++ servers expose their IOR's through a /proc/corba filesystem.
++* Filesystems may be implemented as remote CORBA objects and mounted on
++ the local machine, by using 'mount -t corbafs -o IOR:... none /mnt/corba'
++
++This are just some of the features available _RIGHT_NOW_ that are
++supported by kORBit. I'm sure that YOU can think of many more.
++
++Implementation:
++We implemented this port by providing a user->kernel mapping layer that
++consists of providing standard system header files for the "user" code to
++#include. In these header files, we do the mapping required. For
++example, we implement a <stdio.h> that #defines printf to printk (as a
++trivial example). Only user level code sees or uses these wrappers... all
++of our modifications to the Linux kernel are contained within the
++linux/net/korbit subdirectory.
++
++This is currently implemented with a 2.4.0test10 kernel, although forward
++porting should be very easy. This project was implemented as a cs423
++semester project by Chris Lattner, Fredrik Vraalsen, Andy Reitz, and Keith
++Wessel at the University of Illinois @ Urbana Champaign.
++
++Unresolved issues:
++* Our poll model is not optimial. Currently we actually do a real poll on
++ a (struct socket *) set. This causes relatively high latencies (on the
++ order 1 second, worst case) for CORBA requests. Our waitqueues are not
++ working quite as well as they should. :)
++* Security is completely unimplemented. Someone could use corba
++ interfaces to read any file on your system, for example (if the
++ CORBA-FileServer module is installed). Thus, this is really more for
++ prototyping and development than actual real world use. :)
++
++If you have any questions or comments, please feel free to contact us at:
++
++Chris Lattner, Fredrik Vraalsen, Andy Reitz, Keith Wessel
++<korbit-cvs@lists.sourceforge.net>
++
++btw, yes we are quite crazy, but what good is it to be normal and
++conformist afterall? :)
++
++
++
+diff -urN linux-2.4.1/Makefile linux-2.4.1-korbit/Makefile
+--- linux-2.4.1/Makefile Tue Jan 30 09:19:26 2001
++++ linux-2.4.1-korbit/Makefile Thu Feb 1 15:48:45 2001
+@@ -70,7 +70,7 @@
+ # images. Uncomment if you want to place them anywhere other than root.
+ #
+
+-#export INSTALL_PATH=/boot
++export INSTALL_PATH=/boot
+
+ #
+ # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
+diff -urN linux-2.4.1/README.korbit linux-2.4.1-korbit/README.korbit
+--- linux-2.4.1/README.korbit Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/README.korbit Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,83 @@
++ ====================
++ KORBit: A CORBA ORB
++ For The Linux Kernel
++ ====================
++
++ Submitted as a final project in CS423 by
++ Chris Lattner <lattner@uiuc.edu>,
++ Andy Reitz <areitz@uiuc.edu>,
++ Fredrik Vraalsen <vraalsen@uiuc.edu>, and
++ Keith Wessel <kwessel@uiuc.edu>
++
++ December 8, 2000
++
++
++About:
++======
++KORBit is a port of the CORBA Object Request Broker ORBit to the Linux
++kernel. For more information, see http://korbit.sourceforge.net/
++
++In order to use this code, you need to have ORBit-0.5.3 or later
++installed (including the development environment). The KORBit server
++modules make use of the ORBit IDL Compiler during the build process.
++
++Building The Code:
++==================
++In order to compile and run KORBit you need a recent 2.4.0-test
++version of the Linux kernel (KORBit is developed on 2.4.0-test10).
++
++To obtain a copy of the KORBit source code, see the webpage above.
++Once you have untar'ed the source code, copy the contents of the linux
++subdirectory of KORBit into the Linux root source directory
++(e.g. /usr/src/linux).
++
++Run your favourite configuration option for Linux (e.g. 'make
++menuconfig'). To enable KORBit support in the kernel, go into the
++'Networking options' section of the configuration and enable 'Kernel
++ORB'. Then add the various CORBA services that you wish to run in the
++kernel.
++
++NOTE: The Kernel ORB *must* be compiled statically into the kernel
++(answer 'Y') and CORBA services *must* be compiled as modules (answer
++'M') at the moment.
++
++Then compile and install the Linux kernel in the standard way, e.g.:
++
++make dep ; make clean ; make bzImage ; make modules ; make modules_install
++
++Copy System.map and arch/<i386|whatever>/boot/bzImage to the proper
++places (/boot), edit your lilo.conf, run lilo and reboot.
++
++You should now be able to use CORBA in your Linux kernel! Remember,
++this is *pre-alpha* software! Use on your own risk! Don't come to us
++crying if your machine blows up...
++
++Using Our Example KORBit Objects:
++=================================
++The "CORBA Echo Server" is effectively our "hello world" object. Once
++loaded into the kernel, module will instantiate an object that
++implements the "echoString()" interface. This method allows the client
++to send a string, which will be printed on the system console. Then,
++it will return a random number, which the client will print. Thus,
++after running this test, you will verify that two-way communication is
++working between KORBit and your ORB of choice.
++
++To insert this module into your newly-compiled kernel, type
++
++insmod /lib/modules/2.4.0-test10/kernel/net/korbit/modules/Echo/server/corba-echo-server.o
++
++Next verify that this module is actually loaded, by invoking
++"lsmod". You should see something like this:
++
++ Module Size Used by
++ corba-echo-server 3344 0 (unused)
++
++Now, you can grab the IOR to this object by typing "cat
++/proc/corba/echo-server". Now, you need to build the echo client,
++which will use this IOR in order to connect to the echo server. This
++can be accomplished by simply changing to the
++"/usr/src/linux/net/korbit/modules/Echo/client" directory, and then
++typing "make". Once finished, simply type "./echo-client `cat
++/proc/corba/echo-server`", and then cross your fingers!
++
++
+diff -urN linux-2.4.1/Rules.make linux-2.4.1-korbit/Rules.make
+--- linux-2.4.1/Rules.make Sat Dec 30 00:07:19 2000
++++ linux-2.4.1-korbit/Rules.make Thu Feb 1 15:46:07 2001
+@@ -222,9 +222,9 @@
+
+ $(MODINCL)/%.ver: %.c
+ @if [ ! -r $(MODINCL)/$*.stamp -o $(MODINCL)/$*.stamp -ot $< ]; then \
+- echo '$(CC) $(CFLAGS) -E -D__GENKSYMS__ $<'; \
++ echo '$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $<'; \
+ echo '| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp'; \
+- $(CC) $(CFLAGS) -E -D__GENKSYMS__ $< \
++ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $< \
+ | $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then echo $@ is unchanged; rm -f $@.tmp; \
+ else echo mv $@.tmp $@; mv -f $@.tmp $@; fi; \
+diff -urN linux-2.4.1/korbit.patch linux-2.4.1-korbit/korbit.patch
+--- linux-2.4.1/korbit.patch Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/korbit.patch Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,43 @@
++--- linux/Rules.make.orig Wed Jan 31 22:50:40 2001
+++++ linux/Rules.make Thu Feb 1 01:39:46 2001
++@@ -222,9 +222,9 @@
++
++ $(MODINCL)/%.ver: %.c
++ @if [ ! -r $(MODINCL)/$*.stamp -o $(MODINCL)/$*.stamp -ot $< ]; then \
++- echo '$(CC) $(CFLAGS) -E -D__GENKSYMS__ $<'; \
+++ echo '$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $<'; \
++ echo '| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp'; \
++- $(CC) $(CFLAGS) -E -D__GENKSYMS__ $< \
+++ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $< \
++ | $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
++ if [ -r $@ ] && cmp -s $@ $@.tmp; then echo $@ is unchanged; rm -f $@.tmp; \
++ else echo mv $@.tmp $@; mv -f $@.tmp $@; fi; \
++--- linux/net/Config.in.orig Wed Jan 31 22:39:32 2001
+++++ linux/net/Config.in Thu Feb 1 01:40:02 2001
++@@ -30,6 +30,7 @@
++ fi
++ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
++ source net/khttpd/Config.in
+++ source net/korbit/Config.in
++ fi
++ fi
++ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
++--- linux/net/Makefile.orig Thu Feb 1 01:41:42 2001
+++++ linux/net/Makefile Thu Feb 1 01:41:35 2001
++@@ -7,7 +7,7 @@
++
++ O_TARGET := network.o
++
++-mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched
+++mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched korbit
++ export-objs := netsyms.o
++
++ subdir-y := core ethernet
++@@ -27,6 +27,7 @@
++ endif
++
++ subdir-$(CONFIG_KHTTPD) += khttpd
+++subdir-$(CONFIG_KORBIT) += korbit
++ subdir-$(CONFIG_NETLINK) += netlink
++ subdir-$(CONFIG_PACKET) += packet
++ subdir-$(CONFIG_NET_SCHED) += sched
+diff -urN linux-2.4.1/makekorbit.sh linux-2.4.1-korbit/makekorbit.sh
+--- linux-2.4.1/makekorbit.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/makekorbit.sh Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,4 @@
++#!/bin/sh
++
++make CFLAGS="-D__KERNEL__ -I`pwd`/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -march=k6 -DHAVE_CONFIG_H -DHAVE_UNISTD_H -I. -I.. -I../include -nostdinc" -C net/korbit TOPDIR=`pwd`
++
+diff -urN linux-2.4.1/net/CVS/Entries linux-2.4.1-korbit/net/CVS/Entries
+--- linux-2.4.1/net/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Entries Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/CVS/Entries.Log linux-2.4.1-korbit/net/CVS/Entries.Log
+--- linux-2.4.1/net/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Entries.Log Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++A D/korbit////
+diff -urN linux-2.4.1/net/CVS/Repository linux-2.4.1-korbit/net/CVS/Repository
+--- linux-2.4.1/net/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Repository Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net
+diff -urN linux-2.4.1/net/CVS/Root linux-2.4.1-korbit/net/CVS/Root
+--- linux-2.4.1/net/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Root Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/Config.in linux-2.4.1-korbit/net/Config.in
+--- linux-2.4.1/net/Config.in Tue Oct 10 19:33:52 2000
++++ linux-2.4.1-korbit/net/Config.in Thu Feb 1 15:46:07 2001
+@@ -30,6 +30,7 @@
+ fi
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ source net/khttpd/Config.in
++ source net/korbit/Config.in
+ fi
+ fi
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+diff -urN linux-2.4.1/net/Makefile linux-2.4.1-korbit/net/Makefile
+--- linux-2.4.1/net/Makefile Sat Dec 30 00:07:24 2000
++++ linux-2.4.1-korbit/net/Makefile Thu Feb 1 15:46:07 2001
+@@ -7,7 +7,7 @@
+
+ O_TARGET := network.o
+
+-mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched
++mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched korbit
+ export-objs := netsyms.o
+
+ subdir-y := core ethernet
+@@ -27,6 +27,7 @@
+ endif
+
+ subdir-$(CONFIG_KHTTPD) += khttpd
++subdir-$(CONFIG_KORBIT) += korbit
+ subdir-$(CONFIG_NETLINK) += netlink
+ subdir-$(CONFIG_PACKET) += packet
+ subdir-$(CONFIG_NET_SCHED) += sched
+diff -urN linux-2.4.1/net/korbit/CVS/Entries linux-2.4.1-korbit/net/korbit/CVS/Entries
+--- linux-2.4.1/net/korbit/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Entries Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,6 @@
++/Config.in/1.3/Thu Feb 1 09:46:49 2001//
++/Makefile/1.7/Thu Feb 1 09:46:49 2001//
++/config.h/1.2/Thu Feb 1 09:46:49 2001//
++/exported_symbols.c/1.8/Thu Feb 1 09:46:49 2001//
++/korbit.h/1.2/Thu Feb 1 09:46:49 2001//
++D
+diff -urN linux-2.4.1/net/korbit/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Entries.Log Thu Feb 1 11:47:15 2001
+@@ -0,0 +1,7 @@
++A D/IIOP////
++A D/ORBitutil////
++A D/include////
++A D/kglib////
++A D/modules////
++A D/orb////
++A D/sup////
+diff -urN linux-2.4.1/net/korbit/CVS/Repository linux-2.4.1-korbit/net/korbit/CVS/Repository
+--- linux-2.4.1/net/korbit/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Repository Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit
+diff -urN linux-2.4.1/net/korbit/CVS/Root linux-2.4.1-korbit/net/korbit/CVS/Root
+--- linux-2.4.1/net/korbit/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Root Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/Config.in linux-2.4.1-korbit/net/korbit/Config.in
+--- linux-2.4.1/net/korbit/Config.in Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/Config.in Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,8 @@
++#
++# KORBit
++#
++
++#tristate ' Kernel ORB (EXPERIMENTAL)' CONFIG_KORBIT
++bool ' Kernel ORB (EXPERIMENTAL)' CONFIG_KORBIT
++
++source net/korbit/modules/Config.in
+diff -urN linux-2.4.1/net/korbit/IIOP/CVS/Entries linux-2.4.1-korbit/net/korbit/IIOP/CVS/Entries
+--- linux-2.4.1/net/korbit/IIOP/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/CVS/Entries Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,15 @@
++/IIOP-config.h/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/IIOP-design.txt/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/IIOP-private.h/1.2/Thu Feb 1 09:46:50 2001//
++/IIOP-types.h/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/IIOP.h/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/Makefile/1.4/Thu Feb 1 09:46:51 2001//
++/connection.c/1.19/Thu Feb 1 09:46:51 2001//
++/encoders.c/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/giop-msg-buffer.c/1.12/Thu Feb 1 09:46:51 2001//
++/giop-msg-buffer.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-encoders.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-endian.c/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-endian.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-endianP.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++D
+diff -urN linux-2.4.1/net/korbit/IIOP/CVS/Repository linux-2.4.1-korbit/net/korbit/IIOP/CVS/Repository
+--- linux-2.4.1/net/korbit/IIOP/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/CVS/Repository Thu Feb 1 11:46:50 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/IIOP
+diff -urN linux-2.4.1/net/korbit/IIOP/CVS/Root linux-2.4.1-korbit/net/korbit/IIOP/CVS/Root
+--- linux-2.4.1/net/korbit/IIOP/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/CVS/Root Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-config.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP-config.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP-config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-config.h Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,5 @@
++/* The size of the chunks that are used for indirect pieces of messages.
++ Too low, and you'll have a lot of malloc overhead. Too high, and you'll
++ get wasted mem.
++*/
++#define GIOP_INDIRECT_CHUNK_SIZE 1024
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-design.txt linux-2.4.1-korbit/net/korbit/IIOP/IIOP-design.txt
+--- linux-2.4.1/net/korbit/IIOP/IIOP-design.txt Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-design.txt Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,14 @@
++
++void Hello_hello(CORBA_Object anobj, const char *arg1, CORBA_Environment *ev)
++
++If we're doing a local call (i.e. shared library object activation),
++just do it.
++
++If we're doing a remote call, we need to setup generic header
++(utilfunc), setup request header (utilfunc), encode arguments (stubs),
++send the message headers & body (utilfunc) and wait for a reply (XXX
++define more clearly). When we get the reply, we need to read the
++reply(utilfunc), decode the return value & out/inout arguments(stubs)
++& fill them in (or decode the exception that resulted (utilfunc)), and
++return.
++
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-private.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP-private.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP-private.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-private.h Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,46 @@
++#ifndef IIOP_PRIVATE_H
++#define IIOP_PRIVATE_H 1
++
++
++#include "config.h"
++
++#if defined(HAVE_POLL) && defined(I_WANT_POLL)
++#define USE_POLL
++#else
++#undef USE_POLL
++#endif
++
++#ifdef HAVE_SYS_POLL_H
++#include <sys/poll.h>
++#endif
++
++#include <sys/time.h>
++#include <sys/types.h>
++#include <unistd.h>
++
++#include <glib.h>
++
++typedef struct {
++ GList *list;
++ gboolean connection_list_changed;
++#ifndef __KORBIT__
++ GPtrArray *fd_to_connection_mapping;
++#else /* __KORBIT__ */
++ GHashTable *fd_to_connection_mapping;
++#endif /* __KORBIT__ */
++# ifdef USE_POLL
++ GArray *pollset;
++# else
++ fd_set selectset_rd, selectset_ex;
++# endif
++ int max_fd;
++} GIOPConnectionList;
++
++extern GIOPConnectionList giop_connection_list;
++
++/* If you get a buffer that you didn't want, add it to the list! */
++void giop_received_list_push(GIOPRecvBuffer *recv_buffer);
++GIOPRecvBuffer *giop_received_list_pop(void);
++
++
++#endif
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-types.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP-types.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP-types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-types.h Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,76 @@
++#ifndef IIOP_TYPES_H
++#define IIOP_TYPES_H 1
++
++/* XXX todo sync this up with basic_types.h if needed */
++#include <unistd.h>
++#include <netinet/in.h>
++#include <sys/un.h>
++
++#include <ORBitutil/basic_types.h>
++
++typedef enum {
++ GIOP_CONNECTION_SERVER, /* Not a real connection to any place - just
++ listening */
++ GIOP_CONNECTION_CLIENT
++} GIOPConnectionClass;
++
++typedef struct _GIOPConnection GIOPConnection;
++struct _GIOPConnection {
++ enum { GIOP_CONNECTION_NONE, GIOP_CONNECTION_IIOP } connection_type;
++ void (*destroy_func)(GIOPConnection *connection);
++
++ gint refcount;
++ GIOPConnectionClass connection_class;
++
++ int fd;
++
++ /* You can access these if you wish. */
++ gpointer orb_data;
++ gpointer user_data;
++ /* end accessable stuff */
++
++ guchar is_valid, was_initiated, is_auth;
++
++ gpointer incoming_msg; /* GIOPRecvBuffer */
++};
++
++#define GIOP_CONNECTION(x) ((GIOPConnection *)(x))
++#define GIOP_CONNECTION_GET_FD(x) (GIOP_CONNECTION((x))->fd)
++
++typedef enum { IIOP_IPV4, IIOP_IPV6, IIOP_USOCK } IIOPConnectionType;
++
++typedef struct {
++ GIOPConnection giop_connection;
++
++ gboolean is_serversock;
++ IIOPConnectionType icnxtype;
++ union {
++ struct {
++ char *hostname;
++ struct sockaddr_in location;
++ } ipv4;
++ struct sockaddr_un usock;
++ /* Yes this is a config.h define, and no it doesn't matter,
++ because this structure should only be used internally anyways */
++#ifdef HAVE_IPV6
++ struct {
++ char *hostname;
++ struct sockaddr_in6 location;
++ } ipv6;
++#endif
++ } u;
++} IIOPConnection;
++
++#define IIOP_CONNECTION(x) ((IIOPConnection *)(x))
++
++#if defined(DEBUG_sopwith_connection_refcounting)
++#define giop_connection_ref(x) G_STMT_START{ (GIOP_CONNECTION(x)->refcount++); g_print("! reffing fd %d in " __PRETTY_FUNCTION__ ":%d to %d\n", GIOP_CONNECTION_GET_FD(x), __LINE__, GIOP_CONNECTION(x)->refcount); }G_STMT_END
++
++#define giop_connection_unref(x) G_STMT_START{ GIOP_CONNECTION(x)->refcount--; g_print("! dereffing fd %d in " __PRETTY_FUNCTION__ ":%d to %d\n", GIOP_CONNECTION_GET_FD(x), __LINE__, GIOP_CONNECTION(x)->refcount); if(GIOP_CONNECTION(x)->refcount <= 0) giop_connection_free(x); }G_STMT_END
++#else
++#define giop_connection_ref(x) G_STMT_START{ (GIOP_CONNECTION(x)->refcount++); }G_STMT_END
++
++#define giop_connection_unref(x) G_STMT_START{ GIOP_CONNECTION(x)->refcount--; if(GIOP_CONNECTION(x)->refcount <= 0) giop_connection_free(x); }G_STMT_END
++#endif
++
++#endif /* IIOP_TYPES_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP.h Thu Feb 1 16:19:47 2001
+@@ -0,0 +1,52 @@
++#ifndef IIOP_H
++#define IIOP_H 1
++
++#include <unistd.h>
++#include <ORBitutil/util.h>
++#include "IIOP-config.h"
++#include "IIOP-types.h"
++#include "giop-msg-buffer.h"
++#include "iiop-encoders.h"
++#include "iiop-endian.h"
++
++/* We don't speak GIOP 1.0, sosumi */
++#define GIOP_1_1
++
++
++void giop_init(const char *argv0);
++
++/* You use this to get a pointer to a new (or existing) connection
++ that has the specified host/port characteristics */
++IIOPConnection *iiop_connection_get(const char *host, gushort port,
++ gboolean existing_only);
++/* Similar, but for UNIX sockets */
++IIOPConnection *iiop_connection_unix_get(const char *sockpath,
++ gboolean existing_only);
++
++/* gives us a local socket that other people can connect to... */
++IIOPConnection *iiop_connection_server(void);
++IIOPConnection *iiop_connection_server_ipv6(void);
++IIOPConnection *iiop_connection_server_unix(const char *sockpath);
++
++void giop_main_quit(void);
++void giop_main(void); /* main loop for the program if none other is given,
++ and also used while waiting for a reply */
++void giop_main_iterate(gboolean blocking);
++void giop_main_handle_connection(GIOPConnection *connection);
++void giop_main_handle_connection_exception(GIOPConnection *connection);
++GIOPRecvBuffer *giop_main_next_message(gboolean blocking);
++GIOPRecvBuffer *giop_main_next_message_2(gboolean blocking,
++ GIOPConnection *monitor);
++GIOPConnection *giop_check_connections(gboolean block_for_reply);
++
++/* This assumes that the appropriate GIOP_CLOSECONNECTION message
++ has been sent to the peer */
++void giop_connection_free(GIOPConnection *connection);
++
++/* Called when a connection is created */
++extern void (*IIOPAddConnectionHandler)(GIOPConnection *newcnx);
++/* Called when a connection is about to be destroyed */
++extern void (*IIOPRemoveConnectionHandler)(GIOPConnection *oldcnx);
++extern void (*IIOPIncomingMessageHandler)(GIOPRecvBuffer *recv_buffer);
++
++#endif /* IIOP_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/Makefile linux-2.4.1-korbit/net/korbit/IIOP/Makefile
+--- linux-2.4.1/net/korbit/IIOP/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/Makefile Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,18 @@
++#
++# Makefile for KORBit/IIOP
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .o file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := IIOPlib.o
++
++#obj-m := $(O_TARGET)
++obj-y := connection.o encoders.o giop-msg-buffer.o iiop-endian.o
++
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I.. -I../include -I../kglib -I../ORBitutil -nostdinc
++
++include $(TOPDIR)/Rules.make
+diff -urN linux-2.4.1/net/korbit/IIOP/connection.c linux-2.4.1-korbit/net/korbit/IIOP/connection.c
+--- linux-2.4.1/net/korbit/IIOP/connection.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/connection.c Thu Feb 1 19:26:07 2001
+@@ -0,0 +1,1565 @@
++#include "config.h"
++
++#if defined(HAVE_POLL) && defined(I_WANT_POLL)
++#define USE_POLL
++#else
++#undef USE_POLL
++#endif
++
++#ifndef _XOPEN_SOURCE_EXTENDED
++# define _XOPEN_SOURCE_EXTENDED 1
++# define WE_DEFINED_XOPEN_SOURCE_EXTENDED 1
++#endif
++#include "iiop-endianP.h"
++#ifdef WE_DEFINED_XOPEN_SOURCE_EXTENDED
++# undef _XOPEN_SOURCE_EXTENDED
++#endif
++#include "IIOP.h"
++#include "IIOP-private.h"
++#include "giop-msg-buffer.h"
++#include <stdlib.h>
++#include <unistd.h>
++#ifdef ORBIT_DEBUG
++#include <errno.h>
++#endif
++#include <sys/types.h>
++#include <fcntl.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++#ifndef _XOPEN_SOURCE_EXTENDED
++# define _XOPEN_SOURCE_EXTENDED 1
++#endif
++#include <arpa/inet.h>
++#include <netdb.h>
++#ifdef WE_DEFINED_XOPEN_SOURCE_EXTENDED
++# undef _XOPEN_SOURCE_EXTENDED
++#endif
++#include <ctype.h>
++#include <string.h>
++#include <sys/time.h>
++#include <sys/ioctl.h>
++#include <signal.h>
++#include <syslog.h>
++#include <stdio.h>
++
++/*
++#ifdef O_NONBLOCK
++#undef O_NONBLOCK
++#endif
++#define O_NONBLOCK 0
++*/
++
++#if defined(HAVE_TCPD_H) && defined(HAVE_HOSTS_ACCESS)
++#include <tcpd.h>
++#endif
++
++#if 0
++#include <malloc.h>
++
++static struct mallinfo mi1, mi2;
++
++#define AM() mi1 = mallinfo();
++#define PM(x) mi2 = mallinfo(); printf(x ": used %d, now %d\n", \
++mi2.uordblks - mi1.uordblks, mi2.uordblks);
++#endif
++
++#ifdef HAVE_POLL
++#include <sys/poll.h>
++#endif
++
++#ifndef SUN_LEN
++/* This system is not POSIX.1g. */
++#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
++ + strlen ((ptr)->sun_path))
++#endif
++
++void (*IIOPAddConnectionHandler)(GIOPConnection *newcnx) = NULL;
++void (*IIOPRemoveConnectionHandler)(GIOPConnection *oldcnx) = NULL;
++void (*IIOPIncomingMessageHandler)(GIOPRecvBuffer *recv_buffer) = NULL;
++
++static void giop_connection_add_to_list (GIOPConnection *cnx);
++static void giop_connection_remove_from_list (GIOPConnection *cnx);
++
++static void iiop_init (void);
++static void iiop_connection_server_accept (GIOPConnection *connection);
++static void iiop_connection_destroy (IIOPConnection *connection);
++static IIOPConnection *iiop_connection_new (const char *host, gushort port);
++static IIOPConnection *iiop_connection_unix_new (const char *sockpath);
++static void iiop_unlink_unix_sockets (void);
++
++DEFINE_LOCK(giop_connection_list);
++GIOPConnectionList giop_connection_list;
++static GSList *iiop_unix_socket_list = NULL;
++
++#if defined(HAVE_HOSTS_ACCESS) && defined (HAVE_TCPD_H)
++static const char *argv0_val = NULL;
++#endif
++
++struct fd_hash_elem
++{
++ guint fd;
++ GIOPConnection *cnx;
++};
++
++static guint fd_hash_func(gconstpointer key)
++{
++ const guint *key_ptr = (guint *)key;
++ guint result = *key_ptr >> 2;
++ return result;
++}
++
++static gint fd_compare_func(gconstpointer a, gconstpointer b)
++{
++ const guint *a_ptr = (guint *)a;
++ const guint *b_ptr = (guint *)b;
++ return *a_ptr == *b_ptr;
++}
++
++static gboolean fd_hash_clear(gpointer key, gpointer value, gpointer user_data)
++{
++ struct fd_hash_elem *el = (struct fd_hash_elem *)value;
++ g_free(el);
++ return TRUE;
++}
++
++/*
++ * giop_init
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: Initializes giop_connection_list
++ * Global data structures used: giop_connection_list
++ *
++ * Description: Initializes giop_connection_list. Calls
++ * giop_message_buffer_init() to initialize the
++ * message_buffer subsystem. Calls iiop_init()
++ * to perform IIOP-specific initialization.
++ */
++
++void giop_init(const char *argv0)
++{
++#ifndef __KERNEL__
++ struct sigaction mypipe;
++#endif
++ g_assert(sizeof(GIOPMessageHeader) == 12);
++
++#if defined(HAVE_HOSTS_ACCESS) && defined (HAVE_TCPD_H)
++ argv0_val = g_strdup(g_basename(argv0)); /* For TCP wrappers */
++#endif
++
++#ifndef __KERNEL__
++ memset(&mypipe, '\0', sizeof(mypipe));
++ mypipe.sa_handler = SIG_IGN;
++
++ sigaction(SIGPIPE, &mypipe, NULL);
++#endif
++
++ giop_message_buffer_init();
++
++ INIT_LOCK(giop_connection_list);
++
++ giop_connection_list.list = NULL;
++ giop_connection_list.connection_list_changed = FALSE;
++
++#ifdef USE_POLL
++ giop_connection_list.pollset = g_array_new(FALSE, FALSE,
++ sizeof(struct pollfd));
++#else
++ FD_ZERO(&giop_connection_list.selectset_rd);
++ FD_ZERO(&giop_connection_list.selectset_ex);
++#endif
++
++#ifndef __KORBIT__
++ giop_connection_list.fd_to_connection_mapping = g_ptr_array_new();
++#else
++ giop_connection_list.fd_to_connection_mapping =
++ g_hash_table_new(&fd_hash_func,
++ &fd_compare_func);
++#endif
++
++ /*
++ * This also needs to do any transport-specific initialization
++ * as appropriate
++ */
++ iiop_init();
++}
++
++/*** giop_connection_init
++ *
++ * Inputs: 'giop_connection' - memory region allocated for use as a
++ * GIOPConnection.
++ * 'cnxclass' - the class of connection that will be stored
++ * here (SERVER, CLIENT)
++ *
++ * Outputs: None
++ *
++ * Side effects: Initializes 'giop_connection'.
++ *
++ * Description: Basic setup of a GIOPConnection.
++ * Sets is_valid to FALSE because it is the responsibility of
++ * the transport-specific initialization routine to make
++ * a connection valid.
++ */
++
++static void giop_connection_init(GIOPConnection *giop_connection,
++ GIOPConnectionClass cnxclass)
++{
++ giop_connection->connection_type = GIOP_CONNECTION_NONE;
++ giop_connection->refcount = 0;
++ giop_connection->connection_class = cnxclass;
++ giop_connection->is_valid = FALSE;
++ giop_connection->is_auth = FALSE;
++ giop_connection->was_initiated = FALSE;
++}
++
++/*
++ * giop_connection_free
++ * Inputs: 'connection'
++ * Outputs: None
++ * Side effects: Makes the 'connection' invalid as a GIOPConnection
++ * and as a gpointer.
++ *
++ * Description: Calls giop_connection_remove_from_list() to
++ * stop the connection from being used for incoming.
++ *
++ * If a transport-specific finalization function has
++ * been provided, call it.
++ *
++ * Free the memory block at '*connection'.
++ *
++ */
++void giop_connection_free(GIOPConnection *connection)
++{
++ g_return_if_fail(connection != NULL);
++ giop_connection_remove_from_list(connection);
++
++ if(connection->is_valid && connection->destroy_func)
++ connection->destroy_func(connection);
++
++ connection->is_valid = FALSE;
++
++ if(connection->incoming_msg) {
++ GIOPRecvBuffer *buf;
++
++ buf = connection->incoming_msg;
++ connection->incoming_msg = NULL;
++ giop_recv_buffer_unuse(buf);
++ }
++
++ g_free(connection);
++}
++
++/*
++ * giop_connection_list_recreate
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: giop_connection_list changes.
++ *
++ * Global data structures used: giop_connection_list
++ *
++ * Description:
++ * When new connections are added to giop_connection_list.list,
++ * the data structures passed to poll() or select() (OS-dependant)
++ * must be recreated to match this list.
++ *
++ * [We do this at add-connection/remove-connection time
++ * instead of every time a poll/select is done in order to
++ * speed things up a little]
++ *
++ * This function reinitializes the OS-specific file
++ * descriptor data structure and then adds all the file
++ * descriptors in the list to it.
++ *
++ * It also regenerates the array that maps file descriptors
++ * into GIOPConnection*'s
++ *
++ */
++static void
++giop_connection_list_recreate(void)
++{
++ int curfd;
++ GList *item;
++ GIOPConnection *cnx;
++#ifdef USE_POLL
++ struct pollfd new_poll;
++
++ new_poll.revents = 0;
++#endif
++
++ giop_connection_list.max_fd = 0;
++ for(item = giop_connection_list.list; item; item = g_list_next(item))
++ {
++ cnx = item->data;
++ curfd = GIOP_CONNECTION_GET_FD(cnx);
++
++ if(curfd > giop_connection_list.max_fd)
++ giop_connection_list.max_fd = curfd;
++ }
++
++#ifndef __KORBIT__
++ g_ptr_array_set_size(giop_connection_list.fd_to_connection_mapping,
++ giop_connection_list.max_fd + 1);
++#else
++ g_hash_table_foreach_remove(giop_connection_list.fd_to_connection_mapping,
++ fd_hash_clear,
++ NULL);
++#endif
++
++#ifdef USE_POLL
++ g_array_set_size(giop_connection_list.pollset, 0);
++#else
++ FD_ZERO(&giop_connection_list.selectset_rd);
++ FD_ZERO(&giop_connection_list.selectset_ex);
++#endif
++
++ for(item = giop_connection_list.list; item; item = g_list_next(item))
++ {
++ struct fd_hash_elem *el;
++
++ cnx = item->data;
++ curfd = GIOP_CONNECTION_GET_FD(cnx);
++
++#ifndef __KORBIT__
++ giop_connection_list.fd_to_connection_mapping->pdata[curfd] = cnx;
++#else
++ el = g_new(struct fd_hash_elem, 1);
++ el->fd = curfd;
++ el->cnx = cnx;
++ g_hash_table_insert(giop_connection_list.fd_to_connection_mapping,
++ &(el->fd),
++ el);
++#endif
++
++# ifdef USE_POLL
++ new_poll.fd = curfd;
++ new_poll.events = POLLIN|POLLPRI;
++ g_array_append_val(giop_connection_list.pollset,
++ new_poll);
++# else
++ FD_SET(curfd, &giop_connection_list.selectset_rd);
++ FD_SET(curfd, &giop_connection_list.selectset_ex);
++# endif
++ }
++}
++
++/*
++ * giop_connection_add_to_list
++ *
++ * Inputs: 'cnx' - a GIOPConnection that the user wishes added to the list
++ * Outputs: None
++ *
++ * Side effects: Modifies giop_connection_list
++ * Global data structures used: giop_connection_list
++ * Bugs: Does not check for duplicate additions.
++ *
++ * Description:
++ * Adds a connection to the list of active connections.
++ */
++static void
++giop_connection_add_to_list(GIOPConnection *cnx)
++{
++ g_return_if_fail(cnx->is_valid == FALSE);
++
++ cnx->is_valid = TRUE;
++
++ GET_LOCK(giop_connection_list);
++ giop_connection_list.list = g_list_prepend(giop_connection_list.list, cnx);
++
++ giop_connection_list_recreate();
++
++ RELEASE_LOCK(giop_connection_list);
++
++ if(IIOPAddConnectionHandler)
++ IIOPAddConnectionHandler(cnx);
++
++ giop_connection_ref(cnx);
++}
++
++/*
++ * giop_connection_remove_from_list
++ *
++ * Inputs: 'cnx' - a GIOPConnection that the user wishes
++ * Outputs: None
++ *
++ * Side effects: Modifies giop_connection_list
++ * Global data structures used: giop_connection_list
++ *
++ * Description:
++ * Removes a connection from the list of active connections.
++ * Calls the library user's "I removed connection" handler if it
++ * exists.
++ *
++ * Bugs: Does not check for duplicate removals. This may not be "bad" though.
++ */
++void
++giop_connection_remove_from_list(GIOPConnection *cnx)
++{
++ GList *link;
++
++ GET_LOCK(giop_connection_list);
++
++ link = g_list_find(giop_connection_list.list, cnx);
++
++ if(!link)
++ goto out;
++
++ if(IIOPRemoveConnectionHandler && cnx->is_valid)
++ IIOPRemoveConnectionHandler(cnx);
++
++ giop_connection_list.list = g_list_remove_link(giop_connection_list.list,
++ link);
++ g_list_free_1(link);
++
++ giop_connection_unref(cnx);
++
++ giop_connection_list_recreate();
++ out:
++ RELEASE_LOCK(giop_connection_list);
++}
++
++/************************************************
++ * Routines specific to the IIOP/IPv4 transport *
++ ************************************************/
++
++/*
++ * iiop_init
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: Initializes iiop_unix_socket_list
++ * Global data structures used: iiop_unix_socket_list
++ *
++ * Description: Initializes iiop_unix_socket_list.
++ * Registers Unix domain sockets for
++ * removal at server termination.
++ */
++static void
++iiop_init(void)
++{
++#ifndef __KERNEL__
++ g_atexit(iiop_unlink_unix_sockets);
++#endif
++}
++
++/*
++ * iiop_connection_init
++ *
++ * Inputs: 'connection' - a memory region that needs to be initialized as
++ * an 'IIOPConnection'.
++ *
++ * Side effects: initializes 'connection'
++ *
++ * Description: Performs the IIOP-specific initialization of an
++ * IIOPConnection. giop_connection_init is called.
++ *
++ */
++void
++iiop_connection_init(IIOPConnection *connection,
++ GIOPConnectionClass cnxclass,
++ IIOPConnectionType iioptype)
++{
++ giop_connection_init(GIOP_CONNECTION(connection), cnxclass);
++
++ GIOP_CONNECTION(connection)->connection_type =
++ GIOP_CONNECTION_IIOP;
++
++ GIOP_CONNECTION(connection)->destroy_func =
++ (void (*)(GIOPConnection *))iiop_connection_destroy;
++
++ connection->icnxtype = iioptype;
++}
++
++/*
++ * iiop_connection_from_fd
++ *
++ * Inputs: 'fd' - a file descriptor that attention should be paid to
++ * Outputs: 'fd_cnx' - the created connection
++ *
++ * Description: This is intended to be used on a file descriptor
++ * that has been accept()'d. It creates the connection
++ * and fills in the connection information, then adds
++ * it to the active list.
++ */
++IIOPConnection *
++iiop_connection_from_fd(int fd, IIOPConnection *parent)
++{
++ IIOPConnection *fd_cnx;
++ struct hostent *hent;
++ socklen_t n;
++
++ g_assert(fd >= 0);
++
++ fd_cnx = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(fd_cnx, GIOP_CONNECTION_CLIENT, parent->icnxtype);
++
++ GIOP_CONNECTION(fd_cnx)->fd = fd;
++
++ switch(parent->icnxtype) {
++ case IIOP_IPV4:
++ n = sizeof(struct sockaddr_in);
++ if(getpeername(GIOP_CONNECTION_GET_FD(fd_cnx), (struct sockaddr *)&fd_cnx->u.ipv4.location, &n))
++ {
++ fd_cnx->u.ipv4.hostname = g_strdup("");
++ }
++ else
++ {
++ hent = gethostbyaddr((const char *)&fd_cnx->u.ipv4.location.sin_addr.s_addr, 4, AF_INET);
++ if(hent)
++ {
++ fd_cnx->u.ipv4.hostname = g_strdup(hent->h_name);
++ }
++ else
++ {
++ fd_cnx->u.ipv4.hostname = inet_ntoa(*((struct in_addr *)&fd_cnx->u.ipv4.location.sin_addr));
++ }
++ }
++ break;
++
++ case IIOP_USOCK:
++ n = sizeof(struct sockaddr_un);
++ fd_cnx->u.usock.sun_family = AF_UNIX;
++ getpeername(GIOP_CONNECTION_GET_FD(fd_cnx),
++ (struct sockaddr *)&fd_cnx->u.usock, &n);
++ break;
++
++#ifdef HAVE_IPV6
++ case IIOP_IPV6:
++ n = sizeof(struct sockaddr_in6);
++ getpeername(GIOP_CONNECTION_GET_FD(fd_cnx),
++ (struct sockaddr *)&fd_cnx->u.ipv6.location, &n);
++ hent = gethostbyaddr((const char *)&fd_cnx->u.ipv6.location.sin6_addr,
++ sizeof(fd_cnx->u.ipv6.location.sin6_addr), AF_INET6);
++ fd_cnx->u.ipv6.hostname = g_strdup(hent->h_name);
++ break;
++#endif
++
++ default:
++ g_error("Unsupported connection type %d", parent->icnxtype);
++ }
++
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_from_fd connect [%d]\n",
++ GIOP_CONNECTION_GET_FD(fd_cnx));
++
++ giop_connection_add_to_list(GIOP_CONNECTION(fd_cnx));
++
++ return fd_cnx;
++}
++
++/*
++ * iiop_connection_server
++ *
++ * Outputs: 'server_cnx'
++ *
++ * Description: Creates a special IIOPConnection on which incoming
++ * connections come.
++ */
++IIOPConnection *
++iiop_connection_server(void)
++{
++ struct hostent *hent;
++ char hn_tmp[65];
++ socklen_t n;
++ IIOPConnection *server_cnx = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(server_cnx, GIOP_CONNECTION_SERVER, IIOP_IPV4);
++
++ server_cnx->is_serversock = TRUE;
++ GIOP_CONNECTION(server_cnx)->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
++
++ if(GIOP_CONNECTION_GET_FD(server_cnx) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_server: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ server_cnx->u.ipv4.location.sin_family = AF_INET;
++ server_cnx->u.ipv4.location.sin_addr.s_addr = INADDR_ANY;
++ bind(GIOP_CONNECTION_GET_FD(server_cnx),
++ (struct sockaddr *)&server_cnx->u.ipv4.location,
++ sizeof(struct sockaddr_in));
++
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ n = sizeof(struct sockaddr_in);
++ getsockname(GIOP_CONNECTION_GET_FD(server_cnx),
++ (struct sockaddr *)&server_cnx->u.ipv4.location, &n);
++
++ gethostname(hn_tmp, sizeof(hn_tmp) - 1);
++
++ hent = gethostbyname(hn_tmp);
++ if(hent)
++ {
++ if (strchr (hent->h_name, '.'))
++ server_cnx->u.ipv4.hostname = g_strdup(hent->h_name);
++ else
++ {
++ struct in_addr * addr = (struct in_addr *) hent->h_addr_list[0];
++ g_assert (hent->h_length == sizeof (struct in_addr) && addr);
++ server_cnx->u.ipv4.hostname = g_strdup (inet_ntoa (*addr));
++ }
++ }
++ else
++ server_cnx->u.ipv4.hostname = g_strdup(hn_tmp);
++
++ listen(GIOP_CONNECTION_GET_FD(server_cnx), 5);
++
++ giop_connection_add_to_list(GIOP_CONNECTION(server_cnx));
++
++ return server_cnx;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(server_cnx));
++ GIOP_CONNECTION(server_cnx)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(server_cnx));
++ server_cnx = NULL;
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx
++ RELEASE_LOCK(server_cnx);
++ */
++ return NULL;
++}
++
++/*
++ * iiop_connection_server_ipv6
++ * Outputs: 'server_cnx'
++ *
++ * Description: Create a special IIOPConnection on which incoming
++ * connections come.
++ */
++IIOPConnection *
++iiop_connection_server_ipv6(void)
++{
++#ifdef HAVE_IPV6
++ struct hostent *hent, *hent2;
++
++ char hn_tmp[65];
++ int n;
++ IIOPConnection *server_cnx;
++
++ g_error("IPv6 support is baroquen! (Actually just never worked)");
++
++ server_cnx = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(server_cnx, GIOP_CONNECTION_SERVER, IIOP_IPV6);
++
++ server_cnx->is_serversock = TRUE;
++ GIOP_CONNECTION(server_cnx)->fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
++
++ if(GIOP_CONNECTION_GET_FD(server_cnx) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_server_ipv6: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ server_cnx->u.ipv6.location.sin6_family = AF_INET6;
++ bind(GIOP_CONNECTION_GET_FD(server_cnx),
++ (struct sockaddr *)&server_cnx->u.ipv6.location,
++ sizeof(struct sockaddr_in6));
++
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ n = sizeof(struct sockaddr_in6);
++ getsockname(GIOP_CONNECTION_GET_FD(server_cnx), &server_cnx->u.ipv6.location, &n);
++
++ gethostname(hn_tmp, sizeof(hn_tmp) - 1);
++
++ hent = gethostbyname(hn_tmp);
++ if(hent) {
++ hent2 = gethostbyaddr(hent->h_addr, sizeof(server_cnx->u.ipv6.location.sin6_addr), AF_INET6);
++ if(hent2)
++ server_cnx->hostname = g_strdup(hent2->h_name);
++ else
++ server_cnx->hostname = g_strdup(hn_tmp);
++ } else
++ server_cnx->hostname = g_strdup(hn_tmp);
++
++ listen(GIOP_CONNECTION_GET_FD(server_cnx), 5);
++
++ giop_connection_add_to_list(GIOP_CONNECTION(server_cnx));
++
++ return server_cnx;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(server_cnx));
++ GIOP_CONNECTION(server_cnx)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(server_cnx));
++ server_cnx = NULL;
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx
++ RELEASE_LOCK(server_cnx);
++ */
++#endif
++ return NULL;
++}
++
++/*
++ * iiop_connection_server_unix
++ *
++ * Outputs: 'server_cnx_unix'
++ *
++ * Side effects: Initializes 'server_cnx_unix' if not initialized.
++ *
++ * Description: Return a special IIOPConnection on which incoming connections
++ * come. If not already initialized, it creates the connection,
++ * otherwise it returns the existing one.
++ * This is
++ */
++IIOPConnection *
++iiop_connection_server_unix(const char *sockpath)
++{
++ IIOPConnection *server_cnx_unix;
++
++ g_assert(sockpath && *sockpath);
++
++ server_cnx_unix = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(server_cnx_unix, GIOP_CONNECTION_SERVER, IIOP_USOCK);
++
++ server_cnx_unix->is_serversock = TRUE;
++ GIOP_CONNECTION(server_cnx_unix)->fd = socket(AF_UNIX, SOCK_STREAM, 0);
++
++ if(GIOP_CONNECTION_GET_FD(server_cnx_unix) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_server_unix: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ strcpy(server_cnx_unix->u.usock.sun_path, sockpath);
++
++ server_cnx_unix->u.usock.sun_family = AF_UNIX;
++ if(bind(GIOP_CONNECTION_GET_FD(server_cnx_unix),
++ (struct sockaddr *)&server_cnx_unix->u.usock,
++ SUN_LEN(&server_cnx_unix->u.usock)) != 0) {
++ /* see the comment in iiop_connection_destroy switch as to why we
++ close it here. bad hack */
++ close(GIOP_CONNECTION_GET_FD(server_cnx_unix));
++ GIOP_CONNECTION(server_cnx_unix)->fd = -1;
++ goto failed;
++ }
++
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ if(listen(GIOP_CONNECTION_GET_FD(server_cnx_unix), 5) != 0)
++ goto failed;
++
++ giop_connection_add_to_list(GIOP_CONNECTION(server_cnx_unix));
++ iiop_unix_socket_list = g_slist_prepend(iiop_unix_socket_list,
++ server_cnx_unix);
++
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx_unix
++ RELEASE_LOCK(server_cnx_unix);
++ */
++
++ return server_cnx_unix;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(server_cnx_unix));
++ GIOP_CONNECTION(server_cnx_unix)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(server_cnx_unix));
++ server_cnx_unix = NULL;
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx_unix
++ RELEASE_LOCK(server_cnx_unix);
++ */
++ return NULL;
++}
++
++/*
++ * iiop_unlink_unix_sockets(void)
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: Modifies iiop_unix_socket_list
++ * Global data structures used: iiop_unix_socket_list
++ *
++ * Description:
++ * Unlinks any Unix server sockets created.
++ * Called during program termination.
++ */
++static void
++iiop_unlink_unix_sockets(void)
++{
++ GSList *item;
++
++ for (item = iiop_unix_socket_list;
++ item; item = g_slist_next(item)) {
++ GIOPConnection *cnx;
++
++ cnx = GIOP_CONNECTION(item->data);
++ if(cnx->connection_class == GIOP_CONNECTION_SERVER)
++ unlink(IIOP_CONNECTION(cnx)->u.usock.sun_path);
++ }
++
++ if (iiop_unix_socket_list) {
++ g_slist_free(iiop_unix_socket_list);
++ iiop_unix_socket_list = NULL;
++ }
++}
++
++/*
++ * iiop_connection_get
++ *
++ * Inputs: 'host' - the hostname (or dotted quad) of the remote host that
++ * will be connected
++ * 'port' - the port number on the above host to connect to.
++ * 'existing_only' - don't create a new connection if
++ * an existing one with the specified host:port
++ * doesn't exist.
++ *
++ * Outputs: 'cnx' - the connection to the specified host:port, or
++ * NULL upon error.
++ *
++ * Description: Returns an IIOPConnection that is connected to the
++ * specified host:port. If a connection already exists to the
++ * host:port, just returns it. Otherwise, calls
++ * 'iiop_connection_new' to create a new connection
++ * to host:port.
++ */
++IIOPConnection *
++iiop_connection_get(const char *host, gushort port, gboolean existing_only)
++{
++ IIOPConnection *cnx = NULL, *tmp;
++ GList *link;
++
++ g_assert(host);
++ g_assert(port);
++
++ GET_LOCK(giop_connection_list);
++ for(link = giop_connection_list.list; link; link = link->next)
++ {
++ tmp = IIOP_CONNECTION(link->data);
++ if(GIOP_CONNECTION(tmp)->connection_type != GIOP_CONNECTION_IIOP)
++ continue;
++
++ if(!GIOP_CONNECTION(tmp)->is_valid)
++ continue;
++
++ if(GIOP_CONNECTION(tmp)->connection_class != GIOP_CONNECTION_CLIENT)
++ continue;
++
++ if(IIOP_CONNECTION(tmp)->icnxtype != IIOP_IPV4)
++ continue;
++
++ if(!strcmp(host, tmp->u.ipv4.hostname)
++ && htons(port) == tmp->u.ipv4.location.sin_port) {
++ cnx = tmp;
++ break;
++ }
++ }
++ RELEASE_LOCK(giop_connection_list);
++
++ if(!cnx && !existing_only)
++ cnx = iiop_connection_new(host, port);
++
++ return cnx;
++}
++
++
++/*
++ * iiop_connection_new
++ *
++ * Inputs: same meanings as in 'iiop_connection_get'
++ * Outputs: 'retval' - newly created IIOPConnection
++ *
++ * Description: Allocates and initializes a new IIOPConnection,
++ * turns 'host' into an IP address, and then makes a TCP
++ * connection to host:port. Adds it to the list of active
++ * connections.
++ */
++IIOPConnection *
++iiop_connection_new(const char *host, gushort port)
++{
++ IIOPConnection *retval;
++
++ g_return_val_if_fail(host != NULL && port != 0, NULL);
++
++ retval = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(retval, GIOP_CONNECTION_CLIENT, IIOP_IPV4);
++
++ GIOP_CONNECTION(retval)->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
++ if(GIOP_CONNECTION_GET_FD(retval) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ retval->u.ipv4.hostname = g_strdup(host);
++
++ retval->u.ipv4.location.sin_port = htons(port);
++ retval->u.ipv4.location.sin_family = AF_INET;
++ if(!inet_aton(host, &retval->u.ipv4.location.sin_addr))
++ {
++ struct hostent *hent;
++ hent = gethostbyname(host);
++ if(!hent) {
++ /* a (char *)h_strerror(int) function would be nice here */
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: gethostbyname error: %d\n", h_errno);
++ goto failed;
++ }
++ memcpy(&retval->u.ipv4.location.sin_addr, hent->h_addr, (size_t) sizeof(retval->u.ipv4.location.sin_addr));
++ }
++ if(connect(GIOP_CONNECTION_GET_FD(retval), (struct sockaddr *)&retval->u.ipv4.location, sizeof(retval->u.ipv4.location)) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: connect error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_new connect [%d] to %s:%d\n",
++ GIOP_CONNECTION_GET_FD(retval),
++ host, (guint)port);
++
++
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFD, FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ GIOP_CONNECTION(retval)->was_initiated = TRUE;
++ GIOP_CONNECTION(retval)->is_auth = TRUE;
++
++ giop_connection_add_to_list(GIOP_CONNECTION(retval));
++
++ return retval;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(retval));
++ GIOP_CONNECTION(retval)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(retval));
++ return NULL;
++}
++
++/*
++ * iiop_connection_unix_get
++ *
++ * Inputs: 'sockpath' - Of the format 'path'
++ *
++ * Outputs: 'cnx' - the connection to the specified path, or
++ * NULL upon error.
++ *
++ * Description: Returns an IIOPConnection that is connected to the
++ * specified UNIX socket, if possible. If a connection
++ * already exists, just returns it. Otherwise,
++ * calls 'iiop_connection_unix_new' to create a new
++ * connection to sockpath.
++ */
++IIOPConnection *
++iiop_connection_unix_get(const char *sockpath, gboolean existing_only)
++{
++ IIOPConnection *cnx = NULL, *tmp;
++ GList *link;
++
++ GET_LOCK(giop_connection_list);
++ for(link = giop_connection_list.list; link; link = link->next)
++ {
++ tmp = IIOP_CONNECTION(link->data);
++
++ if(GIOP_CONNECTION(tmp)->connection_type != GIOP_CONNECTION_IIOP)
++ continue;
++
++ if(!GIOP_CONNECTION(tmp)->is_valid)
++ continue;
++
++ if(GIOP_CONNECTION(tmp)->connection_class != GIOP_CONNECTION_CLIENT)
++ continue;
++
++ if(IIOP_CONNECTION(tmp)->icnxtype != IIOP_USOCK)
++ continue;
++
++ if(!strcmp(sockpath, tmp->u.usock.sun_path)) {
++ cnx = tmp;
++ break;
++ }
++ }
++ RELEASE_LOCK(giop_connection_list);
++
++ if(!cnx && !existing_only)
++ cnx = iiop_connection_unix_new(sockpath);
++
++ return cnx;
++}
++
++/*
++ * iiop_connection_unix_new
++ *
++ * Inputs:
++ *
++ * Outputs: 'retval' - newly created IIOPConnection, or NULL upon error
++ *
++ * Description: Creates a connection to a UNIX socket (if possible)
++ * Adds it to the list of active connections.
++ */
++static IIOPConnection *
++iiop_connection_unix_new(const char *sockpath)
++{
++ IIOPConnection *retval;
++
++ retval = g_new0(IIOPConnection, 1);
++
++ retval->u.usock.sun_family = AF_UNIX;
++
++ g_snprintf(retval->u.usock.sun_path,
++ sizeof(retval->u.usock.sun_path), "%s", sockpath);
++
++ iiop_connection_init(retval, GIOP_CONNECTION_CLIENT, IIOP_USOCK);
++
++ GIOP_CONNECTION(retval)->fd = socket(AF_UNIX, SOCK_STREAM, 0);
++ if(GIOP_CONNECTION_GET_FD(retval) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ if(connect(GIOP_CONNECTION_GET_FD(retval), (struct sockaddr *)&retval->u.usock, SUN_LEN(&retval->u.usock)) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: connect error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ GIOP_CONNECTION(retval)->was_initiated = TRUE;
++ GIOP_CONNECTION(retval)->is_auth = TRUE;
++
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFD, FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ giop_connection_add_to_list(GIOP_CONNECTION(retval));
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_unix_new connect [%d] to %s\n",
++ GIOP_CONNECTION_GET_FD(retval),
++ sockpath);
++
++ return retval;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(retval));
++ GIOP_CONNECTION(retval)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(retval));
++ return NULL;
++}
++
++/*
++ * iiop_connection_server_accept
++ * Inputs: 'connection' - a server IIOPConnection.
++ *
++ * Description: Performs accept(), TCP wrapper, access checking and related
++ * duties on a connection
++ */
++int allow_severity = LOG_INFO, deny_severity = LOG_NOTICE;
++
++#if defined(HAVE_HOSTS_ACCESS) && defined(HAVE_TCPD_H)
++DEFINE_LOCK(tcp_wrappers_usage);
++
++#endif
++static void
++iiop_connection_server_accept(GIOPConnection *connection)
++{
++ struct sockaddr sock;
++ socklen_t n;
++ int newfd;
++ GIOPConnection *newcnx;
++
++// printk("iiop_conncetion_server_accept( %d )\n",
++// GIOP_CONNECTION_GET_FD(connection));
++
++ n = sizeof(sock);
++
++ switch(IIOP_CONNECTION(connection)->icnxtype) {
++ case IIOP_IPV4: sock.sa_family = AF_INET; break;
++ case IIOP_USOCK: sock.sa_family = AF_UNIX; break;
++ case IIOP_IPV6:
++#ifdef HAVE_IPV6
++ sock.sa_family = AF_INET6;
++#endif
++ break;
++ }
++
++ newfd = accept(GIOP_CONNECTION_GET_FD(connection), &sock, &n);
++
++#if defined(HAVE_HOSTS_ACCESS) && defined(HAVE_TCPD_H)
++ /* tcp wrappers access checking */
++ switch(IIOP_CONNECTION(connection)->icnxtype) {
++ case IIOP_IPV4:
++ {
++ struct request_info request;
++
++ GET_LOCK(tcp_wrappers_usage);
++
++ request_init(&request, RQ_DAEMON, argv0_val, RQ_FILE, newfd, 0);
++
++ fromhost(&request);
++ if(!hosts_access(&request)) {
++ syslog(deny_severity, "[orbit] refused connect from %s", eval_client(&request));
++ close(newfd); newfd = -1;
++ } else
++ syslog(allow_severity, "[orbit] connect from %s", eval_client(&request));
++
++ RELEASE_LOCK(tcp_wrappers_usage);
++ }
++ break;
++ default:
++ /* No access controls for these transports */
++ break;
++ }
++#endif
++
++ if(newfd >= 0) {
++ newcnx = GIOP_CONNECTION(iiop_connection_from_fd(newfd,
++ IIOP_CONNECTION(connection)));
++ GIOP_CONNECTION(newcnx)->orb_data = connection->orb_data;
++ switch(IIOP_CONNECTION(connection)->icnxtype) {
++ case IIOP_USOCK: newcnx->is_auth = TRUE; break;
++ default:
++ break;
++ }
++ }
++}
++
++/*
++ * iiop_connection_destroy
++ *
++ * Inputs: 'iiop_connection' - an IIOPConnection to be finalized
++ *
++ * Side effects: invalidates 'iiop_connection' for use as an IIOPConnection
++ *
++ * Description: Performs the IIOP-specific parts of connection shutdown,
++ * including sending a CLOSECONNECTION message to the remote side.
++ */
++static void
++iiop_connection_destroy(IIOPConnection *iiop_connection)
++{
++ const GIOPMessageHeader mh = {"GIOP", {1,0}, FLAG_ENDIANNESS,
++ GIOP_CLOSECONNECTION, 0};
++
++ switch(iiop_connection->icnxtype) {
++ case IIOP_IPV4:
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_destroy connect [%d] of %s:%d\n",
++ GIOP_CONNECTION_GET_FD(iiop_connection),
++ iiop_connection->u.ipv4.hostname,
++ ntohs(iiop_connection->u.ipv4.location.sin_port));
++ g_free(iiop_connection->u.ipv4.hostname);
++ break;
++ case IIOP_IPV6:
++#ifdef HAVE_IPV6
++ g_free(iiop_connection->u.ipv6.hostname);
++#else
++ g_warning("IPv6 unsupported, can't free it!");
++#endif
++ break;
++ case IIOP_USOCK:
++ /* why do we check if fd is > 0 here?
++ the orb code tries to reuse existing socket connection points.
++ If binding to any of those fails because another process is using it,
++ we don't want to unlink the other server's socket!
++ if the bind fails, iiop_connection_server_unix closes the fd for us */
++ if(GIOP_CONNECTION(iiop_connection)->connection_class == GIOP_CONNECTION_SERVER
++ && GIOP_CONNECTION(iiop_connection)->fd >= 0)
++ unlink(iiop_connection->u.usock.sun_path);
++ break;
++ default:
++ break;
++ }
++
++ if(GIOP_CONNECTION_GET_FD(iiop_connection) >= 0) {
++ if(GIOP_CONNECTION(iiop_connection)->is_valid
++ && !GIOP_CONNECTION(iiop_connection)->was_initiated)
++ {
++ write(GIOP_CONNECTION_GET_FD(iiop_connection), &mh, sizeof(mh));
++ }
++
++ shutdown(GIOP_CONNECTION_GET_FD(iiop_connection), 2);
++ close(GIOP_CONNECTION_GET_FD(iiop_connection));
++ GIOP_CONNECTION(iiop_connection)->fd = -1;
++ }
++}
++
++static int giop_nloops = 0;
++
++void giop_main_quit(void) { giop_nloops--; }
++
++void
++giop_main(void)
++{
++ int looplevel;
++
++ looplevel = ++giop_nloops;
++
++ while(giop_nloops > 0) {
++
++ giop_main_iterate(TRUE);
++
++ if(giop_nloops != looplevel) {
++ giop_nloops = --looplevel;
++ return;
++ }
++ }
++}
++
++GIOPRecvBuffer *
++giop_main_next_message(gboolean blocking)
++{
++ return giop_main_next_message_2(blocking, NULL);
++}
++
++GIOPRecvBuffer *
++giop_main_next_message_2(gboolean blocking,
++ GIOPConnection *monitor)
++{
++ GIOPConnection *connection;
++ GIOPRecvBuffer *recv_buffer = NULL;
++
++ do {
++ recv_buffer = giop_received_list_pop();
++// printk("giop_main_next_message_2 : recv_buffer = 0x%08X\n", recv_buffer);
++ if(recv_buffer)
++ break;
++
++ connection = giop_check_connections(blocking);
++// printk("giop_main_next_message_2 : connection = 0x%08X\n", connection);
++ if(!connection)
++ {
++ return NULL;
++ }
++
++ if(GIOP_CONNECTION_GET_FD(connection) < 0) {
++ g_assert(!"connection has -ve fd!");
++ }
++
++// printk("giop_main_next_message_2 : connection class = %d\n",
++// connection->connection_class);
++ if(connection->connection_class == GIOP_CONNECTION_SERVER)
++ iiop_connection_server_accept(connection);
++ else
++ recv_buffer = giop_recv_message_buffer_use(connection);
++
++ if(monitor && !monitor->is_valid)
++ {
++ return NULL;
++ }
++
++ } while(!recv_buffer);
++
++ return recv_buffer;
++}
++
++void
++giop_main_handle_connection(GIOPConnection *connection)
++{
++ GIOPRecvBuffer *recv_buffer;
++
++ //printk("giop_main_handle_connection\n");
++
++ g_return_if_fail(connection != NULL);
++ g_return_if_fail(connection->is_valid);
++
++ if(connection->connection_class == GIOP_CONNECTION_SERVER) {
++ iiop_connection_server_accept(connection);
++ return;
++ } else
++ recv_buffer = giop_recv_message_buffer_use(connection);
++
++ if(recv_buffer) {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(recv_buffer);
++ else
++ giop_received_list_push(recv_buffer);
++ }
++}
++
++/*
++ * giop_main_handle_connection_exception
++ *
++ * Input: GIOPConnection *connection
++ *
++ * Output:
++ *
++ * Side effects: invalidates connection
++ *
++ * Description:
++ * When poll() or select() indicates that a file descriptor
++ * has been closed at the remote end, we must invalidate the associated
++ * GIOPConnection structure.
++ */
++void
++giop_main_handle_connection_exception(GIOPConnection *connection)
++{
++ g_return_if_fail(connection != NULL);
++ g_return_if_fail(connection->is_valid);
++
++// printk("giop_main_handle_connection_exception(0x%X)\n", GIOP_CONNECTION_GET_FD(connection));
++
++ giop_connection_ref(connection);
++
++ giop_connection_remove_from_list(connection);
++
++ shutdown(GIOP_CONNECTION_GET_FD(connection), 2);
++ close(GIOP_CONNECTION_GET_FD(connection));
++ GIOP_CONNECTION(connection)->fd = -1;
++ connection->is_valid = FALSE;
++
++ if(connection->incoming_msg) {
++ giop_recv_buffer_unuse(connection->incoming_msg);
++ connection->incoming_msg = NULL;
++ }
++
++ giop_connection_unref(connection);
++}
++
++/*
++ * giop_main_iterate
++ *
++ * Input: 'blocking' - flag to indicate whether to wait for incoming
++ * messages (TRUE), or whether to return immediately if no
++ * incoming messages are available (FALSE).
++ * Output: None
++ * Description:
++ * Gets the next message into recv_buffer (see
++ * giop_main_next_message) If we have a handler for incoming
++ * messages, then pass recv_buffer to the handler (handler
++ * becomes the new owner of recv_buffer's contents). Otherwise,
++ * tosses it onto the list of received-but-unprocessed buffers.
++ *
++ * Warnings:
++ * If you don't have an IIOPIncomingMessageHandler set, you're
++ * probably really screwed in the long run.
++ */
++void
++giop_main_iterate(gboolean blocking)
++{
++ GIOPRecvBuffer *recv_buffer;
++
++// printk("giop_main_iterate: blocking: %d\n", blocking);
++schedule();
++
++ recv_buffer = giop_main_next_message(blocking);
++
++// printk("giop_main_iterate: recv_buffer = 0x%08X\n", recv_buffer);
++
++ if(recv_buffer) {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(recv_buffer);
++ else
++ giop_received_list_push(recv_buffer);
++ }
++}
++
++/*
++ * giop_check_connections
++ *
++ * Inputs: 'block_for_reply' - If no incoming data is immediately available
++ * should this routine wait for incoming data (TRUE) or return
++ * immediately (FALSE).
++ *
++ * Outputs: 'connection' - the first connection that has incoming
++ * data available for reading (supposedly a GIOP message, but
++ * could be anything).
++ *
++ * Side effects: Removes closed connections from the active list.
++ *
++ * Global data structures used: giop_connection_list
++ *
++ * Description: Does a poll or select (OS-dependant) on the list of file
++ * descriptors in giop_connection_list.
++ *
++ * If a file descriptor has been closed, call
++ * giop_connection_handle_exception() on it and (as
++ * appropriated by 'block_for_reply') either return
++ * NULL or do another poll/select.
++ *
++ * If a file descriptor has data available for
++ * reading, find the associated GIOPConnection (using
++ * giop_connection_list.fd_to_connection_mapping) and
++ * return that.
++ *
++ */
++GIOPConnection *
++giop_check_connections(gboolean block_for_reply)
++{
++ GIOPConnection *connection = NULL;
++ int pollret;
++ int numcnx_checks;
++ int i;
++#ifndef USE_POLL
++ fd_set selectset_rd, selectset_ex;
++
++ struct timeval immediate_timeout = {0,0};
++#endif
++
++// printk("giop_check_connections\n");
++
++ do_read_msg:
++
++ if(!giop_connection_list.list)
++ {
++// printk("giop_check_connections : list = NULL\n");
++ BUG();
++ return NULL;
++ }
++
++#if 0
++ giop_connection_list_recreate(); /* easiest way to get valid
++ select sets... */
++#endif
++
++#ifdef USE_POLL
++ numcnx_checks = giop_connection_list.pollset->len;
++#else
++ memcpy(&selectset_rd, &giop_connection_list.selectset_rd,
++ sizeof(selectset_rd));
++ memcpy(&selectset_ex, &giop_connection_list.selectset_ex,
++ sizeof(selectset_ex));
++
++ numcnx_checks = giop_connection_list.max_fd+1;
++#endif
++
++ restart:
++#ifdef USE_POLL
++ pollret = poll((struct pollfd *)giop_connection_list.pollset->data,
++ giop_connection_list.pollset->len,
++ block_for_reply?-1:0);
++
++#if KORBIT_DEBUG_WRITING
++{
++ int ix;
++ struct pollfd *fds = (struct pollfd *)giop_connection_list.pollset->data;
++// printk("back from poll(#fds = %d, block = %d) = %d)\n", giop_connection_list.pollset->len, block_for_reply, pollret);
++// for (ix = 0; ix < giop_connection_list.pollset->len; ix++)
++ // printk(" [fd = 0x%X, event = 0x%X, revent = 0x%X]\n",
++// fds[ix].fd, fds[ix].events, fds[ix].revents);
++
++}
++#endif /* KORBIT_DEBUG_WRITING */
++
++
++# else /* !USE_POLL */
++
++ {
++ pollret = select (giop_connection_list.max_fd + 1,
++ &selectset_rd,
++ NULL, &selectset_ex,
++ block_for_reply?NULL:&immediate_timeout);
++ }
++# endif /* !USE_POLL */
++
++// printk("giop_check_connections : pollret == %d\n", pollret);
++ if(pollret <= 0) {
++ if(pollret < 0) {
++ if(errno == EINTR)
++ goto restart;
++ else
++ g_warning("Error code from select/poll: %s", g_strerror(errno));
++ } else
++ return NULL;
++ }
++
++ /* Check for data to be read on the fd's.
++ Note we have to do the hangup/exception checking in a separate loop,
++ because there may be data waiting to be read on a connection that the
++ other end has closed. */
++ for(i = 0; i < numcnx_checks; i++) {
++ struct fd_hash_elem *el;
++
++#ifdef USE_POLL
++ struct pollfd *p =
++ &g_array_index(giop_connection_list.pollset,
++ struct pollfd,
++ i);
++ g_assert(p->fd <= giop_connection_list.max_fd);
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[p->fd];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &(p->fd));
++ if (el)
++ connection = el->cnx;
++#endif
++ if(p->revents & POLLIN)
++ goto got_connection;
++#else
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[i];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &i);
++ if (el)
++ connection = el->cnx;
++#endif
++ if (FD_ISSET(i, &selectset_rd)) {
++ goto got_connection;
++ }
++#endif
++ }
++
++ /* Handle fd exceptions */
++ for(i = 0; i < numcnx_checks; i++)
++ {
++ struct fd_hash_elem *el;
++#ifdef USE_POLL
++ struct pollfd *p =
++ &g_array_index(giop_connection_list.pollset,
++ struct pollfd,
++ i);
++
++ g_assert(p->fd <= giop_connection_list.max_fd);
++ if(p->revents & (POLLHUP|POLLNVAL)) {
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[p->fd];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &(p->fd));
++ if (el)
++ connection = el->cnx;
++#endif
++ giop_main_handle_connection_exception(connection);
++ }
++#else /* !USE_POLL */
++ if(FD_ISSET(i, &selectset_ex)) {
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[i];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &i);
++ if (el)
++ connection = el->cnx;
++#endif
++ giop_main_handle_connection_exception(connection);
++ }
++#endif /* !USE_POLL */
++ }
++
++ /* Only reached if we didn't find a connection to read data from */
++ if(block_for_reply)
++ goto do_read_msg;
++
++ got_connection:
++// printk("giop_check_connections : got connection\n");
++ return connection;
++}
++
+diff -urN linux-2.4.1/net/korbit/IIOP/encoders.c linux-2.4.1-korbit/net/korbit/IIOP/encoders.c
+--- linux-2.4.1/net/korbit/IIOP/encoders.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/encoders.c Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,46 @@
++#include "config.h"
++#include <string.h>
++#include "IIOP.h"
++
++ENCODER_DEC(IOP_ServiceContext)
++{
++ APA(&mem->context_id, sizeof(mem->context_id));
++ ENCODER_CALL(CORBA_sequence_octet, &mem->context_data);
++}
++
++ENCODER_DEC(IOP_ServiceContextList)
++{
++ int i;
++
++ if(!mem)
++ {
++ APA((gpointer)giop_scratch_space, sizeof(mem->_length));
++ return;
++ }
++
++ APA(&mem->_length, sizeof(mem->_length));
++
++ for(i = 0; i < mem->_length; i++)
++ ENCODER_CALL(IOP_ServiceContext, &mem->_buffer[i]);
++}
++
++ENCODER_DEC(CORBA_sequence_octet)
++{
++ if(!mem)
++ {
++ APA((gpointer)giop_scratch_space, sizeof(mem->_length));
++ return;
++ }
++
++ APIA(&mem->_length, sizeof(mem->_length));
++ if(mem->_length > 0)
++ AP(mem->_buffer, mem->_length);
++}
++
++ENCODER_DEC(CORBA_char)
++{
++ GIOP_unsigned_long len = strlen(mem) + 1;
++
++ APIA(&len, sizeof(len));
++ AP(mem, len);
++}
+diff -urN linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.c linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.c
+--- linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.c Fri Feb 2 01:23:46 2001
+@@ -0,0 +1,1443 @@
++/* The big picture:
++ * For every outgoing request, we have to have the network-ready data
++ * somewhere in memory.
++ *
++ * Using writev, any pieces that do not need endian conversion can
++ * be written in-place.
++ *
++ * The pieces that do need endian conversion can be put into one or more
++ * buffers.
++ *
++ * WHOA WHOA newsflash
++ * Because IIOP lets the message sender specify the endianness,
++ * we do not need to do endian conversion _ever_! The receiver can do all
++ * conversions if need be, or if they are the same endianness as sender they
++ * can just pull it in right off the wire :)
++ *
++ */
++
++#include "config.h"
++#include "iiop-endianP.h"
++#include <string.h>
++#include <unistd.h>
++#include <stdio.h>
++#include <errno.h>
++#include <sys/types.h>
++#include <fcntl.h>
++#include <string.h>
++
++#ifdef HAVE_POLL
++# include <sys/poll.h>
++#else
++# include <sys/types.h>
++# include <sys/time.h>
++#endif
++#include "IIOP.h"
++#include "IIOP-private.h"
++
++#ifdef HAVE_LIMITED_WRITEV
++#define writev g_writev
++#endif
++
++/*
++#ifdef O_NONBLOCK
++#undef O_NONBLOCK
++#endif
++#define O_NONBLOCK 0
++*/
++
++
++/* type defs */
++
++#ifdef __GNUC__
++#define PACKED __attribute__((packed))
++#else
++#define PACKED
++#endif
++
++/*
++ * Overlaps with struct _GIOPMessageHeader on purpose
++ * - we save time because this stuff never changes
++ */
++struct _GIOPMessageHeaderConstants {
++ GIOP_char magic[4];
++ GIOP_char GIOP_version[2];
++ GIOP_octet flags;
++} PACKED;
++
++/* functions */
++static gint giop_recv_decode_message(GIOPRecvBuffer *buf);
++static gboolean num_on_list(GIOP_unsigned_long num,
++ const GIOP_unsigned_long *request_ids,
++ GIOP_unsigned_long req_count);
++static gint giop_recv_reply_decode_message(GIOPRecvBuffer *buf);
++static gint giop_recv_request_decode_message(GIOPRecvBuffer *buf);
++static gint giop_recv_locate_reply_decode_message(GIOPRecvBuffer *buf);
++static gint giop_recv_locate_request_decode_message(GIOPRecvBuffer *buf);
++static GIOPRecvBuffer *giop_received_list_check_reply(GIOP_unsigned_long request_id);
++
++#ifdef NOT_REENTRANT
++extern DEFINE_LOCK(iiop_connection_list);
++#endif
++GList *iiop_connection_list = NULL;
++
++/* global variables */
++char giop_scratch_space[2048];
++
++static const struct _GIOPMessageHeaderConstants
++giop_message_header_constants = {
++ "GIOP",
++ {1,0},
++ FLAG_ENDIANNESS,
++};
++
++struct iovec
++giop_first_message_vec = {NULL,
++ sizeof(struct _GIOPMessageHeaderConstants)};
++
++DEFINE_LOCK(sendbufferlist);
++GSList *sendbufferlist = NULL;
++
++DEFINE_LOCK(recvbufferlist);
++GSList *recvbufferlist = NULL;
++
++DEFINE_LOCK(incoming_bufs);
++GList *incoming_bufs = NULL; /* List of incoming messages that had to be
++ shunted aside */
++
++DEFINE_LOCK(sendbuffers);
++DEFINE_LOCK(recvbuffers);
++GMemChunk *sendbuffers = NULL, *recvbuffers = NULL;
++
++DEFINE_LOCK(request_id_counter);
++GIOP_unsigned_long request_id_counter;
++
++#if 0
++inline
++void giop_message_buffer_append_iovec(GIOPMessageBuffer *msgbuf,
++ const struct iovec *iovec)
++{
++ /* g_print("Appending iovec %d bytes @ %p\n", iovec->iov_len, iovec->iov_base); */
++ g_array_append_val(msgbuf->iovecs, *iovec);
++}
++#else
++#define giop_message_buffer_append_iovec(msgbuf, iovec) g_array_append_val((msgbuf)->iovecs, *(iovec))
++#endif
++
++void
++giop_message_buffer_init(void)
++{
++ giop_first_message_vec.iov_base = (gpointer)&giop_message_header_constants;
++ INIT_LOCK(sendbufferlist);
++ INIT_LOCK(recvbufferlist);
++ request_id_counter = 1;
++ INIT_LOCK(request_id_counter);
++
++ INIT_LOCK(sendbuffers);
++ sendbuffers = g_mem_chunk_create(GIOPSendBuffer, 2, G_ALLOC_ONLY);
++ INIT_LOCK(recvbuffers);
++ recvbuffers = g_mem_chunk_create(GIOPRecvBuffer, 2, G_ALLOC_ONLY);
++}
++
++static void
++giop_message_buffer_new(GIOPMessageBuffer *buf)
++{
++ buf->iovecs = g_array_new(FALSE, FALSE, sizeof(struct iovec));
++}
++
++#define STRUCT_OFFSET(t, f) ((int) ((char*) &((t*) 0)->f))
++
++/* Send buffers only */
++static GIOPSendBuffer *
++giop_send_buffer_new(void)
++{
++ GIOPSendBuffer *msgbuf;
++ struct iovec firstvec;
++
++ GET_LOCK(sendbuffers);
++ msgbuf = g_chunk_new(GIOPSendBuffer, sendbuffers);
++ RELEASE_LOCK(sendbuffers);
++
++ giop_message_buffer_new(GIOP_MESSAGE_BUFFER(msgbuf));
++
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(msgbuf),
++ &giop_first_message_vec);
++
++ firstvec.iov_base = &(GIOP_MESSAGE_BUFFER(msgbuf)->message_header.message_type);
++ firstvec.iov_len = sizeof(GIOPMessageHeader)
++ - STRUCT_OFFSET(GIOPMessageHeader, message_type);
++ GIOP_MESSAGE_BUFFER(msgbuf)->message_header.message_size = 0;
++
++ msgbuf->indirects = g_mem_chunk_create(char[GIOP_INDIRECT_CHUNK_SIZE],
++ 2, G_ALLOC_ONLY);
++
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(msgbuf), &firstvec);
++
++ return msgbuf;
++}
++
++gint
++giop_send_buffer_write(GIOPSendBuffer *send_buffer)
++{
++ gulong nvecs;
++ glong res, sum, t;
++ struct iovec *curvec;
++ int fd;
++ GIOPConnection *cnx;
++ gint retval = -1;
++
++// printf("giop_send_buffer_write\n");
++
++ cnx = GIOP_MESSAGE_BUFFER(send_buffer)->connection;
++ if(!cnx->is_valid)
++ return -1;
++
++ fd = GIOP_CONNECTION_GET_FD(cnx);
++ nvecs = GIOP_MESSAGE_BUFFER(send_buffer)->iovecs->len;
++ curvec = (struct iovec *)GIOP_MESSAGE_BUFFER(send_buffer)->iovecs->data;
++
++#if defined(ORBIT_DEBUG) && 0
++ g_print("Message of length %d looks like:\n",
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size);
++{ int i = 0;
++ for(sum = 0; i < nvecs; i++) {
++ sum += curvec[i].iov_len;
++ g_print(" [%p, %d]: %d\n", curvec[i].iov_base, curvec[i].iov_len,
++ sum);
++ }
++}
++#endif
++
++ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
++ res = writev(fd, curvec, nvecs);
++// printk("writev wrote %d byte\n", res);
++
++ sum = (GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size + sizeof(GIOPMessageHeader));
++ if(res < sum) {
++ if(res < 0) {
++//printf("writev returned %d\n", res);
++ if(errno != EAGAIN) {
++ giop_main_handle_connection_exception(cnx);
++ goto out;
++ }
++
++ res = 0;
++ }
++
++ /* wrote 7, iovecs 3, 2, 2, 4:
++ 0 + 3 !> 7
++ 3 + 2 !> 7
++ 5 + 2 !> 7
++ */
++
++ for(t = 0; ; t += curvec->iov_len, curvec++, nvecs--) {
++ if((t + curvec->iov_len) > res)
++ break;
++ }
++ if((res - t) > 0) {
++ curvec->iov_len -= (res - t);
++ curvec->iov_base = (gpointer)((char *)curvec->iov_base + (res - t));
++ }
++
++
++ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
++ t = writev(fd, curvec, nvecs);
++
++ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
++
++ if((t < 0) || ((res + t) < sum)) {
++//printf("crap, t = %d res = %d sum = %d\n", t, res, sum);
++ giop_main_handle_connection_exception(cnx);
++ goto out;
++ }
++ }
++
++ retval = 0;
++
++ out:
++
++ return retval;
++}
++
++static GIOPSendBuffer *
++giop_send_buffer_use(GIOPConnection *connection)
++{
++ GIOPSendBuffer *retval;
++
++ if(!connection->is_valid)
++ return NULL;
++
++ GET_LOCK(sendbufferlist);
++
++ if(sendbufferlist)
++ {
++ GSList *head;
++
++ retval = sendbufferlist->data;
++
++ head = sendbufferlist;
++ sendbufferlist = g_slist_remove_link(sendbufferlist, sendbufferlist);
++ g_slist_free_1 (head);
++
++ g_array_set_size(GIOP_MESSAGE_BUFFER(retval)->iovecs, 2);
++ GIOP_MESSAGE_BUFFER(retval)->message_header.message_size = 0;
++ }
++ else
++ retval = giop_send_buffer_new();
++
++ RELEASE_LOCK(sendbufferlist);
++
++ giop_connection_ref(connection);
++ GIOP_MESSAGE_BUFFER(retval)->connection = connection;
++
++ g_mem_chunk_reset(retval->indirects);
++ retval->indirect = g_chunk_new(gpointer, retval->indirects);
++#ifdef ORBIT_DEBUG
++ memset(retval->indirect, '\xFE', GIOP_INDIRECT_CHUNK_SIZE);
++#endif
++ retval->indirect_used = 0;
++
++ return retval;
++}
++
++GIOPSendBuffer *
++giop_send_reply_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOPReplyStatusType reply_status)
++{
++ GIOPSendBuffer *send_buffer;
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if(!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_REPLY;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ if(!service_context) {
++ static const GIOP_unsigned_long sc_zero_int = 0;
++ AP(&sc_zero_int, sizeof(service_context->_length));
++ } else {
++ int i, n;
++ n = service_context->_length;
++ AP(&service_context->_length, sizeof(service_context->_length));
++ for(i = 0; i < n; i++) {
++ int j, o;
++ CORBA_sequence_octet *seqo;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&service_context->_buffer[i].context_id,
++ sizeof(service_context->_buffer[i].context_id));
++ seqo = &service_context->_buffer[i].context_data;
++ o = seqo->_length;
++ AP(&seqo->_length, sizeof(GIOP_unsigned_long));
++ for(j = 0; j < o; j++)
++ AP(seqo->_buffer, seqo->_length);
++ }
++ }
++ send_buffer->message.u.reply.request_id = request_id;
++ send_buffer->message.u.reply.reply_status = reply_status;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.reply.request_id,
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.reply.reply_status,
++ sizeof(GIOP_unsigned_long));
++
++ return send_buffer;
++}
++
++GIOPSendBuffer *
++giop_send_locate_reply_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ GIOPLocateStatusType locate_reply_status)
++{
++ GIOPSendBuffer *send_buffer;
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if(!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_LOCATEREPLY;
++
++ APIA(&request_id, sizeof(request_id));
++ APIA(&locate_reply_status, sizeof(locate_reply_status));
++
++ return send_buffer;
++}
++
++GIOPSendBuffer *
++giop_send_request_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOP_boolean response_expected,
++ const struct iovec *object_key_vec,
++ const struct iovec *operation_vec,
++ const struct iovec *principal_vec)
++{
++ GIOPSendBuffer *send_buffer;
++#if 0
++ static const struct {
++ CORBA_unsigned_long _length;
++ char _buffer[7];
++ } default_principal = { sizeof("nobody"), "nobody" };
++ static const struct iovec default_principal_vec =
++ {(void *)&default_principal,
++ sizeof(CORBA_unsigned_long) + sizeof("nobody")};
++#endif
++
++ if (!connection)
++ return NULL;
++ if(!object_key_vec)
++ return NULL;
++ if(!operation_vec)
++ return NULL;
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "Sending request %s id %d to %s\n",
++ ((guchar *)operation_vec->iov_base) + 4,
++ request_id, ((guchar *)object_key_vec->iov_base) + 4);
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if (!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_REQUEST;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ if(!service_context) {
++ static const GIOP_unsigned_long sc_zero_int = 0;
++ AP(&sc_zero_int, sizeof(GIOP_unsigned_long));
++ } else {
++ int i, n;
++ n = service_context->_length;
++ AP(&service_context->_length, sizeof(service_context->_length));
++ for(i = 0; i < n; i++) {
++ int j, o;
++ CORBA_sequence_octet *seqo;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&service_context->_buffer[i].context_id,
++ sizeof(service_context->_buffer[i].context_id));
++ seqo = &service_context->_buffer[i].context_data;
++ o = seqo->_length;
++ AP(&seqo->_length, sizeof(GIOP_unsigned_long));
++ for(j = 0; j < o; j++)
++ AP(seqo->_buffer, seqo->_length);
++ }
++ }
++ send_buffer->message.u.request.request_id = request_id;
++ send_buffer->message.u.request.response_expected = response_expected;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.request.request_id,
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.request.response_expected,
++ sizeof(GIOP_boolean));
++#if 0
++ API(&response_expected, 1);
++ AP((gpointer)giop_scratch_space, 3);
++#endif
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ object_key_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ object_key_vec->iov_len;
++
++ /*
++ * We can know the length at compile time - don't calculate it at runtime
++ * if we can help it :)
++ */
++ /* ENCODER_CALL(CORBA_string, (CORBA_string *)operation); */
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ operation_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ operation_vec->iov_len;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ principal_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ principal_vec->iov_len;
++
++ return send_buffer;
++}
++
++GIOPSendBuffer *
++giop_send_locate_request_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ const struct iovec *object_key_vec)
++{
++ GIOPSendBuffer *send_buffer;
++
++ if (!connection)
++ return NULL;
++ if (!object_key_vec)
++ return NULL;
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "Sending locate request id %d to %s\n",
++ request_id, ((guchar *)object_key_vec->iov_base) + 4);
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if (!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_LOCATEREQUEST;
++
++ APIA(&request_id, sizeof(request_id));
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ object_key_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ object_key_vec->iov_len;
++
++ return send_buffer;
++}
++
++void
++giop_send_buffer_unuse(GIOPSendBuffer *send_buffer)
++{
++ if (send_buffer == NULL)
++ return;
++
++ giop_connection_unref(GIOP_MESSAGE_BUFFER(send_buffer)->connection);
++
++ GET_LOCK(sendbufferlist);
++ sendbufferlist = g_slist_prepend(sendbufferlist, send_buffer);
++ RELEASE_LOCK(sendbufferlist);
++}
++
++gulong
++giop_message_buffer_do_alignment(GIOPMessageBuffer *buffer,
++ gulong align_for)
++{
++ struct iovec newvec;
++ struct iovec *lastvec;
++ guint alignme;
++ gulong real_msgsize;
++ gulong align_diff;
++
++ if(align_for < 2) return 0;
++ if(align_for >
++ MAX(sizeof(GIOP_long_long),sizeof(GIOP_long_double)))
++ align_for = MAX(sizeof(GIOP_long_long), sizeof(GIOP_long_double));
++
++ real_msgsize = buffer->message_header.message_size+sizeof(GIOPMessageHeader);
++
++ alignme = (gulong)ALIGN_ADDRESS(real_msgsize, align_for);
++
++ align_diff = alignme - real_msgsize;
++ if(align_diff > 0)
++ {
++ lastvec = (struct iovec *)(buffer->iovecs->data)
++ + buffer->iovecs->len - 1;
++
++ if(lastvec->iov_base == giop_scratch_space)
++ {
++ newvec.iov_len = align_diff;
++ lastvec->iov_len += align_diff;
++ buffer->message_header.message_size += align_diff;
++ }
++ else
++ {
++ newvec.iov_base = (gpointer)giop_scratch_space;
++ newvec.iov_len = align_diff;
++ buffer->message_header.message_size += align_diff;
++ giop_message_buffer_append_iovec(buffer, &newvec);
++ }
++ return newvec.iov_len;
++ }
++ else
++ return 0;
++}
++
++void
++giop_message_buffer_append_mem_a(GIOPMessageBuffer *buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ struct iovec newvec;
++ struct iovec *lastvec;
++ gint alignfor;
++
++ alignfor = giop_message_buffer_do_alignment(buffer, mem_region_length);
++
++ lastvec = (struct iovec *)(buffer->iovecs->data) +
++ + buffer->iovecs->len - 1;
++
++ if((mem_region == giop_scratch_space && lastvec->iov_base == giop_scratch_space)
++ || (alignfor == 0 && (((guchar *)lastvec->iov_base) + lastvec->iov_len) == mem_region))
++ {
++ lastvec->iov_len += mem_region_length;
++ }
++ else
++ {
++ newvec.iov_base = (gpointer)mem_region;
++ newvec.iov_len = mem_region_length;
++ giop_message_buffer_append_iovec(buffer, &newvec);
++ }
++
++ buffer->message_header.message_size += mem_region_length;
++}
++
++void
++giop_message_buffer_append_mem(GIOPMessageBuffer *buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ struct iovec newvec;
++ struct iovec *lastvec;
++
++ lastvec = (struct iovec *)(buffer->iovecs->data)
++ + buffer->iovecs->len - 1;
++
++ if((mem_region == giop_scratch_space
++ && lastvec->iov_base == giop_scratch_space)
++ || ((((guchar *)lastvec->iov_base) + lastvec->iov_len) == mem_region))
++ {
++ lastvec->iov_len += mem_region_length;
++ }
++ else
++ {
++ newvec.iov_base = (gpointer)mem_region;
++ newvec.iov_len = mem_region_length;
++ giop_message_buffer_append_iovec(buffer, &newvec);
++ }
++
++ buffer->message_header.message_size += mem_region_length;
++}
++
++/* I think we need a WE_WANT_NEW_CRAPPY_BUGGY_CODE ifdef here - this
++ tiny routine seems to be horribly hard to get right.
++
++ Basically we have to paste the whole of 'mem_region' into our
++ memory chunks, possibly subdividing it up to fit it into multiple
++ 1K chunks. Because we have to return the first paste point in case
++ the client wants to manipulate it afterwards, if mem_region_length
++ >= sizeof(CORBA_unsigned_long), we also have to guarantee that the
++ pasted stuff doesn't get divided on a finer boundary than
++ sizeof(CORBA_unsigned_long).
++*/
++gpointer
++giop_send_buffer_append_mem_indirect(GIOPSendBuffer *send_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ gulong offset = 0, thisblock_size;
++ gpointer blockstart = NULL;
++
++ while(offset < mem_region_length) {
++ thisblock_size = MIN(mem_region_length - offset,
++ GIOP_INDIRECT_CHUNK_SIZE - send_buffer->indirect_used);
++
++ if((thisblock_size >= sizeof(CORBA_unsigned_long))
++ || (mem_region_length - offset) < sizeof(CORBA_unsigned_long)) {
++ if (!blockstart)
++ blockstart =
++ ((guchar*) send_buffer->indirect) + send_buffer->indirect_used;
++
++ memcpy((guchar*)send_buffer->indirect + send_buffer->indirect_used,
++ (guchar*)mem_region + offset, thisblock_size);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ (guchar*)send_buffer->indirect +
++ send_buffer->indirect_used,
++ thisblock_size);
++ offset += thisblock_size;
++ send_buffer->indirect_used += thisblock_size;
++ }
++
++ if(send_buffer->indirect_used >= (GIOP_INDIRECT_CHUNK_SIZE - sizeof(CORBA_unsigned_long))) {
++#ifdef I_CANT_FIGURE_OUT_WHAT_THIS_LOGIC_WAS_MEANT_TO_DO
++ || (thisblock_size >= sizeof(CORBA_unsigned_long)
++ && (mem_region_length - offset) > 0)) {
++#endif
++ send_buffer->indirect_used = 0;
++ send_buffer->indirect = g_chunk_new(gpointer,
++ send_buffer->indirects);
++ }
++ }
++
++ return blockstart;
++}
++
++#ifdef WE_WANT_OLD_DEAD_CRAPPY_BUGGY_CODE
++gpointer
++_giop_send_buffer_append_mem_indirect(GIOPSendBuffer *send_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ gpointer blockstart = NULL;
++ gulong offset, new_offset;
++
++ for(offset = new_offset = 0; new_offset < mem_region_length;)
++ {
++ new_offset =
++ MIN(mem_region_length - offset,
++ GIOP_INDIRECT_CHUNK_SIZE - send_buffer->indirect_used);
++
++ if((new_offset - offset) > sizeof(CORBA_unsigned_long)
++ || mem_region_length >= sizeof(CORBA_unsigned_long)) {
++
++ if(!blockstart)
++ blockstart = send_buffer->indirect + send_buffer->indirect_used;
++ }
++
++ memcpy(send_buffer->indirect + send_buffer->indirect_used,
++ mem_region + offset, new_offset - offset);
++
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ send_buffer->indirect + send_buffer->indirect_used,
++ new_offset - offset);
++
++ send_buffer->indirect_used += new_offset - offset;
++
++ offset = new_offset;
++
++ if(new_offset >= GIOP_INDIRECT_CHUNK_SIZE)
++ {
++ send_buffer->indirect_used = 0;
++ send_buffer->indirect = g_chunk_new(gpointer,
++ send_buffer->indirects);
++#ifdef ORBIT_DEBUG
++ memset(send_buffer->indirect, '\xFE', GIOP_INDIRECT_CHUNK_SIZE);
++#endif
++ }
++ }
++
++ return blockstart;
++}
++#endif
++
++gpointer
++giop_send_buffer_append_mem_indirect_a(GIOPSendBuffer *send_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ mem_region_length);
++ return giop_send_buffer_append_mem_indirect(send_buffer,
++ mem_region, mem_region_length);
++}
++
++GIOP_unsigned_long
++giop_get_request_id(void)
++{
++ GIOP_unsigned_long retval;
++ GET_LOCK(request_id_counter);
++ retval = request_id_counter++;
++ RELEASE_LOCK(request_id_counter);
++ return retval;
++}
++
++/****************************************************
++ * GIOPRecvBuffer routines
++ ****************************************************/
++
++static GIOPRecvBuffer *
++giop_recv_buffer_new(void)
++{
++ GIOPRecvBuffer *msgbuf;
++
++ GET_LOCK(recvbuffers);
++ msgbuf = g_chunk_new(GIOPRecvBuffer, recvbuffers);
++ RELEASE_LOCK(recvbuffers);
++
++ giop_message_buffer_new(GIOP_MESSAGE_BUFFER(msgbuf));
++ msgbuf->message_body = NULL;
++
++ return msgbuf;
++}
++
++void
++giop_recv_buffer_unuse(GIOPRecvBuffer *buffer)
++{
++ if (buffer == NULL)
++ return;
++
++ if(buffer->message_body) {
++ buffer->message_body = ((guchar *)buffer->message_body)
++ - sizeof(GIOPMessageHeader);
++
++ g_free(buffer->message_body);
++ buffer->message_body = NULL;
++ }
++
++ if(GIOP_MESSAGE_BUFFER(buffer)->connection->incoming_msg == buffer)
++ GIOP_MESSAGE_BUFFER(buffer)->connection->incoming_msg = NULL;
++
++ giop_connection_unref(GIOP_MESSAGE_BUFFER(buffer)->connection);
++
++ GET_LOCK(recvbufferlist);
++ recvbufferlist = g_slist_prepend(recvbufferlist, buffer);
++ RELEASE_LOCK(recvbufferlist);
++}
++
++static GIOPRecvBuffer *
++giop_recv_buffer_use(GIOPConnection *connection)
++{
++ GIOPRecvBuffer *retval;
++
++ if(!connection || !connection->is_valid)
++ return NULL;
++
++ GET_LOCK(recvbufferlist);
++
++ if(recvbufferlist)
++ {
++ GSList *head;
++
++ retval = recvbufferlist->data;
++
++ head = recvbufferlist;
++ recvbufferlist = g_slist_remove_link(recvbufferlist, recvbufferlist);
++ g_slist_free_1 (head);
++
++ GIOP_MESSAGE_BUFFER(retval)->message_header.message_size = 0;
++ retval->message_body = NULL;
++ }
++ else
++ retval = giop_recv_buffer_new();
++
++ retval->state = GIOP_MSG_READING_HEADER;
++ retval->left_to_read = sizeof(GIOPMessageHeader);
++
++ RELEASE_LOCK(recvbufferlist);
++
++ giop_connection_ref(connection);
++ GIOP_MESSAGE_BUFFER(retval)->connection = connection;
++
++ return retval;
++}
++
++GIOPRecvBuffer *
++giop_recv_message_buffer_use(GIOPConnection *connection)
++{
++ GIOPRecvBuffer *retval;
++ char *bptr;
++ int sysret;
++ guint message_size;
++
++// printf("giop_recv_message_buffer_use: connection = 0x%X\n", connection);
++
++ if(!connection || !connection->is_valid)
++ return NULL;
++
++ if(connection->incoming_msg)
++ retval = connection->incoming_msg;
++ else {
++ retval = giop_recv_buffer_use(connection);
++ connection->incoming_msg = retval;
++ }
++
++ if(!retval) return NULL;
++
++ do {
++ switch(retval->state) {
++ case GIOP_MSG_READING_HEADER:
++ bptr = ((char *)&(GIOP_MESSAGE_BUFFER(retval)->message_header));
++ bptr += sizeof(GIOP_MESSAGE_BUFFER(retval)->message_header)
++ - retval->left_to_read;
++ break;
++ case GIOP_MSG_READING_BODY:
++ bptr = retval->cur; /* Reason for not using retval->message_body:
++ See note XXX1 below */
++ bptr += GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
++ bptr -= retval->left_to_read;
++ break;
++ default:
++ bptr = NULL;
++ }
++
++//printf("#1p1: READ %d bytes: errno %d state = %d\n", retval->left_to_read, errno, retval->state);
++ sysret = read(GIOP_CONNECTION_GET_FD(connection), bptr,
++ retval->left_to_read);
++
++ if((sysret == 0)
++ || ((sysret < 0) && (errno != EAGAIN))) {
++//printf("#1: sysret = %d bptr = 0x%X errno = %d\n", sysret, bptr, errno);
++ goto errout;
++ }
++
++ if(sysret > 0)
++ retval->left_to_read -= sysret;
++
++ if(retval->left_to_read == 0) {
++ /* we change states here */
++
++ switch(retval->state) {
++ case GIOP_MSG_READING_HEADER:
++ /* Check the magic stuff */
++ if(strncmp(GIOP_MESSAGE_BUFFER(retval)->message_header.magic, "GIOP", 4)
++ || GIOP_MESSAGE_BUFFER(retval)->message_header.GIOP_version[0] != 1) {
++//printf("#2: Not a GIOP thinger? '%s'\n", GIOP_MESSAGE_BUFFER(retval)->message_header.magic);
++ goto errout;
++ }
++ if(GIOP_MESSAGE_BUFFER(retval)->message_header.message_size == 0
++ && GIOP_MESSAGE_BUFFER(retval)->message_header.message_type != GIOP_CLOSECONNECTION) {
++// printf("Unexpected 0-length IIOP message\n");
++ goto errout;
++ }
++
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(retval))) {
++ CORBA_unsigned_long t = GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
++ retval->decoder = (void (*)(gpointer, gpointer, gulong))iiop_byteswap;
++
++ iiop_byteswap((gpointer)&GIOP_MESSAGE_BUFFER(retval)->message_header.message_size,
++ (gpointer)&t, sizeof(t));
++ } else {
++#ifdef __KERNEL__
++ retval->decoder = (void (*)(gpointer,gpointer,gulong))__memcpy;
++#else
++ retval->decoder = (void (*)(gpointer,gpointer,gulong))memcpy;
++#endif
++ }
++
++ message_size = GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
++ if(!connection->is_auth
++ && message_size > 131072) {
++// printf("message size is bigger than 128k (%d)\n", message_size);
++ goto errout;
++ }
++
++ retval->message_body = g_malloc(message_size+sizeof(GIOPMessageHeader));
++ /* XXX1 This is a lame hack to work with the fact that
++ alignment is relative to the MessageHeader, not the RequestHeader */
++ retval->message_body = ((guchar *)retval->message_body) + sizeof(GIOPMessageHeader);
++ retval->cur = retval->message_body;
++ retval->state = GIOP_MSG_READING_BODY;
++ retval->left_to_read = message_size;
++ break;
++ case GIOP_MSG_READING_BODY:
++ if(giop_recv_decode_message(retval)) {
++//printf("giop_recv_decode_message FAILURE!\n");
++ goto errout;
++ }
++ connection->incoming_msg = NULL;
++ retval->state = GIOP_MSG_READY;
++ break;
++ default:
++ break;
++ }
++ } else if(retval->left_to_read < 0) {
++// printf("Whoa, we overstepped the number of bytes we were supposed to read by %d\n", -retval->left_to_read);
++ goto errout;
++ } else /* retval->left_to_read > 0 */ {
++ /* couldn't read the whole piece, save it */
++ retval = NULL;
++ }
++ } while(retval && retval->state != GIOP_MSG_READY);
++
++ return retval;
++
++ errout:
++ giop_recv_buffer_unuse(retval);
++ giop_main_handle_connection_exception(connection);
++ return NULL;
++}
++
++void
++giop_received_list_push(GIOPRecvBuffer *recv_buffer)
++{
++ GET_LOCK(incoming_bufs);
++ incoming_bufs = g_list_prepend(incoming_bufs, recv_buffer);
++ RELEASE_LOCK(incoming_bufs);
++}
++
++GIOPRecvBuffer *giop_received_list_pop(void)
++{
++ GList *head;
++ GIOPRecvBuffer *retval;
++
++ GET_LOCK(incoming_bufs);
++
++ head = incoming_bufs;
++
++ if(!head)
++ return NULL;
++
++ retval = head->data;
++ incoming_bufs = g_list_remove_link(incoming_bufs, head);
++ g_list_free_1 (head);
++
++ RELEASE_LOCK(incoming_bufs);
++
++ return retval;
++}
++
++static GIOPRecvBuffer *
++giop_received_list_check_reply(GIOP_unsigned_long request_id)
++{
++ GIOPRecvBuffer *retval = NULL;
++ GList *item = NULL;
++
++ GET_LOCK(incoming_bufs);
++
++ for(item = incoming_bufs; item; item = g_list_next(item))
++ {
++ if(GIOP_MESSAGE_BUFFER(item->data)->message_header.message_type == GIOP_REPLY
++ && GIOP_RECV_BUFFER(item->data)->message.u.reply.request_id == request_id) {
++ retval = item->data;
++ break;
++ }
++ }
++
++ if(retval)
++ incoming_bufs = g_list_remove(incoming_bufs, retval);
++
++ RELEASE_LOCK(incoming_bufs);
++
++ return retval;
++}
++
++/** giop_recv_reply_buffer_use_multiple
++ */
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple(GArray *request_ids,
++ gboolean block_for_reply)
++{
++ return giop_recv_reply_buffer_use_multiple_2(NULL, request_ids, block_for_reply);
++}
++
++/* here is how it will be:
++ one routine for getting next message with a specified reply ID.
++ */
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple_2(GIOPConnection *request_cnx,
++ GArray *request_ids,
++ gboolean block_for_reply)
++{
++ int i;
++ GIOPRecvBuffer *retval = NULL;
++ GSList *pushme = NULL;
++
++ do {
++ /*
++ * We _do_ want to put this inside the loop,
++ * because we may call ourselves recursively for different request_id's
++ */
++ for(i = 0; i < request_ids->len && !retval; i++)
++ retval = giop_received_list_check_reply(g_array_index(request_ids, GIOP_unsigned_long, i));
++
++ if(retval)
++ break;
++
++ retval = giop_main_next_message_2(block_for_reply, request_cnx);
++
++ if(retval) {
++ if(GIOP_MESSAGE_BUFFER(retval)->message_header.message_type == GIOP_REPLY) {
++ if(num_on_list(retval->message.u.reply.request_id,
++ (GIOP_unsigned_long *)request_ids->data,
++ request_ids->len))
++ break;
++ else {
++ pushme = g_slist_prepend(pushme, retval); retval = NULL;
++ }
++ } else {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(retval);
++ else {
++ pushme = g_slist_prepend(pushme, retval); retval = NULL;
++ }
++ retval = NULL;
++ }
++ } else
++ return NULL;
++
++ } while(!retval && block_for_reply);
++
++ g_slist_foreach(pushme, (GFunc)giop_received_list_push, NULL);
++ g_slist_free(pushme);
++
++ return retval;
++}
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply)
++{
++ return giop_recv_reply_buffer_use_2(NULL, request_id, block_for_reply);
++}
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_2(GIOPConnection *request_cnx,
++ GIOP_unsigned_long request_id,
++ gboolean block_for_reply)
++{
++ GArray fakeme;
++
++ fakeme.len = 1;
++ fakeme.data = (gpointer)&request_id;
++
++ return giop_recv_reply_buffer_use_multiple_2(request_cnx,
++ &fakeme,
++ block_for_reply);
++}
++
++GIOPRecvBuffer *
++giop_recv_locate_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply)
++{
++ GIOPRecvBuffer *retval = NULL;
++
++ do {
++ /*
++ * We _do_ want to put this inside the loop,
++ * because we may call ourselves recursively for different request_id's
++ */
++ retval = giop_received_list_check_reply(request_id);
++
++ if(retval)
++ break;
++
++ retval = giop_main_next_message_2(TRUE, NULL);
++
++ if(retval) {
++ if(GIOP_MESSAGE_BUFFER(retval)->message_header.message_type == GIOP_LOCATEREPLY
++ && retval->message.u.locate_reply.request_id == request_id)
++ break;
++ else {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(retval);
++ else
++ giop_received_list_push(retval);
++ retval = NULL;
++ }
++ } else
++ return NULL;
++ } while(!retval && block_for_reply);
++
++ return retval;
++}
++
++static gint
++giop_recv_decode_message(GIOPRecvBuffer *buf)
++{
++ switch(GIOP_MESSAGE_BUFFER(buf)->message_header.message_type)
++ {
++ case GIOP_REPLY:
++ return giop_recv_reply_decode_message(buf);
++ break;
++ case GIOP_REQUEST:
++ return giop_recv_request_decode_message(buf);
++ break;
++ case GIOP_LOCATEREQUEST:
++ return(giop_recv_locate_request_decode_message(buf));
++ break;
++ case GIOP_LOCATEREPLY:
++ return(giop_recv_locate_reply_decode_message(buf));
++ break;
++ case GIOP_CLOSECONNECTION:
++ return 0;
++ break;
++ default:
++// printf("Don't know how to decode message type %d\n",
++// GIOP_MESSAGE_BUFFER(buf)->message_header.message_type);
++ return -1;
++ }
++}
++
++/* if(currptr+len > end || currptr + len < currptr) */
++
++/* This whole mess needs redoing. */
++#define CHECK_NEW_POS(buf, requested_increment) \
++if(!( (( ((guchar*)GIOP_RECV_BUFFER(buf)->cur) \
++ + (requested_increment) ) \
++ <= ( ((guchar *)GIOP_RECV_BUFFER(buf)->message_body) \
++ + GIOP_MESSAGE_BUFFER(buf)->message_header.message_size)) \
++ && ( ( ((guchar*)GIOP_RECV_BUFFER(buf)->cur) \
++ + (requested_increment) ) \
++ >= ((guchar*)GIOP_RECV_BUFFER(buf)->cur) ))) goto out;
++
++#define NEW_POS_OUT out: return -1
++
++#define SAFE_ALIGN_ADDRESS(buf, amt) G_STMT_START { \
++guchar *newval; \
++newval = ALIGN_ADDRESS(GIOP_RECV_BUFFER(buf)->cur, amt); \
++CHECK_NEW_POS(buf, newval-((guchar *)GIOP_RECV_BUFFER(buf)->cur)); \
++GIOP_RECV_BUFFER(buf)->cur = newval; \
++} G_STMT_END
++
++#define GET_ULONG(x) G_STMT_START{ \
++ (x) = GUINT32_SWAP_LE_BE((*(CORBA_unsigned_long *)buf->cur)); \
++ CHECK_NEW_POS(buf, sizeof(CORBA_unsigned_long)); \
++ buf->cur = ((guchar *)buf->cur) + sizeof(CORBA_unsigned_long); \
++ }G_STMT_END
++
++#define GET_ULONG_NC(x) G_STMT_START{ \
++ *(x) = (*((CORBA_unsigned_long *)(buf->cur))); \
++ CHECK_NEW_POS(buf, sizeof(CORBA_unsigned_long)); \
++ buf->cur = ((guchar *)buf->cur) + sizeof(CORBA_unsigned_long); \
++ }G_STMT_END
++
++/* There be dragons in here. */
++static gint
++giop_recv_reply_decode_message(GIOPRecvBuffer *buf)
++{
++ /*
++ enum ReplyStatusType {
++ NO_EXCEPTION,
++ USER_EXCEPTION,
++ SYSTEM_EXCEPTION,
++ LOCATION_FORWARD
++ };
++
++ struct ReplyHeader {
++ IOP::ServiceContextList service_context;
++ unsigned long request_id;
++ ReplyStatusType reply_status;
++ };
++ */
++ int i;
++
++ buf->message.u.reply.service_context._maximum = 0;
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ GET_ULONG(buf->message.u.reply.service_context._length);
++/* XXX bad hardcoded hack until someone gives a "right answer" to how to
++solve this problem */
++ if(buf->message.u.reply.service_context._length > 128) return -1;
++ buf->message.u.reply.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.reply.service_context._length);
++
++ for(i = 0; i < buf->message.u.reply.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.reply.service_context._buffer[i].context_id);
++ GET_ULONG(buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->message.u.reply.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.reply.service_context._buffer[i].context_data._length;
++ }
++ GET_ULONG(buf->message.u.reply.request_id);
++ GET_ULONG(buf->message.u.reply.reply_status);
++ }
++ else
++ {
++
++ GET_ULONG_NC(&buf->message.u.reply.service_context._length);
++/* XXX bad hardcoded hack until someone gives a "right answer" to how to
++solve this problem */
++ if(buf->message.u.reply.service_context._length > 128) return -1;
++ buf->message.u.reply.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.reply.service_context._length);
++
++ for(i = 0; i < buf->message.u.reply.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(CORBA_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.reply.service_context._buffer[i].context_id);
++ GET_ULONG_NC(&buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->message.u.reply.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.reply.service_context._buffer[i].context_data._length;
++ }
++ GET_ULONG_NC(&buf->message.u.reply.request_id);
++ GET_ULONG_NC(&buf->message.u.reply.reply_status);
++ }
++
++#if 0
++ g_message("[%d] Received reply %d size %d to request %d",
++ getpid(),
++ buf->message.u.reply.reply_status,
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size,
++ buf->message.u.reply.request_id);
++#endif
++
++ return 0;
++
++ NEW_POS_OUT;
++}
++
++static gint
++giop_recv_locate_reply_decode_message(GIOPRecvBuffer *buf)
++{
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ GET_ULONG(buf->message.u.locate_reply.request_id);
++ GET_ULONG(buf->message.u.locate_reply.locate_status);
++ }
++ else
++ {
++ GET_ULONG_NC(&buf->message.u.locate_reply.request_id);
++ GET_ULONG_NC(&buf->message.u.locate_reply.locate_status);
++ }
++
++ return 0;
++ NEW_POS_OUT;
++}
++
++static gint
++giop_recv_request_decode_message(GIOPRecvBuffer *buf)
++{
++ GIOP_unsigned_long len;
++ int i;
++
++ buf->message.u.request.service_context._maximum = 0;
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ GET_ULONG(buf->message.u.request.service_context._length);
++
++ /* XXX bad hardcoded hack until someone gives a "right answer"
++ to how to solve this problem */
++
++ if(buf->message.u.request.service_context._length > 128) return -1;
++ buf->message.u.request.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.request.service_context._length);
++
++ for(i = 0; i < buf->message.u.request.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.service_context._buffer[i].context_id);
++ GET_ULONG(buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->message.u.request.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.service_context._buffer[i].context_data._length;
++ }
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.request_id);
++ buf->message.u.request.response_expected = *((GIOP_boolean *)buf->cur);
++ CHECK_NEW_POS(buf, sizeof(GIOP_boolean));
++ buf->cur = ((guchar *)buf->cur) + sizeof(GIOP_boolean);
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.object_key._length);
++ buf->message.u.request.object_key._buffer = buf->cur;
++
++ CHECK_NEW_POS(buf, buf->message.u.request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.object_key._length;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(len);
++ buf->message.u.request.operation = buf->cur;
++
++ CHECK_NEW_POS(buf, len);
++ buf->cur = ((guchar *)buf->cur) + len;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.requesting_principal._length);
++ buf->message.u.request.requesting_principal._buffer = buf->cur;
++
++ CHECK_NEW_POS(buf, buf->message.u.request.requesting_principal._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.requesting_principal._length;
++ }
++ else
++ {
++ GET_ULONG_NC(&buf->message.u.request.service_context._length);
++
++ /* XXX bad hardcoded hack until someone gives a "right answer"
++ to how to solve this problem */
++ if(buf->message.u.request.service_context._length > 128) return -1;
++ buf->message.u.request.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.request.service_context._length);
++
++ for(i = 0; i < buf->message.u.request.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.service_context._buffer[i].context_id);
++ GET_ULONG_NC(&buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->message.u.request.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.service_context._buffer[i].context_data._length;
++ }
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.request_id);
++ buf->message.u.request.response_expected = *((GIOP_boolean *)buf->cur);
++ CHECK_NEW_POS(buf, sizeof(GIOP_boolean));
++ buf->cur = ((guchar *)buf->cur) + sizeof(GIOP_boolean);
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.object_key._length);
++ buf->message.u.request.object_key._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.object_key._length;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&len);
++ buf->message.u.request.operation = buf->cur;
++ CHECK_NEW_POS(buf, len);
++ buf->cur = ((guchar *)buf->cur) + len;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.requesting_principal._length);
++ buf->message.u.request.requesting_principal._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.requesting_principal._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.requesting_principal._length;
++ }
++
++#if 0
++ g_message("[%d] Received request %s size %d ID %d",
++ getpid(),
++ buf->message.u.request.operation,
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size,
++ buf->message.u.request.request_id);
++#endif
++
++ return 0;
++
++ NEW_POS_OUT;
++}
++
++static gint
++giop_recv_locate_request_decode_message(GIOPRecvBuffer *buf)
++{
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.locate_request.request_id);
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.locate_request.object_key._length);
++ buf->message.u.locate_request.object_key._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.locate_request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.locate_request.object_key._length;
++ }
++ else
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.locate_request.request_id);
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.locate_request.object_key._length);
++ buf->message.u.locate_request.object_key._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.locate_request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.locate_request.object_key._length;
++ }
++
++ return 0;
++
++ NEW_POS_OUT;
++}
++
++gboolean
++num_on_list(GIOP_unsigned_long num,
++ const GIOP_unsigned_long *request_ids,
++ GIOP_unsigned_long req_count)
++{
++ int i;
++ for(i = 0; i < req_count; i++)
++ {
++ if(num == request_ids[i])
++ return TRUE;
++ }
++
++ return FALSE;
++}
+diff -urN linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.h linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.h
+--- linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.h Thu Feb 1 16:19:47 2001
+@@ -0,0 +1,228 @@
++#ifndef GIOP_MSG_BUFFER_H
++#define GIOP_MSG_BUFFER_H 1
++
++#include "IIOP.h"
++/* For struct iovec */
++#include <sys/uio.h>
++
++typedef enum {
++ GIOP_REQUEST,
++ GIOP_REPLY,
++ GIOP_CANCELREQUEST,
++ GIOP_LOCATEREQUEST,
++ GIOP_LOCATEREPLY,
++ GIOP_CLOSECONNECTION,
++ GIOP_MESSAGEERROR,
++ GIOP_FRAGMENT
++} GIOPMsgType;
++
++/* GIOP message header */
++typedef struct _GIOPMessageHeader {
++ GIOP_char magic[4];
++ GIOP_char GIOP_version[2];
++ GIOP_octet flags;
++
++ /*
++ * We should really use GIOPMsgType
++ * but that enum winds up being an int...
++ */
++ GIOP_octet message_type;
++
++ GIOP_unsigned_long message_size;
++} GIOPMessageHeader;
++
++#define GIOP_MESSAGE_BUFFER(x) ((GIOPMessageBuffer *)x)
++typedef struct _GIOPMessageBuffer
++{
++ /* The connection that this message will go out over... */
++ GIOPConnection *connection;
++
++ GArray *iovecs;
++ GIOPMessageHeader message_header;
++} GIOPMessageBuffer;
++
++#include "../orb/iop.h"
++
++/* GIOP_REQUEST header */
++typedef enum {
++ GIOP_NO_EXCEPTION,
++ GIOP_USER_EXCEPTION,
++ GIOP_SYSTEM_EXCEPTION,
++ GIOP_LOCATION_FORWARD
++} GIOPReplyStatusType;
++
++typedef struct _GIOPMessageRequest {
++ IOP_ServiceContextList service_context;
++ GIOP_unsigned_long request_id;
++ GIOP_boolean response_expected;
++ CORBA_sequence_octet object_key;
++ CORBA_char *operation;
++ CORBA_Principal requesting_principal;
++} GIOPMessageRequest;
++
++typedef struct _GIOPMessageReply {
++ IOP_ServiceContextList service_context;
++ GIOP_unsigned_long request_id;
++ GIOPReplyStatusType reply_status;
++} GIOPMessageReply;
++
++typedef struct _GIOPMessageCancelRequest {
++ GIOP_unsigned_long request_id;
++} GIOPMessageCancelRequest;
++
++typedef struct _GIOPMessageLocateRequest {
++ GIOP_unsigned_long request_id;
++ CORBA_sequence_octet object_key;
++} GIOPMessageLocateRequest;
++
++typedef enum {
++ GIOP_UNKNOWN_OBJECT,
++ GIOP_OBJECT_HERE,
++ GIOP_OBJECT_FORWARD
++} GIOPLocateStatusType;
++
++typedef struct _GIOPMessageLocateReply {
++ GIOP_unsigned_long request_id;
++ GIOPLocateStatusType locate_status;
++} GIOPMessageLocateReply;
++
++typedef struct _GIOPMessage
++{
++ union {
++ GIOPMessageRequest request;
++ GIOPMessageReply reply;
++ GIOPMessageCancelRequest cancel_request;
++ GIOPMessageLocateRequest locate_request;
++ GIOPMessageLocateReply locate_reply;
++ } u;
++} GIOPMessage;
++
++typedef enum {
++ GIOP_MSG_READING_HEADER,
++ GIOP_MSG_READING_BODY,
++ GIOP_MSG_READY
++} GIOPMessageBufferState;
++
++#define GIOP_SEND_BUFFER(x) ((GIOPSendBuffer *)x)
++typedef struct _GIOPSendBuffer
++{
++ GIOPMessageBuffer message_buffer;
++
++ gpointer indirect;
++
++ GMemChunk *indirects; /* Request buffers only (at present) */
++ gulong indirect_used;
++
++ GIOPMessage message;
++ CORBA_unsigned_long scontext_tmp;
++} GIOPSendBuffer;
++
++#define GIOP_RECV_BUFFER(x) ((GIOPRecvBuffer *)x)
++typedef struct _GIOPRecvBuffer
++{
++ GIOPMessageBuffer message_buffer;
++ GIOPMessage message;
++
++ gpointer message_body;
++ gpointer cur;
++
++ void (*decoder)(gpointer dest, gpointer src, gulong len);
++
++ GIOPMessageBufferState state;
++ gint left_to_read;
++} GIOPRecvBuffer;
++
++/* This function needs to be called before useful things happen */
++void giop_message_buffer_init(void);
++
++gint giop_send_buffer_write(GIOPSendBuffer *request_buffer);
++
++void
++giop_message_buffer_append_mem_a(GIOPMessageBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++void
++giop_message_buffer_append_mem(GIOPMessageBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++
++/*
++ * This copies the value into a request-specific buffer before
++ * adding it to the list
++ */
++gpointer
++giop_send_buffer_append_mem_indirect_a(GIOPSendBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++gpointer
++giop_send_buffer_append_mem_indirect(GIOPSendBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++
++GIOPSendBuffer *
++giop_send_request_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOP_boolean response_expected,
++ const struct iovec *object_key_vec,
++ const struct iovec *operation_vec,
++ const struct iovec *principal_vec);
++GIOPSendBuffer *
++giop_send_reply_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOPReplyStatusType reply_status);
++GIOPSendBuffer *
++giop_send_locate_request_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ const struct iovec *object_key_vec);
++GIOPSendBuffer *
++giop_send_locate_reply_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ GIOPLocateStatusType reply_status);
++
++void giop_send_buffer_unuse(GIOPSendBuffer *send_buffer);
++
++GIOP_unsigned_long giop_get_request_id(void);
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply);
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_2(GIOPConnection *request_cnx,
++ GIOP_unsigned_long request_id,
++ gboolean block_for_reply);
++
++/* For DII - hands back the first received request matching an id on the list */
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple(GArray *request_ids,
++ gboolean block_for_reply);
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple_2(GIOPConnection *request_cnx,
++ GArray *request_ids,
++ gboolean block_for_reply);
++
++GIOPRecvBuffer *
++giop_recv_locate_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply);
++
++/*
++ * For server-side use. It's the responsibility of the caller to do
++ * any select()ion desired
++ */
++GIOPRecvBuffer *
++giop_recv_message_buffer_use(GIOPConnection *connection);
++
++void giop_recv_buffer_unuse(GIOPRecvBuffer *buffer);
++
++/*
++ * This is used for sending (and recving, if we ever
++ * get zero-copy receives implemented) alignment bytes
++ */
++extern char giop_scratch_space[2048];
++gulong giop_message_buffer_do_alignment(GIOPMessageBuffer *buffer,
++ gulong align_for);
++
++#define giop_msg_conversion_needed(msgbuf) (conversion_needed(GIOP_MESSAGE_BUFFER(msgbuf)->message_header.flags & 1))
++
++#endif /* GIOP_MSG_BUFFER_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-encoders.h linux-2.4.1-korbit/net/korbit/IIOP/iiop-encoders.h
+--- linux-2.4.1/net/korbit/IIOP/iiop-encoders.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-encoders.h Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,25 @@
++#ifndef ENCODERS_H
++#define ENCODERS_H 1
++
++#define ENCODER_DEC(typename) \
++void giop_encoder_##typename##(GIOPSendBuffer *send_buffer, \
++ const typename *mem)
++
++#define ENCODER_CALL(typename, mem) \
++giop_encoder_##typename##(send_buffer, mem)
++
++#define AP(m, l) giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer), m, l)
++#define APA(m, l) giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer), m, l)
++
++#define API(m, l) giop_send_buffer_append_mem_indirect(send_buffer, m, l)
++#define APIA(m, l) giop_send_buffer_append_mem_indirect_a(send_buffer, m, l)
++
++ENCODER_DEC(IOP_ServiceContext);
++ENCODER_DEC(IOP_ServiceContextList);
++ENCODER_DEC(CORBA_sequence_octet);
++ENCODER_DEC(CORBA_Principal);
++#define giop_encoder_CORBA_Principal(rb, mem) \
++ giop_encoder_CORBA_sequence_octet(rb, mem)
++ENCODER_DEC(CORBA_char);
++
++#endif /* ENCODERS_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-endian.c linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.c
+--- linux-2.4.1/net/korbit/IIOP/iiop-endian.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.c Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,12 @@
++#define IIOP_DO_NOT_INLINE_IIOP_BYTESWAP
++#include "iiop-endian.h"
++
++void iiop_byteswap(guchar *outdata,
++ const guchar *data,
++ gulong datalen)
++{
++ const guchar *source_ptr = data;
++ guchar *dest_ptr = (guchar *)outdata + datalen - 1;
++ while(dest_ptr >= outdata)
++ *dest_ptr-- = *source_ptr++;
++}
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-endian.h linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.h
+--- linux-2.4.1/net/korbit/IIOP/iiop-endian.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.h Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,42 @@
++#ifndef IIOP_ENDIAN_H
++#define IIOP_ENDIAN_H 1
++
++#include <glib.h>
++
++#if G_BYTE_ORDER == G_BIG_ENDIAN
++
++# define FLAG_ENDIANNESS FLAG_BIG_ENDIAN
++# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_BIG_ENDIAN)
++
++#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
++
++# define FLAG_ENDIANNESS FLAG_LITTLE_ENDIAN
++# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_LITTLE_ENDIAN)
++
++#else
++
++#error "Unsupported endianness on this system."
++
++#endif
++
++#define FLAG_BIG_ENDIAN 0
++#define FLAG_LITTLE_ENDIAN 1
++
++/* This is also defined in IIOP-types.c */
++void iiop_byteswap(guchar *outdata,
++ const guchar *data,
++ gulong datalen);
++
++#if defined(G_CAN_INLINE) && !defined(IIOP_DO_NOT_INLINE_IIOP_BYTESWAP)
++G_INLINE_FUNC void iiop_byteswap(guchar *outdata,
++ const guchar *data,
++ gulong datalen)
++{
++ const guchar *source_ptr = data;
++ guchar *dest_ptr = outdata + datalen - 1;
++ while(dest_ptr >= outdata)
++ *dest_ptr-- = *source_ptr++;
++}
++#endif
++
++#endif
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-endianP.h linux-2.4.1-korbit/net/korbit/IIOP/iiop-endianP.h
+--- linux-2.4.1/net/korbit/IIOP/iiop-endianP.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-endianP.h Thu Feb 1 16:19:47 2001
+@@ -0,0 +1,11 @@
++#ifndef IIOP_ENDIANP_H
++#define IIOP_ENDIANP_H 1
++
++/* This is pretty much "here" */
++
++#include "config.h"
++#include "IIOP.h"
++
++#include "iiop-endian.h"
++
++#endif /* !IIOP_ENDIANP_H */
+diff -urN linux-2.4.1/net/korbit/Makefile linux-2.4.1-korbit/net/korbit/Makefile
+--- linux-2.4.1/net/korbit/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/Makefile Thu Feb 1 15:57:33 2001
+@@ -0,0 +1,22 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := korbit.o
++
++subdir-y := kglib orb IIOP ORBitutil modules
++subdir-m := modules
++
++obj-y := kglib/kglib.o orb/orblib.o IIOP/IIOPlib.o ORBitutil/ORBitutillib.o exported_symbols.o
++
++export-objs := exported_symbols.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I./include -I./kglib -I./ORBitutil -nostdinc
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/ORBitutil/CVS/Entries linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Entries
+--- linux-2.4.1/net/korbit/ORBitutil/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Entries Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,13 @@
++/Makefile/1.4/Thu Feb 1 09:46:52 2001//
++/basic_types.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/compat.c/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/compat.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/orbit-os-config.h/1.2/Thu Feb 1 09:46:52 2001//
++/os-feature-alloca.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/os-specifics.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/thread-safety.c/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/thread-safety.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/trace.c/1.2/Thu Feb 1 09:46:52 2001//
++/trace.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/util.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++D
+diff -urN linux-2.4.1/net/korbit/ORBitutil/CVS/Repository linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Repository
+--- linux-2.4.1/net/korbit/ORBitutil/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Repository Thu Feb 1 11:46:51 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/ORBitutil
+diff -urN linux-2.4.1/net/korbit/ORBitutil/CVS/Root linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Root
+--- linux-2.4.1/net/korbit/ORBitutil/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Root Thu Feb 1 11:46:51 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/ORBitutil/Makefile linux-2.4.1-korbit/net/korbit/ORBitutil/Makefile
+--- linux-2.4.1/net/korbit/ORBitutil/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/Makefile Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,17 @@
++#
++# Makefile for KORBit/ORBitutil
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .o file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := ORBitutillib.o
++
++#obj-m := $(O_TARGET)
++obj-y := compat.o thread-safety.o trace.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I.. -I../include -I../kglib -I../ORBitutil -nostdinc
++
++include $(TOPDIR)/Rules.make
+diff -urN linux-2.4.1/net/korbit/ORBitutil/basic_types.h linux-2.4.1-korbit/net/korbit/ORBitutil/basic_types.h
+--- linux-2.4.1/net/korbit/ORBitutil/basic_types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/basic_types.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,46 @@
++#ifndef BASIC_TYPES_H
++#define BASIC_TYPES_H 1
++
++#include <glib.h>
++
++typedef gint16 CORBA_short;
++typedef gint32 CORBA_long;
++typedef guint16 CORBA_unsigned_short;
++typedef guint32 CORBA_unsigned_long;
++typedef gfloat CORBA_float;
++typedef gdouble CORBA_double;
++typedef char CORBA_char;
++typedef guchar CORBA_boolean;
++typedef guchar CORBA_octet;
++typedef gdouble CORBA_long_double;
++typedef guint16 CORBA_wchar; /* I'm not sure what size a wchar is supposed to be */
++
++/* Just a peeve */
++typedef CORBA_char GIOP_char;
++typedef CORBA_wchar GIOP_wchar;
++typedef CORBA_short GIOP_short;
++typedef CORBA_long GIOP_long;
++typedef CORBA_unsigned_short GIOP_unsigned_short;
++typedef CORBA_unsigned_long GIOP_unsigned_long;
++typedef CORBA_octet GIOP_octet;
++typedef CORBA_long GIOP_enum;
++typedef CORBA_boolean GIOP_boolean;
++typedef CORBA_float GIOP_float;
++typedef CORBA_double GIOP_double;
++typedef CORBA_long_double GIOP_long_double;
++
++#ifdef G_HAVE_GINT64
++#define HAVE_CORBA_LONG_LONG
++/* According to the spec, these two are optional. We support them if we can. */
++typedef gint64 CORBA_long_long;
++typedef guint64 CORBA_unsigned_long_long;
++typedef CORBA_long_long GIOP_long_long;
++typedef CORBA_unsigned_long_long GIOP_unsigned_long_long;
++#else
++#warning ""
++#warning "You don't G_HAVE_GINT64 defined in glib."
++#warning "Please make sure you don't have an old glibconfig.h lying around."
++#warning ""
++#endif
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/compat.c linux-2.4.1-korbit/net/korbit/ORBitutil/compat.c
+--- linux-2.4.1/net/korbit/ORBitutil/compat.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/compat.c Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,43 @@
++#include "config.h"
++#include "util.h"
++
++#define MAX_IOVS 16
++
++int g_writev(int fd, const struct iovec * vector, size_t count)
++{
++ int retval = 0;
++
++ while(count > MAX_IOVS) {
++ retval += writev(fd, vector, MAX_IOVS);
++ vector += MAX_IOVS; count -= MAX_IOVS;
++ }
++
++ return writev(fd, vector, count) + retval;
++}
++
++#ifndef HAVE_INET_ATON
++#include <netinet/in.h>
++#include <string.h>
++int inet_aton(const char *cp, struct in_addr *inp)
++{
++ union {
++ unsigned int n;
++ char parts[4];
++ } u;
++ int a=0,b=0,c=0,d=0, i;
++
++ i = sscanf(cp, "%d.%d.%d.%d%*s", &a, &b, &c, &d);
++
++ if(i != 4)
++ return 0;
++
++ u.parts[0] = a;
++ u.parts[1] = b;
++ u.parts[2] = c;
++ u.parts[3] = d;
++
++ inp->s_addr = u.n;
++
++ return 1;
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/compat.h linux-2.4.1-korbit/net/korbit/ORBitutil/compat.h
+--- linux-2.4.1/net/korbit/ORBitutil/compat.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/compat.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,8 @@
++#ifndef ORBITUTIL_COMPAT_H
++#define ORBITUTIL_COMPAT_H 1
++#include <sys/types.h>
++#include <sys/uio.h>
++
++int g_writev(int fd, const struct iovec * vector, size_t count);
++
++#endif /*#define ORBITUTIL_COMPAT_H 1 */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/orbit-os-config.h linux-2.4.1-korbit/net/korbit/ORBitutil/orbit-os-config.h
+--- linux-2.4.1/net/korbit/ORBitutil/orbit-os-config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/orbit-os-config.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,8 @@
++#ifndef OS_CONFIG_H
++#define OS_CONFIG_H 1
++
++#ifndef __KORBIT__
++#define ORBIT_HAVE_ALLOCA_H 1
++#endif
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/os-feature-alloca.h linux-2.4.1-korbit/net/korbit/ORBitutil/os-feature-alloca.h
+--- linux-2.4.1/net/korbit/ORBitutil/os-feature-alloca.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/os-feature-alloca.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,26 @@
++#ifndef OS_FEATURE_ALLOCA_H
++#define OS_FEATURE_ALLOCA_H 1
++
++# if ORBIT_HAVE_ALLOCA_H
++# include <alloca.h>
++# endif
++
++# include <string.h>
++
++# if defined(__GNUC__)
++
++# if defined(__STRICT_ANSI__)
++# define alloca __builtin_alloca
++# endif
++
++# elif !(ORBIT_HAVE_ALLOCA_H)
++
++# if defined(_AIX)
++ #pragma alloca
++# elif !defined(alloca) /* predefined by HP cc +Olibcalls */
++char *alloca ();
++# endif
++
++# endif /* __GNUC__ etc. */
++
++#endif /* OS_FEATURE_ALLOCA_H */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/os-specifics.h linux-2.4.1-korbit/net/korbit/ORBitutil/os-specifics.h
+--- linux-2.4.1/net/korbit/ORBitutil/os-specifics.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/os-specifics.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,12 @@
++#ifndef ORBITUTIL_OS_SPECIFICS_H
++#define ORBITUTIL_OS_SPECIFICS_H 1
++
++#include <ORBitutil/orbit-os-config.h>
++
++#include <ORBitutil/os-feature-alloca.h>
++
++/* This file should be a bunch of #ifdef's to #include the
++ os-<osname>.h for the current OS. It is intended to abstract the
++ gunkiness necessary to get some OS's to build ORBit properly. */
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/thread-safety.c linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.c
+--- linux-2.4.1/net/korbit/ORBitutil/thread-safety.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.c Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,19 @@
++#include "util.h"
++
++#ifdef NOT_REENTRANT
++#include <pthread.h>
++
++pthread_key_t thread_data;
++
++void init_thread_data(void) __attribute__ ((constructor));
++
++void init_thread_data(void)
++{
++ pthread_key_create(&thread_data, NULL);
++}
++
++#else
++
++gpointer prog_data = NULL;
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/thread-safety.h linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.h
+--- linux-2.4.1/net/korbit/ORBitutil/thread-safety.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,36 @@
++#ifndef THREAD_SAFETY_H
++#define THREAD_SAFETY_H 1
++
++#ifdef NOT_REENTRANT
++
++#include <pthread.h>
++
++#define DEFINE_LOCK(x) pthread_mutex_t x##_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
++#define INIT_LOCK(x) /* We use static initialization, see above */
++#define GET_LOCK(x) pthread_mutex_lock(&x##_lock)
++#define RELEASE_LOCK(x) pthread_mutex_unlock(&x##_lock)
++#define PARAM_LOCK(x) pthread_mutex_t x##_lock
++#define LOCK_NAME(x) x##_lock
++#define EXTERN_LOCK(x) extern pthread_mutex_t x##_lock
++extern pthread_key_t thread_data;
++#define GET_THREAD_DATA() pthread_getspecific(thread_data)
++#define SET_THREAD_DATA(x) pthread_setspecific(thread_data, (x))
++
++#else
++
++/* stupid work around ANSI & empty semicolons. */
++#define DEFINE_LOCK(x)
++#define INIT_LOCK(x)
++#define GET_LOCK(x)
++#define RELEASE_LOCK(x)
++#define PARAM_LOCK(x) gpointer x##_lock
++#define LOCK_NAME(x) NULL
++#define EXTERN_LOCK(x)
++
++extern gpointer prog_data;
++#define GET_THREAD_DATA() prog_data
++#define SET_THREAD_DATA(x) (prog_data = (x))
++
++#endif
++
++#endif /* THREAD_SAFETY_H */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/trace.c linux-2.4.1-korbit/net/korbit/ORBitutil/trace.c
+--- linux-2.4.1/net/korbit/ORBitutil/trace.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/trace.c Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,94 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ *
++ */
++
++#include <stdio.h>
++#include <stdarg.h>
++
++#include "trace.h"
++
++/*
++ * The function to call to handle trace messages, or NULL to use the default
++ * of printing to stderr.
++ */
++#ifdef ORBIT_DEBUG
++static int (* TraceCallback)(char *, va_list)=NULL;
++static int TraceModules=0;
++static ORBit_TraceLevel TraceMaxLevel=0;
++
++const char *ORBit_Trace_levellist[] = {
++ "ALERT ",
++ "CRITICAL",
++ "ERROR ",
++ "WARNING ",
++ "NOTICE ",
++ "INFO ",
++ "DEBUG "
++};
++
++void ORBit_Trace_setCallback(int (*cbf)(char *, va_list))
++{
++ TraceCallback=cbf;
++}
++
++int (*ORBit_Trace_getCallback(void))(char *, va_list)
++{
++ return(TraceCallback);
++}
++
++void ORBit_Trace_setModules(int modules)
++{
++ TraceModules=modules;
++}
++
++void ORBit_Trace_setLevel(ORBit_TraceLevel level)
++{
++ TraceMaxLevel=level;
++}
++
++int ORBit_Trace(ORBit_TraceModule module, ORBit_TraceLevel level, char *fmt, ...)
++{
++ va_list args;
++
++ if(!BitTest(TraceModules, module))
++ return 0;
++ if(TraceMaxLevel < level)
++ return 0;
++
++ va_start(args, fmt);
++ if(TraceCallback!=NULL)
++ return((*TraceCallback)(fmt, args));
++
++#ifdef __KORBIT__
++ printf("[%s]: ", ORBit_Trace_levellist[level]);
++
++ printf("%s", g_strdup_vprintf(fmt, args));
++ return 0; // breaks semantics, but return value is never used
++#else /* !__KORBIT__ */
++ fprintf(stderr, "[%s]: ", ORBit_Trace_levellist[level]);
++
++ return vfprintf(stderr, fmt, args);
++#endif /* !__KORBIT__ */
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/trace.h linux-2.4.1-korbit/net/korbit/ORBitutil/trace.h
+--- linux-2.4.1/net/korbit/ORBitutil/trace.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/trace.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,68 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ *
++ */
++
++#ifndef _ORBIT_TRACE_H_
++#define _ORBIT_TRACE_H_
++
++#include <stdarg.h>
++#include "util.h"
++
++typedef enum {
++ TraceMod_ORB,
++ TraceMod_CDR,
++ TraceMod_IIOP,
++ TraceMod_TC,
++ TraceMod_IR,
++ TraceMod_User=32
++} ORBit_TraceModule;
++
++typedef enum {
++ TraceLevel_Alert=0,
++ TraceLevel_Critical,
++ TraceLevel_Error,
++ TraceLevel_Warning,
++ TraceLevel_Notice,
++ TraceLevel_Info,
++ TraceLevel_Debug
++} ORBit_TraceLevel;
++
++extern const char *ORBit_Trace_levellist[];
++
++#ifdef ORBIT_DEBUG
++extern void ORBit_Trace_setCallback(int (*)(char *, va_list));
++extern int (*ORBit_Trace_getCallback(void))(char *, va_list);
++extern void ORBit_Trace_setModules(int);
++extern void ORBit_Trace_setLevel(ORBit_TraceLevel);
++extern int ORBit_Trace(ORBit_TraceModule, ORBit_TraceLevel, char *, ...);
++#else
++#define ORBit_Trace_setCallback(x)
++#define ORBit_Trace_getCallback() NULL
++#define ORBit_Trace_setModules(x)
++#define ORBit_Trace_setLevel(x)
++#define ORBit_Trace(module,level,fmt,args...)
++#endif
++
++
++#endif /* !_ORBIT_TRACE_H_ */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/util.h linux-2.4.1-korbit/net/korbit/ORBitutil/util.h
+--- linux-2.4.1/net/korbit/ORBitutil/util.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/util.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,35 @@
++#ifndef UTIL_H
++#define UTIL_H 1
++
++#include <glib.h>
++
++#define ORBIT_DEBUG 1
++
++#ifdef ORBIT_DEBUG
++#define ORBIT_DEBUG_NOTE(x) (x)
++#else
++#define ORBIT_DEBUG_NOTE(x)
++#endif
++
++
++#define BitTest(f, bit) ((f) & (1<<(bit)))
++#define BitSet(f, bit) ((f) |= (1<<(bit)))
++#define BitClr(f, bit) ((f) &= ~(1<<(bit)))
++/* Align an address upward to a boundary, expressed as a number of bytes.
++ E.g. align to an 8-byte boundary with argument of 8. */
++
++/*
++ * (this + boundary - 1)
++ * &
++ * ~(boundary - 1)
++ */
++
++#define ALIGN_ADDRESS(this, boundary) \
++ ((gpointer)((( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))))
++
++#include <ORBitutil/thread-safety.h>
++#include <ORBitutil/trace.h>
++#include <ORBitutil/compat.h>
++#include <ORBitutil/os-specifics.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/config.h linux-2.4.1-korbit/net/korbit/config.h
+--- linux-2.4.1/net/korbit/config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/config.h Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,73 @@
++
++/* Define if you have alloca, as a function or macro. */
++#define HAVE_ALLOCA 1
++
++#define HAVE_ATEXIT 1
++#define NO_SYS_SIGLIST 1 /* reduce dependencies */
++#define NO_SYS_ERRLIST 1 /* reduce dependencies */
++
++/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
++/* #define HAVE_ALLOCA_H 1 */
++
++/* Define if you have the vprintf function. */
++#define HAVE_VPRINTF 1
++
++/* Define if you have the ANSI C header files. */
++#define STDC_HEADERS 1
++
++#define HAVE_INET_ATON 1
++/* #undef ORBIT_SERIAL */
++
++/* Define to 'int' if it isn't defined in the header files. */
++/* #undef socklen_t */
++
++#define ALIGNOF_CORBA_BOOLEAN 1
++#define ALIGNOF_CORBA_CHAR 1
++#define ALIGNOF_CORBA_DOUBLE 4
++#define ALIGNOF_CORBA_FLOAT 4
++#define ALIGNOF_CORBA_LONG 4
++#define ALIGNOF_CORBA_LONG_DOUBLE 4
++#define ALIGNOF_CORBA_LONG_LONG 4
++#define ALIGNOF_CORBA_OCTET 1
++#define ALIGNOF_CORBA_SHORT 2
++#define ALIGNOF_CORBA_STRUCT 1
++#define ALIGNOF_CORBA_UNSIGNED_LONG 4
++#define ALIGNOF_CORBA_UNSIGNED_LONG_LONG 4
++#define ALIGNOF_CORBA_UNSIGNED_SHORT 2
++#define ALIGNOF_CORBA_WCHAR 2
++#define ALIGNOF_CORBA_POINTER 4
++
++/* TCP wrappers */
++#define HAVE_TCPD_H 1
++
++#ifdef HAVE_ALLOCA_H
++#include <alloca.h>
++#endif
++
++/* Define if you have the basename function. */
++#define HAVE_BASENAME 1
++
++/* Define if you have the poll function. */
++#define HAVE_POLL 1
++#define I_WANT_POLL 1
++
++/* Define if you have the <endian.h> header file. */
++#define HAVE_ENDIAN_H 1
++
++/* Define if you have the <fcntl.h> header file. */
++#define HAVE_FCNTL_H 1
++
++/* Define if you have the <stddef.h> header file. */
++#define HAVE_STDDEF_H 1
++
++/* Define if you have the <sys/poll.h> header file. */
++#define HAVE_SYS_POLL_H 1
++
++/* Define if you have the <tcpd.h> header file. */
++#define HAVE_TCPD_H 1
++
++/* Define if you have the <unistd.h> header file. */
++#define HAVE_UNISTD_H 1
++
++/* Define if you have the <wchar.h> header file. */
++#define HAVE_WCHAR_H 1
+diff -urN linux-2.4.1/net/korbit/exported_symbols.c linux-2.4.1-korbit/net/korbit/exported_symbols.c
+--- linux-2.4.1/net/korbit/exported_symbols.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/exported_symbols.c Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,93 @@
++/*
++ * #include whatever it takes to get the EXPORT_SYMBOL macro, and
++ * whatever header files from korbit (for things that are being
++ * exported.
++ */
++#include <linux/config.h>
++#include <linux/module.h>
++#include "errno.h"
++#include "orb/orbit.h"
++
++/*
++ * Stuff that's good to export
++ */
++EXPORT_SYMBOL(errno);
++
++/*
++ * kglib exports...
++ */
++EXPORT_SYMBOL(g_malloc0);
++EXPORT_SYMBOL(g_free);
++EXPORT_SYMBOL(g_snprintf);
++
++/*
++ * Mainline CORBA symbols.
++ */
++EXPORT_SYMBOL(CORBA_exception_init);
++EXPORT_SYMBOL(CORBA_ORB_init);
++EXPORT_SYMBOL(CORBA_ORB_resolve_initial_references);
++EXPORT_SYMBOL(CORBA_ORB_object_to_string);
++EXPORT_SYMBOL(CORBA_free);
++EXPORT_SYMBOL(CORBA_ORB_run);
++EXPORT_SYMBOL(CORBA_Object_release);
++EXPORT_SYMBOL(CORBA_Object_duplicate);
++EXPORT_SYMBOL(CORBA_octet_allocbuf);
++EXPORT_SYMBOL(CORBA_exception_set);
++EXPORT_SYMBOL(CORBA_string__free);
++EXPORT_SYMBOL(CORBA_ORB_string_to_object);
++EXPORT_SYMBOL(CORBA_string_alloc);
++EXPORT_SYMBOL(CORBA_exception_set_system);
++
++/*
++ * ORBIT Specific symbols to export
++ */
++EXPORT_SYMBOL(ORBit_TypeCode_epv);
++EXPORT_SYMBOL(ORBit_send_system_exception);
++EXPORT_SYMBOL(ORBit_register_class);
++EXPORT_SYMBOL(ORBit_marshal_object);
++EXPORT_SYMBOL(ORBit_alloc);
++EXPORT_SYMBOL(ORBit_free);
++EXPORT_SYMBOL(ORBit_send_user_exception);
++EXPORT_SYMBOL(ORBit_delete_profiles);
++EXPORT_SYMBOL(ORBit_demarshal_object);
++EXPORT_SYMBOL(_ORBit_object_get_connection);
++EXPORT_SYMBOL(ORBit_handle_exception);
++EXPORT_SYMBOL(ORBit_object_get_forwarded_connection);
++EXPORT_SYMBOL(ORBit_default_principal_iovec);
++EXPORT_SYMBOL(ORBit_demarshal_IOR);
++
++/*
++ * CORBA giop functions
++ */
++EXPORT_SYMBOL(giop_send_buffer_write);
++EXPORT_SYMBOL(giop_send_buffer_unuse);
++EXPORT_SYMBOL(giop_message_buffer_do_alignment);
++EXPORT_SYMBOL(giop_message_buffer_append_mem);
++EXPORT_SYMBOL(giop_send_reply_buffer_use);
++EXPORT_SYMBOL(giop_send_request_buffer_use);
++EXPORT_SYMBOL(giop_recv_buffer_unuse);
++EXPORT_SYMBOL(giop_recv_reply_buffer_use_2);
++
++/*
++ * POA Symbols.
++ */
++EXPORT_SYMBOL(PortableServer_POAManager_activate);
++EXPORT_SYMBOL(PortableServer_POA_activate_object_with_id);
++EXPORT_SYMBOL(PortableServer_POA_servant_to_reference);
++EXPORT_SYMBOL(PortableServer_POA_deactivate_object);
++EXPORT_SYMBOL(PortableServer_POA__get_the_POAManager);
++EXPORT_SYMBOL(PortableServer_ServantBase__init);
++EXPORT_SYMBOL(PortableServer_ServantBase__fini);
++EXPORT_SYMBOL(PortableServer_POA_reference_to_servant);
++EXPORT_SYMBOL(PortableServer_POA_servant_to_id);
++EXPORT_SYMBOL(PortableServer_POA_activate_object);
++EXPORT_SYMBOL(PortableServer_POA_reference_to_id);
++
++/*
++ * TC Stuff (whatever that is)
++ */
++EXPORT_SYMBOL(TC_octet_struct);
++EXPORT_SYMBOL(TC_long_struct);
++EXPORT_SYMBOL(TC_ulong_struct);
++EXPORT_SYMBOL(TC_short_struct);
++EXPORT_SYMBOL(TC_string_struct);
+diff -urN linux-2.4.1/net/korbit/include/.cvsignore linux-2.4.1-korbit/net/korbit/include/.cvsignore
+--- linux-2.4.1/net/korbit/include/.cvsignore Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/.cvsignore Thu Feb 1 11:46:53 2001
+@@ -0,0 +1 @@
++stdarg.h
+diff -urN linux-2.4.1/net/korbit/include/CVS/Entries linux-2.4.1-korbit/net/korbit/include/CVS/Entries
+--- linux-2.4.1/net/korbit/include/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Entries Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,24 @@
++/.cvsignore/1.1/Thu Feb 1 09:46:53 2001//
++/alloca.h/1.3/Thu Feb 1 09:46:53 2001//
++/assert.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/ctype.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/dirent.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/errno.h/1.2/Thu Feb 1 09:46:53 2001//
++/fcntl.h/1.3/Thu Feb 1 09:46:53 2001//
++/host_list.h/1.7/Thu Feb 1 09:46:53 2001//
++/limits.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/locale.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/math.h/1.2/Thu Feb 1 09:46:53 2001//
++/netdb.h/1.17/Thu Feb 1 09:46:53 2001//
++/pwd.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/signal.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/stdarg.h/1.3/Thu Feb 1 09:46:54 2001//
++/stddef.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++/stdio.h/1.19/Thu Feb 1 09:46:54 2001//
++/stdlib.h/1.4/Thu Feb 1 09:46:54 2001//
++/string.h/1.3/Thu Feb 1 09:46:54 2001//
++/syslog.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++/time.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++/unistd.h/1.3/Thu Feb 1 09:46:54 2001//
++/utime.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/include/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/include/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Entries.Log Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,3 @@
++A D/arpa////
++A D/netinet////
++A D/sys////
+diff -urN linux-2.4.1/net/korbit/include/CVS/Repository linux-2.4.1-korbit/net/korbit/include/CVS/Repository
+--- linux-2.4.1/net/korbit/include/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Repository Thu Feb 1 11:46:53 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include
+diff -urN linux-2.4.1/net/korbit/include/CVS/Root linux-2.4.1-korbit/net/korbit/include/CVS/Root
+--- linux-2.4.1/net/korbit/include/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Root Thu Feb 1 11:46:53 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/alloca.h linux-2.4.1-korbit/net/korbit/include/alloca.h
+--- linux-2.4.1/net/korbit/include/alloca.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/alloca.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,6 @@
++#ifndef __KORBIT_ALLOCA_H__
++#define __KORBIT_ALLOCA_H__
++
++#include <stdlib.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/arpa/CVS/Entries linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Entries
+--- linux-2.4.1/net/korbit/include/arpa/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Entries Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,2 @@
++/inet.h/1.4/Thu Feb 1 09:46:54 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/arpa/CVS/Repository linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Repository
+--- linux-2.4.1/net/korbit/include/arpa/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Repository Thu Feb 1 11:46:54 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include/arpa
+diff -urN linux-2.4.1/net/korbit/include/arpa/CVS/Root linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Root
+--- linux-2.4.1/net/korbit/include/arpa/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Root Thu Feb 1 11:46:54 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/arpa/inet.h linux-2.4.1-korbit/net/korbit/include/arpa/inet.h
+--- linux-2.4.1/net/korbit/include/arpa/inet.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/inet.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,50 @@
++#ifndef __KORBIT_ARPA_INET_H__
++#define __KORBIT_ARPA_INET_H__
++
++#include <linux/inet.h>
++#include <linux/in.h>
++
++static inline char* inet_ntoa(struct in_addr in)
++{
++ return in_ntoa(in.s_addr);
++}
++
++static inline int inet_aton(const char *cp, struct in_addr *inp)
++{
++ unsigned long l;
++ unsigned int val;
++ int i;
++
++ if (!cp || !inp)
++ return 0;
++
++ l = 0;
++ for (i = 0; i < 4; i++)
++ {
++ l <<= 8;
++ if (*cp != '\0')
++ {
++ val = 0;
++ while (*cp != '\0' && *cp != '.')
++ {
++ if (*cp < '0' || '9' < *cp)
++ return 0;
++
++ val *= 10;
++ val += *cp - '0';
++ cp++;
++ }
++ if (val > 255)
++ return 0;
++
++ l |= val;
++ if (*cp != '\0')
++ cp++;
++ }
++ }
++ inp->s_addr = htonl(l);
++
++ return 1;
++}
++
++#endif /* __KORBIT_ARPA_INET_H__ */
+diff -urN linux-2.4.1/net/korbit/include/assert.h linux-2.4.1-korbit/net/korbit/include/assert.h
+--- linux-2.4.1/net/korbit/include/assert.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/assert.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_ASSERT_H__
++#define __KORBIT_ASSERT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/ctype.h linux-2.4.1-korbit/net/korbit/include/ctype.h
+--- linux-2.4.1/net/korbit/include/ctype.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/ctype.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_CTYPE_H__
++#define __KORBIT_CTYPE_H__
++#include <linux/ctype.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/dirent.h linux-2.4.1-korbit/net/korbit/include/dirent.h
+--- linux-2.4.1/net/korbit/include/dirent.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/dirent.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_DIRENT_H__
++#define __KORBIT_DIRENT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/errno.h linux-2.4.1-korbit/net/korbit/include/errno.h
+--- linux-2.4.1/net/korbit/include/errno.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/errno.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,9 @@
++#ifndef __KORBIT_ERRNO_H__
++#define __KORBIT_ERRNO_H__
++
++#include <asm/errno.h>
++
++#define errno korbit_errno
++extern int korbit_errno;
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/fcntl.h linux-2.4.1-korbit/net/korbit/include/fcntl.h
+--- linux-2.4.1/net/korbit/include/fcntl.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/fcntl.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,49 @@
++#ifndef __KORBIT_FCNTL_H__
++#define __KORBIT_FCNTL_H__
++
++#include <linux/mm.h>
++#include <linux/file.h>
++#include <linux/smp_lock.h>
++
++#include <asm/fcntl.h>
++
++#include <stdio.h>
++
++#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
++
++static inline int fcntl(int fd, int cmd, long arg)
++{
++ struct file *filp = fd2file(fd);
++ long err = -EINVAL;
++
++ switch (cmd)
++ {
++ case F_SETFD:
++ case F_GETFD:
++ err = 0;
++ break;
++ case F_GETFL:
++ if (filp)
++ err = filp->f_flags;
++ break;
++ case F_SETFL:
++ if (filp)
++ {
++ lock_kernel();
++
++ /* required for strict SunOS emulation */
++ if (O_NONBLOCK != O_NDELAY)
++ if (arg & O_NDELAY)
++ arg |= O_NONBLOCK;
++
++ filp->f_flags = (arg & SETFL_MASK) |
++ (filp->f_flags & ~SETFL_MASK);
++ err = 0;
++ unlock_kernel();
++ }
++ break;
++ }
++ return err;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/host_list.h linux-2.4.1-korbit/net/korbit/include/host_list.h
+--- linux-2.4.1/net/korbit/include/host_list.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/host_list.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,24 @@
++/*
++ * A statically-allocated list of Hostnames<->IPv4 addresses.
++ */
++#ifndef __KORBIT_HOST_LIST_H
++#define __KORBIT_HOST_LIST_H
++
++static struct {
++ char *name;
++ char *IP;
++} host_table[] = {
++ {"redefine.dyndns.org", "206.221.225.140"},
++ {"csil-sunb4.cs.uiuc.edu", "128.174.243.204"},
++ {"kazoo.cs.uiuc.edu", "128.174.237.133"},
++ {"opus0.cs.uiuc.edu", "128.174.236.20"},
++ {"wakeland-56.flexabit.net", "64.198.239.56"},
++ {"es-dcl-border1.cso.uiuc.edu", "127.0.0.1"},
++ {"es-dcl-border1", "127.0.0.1"}
++// {"es-dcl-border1.cso.uiuc.edu", "130.126.112.222"},
++// {"es-dcl-border1", "130.126.112.222"}
++};
++
++#define __MAX_STATIC_NAMES (sizeof(host_table) / sizeof(host_table[0]))
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/limits.h linux-2.4.1-korbit/net/korbit/include/limits.h
+--- linux-2.4.1/net/korbit/include/limits.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/limits.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,7 @@
++#ifndef __KORBIT_LIMITS_H__
++#define __KORBIT_LIMITS_H__
++
++#include <linux/limits.h>
++#include <linux/kernel.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/locale.h linux-2.4.1-korbit/net/korbit/include/locale.h
+--- linux-2.4.1/net/korbit/include/locale.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/locale.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_LOCALE_H__
++#define __KORBIT_LOCALE_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/math.h linux-2.4.1-korbit/net/korbit/include/math.h
+--- linux-2.4.1/net/korbit/include/math.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/math.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,16 @@
++#ifndef __KORBIT_MATH_H__
++#define __KORBIT_MATH_H__
++
++#include <asm/page.h>
++
++static inline double pow(double x, double y) {
++ double Q = 1.0;
++ if (y < 0)
++ BUG();
++/* return 1.0/pow(x,-y);*/
++ while (y-- > 0)
++ Q *= x;
++ return Q;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/netdb.h linux-2.4.1-korbit/net/korbit/include/netdb.h
+--- linux-2.4.1/net/korbit/include/netdb.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netdb.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,197 @@
++#ifndef __KORBIT_NETDB_H__
++#define __KORBIT_NETDB_H__
++
++#include <sys/socket.h>
++#include <linux/in.h>
++#include <arpa/inet.h>
++#include "host_list.h"
++
++#define h_errno 0
++/* static int h_errno; */
++
++/* Description of data base entry for a single host. */
++struct hostent
++{
++ char *h_name; /* Official name of host. */
++ char **h_aliases; /* Alias list. */
++ int h_addrtype; /* Host address type. */
++ socklen_t h_length; /* Length of address. */
++ char **h_addr_list; /* List of addresses from name server. */
++#define h_addr h_addr_list[0] /* Address, for backward compatibility. */
++};
++
++/* Is this defined somewhere else? */
++/*struct in_addr {
++ __uint32_t s_addr;
++};*/
++
++/*
++ * Set h_errno?
++ * #define HOST_NOT_FOUND 1
++ * #define TRY_AGAIN 2
++ * #define NO_RECOVERY 3
++ * #define NO_DATA 4
++ */
++static inline struct hostent *gethostbyname (char *host)
++{
++ int c;
++ static struct in_addr tmp_in;
++ static struct hostent ret_host;
++ static char *aliases[2];
++ static char *addrs[2];
++
++ if (host == NULL)
++ {
++ printf ("** gethostbyname() Error: Got NULL parameter! **\n");
++ return (NULL);
++ }
++
++ /*
++ * The actual lookup.
++ */
++ for (c = 0; c < __MAX_STATIC_NAMES; c++)
++ {
++ if (host_table[c].name && strncmp (host, host_table[c].name, strlen(host_table[c].name)) == 0)
++ {
++/* printf ("Name '%s' found at position %d!\n", argv[1], c);*/
++/* printf ("IP address is: '%s'.\n", IPs[c]);*/
++ break;
++ }
++ }
++
++ if (c == __MAX_STATIC_NAMES)
++ {
++ /* Host not found, return NULL. */
++ return (NULL);
++ }
++ /* else, names[c] is gold! */
++
++ /* make a new hostent, ret_host */
++
++ ret_host.h_addrtype = AF_INET;
++ ret_host.h_aliases = aliases;
++ aliases[0] = host_table[c].name;
++ aliases[1] = NULL;
++ ret_host.h_name = host_table[c].name;
++ if (!inet_aton (host_table[c].IP, &tmp_in))
++ {
++ printf ("** gethostbyname() Error: Invalid IP address in table! **\n");
++ return (NULL);
++ }
++ ret_host.h_addr_list = addrs;
++ addrs[0] = (char *)&tmp_in.s_addr;
++ addrs[1] = NULL;
++ ret_host.h_length = sizeof (tmp_in.s_addr);
++ return (&ret_host);
++} /* End gethostbyname(). */
++
++/*
++ * TODO: getpeername(), gethostbyaddr(), getsockname(), gethostname()
++ * Everything from here-on has been untested (in userland). Buyer beware.
++ */
++static inline struct hostent *gethostbyaddr (const char *addr, int len, int type)
++{
++ struct in_addr tin;
++ char *inp_addr;
++ int c;
++ static struct hostent ret_host;
++ static char *aliases[1];
++ static char *addrs[2];
++ static struct in_addr tmp_in;
++
++
++ if ((type != AF_INET) || (len != 4))
++ {
++ printf ("** gethostbyaddr Error: Don't know how to deal with non-AF_INET addresses! **\n");
++ return (NULL);
++ }
++
++ tin.s_addr = *((__u32 *)addr);
++ inp_addr = inet_ntoa (tin);
++ if (inp_addr == NULL)
++ {
++ /* We got some invalid input, baby. */
++ return (NULL);
++
++ }
++
++ /*
++ * The actual lookup.
++ */
++ for (c = 0; c < __MAX_STATIC_NAMES; c++)
++ {
++ if (host_table[c].IP && strncmp (inp_addr, host_table[c].IP, strlen(host_table[c].IP)) == 0)
++ {
++ break;
++ }
++ }
++
++ if (c == __MAX_STATIC_NAMES)
++ {
++ /* Host not found, return NULL. */
++ return (NULL);
++ }
++ /* else, host_table[c].IP is gold! */
++
++ ret_host.h_addrtype = AF_INET;
++ ret_host.h_aliases = aliases;
++ aliases[0] = NULL;
++ ret_host.h_name = host_table[c].name;
++ if (!inet_aton (host_table[c].IP, &tmp_in))
++ {
++ printf ("** gethostbyname() Error: Invalid IP address in table! **\n");
++ return (NULL);
++ }
++ ret_host.h_addr_list = addrs;
++ addrs[0] = (char *)&tmp_in.s_addr;
++ addrs[1] = NULL;
++ ret_host.h_length = sizeof (tmp_in.s_addr);
++ return (&ret_host);
++} /* End gethostbyaddr(). */
++
++/*
++ * If successful, return 0. Else, return -1 and set errno.
++ * Errors:
++ * EBADF The argument s is not a valid file descriptor.
++ *
++ * ENOMEM
++ * There was insufficient memory available for the opera-
++ * tion to complete.
++ *
++ * ENOSR There were insufficient STREAMS resources available
++ * for the operation to complete.
++ *
++ * ENOTSOCK
++ * The argument s is not a socket.
++ */
++static inline int getsockname (int s, struct sockaddr *name, socklen_t *namelen)
++{
++ struct socket *sock = fd2sock(s);
++
++ if (sock == NULL)
++ return -1;
++
++ /*
++ * getname() wants an 'int *' for the length, will it by this
++ * 'socklen_t *' business? (even though it is just an 'int *'?).
++ */
++ if (sock->ops->getname(sock, name, namelen, 0) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++} /* End getsockname(). */
++
++static inline int getpeername (int s, struct sockaddr *name, socklen_t *namelen)
++{
++ struct socket *sock = fd2sock(s);
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->getname(sock, name, namelen, 1) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++} /* End getpeername(). */
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/netinet/CVS/Entries linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Entries
+--- linux-2.4.1/net/korbit/include/netinet/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Entries Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,2 @@
++/in.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/netinet/CVS/Repository linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Repository
+--- linux-2.4.1/net/korbit/include/netinet/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Repository Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include/netinet
+diff -urN linux-2.4.1/net/korbit/include/netinet/CVS/Root linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Root
+--- linux-2.4.1/net/korbit/include/netinet/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Root Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/netinet/in.h linux-2.4.1-korbit/net/korbit/include/netinet/in.h
+--- linux-2.4.1/net/korbit/include/netinet/in.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/in.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,5 @@
++#ifndef __KORBIT_NETINET_IN_H__
++#define __KORBIT_NETINET_IN_H__
++#include <linux/socket.h>
++#include <linux/in.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/pwd.h linux-2.4.1-korbit/net/korbit/include/pwd.h
+--- linux-2.4.1/net/korbit/include/pwd.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/pwd.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_PWD_H__
++#define __KORBIT_PWD_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/signal.h linux-2.4.1-korbit/net/korbit/include/signal.h
+--- linux-2.4.1/net/korbit/include/signal.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/signal.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,6 @@
++#ifndef __KORBIT_SIGNAL_H__
++#define __KORBIT_SIGNAL_H__
++
++#include <asm/signal.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stdarg.h linux-2.4.1-korbit/net/korbit/include/stdarg.h
+--- linux-2.4.1/net/korbit/include/stdarg.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stdarg.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,13 @@
++#ifndef __KORBIT_STDARG_H__
++#define __KORBIT_STDARG_H__
++
++#define ANDY 1
++
++#if FREDRIK
++#include "/usr/lib/gcc-lib/i386-glibc21-linux/egcs-2.91.66/include/stdarg.h"
++#elif CHRIS
++#include "/usr/lib/gcc-lib/i586-mandrake-linux/egcs-2.91.66/include/stdarg.h"
++#elif ANDY
++#include "/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h"
++#endif
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stddef.h linux-2.4.1-korbit/net/korbit/include/stddef.h
+--- linux-2.4.1/net/korbit/include/stddef.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stddef.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_STDDEF_H__
++#define __KORBIT_STDDEF_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stdio.h linux-2.4.1-korbit/net/korbit/include/stdio.h
+--- linux-2.4.1/net/korbit/include/stdio.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stdio.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,402 @@
++#ifndef __KORBIT_STDIO_H__
++#define __KORBIT_STDIO_H__
++
++#include <asm/segment.h>
++#include <asm/uaccess.h>
++#include <linux/smp_lock.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/uio.h>
++#include <linux/dcache.h>
++#include <linux/file.h>
++#include <linux/highuid.h>
++#include <sys/socket.h>
++
++#include <errno.h>
++
++#define KORBIT_DEBUG_WRITING 0
++
++
++#define printf(format,args...) printk(format,##args)
++#define fflush(x)
++
++#define SEEK_SET 0 /* Seek from beginning of file. */
++#define SEEK_CUR 1 /* Seek from current position. */
++#define SEEK_END 2 /* Seek from end of file. */
++
++static inline int unlink(const char *pathname) {
++ printf("KERNEL UNLINK('%s') CALLED!\n", pathname);
++ return -1;
++}
++
++static inline struct file *fd2file(int fd) {
++ if (fd & 1) /* can't convert a socket! */
++ return NULL;
++
++ return (struct file *)(-(fd & ~1));
++}
++
++static inline int open(const char *filename, int flags, int mode) {
++ struct file *RetVal = filp_open(filename, flags, mode);
++ if (IS_ERR(RetVal))
++ {
++ errno = PTR_ERR(RetVal);
++ return -1;
++ }
++ return -(int)RetVal;
++}
++
++static inline int creat(const char *filename, mode_t mode)
++{
++ return open(filename, O_CREAT | O_WRONLY | O_TRUNC, mode);
++}
++
++static inline int lseek(int fd, long offset, int whence)
++{
++ if ((fd & 1) == 1)
++ {
++ printk("KERNEL FSEEK() CALLED ON SOCKET!\n");
++ return -1;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ loff_t (*fn)(struct file *, loff_t, int);
++ int retval = -1;
++
++ if (whence <= 2)
++ {
++ fn = default_llseek;
++ if (F->f_op && F->f_op->llseek)
++ fn = F->f_op->llseek;
++
++ lock_kernel();
++ retval = fn(F, offset, whence);
++ unlock_kernel();
++ }
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++ }
++}
++
++
++asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
++static inline int stat(char *filename, struct stat *buf)
++{
++ mm_segment_t oldfs;
++ int retval;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ retval = sys_newstat(filename, buf);
++ set_fs(oldfs);
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++}
++
++asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
++static inline int lstat(char *filename, struct stat *buf)
++{
++ mm_segment_t oldfs;
++ int retval;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ retval = sys_newlstat(filename, buf);
++ set_fs(oldfs);
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++}
++
++
++static inline int do_revalidate(struct dentry *dentry)
++{
++ struct inode * inode = dentry->d_inode;
++ if (inode->i_op && inode->i_op->revalidate)
++ return inode->i_op->revalidate(dentry);
++ return 0;
++}
++
++
++static inline int cp_new_stat(struct inode * inode, struct stat * statbuf)
++{
++ struct stat tmp;
++
++ memset(&tmp, 0, sizeof(tmp));
++ tmp.st_dev = kdev_t_to_nr(inode->i_dev);
++ tmp.st_ino = inode->i_ino;
++ tmp.st_mode = inode->i_mode;
++ tmp.st_nlink = inode->i_nlink;
++ SET_STAT_UID(tmp, inode->i_uid);
++ SET_STAT_GID(tmp, inode->i_gid);
++ tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
++#if BITS_PER_LONG == 32
++ if (inode->i_size > 0x7fffffff)
++ return -EOVERFLOW;
++ else
++#endif
++ {
++ tmp.st_size = inode->i_size;
++ tmp.st_atime = inode->i_atime;
++ tmp.st_mtime = inode->i_mtime;
++ tmp.st_ctime = inode->i_ctime;
++
++ tmp.st_blocks = inode->i_blocks;
++ tmp.st_blksize = inode->i_blksize;
++
++ memcpy(statbuf, &tmp, sizeof(tmp));
++ return 0;
++ }
++}
++
++
++static inline int fstat(int fd, struct stat *buf)
++{
++ if ((fd & 1) == 1)
++ {
++ printk("TODO : FSTAT FOR SOCKETS, DO WE WANT THIS?\n");
++ errno = EBADF;
++ return -1;
++ }
++ else
++ {
++ struct file *file = fd2file(fd);
++ struct dentry *dentry;
++ int retval = -EBADF;
++
++ if (file)
++ {
++ dentry = file->f_dentry;
++ retval = do_revalidate(dentry);
++
++ if (!retval)
++ retval = cp_new_stat(dentry->d_inode, buf);
++ }
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++ }
++}
++
++
++asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz);
++static inline int readlink(const char *path, char *buf, size_t bufsiz)
++{
++ int retval;
++ mm_segment_t oldfs;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ retval = sys_readlink(path, buf, bufsiz);
++ set_fs(oldfs);
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++}
++
++
++static inline int read(int fd, void *buffer, size_t count) {
++ if ((fd & 1) == 1)
++ {
++ struct socket *sock = fd2sock(fd);
++ struct iovec iov;
++ struct msghdr msg;
++ mm_segment_t oldfs;
++ int flags = 0;
++ int RetVal;
++
++ msg.msg_name = NULL;
++ msg.msg_namelen = 0;
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++ msg.msg_control = NULL;
++ msg.msg_controllen = 0;
++ msg.msg_flags = 0;
++ iov.iov_base = buffer;
++ iov.iov_len = count;
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ RetVal = sock_recvmsg(sock, &msg, count, flags);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ mm_segment_t oldfs;
++ int RetVal;
++
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ RetVal = F->f_op->read(F, buffer, count, &F->f_pos);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++}
++
++static inline int write(int fd, const void *buffer, size_t count) {
++ if ((fd & 1) == 1)
++ {
++ struct socket *sock = fd2sock(fd);
++ struct iovec iov;
++ struct msghdr msg;
++ mm_segment_t oldfs;
++ int RetVal;
++ msg.msg_name = NULL;
++ msg.msg_namelen = 0;
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++ msg.msg_control = NULL;
++ msg.msg_controllen = 0;
++ msg.msg_flags = MSG_NOSIGNAL;
++ if (sock->type == SOCK_SEQPACKET)
++ msg.msg_flags |= MSG_EOR;
++ iov.iov_base = (void *)buffer;
++ iov.iov_len = count;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ RetVal = sock_sendmsg(sock, &msg, count);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ mm_segment_t oldfs;
++ int RetVal;
++
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ RetVal = F->f_op->write(F, buffer, count, &F->f_pos);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++}
++
++static inline int writev(int fd, const struct iovec *vector, int count) {
++#ifndef DONT_USE_SIMPLE_WRITEV
++ int i, amount = 0;
++#if KORBIT_DEBUG_WRITING
++ printk("writev (fd = 0x%X, vec=0x%p, count = %d)\n", fd, vector, count);
++#endif
++ for (i = 0; i < count; i++) {
++ char *Buf = vector[i].iov_base;
++ int Amount = vector[i].iov_len;
++ while (Amount > 0) {
++ int A = write(fd, Buf, Amount);
++//#if KORBIT_DEBUG_WRITING
++if (A < Amount)
++ printk(" write(fd = 0x%X, buf = 0x%p, size = 0x%X) "
++ "= 0x%X errno = 0x%X\n", fd, Buf, Amount, A, errno);
++//#endif
++ Amount -= A;
++ amount += A;
++ Buf += A;
++ if (Amount > 0) schedule(); // Behave somewhat nicely...
++ }
++ }
++
++#if KORBIT_DEBUG_WRITING
++ printk("writev returning 0x%X[%d]\n", amount, amount);
++#endif
++ return amount;
++
++#else
++ if ((fd & 1) == 1)
++ {
++ struct socket *sock = fd2sock(fd);
++ struct msghdr msg;
++ mm_segment_t oldfs;
++ int i, RetVal;
++ size_t tot_len = 0;
++
++ for (i = 0; i < count; i++)
++ tot_len += vector[i].iov_len;
++
++ msg.msg_name = NULL;
++ msg.msg_namelen = 0;
++ msg.msg_iov = (struct iovec *)vector;
++ msg.msg_iovlen = count;
++ msg.msg_control = NULL;
++ msg.msg_controllen = 0;
++ if (sock->type == SOCK_SEQPACKET)
++ msg.msg_flags |= MSG_EOR;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ RetVal = sock_sendmsg(sock, &msg, tot_len);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ mm_segment_t oldfs;
++ int RetVal;
++
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ RetVal = F->f_op->writev(F, vector, (unsigned)count, &F->f_pos);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++#endif
++}
++
++static inline int close(int fd) {
++ int err = 0;
++ if ((fd & 1) == 1) {
++ struct socket *sock = fd2sock(fd);
++ sock_release(sock);
++ } else {
++ struct file *file = fd2file(fd);
++ fput(file);
++ }
++ return err;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stdlib.h linux-2.4.1-korbit/net/korbit/include/stdlib.h
+--- linux-2.4.1/net/korbit/include/stdlib.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stdlib.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,99 @@
++#ifndef __KORBIT_STDLIB_H__
++#define __KORBIT_STDLIB_H__
++
++#include <linux/kernel.h>
++#include <linux/malloc.h>
++#include <linux/types.h>
++#include <asm/string.h>
++
++#define strtol(nptr,endptr,base) simple_strtol(nptr,endptr,base)
++
++#if 0
++#define malloc(size) kmalloc(size, GFP_KERNEL)
++#define free(ptr) kfree(ptr)
++#endif
++
++static inline void *malloc(size_t size)
++{
++ void *ptr = NULL;
++
++ if (size == 0)
++ size = 4;
++
++ ptr = kmalloc(size + sizeof(size), GFP_KERNEL);
++
++ if (ptr)
++ {
++ *((size_t *)ptr) = size;
++ ptr = (size_t *)ptr + 1;
++ }
++
++ return ptr;
++}
++
++static inline void free(void *ptr)
++{
++ if (ptr)
++ kfree((size_t *)ptr - 1);
++}
++
++#define alloca(size) malloc(size)
++
++/* freeca(ptr) - free a mem allocation if ptr points to one, otherwise do
++ * nothing.
++ */
++static inline void freeca(void *ptr)
++{
++ if (ptr != NULL) { /* Don't free it if it's already free */
++ free(ptr);
++ }
++}
++
++static inline void *calloc(size_t nmemb, size_t size)
++{
++ void *ptr = malloc(nmemb*size);
++ if (ptr)
++ memset(ptr,0,nmemb*size);
++ return ptr;
++}
++
++static inline void *realloc(void *ptr, size_t size)
++{
++ void *newptr = NULL;
++
++ if (size != 0)
++ newptr = malloc(size);
++
++ if (ptr && newptr) /* Copy old contents */
++ {
++ size_t *p1 = (size_t *)ptr - 1;
++ size_t *p2 = (size_t *)newptr - 1;
++ size_t n = *p1 < *p2 ? *p1 : *p2;
++ memcpy(newptr, ptr, n);
++ }
++
++ if (ptr)
++ free(ptr);
++
++ return newptr;
++}
++
++/* Returned by `div'. */
++typedef struct
++{
++ int quot; /* Quotient. */
++ int rem; /* Remainder. */
++} div_t;
++
++static inline div_t div(int number, int denom)
++{
++ div_t result;
++ result.quot = number/denom;
++ result.rem = number-(number*result.quot);
++ return result;
++}
++
++#define atexit(fn) -1
++#define getenv(name) 0
++
++#endif /* __KORBIT_STDLIB_H__ */
+diff -urN linux-2.4.1/net/korbit/include/string.h linux-2.4.1-korbit/net/korbit/include/string.h
+--- linux-2.4.1/net/korbit/include/string.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/string.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,11 @@
++#ifndef __KORBIT_STRING_H__
++#define __KORBIT_STRING_H__
++
++#include <linux/types.h>
++#include <asm/string.h>
++
++#include <glib.h>
++
++#define strerror(errno) g_strerror(errno)
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/CVS/Entries linux-2.4.1-korbit/net/korbit/include/sys/CVS/Entries
+--- linux-2.4.1/net/korbit/include/sys/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/CVS/Entries Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,10 @@
++/ioctl.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++/poll.h/1.25/Thu Feb 1 09:46:55 2001//
++/socket.h/1.20/Thu Feb 1 09:46:55 2001//
++/stat.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++/time.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++/types.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++/uio.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++/un.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++/wait.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/sys/CVS/Repository linux-2.4.1-korbit/net/korbit/include/sys/CVS/Repository
+--- linux-2.4.1/net/korbit/include/sys/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/CVS/Repository Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include/sys
+diff -urN linux-2.4.1/net/korbit/include/sys/CVS/Root linux-2.4.1-korbit/net/korbit/include/sys/CVS/Root
+--- linux-2.4.1/net/korbit/include/sys/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/CVS/Root Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/sys/ioctl.h linux-2.4.1-korbit/net/korbit/include/sys/ioctl.h
+--- linux-2.4.1/net/korbit/include/sys/ioctl.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/ioctl.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_SYS_IOCTL_H__
++#define __KORBIT_SYS_IOCTL_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/poll.h linux-2.4.1-korbit/net/korbit/include/sys/poll.h
+--- linux-2.4.1/net/korbit/include/sys/poll.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/poll.h Fri Feb 2 01:22:10 2001
+@@ -0,0 +1,112 @@
++#ifndef __KORBIT_SYS_POLL_H__
++#define __KORBIT_SYS_POLL_H__
++
++#include <asm/poll.h>
++#include <asm/param.h>
++#include <linux/net.h>
++#include <linux/tcp.h>
++#include <linux/socket.h>
++#include <net/tcp.h>
++#include <net/sock.h>
++#include <linux/skbuff.h>
++#include <linux/sched.h>
++#include "stdlib.h"
++#include "sys/socket.h"
++
++/* Poll the file descriptors described by the NFDS structures starting at
++ * FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for
++ * an event to occur; if TIMEOUT is -1, block until an event occurs.
++ * Returns the number of file descriptors with events, zero if timed
++ * out, or -1 for errors.
++ */
++
++/* This implementation of poll assumes that we are sitting on the wait
++ * queues for all of the file descriptors already. Therefore if we are about
++ * to block, all we have to do is perform the schedule call which will
++ * automatically cause us to "block".
++ */
++static int poll_CheckFDs(struct pollfd *fds, unsigned long int nfds)
++{
++ int NumReady = 0, i;
++
++ // Loop over the file descriptors seeing if there is already work to be
++ // done...
++ for (i = 0; i < nfds; i++) {
++ struct socket *sock = fd2sock(fds[i].fd);
++ fds[i].revents = 0;
++
++ // Check to see if stuff is available to read
++ if (sock) {
++ // It's a socket baby
++ fds[i].revents = tcp_poll(0, sock, 0);
++
++ // Apparently tcp_poll doesn't look at the CLOSE_WAIT value,
++ // and we have a lot of sockets that end up in this state.
++ // This is a hack to shortcircuit some read failures from
++ // later. This breaks "poll semantics" strictly speaking, but
++ // it's basically the "right thing to do" (tm).
++ if (sock->sk->state == TCP_CLOSE_WAIT)
++ fds[i].revents = POLLHUP;
++ fds[i].revents &= fds[i].events | POLLERR | POLLHUP;
++ } else {
++ // It's a file
++ //struct file *f = fd2file(fd);
++// printk("POLL NOT IMPLEMENTED FOR FILES YET\n");
++ BUG();
++ }
++
++ if (fds[i].revents) {
++ NumReady++;
++// printk("FD #%d: Event = 0x%X\n", i, fds[i].revents);
++ }
++
++ } /* for */
++
++ return NumReady;
++} /* End poll_CheckFDs(). */
++
++
++static int poll(struct pollfd *fds, unsigned long int nfds, int timeout) {
++ wait_queue_t *WaitQueues = 0;
++ int NumReady = poll_CheckFDs(fds, nfds);
++ int i;
++
++ if (NumReady || timeout == 0)
++ return NumReady;
++
++// printk("Starting to Poll... %d fds...\n", nfds);
++ WaitQueues = (wait_queue_t*)malloc(nfds*sizeof(wait_queue_t));
++ if (WaitQueues == 0) return 0; // Crap, nomem...
++
++ for (i = 0; i < nfds; i++) {
++ struct socket *sock = fd2sock(fds[i].fd);
++ init_waitqueue_entry(WaitQueues+i, current);
++
++ if (sock)
++ add_wait_queue_exclusive(sock->sk->sleep, WaitQueues+i);
++// else
++// printk("I don't know how to wait on fd #%d = 0x%X\n", i, fds[i].fd);
++ }
++
++ // Wait for us to get notified by one of the socket wait queue notifiers!
++ do {
++ // Change our task state so that we are not immediately rescheduled.
++ // This lets the scheduler know that we are waiting for something to happen
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule();
++ } while (!(NumReady = poll_CheckFDs(fds, nfds)));
++
++ set_current_state(TASK_RUNNING);
++
++ for (i = 0; i < nfds; i++) {
++ struct socket *sock = fd2sock(fds[i].fd);
++ if (sock)
++ remove_wait_queue(sock->sk->sleep, WaitQueues+i);
++ }
++
++ free(WaitQueues);
++// printk("Returning %d\n", NumReady);
++ return NumReady;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/socket.h linux-2.4.1-korbit/net/korbit/include/sys/socket.h
+--- linux-2.4.1/net/korbit/include/sys/socket.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/socket.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,126 @@
++#ifndef __KORBIT_SYS_SOCKET_H__
++#define __KORBIT_SYS_SOCKET_H__
++typedef unsigned int socklen_t;
++
++#include <linux/socket.h>
++#include <linux/wait.h>
++#include <asm/semaphore.h>
++#include <net/sock.h>
++
++/* These functions are declared in net/socket.c */
++asmlinkage long sys_socket(int family, int type, int protocol);
++struct socket *sockfd_lookup(int fd, int *err);
++
++
++static inline int sock2fd(struct socket *s)
++{
++ return (-(int)s) | 1;
++}
++
++static inline struct socket *fd2sock(int sockfd)
++{
++ if ((sockfd & 1) == 0) /* can't convert a file! */
++ return NULL;
++
++ return (struct socket *)(-(sockfd & ~1));
++}
++
++
++static inline int socket(int domain, int type, int protocol) {
++ struct socket *sock;
++ int retval = sock_create(domain, type, protocol, &sock);
++
++ if (retval < 0) return (int)NULL;
++ return sock2fd(sock);
++}
++
++
++static inline int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
++{
++ struct socket *sock = fd2sock(sockfd);
++
++ if (sock == NULL)
++ return -1;
++ if (!sock->ops->bind(sock, my_addr, addrlen))
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++
++static inline int connect(int sockfd, const struct sockaddr *serv_addr,
++ socklen_t addrlen)
++{
++ struct socket *sock = fd2sock(sockfd);
++ int flags = 0; /* TODO : what is flags supposed to be? */
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->connect(sock, (struct sockaddr *)serv_addr, addrlen, flags) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++
++static inline int listen(int sockfd, int backlog)
++{
++ struct socket *sock = fd2sock(sockfd);
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->listen(sock, backlog) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++
++static inline int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
++{
++ struct socket *sock = fd2sock(sockfd);
++ struct socket *newsock;
++ struct sockaddr_in *newaddr = (struct sockaddr_in *)addr; /* check? */
++ int flags = 0; /* Should be ok */
++
++ if (sock == 0)
++ return -1;
++
++ newsock = sock_alloc();
++ if (newsock == 0)
++ return -1;
++
++ newsock->type = sock->type;
++ newsock->ops = sock->ops;
++ if (sock->ops->accept(sock, newsock, flags) < 0)
++ {
++ sock_release(newsock);
++ return -1; /* should normally also set errno */
++ }
++
++ newaddr->sin_family = AF_INET;
++ newaddr->sin_port = newsock->sk->dport;
++ newaddr->sin_addr.s_addr = newsock->sk->daddr;
++
++ *addrlen = sizeof(newaddr);
++
++ return sock2fd(newsock);
++}
++
++
++static inline int shutdown(int sockfd, int how)
++{
++ struct socket *sock = fd2sock(sockfd);
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->shutdown(sock, how) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/stat.h linux-2.4.1-korbit/net/korbit/include/sys/stat.h
+--- linux-2.4.1/net/korbit/include/sys/stat.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/stat.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_SYS_STAT_H__
++#define __KORBIT_SYS_STAT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/time.h linux-2.4.1-korbit/net/korbit/include/sys/time.h
+--- linux-2.4.1/net/korbit/include/sys/time.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/time.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,6 @@
++#ifndef __KORBIT_TIME_H__
++#define __KORBIT_TIME_H__
++
++#include <linux/time.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/types.h linux-2.4.1-korbit/net/korbit/include/sys/types.h
+--- linux-2.4.1/net/korbit/include/sys/types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/types.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_SYS_TYPES_H__
++#define __KORBIT_SYS_TYPES_H__
++#include <linux/types.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/uio.h linux-2.4.1-korbit/net/korbit/include/sys/uio.h
+--- linux-2.4.1/net/korbit/include/sys/uio.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/uio.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_SYS_UIO_H__
++#define __KORBIT_SYS_UIO_H__
++#include <linux/uio.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/un.h linux-2.4.1-korbit/net/korbit/include/sys/un.h
+--- linux-2.4.1/net/korbit/include/sys/un.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/un.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,5 @@
++#ifndef __KORBIT_SYS_UN_H__
++#define __KORBIT_SYS_UN_H__
++#include <linux/socket.h>
++#include <linux/un.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/wait.h linux-2.4.1-korbit/net/korbit/include/sys/wait.h
+--- linux-2.4.1/net/korbit/include/sys/wait.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/wait.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_SYS_WAIT_H__
++#define __KORBIT_SYS_WAIT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/syslog.h linux-2.4.1-korbit/net/korbit/include/syslog.h
+--- linux-2.4.1/net/korbit/include/syslog.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/syslog.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,7 @@
++#ifndef __KORBIT_SYSLOG_H__
++#define __KORBIT_SYSLOG_H__
++
++#define LOG_NOTICE 5 /* normal but significant condition */
++#define LOG_INFO 6 /* informational */
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/time.h linux-2.4.1-korbit/net/korbit/include/time.h
+--- linux-2.4.1/net/korbit/include/time.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/time.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_TIME_H__
++#define __KORBIT_TIME_H__
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/unistd.h linux-2.4.1-korbit/net/korbit/include/unistd.h
+--- linux-2.4.1/net/korbit/include/unistd.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/unistd.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,19 @@
++#ifndef __KORBIT_UNISTD_H__
++#define __KORBIT_UNISTD_H__
++
++#include <linux/types.h>
++#include <linux/utsname.h>
++#include <asm/string.h>
++#include <asm/semaphore.h>
++/* extern char *getcwd(char * buf, size_t size); */
++
++static inline int gethostname(char *name, size_t len) {
++ down_read(&uts_sem);
++ strncpy(name, system_utsname.nodename, len);
++ up_read(&uts_sem);
++printk("gethostname() = %s\n", name);
++ return 0;
++}
++
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/utime.h linux-2.4.1-korbit/net/korbit/include/utime.h
+--- linux-2.4.1/net/korbit/include/utime.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/utime.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_UTIME_H__
++#define __KORBIT_UTIME_H__
++#include <linux/utime.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/kglib/CVS/Entries linux-2.4.1-korbit/net/korbit/kglib/CVS/Entries
+--- linux-2.4.1/net/korbit/kglib/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/CVS/Entries Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,15 @@
++/Makefile/1.4/Thu Feb 1 09:46:56 2001//
++/garray.c/1.3/Thu Feb 1 09:46:56 2001//
++/ghash.c/1.2/Thu Feb 1 09:46:56 2001//
++/glib.h/1.3/Thu Feb 1 09:46:56 2001//
++/glibconfig.h/1.2/Thu Feb 1 09:46:56 2001//
++/glist.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gmem.c/1.2/Thu Feb 1 09:46:57 2001//
++/gprimes.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gslist.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gstrfuncs.c/1.2/Thu Feb 1 09:46:57 2001//
++/gstring.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gtree.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gutils.c/1.2/Thu Feb 1 09:46:57 2001//
++/korbit_errno.c/1.1/Thu Feb 1 09:46:57 2001//
++D
+diff -urN linux-2.4.1/net/korbit/kglib/CVS/Repository linux-2.4.1-korbit/net/korbit/kglib/CVS/Repository
+--- linux-2.4.1/net/korbit/kglib/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/CVS/Repository Thu Feb 1 11:46:56 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/kglib
+diff -urN linux-2.4.1/net/korbit/kglib/CVS/Root linux-2.4.1-korbit/net/korbit/kglib/CVS/Root
+--- linux-2.4.1/net/korbit/kglib/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/CVS/Root Thu Feb 1 11:46:56 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/kglib/Makefile linux-2.4.1-korbit/net/korbit/kglib/Makefile
+--- linux-2.4.1/net/korbit/kglib/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/Makefile Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,18 @@
++#
++# Makefile for KORBit/kglib
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := kglib.o
++
++#obj-m := $(O_TARGET)
++obj-y := garray.o glist.o gprimes.o gstrfuncs.o gtree.o \
++ ghash.o gmem.o gslist.o gstring.o gutils.o korbit_errno.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -DHAVE_UNISTD_H -I. -I.. -I../include -nostdinc
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/kglib/garray.c linux-2.4.1-korbit/net/korbit/kglib/garray.c
+--- linux-2.4.1/net/korbit/kglib/garray.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/garray.c Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,431 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include <string.h>
++#include "glib.h"
++
++
++#define MIN_ARRAY_SIZE 16
++
++
++typedef struct _GRealArray GRealArray;
++
++struct _GRealArray
++{
++ guint8 *data;
++ guint len;
++ guint alloc;
++ guint elt_size;
++ guint zero_terminated : 1;
++ guint clear : 1;
++};
++
++
++static gint g_nearest_pow (gint num);
++static void g_array_maybe_expand (GRealArray *array,
++ gint len);
++
++static GMemChunk *array_mem_chunk = NULL;
++G_LOCK_DEFINE_STATIC (array_mem_chunk);
++
++GArray*
++g_array_new (gboolean zero_terminated,
++ gboolean clear,
++ guint elt_size)
++{
++ GRealArray *array;
++
++ G_LOCK (array_mem_chunk);
++ if (!array_mem_chunk)
++ array_mem_chunk = g_mem_chunk_new ("array mem chunk",
++ sizeof (GRealArray),
++ 1024, G_ALLOC_AND_FREE);
++
++ array = g_chunk_new (GRealArray, array_mem_chunk);
++ G_UNLOCK (array_mem_chunk);
++
++ array->data = NULL;
++ array->len = 0;
++ array->alloc = 0;
++ array->zero_terminated = (zero_terminated ? 1 : 0);
++ array->clear = (clear ? 1 : 0);
++ array->elt_size = elt_size;
++
++ return (GArray*) array;
++}
++
++void
++g_array_free (GArray *array,
++ gboolean free_segment)
++{
++ if (free_segment)
++ g_free (array->data);
++
++ G_LOCK (array_mem_chunk);
++ g_mem_chunk_free (array_mem_chunk, array);
++ G_UNLOCK (array_mem_chunk);
++}
++
++GArray*
++g_array_append_vals (GArray *farray,
++ gconstpointer data,
++ guint len)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ g_array_maybe_expand (array, len);
++
++ memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
++
++ array->len += len;
++
++ return farray;
++}
++
++GArray*
++g_array_prepend_vals (GArray *farray,
++ gconstpointer data,
++ guint len)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ g_array_maybe_expand (array, len);
++
++ g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
++
++ memcpy (array->data, data, len * array->elt_size);
++
++ array->len += len;
++
++ return farray;
++}
++
++GArray*
++g_array_insert_vals (GArray *farray,
++ guint index,
++ gconstpointer data,
++ guint len)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ g_array_maybe_expand (array, len);
++
++ g_memmove (array->data + array->elt_size * (len + index),
++ array->data + array->elt_size * index,
++ array->elt_size * (array->len - index));
++
++ memcpy (array->data + array->elt_size * index, data, len * array->elt_size);
++
++ array->len += len;
++
++ return farray;
++}
++
++GArray*
++g_array_set_size (GArray *farray,
++ guint length)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ if (array->len < length)
++ g_array_maybe_expand (array, length - array->len);
++
++ array->len = length;
++
++ return farray;
++}
++
++GArray*
++g_array_remove_index (GArray* farray,
++ guint index)
++{
++ GRealArray* array = (GRealArray*) farray;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ if (index != array->len - 1)
++ g_memmove (array->data + array->elt_size * index,
++ array->data + array->elt_size * (index + 1),
++ array->elt_size * (array->len - index - 1));
++
++ if (array->zero_terminated)
++ memset (array->data + array->elt_size * (array->len - 1), 0,
++ array->elt_size);
++
++ array->len -= 1;
++
++ return farray;
++}
++
++GArray*
++g_array_remove_index_fast (GArray* farray,
++ guint index)
++{
++ GRealArray* array = (GRealArray*) farray;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ if (index != array->len - 1)
++ g_memmove (array->data + array->elt_size * index,
++ array->data + array->elt_size * (array->len - 1),
++ array->elt_size);
++
++ if (array->zero_terminated)
++ memset (array->data + array->elt_size * (array->len - 1), 0,
++ array->elt_size);
++
++ array->len -= 1;
++
++ return farray;
++}
++
++static gint
++g_nearest_pow (gint num)
++{
++ gint n = 1;
++
++ while (n < num)
++ n <<= 1;
++
++ return n;
++}
++
++static void
++g_array_maybe_expand (GRealArray *array,
++ gint len)
++{
++ guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;
++
++ if (want_alloc > array->alloc)
++ {
++ guint old_alloc = array->alloc;
++
++ array->alloc = g_nearest_pow (want_alloc);
++ array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
++
++ array->data = g_realloc (array->data, array->alloc);
++
++ if (array->clear || array->zero_terminated)
++ memset (array->data + old_alloc, 0, array->alloc - old_alloc);
++ }
++}
++
++/* Pointer Array
++ */
++
++typedef struct _GRealPtrArray GRealPtrArray;
++
++struct _GRealPtrArray
++{
++ gpointer *pdata;
++ guint len;
++ guint alloc;
++};
++
++static void g_ptr_array_maybe_expand (GRealPtrArray *array,
++ gint len);
++
++static GMemChunk *ptr_array_mem_chunk = NULL;
++G_LOCK_DEFINE_STATIC (ptr_array_mem_chunk);
++
++
++GPtrArray*
++g_ptr_array_new (void)
++{
++ GRealPtrArray *array;
++
++ G_LOCK (ptr_array_mem_chunk);
++ if (!ptr_array_mem_chunk)
++ ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
++ sizeof (GRealPtrArray),
++ 1024, G_ALLOC_AND_FREE);
++
++ array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
++ G_UNLOCK (ptr_array_mem_chunk);
++
++ array->pdata = NULL;
++ array->len = 0;
++ array->alloc = 0;
++
++ return (GPtrArray*) array;
++}
++
++void
++g_ptr_array_free (GPtrArray *array,
++ gboolean free_segment)
++{
++ g_return_if_fail (array);
++
++ if (free_segment)
++ g_free (array->pdata);
++
++ G_LOCK (ptr_array_mem_chunk);
++ g_mem_chunk_free (ptr_array_mem_chunk, array);
++ G_UNLOCK (ptr_array_mem_chunk);
++}
++
++static void
++g_ptr_array_maybe_expand (GRealPtrArray *array,
++ gint len)
++{
++ guint old_alloc;
++
++ if ((array->len + len) > array->alloc)
++ {
++ old_alloc = array->alloc;
++
++ array->alloc = g_nearest_pow (array->len + len);
++ array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
++ if (array->pdata)
++ array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
++ else
++ array->pdata = g_new0 (gpointer, array->alloc);
++
++ memset (array->pdata + old_alloc, 0,
++ sizeof (gpointer) * (array->alloc - old_alloc));
++ }
++}
++
++void
++g_ptr_array_set_size (GPtrArray *farray,
++ gint length)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++
++ g_return_if_fail (array);
++
++ if (length > array->len)
++ g_ptr_array_maybe_expand (array, (length - array->len));
++
++ array->len = length;
++}
++
++gpointer
++g_ptr_array_remove_index (GPtrArray* farray,
++ guint index)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ gpointer result;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ result = array->pdata[index];
++
++ if (index != array->len - 1)
++ g_memmove (array->pdata + index, array->pdata + index + 1,
++ sizeof (gpointer) * (array->len - index - 1));
++
++ array->pdata[array->len - 1] = NULL;
++
++ array->len -= 1;
++
++ return result;
++}
++
++gpointer
++g_ptr_array_remove_index_fast (GPtrArray* farray,
++ guint index)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ gpointer result;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ result = array->pdata[index];
++
++ if (index != array->len - 1)
++ array->pdata[index] = array->pdata[array->len - 1];
++
++ array->pdata[array->len - 1] = NULL;
++
++ array->len -= 1;
++
++ return result;
++}
++
++gboolean
++g_ptr_array_remove (GPtrArray* farray,
++ gpointer data)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ int i;
++
++ g_return_val_if_fail (array, FALSE);
++
++ for (i = 0; i < array->len; i += 1)
++ {
++ if (array->pdata[i] == data)
++ {
++ g_ptr_array_remove_index (farray, i);
++ return TRUE;
++ }
++ }
++
++ return FALSE;
++}
++
++gboolean
++g_ptr_array_remove_fast (GPtrArray* farray,
++ gpointer data)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ int i;
++
++ g_return_val_if_fail (array, FALSE);
++
++ for (i = 0; i < array->len; i += 1)
++ {
++ if (array->pdata[i] == data)
++ {
++ g_ptr_array_remove_index_fast (farray, i);
++ return TRUE;
++ }
++ }
++
++ return FALSE;
++}
++
++void
++g_ptr_array_add (GPtrArray* farray,
++ gpointer data)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++
++ g_return_if_fail (array);
++
++ g_ptr_array_maybe_expand (array, 1);
++
++ array->pdata[array->len++] = data;
++}
++
+diff -urN linux-2.4.1/net/korbit/kglib/ghash.c linux-2.4.1-korbit/net/korbit/kglib/ghash.c
+--- linux-2.4.1/net/korbit/kglib/ghash.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/ghash.c Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,404 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++#define HASH_TABLE_MIN_SIZE 11
++#define HASH_TABLE_MAX_SIZE 13845163
++
++
++typedef struct _GHashNode GHashNode;
++
++struct _GHashNode
++{
++ gpointer key;
++ gpointer value;
++ GHashNode *next;
++};
++
++struct _GHashTable
++{
++ gint size;
++ gint nnodes;
++ guint frozen;
++ GHashNode **nodes;
++ GHashFunc hash_func;
++ GCompareFunc key_compare_func;
++};
++
++
++static void g_hash_table_resize (GHashTable *hash_table);
++static GHashNode** g_hash_table_lookup_node (GHashTable *hash_table,
++ gconstpointer key);
++static GHashNode* g_hash_node_new (gpointer key,
++ gpointer value);
++static void g_hash_node_destroy (GHashNode *hash_node);
++static void g_hash_nodes_destroy (GHashNode *hash_node);
++
++
++G_LOCK_DEFINE_STATIC (g_hash_global);
++
++static GMemChunk *node_mem_chunk = NULL;
++static GHashNode *node_free_list = NULL;
++
++
++GHashTable*
++g_hash_table_new (GHashFunc hash_func,
++ GCompareFunc key_compare_func)
++{
++ GHashTable *hash_table;
++ guint i;
++
++ hash_table = g_new (GHashTable, 1);
++ hash_table->size = HASH_TABLE_MIN_SIZE;
++ hash_table->nnodes = 0;
++ hash_table->frozen = FALSE;
++ hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
++ hash_table->key_compare_func = key_compare_func;
++ hash_table->nodes = g_new (GHashNode*, hash_table->size);
++
++ for (i = 0; i < hash_table->size; i++)
++ hash_table->nodes[i] = NULL;
++
++ return hash_table;
++}
++
++void
++g_hash_table_destroy (GHashTable *hash_table)
++{
++ guint i;
++
++ g_return_if_fail (hash_table != NULL);
++
++ for (i = 0; i < hash_table->size; i++)
++ g_hash_nodes_destroy (hash_table->nodes[i]);
++
++ g_free (hash_table->nodes);
++ g_free (hash_table);
++}
++
++static inline GHashNode**
++g_hash_table_lookup_node (GHashTable *hash_table,
++ gconstpointer key)
++{
++ GHashNode **node;
++
++ node = &hash_table->nodes
++ [(* hash_table->hash_func) (key) % hash_table->size];
++
++ /* Hash table lookup needs to be fast.
++ * We therefore remove the extra conditional of testing
++ * whether to call the key_compare_func or not from
++ * the inner loop.
++ */
++ if (hash_table->key_compare_func)
++ while (*node && !(*hash_table->key_compare_func) ((*node)->key, key))
++ node = &(*node)->next;
++ else
++ while (*node && (*node)->key != key)
++ node = &(*node)->next;
++
++ return node;
++}
++
++gpointer
++g_hash_table_lookup (GHashTable *hash_table,
++ gconstpointer key)
++{
++ GHashNode *node;
++
++ g_return_val_if_fail (hash_table != NULL, NULL);
++
++ node = *g_hash_table_lookup_node (hash_table, key);
++
++ return node ? node->value : NULL;
++}
++
++void
++g_hash_table_insert (GHashTable *hash_table,
++ gpointer key,
++ gpointer value)
++{
++ GHashNode **node;
++
++ g_return_if_fail (hash_table != NULL);
++
++ node = g_hash_table_lookup_node (hash_table, key);
++
++ if (*node)
++ {
++ /* do not reset node->key in this place, keeping
++ * the old key might be intended.
++ * a g_hash_table_remove/g_hash_table_insert pair
++ * can be used otherwise.
++ *
++ * node->key = key; */
++ (*node)->value = value;
++ }
++ else
++ {
++ *node = g_hash_node_new (key, value);
++ hash_table->nnodes++;
++ if (!hash_table->frozen)
++ g_hash_table_resize (hash_table);
++ }
++}
++
++void
++g_hash_table_remove (GHashTable *hash_table,
++ gconstpointer key)
++{
++ GHashNode **node, *dest;
++
++ g_return_if_fail (hash_table != NULL);
++
++ node = g_hash_table_lookup_node (hash_table, key);
++
++ if (*node)
++ {
++ dest = *node;
++ (*node) = dest->next;
++ g_hash_node_destroy (dest);
++ hash_table->nnodes--;
++
++ if (!hash_table->frozen)
++ g_hash_table_resize (hash_table);
++ }
++}
++
++gboolean
++g_hash_table_lookup_extended (GHashTable *hash_table,
++ gconstpointer lookup_key,
++ gpointer *orig_key,
++ gpointer *value)
++{
++ GHashNode *node;
++
++ g_return_val_if_fail (hash_table != NULL, FALSE);
++
++ node = *g_hash_table_lookup_node (hash_table, lookup_key);
++
++ if (node)
++ {
++ if (orig_key)
++ *orig_key = node->key;
++ if (value)
++ *value = node->value;
++ return TRUE;
++ }
++ else
++ return FALSE;
++}
++
++void
++g_hash_table_freeze (GHashTable *hash_table)
++{
++ g_return_if_fail (hash_table != NULL);
++
++ hash_table->frozen++;
++}
++
++void
++g_hash_table_thaw (GHashTable *hash_table)
++{
++ g_return_if_fail (hash_table != NULL);
++
++ if (hash_table->frozen)
++ if (!(--hash_table->frozen))
++ g_hash_table_resize (hash_table);
++}
++
++guint
++g_hash_table_foreach_remove (GHashTable *hash_table,
++ GHRFunc func,
++ gpointer user_data)
++{
++ GHashNode *node, *prev;
++ guint i;
++ guint deleted = 0;
++
++ g_return_val_if_fail (hash_table != NULL, 0);
++ g_return_val_if_fail (func != NULL, 0);
++
++ for (i = 0; i < hash_table->size; i++)
++ {
++ restart:
++
++ prev = NULL;
++
++ for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
++ {
++ if ((* func) (node->key, node->value, user_data))
++ {
++ deleted += 1;
++
++ hash_table->nnodes -= 1;
++
++ if (prev)
++ {
++ prev->next = node->next;
++ g_hash_node_destroy (node);
++ node = prev;
++ }
++ else
++ {
++ hash_table->nodes[i] = node->next;
++ g_hash_node_destroy (node);
++ goto restart;
++ }
++ }
++ }
++ }
++
++ if (!hash_table->frozen)
++ g_hash_table_resize (hash_table);
++
++ return deleted;
++}
++
++void
++g_hash_table_foreach (GHashTable *hash_table,
++ GHFunc func,
++ gpointer user_data)
++{
++ GHashNode *node;
++ gint i;
++
++ g_return_if_fail (hash_table != NULL);
++ g_return_if_fail (func != NULL);
++
++ for (i = 0; i < hash_table->size; i++)
++ for (node = hash_table->nodes[i]; node; node = node->next)
++ (* func) (node->key, node->value, user_data);
++}
++
++/* Returns the number of elements contained in the hash table. */
++guint
++g_hash_table_size (GHashTable *hash_table)
++{
++ g_return_val_if_fail (hash_table != NULL, 0);
++
++ return hash_table->nnodes;
++}
++
++static void
++g_hash_table_resize (GHashTable *hash_table)
++{
++ GHashNode **new_nodes;
++ GHashNode *node;
++ GHashNode *next;
++#ifdef __KORBIT__
++ guint nodes_per_list;
++#else
++ gfloat nodes_per_list;
++#endif
++ guint hash_val;
++ gint new_size;
++ gint i;
++
++ nodes_per_list = (hash_table->nnodes * 10) / hash_table->size;
++
++ if ((nodes_per_list > 3 || hash_table->size <= HASH_TABLE_MIN_SIZE) &&
++ (nodes_per_list < 30 || hash_table->size >= HASH_TABLE_MAX_SIZE))
++ return;
++
++ new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
++ HASH_TABLE_MIN_SIZE,
++ HASH_TABLE_MAX_SIZE);
++ new_nodes = g_new0 (GHashNode*, new_size);
++
++ for (i = 0; i < hash_table->size; i++)
++ for (node = hash_table->nodes[i]; node; node = next)
++ {
++ next = node->next;
++
++ hash_val = (* hash_table->hash_func) (node->key) % new_size;
++
++ node->next = new_nodes[hash_val];
++ new_nodes[hash_val] = node;
++ }
++
++ g_free (hash_table->nodes);
++ hash_table->nodes = new_nodes;
++ hash_table->size = new_size;
++}
++
++static GHashNode*
++g_hash_node_new (gpointer key,
++ gpointer value)
++{
++ GHashNode *hash_node;
++
++ G_LOCK (g_hash_global);
++ if (node_free_list)
++ {
++ hash_node = node_free_list;
++ node_free_list = node_free_list->next;
++ }
++ else
++ {
++ if (!node_mem_chunk)
++ node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
++ sizeof (GHashNode),
++ 1024, G_ALLOC_ONLY);
++
++ hash_node = g_chunk_new (GHashNode, node_mem_chunk);
++ }
++ G_UNLOCK (g_hash_global);
++
++ hash_node->key = key;
++ hash_node->value = value;
++ hash_node->next = NULL;
++
++ return hash_node;
++}
++
++static void
++g_hash_node_destroy (GHashNode *hash_node)
++{
++ G_LOCK (g_hash_global);
++ hash_node->next = node_free_list;
++ node_free_list = hash_node;
++ G_UNLOCK (g_hash_global);
++}
++
++static void
++g_hash_nodes_destroy (GHashNode *hash_node)
++{
++ if (hash_node)
++ {
++ GHashNode *node = hash_node;
++
++ while (node->next)
++ node = node->next;
++
++ G_LOCK (g_hash_global);
++ node->next = node_free_list;
++ node_free_list = hash_node;
++ G_UNLOCK (g_hash_global);
++ }
++}
+diff -urN linux-2.4.1/net/korbit/kglib/glib.h linux-2.4.1-korbit/net/korbit/kglib/glib.h
+--- linux-2.4.1/net/korbit/kglib/glib.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/glib.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,1671 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#ifndef __G_LIB_H__
++#define __G_LIB_H__
++
++#ifdef __KORBIT__
++#define G_DISABLE_ASSERT 1
++#include <stdio.h>
++#endif
++
++#include "config.h"
++
++/* system specific config file glibconfig.h provides definitions for
++ * the extrema of many of the standard types. These are:
++ *
++ * G_MINSHORT, G_MAXSHORT
++ * G_MININT, G_MAXINT
++ * G_MINLONG, G_MAXLONG
++ * G_MINFLOAT, G_MAXFLOAT
++ * G_MINDOUBLE, G_MAXDOUBLE
++ *
++ * It also provides the following typedefs:
++ *
++ * gint8, guint8
++ * gint16, guint16
++ * gint32, guint32
++ * gint64, guint64
++ *
++ * It defines the G_BYTE_ORDER symbol to one of G_*_ENDIAN (see later in
++ * this file).
++ *
++ * And it provides a way to store and retrieve a `gint' in/from a `gpointer'.
++ * This is useful to pass an integer instead of a pointer to a callback.
++ *
++ * GINT_TO_POINTER(i), GUINT_TO_POINTER(i)
++ * GPOINTER_TO_INT(p), GPOINTER_TO_UINT(p)
++ *
++ * Finally, it provide the following wrappers to STDC functions:
++ *
++ * g_ATEXIT
++ * To register hooks which are executed on exit().
++ * Usually a wrapper for STDC atexit.
++ *
++ * void *g_memmove(void *dest, const void *src, guint count);
++ * A wrapper for STDC memmove, or an implementation, if memmove doesn't
++ * exist. The prototype looks like the above, give or take a const,
++ * or size_t.
++ */
++#include <glibconfig.h>
++
++/* include varargs functions for assertment macros
++ */
++#include <stdarg.h>
++
++#define G_DIR_SEPARATOR '/'
++#define G_DIR_SEPARATOR_S "/"
++#define G_SEARCHPATH_SEPARATOR ':'
++#define G_SEARCHPATH_SEPARATOR_S ":"
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++
++/* Provide definitions for some commonly used macros.
++ * Some of them are only provided if they haven't already
++ * been defined. It is assumed that if they are already
++ * defined then the current definition is correct.
++ */
++#ifndef NULL
++#define NULL ((void*) 0)
++#endif
++
++#ifndef FALSE
++#define FALSE (0)
++#endif
++
++#ifndef TRUE
++#define TRUE (!FALSE)
++#endif
++
++#undef MAX
++#define MAX(a, b) (((a) > (b)) ? (a) : (b))
++
++#undef MIN
++#define MIN(a, b) (((a) < (b)) ? (a) : (b))
++
++#undef ABS
++#define ABS(a) (((a) < 0) ? -(a) : (a))
++
++#undef CLAMP
++#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
++
++
++/* Define G_VA_COPY() to do the right thing for copying va_list variables.
++ * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
++ */
++#if !defined (G_VA_COPY)
++# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
++# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
++# elif defined (G_VA_COPY_AS_ARRAY)
++# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list))
++# else /* va_list is a pointer */
++# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2))
++# endif /* va_list is a pointer */
++#endif /* !G_VA_COPY */
++
++
++/* Provide convenience macros for handling structure
++ * fields through their offsets.
++ */
++#define G_STRUCT_OFFSET(struct_type, member) \
++ ((gulong) ((gchar*) &((struct_type*) 0)->member))
++#define G_STRUCT_MEMBER_P(struct_p, struct_offset) \
++ ((gpointer) ((gchar*) (struct_p) + (gulong) (struct_offset)))
++#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset) \
++ (*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset)))
++
++
++/* inlining hassle. for compilers that don't allow the `inline' keyword,
++ * mostly because of strict ANSI C compliance or dumbness, we try to fall
++ * back to either `__inline__' or `__inline'.
++ * we define G_CAN_INLINE, if the compiler seems to be actually
++ * *capable* to do function inlining, in which case inline function bodys
++ * do make sense. we also define G_INLINE_FUNC to properly export the
++ * function prototypes if no inlining can be performed.
++ * we special case most of the stuff, so inline functions can have a normal
++ * implementation by defining G_INLINE_FUNC to extern and G_CAN_INLINE to 1.
++ */
++#ifndef G_INLINE_FUNC
++# define G_CAN_INLINE 1
++#endif
++#ifdef G_HAVE_INLINE
++# if defined (__GNUC__) && defined (__STRICT_ANSI__)
++# undef inline
++# define inline __inline__
++# endif
++#else /* !G_HAVE_INLINE */
++# undef inline
++# if defined (G_HAVE___INLINE__)
++# define inline __inline__
++# else /* !inline && !__inline__ */
++# if defined (G_HAVE___INLINE)
++# define inline __inline
++# else /* !inline && !__inline__ && !__inline */
++# define inline /* don't inline, then */
++# ifndef G_INLINE_FUNC
++# undef G_CAN_INLINE
++# endif
++# endif
++# endif
++#endif
++#ifndef G_INLINE_FUNC
++# ifdef __GNUC__
++# ifdef __OPTIMIZE__
++# define G_INLINE_FUNC extern inline
++# else
++# undef G_CAN_INLINE
++# define G_INLINE_FUNC extern
++# endif
++# else /* !__GNUC__ */
++# ifdef G_CAN_INLINE
++# define G_INLINE_FUNC static inline
++# else
++# define G_INLINE_FUNC extern
++# endif
++# endif /* !__GNUC__ */
++#endif /* !G_INLINE_FUNC */
++
++
++/* Provide simple macro statement wrappers (adapted from Perl):
++ * G_STMT_START { statements; } G_STMT_END;
++ * can be used as a single statement, as in
++ * if (x) G_STMT_START { ... } G_STMT_END; else ...
++ *
++ * For gcc we will wrap the statements within `({' and `})' braces.
++ * For SunOS they will be wrapped within `if (1)' and `else (void) 0',
++ * and otherwise within `do' and `while (0)'.
++ */
++#if !(defined (G_STMT_START) && defined (G_STMT_END))
++# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
++# define G_STMT_START (void)(
++# define G_STMT_END )
++# else
++# if (defined (sun) || defined (__sun__))
++# define G_STMT_START if (1)
++# define G_STMT_END else (void)0
++# else
++# define G_STMT_START do
++# define G_STMT_END while (0)
++# endif
++# endif
++#endif
++
++
++/* Provide macros to feature the GCC function attribute.
++ */
++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
++#define G_GNUC_PRINTF( format_idx, arg_idx ) \
++ __attribute__((format (printf, format_idx, arg_idx)))
++#define G_GNUC_SCANF( format_idx, arg_idx ) \
++ __attribute__((format (scanf, format_idx, arg_idx)))
++#define G_GNUC_FORMAT( arg_idx ) \
++ __attribute__((format_arg (arg_idx)))
++#define G_GNUC_NORETURN \
++ __attribute__((noreturn))
++#define G_GNUC_CONST \
++ __attribute__((const))
++#define G_GNUC_UNUSED \
++ __attribute__((unused))
++#else /* !__GNUC__ */
++#define G_GNUC_PRINTF( format_idx, arg_idx )
++#define G_GNUC_SCANF( format_idx, arg_idx )
++#define G_GNUC_FORMAT( arg_idx )
++#define G_GNUC_NORETURN
++#define G_GNUC_CONST
++#define G_GNUC_UNUSED
++#endif /* !__GNUC__ */
++
++
++/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
++ * macros, so we can refer to them as strings unconditionally.
++ */
++#ifdef __GNUC__
++#define G_GNUC_FUNCTION __FUNCTION__
++#define G_GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__
++#else /* !__GNUC__ */
++#define G_GNUC_FUNCTION ""
++#define G_GNUC_PRETTY_FUNCTION ""
++#endif /* !__GNUC__ */
++
++/* we try to provide a usefull equivalent for ATEXIT if it is
++ * not defined, but use is actually abandoned. people should
++ * use g_atexit() instead.
++ */
++#ifndef ATEXIT
++# define ATEXIT(proc) g_ATEXIT(proc)
++#else
++# define G_NATIVE_ATEXIT
++#endif /* ATEXIT */
++
++/* Hacker macro to place breakpoints for elected machines.
++ * Actual use is strongly deprecated of course ;)
++ */
++#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
++#define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("int $03"); }G_STMT_END
++#elif defined (__alpha__) && defined (__GNUC__) && __GNUC__ >= 2
++#define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("bpt"); }G_STMT_END
++#else /* !__i386__ && !__alpha__ */
++#define G_BREAKPOINT()
++#endif /* __i386__ */
++
++
++/* Provide macros for easily allocating memory. The macros
++ * will cast the allocated memory to the specified type
++ * in order to avoid compiler warnings. (Makes the code neater).
++ */
++
++#ifdef __DMALLOC_H__
++# define g_new(type, count) (ALLOC (type, count))
++# define g_new0(type, count) (CALLOC (type, count))
++# define g_renew(type, mem, count) (REALLOC (mem, type, count))
++#else /* __DMALLOC_H__ */
++# define g_new(type, count) \
++ ((type *) g_malloc ((unsigned) sizeof (type) * (count)))
++# define g_new0(type, count) \
++ ((type *) g_malloc0 ((unsigned) sizeof (type) * (count)))
++# define g_renew(type, mem, count) \
++ ((type *) g_realloc (mem, (unsigned) sizeof (type) * (count)))
++#endif /* __DMALLOC_H__ */
++
++#define g_mem_chunk_create(type, pre_alloc, alloc_type) ( \
++ g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \
++ sizeof (type), \
++ sizeof (type) * (pre_alloc), \
++ (alloc_type)) \
++)
++#define g_chunk_new(type, chunk) ( \
++ (type *) g_mem_chunk_alloc (chunk) \
++)
++#define g_chunk_new0(type, chunk) ( \
++ (type *) g_mem_chunk_alloc0 (chunk) \
++)
++#define g_chunk_free(mem, mem_chunk) G_STMT_START { \
++ g_mem_chunk_free ((mem_chunk), (mem)); \
++} G_STMT_END
++
++
++#define g_string(x) #x
++
++
++/* Provide macros for error handling. The "assert" macros will
++ * exit on failure. The "return" macros will exit the current
++ * function. Two different definitions are given for the macros
++ * if G_DISABLE_ASSERT is not defined, in order to support gcc's
++ * __PRETTY_FUNCTION__ capability.
++ */
++
++#ifdef G_DISABLE_ASSERT
++
++#define g_assert(expr)
++#define g_assert_not_reached()
++
++#else /* !G_DISABLE_ASSERT */
++
++#ifdef __GNUC__
++
++#define g_assert(expr) G_STMT_START{ \
++ if (!(expr)) \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d (%s): assertion failed: (%s)", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__, \
++ #expr); }G_STMT_END
++
++#define g_assert_not_reached() G_STMT_START{ \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d (%s): should not be reached", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__); }G_STMT_END
++
++#else /* !__GNUC__ */
++
++#define g_assert(expr) G_STMT_START{ \
++ if (!(expr)) \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d: assertion failed: (%s)", \
++ __FILE__, \
++ __LINE__, \
++ #expr); }G_STMT_END
++
++#define g_assert_not_reached() G_STMT_START{ \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d: should not be reached", \
++ __FILE__, \
++ __LINE__); }G_STMT_END
++
++#endif /* __GNUC__ */
++
++#endif /* !G_DISABLE_ASSERT */
++
++
++#ifdef __KORBIT__
++
++#define g_return_if_fail(expr) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ return; \
++ }; }G_STMT_END
++
++#define g_return_val_if_fail(expr,val) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ return val; \
++ }; }G_STMT_END
++
++#else /* !__KORBIT__ */
++
++#ifdef G_DISABLE_CHECKS
++
++#define g_return_if_fail(expr)
++#define g_return_val_if_fail(expr,val)
++
++#else /* !G_DISABLE_CHECKS */
++
++#ifdef __GNUC__
++
++#define g_return_if_fail(expr) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d (%s): assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__, \
++ #expr); \
++ return; \
++ }; }G_STMT_END
++
++#define g_return_val_if_fail(expr,val) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d (%s): assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__, \
++ #expr); \
++ return val; \
++ }; }G_STMT_END
++
++#else /* !__GNUC__ */
++
++#define g_return_if_fail(expr) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d: assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ #expr); \
++ return; \
++ }; }G_STMT_END
++
++#define g_return_val_if_fail(expr, val) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d: assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ #expr); \
++ return val; \
++ }; }G_STMT_END
++
++#endif /* !__GNUC__ */
++
++#endif /* !G_DISABLE_CHECKS */
++
++#endif /* !__KORBIT__ */
++
++
++/* Provide type definitions for commonly used types.
++ * These are useful because a "gint8" can be adjusted
++ * to be 1 byte (8 bits) on all platforms. Similarly and
++ * more importantly, "gint32" can be adjusted to be
++ * 4 bytes (32 bits) on all platforms.
++ */
++
++typedef char gchar;
++typedef short gshort;
++typedef long glong;
++typedef int gint;
++typedef gint gboolean;
++
++typedef unsigned char guchar;
++typedef unsigned short gushort;
++typedef unsigned long gulong;
++typedef unsigned int guint;
++
++typedef float gfloat;
++typedef double gdouble;
++
++/* HAVE_LONG_DOUBLE doesn't work correctly on all platforms.
++ * Since gldouble isn't used anywhere, just disable it for now */
++
++#if 0
++#ifdef HAVE_LONG_DOUBLE
++typedef long double gldouble;
++#else /* HAVE_LONG_DOUBLE */
++typedef double gldouble;
++#endif /* HAVE_LONG_DOUBLE */
++#endif /* 0 */
++
++typedef void* gpointer;
++typedef const void *gconstpointer;
++
++
++typedef gint32 gssize;
++typedef guint32 gsize;
++typedef guint32 GQuark;
++typedef gint32 GTime;
++
++
++/* Portable endian checks and conversions
++ *
++ * glibconfig.h defines G_BYTE_ORDER which expands to one of
++ * the below macros.
++ */
++#define G_LITTLE_ENDIAN 1234
++#define G_BIG_ENDIAN 4321
++#define G_PDP_ENDIAN 3412 /* unused, need specific PDP check */
++
++
++/* Basic bit swapping functions
++ */
++#define GUINT16_SWAP_LE_BE_CONSTANT(val) ((guint16) ( \
++ (((guint16) (val) & (guint16) 0x00ffU) << 8) | \
++ (((guint16) (val) & (guint16) 0xff00U) >> 8)))
++#define GUINT32_SWAP_LE_BE_CONSTANT(val) ((guint32) ( \
++ (((guint32) (val) & (guint32) 0x000000ffU) << 24) | \
++ (((guint32) (val) & (guint32) 0x0000ff00U) << 8) | \
++ (((guint32) (val) & (guint32) 0x00ff0000U) >> 8) | \
++ (((guint32) (val) & (guint32) 0xff000000U) >> 24)))
++
++/* Intel specific stuff for speed
++ */
++#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
++# define GUINT16_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ register guint16 __v; \
++ if (__builtin_constant_p (val)) \
++ __v = GUINT16_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ __asm__ __const__ ("rorw $8, %w0" \
++ : "=r" (__v) \
++ : "0" ((guint16) (val))); \
++ __v; }))
++# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_X86 (val))
++# if !defined(__i486__) && !defined(__i586__) \
++ && !defined(__pentium__) && !defined(__i686__) && !defined(__pentiumpro__)
++# define GUINT32_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ register guint32 __v; \
++ if (__builtin_constant_p (val)) \
++ __v = GUINT32_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ __asm__ __const__ ("rorw $8, %w0\n\t" \
++ "rorl $16, %0\n\t" \
++ "rorw $8, %w0" \
++ : "=r" (__v) \
++ : "0" ((guint32) (val))); \
++ __v; }))
++# else /* 486 and higher has bswap */
++# define GUINT32_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ register guint32 __v; \
++ if (__builtin_constant_p (val)) \
++ __v = GUINT32_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ __asm__ __const__ ("bswap %0" \
++ : "=r" (__v) \
++ : "0" ((guint32) (val))); \
++ __v; }))
++# endif /* processor specific 32-bit stuff */
++# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86 (val))
++#else /* !__i386__ */
++# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
++# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
++#endif /* __i386__ */
++
++#ifdef G_HAVE_GINT64
++# define GUINT64_SWAP_LE_BE_CONSTANT(val) ((guint64) ( \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x00000000000000ffU)) << 56) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x000000000000ff00U)) << 40) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x0000000000ff0000U)) << 24) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x00000000ff000000U)) << 8) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x000000ff00000000U)) >> 8) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x0000ff0000000000U)) >> 24) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x00ff000000000000U)) >> 40) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0xff00000000000000U)) >> 56)))
++# if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
++# define GUINT64_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ union { guint64 __ll; \
++ guint32 __l[2]; } __r; \
++ if (__builtin_constant_p (val)) \
++ __r.__ll = GUINT64_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ { \
++ union { guint64 __ll; \
++ guint32 __l[2]; } __w; \
++ __w.__ll = ((guint64) val); \
++ __r.__l[0] = GUINT32_SWAP_LE_BE (__w.__l[1]); \
++ __r.__l[1] = GUINT32_SWAP_LE_BE (__w.__l[0]); \
++ } \
++ __r.__ll; }))
++# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86 (val))
++# else /* !__i386__ */
++# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT(val))
++# endif
++#endif
++
++#define GUINT16_SWAP_LE_PDP(val) ((guint16) (val))
++#define GUINT16_SWAP_BE_PDP(val) (GUINT16_SWAP_LE_BE (val))
++#define GUINT32_SWAP_LE_PDP(val) ((guint32) ( \
++ (((guint32) (val) & (guint32) 0x0000ffffU) << 16) | \
++ (((guint32) (val) & (guint32) 0xffff0000U) >> 16)))
++#define GUINT32_SWAP_BE_PDP(val) ((guint32) ( \
++ (((guint32) (val) & (guint32) 0x00ff00ffU) << 8) | \
++ (((guint32) (val) & (guint32) 0xff00ff00U) >> 8)))
++
++/* The G*_TO_?E() macros are defined in glibconfig.h.
++ * The transformation is symmetric, so the FROM just maps to the TO.
++ */
++#define GINT16_FROM_LE(val) (GINT16_TO_LE (val))
++#define GUINT16_FROM_LE(val) (GUINT16_TO_LE (val))
++#define GINT16_FROM_BE(val) (GINT16_TO_BE (val))
++#define GUINT16_FROM_BE(val) (GUINT16_TO_BE (val))
++#define GINT32_FROM_LE(val) (GINT32_TO_LE (val))
++#define GUINT32_FROM_LE(val) (GUINT32_TO_LE (val))
++#define GINT32_FROM_BE(val) (GINT32_TO_BE (val))
++#define GUINT32_FROM_BE(val) (GUINT32_TO_BE (val))
++
++#ifdef G_HAVE_GINT64
++#define GINT64_FROM_LE(val) (GINT64_TO_LE (val))
++#define GUINT64_FROM_LE(val) (GUINT64_TO_LE (val))
++#define GINT64_FROM_BE(val) (GINT64_TO_BE (val))
++#define GUINT64_FROM_BE(val) (GUINT64_TO_BE (val))
++#endif
++
++#define GLONG_FROM_LE(val) (GLONG_TO_LE (val))
++#define GULONG_FROM_LE(val) (GULONG_TO_LE (val))
++#define GLONG_FROM_BE(val) (GLONG_TO_BE (val))
++#define GULONG_FROM_BE(val) (GULONG_TO_BE (val))
++
++#define GINT_FROM_LE(val) (GINT_TO_LE (val))
++#define GUINT_FROM_LE(val) (GUINT_TO_LE (val))
++#define GINT_FROM_BE(val) (GINT_TO_BE (val))
++#define GUINT_FROM_BE(val) (GUINT_TO_BE (val))
++
++
++/* Portable versions of host-network order stuff
++ */
++#define g_ntohl(val) (GUINT32_FROM_BE (val))
++#define g_ntohs(val) (GUINT16_FROM_BE (val))
++#define g_htonl(val) (GUINT32_TO_BE (val))
++#define g_htons(val) (GUINT16_TO_BE (val))
++
++
++/* Glib version.
++ * we prefix variable declarations so they can
++ * properly get exported in windows dlls.
++ */
++#define GUTILS_C_VAR extern
++
++
++GUTILS_C_VAR const guint glib_major_version;
++GUTILS_C_VAR const guint glib_minor_version;
++GUTILS_C_VAR const guint glib_micro_version;
++GUTILS_C_VAR const guint glib_interface_age;
++GUTILS_C_VAR const guint glib_binary_age;
++
++#define GLIB_CHECK_VERSION(major,minor,micro) \
++ (GLIB_MAJOR_VERSION > (major) || \
++ (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION > (minor)) || \
++ (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION == (minor) && \
++ GLIB_MICRO_VERSION >= (micro)))
++
++/* Forward declarations of glib types.
++ */
++typedef struct _GAllocator GAllocator;
++typedef struct _GArray GArray;
++typedef struct _GByteArray GByteArray;
++typedef struct _GDebugKey GDebugKey;
++typedef struct _GHashTable GHashTable;
++typedef struct _GList GList;
++typedef struct _GMemChunk GMemChunk;
++typedef struct _GNode GNode;
++typedef struct _GPtrArray GPtrArray;
++typedef struct _GSList GSList;
++typedef struct _GString GString;
++typedef struct _GStringChunk GStringChunk;
++typedef struct _GTree GTree;
++typedef struct _GTuples GTuples;
++
++/* Tree traverse flags */
++typedef enum
++{
++ G_TRAVERSE_LEAFS = 1 << 0,
++ G_TRAVERSE_NON_LEAFS = 1 << 1,
++ G_TRAVERSE_ALL = G_TRAVERSE_LEAFS | G_TRAVERSE_NON_LEAFS,
++ G_TRAVERSE_MASK = 0x03
++} GTraverseFlags;
++
++/* Tree traverse orders */
++typedef enum
++{
++ G_IN_ORDER,
++ G_PRE_ORDER,
++ G_POST_ORDER,
++ G_LEVEL_ORDER
++} GTraverseType;
++
++/* Log level shift offset for user defined
++ * log levels (0-7 are used by GLib).
++ */
++#define G_LOG_LEVEL_USER_SHIFT (8)
++
++/* Glib log levels and flags.
++ */
++typedef enum
++{
++ /* log flags */
++ G_LOG_FLAG_RECURSION = 1 << 0,
++ G_LOG_FLAG_FATAL = 1 << 1,
++
++ /* GLib log levels */
++ G_LOG_LEVEL_ERROR = 1 << 2, /* always fatal */
++ G_LOG_LEVEL_CRITICAL = 1 << 3,
++ G_LOG_LEVEL_WARNING = 1 << 4,
++ G_LOG_LEVEL_MESSAGE = 1 << 5,
++ G_LOG_LEVEL_INFO = 1 << 6,
++ G_LOG_LEVEL_DEBUG = 1 << 7,
++
++ G_LOG_LEVEL_MASK = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL)
++} GLogLevelFlags;
++
++/* GLib log levels that are considered fatal by default */
++#define G_LOG_FATAL_MASK (G_LOG_FLAG_RECURSION | G_LOG_LEVEL_ERROR)
++
++
++typedef gint (*GCompareFunc) (gconstpointer a,
++ gconstpointer b);
++typedef gchar* (*GCompletionFunc) (gpointer);
++typedef void (*GDestroyNotify) (gpointer data);
++typedef void (*GDataForeachFunc) (GQuark key_id,
++ gpointer data,
++ gpointer user_data);
++typedef void (*GFunc) (gpointer data,
++ gpointer user_data);
++typedef guint (*GHashFunc) (gconstpointer key);
++typedef void (*GFreeFunc) (gpointer data);
++typedef void (*GHFunc) (gpointer key,
++ gpointer value,
++ gpointer user_data);
++typedef gboolean (*GHRFunc) (gpointer key,
++ gpointer value,
++ gpointer user_data);
++typedef void (*GLogFunc) (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *message,
++ gpointer user_data);
++typedef gboolean (*GNodeTraverseFunc) (GNode *node,
++ gpointer data);
++typedef void (*GNodeForeachFunc) (GNode *node,
++ gpointer data);
++typedef gint (*GSearchFunc) (gpointer key,
++ gpointer data);
++typedef gint (*GTraverseFunc) (gpointer key,
++ gpointer value,
++ gpointer data);
++typedef void (*GVoidFunc) (void);
++
++
++struct _GList
++{
++ gpointer data;
++ GList *next;
++ GList *prev;
++};
++
++struct _GSList
++{
++ gpointer data;
++ GSList *next;
++};
++
++struct _GString
++{
++ gchar *str;
++ gint len;
++};
++
++struct _GArray
++{
++ gchar *data;
++ guint len;
++};
++
++struct _GByteArray
++{
++ guint8 *data;
++ guint len;
++};
++
++struct _GPtrArray
++{
++ gpointer *pdata;
++ guint len;
++};
++
++struct _GTuples
++{
++ guint len;
++};
++
++struct _GDebugKey
++{
++ gchar *key;
++ guint value;
++};
++
++
++/* Doubly linked lists
++ */
++void g_list_push_allocator (GAllocator *allocator);
++void g_list_pop_allocator (void);
++GList* g_list_alloc (void);
++void g_list_free (GList *list);
++void g_list_free_1 (GList *list);
++GList* g_list_append (GList *list,
++ gpointer data);
++GList* g_list_prepend (GList *list,
++ gpointer data);
++GList* g_list_insert (GList *list,
++ gpointer data,
++ gint position);
++GList* g_list_insert_sorted (GList *list,
++ gpointer data,
++ GCompareFunc func);
++GList* g_list_concat (GList *list1,
++ GList *list2);
++GList* g_list_remove (GList *list,
++ gpointer data);
++GList* g_list_remove_link (GList *list,
++ GList *llink);
++GList* g_list_reverse (GList *list);
++GList* g_list_copy (GList *list);
++GList* g_list_nth (GList *list,
++ guint n);
++GList* g_list_find (GList *list,
++ gpointer data);
++GList* g_list_find_custom (GList *list,
++ gpointer data,
++ GCompareFunc func);
++gint g_list_position (GList *list,
++ GList *llink);
++gint g_list_index (GList *list,
++ gpointer data);
++GList* g_list_last (GList *list);
++GList* g_list_first (GList *list);
++guint g_list_length (GList *list);
++void g_list_foreach (GList *list,
++ GFunc func,
++ gpointer user_data);
++GList* g_list_sort (GList *list,
++ GCompareFunc compare_func);
++gpointer g_list_nth_data (GList *list,
++ guint n);
++#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL)
++#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL)
++
++
++/* Singly linked lists
++ */
++void g_slist_push_allocator (GAllocator *allocator);
++void g_slist_pop_allocator (void);
++GSList* g_slist_alloc (void);
++void g_slist_free (GSList *list);
++void g_slist_free_1 (GSList *list);
++GSList* g_slist_append (GSList *list,
++ gpointer data);
++GSList* g_slist_prepend (GSList *list,
++ gpointer data);
++GSList* g_slist_insert (GSList *list,
++ gpointer data,
++ gint position);
++GSList* g_slist_insert_sorted (GSList *list,
++ gpointer data,
++ GCompareFunc func);
++GSList* g_slist_concat (GSList *list1,
++ GSList *list2);
++GSList* g_slist_remove (GSList *list,
++ gpointer data);
++GSList* g_slist_remove_link (GSList *list,
++ GSList *llink);
++GSList* g_slist_reverse (GSList *list);
++GSList* g_slist_copy (GSList *list);
++GSList* g_slist_nth (GSList *list,
++ guint n);
++GSList* g_slist_find (GSList *list,
++ gpointer data);
++GSList* g_slist_find_custom (GSList *list,
++ gpointer data,
++ GCompareFunc func);
++gint g_slist_position (GSList *list,
++ GSList *llink);
++gint g_slist_index (GSList *list,
++ gpointer data);
++GSList* g_slist_last (GSList *list);
++guint g_slist_length (GSList *list);
++void g_slist_foreach (GSList *list,
++ GFunc func,
++ gpointer user_data);
++GSList* g_slist_sort (GSList *list,
++ GCompareFunc compare_func);
++gpointer g_slist_nth_data (GSList *list,
++ guint n);
++#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
++
++
++/* Hash tables
++ */
++GHashTable* g_hash_table_new (GHashFunc hash_func,
++ GCompareFunc key_compare_func);
++void g_hash_table_destroy (GHashTable *hash_table);
++void g_hash_table_insert (GHashTable *hash_table,
++ gpointer key,
++ gpointer value);
++void g_hash_table_remove (GHashTable *hash_table,
++ gconstpointer key);
++gpointer g_hash_table_lookup (GHashTable *hash_table,
++ gconstpointer key);
++gboolean g_hash_table_lookup_extended(GHashTable *hash_table,
++ gconstpointer lookup_key,
++ gpointer *orig_key,
++ gpointer *value);
++void g_hash_table_freeze (GHashTable *hash_table);
++void g_hash_table_thaw (GHashTable *hash_table);
++void g_hash_table_foreach (GHashTable *hash_table,
++ GHFunc func,
++ gpointer user_data);
++guint g_hash_table_foreach_remove (GHashTable *hash_table,
++ GHRFunc func,
++ gpointer user_data);
++guint g_hash_table_size (GHashTable *hash_table);
++
++
++
++
++/* Balanced binary trees
++ */
++GTree* g_tree_new (GCompareFunc key_compare_func);
++void g_tree_destroy (GTree *tree);
++void g_tree_insert (GTree *tree,
++ gpointer key,
++ gpointer value);
++void g_tree_remove (GTree *tree,
++ gpointer key);
++gpointer g_tree_lookup (GTree *tree,
++ gpointer key);
++void g_tree_traverse (GTree *tree,
++ GTraverseFunc traverse_func,
++ GTraverseType traverse_type,
++ gpointer data);
++gpointer g_tree_search (GTree *tree,
++ GSearchFunc search_func,
++ gpointer data);
++gint g_tree_height (GTree *tree);
++gint g_tree_nnodes (GTree *tree);
++
++
++
++/* N-way tree implementation
++ */
++struct _GNode
++{
++ gpointer data;
++ GNode *next;
++ GNode *prev;
++ GNode *parent;
++ GNode *children;
++};
++
++#define G_NODE_IS_ROOT(node) (((GNode*) (node))->parent == NULL && \
++ ((GNode*) (node))->prev == NULL && \
++ ((GNode*) (node))->next == NULL)
++#define G_NODE_IS_LEAF(node) (((GNode*) (node))->children == NULL)
++
++void g_node_push_allocator (GAllocator *allocator);
++void g_node_pop_allocator (void);
++GNode* g_node_new (gpointer data);
++void g_node_destroy (GNode *root);
++void g_node_unlink (GNode *node);
++GNode* g_node_insert (GNode *parent,
++ gint position,
++ GNode *node);
++GNode* g_node_insert_before (GNode *parent,
++ GNode *sibling,
++ GNode *node);
++GNode* g_node_prepend (GNode *parent,
++ GNode *node);
++guint g_node_n_nodes (GNode *root,
++ GTraverseFlags flags);
++GNode* g_node_get_root (GNode *node);
++gboolean g_node_is_ancestor (GNode *node,
++ GNode *descendant);
++guint g_node_depth (GNode *node);
++GNode* g_node_find (GNode *root,
++ GTraverseType order,
++ GTraverseFlags flags,
++ gpointer data);
++
++/* convenience macros */
++#define g_node_append(parent, node) \
++ g_node_insert_before ((parent), NULL, (node))
++#define g_node_insert_data(parent, position, data) \
++ g_node_insert ((parent), (position), g_node_new (data))
++#define g_node_insert_data_before(parent, sibling, data) \
++ g_node_insert_before ((parent), (sibling), g_node_new (data))
++#define g_node_prepend_data(parent, data) \
++ g_node_prepend ((parent), g_node_new (data))
++#define g_node_append_data(parent, data) \
++ g_node_insert_before ((parent), NULL, g_node_new (data))
++
++/* traversal function, assumes that `node' is root
++ * (only traverses `node' and its subtree).
++ * this function is just a high level interface to
++ * low level traversal functions, optimized for speed.
++ */
++void g_node_traverse (GNode *root,
++ GTraverseType order,
++ GTraverseFlags flags,
++ gint max_depth,
++ GNodeTraverseFunc func,
++ gpointer data);
++
++/* return the maximum tree height starting with `node', this is an expensive
++ * operation, since we need to visit all nodes. this could be shortened by
++ * adding `guint height' to struct _GNode, but then again, this is not very
++ * often needed, and would make g_node_insert() more time consuming.
++ */
++guint g_node_max_height (GNode *root);
++
++void g_node_children_foreach (GNode *node,
++ GTraverseFlags flags,
++ GNodeForeachFunc func,
++ gpointer data);
++void g_node_reverse_children (GNode *node);
++guint g_node_n_children (GNode *node);
++GNode* g_node_nth_child (GNode *node,
++ guint n);
++GNode* g_node_last_child (GNode *node);
++GNode* g_node_find_child (GNode *node,
++ GTraverseFlags flags,
++ gpointer data);
++gint g_node_child_position (GNode *node,
++ GNode *child);
++gint g_node_child_index (GNode *node,
++ gpointer data);
++
++GNode* g_node_first_sibling (GNode *node);
++GNode* g_node_last_sibling (GNode *node);
++
++#define g_node_prev_sibling(node) ((node) ? \
++ ((GNode*) (node))->prev : NULL)
++#define g_node_next_sibling(node) ((node) ? \
++ ((GNode*) (node))->next : NULL)
++#define g_node_first_child(node) ((node) ? \
++ ((GNode*) (node))->children : NULL)
++
++
++
++/* Fatal error handlers.
++ * g_on_error_query() will prompt the user to either
++ * [E]xit, [H]alt, [P]roceed or show [S]tack trace.
++ * g_on_error_stack_trace() invokes gdb, which attaches to the current
++ * process and shows a stack trace.
++ * These function may cause different actions on non-unix platforms.
++ * The prg_name arg is required by gdb to find the executable, if it is
++ * passed as NULL, g_on_error_query() will try g_get_prgname().
++ */
++void g_on_error_query (const gchar *prg_name);
++void g_on_error_stack_trace (const gchar *prg_name);
++
++
++/* Logging mechanism
++ */
++extern const gchar *g_log_domain_glib;
++guint g_log_set_handler (const gchar *log_domain,
++ GLogLevelFlags log_levels,
++ GLogFunc log_func,
++ gpointer user_data);
++void g_log_remove_handler (const gchar *log_domain,
++ guint handler_id);
++void g_log_default_handler (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *message,
++ gpointer unused_data);
++#ifdef __KORBIT__
++#define g_log(log_domain, log_level, format, args...) \
++G_STMT_START { printf(format, ##args); printf("\n"); } G_STMT_END
++#define g_logv(log_domain, log_level, format, args...)
++#else /* !__KORBIT__ */
++void g_log (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *format,
++ ...) G_GNUC_PRINTF (3, 4);
++void g_logv (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *format,
++ va_list args);
++#endif /* !__KORBIT__ */
++GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain,
++ GLogLevelFlags fatal_mask);
++GLogLevelFlags g_log_set_always_fatal (GLogLevelFlags fatal_mask);
++#ifndef G_LOG_DOMAIN
++#define G_LOG_DOMAIN ((gchar*) 0)
++#endif /* G_LOG_DOMAIN */
++#ifdef __GNUC__
++#define g_error(format, args...) g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ format, ##args)
++#define g_message(format, args...) g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_MESSAGE, \
++ format, ##args)
++#define g_warning(format, args...) g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_WARNING, \
++ format, ##args)
++#else /* !__GNUC__ */
++static void
++g_error (const gchar *format,
++ ...)
++{
++ va_list args;
++ va_start (args, format);
++ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
++ va_end (args);
++}
++static void
++g_message (const gchar *format,
++ ...)
++{
++ va_list args;
++ va_start (args, format);
++ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
++ va_end (args);
++}
++static void
++g_warning (const gchar *format,
++ ...)
++{
++ va_list args;
++ va_start (args, format);
++ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, args);
++ va_end (args);
++}
++#endif /* !__GNUC__ */
++
++typedef void (*GPrintFunc) (const gchar *string);
++#ifdef __KORBIT__
++#define g_print(format, args...) printf(format, ##args)
++#else
++void g_print (const gchar *format,
++ ...) G_GNUC_PRINTF (1, 2);
++#endif
++GPrintFunc g_set_print_handler (GPrintFunc func);
++void g_printerr (const gchar *format,
++ ...) G_GNUC_PRINTF (1, 2);
++GPrintFunc g_set_printerr_handler (GPrintFunc func);
++
++/* deprecated compatibility functions, use g_log_set_handler() instead */
++typedef void (*GErrorFunc) (const gchar *str);
++typedef void (*GWarningFunc) (const gchar *str);
++GErrorFunc g_set_error_handler (GErrorFunc func);
++GWarningFunc g_set_warning_handler (GWarningFunc func);
++GPrintFunc g_set_message_handler (GPrintFunc func);
++
++
++gpointer g_malloc (gulong size);
++gpointer g_malloc0 (gulong size);
++gpointer g_realloc (gpointer mem,
++ gulong size);
++void g_free (gpointer mem);
++
++/* Generic allocators
++ */
++GAllocator* g_allocator_new (const gchar *name,
++ guint n_preallocs);
++void g_allocator_free (GAllocator *allocator);
++
++#define G_ALLOCATOR_LIST (1)
++#define G_ALLOCATOR_SLIST (2)
++#define G_ALLOCATOR_NODE (3)
++
++
++/* "g_mem_chunk_new" creates a new memory chunk.
++ * Memory chunks are used to allocate pieces of memory which are
++ * always the same size. Lists are a good example of such a data type.
++ * The memory chunk allocates and frees blocks of memory as needed.
++ * Just be sure to call "g_mem_chunk_free" and not "g_free" on data
++ * allocated in a mem chunk. ("g_free" will most likely cause a seg
++ * fault...somewhere).
++ *
++ * Oh yeah, GMemChunk is an opaque data type. (You don't really
++ * want to know what's going on inside do you?)
++ */
++
++/* ALLOC_ONLY MemChunk's can only allocate memory. The free operation
++ * is interpreted as a no op. ALLOC_ONLY MemChunk's save 4 bytes per
++ * atom. (They are also useful for lists which use MemChunk to allocate
++ * memory but are also part of the MemChunk implementation).
++ * ALLOC_AND_FREE MemChunk's can allocate and free memory.
++ */
++
++#define G_ALLOC_ONLY 1
++#define G_ALLOC_AND_FREE 2
++
++GMemChunk* g_mem_chunk_new (gchar *name,
++ gint atom_size,
++ gulong area_size,
++ gint type);
++void g_mem_chunk_destroy (GMemChunk *mem_chunk);
++gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk);
++gpointer g_mem_chunk_alloc0 (GMemChunk *mem_chunk);
++void g_mem_chunk_free (GMemChunk *mem_chunk,
++ gpointer mem);
++void g_mem_chunk_clean (GMemChunk *mem_chunk);
++void g_mem_chunk_reset (GMemChunk *mem_chunk);
++void g_mem_chunk_print (GMemChunk *mem_chunk);
++void g_mem_chunk_info (void);
++
++/* Ah yes...we have a "g_blow_chunks" function.
++ * "g_blow_chunks" simply compresses all the chunks. This operation
++ * consists of freeing every memory area that should be freed (but
++ * which we haven't gotten around to doing yet). And, no,
++ * "g_blow_chunks" doesn't follow the naming scheme, but it is a
++ * much better name than "g_mem_chunk_clean_all" or something
++ * similar.
++ */
++void g_blow_chunks (void);
++
++
++/* String utility functions that modify a string argument or
++ * return a constant string that must not be freed.
++ */
++#define G_STR_DELIMITERS "_-|> <."
++gchar* g_strdelimit (gchar *string,
++ const gchar *delimiters,
++ gchar new_delimiter);
++#ifndef __KORBIT__
++gdouble g_strtod (const gchar *nptr,
++ gchar **endptr);
++#endif /* !__KORBIT__ */
++gchar* g_strerror (gint errnum);
++gchar* g_strsignal (gint signum);
++gint g_strcasecmp (const gchar *s1,
++ const gchar *s2);
++gint g_strncasecmp (const gchar *s1,
++ const gchar *s2,
++ guint n);
++void g_strdown (gchar *string);
++void g_strup (gchar *string);
++void g_strreverse (gchar *string);
++/* removes leading spaces */
++gchar* g_strchug (gchar *string);
++/* removes trailing spaces */
++gchar* g_strchomp (gchar *string);
++/* removes leading & trailing spaces */
++#define g_strstrip( string ) g_strchomp (g_strchug (string))
++
++/* String utility functions that return a newly allocated string which
++ * ought to be freed from the caller at some point.
++ */
++gchar* g_strdup (const gchar *str);
++gchar* g_strdup_printf (const gchar *format,
++ ...) G_GNUC_PRINTF (1, 2);
++gchar* g_strdup_vprintf (const gchar *format,
++ va_list args);
++gchar* g_strndup (const gchar *str,
++ guint n);
++gchar* g_strnfill (guint length,
++ gchar fill_char);
++gchar* g_strconcat (const gchar *string1,
++ ...); /* NULL terminated */
++gchar* g_strjoin (const gchar *separator,
++ ...); /* NULL terminated */
++gchar* g_strescape (gchar *string);
++gpointer g_memdup (gconstpointer mem,
++ guint byte_size);
++
++/* NULL terminated string arrays.
++ * g_strsplit() splits up string into max_tokens tokens at delim and
++ * returns a newly allocated string array.
++ * g_strjoinv() concatenates all of str_array's strings, sliding in an
++ * optional separator, the returned string is newly allocated.
++ * g_strfreev() frees the array itself and all of its strings.
++ */
++gchar** g_strsplit (const gchar *string,
++ const gchar *delimiter,
++ gint max_tokens);
++gchar* g_strjoinv (const gchar *separator,
++ gchar **str_array);
++void g_strfreev (gchar **str_array);
++
++
++
++/* calculate a string size, guarranteed to fit format + args.
++ */
++guint g_printf_string_upper_bound (const gchar* format,
++ va_list args);
++
++
++/* Retrive static string info
++ */
++gchar* g_get_user_name (void);
++gchar* g_get_real_name (void);
++gchar* g_get_home_dir (void);
++gchar* g_get_tmp_dir (void);
++gchar* g_get_prgname (void);
++void g_set_prgname (const gchar *prgname);
++
++
++/* Miscellaneous utility functions
++ */
++guint g_parse_debug_string (const gchar *string,
++ GDebugKey *keys,
++ guint nkeys);
++gint g_snprintf (gchar *string,
++ gulong n,
++ gchar const *format,
++ ...) G_GNUC_PRINTF (3, 4);
++gint g_vsnprintf (gchar *string,
++ gulong n,
++ gchar const *format,
++ va_list args);
++gchar* g_basename (const gchar *file_name);
++/* Check if a file name is an absolute path */
++gboolean g_path_is_absolute (const gchar *file_name);
++/* In case of absolute paths, skip the root part */
++gchar* g_path_skip_root (gchar *file_name);
++
++/* strings are newly allocated with g_malloc() */
++gchar* g_dirname (const gchar *file_name);
++gchar* g_get_current_dir (void);
++gchar* g_getenv (const gchar *variable);
++
++
++/* we use a GLib function as a replacement for ATEXIT, so
++ * the programmer is not required to check the return value
++ * (if there is any in the implementation) and doesn't encounter
++ * missing include files.
++ */
++void g_atexit (GVoidFunc func);
++
++
++/* Bit tests
++ */
++G_INLINE_FUNC gint g_bit_nth_lsf (guint32 mask,
++ gint nth_bit);
++#ifdef G_CAN_INLINE
++G_INLINE_FUNC gint
++g_bit_nth_lsf (guint32 mask,
++ gint nth_bit)
++{
++ do
++ {
++ nth_bit++;
++ if (mask & (1 << (guint) nth_bit))
++ return nth_bit;
++ }
++ while (nth_bit < 32);
++ return -1;
++}
++#endif /* G_CAN_INLINE */
++
++G_INLINE_FUNC gint g_bit_nth_msf (guint32 mask,
++ gint nth_bit);
++#ifdef G_CAN_INLINE
++G_INLINE_FUNC gint
++g_bit_nth_msf (guint32 mask,
++ gint nth_bit)
++{
++ if (nth_bit < 0)
++ nth_bit = 32;
++ do
++ {
++ nth_bit--;
++ if (mask & (1 << (guint) nth_bit))
++ return nth_bit;
++ }
++ while (nth_bit > 0);
++ return -1;
++}
++#endif /* G_CAN_INLINE */
++
++G_INLINE_FUNC guint g_bit_storage (guint number);
++#ifdef G_CAN_INLINE
++G_INLINE_FUNC guint
++g_bit_storage (guint number)
++{
++ register guint n_bits = 0;
++
++ do
++ {
++ n_bits++;
++ number >>= 1;
++ }
++ while (number);
++ return n_bits;
++}
++#endif /* G_CAN_INLINE */
++
++/* String Chunks
++ */
++GStringChunk* g_string_chunk_new (gint size);
++void g_string_chunk_free (GStringChunk *chunk);
++gchar* g_string_chunk_insert (GStringChunk *chunk,
++ const gchar *string);
++gchar* g_string_chunk_insert_const (GStringChunk *chunk,
++ const gchar *string);
++
++
++/* Strings
++ */
++GString* g_string_new (const gchar *init);
++GString* g_string_sized_new (guint dfl_size);
++void g_string_free (GString *string,
++ gint free_segment);
++GString* g_string_assign (GString *lval,
++ const gchar *rval);
++GString* g_string_truncate (GString *string,
++ gint len);
++GString* g_string_append (GString *string,
++ const gchar *val);
++GString* g_string_append_c (GString *string,
++ gchar c);
++GString* g_string_prepend (GString *string,
++ const gchar *val);
++GString* g_string_prepend_c (GString *string,
++ gchar c);
++GString* g_string_insert (GString *string,
++ gint pos,
++ const gchar *val);
++GString* g_string_insert_c (GString *string,
++ gint pos,
++ gchar c);
++GString* g_string_erase (GString *string,
++ gint pos,
++ gint len);
++GString* g_string_down (GString *string);
++GString* g_string_up (GString *string);
++void g_string_sprintf (GString *string,
++ const gchar *format,
++ ...) G_GNUC_PRINTF (2, 3);
++void g_string_sprintfa (GString *string,
++ const gchar *format,
++ ...) G_GNUC_PRINTF (2, 3);
++
++
++/* Resizable arrays, remove fills any cleared spot and shortens the
++ * array, while preserving the order. remove_fast will distort the
++ * order by moving the last element to the position of the removed
++ */
++
++#define g_array_append_val(a,v) g_array_append_vals (a, &v, 1)
++#define g_array_prepend_val(a,v) g_array_prepend_vals (a, &v, 1)
++#define g_array_insert_val(a,i,v) g_array_insert_vals (a, i, &v, 1)
++#define g_array_index(a,t,i) (((t*) (a)->data) [(i)])
++
++GArray* g_array_new (gboolean zero_terminated,
++ gboolean clear,
++ guint element_size);
++void g_array_free (GArray *array,
++ gboolean free_segment);
++GArray* g_array_append_vals (GArray *array,
++ gconstpointer data,
++ guint len);
++GArray* g_array_prepend_vals (GArray *array,
++ gconstpointer data,
++ guint len);
++GArray* g_array_insert_vals (GArray *array,
++ guint index,
++ gconstpointer data,
++ guint len);
++GArray* g_array_set_size (GArray *array,
++ guint length);
++GArray* g_array_remove_index (GArray *array,
++ guint index);
++GArray* g_array_remove_index_fast (GArray *array,
++ guint index);
++
++/* Resizable pointer array. This interface is much less complicated
++ * than the above. Add appends appends a pointer. Remove fills any
++ * cleared spot and shortens the array. remove_fast will again distort
++ * order.
++ */
++#define g_ptr_array_index(array,index) (array->pdata)[index]
++GPtrArray* g_ptr_array_new (void);
++void g_ptr_array_free (GPtrArray *array,
++ gboolean free_seg);
++void g_ptr_array_set_size (GPtrArray *array,
++ gint length);
++gpointer g_ptr_array_remove_index (GPtrArray *array,
++ guint index);
++gpointer g_ptr_array_remove_index_fast (GPtrArray *array,
++ guint index);
++gboolean g_ptr_array_remove (GPtrArray *array,
++ gpointer data);
++gboolean g_ptr_array_remove_fast (GPtrArray *array,
++ gpointer data);
++void g_ptr_array_add (GPtrArray *array,
++ gpointer data);
++
++/* Hash Functions
++ */
++gint g_str_equal (gconstpointer v,
++ gconstpointer v2);
++guint g_str_hash (gconstpointer v);
++
++gint g_int_equal (gconstpointer v,
++ gconstpointer v2);
++guint g_int_hash (gconstpointer v);
++
++/* This "hash" function will just return the key's adress as an
++ * unsigned integer. Useful for hashing on plain adresses or
++ * simple integer values.
++ * passing NULL into g_hash_table_new() as GHashFunc has the
++ * same effect as passing g_direct_hash().
++ */
++guint g_direct_hash (gconstpointer v);
++gint g_direct_equal (gconstpointer v,
++ gconstpointer v2);
++
++
++
++/* Prime numbers.
++ */
++
++/* This function returns prime numbers spaced by approximately 1.5-2.0
++ * and is for use in resizing data structures which prefer
++ * prime-valued sizes. The closest spaced prime function returns the
++ * next largest prime, or the highest it knows about which is about
++ * MAXINT/4.
++ */
++guint g_spaced_primes_closest (guint num);
++
++
++
++#ifndef __KORBIT__
++/* GLib Thread support
++ */
++typedef struct _GMutex GMutex;
++typedef struct _GCond GCond;
++typedef struct _GPrivate GPrivate;
++typedef struct _GStaticPrivate GStaticPrivate;
++typedef struct _GThreadFunctions GThreadFunctions;
++struct _GThreadFunctions
++{
++ GMutex* (*mutex_new) (void);
++ void (*mutex_lock) (GMutex *mutex);
++ gboolean (*mutex_trylock) (GMutex *mutex);
++ void (*mutex_unlock) (GMutex *mutex);
++ void (*mutex_free) (GMutex *mutex);
++ GCond* (*cond_new) (void);
++ void (*cond_signal) (GCond *cond);
++ void (*cond_broadcast) (GCond *cond);
++ void (*cond_wait) (GCond *cond,
++ GMutex *mutex);
++ gboolean (*cond_timed_wait) (GCond *cond,
++ GMutex *mutex,
++ GTimeVal *end_time);
++ void (*cond_free) (GCond *cond);
++ GPrivate* (*private_new) (GDestroyNotify destructor);
++ gpointer (*private_get) (GPrivate *private_key);
++ void (*private_set) (GPrivate *private_key,
++ gpointer data);
++};
++
++GUTILS_C_VAR GThreadFunctions g_thread_functions_for_glib_use;
++GUTILS_C_VAR gboolean g_thread_use_default_impl;
++GUTILS_C_VAR gboolean g_threads_got_initialized;
++
++/* initializes the mutex/cond/private implementation for glib, might
++ * only be called once, and must not be called directly or indirectly
++ * from another glib-function, e.g. as a callback.
++ */
++void g_thread_init (GThreadFunctions *vtable);
++
++/* internal function for fallback static mutex implementation */
++GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
++
++/* shorthands for conditional and unconditional function calls */
++#define G_THREAD_UF(name, arglist) \
++ (*g_thread_functions_for_glib_use . name) arglist
++#define G_THREAD_CF(name, fail, arg) \
++ (g_thread_supported () ? G_THREAD_UF (name, arg) : (fail))
++/* keep in mind, all those mutexes and static mutexes are not
++ * recursive in general, don't rely on that
++ */
++#define g_thread_supported() (g_threads_got_initialized)
++#define g_mutex_new() G_THREAD_UF (mutex_new, ())
++#define g_mutex_lock(mutex) G_THREAD_CF (mutex_lock, (void)0, (mutex))
++#define g_mutex_trylock(mutex) G_THREAD_CF (mutex_trylock, TRUE, (mutex))
++#define g_mutex_unlock(mutex) G_THREAD_CF (mutex_unlock, (void)0, (mutex))
++#define g_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
++#define g_cond_new() G_THREAD_UF (cond_new, ())
++#define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond))
++#define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond))
++#define g_cond_wait(cond, mutex) G_THREAD_CF (cond_wait, (void)0, (cond, \
++ mutex))
++#define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond))
++#define g_cond_timed_wait(cond, mutex, abs_time) G_THREAD_CF (cond_timed_wait, \
++ TRUE, \
++ (cond, mutex, \
++ abs_time))
++#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
++#define g_private_get(private_key) G_THREAD_CF (private_get, \
++ ((gpointer)private_key), \
++ (private_key))
++#define g_private_set(private_key, value) G_THREAD_CF (private_set, \
++ (void) (private_key = \
++ (GPrivate*) (value)), \
++ (private_key, value))
++/* GStaticMutexes can be statically initialized with the value
++ * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
++ * much easier, than having to explicitly allocate the mutex before
++ * use
++ */
++#define g_static_mutex_lock(mutex) \
++ g_mutex_lock (g_static_mutex_get_mutex (mutex))
++#define g_static_mutex_trylock(mutex) \
++ g_mutex_trylock (g_static_mutex_get_mutex (mutex))
++#define g_static_mutex_unlock(mutex) \
++ g_mutex_unlock (g_static_mutex_get_mutex (mutex))
++struct _GStaticPrivate
++{
++ guint index;
++};
++#define G_STATIC_PRIVATE_INIT { 0 }
++gpointer g_static_private_get (GStaticPrivate *private_key);
++void g_static_private_set (GStaticPrivate *private_key,
++ gpointer data,
++ GDestroyNotify notify);
++#endif /* __KORBIT__ */
++
++/* these are some convenience macros that expand to nothing if GLib
++ * was configured with --disable-threads. for using StaticMutexes,
++ * you define them with G_LOCK_DEFINE_STATIC (name) or G_LOCK_DEFINE (name)
++ * if you need to export the mutex. With G_LOCK_EXTERN (name) you can
++ * declare such an globally defined lock. name is a unique identifier
++ * for the protected varibale or code portion. locking, testing and
++ * unlocking of such mutexes can be done with G_LOCK(), G_UNLOCK() and
++ * G_TRYLOCK() respectively.
++ */
++#ifdef __KORBIT__
++#undef G_THREADS_ENABLED
++#endif
++
++extern void glib_dummy_decl (void);
++#define G_LOCK_NAME(name) (g__ ## name ## _lock)
++#ifdef G_THREADS_ENABLED
++# define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
++# define G_LOCK_DEFINE(name) \
++ GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT
++# define G_LOCK_EXTERN(name) extern GStaticMutex G_LOCK_NAME (name)
++
++# define G_LOCK(name) g_static_mutex_lock (&G_LOCK_NAME (name))
++# define G_UNLOCK(name) g_static_mutex_unlock (&G_LOCK_NAME (name))
++# define G_TRYLOCK(name) g_static_mutex_trylock (&G_LOCK_NAME (name))
++#else /* !G_THREADS_ENABLED */
++# define G_LOCK_DEFINE_STATIC(name) extern void glib_dummy_decl (void)
++# define G_LOCK_DEFINE(name) extern void glib_dummy_decl (void)
++# define G_LOCK_EXTERN(name) extern void glib_dummy_decl (void)
++# define G_LOCK(name)
++# define G_UNLOCK(name)
++# define G_TRYLOCK(name) (FALSE)
++#endif /* !G_THREADS_ENABLED */
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++
++#endif /* __G_LIB_H__ */
+diff -urN linux-2.4.1/net/korbit/kglib/glibconfig.h linux-2.4.1-korbit/net/korbit/kglib/glibconfig.h
+--- linux-2.4.1/net/korbit/kglib/glibconfig.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/glibconfig.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,131 @@
++/* glibconfig.h
++ *
++ * This is a generated file. Please modify `configure.in'
++ */
++
++#ifndef GLIBCONFIG_H
++#define GLIBCONFIG_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#include <limits.h>
++/*#include <float.h>*/
++#define GLIB_HAVE_SYS_POLL_H
++
++#define G_MINFLOAT FLT_MIN
++#define G_MAXFLOAT FLT_MAX
++#define G_MINDOUBLE DBL_MIN
++#define G_MAXDOUBLE DBL_MAX
++#define G_MINSHORT SHRT_MIN
++#define G_MAXSHORT SHRT_MAX
++#define G_MININT INT_MIN
++#define G_MAXINT INT_MAX
++#define G_MINLONG LONG_MIN
++#define G_MAXLONG LONG_MAX
++
++typedef signed char gint8;
++typedef unsigned char guint8;
++typedef signed short gint16;
++typedef unsigned short guint16;
++typedef signed int gint32;
++typedef unsigned int guint32;
++
++#if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
++# define G_GNUC_EXTENSION __extension__
++#else
++# define G_GNUC_EXTENSION
++#endif
++
++#define G_HAVE_GINT64 1
++
++G_GNUC_EXTENSION typedef signed long long gint64;
++G_GNUC_EXTENSION typedef unsigned long long guint64;
++
++#define G_GINT64_CONSTANT(val) (G_GNUC_EXTENSION (val##LL))
++
++#define GPOINTER_TO_INT(p) ((gint) (p))
++#define GPOINTER_TO_UINT(p) ((guint) (p))
++
++#define GINT_TO_POINTER(i) ((gpointer) (i))
++#define GUINT_TO_POINTER(u) ((gpointer) (u))
++
++#ifdef NeXT /* @#%@! NeXTStep */
++# define g_ATEXIT(proc) (!atexit (proc))
++#else
++# define g_ATEXIT(proc) (atexit (proc))
++#endif
++
++#define g_memmove(d,s,n) G_STMT_START { memmove ((d), (s), (n)); } G_STMT_END
++
++#define GLIB_MAJOR_VERSION 1
++#define GLIB_MINOR_VERSION 2
++#define GLIB_MICRO_VERSION 8
++
++
++#define G_VA_COPY __va_copy
++
++#ifdef __cplusplus
++#define G_HAVE_INLINE 1
++#else /* !__cplusplus */
++#define G_HAVE_INLINE 1
++#define G_HAVE___INLINE 1
++#define G_HAVE___INLINE__ 1
++#endif /* !__cplusplus */
++
++#define G_THREADS_ENABLED
++#define G_THREADS_IMPL_POSIX
++typedef struct _GStaticMutex GStaticMutex;
++struct _GStaticMutex
++{
++ struct _GMutex *runtime_mutex;
++ union {
++ char pad[24];
++ double dummy_double;
++ void *dummy_pointer;
++ long dummy_long;
++ } aligned_pad_u;
++};
++#define G_STATIC_MUTEX_INIT { NULL, { { 0,0,0,0,0,0,77,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} } }
++#define g_static_mutex_get_mutex(mutex) (g_thread_use_default_impl ? ((GMutex*) &((mutex)->aligned_pad_u)) : g_static_mutex_get_mutex_impl (&((mutex)->runtime_mutex)))
++
++#define GINT16_TO_BE(val) ((gint16) (val))
++#define GUINT16_TO_BE(val) ((guint16) (val))
++#define GINT16_TO_LE(val) ((gint16) GUINT16_SWAP_LE_BE (val))
++#define GUINT16_TO_LE(val) (GUINT16_SWAP_LE_BE (val))
++#define GINT32_TO_BE(val) ((gint32) (val))
++#define GUINT32_TO_BE(val) ((guint32) (val))
++#define GINT32_TO_LE(val) ((gint32) GUINT32_SWAP_LE_BE (val))
++#define GUINT32_TO_LE(val) (GUINT32_SWAP_LE_BE (val))
++#define GINT64_TO_BE(val) ((gint64) (val))
++#define GUINT64_TO_BE(val) ((guint64) (val))
++#define GINT64_TO_LE(val) ((gint64) GUINT64_SWAP_LE_BE (val))
++#define GUINT64_TO_LE(val) (GUINT64_SWAP_LE_BE (val))
++#define GLONG_TO_LE(val) ((glong) GINT32_TO_LE (val))
++#define GULONG_TO_LE(val) ((gulong) GUINT32_TO_LE (val))
++#define GLONG_TO_BE(val) ((glong) GINT32_TO_BE (val))
++#define GULONG_TO_BE(val) ((gulong) GUINT32_TO_BE (val))
++#define GINT_TO_LE(val) ((gint) GINT32_TO_LE (val))
++#define GUINT_TO_LE(val) ((guint) GUINT32_TO_LE (val))
++#define GINT_TO_BE(val) ((gint) GINT32_TO_BE (val))
++#define GUINT_TO_BE(val) ((guint) GUINT32_TO_BE (val))
++#define G_BYTE_ORDER G_LITTLE_ENDIAN
++
++#define GLIB_SYSDEF_POLLIN =1
++#define GLIB_SYSDEF_POLLOUT =4
++#define GLIB_SYSDEF_POLLPRI =2
++#define GLIB_SYSDEF_POLLERR =8
++#define GLIB_SYSDEF_POLLHUP =16
++#define GLIB_SYSDEF_POLLNVAL =32
++
++
++#define G_HAVE_WCHAR_H 1
++#define G_HAVE_WCTYPE_H 1
++
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* GLIBCONFIG_H */
+diff -urN linux-2.4.1/net/korbit/kglib/glist.c linux-2.4.1-korbit/net/korbit/kglib/glist.c
+--- linux-2.4.1/net/korbit/kglib/glist.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/glist.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,666 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++struct _GAllocator /* from gmem.c */
++{
++ gchar *name;
++ guint16 n_preallocs;
++ guint is_unused : 1;
++ guint type : 4;
++ GAllocator *last;
++ GMemChunk *mem_chunk;
++ GList *free_lists; /* implementation specific */
++};
++
++static GAllocator *current_allocator = NULL;
++G_LOCK_DEFINE_STATIC (current_allocator);
++
++/* HOLDS: current_allocator_lock */
++static void
++g_list_validate_allocator (GAllocator *allocator)
++{
++ g_return_if_fail (allocator != NULL);
++ g_return_if_fail (allocator->is_unused == TRUE);
++
++ if (allocator->type != G_ALLOCATOR_LIST)
++ {
++ allocator->type = G_ALLOCATOR_LIST;
++ if (allocator->mem_chunk)
++ {
++ g_mem_chunk_destroy (allocator->mem_chunk);
++ allocator->mem_chunk = NULL;
++ }
++ }
++
++ if (!allocator->mem_chunk)
++ {
++ allocator->mem_chunk = g_mem_chunk_new (allocator->name,
++ sizeof (GList),
++ sizeof (GList) * allocator->n_preallocs,
++ G_ALLOC_ONLY);
++ allocator->free_lists = NULL;
++ }
++
++ allocator->is_unused = FALSE;
++}
++
++void
++g_list_push_allocator(GAllocator *allocator)
++{
++ G_LOCK (current_allocator);
++ g_list_validate_allocator ( allocator );
++ allocator->last = current_allocator;
++ current_allocator = allocator;
++ G_UNLOCK (current_allocator);
++}
++
++void
++g_list_pop_allocator (void)
++{
++ G_LOCK (current_allocator);
++ if (current_allocator)
++ {
++ GAllocator *allocator;
++
++ allocator = current_allocator;
++ current_allocator = allocator->last;
++ allocator->last = NULL;
++ allocator->is_unused = TRUE;
++ }
++ G_UNLOCK (current_allocator);
++}
++
++GList*
++g_list_alloc (void)
++{
++ GList *list;
++
++ G_LOCK (current_allocator);
++ if (!current_allocator)
++ {
++ GAllocator *allocator = g_allocator_new ("GLib default GList allocator",
++ 128);
++ g_list_validate_allocator (allocator);
++ allocator->last = NULL;
++ current_allocator = allocator;
++ }
++ if (!current_allocator->free_lists)
++ {
++ list = g_chunk_new (GList, current_allocator->mem_chunk);
++ list->data = NULL;
++ }
++ else
++ {
++ if (current_allocator->free_lists->data)
++ {
++ list = current_allocator->free_lists->data;
++ current_allocator->free_lists->data = list->next;
++ list->data = NULL;
++ }
++ else
++ {
++ list = current_allocator->free_lists;
++ current_allocator->free_lists = list->next;
++ }
++ }
++ G_UNLOCK (current_allocator);
++ list->next = NULL;
++ list->prev = NULL;
++
++ return list;
++}
++
++void
++g_list_free (GList *list)
++{
++ if (list)
++ {
++ list->data = list->next;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++void
++g_list_free_1 (GList *list)
++{
++ if (list)
++ {
++ list->data = NULL;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++GList*
++g_list_append (GList *list,
++ gpointer data)
++{
++ GList *new_list;
++ GList *last;
++
++ new_list = g_list_alloc ();
++ new_list->data = data;
++
++ if (list)
++ {
++ last = g_list_last (list);
++ /* g_assert (last != NULL); */
++ last->next = new_list;
++ new_list->prev = last;
++
++ return list;
++ }
++ else
++ return new_list;
++}
++
++GList*
++g_list_prepend (GList *list,
++ gpointer data)
++{
++ GList *new_list;
++
++ new_list = g_list_alloc ();
++ new_list->data = data;
++
++ if (list)
++ {
++ if (list->prev)
++ {
++ list->prev->next = new_list;
++ new_list->prev = list->prev;
++ }
++ list->prev = new_list;
++ new_list->next = list;
++ }
++
++ return new_list;
++}
++
++GList*
++g_list_insert (GList *list,
++ gpointer data,
++ gint position)
++{
++ GList *new_list;
++ GList *tmp_list;
++
++ if (position < 0)
++ return g_list_append (list, data);
++ else if (position == 0)
++ return g_list_prepend (list, data);
++
++ tmp_list = g_list_nth (list, position);
++ if (!tmp_list)
++ return g_list_append (list, data);
++
++ new_list = g_list_alloc ();
++ new_list->data = data;
++
++ if (tmp_list->prev)
++ {
++ tmp_list->prev->next = new_list;
++ new_list->prev = tmp_list->prev;
++ }
++ new_list->next = tmp_list;
++ tmp_list->prev = new_list;
++
++ if (tmp_list == list)
++ return new_list;
++ else
++ return list;
++}
++
++GList *
++g_list_concat (GList *list1, GList *list2)
++{
++ GList *tmp_list;
++
++ if (list2)
++ {
++ tmp_list = g_list_last (list1);
++ if (tmp_list)
++ tmp_list->next = list2;
++ else
++ list1 = list2;
++ list2->prev = tmp_list;
++ }
++
++ return list1;
++}
++
++GList*
++g_list_remove (GList *list,
++ gpointer data)
++{
++ GList *tmp;
++
++ tmp = list;
++ while (tmp)
++ {
++ if (tmp->data != data)
++ tmp = tmp->next;
++ else
++ {
++ if (tmp->prev)
++ tmp->prev->next = tmp->next;
++ if (tmp->next)
++ tmp->next->prev = tmp->prev;
++
++ if (list == tmp)
++ list = list->next;
++
++ g_list_free_1 (tmp);
++
++ break;
++ }
++ }
++ return list;
++}
++
++GList*
++g_list_remove_link (GList *list,
++ GList *link)
++{
++ if (link)
++ {
++ if (link->prev)
++ link->prev->next = link->next;
++ if (link->next)
++ link->next->prev = link->prev;
++
++ if (link == list)
++ list = list->next;
++
++ link->next = NULL;
++ link->prev = NULL;
++ }
++
++ return list;
++}
++
++GList*
++g_list_copy (GList *list)
++{
++ GList *new_list = NULL;
++
++ if (list)
++ {
++ GList *last;
++
++ new_list = g_list_alloc ();
++ new_list->data = list->data;
++ last = new_list;
++ list = list->next;
++ while (list)
++ {
++ last->next = g_list_alloc ();
++ last->next->prev = last;
++ last = last->next;
++ last->data = list->data;
++ list = list->next;
++ }
++ }
++
++ return new_list;
++}
++
++GList*
++g_list_reverse (GList *list)
++{
++ GList *last;
++
++ last = NULL;
++ while (list)
++ {
++ last = list;
++ list = last->next;
++ last->next = last->prev;
++ last->prev = list;
++ }
++
++ return last;
++}
++
++GList*
++g_list_nth (GList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list;
++}
++
++gpointer
++g_list_nth_data (GList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list ? list->data : NULL;
++}
++
++GList*
++g_list_find (GList *list,
++ gpointer data)
++{
++ while (list)
++ {
++ if (list->data == data)
++ break;
++ list = list->next;
++ }
++
++ return list;
++}
++
++GList*
++g_list_find_custom (GList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ g_return_val_if_fail (func != NULL, list);
++
++ while (list)
++ {
++ if (! func (list->data, data))
++ return list;
++ list = list->next;
++ }
++
++ return NULL;
++}
++
++
++gint
++g_list_position (GList *list,
++ GList *link)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list == link)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++gint
++g_list_index (GList *list,
++ gpointer data)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list->data == data)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++GList*
++g_list_last (GList *list)
++{
++ if (list)
++ {
++ while (list->next)
++ list = list->next;
++ }
++
++ return list;
++}
++
++GList*
++g_list_first (GList *list)
++{
++ if (list)
++ {
++ while (list->prev)
++ list = list->prev;
++ }
++
++ return list;
++}
++
++guint
++g_list_length (GList *list)
++{
++ guint length;
++
++ length = 0;
++ while (list)
++ {
++ length++;
++ list = list->next;
++ }
++
++ return length;
++}
++
++void
++g_list_foreach (GList *list,
++ GFunc func,
++ gpointer user_data)
++{
++ while (list)
++ {
++ (*func) (list->data, user_data);
++ list = list->next;
++ }
++}
++
++
++GList*
++g_list_insert_sorted (GList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ GList *tmp_list = list;
++ GList *new_list;
++ gint cmp;
++
++ g_return_val_if_fail (func != NULL, list);
++
++ if (!list)
++ {
++ new_list = g_list_alloc();
++ new_list->data = data;
++ return new_list;
++ }
++
++ cmp = (*func) (data, tmp_list->data);
++
++ while ((tmp_list->next) && (cmp > 0))
++ {
++ tmp_list = tmp_list->next;
++ cmp = (*func) (data, tmp_list->data);
++ }
++
++ new_list = g_list_alloc();
++ new_list->data = data;
++
++ if ((!tmp_list->next) && (cmp > 0))
++ {
++ tmp_list->next = new_list;
++ new_list->prev = tmp_list;
++ return list;
++ }
++
++ if (tmp_list->prev)
++ {
++ tmp_list->prev->next = new_list;
++ new_list->prev = tmp_list->prev;
++ }
++ new_list->next = tmp_list;
++ tmp_list->prev = new_list;
++
++ if (tmp_list == list)
++ return new_list;
++ else
++ return list;
++}
++
++static GList *
++g_list_sort_merge (GList *l1,
++ GList *l2,
++ GCompareFunc compare_func)
++{
++ GList list, *l, *lprev;
++
++ l = &list;
++ lprev = NULL;
++
++ while (l1 && l2)
++ {
++ if (compare_func (l1->data, l2->data) < 0)
++ {
++ l->next = l1;
++ l = l->next;
++ l->prev = lprev;
++ lprev = l;
++ l1 = l1->next;
++ }
++ else
++ {
++ l->next = l2;
++ l = l->next;
++ l->prev = lprev;
++ lprev = l;
++ l2 = l2->next;
++ }
++ }
++ l->next = l1 ? l1 : l2;
++ l->next->prev = l;
++
++ return list.next;
++}
++
++GList*
++g_list_sort (GList *list,
++ GCompareFunc compare_func)
++{
++ GList *l1, *l2;
++
++ if (!list)
++ return NULL;
++ if (!list->next)
++ return list;
++
++ l1 = list;
++ l2 = list->next;
++
++ while ((l2 = l2->next) != NULL)
++ {
++ if ((l2 = l2->next) == NULL)
++ break;
++ l1 = l1->next;
++ }
++ l2 = l1->next;
++ l1->next = NULL;
++
++ return g_list_sort_merge (g_list_sort (list, compare_func),
++ g_list_sort (l2, compare_func),
++ compare_func);
++}
++
++GList*
++g_list_sort2 (GList *list,
++ GCompareFunc compare_func)
++{
++ GSList *runs = NULL;
++ GList *tmp;
++
++ /* Degenerate case. */
++ if (!list) return NULL;
++
++ /* Assume: list = [12,2,4,11,2,4,6,1,1,12]. */
++ for (tmp = list; tmp; )
++ {
++ GList *tmp2;
++ for (tmp2 = tmp;
++ tmp2->next && compare_func (tmp2->data, tmp2->next->data) <= 0;
++ tmp2 = tmp2->next)
++ /* Nothing */;
++ runs = g_slist_append (runs, tmp);
++ tmp = tmp2->next;
++ tmp2->next = NULL;
++ }
++ /* Now: runs = [[12],[2,4,11],[2,4,6],[1,1,12]]. */
++
++ while (runs->next)
++ {
++ /* We have more than one run. Merge pairwise. */
++ GSList *dst, *src, *dstprev = NULL;
++ dst = src = runs;
++ while (src && src->next)
++ {
++ dst->data = g_list_sort_merge (src->data,
++ src->next->data,
++ compare_func);
++ dstprev = dst;
++ dst = dst->next;
++ src = src->next->next;
++ }
++
++ /* If number of runs was odd, just keep the last. */
++ if (src)
++ {
++ dst->data = src->data;
++ dstprev = dst;
++ dst = dst->next;
++ }
++
++ dstprev->next = NULL;
++ g_slist_free (dst);
++ }
++
++ /* After 1st loop: runs = [[2,4,11,12],[1,1,2,4,6,12]]. */
++ /* After 2nd loop: runs = [[1,1,2,2,4,4,6,11,12,12]]. */
++
++ list = runs->data;
++ g_slist_free (runs);
++ return list;
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gmem.c linux-2.4.1-korbit/net/korbit/kglib/gmem.c
+--- linux-2.4.1/net/korbit/kglib/gmem.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gmem.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,767 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ *
++ * Mutilated on 10/22/00 by Fredrik and Chris
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdlib.h>
++#include <string.h>
++#include "glib.h"
++
++#define MEM_PROFILE_TABLE_SIZE 8192
++#define ENTER_MEM_CHUNK_ROUTINE()
++#define LEAVE_MEM_CHUNK_ROUTINE()
++
++/*
++ * This library can check for some attempts to do illegal things to
++ * memory (ENABLE_MEM_CHECK), and can do profiling
++ * (ENABLE_MEM_PROFILE). Both features are implemented by storing
++ * words before the start of the memory chunk.
++ *
++ * The first, at offset -2*SIZEOF_LONG, is used only if
++ * ENABLE_MEM_CHECK is set, and stores 0 after the memory has been
++ * allocated and 1 when it has been freed. The second, at offset
++ * -SIZEOF_LONG, is used if either flag is set and stores the size of
++ * the block.
++ *
++ * The MEM_CHECK flag is checked when memory is realloc'd and free'd,
++ * and it can be explicitly checked before using a block by calling
++ * g_mem_check().
++ */
++
++#define MEM_AREA_SIZE 4L
++
++#define MEM_ALIGN sizeof(long)
++
++
++typedef struct _GFreeAtom GFreeAtom;
++typedef struct _GMemArea GMemArea;
++typedef struct _GRealMemChunk GRealMemChunk;
++
++struct _GFreeAtom
++{
++ GFreeAtom *next;
++};
++
++struct _GMemArea
++{
++ GMemArea *next; /* the next mem area */
++ GMemArea *prev; /* the previous mem area */
++ gulong index; /* the current index into the "mem" array */
++ gulong free; /* the number of free bytes in this mem area */
++ gulong allocated; /* the number of atoms allocated from this area */
++ gulong mark; /* is this mem area marked for deletion */
++ gchar mem[MEM_AREA_SIZE]; /* the mem array from which atoms get allocated
++ * the actual size of this array is determined by
++ * the mem chunk "area_size". ANSI says that it
++ * must be declared to be the maximum size it
++ * can possibly be (even though the actual size
++ * may be less).
++ */
++};
++
++struct _GRealMemChunk
++{
++ gchar *name; /* name of this MemChunk...used for debugging output */
++ gint type; /* the type of MemChunk: ALLOC_ONLY or ALLOC_AND_FREE */
++ gint num_mem_areas; /* the number of memory areas */
++ gint num_marked_areas; /* the number of areas marked for deletion */
++ guint atom_size; /* the size of an atom */
++ gulong area_size; /* the size of a memory area */
++ GMemArea *mem_area; /* the current memory area */
++ GMemArea *mem_areas; /* a list of all the mem areas owned by this chunk */
++ GMemArea *free_mem_area; /* the free area...which is about to be destroyed */
++ GFreeAtom *free_atoms; /* the free atoms list */
++ GTree *mem_tree; /* tree of mem areas sorted by memory address */
++ GRealMemChunk *next; /* pointer to the next chunk */
++ GRealMemChunk *prev; /* pointer to the previous chunk */
++};
++
++
++static gulong g_mem_chunk_compute_size (gulong size,
++ gulong min_size);
++static gint g_mem_chunk_area_compare (GMemArea *a,
++ GMemArea *b);
++static gint g_mem_chunk_area_search (GMemArea *a,
++ gchar *addr);
++
++
++/* here we can't use StaticMutexes, as they depend upon a working
++ * g_malloc, the same holds true for StaticPrivate */
++#ifndef __KORBIT__
++static GMutex* mem_chunks_lock = NULL;
++#endif /* !__KORBIT__ */
++static GRealMemChunk *mem_chunks = NULL;
++
++
++gpointer
++g_malloc (gulong size)
++{
++ gpointer p;
++
++ if (size == 0)
++ return NULL;
++
++ p = (gpointer) malloc (size);
++ if (!p)
++ g_error ("could not allocate %ld bytes", size);
++
++ return p;
++}
++
++gpointer
++g_malloc0 (gulong size)
++{
++ gpointer p;
++
++ if (size == 0)
++ return NULL;
++
++ p = (gpointer) calloc (size, 1);
++ if (!p)
++ g_error ("could not allocate %ld bytes", size);
++
++ return p;
++}
++
++gpointer
++g_realloc (gpointer mem,
++ gulong size)
++{
++ gpointer p;
++
++ if (size == 0)
++ {
++ g_free (mem);
++
++ return NULL;
++ }
++
++ if (!mem)
++ {
++#ifdef REALLOC_0_WORKS
++ p = (gpointer) realloc (NULL, size);
++#else /* !REALLOC_0_WORKS */
++ p = (gpointer) malloc (size);
++#endif /* !REALLOC_0_WORKS */
++ }
++ else
++ {
++ p = (gpointer) realloc (mem, size);
++ }
++
++ if (!p)
++ g_error ("could not reallocate %lu bytes", (gulong) size);
++
++ return p;
++}
++
++void
++g_free (gpointer mem)
++{
++ if (mem)
++ {
++ free (mem);
++ }
++}
++
++
++void
++g_mem_profile (void)
++{
++}
++
++void
++g_mem_check (gpointer mem)
++{
++}
++
++GMemChunk*
++g_mem_chunk_new (gchar *name,
++ gint atom_size,
++ gulong area_size,
++ gint type)
++{
++ GRealMemChunk *mem_chunk;
++ gulong rarea_size;
++
++ g_return_val_if_fail (atom_size > 0, NULL);
++ g_return_val_if_fail (area_size >= atom_size, NULL);
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ area_size = (area_size + atom_size - 1) / atom_size;
++ area_size *= atom_size;
++
++ mem_chunk = g_new (struct _GRealMemChunk, 1);
++ mem_chunk->name = name;
++ mem_chunk->type = type;
++ mem_chunk->num_mem_areas = 0;
++ mem_chunk->num_marked_areas = 0;
++ mem_chunk->mem_area = NULL;
++ mem_chunk->free_mem_area = NULL;
++ mem_chunk->free_atoms = NULL;
++ mem_chunk->mem_tree = NULL;
++ mem_chunk->mem_areas = NULL;
++ mem_chunk->atom_size = atom_size;
++
++ if (mem_chunk->type == G_ALLOC_AND_FREE)
++ mem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
++
++ if (mem_chunk->atom_size % MEM_ALIGN)
++ mem_chunk->atom_size += MEM_ALIGN - (mem_chunk->atom_size % MEM_ALIGN);
++
++ rarea_size = area_size + sizeof (GMemArea) - MEM_AREA_SIZE;
++ rarea_size = g_mem_chunk_compute_size (rarea_size, atom_size + sizeof (GMemArea) - MEM_AREA_SIZE);
++ mem_chunk->area_size = rarea_size - (sizeof (GMemArea) - MEM_AREA_SIZE);
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk->next = mem_chunks;
++ mem_chunk->prev = NULL;
++ if (mem_chunks)
++ mem_chunks->prev = mem_chunk;
++ mem_chunks = mem_chunk;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++
++ return ((GMemChunk*) mem_chunk);
++}
++
++void
++g_mem_chunk_destroy (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_areas;
++ GMemArea *temp_area;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ mem_areas = rmem_chunk->mem_areas;
++ while (mem_areas)
++ {
++ temp_area = mem_areas;
++ mem_areas = mem_areas->next;
++ g_free (temp_area);
++ }
++
++ if (rmem_chunk->next)
++ rmem_chunk->next->prev = rmem_chunk->prev;
++ if (rmem_chunk->prev)
++ rmem_chunk->prev->next = rmem_chunk->next;
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ if (rmem_chunk == mem_chunks)
++ mem_chunks = mem_chunks->next;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_destroy (rmem_chunk->mem_tree);
++
++ g_free (rmem_chunk);
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++}
++
++gpointer
++g_mem_chunk_alloc (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *temp_area;
++ gpointer mem;
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ g_return_val_if_fail (mem_chunk != NULL, NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ while (rmem_chunk->free_atoms)
++ {
++ /* Get the first piece of memory on the "free_atoms" list.
++ * We can go ahead and destroy the list node we used to keep
++ * track of it with and to update the "free_atoms" list to
++ * point to its next element.
++ */
++ mem = rmem_chunk->free_atoms;
++ rmem_chunk->free_atoms = rmem_chunk->free_atoms->next;
++
++ /* Determine which area this piece of memory is allocated from */
++ temp_area = g_tree_search (rmem_chunk->mem_tree,
++ (GSearchFunc) g_mem_chunk_area_search,
++ mem);
++
++ /* If the area has been marked, then it is being destroyed.
++ * (ie marked to be destroyed).
++ * We check to see if all of the segments on the free list that
++ * reference this area have been removed. This occurs when
++ * the ammount of free memory is less than the allocatable size.
++ * If the chunk should be freed, then we place it in the "free_mem_area".
++ * This is so we make sure not to free the mem area here and then
++ * allocate it again a few lines down.
++ * If we don't allocate a chunk a few lines down then the "free_mem_area"
++ * will be freed.
++ * If there is already a "free_mem_area" then we'll just free this mem area.
++ */
++ if (temp_area->mark)
++ {
++ /* Update the "free" memory available in that area */
++ temp_area->free += rmem_chunk->atom_size;
++
++ if (temp_area->free == rmem_chunk->area_size)
++ {
++ if (temp_area == rmem_chunk->mem_area)
++ rmem_chunk->mem_area = NULL;
++
++ if (rmem_chunk->free_mem_area)
++ {
++ rmem_chunk->num_mem_areas -= 1;
++
++ if (temp_area->next)
++ temp_area->next->prev = temp_area->prev;
++ if (temp_area->prev)
++ temp_area->prev->next = temp_area->next;
++ if (temp_area == rmem_chunk->mem_areas)
++ rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_remove (rmem_chunk->mem_tree, temp_area);
++ g_free (temp_area);
++ }
++ else
++ rmem_chunk->free_mem_area = temp_area;
++
++ rmem_chunk->num_marked_areas -= 1;
++ }
++ }
++ else
++ {
++ /* Update the number of allocated atoms count.
++ */
++ temp_area->allocated += 1;
++
++ /* The area wasn't marked...return the memory
++ */
++ goto outa_here;
++ }
++ }
++
++ /* If there isn't a current mem area or the current mem area is out of space
++ * then allocate a new mem area. We'll first check and see if we can use
++ * the "free_mem_area". Otherwise we'll just malloc the mem area.
++ */
++ if ((!rmem_chunk->mem_area) ||
++ ((rmem_chunk->mem_area->index + rmem_chunk->atom_size) > rmem_chunk->area_size))
++ {
++ if (rmem_chunk->free_mem_area)
++ {
++ rmem_chunk->mem_area = rmem_chunk->free_mem_area;
++ rmem_chunk->free_mem_area = NULL;
++ }
++ else
++ {
++ rmem_chunk->mem_area = (GMemArea*) g_malloc (sizeof (GMemArea) -
++ MEM_AREA_SIZE +
++ rmem_chunk->area_size);
++
++ rmem_chunk->num_mem_areas += 1;
++ rmem_chunk->mem_area->next = rmem_chunk->mem_areas;
++ rmem_chunk->mem_area->prev = NULL;
++
++ if (rmem_chunk->mem_areas)
++ rmem_chunk->mem_areas->prev = rmem_chunk->mem_area;
++ rmem_chunk->mem_areas = rmem_chunk->mem_area;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_insert (rmem_chunk->mem_tree, rmem_chunk->mem_area, rmem_chunk->mem_area);
++ }
++
++ rmem_chunk->mem_area->index = 0;
++ rmem_chunk->mem_area->free = rmem_chunk->area_size;
++ rmem_chunk->mem_area->allocated = 0;
++ rmem_chunk->mem_area->mark = 0;
++ }
++
++ /* Get the memory and modify the state variables appropriately.
++ */
++ mem = (gpointer) &rmem_chunk->mem_area->mem[rmem_chunk->mem_area->index];
++ rmem_chunk->mem_area->index += rmem_chunk->atom_size;
++ rmem_chunk->mem_area->free -= rmem_chunk->atom_size;
++ rmem_chunk->mem_area->allocated += 1;
++
++outa_here:
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++
++ return mem;
++}
++
++gpointer
++g_mem_chunk_alloc0 (GMemChunk *mem_chunk)
++{
++ gpointer mem;
++
++ mem = g_mem_chunk_alloc (mem_chunk);
++ if (mem)
++ {
++ GRealMemChunk *rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ memset (mem, 0, rmem_chunk->atom_size);
++ }
++
++ return mem;
++}
++
++void
++g_mem_chunk_free (GMemChunk *mem_chunk,
++ gpointer mem)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *temp_area;
++ GFreeAtom *free_atom;
++
++ g_return_if_fail (mem_chunk != NULL);
++ g_return_if_fail (mem != NULL);
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ /* Don't do anything if this is an ALLOC_ONLY chunk
++ */
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ {
++ /* Place the memory on the "free_atoms" list
++ */
++ free_atom = (GFreeAtom*) mem;
++ free_atom->next = rmem_chunk->free_atoms;
++ rmem_chunk->free_atoms = free_atom;
++
++ temp_area = g_tree_search (rmem_chunk->mem_tree,
++ (GSearchFunc) g_mem_chunk_area_search,
++ mem);
++
++ temp_area->allocated -= 1;
++
++ if (temp_area->allocated == 0)
++ {
++ temp_area->mark = 1;
++ rmem_chunk->num_marked_areas += 1;
++ }
++ }
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++}
++
++/* This doesn't free the free_area if there is one */
++void
++g_mem_chunk_clean (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_area;
++ GFreeAtom *prev_free_atom;
++ GFreeAtom *temp_free_atom;
++ gpointer mem;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ {
++ prev_free_atom = NULL;
++ temp_free_atom = rmem_chunk->free_atoms;
++
++ while (temp_free_atom)
++ {
++ mem = (gpointer) temp_free_atom;
++
++ mem_area = g_tree_search (rmem_chunk->mem_tree,
++ (GSearchFunc) g_mem_chunk_area_search,
++ mem);
++
++ /* If this mem area is marked for destruction then delete the
++ * area and list node and decrement the free mem.
++ */
++ if (mem_area->mark)
++ {
++ if (prev_free_atom)
++ prev_free_atom->next = temp_free_atom->next;
++ else
++ rmem_chunk->free_atoms = temp_free_atom->next;
++ temp_free_atom = temp_free_atom->next;
++
++ mem_area->free += rmem_chunk->atom_size;
++ if (mem_area->free == rmem_chunk->area_size)
++ {
++ rmem_chunk->num_mem_areas -= 1;
++ rmem_chunk->num_marked_areas -= 1;
++
++ if (mem_area->next)
++ mem_area->next->prev = mem_area->prev;
++ if (mem_area->prev)
++ mem_area->prev->next = mem_area->next;
++ if (mem_area == rmem_chunk->mem_areas)
++ rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
++ if (mem_area == rmem_chunk->mem_area)
++ rmem_chunk->mem_area = NULL;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_remove (rmem_chunk->mem_tree, mem_area);
++ g_free (mem_area);
++ }
++ }
++ else
++ {
++ prev_free_atom = temp_free_atom;
++ temp_free_atom = temp_free_atom->next;
++ }
++ }
++ }
++}
++
++void
++g_mem_chunk_reset (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_areas;
++ GMemArea *temp_area;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ mem_areas = rmem_chunk->mem_areas;
++ rmem_chunk->num_mem_areas = 0;
++ rmem_chunk->mem_areas = NULL;
++ rmem_chunk->mem_area = NULL;
++
++ while (mem_areas)
++ {
++ temp_area = mem_areas;
++ mem_areas = mem_areas->next;
++ g_free (temp_area);
++ }
++
++ rmem_chunk->free_atoms = NULL;
++
++ if (rmem_chunk->mem_tree)
++ g_tree_destroy (rmem_chunk->mem_tree);
++ rmem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
++}
++
++void
++g_mem_chunk_print (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_areas;
++ gulong mem;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++ mem_areas = rmem_chunk->mem_areas;
++ mem = 0;
++
++ while (mem_areas)
++ {
++ mem += rmem_chunk->area_size - mem_areas->free;
++ mem_areas = mem_areas->next;
++ }
++
++ g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
++ "%s: %ld bytes using %d mem areas",
++ rmem_chunk->name, mem, rmem_chunk->num_mem_areas);
++}
++
++void
++g_mem_chunk_info (void)
++{
++ GRealMemChunk *mem_chunk;
++ gint count;
++
++ count = 0;
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk = mem_chunks;
++ while (mem_chunk)
++ {
++ count += 1;
++ mem_chunk = mem_chunk->next;
++ }
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks", count);
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk = mem_chunks;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++
++ while (mem_chunk)
++ {
++ g_mem_chunk_print ((GMemChunk*) mem_chunk);
++ mem_chunk = mem_chunk->next;
++ }
++}
++
++void
++g_blow_chunks (void)
++{
++ GRealMemChunk *mem_chunk;
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk = mem_chunks;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ while (mem_chunk)
++ {
++ g_mem_chunk_clean ((GMemChunk*) mem_chunk);
++ mem_chunk = mem_chunk->next;
++ }
++}
++
++
++static gulong
++g_mem_chunk_compute_size (gulong size,
++ gulong min_size)
++{
++ gulong power_of_2;
++ gulong lower, upper;
++
++ power_of_2 = 16;
++ while (power_of_2 < size)
++ power_of_2 <<= 1;
++
++ lower = power_of_2 >> 1;
++ upper = power_of_2;
++
++ if (size - lower < upper - size && lower >= min_size)
++ return lower;
++ else
++ return upper;
++}
++
++static gint
++g_mem_chunk_area_compare (GMemArea *a,
++ GMemArea *b)
++{
++ if (a->mem > b->mem)
++ return 1;
++ else if (a->mem < b->mem)
++ return -1;
++ return 0;
++}
++
++static gint
++g_mem_chunk_area_search (GMemArea *a,
++ gchar *addr)
++{
++ if (a->mem <= addr)
++ {
++ if (addr < &a->mem[a->index])
++ return 0;
++ return 1;
++ }
++ return -1;
++}
++
++/* generic allocators
++ */
++struct _GAllocator /* from gmem.c */
++{
++ gchar *name;
++ guint16 n_preallocs;
++ guint is_unused : 1;
++ guint type : 4;
++ GAllocator *last;
++ GMemChunk *mem_chunk;
++ gpointer dummy; /* implementation specific */
++};
++
++GAllocator*
++g_allocator_new (const gchar *name,
++ guint n_preallocs)
++{
++ GAllocator *allocator;
++
++ g_return_val_if_fail (name != NULL, NULL);
++
++ allocator = g_new0 (GAllocator, 1);
++ allocator->name = g_strdup (name);
++ allocator->n_preallocs = CLAMP (n_preallocs, 1, 65535);
++ allocator->is_unused = TRUE;
++ allocator->type = 0;
++ allocator->last = NULL;
++ allocator->mem_chunk = NULL;
++ allocator->dummy = NULL;
++
++ return allocator;
++}
++
++void
++g_allocator_free (GAllocator *allocator)
++{
++ g_return_if_fail (allocator != NULL);
++ g_return_if_fail (allocator->is_unused == TRUE);
++
++ g_free (allocator->name);
++ if (allocator->mem_chunk)
++ g_mem_chunk_destroy (allocator->mem_chunk);
++
++ g_free (allocator);
++}
++
++void
++g_mem_init (void)
++{
++#ifndef __KORBIT__
++ mem_chunks_lock = g_mutex_new();
++#endif /* !__KORBIT__ */
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gprimes.c linux-2.4.1-korbit/net/korbit/kglib/gprimes.c
+--- linux-2.4.1/net/korbit/kglib/gprimes.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gprimes.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,79 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++static const guint g_primes[] =
++{
++ 11,
++ 19,
++ 37,
++ 73,
++ 109,
++ 163,
++ 251,
++ 367,
++ 557,
++ 823,
++ 1237,
++ 1861,
++ 2777,
++ 4177,
++ 6247,
++ 9371,
++ 14057,
++ 21089,
++ 31627,
++ 47431,
++ 71143,
++ 106721,
++ 160073,
++ 240101,
++ 360163,
++ 540217,
++ 810343,
++ 1215497,
++ 1823231,
++ 2734867,
++ 4102283,
++ 6153409,
++ 9230113,
++ 13845163,
++};
++
++static const guint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
++
++guint
++g_spaced_primes_closest (guint num)
++{
++ gint i;
++
++ for (i = 0; i < g_nprimes; i++)
++ if (g_primes[i] > num)
++ return g_primes[i];
++
++ return g_primes[g_nprimes - 1];
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gslist.c linux-2.4.1-korbit/net/korbit/kglib/gslist.c
+--- linux-2.4.1/net/korbit/kglib/gslist.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gslist.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,591 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++struct _GAllocator /* from gmem.c */
++{
++ gchar *name;
++ guint16 n_preallocs;
++ guint is_unused : 1;
++ guint type : 4;
++ GAllocator *last;
++ GMemChunk *mem_chunk;
++ GSList *free_lists; /* implementation specific */
++};
++
++G_LOCK_DEFINE_STATIC (current_allocator);
++static GAllocator *current_allocator = NULL;
++
++/* HOLDS: current_allocator_lock */
++static void
++g_slist_validate_allocator (GAllocator *allocator)
++{
++ g_return_if_fail (allocator != NULL);
++ g_return_if_fail (allocator->is_unused == TRUE);
++
++ if (allocator->type != G_ALLOCATOR_SLIST)
++ {
++ allocator->type = G_ALLOCATOR_SLIST;
++ if (allocator->mem_chunk)
++ {
++ g_mem_chunk_destroy (allocator->mem_chunk);
++ allocator->mem_chunk = NULL;
++ }
++ }
++
++ if (!allocator->mem_chunk)
++ {
++ allocator->mem_chunk = g_mem_chunk_new (allocator->name,
++ sizeof (GSList),
++ sizeof (GSList) * allocator->n_preallocs,
++ G_ALLOC_ONLY);
++ allocator->free_lists = NULL;
++ }
++
++ allocator->is_unused = FALSE;
++}
++
++void
++g_slist_push_allocator (GAllocator *allocator)
++{
++ G_LOCK (current_allocator);
++ g_slist_validate_allocator (allocator);
++ allocator->last = current_allocator;
++ current_allocator = allocator;
++ G_UNLOCK (current_allocator);
++}
++
++void
++g_slist_pop_allocator (void)
++{
++ G_LOCK (current_allocator);
++ if (current_allocator)
++ {
++ GAllocator *allocator;
++
++ allocator = current_allocator;
++ current_allocator = allocator->last;
++ allocator->last = NULL;
++ allocator->is_unused = TRUE;
++ }
++ G_UNLOCK (current_allocator);
++}
++
++GSList*
++g_slist_alloc (void)
++{
++ GSList *list;
++
++ G_LOCK (current_allocator);
++ if (!current_allocator)
++ {
++ GAllocator *allocator = g_allocator_new ("GLib default GSList allocator",
++ 128);
++ g_slist_validate_allocator (allocator);
++ allocator->last = NULL;
++ current_allocator = allocator;
++ }
++ if (!current_allocator->free_lists)
++ {
++ list = g_chunk_new (GSList, current_allocator->mem_chunk);
++ list->data = NULL;
++ }
++ else
++ {
++ if (current_allocator->free_lists->data)
++ {
++ list = current_allocator->free_lists->data;
++ current_allocator->free_lists->data = list->next;
++ list->data = NULL;
++ }
++ else
++ {
++ list = current_allocator->free_lists;
++ current_allocator->free_lists = list->next;
++ }
++ }
++ G_UNLOCK (current_allocator);
++
++ list->next = NULL;
++
++ return list;
++}
++
++void
++g_slist_free (GSList *list)
++{
++ if (list)
++ {
++ list->data = list->next;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++void
++g_slist_free_1 (GSList *list)
++{
++ if (list)
++ {
++ list->data = NULL;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++GSList*
++g_slist_append (GSList *list,
++ gpointer data)
++{
++ GSList *new_list;
++ GSList *last;
++
++ new_list = g_slist_alloc ();
++ new_list->data = data;
++
++ if (list)
++ {
++ last = g_slist_last (list);
++ /* g_assert (last != NULL); */
++ last->next = new_list;
++
++ return list;
++ }
++ else
++ return new_list;
++}
++
++GSList*
++g_slist_prepend (GSList *list,
++ gpointer data)
++{
++ GSList *new_list;
++
++ new_list = g_slist_alloc ();
++ new_list->data = data;
++ new_list->next = list;
++
++ return new_list;
++}
++
++GSList*
++g_slist_insert (GSList *list,
++ gpointer data,
++ gint position)
++{
++ GSList *prev_list;
++ GSList *tmp_list;
++ GSList *new_list;
++
++ if (position < 0)
++ return g_slist_append (list, data);
++ else if (position == 0)
++ return g_slist_prepend (list, data);
++
++ new_list = g_slist_alloc ();
++ new_list->data = data;
++
++ if (!list)
++ return new_list;
++
++ prev_list = NULL;
++ tmp_list = list;
++
++ while ((position-- > 0) && tmp_list)
++ {
++ prev_list = tmp_list;
++ tmp_list = tmp_list->next;
++ }
++
++ if (prev_list)
++ {
++ new_list->next = prev_list->next;
++ prev_list->next = new_list;
++ }
++ else
++ {
++ new_list->next = list;
++ list = new_list;
++ }
++
++ return list;
++}
++
++GSList *
++g_slist_concat (GSList *list1, GSList *list2)
++{
++ if (list2)
++ {
++ if (list1)
++ g_slist_last (list1)->next = list2;
++ else
++ list1 = list2;
++ }
++
++ return list1;
++}
++
++GSList*
++g_slist_remove (GSList *list,
++ gpointer data)
++{
++ GSList *tmp;
++ GSList *prev;
++
++ prev = NULL;
++ tmp = list;
++
++ while (tmp)
++ {
++ if (tmp->data == data)
++ {
++ if (prev)
++ prev->next = tmp->next;
++ if (list == tmp)
++ list = list->next;
++
++ tmp->next = NULL;
++ g_slist_free (tmp);
++
++ break;
++ }
++
++ prev = tmp;
++ tmp = tmp->next;
++ }
++
++ return list;
++}
++
++GSList*
++g_slist_remove_link (GSList *list,
++ GSList *link)
++{
++ GSList *tmp;
++ GSList *prev;
++
++ prev = NULL;
++ tmp = list;
++
++ while (tmp)
++ {
++ if (tmp == link)
++ {
++ if (prev)
++ prev->next = tmp->next;
++ if (list == tmp)
++ list = list->next;
++
++ tmp->next = NULL;
++ break;
++ }
++
++ prev = tmp;
++ tmp = tmp->next;
++ }
++
++ return list;
++}
++
++GSList*
++g_slist_copy (GSList *list)
++{
++ GSList *new_list = NULL;
++
++ if (list)
++ {
++ GSList *last;
++
++ new_list = g_slist_alloc ();
++ new_list->data = list->data;
++ last = new_list;
++ list = list->next;
++ while (list)
++ {
++ last->next = g_slist_alloc ();
++ last = last->next;
++ last->data = list->data;
++ list = list->next;
++ }
++ }
++
++ return new_list;
++}
++
++GSList*
++g_slist_reverse (GSList *list)
++{
++ GSList *prev = NULL;
++
++ while (list)
++ {
++ GSList *next = list->next;
++
++ list->next = prev;
++
++ prev = list;
++ list = next;
++ }
++
++ return prev;
++}
++
++GSList*
++g_slist_nth (GSList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list;
++}
++
++gpointer
++g_slist_nth_data (GSList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list ? list->data : NULL;
++}
++
++GSList*
++g_slist_find (GSList *list,
++ gpointer data)
++{
++ while (list)
++ {
++ if (list->data == data)
++ break;
++ list = list->next;
++ }
++
++ return list;
++}
++
++GSList*
++g_slist_find_custom (GSList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ g_return_val_if_fail (func != NULL, list);
++
++ while (list)
++ {
++ if (! func (list->data, data))
++ return list;
++ list = list->next;
++ }
++
++ return NULL;
++}
++
++gint
++g_slist_position (GSList *list,
++ GSList *link)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list == link)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++gint
++g_slist_index (GSList *list,
++ gpointer data)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list->data == data)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++GSList*
++g_slist_last (GSList *list)
++{
++ if (list)
++ {
++ while (list->next)
++ list = list->next;
++ }
++
++ return list;
++}
++
++guint
++g_slist_length (GSList *list)
++{
++ guint length;
++
++ length = 0;
++ while (list)
++ {
++ length++;
++ list = list->next;
++ }
++
++ return length;
++}
++
++void
++g_slist_foreach (GSList *list,
++ GFunc func,
++ gpointer user_data)
++{
++ while (list)
++ {
++ (*func) (list->data, user_data);
++ list = list->next;
++ }
++}
++
++GSList*
++g_slist_insert_sorted (GSList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ GSList *tmp_list = list;
++ GSList *prev_list = NULL;
++ GSList *new_list;
++ gint cmp;
++
++ g_return_val_if_fail (func != NULL, list);
++
++ if (!list)
++ {
++ new_list = g_slist_alloc();
++ new_list->data = data;
++ return new_list;
++ }
++
++ cmp = (*func) (data, tmp_list->data);
++
++ while ((tmp_list->next) && (cmp > 0))
++ {
++ prev_list = tmp_list;
++ tmp_list = tmp_list->next;
++ cmp = (*func) (data, tmp_list->data);
++ }
++
++ new_list = g_slist_alloc();
++ new_list->data = data;
++
++ if ((!tmp_list->next) && (cmp > 0))
++ {
++ tmp_list->next = new_list;
++ return list;
++ }
++
++ if (prev_list)
++ {
++ prev_list->next = new_list;
++ new_list->next = tmp_list;
++ return list;
++ }
++ else
++ {
++ new_list->next = list;
++ return new_list;
++ }
++}
++
++static GSList*
++g_slist_sort_merge (GSList *l1,
++ GSList *l2,
++ GCompareFunc compare_func)
++{
++ GSList list, *l;
++
++ l=&list;
++
++ while (l1 && l2)
++ {
++ if (compare_func(l1->data,l2->data) < 0)
++ {
++ l=l->next=l1;
++ l1=l1->next;
++ }
++ else
++ {
++ l=l->next=l2;
++ l2=l2->next;
++ }
++ }
++ l->next= l1 ? l1 : l2;
++
++ return list.next;
++}
++
++GSList*
++g_slist_sort (GSList *list,
++ GCompareFunc compare_func)
++{
++ GSList *l1, *l2;
++
++ if (!list)
++ return NULL;
++ if (!list->next)
++ return list;
++
++ l1 = list;
++ l2 = list->next;
++
++ while ((l2 = l2->next) != NULL)
++ {
++ if ((l2 = l2->next) == NULL)
++ break;
++ l1=l1->next;
++ }
++ l2 = l1->next;
++ l1->next = NULL;
++
++ return g_slist_sort_merge (g_slist_sort (list, compare_func),
++ g_slist_sort (l2, compare_func),
++ compare_func);
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gstrfuncs.c linux-2.4.1-korbit/net/korbit/kglib/gstrfuncs.c
+--- linux-2.4.1/net/korbit/kglib/gstrfuncs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gstrfuncs.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,1308 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <locale.h>
++#include <ctype.h> /* For tolower() */
++#if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
++#include <signal.h>
++#endif
++#include "glib.h"
++/* do not include <unistd.h> in this place since it
++ * inteferes with g_strsignal() on some OSes
++ */
++
++gchar*
++g_strdup (const gchar *str) {
++ gchar *new_str;
++
++ if (str)
++ {
++ new_str = g_new (char, strlen (str) + 1);
++ strcpy (new_str, str);
++ }
++ else
++ new_str = NULL;
++
++ return new_str;
++}
++
++gpointer
++g_memdup (gconstpointer mem,
++ guint byte_size)
++{
++ gpointer new_mem;
++
++ if (mem)
++ {
++ new_mem = g_malloc (byte_size);
++ memcpy (new_mem, mem, byte_size);
++ }
++ else
++ new_mem = NULL;
++
++ return new_mem;
++}
++
++gchar*
++g_strndup (const gchar *str,
++ guint n)
++{
++ gchar *new_str;
++
++ if (str)
++ {
++ new_str = g_new (gchar, n + 1);
++ strncpy (new_str, str, n);
++ new_str[n] = '\0';
++ }
++ else
++ new_str = NULL;
++
++ return new_str;
++}
++
++gchar*
++g_strnfill (guint length,
++ gchar fill_char)
++{
++ register gchar *str, *s, *end;
++
++ str = g_new (gchar, length + 1);
++ s = str;
++ end = str + length;
++ while (s < end)
++ *(s++) = fill_char;
++ *s = 0;
++
++ return str;
++}
++
++gchar*
++g_strdup_vprintf (const gchar *format,
++ va_list args1)
++{
++ gchar *buffer;
++ va_list args2;
++
++ G_VA_COPY (args2, args1);
++
++ buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
++
++ vsprintf (buffer, format, args2);
++ va_end (args2);
++
++ return buffer;
++}
++
++gchar*
++g_strdup_printf (const gchar *format,
++ ...)
++{
++ gchar *buffer;
++ va_list args;
++
++ va_start (args, format);
++ buffer = g_strdup_vprintf (format, args);
++ va_end (args);
++
++ return buffer;
++}
++
++gchar*
++g_strconcat (const gchar *string1, ...)
++{
++ guint l;
++ va_list args;
++ gchar *s;
++ gchar *concat;
++
++ g_return_val_if_fail (string1 != NULL, NULL);
++
++ l = 1 + strlen (string1);
++ va_start (args, string1);
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ l += strlen (s);
++ s = va_arg (args, gchar*);
++ }
++ va_end (args);
++
++ concat = g_new (gchar, l);
++ concat[0] = 0;
++
++ strcat (concat, string1);
++ va_start (args, string1);
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ strcat (concat, s);
++ s = va_arg (args, gchar*);
++ }
++ va_end (args);
++
++ return concat;
++}
++
++#ifndef __KORBIT__
++gdouble
++g_strtod (const gchar *nptr,
++ gchar **endptr)
++{
++ gchar *fail_pos_1;
++ gchar *fail_pos_2;
++ gdouble val_1;
++ gdouble val_2 = 0;
++
++ g_return_val_if_fail (nptr != NULL, 0);
++
++ fail_pos_1 = NULL;
++ fail_pos_2 = NULL;
++
++ val_1 = strtod (nptr, &fail_pos_1);
++
++ if (fail_pos_1 && fail_pos_1[0] != 0)
++ {
++ gchar *old_locale;
++
++ old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
++ setlocale (LC_NUMERIC, "C");
++ val_2 = strtod (nptr, &fail_pos_2);
++ setlocale (LC_NUMERIC, old_locale);
++ g_free (old_locale);
++ }
++
++ if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
++ {
++ if (endptr)
++ *endptr = fail_pos_1;
++ return val_1;
++ }
++ else
++ {
++ if (endptr)
++ *endptr = fail_pos_2;
++ return val_2;
++ }
++}
++#endif /* !__KORBIT__ */
++
++gchar*
++g_strerror (gint errnum)
++{
++#ifndef __KORBIT__
++ static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
++ char *msg;
++#endif
++
++#ifdef __KORBIT__
++#undef HAVE_STRERROR
++#define NO_SYS_ERRLIST 1
++#endif
++
++#if defined(HAVE_STRERROR)
++ return strerror (errnum);
++#elif NO_SYS_ERRLIST
++ switch (errnum)
++ {
++#ifdef E2BIG
++ case E2BIG: return "argument list too long";
++#endif
++#ifdef EACCES
++ case EACCES: return "permission denied";
++#endif
++#ifdef EADDRINUSE
++ case EADDRINUSE: return "address already in use";
++#endif
++#ifdef EADDRNOTAVAIL
++ case EADDRNOTAVAIL: return "can't assign requested address";
++#endif
++#ifdef EADV
++ case EADV: return "advertise error";
++#endif
++#ifdef EAFNOSUPPORT
++ case EAFNOSUPPORT: return "address family not supported by protocol family";
++#endif
++#ifdef EAGAIN
++ case EAGAIN: return "try again";
++#endif
++#ifdef EALIGN
++ case EALIGN: return "EALIGN";
++#endif
++#ifdef EALREADY
++ case EALREADY: return "operation already in progress";
++#endif
++#ifdef EBADE
++ case EBADE: return "bad exchange descriptor";
++#endif
++#ifdef EBADF
++ case EBADF: return "bad file number";
++#endif
++#ifdef EBADFD
++ case EBADFD: return "file descriptor in bad state";
++#endif
++#ifdef EBADMSG
++ case EBADMSG: return "not a data message";
++#endif
++#ifdef EBADR
++ case EBADR: return "bad request descriptor";
++#endif
++#ifdef EBADRPC
++ case EBADRPC: return "RPC structure is bad";
++#endif
++#ifdef EBADRQC
++ case EBADRQC: return "bad request code";
++#endif
++#ifdef EBADSLT
++ case EBADSLT: return "invalid slot";
++#endif
++#ifdef EBFONT
++ case EBFONT: return "bad font file format";
++#endif
++#ifdef EBUSY
++ case EBUSY: return "mount device busy";
++#endif
++#ifdef ECHILD
++ case ECHILD: return "no children";
++#endif
++#ifdef ECHRNG
++ case ECHRNG: return "channel number out of range";
++#endif
++#ifdef ECOMM
++ case ECOMM: return "communication error on send";
++#endif
++#ifdef ECONNABORTED
++ case ECONNABORTED: return "software caused connection abort";
++#endif
++#ifdef ECONNREFUSED
++ case ECONNREFUSED: return "connection refused";
++#endif
++#ifdef ECONNRESET
++ case ECONNRESET: return "connection reset by peer";
++#endif
++#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK)) && (!defined(EDEADLOCK) || (EDEADLK != EDEADLOCK))
++ case EDEADLK: return "resource deadlock avoided";
++#endif
++#ifdef EDEADLOCK
++ case EDEADLOCK: return "resource deadlock avoided";
++#endif
++#ifdef EDESTADDRREQ
++ case EDESTADDRREQ: return "destination address required";
++#endif
++#ifdef EDIRTY
++ case EDIRTY: return "mounting a dirty fs w/o force";
++#endif
++#ifdef EDOM
++ case EDOM: return "math argument out of range";
++#endif
++#ifdef EDOTDOT
++ case EDOTDOT: return "cross mount point";
++#endif
++#ifdef EDQUOT
++ case EDQUOT: return "disk quota exceeded";
++#endif
++#ifdef EDUPPKG
++ case EDUPPKG: return "duplicate package name";
++#endif
++#ifdef EEXIST
++ case EEXIST: return "file already exists";
++#endif
++#ifdef EFAULT
++ case EFAULT: return "bad address in system call argument";
++#endif
++#ifdef EFBIG
++ case EFBIG: return "file too large";
++#endif
++#ifdef EHOSTDOWN
++ case EHOSTDOWN: return "host is down";
++#endif
++#ifdef EHOSTUNREACH
++ case EHOSTUNREACH: return "host is unreachable";
++#endif
++#ifdef EIDRM
++ case EIDRM: return "identifier removed";
++#endif
++#ifdef EINIT
++ case EINIT: return "initialization error";
++#endif
++#ifdef EINPROGRESS
++ case EINPROGRESS: return "operation now in progress";
++#endif
++#ifdef EINTR
++ case EINTR: return "interrupted system call";
++#endif
++#ifdef EINVAL
++ case EINVAL: return "invalid argument";
++#endif
++#ifdef EIO
++ case EIO: return "I/O error";
++#endif
++#ifdef EISCONN
++ case EISCONN: return "socket is already connected";
++#endif
++#ifdef EISDIR
++ case EISDIR: return "illegal operation on a directory";
++#endif
++#ifdef EISNAME
++ case EISNAM: return "is a name file";
++#endif
++#ifdef ELBIN
++ case ELBIN: return "ELBIN";
++#endif
++#ifdef EL2HLT
++ case EL2HLT: return "level 2 halted";
++#endif
++#ifdef EL2NSYNC
++ case EL2NSYNC: return "level 2 not synchronized";
++#endif
++#ifdef EL3HLT
++ case EL3HLT: return "level 3 halted";
++#endif
++#ifdef EL3RST
++ case EL3RST: return "level 3 reset";
++#endif
++#ifdef ELIBACC
++ case ELIBACC: return "can not access a needed shared library";
++#endif
++#ifdef ELIBBAD
++ case ELIBBAD: return "accessing a corrupted shared library";
++#endif
++#ifdef ELIBEXEC
++ case ELIBEXEC: return "can not exec a shared library directly";
++#endif
++#ifdef ELIBMAX
++ case ELIBMAX: return "attempting to link in more shared libraries than system limit";
++#endif
++#ifdef ELIBSCN
++ case ELIBSCN: return ".lib section in a.out corrupted";
++#endif
++#ifdef ELNRNG
++ case ELNRNG: return "link number out of range";
++#endif
++#ifdef ELOOP
++ case ELOOP: return "too many levels of symbolic links";
++#endif
++#ifdef EMFILE
++ case EMFILE: return "too many open files";
++#endif
++#ifdef EMLINK
++ case EMLINK: return "too many links";
++#endif
++#ifdef EMSGSIZE
++ case EMSGSIZE: return "message too long";
++#endif
++#ifdef EMULTIHOP
++ case EMULTIHOP: return "multihop attempted";
++#endif
++#ifdef ENAMETOOLONG
++ case ENAMETOOLONG: return "file name too long";
++#endif
++#ifdef ENAVAIL
++ case ENAVAIL: return "not available";
++#endif
++#ifdef ENET
++ case ENET: return "ENET";
++#endif
++#ifdef ENETDOWN
++ case ENETDOWN: return "network is down";
++#endif
++#ifdef ENETRESET
++ case ENETRESET: return "network dropped connection on reset";
++#endif
++#ifdef ENETUNREACH
++ case ENETUNREACH: return "network is unreachable";
++#endif
++#ifdef ENFILE
++ case ENFILE: return "file table overflow";
++#endif
++#ifdef ENOANO
++ case ENOANO: return "anode table overflow";
++#endif
++#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
++ case ENOBUFS: return "no buffer space available";
++#endif
++#ifdef ENOCSI
++ case ENOCSI: return "no CSI structure available";
++#endif
++#ifdef ENODATA
++ case ENODATA: return "no data available";
++#endif
++#ifdef ENODEV
++ case ENODEV: return "no such device";
++#endif
++#ifdef ENOENT
++ case ENOENT: return "no such file or directory";
++#endif
++#ifdef ENOEXEC
++ case ENOEXEC: return "exec format error";
++#endif
++#ifdef ENOLCK
++ case ENOLCK: return "no locks available";
++#endif
++#ifdef ENOLINK
++ case ENOLINK: return "link has be severed";
++#endif
++#ifdef ENOMEM
++ case ENOMEM: return "not enough memory";
++#endif
++#ifdef ENOMSG
++ case ENOMSG: return "no message of desired type";
++#endif
++#ifdef ENONET
++ case ENONET: return "machine is not on the network";
++#endif
++#ifdef ENOPKG
++ case ENOPKG: return "package not installed";
++#endif
++#ifdef ENOPROTOOPT
++ case ENOPROTOOPT: return "bad proocol option";
++#endif
++#ifdef ENOSPC
++ case ENOSPC: return "no space left on device";
++#endif
++#ifdef ENOSR
++ case ENOSR: return "out of stream resources";
++#endif
++#ifdef ENOSTR
++ case ENOSTR: return "not a stream device";
++#endif
++#ifdef ENOSYM
++ case ENOSYM: return "unresolved symbol name";
++#endif
++#ifdef ENOSYS
++ case ENOSYS: return "function not implemented";
++#endif
++#ifdef ENOTBLK
++ case ENOTBLK: return "block device required";
++#endif
++#ifdef ENOTCONN
++ case ENOTCONN: return "socket is not connected";
++#endif
++#ifdef ENOTDIR
++ case ENOTDIR: return "not a directory";
++#endif
++#ifdef ENOTEMPTY
++ case ENOTEMPTY: return "directory not empty";
++#endif
++#ifdef ENOTNAM
++ case ENOTNAM: return "not a name file";
++#endif
++#ifdef ENOTSOCK
++ case ENOTSOCK: return "socket operation on non-socket";
++#endif
++#ifdef ENOTTY
++ case ENOTTY: return "inappropriate device for ioctl";
++#endif
++#ifdef ENOTUNIQ
++ case ENOTUNIQ: return "name not unique on network";
++#endif
++#ifdef ENXIO
++ case ENXIO: return "no such device or address";
++#endif
++#ifdef EOPNOTSUPP
++ case EOPNOTSUPP: return "operation not supported on socket";
++#endif
++#ifdef EPERM
++ case EPERM: return "not owner";
++#endif
++#ifdef EPFNOSUPPORT
++ case EPFNOSUPPORT: return "protocol family not supported";
++#endif
++#ifdef EPIPE
++ case EPIPE: return "broken pipe";
++#endif
++#ifdef EPROCLIM
++ case EPROCLIM: return "too many processes";
++#endif
++#ifdef EPROCUNAVAIL
++ case EPROCUNAVAIL: return "bad procedure for program";
++#endif
++#ifdef EPROGMISMATCH
++ case EPROGMISMATCH: return "program version wrong";
++#endif
++#ifdef EPROGUNAVAIL
++ case EPROGUNAVAIL: return "RPC program not available";
++#endif
++#ifdef EPROTO
++ case EPROTO: return "protocol error";
++#endif
++#ifdef EPROTONOSUPPORT
++ case EPROTONOSUPPORT: return "protocol not suppored";
++#endif
++#ifdef EPROTOTYPE
++ case EPROTOTYPE: return "protocol wrong type for socket";
++#endif
++#ifdef ERANGE
++ case ERANGE: return "math result unrepresentable";
++#endif
++#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
++ case EREFUSED: return "EREFUSED";
++#endif
++#ifdef EREMCHG
++ case EREMCHG: return "remote address changed";
++#endif
++#ifdef EREMDEV
++ case EREMDEV: return "remote device";
++#endif
++#ifdef EREMOTE
++ case EREMOTE: return "pathname hit remote file system";
++#endif
++#ifdef EREMOTEIO
++ case EREMOTEIO: return "remote i/o error";
++#endif
++#ifdef EREMOTERELEASE
++ case EREMOTERELEASE: return "EREMOTERELEASE";
++#endif
++#ifdef EROFS
++ case EROFS: return "read-only file system";
++#endif
++#ifdef ERPCMISMATCH
++ case ERPCMISMATCH: return "RPC version is wrong";
++#endif
++#ifdef ERREMOTE
++ case ERREMOTE: return "object is remote";
++#endif
++#ifdef ESHUTDOWN
++ case ESHUTDOWN: return "can't send afer socket shutdown";
++#endif
++#ifdef ESOCKTNOSUPPORT
++ case ESOCKTNOSUPPORT: return "socket type not supported";
++#endif
++#ifdef ESPIPE
++ case ESPIPE: return "invalid seek";
++#endif
++#ifdef ESRCH
++ case ESRCH: return "no such process";
++#endif
++#ifdef ESRMNT
++ case ESRMNT: return "srmount error";
++#endif
++#ifdef ESTALE
++ case ESTALE: return "stale remote file handle";
++#endif
++#ifdef ESUCCESS
++ case ESUCCESS: return "Error 0";
++#endif
++#ifdef ETIME
++ case ETIME: return "timer expired";
++#endif
++#ifdef ETIMEDOUT
++ case ETIMEDOUT: return "connection timed out";
++#endif
++#ifdef ETOOMANYREFS
++ case ETOOMANYREFS: return "too many references: can't splice";
++#endif
++#ifdef ETXTBSY
++ case ETXTBSY: return "text file or pseudo-device busy";
++#endif
++#ifdef EUCLEAN
++ case EUCLEAN: return "structure needs cleaning";
++#endif
++#ifdef EUNATCH
++ case EUNATCH: return "protocol driver not attached";
++#endif
++#ifdef EUSERS
++ case EUSERS: return "too many users";
++#endif
++#ifdef EVERSION
++ case EVERSION: return "version mismatch";
++#endif
++#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
++ case EWOULDBLOCK: return "operation would block";
++#endif
++#ifdef EXDEV
++ case EXDEV: return "cross-domain link";
++#endif
++#ifdef EXFULL
++ case EXFULL: return "message tables full";
++#endif
++ }
++#else /* NO_SYS_ERRLIST */
++ extern int sys_nerr;
++ extern char *sys_errlist[];
++
++ if ((errnum > 0) && (errnum <= sys_nerr))
++ return sys_errlist [errnum];
++#endif /* NO_SYS_ERRLIST */
++
++#ifndef __KORBIT__
++ msg = g_static_private_get (&msg_private);
++ if (!msg)
++ {
++ msg = g_new (gchar, 64);
++ g_static_private_set (&msg_private, msg, g_free);
++ }
++
++ sprintf (msg, "unknown error (%d)", errnum);
++
++ return msg;
++#else
++ return "unknown error";
++#endif /* !__KORBIT__ */
++}
++
++gchar*
++g_strsignal (gint signum)
++{
++#ifndef __KORBIT__
++ static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
++ char *msg;
++#endif
++
++#ifdef HAVE_STRSIGNAL
++ extern char *strsignal (int sig);
++ return strsignal (signum);
++#elif NO_SYS_SIGLIST
++ switch (signum)
++ {
++#ifdef SIGHUP
++ case SIGHUP: return "Hangup";
++#endif
++#ifdef SIGINT
++ case SIGINT: return "Interrupt";
++#endif
++#ifdef SIGQUIT
++ case SIGQUIT: return "Quit";
++#endif
++#ifdef SIGILL
++ case SIGILL: return "Illegal instruction";
++#endif
++#ifdef SIGTRAP
++ case SIGTRAP: return "Trace/breakpoint trap";
++#endif
++#ifdef SIGABRT
++ case SIGABRT: return "IOT trap/Abort";
++#endif
++#ifdef SIGBUS
++ case SIGBUS: return "Bus error";
++#endif
++#ifdef SIGFPE
++ case SIGFPE: return "Floating point exception";
++#endif
++#ifdef SIGKILL
++ case SIGKILL: return "Killed";
++#endif
++#ifdef SIGUSR1
++ case SIGUSR1: return "User defined signal 1";
++#endif
++#ifdef SIGSEGV
++ case SIGSEGV: return "Segmentation fault";
++#endif
++#ifdef SIGUSR2
++ case SIGUSR2: return "User defined signal 2";
++#endif
++#ifdef SIGPIPE
++ case SIGPIPE: return "Broken pipe";
++#endif
++#ifdef SIGALRM
++ case SIGALRM: return "Alarm clock";
++#endif
++#ifdef SIGTERM
++ case SIGTERM: return "Terminated";
++#endif
++#ifdef SIGSTKFLT
++ case SIGSTKFLT: return "Stack fault";
++#endif
++#ifdef SIGCHLD
++ case SIGCHLD: return "Child exited";
++#endif
++#ifdef SIGCONT
++ case SIGCONT: return "Continued";
++#endif
++#ifdef SIGSTOP
++ case SIGSTOP: return "Stopped (signal)";
++#endif
++#ifdef SIGTSTP
++ case SIGTSTP: return "Stopped";
++#endif
++#ifdef SIGTTIN
++ case SIGTTIN: return "Stopped (tty input)";
++#endif
++#ifdef SIGTTOU
++ case SIGTTOU: return "Stopped (tty output)";
++#endif
++#ifdef SIGURG
++ case SIGURG: return "Urgent condition";
++#endif
++#ifdef SIGXCPU
++ case SIGXCPU: return "CPU time limit exceeded";
++#endif
++#ifdef SIGXFSZ
++ case SIGXFSZ: return "File size limit exceeded";
++#endif
++#ifdef SIGVTALRM
++ case SIGVTALRM: return "Virtual time alarm";
++#endif
++#ifdef SIGPROF
++ case SIGPROF: return "Profile signal";
++#endif
++#ifdef SIGWINCH
++ case SIGWINCH: return "Window size changed";
++#endif
++#ifdef SIGIO
++ case SIGIO: return "Possible I/O";
++#endif
++#ifdef SIGPWR
++ case SIGPWR: return "Power failure";
++#endif
++#ifdef SIGUNUSED
++ case SIGUNUSED: return "Unused signal";
++#endif
++ }
++#else /* NO_SYS_SIGLIST */
++
++#ifdef NO_SYS_SIGLIST_DECL
++ extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
++#endif
++
++ return (char*) /* this function should return const --josh */ sys_siglist [signum];
++#endif /* NO_SYS_SIGLIST */
++
++#ifndef __KORBIT__
++ msg = g_static_private_get (&msg_private);
++ if (!msg)
++ {
++ msg = g_new (gchar, 64);
++ g_static_private_set (&msg_private, msg, g_free);
++ }
++
++ sprintf (msg, "unknown signal (%d)", signum);
++
++ return msg;
++#else
++ return "unknown error";
++#endif /* !__KORBIT__ */
++}
++
++guint
++g_printf_string_upper_bound (const gchar* format,
++ va_list args)
++{
++ guint len = 1;
++
++ while (*format)
++ {
++ gboolean long_int = FALSE;
++ gboolean extra_long = FALSE;
++ gchar c;
++
++ c = *format++;
++
++ if (c == '%')
++ {
++ gboolean done = FALSE;
++
++ while (*format && !done)
++ {
++ switch (*format++)
++ {
++ gchar *string_arg;
++
++ case '*':
++ len += va_arg (args, int);
++ break;
++ case '1':
++ case '2':
++ case '3':
++ case '4':
++ case '5':
++ case '6':
++ case '7':
++ case '8':
++ case '9':
++ /* add specified format length, since it might exceed the
++ * size we assume it to have.
++ */
++ format -= 1;
++ len += strtol (format, (char**) &format, 10);
++ break;
++ case 'h':
++ /* ignore short int flag, since all args have at least the
++ * same size as an int
++ */
++ break;
++ case 'l':
++ if (long_int)
++ extra_long = TRUE; /* linux specific */
++ else
++ long_int = TRUE;
++ break;
++ case 'q':
++ case 'L':
++ long_int = TRUE;
++ extra_long = TRUE;
++ break;
++ case 's':
++ string_arg = va_arg (args, char *);
++ if (string_arg)
++ len += strlen (string_arg);
++ else
++ {
++ /* add enough padding to hold "(null)" identifier */
++ len += 16;
++ }
++ done = TRUE;
++ break;
++ case 'd':
++ case 'i':
++ case 'o':
++ case 'u':
++ case 'x':
++ case 'X':
++#ifdef G_HAVE_GINT64
++ if (extra_long)
++ (void) va_arg (args, gint64);
++ else
++#endif /* G_HAVE_GINT64 */
++ {
++ if (long_int)
++ (void) va_arg (args, long);
++ else
++ (void) va_arg (args, int);
++ }
++ len += extra_long ? 64 : 32;
++ done = TRUE;
++ break;
++ case 'D':
++ case 'O':
++ case 'U':
++ (void) va_arg (args, long);
++ len += 32;
++ done = TRUE;
++ break;
++ case 'e':
++ case 'E':
++ case 'f':
++ case 'g':
++#ifdef HAVE_LONG_DOUBLE
++ if (extra_long)
++ (void) va_arg (args, long double);
++ else
++#endif /* HAVE_LONG_DOUBLE */
++ (void) va_arg (args, double);
++ len += extra_long ? 128 : 64;
++ done = TRUE;
++ break;
++ case 'c':
++ (void) va_arg (args, int);
++ len += 1;
++ done = TRUE;
++ break;
++ case 'p':
++ case 'n':
++ (void) va_arg (args, void*);
++ len += 32;
++ done = TRUE;
++ break;
++ case '%':
++ len += 1;
++ done = TRUE;
++ break;
++ default:
++ /* ignore unknow/invalid flags */
++ break;
++ }
++ }
++ }
++ else
++ len += 1;
++ }
++
++ return len;
++}
++
++void
++g_strdown (gchar *string)
++{
++ register guchar *s;
++
++ g_return_if_fail (string != NULL);
++
++ s = string;
++
++ while (*s)
++ {
++ *s = tolower (*s);
++ s++;
++ }
++}
++
++void
++g_strup (gchar *string)
++{
++ register guchar *s;
++
++ g_return_if_fail (string != NULL);
++
++ s = string;
++
++ while (*s)
++ {
++ *s = toupper (*s);
++ s++;
++ }
++}
++
++void
++g_strreverse (gchar *string)
++{
++ g_return_if_fail (string != NULL);
++
++ if (*string)
++ {
++ register gchar *h, *t;
++
++ h = string;
++ t = string + strlen (string) - 1;
++
++ while (h < t)
++ {
++ register gchar c;
++
++ c = *h;
++ *h = *t;
++ h++;
++ *t = c;
++ t--;
++ }
++ }
++}
++
++gint
++g_strcasecmp (const gchar *s1,
++ const gchar *s2)
++{
++#ifdef HAVE_STRCASECMP
++ g_return_val_if_fail (s1 != NULL, 0);
++ g_return_val_if_fail (s2 != NULL, 0);
++
++ return strcasecmp (s1, s2);
++#else
++ gint c1, c2;
++
++ g_return_val_if_fail (s1 != NULL, 0);
++ g_return_val_if_fail (s2 != NULL, 0);
++
++ while (*s1 && *s2)
++ {
++ /* According to A. Cox, some platforms have islower's that
++ * don't work right on non-uppercase
++ */
++ c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
++ c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
++ if (c1 != c2)
++ return (c1 - c2);
++ s1++; s2++;
++ }
++
++ return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
++#endif
++}
++
++gint
++g_strncasecmp (const gchar *s1,
++ const gchar *s2,
++ guint n)
++{
++#ifdef HAVE_STRNCASECMP
++ return strncasecmp (s1, s2, n);
++#else
++ gint c1, c2;
++
++ g_return_val_if_fail (s1 != NULL, 0);
++ g_return_val_if_fail (s2 != NULL, 0);
++
++ while (n-- && *s1 && *s2)
++ {
++ /* According to A. Cox, some platforms have islower's that
++ * don't work right on non-uppercase
++ */
++ c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
++ c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
++ if (c1 != c2)
++ return (c1 - c2);
++ s1++; s2++;
++ }
++
++ if (n)
++ return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
++ else
++ return 0;
++#endif
++}
++
++gchar*
++g_strdelimit (gchar *string,
++ const gchar *delimiters,
++ gchar new_delim)
++{
++ register gchar *c;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ if (!delimiters)
++ delimiters = G_STR_DELIMITERS;
++
++ for (c = string; *c; c++)
++ {
++ if (strchr (delimiters, *c))
++ *c = new_delim;
++ }
++
++ return string;
++}
++
++gchar*
++g_strescape (gchar *string)
++{
++ gchar *q;
++ gchar *escaped;
++ guint backslashes = 0;
++ gchar *p = string;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ while (*p != '\000')
++ backslashes += (*p++ == '\\');
++
++ if (!backslashes)
++ return g_strdup (string);
++
++ escaped = g_new (gchar, strlen (string) + backslashes + 1);
++
++ p = string;
++ q = escaped;
++
++ while (*p != '\000')
++ {
++ if (*p == '\\')
++ *q++ = '\\';
++ *q++ = *p++;
++ }
++ *q = '\000';
++
++ return escaped;
++}
++
++/* blame Elliot for these next five routines */
++gchar*
++g_strchug (gchar *string)
++{
++ guchar *start;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ for (start = string; *start && isspace (*start); start++)
++ ;
++
++ g_memmove(string, start, strlen(start) + 1);
++
++ return string;
++}
++
++gchar*
++g_strchomp (gchar *string)
++{
++ gchar *s;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ if (!*string)
++ return string;
++
++ for (s = string + strlen (string) - 1; s >= string && isspace ((guchar)*s);
++ s--)
++ *s = '\0';
++
++ return string;
++}
++
++gchar**
++g_strsplit (const gchar *string,
++ const gchar *delimiter,
++ gint max_tokens)
++{
++ GSList *string_list = NULL, *slist;
++ gchar **str_array, *s;
++ guint i, n = 1;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (delimiter != NULL, NULL);
++
++ if (max_tokens < 1)
++ max_tokens = G_MAXINT;
++
++ s = strstr (string, delimiter);
++ if (s)
++ {
++ guint delimiter_len = strlen (delimiter);
++
++ do
++ {
++ guint len;
++ gchar *new_string;
++
++ len = s - string;
++ new_string = g_new (gchar, len + 1);
++ strncpy (new_string, string, len);
++ new_string[len] = 0;
++ string_list = g_slist_prepend (string_list, new_string);
++ n++;
++ string = s + delimiter_len;
++ s = strstr (string, delimiter);
++ }
++ while (--max_tokens && s);
++ }
++ if (*string)
++ {
++ n++;
++ string_list = g_slist_prepend (string_list, g_strdup (string));
++ }
++
++ str_array = g_new (gchar*, n);
++
++ i = n - 1;
++
++ str_array[i--] = NULL;
++ for (slist = string_list; slist; slist = slist->next)
++ str_array[i--] = slist->data;
++
++ g_slist_free (string_list);
++
++ return str_array;
++}
++
++void
++g_strfreev (gchar **str_array)
++{
++ if (str_array)
++ {
++ int i;
++
++ for(i = 0; str_array[i] != NULL; i++)
++ g_free(str_array[i]);
++
++ g_free (str_array);
++ }
++}
++
++gchar*
++g_strjoinv (const gchar *separator,
++ gchar **str_array)
++{
++ gchar *string;
++
++ g_return_val_if_fail (str_array != NULL, NULL);
++
++ if (separator == NULL)
++ separator = "";
++
++ if (*str_array)
++ {
++ guint i, len;
++ guint separator_len;
++
++ separator_len = strlen (separator);
++ len = 1 + strlen (str_array[0]);
++ for(i = 1; str_array[i] != NULL; i++)
++ len += separator_len + strlen(str_array[i]);
++
++ string = g_new (gchar, len);
++ *string = 0;
++ strcat (string, *str_array);
++ for (i = 1; str_array[i] != NULL; i++)
++ {
++ strcat (string, separator);
++ strcat (string, str_array[i]);
++ }
++ }
++ else
++ string = g_strdup ("");
++
++ return string;
++}
++
++gchar*
++g_strjoin (const gchar *separator,
++ ...)
++{
++ gchar *string, *s;
++ va_list args;
++ guint len;
++ guint separator_len;
++
++ if (separator == NULL)
++ separator = "";
++
++ separator_len = strlen (separator);
++
++ va_start (args, separator);
++
++ s = va_arg (args, gchar*);
++
++ if (s)
++ {
++ len = strlen (s);
++
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ len += separator_len + strlen (s);
++ s = va_arg (args, gchar*);
++ }
++ va_end (args);
++
++ string = g_new (gchar, len + 1);
++ *string = 0;
++
++ va_start (args, separator);
++
++ s = va_arg (args, gchar*);
++ strcat (string, s);
++
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ strcat (string, separator);
++ strcat (string, s);
++ s = va_arg (args, gchar*);
++ }
++ }
++ else
++ string = g_strdup ("");
++
++ va_end (args);
++
++ return string;
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gstring.c linux-2.4.1-korbit/net/korbit/kglib/gstring.c
+--- linux-2.4.1/net/korbit/kglib/gstring.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gstring.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,508 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include <stdarg.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <ctype.h>
++#include "glib.h"
++
++
++typedef struct _GRealStringChunk GRealStringChunk;
++typedef struct _GRealString GRealString;
++
++struct _GRealStringChunk
++{
++ GHashTable *const_table;
++ GSList *storage_list;
++ gint storage_next;
++ gint this_size;
++ gint default_size;
++};
++
++struct _GRealString
++{
++ gchar *str;
++ gint len;
++ gint alloc;
++};
++
++G_LOCK_DEFINE_STATIC (string_mem_chunk);
++static GMemChunk *string_mem_chunk = NULL;
++
++/* Hash Functions.
++ */
++
++gint
++g_str_equal (gconstpointer v, gconstpointer v2)
++{
++ return strcmp ((const gchar*) v, (const gchar*)v2) == 0;
++}
++
++/* 31 bit hash function */
++guint
++g_str_hash (gconstpointer key)
++{
++ const char *p = key;
++ guint h = *p;
++
++ if (h)
++ for (p += 1; *p != '\0'; p++)
++ h = (h << 5) - h + *p;
++
++ return h;
++}
++
++/* String Chunks.
++ */
++
++GStringChunk*
++g_string_chunk_new (gint default_size)
++{
++ GRealStringChunk *new_chunk = g_new (GRealStringChunk, 1);
++ gint size = 1;
++
++ while (size < default_size)
++ size <<= 1;
++
++ new_chunk->const_table = NULL;
++ new_chunk->storage_list = NULL;
++ new_chunk->storage_next = size;
++ new_chunk->default_size = size;
++ new_chunk->this_size = size;
++
++ return (GStringChunk*) new_chunk;
++}
++
++void
++g_string_chunk_free (GStringChunk *fchunk)
++{
++ GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
++ GSList *tmp_list;
++
++ g_return_if_fail (chunk != NULL);
++
++ if (chunk->storage_list)
++ {
++ for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
++ g_free (tmp_list->data);
++
++ g_slist_free (chunk->storage_list);
++ }
++
++ if (chunk->const_table)
++ g_hash_table_destroy (chunk->const_table);
++
++ g_free (chunk);
++}
++
++gchar*
++g_string_chunk_insert (GStringChunk *fchunk,
++ const gchar *string)
++{
++ GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
++ gint len = strlen (string);
++ char* pos;
++
++ g_return_val_if_fail (chunk != NULL, NULL);
++
++ if ((chunk->storage_next + len + 1) > chunk->this_size)
++ {
++ gint new_size = chunk->default_size;
++
++ while (new_size < len+1)
++ new_size <<= 1;
++
++ chunk->storage_list = g_slist_prepend (chunk->storage_list,
++ g_new (char, new_size));
++
++ chunk->this_size = new_size;
++ chunk->storage_next = 0;
++ }
++
++ pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
++
++ strcpy (pos, string);
++
++ chunk->storage_next += len + 1;
++
++ return pos;
++}
++
++gchar*
++g_string_chunk_insert_const (GStringChunk *fchunk,
++ const gchar *string)
++{
++ GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
++ char* lookup;
++
++ g_return_val_if_fail (chunk != NULL, NULL);
++
++ if (!chunk->const_table)
++ chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
++
++ lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
++
++ if (!lookup)
++ {
++ lookup = g_string_chunk_insert (fchunk, string);
++ g_hash_table_insert (chunk->const_table, lookup, lookup);
++ }
++
++ return lookup;
++}
++
++/* Strings.
++ */
++static gint
++nearest_pow (gint num)
++{
++ gint n = 1;
++
++ while (n < num)
++ n <<= 1;
++
++ return n;
++}
++
++static void
++g_string_maybe_expand (GRealString* string, gint len)
++{
++ if (string->len + len >= string->alloc)
++ {
++ string->alloc = nearest_pow (string->len + len + 1);
++ string->str = g_realloc (string->str, string->alloc);
++ }
++}
++
++GString*
++g_string_sized_new (guint dfl_size)
++{
++ GRealString *string;
++
++ G_LOCK (string_mem_chunk);
++ if (!string_mem_chunk)
++ string_mem_chunk = g_mem_chunk_new ("string mem chunk",
++ sizeof (GRealString),
++ 1024, G_ALLOC_AND_FREE);
++
++ string = g_chunk_new (GRealString, string_mem_chunk);
++ G_UNLOCK (string_mem_chunk);
++
++ string->alloc = 0;
++ string->len = 0;
++ string->str = NULL;
++
++ g_string_maybe_expand (string, MAX (dfl_size, 2));
++ string->str[0] = 0;
++
++ return (GString*) string;
++}
++
++GString*
++g_string_new (const gchar *init)
++{
++ GString *string;
++
++ string = g_string_sized_new (2);
++
++ if (init)
++ g_string_append (string, init);
++
++ return string;
++}
++
++void
++g_string_free (GString *string,
++ gint free_segment)
++{
++ g_return_if_fail (string != NULL);
++
++ if (free_segment)
++ g_free (string->str);
++
++ G_LOCK (string_mem_chunk);
++ g_mem_chunk_free (string_mem_chunk, string);
++ G_UNLOCK (string_mem_chunk);
++}
++
++GString*
++g_string_assign (GString *lval,
++ const gchar *rval)
++{
++ g_return_val_if_fail (lval != NULL, NULL);
++ g_return_val_if_fail (rval != NULL, NULL);
++
++ g_string_truncate (lval, 0);
++ g_string_append (lval, rval);
++
++ return lval;
++}
++
++GString*
++g_string_truncate (GString* fstring,
++ gint len)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (len >= 0, NULL);
++
++ string->len = len;
++
++ string->str[len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_append (GString *fstring,
++ const gchar *val)
++{
++ GRealString *string = (GRealString*)fstring;
++ int len;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (val != NULL, fstring);
++
++ len = strlen (val);
++ g_string_maybe_expand (string, len);
++
++ strcpy (string->str + string->len, val);
++
++ string->len += len;
++
++ return fstring;
++}
++
++GString*
++g_string_append_c (GString *fstring,
++ gchar c)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_string_maybe_expand (string, 1);
++
++ string->str[string->len++] = c;
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_prepend (GString *fstring,
++ const gchar *val)
++{
++ GRealString *string = (GRealString*)fstring;
++ gint len;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (val != NULL, fstring);
++
++ len = strlen (val);
++ g_string_maybe_expand (string, len);
++
++ g_memmove (string->str + len, string->str, string->len);
++
++ strncpy (string->str, val, len);
++
++ string->len += len;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_prepend_c (GString *fstring,
++ gchar c)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_string_maybe_expand (string, 1);
++
++ g_memmove (string->str + 1, string->str, string->len);
++
++ string->str[0] = c;
++
++ string->len += 1;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_insert (GString *fstring,
++ gint pos,
++ const gchar *val)
++{
++ GRealString *string = (GRealString*)fstring;
++ gint len;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (val != NULL, fstring);
++ g_return_val_if_fail (pos >= 0, fstring);
++ g_return_val_if_fail (pos <= string->len, fstring);
++
++ len = strlen (val);
++ g_string_maybe_expand (string, len);
++
++ g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
++
++ strncpy (string->str + pos, val, len);
++
++ string->len += len;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString *
++g_string_insert_c (GString *fstring,
++ gint pos,
++ gchar c)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (pos <= string->len, fstring);
++
++ g_string_maybe_expand (string, 1);
++
++ g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
++
++ string->str[pos] = c;
++
++ string->len += 1;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_erase (GString *fstring,
++ gint pos,
++ gint len)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (len >= 0, fstring);
++ g_return_val_if_fail (pos >= 0, fstring);
++ g_return_val_if_fail (pos <= string->len, fstring);
++ g_return_val_if_fail (pos + len <= string->len, fstring);
++
++ if (pos + len < string->len)
++ g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
++
++ string->len -= len;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_down (GString *fstring)
++{
++ GRealString *string = (GRealString*)fstring;
++ guchar *s;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ s = string->str;
++
++ while (*s)
++ {
++ *s = tolower (*s);
++ s++;
++ }
++
++ return fstring;
++}
++
++GString*
++g_string_up (GString *fstring)
++{
++ GRealString *string = (GRealString*)fstring;
++ guchar *s;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ s = string->str;
++
++ while (*s)
++ {
++ *s = toupper (*s);
++ s++;
++ }
++
++ return fstring;
++}
++
++static void
++g_string_sprintfa_int (GString *string,
++ const gchar *fmt,
++ va_list args)
++{
++ gchar *buffer;
++
++ buffer = g_strdup_vprintf (fmt, args);
++ g_string_append (string, buffer);
++ g_free (buffer);
++}
++
++void
++g_string_sprintf (GString *string,
++ const gchar *fmt,
++ ...)
++{
++ va_list args;
++
++ g_string_truncate (string, 0);
++
++ va_start (args, fmt);
++ g_string_sprintfa_int (string, fmt, args);
++ va_end (args);
++}
++
++void
++g_string_sprintfa (GString *string,
++ const gchar *fmt,
++ ...)
++{
++ va_list args;
++
++ va_start (args, fmt);
++ g_string_sprintfa_int (string, fmt, args);
++ va_end (args);
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gtree.c linux-2.4.1-korbit/net/korbit/kglib/gtree.c
+--- linux-2.4.1/net/korbit/kglib/gtree.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gtree.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,740 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++typedef struct _GRealTree GRealTree;
++typedef struct _GTreeNode GTreeNode;
++
++struct _GRealTree
++{
++ GTreeNode *root;
++ GCompareFunc key_compare;
++};
++
++struct _GTreeNode
++{
++ gint balance; /* height (left) - height (right) */
++ GTreeNode *left; /* left subtree */
++ GTreeNode *right; /* right subtree */
++ gpointer key; /* key for this node */
++ gpointer value; /* value stored at this node */
++};
++
++
++static GTreeNode* g_tree_node_new (gpointer key,
++ gpointer value);
++static void g_tree_node_destroy (GTreeNode *node);
++static GTreeNode* g_tree_node_insert (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key,
++ gpointer value,
++ gint *inserted);
++static GTreeNode* g_tree_node_remove (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key);
++static GTreeNode* g_tree_node_balance (GTreeNode *node);
++static GTreeNode* g_tree_node_remove_leftmost (GTreeNode *node,
++ GTreeNode **leftmost);
++static GTreeNode* g_tree_node_restore_left_balance (GTreeNode *node,
++ gint old_balance);
++static GTreeNode* g_tree_node_restore_right_balance (GTreeNode *node,
++ gint old_balance);
++static gpointer g_tree_node_lookup (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key);
++static gint g_tree_node_count (GTreeNode *node);
++static gint g_tree_node_pre_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data);
++static gint g_tree_node_in_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data);
++static gint g_tree_node_post_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data);
++static gpointer g_tree_node_search (GTreeNode *node,
++ GSearchFunc search_func,
++ gpointer data);
++static gint g_tree_node_height (GTreeNode *node);
++static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
++static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
++static void g_tree_node_check (GTreeNode *node);
++
++
++G_LOCK_DEFINE_STATIC (g_tree_global);
++static GMemChunk *node_mem_chunk = NULL;
++static GTreeNode *node_free_list = NULL;
++
++
++static GTreeNode*
++g_tree_node_new (gpointer key,
++ gpointer value)
++{
++ GTreeNode *node;
++
++ G_LOCK (g_tree_global);
++ if (node_free_list)
++ {
++ node = node_free_list;
++ node_free_list = node->right;
++ }
++ else
++ {
++ if (!node_mem_chunk)
++ node_mem_chunk = g_mem_chunk_new ("GLib GTreeNode mem chunk",
++ sizeof (GTreeNode),
++ 1024,
++ G_ALLOC_ONLY);
++
++ node = g_chunk_new (GTreeNode, node_mem_chunk);
++ }
++ G_UNLOCK (g_tree_global);
++
++ node->balance = 0;
++ node->left = NULL;
++ node->right = NULL;
++ node->key = key;
++ node->value = value;
++
++ return node;
++}
++
++static void
++g_tree_node_destroy (GTreeNode *node)
++{
++ if (node)
++ {
++ g_tree_node_destroy (node->right);
++ g_tree_node_destroy (node->left);
++ G_LOCK (g_tree_global);
++ node->right = node_free_list;
++ node_free_list = node;
++ G_UNLOCK (g_tree_global);
++ }
++}
++
++
++GTree*
++g_tree_new (GCompareFunc key_compare_func)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (key_compare_func != NULL, NULL);
++
++ rtree = g_new (GRealTree, 1);
++ rtree->root = NULL;
++ rtree->key_compare = key_compare_func;
++
++ return (GTree*) rtree;
++}
++
++void
++g_tree_destroy (GTree *tree)
++{
++ GRealTree *rtree;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ g_tree_node_destroy (rtree->root);
++ g_free (rtree);
++}
++
++void
++g_tree_insert (GTree *tree,
++ gpointer key,
++ gpointer value)
++{
++ GRealTree *rtree;
++ gint inserted;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ inserted = FALSE;
++ rtree->root = g_tree_node_insert (rtree->root, rtree->key_compare,
++ key, value, &inserted);
++}
++
++void
++g_tree_remove (GTree *tree,
++ gpointer key)
++{
++ GRealTree *rtree;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ rtree->root = g_tree_node_remove (rtree->root, rtree->key_compare, key);
++}
++
++gpointer
++g_tree_lookup (GTree *tree,
++ gpointer key)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, NULL);
++
++ rtree = (GRealTree*) tree;
++
++ return g_tree_node_lookup (rtree->root, rtree->key_compare, key);
++}
++
++void
++g_tree_traverse (GTree *tree,
++ GTraverseFunc traverse_func,
++ GTraverseType traverse_type,
++ gpointer data)
++{
++ GRealTree *rtree;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ if (!rtree->root)
++ return;
++
++ switch (traverse_type)
++ {
++ case G_PRE_ORDER:
++ g_tree_node_pre_order (rtree->root, traverse_func, data);
++ break;
++
++ case G_IN_ORDER:
++ g_tree_node_in_order (rtree->root, traverse_func, data);
++ break;
++
++ case G_POST_ORDER:
++ g_tree_node_post_order (rtree->root, traverse_func, data);
++ break;
++
++ case G_LEVEL_ORDER:
++ g_warning ("g_tree_traverse(): traverse type G_LEVEL_ORDER isn't implemented.");
++ break;
++ }
++}
++
++gpointer
++g_tree_search (GTree *tree,
++ GSearchFunc search_func,
++ gpointer data)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, NULL);
++
++ rtree = (GRealTree*) tree;
++
++ if (rtree->root)
++ return g_tree_node_search (rtree->root, search_func, data);
++ else
++ return NULL;
++}
++
++gint
++g_tree_height (GTree *tree)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, 0);
++
++ rtree = (GRealTree*) tree;
++
++ if (rtree->root)
++ return g_tree_node_height (rtree->root);
++ else
++ return 0;
++}
++
++gint
++g_tree_nnodes (GTree *tree)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, 0);
++
++ rtree = (GRealTree*) tree;
++
++ if (rtree->root)
++ return g_tree_node_count (rtree->root);
++ else
++ return 0;
++}
++
++static GTreeNode*
++g_tree_node_insert (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key,
++ gpointer value,
++ gint *inserted)
++{
++ gint old_balance;
++ gint cmp;
++
++ if (!node)
++ {
++ *inserted = TRUE;
++ return g_tree_node_new (key, value);
++ }
++
++ cmp = (* compare) (key, node->key);
++ if (cmp == 0)
++ {
++ *inserted = FALSE;
++ node->value = value;
++ return node;
++ }
++
++ if (cmp < 0)
++ {
++ if (node->left)
++ {
++ old_balance = node->left->balance;
++ node->left = g_tree_node_insert (node->left, compare, key, value, inserted);
++
++ if ((old_balance != node->left->balance) && node->left->balance)
++ node->balance -= 1;
++ }
++ else
++ {
++ *inserted = TRUE;
++ node->left = g_tree_node_new (key, value);
++ node->balance -= 1;
++ }
++ }
++ else if (cmp > 0)
++ {
++ if (node->right)
++ {
++ old_balance = node->right->balance;
++ node->right = g_tree_node_insert (node->right, compare, key, value, inserted);
++
++ if ((old_balance != node->right->balance) && node->right->balance)
++ node->balance += 1;
++ }
++ else
++ {
++ *inserted = TRUE;
++ node->right = g_tree_node_new (key, value);
++ node->balance += 1;
++ }
++ }
++
++ if (*inserted)
++ {
++ if ((node->balance < -1) || (node->balance > 1))
++ node = g_tree_node_balance (node);
++ }
++
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_remove (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key)
++{
++ GTreeNode *new_root;
++ gint old_balance;
++ gint cmp;
++
++ if (!node)
++ return NULL;
++
++ cmp = (* compare) (key, node->key);
++ if (cmp == 0)
++ {
++ GTreeNode *garbage;
++
++ garbage = node;
++
++ if (!node->right)
++ {
++ node = node->left;
++ }
++ else
++ {
++ old_balance = node->right->balance;
++ node->right = g_tree_node_remove_leftmost (node->right, &new_root);
++ new_root->left = node->left;
++ new_root->right = node->right;
++ new_root->balance = node->balance;
++ node = g_tree_node_restore_right_balance (new_root, old_balance);
++ }
++
++ G_LOCK (g_tree_global);
++ garbage->right = node_free_list;
++ node_free_list = garbage;
++ G_UNLOCK (g_tree_global);
++ }
++ else if (cmp < 0)
++ {
++ if (node->left)
++ {
++ old_balance = node->left->balance;
++ node->left = g_tree_node_remove (node->left, compare, key);
++ node = g_tree_node_restore_left_balance (node, old_balance);
++ }
++ }
++ else if (cmp > 0)
++ {
++ if (node->right)
++ {
++ old_balance = node->right->balance;
++ node->right = g_tree_node_remove (node->right, compare, key);
++ node = g_tree_node_restore_right_balance (node, old_balance);
++ }
++ }
++
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_balance (GTreeNode *node)
++{
++ if (node->balance < -1)
++ {
++ if (node->left->balance > 0)
++ node->left = g_tree_node_rotate_left (node->left);
++ node = g_tree_node_rotate_right (node);
++ }
++ else if (node->balance > 1)
++ {
++ if (node->right->balance < 0)
++ node->right = g_tree_node_rotate_right (node->right);
++ node = g_tree_node_rotate_left (node);
++ }
++
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_remove_leftmost (GTreeNode *node,
++ GTreeNode **leftmost)
++{
++ gint old_balance;
++
++ if (!node->left)
++ {
++ *leftmost = node;
++ return node->right;
++ }
++
++ old_balance = node->left->balance;
++ node->left = g_tree_node_remove_leftmost (node->left, leftmost);
++ return g_tree_node_restore_left_balance (node, old_balance);
++}
++
++static GTreeNode*
++g_tree_node_restore_left_balance (GTreeNode *node,
++ gint old_balance)
++{
++ if (!node->left)
++ node->balance += 1;
++ else if ((node->left->balance != old_balance) &&
++ (node->left->balance == 0))
++ node->balance += 1;
++
++ if (node->balance > 1)
++ return g_tree_node_balance (node);
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_restore_right_balance (GTreeNode *node,
++ gint old_balance)
++{
++ if (!node->right)
++ node->balance -= 1;
++ else if ((node->right->balance != old_balance) &&
++ (node->right->balance == 0))
++ node->balance -= 1;
++
++ if (node->balance < -1)
++ return g_tree_node_balance (node);
++ return node;
++}
++
++static gpointer
++g_tree_node_lookup (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key)
++{
++ gint cmp;
++
++ if (!node)
++ return NULL;
++
++ cmp = (* compare) (key, node->key);
++ if (cmp == 0)
++ return node->value;
++
++ if (cmp < 0)
++ {
++ if (node->left)
++ return g_tree_node_lookup (node->left, compare, key);
++ }
++ else if (cmp > 0)
++ {
++ if (node->right)
++ return g_tree_node_lookup (node->right, compare, key);
++ }
++
++ return NULL;
++}
++
++static gint
++g_tree_node_count (GTreeNode *node)
++{
++ gint count;
++
++ count = 1;
++ if (node->left)
++ count += g_tree_node_count (node->left);
++ if (node->right)
++ count += g_tree_node_count (node->right);
++
++ return count;
++}
++
++static gint
++g_tree_node_pre_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data)
++{
++ if ((*traverse_func) (node->key, node->value, data))
++ return TRUE;
++ if (node->left)
++ {
++ if (g_tree_node_pre_order (node->left, traverse_func, data))
++ return TRUE;
++ }
++ if (node->right)
++ {
++ if (g_tree_node_pre_order (node->right, traverse_func, data))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static gint
++g_tree_node_in_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data)
++{
++ if (node->left)
++ {
++ if (g_tree_node_in_order (node->left, traverse_func, data))
++ return TRUE;
++ }
++ if ((*traverse_func) (node->key, node->value, data))
++ return TRUE;
++ if (node->right)
++ {
++ if (g_tree_node_in_order (node->right, traverse_func, data))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static gint
++g_tree_node_post_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data)
++{
++ if (node->left)
++ {
++ if (g_tree_node_post_order (node->left, traverse_func, data))
++ return TRUE;
++ }
++ if (node->right)
++ {
++ if (g_tree_node_post_order (node->right, traverse_func, data))
++ return TRUE;
++ }
++ if ((*traverse_func) (node->key, node->value, data))
++ return TRUE;
++
++ return FALSE;
++}
++
++static gpointer
++g_tree_node_search (GTreeNode *node,
++ GSearchFunc search_func,
++ gpointer data)
++{
++ gint dir;
++
++ if (!node)
++ return NULL;
++
++ do {
++ dir = (* search_func) (node->key, data);
++ if (dir == 0)
++ return node->value;
++
++ if (dir < 0)
++ node = node->left;
++ else if (dir > 0)
++ node = node->right;
++ } while (node && (dir != 0));
++
++ return NULL;
++}
++
++static gint
++g_tree_node_height (GTreeNode *node)
++{
++ gint left_height;
++ gint right_height;
++
++ if (node)
++ {
++ left_height = 0;
++ right_height = 0;
++
++ if (node->left)
++ left_height = g_tree_node_height (node->left);
++
++ if (node->right)
++ right_height = g_tree_node_height (node->right);
++
++ return MAX (left_height, right_height) + 1;
++ }
++
++ return 0;
++}
++
++static GTreeNode*
++g_tree_node_rotate_left (GTreeNode *node)
++{
++ GTreeNode *left;
++ GTreeNode *right;
++ gint a_bal;
++ gint b_bal;
++
++ left = node->left;
++ right = node->right;
++
++ node->right = right->left;
++ right->left = node;
++
++ a_bal = node->balance;
++ b_bal = right->balance;
++
++ if (b_bal <= 0)
++ {
++ if (a_bal >= 1)
++ right->balance = b_bal - 1;
++ else
++ right->balance = a_bal + b_bal - 2;
++ node->balance = a_bal - 1;
++ }
++ else
++ {
++ if (a_bal <= b_bal)
++ right->balance = a_bal - 2;
++ else
++ right->balance = b_bal - 1;
++ node->balance = a_bal - b_bal - 1;
++ }
++
++ return right;
++}
++
++static GTreeNode*
++g_tree_node_rotate_right (GTreeNode *node)
++{
++ GTreeNode *left;
++ gint a_bal;
++ gint b_bal;
++
++ left = node->left;
++
++ node->left = left->right;
++ left->right = node;
++
++ a_bal = node->balance;
++ b_bal = left->balance;
++
++ if (b_bal <= 0)
++ {
++ if (b_bal > a_bal)
++ left->balance = b_bal + 1;
++ else
++ left->balance = a_bal + 2;
++ node->balance = a_bal - b_bal + 1;
++ }
++ else
++ {
++ if (a_bal <= -1)
++ left->balance = b_bal + 1;
++ else
++ left->balance = a_bal + b_bal + 2;
++ node->balance = a_bal + 1;
++ }
++
++ return left;
++}
++
++static void
++g_tree_node_check (GTreeNode *node)
++{
++ gint left_height;
++ gint right_height;
++ gint balance;
++
++ if (node)
++ {
++ left_height = 0;
++ right_height = 0;
++
++ if (node->left)
++ left_height = g_tree_node_height (node->left);
++ if (node->right)
++ right_height = g_tree_node_height (node->right);
++
++ balance = right_height - left_height;
++ if (balance != node->balance)
++ g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
++ "g_tree_node_check: failed: %d ( %d )\n",
++ balance, node->balance);
++
++ if (node->left)
++ g_tree_node_check (node->left);
++ if (node->right)
++ g_tree_node_check (node->right);
++ }
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gutils.c linux-2.4.1-korbit/net/korbit/kglib/gutils.c
+--- linux-2.4.1/net/korbit/kglib/gutils.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gutils.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,915 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#define G_INLINE_FUNC extern
++#define G_CAN_INLINE 1
++
++#ifdef HAVE_UNISTD_H
++#include <unistd.h>
++#endif
++#include <stdarg.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#ifdef HAVE_PWD_H
++#include <pwd.h>
++#endif
++#include <sys/types.h>
++#ifdef HAVE_SYS_PARAM_H
++#include <sys/param.h>
++#endif
++
++#ifdef NATIVE_WIN32
++# define STRICT /* Strict typing, please */
++# include <windows.h>
++# include <direct.h>
++# include <errno.h>
++# include <ctype.h>
++# ifdef _MSC_VER
++# include <io.h>
++# endif /* _MSC_VER */
++#endif /* NATIVE_WIN32 */
++
++/* implement Glib's inline functions
++ */
++#include "glib.h"
++
++#ifdef MAXPATHLEN
++#define G_PATH_LENGTH (MAXPATHLEN + 1)
++#elif defined (PATH_MAX)
++#define G_PATH_LENGTH (PATH_MAX + 1)
++#else /* !MAXPATHLEN */
++#define G_PATH_LENGTH (2048 + 1)
++#endif /* !MAXPATHLEN && !PATH_MAX */
++
++const guint glib_major_version = 1;
++const guint glib_minor_version = 2;
++const guint glib_micro_version = 8;
++const guint glib_interface_age = 8;
++const guint glib_binary_age = 8;
++
++#if defined (NATIVE_WIN32) && defined (__LCC__)
++int __stdcall
++LibMain (void *hinstDll,
++ unsigned long dwReason,
++ void *reserved)
++{
++ return 1;
++}
++#endif /* NATIVE_WIN32 && __LCC__ */
++
++void
++g_atexit (GVoidFunc func)
++{
++ gint result;
++ gchar *error = NULL;
++
++ /* keep this in sync with glib.h */
++
++#ifdef G_NATIVE_ATEXIT
++ result = ATEXIT (func);
++ if (result)
++ error = g_strerror (errno);
++#elif defined (HAVE_ATEXIT)
++# ifdef NeXT /* @#%@! NeXTStep */
++ result = !atexit ((void (*)(void)) func);
++ if (result)
++ error = g_strerror (errno);
++# else
++ result = atexit ((void (*)(void)) func);
++ if (result)
++ error = g_strerror (errno);
++# endif /* NeXT */
++#elif defined (HAVE_ON_EXIT)
++ result = on_exit ((void (*)(int, void *)) func, NULL);
++ if (result)
++ error = g_strerror (errno);
++#else
++ result = 0;
++ error = "no implementation";
++#endif /* G_NATIVE_ATEXIT */
++
++ if (error)
++ g_error ("Could not register atexit() function: %s", error);
++}
++
++gint
++g_snprintf (gchar *str,
++ gulong n,
++ gchar const *fmt,
++ ...)
++{
++#ifdef HAVE_VSNPRINTF
++ va_list args;
++ gint retval;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ va_start (args, fmt);
++ retval = vsnprintf (str, n, fmt, args);
++ va_end (args);
++
++ if (retval < 0)
++ {
++ str[n-1] = '\0';
++ retval = strlen (str);
++ }
++
++ return retval;
++#else /* !HAVE_VSNPRINTF */
++ gchar *printed;
++ va_list args;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ va_start (args, fmt);
++ printed = g_strdup_vprintf (fmt, args);
++ va_end (args);
++
++ strncpy (str, printed, n);
++ str[n-1] = '\0';
++
++ g_free (printed);
++
++ return strlen (str);
++#endif /* !HAVE_VSNPRINTF */
++}
++
++gint
++g_vsnprintf (gchar *str,
++ gulong n,
++ gchar const *fmt,
++ va_list args)
++{
++#ifdef HAVE_VSNPRINTF
++ gint retval;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ retval = vsnprintf (str, n, fmt, args);
++
++ if (retval < 0)
++ {
++ str[n-1] = '\0';
++ retval = strlen (str);
++ }
++
++ return retval;
++#else /* !HAVE_VSNPRINTF */
++ gchar *printed;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ printed = g_strdup_vprintf (fmt, args);
++ strncpy (str, printed, n);
++ str[n-1] = '\0';
++
++ g_free (printed);
++
++ return strlen (str);
++#endif /* !HAVE_VSNPRINTF */
++}
++
++guint
++g_parse_debug_string (const gchar *string,
++ GDebugKey *keys,
++ guint nkeys)
++{
++ guint i;
++ guint result = 0;
++
++ g_return_val_if_fail (string != NULL, 0);
++
++ if (!g_strcasecmp (string, "all"))
++ {
++ for (i=0; i<nkeys; i++)
++ result |= keys[i].value;
++ }
++ else
++ {
++ gchar *str = g_strdup (string);
++ gchar *p = str;
++ gchar *q;
++ gboolean done = FALSE;
++
++ while (*p && !done)
++ {
++ q = strchr (p, ':');
++ if (!q)
++ {
++ q = p + strlen(p);
++ done = TRUE;
++ }
++
++ *q = 0;
++
++ for (i=0; i<nkeys; i++)
++ if (!g_strcasecmp(keys[i].key, p))
++ result |= keys[i].value;
++
++ p = q+1;
++ }
++
++ g_free (str);
++ }
++
++ return result;
++}
++
++gchar*
++g_basename (const gchar *file_name)
++{
++ register gchar *base;
++
++ g_return_val_if_fail (file_name != NULL, NULL);
++
++ base = strrchr (file_name, G_DIR_SEPARATOR);
++ if (base)
++ return base + 1;
++
++#ifdef NATIVE_WIN32
++ if (isalpha (file_name[0]) && file_name[1] == ':')
++ return (gchar*) file_name + 2;
++#endif /* NATIVE_WIN32 */
++
++ return (gchar*) file_name;
++}
++
++gboolean
++g_path_is_absolute (const gchar *file_name)
++{
++ g_return_val_if_fail (file_name != NULL, FALSE);
++
++ if (file_name[0] == G_DIR_SEPARATOR)
++ return TRUE;
++
++#ifdef NATIVE_WIN32
++ if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
++ return TRUE;
++#endif
++
++ return FALSE;
++}
++
++gchar*
++g_path_skip_root (gchar *file_name)
++{
++ g_return_val_if_fail (file_name != NULL, NULL);
++
++ if (file_name[0] == G_DIR_SEPARATOR)
++ return file_name + 1;
++
++#ifdef NATIVE_WIN32
++ if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
++ return file_name + 3;
++#endif
++
++ return NULL;
++}
++
++gchar*
++g_dirname (const gchar *file_name)
++{
++ register gchar *base;
++ register guint len;
++
++ g_return_val_if_fail (file_name != NULL, NULL);
++
++ base = strrchr (file_name, G_DIR_SEPARATOR);
++ if (!base)
++ return g_strdup (".");
++ while (base > file_name && *base == G_DIR_SEPARATOR)
++ base--;
++ len = (guint) 1 + base - file_name;
++
++ base = g_new (gchar, len + 1);
++ g_memmove (base, file_name, len);
++ base[len] = 0;
++
++ return base;
++}
++
++#ifndef __KORBIT__
++gchar*
++g_get_current_dir (void)
++{
++ gchar *buffer;
++ gchar *dir;
++
++ buffer = g_new (gchar, G_PATH_LENGTH);
++ *buffer = 0;
++
++ /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
++ * and, if that wasn't bad enough, hangs in doing so.
++ */
++#if defined (sun) && !defined (__SVR4)
++ dir = getwd (buffer);
++#else /* !sun */
++ dir = getcwd (buffer, G_PATH_LENGTH - 1);
++#endif /* !sun */
++
++ if (!dir || !*buffer)
++ {
++ /* hm, should we g_error() out here?
++ * this can happen if e.g. "./" has mode \0000
++ */
++ buffer[0] = G_DIR_SEPARATOR;
++ buffer[1] = 0;
++ }
++
++ dir = g_strdup (buffer);
++ g_free (buffer);
++
++ return dir;
++}
++#endif /* !__KORBIT__ */
++
++gchar*
++g_getenv (const gchar *variable)
++{
++#ifndef NATIVE_WIN32
++ g_return_val_if_fail (variable != NULL, NULL);
++
++ return getenv (variable);
++#else
++ gchar *v;
++ guint k;
++ static gchar *p = NULL;
++ static gint l;
++ gchar dummy[2];
++
++ g_return_val_if_fail (variable != NULL, NULL);
++
++ v = getenv (variable);
++ if (!v)
++ return NULL;
++
++ /* On Windows NT, it is relatively typical that environment variables
++ * contain references to other environment variables. Handle that by
++ * calling ExpandEnvironmentStrings.
++ */
++
++ /* First check how much space we need */
++ k = ExpandEnvironmentStrings (v, dummy, 2);
++ /* Then allocate that much, and actualy do the expansion */
++ if (p == NULL)
++ {
++ p = g_malloc (k);
++ l = k;
++ }
++ else if (k > l)
++ {
++ p = g_realloc (p, k);
++ l = k;
++ }
++ ExpandEnvironmentStrings (v, p, k);
++ return p;
++#endif
++}
++
++
++G_LOCK_DEFINE_STATIC (g_utils_global);
++
++static gchar *g_tmp_dir = NULL;
++static gchar *g_user_name = NULL;
++static gchar *g_real_name = NULL;
++static gchar *g_home_dir = NULL;
++
++/* HOLDS: g_utils_global_lock */
++static void
++g_get_any_init (void)
++{
++ if (!g_tmp_dir)
++ {
++ g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
++ if (!g_tmp_dir)
++ g_tmp_dir = g_strdup (g_getenv ("TMP"));
++ if (!g_tmp_dir)
++ g_tmp_dir = g_strdup (g_getenv ("TEMP"));
++
++#ifdef P_tmpdir
++ if (!g_tmp_dir)
++ {
++ int k;
++ g_tmp_dir = g_strdup (P_tmpdir);
++ k = strlen (g_tmp_dir);
++ if (g_tmp_dir[k-1] == G_DIR_SEPARATOR)
++ g_tmp_dir[k-1] = '\0';
++ }
++#endif
++
++ if (!g_tmp_dir)
++ {
++#ifndef NATIVE_WIN32
++ g_tmp_dir = g_strdup ("/tmp");
++#else /* NATIVE_WIN32 */
++ g_tmp_dir = g_strdup ("C:\\");
++#endif /* NATIVE_WIN32 */
++ }
++
++ if (!g_home_dir)
++ g_home_dir = g_strdup (g_getenv ("HOME"));
++
++#ifdef NATIVE_WIN32
++ if (!g_home_dir)
++ {
++ /* The official way to specify a home directory on NT is
++ * the HOMEDRIVE and HOMEPATH environment variables.
++ *
++ * This is inside #ifdef NATIVE_WIN32 because with the cygwin dll,
++ * HOME should be a POSIX style pathname.
++ */
++
++ if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
++ {
++ gchar *homedrive, *homepath;
++
++ homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
++ homepath = g_strdup (g_getenv ("HOMEPATH"));
++
++ g_home_dir = g_strconcat (homedrive, homepath, NULL);
++ g_free (homedrive);
++ g_free (homepath);
++ }
++ }
++#endif /* !NATIVE_WIN32 */
++
++#ifdef HAVE_PWD_H
++ {
++ struct passwd *pw = NULL;
++ gpointer buffer = NULL;
++
++# ifdef HAVE_GETPWUID_R
++ struct passwd pwd;
++ guint bufsize = 64;
++ gint error;
++
++ do
++ {
++ g_free (buffer);
++ buffer = g_malloc (bufsize);
++ errno = 0;
++
++# ifdef HAVE_GETPWUID_R_POSIX
++ error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
++ error = error < 0 ? errno : error;
++# else /* !HAVE_GETPWUID_R_POSIX */
++# ifdef _AIX
++ error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
++ pw = error == 0 ? &pwd : NULL;
++# else /* !_AIX */
++ pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
++ error = pw ? 0 : errno;
++# endif /* !_AIX */
++# endif /* !HAVE_GETPWUID_R_POSIX */
++
++ if (!pw)
++ {
++ /* we bail out prematurely if the user id can't be found
++ * (should be pretty rare case actually), or if the buffer
++ * should be sufficiently big and lookups are still not
++ * successfull.
++ */
++ if (error == 0 || error == ENOENT)
++ {
++ g_warning ("getpwuid_r(): failed due to: No such user %d.",
++ getuid ());
++ break;
++ }
++ if (bufsize > 32 * 1024)
++ {
++ g_warning ("getpwuid_r(): failed due to: %s.",
++ g_strerror (error));
++ break;
++ }
++
++ bufsize *= 2;
++ }
++ }
++ while (!pw);
++# endif /* !HAVE_GETPWUID_R */
++
++ if (!pw)
++ {
++ setpwent ();
++ pw = getpwuid (getuid ());
++ endpwent ();
++ }
++ if (pw)
++ {
++ g_user_name = g_strdup (pw->pw_name);
++ g_real_name = g_strdup (pw->pw_gecos);
++ if (!g_home_dir)
++ g_home_dir = g_strdup (pw->pw_dir);
++ }
++ g_free (buffer);
++ }
++
++#else /* !HAVE_PWD_H */
++
++# ifdef NATIVE_WIN32
++ {
++ guint len = 17;
++ gchar buffer[17];
++
++ if (GetUserName (buffer, &len))
++ {
++ g_user_name = g_strdup (buffer);
++ g_real_name = g_strdup (buffer);
++ }
++ }
++# endif /* NATIVE_WIN32 */
++
++#endif /* !HAVE_PWD_H */
++
++ if (!g_user_name)
++ g_user_name = g_strdup ("somebody");
++ if (!g_real_name)
++ g_real_name = g_strdup ("Unknown");
++ else
++ {
++ gchar *p;
++
++ for (p = g_real_name; *p; p++)
++ if (*p == ',')
++ {
++ *p = 0;
++ p = g_strdup (g_real_name);
++ g_free (g_real_name);
++ g_real_name = p;
++ break;
++ }
++ }
++ }
++}
++
++gchar*
++g_get_user_name (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_user_name;
++}
++
++gchar*
++g_get_real_name (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_real_name;
++}
++
++/* Return the home directory of the user. If there is a HOME
++ * environment variable, its value is returned, otherwise use some
++ * system-dependent way of finding it out. If no home directory can be
++ * deduced, return NULL.
++ */
++
++gchar*
++g_get_home_dir (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_home_dir;
++}
++
++/* Return a directory to be used to store temporary files. This is the
++ * value of the TMPDIR, TMP or TEMP environment variables (they are
++ * checked in that order). If none of those exist, use P_tmpdir from
++ * stdio.h. If that isn't defined, return "/tmp" on POSIXly systems,
++ * and C:\ on Windows.
++ */
++
++gchar*
++g_get_tmp_dir (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_tmp_dir;
++}
++
++static gchar *g_prgname = NULL;
++
++gchar*
++g_get_prgname (void)
++{
++ gchar* retval;
++
++ G_LOCK (g_utils_global);
++ retval = g_prgname;
++ G_UNLOCK (g_utils_global);
++
++ return retval;
++}
++
++void
++g_set_prgname (const gchar *prgname)
++{
++ gchar *c;
++
++ G_LOCK (g_utils_global);
++ c = g_prgname;
++ g_prgname = g_strdup (prgname);
++ g_free (c);
++ G_UNLOCK (g_utils_global);
++}
++
++guint
++g_direct_hash (gconstpointer v)
++{
++ return GPOINTER_TO_UINT (v);
++}
++
++gint
++g_direct_equal (gconstpointer v1,
++ gconstpointer v2)
++{
++ return v1 == v2;
++}
++
++gint
++g_int_equal (gconstpointer v1,
++ gconstpointer v2)
++{
++ return *((const gint*) v1) == *((const gint*) v2);
++}
++
++guint
++g_int_hash (gconstpointer v)
++{
++ return *(const gint*) v;
++}
++
++#if 0 /* Old IO Channels */
++
++GIOChannel*
++g_iochannel_new (gint fd)
++{
++ GIOChannel *channel = g_new (GIOChannel, 1);
++
++ channel->fd = fd;
++
++#ifdef NATIVE_WIN32
++ channel->peer = 0;
++ channel->peer_fd = 0;
++ channel->offset = 0;
++ channel->need_wakeups = 0;
++#endif /* NATIVE_WIN32 */
++
++ return channel;
++}
++
++void
++g_iochannel_free (GIOChannel *channel)
++{
++ g_return_if_fail (channel != NULL);
++
++ g_free (channel);
++}
++
++void
++g_iochannel_close_and_free (GIOChannel *channel)
++{
++ g_return_if_fail (channel != NULL);
++
++ close (channel->fd);
++
++ g_iochannel_free (channel);
++}
++
++#undef g_iochannel_wakeup_peer
++
++void
++g_iochannel_wakeup_peer (GIOChannel *channel)
++{
++#ifdef NATIVE_WIN32
++ static guint message = 0;
++#endif
++
++ g_return_if_fail (channel != NULL);
++
++#ifdef NATIVE_WIN32
++ if (message == 0)
++ message = RegisterWindowMessage ("gdk-pipe-readable");
++
++# if 0
++ g_print ("g_iochannel_wakeup_peer: calling PostThreadMessage (%#x, %d, %d, %d)\n",
++ channel->peer, message, channel->peer_fd, channel->offset);
++# endif
++ PostThreadMessage (channel->peer, message,
++ channel->peer_fd, channel->offset);
++#endif /* NATIVE_WIN32 */
++}
++
++#endif /* Old IO Channels */
++
++#ifdef NATIVE_WIN32
++#ifdef _MSC_VER
++
++int
++gwin_ftruncate (gint fd,
++ guint size)
++{
++ HANDLE hfile;
++ guint curpos;
++
++ g_return_val_if_fail (fd >= 0, -1);
++
++ hfile = (HANDLE) _get_osfhandle (fd);
++ curpos = SetFilePointer (hfile, 0, NULL, FILE_CURRENT);
++ if (curpos == 0xFFFFFFFF
++ || SetFilePointer (hfile, size, NULL, FILE_BEGIN) == 0xFFFFFFFF
++ || !SetEndOfFile (hfile))
++ {
++ gint error = GetLastError ();
++
++ switch (error)
++ {
++ case ERROR_INVALID_HANDLE:
++ errno = EBADF;
++ break;
++ default:
++ errno = EIO;
++ break;
++ }
++
++ return -1;
++ }
++
++ return 0;
++}
++
++DIR*
++gwin_opendir (const char *dirname)
++{
++ DIR *result;
++ gchar *mask;
++ guint k;
++
++ g_return_val_if_fail (dirname != NULL, NULL);
++
++ result = g_new0 (DIR, 1);
++ result->find_file_data = g_new0 (WIN32_FIND_DATA, 1);
++ result->dir_name = g_strdup (dirname);
++
++ k = strlen (result->dir_name);
++ if (k && result->dir_name[k - 1] == '\\')
++ {
++ result->dir_name[k - 1] = '\0';
++ k--;
++ }
++ mask = g_strdup_printf ("%s\\*", result->dir_name);
++
++ result->find_file_handle = (guint) FindFirstFile (mask,
++ (LPWIN32_FIND_DATA) result->find_file_data);
++ g_free (mask);
++
++ if (result->find_file_handle == (guint) INVALID_HANDLE_VALUE)
++ {
++ int error = GetLastError ();
++
++ g_free (result->dir_name);
++ g_free (result->find_file_data);
++ g_free (result);
++ switch (error)
++ {
++ default:
++ errno = EIO;
++ return NULL;
++ }
++ }
++ result->just_opened = TRUE;
++
++ return result;
++}
++
++struct dirent*
++gwin_readdir (DIR *dir)
++{
++ static struct dirent result;
++
++ g_return_val_if_fail (dir != NULL, NULL);
++
++ if (dir->just_opened)
++ dir->just_opened = FALSE;
++ else
++ {
++ if (!FindNextFile ((HANDLE) dir->find_file_handle,
++ (LPWIN32_FIND_DATA) dir->find_file_data))
++ {
++ int error = GetLastError ();
++
++ switch (error)
++ {
++ case ERROR_NO_MORE_FILES:
++ return NULL;
++ default:
++ errno = EIO;
++ return NULL;
++ }
++ }
++ }
++ strcpy (result.d_name, g_basename (((LPWIN32_FIND_DATA) dir->find_file_data)->cFileName));
++
++ return &result;
++}
++
++void
++gwin_rewinddir (DIR *dir)
++{
++ gchar *mask;
++
++ g_return_if_fail (dir != NULL);
++
++ if (!FindClose ((HANDLE) dir->find_file_handle))
++ g_warning ("gwin_rewinddir(): FindClose() failed\n");
++
++ mask = g_strdup_printf ("%s\\*", dir->dir_name);
++ dir->find_file_handle = (guint) FindFirstFile (mask,
++ (LPWIN32_FIND_DATA) dir->find_file_data);
++ g_free (mask);
++
++ if (dir->find_file_handle == (guint) INVALID_HANDLE_VALUE)
++ {
++ int error = GetLastError ();
++
++ switch (error)
++ {
++ default:
++ errno = EIO;
++ return;
++ }
++ }
++ dir->just_opened = TRUE;
++}
++
++gint
++gwin_closedir (DIR *dir)
++{
++ g_return_val_if_fail (dir != NULL, -1);
++
++ if (!FindClose ((HANDLE) dir->find_file_handle))
++ {
++ int error = GetLastError ();
++
++ switch (error)
++ {
++ default:
++ errno = EIO; return -1;
++ }
++ }
++
++ g_free (dir->dir_name);
++ g_free (dir->find_file_data);
++ g_free (dir);
++
++ return 0;
++}
++
++#endif /* _MSC_VER */
++
++#endif /* NATIVE_WIN32 */
+diff -urN linux-2.4.1/net/korbit/kglib/korbit_errno.c linux-2.4.1-korbit/net/korbit/kglib/korbit_errno.c
+--- linux-2.4.1/net/korbit/kglib/korbit_errno.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/korbit_errno.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1 @@
++int korbit_errno;
+diff -urN linux-2.4.1/net/korbit/korbit.h linux-2.4.1-korbit/net/korbit/korbit.h
+--- linux-2.4.1/net/korbit/korbit.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/korbit.h Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,53 @@
++
++#ifndef KORBIT_H
++#define KORBIT_H
++
++#ifdef __KERNEL__
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#endif
++
++#include "stdlib.h"
++
++#ifdef __KERNEL__
++static int korbit_get_ior_func(char *buffer, char **start, off_t offset,
++ int length, int *eof, void *data) {
++ int Len = strlen((char*)data);
++ memcpy(buffer, data, Len); // Data is the ior...
++ buffer[Len++] = '\n'; // Add a newline to make fredrik happy
++ buffer[Len] = 0; // Null terminate the buffer...
++ *start = buffer + offset;
++ *eof = 1;
++
++ Len -= offset;
++ if (Len > length)
++ Len = length;
++ if (Len < 0)
++ Len = 0;
++
++ return Len;
++}
++
++#endif
++
++
++static inline void korbit_register_ior(const char *name, CORBA_Object obj,
++ CORBA_ORB orb, CORBA_Environment *ev) {
++ char *retval = CORBA_ORB_object_to_string(orb, obj, ev);
++#if defined(__KERNEL__) && defined(CONFIG_PROC_FS)
++ char *procdirname = malloc(strlen(name)+7); // 7 = len("corba/\0")
++ strcpy(procdirname, "corba/");
++ strcpy(procdirname+6, name);
++
++ create_proc_read_entry(procdirname, 0, 0, korbit_get_ior_func, retval);
++
++ free(procdirname);
++ // Don't free the ior in the /proc handling case...
++#else
++ // No procfs support, just print to console... :(
++ g_print("%s IOR:\n%s\n", name, retval);
++ CORBA_free(retval);
++#endif
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Entries Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,5 @@
++/Config.in/1.8/Thu Feb 1 09:46:58 2001//
++/Makefile/1.8/Thu Feb 1 09:46:58 2001//
++/Makefile.module/1.2/Thu Feb 1 09:46:58 2001//
++/README/1.1/Thu Feb 1 09:46:58 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Entries.Log Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,6 @@
++A D/CharDev////
++A D/Console////
++A D/CorbaFS////
++A D/Echo////
++A D/FileServer////
++A D/UserFS////
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Repository Thu Feb 1 11:46:57 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Root Thu Feb 1 11:46:57 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.3/Thu Feb 1 09:46:58 2001//
++/README/1.1/Thu Feb 1 09:46:58 2001//
++/chardev.idl/1.1/Thu Feb 1 09:46:58 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries.Log Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,3 @@
++A D/kernel////
++A D/kernel-perl////
++A D/userspace////
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Repository Thu Feb 1 11:46:58 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Root Thu Feb 1 11:46:58 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/Makefile linux-2.4.1-korbit/net/korbit/modules/CharDev/Makefile
+--- linux-2.4.1/net/korbit/modules/CharDev/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/Makefile Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit - CharDev
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CHARDEV) := kernel
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/README linux-2.4.1-korbit/net/korbit/modules/CharDev/README
+--- linux-2.4.1/net/korbit/modules/CharDev/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/README Thu Feb 1 11:46:58 2001
+@@ -0,0 +1 @@
++This module is used to implement a character device with kORBit.
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/chardev.idl linux-2.4.1-korbit/net/korbit/modules/CharDev/chardev.idl
+--- linux-2.4.1/net/korbit/modules/CharDev/chardev.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/chardev.idl Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,5 @@
++typedef sequence<octet> Buffer;
++
++interface CharDev {
++ long read(out Buffer buffer, in long size);
++};
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Entries Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.2/Thu Feb 1 09:46:59 2001//
++/README/1.2/Thu Feb 1 09:46:59 2001//
++/chardev-kernel.c/1.9/Thu Feb 1 09:46:59 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Repository Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev/kernel
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Root Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/Makefile linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/Makefile
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/Makefile Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit / chardev
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-chardev-kernel.o
++
++obj-y := chardev-common.o chardev-stubs.o chardev-kernel.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++chardev-kernel.c: chardev.h
++
++chardev.h chardev-stubs.c chardev-common.c: ../chardev.idl
++ $(ORBIT_IDL) ../chardev.idl
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/README linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/README
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/README Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,5 @@
++This module is used to implement the kernel side of the CORBA Character
++device.
++
++ORB: kORBit
++Status: Working!!!
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/chardev-kernel.c linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/chardev-kernel.c
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/chardev-kernel.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/chardev-kernel.c Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,140 @@
++//-----------------------------------------------------------------------------
++//
++// chardev-kernel - Kernel miscdevice to CORBA glue.
++//
++// This file implements a standard Linux Kernel "miscdevice". This device
++// operates by forwarding all calls across to a remote CORBA server. This
++// server is located by reading the file /tmp/chardev-ior at the time the
++// device is opened. The device exported is major #10, minor #42. Create this
++// device with 'mknod' like all the others.
++//
++// No implementations of CORBA functions should block, although I think it
++// might be just fine, I'm not sure. Let's just make this a TODO. :) -CAL
++//
++// TODO: Locking, finish exporting all "miscdevice" functions, send position
++// on READ request.
++//
++// History:
++// Keith Wessel - Initial hack, initial idea
++// Andy Reitz - Get it to compile
++// Chris Lattner - Make it work. :)
++//
++//-----------------------------------------------------------------------------
++
++
++#include "chardev.h"
++#include <stdio.h>
++#include "orb/orbit.h"
++#include "korbit.h"
++#include <linux/miscdevice.h>
++
++#define DEV_MINOR 42
++
++CORBA_ORB orb;
++CORBA_Environment *ev;
++
++static int open_dev(struct inode *inode, struct file *file) {
++ char *iorstr = (char *)malloc(10240);
++ int error = -EINVAL;
++ int fd, len;
++
++ if (iorstr == 0) return -ENOMEM;
++
++ if ((fd = open ("/tmp/chardev-ior", O_RDONLY, 0)) == -1) {
++ printk("kORBit: chararacter driver couldn't open /tmp/chardev-ior!\n");
++ goto outfree;
++ }
++
++ len = read(fd, iorstr, 10240);
++ close(fd);
++ if (len == -1)
++ goto outfree;
++
++ iorstr[len] = 0; // Null terminate string!
++
++ printk("CharDEV IOR String = %s\n", iorstr);
++ file->private_data = (void*)CORBA_ORB_string_to_object(orb, iorstr, ev);
++ if (!file->private_data)
++ goto outfree;
++
++ // TODO: Send create_dev message out over CORBA
++
++ error = 0;
++ outfree:
++ free(iorstr);
++ return error;
++}
++
++static int release_dev(struct inode *inode, struct file *file) {
++ // TODO: Send release_dev message out over CORBA...
++ if (file->private_data)
++ CORBA_free(file->private_data);
++ return 0;
++}
++
++
++static ssize_t read_dev(struct file * file, char * buf, size_t count,
++ loff_t *ppos) {
++ Buffer *octet_buffer = NULL;
++ if (!file->private_data) return -EINVAL;
++ if (!count) return 0;
++
++ if (!access_ok(VERIFY_WRITE, buf, count))
++ return -EFAULT;
++
++ CharDev_read(file->private_data, &octet_buffer, count, ev);
++
++ if (!octet_buffer)
++ return -EPERM;
++
++ if (copy_to_user(buf, octet_buffer->_buffer, octet_buffer->_length))
++ return -EFAULT;
++
++ // TODO: Should free octet_buffer here!?!?!?
++
++ return octet_buffer->_length;
++}
++
++
++//-----------------------------------------------------------------------------
++// Kernel Callbacks for miscdevice
++//-----------------------------------------------------------------------------
++
++
++static struct file_operations dev_fops = {
++ owner: THIS_MODULE,
++ open: open_dev,
++ read: read_dev,
++ release: release_dev,
++ // mmap: mmap_dev,
++ // llseek: llseek_dev,
++ // write: write_dev,
++};
++
++static struct miscdevice cdev = {
++ DEV_MINOR,
++ "CORBA Character device",
++ &dev_fops
++};
++
++
++//-----------------------------------------------------------------------------
++// Module Initializion/Finalization
++//-----------------------------------------------------------------------------
++
++static int __init CharDev_init(void) {
++ int argc = 1;
++ char *argv[] = { "CharDev-kernel", 0 };
++ ev = g_new0(CORBA_Environment,1);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++
++ // Register the device
++ return misc_register(&cdev);
++}
++
++static void __exit CharDev_exit(void) {
++ misc_deregister(&cdev);
++}
++
++module_init(CharDev_init)
++module_exit(CharDev_exit)
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Entries Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,3 @@
++/PerlTest/1.1/Thu Feb 1 09:46:59 2001//
++/README/1.1/Thu Feb 1 09:46:59 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Repository Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev/kernel-perl
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Root Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/PerlTest linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/PerlTest
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/PerlTest Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/PerlTest Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,17 @@
++#!/usr/bin/perl -w
++
++use CORBA::ORBit idl => [ qw(../chardev.idl) ];
++use Error qw(:try);
++use strict;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++open IOR, "/tmp/chardev-ior" or die "no chardev server found!";
++my $ior = <IOR>;
++close IOR;
++#chomp($ior); # Kill fredrik's newline...
++
++my $chardev = $orb->string_to_object($ior);
++# Echo echoString(in string astring, out long anum);
++my ($ressize, $buf) = $chardev->read(10);
++
++print "Return size = $ressize\nresult = $buf\n";
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/README linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/README
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/README Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,6 @@
++This module is used to test the user side of the CORBA Character
++device. It doesn't do anything really complex, just implements a quick
++sanity test for the server.
++
++ORB: ORBit - Perl
++Status: Working!
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Entries Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,6 @@
++/Makefile/1.5/Thu Feb 1 09:47:00 2001//
++/README/1.1/Thu Feb 1 09:47:00 2001//
++/RunServer.sh/1.1/Thu Feb 1 09:47:00 2001//
++/chardev-server.c/1.5/Thu Feb 1 09:47:00 2001//
++/chardev-skelimpl.c/1.5/Thu Feb 1 09:47:00 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Repository Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev/userspace
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Root Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/Makefile linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/Makefile
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/Makefile Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,30 @@
++#
++# Makefile for KORBit / CharDev
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++CFLAGS = -Wall -I/usr/lib/glib/include
++LDFLAGS = -lORBit -lIIOP -lORBitutil
++OBJS = chardev-common.o chardev-skels.o chardev-server.o
++ORBIT-IDL = /usr/bin/orbit-idl
++
++chardev-server: $(OBJS)
++ gcc -o chardev-server $(OBJS) $(LDFLAGS)
++
++chardev-server.o: chardev.h chardev-skelimpl.c
++
++chardev.h chardev-skels.c chardev-common.c: ../chardev.idl
++ $(ORBIT-IDL) ../chardev.idl
++
++chardev-skelimpl.c:
++
++%.o: %.c
++ gcc -c $< $(CFLAGS)
++clean:
++ rm -f $(OBJS) chardev-server chardev-common.c chardev-skels.c \
++ chardev-stubs.c chardev.h
++
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/README linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/README
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/README Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,4 @@
++This is an example character driver.
++
++ORB: ORBit
++Status: not yet working
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/RunServer.sh linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/RunServer.sh
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/RunServer.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/RunServer.sh Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++./chardev-server -ORBIIOPUSock=0 -ORBIIOPIPv4=1
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-server.c linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-server.c
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-server.c Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,77 @@
++//-----------------------------------------------------------------------------
++//
++// chardev-server.c - TEST Kernel miscdevice implementation
++//
++// This file implements the standard server code for a userspace server. This
++// is basically cut and paste boilerplate code adapted from the CorbaFS server
++// by Fredrik Vraalsen.
++//
++// TODO: Locking, finish exporting all "miscdevice" functions, send position
++// on READ request.
++//
++// History:
++// Keith Wessel - Initial hack, initial idea
++// Andy Reitz - Get it to compile
++// Chris Lattner - Hack'n'slash, make it work, comment it, kill warnings.
++//
++//-----------------------------------------------------------------------------
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <signal.h>
++#include <orb/orbit.h>
++
++// #include the C file because all the functions are static. Bizarre.
++#include "chardev-skelimpl.c"
++
++int main(int argc, char *argv[]) {
++ PortableServer_POA poa;
++ PortableServer_POAManager pm;
++
++ CharDev chardev = CORBA_OBJECT_NIL;
++ impl_POA_CharDev *chardev_impl;
++ PortableServer_ObjectId *objid;
++
++ CORBA_Environment ev;
++ char *retval;
++ CORBA_ORB orb;
++ FILE *IORFILE;
++
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++ poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
++
++ chardev = impl_CharDev__create(poa, &ev);
++ pm = PortableServer_POA__get_the_POAManager(poa, &ev);
++ PortableServer_POAManager_activate(pm, &ev);
++
++ if (!chardev) {
++ printf("Cannot get objref\n");
++ return 1;
++ }
++
++ chardev_impl = PortableServer_POA_reference_to_servant(poa, chardev, &ev);
++ objid = PortableServer_POA_servant_to_id(poa, chardev_impl, &ev);
++
++ retval = CORBA_ORB_object_to_string(orb, chardev, &ev);
++
++ g_print("FYI, this also goes into /tmp/chardev-ior for you.\n");
++ g_print("%s\n", retval); fflush(stdout);
++
++ IORFILE = fopen ("/tmp/chardev-ior", "w");
++ if (IORFILE == NULL) {
++ perror("ERROR: IOR_WRITE_TO_DISK");
++ exit(1);
++ }
++
++ fprintf(IORFILE, "%s", retval);
++ fclose(IORFILE);
++
++ CORBA_free(retval); // Free the corba string like a good little CORBear
++
++
++ // La dee dah... I will never return for you mister.
++ CORBA_ORB_run(orb, &ev);
++ return 0;
++}
++
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,119 @@
++//-----------------------------------------------------------------------------
++//
++// chardev-skelimpl.c - TEST Kernel miscdevice implementation
++//
++// This file implements a CORBA "miscdevice" (character device node).
++// This device simply outputs a fixed string (set by "message", below) when
++// cat'd. Pretty simple stuff, but you can obviously do much more creative
++// things with it.
++//
++// TODO: Locking, finish exporting all "miscdevice" functions, send position
++// on READ request.
++//
++// Right now we have ONE server object with global state, so that when you
++// read the string from that object, it is finished. This should be reset
++// whenever an open request is had or when the file position is reset (duh).
++//
++// History:
++// Keith Wessel - Initial hack, initial idea
++// Andy Reitz - Get it to compile
++// Chris Lattner - Make it work, comment it, no warnings.
++//
++//-----------------------------------------------------------------------------
++
++#include "chardev.h"
++
++// The message to spit out.
++const char *message = "Hello world!\nI love kORBit\n";
++
++
++/*** App-specific servant structures ***/
++
++typedef struct
++{
++ POA_CharDev servant;
++ PortableServer_POA poa;
++ int AmountRead;
++
++}
++impl_POA_CharDev;
++
++/*** Implementation stub prototypes ***/
++
++static inline void impl_CharDev__destroy(impl_POA_CharDev * servant,
++ CORBA_Environment * ev);
++static CORBA_long
++impl_CharDev_read(impl_POA_CharDev * servant,
++ Buffer ** buffer, CORBA_long size, CORBA_Environment * ev);
++
++/*** epv structures ***/
++
++static PortableServer_ServantBase__epv impl_CharDev_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_CharDev__epv impl_CharDev_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_CharDev_read,
++
++};
++
++/*** vepv structures ***/
++
++static POA_CharDev__vepv impl_CharDev_vepv = {
++ &impl_CharDev_base_epv,
++ &impl_CharDev_epv,
++};
++
++/*** Stub implementations ***/
++
++static CharDev
++impl_CharDev__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ CharDev retval;
++ impl_POA_CharDev *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_CharDev, 1);
++ newservant->servant.vepv = &impl_CharDev_vepv;
++ newservant->poa = poa;
++ newservant->AmountRead = 0; // Initialize chardev stuff...
++
++ POA_CharDev__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static inline void
++impl_CharDev__destroy(impl_POA_CharDev * servant, CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_CharDev__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static CORBA_long
++impl_CharDev_read(impl_POA_CharDev * servant,
++ Buffer ** buffer, CORBA_long ReqSize, CORBA_Environment * ev)
++{
++ int AvailSize = strlen(message)-servant->AmountRead;
++ CORBA_long retval = (ReqSize > AvailSize) ? AvailSize : ReqSize;
++
++ *buffer = Buffer__alloc();
++ (*buffer)->_buffer = CORBA_octet_allocbuf(retval);
++ (*buffer)->_length = retval;
++
++ strncpy((*buffer)->_buffer, message + servant->AmountRead, retval);
++ servant->AmountRead += retval;
++ return retval;
++}
++
+diff -urN linux-2.4.1/net/korbit/modules/Config.in linux-2.4.1-korbit/net/korbit/modules/Config.in
+--- linux-2.4.1/net/korbit/modules/Config.in Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Config.in Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,11 @@
++# Console server
++#
++dep_tristate ' CORBA Console Server (EXPERIMENTAL)' CONFIG_CORBA_CONSOLE $CONFIG_KORBIT
++
++dep_tristate ' CORBA Echo Server (EXPERIMENTAL)' CONFIG_CORBA_ECHO $CONFIG_KORBIT
++
++dep_tristate ' CORBA FileSystem Access (EXPERIMENTAL)' CONFIG_CORBA_FILESERVER $CONFIG_KORBIT
++
++dep_tristate ' CORBA User-space FileSystem (EXPERIMENTAL)' CONFIG_CORBA_CORBAFS $CONFIG_KORBIT
++
++dep_tristate ' CORBA Character Device Interface (EXPERIMENTAL)' CONFIG_CORBA_CHARDEV $CONFIG_KORBIT
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.2/Thu Feb 1 09:47:00 2001//
++/README/1.1/Thu Feb 1 09:47:00 2001//
++/console.idl/1.1/Thu Feb 1 09:47:00 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries.Log Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,3 @@
++A D/PerlClient////
++A D/client////
++A D/server////
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Repository Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Root Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/Makefile linux-2.4.1-korbit/net/korbit/modules/Console/Makefile
+--- linux-2.4.1/net/korbit/modules/Console/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/Makefile Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit/modules/Console
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CONSOLE) := server
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Entries Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,3 @@
++/Client/1.1/Thu Feb 1 09:47:01 2001//
++/README/1.1/Thu Feb 1 09:47:01 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Repository Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console/PerlClient
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Root Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/Client linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/Client
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/Client Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/Client Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,14 @@
++#!/usr/bin/perl -w
++
++use CORBA::ORBit idl => [ qw(../console.idl) ];
++use Error qw(:try);
++use strict;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++open IOR, "/proc/corba/console-server" or die "no console server found!";
++my $ior = <IOR>;
++close IOR;
++chomp($ior); # Kill fredrik's newline...
++
++my $console = $orb->string_to_object($ior);
++$console->print("Hello Strange World");
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/README linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/README
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/README Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,3 @@
++This is a perl client for the Console server.
++
++ORB: ORBit
+diff -urN linux-2.4.1/net/korbit/modules/Console/README linux-2.4.1-korbit/net/korbit/modules/Console/README
+--- linux-2.4.1/net/korbit/modules/Console/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/README Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++The "hello world" testcase. This is used to write a string to the linux console.
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Entries Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.2/Thu Feb 1 09:47:01 2001//
++/README/1.1/Thu Feb 1 09:47:01 2001//
++/console-client.c/1.1/Thu Feb 1 09:47:01 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Repository Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console/client
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Root Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/Makefile linux-2.4.1-korbit/net/korbit/modules/Console/client/Makefile
+--- linux-2.4.1/net/korbit/modules/Console/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/Makefile Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = console
++
++CFLAGS = -Wall `orbit-config --cflags client` -I../../..
++LDFLAGS = `orbit-config --libs client`
++OBJS = $(PROJECT)-common.o $(PROJECT)-stubs.o $(PROJECT)-client.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-client: $(OBJS)
++ gcc -o $(PROJECT)-client $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-client.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-stubs.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --noskels ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-client
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-stubs.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/README linux-2.4.1-korbit/net/korbit/modules/Console/client/README
+--- linux-2.4.1/net/korbit/modules/Console/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/README Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,3 @@
++C Client to access console server.
++
++ORB: ORBit
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/console-client.c linux-2.4.1-korbit/net/korbit/modules/Console/client/console-client.c
+--- linux-2.4.1/net/korbit/modules/Console/client/console-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/console-client.c Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,63 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <orb/orbit.h>
++
++#include "console.h"
++
++Console console_client;
++
++int
++main (int argc, char *argv[])
++{
++ CORBA_Environment ev;
++ CORBA_ORB orb;
++ char *Message = "Hey dood, nice hair";
++ int i;
++
++ int niters = 10;
++
++ CORBA_exception_init(&ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++
++#if 0
++ for(i = 0; i < (sizeof(theblah) - 1); i++)
++ theblah[i] = 'a';
++ theblah[sizeof(theblah) - 1] = '\0';
++#endif
++
++ if(argc < 2)
++ {
++ printf("Need a binding ID thing as argv[1]\n");
++ return 1;
++ }
++
++ if(argc >= 3)
++ niters = atoi(argv[2]);
++
++ if (argc >= 4)
++ Message = argv[3];
++
++ console_client = CORBA_ORB_string_to_object(orb, argv[1], &ev);
++ if (!console_client) {
++ printf("Cannot bind to %s\n", argv[1]);
++ return 1;
++ }
++
++ printf("corba = %d, console = %d, foobar = %d\n",
++ CORBA_Object_is_a(console_client, "IDL:CORBA/Object:1.0", &ev),
++ CORBA_Object_is_a(console_client, "IDL:Empty:1.0", &ev),
++ CORBA_Object_is_a(console_client, "IDL:Foo/Bar:1.0", &ev));
++
++ for(i = 0; i < niters; i++) {
++ Console_print(console_client, Message, &ev);
++ if(ev._major != CORBA_NO_EXCEPTION) {
++ printf("we got exception %d from doNothing!\n", ev._major);
++ return 1;
++ }
++ }
++
++ CORBA_Object_release(console_client, &ev);
++ CORBA_Object_release((CORBA_Object)orb, &ev);
++
++ return 0;
++}
+diff -urN linux-2.4.1/net/korbit/modules/Console/console.idl linux-2.4.1-korbit/net/korbit/modules/Console/console.idl
+--- linux-2.4.1/net/korbit/modules/Console/console.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/console.idl Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,3 @@
++interface Console {
++ void print(in string TheString);
++};
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Entries Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,5 @@
++/Makefile/1.7/Thu Feb 1 09:47:02 2001//
++/Makefile.user/1.1/Thu Feb 1 09:47:02 2001//
++/README/1.1/Thu Feb 1 09:47:02 2001//
++/console-server.c/1.7/Thu Feb 1 09:47:02 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Repository Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console/server
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Root Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/Makefile linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile
+--- linux-2.4.1/net/korbit/modules/Console/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,21 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-cons-server.o
++
++obj-y := console-server.o console-skels.o console-common.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++console-server.c: console.h console-common.c console-skels.c
++
++
++console.h console-skels.c: ../console.idl
++ $(ORBIT_IDL) ../console.idl
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/Makefile.user linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile.user
+--- linux-2.4.1/net/korbit/modules/Console/server/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile.user Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = console
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/README linux-2.4.1-korbit/net/korbit/modules/Console/server/README
+--- linux-2.4.1/net/korbit/modules/Console/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/README Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++Kernel module to implement Console server.
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/console-server.c linux-2.4.1-korbit/net/korbit/modules/Console/server/console-server.c
+--- linux-2.4.1/net/korbit/modules/Console/server/console-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/console-server.c Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,85 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <signal.h>
++#include <orb/orbit.h>
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include "console.h"
++#include "glib.h"
++#include "korbit.h"
++
++Console console_client = CORBA_OBJECT_NIL;
++
++static void corba_console_print(PortableServer_Servant _servant,
++ CORBA_char *TheString,
++ CORBA_Environment *ev);
++
++PortableServer_ServantBase__epv base_epv = {
++ NULL,
++ NULL,
++ NULL
++};
++POA_Console__epv console_epv = { NULL, corba_console_print };
++POA_Console__vepv poa_console_vepv = { &base_epv, &console_epv };
++POA_Console poa_console_servant = { NULL, &poa_console_vepv };
++
++// MAke this global so that I can unregister the module...
++PortableServer_ObjectId objid = {0, sizeof("myFoo"), "myFoo"};
++CORBA_Environment *ev;
++PortableServer_POA poa;
++
++#ifdef __KERNEL__
++int __init corba_console_init(void)
++#else
++int main(int argc, char *argv[])
++#endif
++{
++#ifdef __KERNEL__
++ int argc = 1; char *argv[] = { "server", 0 };
++#endif
++ CORBA_ORB orb;
++
++ ev = g_new0(CORBA_Environment, 1);
++ CORBA_exception_init(ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++
++ poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
++ PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, ev), ev);
++
++ POA_Console__init(&poa_console_servant, ev);
++
++ PortableServer_POA_activate_object_with_id(poa,
++ &objid, &poa_console_servant, ev);
++
++ console_client =
++ PortableServer_POA_servant_to_reference(poa, &poa_console_servant, ev);
++ if (!console_client) {
++ printf("Cannot get objref\n");
++ return 1;
++ }
++
++ korbit_register_ior("console-server", console_client, orb, ev);
++
++ CORBA_ORB_run(orb, ev);
++
++ return 0;
++}
++
++#ifdef __KERNEL__
++void corba_console_exit(void) {
++ PortableServer_POA_deactivate_object(poa, &objid, ev);
++ remove_proc_entry("corba/console-server", 0);
++}
++
++module_init(corba_console_init)
++module_exit(corba_console_exit)
++#endif
++
++static void corba_console_print(PortableServer_Servant _servant,
++ CORBA_char *TheString,
++ CORBA_Environment *ev) {
++ printf("Yo. Dood. You said: '%s'!\n", TheString);
++}
++
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,4 @@
++/CorbaFS.idl/1.7/Thu Feb 1 09:47:02 2001//
++/Makefile/1.4/Thu Feb 1 09:47:02 2001//
++/README/1.2/Thu Feb 1 09:47:02 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries.Log Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,3 @@
++A D/client////
++A D/server////
++A D/server-perl////
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Repository Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Root Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CorbaFS.idl linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CorbaFS.idl
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CorbaFS.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CorbaFS.idl Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,38 @@
++// -----------------------------------------------------------------------------
++// CorbaDS Module - Implement Kernel functionality in Korba
++// -----------------------------------------------------------------------------
++//
++// Main source of information:
++// http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html
++//
++module CorbaFS {
++
++ struct dirent
++ {
++ long inode; // inode number
++ string name; // file name (null-terminated)
++ };
++
++ typedef sequence<dirent> DirEntSeq;
++ typedef sequence<octet> Buffer;
++
++ interface Inode {
++ void getStatus(out unsigned short mode, out unsigned long uid, out unsigned long gid,
++ out unsigned long size, out unsigned long inodeNum, out unsigned short numLinks,
++ out long atime, out long mtime, out long ctime);
++ void readpage(out Buffer buffer, in long size, in long offset);
++ void release();
++ };
++
++ interface FileSystem {
++ Inode getInode(in string path);
++
++ // DirectoryInode getStatus implementation must have S_IFDIR in the S_IFMT
++ // field of the mode value.
++ DirEntSeq readdir(in string path);
++
++ // SymlinkInode getStatus implementation must have S_IFLNK in the S_IFMT
++ // field of the mode value.
++ string readlink(in string filename);
++ };
++};
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/Makefile linux-2.4.1-korbit/net/korbit/modules/CorbaFS/Makefile
+--- linux-2.4.1/net/korbit/modules/CorbaFS/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/Makefile Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit - CorbaFS
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CORBAFS) := client
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/README Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,14 @@
++This interface is used to implement linux FileSystems in CORBA.
++
++Status: Working for readonly filesystems. Write capability is a todo.
++
++This lets you do all kinds of interesting things (just like the user level
++filesystem proposals would let you do):
++ server/ implements NFS like capability of just exporting an existing FS
++ TODO: webfs, ftpfs, cvsfs, mysqlfs...
++
++Usage:
++ insmod corba-corbafs.o
++ mount -t corbafs -o IOR:... none /mnt/corbafs
++
++Where the IOR comes from a filesystem server that you run somewhere...
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Entries Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,6 @@
++/CorbaFS-client.c/1.9/Thu Feb 1 09:47:03 2001//
++/CorbaFS-user-client.c/1.3/Thu Feb 1 09:47:03 2001//
++/Makefile/1.4/Thu Feb 1 09:47:03 2001//
++/Makefile.user/1.1/Thu Feb 1 09:47:03 2001//
++/README/1.1/Thu Feb 1 09:47:03 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Repository Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS/client
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Root Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-client.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-client.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-client.c Fri Feb 2 02:20:21 2001
+@@ -0,0 +1,469 @@
++/*
++ * corbafs - Interface glue between native linux VFS layer and CORBA
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/pagemap.h>
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/locks.h>
++#include <linux/dirent.h>
++#include <linux/module.h>
++
++#include <asm/uaccess.h>
++#include "CorbaFS.h"
++
++/* some random number */
++#define CORBAFS_MAGIC 0xC02BAF5
++
++// CORBA Stuff...
++CORBA_ORB orb;
++CORBA_Environment *ev;
++
++
++/*
++ * FILE OPERATIONS FILE OPERATIONS FILE OPERATIONS FILE OPERATIONS
++ */
++
++/* Declarations for the file_operations structure for normal files...
++ */
++static struct file_operations corbafs_file_operations = {
++ read: generic_file_read,
++};
++
++
++/* Declarations for the file_operations structure for directories...
++ */
++static int corbafs_readdir(struct file *file, void *data, filldir_t filldir);
++
++static struct file_operations corbafs_dir_operations = {
++ read: generic_read_dir,
++ readdir: corbafs_readdir,
++};
++
++
++/*
++ * INODE OPERATIONS INODE OPERATIONS INODE OPERATIONS INODE OPERATIONS
++ */
++
++/* Declarations for the inode_operations structure for symlinks...
++ */
++static int corbafs_readlink(struct dentry *dentry, char *buffer, int buflen);
++static int corbafs_followlink(struct dentry *link, struct nameidata *nd);
++
++static struct inode_operations corbafs_symlink_inode_operations = {
++ readlink: corbafs_readlink,
++ follow_link: corbafs_followlink,
++};
++
++
++/* Declarations for the inode_operations structure for directories...
++ */
++static struct dentry *corbafs_lookup(struct inode *dir, struct dentry *dentry);
++
++static struct inode_operations corbafs_dir_inode_operations = {
++ lookup: corbafs_lookup,
++};
++
++
++/*
++ * OTHER OPERATIONS OTHER OPERATIONS OTHER OPERATIONS OTHER OPERATIONS
++ */
++
++/* Declarations for the corba FS's address space ops...
++ */
++static int corbafs_readpage(struct file *file, struct page * page);
++
++static struct address_space_operations corbafs_aops = {
++ readpage: corbafs_readpage,
++};
++
++
++/* Declarations for the super_operations structure...
++ */
++static int corbafs_statfs(struct super_block *sb, struct statfs *buf);
++static void corbafs_delete_inode(struct inode *);
++
++static struct super_operations corbafs_ops = {
++ statfs: corbafs_statfs,
++ delete_inode: corbafs_delete_inode,
++};
++
++
++
++
++/* do_local_path - Modified version of d_path that is used to get the remote
++ * filename that a dentry represents...
++ */
++static char *d_local_path(struct dentry *dentry, char *buffer, int buflen) {
++ char * end = buffer+buflen;
++ char * retval;
++ int namelen;
++
++ *--end = '\0';
++ buflen--;
++
++ /* Get '/' right */
++ retval = end-1;
++ *retval = '/';
++ for (;;) {
++ if (IS_ROOT(dentry)) {
++ if (dentry->d_name.len > 1 ||
++ dentry->d_name.name[0] != '/' ||
++ retval != end) { /* Only for root directory */
++ namelen = dentry->d_name.len;
++ buflen -= namelen;
++ if (buflen >= 0) {
++ end -= namelen;
++ memcpy(end, dentry->d_name.name, namelen);
++ }
++ }
++ return end;
++ }
++ namelen = dentry->d_name.len;
++ buflen -= namelen + 1;
++ if (buflen < 0)
++ break;
++ end -= namelen;
++ memcpy(end, dentry->d_name.name, namelen);
++ *--end = '/';
++ retval = end;
++ if (dentry == dentry->d_parent) break;
++ dentry = dentry->d_parent;
++ }
++ return retval;
++}
++
++
++/* corbafs_readpage - This request should be between a file_open and a
++ * file_release, so file_fd(f) should be valid. Just read the buffer...
++ */
++static int corbafs_readpage(struct file *f, struct page * page)
++{
++ struct inode *d_inode = f->f_dentry->d_inode;
++ CorbaFS_Inode inode;
++ CorbaFS_Buffer *buffer = NULL;
++
++ int offset = page->index*PAGE_CACHE_SIZE;
++ int bytesRead;
++
++#if 0
++ printk("*** READPAGE 0x%p: 0x%lX->0x%lX to 0x%p\n",
++ f,
++ page->index,
++ page->index*PAGE_CACHE_SIZE,
++ page_address(page));
++#endif
++
++ inode = d_inode->u.generic_ip;
++ if (!inode) return -EPERM;
++
++ CorbaFS_Inode_readpage(inode, &buffer, PAGE_CACHE_SIZE, offset, ev);
++ if (!buffer) return -EPERM; /* ??? */
++
++ bytesRead = buffer->_length;
++ memcpy(page_address(page), buffer->_buffer, bytesRead);
++
++ if (bytesRead != PAGE_CACHE_SIZE) { /* EOF? */
++ /* Zero out rest of page for security. */
++ memset((void*)(page_address(page)+bytesRead), 0,
++ PAGE_CACHE_SIZE-bytesRead);
++ }
++
++ SetPageUptodate(page);
++ UnlockPage(page);
++ return 0;
++}
++
++
++
++struct inode *corbafs_get_inode(struct super_block *sb, const char *path)
++{
++ struct inode * inode = get_empty_inode();
++ CorbaFS_FileSystem fs_client;
++ CorbaFS_Inode newInode;
++
++ if (!inode) return 0;
++
++ inode->i_sb = sb;
++ inode->i_dev = sb->s_dev;
++
++ fs_client = sb->u.generic_sbp;
++//printk("\n \n \nCorbaFS_FileSystem_getInode(0x%X, %s)\n", fs_client, path);
++ newInode = CorbaFS_FileSystem_getInode(fs_client, path, ev);
++//printk("NewInode = 0x%X\n \n \n \n", newInode);
++ if (!newInode) {
++ iput(inode);
++ return NULL;
++ }
++
++//printk("CorbaFS_Inode_getStatus\n");
++ CorbaFS_Inode_getStatus(newInode,
++ &inode->i_mode, &inode->i_uid, &inode->i_gid,
++ (CORBA_unsigned_long *)&inode->i_size,
++ (CORBA_unsigned_long *)&inode->i_ino,
++ &inode->i_nlink,
++ (CORBA_long *)&inode->i_atime,
++ (CORBA_long *)&inode->i_mtime,
++ (CORBA_long *)&inode->i_ctime,
++ ev);
++//printk("Back from CorbaFS_Inode_getStatus\n \n \n \n");
++
++ inode->u.generic_ip = (void*)newInode;
++
++ /* TODO: Map things back correctly??? */
++ inode->i_uid = 0 /*current->fsuid */;
++ inode->i_gid = 0 /*current->fsgid */;
++
++ inode->i_blksize = PAGE_CACHE_SIZE;
++ inode->i_blocks = 0;
++ inode->i_rdev = 0;
++ inode->i_op = NULL;
++ inode->i_fop = NULL;
++ inode->i_mapping->a_ops = &corbafs_aops;
++ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
++
++ switch (inode->i_mode & S_IFMT) {
++ default:
++ /* Do I really want to expose device inodes? */
++ init_special_inode(inode, inode->i_mode, sb->s_dev);
++ break;
++ case S_IFREG:
++ inode->i_fop = &corbafs_file_operations;
++ break;
++ case S_IFDIR:
++ inode->i_op = &corbafs_dir_inode_operations;
++ inode->i_fop = &corbafs_dir_operations;
++ break;
++ case S_IFLNK:
++ inode->i_op = &corbafs_symlink_inode_operations;
++ break;
++ }
++ insert_inode_hash(inode);
++
++ return inode;
++}
++
++static int corbafs_readdir(struct file *file, void *data, filldir_t filldir)
++{
++ struct inode *inode = file->f_dentry->d_inode;
++ struct super_block *sb = file->f_dentry->d_sb;
++ unsigned offset = file->f_pos;
++ char *path, *page = (char *)__get_free_page(GFP_KERNEL);
++ int i;
++ unsigned char d_type = DT_UNKNOWN;
++ CorbaFS_FileSystem fs_client;
++ CorbaFS_DirEntSeq *dirEntSeq;
++ CorbaFS_dirent *dirEnts;
++
++ if (offset >= inode->i_size) return 0;
++
++ path = d_local_path(file->f_dentry, page, PAGE_SIZE);
++
++ fs_client = sb->u.generic_sbp;
++ if (!fs_client)
++ return -EPERM; /* ??? */
++
++// printk("\n \n \nCorbaFS_FileSystem_readdir(%s)\n", path);
++
++ dirEntSeq = CorbaFS_FileSystem_readdir(fs_client, path, ev);
++
++// printk("CorbaFS_FileSystem_readdir = %d\n \n \n \n", dirEntSeq->_length);
++
++ if (dirEntSeq->_length == 0) goto full;
++
++ dirEnts = dirEntSeq->_buffer;
++ i = 0;
++ if (offset) { // We have read PART of the directory
++ int idxadj = offset; // Start reading now from where we left
++ while (idxadj > 0) { // off...
++ idxadj -= sizeof(struct dirent)+
++ strlen(dirEnts[i].name);
++ i++;
++ }
++
++ if (idxadj < 0) { // We should end up with exactly 0.
++ printf("Alert! Readdir can't resume in the middle "
++ "of a directory! stopage.\n");
++ goto full;
++ }
++ }
++
++ for (; i < dirEntSeq->_length; i++) {
++ int myinode = dirEnts[i].inode;
++ char *myname = dirEnts[i].name;
++ int namelen = strlen(myname);
++
++ if (filldir(data, myname, namelen, offset, myinode, d_type))
++ goto full;
++ offset += sizeof(struct dirent)+namelen;
++ }
++
++ full:
++ file->f_pos = offset;
++ return 0;
++}
++
++static int corbafs_statfs(struct super_block *sb, struct statfs *buf) {
++ buf->f_type = CORBAFS_MAGIC;
++ buf->f_bsize = PAGE_CACHE_SIZE;
++ buf->f_namelen = 255;
++ return 0;
++}
++
++/*
++ * Lookup the data. Most of the grunt work is done by corbafs_get_inode.
++ */
++static struct dentry *corbafs_lookup(struct inode *dir, struct dentry *dentry)
++{
++ struct inode *New;
++ char *Path, *Page = (char *)__get_free_page(GFP_KERNEL);
++ if (Page == 0) goto out; /* nomem? */
++
++ Path = d_local_path(dentry, Page, PAGE_SIZE);
++
++ New = corbafs_get_inode(dir->i_sb, Path);
++ free_page((unsigned long)Page);
++
++ if (New) {
++ d_add(dentry, New);
++ return 0;
++ }
++
++out:
++ d_add(dentry, NULL);
++ return 0;
++}
++
++
++static char *corbafs_read_a_link(struct dentry *dentry) {
++ char *path, *page, *s = 0;
++ struct super_block *sb = dentry->d_sb;
++ CorbaFS_FileSystem fs_client;
++
++ page = (char *)__get_free_page(GFP_KERNEL);
++ if (page == 0) goto out; /* nomem? */
++
++ path = d_local_path(dentry, page, PAGE_SIZE);
++
++ fs_client = sb->u.generic_sbp;
++// printk("\n \n \nCorbaFS_FileSystem_readlink(%s)\n", path);
++ s = CorbaFS_FileSystem_readlink(fs_client, path, ev);
++// printk("CorbaFS_FileSystem_readlink = %s\n \n \n \n", s);
++
++ if (ev->_major != CORBA_NO_EXCEPTION) {
++ if (s) {
++ // CORBA_string_free(s,..);
++ s = 0;
++ }
++ goto outfree;
++ }
++ outfree:
++ free_page((unsigned long)page);
++ out:
++ return s;
++}
++
++
++static int corbafs_readlink(struct dentry *dentry, char *buffer, int buflen) {
++ char *str = corbafs_read_a_link(dentry);
++ int error = -EINVAL;
++
++ if (str) {
++ error = vfs_readlink(dentry, buffer, buflen, str);
++ // TODO: CORBA_string__free the string str.
++ }
++ return error;
++}
++
++/* Fill in nd->dentry
++ */
++static int corbafs_followlink(struct dentry *link, struct nameidata *nd) {
++ int Error = -ENOMEM;
++ char *Path = corbafs_read_a_link(link);
++ if (!Path) goto out;
++
++#if 1
++ printk("Followlink: %s\n", Path);
++#endif
++ Error = vfs_follow_link(nd, Path);
++ // TODO: CORBA_string__free the string str.
++
++ out:
++ return Error;
++}
++
++static void corbafs_delete_inode(struct inode *inode) {
++ CorbaFS_Inode Inode = inode->u.generic_ip;
++// printk("\n \n \nCorbaFS_Inode_Release\n");
++ CorbaFS_Inode_release(Inode, ev);
++// printk("CorbaFS_Inode_Release done\n \n \n \n");
++}
++
++static void corbafs_put_super(struct super_block *sb) {
++// MOD_DEC_USE_COUNT;
++}
++
++static struct super_block *corbafs_read_super(struct super_block * sb, void * data, int silent) {
++ struct dentry *root = 0;
++ struct inode *root_inode = 0;
++
++ CorbaFS_FileSystem fs_client;
++
++ sb->s_blocksize = PAGE_CACHE_SIZE;
++ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
++ sb->s_magic = CORBAFS_MAGIC;
++ sb->s_op = &corbafs_ops;
++
++//printk("corbafs_read_super: '%s'\n", (char*)data);
++
++ // Note that the CORBA IOR is now in *data
++ fs_client = CORBA_ORB_string_to_object(orb, data, ev);
++
++//printk("fs_client: 0x%X\n", fs_client);
++ if (!fs_client)
++ return NULL;
++
++ sb->u.generic_sbp = fs_client;
++
++ root_inode = corbafs_get_inode(sb, "/");
++//printk("root_inode = 0x%X\n", root_inode);
++ root = d_alloc_root(root_inode);
++ if (!root) {
++ iput(root_inode);
++ return NULL;
++ }
++ sb->s_root = root;
++
++// MOD_INC_USE_COUNT;
++ return sb;
++}
++
++static DECLARE_FSTYPE(corbafs_fs_type, "corbafs", corbafs_read_super, 0);
++
++static int __init init_corbafs_fs(void) {
++ int argc = 1;
++ char *argv[] = { "client", 0 };
++ ev = g_new0(CORBA_Environment,1);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++
++ return register_filesystem(&corbafs_fs_type);
++}
++
++static void __exit exit_corbafs_fs(void)
++{
++ // remove object from orb.
++ printf("\n \n \nCorbaFS_exit()\n");
++ unregister_filesystem(&corbafs_fs_type);
++ CORBA_Object_release((CORBA_Object)orb, ev);
++}
++
++module_init(init_corbafs_fs)
++module_exit(exit_corbafs_fs)
++
++/*
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-common.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-common.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-common.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-common.c Thu Feb 1 16:36:08 2001
+@@ -0,0 +1,370 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "CorbaFS.h"
++
++#if ( (TC_IMPL_TC_CorbaFS_dirent_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_dirent_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_dirent_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_dirent_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_dirent_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_dirent_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_dirent_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_dirent)
++#define TC_DEF_TC_CorbaFS_dirent 1
++static const char *anon_subnames_array1[] = { "inode", "name" };
++static const CORBA_TypeCode anon_subtypes_array2[] =
++ { (CORBA_TypeCode) & TC_CORBA_long_struct,
++ (CORBA_TypeCode) & TC_CORBA_string_struct };
++const struct CORBA_TypeCode_struct TC_CorbaFS_dirent_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_struct, "dirent", "IDL:CorbaFS/dirent:1.0",
++ 0, 2,
++ (const char **) anon_subnames_array1,
++ (CORBA_TypeCode *) anon_subtypes_array2,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CorbaFS_dirent)
++#define TC_DEF_TC_CORBA_sequence_CorbaFS_dirent 1
++static const CORBA_TypeCode anon_subtypes_array6[] =
++ { (CORBA_TypeCode) & TC_CorbaFS_dirent_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CorbaFS_dirent_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array6,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CorbaFS_dirent)
++#define TC_DEF_TC_CORBA_sequence_CorbaFS_dirent 1
++static const CORBA_TypeCode anon_subtypes_array15[] =
++ { (CORBA_TypeCode) & TC_CorbaFS_dirent_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CorbaFS_dirent_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array15,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_DirEntSeq_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_DirEntSeq)
++#define TC_DEF_TC_CorbaFS_DirEntSeq 1
++static const CORBA_TypeCode anon_subtypes_array19[] =
++ { (CORBA_TypeCode) & TC_CORBA_sequence_CorbaFS_dirent_struct };
++const struct CORBA_TypeCode_struct TC_CorbaFS_DirEntSeq_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_alias, "DirEntSeq", "IDL:CorbaFS/DirEntSeq:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array19,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CORBA_octet_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CORBA_octet)
++#define TC_DEF_TC_CORBA_sequence_CORBA_octet 1
++static const CORBA_TypeCode anon_subtypes_array23[] =
++ { (CORBA_TypeCode) & TC_CORBA_octet_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CORBA_octet_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array23,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CORBA_octet_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CORBA_octet)
++#define TC_DEF_TC_CORBA_sequence_CORBA_octet 1
++static const CORBA_TypeCode anon_subtypes_array32[] =
++ { (CORBA_TypeCode) & TC_CORBA_octet_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CORBA_octet_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array32,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_Buffer_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_Buffer)
++#define TC_DEF_TC_CorbaFS_Buffer 1
++static const CORBA_TypeCode anon_subtypes_array36[] =
++ { (CORBA_TypeCode) & TC_CORBA_sequence_CORBA_octet_struct };
++const struct CORBA_TypeCode_struct TC_CorbaFS_Buffer_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_alias, "Buffer", "IDL:CorbaFS/Buffer:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array36,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_Inode_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_Inode_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_Inode_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_Inode_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_Inode_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_Inode_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_Inode_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_Inode)
++#define TC_DEF_TC_CorbaFS_Inode 1
++const struct CORBA_TypeCode_struct TC_CorbaFS_Inode_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "Inode", "IDL:CorbaFS/Inode:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_FileSystem_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_FileSystem)
++#define TC_DEF_TC_CorbaFS_FileSystem 1
++const struct CORBA_TypeCode_struct TC_CorbaFS_FileSystem_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "FileSystem", "IDL:CorbaFS/FileSystem:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++gpointer
++CorbaFS_dirent__free(gpointer mem, gpointer dat, CORBA_boolean free_strings)
++{
++ CorbaFS_dirent *var = mem;
++
++ if (free_strings) {
++ CORBA_string__free(&(var->name), NULL, free_strings);
++ }
++ return (gpointer) (var + 1);
++}
++
++CorbaFS_dirent *
++CorbaFS_dirent__alloc(void)
++{
++ CorbaFS_dirent *retval;
++
++ retval =
++ ORBit_alloc(sizeof(CorbaFS_dirent),
++ (ORBit_free_childvals) CorbaFS_dirent__free,
++ GUINT_TO_POINTER(1));
++ memset(&(retval->name), '\0', sizeof(retval->name));
++ return retval;
++}
++
++#if ( (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_0 == 'C') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_1 == 'o') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_2 == 'r') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_3 == 'b') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_4 == 'a') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_5 == 'F') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_6 == 'S') \
++) && !defined(ORBIT_DEF_CORBA_sequence_CorbaFS_dirent)
++#define ORBIT_DEF_CORBA_sequence_CorbaFS_dirent 1
++
++gpointer
++CORBA_sequence_CorbaFS_dirent__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings)
++{
++ CORBA_sequence_CorbaFS_dirent *val = mem;
++
++ if (val->_release)
++ ORBit_free(val->_buffer, free_strings);
++ return (gpointer) (val + 1);
++}
++
++CORBA_sequence_CorbaFS_dirent *
++CORBA_sequence_CorbaFS_dirent__alloc(void)
++{
++ CORBA_sequence_CorbaFS_dirent *retval;
++
++ retval =
++ ORBit_alloc(sizeof(CORBA_sequence_CorbaFS_dirent),
++ (ORBit_free_childvals) CORBA_sequence_CorbaFS_dirent__free,
++ GUINT_TO_POINTER(1));
++ retval->_maximum = 0;
++ retval->_length = 0;
++ retval->_buffer = NULL;
++ retval->_release = CORBA_FALSE;
++ return retval;
++}
++
++CorbaFS_dirent *
++CORBA_sequence_CorbaFS_dirent_allocbuf(CORBA_unsigned_long len)
++{
++ CorbaFS_dirent *retval =
++ ORBit_alloc(sizeof(CorbaFS_dirent) * len,
++ (ORBit_free_childvals) CorbaFS_dirent__free,
++ GUINT_TO_POINTER(len));
++
++ memset(retval, '\0', sizeof(CorbaFS_dirent) * len);
++ return retval;
++}
++#endif
++
++gpointer
++CorbaFS_DirEntSeq__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings)
++{
++ return CORBA_sequence_CorbaFS_dirent__free(mem, dat, free_strings);
++}
++
++CorbaFS_DirEntSeq *
++CorbaFS_DirEntSeq__alloc(void)
++{
++ return CORBA_sequence_CorbaFS_dirent__alloc();
++}
++
++#if ( (ORBIT_IMPL_CORBA_sequence_CORBA_octet_0 == 'C') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_1 == 'o') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_2 == 'r') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_3 == 'b') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_4 == 'a') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_5 == 'F') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_6 == 'S') \
++) && !defined(ORBIT_DEF_CORBA_sequence_CORBA_octet)
++#define ORBIT_DEF_CORBA_sequence_CORBA_octet 1
++
++gpointer
++CORBA_sequence_CORBA_octet__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings)
++{
++ CORBA_sequence_CORBA_octet *val = mem;
++
++ if (val->_release)
++ ORBit_free(val->_buffer, free_strings);
++ return (gpointer) (val + 1);
++}
++
++CORBA_sequence_CORBA_octet *
++CORBA_sequence_CORBA_octet__alloc(void)
++{
++ CORBA_sequence_CORBA_octet *retval;
++
++ retval =
++ ORBit_alloc(sizeof(CORBA_sequence_CORBA_octet),
++ (ORBit_free_childvals) CORBA_sequence_CORBA_octet__free,
++ GUINT_TO_POINTER(1));
++ retval->_maximum = 0;
++ retval->_length = 0;
++ retval->_buffer = NULL;
++ retval->_release = CORBA_FALSE;
++ return retval;
++}
++
++CORBA_octet *
++CORBA_sequence_CORBA_octet_allocbuf(CORBA_unsigned_long len)
++{
++ CORBA_octet *retval =
++ ORBit_alloc(sizeof(CORBA_octet) * len, (ORBit_free_childvals) NULL,
++ GUINT_TO_POINTER(len));
++
++ return retval;
++}
++#endif
++
++gpointer
++CorbaFS_Buffer__free(gpointer mem, gpointer dat, CORBA_boolean free_strings)
++{
++ return CORBA_sequence_CORBA_octet__free(mem, dat, free_strings);
++}
++
++CorbaFS_Buffer *
++CorbaFS_Buffer__alloc(void)
++{
++ return CORBA_sequence_CORBA_octet__alloc();
++}
++
++CORBA_unsigned_long CorbaFS_Inode__classid = 0;
++CORBA_unsigned_long CorbaFS_FileSystem__classid = 0;
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c Thu Feb 1 16:36:08 2001
+@@ -0,0 +1,791 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "CorbaFS.h"
++
++void
++CorbaFS_Inode_getStatus(CorbaFS_Inode _obj, CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid, CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks, CORBA_long * atime,
++ CORBA_long * mtime, CORBA_long * ctime,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_Inode__classid) {
++
++ ((POA_CorbaFS_Inode__epv *) _obj->vepv[CorbaFS_Inode__classid])->
++ getStatus(_obj->servant, mode, uid, gid, size, inodeNum, numLinks,
++ atime, mtime, ctime, ev);
++ return;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[10];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 10, "getStatus"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 14 };
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 2);
++
++ (*((guint16 *) & ((*mode)))) =
++ GUINT16_SWAP_LE_BE(*((guint16 *) _ORBIT_curptr));
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*uid)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*gid)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*size)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*inodeNum)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint16 *) & ((*numLinks)))) =
++ GUINT16_SWAP_LE_BE(*((guint16 *) _ORBIT_curptr));
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*atime)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*mtime)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*ctime)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));} else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 2);
++ (*mode) = *((CORBA_unsigned_short *) _ORBIT_curptr);
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*uid) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*gid) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*size) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*inodeNum) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*numLinks) = *((CORBA_unsigned_short *) _ORBIT_curptr);
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*atime) = *((CORBA_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*mtime) = *((CORBA_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*ctime) = *((CORBA_long *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ }
++ }
++}
++void
++CorbaFS_Inode_readpage(CorbaFS_Inode _obj, CorbaFS_Buffer ** buffer,
++ const CORBA_long size, const CORBA_long offset,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ register CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_Inode__classid) {
++
++ ((POA_CorbaFS_Inode__epv *) _obj->vepv[CorbaFS_Inode__classid])->
++ readpage(_obj->servant, buffer, size, offset, ev);
++ return;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[9];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 9, "readpage"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 13 };
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ &(size), sizeof(size));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ &(offset), sizeof(offset));
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ *buffer = CorbaFS_Buffer__alloc();
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & (((**buffer))._length))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ ((**buffer))._buffer =
++ CORBA_sequence_CORBA_octet_allocbuf(((**buffer))._length);
++ ((**buffer))._release = CORBA_TRUE;
++ memcpy(((**buffer))._buffer, _ORBIT_curptr,
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length);
++ _ORBIT_curptr +=
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length;
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ ((**buffer))._length = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++
++ ((**buffer))._buffer =
++ CORBA_sequence_CORBA_octet_allocbuf(((**buffer))._length);
++ ((**buffer))._release = CORBA_TRUE;
++ memcpy(((**buffer))._buffer, _ORBIT_curptr,
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length);
++ _ORBIT_curptr +=
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length;
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ }
++ }
++}
++void
++CorbaFS_Inode_release(CorbaFS_Inode _obj, CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_Inode__classid) {
++
++ ((POA_CorbaFS_Inode__epv *) _obj->vepv[CorbaFS_Inode__classid])->
++ release(_obj->servant, ev);
++ return;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[8];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 8, "release"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 12 };
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ } else {
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ }
++ }
++}
++CorbaFS_Inode
++CorbaFS_FileSystem_getInode(CorbaFS_FileSystem _obj, const CORBA_char * path,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ CorbaFS_Inode _ORBIT_retval;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_FileSystem__classid) {
++ _ORBIT_retval =
++ ((POA_CorbaFS_FileSystem__epv *) _obj->
++ vepv[CorbaFS_FileSystem__classid])->getInode(_obj->servant, path,
++ ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[9];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 9, "getInode"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 13 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(path) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (path),
++ sizeof(path[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ } else {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
++CorbaFS_DirEntSeq *
++CorbaFS_FileSystem_readdir(CorbaFS_FileSystem _obj, const CORBA_char * path,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ CorbaFS_DirEntSeq *_ORBIT_retval;
++ register CORBA_unsigned_long _ORBIT_tmpvar_5;
++ register CORBA_unsigned_long _ORBIT_tmpvar_6;
++ CORBA_unsigned_long _ORBIT_tmpvar_7;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_FileSystem__classid) {
++ _ORBIT_retval =
++ ((POA_CorbaFS_FileSystem__epv *) _obj->
++ vepv[CorbaFS_FileSystem__classid])->readdir(_obj->servant, path,
++ ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[8];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 8, "readdir"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 12 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(path) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (path),
++ sizeof(path[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_retval = CorbaFS_DirEntSeq__alloc();
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*_ORBIT_retval)._length))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer =
++ CORBA_sequence_CorbaFS_dirent_allocbuf((*_ORBIT_retval)._length);
++ (*_ORBIT_retval)._release = CORBA_TRUE;
++ for (_ORBIT_tmpvar_5 = 0; _ORBIT_tmpvar_5 < (*_ORBIT_retval)._length;
++ _ORBIT_tmpvar_5++) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*
++ ((guint32 *) &
++ ((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].inode))) =
++GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ (*((guint32 *) & (_ORBIT_tmpvar_7))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name =
++ CORBA_string_alloc(_ORBIT_tmpvar_7);
++ memcpy((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name,
++ _ORBIT_curptr,
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7);
++ _ORBIT_curptr +=
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7;
++ }
++
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*_ORBIT_retval)._length = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer =
++ CORBA_sequence_CorbaFS_dirent_allocbuf((*_ORBIT_retval)._length);
++ (*_ORBIT_retval)._release = CORBA_TRUE;
++ for (_ORBIT_tmpvar_5 = 0; _ORBIT_tmpvar_5 < (*_ORBIT_retval)._length;
++ _ORBIT_tmpvar_5++) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].inode = *((CORBA_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ _ORBIT_tmpvar_7 = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name =
++ CORBA_string_alloc(_ORBIT_tmpvar_7);
++ memcpy((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name,
++ _ORBIT_curptr,
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7);
++ _ORBIT_curptr +=
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7;
++ }
++
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
++CORBA_char *
++CorbaFS_FileSystem_readlink(CorbaFS_FileSystem _obj,
++ const CORBA_char * filename,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ CORBA_char *_ORBIT_retval;
++ register CORBA_unsigned_long _ORBIT_tmpvar_4;
++ CORBA_unsigned_long _ORBIT_tmpvar_5;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_FileSystem__classid) {
++ _ORBIT_retval =
++ ((POA_CorbaFS_FileSystem__epv *) _obj->
++ vepv[CorbaFS_FileSystem__classid])->readlink(_obj->servant,
++ filename, ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[9];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 9, "readlink"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 13 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(filename) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (filename),
++ sizeof(filename[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & (_ORBIT_tmpvar_5))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ _ORBIT_retval = CORBA_string_alloc(_ORBIT_tmpvar_5);
++ memcpy(_ORBIT_retval, _ORBIT_curptr,
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5);
++ _ORBIT_curptr +=
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5;
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ _ORBIT_tmpvar_5 = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ _ORBIT_retval = CORBA_string_alloc(_ORBIT_tmpvar_5);
++ memcpy(_ORBIT_retval, _ORBIT_curptr,
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5);
++ _ORBIT_curptr +=
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5;
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,92 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <orb/orbit.h>
++
++#include "CorbaFS.h"
++
++CorbaFS_FileSystem fs;
++
++int
++main (int argc, char *argv[])
++{
++ CORBA_Environment ev;
++ CORBA_ORB orb;
++ CorbaFS_Inode inode;
++ CorbaFS_Buffer *buffer;
++ CorbaFS_DirEntSeq *dirents;
++ CorbaFS_dirent *dirent;
++
++ CORBA_unsigned_short mode;
++ CORBA_unsigned_long uid;
++ CORBA_unsigned_long gid;
++ CORBA_unsigned_long size;
++ CORBA_unsigned_long inodeNum;
++ CORBA_unsigned_short numLinks;
++ CORBA_long atime;
++ CORBA_long mtime;
++ CORBA_long ctime;
++
++ int i;
++
++ int niters = 10;
++
++ CORBA_exception_init(&ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++
++ if(argc < 2)
++ {
++ printf("Need a binding ID thing as argv[1]\n");
++ return 1;
++ }
++
++
++ fs = CORBA_ORB_string_to_object(orb, argv[1], &ev);
++ if (!fs) {
++ printf("Cannot bind to %s\n", argv[1]);
++ return 1;
++ }
++
++ if (argc >= 3)
++ inode = CorbaFS_FileSystem_getInode(fs, argv[2], &ev);
++ else
++ inode = CorbaFS_FileSystem_getInode(fs, "/proc/cpuinfo", &ev);
++
++ if (!inode)
++ {
++ printf("Cannot get inode\n");
++ }
++
++ CorbaFS_Inode_getStatus(inode,
++ &mode,
++ &uid,
++ &gid,
++ &size,
++ &inodeNum,
++ &numLinks,
++ &atime,
++ &mtime,
++ &ctime,
++ &ev);
++
++ printf("inode = %x\n", inode);
++ CorbaFS_Inode_readpage(inode, &buffer, 1000, 100, &ev);
++ printf("readpage got %d bytes\n", buffer->_length);
++ printf("readpage returned : %s\n", buffer->_buffer);
++
++ if (argc >= 3)
++ dirents = CorbaFS_FileSystem_readdir(fs, argv[2], &ev);
++ else
++ dirents = CorbaFS_FileSystem_readdir(fs, "/", &ev);
++
++ dirent = dirents->_buffer;
++ for (i = 0; i < dirents->_length; i++)
++ {
++ printf("%d = %s\n", dirent->inode, dirent->name);
++ dirent++;
++ }
++
++ CORBA_Object_release(fs, &ev);
++ CORBA_Object_release((CORBA_Object)orb, &ev);
++
++ return 0;
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS.h linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS.h
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS.h Thu Feb 1 16:36:08 2001
+@@ -0,0 +1,349 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <glib.h>
++#define ORBIT_IDL_SERIAL 9
++#include <orb/orbit.h>
++
++#ifndef CorbaFS_H
++#define CorbaFS_H 1
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++/** typedefs **/
++#if !defined(_CorbaFS_dirent_defined)
++#define _CorbaFS_dirent_defined 1
++ typedef struct
++ {
++ CORBA_long inode;
++ CORBA_char *name;
++ }
++ CorbaFS_dirent;
++
++#if !defined(TC_IMPL_TC_CorbaFS_dirent_0)
++#define TC_IMPL_TC_CorbaFS_dirent_0 'C'
++#define TC_IMPL_TC_CorbaFS_dirent_1 'o'
++#define TC_IMPL_TC_CorbaFS_dirent_2 'r'
++#define TC_IMPL_TC_CorbaFS_dirent_3 'b'
++#define TC_IMPL_TC_CorbaFS_dirent_4 'a'
++#define TC_IMPL_TC_CorbaFS_dirent_5 'F'
++#define TC_IMPL_TC_CorbaFS_dirent_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_dirent_struct;
++#define TC_CorbaFS_dirent ((CORBA_TypeCode)&TC_CorbaFS_dirent_struct)
++#endif
++ extern CorbaFS_dirent *CorbaFS_dirent__alloc(void);
++ extern gpointer CorbaFS_dirent__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++#endif
++#if !defined(ORBIT_DECL_CORBA_sequence_CorbaFS_dirent) && !defined(_CORBA_sequence_CorbaFS_dirent_defined)
++#define ORBIT_DECL_CORBA_sequence_CorbaFS_dirent 1
++#define _CORBA_sequence_CorbaFS_dirent_defined 1
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_0 'C'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_1 'o'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_2 'r'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_3 'b'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_4 'a'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_5 'F'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_6 'S'
++ typedef struct
++ {
++ CORBA_unsigned_long _maximum,
++ _length;
++ CorbaFS_dirent *_buffer;
++ CORBA_boolean _release;
++ }
++ CORBA_sequence_CorbaFS_dirent;
++#if !defined(TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0)
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0 'C'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_1 'o'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_2 'r'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_3 'b'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_4 'a'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_5 'F'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_6 'S'
++ extern const struct CORBA_TypeCode_struct
++ TC_CORBA_sequence_CorbaFS_dirent_struct;
++#define TC_CORBA_sequence_CorbaFS_dirent ((CORBA_TypeCode)&TC_CORBA_sequence_CorbaFS_dirent_struct)
++#endif
++ extern CORBA_sequence_CorbaFS_dirent
++ *CORBA_sequence_CorbaFS_dirent__alloc(void);
++ extern gpointer CORBA_sequence_CorbaFS_dirent__free(gpointer mem,
++ gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++ CorbaFS_dirent *CORBA_sequence_CorbaFS_dirent_allocbuf(CORBA_unsigned_long
++ len);
++#endif
++#if !defined(_CorbaFS_DirEntSeq_defined)
++#define _CorbaFS_DirEntSeq_defined 1
++ typedef CORBA_sequence_CorbaFS_dirent CorbaFS_DirEntSeq;
++#if !defined(TC_IMPL_TC_CorbaFS_DirEntSeq_0)
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_0 'C'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_1 'o'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_2 'r'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_3 'b'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_4 'a'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_5 'F'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_DirEntSeq_struct;
++#define TC_CorbaFS_DirEntSeq ((CORBA_TypeCode)&TC_CorbaFS_DirEntSeq_struct)
++#endif
++ extern CorbaFS_DirEntSeq *CorbaFS_DirEntSeq__alloc(void);
++ extern gpointer CorbaFS_DirEntSeq__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++#endif
++#if !defined(ORBIT_DECL_CORBA_sequence_CORBA_octet) && !defined(_CORBA_sequence_CORBA_octet_defined)
++#define ORBIT_DECL_CORBA_sequence_CORBA_octet 1
++#define _CORBA_sequence_CORBA_octet_defined 1
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_0 'C'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_1 'o'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_2 'r'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_3 'b'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_4 'a'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_5 'F'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_6 'S'
++ typedef struct
++ {
++ CORBA_unsigned_long _maximum,
++ _length;
++ CORBA_octet *_buffer;
++ CORBA_boolean _release;
++ }
++ CORBA_sequence_CORBA_octet;
++#if !defined(TC_IMPL_TC_CORBA_sequence_CORBA_octet_0)
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_0 'C'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_1 'o'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_2 'r'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_3 'b'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_4 'a'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_5 'F'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_6 'S'
++ extern const struct CORBA_TypeCode_struct
++ TC_CORBA_sequence_CORBA_octet_struct;
++#define TC_CORBA_sequence_CORBA_octet ((CORBA_TypeCode)&TC_CORBA_sequence_CORBA_octet_struct)
++#endif
++ extern CORBA_sequence_CORBA_octet *CORBA_sequence_CORBA_octet__alloc(void);
++ extern gpointer CORBA_sequence_CORBA_octet__free(gpointer mem,
++ gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++ CORBA_octet *CORBA_sequence_CORBA_octet_allocbuf(CORBA_unsigned_long len);
++#endif
++#if !defined(_CorbaFS_Buffer_defined)
++#define _CorbaFS_Buffer_defined 1
++ typedef CORBA_sequence_CORBA_octet CorbaFS_Buffer;
++#if !defined(TC_IMPL_TC_CorbaFS_Buffer_0)
++#define TC_IMPL_TC_CorbaFS_Buffer_0 'C'
++#define TC_IMPL_TC_CorbaFS_Buffer_1 'o'
++#define TC_IMPL_TC_CorbaFS_Buffer_2 'r'
++#define TC_IMPL_TC_CorbaFS_Buffer_3 'b'
++#define TC_IMPL_TC_CorbaFS_Buffer_4 'a'
++#define TC_IMPL_TC_CorbaFS_Buffer_5 'F'
++#define TC_IMPL_TC_CorbaFS_Buffer_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_Buffer_struct;
++#define TC_CorbaFS_Buffer ((CORBA_TypeCode)&TC_CorbaFS_Buffer_struct)
++#endif
++ extern CorbaFS_Buffer *CorbaFS_Buffer__alloc(void);
++ extern gpointer CorbaFS_Buffer__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++#endif
++#if !defined(ORBIT_DECL_CorbaFS_Inode) && !defined(_CorbaFS_Inode_defined)
++#define ORBIT_DECL_CorbaFS_Inode 1
++#define _CorbaFS_Inode_defined 1
++#define CorbaFS_Inode__free CORBA_Object__free
++ typedef CORBA_Object CorbaFS_Inode;
++ extern CORBA_unsigned_long CorbaFS_Inode__classid;
++#if !defined(TC_IMPL_TC_CorbaFS_Inode_0)
++#define TC_IMPL_TC_CorbaFS_Inode_0 'C'
++#define TC_IMPL_TC_CorbaFS_Inode_1 'o'
++#define TC_IMPL_TC_CorbaFS_Inode_2 'r'
++#define TC_IMPL_TC_CorbaFS_Inode_3 'b'
++#define TC_IMPL_TC_CorbaFS_Inode_4 'a'
++#define TC_IMPL_TC_CorbaFS_Inode_5 'F'
++#define TC_IMPL_TC_CorbaFS_Inode_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_Inode_struct;
++#define TC_CorbaFS_Inode ((CORBA_TypeCode)&TC_CorbaFS_Inode_struct)
++#endif
++#endif
++#if !defined(ORBIT_DECL_CorbaFS_FileSystem) && !defined(_CorbaFS_FileSystem_defined)
++#define ORBIT_DECL_CorbaFS_FileSystem 1
++#define _CorbaFS_FileSystem_defined 1
++#define CorbaFS_FileSystem__free CORBA_Object__free
++ typedef CORBA_Object CorbaFS_FileSystem;
++ extern CORBA_unsigned_long CorbaFS_FileSystem__classid;
++#if !defined(TC_IMPL_TC_CorbaFS_FileSystem_0)
++#define TC_IMPL_TC_CorbaFS_FileSystem_0 'C'
++#define TC_IMPL_TC_CorbaFS_FileSystem_1 'o'
++#define TC_IMPL_TC_CorbaFS_FileSystem_2 'r'
++#define TC_IMPL_TC_CorbaFS_FileSystem_3 'b'
++#define TC_IMPL_TC_CorbaFS_FileSystem_4 'a'
++#define TC_IMPL_TC_CorbaFS_FileSystem_5 'F'
++#define TC_IMPL_TC_CorbaFS_FileSystem_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_FileSystem_struct;
++#define TC_CorbaFS_FileSystem ((CORBA_TypeCode)&TC_CorbaFS_FileSystem_struct)
++#endif
++#endif
++
++/** POA structures **/
++ typedef struct
++ {
++ void *_private;
++ void (*getStatus) (PortableServer_Servant _servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid, CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks, CORBA_long * atime,
++ CORBA_long * mtime, CORBA_long * ctime,
++ CORBA_Environment * ev);
++ void (*readpage) (PortableServer_Servant _servant,
++ CorbaFS_Buffer ** buffer, const CORBA_long size,
++ const CORBA_long offset, CORBA_Environment * ev);
++ void (*release) (PortableServer_Servant _servant,
++ CORBA_Environment * ev);
++ }
++ POA_CorbaFS_Inode__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_CorbaFS_Inode__epv *CorbaFS_Inode_epv;
++ }
++ POA_CorbaFS_Inode__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_CorbaFS_Inode__vepv *vepv;
++ }
++ POA_CorbaFS_Inode;
++ extern void POA_CorbaFS_Inode__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_CorbaFS_Inode__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ typedef struct
++ {
++ void *_private;
++
++ CorbaFS_Inode(*getInode) (PortableServer_Servant _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CorbaFS_DirEntSeq *(*readdir) (PortableServer_Servant _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CORBA_char *(*readlink) (PortableServer_Servant _servant,
++ const CORBA_char * filename,
++ CORBA_Environment * ev);
++ }
++ POA_CorbaFS_FileSystem__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_CorbaFS_FileSystem__epv *CorbaFS_FileSystem_epv;
++ }
++ POA_CorbaFS_FileSystem__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_CorbaFS_FileSystem__vepv *vepv;
++ }
++ POA_CorbaFS_FileSystem;
++ extern void POA_CorbaFS_FileSystem__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_CorbaFS_FileSystem__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++/** prototypes **/
++ void CorbaFS_Inode_getStatus(CorbaFS_Inode _obj,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime, CORBA_long * mtime,
++ CORBA_long * ctime, CORBA_Environment * ev);
++ void CorbaFS_Inode_readpage(CorbaFS_Inode _obj, CorbaFS_Buffer ** buffer,
++ const CORBA_long size, const CORBA_long offset,
++ CORBA_Environment * ev);
++ void CorbaFS_Inode_release(CorbaFS_Inode _obj, CORBA_Environment * ev);
++ CorbaFS_Inode CorbaFS_FileSystem_getInode(CorbaFS_FileSystem _obj,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CorbaFS_DirEntSeq *CorbaFS_FileSystem_readdir(CorbaFS_FileSystem _obj,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CORBA_char *CorbaFS_FileSystem_readlink(CorbaFS_FileSystem _obj,
++ const CORBA_char * filename,
++ CORBA_Environment * ev);
++
++ void _ORBIT_skel_CorbaFS_Inode_getStatus(POA_CorbaFS_Inode *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ void (*_impl_getStatus)
++ (PortableServer_Servant _servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime,
++ CORBA_long * mtime,
++ CORBA_long * ctime,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_Inode_readpage(POA_CorbaFS_Inode * _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ void (*_impl_readpage)
++ (PortableServer_Servant _servant,
++ CorbaFS_Buffer ** buffer,
++ const CORBA_long size,
++ const CORBA_long offset,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_Inode_release(POA_CorbaFS_Inode * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ void (*_impl_release)
++ (PortableServer_Servant _servant,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_FileSystem_getInode(POA_CorbaFS_FileSystem *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ CorbaFS_Inode(*_impl_getInode)
++ (PortableServer_Servant
++ _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_FileSystem_readdir(POA_CorbaFS_FileSystem *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ CorbaFS_DirEntSeq *
++ (*_impl_readdir)
++ (PortableServer_Servant
++ _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_FileSystem_readlink(POA_CorbaFS_FileSystem *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ CORBA_char *
++ (*_impl_readlink)
++ (PortableServer_Servant
++ _servant,
++ const CORBA_char * filename,
++ CORBA_Environment * ev));
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif
++#undef ORBIT_IDL_SERIAL
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit CorbaFS client
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-corbafs-client.o
++
++obj-y := CorbaFS-common.o CorbaFS-stubs.o CorbaFS-client.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++CorbaFS-client.c: CorbaFS.h
++
++CorbaFS.h CorbaFS-common.c CorbaFS-stubs.c: ../CorbaFS.idl
++ $(ORBIT_IDL) --noskels ../CorbaFS.idl
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile.user linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile.user
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile.user Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = CorbaFS
++
++CFLAGS = -Wall `orbit-config --cflags client` -I../../..
++LDFLAGS = `orbit-config --libs client`
++OBJS = $(PROJECT)-common.o $(PROJECT)-stubs.o $(PROJECT)-user-client.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-user-client: $(OBJS)
++ gcc -o $(PROJECT)-user-client $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-user-client.o: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-stubs.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --noskels ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-user-client
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/README Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,4 @@
++This module implements the kernel VFS->kORBit interface. This is called a 'client'
++because it actually USES a CORBA object that is exported from someplace else.
++
++ORB: kORBit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Entries Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,6 @@
++/CorbaFS-server.c/1.8/Thu Feb 1 09:47:03 2001//
++/CorbaFS-skelimpl.c/1.10/Thu Feb 1 09:47:04 2001//
++/Makefile/1.5/Thu Feb 1 09:47:04 2001//
++/README/1.2/Thu Feb 1 09:47:04 2001//
++/RunServer.sh/1.1/Thu Feb 1 09:47:04 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Repository Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS/server
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Root Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-server.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-server.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-server.c Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,37 @@
++#include <stdio.h>
++#include "CorbaFS-skelimpl.c"
++
++CORBA_ORB orb;
++PortableServer_POA poa;
++CORBA_Environment *ev;
++PortableServer_ObjectId *objid;
++
++int main(int argc, char *argv[]) {
++ CorbaFS_FileSystem fs;
++ impl_POA_CorbaFS_FileSystem *fs_impl;
++
++ PortableServer_POAManager pm;
++ ev = g_new0(CORBA_Environment,1);
++
++ CORBA_exception_init(ev);
++ printf("Make sure you use TCP/IP and not Unix sockets!\n");
++
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++ poa = (PortableServer_POA)
++ CORBA_ORB_resolve_initial_references(orb,
++ "RootPOA",
++ ev);
++ fs = impl_CorbaFS_FileSystem__create(poa, ev);
++
++ pm = PortableServer_POA__get_the_POAManager(poa, ev);
++ PortableServer_POAManager_activate(pm, ev);
++
++ fs_impl = PortableServer_POA_reference_to_servant( poa, fs, ev );
++ objid = PortableServer_POA_servant_to_id( poa, fs_impl, ev );
++
++ printf("CorbaFS-server:\n%s\n", CORBA_ORB_object_to_string(orb, fs, ev));
++
++ CORBA_ORB_run(orb, ev);
++
++ return 0;
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,353 @@
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include <dirent.h>
++
++#include "CorbaFS.h"
++
++/*** App-specific servant structures ***/
++
++#define printf(fmt, args...) fprintf(stderr, fmt, ##args);
++
++typedef struct
++{
++ POA_CorbaFS_Inode servant;
++ PortableServer_POA poa;
++
++ CORBA_char *path;
++#if 0
++ CORBA_unsigned_short mode;
++ CORBA_unsigned_long uid;
++ CORBA_unsigned_long gid;
++ CORBA_unsigned_long size;
++ CORBA_unsigned_long inodeNum;
++ CORBA_unsigned_short numLinks;
++ CORBA_long atime;
++ CORBA_long mtime;
++ CORBA_long ctime;
++#endif
++}
++impl_POA_CorbaFS_Inode;
++
++typedef struct
++{
++ POA_CorbaFS_FileSystem servant;
++ PortableServer_POA poa;
++
++}
++impl_POA_CorbaFS_FileSystem;
++
++/*** Implementation stub prototypes ***/
++
++static void impl_CorbaFS_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev);
++static void
++impl_CorbaFS_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime,
++ CORBA_long * mtime,
++ CORBA_long * ctime, CORBA_Environment * ev);
++
++static void
++impl_CorbaFS_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
++ CorbaFS_Buffer ** buffer,
++ CORBA_long size,
++ CORBA_long offset, CORBA_Environment * ev);
++
++static void
++impl_CorbaFS_Inode_release(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev);
++
++static void impl_CorbaFS_FileSystem__destroy(impl_POA_CorbaFS_FileSystem *
++ servant, CORBA_Environment * ev);
++static CorbaFS_Inode
++impl_CorbaFS_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path, CORBA_Environment * ev);
++
++static CorbaFS_DirEntSeq
++ *impl_CorbaFS_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path,
++
++ CORBA_Environment * ev);
++
++static CORBA_char
++ *impl_CorbaFS_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * filename,
++ CORBA_Environment * ev);
++
++/*** epv structures ***/
++
++static PortableServer_ServantBase__epv impl_CorbaFS_Inode_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_CorbaFS_Inode__epv impl_CorbaFS_Inode_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_CorbaFS_Inode_getStatus,
++
++ (gpointer) & impl_CorbaFS_Inode_readpage,
++
++ (gpointer) & impl_CorbaFS_Inode_release,
++
++};
++static PortableServer_ServantBase__epv impl_CorbaFS_FileSystem_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_CorbaFS_FileSystem__epv impl_CorbaFS_FileSystem_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_CorbaFS_FileSystem_getInode,
++
++ (gpointer) & impl_CorbaFS_FileSystem_readdir,
++
++ (gpointer) & impl_CorbaFS_FileSystem_readlink,
++
++};
++
++/*** vepv structures ***/
++
++static POA_CorbaFS_Inode__vepv impl_CorbaFS_Inode_vepv = {
++ &impl_CorbaFS_Inode_base_epv,
++ &impl_CorbaFS_Inode_epv,
++};
++static POA_CorbaFS_FileSystem__vepv impl_CorbaFS_FileSystem_vepv = {
++ &impl_CorbaFS_FileSystem_base_epv,
++ &impl_CorbaFS_FileSystem_epv,
++};
++
++/*** Stub implementations ***/
++
++static CorbaFS_Inode
++impl_CorbaFS_Inode__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ CorbaFS_Inode retval;
++ impl_POA_CorbaFS_Inode *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_CorbaFS_Inode, 1);
++ newservant->servant.vepv = &impl_CorbaFS_Inode_vepv;
++ newservant->poa = poa;
++ POA_CorbaFS_Inode__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_CorbaFS_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_CorbaFS_Inode__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static void
++impl_CorbaFS_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime,
++ CORBA_long * mtime,
++ CORBA_long * ctime, CORBA_Environment * ev)
++{
++ struct stat buf;
++
++ printf("Inode_getStatus()\n");
++ printf("Inode path = %s\n", servant->path);
++ lstat(servant->path, &buf);
++
++ *mode = buf.st_mode;
++ *uid = buf.st_uid;
++ *gid = buf.st_gid;
++ *size = buf.st_size;
++ *inodeNum = buf.st_ino;
++ *numLinks = buf.st_nlink;
++ *atime = buf.st_atime;
++ *mtime = buf.st_mtime;
++ *ctime = buf.st_ctime;
++}
++
++static void
++impl_CorbaFS_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
++ CorbaFS_Buffer ** buffer,
++ CORBA_long size,
++ CORBA_long offset, CORBA_Environment * ev)
++{
++ int fd = -1, c = 0;
++
++ printf("Inode_readpage(buffer, %d, %d)\n", size, offset);
++ printf("Inode_readpage : path = %s\n", servant->path);
++
++ *buffer = CorbaFS_Buffer__alloc();
++ (*buffer)->_maximum = size;
++ (*buffer)->_buffer = CORBA_octet_allocbuf(size);
++
++ memset((*buffer)->_buffer, size, 0);
++
++ fd = open(servant->path, O_RDONLY);
++ printf("Inode_readpage : fd = %d\n", fd);
++ lseek(fd, offset, SEEK_SET);
++ c = read(fd, (*buffer)->_buffer, size);
++ printf("Inode_readpage : read %d bytes\n", c);
++ (*buffer)->_length = c;
++ close(fd);
++}
++
++static void
++impl_CorbaFS_Inode_release(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev)
++{
++ printf("Inode_release()\n");
++}
++
++static CorbaFS_FileSystem
++impl_CorbaFS_FileSystem__create(PortableServer_POA poa,
++ CORBA_Environment * ev)
++{
++ CorbaFS_FileSystem retval;
++ impl_POA_CorbaFS_FileSystem *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_CorbaFS_FileSystem, 1);
++ newservant->servant.vepv = &impl_CorbaFS_FileSystem_vepv;
++ newservant->poa = poa;
++ POA_CorbaFS_FileSystem__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_CorbaFS_FileSystem__destroy(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_CorbaFS_FileSystem__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static CorbaFS_Inode
++impl_CorbaFS_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path, CORBA_Environment * ev)
++{
++ CorbaFS_Inode retval;
++ impl_POA_CorbaFS_Inode *inode;
++
++ printf("FileSystem_getInode(%s)\n", path);
++
++ retval = impl_CorbaFS_Inode__create(servant->poa, ev);
++
++ inode = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
++ inode->path = CORBA_string_dup(path);
++#if 0
++ inode->mode = 0040777; /* world-readable directory */
++ inode->uid = 0;
++ inode->gid = 0;
++ inode->size = 4096;
++ inode->inodeNum = inodeNum++;
++ inode->numLinks = 1;
++ inode->atime = 0;
++ inode->mtime = 100;
++ inode->ctime = 10000;
++#endif
++
++ return retval;
++}
++
++static CorbaFS_DirEntSeq *
++impl_CorbaFS_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path, CORBA_Environment * ev)
++{
++ CorbaFS_DirEntSeq *retval;
++ CorbaFS_dirent *dirent;
++
++ DIR *dir;
++ struct dirent *dirp;
++ int c;
++
++ printf("FileSystem_readdir(%s)\n", path);
++
++ retval = CorbaFS_DirEntSeq__alloc();
++ retval->_maximum = 0;
++ retval->_length = 0;
++
++ dir = opendir(path);
++ if (dir == NULL)
++ return retval;
++
++ c = 0;
++ while ((dirp = readdir(dir)))
++ c++;
++
++ rewinddir(dir);
++
++ printf("%d directories\n", c);
++
++ retval->_buffer = CORBA_sequence_CorbaFS_dirent_allocbuf(c);
++ retval->_maximum = c;
++ dirent = retval->_buffer;
++
++ c = 0;
++ while ((dirp = readdir(dir)) && (c < retval->_maximum))
++ {
++ printf("Adding directory %d : %s (%d)\n", c, dirp->d_name, dirp->d_ino);
++
++ dirent[c].inode = dirp->d_ino;
++ dirent[c].name = CORBA_string_dup(dirp->d_name);
++ c++;
++ }
++ retval->_length = c;
++
++ closedir(dir);
++
++ return retval;
++}
++
++static CORBA_char *
++impl_CorbaFS_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * filename,
++ CORBA_Environment * ev)
++{
++ CORBA_char *retval = CORBA_OBJECT_NIL;
++ char tmp[MAXPATHLEN + 1];
++ int len;
++
++ printf("FileSystem_readlink(%s) = ", filename);
++ len = readlink(filename, tmp, MAXPATHLEN);
++ if (len != -1)
++ {
++ tmp[len] = '\0';
++ retval = CORBA_string_dup(tmp);
++ }
++
++ printf("%s\n", retval);
++
++ return retval;
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/Makefile linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/Makefile
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/Makefile Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = CorbaFS
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.o: $(PROJECT).h $(PROJECT)-skelimpl.c
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/README Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,8 @@
++This server provides an NFS like capability of exporting an existing filesystem.
++
++ORB: ORBit
++Status: Working! (for readonly fs's)
++
++NOTE!!!!: When starting this server make sure you pass ORBit the options to
++ have it use ipv4 sockets and not unix domain sockets, or else bad
++ things will happen. You can use the included RunServer script.
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/RunServer.sh linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/RunServer.sh
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/RunServer.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/RunServer.sh Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++./CorbaFS-server -ORBIIOPUSock=0 -ORBIIOPIPv4=1
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Entries Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,3 @@
++/PerlServer/1.2/Thu Feb 1 09:47:04 2001//
++/README/1.1/Thu Feb 1 09:47:04 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Repository Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS/server-perl
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Root Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/PerlServer linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/PerlServer
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/PerlServer Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/PerlServer Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,67 @@
++#!/usr/bin/perl -w
++use CORBA::ORBit idl => [ qw(../CorbaFS.idl) ];
++use Error qw(:try);
++use strict;
++
++
++package MyFSInode;
++@MyFSInode::ISA = qw(POA_CorbaFS::Inode);
++
++sub new {
++ my $self = bless { name => shift };
++ print "INODE CREATED: $self->{name}!\n";
++}
++
++sub getStatus {
++ my ($self) = @_;
++ print "$self->getStatus()\n";
++}
++
++sub readpage {
++ return "";
++}
++
++sub release {
++}
++
++
++package MyFileSystem;
++@MyFileSystem::ISA = qw(POA_CorbaFS::FileSystem);
++
++sub new {
++ my $self = bless { root => '/home' };
++}
++
++sub getInode {
++ my $path = shift;
++ print "getInode($path)\n";
++ return new MyFSInode($path);
++}
++
++sub readdir {
++ my $path = shift;
++ print "readdir($path)\n";
++ return [ { inode => 1, name => '...' } ];
++}
++
++sub readlink {
++ my $path = shift;
++ print "readlink($path)\n";
++ return "fredrik";
++}
++
++
++package Main;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++my $poa = $orb->resolve_initial_references("RootPOA");
++
++my $Server = new MyFileSystem();
++my $id = $poa->activate_object($Server);
++my $ref = $orb->object_to_string($poa->id_to_reference($id));
++
++print "$ref\n";
++
++print "Running orb:\n";
++$orb->run();
++exit(0);
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/README Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,4 @@
++Test filesystem implementation in Perl.
++
++ORB: ORBit/Perl
++Status: horribly broken
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.3/Thu Feb 1 09:47:04 2001//
++/README/1.1/Thu Feb 1 09:47:05 2001//
++/echo.idl/1.1/Thu Feb 1 09:47:05 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries.Log Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,3 @@
++A D/client////
++A D/client-perl////
++A D/server////
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Repository Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Root Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/Makefile linux-2.4.1-korbit/net/korbit/modules/Echo/Makefile
+--- linux-2.4.1/net/korbit/modules/Echo/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/Makefile Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit/modules/Console
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_ECHO) := client server
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/Echo/README linux-2.4.1-korbit/net/korbit/modules/Echo/README
+--- linux-2.4.1/net/korbit/modules/Echo/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/README Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,2 @@
++The Echo test is very similar to the console test, but it also "returns" a
++"random" number. The random number, in our case, is simply a constant.
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Entries Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,6 @@
++/Makefile/1.4/Thu Feb 1 09:47:05 2001//
++/Makefile.user/1.1/Thu Feb 1 09:47:05 2001//
++/README/1.1/Thu Feb 1 09:47:05 2001//
++/RunClient.sh/1.1/Thu Feb 1 09:47:05 2001//
++/echo-client.c/1.6/Thu Feb 1 09:47:05 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Repository Thu Feb 1 11:47:05 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo/client
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Root Thu Feb 1 11:47:05 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/Makefile linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile
+--- linux-2.4.1/net/korbit/modules/Echo/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-echo-client.o
++
++obj-y := echo-common.o echo-stubs.o echo-client.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++echo-client.c: echo.h
++
++echo.h echo-common.c echo-stubs.c: ../echo.idl
++ $(ORBIT_IDL) --noskels ../echo.idl
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/Makefile.user linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile.user
+--- linux-2.4.1/net/korbit/modules/Echo/client/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile.user Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = echo
++
++CFLAGS = -Wall `orbit-config --cflags client` -I../../..
++LDFLAGS = `orbit-config --libs client`
++OBJS = $(PROJECT)-common.o $(PROJECT)-stubs.o $(PROJECT)-client.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-client: $(OBJS)
++ gcc -o $(PROJECT)-client $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-client.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-stubs.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --noskels ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-client
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-stubs.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/README linux-2.4.1-korbit/net/korbit/modules/Echo/client/README
+--- linux-2.4.1/net/korbit/modules/Echo/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/README Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,4 @@
++This simply tests the Echo service.
++
++ORB: ORBit
++Status: working
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/RunClient.sh linux-2.4.1-korbit/net/korbit/modules/Echo/client/RunClient.sh
+--- linux-2.4.1/net/korbit/modules/Echo/client/RunClient.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/RunClient.sh Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,3 @@
++#!/bin/sh
++date
++./echo-client `cat /proc/corba/echo-server` 5
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo-client.c linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-client.c
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-client.c Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,119 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <sys/time.h>
++#include <unistd.h>
++#include <orb/orbit.h>
++
++#ifdef __KERNEL__
++#include <linux/init.h>
++#include <linux/module.h>
++#include "korbit.h"
++#endif
++#include "echo.h"
++
++Echo echo_client, bec;
++
++#define BATCH_SIZE 1
++
++
++#ifndef __KERNEL__
++int main (int argc, char *argv[]) {
++#else
++int __init corba_echo_init(void) {
++ int argc = 1; char *argv[] = { "echo-client", 0, 0 };
++#endif
++ CORBA_Environment ev;
++ CORBA_ORB orb;
++ CORBA_long rv;
++ char buf[30];
++ int i, j;
++
++ int niters = 5;
++
++#ifndef __KERNEL__
++ struct timeval start, end;
++ long diff, diffsum = 0;
++#endif
++
++ CORBA_exception_init(&ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++
++#ifdef __KERNEL__
++ {
++ int c, fd = open("/tmp/echo-ior", O_RDONLY, 0);
++ if (fd == -1)
++ return -1;
++ printf("Reading IOR from /tmp/echo-ior\n");
++ argv[1] = malloc(501);
++ c = read(fd, argv[1], 500);
++ argv[1][c] = '\0';
++ printf("Reading %d bytes: %s\n", c, argv[1]);
++ }
++#else
++ if(argc < 2)
++ {
++ printf("Need an IOR as argv[1]\n");
++ return 1;
++ }
++
++ if(argc == 3)
++ niters = atoi(argv[2]);
++#endif
++
++ echo_client = CORBA_ORB_string_to_object(orb, argv[1], &ev);
++ if (!echo_client) {
++ printf("Cannot bind to %s\n", argv[1]);
++ return 1;
++ }
++
++ for(i = 0; i < niters; i++) {
++ g_snprintf(buf, sizeof(buf), "Hello, world [%d]", i);
++#ifdef __KERNEL__
++ bec = Echo_echoString(echo_client, buf, &rv, &ev);
++#else
++ gettimeofday(&start, NULL);
++ for (j = BATCH_SIZE; j > 0; j--) {
++ bec = Echo_echoString(echo_client, buf, &rv, &ev);
++ if (j != 1) CORBA_Object_release(bec, &ev);
++ }
++ gettimeofday(&end, NULL);
++ diff = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
++ diff /= BATCH_SIZE;
++ diffsum += diff;
++
++ printf("duration = %d usec\t", diff);
++#endif
++
++ if(ev._major != CORBA_NO_EXCEPTION) {
++ printf("\nWe got exception %d from echoString!\n", ev._major);
++ return 1;
++ }
++
++ CORBA_Object_release(echo_client, &ev);
++ if(ev._major != CORBA_NO_EXCEPTION) {
++ printf("we got exception %d from release!\n", ev._major);
++ return 1;
++ }
++
++ printf("[client] %d\n", rv);
++
++ echo_client = bec; bec = CORBA_OBJECT_NIL;
++ }
++
++#ifndef __KERNEL__
++ printf("duration average = %d usec\n", diffsum / niters);
++ CORBA_Object_release(echo_client, &ev);
++ CORBA_Object_release((CORBA_Object)orb, &ev);
++#endif
++
++ return 0;
++}
++
++
++#ifdef __KERNEL__
++void corba_echo_exit(void) {
++}
++
++module_init(corba_echo_init)
++module_exit(corba_echo_exit)
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo-common.c linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-common.c
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo-common.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-common.c Thu Feb 1 16:36:36 2001
+@@ -0,0 +1,27 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++#if ( (TC_IMPL_TC_Echo_0 == 'e') \
++&& (TC_IMPL_TC_Echo_1 == 'c') \
++&& (TC_IMPL_TC_Echo_2 == 'h') \
++&& (TC_IMPL_TC_Echo_3 == 'o') \
++) && !defined(TC_DEF_TC_Echo)
++#define TC_DEF_TC_Echo 1
++const struct CORBA_TypeCode_struct TC_Echo_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "Echo", "IDL:Echo:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++CORBA_unsigned_long Echo__classid = 0;
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo-stubs.c linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-stubs.c
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo-stubs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-stubs.c Thu Feb 1 16:36:36 2001
+@@ -0,0 +1,134 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++Echo
++Echo_echoString(Echo _obj, const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ Echo _ORBIT_retval;
++
++ if (_obj->servant && _obj->vepv && Echo__classid) {
++ _ORBIT_retval =
++ ((POA_Echo__epv *) _obj->vepv[Echo__classid])->echoString(_obj->
++ servant,
++ astring,
++ anum, ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[11];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 11, "echoString"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 15 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(astring) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (astring),
++ sizeof(astring[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*anum)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));} else {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*anum) = *((CORBA_long *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo.h linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo.h
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo.h Thu Feb 1 16:36:36 2001
+@@ -0,0 +1,77 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <glib.h>
++#define ORBIT_IDL_SERIAL 9
++#include <orb/orbit.h>
++
++#ifndef echo_H
++#define echo_H 1
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++/** typedefs **/
++#if !defined(ORBIT_DECL_Echo) && !defined(_Echo_defined)
++#define ORBIT_DECL_Echo 1
++#define _Echo_defined 1
++#define Echo__free CORBA_Object__free
++ typedef CORBA_Object Echo;
++ extern CORBA_unsigned_long Echo__classid;
++#if !defined(TC_IMPL_TC_Echo_0)
++#define TC_IMPL_TC_Echo_0 'e'
++#define TC_IMPL_TC_Echo_1 'c'
++#define TC_IMPL_TC_Echo_2 'h'
++#define TC_IMPL_TC_Echo_3 'o'
++ extern const struct CORBA_TypeCode_struct TC_Echo_struct;
++#define TC_Echo ((CORBA_TypeCode)&TC_Echo_struct)
++#endif
++#endif
++
++/** POA structures **/
++ typedef struct
++ {
++ void *_private;
++
++ Echo(*echoString) (PortableServer_Servant _servant,
++ const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev);
++ }
++ POA_Echo__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_Echo__epv *Echo_epv;
++ }
++ POA_Echo__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_Echo__vepv *vepv;
++ }
++ POA_Echo;
++ extern void POA_Echo__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_Echo__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++/** prototypes **/
++ Echo Echo_echoString(Echo _obj, const CORBA_char * astring,
++ CORBA_long * anum, CORBA_Environment * ev);
++
++ void _ORBIT_skel_Echo_echoString(POA_Echo * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ Echo(*_impl_echoString)
++ (PortableServer_Servant _servant,
++ const CORBA_char * astring,
++ CORBA_long * anum,
++ CORBA_Environment * ev));
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif
++#undef ORBIT_IDL_SERIAL
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Entries Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,3 @@
++/PerlTest/1.2/Thu Feb 1 09:47:06 2001//
++/README/1.1/Thu Feb 1 09:47:06 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Repository Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo/client-perl
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Root Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/PerlTest linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/PerlTest
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/PerlTest Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/PerlTest Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,17 @@
++#!/usr/bin/perl -w
++
++use CORBA::ORBit idl => [ qw(../echo.idl) ];
++use Error qw(:try);
++use strict;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++open IOR, "/proc/corba/echo-server" or die "no console server found!";
++my $ior = <IOR>;
++close IOR;
++chomp($ior); # Kill fredrik's newline...
++
++my $echo = $orb->string_to_object($ior);
++# Echo echoString(in string astring, out long anum);
++my ($echo2, $num) = $echo->echoString("Echo Strange World");
++
++print "Return Echo = $echo2\nnum = $num\n";
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/README linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/README
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/README Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,4 @@
++Another test of the echo server.
++
++ORB: ORBit/Perl
++Status: Working fine
+diff -urN linux-2.4.1/net/korbit/modules/Echo/echo.idl linux-2.4.1-korbit/net/korbit/modules/Echo/echo.idl
+--- linux-2.4.1/net/korbit/modules/Echo/echo.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/echo.idl Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,3 @@
++interface Echo {
++ Echo echoString(in string astring, out long anum);
++};
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Entries Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,6 @@
++/Makefile/1.2/Thu Feb 1 09:47:06 2001//
++/Makefile.user/1.3/Thu Feb 1 09:47:06 2001//
++/README/1.1/Thu Feb 1 09:47:06 2001//
++/RunServer.sh/1.1/Thu Feb 1 09:47:06 2001//
++/echo-server.c/1.8/Thu Feb 1 09:47:06 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Repository Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo/server
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Root Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/Makefile linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile
+--- linux-2.4.1/net/korbit/modules/Echo/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,21 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-echo-server.o
++
++obj-y := echo-server.o echo-skels.o echo-common.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++echo-server.c: echo.h echo-skels.c
++
++
++echo.h echo-common.c echo-skels.c: ../echo.idl
++ $(ORBIT_IDL) ../echo.idl
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/Makefile.user linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile.user
+--- linux-2.4.1/net/korbit/modules/Echo/server/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile.user Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,27 @@
++#
++# Makefile for user level server
++#
++
++PROJECT = echo
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/README linux-2.4.1-korbit/net/korbit/modules/Echo/server/README
+--- linux-2.4.1/net/korbit/modules/Echo/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/README Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,5 @@
++This server implements the kernel side interface in terms of printk.
++
++This server also builds in user space with ORBit. Build with
++ make -f Makefile.user
++
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/RunServer.sh linux-2.4.1-korbit/net/korbit/modules/Echo/server/RunServer.sh
+--- linux-2.4.1/net/korbit/modules/Echo/server/RunServer.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/RunServer.sh Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++./echo-server -ORBIIOPUSock=0 -ORBIIOPIPv4=1
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-common.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-common.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-common.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-common.c Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,27 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++#if ( (TC_IMPL_TC_Echo_0 == 'e') \
++&& (TC_IMPL_TC_Echo_1 == 'c') \
++&& (TC_IMPL_TC_Echo_2 == 'h') \
++&& (TC_IMPL_TC_Echo_3 == 'o') \
++) && !defined(TC_DEF_TC_Echo)
++#define TC_DEF_TC_Echo 1
++const struct CORBA_TypeCode_struct TC_Echo_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "Echo", "IDL:Echo:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++CORBA_unsigned_long Echo__classid = 0;
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-server.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-server.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-server.c Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,103 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <signal.h>
++#include <orb/orbit.h>
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include "echo.h"
++#include "glib.h"
++#include "korbit.h"
++
++Echo echo_client = CORBA_OBJECT_NIL;
++
++static CORBA_Object
++do_echoString(PortableServer_Servant servant,
++ CORBA_char *astring,
++ CORBA_long *outnum,
++ CORBA_Environment *ev);
++
++PortableServer_ServantBase__epv base_epv = {
++ NULL,
++ NULL,
++ NULL
++};
++POA_Echo__epv echo_epv = { NULL, do_echoString };
++POA_Echo__vepv poa_echo_vepv = { &base_epv, &echo_epv };
++POA_Echo poa_echo_servant = { NULL, &poa_echo_vepv };
++
++PortableServer_ObjectId objid = {0, sizeof("myEchoString"), "myEchoString"};
++PortableServer_POA poa;
++CORBA_Environment *ev;
++
++#ifdef __KERNEL__
++int __init corba_echo_init(void)
++#else
++int main(int argc, char *argv[])
++#endif
++{
++#ifdef __KERNEL__
++ int argc = 1; char *argv[] = { "server", 0 };
++#endif
++ CORBA_ORB orb;
++ ev = g_new0(CORBA_Environment, 1);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++ if (!orb) {
++ printf("Error getting ORB!\n");
++ return 1;
++ }
++
++ poa = (PortableServer_POA)
++ CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
++ if (!poa) {
++ printf("Error getting POA!\n");
++ return 1;
++ }
++
++ PortableServer_POAManager_activate(
++ PortableServer_POA__get_the_POAManager(poa, ev), ev);
++
++
++ POA_Echo__init(&poa_echo_servant, ev);
++ PortableServer_POA_activate_object_with_id(poa,
++ &objid, &poa_echo_servant, ev);
++
++ echo_client = PortableServer_POA_servant_to_reference(poa,
++ &poa_echo_servant,
++ ev);
++ if (!echo_client) {
++ printf("Cannot get objref\n");
++ return 1;
++ }
++
++ korbit_register_ior("echo-server", echo_client, orb, ev);
++
++ CORBA_ORB_run(orb, ev);
++ return 0;
++}
++
++#ifdef __KERNEL__
++void corba_echo_exit(void) {
++ PortableServer_POA_deactivate_object(poa, &objid, ev);
++ remove_proc_entry("corba/echo-server", 0);
++}
++
++module_init(corba_echo_init)
++module_exit(corba_echo_exit)
++#endif
++
++static CORBA_Object
++do_echoString(PortableServer_Servant servant,
++ CORBA_char *astring,
++ CORBA_long *outnum,
++ CORBA_Environment *ev)
++{
++ *outnum = 12345678;
++
++#if 1
++ g_message("[server] %s -> %d", astring, *outnum);
++#endif
++
++ return CORBA_Object_duplicate(echo_client, ev);
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-skels.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-skels.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-skels.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-skels.c Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,115 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++void
++_ORBIT_skel_Echo_echoString(POA_Echo * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ Echo(*_impl_echoString) (PortableServer_Servant
++ _servant,
++ const CORBA_char *
++ astring,
++ CORBA_long * anum,
++ CORBA_Environment * ev))
++{
++ Echo _ORBIT_retval;
++ CORBA_char *astring;
++ CORBA_long anum;
++
++ { /* demarshalling */
++ guchar *_ORBIT_curptr;
++ register CORBA_unsigned_long _ORBIT_tmpvar_2;
++ CORBA_unsigned_long _ORBIT_tmpvar_3;
++
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & (_ORBIT_tmpvar_3))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ astring = (void *) _ORBIT_curptr;
++ _ORBIT_curptr += sizeof(astring[_ORBIT_tmpvar_2]) * _ORBIT_tmpvar_3;
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ _ORBIT_tmpvar_3 = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ astring = (void *) _ORBIT_curptr;
++ _ORBIT_curptr += sizeof(astring[_ORBIT_tmpvar_2]) * _ORBIT_tmpvar_3;
++ }
++ }
++ _ORBIT_retval = _impl_echoString(_ORBIT_servant, astring, &(anum), ev);
++ { /* marshalling */
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++
++ _ORBIT_send_buffer =
++ giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection, NULL,
++ _ORBIT_recv_buffer->message.u.request.
++ request_id, ev->_major);
++ if (_ORBIT_send_buffer) {
++ if (ev->_major == CORBA_NO_EXCEPTION) {
++ ORBit_marshal_object(_ORBIT_send_buffer, _ORBIT_retval);
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), &(anum),
++ sizeof(anum));
++ } else
++ ORBit_send_system_exception(_ORBIT_send_buffer, ev);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ }
++ if (ev->_major == CORBA_NO_EXCEPTION)
++ CORBA_Object_release(_ORBIT_retval, ev);
++ }
++}
++static ORBitSkeleton
++get_skel_Echo(POA_Echo * servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer, gpointer * impl)
++{
++ gchar *opname = _ORBIT_recv_buffer->message.u.request.operation;
++
++ switch (opname[0]) {
++ case 'e':
++ if (strcmp((opname + 1), "choString"))
++ break;
++ *impl = (gpointer) servant->vepv->Echo_epv->echoString;
++ return (ORBitSkeleton) _ORBIT_skel_Echo_echoString;
++ break;
++ default:
++ break;
++ }
++ return NULL;
++}
++
++static void
++init_local_objref_Echo(CORBA_Object obj, POA_Echo * servant)
++{
++ obj->vepv[Echo__classid] = servant->vepv->Echo_epv;
++}
++
++void
++POA_Echo__init(PortableServer_Servant servant, CORBA_Environment * env)
++{
++ static const PortableServer_ClassInfo class_info =
++ { (ORBit_impl_finder) & get_skel_Echo, "IDL:Echo:1.0",
++ (ORBit_local_objref_init) & init_local_objref_Echo };
++
++ PortableServer_ServantBase__init(((PortableServer_ServantBase *) servant),
++ env);
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *) servant)->_private)->
++ class_info = (PortableServer_ClassInfo *) & class_info;
++ if (!Echo__classid)
++ Echo__classid = ORBit_register_class(&class_info);
++}
++
++void
++POA_Echo__fini(PortableServer_Servant servant, CORBA_Environment * env)
++{
++ PortableServer_ServantBase__fini(servant, env);
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-stubs.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-stubs.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-stubs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-stubs.c Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,134 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++Echo
++Echo_echoString(Echo _obj, const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ Echo _ORBIT_retval;
++
++ if (_obj->servant && _obj->vepv && Echo__classid) {
++ _ORBIT_retval =
++ ((POA_Echo__epv *) _obj->vepv[Echo__classid])->echoString(_obj->
++ servant,
++ astring,
++ anum, ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[11];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 11, "echoString"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 15 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(astring) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (astring),
++ sizeof(astring[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*anum)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));} else {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*anum) = *((CORBA_long *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo.h linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo.h
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo.h Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,77 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <glib.h>
++#define ORBIT_IDL_SERIAL 9
++#include <orb/orbit.h>
++
++#ifndef echo_H
++#define echo_H 1
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++/** typedefs **/
++#if !defined(ORBIT_DECL_Echo) && !defined(_Echo_defined)
++#define ORBIT_DECL_Echo 1
++#define _Echo_defined 1
++#define Echo__free CORBA_Object__free
++ typedef CORBA_Object Echo;
++ extern CORBA_unsigned_long Echo__classid;
++#if !defined(TC_IMPL_TC_Echo_0)
++#define TC_IMPL_TC_Echo_0 'e'
++#define TC_IMPL_TC_Echo_1 'c'
++#define TC_IMPL_TC_Echo_2 'h'
++#define TC_IMPL_TC_Echo_3 'o'
++ extern const struct CORBA_TypeCode_struct TC_Echo_struct;
++#define TC_Echo ((CORBA_TypeCode)&TC_Echo_struct)
++#endif
++#endif
++
++/** POA structures **/
++ typedef struct
++ {
++ void *_private;
++
++ Echo(*echoString) (PortableServer_Servant _servant,
++ const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev);
++ }
++ POA_Echo__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_Echo__epv *Echo_epv;
++ }
++ POA_Echo__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_Echo__vepv *vepv;
++ }
++ POA_Echo;
++ extern void POA_Echo__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_Echo__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++/** prototypes **/
++ Echo Echo_echoString(Echo _obj, const CORBA_char * astring,
++ CORBA_long * anum, CORBA_Environment * ev);
++
++ void _ORBIT_skel_Echo_echoString(POA_Echo * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ Echo(*_impl_echoString)
++ (PortableServer_Servant _servant,
++ const CORBA_char * astring,
++ CORBA_long * anum,
++ CORBA_Environment * ev));
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif
++#undef ORBIT_IDL_SERIAL
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,4 @@
++/FileServer.idl/1.3/Thu Feb 1 09:47:07 2001//
++/Makefile/1.2/Thu Feb 1 09:47:07 2001//
++/README/1.1/Thu Feb 1 09:47:07 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries.Log Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,4 @@
++A D/client////
++A D/server////
++A D/server-user////
++A D/wrapper////
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Repository Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Root Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/FileServer.idl linux-2.4.1-korbit/net/korbit/modules/FileServer/FileServer.idl
+--- linux-2.4.1/net/korbit/modules/FileServer/FileServer.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/FileServer.idl Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,158 @@
++// -----------------------------------------------------------------------------
++// FileServer.idl
++// -----------------------------------------------------------------------------
++//
++// This file is used to define the Kernel CORBA API for accessing the filesystem
++// on a machine. This defines mappings both to access the files in the kernel
++// and to implement a filesystem for the kernel. This should probably be split
++// into two files eventually.
++//
++// Currently unimplemented: KernelAccessAPI::FileSystem::ReadDirectory
++// KernelAccessAPI::FileSystem::Select
++// KernelImplementationAPI::SuperBlock::getDiskQuotaOps
++//
++// -----------------------------------------------------------------------------
++
++
++// These are the exceptions that may be thrown and what they map to in the
++// Linux kernel. This interface is extended by other interfaces so that the
++// names don't have to be typedef'd into each interface that wants to use these
++// errors.
++//
++interface Errors {
++ exception IsDirectory {}; // EISDIR
++ exception PermissionDenied {}; // EACCES
++ exception FileExists {}; // EEXIST
++ exception FileNotFound {}; // ENOENT
++ exception IsNotDirectory {}; // ENOTDIR
++ exception ReadOnlyFile {}; // EROFS, ETXTBSY
++ exception RecursiveSymlink {}; // ELOOP
++ exception IsBusy {}; // EBUSY
++ exception OtherError{}; // Misc other ones...
++};
++
++
++// -----------------------------------------------------------------------------
++// KernelAccessAPI Module - Allow user level programs to call into the kernel
++// -----------------------------------------------------------------------------
++
++module FileServer {
++ struct FileStatus { // Corba equilivant of struct stat
++ long DeviceNum; // st_dev
++ long InodeNum; // st_ino
++ short Mode; // st_mode
++ short NumLinks; // st_nlink
++ long UserID; // st_uid
++ long GroupID; // st_gid
++ long DeviceType; // st_rdev
++ unsigned long Size; // st_size
++ unsigned long BlockSize; // st_blksize
++ unsigned long NumBlocks; // st_blocks;
++ unsigned long AccessTime; // st_blocks;
++ unsigned long ModifiedTime; // st_blocks;
++ unsigned long ChangeTime; // st_blocks;
++ };
++
++ typedef sequence<octet> buffer;
++
++ // ---------------------------------------------------------------------------
++ // FileSystem Interface - Access to filesystem and File object factory
++ // ---------------------------------------------------------------------------
++
++ interface File : Errors {
++ void Read(in long count, out buffer buf)
++ raises (IsDirectory, OtherError);
++ void Write(in buffer buf)
++ raises (OtherError);
++ void Close();
++
++ long FileControl(in long command) raises (OtherError);
++
++ FileStatus GetStatus() raises (OtherError);
++
++ void ChangeDirectoryTo() // This implements fchdir...
++ raises (IsNotDirectory, PermissionDenied, OtherError);
++
++ enum SeekDirection { FromStart, FromCurrent, FromEnd };
++ long Seek(in long Offset, in SeekDirection Direction) raises (OtherError);
++
++ File Duplicate() raises (OtherError);
++ };
++
++
++
++ // ---------------------------------------------------------------------------
++ // FileSystem Interface - Access to filesystem and File object factory
++ // ---------------------------------------------------------------------------
++
++ interface FileSystem : Errors {
++
++ // -------------------------------------------------------------------------
++ // File Manipulation Routines
++ // -------------------------------------------------------------------------
++
++ File Open(in string Filename, in long openFlags, in short mode)
++ raises (FileExists, IsDirectory, PermissionDenied, FileNotFound,
++ IsNotDirectory, ReadOnlyFile, RecursiveSymlink, OtherError);
++
++ File Create(in string Filename, in short mode)
++ raises (FileExists, IsDirectory, PermissionDenied, FileNotFound,
++ IsNotDirectory, ReadOnlyFile, RecursiveSymlink, OtherError);
++
++ void Link(in string FromPath, in string ToPath)
++ raises (PermissionDenied, IsNotDirectory, RecursiveSymlink, FileExists);
++
++ void Unlink(in string Filename)
++ raises (PermissionDenied, FileNotFound, IsNotDirectory, IsDirectory);
++
++ void Rename(in string OldName, in string NewName)
++ raises (IsDirectory, FileExists, IsBusy, IsNotDirectory, PermissionDenied,
++ RecursiveSymlink);
++
++ void ReadLink(in string Linkname, out string LinkValue)
++ raises (FileNotFound, PermissionDenied, RecursiveSymlink, OtherError);
++
++
++ FileStatus GetStatus(in string Filename)
++ raises (FileNotFound, PermissionDenied, RecursiveSymlink, IsNotDirectory,
++ OtherError);
++
++ FileStatus GetLinkStatus(in string Filename)
++ raises (FileNotFound, PermissionDenied, RecursiveSymlink, IsNotDirectory,
++ OtherError);
++
++
++ // -------------------------------------------------------------------------
++ // Directory Manipulation Routines
++ // -------------------------------------------------------------------------
++
++ void MakeDirectory(in string PathName, in short mode)
++ raises (FileExists, PermissionDenied, FileNotFound, IsNotDirectory,
++ ReadOnlyFile, RecursiveSymlink, OtherError);
++
++ void RemoveDirectory(in string PathName)
++ raises (PermissionDenied, FileNotFound, IsNotDirectory);
++
++ // ChangeDirectory returns CWD so that you can implement getcwd as
++ // { return ChangeDirectory("."); }
++ string ChangeDirectory(in string PathName)
++ raises (IsNotDirectory, PermissionDenied, FileNotFound, RecursiveSymlink);
++
++
++ // -------------------------------------------------------------------------
++ // Special Purpose Routines...
++ // -------------------------------------------------------------------------
++
++ void MakeNode(in string FileName, in short Mode, in long DeviceNum)
++ raises (PermissionDenied, FileExists, FileNotFound, IsNotDirectory,
++ RecursiveSymlink);
++
++ void Mount(in string DeviceFile, in string Location, in string FSType,
++ in long Flags)
++ raises (PermissionDenied, FileNotFound, IsBusy, IsNotDirectory);
++
++ void Unmount(in string Filename)
++ raises (PermissionDenied, FileNotFound, IsBusy);
++ };
++
++};
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/Makefile Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit/modules/CorbaFS
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_FILESERVER) := server
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/README linux-2.4.1-korbit/net/korbit/modules/FileServer/README
+--- linux-2.4.1/net/korbit/modules/FileServer/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/README Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,8 @@
++This interface lets you export file related syscalls through CORBA. This is
++genuinely useful, however, when you use the 'wrapper' library, that can be
++LD_PRELOADED before you run your application. This allows you to forward
++filesystem calls through CORBA without having to modify your application.
++
++Being able to forward filesystem calls though CORBA, of course, means that
++you can attach to any remote machine you want. :)
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Entries Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,4 @@
++/FileServer-client.cpp/1.1/Thu Feb 1 09:47:07 2001//
++/Makefile/1.1/Thu Feb 1 09:47:07 2001//
++/README/1.1/Thu Feb 1 09:47:07 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Repository Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/client
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Root Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/FileServer-client.cpp linux-2.4.1-korbit/net/korbit/modules/FileServer/client/FileServer-client.cpp
+--- linux-2.4.1/net/korbit/modules/FileServer/client/FileServer-client.cpp Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/FileServer-client.cpp Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,78 @@
++#include <OB/CORBA.h>
++#include <OB/Util.h>
++#include <OB/CosNaming.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
++#include "FileServer.h"
++
++int main(int argc, char* argv[])
++{
++ if (argc < 3)
++ {
++ cout << "Usage : " << argv[0] << " ior filename" << endl;
++ exit(1);
++ }
++
++ cout << "FileServer client initializing" << endl;
++
++ CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
++ cout << "ORB initialized" << endl;
++
++ try
++ {
++ CORBA_Object_var obj = orb->string_to_object( argv[1] );
++ assert(!CORBA_is_nil(obj));
++ cout << "got object... " << orb->object_to_string(obj) << endl;
++
++ FileServer_FileSystem_var fs = FileServer_FileSystem::_narrow(obj);
++ assert(!CORBA_is_nil(fs));
++ cout << "it's a FileServer!" << endl;
++
++ obj = fs->Open(argv[2], O_RDONLY, 0);
++ assert(!CORBA_is_nil(obj));
++ cout << "got object... " << orb->object_to_string(obj) << endl;
++
++ FileServer_File_var file = FileServer_File::_narrow(obj);
++ assert(!CORBA_is_nil(file));
++ cout << "it's a FileServer_File!" << endl;
++
++ FileServer_buffer *buf = new FileServer_buffer;
++ cout << "reading 1000 bytes" << endl;
++ file->Read(1000, buf);
++
++ cout << "got " << buf->length() << " bytes" << endl;
++ cout << buf->data() << endl;
++
++ file->Close();
++
++ delete buf;
++ }
++ catch (const CORBA_SystemException& ex) {
++ OBPrintException(ex);
++ return 1;
++ }
++ catch (const Errors::FileNotFound& ex) {
++ cout << "ERROR : File not found" << endl;
++ return 1;
++ }
++ catch (const Errors::PermissionDenied& ex) {
++ cout << "ERROR : Permission denied" << endl;
++ return 1;
++ }
++ catch (const Errors::IsDirectory& ex) {
++ cout << "ERROR : Is directory" << endl;
++ return 1;
++ }
++ catch (const Errors::OtherError& ex) {
++ cout << "ERROR : Other error" << endl;
++ return 1;
++ }
++ catch (const CORBA_UserException& ex)
++ {
++ cout << "ERROR : Uncaught exception" << endl;
++ return 1;
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/client/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/Makefile Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,32 @@
++CC = CC -mt -pta
++OBDIR = /home/class/cs423/local
++IDL = $(OBDIR)/bin/idl
++CPPFLAGS = -I. -I$(OBDIR)/include
++LDFLAGS = -L$(OBDIR)/lib
++LIBS = -lCosNaming -lOB -lJTC -lsocket -lnsl -lposix4
++
++all: FileServer-client
++
++FileServer-client: FileServer.o FileServer-client.o
++ $(CC) $(LDFLAGS) -o FileServer-client FileServer-client.o FileServer.o $(LIBS)
++
++nameserv:
++ nameserv -i -OAport 10000
++
++FileServer.h FileServer.cpp: ../FileServer.idl
++ rm -f FileServer.cpp FileServer.h
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ $(IDL) ../FileServer.idl
++
++FileServer_skel.cpp FileServer_skel.h: FileServer.cpp
++
++%.o: %.cpp
++ $(CC) $(CPPFLAGS) -c $<
++
++clean:
++ rm -f FileServer-client *.o *~
++
++realclean: clean
++ rm -f FileServer.h FileServer.cpp
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ rm -rf SunWS_cache
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/README linux-2.4.1-korbit/net/korbit/modules/FileServer/client/README
+--- linux-2.4.1/net/korbit/modules/FileServer/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/README Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,4 @@
++Very minimal test of the FileServer capability.
++
++ORB: Orbacus
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Entries Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,6 @@
++/FileServer-server.c/1.2/Thu Feb 1 09:47:08 2001//
++/FileServer-skelimpl.c/1.8/Thu Feb 1 09:47:08 2001//
++/Makefile/1.3/Thu Feb 1 09:47:08 2001//
++/Makefile.user/1.4/Thu Feb 1 09:47:08 2001//
++/README/1.1/Thu Feb 1 09:47:08 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Repository Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/server
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Root Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-server.c linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-server.c
+--- linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-server.c Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,57 @@
++#include <stdio.h>
++#include "FileServer-skelimpl.c"
++#include "korbit.h"
++
++CORBA_ORB orb;
++PortableServer_POA poa;
++CORBA_Environment *ev;
++PortableServer_ObjectId *objid;
++
++#ifdef __KERNEL__
++int __init FileServer_init(void) {
++#else
++int main(int argc, char *argv[]) {
++#endif
++ FileServer_FileSystem fs;
++ impl_POA_FileServer_FileSystem *fs_impl;
++
++ PortableServer_POAManager pm;
++#ifdef __KERNEL__
++ int argc = 1;
++ char *argv[] = { "server", 0 };
++#endif
++ ev = g_new0(CORBA_Environment,1);
++
++ CORBA_exception_init(ev);
++
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++ poa = (PortableServer_POA)
++ CORBA_ORB_resolve_initial_references(orb,
++ "RootPOA",
++ ev);
++ fs = impl_FileServer_FileSystem__create(poa, ev);
++
++ pm = PortableServer_POA__get_the_POAManager(poa, ev);
++ PortableServer_POAManager_activate(pm, ev);
++
++ fs_impl = PortableServer_POA_reference_to_servant( poa, fs, ev );
++ objid = PortableServer_POA_servant_to_id( poa, fs_impl, ev );
++
++ korbit_register_ior("FileServer-server", fs, orb, ev);
++
++ CORBA_ORB_run(orb, ev);
++
++ return 0;
++}
++
++#ifdef __KERNEL__
++void FileServer_exit(void)
++{
++ PortableServer_POA_deactivate_object(poa, objid, ev);
++ remove_proc_entry("corba/FileServer-server", 0);
++ printf("FileServer_exit()\n");
++}
++
++module_init(FileServer_init)
++module_exit(FileServer_exit)
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-skelimpl.c linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-skelimpl.c
+--- linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-skelimpl.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-skelimpl.c Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,804 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++
++#include "FileServer.h"
++
++static void set_exception(int errno, CORBA_Environment *ev)
++{
++ switch (errno)
++ {
++ case ENOENT:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_FileNotFound,
++ Errors_FileNotFound__alloc());
++ break;
++ case EEXIST:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_FileExists,
++ Errors_FileExists__alloc());
++ break;
++ case EACCES:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_PermissionDenied,
++ Errors_PermissionDenied__alloc());
++ break;
++ case EISDIR:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_IsDirectory,
++ Errors_IsDirectory__alloc());
++ break;
++ case ENOTDIR:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_IsNotDirectory,
++ Errors_IsNotDirectory__alloc());
++ break;
++ case EROFS:
++ case ETXTBSY:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_ReadOnlyFile,
++ Errors_ReadOnlyFile__alloc());
++ break;
++ case ELOOP:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_RecursiveSymlink,
++ Errors_RecursiveSymlink__alloc());
++ break;
++ case EBUSY:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_IsBusy,
++ Errors_IsBusy__alloc());
++ break;
++ default:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_OtherError,
++ Errors_OtherError__alloc());
++ break;
++ }
++}
++
++
++/*** App-specific servant structures ***/
++typedef struct
++{
++ POA_Errors servant;
++ PortableServer_POA poa;
++
++}
++impl_POA_Errors;
++
++typedef struct
++{
++ POA_FileServer_File servant;
++ PortableServer_POA poa;
++
++ int fd;
++}
++impl_POA_FileServer_File;
++
++typedef struct
++{
++ POA_FileServer_FileSystem servant;
++ PortableServer_POA poa;
++
++}
++impl_POA_FileServer_FileSystem;
++
++/*** Implementation stub prototypes ***/
++static void impl_Errors__destroy(impl_POA_Errors * servant,
++ CORBA_Environment * ev);
++
++static void impl_FileServer_File__destroy(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++static void
++impl_FileServer_File_Read(impl_POA_FileServer_File * servant,
++ CORBA_long count,
++ FileServer_buffer ** buf, CORBA_Environment * ev);
++
++static void
++impl_FileServer_File_Write(impl_POA_FileServer_File * servant,
++ FileServer_buffer * buf, CORBA_Environment * ev);
++
++static void
++impl_FileServer_File_Close(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static CORBA_long
++impl_FileServer_File_FileControl(impl_POA_FileServer_File * servant,
++ CORBA_long command, CORBA_Environment * ev);
++
++static FileServer_FileStatus
++impl_FileServer_File_GetStatus(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_File_ChangeDirectoryTo(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static CORBA_long
++impl_FileServer_File_Seek(impl_POA_FileServer_File * servant,
++ CORBA_long Offset,
++ FileServer_File_SeekDirection Direction,
++ CORBA_Environment * ev);
++
++static FileServer_File
++impl_FileServer_File_Duplicate(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static void impl_FileServer_FileSystem__destroy(impl_POA_FileServer_FileSystem
++ * servant,
++
++ CORBA_Environment * ev);
++static FileServer_File
++impl_FileServer_FileSystem_Open(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename, CORBA_long openFlags,
++ CORBA_short mode, CORBA_Environment * ev);
++
++static FileServer_File
++impl_FileServer_FileSystem_Create(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_short mode, CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Link(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FromPath,
++ CORBA_char * ToPath, CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Unlink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Rename(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * OldName,
++ CORBA_char * NewName,
++
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_ReadLink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Linkname,
++ CORBA_char ** LinkValue,
++ CORBA_Environment * ev);
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetStatus(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev);
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetLinkStatus(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * Filename,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_MakeDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_short mode,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_RemoveDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_Environment * ev);
++
++static CORBA_char
++ *impl_FileServer_FileSystem_ChangeDirectory(impl_POA_FileServer_FileSystem
++ * servant,
++ CORBA_char * PathName,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_MakeNode(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FileName,
++ CORBA_short Mode,
++ CORBA_long DeviceNum,
++
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Mount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * DeviceFile,
++ CORBA_char * Location,
++ CORBA_char * FSType,
++ CORBA_long Flags, CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Unmount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++
++ CORBA_Environment * ev);
++
++/*** epv structures ***/
++static PortableServer_ServantBase__epv impl_Errors_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_Errors__epv impl_Errors_epv = {
++ NULL, /* _private */
++
++};
++
++static PortableServer_ServantBase__epv impl_FileServer_File_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_FileServer_File__epv impl_FileServer_File_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_FileServer_File_Read,
++
++ (gpointer) & impl_FileServer_File_Write,
++
++ (gpointer) & impl_FileServer_File_Close,
++
++ (gpointer) & impl_FileServer_File_FileControl,
++
++ (gpointer) & impl_FileServer_File_GetStatus,
++
++ (gpointer) & impl_FileServer_File_ChangeDirectoryTo,
++
++ (gpointer) & impl_FileServer_File_Seek,
++
++ (gpointer) & impl_FileServer_File_Duplicate,
++
++};
++static POA_Errors__epv impl_FileServer_File_Errors_epv = {
++ NULL, /* _private */
++};
++static PortableServer_ServantBase__epv impl_FileServer_FileSystem_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_FileServer_FileSystem__epv impl_FileServer_FileSystem_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_FileServer_FileSystem_Open,
++
++ (gpointer) & impl_FileServer_FileSystem_Create,
++
++ (gpointer) & impl_FileServer_FileSystem_Link,
++
++ (gpointer) & impl_FileServer_FileSystem_Unlink,
++
++ (gpointer) & impl_FileServer_FileSystem_Rename,
++
++ (gpointer) & impl_FileServer_FileSystem_ReadLink,
++
++ (gpointer) & impl_FileServer_FileSystem_GetStatus,
++
++ (gpointer) & impl_FileServer_FileSystem_GetLinkStatus,
++
++ (gpointer) & impl_FileServer_FileSystem_MakeDirectory,
++
++ (gpointer) & impl_FileServer_FileSystem_RemoveDirectory,
++
++ (gpointer) & impl_FileServer_FileSystem_ChangeDirectory,
++
++ (gpointer) & impl_FileServer_FileSystem_MakeNode,
++
++ (gpointer) & impl_FileServer_FileSystem_Mount,
++
++ (gpointer) & impl_FileServer_FileSystem_Unmount,
++
++};
++static POA_Errors__epv impl_FileServer_FileSystem_Errors_epv = {
++ NULL, /* _private */
++};
++
++/*** vepv structures ***/
++static POA_Errors__vepv impl_Errors_vepv = {
++ &impl_Errors_base_epv,
++ &impl_Errors_epv,
++};
++
++static POA_FileServer_File__vepv impl_FileServer_File_vepv = {
++ &impl_FileServer_File_base_epv,
++ &impl_FileServer_File_Errors_epv,
++ &impl_FileServer_File_epv,
++};
++static POA_FileServer_FileSystem__vepv impl_FileServer_FileSystem_vepv = {
++ &impl_FileServer_FileSystem_base_epv,
++ &impl_FileServer_FileSystem_Errors_epv,
++ &impl_FileServer_FileSystem_epv,
++};
++
++/*** Stub implementations ***/
++static Errors
++impl_Errors__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ Errors retval;
++ impl_POA_Errors *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_Errors, 1);
++ newservant->servant.vepv = &impl_Errors_vepv;
++ newservant->poa = poa;
++ POA_Errors__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_Errors__destroy(impl_POA_Errors * servant, CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_Errors__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static FileServer_File
++impl_FileServer_File__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ FileServer_File retval;
++ impl_POA_FileServer_File *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_FileServer_File, 1);
++ newservant->servant.vepv = &impl_FileServer_File_vepv;
++ newservant->poa = poa;
++ newservant->fd = -1;
++
++ POA_FileServer_File__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_FileServer_File__destroy(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_FileServer_File__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static void
++impl_FileServer_File_Read(impl_POA_FileServer_File * servant,
++ CORBA_long count,
++ FileServer_buffer ** buf, CORBA_Environment * ev)
++{
++ size_t num_read;
++
++ *buf = FileServer_buffer__alloc();
++ (*buf)->_maximum = count;
++ (*buf)->_buffer = CORBA_octet_allocbuf(count);
++ (*buf)->_length = 0;
++
++ printf("File->Read(%d, char *buf)\n", count);
++
++ if (servant->fd == -1) /* Trying to read from a closed file */
++ {
++ printf("File->Read ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return;
++ }
++
++ num_read = read(servant->fd, (*buf)->_buffer, count);
++ if (num_read == -1)
++ {
++ printf("File->Read ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ return;
++ }
++
++ (*buf)->_length = num_read;
++}
++
++static void
++impl_FileServer_File_Write(impl_POA_FileServer_File * servant,
++ FileServer_buffer * buf, CORBA_Environment * ev)
++{
++ printf("UNIMP: FileServer::File::Write called and unimplemented\n");
++}
++
++static void
++impl_FileServer_File_Close(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ printf("File->Close()\n");
++
++ if (servant->fd == -1) /* This should never happen !?! */
++ {
++ printf("File->Close ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return;
++ }
++
++ close(servant->fd);
++ servant->fd = 0;
++ impl_FileServer_File__destroy(servant, ev);
++}
++
++static CORBA_long
++impl_FileServer_File_FileControl(impl_POA_FileServer_File * servant,
++ CORBA_long command, CORBA_Environment * ev)
++{
++ CORBA_long retval;
++
++ if (servant->fd == -1)
++ {
++ printf("File->FileControl ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return -1;
++ }
++
++ retval = fcntl(servant->fd, command, 0); /* FIXME arg? */
++ if (retval == -1)
++ {
++ printf("File->FileControl ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++
++FileServer_FileStatus
++stat2FileStatus(struct stat buf)
++{
++ FileServer_FileStatus retval;
++
++ retval.DeviceNum = buf.st_dev;
++ retval.InodeNum = buf.st_ino;
++ retval.Mode = buf.st_mode;
++ retval.NumLinks = buf.st_nlink;
++ retval.UserID = buf.st_uid;
++ retval.GroupID = buf.st_gid;
++ retval.DeviceType = buf.st_rdev;
++ retval.Size = buf.st_size;
++ retval.BlockSize = buf.st_blksize;
++ retval.NumBlocks = buf.st_blocks;
++ retval.AccessTime = buf.st_atime;
++ retval.ModifiedTime = buf.st_mtime;
++ retval.ChangeTime = buf.st_ctime;
++
++ return retval;
++}
++
++
++static FileServer_FileStatus
++impl_FileServer_File_GetStatus(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ FileServer_FileStatus retval;
++
++ struct stat buf;
++ int res;
++
++ if (servant->fd == -1)
++ {
++ printf("File->GetStatus ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return retval;
++ }
++
++ res = fstat(servant->fd, &buf);
++ if (res == -1)
++ {
++ printf("File->GetStatus ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ return retval;
++ }
++
++ retval = stat2FileStatus(buf);
++
++ return retval;
++}
++
++static void
++impl_FileServer_File_ChangeDirectoryTo(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_File_ChangeDirectoryTo\n");
++}
++
++static CORBA_long
++impl_FileServer_File_Seek(impl_POA_FileServer_File * servant,
++ CORBA_long Offset,
++ FileServer_File_SeekDirection Direction,
++ CORBA_Environment * ev)
++{
++ CORBA_long retval = -1;
++ int whence;
++
++ if (servant->fd == -1)
++ {
++ printf("File->Seek ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return retval;
++ }
++
++ switch (Direction)
++ {
++ case FileServer_File_FromStart :
++ whence = SEEK_SET;
++ break;
++ case FileServer_File_FromCurrent :
++ whence = SEEK_CUR;
++ break;
++ case FileServer_File_FromEnd :
++ whence = SEEK_END;
++ break;
++ default :
++ set_exception(EINVAL, ev);
++ return retval;
++ }
++
++ retval = lseek(servant->fd, Offset, whence);
++ if (retval == -1)
++ {
++ printf("File->Seek ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++static FileServer_File
++impl_FileServer_File_Duplicate(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ FileServer_File retval;
++ printf("UNIMP: impl_FileServer_File_Duplicate\n");
++ return retval;
++}
++
++static FileServer_FileSystem
++impl_FileServer_FileSystem__create(PortableServer_POA poa,
++ CORBA_Environment * ev)
++{
++ FileServer_FileSystem retval;
++ impl_POA_FileServer_FileSystem *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_FileServer_FileSystem, 1);
++ newservant->servant.vepv = &impl_FileServer_FileSystem_vepv;
++ newservant->poa = poa;
++ POA_FileServer_FileSystem__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem__destroy(impl_POA_FileServer_FileSystem * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_FileServer_FileSystem__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static FileServer_File
++impl_FileServer_FileSystem_Open(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_long openFlags,
++ CORBA_short mode, CORBA_Environment * ev)
++{
++ FileServer_File retval = CORBA_OBJECT_NIL;
++
++ impl_POA_FileServer_File *file;
++
++ printf("FileSystem->Open(%s,%x)\n", Filename, openFlags);
++
++ retval = impl_FileServer_File__create(servant->poa, ev);
++
++ file = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
++ file->fd = open(Filename, openFlags, mode);
++
++ if (file->fd == -1) {
++ printf("FileSystem->Open ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++static FileServer_File
++impl_FileServer_FileSystem_Create(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_short mode, CORBA_Environment * ev)
++{
++ FileServer_File retval = CORBA_OBJECT_NIL;
++
++ impl_POA_FileServer_File *file;
++
++ printf("FileSystem->Create(%s,%x)\n", Filename, mode);
++
++ retval = impl_FileServer_File__create(servant->poa, ev);
++
++ file = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
++ file->fd = creat(Filename, mode);
++
++ if (file->fd == -1) {
++ printf("FileSystem->Create ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem_Link(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FromPath,
++ CORBA_char * ToPath, CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Link\n");
++}
++
++static void
++impl_FileServer_FileSystem_Unlink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Unlink\n");
++}
++
++static void
++impl_FileServer_FileSystem_Rename(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * OldName,
++ CORBA_char * NewName,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Rename\n");
++}
++
++static void
++impl_FileServer_FileSystem_ReadLink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Linkname,
++ CORBA_char ** LinkValue,
++ CORBA_Environment * ev)
++{
++ char tmp[PATH_MAX + 1];
++ int res, len;
++
++ printf("FileSystem->ReadLink(%s, value)\n", Linkname);
++
++ res = readlink(Linkname, tmp, PATH_MAX);
++ if (res == -1)
++ {
++ set_exception(errno, ev);
++ return;
++ }
++
++ len = strlen(tmp);
++ *LinkValue = (char *)malloc(len * sizeof(char));
++ memcpy(*LinkValue, tmp, len);
++ (*LinkValue)[len] = '\0';
++}
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetStatus(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ FileServer_FileStatus retval;
++ struct stat buf;
++ int res;
++
++ printf("FileSystem->GetStatus(%s)\n", Filename);
++
++ res = stat(Filename, &buf);
++
++ if (res == -1)
++ {
++ printf("FileSystem->GetStatus(%s)\n", Filename);
++ set_exception(errno, ev);
++ return retval;
++ }
++
++ retval = stat2FileStatus(buf);
++
++ return retval;
++}
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetLinkStatus(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ FileServer_FileStatus retval;
++ struct stat buf;
++ int res;
++
++ printf("FileSystem->GetLinkStatus(%s)\n", Filename);
++
++ res = lstat(Filename, &buf);
++
++ if (res == -1)
++ {
++ printf("FileSystem->GetLinkStatus(%s)\n", Filename);
++ set_exception(errno, ev);
++ return retval;
++ }
++
++ retval = stat2FileStatus(buf);
++
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem_MakeDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_short mode,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_MakeDirectory\n");
++}
++
++static void
++impl_FileServer_FileSystem_RemoveDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_RemoveDirectory\n");
++}
++
++static CORBA_char *
++impl_FileServer_FileSystem_ChangeDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_Environment * ev)
++{
++ CORBA_char *retval;
++ printf("UNIMP: impl_FileServer_FileSystem_ChangeDirectory\n");
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem_MakeNode(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FileName,
++ CORBA_short Mode,
++ CORBA_long DeviceNum,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_MakeNode\n");
++}
++
++static void
++impl_FileServer_FileSystem_Mount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * DeviceFile,
++ CORBA_char * Location,
++ CORBA_char * FSType,
++ CORBA_long Flags, CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Mount: ARE YOU CRAZY!?!?\n");
++}
++
++static void
++impl_FileServer_FileSystem_Unmount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Unmount: Ha ha ha funny guy!\n");
++}
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit / FileServer
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-fileserver-server.o
++
++obj-y := FileServer-common.o FileServer-skels.o FileServer-server.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++FileServer-server.c: FileServer.h FileServer-common.c FileServer-skels.c FileServer-skelimpl.c
++
++FileServer.h FileServer-skels.c FileServer-common.c: ../FileServer.idl
++ $(ORBIT_IDL) ../FileServer.idl
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/Makefile.user linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile.user
+--- linux-2.4.1/net/korbit/modules/FileServer/server/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile.user Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = FileServer
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.c: $(PROJECT).h $(PROJECT)-skelimpl.c
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c $(PROJECT)-skelimpl.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/README linux-2.4.1-korbit/net/korbit/modules/FileServer/server/README
+--- linux-2.4.1/net/korbit/modules/FileServer/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/README Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,4 @@
++Kernel side implementation of the file server functionality.
++
++ORB: kORBit
++Status: Mostly unimplemented.
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Entries Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,4 @@
++/FileServer-server.c/1.1/Thu Feb 1 09:47:08 2001//
++/Makefile/1.1/Thu Feb 1 09:47:08 2001//
++/README/1.1/Thu Feb 1 09:47:08 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Repository Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/server-user
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Root Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/FileServer-server.c linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/FileServer-server.c
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/FileServer-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/FileServer-server.c Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,234 @@
++#include <OB/CORBA.h>
++#include <OB/Util.h>
++#include <OB/CosNaming.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++
++#include "FileServer_skel.h"
++
++static void ThrowErr() {
++ switch (errno) {
++ case 0: return;
++ case EISDIR:
++ throw Errors::IsDirectory();
++ case EPERM:
++ throw Errors::PermissionDenied();
++ case EEXIST:
++ throw Errors::FileExists();
++ case ENOENT:
++ throw Errors::FileNotFound();
++ case ENOTDIR:
++ throw Errors::IsNotDirectory();
++ case EROFS:
++ case ETXTBSY:
++ throw Errors::ReadOnlyFile();
++ case ELOOP:
++ throw Errors::RecursiveSymlink();
++ case EBUSY:
++ throw Errors::IsBusy();
++ default:
++ throw Errors::OtherError();
++ }
++}
++
++
++class FileServer_File_impl : public FileServer_File_skel {
++ int FD;
++ public:
++ FileServer_File_impl(int fd) { FD = fd; }
++
++ virtual void Read(CORBA_Long count, FileServer_buffer*& buf) {
++ errno = 0;
++ cout << "Read\n";
++ buf = new FileServer_buffer();
++ ThrowErr();
++ }
++
++ virtual void Write(const FileServer_buffer& buf) {
++ errno = 0;
++ cout << "Write\n";
++ ThrowErr();
++ }
++
++ virtual void Close() {
++ errno = 0;
++ close(FD);
++ cout << "Close()\n";
++ ThrowErr();
++ }
++
++ virtual CORBA_Long FileControl(CORBA_Long command) {
++ errno = 0;
++ cout << "filecontrol\n";
++ ThrowErr();
++ return 0;
++ }
++
++ virtual FileServer_FileStatus GetStatus() {
++ errno = 0;
++ cout << "stat\n";
++ FileServer_FileStatus Stat;
++ ThrowErr();
++ return Stat;
++ }
++
++ virtual void ChangeDirectoryTo() {
++ errno = 0;
++ cout << "ChangeDirectoryTo()\n";
++ ThrowErr();
++ }
++
++ virtual CORBA_Long Seek(CORBA_Long Offset, SeekDirection Direction) {
++ errno = 0;
++ cout << "Seek(" << Offset << ")\n";
++ ThrowErr();
++ return -1;
++ }
++
++ virtual FileServer_File_ptr Duplicate() {
++ errno = 0;
++ cout << "Duplicate!\n";
++ ThrowErr();
++ return 0;
++ }
++};
++
++
++class FileServer_impl : public FileServer_FileSystem_skel {
++ public :
++ virtual FileServer_File_ptr Open(const char* Filename,
++ CORBA_Long openFlags,
++ CORBA_Short mode) {
++ errno = 0;
++ int fd = open(Filename, openFlags, mode);
++ if (fd != -1) return new FileServer_File_impl(fd);
++ cout << "open\n";
++ ThrowErr();
++ return 0;
++ }
++
++ virtual FileServer_File_ptr Create(const char* Filename,
++ CORBA_Short mode) {
++ errno = 0;
++ cout << "create\n";
++ ThrowErr();
++ return 0;
++ }
++
++
++ virtual void Link(const char* FromPath,
++ const char* ToPath) {
++ errno = 0;
++ cout << "link\n";
++ ThrowErr();
++ }
++
++ virtual void Unlink(const char* Filename) {
++ errno = 0;
++ cout << "unlink\n";
++ ThrowErr();
++ }
++
++ virtual void Rename(const char* OldName,
++ const char* NewName) {
++ errno = 0;
++ cout << "rename\n";
++ ThrowErr();
++ }
++
++
++ virtual void ReadLink(const char* Linkname,
++ char*& LinkValue) {
++ errno = 0;
++ cout << "readlink\n";
++ ThrowErr();
++ }
++
++ virtual FileServer_FileStatus GetStatus(const char* Filename) {
++ errno = 0;
++ cout << "stat\n";
++ FileServer_FileStatus Stat;
++ ThrowErr();
++ return Stat;
++ }
++
++
++ virtual FileServer_FileStatus GetLinkStatus(const char* Filename) {
++ errno = 0;
++ cout << "lstat\n";
++ FileServer_FileStatus Stat;
++ ThrowErr();
++ return Stat;
++ }
++
++
++ virtual void MakeDirectory(const char* PathName,
++ CORBA_Short mode) {
++ errno = 0;
++ cout << "mkdir\n";
++ ThrowErr();
++ }
++
++ virtual void RemoveDirectory(const char* PathName) {
++ errno = 0;
++ cout << "rmdir\n";
++ ThrowErr();
++ }
++
++
++ virtual char* ChangeDirectory(const char* PathName) {
++ errno = 0;
++ cout << "chdir\n";
++ ThrowErr();
++ return CORBA_string_dup("hello");
++ }
++
++ virtual void MakeNode(const char* FileName,
++ CORBA_Short Mode,
++ CORBA_Long DeviceNum) {
++ errno = 0;
++ cout << "mknod\n";
++ ThrowErr();
++ }
++
++
++ virtual void Mount(const char* DeviceFile,
++ const char* Location,
++ const char* FSType,
++ CORBA_Long Flags) {
++ errno = 0;
++ cout << "Mount\n";
++ ThrowErr();
++ }
++
++ virtual void Unmount(const char* Filename) {
++ errno = 0;
++ cout << "Unmount\n";
++ ThrowErr();
++ }
++};
++
++
++int main(int argc, char* argv[]) {
++ cout << "FileServer UserSpace Server initializing" << endl;
++
++ try {
++ CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
++ CORBA_BOA_var boa = orb->BOA_init(argc, argv);
++
++ FileServer_FileSystem_var FS = new FileServer_impl();
++
++ cout << orb->object_to_string(FS) << endl;
++
++ //
++ // Run implementation
++ //
++ boa -> impl_is_ready(CORBA_ImplementationDef::_nil());
++ } catch(CORBA_SystemException& ex) {
++ OBPrintException(ex);
++ return 1;
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/Makefile Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,29 @@
++CC = CC -mt -pta
++OBDIR = /home/class/cs423/local
++IDL = $(OBDIR)/bin/idl
++CPPFLAGS = -I. -I$(OBDIR)/include
++LDFLAGS = -L$(OBDIR)/lib
++LIBS = -lCosNaming -lOB -lJTC -lsocket -lnsl -lposix4
++
++all: FileServer
++
++FileServer: FileServer.o FileServer-server.o FileServer_skel.o
++ $(CC) $(LDFLAGS) -o FileServer FileServer-server.o FileServer.o FileServer_skel.o $(LIBS)
++
++FileServer.h FileServer.cpp: ../FileServer.idl
++ rm -f FileServer.cpp FileServer.h
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ $(IDL) ../FileServer.idl
++
++FileServer_skel.cpp FileServer_skel.h: FileServer.cpp
++
++%.o: %.cpp
++ $(CC) $(CPPFLAGS) -c $<
++
++clean:
++ rm -f FileServer *.o *~
++
++realclean: clean
++ rm -f FileServer.h FileServer.cpp
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ rm -rf SunWS_cache
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/README linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/README
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/README Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++This is a user space implementation of the FileServer interface.
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Entries Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,6 @@
++/FileServer_wrapper.cpp/1.2/Thu Feb 1 09:47:09 2001//
++/FileServer_wrapper.h/1.2/Thu Feb 1 09:47:09 2001//
++/Makefile/1.1/Thu Feb 1 09:47:09 2001//
++/README/1.1/Thu Feb 1 09:47:09 2001//
++/test.c/1.2/Thu Feb 1 09:47:09 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Repository Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/wrapper
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Root Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,135 @@
++/*
++ * FileServer_wrapper.cpp
++ *
++ * We want to intercept *all* file I/O, so that once the LD_PRELOAD
++ * variable is set, everything you see is on the remote side.
++ *
++ * Needed environment variables:
++ * LD_PRELOAD - duh (what's the lib name?)
++ * KORBIT_IOR - IOR of the file servin' ORB to connect to.
++ *
++ */
++
++#include <stdio.h>
++#include <dlfcn.h>
++#include <stdarg.h>
++#include <stdlib.h>
++#include <string.h>
++#include <dirent.h>
++#include <errno.h>
++
++#include "OB/CORBA.h"
++//#include "OB/Util.h"
++//#include "OB/CosNaming.h"
++
++#include "FileServer.h"
++#include "FileServer_wrapper.h"
++
++#define DEBUG
++
++#ifdef DEBUG
++#define debugOut(X) cerr << X << flush;
++#else
++#define debugOut(X)
++#endif
++
++
++FileSystemState::FileSystemState() {
++ char *argv[] = { (char*)"/usr/bin/mkdir", 0 };
++ int argc = 1;
++
++ debugOut ("FS_wrapper: InitializeOrb(): start.\n");
++
++ /* Set 'PerformingInitialization = true'? */
++
++ orb = CORBA_ORB_init(argc, argv);
++ if (CORBA_is_nil(orb)) {
++ cerr << "Error initializing ORB!\n";
++ exit(1);
++ }
++ debugOut ("\tORB initialized successfully.\n");
++
++ const char *env = getenv("KORBIT_IOR");
++ if (!env) {
++ // This should check /proc/corba/FileServer-server also!
++ cerr << "InitializeOrb Error: KORBIT_IOR not found in environment!\n";
++ exit(1);
++ }
++
++ cout << "IOR = " << env << endl;
++
++ // WHY DO I HANG IN string_to_object??
++ CORBA_Object_var obj = orb->string_to_object(env);
++ debugOut("\tORB initialized successfully.\n");
++
++ if (CORBA_is_nil(obj)) {
++ cerr << "InitializeOrb Error: IOR is invalid: " << env << endl;
++ exit (1);
++ }
++
++ debugOut ("\tORB initialized successfully.\n");
++ try {
++ FS = FileServer_FileSystem::_narrow(obj);
++ } catch (...) {
++ cerr << "InitializeOrb Error: Got an exception from _narrow().\n";
++ exit (1);
++ }
++
++ /* Initialize my data structure 'o file descriptors. */
++
++ // Set up mapping for stdin, stdout, stderr. Set up a new fd, #4 for
++ // console/debug output
++
++ // stderr can go to console for now.
++
++ debugOut ("FS_wrapper: InitializeOrb(): finished successfully.\n");
++} /* End InitializeOrb(). */
++
++
++FileSystemState::~FileSystemState() (void) {
++} /* End CleanupOrb(). */
++
++
++void HandleException(CORBA_UserException &Exception) {
++ try {
++ throw Exception; // get the type back...
++ } catch (Errors::FileExists &) {
++ errno = EEXIST;
++ } catch (Errors::PermissionDenied &) {
++ errno = EACCES;
++ } catch (Errors::FileNotFound &) {
++ errno = ENOENT;
++ } catch (Errors::IsNotDirectory &) {
++ errno = ENOTDIR;
++ } catch (Errors::ReadOnlyFile &) {
++ errno = EROFS;
++ } catch (Errors::RecursiveSymlink &) {
++ errno = ELOOP;
++ } catch (Errors::OtherError &) {
++ errno = EIO; /* I/O error */
++ } catch (CORBA_UserException &Exception) {
++ cerr << "unknown exception occurred! \n";
++ }
++}
++
++//int open(const char *path, int oflag, mode_t mode) {
++
++
++// return -1;
++//}
++
++int mkdir(const char *pathname, mode_t mode) {
++ debugOut("FS_wrapper: mkdir(" << pathname << "): start.\n");
++
++ try {
++ FileSystemState::get().getFS()->MakeDirectory(pathname, mode);
++ } catch (CORBA_UserException &ex) {
++ HandleException(ex);
++ return -1;
++ }
++
++ // Success!
++ debugOut("FS wrapper: mkdir(): finish successfully.\n");
++ return 0;
++} // End mkdir()
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,81 @@
++// The KORBit FileServer wrapper, which is a shared library that gets
++// hit with the LD_PRELOAD action, so as to redirect all FS calls
++// out the CORBA hole.
++//
++// Note that most of these functions have the side effect of modifying errno.
++//
++#ifndef FILESERVER_WRAPPER_H
++#define FILESERVER_WRAPPER_H
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
++// This class contains all the global variables for this file. It is very
++// important that we use this mechanism so that our library is initialized as
++// early as possible, but no earlier. In particular this means that we cannot
++// be initialized before iostreams are, which we use for debugging. This scheme
++// the only way to that we are constructed and descructed on demand.
++//
++class FileSystemState {
++private:
++ FileSystemState(); // private ctor/dtor. The only way to get one of these is
++ ~FileSystemState(); // to call FileSystemState::get()
++
++ FileSystemState(const FileSystemState &); // do not implement
++ FileSystemState &operator=(const FileSystemState &); // do not implement
++
++
++ CORBA_ORB_var orb; // Global reference to the orb.
++ FileServer_FileSystem_var FS; // Global reference to FS object...
++public:
++ static FileSystemState &get() {
++ // Static objects like this are intialized the first time they are used, and
++ // destroyed when the project shuts down. This is exactly the semantics we
++ // want.
++ static FileSystemState FSS;
++ return FSS;
++ }
++
++ CORBA_ORB_var getORB() { return orb; }
++ FileServer_FileSystem_var getFS() { return FS; }
++};
++
++extern "C" {
++
++ //
++ // interface File
++ //
++ // pread, readv, pwrite, writev
++ int read(int FD, void *Buffer, size_t NumBytes);
++ int write(int FD, void *Buffer, size_t NumBytes);
++ int close(int FD);
++ // fcntl
++ // fstat
++ // fchdir
++ // seek
++ int dup(int FD);
++ int dup2(int FDFrom, int FDTo);
++
++ //
++ // interface FileSystem
++ //
++ // int open(const char *path, int oflag, mode_t mode);
++ int creat(const char *path, mode_t mode);
++
++// link
++// unlink
++// rename
++// readlink
++// stat
++// lstat
++ int mkdir(const char *Path, mode_t Mode);
++// rmdir
++ int chdir(const char *Path);
++}
++
++//
++// Local function prototypes.
++//
++
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/Makefile Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,29 @@
++CC = CC -mt -pta -g
++OBDIR = /home/class/cs423/local
++IDL = $(OBDIR)/bin/idl
++CPPFLAGS = -I. -I$(OBDIR)/include
++LDFLAGS = -L$(OBDIR)/lib -G -fPIC
++LIBS = -lCosNaming -lOB -lJTC -lsocket -lnsl -lposix4 -lCstd -lCrun
++
++all: libfswrapper.so
++
++libfswrapper.so: FileServer.o FileServer_wrapper.o
++ CC $(LDFLAGS) -o $@ FileServer_wrapper.o FileServer.o $(LIBS)
++
++FileServer.h FileServer.cpp: ../FileServer.idl
++ rm -f FileServer.cpp FileServer.h
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ $(IDL) ../FileServer.idl
++
++FileServer_skel.cpp FileServer_skel.h: FileServer.cpp
++
++%.o: %.cpp
++ $(CC) $(CPPFLAGS) -c $<
++
++clean:
++ rm -f libfswrapper.so *.o *~
++
++realclean: clean
++ rm -f FileServer.h FileServer.cpp
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ rm -rf SunWS_cache
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/README linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/README
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/README Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,5 @@
++This is a library that may be LD_PRELOAD'd to forward filesystem related calls
++through the FileServer interface.
++
++ORB: ORBacus
++Status: Mostly not working
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/test.c linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/test.c
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/test.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/test.c Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,15 @@
++#include <stdlib.h>
++#include <stdio.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++
++int main(void)
++{
++ if (mkdir("test", 0666) == -1)
++ {
++ perror ("mkdir failed because: ");
++ return (1);
++ }
++
++ return (0);
++}
+diff -urN linux-2.4.1/net/korbit/modules/Makefile linux-2.4.1-korbit/net/korbit/modules/Makefile
+--- linux-2.4.1/net/korbit/modules/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Makefile Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,15 @@
++#
++# Makefile for KORBit/modules
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CONSOLE) += Console
++subdir-$(CONFIG_CORBA_ECHO) += Echo
++subdir-$(CONFIG_CORBA_FILESERVER) += FileServer
++subdir-$(CONFIG_CORBA_CORBAFS) += CorbaFS
++subdir-$(CONFIG_CORBA_CHARDEV) += CharDev
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/Makefile.module linux-2.4.1-korbit/net/korbit/modules/Makefile.module
+--- linux-2.4.1/net/korbit/modules/Makefile.module Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Makefile.module Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,9 @@
++M_OBJS := $(O_TARGET)
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I../../.. -I../../../include -I../../../kglib -nostdinc
++
++
++ORBIT_IDL = orbit-idl
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/README linux-2.4.1-korbit/net/korbit/modules/README
+--- linux-2.4.1/net/korbit/modules/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/README Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,7 @@
++Modules included so far:
++
++CharDev : Implement Linux character device drivers
++Console : Print strings to the Linux console
++CorbaFS : Implement Linux filesystems through the VFS layer
++Echo : Testcase to test orb two-way communication
++FileServer: Access a filesystem through CORBA
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries.Log Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++A D/client////
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Repository Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/UserFS
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Root linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Root
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Root Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Entries Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Repository Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/UserFS/client
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Root Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/orb/CVS/Entries linux-2.4.1-korbit/net/korbit/orb/CVS/Entries
+--- linux-2.4.1/net/korbit/orb/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/CVS/Entries Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,60 @@
++/Makefile/1.6/Thu Feb 1 09:47:10 2001//
++/allocator-defs.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/allocators.c/1.2/Thu Feb 1 09:47:10 2001//
++/allocators.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/cdr.c/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/cdr.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/corba_any.c/1.3/Thu Feb 1 09:47:10 2001//
++/corba_any.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/corba_any_proto.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_any_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_basic_sequences_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_context.c/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_context.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_env.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_env_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_object.c/1.7/Thu Feb 1 09:47:11 2001//
++/corba_object.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_object_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_orb.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_orb_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_portableserver.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_portableserver_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_sequences.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/corba_sequences_type.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/corba_typecode.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/corba_typecode_type.h/1.3/Thu Feb 1 09:47:12 2001//
++/dii.c/1.2/Thu Feb 1 09:47:12 2001//
++/dii.h/1.2/Thu Feb 1 09:47:12 2001//
++/env.c/1.2/Thu Feb 1 09:47:12 2001//
++/env.h/1.2/Thu Feb 1 09:47:12 2001//
++/genrand.c/1.4/Thu Feb 1 09:47:12 2001//
++/genrand.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/iop.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/ir.c/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/ir.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/options.c/1.2/Thu Feb 1 09:47:12 2001//
++/options.h/1.2/Thu Feb 1 09:47:13 2001//
++/orb.c/1.13/Thu Feb 1 09:47:13 2001//
++/orb.h/1.2/Thu Feb 1 09:47:13 2001//
++/orbit.c/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit.h/1.2/Thu Feb 1 09:47:13 2001//
++/orbit.h.in/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_config.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_object.c/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_object.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_object_type.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_poa.c/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_poa.h/1.3/Thu Feb 1 09:47:13 2001//
++/orbit_poa_type.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_typecode.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/orbit_typecode.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/orbit_types.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/poa.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/poa.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/sequences.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/sequences.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/server.c/1.5/Thu Feb 1 09:47:14 2001//
++/typecode.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/typecode.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++D
+diff -urN linux-2.4.1/net/korbit/orb/CVS/Repository linux-2.4.1-korbit/net/korbit/orb/CVS/Repository
+--- linux-2.4.1/net/korbit/orb/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/CVS/Repository Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/orb
+diff -urN linux-2.4.1/net/korbit/orb/CVS/Root linux-2.4.1-korbit/net/korbit/orb/CVS/Root
+--- linux-2.4.1/net/korbit/orb/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/CVS/Root Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/orb/Makefile linux-2.4.1-korbit/net/korbit/orb/Makefile
+--- linux-2.4.1/net/korbit/orb/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/Makefile Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,25 @@
++#
++# Makefile for KORBit/orb
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .o file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := orblib.o
++
++#obj-m := $(O_TARGET)
++obj-y := allocators.o options.o poa.o \
++ cdr.o env.o orb.o sequences.o \
++ corba_any.o genrand.o orbit.o server.o \
++ corba_context.o orbit_object.o typecode.o \
++ corba_object.o orbit_poa.o \
++ dii.o ir.o orbit_typecode.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I.. -I../include -I../kglib -I../ORBitutil -nostdinc \
++ -DORBit_SYSRC=\"/etc/orbitrc\" \
++ -DORBIT_MAJOR_VERSION="0" -DORBIT_MINOR_VERSION="5" -DORBIT_MICRO_VERSION="3" -DORBIT_VERSION=\"0.5.3\"
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/orb/allocator-defs.h linux-2.4.1-korbit/net/korbit/orb/allocator-defs.h
+--- linux-2.4.1/net/korbit/orb/allocator-defs.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/allocator-defs.h Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,40 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* By Elliot Lee. Copyright (c) 1998 Red Hat Software */
++
++
++/********************************************************
++ * Never include this header file directly. Only allocators.[ch]
++ * should do this
++ ********************************************************/
++
++/* Macro crap */
++
++#ifdef ALLOCATOR_DEFINITION
++
++#define ORBIT_DEFINE_CHUNK(x, xsize) \
++DEFINE_LOCK(x##_allocator); \
++GMemChunk *x##_allocator = NULL
++
++#elif defined(ALLOCATOR_INITIALIZATION)
++
++#define ORBIT_DEFINE_CHUNK(x, xsize) INIT_LOCK(x##_allocator); \
++x##_allocator = g_mem_chunk_new(#x, (xsize), \
++(xsize) * ORBIT_CHUNKS_PREALLOC, G_ALLOC_AND_FREE)
++
++#else
++
++#define ORBIT_DEFINE_CHUNK(x, xsize) \
++EXTERN_LOCK(x##_allocator); \
++extern GMemChunk *x##_allocator
++
++#endif
++
++/*****************************************************
++ * Here's where we define the actual chunks that are used
++ *****************************************************/
++ORBIT_DEFINE_CHUNK(CORBA_TypeCode, sizeof(struct CORBA_TypeCode_struct));
++ORBIT_DEFINE_CHUNK(CORBA_Object, sizeof(struct CORBA_Object_struct));
++ORBIT_DEFINE_CHUNK(CORBA_NVList, sizeof(struct CORBA_NVList_type));
++
++#undef ORBIT_DEFINE_CHUNK
+diff -urN linux-2.4.1/net/korbit/orb/allocators.c linux-2.4.1-korbit/net/korbit/orb/allocators.c
+--- linux-2.4.1/net/korbit/orb/allocators.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/allocators.c Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,241 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* By Elliot Lee. Copyright (c) 1998 Red Hat Software */
++
++#include "orbit.h"
++
++#if 0
++#define CORBA_Object_release(x, y) ({ g_message(__FILE__ ":%d Releasing object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_release(x, y); })
++#define CORBA_Object_duplicate(x, y) ({ g_message(__FILE__ ":%d Duping object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_duplicate(x, y); })
++#endif
++
++/* The memory chunk stuff */
++
++#define ALLOCATOR_DEFINITION
++#include "allocator-defs.h"
++#undef ALLOCATOR_DEFINITION
++
++void
++ORBit_chunks_init(void)
++{
++#define ALLOCATOR_INITIALIZATION
++#include "allocator-defs.h"
++#undef ALLOCATOR_INTIALIZATION
++}
++
++gpointer
++ORBit_chunk_alloc(GMemChunk *chunk,
++ PARAM_LOCK(chunk))
++{
++ gpointer retval;
++
++ GET_LOCK(chunk);
++ retval = g_mem_chunk_alloc(chunk);
++ RELEASE_LOCK(chunk);
++
++ return retval;
++}
++
++void
++ORBit_chunk_free(GMemChunk *chunk,
++ PARAM_LOCK(chunk),
++ gpointer mem)
++{
++ GET_LOCK(chunk);
++ g_mem_chunk_free(chunk, mem);
++ RELEASE_LOCK(chunk);
++}
++
++/* end memory chunk routines */
++
++/****************************************************************/
++
++/************* begin funky memory alloc/free system */
++
++/****** functions */
++
++gpointer ORBit_alloc(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data)
++{
++ return ORBit_alloc_2(block_size, freefunc, func_data, 0);
++}
++
++gpointer
++ORBit_alloc_2(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data,
++ size_t before_size)
++{
++ ORBit_mem_info *block;
++
++ if(block_size == 0) return NULL;
++
++ block = (ORBit_mem_info *)((char *)
++ g_malloc(block_size + sizeof(ORBit_mem_info) + before_size)
++ + before_size);
++
++#ifdef ORBIT_DEBUG
++ block->magic = 0xdeadbeef;
++#endif
++ block->free = freefunc;
++ block->func_data = func_data;
++
++ return MEMINFO_TO_PTR(block);
++}
++
++/*
++ ORBit_free
++ ----------
++
++ Frees a corba primitive type.
++
++ mem = pointer to the memory block. (must have a preceeding pointer to a meminfo block)
++
++ 1)obtains a pointer to the preceeding meminfo structure
++ 2)Uses the meminfo structure to find the number of elements in the memory block
++ 3)iterates through the memory block, calling the free function for each item.
++
++ */
++
++void
++ORBit_free(gpointer mem, CORBA_boolean free_strings)
++{
++ ORBit_mem_info *block;
++
++ if(!mem)
++ return;
++
++ block = PTR_TO_MEMINFO(mem);
++
++#ifdef ORBIT_DEBUG
++ g_assert(block->magic == 0xdeadbeef);
++#endif
++
++ if(block->free) {
++ int i;
++ gpointer x;
++ gpointer my_data;
++
++ if((gpointer)block->free == (gpointer)ORBit_free_via_TypeCode)
++ my_data = ((guchar *)block) - sizeof(CORBA_TypeCode);
++ else
++ my_data = NULL;
++
++#ifdef ORBIT_DEBUG
++ if(block->func_data == NULL)
++ g_warning("block with freefunc %p has no items", block->free);
++#endif
++
++ for(i = 0, x = mem; i < (gulong)block->func_data; i++)
++ x = block->free(x, my_data, free_strings);
++
++ if((gpointer)block->free == (gpointer)ORBit_free_via_TypeCode)
++ /* ((guchar *)block) -= sizeof(CORBA_TypeCode); */
++ block = (ORBit_mem_info *)
++ (((guchar *)block) - sizeof(CORBA_TypeCode));
++ g_free(block);
++ } else
++ g_free(block);
++}
++
++/******************************************************************/
++/* These aren't currently used... */
++
++gpointer
++ORBit_free_via_TypeCode(gpointer mem, gpointer tcp, gboolean free_strings)
++{
++ CORBA_TypeCode tc = *(CORBA_TypeCode *)tcp, subtc;
++ int i;
++ guchar *retval = NULL;
++
++ switch(tc->kind) {
++ case CORBA_tk_any:
++ {
++ CORBA_any *anyval = mem;
++ if(anyval->_release)
++ CORBA_free(anyval->_value);
++ retval = (guchar *)(anyval + 1);
++ }
++ break;
++ case CORBA_tk_TypeCode:
++ case CORBA_tk_objref:
++ {
++ CORBA_Object_release(*(CORBA_Object *)mem, NULL);
++
++ retval = (guchar *)mem + sizeof(CORBA_Object);
++ }
++ break;
++ case CORBA_tk_Principal:
++ {
++ CORBA_Principal *pval = mem;
++ if(pval->_release)
++ CORBA_free(pval->_buffer);
++ retval = (guchar *)(pval + 1);
++ }
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ mem = ALIGN_ADDRESS(mem, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc->subtypes[i], NULL);
++ mem = ORBit_free_via_TypeCode(mem, &subtc,
++ free_strings);
++ }
++ retval = mem;
++ break;
++ case CORBA_tk_union:
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate(
++ (CORBA_Object)ORBit_get_union_tag(tc, &mem, TRUE), NULL);
++ {
++ int sz = 0;
++ int al = 1;
++ for(i = 0; i < tc->sub_parts; i++) {
++ al = MAX(al, ORBit_find_alignment(tc->subtypes[i]));
++ sz = MAX(sz, ORBit_gather_alloc_info(tc->subtypes[i]));
++ }
++ mem = ALIGN_ADDRESS(mem, al);
++ ORBit_free_via_TypeCode(mem, &subtc, free_strings);
++ /* the end of the body (subtc) may not be the
++ * same as the end of the union */
++ retval = mem + sz;
++ }
++ break;
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ if(free_strings)
++ CORBA_free(*(char **)mem);
++ retval = (guchar *)mem + sizeof(char *);
++ break;
++ case CORBA_tk_sequence:
++ {
++ CORBA_sequence_octet *pval = mem;
++ if(pval->_release)
++ CORBA_free(pval->_buffer);
++
++ retval = (guchar *)mem + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_array:
++ for(i = 0; i < tc->length; i++) {
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc->subtypes[0], NULL);
++ mem = ORBit_free_via_TypeCode(mem, &subtc,
++ free_strings);
++ }
++ retval = mem;
++ break;
++ case CORBA_tk_alias:
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc->subtypes[0], NULL);
++ retval = ORBit_free_via_TypeCode(mem, &subtc, free_strings);
++ break;
++ default:
++ retval = ((guchar *)mem) + ORBit_gather_alloc_info(tc);
++ break;
++ }
++
++ CORBA_Object_release((CORBA_Object)tc, NULL);
++
++ return (gpointer)retval;
++}
+diff -urN linux-2.4.1/net/korbit/orb/allocators.h linux-2.4.1-korbit/net/korbit/orb/allocators.h
+--- linux-2.4.1/net/korbit/orb/allocators.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/allocators.h Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,61 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* By Elliot Lee. Copyright (c) 1998 Red Hat Software */
++
++#ifndef ALLOCATORS_H
++#define ALLOCATORS_H 1
++
++#include <orb/orbit.h>
++
++#include <orb/allocator-defs.h>
++
++#define ORBIT_CHUNK_ALLOC(typename) \
++ORBit_chunk_alloc(typename##_allocator, LOCK_NAME(typename##_allocator))
++
++#define ORBIT_CHUNK_FREE(typename, mem) \
++ORBit_chunk_free(typename##_allocator, LOCK_NAME(typename##_allocator), (mem))
++
++void ORBit_chunks_init(void);
++
++gpointer ORBit_chunk_alloc(GMemChunk *chunk,
++ PARAM_LOCK(chunk_lock));
++
++void ORBit_chunk_free(GMemChunk *chunk,
++ PARAM_LOCK(chunk_lock),
++ gpointer mem);
++
++/* General memory allocation routines */
++
++#define PTR_TO_MEMINFO(x) (((ORBit_mem_info *)(x)) - 1)
++#define MEMINFO_TO_PTR(x) ((gpointer)((x) + 1))
++
++typedef gpointer (*ORBit_free_childvals)(gpointer mem,
++ gpointer func_data,
++ CORBA_boolean free_strings);
++
++typedef struct {
++#ifdef ORBIT_DEBUG
++ gulong magic;
++#endif
++ /* If this routine returns FALSE, it indicates that it already free'd
++ the memory block itself */
++ ORBit_free_childvals free; /* function pointer to free function */
++ gpointer func_data;
++} ORBit_mem_info;
++
++gpointer ORBit_alloc(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data);
++gpointer ORBit_alloc_2(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data,
++ size_t before_size);
++
++void ORBit_free(gpointer mem, CORBA_boolean free_strings);
++
++/* internal stuff */
++gpointer ORBit_free_via_TypeCode(gpointer mem,
++ gpointer tcp,
++ gboolean free_strings);
++
++#endif /* ALLOCATORS_H */
+diff -urN linux-2.4.1/net/korbit/orb/cdr.c linux-2.4.1-korbit/net/korbit/orb/cdr.c
+--- linux-2.4.1/net/korbit/orb/cdr.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/cdr.c Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,643 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#include "config.h"
++#include "../IIOP/iiop-endianP.h"
++#include <stdlib.h>
++#include <string.h>
++#include <ctype.h>
++#include <assert.h>
++
++#include "orbit.h"
++
++#define CDR_GROW_AMOUNT 128
++
++static CORBA_boolean CDR_buffer_grow(CDR_Codec *codec, const unsigned int growth)
++{
++ unsigned int real_growth;
++ div_t divvy;
++
++ if(codec->release_buffer) {
++ divvy=div(growth, CDR_GROW_AMOUNT);
++ real_growth=CDR_GROW_AMOUNT * (divvy.quot+1);
++
++ codec->buffer=(CORBA_octet *)g_realloc(codec->buffer,
++ codec->buf_len
++ +real_growth);
++ }
++
++ return CORBA_TRUE;
++}
++
++static void CDR_buffer_puts(CDR_Codec *codec, const void *data, const unsigned int len)
++{
++ if(codec->wptr+len > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, len);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ memcpy(&codec->buffer[codec->wptr], data, len);
++ codec->wptr+=len;
++}
++
++CORBA_boolean CDR_buffer_gets(CDR_Codec *codec, void *dest, const unsigned int len)
++{
++ if(codec->rptr+len > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_gets: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ memcpy(dest, &codec->buffer[codec->rptr], len);
++ codec->rptr+=len;
++
++ return(CORBA_TRUE);
++}
++
++static void CDR_buffer_put(CDR_Codec *codec, void *datum)
++{
++ if(codec->wptr+1 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, 1);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ codec->buffer[codec->wptr++]=*(unsigned char *)datum;
++}
++
++static CORBA_boolean CDR_buffer_get(CDR_Codec *codec, void *dest)
++{
++ if(codec->rptr+1 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ *(CORBA_octet *)dest=codec->buffer[codec->rptr++];
++ return(CORBA_TRUE);
++}
++
++#ifdef lame_slow_code
++static void CDR_buffer_put2(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+1)&~1L);
++
++ if(align+2 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+2-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++}
++
++static CORBA_boolean CDR_buffer_get2(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+1)&~1L);
++
++ if(align+2 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get2: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++
++static void CDR_buffer_put4(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+3)&~3L);
++
++ if(align+4 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+4-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[2];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[3];
++}
++
++static CORBA_boolean CDR_buffer_get4(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+3)&~3L);
++
++ if(align+4 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get4: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[2]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[3]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++
++static void CDR_buffer_put8(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+7)&~7L);
++
++ if(align+8 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+8-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[2];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[3];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[4];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[5];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[6];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[7];
++}
++
++#if 0
++static CORBA_boolean CDR_buffer_get8(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+7)&~7L);
++
++ if(align+8 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get8: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[2]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[3]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[4]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[5]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[6]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[7]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++#endif
++
++static void CDR_buffer_put16(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+15)&~15L);
++
++ if(align+16 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+16-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[2];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[3];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[4];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[5];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[6];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[7];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[8];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[9];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[10];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[11];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[12];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[13];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[14];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[15];
++}
++
++#if 0
++static CORBA_boolean CDR_buffer_get16(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+15)&~15L);
++
++ if(align+16 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get16: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[2]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[3]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[4]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[5]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[6]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[7]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[8]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[9]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[10]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[11]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[12]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[13]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[14]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[15]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++#endif
++#endif /* lame_slow_code */
++
++#define CDR_buffer_put2(codec, datum) CDR_buffer_putn(codec, datum, 2)
++#define CDR_buffer_put4(codec, datum) CDR_buffer_putn(codec, datum, 4)
++#define CDR_buffer_put8(codec, datum) CDR_buffer_putn(codec, datum, 8)
++#define CDR_buffer_put16(codec, datum) CDR_buffer_putn(codec, datum, 16)
++#define CDR_buffer_get2(codec, dest) CDR_buffer_getn(codec, dest, 2)
++#define CDR_buffer_get4(codec, dest) CDR_buffer_getn(codec, dest, 4)
++#define CDR_buffer_get8(codec, dest) CDR_buffer_getn(codec, dest, 8)
++#define CDR_buffer_get16(codec, dest) CDR_buffer_getn(codec, dest, 16)
++
++static CORBA_boolean
++CDR_buffer_getn(CDR_Codec *codec, void *dest, int bsize)
++{
++ codec->rptr = (unsigned long)ALIGN_ADDRESS(codec->rptr, bsize);
++ if(codec->host_endian==codec->data_endian)
++ memcpy(dest, codec->buffer + codec->rptr, bsize);
++ else
++ iiop_byteswap(dest, codec->buffer + codec->rptr, bsize);
++ codec->rptr += bsize;
++
++ return CORBA_TRUE;
++}
++
++static CORBA_boolean
++CDR_buffer_putn(CDR_Codec *codec, void *datum, int bsize)
++{
++ codec->wptr = (unsigned long)ALIGN_ADDRESS(codec->wptr, bsize);
++ if(codec->host_endian==codec->data_endian)
++ memcpy(codec->buffer + codec->wptr, datum, bsize);
++ else
++ iiop_byteswap(codec->buffer + codec->wptr, datum, bsize);
++ codec->wptr += bsize;
++
++ return CORBA_TRUE;
++}
++
++#define CDR_swap2(d,s) iiop_byteswap((d), (s), 2)
++#define CDR_swap4(d,s) iiop_byteswap((d), (s), 4)
++#define CDR_swap8(d,s) iiop_byteswap((d), (s), 8)
++#define CDR_swap16(d,s) iiop_byteswap((d), (s), 16)
++
++#ifdef lame_slow_code
++static void CDR_swap2(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[0];
++}
++
++static void CDR_swap4(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[3];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[2];
++ ((CORBA_octet *)d)[2]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[3]=((CORBA_octet *)s)[0];
++}
++
++static void CDR_swap8(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[7];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[6];
++ ((CORBA_octet *)d)[2]=((CORBA_octet *)s)[5];
++ ((CORBA_octet *)d)[3]=((CORBA_octet *)s)[4];
++ ((CORBA_octet *)d)[4]=((CORBA_octet *)s)[3];
++ ((CORBA_octet *)d)[5]=((CORBA_octet *)s)[2];
++ ((CORBA_octet *)d)[6]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[7]=((CORBA_octet *)s)[0];
++}
++
++static void CDR_swap16(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[15];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[14];
++ ((CORBA_octet *)d)[2]=((CORBA_octet *)s)[13];
++ ((CORBA_octet *)d)[3]=((CORBA_octet *)s)[12];
++ ((CORBA_octet *)d)[4]=((CORBA_octet *)s)[11];
++ ((CORBA_octet *)d)[5]=((CORBA_octet *)s)[10];
++ ((CORBA_octet *)d)[6]=((CORBA_octet *)s)[9];
++ ((CORBA_octet *)d)[7]=((CORBA_octet *)s)[8];
++ ((CORBA_octet *)d)[8]=((CORBA_octet *)s)[7];
++ ((CORBA_octet *)d)[9]=((CORBA_octet *)s)[6];
++ ((CORBA_octet *)d)[10]=((CORBA_octet *)s)[5];
++ ((CORBA_octet *)d)[11]=((CORBA_octet *)s)[4];
++ ((CORBA_octet *)d)[12]=((CORBA_octet *)s)[3];
++ ((CORBA_octet *)d)[13]=((CORBA_octet *)s)[2];
++ ((CORBA_octet *)d)[14]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[15]=((CORBA_octet *)s)[0];
++}
++#endif
++
++
++void CDR_put_short(CDR_Codec *codec, CORBA_short s)
++{
++ CDR_buffer_put2(codec, &s);
++}
++
++CORBA_boolean CDR_get_short(CDR_Codec *codec, CORBA_short *s)
++{
++ return CDR_buffer_get2(codec, s);
++}
++
++void CDR_put_ushort(CDR_Codec *codec, CORBA_unsigned_short us)
++{
++ CDR_buffer_put2(codec, &us);
++}
++
++CORBA_boolean CDR_get_ushort(CDR_Codec *codec, CORBA_unsigned_short *us)
++{
++ return CDR_buffer_get2(codec, us);
++}
++
++void CDR_put_long(CDR_Codec *codec, CORBA_long l)
++{
++ CDR_buffer_put4(codec, &l);
++}
++
++CORBA_boolean CDR_get_long(CDR_Codec *codec, CORBA_long *l)
++{
++ return CDR_buffer_get4(codec, l);
++}
++
++void CDR_put_ulong(CDR_Codec *codec, CORBA_unsigned_long ul)
++{
++ CDR_buffer_put4(codec, &ul);
++}
++
++CORBA_boolean CDR_get_ulong(CDR_Codec *codec, CORBA_unsigned_long *ul)
++{
++ return CDR_buffer_get4(codec, ul);
++}
++
++#ifdef HAVE_CORBA_LONG_LONG
++CORBA_boolean CDR_get_long_long(CDR_Codec *codec, CORBA_long_long *ul)
++{
++ return CDR_buffer_get8(codec, ul);
++}
++
++void CDR_put_long_long(CDR_Codec *codec, CORBA_long_long ll)
++{
++ CDR_buffer_put8(codec, &ll);
++}
++
++void CDR_put_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long ll)
++{
++ CDR_buffer_put8(codec, &ll);
++}
++
++CORBA_boolean CDR_get_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long *ull)
++{
++ return CDR_buffer_get8(codec, ull);
++}
++#endif
++
++void CDR_put_float(CDR_Codec *codec, CORBA_float f)
++{
++ CDR_buffer_put4(codec, &f);
++}
++
++void CDR_put_double(CDR_Codec *codec, CORBA_double d)
++{
++ CDR_buffer_put8(codec, &d);
++}
++
++void CDR_put_long_double(CDR_Codec *codec, CORBA_long_double ld)
++{
++ CDR_buffer_put16(codec, &ld);
++}
++
++void CDR_put_octet(CDR_Codec *codec, CORBA_octet datum)
++{
++ CDR_buffer_put(codec, &datum);
++}
++
++CORBA_boolean CDR_get_octet(CDR_Codec *codec, CORBA_octet *datum)
++{
++ return(CDR_buffer_get(codec, datum));
++}
++
++void CDR_put_octets(CDR_Codec *codec, void *data, unsigned long len)
++{
++ CDR_buffer_puts(codec, data, len);
++}
++
++void CDR_put_char(CDR_Codec *codec, CORBA_char c)
++{
++ CDR_buffer_put(codec, &c);
++}
++
++CORBA_boolean CDR_get_char(CDR_Codec *codec, CORBA_char *c)
++{
++ return CDR_buffer_get(codec, c);
++}
++
++void CDR_put_boolean(CDR_Codec *codec, CORBA_boolean datum)
++{
++ datum = datum&&1;
++ CDR_buffer_put(codec, &datum);
++}
++
++CORBA_boolean CDR_get_boolean(CDR_Codec *codec, CORBA_boolean *b)
++{
++ return CDR_buffer_get(codec, b);
++}
++
++void CDR_put_string(CDR_Codec *codec, const char *str)
++{
++ unsigned int len;
++
++ len=strlen(str)+1;
++
++ CDR_put_ulong(codec, len);
++ CDR_buffer_puts(codec, str, len);
++}
++
++CORBA_boolean CDR_get_string_static(CDR_Codec *codec,
++ CORBA_char **str)
++{
++ CORBA_unsigned_long len;
++
++ if(CDR_get_ulong(codec, &len)==CORBA_FALSE)
++ return CORBA_FALSE;
++
++ if((codec->rptr + len) > codec->buf_len)
++ return CORBA_FALSE;
++
++ *str = ((CORBA_char *)codec->buffer) + codec->rptr;
++
++ codec->rptr += len;
++
++ return CORBA_TRUE;
++}
++
++CORBA_boolean CDR_get_string(CDR_Codec *codec, CORBA_char **str)
++{
++ CORBA_unsigned_long len;
++
++ if(CDR_get_ulong(codec, &len)==CORBA_FALSE)
++ return(CORBA_FALSE);
++
++ if(len==0)
++ return(CORBA_FALSE);
++
++ *str=g_new(CORBA_char, len);
++
++ if(CDR_buffer_gets(codec, *str, len)==CORBA_FALSE) {
++ g_free(*str);
++ return(CORBA_FALSE);
++ }
++
++ if((*str)[len-1]!='\0') {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Notice, "CDR_get_string: string was not NULL-terminated, terminating it now\n");
++ (*str)[len-1]='\0';
++ }
++
++ return(CORBA_TRUE);
++}
++
++CORBA_boolean CDR_get_seq_begin(CDR_Codec *codec, CORBA_unsigned_long *ul)
++{
++ return(CDR_get_ulong(codec, ul));
++}
++
++CDR_Codec *CDR_codec_init_static(CDR_Codec *codec)
++{
++ memset(codec, 0, sizeof(CDR_Codec));
++
++ codec->host_endian = FLAG_ENDIANNESS;
++
++ return codec;
++}
++
++CDR_Codec *CDR_codec_init(void)
++{
++ CDR_Codec *new;
++
++ new=g_new0(CDR_Codec, 1);
++ CDR_codec_init_static(new);
++ new->release_buffer = CORBA_TRUE;
++
++ return(new);
++}
++
++void CDR_codec_free(CDR_Codec *codec)
++{
++ if(codec->release_buffer)
++ g_free(codec->buffer);
++
++ g_free(codec);
++}
+diff -urN linux-2.4.1/net/korbit/orb/cdr.h linux-2.4.1-korbit/net/korbit/orb/cdr.h
+--- linux-2.4.1/net/korbit/orb/cdr.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/cdr.h Thu Feb 1 16:22:12 2001
+@@ -0,0 +1,83 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CDR_H_
++#define _ORBIT_CDR_H_
++
++#include "orbit_types.h"
++
++typedef enum {
++ BigEndian=0,
++ LittleEndian=1
++} CDR_Endianness;
++
++typedef struct {
++ CDR_Endianness host_endian;
++ CDR_Endianness data_endian;
++ CORBA_octet *buffer;
++ unsigned int buf_len;
++ unsigned int wptr, rptr;
++ CORBA_boolean readonly;
++ CORBA_boolean release_buffer;
++} CDR_Codec;
++
++#define HEXDIGIT(c) (isdigit((guchar)(c))?(c)-'0':tolower((guchar)(c))-'a'+10)
++#define HEXOCTET(a,b) ((HEXDIGIT((a)) << 4) | HEXDIGIT((b)))
++
++extern CDR_Codec *CDR_codec_init(void);
++extern CDR_Codec *CDR_codec_init_static(CDR_Codec *codec);
++extern void CDR_codec_free(CDR_Codec *);
++
++extern void CDR_put_short(CDR_Codec *codec, CORBA_short s);
++extern void CDR_put_ushort(CDR_Codec *codec, CORBA_unsigned_short us);
++extern void CDR_put_long(CDR_Codec *codec, CORBA_long l);
++extern void CDR_put_ulong(CDR_Codec *codec, CORBA_unsigned_long ul);
++#ifdef HAVE_CORBA_LONG_LONG
++extern void CDR_put_long_long(CDR_Codec *codec, CORBA_long_long ll);
++extern void CDR_put_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long ull);
++extern CORBA_boolean CDR_get_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long *ul);
++extern CORBA_boolean CDR_get_long_long(CDR_Codec *codec, CORBA_long_long *ul);
++#endif
++extern void CDR_put_float(CDR_Codec *codec, CORBA_float f);
++extern void CDR_put_double(CDR_Codec *codec, CORBA_double d);
++extern void CDR_put_long_double(CDR_Codec *codec, CORBA_long_double ld);
++extern void CDR_put_octet(CDR_Codec *codec, CORBA_octet datum);
++extern void CDR_put_octets(CDR_Codec *codec, void *data, unsigned long len);
++extern void CDR_put_char(CDR_Codec *codec, CORBA_char c);
++extern void CDR_put_boolean(CDR_Codec *codec, CORBA_boolean datum);
++extern void CDR_put_string(CDR_Codec *codec, const char *str);
++extern CORBA_boolean CDR_buffer_gets(CDR_Codec *codec, void *dest, const unsigned int len);
++extern CORBA_boolean CDR_get_short(CDR_Codec *codec, CORBA_short *us);
++extern CORBA_boolean CDR_get_ushort(CDR_Codec *codec, CORBA_unsigned_short *us);
++extern CORBA_boolean CDR_get_long(CDR_Codec *codec, CORBA_long *l);
++extern CORBA_boolean CDR_get_ulong(CDR_Codec *codec, CORBA_unsigned_long *ul);
++extern CORBA_boolean CDR_get_octet(CDR_Codec *codec, CORBA_octet *datum);
++extern CORBA_boolean CDR_get_boolean(CDR_Codec *codec, CORBA_boolean *b);
++extern CORBA_boolean CDR_get_char(CDR_Codec *codec, CORBA_char *c);
++extern CORBA_boolean CDR_get_string(CDR_Codec *codec, CORBA_char **str);
++extern CORBA_boolean CDR_get_string_static(CDR_Codec *codec, CORBA_char **str);
++extern CORBA_boolean CDR_get_seq_begin(CDR_Codec *codec, CORBA_unsigned_long *ul);
++
++#endif /* !_ORBIT_CDR_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_any.c linux-2.4.1-korbit/net/korbit/orb/corba_any.c
+--- linux-2.4.1/net/korbit/orb/corba_any.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any.c Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,914 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#include <config.h>
++#include <IIOP/IIOP.h>
++#include "orbit.h"
++
++#if 0
++#define CORBA_Object_release(x, y) ({ g_message(__FILE__ ":%d Releasing object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_release(x, y); })
++#define CORBA_Object_duplicate(x, y) ({ g_message(__FILE__ ":%d Duping object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_duplicate(x, y); })
++#endif
++
++gint
++ORBit_find_alignment(CORBA_TypeCode tc)
++{
++ gint retval = 1;
++ int i;
++
++ switch(tc->kind) {
++ case CORBA_tk_union:
++ retval = MAX(retval, ORBit_find_alignment(tc->discriminator));
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++#if ALIGNOF_CORBA_STRUCT > 1
++ retval = MAX(retval, ALIGNOF_CORBA_STRUCT);
++#endif
++ for(i = 0; i < tc->sub_parts; i++)
++ retval = MAX(retval, ORBit_find_alignment(tc->subtypes[i]));
++ return retval;
++ case CORBA_tk_ulong:
++ case CORBA_tk_long:
++ case CORBA_tk_enum:
++ return ALIGNOF_CORBA_LONG;
++ case CORBA_tk_ushort:
++ case CORBA_tk_short:
++ case CORBA_tk_wchar:
++ return ALIGNOF_CORBA_SHORT;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ return ALIGNOF_CORBA_LONG_LONG;
++ case CORBA_tk_longdouble:
++ return ALIGNOF_CORBA_LONG_DOUBLE;
++ case CORBA_tk_float:
++ return ALIGNOF_CORBA_FLOAT;
++ case CORBA_tk_double:
++ return ALIGNOF_CORBA_DOUBLE;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ return ALIGNOF_CORBA_CHAR;
++ case CORBA_tk_string:
++ case CORBA_tk_wstring:
++ case CORBA_tk_TypeCode:
++ case CORBA_tk_objref:
++ return ALIGNOF_CORBA_POINTER;
++ case CORBA_tk_sequence:
++ case CORBA_tk_any:
++ return MAX(MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_STRUCT), ALIGNOF_CORBA_POINTER);
++ case CORBA_tk_array:
++ case CORBA_tk_alias:
++ return ORBit_find_alignment(tc->subtypes[0]);
++ case CORBA_tk_fixed:
++ return MAX(ALIGNOF_CORBA_SHORT, ALIGNOF_CORBA_STRUCT);
++ default:
++ return 1;
++ }
++}
++
++static void
++ORBit_marshal_value(GIOPSendBuffer *buf,
++ gpointer *val,
++ CORBA_TypeCode tc,
++ ORBit_marshal_value_info *mi)
++{
++ CORBA_unsigned_long i, ulval;
++ gpointer subval;
++ ORBit_marshal_value_info submi;
++
++#if 0
++ g_message("Marshalling a %d value from %#x to offset %d",
++ tc->kind, (gulong)*val,
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size);
++#endif
++
++ switch(tc->kind) {
++ case CORBA_tk_wchar:
++ case CORBA_tk_ushort:
++ case CORBA_tk_short:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_SHORT);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_short));
++ *val = ((guchar *)*val) + sizeof(CORBA_short);
++ break;
++ case CORBA_tk_enum:
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_long));
++ *val = ((guchar *)*val) + sizeof(CORBA_long);
++ break;
++ case CORBA_tk_float:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_FLOAT);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_float));
++ *val = ((guchar *)*val) + sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_DOUBLE);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_double));
++ *val = ((guchar *)*val) + sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_octet));
++ *val = ((guchar *)*val) + sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT, ALIGNOF_CORBA_POINTER));
++ ORBit_marshal_any(buf, *val);
++ *val = ((guchar *)*val) + sizeof(CORBA_any);
++ break;
++ case CORBA_tk_TypeCode:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ ORBit_encode_CORBA_TypeCode(*val, buf);
++ *val = ((guchar *)*val) + sizeof(CORBA_TypeCode);
++ break;
++ case CORBA_tk_Principal:
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++
++ ulval = *(CORBA_unsigned_long *)(*val);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_unsigned_long));
++
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf),
++ *(char**)((char *)*val+sizeof(CORBA_unsigned_long)),
++ ulval);
++ *val = ((guchar *)*val) + sizeof(CORBA_Principal);
++ break;
++ case CORBA_tk_objref:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ ORBit_marshal_object(buf, *val);
++ *val = ((guchar *)*val) + sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ ORBit_marshal_value(buf, val, tc->subtypes[i], mi);
++ }
++ break;
++ case CORBA_tk_union:
++ /* Basic algorithm:
++ marshal the discriminator
++ find out which value we want to use */
++ {
++ CORBA_TypeCode utc;
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_STRUCT);
++
++ utc = ORBit_get_union_tag(tc, val, TRUE);
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_STRUCT);
++
++ ORBit_marshal_value(buf, val, tc->discriminator, mi);
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ ORBit_marshal_value(buf, val, utc, mi);
++ }
++ break;
++ case CORBA_tk_wstring:
++ ulval = strlen(*(char **)*val) + 1;
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ giop_send_buffer_append_mem_indirect_a(buf,
++ &ulval,
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), *(char **)*val, ulval);
++
++ *val = ((guchar *)*val) + sizeof(char *);
++ break;
++ case CORBA_tk_string:
++ ulval = strlen(*(char **)*val) + 1;
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++
++ giop_send_buffer_append_mem_indirect_a(buf,
++ &ulval,
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), *(char **)*val, ulval);
++
++ *val = ((guchar *)*val) + sizeof(char *);
++ break;
++ case CORBA_tk_sequence:
++ {
++ CORBA_sequence_octet *sval = *val;
++
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_STRUCT), ALIGNOF_CORBA_POINTER));
++
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf),
++ &sval->_length,
++ sizeof(sval->_length));
++
++ subval = sval->_buffer;
++
++ for(i = 0; i < sval->_length; i++)
++ ORBit_marshal_value(buf, &subval, tc->subtypes[0], mi);
++
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_array:
++ submi.alias_element_type = tc->subtypes[0];
++ for(i = 0; i < tc->length; i++) {
++ ORBit_marshal_value(buf, val, submi.alias_element_type, &submi);
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc->subtypes[0]));
++ }
++ break;
++ case CORBA_tk_alias:
++ submi.alias_element_type = tc->subtypes[0];
++ ORBit_marshal_value(buf, val, submi.alias_element_type, &submi);
++ break;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_LONG);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_long_long));
++ return /* *val + sizeof(CORBA_long_long)*/;
++ break;
++ case CORBA_tk_longdouble:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_DOUBLE);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_long_double));
++ return /* *val + sizeof(CORBA_long_double)*/;
++ break;
++ case CORBA_tk_fixed:
++ /* XXX todo */
++ g_error("CORBA_fixed NYI");
++
++ break;
++ case CORBA_tk_null:
++ case CORBA_tk_void:
++ break;
++ default:
++ g_error("Can't encode unknown type %d", tc->kind);
++ }
++}
++
++static glong ORBit_get_union_switch(CORBA_TypeCode tc, gpointer *val, gboolean update)
++{
++#ifdef __KORBIT__
++ glong retval = 0;
++#else
++ glong retval;
++#endif
++
++ switch(tc->kind) {
++ case CORBA_tk_ulong:
++ case CORBA_tk_long:
++ case CORBA_tk_enum:
++ retval = *(CORBA_long *)*val;
++ if(update) *val += sizeof(CORBA_long);
++ break;
++ case CORBA_tk_ushort:
++ case CORBA_tk_short:
++ retval = *(CORBA_short *)*val;
++ if(update) *val += sizeof(CORBA_short);
++ break;
++ case CORBA_tk_char:
++ case CORBA_tk_boolean:
++ case CORBA_tk_octet:
++ retval = *(CORBA_octet *)*val;
++ if(update) *val += sizeof(CORBA_char);
++ break;
++ case CORBA_tk_alias:
++ return ORBit_get_union_switch(tc->subtypes[0], val, update);
++ break;
++ default:
++ g_error("Wow, some nut has passed us a weird type[%d] as a union discriminator!", tc->kind);
++ }
++
++ return retval;
++}
++
++/* This function (and the one above it) exist for the
++ sole purpose of finding out which CORBA_TypeCode a union discriminator value
++ indicates.
++
++ If {update} is TRUE, {*val} will be advanced by the native size
++ of the descriminator type.
++
++ Hairy stuff.
++*/
++CORBA_TypeCode
++ORBit_get_union_tag(CORBA_TypeCode union_tc, gpointer *val, gboolean update)
++{
++ glong discrim_val, case_val;
++ int i;
++ CORBA_TypeCode retval = CORBA_OBJECT_NIL;
++
++ discrim_val = ORBit_get_union_switch(union_tc->discriminator, val, update);
++
++ for(i = 0; i < union_tc->sub_parts; i++) {
++ if(i == union_tc->default_index)
++ continue;
++
++ case_val = ORBit_get_union_switch(union_tc->sublabels[i]._type,
++ &union_tc->sublabels[i]._value, FALSE);
++ if(case_val == discrim_val) {
++ retval = union_tc->subtypes[i];
++ break;
++ }
++ }
++
++ if(retval)
++ return retval;
++ else if(union_tc->default_index >= 0)
++ return union_tc->subtypes[union_tc->default_index];
++ else {
++ return TC_null;
++ }
++}
++
++void
++ORBit_marshal_arg(GIOPSendBuffer *buf,
++ gpointer val,
++ CORBA_TypeCode tc)
++{
++ ORBit_marshal_value_info mi;
++
++ ORBit_marshal_value(buf, &val, tc, &mi);
++}
++
++
++void
++ORBit_marshal_any(GIOPSendBuffer *buf, const CORBA_any *val)
++{
++ ORBit_marshal_value_info mi;
++
++ gpointer mval = val->_value;
++
++ ORBit_encode_CORBA_TypeCode(val->_type, buf);
++
++ ORBit_marshal_value(buf, &mval, val->_type, &mi);
++}
++
++size_t
++ORBit_gather_alloc_info(CORBA_TypeCode tc)
++{
++ int i, n, align=1, prevalign, sum, prev;
++ size_t block_size;
++
++ switch(tc->kind) {
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ case CORBA_tk_enum:
++ return sizeof(CORBA_long);
++ break;
++ case CORBA_tk_short:
++ case CORBA_tk_ushort:
++ return sizeof(CORBA_short);
++ break;
++ case CORBA_tk_float:
++ return sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ return sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ return sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ return sizeof(CORBA_any);
++ break;
++ case CORBA_tk_TypeCode:
++ return sizeof(CORBA_TypeCode);
++ break;
++ case CORBA_tk_Principal:
++ return sizeof(CORBA_Principal);
++ break;
++ case CORBA_tk_objref:
++ return sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ sum = 0;
++ for(i = 0; i < tc->sub_parts; i++) {
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc->subtypes[i])));
++ sum += ORBit_gather_alloc_info(tc->subtypes[i]);
++ }
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc)));
++ return sum;
++ break;
++ case CORBA_tk_union:
++ sum = ORBit_gather_alloc_info(tc->discriminator);
++ n = -1;
++ align = 1;
++ for(prev = prevalign = i = 0; i < tc->sub_parts; i++) {
++ prevalign = align;
++ align = ORBit_find_alignment(tc->subtypes[i]);
++ if(align > prevalign)
++ n = i;
++
++ prev = MAX(prev, ORBit_gather_alloc_info(tc->subtypes[i]));
++ }
++ if(n >= 0)
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc->subtypes[n])));
++ sum += prev;
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc)));
++ return sum;
++ break;
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ return sizeof(char *);
++ break;
++ case CORBA_tk_sequence:
++ return sizeof(CORBA_sequence_octet);
++ break;
++ case CORBA_tk_array:
++ block_size = ORBit_gather_alloc_info(tc->subtypes[0]);
++ return block_size * tc->length;
++ break;
++ case CORBA_tk_alias:
++ return ORBit_gather_alloc_info(tc->subtypes[0]);
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ return sizeof(CORBA_long_long);
++ case CORBA_tk_longdouble:
++ return sizeof(CORBA_long_double);
++ case CORBA_tk_wchar:
++ return sizeof(CORBA_wchar);
++ case CORBA_tk_fixed:
++ return sizeof(CORBA_fixed_d_s);
++ default:
++ return 0;
++ }
++}
++
++/* to allocate a block, we need to know of any important data
++ contained in it.
++*/
++static gpointer
++ORBit_demarshal_allocate_mem(CORBA_TypeCode tc, gint nelements)
++{
++ size_t block_size;
++ gpointer retval = NULL;
++
++ if(!nelements) return retval;
++
++ block_size = ORBit_gather_alloc_info(tc);
++
++ if(block_size) {
++ retval = ORBit_alloc_2(block_size * nelements,
++ (ORBit_free_childvals)ORBit_free_via_TypeCode,
++ GINT_TO_POINTER(nelements),
++ sizeof(CORBA_TypeCode));
++
++ *(CORBA_TypeCode *)((char *)retval-sizeof(ORBit_mem_info)-sizeof(CORBA_TypeCode)) = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc, NULL);
++ }
++
++ return retval;
++}
++
++#define DM_GET_ATOM(x, n) G_STMT_START{ GIOP_RECV_BUFFER(buf)->decoder(x, (GIOP_RECV_BUFFER(buf)->cur), n); GIOP_RECV_BUFFER(buf)->cur = ((guchar *)GIOP_RECV_BUFFER(buf)->cur) + n; }G_STMT_END
++
++static void
++ORBit_demarshal_value(GIOPRecvBuffer *buf,
++ gpointer *val,
++ CORBA_TypeCode tc,
++ gboolean dup_strings,
++ CORBA_ORB orb)
++{
++ CORBA_long i, n;
++
++#if 0
++ g_message("Demarshalling a %d value from offset %d into %#x",
++ tc->kind, buf->cur - buf->message_body, (gulong)*val);
++#endif
++
++ switch(tc->kind) {
++ case CORBA_tk_short:
++ case CORBA_tk_ushort:
++ case CORBA_tk_wchar:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_SHORT);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_short));
++ DM_GET_ATOM(*val, sizeof(CORBA_short));
++ *val = ((guchar *)*val) + sizeof(CORBA_short);
++ break;
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ case CORBA_tk_enum:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ DM_GET_ATOM(*val, sizeof(CORBA_long));
++ *val = ((guchar *)*val) + sizeof(CORBA_long);
++ break;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_LONG);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long_long));
++ DM_GET_ATOM(*val, sizeof(CORBA_long_long));
++ *val = ((guchar *)*val) + sizeof(CORBA_long_long);
++ break;
++ case CORBA_tk_longdouble:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_DOUBLE);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long_double));
++ DM_GET_ATOM(*val, sizeof(CORBA_long_double));
++ *val = ((guchar *)*val) + sizeof(CORBA_long_double);
++ break;
++ case CORBA_tk_float:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_FLOAT);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_float));
++ DM_GET_ATOM(*val, sizeof(CORBA_float));
++ *val = ((guchar *)*val) + sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_DOUBLE);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_double));
++ DM_GET_ATOM(*val, sizeof(CORBA_double));
++ *val = ((guchar *)*val) + sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ DM_GET_ATOM(*val, sizeof(CORBA_octet));
++ *val = ((guchar *)*val) + sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ {
++ CORBA_any *decoded;
++
++ *val = ALIGN_ADDRESS(*val,
++ MAX(ALIGNOF_CORBA_LONG,
++ MAX(ALIGNOF_CORBA_POINTER, ALIGNOF_CORBA_STRUCT)));
++ decoded = *val;
++ decoded->_release = CORBA_FALSE;
++ ORBit_demarshal_any(buf, decoded, dup_strings, orb);
++ *val = ((guchar *)*val) + sizeof(CORBA_any);
++ }
++ break;
++ case CORBA_tk_TypeCode:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ ORBit_decode_CORBA_TypeCode(*val, buf);
++ CORBA_Object_duplicate(*(CORBA_Object *)*val, NULL);
++ *val = ((guchar *)*val) + sizeof(CORBA_TypeCode);
++ break;
++ case CORBA_tk_Principal:
++ {
++ CORBA_Principal *p;
++
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT,
++ MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_POINTER)));
++
++ p = *val;
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ CORBA_sequence_set_release(p, dup_strings);
++ DM_GET_ATOM(&p->_length, sizeof(CORBA_long));
++ p->_buffer = ORBit_alloc(p->_length, NULL, GINT_TO_POINTER(1));
++ memcpy(p->_buffer, buf->cur, p->_length);
++ buf->cur = ((guchar *)buf->cur) + p->_length;
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_objref:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ *(CORBA_Object *)*val = ORBit_demarshal_object(buf, orb);
++ *val = ((guchar *)*val) + sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ ORBit_demarshal_value(buf, val, tc->subtypes[i], dup_strings, orb);
++ }
++ break;
++ case CORBA_tk_union:
++ {
++ gpointer discrimptr;
++
++ discrimptr = *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ ORBit_demarshal_value(buf, val, tc->discriminator, dup_strings, orb);
++ n = 1;
++ for(i = 0; i < tc->sub_parts; i++) {
++ n = MAX(n, ORBit_find_alignment(tc->subtypes[i]));
++ }
++ *val = ALIGN_ADDRESS(*val, n);
++ ORBit_demarshal_value(buf, val,
++ ORBit_get_union_tag(tc, &discrimptr, FALSE),
++ dup_strings, orb);
++ }
++ break;
++ case CORBA_tk_string:
++ case CORBA_tk_wstring:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ DM_GET_ATOM(&i, sizeof(CORBA_long));
++ if(dup_strings)
++ *(char **)*val = CORBA_string_dup(buf->cur);
++ else
++ *(char **)*val = buf->cur;
++ *val = ((guchar *)*val) + sizeof(CORBA_char *);
++ buf->cur = (gpointer)((char *)buf->cur + i);
++ break;
++ case CORBA_tk_sequence:
++ {
++ CORBA_sequence_octet *p;
++ gpointer subval;
++
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT,
++ MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_POINTER)));
++ p = *val;
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ DM_GET_ATOM(&p->_length, sizeof(CORBA_long));
++ if(tc->subtypes[0]->kind == CORBA_tk_octet
++ || tc->subtypes[0]->kind == CORBA_tk_boolean
++ || tc->subtypes[0]->kind == CORBA_tk_char) {
++ /* This special-casing could be taken further to apply to
++ all atoms... */
++ p->_buffer = ORBit_alloc(p->_length, NULL, GINT_TO_POINTER(1));
++ memcpy(p->_buffer, buf->cur, p->_length);
++ buf->cur = ((guchar *)buf->cur) + p->_length;
++ } else {
++ p->_buffer = ORBit_demarshal_allocate_mem(tc->subtypes[0],
++ p->_length);
++ subval = p->_buffer;
++
++ for(i = 0; i < p->_length; i++)
++ ORBit_demarshal_value(buf, &subval,
++ tc->subtypes[0],
++ dup_strings,
++ orb);
++ }
++
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_array:
++ for(i = 0; i < tc->length; i++)
++ ORBit_demarshal_value(buf, val, tc->subtypes[0], dup_strings, orb);
++ break;
++ case CORBA_tk_alias:
++ ORBit_demarshal_value(buf, val, tc->subtypes[0], dup_strings, orb);
++ break;
++ case CORBA_tk_fixed:
++ g_error("CORBA_fixed NYI");
++ break;
++ default:
++ break;
++ }
++}
++
++gpointer
++ORBit_demarshal_arg(GIOPRecvBuffer *buf,
++ CORBA_TypeCode tc,
++ gboolean dup_strings,
++ CORBA_ORB orb)
++{
++ gpointer retval, val;
++
++ retval = val = ORBit_demarshal_allocate_mem(tc, 1);
++
++ ORBit_demarshal_value(buf, &val, tc, dup_strings, orb);
++
++ return retval;
++}
++
++void
++ORBit_demarshal_any(GIOPRecvBuffer *buf, CORBA_any *retval,
++ gboolean dup_strings,
++ CORBA_ORB orb)
++{
++ gpointer val;
++
++#if 0
++ /* I wish I knew whether this was correct or not. It breaks things like 'any anop();' for sure,
++ since we can't always initialize every single possible 'any' underneath _ORBIT_retval */
++ if(retval->_release)
++ CORBA_free(retval->_value);
++#endif
++
++ CORBA_any_set_release(retval, CORBA_TRUE);
++
++ ORBit_decode_CORBA_TypeCode(&retval->_type, buf);
++ CORBA_Object_duplicate((CORBA_Object)retval->_type, NULL);
++
++ val = retval->_value = ORBit_demarshal_allocate_mem(retval->_type, 1);
++ ORBit_demarshal_value(buf, &val, retval->_type, dup_strings, orb);
++}
++
++void
++_ORBit_copy_value(gpointer *val, gpointer *newval, CORBA_TypeCode tc)
++{
++ CORBA_long i;
++ gpointer pval1, pval2;
++
++ switch(tc->kind) {
++ case CORBA_tk_wchar:
++ case CORBA_tk_short:
++ case CORBA_tk_ushort:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_SHORT);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_SHORT);
++ *(CORBA_short *)*newval = *(CORBA_short *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_short);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_short);
++ break;
++ case CORBA_tk_enum:
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_LONG);
++ *(CORBA_long *)*newval = *(CORBA_long *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_long);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_long);
++ break;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_LONG);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_LONG_LONG);
++ *(CORBA_long_long *)*newval = *(CORBA_long_long *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_long_long);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_long_long);
++ break;
++ case CORBA_tk_longdouble:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_DOUBLE);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_LONG_DOUBLE);
++ *(CORBA_long_double *)*newval = *(CORBA_long_double *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_long_double);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_long_double);
++ break;
++ case CORBA_tk_float:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_FLOAT);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_FLOAT);
++ *(CORBA_long *)*newval = *(CORBA_long *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_float);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_DOUBLE);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_DOUBLE);
++ *(CORBA_double *)*newval = *(CORBA_double *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_double);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ *(CORBA_octet *)*newval = *(CORBA_octet *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_octet);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ {
++ CORBA_any *oldany, *newany;
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT, ALIGNOF_CORBA_POINTER));
++ *newval = ALIGN_ADDRESS(*newval, MAX(ALIGNOF_CORBA_STRUCT, ALIGNOF_CORBA_POINTER));
++ oldany = *val;
++ newany = *newval;
++ newany->_type = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)oldany->_type, NULL);
++ /* XXX are we supposed to do this even if oldany->_release
++ == FALSE? */
++ newany->_value = ORBit_copy_value(oldany->_value, oldany->_type);
++ newany->_release = CORBA_TRUE;
++ *val = ((guchar *)*val) + sizeof(CORBA_any);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_any);
++ }
++ break;
++ case CORBA_tk_Principal:
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ *newval = ALIGN_ADDRESS(*newval,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ *(CORBA_Principal *)*newval = *(CORBA_Principal *)*val;
++ ((CORBA_Principal *)*newval)->_buffer =
++ CORBA_octet_allocbuf(((CORBA_Principal *)*newval)->_length);
++ memcpy(((CORBA_Principal *)*newval)->_buffer,
++ ((CORBA_Principal *)*val)->_buffer,
++ ((CORBA_Principal *)*val)->_length);
++ *val = ((guchar *)*val) + sizeof(CORBA_Principal);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_Principal);
++ break;
++ case CORBA_tk_TypeCode:
++ case CORBA_tk_objref:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_POINTER);
++ *(CORBA_Object *)*newval = CORBA_Object_duplicate(*(CORBA_Object *)*val,
++ NULL);
++ *val = ((guchar *)*val) + sizeof(CORBA_Object);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_struct:
++ case CORBA_tk_except:
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ *newval = ALIGN_ADDRESS(*newval, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ _ORBit_copy_value(val, newval, tc->subtypes[i]);
++ }
++ break;
++ case CORBA_tk_union:
++ {
++ CORBA_TypeCode utc = ORBit_get_union_tag(tc, val, FALSE);
++ gint union_align = ORBit_find_alignment(tc);
++ size_t union_size = ORBit_gather_alloc_info(tc);
++
++ /* need to advance val,newval by size of union, not just
++ * current tagged field within it */
++ pval1 = *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_STRUCT);
++ pval2 = *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_STRUCT);
++ _ORBit_copy_value(&pval1, &pval2, tc->discriminator);
++ pval1 = ALIGN_ADDRESS(pval1, union_align);
++ pval2 = ALIGN_ADDRESS(pval2, union_align);
++ _ORBit_copy_value(&pval1, &pval2, utc);
++ *val = ((guchar *)*val) + union_size;
++ *newval = ((guchar *)*newval) + union_size;
++ }
++ break;
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_POINTER);
++
++ *(CORBA_char **)*newval = CORBA_string_dup(*(CORBA_char **)*val);
++ *val = ((guchar *)*val) + sizeof(CORBA_char *);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_char *);
++ break;
++ case CORBA_tk_sequence:
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ *newval = ALIGN_ADDRESS(*newval,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ ((CORBA_Principal *)*newval)->_release = CORBA_TRUE;
++ ((CORBA_Principal *)*newval)->_length =
++ ((CORBA_Principal *)*newval)->_maximum =
++ ((CORBA_Principal *)*val)->_length;
++ ((CORBA_Principal *)*newval)->_buffer = pval2 =
++ ORBit_demarshal_allocate_mem(tc->subtypes[0],
++ ((CORBA_Principal *)*val)->_length);
++ pval1 = ((CORBA_Principal *)*val)->_buffer;
++
++ for(i = 0; i < ((CORBA_Principal *)*newval)->_length; i++) {
++ _ORBit_copy_value(&pval1, &pval2, tc->subtypes[0]);
++ }
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_sequence_octet);
++ break;
++ case CORBA_tk_array:
++ for(i = 0; i < tc->length; i++) {
++ _ORBit_copy_value(val, newval, tc->subtypes[0]);
++ }
++ break;
++ case CORBA_tk_alias:
++ _ORBit_copy_value(val, newval, tc->subtypes[0]);
++ break;
++ case CORBA_tk_fixed:
++ g_error("CORBA_fixed NYI!");
++ break;
++ case CORBA_tk_void:
++ case CORBA_tk_null:
++ *val = NULL;
++ break;
++ default:
++ g_error("Can't handle copy of value kind %d", tc->kind);
++ }
++}
++
++gpointer
++ORBit_copy_value(gpointer value, CORBA_TypeCode tc)
++{
++ gpointer retval, newval;
++
++ retval = newval = ORBit_demarshal_allocate_mem(tc, 1);
++ _ORBit_copy_value(&value, &newval, tc);
++
++ return retval;
++}
++
++void
++CORBA_any__copy(CORBA_any *out, CORBA_any *in)
++{
++ out->_type = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)in->_type,
++ NULL);
++ out->_value = ORBit_copy_value(in->_value, in->_type);
++ out->_release = CORBA_TRUE;
++}
+diff -urN linux-2.4.1/net/korbit/orb/corba_any.h linux-2.4.1-korbit/net/korbit/orb/corba_any.h
+--- linux-2.4.1/net/korbit/orb/corba_any.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,45 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ANY_H_
++#define _ORBIT_CORBA_ANY_H_
++
++#include "orbit_types.h"
++#include "corba_typecode.h"
++
++#include <unistd.h>
++
++typedef struct CORBA_any_type CORBA_any;
++
++size_t ORBit_gather_alloc_info(CORBA_TypeCode tc);
++gint ORBit_find_alignment(CORBA_TypeCode tc);
++CORBA_TypeCode ORBit_get_union_tag(CORBA_TypeCode union_tc,
++ gpointer *val, gboolean update);
++gpointer ORBit_copy_value(gpointer value, CORBA_TypeCode tc);
++void _ORBit_copy_value(gpointer *val, gpointer *newval, CORBA_TypeCode tc);
++
++void CORBA_any__copy(CORBA_any *out, CORBA_any *in);
++
++#endif /* !_ORBIT_CORBA_ANY_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_any_proto.h linux-2.4.1-korbit/net/korbit/orb/corba_any_proto.h
+--- linux-2.4.1/net/korbit/orb/corba_any_proto.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any_proto.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,16 @@
++#ifndef _ORBIT_CORBA_ANY_PROTO_H_
++#define _ORBIT_CORBA_ANY_PROTO_H_
++
++void ORBit_marshal_arg(GIOPSendBuffer *buf,
++ gpointer val,
++ CORBA_TypeCode tc);
++void ORBit_marshal_any(GIOPSendBuffer *buf, const CORBA_any *val);
++gpointer ORBit_demarshal_arg(GIOPRecvBuffer *buf,
++ CORBA_TypeCode tc,
++ gboolean dup_strings,
++ CORBA_ORB orb);
++void ORBit_demarshal_any(GIOPRecvBuffer *buf, CORBA_any *retval,
++ gboolean dup_strings,
++ CORBA_ORB orb);
++
++#endif /* !_ORBIT_CORBA_ANY_PROTO_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_any_type.h linux-2.4.1-korbit/net/korbit/orb/corba_any_type.h
+--- linux-2.4.1/net/korbit/orb/corba_any_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,48 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ANY_TYPE_H_
++#define _ORBIT_CORBA_ANY_TYPE_H_
++
++#include "corba_any.h"
++#include "corba_typecode.h"
++
++struct CORBA_any_type {
++ CORBA_TypeCode _type;
++ gpointer _value;
++ CORBA_boolean _release;
++};
++
++typedef struct ORBit_marshal_value_info_struct {
++ CORBA_TypeCode alias_element_type;
++} ORBit_marshal_value_info;
++
++#define CORBA_ANYFLAGS_RELEASE 1
++
++
++#endif /* !_ORBIT_CORBA_ANY_TYPE_H_ */
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_basic_sequences_type.h linux-2.4.1-korbit/net/korbit/orb/corba_basic_sequences_type.h
+--- linux-2.4.1/net/korbit/orb/corba_basic_sequences_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_basic_sequences_type.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,43 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_BASIC_SEQUENCES_TYPE_H_
++#define _ORBIT_CORBA_BASIC_SEQUENCES_TYPE_H_
++
++#include <ORBitutil/basic_types.h>
++
++#ifndef _CORBA_sequence_octet_defined
++#define _CORBA_sequence_octet_defined 1
++
++typedef struct CORBA_sequence_octet_struct {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_octet *_buffer;
++ CORBA_boolean _release;
++} CORBA_sequence_octet;
++#endif /* !_CORBA_sequence_octet_defined */
++
++#include <orb/corba_sequences.h>
++#endif /* !_ORBIT_CORBA_BASIC_SEQUENCES_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_context.c linux-2.4.1-korbit/net/korbit/orb/corba_context.c
+--- linux-2.4.1/net/korbit/orb/corba_context.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_context.c Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,390 @@
++#include "orb/orbit.h"
++
++#define o_return_val_if_fail(expr, val) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return (val); }
++#define o_return_if_fail(expr) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return; }
++
++static gboolean
++free_entry(gpointer key, gpointer value, gpointer user_data)
++{
++ g_free(key);
++ g_free(value);
++
++ return TRUE;
++}
++
++static void
++ORBit_Context_release(CORBA_Context ctx, CORBA_Environment *ev);
++
++static gboolean
++free_child(gpointer value, gpointer user_data)
++{
++ CORBA_Context ctx = value;
++
++ ORBIT_ROOT_OBJECT(ctx)->refs = 1;
++ ctx->parent_ctx = CORBA_OBJECT_NIL;
++ ORBit_Context_release(ctx, NULL);
++
++ return TRUE;
++}
++
++static void
++ORBit_Context_release(CORBA_Context ctx,
++ CORBA_Environment *ev)
++{
++ ORBIT_ROOT_OBJECT_UNREF(ctx);
++
++ if(ORBIT_ROOT_OBJECT(ctx)->refs <= 0) {
++ if(ctx->children) {
++ g_slist_foreach(ctx->children, (GFunc)free_child, ctx);
++ g_slist_free(ctx->children);
++ }
++
++ if(ctx->mappings) {
++ g_hash_table_foreach_remove(ctx->mappings, free_entry, ctx);
++ g_hash_table_destroy(ctx->mappings);
++ }
++
++ if(ctx->parent_ctx != CORBA_OBJECT_NIL)
++ ctx->parent_ctx->children = g_slist_remove(ctx->parent_ctx->children, ctx->the_name);
++
++ g_free(ctx->the_name);
++
++ g_free(ctx);
++ }
++}
++
++static const ORBit_RootObject_Interface CORBA_Context_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_Context_release,
++};
++
++static CORBA_Context
++CORBA_Context_new(CORBA_Context parent, const char *name, CORBA_Environment *ev)
++{
++ CORBA_Context retval;
++
++ retval = g_new0(struct CORBA_Context_type, 1);
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(retval), ORBIT_PSEUDO_CONTEXT, ev);
++
++ ORBIT_ROOT_OBJECT(retval)->refs = 0;
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(retval), (gpointer)&CORBA_Context_epv, ev);
++
++ if(name)
++ retval->the_name = g_strdup(name);
++
++ retval->parent_ctx = parent;
++ if(parent)
++ parent->children = g_slist_prepend(parent->children, retval);
++
++ return retval;
++}
++
++/* Section 5.6.1 */
++CORBA_Status CORBA_ORB_get_default_context(CORBA_ORB orb, CORBA_Context *ctx, CORBA_Environment *ev)
++{
++ g_return_if_fail(ev != NULL);
++ o_return_if_fail(orb && ctx);
++
++ if(!orb->default_ctx)
++ orb->default_ctx = CORBA_Context_new(CORBA_OBJECT_NIL, NULL, ev);
++
++ *ctx = (CORBA_Context)CORBA_Object_duplicate((CORBA_Object)orb->default_ctx, ev);
++}
++
++/********* XXX todo - CORBA_Context support */
++CORBA_Status CORBA_Context_set_one_value(CORBA_Context ctx, CORBA_Identifier prop_name, char *value, CORBA_Environment *ev)
++{
++ gpointer old_nom, old_value;
++ g_return_if_fail(ev != NULL);
++ o_return_if_fail(ctx && prop_name && value);
++
++ if(!ctx->mappings)
++ ctx->mappings = g_hash_table_new(g_str_hash, g_str_equal);
++
++ if(g_hash_table_lookup_extended(ctx->mappings, prop_name, &old_nom, &old_value)) {
++ g_free(old_nom);
++ g_free(old_value);
++ }
++
++ g_hash_table_insert(ctx->mappings, g_strdup(prop_name), g_strdup(value));
++}
++
++/* Section 5.6.3 */
++CORBA_Status CORBA_Context_set_values(CORBA_Context ctx, CORBA_NVList *values, CORBA_Environment *ev)
++{
++ int i;
++
++ for(i = 0; i < values->list->len; i++) {
++ CORBA_NamedValue *nvp;
++
++ nvp = ((CORBA_NamedValue *)values->list->data) + i;
++
++ g_assert(nvp->argument._type == TC_string);
++
++ CORBA_Context_set_one_value(ctx, nvp->name, nvp->argument._value, ev);
++ }
++}
++
++/* Section 5.6.4 */
++
++typedef struct {
++ CORBA_Context ctx;
++ CORBA_Identifier prop_name;
++ CORBA_NVList *values;
++ CORBA_Environment *ev;
++ int len;
++} CTXSearchInfo;
++
++static gboolean
++list_has_key(CORBA_NVList *list, const char *key)
++{
++ int i;
++
++ for(i = 0; i < list->list->len; i++) {
++ CORBA_NamedValue *nvp;
++
++ nvp = ((CORBA_NamedValue *)list->list->data) + i;
++
++ if(!strcmp(nvp->name, key))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static void
++search_props(gpointer key, gpointer value, CTXSearchInfo *csi)
++{
++ if(strncmp(key, csi->prop_name, csi->len))
++ return;
++
++ if(list_has_key(csi->values, key))
++ return;
++
++ CORBA_NVList_add_item(csi->values, key, TC_string, &value, strlen(value) + 1, CORBA_IN_COPY_VALUE, NULL);
++}
++
++static void
++ctx_get_values(CORBA_Context ctx, CORBA_Flags op_flags,
++ CORBA_Identifier prop_name, CORBA_NVList **values,
++ gint is_wc,
++ CORBA_Environment *ev)
++{
++ gboolean go_up = FALSE;
++
++ if(is_wc >= 0) {
++ CTXSearchInfo csi;
++
++ csi.ctx = ctx;
++ csi.prop_name = prop_name;
++ csi.values = *values;
++ csi.ev = ev;
++ csi.len = is_wc;
++
++ if(ctx->mappings)
++ g_hash_table_foreach(ctx->mappings, (GHFunc)search_props, &csi);
++
++ go_up = TRUE;
++
++ } else {
++ char *val = NULL;
++
++ if(ctx->mappings)
++ val = g_hash_table_lookup(ctx->mappings, prop_name);
++
++ if(val)
++ CORBA_NVList_add_item(*values, prop_name, TC_string, &val, strlen(val) + 1, CORBA_IN_COPY_VALUE, ev);
++ else
++ go_up = TRUE;
++ }
++
++ if(go_up
++ && ctx->parent_ctx
++ && !(op_flags & CORBA_CTX_RESTRICT_SCOPE))
++ ctx_get_values(ctx->parent_ctx, op_flags, prop_name, values, is_wc, ev);
++}
++
++CORBA_Status CORBA_Context_get_values(CORBA_Context ctx,
++ CORBA_Identifier start_scope,
++ CORBA_Flags op_flags,
++ CORBA_Identifier prop_name,
++ CORBA_NVList **values,
++ CORBA_Environment *ev)
++{
++ char *ctmp;
++ int wc_pos;
++
++ CORBA_ORB_create_list(CORBA_OBJECT_NIL, 0, values, ev);
++
++ if(start_scope && *start_scope) {
++ while(ctx && (!ctx->the_name || strcmp(ctx->the_name, start_scope)))
++ ctx = ctx->parent_ctx;
++
++ if(!ctx) {
++ CORBA_exception_set_system(ev, ex_CORBA_INV_IDENT, CORBA_COMPLETED_NO);
++ return;
++ }
++ }
++
++ ctmp = strchr(prop_name, '*');
++ if(ctmp)
++ wc_pos = ctmp - prop_name;
++ else
++ wc_pos = -1;
++
++ CORBA_ORB_create_list(CORBA_OBJECT_NIL, 0, values, ev);
++
++ ctx_get_values(ctx, op_flags, prop_name, values, (prop_name[strlen(prop_name) - 1] == '*'), ev);
++
++ if((*values)->list->len == 0)
++ {
++ CORBA_NVList_free(*values, ev);
++ *values = NULL;
++ CORBA_exception_set_system(ev, ex_CORBA_UNKNOWN, CORBA_COMPLETED_NO);
++ }
++}
++
++/* Section 5.6.5 */
++static void
++delete_props(gpointer key, gpointer value, CTXSearchInfo *csi)
++{
++ if(strncmp(key, csi->prop_name, csi->len))
++ return;
++
++ g_hash_table_remove(csi->ctx->mappings, key);
++ g_free(key);
++ g_free(value);
++}
++
++CORBA_Status CORBA_Context_delete_values(CORBA_Context ctx, CORBA_Identifier prop_name, CORBA_Environment *ev)
++{
++ char *ctmp;
++ int wc_pos;
++
++ if(!ctx->mappings)
++ return;
++
++ ctmp = strchr(prop_name, '*');
++ if(ctmp)
++ wc_pos = ctmp - prop_name;
++ else
++ wc_pos = -1;
++
++ if(wc_pos >= 0) {
++ CTXSearchInfo csi;
++
++ memset(&csi, 0, sizeof(csi));
++ csi.ctx = ctx;
++ csi.prop_name = prop_name;
++ csi.ev = ev;
++ csi.len = wc_pos;
++
++ g_hash_table_foreach(ctx->mappings, (GHFunc)delete_props, &csi);
++ } else {
++ gpointer old_nom, old_value;
++
++ if(g_hash_table_lookup_extended(ctx->mappings, prop_name, &old_nom, &old_value)) {
++ g_free(old_nom);
++ g_free(old_value);
++ }
++ }
++}
++
++/* Section 5.6.6 */
++CORBA_Status CORBA_Context_create_child(CORBA_Context ctx, CORBA_Identifier ctx_name, CORBA_Context *child_ctx, CORBA_Environment *ev)
++{
++ *child_ctx = CORBA_Context_new(ctx, ctx_name, ev);
++}
++
++/* Section 5.6.7 */
++CORBA_Status CORBA_Context_delete(CORBA_Context ctx, CORBA_Flags del_flags, CORBA_Environment *ev)
++{
++ if((del_flags & CORBA_CTX_DELETE_DESCENDENTS)
++ || !ctx->children)
++ free_child(ctx, NULL);
++}
++
++void
++ORBit_Context_marshal(CORBA_Context ctx, const ORBit_ContextMarshalItem *mlist, CORBA_unsigned_long nitems, GIOPSendBuffer *buf)
++{
++ int i;
++ CORBA_unsigned_long *real_nitems, ltmp;
++
++ real_nitems = giop_send_buffer_append_mem_indirect_a(buf, &nitems, sizeof(nitems));
++ if(!ctx->mappings) {
++ *real_nitems = 0;
++ return;
++ }
++
++ for(*real_nitems = i = 0; i < nitems; i++) {
++ char *value;
++
++ value = g_hash_table_lookup(ctx->mappings, mlist[i].str);
++ if(!value)
++ continue;
++
++ /* Key */
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), &(mlist[i].len), sizeof(mlist[i].len));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), mlist[i].str, mlist[i].len);
++ (*real_nitems)++;
++
++ /* Value */
++ ltmp = strlen(value) + 1;
++ giop_send_buffer_append_mem_indirect_a(buf, &ltmp, sizeof(ltmp));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), value, ltmp);
++ (*real_nitems)++;
++ }
++}
++
++#define GET_ATOM(x) G_STMT_START{ GIOP_RECV_BUFFER(recv_buffer)->decoder(&x, (GIOP_RECV_BUFFER(recv_buffer)->cur), sizeof(x)); \
++GIOP_RECV_BUFFER(recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(recv_buffer)->cur) + sizeof(x); \
++}G_STMT_END
++#define ALIGNFOR(x) recv_buffer->cur = ALIGN_ADDRESS(recv_buffer->cur, sizeof(x))
++
++void
++ORBit_Context_demarshal(CORBA_Context parent, CORBA_Context initme, GIOPRecvBuffer *recv_buffer)
++{
++ CORBA_unsigned_long nstrings, keylen, vallen, i;
++ char *key, *value;
++
++ memset(initme, 0, sizeof(struct CORBA_Context_type));
++ ORBIT_ROOT_OBJECT(initme)->refs = -1;
++
++ initme->parent_ctx = parent;
++
++ ALIGNFOR(nstrings);
++ GET_ATOM(nstrings);
++
++ if(nstrings)
++ initme->mappings = g_hash_table_new(g_str_hash, g_str_equal);
++ else
++ return;
++
++ g_hash_table_freeze(initme->mappings);
++ for(i = 0; i < nstrings; ) {
++ ALIGNFOR(keylen);
++ GET_ATOM(keylen);
++ key = recv_buffer->cur;
++ recv_buffer->cur = ((char *)recv_buffer->cur) + keylen;
++ i++;
++
++ if(i >= nstrings)
++ break;
++
++ ALIGNFOR(vallen);
++ GET_ATOM(vallen);
++ value = recv_buffer->cur;
++ recv_buffer->cur = ((char *)recv_buffer->cur) + vallen;
++ i++;
++
++ g_hash_table_insert(initme->mappings, key, value);
++ }
++ g_hash_table_thaw(initme->mappings);
++}
++
++void
++ORBit_Context_server_free(CORBA_Context ctx)
++{
++ g_hash_table_destroy(ctx->mappings);
++}
+diff -urN linux-2.4.1/net/korbit/orb/corba_context.h linux-2.4.1-korbit/net/korbit/orb/corba_context.h
+--- linux-2.4.1/net/korbit/orb/corba_context.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_context.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,65 @@
++#ifndef CORBA_CONTEXT_H
++#define CORBA_CONTEXT_H 1
++
++#include "orbit_object_type.h"
++#include "orbit_object.h"
++
++typedef struct {
++ CORBA_unsigned_long len;
++ const CORBA_char *str;
++} ORBit_ContextMarshalItem;
++
++typedef struct CORBA_Context_type *CORBA_Context;
++
++struct CORBA_Context_type {
++ struct ORBit_PseudoObject_struct parent;
++ GHashTable *mappings;
++ GSList *children;
++
++ char *the_name;
++
++ CORBA_Context parent_ctx;
++};
++
++
++extern CORBA_Status CORBA_Context_set_one_value(
++ CORBA_Context ctx,
++ CORBA_Identifier prop_name,
++ char *value,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_set_values(
++ CORBA_Context ctx,
++ CORBA_NVList *values,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_get_values(
++ CORBA_Context ctx,
++ CORBA_Identifier start_scope,
++ CORBA_Flags op_flags,
++ CORBA_Identifier prop_name,
++ CORBA_NVList **values,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_delete_values(
++ CORBA_Context ctx,
++ CORBA_Identifier prop_name,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_create_child(
++ CORBA_Context ctx,
++ CORBA_Identifier ctx_name,
++ CORBA_Context *child_ctx,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_delete(
++ CORBA_Context ctx,
++ CORBA_Flags del_flags,
++ CORBA_Environment *ev);
++
++void ORBit_Context_marshal(CORBA_Context ctx, const ORBit_ContextMarshalItem *mlist,
++ CORBA_unsigned_long nitems, GIOPSendBuffer *buf);
++void ORBit_Context_demarshal(CORBA_Context parent, CORBA_Context initme, GIOPRecvBuffer *recv_buffer);
++void ORBit_Context_server_free(CORBA_Context ctx);
++
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/corba_env.h linux-2.4.1-korbit/net/korbit/orb/corba_env.h
+--- linux-2.4.1/net/korbit/orb/corba_env.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_env.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,79 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ENV_H_
++#define _ORBIT_CORBA_ENV_H_
++
++typedef struct CORBA_Environment_type CORBA_Environment;
++
++/* 3.15 */
++typedef enum {
++ CORBA_COMPLETED_YES=0,
++ CORBA_COMPLETED_NO,
++ CORBA_COMPLETED_MAYBE
++} CORBA_completion_status;
++
++typedef enum {
++ CORBA_NO_EXCEPTION=0,
++ CORBA_USER_EXCEPTION,
++ CORBA_SYSTEM_EXCEPTION
++} CORBA_exception_type;
++
++
++#define ex_CORBA_UNKNOWN 1
++#define ex_CORBA_BAD_PARAM 2
++#define ex_CORBA_NO_MEMORY 3
++#define ex_CORBA_IMP_LIMIT 4
++#define ex_CORBA_COMM_FAILURE 5
++#define ex_CORBA_INV_OBJREF 6
++#define ex_CORBA_NO_PERMISSION 7
++#define ex_CORBA_INTERNAL 8
++#define ex_CORBA_MARSHAL 9
++#define ex_CORBA_INITIALIZE 10
++#define ex_CORBA_NO_IMPLEMENT 11
++#define ex_CORBA_BAD_TYPECODE 12
++#define ex_CORBA_BAD_OPERATION 13
++#define ex_CORBA_NO_RESOURCES 14
++#define ex_CORBA_NO_RESPONSE 15
++#define ex_CORBA_PERSIST_STORE 16
++#define ex_CORBA_BAD_INV_ORDER 17
++#define ex_CORBA_TRANSIENT 18
++#define ex_CORBA_FREE_MEM 19
++#define ex_CORBA_INV_IDENT 20
++#define ex_CORBA_INV_FLAG 21
++#define ex_CORBA_INTF_REPOS 22
++#define ex_CORBA_BAD_CONTEXT 23
++#define ex_CORBA_OBJ_ADAPTER 24
++#define ex_CORBA_DATA_CONVERSION 25
++#define ex_CORBA_OBJECT_NOT_EXIST 26
++#define ex_CORBA_TRANSACTION_REQUIRED 27
++#define ex_CORBA_TRANSACTION_ROLLEDBACK 28
++#define ex_CORBA_INVALID_TRANSACTION 29
++
++
++#endif /* !_ORBIT_CORBA_ENV_H_ */
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_env_type.h linux-2.4.1-korbit/net/korbit/orb/corba_env_type.h
+--- linux-2.4.1/net/korbit/orb/corba_env_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_env_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,79 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ENV_TYPE_H_
++#define _ORBIT_CORBA_ENV_TYPE_H_
++
++#include "corba_env.h"
++#include "corba_any.h"
++
++typedef struct CORBA_system_exception {
++ CORBA_unsigned_long minor;
++ CORBA_completion_status completed;
++} CORBA_SystemException;
++
++#define SYSEXC(name) typedef CORBA_SystemException name;
++
++SYSEXC(CORBA_UNKNOWN)
++SYSEXC(CORBA_BAD_PARAM)
++SYSEXC(CORBA_NO_MEMORY)
++SYSEXC(CORBA_IMP_LIMIT)
++SYSEXC(CORBA_COMM_FAILURE)
++SYSEXC(CORBA_INV_OBJREF)
++SYSEXC(CORBA_NO_PERMISSION)
++SYSEXC(CORBA_INTERNAL)
++SYSEXC(CORBA_MARSHAL)
++SYSEXC(CORBA_INITIALIZE)
++SYSEXC(CORBA_NO_IMPLEMENT)
++SYSEXC(CORBA_BAD_TYPECODE)
++SYSEXC(CORBA_BAD_OPERATION)
++SYSEXC(CORBA_NO_RESOURCES)
++SYSEXC(CORBA_NO_RESPONSE)
++SYSEXC(CORBA_PERSIST_STORE)
++SYSEXC(CORBA_BAD_INV_ORDER)
++SYSEXC(CORBA_TRANSIENT)
++SYSEXC(CORBA_FREE_MEM)
++SYSEXC(CORBA_INV_IDENT)
++SYSEXC(CORBA_INV_FLAG)
++SYSEXC(CORBA_INTF_REPOS)
++SYSEXC(CORBA_BAD_CONTEXT)
++SYSEXC(CORBA_OBJ_ADAPTER)
++SYSEXC(CORBA_DATA_CONVERSION)
++SYSEXC(CORBA_OBJECT_NOT_EXIST)
++SYSEXC(CORBA_TRANSACTION_REQUIRED)
++SYSEXC(CORBA_TRANSACTION_ROLLEDBACK)
++SYSEXC(CORBA_INVALID_TRANSACTION)
++
++
++/* 19.22 */
++struct CORBA_Environment_type {
++ CORBA_exception_type _major;
++ CORBA_char *_repo_id;
++ void *_params;
++ CORBA_any *_any;
++};
++
++
++#endif /* !_ORBIT_CORBA_ENV_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_object.c linux-2.4.1-korbit/net/korbit/orb/corba_object.c
+--- linux-2.4.1/net/korbit/orb/corba_object.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_object.c Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,467 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#include "config.h"
++#include <IIOP/IIOP.h>
++#include "orbit_types.h"
++#include "corba_object.h"
++#include "corba_object_type.h"
++#include "env.h"
++#include "orb.h"
++#ifdef __KORBIT__
++#include "orbit.h"
++#else /* !__KORBIT__ */
++#include "interface_repository.h"
++#endif /* !__KORBIT__ */
++#include <signal.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <alloca.h>
++
++#ifndef __KERNEL__
++#define freeca(ptr)
++#endif
++
++#ifndef __KORBIT__
++/* Section 4.2.1 */
++CORBA_InterfaceDef CORBA_Object_get_interface(CORBA_Object obj, CORBA_Environment *ev)
++{
++ CORBA_Repository repo;
++ CORBA_InterfaceDef interface;
++
++ if(obj==CORBA_OBJECT_NIL)
++ return(CORBA_OBJECT_NIL); /* no exception defined in spec */
++
++ repo=CORBA_ORB_resolve_initial_references(obj->orb, "InterfaceRepository", ev);
++ if(repo==CORBA_OBJECT_NIL)
++ return(CORBA_OBJECT_NIL);
++
++ interface=CORBA_Repository_lookup_id(repo, obj->object_id, ev);
++ CORBA_Object_release(repo, ev);
++
++ return(interface);
++}
++#endif /* !__KORBIT__ */
++
++/* Section 4.2.3 */
++CORBA_boolean CORBA_Object_is_nil(CORBA_Object obj, CORBA_Environment *ev)
++{
++ if(obj==CORBA_OBJECT_NIL) {
++ return(CORBA_TRUE);
++ } else {
++ return(CORBA_FALSE);
++ }
++}
++
++/* Section 4.2.2 */
++/* XXXX Big warning: lots of places inside ORBit expect this to
++ always return 'obj'. Do not change this, upon pain
++ of death... */
++CORBA_Object CORBA_Object_duplicate(CORBA_Object obj, CORBA_Environment *ev)
++{
++ if(obj == CORBA_OBJECT_NIL)
++ return CORBA_OBJECT_NIL;
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs >= 0)
++ ORBIT_ROOT_OBJECT_REF(obj);
++
++ return(obj);
++}
++
++
++/* Section 4.2.2 */
++void CORBA_Object_release(CORBA_Object obj, CORBA_Environment *ev)
++{
++ if(obj != CORBA_OBJECT_NIL)
++ ORBIT_ROOT_OBJECT_release(obj,ev);
++}
++
++extern GHashTable *ORBit_class_assignments;
++
++void ORBit_impl_CORBA_Object_is_a(gpointer servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment *ev,
++ gpointer dummy)
++{
++ GIOPSendBuffer *_ORBIT_send_buffer;
++ struct CORBA_Object_struct objdummy; /* XXX badhack to save backwards compat */
++ CORBA_boolean retval;
++ char *repo_id;
++ CORBA_unsigned_long slen;
++ guchar *curptr;
++ ORBit_ObjectKey *objkey;
++ gpointer *tmp_vepv;
++ guint sz;
++ CORBA_unsigned_long clsid;
++ PortableServer_ServantBase *_ORBIT_servant;
++
++ _ORBIT_servant = servant;
++
++ /* XXX security implications */
++ curptr = _ORBIT_recv_buffer->cur;
++ curptr = ALIGN_ADDRESS(curptr, 4);
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)))
++ iiop_byteswap((guchar *)&slen, curptr, sizeof(CORBA_unsigned_long));
++ else
++ slen = *((CORBA_unsigned_long *)curptr);
++ curptr += 4;
++ repo_id = curptr;
++
++ repo_id[slen] = '\0';
++
++ objkey = ORBIT_OBJECT_KEY(_ORBIT_servant->_private);
++
++ sz = sizeof(gpointer) * (ORBit_class_assignment_counter + 1);
++ tmp_vepv = alloca(sz);
++ memset(tmp_vepv, '\0', sz);
++
++ objdummy.vepv = tmp_vepv;
++ objkey->class_info->init_local_objref(&objdummy, servant);
++
++ clsid = GPOINTER_TO_UINT(g_hash_table_lookup(ORBit_class_assignments, repo_id));
++ retval = (clsid && tmp_vepv[clsid]);
++
++ _ORBIT_send_buffer = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->connection, NULL,
++ _ORBIT_recv_buffer->message.u.request.request_id, ev->_major);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), &retval, sizeof(retval));
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ freeca(tmp_vepv);
++}
++
++/* Section 4.2.4 */
++CORBA_boolean CORBA_Object_is_a(CORBA_Object obj, CORBA_char *logical_type_id, CORBA_Environment *ev)
++{
++ if(obj == CORBA_OBJECT_NIL)
++ return CORBA_FALSE;
++
++ if (obj->servant && obj->vepv) {
++ CORBA_unsigned_long clsid;
++
++ clsid = GPOINTER_TO_UINT(g_hash_table_lookup(ORBit_class_assignments, logical_type_id));
++
++ return (clsid && (clsid < obj->vepv_size) && obj->vepv[clsid]);
++ } else if(!strcmp(obj->object_id, logical_type_id)
++ || !strcmp("IDL:CORBA/Object:1.0", logical_type_id)) {
++ return CORBA_TRUE;
++ } else {
++ /* Cut and paste from orbit-idl output */
++ /* XXX security implications */
++ GIOP_unsigned_long _ORBIT_request_id;
++ register GIOP_unsigned_long _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++
++ _cnx = ORBit_object_get_connection(obj);
++
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ /* A unique uint pointer is anything on the stack,
++ so set this variable to point to its own address on the
++ stack. :) */
++ _ORBIT_request_id = GPOINTER_TO_UINT(&_ORBIT_request_id);
++ { /* marshalling */
++ static const struct {
++ CORBA_unsigned_long len;
++ char opname[6];
++ } _ORBIT_operation_name_data = {
++ 6, "_is_a"
++ };
++ static const struct iovec _ORBIT_operation_vec =
++ {(gpointer) & _ORBIT_operation_name_data, 10};
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id, CORBA_TRUE,
++ &(obj->active_profile->object_key_vec), &_ORBIT_operation_vec, &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(logical_type_id) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), 4);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), (logical_type_id), sizeof(logical_type_id[_ORBIT_tmpvar_0]) * _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++ CORBA_boolean _ORBIT_retval;
++
++ _ORBIT_recv_buffer = giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status != GIOP_NO_EXCEPTION)
++ goto _ORBIT_msg_exception;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_retval = *((CORBA_boolean *) _ORBIT_curptr);
++ } else {
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_retval = *((CORBA_boolean *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor, _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status == GIOP_LOCATION_FORWARD) {
++ if (obj->forward_locations != NULL)
++ ORBit_delete_profiles(obj->forward_locations);
++ obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++
++ }
++}
++
++/* Section 4.2.5 */
++#ifndef __KORBIT__
++static void do_exit(int signum) {
++ _exit(5);
++#warning "This should be removed... use BUG instead..."
++}
++#endif
++
++/* Lovely hack to try and figure out without hanging whether an object exists or not. */
++CORBA_boolean CORBA_Object_non_existent(CORBA_Object obj, CORBA_Environment *ev)
++{
++#ifndef __KORBIT__
++ int childpid, exitstatus, itmp;
++#endif
++
++ ev->_major = CORBA_NO_EXCEPTION;
++
++ if(obj == CORBA_OBJECT_NIL)
++ return TRUE;
++
++ if(obj->servant)
++ return FALSE;
++
++ if(obj->connection && obj->connection->is_valid)
++ return FALSE;
++
++#ifndef __KORBIT__
++ childpid = fork();
++
++ if(!childpid) {
++ GIOPConnection* cnx = NULL;
++ struct sigaction sa;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.sa_handler = do_exit;
++ sigaction(SIGALRM, &sa, NULL);
++ alarm(2);
++ cnx = _ORBit_object_get_connection(obj);
++
++ /* XXX todo - try invoking a strange operation on the object, and see what type of exception we get. */
++
++ _exit((cnx == NULL)?1:0);
++ }
++
++ itmp = waitpid(childpid, &exitstatus, 0);
++
++ if(itmp < 0) return TRUE;
++ return WEXITSTATUS(exitstatus) && TRUE;
++#else /* __KORBIT__ */
++ return FALSE;
++#endif /* __KORBIT__ */
++}
++
++gboolean
++g_CORBA_Object_equal(CORBA_Object obj1, CORBA_Object obj2)
++{
++ gboolean retval;
++ CORBA_Environment ev;
++
++ CORBA_exception_init(&ev);
++
++ retval = (gboolean)CORBA_Object_is_equivalent(obj1, obj2, &ev);
++
++ CORBA_exception_free(&ev);
++
++ return retval;
++}
++
++/* Section 4.2.6 */
++CORBA_boolean CORBA_Object_is_equivalent(CORBA_Object obj, CORBA_Object other_object, CORBA_Environment *ev)
++{
++ ORBit_Object_info *obj_profile, *other_object_profile;
++ int i,j, obj_profile_count, other_object_profile_count;
++
++ if(obj == CORBA_OBJECT_NIL
++ && other_object == CORBA_OBJECT_NIL)
++ return CORBA_TRUE;
++
++ if(obj == CORBA_OBJECT_NIL
++ || other_object == CORBA_OBJECT_NIL)
++ goto ret_false;
++
++ /*
++ * If one profile in "obj" matches one in "other_object", then these
++ * objects are equivalent.
++ *
++ * This is O(n*m) at worst case :-( Hopefully though most objects will
++ * only have 1 or 2 profiles.
++ *
++ * The profile list could be indexed as a hash table (the linked list
++ * is still needed, as the profile order is significant)
++ */
++
++ obj_profile_count = g_slist_length(obj->profile_list);
++ other_object_profile_count = g_slist_length(other_object->profile_list);
++
++ for(i=0;i<obj_profile_count;i++) {
++ obj_profile=(ORBit_Object_info *)g_slist_nth_data(obj->profile_list, i);
++
++ for(j=0;j<other_object_profile_count;j++) {
++ other_object_profile=(ORBit_Object_info *)g_slist_nth_data(other_object->profile_list, j);
++
++ if(obj_profile->profile_type != other_object_profile->profile_type)
++ continue;
++
++ if(obj_profile->object_key._length != other_object_profile->object_key._length)
++ continue;
++
++ if(memcmp(obj_profile->object_key._buffer, other_object_profile->object_key._buffer, obj_profile->object_key._length))
++ continue;
++
++ if(obj_profile->profile_type == IOP_TAG_INTERNET_IOP) {
++ TAG_INTERNET_IOP_info *ii1, *ii2;
++
++ ii1 = &obj_profile->tag.iopinfo;
++ ii2 = &other_object_profile->tag.iopinfo;
++
++ if(ii1->port != ii2->port)
++ continue;
++ if(strcmp(ii1->host, ii2->host))
++ continue;
++
++ return(CORBA_TRUE);
++ } else if(obj_profile->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ TAG_ORBIT_SPECIFIC_info *oi1, *oi2;
++
++ oi1 = &obj_profile->tag.orbitinfo;
++ oi2 = &other_object_profile->tag.orbitinfo;
++
++ if(strcmp(oi1->unix_sock_path, oi2->unix_sock_path))
++ continue;
++ if(oi1->ipv6_port != oi2->ipv6_port)
++ continue;
++
++ return(CORBA_TRUE);
++ }
++ }
++ }
++
++ ret_false:
++ return CORBA_FALSE;
++}
++
++guint
++g_CORBA_Object_hash(CORBA_Object obj)
++{
++ guint retval;
++ CORBA_Environment ev;
++
++ CORBA_exception_init(&ev);
++
++ retval = (guint)CORBA_Object_hash(obj, UINT_MAX, &ev);
++
++ CORBA_exception_free(&ev);
++
++ return retval;
++}
++
++static void profile_hash(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ CORBA_unsigned_long *retval = (CORBA_unsigned_long *)data;
++
++ g_assert(info);
++ g_assert(retval);
++
++ *retval ^= info->object_key._length;
++
++ if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ *retval ^= !info->tag.iopinfo.port;
++ } else if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ *retval ^= g_str_hash(info->tag.orbitinfo.unix_sock_path);
++ *retval ^= !info->tag.orbitinfo.ipv6_port;
++ }
++}
++
++/* Section 4.2.6 */
++CORBA_unsigned_long CORBA_Object_hash(CORBA_Object obj,
++ CORBA_unsigned_long maximum,
++ CORBA_Environment *ev)
++{
++ CORBA_unsigned_long retval = 0;
++ char *tptr;
++
++ g_assert(obj);
++
++ tptr = obj->object_id;
++ while(*tptr) {
++ retval = (retval << 8) ^ *tptr;
++ tptr++;
++ }
++
++ if(g_slist_length(obj->profile_list)>0) {
++ g_slist_foreach(obj->profile_list, profile_hash, &retval);
++ } else {
++ g_warning("Object of type %s doesn't seem to have any connection info!", obj->object_id);
++ }
++
++ return (retval % maximum);
++}
++
++/* Section 4.2.7 */
++CORBA_Policy CORBA_Object_get_policy(CORBA_Object obj, CORBA_PolicyType policy_type, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
+diff -urN linux-2.4.1/net/korbit/orb/corba_object.h linux-2.4.1-korbit/net/korbit/orb/corba_object.h
+--- linux-2.4.1/net/korbit/orb/corba_object.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_object.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,59 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_OBJECT_H_
++#define _ORBIT_CORBA_OBJECT_H_
++
++#include <ORBitutil/basic_types.h>
++
++#include "corba_env.h"
++#include "corba_orb.h"
++#include "corba_sequences.h"
++
++#define CORBA_OBJECT_NIL NULL
++
++typedef struct CORBA_Object_struct *CORBA_Object;
++
++#define CORBA_OBJECT(x) ((CORBA_Object)(x))
++
++/* Used for internal stuff mostly, but also good if you want to store
++ a hash of objects */
++gboolean g_CORBA_Object_equal(CORBA_Object obj1, CORBA_Object obj2);
++guint g_CORBA_Object_hash(CORBA_Object obj);
++
++void ORBit_impl_CORBA_Object_is_a(gpointer servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment *ev, gpointer dummy);
++#define ORBIT_IMPLEMENTS_IS_A
++
++extern CORBA_boolean CORBA_Object_is_a(
++ CORBA_Object obj,
++ CORBA_char *logical_type_id,
++ CORBA_Environment *ev);
++
++#endif /* !_ORBIT_CORBA_OBJECT_H_ */
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_object_type.h linux-2.4.1-korbit/net/korbit/orb/corba_object_type.h
+--- linux-2.4.1/net/korbit/orb/corba_object_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_object_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,54 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_OBJECT_TYPE_H_
++#define _ORBIT_CORBA_OBJECT_TYPE_H_
++
++#include <sys/uio.h> /* for struct iovec */
++
++#include <IIOP/IIOP.h> /* for giop_connection */
++
++#include "corba_object.h"
++#include "corba_basic_sequences_type.h"
++
++#include "orbit_object_type.h"
++
++struct CORBA_Object_struct {
++ struct ORBit_RootObject_struct parent;
++ CORBA_ORB orb;
++ GIOPConnection *connection;
++ CORBA_char *object_id;
++ GSList *profile_list;
++ GSList *forward_locations;
++ ORBit_Object_info *active_profile; /* points at a member of profile_list or forward_locations */
++
++ /* Used for direct calls */
++ gpointer *vepv;
++ /* PortableServer_Servant - looping includes :( */ gpointer servant;
++ guint vepv_size;
++};
++
++
++#endif /* !_ORBIT_CORBA_OBJECT_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_orb.h linux-2.4.1-korbit/net/korbit/orb/corba_orb.h
+--- linux-2.4.1/net/korbit/orb/corba_orb.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_orb.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,48 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ORB_H_
++#define _ORBIT_CORBA_ORB_H_
++
++typedef char *CORBA_ORB_ObjectId;
++
++#ifndef CORBA_POLICY_TYPE
++#define CORBA_POLICY_TYPE 1
++/* We need to define this in corba_orb_type.h as well, sometimes... */
++typedef struct CORBA_Policy_type *CORBA_Policy;
++#endif
++
++typedef CORBA_unsigned_long CORBA_PolicyType;
++
++typedef struct CORBA_ORB_type *CORBA_ORB;
++
++typedef struct CORBA_DomainManager_type *CORBA_DomainManager;
++
++typedef struct CORBA_ConstructionPolicy_type *CORBA_ConstructionPolicy;
++
++#define ex_CORBA_ORB_InvalidName "IDL:CORBA/ORB/InvalidName:1.0"
++
++#endif /* !_ORBIT_CORBA_ORB_H_ */
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_orb_type.h linux-2.4.1-korbit/net/korbit/orb/corba_orb_type.h
+--- linux-2.4.1/net/korbit/orb/corba_orb_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_orb_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,77 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ORB_TYPE_H_
++#define _ORBIT_CORBA_ORB_TYPE_H_
++
++#include "corba_object.h"
++
++struct CORBA_ORB_type {
++ struct ORBit_PseudoObject_struct parent;
++ CORBA_ORBid orb_identifier;
++ CORBA_RepositoryId repoid;
++ CORBA_boolean use_poa;
++
++ CORBA_Object imr, ir, naming, root_poa;
++ struct {
++ GIOPConnection *ipv4;
++ GIOPConnection *ipv6;
++ GIOPConnection *usock;
++ } cnx;
++
++ GHashTable *objrefs;
++
++ GPtrArray *poas;
++
++ CORBA_Context default_ctx;
++};
++
++#define CORBA_ORB_CAST(orb) ((CORBA_ORB)orb)
++
++typedef struct CORBA_ORB_InvalidName {
++ int dummy;
++} CORBA_ORB_InvalidName;
++
++struct CORBA_Policy_type {
++ struct ORBit_PseudoObject_struct parent;
++ CORBA_PolicyType policy_type;
++};
++#ifndef CORBA_POLICY_TYPE
++#define CORBA_POLICY_TYPE 1
++typedef struct CORBA_Policy_type *CORBA_Policy;
++#endif
++
++struct CORBA_DomainManager_type {
++ struct ORBit_PseudoObject_struct parent;
++};
++
++#define CORBA_SecConstruction (11)
++
++struct CORBA_ConstructionPolicy_type {
++ int fill_me_in;
++};
++
++
++#endif /* !_ORBIT_CORBA_ORB_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_portableserver.h linux-2.4.1-korbit/net/korbit/orb/corba_portableserver.h
+--- linux-2.4.1/net/korbit/orb/corba_portableserver.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_portableserver.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,80 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_PORTABLESERVER_H_
++#define _ORBIT_CORBA_PORTABLESERVER_H_
++
++typedef struct PortableServer_ThreadPolicy_type *PortableServer_ThreadPolicy;
++typedef struct PortableServer_LifespanPolicy_type *PortableServer_LifespanPolicy;
++typedef struct PortableServer_IdUniquenessPolicy_type *PortableServer_IdUniquenessPolicy;
++typedef struct PortableServer_IdAssignmentPolicy_type *PortableServer_IdAssignmentPolicy;
++typedef struct PortableServer_ImplicitActivationPolicy_type *PortableServer_ImplicitActivationPolicy;
++typedef struct PortableServer_ServantRetentionPolicy_type *PortableServer_ServantRetentionPolicy;
++typedef struct PortableServer_RequestProcessingPolicy_type *PortableServer_RequestProcessingPolicy;
++typedef struct PortableServer_POAManager_type* PortableServer_POAManager;
++typedef struct PortableServer_AdapterActivator_type *PortableServer_AdapterActivator;
++typedef struct PortableServer_ServantManager_type *PortableServer_ServantManager;
++typedef struct PortableServer_ServantActivator_type *PortableServer_ServantActivator;
++typedef struct PortableServer_ServantLocator_type *PortableServer_ServantLocator;
++typedef struct PortableServer_POA_type *PortableServer_POA;
++typedef struct PortableServer_Current_type *PortableServer_Current;
++
++typedef enum {
++ PortableServer_ORB_CTRL_MODEL=0,
++ PortableServer_SINGLE_THREAD_MODEL
++} PortableServer_ThreadPolicyValue;
++
++typedef enum {
++ PortableServer_TRANSIENT=0,
++ PortableServer_PERSISTENT
++} PortableServer_LifespanPolicyValue;
++
++typedef enum {
++ PortableServer_UNIQUE_ID=0,
++ PortableServer_MULTIPLE_ID
++} PortableServer_IdUniquenessPolicyValue;
++
++typedef enum {
++ PortableServer_USER_ID=0,
++ PortableServer_SYSTEM_ID
++} PortableServer_IdAssignmentPolicyValue;
++
++typedef enum {
++ PortableServer_IMPLICIT_ACTIVATION=0,
++ PortableServer_NO_IMPLICIT_ACTIVATION
++} PortableServer_ImplicitActivationPolicyValue;
++
++typedef enum {
++ PortableServer_RETAIN=0,
++ PortableServer_NON_RETAIN
++} PortableServer_ServantRetentionPolicyValue;
++
++typedef enum {
++ PortableServer_USE_ACTIVE_OBJECT_MAP_ONLY=0,
++ PortableServer_USE_DEFAULT_SERVANT,
++ PortableServer_USE_SERVANT_MANAGER
++} PortableServer_RequestProcessingPolicyValue;
++
++#endif /* !_ORBIT_CORBA_PORTABLESERVER_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_portableserver_type.h linux-2.4.1-korbit/net/korbit/orb/corba_portableserver_type.h
+--- linux-2.4.1/net/korbit/orb/corba_portableserver_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_portableserver_type.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,361 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_PORTABLESERVER_TYPE_H_
++#define _ORBIT_CORBA_PORTABLESERVER_TYPE_H_
++
++/* 19.26 */
++
++typedef void *PortableServer_ServantLocator_Cookie;
++typedef void *PortableServer_Servant;
++
++#ifndef _PortableServer_ForwardRequest_defined
++#define _PortableServer_ForwardRequest_defined
++
++typedef struct PortableServer_ForwardRequest {
++ CORBA_Object forward_reference;
++} PortableServer_ForwardRequest;
++
++#define ex_PortableServer_ForwardRequest "IDL:PortableServer/ForwardRequest:1.0"
++#endif /* !_PortableServer_ForwardRequest_defined */
++
++#define PortableServer_THREAD_POLICY_ID 16
++struct PortableServer_ThreadPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_ThreadPolicyValue value;
++};
++
++#define PortableServer_LIFESPAN_POLICY_ID 17
++extern const CORBA_PolicyType PortableServer_LifespanPolicy_PolicyType;
++struct PortableServer_LifespanPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_LifespanPolicyValue value;
++};
++
++#define PortableServer_ID_UNIQUENESS_POLICY_ID 18
++struct PortableServer_IdUniquenessPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_IdUniquenessPolicyValue value;
++};
++
++#define PortableServer_ID_ASSIGNMENT_POLICY_ID 19
++struct PortableServer_IdAssignmentPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_IdAssignmentPolicyValue value;
++};
++
++#define PortableServer_IMPLICIT_ACTIVATION_POLICY_ID 20
++struct PortableServer_ImplicitActivationPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_ImplicitActivationPolicyValue value;
++};
++
++#define PortableServer_SERVANT_RETENTION_POLICY_ID 21
++struct PortableServer_ServantRetentionPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_ServantRetentionPolicyValue value;
++};
++
++#define PortableServer_REQUEST_PROCESSING_POLICY_ID 22
++struct PortableServer_RequestProcessingPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_RequestProcessingPolicyValue value;
++};
++
++#ifndef _PortableServer_POAManager_AdapterInactive_defined
++#define _PortableServer_POAManager_AdapterInactive_defined
++
++typedef struct PortableServer_POAManager_AdapterInactive {
++ int fill_me_in;
++} PortableServer_POAManager_AdapterInactive;
++
++#define ex_PortableServer_POAManager_AdapterInactive "IDL:PortableServer/POAManager/AdapterInactive:1.0"
++#endif /* !_PortableServer_POAManager_AdapterInactive_defined */
++
++typedef enum { PortableServer_POAManager_HOLDING,
++ PortableServer_POAManager_ACTIVE,
++ PortableServer_POAManager_DISCARDING,
++ PortableServer_POAManager_INACTIVE
++} PortableServer_POAManager_State;
++
++struct PortableServer_POAManager_type {
++ struct ORBit_PseudoObject_struct parent;
++ GSList* poa_collection;
++ CORBA_ORB orb;
++ PortableServer_POAManager_State state;
++};
++
++struct PortableServer_AdapterActivator_type {
++ int fill_me_in;
++};
++
++struct PortableServer_ServantManager_type {
++ int fill_me_in;
++};
++
++#ifndef _PortableServer_POA_AdapterAlreadyExists_defined
++#define _PortableServer_POA_AdapterAlreadyExists_defined
++
++typedef struct PortableServer_POA_AdapterAlreadyExists {
++ int fill_me_in;
++} PortableServer_POA_AdapterAlreadyExists;
++
++#define ex_PortableServer_POA_AdapterAlreadyExists "IDL:PortableServer/POA/AdapterAlreadyExists:1.0"
++#endif /* !_PortableServer_POA_AdapterAlreadyExists_defined */
++
++#ifndef _PortableServer_POAManager_AdapterInactive_defined
++#define _PortableServer_POAManager_AdapterInactive_defined
++
++typedef struct PortableServer_POAManager_AdapterInactive {
++ int fill_me_in;
++} PortableServer_POAManager_AdapterInactive;
++
++#define ex_PortableServer_POAManager_AdapterInactive "IDL:PortableServer/POAManager/AdapterInactive:1.0"
++#endif /* !_PortableServer_POAManager_AdapterInactive_defined */
++
++#ifndef _PortableServer_POA_AdapterNonExistent_defined
++#define _PortableServer_POA_AdapterNonExistent_defined
++
++typedef struct PortableServer_POA_AdapterNonExistent {
++ int fill_me_in;
++} PortableServer_POA_AdapterNonExistent;
++
++#define ex_PortableServer_POA_AdapterNonExistent "IDL:PortableServer/POA/AdapterNonExistent:1.0"
++#endif /* !_PortableServer_POA_AdapterNonExistent_defined */
++
++#ifndef _PortableServer_POA_InvalidPolicy_defined
++#define _PortableServer_POA_InvalidPolicy_defined
++
++typedef struct PortableServer_POA_InvalidPolicy {
++ CORBA_unsigned_short index;
++} PortableServer_POA_InvalidPolicy;
++
++#define ex_PortableServer_POA_InvalidPolicy "IDL:PortableServer/POA/InvalidPolicy:1.0"
++#endif /* !_PortableServer_POA_InvalidPolicy_defined */
++
++#ifndef _PortableServer_POA_NoServant_defined
++#define _PortableServer_POA_NoServant_defined
++
++typedef struct PortableServer_POA_NoServant {
++ int fill_me_in;
++} PortableServer_POA_NoServant;
++
++#define ex_PortableServer_POA_NoServant "IDL:PortableServer/POA/NoServant:1.0"
++#endif /* !_PortableServer_POA_NoServant_defined */
++
++#ifndef _PortableServer_POA_ObjectAlreadyActive_defined
++#define _PortableServer_POA_ObjectAlreadyActive_defined
++
++typedef struct PortableServer_POA_ObjectAlreadyActive {
++ int fill_me_in;
++} PortableServer_POA_ObjectAlreadyActive;
++
++#define ex_PortableServer_POA_ObjectAlreadyActive "IDL:PortableServer/POA/ObjectAlreadyActive:1.0"
++#endif /* !_PortableServer_POA_ObjectAlreadyActive_defined */
++
++#ifndef _PortableServer_POA_ObjectNotActive_defined
++#define _PortableServer_POA_ObjectNotActive_defined
++
++typedef struct PortableServer_POA_ObjectNotActive {
++ int fill_me_in;
++} PortableServer_POA_ObjectNotActive;
++
++#define ex_PortableServer_POA_ObjectNotActive "IDL:PortableServer/POA/ObjectNotActive:1.0"
++#endif /* !_PortableServer_POA_ObjectNotActive_defined */
++
++#ifndef _PortableServer_POA_ServantAlreadyActive_defined
++#define _PortableServer_POA_ServantAlreadyActive_defined
++
++typedef struct PortableServer_POA_ServantAlreadyActive {
++ int fill_me_in;
++} PortableServer_POA_ServantAlreadyActive;
++
++#define ex_PortableServer_POA_ServantAlreadyActive "IDL:PortableServer/POA/ServantAlreadyActive:1.0"
++#endif /* !_PortableServer_POA_ServantAlreadyActive_defined */
++
++#ifndef _PortableServer_POA_ServantNotActive_defined
++#define _PortableServer_POA_ServantNotActive_defined
++
++typedef struct PortableServer_POA_ServantNotActive {
++ int fill_me_in;
++} PortableServer_POA_ServantNotActive;
++
++#define ex_PortableServer_POA_ServantNotActive "IDL:PortableServer/POA/ServantNotActive:1.0"
++#endif /* !_PortableServer_POA_ServantNotActive_defined */
++
++#ifndef _PortableServer_POA_WrongAdapter_defined
++#define _PortableServer_POA_WrongAdapter_defined
++
++typedef struct PortableServer_POA_WrongAdapter {
++ int fill_me_in;
++} PortableServer_POA_WrongAdapter;
++
++#define ex_PortableServer_POA_WrongAdapter "IDL:PortableServer/POA/WrongAdapter:1.0"
++#endif /* !_PortableServer_POA_WrongAdapter_defined */
++
++#ifndef _PortableServer_POA_WrongPolicy_defined
++#define _PortableServer_POA_WrongPolicy_defined
++
++typedef struct PortableServer_POA_WrongPolicy {
++ int fill_me_in;
++} PortableServer_POA_WrongPolicy;
++
++#define ex_PortableServer_POA_WrongPolicy "IDL:PortableServer/POA/WrongPolicy:1.0"
++#endif /* !_PortableServer_POA_WrongPolicy_defined */
++
++#ifndef _PortableServer_Current_NoContext_defined
++#define _PortableServer_Current_NoContext_defined
++
++typedef struct PortableServer_Current_NoContext {
++ int fill_me_in;
++} PortableServer_Current_NoContext;
++
++#define ex_PortableServer_Current_NoContext "IDL:PortableServer/Current/NoContext:1.0"
++#endif /* !_PortableServer_Current_NoContext_defined */
++
++struct PortableServer_Current_type {
++ int fill_me_in;
++};
++
++typedef struct PortableServer_ServantBase__epv {
++ void *_private;
++ void (*finalize)(PortableServer_Servant, CORBA_Environment *);
++ PortableServer_POA (*default_POA)(PortableServer_Servant, CORBA_Environment *);
++} PortableServer_ServantBase__epv;
++
++typedef PortableServer_ServantBase__epv *PortableServer_ServantBase__vepv;
++
++typedef struct PortableServer_ServantBase {
++ void *_private;
++ PortableServer_ServantBase__vepv *vepv;
++} PortableServer_ServantBase;
++
++/* 19.27 */
++
++typedef void (*PortableServer_DynamicImplRoutine) (PortableServer_Servant servant, CORBA_ServerRequest request);
++
++typedef struct PortableServer_DynamicImpl__epv {
++ void *_private;
++ PortableServer_DynamicImplRoutine invoke;
++ CORBA_RepositoryId (*primary_interface) (PortableServer_Servant svt, PortableServer_ObjectId id, PortableServer_POA poa, CORBA_Environment *env);
++} PortableServer_DynamicImpl__epv;
++
++typedef struct PortableServer_DynamicImpl__vepv {
++ PortableServer_ServantBase__epv *_base_epv;
++ PortableServer_DynamicImpl__epv *PortableServer_DynamicImpl_epv;
++} PortableServer_DynamicImpl__vepv;
++
++typedef struct PortableServer_DynamicImpl {
++ void *_private;
++ PortableServer_DynamicImpl__vepv *vepv;
++} PortableServer_DynamicImpl;
++
++typedef struct {
++ void *_private;
++} POA_PortableServer_ServantManager__epv;
++
++typedef struct {
++ void *_private;
++
++ PortableServer_Servant (*incarnate) (PortableServer_Servant servant,
++ PortableServer_ObjectId * oid,
++ PortableServer_POA adapter,
++ CORBA_Environment * ev);
++
++ void (*etherealize) (PortableServer_Servant servant,
++ PortableServer_ObjectId* oid,
++ PortableServer_POA adapter,
++ PortableServer_Servant serv,
++ CORBA_boolean cleanup_in_progress,
++ CORBA_boolean remaining_activations,
++ CORBA_Environment * ev);
++
++} POA_PortableServer_ServantActivator__epv;
++
++typedef struct {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_PortableServer_ServantManager__epv *PortableServer_ServantManager_epv;
++ POA_PortableServer_ServantActivator__epv *PortableServer_ServantActivator_epv;
++} POA_PortableServer_ServantActivator__vepv;
++
++typedef struct {
++ void *_private;
++ POA_PortableServer_ServantActivator__vepv *vepv;
++} POA_PortableServer_ServantActivator;
++
++extern void
++POA_PortableServer_ServantActivator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++extern void
++POA_PortableServer_ServantActivator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++typedef struct {
++ void *_private;
++
++ PortableServer_Servant (*preinvoke) (PortableServer_Servant servant,
++ PortableServer_ObjectId * oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier operation,
++ PortableServer_ServantLocator_Cookie *the_cookie,
++ CORBA_Environment * ev);
++
++ void (*postinvoke) (PortableServer_Servant servant,
++ PortableServer_ObjectId * oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier operation,
++ PortableServer_ServantLocator_Cookie the_cookie,
++ PortableServer_Servant the_servant,
++ CORBA_Environment * ev);
++} POA_PortableServer_ServantLocator__epv;
++
++typedef struct {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_PortableServer_ServantManager__epv *PortableServer_ServantManager_epv;
++ POA_PortableServer_ServantLocator__epv *PortableServer_ServantLocator_epv;
++} POA_PortableServer_ServantLocator__vepv;
++
++typedef struct {
++ void *_private;
++ POA_PortableServer_ServantLocator__vepv *vepv;
++} POA_PortableServer_ServantLocator;
++
++extern void
++POA_PortableServer_ServantLocator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++extern void
++POA_PortableServer_ServantLocator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++struct CORBA_ServerRequest_type {
++ struct ORBit_PseudoObject_struct parent;
++ GIOPRecvBuffer *rbuf;
++ GIOPSendBuffer *sbuf;
++ CORBA_NVList *params;
++ CORBA_ORB orb;
++ guchar did_ctx, did_exc;
++};
++
++#endif /* !_ORBIT_CORBA_PORTABLESERVER_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_sequences.h linux-2.4.1-korbit/net/korbit/orb/corba_sequences.h
+--- linux-2.4.1/net/korbit/orb/corba_sequences.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_sequences.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,74 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_SEQUENCES_H_
++#define _ORBIT_CORBA_SEQUENCES_H_
++
++
++/* moved from sequences.h */
++#include "corba_basic_sequences_type.h"
++
++typedef CORBA_sequence_octet CORBA_ReferenceData;
++
++#define _CORBA_sequence_ServiceOption_defined
++typedef struct CORBA_sequence_ServiceOption CORBA_sequence_ServiceOption;
++
++#define _CORBA_sequence_ServiceDetail_defined
++typedef struct CORBA_sequence_ServiceDetail CORBA_sequence_ServiceDetail;
++
++#define _CORBA_sequence_ORB_ObjectId_defined
++typedef struct CORBA_sequence_ORB_ObjectId CORBA_ORB_ObjectIdList;
++
++#define _CORBA_sequence_NameValuePair_defined
++typedef struct CORBA_sequence_NameValuePair CORBA_NameValuePairSeq;
++
++#define _CORBA_sequence_CORBA_any_defined
++typedef struct CORBA_sequence_CORBA_any_struct CORBA_AnySeq;
++typedef struct CORBA_sequence_CORBA_any_struct CORBA_sequence_CORBA_any;
++
++#define _CORBA_sequence_Policy_defined
++typedef struct CORBA_sequence_Policy CORBA_PolicyList;
++
++#define _CORBA_sequence_DomainManager_defined
++typedef struct CORBA_sequence_DomainManager CORBA_DomainManagerList;
++
++#define _PortableServer_sequence_octet_defined
++typedef struct PortableServer_sequence_octet PortableServer_ObjectId;
++
++
++/* Moved from orbit_types.h */
++#ifndef HAVE_CORBA_PRINCIPAL
++#define HAVE_CORBA_PRINCIPAL 1
++typedef CORBA_sequence_octet CORBA_Principal;
++#endif
++typedef CORBA_sequence_octet CORBA_DynAny_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynFixed_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynEnum_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynStruct_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynUnion_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynSequence_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynArray_OctetSeq;
++
++#endif /* !_ORBIT_CORBA_SEQUENCES_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_sequences_type.h linux-2.4.1-korbit/net/korbit/orb/corba_sequences_type.h
+--- linux-2.4.1/net/korbit/orb/corba_sequences_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_sequences_type.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,98 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_SEQUENCES_TYPE_H_
++#define _ORBIT_CORBA_SEQUENCES_TYPE_H_
++
++#include "corba_sequences.h"
++
++struct CORBA_sequence_ServiceOption {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_ServiceOption *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_ServiceDetail {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_ServiceDetail *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_ORB_ObjectId {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_ORB_ObjectId *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_NameValuePair {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ struct CORBA_NameValuePair *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_CORBA_any_struct {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_any *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_Policy {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_Policy *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_DomainManager {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_DomainManager *_buffer;
++ CORBA_boolean _release;
++};
++
++struct PortableServer_sequence_octet {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_octet *_buffer;
++ CORBA_boolean _release;
++};
++
++/* Generic sequence */
++struct CORBA_Sequence_type {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ void *_buffer;
++ CORBA_boolean _release;
++};
++
++#define CORBA_SEQFLAGS_RELEASE 1
++
++
++#endif /* !_ORBIT_CORBA_SEQUENCES_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_typecode.h linux-2.4.1-korbit/net/korbit/orb/corba_typecode.h
+--- linux-2.4.1/net/korbit/orb/corba_typecode.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_typecode.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,167 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_TYPECODE_H_
++#define _ORBIT_CORBA_TYPECODE_H_
++
++/* moved from orbit_types.h */
++typedef struct CORBA_TypeCode_struct *CORBA_TypeCode;
++
++typedef enum {
++ CORBA_tk_null=0,
++ CORBA_tk_void=1,
++ CORBA_tk_short=2,
++ CORBA_tk_long=3,
++ CORBA_tk_ushort=4,
++ CORBA_tk_ulong=5,
++ CORBA_tk_float=6,
++ CORBA_tk_double=7,
++ CORBA_tk_boolean=8,
++ CORBA_tk_char=9,
++ CORBA_tk_octet=10,
++ CORBA_tk_any=11,
++ CORBA_tk_TypeCode=12,
++ CORBA_tk_Principal=13,
++ CORBA_tk_objref=14,
++ CORBA_tk_struct=15,
++ CORBA_tk_union=16,
++ CORBA_tk_enum=17,
++ CORBA_tk_string=18,
++ CORBA_tk_sequence=19,
++ CORBA_tk_array=20,
++ CORBA_tk_alias=21,
++ CORBA_tk_except=22,
++ CORBA_tk_longlong=23,
++ CORBA_tk_ulonglong=24,
++ CORBA_tk_longdouble=25,
++ CORBA_tk_wchar=26,
++ CORBA_tk_wstring=27,
++ CORBA_tk_fixed=28,
++ CORBA_tk_recursive=0xffffffff,
++ CORBA_tk_last=29 /* hack for GIOP */
++} CORBA_TCKind;
++
++#define TC_CORBA_short TC_short
++#define TC_CORBA_long TC_long
++#define TC_CORBA_longlong TC_longlong
++#define TC_CORBA_long_long TC_longlong
++#define TC_CORBA_ushort TC_ushort
++#define TC_CORBA_unsigned_short TC_ushort
++#define TC_CORBA_ulong TC_ulong
++#define TC_CORBA_unsigned_long TC_ulong
++#define TC_CORBA_ulonglong TC_ulonglong
++#define TC_CORBA_unsigned_long_long TC_ulonglong
++#define TC_CORBA_float TC_float
++#define TC_CORBA_double TC_double
++#define TC_CORBA_longdouble TC_longdouble
++#define TC_CORBA_long_double TC_longdouble
++#define TC_CORBA_boolean TC_boolean
++#define TC_CORBA_char TC_char
++#define TC_CORBA_wchar TC_wchar
++#define TC_CORBA_octet TC_octet
++#define TC_CORBA_any TC_any
++#define TC_CORBA_TypeCode TC_TypeCode
++#define TC_CORBA_Principal TC_Principal
++#define TC_CORBA_Object TC_Object
++#define TC_CORBA_string TC_string
++#define TC_CORBA_wstring TC_wstring
++
++#define TC_null ((CORBA_TypeCode)&TC_null_struct)
++#define TC_void ((CORBA_TypeCode)&TC_void_struct)
++#define TC_short ((CORBA_TypeCode)&TC_short_struct)
++#define TC_long ((CORBA_TypeCode)&TC_long_struct)
++#define TC_longlong ((CORBA_TypeCode)&TC_longlong_struct)
++#define TC_ushort ((CORBA_TypeCode)&TC_ushort_struct)
++#define TC_ulong ((CORBA_TypeCode)&TC_ulong_struct)
++#define TC_ulonglong ((CORBA_TypeCode)&TC_ulonglong_struct)
++#define TC_float ((CORBA_TypeCode)&TC_float_struct)
++#define TC_double ((CORBA_TypeCode)&TC_double_struct)
++#define TC_longdouble ((CORBA_TypeCode)&TC_longdouble_struct)
++#define TC_boolean ((CORBA_TypeCode)&TC_boolean_struct)
++#define TC_char ((CORBA_TypeCode)&TC_char_struct)
++#define TC_wchar ((CORBA_TypeCode)&TC_wchar_struct)
++#define TC_octet ((CORBA_TypeCode)&TC_octet_struct)
++#define TC_any ((CORBA_TypeCode)&TC_any_struct)
++#define TC_TypeCode ((CORBA_TypeCode)&TC_TypeCode_struct)
++#define TC_Principal ((CORBA_TypeCode)&TC_Principal_struct)
++#define TC_Object ((CORBA_TypeCode)&TC_Object_struct)
++#define TC_string ((CORBA_TypeCode)&TC_string_struct)
++#define TC_wstring ((CORBA_TypeCode)&TC_wstring_struct)
++#define TC_CORBA_NamedValue ((CORBA_TypeCode)&TC_CORBA_NamedValue_struct)
++
++#define TC_CORBA_short_struct TC_short_struct
++#define TC_CORBA_long_struct TC_long_struct
++#define TC_CORBA_longlong_struct TC_longlong_struct
++#define TC_CORBA_long_long_struct TC_longlong_struct
++#define TC_CORBA_ushort_struct TC_ushort_struct
++#define TC_CORBA_unsigned_short_struct TC_ushort_struct
++#define TC_CORBA_ulong_struct TC_ulong_struct
++#define TC_CORBA_unsigned_long_struct TC_ulong_struct
++#define TC_CORBA_ulonglong_struct TC_ulonglong_struct
++#define TC_CORBA_unsigned_long_long_struct TC_ulonglong_struct
++#define TC_CORBA_float_struct TC_float_struct
++#define TC_CORBA_double_struct TC_double_struct
++#define TC_CORBA_longdouble_struct TC_longdouble_struct
++#define TC_CORBA_long_double_struct TC_longdouble_struct
++#define TC_CORBA_boolean_struct TC_boolean_struct
++#define TC_CORBA_char_struct TC_char_struct
++#define TC_CORBA_wchar_struct TC_wchar_struct
++#define TC_CORBA_octet_struct TC_octet_struct
++#define TC_CORBA_any_struct TC_any_struct
++#define TC_CORBA_TypeCode_struct TC_TypeCode_struct
++#define TC_CORBA_Principal_struct TC_Principal_struct
++#define TC_CORBA_Object_struct TC_Object_struct
++#define TC_CORBA_string_struct TC_string_struct
++#define TC_CORBA_wstring_struct TC_wstring_struct
++
++extern const struct CORBA_TypeCode_struct TC_null_struct;
++extern const struct CORBA_TypeCode_struct TC_void_struct;
++extern const struct CORBA_TypeCode_struct TC_short_struct;
++extern const struct CORBA_TypeCode_struct TC_long_struct;
++extern const struct CORBA_TypeCode_struct TC_longlong_struct;
++extern const struct CORBA_TypeCode_struct TC_ushort_struct;
++extern const struct CORBA_TypeCode_struct TC_ulong_struct;
++extern const struct CORBA_TypeCode_struct TC_ulonglong_struct;
++extern const struct CORBA_TypeCode_struct TC_float_struct;
++extern const struct CORBA_TypeCode_struct TC_double_struct;
++extern const struct CORBA_TypeCode_struct TC_longdouble_struct;
++extern const struct CORBA_TypeCode_struct TC_boolean_struct;
++extern const struct CORBA_TypeCode_struct TC_char_struct;
++extern const struct CORBA_TypeCode_struct TC_wchar_struct;
++extern const struct CORBA_TypeCode_struct TC_octet_struct;
++extern const struct CORBA_TypeCode_struct TC_any_struct;
++extern const struct CORBA_TypeCode_struct TC_TypeCode_struct;
++extern const struct CORBA_TypeCode_struct TC_Principal_struct;
++extern const struct CORBA_TypeCode_struct TC_Object_struct;
++extern const struct CORBA_TypeCode_struct TC_string_struct;
++extern const struct CORBA_TypeCode_struct TC_wstring_struct;
++extern const struct CORBA_TypeCode_struct TC_CORBA_NamedValue_struct;
++
++
++#endif /* !_ORBIT_CORBA_TYPECODE_H_ */
++
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_typecode_type.h linux-2.4.1-korbit/net/korbit/orb/corba_typecode_type.h
+--- linux-2.4.1/net/korbit/orb/corba_typecode_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_typecode_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,66 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_TYPECODE_TYPE_H_
++#define _ORBIT_CORBA_TYPECODE_TYPE_H_
++
++#include <ORBitutil/basic_types.h>
++#include "corba_typecode.h"
++#include "corba_any.h"
++
++typedef struct CORBA_TypeCode_Bounds {
++ int dummy;
++} CORBA_TypeCode_Bounds;
++
++typedef struct CORBA_TypeCode_BadKind {
++ int dummy;
++} CORBA_TypeCode_BadKind;
++
++struct CORBA_TypeCode_struct {
++ struct ORBit_PseudoObject_struct parent;
++ CORBA_TCKind kind;
++#ifndef __KORBIT__
++ const
++#endif
++ char *name;
++#ifndef __KORBIT__
++ const
++#endif
++ char *repo_id;
++ CORBA_unsigned_long length;
++ CORBA_unsigned_long sub_parts;
++ const char **subnames; /* for struct, exception, union, enum */
++ CORBA_TypeCode *subtypes; /* for struct, exception, union, alias, array, sequence */
++ CORBA_any *sublabels; /* for union */
++ CORBA_TypeCode discriminator; /* for union */
++ CORBA_unsigned_long recurse_depth; /* for recursive sequence */
++ CORBA_long default_index; /* for union */
++ CORBA_unsigned_short digits; /* for fixed */
++ CORBA_short scale; /* for fixed */
++};
++
++
++#endif /* !_ORBIT_CORBA_TYPECODE_TYPE_H_ */
++
+diff -urN linux-2.4.1/net/korbit/orb/dii.c linux-2.4.1-korbit/net/korbit/orb/dii.c
+--- linux-2.4.1/net/korbit/orb/dii.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/dii.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,454 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Red Hat Software, Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Elliot Lee <sopwith@redhat.com>
++ * Dick Porter <dick@cymru.net>
++ *
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++
++#include "orbit.h"
++#ifndef __KORBIT__
++#include "interface_repository.h"
++#endif /* !__KORBIT__ */
++
++struct CORBA_Request_type {
++ struct ORBit_PseudoObject_struct parent;
++
++ CORBA_Object obj;
++ CORBA_Context ctx;
++
++ CORBA_Flags req_flags;
++ CORBA_Identifier operation;
++
++ CORBA_NamedValue *result;
++ CORBA_NVList *arg_list;
++
++ CORBA_unsigned_long request_id;
++ GIOPSendBuffer *request_buffer;
++ GIOPRecvBuffer *reply_buffer;
++};
++
++static const ORBit_RootObject_Interface interface_CORBA_Request = {
++ (void (*)(gpointer,CORBA_Environment *))CORBA_Request_delete
++};
++
++/* Section 5.2.1 */
++CORBA_Status
++CORBA_Object_create_request(CORBA_Object obj,
++ CORBA_Context ctx,
++ CORBA_Identifier operation,
++ CORBA_NVList *arg_list,
++ CORBA_NamedValue *result,
++ CORBA_Request *request,
++ CORBA_Flags req_flags,
++ CORBA_Environment *ev)
++{
++ CORBA_Request new;
++
++ new=g_new0(struct CORBA_Request_type, 1);
++ ORBit_pseudo_object_init((ORBit_PseudoObject)new, ORBIT_PSEUDO_REQUEST, ev);
++ ORBit_RootObject_set_interface((ORBit_RootObject)new,
++ (ORBit_RootObject_Interface *)&interface_CORBA_Request, ev);
++
++ if(new==NULL) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ new->obj=CORBA_Object_duplicate(obj, ev);
++ new->ctx=(CORBA_Context)CORBA_Object_duplicate((CORBA_Object)ctx, ev);
++ new->operation=CORBA_string_dup(operation);
++
++ new->result=result;
++
++ new->req_flags=req_flags;
++ new->request_id = giop_get_request_id();
++ new->arg_list = arg_list;
++
++ *request=(CORBA_Request)CORBA_Object_duplicate((CORBA_Object)new, ev);
++}
++
++/* Section 5.2, 5.2.2 */
++CORBA_Status
++CORBA_Request_add_arg(CORBA_Request req,
++ CORBA_Identifier name,
++ CORBA_TypeCode arg_type,
++ void *value,
++ CORBA_long len,
++ CORBA_Flags arg_flags,
++ CORBA_Environment *ev)
++{
++ gpointer new_value;
++
++ g_assert(req!=NULL);
++
++ if((arg_flags & CORBA_IN_COPY_VALUE) && (arg_flags & CORBA_ARG_IN)) {
++ new_value = ORBit_copy_value(value, arg_type);
++ if(new_value==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++ } else
++ new_value=value;
++
++ CORBA_NVList_add_item(req->arg_list, name, arg_type,
++ new_value, len, arg_flags | req->req_flags, ev);
++}
++
++/* Section 5.2, 5.2.3 */
++CORBA_Status
++CORBA_Request_invoke(CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev)
++{
++ CORBA_Request_send(req, invoke_flags, ev);
++ if(ev->_major == CORBA_NO_EXCEPTION)
++ CORBA_Request_get_response(req, invoke_flags, ev);
++}
++
++/* Section 5.2, 5.2.4 */
++CORBA_Status CORBA_Request_delete(CORBA_Request req, CORBA_Environment *ev)
++{
++ CORBA_Object_release(req->obj, ev);
++ CORBA_Object_release((CORBA_Object)req->ctx, ev);
++
++ if(req->operation != NULL)
++ CORBA_free(req->operation);
++
++ if(req->arg_list != NULL) {
++ if(req->req_flags & CORBA_OUT_LIST_MEMORY)
++ CORBA_NVList_free(req->arg_list, ev);
++ else {
++ int i;
++ for(i = 0; i < req->arg_list->list->len; i++)
++ ORBit_NamedValue_free(&g_array_index(req->arg_list->list,
++ CORBA_NamedValue, i));
++ g_array_free(req->arg_list->list, TRUE);
++
++ g_free(req->arg_list);
++ }
++ }
++
++ if(req->result!=NULL)
++ ORBit_NamedValue_free(req->result);
++
++ if(req->request_buffer)
++ giop_send_buffer_unuse(req->request_buffer);
++
++ if(req->reply_buffer)
++ giop_recv_buffer_unuse(req->reply_buffer);
++
++ g_free(req);
++}
++
++/* Section 5.2, 5.3.1 */
++CORBA_Status
++CORBA_Request_send(CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev)
++{
++ int i;
++ GIOPConnection *cnx;
++
++ struct { CORBA_unsigned_long opstrlen; char opname[1]; } *opnameinfo;
++ struct iovec opvec = { NULL, 0 };
++
++ opvec.iov_len = strlen(req->operation)+1+sizeof(CORBA_unsigned_long);
++
++ opnameinfo = g_malloc(strlen(req->operation)+1+sizeof(CORBA_unsigned_long));
++ opvec.iov_base = (gpointer)opnameinfo;
++ opnameinfo->opstrlen = strlen(req->operation) + 1;
++ strcpy(opnameinfo->opname, req->operation);
++
++ cnx = ORBit_object_get_connection(req->obj);
++
++ g_assert(req->obj->active_profile);
++ req->request_buffer =
++ giop_send_request_buffer_use(req->obj->connection,
++ NULL,
++ req->request_id,
++ req->result?TRUE:FALSE,
++ &(req->obj->active_profile->object_key_vec),
++ &opvec,
++ &ORBit_default_principal_iovec
++ );
++
++ if(!req->request_buffer) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ for(i = 0; i < req->arg_list->list->len; i++) {
++ CORBA_NamedValue *nv;
++
++ nv = &g_array_index(req->arg_list->list, CORBA_NamedValue, i);
++
++ if((nv->arg_modes & CORBA_ARG_IN)
++ || (nv->arg_modes & CORBA_ARG_INOUT))
++ ORBit_marshal_arg(req->request_buffer,
++ nv->argument._value,
++ nv->argument._type);
++ }
++
++ giop_send_buffer_write(req->request_buffer);
++
++ giop_send_buffer_unuse(req->request_buffer);
++ req->request_buffer = 0;
++
++ g_free(opnameinfo);
++}
++
++/* Section 5.3.2 */
++CORBA_Status
++CORBA_send_multiple_requests(CORBA_Request *reqs,
++ CORBA_Environment *env,
++ CORBA_long count,
++ CORBA_Flags invoke_flags)
++{
++ int i;
++
++ for(i = 0; i < count; i++)
++ CORBA_Request_send(reqs[i], invoke_flags, env);
++}
++
++void
++ORBit_handle_dii_reply(CORBA_Request req, CORBA_Environment *ev)
++{
++ int i;
++
++ /* XXX TODO - handle exceptions, location forwards(?), all that */
++ req->result->argument._value =
++ ORBit_demarshal_arg(req->reply_buffer, req->result->argument._type,
++ TRUE, req->obj->orb);
++ req->result->argument._release = CORBA_TRUE;
++
++ for(i = 0; i < req->arg_list->list->len; i++) {
++ CORBA_NamedValue *nv;
++
++ nv = &g_array_index(req->arg_list->list, CORBA_NamedValue, i);
++
++ if(nv->arg_modes & CORBA_ARG_INOUT) {
++ CORBA_Object_duplicate((CORBA_Object)nv->argument._type, NULL);
++ CORBA_any__free(&nv->argument, NULL, TRUE);
++ }
++
++ if((nv->arg_modes & CORBA_ARG_OUT)
++ || (nv->arg_modes & CORBA_ARG_INOUT))
++ nv->argument._value = ORBit_demarshal_arg(req->reply_buffer,
++ nv->argument._type,
++ TRUE, req->obj->orb);
++ }
++
++ giop_recv_buffer_unuse(req->reply_buffer);
++ req->reply_buffer = 0;
++}
++
++/* Section 5.2, 5.3.3
++ *
++ * Raises: WrongTransaction
++ */
++CORBA_Status
++CORBA_Request_get_response(CORBA_Request req,
++ CORBA_Flags response_flags,
++ CORBA_Environment *ev)
++{
++ req->reply_buffer = giop_recv_reply_buffer_use(req->request_id,
++ !(response_flags & CORBA_RESP_NO_WAIT));
++
++ if(!req->reply_buffer) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ ORBit_handle_dii_reply(req, ev);
++}
++
++/* Section 5.3.4
++ *
++ * Raises: WrongTransaction
++ */
++CORBA_Status
++CORBA_Request_get_next_response(CORBA_Environment *env,
++ CORBA_Flags response_flags,
++ CORBA_Request *req)
++{
++ int i;
++ GIOPRecvBuffer *rb;
++ GArray *reqids = g_array_new(FALSE, FALSE,
++ sizeof(CORBA_unsigned_long));
++
++ for(i = 0; req[i]; i++) {
++ g_array_append_val(reqids, req[i]->request_id);
++ }
++
++ rb = giop_recv_reply_buffer_use_multiple(reqids,
++ !(response_flags & CORBA_RESP_NO_WAIT));
++
++ if(rb) {
++ for(i = 0; i < reqids->len; i++) {
++ if(g_array_index(reqids, CORBA_unsigned_long, i)
++ == rb->message.u.reply.request_id) {
++ req[i]->reply_buffer = rb;
++ break;
++ }
++ }
++
++ if(i < reqids->len)
++ ORBit_handle_dii_reply(req[i], env);
++ }
++
++ g_array_free(reqids, TRUE);
++}
++
++
++/* Section 5.4.1 */
++CORBA_Status
++CORBA_ORB_create_list(CORBA_ORB orb,
++ CORBA_long count,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev)
++{
++ CORBA_NVList *new;
++
++ new = g_new0(CORBA_NVList, 1);
++ if(new==NULL) goto new_alloc_failed;
++
++ new->list = g_array_new(FALSE, TRUE, sizeof(CORBA_NamedValue));
++
++ *new_list = new;
++
++ return;
++
++ new_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++}
++
++#ifndef __KORBIT__
++/* Section 5.4.6 */
++CORBA_Status
++CORBA_ORB_create_operation_list(CORBA_ORB orb,
++ CORBA_OperationDef oper,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev)
++{
++ if(!new_list) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ g_warning("CORBA_ORB_create_operation_list NYI");
++
++ CORBA_exception_set_system(ev,
++ ex_CORBA_IMP_LIMIT,
++ CORBA_COMPLETED_NO);
++}
++#endif /* !__KORBIT__ */
++
++/* Section 5.4.2 */
++CORBA_Status
++CORBA_NVList_add_item(CORBA_NVList *list,
++ CORBA_Identifier item_name,
++ CORBA_TypeCode item_type,
++ void *value,
++ CORBA_long value_len,
++ CORBA_Flags item_flags,
++ CORBA_Environment *ev)
++{
++ CORBA_NamedValue newval;
++
++ g_assert(list!=NULL);
++
++ newval.name = CORBA_string_dup(item_name);
++ newval.argument._type = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)item_type, ev);
++ if(item_flags & CORBA_IN_COPY_VALUE) {
++ newval.argument._value = ORBit_copy_value(value, item_type);
++ newval.argument._release = CORBA_TRUE;
++ } else {
++ newval.argument._value = value;
++ newval.argument._release = CORBA_FALSE;
++ }
++
++ newval.len = value_len; /* Is this even useful? *sigh* */
++ newval.arg_modes = item_flags;
++
++ g_array_append_val(list->list, newval);
++}
++
++void ORBit_NamedValue_free(CORBA_NamedValue *nv)
++{
++ CORBA_free(nv->name);
++}
++
++/* Section 5.4.3 */
++CORBA_Status
++CORBA_NVList_free(CORBA_NVList *list,
++ CORBA_Environment *ev)
++{
++ int i;
++
++ CORBA_NVList_free_memory(list, ev);
++
++ for(i = 0; i < list->list->len; i++)
++ ORBit_NamedValue_free(&g_array_index(list->list, CORBA_NamedValue, i));
++
++ g_array_free(list->list, TRUE);
++
++ g_free(list);
++}
++
++/* Section 5.4.4 */
++CORBA_Status
++CORBA_NVList_free_memory(CORBA_NVList *list,
++ CORBA_Environment *ev)
++{
++ int i;
++
++ for(i = 0; i < list->list->len; i++) {
++ CORBA_free(g_array_index(list->list, CORBA_NamedValue, i).argument._value);
++ g_array_index(list->list, CORBA_NamedValue, i).argument._value = NULL;
++ CORBA_Object_release((CORBA_Object)g_array_index(list->list, CORBA_NamedValue, i).argument._type, ev);
++ g_array_index(list->list, CORBA_NamedValue, i).argument._release = CORBA_FALSE;
++ }
++}
++
++
++/* Section 5.4.5 */
++CORBA_Status
++CORBA_NVList_get_count(CORBA_NVList *list,
++ CORBA_long *count,
++ CORBA_Environment *ev)
++{
++ *count = list->list->len;
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/dii.h linux-2.4.1-korbit/net/korbit/orb/dii.h
+--- linux-2.4.1/net/korbit/orb/dii.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/dii.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,124 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_DII_H_
++#define _ORBIT_DII_H_
++
++#include "orb/orbit_types.h"
++#ifndef __KORBIT__
++#include "orb/interface_repository.h"
++#endif /* !__KORBIT__ */
++
++extern CORBA_Status CORBA_Object_create_request(
++ CORBA_Object obj,
++ CORBA_Context ctx,
++ CORBA_Identifier operation,
++ CORBA_NVList *arg_list,
++ CORBA_NamedValue *result,
++ CORBA_Request *request,
++ CORBA_Flags req_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_add_arg(
++ CORBA_Request req,
++ CORBA_Identifier name,
++ CORBA_TypeCode arg_type,
++ void *value,
++ CORBA_long len,
++ CORBA_Flags arg_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_invoke(
++ CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_delete(
++ CORBA_Request req,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_send(
++ CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_send_multiple_requests(
++ CORBA_Request reqs[],
++ CORBA_Environment *env,
++ CORBA_long count,
++ CORBA_Flags invoke_flags);
++
++extern CORBA_Status CORBA_Request_get_response(
++ CORBA_Request req,
++ CORBA_Flags response_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_get_next_response(
++ CORBA_Environment *env,
++ CORBA_Flags response_flags,
++ CORBA_Request *req);
++
++extern CORBA_Status CORBA_NVList_add_item(
++ CORBA_NVList *list,
++ CORBA_Identifier item_name,
++ CORBA_TypeCode item_type,
++ void *value,
++ CORBA_long value_len,
++ CORBA_Flags item_flags,
++ CORBA_Environment *ev);
++
++extern void ORBit_NamedValue_free(
++ CORBA_NamedValue *nv);
++
++
++extern CORBA_Status CORBA_ORB_create_list(
++ CORBA_ORB orb,
++ CORBA_long count,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_Status CORBA_ORB_create_operation_list(
++ CORBA_ORB orb,
++ CORBA_OperationDef oper,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev);
++#endif /* !__KORBIT__ */
++
++extern CORBA_Status CORBA_NVList_free(CORBA_NVList *list,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_NVList_free_memory(
++ CORBA_NVList *list,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_NVList_get_count(
++ CORBA_NVList *list,
++ CORBA_long *count,
++ CORBA_Environment *ev);
++
++extern const int sizeofs[], container_sizeofs[];
++
++#endif /* _ORBIT_DII_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/env.c linux-2.4.1-korbit/net/korbit/orb/env.c
+--- linux-2.4.1/net/korbit/orb/env.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/env.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,345 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++/*
++ * CORBA_Environment handling functions
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++
++#include "orbit.h"
++#ifndef __KORBIT__
++#include "interface_repository.h"
++#endif /* !__KORBIT__ */
++
++struct SysExInfo {
++ const char *repo_id;
++ const int exnum;
++};
++
++static const struct SysExInfo exception_table[] = {
++ {NULL, 0},
++ {"IDL:CORBA/UNKNOWN:1.0", 1},
++ {"IDL:CORBA/BAD_PARAM:1.0", 2},
++ {"IDL:CORBA/NO_MEMORY:1.0", 3},
++ {"IDL:CORBA/IMP_LIMIT:1.0", 4},
++ {"IDL:CORBA/COMM_FAILURE:1.0", 5},
++ {"IDL:CORBA/INV_OBJREF:1.0", 6},
++ {"IDL:CORBA/NO_PERMISSION:1.0", 7},
++ {"IDL:CORBA/INTERNAL:1.0", 8},
++ {"IDL:CORBA/MARSHAL:1.0", 9},
++ {"IDL:CORBA/INITIALIZE:1.0", 10},
++ {"IDL:CORBA/NO_IMPLEMENT:1.0", 11},
++ {"IDL:CORBA/BAD_TYPECODE:1.0", 12},
++ {"IDL:CORBA/BAD_OPERATION:1.0", 13},
++ {"IDL:CORBA/NO_RESOURCES:1.0", 14},
++ {"IDL:CORBA/NO_RESPONSE:1.0", 15},
++ {"IDL:CORBA/PERSIST_STORE:1.0", 16},
++ {"IDL:CORBA/BAD_INV_ORDER:1.0", 17},
++ {"IDL:CORBA/TRANSIENT:1.0", 18},
++ {"IDL:CORBA/FREE_MEM:1.0", 19},
++ {"IDL:CORBA/INV_IDENT:1.0", 20},
++ {"IDL:CORBA/INV_FLAG:1.0", 21},
++ {"IDL:CORBA/INTF_REPOS:1.0", 22},
++ {"IDL:CORBA/BAD_CONTEXT:1.0", 23},
++ {"IDL:CORBA/OBJ_ADAPTER:1.0", 24},
++ {"IDL:CORBA/DATA_CONVERSION:1.0", 25},
++ {"IDL:CORBA/OBJECT_NOT_EXIST:1.0", 26},
++ {"IDL:CORBA/TRANSACTION_REQUIRED:1.0", 27},
++ {"IDL:CORBA/TRANSACTION_ROLLEDBACK:1.0", 28},
++ {"IDL:CORBA/INVALID_TRANSACTION:1.0", 29},
++ {NULL,0}
++};
++
++void CORBA_exception_free(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ ev->_major=CORBA_NO_EXCEPTION;
++
++ if(ev->_repo_id) {
++ CORBA_free(ev->_repo_id);
++ ev->_repo_id=NULL;
++ }
++
++ if(ev->_params) {
++ CORBA_free(ev->_params);
++ ev->_params=NULL;
++ }
++
++ if(ev->_any) {
++ CORBA_free(ev->_any);
++ ev->_any=NULL;
++ }
++}
++
++void CORBA_exception_set(CORBA_Environment *ev, CORBA_exception_type major,
++ const CORBA_char *except_repos_id, void *param)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major != CORBA_NO_EXCEPTION)
++ CORBA_exception_free(ev);
++
++ ev->_major=major;
++
++ if(except_repos_id==NULL) {
++ ev->_repo_id=NULL;
++ } else {
++ ev->_repo_id=CORBA_string_dup(except_repos_id);
++ }
++
++ ev->_params=param;
++}
++
++void CORBA_exception_set_system(CORBA_Environment *ev, CORBA_unsigned_long ex_value,
++ CORBA_completion_status completed)
++{
++ CORBA_SystemException *new;
++
++ new=ORBit_alloc(sizeof(CORBA_SystemException), NULL, NULL);
++ if(new!=NULL) {
++ new->minor=0;
++ new->completed=completed;
++
++ /* XXX what should the repo ID be? */
++ CORBA_exception_set(ev, CORBA_SYSTEM_EXCEPTION,
++ exception_table[ex_value].repo_id,
++ new);
++ }
++}
++
++void CORBA_exception_init(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ ev->_major=CORBA_NO_EXCEPTION;
++ ev->_repo_id=NULL;
++ ev->_params=NULL;
++ ev->_any=NULL;
++}
++
++CORBA_char *CORBA_exception_id(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major==CORBA_NO_EXCEPTION) {
++ return(NULL);
++ } else {
++ return(ev->_repo_id);
++ }
++}
++
++void *CORBA_exception_value(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major==CORBA_NO_EXCEPTION) {
++ return(NULL);
++ } else {
++ return(ev->_params);
++ }
++}
++
++#ifndef __KORBIT__
++CORBA_any *CORBA_exception_as_any(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major==CORBA_NO_EXCEPTION) {
++ return(NULL);
++ }
++
++ if(ev->_any!=NULL) {
++ return(ev->_any);
++ }
++
++ ev->_any=g_new(CORBA_any, 1);
++ if(ev->_any!=NULL) {
++ /* XXX is this the correct type? */
++ ev->_any->_type = (CORBA_TypeCode)TC_CORBA_ExceptionDescription;
++ ev->_any->_value = ev->_params;
++ ev->_any->_release = 0;
++ }
++
++ return(ev->_any);
++}
++#endif /* !__KORBIT__ */
++
++/**** ORBit_handle_exception
++ Inputs: 'rb' - a receive buffer for which an exception condition has
++ been determined
++ 'ev' - memory in which to store the exception information
++
++ 'user_exceptions' - list of user exceptions raisable
++ for this particular operation.
++ Side-effects: reinitializes '*ev'
++
++ Description:
++ During demarshalling a reply, if reply_status != CORBA_NO_EXCEPTION,
++ we must find out what exception was raised and place that information
++ in '*ev'. */
++
++void ORBit_handle_exception(GIOPRecvBuffer *rb, CORBA_Environment *ev,
++ const ORBit_exception_demarshal_info *user_exceptions,
++ CORBA_ORB orb)
++{
++ CORBA_SystemException *new;
++ CORBA_unsigned_long len, completion_status;
++ CORBA_char *my_repoid;
++
++ g_return_if_fail(GIOP_MESSAGE_BUFFER(rb)->message_header.message_type == GIOP_REPLY);
++
++ CORBA_exception_free(ev);
++
++ rb->cur = ALIGN_ADDRESS(rb->cur, sizeof(len));
++ rb->decoder(&len, rb->cur, sizeof(len));
++ /* (guchar *)rb->cur += sizeof(len); */
++ rb->cur = ((guchar *)rb->cur) + sizeof(len);
++
++ if(len) {
++ my_repoid = rb->cur;
++ rb->cur = ((guchar *)rb->cur) + len;
++ } else
++ my_repoid = NULL;
++
++ if(rb->message.u.reply.reply_status == CORBA_SYSTEM_EXCEPTION) {
++ CORBA_unsigned_long minor;
++
++ ev->_major = CORBA_SYSTEM_EXCEPTION;
++
++ rb->cur = ALIGN_ADDRESS(rb->cur, sizeof(minor));
++ rb->decoder(&minor, rb->cur, sizeof(minor));
++ rb->cur = ((guchar *)rb->cur) + sizeof(minor);
++
++ rb->cur = ALIGN_ADDRESS(rb->cur, sizeof(completion_status));
++ rb->decoder(&completion_status, rb->cur, sizeof(completion_status));
++ rb->cur = ((guchar *)rb->cur) + sizeof(completion_status);
++
++ new=ORBit_alloc(sizeof(CORBA_SystemException), NULL, NULL);
++
++ if(new!=NULL) {
++ new->minor=minor;
++ new->completed=completion_status;
++
++ /* XXX what should the repo ID be? */
++ CORBA_exception_set(ev, CORBA_SYSTEM_EXCEPTION,
++ my_repoid,
++ new);
++ }
++ } else if(rb->message.u.reply.reply_status == CORBA_USER_EXCEPTION) {
++ int i;
++
++ if(!user_exceptions) {
++ /* weirdness; they raised an exception that we don't
++ know about */
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ } else {
++ for(i = 0; user_exceptions[i].tc != CORBA_OBJECT_NIL;
++ i++) {
++ if(!strcmp(user_exceptions[i].tc->repo_id,
++ my_repoid))
++ break;
++ }
++
++ if(user_exceptions[i].tc == CORBA_OBJECT_NIL) {
++ /* weirdness; they raised an exception
++ that we don't know about */
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ } else {
++ user_exceptions[i].demarshal(rb, ev);
++ }
++ }
++ };
++
++ /* ignore LOCATION_FORWARD here, that gets handled in the stub */
++}
++
++void
++ORBit_send_system_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev)
++{
++ CORBA_unsigned_long minor;
++ CORBA_unsigned_long completion_status;
++ CORBA_SystemException *se = ev->_params;
++
++ minor = se->minor;
++ completion_status = se->completed;
++
++ ENCODER_CALL(CORBA_char, ev->_repo_id);
++ giop_send_buffer_append_mem_indirect_a(send_buffer, &minor,
++ sizeof(minor));
++ giop_send_buffer_append_mem_indirect_a(send_buffer,
++ &completion_status,
++ sizeof(completion_status));
++}
++
++void
++ORBit_send_user_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev,
++ const ORBit_exception_marshal_info *user_exceptions)
++{
++ int i;
++
++ for(i = 0; user_exceptions[i].tc != CORBA_OBJECT_NIL; i++) {
++ if(!strcmp(user_exceptions[i].tc->repo_id, ev->_repo_id))
++ break;
++ }
++
++ if(user_exceptions[i].tc == CORBA_OBJECT_NIL) {
++ CORBA_Environment fakeev;
++ CORBA_exception_init(&fakeev);
++ CORBA_exception_set_system(&fakeev, ex_CORBA_UNKNOWN,
++ CORBA_COMPLETED_MAYBE);
++ ORBit_send_system_exception(send_buffer, &fakeev);
++ CORBA_exception_free(&fakeev);
++ } else {
++ ENCODER_CALL(CORBA_char, ev->_repo_id);
++
++ if(user_exceptions[i].marshal && ev->_params)
++ user_exceptions[i].marshal(send_buffer, ev);
++ }
++}
++
++void
++ORBit_handle_system_exception(CORBA_Environment *ev,
++ CORBA_unsigned_long system_exception_minor,
++ CORBA_unsigned_long completion_status,
++ GIOPRecvBuffer *recv_buffer,
++ GIOPSendBuffer *send_buffer)
++{
++ CORBA_exception_set_system(ev, system_exception_minor, completion_status);
++
++ if(send_buffer)
++ giop_send_buffer_unuse(send_buffer);
++
++ if(recv_buffer)
++ giop_recv_buffer_unuse(recv_buffer);
++}
+diff -urN linux-2.4.1/net/korbit/orb/env.h linux-2.4.1-korbit/net/korbit/orb/env.h
+--- linux-2.4.1/net/korbit/orb/env.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/env.h Thu Feb 1 16:21:56 2001
+@@ -0,0 +1,79 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998, 1999 Richard H. Porter, Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_ENV_H_
++#define _ORBIT_ENV_H_
++
++#include "orbit_types.h"
++
++extern void CORBA_exception_set(CORBA_Environment *ev,
++ CORBA_exception_type major,
++ const CORBA_char *except_repos_id,
++ void *param);
++
++extern void CORBA_exception_set_system(CORBA_Environment *ev,
++ CORBA_unsigned_long ex_value,
++ CORBA_completion_status completed);
++
++extern void CORBA_exception_init(CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_exception_id(CORBA_Environment *e);
++
++extern void *CORBA_exception_value(CORBA_Environment *ev);
++
++extern void CORBA_exception_free(CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_any *CORBA_exception_as_any(CORBA_Environment *ev);
++#endif /* !__KORBIT__ */
++
++typedef struct {
++ const CORBA_TypeCode tc;
++ void (*demarshal)(GIOPRecvBuffer *_ORBIT_recv_buffer, CORBA_Environment *ev);
++} ORBit_exception_demarshal_info;
++
++typedef struct {
++ const CORBA_TypeCode tc;
++ void (*marshal)(GIOPSendBuffer *_ORBIT_send_buffer, CORBA_Environment *ev);
++} ORBit_exception_marshal_info;
++
++/* ORBit-specific */
++void ORBit_handle_exception(GIOPRecvBuffer *rb, CORBA_Environment *ev,
++ const ORBit_exception_demarshal_info *user_exceptions,
++ CORBA_ORB orb);
++void ORBit_send_system_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev);
++void ORBit_send_user_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev,
++ const ORBit_exception_marshal_info *user_exceptions);
++
++/* Used by stubs */
++void ORBit_handle_system_exception(CORBA_Environment *ev,
++ CORBA_unsigned_long system_exception_minor,
++ CORBA_unsigned_long completion_status,
++ GIOPRecvBuffer *recv_buffer,
++ GIOPSendBuffer *send_buffer);
++
++#endif /* !_ORBIT_ENV_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/genrand.c linux-2.4.1-korbit/net/korbit/orb/genrand.c
+--- linux-2.4.1/net/korbit/orb/genrand.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/genrand.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,131 @@
++#include "genrand.h"
++#include "ORBitutil/util.h"
++#include <unistd.h>
++#include <sys/types.h>
++#include <fcntl.h>
++#include <glib.h>
++#include <signal.h>
++#include <sys/time.h>
++#include <limits.h>
++#include <stdio.h>
++#ifdef __KERNEL__
++#include <linux/random.h>
++#endif
++
++static gboolean
++genrand_dev(guchar *buffer, int buf_len)
++{
++#ifdef __KERNEL__
++ get_random_bytes(buffer, buf_len);
++#else /*! __KERNEL__*/
++ int fd;
++
++ fd = open("/dev/urandom", O_RDONLY);
++ if(fd < 0)
++ return FALSE;
++
++ if(read(fd, buffer, buf_len) < buf_len)
++ {
++ close(fd);
++ return FALSE;
++ }
++
++ close(fd);
++#endif /*! __KERNEL__*/
++
++ return TRUE;
++}
++
++#ifndef __KORBIT__
++static volatile int received_alarm = 0;
++
++static void
++handle_alarm(int signum)
++{
++ received_alarm = 1;
++}
++
++static inline guchar
++hashlong(long val)
++{
++ guchar retval, *ptr;
++ int i;
++
++ for(ptr = (guchar *)&val, i = 0; i < sizeof(val); i++)
++ retval ^= ptr[i];
++
++ return retval;
++}
++
++static gboolean
++genrand_unix(guchar *buffer, int buf_len)
++{
++ struct sigaction sa, oldsa;
++ struct itimerval it, oldit;
++ int i;
++ long min, max;
++ long *counts;
++ double diff;
++ long *uninit;
++
++ counts = alloca(buf_len * sizeof(long));
++
++ memset(&sa, 0, sizeof(sa));
++ sa.sa_handler = handle_alarm;
++ sigaction(SIGALRM, &sa, &oldsa);
++ memset(&it, 0, sizeof(it));
++ it.it_value.tv_usec = 1;
++ getitimer(ITIMER_REAL, &oldit);
++
++ for(i = 0, min = LONG_MAX, max = 0; i < buf_len; i++)
++ {
++ received_alarm = 0;
++ setitimer(ITIMER_REAL, &it, NULL);
++ for(counts[i] = 0; !received_alarm; counts[i]++);
++
++ max = MAX(counts[i], max);
++ min = MIN(counts[i], min);
++ }
++
++ if(!(max - min))
++ {
++ freeca(counts);
++ return FALSE;
++ }
++
++ diff = max - min;
++
++ uninit = alloca(buf_len * sizeof(long)); /* Purposely not initialized */
++ for(i = 0; i < buf_len; i++)
++ {
++ long diffval;
++ diffval = counts[i] - min;
++
++ buffer[i] ^= (guchar)( ((double) (diffval*256) / diff )) ^ hashlong(uninit[i]);
++ }
++
++ setitimer(ITIMER_REAL, &oldit, NULL);
++ sigaction(SIGALRM, &oldsa, NULL);
++
++ freeca(counts);
++ freeca(uninit);
++
++ return TRUE;
++}
++#endif /* !__KORBIT__ */
++
++void
++orbit_genrand(guchar *buffer, int buf_len)
++{
++ g_return_if_fail(buf_len);
++
++ if(genrand_dev(buffer, buf_len))
++ return;
++#ifndef __KORBIT__
++ else if(genrand_unix(buffer, buf_len))
++ return;
++#endif
++ else
++ g_error("Couldn't generate random data!");
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/genrand.h linux-2.4.1-korbit/net/korbit/orb/genrand.h
+--- linux-2.4.1/net/korbit/orb/genrand.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/genrand.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,8 @@
++#ifndef ORBIT_GENRAND_H
++#define ORBIT_GENRAND_H 1
++
++#include <glib.h>
++
++void orbit_genrand(guchar *buffer, int buf_len);
++
++#endif /* ORBIT_GENRAND_H */
+diff -urN linux-2.4.1/net/korbit/orb/iop.h linux-2.4.1-korbit/net/korbit/orb/iop.h
+--- linux-2.4.1/net/korbit/orb/iop.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/iop.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,207 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_IOP_H_
++#define _ORBIT_IOP_H_
++
++#include <ORBitutil/basic_types.h>
++
++#include <orb/corba_basic_sequences_type.h>
++
++#ifndef HAVE_CORBA_PRINCIPAL
++#define HAVE_CORBA_PRINCIPAL 1
++typedef CORBA_sequence_octet CORBA_Principal;
++#endif
++
++typedef CORBA_unsigned_long IOP_ProfileId;
++
++#define IOP_TAG_INTERNET_IOP 0
++#define IOP_TAG_MULTIPLE_COMPONENTS 1
++#define IOP_TAG_ORBIT_SPECIFIC 0xbadfaecal
++
++typedef struct IOP_TaggedProfile {
++ IOP_ProfileId tag;
++ CORBA_sequence_octet profile_data;
++} IOP_TaggedProfile;
++
++typedef struct CORBA_sequence_TaggedProfile {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ IOP_TaggedProfile *_buffer;
++} CORBA_sequence_TaggedProfile;
++
++typedef struct IOP_IOR {
++ CORBA_char *type_id;
++ CORBA_sequence_TaggedProfile profiles;
++} IOP_IOR;
++
++typedef CORBA_unsigned_long IOP_ComponentId;
++
++typedef struct IOP_TaggedComponent {
++ IOP_ComponentId tag;
++ CORBA_sequence_octet component_data;
++} IOP_TaggedComponent;
++
++typedef struct CORBA_sequence_TaggedComponent {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ IOP_TaggedComponent *_buffer;
++} CORBA_sequence_TaggedComponent;
++
++typedef struct CORBA_sequence_TaggedComponent IOP_MultipleComponentProfile;
++
++#define IOP_TAG_ORB_TYPE 0
++#define IOP_TAG_CODE_SETS 1
++#define IOP_TAG_SEC_NAME 14
++#define IOP_TAG_ASSOCIATION_OPTIONS 13
++#define IOP_TAG_GENERIC_SEC_MECH 12
++
++typedef CORBA_unsigned_long IOP_ServiceId;
++
++typedef struct IOP_ServiceContext {
++ IOP_ServiceId context_id;
++ CORBA_sequence_octet context_data;
++} IOP_ServiceContext;
++
++typedef struct CORBA_sequence_ServiceContext {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ IOP_ServiceContext *_buffer;
++} CORBA_sequence_ServiceContext;
++
++typedef struct CORBA_sequence_ServiceContext IOP_ServiceContextList;
++
++#define IOP_TransactionService 0
++#define IOP_CodeSets 1
++
++typedef CORBA_unsigned_long CONV_FRAME_CodeSetId;
++
++typedef struct CORBA_sequence_CodeSetId {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CONV_FRAME_CodeSetId *_buffer;
++} CORBA_sequence_CodeSetId;
++
++typedef struct CONV_FRAME_CodeSetComponent {
++ CONV_FRAME_CodeSetId native_code_set;
++ CORBA_sequence_CodeSetId conversion_code_sets;
++} CONV_FRAME_CodeSetComponent;
++
++typedef struct CONV_FRAME_CodeSetComponentInfo {
++ CONV_FRAME_CodeSetComponent ForCharData;
++ CONV_FRAME_CodeSetComponent ForWcharData;
++} CONV_FRAME_CodeSetComponentInfo;
++
++typedef struct CONV_FRAME_CodeSetContext {
++ CONV_FRAME_CodeSetId char_data;
++ CONV_FRAME_CodeSetId wchar_data;
++} CONV_FRAME_CodeSetContext;
++
++typedef struct GIOP_Version {
++ CORBA_octet major;
++ CORBA_octet minor;
++} GIOP_Version;
++
++typedef enum {
++ GIOP_Request=0,
++ GIOP_Reply,
++ GIOP_CancelRequest,
++ GIOP_LocateRequest,
++ GIOP_LocateReply,
++ GIOP_CloseConnection,
++ GIOP_MessageError
++} GIOP_MsgType_1_0;
++
++typedef struct GIOP_MessageHeader_1_0 {
++ CORBA_char magic[4];
++ GIOP_Version GIOP_version;
++ CORBA_boolean byte_order;
++ CORBA_octet message_type;
++ CORBA_unsigned_long message_size;
++} GIOP_MessageHeader_1_0;
++
++typedef struct GIOP_MessageHeader_1_1 {
++ CORBA_char magic[4];
++ GIOP_Version GIOP_version;
++ CORBA_octet flags;
++ CORBA_octet message_type;
++ CORBA_unsigned_long message_size;
++} GIOP_MessageHeader_1_1;
++
++typedef struct GIOP_RequestHeader_1_0 {
++ IOP_ServiceContextList service_context;
++ CORBA_unsigned_long request_id;
++ CORBA_boolean response_expected;
++ CORBA_sequence_octet object_key;
++ CORBA_char *operation;
++ CORBA_Principal requesting_principal;
++} GIOP_RequestHeader_1_0;
++
++typedef struct GIOP_RequestHeader_1_1 {
++ IOP_ServiceContextList service_context;
++ CORBA_unsigned_long request_id;
++ CORBA_boolean response_expected;
++ CORBA_octet reserved[3];
++ CORBA_sequence_octet object_key;
++ CORBA_char *operation;
++ CORBA_Principal requesting_principal;
++} GIOP_RequestHeader_1_1;
++
++typedef struct GIOP_SystemExceptionReplyBody {
++ CORBA_char *exception_id;
++ CORBA_unsigned_long minor_code_value;
++ CORBA_unsigned_long completion_status;
++} GIOP_SystemExceptionReplyBody;
++
++typedef struct GIOP_CancelRequestHeader {
++ CORBA_unsigned_long request_id;
++} GIOP_CancelRequestHeader;
++
++typedef struct GIOP_LocateRequestHeader {
++ CORBA_unsigned_long request_id;
++ CORBA_sequence_octet object_key;
++} GIOP_LocateRequestHeader;
++
++typedef struct IIOP_Version {
++ CORBA_octet major;
++ CORBA_octet minor;
++} IIOP_Version;
++
++typedef struct IIOP_ProfileBody_1_0 {
++ IIOP_Version iiop_version;
++ CORBA_char *host;
++ CORBA_unsigned_short port;
++ CORBA_sequence_octet object_key;
++} IIOP_ProfileBody_1_0;
++
++typedef struct IIOP_ProfileBody_1_1 {
++ IIOP_Version iiop_version;
++ CORBA_char *host;
++ CORBA_unsigned_short port;
++ CORBA_sequence_octet object_key;
++ CORBA_sequence_TaggedComponent components;
++} IIOP_ProfileBody_1_1;
++
++#endif /* !_ORBIT_IOP_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/ir.c linux-2.4.1-korbit/net/korbit/orb/ir.c
+--- linux-2.4.1/net/korbit/orb/ir.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/ir.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,293 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#include <stdlib.h>
++#include <assert.h>
++
++#include "orbit.h"
++
++/* FIXME: Right now this function doesn't record whether or not it has
++ already visited a given TypeCode. I'm not sure if every recursive
++ type will have a tk_recursive node in it; if not, then this will
++ need to be reworked a bit. */
++CORBA_boolean CORBA_TypeCode_equal(CORBA_TypeCode obj, CORBA_TypeCode tc, CORBA_Environment *ev)
++{
++ int i;
++
++ g_return_val_if_fail(obj!=NULL, CORBA_FALSE);
++ g_return_val_if_fail(tc!=NULL, CORBA_FALSE);
++
++ if (obj->kind != tc->kind) {
++ return CORBA_FALSE;
++ }
++
++ switch (obj->kind) {
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ return obj->length == tc->length;
++ case CORBA_tk_objref:
++ return ! strcmp (obj->repo_id, tc->repo_id);
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ if (strcmp (obj->repo_id, tc->repo_id)
++ || obj->sub_parts != tc->sub_parts)
++ return CORBA_FALSE;
++ for (i = 0; i < obj->sub_parts; ++i)
++ if (! CORBA_TypeCode_equal (obj->subtypes[i],
++ tc->subtypes[i], ev))
++ return CORBA_FALSE;
++ break;
++ case CORBA_tk_union:
++ if (strcmp (obj->repo_id, tc->repo_id)
++ || obj->sub_parts != tc->sub_parts
++ || ! CORBA_TypeCode_equal (obj->discriminator,
++ tc->discriminator, ev)
++ || obj->default_index != tc->default_index)
++ return CORBA_FALSE;
++ for (i = 0; i < obj->sub_parts; ++i)
++
++ if (! CORBA_TypeCode_equal (obj->subtypes[i],
++ tc->subtypes[i], ev)
++ || ! ORBit_any_equivalent (obj->sublabels[i],
++ tc->sublabels[i], ev))
++ return CORBA_FALSE;
++
++ break;
++ case CORBA_tk_enum:
++ if (obj->sub_parts != tc->sub_parts
++ || strcmp (obj->repo_id, tc->repo_id))
++ return CORBA_FALSE;
++ for (i = 0; i < obj->sub_parts; ++i)
++ if (strcmp (obj->subnames[i], tc->subnames[i]))
++ return CORBA_FALSE;
++ break;
++ case CORBA_tk_sequence:
++ case CORBA_tk_array:
++ if (obj->length != tc->length)
++ return CORBA_FALSE;
++ g_assert (obj->sub_parts == 1);
++ g_assert (tc->sub_parts == 1);
++ return CORBA_TypeCode_equal (obj->subtypes[0], tc->subtypes[0],
++ ev);
++ case CORBA_tk_alias:
++ if (strcmp (obj->repo_id, tc->repo_id))
++ return CORBA_FALSE;
++
++ g_assert (obj->sub_parts == 1);
++ g_assert (tc->sub_parts == 1);
++
++ return CORBA_TypeCode_equal (obj->subtypes[0], tc->subtypes[0],
++ ev);
++ break;
++ case CORBA_tk_recursive:
++ return obj->recurse_depth == tc->recurse_depth;
++ case CORBA_tk_fixed:
++ return obj->digits == tc->digits && obj->scale == tc->scale;
++
++ default:
++ /* Everything else is primitive. */
++ break;
++ }
++
++ return CORBA_TRUE;
++}
++
++CORBA_TCKind CORBA_TypeCode_kind(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ return obj->kind;
++}
++
++static void bad_kind (CORBA_Environment *ev)
++{
++ CORBA_TypeCode_BadKind *err;
++ err = g_new (CORBA_TypeCode_BadKind, 1);
++ if (err == NULL) {
++ CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ } else {
++ err->dummy = 23;
++ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
++ "IDL:omg.org/CORBA/TypeCode/BadKind/1.0",
++ err);
++ }
++}
++
++CORBA_RepositoryId CORBA_TypeCode_id(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_objref || obj->kind == CORBA_tk_struct
++ || obj->kind == CORBA_tk_enum || obj->kind == CORBA_tk_alias
++ || obj->kind == CORBA_tk_except)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ return obj->repo_id;
++}
++
++CORBA_Identifier CORBA_TypeCode_name(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_objref || obj->kind == CORBA_tk_struct
++ || obj->kind == CORBA_tk_enum || obj->kind == CORBA_tk_alias
++ || obj->kind == CORBA_tk_except)) {
++ bad_kind (ev);
++ return NULL;
++ }
++
++ return obj->name;
++}
++
++CORBA_unsigned_long CORBA_TypeCode_member_count(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union
++ || obj->kind == CORBA_tk_enum)) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->sub_parts;
++}
++
++static void bounds_error (CORBA_Environment *ev)
++{
++ CORBA_TypeCode_Bounds *err;
++ err = g_new (CORBA_TypeCode_Bounds, 1);
++ if (err == NULL) {
++ CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ } else {
++ err->dummy = 23;
++ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
++ "IDL:omg.org/CORBA/TypeCode/Bounds/1.0",
++ err);
++ }
++}
++
++CORBA_Identifier CORBA_TypeCode_member_name(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union
++ || obj->kind == CORBA_tk_enum)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ if (index > obj->sub_parts) {
++ bounds_error (ev);
++ return NULL;
++ }
++ return obj->subnames[index];
++}
++
++CORBA_TypeCode CORBA_TypeCode_member_type(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union
++ || obj->kind == CORBA_tk_enum)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ if (index > obj->sub_parts) {
++ bounds_error (ev);
++ return NULL;
++ }
++ return obj->subtypes[index];
++}
++
++CORBA_any *CORBA_TypeCode_member_label(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_union) {
++ bad_kind (ev);
++ return NULL;
++ }
++ if (index > obj->sub_parts) {
++ bounds_error (ev);
++ return NULL;
++ }
++ return &obj->sublabels[index];
++}
++
++CORBA_TypeCode CORBA_TypeCode_discriminator_type(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_union) {
++ bad_kind (ev);
++ return NULL;
++ }
++ return obj->discriminator;
++}
++
++CORBA_long CORBA_TypeCode_default_index(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_union) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->default_index;
++}
++
++CORBA_unsigned_long CORBA_TypeCode_length(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_string || obj->kind == CORBA_tk_wstring
++ || obj->kind == CORBA_tk_array)) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->length;
++}
++
++CORBA_TypeCode CORBA_TypeCode_content_type(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_sequence || obj->kind == CORBA_tk_array
++ || obj->kind == CORBA_tk_alias)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ g_assert (obj->sub_parts == 1);
++ return obj->subtypes[0];
++}
++
++CORBA_unsigned_short CORBA_TypeCode_fixed_digits(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_fixed) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->digits;
++}
++
++CORBA_short CORBA_TypeCode_fixed_scale(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_fixed) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->scale;
++}
++
++CORBA_long CORBA_TypeCode_param_count(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ g_assert(!"Deprecated");
++ return(0);
++}
++
++CORBA_any *CORBA_TypeCode_parameter(CORBA_TypeCode obj, CORBA_long index, CORBA_Environment *ev)
++{
++ g_assert(!"Deprecated");
++ return(NULL);
++}
+diff -urN linux-2.4.1/net/korbit/orb/ir.h linux-2.4.1-korbit/net/korbit/orb/ir.h
+--- linux-2.4.1/net/korbit/orb/ir.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/ir.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,100 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_IR_H_
++#define _ORBIT_IR_H_
++
++#include "orbit_types.h"
++
++extern CORBA_boolean CORBA_TypeCode_equal(
++ CORBA_TypeCode obj,
++ CORBA_TypeCode tc,
++ CORBA_Environment *ev);
++
++extern CORBA_TCKind CORBA_TypeCode_kind(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_RepositoryId CORBA_TypeCode_id(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Identifier CORBA_TypeCode_name(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_long CORBA_TypeCode_member_count(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Identifier CORBA_TypeCode_member_name(
++ CORBA_TypeCode obj,
++ CORBA_unsigned_long index,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_TypeCode_member_type(
++ CORBA_TypeCode obj,
++ CORBA_unsigned_long index,
++ CORBA_Environment *ev);
++
++extern CORBA_any *CORBA_TypeCode_member_label(
++ CORBA_TypeCode obj,
++ CORBA_unsigned_long index,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_TypeCode_discriminator_type(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_long CORBA_TypeCode_default_index(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_long CORBA_TypeCode_length(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_TypeCode_content_type(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_short CORBA_TypeCode_fixed_digits(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_short CORBA_TypeCode_fixed_scale(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_long CORBA_TypeCode_param_count(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_any *CORBA_TypeCode_parameter(
++ CORBA_TypeCode obj,
++ CORBA_long index,
++ CORBA_Environment *ev);
++
++#endif /* !_ORBIT_IR_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/options.c linux-2.4.1-korbit/net/korbit/orb/options.c
+--- linux-2.4.1/net/korbit/orb/options.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/options.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,160 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++/*
++ * Option parsing
++ *
++ * All ORB options are stripped from the application's argv, and argc is
++ * adjusted accordingly
++ */
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <glib.h>
++
++#include "options.h"
++
++#ifndef __KORBIT__
++void ORBit_option_set(ORBit_orb_options *option, const char *val)
++{
++ g_assert(option!=NULL);
++
++ if(option->type==no_arg && option->arg!=NULL) {
++ /* Treat as an int arg with val=1
++ */
++ int *int_arg=(int *)option->arg;
++
++ *int_arg=1;
++ } else {
++ if(option->type==string_arg && option->arg!=NULL) {
++ char **str_arg=(char **)option->arg;
++
++ /* free any existing value */
++ if(*str_arg!=NULL) {
++ g_free(*str_arg);
++ }
++ *str_arg=g_strdup(val);
++ } else if(option->type==int_arg && option->arg!=NULL) {
++ int *int_arg=(int *)option->arg;
++
++ *int_arg=atoi(val);
++ }
++
++ }
++}
++
++void ORBit_option_parse(int *argc, char **argv, ORBit_orb_options *options)
++{
++ int i,j,numargs;
++ char name[1024], *val;
++ ORBit_orb_options *search=NULL;
++ int *erase;
++
++ numargs=*argc;
++
++ erase=g_new0(int, *argc);
++
++ for(i=1; i< *argc; i++) {
++ if(argv[i][0]!='-') {
++ if(search==NULL) {
++ /* Skip non-option */
++ continue;
++ } else {
++ /* an required option value has been found */
++ erase[i]=1;
++ numargs-=1;
++
++ if(search->arg==NULL) {
++ /* dont store any values, just strip
++ * the argv
++ */
++ search=NULL;
++ continue;
++ }
++
++ ORBit_option_set(search, argv[i]);
++
++ search=NULL;
++ continue;
++ }
++ } else {
++ if(search!=NULL &&
++ (search->type==string_arg || search->type==int_arg)) {
++ fprintf(stderr, "Option %s requires an argument\n", search->name);
++ }
++ }
++
++ val=argv[i];
++ while(*val && *val=='-')
++ val++;
++
++ strncpy(name,val,1023);
++ name[1023]='\0';
++
++ val=strchr(name, '=');
++ if(val!=NULL) {
++ *val++='\0';
++ }
++
++ for(search=options;search->name!=NULL;search++) {
++ if(!strcmp(name, search->name)) {
++ break;
++ }
++ }
++
++ if(search->name==NULL) {
++ /* Didn't find it in our list of interesting options */
++ search=NULL;
++ } else {
++ /* Found it */
++ erase[i]=1;
++ numargs-=1;
++
++ if(search->type==no_arg || val!=NULL) {
++ ORBit_option_set(search, val);
++ search=NULL;
++ }
++ }
++ }
++
++ j=1;
++ for(i=1; i< *argc; i++) {
++ if(erase[i]==1) {
++ continue;
++ } else {
++ if(j<numargs) {
++ argv[j++]=argv[i];
++ } else {
++ argv[j++]='\0';
++ }
++ }
++ }
++
++ *argc=numargs;
++
++ g_free(erase);
++}
++#endif /* !__KORBIT__ */
+diff -urN linux-2.4.1/net/korbit/orb/options.h linux-2.4.1-korbit/net/korbit/orb/options.h
+--- linux-2.4.1/net/korbit/orb/options.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/options.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,46 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_OPTIONS_H_
++#define _ORBIT_OPTIONS_H_
++
++typedef enum {
++ no_arg=0,
++ string_arg,
++ int_arg
++} ORBit_opt_type;
++
++typedef struct {
++ char *name;
++ ORBit_opt_type type;
++ void *arg;
++} ORBit_orb_options;
++
++#ifndef __KORBIT__
++extern void ORBit_option_set(ORBit_orb_options *found, const char *val);
++extern void ORBit_option_parse(int *argc, char **argv, ORBit_orb_options *options);
++#endif
++
++#endif /* !_ORBIT_OPTIONS_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orb.c linux-2.4.1-korbit/net/korbit/orb/orb.c
+--- linux-2.4.1/net/korbit/orb/orb.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orb.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,1700 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#define o_return_val_if_fail(expr, val) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return (val); }
++#define o_return_if_fail(expr) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return; }
++
++#include "config.h"
++
++#include <unistd.h>
++#include <errno.h>
++#include <sys/stat.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <ctype.h>
++#include <assert.h>
++#include <pwd.h>
++#include <time.h>
++#include <sys/types.h>
++#include <dirent.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <utime.h>
++
++#include "../IIOP/iiop-endianP.h"
++#include "orbit.h"
++
++#include "orbit_poa.h"
++#include "orbit_object.h"
++#include "orbit_object_type.h"
++
++#ifndef __KERNEL__
++#define freeca(ptr)
++#endif
++
++#ifndef SUN_LEN
++/* This system is not POSIX.1g. */
++#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
++ + strlen ((ptr)->sun_path))
++#endif
++
++static void ORBit_ORB_release(CORBA_ORB orb, CORBA_Environment *ev);
++
++static const ORBit_RootObject_Interface CORBA_ORB_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_ORB_release
++};
++
++
++static int ORBit_ORBid_setup(CORBA_ORB orb, CORBA_ORBid id)
++{
++ g_assert(orb!=NULL);
++ g_assert(id!=NULL);
++
++ if(strcmp(id, "orbit-local-orb")) {
++#ifdef __KORBIT__
++ printf("ORBit_ORBid_setup: Unknown ORB id: %s\n", id);
++#else
++ fprintf(stderr, "ORBit_ORBid_setup: Unknown ORB id: %s\n", id);
++#endif
++ return(0);
++ }
++
++ orb->orb_identifier=g_strdup(id);
++
++ return(1);
++}
++
++#ifndef __KORBIT__
++static gboolean
++free_key_and_data(gpointer key, gpointer data, gpointer user_data)
++{
++ g_free(key); g_free(data);
++
++ return TRUE;
++}
++
++static void ORBit_rc_load(const char *rcfile, ORBit_orb_options *options)
++{
++ FILE *fp;
++ GHashTable *read_options;
++ ORBit_orb_options *search;
++
++ fp=fopen(rcfile, "r");
++
++ if(fp==NULL)
++ return;
++
++ read_options=g_hash_table_new(g_str_hash, g_str_equal);
++
++ while(!feof(fp)) {
++ char buf[1024];
++
++ if(fgets(buf, 1024, fp)!=NULL) {
++ guchar *bptr, *tmp, *key, *data;
++ size_t start, len;
++
++ if(buf[0]=='#')
++ continue;
++
++ bptr=buf;
++ tmp=strpbrk(bptr, " \t\n=");
++ if(tmp==NULL) continue;
++ *tmp++='\0';
++ key=g_strdup(bptr);
++ bptr=tmp;
++
++ start=0;
++ while(bptr+start != '\0' &&
++ (isspace(bptr[start]) || bptr[start]=='='))
++ start++;
++ len=strcspn(bptr+start, " \t\n");
++ bptr[start+len]='\0';
++ if(len>0) {
++ data=g_strdup(bptr+start);
++ } else {
++ data=g_strdup("TRUE");
++ }
++
++ g_hash_table_insert(read_options, key, data);
++ }
++ }
++ fclose(fp);
++
++ for(search=options;search->name!=NULL;search++) {
++ char *read_val;
++
++ read_val=g_hash_table_lookup(read_options, search->name);
++ if(read_val!=NULL) {
++ ORBit_option_set(search, read_val);
++ }
++ }
++
++ g_hash_table_foreach_remove(read_options, free_key_and_data, NULL);
++ g_hash_table_destroy(read_options);
++}
++#endif /* !__KORBIT__ */
++
++static void ORBit_ORB_release(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_assert(orb!=NULL);
++
++ if(--(ORBIT_ROOT_OBJECT(orb)->refs))
++ return;
++
++ if(orb->orb_identifier!=NULL) {
++ g_free(orb->orb_identifier);
++ }
++ if(!CORBA_Object_is_nil(orb->imr, ev)) {
++ CORBA_Object_release(orb->imr, ev);
++ }
++ if(!CORBA_Object_is_nil(orb->ir, ev)) {
++ CORBA_Object_release(orb->ir, ev);
++ }
++ if(!CORBA_Object_is_nil(orb->naming, ev)) {
++ CORBA_Object_release(orb->naming, ev);
++ }
++ if(!CORBA_Object_is_nil(orb->root_poa, ev)) {
++ CORBA_Object_release(orb->root_poa, ev);
++ }
++ if(orb->cnx.ipv4)
++ giop_connection_unref(orb->cnx.ipv4);
++ if(orb->cnx.ipv6)
++ giop_connection_unref(orb->cnx.ipv6);
++#ifndef __KORBIT__
++ if(orb->cnx.usock)
++ giop_connection_unref(orb->cnx.usock);
++#endif
++
++ g_free(orb);
++}
++
++#ifndef __KORBIT__
++static GIOPConnection*
++ORBit_ORB_make_usock_connection(void)
++{
++ GIOPConnection *retval = NULL;
++ GString *tmpstr;
++ struct stat statbuf;
++
++ tmpstr = g_string_new(NULL);
++
++ g_string_sprintf(tmpstr, "/tmp/orbit-%s", g_get_user_name());
++
++ if(mkdir(tmpstr->str, 0700) != 0) {
++ int e = errno;
++
++ switch (e) {
++ case 0:
++ case EEXIST:
++ if (stat(tmpstr->str, &statbuf) != 0)
++ g_error ("Can not stat %s\n", tmpstr->str);
++
++ if (statbuf.st_uid != getuid ())
++ g_error ("Owner of %s is not the current user\n",
++ tmpstr->str);
++
++ if((statbuf.st_mode & (S_IRWXG|S_IRWXO))
++ || !S_ISDIR(statbuf.st_mode))
++ g_error ("Wrong permissions for %s\n",
++ tmpstr->str);
++ break;
++
++ default:
++ g_error("Unknown error on directory creation of %s (%s)\n",
++ tmpstr->str, g_strerror (e));
++ }
++ }
++
++ {
++ struct utimbuf utb;
++ memset(&utb, 0, sizeof(utb));
++ utime(tmpstr->str, &utb);
++ }
++
++
++#ifdef WE_DONT_CARE_ABOUT_STUPID_2DOT0DOTX_KERNELS
++ g_string_sprintf(tmpstr, "/tmp/orbit-%s",
++ g_get_user_name());
++ dirh = opendir(tmpstr->str);
++ while(!retval && (dent = readdir(dirh))) {
++ int usfd, ret;
++ struct sockaddr_un saddr;
++
++ saddr.sun_family = AF_UNIX;
++
++ if(strncmp(dent->d_name, "orb-", 4))
++ continue;
++
++ g_snprintf(saddr.sun_path, sizeof(saddr.sun_path),
++ "/tmp/orbit-%s/%s",
++ g_get_user_name(), dent->d_name);
++
++ usfd = socket(AF_UNIX, SOCK_STREAM, 0);
++ g_assert(usfd >= 0);
++
++ ret = connect(usfd, &saddr, SUN_LEN(&saddr));
++ close(usfd);
++
++ if(ret >= 0)
++ continue;
++
++ unlink(saddr.sun_path);
++ }
++ closedir(dirh);
++#endif /* WE_DONT_CARE_ABOUT_STUPID_2DOT0DOTX_KERNELS */
++
++ srand(time(NULL));
++ while(!retval) {
++ g_string_sprintf(tmpstr, "/tmp/orbit-%s/orb-%d%d",
++ g_get_user_name(), rand(), rand());
++ retval =
++ GIOP_CONNECTION(iiop_connection_server_unix(tmpstr->str));
++ }
++
++ g_string_free(tmpstr, TRUE);
++
++ return retval;
++}
++#endif /* !__KORBIT__ */
++
++
++// Synchronize between the user process starting up the orb and the ORB thread
++// this mutex gets released when the orb is all fired up and ready to go.
++static DECLARE_MUTEX(StartupSem);
++static CORBA_ORB TheOneTrueOrb = 0;
++
++struct CORBA_ORB_init_args { // A pointer to this struct is passed to
++ int *argc; // __CORBA_ORB_init
++ char **argv;
++ CORBA_ORBid orb_identifier;
++ CORBA_Environment *ev;
++};
++
++
++CORBA_ORB __CORBA_ORB_init(struct CORBA_ORB_init_args *Args) {
++ int *argc = Args->argc;
++ char **argv = Args->argv;
++ CORBA_ORBid orb_identifier = Args->orb_identifier;
++ CORBA_Environment *ev = Args->ev;
++
++ int no_iiop_server=0;
++ int no_iiop_proxy=0;
++#ifdef __KORBIT__
++ int use_ipv4=1;
++#else
++ int use_ipv4=0;
++#endif
++ int use_ipv6=0;
++ int use_usock=1;
++ int debug_level=0;
++ int debug_modules=0;
++ int nosysrc=0;
++ int nouserrc=0;
++ char *imr_ior=NULL, *imr_addr=NULL;
++ char *ir_ior=NULL, *ir_addr=NULL;
++ char *naming_ior=NULL, *naming_addr=NULL;
++ char *root_poa_ior=NULL, *root_poa_addr=NULL;
++ char *orb_id_opt=NULL;
++#ifndef __KORBIT__
++ char *ctmp;
++#endif
++ CORBA_ORB orb = 0;
++
++ /* The variable addresses in these structs need to be assigned at
++ * run-time if you want to compile with -pedantic
++ *
++ * (You will also get scads of warnings about "long long" too)
++ */
++
++ ORBit_orb_options pre_rc_options[]={
++ {"ORBNoSystemRC", no_arg, NULL},
++ {"ORBNoUserRC", no_arg, NULL},
++ {NULL, 0, NULL},
++ };
++
++ /* These options are compatible with MICO */
++ ORBit_orb_options options[]={
++ {"ORBNoIIOPServer", no_arg, NULL},
++ {"ORBNoIIOPProxy", no_arg, NULL},
++ {"ORBid", string_arg, NULL},
++ {"ORBImplRepoIOR", string_arg, NULL},
++ {"ORBImplRepoAddr", string_arg, NULL},
++ {"ORBIfaceRepoIOR", string_arg, NULL},
++ {"ORBIfaceRepoAddr", string_arg, NULL},
++ {"ORBNamingIOR", string_arg, NULL},
++ {"ORBNamingAddr", string_arg, NULL},
++ {"ORBDebugLevel", int_arg, NULL},
++ {"ORBBindAddr", string_arg, NULL}, /* XXX need to make
++ libIIOP support this */
++ {"ORBIIOPAddr", string_arg, NULL},
++
++ /* These options aren't */
++ {"ORBDebugModules", int_arg, NULL},
++ {"ORBRootPOAIOR", string_arg, NULL},
++ {"ORBRootPOAAddr", string_arg, NULL},
++ {"ORBIIOPUSock", int_arg, NULL},
++ {"ORBIIOPIPv4", int_arg, NULL},
++ {"ORBIIOPIPv6", int_arg, NULL},
++ {NULL,0,NULL},
++ };
++
++ if (ev == NULL || !argc || !argv || !orb_identifier) {
++ if (ev) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ }
++ up(&StartupSem); // Okay, let the insmod thread continue...
++ return 0;
++ }
++
++ pre_rc_options[0].arg = (void *) &nosysrc;
++ pre_rc_options[1].arg = (void *) &nouserrc;
++ options[0].arg = (void *) &no_iiop_server;
++ options[1].arg = (void *) &no_iiop_proxy;
++ options[2].arg = (void *) &orb_id_opt;
++ options[3].arg = (void *) &imr_ior;
++ options[4].arg = (void *) &imr_addr;
++ options[5].arg = (void *) &ir_ior;
++ options[6].arg = (void *) &ir_addr;
++ options[7].arg = (void *) &naming_ior;
++ options[8].arg = (void *) &naming_addr;
++ options[9].arg = (void *) &debug_level;
++ options[12].arg = (void *) &debug_modules;
++ options[13].arg = (void *) &root_poa_ior;
++ options[14].arg = (void *) &root_poa_addr;
++ options[15].arg = (void *) &use_usock;
++ options[16].arg = (void *) &use_ipv4;
++ options[17].arg = (void *) &use_ipv6;
++
++#ifndef __KORBIT__
++ ORBit_option_parse(argc, argv, pre_rc_options);
++
++ if(!nosysrc) {
++ ORBit_rc_load(ORBit_SYSRC, options);
++ }
++
++ if(!nouserrc) {
++ char *buf;
++
++ ctmp = g_get_home_dir();
++
++ buf = alloca(strlen(ctmp) + sizeof("/.orbitrc"));
++ sprintf(buf, "%s/.orbitrc", ctmp);
++ ORBit_rc_load(buf, options);
++ freeca(buf);
++ }
++
++ ORBit_option_parse(argc, argv, options);
++#endif /* !__KORBIT__ */
++
++ ORBit_Trace_setLevel(debug_level);
++ ORBit_Trace_setModules(debug_modules);
++
++ CORBA_exception_init(ev);
++
++ ORBit_chunks_init();
++
++ giop_init(argv[0]);
++
++ orb=g_new0(struct CORBA_ORB_type, 1);
++
++ if(orb==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(orb), ORBIT_PSEUDO_ORB, ev);
++
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(orb),
++ (gpointer)&CORBA_ORB_epv, ev);
++
++ ORBIT_ROOT_OBJECT(orb)->refs = 1;
++
++ if(orb_id_opt!=NULL) {
++ if(!ORBit_ORBid_setup(orb, orb_id_opt))
++ goto error;
++ g_free(orb_id_opt);
++ } else if(orb_identifier!=NULL) {
++ if(!ORBit_ORBid_setup(orb, orb_identifier))
++ goto error;
++ } else {
++ orb->orb_identifier=g_strdup("orbit-local-orb");
++ }
++
++ if(orb->orb_identifier==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ if(use_ipv4) {
++ orb->cnx.ipv4 = GIOP_CONNECTION(iiop_connection_server());
++
++ giop_connection_ref(orb->cnx.ipv4);
++ GIOP_CONNECTION(orb->cnx.ipv4)->orb_data = orb;
++ }
++
++ if(use_ipv6) {
++ orb->cnx.ipv6 = GIOP_CONNECTION(iiop_connection_server_ipv6());
++ giop_connection_ref(orb->cnx.ipv6);
++ GIOP_CONNECTION(orb->cnx.ipv6)->orb_data = orb;
++ }
++
++#ifndef __KORBIT__
++ if(use_usock) {
++ orb->cnx.usock = ORBit_ORB_make_usock_connection();
++
++ giop_connection_ref(orb->cnx.usock);
++ GIOP_CONNECTION(orb->cnx.usock)->orb_data = orb;
++ }
++#endif
++
++ orb->objrefs = g_hash_table_new((GHashFunc)g_CORBA_Object_hash,
++ (GCompareFunc)g_CORBA_Object_equal);
++ orb->poas = g_ptr_array_new();
++
++ /* when I figure out what MICO is doing with the iiop_proxy and
++ * iiop_server stuff, it'll get handled here.
++ */
++
++ /*
++ * Connect to / create implementation repository
++ */
++
++ {
++ CORBA_Object imr=NULL;
++
++ if(imr_ior!=NULL) {
++ imr=CORBA_ORB_string_to_object(orb, imr_ior, ev);
++ g_free(imr_ior);
++ } else if(imr_addr!=NULL) {
++ /*imr=CORBA_ORB_bind(orb, "IDL:omg.org/CORBA/ImplRepository:1.0", imr_addr, ev);*/
++ g_free(imr_addr);
++ }
++
++ if(!CORBA_Object_is_nil(imr, ev)) {
++ CORBA_ORB_set_initial_reference(orb, "ImplementationRepository", imr, ev);
++ }
++ }
++
++ /*
++ * Connect to / create interface repository
++ */
++
++ {
++ CORBA_Object ir=NULL;
++
++ if(ir_ior!=NULL) {
++ ir=CORBA_ORB_string_to_object(orb, ir_ior, ev);
++ g_free(ir_ior);
++ } else if(ir_addr!=NULL) {
++ /*ir=CORBA_ORB_bind(orb, "IDL:omg.org/CORBA/Repository:1.0", ir_addr, ev);*/
++ g_free(ir_addr);
++ }
++
++ if(!CORBA_Object_is_nil(ir, ev)) {
++ CORBA_ORB_set_initial_reference(orb, "InterfaceRepository", ir, ev);
++ }
++ }
++
++ /*
++ * Connect to naming service
++ */
++
++ {
++ CORBA_Object naming=NULL;
++
++ if(naming_ior!=NULL) {
++ naming=CORBA_ORB_string_to_object(orb, naming_ior, ev);
++ g_free(naming_ior);
++ } else if(naming_addr!=NULL) {
++ /*CORBA_ORB_ObjectTag tag=CORBA_ORB_string_to_tag(orb, "root", ev);*/
++
++ /*naming=CORBA_ORB_bind_tag(orb, "IDL:omg.org/CosNaming/NamingContext:1.0", tag, naming_addr, ev);*/
++ g_free(naming_addr);
++ }
++
++ if(!CORBA_Object_is_nil(naming, ev)) {
++ CORBA_ORB_set_initial_reference(orb, "NameService", naming, ev);
++ }
++ }
++
++ /*
++ * Connect to / create RootPOA
++ */
++
++ {
++ PortableServer_POA root_poa=CORBA_OBJECT_NIL;
++
++ if(root_poa_ior!=NULL) {
++ root_poa=(PortableServer_POA)
++ CORBA_ORB_string_to_object(orb,
++ root_poa_ior, ev);
++ g_free(root_poa_ior);
++ }
++
++ /* And attatch it to the orb */
++
++ if(!CORBA_Object_is_nil((CORBA_Object)root_poa, ev)) {
++ CORBA_ORB_set_initial_reference((CORBA_ORB)orb,
++ "RootPOA",
++ (CORBA_Object)root_poa,
++ ev);
++ }
++ }
++
++ ORBit_custom_run_setup(orb, ev);
++
++ if (!strcmp("server", argv[0])) // Only do this for servers.
++ TheOneTrueOrb = orb;
++ up(&StartupSem); // Okay, let the insmod thread continue...
++ return orb;
++
++error:
++ if(orb!=NULL) {
++ ORBit_ORB_release(orb, ev);
++ orb = NULL;
++ }
++ g_free(imr_ior);
++ g_free(imr_addr);
++ g_free(ir_ior);
++ g_free(ir_addr);
++ g_free(naming_ior);
++ g_free(naming_addr);
++ g_free(root_poa_ior);
++ g_free(root_poa_addr);
++ g_free(orb_id_opt);
++
++ TheOneTrueOrb = 0;
++ up(&StartupSem); // Okay, let the insmod thread continue...
++ return 0;
++}
++
++
++#if __KERNEL__
++#include <linux/smp_lock.h>
++#include <linux/proc_fs.h>
++
++// This is the main corba thread function...
++//
++void __CORBA_ORB_run(CORBA_ORB orb, CORBA_Environment *ev);
++int MainCORBAThread(void *Args) {
++ // Make a directory in /proc... yaay...
++ proc_mkdir("corba", 0);
++
++ __CORBA_ORB_init((struct CORBA_ORB_init_args*)Args);
++ if (TheOneTrueOrb == 0) return 0;
++
++ strcpy(current->comm, "korbit"); // Set the thread name...
++
++ lock_kernel(); /* This seems to be required for exit_mm */
++ exit_mm(current);
++
++ __CORBA_ORB_run(TheOneTrueOrb,
++ ((struct CORBA_ORB_init_args*)Args)->ev);
++ return 0;
++}
++#endif
++
++
++/* Section 4.4
++ *
++ * Adjusts argc and argv appropriately
++ */
++
++CORBA_ORB CORBA_ORB_init(int *argc, char **argv, CORBA_ORBid orb_identifier,
++ CORBA_Environment *ev) {
++
++ struct CORBA_ORB_init_args Args;
++ Args.argc = argc;
++ Args.argv = argv;
++ Args.orb_identifier = orb_identifier;
++ Args.ev = ev;
++
++#ifdef __KERNEL__
++ if (!strcmp(argv[0], "server")) { // Are we a server?
++ down(&StartupSem); // Grab the semaphore...
++ if (TheOneTrueOrb) {
++ CORBA_exception_init(ev);
++ goto out_success;
++ }
++
++ // This releases the semaphore when it is done initializing.
++ (void)kernel_thread(MainCORBAThread, &Args,
++ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++
++ // This will block until the semaphore is released by the
++ // ORB thread.
++ down(&StartupSem);
++ } else { // If we are a corba client, like CorbaFS...
++ return __CORBA_ORB_init(&Args);
++ }
++
++ out_success:
++ up(&StartupSem); // Okay, we're now here.
++#else
++ __CORBA_ORB_init(&Args);
++#endif
++ if (TheOneTrueOrb)
++ return (CORBA_ORB)CORBA_Object_duplicate((CORBA_Object)TheOneTrueOrb, ev);
++ return 0;
++}
++
++
++
++
++typedef struct {
++ CORBA_Object obj;
++ CDR_Codec *codec;
++ gboolean emit_active;
++} profile_user_data;
++
++static void ORBit_emit_profile(gpointer item, gpointer userdata)
++{
++ ORBit_Object_info *profile=(ORBit_Object_info *)item;
++ profile_user_data *data=(profile_user_data *)userdata;
++ CORBA_Object obj=data->obj;
++ CDR_Codec encaps_codec_d;
++ CDR_Codec *codec=data->codec, *encaps = &encaps_codec_d;
++ gboolean emit_active=data->emit_active;
++ static const CORBA_octet iiopversion[] = {1,0};
++ CORBA_octet codecbuf[2048];
++
++ g_assert(obj!=NULL);
++ g_assert(codec!=NULL);
++ g_assert(profile!=NULL);
++
++ if((profile == obj->active_profile) && (emit_active == FALSE))
++ return; /* we already did this one */
++
++ switch(profile->profile_type) {
++ case IOP_TAG_INTERNET_IOP:
++ CDR_codec_init_static(encaps);
++ encaps->buffer = codecbuf;
++ encaps->release_buffer = CORBA_FALSE;
++ encaps->buf_len = 2048;
++ encaps->readonly = CORBA_FALSE;
++ encaps->host_endian = encaps->data_endian = FLAG_ENDIANNESS;
++
++ CDR_put_ulong(codec, IOP_TAG_INTERNET_IOP);
++ CDR_put_octet(encaps, FLAG_ENDIANNESS);
++ CDR_put_octets(encaps, (gpointer)iiopversion, sizeof(iiopversion));
++ CDR_put_string(encaps, profile->tag.iopinfo.host);
++ CDR_put_ushort(encaps, profile->tag.iopinfo.port);
++ CDR_put_ulong(encaps, profile->object_key._length);
++ CDR_put_octets(encaps, profile->object_key._buffer,
++ profile->object_key._length);
++ CDR_put_ulong(codec, encaps->wptr);
++ CDR_put_octets(codec, encaps->buffer, encaps->wptr);
++ break;
++
++ case IOP_TAG_ORBIT_SPECIFIC:
++ CDR_codec_init_static(encaps);
++ encaps->buffer = codecbuf;
++ encaps->release_buffer = CORBA_FALSE;
++ encaps->buf_len = 2048;
++ encaps->readonly = CORBA_FALSE;
++ encaps->host_endian = encaps->data_endian = FLAG_ENDIANNESS;
++
++ CDR_put_ulong(codec, IOP_TAG_ORBIT_SPECIFIC);
++ CDR_put_octet(encaps, FLAG_ENDIANNESS);
++ CDR_put_octets(encaps, (gpointer)iiopversion, sizeof(iiopversion));
++ CDR_put_string(encaps, profile->tag.orbitinfo.unix_sock_path);
++ CDR_put_ushort(encaps, profile->tag.orbitinfo.ipv6_port);
++ CDR_put_ulong(encaps, profile->object_key._length);
++ CDR_put_octets(encaps, profile->object_key._buffer,
++ profile->object_key._length);
++ CDR_put_ulong(codec, encaps->wptr);
++ CDR_put_octets(codec, encaps->buffer, encaps->wptr);
++ break;
++
++ default:
++ g_warning("Skipping tag %d", profile->profile_type);
++ break;
++ }
++}
++
++CORBA_char *CORBA_ORB_object_to_string(CORBA_ORB orb,
++ CORBA_Object obj,
++ CORBA_Environment *ev)
++{
++ int i;
++ CDR_Codec codec_d;
++ CDR_Codec *codec = &codec_d;
++ CORBA_char *rc = NULL;
++ CORBA_unsigned_long ntags;
++ profile_user_data data;
++ CORBA_octet codecbuf[2048];
++ char *ctmp;
++
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(orb && obj, NULL);
++
++ if(!obj || !orb) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ if(ORBIT_ROOT_OBJECT(obj)->is_pseudo_object) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ CDR_codec_init_static(codec);
++
++ codec->buffer = codecbuf;
++ codec->release_buffer = CORBA_FALSE;
++ codec->buf_len = 2048;
++ codec->readonly = CORBA_FALSE;
++ codec->host_endian = codec->data_endian = FLAG_ENDIANNESS;
++
++ CDR_put_octet(codec, FLAG_ENDIANNESS);
++
++ CDR_put_string(codec, obj->object_id);
++ ntags = g_slist_length(obj->profile_list);
++ CDR_put_ulong(codec, ntags);
++
++ data.obj=obj;
++ data.codec=codec;
++ data.emit_active=TRUE;
++ if(obj->active_profile != NULL)
++ ORBit_emit_profile(obj->active_profile, &data); /* do this one first */
++
++ data.emit_active=FALSE;
++ g_slist_foreach(obj->profile_list, ORBit_emit_profile, &data);
++
++ rc = CORBA_string_alloc(4 + (codec->wptr * 2) + 1);
++ strcpy(rc, "IOR:");
++
++#define hexdigit(n) (((n)>9)?(n+'a'-10):(n+'0'))
++
++ for(i = 0, ctmp = rc + strlen("IOR:"); i < codec->wptr; i++) {
++ *(ctmp++) = hexdigit((((codec->buffer[i]) & 0xF0) >> 4));
++ *(ctmp++) = hexdigit(((codec->buffer[i]) & 0xF));
++ }
++ *ctmp = '\0';
++
++ {
++ /* Debug check */
++ CORBA_Object obj;
++ CORBA_Environment myev;
++
++ CORBA_exception_init(&myev);
++
++ obj = CORBA_ORB_string_to_object(orb, rc, &myev);
++
++ if (CORBA_Object_is_nil(obj, &myev)) {
++ g_warning("Bug in %s, created bad IOR `%s'\n",
++ __FUNCTION__, rc);
++ CORBA_free(rc);
++ return NULL;
++ }
++
++ CORBA_Object_release(obj, &myev);
++ }
++
++ return rc;
++}
++
++/* Quote from the GNU libc manual:
++
++ "If you try to allocate more storage than the machine can provide,
++ you don't get a clean error message. Instead you get a fatal
++ signal like the one you would get from an infinite recursion;
++ probably a segmentation violation (see section Program Error
++ Signals)."
++
++ The man page claims alloca() returns NULL on failure; this appears
++ to be a load of shit on Linux where you just get flaming death, but
++ we check anyway in case other systems work that way.
++
++ On Linux we check that the size is less than MAX_STACK_ALLOC
++
++ Note that the CORBA_alloc() calls in here can still cause
++ program abort, and really that should be fixed in a similar
++ way since our lengths are coming in from unpredictable sources
++ like files or the network.
++*/
++
++#define MAX_STACK_ALLOC 8192
++
++CORBA_Object CORBA_ORB_string_to_object(CORBA_ORB orb, CORBA_char *str,
++ CORBA_Environment *ev)
++{
++ GSList *profiles=NULL;
++ CORBA_Object retval = NULL;
++ CORBA_char *type_id;
++ ORBit_Object_info *object_info;
++ CDR_Codec codec_d, encaps_codec_d;
++ CDR_Codec *codec = &codec_d, *encaps_codec = &encaps_codec_d;
++ CORBA_octet *buffer, endian;
++ int i, j;
++ CORBA_unsigned_long len, seq_len, misclen;
++
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(orb && str, CORBA_OBJECT_NIL);
++
++ if(strncmp(str, "IOR:", 4)) {
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_NO);
++ return(CORBA_OBJECT_NIL);
++ }
++
++ CDR_codec_init_static(codec);
++ len = strlen(str);
++
++ if((len % 2) || len <= 4) {
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_NO);
++ return(CORBA_OBJECT_NIL);
++ }
++
++ codec->buf_len = (len-4)/2;
++ buffer = alloca(codec->buf_len);
++
++ codec->buffer=buffer;
++ codec->release_buffer = CORBA_FALSE;
++ codec->readonly = TRUE;
++
++ for(j = 0, i = 4; i < len; i+=2) {
++ buffer[j++] = HEXOCTET(str[i], str[i+1]);
++ };
++
++ CDR_get_octet(codec, &endian);
++
++ codec->data_endian = endian;
++ codec->host_endian = FLAG_ENDIANNESS;
++
++ CDR_get_string_static(codec, &type_id);
++
++ CDR_get_seq_begin(codec, &seq_len);
++
++ for(i = 0; i < seq_len; i++) {
++ IOP_ProfileId tag;
++
++ object_info=g_new0(ORBit_Object_info, 1);
++
++ if (!CDR_get_ulong(codec, &tag))
++ goto error_out;
++
++ switch(tag) {
++ case IOP_TAG_INTERNET_IOP:
++ if (!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->readonly = CORBA_TRUE;
++ if(!CDR_get_octet(encaps_codec, &endian))
++ goto error_out;
++ encaps_codec->data_endian = endian;
++ encaps_codec->host_endian = FLAG_ENDIANNESS;
++
++ if (encaps_codec->data_endian > 1)
++ goto error_out;
++
++ object_info->profile_type = IOP_TAG_INTERNET_IOP;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_major))
++ goto error_out;
++ if(object_info->iiop_major != 1)
++ goto error_out;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_minor))
++ goto error_out;
++ if(!CDR_get_string(encaps_codec, &object_info->tag.iopinfo.host))
++ goto error_out;
++ if(!CDR_get_ushort(encaps_codec, &object_info->tag.iopinfo.port))
++ goto error_out;
++ if(!CDR_get_seq_begin(encaps_codec, &object_info->object_key._length))
++ goto error_out;
++
++ object_info->object_key._maximum = 0;
++
++ /* The POA gives out ORBit_alloc()d profiles, so we have to too */
++ object_info->object_key._buffer = ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ if(!CDR_buffer_gets(encaps_codec, object_info->object_key._buffer,
++ object_info->object_key._length))
++ goto error_out;
++
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ break;
++
++ case IOP_TAG_MULTIPLE_COMPONENTS:
++ /* Just skip any multiple_components data, for now */
++ if(!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ encaps_codec->readonly = CORBA_TRUE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++ break;
++
++ case IOP_TAG_ORBIT_SPECIFIC:
++ if(!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->readonly = CORBA_TRUE;
++
++ if(!CDR_get_octet(encaps_codec, &endian))
++ goto error_out;
++
++ encaps_codec->data_endian = endian;
++ encaps_codec->host_endian = FLAG_ENDIANNESS;
++
++ if (encaps_codec->data_endian > 1)
++ goto error_out;
++
++ object_info->profile_type=IOP_TAG_ORBIT_SPECIFIC;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_major))
++ goto error_out;
++
++ if(object_info->iiop_major != 1)
++ goto error_out;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_minor))
++ goto error_out;
++
++ if(!CDR_get_string(encaps_codec, &object_info->tag.orbitinfo.unix_sock_path))
++ goto error_out;
++
++ if(!CDR_get_ushort(encaps_codec, &object_info->tag.orbitinfo.ipv6_port))
++ goto error_out;
++ if(!CDR_get_seq_begin(encaps_codec, &object_info->object_key._length))
++ goto error_out;
++ object_info->object_key._maximum = 0;
++
++ /* The POA gives out ORBit_alloc()d profiles, so we have to too */
++ object_info->object_key._buffer = ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ if(!CDR_buffer_gets(encaps_codec, object_info->object_key._buffer,
++ object_info->object_key._length))
++ goto error_out;
++
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ break;
++ default:
++ g_warning("Unknown tag 0x%x", tag);
++
++ /* Skip it */
++ if(!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ encaps_codec->readonly = CORBA_TRUE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++
++ break;
++ }
++ }
++
++ freeca(buffer); /* Same as codec->buffer */
++ freeca(encaps_codec->buffer);
++
++ return ORBit_create_object_with_info(profiles, type_id, orb, ev);
++
++ error_out:
++
++ if(object_info) {
++ CORBA_free(object_info->object_key._buffer);
++ g_free(object_info);
++ ORBit_delete_profiles(profiles);
++ }
++
++ freeca(buffer); /* Same as codec->buffer */
++ freeca(encaps_codec->buffer);
++
++ return retval;
++}
++
++/* Section 4.1.2 */
++CORBA_boolean CORBA_ORB_get_service_information(CORBA_ORB orb, CORBA_ServiceType service_type, CORBA_ServiceInformation *service_information, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(CORBA_FALSE);
++}
++
++CORBA_Current *CORBA_ORB_get_current(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(orb, NULL);
++
++ /* XXX check this over */
++ return (CORBA_Current *)GET_THREAD_DATA();
++}
++
++/* Section 4.5 */
++CORBA_ORB_ObjectIdList *CORBA_ORB_list_initial_services(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ static const char *services[] = {"RootPOA"};
++ CORBA_ORB_ObjectIdList *list;
++
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(orb, NULL);
++
++ list = (CORBA_ORB_ObjectIdList *)CORBA_sequence_octet__alloc();
++ list->_maximum=list->_length= 1;
++ list->_buffer = (CORBA_ORB_ObjectId *)services;
++ CORBA_sequence_set_release((void *)list, CORBA_FALSE);
++
++ /* defined reserved references are:
++ * RootPOA
++ * POACurrent
++ * InterfaceRepository
++ * NameService
++ * TradingService
++ * SecurityCurrent
++ * TransactionCurrent
++ */
++
++ return list;
++}
++
++/* Section 4.5
++ *
++ * raises InvalidName
++ */
++CORBA_Object CORBA_ORB_resolve_initial_references(CORBA_ORB orb, CORBA_ORB_ObjectId identifier, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(orb, CORBA_OBJECT_NIL);
++
++ if(!strcmp(identifier, "ImplementationRepository"))
++ return CORBA_Object_duplicate(orb->imr, ev);
++ else if(!strcmp(identifier, "InterfaceRepository"))
++ return CORBA_Object_duplicate(orb->ir, ev);
++ else if(!strcmp(identifier, "NameService"))
++ return CORBA_Object_duplicate(orb->naming, ev);
++ else if(!strcmp(identifier, "RootPOA")) {
++ if(CORBA_Object_is_nil(orb->root_poa, ev)) {
++ CORBA_PolicyList policies = {0,0,NULL,CORBA_FALSE};
++ PortableServer_POAManager poa_mgr;
++ /* Create a poa manager */
++ poa_mgr = ORBit_POAManager_new(ev);
++ poa_mgr->orb = orb;
++
++ /* Create the root poa */
++ orb->root_poa = (CORBA_Object)
++ ORBit_POA_new(orb,
++ "RootPOA",
++ poa_mgr,
++ &policies,
++ ev);
++ CORBA_Object_duplicate(orb->root_poa, ev);
++ }
++
++ return CORBA_Object_duplicate(orb->root_poa, ev);
++ }
++
++ /* throw user exception: InvalidName */
++ CORBA_exception_set(ev,CORBA_USER_EXCEPTION,
++ ex_CORBA_ORB_InvalidName,
++ NULL);
++
++ goto error;
++error:
++ return(NULL);
++}
++
++/* This is a MICO extension
++ *
++ * raises InvalidName
++ */
++void CORBA_ORB_set_initial_reference(CORBA_ORB orb, CORBA_ORB_ObjectId identifier, CORBA_Object obj, CORBA_Environment *ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(orb && identifier && obj);
++
++ if(!strcmp(identifier, "ImplementationRepository")) {
++ if(!CORBA_Object_is_nil(orb->imr, ev)) {
++ CORBA_Object_release(orb->imr, ev);
++ }
++ orb->imr=CORBA_Object_duplicate(obj, ev);
++ } else if(!strcmp(identifier, "InterfaceRepository")) {
++ if(!CORBA_Object_is_nil(orb->ir, ev)) {
++ CORBA_Object_release(orb->ir, ev);
++ }
++ orb->ir=CORBA_Object_duplicate(obj, ev);
++ } else if(!strcmp(identifier, "NameService")) {
++ if(!CORBA_Object_is_nil(orb->naming, ev)) {
++ CORBA_Object_release(orb->naming, ev);
++ }
++ orb->naming=CORBA_Object_duplicate(obj, ev);
++ } else if(!strcmp(identifier, "RootPOA")) {
++ if(!CORBA_Object_is_nil(orb->root_poa, ev)) {
++ CORBA_Object_release(orb->root_poa, ev);
++ }
++ orb->root_poa=CORBA_Object_duplicate(obj, ev);
++ } else {
++ /* throw user exception: InvalidName */
++ CORBA_exception_set(ev,CORBA_USER_EXCEPTION,ex_CORBA_ORB_InvalidName,NULL);
++ goto error;
++ }
++
++ return;
++error:
++ return;
++}
++
++/* Section 4.9.1 */
++CORBA_boolean CORBA_ORB_work_pending(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(CORBA_FALSE);
++}
++
++/* Section 4.9.2 */
++void CORBA_ORB_perform_work(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++/* Section 4.9.4 */
++void
++CORBA_ORB_shutdown(CORBA_ORB orb,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(orb);
++
++ /* XXX implement on a per-ORB basis, and also
++ handle whatever wait_for_completion means */
++
++ if(orb->cnx.ipv4)
++ giop_connection_unref(orb->cnx.ipv4);
++ if(orb->cnx.ipv6)
++ giop_connection_unref(orb->cnx.ipv6);
++#ifndef __KORBIT__
++ if(orb->cnx.usock)
++ giop_connection_unref(orb->cnx.usock);
++#endif
++
++ giop_main_quit();
++}
++
++/* Section 4.9.3 */
++/* CORBA_ORB_run is in server.c */
++
++/* Section 4.7 */
++CORBA_PolicyType
++CORBA_Policy__get_policy_type(CORBA_Policy obj, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, 0);
++ o_return_val_if_fail(obj, 0);
++
++ return obj->policy_type;
++}
++
++/* Section 4.7 */
++CORBA_Policy CORBA_Policy_copy(CORBA_Policy obj, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(obj, CORBA_OBJECT_NIL);
++
++ ORBIT_ROOT_OBJECT_REF(obj);
++
++ return obj;
++}
++
++/* Section 4.7
++ *
++ * raises CORBA_NO_PERMISSION
++ */
++void CORBA_Policy_destroy(CORBA_Policy obj, CORBA_Environment *ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(obj);
++
++ ORBIT_ROOT_OBJECT_UNREF(obj);
++ if(ORBIT_ROOT_OBJECT(obj)->refs <= 0)
++ ORBIT_ROOT_OBJECT_release(obj, ev);
++}
++
++#ifndef __KORBIT__
++/* Section 4.8.2 */
++CORBA_Policy CORBA_DomainManager_get_domain_policy(CORBA_DomainManager obj, CORBA_PolicyType policy_type, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(obj, CORBA_OBJECT_NIL);
++
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++/* Section 4.8.2 */
++void CORBA_ConstructionPolicy_make_domain_manager(CORBA_ConstructionPolicy obj, CORBA_InterfaceDef object_type, CORBA_boolean constr_policy, CORBA_Environment *
++ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(obj && object_type);
++
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++/* Section 4.2.8 */
++CORBA_DomainManagerList *CORBA_Object_get_domain_managers(CORBA_Object obj, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(obj, NULL);
++
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_struct_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_StructMemberSeq members, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc == NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, members._length);
++ if(tc->subtypes == NULL)
++ goto subtypes_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames == NULL)
++ goto subnames_alloc_failed;
++
++ tc->kind=CORBA_tk_struct;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=members._length;
++ tc->length=members._length;
++
++ for(i=0;i<members._length;i++) {
++ CORBA_StructMember *mem=(CORBA_StructMember *)&(members._buffer[i]);
++
++ g_assert(&(mem->type)!=NULL);
++
++ tc->subtypes[i] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[i], mem->type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++ tc->subnames[i]=g_strdup(mem->name);
++ }
++
++ return(tc);
++
++ subnames_alloc_failed:
++ g_free(tc->subtypes);
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return NULL;
++}
++
++CORBA_TypeCode
++CORBA_ORB_create_union_tc(CORBA_ORB obj, CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_TypeCode discriminator_type,
++ CORBA_UnionMemberSeq members,
++ CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++
++ if(tc == NULL)
++ goto tc_alloc_failed;
++
++ tc->discriminator = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++
++ if(tc->discriminator == NULL)
++ goto discriminator_alloc_failed;
++
++ memcpy(tc->discriminator, discriminator_type, (size_t)sizeof(CORBA_TypeCode));
++
++ tc->subtypes=g_new0(CORBA_TypeCode, members._length);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames==NULL)
++ goto subnames_alloc_failed;
++
++ tc->sublabels=g_new0(CORBA_any, members._length);
++ if(tc->sublabels == NULL)
++ goto sublabels_alloc_failed;
++
++ tc->kind=CORBA_tk_union;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=members._length;
++ tc->length=members._length;
++ tc->default_index=-1;
++
++ for(i=0;i<members._length;i++) {
++ CORBA_UnionMember *mem=(CORBA_UnionMember *)&(members._buffer[i]);
++
++ g_assert(&(mem->label)!=NULL);
++ memcpy(&(tc->sublabels[i]), &(mem->label), (size_t)sizeof(CORBA_any));
++ g_assert(&(mem->type)!=NULL);
++ tc->subtypes[i] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[i], mem->type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++ tc->subnames[i]=g_strdup(mem->name);
++
++ if(mem->label._type->kind==CORBA_tk_octet) {
++ tc->default_index=i;
++ }
++ }
++
++ return(tc);
++
++sublabels_alloc_failed:
++ g_free(tc->sublabels);
++subnames_alloc_failed:
++ g_free(tc->subtypes);
++subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc->discriminator);
++discriminator_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return NULL;
++}
++
++CORBA_TypeCode CORBA_ORB_create_enum_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_EnumMemberSeq members, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc == NULL)
++ goto tc_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames==NULL)
++ goto subnames_alloc_failed;
++
++ tc->kind = CORBA_tk_enum;
++ tc->name = g_strdup(name);
++ tc->repo_id = g_strdup(id);
++ tc->sub_parts = members._length;
++ tc->length = members._length;
++
++ for(i=0;i<members._length;i++) {
++ tc->subnames[i]=g_strdup(members._buffer[i]);
++ }
++
++ return(tc);
++
++ subnames_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_alias_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_TypeCode original_type, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ /* Can't use chunks here, because it's sometimes an array. Doh! */
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_alias;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=1;
++ tc->length=1;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[0], original_type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++
++ return(tc);
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return NULL;
++}
++
++CORBA_TypeCode CORBA_ORB_create_exception_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_StructMemberSeq members, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, members._length);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames==NULL)
++ goto subnames_alloc_failed;
++
++ tc->kind=CORBA_tk_except;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=members._length;
++ tc->length=members._length;
++
++ for(i=0;i<members._length;i++) {
++ CORBA_StructMember *mem=(CORBA_StructMember *)&(members._buffer[i]);
++
++ g_assert(mem->type != NULL);
++ tc->subtypes[i] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[i], mem->type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++ tc->subnames[i]=g_strdup(mem->name);
++ }
++
++ return(tc);
++
++ subnames_alloc_failed:
++ g_free(tc->subtypes);
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_interface_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_objref;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_string_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_string;
++ tc->length=bound;
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_wstring_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_wstring;
++ tc->length=bound;
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_fixed_tc(CORBA_ORB obj, CORBA_unsigned_short digits, CORBA_short scale, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_fixed;
++ tc->digits=digits;
++ tc->scale=scale;
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_sequence_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_TypeCode element_type, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ /* Can't use chunks here because we can only be sure of getting
++ one consecutive chunk from glib */
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_sequence;
++ tc->sub_parts=1;
++ tc->length=bound;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[0], element_type,
++ (size_t)sizeof(struct CORBA_TypeCode_struct));
++
++ return(tc);
++
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_recursive_sequence_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_unsigned_long offset, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_sequence;
++ tc->sub_parts=1;
++ tc->length=bound;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ tc->subtypes[0]->kind=CORBA_tk_recursive;
++ tc->subtypes[0]->recurse_depth=offset;
++
++ return(tc);
++
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_array_tc(CORBA_ORB obj, CORBA_unsigned_long length, CORBA_TypeCode element_type, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_array;
++ tc->sub_parts=1;
++ tc->length=length;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[0], element_type, (size_t)sizeof(CORBA_TypeCode));
++
++ return(tc);
++
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++#endif /* !__KORBIT__ */
+diff -urN linux-2.4.1/net/korbit/orb/orb.h linux-2.4.1-korbit/net/korbit/orb/orb.h
+--- linux-2.4.1/net/korbit/orb/orb.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orb.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,231 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_ORB_H_
++#define _ORBIT_ORB_H_
++
++#include "orb/orbit_types.h"
++#ifndef __KORBIT__
++#include "orb/interface_repository.h"
++#endif /* !__KORBIT__ */
++
++extern CORBA_ORB CORBA_ORB_init(
++ int *argc,
++ char **argv,
++ CORBA_ORBid orb_identifier,
++ CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_ORB_object_to_string(
++ CORBA_ORB orb,
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Object CORBA_ORB_string_to_object(
++ CORBA_ORB orb,
++ CORBA_char *str,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_ORB_get_default_context(
++ CORBA_ORB orb,
++ CORBA_Context *ctx,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_ORB_get_service_information(
++ CORBA_ORB orb,
++ CORBA_ServiceType service_type,
++ CORBA_ServiceInformation *service_information,
++ CORBA_Environment *ev);
++
++extern CORBA_Current *CORBA_ORB_get_current(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern CORBA_ORB_ObjectIdList* CORBA_ORB_list_initial_services(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern CORBA_Object CORBA_ORB_resolve_initial_references(
++ CORBA_ORB orb,
++ CORBA_ORB_ObjectId identifier,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_set_initial_reference(
++ CORBA_ORB orb,
++ CORBA_ORB_ObjectId identifier,
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_ORB_work_pending(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_perform_work(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_shutdown(
++ CORBA_ORB orb,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_run(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern CORBA_PolicyType CORBA_Policy__get_policy_type(
++ CORBA_Policy obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Policy CORBA_Policy_copy(
++ CORBA_Policy obj,
++ CORBA_Environment *ev);
++
++extern void CORBA_Policy_destroy(
++ CORBA_Policy obj,
++ CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_InterfaceDef CORBA_Object_get_interface(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++#endif /* !__KORBIT__ */
++
++extern CORBA_boolean CORBA_Object_is_nil(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Object CORBA_Object_duplicate(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern void CORBA_Object_release(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_Object_non_existent(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_Object_is_equivalent(
++ CORBA_Object obj,
++ CORBA_Object other_object,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_long CORBA_Object_hash(
++ CORBA_Object obj,
++ CORBA_unsigned_long maximum,
++ CORBA_Environment *ev);
++
++extern CORBA_Policy CORBA_Object_get_policy(
++ CORBA_Object obj,
++ CORBA_PolicyType policy_type,
++ CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_DomainManagerList *CORBA_Object_get_domain_managers(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Policy CORBA_DomainManager_get_domain_policy(
++ CORBA_DomainManager obj,
++ CORBA_PolicyType policy_type,
++ CORBA_Environment *ev);
++
++extern void CORBA_ConstructionPolicy_make_domain_manager(
++ CORBA_ConstructionPolicy obj,
++ CORBA_Object /*CORBA_InterfaceDef*/ object_type,
++ CORBA_boolean constr_policy,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_struct_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_StructMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_union_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_TypeCode discriminator_type,
++ CORBA_UnionMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_enum_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_EnumMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_alias_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_TypeCode original_type,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_exception_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_StructMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_interface_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_string_tc(CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_wstring_tc(CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_fixed_tc(CORBA_ORB obj,
++ CORBA_unsigned_short digits,
++ CORBA_short scale,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_ORB_create_sequence_tc(
++ CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_TypeCode element_type,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_ORB_create_recursive_sequence_tc(
++ CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_unsigned_long offset,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_ORB_create_array_tc(
++ CORBA_ORB obj,
++ CORBA_unsigned_long length,
++ CORBA_TypeCode element_type,
++ CORBA_Environment *ev);
++
++#endif /* !__KORBIT__ */
++
++#endif /* !_ORBIT_ORB_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit.c linux-2.4.1-korbit/net/korbit/orb/orbit.c
+--- linux-2.4.1/net/korbit/orb/orbit.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,387 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++/*
++ * This file is a repository for random functions that don't fit anywhere
++ * else, and for ORBit-specific stuff.
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
++#include <netdb.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <assert.h>
++#include <math.h>
++
++#include "orbit.h"
++
++const guint orbit_major_version = ORBIT_MAJOR_VERSION,
++ orbit_minor_version = ORBIT_MINOR_VERSION,
++ orbit_micro_version = ORBIT_MICRO_VERSION;
++const char orbit_version[] = ORBIT_VERSION;
++
++typedef struct ORBitClassInfo ORBitClassInfo;
++
++typedef void (*ORBitObjectInitFunc)(CORBA_Object _handle_to_be, gpointer class_data);
++
++struct ORBitClassInfo {
++ char *name;
++ gulong id;
++ gpointer method_stubs, method_skels;
++ ORBitObjectInitFunc class_vtable_init_func;
++ ORBitClassInfo **parent_classes;
++};
++
++GHashTable *orbit_class_list = NULL, *orbit_class_byid;
++glong class_id_counter = -1;
++
++void CORBA_any_set_release(CORBA_any *any, CORBA_boolean flag)
++{
++ g_assert(any!=NULL);
++
++ if(flag==CORBA_TRUE) {
++ any->_release |= CORBA_ANYFLAGS_RELEASE;
++ } else {
++ any->_release &= ~CORBA_ANYFLAGS_RELEASE;
++ }
++
++}
++
++CORBA_boolean CORBA_any_get_release(CORBA_any *any)
++{
++ g_assert(any!=NULL);
++
++ if(any->_release & CORBA_ANYFLAGS_RELEASE)
++ return(CORBA_TRUE);
++ else
++ return(CORBA_FALSE);
++}
++
++void CORBA_sequence_set_release(void *seq, CORBA_boolean flag)
++{
++ struct CORBA_Sequence_type *sequence;
++
++ g_assert(seq!=NULL);
++
++ sequence=(struct CORBA_Sequence_type *)seq;
++
++ if(flag==CORBA_TRUE) {
++ sequence->_release |= CORBA_ANYFLAGS_RELEASE;
++ } else {
++ sequence->_release &= ~CORBA_ANYFLAGS_RELEASE;
++ }
++}
++
++CORBA_boolean CORBA_sequence_get_release(void *seq)
++{
++ struct CORBA_Sequence_type *sequence;
++
++ g_assert(seq!=NULL);
++
++ sequence=(struct CORBA_Sequence_type *)seq;
++
++ if(sequence->_release & CORBA_ANYFLAGS_RELEASE)
++ return(CORBA_TRUE);
++ else
++ return(CORBA_FALSE);
++}
++
++/*
++ * As far as I understand, values returned by CORBA_*_alloc() are supposed to be
++ * freeable by CORBA_free(), so we can't use memory chunks here in any reasonable
++ * fashion.
++ */
++gpointer
++CORBA_any__free(gpointer mem, gpointer func_data, CORBA_boolean free_strings)
++{
++ CORBA_any *aval = mem;
++
++ if(aval->_release)
++ ORBit_free(aval->_value, free_strings);
++ CORBA_Object_release((CORBA_Object)aval->_type, NULL);
++
++ return aval + 1;
++}
++
++CORBA_any *CORBA_any_alloc(void)
++{
++ CORBA_any *retval = ORBit_alloc(sizeof(CORBA_any), &CORBA_any__free,
++ GINT_TO_POINTER(1));
++
++ memset(retval, 0, sizeof(CORBA_any)); /* Make things easier on stubs */
++
++ return retval;
++}
++
++/*
++ * Compares the typecodes of each any
++ */
++CORBA_boolean ORBit_any_equivalent(CORBA_any obj, CORBA_any any, CORBA_Environment *ev)
++{
++ return(CORBA_FALSE);
++}
++
++/* This is needed by skels, that generate a __free function when they see
++ the TypeCode interface */
++gpointer
++CORBA_TypeCode__free(gpointer mem, gpointer func_data, CORBA_boolean free_strings)
++{
++ CORBA_Object_release(*(CORBA_Object *)mem, NULL);
++ return ((guchar *)mem) + sizeof(CORBA_TypeCode);
++}
++
++CORBA_char *CORBA_string_dup(const CORBA_char *string)
++{
++ if(!string)
++ return NULL;
++
++ return strcpy(ORBit_alloc(strlen(string)+1, NULL, NULL), string);
++}
++
++CORBA_char *CORBA_string_alloc(CORBA_unsigned_long len)
++{
++ return ORBit_alloc(len + 1, NULL, NULL);
++}
++
++CORBA_wchar *CORBA_wstring_alloc(CORBA_unsigned_long len)
++{
++ return ORBit_alloc(len + 1, NULL, NULL);
++}
++
++gpointer
++CORBA_string__free(gpointer str, gpointer dat, CORBA_boolean free_strings)
++{
++ if(free_strings)
++ CORBA_free(*((gpointer *)str));
++ return (gpointer)((guchar *)str + sizeof(CORBA_char *));
++}
++
++gpointer CORBA_Object__free(gpointer str, gpointer dat, CORBA_boolean free_strings)
++{
++ CORBA_Environment ev;
++ CORBA_exception_init(&ev);
++ CORBA_Object_release(*((gpointer *)str), &ev);
++ CORBA_exception_free(&ev);
++ return (gpointer)((guchar *)str + sizeof(CORBA_Object));
++}
++
++/* 19.14 */
++
++/* The big picture for fixeds.
++ We have to represent a number in memory.
++
++ 1 2 3 . 4 5 6 7
++
++ There are three pieces of information in a fixed:
++
++ - Number of significant digits. (_digits)
++
++ - The scale. The number of places the decimal point is to the right
++ of the first significant digit. (_scale)
++
++ - The digits themselves (_value)
++
++ */
++CORBA_long CORBA_fixed_integer_part(const void *fp)
++{
++ CORBA_long retval = 0;
++ int i, power_of_ten, digit;
++ const CORBA_fixed_d_s *val = fp;
++
++ g_return_val_if_fail(fp != NULL, INT_MIN);
++
++ for(i = 0; i < (val->_digits - val->_scale); i++) {
++ power_of_ten = val->_digits - i - val->_scale - 1;
++ digit = val->_value[i];
++ retval += digit * ((int)pow(10, power_of_ten));
++ }
++
++ return retval;
++}
++
++CORBA_long CORBA_fixed_fraction_part(const void *fp)
++{
++ CORBA_long retval = 0;
++ int i, power_of_ten, digit;
++ const CORBA_fixed_d_s *val = fp;
++
++ g_return_val_if_fail(fp != NULL, INT_MIN);
++
++ for(i = val->_digits - val->_scale; i < val->_digits; i++){
++ power_of_ten = val->_digits - i - 1;
++ digit = val->_value[i];
++ retval += digit * ((int)pow(10, power_of_ten));
++ }
++
++ return retval;
++}
++
++static inline
++CORBA_long do_div (CORBA_long *n)
++{
++ int __res;
++
++ __res = (*n) % (unsigned) 10;
++ *n = (*n) / (unsigned) 10;
++
++ return __res;
++}
++
++void CORBA_fixed_set(void *rp, CORBA_long i, CORBA_long f)
++{
++ CORBA_fixed_d_s *val = rp;
++ CORBA_long left_to_eat, cur;
++ signed char sign = 1;
++
++ g_return_if_fail(rp != NULL);
++
++ memset(val->_value, 0, val->_digits);
++
++ if(i) sign = i/abs(i);
++ val->_sign = sign;
++ i = abs(i);
++ f = abs(f);
++
++ for(cur = 0, left_to_eat = i;
++ left_to_eat != 0 && cur < val->_digits; cur++) {
++ val->_value[cur] = do_div(&left_to_eat) * sign;
++ sign = 1;
++ }
++
++ val->_scale = cur - 1;
++
++ for(left_to_eat = f;
++ left_to_eat != 0 && cur < val->_digits; cur++) {
++ val->_value[cur] = do_div(&left_to_eat);
++ }
++}
++
++void CORBA_fixed_add(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++void CORBA_fixed_sub(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++void CORBA_fixed_mul(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++void CORBA_fixed_div(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++CORBA_fixed_d_s *CORBA_fixed_alloc(CORBA_unsigned_short d)
++{
++ return (CORBA_fixed_d_s *)
++ g_malloc(sizeof(CORBA_fixed_d_s) + d + 1);
++}
++
++void CORBA_free(void *storage)
++{
++ ORBit_free(storage, CORBA_TRUE);
++}
++
++int ORBit_parse_unixsock(CORBA_Object obj,
++ char *sockpath,
++ gboolean existing_only)
++{
++ if(!sockpath || !*sockpath)
++ return -1;
++
++ obj->connection =
++ GIOP_CONNECTION(iiop_connection_unix_get(sockpath,
++ existing_only));
++
++ if(!obj->connection)
++ return -1;
++
++ giop_connection_ref(obj->connection);
++ return 0;
++}
++
++int ORBit_parse_inet(CORBA_Object obj, char *hostname, unsigned short port,
++ gboolean existing_only)
++{
++ obj->connection = GIOP_CONNECTION(iiop_connection_get(hostname, port, existing_only));
++
++ if(!obj->connection)
++ return -1;
++ giop_connection_ref(obj->connection);
++ return 0;
++}
++
++static const CORBA_unsigned_long zero_int = 0;
++struct iovec ORBit_default_principal_iovec = {(gpointer)&zero_int, sizeof(zero_int)};
++
++void ORBit_set_default_principal(CORBA_Principal *principal)
++{
++ gpointer t;
++
++ if((gpointer)ORBit_default_principal_iovec.iov_base != (gpointer)&zero_int)
++ g_free(ORBit_default_principal_iovec.iov_base);
++
++ ORBit_default_principal_iovec.iov_len = principal->_length
++ + sizeof(CORBA_unsigned_long);
++
++ t = ORBit_default_principal_iovec.iov_base =
++ g_malloc(ORBit_default_principal_iovec.iov_len);
++
++ memcpy(t, &principal->_length, sizeof(principal->_length));
++
++ t = ((guchar *)t) + sizeof(principal->_length);
++ memcpy(t, principal->_buffer, principal->_length);
++}
++
++CORBA_unsigned_long ORBit_class_assignment_counter = 0;
++GHashTable *ORBit_class_assignments = NULL;
++
++/* XXX not thread-safe */
++CORBA_unsigned_long
++ORBit_register_class(const PortableServer_ClassInfo *class_info)
++{
++ CORBA_unsigned_long retval;
++
++ if(!ORBit_class_assignments)
++ ORBit_class_assignments = g_hash_table_new(g_str_hash, g_str_equal);
++
++ /* This needs to be pre-increment - we don't want to give out
++ classid 0, because (a) that is reserved for the base Object class
++ (b) all the routines allocate a new id if the variable
++ storing their ID == 0 */
++ retval = ++ORBit_class_assignment_counter;
++
++ g_hash_table_insert(ORBit_class_assignments, (gpointer)class_info->class_name,
++ GINT_TO_POINTER(retval));
++
++ return retval;
++}
+diff -urN linux-2.4.1/net/korbit/orb/orbit.h linux-2.4.1-korbit/net/korbit/orb/orbit.h
+--- linux-2.4.1/net/korbit/orb/orbit.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,207 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/* these two blocks are outside of the main header for good reason...
++ People may include headers from many different stubs, and we want to
++ have the version checked on all of them.
++ */
++#ifndef ORBIT_SERIAL
++#define ORBIT_SERIAL 9
++#endif
++
++#ifdef ORBIT_IDL_SERIAL
++#if ORBIT_IDL_SERIAL < 9
++#error "You need to rerun 'orbit-idl' on the .idl file whose stubs you are using. These stubs were generated with an older version of ORBit, and need to be regenerated."
++#endif
++#endif
++
++#ifndef _ORBIT_H_
++#define _ORBIT_H_
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#include <glib.h>
++
++#define BACKWARDS_COMPAT_0_4
++#undef NOT_BACKWARDS_COMPAT_0_4
++
++#include <sys/types.h>
++#include <sys/uio.h>
++#include <IIOP/IIOP.h>
++#include <ORBitutil/util.h>
++#include <orb/orbit_config.h>
++#include <orb/orbit_types.h>
++#include <orb/allocators.h>
++#include <orb/cdr.h>
++#include <orb/dii.h>
++#ifndef __KORBIT__
++#include <orb/dynany.h>
++#endif
++#include <orb/env.h>
++#include <orb/iop.h>
++#include <orb/ir.h>
++#include <orb/options.h>
++#include <orb/orb.h>
++#include <orb/poa.h>
++#include <orb/sequences.h>
++#include <orb/orbit_typecode.h>
++#include <orb/typecode.h>
++
++#ifndef ORBIT_MAJOR_VERSION
++#define ORBIT_MAJOR_VERSION (0)
++#define ORBIT_MINOR_VERSION (5)
++#define ORBIT_MICRO_VERSION (3)
++#endif
++
++extern const guint orbit_major_version,
++ orbit_minor_version,
++ orbit_micro_version;
++extern const char orbit_version[];
++
++extern void CORBA_any_set_release(
++ CORBA_any *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_any_get_release(
++ CORBA_any *);
++
++extern void CORBA_sequence_set_release(
++ void *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_sequence_get_release(
++ void *);
++
++#define CORBA_any__alloc CORBA_any_alloc
++extern CORBA_any *CORBA_any_alloc(
++ void);
++
++extern gpointer CORBA_any__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++extern gpointer CORBA_TypeCode__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++
++extern CORBA_boolean ORBit_any_equivalent(
++ CORBA_any obj,
++ CORBA_any any,
++ CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_string_dup(const CORBA_char *string);
++extern CORBA_char *CORBA_string_alloc(CORBA_unsigned_long len);
++extern gpointer CORBA_string__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++gpointer CORBA_Object__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++extern CORBA_wchar *CORBA_wstring_alloc(CORBA_unsigned_long len);
++#define CORBA_wstring_free CORBA_string_free
++
++/* 19.14 */
++extern CORBA_long CORBA_fixed_integer_part(
++ const void *fp);
++
++extern CORBA_long CORBA_fixed_fraction_part(
++ const void *fp);
++
++extern void CORBA_fixed_set(
++ void *rp,
++ CORBA_long i,
++ CORBA_long f);
++
++extern void CORBA_fixed_add(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_sub(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_mul(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_div(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern CORBA_fixed_d_s *CORBA_fixed_alloc(
++ CORBA_unsigned_short d);
++
++extern void CORBA_free(
++ void *storage);
++
++extern int ORBit_parse_inet(
++ CORBA_Object obj,
++ char *hostname,
++ unsigned short port,
++ gboolean existing_only);
++
++extern int ORBit_parse_unixsock(CORBA_Object obj,
++ char *sockpath,
++ gboolean existing_only);
++
++/****
++ This function lets you use your own event loop, if you so wish.
++ Also see IIOP.h's IIOP{Add,Remove}ConnectionHandler function pointers,
++ which are app-settable (you should set them before CORBA_ORB_init,
++ if you want them to be useful)
++ ****/
++
++ /* needs to be called by your event loop when data comes in on one of the
++ GIOPConnection fd's */
++void ORBit_custom_run_setup(CORBA_ORB orb, CORBA_Environment *ev);
++ void ORBit_handle_incoming(GIOPConnection *connection);
++
++/* Returns CORBA_TRUE if the request is OK to proceed. */
++typedef enum {
++ ORBIT_MESSAGE_BAD,
++ ORBIT_MESSAGE_ALLOW,
++ ORBIT_MESSAGE_ALLOW_ALL /* Allow all subsequent messages on
++ this connection with no checking */
++} ORBit_MessageValidationResult;
++typedef ORBit_MessageValidationResult (*ORBit_request_validate)
++ (CORBA_unsigned_long request_id,
++ CORBA_Principal *principal,
++ CORBA_char *operation);
++void ORBit_set_request_validation_handler(ORBit_request_validate validator);
++
++extern struct iovec ORBit_default_principal_iovec;
++void ORBit_set_default_principal(CORBA_Principal *principal);
++
++extern CORBA_unsigned_long ORBit_class_assignment_counter;
++
++CORBA_unsigned_long ORBit_register_class(const PortableServer_ClassInfo *class_info);
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* !_ORBIT_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit.h.in linux-2.4.1-korbit/net/korbit/orb/orbit.h.in
+--- linux-2.4.1/net/korbit/orb/orbit.h.in Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit.h.in Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,205 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/* these two blocks are outside of the main header for good reason...
++ People may include headers from many different stubs, and we want to
++ have the version checked on all of them.
++ */
++#ifndef ORBIT_SERIAL
++#define ORBIT_SERIAL @ORBIT_SERIAL@
++#endif
++
++#ifdef ORBIT_IDL_SERIAL
++#if ORBIT_IDL_SERIAL < @ORBIT_SERIAL@
++#error "You need to rerun 'orbit-idl' on the .idl file whose stubs you are using. These stubs were generated with an older version of ORBit, and need to be regenerated."
++#endif
++#endif
++
++#ifndef _ORBIT_H_
++#define _ORBIT_H_
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#include <glib.h>
++
++#define BACKWARDS_COMPAT_0_4
++#undef NOT_BACKWARDS_COMPAT_0_4
++
++#include <sys/types.h>
++#include <sys/uio.h>
++#include <IIOP/IIOP.h>
++#include <ORBitutil/util.h>
++#include <orb/orbit_config.h>
++#include <orb/orbit_types.h>
++#include <orb/allocators.h>
++#include <orb/cdr.h>
++#include <orb/dii.h>
++#include <orb/dynany.h>
++#include <orb/env.h>
++#include <orb/iop.h>
++#include <orb/ir.h>
++#include <orb/options.h>
++#include <orb/orb.h>
++#include <orb/poa.h>
++#include <orb/sequences.h>
++#include <orb/orbit_typecode.h>
++#include <orb/typecode.h>
++
++#ifndef ORBIT_MAJOR_VERSION
++#define ORBIT_MAJOR_VERSION (@ORBIT_MAJOR_VERSION@)
++#define ORBIT_MINOR_VERSION (@ORBIT_MINOR_VERSION@)
++#define ORBIT_MICRO_VERSION (@ORBIT_MICRO_VERSION@)
++#endif
++
++extern const guint orbit_major_version,
++ orbit_minor_version,
++ orbit_micro_version;
++extern const char orbit_version[];
++
++extern void CORBA_any_set_release(
++ CORBA_any *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_any_get_release(
++ CORBA_any *);
++
++extern void CORBA_sequence_set_release(
++ void *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_sequence_get_release(
++ void *);
++
++#define CORBA_any__alloc CORBA_any_alloc
++extern CORBA_any *CORBA_any_alloc(
++ void);
++
++extern gpointer CORBA_any__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++extern gpointer CORBA_TypeCode__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++
++extern CORBA_boolean ORBit_any_equivalent(
++ CORBA_any obj,
++ CORBA_any any,
++ CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_string_dup(const CORBA_char *string);
++extern CORBA_char *CORBA_string_alloc(CORBA_unsigned_long len);
++extern gpointer CORBA_string__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++gpointer CORBA_Object__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++extern CORBA_wchar *CORBA_wstring_alloc(CORBA_unsigned_long len);
++#define CORBA_wstring_free CORBA_string_free
++
++/* 19.14 */
++extern CORBA_long CORBA_fixed_integer_part(
++ const void *fp);
++
++extern CORBA_long CORBA_fixed_fraction_part(
++ const void *fp);
++
++extern void CORBA_fixed_set(
++ void *rp,
++ CORBA_long i,
++ CORBA_long f);
++
++extern void CORBA_fixed_add(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_sub(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_mul(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_div(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern CORBA_fixed_d_s *CORBA_fixed_alloc(
++ CORBA_unsigned_short d);
++
++extern void CORBA_free(
++ void *storage);
++
++extern int ORBit_parse_inet(
++ CORBA_Object obj,
++ char *hostname,
++ unsigned short port,
++ gboolean existing_only);
++
++extern int ORBit_parse_unixsock(CORBA_Object obj,
++ char *sockpath,
++ gboolean existing_only);
++
++/****
++ This function lets you use your own event loop, if you so wish.
++ Also see IIOP.h's IIOP{Add,Remove}ConnectionHandler function pointers,
++ which are app-settable (you should set them before CORBA_ORB_init,
++ if you want them to be useful)
++ ****/
++
++ /* needs to be called by your event loop when data comes in on one of the
++ GIOPConnection fd's */
++void ORBit_custom_run_setup(CORBA_ORB orb, CORBA_Environment *ev);
++ void ORBit_handle_incoming(GIOPConnection *connection);
++
++/* Returns CORBA_TRUE if the request is OK to proceed. */
++typedef enum {
++ ORBIT_MESSAGE_BAD,
++ ORBIT_MESSAGE_ALLOW,
++ ORBIT_MESSAGE_ALLOW_ALL /* Allow all subsequent messages on
++ this connection with no checking */
++} ORBit_MessageValidationResult;
++typedef ORBit_MessageValidationResult (*ORBit_request_validate)
++ (CORBA_unsigned_long request_id,
++ CORBA_Principal *principal,
++ CORBA_char *operation);
++void ORBit_set_request_validation_handler(ORBit_request_validate validator);
++
++extern struct iovec ORBit_default_principal_iovec;
++void ORBit_set_default_principal(CORBA_Principal *principal);
++
++extern CORBA_unsigned_long ORBit_class_assignment_counter;
++
++CORBA_unsigned_long ORBit_register_class(const PortableServer_ClassInfo *class_info);
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* !_ORBIT_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_config.h linux-2.4.1-korbit/net/korbit/orb/orbit_config.h
+--- linux-2.4.1/net/korbit/orb/orbit_config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_config.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,9 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++#ifndef ORB_CONFIG_H
++#define ORB_CONFIG_H 1
++
++/* When creating a memory pool for a particular type, how many chunks
++ do we want to pre-allocated? */
++#define ORBIT_CHUNKS_PREALLOC 2
++
++#endif /* ORB_CONFIG_H */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_object.c linux-2.4.1-korbit/net/korbit/orb/orbit_object.c
+--- linux-2.4.1/net/korbit/orb/orbit_object.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_object.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,699 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/*
++ * ORBit specific CORBA_Object functions.
++ *
++ */
++
++#include <string.h>
++#include "config.h"
++#include "../IIOP/iiop-endianP.h"
++#include "orbit_object_type.h"
++#include "corba_object_type.h"
++#include "allocators.h"
++#include "iop.h"
++#include <IIOP/IIOP.h>
++
++static void ORBit_object_try_existing_connections(CORBA_Object obj);
++static void CORBA_Object_release_fn(CORBA_Object obj, CORBA_Environment *ev);
++
++static ORBit_RootObject_Interface CORBA_Object_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))CORBA_Object_release_fn,
++};
++
++void ORBit_pseudo_object_init(ORBit_PseudoObject obj,
++ ORBit_PseudoObject_type obj_type,
++ CORBA_Environment *ev)
++{
++ ORBIT_ROOT_OBJECT(obj)->is_pseudo_object = TRUE;
++ ORBIT_ROOT_OBJECT(obj)->refs = 0;
++ ORBIT_PSEUDO_OBJECT(obj)->pseudo_object_type = obj_type;
++}
++
++static const ORBit_RootObject_Interface CORBA_Policy__epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))CORBA_Policy_destroy
++};
++
++void ORBit_policy_object_init(CORBA_Policy obj,
++ CORBA_PolicyType obj_type,
++ CORBA_Environment *ev)
++{
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(obj),
++ ORBIT_PSEUDO_POLICY, ev);
++
++ obj->policy_type = obj_type;
++
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(obj),
++ (gpointer)&CORBA_Policy__epv,
++ ev);
++}
++
++void ORBit_object_reference_init(CORBA_Object obj, CORBA_Environment *ev)
++{
++ /* set the interface up */
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(obj),&CORBA_Object_epv,ev);
++ /* initialise the reference count */
++ ORBIT_ROOT_OBJECT(obj)->refs = 0;
++ ORBIT_ROOT_OBJECT(obj)->is_pseudo_object = FALSE;
++}
++
++CORBA_Object
++ORBit_CORBA_Object_new(CORBA_Environment *ev)
++{
++ CORBA_Object obj;
++ /* Create the object */
++ obj = ORBIT_CHUNK_ALLOC(CORBA_Object);
++ memset(obj, '\0', sizeof(struct CORBA_Object_struct));
++
++ ORBit_object_reference_init(obj, ev);
++
++ return obj;
++
++}
++
++void
++ORBit_set_object_key(ORBit_Object_info *info)
++{
++ g_assert(info);
++
++ g_assert(info->object_key._length);
++
++ info->object_key_data = g_malloc(sizeof(CORBA_unsigned_long) + info->object_key._length);
++ info->object_key_data->_length = info->object_key._length;
++ memcpy(info->object_key_data->_buffer, info->object_key._buffer, info->object_key._length);
++
++ info->object_key_vec.iov_base =
++ (gpointer)info->object_key_data;
++ info->object_key_vec.iov_len = sizeof(CORBA_unsigned_long) + info->object_key._length;
++}
++
++static void ORBit_free_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info=(ORBit_Object_info *)item;
++
++ g_assert(info);
++
++ g_free(info->object_key_data);
++ CORBA_free(info->object_key._buffer);
++
++ if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ g_free(info->tag.iopinfo.host);
++ } else if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ g_free(info->tag.orbitinfo.unix_sock_path);
++ } else {
++ g_warning("ORBit_free_profile asked to free type %d", info->profile_type);
++ }
++
++ g_free(info); /* Check its safe to free the item within a foreach func */
++}
++
++void ORBit_delete_profiles(GSList *profile_list)
++{
++ g_slist_foreach(profile_list, ORBit_free_profile, NULL);
++ g_slist_free(profile_list);
++}
++
++/* this function is wired up to the RootObject interface */
++void
++CORBA_Object_release_fn(CORBA_Object obj, CORBA_Environment *ev)
++{
++
++ g_assert(obj!=NULL);
++
++ ORBIT_ROOT_OBJECT_UNREF(obj);
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs <= 0) {
++ g_hash_table_remove(obj->orb->objrefs, obj);
++
++ if(obj->connection)
++ giop_connection_unref(obj->connection);
++
++ g_free(obj->object_id);
++ ORBit_delete_profiles(obj->profile_list);
++ ORBit_delete_profiles(obj->forward_locations);
++
++ ORBIT_CHUNK_FREE(CORBA_Object, obj);
++ }
++}
++
++
++/* Sets the interface member in the RootObject to the epv specified*/
++void
++ORBit_RootObject_set_interface(ORBit_RootObject obj,
++ ORBit_RootObject_Interface* epv,
++ CORBA_Environment *ev)
++{
++ g_assert(obj!=NULL);
++ g_assert(epv!=NULL);
++
++ obj->interface = epv;
++}
++
++#define GET_ATOM(x) G_STMT_START{ GIOP_RECV_BUFFER(recv_buffer)->decoder(&x, (GIOP_RECV_BUFFER(recv_buffer)->cur), sizeof(x)); \
++GIOP_RECV_BUFFER(recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(recv_buffer)->cur) + sizeof(x); \
++}G_STMT_END
++#define ALIGNFOR(x) recv_buffer->cur = ALIGN_ADDRESS(recv_buffer->cur, sizeof(x))
++
++CORBA_Object
++ORBit_create_object_with_info(GSList *profiles,
++ const CORBA_char *type_id,
++ CORBA_ORB orb,
++ CORBA_Environment *ev)
++{
++ CORBA_Object new;
++ struct CORBA_Object_struct refcheck;
++
++ if(!type_id || !*type_id) {
++ g_warning("Failing object creation because object has no type");
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ return CORBA_OBJECT_NIL;
++ }
++
++ if(g_slist_length(profiles) < 1) {
++ g_warning("Failing object creation because object has no profiles");
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ return CORBA_OBJECT_NIL;
++ }
++
++ /* XXX badhack :) */
++ refcheck.object_id = type_id;
++ refcheck.profile_list = profiles;
++
++ new = g_hash_table_lookup(orb->objrefs, &refcheck);
++ if(new) {
++ ORBit_delete_profiles(profiles);
++ return CORBA_Object_duplicate(new, ev);
++ }
++
++ new = ORBit_CORBA_Object_new(ev);
++ new->connection = NULL;
++ new->object_id = g_strdup(type_id);
++ new->orb = (CORBA_ORB)CORBA_Object_duplicate((CORBA_Object)orb, ev);
++ new->profile_list = profiles;
++ new->active_profile = NULL;
++
++ ORBit_object_try_existing_connections(new);
++
++ g_hash_table_insert(orb->objrefs, new, new);
++
++ return CORBA_Object_duplicate(new, ev);
++}
++
++static ORBit_Object_info *
++ORBit_demarshal_profile(GIOPRecvBuffer *recv_buffer, IOP_ProfileId profile_id)
++{
++ ORBit_Object_info *object_info;
++ CORBA_unsigned_long subpart_len;
++ CORBA_octet o;
++ CDR_Codec codec_d;
++ CDR_Codec *codec=&codec_d;
++
++ object_info = g_new0(ORBit_Object_info, 1);
++
++ switch(profile_id) {
++ case IOP_TAG_INTERNET_IOP:
++ GET_ATOM(subpart_len); /* The length of the embedded sequence */
++ CDR_codec_init_static(codec);
++ codec->buffer = recv_buffer->cur;
++ codec->release_buffer = CORBA_FALSE;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + subpart_len;
++
++ codec->readonly = CORBA_TRUE;
++ codec->host_endian = codec->data_endian = FLAG_ENDIANNESS;
++ codec->buf_len = subpart_len;
++
++ CDR_get_octet(codec, &o);
++ codec->data_endian = o;
++
++ object_info->profile_type = IOP_TAG_INTERNET_IOP;
++ CDR_get_octet(codec, &object_info->iiop_major);
++
++ if(object_info->iiop_major != 1)
++ goto error_exit;
++ /* XXX should we check for a specific minor version? */
++ CDR_get_octet(codec, &object_info->iiop_minor);
++
++ CDR_get_string(codec, &object_info->tag.iopinfo.host);
++
++ CDR_get_ushort(codec, &object_info->tag.iopinfo.port);
++
++ CDR_get_seq_begin(codec, &object_info->object_key._length);
++ object_info->object_key._buffer =
++ ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ CDR_buffer_gets(codec, object_info->object_key._buffer,
++ object_info->object_key._length);
++ object_info->object_key._maximum = object_info->object_key._release = 0;
++
++ ORBit_set_object_key(object_info);
++
++ return(object_info);
++ break;
++
++ case IOP_TAG_MULTIPLE_COMPONENTS:
++ default:
++ GET_ATOM(subpart_len);
++ g_warning("IOP_TAG_MULTIPLE_COMPONENTS decoding needs finishing");
++ object_info->profile_type = IOP_TAG_MULTIPLE_COMPONENTS;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + subpart_len;
++ return(object_info);
++ break;
++
++ case IOP_TAG_ORBIT_SPECIFIC:
++ GET_ATOM(subpart_len);
++ CDR_codec_init_static(codec);
++ codec->buffer = recv_buffer->cur;
++ codec->release_buffer = CORBA_FALSE;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + subpart_len;
++
++ codec->readonly = CORBA_TRUE;
++ codec->host_endian = codec->data_endian = FLAG_ENDIANNESS;
++ codec->buf_len = subpart_len;
++
++ CDR_get_octet(codec, &o);
++ codec->data_endian = o;
++
++ object_info->profile_type = IOP_TAG_ORBIT_SPECIFIC;
++ CDR_get_octet(codec, &object_info->iiop_major);
++
++ if(object_info->iiop_major != 1)
++ goto error_exit;
++ /* XXX should we check for a specific minor version? */
++ CDR_get_octet(codec, &object_info->iiop_minor);
++
++ CDR_get_string(codec, &object_info->tag.orbitinfo.unix_sock_path);
++ CDR_get_ushort(codec, &object_info->tag.orbitinfo.ipv6_port);
++
++ CDR_get_seq_begin(codec, &object_info->object_key._length);
++ object_info->object_key._buffer =
++ ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ CDR_buffer_gets(codec, object_info->object_key._buffer,
++ object_info->object_key._length);
++ object_info->object_key._maximum = object_info->object_key._release = 0;
++
++ ORBit_set_object_key(object_info);
++
++ return(object_info);
++ break;
++ }
++
++error_exit:
++ g_message("demarshal_profile(): IIOP major is %d",
++ object_info->iiop_major);
++ g_free(object_info);
++
++ return(NULL);
++}
++
++GSList *ORBit_demarshal_IOR(GIOPRecvBuffer *recv_buffer)
++{
++ GSList *profiles=NULL;
++ ORBit_Object_info *object_info;
++ CORBA_unsigned_long len, seq_len;
++ IOP_ProfileId profile_id;
++ int i;
++
++ /* Get type_id */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(len);
++
++ if(len == 0)
++ return(NULL);
++
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + len;
++
++ /* Decode the sequence<TaggedProfile> */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(seq_len);
++ for(i = 0; i < seq_len; i++) {
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(profile_id);
++ object_info=ORBit_demarshal_profile(recv_buffer, profile_id);
++ if(object_info==NULL) {
++ goto error_exit;
++ } else {
++ profiles=g_slist_append(profiles, object_info);
++ }
++ }
++
++ return(profiles);
++
++error_exit:
++ ORBit_delete_profiles(profiles);
++ return(NULL);
++}
++
++CORBA_Object
++ORBit_demarshal_object(GIOPRecvBuffer *recv_buffer, CORBA_ORB orb)
++{
++ GSList *profiles=NULL;
++ ORBit_Object_info *object_info;
++ CORBA_char *type_id;
++ CORBA_unsigned_long len, seq_len;
++ IOP_ProfileId profile_id;
++ int i;
++ CORBA_Environment ev;
++ CORBA_Object retval;
++
++ CORBA_exception_init(&ev);
++
++ /* Get type_id */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(len);
++
++ type_id = recv_buffer->cur;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + len;
++
++ /* Decode the sequence<TaggedProfile> */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(seq_len);
++
++ if(!seq_len)
++ return CORBA_OBJECT_NIL;
++
++ for(i = 0; i < seq_len; i++) {
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(profile_id);
++ object_info=ORBit_demarshal_profile(recv_buffer, profile_id);
++ if(object_info)
++ profiles=g_slist_append(profiles, object_info);
++ }
++
++ if(!profiles)
++ goto error_exit;
++
++ retval = ORBit_create_object_with_info(profiles, type_id, orb, &ev);
++
++ return retval;
++
++ error_exit:
++ ORBit_delete_profiles(profiles);
++
++ CORBA_exception_set_system(&ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ return CORBA_OBJECT_NIL;
++}
++
++static void ORBit_marshal_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ GIOPSendBuffer *send_buffer = (GIOPSendBuffer *)data;
++ static const CORBA_unsigned_long ioptag = IOP_TAG_INTERNET_IOP,
++ orbittag = IOP_TAG_ORBIT_SPECIFIC;
++ CDR_Codec codec_d;
++ CDR_Codec *codec = &codec_d;
++ CORBA_unsigned_long len;
++ CORBA_octet codecbuf[2048];
++ static const CORBA_octet oc_endian = FLAG_ENDIANNESS;
++ static const CORBA_octet iiopversion[] = {1,0};
++
++ g_assert(info);
++ g_assert(send_buffer);
++
++ if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ &ioptag, sizeof(ioptag));
++
++ CDR_codec_init_static(codec);
++ codec->buffer = codecbuf;
++ codec->buf_len = 2048;
++ codec->release_buffer = CORBA_FALSE;
++ codec->readonly = CORBA_FALSE;
++ codec->data_endian = codec->host_endian = FLAG_ENDIANNESS;
++ CDR_put_octet(codec, oc_endian);
++ CDR_put_octet(codec, iiopversion[0]);
++ CDR_put_octet(codec, iiopversion[1]);
++ CDR_put_string(codec, info->tag.iopinfo.host);
++ CDR_put_ushort(codec, info->tag.iopinfo.port);
++ CDR_put_ulong(codec, info->object_key._length);
++ CDR_put_octets(codec, info->object_key._buffer,
++ info->object_key._length);
++ len = codec->wptr;
++ giop_send_buffer_append_mem_indirect_a(send_buffer,
++ &len, sizeof(len));
++ giop_send_buffer_append_mem_indirect(send_buffer,
++ codec->buffer, codec->wptr);
++ } else if(info->profile_type==IOP_TAG_ORBIT_SPECIFIC) {
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer),
++ &orbittag, sizeof(orbittag));
++ CDR_codec_init_static(codec);
++ codec->buffer = codecbuf;
++ codec->release_buffer = CORBA_FALSE;
++ codec->buf_len = 2048;
++ codec->readonly = CORBA_FALSE;
++ codec->data_endian = codec->host_endian = FLAG_ENDIANNESS;
++ CDR_put_octet(codec, oc_endian);
++ CDR_put_octets(codec, (gpointer)iiopversion, sizeof(iiopversion));
++ CDR_put_string(codec, info->tag.orbitinfo.unix_sock_path);
++ CDR_put_ushort(codec, info->tag.orbitinfo.ipv6_port);
++ CDR_put_ulong(codec, info->object_key._length);
++ CDR_put_octets(codec, info->object_key._buffer,
++ info->object_key._length);
++ len = codec->wptr;
++ giop_send_buffer_append_mem_indirect_a(send_buffer,
++ &len, sizeof(len));
++ giop_send_buffer_append_mem_indirect(send_buffer,
++ codec->buffer, codec->wptr);
++ } else {
++ g_warning("ORBit_marshal_profile ask to marshal type %d\n", info->profile_type);
++ }
++}
++
++void
++ORBit_marshal_object(GIOPSendBuffer *send_buffer, CORBA_Object obj)
++{
++ CORBA_unsigned_long len;
++
++
++ if(!obj) {
++ static const CORBA_unsigned_long zero = 0, one = 1;
++ /* zero-length typename */
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer),
++ &one, sizeof(one));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ &zero, 1);
++
++ /* zero profiles */
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer),
++ &zero, sizeof(zero));
++ return;
++ }
++ g_return_if_fail(ORBIT_ROOT_OBJECT(obj)->refs > 0);
++
++ len = strlen(obj->object_id) + 1;
++ giop_send_buffer_append_mem_indirect_a(send_buffer, &len,
++ sizeof(len));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ obj->object_id, len);
++
++ len = g_slist_length(obj->profile_list);
++ giop_send_buffer_append_mem_indirect_a(GIOP_SEND_BUFFER(send_buffer),
++ &len, sizeof(len));
++
++ /* Marshal active first? */
++ g_slist_foreach(obj->profile_list, ORBit_marshal_profile, send_buffer);
++}
++
++static void ORBit_test_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ CORBA_Object obj = (CORBA_Object)data;
++
++ if(obj->active_profile != NULL)
++ return; /* we already have a good profile */
++
++ if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ if(!ORBit_parse_unixsock(obj, info->tag.orbitinfo.unix_sock_path, TRUE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ } else if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ if(!ORBit_parse_inet(obj, info->tag.iopinfo.host, info->tag.iopinfo.port, TRUE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ }
++}
++
++static void
++ORBit_object_try_existing_connections(CORBA_Object obj)
++{
++ g_slist_foreach(obj->profile_list, ORBit_test_profile, obj);
++}
++
++static void ORBit_activate_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ CORBA_Object obj = (CORBA_Object)data;
++
++ if(obj->active_profile != NULL)
++ return; /* we already have a good profile */
++
++ if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ if(!ORBit_parse_unixsock(obj, info->tag.orbitinfo.unix_sock_path, FALSE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ } else if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ if(!ORBit_parse_inet(obj, info->tag.iopinfo.host, info->tag.iopinfo.port, FALSE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ }
++}
++
++GIOPConnection *
++_ORBit_object_get_connection(CORBA_Object obj)
++{
++ g_return_val_if_fail(obj, NULL);
++
++ if (obj->connection) {
++ giop_connection_unref(obj->connection);
++ obj->connection = NULL;
++ obj->active_profile = NULL;
++ }
++
++ g_slist_foreach(obj->profile_list, ORBit_activate_profile, obj);
++
++ if(obj->active_profile == NULL || !obj->connection)
++ return NULL;
++
++ obj->connection->orb_data = obj->orb;
++
++ return obj->connection;
++}
++
++GIOPConnection *
++ORBit_object_get_forwarded_connection(CORBA_Object obj)
++{
++ g_return_val_if_fail(obj, NULL);
++
++ if (obj->connection) {
++ giop_connection_unref(obj->connection);
++ obj->connection = NULL;
++ obj->active_profile = NULL;
++ }
++
++ g_slist_foreach(obj->forward_locations, ORBit_activate_profile, obj);
++
++ if(obj->active_profile == NULL || !obj->connection)
++ return NULL;
++
++ obj->connection->orb_data = obj->orb;
++
++ return obj->connection;
++}
++
++/* This function is heavily based on the idl stubs output. Any changes there
++ will probably have to be reflected here also. */
++
++void ORBit_object_locate(CORBA_Object obj, CORBA_Environment *ev)
++{
++ GIOPConnection *cnx;
++ GIOPSendBuffer *send_buffer;
++ GIOPRecvBuffer *recv_buffer;
++ GIOP_unsigned_long request_id;
++
++ g_return_if_fail(obj!=NULL);
++ g_return_if_fail(ev!=NULL);
++
++ /* Send a LOCATE_REQUEST, wait for a LOCATE_REPLY. The reply will
++ either say "Object here", or will carry a new location. We set
++ obj->active_profile appropriately */
++
++ cnx=ORBit_object_get_connection(obj);
++ if((cnx==NULL) || (obj->active_profile==NULL)) {
++ CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);
++ return;
++ }
++ request_id=giop_get_request_id();
++ send_buffer=giop_send_locate_request_buffer_use(cnx, request_id, &(obj->active_profile->object_key_vec));
++ if(!send_buffer) {
++ CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);
++ return;
++ }
++
++ giop_send_buffer_write(send_buffer);
++ giop_send_buffer_unuse(send_buffer);
++
++ recv_buffer=giop_recv_locate_reply_buffer_use(request_id, TRUE);
++ if(recv_buffer==NULL || recv_buffer->message_buffer.message_header.message_type!=GIOP_LOCATEREPLY) {
++ CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_MAYBE);
++ if(recv_buffer)
++ giop_recv_buffer_unuse(recv_buffer);
++
++ return;
++ }
++
++ ev->_major=CORBA_NO_EXCEPTION;
++ switch(recv_buffer->message.u.locate_reply.locate_status) {
++ case GIOP_UNKNOWN_OBJECT:
++ CORBA_exception_set_system(ev, ex_CORBA_OBJECT_NOT_EXIST, CORBA_COMPLETED_NO);
++ break;
++
++ case GIOP_OBJECT_HERE:
++ /* No further processing necessary */
++ break;
++
++ case GIOP_OBJECT_FORWARD:
++ /* We've been forwarded onto somewhere else. The message body
++ contains the new IOR */
++ if(obj->forward_locations != NULL) {
++ ORBit_delete_profiles(obj->forward_locations);
++ }
++ obj->forward_locations=ORBit_demarshal_IOR(recv_buffer);
++
++ /* This will adjust obj->active_profile */
++ cnx=ORBit_object_get_forwarded_connection(obj);
++ break;
++
++ default:
++ g_message("Bad Reply in ORBit_locate_object()\n");
++ break;
++
++ }
++
++ giop_recv_buffer_unuse(recv_buffer);
++}
++
++GIOPConnection *
++ORBit_handle_location_forward(GIOPRecvBuffer *rb, CORBA_Object obj)
++{
++ GIOPConnection *retval;
++
++ if(obj->forward_locations)
++ ORBit_delete_profiles(obj->forward_locations);
++ obj->forward_locations = ORBit_demarshal_IOR(rb);
++
++ retval = ORBit_object_get_forwarded_connection(obj);
++ giop_recv_buffer_unuse(rb);
++
++ return retval;
++}
+diff -urN linux-2.4.1/net/korbit/orb/orbit_object.h linux-2.4.1-korbit/net/korbit/orb/orbit_object.h
+--- linux-2.4.1/net/korbit/orb/orbit_object.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_object.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,114 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ *
++ */
++
++/*
++ * ORBit specific CORBA_Object funcitons.
++ *
++ */
++#ifndef _ORBIT_ORBIT_OBJECT_H_
++#define _ORBIT_ORBIT_OBJECT_H_
++
++#include <IIOP/IIOP.h>
++#include "corba_object.h"
++
++extern CORBA_Object ORBit_CORBA_Object_new(CORBA_Environment *ev);
++extern void ORBit_CORBA_Object_free(CORBA_Object obj, CORBA_Environment *ev);
++
++
++typedef enum {
++ ORBIT_PSEUDO_ORB,
++ ORBIT_PSEUDO_POA,
++ ORBIT_PSEUDO_POAMANAGER,
++ ORBIT_PSEUDO_POLICY,
++ ORBIT_PSEUDO_TYPECODE,
++ ORBIT_PSEUDO_REQUEST,
++ ORBIT_PSEUDO_SERVERREQUEST,
++ ORBIT_PSEUDO_CONTEXT
++} ORBit_PseudoObject_type;
++typedef struct ORBit_PseudoObject_struct *ORBit_PseudoObject;
++
++void ORBit_pseudo_object_init(ORBit_PseudoObject obj,
++ ORBit_PseudoObject_type obj_type,
++ CORBA_Environment *ev);
++void ORBit_policy_object_init(CORBA_Policy obj,
++ CORBA_PolicyType obj_type,
++ CORBA_Environment *ev);
++
++/* Use ORBit_CORBA_Object_new() */
++void ORBit_object_reference_init(CORBA_Object obj, CORBA_Environment *ev);
++
++typedef struct {
++ CORBA_char *host;
++ CORBA_unsigned_short port;
++} TAG_INTERNET_IOP_info;
++
++typedef struct {
++ CORBA_char *unix_sock_path;
++ CORBA_unsigned_short ipv6_port;
++} TAG_ORBIT_SPECIFIC_info;
++
++typedef struct {
++ int fill_me_in;
++} TAG_MULTIPLE_COMPONENTS_info;
++
++typedef struct {
++ CORBA_octet iiop_major, iiop_minor;
++ IOP_ProfileId profile_type;
++ union {
++ TAG_INTERNET_IOP_info iopinfo;
++ TAG_ORBIT_SPECIFIC_info orbitinfo;
++ TAG_MULTIPLE_COMPONENTS_info mcinfo;
++ } tag;
++
++ /* If the object key is invariant wrt to the various profiles, then
++ this should probably go in CORBA_Object_struct
++ */
++ CORBA_sequence_octet object_key;
++ struct { CORBA_unsigned_long _length; char _buffer[1]; } *object_key_data;
++ struct iovec object_key_vec;
++} ORBit_Object_info;
++
++void ORBit_set_object_key(ORBit_Object_info *info);
++
++CORBA_Object ORBit_create_object_with_info(GSList *profiles,
++ const CORBA_char *type_id,
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++#define ORBit_object_get_connection(obj) \
++ ((obj)->connection && (obj)->connection->is_valid)?((obj)->connection):_ORBit_object_get_connection(obj)
++GIOPConnection *_ORBit_object_get_connection(CORBA_Object obj);
++GIOPConnection *ORBit_object_get_forwarded_connection(CORBA_Object obj);
++void ORBit_object_locate(CORBA_Object obj, CORBA_Environment *ev);
++
++void ORBit_marshal_object(GIOPSendBuffer *send_buffer, CORBA_Object obj);
++CORBA_Object ORBit_demarshal_object(GIOPRecvBuffer *recv_buffer,
++ CORBA_ORB orb);
++GSList *ORBit_demarshal_IOR(GIOPRecvBuffer *recv_buffer);
++
++extern void ORBit_delete_profiles(GSList *profile_list);
++GIOPConnection *ORBit_handle_location_forward(GIOPRecvBuffer *rb, CORBA_Object obj);
++
++#endif /* _ORBIT_ORBIT_OBJECT_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_object_type.h linux-2.4.1-korbit/net/korbit/orb/orbit_object_type.h
+--- linux-2.4.1/net/korbit/orb/orbit_object_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_object_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,87 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Philip Dawes
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#ifndef _ORBIT_ORBIT_OBJECT_TYPE_H_
++#define _ORBIT_ORBIT_OBJECT_TYPE_H_
++
++#include "orbit_object.h"
++
++
++/****** Root object **********/
++/*****************************/
++
++typedef struct ORBit_RootObject_Interface_struct ORBit_RootObject_Interface;
++struct ORBit_RootObject_Interface_struct
++{
++ void (*release)(gpointer obj, CORBA_Environment *ev);
++};
++
++
++
++#define ORBIT_ROOT_OBJECT(x) ((ORBit_RootObject)(x))
++
++
++typedef struct ORBit_RootObject_struct *ORBit_RootObject;
++struct ORBit_RootObject_struct {
++ ORBit_RootObject_Interface* interface; /* the interface */
++
++ guchar is_pseudo_object;
++ gint refs;
++};
++
++
++/* Reference counting interface */
++
++#define ORBIT_ROOT_OBJECT_REF(obj) (ORBIT_ROOT_OBJECT(obj)->refs++)
++#define ORBIT_ROOT_OBJECT_UNREF(obj) (ORBIT_ROOT_OBJECT(obj)->refs--)
++
++
++ /* Virtual function interface*/
++
++#define ORBIT_ROOT_OBJECT_release(obj,ev) \
++(ORBIT_ROOT_OBJECT(obj)->interface->release(obj,ev))
++
++
++
++extern void ORBit_RootObject_set_interface(ORBit_RootObject obj,
++ ORBit_RootObject_Interface* epv,
++ CORBA_Environment *ev);
++
++
++
++/****** Pseudo object --> RootObject ********/
++/*********************************************/
++
++#define ORBIT_PSEUDO_OBJECT(x) ((ORBit_PseudoObject)(x))
++
++struct ORBit_PseudoObject_struct {
++ struct ORBit_RootObject_struct parent;
++ ORBit_PseudoObject_type pseudo_object_type;
++};
++
++
++#endif /* !_ORBIT_CORBA_OBJECT_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_poa.c linux-2.4.1-korbit/net/korbit/orb/orbit_poa.c
+--- linux-2.4.1/net/korbit/orb/orbit_poa.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_poa.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,809 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/*
++ * ORBit specific POA funcitons.
++ *
++ */
++
++#include <string.h>
++#include "orbit.h"
++#include "orbit_poa_type.h"
++#include "orbit_poa.h"
++#include "genrand.h"
++
++#define POA_KEY_LEN (sizeof(CORBA_unsigned_long) + ORBIT_RAND_KEY_LEN)
++#define OBJ_KEY_LEN (sizeof(CORBA_unsigned_long) + ORBIT_RAND_KEY_LEN)
++
++static void ORBit_POAManager_release(PortableServer_POAManager poa_mgr,
++ CORBA_Environment *ev);
++
++static void ORBit_POA_release(PortableServer_POA poa,
++ CORBA_Environment *ev);
++
++static PortableServer_Servant
++ORBit_POA_ServantManager_use_servant(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie *the_cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev);
++static void
++ORBit_POA_ServantManager_unuse_servant(PortableServer_Servant servant,
++ PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev);
++
++static const ORBit_RootObject_Interface CORBA_POAManager_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_POAManager_release,
++};
++
++static const ORBit_RootObject_Interface CORBA_POA_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_POA_release,
++};
++
++guint
++g_sequence_octet_hash(CORBA_sequence_octet *so)
++{
++ const char *s = (char*)so->_buffer;
++ const char *p, *e = ((char *)so->_buffer) + so->_length;
++ guint h=0, g;
++
++ for(p = s; p < e; p ++) {
++ h = ( h << 4 ) + *p;
++ if ( ( g = h & 0xf0000000 ) ) {
++ h = h ^ (g >> 24);
++ h = h ^ g;
++ }
++ }
++
++ return h;
++}
++
++gint
++g_sequence_octet_compare(CORBA_sequence_octet *s1, CORBA_sequence_octet *s2)
++{
++ if(s2->_length != s1->_length)
++ return FALSE;
++
++ return !memcmp(s1->_buffer, s2->_buffer, s1->_length);
++}
++
++PortableServer_POAManager
++ORBit_POAManager_new(CORBA_Environment *ev)
++{
++ PortableServer_POAManager poa_mgr;
++
++ poa_mgr = g_new0(struct PortableServer_POAManager_type, 1);
++
++ if(poa_mgr == NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ /* Initialise poa manager */
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(poa_mgr),
++ ORBIT_PSEUDO_POAMANAGER, ev);
++ ORBIT_ROOT_OBJECT(poa_mgr)->refs = 0;
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(poa_mgr),
++ (gpointer)&CORBA_POAManager_epv, ev);
++
++ poa_mgr->poa_collection = NULL;
++ poa_mgr->state = PortableServer_POAManager_HOLDING;
++
++ return poa_mgr;
++
++error:
++ if(poa_mgr != NULL){
++ ORBit_POAManager_release(poa_mgr, ev);
++ }
++ return NULL;
++}
++
++static void
++ORBit_POAManager_release(PortableServer_POAManager poa_mgr,
++ CORBA_Environment *ev)
++{
++
++ if(--(ORBIT_ROOT_OBJECT(poa_mgr)->refs) > 0)
++ return;
++
++ if(poa_mgr != NULL) {
++ if(poa_mgr->poa_collection != NULL) {
++ g_slist_free(poa_mgr->poa_collection);
++ poa_mgr->poa_collection = NULL;
++ }
++ g_free(poa_mgr);
++ poa_mgr = NULL;
++ }
++}
++
++static void
++ORBit_POAManager_register_poa(PortableServer_POAManager poa_mgr,
++ PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ poa_mgr->poa_collection = g_slist_remove(poa_mgr->poa_collection, poa);
++ poa_mgr->poa_collection =
++ g_slist_append(poa_mgr->poa_collection, poa);
++}
++
++static void
++ORBit_POAManager_unregister_poa(PortableServer_POAManager poa_mgr,
++ PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ poa_mgr->poa_collection = g_slist_remove(poa_mgr->poa_collection, poa);
++}
++
++static void
++ORBit_POA_set_policy(PortableServer_POA poa,
++ CORBA_Policy policy,
++ CORBA_Environment *ev)
++{
++ switch(policy->policy_type) {
++ case PortableServer_THREAD_POLICY_ID:
++ poa->thread = ((PortableServer_ThreadPolicy)policy)->value;
++ break;
++ case PortableServer_LIFESPAN_POLICY_ID:
++ poa->lifespan = ((PortableServer_LifespanPolicy)policy)->value;
++ break;
++ case PortableServer_ID_UNIQUENESS_POLICY_ID:
++ poa->id_uniqueness = ((PortableServer_IdUniquenessPolicy)policy)->value;
++ break;
++ case PortableServer_ID_ASSIGNMENT_POLICY_ID:
++ poa->id_assignment = ((PortableServer_IdAssignmentPolicy)policy)->value;
++ break;
++ case PortableServer_IMPLICIT_ACTIVATION_POLICY_ID:
++ poa->implicit_activation = ((PortableServer_ImplicitActivationPolicy)policy)->value;
++ break;
++ case PortableServer_SERVANT_RETENTION_POLICY_ID:
++ poa->servant_retention = ((PortableServer_ServantRetentionPolicy)policy)->value;
++ break;
++ case PortableServer_REQUEST_PROCESSING_POLICY_ID:
++ poa->request_processing = ((PortableServer_ServantRetentionPolicy)policy)->value;
++ break;
++ default:
++ g_warning("Unknown policy type, cannot set it on this POA");
++ }
++}
++
++
++static void
++ORBit_POA_check_policy_conflicts(PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++
++ /* Check for those policy combinations that aren't allowed */
++ if ((poa->servant_retention == PortableServer_NON_RETAIN &&
++ poa->request_processing == PortableServer_USE_ACTIVE_OBJECT_MAP_ONLY) ||
++
++ (poa->request_processing == PortableServer_USE_DEFAULT_SERVANT &&
++ poa->id_uniqueness == PortableServer_UNIQUE_ID) ||
++
++ (poa->implicit_activation == PortableServer_IMPLICIT_ACTIVATION &&
++ (poa->id_assignment == PortableServer_USER_ID ||
++ poa->servant_retention == PortableServer_NON_RETAIN))
++ )
++ {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_InvalidPolicy,
++ NULL);
++ }
++}
++
++
++static void
++ORBit_POA_set_policylist(PortableServer_POA poa,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev)
++{
++ CORBA_unsigned_long i;
++
++ for(i = 0; i < policies->_length; i++) {
++ if(ev->_major != CORBA_NO_EXCEPTION)
++ break;
++ ORBit_POA_set_policy(poa, policies->_buffer[i], ev);
++ }
++}
++
++PortableServer_POA
++ORBit_POA_new(CORBA_ORB orb,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager the_POAManager,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev)
++{
++ PortableServer_POA poa;
++
++ /* Create the object */
++ poa = (PortableServer_POA) g_new0(struct PortableServer_POA_type, 1);
++ if(poa == NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(poa), ORBIT_PSEUDO_POA, ev);
++
++ ORBIT_ROOT_OBJECT(poa)->refs = 0;
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(poa),
++ (gpointer)&CORBA_POA_epv, ev);
++
++ if(ev->_major != CORBA_NO_EXCEPTION) goto error;
++
++ /* If no POAManager was specified, create one */
++ if(the_POAManager == NULL) {
++ the_POAManager = ORBit_POAManager_new(ev);
++ }
++
++ /* Register this poa with the poa manager */
++ if(the_POAManager != NULL)
++ ORBit_POAManager_register_poa(the_POAManager,poa,ev);
++ if(ev->_major != CORBA_NO_EXCEPTION) goto error;
++
++ /* Wire up the poa_manager */
++ poa->the_POAManager = the_POAManager;
++
++ /* Initialise the child poas table */
++ poa->child_POAs = NULL; /* initialise the slist */
++
++ poa->held_requests = NULL;
++
++ poa->poaID = orb->poas->len;
++ g_ptr_array_set_size(orb->poas, orb->poas->len + 1);
++ g_ptr_array_index(orb->poas, poa->poaID) = poa;
++
++ poa->orb = orb;
++
++ g_return_val_if_fail(ev->_major == CORBA_NO_EXCEPTION, NULL);
++
++ /* Need to initialise poa policies etc.. here */
++ poa->thread = PortableServer_ORB_CTRL_MODEL;
++ poa->lifespan = PortableServer_TRANSIENT;
++ poa->id_uniqueness = PortableServer_UNIQUE_ID;
++ poa->id_assignment = PortableServer_SYSTEM_ID;
++ poa->servant_retention = PortableServer_RETAIN;
++ poa->request_processing = PortableServer_USE_ACTIVE_OBJECT_MAP_ONLY;
++ poa->implicit_activation = PortableServer_NO_IMPLICIT_ACTIVATION;
++ if (policies) {
++ ORBit_POA_set_policylist(poa, policies, ev);
++ ORBit_POA_check_policy_conflicts(poa, ev);
++ if(ev->_major != CORBA_NO_EXCEPTION) goto error;
++ }
++
++ /* copy the name */
++ poa->the_name = CORBA_string_dup(adapter_name);
++
++ poa->active_object_map = g_hash_table_new((GHashFunc)g_sequence_octet_hash,
++ (GCompareFunc)g_sequence_octet_compare);
++ poa->objnum_to_obj = g_ptr_array_new();
++ g_ptr_array_set_size(poa->objnum_to_obj, 1);
++ g_ptr_array_index(poa->objnum_to_obj, 0) = NULL;
++
++ orbit_genrand(poa->rand_data, ORBIT_RAND_KEY_LEN);
++
++ return poa;
++
++error:
++ if(poa && poa->the_name){
++ CORBA_free(poa->the_name);
++ }
++
++ if(poa != NULL){
++ ORBit_POA_release(poa, NULL);
++ }
++ return NULL;
++}
++
++static void
++ORBit_POA_release(PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ ORBIT_ROOT_OBJECT_UNREF(poa);
++
++ if(ORBIT_ROOT_OBJECT(poa)->refs <= 0) {
++ CORBA_free(poa->the_name);
++
++ g_slist_foreach(poa->child_POAs, (GFunc)CORBA_Object_release,
++ ev);
++
++ if(poa->parent_poa)
++ ORBit_POA_remove_child(poa->parent_poa, poa, ev);
++
++ ORBit_POAManager_unregister_poa(poa->the_POAManager,
++ poa, ev);
++
++ g_ptr_array_index(poa->orb->poas, poa->poaID) = NULL;
++
++ g_free(poa);
++ }
++}
++
++void
++ORBit_POA_add_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev)
++
++{
++ g_return_if_fail(poa != NULL);
++ g_return_if_fail(child_poa != NULL);
++
++ poa->child_POAs = g_slist_prepend(poa->child_POAs, child_poa);
++}
++
++void
++ORBit_POA_remove_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev)
++{
++ g_return_if_fail(poa != NULL);
++ g_return_if_fail(child_poa != NULL);
++
++ poa->child_POAs = g_slist_remove(poa->child_POAs, child_poa);
++}
++
++extern ORBit_request_validate ORBIT_request_validator;
++
++gboolean
++ORBit_POA_handle_request(GIOPRecvBuffer *recv_buffer,
++ PortableServer_POA poa)
++{
++ PortableServer_ServantBase *servant;
++ PortableServer_ServantLocator_Cookie cookie;
++ ORBit_POAObject *obj_impl = NULL, tmp_obj_impl;
++ ORBitSkeleton skel;
++ gpointer imp = NULL;
++ CORBA_Environment ev;
++ GIOPSendBuffer *send_buffer;
++ guchar *opname;
++ PortableServer_ObjectId *oid = NULL;
++
++ CORBA_exception_init(&ev);
++
++ switch(poa->the_POAManager->state) {
++ case PortableServer_POAManager_HOLDING:
++ poa->held_requests = g_slist_prepend(poa->held_requests,
++ recv_buffer);
++ return FALSE;
++ break;
++ case PortableServer_POAManager_DISCARDING:
++ send_buffer = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(recv_buffer)->connection,
++ NULL,
++ recv_buffer->message.u.request.request_id,
++ CORBA_SYSTEM_EXCEPTION);
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_TRANSIENT,
++ CORBA_COMPLETED_NO);
++ ORBit_send_system_exception(send_buffer, &ev);
++ giop_send_buffer_write(send_buffer);
++ giop_recv_buffer_unuse(recv_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ CORBA_exception_free(&ev);
++ return TRUE;
++ break;
++ case PortableServer_POAManager_INACTIVE:
++ send_buffer = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(recv_buffer)->connection,
++ NULL,
++ recv_buffer->message.u.request.request_id,
++ CORBA_SYSTEM_EXCEPTION);
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJ_ADAPTER,
++ CORBA_COMPLETED_NO);
++ ORBit_send_system_exception(send_buffer, &ev);
++ giop_send_buffer_write(send_buffer);
++ giop_recv_buffer_unuse(recv_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ CORBA_exception_free(&ev);
++ return TRUE;
++ break;
++ case PortableServer_POAManager_ACTIVE:
++ default:
++ break;
++ }
++
++ servant = NULL;
++
++ if(recv_buffer->message.u.request.object_key._length
++ < (POA_KEY_LEN + sizeof(CORBA_unsigned_long))) {
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJECT_NOT_EXIST,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++
++ obj_impl = ORBit_POA_find_oid_for_object_key(poa, &(recv_buffer->message.u.request.object_key), &oid);
++
++ if(poa->servant_retention == PortableServer_RETAIN
++ && obj_impl) {
++ servant = obj_impl->servant;
++ oid = obj_impl->object_id;
++ }
++
++ if(!servant) {
++ switch(poa->request_processing) {
++ case PortableServer_USE_SERVANT_MANAGER:
++ servant = ORBit_POA_ServantManager_use_servant(poa,
++ recv_buffer,
++ &cookie,
++ oid,
++ &tmp_obj_impl,
++ &ev);
++ break;
++ case PortableServer_USE_DEFAULT_SERVANT:
++ servant = poa->default_servant;
++ if(servant == NULL) {
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJ_ADAPTER,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++ break;
++ default:
++ break;
++ }
++ }
++
++ if(!poa || !servant || !servant->_private) {
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJECT_NOT_EXIST,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++
++ opname = recv_buffer->message.u.request.operation;
++
++ skel = ORBIT_OBJECT_KEY(servant->_private)->class_info->relay_call(servant, recv_buffer, &imp);
++
++ if(!skel) {
++ if (opname[0] == '_' && strcmp(opname + 1, "is_a") == 0) {
++ skel = (gpointer)&ORBit_impl_CORBA_Object_is_a;
++ }
++ else {
++ CORBA_exception_set_system(&ev, ex_CORBA_BAD_OPERATION,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++ }
++ else if (!imp) {
++ CORBA_exception_set_system(&ev, ex_CORBA_NO_IMPLEMENT,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++
++ /* If it got through the random keys, and nobody else had the opportunity to say otherwise, it must be auth'd */
++
++ if(!ORBIT_request_validator)
++ GIOP_MESSAGE_BUFFER(recv_buffer)->connection->is_auth = TRUE;
++
++ skel(servant, recv_buffer, &ev, imp);
++
++ if(poa->request_processing == PortableServer_USE_SERVANT_MANAGER) {
++ ORBit_POA_ServantManager_unuse_servant(servant,
++ poa,
++ recv_buffer,
++ cookie, oid,
++ &tmp_obj_impl,
++ &ev);
++ }
++
++ if(!obj_impl)
++ CORBA_free(oid);
++
++ CORBA_exception_free(&ev);
++
++ return TRUE;
++
++ errout:
++ if(ev._major == CORBA_SYSTEM_EXCEPTION) {
++ GIOPSendBuffer *reply_buf;
++
++ reply_buf =
++ giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(recv_buffer)->connection,
++ NULL,
++ recv_buffer->message.u.request.request_id,
++ CORBA_SYSTEM_EXCEPTION);
++
++ ORBit_send_system_exception(reply_buf, &ev);
++
++ giop_send_buffer_write(reply_buf);
++ giop_send_buffer_unuse(reply_buf);
++ } else /* User exceptions are handled in the skels! */
++ g_assert(ev._major == CORBA_NO_EXCEPTION);
++
++ if(!obj_impl)
++ CORBA_free(oid);
++
++ CORBA_exception_free(&ev);
++
++ return TRUE;
++}
++
++PortableServer_POA
++ORBit_POA_find_POA_for_object_key(PortableServer_POA root_poa,
++ CORBA_sequence_octet *key)
++{
++ CORBA_unsigned_long pid;
++
++ if(key->_length < (sizeof(CORBA_unsigned_long) + ORBIT_RAND_KEY_LEN))
++ return NULL;
++
++ pid = *((CORBA_unsigned_long *)key->_buffer);
++
++ if(pid < root_poa->orb->poas->len) {
++ PortableServer_POA poa;
++ poa = g_ptr_array_index(root_poa->orb->poas, pid);
++ if(!poa)
++ return NULL;
++ if(memcmp(poa->rand_data, key->_buffer + sizeof(CORBA_unsigned_long), ORBIT_RAND_KEY_LEN))
++ return NULL;
++ return poa;
++ } else
++ return NULL;
++}
++
++void
++ORBit_POA_find_object_key_for_oid(PortableServer_POA poa,
++ ORBit_POAObject *obj,
++ PortableServer_ObjectId *oid,
++ CORBA_sequence_octet *retval)
++{
++ CORBA_long *vptr;
++
++ g_return_if_fail(poa && (obj || oid));
++ g_return_if_fail(retval);
++
++ if(oid)
++ g_assert(!oid->_buffer[oid->_length - 1]);
++
++ if(obj)
++ retval->_length = POA_KEY_LEN + OBJ_KEY_LEN;
++ else
++ retval->_length = POA_KEY_LEN + sizeof(CORBA_long) + oid->_length;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++ CORBA_sequence_set_release(retval, CORBA_TRUE);
++
++ vptr = (CORBA_long *)retval->_buffer;
++ *vptr = poa->poaID;
++ memcpy(retval->_buffer + sizeof(CORBA_unsigned_long), poa->rand_data, ORBIT_RAND_KEY_LEN);
++
++ vptr = (CORBA_long *)(retval->_buffer + POA_KEY_LEN);
++ if(obj) {
++ *vptr = obj->objnum;
++ memcpy(retval->_buffer + POA_KEY_LEN + sizeof(CORBA_unsigned_long), obj->rand_data, ORBIT_RAND_KEY_LEN);
++ } else {
++ *vptr = -((CORBA_long)oid->_length);
++ memcpy(retval->_buffer + POA_KEY_LEN + sizeof(CORBA_unsigned_long), oid->_buffer, oid->_length);
++ }
++}
++
++ORBit_POAObject *
++ORBit_POA_find_oid_for_object_key(PortableServer_POA poa,
++ CORBA_sequence_octet *object_key,
++ PortableServer_ObjectId **oid)
++{
++ CORBA_long onum;
++ guchar *nptr;
++ ORBit_POAObject *objinfo;
++
++ *oid = NULL;
++ nptr = object_key->_buffer + POA_KEY_LEN;
++
++ if(object_key->_length < (POA_KEY_LEN + sizeof(CORBA_long))) {
++ return NULL;
++ }
++
++ onum = *((CORBA_long *)nptr);
++
++ if(onum < 0) {
++ /* onum will be the -strlen(ObjectId) */
++ if(object_key->_length < (POA_KEY_LEN + sizeof(CORBA_long) - onum))
++ return NULL;
++
++ *oid = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ (*oid)->_length = -onum;
++ (*oid)->_buffer = CORBA_octet_allocbuf((*oid)->_length);
++ memcpy((*oid)->_buffer, object_key->_buffer + POA_KEY_LEN + sizeof(CORBA_long), (*oid)->_length);
++
++ return NULL;
++ }
++
++ if(onum >= poa->objnum_to_obj->len)
++ return NULL;
++
++ objinfo = g_ptr_array_index(poa->objnum_to_obj, onum);
++
++ if(GPOINTER_TO_UINT(objinfo) <= poa->objnum_to_obj->len)
++ return NULL;
++
++ if(object_key->_length < (POA_KEY_LEN + OBJ_KEY_LEN))
++ return NULL;
++
++ if(memcmp(object_key->_buffer + POA_KEY_LEN + sizeof(CORBA_long), objinfo->rand_data, ORBIT_RAND_KEY_LEN))
++ return NULL;
++
++ return objinfo;
++}
++
++DEFINE_LOCK(id_assignment_counter);
++static int id_assignment_counter = 0;
++
++PortableServer_ObjectId *
++ORBit_POA_allocate_oid(PortableServer_POA poa,
++ const char *basis)
++{
++ PortableServer_ObjectId *new_objid;
++ char buf[512];
++ int len;
++
++ new_objid = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++
++ GET_LOCK(id_assignment_counter);
++ g_snprintf(buf, sizeof(buf), "%s%d", basis?basis:"Object",
++ id_assignment_counter);
++ id_assignment_counter++;
++ RELEASE_LOCK(id_assignment_counter);
++
++ len = strlen(buf)+1;
++ new_objid->_buffer = CORBA_octet_allocbuf(len);
++ new_objid->_length = len;
++ new_objid->_maximum = len;
++ new_objid->_release = CORBA_TRUE;
++
++ strcpy((CORBA_char *)new_objid->_buffer, buf);
++
++ return new_objid;
++}
++
++static PortableServer_Servant
++ORBit_POA_ServantManager_use_servant(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie *the_cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev)
++{
++ if(poa->servant_retention == PortableServer_RETAIN) {
++ POA_PortableServer_ServantActivator *sm;
++ POA_PortableServer_ServantActivator__epv *epv;
++
++ sm = (POA_PortableServer_ServantActivator *)poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantActivator_epv;
++ return epv->incarnate(sm, oid, poa, ev);
++ } else {
++ POA_PortableServer_ServantLocator *sm;
++ POA_PortableServer_ServantLocator__epv *epv;
++ PortableServer_ServantBase *retval;
++
++ sm = (POA_PortableServer_ServantLocator *)poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantLocator_epv;
++ retval = epv->preinvoke(sm, oid,
++ poa, recv_buffer->message.u.request.operation,
++ the_cookie,
++ ev);
++
++ ((ORBit_ObjectKey *)retval->_private)->object = fake_obj_impl;
++ fake_obj_impl->object_id = oid;
++ fake_obj_impl->poa = poa;
++ fake_obj_impl->orb = poa->orb;
++ fake_obj_impl->objnum = -1;
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++ fake_obj_impl->use_count = NULL;
++ fake_obj_impl->death_callback = NULL;
++#endif
++
++ return retval;
++ }
++}
++
++static void
++ORBit_POA_ServantManager_unuse_servant(PortableServer_Servant servant,
++ PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev)
++{
++ POA_PortableServer_ServantLocator *sm;
++ POA_PortableServer_ServantLocator__epv *epv;
++
++ if(poa->servant_retention != PortableServer_NON_RETAIN)
++ return;
++
++ sm = (POA_PortableServer_ServantLocator *)poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantLocator_epv;
++
++ ((ORBit_ObjectKey *)((PortableServer_ServantBase *)servant)->_private)->object = NULL;
++ epv->postinvoke(sm, oid,
++ poa, recv_buffer->message.u.request.operation,
++ cookie, servant, ev);
++
++}
++
++typedef struct {
++ PortableServer_POA poa;
++ CORBA_Environment *ev;
++} EtherealizeInfo;
++
++void
++ORBit_POA_etherealize_object(PortableServer_ObjectId *oid,
++ ORBit_POAObject *obj_impl,
++ EtherealizeInfo *ei)
++{
++ POA_PortableServer_ServantActivator__epv *epv;
++ POA_PortableServer_ServantActivator *sm;
++
++ g_assert(ei->poa->servant_manager);
++
++ g_hash_table_remove(ei->poa->active_object_map,
++ obj_impl->object_id);
++
++ sm = (POA_PortableServer_ServantActivator *)ei->poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantActivator_epv;
++ epv->etherealize(sm, obj_impl->object_id, ei->poa,
++ obj_impl->servant,
++ CORBA_TRUE, CORBA_FALSE, ei->ev);
++}
++
++void
++ORBit_POA_etherealize_objects(PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ EtherealizeInfo ei;
++
++ ei.poa = poa;
++ ei.ev = ev;
++
++ if(poa->servant_retention == PortableServer_RETAIN
++ && poa->request_processing == PortableServer_USE_SERVANT_MANAGER) {
++
++ g_hash_table_foreach(poa->active_object_map,
++ (GHFunc)ORBit_POA_etherealize_object,
++ &ei);
++ }
++}
++
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++void ORBit_servant_set_deathwatch(PortableServer_ServantBase *servant,
++ int *use_count,
++ GFunc death_func,
++ gpointer user_data)
++{
++ ORBit_POAObject *pobj;
++
++ pobj = ORBIT_OBJECT_KEY(servant->_private)->object;
++
++ pobj->use_count = use_count;
++ pobj->death_callback = death_func;
++ pobj->user_data = user_data;
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/orbit_poa.h linux-2.4.1-korbit/net/korbit/orb/orbit_poa.h
+--- linux-2.4.1/net/korbit/orb/orbit_poa.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_poa.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,89 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ *
++ */
++
++/*
++ * ORBit specific POA funcitons.
++ *
++ */
++
++#ifndef _ORBIT_ORBIT_POA_H_
++#define _ORBIT_ORBIT_POA_H_
++
++#include "orbit_types.h"
++#include "orbit_poa_type.h"
++
++/*
++ * Creates a new POAManager
++ */
++
++extern PortableServer_POAManager ORBit_POAManager_new(CORBA_Environment *ev);
++
++extern void ORBit_POAManager_free(PortableServer_POAManager poa_mgr,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA ORBit_POA_new(CORBA_ORB orb,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager the_POAManager,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev);
++
++extern void ORBit_POA_free(PortableServer_POA poa, CORBA_Environment *ev);
++
++extern void ORBit_POA_add_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev);
++void ORBit_POA_remove_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev);
++
++gboolean ORBit_POA_handle_request(GIOPRecvBuffer *recv_buffer,
++ PortableServer_POA poa);
++PortableServer_POA
++ORBit_POA_find_POA_for_object_key(PortableServer_POA root_poa,
++ CORBA_sequence_octet *key);
++void
++ORBit_POA_find_object_key_for_oid(PortableServer_POA poa,
++ ORBit_POAObject *obj,
++ PortableServer_ObjectId *oid,
++ CORBA_sequence_octet *retval);
++ORBit_POAObject *
++ORBit_POA_find_oid_for_object_key(PortableServer_POA poa,
++ CORBA_sequence_octet *object_key,
++ PortableServer_ObjectId **oid);
++
++PortableServer_ObjectId *ORBit_POA_allocate_oid(PortableServer_POA poa,
++ const char *basis);
++
++void ORBit_POA_etherealize_objects(PortableServer_POA poa, CORBA_Environment *ev);
++
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++/* Bad hack for shared libraries */
++void ORBit_servant_set_deathwatch(PortableServer_ServantBase *servant,
++ int *use_count,
++ GFunc death_func,
++ gpointer user_data);
++#endif
++
++#endif /* !_ORBIT_ORBIT_POA_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_poa_type.h linux-2.4.1-korbit/net/korbit/orb/orbit_poa_type.h
+--- linux-2.4.1/net/korbit/orb/orbit_poa_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_poa_type.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,112 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ *
++ */
++
++/*
++ * ORBit specific POA funcitons.
++ *
++ */
++
++#ifndef _ORBIT_ORBIT_POA_TYPE_H_
++#define _ORBIT_ORBIT_POA_TYPE_H_
++
++typedef void (*ORBitSkeleton)(PortableServer_ServantBase *_ORBIT_servant,
++ gpointer _ORBIT_recv_buffer,
++ CORBA_Environment *ev,
++ gpointer implementation);
++typedef ORBitSkeleton (*ORBit_impl_finder)(PortableServer_ServantBase *servant,
++ gpointer _ORBIT_recv_buffer,
++ gpointer *implementation);
++typedef void (*ORBit_local_objref_init)(CORBA_Object obj,
++ PortableServer_ServantBase *servant);
++typedef struct {
++ ORBit_impl_finder relay_call;
++ const gchar *class_name;
++ ORBit_local_objref_init init_local_objref;
++} PortableServer_ClassInfo;
++
++#define ORBIT_RAND_KEY_LEN 8
++
++typedef struct {
++ PortableServer_ObjectId *object_id;
++ PortableServer_Servant servant;
++ PortableServer_POA poa;
++ CORBA_ORB orb;
++ CORBA_unsigned_long objnum;
++
++ /* Stuff for doing shared libraries nicely */
++ guchar rand_data[ORBIT_RAND_KEY_LEN];
++
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++ int *use_count;
++ GFunc death_callback;
++ gpointer user_data;
++#endif
++} ORBit_POAObject;
++
++typedef struct {
++ PortableServer_ClassInfo *class_info;
++ ORBit_POAObject *object;
++} ORBit_ObjectKey;
++
++#define ORBIT_OBJECT_KEY(x) ((ORBit_ObjectKey *)(x))
++
++struct PortableServer_POA_type {
++ struct ORBit_PseudoObject_struct parent;
++
++ PortableServer_POA parent_poa;
++ CORBA_ORB orb;
++ CORBA_unsigned_long poaID;
++
++ GHashTable *active_object_map;
++ GPtrArray *objnum_to_obj; /* maps objnums to ORBit_POAObject's */
++ CORBA_long first_free_id;
++
++ /* Requests received while in a HOLDING state */
++ GSList *held_requests;
++
++ /* this'll be a hash table when I can be arsed to look up
++ how to implement efficient hash tables - Phil.*/
++ GSList *child_POAs;
++
++ CORBA_char *the_name;
++ PortableServer_POAManager the_POAManager;
++
++ PortableServer_AdapterActivator the_activator;
++
++ PortableServer_ServantManager servant_manager;
++ PortableServer_Servant default_servant;
++
++ PortableServer_ThreadPolicyValue thread;
++ PortableServer_LifespanPolicyValue lifespan;
++ PortableServer_IdUniquenessPolicyValue id_uniqueness;
++ PortableServer_IdAssignmentPolicyValue id_assignment;
++ PortableServer_ImplicitActivationPolicyValue implicit_activation;
++ PortableServer_ServantRetentionPolicyValue servant_retention;
++ PortableServer_RequestProcessingPolicyValue request_processing;
++
++ guchar rand_data[ORBIT_RAND_KEY_LEN];
++};
++
++#endif /* !_ORBIT_ORBIT_POA_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_typecode.c linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.c
+--- linux-2.4.1/net/korbit/orb/orbit_typecode.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,593 @@
++#include "orbit.h"
++#include "orbit_typecode.h"
++#include "cdr.h"
++#include "corba_typecode_type.h"
++#include <IIOP/giop-msg-buffer.h>
++#include "../IIOP/iiop-endianP.h"
++
++#if 0
++#define CORBA_Object_release(x, y) ({ g_message(__FILE__ ":%d Releasing object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_release(x, y); })
++#define CORBA_Object_duplicate(x, y) ({ g_message(__FILE__ ":%d Duping object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_duplicate(x, y); })
++#endif
++
++typedef struct{
++ CORBA_TypeCode tc;
++ guint index;
++}TCRecursionNode;
++
++typedef struct{
++ GSList* prior_tcs; /* Could be a hash table by typecode */
++ guint current_idx; /* The "top-level" index of the start of the current codec */
++}TCEncodeContext;
++
++typedef struct{
++ GSList* prior_tcs; /* Could be a hash table by offset */
++ guint current_idx;
++}TCDecodeContext;
++
++
++
++static void tc_enc(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec(CORBA_TypeCode* t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++
++
++
++typedef void
++(*CORBA_TypeCodeEncoder)(CORBA_TypeCode t,
++ CDR_Codec* c,
++ TCEncodeContext* ctx);
++
++typedef void
++(*CORBA_TypeCodeDecoder)(CORBA_TypeCode t,
++ CDR_Codec* c,
++ TCDecodeContext* ctx);
++
++
++typedef enum{
++ TK_EMPTY,
++ TK_SIMPLE,
++ TK_COMPLEX
++} TkType;
++
++typedef struct{
++ TkType type;
++ CORBA_TypeCodeEncoder encoder;
++ CORBA_TypeCodeDecoder decoder;
++} TkInfo;
++
++static const TkInfo tk_info[CORBA_tk_last]={
++ {TK_EMPTY, NULL, NULL}, /* tk_null */
++ {TK_EMPTY, NULL, NULL}, /* tk_void */
++ {TK_EMPTY, NULL, NULL}, /* tk_short */
++ {TK_EMPTY, NULL, NULL}, /* tk_long */
++ {TK_EMPTY, NULL, NULL}, /* tk_ushort */
++ {TK_EMPTY, NULL, NULL}, /* tk_ulong */
++ {TK_EMPTY, NULL, NULL}, /* tk_float */
++ {TK_EMPTY, NULL, NULL}, /* tk_double */
++ {TK_EMPTY, NULL, NULL}, /* tk_boolean */
++ {TK_EMPTY, NULL, NULL}, /* tk_char */
++ {TK_EMPTY, NULL, NULL}, /* tk_octet */
++ {TK_EMPTY, NULL, NULL}, /* tk_any */
++ {TK_EMPTY, NULL, NULL}, /* tk_TypeCode */
++ {TK_EMPTY, NULL, NULL}, /* tk_Principal */
++ {TK_COMPLEX, tc_enc_tk_objref, tc_dec_tk_objref}, /* tk_objref */
++ {TK_COMPLEX, tc_enc_tk_struct, tc_dec_tk_struct}, /* tk_struct */
++ {TK_COMPLEX, tc_enc_tk_union, tc_dec_tk_union}, /* tk_union */
++ {TK_COMPLEX, tc_enc_tk_enum, tc_dec_tk_enum}, /* tk_enum */
++ {TK_SIMPLE, tc_enc_tk_string, tc_dec_tk_string}, /* tk_string */
++ {TK_COMPLEX, tc_enc_tk_sequence, tc_dec_tk_sequence}, /* tk_sequence */
++ {TK_COMPLEX, tc_enc_tk_array, tc_dec_tk_array}, /* tk_array */
++ {TK_COMPLEX, tc_enc_tk_alias, tc_dec_tk_alias}, /* tk_alias */
++ {TK_COMPLEX, tc_enc_tk_except, tc_dec_tk_except}, /* tk_except */
++ {TK_EMPTY, NULL, NULL}, /* tk_longlong */
++ {TK_EMPTY, NULL, NULL}, /* tk_ulonglong */
++ {TK_EMPTY, NULL, NULL}, /* tk_longdouble */
++ {TK_EMPTY, NULL, NULL}, /* tk_wchar */
++ {TK_SIMPLE, tc_enc_tk_wstring, tc_dec_tk_wstring}, /* tk_wstring */
++ {TK_SIMPLE, tc_enc_tk_fixed, tc_dec_tk_fixed} /* tk_fixed */
++};
++
++void ORBit_encode_CORBA_TypeCode(CORBA_TypeCode t, GIOPSendBuffer* buf)
++{
++ CDR_Codec codec_d;
++ CDR_Codec* codec = &codec_d;
++ TCEncodeContext ctx;
++ GSList* l;
++ CORBA_octet codecbuf[2048];
++
++ CDR_codec_init_static(codec);
++
++ codec->wptr = 0;
++ codec->buffer = codecbuf;
++ codec->release_buffer = FALSE;
++ codec->buf_len = 2048;
++ codec->data_endian=FLAG_ENDIANNESS;
++
++ ctx.current_idx=0;
++ ctx.prior_tcs=NULL;
++ tc_enc(t, codec, &ctx);
++ for(l=ctx.prior_tcs;l;l=l->next)
++ g_free(l->data);
++ g_slist_free(ctx.prior_tcs);
++ giop_send_buffer_append_mem_indirect(buf,
++ codec->buffer,
++ codec->wptr);
++}
++
++void ORBit_decode_CORBA_TypeCode(CORBA_TypeCode* t, GIOPRecvBuffer* buf)
++{
++ CDR_Codec codec_d;
++ CDR_Codec* codec = &codec_d;
++ TCDecodeContext ctx;
++ GSList* l;
++
++ CDR_codec_init_static(codec);
++ codec->buffer=buf->cur;
++ codec->release_buffer=CORBA_FALSE;
++ codec->readonly=CORBA_TRUE;
++ codec->buf_len = /* hope this is correct */
++ ((guchar *)buf->message_body) +
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size
++ - ((guchar *)buf->cur);
++
++ codec->data_endian=GIOP_MESSAGE_BUFFER(buf)->message_header.flags & 1;
++
++ ctx.current_idx=0;
++ ctx.prior_tcs=NULL;
++ tc_dec(t, codec, &ctx);
++ for(l=ctx.prior_tcs;l;l=l->next)
++ g_free(l->data);
++ g_slist_free(ctx.prior_tcs);
++ buf->cur = ((guchar *)buf->cur) + codec->rptr;
++}
++
++
++/* Encode a typecode to a codec, possibly recursively */
++
++static void tc_enc(CORBA_TypeCode tc,
++ CDR_Codec* codec,
++ TCEncodeContext* ctx)
++{
++ TCRecursionNode* node;
++ const TkInfo* info;
++ GSList* l;
++ CORBA_octet codecbuf[2048];
++ CDR_Codec encaps_d;
++ CDR_Codec* encaps = &encaps_d;
++
++ g_assert(CLAMP(0, tc->kind, CORBA_tk_last) == tc->kind);
++
++ for(l=ctx->prior_tcs;l;l=l->next){
++ TCRecursionNode* node=l->data;
++ /* CORBA_CORBA_TypeCode_equal might save space, but is slow.. */
++ if(node->tc==tc){
++ CDR_put_ulong(codec, CORBA_tk_recursive);
++ CDR_put_long(codec,
++ node->index
++ -ctx->current_idx
++ -codec->wptr);
++ return;
++ }
++ }
++
++ /* All right, this isn't a previously met type. So record it. */
++ /* NOTE: put kind before recording index so alignment is dealt with! */
++ CDR_put_ulong(codec, tc->kind);
++
++ node=g_new(TCRecursionNode, 1);
++ node->tc=tc;
++ node->index=ctx->current_idx+codec->wptr - 4; /* -4 for kind */
++ ctx->prior_tcs=g_slist_prepend(ctx->prior_tcs, node);
++
++ info=&tk_info[tc->kind];
++ switch(info->type){
++ guint tmp_index;
++ case TK_EMPTY:
++ break;
++ case TK_COMPLEX:
++ tmp_index=ctx->current_idx;
++ ctx->current_idx+=codec->wptr+4; /* +4 for the length */
++ CDR_codec_init_static(encaps);
++ encaps->wptr = 0;
++ encaps->buffer = codecbuf;
++ encaps->release_buffer = FALSE;
++ encaps->buf_len = 2048;
++ encaps->data_endian=FLAG_ENDIANNESS;
++ CDR_put_octet(encaps, FLAG_ENDIANNESS);
++ (info->encoder)(tc, encaps, ctx);
++ CDR_put_ulong(codec, encaps->wptr);
++ /* Now this is a time hog */
++ CDR_put_octets(codec, encaps->buffer, encaps->wptr);
++ ctx->current_idx=tmp_index;
++ break;
++ case TK_SIMPLE:
++ (info->encoder)(tc, codec, ctx);
++ }
++}
++
++static void
++ORBit_TypeCode_release(gpointer obj, CORBA_Environment *ev)
++{
++ /* we will initialize the TC_ constants with a negative refcount */
++ if(ORBIT_ROOT_OBJECT(obj)->refs >= 0) {
++ ORBIT_ROOT_OBJECT_UNREF(obj);
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs <= 0) {
++ CORBA_TypeCode tc = obj;
++ int i;
++
++ g_free(tc->name);
++ g_free(tc->repo_id);
++
++ for(i = 0; i < tc->sub_parts; i++) {
++ if(tc->subnames)
++ g_free(tc->subnames[i]);
++
++ if(tc->subtypes)
++ CORBA_Object_release((CORBA_Object)tc->subtypes[i], ev);
++
++ if(tc->sublabels)
++ CORBA_any__free(&tc->sublabels[i], NULL, TRUE);
++ }
++
++ g_free(tc->subnames);
++ g_free(tc->subtypes);
++ g_free(tc->sublabels);
++
++ if(tc->discriminator)
++ CORBA_Object_release((CORBA_Object)tc->discriminator, ev);
++
++ g_free(obj);
++ }
++
++ }
++}
++
++const ORBit_RootObject_Interface ORBit_TypeCode_epv = {
++ &ORBit_TypeCode_release
++};
++
++static void tc_dec(CORBA_TypeCode* t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_TCKind kind;
++ CORBA_TypeCode tc;
++ const TkInfo* info;
++ TCRecursionNode* node;
++ CDR_Codec encaps_d;
++ CDR_Codec* encaps = &encaps_d;
++
++ CDR_get_ulong(c, &kind);
++
++ g_assert(CLAMP(0, kind, CORBA_tk_last) == kind);
++
++ if(kind==CORBA_tk_recursive){
++ CORBA_long offset;
++ GSList* l;
++ CDR_get_ulong(c, &offset);
++ for(l=ctx->prior_tcs;l;l=l->next){
++ node=l->data;
++ /* NOTE: below, -4 is b/c we already read offset */
++ if(node->index==ctx->current_idx+c->rptr+offset-4){
++ *t=node->tc;
++ return;
++ }
++ }
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Error,
++ "tc_dec: Invalid CORBA_TypeCode recursion offset "
++ "in input buffer\n");
++ g_assert_not_reached();
++ }
++
++ ORBit_Trace(TraceMod_TC, TraceLevel_Debug, "codec->host_endian: %d, codec->data_endian: %d\n", c->host_endian, c->data_endian);
++ ORBit_Trace(TraceMod_TC, TraceLevel_Debug, "kind: %d, CORBA_tk_last: %d\n", kind, CORBA_tk_last);
++ g_assert(kind<CORBA_tk_last);
++
++ node=g_new(TCRecursionNode, 1);
++ node->index=ctx->current_idx+c->rptr-4; /* -4 for the TCKind */
++ info=&tk_info[kind];
++
++ tc=g_new0(struct CORBA_TypeCode_struct, 1);
++
++ /* Passing in NULL for CORBA_Environment is patently dangerous. */
++ ORBit_pseudo_object_init((ORBit_PseudoObject)tc,
++ ORBIT_PSEUDO_TYPECODE, NULL);
++ ORBit_RootObject_set_interface((ORBit_RootObject)tc,
++ (ORBit_RootObject_Interface *)&ORBit_TypeCode_epv,
++ NULL);
++
++ tc->kind=kind;
++ switch(info->type){
++ guint tmp_index;
++ CORBA_octet o;
++
++ case TK_EMPTY:
++ break;
++
++ case TK_COMPLEX:
++ tmp_index=ctx->current_idx;
++ CDR_codec_init_static(encaps);
++ CDR_get_ulong(c, &encaps->buf_len);
++ ctx->current_idx+=c->rptr;
++ encaps->buffer=&c->buffer[c->rptr];
++ encaps->release_buffer=CORBA_FALSE;
++ CDR_get_octet(encaps, &o);
++ encaps->data_endian=o;
++ (info->decoder)(tc, encaps, ctx);
++ c->rptr += encaps->buf_len;
++ ctx->current_idx=tmp_index;
++ break;
++ case TK_SIMPLE:
++ (info->decoder)(tc, c, ctx);
++ break;
++ }
++ node->tc=tc;
++ ctx->prior_tcs=g_slist_prepend(ctx->prior_tcs, node);
++ *t=tc;
++}
++
++
++
++static void tc_enc_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++}
++
++static void tc_dec_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++}
++
++static void tc_enc_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ tc_enc(*t->subtypes, c, ctx);
++ CDR_put_ulong(c, t->length);
++}
++
++static void tc_dec_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ t->subtypes=g_new(CORBA_TypeCode, 1);
++ tc_dec(&t->subtypes[0], c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[0], NULL);
++ CDR_get_ulong(c, &t->length);
++}
++
++static void tc_enc_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CDR_put_ulong(c, t->length);
++}
++
++static void tc_dec_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CDR_get_ulong(c, &t->length);
++}
++
++static void tc_enc_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ CDR_put_ulong(c, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++){
++ CDR_put_string(c, t->subnames[i]);
++ tc_enc(t->subtypes[i], c, ctx);
++ }
++}
++
++static void tc_dec_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ CDR_get_ulong(c, &t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ t->subtypes=g_new(CORBA_TypeCode, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++){
++ CDR_get_string(c, &t->subnames[i]);
++ tc_dec(&t->subtypes[i], c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[i], NULL);
++ }
++}
++
++#define UNION_MEMBERS(dir) \
++ MEMBER_LOOPER_##dir(ulong, long, long); \
++ case CORBA_tk_enum: /* fall through */ \
++ MEMBER_LOOPER_##dir(ulong, unsigned_long, ulong); \
++ MEMBER_LOOPER_##dir(octet, boolean, boolean); \
++ MEMBER_LOOPER_##dir(octet, char, char); \
++ MEMBER_LOOPER_##dir(ushort, short, short); \
++ MEMBER_LOOPER_##dir(ushort, unsigned_short, ushort); \
++ MEMBER_LOOPER_##dir(ulong_long, long_long, longlong); \
++ MEMBER_LOOPER_##dir(ulong_long, unsigned_long_long, ulonglong); \
++ /* MEMBER_LOOPER_##dir(wchar, wchar, wchar); */
++
++
++static void tc_enc_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ tc_enc(t->discriminator, c, ctx);
++ CDR_put_long(c, t->default_index);
++ CDR_put_ulong(c, t->sub_parts);
++ i=t->sub_parts;
++ /* Thank goodness the discriminator types are rather limited,
++ we can do the marshalling inline.. */
++#define MEMBER_LOOPER_ENC(putname, typename, tkname) \
++ case CORBA_tk_##tkname: \
++ for(i=0;i<t->sub_parts;i++){ \
++ CDR_put_##putname(c, *(CORBA_##typename*) \
++ (t->sublabels[i]._value)); \
++ CDR_put_string(c, t->subnames[i]); \
++ tc_enc(t->subtypes[i], c, ctx); \
++ } \
++ break
++
++ switch(t->discriminator->kind){
++ UNION_MEMBERS(ENC);
++ default:
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Error,
++ "tc_enc_tk_union: Illegal union discriminator "
++ "type %s\n", t->discriminator->name);
++ }
++}
++
++static void tc_dec_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ tc_dec(&t->discriminator, c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->discriminator, NULL);
++ CDR_get_ulong(c, &t->default_index);
++ CDR_get_ulong(c, &t->sub_parts);
++
++ t->sublabels=g_new(CORBA_any, t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ t->subtypes=g_new(CORBA_TypeCode, t->sub_parts);
++
++#define MEMBER_LOOPER_DEC(getname, typename, tkname) \
++ case CORBA_tk_##tkname: \
++ for(i=0;i<t->sub_parts;i++){ \
++ t->sublabels[i]._type = \
++ CORBA_Object_duplicate((CORBA_Object)t->discriminator, NULL); \
++ t->sublabels[i]._value = g_new(CORBA_##typename,1); \
++ t->sublabels[i]._release = CORBA_TRUE; \
++ CDR_get_##getname(c, t->sublabels[i]._value); \
++ CDR_get_string(c, &t->subnames[i]); \
++ tc_dec(&t->subtypes[i], c, ctx); \
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[i], NULL); \
++ } \
++ break
++
++ switch(t->discriminator->kind){
++ UNION_MEMBERS(DEC);
++ default:
++ /* XXX: what is correct error handling */
++ g_assert(!"Not yet implemented.");
++ }
++}
++
++static void tc_enc_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ CDR_put_ulong(c, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++)
++ CDR_put_string(c, t->subnames[i]);
++}
++
++static void tc_dec_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ CDR_get_ulong(c, &t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++)
++ CDR_get_string(c, &t->subnames[i]);
++}
++
++static void tc_enc_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ tc_enc(*t->subtypes, c, ctx);
++}
++
++static void tc_dec_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ t->subtypes=g_new(CORBA_TypeCode, 1);
++ tc_dec(t->subtypes, c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[0], NULL);
++}
++
++
++static void tc_enc_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ gulong i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ CDR_put_ulong(c, t->sub_parts);
++ for(i=0;i<t->length;i++){
++ CDR_put_string(c, t->subnames[i]);
++ tc_enc(t->subtypes[i], c, ctx);
++ }
++}
++
++static void tc_dec_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ gulong i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ CDR_get_ulong(c, &t->sub_parts);
++ t->subtypes=g_new(CORBA_TypeCode, t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ for(i=0;i<t->length;i++){
++ CDR_get_string(c, &t->subnames[i]);
++ tc_dec(&t->subtypes[i], c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[i], NULL);
++ }
++}
++
++static void tc_enc_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ tc_enc(*t->subtypes, c, ctx);
++ CDR_put_ulong(c, t->length);
++}
++
++static void tc_dec_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ t->subtypes=g_new(CORBA_TypeCode, 1);
++ tc_dec(t->subtypes, c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[0], NULL);
++ CDR_get_ulong(c, &t->length);
++}
++
++static void tc_enc_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
++
++static void tc_dec_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
++
++static void tc_enc_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
++
++static void tc_dec_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
+diff -urN linux-2.4.1/net/korbit/orb/orbit_typecode.h linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.h
+--- linux-2.4.1/net/korbit/orb/orbit_typecode.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.h Thu Feb 1 16:21:53 2001
+@@ -0,0 +1,10 @@
++#ifndef _ORBIT_ORBIT_TYPECODE_H_
++#define _ORBIT_ORBIT_TYPECODE_H_
++
++#include "orbit_types.h"
++
++extern const ORBit_RootObject_Interface ORBit_TypeCode_epv;
++void ORBit_encode_CORBA_TypeCode(CORBA_TypeCode tc, GIOPSendBuffer* buf);
++void ORBit_decode_CORBA_TypeCode(CORBA_TypeCode* tc, GIOPRecvBuffer* buf);
++
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/orbit_types.h linux-2.4.1-korbit/net/korbit/orb/orbit_types.h
+--- linux-2.4.1/net/korbit/orb/orbit_types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_types.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,176 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_TYPES_H_
++#define _ORBIT_TYPES_H_
++
++#include <stddef.h> /* for wchar_t */
++#include <sys/types.h> /* for sysdep types */
++#include <netinet/in.h> /* for sockaddr_in */
++#include <sys/uio.h> /* for struct iovec */
++
++#include <ORBitutil/basic_types.h>
++
++#define CORBA_TRUE 1
++#define CORBA_FALSE 0
++
++typedef CORBA_char *CORBA_ORBid;
++
++typedef CORBA_unsigned_long CORBA_ServiceOption;
++typedef CORBA_unsigned_long CORBA_ServiceDetailType;
++
++#include "corba_orb.h"
++
++/*
++ * CORBA_RepositoryId and CORBA_Identifier are defined in the Interface
++ * Repository, but are needed in other interfaces in the ORB itself.
++ */
++#if !defined(_CORBA_Identifier_defined)
++#define _CORBA_Identifier_defined 1
++typedef CORBA_char *CORBA_Identifier;
++#define CORBA_Identifier__free CORBA_string__free
++#endif
++
++#if !defined(_CORBA_RepositoryId_defined)
++#define _CORBA_RepositoryId_defined 1
++typedef CORBA_char *CORBA_RepositoryId;
++#define CORBA_RepositoryId__free CORBA_string__free
++#endif
++
++#include "corba_any.h"
++
++typedef struct CORBA_ServiceDetail_type CORBA_ServiceDetail;
++typedef struct CORBA_Request_type *CORBA_Request;
++typedef struct CORBA_ServerRequest_type *CORBA_ServerRequest;
++typedef struct CORBA_DynFixed_type *CORBA_DynFixed;
++typedef struct CORBA_Current_type *CORBA_Current;
++typedef void CORBA_Status;
++typedef CORBA_unsigned_long CORBA_enum;
++typedef CORBA_unsigned_long CORBA_Flags;
++
++typedef struct CORBA_NVList_type {
++ CORBA_Flags flags;
++ GArray *list;
++} CORBA_NVList;
++
++#include "corba_context.h"
++
++#include "corba_portableserver.h"
++
++#include "corba_env.h"
++
++#include "corba_sequences_type.h"
++
++#include "corba_basic_sequences_type.h"
++
++#include "corba_object.h"
++
++#include "orbit_object_type.h"
++
++#include "corba_object_type.h"
++
++#include "corba_orb_type.h"
++
++#include "corba_typecode.h"
++#include "corba_typecode_type.h"
++#include "corba_any_type.h"
++#include "corba_any_proto.h"
++
++#if !defined(TC_IMPL_TC_CORBA_Identifier_0)
++#define TC_IMPL_TC_CORBA_Identifier_0 '/'
++#define TC_CORBA_Identifier ((CORBA_TypeCode)&TC_CORBA_Identifier_struct)
++extern const struct CORBA_TypeCode_struct TC_CORBA_Identifier_struct;
++#endif
++
++#if !defined(TC_IMPL_TC_CORBA_RepositoryId_0)
++#define TC_IMPL_TC_CORBA_RepositoryId_0 '/'
++extern const struct CORBA_TypeCode_struct TC_CORBA_RepositoryId_struct;
++#define TC_CORBA_RepositoryId ((CORBA_TypeCode)&TC_CORBA_RepositoryId_struct)
++#endif
++
++/* 19.14 */
++
++/* XXX */
++typedef struct CORBA_fixed_d_s {
++ CORBA_unsigned_short _digits;
++ CORBA_short _scale;
++ signed char _sign;
++ signed char _value[1];
++} CORBA_fixed_d_s;
++
++#include "corba_env_type.h"
++
++
++typedef struct CORBA_WrongTransaction {
++ int dummy;
++} CORBA_WrongTransaction;
++
++#define CORBA_ARG_IN (1<<0)
++#define CORBA_ARG_OUT (1<<1)
++#define CORBA_ARG_INOUT (1<<2)
++#define CORBA_CTX_RESTRICT_SCOPE (1<<3)
++#define CORBA_CTX_DELETE_DESCENDENTS (1<<4)
++#define CORBA_OUT_LIST_MEMORY (1<<5)
++#define CORBA_IN_COPY_VALUE (1<<6)
++#define CORBA_DEPENDENT_LIST (1<<7)
++#define CORBA_INV_NO_RESPONSE (1<<8)
++#define CORBA_INV_TERM_ON_ERROR (1<<9)
++#define CORBA_RESP_NO_WAIT (1<<10)
++
++typedef struct CORBA_NamedValue {
++ CORBA_Identifier name; /* argument name */
++ CORBA_any argument; /* argument */
++ CORBA_long len; /* length/count of argument value */
++ CORBA_Flags arg_modes; /* argument mode flags */
++} CORBA_NamedValue;
++
++typedef CORBA_char *CORBA_FieldName;
++
++typedef struct CORBA_NameValuePair {
++ CORBA_FieldName id;
++ CORBA_any value;
++} CORBA_NameValuePair;
++
++struct CORBA_Current_type {
++ int fill_me_in;
++};
++
++#include "corba_portableserver_type.h"
++
++typedef CORBA_unsigned_short CORBA_ServiceType;
++
++#define CORBA_Security (1)
++
++struct CORBA_ServiceDetail_type {
++ CORBA_ServiceDetailType service_detail_type;
++ CORBA_sequence_octet service_detail;
++};
++
++typedef struct CORBA_ServiceInformation_struct {
++ CORBA_sequence_ServiceOption service_options;
++ CORBA_sequence_ServiceDetail service_details;
++} CORBA_ServiceInformation;
++
++#endif /* !_ORBIT_TYPES_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/poa.c linux-2.4.1-korbit/net/korbit/orb/poa.c
+--- linux-2.4.1/net/korbit/orb/poa.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/poa.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,1387 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter, and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#include <string.h>
++#include <stdio.h>
++#include <assert.h>
++
++#include "orbit.h"
++#include "orbit_poa.h"
++#include "genrand.h"
++
++PortableServer_ThreadPolicyValue
++PortableServer_ThreadPolicy__get_value(PortableServer_ThreadPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++ ev->_major = CORBA_NO_EXCEPTION;
++
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_LifespanPolicyValue
++PortableServer_LifespanPolicy__get_value(PortableServer_LifespanPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_IdUniquenessPolicyValue
++PortableServer_IdUniquenessPolicy__get_value(PortableServer_IdUniquenessPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_IdAssignmentPolicyValue
++PortableServer_IdAssignmentPolicy__get_value(PortableServer_IdAssignmentPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_ImplicitActivationPolicyValue
++PortableServer_ImplicitActivationPolicy__get_value(PortableServer_ImplicitActivationPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_ServantRetentionPolicyValue
++PortableServer_ServantRetentionPolicy__get_value(PortableServer_ServantRetentionPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_RequestProcessingPolicyValue
++PortableServer_RequestProcessingPolicy__get_value(PortableServer_RequestProcessingPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++/* make emacs happy; */
++
++PortableServer_POAManager_State
++PortableServer_POAManager_get_state(PortableServer_POAManager obj,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return -1;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->state;
++}
++
++/**** PortableServer_POAManager_activate
++ Inputs: 'obj' - a POAManager to activate
++ Outputs: '*ev' - result of the activate operation
++
++ Side effect: Clears the 'held_requests' lists for all POA's
++ associated with the 'obj' POAManager.
++
++ Description: Sets the POAManager state to 'ACTIVE', then
++ goes through all the POA's associated with this
++ POAManager, and makes them re-process their
++ 'held_requests'
++ */
++void
++PortableServer_POAManager_activate(PortableServer_POAManager obj,
++ CORBA_Environment *ev)
++{
++ GSList *todo;
++ GSList *curitem;
++ PortableServer_POA curpoa;
++
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_ACTIVE;
++
++ for(curitem = obj->poa_collection; curitem;
++ curitem = g_slist_next(curitem)) {
++ curpoa = (PortableServer_POA)curitem->data;
++
++ todo = curpoa->held_requests;
++ curpoa->held_requests = NULL;
++
++ g_slist_foreach(todo, (GFunc)ORBit_POA_handle_request,
++ curpoa);
++ g_slist_foreach(todo, (GFunc)giop_recv_buffer_unuse,
++ NULL);
++
++ g_slist_free(todo);
++ }
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POAManager_hold_requests(PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_HOLDING;
++ if(!wait_for_completion)
++ g_warning("hold_requests not finished - don't know how to kill outstanding request fulfillments");
++
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POAManager_discard_requests(PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_DISCARDING;
++ if(!wait_for_completion)
++ g_warning("discard_requests not finished - don't know how to kill outstanding request fulfillments");
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POAManager_deactivate(PortableServer_POAManager obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_INACTIVE;
++
++ if(etherealize_objects)
++ g_slist_foreach(obj->poa_collection, (GFunc)ORBit_POA_etherealize_objects, ev);
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++
++CORBA_boolean
++PortableServer_AdapterActivator_unknown_adapter(PortableServer_AdapterActivator obj,
++ PortableServer_POA parent,
++ CORBA_char *name,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(CORBA_FALSE);
++}
++
++
++/**** PortableServer_ServantActivator_incarnate
++ */
++PortableServer_Servant
++
++PortableServer_ServantActivator_incarnate
++(PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++void
++PortableServer_ServantActivator_etherealize
++(PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid, PortableServer_POA adapter,
++ PortableServer_Servant serv,
++ CORBA_boolean cleanup_in_progress,
++ CORBA_boolean remaining_activations,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++PortableServer_POA
++PortableServer_POA_create_POA
++ (PortableServer_POA poa,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager a_POAManager,
++ CORBA_PolicyList* policies,
++ CORBA_Environment *ev)
++{
++ PortableServer_POA new_poa = NULL;
++ PortableServer_POA check_poa = NULL;
++
++ /* Check for a child POA by the same name in parent */
++ check_poa = PortableServer_POA_find_POA(poa,adapter_name,
++ FALSE, ev);
++ CORBA_exception_free (ev);
++
++ if (!check_poa) {
++ new_poa = ORBit_POA_new(poa->orb,
++ adapter_name, a_POAManager, policies, ev);
++ } else {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_AdapterAlreadyExists,
++ NULL);
++ new_poa = NULL;
++ }
++
++ if(ev->_major == CORBA_NO_EXCEPTION) {
++ new_poa->parent_poa = poa;
++ ORBit_POA_add_child(poa, new_poa, ev);
++ }
++
++ return new_poa;
++}
++
++/**** PortableServer_POA_find_POA
++ Inputs: 'obj' - a POA
++ 'activate_it' - whether to activate unknown POA's
++
++ Outputs: 'child_poa'
++
++ Description: Finds (and optionally activates) a child POA of 'obj'
++ with the specified names.
++
++ TODO: Activate non-existent adapters if asked.
++
++ */
++PortableServer_POA
++PortableServer_POA_find_POA(PortableServer_POA obj,
++ CORBA_char *adapter_name,
++ CORBA_boolean activate_it,
++ CORBA_Environment *ev)
++{
++ GSList *curitem;
++ PortableServer_POA child_poa;
++
++ for(curitem = obj->child_POAs; curitem;
++ curitem = g_slist_next(curitem)) {
++ child_poa = (PortableServer_POA)curitem->data;
++ if(!strcmp(child_poa->the_name, adapter_name)) {
++ ev->_major = CORBA_NO_EXCEPTION;
++ return child_poa;
++ }
++ }
++
++ if(activate_it)
++ g_warning("Don't yet know how to activate POA named \"%s\"",
++ adapter_name);
++
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_AdapterNonExistent,
++ NULL);
++
++ return NULL;
++}
++
++/**** PortableServer_POA_destroy
++ Inputs: 'obj' - the POA to be destroyed
++ 'etherealize_objects' - flag indicating whether any servant
++ manager should be asked to etherealize
++ objects in the active object map
++ 'wait_for_completion' - flag indicating whether to wait for
++ requests currently being handled
++ */
++void
++PortableServer_POA_destroy(PortableServer_POA obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(etherealize_objects || !wait_for_completion)
++ g_warning("PortableServer_POA_destroy not yet fully implemented; ignoring flags");
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs > 1)
++ g_warning("POA has multiple refs [%d]",
++ ORBIT_ROOT_OBJECT(obj)->refs);
++
++ CORBA_Object_release((CORBA_Object)obj, ev);
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++PortableServer_ThreadPolicy PortableServer_POA_create_thread_policy(PortableServer_POA obj, PortableServer_ThreadPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_ThreadPolicy retval;
++
++ retval = g_new(struct PortableServer_ThreadPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_THREAD_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_ThreadPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_LifespanPolicy PortableServer_POA_create_lifespan_policy(PortableServer_POA obj, PortableServer_LifespanPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_LifespanPolicy retval;
++
++ retval = g_new(struct PortableServer_LifespanPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_LIFESPAN_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_LifespanPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_IdUniquenessPolicy PortableServer_POA_create_id_uniqueness_policy(PortableServer_POA obj, PortableServer_IdUniquenessPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_IdUniquenessPolicy retval;
++
++ retval = g_new(struct PortableServer_IdUniquenessPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_ID_UNIQUENESS_POLICY_ID,
++ ev);
++
++ retval->value = value;
++
++ return (PortableServer_IdUniquenessPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_IdAssignmentPolicy PortableServer_POA_create_id_assignment_policy(PortableServer_POA obj, PortableServer_IdAssignmentPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_IdAssignmentPolicy retval;
++
++ retval = g_new(struct PortableServer_IdAssignmentPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_ID_ASSIGNMENT_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_IdAssignmentPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_ImplicitActivationPolicy PortableServer_POA_create_implicit_activation_policy(PortableServer_POA obj, PortableServer_ImplicitActivationPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_ImplicitActivationPolicy retval;
++
++ retval = g_new(struct PortableServer_ImplicitActivationPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_IMPLICIT_ACTIVATION_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_ImplicitActivationPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_ServantRetentionPolicy PortableServer_POA_create_servant_retention_policy(PortableServer_POA obj, PortableServer_ServantRetentionPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_ServantRetentionPolicy retval;
++
++ retval = g_new(struct PortableServer_ServantRetentionPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_SERVANT_RETENTION_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_ServantRetentionPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_RequestProcessingPolicy PortableServer_POA_create_request_processing_policy(PortableServer_POA obj, PortableServer_RequestProcessingPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_RequestProcessingPolicy retval;
++
++ retval = g_new(struct PortableServer_RequestProcessingPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_REQUEST_PROCESSING_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_RequestProcessingPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++CORBA_char *PortableServer_POA__get_the_name(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ g_assert(obj);
++ g_assert(obj->the_name);
++ return obj->the_name;
++}
++
++PortableServer_POA
++PortableServer_POA__get_the_parent(PortableServer_POA obj,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return obj->parent_poa;
++}
++
++PortableServer_POAManager
++PortableServer_POA__get_the_POAManager(PortableServer_POA obj,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return obj->the_POAManager;
++}
++
++PortableServer_AdapterActivator PortableServer_POA__get_the_activator(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return obj->the_activator;
++}
++
++void PortableServer_POA__set_the_activator(PortableServer_POA obj, PortableServer_AdapterActivator the_activator, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ obj->the_activator = the_activator;
++}
++
++PortableServer_ServantManager PortableServer_POA_get_servant_manager(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ if(obj->request_processing != PortableServer_USE_SERVANT_MANAGER) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ return obj->servant_manager;
++}
++
++void PortableServer_POA_set_servant_manager(PortableServer_POA obj, PortableServer_ServantManager imgr, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->request_processing != PortableServer_USE_SERVANT_MANAGER) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return;
++ }
++
++ obj->servant_manager = imgr;
++}
++
++PortableServer_Servant PortableServer_POA_get_servant(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ return obj->default_servant;
++}
++
++void PortableServer_POA_set_servant(PortableServer_POA obj, PortableServer_Servant p_servant, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return;
++ }
++
++ obj->default_servant = p_servant;
++}
++
++static CORBA_unsigned_long
++get_objnum_for_obj(PortableServer_POA poa, ORBit_POAObject *obj)
++{
++ CORBA_unsigned_long retval;
++
++ if(poa->first_free_id) {
++ retval = poa->first_free_id;
++ poa->first_free_id = GPOINTER_TO_UINT(g_ptr_array_index(poa->objnum_to_obj,
++ retval));
++ g_ptr_array_index(poa->objnum_to_obj, retval) = obj;
++ } else {
++ retval = poa->objnum_to_obj->len;
++ g_ptr_array_add(poa->objnum_to_obj,
++ obj);
++ }
++
++ return retval;
++}
++
++static CORBA_ORB
++get_orb_for_poa(PortableServer_POA poa)
++{
++ if(poa->orb)
++ return poa->orb;
++ if(poa->parent_poa)
++ return get_orb_for_poa(poa->parent_poa);
++
++ return CORBA_OBJECT_NIL;
++}
++
++PortableServer_ObjectId *
++PortableServer_POA_activate_object(PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *servant;
++ PortableServer_ObjectId *new_objid;
++ ORBit_POAObject *new_obj;
++
++ servant = p_servant;
++
++ if(obj->servant_retention != PortableServer_RETAIN
++ || obj->id_assignment != PortableServer_SYSTEM_ID) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ /* Servant Already Active */
++ if((obj->id_uniqueness==PortableServer_UNIQUE_ID) &&
++ (ORBIT_OBJECT_KEY(servant->_private)->object != 0)) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ServantAlreadyActive,
++ NULL);
++ return NULL;
++ }
++
++
++ new_obj = g_new0(ORBit_POAObject, 1);
++ new_obj->object_id = (PortableServer_ObjectId*)CORBA_sequence_octet__alloc();
++
++ new_objid =
++ ORBit_POA_allocate_oid(obj,
++ ORBIT_OBJECT_KEY(servant->_private)->class_info->class_name);
++
++ new_obj->object_id->_buffer = CORBA_octet_allocbuf(new_objid->_length);
++ new_obj->object_id->_length = new_objid->_length;
++ memcpy(new_obj->object_id->_buffer, new_objid->_buffer,
++ new_objid->_length);
++ CORBA_sequence_set_release(new_obj->object_id, CORBA_TRUE);
++
++ new_obj->servant = p_servant;
++ ORBIT_OBJECT_KEY(servant->_private)->object = new_obj;
++ new_obj->orb = get_orb_for_poa(obj);
++ new_obj->poa = obj;
++ new_obj->objnum = get_objnum_for_obj(obj, new_obj);
++ orbit_genrand(new_obj->rand_data, ORBIT_RAND_KEY_LEN);
++
++ g_hash_table_insert(obj->active_object_map,
++ new_obj->object_id,
++ new_obj);
++
++ ev->_major = CORBA_NO_EXCEPTION;
++
++ return new_objid;
++}
++
++void
++PortableServer_POA_activate_object_with_id(PortableServer_POA obj,
++ PortableServer_ObjectId *id,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *servant = p_servant;
++ ORBit_POAObject *newobj;
++
++ if(!obj || !id || !p_servant) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ newobj = g_hash_table_lookup(obj->active_object_map,
++ id);
++
++ if(newobj) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectAlreadyActive, NULL);
++ return;
++ }
++
++ newobj = g_new0(ORBit_POAObject, 1);
++ newobj->object_id = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ newobj->object_id->_length = id->_length;
++ newobj->object_id->_buffer = CORBA_octet_allocbuf(id->_length);
++ newobj->object_id->_release = CORBA_TRUE;
++ memcpy(newobj->object_id->_buffer, id->_buffer, id->_length);
++ newobj->poa = obj;
++ newobj->orb = get_orb_for_poa(obj);
++ newobj->objnum = get_objnum_for_obj(obj, newobj);
++ orbit_genrand(newobj->rand_data, ORBIT_RAND_KEY_LEN);
++
++ newobj->servant = p_servant;
++
++ g_hash_table_insert(obj->active_object_map,
++ newobj->object_id,
++ newobj);
++
++ ORBIT_OBJECT_KEY(servant->_private)->object = newobj;
++
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POA_deactivate_object(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev)
++{
++ ORBit_POAObject *oldobj;
++
++ if(!obj || !oid) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ oldobj = g_hash_table_lookup(obj->active_object_map,
++ oid);
++
++ if(!oldobj) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectNotActive,
++ NULL);
++ return;
++ }
++
++ g_ptr_array_index(obj->objnum_to_obj, oldobj->objnum) = GUINT_TO_POINTER(obj->first_free_id);
++ obj->first_free_id = oldobj->objnum;
++
++ g_hash_table_remove(obj->active_object_map, oid);
++
++ if(obj->request_processing == PortableServer_USE_SERVANT_MANAGER) {
++ POA_PortableServer_ServantActivator__epv *epv;
++ POA_PortableServer_ServantActivator *sm;
++
++ sm = (POA_PortableServer_ServantActivator *)obj->servant_manager;
++ epv = sm->vepv->PortableServer_ServantActivator_epv;
++ epv->etherealize(sm, oldobj->object_id, obj,
++ oldobj->servant,
++ CORBA_FALSE,
++ CORBA_FALSE,
++ ev);
++ }
++
++ CORBA_free(oldobj->object_id);
++
++ g_free(oldobj);
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++CORBA_Object
++PortableServer_POA_create_reference(PortableServer_POA obj,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++PortableServer_ObjectId *PortableServer_POA_servant_to_id(PortableServer_POA obj, PortableServer_Servant p_servant, CORBA_Environment *ev)
++{
++ PortableServer_ObjectId *retval, *orig;
++ PortableServer_ServantBase *serv = p_servant;
++ g_return_val_if_fail(p_servant != NULL, NULL);
++
++ orig = ORBIT_OBJECT_KEY(serv->_private)->object->object_id;
++ retval = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ retval->_length = retval->_maximum = orig->_length;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++ memcpy(retval->_buffer, orig->_buffer, retval->_length);
++ CORBA_sequence_set_release(retval, CORBA_TRUE);
++
++ return retval;
++}
++
++CORBA_Object
++PortableServer_POA_servant_to_reference(PortableServer_POA obj, PortableServer_Servant p_servant, CORBA_Environment *ev)
++{
++ CORBA_Object retval;
++ PortableServer_ObjectId *orig_id;
++ PortableServer_ServantBase *servant = p_servant;
++ ORBit_ObjectKey *obj_key = ORBIT_OBJECT_KEY(servant->_private);
++
++ int implicit = (obj->implicit_activation == PortableServer_IMPLICIT_ACTIVATION);
++ int activate_able = (obj_key->object == 0) ||
++ (obj->id_uniqueness==PortableServer_MULTIPLE_ID);
++ /* ImplicitActivationPolicy */
++ if( implicit && activate_able) {
++ orig_id = PortableServer_POA_activate_object(obj, p_servant, ev);
++ } else {
++ orig_id = obj_key->object->object_id;
++ }
++ retval = PortableServer_POA_id_to_reference(obj,orig_id,ev);
++
++ return retval;
++}
++
++PortableServer_Servant
++PortableServer_POA_reference_to_servant(PortableServer_POA obj, CORBA_Object reference, CORBA_Environment *ev)
++{
++ GSList *cur;
++
++ g_assert(reference);
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT
++ && obj->servant_retention != PortableServer_RETAIN) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ if(reference->servant)
++ return reference->servant;
++
++ for(cur = reference->profile_list; cur; cur = cur->next) {
++ PortableServer_ObjectId *oid;
++ ORBit_Object_info *curprof = cur->data;
++ ORBit_POAObject *objinfo;
++
++ objinfo = ORBit_POA_find_oid_for_object_key(obj, &(curprof->object_key), &oid);
++ CORBA_free(oid);
++ if(objinfo)
++ return objinfo->servant;
++ }
++
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectNotActive,
++ NULL);
++ return NULL;
++}
++
++PortableServer_ObjectId *PortableServer_POA_reference_to_id(PortableServer_POA obj, CORBA_Object reference, CORBA_Environment *ev)
++{
++ PortableServer_ObjectId *retval;
++ ORBit_POAObject *objinfo;
++
++ g_assert(reference);
++ g_assert(reference->active_profile);
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT
++ && obj->servant_retention != PortableServer_RETAIN) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ objinfo = ORBit_POA_find_oid_for_object_key(obj, &(reference->active_profile->object_key), &retval);
++ if(objinfo) {
++ CORBA_free(retval);
++ retval = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ retval->_length = retval->_maximum = objinfo->object_id->_length;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++ memcpy(retval->_buffer, objinfo->object_id->_buffer, retval->_length);
++ CORBA_sequence_set_release(retval, CORBA_TRUE);
++ return retval;
++ } else if(retval)
++ return retval;
++
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectNotActive,
++ NULL);
++ return NULL;
++}
++
++PortableServer_Servant PortableServer_POA_id_to_servant(PortableServer_POA obj, PortableServer_ObjectId *oid, CORBA_Environment *ev)
++{
++ ORBit_POAObject *objinfo;
++
++ if(obj->servant_retention != PortableServer_RETAIN) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ objinfo = g_hash_table_lookup(obj->active_object_map,
++ oid);
++
++ if(!objinfo) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ return objinfo->servant;
++}
++
++static CORBA_Object
++my_PortableServer_POA_id_to_reference(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ const char *type_id,
++ CORBA_Environment *ev)
++{
++ GSList *profiles=NULL;
++ ORBit_Object_info *object_info;
++ CORBA_Object retval;
++ CORBA_ORB orb;
++ ORBit_POAObject *pobj;
++ ORBit_ObjectKey *objkey = NULL;
++
++ orb = obj->the_POAManager->orb;
++
++ g_assert(!oid->_buffer[oid->_length - 1]);
++
++ pobj = g_hash_table_lookup(obj->active_object_map, oid);
++
++ if(pobj) {
++ objkey = ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)pobj->servant)->_private);
++ type_id= objkey->class_info->class_name;
++ }
++
++ /* Do the local connection first, so it will be attempted first by
++ the client parsing the IOR string
++ */
++ if(orb->cnx.ipv6 || orb->cnx.usock) {
++ object_info = g_new0(ORBit_Object_info, 1);
++
++ object_info->profile_type=IOP_TAG_ORBIT_SPECIFIC;
++ object_info->iiop_major = 1;
++ object_info->iiop_minor = 0;
++
++ ORBit_POA_find_object_key_for_oid(obj, pobj, oid, &object_info->object_key);
++
++#ifdef HAVE_IPV6
++ if(orb->cnx.ipv6) {
++ object_info->tag.orbitinfo.ipv6_port =
++ ntohs(IIOP_CONNECTION(orb->cnx.ipv6)->u.ipv6.location.sin_port);
++ }
++#endif
++ if(orb->cnx.usock) {
++ object_info->tag.orbitinfo.unix_sock_path =
++ g_strdup(IIOP_CONNECTION(orb->cnx.usock)->u.usock.sun_path);
++ }
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ }
++
++ if(orb->cnx.ipv4) {
++ object_info=g_new0(ORBit_Object_info, 1);
++
++ object_info->profile_type = IOP_TAG_INTERNET_IOP;
++ object_info->iiop_major = 1;
++ object_info->iiop_minor = 0;
++ ORBit_POA_find_object_key_for_oid(obj, pobj, oid, &object_info->object_key);
++
++ object_info->tag.iopinfo.host = g_strdup(IIOP_CONNECTION(orb->cnx.ipv4)->u.ipv4.hostname);
++ object_info->tag.iopinfo.port = ntohs(IIOP_CONNECTION(orb->cnx.ipv4)->u.ipv4.location.sin_port);
++
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ }
++
++ retval = ORBit_create_object_with_info(profiles, type_id, orb, ev);
++
++ if(retval != CORBA_OBJECT_NIL
++ && ev->_major == CORBA_NO_EXCEPTION
++ && objkey && objkey->class_info && objkey->class_info->init_local_objref) {
++ /* XXX potential memleak if we get an already-valid objref */
++ retval->vepv = g_new0(gpointer, ORBit_class_assignment_counter + 1);
++ retval->vepv_size = ORBit_class_assignment_counter + 1;
++ objkey->class_info->init_local_objref(retval, pobj->servant);
++ retval->servant = pobj->servant;
++ } else
++ retval->vepv = retval->servant = NULL;
++
++ return retval;
++}
++
++CORBA_Object PortableServer_POA_id_to_reference(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev)
++{
++ return my_PortableServer_POA_id_to_reference(obj, oid, NULL, ev);
++}
++
++CORBA_Object
++PortableServer_POA_create_reference_with_id(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev)
++{
++ return my_PortableServer_POA_id_to_reference(obj, oid, intf, ev);
++}
++
++PortableServer_POA PortableServer_Current_get_POA(PortableServer_Current obj, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++PortableServer_ObjectId *PortableServer_Current_get_object_id(PortableServer_Current obj, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++
++CORBA_char *PortableServer_ObjectId_to_string(PortableServer_ObjectId *id, CORBA_Environment *env)
++{
++ return CORBA_string_dup((CORBA_char *)id->_buffer);
++}
++
++CORBA_wchar *PortableServer_ObjectId_to_wstring(PortableServer_ObjectId *id, CORBA_Environment *env)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++PortableServer_ObjectId *PortableServer_string_to_ObjectId(CORBA_char *str, CORBA_Environment *env)
++{
++ PortableServer_ObjectId *retval;
++
++ retval = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++
++ retval->_length = strlen(str) + 1;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++
++ memcpy(retval->_buffer, str, retval->_length);
++
++ return retval;
++}
++
++PortableServer_ObjectId *PortableServer_wstring_to_ObjectId(CORBA_wchar *str, CORBA_Environment *env)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++
++PortableServer_POA PortableServer_ServantBase__default_POA(PortableServer_Servant servant, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(servant, NULL);
++
++ return ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->object->poa;
++}
++
++void PortableServer_ServantLocator_preinvoke(PortableServer_ObjectId *oid, PortableServer_POA adapter, CORBA_Identifier op_name, PortableServer_ServantLocator_Cookie *cookie)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++void PortableServer_ServantLocator_postinvoke(PortableServer_ObjectId *oid, PortableServer_POA adapter, CORBA_Identifier op_name, PortableServer_ServantLocator_Cookie cookie, PortableServer_Servant servant)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++void PortableServer_ServantBase__init(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *serv = servant;
++
++ if(!serv->_private) /* If not already initialized, create the place to
++ stick our info */
++ serv->_private = g_new0(ORBit_ObjectKey, 1);
++}
++
++void PortableServer_ServantBase__fini(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *serv = servant;
++
++ g_free(serv->_private);
++ serv->_private = NULL;
++}
++
++
++/************************ ServerRequest stuff ********************/
++
++CORBA_Identifier CORBA_ServerRequest_operation(CORBA_ServerRequest req, CORBA_Environment *env)
++{
++ return CORBA_string_dup(req->rbuf->message.u.request.operation);
++}
++
++CORBA_Context
++CORBA_ServerRequest_ctx(CORBA_ServerRequest req, CORBA_Environment *env)
++{
++ if(!req->params || req->did_ctx) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return NULL;
++}
++
++void
++CORBA_ServerRequest_arguments(CORBA_ServerRequest req,
++ CORBA_NVList *parameters,
++ CORBA_Environment *env)
++{
++ int i;
++
++ if(req->params) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->params = parameters;
++
++ for(i = 0; i < parameters->list->len; i++) {
++ CORBA_NamedValue *cur;
++
++ cur = &g_array_index(parameters->list, CORBA_NamedValue, i);
++
++ if(cur->arg_modes & CORBA_ARG_OUT) continue;
++ cur->argument._value = ORBit_demarshal_arg(req->rbuf,
++ cur->argument._type,
++ TRUE,
++ (CORBA_ORB)req->orb);
++ CORBA_any_set_release(&cur->argument, TRUE);
++ }
++}
++
++void
++CORBA_ServerRequest_set_result(CORBA_ServerRequest req,
++ CORBA_any *value,
++ CORBA_Environment *env)
++{
++ if(req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->sbuf = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(req->rbuf)->connection,
++ NULL,
++ req->rbuf->message.u.request.request_id,
++ CORBA_NO_EXCEPTION);
++ if(!req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ ORBit_marshal_arg(req->sbuf, value->_value, value->_type);
++}
++
++void
++CORBA_ServerRequest_set_exception(CORBA_ServerRequest req,
++ CORBA_exception_type major,
++ CORBA_any *value,
++ CORBA_Environment *env)
++{
++ if(req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->sbuf = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(req->rbuf)->connection,
++ NULL,
++ req->rbuf->message.u.request.request_id,
++ major);
++ if(!req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->did_exc = TRUE;
++
++ /* XXX do we really need to copy the repo_id into the
++ send buffer? Or is there a way to assume that the CORBA_TypeCode
++ value->_type will be around until after we send the message? */
++ {
++ CORBA_unsigned_long slen;
++ slen = strlen(value->_type->repo_id) + 1;
++ giop_send_buffer_append_mem_indirect_a(req->sbuf, &slen,
++ sizeof(slen));
++ giop_send_buffer_append_mem_indirect(req->sbuf,
++ value->_type->repo_id,
++ slen);
++ }
++
++ ORBit_marshal_arg(req->sbuf, value->_value, value->_type);
++}
++
++void
++POA_PortableServer_ServantActivator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ static const PortableServer_ClassInfo class_info =
++ {NULL,
++ "IDL:omg.org/PortableServer/ServantActivator:1.0",
++ NULL};
++
++ PortableServer_ServantBase__init(((PortableServer_ServantBase *) servant), ev);
++
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->class_info = (gpointer)&class_info;
++}
++
++void
++POA_PortableServer_ServantActivator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ServantBase__fini(servant, ev);
++}
++
++void
++POA_PortableServer_ServantLocator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ static const PortableServer_ClassInfo class_info =
++ {NULL,
++ "IDL:omg.org/PortableServer/ServantLocator:1.0",
++ NULL};
++
++ PortableServer_ServantBase__init(((PortableServer_ServantBase *)servant), ev);
++
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->class_info = (gpointer)&class_info;
++}
++
++void
++POA_PortableServer_ServantLocator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ServantBase__fini(servant, ev);
++}
++
++/* POA-related DSI stuff */
++static void
++dynamic_impl_skel(PortableServer_DynamicImpl *_ORBIT_servant,
++ GIOPRecvBuffer *_ORBIT_recv_buffer,
++ CORBA_Environment *ev,
++ PortableServer_DynamicImplRoutine invoke)
++{
++ /* here the magic occurs... */
++ struct CORBA_ServerRequest_type sr;
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(&sr),
++ ORBIT_PSEUDO_SERVERREQUEST, ev);
++
++ CORBA_Object_duplicate((CORBA_Object)&sr, ev); /* just to make
++ sure it doesn't die
++ elsewhere */
++
++ sr.rbuf = _ORBIT_recv_buffer;
++ sr.orb = GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->connection->orb_data;
++
++ _ORBIT_servant->vepv->PortableServer_DynamicImpl_epv->invoke(_ORBIT_servant,
++ &sr);
++
++ if(sr.sbuf) {
++ int i;
++ for(i = 0; i < sr.params->list->len; i++) {
++ CORBA_NamedValue *cur;
++
++ cur = &g_array_index(sr.params->list, CORBA_NamedValue, i);
++
++ if(cur->arg_modes & CORBA_ARG_IN) continue;
++
++ ORBit_marshal_arg(sr.sbuf, cur->argument._value,
++ cur->argument._type);
++ }
++
++ giop_send_buffer_write(sr.sbuf);
++ giop_send_buffer_unuse(sr.sbuf);
++ } else
++ g_warning("Yo, your DSI code is messed up! You forgot to set_result|set_exception");
++
++ CORBA_NVList_free(sr.params, ev);
++}
++
++static ORBitSkeleton
++dynamic_impl_get_skel(PortableServer_DynamicImpl * servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ gpointer * impl)
++{
++ *impl = (gpointer)servant->vepv->PortableServer_DynamicImpl_epv->invoke;
++
++ return (ORBitSkeleton)dynamic_impl_skel;
++}
++
++void
++PortableServer_DynamicImpl__init(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ static const PortableServer_ClassInfo class_info =
++ {(ORBitSkeleton (*)(PortableServer_ServantBase *, gpointer, gpointer *))
++ &dynamic_impl_get_skel, "IDL:CORBA/Object:1.0", NULL};
++
++ PortableServer_ServantBase__init(servant, ev);
++
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->class_info =
++ (PortableServer_ClassInfo *) & class_info;
++
++}
++
++void PortableServer_DynamicImpl__fini(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase__fini(servant, ev);
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/poa.h linux-2.4.1-korbit/net/korbit/orb/poa.h
+--- linux-2.4.1/net/korbit/orb/poa.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/poa.h Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,337 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_POA_H_
++#define _ORBIT_POA_H_
++
++#include "orbit_types.h"
++
++extern PortableServer_ThreadPolicyValue PortableServer_ThreadPolicy__get_value(
++ PortableServer_ThreadPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_LifespanPolicyValue PortableServer_LifespanPolicy__get_value(
++ PortableServer_LifespanPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdUniquenessPolicyValue PortableServer_IdUniquenessPolicy__get_value(
++ PortableServer_IdUniquenessPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdAssignmentPolicyValue PortableServer_IdAssignmentPolicy__get_value(
++ PortableServer_IdAssignmentPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_ImplicitActivationPolicyValue PortableServer_ImplicitActivationPolicy__get_value(
++ PortableServer_ImplicitActivationPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_ServantRetentionPolicyValue PortableServer_ServantRetentionPolicy__get_value(
++ PortableServer_ServantRetentionPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_RequestProcessingPolicyValue PortableServer_RequestProcessingPolicy__get_value(
++ PortableServer_RequestProcessingPolicy obj,
++ CORBA_Environment *ev);
++
++PortableServer_POAManager_State
++PortableServer_POAManager_get_state(PortableServer_POAManager obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_activate(
++ PortableServer_POAManager obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_hold_requests(
++ PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_discard_requests(
++ PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_deactivate(
++ PortableServer_POAManager obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean PortableServer_AdapterActivator_unknown_adapter(
++ PortableServer_AdapterActivator obj,
++ PortableServer_POA parent,
++ CORBA_char *name,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_ServantActivator_incarnate(
++ PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Environment *ev);
++
++extern void PortableServer_ServantActivator_etherealize(
++ PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ PortableServer_Servant serv,
++ CORBA_boolean cleanup_in_progress,
++ CORBA_boolean remaining_activations,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_POA_create_POA(
++ PortableServer_POA obj,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager a_POAManager,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_POA_find_POA(
++ PortableServer_POA obj,
++ CORBA_char *adapter_name,
++ CORBA_boolean activate_it,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_destroy(
++ PortableServer_POA obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern PortableServer_ThreadPolicy PortableServer_POA_create_thread_policy(
++ PortableServer_POA obj,
++ PortableServer_ThreadPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_LifespanPolicy PortableServer_POA_create_lifespan_policy(
++ PortableServer_POA obj,
++ PortableServer_LifespanPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdUniquenessPolicy PortableServer_POA_create_id_uniqueness_policy(
++ PortableServer_POA obj,
++ PortableServer_IdUniquenessPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdAssignmentPolicy PortableServer_POA_create_id_assignment_policy(
++ PortableServer_POA obj,
++ PortableServer_IdAssignmentPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_ImplicitActivationPolicy PortableServer_POA_create_implicit_activation_policy(
++ PortableServer_POA obj,
++ PortableServer_ImplicitActivationPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_ServantRetentionPolicy PortableServer_POA_create_servant_retention_policy(
++ PortableServer_POA obj,
++ PortableServer_ServantRetentionPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_RequestProcessingPolicy PortableServer_POA_create_request_processing_policy(
++ PortableServer_POA obj,
++ PortableServer_RequestProcessingPolicyValue value,
++ CORBA_Environment *ev);
++
++extern CORBA_char *PortableServer_POA__get_the_name(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_POA__get_the_parent(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_POAManager PortableServer_POA__get_the_POAManager(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_AdapterActivator PortableServer_POA__get_the_activator(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA__set_the_activator(
++ PortableServer_POA obj,
++ PortableServer_AdapterActivator the_activator,
++ CORBA_Environment *ev);
++
++extern PortableServer_ServantManager PortableServer_POA_get_servant_manager(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_set_servant_manager(
++ PortableServer_POA obj,
++ PortableServer_ServantManager imgr,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_POA_get_servant(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_set_servant(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_POA_activate_object(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_activate_object_with_id(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *id,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_deactivate_object(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_create_reference(
++ PortableServer_POA obj,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_create_reference_with_id(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_POA_servant_to_id(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_servant_to_reference(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_POA_reference_to_servant(
++ PortableServer_POA obj,
++ CORBA_Object reference,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_POA_reference_to_id(
++ PortableServer_POA obj,
++ CORBA_Object reference,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_POA_id_to_servant(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_id_to_reference(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_Current_get_POA(
++ PortableServer_Current obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_Current_get_object_id(
++ PortableServer_Current obj,
++ CORBA_Environment *ev);
++
++extern CORBA_char *PortableServer_ObjectId_to_string(
++ PortableServer_ObjectId *id,
++ CORBA_Environment *env);
++
++extern CORBA_wchar *PortableServer_ObjectId_to_wstring(
++ PortableServer_ObjectId *id,
++ CORBA_Environment *env);
++
++extern PortableServer_ObjectId *PortableServer_string_to_ObjectId(
++ CORBA_char *str,
++ CORBA_Environment *env);
++
++extern PortableServer_ObjectId *PortableServer_wstring_to_ObjectId(
++ CORBA_wchar *str,
++ CORBA_Environment *env);
++
++extern PortableServer_POA PortableServer_ServantBase__default_POA(
++ PortableServer_Servant,
++ CORBA_Environment *);
++
++extern void PortableServer_ServantLocator_preinvoke(
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier op_name,
++ PortableServer_ServantLocator_Cookie *cookie);
++
++extern void PortableServer_ServantLocator_postinvoke(
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier op_name,
++ PortableServer_ServantLocator_Cookie cookie,
++ PortableServer_Servant servant);
++
++extern void PortableServer_ServantBase__init(
++ PortableServer_Servant,
++ CORBA_Environment *);
++
++extern void PortableServer_ServantBase__fini(
++ PortableServer_Servant,
++ CORBA_Environment *);
++
++/* 19.27 */
++extern CORBA_Identifier CORBA_ServerRequest_operation(
++ CORBA_ServerRequest req,
++ CORBA_Environment *env);
++
++extern CORBA_Context CORBA_ServerRequest_ctx(
++ CORBA_ServerRequest req,
++ CORBA_Environment *env);
++
++extern void CORBA_ServerRequest_arguments(
++ CORBA_ServerRequest req,
++ CORBA_NVList *parameters,
++ CORBA_Environment *env);
++
++extern void CORBA_ServerRequest_set_result(
++ CORBA_ServerRequest req,
++ CORBA_any *value,
++ CORBA_Environment *env);
++
++extern void CORBA_ServerRequest_set_exception(
++ CORBA_ServerRequest req,
++ CORBA_exception_type major,
++ CORBA_any *value,
++ CORBA_Environment *env);
++
++extern void PortableServer_DynamicImpl__init(PortableServer_Servant,
++ CORBA_Environment *ev);
++
++extern void PortableServer_DynamicImpl__fini(PortableServer_Servant,
++ CORBA_Environment *ev);
++
++
++#include "orbit_poa_type.h"
++
++#endif /* !_ORBIT_POA_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/sequences.c linux-2.4.1-korbit/net/korbit/orb/sequences.c
+--- linux-2.4.1/net/korbit/orb/sequences.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/sequences.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,35 @@
++#include "orbit.h"
++#include "sequences.h"
++
++gpointer CORBA_sequence_octet_free(gpointer mem,
++ gpointer func_data)
++{
++ CORBA_sequence_octet *seqo = mem;
++
++ if(seqo->_release)
++ CORBA_free(seqo->_buffer);
++
++ return (gpointer)((guchar *)mem + sizeof(CORBA_sequence_octet));
++}
++
++CORBA_octet *
++CORBA_octet_allocbuf(CORBA_unsigned_long len)
++{
++ return (CORBA_octet *)ORBit_alloc(len, NULL, NULL);
++}
++
++CORBA_sequence_octet *CORBA_sequence_octet__alloc(void)
++{
++ CORBA_sequence_octet *seqo;
++
++ seqo = ORBit_alloc(sizeof(CORBA_sequence_octet),
++ (ORBit_free_childvals)CORBA_sequence_octet_free,
++ GUINT_TO_POINTER(1));
++
++ seqo->_length = seqo->_maximum = 0;
++ seqo->_buffer = NULL;
++ seqo->_release = CORBA_TRUE;
++
++ return seqo;
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/sequences.h linux-2.4.1-korbit/net/korbit/orb/sequences.h
+--- linux-2.4.1/net/korbit/orb/sequences.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/sequences.h Thu Feb 1 16:21:19 2001
+@@ -0,0 +1,35 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_SEQUENCES_H_
++#define _ORBIT_SEQUENCES_H_
++
++/* #include "corba_sequences_type.h" */
++#include "orbit_types.h"
++
++CORBA_octet *CORBA_octet_allocbuf(CORBA_unsigned_long len);
++CORBA_sequence_octet *CORBA_sequence_octet__alloc(void);
++
++#endif /* !_ORBIT_SEQUENCES_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/server.c linux-2.4.1-korbit/net/korbit/orb/server.c
+--- linux-2.4.1/net/korbit/orb/server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/server.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,217 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* Elliot's stuff */
++/* This is somewhat a mess, because I tried to make it easy to add
++ select() support, and as a result #ifdef's litter the land. */
++
++#include "orbit.h"
++#include "orbit_poa.h"
++#include "orbit_poa_type.h"
++#include <IIOP/IIOP-private.h>
++#ifdef HAVE_SYS_POLL_H
++#include <sys/poll.h>
++#endif
++#include <sys/types.h>
++#include <sys/socket.h>
++
++/* We need:
++ a way to find out what FD's need to be selected on
++ a dummy main loop to implement the CORBA_ORB_run() routine;
++*/
++
++gboolean orb_server_keep_running = FALSE;
++
++ORBit_request_validate ORBIT_request_validator = NULL;
++
++/* function protos */
++static PortableServer_POA ORBit_find_POA_for_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer);
++static PortableServer_POA ORBit_find_POA_for_locate_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer);
++
++static void ORBit_handle_incoming_message(GIOPRecvBuffer *recv_buffer);
++
++void
++ORBit_custom_run_setup(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ IIOPIncomingMessageHandler = ORBit_handle_incoming_message;
++}
++
++
++#if __KERNEL__
++// Modules don't do anything when they call this...
++void CORBA_ORB_run(CORBA_ORB orb, CORBA_Environment *ev) {
++ // This should probably free the ORB pointer, because it is a
++ // duplicated pointer from the one true orb.
++
++}
++
++// The ORB thread calls __CORBA_ORB_run by itself.
++#define CORBA_ORB_run __CORBA_ORB_run
++
++#endif
++
++void
++CORBA_ORB_run(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ ORBit_custom_run_setup(orb, ev);
++
++ orb_server_keep_running = TRUE;
++
++ giop_main();
++}
++
++static void
++ORBit_handle_incoming_request(GIOPRecvBuffer *recv_buffer)
++{
++ CORBA_ORB orb;
++ PortableServer_POA poa;
++ GIOPConnection *connection;
++ ORBit_MessageValidationResult mvr;
++ gboolean do_unuse = TRUE;
++
++ g_assert(recv_buffer);
++
++ connection = GIOP_MESSAGE_BUFFER(recv_buffer)->connection;
++ g_return_if_fail(connection != NULL);
++
++ orb = connection->orb_data;
++
++ g_return_if_fail(orb != NULL);
++
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Debug,
++ "Received request %s, id %d, on %s",
++ recv_buffer->message.u.request.operation,
++ recv_buffer->message.u.request.request_id,
++ recv_buffer->message.u.request.object_key._buffer);
++
++ if(ORBIT_request_validator)
++ mvr = ORBIT_request_validator(recv_buffer->message.u.request.request_id,
++ &recv_buffer->message.u.request.requesting_principal,
++ recv_buffer->message.u.request.operation);
++ else
++ mvr = ORBIT_MESSAGE_ALLOW;
++
++ if(mvr == ORBIT_MESSAGE_ALLOW_ALL)
++ connection->is_auth = TRUE;
++
++ if(mvr != ORBIT_MESSAGE_BAD) {
++ /* Find the POA for this incoming request */
++ poa = ORBit_find_POA_for_request((PortableServer_POA)orb->root_poa,
++ recv_buffer);
++
++ if(poa)
++ do_unuse = ORBit_POA_handle_request(recv_buffer, poa);
++ else
++ g_warning("No POA found for operation %s [%d]",
++ recv_buffer->message.u.request.operation,
++ recv_buffer->message.u.request.request_id);
++ } else {
++ g_warning("Request %s, ID %d was rejected by the authentication mechanism!",
++ recv_buffer->message.u.request.operation,
++ recv_buffer->message.u.request.request_id);
++ }
++
++ if(do_unuse)
++ giop_recv_buffer_unuse(recv_buffer);
++}
++
++static void
++ORBit_handle_incoming_locate_request(GIOPRecvBuffer *recv_buffer)
++{
++ CORBA_ORB orb;
++ PortableServer_POA poa;
++ GIOPConnection *connection;
++ GIOPSendBuffer *send_buffer;
++
++ g_assert(recv_buffer!=NULL);
++
++ connection = GIOP_MESSAGE_BUFFER(recv_buffer)->connection;
++ g_return_if_fail(connection != NULL);
++
++ orb = connection->orb_data;
++
++ g_return_if_fail(orb != NULL);
++
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Debug,
++ "Received locate request id %d, on %s",
++ recv_buffer->message.u.locate_request.request_id,
++ recv_buffer->message.u.locate_request.object_key._buffer);
++ /* Find the POA for this incoming request */
++ poa = ORBit_find_POA_for_locate_request((PortableServer_POA)orb->root_poa, recv_buffer);
++
++ if(poa) {
++ /* Object found, reply with "Object Here" */
++ send_buffer = giop_send_locate_reply_buffer_use(connection,
++ recv_buffer->message.u.locate_request.request_id,
++ GIOP_OBJECT_HERE);
++ giop_send_buffer_write(send_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ } else {
++ /* Object not found, reply with "Unknown Object" */
++ send_buffer = giop_send_locate_reply_buffer_use(connection,
++ recv_buffer->message.u.locate_request.request_id,
++ GIOP_UNKNOWN_OBJECT);
++ giop_send_buffer_write(send_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ }
++
++ giop_recv_buffer_unuse(recv_buffer);
++}
++
++static void
++ORBit_handle_incoming_message(GIOPRecvBuffer *recv_buffer)
++{
++ GIOPConnection *connection;
++
++ g_assert(recv_buffer);
++
++ connection = GIOP_MESSAGE_BUFFER(recv_buffer)->connection;
++ g_return_if_fail(connection != NULL);
++
++ switch(GIOP_MESSAGE_BUFFER(recv_buffer)->message_header.message_type) {
++ case GIOP_REQUEST:
++ ORBit_handle_incoming_request(recv_buffer);
++ break;
++ case GIOP_LOCATEREQUEST:
++ ORBit_handle_incoming_locate_request(recv_buffer);
++ break;
++ case GIOP_CLOSECONNECTION:
++ /* Lame hack - need to do this in a manner that isn't
++ IIOP-specific */
++ giop_recv_buffer_unuse(recv_buffer);
++ giop_main_handle_connection_exception(connection);
++ break;
++ case GIOP_REPLY:
++ /* the above comment probably applies here also... */
++ giop_received_list_push(recv_buffer);
++ break;
++ default:
++ g_warning("discarding message type %d (id possibly %d)",
++ GIOP_MESSAGE_BUFFER(recv_buffer)->message_header.message_type,
++ GIOP_MESSAGE_BUFFER(recv_buffer)->message_header.message_type?recv_buffer->message.u.reply.request_id:recv_buffer->message.u.request.request_id);
++ break;
++ }
++}
++
++static PortableServer_POA
++ORBit_find_POA_for_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer)
++{
++ return ORBit_POA_find_POA_for_object_key(poa,
++ &recv_buffer->message.u.request.object_key);
++}
++
++static PortableServer_POA
++ORBit_find_POA_for_locate_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer)
++{
++ return ORBit_POA_find_POA_for_object_key(poa,
++ &recv_buffer->message.u.locate_request.object_key);
++}
++
++void
++ORBit_set_request_validation_handler(ORBit_request_validate validator)
++{
++ ORBIT_request_validator = validator;
++}
+diff -urN linux-2.4.1/net/korbit/orb/typecode.c linux-2.4.1-korbit/net/korbit/orb/typecode.c
+--- linux-2.4.1/net/korbit/orb/typecode.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/typecode.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,104 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter, Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Elliot Lee <sopwith@cuc.edu>
++ *
++ */
++
++#include "orbit.h"
++#include "orbit_typecode.h"
++
++const struct CORBA_TypeCode_struct TC_null_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_null, "null", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_void_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_void, "void", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_short_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_short, "short", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_long_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_long, "long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_longlong_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_longlong, "long long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_ushort_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_ushort, "unsigned short", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_ulong_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_ulong, "unsigned long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_ulonglong_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_ulonglong, "unsigned long long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_float_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_float, "float", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_double_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_double, "double", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_longdouble_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_longdouble, "long double", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_boolean_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_boolean, "boolean", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_char_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_char, "char", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_wchar_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_wchar, "wide char", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_octet_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_octet, "octet", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_any_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_any, "any", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_TypeCode_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_TypeCode, "TypeCode", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_Principal_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_Principal, "Principal", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_Object_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_objref, "Object Reference", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_string_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_string, "string", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_wstring_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_wstring, "wide string", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_CORBA_NamedValue_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_struct, "CORBA NamedValue", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++
++static const CORBA_TypeCode anon_subtypes_array7[] =
++{(CORBA_TypeCode) & TC_CORBA_string_struct};
++
++#if (TC_IMPL_TC_CORBA_Identifier_0 == '/')
++const struct CORBA_TypeCode_struct TC_CORBA_Identifier_struct =
++{
++ {
++ {(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1}, ORBIT_PSEUDO_TYPECODE},
++ CORBA_tk_alias, "Identifier", "IDL:omg.org/CORBA/Identifier:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array7,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++
++#if (TC_IMPL_TC_CORBA_RepositoryId_0 == '/')
++const struct CORBA_TypeCode_struct TC_CORBA_RepositoryId_struct =
++{
++ {
++ {(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1}, ORBIT_PSEUDO_TYPECODE},
++ CORBA_tk_alias, "RepositoryId", "IDL:omg.org/CORBA/RepositoryId:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array7,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/typecode.h linux-2.4.1-korbit/net/korbit/orb/typecode.h
+--- linux-2.4.1/net/korbit/orb/typecode.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/typecode.h Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,31 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_TYPECODE_H_
++#define _ORBIT_TYPECODE_H_
++
++#include "orbit_types.h"
++
++#endif /* !_ORBIT_TYPECODE_H_ */
+diff -urN linux-2.4.1/net/korbit/sup/CVS/Entries linux-2.4.1-korbit/net/korbit/sup/CVS/Entries
+--- linux-2.4.1/net/korbit/sup/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/sup/CVS/Entries Thu Feb 1 11:47:15 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/korbit/sup/CVS/Repository linux-2.4.1-korbit/net/korbit/sup/CVS/Repository
+--- linux-2.4.1/net/korbit/sup/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/sup/CVS/Repository Thu Feb 1 11:47:15 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/sup
+diff -urN linux-2.4.1/net/korbit/sup/CVS/Root linux-2.4.1-korbit/net/korbit/sup/CVS/Root
+--- linux-2.4.1/net/korbit/sup/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/sup/CVS/Root Thu Feb 1 11:47:15 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
diff --git a/fs/libmysqlfs.c b/fs/libmysqlfs.c
new file mode 100644
index 00000000000..fde325c3c42
--- /dev/null
+++ b/fs/libmysqlfs.c
@@ -0,0 +1,151 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "libmysqlfs.h"
+
+int search_and_replace(char *search, char* replace, char* string)
+{
+ char buff[1024];
+ int found=0;
+ char *ptr1;
+ const char *ptr2=buff;
+ char *strptr=string;
+
+ DBUG_ENTER("search_and_replace");
+ DBUG_PRINT("enter",("search: '%s' replace:'%s' string:'%s'",search,replace,string));
+ strcpy(buff,string);
+ while(ptr1=strstr(ptr2,search))
+ {
+ strncpy(strptr,ptr2,ptr1-buff);
+ strptr+=ptr1-buff;
+ ptr2+=ptr1-buff+strlen(search);
+ strcpy(strptr,replace);
+ strptr+=strlen(replace);
+ found++;
+ }
+ DBUG_RETURN(found);
+}
+
+int show_functions(char *b, function_type type)
+{
+ int i=0,j=0;
+ struct func_st func;
+ DBUG_ENTER("show_functions");
+ get_dynamic(&functions_array,(gptr)&func,i);
+ while(func.length) {
+ if (func.type == type)
+ strcpy(&b[j++*BUFLEN],func.filename);
+ get_dynamic(&functions_array,(gptr)&func,++i);
+ }
+ DBUG_RETURN(j);
+}
+
+struct func_st * check_if_function(char *name, function_type type)
+{
+ int pathlen;
+ int j,i=0, len;
+ static struct func_st function;
+ char buffer[BUFLEN];
+
+ DBUG_ENTER("check_if_function");
+ DBUG_PRINT("enter",("name: '%s' type: '%d'", name, type));
+ pathlen=strlen(name);
+
+ /* We try to compare last element in path to function names */
+ get_dynamic(&functions_array,(gptr)&function,i);
+ while(function.length) {
+ function.continuous ?
+ (j=!strncasecmp(function.filename, name, function.length))
+ : (j=!strcasecmp(function.filename,name));
+ if(j) { /* This happens when function was matched */
+ DBUG_PRINT("info",("Function %s detected!",function.filename));
+ break;
+ }
+ get_dynamic(&functions_array,(gptr)&function,++i);
+ }
+
+ /* Copy path to buffer and trip function name (if found) from it */
+ if(function.length != 0)
+ {
+ DBUG_RETURN(&function);
+ } else {
+ DBUG_RETURN(0);
+ }
+}
+
+/*
+ * parse - splits "path" into different variables
+ * in way "/server/database/table/(field|key)/(value|function)". If path is shorter,
+ * then other fields will be NULL. If path is longer than four levels or
+ * shorter than one level, FS_NOTEXIST is returned.
+ */
+int parse(const char * path, char *server, char * database, char *table,
+ char* field, char* value, struct func_st **funce)
+{
+ char buffer[BUFLEN];
+ char *p=buffer;
+ char *x;
+ int len;
+
+ DBUG_ENTER("parse");
+ DBUG_PRINT("enter",("path: '%s'", path));
+
+ *server=*database=*table=*field=*value='\0';
+
+ /* Search for first slash and drop it */
+ strcpy(buffer,path);
+ x=strtok_r(p,"/",&p);
+ if(x)
+ {
+ strcpy(server,x); /* First argument is server name */
+ if(*p)
+ strcpy(database,strtok_r(p,"/",&p)); /* Second is database */
+ if(p && *p)
+ strcpy(table ,strtok_r(p,"/",&p)); /* Third is table name */
+ if(p && *p)
+ strcpy(field ,strtok_r(p,"/",&p)); /* Fourth is field or key name */
+ if(p && *p)
+ strcpy(value ,strtok_r(p,"/",&p)); /* Fifth is field/key value or function */
+ }
+
+ /* We have to find if last argument is function,
+ * In which case we clear it
+ */
+ if(*value) {
+ *funce=check_if_function(value,VALUE_FUNCTION);
+ if(*funce) *value='\0';
+ } else if (*field) {
+ *funce=check_if_function(field,FIELD_FUNCTION);
+ if(*funce) *field='\0';
+ } else if (*table) {
+ *funce=check_if_function(table,TABLE_FUNCTION);
+ if(*funce) *table='\0';
+ } else if (*database) {
+ *funce=check_if_function(database,DATABASE_FUNCTION);
+ if(*funce) *database='\0';
+ } else if (*server) {
+ *funce=check_if_function(server,SERVER_FUNCTION);
+ if(*funce) *server='\0';
+ } else
+ *funce=NULL;
+
+ DBUG_PRINT("info",("path: '%s', server: '%s', db: '%s', table: '%s', field: '%s', value: '%s', function: '%x'",
+ buffer, server, database, table, field, value, funce ));
+ if(p && *p) /* Something is in buffer - too deep in levels */
+ DBUG_RETURN(-1)
+ else
+ DBUG_RETURN(0)
+}
diff --git a/fs/libmysqlfs.h b/fs/libmysqlfs.h
new file mode 100644
index 00000000000..0e95daaa791
--- /dev/null
+++ b/fs/libmysqlfs.h
@@ -0,0 +1,81 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "CorbaFS.h"
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+
+#define BUFLEN 1024
+#define MAXDIRS 1024
+
+typedef enum {
+ FUNC_NONE,
+ FUNC_SERVER_UPTIME,
+ FUNC_SERVER_THREADS,
+ FUNC_SERVER_VERSION,
+ FUNC_DATABASE_CREATED,
+ FUNC_TABLE_COUNT,
+ FUNC_TABLE_CREATED,
+ FUNC_FIELD_LENGTH,
+ FUNC_KEY_AVG,
+ FUNC_KEY_SUM,
+ FUNC_KEY_MAX,
+ FUNC_KEY_MIN
+} func_enum;
+
+
+typedef enum {
+ NONE_FUNCTION,
+ ROOT_FUNCTION,
+ SERVER_FUNCTION,
+ DATABASE_FUNCTION,
+ TABLE_FUNCTION,
+ KEY_FUNCTION,
+ FIELD_FUNCTION,
+ VALUE_FUNCTION
+} function_type;
+
+struct func_st {
+ char type_s[20];
+ char filename[20];
+ char function[80];
+ function_type type;
+ int length;
+ my_bool continuous;
+} ;
+
+
+int parse(const char* path,
+ char* root,
+ char* database,
+ char* table,
+ char* key,
+ char* field,
+ struct func_st **func
+);
+
+gptr db_load_functions();
+int db_function(char *b,const char *server, const char *database,const char *table,const char *field,
+ const char *value, const char *path, struct func_st *function);
+int fix_filenames(char *buf);
+
+DYNAMIC_ARRAY functions_array;
+
+
diff --git a/fs/my.cnf b/fs/my.cnf
new file mode 100644
index 00000000000..e70f2c30cbf
--- /dev/null
+++ b/fs/my.cnf
@@ -0,0 +1,5 @@
+[mysqlcorbafs]
+socket=/var/lib/mysql/mysql.sock
+host=127.0.0.1
+user=root
+#password=xxxxxx
diff --git a/fs/mysqlcorbafs.c b/fs/mysqlcorbafs.c
new file mode 100644
index 00000000000..4bc27618d4d
--- /dev/null
+++ b/fs/mysqlcorbafs.c
@@ -0,0 +1,998 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/*
+ *
+ * fsck.mysql
+ */
+
+#include "libmysqlfs.h"
+#include "mysqlcorbafs.h"
+#include <my_getopt.h>
+#define MAXPATHLEN 256
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+#include <my_sys.h>
+static long inodeNum;
+
+extern DYNAMIC_ARRAY functions_array;
+enum options {OPT_FTB=256, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_KEYWORDS,
+ OPT_LOCKS, OPT_DROP, OPT_OPTIMIZE, OPT_DELAYED, OPT_TABLES,
+ OPT_CHARSETS_DIR, OPT_DEFAULT_CHARSET};
+
+CHANGEABLE_VAR changeable_vars[] = {
+ { "max_allowed_packet", (long*) &max_allowed_packet,24*1024*1024,4096,
+ 24*1024L*1024L,MALLOC_OVERHEAD,1024},
+ { "net_buffer_length", (long*) &net_buffer_length,1024*1024L-1025,4096,
+ 24*1024L*1024L,MALLOC_OVERHEAD,1024},
+ { 0, 0, 0, 0, 0, 0, 0}
+};
+
+CORBA_ORB orb;
+PortableServer_POA poa;
+CORBA_Environment *ev;
+PortableServer_ObjectId *objid;
+static my_bool verbose=0,opt_compress=0,extended_insert=0, lock_tables=0,
+ opt_quoted=0, opt_lock=0, opt_delayed=0, ignore_errors=0;
+
+gptr fptr;
+
+static const char *load_default_groups[]= { "mysqlcorbafs","client",0 };
+static char *default_charset, *current_host, *current_user, *opt_password,
+ *path,*fields_terminated=0, *lines_terminated=0, *enclosed=0,
+ *opt_enclosed=0, *escaped=0;
+
+
+/* This should be fixed to use my_getopt when the program is ready
+
+
+static struct option long_options[] =
+{
+ {"add-locks", no_argument, 0,OPT_LOCKS},
+ {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
+ {"compress", no_argument, 0, 'C'},
+ {"database",required_argument, 0, 'D'},
+ {"debug",optional_argument, 0, '#'},
+ {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
+ {"delayed-insert",no_argument, 0, OPT_DELAYED},
+ {"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
+ {"fields-enclosed-by", required_argument,0, (int) OPT_ENC},
+ {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
+ {"fields-escaped-by", required_argument,0, (int) OPT_ESC},
+ {"functions",required_argument, 0, 'f'},
+ {"help", no_argument, 0,'?'},
+ {"host", required_argument,0, 'h'},
+ {"lines-terminated-by", required_argument, 0, (int) OPT_LTB},
+ {"lock-tables", no_argument, 0, 'l'},
+ {"no-data", no_argument, 0, 'd'},
+ {"password", optional_argument, 0, 'p'},
+#ifdef __WIN__
+ {"pipe",no_argument,0, 'W'},
+#endif
+ {"port", required_argument,0, 'P'},
+// {"quick", no_argument,0, 'q'},
+ {"quote-names",no_argument,0, 'Q'},
+ {"set-variable",required_argument,0, 'O'},
+ {"socket", required_argument,0, 'S'},
+#include "sslopt-longopts.h"
+#ifndef DONT_ALLOW_USER_CHANGE
+ {"user", required_argument,0, 'u'},
+#endif
+ {"verbose", no_argument,0, 'v'},
+ {"version", no_argument,0, 'V'},
+ {0, 0, 0, 0}
+};
+
+*/
+
+/*
+void
+print_table_data(MYSQL_RES *result)
+{
+ String separator(256);
+ MYSQL_ROW cur;
+ MYSQL_FIELD *field;
+ bool *num_flag;
+
+ num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result));
+ if (info_flag)
+ {
+ print_field_types(result);
+ mysql_field_seek(result,0);
+ }
+ separator.copy("+",1);
+ while ((field = mysql_fetch_field(result)))
+ {
+ uint length=skip_column_names ? 0 : (uint) strlen(field->name);
+ if (quick)
+ length=max(length,field->length);
+ else
+ length=max(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length+1;
+ separator.fill(separator.length()+length+2,'-');
+ separator.append('+');
+ }
+ tee_puts(separator.c_ptr(), PAGER);
+ if (!skip_column_names)
+ {
+ mysql_field_seek(result,0);
+ (void) tee_fputs("|", PAGER);
+ for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
+ {
+ tee_fprintf(PAGER, " %-*s|",min(field->max_length,MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+ }
+ (void) tee_fputs("\n", PAGER);
+ tee_puts(separator.c_ptr(), PAGER);
+ }
+
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("|", PAGER);
+ mysql_field_seek(result,0);
+ for (uint off=0 ; off < mysql_num_fields(result); off++)
+ {
+ const char *str=cur[off] ? cur[off] : "NULL";
+ field = mysql_fetch_field(result);
+ uint length=field->max_length;
+ if (length > MAX_COLUMN_LENGTH)
+ {
+ tee_fputs(str,PAGER); tee_fputs(" |",PAGER);
+ }
+ else
+ tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
+ length, str);
+ }
+ (void) tee_fputs("\n", PAGER);
+ }
+ tee_puts(separator.c_ptr(), PAGER);
+ my_afree((gptr) num_flag);
+}
+
+void
+print_table_data_html(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ MYSQL_FIELD *field;
+
+ mysql_field_seek(result,0);
+ (void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
+ if (!skip_column_names)
+ {
+ while((field = mysql_fetch_field(result)))
+ {
+ tee_fprintf(PAGER, "<TH>%s</TH>", (field->name ?
+ (field->name[0] ? field->name :
+ " &nbsp; ") : "NULL"));
+ }
+ (void) tee_fputs("</TR>", PAGER);
+ }
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("<TR>", PAGER);
+ for (uint i=0; i < mysql_num_fields(result); i++)
+ {
+ ulong *lengths=mysql_fetch_lengths(result);
+ (void) tee_fputs("<TD>", PAGER);
+ safe_put_field(cur[i],lengths[i]);
+ (void) tee_fputs("</TD>", PAGER);
+ }
+ (void) tee_fputs("</TR>", PAGER);
+ }
+ (void) tee_fputs("</TABLE>", PAGER);
+}
+
+
+void
+print_table_data_xml(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ MYSQL_FIELD *fields;
+
+ mysql_field_seek(result,0);
+
+ char *statement;
+ statement=(char*) my_malloc(strlen(glob_buffer.ptr())*5+1, MYF(MY_WME));
+ xmlencode(statement, (char*) glob_buffer.ptr());
+
+ (void) my_chomp(strend(statement));
+
+ tee_fprintf(PAGER,"<?xml version=\"1.0\"?>\n\n<resultset statement=\"%s\">", statement);
+
+ my_free(statement,MYF(MY_ALLOW_ZERO_PTR));
+
+ fields = mysql_fetch_fields(result);
+
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("\n <row>\n", PAGER);
+ for (uint i=0; i < mysql_num_fields(result); i++)
+ {
+ char *data;
+ ulong *lengths=mysql_fetch_lengths(result);
+ data=(char*) my_malloc(lengths[i]*5+1, MYF(MY_WME));
+ tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ xmlencode(data, cur[i]);
+ safe_put_field(data, strlen(data));
+ tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ my_free(data,MYF(MY_ALLOW_ZERO_PTR));
+ }
+ (void) tee_fputs(" </row>\n", PAGER);
+ }
+ (void) tee_fputs("</resultset>\n", PAGER);
+}
+
+
+void
+print_table_data_vertically(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ uint max_length=0;
+ MYSQL_FIELD *field;
+
+ while ((field = mysql_fetch_field(result)))
+ {
+ uint length=(uint) strlen(field->name);
+ if (length > max_length)
+ max_length= length;
+ field->max_length=length;
+ }
+
+ mysql_field_seek(result,0);
+ for (uint row_count=1; (cur= mysql_fetch_row(result)); row_count++)
+ {
+ mysql_field_seek(result,0);
+ tee_fprintf(PAGER,
+ "*************************** %d. row ***************************\n", row_count);
+ for (uint off=0; off < mysql_num_fields(result); off++)
+ {
+ field= mysql_fetch_field(result);
+ tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
+ tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
+ }
+ }
+}
+
+
+
+*/
+
+
+
+static my_bool test_if_special_chars(const char *str)
+{
+ for ( ; *str ; str++)
+ if (!isvar(*str) && *str != '$')
+ return 1;
+ return 0;
+} /* test_if_special_chars */
+
+char *quote_name(char *name, char *buff)
+{
+ char *end;
+ DBUG_ENTER("quote_name");
+ if (!opt_quoted && !test_if_special_chars(name))
+ return name;
+ buff[0]=QUOTE_CHAR;
+ *end=strmov(buff+1,name);
+ end[0]=QUOTE_CHAR;
+ end[1]=0;
+ DBUG_RETURN(buff);
+} /* quote_name */
+
+/*
+ * Allow the user to specify field terminator strings like:
+ * "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
+ * This is done by doubleing ' and add a end -\ if needed to avoid
+ * syntax errors from the SQL parser.
+ */
+
+char *field_escape(char *to,const char *from,uint length)
+{
+ const char *end;
+ uint end_backslashes=0;
+ DBUG_ENTER("field_escape");
+
+ {
+ *to++= *from;
+ if (*from == '\\')
+ end_backslashes^=1; /* find odd number of backslashes */
+ else {
+ if (*from == '\'' && !end_backslashes)
+ *to++= *from; /* We want a duplicate of "'" for MySQL */
+ end_backslashes=0;
+ }
+ }
+ /* Add missing backslashes if user has specified odd number of backs.*/
+ if (end_backslashes)
+ *to++= '\\';
+ DBUG_RETURN(to);
+} /* field_escape */
+
+void safe_exit(int error)
+{
+ if (!first_error)
+ first_error= error;
+ if (ignore_errors)
+ return;
+ if (sock)
+ mysql_close(sock);
+ exit(error);
+}
+/* safe_exit */
+
+
+/*
+ * ** DBerror -- prints mysql error message and exits the program.
+ */
+void DBerror(MYSQL *mysql, const char *when)
+{
+ DBUG_ENTER("DBerror");
+ my_printf_error(0,"Got error: %d: %s %s", MYF(0),
+ mysql_errno(mysql), mysql_error(mysql), when);
+ safe_exit(EX_MYSQLERR);
+ DBUG_VOID_RETURN;
+} /* DBerror */
+
+void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,CORBAFS_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+} /* print_version */
+
+void usage(void)
+{
+ uint i;
+ print_version();
+ puts("By Tõnu Samuel. Some code is partially from other geeks around the world");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
+ puts("Dumping definition and data mysql database or table");
+ printf("Usage: %s [OPTIONS]\n", my_progname);
+ printf("\n\
+ -#, --debug=... Output debug log. Often this is 'd:t:o,filename`.\n\
+ --character-sets-dir=...\n\
+ Directory where character sets are\n\
+ -?, --help Display this help message and exit.\n\
+ -c, --complete-insert Use complete insert statements.\n\
+ -C, --compress Use compression in server/client protocol.\n\
+ --default-character-set=...\n\
+ Set the default character set\n\
+ -e, --extended-insert Allows utilization of the new, much faster\n\
+ INSERT syntax.\n\
+ --add-locks Add locks around insert statements.\n\
+ --allow-keywords Allow creation of column names that are keywords.\n\
+ --delayed-insert Insert rows with INSERT DELAYED.\n\
+ -f, --force Continue even if we get an sql-error.\n\
+ -h, --host=... Connect to host.\n");
+puts("\
+ -l, --lock-tables Lock all tables for read.\n\
+ -t, --no-create-info Don't write table creation info.\n\
+ -d, --no-data No row information.\n\
+ -O, --set-variable var=option\n\
+ give a variable a value. --help lists variables\n\
+ -p, --password[=...] Password to use when connecting to server.\n\
+ If password is not given it's solicited on the tty.\n");
+#ifdef __WIN__
+ puts("-W, --pipe Use named pipes to connect to server");
+#endif
+ printf("\
+ -P, --port=... Port number to use for connection.\n\
+ -q, --quick Don't buffer query, dump directly to stdout.\n\
+ -S, --socket=... Socket file to use for connection.\n\
+ --tables Overrides option --databases (-B).\n");
+#include "sslopt-usage.h"
+#ifndef DONT_ALLOW_USER_CHANGE
+ printf("\
+ -u, --user=# User for login if not current user.\n");
+#endif
+ printf("\
+ -v, --verbose Print info about the various stages.\n\
+ -V, --version Output version information and exit.\n\
+");
+ print_defaults("my",load_default_groups);
+
+ printf("\nPossible variables for option --set-variable (-O) are:\n");
+ for (i=0 ; changeable_vars[i].name ; i++)
+ printf("%-20s current value: %lu\n",
+ changeable_vars[i].name,
+ (ulong) *changeable_vars[i].varptr);
+} /* usage */
+
+
+
+static int get_options(int *argc,char ***argv)
+{
+ int c,option_index;
+ my_bool tty_password=0;
+ DBUG_ENTER("get_options");
+ load_defaults("my",load_default_groups,argc,argv);
+
+ /* change this to use my_getopt when program is ready */
+ set_all_changeable_vars(changeable_vars);
+ while ((c=getopt_long(*argc,*argv,"#::p::h:u:O:P:S:T:EBaAcCdefFlnqtvVw:?Ix",
+ long_options, &option_index)) != EOF)
+ {
+ switch(c) {
+ case 'e':
+ extended_insert=1;
+ break;
+ case OPT_DEFAULT_CHARSET:
+ default_charset= optarg;
+ break;
+ case OPT_CHARSETS_DIR:
+ charsets_dir= optarg;
+ break;
+
+ ignore_errors=1;
+ break;
+ case 'h':
+ my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
+ current_host=my_strdup(optarg,MYF(MY_WME));
+ break;
+#ifndef DONT_ALLOW_USER_CHANGE
+ case 'u':
+ current_user=optarg;
+ break;
+#endif
+ case 'O':
+ if (set_changeable_var(optarg, changeable_vars))
+ {
+ usage();
+ return(1);
+ }
+ break;
+ case 'p':
+ if (optarg)
+ {
+ char *start=optarg;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(optarg,MYF(MY_FAE));
+ while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ } else
+ tty_password=1;
+ break;
+ case 'P':
+ opt_mysql_port= (unsigned int) atoi(optarg);
+ break;
+ case 'S':
+ opt_mysql_unix_port= optarg;
+ break;
+ case 'W':
+#ifdef __WIN__
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+#endif
+ break;
+ case 'T':
+ path= optarg;
+ break;
+ case '#':
+ DBUG_PUSH(optarg ? optarg : "d:t:o");
+ break;
+ case 'C':
+ opt_compress=1;
+ break;
+ case 'l': lock_tables=1; break;
+ case 'Q': opt_quoted=1; break;
+ case 'v': verbose=1; break;
+ case 'V': print_version(); exit(0);
+ default:
+ fprintf(stderr,"%s: Illegal option character '%c'\n",my_progname,opterr);
+ /* Fall throught */
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ case (int) OPT_FTB:
+ fields_terminated= optarg;
+ break;
+ case (int) OPT_LTB:
+ lines_terminated= optarg;
+ break;
+ case (int) OPT_ENC:
+ enclosed= optarg;
+ break;
+ case (int) OPT_O_ENC:
+ opt_enclosed= optarg;
+ break;
+ case (int) OPT_ESC:
+ escaped= optarg;
+ break;
+ case (int) OPT_LOCKS:
+ opt_lock=1;
+ break;
+ case (int) OPT_OPTIMIZE:
+ extended_insert=opt_lock=lock_tables=1;
+ break;
+ case (int) OPT_DELAYED:
+ opt_delayed=1;
+ break;
+#include "sslopt-case.h"
+ }
+ }
+ if (opt_delayed)
+ opt_lock=0; /* Can't have lock with delayed */
+ if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
+ fields_terminated))
+ {
+ fprintf(stderr, "%s: You must use option --tab with --fields-...\n", my_progname);
+ return(1);
+ }
+
+ if (enclosed && opt_enclosed)
+ {
+ fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
+ return(1);
+ }
+ if (default_charset)
+ {
+ if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
+ exit(1);
+ }
+ (*argc)-=optind;
+ (*argv)+=optind;
+ if (tty_password)
+ opt_password=get_tty_password(NullS);
+ DBUG_RETURN(0);
+} /* get_options */
+
+
+/*** epv structures ***/
+
+static PortableServer_ServantBase__epv impl_Inode_base_epv = {
+ NULL, /* _private data */
+ NULL, /* finalize routine */
+ NULL, /* default_POA routine */
+};
+static POA_CorbaFS_Inode__epv impl_Inode_epv = {
+ NULL, /* _private */
+ (gpointer) & impl_Inode_getStatus,
+ (gpointer) & impl_Inode_readpage,
+ (gpointer) & impl_Inode_release,
+
+};
+static PortableServer_ServantBase__epv impl_FileSystem_base_epv = {
+ NULL, /* _private data */
+ NULL, /* finalize routine */
+ NULL, /* default_POA routine */
+};
+static POA_CorbaFS_FileSystem__epv impl_FileSystem_epv = {
+ NULL, /* _private */
+ (gpointer) & impl_FileSystem_getInode,
+ (gpointer) & impl_FileSystem_readdir,
+ (gpointer) & impl_FileSystem_readlink,
+};
+
+/*** vepv structures ***/
+
+static POA_CorbaFS_Inode__vepv impl_Inode_vepv = {
+ &impl_Inode_base_epv,
+ &impl_Inode_epv,
+};
+static POA_CorbaFS_FileSystem__vepv impl_FileSystem_vepv = {
+ &impl_FileSystem_base_epv,
+ &impl_FileSystem_epv,
+};
+
+/*** Stub implementations ***/
+
+static CorbaFS_Inode
+impl_Inode__create(PortableServer_POA poa, CORBA_Environment * ev)
+{
+ CorbaFS_Inode retval;
+ impl_POA_CorbaFS_Inode *newservant;
+ PortableServer_ObjectId *objid;
+
+ DBUG_ENTER("impl_Inode__create");
+ newservant = g_new0(impl_POA_CorbaFS_Inode, 1);
+ newservant->servant.vepv = &impl_Inode_vepv;
+ newservant->poa = poa;
+ POA_CorbaFS_Inode__init((PortableServer_Servant) newservant, ev);
+ objid = PortableServer_POA_activate_object(poa, newservant, ev);
+ CORBA_free(objid);
+ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
+
+ DBUG_RETURN(retval);
+}
+
+static void
+impl_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev)
+{
+ PortableServer_ObjectId *objid;
+
+ DBUG_ENTER("impl_Inode__destroy");
+ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
+ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
+ CORBA_free(objid);
+
+ POA_CorbaFS_Inode__fini((PortableServer_Servant) servant, ev);
+ g_free(servant);
+ DBUG_VOID_RETURN;
+}
+
+static void
+impl_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
+ CORBA_unsigned_short * mode,
+ CORBA_unsigned_long * uid,
+ CORBA_unsigned_long * gid,
+ CORBA_unsigned_long * size,
+ CORBA_unsigned_long * inodeNum,
+ CORBA_unsigned_short * numLinks,
+ CORBA_long * atime,
+ CORBA_long * mtime,
+ CORBA_long * ctime, CORBA_Environment * ev)
+{
+ struct stat buf;
+ char
+ server[BUFLEN],
+ database[BUFLEN],
+ table[BUFLEN],
+ key[BUFLEN],
+ field[BUFLEN],
+ value[BUFLEN];
+
+ struct func_st *func;
+
+ DBUG_ENTER("impl_Inode_getStatus");
+ DBUG_PRINT("enter",("path: '%s', mode: '%o', uid: '%d', gid: '%d', size: '%d',
+ inodeNum: '%d', numLinks: '%d', atime: '%d',mtime: '%d', ctime: '%d'",
+ servant->path, mode, uid, gid, size, inodeNum, numLinks, atime, mtime, ctime));
+ DBUG_PRINT("info",("func: %x",&func));
+ if(parse(servant->path, server, database, table, field, value, &func)>0)
+ {
+ DBUG_PRINT("info",("ENOENT"));
+ *mode=0;
+ } else if (func != NULL){
+ DBUG_PRINT("info",("func: %x",&func));
+ DBUG_PRINT("info",("Argument is function at %x, returning S_IFREG",func));
+ *mode = S_IFREG; // File
+ } else if (*field){
+ DBUG_PRINT("info",("Argument is file, returning S_IFREG"));
+ *mode = S_IFREG; // File
+ } else {
+ DBUG_PRINT("info",("Argument is directory, returning S_IFDIR"));
+ *mode = S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH ; // Dir
+ }
+
+ *mode |= S_IRUSR | S_IRGRP | S_IROTH;
+ *uid = 0;
+ *gid = 0;
+ *size = 4096;
+ *inodeNum = servant->inodeNum;
+ *numLinks = 1;
+ *atime = 3;
+ *mtime = 2;
+ *ctime = 1;
+
+// lstat(servant->path, &buf);
+// *mode = buf.st_mode;
+/* *uid = buf.st_uid;
+ *gid = buf.st_gid;
+ *size = buf.st_size;
+ *inodeNum = buf.st_ino;
+ *numLinks = buf.st_nlink;
+ *atime = buf.st_atime;
+ *mtime = buf.st_mtime;
+ *ctime = buf.st_ctime;*/
+ DBUG_VOID_RETURN;
+}
+
+static void
+impl_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
+ CorbaFS_Buffer ** buffer,
+ CORBA_long size,
+ CORBA_long offset, CORBA_Environment * ev)
+{
+ int type;
+ int fd = -1, c = 0;
+ int res;
+ char
+ server[BUFLEN],
+ database[BUFLEN],
+ table[BUFLEN],
+ key[BUFLEN],
+ field[BUFLEN],
+ value[BUFLEN];
+ struct func_st *func;
+
+ DBUG_ENTER("impl_Inode_readpage");
+ DBUG_PRINT("enter",("path: '%s'", servant->path));
+ *buffer = CorbaFS_Buffer__alloc();
+ (*buffer)->_maximum = size;
+ (*buffer)->_buffer = CORBA_octet_allocbuf(size);
+ printf("requested to read %d bytes\n",size);
+ memset((*buffer)->_buffer, size, 0);
+ type = parse(servant->path, server, database, table, field, value, &func);
+ if (func != NULL)
+ res=db_function((*buffer)->_buffer, server, database, table, field, value, servant->path, func);
+ else
+ res=db_show_field((*buffer)->_buffer, database, table, field, path, value);
+ if(res>0)
+ (*buffer)->_length = strlen((*buffer)->_buffer);
+ else
+ (*buffer)->_length = 0;
+/*
+ fd = open(servant->path, O_RDONLY);
+ printf("Inode_readpage : fd = %d\n", fd);
+ lseek(fd, offset, SEEK_SET);
+ c = read(fd, (*buffer)->_buffer, size);
+ printf("Inode_readpage : read %d bytes\n", c);
+ (*buffer)->_length = c;
+ close(fd);
+*/
+ DBUG_VOID_RETURN;
+}
+
+static void
+impl_Inode_release(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev)
+{
+ DBUG_ENTER("impl_Inode_readpage");
+ DBUG_PRINT("enter",("path: '%s'", servant->path));
+ DBUG_VOID_RETURN;
+}
+
+/*
+ * This function is called when we get mounted
+ */
+CorbaFS_FileSystem
+impl_FileSystem__create(PortableServer_POA poa,
+ CORBA_Environment * ev)
+{
+ CorbaFS_FileSystem retval;
+ impl_POA_CorbaFS_FileSystem *newservant;
+ PortableServer_ObjectId *objid;
+
+ DBUG_ENTER("impl_FileSystem__create");
+ newservant = g_new0(impl_POA_CorbaFS_FileSystem, 1);
+ newservant->servant.vepv = &impl_FileSystem_vepv;
+ newservant->poa = poa;
+ POA_CorbaFS_FileSystem__init((PortableServer_Servant) newservant, ev);
+ objid = PortableServer_POA_activate_object(poa, newservant, ev);
+ CORBA_free(objid);
+ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
+
+ DBUG_RETURN(retval);
+}
+
+/*
+ * This function is called when we get unmounted
+ */
+static void
+impl_FileSystem__destroy(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_Environment * ev)
+{
+ PortableServer_ObjectId *objid;
+ DBUG_ENTER("impl_FileSystem__destroy");
+
+ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
+ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
+ CORBA_free(objid);
+
+ POA_CorbaFS_FileSystem__fini((PortableServer_Servant) servant, ev);
+ g_free(servant);
+ DBUG_VOID_RETURN;
+}
+
+static CorbaFS_Inode
+impl_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path, CORBA_Environment * ev)
+{
+ CorbaFS_Inode retval;
+ impl_POA_CorbaFS_Inode *inode;
+ char
+ database[BUFLEN],
+ table[BUFLEN],
+ key[BUFLEN],
+ field[BUFLEN];
+ char buffer[MAXDIRS][BUFLEN];
+ int c;
+
+ DBUG_ENTER("impl_FileSystem_getInode");
+ DBUG_PRINT("enter",("path: '%s'", path));
+
+ //FIXME: We should verify the existense of file/dir here
+ //
+ retval = impl_Inode__create(servant->poa, ev);
+ inode = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
+ inode->path = CORBA_string_dup(path);
+ //FIXME: inodeNum Generation goes here
+ //
+ inode->inodeNum= inodeNum++;
+#if 0
+ inode->mode = 0040777; /* world-readable directory */
+ inode->uid = 0;
+ inode->gid = 0;
+ inode->size = 4096;
+ inode->inodeNum = inodeNum++;
+ inode->numLinks = 1;
+ inode->atime = 0;
+ inode->mtime = 100;
+ inode->ctime = 10000;
+#endif
+ DBUG_RETURN(retval);
+}
+
+
+static CorbaFS_DirEntSeq *
+impl_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path, CORBA_Environment * ev)
+{
+ CorbaFS_DirEntSeq *retval;
+ CorbaFS_dirent *dirent;
+
+ struct func_st *func;
+ int c, c2,i;
+ char
+ server[BUFLEN],
+ table[BUFLEN],
+ field[BUFLEN],
+ value[BUFLEN],
+ buffer[MAXDIRS][BUFLEN],
+ buffer2[MAXDIRS][BUFLEN],
+ database[BUFLEN];
+
+ DBUG_ENTER("impl_FileSystem_readdir");
+ DBUG_PRINT("enter",("path: '%s'", path));
+ retval = CorbaFS_DirEntSeq__alloc();
+ retval->_maximum = 0;
+ retval->_length = 0;
+
+ parse(path, server, database, table, field, value, &func);
+ if (func != NULL) {
+ c2 = db_function((char *)buffer, server, database, table, field, value, path, func);
+ } else if(!*server) {
+ c2 = db_show_servers(buffer2,MAXDIRS);
+ c = show_functions((char *)buffer, ROOT_FUNCTION);
+ } else if(!*database) {
+ c2 = db_show_databases(buffer2,MAXDIRS);
+ c = show_functions((char *)buffer, SERVER_FUNCTION);
+ } else if(!*table){
+ c2 = db_show_tables(buffer2, database);
+ c = show_functions((char *)buffer, DATABASE_FUNCTION);
+ } else if(!*field){
+ c2 = db_show_primary_keys(buffer2, database,table);
+ if(c2>=0) {
+ c = show_functions((char *)buffer, TABLE_FUNCTION);
+ }
+ } else {
+ c2 = db_show_fields(buffer2, database, table, field);
+ c = show_functions((char *)buffer, FIELD_FUNCTION);
+ c = show_functions((char *)buffer, KEY_FUNCTION);
+ }
+ if(c2 < 0)
+ c=c2=0; // Error occured in database routines
+
+ /* Allocate space to hold all found entries plus "." and ".." */
+ retval->_maximum = c + c2 + 2;
+ retval->_buffer = CORBA_sequence_CorbaFS_dirent_allocbuf(retval->_maximum) ;
+ dirent = retval->_buffer;
+
+ i = 0;
+ while (i < c) {
+ long inode = 123L;
+ dirent[i].inode = inode;
+ dirent[i].name = CORBA_string_dup(buffer[i]);
+ i++;
+ }
+ i = 0;
+ while (i < c2) {
+ long inode = 123L;
+ dirent[c+i].inode = inode;
+ dirent[c+i].name = CORBA_string_dup(buffer2[i]);
+ i++;
+ }
+ dirent[c+i].inode = 123L;
+ dirent[c+i].name = CORBA_string_dup(".");
+ i++;
+ dirent[c+i].inode = 123L;
+ dirent[c+i].name = CORBA_string_dup("..");
+
+ retval->_length = retval->_maximum;
+ DBUG_RETURN(retval);
+}
+
+static CORBA_char *
+impl_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * filename,
+ CORBA_Environment * ev)
+{
+ CORBA_char *retval = CORBA_OBJECT_NIL;
+ char tmp[MAXPATHLEN + 1];
+ int len;
+
+ DBUG_ENTER("impl_FileSystem_readlink");
+ DBUG_PRINT("enter",("path: '%s'", filename));
+
+/* len = readlink(filename, tmp, MAXPATHLEN);
+ if (len != -1)
+ {
+ tmp[len] = '\0';
+ retval = CORBA_string_dup(tmp);
+ }
+
+ printf("%s\n", retval);
+ */
+ DBUG_RETURN(retval);
+}
+
+int fix_filenames(char *buf)
+{
+ int i;
+ for(i=0; i<strlen(buf);i++)
+ if(buf[i]=='/')
+ buf[i]='_';
+}
+
+int main(int argc, char *argv[]) {
+ CorbaFS_FileSystem fs;
+ impl_POA_CorbaFS_FileSystem *fs_impl;
+ FILE *f;
+ PortableServer_POAManager pm;
+
+ DBUG_ENTER("main");
+ DBUG_PROCESS(argv[0]);
+ ev = g_new0(CORBA_Environment,1);
+ CORBA_exception_init(ev);
+ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
+ MY_INIT(argv[0]);
+
+ /*
+ ** Check out the args
+ */
+ if (get_options(&argc, &argv))
+ {
+ my_end(0);
+ exit(EX_USAGE);
+ }
+ if (db_connect(current_host, current_user, opt_password))
+ exit(EX_MYSQLERR);
+ fptr = db_load_functions();
+ db_load_formats();
+ poa = (PortableServer_POA)
+ CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
+ fs = impl_FileSystem__create(poa, ev);
+
+ pm = PortableServer_POA__get_the_POAManager(poa, ev);
+ PortableServer_POAManager_activate(pm, ev);
+
+ fs_impl = PortableServer_POA_reference_to_servant( poa, fs, ev );
+ objid = PortableServer_POA_servant_to_id( poa, fs_impl, ev );
+ printf("CorbaFS-server:\n%s\n", CORBA_ORB_object_to_string(orb, fs, ev));
+ f=fopen("/tmp/mysqlcorbafs.ior","w");
+ fputs(CORBA_ORB_object_to_string(orb, fs, ev),f);
+ fclose(f);
+ CORBA_ORB_run(orb, ev);
+ db_disconnect(current_host);
+
+ return 0;
+}
diff --git a/fs/mysqlcorbafs.h b/fs/mysqlcorbafs.h
new file mode 100644
index 00000000000..f805a1fb584
--- /dev/null
+++ b/fs/mysqlcorbafs.h
@@ -0,0 +1,157 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "CorbaFS.h"
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+
+#define QUOTE_CHAR '`'
+/* Exit codes */
+
+#define EX_USAGE 1
+#define EX_MYSQLERR 2
+#define EX_CONSCHECK 3
+#define EX_EOM 4
+
+#define CORBAFS_VERSION "0.01"
+
+typedef struct
+{
+ POA_CorbaFS_Inode servant;
+ PortableServer_POA poa;
+
+ CORBA_char *path;
+ CORBA_unsigned_long inodeNum;
+#if 0
+ CORBA_unsigned_short mode;
+ CORBA_unsigned_long uid;
+ CORBA_unsigned_long gid;
+ CORBA_unsigned_long size;
+ CORBA_unsigned_short numLinks;
+ CORBA_long atime;
+ CORBA_long mtime;
+ CORBA_long ctime;
+#endif
+}
+impl_POA_CorbaFS_Inode;
+
+typedef struct
+{
+ POA_CorbaFS_FileSystem servant;
+ PortableServer_POA poa;
+
+}
+impl_POA_CorbaFS_FileSystem;
+
+/*** Implementation stub prototypes ***/
+CorbaFS_FileSystem
+impl_FileSystem__create(PortableServer_POA poa, CORBA_Environment * ev);
+
+static void
+impl_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev);
+static void
+impl_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
+ CORBA_unsigned_short * mode,
+ CORBA_unsigned_long * uid,
+ CORBA_unsigned_long * gid,
+ CORBA_unsigned_long * size,
+ CORBA_unsigned_long * inodeNum,
+ CORBA_unsigned_short * numLinks,
+ CORBA_long * atime,
+ CORBA_long * mtime,
+ CORBA_long * ctime, CORBA_Environment * ev);
+
+static void
+impl_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
+ CorbaFS_Buffer ** buffer,
+ CORBA_long size,
+ CORBA_long offset, CORBA_Environment * ev);
+
+static void
+impl_Inode_release(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev);
+
+static void impl_FileSystem__destroy(impl_POA_CorbaFS_FileSystem *
+ servant, CORBA_Environment * ev);
+
+static CorbaFS_Inode
+impl_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path, CORBA_Environment * ev);
+
+static CorbaFS_DirEntSeq *
+impl_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path,
+ CORBA_Environment * ev);
+
+static CORBA_char *
+impl_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * filename,
+ CORBA_Environment * ev);
+
+static my_bool verbose,opt_compress;
+static uint opt_mysql_port=0;
+static my_string opt_mysql_unix_port=0;
+static int first_error=0;
+static MYSQL connection, *sock=0;
+
+extern uint opt_mysql_port;
+extern my_string opt_mysql_unix_port,host,user,password;
+
+
+
+static struct format {
+ char *tablestart;
+
+ char *headerrowstart;
+ char *headercellstart;
+ char *headercellseparator;
+ char *headercellend;
+ char *headerrowend;
+ int headerformat; /* 0 - simple, 1 - left padded, 2 - right padded */
+
+ char *contentrowstart;
+ char *contentcellstart;
+ char *contentcellseparator;
+ char *contentcellend;
+ char *contentrowend;
+ int contentformat;
+
+ char *footerrowstart;
+ char *footercellstart;
+ char *footercellseparator;
+ char *footercellend;
+ char *footerrowend;
+ int footerformat;
+
+ char *tableend;
+
+ char *leftuppercorner;
+ char *rightuppercorner;
+ char *leftdowncorner;
+ char *rightdowncorner;
+ char *leftcross;
+ char *rightcross;
+ char *topcross;
+ char *middlecross;
+ char *bottomcross;
+
+
+} Human, HTML, CSF, XML;
diff --git a/fs/mysqlcorbafs_test.c b/fs/mysqlcorbafs_test.c
new file mode 100644
index 00000000000..bd7d9381744
--- /dev/null
+++ b/fs/mysqlcorbafs_test.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <orb/orbit.h>
+
+#include "CorbaFS.h"
+
+CorbaFS_FileSystem fs;
+
+int
+main (int argc, char *argv[])
+{
+ CORBA_Environment ev;
+ CORBA_ORB orb;
+ CorbaFS_Inode inode;
+ CorbaFS_Buffer *buffer;
+ CorbaFS_DirEntSeq *dirents;
+ CorbaFS_dirent *dirent;
+
+ CORBA_unsigned_short mode;
+ CORBA_unsigned_long uid;
+ CORBA_unsigned_long gid;
+ CORBA_unsigned_long size;
+ CORBA_unsigned_long inodeNum;
+ CORBA_unsigned_short numLinks;
+ CORBA_long atime;
+ CORBA_long mtime;
+ CORBA_long ctime;
+
+ int i;
+
+ int niters = 10;
+
+ CORBA_exception_init(&ev);
+ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+
+ if(argc < 2)
+ {
+ printf("Need a binding ID thing as argv[1]\n");
+ return 1;
+ }
+
+
+ fs = CORBA_ORB_string_to_object(orb, argv[1], &ev);
+ if (!fs) {
+ printf("Cannot bind to %s\n", argv[1]);
+ return 1;
+ }
+
+ if (argc >= 3)
+ inode = CorbaFS_FileSystem_getInode(fs, argv[2], &ev);
+ else
+ inode = CorbaFS_FileSystem_getInode(fs, "/proc/cpuinfo", &ev);
+
+ if (!inode)
+ {
+ printf("Cannot get inode\n");
+ }
+
+ CorbaFS_Inode_getStatus(inode,
+ &mode,
+ &uid,
+ &gid,
+ &size,
+ &inodeNum,
+ &numLinks,
+ &atime,
+ &mtime,
+ &ctime,
+ &ev);
+
+ printf("inode = %x\n", inode);
+ CorbaFS_Inode_readpage(inode, &buffer, 100000, 100, &ev);
+ printf("readpage got %d bytes\n", buffer->_length);
+ printf("readpage returned : %s\n", buffer->_buffer);
+
+ if (argc >= 3)
+ dirents = CorbaFS_FileSystem_readdir(fs, argv[2], &ev);
+ else
+ dirents = CorbaFS_FileSystem_readdir(fs, "/", &ev);
+
+ dirent = dirents->_buffer;
+ for (i = 0; i < dirents->_length; i++)
+ {
+ printf("%d = %s\n", dirent->inode, dirent->name);
+ dirent++;
+ }
+
+ CORBA_Object_release(fs, &ev);
+ CORBA_Object_release((CORBA_Object)orb, &ev);
+
+ return 0;
+}
diff --git a/fs/mysqlfsck b/fs/mysqlfsck
new file mode 100755
index 00000000000..7b4e049b1e3
--- /dev/null
+++ b/fs/mysqlfsck
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+mountpoint=$*
+
+if [#($mountpoint) -eq "0"];
+then
+ exit;
+fi
+
+
+
diff --git a/heap/_check.c b/heap/_check.c
index e22eb5e7e4a..03fb664cba9 100644
--- a/heap/_check.c
+++ b/heap/_check.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -79,9 +79,11 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
}
DBUG_PRINT("info",
("records: %ld seeks: %d max links: %d hitrate: %.2f",
- records,seek,max_links,(float) seek / (float) (records ? records : 1)));
+ records,seek,max_links,
+ (float) seek / (float) (records ? records : 1)));
if (print_status)
printf("Key: %d records: %ld seeks: %d max links: %d hitrate: %.2f\n",
- keynr, records, seek, max_links, (float) seek / (float) records);
+ keynr, records, seek, max_links,
+ (float) seek / (float) (records ? records : 1));
return error;
}
diff --git a/heap/_rectest.c b/heap/_rectest.c
index 3368fbeeffa..522940286fd 100644
--- a/heap/_rectest.c
+++ b/heap/_rectest.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/heapdef.h b/heap/heapdef.h
index 938cb55c0eb..bdd7de45370 100644
--- a/heap/heapdef.h
+++ b/heap/heapdef.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -70,6 +70,7 @@ extern int _hp_rec_key_cmp(HP_KEYDEF *keydef,const byte *rec1,
extern int _hp_key_cmp(HP_KEYDEF *keydef,const byte *rec,
const byte *key);
extern void _hp_make_key(HP_KEYDEF *keydef,byte *key,const byte *rec);
+extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record);
extern int _hp_close(register HP_INFO *info);
extern void _hp_clear(HP_SHARE *info);
diff --git a/heap/hp_block.c b/heap/hp_block.c
index 510d89d6d1e..5c052218e58 100644
--- a/heap/hp_block.c
+++ b/heap/hp_block.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_clear.c b/heap/hp_clear.c
index 702c2e09d29..2dcf91c03d7 100644
--- a/heap/hp_clear.c
+++ b/heap/hp_clear.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -44,7 +44,7 @@ void _hp_clear(HP_SHARE *info)
block->levels=0;
block->last_allocated=0;
}
- info->records=info->deleted=info->data_length=info->index_length=0;;
+ info->records=info->deleted=info->data_length=info->index_length=0;
info->blength=1;
info->changed=0;
info->del_link=0;
diff --git a/heap/hp_close.c b/heap/hp_close.c
index 583602e98cb..9e7d9ab31d1 100644
--- a/heap/hp_close.c
+++ b/heap/hp_close.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,7 +19,7 @@
#include "heapdef.h"
/* Close a database open by hp_open() */
- /* Data is not deallocated */
+ /* Data is normally not deallocated */
int heap_close(HP_INFO *info)
{
@@ -43,9 +43,9 @@ int _hp_close(register HP_INFO *info)
}
#endif
info->s->changed=0;
- info->s->open_count--;
heap_open_list=list_delete(heap_open_list,&info->open_list);
+ if (!--info->s->open_count && info->s->delete_on_close)
+ _hp_free(info->s); /* Table was deleted */
my_free((gptr) info,MYF(0));
DBUG_RETURN(error);
}
-
diff --git a/heap/hp_create.c b/heap/hp_create.c
index 01c5f43adfd..1307fab1d12 100644
--- a/heap/hp_create.c
+++ b/heap/hp_create.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,33 +21,49 @@
#include "heapdef.h"
+
int heap_create(const char *name)
{
+ reg1 HP_SHARE *share;
DBUG_ENTER("heap_create");
- (void) heap_delete_all(name);
+ pthread_mutex_lock(&THR_LOCK_heap);
+ if ((share=_hp_find_named_heap(name)))
+ {
+ if (share->open_count == 0)
+ _hp_free(share);
+ }
+ else
+ {
+ my_errno=ENOENT;
+ }
+ pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
-int heap_delete_all(const char *name)
+int heap_delete_table(const char *name)
{
- reg1 HP_SHARE *info;
- int found;
- DBUG_ENTER("heap_delete_all");
+ int result;
+ reg1 HP_SHARE *share;
+ DBUG_ENTER("heap_delete_table");
+
pthread_mutex_lock(&THR_LOCK_heap);
- if ((info=_hp_find_named_heap(name)))
+ if ((share=_hp_find_named_heap(name)))
{
- if (info->open_count == 0)
- _hp_free(info);
- found=0;
+ if (share->open_count == 0)
+ _hp_free(share);
+ else
+ share->delete_on_close=1;
+ result=0;
}
else
{
- found=my_errno=ENOENT;
+ result=my_errno=ENOENT;
}
pthread_mutex_unlock(&THR_LOCK_heap);
- DBUG_RETURN(found);
+ DBUG_RETURN(result);
}
+
void _hp_free(HP_SHARE *share)
{
heap_share_list=list_delete(heap_share_list,&share->open_list);
diff --git a/heap/hp_delete.c b/heap/hp_delete.c
index a6e77fe5f27..3ac321d5fa2 100644
--- a/heap/hp_delete.c
+++ b/heap/hp_delete.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -50,7 +50,8 @@ int heap_delete(HP_INFO *info, const byte *record)
info->current_hash_ptr=0;
DBUG_RETURN(0);
err:
- if( ++(share->records) == share->blength) share->blength+= share->blength;
+ if (++(share->records) == share->blength)
+ share->blength+= share->blength;
DBUG_RETURN(my_errno);
}
@@ -66,7 +67,8 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
DBUG_ENTER("_hp_delete_key");
blength=share->blength;
- if (share->records+1 == blength) blength+= blength;
+ if (share->records+1 == blength)
+ blength+= blength;
lastpos=hp_find_hash(&keyinfo->block,share->records);
last_ptr=0;
diff --git a/heap/hp_extra.c b/heap/hp_extra.c
index 133be01c676..46e3f529f34 100644
--- a/heap/hp_extra.c
+++ b/heap/hp_extra.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_hash.c b/heap/hp_hash.c
index eb35b947871..e29e51d2b75 100644
--- a/heap/hp_hash.c
+++ b/heap/hp_hash.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -158,11 +158,22 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{
uchar *pos=(uchar*) key;
key+=seg->length;
+ if (seg->null_bit)
+ {
+ key++; /* Skipp null byte */
+ if (*pos) /* Found null */
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ pos++;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for (; pos < (uchar*) key ; pos++)
{
- nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) my_sort_order[(uint) *pos]))+ (nr << 8);
+ nr^=(ulong) ((((uint) nr & 63)+nr2) *
+ ((uint) my_sort_order[(uint) *pos])) + (nr << 8);
nr2+=3;
}
}
@@ -170,7 +181,7 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{
for (; pos < (uchar*) key ; pos++)
{
- nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
+ nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
nr2+=3;
}
}
@@ -188,11 +199,20 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
+ if (seg->null_bit)
+ {
+ if (rec[seg->null_pos] & seg->null_bit)
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for (; pos < end ; pos++)
{
- nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) my_sort_order[(uint) *pos]))+ (nr << 8);
+ nr^=(ulong) ((((uint) nr & 63)+nr2)*
+ ((uint) my_sort_order[(uint) *pos]))+ (nr << 8);
nr2+=3;
}
}
@@ -234,6 +254,16 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{
uchar *pos=(uchar*) key;
key+=seg->length;
+ if (seg->null_bit)
+ {
+ key++;
+ if (*pos)
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ pos++;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for (; pos < (uchar*) key ; pos++)
@@ -264,6 +294,14 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
+ if (seg->null_bit)
+ {
+ if (rec[seg->null_pos] & seg->null_bit)
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for ( ; pos < end ; pos++)
@@ -295,6 +333,14 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
+ if (seg->null_bit)
+ {
+ if ((rec1[seg->null_pos] & seg->null_bit) !=
+ (rec2[seg->null_pos] & seg->null_bit))
+ return 1;
+ if (rec1[seg->null_pos] & seg->null_bit)
+ continue;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
if (my_sortcmp(rec1+seg->start,rec2+seg->start,seg->length))
@@ -309,14 +355,24 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
return 0;
}
- /* Compare a key in a record to a hole key */
+ /* Compare a key in a record to a whole key */
int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
{
HP_KEYSEG *seg,*endseg;
- for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
+ for (seg=keydef->seg,endseg=seg+keydef->keysegs ;
+ seg < endseg ;
+ key+= (seg++)->length)
{
+ if (seg->null_bit)
+ {
+ int found_null=test(rec[seg->null_pos] & seg->null_bit);
+ if (found_null != (int) *key++)
+ return 1;
+ if (found_null)
+ continue;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
if (my_sortcmp(rec+seg->start,key,seg->length))
@@ -327,7 +383,6 @@ int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
if (bcmp(rec+seg->start,key,seg->length))
return 1;
}
- key+=seg->length;
}
return 0;
}
@@ -341,7 +396,28 @@ void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
+ if (seg->null_bit)
+ *key++= test(rec[seg->null_pos] & seg->null_bit);
memcpy(key,rec+seg->start,(size_t) seg->length);
key+=seg->length;
}
}
+
+
+/*
+ Test if any of the key parts are NULL.
+ Return:
+ 1 if any of the key parts was NULL
+ 0 otherwise
+*/
+
+my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
+{
+ HP_KEYSEG *seg,*endseg;
+ for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
+ {
+ if (seg->null_bit && (record[seg->null_pos] & seg->null_bit))
+ return 1;
+ }
+ return 0;
+}
diff --git a/heap/hp_info.c b/heap/hp_info.c
index 379f4d9ec0f..3e9d6b6a90b 100644
--- a/heap/hp_info.c
+++ b/heap/hp_info.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_open.c b/heap/hp_open.c
index 692142de14a..938ab8c4f78 100644
--- a/heap/hp_open.c
+++ b/heap/hp_open.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -44,7 +44,12 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
key_segs+= keydef[i].keysegs;
bzero((char*) &keydef[i].block,sizeof(keydef[i].block));
for (j=length=0 ; j < keydef[i].keysegs; j++)
+ {
length+=keydef[i].seg[j].length;
+ if (keydef[i].seg[j].null_bit &&
+ !(keydef[i].flag & HA_NULL_ARE_EQUAL))
+ keydef[i].flag |= HA_NULL_PART_KEY;
+ }
keydef[i].length=length;
if (length > max_length)
max_length=length;
diff --git a/heap/hp_panic.c b/heap/hp_panic.c
index cfd370a56d0..4b93190b7e1 100644
--- a/heap/hp_panic.c
+++ b/heap/hp_panic.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rename.c b/heap/hp_rename.c
index 267c16b589d..118c5931f43 100644
--- a/heap/hp_rename.c
+++ b/heap/hp_rename.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rfirst.c b/heap/hp_rfirst.c
index e3b9654061d..9a1f09244a0 100644
--- a/heap/hp_rfirst.c
+++ b/heap/hp_rfirst.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rkey.c b/heap/hp_rkey.c
index 157267f7149..e7a1d81fba6 100644
--- a/heap/hp_rkey.c
+++ b/heap/hp_rkey.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key)
{
byte *pos;
HP_SHARE *share=info->s;
- DBUG_ENTER("hp_rkey");
+ DBUG_ENTER("heap_rkey");
DBUG_PRINT("enter",("base: %lx inx: %d",info,inx));
if ((uint) inx >= share->keys)
diff --git a/heap/hp_rlast.c b/heap/hp_rlast.c
index 38e07fde2bb..463b6dc9aac 100644
--- a/heap/hp_rlast.c
+++ b/heap/hp_rlast.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rnext.c b/heap/hp_rnext.c
index 6aa3cf06d97..af08a0e68a2 100644
--- a/heap/hp_rnext.c
+++ b/heap/hp_rnext.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -23,7 +23,7 @@ int heap_rnext(HP_INFO *info, byte *record)
byte *pos;
HP_SHARE *share=info->s;
DBUG_ENTER("heap_rnext");
-
+
if (info->lastinx < 0)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
diff --git a/heap/hp_rprev.c b/heap/hp_rprev.c
index 28a821c143e..c7c649e6b9f 100644
--- a/heap/hp_rprev.c
+++ b/heap/hp_rprev.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rrnd.c b/heap/hp_rrnd.c
index 63181967a29..78abebcaf47 100644
--- a/heap/hp_rrnd.c
+++ b/heap/hp_rrnd.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rsame.c b/heap/hp_rsame.c
index 888fb349f5a..a346707641b 100644
--- a/heap/hp_rsame.c
+++ b/heap/hp_rsame.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_scan.c b/heap/hp_scan.c
index b7684cd2673..e74f8b43ba7 100644
--- a/heap/hp_scan.c
+++ b/heap/hp_scan.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_static.c b/heap/hp_static.c
index 5e5326ca76b..a458b742b9c 100644
--- a/heap/hp_static.c
+++ b/heap/hp_static.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_test1.c b/heap/hp_test1.c
index f44752af3bc..e07af2761f0 100644
--- a/heap/hp_test1.c
+++ b/heap/hp_test1.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@
raderas.
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "heap.h"
diff --git a/heap/hp_test2.c b/heap/hp_test2.c
index a76aa19e082..e2570893519 100644
--- a/heap/hp_test2.c
+++ b/heap/hp_test2.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,7 +30,7 @@
#include <signal.h>
#define MAX_RECORDS 100000
-#define MAX_KEYS 3
+#define MAX_KEYS 4
static int get_options(int argc, char *argv[]);
static int rnd(int max_value);
@@ -40,16 +40,20 @@ static uint flag=0,verbose=0,testflag=0,recant=10000,silent=0;
static uint keys=MAX_KEYS;
static uint16 key1[1001];
static my_bool key3[MAX_RECORDS];
+static int reclength=39;
+
static int calc_check(byte *buf,uint length);
+static void make_record(char *record, uint n1, uint n2, uint n3,
+ const char *mark, uint count);
- /* Huvudprogrammet */
+/* Main program */
int main(int argc, char *argv[])
{
register uint i,j;
uint ant,n1,n2,n3;
- uint reclength,write_count,update,opt_delete,check2,dupp_keys,found_key;
+ uint write_count,update,opt_delete,check2,dupp_keys,found_key;
int error;
ulong pos;
unsigned long key_check;
@@ -66,7 +70,6 @@ int main(int argc, char *argv[])
filename2= "test2_2";
file=file2=0;
get_options(argc,argv);
- reclength=37;
write_count=update=opt_delete=0;
key_check=0;
@@ -77,21 +80,33 @@ int main(int argc, char *argv[])
keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[0].seg[0].start=0;
keyinfo[0].seg[0].length=6;
+ keyinfo[0].seg[0].null_bit=0;
keyinfo[1].seg=keyseg+1;
keyinfo[1].keysegs=2;
keyinfo[1].flag=0;
keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[1].seg[0].start=7;
keyinfo[1].seg[0].length=6;
+ keyinfo[1].seg[0].null_bit=0;
keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT;
- keyinfo[1].seg[1].start=0; /* Tv}delad nyckel */
+ keyinfo[1].seg[1].start=0; /* key in two parts */
keyinfo[1].seg[1].length=6;
+ keyinfo[1].seg[1].null_bit=0;
keyinfo[2].seg=keyseg+3;
keyinfo[2].keysegs=1;
keyinfo[2].flag=HA_NOSAME;
keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[2].seg[0].start=12;
keyinfo[2].seg[0].length=8;
+ keyinfo[2].seg[0].null_bit=0;
+ keyinfo[3].keysegs=1;
+ keyinfo[3].flag=HA_NOSAME;
+ keyinfo[3].seg=keyseg+4;
+ keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY;
+ keyinfo[3].seg[0].start=37;
+ keyinfo[3].seg[0].length=1;
+ keyinfo[3].seg[0].null_bit=1;
+ keyinfo[3].seg[0].null_pos=38;
bzero((char*) key1,sizeof(key1));
bzero((char*) key3,sizeof(key3));
@@ -110,7 +125,7 @@ int main(int argc, char *argv[])
for (i=0 ; i < recant ; i++)
{
n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
- sprintf(record,"%6d:%4d:%8d:Pos: %4d ",n1,n2,n3,write_count);
+ make_record(record,n1,n2,n3,"Pos",write_count);
if (heap_write(file,record))
{
@@ -191,7 +206,7 @@ int main(int argc, char *argv[])
for (i=0 ; i < write_count/10 ; i++)
{
n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
- sprintf(record2,"%6d:%4d:%8d:XXX: %4d ",n1,n2,n3,update);
+ make_record(record2, n1, n2, n3, "XXX", update);
if (rnd(2) == 1)
{
if (heap_scan_init(file))
@@ -572,7 +587,7 @@ end:
heap_clear(file);
if (heap_close(file) || (file2 && heap_close(file2)))
goto err;
- heap_delete_all(filename2);
+ heap_delete_table(filename2);
heap_panic(HA_PANIC_CLOSE);
my_end(MY_GIVE_INFO);
return(0);
@@ -654,3 +669,13 @@ static int calc_check(byte *buf, uint length)
check+= (int) (uchar) *(buf++);
return check;
}
+
+static void make_record(char *record, uint n1, uint n2, uint n3,
+ const char *mark, uint count)
+{
+ bfill(record,reclength,' ');
+ sprintf(record,"%6d:%4d:%8d:%3.3s: %4d",
+ n1,n2,n3,mark,count);
+ record[37]='A'; /* Store A in null key */
+ record[38]=1; /* set as null */
+}
diff --git a/heap/hp_update.c b/heap/hp_update.c
index a1d9c51e9dd..8cf3e4d4b8d 100644
--- a/heap/hp_update.c
+++ b/heap/hp_update.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_write.c b/heap/hp_write.c
index 12b5c638f78..806f40e5be5 100644
--- a/heap/hp_write.c
+++ b/heap/hp_write.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -62,6 +62,7 @@ int heap_write(HP_INFO *info, const byte *record)
info->update|=HA_STATE_AKTIV;
DBUG_RETURN(0);
err:
+ DBUG_PRINT("info",("Duplicate key: %d",key));
info->errkey= key;
do
{
@@ -237,8 +238,10 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
_hp_movelink(pos,gpos,empty);
}
- /* Check if dupplicated keys */
- if ((keyinfo->flag & HA_NOSAME) && pos == gpos)
+ /* Check if duplicated keys */
+ if ((keyinfo->flag & HA_NOSAME) && pos == gpos &&
+ (!(keyinfo->flag & HA_NULL_PART_KEY) ||
+ !hp_if_null_in_key(keyinfo, record)))
{
pos=empty;
do
diff --git a/include/Makefile.am b/include/Makefile.am
index 393dac3fd82..576f557cdd3 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -16,28 +16,27 @@
# MA 02111-1307, USA
BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h
-pkginclude_HEADERS = dbug.h m_string.h my_sys.h mysql.h mysql_com.h \
- mysqld_error.h my_list.h \
- my_pthread.h my_no_pthread.h raid.h errmsg.h \
- my_global.h my_net.h \
+pkginclude_HEADERS = dbug.h m_string.h my_sys.h my_list.h \
+ mysql.h mysql_com.h mysqld_error.h mysql_embed.h \
+ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \
+ errmsg.h my_global.h my_net.h my_alloc.h\
sslopt-case.h sslopt-longopts.h sslopt-usage.h \
sslopt-vars.h $(BUILT_SOURCES)
-noinst_HEADERS = global.h config-win.h config-os2.h\
+noinst_HEADERS = config-win.h config-os2.h \
nisam.h heap.h merge.h my_bitmap.h\
myisam.h myisampack.h myisammrg.h ft_global.h\
my_dir.h mysys_err.h my_base.h \
- my_nosys.h my_alarm.h queues.h \
- my_tree.h hash.h thr_alarm.h thr_lock.h \
- getopt.h t_ctype.h violite.h \
- mysql_version.h.in
+ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
+ my_aes.h my_getopt.h my_tree.h hash.h thr_alarm.h \
+ thr_lock.h t_ctype.h violite.h md5.h mysql_version.h.in
# mysql_version.h are generated
-SUPERCLEANFILES = mysql_version.h my_global.h my_config.h
+SUPERCLEANFILES = mysql_version.h my_config.h
# Some include files that may be moved and patched by configure
DISTCLEANFILES = sched.h
-all-local: my_global.h my_config.h
+all-local: my_config.h
# Since we include my_config.h it better exist from the beginning
link_sources:
@@ -48,11 +47,6 @@ link_sources:
my_config.h: ../config.h
$(CP) ../config.h my_config.h
-# This should be changed in the source and removed.
-my_global.h: global.h
- $(RM) -f my_global.h
- $(CP) global.h my_global.h
-
# These files should not be included in distributions since they are
# generated by configure from the .h.in files
dist-hook:
diff --git a/include/config-os2.h b/include/config-os2.h
index e23f4eb75e8..7e9684ae3f5 100644
--- a/include/config-os2.h
+++ b/include/config-os2.h
@@ -67,10 +67,10 @@
#define NO_FCNTL_NONBLOCK
#define EFBIG E2BIG
-//#define ENFILE EMFILE
-//#define ENAMETOOLONG (EOS2ERR+2)
-//#define ETIMEDOUT 145
-//#define EPIPE 146
+/*#define ENFILE EMFILE */
+/*#define ENAMETOOLONG (EOS2ERR+2) */
+/*#define ETIMEDOUT 145 */
+/*#define EPIPE 146 */
#define EROFS 147
#define sleep(A) DosSleep((A)*1000)
@@ -132,7 +132,7 @@ typedef unsigned long long os_off_t;
#define HAVE_ALLOCA 1
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
-//#define HAVE_ALLOCA_H 1
+/* #define HAVE_ALLOCA_H 1 */
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
@@ -148,7 +148,7 @@ typedef unsigned long long os_off_t;
#define HAVE_ST_RDEV 1
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
-//#define HAVE_SYS_WAIT_H 1
+/* #define HAVE_SYS_WAIT_H 1 */
/* Define if you don't have tm_zone but do have the external array
tzname. */
@@ -219,7 +219,7 @@ typedef unsigned long long os_off_t;
#define HAVE_BOOL 1
/* Have berkeley db installed */
-//#define HAVE_BERKELEY_DB 1
+/* #define HAVE_BERKELEY_DB 1 */
/* DSB style signals ? */
/* #undef HAVE_BSD_SIGNALS */
@@ -398,7 +398,7 @@ typedef unsigned long long os_off_t;
#define HAVE_CHSIZE 1
/* Define if you have the cuserid function. */
-//#define HAVE_CUSERID 1
+/* #define HAVE_CUSERID 1 */
/* Define if you have the dlerror function. */
#define HAVE_DLERROR 1
@@ -410,7 +410,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_FCHMOD */
/* Define if you have the fcntl function. */
-//#define HAVE_FCNTL 1
+/* #define HAVE_FCNTL 1 */
/* Define if you have the fconvert function. */
/* #undef HAVE_FCONVERT */
@@ -428,7 +428,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_FSEEKO */
/* Define if you have the ftruncate function. */
-//#define HAVE_FTRUNCATE 1
+/* #define HAVE_FTRUNCATE 1 */
/* Define if you have the getcwd function. */
#define HAVE_GETCWD 1
@@ -443,16 +443,16 @@ typedef unsigned long long os_off_t;
#define HAVE_GETPAGESIZE 1
/* Define if you have the getpass function. */
-//#define HAVE_GETPASS 1
+/*#define HAVE_GETPASS 1 */
/* Define if you have the getpassphrase function. */
/* #undef HAVE_GETPASSPHRASE */
/* Define if you have the getpwnam function. */
-//#define HAVE_GETPWNAM 1
+/* #define HAVE_GETPWNAM 1 */
/* Define if you have the getpwuid function. */
-//#define HAVE_GETPWUID 1
+/* #define HAVE_GETPWUID 1 */
/* Define if you have the getrlimit function. */
/* #undef HAVE_GETRLIMIT */
@@ -494,7 +494,7 @@ typedef unsigned long long os_off_t;
#define HAVE_MEMMOVE 1
/* Define if you have the mkstemp function. */
-//#define HAVE_MKSTEMP 1
+/* #define HAVE_MKSTEMP 1 */
/* Define if you have the mlockall function. */
/* #undef HAVE_MLOCKALL */
@@ -584,7 +584,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_SIGTHREADMASK */
/* Define if you have the snprintf function. */
-//#define HAVE_SNPRINTF 1
+/* #define HAVE_SNPRINTF 1 */
/* Define if you have the socket function. */
#define HAVE_SOCKET 1
@@ -638,7 +638,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_VIDATTR */
/* Define if you have the <alloca.h> header file. */
-//#define HAVE_ALLOCA_H 1
+/* #define HAVE_ALLOCA_H 1 */
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
@@ -650,10 +650,10 @@ typedef unsigned long long os_off_t;
#define HAVE_CRYPT_H 1
/* Define if you have the <curses.h> header file. */
-//#define HAVE_CURSES_H 1
+/* #define HAVE_CURSES_H 1 */
/* Define if you have the <dirent.h> header file. */
-//#define HAVE_DIRENT_H 1
+/* #define HAVE_DIRENT_H 1 */
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
@@ -665,7 +665,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_FLOATINGPOINT_H */
/* Define if you have the <grp.h> header file. */
-//#define HAVE_GRP_H 1
+/* #define HAVE_GRP_H 1 */
/* Define if you have the <ieeefp.h> header file. */
/* #undef HAVE_IEEEFP_H */
@@ -689,7 +689,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_PATHS_H */
/* Define if you have the <pwd.h> header file. */
-//#define HAVE_PWD_H 1
+/* #define HAVE_PWD_H 1 */
/* Define if you have the <sched.h> header file. */
/* #undef HAVE_SCHED_H */
@@ -710,16 +710,16 @@ typedef unsigned long long os_off_t;
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
-//#define HAVE_STRINGS_H 1
+/* #define HAVE_STRINGS_H 1 */
/* Define if you have the <synch.h> header file. */
/* #undef HAVE_SYNCH_H */
/* Define if you have the <sys/dir.h> header file. */
-//#define HAVE_SYS_DIR_H 1
+/* #define HAVE_SYS_DIR_H 1 */
/* Define if you have the <sys/file.h> header file. */
-//#define HAVE_SYS_FILE_H 1
+/* #define HAVE_SYS_FILE_H 1 */
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
@@ -761,7 +761,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_SYS_VADVISE_H */
/* Define if you have the <sys/wait.h> header file. */
-//#define HAVE_SYS_WAIT_H 1
+/* #define HAVE_SYS_WAIT_H 1 */
/* Define if you have the <term.h> header file. */
/* #undef HAVE_TERM_H */
@@ -770,13 +770,13 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_TERMBITS_H */
/* Define if you have the <termcap.h> header file. */
-//#define HAVE_TERMCAP_H 1
+/* #define HAVE_TERMCAP_H 1 */
/* Define if you have the <termio.h> header file. */
-//#define HAVE_TERMIO_H 1
+/* /#define HAVE_TERMIO_H 1 */
/* Define if you have the <termios.h> header file. */
-//#define HAVE_TERMIOS_H 1
+/* #define HAVE_TERMIOS_H 1 */
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
@@ -829,4 +829,4 @@ typedef unsigned long long os_off_t;
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
-#endif // __CONFIG_OS2_H__
+#endif /* __CONFIG_OS2_H__ */
diff --git a/include/config-win.h b/include/config-win.h
index 4e4088f07dd..c0d0dad894e 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Defines for Win32 to make it compatible for MySQL */
@@ -25,14 +24,14 @@
#include <malloc.h>
#if defined(__NT__)
-#define SYSTEM_TYPE "NT"
+#define SYSTEM_TYPE "NT"
#elif defined(__WIN2000__)
-#define SYSTEM_TYPE "WIN2000"
+#define SYSTEM_TYPE "WIN2000"
#else
-#define SYSTEM_TYPE "Win95/Win98"
+#define SYSTEM_TYPE "Win95/Win98"
#endif
-#ifdef _WIN64
+#if defined(_WIN64) || defined(WIN64)
#define MACHINE_TYPE "ia64" /* Define to machine type name */
#else
#define MACHINE_TYPE "i32" /* Define to machine type name */
@@ -44,23 +43,23 @@
#endif
#endif /* _WIN64 */
#ifndef __WIN__
-#define __WIN__ /* To make it easier in VC++ */
+#define __WIN__ /* To make it easier in VC++ */
#endif
/* File and lock constants */
-#define O_SHARE 0x1000 /* Open file in sharing mode */
+#define O_SHARE 0x1000 /* Open file in sharing mode */
#ifdef __BORLANDC__
-#define F_RDLCK LK_NBLCK /* read lock */
-#define F_WRLCK LK_NBRLCK /* write lock */
-#define F_UNLCK LK_UNLCK /* remove lock(s) */
+#define F_RDLCK LK_NBLCK /* read lock */
+#define F_WRLCK LK_NBRLCK /* write lock */
+#define F_UNLCK LK_UNLCK /* remove lock(s) */
#else
-#define F_RDLCK _LK_NBLCK /* read lock */
-#define F_WRLCK _LK_NBRLCK /* write lock */
-#define F_UNLCK _LK_UNLCK /* remove lock(s) */
+#define F_RDLCK _LK_NBLCK /* read lock */
+#define F_WRLCK _LK_NBRLCK /* write lock */
+#define F_UNLCK _LK_UNLCK /* remove lock(s) */
#endif
-#define F_EXCLUSIVE 1 /* We have only exclusive locking */
-#define F_TO_EOF (INT_MAX32/2) /* size for lock of all file */
+#define F_EXCLUSIVE 1 /* We have only exclusive locking */
+#define F_TO_EOF (INT_MAX32/2) /* size for lock of all file */
#define F_OK 0 /* parameter to access() */
#define S_IROTH S_IREAD /* for my_lib */
@@ -71,15 +70,15 @@
#define O_SHORT_LIVED 0
#define SH_DENYNO _SH_DENYNO
#else
-#define O_BINARY _O_BINARY /* compability with MSDOS */
-#define FILE_BINARY _O_BINARY /* my_fopen in binary mode */
-#define O_TEMPORARY _O_TEMPORARY
-#define O_SHORT_LIVED _O_SHORT_LIVED
-#define SH_DENYNO _SH_DENYNO
+#define O_BINARY _O_BINARY /* compability with MSDOS */
+#define FILE_BINARY _O_BINARY /* my_fopen in binary mode */
+#define O_TEMPORARY _O_TEMPORARY
+#define O_SHORT_LIVED _O_SHORT_LIVED
+#define SH_DENYNO _SH_DENYNO
#endif
#define NO_OPEN_3 /* For my_create() */
-#define SIGQUIT SIGTERM /* No SIGQUIT */
+#define SIGQUIT SIGTERM /* No SIGQUIT */
#undef _REENTRANT /* Crashes something for win32 */
#undef SAFE_MUTEX /* Can't be used on windows */
@@ -90,15 +89,15 @@
/* Type information */
-typedef unsigned short ushort;
-typedef unsigned int uint;
+typedef unsigned short ushort;
+typedef unsigned int uint;
typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
-typedef __int64 longlong;
+typedef __int64 longlong;
typedef int sigset_t;
#define longlong_defined
/* off_t should not be __int64 because of conflicts in header files;
Use my_off_t or os_off_t instead */
-typedef long off_t;
+typedef long off_t;
typedef __int64 os_off_t;
#ifdef _WIN64
typedef UINT_PTR rf_SetTimer;
@@ -110,7 +109,7 @@ typedef uint rf_SetTimer;
#define Socket_defined
#define my_socket SOCKET
#define bool BOOL
-#define SIGPIPE SIGINT
+#define SIGPIPE SIGINT
#define RETQSORTTYPE void
#define QSORT_TYPE_IS_VOID
#define RETSIGTYPE void
@@ -119,7 +118,9 @@ typedef uint rf_SetTimer;
#define bool_defined
#define byte_defined
#define HUGE_PTR
-#define STDCALL __stdcall /* Used by libmysql.dll */
+#define STDCALL __stdcall /* Used by libmysql.dll */
+#define isnan(X) _isnan(X)
+#define finite(X) _finite(X)
#ifndef UNDEF_THREAD_HACK
#define THREAD
@@ -138,7 +139,7 @@ typedef uint rf_SetTimer;
#define USE_MB 1
#define USE_MB_IDENT 1
#define USE_STRCOLL 1
-
+
/* Convert some simple functions to Posix */
#define sigset(A,B) signal((A),(B))
@@ -202,7 +203,7 @@ inline double ulonglong2double(ulonglong value)
(((uint32) ((uchar) (A)[1])) << 8) +\
(((uint32) ((uchar) (A)[2])) << 16) +\
(((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) ((uchar) (A)[4])) << 32))
+ (((ulonglong) ((uchar) (A)[4])) << 32))
#define uint8korr(A) (*((ulonglong *) (A)))
#define sint8korr(A) (*((longlong *) (A)))
#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
@@ -248,12 +249,16 @@ inline double ulonglong2double(ulonglong value)
#define HAVE_FLOAT_H
#define HAVE_LIMITS_H
#define HAVE_STDDEF_H
-#define HAVE_RINT /* defined in this file */
-#define NO_FCNTL_NONBLOCK /* No FCNTL */
+#define HAVE_RINT /* defined in this file */
+#define NO_FCNTL_NONBLOCK /* No FCNTL */
#define HAVE_ALLOCA
#define HAVE_STRPBRK
#define HAVE_STRSTR
#define HAVE_COMPRESS
+#define HAVE_CREATESEMAPHORE
+#define HAVE_ISNAN
+#define HAVE_FINITE
+#define HAVE_ISAM /* We want to have support for ISAM in 4.0 */
#ifdef NOT_USED
#define HAVE_SNPRINTF /* Gave link error */
@@ -274,8 +279,8 @@ inline double ulonglong2double(ulonglong value)
#ifdef _CUSTOMCONFIG_
#include <custom_conf.h>
#else
-#define DEFAULT_MYSQL_HOME "c:\\mysql"
-#define PACKAGE "mysql"
+#define DEFAULT_MYSQL_HOME "c:\\mysql"
+#define PACKAGE "mysql"
#define DEFAULT_BASEDIR "C:\\"
#define SHAREDIR "share"
#define DEFAULT_CHARSET_HOME "C:/mysql/"
@@ -301,6 +306,6 @@ inline double ulonglong2double(ulonglong value)
pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L));
#define thread_safe_sub(V,C,L) \
pthread_mutex_lock((L)); (V)-=(C); pthread_mutex_unlock((L));
-#define statistic_add(V,C,L) (V)+=(C)
+#define statistic_add(V,C,L) (V)+=(C)
#endif
#define statistic_increment(V,L) thread_safe_increment((V),(L))
diff --git a/include/dbug.h b/include/dbug.h
index 3c86cbb8ac2..5c88e2e42db 100644
--- a/include/dbug.h
+++ b/include/dbug.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _dbug_h
#define _dbug_h
diff --git a/include/errmsg.h b/include/errmsg.h
index 8087c526937..76a57f47611 100644
--- a/include/errmsg.h
+++ b/include/errmsg.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Error messages for mysql clients */
/* error messages for the demon is in share/language/errmsg.sys */
@@ -57,3 +56,8 @@ extern const char *client_errors[]; /* Error messages */
#define CR_NAMEDPIPESETSTATE_ERROR 2018
#define CR_CANT_READ_CHARSET 2019
#define CR_NET_PACKET_TOO_LARGE 2020
+#define CR_EMBEDDED_CONNECTION 2021
+#define CR_PROBE_SLAVE_STATUS 2022
+#define CR_PROBE_SLAVE_HOSTS 2023
+#define CR_PROBE_SLAVE_CONNECT 2024
+#define CR_PROBE_MASTER_CONNECT 2025
diff --git a/include/ft_global.h b/include/ft_global.h
index 3937bd87c7f..449cc57729f 100644
--- a/include/ft_global.h
+++ b/include/ft_global.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,29 +27,38 @@ extern "C" {
#endif
#define FT_QUERY_MAXLEN 1024
+#define HA_FT_MAXLEN 254
-typedef struct ft_doc_rec {
- my_off_t dpos;
- double weight;
-} FT_DOC;
+typedef struct st_ft_info FT_INFO;
+struct _ft_vft
+{
+ int (*read_next)(FT_INFO *, char *);
+ float (*find_relevance)(FT_INFO *, byte *, uint);
+ void (*close_search)(FT_INFO *);
+ float (*get_relevance)(FT_INFO *);
+ void (*reinit_search)(FT_INFO *);
+};
-typedef struct st_ft_doclist {
- int ndocs;
- int curdoc;
- void *info; /* actually (MI_INFO *) but don't want to include myisam.h */
- FT_DOC doc[1];
-} FT_DOCLIST;
+#ifndef FT_CORE
+struct st_ft_info
+{
+ struct _ft_vft *please; /* INTERCAL style :-) */
+};
+#endif
extern const char *ft_precompiled_stopwords[];
+extern ulong ft_min_word_len;
+extern ulong ft_max_word_len;
+extern ulong ft_max_word_len_for_sort;
+extern const char *ft_boolean_syntax;
+
int ft_init_stopwords(const char **);
void ft_free_stopwords(void);
-FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool);
-int ft_read_next(FT_DOCLIST *, char *);
-#define ft_close_search(handler) my_free(((gptr)(handler)),MYF(0))
-#define ft_get_relevance(handler) ((handler)->doc[(handler)->curdoc].weight)
-#define ft_reinit_search(handler) (((FT_DOCLIST *)(handler))->curdoc=-1)
+#define FT_NL 0
+#define FT_BOOL 1
+FT_INFO *ft_init_search(uint,void *, uint, byte *, uint, my_bool);
#ifdef __cplusplus
}
diff --git a/include/getopt.h b/include/getopt.h
deleted file mode 100644
index 790915b97df..00000000000
--- a/include/getopt.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Declarations for getopt.
- Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#ifndef _GETOPT_H
-#define _GETOPT_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
-struct option
-{
-#if defined (__STDC__) && __STDC__ || defined(__cplusplus)
- const char *name;
-#else
- char *name;
-#endif
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-
-#if ( defined (__STDC__) && __STDC__ ) || defined(__cplusplus) || defined(MSDOS)
-#ifdef __EMX__
-int getopt (int, char **, __const__ char *);
-#elif defined( __GNU_LIBRARY__)
-/* Many other libraries have conflicting prototypes for getopt, with
- differences in the consts, in stdlib.h. To avoid compilation
- errors, only prototype getopt for the GNU C library. */
-extern int getopt (int argc, char *const *argv, const char *shortopts);
-#else /* not __GNU_LIBRARY__ */
-extern int getopt (int argc, char *const *argv, const char *optstring);
-#endif /* __GNU_LIBRARY__ */
-extern int getopt_long (int argc, char *const *argv, const char *shortopts,
- const struct option *longopts, int *longind);
-extern int getopt_long_only (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind);
-
-/* Internal only. Users should not call this directly. */
-extern int _getopt_internal (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind,
- int long_only);
-#else /* not __STDC__ */
-extern int getopt ();
-extern int getopt_long ();
-extern int getopt_long_only ();
-
-extern int _getopt_internal ();
-#endif /* __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GETOPT_H */
diff --git a/include/global.h b/include/global.h
deleted file mode 100644
index 61e00df375d..00000000000
--- a/include/global.h
+++ /dev/null
@@ -1,968 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* This is the main include file that should included 'first' in every
- C file. */
-
-#ifndef _global_h
-#define _global_h
-
-#if defined( __EMX__) && !defined( MYSQL_SERVER)
-/* moved here to use below VOID macro redefinition */
-#define INCL_BASE
-#define INCL_NOPMAPI
-#include <os2.h>
-#endif /* __EMX__ */
-
-#ifdef __CYGWIN__
-/* We use a Unix API, so pretend it's not Windows */
-#undef WIN
-#undef WIN32
-#undef _WIN
-#undef _WIN32
-#undef _WIN64
-#undef __WIN__
-#undef __WIN32__
-#define HAVE_ERRNO_AS_DEFINE
-#endif /* __CYGWIN__ */
-
-
-#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
-#include <config-win.h>
-#elif defined(OS2)
-#include <config-os2.h>
-#else
-#include <my_config.h>
-#if defined(__cplusplus) && defined(inline)
-#undef inline /* fix configure problem */
-#endif
-#endif /* _WIN32... */
-
-/* Fix problem with S_ISLNK() on Linux */
-#if defined(HAVE_LINUXTHREADS)
-#undef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#endif
-
-/* The client defines this to avoid all thread code */
-#if defined(UNDEF_THREADS_HACK)
-#undef THREAD
-#undef HAVE_mit_thread
-#undef HAVE_LINUXTHREADS
-#undef HAVE_UNIXWARE7_THREADS
-#endif
-
-#ifdef HAVE_THREADS_WITHOUT_SOCKETS
-/* MIT pthreads does not work with unix sockets */
-#undef HAVE_SYS_UN_H
-#endif
-
-#define __EXTENSIONS__ 1 /* We want some extension */
-#ifndef __STDC_EXT__
-#define __STDC_EXT__ 1 /* To get large file support on hpux */
-#endif
-
-#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
-#endif
-/* was #if defined(HAVE_LINUXTHREADS) || defined(HAVE_DEC_THREADS) || defined(HPUX) */
-#if !defined(SCO)
-#define _REENTRANT 1 /* Some thread libraries require this */
-#endif
-#if !defined(_THREAD_SAFE) && !defined(_AIX)
-#define _THREAD_SAFE /* Required for OSF1 */
-#endif
-#ifndef HAVE_mit_thread
-#ifdef HAVE_UNIXWARE7_THREADS
-#include <thread.h>
-#else
-#include <pthread.h> /* AIX must have this included first */
-#endif /* HAVE_UNIXWARE7_THREADS */
-#endif /* HAVE_mit_thread */
-#if !defined(SCO) && !defined(_REENTRANT)
-#define _REENTRANT 1 /* Threads requires reentrant code */
-#endif
-#endif /* THREAD */
-
-/* Go around some bugs in different OS and compilers */
-#ifdef _AIX /* By soren@t.dk */
-#define _H_STRINGS
-#define _SYS_STREAM_H
-#define _AIX32_CURSES
-#endif
-
-#ifdef HAVE_BROKEN_SNPRINTF /* HPUX 10.20 don't have this defined */
-#undef HAVE_SNPRINTF
-#endif
-#ifdef HAVE_BROKEN_PREAD /* These doesn't work on HPUX 11.x */
-#undef HAVE_PREAD
-#undef HAVE_PWRITE
-#endif
-
-#ifdef UNDEF_HAVE_GETHOSTBYNAME_R /* For OSF4.x */
-#undef HAVE_GETHOSTBYNAME_R
-#endif
-#ifdef UNDEF_HAVE_INITGROUPS /* For AIX 4.3 */
-#undef HAVE_INITGROUPS
-#endif
-
-/* Fix a bug in gcc 2.8.0 on IRIX 6.2 */
-#if SIZEOF_LONG == 4 && defined(__LONG_MAX__)
-#undef __LONG_MAX__ /* Is a longlong value in gcc 2.8.0 ??? */
-#define __LONG_MAX__ 2147483647
-#endif
-
-/* egcs 1.1.2 has a problem with memcpy on Alpha */
-#if defined(__GNUC__) && defined(__alpha__) && ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
-#define BAD_MEMCPY
-#endif
-
-/* In Linux-alpha we have atomic.h if we are using gcc */
-#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95)) && !defined(HAVE_ATOMIC_ADD)
-#define HAVE_ATOMIC_ADD
-#define HAVE_ATOMIC_SUB
-#endif
-
-/* In Linux-ia64 including atomic.h will give us an error */
-#if (defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && (defined(__ia64__) || defined(__powerpc64__))) || !defined(THREAD)
-#undef HAVE_ATOMIC_ADD
-#undef HAVE_ATOMIC_SUB
-#endif
-
-#if defined(_lint) && !defined(lint)
-#define lint
-#endif
-#if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
-#define _LONG_LONG 1 /* For AIX string library */
-#endif
-
-#ifndef stdin
-#include <stdio.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STDDEF_H
-#include <stddef.h>
-#endif
-
-#include <math.h>
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_FLOAT_H
-#include <float.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_TIMEB_H
-#include <sys/timeb.h> /* Avoid warnings on SCO */
-#endif
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif /* TIME_WITH_SYS_TIME */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA)
-#undef HAVE_ALLOCA
-#undef HAVE_ALLOCA_H
-#endif
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-#ifdef HAVE_ATOMIC_ADD
-#define __SMP__
-#define CONFIG_SMP
-#include <asm/atomic.h>
-#endif
-
-/* Go around some bugs in different OS and compilers */
-#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
-#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */
-#define HAVE_ULONG
-#endif
-#ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */
-#undef HAVE_FINITE
-#endif
-#if defined(HPUX) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
-/* Fix bug in setrlimit */
-#undef setrlimit
-#define setrlimit cma_setrlimit64
-#endif
-
-/* We can not live without these */
-
-#define USE_MYFUNC 1 /* Must use syscall indirection */
-#define MASTER 1 /* Compile without unireg */
-#define ENGLISH 1 /* Messages in English */
-#define POSIX_MISTAKE 1 /* regexp: Fix stupid spec error */
-#define USE_REGEX 1 /* We want the use the regex library */
-/* Do not define for ultra sparcs */
-#ifndef OS2
-#define USE_BMOVE512 1 /* Use this unless the system bmove is faster */
-#endif
-
-/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
-#ifdef I_AM_PARANOID
-#define DONT_ALLOW_USER_CHANGE 1
-#define DONT_USE_MYSQL_PWD 1
-#endif
-
-/* #define USE_some_charset 1 was deprecated by changes to configure */
-/* my_ctype my_to_upper, my_to_lower, my_sort_order gain theit right value */
-/* automagically during configuration */
-
-/* Does the system remember a signal handler after a signal ? */
-#ifndef HAVE_BSD_SIGNALS
-#define DONT_REMEMBER_SIGNAL
-#endif
-
-/* Define void to stop lint from generating "null effekt" comments */
-#ifndef DONT_DEFINE_VOID
-#ifdef _lint
-int __void__;
-#define VOID(X) (__void__ = (int) (X))
-#else
-#undef VOID
-#define VOID(X) (X)
-#endif
-#endif /* DONT_DEFINE_VOID */
-
-#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
-#define LINT_INIT(var) var=0 /* No uninitialize-warning */
-#else
-#define LINT_INIT(var)
-#endif
-
-/* Define som useful general macros */
-#if defined(__cplusplus) && defined(__GNUC__)
-#define max(a, b) ((a) >? (b))
-#define min(a, b) ((a) <? (b))
-#elif !defined(max)
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-#if defined(__EMX__) || !defined(HAVE_UINT)
-typedef unsigned int uint;
-typedef unsigned short ushort;
-#endif
-
-#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
-#define swap(t,a,b) { register t dummy; dummy = a; a = b; b = dummy; }
-#define test(a) ((a) ? 1 : 0)
-#define set_if_bigger(a,b) { if ((a) < (b)) (a)=(b); }
-#define set_if_smaller(a,b) { if ((a) > (b)) (a)=(b); }
-#define test_all_bits(a,b) (((a) & (b)) == (b))
-#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1))
-#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
-#ifndef HAVE_RINT
-#define rint(A) floor((A)+0.5)
-#endif
-
-/* Define som general constants */
-#ifndef TRUE
-#define TRUE (1) /* Logical true */
-#define FALSE (0) /* Logical false */
-#endif
-
-#if defined(__GNUC__)
-#define function_volatile volatile
-#define my_reinterpret_cast(A) reinterpret_cast<A>
-#define my_const_cast(A) const_cast<A>
-#elif !defined(my_reinterpret_cast)
-#define my_reinterpret_cast(A) (A)
-#define my_const_cast(A) (A)
-#endif
-#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
-#define __attribute__(A)
-#endif
-
-/* From old s-system.h */
-
-/* Support macros for non ansi & other old compilers. Since such
- things are no longer supported we do nothing. We keep then since
- some of our code may still be needed to upgrade old customers. */
-#define _VARARGS(X) X
-#define _STATIC_VARARGS(X) X
-#define _PC(X) X
-
-#if defined(DBUG_ON) && defined(DBUG_OFF)
-#undef DBUG_OFF
-#endif
-
-#if defined(_lint) && !defined(DBUG_OFF)
-#define DBUG_OFF
-#endif
-
-#include <dbug.h>
-#ifndef DBUG_OFF
-#define dbug_assert(A) assert(A)
-#else
-#define dbug_assert(A)
-#endif
-
-#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
-#define ASCII_BITS_USED 8 /* Bit char used */
-#define NEAR_F /* No near function handling */
-
-/* Some types that is different between systems */
-
-typedef int File; /* File descriptor */
-#ifndef Socket_defined
-typedef int my_socket; /* File descriptor for sockets */
-#define INVALID_SOCKET -1
-#endif
-/* Type for fuctions that handles signals */
-#define sig_handler RETSIGTYPE
-typedef void (*sig_return)();/* Returns type from signal */
-#if defined(__GNUC__) && !defined(_lint)
-typedef char pchar; /* Mixed prototypes can take char */
-typedef char puchar; /* Mixed prototypes can take char */
-typedef char pbool; /* Mixed prototypes can take char */
-typedef short pshort; /* Mixed prototypes can take short int */
-typedef float pfloat; /* Mixed prototypes can take float */
-#else
-typedef int pchar; /* Mixed prototypes can't take char */
-typedef uint puchar; /* Mixed prototypes can't take char */
-typedef int pbool; /* Mixed prototypes can't take char */
-typedef int pshort; /* Mixed prototypes can't take short int */
-typedef double pfloat; /* Mixed prototypes can't take float */
-#endif
-typedef int (*qsort_cmp)(const void *,const void *);
-#ifdef HAVE_mit_thread
-#define qsort_t void
-#undef QSORT_TYPE_IS_VOID
-#define QSORT_TYPE_IS_VOID
-#else
-#define qsort_t RETQSORTTYPE /* Broken GCC cant handle typedef !!!! */
-#endif
-#ifdef HAVE_mit_thread
-#define size_socket socklen_t /* Type of last arg to accept */
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-typedef SOCKET_SIZE_TYPE size_socket;
-#endif
-
-#ifndef SOCKOPT_OPTLEN_TYPE
-#define SOCKOPT_OPTLEN_TYPE size_socket
-#endif
-
-/* file create flags */
-
-#ifndef O_SHARE
-#define O_SHARE 0 /* Flag to my_open for shared files */
-#ifndef O_BINARY
-#define O_BINARY 0 /* Flag to my_open for binary files */
-#endif
-#define FILE_BINARY 0 /* Flag to my_fopen for binary streams */
-#ifdef HAVE_FCNTL
-#define HAVE_FCNTL_LOCK
-#define F_TO_EOF 0L /* Param to lockf() to lock rest of file */
-#endif
-#endif /* O_SHARE */
-#ifndef O_TEMPORARY
-#define O_TEMPORARY 0
-#endif
-#ifndef O_SHORT_LIVED
-#define O_SHORT_LIVED 0
-#endif
-
-/* #define USE_RECORD_LOCK */
-
- /* Unsigned types supported by the compiler */
-#define UNSINT8 /* unsigned int8 (char) */
-#define UNSINT16 /* unsigned int16 */
-#define UNSINT32 /* unsigned int32 */
-
- /* General constants */
-#define SC_MAXWIDTH 256 /* Max width of screen (for error messages) */
-#define FN_LEN 256 /* Max file name len */
-#define FN_HEADLEN 253 /* Max length of filepart of file name */
-#define FN_EXTLEN 20 /* Max length of extension (part of FN_LEN) */
-#define FN_REFLEN 512 /* Max length of full path-name */
-#define FN_EXTCHAR '.'
-#define FN_HOMELIB '~' /* ~/ is used as abbrev for home dir */
-#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
-#define FN_PARENTDIR ".." /* Parentdirectory; Must be a string */
-#define FN_DEVCHAR ':'
-
-#ifndef FN_LIBCHAR
-#ifdef __EMX__
-#define FN_LIBCHAR '\\'
-#define FN_ROOTDIR "\\"
-#else
-#define FN_LIBCHAR '/'
-#define FN_ROOTDIR "/"
-#endif
-#define MY_NFILE 1024 /* This is only used to save filenames */
-#endif
-
-/* #define EXT_IN_LIBNAME */
-/* #define FN_NO_CASE_SENCE */
-/* #define FN_UPPER_CASE TRUE */
-
-/* Io buffer size; Must be a power of 2 and a multiple of 512. May be
- smaller what the disk page size. This influences the speed of the
- isam btree library. eg to big to slow. */
-#define IO_SIZE 4096
-/* How much overhead does malloc have. The code often allocates
- something like 1024-MALLOC_OVERHEAD bytes */
-#ifdef SAFEMALLOC
-#define MALLOC_OVERHEAD (8+24+4)
-#else
-#define MALLOC_OVERHEAD 8
-#endif
- /* get memory in huncs */
-#define ONCE_ALLOC_INIT (uint) (4096-MALLOC_OVERHEAD)
- /* Typical record cash */
-#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
- /* Typical key cash */
-#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
-
- /* Some things that this system doesn't have */
-
-#define ONLY_OWN_DATABASES /* We are using only databases by monty */
-#define NO_PISAM /* Not needed anymore */
-#define NO_MISAM /* Not needed anymore */
-#define NO_HASH /* Not needed anymore */
-#ifdef __WIN__
-#define NO_DIR_LIBRARY /* Not standar dir-library */
-#define USE_MY_STAT_STRUCT /* For my_lib */
-#endif
-
-/* Some things that this system does have */
-
-#ifndef HAVE_ITOA
-#define USE_MY_ITOA /* There is no itoa */
-#endif
-
-/* Some defines of functions for portability */
-
-#ifndef HAVE_ATOD
-#define atod atof
-#endif
-#ifdef USE_MY_ATOF
-#define atof my_atof
-extern void init_my_atof(void);
-extern double my_atof(const char*);
-#endif
-#undef remove /* Crashes MySQL on SCO 5.0.0 */
-#ifndef __WIN__
-#ifdef OS2
-#define closesocket(A) soclose(A)
-#else
-#define closesocket(A) close(A)
-#endif
-#ifndef ulonglong2double
-#define ulonglong2double(A) ((double) (A))
-#define my_off_t2double(A) ((double) (A))
-#endif
-#endif
-
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-#define ulong_to_double(X) ((double) (ulong) (X))
-#define SET_STACK_SIZE(X) /* Not needed on real machines */
-
-#if !defined(HAVE_mit_thread) && !defined(HAVE_STRTOK_R)
-#define strtok_r(A,B,C) strtok((A),(B))
-#endif
-
-#ifdef HAVE_LINUXTHREADS
-/* #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) */
-/* #define sigset(A,B) signal((A),(B)) */
-#endif
-
-/* Remove some things that mit_thread break or doesn't support */
-#if defined(HAVE_mit_thread) && defined(THREAD)
-#undef HAVE_PREAD
-#undef HAVE_REALPATH
-#undef HAVE_MLOCK
-#undef HAVE_TEMPNAM /* Use ours */
-#undef HAVE_PTHREAD_SETPRIO
-#undef HAVE_FTRUNCATE
-#undef HAVE_READLINK
-#endif
-
-/* This is from the old m-machine.h file */
-
-#if SIZEOF_LONG_LONG > 4
-#define HAVE_LONG_LONG 1
-#endif
-
-#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
-#define LONGLONG_MIN ((long long) 0x8000000000000000LL)
-#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL)
-#endif
-
-#if SIZEOF_LONG == 4
-#define INT_MIN32 (long) 0x80000000L
-#define INT_MAX32 (long) 0x7FFFFFFFL
-#define INT_MIN24 ((long) 0xff800000L)
-#define INT_MAX24 0x007fffffL
-#define INT_MIN16 ((short int) 0x8000)
-#define INT_MAX16 0x7FFF
-#define INT_MIN8 ((char) 0x80)
-#define INT_MAX8 ((char) 0x7F)
-#else /* Probably Alpha */
-#define INT_MIN32 ((long) (int) 0x80000000)
-#define INT_MAX32 ((long) (int) 0x7FFFFFFF)
-#define INT_MIN24 ((long) (int) 0xff800000)
-#define INT_MAX24 ((long) (int) 0x007fffff)
-#define INT_MIN16 ((short int) 0xffff8000)
-#define INT_MAX16 ((short int) 0x00007FFF)
-#endif
-
-/* From limits.h instead */
-#ifndef DBL_MIN
-#define DBL_MIN 4.94065645841246544e-324
-#define FLT_MIN ((float)1.40129846432481707e-45)
-#endif
-#ifndef DBL_MAX
-#define DBL_MAX 1.79769313486231470e+308
-#define FLT_MAX ((float)3.40282346638528860e+38)
-#endif
-
-/* Max size that must be added to a so that we know Size to make
- adressable obj. */
-typedef long my_ptrdiff_t;
-#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
-#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
-/* Size to make adressable obj. */
-#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A),sizeof(t)))
- /* Offset of filed f in structure t */
-#define OFFSET(t, f) ((size_t)(char *)&((t *)0)->f)
-#define ADD_TO_PTR(ptr,size,type) (type) ((byte*) (ptr)+size)
-#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((byte*) (A) - (byte*) (B))
-
-#define NullS (char *) 0
-/* Nowdays we do not support MessyDos */
-#ifndef NEAR
-#define NEAR /* Who needs segments ? */
-#define FAR /* On a good machine */
-#ifndef HUGE_PTR
-#define HUGE_PTR
-#endif
-#endif
-#if defined(__IBMC__) || defined(__IBMCPP__)
-#define STDCALL _System _Export
-#elif !defined( STDCALL)
-#define STDCALL
-#endif
-
-/* Typdefs for easyier portability */
-
-#if defined(VOIDTYPE)
-typedef void *gptr; /* Generic pointer */
-#else
-typedef char *gptr; /* Generic pointer */
-#endif
-#ifndef HAVE_INT_8_16_32
-typedef char int8; /* Signed integer >= 8 bits */
-typedef short int16; /* Signed integer >= 16 bits */
-#endif
-#ifndef HAVE_UCHAR
-typedef unsigned char uchar; /* Short for unsigned char */
-#endif
-typedef unsigned char uint8; /* Short for unsigned integer >= 8 bits */
-typedef unsigned short uint16; /* Short for unsigned integer >= 16 bits */
-
-#if SIZEOF_INT == 4
-#ifndef HAVE_INT_8_16_32
-typedef int int32;
-#endif
-typedef unsigned int uint32; /* Short for unsigned integer >= 32 bits */
-#elif SIZEOF_LONG == 4
-#ifndef HAVE_INT_8_16_32
-typedef long int32;
-#endif
-typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */
-#else
-error "Neither int or long is of 4 bytes width"
-#endif
-
-#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC)
-typedef unsigned long ulong; /* Short for unsigned long */
-#endif
-#ifndef longlong_defined
-#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8
-typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
-typedef long long int longlong;
-#else
-typedef unsigned long ulonglong; /* ulong or unsigned long long */
-typedef long longlong;
-#endif
-#endif
-
-#ifdef USE_RAID
-/* The following is done with a if to not get problems with pre-processors
- with late define evaluation */
-#if SIZEOF_OFF_T == 4
-#define SYSTEM_SIZEOF_OFF_T 4
-#else
-#define SYSTEM_SIZEOF_OFF_T 8
-#endif
-#undef SIZEOF_OFF_T
-#define SIZEOF_OFF_T 8
-#else
-#define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T
-#endif /* USE_RAID */
-
-#if SIZEOF_OFF_T > 4
-typedef ulonglong my_off_t;
-#else
-typedef unsigned long my_off_t;
-#endif
-#define MY_FILEPOS_ERROR (~(my_off_t) 0)
-#if !defined(__WIN__) && !defined(OS2)
-typedef off_t os_off_t;
-#endif
-
-#if defined(__WIN__)
-#define socket_errno WSAGetLastError()
-#define SOCKET_EINTR WSAEINTR
-#define SOCKET_EAGAIN WSAEINPROGRESS
-#define SOCKET_ENFILE ENFILE
-#define SOCKET_EMFILE EMFILE
-#elif defined(OS2)
-#define socket_errno sock_errno()
-#define SOCKET_EINTR SOCEINTR
-#define SOCKET_EAGAIN SOCEINPROGRESS
-#define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK
-#define SOCKET_ENFILE SOCENFILE
-#define SOCKET_EMFILE SOCEMFILE
-#define closesocket(A) soclose(A)
-#else /* Unix */
-#define socket_errno errno
-#define closesocket(A) close(A)
-#define SOCKET_EINTR EINTR
-#define SOCKET_EAGAIN EAGAIN
-#define SOCKET_EWOULDBLOCK EWOULDBLOCK
-#define SOCKET_ENFILE ENFILE
-#define SOCKET_EMFILE EMFILE
-#endif
-
-typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */
-typedef short int15; /* Most effective integer 0 <= x <= 32767 */
-typedef char *my_string; /* String of characters */
-typedef unsigned long size_s; /* Size of strings (In string-funcs) */
-typedef int myf; /* Type of MyFlags in my_funcs */
-#ifndef byte_defined
-typedef char byte; /* Smallest addressable unit */
-#endif
-typedef char my_bool; /* Small bool */
-#if !defined(bool) && !defined(bool_defined) && (!defined(HAVE_BOOL) || !defined(__cplusplus))
-typedef char bool; /* Ordinary boolean values 0 1 */
-#endif
- /* Macros for converting *constants* to the right type */
-#define INT8(v) (int8) (v)
-#define INT16(v) (int16) (v)
-#define INT32(v) (int32) (v)
-#define MYF(v) (myf) (v)
-
-/* Defines to make it possible to prioritize register assignments. No
- longer needed with moder compilers */
-#ifndef USING_X
-#define reg1 register
-#define reg2 register
-#define reg3 register
-#define reg4 register
-#define reg5 register
-#define reg6 register
-#define reg7 register
-#define reg8 register
-#define reg9 register
-#define reg10 register
-#define reg11 register
-#define reg12 register
-#define reg13 register
-#define reg14 register
-#define reg15 register
-#define reg16 register
-#endif
-
-/* Defines for time function */
-#define SCALE_SEC 100
-#define SCALE_USEC 10000
-#define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */
-#define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */
-
-/*
-** Define-funktions for reading and storing in machine independent format
-** (low byte first)
-*/
-
-/* Optimized store functions for Intel x86 */
-#ifdef __i386__
-#define sint2korr(A) (*((int16 *) (A)))
-#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
- (((uint32) 255L << 24) | \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])) : \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])))
-#define sint4korr(A) (*((long *) (A)))
-#define uint2korr(A) (*((uint16 *) (A)))
-#define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF)
-#define uint4korr(A) (*((unsigned long *) (A)))
-#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) ((uchar) (A)[4])) << 32))
-#define uint8korr(A) (*((ulonglong *) (A)))
-#define sint8korr(A) (*((longlong *) (A)))
-#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
-#define int3store(T,A) { *(T)= (uchar) ((A));\
- *(T+1)=(uchar) (((uint) (A) >> 8));\
- *(T+2)=(uchar) (((A) >> 16)); }
-#define int4store(T,A) *((long *) (T))= (long) (A)
-#define int5store(T,A) { *(T)= (uchar)((A));\
- *((T)+1)=(uchar) (((A) >> 8));\
- *((T)+2)=(uchar) (((A) >> 16));\
- *((T)+3)=(uchar) (((A) >> 24)); \
- *((T)+4)=(uchar) (((A) >> 32)); }
-#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
-
-typedef union {
- double v;
- long m[2];
-} doubleget_union;
-#define doubleget(V,M) { ((doubleget_union *)&V)->m[0] = *((long*) M); \
- ((doubleget_union *)&V)->m[1] = *(((long*) M)+1); }
-#define doublestore(T,V) { *((long *) T) = ((doubleget_union *)&V)->m[0]; \
- *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; }
-#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); }
-#define float8get(V,M) doubleget((V),(M))
-#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
-#define float8store(V,M) doublestore((V),(M))
-#endif /* __i386__ */
-
-#ifndef sint2korr
-#define sint2korr(A) (int16) (((int16) ((uchar) (A)[0])) +\
- ((int16) ((int16) (A)[1]) << 8))
-#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
- (((uint32) 255L << 24) | \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])) : \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])))
-#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) +\
- (((int32) ((uchar) (A)[1]) << 8)) +\
- (((int32) ((uchar) (A)[2]) << 16)) +\
- (((int32) ((int16) (A)[3]) << 24)))
-#define sint8korr(A) (longlong) uint8korr(A)
-#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) +\
- ((uint16) ((uchar) (A)[1]) << 8))
-#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16))
-#define uint4korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24))
-#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) ((uchar) (A)[4])) << 32))
-#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) (((uint32) ((uchar) (A)[4])) +\
- (((uint32) ((uchar) (A)[5])) << 8) +\
- (((uint32) ((uchar) (A)[6])) << 16) +\
- (((uint32) ((uchar) (A)[7])) << 24))) <<\
- 32))
-#define int2store(T,A) { uint def_temp= (uint) (A) ;\
- *((uchar*) (T))= (uchar)(def_temp); \
- *((uchar*) (T+1))=(uchar)((def_temp >> 8)); }
-#define int3store(T,A) { /*lint -save -e734 */\
- *((T))=(char) ((A));\
- *((T)+1)=(char) (((A) >> 8));\
- *((T)+2)=(char) (((A) >> 16)); \
- /*lint -restore */}
-#define int4store(T,A) { *(T)=(char) ((A));\
- *((T)+1)=(char) (((A) >> 8));\
- *((T)+2)=(char) (((A) >> 16));\
- *((T)+3)=(char) (((A) >> 24)); }
-#define int5store(T,A) { *(T)=((A));\
- *((T)+1)=(((A) >> 8));\
- *((T)+2)=(((A) >> 16));\
- *((T)+3)=(((A) >> 24)); \
- *((T)+4)=(((A) >> 32)); }
-#define int8store(T,A) { uint def_temp= (uint) (A), def_temp2= (uint) ((A) >> 32); \
- int4store((T),def_temp); \
- int4store((T+4),def_temp2); \
- }
-#ifdef WORDS_BIGENDIAN
-#define float4store(T,A) { *(T)= ((byte *) &A)[3];\
- *((T)+1)=(char) ((byte *) &A)[2];\
- *((T)+2)=(char) ((byte *) &A)[1];\
- *((T)+3)=(char) ((byte *) &A)[0]; }
-
-#define float4get(V,M) { float def_temp;\
- ((byte*) &def_temp)[0]=(M)[3];\
- ((byte*) &def_temp)[1]=(M)[2];\
- ((byte*) &def_temp)[2]=(M)[1];\
- ((byte*) &def_temp)[3]=(M)[0];\
- (V)=def_temp; }
-#define float8store(T,V) { *(T)= ((byte *) &V)[7];\
- *((T)+1)=(char) ((byte *) &V)[6];\
- *((T)+2)=(char) ((byte *) &V)[5];\
- *((T)+3)=(char) ((byte *) &V)[4];\
- *((T)+4)=(char) ((byte *) &V)[3];\
- *((T)+5)=(char) ((byte *) &V)[2];\
- *((T)+6)=(char) ((byte *) &V)[1];\
- *((T)+7)=(char) ((byte *) &V)[0]; }
-
-#define float8get(V,M) { double def_temp;\
- ((byte*) &def_temp)[0]=(M)[7];\
- ((byte*) &def_temp)[1]=(M)[6];\
- ((byte*) &def_temp)[2]=(M)[5];\
- ((byte*) &def_temp)[3]=(M)[4];\
- ((byte*) &def_temp)[4]=(M)[3];\
- ((byte*) &def_temp)[5]=(M)[2];\
- ((byte*) &def_temp)[6]=(M)[1];\
- ((byte*) &def_temp)[7]=(M)[0];\
- (V) = def_temp; }
-#else
-#define float4get(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float))
-#define float4store(V,M) memcpy_fixed((byte*) V,(byte*) (&M),sizeof(float))
-
-#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
-#define doublestore(T,V) { *(T)= ((byte *) &V)[4];\
- *((T)+1)=(char) ((byte *) &V)[5];\
- *((T)+2)=(char) ((byte *) &V)[6];\
- *((T)+3)=(char) ((byte *) &V)[7];\
- *((T)+4)=(char) ((byte *) &V)[0];\
- *((T)+5)=(char) ((byte *) &V)[1];\
- *((T)+6)=(char) ((byte *) &V)[2];\
- *((T)+7)=(char) ((byte *) &V)[3]; }
-#define doubleget(V,M) { double def_temp;\
- ((byte*) &def_temp)[0]=(M)[4];\
- ((byte*) &def_temp)[1]=(M)[5];\
- ((byte*) &def_temp)[2]=(M)[6];\
- ((byte*) &def_temp)[3]=(M)[7];\
- ((byte*) &def_temp)[4]=(M)[0];\
- ((byte*) &def_temp)[5]=(M)[1];\
- ((byte*) &def_temp)[6]=(M)[2];\
- ((byte*) &def_temp)[7]=(M)[3];\
- (V) = def_temp; }
-#endif /* __FLOAT_WORD_ORDER */
-
-#define float8get(V,M) doubleget((V),(M))
-#define float8store(V,M) doublestore((V),(M))
-#endif /* WORDS_BIGENDIAN */
-
-#endif /* sint2korr */
-
-/* Define-funktions for reading and storing in machine format from/to
- short/long to/from some place in memory V should be a (not
- register) variable, M is a pointer to byte */
-
-#ifdef WORDS_BIGENDIAN
-
-#define ushortget(V,M) { V = (uint16) (((uint16) ((uchar) (M)[1]))+\
- ((uint16) ((uint16) (M)[0]) << 8)); }
-#define shortget(V,M) { V = (short) (((short) ((uchar) (M)[1]))+\
- ((short) ((short) (M)[0]) << 8)); }
-#define longget(V,M) { int32 def_temp;\
- ((byte*) &def_temp)[0]=(M)[0];\
- ((byte*) &def_temp)[1]=(M)[1];\
- ((byte*) &def_temp)[2]=(M)[2];\
- ((byte*) &def_temp)[3]=(M)[3];\
- (V)=def_temp; }
-#define ulongget(V,M) { uint32 def_temp;\
- ((byte*) &def_temp)[0]=(M)[0];\
- ((byte*) &def_temp)[1]=(M)[1];\
- ((byte*) &def_temp)[2]=(M)[2];\
- ((byte*) &def_temp)[3]=(M)[3];\
- (V)=def_temp; }
-#define shortstore(T,A) { uint def_temp=(uint) (A) ;\
- *(T+1)=(char)(def_temp); \
- *(T+0)=(char)(def_temp >> 8); }
-#define longstore(T,A) { *((T)+3)=((A));\
- *((T)+2)=(((A) >> 8));\
- *((T)+1)=(((A) >> 16));\
- *((T)+0)=(((A) >> 24)); }
-
-#define doubleget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(double))
-#define doublestore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(double))
-#define longlongget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(ulonglong))
-#define longlongstore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(ulonglong))
-
-#else
-
-#define ushortget(V,M) { V = uint2korr(M); }
-#define shortget(V,M) { V = sint2korr(M); }
-#define longget(V,M) { V = sint4korr(M); }
-#define ulongget(V,M) { V = uint4korr(M); }
-#define shortstore(T,V) int2store(T,V)
-#define longstore(T,V) int4store(T,V)
-#ifndef doubleget
-#define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
-#define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
-#endif /* doubleget */
-#define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
-#define longlongstore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(ulonglong))
-
-#endif /* WORDS_BIGENDIAN */
-
-/* sprintf does not always return the number of bytes :- */
-#ifdef SPRINTF_RETURNS_INT
-#define my_sprintf(buff,args) sprintf args
-#else
-#ifdef SPRINTF_RETURNS_PTR
-#define my_sprintf(buff,args) ((int)(sprintf args - buff))
-#else
-#define my_sprintf(buff,args) sprintf args,strlen(buff)
-#endif
-#endif
-
-#ifndef THREAD
-#define thread_safe_increment(V,L) (V)++
-#define thread_safe_add(V,C,L) (V)+=(C)
-#define thread_safe_sub(V,C,L) (V)-=(C)
-#define statistic_increment(V,L) (V)++
-#define statistic_add(V,C,L) (V)+=(C)
-#endif
-
-#endif /* _global_h */
diff --git a/include/hash.h b/include/hash.h
index 2f6a424fb3c..e9c8c73c05b 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Dynamic hashing of record with different key-length */
@@ -55,6 +54,7 @@ gptr hash_next(HASH *info,const byte *key,uint length);
my_bool hash_insert(HASH *info,const byte *data);
my_bool hash_delete(HASH *hash,byte *record);
my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length);
+void hash_replace(HASH *hash, uint idx, byte *new_row);
my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
diff --git a/include/heap.h b/include/heap.h
index 14698810297..02b04e2b3ec 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using heap_database_funktions */
/* Author: Michael Widenius */
@@ -79,11 +78,13 @@ typedef struct st_hp_keyseg /* Key-portion */
uint start; /* Start of key in record (from 0) */
uint length; /* Keylength */
uint type;
+ uint null_bit; /* bit set in row+null_pos */
+ uint null_pos;
} HP_KEYSEG;
typedef struct st_hp_keydef /* Key definition with open */
{
- uint flag; /* NOSAME */
+ uint flag; /* HA_NOSAME | HA_NULL_PART_KEY */
uint keysegs; /* Number of key-segment */
uint length; /* Length of key (automatic) */
HP_KEYSEG *seg;
@@ -109,6 +110,7 @@ typedef struct st_heap_share
THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */
#endif
+ my_bool delete_on_close;
LIST open_list;
} HP_SHARE;
@@ -144,7 +146,7 @@ extern int heap_scan(register HP_INFO *info, byte *record);
extern int heap_delete(HP_INFO *info,const byte *buff);
extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
extern int heap_create(const char *name);
-extern int heap_delete_all(const char *name);
+extern int heap_delete_table(const char *name);
extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
extern int heap_rename(const char *old_name,const char *new_name);
extern int heap_panic(enum ha_panic_function flag);
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 645c07b79ae..fc983d1d580 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
A better inplementation of the UNIX ctype(3) library.
- Notes: global.h should be included before ctype.h
+ Notes: my_global.h should be included before ctype.h
*/
#ifndef _m_ctype_h
@@ -57,13 +56,12 @@ extern CHARSET_INFO *default_charset_info;
extern CHARSET_INFO *find_compiled_charset(uint cs_number);
extern CHARSET_INFO *find_compiled_charset_by_name(const char *name);
extern CHARSET_INFO compiled_charsets[];
+extern uint compiled_charset_number(const char *name);
+extern const char *compiled_charset_name(uint charset_number);
#define MY_CHARSET_UNDEFINED 0
#define MY_CHARSET_CURRENT (default_charset_info->number)
-#ifdef __WIN__
-#include <ctype.h>
-#endif
/* Don't include std ctype.h when this is included */
#define _CTYPE_H
#define _CTYPE_H_
@@ -71,12 +69,32 @@ extern CHARSET_INFO compiled_charsets[];
#define __CTYPE_INCLUDED
#define _CTYPE_USING /* Don't put names in global namespace. */
+/* Fix things, if ctype.h would have been included before */
+#undef toupper
+#undef _toupper
+#undef _tolower
+#undef toupper
+#undef tolower
+#undef isalpha
+#undef isupper
+#undef islower
+#undef isdigit
+#undef isxdigit
+#undef isalnum
+#undef isspace
+#undef ispunct
+#undef isprint
+#undef isgraph
+#undef iscntrl
+#undef isascii
+#undef toascii
+
#define _U 01 /* Upper case */
#define _L 02 /* Lower case */
-#define _N 04 /* Numeral (digit) */
-#define _S 010 /* Spacing character */
-#define _P 020 /* Punctuation */
-#define _C 040 /* Control character */
+#define _NMR 04 /* Numeral (digit) */
+#define _SPC 010 /* Spacing character */
+#define _PNT 020 /* Punctuation */
+#define _CTR 040 /* Control character */
#define _B 0100 /* Blank */
#define _X 0200 /* heXadecimal digit */
@@ -85,7 +103,6 @@ extern CHARSET_INFO compiled_charsets[];
#define my_to_lower (default_charset_info->to_lower)
#define my_sort_order (default_charset_info->sort_order)
-#ifndef __WIN__
#define _toupper(c) (char) my_to_upper[(uchar) (c)]
#define _tolower(c) (char) my_to_lower[(uchar) (c)]
#define toupper(c) (char) my_to_upper[(uchar) (c)]
@@ -94,14 +111,14 @@ extern CHARSET_INFO compiled_charsets[];
#define isalpha(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L))
#define isupper(c) ((my_ctype+1)[(uchar) (c)] & _U)
#define islower(c) ((my_ctype+1)[(uchar) (c)] & _L)
-#define isdigit(c) ((my_ctype+1)[(uchar) (c)] & _N)
+#define isdigit(c) ((my_ctype+1)[(uchar) (c)] & _NMR)
#define isxdigit(c) ((my_ctype+1)[(uchar) (c)] & _X)
-#define isalnum(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L | _N))
-#define isspace(c) ((my_ctype+1)[(uchar) (c)] & _S)
-#define ispunct(c) ((my_ctype+1)[(uchar) (c)] & _P)
-#define isprint(c) ((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N | _B))
-#define isgraph(c) ((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N))
-#define iscntrl(c) ((my_ctype+1)[(uchar) (c)] & _C)
+#define isalnum(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L | _NMR))
+#define isspace(c) ((my_ctype+1)[(uchar) (c)] & _SPC)
+#define ispunct(c) ((my_ctype+1)[(uchar) (c)] & _PNT)
+#define isprint(c) ((my_ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR | _B))
+#define isgraph(c) ((my_ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR))
+#define iscntrl(c) ((my_ctype+1)[(uchar) (c)] & _CTR)
#define isascii(c) (!((c) & ~0177))
#define toascii(c) ((c) & 0177)
@@ -109,19 +126,17 @@ extern CHARSET_INFO compiled_charsets[];
#undef ctype
#endif /* ctype */
-#endif /* __WIN__ */
-
#define my_isalpha(s, c) (((s)->ctype+1)[(uchar) (c)] & (_U | _L))
#define my_isupper(s, c) (((s)->ctype+1)[(uchar) (c)] & _U)
#define my_islower(s, c) (((s)->ctype+1)[(uchar) (c)] & _L)
-#define my_isdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _N)
+#define my_isdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _NMR)
#define my_isxdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _X)
-#define my_isalnum(s, c) (((s)->ctype+1)[(uchar) (c)] & (_U | _L | _N))
-#define my_isspace(s, c) (((s)->ctype+1)[(uchar) (c)] & _S)
-#define my_ispunct(s, c) (((s)->ctype+1)[(uchar) (c)] & _P)
-#define my_isprint(s, c) (((s)->ctype+1)[(uchar) (c)] & (_P | _U | _L | _N | _B))
-#define my_isgraph(s, c) (((s)->ctype+1)[(uchar) (c)] & (_P | _U | _L | _N))
-#define my_iscntrl(s, c) (((s)->ctype+1)[(uchar) (c)] & _C)
+#define my_isalnum(s, c) (((s)->ctype+1)[(uchar) (c)] & (_U | _L | _NMR))
+#define my_isspace(s, c) (((s)->ctype+1)[(uchar) (c)] & _SPC)
+#define my_ispunct(s, c) (((s)->ctype+1)[(uchar) (c)] & _PNT)
+#define my_isprint(s, c) (((s)->ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR | _B))
+#define my_isgraph(s, c) (((s)->ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR))
+#define my_iscntrl(s, c) (((s)->ctype+1)[(uchar) (c)] & _CTR)
#define use_strcoll(s) ((s)->strcoll != NULL)
#define MY_STRXFRM_MULTIPLY (default_charset_info->strxfrm_multiply)
diff --git a/include/m_string.h b/include/m_string.h
index 7eb2f1fe690..c6943613b1a 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* There may be prolems include all of theese. Try to test in
configure with ones are needed? */
@@ -132,11 +131,12 @@ extern void bzero(gptr dst,uint len);
#if !defined(bcmp) && !defined(HAVE_BCMP)
extern int bcmp(const char *s1,const char *s2,uint len);
+#endif
#ifdef HAVE_purify
extern int my_bcmp(const char *s1,const char *s2,uint len);
+#undef bcmp
#define bcmp(A,B,C) my_bcmp((A),(B),(C))
#endif
-#endif
#ifndef bmove512
extern void bmove512(gptr dst,const gptr src,uint len);
diff --git a/include/md5.h b/include/md5.h
new file mode 100644
index 00000000000..aa4116ff17f
--- /dev/null
+++ b/include/md5.h
@@ -0,0 +1,93 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+ been defined with C compiler flags.
+ */
+
+/* egcs 1.1.2 under linux didn't defined it.... :( */
+
+#ifndef PROTOTYPES
+#define PROTOTYPES 1 /* Assume prototypes */
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef uint16 UINT2; /* Fix for MySQL / Alpha */
+
+/* UINT4 defines a four byte word */
+typedef uint32 UINT4; /* Fix for MySQL / Alpha */
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+/* MD5 context. */
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} my_MD5_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void my_MD5Init PROTO_LIST ((my_MD5_CTX *));
+ void my_MD5Update PROTO_LIST
+ ((my_MD5_CTX *, unsigned char *, unsigned int));
+ void my_MD5Final PROTO_LIST ((unsigned char [16], my_MD5_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/merge.h b/include/merge.h
index c661e03a0c7..97cea5fabb1 100644
--- a/include/merge.h
+++ b/include/merge.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using merge_isam_funktions */
/* Author: Michael Widenius */
diff --git a/include/my_aes.h b/include/my_aes.h
new file mode 100644
index 00000000000..5852baa5892
--- /dev/null
+++ b/include/my_aes.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* Header file for my_aes.c */
+/* Wrapper to give simple interface for MySQL to AES standard encryption */
+
+#include "rijndael.h"
+
+C_MODE_START
+
+#define AES_KEY_LENGTH 128 /* Must be 128 192 or 256 */
+
+/*
+ my_aes_encrypt - Crypt buffer with AES encryption algorithm.
+ source - Pointer to data for encryption
+ source_length - size of encryption data
+ dest - buffer to place encrypted data (must be large enough)
+ key - Key to be used for encryption
+ kel_length - Length of the key. Will handle keys of any length
+
+ returns - size of encrypted data, or negative in case of error.
+*/
+
+int my_aes_encrypt(const char *source, int source_length, char *dest,
+ const char *key, int key_length);
+
+/*
+ my_aes_decrypt - DeCrypt buffer with AES encryption algorithm.
+ source - Pointer to data for decryption
+ source_length - size of encrypted data
+ dest - buffer to place decrypted data (must be large enough)
+ key - Key to be used for decryption
+ kel_length - Length of the key. Will handle keys of any length
+
+ returns - size of original data, or negative in case of error.
+*/
+
+
+int my_aes_decrypt(const char *source, int source_length, char *dest,
+ const char *key, int key_length);
+
+/*
+ my_aes_get_size - get size of buffer which will be large enough for encrypted
+ data
+ source_length - length of data to be encrypted
+
+ returns - size of buffer required to store encrypted data
+*/
+
+int my_aes_get_size(int source_length);
+
+C_MODE_END
diff --git a/include/my_alarm.h b/include/my_alarm.h
index b6c5ca6a3f4..fdfce9c65c9 100644
--- a/include/my_alarm.h
+++ b/include/my_alarm.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
File to include when we want to use alarm or a loop_counter to display
diff --git a/include/my_alloc.h b/include/my_alloc.h
new file mode 100644
index 00000000000..31f1fb7165f
--- /dev/null
+++ b/include/my_alloc.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Data structures for mysys/my_alloc.c (root memory allocator)
+*/
+
+#ifndef _my_alloc_h
+#define _my_alloc_h
+
+#define MAX_BLOCK_USAGE_BEFORE_DROP 10
+
+typedef struct st_used_mem
+{ /* struct for once_alloc (block) */
+ struct st_used_mem *next; /* Next block in use */
+ unsigned int left; /* memory left in block */
+ unsigned int size; /* size of block */
+} USED_MEM;
+
+
+typedef struct st_mem_root
+{
+ USED_MEM *free; /* blocks with free memory in it */
+ USED_MEM *used; /* blocks almost without free memory */
+ USED_MEM *pre_alloc; /* preallocated block */
+ /* if block have less memory it will be put in 'used' list */
+ unsigned int min_malloc;
+ unsigned int block_size; /* initial block size */
+ unsigned int block_num; /* allocated blocks counter */
+ /*
+ first free block in queue test counter (if it exceed
+ MAX_BLOCK_USAGE_BEFORE_DROP block will be droped in 'used' list)
+ */
+ unsigned int first_block_usage;
+
+ void (*error_handler)(void);
+} MEM_ROOT;
+#endif
diff --git a/include/my_base.h b/include/my_base.h
index 6275adab124..ae8fc2204d5 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file includes constants used with all databases */
/* Author: Michael Widenius */
@@ -24,7 +23,7 @@
#ifndef stdin /* Included first in handler */
#define USES_TYPES /* my_dir with sys/types is included */
#define CHSIZE_USED
-#include <global.h>
+#include <my_global.h>
#include <my_dir.h> /* This includes types */
#include <my_sys.h>
#include <m_string.h>
@@ -57,7 +56,22 @@ enum ha_rkey_function {
HA_READ_AFTER_KEY, /* Find next rec. after key-record */
HA_READ_BEFORE_KEY, /* Find next rec. before key-record */
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_UNDEF= 0, /* Not specified (old file) */
+ HA_KEY_ALG_BTREE= 1, /* B-tree, default one */
+ HA_KEY_ALG_RTREE= 2, /* R-tree, for spatial searches */
+ HA_KEY_ALG_HASH= 3, /* HASH keys (HEAP tables) */
+ HA_KEY_ALG_FULLTEXT= 4 /* FULLTEXT (MyISAM tables) */
};
/* The following is parameter to ha_extra() */
@@ -91,7 +105,10 @@ enum ha_extra_function {
HA_EXTRA_RESET_STATE, /* Reset positions */
HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/
HA_EXTRA_NO_IGNORE_DUP_KEY,
- HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE /* Cursor will not be used for update */
+ HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */
+ HA_EXTRA_BULK_INSERT_BEGIN,
+ HA_EXTRA_BULK_INSERT_END,
+ HA_EXTRA_PREPARE_FOR_DELETE
};
/* The following is parameter to ha_panic() */
@@ -134,6 +151,9 @@ enum ha_base_keytype {
#define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */
#define HA_FULLTEXT 128 /* SerG: for full-text search */
#define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */
+#define HA_SPATIAL 1024 /* Alex Barkov: for spatial search */
+#define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */
+
/* Automatic bits in key-flag */
@@ -156,6 +176,7 @@ enum ha_base_keytype {
#define HA_BLOB_PART 32
#define HA_SWAP_KEY 64
#define HA_REVERSE_SORT 128 /* Sort key in reverse order */
+#define HA_NO_SORT 256 /* do not bother sorting on this keyseg */
/* optionbits for database */
#define HA_OPTION_PACK_RECORD 1
@@ -222,6 +243,7 @@ enum ha_base_keytype {
/* Other constants */
#define HA_NAMELEN 64 /* Max length of saved filename */
+#define NO_SUCH_KEY ((uint)~0) /* used as a key no. */
/* Intern constants in databases */
@@ -235,6 +257,13 @@ enum ha_base_keytype {
#define SEARCH_UPDATE 64
#define SEARCH_PREFIX 128
#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
+#define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */
/* bits in opt_flag */
#define QUICK_USED 1
@@ -259,8 +288,8 @@ enum ha_base_keytype {
#define HA_STATE_EXTEND_BLOCK 2048
enum en_fieldtype {
- FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIPP_ENDSPACE,FIELD_SKIPP_PRESPACE,
- FIELD_SKIPP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
+ FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIP_ENDSPACE,FIELD_SKIP_PRESPACE,
+ FIELD_SKIP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
FIELD_VARCHAR,FIELD_CHECK
};
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 3243e5f0b24..ca0037addfb 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_bitmap_h_
#define _my_bitmap_h_
diff --git a/include/my_dir.h b/include/my_dir.h
index 1961ca79549..4ccda050914 100644
--- a/include/my_dir.h
+++ b/include/my_dir.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_dir_h
#define _my_dir_h
diff --git a/include/my_getopt.h b/include/my_getopt.h
new file mode 100644
index 00000000000..3b4551b445e
--- /dev/null
+++ b/include/my_getopt.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+C_MODE_START
+
+enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG,
+ GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC };
+enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
+
+struct my_option
+{
+ const char *name; /* Name of the option */
+ int id; /* unique id or short option */
+ const char *comment; /* option comment, for autom. --help */
+ gptr *value; /* The variable value */
+ gptr *u_max_value; /* The user def. max variable value */
+ const char **str_values; /* Pointer to possible values */
+ enum get_opt_var_type var_type;
+ enum get_opt_arg_type arg_type;
+ longlong def_value; /* Default value */
+ longlong min_value; /* Min allowed value */
+ longlong max_value; /* Max allowed value */
+ longlong sub_size; /* Subtract this from given value */
+ long block_size; /* Value should be a mult. of this */
+ int app_type; /* To be used by an application */
+};
+
+extern char *disabled_my_option;
+extern my_bool my_getopt_print_errors;
+
+extern int handle_options (int *argc, char ***argv,
+ const struct my_option *longopts,
+ my_bool (*get_one_option)(int,
+ const struct my_option *,
+ char *));
+extern void my_print_help(const struct my_option *options);
+extern void my_print_variables(const struct my_option *options);
+
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp);
+my_bool getopt_compare_strings(const char *s, const char *t, uint length);
+C_MODE_END
diff --git a/include/my_global.h b/include/my_global.h
new file mode 100644
index 00000000000..8dd509b9b54
--- /dev/null
+++ b/include/my_global.h
@@ -0,0 +1,1037 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* This is the include file that should be included 'first' in every C file. */
+
+#ifndef _global_h
+#define _global_h
+
+#if defined( __EMX__) && !defined( MYSQL_SERVER)
+/* moved here to use below VOID macro redefinition */
+#define INCL_BASE
+#define INCL_NOPMAPI
+#include <os2.h>
+#endif /* __EMX__ */
+
+#ifdef __CYGWIN__
+/* We use a Unix API, so pretend it's not Windows */
+#undef WIN
+#undef WIN32
+#undef _WIN
+#undef _WIN32
+#undef _WIN64
+#undef __WIN__
+#undef __WIN32__
+#define HAVE_ERRNO_AS_DEFINE
+#endif /* __CYGWIN__ */
+
+
+#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
+#include <config-win.h>
+#elif defined(OS2)
+#include <config-os2.h>
+#else
+#include <my_config.h>
+#if defined(__cplusplus) && defined(inline)
+#undef inline /* fix configure problem */
+#endif
+#endif /* _WIN32... */
+
+/*
+ The macros below are borrowed from include/linux/compiler.h in the
+ Linux kernel. Use them to indicate the likelyhood of the truthfulness
+ of a condition. This serves two purposes - newer versions of gcc will be
+ able to optimize for branch predication, which could yield siginficant
+ performance gains in frequently executed sections of the code, and the
+ other reason to use them is for documentation
+*/
+
+#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
+#define __builtin_expect(x, expected_value) (x)
+#endif
+
+#define likely(x) __builtin_expect((x),1)
+#define unlikely(x) __builtin_expect((x),0)
+
+
+/* Fix problem with S_ISLNK() on Linux */
+#if defined(HAVE_LINUXTHREADS)
+#undef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+/* The client defines this to avoid all thread code */
+#if defined(UNDEF_THREADS_HACK)
+#undef THREAD
+#undef HAVE_mit_thread
+#undef HAVE_LINUXTHREADS
+#undef HAVE_UNIXWARE7_THREADS
+#endif
+
+#ifdef HAVE_THREADS_WITHOUT_SOCKETS
+/* MIT pthreads does not work with unix sockets */
+#undef HAVE_SYS_UN_H
+#endif
+
+#define __EXTENSIONS__ 1 /* We want some extension */
+#ifndef __STDC_EXT__
+#define __STDC_EXT__ 1 /* To get large file support on hpux */
+#endif
+
+#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
+#ifndef _POSIX_PTHREAD_SEMANTICS
+#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
+#endif
+
+#if !defined(SCO)
+#define _REENTRANT 1 /* Some thread libraries require this */
+#endif
+#if !defined(_THREAD_SAFE) && !defined(_AIX)
+#define _THREAD_SAFE /* Required for OSF1 */
+#endif
+#ifndef HAVE_mit_thread
+#ifdef HAVE_UNIXWARE7_THREADS
+#include <thread.h>
+#else
+#include <pthread.h> /* AIX must have this included first */
+#endif /* HAVE_UNIXWARE7_THREADS */
+#endif /* HAVE_mit_thread */
+#if !defined(SCO) && !defined(_REENTRANT)
+#define _REENTRANT 1 /* Threads requires reentrant code */
+#endif
+#endif /* THREAD */
+
+/* Go around some bugs in different OS and compilers */
+#ifdef _AIX /* By soren@t.dk */
+#define _H_STRINGS
+#define _SYS_STREAM_H
+/* #define _AIX32_CURSES */ /* XXX: this breaks AIX 4.3.3 (others?). */
+#endif
+
+#ifdef __QNXNTO__
+#define HAVE_ERRNO_AS_DEFINE
+#define HAVE_FCNTL_LOCK
+#undef HAVE_SYS_UN_H
+#undef HAVE_FINITE
+#undef HAVE_RINT
+#endif
+
+#ifdef HAVE_BROKEN_SNPRINTF /* HPUX 10.20 don't have this defined */
+#undef HAVE_SNPRINTF
+#endif
+#ifdef HAVE_BROKEN_PREAD /* These doesn't work on HPUX 11.x */
+#undef HAVE_PREAD
+#undef HAVE_PWRITE
+#endif
+
+#ifdef UNDEF_HAVE_GETHOSTBYNAME_R /* For OSF4.x */
+#undef HAVE_GETHOSTBYNAME_R
+#endif
+#ifdef UNDEF_HAVE_INITGROUPS /* For AIX 4.3 */
+#undef HAVE_INITGROUPS
+#endif
+
+/* Fix a bug in gcc 2.8.0 on IRIX 6.2 */
+#if SIZEOF_LONG == 4 && defined(__LONG_MAX__)
+#undef __LONG_MAX__ /* Is a longlong value in gcc 2.8.0 ??? */
+#define __LONG_MAX__ 2147483647
+#endif
+
+/* Fix problem when linking c++ programs with gcc 3.x */
+#ifdef DEFINE_CXA_PURE_VIRTUAL
+#define FIX_GCC_LINKING_PROBLEM extern "C" { int __cxa_pure_virtual() {return 0;} }
+#else
+#define FIX_GCC_LINKING_PROBLEM
+#endif
+
+/* egcs 1.1.2 has a problem with memcpy on Alpha */
+#if defined(__GNUC__) && defined(__alpha__) && ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
+#define BAD_MEMCPY
+#endif
+
+/* In Linux-alpha we have atomic.h if we are using gcc */
+#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95)) && !defined(HAVE_ATOMIC_ADD)
+#define HAVE_ATOMIC_ADD
+#define HAVE_ATOMIC_SUB
+#endif
+
+/* In Linux-ia64 including atomic.h will give us an error */
+#if (defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__ia64__)) || !defined(THREAD)
+#undef HAVE_ATOMIC_ADD
+#undef HAVE_ATOMIC_SUB
+#endif
+
+#if defined(_lint) && !defined(lint)
+#define lint
+#endif
+#if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
+#define _LONG_LONG 1 /* For AIX string library */
+#endif
+
+#ifndef stdin
+#include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#include <math.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TIMEB_H
+#include <sys/timeb.h> /* Avoid warnings on SCO */
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif /* TIME_WITH_SYS_TIME */
+#ifdef HAVE_UNISTD_H
+#if defined(HAVE_OPENSSL) && !defined(__FreeBSD__) && !defined(NeXT)
+#define crypt unistd_crypt
+#endif
+#include <unistd.h>
+#ifdef HAVE_OPENSSL
+#undef crypt
+#endif
+#endif
+#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA)
+#undef HAVE_ALLOCA
+#undef HAVE_ALLOCA_H
+#endif
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+#ifdef HAVE_ATOMIC_ADD
+#define __SMP__
+#include <asm/atomic.h>
+#endif
+
+/* Go around some bugs in different OS and compilers */
+#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
+#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */
+#define HAVE_ULONG
+#endif
+#ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */
+#undef HAVE_FINITE
+#endif
+#if defined(HPUX) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
+/* Fix bug in setrlimit */
+#undef setrlimit
+#define setrlimit cma_setrlimit64
+#endif
+
+/* We can not live without the following defines */
+
+#define USE_MYFUNC 1 /* Must use syscall indirection */
+#define MASTER 1 /* Compile without unireg */
+#define ENGLISH 1 /* Messages in English */
+#define POSIX_MISTAKE 1 /* regexp: Fix stupid spec error */
+#define USE_REGEX 1 /* We want the use the regex library */
+/* Do not define for ultra sparcs */
+#ifndef OS2
+#define USE_BMOVE512 1 /* Use this unless system bmove is faster */
+#endif
+
+/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
+#ifdef I_AM_PARANOID
+#define DONT_ALLOW_USER_CHANGE 1
+#define DONT_USE_MYSQL_PWD 1
+#endif
+
+/* Does the system remember a signal handler after a signal ? */
+#ifndef HAVE_BSD_SIGNALS
+#define DONT_REMEMBER_SIGNAL
+#endif
+
+/* Define void to stop lint from generating "null effekt" comments */
+#ifndef DONT_DEFINE_VOID
+#ifdef _lint
+int __void__;
+#define VOID(X) (__void__ = (int) (X))
+#else
+#undef VOID
+#define VOID(X) (X)
+#endif
+#endif /* DONT_DEFINE_VOID */
+
+#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
+#define LINT_INIT(var) var=0 /* No uninitialize-warning */
+#else
+#define LINT_INIT(var)
+#endif
+
+/* Define some useful general macros */
+#if defined(__cplusplus) && defined(__GNUC__)
+#define max(a, b) ((a) >? (b))
+#define min(a, b) ((a) <? (b))
+#elif !defined(max)
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#if defined(__EMX__) || !defined(HAVE_UINT)
+typedef unsigned int uint;
+typedef unsigned short ushort;
+#endif
+
+#define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
+#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
+#define swap(t,a,b) { register t dummy; dummy = a; a = b; b = dummy; }
+#define test(a) ((a) ? 1 : 0)
+#define set_if_bigger(a,b) { if ((a) < (b)) (a)=(b); }
+#define set_if_smaller(a,b) { if ((a) > (b)) (a)=(b); }
+#define test_all_bits(a,b) (((a) & (b)) == (b))
+#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1))
+#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
+#ifndef HAVE_RINT
+#define rint(A) floor((A)+0.5)
+#endif
+
+/* Define some general constants */
+#ifndef TRUE
+#define TRUE (1) /* Logical true */
+#define FALSE (0) /* Logical false */
+#endif
+
+#if defined(__GNUC__)
+#define function_volatile volatile
+#define my_reinterpret_cast(A) reinterpret_cast<A>
+#define my_const_cast(A) const_cast<A>
+#elif !defined(my_reinterpret_cast)
+#define my_reinterpret_cast(A) (A)
+#define my_const_cast(A) (A)
+#endif
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#define __attribute__(A)
+#endif
+
+/* From old s-system.h */
+
+/*
+ Support macros for non ansi & other old compilers. Since such
+ things are no longer supported we do nothing. We keep then since
+ some of our code may still be needed to upgrade old customers.
+*/
+#define _VARARGS(X) X
+#define _STATIC_VARARGS(X) X
+#define _PC(X) X
+
+#if defined(DBUG_ON) && defined(DBUG_OFF)
+#undef DBUG_OFF
+#endif
+
+#if defined(_lint) && !defined(DBUG_OFF)
+#define DBUG_OFF
+#endif
+
+#include <dbug.h>
+
+#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
+#define ASCII_BITS_USED 8 /* Bit char used */
+#define NEAR_F /* No near function handling */
+
+/* Some types that is different between systems */
+
+typedef int File; /* File descriptor */
+#ifndef Socket_defined
+typedef int my_socket; /* File descriptor for sockets */
+#define INVALID_SOCKET -1
+#endif
+/* Type for fuctions that handles signals */
+#define sig_handler RETSIGTYPE
+typedef void (*sig_return)();/* Returns type from signal */
+#if defined(__GNUC__) && !defined(_lint)
+typedef char pchar; /* Mixed prototypes can take char */
+typedef char puchar; /* Mixed prototypes can take char */
+typedef char pbool; /* Mixed prototypes can take char */
+typedef short pshort; /* Mixed prototypes can take short int */
+typedef float pfloat; /* Mixed prototypes can take float */
+#else
+typedef int pchar; /* Mixed prototypes can't take char */
+typedef uint puchar; /* Mixed prototypes can't take char */
+typedef int pbool; /* Mixed prototypes can't take char */
+typedef int pshort; /* Mixed prototypes can't take short int */
+typedef double pfloat; /* Mixed prototypes can't take float */
+#endif
+typedef int (*qsort_cmp)(const void *,const void *);
+typedef int (*qsort_cmp2)(void*, const void *,const void *);
+#ifdef HAVE_mit_thread
+#define qsort_t void
+#undef QSORT_TYPE_IS_VOID
+#define QSORT_TYPE_IS_VOID
+#else
+#define qsort_t RETQSORTTYPE /* Broken GCC cant handle typedef !!!! */
+#endif
+#ifdef HAVE_mit_thread
+#define size_socket socklen_t /* Type of last arg to accept */
+#else
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+typedef SOCKET_SIZE_TYPE size_socket;
+#endif
+
+#ifndef SOCKOPT_OPTLEN_TYPE
+#define SOCKOPT_OPTLEN_TYPE size_socket
+#endif
+
+/* file create flags */
+
+#ifndef O_SHARE
+#define O_SHARE 0 /* Flag to my_open for shared files */
+#ifndef O_BINARY
+#define O_BINARY 0 /* Flag to my_open for binary files */
+#endif
+#define FILE_BINARY 0 /* Flag to my_fopen for binary streams */
+#ifdef HAVE_FCNTL
+#define HAVE_FCNTL_LOCK
+#define F_TO_EOF 0L /* Param to lockf() to lock rest of file */
+#endif
+#endif /* O_SHARE */
+#ifndef O_TEMPORARY
+#define O_TEMPORARY 0
+#endif
+#ifndef O_SHORT_LIVED
+#define O_SHORT_LIVED 0
+#endif
+
+/* #define USE_RECORD_LOCK */
+
+ /* Unsigned types supported by the compiler */
+#define UNSINT8 /* unsigned int8 (char) */
+#define UNSINT16 /* unsigned int16 */
+#define UNSINT32 /* unsigned int32 */
+
+ /* General constants */
+#define SC_MAXWIDTH 256 /* Max width of screen (for error messages) */
+#define FN_LEN 256 /* Max file name len */
+#define FN_HEADLEN 253 /* Max length of filepart of file name */
+#define FN_EXTLEN 20 /* Max length of extension (part of FN_LEN) */
+#define FN_REFLEN 512 /* Max length of full path-name */
+#define FN_EXTCHAR '.'
+#define FN_HOMELIB '~' /* ~/ is used as abbrev for home dir */
+#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
+#define FN_PARENTDIR ".." /* Parentdirectory; Must be a string */
+#define FN_DEVCHAR ':'
+
+#ifndef FN_LIBCHAR
+#ifdef __EMX__
+#define FN_LIBCHAR '\\'
+#define FN_ROOTDIR "\\"
+#else
+#define FN_LIBCHAR '/'
+#define FN_ROOTDIR "/"
+#endif
+#define MY_NFILE 1024 /* This is only used to save filenames */
+#endif
+
+/* #define EXT_IN_LIBNAME */
+/* #define FN_NO_CASE_SENCE */
+/* #define FN_UPPER_CASE TRUE */
+
+/*
+ Io buffer size; Must be a power of 2 and a multiple of 512. May be
+ smaller what the disk page size. This influences the speed of the
+ isam btree library. eg to big to slow.
+*/
+#define IO_SIZE 4096
+/*
+ How much overhead does malloc have. The code often allocates
+ something like 1024-MALLOC_OVERHEAD bytes
+*/
+#ifdef SAFEMALLOC
+#define MALLOC_OVERHEAD (8+24+4)
+#else
+#define MALLOC_OVERHEAD 8
+#endif
+ /* get memory in huncs */
+#define ONCE_ALLOC_INIT (uint) (4096-MALLOC_OVERHEAD)
+ /* Typical record cash */
+#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
+ /* Typical key cash */
+#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
+
+ /* Some things that this system doesn't have */
+
+#define NO_HASH /* Not needed anymore */
+#ifdef __WIN__
+#define NO_DIR_LIBRARY /* Not standar dir-library */
+#define USE_MY_STAT_STRUCT /* For my_lib */
+#endif
+
+/* Some things that this system does have */
+
+#ifndef HAVE_ITOA
+#define USE_MY_ITOA /* There is no itoa */
+#endif
+
+/* Some defines of functions for portability */
+
+#ifndef HAVE_ATOD
+#define atod atof
+#endif
+#ifdef USE_MY_ATOF
+#define atof my_atof
+extern void init_my_atof(void);
+extern double my_atof(const char*);
+#endif
+#undef remove /* Crashes MySQL on SCO 5.0.0 */
+#ifndef __WIN__
+#ifdef OS2
+#define closesocket(A) soclose(A)
+#else
+#define closesocket(A) close(A)
+#endif
+#ifndef ulonglong2double
+#define ulonglong2double(A) ((double) (A))
+#define my_off_t2double(A) ((double) (A))
+#endif
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+#define ulong_to_double(X) ((double) (ulong) (X))
+#define SET_STACK_SIZE(X) /* Not needed on real machines */
+
+#if !defined(HAVE_mit_thread) && !defined(HAVE_STRTOK_R)
+#define strtok_r(A,B,C) strtok((A),(B))
+#endif
+
+/* Remove some things that mit_thread break or doesn't support */
+#if defined(HAVE_mit_thread) && defined(THREAD)
+#undef HAVE_PREAD
+#undef HAVE_REALPATH
+#undef HAVE_MLOCK
+#undef HAVE_TEMPNAM /* Use ours */
+#undef HAVE_PTHREAD_SETPRIO
+#undef HAVE_FTRUNCATE
+#undef HAVE_READLINK
+#endif
+
+/* This is from the old m-machine.h file */
+
+#if SIZEOF_LONG_LONG > 4
+#define HAVE_LONG_LONG 1
+#endif
+
+#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
+#define LONGLONG_MIN ((long long) 0x8000000000000000LL)
+#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL)
+#endif
+
+#if SIZEOF_LONG == 4
+#define INT_MIN32 (long) 0x80000000L
+#define INT_MAX32 (long) 0x7FFFFFFFL
+#define INT_MIN24 ((long) 0xff800000L)
+#define INT_MAX24 0x007fffffL
+#define INT_MIN16 ((short int) 0x8000)
+#define INT_MAX16 0x7FFF
+#define INT_MIN8 ((char) 0x80)
+#define INT_MAX8 ((char) 0x7F)
+#else /* Probably Alpha */
+#define INT_MIN32 ((long) (int) 0x80000000)
+#define INT_MAX32 ((long) (int) 0x7FFFFFFF)
+#define INT_MIN24 ((long) (int) 0xff800000)
+#define INT_MAX24 ((long) (int) 0x007fffff)
+#define INT_MIN16 ((short int) 0xffff8000)
+#define INT_MAX16 ((short int) 0x00007FFF)
+#endif
+
+/* From limits.h instead */
+#ifndef DBL_MIN
+#define DBL_MIN 4.94065645841246544e-324
+#define FLT_MIN ((float)1.40129846432481707e-45)
+#endif
+#ifndef DBL_MAX
+#define DBL_MAX 1.79769313486231470e+308
+#define FLT_MAX ((float)3.40282346638528860e+38)
+#endif
+
+/*
+ Max size that must be added to a so that we know Size to make
+ adressable obj.
+*/
+typedef long my_ptrdiff_t;
+#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
+#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
+/* Size to make adressable obj. */
+#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A),sizeof(t)))
+ /* Offset of filed f in structure t */
+#define OFFSET(t, f) ((size_t)(char *)&((t *)0)->f)
+#define ADD_TO_PTR(ptr,size,type) (type) ((byte*) (ptr)+size)
+#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((byte*) (A) - (byte*) (B))
+
+#define NullS (char *) 0
+/* Nowdays we do not support MessyDos */
+#ifndef NEAR
+#define NEAR /* Who needs segments ? */
+#define FAR /* On a good machine */
+#ifndef HUGE_PTR
+#define HUGE_PTR
+#endif
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+#define STDCALL _System _Export
+#elif !defined( STDCALL)
+#define STDCALL
+#endif
+
+/* Typdefs for easyier portability */
+
+#if defined(VOIDTYPE)
+typedef void *gptr; /* Generic pointer */
+#else
+typedef char *gptr; /* Generic pointer */
+#endif
+#ifndef HAVE_INT_8_16_32
+typedef char int8; /* Signed integer >= 8 bits */
+typedef short int16; /* Signed integer >= 16 bits */
+#endif
+#ifndef HAVE_UCHAR
+typedef unsigned char uchar; /* Short for unsigned char */
+#endif
+typedef unsigned char uint8; /* Short for unsigned integer >= 8 bits */
+typedef unsigned short uint16; /* Short for unsigned integer >= 16 bits */
+
+#if SIZEOF_INT == 4
+#ifndef HAVE_INT_8_16_32
+typedef int int32;
+#endif
+typedef unsigned int uint32; /* Short for unsigned integer >= 32 bits */
+#elif SIZEOF_LONG == 4
+#ifndef HAVE_INT_8_16_32
+typedef long int32;
+#endif
+typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */
+#else
+error "Neither int or long is of 4 bytes width"
+#endif
+
+#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC)
+typedef unsigned long ulong; /* Short for unsigned long */
+#endif
+#ifndef longlong_defined
+#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8
+typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
+typedef long long int longlong;
+#else
+typedef unsigned long ulonglong; /* ulong or unsigned long long */
+typedef long longlong;
+#endif
+#endif
+
+#ifdef USE_RAID
+/*
+ The following is done with a if to not get problems with pre-processors
+ with late define evaluation
+*/
+#if SIZEOF_OFF_T == 4
+#define SYSTEM_SIZEOF_OFF_T 4
+#else
+#define SYSTEM_SIZEOF_OFF_T 8
+#endif
+#undef SIZEOF_OFF_T
+#define SIZEOF_OFF_T 8
+#else
+#define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T
+#endif /* USE_RAID */
+
+#if SIZEOF_OFF_T > 4
+typedef ulonglong my_off_t;
+#else
+typedef unsigned long my_off_t;
+#endif
+#define MY_FILEPOS_ERROR (~(my_off_t) 0)
+#if !defined(__WIN__) && !defined(OS2)
+typedef off_t os_off_t;
+#endif
+
+#if defined(__WIN__)
+#define socket_errno WSAGetLastError()
+#define SOCKET_EINTR WSAEINTR
+#define SOCKET_EAGAIN WSAEINPROGRESS
+#define SOCKET_EWOULDBLOCK WSAEINPROGRESS
+#define SOCKET_ENFILE ENFILE
+#define SOCKET_EMFILE EMFILE
+#elif defined(OS2)
+#define socket_errno sock_errno()
+#define SOCKET_EINTR SOCEINTR
+#define SOCKET_EAGAIN SOCEINPROGRESS
+#define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK
+#define SOCKET_ENFILE SOCENFILE
+#define SOCKET_EMFILE SOCEMFILE
+#define closesocket(A) soclose(A)
+#else /* Unix */
+#define socket_errno errno
+#define closesocket(A) close(A)
+#define SOCKET_EINTR EINTR
+#define SOCKET_EAGAIN EAGAIN
+#define SOCKET_EWOULDBLOCK EWOULDBLOCK
+#define SOCKET_ENFILE ENFILE
+#define SOCKET_EMFILE EMFILE
+#endif
+
+typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */
+typedef short int15; /* Most effective integer 0 <= x <= 32767 */
+typedef char *my_string; /* String of characters */
+typedef unsigned long size_s; /* Size of strings (In string-funcs) */
+typedef int myf; /* Type of MyFlags in my_funcs */
+#ifndef byte_defined
+typedef char byte; /* Smallest addressable unit */
+#endif
+typedef char my_bool; /* Small bool */
+#if !defined(bool) && !defined(bool_defined) && (!defined(HAVE_BOOL) || !defined(__cplusplus))
+typedef char bool; /* Ordinary boolean values 0 1 */
+#endif
+ /* Macros for converting *constants* to the right type */
+#define INT8(v) (int8) (v)
+#define INT16(v) (int16) (v)
+#define INT32(v) (int32) (v)
+#define MYF(v) (myf) (v)
+
+/*
+ Defines to make it possible to prioritize register assignments. No
+ longer that important with modern compilers.
+*/
+#ifndef USING_X
+#define reg1 register
+#define reg2 register
+#define reg3 register
+#define reg4 register
+#define reg5 register
+#define reg6 register
+#define reg7 register
+#define reg8 register
+#define reg9 register
+#define reg10 register
+#define reg11 register
+#define reg12 register
+#define reg13 register
+#define reg14 register
+#define reg15 register
+#define reg16 register
+#endif
+
+/*
+ Sometimes we want to make sure that the variable is not put into
+ a register in debugging mode so we can see its value in the core
+*/
+
+#ifndef DBUG_OFF
+#define dbug_volatile volatile
+#else
+#define dbug_volatile
+#endif
+
+/* Defines for time function */
+#define SCALE_SEC 100
+#define SCALE_USEC 10000
+#define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */
+#define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */
+
+#ifdef HAVE_TIMESPEC_TS_SEC
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).ts_sec=time(0) + (time_t) (SEC); (ABSTIME).ts_nsec=0; }
+#elif defined(__WIN__)
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=time((time_t*)0) + (time_t) (SEC); (ABSTIME).tv_nsec=0; }
+#else
+#define set_timespec(ABSTIME,SEC) \
+{\
+ struct timeval tv;\
+ gettimeofday(&tv,0);\
+ (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
+ (ABSTIME).tv_nsec=tv.tv_usec*1000;\
+}
+#endif
+
+/*
+ Define-funktions for reading and storing in machine independent format
+ (low byte first)
+*/
+
+/* Optimized store functions for Intel x86 */
+#ifdef __i386__
+#define sint2korr(A) (*((int16 *) (A)))
+#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
+ (((uint32) 255L << 24) | \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])) : \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])))
+#define sint4korr(A) (*((long *) (A)))
+#define uint2korr(A) (*((uint16 *) (A)))
+#define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF)
+#define uint4korr(A) (*((unsigned long *) (A)))
+#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24)) +\
+ (((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint8korr(A) (*((ulonglong *) (A)))
+#define sint8korr(A) (*((longlong *) (A)))
+#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
+#define int3store(T,A) { *(T)= (uchar) ((A));\
+ *(T+1)=(uchar) (((uint) (A) >> 8));\
+ *(T+2)=(uchar) (((A) >> 16)); }
+#define int4store(T,A) *((long *) (T))= (long) (A)
+#define int5store(T,A) { *(T)= (uchar)((A));\
+ *((T)+1)=(uchar) (((A) >> 8));\
+ *((T)+2)=(uchar) (((A) >> 16));\
+ *((T)+3)=(uchar) (((A) >> 24)); \
+ *((T)+4)=(uchar) (((A) >> 32)); }
+#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
+
+typedef union {
+ double v;
+ long m[2];
+} doubleget_union;
+#define doubleget(V,M) { ((doubleget_union *)&V)->m[0] = *((long*) M); \
+ ((doubleget_union *)&V)->m[1] = *(((long*) M)+1); }
+#define doublestore(T,V) { *((long *) T) = ((doubleget_union *)&V)->m[0]; \
+ *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; }
+#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); }
+#define float8get(V,M) doubleget((V),(M))
+#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
+#define float8store(V,M) doublestore((V),(M))
+#endif /* __i386__ */
+
+#ifndef sint2korr
+#define sint2korr(A) (int16) (((int16) ((uchar) (A)[0])) +\
+ ((int16) ((int16) (A)[1]) << 8))
+#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
+ (((uint32) 255L << 24) | \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])) : \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])))
+#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) +\
+ (((int32) ((uchar) (A)[1]) << 8)) +\
+ (((int32) ((uchar) (A)[2]) << 16)) +\
+ (((int32) ((int16) (A)[3]) << 24)))
+#define sint8korr(A) (longlong) uint8korr(A)
+#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) +\
+ ((uint16) ((uchar) (A)[1]) << 8))
+#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16))
+#define uint4korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24))
+#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24)) +\
+ (((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24)) +\
+ (((ulonglong) (((uint32) ((uchar) (A)[4])) +\
+ (((uint32) ((uchar) (A)[5])) << 8) +\
+ (((uint32) ((uchar) (A)[6])) << 16) +\
+ (((uint32) ((uchar) (A)[7])) << 24))) <<\
+ 32))
+#define int2store(T,A) { uint def_temp= (uint) (A) ;\
+ *((uchar*) (T))= (uchar)(def_temp); \
+ *((uchar*) (T+1))=(uchar)((def_temp >> 8)); }
+#define int3store(T,A) { /*lint -save -e734 */\
+ *((uchar*)(T))=(uchar) ((A));\
+ *((uchar*) (T)+1)=(uchar) (((A) >> 8));\
+ *((uchar*)(T)+2)=(uchar) (((A) >> 16)); \
+ /*lint -restore */}
+#define int4store(T,A) { *(T)=(char) ((A));\
+ *((T)+1)=(char) (((A) >> 8));\
+ *((T)+2)=(char) (((A) >> 16));\
+ *((T)+3)=(char) (((A) >> 24)); }
+#define int5store(T,A) { *(T)=((A));\
+ *((T)+1)=(((A) >> 8));\
+ *((T)+2)=(((A) >> 16));\
+ *((T)+3)=(((A) >> 24)); \
+ *((T)+4)=(((A) >> 32)); }
+#define int8store(T,A) { uint def_temp= (uint) (A), def_temp2= (uint) ((A) >> 32); \
+ int4store((T),def_temp); \
+ int4store((T+4),def_temp2); \
+ }
+#ifdef WORDS_BIGENDIAN
+#define float4store(T,A) { *(T)= ((byte *) &A)[3];\
+ *((T)+1)=(char) ((byte *) &A)[2];\
+ *((T)+2)=(char) ((byte *) &A)[1];\
+ *((T)+3)=(char) ((byte *) &A)[0]; }
+
+#define float4get(V,M) { float def_temp;\
+ ((byte*) &def_temp)[0]=(M)[3];\
+ ((byte*) &def_temp)[1]=(M)[2];\
+ ((byte*) &def_temp)[2]=(M)[1];\
+ ((byte*) &def_temp)[3]=(M)[0];\
+ (V)=def_temp; }
+#define float8store(T,V) { *(T)= ((byte *) &V)[7];\
+ *((T)+1)=(char) ((byte *) &V)[6];\
+ *((T)+2)=(char) ((byte *) &V)[5];\
+ *((T)+3)=(char) ((byte *) &V)[4];\
+ *((T)+4)=(char) ((byte *) &V)[3];\
+ *((T)+5)=(char) ((byte *) &V)[2];\
+ *((T)+6)=(char) ((byte *) &V)[1];\
+ *((T)+7)=(char) ((byte *) &V)[0]; }
+
+#define float8get(V,M) { double def_temp;\
+ ((byte*) &def_temp)[0]=(M)[7];\
+ ((byte*) &def_temp)[1]=(M)[6];\
+ ((byte*) &def_temp)[2]=(M)[5];\
+ ((byte*) &def_temp)[3]=(M)[4];\
+ ((byte*) &def_temp)[4]=(M)[3];\
+ ((byte*) &def_temp)[5]=(M)[2];\
+ ((byte*) &def_temp)[6]=(M)[1];\
+ ((byte*) &def_temp)[7]=(M)[0];\
+ (V) = def_temp; }
+#else
+#define float4get(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float))
+#define float4store(V,M) memcpy_fixed((byte*) V,(byte*) (&M),sizeof(float))
+
+#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
+#define doublestore(T,V) { *(T)= ((byte *) &V)[4];\
+ *((T)+1)=(char) ((byte *) &V)[5];\
+ *((T)+2)=(char) ((byte *) &V)[6];\
+ *((T)+3)=(char) ((byte *) &V)[7];\
+ *((T)+4)=(char) ((byte *) &V)[0];\
+ *((T)+5)=(char) ((byte *) &V)[1];\
+ *((T)+6)=(char) ((byte *) &V)[2];\
+ *((T)+7)=(char) ((byte *) &V)[3]; }
+#define doubleget(V,M) { double def_temp;\
+ ((byte*) &def_temp)[0]=(M)[4];\
+ ((byte*) &def_temp)[1]=(M)[5];\
+ ((byte*) &def_temp)[2]=(M)[6];\
+ ((byte*) &def_temp)[3]=(M)[7];\
+ ((byte*) &def_temp)[4]=(M)[0];\
+ ((byte*) &def_temp)[5]=(M)[1];\
+ ((byte*) &def_temp)[6]=(M)[2];\
+ ((byte*) &def_temp)[7]=(M)[3];\
+ (V) = def_temp; }
+#endif /* __FLOAT_WORD_ORDER */
+
+#define float8get(V,M) doubleget((V),(M))
+#define float8store(V,M) doublestore((V),(M))
+#endif /* WORDS_BIGENDIAN */
+
+#endif /* sint2korr */
+
+/*
+ Define-funktions for reading and storing in machine format from/to
+ short/long to/from some place in memory V should be a (not
+ register) variable, M is a pointer to byte
+*/
+
+#ifdef WORDS_BIGENDIAN
+
+#define ushortget(V,M) { V = (uint16) (((uint16) ((uchar) (M)[1]))+\
+ ((uint16) ((uint16) (M)[0]) << 8)); }
+#define shortget(V,M) { V = (short) (((short) ((uchar) (M)[1]))+\
+ ((short) ((short) (M)[0]) << 8)); }
+#define longget(V,M) { int32 def_temp;\
+ ((byte*) &def_temp)[0]=(M)[0];\
+ ((byte*) &def_temp)[1]=(M)[1];\
+ ((byte*) &def_temp)[2]=(M)[2];\
+ ((byte*) &def_temp)[3]=(M)[3];\
+ (V)=def_temp; }
+#define ulongget(V,M) { uint32 def_temp;\
+ ((byte*) &def_temp)[0]=(M)[0];\
+ ((byte*) &def_temp)[1]=(M)[1];\
+ ((byte*) &def_temp)[2]=(M)[2];\
+ ((byte*) &def_temp)[3]=(M)[3];\
+ (V)=def_temp; }
+#define shortstore(T,A) { uint def_temp=(uint) (A) ;\
+ *(T+1)=(char)(def_temp); \
+ *(T+0)=(char)(def_temp >> 8); }
+#define longstore(T,A) { *((T)+3)=((A));\
+ *((T)+2)=(((A) >> 8));\
+ *((T)+1)=(((A) >> 16));\
+ *((T)+0)=(((A) >> 24)); }
+
+#define doubleget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(double))
+#define doublestore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(double))
+#define longlongget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(ulonglong))
+#define longlongstore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(ulonglong))
+
+#else
+
+#define ushortget(V,M) { V = uint2korr(M); }
+#define shortget(V,M) { V = sint2korr(M); }
+#define longget(V,M) { V = sint4korr(M); }
+#define ulongget(V,M) { V = uint4korr(M); }
+#define shortstore(T,V) int2store(T,V)
+#define longstore(T,V) int4store(T,V)
+#ifndef doubleget
+#define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
+#define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
+#endif /* doubleget */
+#define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
+#define longlongstore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(ulonglong))
+
+#endif /* WORDS_BIGENDIAN */
+
+/* sprintf does not always return the number of bytes :- */
+#ifdef SPRINTF_RETURNS_INT
+#define my_sprintf(buff,args) sprintf args
+#else
+#ifdef SPRINTF_RETURNS_PTR
+#define my_sprintf(buff,args) ((int)(sprintf args - buff))
+#else
+#define my_sprintf(buff,args) sprintf args,strlen(buff)
+#endif
+#endif
+
+#ifndef THREAD
+#define thread_safe_increment(V,L) (V)++
+#define thread_safe_add(V,C,L) (V)+=(C)
+#define thread_safe_sub(V,C,L) (V)-=(C)
+#define statistic_increment(V,L) (V)++
+#define statistic_add(V,C,L) (V)+=(C)
+#endif
+
+/* Macros to make switching between C and C++ mode easier */
+#ifdef __cplusplus
+#define C_MODE_START extern "C" {
+#define C_MODE_END }
+#else
+#define C_MODE_START
+#define C_MODE_END
+#endif
+
+#endif /* _global_h */
diff --git a/include/my_list.h b/include/my_list.h
index 7391db70e27..0f56d4c532b 100644
--- a/include/my_list.h
+++ b/include/my_list.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _list_h_
#define _list_h_
diff --git a/include/my_net.h b/include/my_net.h
index a4910d8af1d..2f5743923cf 100644
--- a/include/my_net.h
+++ b/include/my_net.h
@@ -1,28 +1,33 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* thread safe version of some common functions */
-
-/* for thread safe my_inet_ntoa */
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__BEOS__)
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ thread safe version of some common functions:
+ my_inet_ntoa
+
+ This file is also used to make handling of sockets and ioctl()
+ portable accross systems.
+
+*/
+
+#ifndef _my_net_h
+#define _my_net_h
+C_MODE_START
+
+#include <errno.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@@ -32,7 +37,33 @@ extern "C" {
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
-#endif /* !defined(MSDOS) && !defined(__WIN__) */
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__)
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#if !defined(alpha_linux_port)
+#include <netinet/tcp.h>
+#endif
+#endif
+
+#if defined(__EMX__)
+#include <sys/ioctl.h>
+#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
+#undef HAVE_FCNTL
+#endif /* defined(__EMX__) */
+
+#if defined(MSDOS) || defined(__WIN__)
+#define O_NONBLOCK 1 /* For emulation of fcntl() */
+#endif
+
+/* Thread safe or portable version of some functions */
void my_inet_ntoa(struct in_addr in, char *buf);
@@ -78,6 +109,5 @@ struct hostent *my_gethostbyname_r(const char *name,
#define h_errno errno
#endif
-#ifdef __cplusplus
-}
+C_MODE_END
#endif
diff --git a/include/my_no_pthread.h b/include/my_no_pthread.h
index 2ff8896fa74..81c0de580db 100644
--- a/include/my_no_pthread.h
+++ b/include/my_no_pthread.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
This undefs some pthread mutex locks when one isn't using threads
diff --git a/include/my_nosys.h b/include/my_nosys.h
index 5991904f260..605906f0e07 100644
--- a/include/my_nosys.h
+++ b/include/my_nosys.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Header to remove use of my_functions in functions where we need speed and
diff --git a/include/my_pthread.h b/include/my_pthread.h
index bcad292ecc9..a822d2db484 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Defines to make different thread packages compatible */
@@ -133,16 +132,17 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#define pthread_equal(A,B) ((A) == (B))
#ifdef OS2
-int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
-int pthread_mutex_lock (pthread_mutex_t *);
-int pthread_mutex_unlock (pthread_mutex_t *);
-int pthread_mutex_destroy (pthread_mutex_t *);
+extern int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
+extern int pthread_mutex_lock (pthread_mutex_t *);
+extern int pthread_mutex_unlock (pthread_mutex_t *);
+extern int pthread_mutex_destroy (pthread_mutex_t *);
#define my_pthread_setprio(A,B) DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A)
#define pthread_kill(A,B) raise(B)
#define pthread_exit(A) pthread_dummy()
#else
#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
+#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
@@ -428,6 +428,15 @@ struct tm *localtime_r(const time_t *clock, struct tm *res);
#endif /* defined(__WIN__) */
+#if defined(HPUX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
+#undef pthread_cond_timedwait
+#define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c))
+#define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a))
+int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+ struct timespec *abstime);
+int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
+#endif
+
/* safe_mutex adds checking to mutex for easier debugging */
typedef struct st_safe_mutex_t
@@ -458,6 +467,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
#undef pthread_mutex_t
#undef pthread_cond_wait
#undef pthread_cond_timedwait
+#undef pthread_mutex_trylock
#define pthread_mutex_init(A,B) safe_mutex_init((A),(B))
#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
@@ -476,6 +486,8 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
#define my_rwlock_init(A,B) pthread_mutex_init((A),(B))
#define rw_rdlock(A) pthread_mutex_lock((A))
#define rw_wrlock(A) pthread_mutex_lock((A))
+#define rw_tryrdlock(A) pthread_mutex_trylock((A))
+#define rw_trywrlock(A) pthread_mutex_trylock((A))
#define rw_unlock(A) pthread_mutex_unlock((A))
#define rwlock_destroy(A) pthread_mutex_destroy((A))
#elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
@@ -483,6 +495,8 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
#define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
#define rw_rdlock(A) pthread_rwlock_rdlock(A)
#define rw_wrlock(A) pthread_rwlock_wrlock(A)
+#define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A))
+#define rw_trywrlock(A) pthread_rwlock_trywrlock((A))
#define rw_unlock(A) pthread_rwlock_unlock(A)
#define rwlock_destroy(A) pthread_rwlock_destroy(A)
#elif defined(HAVE_RWLOCK_INIT)
@@ -503,14 +517,18 @@ typedef struct _my_rw_lock_t {
#define rw_lock_t my_rw_lock_t
#define rw_rdlock(A) my_rw_rdlock((A))
#define rw_wrlock(A) my_rw_wrlock((A))
+#define rw_tryrdlock(A) my_rw_tryrdlock((A))
+#define rw_trywrlock(A) my_rw_trywrlock((A))
#define rw_unlock(A) my_rw_unlock((A))
#define rwlock_destroy(A) my_rwlock_destroy((A))
-extern int my_rwlock_init( my_rw_lock_t *, void * );
-extern int my_rwlock_destroy( my_rw_lock_t * );
-extern int my_rw_rdlock( my_rw_lock_t * );
-extern int my_rw_wrlock( my_rw_lock_t * );
-extern int my_rw_unlock( my_rw_lock_t * );
+extern int my_rwlock_init(my_rw_lock_t *, void *);
+extern int my_rwlock_destroy(my_rw_lock_t *);
+extern int my_rw_rdlock(my_rw_lock_t *);
+extern int my_rw_wrlock(my_rw_lock_t *);
+extern int my_rw_unlock(my_rw_lock_t *);
+extern int my_rw_tryrdlock(my_rw_lock_t *);
+extern int my_rw_trywrlock(my_rw_lock_t *);
#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
#define GETHOSTBYADDR_BUFF_SIZE 2048
@@ -575,6 +593,11 @@ struct st_my_thread_var
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
#define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno
+/*
+ Keep track of shutdown,signal, and main threads so that my_end() will not
+ report errors with them
+*/
+extern pthread_t shutdown_th, main_th, signal_th;
/* statistics_xxx functions are for not essential statistic */
@@ -605,5 +628,4 @@ extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
#ifdef __cplusplus
}
#endif
-
#endif /* _my_ptread_h */
diff --git a/include/my_semaphore.h b/include/my_semaphore.h
new file mode 100644
index 00000000000..aecbde09511
--- /dev/null
+++ b/include/my_semaphore.h
@@ -0,0 +1,61 @@
+/*
+ * Module: semaphore.h
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA
+ */
+
+/* This is hacked by Monty to be included in mysys library */
+
+#ifndef _my_semaphore_h_
+#define _my_semaphore_h_
+
+C_MODE_START
+
+#ifdef HAVE_SEMAPHORE_H
+#include <semaphore.h>
+#else
+
+#ifdef __WIN__
+typedef HANDLE sem_t;
+#else
+typedef struct {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ uint count;
+} sem_t;
+#endif
+
+int sem_init(sem_t * sem, int pshared, unsigned int value);
+int sem_destroy(sem_t * sem);
+int sem_trywait(sem_t * sem);
+int sem_wait(sem_t * sem);
+int sem_post(sem_t * sem);
+int sem_post_multiple(sem_t * sem, unsigned int count);
+int sem_getvalue(sem_t * sem, unsigned int * sval);
+
+#endif
+
+C_MODE_END
+#endif /* !_my_semaphore_h_ */
diff --git a/include/my_sys.h b/include/my_sys.h
index 8cdc78025f3..0236f7007a2 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -1,25 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_sys_h
#define _my_sys_h
-#ifdef __cplusplus
-extern "C" {
-#endif
+C_MODE_START
#ifdef HAVE_AIOWAIT
#include <sys/asynch.h> /* Used by record-cache */
@@ -39,7 +36,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#include <m_ctype.h> /* for CHARSET_INFO */
#endif
-#include <stdarg.h>
+#include <stdarg.h>
#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; }
#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
@@ -59,6 +56,9 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */
+#define MY_FULL_IO 512 /* For my_read - loop intil I/O
+ is complete
+ */
#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */
#define MY_COPYTIME 64 /* my_redel() copys time */
@@ -90,6 +90,16 @@ extern int NEAR my_errno; /* Last error in mysys */
#define ME_COLOUR2 ((2 << ME_HIGHBYTE))
#define ME_COLOUR3 ((3 << ME_HIGHBYTE))
+ /* Bits in last argument to fn_format */
+#define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */
+#define MY_REPLACE_EXT 2 /* replace extension with 'ext' */
+#define MY_UNPACK_FILENAME 4 /* Unpack name (~ -> home) */
+#define MY_PACK_FILENAME 8 /* Pack name (home -> ~) */
+#define MY_RESOLVE_SYMLINKS 16 /* Resolve all symbolic links */
+#define MY_RETURN_REAL_PATH 32 /* return full path for file */
+#define MY_SAFE_PATH 64 /* Return NULL if too long path */
+#define MY_RELATIVE_PATH 128 /* name is relative to 'dir' */
+
/* My seek flags */
#define MY_SEEK_SET 0
#define MY_SEEK_CUR 1
@@ -106,10 +116,12 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
-#define KEYCACHE_BLOCK_SIZE 1024
+#define DEFAULT_KEYCACHE_BLOCK_SIZE 1024
+#define MAX_KEYCACHE_BLOCK_SIZE 16384
/* root_alloc flags */
#define MY_KEEP_PREALLOC 1
+#define MY_MARK_BLOCKS_FREE 2 /* move used to free list and reuse them */
/* defines when allocating data */
@@ -125,6 +137,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define NORMAL_SAFEMALLOC sf_malloc_quick=0
extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
extern ulonglong safemalloc_mem_limit;
+
#define CALLER_INFO_PROTO , const char *sFile, uint uLine
#define CALLER_INFO , __FILE__, __LINE__
#define ORIG_CALLER_INFO , sFile, uLine
@@ -146,6 +159,13 @@ extern my_string my_strdup(const char *from,myf MyFlags);
#define ORIG_CALLER_INFO /* nothing */
#endif
#ifdef HAVE_ALLOCA
+#ifdef __GNUC__
+/* Remove any previous definitions. */
+#undef alloca
+#define alloca(size) __builtin_alloca (size)
+#else /* xlc */
+ #pragma alloca
+#endif /* GCC. */
#define my_alloca(SZ) alloca((size_t) (SZ))
#define my_afree(PTR) {}
#else
@@ -197,9 +217,10 @@ extern char *get_charsets_dir(char *buf);
/* statistics */
extern ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests,
_my_cache_read;
-extern ulong _my_blocks_used,_my_blocks_changed;
+extern ulong _my_blocks_used,_my_blocks_changed;
+extern uint key_cache_block_size;
extern ulong my_file_opened,my_stream_opened, my_tmp_file_created;
-extern my_bool key_cache_inited;
+extern my_bool key_cache_inited, my_init_done;
/* Point to current my_message() */
extern void (*my_sigtstp_cleanup)(void),
@@ -231,13 +252,20 @@ typedef struct wild_file_pack /* Struct to hold info when selecting files */
typedef struct st_typelib { /* Different types saved here */
uint count; /* How many types */
- const char *name; /* Name of typelib */
+ const char *name; /* Name of typelib */
const char **type_names;
} TYPELIB;
-enum cache_type {READ_CACHE,WRITE_CACHE,READ_FIFO,READ_NET,WRITE_NET};
-enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED,
- FLUSH_FORCE_WRITE};
+enum cache_type
+{
+ READ_CACHE,WRITE_CACHE,
+ SEQ_READ_APPEND /* sequential read or append */,
+ READ_FIFO, READ_NET,WRITE_NET};
+
+enum flush_type
+{
+ FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE
+};
typedef struct st_record_cache /* Used when cacheing records */
{
@@ -253,45 +281,168 @@ typedef struct st_record_cache /* Used when cacheing records */
enum cache_type type;
} RECORD_CACHE;
-enum file_type { UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE,
- STREAM_BY_FOPEN, STREAM_BY_FDOPEN, FILE_BY_MKSTEMP };
+enum file_type
+{
+ UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, STREAM_BY_FOPEN, STREAM_BY_FDOPEN,
+ FILE_BY_MKSTEMP, FILE_BY_DUP
+};
extern struct my_file_info
{
my_string name;
enum file_type type;
-#if defined(THREAD) && !defined(HAVE_PREAD)
+#if defined(THREAD) && !defined(HAVE_PREAD)
pthread_mutex_t mutex;
#endif
} my_file_info[MY_NFILE];
-typedef struct st_dynamic_array {
+typedef struct st_dynamic_array
+{
char *buffer;
uint elements,max_element;
uint alloc_increment;
uint size_of_element;
} DYNAMIC_ARRAY;
-typedef struct st_dynamic_string {
+typedef struct st_dynamic_string
+{
char *str;
uint length,max_length,alloc_increment;
} DYNAMIC_STRING;
+struct st_io_cache;
+typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
+
+#ifdef THREAD
+typedef struct st_io_cache_share
+{
+ /* to sync on reads into buffer */
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int count;
+ /* actual IO_CACHE that filled the buffer */
+ struct st_io_cache *active;
+#ifdef NOT_YET_IMPLEMENTED
+ /* whether the structure should be free'd */
+ my_bool alloced;
+#endif
+} IO_CACHE_SHARE;
+#endif
typedef struct st_io_cache /* Used when cacheing files */
{
- my_off_t pos_in_file,end_of_file;
- byte *rc_pos,*rc_end,*buffer,*rc_request_pos;
+ /* Offset in file corresponding to the first byte of byte* buffer. */
+ my_off_t pos_in_file;
+ /*
+ The offset of end of file for READ_CACHE and WRITE_CACHE.
+ For SEQ_READ_APPEND it the maximum of the actual end of file and
+ the position represented by read_end.
+ */
+ my_off_t end_of_file;
+ /* Points to current read position in the buffer */
+ byte *read_pos;
+ /* the non-inclusive boundary in the buffer for the currently valid read */
+ byte *read_end;
+ byte *buffer; /* The read buffer */
+ /* Used in ASYNC_IO */
+ byte *request_pos;
+
+ /* Only used in WRITE caches and in SEQ_READ_APPEND to buffer writes */
+ byte *write_buffer;
+ /*
+ Only used in SEQ_READ_APPEND, and points to the current read position
+ in the write buffer. Note that reads in SEQ_READ_APPEND caches can
+ happen from both read buffer (byte* buffer) and write buffer
+ (byte* write_buffer).
+ */
+ byte *append_read_pos;
+ /* Points to current write position in the write buffer */
+ byte *write_pos;
+ /* The non-inclusive boundary of the valid write area */
+ byte *write_end;
+
+ /*
+ Current_pos and current_end are convenience variables used by
+ my_b_tell() and other routines that need to know the current offset
+ current_pos points to &write_pos, and current_end to &write_end in a
+ WRITE_CACHE, and &read_pos and &read_end respectively otherwise
+ */
+ byte **current_pos, **current_end;
+#ifdef THREAD
+ /*
+ The lock is for append buffer used in SEQ_READ_APPEND cache
+ need mutex copying from append buffer to read buffer.
+ */
+ pthread_mutex_t append_buffer_lock;
+ /*
+ The following is used when several threads are reading the
+ same file in parallel. They are synchronized on disk
+ accesses reading the cached part of the file asynchronously.
+ It should be set to NULL to disable the feature. Only
+ READ_CACHE mode is supported.
+ */
+ IO_CACHE_SHARE *share;
+#endif
+ /*
+ A caller will use my_b_read() macro to read from the cache
+ if the data is already in cache, it will be simply copied with
+ memcpy() and internal variables will be accordinging updated with
+ no functions invoked. However, if the data is not fully in the cache,
+ my_b_read() will call read_function to fetch the data. read_function
+ must never be invoked directly.
+ */
int (*read_function)(struct st_io_cache *,byte *,uint);
+ /*
+ Same idea as in the case of read_function, except my_b_write() needs to
+ be replaced with my_b_append() for a SEQ_READ_APPEND cache
+ */
+ int (*write_function)(struct st_io_cache *,const byte *,uint);
+ /*
+ Specifies the type of the cache. Depending on the type of the cache
+ certain operations might not be available and yield unpredicatable
+ results. Details to be documented later
+ */
+ enum cache_type type;
+ /*
+ Callbacks when the actual read I/O happens. These were added and
+ are currently used for binary logging of LOAD DATA INFILE - when a
+ block is read from the file, we create a block create/append event, and
+ when IO_CACHE is closed, we create an end event. These functions could,
+ of course be used for other things
+ */
+ IO_CACHE_CALLBACK pre_read;
+ IO_CACHE_CALLBACK post_read;
+ IO_CACHE_CALLBACK pre_close;
+ void* arg; /* for use by pre/post_read */
char *file_name; /* if used with 'open_cached_file' */
char *dir,*prefix;
- File file;
+ File file; /* file descriptor */
+ /*
+ seek_not_done is set by my_b_seek() to inform the upcoming read/write
+ operation that a seek needs to be preformed prior to the actual I/O
+ error is 0 if the cache operation was successful, -1 if there was a
+ "hard" error, and the actual number of I/O-ed bytes if the read/write was
+ partial.
+ */
int seek_not_done,error;
- uint buffer_length,read_length;
+ /* buffer_length is memory size allocated for buffer or write_buffer */
+ uint buffer_length;
+ /* read_length is the same as buffer_length except when we use async io */
+ uint read_length;
myf myflags; /* Flags used to my_read/my_write */
- enum cache_type type;
+ /*
+ alloced_buffer is 1 if the buffer was allocated by init_io_cache() and
+ 0 if it was supplied by the user.
+ Currently READ_NET is the only one that will use a buffer allocated
+ somewhere else
+ */
+ my_bool alloced_buffer;
#ifdef HAVE_AIOWAIT
+ /*
+ As inidicated by ifdef, this is for async I/O, which is not currently
+ used (because it's not reliable on all systems)
+ */
uint inited;
my_off_t aio_read_pos;
my_aio_result aio_result;
@@ -308,67 +459,41 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
#define my_b_EOF INT_MIN
#define my_b_read(info,Buffer,Count) \
- ((info)->rc_pos + (Count) <= (info)->rc_end ?\
- (memcpy(Buffer,(info)->rc_pos,(size_t) (Count)), \
- ((info)->rc_pos+=(Count)),0) :\
+ ((info)->read_pos + (Count) <= (info)->read_end ?\
+ (memcpy(Buffer,(info)->read_pos,(size_t) (Count)), \
+ ((info)->read_pos+=(Count)),0) :\
(*(info)->read_function)((info),Buffer,Count))
+#define my_b_write(info,Buffer,Count) \
+ ((info)->write_pos + (Count) <=(info)->write_end ?\
+ (memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\
+ ((info)->write_pos+=(Count)),0) : \
+ (*(info)->write_function)((info),(Buffer),(Count)))
+
#define my_b_get(info) \
- ((info)->rc_pos != (info)->rc_end ?\
- ((info)->rc_pos++, (int) (uchar) (info)->rc_pos[-1]) :\
+ ((info)->read_pos != (info)->read_end ?\
+ ((info)->read_pos++, (int) (uchar) (info)->read_pos[-1]) :\
_my_b_get(info))
-#define my_b_write(info,Buffer,Count) \
- ((info)->rc_pos + (Count) <= (info)->rc_end ?\
- (memcpy((info)->rc_pos,Buffer,(size_t) (Count)), \
- ((info)->rc_pos+=(Count)),0) :\
- _my_b_write(info,Buffer,Count))
-
/* my_b_write_byte dosn't have any err-check */
#define my_b_write_byte(info,chr) \
- (((info)->rc_pos < (info)->rc_end) ?\
- ((*(info)->rc_pos++)=(chr)) :\
- (_my_b_write(info,0,0) , ((*(info)->rc_pos++)=(chr))))
+ (((info)->write_pos < (info)->write_end) ?\
+ ((*(info)->write_pos++)=(chr)) :\
+ (_my_b_write(info,0,0) , ((*(info)->write_pos++)=(chr))))
#define my_b_fill_cache(info) \
- (((info)->rc_end=(info)->rc_pos),(*(info)->read_function)(info,0,0))
+ (((info)->read_end=(info)->read_pos),(*(info)->read_function)(info,0,0))
#define my_b_tell(info) ((info)->pos_in_file + \
- ((info)->rc_pos - (info)->rc_request_pos))
-
-#define my_b_bytes_in_cache(info) ((uint) ((info)->rc_end - (info)->rc_pos))
-
-typedef struct st_changeable_var {
- const char *name; /* Name of variable */
- long *varptr; /* Pointer to variable */
- long def_value, /* Default value */
- min_value, /* Min allowed value */
- max_value, /* Max allowed value */
- sub_size, /* Subtract this from given value */
- block_size; /* Value should be a mult. of this */
-} CHANGEABLE_VAR;
-
-
-/* structs for alloc_root */
-
-#ifndef ST_USED_MEM_DEFINED
-#define ST_USED_MEM_DEFINED
-typedef struct st_used_mem { /* struct for once_alloc */
- struct st_used_mem *next; /* Next block in use */
- unsigned int left; /* memory left in block */
- unsigned int size; /* Size of block */
-} USED_MEM;
-
-typedef struct st_mem_root {
- USED_MEM *free;
- USED_MEM *used;
- USED_MEM *pre_alloc;
- unsigned int min_malloc;
- unsigned int block_size;
-
- void (*error_handler)(void);
-} MEM_ROOT;
-#endif
+ (uint) (*(info)->current_pos - (info)->request_pos))
+
+/* tell write offset in the SEQ_APPEND cache */
+my_off_t my_b_append_tell(IO_CACHE* info);
+
+#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
+ *(info)->current_pos)
+
+#include <my_alloc.h>
/* Prototypes for mysys and my_func functions */
@@ -388,6 +513,7 @@ extern File my_register_filename(File fd, const char *FileName,
extern File my_create(const char *FileName,int CreateFlags,
int AccsesFlags, myf MyFlags);
extern int my_close(File Filedes,myf MyFlags);
+extern File my_dup(File file, myf MyFlags);
extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
extern int my_readlink(char *to, const char *filename, myf MyFlags);
extern int my_realpath(char *to, const char *filename, myf MyFlags);
@@ -465,12 +591,12 @@ extern uint dirname_part(my_string to,const char *name);
extern uint dirname_length(const char *name);
#define base_name(A) (A+dirname_length(A))
extern int test_if_hard_path(const char *dir_name);
-extern char *convert_dirname(my_string name);
+extern char *convert_dirname(char *to, const char *from, const char *from_end);
extern void to_unix_path(my_string name);
extern my_string fn_ext(const char *name);
extern my_string fn_same(my_string toname,const char *name,int flag);
-extern my_string fn_format(my_string to,const char *name,const char *dsk,
- const char *form,int flag);
+extern my_string fn_format(my_string to,const char *name,const char *dir,
+ const char *form, uint flag);
extern size_s strlength(const char *str);
extern void pack_dirname(my_string to,const char *from);
extern uint unpack_dirname(my_string to,const char *from);
@@ -508,7 +634,8 @@ extern int flush_write_cache(RECORD_CACHE *info);
extern long my_clock(void);
extern sig_handler sigtstp_handler(int signal_number);
extern void handle_recived_signals(void);
-extern int init_key_cache(ulong use_mem,ulong leave_this_much_mem);
+extern int init_key_cache(ulong use_mem);
+extern int resize_key_cache(ulong use_mem);
extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length,
uint block_length,int return_buffer);
extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length,
@@ -529,13 +656,24 @@ extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
my_off_t seek_offset,pbool use_async_io,
pbool clear_cache);
extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count);
+#ifdef THREAD
+extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count);
+extern void init_io_cache_share(IO_CACHE *info,
+ IO_CACHE_SHARE *s, uint num_threads);
+extern void remove_io_thread(IO_CACHE *info);
+#endif
+extern int _my_b_seq_read(IO_CACHE *info,byte *Buffer,uint Count);
extern int _my_b_net_read(IO_CACHE *info,byte *Buffer,uint Count);
extern int _my_b_get(IO_CACHE *info);
extern int _my_b_async_read(IO_CACHE *info,byte *Buffer,uint Count);
extern int _my_b_write(IO_CACHE *info,const byte *Buffer,uint Count);
+extern int my_b_append(IO_CACHE *info,const byte *Buffer,uint Count);
extern int my_block_write(IO_CACHE *info, const byte *Buffer,
uint Count, my_off_t pos);
-extern int flush_io_cache(IO_CACHE *info);
+extern int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock);
+
+#define flush_io_cache(info) _flush_io_cache((info),1)
+
extern int end_io_cache(IO_CACHE *info);
extern uint my_b_fill(IO_CACHE *info);
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
@@ -576,10 +714,6 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size);
extern void dynstr_free(DYNAMIC_STRING *str);
-void set_all_changeable_vars(CHANGEABLE_VAR *vars);
-my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars);
-my_bool set_changeable_varval(const char *var, ulong val,
- CHANGEABLE_VAR *vars);
#ifdef HAVE_MLOCK
extern byte *my_malloc_lock(uint length,myf flags);
extern void my_free_lock(byte *ptr,myf flags);
@@ -591,7 +725,9 @@ extern void my_free_lock(byte *ptr,myf flags);
void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size);
gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
void free_root(MEM_ROOT *root, myf MyFLAGS);
+void set_prealloc_root(MEM_ROOT *root, char *ptr);
char *strdup_root(MEM_ROOT *root,const char *str);
+char *strmake_root(MEM_ROOT *root,const char *str,uint len);
char *memdup_root(MEM_ROOT *root,const char *str,uint len);
void load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv);
@@ -601,6 +737,7 @@ my_bool my_compress(byte *, ulong *, ulong *);
my_bool my_uncompress(byte *, ulong *, ulong *);
byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
ulong checksum(const byte *mem, uint count);
+uint my_bit_log2(ulong value);
#if defined(_MSC_VER) && !defined(__WIN__)
extern void sleep(int sec);
@@ -609,8 +746,6 @@ extern void sleep(int sec);
extern my_bool have_tcpip; /* Is set if tcpip is used */
#endif
-#ifdef __cplusplus
-}
-#endif
+C_MODE_END
#include "raid.h"
#endif /* _my_sys_h */
diff --git a/include/my_tree.h b/include/my_tree.h
index 0a227ea3944..8b326a19518 100644
--- a/include/my_tree.h
+++ b/include/my_tree.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _tree_h
#define _tree_h
@@ -32,6 +31,9 @@ typedef enum { left_root_right, right_root_left } TREE_WALK;
typedef uint32 element_count;
typedef int (*tree_walk_action)(void *,element_count,void *);
+typedef enum { free_init, free_free, free_end } TREE_FREE;
+typedef void (*tree_element_free)(void*, TREE_FREE, void *);
+
#ifdef MSDOS
typedef struct st_tree_element {
struct st_tree_element *left,*right;
@@ -49,18 +51,22 @@ typedef struct st_tree_element {
typedef struct st_tree {
TREE_ELEMENT *root,null_element;
TREE_ELEMENT **parents[MAX_TREE_HIGHT];
- uint offset_to_key,elements_in_tree,size_of_element;
- qsort_cmp compare;
+ uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated;
+ qsort_cmp2 compare;
+ void* custom_arg;
MEM_ROOT mem_root;
my_bool with_delete;
- void (*free)(void *);
+ tree_element_free free;
} TREE;
- /* Functions on hole tree */
-void init_tree(TREE *tree,uint default_alloc_size, int element_size,
- qsort_cmp compare, my_bool with_delete,
- void (*free_element)(void*));
+ /* Functions on whole tree */
+void init_tree(TREE *tree, uint default_alloc_size, uint memory_limit,
+ int size, qsort_cmp2 compare, my_bool with_delete,
+ tree_element_free free_element, void *custom_arg);
void delete_tree(TREE*);
+void reset_tree(TREE*);
+ /* similar to delete tree, except we do not my_free() blocks in mem_root
+ */
#define is_tree_inited(tree) ((tree)->root != 0)
/* Functions on leafs */
diff --git a/include/myisam.h b/include/myisam.h
index 9ecb5ef4294..248aabb807d 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using myisam_funktions */
@@ -46,6 +45,11 @@ extern "C" {
/* Max extra space to use when sorting keys */
#define MI_MAX_TEMP_LENGTH 256*1024L*1024L
+/* Possible values for myisam_block_size (must be power of 2) */
+#define MI_KEY_BLOCK_LENGTH 1024 /* default key block length */
+#define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */
+#define MI_MAX_KEY_BLOCK_LENGTH 16384
+
#define mi_portable_sizeof_char_ptr 8
typedef uint32 ha_checksum;
@@ -68,6 +72,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
ulong mean_reclength; /* Mean recordlength (if packed) */
ulonglong auto_increment;
ulonglong key_map; /* Which keys are used */
+ char *data_file_name, *index_file_name;
uint keys; /* Number of keys in use */
uint options; /* HA_OPTION_... used */
int errkey, /* With key was dupplicated on err */
@@ -86,6 +91,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
typedef struct st_mi_create_info
{
+ char *index_file_name, *data_file_name; /* If using symlinks */
ha_rows max_rows;
ha_rows reloc_rows;
ulonglong auto_increment;
@@ -120,6 +126,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */
uint16 keysegs; /* Number of key-segment */
uint16 flag; /* NOSAME, PACK_USED */
+ uint8 key_alg; /* BTREE, RTREE */
uint16 block_length; /* Length of keyblock (auto) */
uint16 underflow_block_length; /* When to execute underflow */
uint16 keylength; /* Tot length of keyparts (auto) */
@@ -163,9 +170,11 @@ typedef struct st_mi_decode_tree /* Decode huff-table */
struct st_mi_bit_buff;
-/* Note that null markers should always be first in a row !
- When creating a column, one should only specify:
- type, length, null_bit and null_pos */
+/*
+ Note that null markers should always be first in a row !
+ When creating a column, one should only specify:
+ type, length, null_bit and null_pos
+*/
typedef struct st_columndef /* column information */
{
@@ -184,12 +193,15 @@ typedef struct st_columndef /* column information */
#endif
} MI_COLUMNDEF;
+/* invalidator function reference for Query Cache */
+typedef void (* invalidator_by_filename)(const char * filename);
extern my_string myisam_log_filename; /* Name of logfile */
extern uint myisam_block_size;
-extern my_bool myisam_flush,myisam_delay_key_write;
+extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
extern my_bool myisam_concurrent_insert;
extern my_off_t myisam_max_temp_length,myisam_max_extra_temp_length;
+extern ulong myisam_bulk_insert_tree_size;
/* Prototypes for myisam-functions */
@@ -219,13 +231,14 @@ extern my_off_t mi_position(struct st_myisam_info *file);
extern int mi_status(struct st_myisam_info *info, MI_ISAMINFO *x, uint flag);
extern int mi_lock_database(struct st_myisam_info *file,int lock_type);
extern int mi_create(const char *name,uint keys,MI_KEYDEF *keydef,
- uint columns, MI_COLUMNDEF *columndef,
+ uint columns, MI_COLUMNDEF *columndef,
uint uniques, MI_UNIQUEDEF *uniquedef,
MI_CREATE_INFO *create_info, uint flags);
extern int mi_delete_table(const char *name);
extern int mi_rename(const char *from, const char *to);
extern int mi_extra(struct st_myisam_info *file,
- enum ha_extra_function function);
+ enum ha_extra_function function,
+ void *extra_arg);
extern ha_rows mi_records_in_range(struct st_myisam_info *info,int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,
@@ -239,42 +252,60 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
/* this is used to pass to mysql_myisamchk_table -- by Sasha Pachev */
-#define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r*/
-#define MYISAMCHK_VERIFY 2 /* run equivalent of myisamchk -c,
- * if corruption is detected, do myisamchk -r*/
-
-/* definitions needed for myisamchk.c -- by Sasha Pachev */
-
-#define T_VERBOSE 1
-#define T_SILENT 2
-#define T_DESCRIPT 4
-#define T_EXTEND 8
-#define T_INFO 16
-#define T_REP 32
-#define T_OPT 64 /* Not currently used */
-#define T_FORCE_CREATE 128
-#define T_WRITE_LOOP 256
-#define T_UNPACK 512
-#define T_STATISTICS 1024
-#define T_VERY_SILENT 2048
-#define T_SORT_RECORDS 4096
-#define T_SORT_INDEX 8192
-#define T_WAIT_FOREVER 16384
-#define T_REP_BY_SORT 32768L
-#define T_FAST 65536L
-#define T_READONLY 131072L
-#define T_MEDIUM T_READONLY*2
-#define T_AUTO_INC T_MEDIUM*2
-#define T_CHECK T_AUTO_INC*2
-#define T_UPDATE_STATE T_CHECK*2
-#define T_CHECK_ONLY_CHANGED T_UPDATE_STATE*2
-#define T_DONT_CHECK_CHECKSUM T_CHECK_ONLY_CHANGED*2
-#define T_TRUST_HEADER T_DONT_CHECK_CHECKSUM*2
-#define T_CREATE_MISSING_KEYS T_TRUST_HEADER*2
-#define T_SAFE_REPAIR T_CREATE_MISSING_KEYS*2
-#define T_AUTO_REPAIR T_SAFE_REPAIR*2
-#define T_BACKUP_DATA T_AUTO_REPAIR*2
-#define T_CALC_CHECKSUM T_BACKUP_DATA*2
+#define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r */
+#define MYISAMCHK_VERIFY 2 /* Verify, run repair if failure */
+
+/*
+ Definitions needed for myisamchk.c
+
+ Entries marked as "QQ to be removed" are NOT used to
+ pass check/repair options to mi_check.c. They are used
+ internally by myisamchk.c or/and ha_myisam.cc and should NOT
+ be stored together with other flags. They should be removed
+ from the following list to make addition of new flags possible.
+*/
+
+#define T_AUTO_INC 1
+#define T_AUTO_REPAIR 2 /* QQ to be removed */
+#define T_BACKUP_DATA 4
+#define T_CALC_CHECKSUM 8
+#define T_CHECK 16 /* QQ to be removed */
+#define T_CHECK_ONLY_CHANGED 32 /* QQ to be removed */
+#define T_CREATE_MISSING_KEYS 64
+#define T_DESCRIPT 128
+#define T_DONT_CHECK_CHECKSUM 256
+#define T_EXTEND 512
+#define T_FAST (1L << 10) /* QQ to be removed */
+#define T_FORCE_CREATE (1L << 11) /* QQ to be removed */
+#define T_FORCE_UNIQUENESS (1L << 12)
+#define T_INFO (1L << 13)
+#define T_MEDIUM (1L << 14)
+#define T_QUICK (1L << 15) /* QQ to be removed */
+#define T_READONLY (1L << 16) /* QQ to be removed */
+#define T_REP (1L << 17)
+#define T_REP_BY_SORT (1L << 18) /* QQ to be removed */
+#define T_REP_PARALLEL (1L << 19) /* QQ to be removed */
+#define T_RETRY_WITHOUT_QUICK (1L << 20)
+#define T_SAFE_REPAIR (1L << 21)
+#define T_SILENT (1L << 22)
+#define T_SORT_INDEX (1L << 23) /* QQ to be removed */
+#define T_SORT_RECORDS (1L << 24) /* QQ to be removed */
+#define T_STATISTICS (1L << 25)
+#define T_UNPACK (1L << 26)
+#define T_UPDATE_STATE (1L << 27)
+#define T_VERBOSE (1L << 28)
+#define T_VERY_SILENT (1L << 29)
+#define T_WAIT_FOREVER (1L << 30)
+#define T_WRITE_LOOP (1L << 31)
+
+#define T_REP_ANY (T_REP | T_REP_BY_SORT | T_REP_PARALLEL)
+
+/*
+ Flags used by myisamchk.c or/and ha_myisam.cc that are NOT passed
+ to mi_check.c follows:
+*/
+
+#define TT_USEFRM 1
#define O_NEW_INDEX 1 /* Bits set in out_flag */
#define O_NEW_DATA 2
@@ -282,31 +313,14 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
/* these struct is used by my_check to tell it what to do */
-typedef struct st_sort_key_blocks { /* Used when sorting */
+typedef struct st_sort_key_blocks /* Used when sorting */
+{
uchar *buff,*end_pos;
uchar lastkey[MI_MAX_POSSIBLE_KEY_BUFF];
uint last_length;
int inited;
} SORT_KEY_BLOCKS;
-struct st_mi_check_param;
-
-typedef struct st_sort_info {
- MI_INFO *info;
- struct st_mi_check_param *param;
- enum data_file_type new_data_file_type;
- SORT_KEY_BLOCKS *key_block,*key_block_end;
- uint key,find_length;
- my_off_t pos,max_pos,filepos,start_recpos,filelength,dupp,buff_length;
- ha_rows max_records;
- ulonglong unique[MI_MAX_KEY_SEG+1];
- my_bool fix_datafile;
- char *record,*buff;
- MI_KEYDEF *keyinfo;
- MI_KEYSEG *keyseg;
-} SORT_INFO;
-
-
typedef struct st_mi_check_param
{
ulonglong auto_increment_value;
@@ -319,18 +333,16 @@ typedef struct st_mi_check_param
ha_checksum record_checksum,glob_crc;
ulong use_buffers,read_buffer_length,write_buffer_length,
sort_buffer_length,sort_key_blocks;
- uint out_flag,warning_printed,error_printed,
- opt_rep_quick,verbose;
+ uint out_flag,warning_printed,error_printed,verbose;
uint opt_sort_key,total_files,max_level;
uint testflag;
uint8 language;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
- my_bool retry_repair,retry_without_quick, force_sort, calc_checksum;
+ my_bool retry_repair, force_sort, calc_checksum;
char temp_filename[FN_REFLEN],*isam_file_name,*tmpdir;
int tmpfile_createflag;
myf myf_rw;
IO_CACHE read_cache;
- SORT_INFO sort_info;
ulonglong unique_count[MI_MAX_KEY_SEG+1];
ha_checksum key_crc[MI_MAX_POSSIBLE_KEY];
ulong rec_per_key_part[MI_MAX_KEY_SEG*MI_MAX_POSSIBLE_KEY];
@@ -340,18 +352,50 @@ typedef struct st_mi_check_param
} MI_CHECK;
-typedef struct st_mi_sortinfo {
+typedef struct st_sort_info
+{
+ MI_INFO *info;
+ MI_CHECK *param;
+ enum data_file_type new_data_file_type;
+ SORT_KEY_BLOCKS *key_block,*key_block_end;
+ uint current_key, total_keys;
+ my_off_t filelength,dupp,buff_length;
ha_rows max_records;
+ char *buff;
+ myf myf_rw;
+ /* sync things*/
+ uint got_error, threads_running;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+} SORT_INFO;
+
+
+typedef struct st_mi_sort_param
+{
+ pthread_t thr;
+ IO_CACHE read_cache;
+ ulonglong unique[MI_MAX_KEY_SEG+1];
+ uint key, key_length,real_key_length,sortbuff_size;
+ uint maxbuffers, keys, find_length, sort_keys_length;
+ uchar **sort_keys;
+ byte *rec_buff;
+ uint alloced_rec_buff_length;
+ void *wordlist, *wordptr;
+ MI_KEYDEF *keyinfo;
SORT_INFO *sort_info;
+ IO_CACHE tempfile, tempfile_for_exceptions;
+ DYNAMIC_ARRAY buffpek;
+ my_off_t pos,max_pos,filepos,start_recpos;
+ my_bool fix_datafile, master;
+ char *record;
char *tmpdir;
- int (*key_cmp)(SORT_INFO *info, const void *, const void *);
- int (*key_read)(SORT_INFO *info,void *buff);
- int (*key_write)(SORT_INFO *info, const void *buff);
- void (*lock_in_memory)(MI_CHECK *info);
- uint key_length;
- myf myf_rw;
+ int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *);
+ int (*key_read)(struct st_mi_sort_param *,void *);
+ int (*key_write)(struct st_mi_sort_param *, const void *);
+ void (*lock_in_memory)(MI_CHECK *);
} MI_SORT_PARAM;
+
/* functions in mi_check */
void myisamchk_init(MI_CHECK *param);
int chk_status(MI_CHECK *param, MI_INFO *info);
@@ -364,6 +408,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name);
int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
const char * name, int rep_quick);
+int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
+ const char * name, int rep_quick);
int change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext, uint raid_chunks,
myf myflags);
@@ -374,14 +420,15 @@ int flush_blocks(MI_CHECK *param, File file);
void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
my_bool repair);
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update);
+void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
+ ulonglong *unique, ulonglong records);
int filecopy(MI_CHECK *param, File to,File from,my_off_t start,
my_off_t length, const char *type);
int movepoint(MI_INFO *info,byte *record,my_off_t oldpos,
my_off_t newpos, uint prot_key);
-int sort_write_record(SORT_INFO *sort_info);
- int write_data_suffix(MI_CHECK *param, MI_INFO *info);
-int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
- ulong);
+int sort_write_record(MI_SORT_PARAM *sort_param);
+int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile);
+int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulong);
int test_if_almost_full(MI_INFO *info);
int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
diff --git a/include/myisammrg.h b/include/myisammrg.h
index a797c954614..c3b3b39424b 100644
--- a/include/myisammrg.h
+++ b/include/myisammrg.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using merge_isam_funktions */
@@ -34,6 +33,13 @@ extern "C" {
#define MYRG_NAME_EXT ".MRG"
+/* In which table to INSERT rows */
+#define MERGE_INSERT_DISABLED 0
+#define MERGE_INSERT_TO_FIRST 1
+#define MERGE_INSERT_TO_LAST 2
+
+extern TYPELIB merge_insert_method;
+
/* Param to/from myrg_info */
typedef struct st_mymerge_info /* Struct from h_info */
@@ -44,7 +50,7 @@ typedef struct st_mymerge_info /* Struct from h_info */
ulonglong data_file_length;
uint reclength; /* Recordlength */
int errkey; /* With key was dupplicated on err */
- uint options; /* HA_OPTIONS_... used */
+ uint options; /* HA_OPTION_... used */
} MYMERGE_INFO;
typedef struct st_myrg_table_info
@@ -59,10 +65,12 @@ typedef struct st_myrg_info
ulonglong records; /* records in tables */
ulonglong del; /* Removed records */
ulonglong data_file_length;
+ ulong cache_size;
+ uint merge_insert_method;
uint tables,options,reclength,keys;
my_bool cache_in_use;
- LIST open_list;
- QUEUE by_key;
+ LIST open_list;
+ QUEUE by_key;
} MYRG_INFO;
@@ -81,11 +89,14 @@ extern int myrg_rkey(MYRG_INFO *file,byte *buf,int inx,const byte *key,
extern int myrg_rrnd(MYRG_INFO *file,byte *buf,ulonglong pos);
extern int myrg_rsame(MYRG_INFO *file,byte *record,int inx);
extern int myrg_update(MYRG_INFO *file,const byte *old,byte *new_rec);
+extern int myrg_write(MYRG_INFO *info,byte *rec);
extern int myrg_status(MYRG_INFO *file,MYMERGE_INFO *x,int flag);
extern int myrg_lock_database(MYRG_INFO *file,int lock_type);
-extern int myrg_create(const char *name,const char **table_names,
- my_bool fix_names);
-extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function);
+extern int myrg_create(const char *name, const char **table_names,
+ uint insert_method, my_bool fix_names);
+extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function,
+ void *extra_arg);
+extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv);
extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,
diff --git a/include/myisampack.h b/include/myisampack.h
index a51cdc7e6eb..31666bb184c 100644
--- a/include/myisampack.h
+++ b/include/myisampack.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Storing of values in high byte first order.
diff --git a/include/mysql.h b/include/mysql.h
index 0bd5b7092b8..af3e8c773ef 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -1,21 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-/* defines for the libmysql library */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _mysql_h
#define _mysql_h
@@ -28,12 +25,10 @@
#undef __WIN__
#endif
-#ifndef MYSQL_SERVER
#ifdef __cplusplus
extern "C" {
#endif
-#endif
-
+
#ifndef _global_h /* If not standard header */
#include <sys/types.h>
#ifdef __LCC__
@@ -50,32 +45,15 @@ typedef char my_bool;
#endif
typedef char * gptr;
-#ifndef ST_USED_MEM_DEFINED
-#define ST_USED_MEM_DEFINED
-typedef struct st_used_mem { /* struct for once_alloc */
- struct st_used_mem *next; /* Next block in use */
- unsigned int left; /* memory left in block */
- unsigned int size; /* size of block */
-} USED_MEM;
-typedef struct st_mem_root {
- USED_MEM *free;
- USED_MEM *used;
- USED_MEM *pre_alloc;
- unsigned int min_malloc;
- unsigned int block_size;
-
- void (*error_handler)(void);
-} MEM_ROOT;
-#endif
-
#ifndef my_socket_defined
#ifdef __WIN__
#define my_socket SOCKET
#else
typedef int my_socket;
-#endif
-#endif
-#endif
+#endif /* __WIN__ */
+#endif /* my_socket_defined */
+#endif /* _global_h */
+
#include "mysql_com.h"
#include "mysql_version.h"
@@ -92,12 +70,14 @@ extern char *mysql_unix_port;
typedef struct st_mysql_field {
char *name; /* Name of column */
char *table; /* Table of column if column was a field */
+ char *org_table; /* Org table name if table was an alias */
+ char *db; /* Database for table */
char *def; /* Default value (set by mysql_list_fields) */
- enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
- unsigned int length; /* Width of column */
- unsigned int max_length; /* Max width of selected set */
+ unsigned long length; /* Width of column */
+ unsigned long max_length; /* Max width of selected set */
unsigned int flags; /* Div flags */
unsigned int decimals; /* Number of decimals in field */
+ enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
} MYSQL_FIELD;
typedef char **MYSQL_ROW; /* return data as array of strings */
@@ -120,6 +100,8 @@ typedef struct st_mysql_rows {
typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
+#include <my_alloc.h>
+
typedef struct st_mysql_data {
my_ulonglong rows;
unsigned int fields;
@@ -129,15 +111,31 @@ typedef struct st_mysql_data {
struct st_mysql_options {
unsigned int connect_timeout,client_flag;
- my_bool compress,named_pipe;
unsigned int port;
char *host,*init_command,*user,*password,*unix_socket,*db;
char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
- my_bool use_ssl; /* if to use SSL or not */
char *ssl_key; /* PEM key file */
char *ssl_cert; /* PEM cert file */
char *ssl_ca; /* PEM CA file */
char *ssl_capath; /* PEM directory of CA-s? */
+ char *ssl_cipher; /* cipher to use */
+ my_bool use_ssl; /* if to use SSL or not */
+ my_bool compress,named_pipe;
+ /*
+ On connect, find out the replication role of the server, and
+ establish connections to all the peers
+ */
+ my_bool rpl_probe;
+ /*
+ Each call to mysql_real_query() will parse it to tell if it is a read
+ or a write, and direct it to the slave or the master
+ */
+ my_bool rpl_parse;
+ /*
+ If set, never read from a master,only from slave, when doing
+ a read that is replication-aware
+ */
+ my_bool no_master_reads;
};
enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
@@ -149,48 +147,116 @@ enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
MYSQL_STATUS_USE_RESULT};
+/*
+ There are three types of queries - the ones that have to go to
+ the master, the ones that go to a slave, and the adminstrative
+ type which must happen on the pivot connectioin
+*/
+enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE,
+ MYSQL_RPL_ADMIN };
+
+
typedef struct st_mysql {
NET net; /* Communication parameters */
gptr connector_fd; /* ConnectorFd for SSL */
char *host,*user,*passwd,*unix_socket,*server_version,*host_info,
*info,*db;
- unsigned int port,client_flag,server_capabilities;
- unsigned int protocol_version;
- unsigned int field_count;
- unsigned int server_status;
- unsigned long thread_id; /* Id for connection in server */
+ struct charset_info_st *charset;
+ MYSQL_FIELD *fields;
+ MEM_ROOT field_alloc;
my_ulonglong affected_rows;
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
my_ulonglong extra_info; /* Used by mysqlshow */
+ unsigned long thread_id; /* Id for connection in server */
unsigned long packet_length;
+ unsigned int port,client_flag,server_capabilities;
+ unsigned int protocol_version;
+ unsigned int field_count;
+ unsigned int server_status;
+ unsigned int server_language;
+ struct st_mysql_options options;
enum mysql_status status;
- MYSQL_FIELD *fields;
- MEM_ROOT field_alloc;
my_bool free_me; /* If free in mysql_close */
my_bool reconnect; /* set to 1 if automatic reconnect */
- struct st_mysql_options options;
char scramble_buff[9];
- struct charset_info_st *charset;
- unsigned int server_language;
+
+ /*
+ Set if this is the original connection, not a master or a slave we have
+ added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave()
+ */
+ my_bool rpl_pivot;
+ /*
+ Pointers to the master, and the next slave connections, points to
+ itself if lone connection.
+ */
+ struct st_mysql* master, *next_slave;
+
+ struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
+ /* needed for send/read/store/use result to work correctly with replication */
+ struct st_mysql* last_used_con;
} MYSQL;
typedef struct st_mysql_res {
my_ulonglong row_count;
- unsigned int field_count, current_field;
MYSQL_FIELD *fields;
MYSQL_DATA *data;
MYSQL_ROWS *data_cursor;
+ unsigned long *lengths; /* column lengths of current row */
+ MYSQL *handle; /* for unbuffered reads */
MEM_ROOT field_alloc;
+ unsigned int field_count, current_field;
MYSQL_ROW row; /* If unbuffered read */
MYSQL_ROW current_row; /* buffer to current row */
- unsigned long *lengths; /* column lengths of current row */
- MYSQL *handle; /* for unbuffered reads */
- my_bool eof; /* Used my mysql_fetch_row */
+ my_bool eof; /* Used by mysql_fetch_row */
} MYSQL_RES;
-/* Functions to get information from the MYSQL and MYSQL_RES structures */
-/* Should definitely be used if one uses shared libraries */
+#define MAX_MYSQL_MANAGER_ERR 256
+#define MAX_MYSQL_MANAGER_MSG 256
+
+#define MANAGER_OK 200
+#define MANAGER_INFO 250
+#define MANAGER_ACCESS 401
+#define MANAGER_CLIENT_ERR 450
+#define MANAGER_INTERNAL_ERR 500
+
+
+
+typedef struct st_mysql_manager
+{
+ NET net;
+ char *host,*user,*passwd;
+ unsigned int port;
+ my_bool free_me;
+ my_bool eof;
+ int cmd_status;
+ int last_errno;
+ char* net_buf,*net_buf_pos,*net_data_end;
+ int net_buf_size;
+ char last_error[MAX_MYSQL_MANAGER_ERR];
+} MYSQL_MANAGER;
+
+/*
+ Set up and bring down the server; to ensure that applications will
+ work when linked against either the standard client library or the
+ embedded server library, these functions should be called.
+*/
+int STDCALL mysql_server_init(int argc, char **argv, char **groups);
+void STDCALL mysql_server_end(void);
+
+/*
+ Set up and bring down a thread; these function should be called
+ for each thread in an application which opens at least one MySQL
+ connection. All uses of the connection(s) should be between these
+ function calls.
+*/
+my_bool STDCALL mysql_thread_init(void);
+void STDCALL mysql_thread_end(void);
+
+/*
+ Functions to get information from the MYSQL and MYSQL_RES structures
+ Should definitely be used if one uses shared libraries.
+*/
my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
@@ -198,31 +264,24 @@ my_bool STDCALL mysql_eof(MYSQL_RES *res);
MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res,
unsigned int fieldnr);
MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res);
-MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res);
-unsigned int STDCALL mysql_field_tell(MYSQL_RES *res);
+MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res);
+MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res);
unsigned int STDCALL mysql_field_count(MYSQL *mysql);
my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
unsigned int STDCALL mysql_errno(MYSQL *mysql);
-char * STDCALL mysql_error(MYSQL *mysql);
-char * STDCALL mysql_info(MYSQL *mysql);
+const char * STDCALL mysql_error(MYSQL *mysql);
+const char * STDCALL mysql_info(MYSQL *mysql);
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
MYSQL * STDCALL mysql_init(MYSQL *mysql);
-#ifdef HAVE_OPENSSL
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
- const char *capath);
-char * STDCALL mysql_ssl_cipher(MYSQL *mysql);
-int STDCALL mysql_ssl_clear(MYSQL *mysql);
-#endif /* HAVE_OPENSSL */
-MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
- const char *user, const char *passwd);
+ const char *capath, const char *cipher);
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db);
-#if MYSQL_VERSION_ID >= 32200
MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
const char *user,
const char *passwd,
@@ -230,34 +289,65 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
unsigned int port,
const char *unix_socket,
unsigned int clientflag);
-#else
-MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
- const char *user,
- const char *passwd,
- unsigned int port,
- const char *unix_socket,
- unsigned int clientflag);
-#endif
void STDCALL mysql_close(MYSQL *sock);
int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
- unsigned int length);
+ unsigned long length);
int STDCALL mysql_read_query_result(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
- unsigned int length);
-int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
-int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
+ unsigned long length);
+/* perform query on master */
+int STDCALL mysql_master_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+/* perform query on slave */
+int STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+
+/*
+ enable/disable parsing of all queries to decide if they go on master or
+ slave
+*/
+void STDCALL mysql_enable_rpl_parse(MYSQL* mysql);
+void STDCALL mysql_disable_rpl_parse(MYSQL* mysql);
+/* get the value of the parse flag */
+int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
+
+/* enable/disable reads from master */
+void STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
+void STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
+/* get the value of the master read flag */
+int STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
+
+enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len);
+
+/* discover the master and its slaves */
+int STDCALL mysql_rpl_probe(MYSQL* mysql);
+
+/* set the master, close/free the old one, if it is not a pivot */
+int STDCALL mysql_set_master(MYSQL* mysql, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd);
+int STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd);
+
int STDCALL mysql_shutdown(MYSQL *mysql);
int STDCALL mysql_dump_debug_info(MYSQL *mysql);
int STDCALL mysql_refresh(MYSQL *mysql,
unsigned int refresh_options);
int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
int STDCALL mysql_ping(MYSQL *mysql);
-char * STDCALL mysql_stat(MYSQL *mysql);
-char * STDCALL mysql_get_server_info(MYSQL *mysql);
-char * STDCALL mysql_get_client_info(void);
-char * STDCALL mysql_get_host_info(MYSQL *mysql);
+const char * STDCALL mysql_stat(MYSQL *mysql);
+const char * STDCALL mysql_get_server_info(MYSQL *mysql);
+const char * STDCALL mysql_get_client_info(void);
+const char * STDCALL mysql_get_host_info(MYSQL *mysql);
unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
@@ -271,7 +361,8 @@ int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
void STDCALL mysql_free_result(MYSQL_RES *result);
void STDCALL mysql_data_seek(MYSQL_RES *result,
my_ulonglong offset);
-MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET);
+MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result,
+ MYSQL_ROW_OFFSET offset);
MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
MYSQL_FIELD_OFFSET offset);
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
@@ -295,18 +386,40 @@ char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
unsigned long *length));
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
-
-
+MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con);
+MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
+ const char* host,
+ const char* user,
+ const char* passwd,
+ unsigned int port);
+void STDCALL mysql_manager_close(MYSQL_MANAGER* con);
+int STDCALL mysql_manager_command(MYSQL_MANAGER* con,
+ const char* cmd, int cmd_len);
+int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
+ char* res_buf,
+ int res_buf_size);
#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
-/* new api functions */
-
+#ifdef USE_OLD_FUNCTIONS
+MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
+ const char *user, const char *passwd);
+int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
+int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
+#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
+#endif
#define HAVE_MYSQL_REAL_CONNECT
-#ifndef MYSQL_SERVER
+/*
+ The following functions are mainly exported because of mysqlbinlog;
+ They are not for general usage
+*/
+
+int simple_command(MYSQL *mysql,enum enum_server_command command,
+ const char *arg, unsigned long length, my_bool skipp_check);
+unsigned long net_safe_read(MYSQL* mysql);
+
#ifdef __cplusplus
}
#endif
-#endif
-#endif
+#endif /* _mysql_h */
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 525a631caf6..641c4b95f24 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Common definition between mysql server & client
@@ -22,7 +21,6 @@
#ifndef _mysql_com_h
#define _mysql_com_h
-
#define NAME_LEN 64 /* Field/table name length */
#define HOSTNAME_LENGTH 60
#define USERNAME_LENGTH 16
@@ -42,7 +40,8 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
COM_CHANGE_USER, COM_BINLOG_DUMP,
- COM_TABLE_DUMP, COM_CONNECT_OUT};
+ COM_TABLE_DUMP, COM_CONNECT_OUT,
+ COM_REGISTER_SLAVE};
#define NOT_NULL_FLAG 1 /* Field can't be NULL */
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
@@ -77,6 +76,12 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
#define REFRESH_FAST 32768 /* Intern flag */
+/* RESET (remove all queries) from query cache */
+#define REFRESH_QUERY_CACHE 65536
+#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
+#define REFRESH_DES_KEY_FILE 0x40000L
+#define REFRESH_USER_RESOURCES 0x80000L
+
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
#define CLIENT_LONG_FLAG 4 /* Get all column flags */
@@ -86,7 +91,6 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define CLIENT_ODBC 64 /* Odbc client */
#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */
#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */
-#define CLIENT_CHANGE_USER 512 /* Support the mysql_change_user() */
#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */
#define CLIENT_SSL 2048 /* Switch to SSL after handshake */
#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */
@@ -100,36 +104,37 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define NET_WRITE_TIMEOUT 60 /* Timeout on write */
#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
-#ifndef Vio_defined
-#define Vio_defined
-#ifdef HAVE_VIO
-class Vio; /* Fill Vio class in C++ */
-#else
struct st_vio; /* Only C */
typedef struct st_vio Vio;
-#endif
-#endif
+
+#define MAX_CHAR_WIDTH 255 /* Max length for a CHAR colum */
+#define MAX_BLOB_WIDTH 8192 /* Default width for blob */
typedef struct st_net {
Vio* vio;
+ unsigned char *buff,*buff_end,*write_pos,*read_pos;
my_socket fd; /* For Perl DBI/dbd */
+ unsigned long max_packet,max_packet_size;
+ unsigned int last_errno,pkt_nr,compress_pkt_nr;
+ unsigned int write_timeout,read_timeout;
int fcntl;
- unsigned char *buff,*buff_end,*write_pos,*read_pos;
char last_error[MYSQL_ERRMSG_SIZE];
- unsigned int last_errno,max_packet,timeout,pkt_nr;
unsigned char error;
my_bool return_errno,compress;
- my_bool no_send_ok; /* needed if we are doing several
- queries in one command ( as in LOAD TABLE ... FROM MASTER ),
- and do not want to confuse the client with OK at the wrong time
- */
+ /*
+ The following variable is set if we are doing several queries in one
+ command ( as in LOAD TABLE ... FROM MASTER ),
+ and do not want to confuse the client with OK at the wrong time
+ */
unsigned long remain_in_buf,length, buf_length, where_b;
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
+ my_bool no_send_ok;
+ gptr query_cache_query;
} NET;
-#define packet_error ((unsigned int) -1)
+#define packet_error (~(unsigned long) 0)
enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
FIELD_TYPE_SHORT, FIELD_TYPE_LONG,
@@ -146,18 +151,21 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
FIELD_TYPE_LONG_BLOB=251,
FIELD_TYPE_BLOB=252,
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_INTERVAL FIELD_TYPE_ENUM /* For compability */
-extern unsigned long max_allowed_packet;
-extern unsigned long net_buffer_length;
-
#define net_new_transaction(net) ((net)->pkt_nr=0)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int my_net_init(NET *net, Vio* vio);
+void my_net_local_init(NET *net);
void net_end(NET *net);
void net_clear(NET *net);
int net_flush(NET *net);
@@ -165,13 +173,22 @@ int my_net_write(NET *net,const char *packet,unsigned long len);
int net_write_command(NET *net,unsigned char command,const char *packet,
unsigned long len);
int net_real_write(NET *net,const char *packet,unsigned long len);
-unsigned int my_net_read(NET *net);
+unsigned long my_net_read(NET *net);
+
+/* The following function is not meant for normal usage */
+struct sockaddr;
+int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
+ unsigned int timeout);
struct rand_struct {
unsigned long seed1,seed2,max_value;
double max_value_dbl;
};
+#ifdef __cplusplus
+}
+#endif
+
/* The following is for user defined functions */
enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT};
@@ -191,7 +208,7 @@ typedef struct st_udf_init
{
my_bool maybe_null; /* 1 if function can return NULL */
unsigned int decimals; /* for real functions */
- unsigned int max_length; /* For string functions */
+ unsigned long max_length; /* For string functions */
char *ptr; /* free pointer for function data */
my_bool const_item; /* 0 if result is independent of arguments */
} UDF_INIT;
@@ -205,7 +222,10 @@ typedef struct st_udf_init
#ifdef __cplusplus
extern "C" {
#endif
-
+
+extern unsigned long max_allowed_packet;
+extern unsigned long net_buffer_length;
+
void randominit(struct rand_struct *,unsigned long seed1,
unsigned long seed2);
double rnd(struct rand_struct *);
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
new file mode 100644
index 00000000000..bc75c3fbcb8
--- /dev/null
+++ b/include/mysql_embed.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Defines that are unique to the embedded version of MySQL */
+
+#ifdef EMBEDDED_LIBRARY
+
+/* Things we don't need in the embedded version of MySQL */
+
+#undef HAVE_PSTACK /* No stacktrace */
+#undef HAVE_DLOPEN /* No udf functions */
+#undef HAVE_OPENSSL
+#undef HAVE_VIO
+#undef HAVE_ISAM
+
+#define DONT_USE_RAID
+
+#undef MYSQL_SERVER_SUFFIX
+#define MYSQL_SERVER_SUFFIX "-embedded"
+
+#endif /* EMBEDDED_LIBRARY */
diff --git a/include/mysql_version.h.in b/include/mysql_version.h.in
index 44fd00f806a..5d738ce3326 100644
--- a/include/mysql_version.h.in
+++ b/include/mysql_version.h.in
@@ -3,6 +3,8 @@
/* Version numbers for protocol & mysqld */
+#ifndef _mysql_version_h
+#define _mysql_version_h
#ifdef _CUSTOMCONFIG_
#include <custom_conf.h>
#else
@@ -17,5 +19,6 @@
/* mysqld compile time options */
#ifndef MYSQL_CHARSET
#define MYSQL_CHARSET "@default_charset@"
-#endif
-#endif
+#endif /* MYSQL_CHARSET */
+#endif /* _CUSTOMCONFIG_ */
+#endif /* _mysql_version_h */
diff --git a/include/mysqld_error.h b/include/mysqld_error.h
index f0fb11c1832..9f0ea9d7988 100644
--- a/include/mysqld_error.h
+++ b/include/mysqld_error.h
@@ -234,4 +234,22 @@
#define ER_CANNOT_ADD_FOREIGN 1215
#define ER_NO_REFERENCED_ROW 1216
#define ER_ROW_IS_REFERENCED 1217
-#define ER_ERROR_MESSAGES 218
+#define ER_CONNECT_TO_MASTER 1218
+#define ER_QUERY_ON_MASTER 1219
+#define ER_ERROR_WHEN_EXECUTING_COMMAND 1220
+#define ER_WRONG_USAGE 1221
+#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1222
+#define ER_CANT_UPDATE_WITH_READLOCK 1223
+#define ER_MIXING_NOT_ALLOWED 1224
+#define ER_DUP_ARGUMENT 1225
+#define ER_USER_LIMIT_REACHED 1226
+#define ER_SPECIFIC_ACCESS_DENIED_ERROR 1227
+#define ER_LOCAL_VARIABLE 1228
+#define ER_GLOBAL_VARIABLE 1229
+#define ER_NO_DEFAULT 1230
+#define ER_WRONG_VALUE_FOR_VAR 1231
+#define ER_WRONG_TYPE_FOR_VAR 1232
+#define ER_VAR_CANT_BE_READ 1233
+#define ER_CANT_USE_OPTION_HERE 1234
+#define ER_NOT_SUPPORTED_YET 1235
+#define ER_ERROR_MESSAGES 236
diff --git a/include/mysys_err.h b/include/mysys_err.h
index 2d23ead36b6..a86765c74fd 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _mysys_err_h
#define _mysys_err_h
@@ -55,7 +54,23 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EE_CANT_SYMLINK 25
#define EE_REALPATH 26
+ /* exit codes for all MySQL programs */
+
+#define EXIT_UNSPECIFIED_ERROR 1
+#define EXIT_UNKNOWN_OPTION 2
+#define EXIT_AMBIGUOUS_OPTION 3
+#define EXIT_NO_ARGUMENT_ALLOWED 4
+#define EXIT_ARGUMENT_REQUIRED 5
+#define EXIT_VAR_PREFIX_NOT_UNIQUE 6
+#define EXIT_UNKNOWN_VARIABLE 7
+#define EXIT_OUT_OF_MEMORY 8
+#define EXIT_UNKNOWN_SUFFIX 9
+#define EXIT_NO_PTR_TO_VARIABLE 10
+#define EXIT_CANNOT_CONNECT_TO_SERVICE 11
+
+
#ifdef __cplusplus
}
#endif
#endif
+
diff --git a/include/nisam.h b/include/nisam.h
index 7ce2b44ee79..e8f29991a4e 100644
--- a/include/nisam.h
+++ b/include/nisam.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using nisam_funktions */
/* Author: Michael Widenius */
diff --git a/include/queues.h b/include/queues.h
index 66125e650ca..70cb99a1513 100644
--- a/include/queues.h
+++ b/include/queues.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for generell handling of priority Queues.
@@ -53,6 +52,7 @@ void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,byte *element);
byte *queue_remove(QUEUE *queue,uint idx);
void _downheap(QUEUE *queue,uint idx);
+void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0)
#ifdef __cplusplus
diff --git a/include/raid.h b/include/raid.h
index 8cbd0f1a442..4a988760157 100644
--- a/include/raid.h
+++ b/include/raid.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Parser needs these defines always, even if USE_RAID is not defined */
#define RAID_TYPE_0 1 /* Striping */
@@ -23,15 +22,10 @@
#define RAID_DEFAULT_CHUNKS 4
#define RAID_DEFAULT_CHUNKSIZE 256*1024 /* 256kB */
+C_MODE_START
+#define my_raid_type(raid_type) raid_type_string[(int)(raid_type)]
extern const char *raid_type_string[];
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-const char *my_raid_type(int raid_type);
-#ifdef __cplusplus
-}
-#endif
+C_MODE_END
#if defined(USE_RAID) && !defined(DONT_USE_RAID)
diff --git a/include/rijndael.h b/include/rijndael.h
new file mode 100644
index 00000000000..e286c89cbdc
--- /dev/null
+++ b/include/rijndael.h
@@ -0,0 +1,42 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ rijndael-alg-fst.h
+
+ @version 3.0 (December 2000)
+ Optimised ANSI C code for the Rijndael cipher (now AES)
+ @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ @author Paulo Barreto <paulo.barreto@terra.com.br>
+
+ This code is hereby placed in the public domain.
+ Modified by Peter Zaitsev to fit MySQL coding style.
+ */
+
+#define AES_MAXKC (256/32)
+#define AES_MAXKB (256/8)
+#define AES_MAXNR 14
+
+int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits);
+int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits);
+void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 pt[16], uint8 ct[16]);
+void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 ct[16], uint8 pt[16]);
diff --git a/include/sha1.h b/include/sha1.h
new file mode 100644
index 00000000000..1c345469d3c
--- /dev/null
+++ b/include/sha1.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ This is the header file for code which implements the Secure
+ Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
+ April 17, 1995.
+
+ Many of the variable names in this code, especially the
+ single character names, were used because those were the names
+ used in the publication.
+
+ Please read the file sha1.c for more information.
+
+ Modified 2002 by Peter Zaitsev to better follow MySQL standards
+*/
+
+
+enum sha_result_codes
+{
+ SHA_SUCCESS = 0,
+ SHA_NULL, /* Null pointer parameter */
+ SHA_INPUT_TOO_LONG, /* input data too long */
+ SHA_STATE_ERROR /* called Input after Result */
+};
+
+#define SHA1_HASH_SIZE 20 /* Hash size in bytes */
+
+/*
+ This structure will hold context information for the SHA-1
+ hashing operation
+*/
+
+typedef struct SHA1_CONTEXT
+{
+ ulonglong Length; /* Message length in bits */
+ uint32 Intermediate_Hash[SHA1_HASH_SIZE/4]; /* Message Digest */
+ int Computed; /* Is the digest computed? */
+ int Corrupted; /* Is the message digest corrupted? */
+ int16 Message_Block_Index; /* Index into message block array */
+ uint8 Message_Block[64]; /* 512-bit message blocks */
+} SHA1_CONTEXT;
+
+/*
+ Function Prototypes
+*/
+
+C_MODE_START
+
+int sha1_reset( SHA1_CONTEXT* );
+int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int );
+int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] );
+
+C_MODE_END
diff --git a/include/sslopt-case.h b/include/sslopt-case.h
index d995e31044e..331c9a307f1 100644
--- a/include/sslopt-case.h
+++ b/include/sslopt-case.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef HAVE_OPENSSL
case OPT_SSL_SSL:
@@ -21,8 +20,8 @@
break;
case OPT_SSL_KEY:
opt_use_ssl = 1; /* true */
- my_free(opt_ssl_key, MYF(MY_ALLOW_ZERO_PTR));
- opt_ssl_key = my_strdup(optarg, MYF(0));
+/* QQ to be removed??? my_free(opt_ssl_key, MYF(MY_ALLOW_ZERO_PTR)); */
+/* QQ to be removed??? opt_ssl_key = my_strdup(optarg, MYF(0)); */
break;
case OPT_SSL_CERT:
opt_use_ssl = 1; /* true */
@@ -36,7 +35,12 @@
break;
case OPT_SSL_CAPATH:
opt_use_ssl = 1; /* true */
- my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
- opt_ssl_ca = my_strdup(optarg, MYF(0));
+ my_free(opt_ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
+ opt_ssl_capath = my_strdup(optarg, MYF(0));
+ break;
+ case OPT_SSL_CIPHER:
+ opt_use_ssl = 1; /* true */
+ my_free(opt_ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ opt_ssl_cipher = my_strdup(optarg, MYF(0));
break;
#endif
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index 2f58f0e9265..d82c833c439 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -1,31 +1,41 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef HAVE_OPENSSL
-#define OPT_SSL_SSL 200
-#define OPT_SSL_KEY 201
-#define OPT_SSL_CERT 202
-#define OPT_SSL_CA 203
-#define OPT_SSL_CAPATH 204
- {"ssl", no_argument, 0, OPT_SSL_SSL},
- {"ssl-key", required_argument, 0, OPT_SSL_KEY},
- {"ssl-cert", required_argument, 0, OPT_SSL_CERT},
- {"ssl-ca", required_argument, 0, OPT_SSL_CA},
- {"ssl-capath", required_argument, 0, OPT_SSL_CAPATH},
+ {"ssl", OPT_SSL_SSL,
+ "Use SSL for connection (automatically set with other flags)",
+ (gptr*) &opt_use_ssl, (gptr*) &opt_use_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl)",
+ (gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl)",
+ (gptr*) &opt_ssl_cert, (gptr*) &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-ca", OPT_SSL_CA,
+ "CA file in PEM format (check OpenSSL docs, implies --ssl)",
+ (gptr*) &opt_ssl_ca, (gptr*) &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-capath", OPT_SSL_CAPATH,
+ "CA directory (check OpenSSL docs, implies --ssl)",
+ (gptr*) &opt_ssl_capath, (gptr*) &opt_ssl_capath, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-cipher", OPT_SSL_CAPATH, "SSL cipher to use (implies --ssl)",
+ (gptr*) &opt_ssl_cipher, (gptr*) &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
diff --git a/include/sslopt-usage.h b/include/sslopt-usage.h
index 5b2b4a88709..e5e374dea44 100644
--- a/include/sslopt-usage.h
+++ b/include/sslopt-usage.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef OPEN_SSL
puts("\
@@ -21,5 +20,6 @@
--ssl-key X509 key in PEM format (implies --ssl)\n\
--ssl-cert X509 cert in PEM format (implies --ssl)\n\
--ssl-ca CA file in PEM format (check OpenSSL docs, implies --ssl)\n\
- --ssl-capath CA directory (check OpenSSL docs, implies --ssl)");
+ --ssl-capath CA directory (check OpenSSL docs, implies --ssl)\n\
+ --ssl-cipher SSL cipher to use (implies --ssl)");
#endif
diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h
index 597ab4d9fa6..164cf541381 100644
--- a/include/sslopt-vars.h
+++ b/include/sslopt-vars.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef HAVE_OPENSSL
static my_bool opt_use_ssl = 0;
@@ -21,4 +20,5 @@ static char *opt_ssl_key = 0;
static char *opt_ssl_cert = 0;
static char *opt_ssl_ca = 0;
static char *opt_ssl_capath = 0;
+static char *opt_ssl_cipher = 0;
#endif
diff --git a/include/t_ctype.h b/include/t_ctype.h
index f6e799828e6..3e190977e6c 100644
--- a/include/t_ctype.h
+++ b/include/t_ctype.h
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/*
Copyright (C) 1998, 1999 by Pruet Boonma, all rights reserved.
Copyright (C) 1998 by Theppitak Karoonboonyanan, all rights reserved.
@@ -121,7 +137,7 @@ enum l1_symbols {
L1_SARA_AI_MAIMUAN,
L1_SARA_AI_MAIMALAI
};
-
+
/* level 2 symbols & order */
enum l2_symbols {
L2_BLANK = TOT_LEVELS,
@@ -135,7 +151,7 @@ enum l2_symbols {
L2_TONE3,
L2_TONE4
};
-
+
/* level 3 symbols & order */
enum l3_symbols {
L3_BLANK = TOT_LEVELS,
diff --git a/include/thr_alarm.h b/include/thr_alarm.h
index 1f3fed1d29b..30825d49158 100644
--- a/include/thr_alarm.h
+++ b/include/thr_alarm.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Prototypes when using thr_alarm library functions */
@@ -39,24 +38,32 @@ extern "C" {
#define THR_SERVER_ALARM SIGALRM
#endif
-#if defined(DONT_USE_THR_ALARM)
+typedef struct st_alarm_info
+{
+ ulong next_alarm_time;
+ uint active_alarms;
+ uint max_used_alarms;
+} ALARM_INFO;
+
+void thr_alarm_info(ALARM_INFO *info);
+
+#if defined(DONT_USE_THR_ALARM) || !defined(THREAD)
#define USE_ALARM_THREAD
#undef USE_ONE_SIGNAL_HAND
-typedef struct st_thr_alarm_entry
-{
- uint crono;
-} thr_alarm_entry;
+typedef my_bool thr_alarm_t;
+typedef my_bool ALARM;
-#define thr_alarm_init(A) (A)->crono=0
-#define thr_alarm_in_use(A) (A)->crono
+#define thr_alarm_init(A) (*(A))=0
+#define thr_alarm_in_use(A) (*(A) != 0)
+#define thr_end_alarm(A)
+#define thr_alarm(A,B,C) ((*(A)=1)-1)
+/* The following should maybe be (*(A)) */
+#define thr_got_alarm(A) 0
#define init_thr_alarm(A)
#define thr_alarm_kill(A)
#define end_thr_alarm()
-#define thr_alarm(A,B) (((A)->crono=1)-1)
-#define thr_got_alarm(A) (A)->crono
-#define thr_end_alarm(A)
#else
#if defined(__WIN__)
@@ -109,4 +116,3 @@ bool thr_got_alarm(thr_alarm_t *alrm);
}
#endif /* __cplusplus */
#endif /* _thr_alarm_h */
-
diff --git a/include/thr_lock.h b/include/thr_lock.h
index 6dd59f80e64..7459849cb04 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* For use with thr_lock:s */
@@ -28,7 +27,7 @@ extern "C" {
struct st_thr_lock;
extern ulong locks_immediate,locks_waited ;
-
+
enum thr_lock_type { TL_IGNORE=-1,
TL_UNLOCK, /* UNLOCK ANY LOCK */
TL_READ, /* Read lock */
diff --git a/include/violite.h b/include/violite.h
index 49df6994d53..40da31ee1b6 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* Vio Lite.
@@ -25,9 +24,6 @@
#include "my_net.h" /* needed because of struct in_addr */
-#ifdef HAVE_VIO
-#include <Vio.h> /* Full VIO interface */
-#else
/* Simple vio interface in C; The functions are implemented in violite.c */
@@ -35,83 +31,202 @@
extern "C" {
#endif /* __cplusplus */
-#ifndef Vio_defined
-#define Vio_defined
-struct st_vio; /* Only C */
-typedef struct st_vio Vio;
-#endif
-
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
-Vio* vio_new(my_socket sd,
- enum enum_vio_type type,
- my_bool localhost);
+#ifndef __WIN__
+#define HANDLE void *
+#endif
+
+Vio* vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost);
#ifdef __WIN__
-Vio* vio_new_win32pipe(HANDLE hPipe);
+Vio* vio_new_win32pipe(HANDLE hPipe);
+#endif
+void vio_delete(Vio* vio);
+
+#ifdef EMBEDDED_LIBRARY
+void vio_reset(Vio *vio);
+#else
+void vio_reset(Vio* vio, enum enum_vio_type type,
+ my_socket sd, HANDLE hPipe, my_bool localhost);
#endif
-void vio_delete(Vio* vio);
/*
* vio_read and vio_write should have the same semantics
* as read(2) and write(2).
*/
-int vio_read( Vio* vio,
- gptr buf, int size);
-int vio_write( Vio* vio,
- const gptr buf,
- int size);
+int vio_read(Vio *vio, gptr buf, int size);
+int vio_write(Vio *vio, const gptr buf, int size);
/*
* Whenever the socket is set to blocking mode or not.
*/
-int vio_blocking( Vio* vio,
- my_bool onoff);
-my_bool vio_is_blocking( Vio* vio);
+int vio_blocking(Vio *vio, my_bool onoff);
+my_bool vio_is_blocking(Vio *vio);
/*
* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
*/
- int vio_fastsend( Vio* vio);
+int vio_fastsend(Vio *vio);
/*
* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
*/
-int vio_keepalive( Vio* vio,
- my_bool onoff);
+int vio_keepalive(Vio *vio, my_bool onoff);
/*
* Whenever we should retry the last read/write operation.
*/
-my_bool vio_should_retry( Vio* vio);
+my_bool vio_should_retry(Vio *vio);
/*
* When the workday is over...
*/
-int vio_close( Vio* vio);
+int vio_close(Vio* vio);
/*
* Short text description of the socket for those, who are curious..
*/
-const char* vio_description( Vio* vio);
+const char* vio_description(Vio *vio);
/* Return the type of the connection */
- enum enum_vio_type vio_type(Vio* vio);
+enum enum_vio_type vio_type(Vio* vio);
/* Return last error number */
-int vio_errno(Vio *vio);
+int vio_errno(Vio*vio);
/* Get socket number */
-my_socket vio_fd(Vio *vio);
+my_socket vio_fd(Vio*vio);
/*
* Remote peer's address and name in text form.
*/
-my_bool vio_peer_addr(Vio * vio, char *buf);
+my_bool vio_peer_addr(Vio* vio, char *buf);
/* Remotes in_addr */
void vio_in_addr(Vio *vio, struct in_addr *in);
- /* Return 1 if there is data to be read */
my_bool vio_poll_read(Vio *vio,uint timeout);
#ifdef __cplusplus
}
#endif
+
+#if defined(HAVE_VIO) && !defined(DONT_MAP_VIO)
+#define vio_delete(vio) (vio)->viodelete(vio)
+#define vio_errno(vio) (vio)->vioerrno(vio)
+#define vio_read(vio, buf, size) (vio)->read(vio,buf,size)
+#define vio_write(vio, buf, size) (vio)->write(vio, buf, size)
+#define vio_blocking(vio, set_blocking_mode) (vio)->vioblocking(vio, set_blocking_mode)
+#define vio_is_blocking(vio) (vio)->is_blocking(vio)
+#define vio_fastsend(vio) (vio)->fastsend(vio)
+#define vio_keepalive(vio, set_keep_alive) (vio)->viokeepalive(vio, set_keep_alive)
+#define vio_should_retry(vio) (vio)->should_retry(vio)
+#define vio_close(vio) ((vio)->vioclose)(vio)
+#define vio_peer_addr(vio, buf) (vio)->peer_addr(vio, buf)
+#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
+#endif /* defined(HAVE_VIO) && !defined(DONT_MAP_VIO) */
+
+#ifdef HAVE_OPENSSL
+#define HEADER_DES_LOCL_H dummy_something
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include "my_net.h" /* needed because of struct in_addr */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void vio_ssl_delete(Vio* vio);
+
+int vio_ssl_read(Vio* vio,gptr buf, int size);
+int vio_ssl_write(Vio* vio,const gptr buf,int size);
+int vio_ssl_blocking(Vio* vio,my_bool onoff);
+my_bool vio_ssl_is_blocking(Vio* vio);
+
+/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
+ int vio_ssl_fastsend(Vio* vio);
+/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
+int vio_ssl_keepalive(Vio* vio, my_bool onoff);
+/* Whenever we should retry the last read/write operation. */
+my_bool vio_ssl_should_retry(Vio* vio);
+/* When the workday is over... */
+int vio_ssl_close(Vio* vio);
+/* Return last error number */
+int vio_ssl_errno(Vio *vio);
+my_bool vio_ssl_peer_addr(Vio* vio, char *buf);
+void vio_ssl_in_addr(Vio *vio, struct in_addr *in);
+
+/* Single copy for server */
+enum vio_ssl_acceptorfd_state
+{
+ state_connect = 1,
+ state_accept = 2
+};
+
+struct st_VioSSLAcceptorFd
+{
+ SSL_CTX* ssl_context_;
+ SSL_METHOD* ssl_method_;
+ struct st_VioSSLAcceptorFd* session_id_context_;
+};
+
+/* One copy for client */
+struct st_VioSSLConnectorFd
+{
+ SSL_CTX* ssl_context_;
+ /* function pointers which are only once for SSL client */
+ SSL_METHOD* ssl_method_;
+};
+
+void sslaccept(struct st_VioSSLAcceptorFd*, Vio*, long timeout);
+void sslconnect(struct st_VioSSLConnectorFd*, Vio*, long timeout);
+
+struct st_VioSSLConnectorFd
+*new_VioSSLConnectorFd(const char* key_file, const char* cert_file,
+ const char* ca_file, const char* ca_path,
+ const char* cipher);
+struct st_VioSSLAcceptorFd
+*new_VioSSLAcceptorFd(const char* key_file, const char* cert_file,
+ const char* ca_file,const char* ca_path,
+ const char* cipher);
+Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* HAVE_OPENSSL */
+
+/* This enumerator is used in parser - should be always visible */
+enum SSL_type {SSL_TYPE_NONE, SSL_TYPE_ANY, SSL_TYPE_X509, SSL_TYPE_SPECIFIED};
+
+#ifndef EMBEDDED_LIBRARY
+/* This structure is for every connection on both sides */
+struct st_vio
+{
+ my_socket sd; /* my_socket - real or imaginary */
+ HANDLE hPipe;
+ my_bool localhost; /* Are we from localhost? */
+ int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
+ struct sockaddr_in local; /* Local internet address */
+ struct sockaddr_in remote; /* Remote internet address */
+ enum enum_vio_type type; /* Type of connection */
+ char desc[30]; /* String description */
+#ifdef HAVE_VIO
+ /* function pointers. They are similar for socket/SSL/whatever */
+ void (*viodelete)(Vio*);
+ int (*vioerrno)(Vio*);
+ int (*read)(Vio*, gptr, int);
+ int (*write)(Vio*, gptr, int);
+ int (*vioblocking)(Vio*, my_bool);
+ my_bool (*is_blocking)(Vio*);
+ int (*viokeepalive)(Vio*, my_bool);
+ int (*fastsend)(Vio*);
+ my_bool (*peer_addr)(Vio*, gptr);
+ void (*in_addr)(Vio*, struct in_addr*);
+ my_bool (*should_retry)(Vio*);
+ int (*vioclose)(Vio*);
+
+#ifdef HAVE_OPENSSL
+ SSL* ssl_;
+ my_bool open_;
+#endif /* HAVE_OPENSSL */
#endif /* HAVE_VIO */
+};
+#endif /* EMBEDDED_LIBRARY */
#endif /* vio_violite_h_ */
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index 15642e6ccbc..38d97785832 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -868,7 +868,7 @@ btr_parse_page_reorganize(
/*======================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -1469,7 +1469,7 @@ btr_page_split_and_insert(
page_t* insert_page;
page_cur_t* page_cursor;
rec_t* first_rec;
- byte* buf;
+ byte* buf = 0; /* remove warning */
rec_t* move_limit;
ibool insert_will_fit;
ulint n_iterations = 0;
@@ -1647,7 +1647,7 @@ static
void
btr_level_list_remove(
/*==================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_tree_t* tree __attribute__((unused)), /* in: index tree */
page_t* page, /* in: page to remove */
mtr_t* mtr) /* in: mtr */
{
@@ -2368,7 +2368,7 @@ btr_validate_level(
{
ulint space;
page_t* page;
- page_t* right_page;
+ page_t* right_page = 0; /* remove warning */
page_t* father_page;
page_t* right_father_page;
rec_t* node_ptr;
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index 50f9584e86d..1fe322be81e 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -110,7 +110,7 @@ static
void
btr_cur_latch_leaves(
/*=================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_tree_t* tree __attribute__((unused)), /* in: index tree */
page_t* page, /* in: leaf page where the search
converged */
ulint space, /* in: space id */
@@ -232,7 +232,7 @@ btr_cur_search_to_nth_level(
ulint buf_mode;
ulint estimate;
ulint ignore_sec_unique;
- ulint root_height;
+ ulint root_height = 0; /* remove warning */
#ifdef BTR_CUR_ADAPT
btr_search_t* info;
#endif
@@ -503,7 +503,7 @@ btr_cur_open_at_index_side(
ulint page_no;
ulint space;
ulint height;
- ulint root_height;
+ ulint root_height = 0; /* remove warning */
rec_t* node_ptr;
ulint estimate;
@@ -3058,8 +3058,9 @@ btr_store_big_rec_extern_fields(
rec_t* rec, /* in: record */
big_rec_t* big_rec_vec, /* in: vector containing fields
to be stored externally */
- mtr_t* local_mtr) /* in: mtr containing the latch to
- rec and to the tree */
+ mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ containing the latch to rec and to the
+ tree */
{
byte* data;
ulint local_len;
@@ -3220,9 +3221,9 @@ btr_free_externally_stored_field(
ibool do_not_free_inherited,/* in: TRUE if called in a
rollback and we do not want to free
inherited fields */
- mtr_t* local_mtr) /* in: mtr containing the latch to
- data an an X-latch to the index
- tree */
+ mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ containing the latch to data an an
+ X-latch to the index tree */
{
page_t* page;
page_t* rec_page;
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index 5db737561aa..cfdfefebd1a 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -1306,7 +1306,7 @@ btr_search_update_hash_on_insert(
dulint tree_id;
ulint fold;
ulint ins_fold;
- ulint next_fold;
+ ulint next_fold = 0; /* remove warning (??? bug ???) */
ulint n_fields;
ulint n_bytes;
ulint side;
diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c
index 80e89e16588..663c6cefce6 100644
--- a/innobase/buf/buf0buf.c
+++ b/innobase/buf/buf0buf.c
@@ -285,7 +285,7 @@ buf_page_print(
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Page dump in ascii and hex (%lu bytes):\n%s",
+ " InnoDB: Page dump in ascii and hex (%u bytes):\n%s",
UNIV_PAGE_SIZE, buf);
fprintf(stderr, "InnoDB: End of page dump\n");
diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c
index a2996eefca9..5ab045212c2 100644
--- a/innobase/buf/buf0lru.c
+++ b/innobase/buf/buf0lru.c
@@ -103,9 +103,10 @@ ibool
buf_LRU_search_and_free_block(
/*==========================*/
/* out: TRUE if freed */
- ulint n_iterations) /* in: how many times this has been called
- repeatedly without result: a high value
- means that we should search farther */
+ ulint n_iterations __attribute__((unused))) /* in: how many times
+ this has been called repeatedly without
+ result: a high value means that we should
+ search farther */
{
buf_block_t* block;
ibool freed;
@@ -199,7 +200,7 @@ buf_LRU_get_free_block(void)
buf_block_t* block = NULL;
ibool freed;
ulint n_iterations = 0;
- ibool mon_value_was;
+ ibool mon_value_was = 0; /* remove bug */
ibool started_monitor = FALSE;
loop:
mutex_enter(&(buf_pool->mutex));
diff --git a/innobase/configure.in b/innobase/configure.in
index b606ecfffc0..c234e1e192d 100644
--- a/innobase/configure.in
+++ b/innobase/configure.in
@@ -36,6 +36,7 @@ AC_PROG_RANLIB
AC_PROG_INSTALL
AC_CHECK_HEADERS(aio.h sched.h)
AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(long, 4)
AC_CHECK_FUNCS(sched_yield)
AC_CHECK_FUNCS(fdatasync)
#AC_CHECK_FUNCS(localtime_r) # Already checked by MySQL
diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c
index 61a02f7efd0..8ab5acb4da7 100644
--- a/innobase/data/data0data.c
+++ b/innobase/data/data0data.c
@@ -683,7 +683,7 @@ from entry with dtuple_convert_big_rec. */
void
dtuple_convert_back_big_rec(
/*========================*/
- dict_index_t* index, /* in: index */
+ dict_index_t* index __attribute__((unused)), /* in: index */
dtuple_t* entry, /* in: entry whose data was put to vector */
big_rec_t* vector) /* in, own: big rec vector; it is
freed in this function */
diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c
index 206fbe32940..374c567c3ca 100644
--- a/innobase/dict/dict0boot.c
+++ b/innobase/dict/dict0boot.c
@@ -254,27 +254,29 @@ dict_boot(void)
/* Insert into the dictionary cache the descriptions of the basic
system tables */
/*-------------------------*/
- table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8);
-
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
+ table = dict_mem_table_create((char *) "SYS_TABLES", DICT_HDR_SPACE,8);
+
+ dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "N_COLS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "TYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "MIX_ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "MIX_LEN", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "CLUSTER_NAME", DATA_BINARY,
+ 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "SPACE", DATA_INT, 0, 4, 0);
table->id = DICT_TABLES_ID;
dict_table_add_to_cache(table);
dict_sys->sys_tables = table;
- index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 1);
+ index = dict_mem_index_create((char *) "SYS_TABLES", (char *)
+ "CLUST_IND",
+ DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 1);
- dict_mem_index_add_field(index, "NAME", 0);
+ dict_mem_index_add_field(index, (char *) "NAME", 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLES,
MLOG_4BYTES, &mtr);
@@ -282,51 +284,52 @@ dict_boot(void)
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- index = dict_mem_index_create("SYS_TABLES", "ID_IND", DICT_HDR_SPACE,
- DICT_UNIQUE, 1);
- dict_mem_index_add_field(index, "ID", 0);
+ index = dict_mem_index_create((char *) "SYS_TABLES",
+ (char *) "ID_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE, 1);
+ dict_mem_index_add_field(index, (char *) "ID", 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS,
MLOG_4BYTES, &mtr);
index->id = DICT_TABLE_IDS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7);
-
- dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4, 0);
+ table = dict_mem_table_create((char *) "SYS_COLUMNS",DICT_HDR_SPACE,7);
+
+ dict_mem_table_add_col(table, (char *) "TABLE_ID", DATA_BINARY,0,0,0);
+ dict_mem_table_add_col(table, (char *) "POS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "MTYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "PRTYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "LEN", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "PREC", DATA_INT, 0, 4, 0);
table->id = DICT_COLUMNS_ID;
dict_table_add_to_cache(table);
dict_sys->sys_columns = table;
- index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create((char *) "SYS_COLUMNS",
+ (char *) "CLUST_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, "TABLE_ID", 0);
- dict_mem_index_add_field(index, "POS", 0);
+ dict_mem_index_add_field(index, (char *) "TABLE_ID", 0);
+ dict_mem_index_add_field(index, (char *) "POS", 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS,
MLOG_4BYTES, &mtr);
index->id = DICT_COLUMNS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7);
+ table = dict_mem_table_create((char *) "SYS_INDEXES",DICT_HDR_SPACE,7);
- dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "TABLE_ID", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, (char *) "ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "N_FIELDS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "TYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "SPACE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "PAGE_NO", DATA_INT, 0, 4, 0);
/* The '+ 2' below comes from the 2 system fields */
ut_ad(DICT_SYS_INDEXES_PAGE_NO_FIELD == 6 + 2);
@@ -336,34 +339,34 @@ dict_boot(void)
dict_table_add_to_cache(table);
dict_sys->sys_indexes = table;
- index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create((char *) "SYS_INDEXES",
+ (char *) "CLUST_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, "TABLE_ID", 0);
- dict_mem_index_add_field(index, "ID", 0);
+ dict_mem_index_add_field(index, (char *) "TABLE_ID", 0);
+ dict_mem_index_add_field(index, (char *) "ID", 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES,
MLOG_4BYTES, &mtr);
index->id = DICT_INDEXES_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3);
+ table = dict_mem_table_create((char *) "SYS_FIELDS", DICT_HDR_SPACE,3);
- dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "INDEX_ID", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, (char *) "POS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "COL_NAME", DATA_BINARY, 0,0,0);
table->id = DICT_FIELDS_ID;
dict_table_add_to_cache(table);
dict_sys->sys_fields = table;
- index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create((char *) "SYS_FIELDS",
+ (char *) "CLUST_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, "INDEX_ID", 0);
- dict_mem_index_add_field(index, "POS", 0);
+ dict_mem_index_add_field(index, (char *) "INDEX_ID", 0);
+ dict_mem_index_add_field(index, (char *) "POS", 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS,
MLOG_4BYTES, &mtr);
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index d981dc59036..60beeacf435 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -1045,8 +1045,8 @@ dict_create_or_check_foreign_constraint_tables(void)
mutex_enter(&(dict_sys->mutex));
- table1 = dict_table_get_low("SYS_FOREIGN");
- table2 = dict_table_get_low("SYS_FOREIGN_COLS");
+ table1 = dict_table_get_low((char *) "SYS_FOREIGN");
+ table2 = dict_table_get_low((char *) "SYS_FOREIGN_COLS");
if (table1 && table2
&& UT_LIST_GET_LEN(table1->indexes) == 3
@@ -1062,18 +1062,18 @@ dict_create_or_check_foreign_constraint_tables(void)
trx = trx_allocate_for_mysql();
- trx->op_info = "creating foreign key sys tables";
+ trx->op_info = (char *) "creating foreign key sys tables";
if (table1) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN table\n");
- row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx, TRUE);
}
if (table2) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n");
- row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS",trx,TRUE);
}
fprintf(stderr,
@@ -1083,7 +1083,7 @@ dict_create_or_check_foreign_constraint_tables(void)
there are 2 secondary indexes on SYS_FOREIGN, and they
are defined just like below */
- str =
+ str = (char *)
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
"BEGIN\n"
"CREATE TABLE\n"
@@ -1122,15 +1122,15 @@ dict_create_or_check_foreign_constraint_tables(void)
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN tables\n");
- row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
- row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx, TRUE);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS",trx,TRUE);
error = DB_MUST_GET_MORE_FILE_SPACE;
}
que_graph_free(graph);
- trx->op_info = "";
+ trx->op_info = (char *) "";
trx_free_for_mysql(trx);
@@ -1166,7 +1166,7 @@ dict_create_add_foreigns_to_dictionary(
ut_ad(mutex_own(&(dict_sys->mutex)));
- if (NULL == dict_table_get_low("SYS_FOREIGN")) {
+ if (NULL == dict_table_get_low((char *) "SYS_FOREIGN")) {
fprintf(stderr,
"InnoDB: table SYS_FOREIGN not found from internal data dictionary\n");
return(DB_ERROR);
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 9ed1d088290..5abec8dbb1e 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -571,15 +571,19 @@ dict_table_add_to_cache(
The clustered index will not always physically contain all
system columns. */
- dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS, DATA_ROW_ID, 0, 0);
+ dict_mem_table_add_col(table, (char *) "DB_ROW_ID", DATA_SYS,
+ DATA_ROW_ID, 0, 0);
ut_ad(DATA_ROW_ID == 0);
- dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS, DATA_TRX_ID, 0, 0);
+ dict_mem_table_add_col(table, (char *) "DB_TRX_ID", DATA_SYS,
+ DATA_TRX_ID, 0, 0);
ut_ad(DATA_TRX_ID == 1);
- dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS, DATA_ROLL_PTR,
+ dict_mem_table_add_col(table, (char *) "DB_ROLL_PTR", DATA_SYS,
+ DATA_ROLL_PTR,
0, 0);
ut_ad(DATA_ROLL_PTR == 2);
- dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS, DATA_MIX_ID, 0, 0);
+ dict_mem_table_add_col(table, (char *) "DB_MIX_ID", DATA_SYS,
+ DATA_MIX_ID, 0, 0);
ut_ad(DATA_MIX_ID == 3);
ut_ad(DATA_N_SYS_COLS == 4); /* This assert reminds that if a new
system column is added to the program,
@@ -1777,8 +1781,8 @@ char*
dict_scan_to(
/*=========*/
- char* ptr, /* in: scan from */
- char* string) /* in: look for this */
+ char* ptr, /* in: scan from */
+ const char *string) /* in: look for this */
{
ibool success;
ulint i;
@@ -1816,7 +1820,7 @@ dict_accept(
/* out: if string was accepted, the pointer
is moved after that, else ptr is returned */
char* ptr, /* in: scan from this */
- char* string, /* in: accept only this string as the next
+ const char* string, /* in: accept only this string as the next
non-whitespace string */
ibool* success)/* out: TRUE if accepted */
{
@@ -2073,7 +2077,7 @@ dict_create_foreign_constraints(
}
loop:
- ptr = dict_scan_to(ptr, "FOREIGN");
+ ptr = dict_scan_to(ptr, (char *) "FOREIGN");
if (*ptr == '\0') {
@@ -2085,19 +2089,19 @@ loop:
return(error);
}
- ptr = dict_accept(ptr, "FOREIGN", &success);
+ ptr = dict_accept(ptr, (char *) "FOREIGN", &success);
if (!isspace(*ptr)) {
goto loop;
}
- ptr = dict_accept(ptr, "KEY", &success);
+ ptr = dict_accept(ptr, (char *) "KEY", &success);
if (!success) {
goto loop;
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(ptr, (char *) "(", &success);
if (!success) {
goto loop;
@@ -2115,13 +2119,13 @@ col_loop1:
i++;
- ptr = dict_accept(ptr, ",", &success);
+ ptr = dict_accept(ptr, (char *) ",", &success);
if (success) {
goto col_loop1;
}
- ptr = dict_accept(ptr, ")", &success);
+ ptr = dict_accept(ptr, (char *) ")", &success);
if (!success) {
return(DB_CANNOT_ADD_CONSTRAINT);
@@ -2136,7 +2140,7 @@ col_loop1:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "REFERENCES", &success);
+ ptr = dict_accept(ptr, (char *) "REFERENCES", &success);
if (!success || !isspace(*ptr)) {
return(DB_CANNOT_ADD_CONSTRAINT);
@@ -2171,7 +2175,7 @@ col_loop1:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(ptr, (char *) "(", &success);
if (!success) {
dict_foreign_free(foreign);
@@ -2191,13 +2195,13 @@ col_loop2:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, ",", &success);
+ ptr = dict_accept(ptr, (char *) ",", &success);
if (success) {
goto col_loop2;
}
- ptr = dict_accept(ptr, ")", &success);
+ ptr = dict_accept(ptr, (char *) ")", &success);
if (!success || foreign->n_fields != i) {
dict_foreign_free(foreign);
@@ -2793,7 +2797,8 @@ void
dict_update_statistics_low(
/*=======================*/
dict_table_t* table, /* in: table */
- ibool has_dict_mutex) /* in: TRUE if the caller has the
+ ibool has_dict_mutex __attribute__((unused)))
+ /* in: TRUE if the caller has the
dictionary mutex */
{
dict_index_t* index;
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 6d48ddf4d95..e9caa37fecc 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -48,7 +48,7 @@ dict_get_first_table_name_in_db(
mtr_start(&mtr);
- sys_tables = dict_table_get_low("SYS_TABLES");
+ sys_tables = dict_table_get_low((char *) "SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
tuple = dtuple_create(heap, 1);
@@ -127,7 +127,7 @@ dict_print(void)
mtr_start(&mtr);
- sys_tables = dict_table_get_low("SYS_TABLES");
+ sys_tables = dict_table_get_low((char *) "SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
@@ -216,7 +216,7 @@ dict_load_columns(
mtr_start(&mtr);
- sys_columns = dict_table_get_low("SYS_COLUMNS");
+ sys_columns = dict_table_get_low((char*) "SYS_COLUMNS");
sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
tuple = dtuple_create(heap, 1);
@@ -246,7 +246,7 @@ dict_load_columns(
ut_ad(len == 4);
ut_a(i == mach_read_from_4(field));
- ut_a(0 == ut_strcmp("NAME",
+ ut_a(0 == ut_strcmp((char*) "NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_columns), 4))->name));
@@ -268,7 +268,7 @@ dict_load_columns(
field = rec_get_nth_field(rec, 7, &len);
col_len = mach_read_from_4(field);
- ut_a(0 == ut_strcmp("PREC",
+ ut_a(0 == ut_strcmp((char*) "PREC",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_columns), 8))->name));
@@ -314,7 +314,7 @@ dict_load_fields(
mtr_start(&mtr);
- sys_fields = dict_table_get_low("SYS_FIELDS");
+ sys_fields = dict_table_get_low((char*) "SYS_FIELDS");
sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
tuple = dtuple_create(heap, 1);
@@ -348,7 +348,7 @@ dict_load_fields(
ut_ad(len == 4);
ut_a(i == mach_read_from_4(field));
- ut_a(0 == ut_strcmp("COL_NAME",
+ ut_a(0 == ut_strcmp((char*) "COL_NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_fields), 4))->name));
@@ -411,7 +411,7 @@ dict_load_indexes(
mtr_start(&mtr);
- sys_indexes = dict_table_get_low("SYS_INDEXES");
+ sys_indexes = dict_table_get_low((char*) "SYS_INDEXES");
sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
tuple = dtuple_create(heap, 1);
@@ -476,7 +476,7 @@ dict_load_indexes(
field = rec_get_nth_field(rec, 7, &len);
space = mach_read_from_4(field);
- ut_a(0 == ut_strcmp("PAGE_NO",
+ ut_a(0 == ut_strcmp((char*) "PAGE_NO",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_indexes), 8))->name));
@@ -574,7 +574,7 @@ dict_load_table(
mtr_start(&mtr);
- sys_tables = dict_table_get_low("SYS_TABLES");
+ sys_tables = dict_table_get_low((char *) "SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
tuple = dtuple_create(heap, 1);
@@ -610,7 +610,7 @@ dict_load_table(
return(NULL);
}
- ut_a(0 == ut_strcmp("SPACE",
+ ut_a(0 == ut_strcmp((char *) "SPACE",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 9))->name));
@@ -618,7 +618,7 @@ dict_load_table(
field = rec_get_nth_field(rec, 9, &len);
space = mach_read_from_4(field);
- ut_a(0 == ut_strcmp("N_COLS",
+ ut_a(0 == ut_strcmp((char *) "N_COLS",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 4))->name));
@@ -628,7 +628,7 @@ dict_load_table(
table = dict_mem_table_create(name, space, n_cols);
- ut_a(0 == ut_strcmp("ID",
+ ut_a(0 == ut_strcmp((char *) "ID",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 3))->name));
@@ -829,7 +829,7 @@ dict_load_foreign_cols(
foreign->n_fields * sizeof(void*));
mtr_start(&mtr);
- sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
+ sys_foreign_cols = dict_table_get_low((char *) "SYS_FOREIGN_COLS");
sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes);
tuple = dtuple_create(foreign->heap, 1);
@@ -907,7 +907,7 @@ dict_load_foreign(
mtr_start(&mtr);
- sys_foreign = dict_table_get_low("SYS_FOREIGN");
+ sys_foreign = dict_table_get_low((char *) "SYS_FOREIGN");
sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes);
tuple = dtuple_create(heap2, 1);
@@ -1026,7 +1026,7 @@ dict_load_foreigns(
ut_ad(mutex_own(&(dict_sys->mutex)));
- sys_foreign = dict_table_get_low("SYS_FOREIGN");
+ sys_foreign = dict_table_get_low((char *) "SYS_FOREIGN");
if (sys_foreign == NULL) {
/* No foreign keys defined yet in this database */
diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c
index 110387d8373..157d4e4f98d 100644
--- a/innobase/eval/eval0eval.c
+++ b/innobase/eval/eval0eval.c
@@ -164,8 +164,8 @@ eval_logical(
que_node_t* arg1;
que_node_t* arg2;
ibool val1;
- ibool val2;
- ibool val;
+ ibool val2 = 0; /* remove warning */
+ ibool val = 0; /* remove warning */
int func;
ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
@@ -205,7 +205,7 @@ eval_arith(
que_node_t* arg1;
que_node_t* arg2;
lint val1;
- lint val2;
+ lint val2 = 0; /* remove warning */
lint val;
int func;
@@ -283,7 +283,7 @@ eval_predefined_2(
{
que_node_t* arg;
que_node_t* arg1;
- que_node_t* arg2;
+ que_node_t* arg2 = 0; /* remove warning (??? bug ???) */
lint int_val;
byte* data;
ulint len1;
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index 910ca842f21..da4aee5db76 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -1290,7 +1290,7 @@ fil_aio_wait(
ut_ad(fil_validate());
if (os_aio_use_native_aio) {
- srv_io_thread_op_info[segment] = "native aio handle";
+ srv_io_thread_op_info[segment] = (char *) "native aio handle";
#ifdef WIN_ASYNC_IO
ret = os_aio_windows_handle(segment, 0, &fil_node, &message,
&type);
@@ -1301,7 +1301,7 @@ fil_aio_wait(
ut_a(0);
#endif
} else {
- srv_io_thread_op_info[segment] = "simulated aio handle";
+ srv_io_thread_op_info[segment] =(char *)"simulated aio handle";
ret = os_aio_simulated_handle(segment, (void**) &fil_node,
&message, &type);
@@ -1309,7 +1309,7 @@ fil_aio_wait(
ut_a(ret);
- srv_io_thread_op_info[segment] = "complete io for fil node";
+ srv_io_thread_op_info[segment] = (char *) "complete io for fil node";
mutex_enter(&(system->mutex));
@@ -1322,10 +1322,11 @@ fil_aio_wait(
/* Do the i/o handling */
if (buf_pool_is_block(message)) {
- srv_io_thread_op_info[segment] = "complete io for buf page";
+ srv_io_thread_op_info[segment] =
+ (char *) "complete io for buf page";
buf_page_io_complete(message);
} else {
- srv_io_thread_op_info[segment] = "complete io for log";
+ srv_io_thread_op_info[segment] =(char *) "complete io for log";
log_io_complete(message);
}
}
diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c
index d78db2a5ea8..32e7f5bcad7 100644
--- a/innobase/fsp/fsp0fsp.c
+++ b/innobase/fsp/fsp0fsp.c
@@ -803,7 +803,7 @@ fsp_parse_init_file_page(
/*=====================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page) /* in: page or NULL */
{
ut_ad(ptr && end_ptr);
@@ -1398,7 +1398,7 @@ fsp_seg_inode_page_get_nth_inode(
/* out: segment inode */
page_t* page, /* in: segment inode page */
ulint i, /* in: inode index on page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(i < FSP_SEG_INODES_PER_PAGE);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
@@ -1640,7 +1640,7 @@ fseg_get_nth_frag_page_no(
/* out: page number, FIL_NULL if not in use */
fseg_inode_t* inode, /* in: segment inode */
ulint n, /* in: slot index */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mtr handle */
{
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
@@ -1778,7 +1778,7 @@ fseg_create_general(
fsp_header_t* space_header;
fseg_inode_t* inode;
dulint seg_id;
- fseg_header_t* header;
+ fseg_header_t* header = 0; /* remove warning */
rw_lock_t* latch;
ibool success;
page_t* ret = NULL;
diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
index 2cbffadf6a9..b7d691485cc 100644
--- a/innobase/ibuf/ibuf0ibuf.c
+++ b/innobase/ibuf/ibuf0ibuf.c
@@ -292,6 +292,7 @@ ibuf_count_get(
/**********************************************************************
Sets the ibuf count for a given page. */
+#ifdef UNIV_IBUF_DEBUG
static
void
ibuf_count_set(
@@ -306,6 +307,7 @@ ibuf_count_set(
*(ibuf_counts[space] + page_no) = val;
}
+#endif
/**********************************************************************
Creates the insert buffer data structure at a database startup and
@@ -472,19 +474,18 @@ ibuf_data_init_for_space(
table = dict_mem_table_create(buf, space, 2);
- dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table,(char *) "PAGE_NO", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table,(char *) "TYPES", DATA_BINARY, 0, 0, 0);
table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
dict_table_add_to_cache(table);
- index = dict_mem_index_create(buf, "CLUST_IND", space,
- DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
- 2);
+ index = dict_mem_index_create(buf, (char *) "CLUST_IND", space,
+ DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2);
- dict_mem_index_add_field(index, "PAGE_NO", 0);
- dict_mem_index_add_field(index, "TYPES", 0);
+ dict_mem_index_add_field(index, (char *) "PAGE_NO", 0);
+ dict_mem_index_add_field(index, (char *) "TYPES", 0);
index->page_no = FSP_IBUF_TREE_ROOT_PAGE_NO;
@@ -538,7 +539,7 @@ ibuf_parse_bitmap_init(
/*===================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -561,7 +562,8 @@ ibuf_bitmap_page_get_bits(
page_t* page, /* in: bitmap page */
ulint page_no,/* in: page whose bits to get */
ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
- mtr_t* mtr) /* in: mtr containing an x-latch to the bitmap page */
+ mtr_t* mtr __attribute__((unused))) /* in: mtr containing an x-latch
+ to the bitmap page */
{
ulint byte_offset;
ulint bit_offset;
diff --git a/innobase/include/Makefile.am b/innobase/include/Makefile.am
index fd5cc8b1a80..8664f6dfc17 100644
--- a/innobase/include/Makefile.am
+++ b/innobase/include/Makefile.am
@@ -55,5 +55,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \
ut0dbg.h ut0lst.h ut0mem.h ut0mem.ic ut0rnd.h ut0rnd.ic \
ut0sort.h ut0ut.h ut0ut.ic
+EXTRA_DIST = Makefile.i
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/innobase/include/Makefile.i b/innobase/include/Makefile.i
index 8c7e9910f26..985ec525950 100644
--- a/innobase/include/Makefile.i
+++ b/innobase/include/Makefile.i
@@ -2,7 +2,7 @@
libsdir = ../libs
-INCLUDES = -I../../include -I../include
+INCLUDES = -I$(srcdir)/../include -I$(srcdir)/../../include -I../../include
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/innobase/include/btr0btr.ic b/innobase/include/btr0btr.ic
index 5c1c89e9840..09006828cc9 100644
--- a/innobase/include/btr0btr.ic
+++ b/innobase/include/btr0btr.ic
@@ -89,7 +89,7 @@ btr_page_get_level(
/*===============*/
/* out: level, leaf level == 0 */
page_t* page, /* in: index page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(page && mtr);
@@ -121,7 +121,7 @@ btr_page_get_next(
/*==============*/
/* out: next page number */
page_t* page, /* in: index page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
@@ -155,7 +155,7 @@ btr_page_get_prev(
/*==============*/
/* out: prev page number */
page_t* page, /* in: index page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(page && mtr);
diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic
index 50248a7b2da..e5a2c480922 100644
--- a/innobase/include/buf0buf.ic
+++ b/innobase/include/buf0buf.ic
@@ -631,9 +631,10 @@ UNIV_INLINE
void
buf_page_dbg_add_level(
/*===================*/
- buf_frame_t* frame, /* in: buffer page where we have acquired
- a latch */
- ulint level) /* in: latching order level */
+ buf_frame_t* frame __attribute__((unused)), /* in: buffer page
+ where we have acquired latch */
+ ulint level __attribute__((unused))) /* in: latching order
+ level */
{
#ifdef UNIV_SYNC_DEBUG
sync_thread_add_level(&(buf_block_align(frame)->lock), level);
diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic
index 821465f96a8..71ea67117a7 100644
--- a/innobase/include/dict0dict.ic
+++ b/innobase/include/dict0dict.ic
@@ -106,7 +106,7 @@ dict_table_get_n_sys_cols(
/*======================*/
/* out: number of system (e.g.,
ROW_ID) columns of a table */
- dict_table_t* table) /* in: table */
+ dict_table_t* table __attribute__((unused))) /* in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
diff --git a/innobase/include/dyn0dyn.h b/innobase/include/dyn0dyn.h
index 0952a8b4647..332622b6d4c 100644
--- a/innobase/include/dyn0dyn.h
+++ b/innobase/include/dyn0dyn.h
@@ -18,7 +18,12 @@ typedef dyn_block_t dyn_array_t;
/* Initial 'payload' size in bytes in a dynamic array block */
-#define DYN_ARRAY_DATA_SIZE 512
+#ifndef _AIX
+#define DYN_ARRAY_DATA_SIZE 1024
+#else
+/* AIX has a quite small stack / thread */
+#define DYN_ARRAY_DATA_SIZE 128
+#endif
/*************************************************************************
Initializes a dynamic array. */
diff --git a/innobase/include/ha0ha.ic b/innobase/include/ha0ha.ic
index 7b4c624c653..9d344bca04c 100644
--- a/innobase/include/ha0ha.ic
+++ b/innobase/include/ha0ha.ic
@@ -59,7 +59,7 @@ ha_node_t*
ha_chain_get_next(
/*==============*/
/* out: next node, NULL if none */
- hash_table_t* table, /* in: hash table */
+ hash_table_t* table __attribute__((unused)), /* in: hash table */
ha_node_t* node) /* in: hash chain node */
{
ut_ad(table);
diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic
index 6096e5771f7..e9d493da8b5 100644
--- a/innobase/include/row0mysql.ic
+++ b/innobase/include/row0mysql.ic
@@ -15,7 +15,8 @@ row_mysql_store_var_len(
/*====================*/
/* out: dest + 2 */
byte* dest, /* in: where to store */
- ulint len) /* in: length, must fit in two bytes */
+ ulint len __attribute__((unused))) /* in: length, must fit in two
+ bytes */
{
ut_ad(len < 256 * 256);
/*
diff --git a/innobase/include/row0vers.ic b/innobase/include/row0vers.ic
index aa7a7aa2299..5ece47c35d1 100644
--- a/innobase/include/row0vers.ic
+++ b/innobase/include/row0vers.ic
@@ -60,7 +60,7 @@ row_vers_sec_rec_may_see_older(
/*===========================*/
/* out: FALSE if can be read immediately */
rec_t* rec, /* in: record which should be read or passed */
- dict_index_t* index, /* in: secondary index */
+ dict_index_t* index __attribute__((unused)),/* in: secondary index */
read_view_t* view) /* in: read view */
{
page_t* page;
diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
index 1f76974b03d..178c7b6971f 100644
--- a/innobase/include/srv0srv.h
+++ b/innobase/include/srv0srv.h
@@ -94,6 +94,7 @@ extern ulint srv_n_rows_read;
extern ibool srv_print_innodb_monitor;
extern ibool srv_print_innodb_lock_monitor;
extern ibool srv_print_innodb_tablespace_monitor;
+extern ibool srv_print_verbose_log;
extern ibool srv_print_innodb_table_monitor;
extern ibool srv_lock_timeout_and_monitor_active;
diff --git a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic
index af5c4576da6..43e9202360b 100644
--- a/innobase/include/sync0rw.ic
+++ b/innobase/include/sync0rw.ic
@@ -126,7 +126,8 @@ rw_lock_s_lock_low(
/*===============*/
/* out: TRUE if success */
rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will be
+ ulint pass __attribute__((unused)),
+ /* in: pass value; != 0, if the lock will be
passed to another thread to unlock */
char* file_name, /* in: file name where lock requested */
ulint line) /* in: line where requested */
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index e7d93a594c1..c852741d5ac 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -29,7 +29,7 @@ Created 1/20/1994 Heikki Tuuri
in compiling more Posix-compatible. These headers also define __WIN__
if we are compiling on Windows. */
-#include <global.h>
+#include <my_global.h>
#include <my_pthread.h>
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h
index 2d245e5f72f..09e0d800685 100644
--- a/innobase/include/ut0mem.h
+++ b/innobase/include/ut0mem.h
@@ -69,7 +69,7 @@ ut_strcpy(char* dest, char* sour);
UNIV_INLINE
ulint
-ut_strlen(char* str);
+ut_strlen(const char* str);
UNIV_INLINE
int
diff --git a/innobase/include/ut0mem.ic b/innobase/include/ut0mem.ic
index 7ae9bc8bd74..1049aee8ecc 100644
--- a/innobase/include/ut0mem.ic
+++ b/innobase/include/ut0mem.ic
@@ -36,7 +36,7 @@ ut_strcpy(char* dest, char* sour)
UNIV_INLINE
ulint
-ut_strlen(char* str)
+ut_strlen(const char* str)
{
return(strlen(str));
}
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index f7ba49004d7..7588a576a86 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -539,7 +539,8 @@ lock_sec_rec_cons_read_sees(
index record */
rec_t* rec, /* in: user record which should be read or
passed over by a read cursor */
- dict_index_t* index, /* in: non-clustered index */
+ dict_index_t* index __attribute__((unused)),
+ /* in: non-clustered index */
read_view_t* view) /* in: consistent read view */
{
dulint max_trx_id;
@@ -2303,7 +2304,7 @@ list start is moved to another page. */
void
lock_move_rec_list_start(
/*=====================*/
- page_t* new_page, /* in: index page to move to */
+ page_t* new_page __attribute__((unused)),/*in: index page to move to */
page_t* page, /* in: index page */
rec_t* rec, /* in: record on page: this is the
first record NOT copied */
@@ -2747,7 +2748,7 @@ lock_deadlock_recursive(
we return TRUE */
{
lock_t* lock;
- ulint bit_no;
+ ulint bit_no = 0; /* remove warning */
trx_t* lock_trx;
ut_a(trx && start && wait_lock);
diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c
index 9d79c19a586..9748384183c 100644
--- a/innobase/log/log0log.c
+++ b/innobase/log/log0log.c
@@ -2123,7 +2123,7 @@ log_group_archive(
os_file_t file_handle;
dulint start_lsn;
dulint end_lsn;
- char name[100];
+ char name[1024];
byte* buf;
ulint len;
ibool ret;
@@ -2915,9 +2915,11 @@ logs_empty_and_mark_files_at_shutdown(void)
dulint lsn;
ulint arch_log_no;
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Starting shutdown...\n");
-
+ if (srv_print_verbose_log)
+ {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Starting shutdown...\n");
+ }
/* Wait until the master thread and all other operations are idle: our
algorithm only works if the server is idle at shutdown */
@@ -3022,8 +3024,11 @@ loop:
fil_flush_file_spaces(FIL_TABLESPACE);
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Shutdown completed\n");
+ if (srv_print_verbose_log)
+ {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Shutdown completed\n");
+ }
}
/**********************************************************
diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c
index f8f62dffa8b..f94119b7f38 100644
--- a/innobase/mem/mem0dbg.c
+++ b/innobase/mem/mem0dbg.c
@@ -372,7 +372,8 @@ void
mem_heap_validate_or_print(
/*=======================*/
mem_heap_t* heap, /* in: memory heap */
- byte* top, /* in: calculate and validate only until
+ byte* top __attribute__((unused)),
+ /* in: calculate and validate only until
this top pointer in the heap is reached,
if this pointer is NULL, ignored */
ibool print, /* in: if TRUE, prints the contents
@@ -578,7 +579,8 @@ static
void
mem_print_info_low(
/*===============*/
- ibool print_all) /* in: if TRUE, all heaps are printed,
+ ibool print_all __attribute__((unused)))
+ /* in: if TRUE, all heaps are printed,
else only the heaps allocated after the
previous call of this function */
{
diff --git a/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c
index 565489613ae..e9a6e39d98f 100644
--- a/innobase/mtr/mtr0mtr.c
+++ b/innobase/mtr/mtr0mtr.c
@@ -469,7 +469,8 @@ mtr_read_ulint(
/* out: value read */
byte* ptr, /* in: pointer from where to read */
ulint type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused)))
+ /* in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr),
@@ -494,8 +495,9 @@ mtr_read_dulint(
/*===========*/
/* out: value read */
byte* ptr, /* in: pointer from where to read */
- ulint type, /* in: MLOG_8BYTES */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint type __attribute__((unused)), /* in: MLOG_8BYTES */
+ mtr_t* mtr __attribute__((unused)))
+ /* in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(ptr && mtr);
diff --git a/innobase/odbc/odbc0odbc.c b/innobase/odbc/odbc0odbc.c
index 640a88a2503..0deb17c6714 100644
--- a/innobase/odbc/odbc0odbc.c
+++ b/innobase/odbc/odbc0odbc.c
@@ -421,7 +421,7 @@ SQLError(
}
*pfNativeError = 0;
- ut_memcpy(szSqlState, "S1000", 6);
+ ut_memcpy(szSqlState, (char *) "S1000", 6);
len = (ulint)cbErrorMsgMax - 1;
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 4a1bbfa9874..ae3c8a45f62 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -659,14 +659,13 @@ os_file_get_size(
return(FALSE);
}
- if (sizeof(off_t) > 4) {
- *size = (ulint)(offs & 0xFFFFFFFF);
- *size_high = (ulint)(offs >> 32);
- } else {
- *size = (ulint) offs;
- *size_high = 0;
- }
-
+#if SIZEOF_OFF_T > 4
+ *size = (ulint)(offs & 0xFFFFFFFF);
+ *size_high = (ulint)(offs >> 32);
+#else
+ *size = (ulint) offs;
+ *size_high = 0;
+#endif
return(TRUE);
#endif
}
@@ -829,18 +828,16 @@ os_file_pread(
/* If off_t is > 4 bytes in size, then we assume we can pass a
64-bit address */
- if (sizeof(off_t) > 4) {
- offs = (off_t)offset + (((off_t)offset_high) << 32);
-
- } else {
- offs = (off_t)offset;
+#if SIZEOF_OFF_T > 4
+ offs = (off_t)offset + (((off_t)offset_high) << 32);
+#else
+ offs = (off_t)offset;
- if (offset_high > 0) {
- fprintf(stderr,
- "InnoDB: Error: file read at offset > 4 GB\n");
- }
+ if (offset_high > 0) {
+ fprintf(stderr,
+ "InnoDB: Error: file read at offset > 4 GB\n");
}
-
+#endif
os_n_file_reads++;
#ifdef HAVE_PREAD
diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c
index 11bff73608a..49d4c8518fb 100644
--- a/innobase/os/os0thread.c
+++ b/innobase/os/os0thread.c
@@ -58,7 +58,8 @@ os_thread_create(
#endif
void* arg, /* in: argument to start
function */
- os_thread_id_t* thread_id) /* out: id of created
+ os_thread_id_t* thread_id __attribute__((unused)))
+ /* out: id of created
thread */
{
#ifdef __WIN__
@@ -204,7 +205,8 @@ ulint
os_thread_get_priority(
/*===================*/
/* out: priority */
- os_thread_t handle) /* in: OS handle to the thread */
+ os_thread_t handle __attribute__((unused)))
+ /* in: OS handle to the thread */
{
#ifdef __WIN__
int os_pri;
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c
index dfe28fd40c4..0eaf96f7e51 100644
--- a/innobase/page/page0cur.c
+++ b/innobase/page/page0cur.c
@@ -514,14 +514,14 @@ page_cur_parse_insert_rec(
mtr_t* mtr) /* in: mtr or NULL */
{
ulint extra_info_yes;
- ulint offset;
+ ulint offset = 0; /* remove warning */
ulint origin_offset;
ulint end_seg_len;
ulint mismatch_index;
rec_t* cursor_rec;
byte buf1[1024];
byte* buf;
- ulint info_bits;
+ ulint info_bits = 0; /* remove warning */
page_cur_t cursor;
if (!is_short) {
@@ -842,9 +842,9 @@ page_copy_rec_list_end_to_created_page(
rec_t* rec, /* in: first record to copy */
mtr_t* mtr) /* in: mtr */
{
- page_dir_slot_t* slot;
+ page_dir_slot_t* slot = 0; /* remove warning */
byte* heap_top;
- rec_t* insert_rec;
+ rec_t* insert_rec = 0; /* remove warning */
rec_t* prev_rec;
ulint count;
ulint n_recs;
@@ -889,6 +889,7 @@ page_copy_rec_list_end_to_created_page(
slot_index = 0;
n_recs = 0;
+ /* should be do ... until, comment by Jani */
while (rec != page_get_supremum_rec(page)) {
insert_rec = rec_copy(heap_top, rec);
diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c
index f3f6776bf13..ed74736c8da 100644
--- a/innobase/page/page0page.c
+++ b/innobase/page/page0page.c
@@ -270,7 +270,7 @@ page_parse_create(
/*==============*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -343,7 +343,7 @@ page_create(
tuple = dtuple_create(heap, 1);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "infimum", strlen("infimum") + 1);
+ dfield_set_data(field,(char *) "infimum", strlen("infimum") + 1);
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
/* Set the corresponding physical record to its place in the page
@@ -365,7 +365,7 @@ page_create(
tuple = dtuple_create(heap, 1);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "supremum", strlen("supremum") + 1);
+ dfield_set_data(field, (char *) "supremum", strlen("supremum") + 1);
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
supremum_rec = rec_convert_dtuple_to_rec(heap_top, tuple);
diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c
index 9814c4b21cc..91083e6fa16 100644
--- a/innobase/pars/pars0opt.c
+++ b/innobase/pars/pars0opt.c
@@ -373,7 +373,8 @@ opt_calc_index_goodness(
}
}
- if (index->type & DICT_CLUSTERED) {
+ /* We have to test for goodness here, as last_op may note be set */
+ if (goodness && index->type & DICT_CLUSTERED) {
goodness++;
}
@@ -529,7 +530,7 @@ opt_search_plan_for_table(
ulint last_op = 75946965; /* Eliminate a Purify
warning */
ulint best_goodness;
- ulint best_last_op;
+ ulint best_last_op = 0; /* remove warning */
ulint mix_id_pos;
que_node_t* index_plan[128];
que_node_t* best_index_plan[128];
@@ -547,6 +548,7 @@ opt_search_plan_for_table(
best_index = index; /* Eliminate compiler warning */
best_goodness = 0;
+ /* should be do ... until ? comment by Jani */
while (index) {
goodness = opt_calc_index_goodness(index, sel_node, i,
index_plan, &last_op);
diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c
index 8ffbca579b8..664f498ef3e 100644
--- a/innobase/pars/pars0pars.c
+++ b/innobase/pars/pars0pars.c
@@ -1942,7 +1942,7 @@ Called by yyparse on error. */
void
yyerror(
/*====*/
- char* s) /* in: error message string */
+ char* s __attribute__((unused))) /* in: error message string */
{
ut_ad(s);
diff --git a/innobase/que/que0que.c b/innobase/que/que0que.c
index 41a90a7fb42..7fa444f6741 100644
--- a/innobase/que/que0que.c
+++ b/innobase/que/que0que.c
@@ -103,7 +103,7 @@ que_thr_add_update_info(
mach_write_to_8(thr->msg_buf + SESS_SRV_MSG_N_DELETES,
graph->n_deletes);
}
-#endif
+#endif
/***************************************************************************
Adds a query graph to the session's list of graphs. */
@@ -395,7 +395,7 @@ graph so that the graph can communicate an error message to the client.) */
void
que_fork_error_handle(
/*==================*/
- trx_t* trx, /* in: trx */
+ trx_t* trx __attribute__((unused)), /* in: trx */
que_t* fork) /* in: query graph which was run before signal
handling started, NULL not allowed */
{
@@ -1167,47 +1167,47 @@ que_node_print_info(
addr = (ulint)node;
if (type == QUE_NODE_SELECT) {
- str = "SELECT";
+ str = (char *) "SELECT";
} else if (type == QUE_NODE_INSERT) {
- str = "INSERT";
+ str = (char *) "INSERT";
} else if (type == QUE_NODE_UPDATE) {
- str = "UPDATE";
+ str = (char *) "UPDATE";
} else if (type == QUE_NODE_WHILE) {
- str = "WHILE";
+ str = (char *) "WHILE";
} else if (type == QUE_NODE_ASSIGNMENT) {
- str = "ASSIGNMENT";
+ str = (char *) "ASSIGNMENT";
} else if (type == QUE_NODE_IF) {
- str = "IF";
+ str = (char *) "IF";
} else if (type == QUE_NODE_FETCH) {
- str = "FETCH";
+ str = (char *) "FETCH";
} else if (type == QUE_NODE_OPEN) {
- str = "OPEN";
+ str = (char *) "OPEN";
} else if (type == QUE_NODE_PROC) {
- str = "STORED PROCEDURE";
+ str = (char *) "STORED PROCEDURE";
} else if (type == QUE_NODE_FUNC) {
- str = "FUNCTION";
+ str = (char *) "FUNCTION";
} else if (type == QUE_NODE_LOCK) {
- str = "LOCK";
+ str = (char *) "LOCK";
} else if (type == QUE_NODE_THR) {
- str = "QUERY THREAD";
+ str = (char *) "QUERY THREAD";
} else if (type == QUE_NODE_COMMIT) {
- str = "COMMIT";
+ str = (char *) "COMMIT";
} else if (type == QUE_NODE_UNDO) {
- str = "UNDO ROW";
+ str = (char *) "UNDO ROW";
} else if (type == QUE_NODE_PURGE) {
- str = "PURGE ROW";
+ str = (char *) "PURGE ROW";
} else if (type == QUE_NODE_ROLLBACK) {
- str = "ROLLBACK";
+ str = (char *) "ROLLBACK";
} else if (type == QUE_NODE_CREATE_TABLE) {
- str = "CREATE TABLE";
+ str = (char *) "CREATE TABLE";
} else if (type == QUE_NODE_CREATE_INDEX) {
- str = "CREATE INDEX";
+ str = (char *) "CREATE INDEX";
} else if (type == QUE_NODE_FOR) {
- str = "FOR LOOP";
+ str = (char *) "FOR LOOP";
} else if (type == QUE_NODE_RETURN) {
- str = "RETURN";
+ str = (char *) "RETURN";
} else {
- str = "UNKNOWN NODE TYPE";
+ str = (char *) "UNKNOWN NODE TYPE";
}
printf("Node type %lu: %s, address %lx\n", type, str, addr);
diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c
index 31c76705c4b..c50516dfc8b 100644
--- a/innobase/rem/rem0cmp.c
+++ b/innobase/rem/rem0cmp.c
@@ -80,7 +80,7 @@ ulint
cmp_collate(
/*========*/
/* out: collation order position */
- dtype_t* type, /* in: type */
+ dtype_t* type __attribute__((unused)) , /* in: type */
ulint code) /* in: code of a character stored in database
record */
{
diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c
index 3889f62afa2..a151389798d 100644
--- a/innobase/rem/rem0rec.c
+++ b/innobase/rem/rem0rec.c
@@ -528,9 +528,9 @@ rec_print(
ut_ad(rec);
if (rec_get_1byte_offs_flag(rec)) {
- offs = "TRUE";
+ offs = (char *) "TRUE";
} else {
- offs = "FALSE";
+ offs = (char *) "FALSE";
}
n = rec_get_n_fields(rec);
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 1f0d0f40114..2e6dde6db65 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -633,7 +633,7 @@ row_ins_check_foreign_constraint(
dictionary cache if they exist at all */
dict_table_t* table, /* in: if check_ref is TRUE, then the foreign
table, else the referenced table */
- dict_index_t* index, /* in: index in table */
+ dict_index_t* index __attribute__((unused)),/* in: index in table */
dtuple_t* entry, /* in: index entry for index */
que_thr_t* thr) /* in: query thread */
{
@@ -1159,7 +1159,7 @@ row_ins_index_entry_low(
{
btr_cur_t cursor;
ulint ignore_sec_unique = 0;
- ulint modify;
+ ulint modify = 0; /* remove warning */
rec_t* insert_rec;
rec_t* rec;
ulint err;
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 529007dfb26..e0737f53213 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -595,7 +595,7 @@ row_lock_table_autoinc_for_mysql(
ut_ad(trx);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
- trx->op_info = "setting auto-inc lock";
+ trx->op_info = (char *) "setting auto-inc lock";
if (node == NULL) {
row_get_prebuilt_insert_row(prebuilt);
@@ -631,14 +631,14 @@ run_again:
goto run_again;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
que_thr_stop_for_mysql_no_error(thr, trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -686,7 +686,7 @@ row_insert_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "inserting";
+ trx->op_info = (char *) "inserting";
trx_start_if_not_started(trx);
@@ -727,7 +727,7 @@ run_again:
goto run_again;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -744,7 +744,7 @@ run_again:
}
row_update_statistics_if_needed(prebuilt->table);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -902,7 +902,7 @@ row_update_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "updating or deleting";
+ trx->op_info = (char *) "updating or deleting";
trx_start_if_not_started(trx);
@@ -948,7 +948,7 @@ run_again:
if (err == DB_RECORD_NOT_FOUND) {
trx->error_state = DB_SUCCESS;
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -959,7 +959,7 @@ run_again:
goto run_again;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -978,7 +978,7 @@ run_again:
row_update_statistics_if_needed(prebuilt->table);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -1194,7 +1194,7 @@ row_create_table_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "creating table";
+ trx->op_info = (char *) "creating table";
if (0 == ut_strcmp(table->name, "mysql/host")
|| 0 == ut_strcmp(table->name, "mysql/user")
@@ -1232,11 +1232,11 @@ row_create_table_for_mysql(
namelen = ut_strlen(table->name);
- keywordlen = ut_strlen("innodb_monitor");
+ keywordlen = ut_strlen((char *) "innodb_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_monitor", keywordlen)) {
+ (char *) "innodb_monitor", keywordlen)) {
/* Table name ends to characters innodb_monitor:
start monitor prints */
@@ -1249,32 +1249,34 @@ row_create_table_for_mysql(
os_event_set(srv_lock_timeout_thread_event);
}
- keywordlen = ut_strlen("innodb_lock_monitor");
+ keywordlen = ut_strlen((char *) "innodb_lock_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_lock_monitor", keywordlen)) {
+ (char *) "innodb_lock_monitor", keywordlen)) {
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
}
- keywordlen = ut_strlen("innodb_tablespace_monitor");
+ keywordlen = ut_strlen((char *) "innodb_tablespace_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_tablespace_monitor", keywordlen)) {
+ (char *) "innodb_tablespace_monitor",
+ keywordlen)) {
srv_print_innodb_tablespace_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
}
- keywordlen = ut_strlen("innodb_table_monitor");
+ keywordlen = ut_strlen((char *) "innodb_table_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_table_monitor", keywordlen)) {
+ (char *) "innodb_table_monitor",
+ keywordlen)) {
srv_print_innodb_table_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
@@ -1351,7 +1353,7 @@ row_create_table_for_mysql(
que_graph_free((que_t*) que_node_get_parent(thr));
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -1378,7 +1380,7 @@ row_create_index_for_mysql(
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
- trx->op_info = "creating index";
+ trx->op_info = (char *) "creating index";
trx_start_if_not_started(trx);
@@ -1423,7 +1425,7 @@ row_create_index_for_mysql(
que_graph_free((que_t*) que_node_get_parent(thr));
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -1457,7 +1459,7 @@ row_table_add_foreign_constraints(
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_a(sql_string);
- trx->op_info = "adding foreign keys";
+ trx->op_info = (char *) "adding foreign keys";
trx_start_if_not_started(trx);
@@ -1709,16 +1711,16 @@ row_drop_table_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "dropping table";
+ trx->op_info = (char *) "dropping table";
trx_start_if_not_started(trx);
namelen = ut_strlen(name);
- keywordlen = ut_strlen("innodb_monitor");
+ keywordlen = ut_strlen((char *) "innodb_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_monitor", keywordlen)) {
+ (char *) "innodb_monitor", keywordlen)) {
/* Table name ends to characters innodb_monitor:
stop monitor prints */
@@ -1727,30 +1729,33 @@ row_drop_table_for_mysql(
srv_print_innodb_lock_monitor = FALSE;
}
- keywordlen = ut_strlen("innodb_lock_monitor");
+ keywordlen = ut_strlen((char *) "innodb_lock_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_lock_monitor", keywordlen)) {
+ (char *) "innodb_lock_monitor",
+ keywordlen)) {
srv_print_innodb_monitor = FALSE;
srv_print_innodb_lock_monitor = FALSE;
}
- keywordlen = ut_strlen("innodb_tablespace_monitor");
+ keywordlen = ut_strlen((char *) "innodb_tablespace_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_tablespace_monitor", keywordlen)) {
+ (char *) "innodb_tablespace_monitor",
+ keywordlen)) {
srv_print_innodb_tablespace_monitor = FALSE;
}
- keywordlen = ut_strlen("innodb_table_monitor");
+ keywordlen = ut_strlen((char *) "innodb_table_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_table_monitor", keywordlen)) {
+ (char *) "innodb_table_monitor",
+ keywordlen)) {
srv_print_innodb_table_monitor = FALSE;
}
@@ -1760,7 +1765,7 @@ row_drop_table_for_mysql(
tables in Innobase. Deleting a row from SYS_INDEXES table also
frees the file segments of the B-tree associated with the index. */
- str1 =
+ str1 = (char *)
"PROCEDURE DROP_TABLE_PROC () IS\n"
"table_name CHAR;\n"
"sys_foreign_id CHAR;\n"
@@ -1771,7 +1776,7 @@ row_drop_table_for_mysql(
"BEGIN\n"
"table_name := '";
- str2 =
+ str2 = (char *)
"';\n"
"SELECT ID INTO table_id\n"
"FROM SYS_TABLES\n"
@@ -1942,7 +1947,7 @@ funct_exit:
trx_commit_for_mysql(trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
srv_wake_master_thread();
@@ -1967,14 +1972,14 @@ row_drop_database_for_mysql(
ut_a(name != NULL);
ut_a(name[strlen(name) - 1] == '/');
- trx->op_info = "dropping database";
+ trx->op_info = (char *) "dropping database";
trx_start_if_not_started(trx);
loop:
rw_lock_x_lock(&(dict_foreign_key_check_lock));
mutex_enter(&(dict_sys->mutex));
- while (table_name = dict_get_first_table_name_in_db(name)) {
+ while ((table_name = dict_get_first_table_name_in_db(name))) {
ut_a(memcmp(table_name, name, strlen(name)) == 0);
table = dict_table_get_low(table_name);
@@ -2018,7 +2023,7 @@ loop:
trx_commit_for_mysql(trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -2095,17 +2100,17 @@ row_rename_table_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "renaming table";
+ trx->op_info = (char *) "renaming table";
trx_start_if_not_started(trx);
- str1 =
+ str1 = (char *)
"PROCEDURE RENAME_TABLE_PROC () IS\n"
"new_table_name CHAR;\n"
"old_table_name CHAR;\n"
"BEGIN\n"
"new_table_name :='";
- str2 =
+ str2 = (char *)
"';\nold_table_name := '";
if (row_is_mysql_tmp_table_name(new_name)) {
@@ -2113,13 +2118,13 @@ row_rename_table_for_mysql(
/* We want to preserve the original foreign key
constraint definitions despite the name change */
- str3 =
+ str3 = (char*)
"';\n"
"UPDATE SYS_TABLES SET NAME = new_table_name\n"
"WHERE NAME = old_table_name;\n"
"END;\n";
} else {
- str3 =
+ str3 = (char*)
"';\n"
"UPDATE SYS_TABLES SET NAME = new_table_name\n"
"WHERE NAME = old_table_name;\n"
@@ -2239,7 +2244,7 @@ funct_exit:
trx_commit_for_mysql(trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -2384,7 +2389,7 @@ row_check_table_for_mysql(
ulint n_rows_in_table = ULINT_UNDEFINED;
ulint ret = DB_SUCCESS;
- prebuilt->trx->op_info = "checking table";
+ prebuilt->trx->op_info = (char *) "checking table";
index = dict_table_get_first_index(table);
@@ -2425,7 +2430,7 @@ row_check_table_for_mysql(
ret = DB_ERROR;
}
- prebuilt->trx->op_info = "";
+ prebuilt->trx->op_info = (char *) "";
return(ret);
}
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index 5da98943926..60e057b816e 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -204,7 +204,7 @@ row_purge_remove_sec_if_poss_low(
btr_pcur_t pcur;
btr_cur_t* btr_cur;
ibool success;
- ibool old_has;
+ ibool old_has = 0; /* remove warning */
ibool found;
ulint err;
mtr_t mtr;
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index d6b2413c911..f3dced15fdf 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -64,7 +64,8 @@ row_sel_sec_rec_is_for_clust_rec(
rec_t* sec_rec, /* in: secondary index record */
dict_index_t* sec_index, /* in: secondary index */
rec_t* clust_rec, /* in: clustered index record */
- dict_index_t* clust_index) /* in: clustered index */
+ dict_index_t* clust_index __attribute__((unused)))
+ /* in: clustered index */
{
dict_col_t* col;
byte* sec_field;
@@ -2542,7 +2543,7 @@ row_search_for_mysql(
printf("N tables locked %lu\n", trx->mysql_n_tables_locked);
*/
if (direction == 0) {
- trx->op_info = "starting index read";
+ trx->op_info = (char *) "starting index read";
prebuilt->n_rows_fetched = 0;
prebuilt->n_fetch_cached = 0;
@@ -2553,7 +2554,7 @@ row_search_for_mysql(
row_prebuild_sel_graph(prebuilt);
}
} else {
- trx->op_info = "fetching rows";
+ trx->op_info = (char *) "fetching rows";
if (prebuilt->n_rows_fetched == 0) {
prebuilt->fetch_direction = direction;
@@ -2578,7 +2579,7 @@ row_search_for_mysql(
prebuilt->n_rows_fetched++;
srv_n_rows_read++;
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(DB_SUCCESS);
}
@@ -2590,7 +2591,7 @@ row_search_for_mysql(
cache, but the cache was not full at the time of the
popping: no more rows can exist in the result set */
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(DB_RECORD_NOT_FOUND);
}
@@ -2630,7 +2631,7 @@ row_search_for_mysql(
/* printf("%s record not found 1\n", index->name); */
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(DB_RECORD_NOT_FOUND);
}
@@ -2693,7 +2694,7 @@ row_search_for_mysql(
trx->has_search_latch = FALSE;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(DB_SUCCESS);
} else if (shortcut == SEL_EXHAUSTED) {
@@ -2712,7 +2713,7 @@ row_search_for_mysql(
trx->has_search_latch = FALSE;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(DB_RECORD_NOT_FOUND);
}
@@ -3089,7 +3090,7 @@ lock_wait_or_error:
/* printf("Using index %s cnt %lu ret value %lu err\n", index->name,
cnt, err); */
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
@@ -3110,7 +3111,7 @@ normal_return:
srv_n_rows_read++;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(ret);
}
diff --git a/innobase/row/row0uins.c b/innobase/row/row0uins.c
index 27d1fbcb9ba..9990f893432 100644
--- a/innobase/row/row0uins.c
+++ b/innobase/row/row0uins.c
@@ -234,7 +234,7 @@ void
row_undo_ins_parse_undo_rec(
/*========================*/
undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr __attribute__((unused))) /* in: query thread */
{
dict_index_t* clust_index;
byte* ptr;
diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c
index bbffda39352..b84e55ca643 100644
--- a/innobase/row/row0umod.c
+++ b/innobase/row/row0umod.c
@@ -139,7 +139,7 @@ row_undo_mod_remove_clust_low(
/* out: DB_SUCCESS, DB_FAIL, or error code:
we may run out of file space */
undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
+ que_thr_t* thr __attribute__((unused)), /* in: query thread */
mtr_t* mtr, /* in: mtr */
ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 6eaab79060e..25c82f39da9 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -428,7 +428,7 @@ row_upd_write_sys_vals_to_log(
dulint roll_ptr,/* in: roll ptr of the undo log record */
byte* log_ptr,/* pointer to a buffer of size > 20 opened
in mlog */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr __attribute__((unused))) /* in: mtr */
{
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(mtr);
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 80de52dc4a1..3efb82eb8eb 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -61,7 +61,7 @@ ulint srv_activity_count = 0;
ibool srv_lock_timeout_and_monitor_active = FALSE;
ibool srv_error_monitor_active = FALSE;
-char* srv_main_thread_op_info = "";
+char* srv_main_thread_op_info = (char*) "";
/* Server parameters which are read from the initfile */
@@ -238,6 +238,11 @@ ulint srv_n_rows_updated_old = 0;
ulint srv_n_rows_deleted_old = 0;
ulint srv_n_rows_read_old = 0;
+/*
+ Set the following to 0 if you want InnoDB to write messages on
+ stderr on startup/shutdown
+*/
+ibool srv_print_verbose_log = TRUE;
ibool srv_print_innodb_monitor = FALSE;
ibool srv_print_innodb_lock_monitor = FALSE;
ibool srv_print_innodb_tablespace_monitor = FALSE;
@@ -1629,6 +1634,7 @@ srv_init(void)
for (i = 0; i < OS_THREAD_MAX_N; i++) {
slot = srv_table_get_nth_slot(i);
slot->in_use = FALSE;
+ slot->type=0; /* Avoid purify errors */
slot->event = os_event_create(NULL);
ut_a(slot->event);
}
@@ -2583,7 +2589,7 @@ srv_master_thread(
os_event_set(srv_sys->operational);
loop:
- srv_main_thread_op_info = "reserving kernel mutex";
+ srv_main_thread_op_info = (char*) "reserving kernel mutex";
n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
@@ -2679,10 +2685,10 @@ loop:
+ buf_pool->n_pages_written;
if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) {
- srv_main_thread_op_info = "flushing buffer pool pages";
+ srv_main_thread_op_info = (char*) "flushing buffer pool pages";
buf_flush_batch(BUF_FLUSH_LIST, 50, ut_dulint_max);
- srv_main_thread_op_info = "flushing log";
+ srv_main_thread_op_info = (char*) "flushing log";
log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
log_flush_to_disk();
}
@@ -2717,7 +2723,7 @@ loop:
current_time = time(NULL);
if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
+ srv_main_thread_op_info = (char*) "flushing log";
log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
log_flush_to_disk();
@@ -2797,7 +2803,7 @@ background_loop:
}
mutex_exit(&kernel_mutex);
- srv_main_thread_op_info = "waiting for buffer pool flush to end";
+ srv_main_thread_op_info = (char*) "waiting for buffer pool flush to end";
buf_flush_wait_batch_end(BUF_FLUSH_LIST);
srv_main_thread_op_info = (char*)"making checkpoint";
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index 9768d484ce6..55e734be3bd 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -433,7 +433,7 @@ Normalizes a directory path for Windows: converts slashes to backslashes. */
void
srv_normalize_path_for_win(
/*=======================*/
- char* str) /* in/out: null-terminated character string */
+ char* str __attribute__((unused))) /* in/out: null-terminated character string */
{
#ifdef __WIN__
ulint i;
@@ -618,7 +618,7 @@ open_or_create_log_file(
if (k == 0 && i == 0) {
arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
- fil_space_create("arch_log_space", arch_space_id, FIL_LOG);
+ fil_space_create((char*) "arch_log_space", arch_space_id, FIL_LOG);
} else {
arch_space_id = ULINT_UNDEFINED;
}
@@ -1325,9 +1325,11 @@ innobase_start_or_create_for_mysql(void)
SRV_MAX_N_IO_THREADS);
/* buf_debug_prints = TRUE; */
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Started\n");
-
+ if (srv_print_verbose_log)
+ {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Started\n");
+ }
return((int) DB_SUCCESS);
}
diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c
index 81b5b7de195..36dd8a7d80c 100644
--- a/innobase/sync/sync0arr.c
+++ b/innobase/sync/sync0arr.c
@@ -447,7 +447,7 @@ sync_array_cell_print(
{
mutex_t* mutex;
rw_lock_t* rwlock;
- char* str = NULL;
+ char* str __attribute__((unused)) = NULL;
ulint type;
type = cell->request_type;
diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c
index 1ef2920618f..86ffed7ca95 100644
--- a/innobase/sync/sync0rw.c
+++ b/innobase/sync/sync0rw.c
@@ -115,8 +115,8 @@ rw_lock_create_func(
lock->cfile_name = cfile_name;
lock->cline = cline;
- lock->last_s_file_name = "not yet reserved";
- lock->last_x_file_name = "not yet reserved";
+ lock->last_s_file_name = (char *) "not yet reserved";
+ lock->last_x_file_name = (char *) "not yet reserved";
lock->last_s_line = 0;
lock->last_x_line = 0;
@@ -789,7 +789,7 @@ Prints debug info of an rw-lock. */
void
rw_lock_print(
/*==========*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock __attribute__((unused))) /* in: rw-lock */
{
#ifndef UNIV_SYNC_DEBUG
printf(
diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c
index c070e97f692..14a2a6f8cc1 100644
--- a/innobase/sync/sync0sync.c
+++ b/innobase/sync/sync0sync.c
@@ -229,7 +229,7 @@ mutex_create_func(
mutex_set_waiters(mutex, 0);
mutex->magic_n = MUTEX_MAGIC_N;
mutex->line = 0;
- mutex->file_name = "not yet reserved";
+ mutex->file_name = (char *) "not yet reserved";
mutex->thread_id = ULINT_UNDEFINED;
mutex->level = SYNC_LEVEL_NONE;
mutex->cfile_name = cfile_name;
diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c
index b73629c9fa4..97362d00b4b 100644
--- a/innobase/trx/trx0purge.c
+++ b/innobase/trx/trx0purge.c
@@ -674,9 +674,9 @@ trx_purge_choose_next_log(void)
trx_rseg_t* rseg;
trx_rseg_t* min_rseg;
dulint min_trx_no;
- ulint space;
- ulint page_no;
- ulint offset;
+ ulint space = 0; /* remove warning (??? bug ???) */
+ ulint page_no = 0; /* remove warning (??? bug ???) */
+ ulint offset = 0; /* remove warning (??? bug ???) */
mtr_t mtr;
ut_ad(mutex_own(&(purge_sys->mutex)));
diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c
index abce470bd1c..05e179e06a5 100644
--- a/innobase/trx/trx0rec.c
+++ b/innobase/trx/trx0rec.c
@@ -989,7 +989,7 @@ trx_undo_parse_erase_page_end(
/*==========================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -1263,7 +1263,8 @@ trx_undo_prev_version_build(
DB_ERROR if corrupted record */
rec_t* index_rec,/* in: clustered index record in the
index tree */
- mtr_t* index_mtr,/* in: mtr which contains the latch to
+ mtr_t* index_mtr __attribute__((unused)),
+ /* in: mtr which contains the latch to
index_rec page and purge_view */
rec_t* rec, /* in: version of a clustered index record */
dict_index_t* index, /* in: clustered index */
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index 0a951484b59..4c2ee5dc9be 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -101,7 +101,7 @@ trx_rollback_for_mysql(
return(DB_SUCCESS);
}
- trx->op_info = "rollback";
+ trx->op_info = (char *) "rollback";
/* Tell Innobase server that there might be work for
utility threads: */
@@ -117,7 +117,7 @@ trx_rollback_for_mysql(
srv_active_wake_master_thread();
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -138,7 +138,7 @@ trx_rollback_last_sql_stat_for_mysql(
return(DB_SUCCESS);
}
- trx->op_info = "rollback of SQL statement";
+ trx->op_info = (char *) "rollback of SQL statement";
/* Tell Innobase server that there might be work for
utility threads: */
@@ -154,7 +154,7 @@ trx_rollback_last_sql_stat_for_mysql(
srv_active_wake_master_thread();
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -182,7 +182,7 @@ trx_rollback_or_clean_all_without_sess(void)
if (!trx_dummy_sess) {
trx_dummy_sess = sess_open(NULL, (byte*)"Dummy sess",
- ut_strlen("Dummy sess"));
+ ut_strlen((char *) "Dummy sess"));
}
mutex_exit(&kernel_mutex);
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index c2d99424d33..8d84967a49d 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -68,7 +68,7 @@ trx_create(
trx->magic_n = TRX_MAGIC_N;
- trx->op_info = "";
+ trx->op_info = (char *) "";
trx->type = TRX_USER;
trx->conc_state = TRX_NOT_STARTED;
@@ -151,7 +151,7 @@ trx_allocate_for_mysql(void)
if (!trx_dummy_sess) {
trx_dummy_sess = sess_open(NULL, (byte*)"Dummy sess",
- ut_strlen("Dummy sess"));
+ ut_strlen((char *) "Dummy sess"));
}
trx = trx_create(trx_dummy_sess);
@@ -1121,7 +1121,7 @@ trx_sig_send(
ut_a(0);
sess_raise_error_low(trx, 0, 0, NULL, NULL, NULL, NULL,
- "Signal from another session, or a break execution signal");
+ (char *) "Signal from another session, or a break execution signal");
}
/* If there were no other signals ahead in the queue, try to start
@@ -1422,7 +1422,7 @@ trx_commit_for_mysql(
ut_a(trx);
- trx->op_info = "committing";
+ trx->op_info = (char *) "committing";
trx_start_if_not_started(trx);
@@ -1432,7 +1432,7 @@ trx_commit_for_mysql(
mutex_exit(&kernel_mutex);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(0);
}
diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c
index dd249a7062a..6303c5bbcdd 100644
--- a/innobase/trx/trx0undo.c
+++ b/innobase/trx/trx0undo.c
@@ -374,7 +374,7 @@ trx_undo_seg_create(
/*================*/
/* out: segment header page x-latched, NULL
if no space left */
- trx_rseg_t* rseg, /* in: rollback segment */
+ trx_rseg_t* rseg __attribute__((unused)),/* in: rollback segment */
trx_rsegf_t* rseg_hdr,/* in: rollback segment header, page
x-latched */
ulint type, /* in: type of the segment: TRX_UNDO_INSERT or
@@ -657,7 +657,7 @@ trx_undo_parse_discard_latest(
/*==========================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -844,7 +844,7 @@ static
void
trx_undo_free_page_in_rollback(
/*===========================*/
- trx_t* trx, /* in: transaction */
+ trx_t* trx __attribute__((unused)), /* in: transaction */
trx_undo_t* undo, /* in: undo log memory copy */
ulint page_no,/* in: page number to free: must not be the
header page */
@@ -1567,7 +1567,7 @@ trx_undo_set_state_at_finish(
/*=========================*/
/* out: undo log segment header page,
x-latched */
- trx_t* trx, /* in: transaction */
+ trx_t* trx __attribute__((unused)), /* in: transaction */
trx_undo_t* undo, /* in: undo log memory copy */
mtr_t* mtr) /* in: mtr */
{
diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c
index 6a5f273e731..c164afa0573 100644
--- a/innobase/ut/ut0ut.c
+++ b/innobase/ut/ut0ut.c
@@ -27,11 +27,11 @@ ut_get_high32(
/* out: a >> 32 */
ulint a) /* in: ulint */
{
- if (sizeof(ulint) == 4) {
- return(0);
- }
-
+#if SIZEOF_LONG == 4
+ return 0;
+#else
return(a >> 32);
+#endif
}
/************************************************************
diff --git a/isam/_cache.c b/isam/_cache.c
index 53619126660..bca9a699a85 100644
--- a/isam/_cache.c
+++ b/isam/_cache.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -46,11 +46,11 @@ int _nisam_read_cache(IO_CACHE *info, byte *buff, ulong pos, uint length,
buff+=read_length;
}
if ((offset=pos - (ulong) info->pos_in_file) <
- (ulong) (info->rc_end - info->rc_request_pos))
+ (ulong) (info->read_end - info->request_pos))
{
- in_buff_pos=info->rc_request_pos+(uint) offset;
- in_buff_length= min(length,(uint) (info->rc_end-in_buff_pos));
- memcpy(buff,info->rc_request_pos+(uint) offset,(size_t) in_buff_length);
+ in_buff_pos=info->request_pos+(uint) offset;
+ in_buff_length= min(length,(uint) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
if (!(length-=in_buff_length))
return 0;
pos+=in_buff_length;
@@ -61,14 +61,14 @@ int _nisam_read_cache(IO_CACHE *info, byte *buff, ulong pos, uint length,
if (flag & READING_NEXT)
{
if (pos != ((info)->pos_in_file +
- (uint) ((info)->rc_end - (info)->rc_request_pos)))
+ (uint) ((info)->read_end - (info)->request_pos)))
{
info->pos_in_file=pos; /* Force start here */
- info->rc_pos=info->rc_end=info->rc_request_pos; /* Everything used */
+ info->read_pos=info->read_end=info->request_pos; /* Everything used */
info->seek_not_done=1;
}
else
- info->rc_pos=info->rc_end; /* All block used */
+ info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length))
return 0;
if (!(flag & READING_HEADER) || info->error == -1 ||
diff --git a/isam/_dbug.c b/isam/_dbug.c
index 18e671793ed..0a52dbbc916 100644
--- a/isam/_dbug.c
+++ b/isam/_dbug.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_dynrec.c b/isam/_dynrec.c
index 2a908f5b42c..d17d34e6778 100644
--- a/isam/_dynrec.c
+++ b/isam/_dynrec.c
@@ -432,7 +432,7 @@ uint _nisam_rec_pack(N_INFO *info, register byte *to, register const byte *from)
blob++;
from+=sizeof(char*); /* Skipp blob-pointer */
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) from,zero_string,length) == 0)
flag|=bit;
@@ -441,11 +441,11 @@ uint _nisam_rec_pack(N_INFO *info, register byte *to, register const byte *from)
memcpy((byte*) to,from,(size_t) length); to+=length;
}
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) from; end= (byte*) from + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > from && *(end-1) == ' ')
end--;
@@ -532,7 +532,7 @@ my_bool _nisam_rec_check(N_INFO *info,const char *from)
to+=length+ blob_length;
from+=sizeof(char*);
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) from,zero_string,length) == 0)
{
@@ -542,11 +542,11 @@ my_bool _nisam_rec_check(N_INFO *info,const char *from)
else
to+=length;
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) from; end= (byte*) from + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > from && *(end-1) == ' ')
end--;
@@ -641,10 +641,10 @@ uint _nisam_rec_unpack(register N_INFO *info, register byte *to, byte *from,
bzero((byte*) to,rec_length+sizeof(char*));
to+=sizeof(char*);
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
bzero((byte*) to,rec_length);
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
if (rec->base.length > 255 && *from & 128)
{
@@ -662,7 +662,7 @@ uint _nisam_rec_unpack(register N_INFO *info, register byte *to, byte *from,
if (length >= rec_length ||
min_pack_length + length > (uint) (from_end - from))
goto err;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{
memcpy(to,(byte*) from,(size_t) length);
bfill((byte*) to+length,rec_length-length,' ');
@@ -690,7 +690,7 @@ uint _nisam_rec_unpack(register N_INFO *info, register byte *to, byte *from,
}
else
{
- if (type == FIELD_SKIPP_ENDSPACE || type == FIELD_SKIPP_PRESPACE)
+ if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE)
min_pack_length--;
if (min_pack_length + rec_length > (uint) (from_end - from))
goto err;
diff --git a/isam/_key.c b/isam/_key.c
index 62f080af172..c0d667cb32d 100644
--- a/isam/_key.c
+++ b/isam/_key.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_locking.c b/isam/_locking.c
index ca38c611812..be9741a4237 100644
--- a/isam/_locking.c
+++ b/isam/_locking.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -306,8 +306,8 @@ int _nisam_writeinfo(register N_INFO *info, uint flags)
MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
DBUG_RETURN(1);
}
- }
#endif
+ }
my_errno=olderror;
}
else if (flags)
diff --git a/isam/_packrec.c b/isam/_packrec.c
index 5c387f011ad..74a45852e63 100644
--- a/isam/_packrec.c
+++ b/isam/_packrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -456,7 +456,7 @@ int _nisam_pack_rec_unpack(register N_INFO *info, register byte *to,
static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *, BIT_BUFF *, uchar *, uchar *)
{
switch (rec->base_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_skipp_zero;
return &uf_skipp_zero;
@@ -466,7 +466,7 @@ static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *, BIT_BUFF *, ucha
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_normal;
return &decode_bytes;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
@@ -476,7 +476,7 @@ static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *, BIT_BUFF *, ucha
if (rec->pack_type & PACK_TYPE_SELECTED)
return &uf_endspace_selected;
return &uf_endspace;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
diff --git a/isam/_page.c b/isam/_page.c
index 6f6d632e85d..65733d66b77 100644
--- a/isam/_page.c
+++ b/isam/_page.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_search.c b/isam/_search.c
index 93a08ea2b0d..57787d61818 100644
--- a/isam/_search.c
+++ b/isam/_search.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_statrec.c b/isam/_statrec.c
index d93f4fe27f5..9dbc948440f 100644
--- a/isam/_statrec.c
+++ b/isam/_statrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -187,7 +187,7 @@ int _nisam_read_rnd_static_record(N_INFO *info, byte *buf,
(skipp_deleted_blocks || !filepos))
{
cache_read=1; /* Read record using cache */
- cache_length=(uint) (info->rec_cache.rc_end - info->rec_cache.rc_pos);
+ cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos);
}
else
info->rec_cache.seek_not_done=1; /* Filepos is changed */
diff --git a/isam/changed.c b/isam/changed.c
index 4f87a45aa2d..b8132538b86 100644
--- a/isam/changed.c
+++ b/isam/changed.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/close.c b/isam/close.c
index 6741e7b23f0..f1465990100 100644
--- a/isam/close.c
+++ b/isam/close.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/create.c b/isam/create.c
index fcf54ddc731..1fc2f3b97be 100644
--- a/isam/create.c
+++ b/isam/create.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -96,8 +96,8 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
pack_reclength+=sizeof(char*)+(1 << (rec->base.length*8));
}
}
- else if (type == FIELD_SKIPP_PRESPACE ||
- type == FIELD_SKIPP_ENDSPACE)
+ else if (type == FIELD_SKIP_PRESPACE ||
+ type == FIELD_SKIP_ENDSPACE)
{
if (pack_reclength != NI_POS_ERROR)
pack_reclength+= rec->base.length > 255 ? 2 : 1;
@@ -105,7 +105,7 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
}
else if (type == FIELD_ZERO)
packed--;
- else if (type != FIELD_SKIPP_ZERO)
+ else if (type != FIELD_SKIP_ZERO)
{
min_pack_length+=rec->base.length;
packed--; /* Not a pack record type */
@@ -119,7 +119,7 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
while (rec != recinfo)
{
rec--;
- if (rec->base.type == (int) FIELD_SKIPP_ZERO && rec->base.length == 1)
+ if (rec->base.type == (int) FIELD_SKIP_ZERO && rec->base.length == 1)
{
rec->base.type=(int) FIELD_NORMAL;
packed--;
diff --git a/isam/delete.c b/isam/delete.c
index e50ad72c767..5aa542561c1 100644
--- a/isam/delete.c
+++ b/isam/delete.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -613,5 +613,3 @@ static uint remove_key(N_KEYDEF *keyinfo, uint nod_flag,
(uint) (page_end-start-s_length));
DBUG_RETURN((uint) s_length);
} /* remove_key */
-
-
diff --git a/isam/extra.c b/isam/extra.c
index 1d333fa372f..570c396955f 100644
--- a/isam/extra.c
+++ b/isam/extra.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -204,6 +204,7 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
info->s->changed=1; /* Update on close */
break;
case HA_EXTRA_FORCE_REOPEN:
+ case HA_EXTRA_PREPARE_FOR_DELETE:
pthread_mutex_lock(&THR_LOCK_isam);
info->s->last_version= 0L; /* Impossible version */
#ifdef __WIN__
diff --git a/isam/info.c b/isam/info.c
index 43c15af908d..a23494e4876 100644
--- a/isam/info.c
+++ b/isam/info.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/isamchk.c b/isam/isamchk.c
index 3aa1cf4e3c2..ea3055534ca 100644
--- a/isam/isamchk.c
+++ b/isam/isamchk.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@
#include <m_ctype.h>
#include <stdarg.h>
-#include <getopt.h>
+#include <my_getopt.h>
#ifdef HAVE_SYS_VADVICE_H
#include <sys/vadvise.h>
#endif
@@ -62,7 +62,7 @@ SET_STACK_SIZE(9000) /* Minimum stack size for program */
#define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD)
#endif
-#define NEAD_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
+#define NEED_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
#define MAXERR 20
#define BUFFERS_WHEN_SORTING 16 /* Alloc for sort-key-tree */
#define WRITE_COUNT MY_HOW_OFTEN_TO_WRITE
@@ -94,12 +94,16 @@ typedef struct st_isam_sort_info {
N_KEYSEG *keyseg;
} ISAM_SORT_INFO;
-enum ic_options {OPT_CHARSETS_DIR_IC=256};
+enum ic_options {OPT_CHARSETS_DIR_IC=256, OPT_KEY_BUFFER_SIZE,
+ OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE,
+ OPT_SORT_BUFFER_SIZE, OPT_SORT_KEY_BLOCKS,
+ OPT_DECODE_BITS};
static ulong use_buffers=0,read_buffer_length=0,write_buffer_length=0,
sort_buffer_length=0,sort_key_blocks=0,crc=0,unique_count=0;
static uint testflag=0,out_flag=0,warning_printed=0,error_printed=0,
- rep_quick=0,verbose=0,opt_follow_links=1;
+ verbose=0,opt_follow_links=1;
+static my_bool rep_quick= 0;
static uint opt_sort_key=0,total_files=0,max_level=0,max_key=N_MAXKEY;
static ulong keydata=0,totaldata=0,key_blocks=0;
static ulong new_file_pos=0,record_checksum=0,key_file_blocks=0,decode_bits;
@@ -234,118 +238,118 @@ int main( int argc, char **argv)
} /* main */
-static CHANGEABLE_VAR changeable_vars[] = {
- { "key_buffer_size",(long*) &use_buffers,(long) USE_BUFFER_INIT,
- (long) MALLOC_OVERHEAD, (long) ~0L,(long) MALLOC_OVERHEAD,(long) IO_SIZE },
- { "read_buffer_size", (long*) &read_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "write_buffer_size", (long*) &write_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_buffer_size",(long*) &sort_buffer_length,(long) SORT_BUFFER_INIT,
- (long) (MIN_SORT_BUFFER+MALLOC_OVERHEAD),(long) ~0L,
- (long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_key_blocks",(long*) &sort_key_blocks,BUFFERS_WHEN_SORTING,4L,100L,0L,
- 1L },
- { "decode_bits",(long*) &decode_bits,9L,4L,17L,0L,1L },
- { NullS,(long*) 0,0L,0L,0L,0L,0L,} };
-
-
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"analyze", no_argument, 0, 'a'},
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR_IC},
+ {"analyze", 'a',
+ "Analyze distribution of keys. Will make some joins in MySQL faster.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR_IC,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", required_argument, 0, '#'},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"default-character-set", required_argument, 0, 'C'},
- {"description", no_argument, 0, 'd'},
- {"extend-check", no_argument, 0, 'e'},
- {"information", no_argument, 0, 'i'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"keys-used", required_argument, 0, 'k'},
- {"no-symlinks", no_argument, 0, 'l'},
- {"quick", no_argument, 0, 'q'},
- {"recover", no_argument, 0, 'r'},
- {"safe-recover", no_argument, 0, 'o'},
- {"block-search", required_argument, 0, 'b'},
- {"set-variable", required_argument, 0, 'O'},
- {"silent", no_argument, 0, 's'},
- {"sort-index", no_argument, 0, 'S'},
- {"sort-records", required_argument, 0, 'R'},
- {"unpack", no_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"default-character-set", 'C', "Set the default character set",
+ (gptr*) &default_charset, (gptr*) &default_charset, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"description", 'd', "Prints some information about table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"extend-check", 'e',
+ "Check the table VERY thoroughly. One need to use this only in extreme cases, because isamchk should normally find all errors even without this switch.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"information", 'i', "Print statistics information about the table",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Overwrite old temporary files. If one uses -f when checking tables (running isamchk without -r), isamchk will automatically restart with -r on any wrong table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"keys-used", 'k',
+ "Used with '-r'. Tell ISAM to update only the first # keys. This can be used to get faster inserts!",
+ (gptr*) &max_key, (gptr*) &max_key, 0, GET_UINT, REQUIRED_ARG, N_MAXKEY, 0,
+ 0, 0, 0, 0},
+ {"no-symlinks", 'l',
+ "Do not follow symbolic links when repairing. Normally isamchk repairs the table a symlink points at.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quick", 'q',
+ "Used with -r to get a faster repair. (The data file isn't touched.) One can give a second '-q' to force isamchk to modify the original datafile.",
+ (gptr*) &rep_quick, (gptr*) &rep_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"recover", 'r',
+ "Can fix almost anything except unique keys that aren't unique.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"safe-recover", 'o',
+ "Uses old recovery method; slower than '-r' but can handle a couple of cases that '-r' cannot handle.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"block-search", 'b', "For debugging.", (gptr*) &search_after_block,
+ (gptr*) &search_after_block, 0, GET_ULONG, REQUIRED_ARG, NI_POS_ERROR, 0,
+ 0, 0, 0, 0},
+ {"silent", 's',
+ "Only print errors. One can use two -s to make isamchk very silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-index", 'S',
+ "Sort index blocks. This speeds up 'read-next' in applications.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-records", 'R',
+ "Sort records according to an index. This makes your data much more localized and may speed up things (It may be VERY slow to do a sort the first time!)",
+ (gptr*) &opt_sort_key, (gptr*) &opt_sort_key, 0, GET_UINT, REQUIRED_ARG,
+ 0, 0, (N_MAXKEY - 1), 1, 0, 0},
+ {"unpack", 'u', "Unpack file packed with pack_isam.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v',
+ "Print more information. This can be used with -d and -e. Use many -v for more verbosity!",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Print version and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w', "Wait if table is locked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_buffer_size", OPT_KEY_BUFFER_SIZE, "", (gptr*) &use_buffers,
+ (gptr*) &use_buffers, 0, GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT,
+ (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE,
+ 0},
+ {"read_buffer_size", OPT_READ_BUFFER_SIZE, "",
+ (gptr*) &read_buffer_length, (gptr*) &read_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ {"write_buffer_size", OPT_WRITE_BUFFER_SIZE, "",
+ (gptr*) &write_buffer_length, (gptr*) &write_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L,
+ (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ {"sort_buffer_size", OPT_SORT_BUFFER_SIZE, "",
+ (gptr*) &sort_buffer_length, (gptr*) &sort_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, (long) SORT_BUFFER_INIT,
+ (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L,
+ (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ {"sort_key_blocks", OPT_SORT_KEY_BLOCKS, "",
+ (gptr*) &sort_key_blocks, (gptr*) &sort_key_blocks, 0, GET_ULONG,
+ REQUIRED_ARG, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0},
+ {"decode_bits", OPT_DECODE_BITS, "",
+ (gptr*) &decode_bits, (gptr*) &decode_bits, 0, GET_ULONG, REQUIRED_ARG,
+ 9L, 4L, 17L, 0L, 1L, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void print_version(void)
{
- printf("%s Ver 5.17 for %s at %s\n",my_progname,SYSTEM_TYPE,
+ printf("%s Ver 6.01 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
}
static void usage(void)
{
- uint i;
print_version();
- puts("TCX Datakonsult AB, by Monty, for your professional use");
+ puts("MySQL AB, by Monty, for your professional use");
puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n");
puts("Description, check and repair of ISAM tables.");
puts("Used without options all tables on the command will be checked for errors");
printf("Usage: %s [OPTIONS] tables[.ISM]\n", my_progname);
- puts("\n\
- -a, --analyze Analyze distribution of keys. Will make some joins in\n\
- MySQL faster.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -C, --default-character-set=...\n\
- Set the default character set\n\
- -d, --description Prints some information about table.\n\
- -e, --extend-check Check the table VERY thoroughly. One need use this\n\
- only in extreme cases as isamchk should normally find\n\
- all errors even without this switch\n\
- -f, --force Overwrite old temporary files.\n\
- If one uses -f when checking tables (running isamchk\n\
- without -r), isamchk will automatically restart with\n\
- -r on any wrong table.\n\
- -?, --help Display this help and exit.\n\
- -i, --information Print statistics information about the table\n\
- -k, --keys-used=# Used with '-r'. Tell ISAM to update only the first\n\
- # keys. This can be used to get faster inserts!\n\
- -l, --no-symlinks Do not follow symbolic links when repairing. Normally\n\
- isamchk repairs the table a symlink points at.\n\
- -q, --quick Used with -r to get a faster repair. (The data file\n\
- isn't touched.) One can give a second '-q' to force\n\
- isamchk to modify the original datafile.");
- puts("\
- -r, --recover Can fix almost anything except unique keys that aren't\n\
- unique.\n\
- -o, --safe-recover Uses old recovery method; slower than '-r' but can\n\
- handle a couple of cases that '-r' cannot handle.\n\
- -O, --set-variable var=option\n\
- Change the value of a variable.\n\
- -s, --silent Only print errors. One can use two -s to make isamchk\n\
- very silent\n\
- -S, --sort-index Sort index blocks. This speeds up 'read-next' in\n\
- applications\n\
- -R, --sort-records=#\n\
- Sort records according to an index. This makes your\n\
- data much more localized and may speed up things\n\
- (It may be VERY slow to do a sort the first time!)\n\
- -u, --unpack Unpack file packed with pack_isam.\n\
- -v, --verbose Print more information. This can be used with\n\
- -d and -e. Use many -v for more verbosity!\n\
- -V, --version Print version and exit.\n\
- -w, --wait Wait if table is locked.");
- print_defaults("my",load_default_groups);
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- *changeable_vars[i].varptr);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
}
/* Check table */
@@ -512,7 +516,7 @@ static int nisamchk(my_string filename)
if (!rep_quick)
{
if (testflag & T_EXTEND)
- VOID(init_key_cache(use_buffers,(uint) NEAD_MEM));
+ VOID(init_key_cache(use_buffers));
VOID(init_io_cache(&read_cache,datafile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,
MYF(MY_WME)));
@@ -575,112 +579,94 @@ end2:
} /* nisamchk */
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+
+{
+ switch(optid) {
+ case 'a':
+ testflag|= T_STATISTICS;
+ break;
+ case 's': /* silent */
+ if (testflag & T_SILENT)
+ testflag|=T_VERY_SILENT;
+ testflag|= T_SILENT;
+ testflag&= ~T_WRITE_LOOP;
+ break;
+ case 'w':
+ testflag|= T_WAIT_FOREVER;
+ break;
+ case 'd': /* description if isam-file */
+ testflag|= T_DESCRIPT;
+ break;
+ case 'e': /* extend check */
+ testflag|= T_EXTEND;
+ break;
+ case 'i':
+ testflag|= T_INFO;
+ break;
+ case 'f':
+ tmpfile_createflag= O_RDWR | O_TRUNC;
+ testflag|=T_FORCE_CREATE;
+ break;
+ case 'l':
+ opt_follow_links=0;
+ break;
+ case 'r': /* Repair table */
+ testflag= (testflag & ~T_REP) | T_REP_BY_SORT;
+ break;
+ case 'o':
+ testflag= (testflag & ~T_REP_BY_SORT) | T_REP;
+ my_disable_async_io=1; /* More safety */
+ break;
+ case 'u':
+ testflag|= T_UNPACK | T_REP_BY_SORT;
+ break;
+ case 'v': /* Verbose */
+ testflag|= T_VERBOSE;
+ verbose++;
+ break;
+ case 'R': /* Sort records */
+ testflag|= T_SORT_RECORDS;
+ if (opt_sort_key >= N_MAXKEY)
+ {
+ fprintf(stderr,
+ "The value of the sort key is bigger than max key: %d.\n",
+ N_MAXKEY);
+ exit(1);
+ }
+ break;
+ case 'S': /* Sort index */
+ testflag|= T_SORT_INDEX;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/isamchk.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
/* Read options */
-static void get_options(register int *argc,register char ***argv)
+static void get_options(register int *argc, register char ***argv)
{
- int c,option_index=0;
+ int ho_error;
load_defaults("my",load_default_groups,argc,argv);
defaults_alloc= *argv;
- set_all_changeable_vars(changeable_vars);
if (isatty(fileno(stdout)))
testflag|=T_WRITE_LOOP;
- while ((c=getopt_long(*argc,*argv,"adeif?lqrosSuvVw#:b:k:O:R:C:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
- testflag|= T_STATISTICS;
- break;
- case 'C':
- default_charset=optarg;
- break;
- case OPT_CHARSETS_DIR_IC:
- charsets_dir = optarg;
- break;
- case 'b':
- search_after_block=strtoul(optarg,NULL,10);
- break;
- case 's': /* silent */
- if (testflag & T_SILENT)
- testflag|=T_VERY_SILENT;
- testflag|= T_SILENT;
- testflag&= ~T_WRITE_LOOP;
- break;
- case 'w':
- testflag|= T_WAIT_FOREVER;
- break;
- case 'd': /* description if isam-file */
- testflag|= T_DESCRIPT;
- break;
- case 'e': /* extend check */
- testflag|= T_EXTEND;
- break;
- case 'i':
- testflag|= T_INFO;
- break;
- case 'f':
- tmpfile_createflag= O_RDWR | O_TRUNC;
- testflag|=T_FORCE_CREATE;
- break;
- case 'k':
- max_key= (uint) atoi(optarg);
- break;
- case 'l':
- opt_follow_links=0;
- break;
- case 'r': /* Repair table */
- testflag= (testflag & ~T_REP) | T_REP_BY_SORT;
- break;
- case 'o':
- testflag= (testflag & ~T_REP_BY_SORT) | T_REP;
- my_disable_async_io=1; /* More safety */
- break;
- case 'q':
- rep_quick++;
- break;
- case 'u':
- testflag|= T_UNPACK | T_REP_BY_SORT;
- break;
- case 'v': /* Verbose */
- testflag|= T_VERBOSE;
- verbose++;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage();
- exit(1);
- }
- break;
- case 'R': /* Sort records */
- testflag|= T_SORT_RECORDS;
- opt_sort_key=(uint) atoi(optarg)-1;
- if (opt_sort_key >= N_MAXKEY)
- {
- fprintf(stderr,
- "The value of the sort key is bigger than max key: %d.\n",
- N_MAXKEY);
- exit(1);
- }
- break;
- case 'S': /* Sort index */
- testflag|= T_SORT_INDEX;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/isamchk.trace");
- break;
- case 'V':
- print_version();
- exit(0);
- case '?':
- usage();
- exit(0);
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (*argc == 0)
{
usage();
@@ -1473,7 +1459,7 @@ my_string name;
printf("Data records: %lu\n",(ulong) share->state.records);
}
- VOID(init_key_cache(use_buffers,NEAD_MEM));
+ VOID(init_key_cache(use_buffers));
if (init_io_cache(&read_cache,info->dfile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
goto err;
@@ -1950,7 +1936,7 @@ int write_info;
if (share->state.key_root[sort_key] == NI_POS_ERROR)
DBUG_RETURN(0); /* Nothing to do */
- init_key_cache(use_buffers,NEAD_MEM);
+ init_key_cache(use_buffers);
if (init_io_cache(&info->rec_cache,-1,(uint) write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
diff --git a/isam/isamdef.h b/isam/isamdef.h
index da08b5f6a14..0884b18e997 100644
--- a/isam/isamdef.h
+++ b/isam/isamdef.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/isamlog.c b/isam/isamlog.c
index 5763b697d07..0367c03e08a 100644
--- a/isam/isamlog.c
+++ b/isam/isamlog.c
@@ -327,9 +327,9 @@ static int examine_log(my_string file_name, char **table_names)
init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0));
bzero((gptr) com_count,sizeof(com_count));
- init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,1,
- (void(*)(void*)) file_info_free);
- VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
+ init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
+ (tree_element_free) file_info_free, NULL);
+ VOID(init_key_cache(KEY_CACHE_SIZE));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
@@ -400,11 +400,7 @@ static int examine_log(my_string file_name, char **table_names)
}
to=isam_file_name;
if (filepath)
- {
- strmov(isam_file_name,filepath);
- convert_dirname(isam_file_name);
- to=strend(isam_file_name);
- }
+ to=convert_dirname(isam_file_name, filepath, NullS);
strmov(to,pos);
fn_ext(isam_file_name)[0]=0; /* Remove extension */
}
diff --git a/isam/log.c b/isam/log.c
index a95b53b5110..78b56690401 100644
--- a/isam/log.c
+++ b/isam/log.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/open.c b/isam/open.c
index a3ede4512b9..48fab27cac1 100644
--- a/isam/open.c
+++ b/isam/open.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/pack_isam.c b/isam/pack_isam.c
index 5a66a9cb33c..ca2685d3278 100644
--- a/isam/pack_isam.c
+++ b/isam/pack_isam.c
@@ -30,7 +30,7 @@
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ /* Skipp warnings in getopt.h */
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#if INT_MAX > 32767
#define BITS_SAVED 32
@@ -182,8 +182,9 @@ static int mrg_rrnd(MRG_INFO *info,byte *buf);
static void mrg_reset(MRG_INFO *mrg);
-static int backup=0,error_on_write=0,test_only=0,verbose=0,silent=0,
- write_loop=0,force_pack=0,opt_wait=0,isamchk_neaded=0;
+static int error_on_write=0,test_only=0,verbose=0,silent=0,
+ write_loop=0,force_pack=0,isamchk_neaded=0;
+static my_bool backup, opt_wait;
static int tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
static uint tree_buff_length=8196-MALLOC_OVERHEAD,force_pack_ref_length;
static char tmp_dir[FN_REFLEN]={0},*join_table;
@@ -240,26 +241,44 @@ int main(int argc, char **argv)
}
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"backup", no_argument, 0, 'b'},
- {"debug", optional_argument, 0, '#'},
- {"force", no_argument, 0, 'f'},
- {"join", required_argument, 0, 'j'},
- {"help", no_argument, 0, '?'},
- {"packlength",required_argument, 0, 'p'},
- {"silent", no_argument, 0, 's'},
- {"tmpdir", required_argument, 0, 'T'},
- {"test", no_argument, 0, 't'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"backup", 'b', "Make a backup of the table as table_name.OLD",
+ (gptr*) &backup, (gptr*) &backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Force packing of table even if it's gets bigger or tempfile exists.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"join", 'j',
+ "Join all given tables into 'new_table_name'. All tables MUST have the identical layout.",
+ (gptr*) &join_table, (gptr*) &join_table, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"packlength", 'p', "Force storage size of recordlength (1, 2 or 3)",
+ (gptr*) &force_pack_ref_length, (gptr*) &force_pack_ref_length, 0,
+ GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"tmpdir", 'T', "Use temporary directory to store temporary table",
+ (gptr*) &tmp_dir, (gptr*) &tmp_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"test", 't', "Don't pack table, only test packing it",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"verbose", 'v', "Write info about progress and packing result",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"version", 'V', "output version information and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"wait", 'w', "Wait and retry if table is in use", (gptr*) &opt_wait,
+ (gptr*) &opt_wait, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void print_version(void)
{
- printf("%s Ver 5.8 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
+ printf("%s Ver 5.10 for %s on %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
static void usage(void)
@@ -275,92 +294,72 @@ static void usage(void)
puts("You should give the .ISM file as the filename argument");
printf("\nUsage: %s [OPTIONS] filename...\n", my_progname);
- puts("\n\
- -b, --backup Make a backup of the table as table_name.OLD\n\
- -f, --force Force packing of table even if it's gets bigger or\n\
- tempfile exists.\n\
- -j, --join='new_table_name'\n\
- Join all given tables into 'new_table_name'.\n\
- All tables MUST have the identical layout.\n\
- -p, --packlength=# Force storage size of recordlength (1,2 or 3)\n\
- -s, --silent Be more silent.\n\
- -t, --test Don't pack table, only test packing it\n\
- -v, --verbose Write info about progress and packing result\n\
- -w, --wait Wait and retry if table is in use\n\
- -T, --tmpdir=# Use temporary directory to store temporary table\n\
- -#, --debug=... output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help display this help and exit\n\
- -V, --version output version information and exit\n");
- print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ uint length;
+
+ switch(optid) {
+ case 'f':
+ force_pack= 1;
+ tmpfile_createflag= O_RDWR | O_TRUNC;
+ break;
+ case 'p':
+ if (force_pack_ref_length > 3)
+ force_pack_ref_length= 0;
+ break;
+ case 's':
+ write_loop= verbose= 0;
+ silent= 1;
+ break;
+ case 't':
+ test_only= verbose= 1;
+ break;
+ case 'T':
+ length=(uint) (strmov(tmp_dir, argument) - tmp_dir);
+ if (length != dirname_length(tmp_dir))
+ {
+ tmp_dir[length]= FN_LIBCHAR;
+ tmp_dir[length + 1]= 0;
+ }
+ break;
+ case 'v':
+ verbose= 1;
+ silent= 0;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case 'V': print_version(); exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
}
/* reads options */
/* Initiates DEBUG - but no debugging here ! */
-static void get_options(int *argc,char ***argv)
+static void get_options(int *argc, char ***argv)
{
- int c,option_index=0;
- uint length;
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
my_progname= argv[0][0];
if (isatty(fileno(stdout)))
write_loop=1;
- while ((c=getopt_long(*argc,*argv,"bfj:p:stvwT:#::?V",long_options,
- &option_index)) != EOF)
- {
- switch(c) {
- case 'b':
- backup=1;
- break;
- case 'f':
- force_pack=1;
- tmpfile_createflag=O_RDWR | O_TRUNC;
- break;
- case 'j':
- join_table=optarg;
- break;
- case 'p':
- force_pack_ref_length=(uint) atoi(optarg);
- if (force_pack_ref_length > 3)
- force_pack_ref_length=0;
- break;
- case 's':
- write_loop=verbose=0; silent=1;
- break;
- case 't':
- test_only=verbose=1;
- break;
- case 'T':
- length=(uint) (strmov(tmp_dir,optarg)-tmp_dir);
- if (length != dirname_length(tmp_dir))
- {
- tmp_dir[length]=FN_LIBCHAR;
- tmp_dir[length+1]=0;
- }
- break;
- case 'v':
- verbose=1; silent=0;
- break;
- case 'w':
- opt_wait=1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- default:
- fprintf(stderr,"%s: Illegal option: -%c\n",my_progname,opterr);
- usage();
- exit(1);
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
if (!*argc)
{
usage();
@@ -686,9 +685,9 @@ static HUFF_COUNTS *init_huff_count(N_INFO *info,my_off_t records)
type = FIELD_NORMAL;
if (count[i].field_length <= 8 &&
(type == FIELD_NORMAL ||
- type == FIELD_SKIPP_ZERO))
+ type == FIELD_SKIP_ZERO))
count[i].max_zero_fill= count[i].field_length;
- init_tree(&count[i].int_tree,0,-1,(qsort_cmp) compare_tree,0,NULL);
+ init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,NULL,NULL);
if (records)
count[i].tree_pos=count[i].tree_buff =
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,
@@ -790,7 +789,7 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
/* Save character counters and space-counts and zero-field-counts */
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ENDSPACE)
+ count->field_type == FIELD_SKIP_ENDSPACE)
{
for ( ; end_pos > pos ; end_pos--)
if (end_pos[-1] != ' ')
@@ -809,7 +808,7 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
count->max_end_space = length;
}
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_PRESPACE)
+ count->field_type == FIELD_SKIP_PRESPACE)
{
for (pos=start_pos; pos < end_pos ; pos++)
if (pos[0] != ' ')
@@ -829,7 +828,7 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
}
if (count->field_length <= 8 &&
(count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ZERO))
+ count->field_type == FIELD_SKIP_ZERO))
{
uint i;
if (!memcmp((byte*) start_pos,zero_string,count->field_length))
@@ -910,7 +909,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
new_length=calc_packed_length(huff_counts,0);
if (old_length < new_length && huff_counts->field_length > 1)
{
- huff_counts->field_type=FIELD_SKIPP_ZERO;
+ huff_counts->field_type=FIELD_SKIP_ZERO;
huff_counts->counts[0]-=length;
huff_counts->bytes_packed=old_length- records/8;
goto found_pack;
@@ -954,7 +953,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
huff_counts->counts[' ']+=huff_counts->tot_pre_space;
if (test_space_compress(huff_counts,records,huff_counts->max_end_space,
huff_counts->end_space,
- huff_counts->tot_end_space,FIELD_SKIPP_ENDSPACE))
+ huff_counts->tot_end_space,FIELD_SKIP_ENDSPACE))
goto found_pack;
huff_counts->counts[' ']-=huff_counts->tot_pre_space;
}
@@ -962,7 +961,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
{
if (test_space_compress(huff_counts,records,huff_counts->max_pre_space,
huff_counts->pre_space,
- huff_counts->tot_pre_space,FIELD_SKIPP_PRESPACE))
+ huff_counts->tot_pre_space,FIELD_SKIP_PRESPACE))
goto found_pack;
}
@@ -972,10 +971,10 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
if (huff_counts->max_zero_fill &&
(huff_counts->field_type == FIELD_NORMAL ||
- huff_counts->field_type == FIELD_SKIPP_ZERO))
+ huff_counts->field_type == FIELD_SKIP_ZERO))
{
huff_counts->counts[0]-=huff_counts->max_zero_fill*
- (huff_counts->field_type == FIELD_SKIPP_ZERO ?
+ (huff_counts->field_type == FIELD_SKIP_ZERO ?
records - huff_counts->zero_fields : records);
huff_counts->pack_type|=PACK_TYPE_ZERO_FILL;
huff_counts->bytes_packed=calc_packed_length(huff_counts,0);
@@ -1015,9 +1014,9 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
if (verbose)
printf("\nnormal: %3d empty-space: %3d empty-zero: %3d empty-fill: %3d\npre-space: %3d end-space: %3d table-lookup: %3d zero: %3d\n",
field_count[FIELD_NORMAL],space_fields,
- field_count[FIELD_SKIPP_ZERO],fill_zero_fields,
- field_count[FIELD_SKIPP_PRESPACE],
- field_count[FIELD_SKIPP_ENDSPACE],
+ field_count[FIELD_SKIP_ZERO],fill_zero_fields,
+ field_count[FIELD_SKIP_PRESPACE],
+ field_count[FIELD_SKIP_ENDSPACE],
field_count[FIELD_INTERVALL],
field_count[FIELD_ZERO]);
DBUG_VOID_RETURN;
@@ -1672,7 +1671,7 @@ static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
field_length-=count->max_zero_fill;
switch(count->field_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (!memcmp((byte*) start_pos,zero_string,field_length))
{
write_bits(1,1);
@@ -1686,7 +1685,7 @@ static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
write_bits(tree->code[(uchar) *start_pos],
(uint) tree->code_len[(uchar) *start_pos]);
break;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
for (pos=end_pos ; pos > start_pos && pos[-1] == ' ' ; pos--) ;
length=(uint) (end_pos-pos);
if (count->pack_type & PACK_TYPE_SELECTED)
@@ -1709,7 +1708,7 @@ static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
(uint) tree->code_len[(uchar) *start_pos]);
start_pos=end_pos;
break;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
for (pos=start_pos ; pos < end_pos && pos[0] == ' ' ; pos++) ;
length=(uint) (pos-start_pos);
if (count->pack_type & PACK_TYPE_SELECTED)
diff --git a/isam/panic.c b/isam/panic.c
index 52a5d1eb3b6..e51e83671df 100644
--- a/isam/panic.c
+++ b/isam/panic.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/range.c b/isam/range.c
index 5594991cfc3..3b79b6d93a9 100644
--- a/isam/range.c
+++ b/isam/range.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rfirst.c b/isam/rfirst.c
index 82fd3994bdf..cc1cbee92bf 100644
--- a/isam/rfirst.c
+++ b/isam/rfirst.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rkey.c b/isam/rkey.c
index 8f1f2f11ab5..bbe4576418b 100644
--- a/isam/rkey.c
+++ b/isam/rkey.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rlast.c b/isam/rlast.c
index df2b1bc39af..a91f1f1011b 100644
--- a/isam/rlast.c
+++ b/isam/rlast.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rnext.c b/isam/rnext.c
index 451624bb42b..be26098c901 100644
--- a/isam/rnext.c
+++ b/isam/rnext.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rprev.c b/isam/rprev.c
index 50f22c838fd..0997a04fbbe 100644
--- a/isam/rprev.c
+++ b/isam/rprev.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rrnd.c b/isam/rrnd.c
index 7fd197a6d58..16b3ab1b859 100644
--- a/isam/rrnd.c
+++ b/isam/rrnd.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rsame.c b/isam/rsame.c
index fe617cf258c..9a2a03da054 100644
--- a/isam/rsame.c
+++ b/isam/rsame.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rsamepos.c b/isam/rsamepos.c
index 500dfc60e38..c64ac492d1a 100644
--- a/isam/rsamepos.c
+++ b/isam/rsamepos.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/sort.c b/isam/sort.c
index 72c4c7564f8..d22b0e648a0 100644
--- a/isam/sort.c
+++ b/isam/sort.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/static.c b/isam/static.c
index 941c4defea2..9c68a0cfdba 100644
--- a/isam/static.c
+++ b/isam/static.c
@@ -1,21 +1,21 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
- Static variables for pisam library. All definied here for easy making of
+ Static variables for ISAM library. All definied here for easy making of
a shared library
*/
diff --git a/isam/test1.c b/isam/test1.c
index 33c61a53d4a..9ebc7af041d 100644
--- a/isam/test1.c
+++ b/isam/test1.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,7 +19,7 @@
static void get_options(int argc, char *argv[]);
static int rec_pointer_size=0,verbose=0,remove_ant=0,pack_keys=1,flags[50],
- packed_field=FIELD_SKIPP_PRESPACE;
+ packed_field=FIELD_SKIP_PRESPACE;
int main(int argc, char *argv[])
{
diff --git a/isam/test2.c b/isam/test2.c
index def6a4d3d5c..c8f97ccdefa 100644
--- a/isam/test2.c
+++ b/isam/test2.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -115,17 +115,17 @@ int main(int argc, char *argv[])
keyinfo[5].seg[1].base.type=0;
keyinfo[5].base.flag = (uint8) (pack_type ? HA_PACK_KEY : 0);
- recinfo[0].base.type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[0].base.type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[0].base.length=7;
- recinfo[1].base.type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[1].base.type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[1].base.length=5;
- recinfo[2].base.type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[2].base.type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[2].base.length=9;
recinfo[3].base.type=FIELD_NORMAL;
recinfo[3].base.length=STANDAR_LENGTH-7-5-9-4;
- recinfo[4].base.type=pack_fields ? FIELD_SKIPP_ZERO : 0;
+ recinfo[4].base.type=pack_fields ? FIELD_SKIP_ZERO : 0;
recinfo[4].base.length=4;
- recinfo[5].base.type=pack_fields ? FIELD_SKIPP_ENDSPACE : 0;
+ recinfo[5].base.type=pack_fields ? FIELD_SKIP_ENDSPACE : 0;
recinfo[5].base.length=60;
if (use_blob)
{
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
goto err;
printf("- Writing key:s\n");
if (key_cacheing)
- init_key_cache(IO_SIZE*16,(uint) IO_SIZE*4*10); /* Use a small cache */
+ init_key_cache(IO_SIZE*16); /* Use a small cache */
if (locking)
nisam_lock_database(file,F_WRLCK);
if (write_cacheing)
diff --git a/isam/test3.c b/isam/test3.c
index 935c194106d..7027c56d0f6 100644
--- a/isam/test3.c
+++ b/isam/test3.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -171,8 +171,8 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
- init_key_cache(65536L,(uint) IO_SIZE*4*10);
- printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
+ init_key_cache(65536L);
+ printf("Process %d, pid: %d\n",id,(int) getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
{
@@ -356,7 +356,7 @@ int test_write(N_INFO *file,int id,int lock_type)
nisam_extra(file,HA_EXTRA_WRITE_CACHE);
}
- sprintf(record.id,"%7d",getpid());
+ sprintf(record.id,"%7d",(int) getpid());
strmov(record.text,"Testing...");
tries=(uint) rnd(100)+10;
diff --git a/isam/update.c b/isam/update.c
index 82dab4140e3..b3b676f967d 100644
--- a/isam/update.c
+++ b/isam/update.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/write.c b/isam/write.c
index 49b0916afc4..f2c0d8dbc45 100644
--- a/isam/write.c
+++ b/isam/write.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -262,7 +262,7 @@ int _nisam_insert(register N_INFO *info, register N_KEYDEF *keyinfo,
/* This may happen if a key was deleted and the next key could be
compressed better than before */
DBUG_DUMP("anc_buff",(byte*) anc_buff,a_length);
-
+
bmove(key_pos,key_pos - (int) t_length,(uint)key_offset);
}
_nisam_store_key(keyinfo,key_pos,&s_temp);
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index 68c2022223e..3d380c14076 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -17,11 +17,11 @@
# This file is public domain and comes with NO WARRANTY of any kind
-target = libmysqlclient.la
-target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@
-LIBS = @CLIENT_LIBS@
+target = libmysqlclient.la
+target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT
+LIBS = @CLIENT_LIBS@
INCLUDES = -I$(srcdir)/../include -I../include \
- -I$(srcdir)/.. -I$(top_srcdir) -I..
+ -I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
include $(srcdir)/Makefile.shared
@@ -36,14 +36,23 @@ link_sources:
ss=`echo $(mystringsobjects) | sed "s;\.lo;.c;g"`; \
ds=`echo $(dbugobjects) | sed "s;\.lo;.c;g"`; \
ms=`echo $(mysysobjects) | sed "s;\.lo;.c;g"`; \
+ vs=`echo $(vio_objects) | sed "s;\.lo;.c;g"`; \
for f in $$ss; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
done; \
+ for f in $$vs; do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../vio/$$f $(srcdir)/$$f; \
+ done; \
for f in $(mystringsextra); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
done; \
+ for f in $$qs; do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
+ done; \
for f in $$ds; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../dbug/$$f $(srcdir)/$$f; \
@@ -51,7 +60,9 @@ link_sources:
for f in $$ms $(mysysheaders); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../mysys/$$f $(srcdir)/$$f; \
- done;
+ done; \
+ rm -f $(srcdir)/net.c; \
+ @LN_CP_F@ $(srcdir)/../sql/net_serv.cc $(srcdir)/net.c
# This part requires GNUmake
#
@@ -62,13 +73,13 @@ link_sources:
# keep only the stubs for safemalloc.c and debug.c
#
# A list of needed headers collected from the deps information 000213
-nh = global.h config-win32.h dbug.h errmsg.h global.h \
+nh = my_global.h config-win32.h dbug.h errmsg.h \
m_ctype.h m_string.h \
my_alarm.h my_config.h my_dir.h my_list.h my_net.h my_sys.h \
- mysql.h mysql_com.h mysql_version.h mysqld_error.h mysys_err.h \
- my_pthread.h thr_alarm.h violite.h hash.h
+ mysql.h mysql_com.h mysql_version.h mysqld_error.h \
+ mysys_err.h my_pthread.h thr_alarm.h violite.h hash.h
# Get a list of the needed objects
-lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects)
+lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects) $(sqlobjects)
do-lib-dist:
dir=libmysql-$(MYSQL_NO_DASH_VERSION); \
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 76d37c149c9..87f9fe42a3c 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -31,13 +31,14 @@ noinst_PROGRAMS = conf_to_src
CHARSET_OBJS=@CHARSET_OBJS@
LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo}
-target_sources = libmysql.c net.c violite.c password.c \
- get_password.c errmsg.c
+target_sources = libmysql.c password.c manager.c \
+ get_password.c errmsg.c
-mystringsobjects = strmov.lo strxmov.lo strnmov.lo strmake.lo strend.lo \
+mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
+ strmake.lo strend.lo \
strnlen.lo strfill.lo is_prefix.lo \
int2str.lo str2int.lo strinstr.lo strcont.lo \
- strcend.lo \
+ strcend.lo bcmp.lo \
bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \
strtoull.lo strtoll.lo llstr.lo \
ctype.lo $(LTCHARSET_OBJS)
@@ -55,13 +56,19 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
mf_loadpath.lo my_pthread.lo my_thr_init.lo \
thr_mutex.lo mulalloc.lo string.lo default.lo \
my_compress.lo array.lo my_once.lo list.lo my_net.lo \
- charset.lo hash.lo mf_iocache.lo my_seek.lo \
- my_pread.lo mf_cache.lo my_gethostbyname.lo
+ charset.lo hash.lo mf_iocache.lo \
+ mf_iocache2.lo my_seek.lo \
+ my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo \
+ my_getopt.lo my_gethostbyname.lo
+sqlobjects = net.lo
+
# Not needed in the minimum library
-mysysobjects2 = getopt.lo getopt1.lo getvar.lo my_lib.lo
+mysysobjects2 = my_lib.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
-target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects)
+target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
+ $(vio_objects) $(sqlobjects)
target_ldflags = -version-info @SHARED_LIB_VERSION@
+vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
$(target)
DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
@@ -76,8 +83,9 @@ clean-local:
rm -f `echo $(mystringsobjects) | sed "s;\.lo;.c;g"` \
`echo $(dbugobjects) | sed "s;\.lo;.c;g"` \
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
+ `echo $(vio_objects) | sed "s;\.lo;.c;g"` \
$(mystringsextra) $(mysysheaders) ctype_extra_sources.c \
- ../linked_client_sources
+ net.c ../linked_client_sources
ctype_extra_sources.c: conf_to_src
./conf_to_src $(top_srcdir) @CHARSETS_NEED_SOURCE@ > \
diff --git a/libmysql/conf_to_src.c b/libmysql/conf_to_src.c
index 76316638153..95ffcf1cb2b 100644
--- a/libmysql/conf_to_src.c
+++ b/libmysql/conf_to_src.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* can't use -lmysys because this prog is used to create -lstrings */
diff --git a/libmysql/dll.c b/libmysql/dll.c
index d1a23794025..f0a67d8f091 100644
--- a/libmysql/dll.c
+++ b/libmysql/dll.c
@@ -1,25 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Handling initialization of the dll library
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <my_pthread.h>
diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c
index 67cfe874f77..3fdb9c0ddc6 100644
--- a/libmysql/errmsg.c
+++ b/libmysql/errmsg.c
@@ -1,24 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Error messages for MySQL clients */
-/* error messages for the demon is in share/language/errmsg.sys */
+/* error messages for the daemon is in share/language/errmsg.sys */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "errmsg.h"
@@ -45,7 +44,12 @@ const char *client_errors[]=
"Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
"Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
"Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
+ "Got packet bigger than 'max_allowed_packet'",
+ "Embedded server",
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:"
};
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
@@ -73,7 +77,12 @@ const char *client_errors[]=
"Não pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
- "Obteve pacote maior do que 'max_allowed_packet'"
+ "Obteve pacote maior do que 'max_allowed_packet'",
+ "Embedded server"
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:"
};
#else /* ENGLISH */
@@ -99,7 +108,12 @@ const char *client_errors[]=
"Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
+ "Got packet bigger than 'max_allowed_packet'",
+ "Embedded server",
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:"
};
#endif
diff --git a/libmysql/get_password.c b/libmysql/get_password.c
index 989de9dd11a..124c315a821 100644
--- a/libmysql/get_password.c
+++ b/libmysql/get_password.c
@@ -1,25 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Ask for a password from tty
** This is an own file to avoid conflicts with curses
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "mysql.h"
#include <m_string.h>
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index bab6d304094..458e5db24d5 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,21 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#include <global.h>
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
#if defined(__WIN__) || defined(_WIN32) || defined(_WIN64)
#include <winsock.h>
#include <odbcinst.h>
@@ -60,6 +59,10 @@
static my_bool mysql_client_init=0;
uint mysql_port=0;
my_string mysql_unix_port=0;
+ulong net_buffer_length=8192;
+ulong max_allowed_packet=16*1024*1024L;
+ulong net_read_timeout= NET_READ_TIMEOUT;
+ulong net_write_timeout= NET_WRITE_TIMEOUT;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
@@ -70,7 +73,7 @@ my_string mysql_unix_port=0;
#endif
#if defined(MSDOS) || defined(__WIN__)
-// socket_errno is defined in global.h for all platforms
+// socket_errno is defined in my_global.h for all platforms
#define perror(A)
#else
#include <errno.h>
@@ -91,6 +94,38 @@ static sig_handler pipe_sig_handler(int sig);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length);
+static my_bool org_my_init_done=0;
+
+int STDCALL mysql_server_init(int argc __attribute__((unused)),
+ char **argv __attribute__((unused)),
+ char **groups __attribute__((unused)))
+{
+ return 0;
+}
+
+void STDCALL mysql_server_end()
+{
+ /* If library called my_init(), free memory allocated by it */
+ if (!org_my_init_done)
+ my_end(0);
+}
+
+my_bool STDCALL mysql_thread_init()
+{
+#ifdef THREAD
+ return my_thread_init();
+#else
+ return 0;
+#endif
+}
+
+void STDCALL mysql_thread_end()
+{
+#ifdef THREAD
+ my_thread_end();
+#endif
+}
+
/*
Let the user specify that we don't want SIGPIPE; This doesn't however work
with threaded applications as we can have multiple read in progress.
@@ -106,17 +141,23 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
#define reset_sigpipe(mysql)
#endif
+static MYSQL* spawn_init(MYSQL* parent, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd);
+
+
/****************************************************************************
-* A modified version of connect(). connect2() allows you to specify
-* a timeout value, in seconds, that we should wait until we
-* derermine we can't connect to a particular host. If timeout is 0,
-* connect2() will behave exactly like connect().
-*
-* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
+ A modified version of connect(). connect2() allows you to specify
+ a timeout value, in seconds, that we should wait until we
+ derermine we can't connect to a particular host. If timeout is 0,
+ my_connect() will behave exactly like connect().
+
+ Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
-static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
- uint timeout)
+int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
+ uint timeout)
{
#if defined(__WIN__) || defined(OS2)
return connect(s, (struct sockaddr*) name, namelen);
@@ -212,7 +253,7 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
}
/*
-** Create a named pipe connection
+ Create a named pipe connection
*/
#ifdef __WIN__
@@ -285,15 +326,15 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
/*****************************************************************************
-** read a packet from server. Give error message if socket was down
-** or packet is an error message
+ read a packet from server. Give error message if socket was down
+ or packet is an error message
*****************************************************************************/
-uint
+ulong
net_safe_read(MYSQL *mysql)
{
NET *net= &mysql->net;
- uint len=0;
+ ulong len=0;
init_sigpipe_variables
/* Don't give sigpipe errors if the client doesn't want them */
@@ -311,26 +352,18 @@ net_safe_read(MYSQL *mysql)
CR_NET_PACKET_TOO_LARGE:
CR_SERVER_LOST);
strmov(net->last_error,ER(net->last_errno));
- return(packet_error);
+ return (packet_error);
}
if (net->read_pos[0] == 255)
{
if (len > 3)
{
char *pos=(char*) net->read_pos+1;
- if (mysql->protocol_version > 9)
- { /* New client protocol */
- net->last_errno=uint2korr(pos);
- pos+=2;
- len-=2;
- }
- else
- {
- net->last_errno=CR_UNKNOWN_ERROR;
- len--;
- }
+ net->last_errno=uint2korr(pos);
+ pos+=2;
+ len-=2;
(void) strmake(net->last_error,(char*) pos,
- min(len,sizeof(net->last_error)-1));
+ min((uint) len,(uint) sizeof(net->last_error)-1));
}
else
{
@@ -421,7 +454,7 @@ static void free_rows(MYSQL_DATA *cur)
int
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
- uint length, my_bool skipp_check)
+ ulong length, my_bool skipp_check)
{
NET *net= &mysql->net;
int result= -1;
@@ -540,7 +573,7 @@ static my_bool is_NT(void)
#endif
/*
-** Expand wildcard to a sql string
+ Expand wildcard to a sql string
*/
static void
@@ -566,7 +599,7 @@ append_wild(char *to, char *end, const char *wild)
/**************************************************************************
-** Init debugging if MYSQL_DEBUG environment variable is found
+ Init debugging if MYSQL_DEBUG environment variable is found
**************************************************************************/
void STDCALL
@@ -603,7 +636,7 @@ mysql_debug(const char *debug __attribute__((unused)))
/**************************************************************************
-** Close the server connection if we get a SIGPIPE
+ Close the server connection if we get a SIGPIPE
ARGSUSED
**************************************************************************/
@@ -618,7 +651,7 @@ pipe_sig_handler(int sig __attribute__((unused)))
/**************************************************************************
-** Shut down connection
+ Shut down connection
**************************************************************************/
static void
@@ -652,8 +685,8 @@ mysql_free_result(MYSQL_RES *result)
DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows"));
for (;;)
{
- uint pkt_len;
- if ((pkt_len=(uint) net_safe_read(result->handle)) == packet_error)
+ ulong pkt_len;
+ if ((pkt_len=net_safe_read(result->handle)) == packet_error)
break;
if (pkt_len == 1 && result->handle->net.read_pos[0] == 254)
break; /* End of data */
@@ -672,7 +705,7 @@ mysql_free_result(MYSQL_RES *result)
/****************************************************************************
-** Get options from my.cnf
+ Get options from my.cnf
****************************************************************************/
static const char *default_options[]=
@@ -682,6 +715,8 @@ static const char *default_options[]=
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
"character-sets-dir", "default-character-set", "interactive-timeout",
"connect-timeout", "local-infile", "disable-local-infile",
+ "replication-probe", "enable-reads-from-master", "repl-parse-query",
+ "ssl-cipher",
NullS
};
@@ -826,6 +861,15 @@ static void mysql_read_default_options(struct st_mysql_options *options,
break;
case 22:
options->client_flag&= CLIENT_LOCAL_FILES;
+ break;
+ case 23: /* replication probe */
+ options->rpl_probe= 1;
+ break;
+ case 24: /* enable-reads-from-master */
+ options->no_master_reads= 0;
+ break;
+ case 25: /* repl-parse-query */
+ options->rpl_parse= 1;
break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
@@ -839,7 +883,7 @@ static void mysql_read_default_options(struct st_mysql_options *options,
/***************************************************************************
-** Change field rows to field structs
+ Change field rows to field structs
***************************************************************************/
static MYSQL_FIELD *
@@ -850,13 +894,14 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
MYSQL_FIELD *field,*result;
DBUG_ENTER("unpack_fields");
- field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields);
+ field=result=(MYSQL_FIELD*) alloc_root(alloc,
+ (uint) sizeof(MYSQL_FIELD)*fields);
if (!result)
DBUG_RETURN(0);
for (row=data->data; row ; row = row->next,field++)
{
- field->table= strdup_root(alloc,(char*) row->data[0]);
+ field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
field->name= strdup_root(alloc,(char*) row->data[1]);
field->length= (uint) uint3korr(row->data[2]);
field->type= (enum enum_field_types) (uchar) row->data[3][0];
@@ -888,7 +933,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
uint fields)
{
- uint field,pkt_len;
+ uint field;
+ ulong pkt_len;
ulong len;
uchar *cp;
char *to;
@@ -897,7 +943,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
NET *net = &mysql->net;
DBUG_ENTER("read_rows");
- if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error)
+ if ((pkt_len= net_safe_read(mysql)) == packet_error)
DBUG_RETURN(0);
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
@@ -962,8 +1008,8 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
/*
-** Read one row. Uses packet buffer as storage for fields.
-** When next packet is read, the previous field values are destroyed
+ Read one row. Uses packet buffer as storage for fields.
+ When next packet is read, the previous field values are destroyed
*/
@@ -974,7 +1020,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
ulong pkt_len,len;
uchar *pos,*prev_pos;
- if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error)
+ if ((pkt_len=net_safe_read(mysql)) == packet_error)
return -1;
if (pkt_len == 1 && mysql->net.read_pos[0] == 254)
return 1; /* End of data */
@@ -1002,8 +1048,290 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
return 0;
}
+/* perform query on master */
+int STDCALL mysql_master_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ if (mysql_master_send_query(mysql, q, length))
+ return 1;
+ return mysql_read_query_result(mysql);
+}
+
+int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ MYSQL*master = mysql->master;
+ if (!length)
+ length = strlen(q);
+ if (!master->net.vio && !mysql_real_connect(master,0,0,0,0,0,0,0))
+ return 1;
+ mysql->last_used_con = master;
+ return simple_command(master, COM_QUERY, q, length, 1);
+}
+
+
+/* perform query on slave */
+int STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ if (mysql_slave_send_query(mysql, q, length))
+ return 1;
+ return mysql_read_query_result(mysql);
+}
+
+int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ MYSQL* last_used_slave, *slave_to_use = 0;
+
+ if ((last_used_slave = mysql->last_used_slave))
+ slave_to_use = last_used_slave->next_slave;
+ else
+ slave_to_use = mysql->next_slave;
+ /* next_slave is always safe to use - we have a circular list of slaves
+ if there are no slaves, mysql->next_slave == mysql
+ */
+ mysql->last_used_con = mysql->last_used_slave = slave_to_use;
+ if (!length)
+ length = strlen(q);
+ if (!slave_to_use->net.vio && !mysql_real_connect(slave_to_use, 0,0,0,
+ 0,0,0,0))
+ return 1;
+ return simple_command(slave_to_use, COM_QUERY, q, length, 1);
+}
+
+
+/* enable/disable parsing of all queries to decide
+ if they go on master or slave */
+void STDCALL mysql_enable_rpl_parse(MYSQL* mysql)
+{
+ mysql->options.rpl_parse = 1;
+}
+
+void STDCALL mysql_disable_rpl_parse(MYSQL* mysql)
+{
+ mysql->options.rpl_parse = 0;
+}
+
+/* get the value of the parse flag */
+int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql)
+{
+ return mysql->options.rpl_parse;
+}
+
+/* enable/disable reads from master */
+void STDCALL mysql_enable_reads_from_master(MYSQL* mysql)
+{
+ mysql->options.no_master_reads = 0;
+}
+
+void STDCALL mysql_disable_reads_from_master(MYSQL* mysql)
+{
+ mysql->options.no_master_reads = 1;
+}
+
+/* get the value of the master read flag */
+int STDCALL mysql_reads_from_master_enabled(MYSQL* mysql)
+{
+ return !(mysql->options.no_master_reads);
+}
+
+/* We may get an error while doing replication internals.
+ In this case, we add a special explanation to the original
+ error
+*/
+static inline void expand_error(MYSQL* mysql, int error)
+{
+ char tmp[MYSQL_ERRMSG_SIZE];
+ char* p, *tmp_end;
+ tmp_end = strnmov(tmp, mysql->net.last_error, MYSQL_ERRMSG_SIZE);
+ p = strnmov(mysql->net.last_error, ER(error), MYSQL_ERRMSG_SIZE);
+ memcpy(p, tmp, tmp_end - tmp);
+ mysql->net.last_errno = error;
+}
+
+/*
+ This function assumes we have just called SHOW SLAVE STATUS and have
+ read the given result and row
+*/
+
+static inline int get_master(MYSQL* mysql, MYSQL_RES* res, MYSQL_ROW row)
+{
+ MYSQL* master;
+ if (mysql_num_fields(res) < 3)
+ return 1; /* safety */
+
+ /* use the same username and password as the original connection */
+ if (!(master = spawn_init(mysql, row[0], atoi(row[2]), 0, 0)))
+ return 1;
+ mysql->master = master;
+ return 0;
+}
+
+
+/*
+ Assuming we already know that mysql points to a master connection,
+ retrieve all the slaves
+*/
+
+static inline int get_slaves_from_master(MYSQL* mysql)
+{
+ MYSQL_RES* res = 0;
+ MYSQL_ROW row;
+ int error = 1;
+ int has_auth_info;
+ int port_ind;
+
+ if (!mysql->net.vio && !mysql_real_connect(mysql,0,0,0,0,0,0,0))
+ {
+ expand_error(mysql, CR_PROBE_MASTER_CONNECT);
+ return 1;
+ }
+
+ if (mysql_query(mysql, "SHOW SLAVE HOSTS") ||
+ !(res = mysql_store_result(mysql)))
+ {
+ expand_error(mysql, CR_PROBE_SLAVE_HOSTS);
+ return 1;
+ }
+
+ switch (mysql_num_fields(res)) {
+ case 5:
+ has_auth_info = 0;
+ port_ind=2;
+ break;
+ case 7:
+ has_auth_info = 1;
+ port_ind=4;
+ break;
+ default:
+ goto err;
+ }
+
+ while ((row = mysql_fetch_row(res)))
+ {
+ MYSQL* slave;
+ const char* tmp_user, *tmp_pass;
+
+ if (has_auth_info)
+ {
+ tmp_user = row[2];
+ tmp_pass = row[3];
+ }
+ else
+ {
+ tmp_user = mysql->user;
+ tmp_pass = mysql->passwd;
+ }
+
+ if (!(slave = spawn_init(mysql, row[1], atoi(row[port_ind]),
+ tmp_user, tmp_pass)))
+ goto err;
+
+ /* Now add slave into the circular linked list */
+ slave->next_slave = mysql->next_slave;
+ mysql->next_slave = slave;
+ }
+ error = 0;
+err:
+ if (res)
+ mysql_free_result(res);
+ return error;
+}
+
+int STDCALL mysql_rpl_probe(MYSQL* mysql)
+{
+ MYSQL_RES* res = 0;
+ MYSQL_ROW row;
+ int error = 1;
+ /*
+ First determine the replication role of the server we connected to
+ the most reliable way to do this is to run SHOW SLAVE STATUS and see
+ if we have a non-empty master host. This is still not fool-proof -
+ it is not a sin to have a master that has a dormant slave thread with
+ a non-empty master host. However, it is more reliable to check
+ for empty master than whether the slave thread is actually running
+ */
+ if (mysql_query(mysql, "SHOW SLAVE STATUS") ||
+ !(res = mysql_store_result(mysql)))
+ {
+ expand_error(mysql, CR_PROBE_SLAVE_STATUS);
+ return 1;
+ }
+
+ if (!(row = mysql_fetch_row(res)))
+ goto err;
+
+ /* check master host for emptiness/NULL */
+ if (row[0] && *(row[0]))
+ {
+ /* this is a slave, ask it for the master */
+ if (get_master(mysql, res, row) || get_slaves_from_master(mysql))
+ goto err;
+ }
+ else
+ {
+ mysql->master = mysql;
+ if (get_slaves_from_master(mysql))
+ goto err;
+ }
+
+ error = 0;
+err:
+ if (res)
+ mysql_free_result(res);
+ return error;
+}
+
+
+/*
+ Make a not so fool-proof decision on where the query should go, to
+ the master or the slave. Ideally the user should always make this
+ decision himself with mysql_master_query() or mysql_slave_query().
+ However, to be able to more easily port the old code, we support the
+ option of an educated guess - this should work for most applications,
+ however, it may make the wrong decision in some particular cases. If
+ that happens, the user would have to change the code to call
+ mysql_master_query() or mysql_slave_query() explicitly in the place
+ where we have made the wrong decision
+*/
+
+enum mysql_rpl_type
+STDCALL mysql_rpl_query_type(const char* q, int len)
+{
+ const char* q_end;
+ q_end = (len) ? q + len : strend(q);
+ for (; q < q_end; ++q)
+ {
+ char c;
+ if (isalpha(c=*q))
+ {
+ switch(tolower(c)) {
+ case 'i': /* insert */
+ case 'u': /* update or unlock tables */
+ case 'l': /* lock tables or load data infile */
+ case 'd': /* drop or delete */
+ case 'a': /* alter */
+ return MYSQL_RPL_MASTER;
+ case 'c': /* create or check */
+ return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_MASTER ;
+ case 's': /* select or show */
+ return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_SLAVE;
+ case 'f': /* flush */
+ case 'r': /* repair */
+ case 'g': /* grant */
+ return MYSQL_RPL_ADMIN;
+ default:
+ return MYSQL_RPL_SLAVE;
+ }
+ }
+ }
+ return MYSQL_RPL_MASTER; /* By default, send to master */
+}
+
+
/****************************************************************************
-** Init MySQL structure or allocate one
+ Init MySQL structure or allocate one
****************************************************************************/
MYSQL * STDCALL
@@ -1020,6 +1348,13 @@ mysql_init(MYSQL *mysql)
else
bzero((char*) (mysql),sizeof(*(mysql)));
mysql->options.connect_timeout=CONNECT_TIMEOUT;
+ mysql->last_used_con = mysql->next_slave = mysql->master = mysql;
+ mysql->last_used_slave = 0;
+ /*
+ By default, we are a replication pivot. The caller must reset it
+ after we return if this is not the case.
+ */
+ mysql->rpl_pivot = 1;
#if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__)
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
(void) signal(SIGPIPE,pipe_sig_handler);
@@ -1041,6 +1376,7 @@ static void mysql_once_init()
if (!mysql_client_init)
{
mysql_client_init=1;
+ org_my_init_done=my_init_done;
my_init(); /* Will init threads */
init_client_errs();
if (!mysql_port)
@@ -1079,63 +1415,70 @@ static void mysql_once_init()
#endif
}
-#ifdef HAVE_OPENSSL
/**************************************************************************
-** Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
-** NB! Errors are not reported until you do mysql_real_connect.
+ Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
+ NB! Errors are not reported until you do mysql_real_connect.
**************************************************************************/
-int STDCALL
-mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert,
- const char *ca, const char *capath)
-{
- mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0));
- mysql->options.ssl_cert = cert==0 ? 0 : my_strdup(cert,MYF(0));
- mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,MYF(0));
- mysql->options.ssl_capath = capath==0 ? 0 : my_strdup(capath,MYF(0));
- mysql->options.use_ssl = true;
- mysql->connector_fd = new_VioSSLConnectorFd(key, cert, ca, capath);
- return 0;
-}
-
-/**************************************************************************
-**************************************************************************/
+#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
-char * STDCALL
-mysql_ssl_cipher(MYSQL *mysql)
+int STDCALL
+mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
+ const char *key __attribute__((unused)),
+ const char *cert __attribute__((unused)),
+ const char *ca __attribute__((unused)),
+ const char *capath __attribute__((unused)),
+ const char *cipher __attribute__((unused)))
{
- return (char *)mysql->net.vio->cipher_description();
+#ifdef HAVE_OPENSSL
+ mysql->options.ssl_key= strdup_if_not_null(key);
+ mysql->options.ssl_cert= strdup_if_not_null(cert);
+ mysql->options.ssl_ca= strdup_if_not_null(ca);
+ mysql->options.ssl_capath= strdup_if_not_null(capath);
+ mysql->options.ssl_cipher= strdup_if_not_null(cipher);
+ mysql->options.use_ssl= TRUE;
+ mysql->connector_fd = (gptr) new_VioSSLConnectorFd(key, cert, ca, capath,
+ cipher);
+ DBUG_PRINT("info",("mysql_ssl_set, context: %p",
+ ((struct st_VioSSLConnectorFd *) (mysql->connector_fd))->
+ ssl_context_));
+#endif
+ return 0;
}
/**************************************************************************
-** Free strings in the SSL structure and clear 'use_ssl' flag.
-** NB! Errors are not reported until you do mysql_real_connect.
+ Free strings in the SSL structure and clear 'use_ssl' flag.
+ NB! Errors are not reported until you do mysql_real_connect.
**************************************************************************/
-int STDCALL
-mysql_ssl_clear(MYSQL *mysql)
+static int
+mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
{
+#ifdef HAVE_OPENSSL
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.ssl_key = 0;
mysql->options.ssl_cert = 0;
mysql->options.ssl_ca = 0;
mysql->options.ssl_capath = 0;
- mysql->options.use_ssl = false;
- mysql->connector_fd->delete();
+ mysql->options.ssl_cipher= 0;
+ mysql->options.use_ssl = FALSE;
mysql->connector_fd = 0;
+#endif /* HAVE_OPENSSL */
return 0;
}
-#endif /* HAVE_OPENSSL */
/**************************************************************************
-** Connect to sql server
-** If host == 0 then use localhost
+ Connect to sql server
+ If host == 0 then use localhost
**************************************************************************/
+#ifdef USE_OLD_FUNCTIONS
MYSQL * STDCALL
mysql_connect(MYSQL *mysql,const char *host,
const char *user, const char *passwd)
@@ -1152,11 +1495,12 @@ mysql_connect(MYSQL *mysql,const char *host,
DBUG_RETURN(res);
}
}
+#endif
/*
-** Note that the mysql argument must be initialized with mysql_init()
-** before calling mysql_real_connect !
+ Note that the mysql argument must be initialized with mysql_init()
+ before calling mysql_real_connect !
*/
MYSQL * STDCALL
@@ -1169,7 +1513,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
my_socket sock;
uint32 ip_addr;
struct sockaddr_in sock_addr;
- uint pkt_length;
+ ulong pkt_length;
NET *net= &mysql->net;
#ifdef __WIN__
HANDLE hPipe=INVALID_HANDLE_VALUE;
@@ -1245,7 +1589,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
bzero((char*) &UNIXaddr,sizeof(UNIXaddr));
UNIXaddr.sun_family = AF_UNIX;
strmov(UNIXaddr.sun_path, unix_socket);
- if (connect2(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
+ if (my_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
mysql->options.connect_timeout) <0)
{
DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno));
@@ -1334,7 +1678,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
my_gethostbyname_r_free();
}
sock_addr.sin_port = (ushort) htons((ushort) port);
- if (connect2(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
+ if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
mysql->options.connect_timeout) <0)
{
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,host));
@@ -1372,8 +1716,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_DUMP("packet",(char*) net->read_pos,10);
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
PROTOCOL_VERSION, mysql->protocol_version));
- if (mysql->protocol_version != PROTOCOL_VERSION &&
- mysql->protocol_version != PROTOCOL_VERSION-1)
+ if (mysql->protocol_version != PROTOCOL_VERSION)
{
net->last_errno= CR_VERSION_ERROR;
sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version,
@@ -1409,7 +1752,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
charset_name=charset_name_buff;
sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */
if (!(mysql->charset =
- get_charset((uint8) mysql->server_language, MYF(MY_WME))))
+ get_charset((uint8) mysql->server_language, MYF(0))))
mysql->charset = default_charset_info; /* shouldn't be fatal */
}
@@ -1499,19 +1842,19 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag=client_flag;
#ifdef HAVE_OPENSSL
- /* Oops.. are we careful enough to not send ANY information */
- /* without encryption? */
+ /*
+ Oops.. are we careful enough to not send ANY information without
+ encryption?
+ */
if (client_flag & CLIENT_SSL)
{
if (my_net_write(net,buff,(uint) (2)) || net_flush(net))
goto error;
/* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress..."));
- VioSSLConnectorFd* connector_fd = (VioSSLConnectorFd*)
- (mysql->connector_fd);
- VioSocket* vio_socket = (VioSocket*)(mysql->net.vio);
- VioSSL* vio_ssl = connector_fd->connect(vio_socket);
- mysql->net.vio = (NetVio*)(vio_ssl);
+ DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_));
+ sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio, (long)(mysql->options.connect_timeout));
+ DBUG_PRINT("info", ("IO layer change done!"));
}
#endif /* HAVE_OPENSSL */
@@ -1536,7 +1879,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->db=my_strdup(db,MYF(MY_WME));
db=0;
}
- if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net) ||
+ if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net) ||
net_safe_read(mysql) == packet_error)
goto error;
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
@@ -1553,6 +1896,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->reconnect=reconnect;
}
+ if (mysql->options.rpl_probe && mysql_rpl_probe(mysql))
+ goto error;
+
DBUG_PRINT("exit",("Mysql handler: %lx",mysql));
reset_sigpipe(mysql);
DBUG_RETURN(mysql);
@@ -1572,6 +1918,26 @@ error:
}
+/* needed when we move MYSQL structure to a different address */
+
+static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql)
+{
+ MYSQL *tmp, *tmp_prev;
+ if (mysql->master == old_mysql)
+ mysql->master = mysql;
+ if (mysql->last_used_con == old_mysql)
+ mysql->last_used_con = mysql;
+ if (mysql->last_used_slave == old_mysql)
+ mysql->last_used_slave = mysql;
+ for (tmp_prev = mysql, tmp = mysql->next_slave;
+ tmp != old_mysql;tmp = tmp->next_slave)
+ {
+ tmp_prev = tmp;
+ }
+ tmp_prev->next_slave = mysql;
+}
+
+
static my_bool mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
@@ -1580,13 +1946,14 @@ static my_bool mysql_reconnect(MYSQL *mysql)
if (!mysql->reconnect ||
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
{
- /* Allov reconnect next time */
+ /* Allow reconnect next time */
mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
DBUG_RETURN(1);
}
mysql_init(&tmp_mysql);
tmp_mysql.options=mysql->options;
bzero((char*) &mysql->options,sizeof(mysql->options));
+ tmp_mysql.rpl_pivot = mysql->rpl_pivot;
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
mysql->db, mysql->port, mysql->unix_socket,
mysql->client_flag))
@@ -1595,6 +1962,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
mysql->free_me=0;
mysql_close(mysql);
*mysql=tmp_mysql;
+ mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */
net_clear(&mysql->net);
mysql->affected_rows= ~(my_ulonglong) 0;
DBUG_RETURN(0);
@@ -1602,7 +1970,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
/**************************************************************************
-** Change user and database
+ Change user and database
**************************************************************************/
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
@@ -1620,7 +1988,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
pos=scramble(pos, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9));
pos=strmov(pos+1,db ? db : "");
- if (simple_command(mysql,COM_CHANGE_USER, buff,(uint) (pos-buff),0))
+ if (simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (pos-buff),0))
DBUG_RETURN(1);
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
@@ -1635,7 +2003,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
/**************************************************************************
-** Set current database
+ Set current database
**************************************************************************/
int STDCALL
@@ -1645,7 +2013,7 @@ mysql_select_db(MYSQL *mysql, const char *db)
DBUG_ENTER("mysql_select_db");
DBUG_PRINT("enter",("db: '%s'",db));
- if ((error=simple_command(mysql,COM_INIT_DB,db,(uint) strlen(db),0)))
+ if ((error=simple_command(mysql,COM_INIT_DB,db,(ulong) strlen(db),0)))
DBUG_RETURN(error);
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
mysql->db=my_strdup(db,MYF(MY_WME));
@@ -1654,8 +2022,8 @@ mysql_select_db(MYSQL *mysql, const char *db)
/*************************************************************************
-** Send a QUIT to the server and close the connection
-** If handle is alloced by mysql connect free it.
+ Send a QUIT to the server and close the connection
+ If handle is alloced by mysql connect free it.
*************************************************************************/
void STDCALL
@@ -1686,14 +2054,29 @@ mysql_close(MYSQL *mysql)
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
+#ifdef HAVE_OPENSSL
+ mysql_ssl_free(mysql);
+#endif /* HAVE_OPENSSL */
/* Clear pointers for better safety */
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
bzero((char*) &mysql->options,sizeof(mysql->options));
mysql->net.vio = 0;
-#ifdef HAVE_OPENSSL
- ((VioConnectorFd*)(mysql->connector_fd))->delete();
- mysql->connector_fd = 0;
-#endif /* HAVE_OPENSSL */
+
+ /* free/close slave list */
+ if (mysql->rpl_pivot)
+ {
+ MYSQL* tmp;
+ for (tmp = mysql->next_slave; tmp != mysql; )
+ {
+ /* trick to avoid following freed pointer */
+ MYSQL* tmp1 = tmp->next_slave;
+ mysql_close(tmp);
+ tmp = tmp1;
+ }
+ mysql->rpl_pivot=0;
+ }
+ if (mysql != mysql->master)
+ mysql_close(mysql->master);
if (mysql->free_me)
my_free((gptr) mysql,MYF(0));
}
@@ -1702,8 +2085,8 @@ mysql_close(MYSQL *mysql)
/**************************************************************************
-** Do a query. If query returned rows, free old rows.
-** Read data by mysql_store_result or by repeat call of mysql_fetch_row
+ Do a query. If query returned rows, free old rows.
+ Read data by mysql_store_result or by repeat call of mysql_fetch_row
**************************************************************************/
int STDCALL
@@ -1712,6 +2095,68 @@ mysql_query(MYSQL *mysql, const char *query)
return mysql_real_query(mysql,query, (uint) strlen(query));
}
+
+static MYSQL* spawn_init(MYSQL* parent, const char* host,
+ unsigned int port, const char* user,
+ const char* passwd)
+{
+ MYSQL* child;
+ if (!(child = mysql_init(0)))
+ return 0;
+
+ child->options.user = my_strdup((user) ? user :
+ (parent->user ? parent->user :
+ parent->options.user), MYF(0));
+ child->options.password = my_strdup((passwd) ? passwd :
+ (parent->passwd ?
+ parent->passwd :
+ parent->options.password), MYF(0));
+ child->options.port = port;
+ child->options.host = my_strdup((host) ? host :
+ (parent->host ?
+ parent->host :
+ parent->options.host), MYF(0));
+ if (parent->db)
+ child->options.db = my_strdup(parent->db, MYF(0));
+ else if (parent->options.db)
+ child->options.db = my_strdup(parent->options.db, MYF(0));
+
+ child->options.rpl_parse = child->options.rpl_probe = child->rpl_pivot = 0;
+
+ return child;
+}
+
+
+int
+STDCALL mysql_set_master(MYSQL* mysql, const char* host,
+ unsigned int port, const char* user,
+ const char* passwd)
+{
+ if (mysql->master != mysql && !mysql->master->rpl_pivot)
+ mysql_close(mysql->master);
+ if (!(mysql->master = spawn_init(mysql, host, port, user, passwd)))
+ return 1;
+ mysql->master->rpl_pivot = 0;
+ mysql->master->options.rpl_parse = 0;
+ mysql->master->options.rpl_probe = 0;
+ return 0;
+}
+
+int
+STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd)
+{
+ MYSQL* slave;
+ if (!(slave = spawn_init(mysql, host, port, user, passwd)))
+ return 1;
+ slave->next_slave = mysql->next_slave;
+ mysql->next_slave = slave;
+ return 0;
+}
+
+
/*
Send the query and return so we can do something else.
Needs to be followed by mysql_read_query_result() when we want to
@@ -1719,19 +2164,38 @@ mysql_query(MYSQL *mysql, const char *query)
*/
int STDCALL
-mysql_send_query(MYSQL* mysql, const char* query, uint length)
+mysql_send_query(MYSQL* mysql, const char* query, ulong length)
{
+ if (mysql->options.rpl_parse && mysql->rpl_pivot)
+ {
+ switch (mysql_rpl_query_type(query, length)) {
+ case MYSQL_RPL_MASTER:
+ return mysql_master_send_query(mysql, query, length);
+ case MYSQL_RPL_SLAVE:
+ return mysql_slave_send_query(mysql, query, length);
+ case MYSQL_RPL_ADMIN:
+ break; /* fall through */
+ }
+ }
+
+ mysql->last_used_con = mysql;
return simple_command(mysql, COM_QUERY, query, length, 1);
}
+
int STDCALL mysql_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
MYSQL_DATA *fields;
- uint length;
+ ulong length;
DBUG_ENTER("mysql_read_query_result");
+ /* read from the connection which we actually used, which
+ could differ from the original connection if we have slaves
+ */
+ mysql = mysql->last_used_con;
+
if ((length = net_safe_read(mysql)) == packet_error)
DBUG_RETURN(-1);
free_old_query(mysql); /* Free old result */
@@ -1768,80 +2232,86 @@ get_info:
CLIENT_LONG_FLAG))))
DBUG_RETURN(-1);
mysql->status=MYSQL_STATUS_GET_RESULT;
- mysql->field_count=field_count;
+ mysql->field_count= (uint) field_count;
DBUG_RETURN(0);
}
+
int STDCALL
-mysql_real_query(MYSQL *mysql, const char *query, uint length)
+mysql_real_query(MYSQL *mysql, const char *query, ulong length)
{
DBUG_ENTER("mysql_real_query");
DBUG_PRINT("enter",("handle: %lx",mysql));
DBUG_PRINT("query",("Query = \"%s\"",query));
- if (simple_command(mysql,COM_QUERY,query,length,1))
+
+ if (mysql_send_query(mysql,query,length))
DBUG_RETURN(-1);
DBUG_RETURN(mysql_read_query_result(mysql));
}
+
static int
send_file_to_server(MYSQL *mysql, const char *filename)
{
- int fd, readcount;
- char buf[IO_SIZE*15],*tmp_name;
+ int fd, readcount, result= -1;
+ uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
+ char *buf, tmp_name[FN_REFLEN];
DBUG_ENTER("send_file_to_server");
- fn_format(buf,filename,"","",4); /* Convert to client format */
- if (!(tmp_name=my_strdup(buf,MYF(0))))
+ if (!(buf=my_malloc(packet_length,MYF(0))))
{
strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY));
DBUG_RETURN(-1);
}
+
+ fn_format(tmp_name,filename,"","",4); /* Convert to client format */
if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0)
{
+ my_net_write(&mysql->net,"",0); /* Server needs one packet */
+ net_flush(&mysql->net);
mysql->net.last_errno=EE_FILENOTFOUND;
- sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
- strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
- my_net_write(&mysql->net,"",0); net_flush(&mysql->net);
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ EE(mysql->net.last_errno),tmp_name, errno);
+ goto err;
}
- while ((readcount = (int) my_read(fd,buf,sizeof(buf),MYF(0))) > 0)
+ while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0)
{
if (my_net_write(&mysql->net,buf,readcount))
{
+ DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
mysql->net.last_errno=CR_SERVER_LOST;
strmov(mysql->net.last_error,ER(mysql->net.last_errno));
- DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
- (void) my_close(fd,MYF(0));
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ goto err;
}
}
- (void) my_close(fd,MYF(0));
/* Send empty packet to mark end of file */
if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net))
{
mysql->net.last_errno=CR_SERVER_LOST;
- sprintf(mysql->net.last_error,ER(mysql->net.last_errno),socket_errno);
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno);
+ goto err;
}
if (readcount < 0)
{
mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */
- sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
- strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ tmp_name,errno);
+ goto err;
}
- DBUG_RETURN(0);
+ result=0; /* Ok */
+
+err:
+ if (fd >= 0)
+ (void) my_close(fd,MYF(0));
+ my_free(buf,MYF(0));
+ DBUG_RETURN(result);
}
/**************************************************************************
-** Alloc result struct for buffered results. All rows are read to buffer.
-** mysql_data_seek may be used.
+ Alloc result struct for buffered results. All rows are read to buffer.
+ mysql_data_seek may be used.
**************************************************************************/
MYSQL_RES * STDCALL
@@ -1850,6 +2320,9 @@ mysql_store_result(MYSQL *mysql)
MYSQL_RES *result;
DBUG_ENTER("mysql_store_result");
+ /* read from the actually used connection */
+ mysql = mysql->last_used_con;
+
if (!mysql->fields)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
@@ -1859,8 +2332,9 @@ mysql_store_result(MYSQL *mysql)
DBUG_RETURN(0);
}
mysql->status=MYSQL_STATUS_READY; /* server is ready */
- if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
- sizeof(ulong)*mysql->field_count,
+ if (!(result=(MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+
+ sizeof(ulong) *
+ mysql->field_count),
MYF(MY_WME | MY_ZEROFILL))))
{
mysql->net.last_errno=CR_OUT_OF_MEMORY;
@@ -1887,13 +2361,13 @@ mysql_store_result(MYSQL *mysql)
/**************************************************************************
-** Alloc struct for use with unbuffered reads. Data is fetched by domand
-** when calling to mysql_fetch_row.
-** mysql_data_seek is a noop.
-**
-** No other queries may be specified with the same MYSQL handle.
-** There shouldn't be much processing per row because mysql server shouldn't
-** have to wait for the client (and will not wait more than 30 sec/packet).
+ Alloc struct for use with unbuffered reads. Data is fetched by domand
+ when calling to mysql_fetch_row.
+ mysql_data_seek is a noop.
+
+ No other queries may be specified with the same MYSQL handle.
+ There shouldn't be much processing per row because mysql server shouldn't
+ have to wait for the client (and will not wait more than 30 sec/packet).
**************************************************************************/
MYSQL_RES * STDCALL
@@ -1902,6 +2376,8 @@ mysql_use_result(MYSQL *mysql)
MYSQL_RES *result;
DBUG_ENTER("mysql_use_result");
+ mysql = mysql->last_used_con;
+
if (!mysql->fields)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
@@ -1935,7 +2411,7 @@ mysql_use_result(MYSQL *mysql)
/**************************************************************************
-** Return next field of the query results
+ Return next field of the query results
**************************************************************************/
MYSQL_FIELD * STDCALL
@@ -1948,7 +2424,7 @@ mysql_fetch_field(MYSQL_RES *result)
/**************************************************************************
-** Return next row of the query results
+ Return next row of the query results
**************************************************************************/
MYSQL_ROW STDCALL
@@ -1989,9 +2465,9 @@ mysql_fetch_row(MYSQL_RES *res)
}
/**************************************************************************
-** Get column lengths of the current row
-** If one uses mysql_use_result, res->lengths contains the length information,
-** else the lengths are calculated from the offset between pointers.
+ Get column lengths of the current row
+ If one uses mysql_use_result, res->lengths contains the length information,
+ else the lengths are calculated from the offset between pointers.
**************************************************************************/
ulong * STDCALL
@@ -2016,7 +2492,7 @@ mysql_fetch_lengths(MYSQL_RES *res)
continue;
}
if (start) /* Found end of prev string */
- *prev_length= (uint) (*column-start-1);
+ *prev_length= (ulong) (*column-start-1);
start= *column;
prev_length=lengths;
}
@@ -2025,7 +2501,7 @@ mysql_fetch_lengths(MYSQL_RES *res)
}
/**************************************************************************
-** Move to a specific row and column
+ Move to a specific row and column
**************************************************************************/
void STDCALL
@@ -2040,9 +2516,9 @@ mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
}
/*************************************************************************
-** put the row or field cursor one a position one got from mysql_row_tell()
-** This doesn't restore any data. The next mysql_fetch_row or
-** mysql_fetch_field will return the next row or field after the last used
+ put the row or field cursor one a position one got from mysql_row_tell()
+ This doesn't restore any data. The next mysql_fetch_row or
+ mysql_fetch_field will return the next row or field after the last used
*************************************************************************/
MYSQL_ROW_OFFSET STDCALL
@@ -2064,7 +2540,7 @@ mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset)
}
/*****************************************************************************
-** List all databases
+ List all databases
*****************************************************************************/
MYSQL_RES * STDCALL
@@ -2081,8 +2557,8 @@ mysql_list_dbs(MYSQL *mysql, const char *wild)
/*****************************************************************************
-** List all tables in a database
-** If wild is given then only the tables matching wild is returned
+ List all tables in a database
+ If wild is given then only the tables matching wild is returned
*****************************************************************************/
MYSQL_RES * STDCALL
@@ -2099,10 +2575,10 @@ mysql_list_tables(MYSQL *mysql, const char *wild)
/**************************************************************************
-** List all fields in a table
-** If wild is given then only the fields matching wild is returned
-** Instead of this use query:
-** show fields in 'table' like "wild"
+ List all fields in a table
+ If wild is given then only the fields matching wild is returned
+ Instead of this use query:
+ show fields in 'table' like "wild"
**************************************************************************/
MYSQL_RES * STDCALL
@@ -2117,7 +2593,7 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
LINT_INIT(query);
end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
- if (simple_command(mysql,COM_FIELD_LIST,buff,(uint) (end-buff),1) ||
+ if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) ||
!(query = read_rows(mysql,(MYSQL_FIELD*) 0,6)))
DBUG_RETURN(NULL);
@@ -2167,12 +2643,13 @@ mysql_list_processes(MYSQL *mysql)
}
+#ifdef USE_OLD_FUNCTIONS
int STDCALL
mysql_create_db(MYSQL *mysql, const char *db)
{
DBUG_ENTER("mysql_createdb");
DBUG_PRINT("enter",("db: %s",db));
- DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (uint) strlen(db),0));
+ DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (ulong) strlen(db),0));
}
@@ -2181,8 +2658,9 @@ mysql_drop_db(MYSQL *mysql, const char *db)
{
DBUG_ENTER("mysql_drop_db");
DBUG_PRINT("enter",("db: %s",db));
- DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(uint) strlen(db),0));
+ DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(ulong) strlen(db),0));
}
+#endif
int STDCALL
@@ -2219,7 +2697,7 @@ mysql_dump_debug_info(MYSQL *mysql)
DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
}
-char * STDCALL
+const char * STDCALL
mysql_stat(MYSQL *mysql)
{
DBUG_ENTER("mysql_stat");
@@ -2244,14 +2722,14 @@ mysql_ping(MYSQL *mysql)
}
-char * STDCALL
+const char * STDCALL
mysql_get_server_info(MYSQL *mysql)
{
return((char*) mysql->server_version);
}
-char * STDCALL
+const char * STDCALL
mysql_get_host_info(MYSQL *mysql)
{
return(mysql->host_info);
@@ -2264,7 +2742,7 @@ mysql_get_proto_info(MYSQL *mysql)
return (mysql->protocol_version);
}
-char * STDCALL
+const char * STDCALL
mysql_get_client_info(void)
{
return (char*) MYSQL_SERVER_VERSION;
@@ -2319,8 +2797,8 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
}
/****************************************************************************
-** Functions to get information from the MySQL structure
-** These are functions to make shared libraries more usable.
+ Functions to get information from the MySQL structure
+ These are functions to make shared libraries more usable.
****************************************************************************/
/* MYSQL_RES */
@@ -2349,12 +2827,12 @@ MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res)
return (res)->fields;
}
-MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res)
+MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res)
{
return res->data_cursor;
}
-uint STDCALL mysql_field_tell(MYSQL_RES *res)
+MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res)
{
return (res)->current_field;
}
@@ -2363,32 +2841,32 @@ uint STDCALL mysql_field_tell(MYSQL_RES *res)
unsigned int STDCALL mysql_field_count(MYSQL *mysql)
{
- return mysql->field_count;
+ return mysql->last_used_con->field_count;
}
my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
{
- return (mysql)->affected_rows;
+ return mysql->last_used_con->affected_rows;
}
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
{
- return (mysql)->insert_id;
+ return mysql->last_used_con->insert_id;
}
uint STDCALL mysql_errno(MYSQL *mysql)
{
- return (mysql)->net.last_errno;
+ return mysql->net.last_errno;
}
-char * STDCALL mysql_error(MYSQL *mysql)
+const char * STDCALL mysql_error(MYSQL *mysql)
{
- return (mysql)->net.last_error;
+ return mysql->net.last_error;
}
-char *STDCALL mysql_info(MYSQL *mysql)
+const char *STDCALL mysql_info(MYSQL *mysql)
{
- return (mysql)->info;
+ return mysql->info;
}
ulong STDCALL mysql_thread_id(MYSQL *mysql)
@@ -2412,13 +2890,25 @@ uint STDCALL mysql_thread_safe(void)
}
/****************************************************************************
-** Some support functions
+ Some support functions
****************************************************************************/
/*
-** Add escape characters to a string (blob?) to make it suitable for a insert
-** to should at least have place for length*2+1 chars
-** Returns the length of the to string
+ Functions called my my_net_init() to set some application specific variables
+*/
+
+void my_net_local_init(NET *net)
+{
+ net->max_packet= (uint) net_buffer_length;
+ net->read_timeout= (uint) net_read_timeout;
+ net->write_timeout=(uint) net_write_timeout;
+ net->max_packet_size= max(net_buffer_length, max_allowed_packet);
+}
+
+/*
+ Add escape characters to a string (blob?) to make it suitable for a insert
+ to should at least have place for length*2+1 chars
+ Returns the length of the to string
*/
ulong STDCALL
diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def
new file mode 100644
index 00000000000..988f2b09195
--- /dev/null
+++ b/libmysql/libmysql.def
@@ -0,0 +1,122 @@
+LIBRARY LIBMYSQL
+DESCRIPTION 'MySQL 4.0 Client Library'
+VERSION 4.0
+EXPORTS
+ mysql_affected_rows
+ mysql_close
+ mysql_connect
+ mysql_create_db
+ mysql_data_seek
+ mysql_debug
+ mysql_drop_db
+ mysql_dump_debug_info
+ mysql_eof
+ mysql_errno
+ mysql_error
+ mysql_escape_string
+ mysql_fetch_field
+ mysql_fetch_field_direct
+ mysql_fetch_fields
+ mysql_fetch_lengths
+ mysql_fetch_row
+ mysql_field_count
+ mysql_field_seek
+ mysql_field_tell
+ mysql_free_result
+ mysql_get_client_info
+ mysql_get_host_info
+ mysql_get_proto_info
+ mysql_get_server_info
+ mysql_info
+ mysql_init
+ mysql_insert_id
+ mysql_kill
+ 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_query
+ mysql_refresh
+ mysql_row_seek
+ mysql_row_tell
+ mysql_select_db
+ 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_read_query_result
+ mysql_real_escape_string
+ mysql_ssl_set
+ mysql_ssl_clear
+ mysql_real_connect
+ mysql_master_query
+ mysql_master_send_query
+ mysql_slave_query
+ mysql_slave_send_query
+ mysql_enable_rpl_parse
+ mysql_disable_rpl_parse
+ mysql_rpl_parse_enabled
+ mysql_enable_reads_from_master
+ mysql_disable_reads_from_master
+ mysql_reads_from_master_enabled
+ mysql_rpl_query_type
+ mysql_rpl_probe
+ mysql_set_master
+ mysql_add_slave
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libmysql/manager.c b/libmysql/manager.c
new file mode 100644
index 00000000000..a38c7fe1cd7
--- /dev/null
+++ b/libmysql/manager.c
@@ -0,0 +1,263 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#if defined(THREAD)
+#include <my_pthread.h> /* because of signal() */
+#endif
+#include "mysql.h"
+#include "mysql_version.h"
+#include "mysqld_error.h"
+#include <my_sys.h>
+#include <mysys_err.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include <my_net.h>
+#include <errmsg.h>
+#include <violite.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <errno.h>
+
+#if defined(OS2)
+# include <sys/un.h>
+#elif !defined( __WIN__)
+#include <sys/resource.h>
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+#include <netdb.h>
+#ifdef HAVE_SELECT_H
+# include <select.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <sys/utsname.h>
+#endif /* __WIN__ */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
+
+#define RES_BUF_SHIFT 5
+#define NET_BUF_SIZE 2048
+
+MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con)
+{
+ int net_buf_size=NET_BUF_SIZE;
+ if (!con)
+ {
+ if (!(con=(MYSQL_MANAGER*)my_malloc(sizeof(*con)+net_buf_size,
+ MYF(MY_WME|MY_ZEROFILL))))
+ return 0;
+ con->free_me=1;
+ con->net_buf=(char*)con+sizeof(*con);
+ }
+ else
+ {
+ bzero((char*)con,sizeof(*con));
+ if (!(con->net_buf=my_malloc(net_buf_size,MYF(0))))
+ return 0;
+ }
+ con->net_buf_pos=con->net_data_end=con->net_buf;
+ con->net_buf_size=net_buf_size;
+ return con;
+}
+
+MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
+ const char* host,
+ const char* user,
+ const char* passwd,
+ unsigned int port)
+{
+ my_socket sock;
+ struct sockaddr_in sock_addr;
+ uint32 ip_addr;
+ char msg_buf[MAX_MYSQL_MANAGER_MSG];
+ int msg_len;
+ Vio* vio;
+
+ if (!host)
+ host="localhost";
+ if (!user)
+ user="root";
+ if (!passwd)
+ passwd="";
+
+ if ((sock=(my_socket)socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Cannot create socket");
+ goto err;
+ }
+ if (!(vio=vio_new(sock,VIO_TYPE_TCPIP,FALSE)))
+ {
+ con->last_errno=ENOMEM;
+ strmov(con->last_error,"Cannot create network I/O object");
+ goto err;
+ }
+ vio_blocking(vio,TRUE);
+ my_net_init(&con->net,vio);
+ bzero((char*) &sock_addr,sizeof(sock_addr));
+ sock_addr.sin_family = AF_INET;
+ if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE)
+ {
+ memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr));
+ }
+ else
+ {
+ int tmp_errno;
+ struct hostent tmp_hostent,*hp;
+ char buff2[GETHOSTBYNAME_BUFF_SIZE];
+ hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2),
+ &tmp_errno);
+ if (!hp)
+ {
+ con->last_errno=tmp_errno;
+ sprintf(con->last_error,"Could not resolve host '%s'",host);
+ my_gethostbyname_r_free();
+ goto err;
+ }
+ memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length);
+ my_gethostbyname_r_free();
+ }
+ sock_addr.sin_port = (ushort) htons((ushort) port);
+ if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
+ 0) <0)
+ {
+ con->last_errno=errno;
+ sprintf(con->last_error ,"Could not connect to %-.64s", host);
+ goto err;
+ }
+ /* read the greating */
+ if (my_net_read(&con->net) == packet_error)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Read error on socket");
+ goto err;
+ }
+ sprintf(msg_buf,"%-.16s %-.16s\n",user,passwd);
+ msg_len=strlen(msg_buf);
+ if (my_net_write(&con->net,msg_buf,msg_len) || net_flush(&con->net))
+ {
+ con->last_errno=con->net.last_errno;
+ strmov(con->last_error,"Write error on socket");
+ goto err;
+ }
+ if (my_net_read(&con->net) == packet_error)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Read error on socket");
+ goto err;
+ }
+ if ((con->cmd_status=atoi((char*) con->net.read_pos)) != MANAGER_OK)
+ {
+ strmov(con->last_error,"Access denied");
+ goto err;
+ }
+ if (!my_multi_malloc(MYF(0), &con->host, (uint)strlen(host)+1,
+ &con->user, (uint)strlen(user)+1,
+ &con->passwd, (uint)strlen(passwd)+1,
+ NullS))
+ {
+ con->last_errno=ENOMEM;
+ strmov(con->last_error,"Out of memory");
+ goto err;
+ }
+ strmov(con->host,host);
+ strmov(con->user,user);
+ strmov(con->passwd,passwd);
+ return con;
+
+err:
+ {
+ my_bool free_me=con->free_me;
+ con->free_me=0;
+ mysql_manager_close(con);
+ con->free_me=free_me;
+ }
+ return 0;
+}
+
+void STDCALL mysql_manager_close(MYSQL_MANAGER* con)
+{
+ /*
+ No need to free con->user and con->passwd, because they were
+ allocated in my_multimalloc() along with con->host, freeing
+ con->hosts frees the whole block
+ */
+ my_free((gptr)con->host,MYF(MY_ALLOW_ZERO_PTR));
+ net_end(&con->net);
+ if (con->free_me)
+ my_free((gptr)con,MYF(0));
+}
+
+
+int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd,
+ int cmd_len)
+{
+ if (!cmd_len)
+ cmd_len=strlen(cmd);
+ if (my_net_write(&con->net,(char*)cmd,cmd_len) || net_flush(&con->net))
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Write error on socket");
+ return 1;
+ }
+ con->eof=0;
+ return 0;
+}
+
+
+int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf,
+ int res_buf_size)
+{
+ char* res_buf_end=res_buf+res_buf_size;
+ char* net_buf=(char*) con->net.read_pos, *net_buf_end;
+ int res_buf_shift=RES_BUF_SHIFT;
+ uint num_bytes;
+
+ if (res_buf_size<RES_BUF_SHIFT)
+ {
+ con->last_errno=ENOMEM;
+ strmov(con->last_error,"Result buffer too small");
+ return 1;
+ }
+
+ if ((num_bytes=my_net_read(&con->net)) == packet_error)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"socket read failed");
+ return 1;
+ }
+
+ net_buf_end=net_buf+num_bytes;
+
+ if ((con->eof=(net_buf[3]==' ')))
+ res_buf_shift--;
+ net_buf+=res_buf_shift;
+ res_buf_end[-1]=0;
+ for (;net_buf<net_buf_end && res_buf < res_buf_end;res_buf++,net_buf++)
+ {
+ if ((*res_buf=*net_buf) == '\r')
+ {
+ *res_buf=0;
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/libmysql/net.c b/libmysql/net.c
deleted file mode 100644
index 24e4da3561a..00000000000
--- a/libmysql/net.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Write and read of logical packets to/from socket
-** Writes are cached into net_buffer_length big packets.
-** Read packets are reallocated dynamicly when reading big packets.
-** Each logical packet has the following pre-info:
-** 3 byte length & 1 byte package-number.
-*/
-
-#ifdef __WIN__
-#include <winsock.h>
-#endif
-#include <global.h>
-#include <violite.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include "mysql.h"
-#include "mysqld_error.h"
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <violite.h>
-
-#ifdef MYSQL_SERVER
-ulong max_allowed_packet=65536;
-extern ulong net_read_timeout,net_write_timeout;
-extern uint test_flags;
-#else
-ulong max_allowed_packet=16*1024*1024L;
-ulong net_read_timeout= NET_READ_TIMEOUT;
-ulong net_write_timeout= NET_WRITE_TIMEOUT;
-#endif
-ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
-
-#if !defined(__WIN__) && !defined(MSDOS)
-#include <sys/socket.h>
-#else
-#undef MYSQL_SERVER /* Win32 can't handle interrupts */
-#endif
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__)
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
-#endif
-#endif
-#include "mysqld_error.h"
-#ifdef MYSQL_SERVER
-#include "my_pthread.h"
-#include "thr_alarm.h"
-void sql_print_error(const char *format,...);
-#define RETRY_COUNT mysqld_net_retry_count
-extern ulong mysqld_net_retry_count;
-#else
-
-#ifdef OS2 /* avoid name conflict */
-#define thr_alarm_t thr_alarm_t_net
-#define ALARM ALARM_net
-#endif
-
-typedef my_bool thr_alarm_t;
-typedef my_bool ALARM;
-#define thr_alarm_init(A) (*(A))=0
-#define thr_alarm_in_use(A) (*(A)!= 0)
-#define thr_end_alarm(A)
-#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
-inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
-{
- *A=1;
- return 0;
-}
-#define thr_got_alarm(A) 0
-#define RETRY_COUNT 1
-#endif
-
-#ifdef MYSQL_SERVER
-extern ulong bytes_sent, bytes_received;
-extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
-#else
-#undef statistic_add
-#define statistic_add(A,B,C)
-#endif
-
-/*
-** Give error if a too big packet is found
-** The server can change this with the -O switch, but because the client
-** can't normally do this the client should have a bigger max-buffer.
-*/
-
-#define TEST_BLOCKING 8
-static int net_write_buff(NET *net,const char *packet,uint len);
-
-
- /* Init with packet info */
-
-int my_net_init(NET *net, Vio* vio)
-{
- if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME))))
- return 1;
- if (net_buffer_length > max_allowed_packet)
- max_allowed_packet=net_buffer_length;
- net->buff_end=net->buff+(net->max_packet=net_buffer_length);
- net->vio = vio;
- net->no_send_ok = 0;
- net->error=0; net->return_errno=0; net->return_status=0;
- net->timeout=(uint) net_read_timeout; /* Timeout for read */
- net->pkt_nr=0;
- net->write_pos=net->read_pos = net->buff;
- net->last_error[0]=0;
- net->compress=0; net->reading_or_writing=0;
- net->where_b = net->remain_in_buf=0;
- net->last_errno=0;
-
- if (vio != 0) /* If real connection */
- {
- net->fd = vio_fd(vio); /* For perl DBI/DBD */
-#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
- if (!(test_flags & TEST_BLOCKING))
- vio_blocking(vio, FALSE);
-#endif
- vio_fastsend(vio);
- }
- return 0;
-}
-
-void net_end(NET *net)
-{
- my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR));
- net->buff=0;
-}
-
-/* Realloc the packet buffer */
-
-static my_bool net_realloc(NET *net, ulong length)
-{
- uchar *buff;
- ulong pkt_length;
- if (length >= max_allowed_packet)
- {
- DBUG_PRINT("error",("Packet too large (%lu)", length));
- net->error=1;
- net->last_errno=ER_NET_PACKET_TOO_LARGE;
- return 1;
- }
- pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
- if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME))))
- {
- net->error=1;
-#ifdef MYSQL_SERVER
- net->last_errno=ER_OUT_OF_RESOURCES;
-#endif
- return 1;
- }
- net->buff=net->write_pos=buff;
- net->buff_end=buff+(net->max_packet=pkt_length);
- return 0;
-}
-
- /* Remove unwanted characters from connection */
-
-void net_clear(NET *net)
-{
-#ifndef EXTRA_DEBUG
- int count;
- bool is_blocking=vio_is_blocking(net->vio);
- if (is_blocking)
- vio_blocking(net->vio, FALSE);
- if (!vio_is_blocking(net->vio)) /* Safety if SSL */
- {
- while ( (count = vio_read(net->vio, (char*) (net->buff),
- net->max_packet)) > 0)
- DBUG_PRINT("info",("skipped %d bytes from file: %s",
- count,vio_description(net->vio)));
- if (is_blocking)
- vio_blocking(net->vio, TRUE);
- }
-#endif /* EXTRA_DEBUG */
- net->pkt_nr=0; /* Ready for new command */
- net->write_pos=net->buff;
-}
-
- /* Flush write_buffer if not empty. */
-
-int net_flush(NET *net)
-{
- int error=0;
- DBUG_ENTER("net_flush");
- if (net->buff != net->write_pos)
- {
- error=net_real_write(net,(char*) net->buff,
- (uint) (net->write_pos - net->buff));
- net->write_pos=net->buff;
- }
- DBUG_RETURN(error);
-}
-
-
-/*****************************************************************************
-** Write something to server/client buffer
-*****************************************************************************/
-
-
-/*
-** Write a logical packet with packet header
-** Format: Packet length (3 bytes), packet number(1 byte)
-** When compression is used a 3 byte compression length is added
-** NOTE: If compression is used the original package is destroyed!
-*/
-
-int
-my_net_write(NET *net,const char *packet,ulong len)
-{
- uchar buff[NET_HEADER_SIZE];
- int3store(buff,len);
- buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
- if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
- return 1;
- return net_write_buff(net,packet,len);
-}
-
-int
-net_write_command(NET *net,uchar command,const char *packet,ulong len)
-{
- uchar buff[NET_HEADER_SIZE+1];
- uint length=len+1; /* 1 extra byte for command */
-
- int3store(buff,length);
- buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
- buff[4]=command;
- if (net_write_buff(net,(char*) buff,5))
- return 1;
- return test(net_write_buff(net,packet,len) || net_flush(net));
-}
-
-
-static int
-net_write_buff(NET *net,const char *packet,uint len)
-{
- uint left_length=(uint) (net->buff_end - net->write_pos);
-
- while (len > left_length)
- {
- memcpy((char*) net->write_pos,packet,left_length);
- if (net_real_write(net,(char*) net->buff,net->max_packet))
- return 1;
- net->write_pos=net->buff;
- packet+=left_length;
- len-=left_length;
- left_length=net->max_packet;
- }
- memcpy((char*) net->write_pos,packet,len);
- net->write_pos+=len;
- return 0;
-}
-
-/* Read and write using timeouts */
-
-int
-net_real_write(NET *net,const char *packet,ulong len)
-{
- int length;
- char *pos,*end;
- thr_alarm_t alarmed;
-#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
- ALARM alarm_buff;
-#endif
- uint retry_count=0;
- my_bool net_blocking = vio_is_blocking(net->vio);
- DBUG_ENTER("net_real_write");
-
- if (net->error == 2)
- DBUG_RETURN(-1); /* socket can't be used */
-
- net->reading_or_writing=2;
-#ifdef HAVE_COMPRESS
- if (net->compress)
- {
- ulong complen;
- uchar *b;
- uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
- if (!(b=(uchar*) my_malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE,
- MYF(MY_WME))))
- {
-#ifdef MYSQL_SERVER
- net->last_errno=ER_OUT_OF_RESOURCES;
- net->error=2;
-#endif
- net->reading_or_writing=0;
- DBUG_RETURN(1);
- }
- memcpy(b+header_length,packet,len);
-
- if (my_compress((byte*) b+header_length,&len,&complen))
- {
- DBUG_PRINT("warning",
- ("Compression error; Continuing without compression"));
- complen=0;
- }
- int3store(&b[NET_HEADER_SIZE],complen);
- int3store(b,len);
- b[3]=(uchar) (net->pkt_nr++);
- len+= header_length;
- packet= (char*) b;
- }
-#endif /* HAVE_COMPRESS */
-
- /* DBUG_DUMP("net",packet,len); */
-#ifdef MYSQL_SERVER
- thr_alarm_init(&alarmed);
- if (net_blocking)
- thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
-#else
- alarmed=0;
-#endif /* MYSQL_SERVER */
-
- pos=(char*) packet; end=pos+len;
- while (pos != end)
- {
- if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0)
- {
- my_bool interrupted = vio_should_retry(net->vio);
-#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2))
- if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
- { /* Always true for client */
- if (!vio_is_blocking(net->vio))
- {
- while (vio_blocking(net->vio, TRUE) < 0)
- {
- if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT)
- continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr,
- "%s: my_net_write: fcntl returned error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
- net->error=2; /* Close socket */
- goto end;
- }
- }
- retry_count=0;
- continue;
- }
- }
- else
-#endif /* (!defined(__WIN__) && !defined(__EMX__)) */
- if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
- interrupted)
- {
- if (retry_count++ < RETRY_COUNT)
- continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr, "%s: write looped, aborting thread\n",
- my_progname);
-#endif /* EXTRA_DEBUG */
- }
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
- if (vio_errno(net->vio) == SOCKET_EINTR)
- {
- DBUG_PRINT("warning",("Interrupted write. Retrying..."));
- continue;
- }
-#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
- net->error=2; /* Close socket */
-#ifdef MYSQL_SERVER
- net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
- ER_NET_ERROR_ON_WRITE);
-#endif /* MYSQL_SERVER */
- break;
- }
- pos+=length;
- statistic_add(bytes_sent,length,&LOCK_bytes_sent);
- }
-#ifndef __WIN__
- end:
-#endif
-#ifdef HAVE_COMPRESS
- if (net->compress)
- my_free((char*) packet,MYF(0));
-#endif
- if (thr_alarm_in_use(&alarmed))
- {
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
- }
- net->reading_or_writing=0;
- DBUG_RETURN(((int) (pos != end)));
-}
-
-
-/*****************************************************************************
-** Read something from server/clinet
-*****************************************************************************/
-
-#ifdef MYSQL_SERVER
-
-/*
- Help function to clear the commuication buffer when we get a too
- big packet
-*/
-
-static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed)
-{
- ALARM alarm_buff;
- uint retry_count=0;
- if (!thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(alarmed,net->timeout,&alarm_buff) ||
- (!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0))
- return; /* Can't setup, abort */
- }
- while (remain > 0)
- {
- ulong length;
- if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
- {
- my_bool interrupted = vio_should_retry(net->vio);
- if (!thr_got_alarm(alarmed) && interrupted)
- { /* Probably in MIT threads */
- if (retry_count++ < RETRY_COUNT)
- continue;
- }
- return;
- }
- remain -=(ulong) length;
- statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
- }
-}
-#endif /* MYSQL_SERVER */
-
-
-static uint
-my_real_read(NET *net, ulong *complen)
-{
- uchar *pos;
- long length;
- uint i,retry_count=0;
- ulong len=packet_error;
- thr_alarm_t alarmed;
-#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
- ALARM alarm_buff;
-#endif
- my_bool net_blocking=vio_is_blocking(net->vio);
- ulong remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
- NET_HEADER_SIZE);
- *complen = 0;
-
- net->reading_or_writing=1;
- thr_alarm_init(&alarmed);
-#ifdef MYSQL_SERVER
- if (net_blocking)
- thr_alarm(&alarmed,net->timeout,&alarm_buff);
-#endif /* MYSQL_SERVER */
-
- pos = net->buff + net->where_b; /* net->packet -4 */
- for (i=0 ; i < 2 ; i++)
- {
- while (remain > 0)
- {
- /* First read is done with non blocking mode */
- if ((int) (length=vio_read(net->vio,(char*) pos,remain)) <= 0L)
- {
- my_bool interrupted = vio_should_retry(net->vio);
-
- DBUG_PRINT("info",("vio_read returned %d, errno: %d",
- length, vio_errno(net->vio)));
-#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
- /*
- We got an error that there was no data on the socket. We now set up
- an alarm to not 'read forever', change the socket to non blocking
- mode and try again
- */
- if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */
- {
- if (!vio_is_blocking(net->vio))
- {
- while (vio_blocking(net->vio,TRUE) < 0)
- {
- if (vio_should_retry(net->vio) &&
- retry_count++ < RETRY_COUNT)
- continue;
- DBUG_PRINT("error",
- ("fcntl returned error %d, aborting thread",
- vio_errno(net->vio)));
-#ifdef EXTRA_DEBUG
- fprintf(stderr,
- "%s: read: fcntl returned error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
- len= packet_error;
- net->error=2; /* Close socket */
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_FCNTL_ERROR;
-#endif
- goto end;
- }
- }
- retry_count=0;
- continue;
- }
- }
-#endif /* (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
- if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
- interrupted)
- { /* Probably in MIT threads */
- if (retry_count++ < RETRY_COUNT)
- continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
- }
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
- if (vio_should_retry(net->vio))
- {
- DBUG_PRINT("warning",("Interrupted read. Retrying..."));
- continue;
- }
-#endif
- DBUG_PRINT("error",("Couldn't read packet: remain: %d errno: %d length: %d alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
- len= packet_error;
- net->error=2; /* Close socket */
-#ifdef MYSQL_SERVER
- net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED :
- ER_NET_READ_ERROR);
-#endif
- goto end;
- }
- remain -= (ulong) length;
- pos+= (ulong) length;
- statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
- }
- if (i == 0)
- { /* First parts is packet length */
- ulong helping;
- if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
- {
- if (net->buff[net->where_b] != (uchar) 255)
- {
- DBUG_PRINT("error",
- ("Packets out of order (Found: %d, expected %d)",
- (int) net->buff[net->where_b + 3],
- (uint) (uchar) net->pkt_nr));
-#ifdef EXTRA_DEBUG
- fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n",
- (int) net->buff[net->where_b + 3],
- (uint) (uchar) net->pkt_nr);
-#endif
- }
- len= packet_error;
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
-#endif
- goto end;
- }
- net->pkt_nr++;
-#ifdef HAVE_COMPRESS
- if (net->compress)
- {
- /* complen is > 0 if package is really compressed */
- *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
- }
-#endif
-
- len=uint3korr(net->buff+net->where_b);
- helping = max(len,*complen) + net->where_b;
- /* The necessary size of net->buff */
- if (helping >= net->max_packet)
- {
- /* We must allocate one extra byte for the end null */
- if (net_realloc(net,helping+1))
- {
-#ifdef MYSQL_SERVER
- if (i == 1)
- my_net_skip_rest(net, len, &alarmed);
-#endif
- len= packet_error; /* Return error */
- goto end;
- }
- }
- pos=net->buff + net->where_b;
- remain = len;
- }
- }
-
-end:
- if (thr_alarm_in_use(&alarmed))
- {
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
- }
- net->reading_or_writing=0;
- return(len);
-}
-
-uint
-my_net_read(NET *net)
-{
- ulong len,complen;
-
-#ifdef HAVE_COMPRESS
- if (!net->compress)
- {
-#endif
- len = my_real_read (net,&complen);
- net->read_pos = net->buff + net->where_b;
- if (len != packet_error)
- net->read_pos[len]=0; /* Safeguard for mysql_use_result */
- return len;
-#ifdef HAVE_COMPRESS
- }
- if (net->remain_in_buf)
- net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
- for (;;)
- {
- if (net->remain_in_buf)
- {
- uchar *pos = net->buff + net->buf_length - net->remain_in_buf;
- if (net->remain_in_buf >= 4)
- {
- net->length = uint3korr(pos);
- if (net->length <= net->remain_in_buf - 4)
- {
- /* We have a full packet */
- len=net->length;
- net->remain_in_buf -= net->length + 4;
- net->read_pos=pos + 4;
- break; /* We have a full packet */
- }
- }
- /* Move data down to read next data packet after current one */
- if (net->buf_length != net->remain_in_buf)
- {
- memmove(net->buff,pos,net->remain_in_buf);
- net->buf_length=net->remain_in_buf;
- }
- net->where_b=net->buf_length;
- }
- else
- {
- net->where_b=0;
- net->buf_length=0;
- }
-
- if ((len = my_real_read(net,&complen)) == packet_error)
- break;
- if (my_uncompress((byte*) net->buff + net->where_b, &len, &complen))
- {
- len= packet_error;
- net->error=2; /* caller will close socket */
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_UNCOMPRESS_ERROR;
-#endif
- break;
- }
- net->buf_length+=len;
- net->remain_in_buf+=len;
- }
- if (len != packet_error)
- {
- net->save_char= net->read_pos[len]; /* Must be saved */
- net->read_pos[len]=0; /* Safeguard for mysql_use_result */
- }
- return len;
-#endif
-}
diff --git a/libmysql/password.c b/libmysql/password.c
index 0fd5861873a..9b154603b98 100644
--- a/libmysql/password.c
+++ b/libmysql/password.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* password checking routines */
/*****************************************************************************
@@ -35,7 +34,7 @@
This saves a hashed number as a string in the password field.
*****************************************************************************/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "mysql.h"
diff --git a/libmysql/violite.c b/libmysql/violite.c
deleted file mode 100644
index 37fee6fad3d..00000000000
--- a/libmysql/violite.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*
- Note that we can't have assertion on file descriptors; The reason for
- this is that during mysql shutdown, another thread can close a file
- we are working on. In this case we should just return read errors from
- the file descriptior.
-*/
-
-#include <global.h>
-
-#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
-
-#include <errno.h>
-#include <assert.h>
-#include <violite.h>
-#include <my_sys.h>
-#include <my_net.h>
-#include <m_string.h>
-#ifdef HAVE_POLL
-#include <sys/poll.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__FreeBSD__)
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
-#endif
-#endif
-
-#if defined(__EMX__) || defined(OS2)
-#define ioctlsocket ioctl
-#endif /* defined(__EMX__) */
-
-#if defined(MSDOS) || defined(__WIN__)
-#define O_NONBLOCK 1 /* For emulation of fcntl() */
-#endif
-#ifndef EWOULDBLOCK
-#define SOCKET_EWOULDBLOCK SOCKET_EAGAIN
-#endif
-
-#ifndef __WIN__
-#define HANDLE void *
-#endif
-
-struct st_vio
-{
- my_socket sd; /* my_socket - real or imaginary */
- HANDLE hPipe;
- my_bool localhost; /* Are we from localhost? */
- int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
- enum enum_vio_type type; /* Type of connection */
- char desc[30]; /* String description */
-};
-
-typedef void *vio_ptr;
-typedef char *vio_cstring;
-
-/*
- * Helper to fill most of the Vio* with defaults.
- */
-
-static void vio_reset(Vio* vio, enum enum_vio_type type,
- my_socket sd, HANDLE hPipe,
- my_bool localhost)
-{
- bzero((char*) vio, sizeof(*vio));
- vio->type = type;
- vio->sd = sd;
- vio->hPipe = hPipe;
- vio->localhost= localhost;
-}
-
-/* Open the socket or TCP/IP connection and read the fnctl() status */
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
-{
- Vio *vio;
- DBUG_ENTER("vio_new");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
- {
- vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc,
- (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
- vio->sd);
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
- vio->fcntl_mode = fcntl(sd, F_GETFL);
-#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
- /* Non blocking sockets doesn't work good on HPUX 11.0 */
- (void) ioctl(sd,FIOSNBIO,0);
-#endif
-#else /* !defined(__WIN__) && !defined(__EMX__) */
- {
- /* set to blocking mode by default */
- ulong arg=0, r;
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif
- }
- DBUG_RETURN(vio);
-}
-
-
-#ifdef __WIN__
-
-Vio *vio_new_win32pipe(HANDLE hPipe)
-{
- Vio *vio;
- DBUG_ENTER("vio_new_handle");
- if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
- {
- vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
- strmov(vio->desc, "named pipe");
- }
- DBUG_RETURN(vio);
-}
-
-#endif
-
-void vio_delete(Vio * vio)
-{
- /* It must be safe to delete null pointers. */
- /* This matches the semantics of C++'s delete operator. */
- if (vio)
- {
- if (vio->type != VIO_CLOSED)
- vio_close(vio);
- my_free((gptr) vio,MYF(0));
- }
-}
-
-int vio_errno(Vio *vio __attribute__((unused)))
-{
- return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
-}
-
-
-int vio_read(Vio * vio, gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_read");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosRead((HFILE)vio->hPipe, buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = recv(vio->sd, buf, size,0);
-#else
- errno=0; /* For linux */
- r = read(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_write(Vio * vio, const gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_write");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if ( vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosWrite((HFILE)vio->hPipe, (char*) buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = send(vio->sd, buf, size,0);
-#else
- r = write(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_blocking(Vio * vio, my_bool set_blocking_mode)
-{
- int r=0;
- DBUG_ENTER("vio_blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
-
- if (vio->sd >= 0)
- {
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- else
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- if (old_fcntl != vio->fcntl_mode)
- r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
- }
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN__) && !defined(__EMX__) */
-#ifndef __EMX__
- if (vio->type != VIO_TYPE_NAMEDPIPE)
-#endif
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- {
- arg = 0;
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- }
- else
- {
- arg = 1;
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- }
- if (old_fcntl != vio->fcntl_mode)
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif /* !defined(__WIN__) && !defined(__EMX__) */
- DBUG_RETURN(r);
-}
-
-my_bool
-vio_is_blocking(Vio * vio)
-{
- my_bool r;
- DBUG_ENTER("vio_is_blocking");
- r = !(vio->fcntl_mode & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int) r));
- DBUG_RETURN(r);
-}
-
-
-int vio_fastsend(Vio * vio __attribute__((unused)))
-{
- int r=0;
- DBUG_ENTER("vio_fastsend");
-
-#ifdef IPTOS_THROUGHPUT
- {
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
- sizeof(nodelay))) {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int vio_keepalive(Vio* vio, my_bool set_keep_alive)
-{
- int r=0;
- uint opt = 0;
- DBUG_ENTER("vio_keepalive");
- DBUG_PRINT("enter", ("sd=%d set_keep_alive=%d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- if (set_keep_alive)
- opt = 1;
- r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_should_retry(Vio * vio __attribute__((unused)))
-{
- int en = socket_errno;
- return en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK;
-}
-
-
-int vio_close(Vio * vio)
-{
- int r;
- DBUG_ENTER("vio_close");
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else if (vio->type != VIO_CLOSED)
-#endif /* __WIN__ */
- {
- r=0;
- if (shutdown(vio->sd,2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio->type= VIO_CLOSED;
- vio->sd= -1;
- DBUG_RETURN(r);
-}
-
-
-const char *vio_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_peer_addr(Vio * vio, char *buf)
-{
- DBUG_ENTER("vio_peer_addr");
- DBUG_PRINT("enter", ("sd=%d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(vio->remote.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-void vio_in_addr(Vio *vio, struct in_addr *in)
-{
- DBUG_ENTER("vio_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in)); /* This should never be executed */
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-
-/* Return 0 if there is data to be read */
-
-my_bool vio_poll_read(Vio *vio,uint timeout)
-{
-#ifndef HAVE_POLL
- return 0;
-#else
- struct pollfd fds;
- int res;
- DBUG_ENTER("vio_poll");
- fds.fd=vio->sd;
- fds.events=POLLIN;
- fds.revents=0;
- if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
- {
- DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
- }
- DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
-#endif
-}
-
-#endif /* HAVE_VIO */
diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am
index aa1d398f874..22d71e00752 100644
--- a/libmysql_r/Makefile.am
+++ b/libmysql_r/Makefile.am
@@ -22,7 +22,7 @@ target_defs = -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@
## LIBS = @LIBS@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include \
- -I$(srcdir)/.. -I$(top_srcdir) -I..
+ -I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
## automake barfs if you don't use $(srcdir) or $(top_srcdir) in include
include $(top_srcdir)/libmysql/Makefile.shared
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
new file mode 100644
index 00000000000..10a8459b66b
--- /dev/null
+++ b/libmysqld/Makefile.am
@@ -0,0 +1,135 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# This file is public domain and comes with NO WARRANTY of any kind
+
+MYSQLDATAdir = $(localstatedir)
+MYSQLSHAREdir = $(pkgdatadir)
+MYSQLBASEdir= $(prefix)
+
+DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
+ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+ -DDATADIR="\"$(MYSQLDATAdir)\"" \
+ -DSHAREDIR="\"$(MYSQLSHAREdir)\""
+INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(srcdir)/../include \
+ -I../include -I$(srcdir)/.. -I$(top_srcdir) -I.. \
+ -I../sql -I../regex
+
+noinst_LIBRARIES = libmysqld_int.a
+pkglib_LIBRARIES = libmysqld.a
+SUBDIRS = . examples
+libmysqld_sources= libmysqld.c lib_sql.cc
+libmysqlsources = errmsg.c get_password.c password.c
+
+noinst_HEADERS = embedded_priv.h
+
+sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
+ ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
+ ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \
+ hostname.cc init.cc \
+ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
+ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
+ item_uniq.cc key.cc lock.cc log.cc log_event.cc mf_iocache.cc\
+ mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \
+ opt_sum.cc procedure.cc records.cc sql_acl.cc \
+ repl_failsafe.cc slave.cc sql_load.cc sql_olap.cc \
+ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
+ sql_crypt.cc sql_db.cc sql_delete.cc sql_insert.cc sql_lex.cc \
+ sql_list.cc sql_manager.cc sql_map.cc set_var.cc sql_parse.cc \
+ sql_rename.cc sql_repl.cc sql_select.cc sql_do.cc sql_show.cc \
+ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
+ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
+ unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc
+
+EXTRA_DIST = lib_vio.c
+
+libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
+libmysqld_a_SOURCES=
+
+# Don't depend on things from mit-pthreads
+
+OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
+ __math.h time.h __time.h unistd.h __unistd.h types.h \
+ xtypes.h ac-types.h posix.h string.h __string.h \
+ errno.h socket.h inet.h dirent.h netdb.h \
+ cleanup.h cond.h debug_out.h fd.h kernel.h mutex.h \
+ prio_queue.h pthread_attr.h pthread_once.h queue.h\
+ sleep.h specific.h version.h pwd.h timers.h uio.h \
+ cdefs.h machdep.h signal.h __signal.h util.h lex.h \
+ wait.h
+
+# automake misses these
+sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
+
+# The following libraries should be included in libmysqld.a
+INC_LIB= $(top_builddir)/regex/libregex.a \
+ $(top_builddir)/myisam/libmyisam.a \
+ $(top_builddir)/myisammrg/libmyisammrg.a \
+ $(top_builddir)/heap/libheap.a \
+ @innodb_libs@ @bdb_libs_with_path@ \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/strings/libmystrings.a \
+ $(top_builddir)/dbug/libdbug.a \
+ $(top_builddir)/regex/libregex.a
+
+#
+# To make it easy for the end user to use the embedded library we
+# generate a total libmysqld.a from all library files,
+
+libmysqld.a: libmysqld_int.a $(INC_LIB)
+ if test ! -d tmp ; then mkdir tmp ; fi
+ rm -f $@ libmysqld_int2.a tmp/*.o tmp/*.a
+ cp $(INC_LIB) tmp
+ cp libmysqld_int.a libmysqld_int2.a ; \
+ cd tmp ; \
+ for file in *.a ; do \
+ bfile=`basename $$file .a` ; \
+ ar x $$file; \
+ for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \
+ ar q ../libmysqld_int2.a *.o ; \
+ rm *.o ; \
+ done
+ mv libmysqld_int2.a libmysqld.a
+ rm tmp/*
+ $(RANLIB) libmysqld.a
+
+## XXX: any time the client interface changes, we'll need to bump
+## the version info for libmysqld; however, it's possible for the
+## libmysqld interface to change without affecting the standard
+## libmysqlclient interface. Should we make a separate version
+## string for the two?
+#libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@
+#CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la
+
+# This is called from the toplevel makefile
+link_sources:
+ set -x; \
+ for f in $(sqlsources); do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
+ done; \
+ for f in $(libmysqlsources); do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \
+ done
+
+clean-local:
+ rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"` \
+ $(top_srcdir)/linked_libmysqld_sources
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/libmysqld/copyright b/libmysqld/copyright
new file mode 100644
index 00000000000..0b4dd1725a2
--- /dev/null
+++ b/libmysqld/copyright
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2000
+ * SWsoft company
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h
new file mode 100644
index 00000000000..e17b72e84d8
--- /dev/null
+++ b/libmysqld/embedded_priv.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Prototypes for the embedded version of MySQL */
+
+#include <my_global.h>
+#include <mysql.h>
+#include <mysql_embed.h>
+#include <mysqld_error.h>
+#include <my_pthread.h>
+
+C_MODE_START
+extern void start_embedded_connection(NET * net);
+extern void end_embedded_connection(NET * net);
+extern void lib_connection_phase(NET *net, int phase);
+extern bool lib_dispatch_command(enum enum_server_command command, NET *net,
+ const char *arg, ulong length);
+C_MODE_END
diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am
new file mode 100644
index 00000000000..98d38531f64
--- /dev/null
+++ b/libmysqld/examples/Makefile.am
@@ -0,0 +1,26 @@
+noinst_PROGRAMS = mysqltest mysql
+client_sources = $(mysqltest_SOURCES) $(mysql_SOURCES)
+
+link_sources:
+ for f in $(client_sources); do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../../client/$$f $(srcdir)/$$f; \
+ done;
+
+DEFS = -DEMBEDDED_LIBRARY
+INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include $(openssl_includes) \
+ -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/client
+LIBS = @LIBS@
+LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS)
+
+mysqltest_SOURCES = mysqltest.c
+
+mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
+ my_readline.h sql_string.h completion_hash.h
+mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD)
+
+clean:
+ rm -f $(client_sources)
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/libmysqld/examples/test-run b/libmysqld/examples/test-run
new file mode 100755
index 00000000000..c7434488259
--- /dev/null
+++ b/libmysqld/examples/test-run
@@ -0,0 +1,138 @@
+#! /bin/sh
+
+# This is slapped together as a quick way to run the tests and
+# is not meant for prime time. Please hack at it and submit
+# changes, though, so we can gradually turn it into something
+# that will run on all platforms (or incorporate it into the
+# standard mysql-test-run).
+
+# All paths below must be relative to $test_data_dir
+top_builddir=../..
+mysql_test_dir=$top_builddir/mysql-test
+examples=$top_builddir/libmysqld/examples
+mysqltest=$examples/mysqltest
+datadir=$mysql_test_dir/var/master-data
+test_data_dir=test
+gdb=0
+list=0
+run=
+tests=
+start=
+clean=1
+
+cr="
+"
+er="\b\b\b\b\b\b\b\b"
+
+usage () {
+ cat <<EOF
+usage: $0 [-g|-h|-r] [test-name ...]
+
+ -C | --noclean Do not remove old innodb and bdb files at start.
+ -g | --gdb run $mysqltest in gdb
+ -h | --help show this help
+ -l | --list ) list all available tests
+ -r | --run automatically 'run' program in gdb
+ -s t | --start=t start with test t (skip all tests before t)
+EOF
+}
+
+init_args="--server-arg=--language=$top_builddir/sql/share/english"
+while test $# -gt 0
+do
+ arg=
+ argset=0
+ case "$1" in
+ --?*=* ) arg=`echo "$1" | sed -e 's,^[^=][^=]*=,,'`; argset=1 ;;
+ esac
+
+ case "$1" in
+ -g | --gdb ) gdb=1; shift;;
+ -h | --help | -\? ) usage; exit 0;;
+ -l | --list ) list=1 ; shift ;;
+ -r | --run ) run="${cr}run"; shift;;
+ --debug) init_args="$init_args --debug" ; shift ;;
+ -C | --noclean) clean=0 ; shift ;;
+ -s | --start=* )
+ test $argset -eq 0 && { shift; arg="$1"; }
+ start="$arg"
+ shift
+ ;;
+ -* ) usage; exit 1;;
+ * ) tests="$tests $1"; shift;;
+ esac
+done
+
+if test ! -d "$datadir/$test_data_dir"
+then
+ echo "bad setup (is '$datadir/$test_data_dir'', missing ?)" >&2
+ exit 1
+fi
+
+test -n "$tests" ||
+ tests=`/bin/ls -1 "$mysql_test_dir"/t/*.test | grep -v '^.*/rpl[^/]*$' | \
+ sed -e 's,^.*/,,' -e 's,.test$,,'`
+
+echo "cleaning data directory '$datadir/$test_data_dir'"
+if test $clean = 1
+then
+ rm -f $datadir/ib_* $datadir/ibdata*
+ rm -f $datadir/log.00*
+ rm -f $datadir/test/*.db
+fi
+rm -f $datadir/../tmp/*
+rm -f test-gdbinit
+
+TZ=GMT-3; export TZ
+
+# At least one of the tests needs the following environment variable
+MYSQL_TEST_DIR=`( cd $mysql_test_dir ; pwd )` ; export MYSQL_TEST_DIR
+
+skip=1
+test -z "$start" && skip=0
+
+for b in $tests
+do
+ test $list -eq 1 && { echo " $b"; continue; }
+ test $skip -eq 1 && test -n "$start" && test "$start" = "$b" && skip=0
+ test $skip -eq 1 && { echo "skipping '$b'"; continue; }
+
+ t="t/$b.test"
+ r="r/$b.result"
+
+ # Only test if $t exists; there is no $r for some tests
+ test -f $mysql_test_dir/$t || {
+ echo "test '$mysql_test_dir/$t' doesn't exist" >&2
+ continue
+ }
+ args="$init_args -v --basedir=$mysql_test_dir/ -R $r -x $t --server-arg=--datadir=$datadir"
+ if test -f "$mysql_test_dir/t/$b-master.opt" ; then
+ args="$args --server-file=t/$b-master.opt"
+ fi
+
+ args="$args $test_data_dir" # Add database last
+ echo "set args $args$run" > test-gdbinit
+ #if false && test -n "$run"
+ if test -n "$run" -o $gdb -eq 1
+ then
+ echo -e "$er>>> $b"
+ else
+ echo -e "$er>>> $b> \c"
+ read junk
+ fi
+ if test $gdb -eq 1
+ then
+ if [ -x "$top_builddir/libtool" ]; then
+ $top_builddir/libtool gdb -x test-gdbinit -q $mysqltest
+ else
+ gdb -x test-gdbinit -q $mysqltest
+ fi
+ res=$?
+ rm -f test-gdbinit
+ else
+ $mysqltest $args
+ res=$?
+ fi
+
+ test $res -eq 0 -o $res -eq 2 || echo "!!! error: $res"
+done
diff --git a/libmysqld/lib_load.cc b/libmysqld/lib_load.cc
new file mode 100644
index 00000000000..3db5a2488d1
--- /dev/null
+++ b/libmysqld/lib_load.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2000
+ * SWsoft company
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+/* Copy data from a textfile to table */
+
+#include "mysql_priv.h"
+#include <my_dir.h>
+#include <m_ctype.h>
+
+
+int
+mysql_load_internal(THD * thd, sql_exchange * ex, TABLE_LIST * table_list,
+ List<Item> & fields, enum enum_duplicates handle_duplicates,
+ bool read_file_from_client, thr_lock_type lock_type);
+
+int
+mysql_load(THD * thd, sql_exchange * ex, TABLE_LIST * table_list,
+ List<Item> & fields, enum enum_duplicates handle_duplicates,
+ bool read_file_from_client, thr_lock_type lock_type)
+{
+ read_file_from_client = 0; //server is always in the same process
+ return mysql_load_internal(thd, ex, table_list, fields, handle_duplicates,
+ read_file_from_client, lock_type);
+}
+
+#define mysql_load mysql_load_internal
+
+
+#if defined (__WIN__)
+#include "../sql/sql_load.cpp"
+#else
+#include "../sql/sql_load.cc"
+#endif
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
new file mode 100644
index 00000000000..d461c46d604
--- /dev/null
+++ b/libmysqld/lib_sql.cc
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2000
+ * SWsoft company
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+
+ This code was modified by the MySQL team
+*/
+
+/*
+ The following is needed to not cause conflicts when we include mysqld.cc
+*/
+
+#define main main1
+#define mysql_unix_port mysql_inix_port1
+#define mysql_port mysql_port1
+
+#if defined (__WIN__)
+#include "../sql/mysqld.cpp"
+#else
+#include "../sql/mysqld.cc"
+#endif
+
+#define SCRAMBLE_LENGTH 8
+C_MODE_START
+#include "lib_vio.c"
+
+static int check_connections1(THD * thd);
+static int check_connections2(THD * thd);
+static bool check_user(THD *thd, enum_server_command command,
+ const char *user, const char *passwd, const char *db,
+ bool check_count);
+char * get_mysql_home(){ return mysql_home;};
+char * get_mysql_real_data_home(){ return mysql_real_data_home;};
+
+bool lib_dispatch_command(enum enum_server_command command, NET *net,
+ const char *arg, ulong length)
+{
+ THD *thd=(THD *) net->vio->dest_thd;
+ thd->store_globals(); // Fix if more than one connect
+ thd->net.last_error[0]=0; // Clear error message
+ thd->net.last_errno=0;
+
+ net_new_transaction(&thd->net);
+ return dispatch_command(command, thd, (char *) arg, length + 1);
+}
+
+
+void lib_connection_phase(NET * net, int phase)
+{
+ THD * thd;
+ thd = (THD *)(net->vio->dest_thd);
+ if (thd)
+ {
+ switch (phase)
+ {
+ case 2:
+ check_connections2(thd);
+ break;
+ }
+ }
+}
+C_MODE_END
+
+
+void start_embedded_conn1(NET * net)
+{
+ THD * thd = new THD;
+ my_net_init(&thd->net,NULL);
+ /* if (protocol_version>9) */
+ thd->net.return_errno=1;
+ thd->thread_id = thread_id++;
+
+ Vio * v = net->vio;
+ if (!v)
+ {
+ v = vio_new(0,VIO_CLOSED,0);
+ net->vio = v;
+ }
+ if (v)
+ {
+ v -> dest_thd = thd;
+ }
+ thd->net.vio = v;
+ if (thd->store_globals())
+ {
+ fprintf(stderr,"store_globals failed.\n");
+ return;
+ }
+
+ thd->mysys_var=my_thread_var;
+ thd->dbug_thread_id=my_thread_id();
+ thd->thread_stack= (char*) &thd;
+
+ if (thd->variables.max_join_size == (ulong) HA_POS_ERROR)
+ thd->options |= OPTION_BIG_SELECTS;
+
+ thd->proc_info=0; // Remove 'login'
+ thd->command=COM_SLEEP;
+ thd->version=refresh_version;
+ thd->set_time();
+ init_sql_alloc(&thd->mem_root,8192,8192);
+
+ check_connections1(thd);
+}
+
+
+
+
+static int
+check_connections1(THD *thd)
+{
+ uint connect_errors=0;
+ NET *net= &thd->net;
+ /*
+ ** store the connection details
+ */
+ DBUG_PRINT("info", (("check_connections called by thread %d"),
+ thd->thread_id));
+ DBUG_PRINT("general",("New connection received on %s",
+ vio_description(net->vio)));
+ if (!thd->host) // If TCP/IP connection
+ {
+ thd->host=(char*) localhost;
+ }
+ else /* Hostname given means that the connection was on a socket */
+ {
+ DBUG_PRINT("general",("Host: %s",thd->host));
+ thd->ip=0;
+ bzero((char*) &thd->remote,sizeof(struct sockaddr));
+ }
+ //vio_keepalive(net->vio, TRUE);
+
+ /* nasty, but any other way? */
+ uint pkt_len = 0;
+
+ char buff[80],*end;
+ int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
+ CLIENT_TRANSACTIONS;
+ LINT_INIT(pkt_len);
+
+ end=strmov(buff,server_version)+1;
+ int4store((uchar*) end,thd->thread_id);
+ end+=4;
+ memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
+ end+=SCRAMBLE_LENGTH +1;
+ int2store(end,client_flags);
+ end[2]=MY_CHARSET_CURRENT;
+
+#define MIN_HANDSHAKE_SIZE 6
+
+ int2store(end+3,thd->server_status);
+ bzero(end+5,13);
+ end+=18;
+ if (net_write_command(net,protocol_version, buff,
+ (uint) (end-buff)))
+ {
+ inc_host_errors(&thd->remote.sin_addr);
+ return(ER_HANDSHAKE_ERROR);
+ }
+ return 0;
+}
+
+static int
+check_connections2(THD * thd)
+{
+ uint connect_errors=0;
+ uint pkt_len = 0;
+ NET * net = &thd -> net;
+ if (protocol_version>9) net -> return_errno=1;
+
+ if ( (pkt_len=my_net_read(net)) == packet_error ||
+ pkt_len < MIN_HANDSHAKE_SIZE)
+ {
+ inc_host_errors(&thd->remote.sin_addr);
+ return(ER_HANDSHAKE_ERROR);
+ }
+
+#ifdef _CUSTOMCONFIG_
+#include "_cust_sql_parse.h"
+#endif
+ if (connect_errors)
+ reset_host_errors(&thd->remote.sin_addr);
+ if (thd->packet.alloc(thd->variables.net_buffer_length))
+ return(ER_OUT_OF_RESOURCES);
+
+ thd->client_capabilities=uint2korr(net->read_pos);
+
+ thd->max_client_packet_length=uint3korr(net->read_pos+2);
+ char *user= (char*) net->read_pos+5;
+ char *passwd= strend(user)+1;
+ char *db=0;
+ if (passwd[0] && strlen(passwd) != SCRAMBLE_LENGTH)
+ return ER_HANDSHAKE_ERROR;
+ if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
+ db=strend(passwd)+1;
+ if (thd->client_capabilities & CLIENT_TRANSACTIONS)
+ thd->net.return_status= &thd->server_status;
+ net->read_timeout=thd->variables.net_read_timeout;
+ if (check_user(thd,COM_CONNECT, user, passwd, db, 1))
+ return (-1);
+ thd->password=test(passwd[0]);
+ return 0;
+}
+
+static bool check_user(THD *thd,enum_server_command command, const char *user,
+ const char *passwd, const char *db, bool check_count)
+{
+ NET *net= &thd->net;
+ USER_RESOURCES ur;
+ thd->db=0;
+
+ if (!(thd->user = my_strdup(user, MYF(0))))
+ {
+ send_error(net,ER_OUT_OF_RESOURCES);
+ return 1;
+ }
+ thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
+ passwd, thd->scramble, &thd->priv_user,
+ protocol_version == 9 ||
+ !(thd->client_capabilities &
+ CLIENT_LONG_PASSWORD),&ur);
+ DBUG_PRINT("info",
+ ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
+ thd->client_capabilities, thd->max_client_packet_length,
+ thd->host_or_ip, thd->priv_user,
+ passwd[0] ? "yes": "no",
+ thd->master_access, thd->db ? thd->db : "*none*"));
+ if (thd->master_access & NO_ACCESS)
+ {
+ net_printf(net, ER_ACCESS_DENIED_ERROR,
+ thd->user,
+ thd->host_or_ip,
+ passwd[0] ? ER(ER_YES) : ER(ER_NO));
+ mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR),
+ thd->user,
+ thd->host_or_ip,
+ passwd[0] ? ER(ER_YES) : ER(ER_NO));
+ return(1); // Error already given
+ }
+ if (check_count)
+ {
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ bool tmp=(thread_count - delayed_insert_threads >= max_connections &&
+ !(thd->master_access & PROCESS_ACL));
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ if (tmp)
+ { // Too many connections
+ send_error(net, ER_CON_COUNT_ERROR);
+ return(1);
+ }
+ }
+ mysql_log.write(thd,command,
+ (thd->priv_user == thd->user ?
+ (char*) "%s@%s on %s" :
+ (char*) "%s@%s as anonymous on %s"),
+ user,
+ thd->host_or_ip,
+ db ? db : (char*) "");
+ thd->db_access=0;
+ if (db && db[0])
+ return test(mysql_change_db(thd,db));
+ else
+ send_ok(net); // Ready to handle questions
+ return 0; // ok
+}
+
+
+extern "C"
+{
+
+static my_bool inited, org_my_init_done;
+ulong max_allowed_packet, net_buffer_length;
+
+int STDCALL mysql_server_init(int argc, char **argv, char **groups)
+{
+ char glob_hostname[FN_REFLEN];
+
+ /* This mess is to allow people to call the init function without
+ * having to mess with a fake argv */
+ int *argcp;
+ char ***argvp;
+ int fake_argc = 1;
+ char *fake_argv[] = { (char *)"", 0 };
+ const char *fake_groups[] = { "server", "embedded", 0 };
+ if (argc)
+ {
+ argcp = &argc;
+ argvp = (char***) &argv;
+ }
+ else
+ {
+ argcp = &fake_argc;
+ argvp = (char ***) &fake_argv;
+ }
+ if (!groups)
+ groups = (char**) fake_groups;
+
+ my_umask=0660; // Default umask for new files
+ my_umask_dir=0700; // Default umask for new directories
+
+ /* Only call MY_INIT() if it hasn't been called before */
+ if (!inited)
+ {
+ inited=1;
+ org_my_init_done=my_init_done;
+ }
+ if (!org_my_init_done)
+ {
+ MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads
+ }
+
+ tzset(); // Set tzname
+
+ start_time=time((time_t*) 0);
+#ifdef HAVE_TZNAME
+#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
+ {
+ struct tm tm_tmp;
+ localtime_r(&start_time,&tm_tmp);
+ strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]);
+ }
+#else
+ {
+ struct tm *start_tm;
+ start_tm=localtime(&start_time);
+ strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]);
+ }
+#endif
+#endif
+
+ if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
+ strmov(glob_hostname,"mysql");
+#ifndef DBUG_OFF
+ strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
+#else
+ strmov(strend(server_version),MYSQL_SERVER_SUFFIX);
+#endif
+ load_defaults("my", (const char **) groups, argcp, argvp);
+ defaults_argv=*argvp;
+
+ /* Get default temporary directory */
+ opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
+#if defined( __WIN__) || defined(OS2)
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TEMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TMP");
+#endif
+ if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
+ opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
+
+ set_options();
+ get_options(*argcp, *argvp);
+
+ if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
+ strcat(server_version,"-log");
+ DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
+ server_version, SYSTEM_TYPE,MACHINE_TYPE));
+
+ /* These must be set early */
+
+ (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_grant,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_server_id, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
+ (void) pthread_cond_init(&COND_thread_count,NULL);
+ (void) pthread_cond_init(&COND_refresh,NULL);
+ (void) pthread_cond_init(&COND_thread_cache,NULL);
+ (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
+ (void) pthread_cond_init(&COND_manager,NULL);
+ (void) pthread_cond_init(&COND_rpl_status, NULL);
+
+ if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
+ {
+ mysql_server_end();
+ return 1;
+ }
+ charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
+
+ /* Parameter for threads created for connections */
+ (void) pthread_attr_init(&connection_attrib);
+ (void) pthread_attr_setdetachstate(&connection_attrib,
+ PTHREAD_CREATE_DETACHED);
+ pthread_attr_setstacksize(&connection_attrib,thread_stack);
+ pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
+
+#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
+ /* connections and databases needs lots of files */
+ {
+ uint wanted_files=10+(uint) max(max_connections*5,
+ max_connections+table_cache_size*2);
+ set_if_bigger(wanted_files, open_files_limit);
+ // Note that some system returns 0 if we succeed here:
+ uint files=set_maximum_open_files(wanted_files);
+ if (files && files < wanted_files && ! open_files_limit)
+ {
+ max_connections= (ulong) min((files-10),max_connections);
+ table_cache_size= (ulong) max((files-10-max_connections)/2,64);
+ DBUG_PRINT("warning",
+ ("Changed limits: max_connections: %ld table_cache: %ld",
+ max_connections,table_cache_size));
+ sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size);
+ }
+ }
+#endif
+ unireg_init(opt_specialflag); /* Set up extern variabels */
+ init_errmessage(); /* Read error messages from file */
+ lex_init();
+ item_init();
+ set_var_init();
+ mysys_uses_curses=0;
+#ifdef USE_REGEX
+ regex_init();
+#endif
+ if (use_temp_pool && bitmap_init(&temp_pool,1024,1))
+ {
+ mysql_server_end();
+ return 1;
+ }
+
+ /*
+ We have enough space for fiddling with the argv, continue
+ */
+ umask(((~my_umask) & 0666));
+ table_cache_init();
+ hostname_cache_init();
+ query_cache_result_size_limit(query_cache_limit);
+ query_cache_resize(query_cache_size);
+ randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
+ reset_floating_point_exceptions();
+ init_thr_lock();
+ init_slave_list();
+
+ /* Setup log files */
+ if (opt_log)
+ open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL);
+ if (opt_update_log)
+ {
+ open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
+ LOG_NEW);
+ using_update_log=1;
+ }
+
+ if (opt_slow_log)
+ open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
+ LOG_NORMAL);
+ if (ha_init())
+ {
+ sql_print_error("Can't init databases");
+ exit(1);
+ }
+ ha_key_cache();
+#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
+ if (locked_in_memory && !geteuid())
+ {
+ if (mlockall(MCL_CURRENT))
+ {
+ sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
+ }
+ else
+ locked_in_memory=1;
+ }
+#else
+ locked_in_memory=0;
+#endif
+
+ if (opt_myisam_log)
+ (void) mi_log( 1 );
+ ft_init_stopwords(ft_precompiled_stopwords);
+
+ /*
+ init signals & alarm
+ After this we can't quit by a simple unireg_abort
+ */
+ error_handler_hook = my_message_sql;
+ if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) ||
+ pthread_key_create(&THR_MALLOC,NULL))
+ {
+ sql_print_error("Can't create thread-keys");
+ exit(1);
+ }
+ opt_noacl = 1; // No permissions
+ if (acl_init(opt_noacl))
+ {
+ mysql_server_end();
+ return 1;
+ }
+ if (!opt_noacl)
+ (void) grant_init();
+ init_max_user_conn();
+
+#ifdef HAVE_DLOPEN
+ if (!opt_noacl)
+ udf_init();
+#endif
+
+ if (opt_bin_log)
+ {
+ if (!opt_bin_logname)
+ {
+ char tmp[FN_REFLEN];
+ /* TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
+ */
+ strmake(tmp,glob_hostname,FN_REFLEN-5);
+ strmov(strcend(tmp,'.'),"-bin");
+ opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
+ }
+ mysql_bin_log.set_index_file_name(opt_binlog_index_name);
+ open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
+ LOG_BIN);
+ using_update_log=1;
+ }
+
+ (void) thr_setconcurrency(concurrency); // 10 by default
+
+ if (
+#ifdef HAVE_BERKELEY_DB
+ !berkeley_skip ||
+#endif
+ (flush_time && flush_time != ~(ulong) 0L))
+ {
+ pthread_t hThread;
+ if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
+ sql_print_error("Warning: Can't create thread to manage maintenance");
+ }
+
+ /* Update mysqld variables from client variables */
+ global_system_variables.max_allowed_packet=max_allowed_packet;
+ global_system_variables.net_buffer_length=net_buffer_length;
+ return 0;
+}
+
+
+void STDCALL mysql_server_end()
+{
+ clean_up(0);
+#ifdef THREAD
+ /* Don't call my_thread_end() if the application is using MY_INIT() */
+ if (!org_my_init_done)
+ my_thread_end();
+#endif
+ /* If library called my_init(), free memory allocated by it */
+ if (!org_my_init_done)
+ my_end(0);
+}
+
+my_bool STDCALL mysql_thread_init()
+{
+#ifdef THREAD
+ return my_thread_init();
+#else
+ return 0;
+#endif
+}
+
+void STDCALL mysql_thread_end()
+{
+#ifdef THREAD
+ my_thread_end();
+#endif
+}
+
+void start_embedded_connection(NET * net)
+{
+ start_embedded_conn1(net);
+}
+
+void end_embedded_connection(NET * net)
+{
+ THD *thd = (THD *) net->vio->dest_thd;
+ delete thd;
+}
+
+} /* extern "C" */
diff --git a/libmysqld/lib_vio.c b/libmysqld/lib_vio.c
new file mode 100644
index 00000000000..5460c546faa
--- /dev/null
+++ b/libmysqld/lib_vio.c
@@ -0,0 +1,222 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#include <my_global.h>
+#include "mysql_embed.h"
+#include "mysql.h"
+
+#ifndef HAVE_VIO /* is Vio enabled */
+
+#include <errno.h>
+#include <my_sys.h>
+#include <violite.h>
+#include <my_sys.h>
+#include <my_net.h>
+#include <m_string.h>
+#include <dbug.h>
+#include <assert.h>
+
+#ifndef __WIN__
+#define HANDLE void *
+#endif
+
+struct st_vio
+{
+ my_socket sd; /* my_socket - real or imaginary */
+ HANDLE hPipe;
+ my_bool localhost; /* Are we from localhost? */
+ int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
+ struct sockaddr_in local; /* Local internet address */
+ struct sockaddr_in remote; /* Remote internet address */
+ enum enum_vio_type type; /* Type of connection */
+ char desc[30]; /* String description */
+ void *dest_thd;
+ char *packets, **last_packet;
+ char *where_in_packet, *end_of_packet;
+ my_bool reading;
+ MEM_ROOT root;
+};
+
+/* Initialize the communication buffer */
+
+Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
+{
+ DBUG_ENTER("vio_new");
+ Vio * vio;
+
+ if ((vio= (Vio *) my_malloc(sizeof(*vio),MYF(MY_WME|MY_ZEROFILL))))
+ {
+ init_alloc_root(&vio->root, 8192, 8192);
+ vio->root.min_malloc = sizeof(char *) + 4;
+ vio->last_packet = &vio->packets;
+ }
+ DBUG_RETURN(vio);
+}
+
+
+#ifdef __WIN__
+
+Vio *vio_new_win32pipe(HANDLE hPipe)
+{
+ return (NULL);
+}
+
+#endif
+
+void vio_delete(Vio * vio)
+{
+ DBUG_ENTER("vio_delete");
+ if (vio)
+ {
+ if (vio->type != VIO_CLOSED)
+ vio_close(vio);
+ free_root(&vio->root, MYF(0));
+ my_free((gptr) vio, MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+void vio_reset(Vio *vio)
+{
+ DBUG_ENTER("vio_reset");
+ free_root(&vio->root, MYF(MY_KEEP_PREALLOC));
+ vio->packets = vio->where_in_packet = vio->end_of_packet = 0;
+ vio->last_packet = &vio->packets;
+ DBUG_VOID_RETURN;
+}
+
+int vio_errno(Vio *vio __attribute__((unused)))
+{
+ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+}
+
+int vio_read(Vio * vio, gptr buf, int size)
+{
+ vio->reading = 1;
+ if (vio->where_in_packet >= vio->end_of_packet)
+ {
+ DBUG_ASSERT(vio->packets);
+ vio->where_in_packet = vio->packets + sizeof(char *) + 4;
+ vio->end_of_packet = vio->where_in_packet +
+ uint4korr(vio->packets + sizeof(char *));
+ vio->packets = *(char **)vio->packets;
+ }
+ if (vio->where_in_packet + size > vio->end_of_packet)
+ size = vio->end_of_packet - vio->where_in_packet;
+ memcpy(buf, vio->where_in_packet, size);
+ vio->where_in_packet += size;
+ return (size);
+}
+
+int vio_write(Vio * vio, const gptr buf, int size)
+{
+ DBUG_ENTER("vio_write");
+ char *packet;
+ if (vio->reading)
+ {
+ vio->reading = 0;
+ vio_reset(vio);
+ }
+ if ((packet = alloc_root(&vio->root, sizeof(char*) + 4 + size)))
+ {
+ *vio->last_packet = packet;
+ vio->last_packet = (char **)packet;
+ *((char **)packet) = 0; /* Set forward link to 0 */
+ packet += sizeof(char *);
+ int4store(packet, size);
+ memcpy(packet + 4, buf, size);
+ }
+ else
+ size= -1;
+ DBUG_RETURN(size);
+}
+
+int vio_blocking(Vio * vio, my_bool set_blocking_mode)
+{
+ return (0);
+}
+
+my_bool
+vio_is_blocking(Vio * vio)
+{
+ return(0);
+}
+
+int vio_fastsend(Vio * vio)
+{
+ return(0);
+}
+
+int vio_keepalive(Vio* vio, my_bool set_keep_alive)
+{
+ return (0);
+}
+
+
+my_bool
+vio_should_retry(Vio * vio __attribute__((unused)))
+{
+ int en = socket_errno;
+ return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
+ en == SOCKET_EWOULDBLOCK);
+}
+
+
+int vio_close(Vio * vio)
+{
+ return(0);
+}
+
+
+const char *vio_description(Vio * vio)
+{
+ return "embedded vio";
+}
+
+enum enum_vio_type vio_type(Vio* vio)
+{
+ return VIO_CLOSED;
+}
+
+my_socket vio_fd(Vio* vio)
+{
+ return 0;
+}
+
+
+my_bool vio_peer_addr(Vio * vio, char *buf)
+{
+ return(0);
+}
+
+
+void vio_in_addr(Vio *vio, struct in_addr *in)
+{
+}
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+ return 0;
+}
+
+#endif /* HAVE_VIO */
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
new file mode 100644
index 00000000000..3fba238a8bf
--- /dev/null
+++ b/libmysqld/libmysqld.c
@@ -0,0 +1,2092 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "embedded_priv.h"
+#include <my_sys.h>
+#include <mysys_err.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "errmsg.h"
+#include <violite.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <time.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#if !defined(MSDOS) && !defined(__WIN__)
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifdef HAVE_SELECT_H
+# include <select.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
+
+static my_bool mysql_client_init=0;
+uint mysql_port=0;
+my_string mysql_unix_port=0;
+
+#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
+
+#if defined(MSDOS) || defined(__WIN__)
+#define ERRNO WSAGetLastError()
+#define perror(A)
+#else
+#include <errno.h>
+#define ERRNO errno
+#define SOCKET_ERROR -1
+#define closesocket(A) close(A)
+#endif
+
+static void mysql_once_init(void);
+static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,
+ uint field_count);
+static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
+ ulong *lengths);
+static void end_server(MYSQL *mysql);
+static void read_user_name(char *name);
+static void append_wild(char *to,char *end,const char *wild);
+static int send_file_to_server(MYSQL *mysql,const char *filename);
+static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
+ const char *from, ulong length);
+
+#define init_sigpipe_variables
+#define set_sigpipe(mysql)
+#define reset_sigpipe(mysql)
+
+/*****************************************************************************
+** read a packet from server. Give error message if socket was down
+** or packet is an error message
+*****************************************************************************/
+
+ulong
+net_safe_read(MYSQL *mysql)
+{
+ NET *net= &mysql->net;
+ uint len=0;
+ //init_sigpipe_variables
+ /* Don't give sigpipe errors if the client doesn't want them */
+ set_sigpipe(mysql);
+ if (net->vio != 0)
+ len=my_net_read(net);
+ reset_sigpipe(mysql);
+ if (len == packet_error || len == 0)
+ {
+ DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d",
+ vio_description(net->vio),len));
+ end_server(mysql);
+ net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ?
+ CR_NET_PACKET_TOO_LARGE:
+ CR_SERVER_LOST);
+ strmov(net->last_error,ER(net->last_errno));
+ return(packet_error);
+ }
+ if (net->read_pos[0] == 255)
+ {
+
+ if (len > 3)
+ {
+ char *pos=(char*) net->read_pos+1;
+ if (mysql->protocol_version > 9)
+ { /* New client protocol */
+ net->last_errno=uint2korr(pos);
+ pos+=2;
+ len-=2;
+ }
+ else
+ {
+ net->last_errno=CR_UNKNOWN_ERROR;
+ len--;
+ }
+ (void) strmake(net->last_error,(char*) pos,
+ min(len,sizeof(net->last_error)-1));
+ }
+ else
+ {
+ net->last_errno=CR_UNKNOWN_ERROR;
+ (void) strmov(net->last_error,ER(net->last_errno));
+ }
+ DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno,
+ net->last_error));
+ return(packet_error);
+ }
+ return len;
+}
+
+
+/* Get the length of next field. Change parameter to point at fieldstart */
+static ulong
+net_field_length(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (ulong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (ulong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (ulong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+ return (ulong) uint4korr(pos+1);
+}
+
+/* Same as above, but returns ulonglong values */
+
+static my_ulonglong
+net_field_length_ll(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (my_ulonglong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (my_ulonglong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+#ifdef NO_CLIENT_LONGLONG
+ return (my_ulonglong) uint4korr(pos+1);
+#else
+ return (my_ulonglong) uint8korr(pos+1);
+#endif
+}
+
+
+static void free_rows(MYSQL_DATA *cur)
+{
+ if (cur)
+ {
+ free_root(&cur->alloc,MYF(0));
+ my_free((gptr) cur,MYF(0));
+ }
+}
+
+
+int
+simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
+ ulong length, my_bool skipp_check)
+{
+ NET *net= &mysql->net;
+ int result= -1;
+
+ /* Check that we are calling the client functions in right order */
+ if (mysql->status != MYSQL_STATUS_READY)
+ {
+ strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ goto end;
+ }
+
+ /* Clear result variables */
+ mysql->net.last_error[0]=0;
+ mysql->net.last_errno=0;
+ mysql->info=0;
+ mysql->affected_rows= ~(my_ulonglong) 0;
+
+ /* Clear receive buffer and vio packet list */
+ net_clear(net);
+ vio_reset(net->vio);
+
+ result = lib_dispatch_command(command, net, arg,length);
+ if (!skipp_check)
+ result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?
+ -1 : 0);
+ end:
+ return result;
+}
+
+
+static void free_old_query(MYSQL *mysql)
+{
+ DBUG_ENTER("free_old_query");
+ if (mysql->fields)
+ free_root(&mysql->field_alloc,MYF(0));
+ init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */
+ mysql->fields=0;
+ mysql->field_count=0; /* For API */
+ DBUG_VOID_RETURN;
+}
+
+#ifdef HAVE_GETPWUID
+struct passwd *getpwuid(uid_t);
+char* getlogin(void);
+#endif
+
+#if !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__)
+static void read_user_name(char *name)
+{
+ DBUG_ENTER("read_user_name");
+ if (geteuid() == 0)
+ (void) strmov(name,"root"); /* allow use of surun */
+ else
+ {
+#ifdef HAVE_GETPWUID
+ struct passwd *skr;
+ const char *str;
+/*#ifdef __cplusplus
+ extern "C" struct passwd *getpwuid(uid_t);
+ extern "C" { char* getlogin(void); }
+#else
+ char * getlogin();
+ struct passwd *getpwuid(uid_t);
+#endif
+*/
+ if ((str=getlogin()) == NULL)
+ {
+ if ((skr=getpwuid(geteuid())) != NULL)
+ str=skr->pw_name;
+ else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
+ !(str=getenv("LOGIN")))
+ str="UNKNOWN_USER";
+ }
+ (void) strmake(name,str,USERNAME_LENGTH);
+#elif HAVE_CUSERID
+ (void) cuserid(name);
+#else
+ strmov(name,"UNKNOWN_USER");
+#endif
+ }
+ DBUG_VOID_RETURN;
+}
+
+#else /* If MSDOS || VMS */
+
+static void read_user_name(char *name)
+{
+ char *str=getenv("USER");
+ strmov(name,str ? str : "ODBC"); /* ODBC will send user variable */
+}
+
+#endif
+
+#ifdef __WIN__
+static my_bool is_NT(void)
+{
+ char *os=getenv("OS");
+ return (os && !strcmp(os, "Windows_NT")) ? 1 : 0;
+}
+#endif
+
+/*
+** Expand wildcard to a sql string
+*/
+
+static void
+append_wild(char *to, char *end, const char *wild)
+{
+ end-=5; /* Some extra */
+ if (wild && wild[0])
+ {
+ to=strmov(to," like '");
+ while (*wild && to < end)
+ {
+ if (*wild == '\\' || *wild == '\'')
+ *to++='\\';
+ *to++= *wild++;
+ }
+ if (*wild) /* Too small buffer */
+ *to++='%'; /* Nicer this way */
+ to[0]='\'';
+ to[1]=0;
+ }
+}
+
+
+
+/**************************************************************************
+** Init debugging if MYSQL_DEBUG environment variable is found
+**************************************************************************/
+
+void STDCALL
+mysql_debug(const char *debug)
+{
+#ifndef DBUG_OFF
+ char *env;
+ if (_db_on_)
+ return; /* Already using debugging */
+ if (debug)
+ {
+ DEBUGGER_ON;
+ DBUG_PUSH(debug);
+ }
+ else if ((env = getenv("MYSQL_DEBUG")))
+ {
+ DEBUGGER_ON;
+ DBUG_PUSH(env);
+#if !defined(_WINVER) && !defined(WINVER)
+ puts("\n-------------------------------------------------------");
+ puts("MYSQL_DEBUG found. libmysql started with the following:");
+ puts(env);
+ puts("-------------------------------------------------------\n");
+#else
+ {
+ char buff[80];
+ strmov(strmov(buff,"libmysql: "),env);
+ MessageBox((HWND) 0,"Debugging variable MYSQL_DEBUG used",buff,MB_OK);
+ }
+#endif
+ }
+#endif
+}
+
+/**************************************************************************
+** Shut down connection
+**************************************************************************/
+
+static void
+end_server(MYSQL *mysql)
+{
+ DBUG_ENTER("end_server");
+ if (mysql->net.vio != 0)
+ {
+ end_embedded_connection(&mysql->net);
+ mysql->net.vio= 0; /* Marker */
+ }
+ net_end(&mysql->net);
+ free_old_query(mysql);
+ DBUG_VOID_RETURN;
+}
+
+
+void STDCALL
+mysql_free_result(MYSQL_RES *result)
+{
+ DBUG_ENTER("mysql_free_result");
+ DBUG_PRINT("enter",("mysql_res: %lx",result));
+ if (result)
+ {
+ if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT)
+ {
+ DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows"));
+ for (;;)
+ {
+ uint pkt_len;
+ if ((pkt_len=(uint) net_safe_read(result->handle)) == packet_error)
+ break;
+ if (pkt_len == 1 && result->handle->net.read_pos[0] == 254)
+ break; /* End of data */
+ }
+ result->handle->status=MYSQL_STATUS_READY;
+ }
+ free_rows(result->data);
+ if (result->fields)
+ free_root(&result->field_alloc,MYF(0));
+ if (result->row)
+ my_free((gptr) result->row,MYF(0));
+ my_free((gptr) result,MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/****************************************************************************
+** Get options from my.cnf
+****************************************************************************/
+
+static const char *default_options[]=
+{"port","socket","compress","password","pipe", "timeout", "user",
+ "init-command", "host", "database", "debug", "return-found-rows",
+ "ssl_key" ,"ssl_cert" ,"ssl_ca" ,"ssl_capath",
+ "character-set-dir", "default-character-set",
+ NullS
+};
+
+static TYPELIB option_types={array_elements(default_options)-1,
+ "options",default_options};
+
+static void mysql_read_default_options(struct st_mysql_options *options,
+ const char *filename,const char *group)
+{
+ int argc;
+ char *argv_buff[1],**argv;
+ const char *groups[3];
+ DBUG_ENTER("mysql_read_default_options");
+ DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL"));
+
+ argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
+ groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
+
+ load_defaults(filename, groups, &argc, &argv);
+ if (argc != 1) /* If some default option */
+ {
+ char **option=argv;
+ while (*++option)
+ {
+ /* DBUG_PRINT("info",("option: %s",option[0])); */
+ if (option[0][0] == '-' && option[0][1] == '-')
+ {
+ char *end=strcend(*option,'=');
+ char *opt_arg=0;
+ if (*end)
+ {
+ opt_arg=end+1;
+ *end=0; /* Remove '=' */
+ }
+ switch (find_type(*option+2,&option_types,2)) {
+ case 1: /* port */
+ if (opt_arg)
+ options->port=atoi(opt_arg);
+ break;
+ case 2: /* socket */
+ if (opt_arg)
+ {
+ my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
+ options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 3: /* compress */
+ options->compress=1;
+ break;
+ case 4: /* password */
+ if (opt_arg)
+ {
+ my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
+ options->password=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 5: /* pipe */
+ options->named_pipe=1; /* Force named pipe */
+ break;
+ case 6: /* timeout */
+ if (opt_arg)
+ options->connect_timeout=atoi(opt_arg);
+ break;
+ case 7: /* user */
+ if (opt_arg)
+ {
+ my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
+ options->user=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 8: /* init-command */
+ if (opt_arg)
+ {
+ my_free(options->init_command,MYF(MY_ALLOW_ZERO_PTR));
+ options->init_command=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 9: /* host */
+ if (opt_arg)
+ {
+ my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
+ options->host=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 10: /* database */
+ if (opt_arg)
+ {
+ my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
+ options->db=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 11: /* debug */
+ mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace");
+ break;
+ case 12: /* return-found-rows */
+ options->client_flag|=CLIENT_FOUND_ROWS;
+ break;
+ case 13: /* Ignore SSL options */
+ case 14:
+ case 15:
+ case 16:
+ break;
+ case 17: /* charset-lib */
+ my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
+ options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
+ break;
+ case 18:
+ my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
+ options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
+ break;
+ default:
+ DBUG_PRINT("warning",("unknown option: %s",option[0]));
+ }
+ }
+ }
+ }
+ free_defaults(argv);
+ DBUG_VOID_RETURN;
+}
+
+
+/***************************************************************************
+** Change field rows to field structs
+***************************************************************************/
+
+static MYSQL_FIELD *
+unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
+ my_bool default_value, my_bool long_flag_protocol)
+{
+ MYSQL_ROWS *row;
+ MYSQL_FIELD *field,*result;
+ DBUG_ENTER("unpack_fields");
+
+ field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields);
+ if (!result)
+ DBUG_RETURN(0);
+
+ for (row=data->data; row ; row = row->next,field++)
+ {
+ field->table= strdup_root(alloc,(char*) row->data[0]);
+ field->name= strdup_root(alloc,(char*) row->data[1]);
+ field->length= (uint) uint3korr(row->data[2]);
+ field->type= (enum enum_field_types) (uchar) row->data[3][0];
+ if (long_flag_protocol)
+ {
+ field->flags= uint2korr(row->data[4]);
+ field->decimals=(uint) (uchar) row->data[4][2];
+ }
+ else
+ {
+ field->flags= (uint) (uchar) row->data[4][0];
+ field->decimals=(uint) (uchar) row->data[4][1];
+ }
+ if (INTERNAL_NUM_FIELD(field))
+ field->flags|= NUM_FLAG;
+ if (default_value && row->data[5])
+ field->def=strdup_root(alloc,(char*) row->data[5]);
+ else
+ field->def=0;
+ field->max_length= 0;
+ }
+ free_rows(data); /* Free old data */
+ DBUG_RETURN(result);
+}
+
+
+/* Read all rows (fields or data) from server */
+
+static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ uint fields)
+{
+ uint field,pkt_len;
+ ulong len;
+ uchar *cp;
+ char *to;
+ MYSQL_DATA *result;
+ MYSQL_ROWS **prev_ptr,*cur;
+ NET *net = &mysql->net;
+ DBUG_ENTER("read_rows");
+
+ if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(0);
+ if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
+ result->alloc.min_malloc=sizeof(MYSQL_ROWS);
+ prev_ptr= &result->data;
+ result->rows=0;
+ result->fields=fields;
+
+ while (*(cp=net->read_pos) != 254 || pkt_len != 1)
+ {
+ result->rows++;
+ if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
+ sizeof(MYSQL_ROWS))) ||
+ !(cur->data= ((MYSQL_ROW)
+ alloc_root(&result->alloc,
+ (fields+1)*sizeof(char *)+pkt_len))))
+ {
+ free_rows(result);
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ *prev_ptr=cur;
+ prev_ptr= &cur->next;
+ to= (char*) (cur->data+fields+1);
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
+ { /* null field */
+ cur->data[field] = 0;
+ }
+ else
+ {
+ cur->data[field] = to;
+ memcpy(to,(char*) cp,len); to[len]=0;
+ to+=len+1;
+ cp+=len;
+ if (mysql_fields)
+ {
+ if (mysql_fields[field].max_length < len)
+ mysql_fields[field].max_length=len;
+ }
+ }
+ }
+ cur->data[field]=to; /* End of last field */
+ if ((pkt_len=net_safe_read(mysql)) == packet_error)
+ {
+ free_rows(result);
+ DBUG_RETURN(0);
+ }
+ }
+ *prev_ptr=0; /* last pointer is null */
+ DBUG_PRINT("exit",("Got %d rows",result->rows));
+ DBUG_RETURN(result);
+}
+
+
+/*
+** Read one row. Uses packet buffer as storage for fields.
+** When next packet is read, the previous field values are destroyed
+*/
+
+
+static int
+read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
+{
+ uint field;
+ ulong pkt_len,len;
+ uchar *pos,*prev_pos;
+
+ if ((pkt_len=net_safe_read(mysql)) == packet_error)
+ return -1;
+ if (pkt_len == 1 && mysql->net.read_pos[0] == 254)
+ return 1; /* End of data */
+ prev_pos= 0; /* allowed to write at packet[-1] */
+ pos=mysql->net.read_pos;
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
+ { /* null field */
+ row[field] = 0;
+ *lengths++=0;
+ }
+ else
+ {
+ row[field] = (char*) pos;
+ pos+=len;
+ *lengths++=len;
+ }
+ if (prev_pos)
+ *prev_pos=0; /* Terminate prev field */
+ prev_pos=pos;
+ }
+ row[field]=(char*) prev_pos+1; /* End of last field */
+ *prev_pos=0; /* Terminate last field */
+ return 0;
+}
+
+/****************************************************************************
+** Init MySQL structure or allocate one
+****************************************************************************/
+
+MYSQL * STDCALL
+mysql_init(MYSQL *mysql)
+{
+ mysql_once_init();
+ if (!mysql)
+ {
+ if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
+ return 0;
+ mysql->free_me=1;
+ mysql->net.vio = 0;
+ }
+ else
+ bzero((char*) (mysql),sizeof(*(mysql)));
+ return mysql;
+}
+
+
+static void mysql_once_init()
+{
+ if (!mysql_client_init)
+ {
+ mysql_client_init=1;
+ my_init(); /* Will init threads */
+ init_client_errs();
+ mysql_port = MYSQL_PORT;
+ mysql_debug(NullS);
+ }
+#ifdef THREAD
+ else
+ my_thread_init(); /* Init if new thread */
+#endif
+}
+
+/**************************************************************************
+** Connect to sql server
+** If host == 0 then use localhost
+**************************************************************************/
+
+MYSQL * STDCALL
+mysql_connect(MYSQL *mysql,const char *host,
+ const char *user, const char *passwd)
+{
+ MYSQL *res;
+ mysql=mysql_init(mysql); /* Make it thread safe */
+ {
+ DBUG_ENTER("mysql_connect");
+ if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0)))
+ {
+ if (mysql->free_me)
+ my_free((gptr) mysql,MYF(0));
+ }
+ DBUG_RETURN(res);
+ }
+}
+
+
+/*
+** Note that the mysql argument must be initialized with mysql_init()
+** before calling mysql_real_connect !
+*/
+
+MYSQL * STDCALL
+mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag)
+{
+ char buff[100],charset_name_buff[16],*end,*host_info, *charset_name;
+ uint pkt_length;
+ ulong max_allowed_packet;
+ NET *net= &mysql->net;
+ DBUG_ENTER("mysql_real_connect");
+ DBUG_PRINT("enter",("host: %s db: %s user: %s",
+ host ? host : "(Null)",
+ db ? db : "(Null)",
+ user ? user : "(Null)"));
+
+ net->vio = 0; /* If something goes wrong */
+ /* use default options */
+ if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
+ {
+ mysql_read_default_options(&mysql->options,
+ (mysql->options.my_cnf_file ?
+ mysql->options.my_cnf_file : "my"),
+ mysql->options.my_cnf_group);
+ my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
+ }
+
+ /* Some empty-string-tests are done because of ODBC */
+ if (!host || !host[0])
+ host=mysql->options.host;
+ if (!user || !user[0])
+ user=mysql->options.user;
+ if (!passwd)
+ {
+ passwd=mysql->options.password;
+ }
+ if (!db || !db[0])
+ db=mysql->options.db;
+ port=0;
+ unix_socket=0;
+ mysql->reconnect=1; /* Reconnect as default */
+ mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
+ host_info=(char*) ER(CR_EMBEDDED_CONNECTION);
+ if (my_net_init(net, net->vio))
+ {
+ vio_delete(net->vio);
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
+
+ /* Get version info */
+ mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
+ start_embedded_connection(net);
+
+ if ((pkt_length=net_safe_read(mysql)) == packet_error)
+ goto error;
+
+ /* Check if version of protocoll matches current one */
+
+ mysql->protocol_version= net->read_pos[0];
+ DBUG_DUMP("packet",(char*) net->read_pos,10);
+ DBUG_PRINT("info",("mysql protocol version %d, server=%d",
+ PROTOCOL_VERSION, mysql->protocol_version));
+ if (mysql->protocol_version != PROTOCOL_VERSION &&
+ mysql->protocol_version != PROTOCOL_VERSION-1)
+ {
+ net->last_errno= CR_VERSION_ERROR;
+ sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version,
+ PROTOCOL_VERSION);
+ goto error;
+ }
+ end=strend((char*) net->read_pos+1);
+ mysql->thread_id=uint4korr(end+1);
+ end+=5;
+ strmake(mysql->scramble_buff,end,8);
+ end+=9;
+ if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
+ mysql->server_capabilities=uint2korr(end);
+ if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
+ {
+ /* New protocol with 16 bytes to describe server characteristics */
+ mysql->server_language=end[2];
+ mysql->server_status=uint2korr(end+3);
+ }
+
+ /* Set character set */
+ if ((charset_name=mysql->options.charset_name))
+ {
+ const char *save=charsets_dir;
+ if (mysql->options.charset_dir)
+ charsets_dir=mysql->options.charset_dir;
+ mysql->charset=get_charset_by_name(mysql->options.charset_name,
+ MYF(MY_WME));
+ charsets_dir=save;
+ }
+ else if (mysql->server_language)
+ {
+ charset_name=charset_name_buff;
+ sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */
+ mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME));
+ }
+ else
+ mysql->charset=default_charset_info;
+
+ if (!mysql->charset)
+ {
+ net->last_errno=CR_CANT_READ_CHARSET;
+ if (mysql->options.charset_dir)
+ sprintf(net->last_error,ER(net->last_errno),
+ charset_name ? charset_name : "unknown",
+ mysql->options.charset_dir);
+ else
+ {
+ char cs_dir_name[FN_REFLEN];
+ get_charsets_dir(cs_dir_name);
+ sprintf(net->last_error,ER(net->last_errno),
+ charset_name ? charset_name : "unknown",
+ cs_dir_name);
+ }
+ goto error;
+ }
+
+ /* Save connection information */
+ if (!user) user="";
+ if (!passwd) passwd="";
+ host=LOCAL_HOST;
+ if (!my_multi_malloc(MYF(0),
+ &mysql->host_info, (uint) strlen(host_info)+1,
+ &mysql->host, (uint) strlen(host)+1,
+ &mysql->unix_socket,unix_socket ?
+ (uint) strlen(unix_socket)+1 : (uint) 1,
+ &mysql->server_version,
+ (uint) (end - (char*) net->read_pos),
+ NullS) ||
+ !(mysql->user=my_strdup(user,MYF(0))) ||
+ !(mysql->passwd=my_strdup(passwd,MYF(0))))
+ {
+ strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
+ goto error;
+ }
+ strmov(mysql->host_info,host_info);
+ strmov(mysql->host,host);
+ if (unix_socket)
+ strmov(mysql->unix_socket,unix_socket);
+ else
+ mysql->unix_socket=0;
+ strmov(mysql->server_version,(char*) net->read_pos+1);
+ mysql->port=port;
+ mysql->client_flag=client_flag | mysql->options.client_flag;
+ DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d",
+ mysql->server_version,mysql->server_capabilities,
+ mysql->server_status));
+
+ /* Send client information for access check */
+ client_flag|=CLIENT_CAPABILITIES;
+ client_flag&= ~CLIENT_COMPRESS;
+ if (db)
+ client_flag|=CLIENT_CONNECT_WITH_DB;
+ int2store(buff,client_flag);
+ mysql->client_flag=client_flag;
+
+ max_allowed_packet=net->max_packet_size;
+ int3store(buff+2,max_allowed_packet);
+ if (user && user[0])
+ strmake(buff+5,user,32);
+ else
+ read_user_name((char*) buff+5);
+#ifdef _CUSTOMCONFIG_
+#include "_cust_libmysql.h";
+#endif
+ DBUG_PRINT("info",("user: %s",buff+5));
+ end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
+ (my_bool) (mysql->protocol_version == 9));
+
+ if (db)
+ {
+ end=strmov(end+1,db);
+ mysql->db=my_strdup(db,MYF(MY_WME));
+ db=0;
+ }
+ if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
+ goto error;
+
+ lib_connection_phase(net,2);
+
+ if( net_safe_read(mysql) == packet_error)
+ goto error;
+ if (db && mysql_select_db(mysql,db))
+ goto error;
+ if (mysql->options.init_command)
+ {
+ my_bool reconnect=mysql->reconnect;
+ mysql->reconnect=0;
+ if (mysql_query(mysql,mysql->options.init_command))
+ goto error;
+ mysql_free_result(mysql_use_result(mysql));
+ mysql->reconnect=reconnect;
+ }
+
+ DBUG_PRINT("exit",("Mysql handler: %lx",mysql));
+ reset_sigpipe(mysql);
+ DBUG_RETURN(mysql);
+
+error:
+ reset_sigpipe(mysql);
+ DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error));
+ {
+ /* Free alloced memory */
+ my_bool free_me=mysql->free_me;
+ end_server(mysql);
+ mysql->free_me=0;
+ mysql_close(mysql);
+ mysql->free_me=free_me;
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**************************************************************************
+** Change user and database
+**************************************************************************/
+
+my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
+ const char *passwd, const char *db)
+{
+ char buff[512],*pos=buff;
+ DBUG_ENTER("mysql_change_user");
+
+ if (!user)
+ user="";
+ if (!passwd)
+ passwd="";
+
+ pos=strmov(pos,user)+1;
+ pos=scramble(pos, mysql->scramble_buff, passwd,
+ (my_bool) (mysql->protocol_version == 9));
+ pos=strmov(pos+1,db ? db : "");
+ if (simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (pos-buff),0))
+ DBUG_RETURN(1);
+
+ my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+
+ mysql->user= my_strdup(user,MYF(MY_WME));
+ mysql->passwd=my_strdup(passwd,MYF(MY_WME));
+ mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
+ DBUG_RETURN(0);
+}
+
+
+/**************************************************************************
+** Set current database
+**************************************************************************/
+
+int STDCALL
+mysql_select_db(MYSQL *mysql, const char *db)
+{
+ int error;
+ DBUG_ENTER("mysql_select_db");
+ DBUG_PRINT("enter",("db: '%s'",db));
+
+ if ((error=simple_command(mysql,COM_INIT_DB,db,(ulong) strlen(db),0)))
+ DBUG_RETURN(error);
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->db=my_strdup(db,MYF(MY_WME));
+ DBUG_RETURN(0);
+}
+
+
+/*************************************************************************
+** Send a QUIT to the server and close the connection
+** If handle is alloced by mysql connect free it.
+*************************************************************************/
+
+void STDCALL
+mysql_close(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_close");
+ if (mysql) /* Some simple safety */
+ {
+ if (mysql->net.vio != 0)
+ {
+ free_old_query(mysql);
+ mysql->status=MYSQL_STATUS_READY; /* Force command */
+ simple_command(mysql,COM_QUIT,"",0,1);
+ end_server(mysql);
+ }
+ my_free((gptr) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.db,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
+ /* Clear pointers for better safety */
+ mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
+ bzero((char*) &mysql->options,sizeof(mysql->options));
+ mysql->net.vio = 0;
+#ifdef HAVE_OPENSSL
+ ((VioConnectorFd*)(mysql->connector_fd))->delete();
+ mysql->connector_fd = 0;
+#endif /* HAVE_OPENSSL */
+ if (mysql->free_me)
+ my_free((gptr) mysql,MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/**************************************************************************
+** Do a query. If query returned rows, free old rows.
+** Read data by mysql_store_result or by repeat call of mysql_fetch_row
+**************************************************************************/
+
+int STDCALL
+mysql_query(MYSQL *mysql, const char *query)
+{
+ return mysql_real_query(mysql,query, (ulong) strlen(query));
+}
+
+int STDCALL
+mysql_send_query(MYSQL* mysql, const char* query, ulong length)
+{
+ return simple_command(mysql, COM_QUERY, query, length, 1);
+}
+
+
+int STDCALL
+mysql_read_query_result(MYSQL *mysql)
+{
+ uchar *pos;
+ ulong field_count;
+ MYSQL_DATA *fields;
+ uint length;
+ DBUG_ENTER("mysql_read_query_result");
+
+ if ((length=net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(-1);
+ free_old_query(mysql); /* Free old result */
+get_info:
+ pos=(uchar*) mysql->net.read_pos;
+ if ((field_count= net_field_length(&pos)) == 0)
+ {
+ mysql->affected_rows= net_field_length_ll(&pos);
+ mysql->insert_id= net_field_length_ll(&pos);
+ if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
+ {
+ mysql->server_status=uint2korr(pos); pos+=2;
+ }
+ if (pos < mysql->net.read_pos+length && net_field_length(&pos))
+ mysql->info=(char*) pos;
+ DBUG_RETURN(0);
+ }
+ if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
+ {
+ int error=send_file_to_server(mysql,(char*) pos);
+ if ((length=net_safe_read(mysql)) == packet_error || error)
+ DBUG_RETURN(-1);
+ goto get_info; /* Get info packet */
+ }
+ if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
+ mysql->server_status|= SERVER_STATUS_IN_TRANS;
+
+ mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
+ if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
+ DBUG_RETURN(-1);
+ if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
+ (uint) field_count,0,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG))))
+ DBUG_RETURN(-1);
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ mysql->field_count=field_count;
+ DBUG_RETURN(0);
+}
+
+/****************************************************************************
+* A modified version of connect(). connect2() allows you to specify
+* a timeout value, in seconds, that we should wait until we
+* derermine we can't connect to a particular host. If timeout is 0,
+* my_connect() will behave exactly like connect().
+*
+* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
+*****************************************************************************/
+
+int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
+ uint timeout)
+{
+#if defined(__WIN__) || defined(OS2)
+ return connect(s, (struct sockaddr*) name, namelen);
+#else
+ int flags, res, s_err;
+ SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
+ fd_set sfds;
+ struct timeval tv;
+ time_t start_time, now_time;
+
+ /* If they passed us a timeout of zero, we should behave
+ * exactly like the normal connect() call does.
+ */
+
+ if (timeout == 0)
+ return connect(s, (struct sockaddr*) name, namelen);
+
+ flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
+#ifdef O_NONBLOCK
+ fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
+#endif
+
+ res = connect(s, (struct sockaddr*) name, namelen);
+ s_err = errno; /* Save the error... */
+ fcntl(s, F_SETFL, flags);
+ if ((res != 0) && (s_err != EINPROGRESS))
+ {
+ errno = s_err; /* Restore it */
+ return(-1);
+ }
+ if (res == 0) /* Connected quickly! */
+ return(0);
+
+ /* Otherwise, our connection is "in progress." We can use
+ * the select() call to wait up to a specified period of time
+ * for the connection to suceed. If select() returns 0
+ * (after waiting howevermany seconds), our socket never became
+ * writable (host is probably unreachable.) Otherwise, if
+ * select() returns 1, then one of two conditions exist:
+ *
+ * 1. An error occured. We use getsockopt() to check for this.
+ * 2. The connection was set up sucessfully: getsockopt() will
+ * return 0 as an error.
+ *
+ * Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
+ * who posted this method of timing out a connect() in
+ * comp.unix.programmer on August 15th, 1997.
+ */
+
+ FD_ZERO(&sfds);
+ FD_SET(s, &sfds);
+ /*
+ * select could be interrupted by a signal, and if it is,
+ * the timeout should be adjusted and the select restarted
+ * to work around OSes that don't restart select and
+ * implementations of select that don't adjust tv upon
+ * failure to reflect the time remaining
+ */
+ start_time = time(NULL);
+ for (;;)
+ {
+ tv.tv_sec = (long) timeout;
+ tv.tv_usec = 0;
+ if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0)
+ break;
+ now_time=time(NULL);
+ timeout-= (uint) (now_time - start_time);
+ if (errno != EINTR || (int) timeout <= 0)
+ return -1;
+ }
+
+ /* select() returned something more interesting than zero, let's
+ * see if we have any errors. If the next two statements pass,
+ * we've got an open socket!
+ */
+
+ s_err=0;
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
+ return(-1);
+
+ if (s_err)
+ { /* getsockopt could succeed */
+ errno = s_err;
+ return(-1); /* but return an error... */
+ }
+ return(0); /* It's all good! */
+#endif
+}
+
+
+int STDCALL
+mysql_real_query(MYSQL *mysql, const char *query, ulong length)
+{
+ DBUG_ENTER("mysql_real_query");
+ DBUG_PRINT("enter",("handle: %lx",mysql));
+ DBUG_PRINT("query",("Query = \"%s\"",query));
+ if (mysql_send_query(mysql, query, length))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(mysql_read_query_result(mysql));
+}
+
+
+static int
+send_file_to_server(MYSQL *mysql, const char *filename)
+{
+ int fd, readcount;
+ char buf[IO_SIZE*15],*tmp_name;
+ DBUG_ENTER("send_file_to_server");
+
+ fn_format(buf,filename,"","",4); /* Convert to client format */
+ if (!(tmp_name=my_strdup(buf,MYF(0))))
+ {
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY));
+ DBUG_RETURN(-1);
+ }
+ if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0)
+ {
+ mysql->net.last_errno=EE_FILENOTFOUND;
+ sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
+ strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
+ my_net_write(&mysql->net,"",0); net_flush(&mysql->net);
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+
+ while ((readcount = (int) my_read(fd,buf,sizeof(buf),MYF(0))) > 0)
+ {
+ if (my_net_write(&mysql->net,buf,readcount))
+ {
+ mysql->net.last_errno=CR_SERVER_LOST;
+ strmov(mysql->net.last_error,ER(mysql->net.last_errno));
+ DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
+ (void) my_close(fd,MYF(0));
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ }
+ (void) my_close(fd,MYF(0));
+ /* Send empty packet to mark end of file */
+ if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net))
+ {
+ mysql->net.last_errno=CR_SERVER_LOST;
+ sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno);
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ if (readcount < 0)
+ {
+ mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */
+ sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
+ strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**************************************************************************
+** Alloc result struct for buffered results. All rows are read to buffer.
+** mysql_data_seek may be used.
+**************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_store_result(MYSQL *mysql)
+{
+ MYSQL_RES *result;
+ DBUG_ENTER("mysql_store_result");
+
+ if (!mysql->fields)
+ DBUG_RETURN(0);
+ if (mysql->status != MYSQL_STATUS_GET_RESULT)
+ {
+ strmov(mysql->net.last_error,
+ ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ DBUG_RETURN(0);
+ }
+ mysql->status=MYSQL_STATUS_READY; /* server is ready */
+ if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
+ sizeof(ulong)*mysql->field_count,
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ mysql->net.last_errno=CR_OUT_OF_MEMORY;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ DBUG_RETURN(0);
+ }
+ result->eof=1; /* Marker for buffered */
+ result->lengths=(ulong*) (result+1);
+ if (!(result->data=read_rows(mysql,mysql->fields,mysql->field_count)))
+ {
+ my_free((gptr) result,MYF(0));
+ DBUG_RETURN(0);
+ }
+ mysql->affected_rows= result->row_count= result->data->rows;
+ result->data_cursor= result->data->data;
+ result->fields= mysql->fields;
+ result->field_alloc= mysql->field_alloc;
+ result->field_count= mysql->field_count;
+ result->current_field=0;
+ result->current_row=0; /* Must do a fetch first */
+ mysql->fields=0; /* fields is now in result */
+ DBUG_RETURN(result); /* Data fetched */
+}
+
+
+/**************************************************************************
+** Alloc struct for use with unbuffered reads. Data is fetched by domand
+** when calling to mysql_fetch_row.
+** mysql_data_seek is a noop.
+**
+** No other queries may be specified with the same MYSQL handle.
+** There shouldn't be much processing per row because mysql server shouldn't
+** have to wait for the client (and will not wait more than 30 sec/packet).
+**************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_use_result(MYSQL *mysql)
+{
+ MYSQL_RES *result;
+ DBUG_ENTER("mysql_use_result");
+
+ if (!mysql->fields)
+ DBUG_RETURN(0);
+ if (mysql->status != MYSQL_STATUS_GET_RESULT)
+ {
+ strmov(mysql->net.last_error,
+ ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ DBUG_RETURN(0);
+ }
+ if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
+ sizeof(ulong)*mysql->field_count,
+ MYF(MY_WME | MY_ZEROFILL))))
+ DBUG_RETURN(0);
+ result->lengths=(ulong*) (result+1);
+ if (!(result->row=(MYSQL_ROW)
+ my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME))))
+ { /* Ptrs: to one row */
+ my_free((gptr) result,MYF(0));
+ DBUG_RETURN(0);
+ }
+ result->fields= mysql->fields;
+ result->field_alloc= mysql->field_alloc;
+ result->field_count= mysql->field_count;
+ result->current_field=0;
+ result->handle= mysql;
+ result->current_row= 0;
+ mysql->fields=0; /* fields is now in result */
+ mysql->status=MYSQL_STATUS_USE_RESULT;
+ DBUG_RETURN(result); /* Data is read to be fetched */
+}
+
+
+
+/**************************************************************************
+** Return next field of the query results
+**************************************************************************/
+
+MYSQL_FIELD * STDCALL
+mysql_fetch_field(MYSQL_RES *result)
+{
+ if (result->current_field >= result->field_count)
+ return(NULL);
+ return &result->fields[result->current_field++];
+}
+
+
+/**************************************************************************
+** Return next row of the query results
+**************************************************************************/
+
+MYSQL_ROW STDCALL
+mysql_fetch_row(MYSQL_RES *res)
+{
+ DBUG_ENTER("mysql_fetch_row");
+ if (!res->data)
+ { /* Unbufferred fetch */
+ if (!res->eof)
+ {
+ if (!(read_one_row(res->handle,res->field_count,res->row, res->lengths)))
+ {
+ res->row_count++;
+ DBUG_RETURN(res->current_row=res->row);
+ }
+ else
+ {
+ DBUG_PRINT("info",("end of data"));
+ res->eof=1;
+ res->handle->status=MYSQL_STATUS_READY;
+ }
+ }
+ DBUG_RETURN((MYSQL_ROW) NULL);
+ }
+ {
+ MYSQL_ROW tmp;
+ if (!res->data_cursor)
+ {
+ DBUG_PRINT("info",("end of data"));
+ DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
+ }
+ tmp = res->data_cursor->data;
+ res->data_cursor = res->data_cursor->next;
+ DBUG_RETURN(res->current_row=tmp);
+ }
+}
+
+/**************************************************************************
+** Get column lengths of the current row
+** If one uses mysql_use_result, res->lengths contains the length information,
+** else the lengths are calculated from the offset between pointers.
+**************************************************************************/
+
+ulong * STDCALL
+mysql_fetch_lengths(MYSQL_RES *res)
+{
+ ulong *lengths,*prev_length;
+ byte *start;
+ MYSQL_ROW column,end;
+
+ if (!(column=res->current_row))
+ return 0; /* Something is wrong */
+ if (res->data)
+ {
+ start=0;
+ prev_length=0; /* Keep gcc happy */
+ lengths=res->lengths;
+ for (end=column+res->field_count+1 ; column != end ; column++,lengths++)
+ {
+ if (!*column)
+ {
+ *lengths=0; /* Null */
+ continue;
+ }
+ if (start) /* Found end of prev string */
+ *prev_length= (uint) (*column-start-1);
+ start= *column;
+ prev_length=lengths;
+ }
+ }
+ return res->lengths;
+}
+
+/**************************************************************************
+** Move to a specific row and column
+**************************************************************************/
+
+void STDCALL
+mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
+{
+ MYSQL_ROWS *tmp=0;
+ DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
+ if (result->data)
+ for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ;
+ result->current_row=0;
+ result->data_cursor = tmp;
+}
+
+/*************************************************************************
+** put the row or field cursor one a position one got from mysql_row_tell()
+** This doesn't restore any data. The next mysql_fetch_row or
+** mysql_fetch_field will return the next row or field after the last used
+*************************************************************************/
+
+MYSQL_ROW_OFFSET STDCALL
+mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET row)
+{
+ MYSQL_ROW_OFFSET return_value=result->data_cursor;
+ result->current_row= 0;
+ result->data_cursor= row;
+ return return_value;
+}
+
+
+MYSQL_FIELD_OFFSET STDCALL
+mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset)
+{
+ MYSQL_FIELD_OFFSET return_value=result->current_field;
+ result->current_field=field_offset;
+ return return_value;
+}
+
+/*****************************************************************************
+** List all databases
+*****************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_list_dbs(MYSQL *mysql, const char *wild)
+{
+ char buff[255];
+ DBUG_ENTER("mysql_list_dbs");
+
+ append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild);
+ if (mysql_query(mysql,buff))
+ DBUG_RETURN(0);
+ DBUG_RETURN (mysql_store_result(mysql));
+}
+
+
+/*****************************************************************************
+** List all tables in a database
+** If wild is given then only the tables matching wild is returned
+*****************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_list_tables(MYSQL *mysql, const char *wild)
+{
+ char buff[255];
+ DBUG_ENTER("mysql_list_tables");
+
+ append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild);
+ if (mysql_query(mysql,buff))
+ DBUG_RETURN(0);
+ DBUG_RETURN (mysql_store_result(mysql));
+}
+
+
+/**************************************************************************
+** List all fields in a table
+** If wild is given then only the fields matching wild is returned
+** Instead of this use query:
+** show fields in 'table' like "wild"
+**************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
+{
+ MYSQL_RES *result;
+ MYSQL_DATA *query;
+ char buff[257],*end;
+ DBUG_ENTER("mysql_list_fields");
+ DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : ""));
+
+ LINT_INIT(query);
+
+ end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
+ if (simple_command(mysql,COM_FIELD_LIST,buff,(uint) (end-buff),1) ||
+ !(query = read_rows(mysql,(MYSQL_FIELD*) 0,6)))
+ DBUG_RETURN(NULL);
+
+ free_old_query(mysql);
+ if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES),
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ free_rows(query);
+ DBUG_RETURN(NULL);
+ }
+ result->field_alloc=mysql->field_alloc;
+ mysql->fields=0;
+ result->field_count = (uint) query->rows;
+ result->fields= unpack_fields(query,&result->field_alloc,
+ result->field_count,1,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG));
+ result->eof=1;
+ DBUG_RETURN(result);
+}
+
+/* List all running processes (threads) in server */
+
+MYSQL_RES * STDCALL
+mysql_list_processes(MYSQL *mysql)
+{
+ MYSQL_DATA *fields;
+ uint field_count;
+ uchar *pos;
+ DBUG_ENTER("mysql_list_processes");
+
+ LINT_INIT(fields);
+ if (simple_command(mysql,COM_PROCESS_INFO,"",0,0))
+ DBUG_RETURN(0);
+ free_old_query(mysql);
+ pos=(uchar*) mysql->net.read_pos;
+ field_count=(uint) net_field_length(&pos);
+ if (!(fields = read_rows(mysql,(MYSQL_FIELD*) 0,5)))
+ DBUG_RETURN(NULL);
+ if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG))))
+ DBUG_RETURN(0);
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ mysql->field_count=field_count;
+ DBUG_RETURN(mysql_store_result(mysql));
+}
+
+
+int STDCALL
+mysql_create_db(MYSQL *mysql, const char *db)
+{
+ DBUG_ENTER("mysql_createdb");
+ DBUG_PRINT("enter",("db: %s",db));
+ DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (ulong) strlen(db),0));
+}
+
+
+int STDCALL
+mysql_drop_db(MYSQL *mysql, const char *db)
+{
+ DBUG_ENTER("mysql_drop_db");
+ DBUG_PRINT("enter",("db: %s",db));
+ DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(ulong) strlen(db),0));
+}
+
+
+int STDCALL
+mysql_shutdown(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_shutdown");
+ DBUG_RETURN(simple_command(mysql,COM_SHUTDOWN,"",0,0));
+}
+
+
+int STDCALL
+mysql_refresh(MYSQL *mysql,uint options)
+{
+ uchar bits[1];
+ DBUG_ENTER("mysql_refresh");
+ bits[0]= (uchar) options;
+ DBUG_RETURN(simple_command(mysql,COM_REFRESH,(char*) bits,1,0));
+}
+
+int STDCALL
+mysql_kill(MYSQL *mysql,ulong pid)
+{
+ char buff[12];
+ DBUG_ENTER("mysql_kill");
+ int4store(buff,pid);
+ DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,4,0));
+}
+
+
+int STDCALL
+mysql_dump_debug_info(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_dump_debug_info");
+ DBUG_RETURN(simple_command(mysql,COM_DEBUG,"",0,0));
+}
+
+const char * STDCALL
+mysql_stat(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_stat");
+ if (simple_command(mysql,COM_STATISTICS,"",0,0))
+ return mysql->net.last_error;
+ mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */
+ if (!mysql->net.read_pos[0])
+ {
+ mysql->net.last_errno=CR_WRONG_HOST_INFO;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ return mysql->net.last_error;
+ }
+ DBUG_RETURN((char*) mysql->net.read_pos);
+}
+
+
+int STDCALL
+mysql_ping(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_ping");
+ DBUG_RETURN(simple_command(mysql,COM_PING,"",0,0));
+}
+
+
+const char * STDCALL
+mysql_get_server_info(MYSQL *mysql)
+{
+ return((char*) mysql->server_version);
+}
+
+
+const char * STDCALL
+mysql_get_host_info(MYSQL *mysql)
+{
+ return(mysql->host_info);
+}
+
+
+uint STDCALL
+mysql_get_proto_info(MYSQL *mysql)
+{
+ return (mysql->protocol_version);
+}
+
+const char * STDCALL
+mysql_get_client_info(void)
+{
+ return MYSQL_SERVER_VERSION;
+}
+
+
+int STDCALL
+mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
+{
+ DBUG_ENTER("mysql_option");
+ DBUG_PRINT("enter",("option: %d",(int) option));
+ switch (option) {
+ case MYSQL_OPT_CONNECT_TIMEOUT:
+ mysql->options.connect_timeout= *(uint*) arg;
+ break;
+ case MYSQL_OPT_COMPRESS:
+ mysql->options.compress=1; /* Remember for connect */
+ break;
+ case MYSQL_OPT_NAMED_PIPE:
+ mysql->options.named_pipe=1; /* Force named pipe */
+ break;
+ case MYSQL_INIT_COMMAND:
+ my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.init_command=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_READ_DEFAULT_FILE:
+ my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_READ_DEFAULT_GROUP:
+ my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_SET_CHARSET_DIR:
+ my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_SET_CHARSET_NAME:
+ my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
+ break;
+ default:
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
+
+/****************************************************************************
+** Functions to get information from the MySQL structure
+** These are functions to make shared libraries more usable.
+****************************************************************************/
+
+/* MYSQL_RES */
+my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res)
+{
+ return res->row_count;
+}
+
+unsigned int STDCALL mysql_num_fields(MYSQL_RES *res)
+{
+ return res->field_count;
+}
+
+my_bool STDCALL mysql_eof(MYSQL_RES *res)
+{
+ return res->eof;
+}
+
+MYSQL_FIELD * STDCALL mysql_fetch_field_direct(MYSQL_RES *res,uint fieldnr)
+{
+ return &(res)->fields[fieldnr];
+}
+
+MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res)
+{
+ return (res)->fields;
+}
+
+MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res)
+{
+ return res->data_cursor;
+}
+
+uint STDCALL mysql_field_tell(MYSQL_RES *res)
+{
+ return (res)->current_field;
+}
+
+/* MYSQL */
+
+unsigned int STDCALL mysql_field_count(MYSQL *mysql)
+{
+ return mysql->field_count;
+}
+
+my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
+{
+ return (mysql)->affected_rows;
+}
+
+my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
+{
+ return (mysql)->insert_id;
+}
+
+uint STDCALL mysql_errno(MYSQL *mysql)
+{
+ return (mysql)->net.last_errno;
+}
+
+const char * STDCALL mysql_error(MYSQL *mysql)
+{
+ return (mysql)->net.last_error;
+}
+
+const char *STDCALL mysql_info(MYSQL *mysql)
+{
+ return (mysql)->info;
+}
+
+ulong STDCALL mysql_thread_id(MYSQL *mysql)
+{
+ return (mysql)->thread_id;
+}
+
+const char * STDCALL mysql_character_set_name(MYSQL *mysql)
+{
+ return mysql->charset->name;
+}
+
+
+uint STDCALL mysql_thread_safe(void)
+{
+#ifdef THREAD
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/****************************************************************************
+** Some support functions
+****************************************************************************/
+
+/*
+** Add escape characters to a string (blob?) to make it suitable for a insert
+** to should at least have place for length*2+1 chars
+** Returns the length of the to string
+*/
+
+ulong STDCALL
+mysql_escape_string(char *to,const char *from,ulong length)
+{
+ return mysql_sub_escape_string(default_charset_info,to,from,length);
+}
+
+ulong STDCALL
+mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
+ ulong length)
+{
+ return mysql_sub_escape_string(mysql->charset,to,from,length);
+}
+
+
+static ulong
+mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
+ const char *from, ulong length)
+{
+ const char *to_start=to;
+ const char *end;
+#ifdef USE_MB
+ my_bool use_mb_flag=use_mb(charset_info);
+#endif
+ for (end=from+length; from != end ; from++)
+ {
+#ifdef USE_MB
+ int l;
+ if (use_mb_flag && (l = my_ismbchar(charset_info, from, end)))
+ {
+ while (l--)
+ *to++ = *from++;
+ from--;
+ continue;
+ }
+#endif
+ switch (*from) {
+ case 0: /* Must be escaped for 'mysql' */
+ *to++= '\\';
+ *to++= '0';
+ break;
+ case '\n': /* Must be escaped for logs */
+ *to++= '\\';
+ *to++= 'n';
+ break;
+ case '\r':
+ *to++= '\\';
+ *to++= 'r';
+ break;
+ case '\\':
+ *to++= '\\';
+ *to++= '\\';
+ break;
+ case '\'':
+ *to++= '\\';
+ *to++= '\'';
+ break;
+ case '"': /* Better safe than sorry */
+ *to++= '\\';
+ *to++= '"';
+ break;
+ case '\032': /* This gives problems on Win32 */
+ *to++= '\\';
+ *to++= 'Z';
+ break;
+ default:
+ *to++= *from;
+ }
+ }
+ *to=0;
+ return (ulong) (to-to_start);
+}
+
+
+char * STDCALL
+mysql_odbc_escape_string(MYSQL *mysql,
+ char *to, ulong to_length,
+ const char *from, ulong from_length,
+ void *param,
+ char * (*extend_buffer)
+ (void *, char *, ulong *))
+{
+ char *to_end=to+to_length-5;
+ const char *end;
+#ifdef USE_MB
+ my_bool use_mb_flag=use_mb(mysql->charset);
+#endif
+
+ for (end=from+from_length; from != end ; from++)
+ {
+ if (to >= to_end)
+ {
+ to_length = (ulong) (end-from)+512; /* We want this much more */
+ if (!(to=(*extend_buffer)(param, to, &to_length)))
+ return to;
+ to_end=to+to_length-5;
+ }
+#ifdef USE_MB
+ {
+ int l;
+ if (use_mb_flag && (l = my_ismbchar(mysql->charset, from, end)))
+ {
+ while (l--)
+ *to++ = *from++;
+ from--;
+ continue;
+ }
+ }
+#endif
+ switch (*from) {
+ case 0: /* Must be escaped for 'mysql' */
+ *to++= '\\';
+ *to++= '0';
+ break;
+ case '\n': /* Must be escaped for logs */
+ *to++= '\\';
+ *to++= 'n';
+ break;
+ case '\r':
+ *to++= '\\';
+ *to++= 'r';
+ break;
+ case '\\':
+ *to++= '\\';
+ *to++= '\\';
+ break;
+ case '\'':
+ *to++= '\\';
+ *to++= '\'';
+ break;
+ case '"': /* Better safe than sorry */
+ *to++= '\\';
+ *to++= '"';
+ break;
+ case '\032': /* This gives problems on Win32 */
+ *to++= '\\';
+ *to++= 'Z';
+ break;
+ default:
+ *to++= *from;
+ }
+ }
+ return to;
+}
+
+void STDCALL
+myodbc_remove_escape(MYSQL *mysql,char *name)
+{
+ char *to;
+#ifdef USE_MB
+ my_bool use_mb_flag=use_mb(mysql->charset);
+ char *end;
+ LINT_INIT(end);
+ if (use_mb_flag)
+ for (end=name; *end ; end++) ;
+#endif
+
+ for (to=name ; *name ; name++)
+ {
+#ifdef USE_MB
+ int l;
+ if (use_mb_flag && (l = my_ismbchar( mysql->charset, name , end ) ) )
+ {
+ while (l--)
+ *to++ = *name++;
+ name--;
+ continue;
+ }
+#endif
+ if (*name == '\\' && name[1])
+ name++;
+ *to++= *name;
+ }
+ *to=0;
+}
diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def
new file mode 100644
index 00000000000..c6615ee971c
--- /dev/null
+++ b/libmysqld/libmysqld.def
@@ -0,0 +1,65 @@
+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
diff --git a/ltconfig b/ltconfig
index 18af7c4dce8..b9df847729d 100755
--- a/ltconfig
+++ b/ltconfig
@@ -1308,7 +1308,9 @@ else
hardcode_direct=yes
fi
allow_undefined_flag=' ${wl}-berok'
- archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+ # -qmkshrobj used to be -bexpall, but MySQL uses symbols which start with
+ # an underscore (e.g., _my_b_write), so -bexpall doesn't work.
+ archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-qmkshrobj ${wl}-bnoentry${allow_undefined_flag}'
archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
case "$host_os" in aix4.[01]|aix4.[01].*)
# According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
diff --git a/man/Makefile.am b/man/Makefile.am
index 186fc01685e..7019d2aa865 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -19,7 +19,7 @@
man_MANS = mysql.1 isamchk.1 isamlog.1 mysql_zap.1 mysqlaccess.1 \
mysqladmin.1 mysqld.1 mysqld_multi.1 mysqldump.1 mysqlshow.1 \
- perror.1 replace.1 safe_mysqld.1
+ perror.1 replace.1 mysqld_safe.1
EXTRA_DIST = $(man_MANS)
diff --git a/man/isamchk.1 b/man/isamchk.1
index f225dc35d18..2552d9f80cd 100755..100644
--- a/man/isamchk.1
+++ b/man/isamchk.1
@@ -125,7 +125,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/isamlog.1 b/man/isamlog.1
index efc042ccd7c..ef6ceaff8da 100644
--- a/man/isamlog.1
+++ b/man/isamlog.1
@@ -83,7 +83,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
diff --git a/man/mysql.1 b/man/mysql.1
index 96ccca8f50e..e10fd589092 100644
--- a/man/mysql.1
+++ b/man/mysql.1
@@ -111,7 +111,7 @@ executable
.I /depot/bin/mysqld
executable
.TP
-.I /depot/bin/safe_mysqld
+.I /depot/bin/mysqld_safe
executable shell script for starting mysqld safely
.TP
.I /site/var/mysql/data
@@ -135,7 +135,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/mysql_zap.1 b/man/mysql_zap.1
index 98da195894e..e57eb7a4d07 100644
--- a/man/mysql_zap.1
+++ b/man/mysql_zap.1
@@ -28,7 +28,7 @@ isn't given, ask user for confirmation for each process to kill. If signal isn't
.BR -t
is given the processes is only shown on stdout.
.SH "SEE ALSO"
-isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), safe_mysqld (1), which1 (1), zap (1),
+isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), mysqld_safe (1), which1 (1), zap (1),
.SH AUTHOR
Ver 1.0, distribution 3.23.29a Michael (Monty) Widenius (monty@tcx.se), TCX Datakonsult AB (http://www.tcx.se). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com)
.\" end of man page \ No newline at end of file
diff --git a/man/mysqlaccess.1 b/man/mysqlaccess.1
index 888cfe8f646..0ae06dca137 100755..100644
--- a/man/mysqlaccess.1
+++ b/man/mysqlaccess.1
@@ -106,7 +106,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/mysqladmin.1 b/man/mysqladmin.1
index 58bd2070de6..1e435006bb2 100755..100644
--- a/man/mysqladmin.1
+++ b/man/mysqladmin.1
@@ -189,7 +189,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/mysqld.1 b/man/mysqld.1
index d3f22c0be1b..1f87eb9cf32 100755..100644
--- a/man/mysqld.1
+++ b/man/mysqld.1
@@ -137,7 +137,7 @@ Don't check the rows in the table if there isn't any delete blocks.
Before a table is automaticly repaired, mysqld will add a note about this in the error log. If you want to be able to recover from most things without user intervention, you should use the options BACKUP,FORCE. This will force a repair of a table even if some rows would be deleted, but it will keep the old data file as a backup so that you can later examine what happened.
.TP
.BR \-\-pid\-file=\fP\fIpath \fP
-Path to pid file used by safe_mysqld.
+Path to pid file used by mysqld_safe.
.TP
.BR \-P | \-\-port=...
Port number to listen for TCP/IP connections.
@@ -215,7 +215,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/mysqld_multi.1 b/man/mysqld_multi.1
index b68050e92ef..b7aa77f656d 100644
--- a/man/mysqld_multi.1
+++ b/man/mysqld_multi.1
@@ -36,7 +36,7 @@ Log file. Full path to and the name for the log file. NOTE: If the file exists,
mysqladmin binary to be used for a server shutdown.
.TP
.BR --mysqld=...
-mysqld binary to be used. Note that you can give safe_mysqld to this option also. The options are passed to mysqld. Just make sure you have mysqld in your environment variable PATH or fix safe_mysqld.
+mysqld binary to be used. Note that you can give mysqld_safe to this option also. The options are passed to mysqld. Just make sure you have mysqld in your environment variable PATH or fix mysqld_safe.
.TP
.BR --no-log
Print to stdout instead of the log file. By default the log file is turned on.
@@ -70,7 +70,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
diff --git a/man/mysqld_safe.1 b/man/mysqld_safe.1
new file mode 100644
index 00000000000..c900d193929
--- /dev/null
+++ b/man/mysqld_safe.1
@@ -0,0 +1,86 @@
+.TH SAFE_MYSQLD 1 "19 December 2000" "safe_mysqld (mysql)" mysql.com
+.SH NAME
+mysqld_safe \- start the mysqld daemon on Unix.
+.SH SYNOPSIS
+.B mysqld_safe
+.RB [ \-\-basedir=\fP\fIpath\fP ]
+.RB [ \-\-core\-file\-size=# ]
+.RB [ \-\-defaults\-extra\-file=\fP\fIpath\fP ]
+.RB [ \-\-defaults\-file=\fP\fIpath\fP ]
+.RB [ \-\-open\-files=# ]
+.RB [ \-\-datadir=\fP\fIpath\fP ]
+.RB [ \-\-err\-log=\fP\fIpath \fP]
+.RB [ \-\-ledir=path ]
+.RB [ \-\-log=\fP\fIpath\fP ]
+.RB [ \-\-no\-defaults ]
+.RB [ \-\-open\-files=# ]
+.RB [ \-\-pid\-file=\fP\fIpath\fP ]
+.RB [ \-\-port=# ]
+.RB [ \-\-socket=\fP\fIpath\fP ]
+.RB [ \-\-timezone=# ]
+.RB [ \-\-user=# ]
+.SH DESCRIPTION
+mysqld_safe adds some safety features such as restarting the server when an
+error occurs and logging run-time information to a log file.
+.BR
+.TP
+.BR \-\-basedir=\fP\fIpath \fP
+.TP
+.BR \-\-core\-file\-size=#
+Size of the core file mysqld should be able to create. Passed to ulimit \-c.
+.TP
+.BR \-\-defaults\-extra\-file=\fP\fIpath \fP
+.TP
+.BR \-\-defaults\-file=\fP\fIpath \fP
+.TP
+.BR \-\-datadir=\fP\fIpath \fP
+.TP
+.BR \-\-err\-log=\fP\fIpath \fP
+.TP
+.BR \-\-ledir=\fP\fIpath \fP
+Path to mysqld
+.TP
+.BR \-\-log=\fP\fIpath \fP
+.TP
+.BR \-\-no\-defaults
+.TP
+.BR \-\-open\-files=#
+Number of files mysqld should be able to open. Passed to ulimit \-n.
+.TP
+.BR \-\-pid\-file=\fP\fIpath \fP
+.TP
+.BR \-\-port=#
+.TP
+.BR \-\-socket=\fP\fIpath \fP
+.TP
+.BR \-\-timezone=#
+Set the timezone (the TZ) variable to the value of this parameter.
+.TP
+.BR \-\-user=#
+.SH NOTE
+Note that all options on the command line to mysqld_safe are passed to mysqld. If you wants to use any options in mysqld_safe that mysqld doesn't support, you must specify these in the option file.
+.SH "SEE ALSO"
+isamchk (1),
+isamlog (1),
+mysqlaccess (1),
+mysqladmin (1),
+mysqlbug (1),
+mysqld (1),
+mysqldump (1),
+mysqlshow (1),
+msql2mysql (1),
+perror (1),
+replace (1),
+mysqld_safe (1),
+which1 (1),
+zap (1),
+.SH AUTHOR
+Ver 1.0, distribution 3.23.29a
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/mysqldump.1 b/man/mysqldump.1
index f108da17bf9..b9e5aa33791 100755..100644
--- a/man/mysqldump.1
+++ b/man/mysqldump.1
@@ -258,7 +258,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/mysqlshow.1 b/man/mysqlshow.1
index 55a87c1df78..661b2cd02c8 100755..100644
--- a/man/mysqlshow.1
+++ b/man/mysqlshow.1
@@ -78,7 +78,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/perror.1 b/man/perror.1
index 2853f2cb1ba..7adf99ea772 100755..100644
--- a/man/perror.1
+++ b/man/perror.1
@@ -43,7 +43,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/replace.1 b/man/replace.1
index 10bcf64fc88..38ffe998027 100644
--- a/man/replace.1
+++ b/man/replace.1
@@ -52,7 +52,7 @@ mysqlshow (1),
msql2mysql (1),
perror (1),
replace (1),
-safe_mysqld (1),
+mysqld_safe (1),
which1 (1),
zap (1),
.SH AUTHOR
diff --git a/man/safe_mysqld.1 b/man/safe_mysqld.1
deleted file mode 100755
index 3874801be3b..00000000000
--- a/man/safe_mysqld.1
+++ /dev/null
@@ -1,88 +0,0 @@
-.TH SAFE_MYSQLD 1 "19 December 2000" "safe_mysqld (mysql)" mysql.com
-.SH NAME
-safe_mysqld \- start the mysqld daemon on Unix.
-.SH SYNOPSIS
-.B safe_mysqld
-.RB [ \-\-basedir=\fP\fIpath\fP ]
-.RB [ \-\-core\-file\-size=# ]
-.RB [ \-\-defaults\-extra\-file=\fP\fIpath\fP ]
-.RB [ \-\-defaults\-file=\fP\fIpath\fP ]
-.RB [ \-\-open\-files=# ]
-.RB [ \-\-datadir=\fP\fIpath\fP ]
-.RB [ \-\-err\-log=\fP\fIpath \fP]
-.RB [ \-\-ledir=path ]
-.RB [ \-\-log=\fP\fIpath\fP ]
-.RB [ \-\-no\-defaults ]
-.RB [ \-\-open\-files=# ]
-.RB [ \-\-pid\-file=\fP\fIpath\fP ]
-.RB [ \-\-port=# ]
-.RB [ \-\-socket=\fP\fIpath\fP ]
-.RB [ \-\-timezone=# ]
-.RB [ \-\-user=# ]
-.SH DESCRIPTION
-safe_mysqld adds some safety features such as restarting the server when an
-error occurs and logging run-time information to a log file.
-.BR
-.TP
-.BR \-\-basedir=\fP\fIpath \fP
-.TP
-.BR \-\-core\-file\-size=#
-.TP
-.BR \-\-defaults\-extra\-file=\fP\fIpath \fP
-.TP
-.BR \-\-defaults\-file=\fP\fIpath \fP
-.TP
-.BR \-\-open\-files=#
-Size of the core file mysqld should be able to create. Passed to ulimit \-c.
-.TP
-.BR \-\-datadir=\fP\fIpath \fP
-.TP
-.BR \-\-err\-log=\fP\fIpath \fP
-.TP
-.BR \-\-ledir=\fP\fIpath \fP
-Path to mysqld
-.TP
-.BR \-\-log=\fP\fIpath \fP
-.TP
-.BR \-\-no\-defaults
-.TP
-.BR \-\-open\-files=#
-Number of files mysqld should be able to open. Passed to ulimit \-n.
-.TP
-.BR \-\-pid\-file=\fP\fIpath \fP
-.TP
-.BR \-\-port=#
-.TP
-.BR \-\-socket=\fP\fIpath \fP
-.TP
-.BR \-\-timezone=#
-Set the timezone (the TZ) variable to the value of this parameter.
-.TP
-.BR \-\-user=#
-.SH NOTE
-Note that all options on the command line to safe_mysqld are passed to mysqld. If you wants to use any options in safe_mysqld that mysqld doesn't support, you must specify these in the option file.
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/which.2 b/man/which.2
index 599b68080a2..30d5557ed01 100644
--- a/man/which.2
+++ b/man/which.2
@@ -48,7 +48,7 @@ Ignore option
.BR --read-alias;
don\'t read stdin.
.SH "SEE ALSO"
-isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), safe_mysqld (1), which1 (1), zap (1),
+isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), mysqld_safe (1), which1 (1), zap (1),
.SH AUTHOR
Ver 1.0, distribution 3.23.29a Michael (Monty) Widenius (monty@tcx.se), TCX Datakonsult AB (http://www.tcx.se). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com)
.\" end of man page \ No newline at end of file
diff --git a/merge/Makefile.am b/merge/Makefile.am
index 52abfc4cdc0..94de6d65391 100644
--- a/merge/Makefile.am
+++ b/merge/Makefile.am
@@ -16,10 +16,10 @@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
pkglib_LIBRARIES = libmerge.a
-noinst_HEADERS = mrgdef.h
-libmerge_a_SOURCES = open.c extra.c info.c _locking.c \
- rrnd.c update.c delete.c rsame.c panic.c \
- close.c create.c static.c
+noinst_HEADERS = mrg_def.h
+libmerge_a_SOURCES = mrg_open.c mrg_extra.c mrg_info.c mrg_locking.c \
+ mrg_rrnd.c mrg_update.c mrg_delete.c mrg_rsame.c \
+ mrg_panic.c mrg_close.c mrg_create.c mrg_static.c
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
__math.h time.h __time.h unistd.h __unistd.h types.h \
diff --git a/merge/_locking.c b/merge/_locking.c
deleted file mode 100644
index 81582da1312..00000000000
--- a/merge/_locking.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Lock databases against read or write.
-*/
-
-#include "mrgdef.h"
-
-int mrg_lock_database(MRG_INFO *info,int lock_type)
-{
- int error,new_error;
- MRG_TABLE *file;
-
- error=0;
- for (file=info->open_tables ; file != info->end_table ; file++)
- if ((new_error=nisam_lock_database(file->table,lock_type)))
- error=new_error;
- return(error);
-}
diff --git a/merge/close.c b/merge/close.c
deleted file mode 100644
index 2b769ade8e9..00000000000
--- a/merge/close.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* close a isam-database */
-
-#include "mrgdef.h"
-
-int mrg_close(register MRG_INFO *info)
-{
- int error=0,new_error;
- MRG_TABLE *file;
- DBUG_ENTER("mrg_close");
-
- for (file=info->open_tables ; file != info->end_table ; file++)
- if ((new_error=nisam_close(file->table)))
- error=new_error;
- pthread_mutex_lock(&THR_LOCK_open);
- mrg_open_list=list_delete(mrg_open_list,&info->open_list);
- pthread_mutex_unlock(&THR_LOCK_open);
- my_free((gptr) info,MYF(0));
- if (error)
- {
- my_errno=error;
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
diff --git a/merge/create.c b/merge/create.c
deleted file mode 100644
index fd2c16f9ea2..00000000000
--- a/merge/create.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Create a MERGE-file */
-
-#include "mrgdef.h"
-
- /* create file named 'name' and save filenames in it
- table_names should be NULL or a vector of string-pointers with
- a NULL-pointer last
- */
-
-int mrg_create(const char *name, const char**table_names)
-{
- int save_errno;
- uint errpos;
- File file;
- char buff[FN_REFLEN],*end;
- DBUG_ENTER("mrg_create");
-
- errpos=0;
- if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0,
- O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
- goto err;
- errpos=1;
- if (table_names)
- for ( ; *table_names ; table_names++)
- {
- strmov(buff,*table_names);
- fn_same(buff,name,4);
- *(end=strend(buff))='\n';
- if (my_write(file,*table_names,(uint) (end-buff+1),
- MYF(MY_WME | MY_NABP)))
- goto err;
- }
- if (my_close(file,MYF(0)))
- goto err;
- DBUG_RETURN(0);
-
-err:
- save_errno=my_errno;
- switch (errpos) {
- case 1:
- VOID(my_close(file,MYF(0)));
- }
- my_errno=save_errno; /* Return right errocode */
- DBUG_RETURN(-1);
-} /* mrg_create */
diff --git a/merge/delete.c b/merge/delete.c
deleted file mode 100644
index a4ee46eedc2..00000000000
--- a/merge/delete.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Delete last read record */
-
-#include "mrgdef.h"
-
-int mrg_delete(MRG_INFO *info,const byte *record)
-{
- if (!info->current_table)
- {
- my_errno=HA_ERR_NO_ACTIVE_RECORD;
- return(-1);
- }
- return nisam_delete(info->current_table->table,record);
-}
diff --git a/merge/extra.c b/merge/extra.c
deleted file mode 100644
index c4f048a4385..00000000000
--- a/merge/extra.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Extra functions we want to do with a database
- - All flags, exept record-cache-flags, are set in all used databases
- record-cache-flags are set in mrg_rrnd when we are changing database.
-*/
-
-#include "mrgdef.h"
-
-int mrg_extra(
-MRG_INFO *info,
-enum ha_extra_function function)
-{
- MRG_TABLE *file;
-
- if (function == HA_EXTRA_CACHE)
- info->cache_in_use=1;
- else
- {
- if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET)
- info->cache_in_use=0;
- if (function == HA_EXTRA_RESET || function == HA_EXTRA_RESET_STATE)
- {
- info->current_table=0;
- info->last_used_table=info->open_tables;
- }
- for (file=info->open_tables ; file != info->end_table ; file++)
- nisam_extra(file->table,function);
- }
- return 0;
-}
diff --git a/merge/info.c b/merge/info.c
deleted file mode 100644
index d44ada8e6e6..00000000000
--- a/merge/info.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mrgdef.h"
-
-ulong mrg_position(MRG_INFO *info)
-{
- MRG_TABLE *current_table;
-
- if (!(current_table = info->current_table) &&
- info->open_tables != info->end_table)
- current_table = info->open_tables;
- return (current_table ?
- (ulong) (current_table->table->lastpos +
- current_table->file_offset) :
- ~(ulong) 0);
-}
-
- /* If flag != 0 one only gets pos of last record */
-
-int mrg_info(MRG_INFO *info,register MERGE_INFO *x,int flag)
-{
- MRG_TABLE *current_table;
- DBUG_ENTER("mrg_info");
-
- if (!(current_table = info->current_table) &&
- info->open_tables != info->end_table)
- current_table = info->open_tables;
- x->recpos = info->current_table ?
- info->current_table->table->lastpos + info->current_table->file_offset :
- (ulong) -1L;
- if (flag != HA_STATUS_POS)
- {
- x->records = info->records;
- x->deleted = info->del;
- x->data_file_length = info->data_file_length;
- x->reclength = info->reclength;
- if (current_table)
- x->errkey = current_table->table->errkey;
- else
- { /* No tables in MRG */
- x->errkey=0;
- }
- x->options = info->options;
- }
- DBUG_RETURN(0);
-}
diff --git a/merge/mrg_close.c b/merge/mrg_close.c
new file mode 100644
index 00000000000..e835fd06e47
--- /dev/null
+++ b/merge/mrg_close.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* close a isam-database */
+
+#include "mrg_def.h"
+
+int mrg_close(register MRG_INFO *info)
+{
+ int error=0,new_error;
+ MRG_TABLE *file;
+ DBUG_ENTER("mrg_close");
+
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ if ((new_error=nisam_close(file->table)))
+ error=new_error;
+ pthread_mutex_lock(&THR_LOCK_open);
+ mrg_open_list=list_delete(mrg_open_list,&info->open_list);
+ pthread_mutex_unlock(&THR_LOCK_open);
+ my_free((gptr) info,MYF(0));
+ if (error)
+ {
+ my_errno=error;
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
diff --git a/merge/mrg_create.c b/merge/mrg_create.c
new file mode 100644
index 00000000000..d55a1421647
--- /dev/null
+++ b/merge/mrg_create.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Create a MERGE-file */
+
+#include "mrg_def.h"
+
+ /* create file named 'name' and save filenames in it
+ table_names should be NULL or a vector of string-pointers with
+ a NULL-pointer last
+ */
+
+int mrg_create(const char *name, const char**table_names)
+{
+ int save_errno;
+ uint errpos;
+ File file;
+ char buff[FN_REFLEN],*end;
+ DBUG_ENTER("mrg_create");
+
+ errpos=0;
+ if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0,
+ O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
+ goto err;
+ errpos=1;
+ if (table_names)
+ for ( ; *table_names ; table_names++)
+ {
+ strmov(buff,*table_names);
+ fn_same(buff,name,4);
+ *(end=strend(buff))='\n';
+ if (my_write(file,*table_names,(uint) (end-buff+1),
+ MYF(MY_WME | MY_NABP)))
+ goto err;
+ }
+ if (my_close(file,MYF(0)))
+ goto err;
+ DBUG_RETURN(0);
+
+err:
+ save_errno=my_errno;
+ switch (errpos) {
+ case 1:
+ VOID(my_close(file,MYF(0)));
+ }
+ my_errno=save_errno; /* Return right errocode */
+ DBUG_RETURN(-1);
+} /* mrg_create */
diff --git a/merge/mrg_def.h b/merge/mrg_def.h
new file mode 100644
index 00000000000..8b6be08c32d
--- /dev/null
+++ b/merge/mrg_def.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Denna fil includeras i alla merge-filer */
+
+#ifndef N_MAXKEY
+#include "../isam/isamdef.h"
+#endif
+
+#include "merge.h"
+
+extern LIST *mrg_open_list;
+
+#ifdef THREAD
+extern pthread_mutex_t THR_LOCK_open;
+#endif
diff --git a/merge/mrg_delete.c b/merge/mrg_delete.c
new file mode 100644
index 00000000000..920156be01e
--- /dev/null
+++ b/merge/mrg_delete.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Delete last read record */
+
+#include "mrg_def.h"
+
+int mrg_delete(MRG_INFO *info,const byte *record)
+{
+ if (!info->current_table)
+ {
+ my_errno=HA_ERR_NO_ACTIVE_RECORD;
+ return(-1);
+ }
+ return nisam_delete(info->current_table->table,record);
+}
diff --git a/merge/mrg_extra.c b/merge/mrg_extra.c
new file mode 100644
index 00000000000..d37b1aaa03c
--- /dev/null
+++ b/merge/mrg_extra.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Extra functions we want to do with a database
+ - All flags, exept record-cache-flags, are set in all used databases
+ record-cache-flags are set in mrg_rrnd when we are changing database.
+*/
+
+#include "mrg_def.h"
+
+int mrg_extra(
+MRG_INFO *info,
+enum ha_extra_function function)
+{
+ MRG_TABLE *file;
+
+ if (function == HA_EXTRA_CACHE)
+ info->cache_in_use=1;
+ else
+ {
+ if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET)
+ info->cache_in_use=0;
+ if (function == HA_EXTRA_RESET || function == HA_EXTRA_RESET_STATE)
+ {
+ info->current_table=0;
+ info->last_used_table=info->open_tables;
+ }
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ nisam_extra(file->table,function);
+ }
+ return 0;
+}
diff --git a/merge/mrg_info.c b/merge/mrg_info.c
new file mode 100644
index 00000000000..57f22276487
--- /dev/null
+++ b/merge/mrg_info.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mrg_def.h"
+
+ulong mrg_position(MRG_INFO *info)
+{
+ MRG_TABLE *current_table;
+
+ if (!(current_table = info->current_table) &&
+ info->open_tables != info->end_table)
+ current_table = info->open_tables;
+ return (current_table ?
+ (ulong) (current_table->table->lastpos +
+ current_table->file_offset) :
+ ~(ulong) 0);
+}
+
+ /* If flag != 0 one only gets pos of last record */
+
+int mrg_info(MRG_INFO *info,register MERGE_INFO *x,int flag)
+{
+ MRG_TABLE *current_table;
+ DBUG_ENTER("mrg_info");
+
+ if (!(current_table = info->current_table) &&
+ info->open_tables != info->end_table)
+ current_table = info->open_tables;
+ x->recpos = info->current_table ?
+ info->current_table->table->lastpos + info->current_table->file_offset :
+ (ulong) -1L;
+ if (flag != HA_STATUS_POS)
+ {
+ x->records = info->records;
+ x->deleted = info->del;
+ x->data_file_length = info->data_file_length;
+ x->reclength = info->reclength;
+ if (current_table)
+ x->errkey = current_table->table->errkey;
+ else
+ { /* No tables in MRG */
+ x->errkey=0;
+ }
+ x->options = info->options;
+ }
+ DBUG_RETURN(0);
+}
diff --git a/merge/mrg_locking.c b/merge/mrg_locking.c
new file mode 100644
index 00000000000..bd33e047091
--- /dev/null
+++ b/merge/mrg_locking.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Lock databases against read or write.
+*/
+
+#include "mrg_def.h"
+
+int mrg_lock_database(MRG_INFO *info,int lock_type)
+{
+ int error,new_error;
+ MRG_TABLE *file;
+
+ error=0;
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ if ((new_error=nisam_lock_database(file->table,lock_type)))
+ error=new_error;
+ return(error);
+}
diff --git a/merge/mrg_open.c b/merge/mrg_open.c
new file mode 100644
index 00000000000..83b776ea201
--- /dev/null
+++ b/merge/mrg_open.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* open a MERGE-database */
+
+#include "mrg_def.h"
+#include <stddef.h>
+#include <errno.h>
+#ifdef VMS
+#include "static.c"
+#endif
+
+/* open a MERGE-database.
+
+ if handle_locking is 0 then exit with error if some database is locked
+ if handle_locking is 1 then wait if database is locked
+*/
+
+
+MRG_INFO *mrg_open(
+const char *name,
+int mode,
+int handle_locking)
+{
+ int save_errno,i,errpos;
+ uint files,dir_length,length, options;
+ ulonglong file_offset;
+ char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
+ MRG_INFO info,*m_info;
+ File fd;
+ IO_CACHE file;
+ N_INFO *isam,*last_isam;
+ DBUG_ENTER("mrg_open");
+
+ LINT_INIT(last_isam);
+ isam=0;
+ errpos=files=0;
+ bzero((gptr) &info,sizeof(info));
+ bzero((char*) &file,sizeof(file));
+ if ((fd=my_open(fn_format(name_buff,name,"",MRG_NAME_EXT,4),
+ O_RDONLY | O_SHARE,MYF(0))) < 0 ||
+ init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0,
+ MYF(MY_WME | MY_NABP)))
+ goto err;
+ errpos=1;
+ dir_length=dirname_part(name_buff,name);
+ info.reclength=0;
+ while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
+ {
+ if ((end=buff+length)[-1] == '\n')
+ end[-1]='\0';
+ if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
+ {
+ last_isam=isam;
+ if (!test_if_hard_path(buff))
+ {
+ VOID(strmake(name_buff+dir_length,buff,
+ sizeof(name_buff)-1-dir_length));
+ VOID(cleanup_dirname(buff,name_buff));
+ }
+ if (!(isam=nisam_open(buff,mode,test(handle_locking))))
+ goto err;
+ files++;
+ }
+ last_isam=isam;
+ if (info.reclength && info.reclength != isam->s->base.reclength)
+ {
+ my_errno=HA_ERR_WRONG_IN_RECORD;
+ goto err;
+ }
+ info.reclength=isam->s->base.reclength;
+ }
+ if (!(m_info= (MRG_INFO*) my_malloc(sizeof(MRG_INFO)+files*sizeof(MRG_TABLE),
+ MYF(MY_WME))))
+ goto err;
+ *m_info=info;
+ m_info->open_tables=(MRG_TABLE *) (m_info+1);
+ m_info->tables=files;
+
+ options= (uint) ~0;
+ for (i=files ; i-- > 0 ; )
+ {
+ m_info->open_tables[i].table=isam;
+ m_info->options|=isam->s->base.options;
+ options&=isam->s->base.options;
+ m_info->records+=isam->s->state.records;
+ m_info->del+=isam->s->state.del;
+ m_info->data_file_length=isam->s->state.data_file_length;
+ if (i)
+ isam=(N_INFO*) (isam->open_list.next->data);
+ }
+ /* Don't force readonly if not all tables are readonly */
+ if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA)))
+ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);
+
+ /* Fix fileinfo for easyer debugging (actually set by rrnd) */
+ file_offset=0;
+ for (i=0 ; (uint) i < files ; i++)
+ {
+ m_info->open_tables[i].file_offset=(my_off_t) file_offset;
+ file_offset+=m_info->open_tables[i].table->s->state.data_file_length;
+ }
+ if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
+ {
+ my_errno=HA_ERR_RECORD_FILE_FULL;
+ my_free((char*) m_info,MYF(0));
+ goto err;
+ }
+
+ m_info->end_table=m_info->open_tables+files;
+ m_info->last_used_table=m_info->open_tables;
+
+ VOID(my_close(fd,MYF(0)));
+ end_io_cache(&file);
+ m_info->open_list.data=(void*) m_info;
+ pthread_mutex_lock(&THR_LOCK_open);
+ mrg_open_list=list_add(mrg_open_list,&m_info->open_list);
+ pthread_mutex_unlock(&THR_LOCK_open);
+ DBUG_RETURN(m_info);
+
+err:
+ save_errno=my_errno;
+ switch (errpos) {
+ case 1:
+ VOID(my_close(fd,MYF(0)));
+ end_io_cache(&file);
+ for (i=files ; i-- > 0 ; )
+ {
+ isam=last_isam;
+ if (i)
+ last_isam=(N_INFO*) (isam->open_list.next->data);
+ nisam_close(isam);
+ }
+ }
+ my_errno=save_errno;
+ DBUG_RETURN (NULL);
+}
diff --git a/merge/mrg_panic.c b/merge/mrg_panic.c
new file mode 100644
index 00000000000..e9ad1974d8f
--- /dev/null
+++ b/merge/mrg_panic.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mrg_def.h"
+
+ /* if flag == HA_PANIC_CLOSE then all misam files are closed */
+ /* if flag == HA_PANIC_WRITE then all misam files are unlocked and
+ all changed data in single user misam is written to file */
+ /* if flag == HA_PANIC_READ then all misam files that was locked when
+ nisam_panic(HA_PANIC_WRITE) was done is locked. A ni_readinfo() is
+ done for all single user files to get changes in database */
+
+
+int mrg_panic(
+enum ha_panic_function flag)
+{
+ int error=0;
+ LIST *list_element,*next_open;
+ MRG_INFO *info;
+ DBUG_ENTER("mrg_panic");
+
+ for (list_element=mrg_open_list ; list_element ; list_element=next_open)
+ {
+ next_open=list_element->next; /* Save if close */
+ info=(MRG_INFO*) list_element->data;
+ if (flag == HA_PANIC_CLOSE && mrg_close(info))
+ error=my_errno;
+ }
+ if (mrg_open_list && flag != HA_PANIC_CLOSE)
+ DBUG_RETURN(nisam_panic(flag));
+ if (!error) DBUG_RETURN(0);
+ my_errno=error;
+ DBUG_RETURN(-1);
+}
diff --git a/merge/mrg_rrnd.c b/merge/mrg_rrnd.c
new file mode 100644
index 00000000000..206427d74d4
--- /dev/null
+++ b/merge/mrg_rrnd.c
@@ -0,0 +1,110 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Read a record with random-access. The position to the record must
+ get by mrg_info(). The next record can be read with pos= -1 */
+
+
+#include "mrg_def.h"
+
+static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos);
+
+/*
+ If filepos == -1, read next
+ Returns same as nisam_rrnd:
+ 0 = Ok.
+ 1 = Record deleted.
+ -1 = EOF (or something, errno should be HA_ERR_END_OF_FILE)
+*/
+
+int mrg_rrnd(MRG_INFO *info,byte *buf,mrg_off_t filepos)
+{
+ int error;
+ N_INFO *isam_info;
+
+ if (filepos == ~(mrg_off_t) 0) /* Can't use HA_POS_ERROR */
+ {
+ if (!info->current_table)
+ {
+ if (info->open_tables == info->end_table)
+ { /* No tables */
+ my_errno=HA_ERR_END_OF_FILE;
+ return -1;
+ }
+ isam_info=(info->current_table=info->open_tables)->table;
+ if (info->cache_in_use)
+ nisam_extra(isam_info,HA_EXTRA_CACHE);
+ filepos=isam_info->s->pack.header_length;
+ isam_info->lastinx= (uint) -1; /* Can't forward or backward */
+ }
+ else
+ {
+ isam_info=info->current_table->table;
+ filepos= isam_info->nextpos;
+ }
+
+ for (;;)
+ {
+ isam_info->update&= HA_STATE_CHANGED;
+ if ((error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf,
+ filepos,1)) >= 0 ||
+ my_errno != HA_ERR_END_OF_FILE)
+ return (error);
+ if (info->cache_in_use)
+ nisam_extra(info->current_table->table,HA_EXTRA_NO_CACHE);
+ if (info->current_table+1 == info->end_table)
+ return(-1);
+ info->current_table++;
+ info->last_used_table=info->current_table;
+ if (info->cache_in_use)
+ nisam_extra(info->current_table->table,HA_EXTRA_CACHE);
+ info->current_table->file_offset=
+ info->current_table[-1].file_offset+
+ info->current_table[-1].table->s->state.data_file_length;
+
+ isam_info=info->current_table->table;
+ filepos=isam_info->s->pack.header_length;
+ isam_info->lastinx= (uint) -1;
+ }
+ }
+ info->current_table=find_table(info->open_tables,
+ info->end_table-1,filepos);
+ isam_info=info->current_table->table;
+ isam_info->update&= HA_STATE_CHANGED;
+ return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf,
+ (ulong) (filepos -
+ info->current_table->file_offset),
+ 0));
+}
+
+
+ /* Find which table to use according to file-pos */
+
+static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos)
+{
+ MRG_TABLE *mid;
+
+ while (start != end)
+ {
+ mid=start+((uint) (end-start)+1)/2;
+ if (mid->file_offset > pos)
+ end=mid-1;
+ else
+ start=mid;
+ }
+ return start;
+}
diff --git a/merge/mrg_rsame.c b/merge/mrg_rsame.c
new file mode 100644
index 00000000000..ee840bc3060
--- /dev/null
+++ b/merge/mrg_rsame.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mrg_def.h"
+
+
+int mrg_rsame(
+MRG_INFO *info,
+byte *record,
+int inx) /* not used, should be 0 */
+{
+ if (inx)
+ {
+ my_errno=HA_ERR_WRONG_INDEX;
+ return(-1);
+ }
+ if (!info->current_table)
+ {
+ my_errno=HA_ERR_NO_ACTIVE_RECORD;
+ return(-1);
+ }
+ return nisam_rsame(info->current_table->table,record,inx);
+}
diff --git a/merge/mrg_static.c b/merge/mrg_static.c
new file mode 100644
index 00000000000..1b7327c870f
--- /dev/null
+++ b/merge/mrg_static.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Static variables for pisam library. All definied here for easy making of
+ a shared library
+*/
+
+#ifndef stdin
+#include "mrg_def.h"
+#endif
+
+LIST *mrg_open_list=0;
diff --git a/merge/mrg_update.c b/merge/mrg_update.c
new file mode 100644
index 00000000000..a6650267f36
--- /dev/null
+++ b/merge/mrg_update.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Update last read record */
+
+#include "mrg_def.h"
+
+int mrg_update(
+register MRG_INFO *info,
+const byte *oldrec, const byte *newrec)
+{
+ if (!info->current_table)
+ {
+ my_errno=HA_ERR_NO_ACTIVE_RECORD;
+ return(-1);
+ }
+ return nisam_update(info->current_table->table,oldrec,newrec);
+}
diff --git a/merge/mrgdef.h b/merge/mrgdef.h
deleted file mode 100644
index 3f22c83589a..00000000000
--- a/merge/mrgdef.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Denna fil includeras i alla merge-filer */
-
-#ifndef N_MAXKEY
-#include "../isam/isamdef.h"
-#endif
-
-#include "merge.h"
-
-extern LIST *mrg_open_list;
-
-#ifdef THREAD
-extern pthread_mutex_t THR_LOCK_open;
-#endif
diff --git a/merge/open.c b/merge/open.c
deleted file mode 100644
index c1be98b7e18..00000000000
--- a/merge/open.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* open a MERGE-database */
-
-#include "mrgdef.h"
-#include <stddef.h>
-#include <errno.h>
-#ifdef VMS
-#include "static.c"
-#endif
-
-/* open a MERGE-database.
-
- if handle_locking is 0 then exit with error if some database is locked
- if handle_locking is 1 then wait if database is locked
-*/
-
-
-MRG_INFO *mrg_open(
-const char *name,
-int mode,
-int handle_locking)
-{
- int save_errno,i,errpos;
- uint files,dir_length,length;
- ulonglong file_offset;
- char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
- MRG_INFO info,*m_info;
- File fd;
- IO_CACHE file;
- N_INFO *isam,*last_isam;
- DBUG_ENTER("mrg_open");
-
- LINT_INIT(last_isam);
- isam=0;
- errpos=files=0;
- bzero((gptr) &info,sizeof(info));
- bzero((char*) &file,sizeof(file));
- if ((fd=my_open(fn_format(name_buff,name,"",MRG_NAME_EXT,4),
- O_RDONLY | O_SHARE,MYF(0))) < 0 ||
- init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0,
- MYF(MY_WME | MY_NABP)))
- goto err;
- errpos=1;
- dir_length=dirname_part(name_buff,name);
- info.reclength=0;
- while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
- {
- if ((end=buff+length)[-1] == '\n')
- end[-1]='\0';
- if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
- {
- last_isam=isam;
- if (!test_if_hard_path(buff))
- {
- VOID(strmake(name_buff+dir_length,buff,
- sizeof(name_buff)-1-dir_length));
- VOID(cleanup_dirname(buff,name_buff));
- }
- if (!(isam=nisam_open(buff,mode,test(handle_locking))))
- goto err;
- files++;
- }
- last_isam=isam;
- if (info.reclength && info.reclength != isam->s->base.reclength)
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
- goto err;
- }
- info.reclength=isam->s->base.reclength;
- }
- if (!(m_info= (MRG_INFO*) my_malloc(sizeof(MRG_INFO)+files*sizeof(MRG_TABLE),
- MYF(MY_WME))))
- goto err;
- *m_info=info;
- m_info->open_tables=(MRG_TABLE *) (m_info+1);
- m_info->tables=files;
-
- for (i=files ; i-- > 0 ; )
- {
- m_info->open_tables[i].table=isam;
- m_info->options|=isam->s->base.options;
- m_info->records+=isam->s->state.records;
- m_info->del+=isam->s->state.del;
- m_info->data_file_length=isam->s->state.data_file_length;
- if (i)
- isam=(N_INFO*) (isam->open_list.next->data);
- }
- /* Fix fileinfo for easyer debugging (actually set by rrnd) */
- file_offset=0;
- for (i=0 ; (uint) i < files ; i++)
- {
- m_info->open_tables[i].file_offset=(my_off_t) file_offset;
- file_offset+=m_info->open_tables[i].table->s->state.data_file_length;
- }
- if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
- {
- my_errno=HA_ERR_RECORD_FILE_FULL;
- my_free((char*) m_info,MYF(0));
- goto err;
- }
-
- m_info->end_table=m_info->open_tables+files;
- m_info->last_used_table=m_info->open_tables;
-
- VOID(my_close(fd,MYF(0)));
- end_io_cache(&file);
- m_info->open_list.data=(void*) m_info;
- pthread_mutex_lock(&THR_LOCK_open);
- mrg_open_list=list_add(mrg_open_list,&m_info->open_list);
- pthread_mutex_unlock(&THR_LOCK_open);
- DBUG_RETURN(m_info);
-
-err:
- save_errno=my_errno;
- switch (errpos) {
- case 1:
- VOID(my_close(fd,MYF(0)));
- end_io_cache(&file);
- for (i=files ; i-- > 0 ; )
- {
- isam=last_isam;
- if (i)
- last_isam=(N_INFO*) (isam->open_list.next->data);
- nisam_close(isam);
- }
- }
- my_errno=save_errno;
- DBUG_RETURN (NULL);
-}
diff --git a/merge/panic.c b/merge/panic.c
deleted file mode 100644
index cf333e3a9bf..00000000000
--- a/merge/panic.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mrgdef.h"
-
- /* if flag == HA_PANIC_CLOSE then all misam files are closed */
- /* if flag == HA_PANIC_WRITE then all misam files are unlocked and
- all changed data in single user misam is written to file */
- /* if flag == HA_PANIC_READ then all misam files that was locked when
- nisam_panic(HA_PANIC_WRITE) was done is locked. A ni_readinfo() is
- done for all single user files to get changes in database */
-
-
-int mrg_panic(
-enum ha_panic_function flag)
-{
- int error=0;
- LIST *list_element,*next_open;
- MRG_INFO *info;
- DBUG_ENTER("mrg_panic");
-
- for (list_element=mrg_open_list ; list_element ; list_element=next_open)
- {
- next_open=list_element->next; /* Save if close */
- info=(MRG_INFO*) list_element->data;
- if (flag == HA_PANIC_CLOSE && mrg_close(info))
- error=my_errno;
- }
- if (mrg_open_list && flag != HA_PANIC_CLOSE)
- DBUG_RETURN(nisam_panic(flag));
- if (!error) DBUG_RETURN(0);
- my_errno=error;
- DBUG_RETURN(-1);
-}
diff --git a/merge/rrnd.c b/merge/rrnd.c
deleted file mode 100644
index e53982aca21..00000000000
--- a/merge/rrnd.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Read a record with random-access. The position to the record must
- get by mrg_info(). The next record can be read with pos= -1 */
-
-
-#include "mrgdef.h"
-
-static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos);
-
-/*
- If filepos == -1, read next
- Returns same as nisam_rrnd:
- 0 = Ok.
- 1 = Record deleted.
- -1 = EOF (or something, errno should be HA_ERR_END_OF_FILE)
-*/
-
-int mrg_rrnd(MRG_INFO *info,byte *buf,mrg_off_t filepos)
-{
- int error;
- N_INFO *isam_info;
-
- if (filepos == ~(mrg_off_t) 0) /* Can't use HA_POS_ERROR */
- {
- if (!info->current_table)
- {
- if (info->open_tables == info->end_table)
- { /* No tables */
- my_errno=HA_ERR_END_OF_FILE;
- return -1;
- }
- isam_info=(info->current_table=info->open_tables)->table;
- if (info->cache_in_use)
- nisam_extra(isam_info,HA_EXTRA_CACHE);
- filepos=isam_info->s->pack.header_length;
- isam_info->lastinx= (uint) -1; /* Can't forward or backward */
- }
- else
- {
- isam_info=info->current_table->table;
- filepos= isam_info->nextpos;
- }
-
- for (;;)
- {
- isam_info->update&= HA_STATE_CHANGED;
- if ((error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf,
- filepos,1)) >= 0 ||
- my_errno != HA_ERR_END_OF_FILE)
- return (error);
- if (info->cache_in_use)
- nisam_extra(info->current_table->table,HA_EXTRA_NO_CACHE);
- if (info->current_table+1 == info->end_table)
- return(-1);
- info->current_table++;
- info->last_used_table=info->current_table;
- if (info->cache_in_use)
- nisam_extra(info->current_table->table,HA_EXTRA_CACHE);
- info->current_table->file_offset=
- info->current_table[-1].file_offset+
- info->current_table[-1].table->s->state.data_file_length;
-
- isam_info=info->current_table->table;
- filepos=isam_info->s->pack.header_length;
- isam_info->lastinx= (uint) -1;
- }
- }
- info->current_table=find_table(info->open_tables,
- info->end_table-1,filepos);
- isam_info=info->current_table->table;
- isam_info->update&= HA_STATE_CHANGED;
- return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf,
- (ulong) (filepos -
- info->current_table->file_offset),
- 0));
-}
-
-
- /* Find which table to use according to file-pos */
-
-static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos)
-{
- MRG_TABLE *mid;
-
- while (start != end)
- {
- mid=start+((uint) (end-start)+1)/2;
- if (mid->file_offset > pos)
- end=mid-1;
- else
- start=mid;
- }
- return start;
-}
diff --git a/merge/rsame.c b/merge/rsame.c
deleted file mode 100644
index 4ebf25b21c1..00000000000
--- a/merge/rsame.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mrgdef.h"
-
-
-int mrg_rsame(
-MRG_INFO *info,
-byte *record,
-int inx) /* not used, should be 0 */
-{
- if (inx)
- {
- my_errno=HA_ERR_WRONG_INDEX;
- return(-1);
- }
- if (!info->current_table)
- {
- my_errno=HA_ERR_NO_ACTIVE_RECORD;
- return(-1);
- }
- return nisam_rsame(info->current_table->table,record,inx);
-}
diff --git a/merge/static.c b/merge/static.c
deleted file mode 100644
index e5f95ef195a..00000000000
--- a/merge/static.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Static variables for pisam library. All definied here for easy making of
- a shared library
-*/
-
-#ifndef stdin
-#include "mrgdef.h"
-#endif
-
-LIST *mrg_open_list=0;
diff --git a/merge/update.c b/merge/update.c
deleted file mode 100644
index 9fcb82089e4..00000000000
--- a/merge/update.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Update last read record */
-
-#include "mrgdef.h"
-
-int mrg_update(
-register MRG_INFO *info,
-const byte *oldrec, const byte *newrec)
-{
- if (!info->current_table)
- {
- my_errno=HA_ERR_NO_ACTIVE_RECORD;
- return(-1);
- }
- return nisam_update(info->current_table->table,oldrec,newrec);
-}
diff --git a/mit-pthreads/.cvsignore b/mit-pthreads/.cvsignore
deleted file mode 100644
index 6b051949557..00000000000
--- a/mit-pthreads/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-config.cache
-config.h
-config.log
-config.status
-obj
diff --git a/mit-pthreads/COPYRIGHT b/mit-pthreads/COPYRIGHT
deleted file mode 100644
index 1b727cd8dac..00000000000
--- a/mit-pthreads/COPYRIGHT
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors,
-proven@mit.edu All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by Chris Provenzano,
- the University of California, Berkeley, and contributors.
-4. Neither the name of Chris Provenzano, the University, nor the names of
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO, THE REGENTS OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/mit-pthreads/Changes-mysql b/mit-pthreads/Changes-mysql
deleted file mode 100644
index da30f66fdec..00000000000
--- a/mit-pthreads/Changes-mysql
+++ /dev/null
@@ -1,237 +0,0 @@
-Changes done to this distrubtion (pthreads-1_60_beta6) by Monty (monty@mysql.com)
-
-02.05.07
-- Hacked some files to get it to compile (not work) with glibc 2.2
- This is needed so that we can do 'make dist' in the MySQL distribution
-
-02.04.26
-- removed the following files because of copyright problems
-
-machdep/i386-sco-3.2v5/__signal.h
-machdep/i386-sco-3.2v5/__stdio.h
-machdep/i386-sco-3.2v5/__stdlib.h
-machdep/i386-sco-3.2v5/__string.h
-machdep/i386-sco-3.2v5/__time.h
-machdep/i386-sco-3.2v5/__unistd.h
-machdep/i386-sco-3.2v5/compat.h
-machdep/i386-sco-3.2v5/dirent.h
-machdep/i386-sco-3.2v5/posix/__signal.h
-machdep/i386-sco-3.2v5/socket.h
-machdep/i386-sco-3.2v5/syscall.h
-machdep/i386-sco-3.2v5/timers.h
-machdep/i386-sco-3.2v5/trash.can
-machdep/sco-3.2v5/__math.h
-machdep/sco-3.2v5/__signal.h
-machdep/sco-3.2v5/__stdio.h
-machdep/sco-3.2v5/__stdlib.h
-machdep/sco-3.2v5/__string.h
-machdep/sco-3.2v5/__time.h
-machdep/sco-3.2v5/__unistd.h
-machdep/sco-3.2v5/compat.h
-machdep/sco-3.2v5/dirent.h
-machdep/sco-3.2v5/posix/__signal.h
-machdep/sco-3.2v5/socket.h
-machdep/sco-3.2v5/syscall.h
-machdep/sco-3.2v5/timers.h
-machdep/sco-3.2v5/trash.can
-
-93.04.01
-- socket() didn't return NOTOK (-1) on error.
-- bind() didn't set error code on failure
-
-93.03.27
-- Added patch by D. Richard Hipp <drh@vnet.net> to make strtod and
- printf (of floats/doubles) thread safe. Patch provided by mevans@cti-ltd.com
-- Added patch I got from lucid@secret.org to fix lock in fork().
-
-93.03.26
-- Fixed some include files for BSD 2.0.
-- Changed the prototype of ioctl() for BSD.
-- Fixed new bug in fd_kernel.c; _fd_kern_read returned sometimes wrong errno.
-
-93.03.22
-- Change sys/cdefs.h to get it through Sun cc.
-- Added patches by Mark Evans
- 1. Crashes and hangs.
- 2. Missing functionality (namely flock())
- 3. Use of POSIX reentrant safe routines.
-
-93.03.21
-- Add patches by Larry V. Streepy to fix pthread_cancel.
- Fixed bug in Streepy's patch that checked return values of read,write..
- in fd.c (Already done in fd_sys.c)
-
-1. Added a declaration of &#34;signal&#34; to include/signal.h
-2. Modified PANIC macro to operate like assert and call a new function
- panic_kernel. Added new file pthreads/panic.c.
-3. Added support for fstatfs syscall for linux (mod to
- syscall-i386-linux-1.0.S).
-4. Added missing function declarations to machdep/linux-1.0/socket.h:
- getsockopt
- setsockopt
- getsockname
- getpeername
- send
- recv
- sendto
- recvfrom
- sendmsg
- recvmsg
- shutdown
-5. Added ifdef to avoid type conflict in machdep/linux-1.0/timers.h
-6. Fix bug in getprotoent (bogus semi-colon after if stmt).
-7. Change function name in proto_internal.c from _proto_init to
- _proto_buf.
-8. Fix bug in res_internal.c where buffer pointer was improperly
- maintained.
-9. Fix return value handling for POSIX function implementations.
-10. Fix bug in select handling where a thread could be incorrectly
- resumed with no sockets ready. Also added proper handling of
- selecting for exceptions (this was not implemented at all).
-11. Added deadlock detection to pthread_join (it can now return an
- EDEADLK error).
-12. Added support for pthread_cancel, changes to lots of files for this.
-13. Add new function __pthread_is_valid that searches the pthread list
- for a specified pthread_t value.
-
-93.03.22
-- Fixed some if the tests according to the below changes.
-
-93.03.21 by "Mati Sauks" <mati@psti.com>
-- Fixed bug if priority queue was empty or (*current)->next is empty.
-
-96.03.20 by Josip Gracin
-- Fixed gethostbyname to handle alias
-
-97.02.07
-- Removed CVS directories.
-- Commented make install in GNUmakefile.in.
-
-97.01.26 by David (david@detron.se)
-- Fixed a dist target in the GNUmakefile
-- Added #undef PTHREAD_STACK_MIN to avoid warning on solaris 2.5
-
-97.01.21 by Monty (monty@tcx.se)
-
-- Added file mysql-TODO and the patches directory.
-- Added patch p153 and p155 by Tim Hinderliter and Chris Colohan
- check the patches directory for more info.
-- Changed pthread_cond_timedwait to return ETIME instead of ETIMEDOUT
- (Required by Posix)
-- Changed the include file pthread.h to add prototypes for the following
- functions: pthread_sigmask, sigwait and sigsetwait
-- Added shutdown() and getpeername() prototypes to 'machdep/sunos-5.3/socket.h'
-- Changed __FD_NONBLOCK to (O_NONBLOCK | O_NDELAY) in
- ./machdep/engine-sparc-sunos-5.3.h
-- Added rint() prototype to math.h
-- Added new slot sighandled to 'struct pthread' for easy check if somebody
- interrupts a system call.
-- pthread_kill can now interrupt the following system calls:
- select(), read(), write(), send(), sendto(), sendmsg(), recv_timedwait(),
- recvfrom_timedwait(), readev(), writeev() and some socket functions.
-- Fixed bug in pthread_kill() which count up 'sigcount' wrongly.
- Two pthread_kill() in a row bugged the thread.
-- Merged fd_kern_wait and fd_kern_poll to 1 function and removed a
- a bug when polling select.
-- Implemented getpeername().
-- Some small optimizations.
-- Some re-indentation to make the code readable by me (Sorry about that).
-
-97.08.15 by Monty (monty@tcx.se)
-
-- Added patch by "Chris G. Demetriou" <cgd@pa.dec.com> for NetBSD/alpha.
-
-97.08.18 by Monty (monty@tcx.se)
-
-- Added new machdep definitions for HPUX-10.20,
- by JOERG_HENNE@Non-HP-Germany-om88.om.hp.com
-
-97.09.25 by Monty (monty@tcx.se)
-
-- Added some definitions for i386-SCO from the site:
- http://www.sco.com/skunkware/osr5/libraries/
-
-97.10.12 by Monty (monty@tcx.se)
-
-- Changed prototype macro __P to __P_ to avoid warnings on Solaris.
-- Fixed interruption of select() with pthread_kill() when signal handler
- used read or write.
-
-97.10.16 by Monty (monty@tcx.se)
-
-- Fixed that blocked signals doesn't interrupt threads.
-
-97.10.20 by Monty (monty@tcx.se)
-
-- Fixed broken ftruncate system call for FreeBSD 2.0
- The old one destroyed the orignal file by truncation too much.
-- Fixed prototypes for des_setkey,encrypt and setkey (according to Solaris 2.5)
-
-97.11.26 by Monty (monty@tcx.se)
-
-- Small patch to avoid compile errors on alpha-OSF1 3.2
-
-97.12.18 by Monty (monty@tcx.se)
-
-- Added fix for Irix 5.3 in __unistd.h
-
-98.01.13 by Monty (monty@tcx.se)
-- Added fd_check_entry to dup2 and table sizecheck to fd_check_entry()
- patch by Martin Fuchs <Martin@igdv.fh-darmstadt.de>
-
-98.01.18 by Monty (monty@tcx.se)
-- Added prototype for gettimeofday() for Solars 2.3
-- Added some small fixes for configure and Solaris 2.6
-
-98.01.23 by Monty (monty@tcx.se)
-- Ported to openbsd.
-- Renamed nanosleep() to pthread_nanosleep() to avoid name conflict on
- openbsd.
-- Fixed link problem with variable __sglue for Irix 5.3
- by Vladislav Malyshkin <malyshki@cs.wmich.edu>.
-
-98.03.02 by Monty (monty@tcx.se)
-- Applied patches from Curt Sampson <cjs@portal.ca>; NetBSD 1.3/i386 port.
-
-98.03.09 by Monty (monty@tcx.se)
-- Applied patches from Curt Sampson <cjs@portal.ca>; NetBSD 1.3/Alpha port.
-
-98.05.12
-- Added unixware to config.guess
-
-98.06.07
-- Added patch by Scott Dybiec <sdybiec@humanfactor.com>:
- Fixed select() returning incorrect number of active file descriptors.
-
-99.06.07 by Monty (monty@mysql.com)
-- Added patches from the NETBSD site. Should fix the following platforms:
- alpha-netbsd-1.3, sparc-netbsd-1.3, i386-netbsd, arm32-netbsd
-
-99.09.09 by Monty (monty@mysql.com)
-- Added patches from Christoph Badura <bad@oreilly.de> for NetBSD
-
-99.09.13 by Monty (monty@mysql.com)
-- Added patches from Dirk Froemberg <dirk@FreeBSD.org> for FreeBSD
-
-99.10.18 by Monty (monty@mysql.com)
-- Added patch for machdep_sys_lseek() for netbsd.
-
-99.12.30 by Monty (monty@mysql.com)
-- Added patch by Christoph Badura <bad@oreilly.de> to update mit-pthreads
- to the same version as in the NetBSD pkgsrc.
-
-00.02.24 by Monty (monty@mysql.com)
-- Added configure files to make mit-pthreads to compile and link during
- newer linux systems (needed because of the MySQL configure system).
- The resulting library has however not been verified under Linux.
-
-00.03.30 by Monty (monty@mysql.com)
-- Added chroot() and gethostname().
-
-00.10.18 by Monty (monty@mysql.com)
-- Added patch by Dave Huang <khym@bga.com> to fix problem with date/time
- on NETBSD/Alpha.
-
-01.01.11 by Monty (monty@mysql.com)
-- Added patch by Allen Briggs <briggs@ninthwonder.com> for
- Apple PowerMac 8500 w/ G3 upgrade running NetBSD/macppc
diff --git a/mit-pthreads/FAQ b/mit-pthreads/FAQ
deleted file mode 100644
index e4fd3cfc6d8..00000000000
--- a/mit-pthreads/FAQ
+++ /dev/null
@@ -1,122 +0,0 @@
-
- Answers to frequently asked questions
- for my implementation of POSIX threads
-
--------------------------------------------------------------------------------
-1. Pthreads
-
-(1.0) What is Pthreads?
-(1.1) Where can I get info on Pthreads?
-
-2. Getting, Building, Installing and Using proven's Pthreads
-
-(2.0) Where can I get the latest version of proven's Pthreads?
-(2.1) What platforms does proven's Pthreads run on?
-(2.2) What do I need to build proven's Pthreads?
-(2.3) How do I install proven's Pthreads?
-
-3. Known Problems
-
-(3.0) Tests
-(3.1) Installation
-(3.2) Missing functionality
-(3.3) Signals
-
--------------------------------------------------------------------------------
-1. Pthreads
-
-(1.0) What is Pthreads?
-
-Pthreads stands for POSIX threads and is based on the POSIX 1003.1c 1995
-thread standard. This standard passed international Standards Organization
-(ISO) Committee Document (CD) balloting in February 1995 and got the
-IEEE Standards Board approval in June 1995.
-
-
-(1.1) Where can I get info on Pthreads?
-
-You can call IEEE (908) 562-3800 which is the organization which POSIX
-belongs, and ask for POSIX 1003.1c (not 1003.4a) draft 10 (the standard
-won't be out until sometime in 1996). The draft costs $30.00 plus shipping
-which for me was $4.00. The IEEE doesn't make any of the standards available
-online.
-
-I have made documentation for some of the functions available online.
-To reference these use http://www.mit.edu:8001/people/proven/pthreads.html
-
--------------------------------------------------------------------------------
-2. Getting, Building, Installing and Using proven's Pthreads
-
-(2.0) Where can I get the latest version of proven's Pthreads?
-
-The latest version is pthreads-1_60_beta6 was release on November 16, 1996
-and is available from sipb.mit.edu:/pub/pthreads.
-
-
-(2.1) What platforms does proven's Pthreads run on?
-
-Lot's! It should run on the following platforms; the i386 processor
-running NetBSD-1.x, FreeBSD-2.x, BSDOS-2.0, Linux-1.2 and Linux-1.3;
-the r2000 (DECstation) running Ultrix-4.2; the Sparc running NetBSD-1.x,
-SunOS-4.1.3, Solaris-2.3, and Solaris-2.4; the alpha running OSF-2.3 and
-OSF-3.x; the SGI running IRIX-5.2; and the HPPA running HP/UX-9.x.
-
-Because it runs on so many platforms I don't get to compile and test every
-platform for every release. If you have a problem send mail to
-pthreads-bugs@mit.edu with the processor, OS, and version number along with
-a description of the bug.
-
-
-(2.2) What do I need to build proven's Pthreads?
-
-You will need gcc and gmake to build for all but NetBSD, FreeBSD and BSDOS.
-For those you may use either gmake or pmake (the native make).
-
-
-(2.3) How do I install proven's Pthreads?
-
-Installing pthreads is real easy. At the top level of pthreads do
-
-configure
-make
-make install
-
-It will be installed into the directory /usr/local/pthreads. If you don't
-like the location add a --prefix=<dir> option to configure. That's it.
-
-
--------------------------------------------------------------------------------
-3. Known problems.
-
-(3.0) Tests
-
-Under SunOS-4.1.x there is a bug in the kernel that prevents test_sock_1
-from passing. This bug has to do with a process tring to connect to itself.
-In respose I wrote test_sock_2 to test the socket code for SunOS which
-does work. You should have no problems using the socket code in SunOS
-so long as you don't write a program that need to connect to itself.
-
-
-(3.1) Installation
-
-The only know problem is on the SGI. You will need to use GNU tar instead
-of the native supplied one or edit the config.flags file and remove the -h
-option to tar. Aparently the -h option on IRIX 5.3 version of tar does the
-exact opposite of all the other versions of tar I've used and instead of
-following symbolic links and getting the file it archives the link.
-
-
-(3.2) Missing functionality
-
-The current release is missing cancelation, priority mutexes and others.
-I'm continuing to develope pthreads and I plan to put cancelation and
-priority mutexes and as much other stuff as I can into the 1_70 release
-
-
-(3.3) Signals
-
-Currently to intermix signals with pthreads you need to rename all calls
-to signal() and sigaction() to pthread_signal() and pthread_sigaction().
-I plan to write real wrapper routines for signal() and sigaction() for
-the 1_70 release.
-
diff --git a/mit-pthreads/GNUmakefile b/mit-pthreads/GNUmakefile
deleted file mode 100644
index e3fd53b48e5..00000000000
--- a/mit-pthreads/GNUmakefile
+++ /dev/null
@@ -1,129 +0,0 @@
-# === GNUmakefile =============================================================
-# Copyright (c) 1991, 1992, 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating libpthread.a
-#
-# 1.00 93/11/17 proven
-# -Put all the .o files into one file libpthread.a
-# -Initial cut for pthreads.
-#
-
-INSTALL_PATH = $(exec_prefix)
-
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
- SUBINCDIR = $(INCDIR)/pthread
-
- AR = ar
- AS = gas
- CFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- -O3 -DDBUG_OFF -Werror
- CXXFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- -g -O2
- LD = gld
-
- CSRC =
-
- PTHREAD_DIR = pthreads stdlib stdio gen
- DIRS = $(PTHREAD_DIR)
-
- HEADERS =
-
- LIBRARIES = libpthread.a
-
- .CURDIR = .
-
-# force correct default target
-all:
-
-###############################################################################
-#
-# Read in any special flags that config knows about
-include config.flags
-
-# What the heck. Convert srcdir to absolute form so it looks prettier.
-srcdir := $(shell cd $(srcfoo) && pwd)
-
-################################################################################
-#
-# Here starts the nitty grity part of the Makefile.
-
-all-lib : libpthread.a
-
-include ${srcdir}/pthreads/GNUmakefile.inc
-include ${srcdir}/stdlib/GNUmakefile.inc
-include ${srcdir}/stdio/GNUmakefile.inc
-include ${srcdir}/string/GNUmakefile.inc
-include ${srcdir}/gen/GNUmakefile.inc
-include ${srcdir}/net/GNUmakefile.inc
-include ${srcdir}/scripts/GNUmakefile.inc
-
-REGULAR_OBJS= $(subst .cc,.o,$(SRCS))
-REGULAR_OBJS:= $(subst .c,.o,$(REGULAR_OBJS))
-REGULAR_OBJS:= $(subst .S,.o,$(REGULAR_OBJS))
-OBJS= $(REGULAR_OBJS) $(EXTRA_OBJS)
-REALOBJS = $(addprefix obj/, $(OBJS))
-
-$(REALOBJS) : $(config) $(types) $(paths)
-
-# Since we do not have a list of the relevant files we do a make clean
-# before copying everyting to the distribution directory.
-distdir:
- $(MAKE) clean
- cp -a . $(distdir)
- # Remove symlinks that the distribution should not have.
- rm -f $(distdir)/config.cache \
- $(distdir)/include/pthread/machdep.h \
- $(distdir)/include/pthread/posix.h \
- $(distdir)/include/sys \
- $(distdir)/machdep.c \
- $(distdir)/syscall.S \
- $(distdir)/syscall-template.S
-
-clean:
- rm -f a.out core maketmp makeout $(LIBRARIES) $(BINARIES) libpthread.*
- rm -rf obj
- cd tests && $(MAKE) clean && cd ..
-
-install-lib: $(LIBRARIES) install-dirs
- for x in $(LIBRARIES); \
- do install $$x $(DESTDIR)$(LIBDIR); \
- done
-
-# Removed make install since mysql uses this in place.
-# install-lib install-include install-bin
-install:
-
-libpthread.a: obj/libpthread.a
- rm -f libpthread.a
- ln -s obj/libpthread.a .
-
-obj/libpthread.a: ${REALOBJS}
- rm -f libpthread.a obj/new.a obj/libpthread.a
- cd obj && \
- ar r new.a ${OBJS} && \
- $(RANLIB) new.a && \
- mv -f new.a libpthread.a && \
- cd ..
-
-# For examining a combined symbol table, sizes, &c.
-libpthread.o: ${REALOBJS}
- cd obj && ld -r -o ../libpthread.o ${OBJS} && cd ..
-
-obj/x:
- if [ -d obj ]; then true; else mkdir obj; fi
- cp /dev/null obj/x
-
-GNUmakefile: config.status ${srcdir}/config/GNUmakefile.in
- $(SHELL) config.status
-
-obj/%.o: %.c obj/x
- $(CC) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.cc obj/x
- $(CXX) $(CXXFLAGS) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.S obj/x
- $(CC) $(CFLAGS) -c $< -o $@
diff --git a/mit-pthreads/NOTES b/mit-pthreads/NOTES
deleted file mode 100644
index cebdc6a396c..00000000000
--- a/mit-pthreads/NOTES
+++ /dev/null
@@ -1,59 +0,0 @@
-
-Here are some notes on the internals of the implementation.
-
-LIBC routines.
-
- Unfortuanately many of the libc routine return a pointer to static data.
-There are two methods to deal with this. One write a new routine where the
-arguments are different, and have one argument be a pointer to some space
-to store the data, or two use thread specific data and warn the user that
-data isn't valid if the calling thread is terminated.
-
-INTERNAL LOCKING
-To prevent deadlocks the following rules were used for locks.
-
-1. Local locks for mutex queues and other like things are only locked
- by running threads, at NO time will a local lock be held by
- a thread in a non running state.
-2. Only threads that are in a run state can attempt to lock another thread,
- this way, we can assume that the lock will be released shortly, and don't
- have to unlock the local lock.
-3. The only time a thread will have a pthread->lock and is not in a run
- state is when it is in the reschedule routine.
-4. The reschedule routine assumes all local locks have been released,
- there is a lock on the currently running thread (pthread_run),
- and that this thread is being rescheduled to a non running state.
- It is safe to unlock the currently running threads lock after it
- has been rescheduled.
-5. The reschedule routine locks the kernel, sets the state of the currently
- running thread, unlocks the currently running thread, calls the
- context switch routines.
-6 the kernel lock is used only ...
-
-
-7. The order of locking is ...
-
-1 local locks
-2 pthread->lock /* Assumes it will get it soon */
-3 pthread_run->lock /* Assumes it will get it soon, but must release 2 */
-4 kernel lock /* Currently assumes it will ALWAYS get it. */
-
-8. The kernel lock will be changed to a spin lock for systems that
-already support kernel threads, this way we can mutiplex threads onto
-kernel threads.
-9. There are points where the kernel is locked and it needs to get
-either a local lock or a pthread lock, if at these points the code
-fails to get the lock the kernel gives up and sets a flag which will
-be checked at a later point.
-10. Interrupts are dissabled while the kernel is locked, the interrupt
-mask must be checked afterwards or cleared in some way, after interrputs
-have been reenabled, this allows back to back interrupts, but should always
-avoid missing one.
-
-------------------------------------------------------------------------------
-Copyright (c) 1994 Chris Provenzano. All rights reserved.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-For further licencing and distribution restrictions see the file COPYRIGHT
-included in this directory.
diff --git a/mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE97 b/mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE97
deleted file mode 100644
index fd2e00c9860..00000000000
--- a/mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE97
+++ /dev/null
@@ -1,45 +0,0 @@
-This port to Osr5 was donated by
- ARTURO MONTES mitosys@colomsat.net.co
-Its a snapshot of the 1.60 Beta 5 version
-
-It passes all the tests except test_fork (this seems to be a problem
-with the MIT source)
-and I suspect there may also to be problems with
-the floating point initialisation and perhaps the netdb access as well
-
-
-Regarding the networking API's mind the following (ARTURO):
-
-- Always we are searching host address in /etc/hosts by default, if you
-want other behaviour let me to know.
-
-- If you haven't an entry in /etc/hosts, please create it and after test
-with DNS service.
-
-regarding floating point initialisation (ARTURO)
-
-...mit-pthreads/pthreads/tests> ./test_preemption_float
-test_preemption_float INDETERMINATE
-
-I inhibit the pthread float code, but they are a minor changes in machdep.c.
-
-> What did you do/needs to be done here ??
-
-Look into machdep.c machdep_save_float_state() and
-machdep_restore_float_state() routine. I think the initialization float
-code can have problems with pthread initialization code.
-
-----------------
-
-
-If you wish to rebuild from source you'll need the gnus devsys
-(gmake and gcc) and don't use configure to reconfigure the makefiles, etc
- ( I don't know why this is but it doesn't work)
-
-If Arturo keeps me updated with buildable snapshots I'll endeavour to keep
-the skunkware Website updated with them.
-
-
-Best of luck
-
-hops 01-Aug-97
diff --git a/mit-pthreads/README b/mit-pthreads/README
deleted file mode 100644
index 0a55bcd94bb..00000000000
--- a/mit-pthreads/README
+++ /dev/null
@@ -1,40 +0,0 @@
-This pthread package is/will be based on the POSIX1003.1c Draft 10 pthread
-standard, and Frank Muellers paper on signal handeling presented at the
-Winter 93 USENIX conference.
-
-It is currently being designed and written by me, Chris Provenzano.
-All bug, comments, and questions can be sent me at proven@mit.edu,
-or pthreads@mit.edu.
-
-PLEASE, don't send questions, bugs or patches to any of the *BSD*, Linux
-or GNU mailing lists.
-
-Thanks goes to Ken Raeburn for his help on the Sparc port, the configurator,
-and his many suggestions, Greg Hudson for the thread safe net routines and
-all the testing he's done.
-
-More thanks to Mark Eichin and all the others for the testing they have done.
-
-PORTING
-One of the goals of this user space implementation of pthreads is that it
-be portable. I have minimized the ammount of assembler code necessary,
-but some is.
-
-If you want to port it to another platform here are a few basic hints.
-
-You will need to create a machdep.h, machdep.c and syscall.S for the
-new architecture. The first two are necessary to get the context switch
-section of the pthread package running, the third is for all the syscalls.
-
-INCLUDE FILES AND PORTING
-In addition to the above three files you need to create a slew of .h files.
-Take a look at an existing port to determine what is in each, and then
-take a look at your system header files to determine what to put in them.
-
-------------------------------------------------------------------------------
-Copyright (c) 1993, 1994, 1995, 1996 Chris Provenzano. All rights reserved.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-For further licencing and distribution restrictions see the file COPYRIGHT
-included in this directory.
diff --git a/mit-pthreads/TODO-mysql b/mit-pthreads/TODO-mysql
deleted file mode 100644
index a19b1bd51d6..00000000000
--- a/mit-pthreads/TODO-mysql
+++ /dev/null
@@ -1,4 +0,0 @@
-This what should be done to get more functionally for mysqld.
-
-- open should be interruptable.
-- fcntl lock should be interruptable.
diff --git a/mit-pthreads/Whats_New b/mit-pthreads/Whats_New
deleted file mode 100644
index 556d9f63268..00000000000
--- a/mit-pthreads/Whats_New
+++ /dev/null
@@ -1,198 +0,0 @@
-For patches made to this release, check the file Changes-mysql
-
-For the 96/11/11 release version 1_60_beta6
-
- Ports
- Alpha running NetBSD-1.1 by Chris G Demetriou <cgd+@cs.cmu.edu>
- i386 running BSDi-2.1 by David J MacKenzie <djm@va.pubnix.com>
-
- Bug Fixes
- Test for struct timespec under linux and DTRT.
- include/unistd.h : #define SEEK_SET, SEEK_CUR, and SEEK_END.
- Bug reported by Stephen Tether <tether@MITLNS.MIT.EDU>
- stdlib/system.c : Uses the POSIX signal systemcalls.
- Bug reported by Matthew Newhook <matthew@thor.udc.neweast.ca>.
- net/gethostbyname.c: #include <string.h> and fix dereference problem.
- Bug reported by Chris G Demetriou <cgd+@cs.cmu.edu>
- pthreads/fd.c: Fix bug in close() reported by
- Bug reported by "William S. Lear" <rael@dejanews.com>
- tests/p_bench_pthread_create.c : Only try and create 10000 threads.
- include/pthread/sleep.h : No need to prototype machdep_gettimeofday()
- since it is declared here.
- Bug reported by Stewart Gebbie <stewart@global.co.za>
- stdio/fwrite.c: Fixed bug where if total bytes written = 0 then a divid
- by 0 occurs. Thanks to CTLarsen@lbl.gov for finding is and to
- Jin Guojun <jin@george.lbl.gov> for submitting a patch for it.
- stdio/refill.c (__swalk_lflush()): Second pass of flush should call
- flockfile() not ftrylockfile(). Just like in __swalk_sflush()
- net/res_internal.c (_res_parse_answer()): It looks like if
- iquery is true and type == T_PTR then the result->h_name
- will be over written because the bp isn't incrementd
- appropriately. Thanks to David Halls <David.Halls@cl.cam.ac.uk>
- for finding it.
- net/serv_internal.c (_serv_buf()) : Allocate more than four bytes
- of buffer space. Reported by drh@@tobit.vnet.net.
- pthreads/fd_kern.c: Make sure exception fds are included in
- machdep_sys_select() for support of select(). Thanks to
- Larry V. Streepy, Jr. <streepy@healthcare.com> for the patches.
- pthreads/fd_kern.c: Fix more I/O routines to report NOTOK on error
- instead of the old -error number. Hopefully this is the last of
- them. Thanks to Larry V. Streepy, Jr. <streepy@healthcare.com> for
- the patches.
- machdep/engine-i386-linux-1.0.c: Remove unneeded machdep_sys_readv()
- and machdep_sys_writev() routines. Reported by
- pthreads/process.c : Fix execl() and execle() to work on sparc systems.
- pthreads/fd_sysv.c : Fix accept() to work under Solaris 2.4
-
-
-For the 96/03/09 release version 1_60_beta5
-
- Ports
- Sparc running NetBSD-1.1
-
- Additions
- New reentrant netdb similar to Solaris API (ghudson)
-
- Bug Fixes
- Make default signal handlers work.
- Deadlock scheduling bug reported by Cathy Abbott <cabbot@cs.utk.edu>
- See pthreads-bugs transaction 31
- pthread/queue.c (pthread_queue_remove()): Don't set thread->queue and
- thread->next to NULL unless the thread is removed from the queue.
- pthreads/fd.c (setsockopt(), getsockopt(), getsockname(),
- getpeername()) : Call fd_lock() with appropriate paramaters.
- pthreads/fd_kern.c (sendmsg_timedwait()): Call fd_unlock() with
- FD_WRITE instead of FD_READ paramater.
- machdep/*/timers.h net/res_send.c, pthreads/cond.c, pthreads/select.c
- pthreads/sleep.c, tests/test_pthread_cond_timedwait.c:
- Change timespec to be POSIX compliant.
- include/unistd.h : Change u_int to unsigned [int] in prototypes.
- pthreads/fd.c : Use FD_SETSIZE instead of 1024 for a limit on fds.
-
-
-For the 95/09/xx release version 1_60_beta4
-
- Ports
- SGI running IRIX-5.3
-
- Additions
- Added pthread_sigprocmask().
- Added CV attributes
-
- strtok() and strtok_r() (Greg Hudson)
- getsockname() (Sean Levy)
-
- Bug Fixes
- stdio/fwalk.c, stdio/refill.c : Use flockfile() instead of
- ftrylockfile()/pthread_yield(), for traversing FILE list.
- pthreads/sig.c : Remove enum pthread_sig_flags and just use the vector.
- Added pthread_sigprocmask().
- pthreads/signal.c : Protect calls to pthread_sig_process().
- configure : Create the obj directory.
- tests/test_preemption_float.c : Rewritten to actually work.
- machdep/engine-i386-linux-1.0.c : Added __strtol_internal()
- tests/test_stdio_1.c : Don't use base_name or dir_name as variables.
- gen/getcwd.c : fstat => machdep_sys_fstat, since kernel fd's are
- used in the DIR data structure
- gen/isatty.c : Fixed call to fd_lock() to pass the right # args.
- pthreads/pthread_init.c : Fixed uninitialized members of
- pthread_initial.
-
-
-
-For the 95/06/xx release version 1_60_beta3
-
- Additions
- Add exec variants execl, execlp, execv, execvp (Ken Raeburn)
- pthreads/fd_sysv.c : Added routines setsockopt() and getsockname().
- Added include/endian.h : For machine dependent endian junk. (YUCK)
- Added socketpair()
- Added ttyname_r()
-
- Bug Fixes
- config/Makefile.in : Need $$ to reference shell variables in make.
- config/configure, config/configure.in : Redo freebsd2.* machine.
- machdep/sunos-4.1.3/__stdlib.h : typedef pthread_size_t size_t
- pthreads/fd.c : Fix bug with fd_free(), dup(), dup2(), and close()
- where a fd gets lost after a dup() then close().
- pthreads/fd_kern.c : The fd_table[fd]->flags of the fd that accept()
- returns should be the same as those of the fd passed to accept().
- stdio/fclose.c : Don't call funlockfile(fp) after fp->_file has been
- closed.
- pthreads/select.c : Move pthread_sched_prevent() inside the statement.
- if (machdep_sys_select(...) == OK)
- pthreads/machdep/linux-1.0/cdefs.h : moved the include_next outside
- of the ifdef so that it would eventually find the system cdefs.h
- pthreads/signal.c : Check sig_to_process before and after fd_kern_wait()
- . It is possible for sig_handler_fake() to registered one.
- pthreads/signal.c : Unset pthread_run temporarily around the call to
- sig_handler(0). places where this causes core dumps should check
- pthread_run.
- include/stdlib.h : Fix prototype for bsearch().
- machdep/syscall-i386-freebsd-2.0.S syscall-template-i386-freebsd2.0.S:
- Fix macro expansion problems for FreeBSD-2.0
- machdep/engine-sparc-sunos-5.3.c : Fix machdep_sys_select() to return
- machdep_sys_poll() errors and not the number of entries found.
- gen/getcwd.c : Use strlen(dp->d_name) not dp->d_namlen because there
- may be extra data associated with dp->d_namelen.
- machdep/freebsd-2.0/__unistd.h: Change #define _POSIX_VDISABLE to 0xff
- include/pthread.h : Added prototypes pthread_kill(), pthread_signal()
- machdep/linux-1.0/__signal.h : Added #define __sigmask() and
- #define sigmask, and fixed other SIG macros to use __sigmask.
- machdep/linux-1.0/dirent.h : #include <sys/types.h>
- machdep/linux-1.0/wait.h : Fix #define WIFSTOPPED(x) to use __WSTATUS(x)
- machdep/syscall-i386-linux-1.0.S : Added elf support. (NOT TESTED)
- pthreads/stat.c : Added to separate linux stat calls.
- (SGI will need this too)
- pthreads/signal.c : Whereever #ifdef (SA_RESETHAND) is used then
- #ifdef (SA_RESTART) also
- gen/isatty.c : isatty_basic() is called with the KFD not UFD.
- machdep/sunos-4.1.3/__stdlib.h : #include <sys/stdtypes.h>
- config/sun4os4.mk : Added pipe to SYSCALL_EXCEPTIONS
- machdep/syscall-sparc-sunos-4.1.3.S : Add machdep_sys_pipe().
- include/stdio.h : Remove __getc() and __putc(), because they really
- shouldn't be inlined.
- machdep/sunos-4.1.3/stat.h : Added __BEGIN_DECLS and __END_DECLS.
- machdep/alpha-osf1/cdefs.h, machdep/hpux-9.03/cdefs.h
- machdep/linux-1.0/cdefs.h, machdep/sunos-4.1.3/cdefs.h
- machdep/sunos-5.3/cdefs.h, machdep/ultrix-4.2/cdefs.h :
- #define __INLINE static inline and don't #define
- __CAN_DO_EXTERN_INLINE if __cplusplus and __GCC__ is defined.
- pthreads/fd_sysv.c : Fix so that only systems without socket systemcalls
- compile this file.
- machdep/engine-i386-linux-1.0.c : Fix linux machdep_sys_getdirentries()
- pthreads/gen : Nuke the signal-blocking code in pclose(). It doesn't do
- any good in a threaded program; some other thread would just get
- the signal.
-
-
-For the 94/11/xx release version 1_60
-
- Additions
- Added recvfrom_timedwait(), and similar calls
- Added thread safe time routines: ctime(), localtime(), ...
- Added thread safe rand routines: rand(), random(), ...
- Added priorities and releated routines: pthread_attr_getschedparam(),
- Added signals and releated routines:pthread_kill(), sigwait(), ...
- Added mutex attribues and releated routines: pthread_mutexattr_init(), .
- Added abort
-
- Added counting (recursive) mutexes.
- Added debugging mutexes.
- Added some more tests
-
- Redid entire thread kernel because of priorities, and signals.
- Test and set instructions no longer necessary for versions
- that don't support kernel threads.
-
- More debugging by Greg Hudson along with the network lookup routines
- An Alpha port from Ken Raeburn and Sean Levy
- A solaris port from me.
- select() implementations from Sean Levy and Peter Hofmann
- configure from Ken Raeburn
- pthread_init() no longer necessary for systems with G++ from Ken Raeburn
- net code from Greg Hudson including: gethostbyname(), ...
-
- Bug fixes:
- honor _POSIX_THREAD_DESTRUCTOR_ITERATIONS
- pthread_key_destroy() is really pthread_key_delete()
diff --git a/mit-pthreads/bin/.cvsignore b/mit-pthreads/bin/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/bin/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/bin/Makefile.in b/mit-pthreads/bin/Makefile.in
deleted file mode 100644
index 979ad2db2ea..00000000000
--- a/mit-pthreads/bin/Makefile.in
+++ /dev/null
@@ -1,48 +0,0 @@
-# === GNUmakefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-CC = ../pgcc -notinstalled
-srctop = @srctop@
-srcdir = @srctop@/lib
-VPATH = @srctop@/lib
-CDEBUGFLAGS = @CFLAGS@
-
-CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
-
-#
-DIRS = finger
-
-################################################################################
-#
-all:
- (for i in $(DIRS); do cd $$i; $(MAKE) all; cd ..; done)
-
-clean:
- (for i in $(DIRS); do cd $$i; $(MAKE) clean; cd ..; done)
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- (for i in $(DIRS); do cd $$i; $(MAKE) depend; cd ..; done)
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install:
- (for i in $(DIRS); do cd $$i; $(MAKE) install; cd ..; done)
-
-realclean: clean
- (for i in $(DIRS); do cd $$i; $(MAKE) realclean; cd ..; done)
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd .. ; sh config.status)
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/bin/finger/.cvsignore b/mit-pthreads/bin/finger/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/bin/finger/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/bin/finger/Makefile.in b/mit-pthreads/bin/finger/Makefile.in
deleted file mode 100755
index ee20f47443d..00000000000
--- a/mit-pthreads/bin/finger/Makefile.in
+++ /dev/null
@@ -1,60 +0,0 @@
-# === makefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-srctop = @srctop@
-srcdir = @srctop@/bin/finger
-VPATH = @srctop@/bin/finger
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-
-INSTALL_PATH = @exec_prefix@
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
-
- CC = ../../pgcc -notinstalled
- CDEBUGFLAGS = @CFLAGS@
- INCLUDES = -I@srctop@/lib/libpthreadutil/ -L../../lib/libpthreadutil/
- CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
- RANLIB = @RANLIB@
-
- OBJS = finger.o net.o
- BINARY = finger
-
-################################################################################
-#
-all : $(BINARY)
-
-clean:
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install: $(BINARY)
- install $(BINARY) $(BINDIR)
-
-realclean: clean
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd ../.. ; sh config.status)
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
-$(BINARY) : ${OBJS}
- $(CC) $(CFLAGS) -o $(BINARY) ${OBJS} -lpthreadutil
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/bin/finger/finger.c b/mit-pthreads/bin/finger/finger.c
deleted file mode 100755
index 33b3011e8bb..00000000000
--- a/mit-pthreads/bin/finger/finger.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* ==== finger.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano,
- * the University of California, Berkeley and its contributors.
- * 4. Neither the name of Chris Provenzano, the University nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, THE REGENTS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * 1.00 93/08/26 proven
- * -Pthread redesign of this file.
- *
- * 1.10 95/02/11 proven
- * -Now that gethostbyname works ....
- */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
- @(#) Copyright (c) 1993, 1995 Chris Provenzano.\n\
- @(#) Copyright (c) 1995 Greg Stark.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#include <pthreadutil.h>
-#include <sys/param.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-void *netfinger();
-
-void usage(int eval)
-{
- fprintf(stderr,
- "usage: finger [-lps] [-c <net_count>] [-t|T <timeout>] [-f <filename>] [login ...]\n");
- exit(eval);
-}
-
-/*
- * These globals are set initialy and then are only read.
- * They do not need mutexes.
- */
-int thread_time = 0, program_timeout = 0, lflag = 0;
-pthread_tad_t parse_file_tad;
-pthread_tad_t netfinger_tad;
-
-void * timeout_thread(void * arg)
-{
- sleep(program_timeout);
- exit(0);
-}
-
-void * signal_thread(void * arg)
-{
- int sig;
- sigset_t program_signals;
- sigemptyset(&program_signals);
- sigaddset(&program_signals, SIGINT);
- sigwait(&program_signals, &sig);
- exit(0);
-}
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-void * parse_file(void * arg)
-{
- char hostname[MAXHOSTNAMELEN];
- char * filename = arg;
- pthread_atexit_t atexit_id;
- pthread_attr_t attr;
- pthread_t thread_id;
- char * thread_arg;
- FILE * fp;
- int len;
-
- netsetupwait();
-
- /* Parse the file and create a thread per connection */
- if ((fp = fopen(filename, "r")) == NULL) {
- fprintf(stderr, "Can't open file %s\n", filename);
- pthread_exit(NULL);
- }
- pthread_atexit_add(&atexit_id, fclose_nrv, fp);
-
- if (pthread_attr_init(&attr)) {
- fprintf(stderr, "Error: Can't initialize thread attributes\n");
- exit(2);
- }
- pthread_atexit_add(&atexit_id, pthread_attr_destroy_nrv, &attr);
-
- while (fgets(hostname, MAXHOSTNAMELEN, fp)) {
- if ((thread_arg = (char *)malloc(len = strlen(hostname))) == NULL) {
- fprintf(stderr, "Error: out of memory\n");
- exit(2);
- }
-
- hostname[len - 1] = '\0';
- strcpy(thread_arg, hostname);
- pthread_attr_setcleanup(&attr, free, thread_arg);
- if (pthread_tad_create(&netfinger_tad, &thread_id, NULL,
- netfinger, thread_arg)) {
- fprintf(stderr, "Error: pthread_tad_create() netfinger_tad.\n");
- exit(2);
- }
- }
- pthread_exit(NULL);
-}
-
-main(int argc, char **argv)
-{
- pthread_atexit_t atexit_id;
- pthread_t thread_id;
- int max_count = 0;
- char ch;
-
- /* getopt variables */
- extern char *optarg;
- extern int optind;
-
- /* Setup tad for parse_file() threads */
- if (pthread_tad_init(&parse_file_tad, max_count)) {
- fprintf(stderr,"Error: couldn't create parse_file() TAD.\n");
- exit(1);
- }
-
- while ((ch = getopt(argc, argv, "c:f:t:T:ls")) != (char)EOF)
- switch(ch) {
- case 't': /* Time to let each thread run */
- if ((thread_time = atoi(optarg)) <= 0) {
- usage(1);
- }
- break;
- case 'T': /* Time to let entire program run */
- if ((program_timeout = atoi(optarg)) <= 0) {
- usage(1);
- }
- break;
- case 'f': /* Parse file for list of places to finger */
- if (pthread_tad_create(&parse_file_tad, &thread_id, NULL,
- parse_file, optarg)) {
- fprintf(stderr,"Error: pthread_tad_create() parse_file_tad.\n");
- exit(1);
- }
- break;
- case 'c':
- max_count = atoi(optarg);
- break;
- case 'l': /* long format */
- lflag = 1;
- break;
- case 's': /* short format */
- lflag = 0;
- break;
- case '?':
- usage(0);
- default:
- usage(1);
- }
-
- /* The rest of the argumants are hosts */
- argc -= optind;
- argv += optind;
-
- /* Setup timeout thread, if there is one */
- if (program_timeout) {
- if (pthread_create(&thread_id, NULL, timeout_thread, NULL)) {
- fprintf(stderr,"Error: couldn't create program_timeout() thread\n");
- exit(1);
- }
- }
-
- /* Setup cleanup thread for signals */
- if (pthread_create(&thread_id, NULL, signal_thread, NULL)) {
- fprintf(stderr,"Error: couldn't create signal_timeout() thread\n");
- exit(1);
- }
-
- /* Setup tad for netfinger() threads */
- if (pthread_tad_init(&netfinger_tad, max_count)) {
- fprintf(stderr,"Error: couldn't create netfinger() TAD.\n");
- exit(1);
- }
-
- /* Setup the net and let everyone run */
- netsetup();
-
- while (*argv) {
- if (pthread_tad_create(&netfinger_tad, &thread_id, NULL,
- netfinger, *argv)) {
- fprintf(stderr, "Error: pthread_tad_create() netfinger_tad.\n");
- exit(2);
- }
- argv++;
- }
- pthread_tad_wait(&parse_file_tad, 0);
- pthread_tad_wait(&netfinger_tad, 0);
- exit(0);
-}
-
diff --git a/mit-pthreads/bin/finger/net.c b/mit-pthreads/bin/finger/net.c
deleted file mode 100755
index 77ccd92ee8c..00000000000
--- a/mit-pthreads/bin/finger/net.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* ==== net.c ============================================================
- * Copyright (c) 1993, 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * 1.00 93/08/26 proven
- * -Pthread redesign of this file.
- */
-
-#include <pthreadutil.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-/*
- * These globals are set initialy and then are only read.
- * They do not need mutexes.
- */
-extern int lflag;
-char myhostname[MAXHOSTNAMELEN];
-
-/*
- * These globals change and therefor do need mutexes
- */
-pthread_mutex_t spmutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t spcond = PTHREAD_COND_INITIALIZER;
-struct servent *sp = NULL;
-
-void netsetup(void)
-{
- pthread_mutex_lock(&spmutex);
- if (sp) {
- fprintf(stderr, "finger: service pointer already initialized.\n");
- exit(2);
- }
- if ((sp = (struct servent *)malloc(sizeof(struct servent) + 4096)) == NULL){
- fprintf(stderr, "finger: Couldn't allocate service pointer.\n");
- exit(2);
- }
- if (getservbyname_r("finger", "tcp", sp, (char *)sp + sizeof(struct servent), 4096) == NULL) {
- fprintf(stderr, "finger: tcp/finger: unknown service\n");
- exit(2);
- }
- if (gethostname(myhostname, MAXHOSTNAMELEN)) {
- fprintf(stderr, "finger: couldn't get my hostname.\n");
- exit(2);
- }
- pthread_cond_broadcast(&spcond);
- pthread_mutex_unlock(&spmutex);
-}
-
-void netsetupwait(void)
-{
- pthread_mutex_lock(&spmutex);
- while(sp == NULL) {
- pthread_cond_wait(&spcond, &spmutex);
- }
- pthread_mutex_unlock(&spmutex);
-}
-
-void *netfinger(char *name)
-{
- pthread_atexit_t atexit_id;
- register int c, lastc;
- struct in_addr defaddr;
- struct hostent *hp;
- struct sockaddr_in sin;
- int s, i, readbuflen;
- char readbuf[1024];
- char *host;
-
- netsetupwait();
- pthread_atexit_add(&atexit_id, fflush_nrv, NULL);
-
- if (!(host = strrchr(name, '@'))) {
- host = myhostname;
- } else {
- *host++ = '\0';
- }
- if (!(hp = gethostbyname(host))) {
- if ((defaddr.s_addr = inet_addr(host)) < 0) {
- fprintf(stderr, "[%s] gethostbyname: Unknown host\n", host);
- return;
- }
- }
- sin.sin_family = hp->h_addrtype;
- memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
- sin.sin_port = sp->s_port;
-
- if ((s = socket(sin.sin_family, SOCK_STREAM, 0)) < 0) {
- sprintf(readbuf, "[%s]: socket", hp->h_name);
- perror(readbuf);
- return;
- }
-
- /* have network connection; identify the host connected with */
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- sprintf(readbuf, "[%s]: connect", hp->h_name);
- perror(readbuf);
- close(s);
- return;
- }
-
- /* -l flag for remote fingerd */
- if (lflag)
- write(s, "/W ", 3);
- /* send the name followed by <CR><LF> */
- write(s, name, strlen(name));
- write(s, "\r\n", 2);
-
- /*
- * Read from the remote system; once we're connected, we assume some
- * data. If none arrives, we hang until the user interrupts, or
- * until the thread timeout expires.
- *
- * If we see a <CR> or a <CR> with the high bit set, treat it as
- * a newline; if followed by a newline character, only output one
- * newline.
- *
- * Otherwise, all high bits are stripped; if it isn't printable and
- * it isn't a space, we can simply set the 7th bit. Every ASCII
- * character with bit 7 set is printable.
- */
- for (readbuflen = read(s, readbuf, 1024), flockfile(stdout), lastc = '\n',
- printf("[%s]\n", hp->h_name); readbuflen > 0;
- readbuflen = read(s, readbuf, 1024)) {
- for (i = 0; i < readbuflen; i++) {
- c = readbuf[i] & 0x7f;
- if (c == 0x0d) {
- c = '\n';
- lastc = '\r';
- } else {
- if (!isprint(c) && !isspace(c))
- c |= 0x40;
- if (lastc != '\r' || c != '\n')
- lastc = c;
- else {
- lastc = '\n';
- continue;
- }
- }
- putchar_unlocked(c);
- }
- }
- if (lastc != '\n')
- putchar_unlocked('\n');
- funlockfile(stdout);
-}
diff --git a/mit-pthreads/config/COPYING.GNU b/mit-pthreads/config/COPYING.GNU
deleted file mode 100755
index a43ea2126fb..00000000000
--- a/mit-pthreads/config/COPYING.GNU
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/mit-pthreads/config/COPYRIGHT b/mit-pthreads/config/COPYRIGHT
deleted file mode 100755
index ba3ac43c589..00000000000
--- a/mit-pthreads/config/COPYRIGHT
+++ /dev/null
@@ -1,4 +0,0 @@
-The files config.guess and config.sub in this directory come from the GNU
-autoconf distribution, and are covered by the GNU Public License, which may
-be found in the file COPYING.GNU. They are the only files covered by the
-GPL.
diff --git a/mit-pthreads/config/GNUmakefile.in b/mit-pthreads/config/GNUmakefile.in
deleted file mode 100755
index 7c06ee367e6..00000000000
--- a/mit-pthreads/config/GNUmakefile.in
+++ /dev/null
@@ -1,129 +0,0 @@
-# === GNUmakefile =============================================================
-# Copyright (c) 1991, 1992, 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating libpthread.a
-#
-# 1.00 93/11/17 proven
-# -Put all the .o files into one file libpthread.a
-# -Initial cut for pthreads.
-#
-
-INSTALL_PATH = $(exec_prefix)
-
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
- SUBINCDIR = $(INCDIR)/pthread
-
- AR = ar
- AS = gas
- CFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- @CFLAGS@
- CXXFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- @CXXFLAGS@
- LD = gld
-
- CSRC =
-
- PTHREAD_DIR = pthreads stdlib stdio gen
- DIRS = $(PTHREAD_DIR)
-
- HEADERS =
-
- LIBRARIES = libpthread.a
-
- .CURDIR = .
-
-# force correct default target
-all:
-
-###############################################################################
-#
-# Read in any special flags that config knows about
-include config.flags
-
-# What the heck. Convert srcdir to absolute form so it looks prettier.
-srcdir := $(shell cd $(srcfoo) && pwd)
-
-################################################################################
-#
-# Here starts the nitty grity part of the Makefile.
-
-all-lib : libpthread.a
-
-include ${srcdir}/pthreads/GNUmakefile.inc
-include ${srcdir}/stdlib/GNUmakefile.inc
-include ${srcdir}/stdio/GNUmakefile.inc
-include ${srcdir}/string/GNUmakefile.inc
-include ${srcdir}/gen/GNUmakefile.inc
-include ${srcdir}/net/GNUmakefile.inc
-include ${srcdir}/scripts/GNUmakefile.inc
-
-REGULAR_OBJS= $(subst .cc,.o,$(SRCS))
-REGULAR_OBJS:= $(subst .c,.o,$(REGULAR_OBJS))
-REGULAR_OBJS:= $(subst .S,.o,$(REGULAR_OBJS))
-OBJS= $(REGULAR_OBJS) $(EXTRA_OBJS)
-REALOBJS = $(addprefix obj/, $(OBJS))
-
-$(REALOBJS) : $(config) $(types) $(paths)
-
-# Since we do not have a list of the relevant files we do a make clean
-# before copying everyting to the distribution directory.
-distdir:
- $(MAKE) clean
- cp -a . $(distdir)
- # Remove symlinks that the distribution should not have.
- rm -f $(distdir)/config.cache \
- $(distdir)/include/pthread/machdep.h \
- $(distdir)/include/pthread/posix.h \
- $(distdir)/include/sys \
- $(distdir)/machdep.c \
- $(distdir)/syscall.S \
- $(distdir)/syscall-template.S
-
-clean:
- rm -f a.out core maketmp makeout $(LIBRARIES) $(BINARIES) libpthread.*
- rm -rf obj
- cd tests && $(MAKE) clean && cd ..
-
-install-lib: $(LIBRARIES) install-dirs
- for x in $(LIBRARIES); \
- do install $$x $(DESTDIR)$(LIBDIR); \
- done
-
-# Removed make install since mysql uses this in place.
-# install-lib install-include install-bin
-install:
-
-libpthread.a: obj/libpthread.a
- rm -f libpthread.a
- ln -s obj/libpthread.a .
-
-obj/libpthread.a: ${REALOBJS}
- rm -f libpthread.a obj/new.a obj/libpthread.a
- cd obj && \
- ar r new.a ${OBJS} && \
- $(RANLIB) new.a && \
- mv -f new.a libpthread.a && \
- cd ..
-
-# For examining a combined symbol table, sizes, &c.
-libpthread.o: ${REALOBJS}
- cd obj && ld -r -o ../libpthread.o ${OBJS} && cd ..
-
-obj/x:
- if [ -d obj ]; then true; else mkdir obj; fi
- cp /dev/null obj/x
-
-GNUmakefile: config.status ${srcdir}/config/GNUmakefile.in
- $(SHELL) config.status
-
-obj/%.o: %.c obj/x
- $(CC) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.cc obj/x
- $(CXX) $(CXXFLAGS) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.S obj/x
- $(CC) $(CFLAGS) -c $< -o $@
diff --git a/mit-pthreads/config/Makefile.in b/mit-pthreads/config/Makefile.in
deleted file mode 100644
index 3fa388d740b..00000000000
--- a/mit-pthreads/config/Makefile.in
+++ /dev/null
@@ -1,56 +0,0 @@
-# @(#)Makefile 5.2 (Berkeley) 3/5/91
-#
-
-LIB=pthread
-NOPIC=1
-NOPROFILE=1
-NOLINT=1
-MKPIC=no
-MKPROFILE=no
-MKLINT=no
-CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/include -I${srcdir}/include -DPTHREAD_KERNEL
-CDEBUGFLAGS= @CFLAGS@
-CFLAGS+= ${CDEBUGFLAGS}
-# CFLAGS+= ${CPPFLAGS} <- done by bsd.lib.mk
-CFLAGS+= ${CPPFLAGS}
-LIBDIR= $(exec_prefix)/lib
-BINDIR= $(exec_prefix)/bin
-INCDIR= $(exec_prefix)/include
-MANDIR= $(exec_prefix)/man
-
-.OBJDIR != if test -d ${.CURDIR}/obj ; then true ; else mkdir ${.CURDIR}/obj || exit 1 ; fi ; echo ${.CURDIR}/obj
-
-# Standard bsd install rules look for the "install" program, rather than
-# using some variable. So, hack things so that that install rule works.
-BINGRP != echo " " `groups` " " | sed 's/ [0-9][0-9]* / /g' | awk '{print $$1}'
-BINOWN != echo $${USER}
-LIBMODE = 644 # so ranlib can run!
-
-.include "config.flags"
-
-# %!$@ pmake seems to automagically cd into the obj directory, so relative
-# srcdir references are completely botched. Try to figure out an absolute
-# pathname for srcdir here, and live with it.
-srcdir = $(srctop)
-
-beforeinstall: install-dirs
-
-.include "${srcdir}/pthreads/Makefile.inc"
-.include "${srcdir}/stdlib/Makefile.inc"
-.include "${srcdir}/stdio/Makefile.inc"
-.include "${srcdir}/string/Makefile.inc"
-.include "${srcdir}/gen/Makefile.inc"
-.include "${srcdir}/net/Makefile.inc"
-.include "${srcdir}/scripts/Makefile.inc"
-
-$(OBJS) : $(config) $(types) $(paths)
-
-Makefile: ${srcdir}/config/Makefile.in
- cd ${.CURDIR} && sh config.status
-
-all-lib : libpthread.a
-# Removed make install since mysql uses this in place.
-#install : install-bin install-include
-install:
-
-.include <bsd.lib.mk>
diff --git a/mit-pthreads/config/acconfig.h b/mit-pthreads/config/acconfig.h
deleted file mode 100644
index 14552b0d851..00000000000
--- a/mit-pthreads/config/acconfig.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Does the OS already support struct timespec */
-#undef _OS_HAS_TIMESPEC
-
-/* For networking code: an integral type the size of an IP address (4
- octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipaddr_type
-
-/* For networking code: an integral type the size of an IP port number
- (2 octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipport_type
-
-/* type of clock_t, from system header files */
-#undef pthread_clock_t
-
-/* Specially named so grep processing will find it and put it into the
- generated ac-types.h. */
-#undef pthread_have_va_list_h
-
-/* type of size_t, from system header files */
-#undef pthread_size_t
-
-/* type of ssize_t, from system header files */
-#undef pthread_ssize_t
-
-/* type of time_t, from system header files */
-#undef pthread_time_t
-
-/* type of fpos_t, from system header files */
-#undef pthread_fpos_t
-
-/* type of off_t, from system header files */
-#undef pthread_off_t
-
-/* type of va_list, from system header files */
-#undef pthread_va_list
-
-/* type of sigset_t, from system header files */
-#undef pthread_sigset_t
-
-/* I don't know why the native compiler definitions aren't sufficient
- for this. */
-#undef sunos4
-
-/* define if the linker hauls in certain static data from libc even when
- you don't want it to. yes, this description is bogus, but chris added
- the need for this, without describing the problem. */
-#undef LD_LINKS_STATIC_DATA
-
-/* define if the system reissues the SIGCHLD if the handler reinstalls
- * itself before calling wait()
- */
-#undef BROKEN_SIGNALS
-
-/* where are terminal devices to be found? */
-#undef _PATH_PTY
-
-/* what directory holds the time zone info on this system? */
-#undef _PATH_TZDIR
-
-/* what file indicates the local time zone? */
-#undef _PATH_TZFILE
-
-/* Paths for various networking support files. */
-#undef _PATH_RESCONF
-#undef _PATH_HOSTS
-#undef _PATH_NETWORKS
-#undef _PATH_PROTOCOLS
-#undef _PATH_SERVICES
-
-/* Path for Bourne shell. */
-#undef _PATH_BSHELL
diff --git a/mit-pthreads/config/aclocal.m4 b/mit-pthreads/config/aclocal.m4
deleted file mode 100755
index 2a5cd3e9cbf..00000000000
--- a/mit-pthreads/config/aclocal.m4
+++ /dev/null
@@ -1,94 +0,0 @@
-dnl Autoconf extensions for pthreads package.
-dnl
-ifelse(regexp(AC_DEFINE(xxxxx),.*@@@.*),-1,,[define(IS_AUTOHEADER)])])dnl
-dnl
-dnl Now, the real stuff needed by the pthreads package.
-dnl
-AC_DEFUN([PTHREADS_CHECK_ONE_SYSCALL],
-[AC_MSG_CHECKING(for syscall $1)
-AC_CACHE_VAL(pthreads_cv_syscall_$1,
-AC_TRY_LINK([
-/* FIXME: This list should be generated from info in configure.in. */
-#ifdef HAVE_SYSCALL_H
-#include <syscall.h>
-#else
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#else
-where is your syscall header file??
-#endif
-#endif
-],[
-int x;
-x = SYS_$1 ;
-],
-eval pthreads_cv_syscall_$1=yes,
-eval pthreads_cv_syscall_$1=no))
-if eval test \$pthreads_cv_syscall_$1 = yes ; then
- pthreads_syscall_present=yes
- available_syscalls="$available_syscalls $1"
-dnl Can't just do the obvious substitution here or autoheader gets
-dnl sorta confused. (Sigh.) Getting the requoting of the brackets right
-dnl would be a pain too.
- macroname=HAVE_SYSCALL_`echo $1 | tr '[[[a-z]]]' '[[[A-Z]]]'`
- AC_DEFINE_UNQUOTED($macroname)
-else
- pthreads_syscall_present=no
- missing_syscalls="$missing_syscalls $1"
-fi
-AC_MSG_RESULT($pthreads_syscall_present)
-])dnl
-dnl
-AC_DEFUN(PTHREADS_CHECK_SYSCALLS,dnl
-ifdef([IS_AUTOHEADER],[#
-dnl Need to fake out autoheader, since there's no way to add a new class
-dnl of features to generate config.h.in entries for.
-@@@syscalls="$1"@@@
-@@@funcs="$funcs syscall_`echo $syscalls | sed 's/ / syscall_/g'`"@@@
-],
-[pthreads_syscall_list="$1"
-for pthreads_syscallname in $pthreads_syscall_list ; do
- PTHREADS_CHECK_ONE_SYSCALL([$]pthreads_syscallname)
-done
-]))dnl
-dnl
-dnl Requote each argument.
-define([requote], [ifelse($#, 0, , $#, 1, "$1",
- "$1" [requote(builtin(shift,$@))])])dnl
-dnl
-dnl Determine proper typedef value for a typedef name, and define a
-dnl C macro to expand to that type. (A shell variable with that value
-dnl is also created.) If none of the specified types to try match, the
-dnl macro is left undefined, and the shell variable empty. If the
-dnl typedef name cannot be found in the specified header files, this
-dnl test errors out; perhaps it should be changed to simply leave the
-dnl macro undefined...
-dnl
-dnl PTHREADS_FIND_TYPE(typedefname,varname,includes,possible values...)
-dnl
-AC_DEFUN(PTHREADS_FIND_TYPE,
-ifdef([IS_AUTOHEADER],[#
-@@@syms="$syms $2"@@@
-],[dnl
-AC_MSG_CHECKING(type of $1)
-AC_CACHE_VAL(pthreads_cv_type_$1,
-[AC_TRY_COMPILE([$3],[ extern $1 foo; ],
-[ for try_type in [requote(builtin(shift,builtin(shift,builtin(shift,$@))))] ; do
- AC_TRY_COMPILE([$3],[ extern $1 foo; extern $try_type foo; ],
- [ pthreads_cv_type_$1="$try_type" ; break ])
- done],
- AC_MSG_ERROR(Can't find system typedef for $1.))])
-if test -n "$pthreads_cv_type_$1" ; then
- AC_DEFINE_UNQUOTED($2,$pthreads_cv_type_$1)
-fi
-$2=$pthreads_cv_type_$1
-AC_MSG_RESULT($pthreads_cv_type_$1)]))dnl
-dnl
-dnl
-dnl Like above, but the list of types to try is pre-specified.
-dnl
-AC_DEFUN(PTHREADS_FIND_INTEGRAL_TYPE,[
-PTHREADS_FIND_TYPE([$1], [$2], [$3],
- int, unsigned int, long, unsigned long,
- short, unsigned short, char, unsigned char,
- long long, unsigned long long)])dnl
diff --git a/mit-pthreads/config/config.flags.in b/mit-pthreads/config/config.flags.in
deleted file mode 100755
index 3d16423a045..00000000000
--- a/mit-pthreads/config/config.flags.in
+++ /dev/null
@@ -1,80 +0,0 @@
-# Since the real configure script runs from the config subdirectory,
-# compensate here...
-srctop= @srctop@
-srcfoo= $(srctop)
-
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-
-cpu = @target_cpu@
-os = @target_os@
-
-MISSING_SYSCALLS = @missing_syscalls@
-AVAILABLE_SYSCALLS = @available_syscalls@
-SYSCALL_EXCEPTIONS = @SYSCALL_EXCEPTIONS@
-HAVE_SYSCALL_TEMPLATE = @HAVE_SYSCALL_TEMPLATE@
-
-CC = @CC@
-CXX = @CXX@
-CPP = @CPP@
-SHELL = /bin/sh
-RANLIB = @RANLIB@
-# Should use autoconf to find these. Currently our makefiles are inconsistent.
-#AR = ar
-#AS = gas
-#LD = gld
-
-install-dirs:
- for d in $(INSTALL_PATH) $(BINDIR) $(LIBDIR) $(INCDIR) ; do \
- test -d $(DESTDIR)$$d || mkdir $(DESTDIR)$$d || exit 1 ; \
- done
-
-config.status: @srcdir@/configure
- cd ${.CURDIR} && $(SHELL) config.status --recheck
-config.flags: config.status @srcdir@/config.flags.in
- cd ${.CURDIR} && $(SHELL) config.status
-
-realclean: clean
- cd tests && $(MAKE) realclean && cd ..
- rm -f $(LINKS) config.status config.flags config.cache \
- Makefile GNUmakefile
-
-types=$(.CURDIR)/include/pthread/ac-types.h
-$(types) : config.h
- echo '#ifndef pthread_size_t' > $(types).new
- egrep '^#define pthread_' $(.CURDIR)/config.h >> $(types).new
- echo '#endif' >> $(types).new
- mv -f $(types).new $(types)
-
-config=$(.CURDIR)/include/pthread/config.h
-$(config) : config.h
- echo '#ifndef _SYS___CONFIG_H_' > $(config).new
- echo '#define _SYS___CONFIG_H_' >> $(config).new
- -egrep '^#define _OS_HAS' $(.CURDIR)/config.h >> $(config).new
- echo '#endif' >> $(config).new
- mv -f $(config).new $(config)
-
-paths=$(.CURDIR)/include/pthread/paths.h
-$(paths) : config.h
- echo '#ifndef _SYS___PATHS_H_' > $(paths).new
- echo '#define _SYS___PATHS_H_' >> $(paths).new
- egrep '^#define _PATH' $(.CURDIR)/config.h >> $(paths).new
- echo '#endif' >> $(paths).new
- mv -f $(paths).new $(paths)
-
-all-tests: all-lib
- cd ${.CURDIR}/tests && $(MAKE) all
-check: all-lib
- cd ${.CURDIR}/tests && $(MAKE) check
-all : all-lib all-bin
-
-install-bin: all-bin install-dirs
- for x in $(SCRIPTS) ; do \
- install $$x $(DESTDIR)$(BINDIR); \
- done
-
-install-include: install-dirs
- (cd ${srcdir}/include && tar chf - .)|(cd $(DESTDIR)$(INCDIR) && tar xf -)
- if [ -d config ]; then true; else \
- (cd ${.CURDIR}/include && tar chf - .)|(cd $(DESTDIR)$(INCDIR) && tar xf -); fi
- (cd $(DESTDIR)$(INCDIR) && find . \( -name CVS -o -name \*~ \) -print | xargs rm -rf)
diff --git a/mit-pthreads/config/config.guess b/mit-pthreads/config/config.guess
deleted file mode 100755
index 287ddc13c34..00000000000
--- a/mit-pthreads/config/config.guess
+++ /dev/null
@@ -1,505 +0,0 @@
-#!/bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
-#
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Written by Per Bothner <bothner@cygnus.com>.
-# The master version of this file is at the FSF in /home/gd/gnu/lib.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit system type (host/target name).
-#
-# Only a few systems have been added to this list; please add others
-# (but try to keep the structure clean).
-#
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 8/24/94.)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- alpha:OSF1:V*:*)
- # After 1.2, OSF1 uses "V1.3" for uname -r.
- echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'`
- exit 0 ;;
- alpha:OSF1:*:*)
- # 1.2 uses "1.2" for uname -r.
- echo alpha-dec-osf${UNAME_RELEASE}
- exit 0 ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
- Pyramid*:OSx*:*:*)
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit 0 ;;
- sun4*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:*:*)
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- mips:*:5*:RISCos)
- echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit 0 ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit 0 ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit 0 ;;
- AViiON:dgux:*:*)
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
- -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- exit 0 ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit 0 ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit 0 ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit 0 ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit 0 ;;
- *:IRIX:*:*)
- echo mips-sgi-irix${UNAME_RELEASE}
- exit 0 ;;
- i[34]86:AIX:*:*)
- echo i386-ibm-aix
- exit 0 ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- sed 's/^ //' << EOF >dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- echo rs6000-ibm-aix3.2.5
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit 0 ;;
- *:AIX:*:4)
- if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if grep bos410 /usr/include/stdio.h >/dev/null 2>&1; then
- IBM_REV=4.1
- elif grep bos411 /usr/include/stdio.h >/dev/null 2>&1; then
- IBM_REV=4.1.1
- else
- IBM_REV=4.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit 0 ;;
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit 0 ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit 0 ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit 0 ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit 0 ;;
- 9000/[3478]??:HP-UX:*:*)
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/7?? | 9000/8?7 ) HP_ARCH=hppa1.1 ;;
- 9000/8?? ) HP_ARCH=hppa1.0 ;;
- esac
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
- 3050*:HI-UX:*:*)
- sed 's/^ //' << EOF >dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- echo unknown-hitachi-hiuxwe2
- exit 0 ;;
- 9000/7??:4.3bsd:*:* | 9000/8?7:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit 0 ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit 0 ;;
- hp7??:OSF1:*:* | hp8?7:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit 0 ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit 0 ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit 0 ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit 0 ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit 0 ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit 0 ;;
- CRAY*X-MP:UNICOS:*:*)
- echo xmp-cray-unicos
- exit 0 ;;
- CRAY*Y-MP:UNICOS:*:*)
- echo ymp-cray-unicos
- exit 0 ;;
- CRAY-2:UNICOS:*:*)
- echo cray2-cray-unicos
- exit 0 ;;
- amiga:NetBSD:*:*)
- echo m68k-amiga-netbsd${UNAME_RELEASE}
- exit 0 ;;
- atari:NetBSD:*:*)
- echo m68k-atari-netbsd${UNAME_RELEASE}
- exit 0 ;;
- hp3[0-9][05]:NetBSD:*:*)
- echo m68k-hp-netbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:NetBSD:*:*)
- echo m68k-apple-netbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68:NetBSD:*:*)
- echo m68k-motorola-netbsd${UNAME_RELEASE}
- exit 0 ;;
- next68k:NetBSD:*:*)
- echo m68k-next-netbsd${UNAME_RELEASE}
- exit 0 ;;
- news68k:NetBSD:*:*)
- echo m68k-sony-netbsd${UNAME_RELEASE}
- exit 0 ;;
- sun3:NetBSD:*:*)
- echo m68k-sun-netbsd${UNAME_RELEASE}
- exit 0 ;;
- x68k:NetBSD:*:*)
- echo m68k-sharp-netbsd${UNAME_RELEASE}
- exit 0 ;;
- i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:NetBSD:*:*)
- UNAME_PROCESSOR=`uname -p 2>/dev/null` || UNAME_PROCESSOR=$UNAME_MACHINE
- echo ${UNAME_PROCESSOR}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:GNU:*:*)
- echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
- *:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux
- exit 0 ;;
-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
-# are messed up and put the nodename in both sysname and nodename.
- i[34]86:DYNIX/ptx:4*:*)
- echo i386-sequent-sysv4
- exit 0 ;;
- i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
- else
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- i[34]86:*:3.2:*)
- if /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
- elif test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
- else
- echo ${UNAME_MACHINE}-unknown-sysv32
- fi
- exit 0 ;;
- i?86:*:5:7)
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE}
- exit 0 ;;
- Intel:Mach:3*:*)
- echo i386-unknown-mach3
- exit 0 ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit 0 ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit 0 ;;
- M680[234]0:*:R3V[567]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
- uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3 && exit 0 ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
- m680[234]0:LynxOS:2.2*:*)
- echo m68k-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit 0 ;;
- i[34]86:LynxOS:2.2*:*)
- echo i386-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- TSUNAMI:LynxOS:2.2*:*)
- echo sparc-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- rs6000:LynxOS:2.2*:*)
- echo rs6000-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit 0 ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-cat >dummy.c <<EOF
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
- printf ("m68k-sony-newsos\n"); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-unknown-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- printf ("i386-sequent-ptx\n"); exit (0);
-#endif
-
-#if defined (vax)
-#if !defined (ultrix)
- printf ("vax-dec-bsd\n"); exit (0);
-#else
- printf ("vax-dec-ultrix\n"); exit (0);
-#endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
-rm -f dummy.c dummy
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit 0 ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- c34*)
- echo c34-convex-bsd
- exit 0 ;;
- c38*)
- echo c38-convex-bsd
- exit 0 ;;
- c4*)
- echo c4-convex-bsd
- exit 0 ;;
- esac
-fi
-
-#echo '(Unable to guess system type)' 1>&2
-
-exit 1
diff --git a/mit-pthreads/config/config.h.in b/mit-pthreads/config/config.h.in
deleted file mode 100755
index b5e25404a67..00000000000
--- a/mit-pthreads/config/config.h.in
+++ /dev/null
@@ -1,324 +0,0 @@
-/* config.h.in. Generated automatically from configure.in by autoheader. */
-
-/* Define to `long' if <sys/types.h> doesn't define. */
-#undef off_t
-
-/* Define as the return type of signal handlers (int or void). */
-#undef RETSIGTYPE
-
-/* Define to `unsigned' if <sys/types.h> doesn't define. */
-#undef size_t
-
-/* Define if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Does the OS already support struct timespec */
-#undef _OS_HAS_TIMESPEC
-
-/* Does the OS need socklen_t for the socket syscalls? */
-#undef _OS_HAS_SOCKLEN_T
-
-/* For networking code: an integral type the size of an IP address (4
- octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipaddr_type
-
-/* For networking code: an integral type the size of an IP port number
- (2 octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipport_type
-
-/* type of clock_t, from system header files */
-#undef pthread_clock_t
-
-/* Specially named so grep processing will find it and put it into the
- generated ac-types.h. */
-#undef pthread_have_va_list_h
-
-/* type of size_t, from system header files */
-#undef pthread_size_t
-
-/* type of ssize_t, from system header files */
-#undef pthread_ssize_t
-
-/* type of time_t, from system header files */
-#undef pthread_time_t
-
-/* type of fpos_t, from system header files */
-#undef pthread_fpos_t
-
-/* type of off_t, from system header files */
-#undef pthread_off_t
-
-/* type of va_list, from system header files */
-#undef pthread_va_list
-
-/* I don't know why the native compiler definitions aren't sufficient
- for this. */
-#undef sunos4
-
-/* define if the linker hauls in certain static data from libc even when
- you don't want it to. yes, this description is bogus, but chris added
- the need for this, without describing the problem. */
-#undef LD_LINKS_STATIC_DATA
-
-/* define if the system reissues the SIGCHLD if the handler reinstalls
- * itself before calling wait()
- */
-#undef BROKEN_SIGNALS
-
-/* where are terminal devices to be found? */
-#undef _PATH_PTY
-
-/* what directory holds the time zone info on this system? */
-#undef _PATH_TZDIR
-
-/* what file indicates the local time zone? */
-#undef _PATH_TZFILE
-
-/* Paths for various networking support files. */
-#undef _PATH_RESCONF
-#undef _PATH_HOSTS
-#undef _PATH_NETWORKS
-#undef _PATH_PROTOCOLS
-#undef _PATH_SERVICES
-
-/* Path for Bourne shell. */
-#undef _PATH_BSHELL
-
-/* Define if you have the syscall_accept function. */
-#undef HAVE_SYSCALL_ACCEPT
-
-/* Define if you have the syscall_bind function. */
-#undef HAVE_SYSCALL_BIND
-
-/* Define if you have the syscall_chdir function. */
-#undef HAVE_SYSCALL_CHDIR
-
-/* Define if you have the syscall_chmod function. */
-#undef HAVE_SYSCALL_CHMOD
-
-/* Define if you have the syscall_chown function. */
-#undef HAVE_SYSCALL_CHOWN
-
-/* Define if you have the syscall_chroot function. */
-#undef HAVE_SYSCALL_CHROOT
-
-/* Define if you have the syscall_close function. */
-#undef HAVE_SYSCALL_CLOSE
-
-/* Define if you have the syscall_connect function. */
-#undef HAVE_SYSCALL_CONNECT
-
-/* Define if you have the syscall_creat function. */
-#undef HAVE_SYSCALL_CREAT
-
-/* Define if you have the syscall_dup function. */
-#undef HAVE_SYSCALL_DUP
-
-/* Define if you have the syscall_dup2 function. */
-#undef HAVE_SYSCALL_DUP2
-
-/* Define if you have the syscall_execve function. */
-#undef HAVE_SYSCALL_EXECVE
-
-/* Define if you have the syscall_exit function. */
-#undef HAVE_SYSCALL_EXIT
-
-/* Define if you have the syscall_fchmod function. */
-#undef HAVE_SYSCALL_FCHMOD
-
-/* Define if you have the syscall_fchown function. */
-#undef HAVE_SYSCALL_FCHOWN
-
-/* Define if you have the syscall_fcntl function. */
-#undef HAVE_SYSCALL_FCNTL
-
-/* Define if you have the syscall_flock function. */
-#undef HAVE_SYSCALL_FLOCK
-
-/* Define if you have the syscall_fork function. */
-#undef HAVE_SYSCALL_FORK
-
-/* Define if you have the syscall_fstat function. */
-#undef HAVE_SYSCALL_FSTAT
-
-/* Define if you have the syscall_fstatfs function. */
-#undef HAVE_SYSCALL_FSTATFS
-
-/* Define if you have the syscall_ftruncate function. */
-#undef HAVE_SYSCALL_FTRUNCATE
-
-/* Define if you have the syscall_getdents function. */
-#undef HAVE_SYSCALL_GETDENTS
-
-/* Define if you have the syscall_getdirentries function. */
-#undef HAVE_SYSCALL_GETDIRENTRIES
-
-/* Define if you have the syscall_getdtablesize function. */
-#undef HAVE_SYSCALL_GETDTABLESIZE
-
-/* Define if you have the syscall_getmsg function. */
-#undef HAVE_SYSCALL_GETMSG
-
-/* Define if you have the syscall_getpeername function. */
-#undef HAVE_SYSCALL_GETPEERNAME
-
-/* Define if you have the syscall_getpgrp function. */
-#undef HAVE_SYSCALL_GETPGRP
-
-/* Define if you have the syscall_getsockname function. */
-#undef HAVE_SYSCALL_GETSOCKNAME
-
-/* Define if you have the syscall_getsockopt function. */
-#undef HAVE_SYSCALL_GETSOCKOPT
-
-/* Define if you have the syscall_ioctl function. */
-#undef HAVE_SYSCALL_IOCTL
-
-/* Define if you have the syscall_ksigaction function. */
-#undef HAVE_SYSCALL_KSIGACTION
-
-/* Define if you have the syscall_link function. */
-#undef HAVE_SYSCALL_LINK
-
-/* Define if you have the syscall_listen function. */
-#undef HAVE_SYSCALL_LISTEN
-
-/* Define if you have the syscall_lseek function. */
-#undef HAVE_SYSCALL_LSEEK
-
-/* Define if you have the syscall_lstat function. */
-#undef HAVE_SYSCALL_LSTAT
-
-/* Define if you have the syscall_open function. */
-#undef HAVE_SYSCALL_OPEN
-
-/* Define if you have the syscall_pgrpsys function. */
-#undef HAVE_SYSCALL_PGRPSYS
-
-/* Define if you have the syscall_pipe function. */
-#undef HAVE_SYSCALL_PIPE
-
-/* Define if you have the syscall_poll function. */
-#undef HAVE_SYSCALL_POLL
-
-/* Define if you have the syscall_putmsg function. */
-#undef HAVE_SYSCALL_PUTMSG
-
-/* Define if you have the syscall_read function. */
-#undef HAVE_SYSCALL_READ
-
-/* Define if you have the syscall_readdir function. */
-#undef HAVE_SYSCALL_READDIR
-
-/* Define if you have the syscall_readv function. */
-#undef HAVE_SYSCALL_READV
-
-/* Define if you have the syscall_recv function. */
-#undef HAVE_SYSCALL_RECV
-
-/* Define if you have the syscall_recvfrom function. */
-#undef HAVE_SYSCALL_RECVFROM
-
-/* Define if you have the syscall_recvmsg function. */
-#undef HAVE_SYSCALL_RECVMSG
-
-/* Define if you have the syscall_rename function. */
-#undef HAVE_SYSCALL_RENAME
-
-/* Define if you have the syscall_select function. */
-#undef HAVE_SYSCALL_SELECT
-
-/* Define if you have the syscall_send function. */
-#undef HAVE_SYSCALL_SEND
-
-/* Define if you have the syscall_sendmsg function. */
-#undef HAVE_SYSCALL_SENDMSG
-
-/* Define if you have the syscall_sendto function. */
-#undef HAVE_SYSCALL_SENDTO
-
-/* Define if you have the syscall_setsockopt function. */
-#undef HAVE_SYSCALL_SETSOCKOPT
-
-/* Define if you have the syscall_shutdown function. */
-#undef HAVE_SYSCALL_SHUTDOWN
-
-/* Define if you have the syscall_sigaction function. */
-#undef HAVE_SYSCALL_SIGACTION
-
-/* Define if you have the syscall_sigpause function. */
-#undef HAVE_SYSCALL_SIGPAUSE
-
-/* Define if you have the syscall_sigprocmask function. */
-#undef HAVE_SYSCALL_SIGPROCMASK
-
-/* Define if you have the syscall_sigsuspend function. */
-#undef HAVE_SYSCALL_SIGSUSPEND
-
-/* Define if you have the syscall_socket function. */
-#undef HAVE_SYSCALL_SOCKET
-
-/* Define if you have the syscall_socketcall function. */
-#undef HAVE_SYSCALL_SOCKETCALL
-
-/* Define if you have the syscall_socketpair function. */
-#undef HAVE_SYSCALL_SOCKETPAIR
-
-/* Define if you have the syscall_stat function. */
-#undef HAVE_SYSCALL_STAT
-
-/* Define if you have the syscall_uname function. */
-#undef HAVE_SYSCALL_UNAME
-
-/* Define if you have the syscall_unlink function. */
-#undef HAVE_SYSCALL_UNLINK
-
-/* Define if you have the syscall_wait3 function. */
-#undef HAVE_SYSCALL_WAIT3
-
-/* Define if you have the syscall_wait4 function. */
-#undef HAVE_SYSCALL_WAIT4
-
-/* Define if you have the syscall_waitpid function. */
-#undef HAVE_SYSCALL_WAITPID
-
-/* Define if you have the syscall_waitsys function. */
-#undef HAVE_SYSCALL_WAITSYS
-
-/* Define if you have the syscall_write function. */
-#undef HAVE_SYSCALL_WRITE
-
-/* Define if you have the syscall_writev function. */
-#undef HAVE_SYSCALL_WRITEV
-
-/* Define if you have the vfork function. */
-#undef HAVE_VFORK
-
-/* Define if you have the <alloc.h> header file. */
-#undef HAVE_ALLOC_H
-
-/* Define if you have the <sys/filio.h> header file. */
-#undef HAVE_SYS_FILIO_H
-
-/* Define if you have the <sys/syscall.h> header file. */
-#undef HAVE_SYS_SYSCALL_H
-
-/* Define if you have the <sys/termio.h> header file. */
-#undef HAVE_SYS_TERMIO_H
-
-/* Define if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define if you have the <syscall.h> header file. */
-#undef HAVE_SYSCALL_H
-
-/* Define if you have the <termio.h> header file. */
-#undef HAVE_TERMIO_H
-
-/* Define if you have the <termios.h> header file. */
-#undef HAVE_TERMIOS_H
diff --git a/mit-pthreads/config/config.sub b/mit-pthreads/config/config.sub
deleted file mode 100755
index 7a0c7855a2a..00000000000
--- a/mit-pthreads/config/config.sub
+++ /dev/null
@@ -1,794 +0,0 @@
-#!/bin/sh
-# Configuration validation subroutine script, version 1.1.
-# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-# First pass through any local machine types.
-case $1 in
- *local*)
- echo $1
- exit 0
- ;;
- *)
- ;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS (if any).
-basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-if [ $basic_machine != $1 ]
-then os=`echo $1 | sed 's/.*-/-/'`
-else os=; fi
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
- os=
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -lynx)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- tahoe | i[3456]86 | i860 | m68k | m68000 | m88k | ns32k | arm | arm32 | pyramid \
- | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
- | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
- | powerpc | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
- | pdp11 | mips64el | mips64orion | mips64orionel )
- basic_machine=$basic_machine-unknown
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
- | sparc-* | ns32k-* | fx80-* | arm-* | arm32-* | c[123]* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
- | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
- | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
- | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
- | pdp11-* | sh-* | powerpc-* | sparc64-* | mips64-* | mipsel-* \
- | mips64el-* | mips64orion-* | mips64orionel-* )
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-cbm
- ;;
- amigados)
- basic_machine=m68k-cbm
- os=-amigados
- ;;
- amigaunix | amix)
- basic_machine=m68k-cbm
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
- os=-unicos
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- os=-mvs
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i[3456]86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-sysv32
- ;;
- i[3456]86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-sysv4
- ;;
- i[3456]86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-sysv
- ;;
- i[3456]86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-solaris2
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pentium-*)
- # We will change tis to say i586 once there has been
- # time for various packages to start to recognize that.
- basic_machine=i486-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- xmp)
- basic_machine=xmp-cray
- os=-unicos
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- mips)
- basic_machine=mips-mips
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sparc)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative must end in a *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \
- | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
- | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -freebsd* | -openbsd* \
- |-riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
- | -ptx* | -coff* | -winnt*)
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -xenix)
- os=-xenix
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-ibm)
- os=-aix
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigados
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-masscomp)
- os=-rtu
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -lynxos*)
- vendor=lynx
- ;;
- -aix*)
- vendor=ibm
- ;;
- -hpux*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
diff --git a/mit-pthreads/config/configure b/mit-pthreads/config/configure
deleted file mode 100755
index 4d99ac5c07e..00000000000
--- a/mit-pthreads/config/configure
+++ /dev/null
@@ -1,3336 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
---enable-dce-compat DCE compatibility"
-ac_default_prefix=/usr/local/pthreads
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
-ac_prev=
-for ac_option
-do
-
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case "$ac_option" in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
-
- -disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.13"
- exit 0 ;;
-
- -with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
-
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
- ;;
-
- *)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
-
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=config.flags.in
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
-else
- echo "creating cache $cache_file"
- > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
- fi
-else
- ac_n= ac_c='\c' ac_t=
-fi
-
-
-# Check whether --enable-dce-compat or --disable-dce-compat was given.
-if test "${enable_dce_compat+set}" = set; then
- enableval="$enable_dce_compat"
- { echo "configure: error: Actually, DCE compatibility doesn't work yet..." 1>&2; exit 1; }
-
-else
- true
-
-fi
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:542: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:572: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_prog_rejected=no
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# -gt 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
- fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- if test -z "$CC"; then
- case "`uname -s`" in
- *win32* | *WIN32*)
- # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:623: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="cl"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
- ;;
- esac
- fi
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:655: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 666 "configure"
-#include "confdefs.h"
-
-main(){return(0);}
-EOF
-if { (eval echo configure:671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cc_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cc_cross=no
- else
- ac_cv_prog_cc_cross=yes
- fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:697: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:702: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:711: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
-else
- GCC=
-fi
-
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:730: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_cc_g=yes
-else
- ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-
-for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:766: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CXX="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CXX="$ac_cv_prog_CXX"
-if test -n "$CXX"; then
- echo "$ac_t""$CXX" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$CXX" && break
-done
-test -n "$CXX" || CXX="gcc"
-
-
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:798: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
-
-ac_ext=C
-# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cxx_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 809 "configure"
-#include "confdefs.h"
-
-int main(){return(0);}
-EOF
-if { (eval echo configure:814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cxx_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cxx_cross=no
- else
- ac_cv_prog_cxx_cross=yes
- fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cxx_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
-if test $ac_cv_prog_cxx_works = no; then
- { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:840: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
-cross_compiling=$ac_cv_prog_cxx_cross
-
-echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:845: checking whether we are using GNU C++" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.C <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:854: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gxx=yes
-else
- ac_cv_prog_gxx=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx" 1>&6
-
-if test $ac_cv_prog_gxx = yes; then
- GXX=yes
-else
- GXX=
-fi
-
-ac_test_CXXFLAGS="${CXXFLAGS+set}"
-ac_save_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS=
-echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:873: checking whether ${CXX-g++} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.cc
-if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
- ac_cv_prog_cxx_g=yes
-else
- ac_cv_prog_cxx_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS="$ac_save_CXXFLAGS"
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-
-echo $ac_n "checking compiler availability and simple error detection""... $ac_c" 1>&6
-echo "configure:905: checking compiler availability and simple error detection" >&5
-cat > conftest.$ac_ext <<EOF
-#line 907 "configure"
-#include "confdefs.h"
-
-int main() {
- exit(0);
-; return 0; }
-EOF
-if { (eval echo configure:914: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- cat > conftest.$ac_ext <<EOF
-#line 918 "configure"
-#include "confdefs.h"
-
-int main() {
- syntax errors galore!
-; return 0; }
-EOF
-if { (eval echo configure:925: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Can't detect syntax errors! Is CC set right?" 1>&2; exit 1; }
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- true
-fi
-rm -f conftest*
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't compile test program! Is CC set right?" 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-cat > conftest.$ac_ext <<EOF
-#line 944 "configure"
-#include "confdefs.h"
-
-int main() {
-
- typedef int Integer;
- extern int i;
- extern Integer i;
-
-; return 0; }
-EOF
-if { (eval echo configure:955: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- :
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't redeclare variables with this compiler??" 1>&2; exit 1; }
-fi
-rm -f conftest*
-cat > conftest.$ac_ext <<EOF
-#line 965 "configure"
-#include "confdefs.h"
-
-int main() {
-
- typedef long Long;
- extern int i;
- extern Long i;
-
-; return 0; }
-EOF
-if { (eval echo configure:976: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Compiler doesn't detect conflicting declarations." 1>&2; exit 1; }
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-echo "$ac_t""ok" 1>&6
-
-if test $ac_cv_prog_gcc = yes ; then
- CFLAGS="$CFLAGS -Werror"
-fi
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:991: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 1006 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1012: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 1023 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1029: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -nologo -E"
- cat > conftest.$ac_ext <<EOF
-#line 1040 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1046: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1074: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Do some error checking and defaulting for the host and target type.
-# The inputs are:
-# configure --host=HOST --target=TARGET --build=BUILD NONOPT
-#
-# The rules are:
-# 1. You are not allowed to specify --host, --target, and nonopt at the
-# same time.
-# 2. Host defaults to nonopt.
-# 3. If nonopt is not specified, then host defaults to the current host,
-# as determined by config.guess.
-# 4. Target and build default to nonopt.
-# 5. If nonopt is not specified, then target and build default to host.
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-case $host---$target---$nonopt in
-NONE---*---* | *---NONE---* | *---*---NONE) ;;
-*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
-esac
-
-
-# Make sure we can run config.sub.
-if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:1151: checking host system type" >&5
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:1172: checking target system type" >&5
-
-target_alias=$target
-case "$target_alias" in
-NONE)
- case $nonopt in
- NONE) target_alias=$host_alias ;;
- *) target_alias=$nonopt ;;
- esac ;;
-esac
-
-target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
-target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$target" 1>&6
-
-echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1190: checking build system type" >&5
-
-build_alias=$build
-case "$build_alias" in
-NONE)
- case $nonopt in
- NONE) build_alias=$host_alias ;;
- *) build_alias=$nonopt ;;
- esac ;;
-esac
-
-build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
-
-test "$host_alias" != "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
-
-
-syscall=NONE
-sysincludes=NONE
-extraincludes=NONE
-
-# Treat all x86 machines the same.
-# (Yet below, we pretend we can distinguish between the MIPS r2000 and r4000?)
-# (What about 680x0 machines?)
-case $host in
- i[456]86-*)
- host=`echo $host | sed 's/^i[456]86/i386/'`
- host_cpu=i386
- ;;
-esac
-
-# Here, you should set the following variables:
-# name
-# The "name" of this configuration. Used for "engine-*.c" file name,
-# default for syscall file names. Chris seems to have a thing for
-# putting "-" between OS and version number, but the configure script
-# will already have $host_cpu and $host_os available for you to use
-# in constructing a name.
-# sysincludes
-# Name of machdep directory with "sys" include file
-# replacements, if any. This directory is optional;
-# if you don't provide it, don't set this variable.
-# except
-# Names of any syscalls that shouldn't be generated
-# from the template, if any.
-# syscall
-# Base name of the syscall template files, if not the
-# same as <name>. If they're the same, omit this.
-#
-# Also, you may define random symbols and update CFLAGS if
-# necessary. However, for ease of porting to new machines,
-# it's best if you can create portable autoconf tests for
-# whatever you're trying to do, rather than hard-coding it
-# here based on the OS name. So please, try to keep this
-# section as minimal as possible.
-
-except=""
-name=$host_cpu-$host_os
-
-case $host in
- alpha-*-netbsd1.3[H-Z]|alpha-*-netbsd1.[45]*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- alpha-*-netbsd1.3*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask fstat"
- ;;
- alpha-*-netbsd1.1* | alpha-*-netbsd1.2*)
- name=alpha-netbsd-1.1
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- alpha-*-osf*)
- name=alpha-osf1
- sysincludes=alpha-osf1
- except="fork sigsuspend"
- if test $ac_cv_prog_gcc = no ; then
- CFLAGS="$CFLAGS -std"
- fi
- ;;
- arm32-*-netbsd1.3[H-Z]|arm32-*-netbsd1.[45]*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- arm32-*-netbsd1.3*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate sigsuspend sigprocmask fstat"
- ;;
- hppa1.0-*-hpux10.20 | hppa1.1-*-hpux10.20)
- name=hppa-hpux-10.20
- sysincludes=hpux-10.20
- except="fork"
- ;;
- hppa1.1-*-hpux*9.*)
- name=hppa-hpux-9.03
- sysincludes=hpux-9.03
- # hpux-9.03.mk seems to be missing; what should this be?
- except="fork"
- ;;
- powerpc-*-netbsd1.*)
- name=powerpc-netbsd
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigprocmask sigaction sigsuspend"
- ;;
- sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
- name=sparc-sunos-4.1.3
- sysincludes=sunos-4.1.3
- syscall=sparc-sunos4
- except="fork pipe getpgrp getdirentries"
- cat >> confdefs.h <<\EOF
-#define sunos4 1
-EOF
- # is this really needed??
- ;;
- sparc-*-solaris2.3* | sparc-*-solaris2.4*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.3
- except="fork sigaction"
- # Should really come up with a test for this...
- cat >> confdefs.h <<\EOF
-#define LD_LINKS_STATIC_DATA 1
-EOF
-
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- sparc-*-solaris2*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.5
- except="fork sigaction"
- # Should really come up with a test for this...
- cat >> confdefs.h <<\EOF
-#define LD_LINKS_STATIC_DATA 1
-EOF
-
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- sparc-*-netbsd1.3[H-Z]|sparc-*-netbsd1.[45]*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate fstat"
- available_syscalls="sigprocmask sigsuspend"
- ;;
- sparc-*-netbsd1.3*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate sigprocmask sigsuspend fstat"
- ;;
- sparc-*-netbsd1.0A | sparc-*-netbsd1.1* | sparc-*-netbsd1.2*)
- name=sparc-sunos-4.1.3
- sysincludes=netbsd-1.0
- syscall=sparc-netbsd-1.1
- except="pipe fork sigprocmask sigsuspend"
- ;;
- i386-*-openbsd2.*)
- name=i386-openbsd-2.0
- sysincludes=openbsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- i386-*-linux*)
- #name=i386-linux-1.0
- #sysincludes=linux-1.0
- name=i386-linux-2.0
- sysincludes=linux-2.0
- extraincludes="bits"
- ;;
- i386-*-bsdi1.1)
- name=i386-bsdi-1.1
- sysincludes=bsdi-1.1
- ;;
- i386-*-bsdi2.0* | i386-*-bsdi2.1*)
- name=i386-bsdi-2.0
- sysincludes=bsdi-2.0
- syscall=i386-bsdi-2.0
- except="fork lseek ftruncate sigsuspend"
- ;;
- i386-*-netbsd1.3[H-Z]|i386-*-netbsd1.[45]*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.3*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask fstat"
- ;;
- i386-*-netbsd1.1* | i386-*-netbsd1.2*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.1
- syscall=i386-netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.0*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.0
- except="fork lseek ftruncate sigsuspend"
- ;;
- i386-*-netbsd0.9*)
- name=i386-netbsd-0.9
- sysincludes=netbsd-0.9
- ;;
- m68*-*-netbsd*)
- name=m68000-netbsd
- sysincludes=netbsd-1.1
- except="lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- i386-*-freebsd*)
- name=i386-freebsd-2.0
- sysincludes=freebsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- romp-*-bsd*)
- name=romp-bsd
- ;;
- mips-dec-ultrix*)
- name=r2000-ultrix-4.2
- sysincludes=ultrix-4.2
- except="fork pipe"
- ;;
- mips-sgi-irix*)
- name=ip22-irix-5.2
- sysincludes=irix-5.2
- except="fstat stat"
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- i386-*-sco3.2v5*)
- name=i386-sco3.2.5
- sysincludes=i386-sco3.2.5
- syscall=i386-sco3.2.5
- except="select socketcall accept bind connect getpeername getsockname getsockopt setsockopt listen recv recvfrom recvmsg send sendmsg sendto shutdown socket socketpair fork fcntl dup2 fstat fchmod fchown ftruncate pipe getdirentries sigaction sigpause wait3 waitpid getdtablesize"
- ;;
- *)
- { echo "configure: error: System type $host not recognized or not supported.
-See $srcdir/configure.in for supported systems." 1>&2; exit 1; }
- exit 1
- ;;
-esac
-
-SYSCALL_EXCEPTIONS=$except
-
-
-for ac_hdr in sys/termio.h termios.h termio.h alloc.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1453: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1458 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-ac_safe=`echo "va_list.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for va_list.h""... $ac_c" 1>&6
-echo "configure:1492: checking for va_list.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1497 "configure"
-#include "confdefs.h"
-#include <va_list.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1502: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define pthread_have_va_list_h 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-for ac_hdr in syscall.h sys/syscall.h sys/filio.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1531: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1536 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1541: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-pthreads_syscall_list="open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- rename select getdtablesize ioctl ftruncate flock fstatfs chroot uname
- sigsuspend sigaction sigpause sigprocmask ksigaction
- getdents readdir getdirentries
- wait4 wait3 waitpid waitsys
- socket bind connect accept listen getsockopt setsockopt socketpair
- poll putmsg getmsg
- socketcall
-
- pgrpsys
-
- exit
- readv writev send sendto sendmsg recv recvfrom recvmsg
- getpeername getsockname
- shutdown
- getpgrp fork"
-for pthreads_syscallname in $pthreads_syscall_list ; do
- echo $ac_n "checking for syscall $pthreads_syscallname""... $ac_c" 1>&6
-echo "configure:1587: checking for syscall $pthreads_syscallname" >&5
-if eval "test \"`echo '$''{'pthreads_cv_syscall_$pthreads_syscallname'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1592 "configure"
-#include "confdefs.h"
-
-/* FIXME: This list should be generated from info in configure.in. */
-#ifdef HAVE_SYSCALL_H
-#include <syscall.h>
-#else
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#else
-where is your syscall header file??
-#endif
-#endif
-
-int main() {
-
-int x;
-x = SYS_$pthreads_syscallname ;
-
-; return 0; }
-EOF
-if { (eval echo configure:1613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=no
-fi
-rm -f conftest*
-fi
-
-if eval test \$pthreads_cv_syscall_$pthreads_syscallname = yes ; then
- pthreads_syscall_present=yes
- available_syscalls="$available_syscalls $pthreads_syscallname"
- macroname=HAVE_SYSCALL_`echo $pthreads_syscallname | tr '[a-z]' '[A-Z]'`
- cat >> confdefs.h <<EOF
-#define $macroname 1
-EOF
-
-else
- pthreads_syscall_present=no
- missing_syscalls="$missing_syscalls $pthreads_syscallname"
-fi
-echo "$ac_t""$pthreads_syscall_present" 1>&6
-
-done
-
-
-
-
-
-
-## Determine some typedef values from the system header files.
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1648: checking for ANSI C header files" >&5
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1653 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1661: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- ac_cv_header_stdc=yes
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1678 "configure"
-#include "confdefs.h"
-#include <string.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1696 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
- :
-else
- cat > conftest.$ac_ext <<EOF
-#line 1717 "configure"
-#include "confdefs.h"
-#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
-
-EOF
-if { (eval echo configure:1728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
- :
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_header_stdc=no
-fi
-rm -fr conftest*
-fi
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
-if test $ac_cv_header_stdc = yes; then
- cat >> confdefs.h <<\EOF
-#define STDC_HEADERS 1
-EOF
-
-fi
-
-echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:1752: checking for off_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1757 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_off_t=yes
-else
- rm -rf conftest*
- ac_cv_type_off_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_off_t" 1>&6
-if test $ac_cv_type_off_t = no; then
- cat >> confdefs.h <<\EOF
-#define off_t long
-EOF
-
-fi
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1785: checking for size_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1790 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_size_t=yes
-else
- rm -rf conftest*
- ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
- cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1818: checking return type of signal handlers" >&5
-if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1823 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <signal.h>
-#ifdef signal
-#undef signal
-#endif
-#ifdef __cplusplus
-extern "C" void (*signal (int, void (*)(int)))(int);
-#else
-void (*signal ()) ();
-#endif
-
-int main() {
-int i;
-; return 0; }
-EOF
-if { (eval echo configure:1840: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_type_signal=void
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_type_signal=int
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_type_signal" 1>&6
-cat >> confdefs.h <<EOF
-#define RETSIGTYPE $ac_cv_type_signal
-EOF
-
-
-echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:1859: checking for ssize_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1864 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_ssize_t=yes
-else
- rm -rf conftest*
- ac_cv_type_ssize_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
-if test $ac_cv_type_ssize_t = no; then
- cat >> confdefs.h <<\EOF
-#define ssize_t int
-EOF
-
-fi
-
-echo $ac_n "checking for time_t""... $ac_c" 1>&6
-echo "configure:1892: checking for time_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1897 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])time_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_time_t=yes
-else
- rm -rf conftest*
- ac_cv_type_time_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_time_t" 1>&6
-if test $ac_cv_type_time_t = no; then
- cat >> confdefs.h <<\EOF
-#define time_t long
-EOF
-
-fi
-
-for ac_hdr in sys/time.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1928: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1933 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1965: checking whether time.h and sys/time.h may both be included" >&5
-if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1970 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-int main() {
-struct tm *tp;
-; return 0; }
-EOF
-if { (eval echo configure:1979: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_header_time=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_time=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_header_time" 1>&6
-if test $ac_cv_header_time = yes; then
- cat >> confdefs.h <<\EOF
-#define TIME_WITH_SYS_TIME 1
-EOF
-
-fi
-
-
-echo $ac_n "checking for struct timespec in sys/time.h""... $ac_c" 1>&6
-echo "configure:2001: checking for struct timespec in sys/time.h" >&5
-if eval "test \"`echo '$''{'pthreads_cv_timespec_in_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2006 "configure"
-#include "confdefs.h"
-#include <sys/time.h>
-int main() {
-struct timespec foo;
-; return 0; }
-EOF
-if { (eval echo configure:2013: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_timespec_in_time=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- pthreads_cv_timespec_in_time=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$pthreads_cv_timespec_in_time" 1>&6
-if test $pthreads_cv_timespec_in_time = yes ; then
- cat >> confdefs.h <<\EOF
-#define _OS_HAS_TIMESPEC 1
-EOF
-
-fi
-
-if eval "test \"`echo '$''{'pthreads_cv_socklen_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2037 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-int main() {
-socklen_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2045: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_socklen_t=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- pthreads_cv_socklen_t=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$pthreads_cv_socklen_t" 1>&6
-if test $pthreads_cv_socklen_t = yes ; then
- cat >> confdefs.h <<\EOF
-#define _OS_HAS_SOCKLEN_T 1
-EOF
-
-fi
-
-
-
-echo $ac_n "checking type of size_t""... $ac_c" 1>&6
-echo "configure:2068: checking type of size_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2073 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern size_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2086: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2090 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern size_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_size_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for size_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_size_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_size_t $pthreads_cv_type_size_t
-EOF
-
-fi
-pthread_size_t=$pthreads_cv_type_size_t
-echo "$ac_t""$pthreads_cv_type_size_t" 1>&6
-
-echo $ac_n "checking type of ssize_t""... $ac_c" 1>&6
-echo "configure:2131: checking type of ssize_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2136 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() {
- extern ssize_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2147: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2151 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() {
- extern ssize_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_ssize_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for ssize_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_ssize_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_ssize_t $pthreads_cv_type_ssize_t
-EOF
-
-fi
-pthread_ssize_t=$pthreads_cv_type_ssize_t
-echo "$ac_t""$pthreads_cv_type_ssize_t" 1>&6
-
-echo $ac_n "checking type of clock_t""... $ac_c" 1>&6
-echo "configure:2190: checking type of clock_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_clock_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2195 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern clock_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2214: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2218 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern clock_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2237: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_clock_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for clock_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_clock_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_clock_t $pthreads_cv_type_clock_t
-EOF
-
-fi
-pthread_clock_t=$pthreads_cv_type_clock_t
-echo "$ac_t""$pthreads_cv_type_clock_t" 1>&6
-
-echo $ac_n "checking type of time_t""... $ac_c" 1>&6
-echo "configure:2265: checking type of time_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2270 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern time_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2289: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2293 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern time_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2312: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_time_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for time_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_time_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_time_t $pthreads_cv_type_time_t
-EOF
-
-fi
-pthread_time_t=$pthreads_cv_type_time_t
-echo "$ac_t""$pthreads_cv_type_time_t" 1>&6
-echo $ac_n "checking for fpos_t in stdio.h""... $ac_c" 1>&6
-echo "configure:2339: checking for fpos_t in stdio.h" >&5
-if eval "test \"`echo '$''{'pthreads_cv_fpos_t_in_stdio'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2344 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() {
-fpos_t position;
-; return 0; }
-EOF
-if { (eval echo configure:2351: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$pthreads_cv_fpos_t_in_stdio" 1>&6
-if test $pthreads_cv_fpos_t_in_stdio = yes ; then
-
-echo $ac_n "checking type of fpos_t""... $ac_c" 1>&6
-echo "configure:2367: checking type of fpos_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_fpos_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2372 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern fpos_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2385: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2389 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern fpos_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2402: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_fpos_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for fpos_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_fpos_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_fpos_t $pthreads_cv_type_fpos_t
-EOF
-
-fi
-pthread_fpos_t=$pthreads_cv_type_fpos_t
-echo "$ac_t""$pthreads_cv_type_fpos_t" 1>&6
-else
- cat >> confdefs.h <<\EOF
-#define fpos_t off_t
-EOF
-
- cat >> confdefs.h <<\EOF
-#define pthread_fpos_t pthread_off_t
-EOF
-
-fi
-
-echo $ac_n "checking type of off_t""... $ac_c" 1>&6
-echo "configure:2440: checking type of off_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2445 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern off_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2458: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2462 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern off_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2475: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_off_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for off_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_off_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_off_t $pthreads_cv_type_off_t
-EOF
-
-fi
-pthread_off_t=$pthreads_cv_type_off_t
-echo "$ac_t""$pthreads_cv_type_off_t" 1>&6
-echo $ac_n "checking type of va_list""... $ac_c" 1>&6
-echo "configure:2502: checking type of va_list" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_va_list'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2507 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() {
- extern va_list foo;
-; return 0; }
-EOF
-if { (eval echo configure:2514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "char *" "char **" "void *" "void **" "int *" "long *" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2518 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() {
- extern va_list foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2525: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_va_list="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for va_list." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_va_list" ; then
- cat >> confdefs.h <<EOF
-#define pthread_va_list $pthreads_cv_type_va_list
-EOF
-
-fi
-pthread_va_list=$pthreads_cv_type_va_list
-echo "$ac_t""$pthreads_cv_type_va_list" 1>&6
-
-arpa_headers="#include <sys/types.h>
-#include <arpa/nameser.h>"
-
-echo $ac_n "checking IP address type""... $ac_c" 1>&6
-echo "configure:2556: checking IP address type" >&5
-if eval "test \"`echo '$''{'pthread_cv_type_ipaddr'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2561 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
- &_getlong;
-; return 0; }
-EOF
-if { (eval echo configure:2568: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned long" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2573 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
-extern $type _getlong ();
-; return 0; }
-EOF
-if { (eval echo configure:2580: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipaddr="$type"
- break
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- echo "configure: warning: Can't compile _getlong reference." 1>&2
-fi
-rm -f conftest*
- if test "$pthread_cv_type_ipaddr" = "" ; then
- echo "configure: warning: Can't determine _getlong return type." 1>&2
- echo "configure: warning: Defaulting to unsigned long." 1>&2
- pthread_cv_type_ipaddr="unsigned long"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipaddr" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipaddr_type $pthread_cv_type_ipaddr
-EOF
-
-
-echo $ac_n "checking IP port type""... $ac_c" 1>&6
-echo "configure:2615: checking IP port type" >&5
-if eval "test \"`echo '$''{'pthread_cv_type_ipport'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2620 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
- &_getshort;
-; return 0; }
-EOF
-if { (eval echo configure:2627: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned short" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2632 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
-extern $type _getshort ();
-; return 0; }
-EOF
-if { (eval echo configure:2639: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipport="$type"
- break
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- echo "configure: warning: Can't compile _getshort reference." 1>&2
-fi
-rm -f conftest*
- if test "$pthread_cv_type_ipport" = "" ; then
- echo "configure: warning: Can't determine _getshort return type." 1>&2
- echo "configure: warning: Defaulting to unsigned short." 1>&2
- pthread_cv_type_ipport="unsigned short"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipport" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipport_type $pthread_cv_type_ipport
-EOF
-
-
-echo $ac_n "checking pathname for terminal devices directory""... $ac_c" 1>&6
-echo "configure:2674: checking pathname for terminal devices directory" >&5
-if eval "test \"`echo '$''{'pthread_cv_pty_path'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -d /devices/pseudo ; then
- pty_path=/devices/pseudo/
- else
- pty_path=/dev/
- fi
- pthread_cv_pty_path=$pty_path
-
-fi
-
-cat >> confdefs.h <<EOF
-#define _PATH_PTY "$pthread_cv_pty_path"
-EOF
-
-echo "$ac_t""$pthread_cv_pty_path" 1>&6
-
-echo $ac_n "checking directory name for time zone info""... $ac_c" 1>&6
-echo "configure:2694: checking directory name for time zone info" >&5
-tzdir=NONE
-for f in /usr/lib/zoneinfo /usr/share/zoneinfo /usr/share/lib/zoneinfo /etc/zoneinfo /usr/local/lib/zoneinfo
-do
- if test -d $f ; then
- tzdir=$f
- break
- fi
-done
-case $tzdir in
-NONE)
- echo "configure: warning: Can't find zoneinfo directory." 1>&2
- echo "configure: warning: Defaulting zoneinfo directory to NULL." 1>&2
- tzdir=NULL
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZDIR "$tzdir"
-EOF
-
-echo "$ac_t""$tzdir" 1>&6
-
-echo $ac_n "checking filename for local time zone""... $ac_c" 1>&6
-echo "configure:2717: checking filename for local time zone" >&5
-tzfile=NONE
-for f in $tzdir/localtime /etc/localtime
-do
- if test -f $f ; then
- tzfile=$f
- break
- fi
-done
-case $tzfile in
-NONE) # Should this default to tzdir/localtime?
- echo "configure: warning: Can't find local time zone file." 1>&2
- if test tzdir = NULL ; then
- echo "configure: warning: Defaulting local time zone file to NULL" 1>&2
- tzfile=NULL
- else
- echo "configure: warning: Defaulting local time zone file to $tzdir/localtime." 1>&2
- tzfile=$tzdir/localtime
- fi
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZFILE "$tzfile"
-EOF
-
-echo "$ac_t""$tzfile" 1>&6
-
-cat >> confdefs.h <<\EOF
-#define _PATH_RESCONF "/etc/resolv.conf"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_HOSTS "/etc/hosts"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_NETWORKS "/etc/networks"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_PROTOCOLS "/etc/protocols"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_SERVICES "/etc/services"
-EOF
-
-
-cat >> confdefs.h <<\EOF
-#define _PATH_BSHELL "/bin/sh"
-EOF
-
-
-for ac_func in vfork
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2773: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2778 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-srctop=`cd ${srcdir}/..;pwd`
-
-
-# Now we deal with symlinks &c.
-
-test -d include || mkdir include || \
- { echo "configure: error: Can't create include directory." 1>&2; exit 1; }
-
-test -d include/pthread || mkdir include/pthread || \
- { echo "configure: error: Can't create include/pthread directory." 1>&2; exit 1; }
-
-test -d lib || mkdir lib || \
- { echo "configure: error: Can't create lib directory." 1>&2; exit 1; }
-
-test -d lib/libpthreadutil || mkdir lib/libpthreadutil || \
- { echo "configure: error: Can't create lib/libpthreadutil directory." 1>&2; exit 1; }
-
-test -d bin || mkdir bin || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d bin/finger || mkdir bin/finger || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d tests || mkdir tests || \
- { echo "configure: error: Can't create tests directory." 1>&2; exit 1; }
-
-if test x$syscall = xNONE ; then
- syscall=$name
-fi
-
-links="include/pthread/machdep.h include/pthread/posix.h \
- machdep.c syscall.S"
-targets="../machdep/engine-$name.h ../machdep/posix-$sysincludes.h \
- ../machdep/engine-$name.c ../machdep/syscall-$syscall.S"
-
-# Both these targets are optional. (Autoconf-generated configure scripts
-# will require the existence of link targets, so check before adding them
-# to the list.)
-if test x$sysincludes != xNONE ; then
- links="$links include/sys"
- targets="$targets ../machdep/$sysincludes"
-fi
-
-if test x$extraincludes != xNONE ; then
- for tmp in $extraincludes
- do
- links="$links include/$tmp"
- targets="$targets ../machdep/$sysincludes/extra/$tmp"
- done
-fi
-
-syscall_file=../machdep/syscall-template-$syscall.S
-if test -r $srcdir/$syscall_file ; then
- links="$links syscall-template.S"
- targets="$targets $syscall_file"
- HAVE_SYSCALL_TEMPLATE=yes
-else
- # This really isn't a fatal problem. In fact, it's expected, initially,
- # for some targets. This is just to persuade people to fix the targets
- # they deal with to provide some sort of template.
- #
- # Eventually this file probably will be required...
- echo "configure: warning: No syscall template file syscall-template-$syscall.S found." 1>&2
- HAVE_SYSCALL_TEMPLATE=no
-fi
-
-
-
-
-if test x$makefile_frag != x ; then
- makefile_frag=${srcdir}/$makefile_frag
-else
- makefile_frag=/dev/null
-fi
-
-
-
-
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote substitution
- # turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-DEFS=-DHAVE_CONFIG_H
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.13"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
-
-ac_given_srcdir=$srcdir
-
-trap 'rm -fr `echo "config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@CXX@%$CXX%g
-s%@CPP@%$CPP%g
-s%@RANLIB@%$RANLIB%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
-s%@target@%$target%g
-s%@target_alias@%$target_alias%g
-s%@target_cpu@%$target_cpu%g
-s%@target_vendor@%$target_vendor%g
-s%@target_os@%$target_os%g
-s%@build@%$build%g
-s%@build_alias@%$build_alias%g
-s%@build_cpu@%$build_cpu%g
-s%@build_vendor@%$build_vendor%g
-s%@build_os@%$build_os%g
-s%@SYSCALL_EXCEPTIONS@%$SYSCALL_EXCEPTIONS%g
-s%@available_syscalls@%$available_syscalls%g
-s%@missing_syscalls@%$missing_syscalls%g
-s%@srctop@%$srctop%g
-s%@HAVE_SYSCALL_TEMPLATE@%$HAVE_SYSCALL_TEMPLATE%g
-/@makefile_frag@/r $makefile_frag
-s%@makefile_frag@%%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
- else
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
- fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
- else
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
- fi
-done
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
- fi
-
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
-
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
-
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-if test "${CONFIG_HEADERS+set}" != set; then
-EOF
-cat >> $CONFIG_STATUS <<EOF
- CONFIG_HEADERS="config.h"
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-fi
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- cat $ac_file_inputs > conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
-
-rm -f conftest.tail
-while :
-do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
- echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
-done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
- else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- fi
- rm -f $ac_file
- mv conftest.h $ac_file
- fi
-fi; done
-
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-ac_sources="$targets"
-ac_dests="$links"
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-srcdir=$ac_given_srcdir
-while test -n "$ac_sources"; do
- set $ac_dests; ac_dest=$1; shift; ac_dests=$*
- set $ac_sources; ac_source=$1; shift; ac_sources=$*
-
- echo "linking $srcdir/$ac_source to $ac_dest"
-
- if test ! -r $srcdir/$ac_source; then
- { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
- fi
- rm -f $ac_dest
-
- # Make relative symlinks.
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
- # The dest file is in a subdirectory.
- test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
- ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dest_dir_suffix.
- ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dest_dir_suffix= ac_dots=
- fi
-
- case "$srcdir" in
- [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
- *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
- esac
-
- # Make a symlink if possible; otherwise try a hard link.
- if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
- ln $srcdir/$ac_source $ac_dest; then :
- else
- { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
- fi
-done
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/mit-pthreads/config/configure.in b/mit-pthreads/config/configure.in
deleted file mode 100755
index 45cf0c74809..00000000000
--- a/mit-pthreads/config/configure.in
+++ /dev/null
@@ -1,745 +0,0 @@
-dnl Some reminders:
-dnl "dnl" is a "delete to newline" command for m4 - the remainder of the
-dnl line it's on, including the newline, will be discarded
-dnl "#" comments will usually be copied through
-dnl "[]" are quoting characters; use changequote around code that really
-dnl needs to use them, but try not to invoke autoconf macros
-dnl within such code
-dnl
-dnl When you change this file, re-run "autoreconf" -- that'll automatically
-dnl re-run both autoconf and autoheader.
-dnl
-dnl
-dnl To do:
-dnl CLOCKS_PER_SEC (default 100, Ultrix differs)
-dnl CLK_TCK (default 100, Ultrix differs)
-dnl clockid_t (not on all systems)
-dnl timer_t (not on all systems)
-dnl
-dnl
-dnl Now, the real stuff.
-dnl
-dnl This must be first.
-AC_INIT(config.flags.in)
-dnl
-dnl This file does require autoconf 2.0 or better...
-dnl
-AC_PREREQ(2.0)dnl
-dnl
-dnl Hook for the "--enable-dce-compat" option, when Chris actually
-dnl implements it.
-dnl
-AC_ARG_ENABLE(dce-compat,
- --enable-dce-compat DCE compatibility,
-[dnl "true" action
- AC_MSG_ERROR([Actually, DCE compatibility doesn't work yet...])
-],
-[dnl "false" action
- true
-])
-
-dnl What C compiler?
-AC_PROG_CC
-AC_PROG_CXX
-dnl Apparently autoconf doesn't test to see if the C compiler it locates
-dnl actually works... oops!
-AC_MSG_CHECKING(compiler availability and simple error detection)
-AC_TRY_COMPILE(,[ exit(0); ],[
- dnl true
- AC_TRY_COMPILE(,[ syntax errors galore! ],
- dnl true
- AC_MSG_ERROR(Can't detect syntax errors! Is CC set right?),
- dnl false
- true)],
- dnl false
- AC_MSG_ERROR(Can't compile test program! Is CC set right?))
-
-AC_TRY_COMPILE(,[
- typedef int Integer;
- extern int i;
- extern Integer i;
-], , AC_MSG_ERROR(Can't redeclare variables with this compiler??))
-AC_TRY_COMPILE(,[
- typedef long Long;
- extern int i;
- extern Long i;
-], AC_MSG_ERROR(Compiler doesn't detect conflicting declarations.))
-AC_MSG_RESULT(ok)
-
-if test $ac_cv_prog_gcc = yes ; then
- CFLAGS="$CFLAGS -Werror"
-fi
-
-AC_PROG_CPP
-
-AC_PROG_RANLIB
-
-dnl Default value of prefix should be /usr/local/pthreads, not /usr/local.
-AC_PREFIX_DEFAULT(/usr/local/pthreads)
-
-dnl Determine $host, by guessing if necessary.
-AC_CANONICAL_SYSTEM
-
-syscall=NONE
-sysincludes=NONE
-extraincludes=NONE
-
-# Treat all x86 machines the same.
-# (Yet below, we pretend we can distinguish between the MIPS r2000 and r4000?)
-# (What about 680x0 machines?)
-changequote(,)dnl
-case $host in
- i[456]86-*)
- host=`echo $host | sed 's/^i[456]86/i386/'`
- host_cpu=i386
- ;;
-esac
-changequote([,])dnl
-
-# Here, you should set the following variables:
-# name
-# The "name" of this configuration. Used for "engine-*.c" file name,
-# default for syscall file names. Chris seems to have a thing for
-# putting "-" between OS and version number, but the configure script
-# will already have $host_cpu and $host_os available for you to use
-# in constructing a name.
-# sysincludes
-# Name of machdep directory with "sys" include file
-# replacements, if any. This directory is optional;
-# if you don't provide it, don't set this variable.
-# except
-# Names of any syscalls that shouldn't be generated
-# from the template, if any.
-# syscall
-# Base name of the syscall template files, if not the
-# same as <name>. If they're the same, omit this.
-#
-# Also, you may define random symbols and update CFLAGS if
-# necessary. However, for ease of porting to new machines,
-# it's best if you can create portable autoconf tests for
-# whatever you're trying to do, rather than hard-coding it
-# here based on the OS name. So please, try to keep this
-# section as minimal as possible.
-
-except=""
-name=$host_cpu-$host_os
-
-case $host in
-changequote(,)dnl
- alpha-*-netbsd1.3[H-Z]|alpha-*-netbsd1.[45]*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
-changequote([,])dnl
- alpha-*-netbsd1.3*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask fstat"
- ;;
- alpha-*-netbsd1.1* | alpha-*-netbsd1.2*)
- name=alpha-netbsd-1.1
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- alpha-*-osf*)
- name=alpha-osf1
- sysincludes=alpha-osf1
- except="fork sigsuspend"
- if test $ac_cv_prog_gcc = no ; then
- CFLAGS="$CFLAGS -std"
- fi
- ;;
-changequote(,)dnl
- arm32-*-netbsd1.3[H-Z]|arm32-*-netbsd1.[45]*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
-changequote([,])dnl
- arm32-*-netbsd1.3*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate sigsuspend sigprocmask fstat"
- ;;
- hppa1.0-*-hpux10.20 | hppa1.1-*-hpux10.20)
- name=hppa-hpux-10.20
- sysincludes=hpux-10.20
- except="fork"
- ;;
- hppa1.1-*-hpux*9.*)
- name=hppa-hpux-9.03
- sysincludes=hpux-9.03
- # hpux-9.03.mk seems to be missing; what should this be?
- except="fork"
- ;;
- powerpc-*-netbsd1.*)
- name=powerpc-netbsd
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigprocmask sigaction sigsuspend"
- ;;
- sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
- name=sparc-sunos-4.1.3
- sysincludes=sunos-4.1.3
- syscall=sparc-sunos4
- except="fork pipe getpgrp getdirentries"
- AC_DEFINE(sunos4) # is this really needed??
- ;;
- sparc-*-solaris2.3* | sparc-*-solaris2.4*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.3
- except="fork sigaction"
- # Should really come up with a test for this...
- AC_DEFINE(LD_LINKS_STATIC_DATA)
- AC_DEFINE(BROKEN_SIGNALS)
- ;;
- sparc-*-solaris2*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.5
- except="fork sigaction"
- # Should really come up with a test for this...
- AC_DEFINE(LD_LINKS_STATIC_DATA)
- AC_DEFINE(BROKEN_SIGNALS)
- ;;
-changequote(,)dnl
- sparc-*-netbsd1.3[H-Z]|sparc-*-netbsd1.[45]*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate fstat"
- available_syscalls="sigprocmask sigsuspend"
- ;;
-changequote([,])dnl
- sparc-*-netbsd1.3*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate sigprocmask sigsuspend fstat"
- ;;
- sparc-*-netbsd1.0A | sparc-*-netbsd1.1* | sparc-*-netbsd1.2*)
- name=sparc-sunos-4.1.3
- sysincludes=netbsd-1.0
- syscall=sparc-netbsd-1.1
- except="pipe fork sigprocmask sigsuspend"
- ;;
- i386-*-openbsd2.*)
- name=i386-openbsd-2.0
- sysincludes=openbsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- i386-*-linux*)
- #name=i386-linux-1.0
- #sysincludes=linux-1.0
- name=i386-linux-2.0
- sysincludes=linux-2.0
- extraincludes="bits"
- ;;
- i386-*-bsdi1.1)
- name=i386-bsdi-1.1
- sysincludes=bsdi-1.1
- ;;
- i386-*-bsdi2.0* | i386-*-bsdi2.1*)
- name=i386-bsdi-2.0
- sysincludes=bsdi-2.0
- syscall=i386-bsdi-2.0
- except="fork lseek ftruncate sigsuspend"
- ;;
-changequote(,)dnl
- i386-*-netbsd1.3[H-Z]|i386-*-netbsd1.[45]*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
-changequote([,])dnl
- i386-*-netbsd1.3*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask fstat"
- ;;
- i386-*-netbsd1.1* | i386-*-netbsd1.2*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.1
- syscall=i386-netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.0*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.0
- except="fork lseek ftruncate sigsuspend"
- ;;
- i386-*-netbsd0.9*)
- name=i386-netbsd-0.9
- sysincludes=netbsd-0.9
- ;;
- m68*-*-netbsd*)
- name=m68000-netbsd
- sysincludes=netbsd-1.1
- except="lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- i386-*-freebsd*)
- name=i386-freebsd-2.0
- sysincludes=freebsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- romp-*-bsd*)
- name=romp-bsd
- ;;
- mips-dec-ultrix*)
- name=r2000-ultrix-4.2
- sysincludes=ultrix-4.2
- except="fork pipe"
- ;;
- mips-sgi-irix*)
- name=ip22-irix-5.2
- sysincludes=irix-5.2
- except="fstat stat"
- AC_DEFINE(BROKEN_SIGNALS)
- ;;
- i386-*-sco3.2v5*)
- name=i386-sco3.2.5
- sysincludes=i386-sco3.2.5
- syscall=i386-sco3.2.5
- except="select socketcall accept bind connect getpeername getsockname getsockopt setsockopt listen recv recvfrom recvmsg send sendmsg sendto shutdown socket socketpair fork fcntl dup2 fstat fchmod fchown ftruncate pipe getdirentries sigaction sigpause wait3 waitpid getdtablesize"
- ;;
- *)
- AC_MSG_ERROR(System type $host not recognized or not supported.
-See $srcdir/configure.in for supported systems.)
- exit 1
- ;;
-esac
-
-SYSCALL_EXCEPTIONS=$except
-AC_SUBST(SYSCALL_EXCEPTIONS)
-
-AC_CHECK_HEADERS(sys/termio.h termios.h termio.h alloc.h)
-
-dnl Don't use AC_CHECK_HEADERS for this one, we want to define a special
-dnl symbol name starting with pthread_ if it's found.
-AC_CHECK_HEADER(va_list.h, AC_DEFINE(pthread_have_va_list_h))
-
-dnl Generate a list of system calls that we could generate. We later use
-dnl a syscall template .S file to produce a .o file for each syscall. This
-dnl is a bit better for porting and development purposes than having every
-dnl syscall listed for every target system; this way we only need the
-dnl template, and special hanlding for only those syscalls that can't be
-dnl handled by the templates.
-AC_CHECK_HEADERS(syscall.h sys/syscall.h sys/filio.h)
-
-PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- rename select getdtablesize ioctl ftruncate flock fstatfs chroot uname
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
- getdents readdir getdirentries
- dnl - variants of `wait' syscalls
- wait4 wait3 waitpid waitsys
- dnl - BSD socket calls
- socket bind connect accept listen getsockopt setsockopt socketpair
- dnl - SYSV stream calls
- poll putmsg getmsg
- dnl - Linux version uses one syscall
- socketcall
-
- dnl - Process info
- pgrpsys
-
- exit
- readv writev send sendto sendmsg recv recvfrom recvmsg
- getpeername getsockname
- shutdown
- getpgrp fork)
-
-AC_SUBST(available_syscalls)
-AC_SUBST(missing_syscalls)
-
-dnl Disabled for now -- generates warnings from autoconf.
-dnl ## Check some type sizes.
-dnl AC_CHECK_SIZEOF(int)
-dnl AC_CHECK_SIZEOF(long)
-dnl AC_CHECK_SIZEOF(char *)
-
-## Determine some typedef values from the system header files.
-dnl
-dnl Autoconf provides these automatically. They provide reasonable
-dnl fallbacks if the standard header files don't define the typedef names.
-dnl
-dnl AC_TYPE_MODE_T
-AC_TYPE_OFF_T
-dnl AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-dnl AC_TYPE_UID_T
-AC_TYPE_SIGNAL
-dnl
-dnl Default these types if their definitions can't be found.
-dnl
-AC_CHECK_TYPE(ssize_t,int)
-AC_CHECK_TYPE(time_t,long)
-dnl
-AC_CHECK_HEADERS(sys/time.h)
-AC_HEADER_TIME
-
-dnl
-dnl Check for the existence of these types
-dnl
-dnl struct timespec
-dnl
-AC_MSG_CHECKING(for struct timespec in sys/time.h)
-AC_CACHE_VAL(pthreads_cv_timespec_in_time,
- AC_TRY_COMPILE([#include <sys/time.h>], [struct timespec foo;],
- pthreads_cv_timespec_in_time=yes, pthreads_cv_timespec_in_time=no))
-AC_MSG_RESULT($pthreads_cv_timespec_in_time)
-if test $pthreads_cv_timespec_in_time = yes ; then
- AC_DEFINE(_OS_HAS_TIMESPEC)
-fi
-
-dnl socklen_t
-AC_CACHE_VAL(pthreads_cv_socklen_t,
- AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/socket.h>], [socklen_t foo;],
- pthreads_cv_socklen_t=yes, pthreads_cv_socklen_t=no))
-AC_MSG_RESULT($pthreads_cv_socklen_t)
-if test $pthreads_cv_socklen_t = yes ; then
- AC_DEFINE(_OS_HAS_SOCKLEN_T)
-fi
-
-
-dnl
-dnl Usage: PTHREADS_FIND_TYPE(system-typedef-name, new-macro-name,
-dnl list-of-includes-in-square-brackets,
-dnl comma-separated-list-of-types-to-try)
-dnl
-dnl PTHREADS_FIND_INTEGRAL_TYPE automatically provides a set of integral
-dnl types, and does not permit specification of additional types.
-dnl
-dnl The specified types must all be able to work as prefixes -- i.e., no
-dnl direct specification of array or function types. If you need such
-dnl types, add typedefs for them to include/pthread/xtypes.h, and include
-dnl that in the set of header files. For simple struct types, you can
-dnl try including the definition directly here, but it had better not
-dnl contain any commas or square brackets.
-dnl
-dnl If necessary, you can include other preprocessing commands and such
-dnl in the `includes' portion.
-dnl
-dnl Note: For now, each of these needs a corresponding entry
-dnl in acconfig.h.
-dnl
-dnl size_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(size_t, pthread_size_t, [
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-])
-dnl
-dnl ssize_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(ssize_t, pthread_ssize_t, [
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-])
-dnl
-dnl clock_t ---FIXME I don't know if this is the right set of header files. KR
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(clock_t, pthread_clock_t, [
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-])
-dnl
-dnl time_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(time_t, pthread_time_t, [
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-])
-dnl
-dnl fpos_t
-dnl
-dnl If fpos_t isn't defined in stdio.h, define it to be off_t. It
-dnl looks like AC_CHECK_TYPE won't work for this, because it doesn't
-dnl include stdio.h.
-dnl
-AC_MSG_CHECKING(for fpos_t in stdio.h)
-AC_CACHE_VAL(pthreads_cv_fpos_t_in_stdio,
- AC_TRY_COMPILE([#include <stdio.h>], [fpos_t position;],
- pthreads_cv_fpos_t_in_stdio=yes, pthreads_cv_fpos_t_in_stdio=no))
-AC_MSG_RESULT($pthreads_cv_fpos_t_in_stdio)
-if test $pthreads_cv_fpos_t_in_stdio = yes ; then
- PTHREADS_FIND_INTEGRAL_TYPE(fpos_t, pthread_fpos_t, [
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-])
-else
- AC_DEFINE(fpos_t,off_t)
- AC_DEFINE(pthread_fpos_t,pthread_off_t)
-fi
-dnl
-dnl off_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(off_t, pthread_off_t, [
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-])
-dnl
-dnl va_list -- This one could be tricky. Fortunately, on some systems,
-dnl we can just include the gcc stdarg.h header file if we can't determine
-dnl the type here. Won't work for non-gcc configurations though.
-dnl
-PTHREADS_FIND_TYPE(va_list, pthread_va_list, [#include <stdarg.h>],
- char *, char **, void *, void **, int *, long *)
-dnl
-dnl
-
-arpa_headers="#include <sys/types.h>
-#include <arpa/nameser.h>"
-
-dnl
-dnl Type for network (IP) addresses, 32 bits.
-dnl For now, I'm assuming that the return type from _getlong is it.
-dnl
-AC_MSG_CHECKING(IP address type)
-AC_CACHE_VAL(pthread_cv_type_ipaddr,
- AC_TRY_COMPILE($arpa_headers,[ &_getlong; ],[
- for type in "unsigned long" "unsigned int" ; do
- AC_TRY_COMPILE($arpa_headers, extern $type _getlong ();,[
- pthread_cv_type_ipaddr="$type"
- break
- ])
- done
- ],[ AC_MSG_WARN(Can't compile _getlong reference.) ])
- if test "$pthread_cv_type_ipaddr" = "" ; then
- AC_MSG_WARN(Can't determine _getlong return type.)
- AC_MSG_WARN(Defaulting to unsigned long.)
- pthread_cv_type_ipaddr="unsigned long"
- fi
-)
-AC_MSG_RESULT($pthread_cv_type_ipaddr)
-AC_DEFINE_UNQUOTED(pthread_ipaddr_type,$pthread_cv_type_ipaddr)
-
-dnl
-dnl Type for network (IP) ports, 16 bits.
-dnl For now, I'm assuming that the return type from _getshort is it.
-dnl
-AC_MSG_CHECKING(IP port type)
-AC_CACHE_VAL(pthread_cv_type_ipport,
- AC_TRY_COMPILE($arpa_headers,[ &_getshort; ],[
- for type in "unsigned short" "unsigned int" ; do
- AC_TRY_COMPILE($arpa_headers, extern $type _getshort ();,[
- pthread_cv_type_ipport="$type"
- break
- ])
- done
- ],[ AC_MSG_WARN(Can't compile _getshort reference.) ])
- if test "$pthread_cv_type_ipport" = "" ; then
- AC_MSG_WARN(Can't determine _getshort return type.)
- AC_MSG_WARN(Defaulting to unsigned short.)
- pthread_cv_type_ipport="unsigned short"
- fi
-)
-AC_MSG_RESULT($pthread_cv_type_ipport)
-AC_DEFINE_UNQUOTED(pthread_ipport_type,$pthread_cv_type_ipport)
-
-dnl
-dnl Guess where terminal devices are stored. This is for use in the
-dnl ttyname() implementation provided here.
-dnl
-AC_MSG_CHECKING(pathname for terminal devices directory)
-AC_CACHE_VAL(pthread_cv_pty_path,
- if test -d /devices/pseudo ; then
- pty_path=/devices/pseudo/
- else
- pty_path=/dev/
- fi
- pthread_cv_pty_path=$pty_path
-)
-AC_DEFINE_UNQUOTED(_PATH_PTY,"$pthread_cv_pty_path")
-AC_MSG_RESULT($pthread_cv_pty_path)
-
-dnl
-dnl Look for timezone info, for use in ctime.
-dnl
-AC_MSG_CHECKING(directory name for time zone info)
-tzdir=NONE
-for f in /usr/lib/zoneinfo /usr/share/zoneinfo /usr/share/lib/zoneinfo /etc/zoneinfo /usr/local/lib/zoneinfo
-do
- if test -d $f ; then
- tzdir=$f
- break
- fi
-done
-case $tzdir in
-NONE)
- AC_MSG_WARN(Can't find zoneinfo directory.)
- AC_MSG_WARN(Defaulting zoneinfo directory to NULL.)
- tzdir=NULL
- ;;
-esac
-AC_DEFINE_UNQUOTED(_PATH_TZDIR,"$tzdir")
-AC_MSG_RESULT($tzdir)
-
-AC_MSG_CHECKING(filename for local time zone)
-tzfile=NONE
-for f in $tzdir/localtime /etc/localtime
-do
- if test -f $f ; then
- tzfile=$f
- break
- fi
-done
-case $tzfile in
-NONE) # Should this default to tzdir/localtime?
- AC_MSG_WARN(Can't find local time zone file.)
- if test tzdir = NULL ; then
- AC_MSG_WARN(Defaulting local time zone file to NULL)
- tzfile=NULL
- else
- AC_MSG_WARN(Defaulting local time zone file to $tzdir/localtime.)
- tzfile=$tzdir/localtime
- fi
- ;;
-esac
-AC_DEFINE_UNQUOTED(_PATH_TZFILE,"$tzfile")
-AC_MSG_RESULT($tzfile)
-
-dnl
-dnl Network stuff. At the moment, I don't think there are any other
-dnl values we should expect. If we find a system that does store these
-dnl files elsewhere -- or doesn't have them all -- then run some tests.
-dnl
-AC_DEFINE(_PATH_RESCONF, "/etc/resolv.conf")
-AC_DEFINE(_PATH_HOSTS, "/etc/hosts")
-AC_DEFINE(_PATH_NETWORKS, "/etc/networks")
-AC_DEFINE(_PATH_PROTOCOLS, "/etc/protocols")
-AC_DEFINE(_PATH_SERVICES, "/etc/services")
-
-dnl
-dnl Other stuff
-dnl
-AC_DEFINE(_PATH_BSHELL, "/bin/sh")
-
-dnl If the system provides vfork, autoconf scripts will detect it.
-dnl So we should hide it.
-AC_CHECK_FUNCS(vfork)
-
-srctop=`cd ${srcdir}/..;pwd`
-AC_SUBST(srctop)
-
-# Now we deal with symlinks &c.
-
-test -d include || mkdir include || \
- AC_MSG_ERROR(Can't create include directory.)
-
-test -d include/pthread || mkdir include/pthread || \
- AC_MSG_ERROR(Can't create include/pthread directory.)
-
-test -d lib || mkdir lib || \
- AC_MSG_ERROR(Can't create lib directory.)
-
-test -d lib/libpthreadutil || mkdir lib/libpthreadutil || \
- AC_MSG_ERROR(Can't create lib/libpthreadutil directory.)
-
-test -d bin || mkdir bin || \
- AC_MSG_ERROR(Can't create bin directory.)
-
-test -d bin/finger || mkdir bin/finger || \
- AC_MSG_ERROR(Can't create bin directory.)
-
-test -d tests || mkdir tests || \
- AC_MSG_ERROR(Can't create tests directory.)
-
-if test x$syscall = xNONE ; then
- syscall=$name
-fi
-
-links="include/pthread/machdep.h include/pthread/posix.h \
- machdep.c syscall.S"
-targets="../machdep/engine-$name.h ../machdep/posix-$sysincludes.h \
- ../machdep/engine-$name.c ../machdep/syscall-$syscall.S"
-
-# Both these targets are optional. (Autoconf-generated configure scripts
-# will require the existence of link targets, so check before adding them
-# to the list.)
-if test x$sysincludes != xNONE ; then
- links="$links include/sys"
- targets="$targets ../machdep/$sysincludes"
-fi
-
-if test x$extraincludes != xNONE ; then
- for tmp in $extraincludes
- do
- links="$links include/$tmp"
- targets="$targets ../machdep/$sysincludes/extra/$tmp"
- done
-fi
-
-syscall_file=../machdep/syscall-template-$syscall.S
-if test -r $srcdir/$syscall_file ; then
- links="$links syscall-template.S"
- targets="$targets $syscall_file"
- HAVE_SYSCALL_TEMPLATE=yes
-else
- # This really isn't a fatal problem. In fact, it's expected, initially,
- # for some targets. This is just to persuade people to fix the targets
- # they deal with to provide some sort of template.
- #
- # Eventually this file probably will be required...
- AC_MSG_WARN(No syscall template file syscall-template-$syscall.S found.)
- HAVE_SYSCALL_TEMPLATE=no
-fi
-AC_SUBST(HAVE_SYSCALL_TEMPLATE)
-
-dnl Now tell it to make the links.
-dnl (The links are actually made by config.status.)
-AC_LINK_FILES($targets, $links)
-
-if test x$makefile_frag != x ; then
- makefile_frag=${srcdir}/$makefile_frag
-else
- makefile_frag=/dev/null
-fi
-dnl Drop in file indicated by $makefile_frag on *the line after* the
-dnl magic @makefile_frag@ sequence.
-AC_SUBST_FILE(makefile_frag)
-
-
-dnl Generate output files...
-AC_CONFIG_HEADER(config.h)
-
-dnl This must be last.
-AC_OUTPUT(config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in)
diff --git a/mit-pthreads/config/configure.org b/mit-pthreads/config/configure.org
deleted file mode 100755
index f8526844a24..00000000000
--- a/mit-pthreads/config/configure.org
+++ /dev/null
@@ -1,2874 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.10
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
---enable-dce-compat DCE compatibility"
-ac_default_prefix=/usr/local/pthreads
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-
-ac_prev=
-for ac_option
-do
-
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case "$ac_option" in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
-
- -disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.10"
- exit 0 ;;
-
- -with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
-
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
- ;;
-
- *)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=config.flags.in
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
-else
- echo "creating cache $cache_file"
- > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
- fi
-else
- ac_n= ac_c='\c' ac_t=
-fi
-
-
-# Check whether --enable-dce-compat or --disable-dce-compat was given.
-if test "${enable_dce_compat+set}" = set; then
- enableval="$enable_dce_compat"
- { echo "configure: error: Actually, DCE compatibility doesn't work yet..." 1>&2; exit 1; }
-
-else
- true
-
-fi
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- ac_prog_rejected=no
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# -gt 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
- fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:616: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
- if test "${CFLAGS+set}" != set; then
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_gcc_g=yes
-else
- ac_cv_prog_gcc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
- if test $ac_cv_prog_gcc_g = yes; then
- CFLAGS="-g -O"
- else
- CFLAGS="-O"
- fi
- fi
-else
- GCC=
- test "${CFLAGS+set}" = set || CFLAGS="-g"
-fi
-
-for ac_prog in $CCC c++ g++ gcc CC cxx
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CXX="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CXX="$ac_cv_prog_CXX"
-if test -n "$CXX"; then
- echo "$ac_t""$CXX" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$CXX" && break
-done
-test -n "$CXX" || CXX="gcc"
-
-
-echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.C <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:696: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gxx=yes
-else
- ac_cv_prog_gxx=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx" 1>&6
-if test $ac_cv_prog_gxx = yes; then
- GXX=yes
- if test "${CXXFLAGS+set}" != set; then
- echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gxx_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.cc
-if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
- ac_cv_prog_gxx_g=yes
-else
- ac_cv_prog_gxx_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx_g" 1>&6
- if test $ac_cv_prog_gxx_g = yes; then
- CXXFLAGS="-g -O"
- else
- CXXFLAGS="-O"
- fi
- fi
-else
- GXX=
- test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
-fi
-
-echo $ac_n "checking compiler availability and simple error detection""... $ac_c" 1>&6
-cat > conftest.$ac_ext <<EOF
-#line 735 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
- exit(0);
-; return 0; }
-EOF
-if { (eval echo configure:743: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- cat > conftest.$ac_ext <<EOF
-#line 747 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
- syntax errors galore!
-; return 0; }
-EOF
-if { (eval echo configure:755: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Can't detect syntax errors! Is CC set right?" 1>&2; exit 1; }
-else
- rm -rf conftest*
- true
-fi
-rm -f conftest*
-
-else
- rm -rf conftest*
- { echo "configure: error: Can't compile test program! Is CC set right?" 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-
-cat > conftest.$ac_ext <<EOF
-#line 772 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-
- typedef int Integer;
- extern int i;
- extern Integer i;
-
-; return 0; }
-EOF
-if { (eval echo configure:784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- :
-else
- rm -rf conftest*
- { echo "configure: error: Can't redeclare variables with this compiler??" 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-cat > conftest.$ac_ext <<EOF
-#line 793 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-
- typedef long Long;
- extern int i;
- extern Long i;
-
-; return 0; }
-EOF
-if { (eval echo configure:805: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Compiler doesn't detect conflicting declarations." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-echo "$ac_t""ok" 1>&6
-
-if test $ac_cv_prog_gcc = yes ; then
- CFLAGS="$CFLAGS -Werror"
-fi
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 832 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:838: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 847 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:853: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Do some error checking and defaulting for the host and target type.
-# The inputs are:
-# configure --host=HOST --target=TARGET --build=BUILD NONOPT
-#
-# The rules are:
-# 1. You are not allowed to specify --host, --target, and nonopt at the
-# same time.
-# 2. Host defaults to nonopt.
-# 3. If nonopt is not specified, then host defaults to the current host,
-# as determined by config.guess.
-# 4. Target and build default to nonopt.
-# 5. If nonopt is not specified, then target and build default to host.
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-case $host---$target---$nonopt in
-NONE---*---* | *---NONE---* | *---*---NONE) ;;
-*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
-esac
-
-
-# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`$ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-echo $ac_n "checking target system type""... $ac_c" 1>&6
-
-target_alias=$target
-case "$target_alias" in
-NONE)
- case $nonopt in
- NONE) target_alias=$host_alias ;;
- *) target_alias=$nonopt ;;
- esac ;;
-esac
-
-target=`$ac_config_sub $target_alias`
-target_cpu=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-target_vendor=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-target_os=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$target" 1>&6
-
-echo $ac_n "checking build system type""... $ac_c" 1>&6
-
-build_alias=$build
-case "$build_alias" in
-NONE)
- case $nonopt in
- NONE) build_alias=$host_alias ;;
- *) build_alias=$nonopt ;;
- esac ;;
-esac
-
-build=`$ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
-
-test "$host_alias" != "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
-
-
-syscall=NONE
-sysincludes=NONE
-
-# Treat all x86 machines the same.
-# (Yet below, we pretend we can distinguish between the MIPS r2000 and r4000?)
-# (What about 680x0 machines?)
-case $host in
- i[456]86-*)
- host=`echo $host | sed 's/^i[456]86/i386/'`
- host_cpu=i386
- ;;
-esac
-
-# Here, you should set the following variables:
-# name
-# The "name" of this configuration. Used for "engine-*.c" file name,
-# default for syscall file names. Chris seems to have a thing for
-# putting "-" between OS and version number, but the configure script
-# will already have $host_cpu and $host_os available for you to use
-# in constructing a name.
-# sysincludes
-# Name of machdep directory with "sys" include file
-# replacements, if any. This directory is optional;
-# if you don't provide it, don't set this variable.
-# except
-# Names of any syscalls that shouldn't be generated
-# from the template, if any.
-# syscall
-# Base name of the syscall template files, if not the
-# same as <name>. If they're the same, omit this.
-#
-# Also, you may define random symbols and update CFLAGS if
-# necessary. However, for ease of porting to new machines,
-# it's best if you can create portable autoconf tests for
-# whatever you're trying to do, rather than hard-coding it
-# here based on the OS name. So please, try to keep this
-# section as minimal as possible.
-
-except=""
-name=$host_cpu-$host_os
-
-case $host in
- alpha-*-netbsd1.1* | alpha-*-netbsd1.2*)
- name=alpha-netbsd-1.1
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- alpha-*-osf*)
- name=alpha-osf1
- sysincludes=alpha-osf1
- except="fork sigsuspend"
- if test $ac_cv_prog_gcc = no ; then
- CFLAGS="$CFLAGS -std"
- fi
- ;;
- hppa1.1-*-hpux*)
- name=hppa-hpux-9.03
- sysincludes=hpux-9.03
- # hpux-9.03.mk seems to be missing; what should this be?
- except="fork"
- ;;
- sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
- name=sparc-sunos-4.1.3
- sysincludes=sunos-4.1.3
- syscall=sparc-sunos4
- except="fork pipe getpgrp getdirentries"
- cat >> confdefs.h <<\EOF
-#define sunos4 1
-EOF
- # is this really needed??
- ;;
- sparc-*-solaris2*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.3
- except="fork sigaction"
- # Should really come up with a test for this...
- cat >> confdefs.h <<\EOF
-#define LD_LINKS_STATIC_DATA 1
-EOF
-
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- sparc-*-netbsd1.0A | sparc-*-netbsd1.1* | sparc-*-netbsd1.2*)
- name=sparc-sunos-4.1.3
- sysincludes=netbsd-1.0
- syscall=sparc-netbsd-1.1
- except="pipe fork sigprocmask sigsuspend"
- ;;
- i386-*-linux*)
- name=i386-linux-1.0
- sysincludes=linux-1.0
- ;;
- i386-*-bsdi1.1)
- name=i386-bsdi-1.1
- sysincludes=bsdi-1.1
- ;;
- i386-*-bsdi2.0* | i386-*-bsdi2.1*)
- name=i386-bsdi-2.0
- sysincludes=bsdi-2.0
- syscall=i386-bsdi-2.0
- except="fork lseek sigsuspend"
- ;;
- i386-*-netbsd1.1* | i386-*-netbsd1.2*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.1
- syscall=i386-netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.0*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.0
- except="fork lseek sigsuspend"
- ;;
- i386-*-netbsd0.9*)
- name=i386-netbsd-0.9
- sysincludes=netbsd-0.9
- ;;
- m68*-*-netbsd*)
- name=m68000-netbsd
- ;;
- i386-*-freebsd2.*)
- name=i386-freebsd-2.0
- sysincludes=freebsd-2.0
- except="fork lseek sigsuspend sigprocmask"
- ;;
- romp-*-bsd*)
- name=romp-bsd
- ;;
- mips-dec-ultrix*)
- name=r2000-ultrix-4.2
- sysincludes=ultrix-4.2
- except="fork pipe"
- ;;
- mips-sgi-irix*)
- name=ip22-irix-5.2
- sysincludes=irix-5.2
- except="fstat stat"
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- *)
- { echo "configure: error: System type $host not recognized or not supported.
-See $srcdir/configure.in for supported systems." 1>&2; exit 1; }
- exit 1
- ;;
-esac
-
-SYSCALL_EXCEPTIONS=$except
-
-
-for ac_hdr in sys/termio.h termios.h termio.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1174 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1179: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-ac_safe=`echo "va_list.h" | tr './\055' '___'`
-echo $ac_n "checking for va_list.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1210 "configure"
-#include "confdefs.h"
-#include <va_list.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1215: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define pthread_have_va_list_h 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-for ac_hdr in syscall.h sys/syscall.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1246 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-pthreads_syscall_list="open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- rename select getdtablesize ioctl ftruncate
- sigsuspend sigaction sigpause sigprocmask ksigaction
- getdents readdir getdirentries
- wait4 wait3 waitpid waitsys
- socket bind connect accept listen getsockopt setsockopt socketpair
- poll putmsg getmsg
- socketcall
-
- pgrpsys
-
- exit
- readv writev send sendto sendmsg recv recvfrom recvmsg
- getpeername getsockname
- shutdown
- getpgrp fork"
-for pthreads_syscallname in $pthreads_syscall_list ; do
- echo $ac_n "checking for syscall $pthreads_syscallname""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_syscall_$pthreads_syscallname'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1299 "configure"
-#include "confdefs.h"
-
-/* FIXME: This list should be generated from info in configure.in. */
-#ifdef HAVE_SYSCALL_H
-#include <syscall.h>
-#else
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#else
-where is your syscall header file??
-#endif
-#endif
-
-int main() { return 0; }
-int t() {
-
-int x;
-x = SYS_$pthreads_syscallname ;
-
-; return 0; }
-EOF
-if { (eval echo configure:1321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=yes
-else
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=no
-fi
-rm -f conftest*
-
-fi
-
-if eval test \$pthreads_cv_syscall_$pthreads_syscallname = yes ; then
- pthreads_syscall_present=yes
- available_syscalls="$available_syscalls $pthreads_syscallname"
- macroname=HAVE_SYSCALL_`echo $pthreads_syscallname | tr '[a-z]' '[A-Z]'`
- cat >> confdefs.h <<EOF
-#define $macroname 1
-EOF
-
-else
- pthreads_syscall_present=no
- missing_syscalls="$missing_syscalls $pthreads_syscallname"
-fi
-echo "$ac_t""$pthreads_syscall_present" 1>&6
-
-done
-
-
-
-
-
-
-## Determine some typedef values from the system header files.
-# If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_cross=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 1363 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-{ (eval echo configure:1367: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_c_cross=no
-else
- ac_cv_c_cross=yes
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
-
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1385 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- ac_cv_header_stdc=yes
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1408 "configure"
-#include "confdefs.h"
-#include <string.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1426 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
- :
-else
-cat > conftest.$ac_ext <<EOF
-#line 1447 "configure"
-#include "confdefs.h"
-#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
-
-EOF
-{ (eval echo configure:1458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- :
-else
- ac_cv_header_stdc=no
-fi
-fi
-rm -fr conftest*
-fi
-fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
-if test $ac_cv_header_stdc = yes; then
- cat >> confdefs.h <<\EOF
-#define STDC_HEADERS 1
-EOF
-
-fi
-
-echo $ac_n "checking for off_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1482 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "off_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_off_t=yes
-else
- rm -rf conftest*
- ac_cv_type_off_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_off_t" 1>&6
-if test $ac_cv_type_off_t = no; then
- cat >> confdefs.h <<\EOF
-#define off_t long
-EOF
-
-fi
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1513 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "size_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_size_t=yes
-else
- rm -rf conftest*
- ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
- cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1544 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "ssize_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_ssize_t=yes
-else
- rm -rf conftest*
- ac_cv_type_ssize_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
-if test $ac_cv_type_ssize_t = no; then
- cat >> confdefs.h <<\EOF
-#define ssize_t int
-EOF
-
-fi
-
-echo $ac_n "checking for time_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1575 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "time_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_time_t=yes
-else
- rm -rf conftest*
- ac_cv_type_time_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_time_t" 1>&6
-if test $ac_cv_type_time_t = no; then
- cat >> confdefs.h <<\EOF
-#define time_t long
-EOF
-
-fi
-
-for ac_hdr in sys/time.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1609 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1614: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1643 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-int main() { return 0; }
-int t() {
-struct tm *tp;
-; return 0; }
-EOF
-if { (eval echo configure:1653: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_header_time=yes
-else
- rm -rf conftest*
- ac_cv_header_time=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_header_time" 1>&6
-if test $ac_cv_header_time = yes; then
- cat >> confdefs.h <<\EOF
-#define TIME_WITH_SYS_TIME 1
-EOF
-
-fi
-
-
-echo $ac_n "checking for struct timespec in sys/time.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_timespec_in_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1678 "configure"
-#include "confdefs.h"
-#include <sys/time.h>
-int main() { return 0; }
-int t() {
-struct timespec foo;
-; return 0; }
-EOF
-if { (eval echo configure:1686: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_timespec_in_time=yes
-else
- rm -rf conftest*
- pthreads_cv_timespec_in_time=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$pthreads_cv_timespec_in_time" 1>&6
-if test $pthreads_cv_timespec_in_time = yes ; then
- cat >> confdefs.h <<\EOF
-#define _OS_HAS_TIMESPEC 1
-EOF
-
-fi
-
-
-
-echo $ac_n "checking type of size_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1712 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern size_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1726: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1730 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern size_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1744: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_size_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for size_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_size_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_size_t $pthreads_cv_type_size_t
-EOF
-
-fi
-pthread_size_t=$pthreads_cv_type_size_t
-echo "$ac_t""$pthreads_cv_type_size_t" 1>&6
-
-echo $ac_n "checking type of ssize_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1773 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() { return 0; }
-int t() {
- extern ssize_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1785: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1789 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() { return 0; }
-int t() {
- extern ssize_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1801: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_ssize_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for ssize_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_ssize_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_ssize_t $pthreads_cv_type_ssize_t
-EOF
-
-fi
-pthread_ssize_t=$pthreads_cv_type_ssize_t
-echo "$ac_t""$pthreads_cv_type_ssize_t" 1>&6
-
-echo $ac_n "checking type of clock_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_clock_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1830 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern clock_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1854 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern clock_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1874: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_clock_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for clock_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_clock_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_clock_t $pthreads_cv_type_clock_t
-EOF
-
-fi
-pthread_clock_t=$pthreads_cv_type_clock_t
-echo "$ac_t""$pthreads_cv_type_clock_t" 1>&6
-
-echo $ac_n "checking type of time_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1903 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern time_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1927 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern time_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1947: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_time_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for time_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_time_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_time_t $pthreads_cv_type_time_t
-EOF
-
-fi
-pthread_time_t=$pthreads_cv_type_time_t
-echo "$ac_t""$pthreads_cv_type_time_t" 1>&6
-echo $ac_n "checking for fpos_t in stdio.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_fpos_t_in_stdio'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1975 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() { return 0; }
-int t() {
-fpos_t position;
-; return 0; }
-EOF
-if { (eval echo configure:1983: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=yes
-else
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$pthreads_cv_fpos_t_in_stdio" 1>&6
-if test $pthreads_cv_fpos_t_in_stdio = yes ; then
-
-echo $ac_n "checking type of fpos_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_fpos_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2002 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern fpos_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2016: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2020 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern fpos_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2034: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_fpos_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for fpos_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_fpos_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_fpos_t $pthreads_cv_type_fpos_t
-EOF
-
-fi
-pthread_fpos_t=$pthreads_cv_type_fpos_t
-echo "$ac_t""$pthreads_cv_type_fpos_t" 1>&6
-else
- cat >> confdefs.h <<\EOF
-#define fpos_t off_t
-EOF
-
- cat >> confdefs.h <<\EOF
-#define pthread_fpos_t pthread_off_t
-EOF
-
-fi
-
-echo $ac_n "checking type of off_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2073 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern off_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2087: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2091 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern off_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2105: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_off_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for off_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_off_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_off_t $pthreads_cv_type_off_t
-EOF
-
-fi
-pthread_off_t=$pthreads_cv_type_off_t
-echo "$ac_t""$pthreads_cv_type_off_t" 1>&6
-echo $ac_n "checking type of va_list""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_va_list'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2133 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() { return 0; }
-int t() {
- extern va_list foo;
-; return 0; }
-EOF
-if { (eval echo configure:2141: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "char *" "char **" "void *" "void **" "int *" "long *" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2145 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() { return 0; }
-int t() {
- extern va_list foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2153: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_va_list="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for va_list." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_va_list" ; then
- cat >> confdefs.h <<EOF
-#define pthread_va_list $pthreads_cv_type_va_list
-EOF
-
-fi
-pthread_va_list=$pthreads_cv_type_va_list
-echo "$ac_t""$pthreads_cv_type_va_list" 1>&6
-
-arpa_headers="#include <sys/types.h>
-#include <arpa/nameser.h>"
-
-echo $ac_n "checking IP address type""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthread_cv_type_ipaddr'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2185 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
- &_getlong;
-; return 0; }
-EOF
-if { (eval echo configure:2193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned long" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2198 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
-extern $type _getlong ();
-; return 0; }
-EOF
-if { (eval echo configure:2206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipaddr="$type"
- break
-
-fi
-rm -f conftest*
-
- done
-
-else
- rm -rf conftest*
- echo "configure: warning: Can't compile _getlong reference." 1>&2
-fi
-rm -f conftest*
-
- if test "$pthread_cv_type_ipaddr" = "" ; then
- echo "configure: warning: Can't determine _getlong return type." 1>&2
- echo "configure: warning: Defaulting to unsigned long." 1>&2
- pthread_cv_type_ipaddr="unsigned long"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipaddr" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipaddr_type $pthread_cv_type_ipaddr
-EOF
-
-
-echo $ac_n "checking IP port type""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthread_cv_type_ipport'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2242 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
- &_getshort;
-; return 0; }
-EOF
-if { (eval echo configure:2250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned short" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2255 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
-extern $type _getshort ();
-; return 0; }
-EOF
-if { (eval echo configure:2263: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipport="$type"
- break
-
-fi
-rm -f conftest*
-
- done
-
-else
- rm -rf conftest*
- echo "configure: warning: Can't compile _getshort reference." 1>&2
-fi
-rm -f conftest*
-
- if test "$pthread_cv_type_ipport" = "" ; then
- echo "configure: warning: Can't determine _getshort return type." 1>&2
- echo "configure: warning: Defaulting to unsigned short." 1>&2
- pthread_cv_type_ipport="unsigned short"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipport" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipport_type $pthread_cv_type_ipport
-EOF
-
-
-echo $ac_n "checking pathname for terminal devices directory""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthread_cv_pty_path'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -d /devices/pseudo ; then
- pty_path=/devices/pseudo/
- else
- pty_path=/dev/
- fi
- pthread_cv_pty_path=$pty_path
-
-fi
-
-cat >> confdefs.h <<EOF
-#define _PATH_PTY "$pthread_cv_pty_path"
-EOF
-
-echo "$ac_t""$pthread_cv_pty_path" 1>&6
-
-echo $ac_n "checking directory name for time zone info""... $ac_c" 1>&6
-tzdir=NONE
-for f in /usr/lib/zoneinfo /usr/share/zoneinfo /usr/share/lib/zoneinfo /etc/zoneinfo /usr/local/lib/zoneinfo
-do
- if test -d $f ; then
- tzdir=$f
- break
- fi
-done
-case $tzdir in
-NONE)
- echo "configure: warning: Can't find zoneinfo directory." 1>&2
- echo "configure: warning: Defaulting zoneinfo directory to NULL." 1>&2
- tzdir=NULL
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZDIR "$tzdir"
-EOF
-
-echo "$ac_t""$tzdir" 1>&6
-
-echo $ac_n "checking filename for local time zone""... $ac_c" 1>&6
-tzfile=NONE
-for f in $tzdir/localtime /etc/localtime
-do
- if test -f $f ; then
- tzfile=$f
- break
- fi
-done
-case $tzfile in
-NONE) # Should this default to tzdir/localtime?
- echo "configure: warning: Can't find local time zone file." 1>&2
- if test tzdir = NULL ; then
- echo "configure: warning: Defaulting local time zone file to NULL" 1>&2
- tzfile=NULL
- else
- echo "configure: warning: Defaulting local time zone file to $tzdir/localtime." 1>&2
- tzfile=$tzdir/localtime
- fi
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZFILE "$tzfile"
-EOF
-
-echo "$ac_t""$tzfile" 1>&6
-
-cat >> confdefs.h <<\EOF
-#define _PATH_RESCONF "/etc/resolv.conf"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_HOSTS "/etc/hosts"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_NETWORKS "/etc/networks"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_PROTOCOLS "/etc/protocols"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_SERVICES "/etc/services"
-EOF
-
-
-cat >> confdefs.h <<\EOF
-#define _PATH_BSHELL "/bin/sh"
-EOF
-
-
-for ac_func in vfork
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2395 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-srctop=`cd ${srcdir}/..;pwd`
-
-
-# Now we deal with symlinks &c.
-
-test -d include || mkdir include || \
- { echo "configure: error: Can't create include directory." 1>&2; exit 1; }
-
-test -d include/pthread || mkdir include/pthread || \
- { echo "configure: error: Can't create include/pthread directory." 1>&2; exit 1; }
-
-test -d lib || mkdir lib || \
- { echo "configure: error: Can't create lib directory." 1>&2; exit 1; }
-
-test -d lib/libpthreadutil || mkdir lib/libpthreadutil || \
- { echo "configure: error: Can't create lib/libpthreadutil directory." 1>&2; exit 1; }
-
-test -d bin || mkdir bin || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d bin/finger || mkdir bin/finger || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d tests || mkdir tests || \
- { echo "configure: error: Can't create tests directory." 1>&2; exit 1; }
-
-if test x$syscall = xNONE ; then
- syscall=$name
-fi
-
-links="include/pthread/machdep.h include/pthread/posix.h \
- machdep.c syscall.S"
-targets="../machdep/engine-$name.h ../machdep/posix-$sysincludes.h \
- ../machdep/engine-$name.c ../machdep/syscall-$syscall.S"
-
-# Both these targets are optional. (Autoconf-generated configure scripts
-# will require the existence of link targets, so check before adding them
-# to the list.)
-if test x$sysincludes != xNONE ; then
- links="$links include/sys"
- targets="$targets ../machdep/$sysincludes"
-fi
-
-syscall_file=../machdep/syscall-template-$syscall.S
-if test -r $srcdir/$syscall_file ; then
- links="$links syscall-template.S"
- targets="$targets $syscall_file"
- HAVE_SYSCALL_TEMPLATE=yes
-else
- # This really isn't a fatal problem. In fact, it's expected, initially,
- # for some targets. This is just to persuade people to fix the targets
- # they deal with to provide some sort of template.
- #
- # Eventually this file probably will be required...
- echo "configure: warning: No syscall template file syscall-template-$syscall.S found." 1>&2
- HAVE_SYSCALL_TEMPLATE=no
-fi
-
-
-
-
-if test x$makefile_frag != x ; then
- makefile_frag=${srcdir}/$makefile_frag
-else
- makefile_frag=/dev/null
-fi
-
-
-
-
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
- >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-DEFS=-DHAVE_CONFIG_H
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.10"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
-
-ac_given_srcdir=$srcdir
-
-trap 'rm -fr `echo "config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@CXX@%$CXX%g
-s%@CPP@%$CPP%g
-s%@RANLIB@%$RANLIB%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
-s%@target@%$target%g
-s%@target_alias@%$target_alias%g
-s%@target_cpu@%$target_cpu%g
-s%@target_vendor@%$target_vendor%g
-s%@target_os@%$target_os%g
-s%@build@%$build%g
-s%@build_alias@%$build_alias%g
-s%@build_cpu@%$build_cpu%g
-s%@build_vendor@%$build_vendor%g
-s%@build_os@%$build_os%g
-s%@SYSCALL_EXCEPTIONS@%$SYSCALL_EXCEPTIONS%g
-s%@available_syscalls@%$available_syscalls%g
-s%@missing_syscalls@%$missing_syscalls%g
-s%@srctop@%$srctop%g
-s%@HAVE_SYSCALL_TEMPLATE@%$HAVE_SYSCALL_TEMPLATE%g
-/@makefile_frag@/r $makefile_frag
-s%@makefile_frag@%%g
-
-CEOF
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- # Adjust relative srcdir, etc. for subdirectories.
-
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
- fi
-
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
-fi; done
-rm -f conftest.subs
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"}
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- cp $ac_given_srcdir/$ac_file_in conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
-
-rm -f conftest.tail
-while :
-do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
- echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
-done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
- else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- fi
- rm -f $ac_file
- mv conftest.h $ac_file
- fi
-fi; done
-
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-ac_sources="$targets"
-ac_dests="$links"
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-srcdir=$ac_given_srcdir
-while test -n "$ac_sources"; do
- set $ac_dests; ac_dest=$1; shift; ac_dests=$*
- set $ac_sources; ac_source=$1; shift; ac_sources=$*
-
- echo "linking $srcdir/$ac_source to $ac_dest"
-
- if test ! -r $srcdir/$ac_source; then
- { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
- fi
- rm -f $ac_dest
-
- # Make relative symlinks.
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
- # The dest file is in a subdirectory.
- test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
- ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dest_dir_suffix.
- ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dest_dir_suffix= ac_dots=
- fi
-
- case "$srcdir" in
- [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
- *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
- esac
-
- # Make a symlink if possible; otherwise try a hard link.
- if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
- ln $srcdir/$ac_source $ac_dest; then :
- else
- { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
- fi
-done
-
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/mit-pthreads/config/install-sh b/mit-pthreads/config/install-sh
deleted file mode 100755
index ab74c882e92..00000000000
--- a/mit-pthreads/config/install-sh
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-#
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-tranformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/mit-pthreads/configure b/mit-pthreads/configure
deleted file mode 100755
index ffad2bca3cd..00000000000
--- a/mit-pthreads/configure
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-# This silliness is because Chris wants the autoconf-related files
-# and makefiles not to appear in the top-level directory. Fine by
-# me, I don't much care. This script just needs to invoke the real
-# configure script...
-
-config=`echo $0 | sed -e 's,configure$,config/configure,'`
-
-if test ! -d obj ; then
- mkdir obj
-fi
-
-if test -n "$1" ; then
- sh $config "$@"
-else
- sh $config
-fi
diff --git a/mit-pthreads/gen/GNUmakefile.inc b/mit-pthreads/gen/GNUmakefile.inc
deleted file mode 100755
index a5025860b85..00000000000
--- a/mit-pthreads/gen/GNUmakefile.inc
+++ /dev/null
@@ -1,9 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-VPATH:= ${VPATH}:${srcdir}/gen
-
-SRCS:= ttyname.c directory.c popen.c time.c ctime.c difftime.c syslog.c \
- eprintf.c getpwent.c getpwnamuid.c pwd_internal.c \
- getcwd.c getwd.c isatty.c $(SRCS)
diff --git a/mit-pthreads/gen/Makefile.inc b/mit-pthreads/gen/Makefile.inc
deleted file mode 100644
index 6e2c3d44f43..00000000000
--- a/mit-pthreads/gen/Makefile.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-.PATH: ${srcdir}/gen
-
-SRCS+= ttyname.c isatty.c directory.c popen.c time.c ctime.c difftime.c \
- syslog.c eprintf.c getpwent.c getpwnamuid.c pwd_internal.c
-
-#SRCS+= alarm.c assert.c clock.c crypt.c ctermid.c ctype_.c \
-# disklabel.c err.c errlst.c exec.c fnmatch.c frexp.c \
-# fstab.c fts.c getcap.c getcwd.c getgrent.c getlogin.c getmntinfo.c \
-# getpass.c getpwent.c getsubopt.c getttyent.c getusershell.c glob.c \
-# infinity.c initgroups.c isatty.c isctype.c isinf.c mktemp.c nice.c \
-# nlist.c pause.c psignal.c raise.c \
-# scandir.c setjmperr.c \
-# setmode.c setrgid.c setruid.c siginterrupt.c \
-# siglist.c signal.c sigsetops.c syslog.c \
-# termios.c time.c times.c timezone.c ttyslot.c \
-# ualarm.c unvis.c utime.c valloc.c vis.c
-#
-# gen/regexp sources
-#SRCS+= regerror.c regexp.c regsub.c
-
diff --git a/mit-pthreads/gen/ctime.c b/mit-pthreads/gen/ctime.c
deleted file mode 100644
index 9b38d41e495..00000000000
--- a/mit-pthreads/gen/ctime.c
+++ /dev/null
@@ -1,1315 +0,0 @@
-/*
- * Copyright (c) 1987, 1989 Regents of the University of California.
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Arthur David Olson of the National Cancer Institute.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ctime.c 5.26 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-/*
-** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
-** POSIX-style TZ environment variable handling from Guy Harris
-** (guy@auspex.com).
-*/
-
-/*LINTLIBRARY*/
-#include "config.h"
-#include <pthread.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <time.h>
-#include <tzfile.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#ifndef WILDABBR
-/*
-** Someone might make incorrect use of a time zone abbreviation:
-** 1. They might reference tzname[0] before calling tzset (explicitly
-** or implicitly).
-** 2. They might reference tzname[1] before calling tzset (explicitly
-** or implicitly).
-** 3. They might reference tzname[1] after setting to a time zone
-** in which Daylight Saving Time is never observed.
-** 4. They might reference tzname[0] after setting to a time zone
-** in which Standard Time is never observed.
-** 5. They might reference tm.TM_ZONE after calling offtime.
-** What's best to do in the above cases is open to debate;
-** for now, we just set things up so that in any of the five cases
-** WILDABBR is used. Another possibility: initialize tzname[0] to the
-** string "tzname[0] used before set", and similarly for the other cases.
-** And another: initialize tzname[0] to "ERA", with an explanation in the
-** manual page of what this "time zone abbreviation" means (doing this so
-** that tzname[0] has the "normal" length of three characters).
-*/
-#define WILDABBR " "
-#endif /* !defined WILDABBR */
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif /* !defined TRUE */
-
-static const char GMT[] = "GMT";
-
-struct ttinfo { /* time type information */
- long tt_gmtoff; /* GMT offset in seconds */
- int tt_isdst; /* used to set tm_isdst */
- int tt_abbrind; /* abbreviation list index */
- int tt_ttisstd; /* TRUE if transition is std time */
-};
-
-struct lsinfo { /* leap second information */
- time_t ls_trans; /* transition time */
- long ls_corr; /* correction to apply */
-};
-
-struct state {
- int leapcnt;
- int timecnt;
- int typecnt;
- int charcnt;
- time_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
- struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[(TZ_MAX_CHARS + 1 > sizeof GMT) ?
- TZ_MAX_CHARS + 1 : sizeof GMT];
- struct lsinfo lsis[TZ_MAX_LEAPS];
-};
-
-struct rule {
- int r_type; /* type of rule--see below */
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
- long r_time; /* transition time of rule */
-};
-
-#define JULIAN_DAY 0 /* Jn - Julian day */
-#define DAY_OF_YEAR 1 /* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
-
-/*
-** Prototypes for static functions.
-*/
-
-static int detzcode __P_((const char *));
-static const char * getnum __P_((const char *, int *, int, int));
-static const char * getsecs __P_((const char *, long *));
-static const char * getoffset __P_((const char *, long *));
-static const char * getrule __P_((const char *, struct rule *));
-static const char * getzname __P_((const char *));
-static void gmtload __P_((struct state *));
-static void gmtsub __P_((const time_t *, long, struct tm *));
-static void localsub __P_((const time_t *, long, struct tm *));
-static void normalize __P_((int *, int *, int));
-static void settzname __P_((struct state *));
-static time_t time1 __P_((struct tm *, long));
-static time_t time2 __P_((struct tm *, long, int *));
-static void timesub __P_((const time_t *, long, const struct state *,
- struct tm *));
-static int tmcomp __P_((const struct tm *, const struct tm *));
-static time_t transtime __P_((time_t, int, const struct rule *, long));
-static int tzload __P_((const char *, struct state *));
-static int tzparse __P_((const char *, struct state *, int));
-static void tzset_basic __P_((void));
-static void tzsetwall_basic __P_((void));
-
-static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
-static int lcl_is_set = FALSE;
-static int gmt_is_set = FALSE;
-static struct state lclmem;
-static struct state gmtmem;
-
-#define lclptr (&lclmem)
-#define gmtptr (&gmtmem)
-
-char * tzname[2] = {
- WILDABBR,
- WILDABBR
-};
-
-#ifdef USG_COMPAT
-time_t timezone = 0;
-int daylight = 0;
-#endif /* defined USG_COMPAT */
-
-#ifdef ALTZONE
-time_t altzone = 0;
-#endif /* defined ALTZONE */
-
-static int detzcode(const char * codep)
-{
- int result;
- int i;
-
- result = 0;
- for (i = 0; i < 4; ++i)
- result = (result << 8) | (codep[i] & 0xff);
- return result;
-}
-
-static void settzname(struct state * sp)
-{
- register int i;
-
- tzname[0] = WILDABBR;
- tzname[1] = WILDABBR;
-#ifdef USG_COMPAT
- daylight = 0;
- timezone = 0;
-#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
- altzone = 0;
-#endif /* defined ALTZONE */
- for (i = 0; i < sp->typecnt; ++i) {
- register const struct ttinfo * const ttisp = &sp->ttis[i];
-
- tzname[ttisp->tt_isdst] =
- (char *) &sp->chars[ttisp->tt_abbrind];
-#ifdef USG_COMPAT
- if (ttisp->tt_isdst)
- daylight = 1;
- if (i == 0 || !ttisp->tt_isdst)
- timezone = -(ttisp->tt_gmtoff);
-#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
- if (i == 0 || ttisp->tt_isdst)
- altzone = -(ttisp->tt_gmtoff);
-#endif /* defined ALTZONE */
- }
- /*
- ** And to get the latest zone names into tzname. . .
- */
- for (i = 0; i < sp->timecnt; ++i) {
- register const struct ttinfo * const ttisp =
- &sp->ttis[sp->types[i]];
-
- tzname[ttisp->tt_isdst] =
- (char *) &sp->chars[ttisp->tt_abbrind];
- }
-}
-
-static int tzload(const char * name, struct state * sp)
-{
- register const char * p;
- register int i;
- register int fid;
-
- if (name == NULL && (name = TZDEFAULT) == NULL)
- return -1;
- {
- char fullname[FILENAME_MAX + 1];
-
- if (name[0] == ':')
- ++name;
- if (name[0] != '/') {
- if ((p = TZDIR) == NULL)
- return -1;
- if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
- return -1;
- (void) strcpy(fullname, p);
- (void) strcat(fullname, "/");
- (void) strcat(fullname, name);
- name = fullname;
- }
- if ((fid = open(name, O_RDONLY)) == -1)
- return -1;
- }
- {
- register const struct tzhead * tzhp;
- char buf[sizeof *sp + sizeof *tzhp];
- int ttisstdcnt;
-
- i = read(fid, buf, sizeof buf);
- if (close(fid) != 0 || i < sizeof *tzhp)
- return -1;
- tzhp = (struct tzhead *) buf;
- ttisstdcnt = (int) detzcode(tzhp->tzh_ttisstdcnt);
- sp->leapcnt = (int) detzcode(tzhp->tzh_leapcnt);
- sp->timecnt = (int) detzcode(tzhp->tzh_timecnt);
- sp->typecnt = (int) detzcode(tzhp->tzh_typecnt);
- sp->charcnt = (int) detzcode(tzhp->tzh_charcnt);
- if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
- sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
- sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
- sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
- (ttisstdcnt != sp->typecnt && ttisstdcnt != 0))
- return -1;
- if (i < sizeof *tzhp +
- sp->timecnt * (4 + sizeof (char)) +
- sp->typecnt * (4 + 2 * sizeof (char)) +
- sp->charcnt * sizeof (char) +
- sp->leapcnt * 2 * 4 +
- ttisstdcnt * sizeof (char))
- return -1;
- p = buf + sizeof *tzhp;
- for (i = 0; i < sp->timecnt; ++i) {
- sp->ats[i] = detzcode(p);
- p += 4;
- }
- for (i = 0; i < sp->timecnt; ++i) {
- sp->types[i] = (unsigned char) *p++;
- if (sp->types[i] >= sp->typecnt)
- return -1;
- }
- for (i = 0; i < sp->typecnt; ++i) {
- register struct ttinfo * ttisp;
-
- ttisp = &sp->ttis[i];
- ttisp->tt_gmtoff = detzcode(p);
- p += 4;
- ttisp->tt_isdst = (unsigned char) *p++;
- if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
- return -1;
- ttisp->tt_abbrind = (unsigned char) *p++;
- if (ttisp->tt_abbrind < 0 ||
- ttisp->tt_abbrind > sp->charcnt)
- return -1;
- }
- for (i = 0; i < sp->charcnt; ++i)
- sp->chars[i] = *p++;
- sp->chars[i] = '\0'; /* ensure '\0' at end */
- for (i = 0; i < sp->leapcnt; ++i) {
- register struct lsinfo * lsisp;
-
- lsisp = &sp->lsis[i];
- lsisp->ls_trans = detzcode(p);
- p += 4;
- lsisp->ls_corr = detzcode(p);
- p += 4;
- }
- for (i = 0; i < sp->typecnt; ++i) {
- register struct ttinfo * ttisp;
-
- ttisp = &sp->ttis[i];
- if (ttisstdcnt == 0)
- ttisp->tt_ttisstd = FALSE;
- else {
- ttisp->tt_ttisstd = *p++;
- if (ttisp->tt_ttisstd != TRUE &&
- ttisp->tt_ttisstd != FALSE)
- return -1;
- }
- }
- }
- return 0;
-}
-
-static const int mon_lengths[2][MONSPERYEAR] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
- 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-static const int year_lengths[2] = {
- DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-/*
-** Given a pointer into a time zone string, scan until a character that is not
-** a valid character in a zone name is found. Return a pointer to that
-** character.
-*/
-static const char * getzname(const char * strp)
-{
- register char c;
-
- while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
- c != '+')
- ++strp;
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number from that string.
-** Check that the number is within a specified range; if it is not, return
-** NULL.
-** Otherwise, return a pointer to the first character not part of the number.
-*/
-
-static const char *getnum(const char * strp, int * nump, int min, int max)
-{
- char c;
- int num;
-
- if (strp == NULL || !isdigit(*strp))
- return NULL;
- num = 0;
- while ((c = *strp) != '\0' && isdigit(c)) {
- num = num * 10 + (c - '0');
- if (num > max)
- return NULL; /* illegal value */
- ++strp;
- }
- if (num < min)
- return NULL; /* illegal value */
- *nump = num;
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number of seconds,
-** in hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the number
-** of seconds.
-*/
-static const char * getsecs(const char * strp, long * secsp)
-{
- int num;
-
- strp = getnum(strp, &num, 0, HOURSPERDAY);
- if (strp == NULL)
- return NULL;
- *secsp = num * SECSPERHOUR;
- if (*strp == ':') {
- ++strp;
- strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
- if (strp == NULL)
- return NULL;
- *secsp += num * SECSPERMIN;
- if (*strp == ':') {
- ++strp;
- strp = getnum(strp, &num, 0, SECSPERMIN - 1);
- if (strp == NULL)
- return NULL;
- *secsp += num;
- }
- }
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract an offset, in
-** [+-]hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the time.
-*/
-static const char * getoffset(const char * strp, long * offsetp)
-{
- int neg;
-
- if (*strp == '-') {
- neg = 1;
- ++strp;
- } else if (isdigit(*strp) || *strp++ == '+')
- neg = 0;
- else return NULL; /* illegal offset */
- strp = getsecs(strp, offsetp);
- if (strp == NULL)
- return NULL; /* illegal time */
- if (neg)
- *offsetp = -*offsetp;
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a rule in the form
-** date[/time]. See POSIX section 8 for the format of "date" and "time".
-** If a valid rule is not found, return NULL.
-** Otherwise, return a pointer to the first character not part of the rule.
-*/
-static const char * getrule(const char * strp, struct rule * rulep)
-{
- if (*strp == 'J') {
- /*
- ** Julian day.
- */
- rulep->r_type = JULIAN_DAY;
- ++strp;
- strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
- } else if (*strp == 'M') {
- /*
- ** Month, week, day.
- */
- rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
- ++strp;
- strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_week, 1, 5);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
- } else if (isdigit(*strp)) {
- /*
- ** Day of year.
- */
- rulep->r_type = DAY_OF_YEAR;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
- } else return NULL; /* invalid format */
- if (strp == NULL)
- return NULL;
- if (*strp == '/') {
- /*
- ** Time specified.
- */
- ++strp;
- strp = getsecs(strp, &rulep->r_time);
- } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
- return strp;
-}
-
-/*
-** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the
-** year, a rule, and the offset from GMT at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
-*/
-static time_t transtime(time_t janfirst, int year,
- const struct rule * rulep, long offset)
-{
- register int leapyear;
- register time_t value;
- register int i;
- int d, m1, yy0, yy1, yy2, dow;
-
- leapyear = isleap(year);
- switch (rulep->r_type) {
-
- case JULIAN_DAY:
- /*
- ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
- ** years.
- ** In non-leap years, or if the day number is 59 or less, just
- ** add SECSPERDAY times the day number-1 to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
- if (leapyear && rulep->r_day >= 60)
- value += SECSPERDAY;
- break;
-
- case DAY_OF_YEAR:
- /*
- ** n - day of year.
- ** Just add SECSPERDAY times the day number to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + rulep->r_day * SECSPERDAY;
- break;
-
- case MONTH_NTH_DAY_OF_WEEK:
- /*
- ** Mm.n.d - nth "dth day" of month m.
- */
- value = janfirst;
- for (i = 0; i < rulep->r_mon - 1; ++i)
- value += mon_lengths[leapyear][i] * SECSPERDAY;
-
- /*
- ** Use Zeller's Congruence to get day-of-week of first day of
- ** month.
- */
- m1 = (rulep->r_mon + 9) % 12 + 1;
- yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
- yy1 = yy0 / 100;
- yy2 = yy0 % 100;
- dow = ((26 * m1 - 2) / 10 +
- 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
- if (dow < 0)
- dow += DAYSPERWEEK;
-
- /*
- ** "dow" is the day-of-week of the first day of the month. Get
- ** the day-of-month (zero-origin) of the first "dow" day of the
- ** month.
- */
- d = rulep->r_day - dow;
- if (d < 0)
- d += DAYSPERWEEK;
- for (i = 1; i < rulep->r_week; ++i) {
- if (d + DAYSPERWEEK >=
- mon_lengths[leapyear][rulep->r_mon - 1])
- break;
- d += DAYSPERWEEK;
- }
-
- /*
- ** "d" is the day-of-month (zero-origin) of the day we want.
- */
- value += d * SECSPERDAY;
- break;
- }
-
- /*
- ** "value" is the Epoch-relative time of 00:00:00 GMT on the day in
- ** question. To get the Epoch-relative time of the specified local
- ** time on that day, add the transition time and the current offset
- ** from GMT.
- */
- return value + rulep->r_time + offset;
-}
-
-/*
-** Given a POSIX section 8-style TZ string, fill in the rule tables as
-** appropriate.
-*/
-static int tzparse(const char * name, struct state * sp, int lastditch)
-{
- const char * stdname;
- const char * dstname;
- int stdlen;
- int dstlen;
- long stdoffset;
- long dstoffset;
- register time_t * atp;
- register unsigned char * typep;
- register char * cp;
- register int load_result;
-
- stdname = name;
- if (lastditch) {
- stdlen = strlen(name); /* length of standard zone name */
- name += stdlen;
- if (stdlen >= sizeof sp->chars)
- stdlen = (sizeof sp->chars) - 1;
- } else {
- name = getzname(name);
- stdlen = name - stdname;
- if (stdlen < 3)
- return -1;
- }
- if (*name == '\0')
- return -1;
- else {
- name = getoffset(name, &stdoffset);
- if (name == NULL)
- return -1;
- }
- load_result = tzload(TZDEFRULES, sp);
- if (load_result != 0)
- sp->leapcnt = 0; /* so, we're off a little */
- if (*name != '\0') {
- dstname = name;
- name = getzname(name);
- dstlen = name - dstname; /* length of DST zone name */
- if (dstlen < 3)
- return -1;
- if (*name != '\0' && *name != ',' && *name != ';') {
- name = getoffset(name, &dstoffset);
- if (name == NULL)
- return -1;
- } else dstoffset = stdoffset - SECSPERHOUR;
- if (*name == ',' || *name == ';') {
- struct rule start;
- struct rule end;
- register int year;
- register time_t janfirst;
- time_t starttime;
- time_t endtime;
-
- ++name;
- if ((name = getrule(name, &start)) == NULL)
- return -1;
- if (*name++ != ',')
- return -1;
- if ((name = getrule(name, &end)) == NULL)
- return -1;
- if (*name != '\0')
- return -1;
- sp->typecnt = 2; /* standard time and DST */
- /*
- ** Two transitions per year, from EPOCH_YEAR to 2037.
- */
- sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
- if (sp->timecnt > TZ_MAX_TIMES)
- return -1;
- sp->ttis[0].tt_gmtoff = -dstoffset;
- sp->ttis[0].tt_isdst = 1;
- sp->ttis[0].tt_abbrind = stdlen + 1;
- sp->ttis[1].tt_gmtoff = -stdoffset;
- sp->ttis[1].tt_isdst = 0;
- sp->ttis[1].tt_abbrind = 0;
- atp = sp->ats;
- typep = sp->types;
- janfirst = 0;
- for (year = EPOCH_YEAR; year <= 2037; ++year) {
- starttime = transtime(janfirst, year, &start,
- stdoffset);
- endtime = transtime(janfirst, year, &end,
- dstoffset);
- if (starttime > endtime) {
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- } else {
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- }
- janfirst +=
- year_lengths[isleap(year)] * SECSPERDAY;
- }
- } else {
- int sawstd;
- int sawdst;
- long stdfix;
- long dstfix;
- long oldfix;
- int isdst;
- register int i;
-
- if (*name != '\0')
- return -1;
- if (load_result != 0)
- return -1;
- /*
- ** Compute the difference between the real and
- ** prototype standard and summer time offsets
- ** from GMT, and put the real standard and summer
- ** time offsets into the rules in place of the
- ** prototype offsets.
- */
- sawstd = FALSE;
- sawdst = FALSE;
- stdfix = 0;
- dstfix = 0;
- for (i = 0; i < sp->typecnt; ++i) {
- if (sp->ttis[i].tt_isdst) {
- oldfix = dstfix;
- dstfix =
- sp->ttis[i].tt_gmtoff + dstoffset;
- if (sawdst && (oldfix != dstfix))
- return -1;
- sp->ttis[i].tt_gmtoff = -dstoffset;
- sp->ttis[i].tt_abbrind = stdlen + 1;
- sawdst = TRUE;
- } else {
- oldfix = stdfix;
- stdfix =
- sp->ttis[i].tt_gmtoff + stdoffset;
- if (sawstd && (oldfix != stdfix))
- return -1;
- sp->ttis[i].tt_gmtoff = -stdoffset;
- sp->ttis[i].tt_abbrind = 0;
- sawstd = TRUE;
- }
- }
- /*
- ** Make sure we have both standard and summer time.
- */
- if (!sawdst || !sawstd)
- return -1;
- /*
- ** Now correct the transition times by shifting
- ** them by the difference between the real and
- ** prototype offsets. Note that this difference
- ** can be different in standard and summer time;
- ** the prototype probably has a 1-hour difference
- ** between standard and summer time, but a different
- ** difference can be specified in TZ.
- */
- isdst = FALSE; /* we start in standard time */
- for (i = 0; i < sp->timecnt; ++i) {
- register const struct ttinfo * ttisp;
-
- /*
- ** If summer time is in effect, and the
- ** transition time was not specified as
- ** standard time, add the summer time
- ** offset to the transition time;
- ** otherwise, add the standard time offset
- ** to the transition time.
- */
- ttisp = &sp->ttis[sp->types[i]];
- sp->ats[i] +=
- (isdst && !ttisp->tt_ttisstd) ?
- dstfix : stdfix;
- isdst = ttisp->tt_isdst;
- }
- }
- } else {
- dstlen = 0;
- sp->typecnt = 1; /* only standard time */
- sp->timecnt = 0;
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = 0;
- sp->ttis[0].tt_abbrind = 0;
- }
- sp->charcnt = stdlen + 1;
- if (dstlen != 0)
- sp->charcnt += dstlen + 1;
- if (sp->charcnt > sizeof sp->chars)
- return -1;
- cp = sp->chars;
- (void) strncpy(cp, stdname, stdlen);
- cp += stdlen;
- *cp++ = '\0';
- if (dstlen != 0) {
- (void) strncpy(cp, dstname, dstlen);
- *(cp + dstlen) = '\0';
- }
- return 0;
-}
-
-static void gmtload(struct state * sp)
-{
- if (tzload(GMT, sp) != 0)
- (void) tzparse(GMT, sp, TRUE);
-}
-
-static void tzset_basic()
-{
- const char * name;
- if ((name = getenv("TZ")) == NULL) {
- tzsetwall_basic();
- return;
- }
-
- if (*name == '\0') {
- /*
- ** User wants it fast rather than right.
- */
- lclptr->leapcnt = 0; /* so, we're off a little */
- lclptr->timecnt = 0;
- lclptr->ttis[0].tt_gmtoff = 0;
- lclptr->ttis[0].tt_abbrind = 0;
- (void) strcpy(lclptr->chars, GMT);
- } else {
- if (tzload(name, lclptr) != 0)
- if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
- (void) gmtload(lclptr);
- }
- lcl_is_set = TRUE;
- settzname(lclptr);
-}
-
-void tzset()
-{
- pthread_mutex_lock(&lcl_mutex);
- tzset_basic();
- pthread_mutex_unlock(&lcl_mutex);
-}
-
-static void tzsetwall_basic()
-{
- if (tzload((char *) NULL, lclptr) != 0)
- gmtload(lclptr);
- settzname(lclptr);
- lcl_is_set = TRUE;
-}
-
-void tzsetwall()
-{
- pthread_mutex_lock(&lcl_mutex);
- tzsetwall_basic();
- pthread_mutex_unlock(&lcl_mutex);
-}
-
-/*
-** The easy way to behave "as if no library function calls" localtime
-** is to not call it--so we drop its guts into "localsub", which can be
-** freely called. (And no, the PANS doesn't require the above behavior--
-** but it *is* desirable.)
-**
-** The unused offset argument is for the benefit of mktime variants.
-*/
-
-static void localsub(const time_t * timep, long offset, struct tm * tmp)
-{
- const struct ttinfo * ttisp;
- const time_t t = *timep;
- struct state * sp;
- int i;
-
- if (!lcl_is_set)
- tzset_basic();
- sp = lclptr;
- if (sp->timecnt == 0 || t < sp->ats[0]) {
- i = 0;
- while (sp->ttis[i].tt_isdst)
- if (++i >= sp->typecnt) {
- i = 0;
- break;
- }
- } else {
- for (i = 1; i < sp->timecnt; ++i)
- if (t < sp->ats[i])
- break;
- i = sp->types[i - 1];
- }
- ttisp = &sp->ttis[i];
- /*
- ** To get (wrong) behavior that's compatible with System V Release 2.0
- ** you'd replace the statement below with
- ** t += ttisp->tt_gmtoff;
- ** timesub(&t, 0L, sp, tmp);
- */
- timesub(&t, ttisp->tt_gmtoff, sp, tmp);
- tzname[tmp->tm_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
-#ifdef BSD_TM
- tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
-#endif
- tmp->tm_isdst = ttisp->tt_isdst;
-
- pthread_mutex_unlock(&lcl_mutex);
-}
-
-struct tm * localtime_r(const time_t * timep, struct tm * tm)
-{
- pthread_mutex_lock(&lcl_mutex);
- localsub(timep, 0L, tm);
- pthread_mutex_unlock(&lcl_mutex);
- return(tm);
-}
-
-struct tm * localtime(const time_t * timep)
-{
- static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t localtime_key = -1;
- struct tm * tm;
-
- pthread_mutex_lock(&localtime_mutex);
- if (localtime_key < 0) {
- if (pthread_key_create(&localtime_key, free) < 0) {
- pthread_mutex_unlock(&localtime_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&localtime_mutex);
- if ((tm = pthread_getspecific(localtime_key)) == NULL) {
- if ((tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
- return(NULL);
- }
- pthread_setspecific(localtime_key, tm);
- }
-
- pthread_mutex_lock(&lcl_mutex);
- localsub(timep, 0L, tm);
- pthread_mutex_unlock(&lcl_mutex);
- return tm;
-}
-
-
-/*
- * gmtsub is to gmtime as localsub is to localtime.
- *
- * Once set there is no need to lock the gmt_mutex to view gmtptr
- */
-static void gmtsub(const time_t * timep, long offset, struct tm * tmp)
-{
- pthread_mutex_lock(&gmt_mutex);
- if (gmt_is_set == FALSE) {
- gmt_is_set = TRUE;
- gmtload(gmtptr);
- }
- pthread_mutex_unlock(&gmt_mutex);
-
- timesub(timep, offset, gmtptr, tmp);
- /*
- ** Could get fancy here and deliver something such as
- ** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,
- ** but this is no time for a treasure hunt.
- */
-#ifdef BSD_TM
- if (offset != 0) {
- tmp->tm_zone = WILDABBR;
- } else {
- tmp->tm_zone = gmtptr->chars;
- }
-#endif
-}
-
-struct tm * gmtime_r(const time_t * timep, struct tm * tm)
-{
- gmtsub(timep, 0L, tm);
- return(tm);
-}
-
-struct tm * gmtime(const time_t * timep)
-{
- static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t gmtime_key = -1;
- struct tm * tm;
-
- pthread_mutex_lock(&gmtime_mutex);
- if (gmtime_key < 0) {
- if (pthread_key_create(&gmtime_key, free) < 0) {
- pthread_mutex_unlock(&gmtime_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&gmtime_mutex);
- if ((tm = pthread_getspecific(gmtime_key)) == NULL) {
- if ((tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
- return(NULL);
- }
- pthread_setspecific(gmtime_key, tm);
- }
-
- gmtsub(timep, 0L, tm);
- return(tm);
-}
-
-static void timesub(const time_t * timep, long offset,
- const struct state * sp, struct tm * tmp)
-{
- register const struct lsinfo * lp;
- register long days;
- register long rem;
- register int y;
- register int yleap;
- register const int * ip;
- register long corr;
- register int hit;
- register int i;
-
- corr = 0;
- hit = FALSE;
- i = sp->leapcnt;
- while (--i >= 0) {
- lp = &sp->lsis[i];
- if (*timep >= lp->ls_trans) {
- if (*timep == lp->ls_trans)
- hit = ((i == 0 && lp->ls_corr > 0) ||
- lp->ls_corr > sp->lsis[i - 1].ls_corr);
- corr = lp->ls_corr;
- break;
- }
- }
- days = *timep / SECSPERDAY;
- rem = *timep % SECSPERDAY;
-#ifdef mc68k
- if (*timep == 0x80000000) {
- /*
- ** A 3B1 muffs the division on the most negative number.
- */
- days = -24855;
- rem = -11648;
- }
-#endif /* mc68k */
- rem += (offset - corr);
- while (rem < 0) {
- rem += SECSPERDAY;
- --days;
- }
- while (rem >= SECSPERDAY) {
- rem -= SECSPERDAY;
- ++days;
- }
- tmp->tm_hour = (int) (rem / SECSPERHOUR);
- rem = rem % SECSPERHOUR;
- tmp->tm_min = (int) (rem / SECSPERMIN);
- tmp->tm_sec = (int) (rem % SECSPERMIN);
- if (hit)
- /*
- ** A positive leap second requires a special
- ** representation. This uses "... ??:59:60".
- */
- ++(tmp->tm_sec);
- tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
- if (tmp->tm_wday < 0)
- tmp->tm_wday += DAYSPERWEEK;
- y = EPOCH_YEAR;
- if (days >= 0)
- for ( ; ; ) {
- yleap = isleap(y);
- if (days < (long) year_lengths[yleap])
- break;
- ++y;
- days = days - (long) year_lengths[yleap];
- }
- else do {
- --y;
- yleap = isleap(y);
- days = days + (long) year_lengths[yleap];
- } while (days < 0);
- tmp->tm_year = y - TM_YEAR_BASE;
- tmp->tm_yday = (int) days;
- ip = mon_lengths[yleap];
- for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
- days = days - (long) ip[tmp->tm_mon];
- tmp->tm_mday = (int) (days + 1);
- tmp->tm_isdst = 0;
-#ifdef BSD_TM
- tmp->tm_gmtoff = offset;
-#endif
-}
-
-/*
- * A la X3J11
- *
- * Made thread safe by using thread specific data
- */
-char * asctime_r(const struct tm * timeptr, char * result)
-{
- static const char wday_name[DAYSPERWEEK][3] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- };
- static const char mon_name[MONSPERYEAR][3] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- (void) sprintf(result, "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n",
- wday_name[timeptr->tm_wday],
- mon_name[timeptr->tm_mon],
- timeptr->tm_mday, timeptr->tm_hour,
- timeptr->tm_min, timeptr->tm_sec,
- TM_YEAR_BASE + timeptr->tm_year);
- return(result);
-}
-
-char * asctime(const struct tm * timeptr)
-{
- static pthread_mutex_t asctime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t asctime_key = -1;
- char * result;
-
- pthread_mutex_lock(&asctime_mutex);
- if (asctime_key < 0) {
- if (pthread_key_create(&asctime_key, free) < 0) {
- pthread_mutex_unlock(&asctime_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&asctime_mutex);
- if ((result = pthread_getspecific(asctime_key)) == NULL) {
- if ((result = malloc(26)) == NULL) {
- return(NULL);
- }
- pthread_setspecific(asctime_key, result);
- }
-
- return(asctime_r(timeptr, result));
-}
-
-char * ctime_r(const time_t * timep, char * buf)
-{
- struct tm tm;
- return asctime_r(localtime_r(timep, &tm), buf);
-}
-
-char * ctime(const time_t * timep)
-{
- struct tm tm;
- return asctime(localtime_r(timep, &tm));
-}
-
-/*
-** Adapted from code provided by Robert Elz, who writes:
-** The "best" way to do mktime I think is based on an idea of Bob
-** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
-** It does a binary search of the time_t space. Since time_t's are
-** just 32 bits, its a max of 32 iterations (even at 64 bits it
-** would still be very reasonable).
-*/
-static void normalize(int * tensptr,int * unitsptr, int base)
-{
- if (*unitsptr >= base) {
- *tensptr += *unitsptr / base;
- *unitsptr %= base;
- } else if (*unitsptr < 0) {
- --*tensptr;
- *unitsptr += base;
- if (*unitsptr < 0) {
- *tensptr -= 1 + (-*unitsptr) / base;
- *unitsptr = base - (-*unitsptr) % base;
- }
- }
-}
-
-static int tmcomp(const struct tm * atmp, const struct tm * btmp)
-{
- register int result;
-
- if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
- (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
- (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
- (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
- (result = (atmp->tm_min - btmp->tm_min)) == 0)
- result = atmp->tm_sec - btmp->tm_sec;
- return result;
-}
-
-static time_t time2(struct tm * tmp, long offset, int * okayp)
-{
- register const struct state * sp;
- register int dir;
- register int bits;
- register int i, j ;
- register int saved_seconds;
- time_t newt;
- time_t t;
- struct tm yourtm, mytm;
-
- *okayp = FALSE;
- yourtm = *tmp;
- if (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0)
- normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN);
- normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR);
- normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY);
- normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR);
- while (yourtm.tm_mday <= 0) {
- --yourtm.tm_year;
- yourtm.tm_mday +=
- year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];
- }
- for ( ; ; ) {
- i = mon_lengths[isleap(yourtm.tm_year +
- TM_YEAR_BASE)][yourtm.tm_mon];
- if (yourtm.tm_mday <= i)
- break;
- yourtm.tm_mday -= i;
- if (++yourtm.tm_mon >= MONSPERYEAR) {
- yourtm.tm_mon = 0;
- ++yourtm.tm_year;
- }
- }
- saved_seconds = yourtm.tm_sec;
- yourtm.tm_sec = 0;
- /*
- ** Calculate the number of magnitude bits in a time_t
- ** (this works regardless of whether time_t is
- ** signed or unsigned, though lint complains if unsigned).
- */
- for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
- ;
- /*
- ** If time_t is signed, then 0 is the median value,
- ** if time_t is unsigned, then 1 << bits is median.
- */
- t = (t < 0) ? 0 : ((time_t) 1 << bits);
- for ( ; ; ) {
- localsub(&t, offset, &mytm);
- dir = tmcomp(&mytm, &yourtm);
- if (dir != 0) {
- if (bits-- < 0)
- return NOTOK;
- if (bits < 0)
- --t;
- else if (dir > 0)
- t -= (time_t) 1 << bits;
- else t += (time_t) 1 << bits;
- continue;
- }
- if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
- break;
- /*
- ** Right time, wrong type.
- ** Hunt for right time, right type.
- ** It's okay to guess wrong since the guess
- ** gets checked.
- */
- sp = lclptr;
- for (i = 0; i < sp->typecnt; ++i) {
- if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
- continue;
- for (j = 0; j < sp->typecnt; ++j) {
- if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
- continue;
- newt = t + sp->ttis[j].tt_gmtoff -
- sp->ttis[i].tt_gmtoff;
- localsub(&newt, offset, &mytm);
- if (tmcomp(&mytm, &yourtm) != 0)
- continue;
- if (mytm.tm_isdst != yourtm.tm_isdst)
- continue;
- /*
- ** We have a match.
- */
- t = newt;
- goto label;
- }
- }
- return NOTOK;
- }
-label:
- t += saved_seconds;
- localsub(&t, offset, tmp);
- *okayp = TRUE;
- return t;
-}
-
-static time_t time1(struct tm * tmp, long offset)
-{
- const struct state * sp;
- int samei, otheri, okay;
- time_t t;
-
- if (tmp->tm_isdst > 1)
- tmp->tm_isdst = 1;
- t = time2(tmp, offset, &okay);
- if (okay || tmp->tm_isdst < 0)
- return t;
- /*
- ** We're supposed to assume that somebody took a time of one type
- ** and did some math on it that yielded a "struct tm" that's bad.
- ** We try to divine the type they started from and adjust to the
- ** type they need.
- */
- sp = lclptr;
- for (samei = 0; samei < sp->typecnt; ++samei) {
- if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
- continue;
- for (otheri = 0; otheri < sp->typecnt; ++otheri) {
- if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
- continue;
- tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
- tmp->tm_isdst = !tmp->tm_isdst;
- t = time2(tmp, offset, &okay);
- if (okay)
- return t;
- tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
- tmp->tm_isdst = !tmp->tm_isdst;
- }
- }
- return NOTOK;
-}
-
-time_t mktime(struct tm * tmp)
-{
- time_t mktime_return_value;
-
- pthread_mutex_lock(&lcl_mutex);
- if (lcl_is_set == FALSE) {
- tzset_basic();
- }
- mktime_return_value = time1(tmp, 0L);
- pthread_mutex_unlock(&lcl_mutex);
- return(mktime_return_value);
-}
diff --git a/mit-pthreads/gen/difftime.c b/mit-pthreads/gen/difftime.c
deleted file mode 100644
index cddd896e04a..00000000000
--- a/mit-pthreads/gen/difftime.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)difftime.c 5.2 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-
-double
-difftime(time1, time0)
- time_t time1, time0;
-{
- return(time1 - time0);
-}
diff --git a/mit-pthreads/gen/directory.c b/mit-pthreads/gen/directory.c
deleted file mode 100644
index d189280fc1f..00000000000
--- a/mit-pthreads/gen/directory.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)closedir.c 5.9 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * One of these structures is malloced to describe the current directory
- * position each time telldir is called. It records the current magic
- * cookie returned by getdirentries and the offset within the buffer
- * associated with that return value.
- */
-struct ddloc {
- struct ddloc *loc_next;/* next structure in list */
- long loc_index; /* key associated with structure */
- long loc_seek; /* magic cookie returned by getdirentries */
- long loc_loc; /* offset of entry in buffer */
-};
-
-static long dd_loccnt = 0; /* Index of entry for sequential telldir's */
-
-#include <errno.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-
-
-/*
- * close a directory.
- */
-int closedir(DIR * dirp)
-{
- void *ptr, *nextptr;
- int fd;
-
- pthread_mutex_lock (dirp->dd_lock);
- fd = dirp->dd_fd;
- dirp->dd_fd = -1;
- dirp->dd_loc = 0;
- for (ptr = (void *)dirp->dd_ddloc; ptr; ptr = nextptr) {
- nextptr = (void *)(((struct ddloc *)ptr)->loc_next);
- free(ptr);
- }
- for (ptr = (void *)dirp->dd_dp; ptr; ptr = nextptr) {
- nextptr = (void *)(((struct __dirent *)ptr)->next);
- free(ptr);
- }
- free((void *)dirp->dd_buf);
- free (dirp->dd_lock);
- free((void *)dirp);
- return(machdep_sys_close(fd));
-}
-
-/*
- * open a directory.
- */
-DIR * opendir(const char * name)
-{
- DIR *dirp;
- int fd;
-
- if ((fd = machdep_sys_open(name, 0)) < 0)
- return NULL;
- if (machdep_sys_fcntl(fd, F_SETFD, 1) < 0 ||
- (dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
- machdep_sys_close (fd);
- return NULL;
- }
- dirp->dd_lock = (pthread_mutex_t*) malloc (sizeof (pthread_mutex_t));
- pthread_mutex_init (dirp->dd_lock, 0);
- /*
- * If CLSIZE is an exact multiple of DIRBLKSIZ, use a CLSIZE
- * buffer that it cluster boundary aligned.
- * Hopefully this can be a big win someday by allowing page trades
- * to user space to be done by getdirentries()
- */
-#ifndef CLSIZE
-#define CLSIZE 1
-#endif
- if ((CLSIZE % DIRBLKSIZ) == 0) {
- dirp->dd_buf = malloc(CLSIZE);
- dirp->dd_len = CLSIZE;
- } else {
- dirp->dd_buf = malloc(DIRBLKSIZ);
- dirp->dd_len = DIRBLKSIZ;
- }
- if (dirp->dd_buf == NULL) {
- machdep_sys_close (fd);
- free((void *)dirp);
- return NULL;
- }
-
- dirp->dd_ddloc = NULL;
- dirp->dd_dp = NULL;
- dirp->dd_seek = 0;
- dirp->dd_loc = 0;
- dirp->dd_fd = fd;
- return(dirp);
-}
-
-/*
- * The real work in gettint the next entry in a directory.
- * Return
- * NULL on End of directory
- * &ERR on Error
- * dp on valid directory;
- */
-static struct dirent ERR;
-static struct dirent * readdir_basic(DIR * dirp)
-{
- register struct dirent *dp;
-
- for (;;) {
- if (dirp->dd_loc == 0) {
- dirp->dd_size = machdep_sys_getdirentries(dirp->dd_fd,
- dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
- if (dirp->dd_size < 0)
- return(&ERR);
- if (dirp->dd_size == 0)
- return(NULL);
- }
- if (dirp->dd_loc >= dirp->dd_size) {
- dirp->dd_loc = 0;
- continue;
- }
- dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
- if ((long)dp & 03) /* bogus pointer check */
- return(&ERR);
- if (dp->d_reclen <= 0 ||
- dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
- return(&ERR);
- dirp->dd_loc += dp->d_reclen;
- if (dp->d_ino == 0)
- continue;
- return(dp);
- }
-}
-
-/*
- * POSIX.1 version of getting the next entry in a directory.
- */
-struct dirent * readdir(DIR * dirp)
-{
- register struct dirent * rp;
- struct __dirent * my__dp;
- pthread_t self;
-
- pthread_mutex_lock (dirp->dd_lock);
-
- self = pthread_self();
- /* Allocate space and return */
- for (my__dp = dirp->dd_dp; my__dp; my__dp = my__dp->next) {
- if (pthread_equal(my__dp->owner, self)) {
- break;
- }
- }
- if (my__dp == NULL) {
- if (my__dp = (struct __dirent *)(malloc(sizeof(struct __dirent)))) {
- my__dp->next = dirp->dd_dp;
- dirp->dd_dp = my__dp;
- my__dp->owner = self;
- } else {
- pthread_mutex_unlock (dirp->dd_lock);
- return(NULL);
- }
- }
- if (rp = readdir_basic(dirp)) {
- if (rp != &ERR) {
- memcpy(& (my__dp->data), rp, sizeof(struct dirent));
- rp = & (my__dp->data);
- } else {
- rp = NULL;
- }
- }
- pthread_mutex_unlock (dirp->dd_lock);
- return(rp);
-}
-
-/*
- * POSIX.4a version of getting the next entry in a directory.
- */
-int readdir_r(DIR * dirp, struct dirent * entry, struct dirent ** result)
-{
- register struct dirent * rp;
- int ret;
-
- pthread_mutex_lock (dirp->dd_lock);
- rp = readdir_basic(dirp);
- if (rp != &ERR) {
- if (rp) {
- memcpy(entry, rp, sizeof(struct dirent));
- *result = entry;
- ret = 0;
- } else {
- *result = NULL;
- ret = 0;
- }
- } else {
- /* Should get it from errno */
- ret = EBADF;
- }
- pthread_mutex_unlock (dirp->dd_lock);
- return(ret);
-}
-
-void rewinddir(DIR * dirp)
-{
- pthread_mutex_lock (dirp->dd_lock);
- (void)machdep_sys_lseek(dirp->dd_fd, 0, 0);
- dirp->dd_seek = 0;
- dirp->dd_loc = 0;
- pthread_mutex_unlock (dirp->dd_lock);
-}
-
-/*
- * Seek to an entry in a directory.
- * _seekdir is in telldir.c so that it can share opaque data structures.
- *
- * Use the POSIX reentrant safe readdir_r to simplify varifying POSIX
- * thread-safe compliance.
- */
-void seekdir(DIR * dirp, long loc)
-{
- register struct ddloc ** prevlp;
- register struct ddloc * lp;
- struct dirent * dp;
- struct dirent de;
-
- pthread_mutex_lock (dirp->dd_lock);
- prevlp = (struct ddloc **)&(dirp->dd_ddloc);
- lp = *prevlp;
- while (lp != NULL) {
- if (lp->loc_index == loc)
- break;
- prevlp = &lp->loc_next;
- lp = lp->loc_next;
- }
- if (lp) {
- if (lp->loc_seek != dirp->dd_seek) {
- if (machdep_sys_lseek(dirp->dd_fd, lp->loc_seek, 0) < 0) {
- *prevlp = lp->loc_next;
- pthread_mutex_unlock (dirp->dd_lock);
- return;
- }
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
- if (readdir_r(dirp, &de, &dp)) {
- *prevlp = lp->loc_next;
- break;
- }
- }
- }
- }
- pthread_mutex_unlock (dirp->dd_lock);
-}
-
-/*
- * return a pointer into a directory
- */
-long telldir(DIR *dirp)
-{
- struct ddloc *lp, **fakeout;
- int ret;
-
- pthread_mutex_lock (dirp->dd_lock);
- if (lp = (struct ddloc *)malloc(sizeof(struct ddloc))) {
- lp->loc_index = dd_loccnt++;
- lp->loc_seek = dirp->dd_seek;
- lp->loc_loc = dirp->dd_loc;
- lp->loc_next = dirp->dd_ddloc;
-
- /* Compiler won't let us change anything pointed to by db directly */
- /* So we fake to the left and do it anyway */
- /* Wonder if the compile optomizes it to the correct solution */
- fakeout = (struct ddloc **)&(dirp->dd_ddloc);
- *fakeout = lp;
-
- ret = lp->loc_index;
- } else {
- ret = -1;
- }
- pthread_mutex_unlock (dirp->dd_lock);
- return(ret);
-}
-
diff --git a/mit-pthreads/gen/eprintf.c b/mit-pthreads/gen/eprintf.c
deleted file mode 100644
index bcc65757bd4..00000000000
--- a/mit-pthreads/gen/eprintf.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This function is a replacement for the version in libgcc.a. This
- is needed because typically libgcc.a won't have been compiled
- against the threads library, so its references to "stderr" will
- come out wrong. */
-
-#include <stdio.h>
-
-void __eprintf (const char *fmt, const char *expr, int line, const char *file)
-{
- /* Considering the very special circumstances where this function
- would be called, perhaps we might want to disable the thread
- scheduler and break any existing locks on stderr? Well, maybe if
- we could be sure that stderr was in a useable state... */
- fprintf (stderr, fmt, expr, line, file);
- fflush (stderr);
-
- abort ();
-}
diff --git a/mit-pthreads/gen/getcwd.c b/mit-pthreads/gen/getcwd.c
deleted file mode 100644
index 9c1b089f26e..00000000000
--- a/mit-pthreads/gen/getcwd.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 1989, 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getcwd.c 5.11 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define ISDOT(dp) \
- (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
- dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
-
-
-/* Only use reentrant safe routines to simplify varifying POSIX thread-safe
- * compliance. (mevans).
- */
-
-char *
-getcwd(pt, size)
- char *pt;
- size_t size;
-{
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
- struct dirent *dp;
- struct dirent de;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
- int save_errno;
- char *ept, *eup, *up;
- int namelen;
-
- /*
- * If no buffer specified by the user, allocate one as necessary.
- * If a buffer is specified, the size has to be non-zero. The path
- * is built from the end of the buffer backwards.
- */
- if (pt) {
- ptsize = 0;
- if (!size) {
- errno = EINVAL;
- return((char *)NULL);
- }
- ept = pt + size;
- } else {
- if (!(pt = (char *)malloc(ptsize = 1024 - 4)))
- return((char *)NULL);
- ept = pt + ptsize;
- }
- bpt = ept - 1;
- *bpt = '\0';
-
- /*
- * Allocate bytes (1024 - malloc space) for the string of "../"'s.
- * Should always be enough (it's 340 levels). If it's not, allocate
- * as necessary. Special * case the first stat, it's ".", not "..".
- */
- if (!(up = (char *)malloc(upsize = 1024 - 4)))
- goto err;
- eup = up + MAXPATHLEN;
- bup = up;
- up[0] = '.';
- up[1] = '\0';
-
- /* Save root values, so know when to stop. */
- if (stat("/", &s))
- goto err;
- root_dev = s.st_dev;
- root_ino = s.st_ino;
-
- SET_ERRNO(0);
-
- for (first = 1;; first = 0) {
- /* Stat the current level. */
- if (lstat(up, &s))
- goto err;
-
- /* Save current node values. */
- ino = s.st_ino;
- dev = s.st_dev;
-
- /* Check for reaching root. */
- if (root_dev == dev && root_ino == ino) {
- *--bpt = '/';
- /*
- * It's unclear that it's a requirement to copy the
- * path to the beginning of the buffer, but it's always
- * been that way and stuff would probably break.
- */
- /* XXX was bcopy */
- (void)memcpy(pt, bpt, ept - bpt);
- free(up);
- return(pt);
- }
-
- /*
- * Build pointer to the parent directory, allocating memory
- * as necessary. Max length is 3 for "../", the largest
- * possible component name, plus a trailing NULL.
- */
- if (bup + 3 + MAXNAMLEN + 1 >= eup) {
- if (!(up = (char *)realloc(up, upsize *= 2)))
- goto err;
- eup = up + upsize;
- }
- *bup++ = '.';
- *bup++ = '.';
- *bup = '\0';
-
- /* Open and stat parent directory. */
- /* XXX opendir() returns kernel fd's instead of
- pthread fd's for some odd reason, so we must
- break the abstraction boundry here as well or
- fix everything in opendir et al. SNL */
- if (!(dir = opendir(up)) ||
- machdep_sys_fstat(dirfd(dir), &s))
- goto err;
-
- /* Add trailing slash for next directory. */
- *bup++ = '/';
-
- /*
- * If it's a mount point, have to stat each element because
- * the inode number in the directory is for the entry in the
- * parent directory, not the inode number of the mounted file.
- */
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
- if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
- if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (ISDOT(dp))
- continue;
- memcpy(bup, dp->d_name, strlen(dp->d_name) + 1);
-
- /* Save the first error for later. */
- if (lstat(up, &s)) {
- if (!save_errno)
- save_errno = errno;
- SET_ERRNO(0);
- continue;
- }
- if (s.st_dev == dev && s.st_ino == ino)
- break;
- }
-
- /*
- * Check for length of the current name, preceding slash,
- * leading slash.
- */
- namelen = strlen(dp->d_name);
- if (bpt - pt <= namelen + (first ? 1 : 2)) {
- size_t len, off;
-
- if (!ptsize) {
- SET_ERRNO(ERANGE);
- goto err;
- }
- off = bpt - pt;
- len = ept - bpt;
- if (!(pt = (char *)realloc(pt, ptsize *= 2)))
- goto err;
- bpt = pt + off;
- ept = pt + ptsize;
- /* XXX was bcopy */
- (void)memcpy(ept - len, bpt, len);
- bpt = ept - len;
- }
- if (!first)
- *--bpt = '/';
- bpt -= namelen;
- memcpy(bpt, dp->d_name, namelen);
- (void)closedir(dir);
-
- /* Truncate any file name. */
- *bup = '\0';
- }
-
-notfound:
- /*
- * If readdir set errno, use it, not any saved error; otherwise,
- * didn't find the current directory in its parent directory, set
- * errno to ENOENT.
- */
- if (!errno) {
- if (!save_errno)
- save_errno = ENOENT;
- SET_ERRNO(save_errno);
- }
- /* FALLTHROUGH */
-err:
- if (ptsize)
- free(pt);
- free(up);
- return((char *)NULL);
-}
diff --git a/mit-pthreads/gen/getpwent.c b/mit-pthreads/gen/getpwent.c
deleted file mode 100644
index 7bcb2cbd610..00000000000
--- a/mit-pthreads/gen/getpwent.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 1984 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getpwent.c 5.2 (Berkeley) 3/9/86";
-#endif
-
-#include <pthread.h>
-#include <stdio.h>
-#include <pwd.h>
-#include "pwd_internal.h"
-
-void
-setpwent()
-{
- pwf_context_t *_data;
-
- _data = _pw_get_data();
-
- if (_data) {
- if (_data->pwf == NULL)
- _data->pwf = fopen(_data->pw_file, "r");
- else
- rewind(_data->pwf);
- }
-}
-
-void
-endpwent()
-{
- pwf_context_t *_data;
-
- _data = _pw_get_data();
-
- if (_data) {
- if (_data->pwf != NULL) {
- fclose(_data->pwf);
- _data->pwf = NULL;
- }
-#ifdef DBM_PWD_SUPPORT
- if (_data->pw_db != (DBM *)0) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- _data->pw_stayopen = 0;
- }
-#endif /* DBM_PWD_SUPPORT */
- }
-}
-
-static char *
-pwskip(p)
- char *p;
-{
- while (*p && *p != ':' && *p != '\n')
- ++p;
- if (*p)
- *p++ = 0;
- return(p);
-}
-
-struct passwd *
-getpwent()
-{
- pwf_context_t *_data;
- char *p;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
-
- if (_data->pwf == NULL) {
- if ((_data->pwf = fopen(_data->pw_file, "r" )) == NULL)
- return(0);
- }
- p = fgets(_data->line, BUFSIZ, _data->pwf);
- if (p == NULL)
- return(0);
- _data->passwd.pw_name = p;
- p = pwskip(p);
- _data->passwd.pw_passwd = p;
- p = pwskip(p);
- _data->passwd.pw_uid = atoi(p);
- p = pwskip(p);
- _data->passwd.pw_gid = atoi(p);
- p = pwskip(p);
- _data->passwd.pw_gecos = p;
- p = pwskip(p);
- _data->passwd.pw_dir = p;
- p = pwskip(p);
- _data->passwd.pw_shell = p;
- while (*p && *p != '\n')
- p++;
- *p = '\0';
- return(&_data->passwd);
-}
-
-void
-setpwfile(file)
- char *file;
-{
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (_data)
- _data->pw_file = file;
-}
diff --git a/mit-pthreads/gen/getpwnamuid.c b/mit-pthreads/gen/getpwnamuid.c
deleted file mode 100644
index 0e87081b7a9..00000000000
--- a/mit-pthreads/gen/getpwnamuid.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getpwnamuid.c 5.3 (Berkeley) 12/21/87";
-#endif
-
-#include <stdio.h>
-#include <pwd.h>
-#include <sys/file.h>
-#include "pwd_internal.h"
-
-/*
- * The following are shared with getpwent.c
- */
-
-#ifdef DBM_PWD_SUPPORT
-static struct passwd *
-fetchpw(key)
- datum key;
-{
- char *cp, *tp;
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
- if (key.dptr == 0)
- return ((struct passwd *)NULL);
- key = dbm_fetch(_data->pw_db, key);
- if (key.dptr == 0)
- return ((struct passwd *)NULL);
- cp = key.dptr;
- tp = _data->line;
-
-#define EXPAND(e) _data->passwd.e = tp; while (*tp++ = *cp++);
- EXPAND(pw_name);
- EXPAND(pw_passwd);
- memcpy((char *)&_data->passwd.pw_uid, cp, sizeof (int));
- cp += sizeof (int);
- memcpy((char *)&_data->passwd.pw_gid, cp, sizeof (int));
- cp += sizeof (int);
- EXPAND(pw_gecos);
- EXPAND(pw_dir);
- EXPAND(pw_shell);
- return (&_data->passwd);
-}
-#endif /* DBM_PWD_SUPPORT */
-
-struct passwd *
-getpwnam(nam)
- const char *nam;
-{
-#ifdef DBM_PWD_SUPPORT
- datum key;
-#endif
- struct passwd *pw, *getpwent();
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
-
-#ifdef DBM_PWD_SUPPORT
- if (_data->pw_db == (DBM *)0 &&
- (_data->pw_db = dbm_open(_data->pw_file, O_RDONLY)) == (DBM *)0) {
- oldcode:
-#endif
- setpwent();
- while ((pw = getpwent()) && strcmp(nam, pw->pw_name))
- ;
- if (!_data->pw_stayopen)
- endpwent();
- return (pw);
-#ifdef DBM_PWD_SUPPORT
- }
- if (flock(dbm_dirfno(_data->pw_db), LOCK_SH) < 0) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- goto oldcode;
- }
- key.dptr = nam;
- key.dsize = strlen(nam);
- pw = fetchpw(key);
- (void) flock(dbm_dirfno(_data->pw_db), LOCK_UN);
- if (!_data->pw_stayopen) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- }
- return (pw);
-#endif
-}
-
-struct passwd *
-getpwuid(uid)
- uid_t uid;
-{
-#ifdef DBM_PWD_SUPPORT
- datum key;
-#endif
- struct passwd *pw, *getpwent();
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
-#ifdef DBM_PWD_SUPPORT
- if (_data->pw_db == (DBM *)0 &&
- (_data->pw_db = dbm_open(_data->pw_file, O_RDONLY)) == (DBM *)0) {
- oldcode:
-#endif
- setpwent();
- while ((pw = getpwent()) && pw->pw_uid != uid)
- ;
- if (!_data->pw_stayopen)
- endpwent();
- return (pw);
-#ifdef DBM_PWD_SUPPORT
- }
- if (flock(dbm_dirfno(_data->pw_db), LOCK_SH) < 0) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- goto oldcode;
- }
- key.dptr = (char *) &uid;
- key.dsize = sizeof uid;
- pw = fetchpw(key);
- (void) flock(dbm_dirfno(_data->pw_db), LOCK_UN);
- if (!_data->pw_stayopen) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- }
- return (pw);
-#endif
-}
diff --git a/mit-pthreads/gen/getwd.c b/mit-pthreads/gen/getwd.c
deleted file mode 100644
index 7fdceda0f45..00000000000
--- a/mit-pthreads/gen/getwd.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getwd.c 5.1 (Berkeley) 2/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-char *
-getwd(buf)
- char *buf;
-{
- char *p;
- char *strerror();
-
- if (p = getcwd(buf, MAXPATHLEN))
- return(p);
- (void)strcpy(buf, strerror(errno));
- return((char *)NULL);
-}
diff --git a/mit-pthreads/gen/isatty.c b/mit-pthreads/gen/isatty.c
deleted file mode 100644
index a22f13015d9..00000000000
--- a/mit-pthreads/gen/isatty.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)isatty.c 5.6 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#ifdef sunos4
-#include <sys/termio.h>
-#else
-#include <termios.h>
-#endif
-#include <unistd.h>
-
-/*
- * If TIOCGETA is not defined try TCGETATTR
- * If TCGETATTR is not defined try TCGETA
- * If that doesn't work try getting it from termio.h
- */
-#ifndef TIOCGETA
-#ifdef TCGETATTR
-#define TIOCGETA TCGETATTR
-#else
-#ifndef TCGETA
-#include <termio.h>
-#endif
-#ifndef TIOCGETA
-#define TIOCGETA TCGETA
-#endif
-#endif
-#endif
-
-/* fd is the real fd to pass to the kernel */
-int isatty_basic(int fd)
-{
-#ifdef sunos4
- struct termio t;
-#else /* !sunos4 */
- struct termios t;
-#endif /* sunos4 */
- return (machdep_sys_ioctl(fd,
-#ifdef sunos4
- TCGETA,
-#else /* !sunos4 */
- TIOCGETA,
-#endif /* sunos4 */
- &t) ? 0 : 1);
-}
-
-int isatty(int fd)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = isatty_basic(fd_table[fd]->fd.i);
- fd_unlock(fd, FD_READ);
- } else {
- /* Return 0 or 1 */
- ret = 0;
- }
- return(ret);
-}
-
diff --git a/mit-pthreads/gen/popen.c b/mit-pthreads/gen/popen.c
deleted file mode 100644
index c15fbdce1fe..00000000000
--- a/mit-pthreads/gen/popen.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-static pid_t *pids = NULL;
-static int pids_size = 0;
-static int pids_top = 0;
-static pthread_mutex_t pids_lock = PTHREAD_MUTEX_INITIALIZER;
-
-FILE *popen(const char *cmd, const char *mode)
-{
- int fds[2], parent_fd, child_fd, child_target, new_size, i;
- pid_t pid, *new_pids;
-
- /* Verify the mode. */
- if ((*mode != 'r' && *mode != 'w') || mode[1] != 0)
- return NULL;
-
- /* Generate fds, and choose the parent and child fds. */
- if (pipe(fds) < 0)
- return NULL;
- parent_fd = (*mode == 'r') ? fds[0] : fds[1];
- child_fd = (*mode == 'r') ? fds[1] : fds[0];
-
- /* Ensure that there is space in the pid table. */
- pthread_mutex_lock(&pids_lock);
- if (pids_size <= parent_fd) {
- new_size = parent_fd + 1;
- if ((new_pids = malloc(new_size * sizeof(pid_t))) == NULL) {
- pthread_mutex_unlock(&pids_lock);
- close(parent_fd);
- close(child_fd);
- return NULL;
- }
- if (pids) {
- memcpy(new_pids, pids, pids_size * sizeof(pid_t));
- free(pids);
- }
- while (pids_size < new_size)
- new_pids[pids_size++] = -1;
- pids = new_pids;
- }
- pthread_mutex_unlock(&pids_lock);
-
- /* Fork off a child process. */
- switch (pid = fork()) {
- case -1: /* Failed to fork. */
- close(parent_fd);
- close(child_fd);
- return NULL;
- break;
- case 0: /* Child */
- /*
- * Set the child fd to stdout or stdin as appropriate,
- * and close the parent fd.
- */
- child_target = (*mode == 'r') ? STDOUT_FILENO : STDIN_FILENO;
- if (child_fd != child_target) {
- dup2(child_fd, child_target);
- close(child_fd);
- }
- close(parent_fd);
-
- /* Close all parent fds from previous popens(). */
- for (i = 0; i < pids_top; i++) {
- if (pids[i] != -1)
- close(i);
- }
-
- execl("/bin/sh", "sh", "-c", cmd, NULL);
- exit(1);
- default:
- break;
- }
-
- /* Record the parent fd in the pids table. */
- pthread_mutex_lock(&pids_lock);
- pids[parent_fd] = pid;
- if (pids_top < parent_fd + 1)
- pids_top = parent_fd + 1;
- pthread_mutex_unlock(&pids_lock);
-
- /* Close the child fd and return a stdio buffer for the parent fd. */
- close(child_fd);
- return fdopen(parent_fd, mode);
-}
-
-int pclose(fp)
- FILE *fp;
-{
- pid_t pid, result;
- int fd, pstat;
-
- fd = fileno(fp);
- pthread_mutex_lock(&pids_lock);
- /* Make sure this is a popened file. */
- if ((pids_top <= fd) || ((pid = pids[fd]) == -1)) {
- pthread_mutex_unlock(&pids_lock);
- return -1;
- }
- pids[fd] = -1;
- while (pids_top > 0 && pids[pids_top - 1] == -1)
- pids_top--;
- pthread_mutex_unlock(&pids_lock);
-
- fclose(fp);
-
- /* Wait for the subprocess to quit. */
- return (((result = waitpid(pid, &pstat, 0)) == -1) ? -1 : pstat);
-}
-
diff --git a/mit-pthreads/gen/pwd_internal.c b/mit-pthreads/gen/pwd_internal.c
deleted file mode 100644
index b0ebc27b5c6..00000000000
--- a/mit-pthreads/gen/pwd_internal.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== pwd_internal.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Thread-safe password hacking functions.
- *
- * 1.00 95/02/08 snl
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <pwd.h>
-#include <unistd.h>
-#include "pwd_internal.h"
-
-static pthread_once_t __pw_init = PTHREAD_ONCE_INIT;
-static pthread_key_t __pw_key;
-
-void
-_pw_null_cleanup(void *junkola)
-{
- pwf_context_t *x = (pwf_context_t *)junkola;
-
- if (x) {
- if (x->pwf) {
- fclose(x->pwf);
- x->pwf = 0;
- }
-#ifdef DBM_PWD_SUPPORT
- if (x->pw_db) {
- dbm_close(x->pw_db);
- x->pw_db = 0;
- }
-#endif /* DBM_PWD_SUPPORT */
- free((void *)x);
- }
-}
-
-void
-_pw_create_key()
-{
- if (pthread_key_create(&__pw_key, _pw_null_cleanup)) {
- PANIC();
- }
-}
-
-pwf_context_t *
-_pw_get_data()
-{
- pwf_context_t *_data;
-
- pthread_once(&__pw_init, _pw_create_key);
- _data = (pwf_context_t *)pthread_getspecific(__pw_key);
- if (!_data) {
- _data = (pwf_context_t *)malloc(sizeof(pwf_context_t));
- if (_data) {
- _data->pwf = 0;
- _data->line[0] = '\0';
- _data->pw_stayopen = 0;
- _data->pw_file = "/etc/passwd";
-#ifdef DBM_PWD_SUPPORT
- _data->pw_db = 0;
-#endif /* DBM_PWD_SUPPORT */
- pthread_setspecific(__pw_key, (void *)_data);
- }
- }
- return _data;
-}
diff --git a/mit-pthreads/gen/pwd_internal.h b/mit-pthreads/gen/pwd_internal.h
deleted file mode 100644
index 10fdab6cc4e..00000000000
--- a/mit-pthreads/gen/pwd_internal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _PWD_INTERNAL_H_
-#define _PWD_INTERNAL_H_
-
-#if 0 /* Turn this off for now until we suck in ndbm or use gdbm -- SNL */
-#ifndef DBM_PWD_SUPPORT
-#if !defined(__alpha) && !defined(linux) && !defined(hpux)
-#define DBM_PWD_SUPPORT 1
-#endif /* !alpha && !linux && !hpux */
-#endif /* !DBM_PWD_SUPPORT */
-#endif
-
-#ifdef DBM_PWD_SUPPORT
-#include <ndbm.h>
-#endif /* DBM_PWD_SUPPORT */
-
-typedef struct pwf_context {
- FILE *pwf;
- char line[BUFSIZ+1];
- struct passwd passwd;
- int pw_stayopen;
- char *pw_file;
-#ifdef DBM_PWD_SUPPORT
- DBM *pw_db;
-#endif /* DBM_PWD_SUPPORT */
-} pwf_context_t;
-
-pwf_context_t *_pw_get_data __P_((void));
-
-#endif /* _PWD_INTERNAL_H_ */
diff --git a/mit-pthreads/gen/syslog.c b/mit-pthreads/gen/syslog.c
deleted file mode 100644
index e49795ecb69..00000000000
--- a/mit-pthreads/gen/syslog.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 1983, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of California at Berkeley. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)syslog.c 5.14 (Berkeley) 5/20/88";
-#endif /* LIBC_SCCS and not lint */
-
-
-/*
- * SYSLOG -- print message on log file
- *
- * This routine looks a lot like printf, except that it
- * outputs to the log file instead of the standard output.
- * Also:
- * adds a timestamp,
- * prints the module name in front of the message,
- * has some other formatting types (or will sometime),
- * adds a newline on the end of the message.
- *
- * The output of this routine is intended to be read by /etc/syslogd.
- *
- * Author: Eric Allman
- * Modified to use UNIX domain IPC by Ralph Campbell
- * Modified for pthreads and made more POSIX-compliant by Greg Hudson
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
-#include <syslog.h>
-
-int socket();
-char *strerror(int); /* For systems that don't prototype it */
-
-#define MAXLINE 1024 /* max message size */
-
-#define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
- /* XXX should be in <syslog.h> */
-#define IMPORTANT LOG_ERR
-
-static void basic_init(void);
-
-static char _log_name[] = "/dev/log";
-static char ctty[] = "/dev/console";
-
-static int LogFile = -1; /* fd for log */
-static int LogStat = 0; /* status bits, set by openlog() */
-static char *LogTag = "syslog"; /* string to tag the entry with */
-static int LogMask = 0xff; /* mask of priorities to be logged */
-static int LogFacility = LOG_USER; /* default facility code */
-
-static pthread_mutex_t basic_init_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
-
-static void basic_init()
-{
- pthread_mutex_lock(&basic_init_lock);
- if (LogFile < 0)
- openlog(LogTag, LogStat | LOG_NDELAY, 0);
- pthread_mutex_unlock(&basic_init_lock);
-}
-
-void syslog(int pri, char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- vsyslog(pri, fmt, args);
- va_end(args);
-}
-
-void vsyslog(int pri, char *fmt, va_list args)
-{
- char buf[MAXLINE + 1], outline[MAXLINE + 1];
- register char *b, *f, *o;
- register int c;
- time_t now;
- int olderrno = errno, fd;
-
- /* Do a basic initialization if user didn't call openlog(). */
- if (LogFile < 0)
- basic_init();
-
- /* see if we should just throw out this message */
- if ((unsigned) PRIFAC(pri) >= LOG_NFACILITIES ||
- (LOG_MASK(pri & LOG_PRIMASK) & LogMask) == 0 ||
- (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
- return;
-
- /* set default facility if none specified */
- if ((pri & LOG_FACMASK) == 0)
- pri |= LogFacility;
-
- /* build the message */
- o = outline;
- (void)sprintf(o, "<%d>", pri);
- o += strlen(o);
- time(&now);
- (void)sprintf(o, "%.15s ", ctime(&now) + 4);
- o += strlen(o);
- if (LogTag) {
- strcpy(o, LogTag);
- o += strlen(o);
- }
- if (LogStat & LOG_PID) {
- (void)sprintf(o, "[%d]", getpid());
- o += strlen(o);
- }
- if (LogTag) {
- strcpy(o, ": ");
- o += 2;
- }
-
- b = buf;
- f = fmt;
- while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
- char *strerror();
-
- if (c != '%') {
- *b++ = c;
- continue;
- }
- if ((c = *f++) != 'm') {
- *b++ = '%';
- *b++ = c;
- continue;
- }
- strcpy(b, strerror(olderrno));
- b += strlen(b);
- }
- *b++ = '\n';
- *b = '\0';
- vsprintf(o, buf, args);
- c = strlen(outline);
- if (c > MAXLINE)
- c = MAXLINE;
-
- /* output the message to the local logger */
- if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
- return;
- if (!(LogStat & LOG_CONS))
- return;
-
- /* output the message to the console */
- fd = open(ctty, O_WRONLY);
- alarm(0);
- strcat(o, "\r");
- o = strchr(outline, '>') + 1;
- write(fd, o, c + 1 - (o - outline));
- close(fd);
-}
-
-/*
- * OPENLOG -- open system log
- */
-
-void openlog(char *ident, int logstat, int logfac)
-{
- int flags;
-
- if (ident != NULL)
- LogTag = ident;
- LogStat = logstat;
- if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
- LogFacility = logfac;
- if (LogFile >= 0)
- return;
- SyslogAddr.sa_family = AF_UNIX;
- strncpy(SyslogAddr.sa_data, _log_name, sizeof SyslogAddr.sa_data);
- if (LogStat & LOG_NDELAY) {
- LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
- flags = fcntl(LogFile, F_GETFD);
- fcntl(LogFile, F_SETFD, flags & O_NONBLOCK);
- }
-}
-
-/*
- * CLOSELOG -- close the system log
- */
-
-void closelog()
-{
- (void) close(LogFile);
- LogFile = -1;
-}
-
-/*
- * SETLOGMASK -- set the log mask level
- */
-int setlogmask(int pmask)
-{
- int omask;
-
- omask = LogMask;
- if (pmask != 0)
- LogMask = pmask;
- return (omask);
-}
diff --git a/mit-pthreads/gen/time.c b/mit-pthreads/gen/time.c
deleted file mode 100644
index 82eec7edc1e..00000000000
--- a/mit-pthreads/gen/time.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)time.c 5.6 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-time_t time(time_t * t)
-{
- struct timeval tt;
-
- if (gettimeofday(&tt, (struct timezone *)0) < 0)
- return(-1);
- if (t)
- *t = tt.tv_sec;
- return(tt.tv_sec);
-}
diff --git a/mit-pthreads/gen/ttyname.c b/mit-pthreads/gen/ttyname.c
deleted file mode 100644
index b7a04485f79..00000000000
--- a/mit-pthreads/gen/ttyname.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ttyname.c 5.10 (Berkeley) 5/6/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include "config.h"
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-
-static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_key_t ttyname_key;
-static int ttyname_init = 0;
-extern void free();
-
-char * __ttyname_r_basic(int fd, char * buf, size_t len)
-{
- register struct dirent *dirp;
- register DIR *dp;
- struct stat dsb;
- struct stat sb;
- char * rval;
- int minlen;
-
- rval = NULL;
-
- /* Must be a terminal. */
- if (! isatty_basic(fd))
- return(rval);
- /* Must be a character device. */
- if (machdep_sys_fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
- return(rval);
- /* Must have enough room */
- if (len <= sizeof(_PATH_PTY))
- return(rval);
-
- if ((dp = opendir(_PATH_PTY)) != NULL) {
- memcpy(buf, _PATH_PTY, sizeof(_PATH_PTY));
- for (rval = NULL; dirp = readdir(dp);) {
- if (dirp->d_fileno != sb.st_ino)
- continue;
- minlen = (len - (sizeof(_PATH_PTY) - 1)) < (dirp->d_namlen + 1) ?
- (len - (sizeof(_PATH_PTY) - 1)) : (dirp->d_namlen + 1);
- memcpy (buf + sizeof(_PATH_PTY) - 1, dirp->d_name, minlen);
- if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev ||
- sb.st_ino != dsb.st_ino)
- continue;
- rval = buf;
- break;
- }
- (void)closedir(dp);
- }
- return(rval);
-}
-
-char * __ttyname_basic(int fd)
-{
- char *buf;
-
- pthread_mutex_lock (&ttyname_lock);
- if (ttyname_init == 0) {
- if (pthread_key_create(&ttyname_key, free)) {
- pthread_mutex_unlock (&ttyname_lock);
- return(NULL);
- }
- ttyname_init = 1;
- }
- pthread_mutex_unlock (&ttyname_lock);
-
- /* Must have thread specific data field to put data */
- if ((buf = pthread_getspecific(ttyname_key)) == NULL) {
- if (buf = malloc(sizeof(_PATH_PTY) + MAXNAMLEN)) {
- if (pthread_setspecific(ttyname_key, buf) != OK) {
- free(buf);
- return(NULL);
- }
- } else {
- return(NULL);
- }
- }
- return(__ttyname_r_basic(fd, buf, sizeof(_PATH_PTY) + MAXNAMLEN));
-}
-
-char * ttyname_r(int fd, char * buf, size_t len)
-{
- char * ret;
-
- if (fd_lock(fd, FD_READ) == OK) {
- ret = __ttyname_r_basic(fd_table[fd]->fd.i, buf, len);
- fd_unlock(fd, FD_READ);
- } else {
- ret = NULL;
- }
- return(ret);
-}
-
-char * ttyname(int fd)
-{
- char * ret;
-
- if (fd_lock(fd, FD_READ) == OK) {
- ret = __ttyname_basic(fd_table[fd]->fd.i);
- fd_unlock(fd, FD_READ);
- } else {
- ret = NULL;
- }
- return(ret);
-}
-
-
diff --git a/mit-pthreads/include/Makefile.inc b/mit-pthreads/include/Makefile.inc
deleted file mode 100644
index b7fe59d5f0d..00000000000
--- a/mit-pthreads/include/Makefile.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-# from: @(#)Makefile 5.45.1.1 (Berkeley) 5/6/91
-
-# Doing a make install builds /usr/include/pthread
-#
-# The ``rm -rf''s used below are safe because rm doesn't follow symbolic
-# links.
-
-
-FILES= cond.h copyright.h fd.h fd_pipe.h kernel.h mutex.h posix.h \
- pthread.h pthread_attr.h queue.h util.h
-
-# Machine dependent header file
-MFILE= ${.CURDIR}/arch/${MACHINE}/machdep.h
-
-realinstall:
- if [ ! -d ${DESTDIR}/usr/include/pthread ]; then \
- mkdir ${DESTDIR}/usr/include/pthread; \
- fi
- @echo installing ${FILES}
- @-for i in ${FILES}; do \
- cmp -s $$i ${DESTDIR}/usr/include/pthread/$$i || \
- install -c -m 644 $$i ${DESTDIR}/usr/include/$$i; \
- done
- cmp -s ${MFILE} ${DESTDIR}/usr/include/pthread/machdep.h || \
- install -c -m 644 ${MFILE} ${DESTDIR}/usr/include/pthread/machdep.h
- rm -rf ${DESTDIR}/usr/include/pthread.h
- ln -s /usr/include/pthread/pthread.h ${DESTDIR}/usr/include/pthread.h
- @chown -R ${BINOWN}:${BINGRP} ${DESTDIR}/usr/include/pthread
- @chmod -R a-w ${DESTDIR}/usr/include/pthread
-
diff --git a/mit-pthreads/include/arpa/inet.h b/mit-pthreads/include/arpa/inet.h
deleted file mode 100755
index d6ad76f4eb5..00000000000
--- a/mit-pthreads/include/arpa/inet.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 1983, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)inet.h 5.7 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _INET_H_
-#define _INET_H_
-
-/* External definitions for functions in inet(3) */
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <pthread/types.h>
-
-__BEGIN_DECLS
-
-pthread_ipaddr_type inet_addr __P_((const char *));
-int inet_aton __P_((const char *, struct in_addr *));
-pthread_ipaddr_type inet_lnaof __P_((struct in_addr));
-struct in_addr inet_makeaddr __P_((pthread_ipaddr_type,
- pthread_ipaddr_type));
-pthread_ipaddr_type inet_netof __P_((struct in_addr));
-pthread_ipaddr_type inet_network __P_((const char *));
-char * inet_ntoa __P_((struct in_addr));
-char * inet_ntoa_r __P_((struct in_addr in, char *buf,
- int bufsize));
-
-__END_DECLS
-
-#endif /* !_INET_H_ */
diff --git a/mit-pthreads/include/arpa/nameser.h b/mit-pthreads/include/arpa/nameser.h
deleted file mode 100755
index 350d67538bd..00000000000
--- a/mit-pthreads/include/arpa/nameser.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 1983, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)nameser.h 8.2 (Berkeley) 2/16/94
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#ifndef _NAMESER_H_
-#define _NAMESER_H_
-
-#include <endian.h>
-#include <sys/types.h>
-#include <pthread/types.h>
-
-/*
- * Define constants based on rfc883
- */
-#define PACKETSZ 512 /* maximum packet size */
-#define MAXDNAME 256 /* maximum domain name */
-#define MAXCDNAME 255 /* maximum compressed domain name */
-#define MAXLABEL 63 /* maximum length of domain label */
- /* Number of bytes of fixed size data in query structure */
-#define QFIXEDSZ 4
- /* number of bytes of fixed size data in resource record */
-#define RRFIXEDSZ 10
-
-/*
- * Internet nameserver port number
- */
-#define NAMESERVER_PORT 53
-
-/*
- * Currently defined opcodes
- */
-#define QUERY 0x0 /* standard query */
-#define IQUERY 0x1 /* inverse query */
-#define STATUS 0x2 /* nameserver status query */
-/*#define xxx 0x3*/ /* 0x3 reserved */
- /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
-#define UPDATEA 0x9 /* add resource record */
-#define UPDATED 0xa /* delete a specific resource record */
-#define UPDATEDA 0xb /* delete all named resource record */
-#define UPDATEM 0xc /* modify a specific resource record */
-#define UPDATEMA 0xd /* modify all named resource record */
-
-#define ZONEINIT 0xe /* initial zone transfer */
-#define ZONEREF 0xf /* incremental zone referesh */
-
-/*
- * Currently defined response codes
- */
-#define NOERROR 0 /* no error */
-#define FORMERR 1 /* format error */
-#define SERVFAIL 2 /* server failure */
-#define NXDOMAIN 3 /* non existent domain */
-#define NOTIMP 4 /* not implemented */
-#define REFUSED 5 /* query refused */
- /* non standard */
-#define NOCHANGE 0xf /* update failed to change db */
-
-/*
- * Type values for resources and queries
- */
-#define T_A 1 /* host address */
-#define T_NS 2 /* authoritative server */
-#define T_MD 3 /* mail destination */
-#define T_MF 4 /* mail forwarder */
-#define T_CNAME 5 /* connonical name */
-#define T_SOA 6 /* start of authority zone */
-#define T_MB 7 /* mailbox domain name */
-#define T_MG 8 /* mail group member */
-#define T_MR 9 /* mail rename name */
-#define T_NULL 10 /* null resource record */
-#define T_WKS 11 /* well known service */
-#define T_PTR 12 /* domain name pointer */
-#define T_HINFO 13 /* host information */
-#define T_MINFO 14 /* mailbox information */
-#define T_MX 15 /* mail routing information */
-#define T_TXT 16 /* text strings */
-#define T_RP 17 /* responsible person */
-#define T_AFSDB 18 /* AFS cell database */
-#define T_NSAP 22 /* NSAP address */
-#define T_NSAP_PTR 23 /* reverse lookup for NSAP */
- /* non standard */
-#define T_UINFO 100 /* user (finger) information */
-#define T_UID 101 /* user ID */
-#define T_GID 102 /* group ID */
-#define T_UNSPEC 103 /* Unspecified format (binary data) */
- /* Query type values which do not appear in resource records */
-#define T_AXFR 252 /* transfer zone of authority */
-#define T_MAILB 253 /* transfer mailbox records */
-#define T_MAILA 254 /* transfer mail agent records */
-#define T_ANY 255 /* wildcard match */
-
-/*
- * Values for class field
- */
-
-#define C_IN 1 /* the arpa internet */
-#define C_CHAOS 3 /* for chaos net (MIT) */
-#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */
- /* Query class values which do not appear in resource records */
-#define C_ANY 255 /* wildcard match */
-
-/*
- * Status return codes for T_UNSPEC conversion routines
- */
-#define CONV_SUCCESS 0
-#define CONV_OVERFLOW -1
-#define CONV_BADFMT -2
-#define CONV_BADCKSUM -3
-#define CONV_BADBUFLEN -4
-
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != BIG_ENDIAN \
- && BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != PDP_ENDIAN)
- /* you must determine what the correct bit order is for
- * your compiler - the next line is an intentional error
- * which will force your compiles to bomb until you fix
- * the above macros.
- */
- #error "Undefined or invalid BYTE_ORDER";
-#endif
-
-/*
- * Structure for query header. The order of the fields is machine- and
- * compiler-dependent, depending on the byte/bit order and the layout
- * of bit fields. We use bit fields only in int variables, as this
- * is all ANSI requires. This requires a somewhat confusing rearrangement.
- */
-
-typedef struct {
- pthread_ipport_type id; /* query identification number */
-#if BYTE_ORDER == BIG_ENDIAN
- /* fields in third byte */
- u_int qr:1; /* response flag */
- u_int opcode:4; /* purpose of message */
- u_int aa:1; /* authoritive answer */
- u_int tc:1; /* truncated message */
- u_int rd:1; /* recursion desired */
- /* fields in fourth byte */
- u_int ra:1; /* recursion available */
- u_int pr:1; /* primary server required (non standard) */
- u_int unused:2; /* unused bits */
- u_int rcode:4; /* response code */
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
- /* fields in third byte */
- u_int rd:1; /* recursion desired */
- u_int tc:1; /* truncated message */
- u_int aa:1; /* authoritive answer */
- u_int opcode:4; /* purpose of message */
- u_int qr:1; /* response flag */
- /* fields in fourth byte */
- u_int rcode:4; /* response code */
- u_int unused:2; /* unused bits */
- u_int pr:1; /* primary server required (non standard) */
- u_int ra:1; /* recursion available */
-#endif
- /* remaining bytes */
- pthread_ipport_type qdcount; /* number of question entries */
- pthread_ipport_type ancount; /* number of answer entries */
- pthread_ipport_type nscount; /* number of authority entries */
- pthread_ipport_type arcount; /* number of resource entries */
-} HEADER;
-
-/*
- * Defines for handling compressed domain names
- */
-#define INDIR_MASK 0xc0
-
-/*
- * Structure for passing resource records around.
- */
-struct rrec {
- pthread_ipport_type r_zone; /* zone number */
- pthread_ipport_type r_class; /* class number */
- pthread_ipport_type r_type; /* type number */
- pthread_ipaddr_type r_ttl; /* time to live */
- int r_size; /* size of data area */
- char * r_data; /* pointer to data */
-};
-
-extern pthread_ipport_type _getshort();
-extern pthread_ipaddr_type _getlong();
-
-/*
- * Inline versions of get/put short/long. Pointer is advanced.
- * We also assume that a "pthread_ipport_type" holds 2 "chars"
- * and that a "pthread_ipaddr_type" holds 4 "chars".
- *
- * These macros demonstrate the property of C whereby it can be
- * portable or it can be elegant but never both.
- */
-#define GETSHORT(s, cp) { \
- register u_char *t_cp = (u_char *)(cp); \
- (s) = ((pthread_ipport_type)t_cp[0] << 8) | (pthread_ipport_type)t_cp[1]; \
- (cp) += 2; \
-}
-
-#define GETLONG(l, cp) { \
- register u_char *t_cp = (u_char *)(cp); \
- (l) = (((pthread_ipaddr_type)t_cp[0]) << 24) \
- | (((pthread_ipaddr_type)t_cp[1]) << 16) \
- | (((pthread_ipaddr_type)t_cp[2]) << 8) \
- | (((pthread_ipaddr_type)t_cp[3])); \
- (cp) += 4; \
-}
-
-#define PUTSHORT(s, cp) { \
- register pthread_ipport_type t_s = (pthread_ipport_type)(s); \
- register u_char *t_cp = (u_char *)(cp); \
- *t_cp++ = t_s >> 8; \
- *t_cp = t_s; \
- (cp) += 2; \
-}
-
-/*
- * Warning: PUTLONG --no-longer-- destroys its first argument. if you
- * were depending on this "feature", you will lose.
- */
-#define PUTLONG(l, cp) { \
- register pthread_ipaddr_type t_l = (pthread_ipaddr_type)(l); \
- register u_char *t_cp = (u_char *)(cp); \
- *t_cp++ = t_l >> 24; \
- *t_cp++ = t_l >> 16; \
- *t_cp++ = t_l >> 8; \
- *t_cp = t_l; \
- (cp) += 4; \
-}
-
-#endif /* !_NAMESER_H_ */
diff --git a/mit-pthreads/include/dirent.h b/mit-pthreads/include/dirent.h
deleted file mode 100644
index c3e86cb9da1..00000000000
--- a/mit-pthreads/include/dirent.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _DIRENT_H_
-#define _DIRENT_H_
-
-#include <sys/dirent.h>
-#include <pthread.h>
-
-struct __dirent {
- struct __dirent * next;
- struct dirent data;
- pthread_t owner;
-};
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-/* structure describing an open directory. */
-typedef struct _dirdesc {
- struct __dirent * dd_dp; /* Linked list of struct __dirent pointer */
- int dd_fd; /* file descriptor associated with directory */
- long dd_loc; /* offset in current buffer */
- long dd_size; /* amount of data returned by getdirentries */
- char * dd_buf; /* data buffer */
- int dd_len; /* size of data buffer */
- long dd_seek; /* magic cookie returned by getdirentries */
- void * dd_ddloc; /* Linked list of ddloc structs for telldir/seekdir */
- pthread_mutex_t *dd_lock; /* Lock for open directory structure */
-} DIR;
-
-#define dirfd(dirp) ((dirp)->dd_fd)
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef KERNEL
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-DIR * opendir __P_((const char *));
-struct dirent * readdir __P_((DIR *));
-int readdir_r __P_((DIR *, struct dirent *, struct dirent **));
-void rewinddir __P_((DIR *));
-int closedir __P_((DIR *));
-#ifndef _POSIX_SOURCE
-long telldir __P_((DIR *));
-void seekdir __P_((DIR *, long));
-
-/*
-int scandir __P_((const char *, struct dirent ***,
- int (*)(struct dirent *),
- int (*)(const void *, const void *)));
-int alphasort __P_((const void *, const void *));
-int getdirentries __P_((int, char *, int, long *));
-*/
-#endif /* not POSIX */
-
-__END_DECLS
-
-#endif /* !KERNEL */
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/include/endian.h b/mit-pthreads/include/endian.h
deleted file mode 100644
index 8fb947dbd33..00000000000
--- a/mit-pthreads/include/endian.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 1983, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)nameser.h 8.2 (Berkeley) 2/16/94
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#ifndef _ENDIAN_H_
-#define _ENDIAN_H_
-
-#ifndef BYTE_ORDER
-#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
-#define __LITTLE_ENDIAN 1234
-#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
-#define __BIG_ENDIAN 4321
-#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
-#define __PDP_ENDIAN 3412
-
-#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
- defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
- defined(__alpha__) || defined(__alpha)
-#define BYTE_ORDER LITTLE_ENDIAN
-#define __BYTE_ORDER LITTLE_ENDIAN
-#endif
-
-#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
- defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
- defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || \
- defined(apollo) || defined(hp9000) || defined(hp9000s300) || \
- defined(hp9000s800) || \
- defined (BIT_ZERO_ON_LEFT)
-#define BYTE_ORDER BIG_ENDIAN
-#define __BYTE_ORDER BIG_ENDIAN
-#endif
-#endif /* BYTE_ORDER */
-
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != BIG_ENDIAN \
- && BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != PDP_ENDIAN)
- /* you must determine what the correct bit order is for
- * your compiler - the next line is an intentional error
- * which will force your compiles to bomb until you fix
- * the above macros.
- */
- #error "Undefined or invalid BYTE_ORDER";
-#endif
-
-#endif /* !_ENDIAN_H */
diff --git a/mit-pthreads/include/errno.h b/mit-pthreads/include/errno.h
deleted file mode 100644
index 24b005e9369..00000000000
--- a/mit-pthreads/include/errno.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)errno.h 7.13 (Berkeley) 2/19/91
- * errno.h,v 1.3 1993/05/20 16:22:09 cgd Exp
- */
-
-#ifndef _ERRNO_H_
-#define _ERRNO_H_
-
-#include <sys/cdefs.h>
-#include <sys/errno.h>
-
-__BEGIN_DECLS
-
-extern int * __error();
-
-__END_DECLS
-
-#define errno (* __error())
-#define pthread_errno(x) pthread_run->error_p = x
-
-#endif /* _ERRNO_H_ */
diff --git a/mit-pthreads/include/math.h b/mit-pthreads/include/math.h
deleted file mode 100644
index d5963ce6023..00000000000
--- a/mit-pthreads/include/math.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef _MATH_H_
-#define _MATH_H_
-
-/* Needed for HUGE_VAL */
-#include <sys/__math.h>
-
-/* XOPEN/SVID */
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-#define M_E 2.7182818284590452354 /* e */
-#define M_LOG2E 1.4426950408889634074 /* log 2e */
-#define M_LOG10E 0.43429448190325182765 /* log 10e */
-#define M_LN2 0.69314718055994530942 /* log e2 */
-#define M_LN10 2.30258509299404568402 /* log e10 */
-#define M_PI 3.14159265358979323846 /* pi */
-#define M_PI_2 1.57079632679489661923 /* pi/2 */
-#define M_PI_4 0.78539816339744830962 /* pi/4 */
-#define M_1_PI 0.31830988618379067154 /* 1/pi */
-#define M_2_PI 0.63661977236758134308 /* 2/pi */
-#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
-#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
-#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
-
-#define MAXFLOAT ((float)3.40282346638528860e+38)
-
-#if !defined(_XOPEN_SOURCE)
-
-struct exception {
- int type;
- char *name;
- double arg1;
- double arg2;
- double retval;
-};
-
-#define HUGE MAXFLOAT
-
-#define DOMAIN 1
-#define SING 2
-#define OVERFLOW 3
-#define UNDERFLOW 4
-#define TLOSS 5
-#define PLOSS 6
-
-#endif /* !_XOPEN_SOURCE */
-#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
-
-#include <sys/cdefs.h>
-
-/* ANSI/POSIX */
-
-__BEGIN_DECLS
-
-double hypot __P_((double, double));
-double acos __P_((double));
-double asin __P_((double));
-double atan __P_((double));
-double atan2 __P_((double, double));
-double cos __P_((double));
-double sin __P_((double));
-double tan __P_((double));
-
-double cosh __P_((double));
-double sinh __P_((double));
-double tanh __P_((double));
-
-double exp __P_((double));
-double frexp __P_((double, int *));
-double ldexp __P_((double, int));
-double log __P_((double));
-double log10 __P_((double));
-double modf __P_((double, double *));
-
-double pow __P_((double, double));
-double sqrt __P_((double));
-
-double ceil __P_((double));
-double fabs __P_((double));
-double floor __P_((double));
-double fmod __P_((double, double));
-double rint __P_((double)); /* XOPEN; Added by Monty */
-int finite __P_((double dsrc)); /* math.h; added by Monty */
-__END_DECLS
-
-#endif /* _MATH_H_ */
diff --git a/mit-pthreads/include/netdb.h b/mit-pthreads/include/netdb.h
deleted file mode 100644
index 54d85e5a3ed..00000000000
--- a/mit-pthreads/include/netdb.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*-
- * Copyright (c) 1980, 1983, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)netdb.h 5.15 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _NETDB_H_
-#define _NETDB_H_
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#define _PATH_HEQUIV "/etc/hosts.equiv"
-#define _PATH_HOSTS "/etc/hosts"
-#define _PATH_NETWORKS "/etc/networks"
-#define _PATH_PROTOCOLS "/etc/protocols"
-#define _PATH_SERVICES "/etc/services"
-#define __NETDB_MAXALIASES 35
-#define __NETDB_MAXADDRS 35
-
-/*
- * Structures returned by network data base library. All addresses are
- * supplied in host order, and returned in network order (suitable for
- * use in system calls).
- */
-struct hostent {
- char *h_name; /* official name of host */
- char **h_aliases; /* alias list */
- int h_addrtype; /* host address type */
- int h_length; /* length of address */
- char **h_addr_list; /* list of addresses from name server */
-#define h_addr h_addr_list[0] /* address, for backward compatiblity */
-};
-
-/*
- * Assumption here is that a network number
- * fits in 32 bits -- probably a poor one.
- */
-struct netent {
- char *n_name; /* official name of net */
- char **n_aliases; /* alias list */
- int n_addrtype; /* net address type */
- unsigned long n_net; /* network # */
-};
-
-struct servent {
- char *s_name; /* official service name */
- char **s_aliases; /* alias list */
- int s_port; /* port # */
- char *s_proto; /* protocol to use */
-};
-
-struct protoent {
- char *p_name; /* official protocol name */
- char **p_aliases; /* alias list */
- int p_proto; /* protocol # */
-};
-
-/*
- * Error return codes from gethostbyname() and gethostbyaddr()
- * (left in extern int h_errno).
- */
-
-#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
-#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
-#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
-#define NO_DATA 4 /* Valid name, no data record of requested type */
-#define NO_ADDRESS NO_DATA /* no address, look for MX record */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-void endhostent __P_((void));
-void endnetent __P_((void));
-void endprotoent __P_((void));
-void endservent __P_((void));
-struct hostent *gethostbyaddr __P_((const char *, int, int));
-struct hostent *gethostbyname __P_((const char *));
-struct hostent *gethostent __P_((void));
-struct netent *getnetbyaddr __P_((long, int)); /* u_long? */
-struct netent *getnetbyname __P_((const char *));
-struct netent *getnetent __P_((void));
-struct protoent *getprotobyname __P_((const char *));
-struct protoent *getprotobynumber __P_((int));
-struct protoent *getprotoent __P_((void));
-struct servent *getservbyname __P_((const char *, const char *));
-struct servent *getservbyport __P_((int, const char *));
-struct servent *getservent __P_((void));
-void herror __P_((const char *));
-char *hstrerror __P_((int));
-void sethostent __P_((int));
-void setnetent __P_((int));
-void setprotoent __P_((int));
-void setservent __P_((int));
-struct hostent *gethostbyaddr_r __P_((const char *, int, int,
- struct hostent *, char *, int, int *));
-struct hostent *gethostbyname_r __P_((const char *, struct hostent *, char *,
- int, int *));
-struct hostent *gethostent_r __P_((struct hostent *, char *, int, int *));
-struct netent *getnetbyaddr_r __P_((long, int, struct netent *, char *, int));
-struct netent *getnetbyname_r __P_((const char *, struct netent *, char *,
- int));
-struct netent *getnetent_r __P_((struct netent *, char *, int));
-struct protoent *getprotobyname_r __P_((const char *, struct protoent *, char *,
- int));
-struct protoent *getprotobynumber_r __P_((int, struct protoent *, char *, int));
-struct protoent *getprotoent_r __P_((struct protoent *, char *, int));
-struct servent *getservbyname_r __P_((const char *, const char *,
- struct servent *, char *, int));
-struct servent *getservbyport_r __P_((int, const char *, struct servent *,
- char *, int));
-struct servent *getservent_r __P_((struct servent *, char *, int));
-__END_DECLS
-
-#endif /* !_NETDB_H_ */
diff --git a/mit-pthreads/include/pthread.h b/mit-pthreads/include/pthread.h
deleted file mode 100644
index e8a44050215..00000000000
--- a/mit-pthreads/include/pthread.h
+++ /dev/null
@@ -1,371 +0,0 @@
-/* ==== pthread.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- *
- * 93/9/28 streepy - Added support for pthread cancel
- *
- */
-
-#ifndef _PTHREAD_H_
-#define _PTHREAD_H_
-
-#include <pthread/types.h>
-
-#include <pthread/version.h>
-#include <pthread/machdep.h>
-#include <pthread/cleanup.h>
-#include <pthread/kernel.h>
-#include <pthread/prio_queue.h>
-#include <pthread/queue.h>
-#include <pthread/sleep.h>
-#include <pthread/mutex.h>
-#include <pthread/cond.h>
-#include <pthread/fd.h>
-#include <pthread/debug_out.h>
-
-/* Requires mutex.h */
-#include <pthread/specific.h>
-
-#include <pthread/util.h>
-
-/* More includes */
-#include <pthread/pthread_once.h>
-
-/* More includes, that need size_t */
-#include <pthread/pthread_attr.h>
-
-#include <signal.h> /* for sigset_t */ /* Moved by monty */
-
-/* Constants for use with pthread_setcancelstate and pthread_setcanceltype */
-#define PTHREAD_CANCEL_DISABLE 0
-#define PTHREAD_CANCEL_ENABLE 1
-#define PTHREAD_CANCEL_DEFERRED 0
-#define PTHREAD_CANCEL_ASYNCHRONOUS 1
-
-#define PTHREAD_CANCELLED (void *)1 /* Exit status of a cancelled thread */
-
-
-#ifdef PTHREAD_KERNEL
-
-enum pthread_state {
-#define __pthread_defstate(S,NAME) S,
-#include "pthread/state.def"
-#undef __pthread_defstate
-
- /* enum lists aren't supposed to end with a comma, sigh */
- PS_STATE_MAX
-};
-
-/* Put PANIC inside an expression that evaluates to non-void type, to
- make it easier to combine it in expressions. */
-#define DO_PANIC() (PANIC (), 0)
-#define PANICIF(x) ((x) ? DO_PANIC () : 0)
-
-/* In the thread flag field, we use a series of bit flags. Flags can
- * organized into "groups" of mutually exclusive flags. Other flags
- * are unrelated and can be set and cleared with a single bit operation.
- */
-
-#define PF_WAIT_EVENT 0x01
-#define PF_DONE_EVENT 0x02
-#define PF_EVENT_GROUP 0x03 /* All event bits */
-
-#define PF_CANCEL_STATE 0x04 /* cancellability state */
-#define PF_CANCEL_TYPE 0x08 /* cancellability type */
-#define PF_THREAD_CANCELLED 0x10 /* thread has been cancelled */
-#define PF_RUNNING_TO_CANCEL 0x20 /* Thread is running so it can cancel*/
-#define PF_AT_CANCEL_POINT 0x40 /* Thread is at a cancel point */
-
-/* Flag operations */
-
-#define SET_PF_FLAG(x,f) ( (x)->flags |= (f) )
-#define TEST_PF_FLAG(x,f) ( (x)->flags & (f) )
-#define CLEAR_PF_FLAG(x,f) ( (x)->flags &= ~(f) )
-#define CLEAR_PF_GROUP(x,g) ( (x)->flags &= ~(g) )
-#define SET_PF_FLAG_IN_GROUP(x,g,f) ( CLEAR_PF_GROUP(x,g),SET_PF_FLAG(x,f))
-#define TEST_PF_GROUP(x,g) ( (x)->flags & (g) )
-
-#define SET_PF_DONE_EVENT(x) \
-( !TEST_PF_FLAG(x,PF_DONE_EVENT) \
- ? ( TEST_PF_FLAG(x,PF_WAIT_EVENT) \
- ? (SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_DONE_EVENT), OK) \
- : DO_PANIC ()) \
- : NOTOK )
-
-#define SET_PF_WAIT_EVENT(x) \
-( PANICIF (TEST_PF_GROUP(x,PF_EVENT_GROUP) ), \
- SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_WAIT_EVENT), 0)
-
-#define CLEAR_PF_DONE_EVENT(x) \
-( PANICIF (!TEST_PF_FLAG(x,PF_DONE_EVENT)), \
- CLEAR_PF_GROUP(x,PF_EVENT_GROUP) )
-
-#define SET_PF_CANCELLED(x) ( SET_PF_FLAG(x,PF_THREAD_CANCELLED) )
-#define TEST_PF_CANCELLED(x) ( TEST_PF_FLAG(x,PF_THREAD_CANCELLED) )
-
-#define SET_PF_RUNNING_TO_CANCEL(x) ( SET_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-#define CLEAR_PF_RUNNING_TO_CANCEL(x)( CLEAR_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-#define TEST_PF_RUNNING_TO_CANCEL(x)( TEST_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-
-#define SET_PF_AT_CANCEL_POINT(x) ( SET_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-#define CLEAR_PF_AT_CANCEL_POINT(x) ( CLEAR_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-#define TEST_PF_AT_CANCEL_POINT(x) ( TEST_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-
-#define SET_PF_CANCEL_STATE(x,f) \
- ( (f) ? SET_PF_FLAG(x,PF_CANCEL_STATE) : CLEAR_PF_FLAG(x,PF_CANCEL_STATE) )
-#define TEST_PF_CANCEL_STATE(x) \
- ( (TEST_PF_FLAG(x,PF_CANCEL_STATE)) ? PTHREAD_CANCEL_ENABLE \
- : PTHREAD_CANCEL_DISABLE )
-
-#define SET_PF_CANCEL_TYPE(x,f) \
- ( (f) ? SET_PF_FLAG(x,PF_CANCEL_TYPE) : CLEAR_PF_FLAG(x,PF_CANCEL_TYPE) )
-#define TEST_PF_CANCEL_TYPE(x) \
- ( (TEST_PF_FLAG(x,PF_CANCEL_TYPE)) ? PTHREAD_CANCEL_ASYNCHRONOUS \
- : PTHREAD_CANCEL_DEFERRED )
-
-/* See if a thread is in a state that it can be cancelled */
-#define TEST_PTHREAD_IS_CANCELLABLE(x) \
-( (TEST_PF_CANCEL_STATE(x) == PTHREAD_CANCEL_ENABLE && TEST_PF_CANCELLED(x)) \
- ? ((TEST_PF_CANCEL_TYPE(x) == PTHREAD_CANCEL_ASYNCHRONOUS) \
- ? 1 \
- : TEST_PF_AT_CANCEL_POINT(x)) \
- : 0 )
-
-
-struct pthread_select_data {
- int nfds;
- fd_set readfds;
- fd_set writefds;
- fd_set exceptfds;
-};
-
-union pthread_wait_data {
- pthread_mutex_t * mutex;
- pthread_cond_t * cond;
- const sigset_t * sigwait; /* Waiting on a signal in sigwait */
- struct {
- short fd; /* Used when thread waiting on fd */
- short branch; /* line number, for debugging */
- } fd;
- struct pthread_select_data * select_data;
-};
-
-#define PTT_USER_THREAD 0x0001
-
-struct pthread {
- int thread_type;
- struct machdep_pthread machdep_data;
- pthread_attr_t attr;
-
- /* Signal interface */
- sigset_t sigmask;
- sigset_t sigpending;
- int sigcount; /* Number of signals pending */
- int sighandled; /* Set when signal has been handled */
- /* Timeout time */
- struct timespec wakeup_time;
-
- /* Join queue for waiting threads */
- struct pthread_queue join_queue;
-
- /*
- * Thread implementations are just multiple queue type implemenations,
- * Below are the various link lists currently necessary
- * It is possible for a thread to be on multiple, or even all the
- * queues at once, much care must be taken during queue manipulation.
- *
- * The pthread structure must be locked before you can even look at
- * the link lists.
- */
-
- /*
- * ALL threads, in any state.
- * Must lock kernel lock before manipulating.
- */
- struct pthread * pll;
-
- /*
- * Standard link list for running threads, mutexes, etc ...
- * It can't be on both a running link list and a wait queue.
- * Must lock kernel lock before manipulating.
- */
- struct pthread * next;
- union pthread_wait_data data;
-
- /*
- * Actual queue state and priority of thread.
- * (Note: "priority" is a reserved word in Concurrent C, please
- * don't use it. --KR)
- */
- struct pthread_queue * queue;
- enum pthread_state state;
- enum pthread_state old_state; /* Used when cancelled */
- char flags;
- char pthread_priority;
-
- /*
- * Sleep queue, this is different from the standard link list
- * because it is possible to be on both (pthread_cond_timedwait();
- * Must lock sleep mutex before manipulating
- */
- struct pthread *sll; /* For sleeping threads */
-
- /*
- * Data that doesn't need to be locked
- * Mostly because only the thread owning the data can manipulate it
- */
- void * ret;
- int error;
- int * error_p;
- const void ** specific_data;
- int specific_data_count;
-
- /* Cleanup handlers Link List */
- struct pthread_cleanup *cleanup;
-};
-
-#else /* not PTHREAD_KERNEL */
-
-struct pthread;
-
-#endif
-
-typedef struct pthread *pthread_t;
-
-/*
- * Globals
- */
-#ifdef PTHREAD_KERNEL
-
-extern struct pthread * pthread_run;
-extern struct pthread * pthread_initial;
-extern struct pthread * pthread_link_list;
-extern struct pthread_queue pthread_dead_queue;
-extern struct pthread_queue pthread_alloc_queue;
-
-extern pthread_attr_t pthread_attr_default;
-extern volatile int fork_lock;
-extern pthread_size_t pthread_pagesize;
-
-extern sigset_t * uthread_sigmask;
-
-/* Kernel global functions */
-extern void pthread_sched_prevent(void);
-extern void pthread_sched_resume(void);
-extern int __pthread_is_valid( pthread_t );
-extern void pthread_cancel_internal( int freelocks );
-
-#endif
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(DCE_COMPAT)
-
-typedef void * (*pthread_startroutine_t)(void *);
-typedef void * pthread_addr_t;
-
-int pthread_create __P_((pthread_t *, pthread_attr_t,
- pthread_startroutine_t,
- pthread_addr_t));
-void pthread_exit __P_((pthread_addr_t));
-int pthread_join __P_((pthread_t, pthread_addr_t *));
-
-#else
-
-void pthread_init __P_((void));
-int pthread_create __P_((pthread_t *,
- const pthread_attr_t *,
- void * (*start_routine)(void *),
- void *));
-void pthread_exit __P_((void *));
-pthread_t pthread_self __P_((void));
-int pthread_equal __P_((pthread_t, pthread_t));
-int pthread_join __P_((pthread_t, void **));
-int pthread_detach __P_((pthread_t));
-void pthread_yield __P_((void));
-int pthread_setschedparam __P_((pthread_t pthread, int policy,
- struct sched_param * param));
-int pthread_getschedparam __P_((pthread_t pthread, int * policy,
- struct sched_param * param));
-int pthread_kill __P_((struct pthread *, int));
-void (*pthread_signal __P_((int, void (*)(int))))();
-int pthread_cancel __P_(( pthread_t pthread ));
-int pthread_setcancelstate __P_(( int state, int *oldstate ));
-int pthread_setcanceltype __P_(( int type, int *oldtype ));
-void pthread_testcancel __P_(( void ));
-
-int pthread_sigmask __P_((int how, const sigset_t *set,
- sigset_t * oset)); /* added by Monty */
-int sigwait __P_((const sigset_t * set, int * sig));
-int sigsetwait __P_((const sigset_t * set, int * sig));
-#endif
-
-#if defined(PTHREAD_KERNEL)
-
-/* Not valid, but I can't spell so this will be caught at compile time */
-#define pthread_yeild(notvalid)
-
-#endif
-
-__END_DECLS
-
-/*
- * Static constructors
- */
-#ifdef __cplusplus
-
-extern struct pthread * pthread_initial;
-
-class __pthread_init_t {
-/* struct __pthread_init_t { */
- public:
- __pthread_init_t() {
- if (pthread_initial == NULL) {
- pthread_init();
- }
- }
-};
-
-static __pthread_init_t __pthread_init_this_file;
-
-#endif /* __cplusplus */
-
-#endif
diff --git a/mit-pthreads/include/pthread/ac-types.h b/mit-pthreads/include/pthread/ac-types.h
deleted file mode 100644
index 7fa4568817f..00000000000
--- a/mit-pthreads/include/pthread/ac-types.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef pthread_size_t
-#define pthread_ipaddr_type unsigned long
-#define pthread_ipport_type unsigned short
-#define pthread_clock_t long
-#define pthread_size_t unsigned int
-#define pthread_ssize_t int
-#define pthread_time_t long
-#define pthread_off_t long
-#define pthread_va_list void *
-#endif
diff --git a/mit-pthreads/include/pthread/cleanup.h b/mit-pthreads/include/pthread/cleanup.h
deleted file mode 100755
index cd995ceddcf..00000000000
--- a/mit-pthreads/include/pthread/cleanup.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== cleanup.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : cleanup header.
- *
- * 1.20 94/02/13 proven
- * -Started coding this file.
- */
-
-/*
- * New cleanup structures
- */
-struct pthread_cleanup {
- struct pthread_cleanup *next;
- void (*routine)();
- void *routine_arg;
-};
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_cleanup_push __P_((void (*routine)(void *), void *routine_arg));
-void pthread_cleanup_pop __P_((int execute));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/cond.h b/mit-pthreads/include/pthread/cond.h
deleted file mode 100755
index ec9f7cf0016..00000000000
--- a/mit-pthreads/include/pthread/cond.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== cond.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Condition variable header.
- *
- * 1.00 93/10/30 proven
- * -Started coding this file.
- */
-
-#include <timers.h>
-
-/*
- * New cond structures
- */
-enum pthread_condtype {
- COND_TYPE_FAST,
- COND_TYPE_STATIC_FAST,
- COND_TYPE_COUNTING_FAST, /* Used with MUTEX_TYPE_COUNTING_FAST */
- COND_TYPE_METERED,
- COND_TYPE_DEBUG, /* Debug conds will have lots of options */
- COND_TYPE_MAX
-};
-
-#define PTHREAD_CONDTYPE_FAST 1
-#define PTHREAD_CONDTYPE_DEBUG 4
-#define PTHREAD_CONDTYPE_RECURSIVE 2
-
-typedef struct pthread_cond {
- enum pthread_condtype c_type;
- struct pthread_queue c_queue;
- semaphore c_lock;
- void * c_data;
- long c_flags;
-} pthread_cond_t;
-
-typedef struct pthread_condattr {
- enum pthread_condtype c_type;
- long c_flags;
-} pthread_condattr_t;
-
-/*
- * Flags for conds.
- */
-#define COND_FLAGS_PRIVATE 0x01
-#define COND_FLAGS_INITED 0x02
-#define COND_FLAGS_BUSY 0x04
-
-/*
- * Static cond initialization values.
- */
-#define PTHREAD_COND_INITIALIZER \
-{ COND_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \
- SEMAPHORE_CLEAR, NULL, COND_FLAGS_INITED }
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-struct timespec;
-
-int pthread_cond_init __P_((pthread_cond_t *, const pthread_condattr_t *));
-int pthread_cond_timedwait __P_((pthread_cond_t *, pthread_mutex_t *,
- const struct timespec * abstime));
-int pthread_cond_wait __P_((pthread_cond_t *, pthread_mutex_t *));
-int pthread_cond_signal __P_((pthread_cond_t *));
-int pthread_cond_broadcast __P_((pthread_cond_t *));
-int pthread_cond_destroy __P_((pthread_cond_t *));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/config.h b/mit-pthreads/include/pthread/config.h
deleted file mode 100644
index 251948c3874..00000000000
--- a/mit-pthreads/include/pthread/config.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef _SYS___CONFIG_H_
-#define _SYS___CONFIG_H_
-#define _OS_HAS_TIMESPEC 1
-#define _OS_HAS_SOCKLEN_T 1
-#endif
diff --git a/mit-pthreads/include/pthread/debug_out.h b/mit-pthreads/include/pthread/debug_out.h
deleted file mode 100755
index 6968c5ea90e..00000000000
--- a/mit-pthreads/include/pthread/debug_out.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* debug_out.h - macros to use for debugging prints in places where calls
- to printf() and gang are ill-advised. */
-
-#ifdef PTHREAD_DEBUGGING
-#define PTHREAD_DEBUG_WriteStr(S) (void)machdep_sys_write(2,S,strlen(S))
-#define PTHREAD_DEBUG_WriteInt32Hex(X) \
- { char _xbuf[8]; int _temp = (int)(X), _temp2; \
- _temp2 = ((_temp>>28)&0xf); \
- _xbuf[0] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>24)&0xf); \
- _xbuf[1] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>20)&0xf); \
- _xbuf[2] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>16)&0xf); \
- _xbuf[3] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>12)&0xf); \
- _xbuf[4] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>8)&0xf); \
- _xbuf[5] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>4)&0xf); \
- _xbuf[6] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = (_temp&0xf); \
- _xbuf[7] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- (void)machdep_sys_write(2,_xbuf,8); \
- }
-#ifdef __alpha
-#define PTHREAD_DEBUG_WriteInt64Hex(X) \
- { long _tempX = (long)(X),_tempY; \
- _tempY=((_tempX>>32)&0xffffffff); \
- PTHREAD_DEBUG_WriteInt32Hex(_tempY); \
- _tempY=(_tempX&0xffffffff); \
- PTHREAD_DEBUG_WriteInt32Hex(_tempY); \
- }
-#define PTHREAD_DEBUG_WritePointer(X) PTHREAD_DEBUG_WriteInt64Hex(X)
-#else
-#define PTHREAD_DEBUG_WriteInt64Hex(X) PTHREAD_DEBUG_WriteInt32Hex(X)
-#define PTHREAD_DEBUG_WritePointer(X) PTHREAD_DEBUG_WriteInt32Hex(X)
-#endif /* __alpha */
-#else /* ! PTHREAD_DEBUGGING */
-#define PTHREAD_DEBUG_WriteStr(S)
-#define PTHREAD_DEBUG_WriteInt32Hex(X)
-#define PTHREAD_DEBUG_WriteInt64HeX(X)
-#define PTHREAD_DEBUG_WritePointer(X)
-#endif /* PTHREAD_DEBUGGING */
diff --git a/mit-pthreads/include/pthread/fd.h b/mit-pthreads/include/pthread/fd.h
deleted file mode 100755
index d27a5066936..00000000000
--- a/mit-pthreads/include/pthread/fd.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ==== fd.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic fd header.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added
- */
-
-/*
- * New pthread types.
- */
-enum fd_type {
- FD_NT, /* Not tested */
- FD_NIU, /* Known to be not in use */
- FD_HALF_DUPLEX, /* Files, and seeking devices */
- FD_FULL_DUPLEX, /* pipes, sockets, drivers, ... */
- FD_TEST_HALF_DUPLEX, /* Redo machdep_sys_fcntl */
- FD_TEST_FULL_DUPLEX /* Redo machdep_sys_fcntl */
-};
-
-
-#define FD_READ 0x1
-#define FD_WRITE 0x2
-#define FD_RDWR (FD_READ | FD_WRITE)
-
-union fd_data {
- void *ptr;
- int i;
-};
-
-struct timespec;
-struct iovec;
-struct fd_ops {
- pthread_ssize_t (*write) __P_((union fd_data, int, const void *,
- size_t, struct timespec *));
- pthread_ssize_t (*read) __P_((union fd_data, int, void *, size_t,
- struct timespec *));
- int (*close)();
- int (*fcntl)();
- int (*writev) __P_((union fd_data, int,
- const struct iovec *,
- int, struct timespec *));
- int (*readv) __P_((union fd_data, int,
- const struct iovec *,
- int, struct timespec *));
- off_t (*seek)();
- int use_kfds;
-};
-
-struct fd_table_entry {
- struct pthread_queue r_queue;
- struct pthread_queue w_queue;
- struct pthread *r_owner;
- struct pthread *w_owner;
- pthread_mutex_t mutex;
- struct fd_table_entry *next;
- struct fd_ops *ops;
- enum fd_type type;
- int r_lockcount; /* Count for FILE read locks */
- int w_lockcount; /* Count for FILE write locks */
- int count;
-
- /* data that needs to be passed to the type dependent fd */
- int flags;
- union fd_data fd;
-};
-
-/*
- * Globals
- */
-#if defined(PTHREAD_KERNEL)
-
-extern struct fd_table_entry **fd_table;
-extern int dtablesize;
-
-#endif
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/include/pthread/fd_pipe.h b/mit-pthreads/include/pthread/fd_pipe.h
deleted file mode 100755
index cc5670dbb7d..00000000000
--- a/mit-pthreads/include/pthread/fd_pipe.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ==== fd_pipe.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : The new fast ITC pipe header.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- */
-
-struct __pipe {
- semaphore lock;
- char * buf;
- int size;
- int flags;
- int count;
- int offset;
- struct pthread * wait;
- char * wait_buf;
- size_t wait_size;
-};
-
-#define RD_CLOSED 0x01
-#define WR_CLOSED 0x02
-
diff --git a/mit-pthreads/include/pthread/kernel.h b/mit-pthreads/include/pthread/kernel.h
deleted file mode 100755
index c474d789681..00000000000
--- a/mit-pthreads/include/pthread/kernel.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== kernel.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/07/22 proven
- * -Started coding this file.
- */
-
-/*
- * Defines only for the pthread user kernel.
- */
-#if defined(PTHREAD_KERNEL)
-
-#ifdef __GNUC__
-#include <assert.h>
-#endif
-#ifdef __ASSERT_FUNCTION
-#define PANIC() panic_kernel( __FILE__, __LINE__, __ASSERT_FUNCTION )
-#else
-#define PANIC() panic_kernel( __FILE__, __LINE__, (const char *)0 )
-#endif
-
-
-/* Time each rr thread gets */
-#define PTHREAD_RR_TIMEOUT 100000000
-
-/* Set the errno value */
-#define SET_ERRNO(x) \
-{ \
- if (!pthread_run->error_p) { \
- pthread_run->error_p = &pthread_run->error; \
- } \
- (*(pthread_run->error_p)) = x; \
-}
-
-/* Globals only the internals should see */
-extern struct pthread_prio_queue * pthread_current_prio_queue;
-extern volatile int pthread_kernel_lock;
-
-#endif
diff --git a/mit-pthreads/include/pthread/kthread.h b/mit-pthreads/include/pthread/kthread.h
deleted file mode 100755
index a2e73361d8c..00000000000
--- a/mit-pthreads/include/pthread/kthread.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ==== kthread.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- *
- * 1.32 94/05/25 proven
- * -Started adding kernel thread support
- */
-
-#ifndef _KTHREAD_H_
-#define _KTHREAD_H_
-
-enum kthread_state {
- KS_RUNNING,
- KS_DEAD,
-};
-
-struct kthread {
- enum kthread_state state;
-
- struct pthread_queue pthread_current_queue;
- struct pthread * pthread_link_list;
- struct pthread * pthread_run;
-
- semaphore lock;
-
-};
-
-/*
- * Globals
- */
-extern struct kthread * kthread_link_list;
-
-#endif
diff --git a/mit-pthreads/include/pthread/mutex.h b/mit-pthreads/include/pthread/mutex.h
deleted file mode 100755
index e6f1fe58c0f..00000000000
--- a/mit-pthreads/include/pthread/mutex.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== mutex.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-/*
- * New mutex structures
- */
-enum pthread_mutextype {
- MUTEX_TYPE_STATIC_FAST = 0,
- MUTEX_TYPE_FAST = 1,
- MUTEX_TYPE_COUNTING_FAST = 2, /* Recursive */
- MUTEX_TYPE_METERED = 3,
- MUTEX_TYPE_DEBUG = 4, /* This will have lots of options */
- MUTEX_TYPE_MAX
-};
-
-#define PTHREAD_MUTEXTYPE_FAST 1
-#define PTHREAD_MUTEXTYPE_DEBUG 4
-#define PTHREAD_MUTEXTYPE_RECURSIVE 2
-
-union pthread_mutex_data {
- void * m_ptr;
- int m_count;
-};
-
-typedef struct pthread_mutex {
- enum pthread_mutextype m_type;
- struct pthread_queue m_queue;
- struct pthread * m_owner;
- semaphore m_lock;
- union pthread_mutex_data m_data;
- long m_flags;
-} pthread_mutex_t;
-
-typedef struct pthread_mutexattr {
- enum pthread_mutextype m_type;
- long m_flags;
-} pthread_mutexattr_t;
-
-/*
- * Flags for mutexes.
- */
-#define MUTEX_FLAGS_PRIVATE 0x01
-#define MUTEX_FLAGS_INITED 0x02
-#define MUTEX_FLAGS_BUSY 0x04
-
-/*
- * Static mutex initialization values.
- */
-#define PTHREAD_MUTEX_INITIALIZER \
-{ MUTEX_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \
- NULL, SEMAPHORE_CLEAR, { NULL }, MUTEX_FLAGS_INITED }
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_mutex_init __P_((pthread_mutex_t *, const pthread_mutexattr_t *));
-int pthread_mutex_lock __P_((pthread_mutex_t *));
-int pthread_mutex_unlock __P_((pthread_mutex_t *));
-int pthread_mutex_trylock __P_((pthread_mutex_t *));
-int pthread_mutex_destroy __P_((pthread_mutex_t *));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/paths.h b/mit-pthreads/include/pthread/paths.h
deleted file mode 100644
index bf2bf9d01a2..00000000000
--- a/mit-pthreads/include/pthread/paths.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _SYS___PATHS_H_
-#define _SYS___PATHS_H_
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/lib/zoneinfo"
-#define _PATH_TZFILE "/usr/lib/zoneinfo/localtime"
-#define _PATH_RESCONF "/etc/resolv.conf"
-#define _PATH_HOSTS "/etc/hosts"
-#define _PATH_NETWORKS "/etc/networks"
-#define _PATH_PROTOCOLS "/etc/protocols"
-#define _PATH_SERVICES "/etc/services"
-#define _PATH_BSHELL "/bin/sh"
-#endif
diff --git a/mit-pthreads/include/pthread/prio_queue.h b/mit-pthreads/include/pthread/prio_queue.h
deleted file mode 100755
index e29a0170548..00000000000
--- a/mit-pthreads/include/pthread/prio_queue.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== priority.h ==========================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Priority functions.
- *
- * 1.00 94/09/19 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_PRIO_QUEUE_H_
-#define _PTHREAD_PRIO_QUEUE_H_
-
-/*
- * Static queue initialization values.
- */
-#define PTHREAD_DEFAULT_PRIORITY 64
-#define PTHREAD_MAX_PRIORITY 126
-#define PTHREAD_MIN_PRIORITY 0
-
-/*
- * New prio_queue structures
- */
-struct pthread_prio_level {
- struct pthread * first;
- struct pthread * last;
-};
-
-struct pthread_prio_queue {
- void * data;
- struct pthread * next;
- struct pthread_prio_level level[PTHREAD_MAX_PRIORITY + 1];
-};
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-void pthread_prio_queue_init __P_((struct pthread_prio_queue *));
-void pthread_prio_queue_enq __P_((struct pthread_prio_queue *,
- struct pthread *));
-struct pthread *pthread_prio_queue_deq
- __P_((struct pthread_prio_queue *));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/include/pthread/pthread_attr.h b/mit-pthreads/include/pthread/pthread_attr.h
deleted file mode 100755
index 8cad262bad2..00000000000
--- a/mit-pthreads/include/pthread/pthread_attr.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ==== pthread_attr.h ========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread attributes header.
- *
- * 1.00 93/11/03 proven
- * -Started coding this file.
- */
-
-#define _POSIX_THREAD_ATTR_STACKSIZE
-
-#define PTHREAD_STACK_DEFAULT 65536
-
-/* flags */
-#define PTHREAD_DETACHED 0x1
-#define PTHREAD_SCOPE_SYSTEM 0x2
-#define PTHREAD_INHERIT_SCHED 0x4
-#define PTHREAD_NOFLOAT 0x8
-
-#define PTHREAD_CREATE_DETACHED PTHREAD_DETACHED
-#define PTHREAD_CREATE_JOINABLE 0
-#define PTHREAD_SCOPE_PROCESS 0
-#define PTHREAD_EXPLICIT_SCHED 0
-
-/*
- * New pthread attribute types.
- */
-enum schedparam_policy {
- SCHED_RR,
- SCHED_IO,
- SCHED_FIFO,
- SCHED_OTHER
-};
-
-struct pthread_attr {
- enum schedparam_policy schedparam_policy;
- int sched_priority;
-
- int flags;
- void * arg_attr;
- void (*cleanup_attr)();
- void * stackaddr_attr;
- size_t stacksize_attr;
-};
-
-struct sched_param {
- int sched_priority;
- void * no_data;
-};
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(DCE_COMPAT)
-
-typedef struct pthread_attr * pthread_attr_t;
-
-int pthread_attr_create __P_((pthread_attr_t *));
-int pthread_attr_delete __P_((pthread_attr_t *));
-
-#else
-
-typedef struct pthread_attr pthread_attr_t;
-
-int pthread_attr_init __P_((pthread_attr_t *));
-int pthread_attr_destroy __P_((pthread_attr_t *));
-int pthread_attr_setstacksize __P_((pthread_attr_t *, size_t));
-int pthread_attr_getstacksize __P_((pthread_attr_t *, size_t *));
-int pthread_attr_setstackaddr __P_((pthread_attr_t *, void *));
-int pthread_attr_getstackaddr __P_((pthread_attr_t *, void **));
-int pthread_attr_setdetachstate __P_((pthread_attr_t *, int ));
-int pthread_attr_getdetachstate __P_((pthread_attr_t *, int *));
-int pthread_attr_setscope __P_((pthread_attr_t *, int ));
-int pthread_attr_getscope __P_((pthread_attr_t *, int *));
-int pthread_attr_setinheritsched __P_((pthread_attr_t *, int ));
-int pthread_attr_getinheritsched __P_((pthread_attr_t *, int *));
-int pthread_attr_setschedpolicy __P_((pthread_attr_t *, int ));
-int pthread_attr_getschedpolicy __P_((pthread_attr_t *, int *));
-int pthread_attr_setschedparam __P_((pthread_attr_t *, struct sched_param *));
-int pthread_attr_getschedparam __P_((pthread_attr_t *, struct sched_param *));
-
-int pthread_attr_setfloatstate __P_((pthread_attr_t *, int ));
-int pthread_attr_getfloatstate __P_((pthread_attr_t *, int *));
-int pthread_attr_setcleanup __P_((pthread_attr_t *, void (*routine)(void *),
- void *));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/include/pthread/pthread_once.h b/mit-pthreads/include/pthread/pthread_once.h
deleted file mode 100755
index ac53d5f9b2c..00000000000
--- a/mit-pthreads/include/pthread/pthread_once.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ==== pthread_once.h ========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/12/12 proven
- * -Started coding this file.
- */
-
-/* New pthread_once structures */
-typedef struct pthread_once {
- int state;
- pthread_mutex_t mutex;
-} pthread_once_t;
-
-/* Static pthread_once_t initialization value. */
-#define PTHREAD_NEEDS_INIT 0
-#define PTHREAD_DONE_INIT 1
-#define PTHREAD_ONCE_INIT { PTHREAD_NEEDS_INIT, PTHREAD_MUTEX_INITIALIZER }
-
-/* New functions */
-
-__BEGIN_DECLS
-
-int pthread_once __P_((pthread_once_t *, void (*init_routine)(void)));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/queue.h b/mit-pthreads/include/pthread/queue.h
deleted file mode 100755
index eca7699e95a..00000000000
--- a/mit-pthreads/include/pthread/queue.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ==== queue.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-/*
- * New queue structures
- */
-struct pthread_queue {
- struct pthread *q_next;
- struct pthread *q_last;
- void *q_data;
-};
-
-/*
- * Static queue initialization values.
- */
-#define PTHREAD_QUEUE_INITIALIZER { NULL, NULL, NULL }
-
-/*
- * New functions
- * Should make pthread_queue_get a macro
- */
-
-__BEGIN_DECLS
-
-void pthread_queue_init __P_((struct pthread_queue *));
-void pthread_queue_enq __P_((struct pthread_queue *, struct pthread *));
-int pthread_queue_remove __P_((struct pthread_queue *, struct pthread *));
-struct pthread *pthread_queue_get __P_((struct pthread_queue *));
-struct pthread *pthread_queue_deq __P_((struct pthread_queue *));
-
-__END_DECLS
diff --git a/mit-pthreads/include/pthread/sleep.h b/mit-pthreads/include/pthread/sleep.h
deleted file mode 100755
index 8bf471a24aa..00000000000
--- a/mit-pthreads/include/pthread/sleep.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ==== sleep.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : sleep header.
- *
- * 1.00 94/06/04 proven
- * -Started coding this file.
- */
-
-#if defined(PTHREAD_KERNEL)
-
-#include <timers.h>
-
-/*
- * New functions
- */
-static inline int machdep_gettimeofday(struct timespec * current_time)
-{
- struct timeval current_real_time;
- int ret;
-
- ret = gettimeofday(&current_real_time, NULL);
- TIMEVAL_TO_TIMESPEC((&current_real_time), current_time);
- return(ret);
-}
-
-__BEGIN_DECLS
-
-void sleep_schedule __P_((struct timespec *, struct timespec *));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/include/pthread/specific.h b/mit-pthreads/include/pthread/specific.h
deleted file mode 100755
index 9c66a695556..00000000000
--- a/mit-pthreads/include/pthread/specific.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* ==== specific.h ========================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Thread specific data management header.
- *
- * 1.20 94/03/30 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_DATAKEYS_MAX 256
-#define _POSIX_THREAD_DESTRUTOR_ITERATIONS 4
-
-/*
- * New thread specific key type.
- */
-struct pthread_key {
- pthread_mutex_t mutex;
- long count;
- void (*destructor)();
-};
-
-typedef int pthread_key_t;
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_key_create __P_((pthread_key_t *, void (*routine)(void *)));
-int pthread_setspecific __P_((pthread_key_t, const void *));
-void *pthread_getspecific __P_((pthread_key_t));
-int pthread_key_delete __P_((pthread_key_t));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/state.def b/mit-pthreads/include/pthread/state.def
deleted file mode 100755
index c62d102a9f0..00000000000
--- a/mit-pthreads/include/pthread/state.def
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This file defines the states that a given thread can be in.
-
- The funky macro use here is so that this one header file can also
- define the corresponding state names, so that the two lists can't
- get inconsistent within a given source tree. */
-
-/* The thread is runnable. */
-__pthread_defstate (PS_RUNNING, "running")
-
-/*
- * The rest of the states are where the thread is waiting on some event.
- * Someday maybe the "data" field will point to the object being waited for.
- */
-
-/* Waiting for a mutex (pthread_mutex_lock()). */
-__pthread_defstate (PS_MUTEX_WAIT, "mutex")
-
-/* Waiting on a condition variable
- (pthread_cond_wait(), or pthread_cond_timedwait()). */
-__pthread_defstate (PS_COND_WAIT, "cond")
-
-/*
- * File descriptor stuff.
- *
- * File descriptors have a special lock. If it is a FULL_DUPLEX fd such as
- * a socket or fifo then it has two mutexes, one for reads and one for writes.
- * Some routines will even try to get both. It will always try to get the
- * read lock first before tring to get the write. All other fds only have
- * one mutex which all calls will get. It is displayed as if it is a read lock.
- */
-/* Waiting on a fd read lock (fd_lock()) */
-__pthread_defstate (PS_FDLR_WAIT, "fdlr")
-
-/* Waiting on a fd write lock (fd_lock()) */
-__pthread_defstate (PS_FDLW_WAIT, "fdlw")
-
-/* Waiting for the kernel fd to have data to read,
- (read(), readv(), recv(), recvfrom(), and recvmsg()). */
-__pthread_defstate (PS_FDR_WAIT, "fdr") /* Waiting on a kernel read */
-
-/* Waiting for the kernel fd to allow a write
- (write(), writev(), send(), sendto(), sendmsg()) */
-__pthread_defstate (PS_FDW_WAIT, "fdw")
-
-/* Waiting for several fds in a select() */
-__pthread_defstate (PS_SELECT_WAIT, "select")
-
-/* Waiting on a sleep (sleep(), usleep() or nanosleep()). */
-__pthread_defstate (PS_SLEEP_WAIT, "sleep")
-
-/* Waiting for a child to die (wait(), waitpid(), wait3(), or wait4()). */
-__pthread_defstate (PS_WAIT_WAIT, "wait")
-
-/* Waiting on some set of signals (sigwait()) */
-__pthread_defstate (PS_SIGWAIT, "sig")
-
-/* Waiting for a thread to die (pthread_join()) */
-__pthread_defstate (PS_JOIN, "join")
-
-/* Waiting for some thread to join with me or detach me */
-__pthread_defstate (PS_DEAD, "dead")
-
-/* Waiting for some thread to create me */
-__pthread_defstate (PS_UNALLOCED, "unallocated")
diff --git a/mit-pthreads/include/pthread/types.h b/mit-pthreads/include/pthread/types.h
deleted file mode 100755
index 7fdf001a0bc..00000000000
--- a/mit-pthreads/include/pthread/types.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef pthread_types_h
-#define pthread_types_h
-
-#include <pthread/xtypes.h>
-#include <pthread/ac-types.h>
-
-#if !defined (pthread_va_list) && defined (__NetBSD__)
-#include <stdarg.h>
-#define pthread_va_list _BSD_VA_LIST_
-#endif
-
-#if !defined (pthread_va_list) && defined (__GNUC__)
-#define __need_va_list
-#include <stdarg.h>
-#define pthread_va_list __gnuc_va_list
-#endif /* pthread_va_list, __GNUC__ */
-
-/* OSF/1 does it this way. */
-#if !defined (pthread_va_list) && defined (pthread_have_va_list_h)
-#ifndef _VA_LIST
-#define _HIDDEN_VA_LIST
-#include <va_list.h>
-#define pthread_va_list __va_list
-#else
-/* va_list has already been defined */
-#define pthread_va_list va_list
-#endif
-#endif
-
-/* If all else fails... */
-#ifndef pthread_va_list
-#include <stdarg.h>
-#define pthread_va_list va_list
-#endif
-
-#if defined(__STDC__) || defined(__GNUC__)
-#ifndef __P_
-#define __P_(protos) protos
-#endif
-#else
-#ifndef __P_
-#define __P_(protos)
-#endif
-#endif
-
-#endif /* pthread_types_h */
diff --git a/mit-pthreads/include/pthread/unistd.h b/mit-pthreads/include/pthread/unistd.h
deleted file mode 100755
index 3cb07533114..00000000000
--- a/mit-pthreads/include/pthread/unistd.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execve __P_((const char *, char * const *, char * const *));
-pid_t fork __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-u_int sleep __P_((u_int));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-/* Not implemented for threads yet */
-u_int alarm __P_((u_int));
-char *cuserid __P_((char *));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execvp __P_((const char *, char * const *));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, int *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-
-#ifndef _POSIX_SOURCE
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-int chflags __P_((const char *, long));
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-int des_setkey __P_((const char *key));
-int encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-int fchflags __P_((int, long));
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, int));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((u_int, const char *));
-extern char *sys_siglist[];
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const int *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-int setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-u_int ualarm __P_((u_int, u_int));
-void usleep __P_((u_int));
-int vfork __P_((void));
-
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/util.h b/mit-pthreads/include/pthread/util.h
deleted file mode 100755
index aaa33a6318d..00000000000
--- a/mit-pthreads/include/pthread/util.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ==== util.h ============================================================
- * Copyright (c) 1991, 1992, 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Header file for generic utility functions.
- *
- * 91/08/31 proven - Added exchange.
- * Exchange any two objects of any size in any table.
- *
- * 91/10/06 proven - Cleaned out all the old junk.
- *
- * 91/03/06 proven - Added getint.
- */
-
-#ifndef _PTHREAD_UTIL_H
-#define _PTHREAD_UTIL_H
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* Stuff only pthread internals really uses */
-#if defined(PTHREAD_KERNEL)
-
-#undef FALSE
-#undef TRUE
-
-typedef enum Boolean {
- FALSE,
- TRUE
-} Boolean;
-
-#define OK 0
-#define NUL '\0'
-#define NOTOK -1
-
-#if ! defined(min)
-#define min(a,b) (((a)<(b))?(a):(b))
-#define max(a,b) (((a)>(b))?(a):(b))
-#endif
-
-/* Alingn the size to the next multiple of 4 bytes */
-#define ALIGN4(size) ((size + 3) & ~3)
-#define ALIGN8(size) ((size + 7) & ~7)
-
-#ifdef DEBUG
-#define DEBUG0(s) printf(s)
-#define DEBUG1(s,a) printf(s,a)
-#define DEBUG2(s,a,b) printf(s,a,b)
-#define DEBUG3(s,a,b,c) printf(s,a,b,c)
-#else
-#define DEBUG0(s)
-#define DEBUG1(s)
-#define DEBUG2(s)
-#define DEBUG3(s)
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/include/pthread/version.h b/mit-pthreads/include/pthread/version.h
deleted file mode 100755
index fda3af284d0..00000000000
--- a/mit-pthreads/include/pthread/version.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== version.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Header file for programs that what to KNOW the version.
- *
- * 94/08/24 proven - Added this file for pthreads.
- */
-
-#ifndef _PTHREAD_VERSION_H
-#define _PTHREAD_VERSION_H 1
-#define _PTHREAD_VERSION_M 60
-#define _PTHREAD_VERSION_P 0
-#endif
diff --git a/mit-pthreads/include/pthread/xtypes.h b/mit-pthreads/include/pthread/xtypes.h
deleted file mode 100755
index 4dcc4f04f8c..00000000000
--- a/mit-pthreads/include/pthread/xtypes.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* If you need any special typedefs for function pointers &c to try
- testing for in configure.in, define them here. */
-
-/* According to ANSI, two struct types in the same module are not
- compatible types. So there's no way to define a type for
- pthread_sigset_t that's compatible with sigset_t when they're
- structure types, if we assume we can't pull in a __sigset_t or
- something by itself from system header files.
-
- Since that was my main reason for creating this file, there isn't
- anything here now. If after working on this code a bit longer we
- don't find anything else to put here, this file should just go
- away. */
diff --git a/mit-pthreads/include/pwd.h b/mit-pthreads/include/pwd.h
deleted file mode 100644
index af945a2b8db..00000000000
--- a/mit-pthreads/include/pwd.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)pwd.h 8.2 (Berkeley) 1/21/94
- * $Id$
- */
-
-#ifndef _PWD_H_
-#define _PWD_H_
-
-#include <sys/types.h>
-
-#ifndef _POSIX_SOURCE
-#define _PATH_PASSWD "/etc/passwd"
-#define _PATH_MASTERPASSWD "/etc/master.passwd"
-
-#define _PATH_MP_DB "/etc/pwd.db"
-#define _PATH_SMP_DB "/etc/spwd.db"
-
-#define _PATH_PWD_MKDB "/usr/sbin/pwd_mkdb"
-
-#define _PW_KEYBYNAME '1' /* stored by name */
-#define _PW_KEYBYNUM '2' /* stored by entry in the "file" */
-#define _PW_KEYBYUID '3' /* stored by uid */
-
-#define _PASSWORD_EFMT1 '_' /* extended encryption format */
-
-#define _PASSWORD_LEN 128 /* max length, not counting NULL */
-#endif
-
-struct passwd {
- char *pw_name; /* user name */
- char *pw_passwd; /* encrypted password */
- int pw_uid; /* user uid */
- int pw_gid; /* user gid */
- time_t pw_change; /* password change time */
- char *pw_class; /* user access class */
- char *pw_gecos; /* Honeywell login info */
- char *pw_dir; /* home directory */
- char *pw_shell; /* default shell */
- time_t pw_expire; /* account expiration */
-};
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct passwd *getpwuid __P_((uid_t));
-struct passwd *getpwnam __P_((const char *));
-#ifndef _POSIX_SOURCE
-struct passwd *getpwent __P_((void));
-#ifndef _XOPEN_SOURCE
-int setpassent __P_((int));
-#endif
-void setpwent __P_((void));
-void endpwent __P_((void));
-#endif
-__END_DECLS
-
-#endif /* !_PWD_H_ */
diff --git a/mit-pthreads/include/resolv.h b/mit-pthreads/include/resolv.h
deleted file mode 100644
index f6313a7229e..00000000000
--- a/mit-pthreads/include/resolv.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 1983, 1987, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)resolv.h 5.15 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _RESOLV_H_
-#define _RESOLV_H_
-
-#include <netinet/in.h>
-/*
- * This is specificly for Solaris which defines NOERROR in the streams
- * header files and defines it differently than in arpa/nameser.h
- */
-#ifdef NOERROR
-#undef NOERROR
-#endif
-#include <arpa/nameser.h>
-
-/*
- * revision information. this is the release date in YYYYMMDD format.
- * it can change every day so the right thing to do with it is use it
- * in preprocessor commands such as "#if (__RES > 19931104)". do not
- * compare for equality; rather, use it to determine whether your resolver
- * is new enough to contain a certain feature.
- */
-
-#define __RES 19940703
-
-/*
- * Resolver configuration file.
- * Normally not present, but may contain the address of the
- * inital name server(s) to query and the domain search list.
- */
-
-#ifndef _PATH_RESCONF
-#define _PATH_RESCONF "/etc/resolv.conf"
-#endif
-
-/*
- * Global defines and variables for resolver stub.
- */
-#define MAXNS 3 /* max # name servers we'll track */
-#define MAXDFLSRCH 3 /* # default domain levels to try */
-#define MAXDNSRCH 6 /* max # domains in search path */
-#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
-#define MAXDNSLUS 4 /* max # of host lookup types */
-
-#define RES_TIMEOUT 5 /* min. seconds between retries */
-#define MAXRESOLVSORT 10 /* number of net to sort on */
-#define RES_MAXNDOTS 15 /* should reflect bit field size */
-
-struct __res_state {
- int retrans; /* retransmition time interval */
- int retry; /* number of times to retransmit */
- long options; /* option flags - see below. */
- int nscount; /* number of name servers */
- struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */
-#define nsaddr nsaddr_list[0] /* for backward compatibility */
- u_short id; /* current packet id */
- char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
- char defdname[MAXDNAME]; /* default domain */
- long pfcode; /* RES_PRF_ flags - see below. */
- u_char ndots:4; /* threshold for initial abs. query */
- u_char nsort:4; /* number of elements in sort_list[] */
- char unused[3];
- struct {
- struct in_addr addr;
- u_long mask;
- } sort_list[MAXRESOLVSORT];
- char lookups[MAXDNSLUS];
-};
-
-/*
- * Resolver options
- */
-#define RES_INIT 0x0001 /* address initialized */
-#define RES_DEBUG 0x0002 /* print debug messages */
-#define RES_AAONLY 0x0004 /* authoritative answers only */
-#define RES_USEVC 0x0008 /* use virtual circuit */
-#define RES_PRIMARY 0x0010 /* query primary server only */
-#define RES_IGNTC 0x0020 /* ignore trucation errors */
-#define RES_RECURSE 0x0040 /* recursion desired */
-#define RES_DEFNAMES 0x0080 /* use default domain name */
-#define RES_STAYOPEN 0x0100 /* Keep TCP socket open */
-#define RES_DNSRCH 0x0200 /* search up local domain tree */
-
-#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
-
-/*
- * Resolver "pfcode" values. Used by dig.
- */
-#define RES_PRF_STATS 0x0001
-/* 0x0002 */
-#define RES_PRF_CLASS 0x0004
-#define RES_PRF_CMD 0x0008
-#define RES_PRF_QUES 0x0010
-#define RES_PRF_ANS 0x0020
-#define RES_PRF_AUTH 0x0040
-#define RES_PRF_ADD 0x0080
-#define RES_PRF_HEAD1 0x0100
-#define RES_PRF_HEAD2 0x0200
-#define RES_PRF_TTLID 0x0400
-#define RES_PRF_HEADX 0x0800
-#define RES_PRF_QUERY 0x1000
-#define RES_PRF_REPLY 0x2000
-#define RES_PRF_INIT 0x4000
-/* 0x8000 */
-
-#define _res (*_res_status())
-#define h_errno (_res_get_error())
-
-#include <sys/cdefs.h>
-#include <stdio.h>
-
-/* Private routines shared between libc/net, named, nslookup and others. */
-#define dn_skipname __dn_skipname
-#define fp_query __fp_query
-#define hostalias __hostalias
-#define putlong __putlong
-#define putshort __putshort
-#define p_class __p_class
-#define p_time __p_time
-#define p_type __p_type
-__BEGIN_DECLS
-struct __res_state *_res_status __P_((void));
-int _res_get_error __P_((void));
-
-int __dn_skipname __P_((const u_char *, const u_char *));
-void __fp_query __P_((char *, FILE *));
-char *__hostalias __P_((const char *));
-void __putlong __P_((pthread_ipaddr_type, unsigned char *));
-void __putshort __P_((pthread_ipport_type, unsigned char *));
-char *__p_class __P_((int));
-char *__p_time __P_((unsigned long));
-char *__p_type __P_((int));
-
-int dn_comp __P_((const unsigned char *, unsigned char *, int,
- unsigned char **, unsigned char **));
-int dn_expand __P_((const unsigned char *, const unsigned char *,
- const unsigned char *, unsigned char *, int));
-int res_init __P_((void));
-int res_mkquery __P_((int, const char *, int, int, const char *, int,
- const char *, char *, int));
-int res_send __P_((const char *, int, char *, int));
-__END_DECLS
-
-#endif /* !_RESOLV_H_ */
-
diff --git a/mit-pthreads/include/sched.h b/mit-pthreads/include/sched.h
deleted file mode 100644
index dcd9d4e3600..00000000000
--- a/mit-pthreads/include/sched.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ==== pthread.h ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread header.
- *
- * 1.00 93/08/29 proven
- * -Started coding this file.
- */
-
-#ifndef _SCHED_H_
-#define _SCHED_H_
-
-#include <pthread/prio_queue.h>
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int sched_yield __P_((void));
-int sched_get_priority_max __P_((int));
-int sched_get_priority_min __P_((int));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/include/signal.h b/mit-pthreads/include/signal.h
deleted file mode 100644
index 9fb1ec6e2c8..00000000000
--- a/mit-pthreads/include/signal.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)signal.h 8.3 (Berkeley) 3/30/94
- */
-
-#ifndef _SIGNAL_H
-#define _SIGNAL_H
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/__signal.h>
-
-__BEGIN_DECLS
-
-int raise __P_((int));
-/* RETSIGTYPE signal __P_((int __sig, RETSIGTYPE)); */
-
-#ifndef _ANSI_SOURCE
-
-int sigfillset __P_((sigset_t *));
-int sigemptyset __P_((sigset_t *));
-int sigaddset __P_((sigset_t *, int));
-int sigdelset __P_((sigset_t *, int));
-int sigismember __P_((const sigset_t *, int));
-int sigsuspend __P_((const sigset_t *));
-int sigprocmask __P_((int, const sigset_t *, sigset_t *));
-
-/* Still need work */
-int kill __P_((pid_t, int));
-int sigaction __P_((int, const struct sigaction *, struct sigaction *));
-int sigpending __P_((sigset_t *));
-
-#ifndef _POSIX_SOURCE
-
-int killpg __P_((pid_t, int));
-int siginterrupt __P_((int, int));
-void psignal __P_((unsigned int, const char *));
-
-/* int sigpause __P_((int)); */
-/* int sigsetmask __P_((int)); */
-/* int sigblock __P_((int)); */
-/* int sigreturn __P_((struct sigcontext *)); */
-/* int sigvec __P_((int, struct sigvec *, struct sigvec *)); */
-/* int sigstack __P_((const struct sigstack *, struct sigstack *)); */
-
-#endif /* !_POSIX_SOURCE */
-#endif /* !_ANSI_SOURCE */
-
-__END_DECLS
-
-#endif /* !_USER_SIGNAL_H */
diff --git a/mit-pthreads/include/stdio.h b/mit-pthreads/include/stdio.h
deleted file mode 100644
index 538d4685f3f..00000000000
--- a/mit-pthreads/include/stdio.h
+++ /dev/null
@@ -1,371 +0,0 @@
-/* ==== stdio.h ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdio.h 5.17 (Berkeley) 6/3/91
- * $Id$
- */
-
-#ifndef _STDIO_H_
-#define _STDIO_H_
-
-#include <sys/cdefs.h>
-#include <pthread/types.h>
-#include <pthread/posix.h>
-#include <sys/__stdio.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define _FSTDIO /* Define for new stdio with functions. */
-
-/*
- * NB: to fit things in six character monocase externals, the stdio
- * code uses the prefix `__s' for stdio objects, typically followed
- * by a three-character attempt at a mnemonic.
- */
-
-/* stdio buffers */
-struct __sbuf {
- unsigned char *_base;
- int _size;
-};
-
-/*
- * stdio state variables.
- *
- * The following always hold:
- *
- * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
- * _lbfsize is -_bf._size, else _lbfsize is 0
- * if _flags&__SRD, _w is 0
- * if _flags&__SWR, _r is 0
- *
- * This ensures that the getc and putc macros (or inline functions) never
- * try to write or read from a file that is in `read' or `write' mode.
- * (Moreover, they can, and do, automatically switch from read mode to
- * write mode, and back, on "r+" and "w+" files.)
- *
- * _lbfsize is used only to make the inline line-buffered output stream
- * code as compact as possible.
- *
- * _ub, _up, and _ur are used when ungetc() pushes back more characters
- * than fit in the current _bf, or when ungetc() pushes back a character
- * that does not match the previous one in _bf. When this happens,
- * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
- * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
- */
-typedef struct __sFILE {
- unsigned char *_p; /* current position in (some) buffer */
- int _r; /* read space left for getc() */
- int _w; /* write space left for putc() */
- short _flags; /* flags, below; this FILE is free if 0 */
- short _file; /* fileno, if Unix descriptor, else -1 */
- struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
- int _lbfsize; /* 0 or -_bf._size, for inline putc */
-
- /* separate buffer for long sequences of ungetc() */
- struct __sbuf _ub; /* ungetc buffer */
- unsigned char *_up; /* saved _p when _p is doing ungetc data */
- int _ur; /* saved _r when _r is counting ungetc data */
-
- /* tricks to meet minimum requirements even when malloc() fails */
- unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
- unsigned char _nbuf[1]; /* guarantee a getc() buffer */
-
- /* separate buffer for fgetline() when line crosses buffer boundary */
- struct __sbuf _lb; /* buffer for fgetline() */
-
- /* Unix stdio files get aligned to block boundaries on fseek() */
- int _blksize; /* stat.st_blksize (may be != _bf._size) */
- int _offset; /* current lseek offset */
-} FILE;
-
-__BEGIN_DECLS
-extern FILE __sF[];
-__END_DECLS
-
-#define __SLBF 0x0001 /* line buffered */
-#define __SNBF 0x0002 /* unbuffered */
-#define __SRD 0x0004 /* OK to read */
-#define __SWR 0x0008 /* OK to write */
- /* RD and WR are never simultaneously asserted */
-#define __SRW 0x0010 /* open for reading & writing */
-#define __SEOF 0x0020 /* found EOF */
-#define __SERR 0x0040 /* found error */
-#define __SMBF 0x0080 /* _buf is from malloc */
-#define __SAPP 0x0100 /* fdopen()ed in append mode */
-#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
-#define __SOPT 0x0400 /* do fseek() optimisation */
-#define __SNPT 0x0800 /* do not do fseek() optimisation */
-#define __SOFF 0x1000 /* set iff _offset is in fact correct */
-#define __SMOD 0x2000 /* true => fgetline modified _p text */
-
-/*
- * The following three definitions are for ANSI C, which took them
- * from System V, which brilliantly took internal interface macros and
- * made them official arguments to setvbuf(), without renaming them.
- * Hence, these ugly _IOxxx names are *supposed* to appear in user code.
- *
- * Although numbered as their counterparts above, the implementation
- * does not rely on this.
- */
-#define _IOFBF 0 /* setvbuf should set fully buffered */
-#define _IOLBF 1 /* setvbuf should set line buffered */
-#define _IONBF 2 /* setvbuf should set unbuffered */
-
-#define BUFSIZ 1024 /* size of buffer used by setbuf */
-#define EOF (-1)
-
-/*
- * FOPEN_MAX is a minimum maximum, and should be the number of descriptors
- * that the kernel can provide without allocation of a resource that can
- * fail without the process sleeping. Do not use this for anything.
- */
-#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */
-#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */
-
-/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */
-#ifndef _ANSI_SOURCE
-#define P_tmpdir "/var/tmp/"
-#endif
-#define L_tmpnam 1024 /* XXX must be == PATH_MAX */
-#ifndef TMP_MAX
-#define TMP_MAX 308915776
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0 /* set file offset to offset */
-#endif
-#ifndef SEEK_CUR
-#define SEEK_CUR 1 /* set file offset to current plus offset */
-#endif
-#ifndef SEEK_END
-#define SEEK_END 2 /* set file offset to EOF plus offset */
-#endif
-
-#define stdin (&__sF[0])
-#define stdout (&__sF[1])
-#define stderr (&__sF[2])
-
-/*
- * Functions defined in ANSI C standard.
- */
-__BEGIN_DECLS
-void clearerr __P_((FILE *));
-int fclose __P_((FILE *));
-int feof __P_((FILE *));
-int ferror __P_((FILE *));
-int fflush __P_((FILE *));
-int fgetc __P_((FILE *));
-int fgetpos __P_((FILE *, fpos_t *));
-char * fgets __P_((char *, size_t, FILE *));
-FILE * fopen __P_((const char *, const char *));
-int fprintf __P_((FILE *, const char *, ...));
-int fputc __P_((int, FILE *));
-int fputs __P_((const char *, FILE *));
-size_t fread __P_((void *, size_t, size_t, FILE *));
-FILE * freopen __P_((const char *, const char *, FILE *));
-int fscanf __P_((FILE *, const char *, ...));
-int fseek __P_((FILE *, long, int));
-int fsetpos __P_((FILE *, const fpos_t *));
-long ftell __P_((const FILE *));
-size_t fwrite __P_((const void *, size_t, size_t, FILE *));
-int getc __P_((FILE *));
-int getchar __P_((void));
-char * gets __P_((char *));
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-extern int sys_nerr; /* perror(3) external variables */
-/* Under NetBSD and BSD 4.4, at least, this is expected to be a const
- array of pointers to const. If you take `const' back out of this
- declaration, please make it conditional on __NetBSD__ and bsd4_4. */
-#ifdef HAVE_SYS_ERRLIST_WITHOUT_CONST
-extern char *sys_errlist[];
-#else
-extern const char *const sys_errlist[];
-#endif
-#endif
-
-void perror __P_((const char *));
-int printf __P_((const char *, ...));
-int putc __P_((int, FILE *));
-int putchar __P_((int));
-int puts __P_((const char *));
-int remove __P_((const char *));
-int rename __P_((const char *, const char *));
-void rewind __P_((FILE *));
-int scanf __P_((const char *, ...));
-void setbuf __P_((FILE *, char *));
-int setvbuf __P_((FILE *, char *, int, size_t));
-int sprintf __P_((char *, const char *, ...));
-int sscanf __P_((const char *, const char *, ...));
-FILE * tmpfile __P_((void));
-char * tmpnam __P_((char *));
-int ungetc __P_((int, FILE *));
-int vfprintf __P_((FILE *, const char *, pthread_va_list));
-int vprintf __P_((const char *, pthread_va_list));
-int vsprintf __P_((char *, const char *, pthread_va_list));
-char *mprintf __P_((const char *, ...));
-char *vmprintf __P_((const char *, pthread_va_list));
-__END_DECLS
-
-/*
- * Functions defined in POSIX 1003.1.
- */
-#ifndef _ANSI_SOURCE
-#define L_ctermid 1024 /* size for ctermid(); PATH_MAX */
-#define L_cuserid 9 /* size for cuserid(); UT_NAMESIZE + 1 */
-
-__BEGIN_DECLS
-char * ctermid __P_((char *));
-char * cuserid __P_((char *));
-FILE * fdopen __P_((int, const char *));
-int fileno __P_((FILE *));
-__END_DECLS
-#endif /* not ANSI */
-
-/*
- * Functions defined in POSIX 1003.4a. (1c)
- */
-#ifndef _ANSI_SOURCE
-__BEGIN_DECLS
-void flockfile __P_((FILE *));
-void funlockfile __P_((FILE *));
-int ftrylockfile __P_((FILE *));
-__END_DECLS
-#endif /* not ANSI */
-
-/*
- * Routines that are purely local.
- */
-#if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-char *fgetline __P_((FILE *, size_t *));
-int fpurge __P_((FILE *));
-int getw __P_((FILE *));
-int pclose __P_((FILE *));
-FILE *popen __P_((const char *, const char *));
-int putw __P_((int, FILE *));
-void setbuffer __P_((FILE *, char *, int));
-int setlinebuf __P_((FILE *));
-char *tempnam __P_((const char *, const char *));
-int snprintf __P_((char *, size_t, const char *, ...));
-int vsnprintf __P_((char *, size_t, const char *, pthread_va_list));
-int vscanf __P_((const char *, pthread_va_list));
-int vsscanf __P_((const char *, const char *, pthread_va_list));
-__END_DECLS
-
-/*
- * This is a #define because the function is used internally and
- * (unlike vfscanf) the name __svfscanf is guaranteed not to collide
- * with a user function when _ANSI_SOURCE or _POSIX_SOURCE is defined.
- */
-#define vfscanf __svfscanf
-
-/*
- * Stdio function-access interface.
- */
-__BEGIN_DECLS
-FILE *funopen __P_((const void *,
- int (*)(void *, char *, int),
- int (*)(void *, const char *, int),
- fpos_t (*)(void *, fpos_t, int),
- int (*)(void *)));
-__END_DECLS
-#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
-#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
-#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
-
-/*
- * Functions internal to the implementation.
- */
-__BEGIN_DECLS
-int __srget __P_((FILE *));
-int __svfscanf __P_((FILE *, const char *, pthread_va_list));
-int __swbuf __P_((int, FILE *));
-__END_DECLS
-
-/*
- * The __sfoo macros are here so that we can
- * define function versions in the C library.
- */
-#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
-
-__BEGIN_DECLS
-int __getc __P_((FILE *));
-__END_DECLS
-
-#define getc(fp) __getc(fp)
-#define getchar() getc(stdin)
-#define getc_unlocked(fp) __sgetc(fp)
-#define getchar_unlocked() getc_unlocked(stdin)
-
-#ifdef __CAN_DO_EXTERN_INLINE
-__INLINE int __sputc(int _c, FILE *_p)
-{
- if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
- return (*_p->_p++ = _c);
- else
- return (__swbuf(_c, _p));
-}
-#else
-__BEGIN_DECLS
-int __sputc __P_((int, FILE *));
-__END_DECLS
-#endif
-
-__BEGIN_DECLS
-int __putc __P_((int, FILE *));
-__END_DECLS
-
-#define putc(x, fp) __putc(x, fp)
-#define putchar(x) putc(x, stdout)
-#define putc_unlocked(x, fp) __sputc(x, fp)
-#define putchar_unlocked(x) putc_unlocked(x, stdout)
-
-#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
-#define __sferror(p) (((p)->_flags & __SERR) != 0)
-#define __sfileno(p) ((p)->_file)
-
-#define feof(p) __sfeof(p)
-#define ferror(p) __sferror(p)
-
-#ifndef _ANSI_SOURCE
-#define fileno(p) __sfileno(p)
-#endif
-
-#endif
diff --git a/mit-pthreads/include/stdlib.h b/mit-pthreads/include/stdlib.h
deleted file mode 100644
index 77f84ffa0bb..00000000000
--- a/mit-pthreads/include/stdlib.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _STDLIB_H_
-#define _STDLIB_H_
-
-#include <sys/__stdlib.h>
-
-/* Returned by `div'. */
-typedef struct
- {
- int quot; /* Quotient. */
- int rem; /* Remainder. */
- } div_t;
-
-/* Returned by `ldiv'. */
-typedef struct
- {
- long quot; /* Quotient. */
- long rem; /* Remainder. */
- } ldiv_t;
-
-#ifndef RAND_MAX
-#define RAND_MAX 2147483647
-#endif
-
-#define EXIT_FAILURE 1 /* Failing exit status. */
-#define EXIT_SUCCESS 0 /* Successful exit status. */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-double atof __P_((const char *));
-int atoi __P_((const char *));
-long atol __P_((const char *));
-double strtod __P_((const char *, char **));
-long strtol __P_((const char *, char **, int));
-unsigned long strtoul __P_((const char *, char **, int));
-
-int rand __P_((void));
-void srand __P_((unsigned int));
-
-long random __P_((void));
-void srandom __P_((unsigned int));
-char * initstate __P_((unsigned int, char *, int));
-char * setstate __P_((char *));
-
-void * malloc __P_((size_t));
-void * realloc __P_((void *, size_t));
-void * calloc __P_((size_t, size_t));
-void free __P_((void *));
-
-__NORETURN void abort __P_((void));
-int atexit __P_((void (* __func)() ));
-__NORETURN void exit __P_((int));
-int system __P_((const char *));
-
-extern char ** environ;
-
-char * getenv __P_((const char *));
-int putenv __P_((const char *));
-int setenv __P_((const char *, const char *, int));
-void unsetenv __P_((const char *));
-
-void * bsearch __P_((const void *, const void *, size_t, size_t,
- int (* __func)__P_((const void *, const void *)) ));
-void qsort __P_((void *, size_t, size_t,
- int (* __func)__P_((const void *, const void *)) ));
-
-int abs __P_((int));
-long labs __P_((long));
-div_t div __P_((int, int));
-ldiv_t ldiv __P_((long, long));
-
-void * memchr __P_((const void *, int, size_t));
-
-/* Stuff to do */
-int mblen __P_((const char *, size_t));
-int mbtowc __P_((wchar_t *, const char *, size_t));
-int wctomb __P_((char *, wchar_t));
-size_t mbstowcs __P_((wchar_t *, const char *, size_t));
-size_t wcstombs __P_((char *, const wchar_t *, size_t));
-
-
-__END_DECLS
-
-#endif /* !_STDLIB_H_ */
diff --git a/mit-pthreads/include/string.h b/mit-pthreads/include/string.h
deleted file mode 100644
index 4143a1cfec7..00000000000
--- a/mit-pthreads/include/string.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* $NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $ */
-
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)string.h 5.10 (Berkeley) 3/9/91
- */
-
-#ifndef _STRING_H_
-#define _STRING_H_
-#include <sys/cdefs.h>
-#include <pthread/types.h>
-#include <pthread/posix.h>
-#include <sys/__string.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-__BEGIN_DECLS
-void *memchr __P_((const void *, int, size_t));
-int memcmp __P_((const void *, const void *, size_t));
-void *memcpy __P_((void *, const void *, size_t));
-void *memmove __P_((void *, const void *, size_t));
-void *memset __P_((void *, int, size_t));
-char *strcat __P_((char *, const char *));
-char *strchr __P_((const char *, int));
-int strcmp __P_((const char *, const char *));
-int strcoll __P_((const char *, const char *));
-char *strcpy __P_((char *, const char *));
-size_t strcspn __P_((const char *, const char *));
-char *strerror __P_((int));
-size_t strlen __P_((const char *));
-char *strncat __P_((char *, const char *, size_t));
-int strncmp __P_((const char *, const char *, size_t));
-char *strncpy __P_((char *, const char *, size_t));
-char *strpbrk __P_((const char *, const char *));
-char *strrchr __P_((const char *, int));
-size_t strspn __P_((const char *, const char *));
-char *strstr __P_((const char *, const char *));
-char *strtok __P_((char *, const char *));
-char *strtok_r __P_((char *, const char *, char **));
-size_t strxfrm __P_((char *, const char *, size_t));
-
-/* Nonstandard routines common to all pthreads supported platforms */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-int ffs __P_((int));
-void *memccpy __P_((void *, const void *, int, size_t));
-int strcasecmp __P_((const char *, const char *));
-int strncasecmp __P_((const char *, const char *, size_t));
-char *strsignal __P_((int));
-void swab __P_((const void *, void *, size_t));
-#endif
-__END_DECLS
-
-#endif /* _STRING_H_ */
diff --git a/mit-pthreads/include/syslog.h b/mit-pthreads/include/syslog.h
deleted file mode 100644
index 31b42285fc1..00000000000
--- a/mit-pthreads/include/syslog.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)syslog.h 7.8 (Berkeley) 5/26/88
- */
-
-#ifndef SYSLOG_H
-#define SYSLOG_H
-
-/* Added __[BEGIN/END]_DECLS so this file would work with C++. (mevans) */
-#include <sys/cdefs.h>
-#include <stdarg.h>
-
-/* Discipline: openlog(), closelog(), and setlogmask() are not thread-safe
- * and should only be called when other threads will not be calling syslog
- * functions. syslog() and vsyslog() are thread-safe and may be called
- * asynchronously, even if openlog() has not been called. */
-
-/*
- * Facility codes
- */
-
-#define LOG_KERN (0<<3) /* kernel messages */
-#define LOG_USER (1<<3) /* random user-level messages */
-#define LOG_MAIL (2<<3) /* mail system */
-#define LOG_DAEMON (3<<3) /* system daemons */
-#define LOG_AUTH (4<<3) /* security/authorization messages */
-#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
-#define LOG_LPR (6<<3) /* line printer subsystem */
-#define LOG_NEWS (7<<3) /* network news subsystem */
-#define LOG_UUCP (8<<3) /* UUCP subsystem */
- /* other codes through 15 reserved for system use */
-#define LOG_LOCAL0 (16<<3) /* reserved for local use */
-#define LOG_LOCAL1 (17<<3) /* reserved for local use */
-#define LOG_LOCAL2 (18<<3) /* reserved for local use */
-#define LOG_LOCAL3 (19<<3) /* reserved for local use */
-#define LOG_LOCAL4 (20<<3) /* reserved for local use */
-#define LOG_LOCAL5 (21<<3) /* reserved for local use */
-#define LOG_LOCAL6 (22<<3) /* reserved for local use */
-#define LOG_LOCAL7 (23<<3) /* reserved for local use */
-
-#define LOG_NFACILITIES 24 /* maximum number of facilities */
-#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
-
-#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) /* facility of pri */
-
-/*
- * Priorities (these are ordered)
- */
-
-#define LOG_EMERG 0 /* system is unusable */
-#define LOG_ALERT 1 /* action must be taken immediately */
-#define LOG_CRIT 2 /* critical conditions */
-#define LOG_ERR 3 /* error conditions */
-#define LOG_WARNING 4 /* warning conditions */
-#define LOG_NOTICE 5 /* normal but signification condition */
-#define LOG_INFO 6 /* informational */
-#define LOG_DEBUG 7 /* debug-level messages */
-
-#define LOG_PRIMASK 0x0007 /* mask to extract priority part (internal) */
-#define LOG_PRI(p) ((p) & LOG_PRIMASK) /* extract priority */
-
-#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
-
-#ifdef KERNEL
-#define LOG_PRINTF -1 /* pseudo-priority to indicate use of printf */
-#endif
-
-/*
- * arguments to setlogmask.
- */
-#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
-#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
-
-/*
- * Option flags for openlog.
- *
- * LOG_ODELAY no longer does anything; LOG_NDELAY is the
- * inverse of what it used to be.
- */
-#define LOG_PID 0x01 /* log the pid with each message */
-#define LOG_CONS 0x02 /* log on the console if errors in sending */
-#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */
-#define LOG_NDELAY 0x08 /* don't delay open */
-#define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */
-
-__BEGIN_DECLS
-
-/* Syslogging functions. */
-void syslog(int pri, char *fmt, ...);
-void vsyslog(int pri, char *fmt, va_list args);
-void openlog(char *ident, int logstat, int logfac);
-void closelog(void);
-int setlogmask(int pmask);
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/include/time.h b/mit-pthreads/include/time.h
deleted file mode 100644
index 614bbeb2a59..00000000000
--- a/mit-pthreads/include/time.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _TIME_H_
-#define _TIME_H_
-
-#include <sys/__time.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef __hpux__
-struct tm {
- int tm_sec; /* seconds after the minute [0-60] */
- int tm_min; /* minutes after the hour [0-59] */
- int tm_hour; /* hours since midnight [0-23] */
- int tm_mday; /* day of the month [1-31] */
- int tm_mon; /* months since January [0-11] */
- int tm_year; /* years since 1900 */
- int tm_wday; /* days since Sunday [0-6] */
- int tm_yday; /* days since January 1 [0-365] */
- int tm_isdst; /* Daylight Savings Time flag */
- long tm_gmtoff; /* offset from CUT in seconds */
- char *tm_zone; /* timezone abbreviation */
-};
-#endif /* __hpux__ */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-/* clock_t clock __P_((void)); */
-
-char * asctime __P_((const struct tm *));
-double difftime __P_((time_t, time_t));
-char * ctime __P_((const time_t *));
-struct tm * gmtime __P_((const time_t *));
-struct tm * localtime __P_((const time_t *));
-
-char * asctime_r __P_((const struct tm *, char *));
-char * ctime_r __P_((const time_t *, char *));
-struct tm * gmtime_r __P_((const time_t *, struct tm *));
-struct tm * localtime_r __P_((const time_t *, struct tm *));
-
-time_t mktime __P_((struct tm *));
-
-/* size_t strftime __P_((char *, size_t, const char *, const struct tm *)); */
-time_t time __P_((time_t *));
-
-#if !defined(_ANSI_SOURCE)
-/* #define CLK_TCK 100 */
-extern char *tzname[2];
-void tzset __P_((void));
-#endif /* not ANSI */
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-/* char *timezone __P_((int, int)); */
-void tzsetwall __P_((void));
-#endif /* neither ANSI nor POSIX */
-
-__END_DECLS
-
-#endif /* !_TIME_H_ */
diff --git a/mit-pthreads/include/timers.h b/mit-pthreads/include/timers.h
deleted file mode 100644
index 9a0196a3631..00000000000
--- a/mit-pthreads/include/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _TIMERS_H_
-#define _TIMERS_H_
-
-#include <sys/timers.h>
-
-#endif
diff --git a/mit-pthreads/include/tzfile.h b/mit-pthreads/include/tzfile.h
deleted file mode 100644
index 7a486302e10..00000000000
--- a/mit-pthreads/include/tzfile.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Arthur David Olson of the National Cancer Institute.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)tzfile.h 5.10 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _TZFILE_H_
-#define _TZFILE_H_
-
-#include <pthread/paths.h>
-
-/*
- * Information about time zone files.
- */
-#define TZDIR _PATH_TZDIR
-#define TZDEFAULT _PATH_TZFILE
-#define TZDEFRULES "posixrules"
-
-/*
-** Each file begins with. . .
-*/
-
-struct tzhead {
- char tzh_reserved[24]; /* reserved for future use */
- char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
- char tzh_leapcnt[4]; /* coded number of leap seconds */
- char tzh_timecnt[4]; /* coded number of transition times */
- char tzh_typecnt[4]; /* coded number of local time types */
- char tzh_charcnt[4]; /* coded number of abbr. chars */
-};
-
-/*
-** . . .followed by. . .
-**
-** tzh_timecnt (char [4])s coded transition times a la time(2)
-** tzh_timecnt (unsigned char)s types of local time starting at above
-** tzh_typecnt repetitions of
-** one (char [4]) coded GMT offset in seconds
-** one (unsigned char) used to set tm_isdst
-** one (unsigned char) that's an abbreviation list index
-** tzh_charcnt (char)s '\0'-terminated zone abbreviations
-** tzh_leapcnt repetitions of
-** one (char [4]) coded leap second transition times
-** one (char [4]) total correction after above
-** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
-** time is standard time, if FALSE,
-** transition time is wall clock time
-** if absent, transition times are
-** assumed to be wall clock time
-*/
-
-/*
-** In the current implementation, "tzset()" refuses to deal with files that
-** exceed any of the limits below.
-*/
-
-/*
-** The TZ_MAX_TIMES value below is enough to handle a bit more than a
-** year's worth of solar time (corrected daily to the nearest second) or
-** 138 years of Pacific Presidential Election time
-** (where there are three time zone transitions every fourth year).
-*/
-#define TZ_MAX_TIMES 370
-
-#define NOSOLAR /* 4BSD doesn't currently handle solar time */
-
-#ifndef NOSOLAR
-#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
-#else
-#define TZ_MAX_TYPES 10 /* Maximum number of local time types */
-#endif
-
-#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
-
-#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
-
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
-
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
-
-#define TM_YEAR_BASE 1900
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
-
-/*
-** Accurate only for the past couple of centuries;
-** that will probably do.
-*/
-
-#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
-
-#endif /* !_TZFILE_H_ */
-
diff --git a/mit-pthreads/include/unistd.h b/mit-pthreads/include/unistd.h
deleted file mode 100644
index 213aa983172..00000000000
--- a/mit-pthreads/include/unistd.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/__unistd.h>
-
-#define R_OK 4
-#define W_OK 2
-#define X_OK 1
-#define F_OK 0
-
-#ifndef SEEK_SET
-#define SEEK_SET 0 /* set file offset to offset */
-#endif
-#ifndef SEEK_CUR
-#define SEEK_CUR 1 /* set file offset to current plus offset */
-#endif
-#ifndef SEEK_END
-#define SEEK_END 2 /* set file offset to EOF plus offset */
-#endif
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execve __P_((const char *, char * const *, char * const *));
-pid_t fork __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-unsigned sleep __P_((unsigned));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-/* Not implemented for threads yet */
-unsigned alarm __P_((unsigned));
-char *cuserid __P_((char *));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execvp __P_((const char *, char * const *));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, gid_t *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-
-#ifndef _POSIX_SOURCE
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-/* int chflags __P_((const char *, long)); */
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-void des_setkey __P_((const char *key));
-void encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-/* int fchflags __P_((int, long)); */
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, gid_t));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((unsigned, const char *));
-/* extern char *sys_siglist[]; */
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const gid_t *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-void setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-unsigned ualarm __P_((unsigned, unsigned));
-void usleep __P_((unsigned));
-int vfork __P_((void));
-
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/lib/.cvsignore b/mit-pthreads/lib/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/lib/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/lib/Makefile.in b/mit-pthreads/lib/Makefile.in
deleted file mode 100644
index 821d293d896..00000000000
--- a/mit-pthreads/lib/Makefile.in
+++ /dev/null
@@ -1,48 +0,0 @@
-# === GNUmakefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-CC = ../pgcc -notinstalled
-srctop = @srctop@
-srcdir = @srctop@/lib
-VPATH = @srctop@/lib
-CDEBUGFLAGS = @CFLAGS@
-
-CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
-
-#
-DIRS = libpthreadutil
-
-################################################################################
-#
-all:
- (for i in $(DIRS); do cd $$i; $(MAKE) all; cd ..; done)
-
-clean:
- (for i in $(DIRS); do cd $$i; $(MAKE) clean; cd ..; done)
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- (for i in $(DIRS); do cd $$i; $(MAKE) depend; cd ..; done)
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install:
- (for i in $(DIRS); do cd $$i; $(MAKE) install; cd ..; done)
-
-realclean: clean
- (for i in $(DIRS); do cd $$i; $(MAKE) realclean; cd ..; done)
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd .. ; sh config.status)
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/lib/libpthreadutil/.cvsignore b/mit-pthreads/lib/libpthreadutil/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/lib/libpthreadutil/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/lib/libpthreadutil/Makefile.in b/mit-pthreads/lib/libpthreadutil/Makefile.in
deleted file mode 100755
index 94034f426b3..00000000000
--- a/mit-pthreads/lib/libpthreadutil/Makefile.in
+++ /dev/null
@@ -1,65 +0,0 @@
-# === makefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-srctop = @srctop@
-srcdir = @srctop@/lib/libpthreadutil
-VPATH = @srctop@/lib/libpthreadutil
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-
-INSTALL_PATH = @exec_prefix@
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
-
- CC = ../../pgcc -notinstalled
- CDEBUGFLAGS = @CFLAGS@
- CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
- RANLIB = @RANLIB@
-
- OBJS = pthread_tad.o pthread_atexit.o
- LIBRARY = libpthreadutil.a
- HEADERS = pthreadutil.h
-
-################################################################################
-#
-all : $(LIBRARY)
-
-clean:
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install: $(LIBRARY)
- install $(LIBRARY) $(LIBDIR)
- for x in $(HEADERS); \
- do cp $(srcdir)/$$x $(INCDIR); \
- done
-
-realclean: clean
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd ../.. ; sh config.status)
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
-$(LIBRARY) : ${OBJS}
- ar r new.a ${OBJS} && \
- $(RANLIB) new.a && \
- mv -f new.a $(LIBRARY)
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/lib/libpthreadutil/pthread_atexit.c b/mit-pthreads/lib/libpthreadutil/pthread_atexit.c
deleted file mode 100755
index f244fbfb0c8..00000000000
--- a/mit-pthreads/lib/libpthreadutil/pthread_atexit.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ==== pthread_atexit.c =====================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread attribute functions.
- *
- * 1.20 94/02/13 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#define PTHREAD_KERNEL
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "pthreadutil.h"
-
-static int pthread_atexit_inited = 0;
-static pthread_key_t pthread_atexit_key;
-static pthread_mutex_t pthread_atexit_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/* ==========================================================================
- * pthread_atexit_done()
- */
-static void pthread_atexit_done(void * arg)
-{
- pthread_atexit_t id, id_next;
-
- for (id = arg; id; id = id_next) {
- id_next = id->next;
- id->rtn(id->arg);
- free(id);
- }
-}
-
-/* ==========================================================================
- * pthread_atexit_add()
- */
-int pthread_atexit_add(pthread_atexit_t *id, void (*rtn)(void *), void * arg)
-{
- int ret;
-
- if (ret = pthread_mutex_lock(&pthread_atexit_mutex)) {
- return(ret);
- }
- if (!pthread_atexit_inited) {
- if (ret = pthread_key_create(&pthread_atexit_key, pthread_atexit_done)){
- pthread_mutex_unlock(&pthread_atexit_mutex);
- return(ret);
- }
- pthread_atexit_inited++;
- }
- pthread_mutex_unlock(&pthread_atexit_mutex);
-
- if ((*id) = (pthread_atexit_t)malloc(sizeof(struct pthread_atexit))) {
- if ((*id)->next = pthread_getspecific(pthread_atexit_key)) {
- (*id)->next->prev = (*id);
- }
- pthread_setspecific(pthread_atexit_key, (void *)*id);
- (*id)->prev = NULL;
- (*id)->rtn = rtn;
- (*id)->arg = arg;
- return(OK);
- }
- return(ENOMEM);
-}
-
-/* ==========================================================================
- * pthread_atexit_remove()
- */
-int pthread_atexit_remove(pthread_atexit_t * id, int execute)
-{
- pthread_atexit_t old;
-
- if (old = pthread_getspecific(pthread_atexit_key)) {
- if (old == *id) {
- old = old->next;
- old->prev = NULL;
- pthread_setspecific(pthread_atexit_key, old);
- } else {
- if ((*id)->next) {
- (*id)->next->prev = (*id)->prev;
- }
- (*id)->prev->next = (*id)->next;
- }
- if (execute) {
- (*id)->rtn((*id)->arg);
- }
- free((*id));
- return(OK);
- }
- return(EINVAL);
-}
-
-/* ==========================================================================
- * A few non void functions that are often used as void functions
- */
-void fflush_nrv(void * fp) { fflush((FILE *)fp); }
-void fclose_nrv(void * fp) { fclose((FILE *)fp); }
-
-void pthread_attr_destroy_nrv(void * attr)
-{
- pthread_attr_destroy((pthread_attr_t *)attr);
-}
diff --git a/mit-pthreads/lib/libpthreadutil/pthread_tad.c b/mit-pthreads/lib/libpthreadutil/pthread_tad.c
deleted file mode 100755
index a59fd9b87bf..00000000000
--- a/mit-pthreads/lib/libpthreadutil/pthread_tad.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* ==== pthread_tad.c =========================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano,
- * and its contributors.
- * 4. Neither the name of Chris Provenzano, nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef lint
-static char copyright[] =
- "@(#) Copyright (c) 1995 Chris Provenzano.\nAll rights reserved.\n";
-#endif /* not lint */
-
-/* tad = thread allocation domain */
-#define PTHREAD_KERNEL
-
-#include "pthreadutil.h"
-#include <stdio.h>
-#include <errno.h>
-
-int pthread_tad_count(pthread_tad_t * tad)
-{
- int ret;
-
- pthread_mutex_lock(&tad->mutex);
- ret = tad->count_current;
- pthread_mutex_unlock(&tad->mutex);
- return(ret);
-}
-
-static void pthread_tad_done(void * arg)
-{
- pthread_tad_t * tad = arg;
- pthread_mutex_lock(&tad->mutex);
- --tad->count_current;
-/* if (--tad->count_current < tad->count_max) */
- pthread_cond_broadcast(&tad->cond);
- pthread_mutex_unlock(&tad->mutex);
-}
-
-#ifndef PTHREAD_KERNEL
-struct tad_start {
- pthread_tad_t * tad;
- void * (*routine)();
- void * arg;
-};
-
-static void * pthread_tad_start(struct tad_start * tad_start)
-{
- void * (*routine)() = tad_start->routine;
- void * arg = tad_start->arg;
-
- pthread_mutex_lock(&tad_start->tad->mutex);
- pthread_cleanup_push(pthread_tad_done, tad_start->tad);
- pthread_mutex_unlock(&tad_start->tad->mutex);
- free(tad_start);
- return(routine(arg));
-}
-#else
-static void * pthread_tad_start(void * tad_start_arg)
-{
- pthread_tad_t * tad = tad_start_arg;
- void * (*routine)() = tad->routine;
- void * arg = tad->arg;
-
- tad->count_current++;
- pthread_cleanup_push(pthread_tad_done, tad);
- pthread_mutex_unlock(&tad->mutex);
- return(routine(arg));
-}
-#endif
-
-int pthread_tad_create(pthread_tad_t * tad, pthread_t *thread_id,
- pthread_attr_t *attr, void * (*routine)(), void * arg)
-{
-#ifndef PTHREAD_KERNEL
- struct tad_start tad;
-#endif
- int ret;
-
- pthread_mutex_lock(&tad->mutex);
- while (tad->count_max && (tad->count_current > tad->count_max))
- pthread_cond_wait(&tad->cond, &tad->mutex);
-
-#ifndef PTHREAD_KERNEL
- if ((tad_start = malloc(sizeof(struct tad_start))) == NULL) {
- pthread_mutex_unlock(&tad->mutex);
- return(ENOMEM);
- }
- tad_start->routine = routine;
- tad_start->arg = arg;
- tad_start->tad = tad;
- if ((ret = pthread_create(thread_id, attr,
- pthread_tad_start, tad_start)) == OK)
- tad->count_current++;
- pthread_mutex_unlock(&tad->mutex);
-#else
- tad->routine = routine;
- tad->arg = arg;
- if (ret = pthread_create(thread_id, attr, pthread_tad_start, tad))
- pthread_mutex_unlock(&tad->mutex);
-#endif
- return(ret);
-}
-
-int pthread_tad_wait(pthread_tad_t * tad, unsigned int count)
-{
- if ((tad->count_max) && (tad->count_max < count)) {
- return(EINVAL);
- }
- pthread_mutex_lock(&tad->mutex);
- while (tad->count_current > count)
- pthread_cond_wait(&tad->cond, &tad->mutex);
- pthread_mutex_unlock(&tad->mutex);
- return(OK);
-}
-
-int pthread_tad_init(pthread_tad_t * tad, unsigned int max_count)
-{
- int ret;
-
- if ((ret = pthread_mutex_init(&tad->mutex, NULL)) == OK) {
- if (ret = pthread_cond_init(&tad->cond, NULL)) {
- pthread_mutex_destroy(&tad->mutex);
- } else {
- tad->count_max = max_count;
- tad->count_current = 0;
- }
- }
- return(ret);
-}
-
-/* User is responsible to make sure their are no threads running */
-int pthread_tad_destroy(pthread_tad_t * tad)
-{
- int ret;
-
- if ((ret = pthread_mutex_destroy(&tad->mutex)) == OK) {
- ret = pthread_cond_destroy(&tad->cond);
- } else {
- pthread_cond_destroy(&tad->cond);
- }
- tad->count_max = NOTOK;
- return(ret);
-}
diff --git a/mit-pthreads/lib/libpthreadutil/pthreadutil.h b/mit-pthreads/lib/libpthreadutil/pthreadutil.h
deleted file mode 100755
index 0d8e6a6ef5f..00000000000
--- a/mit-pthreads/lib/libpthreadutil/pthreadutil.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ==== pthread_tad.h ========================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano,
- * and its contributors.
- * 4. Neither the name of Chris Provenzano, nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <pthread.h>
-#include <sys/cdefs.h>
-
-typedef struct pthread_tad_t {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- unsigned int count_current;
- unsigned int count_max;
- void * arg;
- void * (*routine)();
-} pthread_tad_t;
-
-typedef struct pthread_atexit {
- struct pthread_atexit * next;
- struct pthread_atexit * prev;
- void (*rtn)(void *);
- void * arg;
-} * pthread_atexit_t;
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_tad_count __P_((pthread_tad_t *));
-int pthread_tad_create __P_((pthread_tad_t *, pthread_t *, pthread_attr_t *,
- void *(*routine)(), void *));
-int pthread_tad_wait __P_((pthread_tad_t *, unsigned int));
-int pthread_tad_init __P_((pthread_tad_t *, unsigned int));
-int pthread_tad_destroy __P_((pthread_tad_t *));
-
-int pthread_atexit_add __P_((pthread_atexit_t *, void (*)(void *), void *));
-int pthread_atexit_remove __P_((pthread_atexit_t *, int));
-
-
-void fclose_nrv __P_((void *));
-void fflush_nrv __P_((void *));
-void pthread_attr_destroy_nrv __P_((void *));
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__math.h b/mit-pthreads/machdep/alpha-osf1/__math.h
deleted file mode 100755
index 12fdc85678c..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__math.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ANSI required entries in math.h
- *
- */
-#ifdef _ANSI_C_SOURCE
-
-#if defined(_IEEE_FP)
-# define HUGE_VAL 1.8e308
-#else
-# define HUGE_VAL 1.797693134862315708e308
-#endif
-
-#endif /*_ANSI_C_SOURCE */
-
-
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__signal.h b/mit-pthreads/machdep/alpha-osf1/__signal.h
deleted file mode 100755
index 2bb13380314..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__signal.h
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <standards.h>
-
-typedef int sig_atomic_t; /* accessable as an atomic entity (ANSI) */
-
-/*
- * valid signal values: all undefined values are reserved for future use
- * note: POSIX requires a value of 0 to be used as the null signal in kill()
- */
-#define SIGHUP 1 /* hangup, generated when terminal disconnects */
-#define SIGINT 2 /* interrupt, generated from terminal special char */
-#define SIGQUIT 3 /* (*) quit, generated from terminal special char */
-#define SIGILL 4 /* (*) illegal instruction (not reset when caught)*/
-#define SIGTRAP 5 /* (*) trace trap (not reset when caught) */
-#define SIGABRT 6 /* (*) abort process */
-#define SIGEMT 7 /* EMT instruction */
-#define SIGFPE 8 /* (*) floating point exception */
-#define SIGKILL 9 /* kill (cannot be caught or ignored) */
-#define SIGBUS 10 /* (*) bus error (specification exception) */
-#define SIGSEGV 11 /* (*) segmentation violation */
-#define SIGSYS 12 /* (*) bad argument to system call */
-#define SIGPIPE 13 /* write on a pipe with no one to read it */
-#define SIGALRM 14 /* alarm clock timeout */
-#define SIGTERM 15 /* software termination signal */
-#define SIGURG 16 /* (+) urgent contition on I/O channel */
-#define SIGSTOP 17 /* (@) stop (cannot be caught or ignored) */
-#define SIGTSTP 18 /* (@) interactive stop */
-#define SIGCONT 19 /* (!) continue (cannot be caught or ignored) */
-#define SIGCHLD 20 /* (+) sent to parent on child stop or exit */
-#define SIGTTIN 21 /* (@) background read attempted from control terminal*/
-#define SIGTTOU 22 /* (@) background write attempted to control terminal */
-#define SIGIO 23 /* (+) I/O possible, or completed */
-#define SIGXCPU 24 /* cpu time limit exceeded (see setrlimit()) */
-#define SIGXFSZ 25 /* file size limit exceeded (see setrlimit()) */
-#define SIGVTALRM 26 /* virtual time alarm (see setitimer) */
-#define SIGPROF 27 /* profiling time alarm (see setitimer) */
-#define SIGWINCH 28 /* (+) window size changed */
-#define SIGINFO 29 /* information request */
-#define SIGUSR1 30 /* user defined signal 1 */
-#define SIGUSR2 31 /* user defined signal 2 */
-#define SIGMAX 31
-#define NSIG 31
-
-/*
- * additional signal names supplied for compatibility, only
- */
-#define SIGIOINT SIGURG /* printer to backend error signal */
-#define SIGAIO SIGIO /* base lan i/o */
-#define SIGPTY SIGIO /* pty i/o */
-#define SIGPOLL SIGIO /* STREAMS version of this signal */
-#define SIGIOT SIGABRT /* abort (terminate) process */
-#define SIGLOST SIGIOT /* old BSD signal ?? */
-#define SIGPWR SIGINFO /* Power Fail/Restart -- SVID3/SVR4 */
-#define SIGCLD SIGCHLD
-
-/*
- * valid signal action values; other values => pointer to handler function
- */
-#define SIG_DFL (void (*)())0
-#define SIG_IGN (void (*)())1
-
-/*
- * values of "how" argument to sigprocmask() call
- */
-#define SIG_BLOCK 1
-#define SIG_UNBLOCK 2
-#define SIG_SETMASK 3
-
-/*
- * sigaction structure used in sigaction() system call
- * The order of the fields in this structure must match those in
- * the sigvec structure (below).
- */
-struct sigaction {
- void (*sa_handler)(); /* signal handler, or action value */
- sigset_t sa_mask; /* signals to block while in handler */
- int sa_flags; /* signal action flags */
-};
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) ( *(s) |= 1L << ((n) - 1), 0)
-#define __SIGDELSET(s, n) ( *(s) &= ~(1L << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ( (*(s) & (1L << ((n) - 1))) != (sigset_t)0)
-
-
-#define SIGSTKSZ (16384)
-#define MINSIGSTKSZ (4096)
-
-/*
- * valid flags define for sa_flag field of sigaction structure
- */
-#define SA_ONSTACK 0x00000001 /* run on special signal stack */
-#define SA_RESTART 0x00000002 /* restart system calls on sigs */
-#define SA_NOCLDSTOP 0x00000004 /* do not set SIGCHLD for child stops*/
-#define SA_NODEFER 0x00000008 /* don't block while handling */
-#define SA_RESETHAND 0x00000010 /* old sys5 style behavior */
-#define SA_NOCLDWAIT 0x00000020 /* no zombies */
-#define SA_SIGINFO 0x00000040 /* deliver siginfo to handler */
-
-/* This is for sys/time.h */
-/* Removed for OSF1 V3.2
-typedef union sigval {
- int sival_int;
- void *sival_ptr;
-} sigval_t;
-*/
diff --git a/mit-pthreads/machdep/alpha-osf1/__stdio.h b/mit-pthreads/machdep/alpha-osf1/__stdio.h
deleted file mode 100755
index 39801b125c8..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__stdio.h
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#ifndef _FPOS_T
-#define _FPOS_T
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#define HAVE_SYS_ERRLIST_WITHOUT_CONST
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__stdlib.h b/mit-pthreads/machdep/alpha-osf1/__stdlib.h
deleted file mode 100755
index 79ca737e0c8..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__stdlib.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* bleah */
-
-#include <stddef.h>
diff --git a/mit-pthreads/machdep/alpha-osf1/__string.h b/mit-pthreads/machdep/alpha-osf1/__string.h
deleted file mode 100755
index 6558102a282..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__string.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-__BEGIN_DECLS
-
-/*
-void * memchr __P_((const void *, int , size_t ));
-void * memcpy __P_((void *, const void *, size_t ));
-void * memset __P_((void *, int , size_t ));
-size_t strcspn __P_((const char *, const char *));
-size_t strlen __P_((const char *));
-size_t strspn __P_((const char *, const char *));
-*/
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__time.h b/mit-pthreads/machdep/alpha-osf1/__time.h
deleted file mode 100755
index b4ce1ead2bf..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__time.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <pthread/types.h>
-#include <machine/machtime.h> /* CLOCKS_PER_SEC is defined here */
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef pthread_clock_t clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef pthread_time_t time_t;
-#endif
-
-#ifndef CLK_TCK
-#define CLK_TCK 60
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/__unistd.h b/mit-pthreads/machdep/alpha-osf1/__unistd.h
deleted file mode 100755
index 2a7fbe9389b..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__unistd.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <sys/types.h>
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef long ssize_t; /* Added by monty */
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/cdefs.h b/mit-pthreads/machdep/alpha-osf1/cdefs.h
deleted file mode 100755
index c9b54f033ec..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/cdefs.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#define inline
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/compat.h b/mit-pthreads/machdep/alpha-osf1/compat.h
deleted file mode 100755
index 4c2801e05de..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/compat.h
+++ /dev/null
@@ -1 +0,0 @@
-#define omsghdr msghdr
diff --git a/mit-pthreads/machdep/alpha-osf1/dirent.h b/mit-pthreads/machdep/alpha-osf1/dirent.h
deleted file mode 100755
index 697ef7b8a8c..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/dirent.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct dirent {
- ino_t d_ino;
- ushort_t d_reclen, d_namlen;
- char d_name[256];
-};
-#define d_fileno d_ino
-#define MAXNAMLEN 256
diff --git a/mit-pthreads/machdep/alpha-osf1/signal.h b/mit-pthreads/machdep/alpha-osf1/signal.h
deleted file mode 100755
index c387f9f31ad..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/signal.h
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-#include <signal.h>
diff --git a/mit-pthreads/machdep/alpha-osf1/socket.h b/mit-pthreads/machdep/alpha-osf1/socket.h
deleted file mode 100755
index 28e17ca463d..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/socket.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)socket.h 7.13 (Berkeley) 4/20/91
- */
-
-#ifndef _SOCKET_H_
-#define _SOCKET_H_
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 4 /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get/set protocol type */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_NIT 17 /* Network Interface Tap */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_ISO 19 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21
-#define AF_GOSIP 22
-#define AF_MAX 22
-
-/* Not supported by solaris */
-/* #define AF_ROUTE 17 /* Internal Routing Protocol */
-/* #define AF_LINK 18 /* Link layer interface */
-/* #define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* actually longer; address value */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NIT AF_NIT
-#define PF_802 AF_802
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_X25 AF_X25
-#define PF_OSINET AF_OSINET
-#define PF_GOSIP AF_GOSIP
-#define PF_MAX AF_MAX
-
-/* #define PF_ROUTE AF_ROUTE */
-/* #define PF_LINK AF_LINK */
-/* #define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- * Used value-result for recvmsg, value only for sendmsg.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- u_int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- u_int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_MAXIOVLEN 16
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-/* #define MSG_EOR 0x8 data completes record */
-/* #define MSG_TRUNC 0x10 data discarded before delivery */
-/* #define MSG_CTRUNC 0x20 control data lost before delivery */
-/* #define MSG_WAITALL 0x40 wait for full request or error */
-
-/*
- * Header for ancillary data objects in msg_control buffer.
- * Used for additional information with/about a datagram
- * not expressible by flags. The format is a sequence
- * of message elements headed by cmsghdr structures.
- */
-struct cmsghdr {
- u_int cmsg_len; /* data byte count, including hdr */
- int cmsg_level; /* originating protocol */
- int cmsg_type; /* protocol-specific type */
-/* followed by u_char cmsg_data[]; */
-};
-
-/* given pointer to struct adatahdr, return pointer to data */
-#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
-
-/* given pointer to struct adatahdr, return pointer to next adatahdr */
-#define CMSG_NXTHDR(mhdr, cmsg) \
- (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
- (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
- (struct cmsghdr *)NULL : \
- (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
-
-#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
-
-/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* access rights (array of int) */
-
-/*
- * 4.3 compat sockaddr, move to compat file later
- */
-struct osockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-#define SYS_socketcall 83
-
-#define SO_ACCEPT 1
-#define SO_BIND 2
-#define SO_CONNECT 3
-#define SO_GETPEERNAME 4
-#define SO_GETSOCKNAME 5
-#define SO_GETSOCKOPT 6
-#define SO_LISTEN 7
-#define SO_RECV 8
-#define SO_RECVFROM 9
-#define SO_SEND 10
-#define SO_SENDTO 11
-#define SO_SETSOCKOPT 12
-#define SO_SHUTDOWN 13
-#define SO_SOCKET 14
-#define SO_SOCKPOLL 15
-#define SO_GETIPDOMAIN 16
-#define SO_SETIPDOMAIN 17
-#define SO_ADJTIME 18
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-/* original definitions
-int recv __P_((int, void *, int, int));
-int recvfrom __P_((int, void *, int, int,
- struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-int send __P_((int, const void *, int, int));
-int sendto __P_((int, const void *, int, int, const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-*/
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int,
- struct sockaddr *, int *));
-ssize_t recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-ssize_t sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !_SOCKET_H_ */
diff --git a/mit-pthreads/machdep/alpha-osf1/timers.h b/mit-pthreads/machdep/alpha-osf1/timers.h
deleted file mode 100755
index 36317d083f0..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/timers.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/uio.h b/mit-pthreads/machdep/alpha-osf1/uio.h
deleted file mode 100755
index 8d494672ee4..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/uio.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* N.B.: The Alpha, under OSF/1, does *not* use size_t for the length,
- or for the returned values from readv and writev. */
-
-struct iovec {
- void *iov_base;
- int iov_len;
-};
-
-/* I'm assuming the iovec structures are const. I haven't verified
- it. */
-extern ssize_t readv (int, const struct iovec *, int);
-extern ssize_t writev (int, const struct iovec *, int);
diff --git a/mit-pthreads/machdep/bsdi-1.1/compat.h b/mit-pthreads/machdep/bsdi-1.1/compat.h
deleted file mode 100755
index e6f60c372c7..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-1.1/dirent.h b/mit-pthreads/machdep/bsdi-1.1/dirent.h
deleted file mode 100755
index d0272a4ee38..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/dirent.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* BSDI $Id$ */
-
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- unsigned long
- d_fileno; /* file number of entry */
- unsigned short
- d_reclen; /* length of this record */
- unsigned short
- d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-/*
- * There should probably be no need for this. In the BSDI sources,
- * it is excluded if _POSIX_SOURCE is defined, and pthreads are supposed
- * to be posix. Sources that use d_ino should really be using d_fileno.
- * mbd
- */
-#define d_ino d_fileno /* backward compatibility */
-
-#endif /* !_SYS_DIRENT_H_ */
-
diff --git a/mit-pthreads/machdep/bsdi-1.1/errno.h b/mit-pthreads/machdep/bsdi-1.1/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-1.1/socket.h b/mit-pthreads/machdep/bsdi-1.1/socket.h
deleted file mode 100755
index 39d7c1cce26..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/socket.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/* BSDI $Id$ */
-
-/*
- * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)socket.h 7.13 (Berkeley) 4/20/91
- */
-
-#ifndef _SOCKET_H_
-#define _SOCKET_H_
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_ISO 7 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_ROUTE 17 /* Internal Routing Protocol */
-#define AF_LINK 18 /* Link layer interface */
-#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-
-#define AF_MAX 20
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_char sa_len; /* total length */
- u_char sa_family; /* address family */
- char sa_data[14]; /* actually longer; address value */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_ROUTE AF_ROUTE
-#define PF_LINK AF_LINK
-#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- * Used value-result for recvmsg, value only for sendmsg.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- u_int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- u_int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_control; /* ancillary data, see below */
- u_int msg_controllen; /* ancillary data buffer len */
- int msg_flags; /* flags on received message */
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-#define MSG_EOR 0x8 /* data completes record */
-#define MSG_TRUNC 0x10 /* data discarded before delivery */
-#define MSG_CTRUNC 0x20 /* control data lost before delivery */
-#define MSG_WAITALL 0x40 /* wait for full request or error */
-
-/*
- * Header for ancillary data objects in msg_control buffer.
- * Used for additional information with/about a datagram
- * not expressible by flags. The format is a sequence
- * of message elements headed by cmsghdr structures.
- */
-struct cmsghdr {
- u_int cmsg_len; /* data byte count, including hdr */
- int cmsg_level; /* originating protocol */
- int cmsg_type; /* protocol-specific type */
-/* followed by u_char cmsg_data[]; */
-};
-
-/* given pointer to struct adatahdr, return pointer to data */
-#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
-
-/* given pointer to struct adatahdr, return pointer to next adatahdr */
-#define CMSG_NXTHDR(mhdr, cmsg) \
- (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
- (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
- (struct cmsghdr *)NULL : \
- (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
-
-#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
-
-/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* access rights (array of int) */
-
-/*
- * 4.3 compat sockaddr, move to compat file later
- */
-struct osockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * 4.3-compat message header (move to compat file later).
- */
-struct omsghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#ifndef KERNEL
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-/* original definitions
-int recv __P_((int, void *, int, int));
-int recvfrom __P_((int, void *, int, int,
- struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-int send __P_((int, const void *, int, int));
-int sendto __P_((int, const void *, int, int, const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-*/
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int,
- struct sockaddr *, int *));
-ssize_t recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-ssize_t sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !KERNEL */
-
-#endif /* !_SOCKET_H_ */
diff --git a/mit-pthreads/machdep/bsdi-1.1/timers.h b/mit-pthreads/machdep/bsdi-1.1/timers.h
deleted file mode 100755
index 7101ab99106..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/timers.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/__math.h b/mit-pthreads/machdep/bsdi-2.0/__math.h
deleted file mode 100755
index 2c919472f33..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-/* Generate an overflow to create +Inf; the multiply shuts up gcc 1 */
-#define HUGE_VAL (1e250*1e250) /* IEEE: positive infinity */
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/__path.h b/mit-pthreads/machdep/bsdi-2.0/__path.h
deleted file mode 100755
index 9c347016f5f..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__path.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __path.h,v 1.1 1995/01/03 12:53:32 proven Exp
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__signal.h b/mit-pthreads/machdep/bsdi-2.0/__signal.h
deleted file mode 100755
index d3deecf15e2..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__signal.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
diff --git a/mit-pthreads/machdep/bsdi-2.0/__stdio.h b/mit-pthreads/machdep/bsdi-2.0/__stdio.h
deleted file mode 100755
index d4d37c2017c..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__stdio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__stdlib.h b/mit-pthreads/machdep/bsdi-2.0/__stdlib.h
deleted file mode 100755
index 189bb5e8799..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__stdlib.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __stdlib.h,v 1.1 1995/01/03 12:53:34 proven Exp
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__string.h b/mit-pthreads/machdep/bsdi-2.0/__string.h
deleted file mode 100755
index 275032946ea..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__string.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/__time.h b/mit-pthreads/machdep/bsdi-2.0/__time.h
deleted file mode 100755
index bc4d956486d..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__time.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __time.h,v 1.1 1994/12/13 07:18:55 proven Exp
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__unistd.h b/mit-pthreads/machdep/bsdi-2.0/__unistd.h
deleted file mode 100755
index 4a5ee6a245e..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__unistd.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __unistd.h,v 1.1 1995/01/03 12:53:35 proven Exp
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type unsigned long /* For fd.c */
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE ((unsigned char)'\377')
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/compat.h b/mit-pthreads/machdep/bsdi-2.0/compat.h
deleted file mode 100755
index 0dfdc27f9e8..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/compat.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/dirent.h b/mit-pthreads/machdep/bsdi-2.0/dirent.h
deleted file mode 100755
index 0dfdc27f9e8..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/dirent.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/errno.h b/mit-pthreads/machdep/bsdi-2.0/errno.h
deleted file mode 100755
index 1a3c37d0147..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/errno.h
+++ /dev/null
@@ -1,162 +0,0 @@
-
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/time.h b/mit-pthreads/machdep/bsdi-2.0/time.h
deleted file mode 100755
index a8bf0ff8f82..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/time.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef ts_sec
-#define ts_sec tv_sec
-#define ts_nsec tv_nsec
-#endif
-#include "/usr/include/sys/time.h"
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/timers.h b/mit-pthreads/machdep/bsdi-2.0/timers.h
deleted file mode 100755
index b603b78e6b2..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * timers.h,v 1.50 1994/08/08 03:44:09 proven Exp
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/wait.h b/mit-pthreads/machdep/bsdi-2.0/wait.h
deleted file mode 100755
index 5f7635a73a7..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/wait.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.c b/mit-pthreads/machdep/engine-alpha-netbsd-1.1.c
deleted file mode 100644
index c1ff04db16d..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD/Alpha 1.1(+)
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 95/04/22 cgd
- * -Modified to make it go with NetBSD/Alpha
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return __machdep_save_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_restore_state(void)
-{
- __machdep_restore_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_save_float_state (void)
-{
- __machdep_save_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-void machdep_restore_float_state (void)
-{
- __machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- machdep_pthread->machdep_istate[8/*ISTATE_RA*/] = 0;
- machdep_pthread->machdep_istate[0/*ISTATE_PC*/] = (long)machdep_pthread_start;
- machdep_pthread->machdep_istate[10/*ISTATE_PV*/] = (long)machdep_pthread_start;
-
- /* Alpha stack starts high and builds down. */
- {
- long stk_addr = (long) machdep_pthread->machdep_stack;
- stk_addr += stack_size - 1024;
- stk_addr &= ~15;
- machdep_pthread->machdep_istate[9/*ISTATE_SP*/] = stk_addr;
- }
-}
-
-int safe_store (loc, new)
- int *loc;
- int new;
-{
- int locked, old;
- asm ("mb" : : : "memory");
- do {
- asm ("ldl_l %0,%1" : "=r" (old) : "m" (*loc));
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*loc) : "0" (new));
- } while (!locked);
- asm ("mb" : : : "memory");
- return old;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- extern off_t __syscall();
-
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.h b/mit-pthreads/machdep/engine-alpha-netbsd-1.1.h
deleted file mode 100644
index 50c872da7b6..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/* The first machine dependent functions are the SEMAPHORES needing
- the test and set instruction.
-
- On the Alpha, the actual values here are irrelevant; they just have
- to be different. */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ int *_sem_lock = (lock), locked, old; \
- asm ("mb" : : : "memory"); \
- do { asm ("ldl_l %0,%1" : "=r" (old) : "m" (*_sem_lock)); \
- /* ?? if (old != SEMAPHORE_CLEAR) break; */ \
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*_sem_lock) \
- : "0" (SEMAPHORE_SET)); \
- } while (!locked); \
- asm ("mb" : : : "memory"); \
- old == SEMAPHORE_CLEAR; })
-
-#define SEMAPHORE_RESET(lock) \
-({ int *_sem_lock = (lock); \
- *_sem_lock = SEMAPHORE_CLEAR; \
- asm ("mb" : : : "memory"); })
-#endif
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- unsigned long machdep_istate[11];
- unsigned long machdep_fstate[9];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-int __machdep_save_int_state __P_((unsigned long *));
-void __machdep_restore_int_state __P_((unsigned long *));
-void __machdep_save_fp_state __P_((unsigned long *));
-void __machdep_restore_fp_state __P_((unsigned long *));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.c b/mit-pthreads/machdep/engine-alpha-netbsd-1.3.c
deleted file mode 100644
index 0932c421ea2..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD/Alpha 1.1(+)
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 95/04/22 cgd
- * -Modified to make it go with NetBSD/Alpha
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return __machdep_save_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_restore_state(void)
-{
- __machdep_restore_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_save_float_state (void)
-{
- __machdep_save_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-void machdep_restore_float_state (void)
-{
- __machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- machdep_pthread->machdep_istate[8/*ISTATE_RA*/] = 0;
- machdep_pthread->machdep_istate[0/*ISTATE_PC*/] = (long)machdep_pthread_start;
- machdep_pthread->machdep_istate[10/*ISTATE_PV*/] = (long)machdep_pthread_start;
-
- /* Alpha stack starts high and builds down. */
- {
- long stk_addr = (long) machdep_pthread->machdep_stack;
- stk_addr += stack_size - 1024;
- stk_addr &= ~15;
- machdep_pthread->machdep_istate[9/*ISTATE_SP*/] = stk_addr;
- }
-}
-
-int safe_store (loc, new)
- int *loc;
- int new;
-{
- int locked, old;
- asm ("mb" : : : "memory");
- do {
- asm ("ldl_l %0,%1" : "=r" (old) : "m" (*loc));
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*loc) : "0" (new));
- } while (!locked);
- asm ("mb" : : : "memory");
- return old;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- extern off_t __syscall();
-
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.h b/mit-pthreads/machdep/engine-alpha-netbsd-1.3.h
deleted file mode 100644
index bc4178d3c41..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/* The first machine dependent functions are the SEMAPHORES needing
- the test and set instruction.
-
- On the Alpha, the actual values here are irrelevant; they just have
- to be different. */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ int *_sem_lock = (lock), locked, old; \
- asm ("mb" : : : "memory"); \
- do { asm ("ldl_l %0,%1" : "=r" (old) : "m" (*_sem_lock)); \
- /* ?? if (old != SEMAPHORE_CLEAR) break; */ \
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*_sem_lock) \
- : "0" (SEMAPHORE_SET)); \
- } while (!locked); \
- asm ("mb" : : : "memory"); \
- old == SEMAPHORE_CLEAR; })
-
-#define SEMAPHORE_RESET(lock) \
-({ int *_sem_lock = (lock); \
- *_sem_lock = SEMAPHORE_CLEAR; \
- asm ("mb" : : : "memory"); })
-#endif
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- unsigned long machdep_istate[11];
- unsigned long machdep_fstate[9];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-int __machdep_save_int_state __P_((unsigned long *));
-void __machdep_restore_int_state __P_((unsigned long *));
-void __machdep_save_fp_state __P_((unsigned long *));
-void __machdep_restore_fp_state __P_((unsigned long *));
-
-extern off_t machdep_sys_lseek(int, off_t, int);
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-alpha-osf1.c b/mit-pthreads/machdep/engine-alpha-osf1.c
deleted file mode 100644
index 9b563a56c28..00000000000
--- a/mit-pthreads/machdep/engine-alpha-osf1.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-
-/* These would be defined in setjmp.h, if _POSIX_SOURCE and _XOPEN_SOURCE
- were both undefined. But we've already included it, and lost the
- opportunity. */
-#define JB_PC 2
-#define JB_RA 30
-#define JB_PV 31
-#define JB_SP 34
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return setjmp (pthread_run->machdep_data.machdep_state);
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-extern void machdep_restore_from_setjmp (jmp_buf, long);
-void machdep_restore_state(void)
-{
- machdep_restore_from_setjmp (pthread_run->machdep_data.machdep_state, 1);
-}
-
-void machdep_save_float_state (void) { }
-void machdep_restore_float_state (void) { }
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- machdep_pthread->machdep_state[JB_RA] = 0;
- machdep_pthread->machdep_state[JB_PC] = (long)machdep_pthread_start;
- machdep_pthread->machdep_state[JB_PV] = (long)machdep_pthread_start;
-
- /* Alpha stack starts high and builds down. */
- {
- long stk_addr = (long) machdep_pthread->machdep_stack;
- stk_addr += stack_size - 1024;
- stk_addr &= ~15;
- machdep_pthread->machdep_state[JB_SP] = stk_addr;
- }
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int pid, int * statusp, int options)
-{
- return machdep_sys_wait4 (pid, statusp, options, NULL);
-}
-
-/* These are found in flsbuf.o in the Alpha libc. I don't know what
- they're for, precisely. */
-static xxx;
-_bufsync (p)
- char *p;
-{
- long a1 = *(long *)(p+48);
- long t0 = *(long *)(p+8);
- long v0 = a1 - t0;
- long t1, t2;
-
- abort ();
-
- v0 += xxx;
- if (v0 < 0)
- {
- *(char**)(p + 8) = p;
- return v0;
- }
- t1 = *(int*)p;
- t2 = v0 - t1;
- if (t2 < 0)
- *(int*)p = (int) v0;
- return v0;
-}
-
-_findbuf () { abort (); }
-_wrtchk () { abort (); }
-_xflsbuf () { abort (); }
-_flsbuf () { abort (); }
-
-void __xxx_never_called () {
- /* Force other stuff to get dragged in. */
- _cleanup ();
- fflush (NULL);
- fclose (NULL);
-}
-
-int safe_store (loc, new)
- int *loc;
- int new;
-{
- int locked, old;
- asm ("mb" : : : "memory");
- do {
- asm ("ldl_l %0,%1" : "=r" (old) : "m" (*loc));
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*loc) : "0" (new));
- } while (!locked);
- asm ("mb" : : : "memory");
- return old;
-}
diff --git a/mit-pthreads/machdep/engine-alpha-osf1.h b/mit-pthreads/machdep/engine-alpha-osf1.h
deleted file mode 100644
index fdf374ccc44..00000000000
--- a/mit-pthreads/machdep/engine-alpha-osf1.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * $Id$
- *
- */
-
-#ifndef sigwait
-#define sigwait __bogus_osf1_sigwait
-#endif
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-#undef sigwait
-
-/* The first machine dependent functions are the SEMAPHORES needing
- the test and set instruction.
-
- On the Alpha, the actual values here are irrelevant; they just have
- to be different. */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ int *_sem_lock = (lock), locked, old; \
- asm ("mb" : : : "memory"); \
- do { asm ("ldl_l %0,%1" : "=r" (old) : "m" (*_sem_lock)); \
- /* ?? if (old != SEMAPHORE_CLEAR) break; */ \
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*_sem_lock) \
- : "0" (SEMAPHORE_SET)); \
- } while (!locked); \
- asm ("mb" : : : "memory"); \
- old == SEMAPHORE_CLEAR; })
-
-#define SEMAPHORE_RESET(lock) \
-({ int *_sem_lock = (lock); \
- *_sem_lock = SEMAPHORE_CLEAR; \
- asm ("mb" : : : "memory"); })
-#endif
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.c b/mit-pthreads/machdep/engine-arm32-netbsd-1.3.c
deleted file mode 100644
index 510b35fdb0e..00000000000
--- a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD on arm32
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 98/10/22 bad
- * -adapt from i386 version
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-#if defined(_JB_REG_R13)
-#define REG_LR _JB_REG_R14
-#define REG_SP _JB_REG_R13
-#else
-#define REG_LR JMPBUF_REG_R14
-#define REG_SP JMPBUF_REG_R13
-#endif
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[REG_LR] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[REG_SP] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.h b/mit-pthreads/machdep/engine-arm32-netbsd-1.3.h
deleted file mode 100644
index c8a4e79386a..00000000000
--- a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Id: engine-i386-netbsd-1.3.h,v 1.1 1998/02/28 04:53:15 cjs Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-#endif
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-#if 0
- char machdep_float_state[108];
-#endif
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-10.20.c b/mit-pthreads/machdep/engine-hppa-hpux-10.20.c
deleted file mode 100644
index f6f0b2e0f1d..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-10.20.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for HP-UX 9.03 on hppa
- *
- * 1.00 93/12/14 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-volatile int setupStack = 0;
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state()
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(jmp_buf j)
-{
- setjmp(j);
- if( setupStack )
- return;
-
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- jmp_buf tmp_jmp_buf;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /*
- * Set up new stack frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- setjmp(machdep_pthread->machdep_state);
-
- /* get the stack frame from the real machdep_pthread_start */
- setupStack = 1;
-/* machdep_pthread_start(machdep_pthread->machdep_state); */
- machdep_pthread_start(tmp_jmp_buf);
- setupStack = 0;
-
- /* copy over the interesting part of the frame */
- ((int *)machdep_pthread->machdep_state)[44] = ((int *)tmp_jmp_buf)[44];
-
- /* Stack starts low and builds up, but needs two start frames */
- ((int *)machdep_pthread->machdep_state)[1] =
- (int)machdep_pthread->machdep_stack + (64 * 2);
-}
-
-int machdep_sys_getdtablesize()
-{
- return sysconf(_SC_OPEN_MAX);
-}
-
-void sig_check_and_resume()
-{
- return;
-}
-
-void ___exit(int status)
-{
- exit(status);
- PANIC();
-}
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-10.20.h b/mit-pthreads/machdep/engine-hppa-hpux-10.20.h
deleted file mode 100644
index 9cbe3349a3d..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-10.20.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * Stuff for compiling
- */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const
-#endif
-#define inline
-#define signed
-#define volatile
-#endif
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- *
- * Note: The set and clear defines are backwards.
- */
-#define SEMAPHORE_CLEAR { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
-#define SEMAPHORE_SET 0
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long real_addr; \
-long temp; \
- \
-real_addr = ((long)((*lock) + 15) & ~15); \
- \
-__asm__ volatile("ldcwx %%r0(%2),%0" \
- :"=r" (temp) \
- :"0" (temp),"r" (real_addr)); \
-temp ? 0 : 1; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-({ \
-char *real_addr; \
- \
-real_addr = (char*)((long)((*lock) + 15) & ~15); \
-*real_addr = 0xff; \
-})
-
-/*
- * New types
- * The semaphore is really 16 bytes but must be aligened on a 16 byte
- * boundary. By specifing 31 bytes the macros can frob it correctly.
- */
-typedef char semaphore[31];
-
-/*
- * Macros for sigset_t
- */
-#define SIGMAX 30
-/* see hpux-9.03/__signal.h for SIG_ANY */
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- /* long machdep_state[_JBLEN]; */
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 4096
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * page size
- */
-#define getpagesize() 4096
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-9.03.c b/mit-pthreads/machdep/engine-hppa-hpux-9.03.c
deleted file mode 100644
index 3770a2e106a..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-9.03.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for HP-UX 9.03 on hppa
- *
- * 1.00 93/12/14 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state()
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- ((int *)machdep_pthread->machdep_state)[0] = (int)machdep_pthread_start;
-
- /* Stack starts low and builds up, but needs two start frames */
- ((int *)machdep_pthread->machdep_state)[1] =
- (int)machdep_pthread->machdep_stack + (64 * 2);
-}
-
-int machdep_sys_getdtablesize()
-{
- return sysconf(_SC_OPEN_MAX);
-}
-
-void sig_check_and_resume()
-{
- return;
-}
-
-void ___exit(int status)
-{
- exit(status);
- PANIC();
-}
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-9.03.h b/mit-pthreads/machdep/engine-hppa-hpux-9.03.h
deleted file mode 100644
index 7c599400e3e..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-9.03.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * Stuff for compiling
- */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const
-#define inline
-#define signed
-#define volatile
-#endif
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- *
- * Note: The set and clear defines are backwards.
- */
-#define SEMAPHORE_CLEAR { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
-#define SEMAPHORE_SET 0
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long real_addr; \
-long temp; \
- \
-real_addr = ((long)((*lock) + 15) & ~15); \
- \
-__asm__ volatile("ldcwx %%r0(%2),%0" \
- :"=r" (temp) \
- :"0" (temp),"r" (real_addr)); \
-temp ? 0 : 1; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-({ \
-char *real_addr; \
- \
-real_addr = (char*)((long)((*lock) + 15) & ~15); \
-*real_addr = 0xff; \
-})
-
-/*
- * New types
- * The semaphore is really 16 bytes but must be aligened on a 16 byte
- * boundary. By specifing 31 bytes the macros can frob it correctly.
- */
-typedef char semaphore[31];
-
-/*
- * Macros for sigset_t
- */
-#define SIGMAX 30
-/* see hpux-9.03/__signal.h for SIG_ANY */
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- /* long machdep_state[_JBLEN]; */
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 4096
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * page size
- */
-#define getpagesize() 4096
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-1.1.c b/mit-pthreads/machdep/engine-i386-bsdi-1.1.c
deleted file mode 100644
index da78bef393e..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-1.1.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-machdep_sys_send(int s, const void *buf, int len, int flags)
-{
- return(machdep_sys_sendto(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-machdep_sys_recv(int s, void *buf, int len, int flags)
-{
- return(machdep_sys_recvfrom(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-1.1.h b/mit-pthreads/machdep/engine-i386-bsdi-1.1.h
deleted file mode 100644
index 7f7b8a62d06..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-1.1.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-2.0.c b/mit-pthreads/machdep/engine-i386-bsdi-2.0.c
deleted file mode 100644
index 63a6de1b092..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-2.0.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-2.0.h b/mit-pthreads/machdep/engine-i386-bsdi-2.0.h
deleted file mode 100644
index 3be254b4090..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-2.0.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * engine-i386-netbsd-1.0.h,v 1.53 1994/12/13 07:17:23 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK|O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-1.1.c b/mit-pthreads/machdep/engine-i386-freebsd-1.1.c
deleted file mode 100644
index 422193e77e3..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-1.1.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-machdep_sys_send(int s, const void *buf, int len, int flags)
-{
- return(machdep_sys_sendto(s, buf, len, flags, NULL, 0));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-machdep_sys_recv(int s, void *buf, int len, int flags)
-{
- return(machdep_sys_recvfrom(s, buf, len, flags, NULL, 0));
-}
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-1.1.h b/mit-pthreads/machdep/engine-i386-freebsd-1.1.h
deleted file mode 100644
index 0e8e93bdbfb..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-1.1.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-2.0.c b/mit-pthreads/machdep/engine-i386-freebsd-2.0.c
deleted file mode 100644
index 3b6b8f31ae0..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-2.0.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-i386-freebsd-2.0.c,v 1.1 1995/03/01 01:21:20 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(machdep_sys_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- machdep_sys_longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- machdep_sys_setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->_jb[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->_jb[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-2.0.h b/mit-pthreads/machdep/engine-i386-freebsd-2.0.h
deleted file mode 100644
index 87ef21389ce..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-2.0.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-linux-1.0.c b/mit-pthreads/machdep/engine-i386-linux-1.0.c
deleted file mode 100644
index fac044fe47c..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-1.0.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for Linux-1.0 on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-#include <sys/param.h> /* for OPEN_MAX */
-#include <sys/socket.h>
-#include <sys/socketcall.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flag)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->__pc = (char *)machdep_pthread_start;
- machdep_pthread->machdep_state->__bp = (char *)0;/* So the backtrace
- * is sensible (mevans) *
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->__sp =
- (char *)machdep_pthread->machdep_stack + stack_size;
-}
-
-
-/* ==========================================================================
- * Linux Socket calls are a bit different
- * ==========================================================================
- * machdep_sys_socket()
- */
-int machdep_sys_socket(int a, int b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SOCKET, array));
-}
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-int machdep_sys_accept(int a, struct sockaddr * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_ACCEPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-int machdep_sys_bind(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_BIND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-int machdep_sys_connect(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_CONNECT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-int machdep_sys_listen(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_LISTEN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-int machdep_sys_shutdown(int a, int b)
-{
- int array[2];
-
- array[0] = (int)a;
- array[1] = (int)b;
-
- return(machdep_sys_socketcall(SYS_SHUTDOWN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-int machdep_sys_getsockopt(int a, int b, int c, char *d, int *e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_GETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_setsockopt()
- */
-int machdep_sys_setsockopt(int a, int b, int c, char *d, int e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_SETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-int machdep_sys_getpeername(int a, struct sockaddr *b, int *c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETPEERNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-int machdep_sys_send(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SEND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-int machdep_sys_sendto(int a, char *b, int c, int d,
- struct sockaddr *e, int f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_SENDTO, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-int machdep_sys_recv(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_RECV, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-int machdep_sys_recvfrom(int a, char *b, int c, int d,
- struct sockaddr *e, int *f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_RECVFROM, array));
-}
-
-/* ==========================================================================
- * machdep_sys_socketpair()
- */
-int machdep_sys_socketpair(int a, int b, int c, int d[2])
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SOCKETPAIR, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-int machdep_sys_getsockname(int a, char * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETSOCKNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-int machdep_sys_sendmsg(int a, char * b, int c)
-{
-#ifdef SYS_SENDMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SENDMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-int machdep_sys_recvmsg(int a, char * b, int c)
-{
-#ifdef SYS_RECVMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_RECVMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- int ret;
-
- if ((ret = machdep_sys_readdir(fd, buf, 1)) > 0) {
- return(1);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* getdtablesize */
-machdep_sys_getdtablesize ()
-{
- return OPEN_MAX;
-}
-
-struct stat;
-
-/* ==========================================================================
- * _fxstat()
- */
-int _fxstat(int __ver, int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * _lxstat()
- */
-int _lxstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * _xstat()
- */
-int _xstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * strtol()
- */
-__strtol_internal(char * a, char ** b, int c)
-{
- return(strtol(a, b, c));
-}
-
-
diff --git a/mit-pthreads/machdep/engine-i386-linux-1.0.h b/mit-pthreads/machdep/engine-i386-linux-1.0.h
deleted file mode 100644
index 721618a6f19..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-1.0.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- */
-
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-volatile long temp = SEMAPHORE_SET; \
- \
-__asm__("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-linux-2.0.c b/mit-pthreads/machdep/engine-i386-linux-2.0.c
deleted file mode 100644
index 72c757fe08a..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-2.0.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for Linux-1.0 on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-#include <sys/param.h> /* for OPEN_MAX */
-#include <sys/socket.h>
-#include <sys/socketcall.h>
-#include <linux/net.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flag)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->__jmpbuf[JB_PC]= (int) (char *)machdep_pthread_start;
- /* Fix so that the backtrace * is sensible (mevans) */
- machdep_pthread->machdep_state->__jmpbuf[JB_BP] = (int) (char *) 0;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->__jmpbuf[JB_SP]=
- (int) (char *) machdep_pthread->machdep_stack + stack_size;
-}
-
-
-/* ==========================================================================
- * Linux Socket calls are a bit different
- * ==========================================================================
- * machdep_sys_socket()
- */
-int machdep_sys_socket(int a, int b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SOCKET, array));
-}
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-int machdep_sys_accept(int a, struct sockaddr * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_ACCEPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-int machdep_sys_bind(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_BIND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-int machdep_sys_connect(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_CONNECT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-int machdep_sys_listen(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_LISTEN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-int machdep_sys_shutdown(int a, int b)
-{
- int array[2];
-
- array[0] = (int)a;
- array[1] = (int)b;
-
- return(machdep_sys_socketcall(SYS_SHUTDOWN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-int machdep_sys_getsockopt(int a, int b, int c, char *d, int *e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_GETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_setsockopt()
- */
-int machdep_sys_setsockopt(int a, int b, int c, char *d, int e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_SETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-int machdep_sys_getpeername(int a, struct sockaddr *b, int *c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETPEERNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-int machdep_sys_send(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SEND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-int machdep_sys_sendto(int a, char *b, int c, int d,
- struct sockaddr *e, int f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_SENDTO, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-int machdep_sys_recv(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_RECV, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-int machdep_sys_recvfrom(int a, char *b, int c, int d,
- struct sockaddr *e, int *f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_RECVFROM, array));
-}
-
-/* ==========================================================================
- * machdep_sys_socketpair()
- */
-int machdep_sys_socketpair(int a, int b, int c, int d[2])
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SOCKETPAIR, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-int machdep_sys_getsockname(int a, char * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETSOCKNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-int machdep_sys_sendmsg(int a, char * b, int c)
-{
-#ifdef SYS_SENDMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SENDMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-int machdep_sys_recvmsg(int a, char * b, int c)
-{
-#ifdef SYS_RECVMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_RECVMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- int ret;
-
- if ((ret = machdep_sys_readdir(fd, buf, 1)) > 0) {
- return(1);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* getdtablesize */
-machdep_sys_getdtablesize ()
-{
- return OPEN_MAX;
-}
-
-struct stat;
-
-/* ==========================================================================
- * _fxstat()
- */
-int _fxstat(int __ver, int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * _lxstat()
- */
-int _lxstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * _xstat()
- */
-int _xstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * strtol()
- */
-__strtol_internal(char * a, char ** b, int c)
-{
- return(strtol(a, b, c));
-}
-
-
diff --git a/mit-pthreads/machdep/engine-i386-linux-2.0.h b/mit-pthreads/machdep/engine-i386-linux-2.0.h
deleted file mode 100644
index f4f75621226..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-2.0.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- */
-
-/* Avoid problem with including bits/pthreadtypes.h with libc 2.2 */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-volatile long temp = SEMAPHORE_SET; \
- \
-__asm__("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-0.9.c b/mit-pthreads/machdep/engine-i386-netbsd-0.9.c
deleted file mode 100644
index c42363fdeda..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-0.9.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-machdep_sys_send(int s, const void *buf, int len, int flags)
-{
- return(machdep_sys_sendto(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-machdep_sys_recv(int s, void *buf, int len, int flags)
-{
- return(machdep_sys_recvfrom(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-0.9.h b/mit-pthreads/machdep/engine-i386-netbsd-0.9.h
deleted file mode 100644
index 0e8e93bdbfb..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-0.9.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.0.c b/mit-pthreads/machdep/engine-i386-netbsd-1.0.c
deleted file mode 100644
index 7f31cb0305d..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.0.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.0.h b/mit-pthreads/machdep/engine-i386-netbsd-1.0.h
deleted file mode 100644
index 80e17fef368..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.0.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.3.c b/mit-pthreads/machdep/engine-i386-netbsd-1.3.c
deleted file mode 100644
index f86a9e5ba56..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.3.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.3.h b/mit-pthreads/machdep/engine-i386-netbsd-1.3.h
deleted file mode 100644
index f399c4b34b6..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.3.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-openbsd-2.0.c b/mit-pthreads/machdep/engine-i386-openbsd-2.0.c
deleted file mode 100644
index 09ff0072fdc..00000000000
--- a/mit-pthreads/machdep/engine-i386-openbsd-2.0.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-i386-freebsd-2.0.c,v 1.1 1995/03/01 01:21:20 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(machdep_sys_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- machdep_sys_longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- machdep_sys_setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
diff --git a/mit-pthreads/machdep/engine-i386-openbsd-2.0.h b/mit-pthreads/machdep/engine-i386-openbsd-2.0.h
deleted file mode 100644
index 87ef21389ce..00000000000
--- a/mit-pthreads/machdep/engine-i386-openbsd-2.0.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-sco-3.2v5.c b/mit-pthreads/machdep/engine-i386-sco-3.2v5.c
deleted file mode 100755
index 95f0d757585..00000000000
--- a/mit-pthreads/machdep/engine-i386-sco-3.2v5.c
+++ /dev/null
@@ -1,1072 +0,0 @@
-
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for SCO3.2v5 on i386
- *
- * 1.00 96/11/21 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-i386-freebsd-2.0.c,v 1.1 1995/03/01 01:21:20 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/timeb.h>
-#include <sys/stat.h>
-#include <stropts.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/unistd.h>
-#include <sys/utsname.h>
-#include <sys/sysi86.h>
-
-void machdep_sys_abort(char*fname,int lineno)
-
-{
- char buf[128];
-
- sprintf(buf,"panic: %s => %d\n", fname, lineno);
- machdep_sys_write(1, buf, strlen(buf));
- abort();
-}
-
-#if 0
-int setitimer(int which, struct itimerval* value, struct itimerval* ovalue)
-
-{
- register int ret;
- if ((ret = machdep_sys_setitimer(which,value,ovalue))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-#endif
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (machdep_sys_setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = machdep_sys_setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = machdep_sys_setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[JB_PC] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[JB_SP] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
-#if 0
- return(machdep_sys_wait4(0, b, c, d));
-#else
- return -ENOSYS;
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-machdep_sys_fstat(int f, struct stat* b)
-{
- return machdep_sys_fxstat(0x33, f, b);
-}
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-machdep_sys_dup2(int a, int b)
-{
- machdep_sys_close(b);
- return machdep_sys_fcntl(a, F_DUPFD, b);
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-
-{
- register int ret;
- if ((ret = machdep_sys_sysconf(_SC_OPEN_MAX))<0)
- PANIC();
- return ret;
-}
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-machdep_sys_fchown(int fd,uid_t owner,gid_t group)
-
-{
- return -ENOSYS;
-}
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-machdep_sys_fchmod(int fd,mode_t mode)
-
-{
- return -ENOSYS;
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-
-/* ==========================================================================
- * SCO Socket calls are a bit different
- * ==========================================================================
- * machdep_sys_socket()
- */
-int machdep_sys_socket(int domain, int type, int protocol)
-{
- register int s, fd, ret;
- struct socksysreq req;
-
- if ((s = machdep_sys_open("/dev/socksys", 0))<0)
- return s;
-
- req.args[0] = SO_SOCKET;
- req.args[1] = (int)domain;
- req.args[2] = (int)type;
- req.args[3] = (int)protocol;
- if ((fd = machdep_sys_ioctl(s, SIOCSOCKSYS, &req))<0) {
- machdep_sys_close(s);
- return fd;
- }
-
- if ((ret=machdep_sys_dup2(fd, s))<0) {
- machdep_sys_close(fd);
- return ret;
- }
-
- machdep_sys_close(fd);
- return s;
-
-}
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-int machdep_sys_accept(int s, struct sockaddr * b, int * c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_ACCEPT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-int machdep_sys_bind(int s, const struct sockaddr * b, int c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_BIND;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-int machdep_sys_connect(int s, const struct sockaddr * b, int c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_CONNECT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-int machdep_sys_listen(int s, int backlog)
-{
- struct socksysreq req;
-
- req.args[0] = SO_LISTEN;
- req.args[1] = (int)s;
- req.args[2] = (int)backlog;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-int machdep_sys_shutdown(int s, int b)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SHUTDOWN;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-int machdep_sys_getsockopt(int s, int b, int c, char *d, int *e)
-{
- struct socksysreq req;
-
- req.args[0] = SO_GETSOCKOPT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
- req.args[5] = (int)e;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_setsockopt()
- */
-int machdep_sys_setsockopt(int s, int b, int c, char *d, int e)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SETSOCKOPT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
- req.args[5] = (int)e;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-int machdep_sys_getpeername(int s, struct sockaddr *b, int *c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_GETPEERNAME;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-int machdep_sys_send(int s, char *b, int c, int d)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SEND;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-int machdep_sys_sendto(int s, char *b, int c, int d,
- struct sockaddr *e, int f)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SENDTO;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
- req.args[5] = (int)e;
- req.args[6] = (int)f;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-int machdep_sys_recv(int s, char *b, int c, int d)
-{
- struct socksysreq req;
-
- req.args[0] = SO_RECV;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-int machdep_sys_recvfrom(int s, char *buf, int len, int flags,
- struct sockaddr *from, int *fromlen)
-{
- struct socksysreq req;
-
- req.args[0] = SO_RECVFROM;
- req.args[1] = (int)s;
- req.args[2] = (int)buf;
- req.args[3] = (int)len;
- req.args[4] = (int)flags;
- req.args[5] = (int)from;
- req.args[6] = (int)fromlen;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_socketpair()
- */
-int machdep_sys_socketpair(int d, int type, int protocol, int sv[2])
-
-{
- register int s1, s2;
- register int ret;
- struct socksysreq req;
-
- if (d != AF_UNIX)
- return -EPROTONOSUPPORT;
- if ((s1=machdep_sys_socket(d,type,protocol))<0) {
- return s1;
- }
- if ((s2=machdep_sys_socket(d,type,protocol))<0) {
- machdep_sys_close(s1);
- return s2;
- }
- req.args[0] = SO_SOCKPAIR;
- req.args[1] = s1;
- req.args[2] = s2;
- if ((ret=machdep_sys_ioctl(s1,SIOCSOCKSYS,&req))<0) {
- machdep_sys_close(s1);
- machdep_sys_close(s2);
- return ret;
- }
- sv[0] = s1;
- sv[1] = s2;
- return 0;
-}
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-int machdep_sys_getsockname(int s, char * b, int * c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_GETSOCKNAME;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-int machdep_sys_sendmsg(int s, const struct msghdr *msg, int flags)
-
-{
- struct socksysreq req;
-
- req.args[0] = SO_SENDMSG;
- req.args[1] = (int)s;
- req.args[2] = (int)msg;
- req.args[3] = (int)flags;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-int machdep_sys_recvmsg(int s, struct msghdr *msg, int flags)
-
-{
- struct socksysreq req;
-
- req.args[0] = SO_RECVMSG;
- req.args[1] = (int)s;
- req.args[2] = (int)msg;
- req.args[3] = (int)flags;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-u_short ntohs(u_short n)
-
-{
- union {
- unsigned char u_nc[4];
- u_short u_ns;
- } ns;
- register unsigned char* p = &ns.u_nc[0];
-
- ns.u_ns = n;
- return (p[0]<<8)|p[1];
-}
-
-u_short htons(u_short h)
-
-{
- union {
- unsigned char u_nc[2];
- u_short u_ns;
- } ns;
- register unsigned char* p = &ns.u_nc[0];
- p[0] = (h>>8)&0xFF;
- p[1] = (h&0xFF);
- return ns.u_ns;
-}
-
-
-u_long ntohl(u_long n)
-
-{
- union {
- unsigned char u_nc[4];
- u_long u_nl;
- } nl;
- register unsigned char* p = &nl.u_nc[0];
-
- nl.u_nl = n;
- return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
-}
-
-u_long htonl(u_long h)
-
-{
- union {
- unsigned char u_nc[4];
- u_long u_nl;
- } nl;
- register unsigned char* p = &nl.u_nc[0];
- p[0] = (h>>24)&0xFF;
- p[1] = (h>>16)&0xFF;
- p[2] = (h>>8)&0xFF;
- p[3] = (h&0xFF);
- return nl.u_nl;
-}
-
-int getdomainname(char* domain,int len)
-
-{
- /* edi = len */
- struct socksysreq req;
- register int ret, fd;
- if (len>MAXHOSTNAMELEN)
- len = MAXHOSTNAMELEN;
-
- if ((fd = machdep_sys_open("/dev/socksys", 0)) < 0)
- return fd;
-
- req.args[0] = SO_GETIPDOMAIN;
- req.args[1] = (int)domain;
- req.args[2] = (int)len;
- if((ret=machdep_sys_ioctl(fd, SIOCSOCKSYS, &req))<0) {
- machdep_sys_close(fd);
- return ret;
- }
-
- machdep_sys_close(fd);
- domain[len-1] = '\0';
- return 0;
-}
-
-int gethostname(char* name, int namelen)
-
-{
- struct utsname uts;
- register int ret, len;
- char domain[MAXHOSTNAMELEN+1];
-
- if (name==NULL)
- return -EFAULT;
- if ((ret=machdep_sys_uname(&uts))<0)
- return ret;
- if (namelen<(len=strlen(uts.nodename)))
- return -EFAULT;
- strncpy(name,uts.nodename,len);
- if (namelen>len)
- name[len] = '\0';
- if ((ret=getdomainname(domain, namelen - len))<0)
- return ret;
- if (domain[0]=='\0')
- return 0;
- if (len + strlen(domain) + 2 > namelen)
- return -EFAULT;
- strcat(name, ".");
- strcat(name, domain);
- return 0;
-}
-
-int gettimeofday(struct timeval* tp, struct timezone* tz)
-
-{
- register int ret;
- if ((ret = machdep_sys_gettimeofday(tp, NULL))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int kill(pid_t pid, int signo)
-
-{
- register int ret;
- if ((ret = machdep_sys_kill(pid,signo))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-typedef void (*signal_t(int signo, void (*func)(int)))(int);
-
-signal_t* _libc_signal = NULL;
-
-void (*signal(int signo, void (*func)(int)))(int)
-
-{
- int ret;
- void (*oldfunc)(int);
- extern void (*machdep_sys_signal(int signo, void (*func)(int),int* r))(int);
- if (_libc_signal!=NULL)
- return (*_libc_signal)(signo, func);
-
- oldfunc = machdep_sys_signal(signo, func, &ret);
- if (ret!=0) {
- errno = ret;
- return SIG_ERR;
- }
- else {
- return oldfunc;
- }
-}
-
-int (*_libc_sigaction)(int ,const struct sigaction *, struct sigaction *) = NULL;
-int sigaction(int sig,const struct sigaction *act, struct sigaction *oact)
-
-{
- register int ret;
- if (_libc_sigaction!=NULL)
- return (*_libc_sigaction)(sig,act,oact);
- if ((ret = machdep_sys_sigaction(sig,act,oact))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int (*_libc_sigprocmask)(int, const sigset_t *, sigset_t *) = NULL;
-
-int sigprocmask(int how, const sigset_t *set, sigset_t * oset)
-
-{
- register int ret;
- if (_libc_sigprocmask!=NULL)
- return (*_libc_sigprocmask)(how,set,oset);
- if ((ret = machdep_sys_sigprocmask(how,set,oset))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int (*_libc_sigsuspend)(const sigset_t *) = NULL;
-
-int sigsuspend(const sigset_t *set)
-{
- register int ret;
- if (_libc_sigsuspend!=NULL)
- return (*_libc_sigsuspend)(set);
- if ((ret = machdep_sys_sigsuspend(set))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int _sigrelse(sig)
-int sig;
-
-{
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, sig);
- return sigprocmask(SIG_UNBLOCK,&mask,NULL);
-}
-
-int _sighold(sig)
-int sig;
-
-{
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, sig);
- return sigprocmask(SIG_BLOCK,&mask,NULL);
-}
-
-void (*sigset(int sig, void (*func)(int)))(int)
-{
- return signal(sig, func);
-}
-
-
-int (*_libc_getmsg)(int , struct strbuf *, struct strbuf *, int *) = NULL;
-
-int getmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int * flags)
-{
- register int ret;
- if (_libc_getmsg != NULL)
- return (*_libc_getmsg)(fd,ctlptr,dataptr,flags);
- else if ((ret=machdep_sys_getmsg(fd,ctlptr,dataptr,flags))<0) {
- errno = -ret;
- return -1;
- }
- else
- return ret;
-}
-
-int (*_libc_putmsg)(int , const struct strbuf *, const struct strbuf *, int) = NULL;
-
-int putmsg(int fd, const struct strbuf * ctlptr, const struct strbuf * dataptr,
- int flags)
-{
- register int ret;
- if (_libc_putmsg != NULL)
- return (*_libc_putmsg)(fd,ctlptr,dataptr,flags);
- else if ((ret=machdep_sys_putmsg(fd,ctlptr,dataptr,flags))<0) {
- errno = -ret;
- return -1;
- }
- else
- return ret;
-}
-
-int ftime(struct timeb* tp)
-
-{
- register int ret;
- if ((ret=machdep_sys_ftime(tp))<0) {
- errno = -ret;
- return NOTOK;
- }
- return 0;
-}
-
-int getpagesize()
-
-{
- register int ret;
-#if 0
- if ((ret = machdep_sys_sysconf(_SC_PAGE_SIZE))<0) {
- PANIC();
- SET_ERRNO(-ret);
- return -1;
- }
- else {
- return 0;
- }
-#else
- return PAGESIZE;
-#endif
-}
-
-static pthread_mutex_t machdep_mutex =
-{ MUTEX_TYPE_COUNTING_FAST, PTHREAD_QUEUE_INITIALIZER, \
- NULL, SEMAPHORE_CLEAR, { NULL }, MUTEX_FLAGS_INITED };
-
-static pthread_mutex_t malloc_mutex =
-{ MUTEX_TYPE_COUNTING_FAST, PTHREAD_QUEUE_INITIALIZER, \
- NULL, SEMAPHORE_CLEAR, { NULL }, MUTEX_FLAGS_INITED };
-
-struct stdlock {
- volatile long init;
- pthread_mutex_t* mutex;
-};
-
-static void machdep_stdinitlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- pthread_mutex_lock(&machdep_mutex);
- if (!lock->init) {
- register pthread_mutex_t* mutex;
- pthread_mutexattr_t attr;
-
- lock->init = 1;
- lock->mutex = &machdep_mutex;
- mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, MUTEX_TYPE_COUNTING_FAST);
- pthread_mutex_init(mutex, &attr);
- lock->mutex = mutex;
- }
- pthread_mutex_unlock(&machdep_mutex);
-}
-
-void machdep_stdlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- pthread_mutex_lock(lock->mutex);
-}
-
-void machdep_stdunlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- pthread_mutex_unlock(lock->mutex);
-}
-
-int machdep_stdtrylock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- return pthread_mutex_trylock(lock->mutex);
-}
-
-int machdep_stdtryunlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- if (pthread_mutex_trylock(lock->mutex))
- return pthread_mutex_unlock(lock->mutex);
- return 0;
-}
-
-extern void (*_libc_stdlock)(struct stdlock* lock);
-extern void (*_libc_stdunlock)(struct stdlock* lock);
-extern int (*_libc_stdtrylock)(struct stdlock* lock);
-extern int (*_libc_stdtryunlock)(struct stdlock* lock);
-
-int machdep_sys_init()
-
-{
- typedef void (*voidfunc_t)();
- extern voidfunc_t _libc_read;
- extern voidfunc_t _libc_write;
- extern voidfunc_t _libc_readv;
- extern voidfunc_t _libc_writev;
- extern voidfunc_t _libc_open;
- extern voidfunc_t _libc_close;
- extern voidfunc_t _libc_fork;
- extern voidfunc_t _libc_fcntl;
- extern voidfunc_t _libc_dup;
- extern voidfunc_t _libc_pipe;
- extern voidfunc_t _libc_select;
- extern voidfunc_t _libc_malloc;
- extern voidfunc_t _libc_realloc;
- extern voidfunc_t _libc_free;
- extern ssize_t pthread_read (int , char*, int );
- extern ssize_t pthread_write (int , char*, int );
- extern int pthread_close (int);
- extern int pthread_dup (int);
- extern int pthread_fork ();
- extern int pthread_pipe (int*);
- extern int pthread_fcntl(int, int, ...);
- extern int pthread_open(const char *, int, ...);
- extern ssize_t pthread_readv (int , const struct iovec *, int );
- extern ssize_t pthread_writev (int , const struct iovec *, int );
- extern int pthread_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
- extern int pthread_getmsg(int , struct strbuf *, struct strbuf *,int*);
- extern int pthread_putmsg(int , const struct strbuf *, const struct strbuf *,int);
- extern void (*pthread_signal(int , void (*)(int)))(int);
- extern int pthread_sigaction(int,const struct sigaction *, struct sigaction *);
- extern int pthread_sigprocmask(int, const sigset_t *, sigset_t *);
- extern int pthread_sigsuspend(const sigset_t *);
-
-
- static struct {
- voidfunc_t *p;
- voidfunc_t f;
- } maptable[] = {
- {(voidfunc_t*)&_libc_read, (voidfunc_t) pthread_read},
- {(voidfunc_t*)&_libc_write, (voidfunc_t) pthread_write},
- {(voidfunc_t*)&_libc_readv, (voidfunc_t) pthread_readv},
- {(voidfunc_t*)&_libc_writev, (voidfunc_t) pthread_writev},
- {(voidfunc_t*)&_libc_open, (voidfunc_t) pthread_open},
- {(voidfunc_t*)&_libc_close, (voidfunc_t) pthread_close},
- {(voidfunc_t*)&_libc_fork, (voidfunc_t) pthread_fork},
- {(voidfunc_t*)&_libc_fcntl, (voidfunc_t) pthread_fcntl},
- {(voidfunc_t*)&_libc_dup, (voidfunc_t) pthread_dup},
- {(voidfunc_t*)&_libc_pipe, (voidfunc_t) pthread_pipe},
- {(voidfunc_t*)&_libc_select, (voidfunc_t) pthread_select},
- {(voidfunc_t*)&_libc_getmsg, (voidfunc_t) pthread_getmsg},
- {(voidfunc_t*)&_libc_putmsg, (voidfunc_t) pthread_putmsg},
- {(voidfunc_t*)&_libc_signal, (voidfunc_t) pthread_signal},
- {(voidfunc_t*)&_libc_sigaction, (voidfunc_t) pthread_sigaction},
- {(voidfunc_t*)&_libc_sigprocmask, (voidfunc_t) pthread_sigprocmask},
- {(voidfunc_t*)&_libc_sigsuspend, (voidfunc_t) pthread_sigsuspend},
- {(voidfunc_t*) 0, (voidfunc_t) 0}
- };
- register int i;
-
- for (i=0; maptable[i].p; i++)
- *maptable[i].p = maptable[i].f;
-
- _libc_stdlock = machdep_stdlock;
- _libc_stdunlock = machdep_stdunlock;
- _libc_stdtrylock = machdep_stdtrylock;
- _libc_stdtryunlock = machdep_stdtryunlock;
- return 0;
-}
-
-#if 0
-extern end;
-char* nd = (char*) &end;
-char* brk(const char* endds)
-
-{
- register int ret;
-
- if ((ret = machdep_sys_brk((char*)endds))<0) {
- SET_ERRNO(-ret);
- return (char*) -1;
- }
- else {
- nd = (char*) endds;
- return 0;
- }
-}
-
-char *sbrk(int incr)
-
-{
- register char* ret;
- if (incr!=0 && (ret=brk(nd + incr))!=0)
- return ret;
- else
- return nd - incr;
-}
-#endif
-
-sigset_t sigmask(int sig)
-
-{
- sigset_t oset;
- sigemptyset(&oset);
- sigaddset(&oset, sig);
- return oset;
-}
-
-sigset_t sigsetmask(sigset_t set)
-
-{
- sigset_t oset;
- sigprocmask(SIG_SETMASK,&set,&oset);
- return oset;
-}
-
-sigset_t sigblock(sigset_t set)
-
-{
- sigset_t oset;
- sigprocmask(SIG_BLOCK,&set,&oset);
- return oset;
-}
diff --git a/mit-pthreads/machdep/engine-i386-sco-3.2v5.h b/mit-pthreads/machdep/engine-i386-sco-3.2v5.h
deleted file mode 100644
index 8b2aa362f06..00000000000
--- a/mit-pthreads/machdep/engine-i386-sco-3.2v5.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * engine-i386-freebsd-2.0.h,v 1.1.4.1 1995/12/13 05:41:52 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-#define JB_BP 3
-#define JB_SP 4
-#define JB_PC 5
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-ip22-irix-5.2.c b/mit-pthreads/machdep/engine-ip22-irix-5.2.c
deleted file mode 100644
index d205d05f316..00000000000
--- a/mit-pthreads/machdep/engine-ip22-irix-5.2.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for IRIX-5.2 on the IP22
- *
- * 1.00 95/04/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- int i;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- if (setjmp(machdep_pthread->machdep_state)) {
- machdep_pthread_start();
- }
-
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
-
- /* IP22 stack starts high and builds down. */
- machdep_pthread->machdep_state[JB_SP] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[JB_SP] &= ~7;
-
- memcpy((void *)machdep_pthread->machdep_state[JB_SP],
- (char *)(((int)&i) - 24), 32);
-
-}
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-machdep_sys_dup2(int a, int b)
-{
- machdep_sys_close(b);
- machdep_sys_fcntl(a, F_DUPFD, b);
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_waitsys(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_waitsys(a, b, c, NULL));
-}
-
-struct stat;
-
-/* ==========================================================================
- * _fxstat()
- */
-int _fxstat(int __ver, int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * _lxstat()
- */
-int _lxstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * _xstat()
- */
-int _xstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- int i;
-
- i = machdep_sys_getdents(fd, buf, len);
- return i;
-}
diff --git a/mit-pthreads/machdep/engine-ip22-irix-5.2.h b/mit-pthreads/machdep/engine-ip22-irix-5.2.h
deleted file mode 100644
index 94dd386608e..00000000000
--- a/mit-pthreads/machdep/engine-ip22-irix-5.2.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-/*
- * More machine dependent macros
- */
-#ifdef PTHREAD_KERNEL
-
-#define machdep_save_float_state(x)
-#define machdep_restore_float_state()
-
-#endif
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIGMAX 32
-#define SIG_ANY(sig) \
-({ \
- sigset_t *sig_addr = (sigset_t *)&sig; \
- int ret = 0; \
- int i; \
- \
- for (i = 1; i <= SIGMAX; i++) { \
- if (sigismember(sig_addr, i)) { \
- ret = 1; \
- break; \
- } \
- } \
- ret; \
-})
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-m68000-netbsd.c b/mit-pthreads/machdep/engine-m68000-netbsd.c
deleted file mode 100644
index 6346c36ca7c..00000000000
--- a/mit-pthreads/machdep/engine-m68000-netbsd.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * m68k work from David Leonard <david.leonard@it.uq.edu.au>.
- * updated and NetBSD/m68k work from Andy Finnell <andyf@vei.net>.
- *
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "pthread.h"
-#include <sys/syscall.h>
-#include <sys/stat.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return( _setjmp(pthread_run->machdep_data.machdep_state) );
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = pthread->machdep_data.machdep_fstate;
-
- __asm__ ( "fmovem fp0-fp7,%0"::"m" (*fdata) );
- __asm__ ( "fmovem fpcr/fpsr/fpi,%0"::"m" (fdata[80]) );
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- char * fdata = pthread_run->machdep_data.machdep_fstate;
-
- __asm__ ( "fmovem %0,fp0-fp7"::"m" (*fdata) );
- __asm__ ( "fmovem %0,fpcr/fpsr/fpi"::"m" (fdata[80]) );
-
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return((void*)malloc(size));
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current thread's start routine with argument */
- pthread_exit(
- pthread_run->machdep_data.start_routine(
- pthread_run->machdep_data.start_argument
- )
- );
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stack frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- *
- * state is the set_jmp structure, which for m68k is:
- * long onstack_flag; // [0]
- * long sigmask; // [1]
- * long sp; // [2]
- * long fp; // [3]
- * long ap; // [4]
- * long pc; // [5]
- * long ps; // [6]
- * long regs[10]; // non scratch registers
- */
- machdep_pthread->machdep_state[5] = (long)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- extern off_t __syscall();
-
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
-
-int machdep_sys_ftruncate( int fd, off_t length)
-{
- quad_t q;
- int rv;
-
- q = __syscall((quad_t)SYS_ftruncate, fd,0, length);
- if( /* LINTED constant */ sizeof( quad_t ) == sizeof( register_t ) ||
- /* LINTED constant */ BYTE_ORDER == LITTLE_ENDIAN )
- rv = (int)q;
- else
- rv = (int)((u_quad_t)q >> 32);
-
- return rv;
-}
-
-int machdep_sys_fstat( int f, struct stat* st )
-{
- return __fstat13(f,st);
-}
diff --git a/mit-pthreads/machdep/engine-m68000-netbsd.h b/mit-pthreads/machdep/engine-m68000-netbsd.h
deleted file mode 100644
index ec3c6a01bce..00000000000
--- a/mit-pthreads/machdep/engine-m68000-netbsd.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * m68k work by Andy Finnell <andyf@vei.net> based off work by
- * David Leonard and Chris Provenzano.
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0x80;
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
- volatile long temp = SEMAPHORE_CLEAR; \
- __asm__ volatile( \
- "tas %2; bpl 0f; movl #1,%0; 0:" \
- :"=r" (temp) \
- :"0" (temp),"m" (*lock)); \
- temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_fstate[92];
-};
-
-/*
- * Min pthread stacksize
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-
-#ifndef __machdep_stack_get
-#define __machdep_stack_get(x) (x)->machdep_stack
-#endif
-#ifndef __machdep_stack_set
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#endif
-#ifndef __machdep_stack_repl
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-#endif
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-powerpc-netbsd.c b/mit-pthreads/machdep/engine-powerpc-netbsd.c
deleted file mode 100644
index fc17e3de5d0..00000000000
--- a/mit-pthreads/machdep/engine-powerpc-netbsd.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD/PowerPC (1.5+)
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 2001/01/10 briggs
- * -Modified to make it go with NetBSD/PowerPC
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* XXXMLG
- * This is EXTREMELY bogus, but it seems that this function is called
- * with the pthread kernel locked. If this happens, __errno() will
- * return the wrong address until after the first context switch.
- *
- * Clearly there is a leak of pthread_kernel somewhere, but until
- * it is found, we force a context switch here, just before calling
- * the thread start routine. When we return from pthread_yield
- * the kernel will be unlocked.
- */
- pthread_yield();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(void *), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- /* state is sigmask, then r8-r31 where r11 is the LR
- * So, istate[3] is r10, which is the SP
- * So, istate[4] is r11, which is the LR
- * So, istate[5] is r12, which is the CR
- */
- machdep_pthread->machdep_istate[4] = (long)machdep_pthread_start;
- machdep_pthread->machdep_istate[5] = 0;
-
- /* PowerPC stack starts high and builds down, and needs to be 16-byte
- aligned. */
- machdep_pthread->machdep_istate[3] =
- ((long) machdep_pthread->machdep_stack + stack_size) & ~0xf;
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return( _setjmp(pthread_run->machdep_data.machdep_istate) );
-}
-
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_istate, 1);
-}
-
-void machdep_save_float_state (struct pthread *pthread)
-{
- __machdep_save_fp_state(pthread->machdep_data.machdep_fstate);
-}
-
-void machdep_restore_float_state (void)
-{
- __machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread);
-void machdep_pthread_start(void);
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void
-__machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void *
-__machdep_stack_alloc(size_t size)
-{
- return(malloc(size));
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-int
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-int
-machdep_sys_wait3(int * b, int c, int *d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-int
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-int
-machdep_sys_getdtablesize(void)
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t
-machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
-
-int
-machdep_sys_ftruncate( int fd, off_t length)
-{
- quad_t q;
- int rv;
-
- q = __syscall((quad_t)SYS_ftruncate, fd,0, length);
- if( /* LINTED constant */ sizeof( quad_t ) == sizeof( register_t ) ||
- /* LINTED constant */ BYTE_ORDER == LITTLE_ENDIAN )
- rv = (int)q;
- else
- rv = (int)((u_quad_t)q >> 32);
-
- return rv;
-}
-
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-powerpc-netbsd.h b/mit-pthreads/machdep/engine-powerpc-netbsd.h
deleted file mode 100644
index 530b7ca81e2..00000000000
--- a/mit-pthreads/machdep/engine-powerpc-netbsd.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xffff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
- volatile long t1, temp = SEMAPHORE_SET; \
- __asm__ volatile( \
- "1: lwarx %0,0,%1; \
- cmpwi %0, 0; \
- bne 2f; \
- stwcx. %2,0,%1; \
- bne- 1b; \
- 2: " \
- :"=r" (t1) \
- :"m" (lock), "r" (temp)); \
- t1; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_istate;
- unsigned long machdep_fstate[66];
- /* 64-bit fp regs 0-31 + fpscr */
- /* We pretend the fpscr is 64 bits */
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, { 0 }, { 0 } }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if ((stack = __machdep_stack_get(x))) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-int machdep_save_state(void);
-
-void __machdep_save_fp_state(unsigned long *);
-void __machdep_restore_fp_state(unsigned long *);
-void *__machdep_stack_alloc(size_t);
-void __machdep_stack_free(void *);
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.c b/mit-pthreads/machdep/engine-r2000-ultrix-4.2.c
deleted file mode 100644
index 45c8cc73f24..00000000000
--- a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for decstation with r2000/r3000
- *
- * 1.00 93/07/21 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/*
- * The r2000/r3000 processors do not have a test and set instruction, so
- * the semaphore TEST_AND_SET macro is linked very closely to the interrupt
- * handelling of the pthreads package.
- */
-
-/* ==========================================================================
- * semaphore_test_and_set()
- *
- * SEMAPHORE_TEST_AND_SET prevents interrupts, tests the lock and then
- * turns interrupts back on, checking to see if any interrupts have occured
- * between the prevent and resume.
- */
-int semaphore_test_and_set(semaphore *lock)
-{
- int rval;
-
-/* None of this should be necessary
- sig_prevent();
- if (!(rval = (*lock))) {
- *lock = SEMAPHORE_SET;
- }
- sig_check_and_resume();
- return(rval);
-*/
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * fake_longjmp()
- */
-void fake_longjmp(jmp_buf env)
-{
- asm("li $5,1; sw $5, 20($4); li $2,103; syscall");
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- *
- * When I redo machdep_save_state, I'll put the asm in machdep_save_state()
- * and machdep_restore_state() and I won't have to do an additional function
- * call.
- */
-void machdep_restore_state(void)
-{
- fake_longjmp(pthread_run->machdep_data.machdep_state);
- /* longjmp(pthread_run->machdep_data.machdep_state, 1); */
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[JB_RA] = (int)machdep_pthread_start;
- machdep_pthread->machdep_state[JB_PC] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[JB_SP] =
- (int)machdep_pthread->machdep_stack + stack_size;
-
- /* This is the real global pointer */
- /* machdep_pthread->machdep_state[JB_GP] = 0; */
-}
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- * This isn't a real implementation; we can make the assumption that the
- * pthreads library is not using oset, and that it is always blocking or
- * unblocking all signals at once.
- */
-int machdep_sys_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
-{
- switch(how) {
- case SIG_BLOCK:
- sigblock(*set);
- break;
- case SIG_UNBLOCK:
- sigsetmask(~*set);
- break;
- case SIG_SETMASK:
- sigsetmask(*set);
- break;
- default:
- return -EINVAL;
- }
- return(OK);
-}
-
diff --git a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.h b/mit-pthreads/machdep/engine-r2000-ultrix-4.2.h
deleted file mode 100644
index 8e2d70f8feb..00000000000
--- a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Machine dependent header for decstation with r2000/r3000
- * running Ultrix-4.2
- *
- * 1.00 93/07/21 proven
- * -Started coding this file.
- */
-
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) semaphore_test_and_set(lock)
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-#if !defined(_POSIX_SOURCE)
-
-/* typedef int ssize_t; */
-
-#if !defined(__GNUC__)
-
-/*
- * sigset_t macros
- */
-typedef int sigset_t;
-#define sigaddset(set, num) ((*set) |= (1 << (num - 1)))
-#define sigemptyset(set) (*set = 0)
-
-#endif
-#endif
-
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Structures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-
-/*
- * Min stacksize, arch dependent
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int semaphore_test_and_set __P_((semaphore *));
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-romp-bsd.c b/mit-pthreads/machdep/engine-romp-bsd.c
deleted file mode 100644
index dd1a1096ece..00000000000
--- a/mit-pthreads/machdep/engine-romp-bsd.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_pthread_save(pthread_run->machdep_data.machdep_state, 0, 0));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _pthread_restore(pthread_run->machdep_data.machdep_state);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _pthread_save(machdep_pthread->machdep_state,
- (void *)((int)machdep_pthread->machdep_stack + stack_size),
- machdep_pthread_start);
-}
-
diff --git a/mit-pthreads/machdep/engine-romp-bsd.h b/mit-pthreads/machdep/engine-romp-bsd.h
deleted file mode 100644
index 28c59d35e70..00000000000
--- a/mit-pthreads/machdep/engine-romp-bsd.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 John F. Carr, jfc@athena.mit.edu
- *
- * Description : Machine dependent header for IBM/RT
- *
- * 1.00 93/09/xx jfc
- * -Coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-/*
- * Stuff for compiling
- */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const
-#define inline
-#define signed
-#define volatile
-#endif
-
-#define SEMAPHORE_CLEAR 0x0000
-#define SEMAPHORE_SET 0xff00
-#define SEMAPHORE_TEST_AND_SET(lock) _tsh(lock)
-#define SEMAPHORE_RESET(lock) *(lock) = SEMAPHORE_CLEAR
-extern unsigned short _tsh(volatile unsigned short *);
-
-typedef unsigned short semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Min pthread stacksize
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-/* save(jmp_buf, stack pointer, restart proc) */
-extern int _pthread_save(jmp_buf, void *, void (*)());
-extern void _pthread_restore(jmp_buf);
-
-typedef int ssize_t;
-typedef unsigned int sigset_t;
-#define sigemptyset(sp) *(sp) = 0
-#define sigprocmask(op, nssp, ossp) if (ossp) *(int *)ossp = sigsetmask(*nssp); else sigsetmask(*nssp)
-#define sigdelset(sp, i) *(sp) &= ~(1 << (i))
-#define sigaddset(sp, i) *(sp) |= (1 << (i))
-#define sigismember(sp, i) (*(sp) & (1 << (i)))
-#endif
diff --git a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.c b/mit-pthreads/machdep/engine-sparc-netbsd-1.3.c
deleted file mode 100644
index 8e0520cfba5..00000000000
--- a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 98/10/22 bad
- * -update for fat sigset_t in NetBSD 1.3H
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[3] = (int)machdep_pthread_start;
- machdep_pthread->machdep_state[4] = (int)machdep_pthread_start;
-
- /* Sparc stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[2] &= ~7;
-
-}
-
-#if defined(HAVE_SYSCALL_GETDENTS)
-/* ==========================================================================
- * machdep_sys_getdirentries()
- *
- * Always use getdents in place of getdirentries if possible --proven
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-#endif
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int pid, int * statusp, int options)
-{
- if (pid == -1)
- pid = 0;
- else if (pid == 0)
- pid = - getpgrp ();
- return machdep_sys_wait4 (pid, statusp, options, NULL);
-}
-
-#if !defined(HAVE_SYSCALL_SIGPROCMASK)
-#if 0
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- * This isn't a real implementation; we can make the assumption that the
- * pthreads library is not using oset, and that it is always blocking or
- * unblocking all signals at once.
- */
-int machdep_sys_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
-{
- switch(how) {
- case SIG_BLOCK:
- sigblock(*set);
- break;
- case SIG_UNBLOCK:
- sigsetmask(~*set);
- break;
- case SIG_SETMASK:
- sigsetmask(*set);
- break;
- default:
- return -EINVAL;
- }
- return(OK);
-}
-
-/* ==========================================================================
- * sigaction()
- *
- * Temporary until I do machdep_sys_sigaction()
- */
-int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact)
-{
- return(sigvec(sig, (struct sigvec *)act, (struct sigvec *)oldact));
-}
-#endif
-#endif
-
-#if !defined(HAVE_SYSCALL_GETDTABLESIZE)
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-#endif
diff --git a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.h b/mit-pthreads/machdep/engine-sparc-netbsd-1.3.h
deleted file mode 100644
index a187d3dace8..00000000000
--- a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * engine-sparc-sunos-4.1.3.h,v 1.52.4.1 1995/12/13 05:42:33 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-char *p = lock; \
-long temp; \
- \
-__asm__ volatile("ldstub %1,%0" \
- :"=r" (temp) \
- :"m" (*p) \
- :"memory"); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-{ \
-__asm__ volatile("stb %1, %0" \
- :"=m" (*lock) \
- :"r" (SEMAPHORE_CLEAR) \
- :"memory"); \
-}
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c b/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c
deleted file mode 100644
index 6916c3610cd..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[3] = (int)machdep_pthread_start;
- machdep_pthread->machdep_state[4] = (int)machdep_pthread_start;
-
- /* Sparc stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[2] &= ~7;
-
-}
-
-#if defined(HAVE_SYSCALL_GETDENTS)
-/* ==========================================================================
- * machdep_sys_getdirentries()
- *
- * Always use getdents in place of getdirentries if possible --proven
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-#endif
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int pid, int * statusp, int options)
-{
- if (pid == -1)
- pid = 0;
- else if (pid == 0)
- pid = - getpgrp ();
- return machdep_sys_wait4 (pid, statusp, options, NULL);
-}
-
-#if !defined(HAVE_SYSCALL_SIGPROCMASK)
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- * This isn't a real implementation; we can make the assumption that the
- * pthreads library is not using oset, and that it is always blocking or
- * unblocking all signals at once.
- */
-int machdep_sys_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
-{
- switch(how) {
- case SIG_BLOCK:
- sigblock(*set);
- break;
- case SIG_UNBLOCK:
- sigsetmask(~*set);
- break;
- case SIG_SETMASK:
- sigsetmask(*set);
- break;
- default:
- return -EINVAL;
- }
- return(OK);
-}
-
-/* ==========================================================================
- * sigaction()
- *
- * Temporary until I do machdep_sys_sigaction()
- */
-int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact)
-{
- return(sigvec(sig, (struct sigvec *)act, (struct sigvec *)oldact));
-}
-#endif
-
-#if !defined(HAVE_SYSCALL_GETDTABLESIZE)
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-#endif
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h b/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h
deleted file mode 100644
index 1a4a8768ad0..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-char *p = lock; \
-long temp; \
- \
-__asm__ volatile("ldstub %1,%0" \
- :"=r" (temp) \
- :"m" (*p) \
- :"memory"); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-{ \
-__asm__ volatile("stb %1, %0" \
- :"=m" (*lock) \
- :"r" (SEMAPHORE_CLEAR) \
- :"memory"); \
-}
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-5.3.c b/mit-pthreads/machdep/engine-sparc-sunos-5.3.c
deleted file mode 100644
index a228a408da3..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-5.3.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/procset.h>
-#include <sys/systeminfo.h>
-#include <poll.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- if (setjmp(machdep_pthread->machdep_state)) {
- machdep_pthread_start();
- }
-
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
-
- /* Sparc stack starts high and builds down. */
- machdep_pthread->machdep_state[1] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[1] &= ~7;
-
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(-ENOSYS);
- /* return(machdep_sys_wait4(0, b, c, d)); */
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- idtype_t id;
-
- switch (a) {
- case -1:
- id = P_ALL;
- break;
- case 0:
- a = machdep_sys_pgrpsys(0);
- id = P_PGID;
- break;
- default:
- if (a < 0) {
- id = P_PGID;
- a = -a;
- } else {
- id = P_PID;
- }
- break;
- }
-
- return(machdep_sys_waitsys(id, a, b, c));
-}
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-machdep_sys_dup2(int a, int b)
-{
- machdep_sys_close(b);
- machdep_sys_fcntl(a, F_DUPFD, b);
-}
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
-machdep_sys_ftruncate(int a, off_t b)
-{
- flock_t c;
-
- c.l_len = 0;
- c.l_start = b;
- c.l_whence = 0;
- return(machdep_sys_fcntl(a, F_FREESP, c));
-}
-
-/* ==========================================================================
- * machdep_sys_select()
- * Recoded to be quicker by Monty
- */
-static fd_set bogus_fds; /* Always zero, never changed */
-
-machdep_sys_select(int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
-{
- struct pollfd fds[64],*ptr;
- int i, fds_count, time_out, found;
-
- /* Make sure each arg has a valid pointer */
- if ((readfds == NULL) || (writefds == NULL) || (exceptfds == NULL)) {
- if (exceptfds == NULL) {
- exceptfds = &bogus_fds;
- }
- if (writefds == NULL) {
- writefds = &bogus_fds;
- }
- if (readfds == NULL) {
- readfds = &bogus_fds;
- }
- }
-
- ptr=fds;
- for (i = 0 ; i < nfds; i++)
- {
- if (FD_ISSET(i, readfds))
- {
- if (FD_ISSET(i, writefds))
- ptr->events= POLLIN | POLLOUT;
- else
- ptr->events= POLLIN;
- (ptr++)->fd=i;
- }
- else if (FD_ISSET(i, writefds))
- {
- ptr->events=POLLOUT;
- (ptr++)->fd=i;
- }
- }
- FD_ZERO(readfds);
- FD_ZERO(writefds);
- FD_ZERO(exceptfds);
- time_out = timeout->tv_usec / 1000 + timeout->tv_sec * 1000;
- fds_count=(int) (ptr-fds);
- while ((found = machdep_sys_poll(fds, fds_count, time_out)) <= 0)
- {
- if (found != -ERESTART) /* Try again if restartable */
- return(found); /* Usually 0 ; Cant read or write */
- }
-
- while (ptr-- != fds)
- {
- if (ptr->revents & POLLIN)
- FD_SET(ptr->fd, readfds);
- if (ptr->revents & POLLOUT)
- FD_SET(ptr->fd,writefds);
- }
- return(found);
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * getpagesize()
- */
-getpagesize()
-{
- return(sysconf(_SC_PAGESIZE));
-}
-
-/* ==========================================================================
- * gethostname()
- */
-int gethostname(char * name, int namelen)
-{
- if (sysinfo(SI_HOSTNAME, name, namelen) == NOTOK) {
- return(NOTOK);
- } else {
- return(OK);
- }
-}
-
-/* ==========================================================================
- * machdep_sys_sigaction()
- *
- * This is VERY temporary.
- */
-int machdep_sys_sigaction(int a, void * b, void * c)
-{
- return(sigaction(a, b, c));
-}
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-5.3.h b/mit-pthreads/machdep/engine-sparc-sunos-5.3.h
deleted file mode 100644
index 365ecd799eb..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-5.3.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-char *p = lock; \
-long temp; \
- \
-__asm__ volatile("ldstub %1,%0" \
- :"=r" (temp) \
- :"m" (*p) \
- :"memory"); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-{ \
-__asm__ volatile("stb %1, %0" \
- :"=m" (*lock) \
- :"r" (SEMAPHORE_CLEAR) \
- :"memory"); \
-}
-
-/*
- * More machine dependent macros
- */
-#ifdef PTHREAD_KERNEL
-
-#define machdep_save_float_state(x)
-#define machdep_restore_float_state()
-
-#endif
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIGMAX 31
-#define SIG_ANY(sig) \
-({ \
- sigset_t *sig_addr = (sigset_t *)&sig; \
- int ret = 0; \
- int i; \
- \
- for (i = 1; i <= SIGMAX; i++) { \
- if (sigismember(sig_addr, i)) { \
- ret = 1; \
- break; \
- } \
- } \
- ret; \
-})
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#undef PTHREAD_STACK_MIN /* Defined in limits.h */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/freebsd-1.1/compat.h b/mit-pthreads/machdep/freebsd-1.1/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-1.1/dirent.h b/mit-pthreads/machdep/freebsd-1.1/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/freebsd-1.1/socket.h b/mit-pthreads/machdep/freebsd-1.1/socket.h
deleted file mode 100755
index f13d01e7fe5..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/socket.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)socket.h 7.13 (Berkeley) 4/20/91
- * $Id$
- */
-
-#ifndef _SYS_SOCKET_H_
-#define _SYS_SOCKET_H_ 1
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_ISO 7 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_ROUTE 17 /* Internal Routing Protocol */
-#define AF_LINK 18 /* Link layer interface */
-#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-#define AF_RMP 20 /* HP's Remote Maint Protocol */
-#define AF_MAX 21
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_char sa_len; /* total length */
- u_char sa_family; /* address family */
- char sa_data[14]; /* actually longer; address value */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_ROUTE AF_ROUTE
-#define PF_LINK AF_LINK
-#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-#define PF_RMP AF_RMP
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- * Used value-result for recvmsg, value only for sendmsg.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- u_int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- u_int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_control; /* ancillary data, see below */
- u_int msg_controllen; /* ancillary data buffer len */
- int msg_flags; /* flags on received message */
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-#define MSG_EOR 0x8 /* data completes record */
-#define MSG_TRUNC 0x10 /* data discarded before delivery */
-#define MSG_CTRUNC 0x20 /* control data lost before delivery */
-#define MSG_WAITALL 0x40 /* wait for full request or error */
-
-/*
- * Header for ancillary data objects in msg_control buffer.
- * Used for additional information with/about a datagram
- * not expressible by flags. The format is a sequence
- * of message elements headed by cmsghdr structures.
- */
-struct cmsghdr {
- u_int cmsg_len; /* data byte count, including hdr */
- int cmsg_level; /* originating protocol */
- int cmsg_type; /* protocol-specific type */
-/* followed by u_char cmsg_data[]; */
-};
-
-/* given pointer to struct adatahdr, return pointer to data */
-#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
-
-/* given pointer to struct adatahdr, return pointer to next adatahdr */
-#define CMSG_NXTHDR(mhdr, cmsg) \
- (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
- (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
- (struct cmsghdr *)NULL : \
- (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
-
-#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
-
-/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* access rights (array of int) */
-
-/*
- * 4.3 compat sockaddr, move to compat file later
- */
-struct osockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * 4.3-compat message header (move to compat file later).
- */
-struct omsghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#ifndef KERNEL
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int,
- struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !KERNEL */
-#endif /* _SYS_SOCKET_H_ */
diff --git a/mit-pthreads/machdep/freebsd-1.1/timers.h b/mit-pthreads/machdep/freebsd-1.1/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/__math.h b/mit-pthreads/machdep/freebsd-2.0/__math.h
deleted file mode 100755
index 27ed0f2575d..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__path.h b/mit-pthreads/machdep/freebsd-2.0/__path.h
deleted file mode 100755
index 432494daafa..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__signal.h b/mit-pthreads/machdep/freebsd-2.0/__signal.h
deleted file mode 100755
index 918955c9948..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__signal.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__stdio.h b/mit-pthreads/machdep/freebsd-2.0/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/freebsd-2.0/__stdlib.h b/mit-pthreads/machdep/freebsd-2.0/__stdlib.h
deleted file mode 100755
index 5ee2b8ed3d9..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__stdlib.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#ifdef _BSD_RUNE_T_
-typedef _BSD_RUNE_T_ rune_t;
-#undef _BSD_RUNE_T_
-#else
-typedef _BSD_WCHAR_T_ rune_t;
-#endif
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/freebsd-2.0/__string.h b/mit-pthreads/machdep/freebsd-2.0/__string.h
deleted file mode 100755
index 93d4fcf9dd2..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__string.h
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__time.h b/mit-pthreads/machdep/freebsd-2.0/__time.h
deleted file mode 100755
index 5c4b722bc3c..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__time.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-#include <machine/limits.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(CLK_TCK)
-#define CLK_TCK 100
-#endif /* not CLK_TCK */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/freebsd-2.0/__unistd.h b/mit-pthreads/machdep/freebsd-2.0/__unistd.h
deleted file mode 100755
index ed5b0657727..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__unistd.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type unsigned long /* For fd.c */
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#ifndef _POSIX_VERSION
-#define _POSIX_VERSION 198808L
-#endif
-#ifndef _POSIX2_VERSION
-#define _POSIX2_VERSION 199212L
-#endif
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE 0xff
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/compat.h b/mit-pthreads/machdep/freebsd-2.0/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/dirent.h b/mit-pthreads/machdep/freebsd-2.0/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/freebsd-2.0/errno.h b/mit-pthreads/machdep/freebsd-2.0/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/timers.h b/mit-pthreads/machdep/freebsd-2.0/timers.h
deleted file mode 100755
index f9768c68c8f..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/wait.h b/mit-pthreads/machdep/freebsd-2.0/wait.h
deleted file mode 100755
index 7861e3fa180..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/wait.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/__math.h b/mit-pthreads/machdep/hpux-10.20/__math.h
deleted file mode 100755
index 8066bd60713..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__math.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#define HUGE_VAL 1.7976931348623157e+308
-
-
diff --git a/mit-pthreads/machdep/hpux-10.20/__signal.h b/mit-pthreads/machdep/hpux-10.20/__signal.h
deleted file mode 100755
index fbb1d6ce2b1..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__signal.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <sys/signal.h>
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-/* #define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1))) */
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0, 0, 0, 0, 0 }
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff,\
- 0xffffffff,0xffffffff,0xffffffff,0xffffffff}
-#define __SIGADDSET(s, n) ((s)->sigset[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->sigset[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) ((s)->sigset[sigword(n)] & sigmask(n))
-
-#define SIGSET_SIZE sizeof(sigset_t)/sizeof(long)
-
-#define SIG_ANY(sig) sig_any(&sig)
-
-static inline int sig_any(sigset_t *sig) {
- int i;
- for (i=0; i < SIGSET_SIZE; i++)
- if (sig->sigset[i] != 0)
- return 1;
- return 0;
-}
-
diff --git a/mit-pthreads/machdep/hpux-10.20/__stdio.h b/mit-pthreads/machdep/hpux-10.20/__stdio.h
deleted file mode 100755
index b8f1a07d9d6..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__stdio.h
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#include <sys/types.h>
-/*
-typedef pthread_fpos_t fpos_t;
-*/
-
diff --git a/mit-pthreads/machdep/hpux-10.20/__stdlib.h b/mit-pthreads/machdep/hpux-10.20/__stdlib.h
deleted file mode 100755
index 37a14a960d5..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__stdlib.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/__string.h b/mit-pthreads/machdep/hpux-10.20/__string.h
deleted file mode 100755
index 1badf6d660c..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS_STDSYMS_INCLUDED
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard SunOS 4.x string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/__time.h b/mit-pthreads/machdep/hpux-10.20/__time.h
deleted file mode 100755
index ae958dcc3cf..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__time.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#define CLOCKS_PER_SEC 1000000
-
-#if !defined(_ANSI_SOURCE) && !defined(CLK_TCK)
-#define CLK_TCK 60
-#endif /* not ANSI */
-
-#endif
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/hpux-10.20/__unistd.h b/mit-pthreads/machdep/hpux-10.20/__unistd.h
deleted file mode 100755
index 218e13d14ec..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__unistd.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* /afs/sipb.mit.edu/project/pthreads/src/CVS/pthreads/machdep/hpux-9.03/__unist
-d.h,v 1.2 1995/03/10 03:59:53 snl Exp */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/stdsyms.h>
-#include <sys/types.h>
-#include <utime.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _GID_T
-#define _GID_T
-typedef long gid_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef _PID_T
-#define _PID_T
-typedef long pid_t;
-#endif
-
-#ifndef _OFF_T
-#define _OFF_T
-typedef long off_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#define ioctl_request_type int /* For fd.c */
-
-/* Symbolic constants for sysconf() variables defined by POSIX.1-1988: 0-7 */
-
-#define _SC_ARG_MAX 0 /* ARG_MAX: Max length of argument to exec()
- including environment data */
-#define _SC_CHILD_MAX 1 /* CHILD_MAX: Max of processes per userid */
-#define _SC_CLK_TCK 2 /* Number of clock ticks per second */
-#define _SC_NGROUPS_MAX 3 /* NGROUPS_MAX: Max of simultaneous
- supplementary group IDs per process */
-#define _SC_OPEN_MAX 4 /* OPEN_MAX: Max of files that one process
- can have open at any one time */
-#define _SC_JOB_CONTROL 5 /* _POSIX_JOB_CONTROL: 1 iff supported */
-#define _SC_SAVED_IDS 6 /* _POSIX_SAVED_IDS: 1 iff supported */
-#define _SC_1_VERSION_88 7 /* _POSIX_VERSION: Date of POSIX.1-1988 */
-
-/* Symbolic constants for sysconf() variables added by POSIX.1-1990: 100-199 */
-
-#define _SC_STREAM_MAX 100 /* STREAM_MAX: Max of open stdio FILEs */
-#define _SC_TZNAME_MAX 101 /* TZNAME_MAX: Max length of timezone name */
-#define _SC_1_VERSION_90 102 /* _POSIX_VERSION: Date of POSIX.1-1990 */
-
-#endif /* _SYS___UNISTD_H_ */
-
diff --git a/mit-pthreads/machdep/hpux-10.20/cdefs.h b/mit-pthreads/machdep/hpux-10.20/cdefs.h
deleted file mode 100755
index 643089e6df6..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/cdefs.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-#include <sys/_inttypes.h>
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __INLINE static
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-/*
-typedef int int32_t;
-*/
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-/*
-typedef short int16_t;
-*/
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/compat.h b/mit-pthreads/machdep/hpux-10.20/compat.h
deleted file mode 100755
index 5a59434417c..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Compatibility header for networking code.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/dirent.h b/mit-pthreads/machdep/hpux-10.20/dirent.h
deleted file mode 100755
index 5f17af345db..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/dirent.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/hpux-10.20/socket.h b/mit-pthreads/machdep/hpux-10.20/socket.h
deleted file mode 100755
index c7a37706940..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/socket.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-#include <sys/stdsyms.h>
-#include <pthread/posix.h>
-#include <sys/cdefs.h>
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_SND_COPYAVOID 0x1009 /* avoid copy on send*/
-#define SO_RCV_COPYAVOID 0x100a /* avoid copy on rcv */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_OTS 17 /* Used for OSI in the ifnets */
-#define AF_NIT 18 /* NIT */
-
-#define AF_MAX 19
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 20
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/hpux-10.20/stdtypes.h b/mit-pthreads/machdep/hpux-10.20/stdtypes.h
deleted file mode 100755
index 2b22abbf818..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/stdtypes.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* @(#)stdtypes.h 1.6 90/01/04 SMI */
-
-/*
- * Suppose you have an ANSI C or POSIX thingy that needs a typedef
- * for thingy_t. Put it here and include this file wherever you
- * define the thingy. This is used so that we don't have size_t in
- * N (N > 1) different places and so that we don't have to have
- * types.h included all the time and so that we can include this in
- * the lint libs instead of termios.h which conflicts with ioctl.h.
- */
-#ifndef __sys_stdtypes_h
-#define __sys_stdtypes_h
-
-#ifndef _SIGSET_T_
-#define _SIGSET_T_
-typedef int sigset_t; /* signal mask - may change */
-#endif
-
-#ifndef _SPEED_T_
-#define _SPEED_T_
-typedef unsigned int speed_t; /* tty speeds */
-#endif
-
-#ifndef _TCFLAG_T_
-#define _TCFLAG_T_
-typedef unsigned long tcflag_t; /* tty line disc modes */
-#endif
-
-#ifndef _CC_T_
-#define _CC_T_
-typedef unsigned char cc_t; /* tty control char */
-#endif
-
-#ifndef _PID_T_
-#define _PID_T_
-typedef int pid_t; /* process id */
-#endif
-
-#ifndef _MODE_T_
-#define _MODE_T_
-typedef unsigned short mode_t; /* file mode bits */
-#endif
-
-#ifndef _NLINK_T_
-#define _NLINK_T_
-typedef short nlink_t; /* links to a file */
-#endif
-
-#ifndef _CLOCK_T_
-#define _CLOCK_T_
-typedef long clock_t; /* units=ticks (typically 60/sec) */
-#endif
-
-#ifndef _TIME_T_
-#define _TIME_T_
-typedef long time_t; /* value = secs since epoch */
-#endif
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef int size_t; /* ??? */
-#endif
-
-#ifndef _PTRDIFF_T_
-#define _PTRDIFF_T_
-typedef int ptrdiff_t; /* result of subtracting two pointers */
-#endif
-
-#ifndef _WCHAR_T_
-#define _WCHAR_T_
-typedef unsigned short wchar_t; /* big enough for biggest char set */
-#endif
-
-#endif /* !__sys_stdtypes_h */
diff --git a/mit-pthreads/machdep/hpux-10.20/time.h b/mit-pthreads/machdep/hpux-10.20/time.h
deleted file mode 100755
index 544905b0749..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/time.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* $Header$ */
-
-#ifndef _SYS_TIME_INCLUDED
-#define _SYS_TIME_INCLUDED
-
-/* time.h: Definitions for time handling functions */
-
-#ifdef _KERNEL_BUILD
-#include "../h/stdsyms.h"
-#else /* ! _KERNEL_BUILD */
-#include <sys/stdsyms.h>
-#endif /* _KERNEL_BUILD */
-
-#include <sys/types.h>
-
-/* ANSI C time constants, types, and structures */
-
-#ifdef _INCLUDE__STDC__
-# define CLOCKS_PER_SEC 1000000
-
-# ifndef NULL
-# define NULL 0
-# endif
-
-# ifndef _CLOCK_T
-# define _CLOCK_T
- typedef unsigned long clock_t;
-# endif /* _CLOCK_T */
-
-# ifndef _TIME_T
-# define _TIME_T
- typedef long time_t;
-# endif /* _TIME_T */
-
-# ifndef _SIZE_T
-# define _SIZE_T
- typedef unsigned int size_t;
-# endif /* _SIZE_T */
-
- /* Structure used with gmtime(), localtime(), mktime(), strftime(). */
- struct tm {
- int tm_sec; /* second (0-61, allows for leap seconds) */
- int tm_min; /* minute (0-59) */
- int tm_hour; /* hour (0-23) */
- int tm_mday; /* day of the month (1-31) */
- int tm_mon; /* month (0-11) */
- int tm_year; /* years since 1900 */
- int tm_wday; /* day of the week (0-6) */
- int tm_yday; /* day of the year (0-365) */
- int tm_isdst; /* non-0 if daylight savings time is in effect */
- };
-#endif /* _INCLUDE__STDC__ */
-
-
-/* Additional types needed for HP-UX */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifndef _STRUCT_TIMEVAL
-# define _STRUCT_TIMEVAL
- /* Structure returned by gettimeofday(2) system call and others */
- struct timeval {
- unsigned long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
- };
-# endif /* _STRUCT_TIMEVAL */
-
- /* Structure used to represent timezones for gettimeofday(2) and others */
- struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
- };
-
- /* Structure defining a timer setting. */
- struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
- };
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-
-/* Function prototypes and external variable declarations */
-
-#ifndef _KERNEL
-#ifdef __cplusplus
- extern "C" {
-#endif /* __cplusplus */
-
-#ifdef _INCLUDE__STDC__
-# ifdef _PROTOTYPES
- extern double difftime(time_t, time_t);
- extern time_t mktime(struct tm *);
- extern time_t time(time_t *);
- extern char *ctime(const time_t *);
- extern struct tm *gmtime(const time_t *);
- extern struct tm *localtime(const time_t *);
- extern size_t strftime(char *, size_t, const char *, const struct tm *);
-# else /* not _PROTOTYPES */
- extern double difftime();
- extern time_t mktime();
- extern time_t time();
- extern char *ctime();
- extern struct tm *gmtime();
- extern struct tm *localtime();
- extern size_t strftime();
-# endif /* not _PROTOTYPES */
-
-# ifdef _CLASSIC_ANSI_TYPES
- extern long clock();
-# else /* not _CLASSIC_ANSI_TYPES */
-# ifdef _PROTOTYPES
- extern clock_t clock(void);
-# else /* not _PROTOTYPES */
- extern clock_t clock();
-# endif /* not _PROTOTYPES */
-# endif /* not _CLASSIC_ANSI_TYPES */
-#endif /* _INCLUDE__STDC__ */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifdef _PROTOTYPES
- extern void tzset(void);
-# else /* not _PROTOTYPES */
- extern void tzset();
-# endif /* not _PROTOTYPES */
-
- extern char *tzname[2];
-#endif /* _INCLUDE_POSIX_SOURCE */
-
-
-#ifdef _INCLUDE_XOPEN_SOURCE
-# ifdef _PROTOTYPES
- extern char *strptime(const char *, const char *, struct tm *);
-# else /* not _PROTOTYPES */
- extern char *strptime();
-# endif /* not _PROTOTYPES */
-
- extern long timezone;
- extern int daylight;
-#endif /* _INCLUDE_XOPEN_SOURCE */
-
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifdef _PROTOTYPES
- extern struct tm *getdate(const char *);
- extern char *nl_asctime(struct tm *, char *, int);
- extern char *nl_ctime(long *, char *, int);
- extern char *nl_ascxtime(struct tm *, char *);
- extern char *nl_cxtime(long *, char *);
- extern int getitimer(int, struct itimerval *);
- extern int setitimer(int, const struct itimerval *, struct itimerval *);
- extern int gettimeofday(struct timeval *, struct timezone *);
- extern int settimeofday(const struct timeval *, const struct timezone *);
- extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
- extern int stime(const time_t *);
-# else /* not _PROTOTYPES */
- extern struct tm *getdate();
- extern char *nl_asctime();
- extern char *nl_ctime();
- extern char *nl_ascxtime();
- extern char *nl_cxtime();
- extern int getitimer();
- extern int setitimer();
- extern int gettimeofday();
- extern int settimeofday();
- extern int select();
- extern int stime();
-# endif /* not _PROTOTYPES */
- extern int getdate_err;
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#ifdef __cplusplus
- }
-#endif /* __cplusplus */
-#endif /* not _KERNEL */
-
-
-/*
- * CLK_TCK is needed by the kernel, and also in the POSIX namespace.
- */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifndef CLK_TCK
-# ifdef __hp9000s300
-# define CLK_TCK 50
-# endif /* __hp9000s300 */
-# ifdef __hp9000s800
-# define CLK_TCK 100
-# endif /* __hp9000s800 */
-# endif /* CLK_TCK */
-#endif
-
-
-/* Additional HP-UX structures, macros, and constants */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-
- /* Kernel instrumentation time value */
- struct ki_timeval {
- long tv_sec; /* seconds */
- long tv_nunit; /* and native units */
- };
-
- /* Kinds of daylight savings time */
-# define DST_NONE 0 /* not on dst */
-# define DST_USA 1 /* USA style dst */
-# define DST_AUST 2 /* Australian style dst */
-# define DST_WET 3 /* Western European dst */
-# define DST_MET 4 /* Middle European dst */
-# define DST_EET 5 /* Eastern European dst */
-
- /*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-# define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
-
- /* Names of the interval timers */
-# define ITIMER_REAL 0
-# define ITIMER_VIRTUAL 1
-# define ITIMER_PROF 2
-
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#endif /* _SYS_TIME_INCLUDED */
diff --git a/mit-pthreads/machdep/hpux-10.20/timers.h b/mit-pthreads/machdep/hpux-10.20/timers.h
deleted file mode 100755
index 5a76a295400..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/timers.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/signal.h>
-#include <sys/types.h>
-#include <time.h>
-
-/*
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-*/
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/uio.h b/mit-pthreads/machdep/hpux-10.20/uio.h
deleted file mode 100755
index d1ec4c94f22..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/uio.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct HP-UX header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/hpux-10.20/wait.h b/mit-pthreads/machdep/hpux-10.20/wait.h
deleted file mode 100755
index bca70d9f1ec..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/wait.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#define _W_INT(i) (i)
-#define WCOREFLAG 0200
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-#endif
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/__math.h b/mit-pthreads/machdep/hpux-9.03/__math.h
deleted file mode 100755
index 8066bd60713..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__math.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#define HUGE_VAL 1.7976931348623157e+308
-
-
diff --git a/mit-pthreads/machdep/hpux-9.03/__signal.h b/mit-pthreads/machdep/hpux-9.03/__signal.h
deleted file mode 100755
index fbb1d6ce2b1..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__signal.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <sys/signal.h>
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-/* #define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1))) */
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0, 0, 0, 0, 0 }
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff,\
- 0xffffffff,0xffffffff,0xffffffff,0xffffffff}
-#define __SIGADDSET(s, n) ((s)->sigset[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->sigset[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) ((s)->sigset[sigword(n)] & sigmask(n))
-
-#define SIGSET_SIZE sizeof(sigset_t)/sizeof(long)
-
-#define SIG_ANY(sig) sig_any(&sig)
-
-static inline int sig_any(sigset_t *sig) {
- int i;
- for (i=0; i < SIGSET_SIZE; i++)
- if (sig->sigset[i] != 0)
- return 1;
- return 0;
-}
-
diff --git a/mit-pthreads/machdep/hpux-9.03/__stdio.h b/mit-pthreads/machdep/hpux-9.03/__stdio.h
deleted file mode 100755
index 091b065a2e9..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
-
diff --git a/mit-pthreads/machdep/hpux-9.03/__stdlib.h b/mit-pthreads/machdep/hpux-9.03/__stdlib.h
deleted file mode 100755
index 37a14a960d5..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__stdlib.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/__string.h b/mit-pthreads/machdep/hpux-9.03/__string.h
deleted file mode 100755
index 1badf6d660c..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS_STDSYMS_INCLUDED
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard SunOS 4.x string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/__time.h b/mit-pthreads/machdep/hpux-9.03/__time.h
deleted file mode 100755
index ae958dcc3cf..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__time.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#define CLOCKS_PER_SEC 1000000
-
-#if !defined(_ANSI_SOURCE) && !defined(CLK_TCK)
-#define CLK_TCK 60
-#endif /* not ANSI */
-
-#endif
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/hpux-9.03/__unistd.h b/mit-pthreads/machdep/hpux-9.03/__unistd.h
deleted file mode 100755
index 0e8515b1f96..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__unistd.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* /afs/sipb.mit.edu/project/pthreads/src/CVS/pthreads/machdep/hpux-9.03/__unist
-d.h,v 1.2 1995/03/10 03:59:53 snl Exp */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/stdsyms.h>
-#include <sys/types.h>
-#include <utime.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _GID_T
-#define _GID_T
-typedef long gid_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef _PID_T
-#define _PID_T
-typedef long pid_t;
-#endif
-
-#ifndef _OFF_T
-#define _OFF_T
-typedef long off_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-/* Symbolic constants for sysconf() variables defined by POSIX.1-1988: 0-7 */
-
-#define _SC_ARG_MAX 0 /* ARG_MAX: Max length of argument to exec()
- including environment data */
-#define _SC_CHILD_MAX 1 /* CHILD_MAX: Max of processes per userid */
-#define _SC_CLK_TCK 2 /* Number of clock ticks per second */
-#define _SC_NGROUPS_MAX 3 /* NGROUPS_MAX: Max of simultaneous
- supplementary group IDs per process */
-#define _SC_OPEN_MAX 4 /* OPEN_MAX: Max of files that one process
- can have open at any one time */
-#define _SC_JOB_CONTROL 5 /* _POSIX_JOB_CONTROL: 1 iff supported */
-#define _SC_SAVED_IDS 6 /* _POSIX_SAVED_IDS: 1 iff supported */
-#define _SC_1_VERSION_88 7 /* _POSIX_VERSION: Date of POSIX.1-1988 */
-
-/* Symbolic constants for sysconf() variables added by POSIX.1-1990: 100-199 */
-
-#define _SC_STREAM_MAX 100 /* STREAM_MAX: Max of open stdio FILEs */
-#define _SC_TZNAME_MAX 101 /* TZNAME_MAX: Max length of timezone name */
-#define _SC_1_VERSION_90 102 /* _POSIX_VERSION: Date of POSIX.1-1990 */
-
-#endif /* _SYS___UNISTD_H_ */
-
diff --git a/mit-pthreads/machdep/hpux-9.03/cdefs.h b/mit-pthreads/machdep/hpux-9.03/cdefs.h
deleted file mode 100755
index 041300cbe02..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/cdefs.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __INLINE static
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/compat.h b/mit-pthreads/machdep/hpux-9.03/compat.h
deleted file mode 100755
index 5a59434417c..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Compatibility header for networking code.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/dirent.h b/mit-pthreads/machdep/hpux-9.03/dirent.h
deleted file mode 100755
index 5f17af345db..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/dirent.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/hpux-9.03/socket.h b/mit-pthreads/machdep/hpux-9.03/socket.h
deleted file mode 100755
index c7a37706940..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/socket.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-#include <sys/stdsyms.h>
-#include <pthread/posix.h>
-#include <sys/cdefs.h>
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_SND_COPYAVOID 0x1009 /* avoid copy on send*/
-#define SO_RCV_COPYAVOID 0x100a /* avoid copy on rcv */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_OTS 17 /* Used for OSI in the ifnets */
-#define AF_NIT 18 /* NIT */
-
-#define AF_MAX 19
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 20
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/hpux-9.03/stdtypes.h b/mit-pthreads/machdep/hpux-9.03/stdtypes.h
deleted file mode 100755
index 2b22abbf818..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/stdtypes.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* @(#)stdtypes.h 1.6 90/01/04 SMI */
-
-/*
- * Suppose you have an ANSI C or POSIX thingy that needs a typedef
- * for thingy_t. Put it here and include this file wherever you
- * define the thingy. This is used so that we don't have size_t in
- * N (N > 1) different places and so that we don't have to have
- * types.h included all the time and so that we can include this in
- * the lint libs instead of termios.h which conflicts with ioctl.h.
- */
-#ifndef __sys_stdtypes_h
-#define __sys_stdtypes_h
-
-#ifndef _SIGSET_T_
-#define _SIGSET_T_
-typedef int sigset_t; /* signal mask - may change */
-#endif
-
-#ifndef _SPEED_T_
-#define _SPEED_T_
-typedef unsigned int speed_t; /* tty speeds */
-#endif
-
-#ifndef _TCFLAG_T_
-#define _TCFLAG_T_
-typedef unsigned long tcflag_t; /* tty line disc modes */
-#endif
-
-#ifndef _CC_T_
-#define _CC_T_
-typedef unsigned char cc_t; /* tty control char */
-#endif
-
-#ifndef _PID_T_
-#define _PID_T_
-typedef int pid_t; /* process id */
-#endif
-
-#ifndef _MODE_T_
-#define _MODE_T_
-typedef unsigned short mode_t; /* file mode bits */
-#endif
-
-#ifndef _NLINK_T_
-#define _NLINK_T_
-typedef short nlink_t; /* links to a file */
-#endif
-
-#ifndef _CLOCK_T_
-#define _CLOCK_T_
-typedef long clock_t; /* units=ticks (typically 60/sec) */
-#endif
-
-#ifndef _TIME_T_
-#define _TIME_T_
-typedef long time_t; /* value = secs since epoch */
-#endif
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef int size_t; /* ??? */
-#endif
-
-#ifndef _PTRDIFF_T_
-#define _PTRDIFF_T_
-typedef int ptrdiff_t; /* result of subtracting two pointers */
-#endif
-
-#ifndef _WCHAR_T_
-#define _WCHAR_T_
-typedef unsigned short wchar_t; /* big enough for biggest char set */
-#endif
-
-#endif /* !__sys_stdtypes_h */
diff --git a/mit-pthreads/machdep/hpux-9.03/time.h b/mit-pthreads/machdep/hpux-9.03/time.h
deleted file mode 100755
index 544905b0749..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/time.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* $Header$ */
-
-#ifndef _SYS_TIME_INCLUDED
-#define _SYS_TIME_INCLUDED
-
-/* time.h: Definitions for time handling functions */
-
-#ifdef _KERNEL_BUILD
-#include "../h/stdsyms.h"
-#else /* ! _KERNEL_BUILD */
-#include <sys/stdsyms.h>
-#endif /* _KERNEL_BUILD */
-
-#include <sys/types.h>
-
-/* ANSI C time constants, types, and structures */
-
-#ifdef _INCLUDE__STDC__
-# define CLOCKS_PER_SEC 1000000
-
-# ifndef NULL
-# define NULL 0
-# endif
-
-# ifndef _CLOCK_T
-# define _CLOCK_T
- typedef unsigned long clock_t;
-# endif /* _CLOCK_T */
-
-# ifndef _TIME_T
-# define _TIME_T
- typedef long time_t;
-# endif /* _TIME_T */
-
-# ifndef _SIZE_T
-# define _SIZE_T
- typedef unsigned int size_t;
-# endif /* _SIZE_T */
-
- /* Structure used with gmtime(), localtime(), mktime(), strftime(). */
- struct tm {
- int tm_sec; /* second (0-61, allows for leap seconds) */
- int tm_min; /* minute (0-59) */
- int tm_hour; /* hour (0-23) */
- int tm_mday; /* day of the month (1-31) */
- int tm_mon; /* month (0-11) */
- int tm_year; /* years since 1900 */
- int tm_wday; /* day of the week (0-6) */
- int tm_yday; /* day of the year (0-365) */
- int tm_isdst; /* non-0 if daylight savings time is in effect */
- };
-#endif /* _INCLUDE__STDC__ */
-
-
-/* Additional types needed for HP-UX */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifndef _STRUCT_TIMEVAL
-# define _STRUCT_TIMEVAL
- /* Structure returned by gettimeofday(2) system call and others */
- struct timeval {
- unsigned long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
- };
-# endif /* _STRUCT_TIMEVAL */
-
- /* Structure used to represent timezones for gettimeofday(2) and others */
- struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
- };
-
- /* Structure defining a timer setting. */
- struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
- };
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-
-/* Function prototypes and external variable declarations */
-
-#ifndef _KERNEL
-#ifdef __cplusplus
- extern "C" {
-#endif /* __cplusplus */
-
-#ifdef _INCLUDE__STDC__
-# ifdef _PROTOTYPES
- extern double difftime(time_t, time_t);
- extern time_t mktime(struct tm *);
- extern time_t time(time_t *);
- extern char *ctime(const time_t *);
- extern struct tm *gmtime(const time_t *);
- extern struct tm *localtime(const time_t *);
- extern size_t strftime(char *, size_t, const char *, const struct tm *);
-# else /* not _PROTOTYPES */
- extern double difftime();
- extern time_t mktime();
- extern time_t time();
- extern char *ctime();
- extern struct tm *gmtime();
- extern struct tm *localtime();
- extern size_t strftime();
-# endif /* not _PROTOTYPES */
-
-# ifdef _CLASSIC_ANSI_TYPES
- extern long clock();
-# else /* not _CLASSIC_ANSI_TYPES */
-# ifdef _PROTOTYPES
- extern clock_t clock(void);
-# else /* not _PROTOTYPES */
- extern clock_t clock();
-# endif /* not _PROTOTYPES */
-# endif /* not _CLASSIC_ANSI_TYPES */
-#endif /* _INCLUDE__STDC__ */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifdef _PROTOTYPES
- extern void tzset(void);
-# else /* not _PROTOTYPES */
- extern void tzset();
-# endif /* not _PROTOTYPES */
-
- extern char *tzname[2];
-#endif /* _INCLUDE_POSIX_SOURCE */
-
-
-#ifdef _INCLUDE_XOPEN_SOURCE
-# ifdef _PROTOTYPES
- extern char *strptime(const char *, const char *, struct tm *);
-# else /* not _PROTOTYPES */
- extern char *strptime();
-# endif /* not _PROTOTYPES */
-
- extern long timezone;
- extern int daylight;
-#endif /* _INCLUDE_XOPEN_SOURCE */
-
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifdef _PROTOTYPES
- extern struct tm *getdate(const char *);
- extern char *nl_asctime(struct tm *, char *, int);
- extern char *nl_ctime(long *, char *, int);
- extern char *nl_ascxtime(struct tm *, char *);
- extern char *nl_cxtime(long *, char *);
- extern int getitimer(int, struct itimerval *);
- extern int setitimer(int, const struct itimerval *, struct itimerval *);
- extern int gettimeofday(struct timeval *, struct timezone *);
- extern int settimeofday(const struct timeval *, const struct timezone *);
- extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
- extern int stime(const time_t *);
-# else /* not _PROTOTYPES */
- extern struct tm *getdate();
- extern char *nl_asctime();
- extern char *nl_ctime();
- extern char *nl_ascxtime();
- extern char *nl_cxtime();
- extern int getitimer();
- extern int setitimer();
- extern int gettimeofday();
- extern int settimeofday();
- extern int select();
- extern int stime();
-# endif /* not _PROTOTYPES */
- extern int getdate_err;
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#ifdef __cplusplus
- }
-#endif /* __cplusplus */
-#endif /* not _KERNEL */
-
-
-/*
- * CLK_TCK is needed by the kernel, and also in the POSIX namespace.
- */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifndef CLK_TCK
-# ifdef __hp9000s300
-# define CLK_TCK 50
-# endif /* __hp9000s300 */
-# ifdef __hp9000s800
-# define CLK_TCK 100
-# endif /* __hp9000s800 */
-# endif /* CLK_TCK */
-#endif
-
-
-/* Additional HP-UX structures, macros, and constants */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-
- /* Kernel instrumentation time value */
- struct ki_timeval {
- long tv_sec; /* seconds */
- long tv_nunit; /* and native units */
- };
-
- /* Kinds of daylight savings time */
-# define DST_NONE 0 /* not on dst */
-# define DST_USA 1 /* USA style dst */
-# define DST_AUST 2 /* Australian style dst */
-# define DST_WET 3 /* Western European dst */
-# define DST_MET 4 /* Middle European dst */
-# define DST_EET 5 /* Eastern European dst */
-
- /*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-# define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
-
- /* Names of the interval timers */
-# define ITIMER_REAL 0
-# define ITIMER_VIRTUAL 1
-# define ITIMER_PROF 2
-
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#endif /* _SYS_TIME_INCLUDED */
diff --git a/mit-pthreads/machdep/hpux-9.03/timers.h b/mit-pthreads/machdep/hpux-9.03/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/uio.h b/mit-pthreads/machdep/hpux-9.03/uio.h
deleted file mode 100755
index d1ec4c94f22..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/uio.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct HP-UX header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/hpux-9.03/wait.h b/mit-pthreads/machdep/hpux-9.03/wait.h
deleted file mode 100755
index bca70d9f1ec..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/wait.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#define _W_INT(i) (i)
-#define WCOREFLAG 0200
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-#endif
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/irix-5.2/__math.h b/mit-pthreads/machdep/irix-5.2/__math.h
deleted file mode 100755
index 229d5121524..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__math.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/irix-5.2/__signal.h b/mit-pthreads/machdep/irix-5.2/__signal.h
deleted file mode 100755
index 87797da3198..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__signal.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <sys/signal.h>
-
-typedef int sig_atomic_t;
-
-#ifndef sigmask
-#define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
-#endif
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0 };
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff };
-#define __SIGADDSET(s, n) ((s)->sigbits[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->sigbits[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) (sigmask(n) & (s)->sigbits[sigword(n)])
-
diff --git a/mit-pthreads/machdep/irix-5.2/__stdio.h b/mit-pthreads/machdep/irix-5.2/__stdio.h
deleted file mode 100755
index bb4c14b32c6..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__stdio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/irix-5.2/__stdlib.h b/mit-pthreads/machdep/irix-5.2/__stdlib.h
deleted file mode 100755
index 2bec122c5f1..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__stdlib.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <sgidefs.h>
-
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-#if (_MIPS_SZLONG == 32)
-typedef unsigned int size_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef unsigned long size_t;
-#endif
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-#if (_MIPS_SZLONG == 32)
-typedef long wchar_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef __int32_t wchar_t;
-#endif
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
diff --git a/mit-pthreads/machdep/irix-5.2/__string.h b/mit-pthreads/machdep/irix-5.2/__string.h
deleted file mode 100755
index 50261e73cfc..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__string.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
diff --git a/mit-pthreads/machdep/irix-5.2/__time.h b/mit-pthreads/machdep/irix-5.2/__time.h
deleted file mode 100755
index 51fb993b38d..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__time.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef pthread_clock_t clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef pthread_time_t time_t;
-#endif /* !_TIME_T */
-
-#define CLOCKS_PER_SEC 1000000
-
-#ifndef CLK_TCK
-#define CLK_TCK sysconf(3) /* clock ticks per second */
- /* 3 is _SC_CLK_TCK */
-#endif
diff --git a/mit-pthreads/machdep/irix-5.2/__unistd.h b/mit-pthreads/machdep/irix-5.2/__unistd.h
deleted file mode 100755
index 0d71d631a5b..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__unistd.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type int /* For fd.c */
diff --git a/mit-pthreads/machdep/irix-5.2/compat.h b/mit-pthreads/machdep/irix-5.2/compat.h
deleted file mode 100755
index 8fd504e504f..00000000000
--- a/mit-pthreads/machdep/irix-5.2/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description :
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/irix-5.2/dirent.h b/mit-pthreads/machdep/irix-5.2/dirent.h
deleted file mode 100755
index 79fe486951d..00000000000
--- a/mit-pthreads/machdep/irix-5.2/dirent.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _SYS_DIRENT_H
-#define _SYS_DIRENT_H
-
-#if !defined(_POSIX_SOURCE)
-#define MAXNAMLEN 255 /* maximum filename length */
-#define DIRBUF 4096 /* buffer size for fs-indep. dirs */
-#endif /* !defined(_POSIX_SOURCE) */
-
-#include <sys/types.h>
-
-struct dirent { /* data from readdir() */
- ino_t d_ino; /* inode number of entry */
- off_t d_off; /* offset of disk direntory entry */
- unsigned short d_reclen; /* length of this record */
- char d_name[MAXNAMLEN+1];/* name of file */
-};
-
-#define d_namlen d_reclen
-#define d_fileno d_ino
-
-#endif /* _SYS_DIRENT_H */
diff --git a/mit-pthreads/machdep/irix-5.2/socket.h b/mit-pthreads/machdep/irix-5.2/socket.h
deleted file mode 100755
index b08d3939802..00000000000
--- a/mit-pthreads/machdep/irix-5.2/socket.h
+++ /dev/null
@@ -1,304 +0,0 @@
-#ifndef __SYS_TPI_SOCKET_H__
-#ifndef __SYS_SOCKET_H__
-#define __SYS_SOCKET_H__
-/*
- * Copyright (c) 1982,1985, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)socket.h 7.1 (Berkeley) 6/4/86
- */
-#include <sys/cdefs.h>
-#include <sys/bsd_types.h>
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#ifdef _STYPES_LATER /* old ABI */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-#else /* !_STYPES_LATER, new ABI */
-
-#ifndef NC_TPI_CLTS
-#define NC_TPI_CLTS 1 /* must agree with netconfig.h */
-#define NC_TPI_COTS 2 /* must agree with netconfig.h */
-#define NC_TPI_COTS_ORD 3 /* must agree with netconfig.h */
-#define NC_TPI_RAW 4 /* must agree with netconfig.h */
-#endif /* !NC_TPI_CLTS */
-
-#define SOCK_DGRAM NC_TPI_CLTS /* datagram socket */
-#define SOCK_STREAM NC_TPI_COTS /* stream socket */
-#define SOCK_RAW NC_TPI_RAW /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-#ifdef _KERNEL
-#define IRIX4_SOCK_STREAM 1 /* stream socket */
-#define IRIX4_SOCK_DGRAM 2 /* datagram socket */
-#define IRIX4_SOCK_RAW 3 /* raw-protocol interface */
-#define IRIX4_SOCK_RDM 4 /* reliably-delivered message */
-#define IRIX4_SOCK_SEQPACKET 5 /* sequenced packet stream */
-#endif /* _KERNEL */
-#endif /* _STYPES_LATER */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-#define SO_REUSEPORT 0x0200 /* allow local address,port reuse */
-#define SO_ORDREL 0x0200 /* MIPS ABI - unimplemented */
-#define SO_IMASOCKET 0x0400 /* use libsocket (not TLI) semantics */
-#define SO_CHAMELEON 0x1000 /* (cipso) set label to 1st req rcvd */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get protocol type (libsocket) */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- * XTP really is not an address family, but is included here to take
- * up space, because other AF_ entries are numerically equal to their
- * PF_ counterparts.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_ISO 7 /* ISO protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_ROUTE 17 /* Internal Routing Protocol */
-#ifdef __sgi
-#define AF_RAW 18 /* Raw link layer interface */
-#else
-#define AF_LINK 18 /* Link layer interface */
-#endif
-#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-
-/* MIPS ABI VALUES - unimplemented */
-#define AF_NIT 17 /* Network Interface Tap */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_OSI 19 /* umbrella for all families used */
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21 /* AFI = 47, IDI = 4 */
-#define AF_GOSIP 22 /* U.S. Government OSI */
-
-
-#define AF_SDL 23 /* SGI Data Link for DLPI */
-
-#define AF_MAX (AF_SDL+1)
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * An option specification consists of an opthdr, followed by the value of
- * the option. An options buffer contains one or more options. The len
- * field of opthdr specifies the length of the option value in bytes. This
- * length must be a multiple of sizeof(long) (use OPTLEN macro).
- */
-
-struct opthdr {
- long level; /* protocol level affected */
- long name; /* option to modify */
- long len; /* length of option value */
-};
-
-#define OPTLEN(x) ((((x) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
-#define OPTVAL(opt) ((char *)(opt + 1))
-
-/*
- * the optdefault structure is used for internal tables of option default
- * values.
- */
-struct optdefault {
- int optname; /* the option */
- char *val; /* ptr to default value */
- int len; /* length of value */
-};
-
-struct tpisocket;
-struct T_optmgmt_req;
-struct msgb;
-
-/*
- * the opproc structure is used to build tables of options processing
- * functions for dooptions().
- */
-struct opproc {
- int level; /* options level this function handles */
- int (*func)(struct tpisocket *, struct T_optmgmt_req *,
- struct opthdr *, struct msgb *);
- /* the function */
-};
-
-/*
- * This structure is used to encode pseudo system calls
- */
-struct socksysreq {
- int args[7];
-};
-
-/*
- * This structure is used for adding new protocols to the list supported by
- * sockets.
- */
-
-struct socknewproto {
- int family; /* address family (AF_INET, etc.) */
- int type; /* protocol type (SOCK_STREAM, etc.) */
- int proto; /* per family proto number */
- dev_t dev; /* major/minor to use (must be a clone) */
- int flags; /* protosw flags */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_ISO AF_ISO
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_ROUTE AF_ROUTE
-#define PF_LINK AF_LINK
-#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-#ifdef __sgi
-#define PF_RAW AF_RAW
-#endif
-
-/* MIPS ABI VALUES - unimplemented */
-#define PF_NIT AF_NIT /* Network Interface Tap */
-#define PF_802 AF_802 /* IEEE 802.2, also ISO 8802 */
-#define PF_OSI AF_OSI /* umbrella for all families used */
-#define PF_X25 AF_X25 /* CCITT X.25 in particular */
-#define PF_OSINET AF_OSINET /* AFI = 47, IDI = 4 */
-#define PF_GOSIP AF_GOSIP /* U.S. Government OSI */
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-#define MSG_EOR 0x8 /* data completes record (OSI only) */
-#ifdef XTP
-#define MSG_BTAG 0x40 /* XTP packet with BTAG field */
-#define MSG_ETAG 0x80 /* XTP packet with ETAG field */
-#endif
-
-#define MSG_MAXIOVLEN 16
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int, struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !__SYS_SOCKET_H__ */
-#endif /* !__SYS_TPI_SOCKET_H__ */
diff --git a/mit-pthreads/machdep/irix-5.2/timers.h b/mit-pthreads/machdep/irix-5.2/timers.h
deleted file mode 100755
index ffa24dc9a15..00000000000
--- a/mit-pthreads/machdep/irix-5.2/timers.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __SYS_TIMERS_H__
-#define __SYS_TIMERS_H__
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-#endif /* !__SYS_TIMERS_H__ */
diff --git a/mit-pthreads/machdep/irix-5.2/wait.h b/mit-pthreads/machdep/irix-5.2/wait.h
deleted file mode 100755
index c0a7e7113d8..00000000000
--- a/mit-pthreads/machdep/irix-5.2/wait.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)wait.h 7.4 (Berkeley) 1/27/88
- */
-#ifndef __SYS_WAIT_H__
-#define __SYS_WAIT_H__
-
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define WSTOPFLG 0177
-#define WIFSTOPPED(stat) ((_W_INT(stat)&0377)==_WSTOPPED&&((_W_INT(stat)>>8)&0377)!=0)
-#define WSTOPSIG(stat) ((_W_INT(stat)>>8)&0377)
-#define WIFSIGNALED(stat) ((_W_INT(stat)&0377)>0&&((_W_INT(stat)>>8)&0377)==0)
-#define WTERMSIG(stat) (_W_INT(stat)&0177)
-#define WIFEXITED(stat) ((_W_INT(stat)&0377)==0)
-#define WEXITSTATUS(stat) ((_W_INT(stat)>>8)&0377)
-#define WCOREDUMP(stat) (_W_INT(stat) & WCOREFLAG)
-
-/*
- * Option bits for the second argument of wait3. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 0100
-#define WUNTRACED 0004 /* for POSIX */
-
-#if !defined(_POSIX_SOURCE)
-
-/*
- * Structure of the information in the first word returned by both
- * wait and wait3. If w_stopval==_WSTOPPED, then the second structure
- * describes the information returned, else the first. See WUNTRACED below.
- */
-typedef union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#ifdef _MIPSEL
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#ifdef _MIPSEB
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#ifdef _MIPSEL
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#ifdef _MIPSEB
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-} wait_t;
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-
-
-#define WSTOPPED 0004 /* wait for processes stopped by signals */
-#endif /* !defined(_POSIX_SOURCE) */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-__BEGIN_DECLS
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-
-#endif /* __SYS_WAIT_H__ */
diff --git a/mit-pthreads/machdep/linux-1.0/__math.h b/mit-pthreads/machdep/linux-1.0/__math.h
deleted file mode 100755
index 05c65d58321..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__math.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef HUGE_VAL
-#define HUGE_VAL DBL_MAX
-#endif
-
diff --git a/mit-pthreads/machdep/linux-1.0/__path.h b/mit-pthreads/machdep/linux-1.0/__path.h
deleted file mode 100755
index 9caeb7d3016..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/lib/zoneinfo"
-#define _PATH_TZFILE "/usr/lib/zoneinfo/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/linux-1.0/__signal.h b/mit-pthreads/machdep/linux-1.0/__signal.h
deleted file mode 100755
index 4cd671f155c..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__signal.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <features.h>
-#include <linux/signal.h>
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-typedef int sig_atomic_t;
-
-typedef __sighandler_t SignalHandler;
-
-#define SignalBad ((SignalHandler)-1)
-#define SignalDefault ((SignalHandler)0)
-#define SignalIgnore ((SignalHandler)1)
-
-#define __sigmask(sig) (1 << ((sig) - 1))
-#define sigmask __sigmask
-
-#define __SIGFILLSET 0xffffffff
-#define __SIGEMPTYSET 0
-#define __SIGADDSET(s,n) ((*s) |= (__sigmask(n)))
-#define __SIGDELSET(s,n) ((*s) &= ~(__sigmask(n)))
-#define __SIGISMEMBER(s,n) ((*s) & (__sigmask(n)))
-
diff --git a/mit-pthreads/machdep/linux-1.0/__stdio.h b/mit-pthreads/machdep/linux-1.0/__stdio.h
deleted file mode 100755
index eb7e904c34d..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__stdio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/linux-1.0/__stdlib.h b/mit-pthreads/machdep/linux-1.0/__stdlib.h
deleted file mode 100755
index eaa0bb988ee..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__stdlib.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <features.h>
-
-/* Get size_t, wchar_t and NULL from <stddef.h>. */
-#define __need_size_t
-#define __need_wchar_t
-#define __need_NULL
-#include <stddef.h>
-
-#define __need_Emath
-#include <errno.h>
-
-/* Get HUGE_VAL (returned by strtod on overflow) from <float.h>. */
-#define __need_HUGE_VAL
-#include <float.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/__string.h b/mit-pthreads/machdep/linux-1.0/__string.h
deleted file mode 100755
index 8a5e09608e0..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__string.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard Linux string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/__time.h b/mit-pthreads/machdep/linux-1.0/__time.h
deleted file mode 100755
index a088268286e..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__time.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ==== __time.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <features.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *) 0)
-#endif
-#endif
-#endif
-
-#define CLOCKS_PER_SEC 100
-#define CLK_TCK 100
-
-extern long int timezone;
-extern int daylight;
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/__unistd.h b/mit-pthreads/machdep/linux-1.0/__unistd.h
deleted file mode 100755
index 0f15b7c4883..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__unistd.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-#define ioctl_request_type int /* For fd.c */
-
-#include <posix_opt.h>
-#include <sys/types.h>
-#include <stddef.h>
-
-#endif
-
diff --git a/mit-pthreads/machdep/linux-1.0/cdefs.h b/mit-pthreads/machdep/linux-1.0/cdefs.h
deleted file mode 100755
index f9d5668cfe6..00000000000
--- a/mit-pthreads/machdep/linux-1.0/cdefs.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This is intended to eventually find /usr/include/sys/cdefs.h
- * if it's inside the ifdef then it won't work if this file is
- * found in the include files path more than once.
- *
- * include_next is a GNU C extension, we might eventually want
- * to have our own cdefs in here simply to avoid GNU C dependencies
- * (though there are already enough in the asm stuff anyways)
- * [gsstark:19950419.0307EST]
- */
-#include_next <sys/cdefs.h>
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#if !defined(__cplusplus)
-#define __CAN_DO_EXTERN_INLINE
-#endif
-
-#endif /* _PTHREAD_SYS_CDEFS_H_ */
diff --git a/mit-pthreads/machdep/linux-1.0/compat.h b/mit-pthreads/machdep/linux-1.0/compat.h
deleted file mode 100755
index 6edb992ac3d..00000000000
--- a/mit-pthreads/machdep/linux-1.0/compat.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#include <sys/types.h>
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/dirent.h b/mit-pthreads/machdep/linux-1.0/dirent.h
deleted file mode 100755
index 7f783a198e0..00000000000
--- a/mit-pthreads/machdep/linux-1.0/dirent.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS_DIRENT_H
-#define _SYS_DIRENT_H
-
-#include <sys/types.h>
-#include <linux/limits.h>
-
-struct dirent {
- long d_ino;
- off_t d_off;
- unsigned short d_reclen;
- char d_name[NAME_MAX+1];
-};
-
-#ifndef d_fileno
-#define d_fileno d_ino
-#endif
-
-#ifndef d_namlen
-#define d_namlen d_reclen
-#endif
-
-#ifndef MAXNAMLEN
-#define MAXNAMLEN NAME_MAX
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/errno.h b/mit-pthreads/machdep/linux-1.0/errno.h
deleted file mode 100755
index a94a56b0437..00000000000
--- a/mit-pthreads/machdep/linux-1.0/errno.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* ==== errno.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Errno is already broken up into data/prototyes.
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#include <linux/errno.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/socket.h b/mit-pthreads/machdep/linux-1.0/socket.h
deleted file mode 100755
index cc4c0fd262e..00000000000
--- a/mit-pthreads/machdep/linux-1.0/socket.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* ==== socket.h.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_SOCKET_H_
-#define _PTHREAD_SOCKET_H_
-
-/* #include <linux/socket.h> */
-#ifndef _LINUX_SOCKET_H
-#define _LINUX_SOCKET_H
-
-/* IP options */
-#define IP_TOS 1
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-#define IP_TTL 2
-#ifndef IP_HDRINCL
-#define IP_HDRINCL 3
-#endif
-#ifdef V1_3_WILL_DO_THIS_FUNKY_STUFF
-#define IP_OPTIONS 4
-#endif
-
-#endif
-
-/* #include <asm/socket.h> arch-dependent defines */
-#include <linux/sockios.h> /* the SIOCxxx I/O controls */
-#include <pthread/posix.h>
-
-struct sockaddr {
- unsigned short sa_family; /* address family, AF_xxx */
- char sa_data[14]; /* 14 bytes of protocol address */
-};
-
-struct linger {
- int l_onoff; /* Linger active */
- int l_linger; /* How long to linger for */
-};
-
-struct msghdr
-{
- void * msg_name; /* Socket name */
- int msg_namelen; /* Length of name */
- struct iovec * msg_iov; /* Data blocks */
- int msg_iovlen; /* Number of blocks */
- void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
- int msg_accrightslen;/* Length of rights list */
-};
-
-/* Socket types. */
-#define SOCK_STREAM 1 /* stream (connection) socket */
-#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
-#define SOCK_RAW 3 /* raw socket */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequential packet socket */
-#define SOCK_PACKET 10 /* linux specific way of */
- /* getting packets at the dev */
- /* level. For writing rarp and */
- /* other similar things on the */
- /* user level. */
-
-/* Supported address families. */
-#define AF_UNSPEC 0
-#define AF_UNIX 1 /* Unix domain sockets */
-#define AF_INET 2 /* Internet IP Protocol */
-#define AF_AX25 3 /* Amateur Radio AX.25 */
-#define AF_IPX 4 /* Novell IPX */
-#define AF_APPLETALK 5 /* Appletalk DDP */
-#define AF_NETROM 6 /* Amateur radio NetROM */
-#define AF_BRIDGE 7 /* Multiprotocol bridge */
-#define AF_AAL5 8 /* Reserved for Werner's ATM */
-#define AF_X25 9 /* Reserved for X.25 project */
-#define AF_INET6 10 /* IP version 6 */
-#define AF_MAX 12 /* For now.. */
-
-/* Protocol families, same as address families. */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_AX25 AF_AX25
-#define PF_IPX AF_IPX
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NETROM AF_NETROM
-#define PF_BRIDGE AF_BRIDGE
-#define PF_AAL5 AF_AAL5
-#define PF_X25 AF_X25
-#define PF_INET6 AF_INET6
-
-#define PF_MAX AF_MAX
-
-/* Maximum queue length specificable by listen. */
-#define SOMAXCONN 128
-
-/* Flags we can use with send/ and recv. */
-#define MSG_OOB 1
-#define MSG_PEEK 2
-#define MSG_DONTROUTE 4
-
-/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
-#define SOL_SOCKET 1
-#define SOL_IP 0
-#define SOL_IPX 256
-#define SOL_AX25 257
-#define SOL_ATALK 258
-#define SOL_NETROM 259
-#define SOL_TCP 6
-#define SOL_UDP 17
-
-/* For setsockoptions(2) */
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_LINGER 13
-/* To add :#define SO_REUSEPORT 14 */
-
-
-#define IP_MULTICAST_IF 32
-#define IP_MULTICAST_TTL 33
-#define IP_MULTICAST_LOOP 34
-#define IP_ADD_MEMBERSHIP 35
-#define IP_DROP_MEMBERSHIP 36
-
-
-/* These need to appear somewhere around here */
-#define IP_DEFAULT_MULTICAST_TTL 1
-#define IP_DEFAULT_MULTICAST_LOOP 1
-#define IP_MAX_MEMBERSHIPS 20
-
-/* IPX options */
-#define IPX_TYPE 1
-
-/* TCP options - this way around because someone left a set in the c library includes */
-#define TCP_NODELAY 1
-#define TCP_MAXSEG 2
-
-/* The various priorities. */
-#define SOPRI_INTERACTIVE 0
-#define SOPRI_NORMAL 1
-#define SOPRI_BACKGROUND 2
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-int getsockopt __P_((int __s, int __level, int __optname,
- void *__optval, int *__optlen));
-int setsockopt __P_((int __s, int __level, int __optname,
- __const void *__optval, int optlen));
-int getsockname __P_((int __sockfd, struct sockaddr *__addr,
- int *__paddrlen));
-int getpeername __P_((int __sockfd, struct sockaddr *__peer,
- int *__paddrlen));
-ssize_t send __P_((int __sockfd, __const void *__buff, size_t __len, int __flags));
-ssize_t recv __P_((int __sockfd, void *__buff, size_t __len, int __flags));
-ssize_t sendto __P_((int __sockfd, __const void *__buff, size_t __len,
- int __flags, __const struct sockaddr *__to,
- int __tolen));
-ssize_t recvfrom __P_((int __sockfd, void *__buff, size_t __len,
- int __flags, struct sockaddr *__from,
- int *__fromlen));
-extern ssize_t sendmsg __P_((int __fd, __const struct msghdr *__message,
- int __flags));
-extern ssize_t recvmsg __P_((int __fd, struct msghdr *__message,
- int __flags));
-int shutdown __P_((int __sockfd, int __how));
-
-__END_DECLS
-
-#endif
-
-
-
-
diff --git a/mit-pthreads/machdep/linux-1.0/timers.h b/mit-pthreads/machdep/linux-1.0/timers.h
deleted file mode 100755
index 110cb27378c..00000000000
--- a/mit-pthreads/machdep/linux-1.0/timers.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <pthread/config.h>
-#include <sys/types.h>
-#include <time.h>
-
-#ifndef _OS_HAS_TIMESPEC
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-#endif
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/uio.h b/mit-pthreads/machdep/linux-1.0/uio.h
deleted file mode 100755
index 67af5bf76e0..00000000000
--- a/mit-pthreads/machdep/linux-1.0/uio.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/wait.h b/mit-pthreads/machdep/linux-1.0/wait.h
deleted file mode 100755
index bcc28c5ef58..00000000000
--- a/mit-pthreads/machdep/linux-1.0/wait.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait and extract the
- * relevant values. Union wait is no supported with pthreads.
- */
-#define __W_INT(i) (i)
-#define __WSTATUS(x) (__W_INT(x) & 0177)
-#define __WSTOPPED 0177 /* __WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (__WSTATUS(x) == __WSTOPPED)
-#define WSTOPSIG(x) (__W_INT(x) >> 8)
-#define WIFSIGNALED(x) (__WSTATUS(x) != __WSTOPPED && __WSTATUS(x) != 0)
-#define WTERMSIG(x) (__WSTATUS(x))
-#define WIFEXITED(x) (__WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (__W_INT(x) >> 8)
-
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (__W_INT(x) & WCOREFLAG)
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | __WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-
-/* Tokens for special values of the "pid" parameter to wait4. */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED __WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-__BEGIN_DECLS
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
diff --git a/mit-pthreads/machdep/linux-2.0/__math.h b/mit-pthreads/machdep/linux-2.0/__math.h
deleted file mode 100755
index 05c65d58321..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__math.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef HUGE_VAL
-#define HUGE_VAL DBL_MAX
-#endif
-
diff --git a/mit-pthreads/machdep/linux-2.0/__path.h b/mit-pthreads/machdep/linux-2.0/__path.h
deleted file mode 100755
index 9caeb7d3016..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/lib/zoneinfo"
-#define _PATH_TZFILE "/usr/lib/zoneinfo/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/linux-2.0/__signal.h b/mit-pthreads/machdep/linux-2.0/__signal.h
deleted file mode 100755
index 81136b8c14d..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__signal.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <features.h>
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-#define _NSIG 64 /* Biggest signal number + 1
- (including real-time signals). */
-# define NSIG _NSIG
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX (_NSIG-1)
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-
-/* Type of a signal handler. */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
-#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
-#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
-
-typedef int sig_atomic_t;
-
-#define SignalBad ((SignalHandler)-1)
-#define SignalDefault ((SignalHandler)0)
-#define SignalIgnore ((SignalHandler)1)
-
-#include "bits/sigset.h"
-
-#define __SIGFILLSET {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
-#define __SIGEMPTYSET { 0,0,0,0,0,0,0,0 }
-#define __SIGADDSET(s,n) __sigaddset((s),(n))
-#define __SIGDELSET(s,n) __sigdelset((s),(n))
-#define __SIGISMEMBER(s,n) __sigismember((s),(n))
-
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-/* Values for the HOW argument to `sigprocmask'. */
-#define SIG_BLOCK 0 /* Block signals. */
-#define SIG_UNBLOCK 1 /* Unblock signals. */
-#define SIG_SETMASK 2 /* Set the set of blocked signals. */
diff --git a/mit-pthreads/machdep/linux-2.0/__stdio.h b/mit-pthreads/machdep/linux-2.0/__stdio.h
deleted file mode 100755
index 38deb337038..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__stdio.h
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Hack for configuration with libgcc 2.2 */
-#ifndef pthread_fpos_t
-#define pthread_fpos_t long
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/linux-2.0/__stdlib.h b/mit-pthreads/machdep/linux-2.0/__stdlib.h
deleted file mode 100755
index eaa0bb988ee..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__stdlib.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <features.h>
-
-/* Get size_t, wchar_t and NULL from <stddef.h>. */
-#define __need_size_t
-#define __need_wchar_t
-#define __need_NULL
-#include <stddef.h>
-
-#define __need_Emath
-#include <errno.h>
-
-/* Get HUGE_VAL (returned by strtod on overflow) from <float.h>. */
-#define __need_HUGE_VAL
-#include <float.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/__string.h b/mit-pthreads/machdep/linux-2.0/__string.h
deleted file mode 100755
index 8a5e09608e0..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__string.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard Linux string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/__time.h b/mit-pthreads/machdep/linux-2.0/__time.h
deleted file mode 100755
index b86c153543a..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__time.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== __time.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <features.h>
-
-struct timespec
- {
- long int tv_sec; /* Seconds. */
- long int tv_nsec; /* Nanoseconds. */
- };
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *) 0)
-#endif
-#endif
-#endif
-
-#define CLOCKS_PER_SEC 100
-#define CLK_TCK 100
-
-extern long int timezone;
-extern int daylight;
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/__unistd.h b/mit-pthreads/machdep/linux-2.0/__unistd.h
deleted file mode 100755
index 444f070659a..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__unistd.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-
-#include <sys/types.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-int chroot(const char *);
-int gethostname(char *, int);
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/mit-pthreads/machdep/linux-2.0/cdefs.h b/mit-pthreads/machdep/linux-2.0/cdefs.h
deleted file mode 100755
index 04f93a138c9..00000000000
--- a/mit-pthreads/machdep/linux-2.0/cdefs.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This is intended to eventually find /usr/include/sys/cdefs.h
- * if it's inside the ifdef then it won't work if this file is
- * found in the include files path more than once.
- *
- * include_next is a GNU C extension, we might eventually want
- * to have our own cdefs in here simply to avoid GNU C dependencies
- * (though there are already enough in the asm stuff anyways)
- * [gsstark:19950419.0307EST]
- */
-
-/* We are almost always included from features.h. */
-
-#ifndef _FEATURES_H
-#include <features.h>
-#endif
-
-#ifndef __BITS_SOCKET_H
-#define __BITS_SOCKET_H
-#endif
-
-#define __need_timespec
-
-#include_next <sys/cdefs.h>
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#if !defined(__cplusplus)
-#define __CAN_DO_EXTERN_INLINE
-#endif
-
-#endif /* _PTHREAD_SYS_CDEFS_H_ */
diff --git a/mit-pthreads/machdep/linux-2.0/compat.h b/mit-pthreads/machdep/linux-2.0/compat.h
deleted file mode 100755
index 6edb992ac3d..00000000000
--- a/mit-pthreads/machdep/linux-2.0/compat.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#include <sys/types.h>
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/dirent.h b/mit-pthreads/machdep/linux-2.0/dirent.h
deleted file mode 100755
index 7f783a198e0..00000000000
--- a/mit-pthreads/machdep/linux-2.0/dirent.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS_DIRENT_H
-#define _SYS_DIRENT_H
-
-#include <sys/types.h>
-#include <linux/limits.h>
-
-struct dirent {
- long d_ino;
- off_t d_off;
- unsigned short d_reclen;
- char d_name[NAME_MAX+1];
-};
-
-#ifndef d_fileno
-#define d_fileno d_ino
-#endif
-
-#ifndef d_namlen
-#define d_namlen d_reclen
-#endif
-
-#ifndef MAXNAMLEN
-#define MAXNAMLEN NAME_MAX
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/errno.h b/mit-pthreads/machdep/linux-2.0/errno.h
deleted file mode 100755
index a94a56b0437..00000000000
--- a/mit-pthreads/machdep/linux-2.0/errno.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* ==== errno.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Errno is already broken up into data/prototyes.
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#include <linux/errno.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h b/mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h
deleted file mode 100644
index 1a319ccdfd4..00000000000
--- a/mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Minimum guaranteed maximum values for system limits. Linux version.
-
-/* The kernel header pollutes the namespace with the NR_OPEN symbol.
- Remove this after including the header if necessary. */
-
-#ifndef NR_OPEN
-# define __undef_NR_OPEN
-#endif
-
-#include <linux/limits.h>
-
-#ifdef __undef_NR_OPEN
-# undef NR_OPEN
-# undef __undef_NR_OPEN
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/extra/bits/socket.h b/mit-pthreads/machdep/linux-2.0/extra/bits/socket.h
deleted file mode 100755
index 1814e189b64..00000000000
--- a/mit-pthreads/machdep/linux-2.0/extra/bits/socket.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/* ==== socket.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_BITS_SOCKET_H_
-#define _PTHREAD_BITS_SOCKET_H_
-
-/* #include <linux/socket.h> */
-#ifndef _LINUX_SOCKET_H
-#define _LINUX_SOCKET_H
-
-/* IP options */
-#define IP_TOS 1
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-#define IP_TTL 2
-#ifndef IP_HDRINCL
-#define IP_HDRINCL 3
-#endif
-#ifdef V1_3_WILL_DO_THIS_FUNKY_STUFF
-#define IP_OPTIONS 4
-#endif
-
-#endif
-
-/* Fixes to be able to configure with glibc 2.2 */
-typedef unsigned short int sa_family_t;
-#define __SOCKADDR_COMMON(sa_prefix) \
- sa_family_t sa_prefix##family
-#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
-
-/* Type for length arguments in socket calls. */
-typedef unsigned int socklen_t;
-
-/* #include <asm/socket.h> arch-dependent defines */
-#include <linux/sockios.h> /* the SIOCxxx I/O controls */
-#include <pthread/posix.h>
-
-struct sockaddr {
- unsigned short sa_family; /* address family, AF_xxx */
- char sa_data[14]; /* 14 bytes of protocol address */
-};
-
-struct linger {
- int l_onoff; /* Linger active */
- int l_linger; /* How long to linger for */
-};
-
-struct msghdr
-{
- void * msg_name; /* Socket name */
- int msg_namelen; /* Length of name */
- struct iovec * msg_iov; /* Data blocks */
- int msg_iovlen; /* Number of blocks */
- void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
- int msg_accrightslen;/* Length of rights list */
-};
-
-/* Socket types. */
-#define SOCK_STREAM 1 /* stream (connection) socket */
-#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
-#define SOCK_RAW 3 /* raw socket */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequential packet socket */
-#define SOCK_PACKET 10 /* linux specific way of */
- /* getting packets at the dev */
- /* level. For writing rarp and */
- /* other similar things on the */
- /* user level. */
-
-/* Supported address families. */
-#define AF_UNSPEC 0
-#define AF_UNIX 1 /* Unix domain sockets */
-#define AF_INET 2 /* Internet IP Protocol */
-#define AF_AX25 3 /* Amateur Radio AX.25 */
-#define AF_IPX 4 /* Novell IPX */
-#define AF_APPLETALK 5 /* Appletalk DDP */
-#define AF_NETROM 6 /* Amateur radio NetROM */
-#define AF_BRIDGE 7 /* Multiprotocol bridge */
-#define AF_AAL5 8 /* Reserved for Werner's ATM */
-#define AF_X25 9 /* Reserved for X.25 project */
-#define AF_INET6 10 /* IP version 6 */
-#define AF_MAX 12 /* For now.. */
-
-/* Protocol families, same as address families. */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_AX25 AF_AX25
-#define PF_IPX AF_IPX
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NETROM AF_NETROM
-#define PF_BRIDGE AF_BRIDGE
-#define PF_AAL5 AF_AAL5
-#define PF_X25 AF_X25
-#define PF_INET6 AF_INET6
-
-#define PF_MAX AF_MAX
-
-/* Maximum queue length specificable by listen. */
-#define SOMAXCONN 128
-
-/* Flags we can use with send/ and recv. */
-#define MSG_OOB 1
-#define MSG_PEEK 2
-#define MSG_DONTROUTE 4
-
-/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
-#define SOL_SOCKET 1
-#define SOL_IP 0
-#define SOL_IPX 256
-#define SOL_AX25 257
-#define SOL_ATALK 258
-#define SOL_NETROM 259
-#define SOL_TCP 6
-#define SOL_UDP 17
-
-/* For setsockoptions(2) */
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_LINGER 13
-/* To add :#define SO_REUSEPORT 14 */
-
-
-#define IP_MULTICAST_IF 32
-#define IP_MULTICAST_TTL 33
-#define IP_MULTICAST_LOOP 34
-#define IP_ADD_MEMBERSHIP 35
-#define IP_DROP_MEMBERSHIP 36
-
-
-/* These need to appear somewhere around here */
-#define IP_DEFAULT_MULTICAST_TTL 1
-#define IP_DEFAULT_MULTICAST_LOOP 1
-#define IP_MAX_MEMBERSHIPS 20
-
-/* IPX options */
-#define IPX_TYPE 1
-
-/* TCP options - this way around because someone left a set in the c library includes */
-#define TCP_NODELAY 1
-#define TCP_MAXSEG 2
-
-/* The various priorities. */
-#define SOPRI_INTERACTIVE 0
-#define SOPRI_NORMAL 1
-#define SOPRI_BACKGROUND 2
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, socklen_t *));
-int bind __P_((int, const struct sockaddr *, socklen_t));
-int connect __P_((int, const struct sockaddr *, socklen_t));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-int getsockopt __P_((int __s, int __level, int __optname,
- void *__optval, socklen_t *__optlen));
-int setsockopt __P_((int __s, int __level, int __optname,
- __const void *__optval, socklen_t optlen));
-int getsockname __P_((int __sockfd, struct sockaddr *__addr,
- socklen_t *__paddrlen));
-int getpeername __P_((int __sockfd, struct sockaddr *__peer,
- socklen_t *__paddrlen));
-ssize_t send __P_((int __sockfd, __const void *__buff, size_t __len, int __flags));
-ssize_t recv __P_((int __sockfd, void *__buff, size_t __len, int __flags));
-ssize_t sendto __P_((int __sockfd, __const void *__buff, size_t __len,
- int __flags, __const struct sockaddr *__to,
- socklen_t __tolen));
-ssize_t recvfrom __P_((int __sockfd, void *__buff, size_t __len,
- int __flags, struct sockaddr *__from,
- socklen_t *__fromlen));
-extern ssize_t sendmsg __P_((int __fd, __const struct msghdr *__message,
- int __flags));
-extern ssize_t recvmsg __P_((int __fd, struct msghdr *__message,
- int __flags));
-int shutdown __P_((int __sockfd, int __how));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/socket.h b/mit-pthreads/machdep/linux-2.0/socket.h
deleted file mode 100755
index 2a8a04f1903..00000000000
--- a/mit-pthreads/machdep/linux-2.0/socket.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* ==== socket.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_SOCKET_H_
-#define _PTHREAD_SOCKET_H_
-
-#include "bits/socket.h"
-
-#endif
-
diff --git a/mit-pthreads/machdep/linux-2.0/timers.h b/mit-pthreads/machdep/linux-2.0/timers.h
deleted file mode 100755
index 110cb27378c..00000000000
--- a/mit-pthreads/machdep/linux-2.0/timers.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <pthread/config.h>
-#include <sys/types.h>
-#include <time.h>
-
-#ifndef _OS_HAS_TIMESPEC
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-#endif
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/uio.h b/mit-pthreads/machdep/linux-2.0/uio.h
deleted file mode 100755
index 67af5bf76e0..00000000000
--- a/mit-pthreads/machdep/linux-2.0/uio.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/wait.h b/mit-pthreads/machdep/linux-2.0/wait.h
deleted file mode 100755
index bcc28c5ef58..00000000000
--- a/mit-pthreads/machdep/linux-2.0/wait.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait and extract the
- * relevant values. Union wait is no supported with pthreads.
- */
-#define __W_INT(i) (i)
-#define __WSTATUS(x) (__W_INT(x) & 0177)
-#define __WSTOPPED 0177 /* __WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (__WSTATUS(x) == __WSTOPPED)
-#define WSTOPSIG(x) (__W_INT(x) >> 8)
-#define WIFSIGNALED(x) (__WSTATUS(x) != __WSTOPPED && __WSTATUS(x) != 0)
-#define WTERMSIG(x) (__WSTATUS(x))
-#define WIFEXITED(x) (__WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (__W_INT(x) >> 8)
-
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (__W_INT(x) & WCOREFLAG)
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | __WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-
-/* Tokens for special values of the "pid" parameter to wait4. */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED __WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-__BEGIN_DECLS
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
diff --git a/mit-pthreads/machdep/netbsd-0.9/dirent.h b/mit-pthreads/machdep/netbsd-0.9/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/netbsd-0.9/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__math.h b/mit-pthreads/machdep/netbsd-1.0/__math.h
deleted file mode 100755
index dc009d822f4..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/netbsd-1.0/__path.h b/mit-pthreads/machdep/netbsd-1.0/__path.h
deleted file mode 100755
index 432494daafa..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/netbsd-1.0/__signal.h b/mit-pthreads/machdep/netbsd-1.0/__signal.h
deleted file mode 100755
index 918955c9948..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__signal.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
diff --git a/mit-pthreads/machdep/netbsd-1.0/__stdio.h b/mit-pthreads/machdep/netbsd-1.0/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__stdlib.h b/mit-pthreads/machdep/netbsd-1.0/__stdlib.h
deleted file mode 100755
index 7b24491b892..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__stdlib.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__string.h b/mit-pthreads/machdep/netbsd-1.0/__string.h
deleted file mode 100755
index 1ebee28e708..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/__time.h b/mit-pthreads/machdep/netbsd-1.0/__time.h
deleted file mode 100755
index 16ea9d1f0dd..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(_ANSI_SOURCE)
-#define CLK_TCK 100
-#endif /* not ANSI */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__unistd.h b/mit-pthreads/machdep/netbsd-1.0/__unistd.h
deleted file mode 100755
index b4741ba6725..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__unistd.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE ((unsigned char)'\377')
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/compat.h b/mit-pthreads/machdep/netbsd-1.0/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/dirent.h b/mit-pthreads/machdep/netbsd-1.0/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/errno.h b/mit-pthreads/machdep/netbsd-1.0/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/time.h b/mit-pthreads/machdep/netbsd-1.0/time.h
deleted file mode 100755
index f2cc61f8d75..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/time.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* $NetBSD: time.h,v 1.8 1994/06/29 06:45:44 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)time.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-
-/*
- * Structure defined by POSIX.4 to be like a timeval.
- */
-struct timespec {
- long tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-#define DST_CAN 6 /* Canada */
-
-/* Operations on timevals. */
-#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- (((tvp)->tv_sec == (uvp)->tv_sec) ? \
- ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
- ((tvp)->tv_sec cmp (uvp)->tv_sec))
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-/*
- * Getkerninfo clock information structure
- */
-struct clockinfo {
- int hz; /* clock frequency */
- int tick; /* micro-seconds per hz tick */
- int stathz; /* statistics clock frequency */
- int profhz; /* profiling clock frequency */
-};
-
-#include <time.h>
-
-#ifndef _POSIX_SOURCE
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int adjtime __P_((const struct timeval *, struct timeval *));
-int getitimer __P_((int, struct itimerval *));
-int gettimeofday __P_((struct timeval *, struct timezone *));
-int setitimer __P_((int, const struct itimerval *, struct itimerval *));
-int settimeofday __P_((const struct timeval *, const struct timezone *));
-int utimes __P_((const char *, const struct timeval *));
-__END_DECLS
-#endif /* !POSIX */
-
-#endif /* !_SYS_TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/timers.h b/mit-pthreads/machdep/netbsd-1.0/timers.h
deleted file mode 100755
index f9768c68c8f..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/wait.h b/mit-pthreads/machdep/netbsd-1.0/wait.h
deleted file mode 100755
index c1cd876d052..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/wait.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/__math.h b/mit-pthreads/machdep/netbsd-1.1/__math.h
deleted file mode 100755
index dc009d822f4..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/netbsd-1.1/__path.h b/mit-pthreads/machdep/netbsd-1.1/__path.h
deleted file mode 100755
index be7f9f6c658..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __path.h,v 1.1 1995/01/03 12:53:32 proven Exp
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/netbsd-1.1/__signal.h b/mit-pthreads/machdep/netbsd-1.1/__signal.h
deleted file mode 100755
index ea2979f2b4e..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__signal.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <sys/signal.h>
-
-__BEGIN_DECLS
-
-#if NSIG <= 32
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
-#else /* XXX Netbsd >= 1.3H */
-
-int sigaction __P_((int, const struct sigaction *, struct sigaction *)) __RENAME(__sigaction14);
-
-#define __SIGEMPTYSET { 0, 0, 0, 0}
-#define __SIGFILLSET { 0xffffffff, 0xffffffff, \
- 0xffffffff, 0xffffffff }
-#define __SIGMASK(n) (1 << (((n) - 1) & 31))
-#define __SIGWORD(n) (((n) - 1) >> 5)
-#define __SIGADDSET(s, n) ((s)->__bits[__SIGWORD(n)] |= __SIGMASK(n))
-#define __SIGDELSET(s, n) ((s)->__bits[__SIGWORD(n)] &= ~__SIGMASK(n))
-#define __SIGISMEMBER(s, n) (((s)->__bits[__SIGWORD(n)] & __SIGMASK(n)) != 0)
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/netbsd-1.1/__stdio.h b/mit-pthreads/machdep/netbsd-1.1/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/netbsd-1.1/__stdlib.h b/mit-pthreads/machdep/netbsd-1.1/__stdlib.h
deleted file mode 100755
index 189bb5e8799..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__stdlib.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __stdlib.h,v 1.1 1995/01/03 12:53:34 proven Exp
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.1/__string.h b/mit-pthreads/machdep/netbsd-1.1/__string.h
deleted file mode 100755
index 1ebee28e708..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/__time.h b/mit-pthreads/machdep/netbsd-1.1/__time.h
deleted file mode 100755
index 27ceb815852..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __time.h,v 1.1 1994/12/13 07:18:55 proven Exp
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(_ANSI_SOURCE)
-#define CLK_TCK 100
-#endif /* not ANSI */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.1/__unistd.h b/mit-pthreads/machdep/netbsd-1.1/__unistd.h
deleted file mode 100755
index cea3165c229..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__unistd.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __unistd.h,v 1.1 1995/01/03 12:53:35 proven Exp
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE ((unsigned char)'\377')
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/compat.h b/mit-pthreads/machdep/netbsd-1.1/compat.h
deleted file mode 100755
index f843795cc0a..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * compat.h,v 1.50 1994/08/08 03:44:05 proven Exp
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/dirent.h b/mit-pthreads/machdep/netbsd-1.1/dirent.h
deleted file mode 100755
index cf004a274d6..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/dirent.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $NetBSD: dirent.h,v 1.12 1996/04/09 20:55:25 cgd Exp $ */
-
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 8.3 (Berkeley) 8/10/94
- */
-
-/*
- * The dirent structure defines the format of directory entries returned by
- * the getdirentries(2) system call.
- *
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_int32_t d_fileno; /* file number of entry */
- u_int16_t d_reclen; /* length of this record */
- u_int8_t d_type; /* file type, see below */
- u_int8_t d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#ifdef PTHREAD_KERNEL
-#define d_ino d_fileno
-#endif
-
-/*
- * File types
- */
-#define DT_UNKNOWN 0
-#define DT_FIFO 1
-#define DT_CHR 2
-#define DT_DIR 4
-#define DT_BLK 6
-#define DT_REG 8
-#define DT_LNK 10
-#define DT_SOCK 12
-#define DT_WHT 14
-
-/*
- * Convert between stat structure types and directory types.
- */
-#define IFTODT(mode) (((mode) & 0170000) >> 12)
-#define DTTOIF(dirtype) ((dirtype) << 12)
-
-#if defined(_KERNEL)
-/*
- * The DIRENT_SIZE macro gives the minimum record length which will hold
- * the directory entry. This requires the amount of space in struct dirent
- * without the d_name field, plus enough space for the name with a terminating
- * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- */
-#define DIRENT_SIZE(dp) \
- ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
-
-#endif /* !_KERNEL */
diff --git a/mit-pthreads/machdep/netbsd-1.1/errno.h b/mit-pthreads/machdep/netbsd-1.1/errno.h
deleted file mode 100755
index c313b578c5a..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/errno.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* $NetBSD: errno.h,v 1.10 1996/01/20 01:33:53 jtc Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _KERNEL
-extern int errno; /* global error number */
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-extern int sys_nerr;
-extern const char *const sys_errlist[];
-#endif
-#endif
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#ifdef _KERNEL
-/* pseudo-errors returned inside kernel to modify return to process */
-#define ERESTART -1 /* restart syscall */
-#define EJUSTRETURN -2 /* don't modify regs, just return */
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/time.h b/mit-pthreads/machdep/netbsd-1.1/time.h
deleted file mode 100755
index a701db9c62e..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/time.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $NetBSD: time.h,v 1.17 1996/02/01 00:10:36 jtc Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)time.h 8.2 (Berkeley) 7/10/94
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-#include <sys/types.h>
-
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-
-/*
- * Structure defined by POSIX.1b to be like a timeval.
- */
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-#define DST_CAN 6 /* Canada */
-
-/* Operations on timevals. */
-#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- (((tvp)->tv_sec == (uvp)->tv_sec) ? \
- ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
- ((tvp)->tv_sec cmp (uvp)->tv_sec))
-#define timeradd(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
- if ((vvp)->tv_usec >= 1000000) { \
- (vvp)->tv_sec++; \
- (vvp)->tv_usec -= 1000000; \
- } \
- } while (0)
-#define timersub(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
- if ((vvp)->tv_usec < 0) { \
- (vvp)->tv_sec--; \
- (vvp)->tv_usec += 1000000; \
- } \
- } while (0)
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-/*
- * Getkerninfo clock information structure
- */
-struct clockinfo {
- int hz; /* clock frequency */
- int tick; /* micro-seconds per hz tick */
- int tickadj; /* clock skew rate for adjtime() */
- int stathz; /* statistics clock frequency */
- int profhz; /* profiling clock frequency */
-};
-
-#ifdef _KERNEL
-int itimerfix __P_((struct timeval *tv));
-int itimerdecr __P_((struct itimerval *itp, int usec));
-void microtime __P_((struct timeval *tv));
-#else /* !_KERNEL */
-#include <time.h>
-
-#ifndef _POSIX_SOURCE
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int adjtime __P_((const struct timeval *, struct timeval *));
-int getitimer __P_((int, struct itimerval *));
-int gettimeofday __P_((struct timeval *, struct timezone *));
-int setitimer __P_((int, const struct itimerval *, struct itimerval *));
-int settimeofday __P_((const struct timeval *, const struct timezone *));
-int utimes __P_((const char *, const struct timeval *));
-__END_DECLS
-#endif /* !POSIX */
-
-#endif /* !_KERNEL */
-
-#endif /* !_SYS_TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.1/timers.h b/mit-pthreads/machdep/netbsd-1.1/timers.h
deleted file mode 100755
index b603b78e6b2..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * timers.h,v 1.50 1994/08/08 03:44:09 proven Exp
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/wait.h b/mit-pthreads/machdep/netbsd-1.1/wait.h
deleted file mode 100755
index 0a1e9285e56..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/wait.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* $NetBSD: wait.h,v 1.11 1996/04/09 20:55:51 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.2 (Berkeley) 7/10/94
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* don't hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef _KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
-#endif /* !_SYS_WAIT_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__math.h b/mit-pthreads/machdep/openbsd-2.0/__math.h
deleted file mode 100755
index 27ed0f2575d..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__path.h b/mit-pthreads/machdep/openbsd-2.0/__path.h
deleted file mode 100755
index 432494daafa..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__signal.h b/mit-pthreads/machdep/openbsd-2.0/__signal.h
deleted file mode 100755
index 918955c9948..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__signal.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__stdio.h b/mit-pthreads/machdep/openbsd-2.0/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__stdlib.h b/mit-pthreads/machdep/openbsd-2.0/__stdlib.h
deleted file mode 100755
index 5ee2b8ed3d9..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__stdlib.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#ifdef _BSD_RUNE_T_
-typedef _BSD_RUNE_T_ rune_t;
-#undef _BSD_RUNE_T_
-#else
-typedef _BSD_WCHAR_T_ rune_t;
-#endif
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__string.h b/mit-pthreads/machdep/openbsd-2.0/__string.h
deleted file mode 100755
index 93d4fcf9dd2..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__string.h
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__time.h b/mit-pthreads/machdep/openbsd-2.0/__time.h
deleted file mode 100755
index 5c4b722bc3c..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__time.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-#include <machine/limits.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(CLK_TCK)
-#define CLK_TCK 100
-#endif /* not CLK_TCK */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__unistd.h b/mit-pthreads/machdep/openbsd-2.0/__unistd.h
deleted file mode 100755
index 41244522461..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__unistd.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type unsigned long /* For fd.c */
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-/* #define _POSIX_VDISABLE 0xff */
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/compat.h b/mit-pthreads/machdep/openbsd-2.0/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/dirent.h b/mit-pthreads/machdep/openbsd-2.0/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/errno.h b/mit-pthreads/machdep/openbsd-2.0/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/timers.h b/mit-pthreads/machdep/openbsd-2.0/timers.h
deleted file mode 100755
index f9768c68c8f..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/wait.h b/mit-pthreads/machdep/openbsd-2.0/wait.h
deleted file mode 100755
index 7861e3fa180..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/wait.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-alpha-osf1.h b/mit-pthreads/machdep/posix-alpha-osf1.h
deleted file mode 100644
index 1d8bb6c5c4b..00000000000
--- a/mit-pthreads/machdep/posix-alpha-osf1.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#define __WAIT_STATUS int *
-#include <pthread/types.h>
-
-#endif
diff --git a/mit-pthreads/machdep/posix-bsdi-1.1.h b/mit-pthreads/machdep/posix-bsdi-1.1.h
deleted file mode 100644
index 4c56ea93a3b..00000000000
--- a/mit-pthreads/machdep/posix-bsdi-1.1.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-bsdi-2.0.h b/mit-pthreads/machdep/posix-bsdi-2.0.h
deleted file mode 100644
index 4c56ea93a3b..00000000000
--- a/mit-pthreads/machdep/posix-bsdi-2.0.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-freebsd-1.1.h b/mit-pthreads/machdep/posix-freebsd-1.1.h
deleted file mode 100644
index e1a00e9efd1..00000000000
--- a/mit-pthreads/machdep/posix-freebsd-1.1.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-freebsd-2.0.h b/mit-pthreads/machdep/posix-freebsd-2.0.h
deleted file mode 100644
index 7bad77aba02..00000000000
--- a/mit-pthreads/machdep/posix-freebsd-2.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-hpux-10.20.h b/mit-pthreads/machdep/posix-hpux-10.20.h
deleted file mode 100644
index c7ecb429e79..00000000000
--- a/mit-pthreads/machdep/posix-hpux-10.20.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-hpux-9.03.h b/mit-pthreads/machdep/posix-hpux-9.03.h
deleted file mode 100644
index c7ecb429e79..00000000000
--- a/mit-pthreads/machdep/posix-hpux-9.03.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-i386-sco-3.2v5.h b/mit-pthreads/machdep/posix-i386-sco-3.2v5.h
deleted file mode 100644
index ab91311612d..00000000000
--- a/mit-pthreads/machdep/posix-i386-sco-3.2v5.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * posix-freebsd-2.0.h,v 1.1 1995/03/01 01:21:30 proven Exp
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-irix-5.2.h b/mit-pthreads/machdep/posix-irix-5.2.h
deleted file mode 100644
index d387bbbbf69..00000000000
--- a/mit-pthreads/machdep/posix-irix-5.2.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an IRIX-5.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 95/06/01 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-linux-1.0.h b/mit-pthreads/machdep/posix-linux-1.0.h
deleted file mode 100644
index 7f665d6b44a..00000000000
--- a/mit-pthreads/machdep/posix-linux-1.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert a Linux-1.0 system to a more or less POSIX system.
- * Mostly POSIX already
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __INLINE extern inline
-/*
- * OK now do stuff to make the code compile.
- * Every OS has its own prototypes for each function
- */
-#ifdef malloc
-#undef malloc
-#endif
-
-#ifdef free
-#undef free
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-linux-2.0.h b/mit-pthreads/machdep/posix-linux-2.0.h
deleted file mode 100644
index 7f665d6b44a..00000000000
--- a/mit-pthreads/machdep/posix-linux-2.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert a Linux-1.0 system to a more or less POSIX system.
- * Mostly POSIX already
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __INLINE extern inline
-/*
- * OK now do stuff to make the code compile.
- * Every OS has its own prototypes for each function
- */
-#ifdef malloc
-#undef malloc
-#endif
-
-#ifdef free
-#undef free
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-netbsd-0.9.h b/mit-pthreads/machdep/posix-netbsd-0.9.h
deleted file mode 100644
index 00ff2efa327..00000000000
--- a/mit-pthreads/machdep/posix-netbsd-0.9.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#endif
diff --git a/mit-pthreads/machdep/posix-netbsd-1.0.h b/mit-pthreads/machdep/posix-netbsd-1.0.h
deleted file mode 100644
index 7bad77aba02..00000000000
--- a/mit-pthreads/machdep/posix-netbsd-1.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-netbsd-1.1.h b/mit-pthreads/machdep/posix-netbsd-1.1.h
deleted file mode 100644
index f4ff1dfae05..00000000000
--- a/mit-pthreads/machdep/posix-netbsd-1.1.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * posix-netbsd-1.0.h,v 1.53 1995/02/17 03:41:34 proven Exp
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-openbsd-2.0.h b/mit-pthreads/machdep/posix-openbsd-2.0.h
deleted file mode 100644
index 7bad77aba02..00000000000
--- a/mit-pthreads/machdep/posix-openbsd-2.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-romp-bsd.h b/mit-pthreads/machdep/posix-romp-bsd.h
deleted file mode 100644
index 7825622b064..00000000000
--- a/mit-pthreads/machdep/posix-romp-bsd.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert a system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#ifndef O_NONBLOCK
-#ifdef FNDELAY
-#define O_NONBLOCK FNDELAY
-#endif
-#endif
-
-#ifndef O_ACCMODE
-#define O_ACCMODE (O_RDONLY|O_RDWR|O_WRONLY)
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG(x) ((x & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef ENOSYS
-#define ENOSYS EINVAL
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
diff --git a/mit-pthreads/machdep/posix-sco-3.2v5.h b/mit-pthreads/machdep/posix-sco-3.2v5.h
deleted file mode 100644
index ab91311612d..00000000000
--- a/mit-pthreads/machdep/posix-sco-3.2v5.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * posix-freebsd-2.0.h,v 1.1 1995/03/01 01:21:30 proven Exp
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-sunos-4.1.3.h b/mit-pthreads/machdep/posix-sunos-4.1.3.h
deleted file mode 100644
index 719386bc558..00000000000
--- a/mit-pthreads/machdep/posix-sunos-4.1.3.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Do the right thing for a sunos 4.1.3 system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-extern long strtol();
-extern unsigned long strtoul();
-
-#endif
diff --git a/mit-pthreads/machdep/posix-sunos-5.3.h b/mit-pthreads/machdep/posix-sunos-5.3.h
deleted file mode 100644
index 9fb765d60c3..00000000000
--- a/mit-pthreads/machdep/posix-sunos-5.3.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Do the right thing for a sunos 4.1.3 system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-sunos-5.5.h b/mit-pthreads/machdep/posix-sunos-5.5.h
deleted file mode 100644
index 9fb765d60c3..00000000000
--- a/mit-pthreads/machdep/posix-sunos-5.5.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Do the right thing for a sunos 4.1.3 system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-ultrix-4.2.h b/mit-pthreads/machdep/posix-ultrix-4.2.h
deleted file mode 100644
index f21aec23ea3..00000000000
--- a/mit-pthreads/machdep/posix-ultrix-4.2.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__math.h b/mit-pthreads/machdep/sunos-4.1.3/__math.h
deleted file mode 100755
index 9de1dc6d4bd..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__math.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * Posix (actually ansi C) section
- */
-#define HUGE_VAL (__infinity()) /* Produces IEEE Infinity. */
-
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__path.h b/mit-pthreads/machdep/sunos-4.1.3/__path.h
deleted file mode 100755
index 2665b5a0e8a..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__path.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "localtime"
-
-#endif /* !_SYS__PATH_H_ */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__signal.h b/mit-pthreads/machdep/sunos-4.1.3/__signal.h
deleted file mode 100755
index f8b4fb8b6de..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__signal.h
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#include <sys/signal.h>
-#include <sys/stdtypes.h>
-
-typedef int sig_atomic_t;
-
-#define __SIGFILLSET 0xffffffff
-#define __SIGEMPTYSET 0
-#define __SIGADDSET(s,n) ((*s) |= (1 << ((n) - 1)))
-#define __SIGDELSET(s,n) ((*s) &= ~(1 << ((n) - 1)))
-#define __SIGISMEMBER(s,n) ((*s) & (1 << ((n) - 1)))
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__stdio.h b/mit-pthreads/machdep/sunos-4.1.3/__stdio.h
deleted file mode 100755
index 6ca5e57396d..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__stdio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-typedef pthread_fpos_t fpos_t;
-
-#include <sys/stdtypes.h>
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__stdlib.h b/mit-pthreads/machdep/sunos-4.1.3/__stdlib.h
deleted file mode 100755
index 7bb9093c51c..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__stdlib.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <sys/stdtypes.h> /* to get size_t */
-
-#if (! defined _SIZE_T_ ) && (! defined(_GCC_SIZE_T))
-#define _SIZE_T_
-#define _GCC_SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#if (! defined _WCHAR_T_ ) && (! defined(_GCC_WCHAR_T))
-#define _WCHAR_T_
-#define _GCC_WCHAR_T
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__string.h b/mit-pthreads/machdep/sunos-4.1.3/__string.h
deleted file mode 100755
index 0859a80cf24..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__string.h
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#include <sys/stdtypes.h>
-
-/* Non-standard SunOS 4.x string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__time.h b/mit-pthreads/machdep/sunos-4.1.3/__time.h
deleted file mode 100755
index 1ffa0e47d3f..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__time.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#include <sys/stdtypes.h>
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__unistd.h b/mit-pthreads/machdep/sunos-4.1.3/__unistd.h
deleted file mode 100755
index 3b86527252c..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__unistd.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#define _SC_ARG_MAX 1 /* space for argv & envp */
-#define _SC_CHILD_MAX 2 /* maximum children per process??? */
-#define _SC_CLK_TCK 3 /* clock ticks/sec */
-#define _SC_NGROUPS_MAX 4 /* number of groups if multple supp. */
-#define _SC_OPEN_MAX 5 /* max open files per process */
-#define _SC_JOB_CONTROL 6 /* do we have job control */
-#define _SC_SAVED_IDS 7 /* do we have saved uid/gids */
-#define _SC_VERSION 8 /* POSIX version supported */
-
-#define _POSIX_JOB_CONTROL 1
-#define _POSIX_SAVED_IDS 1
-#define _POSIX_VERSION 198808
-
-#define _PC_LINK_MAX 1 /* max links to file/dir */
-#define _PC_MAX_CANON 2 /* max line length */
-#define _PC_MAX_INPUT 3 /* max "packet" to a tty device */
-#define _PC_NAME_MAX 4 /* max pathname component length */
-#define _PC_PATH_MAX 5 /* max pathname length */
-#define _PC_PIPE_BUF 6 /* size of a pipe */
-#define _PC_CHOWN_RESTRICTED 7 /* can we give away files */
-#define _PC_NO_TRUNC 8 /* trunc or error on >NAME_MAX */
-#define _PC_VDISABLE 9 /* best char to shut off tty c_cc */
-#define _PC_LAST 9 /* highest value of any _PC_* */
-
-#ifndef NULL
-#define NULL 0 /* null pointer constant */
-#endif
-
-typedef int ssize_t;
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/cdefs.h b/mit-pthreads/machdep/sunos-4.1.3/cdefs.h
deleted file mode 100755
index a059fa3d3fc..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/cdefs.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/compat.h b/mit-pthreads/machdep/sunos-4.1.3/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/dirent.h b/mit-pthreads/machdep/sunos-4.1.3/dirent.h
deleted file mode 100755
index c2048b1741c..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- off_t d_off; /* offset of next disk dir entry */
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
-
-
diff --git a/mit-pthreads/machdep/sunos-4.1.3/fcntlcom.h b/mit-pthreads/machdep/sunos-4.1.3/fcntlcom.h
deleted file mode 100755
index 2b7acce7696..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/fcntlcom.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* @(#)fcntlcom.h 1.13 91/06/18 SMI; from UCB fcntl.h 5.2 1/8/86 */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#ifndef __sys_fcntlcom_h
-#define __sys_fcntlcom_h
-
-#include <sys/cdefs.h>
-
-/*
- * Rewack the FXXXXX values as _FXXXX so that _POSIX_SOURCE works.
- */
-#define _FOPEN (-1) /* from sys/file.h, kernel use only */
-#define _FREAD 0x0001 /* read enabled */
-#define _FWRITE 0x0002 /* write enabled */
-#define _FNDELAY 0x0004 /* non blocking I/O (4.2 style) */
-#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */
-#define _FSETBLK 0x0010 /* use block offsets */
-#define _FASYNC 0x0040 /* signal pgrp when data ready */
-#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */
-#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */
-#define _FCREAT 0x0200 /* open with file create */
-#define _FTRUNC 0x0400 /* open with truncation */
-#define _FEXCL 0x0800 /* error on open if file exists */
-#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */
-#define _FSYNC 0x2000 /* do all writes synchronously */
-#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */
-#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */
-#define _FMARK 0x10000 /* internal; mark during gc() */
-#define _FDEFER 0x20000 /* internal; defer for next gc pass */
-
-#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
-
-/*
- * Flag values for open(2) and fcntl(2)
- * The kernel adds 1 to the open modes to turn it into some
- * combination of FREAD and FWRITE.
- */
-#define O_RDONLY 0 /* +1 == FREAD */
-#define O_WRONLY 1 /* +1 == FWRITE */
-#define O_RDWR 2 /* +1 == FREAD|FWRITE */
-#define O_APPEND _FAPPEND
-#define O_CREAT _FCREAT
-#define O_TRUNC _FTRUNC
-#define O_EXCL _FEXCL
-/* O_SYNC _FSYNC not posix, defined below */
-/* O_NDELAY _FNDELAY set in include/fcntl.h */
-/* O_NDELAY _FNBIO set in 5include/fcntl.h */
-#define O_NONBLOCK _FNONBLOCK
-#define O_NOCTTY _FNOCTTY
-
-#ifndef _POSIX_SOURCE
-
-#define O_SYNC _FSYNC
-
-/*
- * Flags that work for fcntl(fd, F_SETFL, FXXXX)
- */
-#define FAPPEND _FAPPEND
-#define FSYNC _FSYNC
-#define FASYNC _FASYNC
-#define FNBIO _FNBIO
-#define FNONBIO _FNONBLOCK /* XXX fix to be NONBLOCK everywhere */
-#define FNDELAY _FNDELAY
-
-/*
- * Flags that are disallowed for fcntl's (FCNTLCANT);
- * used for opens, internal state, or locking.
- */
-#define FREAD _FREAD
-#define FWRITE _FWRITE
-#define FMARK _FMARK
-#define FDEFER _FDEFER
-#define FSETBLK _FSETBLK
-#define FSHLOCK _FSHLOCK
-#define FEXLOCK _FEXLOCK
-
-/*
- * The rest of the flags, used only for opens
- */
-#define FOPEN _FOPEN
-#define FCREAT _FCREAT
-#define FTRUNC _FTRUNC
-#define FEXCL _FEXCL
-#define FNOCTTY _FNOCTTY
-
-#endif !_POSIX_SOURCE
-
-/* XXX close on exec request; must match UF_EXCLOSE in user.h */
-#define FD_CLOEXEC 1 /* posix */
-
-/* fcntl(2) requests */
-#define F_DUPFD 0 /* Duplicate fildes */
-#define F_GETFD 1 /* Get fildes flags (close on exec) */
-#define F_SETFD 2 /* Set fildes flags (close on exec) */
-#define F_GETFL 3 /* Get file flags */
-#define F_SETFL 4 /* Set file flags */
-#ifndef _POSIX_SOURCE
-#define F_GETOWN 5 /* Get owner - for ASYNC */
-#define F_SETOWN 6 /* Set owner - for ASYNC */
-#endif /* !_POSIX_SOURCE */
-#define F_GETLK 7 /* Get record-locking information */
-#define F_SETLK 8 /* Set or Clear a record-lock (Non-Blocking) */
-#define F_SETLKW 9 /* Set or Clear a record-lock (Blocking) */
-#ifndef _POSIX_SOURCE
-#define F_RGETLK 10 /* Test a remote lock to see if it is blocked */
-#define F_RSETLK 11 /* Set or unlock a remote lock */
-#define F_CNVT 12 /* Convert a fhandle to an open fd */
-#define F_RSETLKW 13 /* Set or Clear remote record-lock(Blocking) */
-#endif /* !_POSIX_SOURCE */
-
-/* fcntl(2) flags (l_type field of flock structure) */
-#define F_RDLCK 1 /* read lock */
-#define F_WRLCK 2 /* write lock */
-#define F_UNLCK 3 /* remove lock(s) */
-#ifndef _POSIX_SOURCE
-#define F_UNLKSYS 4 /* remove remote locks for a given system */
-#endif /* !_POSIX_SOURCE */
-
-#include <sys/stdtypes.h>
-
-/* file segment locking set data type - information passed to system by user */
-struct flock {
- short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
- short l_whence; /* flag to choose starting offset */
- long l_start; /* relative offset, in bytes */
- long l_len; /* length, in bytes; 0 means lock to EOF */
- short l_pid; /* returned with F_GETLK */
- short l_xxx; /* reserved for future use */
-};
-
-#ifndef _POSIX_SOURCE
-/* extended file segment locking set data type */
-struct eflock {
- short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
- short l_whence; /* flag to choose starting offset */
- long l_start; /* relative offset, in bytes */
- long l_len; /* length, in bytes; 0 means lock to EOF */
- short l_pid; /* returned with F_GETLK */
- short l_xxx; /* reserved for future use */
- long l_rpid; /* Remote process id wanting this lock */
- long l_rsys; /* Remote system id wanting this lock */
-};
-#endif /* !_POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/stat.h> /* sigh. for the mode bits for open/creat */
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-int open __P_((const char *path, int flags, ...));
-int creat __P_((const char *path, mode_t modes));
-int fcntl __P_((int fd, int cmd, ...));
-
-__END_DECLS
-
-#endif /* !KERNEL */
-#endif /* !__sys_fcntlcom_h */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/signal.h b/mit-pthreads/machdep/sunos-4.1.3/signal.h
deleted file mode 100755
index 02a19860922..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/signal.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef __sys_signal_h
-#define __sys_signal_h
-
-#define NSIG 32
-
-/*
- * If any signal defines (SIG*) are added, deleted, or changed, the same
- * changes must be made in /usr/include/signal.h as well.
- */
-#define SIGHUP 1 /* hangup */
-#define SIGINT 2 /* interrupt */
-#define SIGQUIT 3 /* quit */
-#define SIGILL 4 /* illegal instruction (not reset when caught) */
-#define SIGTRAP 5 /* trace trap (not reset when caught) */
-#define SIGIOT 6 /* IOT instruction */
-#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
-#define SIGEMT 7 /* EMT instruction */
-#define SIGFPE 8 /* floating point exception */
-#define SIGKILL 9 /* kill (cannot be caught or ignored) */
-#define SIGBUS 10 /* bus error */
-#define SIGSEGV 11 /* segmentation violation */
-#define SIGSYS 12 /* bad argument to system call */
-#define SIGPIPE 13 /* write on a pipe with no one to read it */
-#define SIGALRM 14 /* alarm clock */
-#define SIGTERM 15 /* software termination signal from kill */
-#define SIGURG 16 /* urgent condition on IO channel */
-#define SIGSTOP 17 /* sendable stop signal not from tty */
-#define SIGTSTP 18 /* stop signal from tty */
-#define SIGCONT 19 /* continue a stopped process */
-#define SIGCHLD 20 /* to parent on child stop or exit */
-#define SIGCLD 20 /* System V name for SIGCHLD */
-#define SIGTTIN 21 /* to readers pgrp upon background tty read */
-#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
-#define SIGIO 23 /* input/output possible signal */
-#define SIGPOLL SIGIO /* System V name for SIGIO */
-#define SIGXCPU 24 /* exceeded CPU time limit */
-#define SIGXFSZ 25 /* exceeded file size limit */
-#define SIGVTALRM 26 /* virtual time alarm */
-#define SIGPROF 27 /* profiling time alarm */
-#define SIGWINCH 28 /* window changed */
-#define SIGLOST 29 /* resource lost (eg, record-lock lost) */
-#define SIGUSR1 30 /* user defined signal 1 */
-#define SIGUSR2 31 /* user defined signal 2 */
-
-struct sigvec {
- void (*sv_handler)(); /* signal handler */
- int sv_mask; /* signal mask to apply */
- int sv_flags; /* see signal options below */
-};
-#define SV_ONSTACK 0x0001 /* take signal on signal stack */
-#define SV_INTERRUPT 0x0002 /* do not restart system on signal return */
-#define SV_RESETHAND 0x0004 /* reset signal handler to SIG_DFL when signal taken */
-/*
- * If any SA_NOCLDSTOP or SV_NOCLDSTOP is change, the same
- * changes must be made in /usr/include/signal.h as well.
- */
-#define SV_NOCLDSTOP 0x0008 /* don't send a SIGCHLD on child stop */
-#define SA_ONSTACK SV_ONSTACK
-#define SA_INTERRUPT SV_INTERRUPT
-#define SA_RESETHAND SV_RESETHAND
-
-#define SA_NOCLDSTOP SV_NOCLDSTOP
-#define sv_onstack sv_flags /* isn't compatibility wonderful! */
-
-/*
- * If SIG_ERR, SIG_DFL, SIG_IGN, or SIG_HOLD are changed, the same changes
- * must be made in /usr/include/signal.h as well.
- */
-#define SIG_ERR (void (*)())-1
-#define SIG_DFL (void (*)())0
-#define SIG_IGN (void (*)())1
-
-/*
- * Macro for converting signal number to a mask suitable for sigblock().
- */
-#define sigmask(m) (1 << ((m)-1))
-
-/*
- * If SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK are changed, the same changes
- * must be made in /usr/include/signal.h as well.
- */
-#define SIG_BLOCK 0x0001
-#define SIG_UNBLOCK 0x0002
-#define SIG_SETMASK 0x0004
-
-/*
- * If changes are made to sigset_t or struct sigaction, the same changes
- * must be made in /usr/include/signal.h as well.
- */
-#include <sys/stdtypes.h>
-
-struct sigaction {
- void (*sa_handler)();
- sigset_t sa_mask;
- int sa_flags;
-};
-
-#endif /* !__sys_signal_h */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/stat.h b/mit-pthreads/machdep/sunos-4.1.3/stat.h
deleted file mode 100755
index 35e7f760204..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/stat.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* @(#)stat.h 2.19 90/01/24 SMI; from UCB 4.7 83/05/21 */
-
-/*
- * NOTE: changes to this file should also be made to xpg2include/sys/stat.h
- */
-
-#ifndef __sys_stat_h
-#define __sys_stat_h
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-struct stat {
- dev_t st_dev;
- ino_t st_ino;
- mode_t st_mode;
- short st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- dev_t st_rdev;
- off_t st_size;
- time_t st_atime;
- int st_spare1;
- time_t st_mtime;
- int st_spare2;
- time_t st_ctime;
- int st_spare3;
- long st_blksize;
- long st_blocks;
- long st_spare4[2];
-};
-
-#define _IFMT 0170000 /* type of file */
-#define _IFDIR 0040000 /* directory */
-#define _IFCHR 0020000 /* character special */
-#define _IFBLK 0060000 /* block special */
-#define _IFREG 0100000 /* regular */
-#define _IFLNK 0120000 /* symbolic link */
-#define _IFSOCK 0140000 /* socket */
-#define _IFIFO 0010000 /* fifo */
-
-#define S_ISUID 0004000 /* set user id on execution */
-#define S_ISGID 0002000 /* set group id on execution */
-#ifndef _POSIX_SOURCE
-#define S_ISVTX 0001000 /* save swapped text even after use */
-#define S_IREAD 0000400 /* read permission, owner */
-#define S_IWRITE 0000200 /* write permission, owner */
-#define S_IEXEC 0000100 /* execute/search permission, owner */
-
-#define S_ENFMT 0002000 /* enforcement-mode locking */
-
-#define S_IFMT _IFMT
-#define S_IFDIR _IFDIR
-#define S_IFCHR _IFCHR
-#define S_IFBLK _IFBLK
-#define S_IFREG _IFREG
-#define S_IFLNK _IFLNK
-#define S_IFSOCK _IFSOCK
-#define S_IFIFO _IFIFO
-#endif !_POSIX_SOURCE
-
-#define S_IRWXU 0000700 /* rwx, owner */
-#define S_IRUSR 0000400 /* read permission, owner */
-#define S_IWUSR 0000200 /* write permission, owner */
-#define S_IXUSR 0000100 /* execute/search permission, owner */
-#define S_IRWXG 0000070 /* rwx, group */
-#define S_IRGRP 0000040 /* read permission, group */
-#define S_IWGRP 0000020 /* write permission, grougroup */
-#define S_IXGRP 0000010 /* execute/search permission, group */
-#define S_IRWXO 0000007 /* rwx, other */
-#define S_IROTH 0000004 /* read permission, other */
-#define S_IWOTH 0000002 /* write permission, other */
-#define S_IXOTH 0000001 /* execute/search permission, other */
-
-#define S_ISBLK(m) (((m)&_IFMT) == _IFBLK)
-#define S_ISCHR(m) (((m)&_IFMT) == _IFCHR)
-#define S_ISDIR(m) (((m)&_IFMT) == _IFDIR)
-#define S_ISFIFO(m) (((m)&_IFMT) == _IFIFO)
-#define S_ISREG(m) (((m)&_IFMT) == _IFREG)
-#ifndef _POSIX_SOURCE
-#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
-#define S_ISSOCK(m) (((m)&_IFMT) == _IFSOCK)
-#endif
-
-__BEGIN_DECLS
-int chmod __P_((const char *path, mode_t mode));
-int fstat __P_((int fd, struct stat *sbuf));
-int mkdir __P_((char *path, mode_t mode));
-int mkfifo __P_((char *path, mode_t mode));
-int stat __P_((const char *path, struct stat *sbuf));
-mode_t umask __P_((mode_t mask));
-__END_DECLS
-
-#endif /* !__sys_stat_h */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/time.h b/mit-pthreads/machdep/sunos-4.1.3/time.h
deleted file mode 100755
index 20bb085e4d8..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* @(#)time.h 2.12 91/05/22 SMI; from UCB 7.1 6/4/86 */
-
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-#include <sys/cdefs.h>
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-#define DST_CAN 6 /* Canada */
-#define DST_GB 7 /* Great Britain and Eire */
-#define DST_RUM 8 /* Rumania */
-#define DST_TUR 9 /* Turkey */
-#define DST_AUSTALT 10 /* Australian style with shift in 1986 */
-
-/*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-__BEGIN_DECLS
-int gettimeofday __P_((struct timeval *, struct timezone *));
-__END_DECLS
-
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/timers.h b/mit-pthreads/machdep/sunos-4.1.3/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/wait.h b/mit-pthreads/machdep/sunos-4.1.3/wait.h
deleted file mode 100755
index 97f5fb261f7..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/wait.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#define _W_INT(i) (i)
-#define WCOREFLAG 0200
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-
-#endif /* _SYS_WAIT_H_ */
diff --git a/mit-pthreads/machdep/sunos-5.3/__math.h b/mit-pthreads/machdep/sunos-5.3/__math.h
deleted file mode 100755
index 5404b52c661..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__math.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ANSI/POSIX
- */
-typedef union _h_val {
- unsigned long _i[2];
- double _d;
-} _h_val;
-
-#ifdef __STDC__
-extern const _h_val __huge_val;
-#else
-extern _h_val __huge_val;
-#endif
-
-#define HUGE_VAL __huge_val._d
-
diff --git a/mit-pthreads/machdep/sunos-5.3/__signal.h b/mit-pthreads/machdep/sunos-5.3/__signal.h
deleted file mode 100755
index 638c1ca7331..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__signal.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <sys/feature_tests.h>
-#include <sys/signal.h>
-
-/*
-typedef struct {
- unsigned long __sigbits[4];
-} sigset_t;
-*/
-
-typedef int sig_atomic_t;
-
-#define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0 };
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff };
-#define __SIGADDSET(s, n) ((s)->__sigbits[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->__sigbits[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) (sigmask(n) & (s)->__sigbits[sigword(n)])
diff --git a/mit-pthreads/machdep/sunos-5.3/__stdio.h b/mit-pthreads/machdep/sunos-5.3/__stdio.h
deleted file mode 100755
index 4dd4becdbe9..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__stdio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-typedef pthread_fpos_t fpos_t;
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__stdlib.h b/mit-pthreads/machdep/sunos-5.3/__stdlib.h
deleted file mode 100755
index a0717ce3c2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__stdlib.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef long wchar_t;
-#endif
-
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__string.h b/mit-pthreads/machdep/sunos-5.3/__string.h
deleted file mode 100755
index 9cb12a07bb7..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__string.h
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__time.h b/mit-pthreads/machdep/sunos-5.3/__time.h
deleted file mode 100755
index 231e997acfa..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-#ifndef _CLOCKID_T
-#define _CLOCKID_T
-typedef int clockid_t;
-#endif
-#ifndef _TIMER_T
-#define _TIMER_T
-typedef int timer_t;
-#endif
-
-#include <sys/time.h>
-#include <sys/siginfo.h>
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__unistd.h b/mit-pthreads/machdep/sunos-5.3/__unistd.h
deleted file mode 100755
index 4e83a863735..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__unistd.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/cdefs.h b/mit-pthreads/machdep/sunos-5.3/cdefs.h
deleted file mode 100755
index f95f7b36958..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/cdefs.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/compat.h b/mit-pthreads/machdep/sunos-5.3/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/dirent.h b/mit-pthreads/machdep/sunos-5.3/dirent.h
deleted file mode 100755
index 303d3d7df2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- off_t d_off; /* offset of next disk dir entry */
- u_short d_reclen; /* length of this record */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_namlen d_reclen
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
-
-
diff --git a/mit-pthreads/machdep/sunos-5.3/socket.h b/mit-pthreads/machdep/sunos-5.3/socket.h
deleted file mode 100755
index 0b075622fed..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/socket.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-#ifndef _SYS_SOCKET_H
-#define _SYS_SOCKET_H
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 2 /* stream socket */
-#define SOCK_DGRAM 1 /* datagram socket */
-#define SOCK_RAW 4 /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get/set protocol type */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_NIT 17 /* NIT */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_ISO 19 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21
-#define AF_GOSIP 22
-#define AF_MAX 22
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NIT AF_NIT
-#define PF_802 AF_802
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_X25 AF_X25
-#define PF_OSINET AF_OSINET
-#define PF_GOSIP AF_GOSIP
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-#include <sys/cdefs.h>
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int getsockname __P_((int, struct sockaddr *, int *));
-int shutdown __P_((int, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-__END_DECLS
-
-#endif /* _SYS_SOCKET_H */
diff --git a/mit-pthreads/machdep/sunos-5.3/timers.h b/mit-pthreads/machdep/sunos-5.3/timers.h
deleted file mode 100755
index 3ee2c78f088..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/timers.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-#define tv_sec tv_sec
-#define tv_nsec tv_nsec
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-#ifndef NOT_USED
-/* for sleep.h */
-/* int gettimeofday __P_((struct timeval *,struct timezone *)); */
-int gettimeofday __P_((struct timeval *,void *));
-#endif
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/uio.h b/mit-pthreads/machdep/sunos-5.3/uio.h
deleted file mode 100755
index 7786142dd87..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/uio.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Solaris header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-typedef struct iovec iovec_t;
-
-struct uio {
- iovec_t *uio_iov; /* pointer to array of iovecs */
- int uio_iovcnt; /* number of iovecs */
- /* These are all bogus */
- int _uio_offset; /* file offset */
- int uio_segflg; /* address space (kernel or user) */
- short uio_fmode; /* file mode flags */
- int _uio_limit; /* u-limit (maximum "block" offset) */
- int uio_resid; /* residual count */
-};
-
-typedef struct uio uio_t;
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/sunos-5.5/__math.h b/mit-pthreads/machdep/sunos-5.5/__math.h
deleted file mode 100755
index 5404b52c661..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__math.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ANSI/POSIX
- */
-typedef union _h_val {
- unsigned long _i[2];
- double _d;
-} _h_val;
-
-#ifdef __STDC__
-extern const _h_val __huge_val;
-#else
-extern _h_val __huge_val;
-#endif
-
-#define HUGE_VAL __huge_val._d
-
diff --git a/mit-pthreads/machdep/sunos-5.5/__signal.h b/mit-pthreads/machdep/sunos-5.5/__signal.h
deleted file mode 100755
index 638c1ca7331..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__signal.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <sys/feature_tests.h>
-#include <sys/signal.h>
-
-/*
-typedef struct {
- unsigned long __sigbits[4];
-} sigset_t;
-*/
-
-typedef int sig_atomic_t;
-
-#define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0 };
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff };
-#define __SIGADDSET(s, n) ((s)->__sigbits[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->__sigbits[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) (sigmask(n) & (s)->__sigbits[sigword(n)])
diff --git a/mit-pthreads/machdep/sunos-5.5/__stdio.h b/mit-pthreads/machdep/sunos-5.5/__stdio.h
deleted file mode 100755
index 4dd4becdbe9..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__stdio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-typedef pthread_fpos_t fpos_t;
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__stdlib.h b/mit-pthreads/machdep/sunos-5.5/__stdlib.h
deleted file mode 100755
index a0717ce3c2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__stdlib.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef long wchar_t;
-#endif
-
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__string.h b/mit-pthreads/machdep/sunos-5.5/__string.h
deleted file mode 100755
index 9cb12a07bb7..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__string.h
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__time.h b/mit-pthreads/machdep/sunos-5.5/__time.h
deleted file mode 100755
index 231e997acfa..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-#ifndef _CLOCKID_T
-#define _CLOCKID_T
-typedef int clockid_t;
-#endif
-#ifndef _TIMER_T
-#define _TIMER_T
-typedef int timer_t;
-#endif
-
-#include <sys/time.h>
-#include <sys/siginfo.h>
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__unistd.h b/mit-pthreads/machdep/sunos-5.5/__unistd.h
deleted file mode 100755
index 4e83a863735..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__unistd.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/cdefs.h b/mit-pthreads/machdep/sunos-5.5/cdefs.h
deleted file mode 100755
index f95f7b36958..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/cdefs.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/compat.h b/mit-pthreads/machdep/sunos-5.5/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/dirent.h b/mit-pthreads/machdep/sunos-5.5/dirent.h
deleted file mode 100755
index 303d3d7df2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- off_t d_off; /* offset of next disk dir entry */
- u_short d_reclen; /* length of this record */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_namlen d_reclen
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
-
-
diff --git a/mit-pthreads/machdep/sunos-5.5/socket.h b/mit-pthreads/machdep/sunos-5.5/socket.h
deleted file mode 100755
index 0b075622fed..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/socket.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-#ifndef _SYS_SOCKET_H
-#define _SYS_SOCKET_H
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 2 /* stream socket */
-#define SOCK_DGRAM 1 /* datagram socket */
-#define SOCK_RAW 4 /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get/set protocol type */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_NIT 17 /* NIT */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_ISO 19 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21
-#define AF_GOSIP 22
-#define AF_MAX 22
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NIT AF_NIT
-#define PF_802 AF_802
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_X25 AF_X25
-#define PF_OSINET AF_OSINET
-#define PF_GOSIP AF_GOSIP
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-#include <sys/cdefs.h>
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int getsockname __P_((int, struct sockaddr *, int *));
-int shutdown __P_((int, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-__END_DECLS
-
-#endif /* _SYS_SOCKET_H */
diff --git a/mit-pthreads/machdep/sunos-5.5/timers.h b/mit-pthreads/machdep/sunos-5.5/timers.h
deleted file mode 100755
index 3aad5f80065..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/timers.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-#define tv_sec tv_sec
-#define tv_nsec tv_nsec
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-#ifdef NOT_USED
-int gettimeofday __P_((struct timeval *,struct timezone *)); /* for sleep.h */
-#endif
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/uio.h b/mit-pthreads/machdep/sunos-5.5/uio.h
deleted file mode 100755
index 7786142dd87..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/uio.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Solaris header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-typedef struct iovec iovec_t;
-
-struct uio {
- iovec_t *uio_iov; /* pointer to array of iovecs */
- int uio_iovcnt; /* number of iovecs */
- /* These are all bogus */
- int _uio_offset; /* file offset */
- int uio_segflg; /* address space (kernel or user) */
- short uio_fmode; /* file mode flags */
- int _uio_limit; /* u-limit (maximum "block" offset) */
- int uio_resid; /* residual count */
-};
-
-typedef struct uio uio_t;
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S b/mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S
deleted file mode 100644
index 5b7dd017426..00000000000
--- a/mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S
+++ /dev/null
@@ -1,206 +0,0 @@
-#include <machine/asm.h>
-#define CHMK() call_pal 0x83
-#define COMPAT_43
-#include <sys/syscall.h>
-#ifndef __CONCAT
-#include <sys/cdefs.h>
-#endif
-#define CONCAT __CONCAT
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl CONCAT(machdep_sys_,x) ;\
- .ent CONCAT(machdep_sys_,x), 0 ;\
-CONCAT(machdep_sys_,x): ;\
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
- beq a3, CONCAT(Lsys_noerr_,x) ;\
- br gp, CONCAT(Lsys_err_,x) ;\
-CONCAT(Lsys_err_,x): ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-CONCAT(Lsys_noerr_,x):
-
-#define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
-machdep_cerror:
- br t0, Lmachdep_cerror_setgp
-Lmachdep_cerror_setgp:
- ldgp gp, 0(t0)
- stl v0, errno
-#if 0
- ldiq v0, -1
-#else
- subq zero, v0, v0
-#endif
- RET
-
-/* The fork system call is special... */
-SYSCALL(fork)
- cmovne a4, 0, v0
- RET
- .end machdep_sys_fork
-
-/* The pipe system call is special... */
-SYSCALL(pipe)
- stl v0, 0(a0)
- stl a4, 4(a0)
- mov zero, v0
- RET
- .end machdep_sys_pipe
-
-/* The sigsuspend system call is special... */
- .align 4
- .globl machdep_sys_sigsuspend
- .ent machdep_sys_sigsuspend, 0
-machdep_sys_sigsuspend:
- ldl a0, 0(a0) /* pass *mask instead of mask */
- ldiq v0, SYS_sigsuspend
- CHMK()
- mov zero, v0 /* shouldn't need; just in case... */
- RET
- .end machdep_sys_sigsuspend
-
-/* The sigprocmask system call is special... */
- .align 4
- .globl machdep_sys_sigprocmask
- .ent machdep_sys_sigprocmask, 0
-machdep_sys_sigprocmask:
- mov a2, a5 /* safe */
- cmoveq a1, 1, a0 /* if set == NULL, how = SIG_BLOCK */
- beq a1, Ldoit /* and set = 0, and do it. */
- ldl a1, 0(a1) /* load the set from *set */
-Ldoit: ldiq v0, SYS_sigprocmask
- CHMK()
- beq a5, Lret /* if they don't want old mask, done */
- stl v0, 0(a5) /* otherwise, give it to them. */
-Lret: mov zero, v0
- RET
- .end machdep_sys_sigprocmask
-
-/* More stuff ... */
- .align 4
- .global __machdep_save_int_state
- .ent __machdep_save_int_state, 0
-__machdep_save_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save integer registers */
- stq ra, ( 0 * 8)(a0) /* return address */
- stq s0, ( 1 * 8)(a0) /* callee-saved registers */
- stq s1, ( 2 * 8)(a0)
- stq s2, ( 3 * 8)(a0)
- stq s3, ( 4 * 8)(a0)
- stq s4, ( 5 * 8)(a0)
- stq s5, ( 6 * 8)(a0)
- stq s6, ( 7 * 8)(a0)
- stq sp, ( 9 * 8)(a0)
- stq ra, ( 8 * 8)(a0) /* RA on return */
- stq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- mov zero, v0
- lda sp, 16(sp)
- RET
- .end __machdep_save_int_state
-
- .align 4
- .global __machdep_restore_int_state
- .ent __machdep_restore_int_state, 0
-__machdep_restore_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore integer registers */
- ldq t0, ( 0 * 8)(a0) /* return address */
- ldq s0, ( 1 * 8)(a0) /* callee-saved registers */
- ldq s1, ( 2 * 8)(a0)
- ldq s2, ( 3 * 8)(a0)
- ldq s3, ( 4 * 8)(a0)
- ldq s4, ( 5 * 8)(a0)
- ldq s5, ( 6 * 8)(a0)
- ldq s6, ( 7 * 8)(a0)
- ldq ra, ( 8 * 8)(a0) /* RA after return */
- ldq sp, ( 9 * 8)(a0)
- ldq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- ldiq v0, 1
- ret zero,(t0),1
- .end __machdep_restore_int_state
-
- .align 4
- .global __machdep_save_fp_state
- .ent __machdep_save_fp_state, 0
-__machdep_save_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save FP registers */
- stt fs0, (0 * 8)(a0) /* callee-saved registers */
- stt fs1, (1 * 8)(a0)
- stt fs2, (2 * 8)(a0)
- stt fs3, (3 * 8)(a0)
- stt fs4, (4 * 8)(a0)
- stt fs5, (5 * 8)(a0)
- stt fs6, (6 * 8)(a0)
- stt fs7, (7 * 8)(a0)
- mf_fpcr ft0 /* and FP control reg */
- stt ft0, (8 * 8)(a0)
-
- lda sp, 16(sp)
- RET
- .end __machdep_save_fp_state
-
- .align 4
- .global __machdep_restore_fp_state
- .ent __machdep_restore_fp_state, 0
-__machdep_restore_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore FP registers */
- ldt fs0, (0 * 8)(a0) /* callee-saved registers */
- ldt fs1, (1 * 8)(a0)
- ldt fs2, (2 * 8)(a0)
- ldt fs3, (3 * 8)(a0)
- ldt fs4, (4 * 8)(a0)
- ldt fs5, (5 * 8)(a0)
- ldt fs6, (6 * 8)(a0)
- ldt fs7, (7 * 8)(a0)
- ldt ft0, (8 * 8)(a0)
- mt_fpcr ft0 /* and FP control reg */
-
- lda sp, 16(sp)
- RET
- .end __machdep_restore_fp_state
diff --git a/mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S b/mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S
deleted file mode 100644
index 61435a729d7..00000000000
--- a/mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S
+++ /dev/null
@@ -1,228 +0,0 @@
-#include <machine/asm.h>
-#define CHMK() call_pal 0x83
-#define COMPAT_43
-#include <sys/syscall.h>
-#ifndef __CONCAT
-#include <sys/cdefs.h>
-#endif
-#define CONCAT __CONCAT
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl CONCAT(machdep_sys_,x) ;\
- .ent CONCAT(machdep_sys_,x), 0 ;\
-CONCAT(machdep_sys_,x): ;\
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
- beq a3, CONCAT(Lsys_noerr_,x) ;\
- br gp, CONCAT(Lsys_err_,x) ;\
-CONCAT(Lsys_err_,x): ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-CONCAT(Lsys_noerr_,x):
-
-#define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
-machdep_cerror:
- br t0, Lmachdep_cerror_setgp
-Lmachdep_cerror_setgp:
- ldgp gp, 0(t0)
- stl v0, errno
-#if 0
- ldiq v0, -1
-#else
- subq zero, v0, v0
-#endif
- RET
-
-/* The fork system call is special... */
-SYSCALL(fork)
- cmovne a4, 0, v0
- RET
- .end machdep_sys_fork
-
-/* The pipe system call is special... */
-SYSCALL(pipe)
- stl v0, 0(a0)
- stl a4, 4(a0)
- mov zero, v0
- RET
- .end machdep_sys_pipe
-
-#ifndef SYS___sigsuspend14
-/* The sigsuspend system call is special... */
- .align 4
- .globl machdep_sys_sigsuspend
- .ent machdep_sys_sigsuspend, 0
-machdep_sys_sigsuspend:
- ldl a0, 0(a0) /* pass *mask instead of mask */
- ldiq v0, SYS_sigsuspend
- CHMK()
- mov zero, v0 /* shouldn't need; just in case... */
- RET
- .end machdep_sys_sigsuspend
-#endif /* SYS_sigsuspend14 */
-
-#ifndef SYS___sigprocmask14
-/* The sigprocmask system call is special... */
- .align 4
- .globl machdep_sys_sigprocmask
- .ent machdep_sys_sigprocmask, 0
-machdep_sys_sigprocmask:
- mov a2, a5 /* safe */
- cmoveq a1, 1, a0 /* if set == NULL, how = SIG_BLOCK */
- beq a1, Ldoit /* and set = 0, and do it. */
- ldl a1, 0(a1) /* load the set from *set */
-Ldoit: ldiq v0, SYS_sigprocmask
- CHMK()
- beq a5, Lret /* if they don't want old mask, done */
- stl v0, 0(a5) /* otherwise, give it to them. */
-Lret: mov zero, v0
- RET
- .end machdep_sys_sigprocmask
-#endif /* SYS_sigprocmask14 */
-
-/* More stuff ... */
- .align 4
- .global __machdep_save_int_state
- .ent __machdep_save_int_state, 0
-__machdep_save_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save integer registers */
- stq ra, ( 0 * 8)(a0) /* return address */
- stq s0, ( 1 * 8)(a0) /* callee-saved registers */
- stq s1, ( 2 * 8)(a0)
- stq s2, ( 3 * 8)(a0)
- stq s3, ( 4 * 8)(a0)
- stq s4, ( 5 * 8)(a0)
- stq s5, ( 6 * 8)(a0)
- stq s6, ( 7 * 8)(a0)
- stq sp, ( 9 * 8)(a0)
- stq ra, ( 8 * 8)(a0) /* RA on return */
- stq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- mov zero, v0
- lda sp, 16(sp)
- RET
- .end __machdep_save_int_state
-
- .align 4
- .global __machdep_restore_int_state
- .ent __machdep_restore_int_state, 0
-__machdep_restore_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore integer registers */
- ldq t0, ( 0 * 8)(a0) /* return address */
- ldq s0, ( 1 * 8)(a0) /* callee-saved registers */
- ldq s1, ( 2 * 8)(a0)
- ldq s2, ( 3 * 8)(a0)
- ldq s3, ( 4 * 8)(a0)
- ldq s4, ( 5 * 8)(a0)
- ldq s5, ( 6 * 8)(a0)
- ldq s6, ( 7 * 8)(a0)
- ldq ra, ( 8 * 8)(a0) /* RA after return */
- ldq sp, ( 9 * 8)(a0)
- ldq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- ldiq v0, 1
- ret zero,(t0),1
- .end __machdep_restore_int_state
-
- .align 4
- .global __machdep_save_fp_state
- .ent __machdep_save_fp_state, 0
-__machdep_save_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save FP registers */
- stt fs0, (0 * 8)(a0) /* callee-saved registers */
- stt fs1, (1 * 8)(a0)
- stt fs2, (2 * 8)(a0)
- stt fs3, (3 * 8)(a0)
- stt fs4, (4 * 8)(a0)
- stt fs5, (5 * 8)(a0)
- stt fs6, (6 * 8)(a0)
- stt fs7, (7 * 8)(a0)
- mf_fpcr ft0 /* and FP control reg */
- stt ft0, (8 * 8)(a0)
-
- lda sp, 16(sp)
- RET
- .end __machdep_save_fp_state
-
- .align 4
- .global __machdep_restore_fp_state
- .ent __machdep_restore_fp_state, 0
-__machdep_restore_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore FP registers */
- ldt fs0, (0 * 8)(a0) /* callee-saved registers */
- ldt fs1, (1 * 8)(a0)
- ldt fs2, (2 * 8)(a0)
- ldt fs3, (3 * 8)(a0)
- ldt fs4, (4 * 8)(a0)
- ldt fs5, (5 * 8)(a0)
- ldt fs6, (6 * 8)(a0)
- ldt fs7, (7 * 8)(a0)
- ldt ft0, (8 * 8)(a0)
- mt_fpcr ft0 /* and FP control reg */
-
- lda sp, 16(sp)
- RET
- .end __machdep_restore_fp_state
-
-/* For fstat() we actually syscall fstat13. */
- .align 4
- .globl machdep_sys_fstat
- .ent machdep_sys_fstat, 0
-machdep_sys_fstat:
- .frame sp,0,ra
- ldiq v0, SYS___fstat13
- CHMK()
- beq a3, Lsys_noerr_fstat
- br gp, Lsys_err_fstat
-Lsys_err_fstat:
- /* Load gp so we can find cerror to jump to. */
- ldgp gp, 0(gp)
- jmp zero, machdep_cerror
-Lsys_noerr_fstat:
- RET
- .end machdep_sys_fstat
diff --git a/mit-pthreads/machdep/syscall-alpha-osf1.S b/mit-pthreads/machdep/syscall-alpha-osf1.S
deleted file mode 100644
index fad823a7352..00000000000
--- a/mit-pthreads/machdep/syscall-alpha-osf1.S
+++ /dev/null
@@ -1,97 +0,0 @@
-#include <asm.h>
-#include <regdef.h>
-#define COMPAT_43
-#include <syscall.h>
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, 2f ;\
- br gp, 1f ;\
-1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-2:
-
-#define XSYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
- .globl machdep_cerror
-machdep_cerror:
- br t0, 1f
-1:
- ldgp gp, 0(t0)
- stl v0, errno
-#if 0
- ldiq v0, -1
-#else
- subq zero, v0, v0
-#endif
- ret
-
-/* The fork system call is special... */
-SYSCALL(fork)
- cmovne a4, 0, v0
- ret
- .end machdep_sys_fork
-
-/* So is the sigsuspend system call */
- .align 4
- .globl machdep_sys_sigsuspend
- .ent machdep_sys_sigsuspend, 0
-machdep_sys_sigsuspend:
- .frame sp,0,ra
-
- bis a0, a0, a1
- ldq a0, 0(a1)
- ldiq v0, SYS_sigsuspend
- CHMK()
- ret
- .end machdep_sys_sigsuspend
-
-/* More stuff ... */
- .align 4
- .globl machdep_restore_from_setjmp
- .ent machdep_restore_from_setjmp, 0
-machdep_restore_from_setjmp:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
- ldq v0, 280(a0)
- subq v0, 0x00000000acedbade, t0
- bne t0, botch
- cmoveq a1, 0x1, a1
- stq a1, 32(a0)
- ldiq v0, 0x67
- call_pal 0x83
-botch:
- /* This should cause the program to crash. Eventually, fix it
- up to print a message first. */
- jsr abort
- .end machdep_restore_from_setjmp
diff --git a/mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S b/mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S
deleted file mode 100644
index 5914674b508..00000000000
--- a/mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S
+++ /dev/null
@@ -1,193 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 0
-
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _C_LABEL(machdep_sys_fork);
-
-_C_LABEL(machdep_sys_fork):;
-
- swi SYS_fork
- bcs 1f
- sub r1, r1, #0x00000001
- and r0, r0, r1
- mov r15, r14
-
-
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
- .globl _C_LABEL(machdep_sys_fstat);
-
-_C_LABEL(machdep_sys_fstat):;
-
- swi SYS___fstat13
- bcs 1f
- mov r15, r14
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- swi SYS___syscall
- bcs 1f
- mov r15, r14
-
-
-#ifndef SYS___sigsuspend14
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _C_LABEL(machdep_sys_sigsuspend);
-
-_C_LABEL(machdep_sys_sigsuspend):;
-
- ldr r0, [r0]
- swi SYS_sigsuspend
- bcs 1f
- mov r0, #0x00000000
- mov r15, r14
-
-#endif
-
-#ifndef SYS___sigprocmask14
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _C_LABEL(machdep_sys_sigprocmask);
-
-_C_LABEL(machdep_sys_sigprocmask):;
-
- teq r1, #0x00000000
- moveq r0, #0x00000001
- moveq r1, #0x00000000
- ldrne r1, [r1]
- swi SYS_sigprocmask
- bcs 1f
- teq r2, #0x00000000
- strne r0, [r2]
- mov r0, #0x00000000
- mov r15, r14
-#endif
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
- .global _C_LABEL(machdep_sys_ftruncate)
-_C_LABEL(machdep_sys_ftruncate):
- mov r12, r13
- stmfd r13!, {r11, r12, r14, r15}
- sub r13, r13, #8
- stmia r13, {r1-r2}
- mov r3, #0
- sub r11, r12, #4
- mov r2, r0
- mov r1, #0
- mov r0, #201
- bl _machdep_sys___syscall
- ldmea r11, {r11, r13, r15}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .global _C_LABEL(machdep_sys_lseek)
-
-_C_LABEL(machdep_sys_lseek):
- mov r12, r13
- stmfd r13!, {r11, r12, r14, r15}
- str r3, [r13, #-4]!
- sub r13, r13, #8
- stmia r13, {r1-r2}
- sub r11, r12, #4
- mov r3, #0
- mov r2, r0
- mov r1, #0
- mov r0, #SYS_lseek
- bl _machdep_sys___syscall
- ldmea r11, {r11, r13, r15}
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _C_LABEL(machdep_sys_pipe);
-
-_C_LABEL(machdep_sys_pipe):;
-
- mov r2, r0
- swi SYS_pipe
- bcs 1f
- str r0, [r2, #0x0000]
- str r1, [r2, #0x0004]
- mov r0, #0x00000000
- mov r15, r14
-
-
-1:
- rsb r0, r0, #0x00000000
- mvn r1, #0x00000000
- mov r15, r14
diff --git a/mit-pthreads/machdep/syscall-hppa-hpux-10.20.S b/mit-pthreads/machdep/syscall-hppa-hpux-10.20.S
deleted file mode 100644
index c63d845bae5..00000000000
--- a/mit-pthreads/machdep/syscall-hppa-hpux-10.20.S
+++ /dev/null
@@ -1,23 +0,0 @@
- .CODE
-
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
-machdep_sys_fork
-
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
-
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi 2 ,%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- or,= %r29,%r0,%r0
- copy %r0,%r28
- bv,n %r0(%r2)
-
- .PROCEND
- .EXPORT machdep_sys_fork,ENTRY
-
diff --git a/mit-pthreads/machdep/syscall-hppa-hpux-9.03.S b/mit-pthreads/machdep/syscall-hppa-hpux-9.03.S
deleted file mode 100644
index c63d845bae5..00000000000
--- a/mit-pthreads/machdep/syscall-hppa-hpux-9.03.S
+++ /dev/null
@@ -1,23 +0,0 @@
- .CODE
-
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
-machdep_sys_fork
-
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
-
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi 2 ,%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- or,= %r29,%r0,%r0
- copy %r0,%r28
- bv,n %r0(%r2)
-
- .PROCEND
- .EXPORT machdep_sys_fork,ENTRY
-
diff --git a/mit-pthreads/machdep/syscall-i386-bsdi-1.1.S b/mit-pthreads/machdep/syscall-i386-bsdi-1.1.S
deleted file mode 100644
index e54cd0d0773..00000000000
--- a/mit-pthreads/machdep/syscall-i386-bsdi-1.1.S
+++ /dev/null
@@ -1,288 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL(write)
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL(read)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL(close)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL(fcntl)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL(dup)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL(dup2)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL(execve)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL(fstat)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL(fchmod)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(chdir)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(link)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(unlink)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(rename)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-SYSCALL(select)
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-SYSCALL(getdirentries)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL(wait4)
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socket()
- */
-SYSCALL(socket)
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-SYSCALL(bind)
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-SYSCALL(connect)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-SYSCALL(accept)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-SYSCALL(listen)
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-SYSCALL(getsockopt)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-SYSCALL(readv)
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-SYSCALL(writev)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-SYSCALL(getpeername)
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-SYSCALL(getsockname)
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-SYSCALL(sendto)
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-SYSCALL(recvfrom)
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-SYSCALL(sendmsg)
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-SYSCALL(recvmsg)
-
-/* ==========================================================================
- * machdep_sys_shutdown() - Is this correct?
- */
-SYSCALL(shutdown)
-
diff --git a/mit-pthreads/machdep/syscall-i386-bsdi-2.0.S b/mit-pthreads/machdep/syscall-i386-bsdi-2.0.S
deleted file mode 100644
index 8a56717da31..00000000000
--- a/mit-pthreads/machdep/syscall-i386-bsdi-2.0.S
+++ /dev/null
@@ -1,294 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-netbsd-1.0.S,v 1.56 1995/09/26 21:04:05 raeburn Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-
-/* BSDI DEFS.h,v 2.1 1995/02/03 06:28:24 polk Exp */
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)DEFS.h 8.1 (Berkeley) 6/4/93
- */
-
-#ifdef PROF
-#define ENTRY(x) .globl _/**/x; .align 2; _/**/x: \
- .data; 1:; .long 0; .text; \
- pushl %ebp; movl %esp,%ebp; \
- leal 1b,%eax; call mcount; leave
-#define ASENTRY(x) .globl x; .align 2; x: \
- .data; 1:; .long 0; .text; \
- pushl %ebp; movl %esp,%ebp; \
- leal 1b,%eax; call mcount; leave
-#else
-#define ENTRY(x) .globl _/**/x; .align 2; _/**/x:
-#define ASENTRY(x) .globl x; .align 2; x:
-#endif
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
- .asciz "@(#)_setjmp.s 8.1 (Berkeley) 6/4/93"
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * C library -- _setjmp, _longjmp
- *
- * _longjmp(a,v)
- * will generate a "return(v)" from the last call to
- * _setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is NOT restored.
- */
-
-
-.globl __setjmp; /* Patch by Jan Legenhausen (monty) */
-.align 2;
-__setjmp:
- movl 4(%esp),%eax
- movl 0(%esp),%edx
- movl %edx, 0(%eax) /* rta */
- movl %ebx, 4(%eax)
- movl %esp, 8(%eax)
- movl %ebp,12(%eax)
- movl %esi,16(%eax)
- movl %edi,20(%eax)
- movl $0,%eax
- ret
-
-.globl __longjmp; /* Patch by Jan Legenhausen ? (monty) */
-.align 2;
-__longjmp:
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ecx
- movl 4(%edx),%ebx
- movl 8(%edx),%esp
- movl 12(%edx),%ebp
- movl 16(%edx),%esi
- movl 20(%edx),%edi
- cmpl $0,%eax
- jne 1f
- movl $1,%eax
-1: movl %ecx,0(%esp)
- ret
diff --git a/mit-pthreads/machdep/syscall-i386-freebsd-1.1.S b/mit-pthreads/machdep/syscall-i386-freebsd-1.1.S
deleted file mode 100644
index 5777cc5e06d..00000000000
--- a/mit-pthreads/machdep/syscall-i386-freebsd-1.1.S
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL(write)
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL(read)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL(close)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL(fcntl)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL(lseek)
-
-/* ==========================================================================
- * machdep_sys_stat()
- */
-SYSCALL(stat)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL(dup)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL(dup2)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL(execve)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL(fstat)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL(fchmod)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(chdir)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(link)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(unlink)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(rename)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-SYSCALL(select)
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-SYSCALL(getdirentries)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL(wait4)
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socket()
- */
-SYSCALL(socket)
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-SYSCALL(bind)
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-SYSCALL(connect)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-SYSCALL(accept)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-SYSCALL(listen)
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-SYSCALL(getsockopt)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-SYSCALL(readv)
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-SYSCALL(writev)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-SYSCALL(getpeername)
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-SYSCALL(getsockname)
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-SYSCALL(sendto)
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-SYSCALL(recvfrom)
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-SYSCALL(sendmsg)
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-SYSCALL(recvmsg)
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-SYSCALL(shutdown)
-
diff --git a/mit-pthreads/machdep/syscall-i386-freebsd-2.0.S b/mit-pthreads/machdep/syscall-i386-freebsd-2.0.S
deleted file mode 100644
index b713bcac344..00000000000
--- a/mit-pthreads/machdep/syscall-i386-freebsd-2.0.S
+++ /dev/null
@@ -1,240 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1995 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-freebsd-2.0.S,v 1.2 1995/05/26 07:44:29 proven Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#ifdef __ELF__
-#define NAME(X) machdep_sys_##X
-#else
-#define NAME(X) _machdep_sys_##X
-#endif
-
-#else
-
-#ifdef __ELF__
-#define NAME(X) machdep_sys_/**/X
-#else
-#define NAME(X) _machdep_sys_/**/X
-#endif
-
-#endif
-
-#ifdef __ELF__
-#define END(X) 5: ; .type NAME(X),@function ; .size NAME(X),5b - NAME(X)
-#define KERNCALL int $0x80
-#else
-#define END(X)
-#define KERNCALL .byte 0x9a; .long 0; .word 7;
-#endif
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl NAME(fork);
-
-NAME(fork):;
-
- movl $(SYS_fork), %eax;
- KERNCALL;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
- END(fork)
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- KERNCALL;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl NAME(sigsuspend);
-
-NAME(sigsuspend):;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- KERNCALL;
- jb 3f;
- ret
-3:
- neg %eax
- movl $0xffffffff,%edx
- ret
- END(sigsuspend)
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl NAME(sigprocmask);
-
-NAME(sigprocmask):;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $ SYS_sigprocmask , %eax
- KERNCALL;
- jb 4f;
- ret
-4:
- neg %eax
- movl $0xffffffff,%edx
- ret
- END(sigprocmask)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl NAME(lseek);
-
-NAME(lseek):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
- END(lseek)
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl NAME(ftruncate);
-
-NAME(ftruncate):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
- END(ftruncate)
-
-/* ==========================================================================
- * machdep_sys_setjmp()
- */
- .globl NAME(setjmp);
-
-NAME(setjmp):;
- movl 4(%esp),%eax
- movl 0(%esp),%edx
- movl %edx, 0(%eax) /* rta */
- movl %ebx, 4(%eax)
- movl %esp, 8(%eax)
- movl %ebp,12(%eax)
- movl %esi,16(%eax)
- movl %edi,20(%eax)
- xorl %eax,%eax
- ret
- END(setjmp)
-
-/* ==========================================================================
- * machdep_sys_longjmp()
- */
- .globl NAME(longjmp);
-
-NAME(longjmp):;
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ecx
- movl 4(%edx),%ebx
- movl 8(%edx),%esp
- movl 12(%edx),%ebp
- movl 16(%edx),%esi
- movl 20(%edx),%edi
- testl %eax,%eax
- jnz 1f
- incl %eax
-1:
- movl %ecx,0(%esp)
- ret
- END(longjmp)
diff --git a/mit-pthreads/machdep/syscall-i386-linux-1.0.S b/mit-pthreads/machdep/syscall-i386-linux-1.0.S
deleted file mode 100644
index 1399c812e2f..00000000000
--- a/mit-pthreads/machdep/syscall-i386-linux-1.0.S
+++ /dev/null
@@ -1,406 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- *
- * 1.16 94/01/30 proven
- * -This file now requires gas version 2.0 or greater.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-#include <config.h>
-
-#ifdef __ELF__
-
-#define NAME(X) machdep_sys_##X
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#define SYSCALL0(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL1(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL2(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define STATCALL2(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- lea SYS_prev_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- END(x)
-
-#define SYSCALL3(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- mov 16(%esp), %edx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- END(x)
-
-
-#define SYSCALL4(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- mov 12(%esp), %ebx; \
- mov 16(%esp), %ecx; \
- mov 20(%esp), %edx; \
- mov 24(%esp), %esi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-#define SYSCALL5(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- push %edi; \
- mov 16(%esp), %ebx; \
- mov 20(%esp), %ecx; \
- mov 24(%esp), %edx; \
- mov 28(%esp), %esi; \
- mov 32(%esp), %edi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %edi; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-/* =========================================================================
- * exit 1 select 82
- * fork 2 fstatfs 100
- * read 3 socketcall 102
- * write 4 flock 143
- * open 5 readv 145
- * creat 8 writev 146
- * link 9
- * unlink 10
- * execve 11
- * chdir 12
- * chmod 15
- * chown 16
- * lseek 19
- * rename 38
- * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
- * dup2 63
- * readdir 89
- * ftruncate 93
- * fchmod 94
- * fchown 95
- */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL3(read)
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL3(write)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL3(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL1(close)
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-SYSCALL2(creat)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL2(dup2)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL3(fcntl)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL3(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL2(fchmod)
-
-/* ==========================================================================
- * machdep_sys_ioctl()
- */
-SYSCALL3(ioctl)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL3(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL2(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL1(chdir)
-
-/* ==========================================================================
- * machdep_sys_unlink()
- */
-SYSCALL1(unlink)
-
-/* ==========================================================================
- * machdep_sys_link()
- */
-SYSCALL2(link)
-
-/* ==========================================================================
- * machdep_sys_rename()
- */
-SYSCALL2(rename)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL3(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL1(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL1(dup)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
-SYSCALL0(fork)
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL3(execve)
-
-/* ==========================================================================
- * machdep_sys_stat()
- */
-#ifdef __ELF__
-STATCALL2(stat)
-#else
-SYSCALL2(stat)
-#endif
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-#ifdef __ELF__
-STATCALL2(fstat)
-#else
-SYSCALL2(fstat)
-#endif
-
-/* ==========================================================================
- * machdep_sys_lstat()
- */
-#ifdef __ELF__
-STATCALL2(lstat)
-#else
-SYSCALL2(lstat)
-#endif
-
-/* ==========================================================================
- * machdep_sys_fstatfs()
- */
-SYSCALL2(fstatfs)
-
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
-SYSCALL2(ftruncate)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-
- .globl NAME(select)
-
-NAME(select):
-
- push %ebx
- lea 8(%esp), %ebx
- lea SYS_select, %eax
- int $0x80
- pop %ebx
- ret
- END(select)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL4(wait4)
-
-/* ==========================================================================
- * machdep_sys_readdir()
- */
-SYSCALL3(readdir)
-
-/* ==========================================================================
- * machdep_sys_socketcall()
- */
-SYSCALL2(socketcall)
-
-
-SYSCALL1(exit)
-SYSCALL3(sigprocmask)
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
-
- .globl NAME(sigsuspend)
-
-NAME(sigsuspend):
-
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- mov 8(%ebp), %edx
- mov (%edx), %edx
- lea SYS_sigsuspend, %eax
- int $0x80
- pop %ebx
- pop %esi
- pop %edi
- mov %ebp,%esp
- pop %ebp
- ret
- END(sigsuspend)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-#ifdef HAVE_SYSCALL_READV
-SYSCALL3(readv)
-#endif
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-#ifdef HAVE_SYSCALL_WRITEV
-SYSCALL3(writev)
-#endif
-
-/* ==========================================================================
- * machdep_sys_flock()
- */
-#ifdef HAVE_SYSCALL_FLOCK
-SYSCALL2(flock)
-#endif
diff --git a/mit-pthreads/machdep/syscall-i386-linux-2.0.S b/mit-pthreads/machdep/syscall-i386-linux-2.0.S
deleted file mode 100644
index d5807b2d9b4..00000000000
--- a/mit-pthreads/machdep/syscall-i386-linux-2.0.S
+++ /dev/null
@@ -1,389 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- *
- * 1.16 94/01/30 proven
- * -This file now requires gas version 2.0 or greater.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-#include <config.h>
-
-#ifdef __ELF__
-
-#define NAME(X) machdep_sys_##X
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#define SYSCALL0(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL1(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL2(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL3(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- mov 16(%esp), %edx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- END(x)
-
-
-#define SYSCALL4(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- mov 12(%esp), %ebx; \
- mov 16(%esp), %ecx; \
- mov 20(%esp), %edx; \
- mov 24(%esp), %esi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-#define SYSCALL5(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- push %edi; \
- mov 16(%esp), %ebx; \
- mov 20(%esp), %ecx; \
- mov 24(%esp), %edx; \
- mov 28(%esp), %esi; \
- mov 32(%esp), %edi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %edi; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-/* =========================================================================
- * exit 1 select 82
- * fork 2 fstatfs 100
- * read 3 socketcall 102
- * write 4 flock 143
- * open 5 readv 145
- * creat 8 writev 146
- * link 9
- * unlink 10
- * execve 11
- * chdir 12
- * chmod 15
- * chown 16
- * lseek 19
- * rename 38
- * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
- * dup2 63
- * readdir 89
- * ftruncate 93
- * fchmod 94
- * fchown 95
- */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL3(read)
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL3(write)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL3(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL1(close)
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-SYSCALL2(creat)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL2(dup2)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL3(fcntl)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL3(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL2(fchmod)
-
-/* ==========================================================================
- * machdep_sys_ioctl()
- */
-SYSCALL3(ioctl)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL3(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL2(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL1(chdir)
-
-/* ==========================================================================
- * machdep_sys_unlink()
- */
-SYSCALL1(unlink)
-
-/* ==========================================================================
- * machdep_sys_link()
- */
-SYSCALL2(link)
-
-/* ==========================================================================
- * machdep_sys_rename()
- */
-SYSCALL2(rename)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL3(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL1(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL1(dup)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
-SYSCALL0(fork)
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL3(execve)
-
-/* ==========================================================================
- * machdep_sys_stat()
- */
-SYSCALL2(stat)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL2(fstat)
-
-/* ==========================================================================
- * machdep_sys_lstat()
- */
-SYSCALL2(lstat)
-
-/* ==========================================================================
- * machdep_sys_fstatfs()
- */
-SYSCALL2(fstatfs)
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
-SYSCALL2(ftruncate)
-
-/* ==========================================================================
- * machdep_sys_chroot()
- */
-SYSCALL1(chroot)
-
-/* ==========================================================================
- * machdep_sys_uname()
- */
-SYSCALL1(uname)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-
- .globl NAME(select)
-
-NAME(select):
-
- push %ebx
- lea 8(%esp), %ebx
- lea SYS_select, %eax
- int $0x80
- pop %ebx
- ret
- END(select)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL4(wait4)
-
-/* ==========================================================================
- * machdep_sys_readdir()
- */
-SYSCALL3(readdir)
-
-/* ==========================================================================
- * machdep_sys_socketcall()
- */
-SYSCALL2(socketcall)
-
-
-SYSCALL1(exit)
-SYSCALL3(sigprocmask)
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
-
- .globl NAME(sigsuspend)
-
-NAME(sigsuspend):
-
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- mov 8(%ebp), %edx
- mov (%edx), %edx
- lea SYS_sigsuspend, %eax
- int $0x80
- pop %ebx
- pop %esi
- pop %edi
- mov %ebp,%esp
- pop %ebp
- ret
- END(sigsuspend)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-#ifdef HAVE_SYSCALL_READV
-SYSCALL3(readv)
-#endif
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-#ifdef HAVE_SYSCALL_WRITEV
-SYSCALL3(writev)
-#endif
-
-/* ==========================================================================
- * machdep_sys_flock()
- */
-#ifdef HAVE_SYSCALL_FLOCK
-SYSCALL2(flock)
-#endif
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-0.9.S b/mit-pthreads/machdep/syscall-i386-netbsd-0.9.S
deleted file mode 100644
index 8d768a673d3..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-0.9.S
+++ /dev/null
@@ -1,229 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL(write)
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL(read)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL(close)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL(fcntl)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL(dup)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL(dup2)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL(execve)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL(fstat)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-SYSCALL(select)
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-SYSCALL(getdirentries)
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socket()
- */
-SYSCALL(socket)
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-SYSCALL(bind)
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-SYSCALL(connect)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-SYSCALL(accept)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-SYSCALL(listen)
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-SYSCALL(getsockopt)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-SYSCALL(readv)
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-SYSCALL(writev)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-SYSCALL(getpeername)
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-SYSCALL(getsockname)
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-SYSCALL(sendto)
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-SYSCALL(recvfrom)
-
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-1.0.S b/mit-pthreads/machdep/syscall-i386-netbsd-1.0.S
deleted file mode 100644
index da535dd2f80..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-1.0.S
+++ /dev/null
@@ -1,158 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-1.1.S b/mit-pthreads/machdep/syscall-i386-netbsd-1.1.S
deleted file mode 100644
index a74d2ac1af6..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-1.1.S
+++ /dev/null
@@ -1,181 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- int $0x80;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- int $0x80;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _machdep_sys_sigprocmask;
-
-_machdep_sys_sigprocmask:;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $(SYS_sigprocmask), %eax;
- int $0x80;
- jb 3b;
- ret
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe;
-
-_machdep_sys_pipe:;
-
- movl $(SYS_pipe), %eax;
- int $0x80;
- jb 3b;
- movl 4(%esp),%ecx
- movl %eax,(%ecx)
- movl %edx,4(%ecx)
- xorl %eax,%eax
- ret
-
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-1.3.S b/mit-pthreads/machdep/syscall-i386-netbsd-1.3.S
deleted file mode 100644
index 85dc6b3e5bc..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-1.3.S
+++ /dev/null
@@ -1,200 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _C_LABEL(machdep_sys_fork);
-
-_C_LABEL(machdep_sys_fork):;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- int $0x80;
- jb 3f;
- ret
-
-#ifndef SYS___sigsuspend14
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _C_LABEL(machdep_sys_sigsuspend);
-
-_C_LABEL(machdep_sys_sigsuspend):;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- int $0x80;
- jb 3f;
- ret
-#endif
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _C_LABEL(machdep_sys_lseek);
-
-_C_LABEL(machdep_sys_lseek):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _C_LABEL(machdep_sys_ftruncate);
-
-_C_LABEL(machdep_sys_ftruncate):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-#ifndef SYS___sigprocmask14
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _C_LABEL(machdep_sys_sigprocmask);
-
-_C_LABEL(machdep_sys_sigprocmask):;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $(SYS_sigprocmask), %eax;
- int $0x80;
- jb 3b;
- ret
-#endif
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _C_LABEL(machdep_sys_pipe);
-
-_C_LABEL(machdep_sys_pipe):;
-
- movl $(SYS_pipe), %eax;
- int $0x80;
- jb 3b;
- movl 4(%esp),%ecx
- movl %eax,(%ecx)
- movl %edx,4(%ecx)
- xorl %eax,%eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
- .globl _C_LABEL(machdep_sys_fstat);
-
-_C_LABEL(machdep_sys_fstat):;
- movl $(SYS___fstat13), %eax;
- int $0x80;
- jb 4f;
- ret
-4:
- neg %eax
- movl $0xffffffff,%edx
- ret
-
diff --git a/mit-pthreads/machdep/syscall-i386-openbsd-2.0.S b/mit-pthreads/machdep/syscall-i386-openbsd-2.0.S
deleted file mode 100644
index cfdbbc77f73..00000000000
--- a/mit-pthreads/machdep/syscall-i386-openbsd-2.0.S
+++ /dev/null
@@ -1,237 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1995 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-freebsd-2.0.S,v 1.2 1995/05/26 07:44:29 proven Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x##; \
- \
-_machdep_sys_##x##:; \
- \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _machdep_sys_sigprocmask;
-
-_machdep_sys_sigprocmask:;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $ SYS_sigprocmask , %eax
- .byte 0x9a; .long 0; .word 7;
- jb 4f;
- ret
-
-4:
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_setjmp()
- */
- .globl _machdep_sys_setjmp;
-
-_machdep_sys_setjmp:;
- movl 4(%esp),%eax
- movl 0(%esp),%edx
- movl %edx, 0(%eax) /* rta */
- movl %ebx, 4(%eax)
- movl %esp, 8(%eax)
- movl %ebp,12(%eax)
- movl %esi,16(%eax)
- movl %edi,20(%eax)
- xorl %eax,%eax
- ret
-
-/* ==========================================================================
- * machdep_sys_longjmp()
- */
- .globl _machdep_sys_longjmp;
-
-_machdep_sys_longjmp:;
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ecx
- movl 4(%edx),%ebx
- movl 8(%edx),%esp
- movl 12(%edx),%ebp
- movl 16(%edx),%esi
- movl 20(%edx),%edi
- testl %eax,%eax
- jnz 1f
- incl %eax
-1: movl %ecx,0(%esp)
- ret
-
diff --git a/mit-pthreads/machdep/syscall-i386-sco-3.2v5.S b/mit-pthreads/machdep/syscall-i386-sco-3.2v5.S
deleted file mode 100644
index 0a60dcdd866..00000000000
--- a/mit-pthreads/machdep/syscall-i386-sco-3.2v5.S
+++ /dev/null
@@ -1,442 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1995 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-sco-3.2v5.S,v 1.2 1995/05/26 07:44:29 proven Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/errno.h>
-#include <sys/syscall.h>
-
-#ifdef _SCO_ELF
-
-#define NAME(X) machdep_sys_##X
-#define GETADDR(X) \
- call 1f; \
-1: \
- popl %ebx; \
- addl $NAME(X)+[.-1b], %ebx
-
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x): \
- movl $(SYS_##x##), %eax; \
- lcall $7, $0; \
- jae 1f; \
- cmp $(ERESTART), %eax; \
- je NAME(x); \
- neg %eax; \
-1: \
- ret; \
-\
- END(x)
-
-
-#else
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x): \
- \
- movl $(SYS_/**/x), %eax; \
- lcall $7, $0; \
- jb 1b; \
- ret; \
- END(x)
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl NAME(fork);
-
-NAME(fork):;
- movl $(SYS_fork), %eax
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- test %edx, %edx
- je 2f
- xor %eax, %eax
-2:
- ret;
- END(fork)
-
-/* ==========================================================================
- * NAME(getdents)
- */
- .globl NAME(getdents);
-
-NAME(getdents):
- movl $(SYS_getdents), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret;
- END(getdents)
-
-/* ==========================================================================
- * NAME(fxstat)
- */
- .globl NAME(fxstat);
-
-NAME(fxstat):;
- movl $(SYS_fxstat), %eax;
- lcall $7, $0
- jae 1f
- neg %eax;
- ret;
-1:
- xor %eax, %eax;
- ret;
- END(fxstat)
-
-/* ==========================================================================
- * NAME(signal)
- */
- .globl NAME(signal);
-
-NAME(signal):;
- movl 4(%esp), %ecx
- movl $(SYS_signal),%eax
-#if 0
- call .L1
-.L1:
- popl %edx
- addl $(NAME(sigreturn)+[.-.L1]), %edx
-#else
- movl $NAME(sigreturn), %edx
-#endif
- lcall $7,$0
- jae 1f
-# movl %eax, 12(%esp)
- neg %eax
- ret
-1:
-# xor %eax, %eax
-# movl %eax, 12(%esp)
- ret
- END(signal)
-
-/* ==========================================================================
- * NAME(sigaction)
- */
- .globl NAME(sigaction);
-
-NAME(sigaction):
- movl $(SYS_sigaction),%eax
-#if 0
- call .L2
-.L2:
- popl %edx
- addl $(NAME(sigreturn)+[.-.L2]), %edx
-#else
- movl $NAME(sigreturn), %edx
-#endif
- lcall $7, $0
- jb 1f
- xor %eax, %eax
- ret
-1:
- neg %eax
- ret
- END(sigaction)
-
- .globl NAME(sigreturn)
-NAME(sigreturn):
- addl $4,%esp
- lcall $0xf, $0
- nop
- nop
- END(sigreturn)
-
-/* ==========================================================================
- * NAME(waitpid)
- */
- .globl NAME(waitpid);
-
-NAME(waitpid):
- .byte 0x9c
- popl %eax
- orl $0x8c4, %eax
- pushl %eax
- .byte 0x9d
- movl $(SYS_wait), %eax
- lcall $7, $0
- jae 2f
- cmpl $(ERESTART), %al
- je NAME(waitpid)
- neg %eax
-3:
- ret
-2:
- movl 8(%esp), %ecx
- test %ecx,%ecx
- je 3b
- mov %edx, (%ecx)
- ret
- END(waitpid)
-
-/* ==========================================================================
- * NAME(uname)
- */
- .globl NAME(uname);
-
-NAME(uname):
- pushl $0
- pushl $0
- pushl 12(%esp)
- subl $4, %esp
- movl $(SYS_utssys), %eax
- .byte 0x9a; .long 0; .word 7;
- jb 1f
- addl $16, %esp
- ret
-1:
- addl $16, %esp
- neg %eax
- ret
- END(uname)
-
-
-/* ==========================================================================
- * machdep_sys_ftruncate
- */
-
-SYSCALL(ftruncate)
-
-/* ==========================================================================
- * machdep_sys_ftime
- */
-
-SYSCALL(ftime)
-
-/* ==========================================================================
- * machdep_sys_gettimeofday()
- */
-
-SYSCALL(gettimeofday)
-
-/* ==========================================================================
- * machdep_sys_kill()
- */
-
-SYSCALL(kill)
-
-/* ==========================================================================
- * pthread_sys_setitimer
- */
- .globl NAME(setitimer);
-
-NAME(setitimer):;
- movl $(SYS_setitimer), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- xor %eax, %eax
- ret;
- END(setitimer)
-
-/* ==========================================================================
- * pthread_sys_sysconf
- */
- .globl NAME(sysconf);
-
-NAME(sysconf):;
- movl $(SYS_sysconf), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret;
- END(sysconf)
-
-/* ==========================================================================
- * pthread_sys_sysi86()
- */
- .globl NAME(sysi86);
-
-NAME(sysi86):;
- movl $(SYS_sysi86), %eax
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret;
- END(sysi86)
-
-
-/* ==========================================================================
- * machdep_sys_brk()
- */
- .globl NAME(brk);
-
-NAME(brk):;
- movl $(SYS_break), %eax
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- xor %eax, %eax
- ret;
- END(brk)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl NAME(pipe);
-
-NAME(pipe):;
- movl $(SYS_pipe), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- movl 4(%esp), %ecx
- movl %eax, (%ecx)
- movl %edx, 4(%ecx)
- xor %eax, %eax
- ret;
- END(brk)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
- .globl NAME(fcntl);
-
-NAME(fcntl):;
- movl $(SYS_fcntl), %eax
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret
- END(fcntl)
-
-
-/* ==========================================================================
- * machdep_sys_select()
- */
- .globl NAME(select);
-
-NAME(select):;
- movl $(SYS_select), %eax
- lcall $7, $0
- jae 1f
- cmp $(ERESTART), %eax
- jne 2f
- movl $(EINTR), %eax
-2:
- neg %eax
-1:
- ret
- END(select)
-
-
-/* ==========================================================================
- * setjmp()
- */
- .globl setjmp;
-
-setjmp:
- movl 4(%esp),%eax
- movl %ebx,(%eax)
- movl %esi,4(%eax)
- movl %edi,8(%eax)
- movl %ebp,12(%eax)
- popl %edx
- movl %esp,16(%eax)
- movl %edx,20(%eax)
- subl %eax,%eax
- jmp *%edx
-1: ; .type setjmp,@function ; .size setjmp,1b - setjmp
-
-/* ==========================================================================
- * longjmp()
- */
- .globl longjmp;
-
-longjmp:
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ebx
- movl 4(%edx),%esi
- movl 8(%edx),%edi
- movl 12(%edx),%ebp
- movl 16(%edx),%esp
- test %eax,%eax
- jne 1f
- inc %eax
-1:
- jmp *20(%edx)
-1: ; .type longjmp,@function ; .size longjmp,1b - longjmp
diff --git a/mit-pthreads/machdep/syscall-ip22-irix-5.2.S b/mit-pthreads/machdep/syscall-ip22-irix-5.2.S
deleted file mode 100644
index ded0fc55e38..00000000000
--- a/mit-pthreads/machdep/syscall-ip22-irix-5.2.S
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <sys.s>
-#include <sys/regdef.h>
-
-/*
- Kernel syscall interface:
- Input:
- v0 syscall number
- Output:
-
- This macro is similar to SYSCALL in sys/syscall.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- Compile with -DPIC for pic code.
-*/
-
-#ifdef PIC
-#define PICOPT .option pic2
-#else
-#define PICOPT
-#endif
-
-
-#define YSYSCALL(x) \
- PICOPT; \
- .globl machdep_sys_##x; \
- .ent machdep_sys_##x, 0; \
-machdep_sys_##x:; \
- .frame sp,0,ra; \
- .set noreorder; \
- li v0, SYS_##x; \
- syscall; \
- bne a3, zero, 1b; \
- nop; \
- j ra; \
- nop; \
- .end machdep_sys_##x
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- subu v0,zero,v0;
- j ra;
-
-/* ==========================================================================
- * lstat
- */
- PICOPT;
- .globl machdep_sys_lstat;
- .ent machdep_sys_lstat, 0;
-machdep_sys_lstat:;
- .frame sp,0,ra;
- .set noreorder;
- move a2, a1
- move a1, a0
- li a0, 2
- li v0, SYS_lxstat;
- syscall;
- bne a3, zero, 1b;
- nop;
- j ra;
- nop;
- .end machdep_sys_lstat
-
-/* ==========================================================================
- * fstat
- */
- PICOPT;
- .globl machdep_sys_fstat;
- .ent machdep_sys_fstat, 0;
-machdep_sys_fstat:;
- .frame sp,0,ra;
- .set noreorder;
- move a2, a1
- move a1, a0
- li a0, 2
- li v0, SYS_fxstat;
- syscall;
- bne a3, zero, 1b;
- nop;
- j ra;
- nop;
- .end machdep_sys_fstat
-
-/* ==========================================================================
- * stat
- */
- PICOPT;
- .globl machdep_sys_stat;
- .ent machdep_sys_stat, 0;
-machdep_sys_stat:;
- .frame sp,0,ra;
- .set noreorder;
- move a2, a1
- move a1, a0
- li a0, 2
- li v0, SYS_xstat;
- syscall;
- bne a3, zero, 1b;
- nop;
- j ra;
- nop;
- .end machdep_sys_stat
diff --git a/mit-pthreads/machdep/syscall-m68000-netbsd.S b/mit-pthreads/machdep/syscall-m68000-netbsd.S
deleted file mode 100644
index f36286770a2..00000000000
--- a/mit-pthreads/machdep/syscall-m68000-netbsd.S
+++ /dev/null
@@ -1,83 +0,0 @@
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-#define IMM #
-#define SYSCALL(x) .even; ENTRY(machdep_sys_ ## x); \
- movl IMM SYS_ ## x,d0; trap IMM 0; jcs err; rts
-#else /* !__STDC__ */
-#define SYSCALL(x) .even; ENTRY(machdep_sys_/**/x); \
- movl #SYS_/**/x,d0; trap #0; jcs err; rts
-#endif /* !__STDC__ */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .even
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-err:
- negl d0
- rts
-
-/* ==========================================================================
- * machdep_sys_pipe
- */
- .even
-ENTRY(machdep_sys_pipe);
- movl #SYS_pipe,d0
- trap #0
- jcs err
- movl sp@(4),a0
- movl d0,a0@+
- movl d1,a0@
- clrl d0
- rts
-
-#ifndef SYS___sigsuspend14
- .even
-ENTRY(machdep_sys_sigsuspend)
- movl sp@(4),a0
- movl a0@,sp@(4)
- movl #SYS_compat_13_sigsuspend13,d0
- trap #0
- jcs err
- clrl d0
- rts
-#endif
-
-#ifndef SYS___sigprocmask14
- .even
-ENTRY(machdep_sys_sigprocmask)
- tstl sp@(8)
- jne gotptr
-/* movl #0,sp@(8) /* null mask pointer; block empty set */
- movl #1,sp@(4)
- jra doit
-gotptr:
- movl sp@(8),a0
- movl a0@,sp@(8)
-doit:
- movl #SYS_compat_13_sigprocmask13,d0
- trap #0
- jcs err
- tstl sp@(12)
- jeq out
- movl sp@(12),a0
- movl d0,a0@
-out:
- clrl d0
- rts
-#endif
diff --git a/mit-pthreads/machdep/syscall-powerpc-netbsd.S b/mit-pthreads/machdep/syscall-powerpc-netbsd.S
deleted file mode 100644
index bdda457f116..00000000000
--- a/mit-pthreads/machdep/syscall-powerpc-netbsd.S
+++ /dev/null
@@ -1,185 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-#ifndef __CONCAT
-#include <sys/cdefs.h>
-#endif
-#define CONCAT __CONCAT
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- 0 - system call number
- 3-8 - arguments, as in C
- Output:
- so - (summary overflow) clear iff successful
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-ENTRY(machdep_cerror)
- mflr 0 # Save LR in 0
- stwu 1,-16(1) # allocate new stack frame
- stw 0,20(1) # Stash 0 in stack
- stw 31,8(1) # Stash 31 in stack (since it's callee-saved
- mr 31,3 # and we stash return there)
- bl PIC_PLT(_C_LABEL(__errno))
- stw 31,0(3) # *errno() = err
- lwz 0,20(1) # Restore LR from stack to 0
- neg 3,31 # return -errno to 3
- lwz 31,8(1) # Restore 31 from stack
- mtlr 0
- la 1,16(1) # Restore stack frame
- li 4,-1 # Put -1 in r4 for those syscalls that return
- blr # two values
-
-/* The fork system call is special... */
-ENTRY(machdep_sys_fork)
- li 0, SYS_fork
- sc
- bso PIC_PLT(_C_LABEL(machdep_cerror))
- addi 4,4,-1
- blr
-
-/* The pipe system call is special... */
-ENTRY(machdep_sys_pipe)
- mr 5,3
- li 0,SYS_pipe
- sc
- bso PIC_PLT(_C_LABEL(machdep_cerror))
- stw 3,0(5) # Success, store fds
- stw 4,4(5)
- li 3,0
- blr # And return 0
-
-#ifndef SYS___sigsuspend14
-/* The sigsuspend system call is special... */
-ENTRY(machdep_sys_sigsuspend)
- lwz 3,0(3)
- li 0,SYS_compat_13_sigsuspend13
- sc
- b PIC_PLT(_C_LABEL(machdep_cerror))
-#endif /* SYS_sigsuspend14 */
-
-#ifndef SYS___sigprocmask14
-/* The sigprocmask system call is special... */
-ENTRY(machdep_sys_sigprocmask)
- or. 4,4,4 # Set == NULL ?
- li 6,1 # how = SIG_BLOCK
- beq Ldoit
- lwz 4,0(4) # if not, replace it in r4 with #set
- mr 6,3
-Ldoit: mr 3,6 # ... using sigprocmask(SIG_BLOCK)
- li 0,SYS_compat_13_sigprocmask13
- sc
- bso PIC_PLT(_C_LABEL(machdep_cerror))
- or. 5,5,5 # Check to see if oset requested
- beq Ldone # if oset != NULL
- stw 3,0(5) # *oset = oldmask
-Ldone:
- li 3,0 # return 0
- blr
-#endif /* SYS_sigprocmask14 */
-
-/* More stuff ... */
-
-/* For fstat() we actually syscall fstat13. */
-ENTRY(machdep_sys_fstat)
- li 0, SYS___fstat13
- sc
- bnslr
- b PIC_PLT(_C_LABEL(machdep_cerror))
-
-/* Do we need to save the entire floating point state? I think so... */
-ENTRY(__machdep_save_fp_state)
- stwu 1,-8(1)
- stw 3,4(1)
- stfd 0,0(3)
- stfdu 1,8(3)
- stfdu 2,8(3)
- stfdu 3,8(3)
- stfdu 4,8(3)
- stfdu 5,8(3)
- stfdu 6,8(3)
- stfdu 7,8(3)
- stfdu 8,8(3)
- stfdu 9,8(3)
- stfdu 10,8(3)
- stfdu 11,8(3)
- stfdu 12,8(3)
- stfdu 13,8(3)
- stfdu 14,8(3)
- stfdu 15,8(3)
- stfdu 16,8(3)
- stfdu 17,8(3)
- stfdu 18,8(3)
- stfdu 19,8(3)
- stfdu 20,8(3)
- stfdu 21,8(3)
- stfdu 22,8(3)
- stfdu 23,8(3)
- stfdu 24,8(3)
- stfdu 25,8(3)
- stfdu 26,8(3)
- stfdu 27,8(3)
- stfdu 28,8(3)
- stfdu 29,8(3)
- stfdu 30,8(3)
- stfdu 31,8(3)
- mffs 0
- stfdu 0,8(3)
- lwz 3,4(1)
- lwz 1,0(1)
- blr
-
-ENTRY(__machdep_restore_fp_state)
- stwu 1,-12(1)
- stw 3,4(1)
- stw 4,8(1)
- mr 4,3
- lfdu 1,8(3)
- lfdu 2,8(3)
- lfdu 3,8(3)
- lfdu 4,8(3)
- lfdu 5,8(3)
- lfdu 6,8(3)
- lfdu 7,8(3)
- lfdu 8,8(3)
- lfdu 9,8(3)
- lfdu 10,8(3)
- lfdu 11,8(3)
- lfdu 12,8(3)
- lfdu 13,8(3)
- lfdu 14,8(3)
- lfdu 15,8(3)
- lfdu 16,8(3)
- lfdu 17,8(3)
- lfdu 18,8(3)
- lfdu 19,8(3)
- lfdu 20,8(3)
- lfdu 21,8(3)
- lfdu 22,8(3)
- lfdu 23,8(3)
- lfdu 24,8(3)
- lfdu 25,8(3)
- lfdu 26,8(3)
- lfdu 27,8(3)
- lfdu 28,8(3)
- lfdu 29,8(3)
- lfdu 30,8(3)
- lfdu 31,8(3)
- lfdu 0,8(3)
- mtfsf 127,0
- lfd 0,0(4)
- lwz 3,4(1)
- lwz 4,8(1)
- lwz 1,0(1)
- blr
diff --git a/mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S b/mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S
deleted file mode 100644
index dc891dc37bd..00000000000
--- a/mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S
+++ /dev/null
@@ -1,166 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for decstation with r2000/r3000
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- */
-
- .text
- .ascii "$Id$";
-
-#include <syscall.h>
-#include <machine/regdef.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value. Eventually I want to load the errno value directly
- * into pthread_run->error but until then ...
- */
-machdep_error:
- negu v0, v0 /* Return negative of errno value. */
- j ra
-
-/* ==========================================================================
- * Syscalls already done,
- * Standard Other important BSD sockets
- * fork = 2 select = 93 socket = 97
- * read = 3 readv = 120 connect = 98
- * write = 4 writev = 121 accept = 99
- * open = 5 getdirentries = send = 101
- * close = 6 recv = 102
- * creat = 8 bind = 104
- * link = 9 listen = 106
- * unlink = 10 recvmsg = 113
- * chdir = 12 sendmsg = 114
- * chmod = 15 getsockopt = 118
- * chown = 16 recvfrom = 125
- * lseek = 19 sendto = 133
- * stat = 38 shutdown = 134
- * dup = 41 getpeername = 141
- * pipe = 42
- * execve = 59
- * fstat = 62
- * wait3 = 84
- * dup2 = 90
- * fcntl = 92
- * fchown = 123
- * fchmod = 124
- * rename = 128
- * waitpid = 189
- * ======================================================================= */
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl machdep_sys_fork
- .ent machdep_sys_fork
-
-machdep_sys_fork:
-
- .frame sp,0,ra /* No frame, return address in ra */
-
- li v0,SYS_fork /* Load fork syscall # into v0 */
- syscall
- bne a3,zero,machdep_error /* Error if a3 != 0 */
- beqz v1,__fork_parent /* Second return value = 0, if parent */
- li v0,0
-__fork_parent:
- j ra
-
- .end machdep_sys_fork
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl machdep_sys_pipe
- .ent machdep_sys_pipe
-
-machdep_sys_pipe:
-
- .frame sp,0,ra /* No frame, return address in ra */
-
- li v0,SYS_pipe /* Load pipe syscall # into v0 */
- syscall
- bne a3,zero,machdep_error /* Error if a3 != 0 */
- sw v0, 0(a0)
- sw v1, 4(a0)
- li v0, 0
- j ra
-
- .end machdep_sys_pipe
-
-/* ==========================================================================
- * Other important asm routines.
- * ======================================================================= */
-/* ==========================================================================
- * fake_setjmp()
- */
- .globl fake_setjmp
- .ent fake_setjmp
-
-fake_setjmp:
-
- .frame sp,0,ra /* No frame, return address in ra */
-
- /* Save all the important registers */
- sw ra,8(a0)
- sw gp,124(a0)
- sw sp,128(a0)
- sw s0,76(a0)
- /* More registers needed. */
- j ra
-
- .end fake_longjmp
-
-/* ==========================================================================
- * machdep_sys_longjmp()
- */
- .globl machdep_sys_longjmp
- .ent machdep_sys_longjmp
-
-machdep_sys_longjmp:
-
- .frame sp,0,ra /* No frame, return address in ra */
- li a1,1 /* Load 1 into reg a1 */
- sw a1, 20(a0); /* Load a1 into address a0 + 20 */
- li v0,SYS_sigreturn /* Load sigreturn syscall # into v0 */
- syscall /* Do syscall to do longjmp */
- j ra
-
- .end machdep_sys_longjmp
diff --git a/mit-pthreads/machdep/syscall-romp-bsd.S b/mit-pthreads/machdep/syscall-romp-bsd.S
deleted file mode 100644
index 233f0b9430b..00000000000
--- a/mit-pthreads/machdep/syscall-romp-bsd.S
+++ /dev/null
@@ -1,327 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1993 by John F. Carr, jfc@mit.edu
- *
- * 1.00 93/09/xx proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-/* DO NOT USE COLONS IN THIS FILE, GCC CAN'T HANDLE THEM */
-/* #include <copyright.h> */
-
- .globl .oVncs
- .text
- .align 2
-
-/* ==========================================================================
- * machdep_sys_write()
- */
- .globl _machdep_sys_write
- .globl _.machdep_sys_write
-
- .text 2
-_machdep_sys_write:
- .long _.machdep_sys_write
-
- .text
-_.machdep_sys_write:
- lcs r0,0(r3)
- svc 4(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_read()
- */
- .globl _machdep_sys_read
- .globl _.machdep_sys_read
-
- .text 2
-_machdep_sys_read:
- .long _.machdep_sys_read
-
- .text
-_.machdep_sys_read:
- lcs r0,0(r3)
- svc 3(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_open()
- */
- .globl _machdep_sys_open
- .globl _.machdep_sys_open
-
- .text 2
-_machdep_sys_open:
- .long _.machdep_sys_open
-
- .text
-_.machdep_sys_open:
- lcs r0,0(r2)
- svc 5(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
- .globl _machdep_sys_bind
- .globl _.machdep_sys_bind
-
- .text 2
-_machdep_sys_bind:
- .long _.machdep_sys_bind
-
- .text
-_.machdep_sys_bind:
- ls r0,0(r3)
- svc 104(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_socket()
- */
- .globl _machdep_sys_socket
- .globl _.machdep_sys_socket
-
- .text 2
-_machdep_sys_socket:
- .long _.machdep_sys_socket
-
- .text
- .align 2
-_.machdep_sys_socket:
- svc 97(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_close()
- */
- .globl _machdep_sys_close
- .globl _.machdep_sys_close
-
- .text 2
-_machdep_sys_close:
- .long _.machdep_sys_close
-
- .text
- .align 2
-_.machdep_sys_close:
- svc 6(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
- .globl _machdep_sys_connect
- .globl _.machdep_sys_connect
-
- .text 2
-_machdep_sys_connect:
- .long _.machdep_sys_connect
-
- .text
-_.machdep_sys_connect:
- lcs r0,0(r3)
- svc 98(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
- .globl _machdep_sys_accept
- .globl _.machdep_sys_accept
-
- .text 2
-_machdep_sys_accept:
- .long _.machdep_sys_accept
-
- .text
-_.machdep_sys_accept:
- lcs r0,0(r3)
- svc 99(r0)
- bntbr r15
- store r2,_errno,r5
- cal r2,-1(r0)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
- .globl _machdep_sys_listen
- .globl _.machdep_sys_listen
-
- .text 2
- .align 2
-_machdep_sys_listen:
- .long _.machdep_sys_listen
-
- .text
- .align 2
-_.machdep_sys_listen:
- svc 106(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
- .globl _.machdep_sys_fcntl
- .globl _machdep_sys_fcntl
-
- .text 2
-_machdep_sys_fcntl:
- .long _.machdep_sys_fcntl
- .text
-_.machdep_sys_fcntl:
- lcs r0,0(sp)
- svc 92(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
- .globl _machdep_sys_getpeername
- .globl _.machdep_sys_getpeername
-
- .text 2
-_machdep_sys_getpeername:
- .long _.machdep_sys_getpeername
-
- .text
-_.machdep_sys_getpeername:
- ls r0,0(sp)
- svc 141(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
- .globl _machdep_sys_getsockopt
- .globl _.machdep_sys_getsockopt
-
- .text 2
-_machdep_sys_getsockopt:
- .long _.machdep_sys_getsockopt
-
- .text
-_.machdep_sys_getsockopt:
- ls r0,0(sp)
- svc 118(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-
-/* ==========================================================================
- * machdep_sys_select()
- */
-
- .globl _.machdep_sys_select
- .globl _machdep_sys_select
-
- .text 2
-_machdep_sys_select:
- .long _.machdep_sys_select
- .text
-_.machdep_sys_select:
- svc 93(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-/* ==========================================================================
- * __tsh()
- */
- .globl _._tsh
- .globl __tsh
- .text 2
-__tsh: .long _._tsh
- .text
- .align 2
-_._tsh:
- brx r15
- tsh r2,0(r2)
-
-
-/* ==========================================================================
- * __pthread_save()
- */
- .globl __pthread_save
- .globl _._pthread_save
- .text 2
-__pthread_save:
- .long _._pthread_save
- .text
- .align 2
-_._pthread_save:
- ail r5,r4,0
- jne 1f
- mr r4,sp
- lis r5,0
- stm r4,0(r2)
- brx r15
- lis r2,0
-1:
- mr r0,r15 # save old return address
- ls r15,0(r4) # new return address
- mr r5,r4 # r0 to restore
- mr r4,r3 # sp to restore
- stm r4,0(r2)
- brx r0
- lis r2,0
-
-
-/* ==========================================================================
- * __pthread_restore()
- */
- .globl __pthread_restore
- .globl _._pthread_restore
- .text 2
-__pthread_restore:
- .long _._pthread_restore
- .text
- .align 2
-_._pthread_restore:
- lm r4,0(r2)
- mr r0,r5
- lis r2,1
- brx r15
- mr sp,r4
-
-
diff --git a/mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S b/mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S
deleted file mode 100644
index 9c4da4b1325..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe
-
-_machdep_sys_pipe:
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- dec %o1;
- retl;
- and %o0, %o1, %o0; ! return 0 in child, pid in parent
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _machdep_sys_sigprocmask;
-
-_machdep_sys_sigprocmask:;
-
- ld [%o1], %o1;
- mov SYS_sigprocmask, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- ld [%o0], %o0;
- mov SYS_sigsuspend, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
diff --git a/mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S b/mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S
deleted file mode 100644
index 74a51e756b7..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S
+++ /dev/null
@@ -1,172 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _C_LABEL(machdep_sys_pipe)
-
-_C_LABEL(machdep_sys_pipe):
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _C_LABEL(machdep_sys_fork);
-
-_C_LABEL(machdep_sys_fork):;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- dec %o1;
- retl;
- and %o0, %o1, %o0; ! return 0 in child, pid in parent
-
-#ifndef SYS___sigprocmask14
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _C_LABEL(machdep_sys_sigprocmask);
-
-_C_LABEL(machdep_sys_sigprocmask):;
-
- ld [%o1], %o1;
- mov SYS_sigprocmask, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-#endif
-
-#ifndef SYS___sigsuspend14
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _C_LABEL(machdep_sys_sigsuspend);
-
-_C_LABEL(machdep_sys_sigsuspend):;
-
- ld [%o0], %o0;
- mov SYS_sigsuspend, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-#endif
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
- .globl _C_LABEL(machdep_sys_fstat);
-
-_C_LABEL(machdep_sys_fstat):;
-
- mov SYS___fstat13, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-_machdep_sys___syscall:;
-
- mov SYS___syscall, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .global _C_LABEL(machdep_sys_lseek)
-
-_C_LABEL(machdep_sys_lseek):
- save %sp,-112,%sp
- mov %i1,%o4
- mov %i2,%o5
- st %i3,[%sp+92]
- mov 0,%o0
- mov SYS_lseek,%o1
- mov %i0,%o2
- call _machdep_sys___syscall,0
- mov 0,%o3
- mov %o0,%i0
- mov %o1,%i1
- ret
- restore
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
- .global _C_LABEL(machdep_sys_ftruncate)
-
-_C_LABEL(machdep_sys_ftruncate):
- save %sp,-104,%sp
- mov %i1,%o4
- mov %i2,%o5
- mov 0,%o0
- mov SYS_ftruncate,%o1
- mov %i0,%o2
- call _machdep_sys___syscall,0
- mov 0,%o3
- mov %o0,%o1
- sra %o0,31,%o0
- ret
- restore %g0,%o1,%o0
diff --git a/mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S b/mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S
deleted file mode 100644
index ec293b0ca3f..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe
-
-_machdep_sys_pipe:
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- tst %o1
- bne,a __fork_parent
- mov %g0, %o0
-__fork_parent:;
- retl
-
-/* POSIX-compliant getpgrp() takes no arguments. The SunOS syscall wants
- one, and gives the POSIXy result if that argument is zero. */
- .globl _getpgrp
-_getpgrp:
- mov SYS_getpgrp, %g1
- mov 0, %i0
- ta 0
- bcs 1b
- nop
- retl
- nop
-
-#if 0
-/* I think this bit of magic will do the right thing for other syscalls.
- We get here with the new `errno' code in %o0. It should get stored in
- *__error(), and -1 returned to the caller. */
- .globl cerror
-cerror:
- save %sp,-104,%sp
- /* Now value is in %i0. Store it in *__error(). */
- call ___error
- nop
- st %i0,[%o0]
-
- /* Now also store a copy in global variable errno, for routines
- like isatty that want to examine it and which haven't been
- converted yet. */
- sethi %hi(_errno), %o0
- st %i0,[%o0+%lo(_errno)]
-
-#if 0 /* use this if you want -errno returned */
- sub %r0,%i0,%i0
-#else /* return -1 */
- mov -1,%i0
-#endif
- retl
- restore
-#endif
diff --git a/mit-pthreads/machdep/syscall-sparc-sunos-5.3.S b/mit-pthreads/machdep/syscall-sparc-sunos-5.3.S
deleted file mode 100644
index 822055ad04e..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-sunos-5.3.S
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#define _ASM
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl machdep_sys_fork;
-
-machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- tst %o1
- bne,a __fork_parent
- mov %g0, %o0
-__fork_parent:;
- retl
- nop; /* Added by monty to keep sparc assembler happy */
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socketcall()
- */
- .globl machdep_sys_socketcall;
-
-machdep_sys_socketcall:;
-
- mov 83, %g1;
- ta 0;
- bcs,a 2b;
- sub %r0,%o0,%o0;
- retl
- nop; /* Added by monty to keep sparc assembler happy */
diff --git a/mit-pthreads/machdep/syscall-sparc-sunos4.S b/mit-pthreads/machdep/syscall-sparc-sunos4.S
deleted file mode 100644
index ec293b0ca3f..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-sunos4.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe
-
-_machdep_sys_pipe:
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- tst %o1
- bne,a __fork_parent
- mov %g0, %o0
-__fork_parent:;
- retl
-
-/* POSIX-compliant getpgrp() takes no arguments. The SunOS syscall wants
- one, and gives the POSIXy result if that argument is zero. */
- .globl _getpgrp
-_getpgrp:
- mov SYS_getpgrp, %g1
- mov 0, %i0
- ta 0
- bcs 1b
- nop
- retl
- nop
-
-#if 0
-/* I think this bit of magic will do the right thing for other syscalls.
- We get here with the new `errno' code in %o0. It should get stored in
- *__error(), and -1 returned to the caller. */
- .globl cerror
-cerror:
- save %sp,-104,%sp
- /* Now value is in %i0. Store it in *__error(). */
- call ___error
- nop
- st %i0,[%o0]
-
- /* Now also store a copy in global variable errno, for routines
- like isatty that want to examine it and which haven't been
- converted yet. */
- sethi %hi(_errno), %o0
- st %i0,[%o0+%lo(_errno)]
-
-#if 0 /* use this if you want -errno returned */
- sub %r0,%i0,%i0
-#else /* return -1 */
- mov -1,%i0
-#endif
- retl
- restore
-#endif
diff --git a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S b/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S
deleted file mode 100644
index a2941ece7c9..00000000000
--- a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-#define CHMK() call_pal 0x83
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, Lsys_noerr_##x ;\
- br gp, Lsys_err_##x ;\
-Lsys_err_##x: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-Lsys_noerr_##x:
-
-#define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-#define XSYSCALL(x) SIMPLE_SYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S
deleted file mode 100644
index 12595feabc1..00000000000
--- a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-#define CHMK() call_pal 0x83
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, Lsys_noerr_##x ;\
- br gp, Lsys_err_##x ;\
-Lsys_err_##x: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-Lsys_noerr_##x:
-
-#define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-#define XSYSCALL(x) SIMPLE_SYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-alpha-osf1.S b/mit-pthreads/machdep/syscall-template-alpha-osf1.S
deleted file mode 100644
index bc4653b5f9e..00000000000
--- a/mit-pthreads/machdep/syscall-template-alpha-osf1.S
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <asm.h>
-#include <regdef.h>
-#define COMPAT_43
-#include <syscall.h>
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, 2f ;\
- br gp, 1f ;\
-1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-2:
-
-#define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-#define XSYSCALL(x) SIMPLE_SYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S
deleted file mode 100644
index 923d2c03a75..00000000000
--- a/mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- swi SYS_##x; \
- bcs 1b; \
- mov r15, r14;
-
-#else
-
-#define SYSCALL(x) \
- .globl _C_LABEL(_machdep_sys_/**/x); \
- \
-_C_LABEL(machdep_sys_/**/x):; \
- \
- swi SYS_/**/x; \
- bcs 1b; \
- mov r15, r14;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 0
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- rsb r0, r0, #0x00000000
- mvn r1, #0x00000000
- mov r15, r14
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S b/mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S
deleted file mode 100644
index 0123b1deee7..00000000000
--- a/mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ==== syscall.S ============================================================
- * Written 1996 by Stefan Grefen, grefen@convex.com
- */
-
-#include <sys/syscall.h>
-
-#define _CAT(a,b)a##b
-#define CAT(a,b)_CAT(a,b)
-
-#define MKNAME(a)CAT(a,SYSCALL_NAME)
-
- .CODE
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
- .label MKNAME(machdep_sys_)
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi MKNAME(SYS_),%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- bv,n %r0(%r2)
- .PROCEND
- .EXPORT MKNAME(machdep_sys_)
diff --git a/mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S b/mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S
deleted file mode 100644
index 0123b1deee7..00000000000
--- a/mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ==== syscall.S ============================================================
- * Written 1996 by Stefan Grefen, grefen@convex.com
- */
-
-#include <sys/syscall.h>
-
-#define _CAT(a,b)a##b
-#define CAT(a,b)_CAT(a,b)
-
-#define MKNAME(a)CAT(a,SYSCALL_NAME)
-
- .CODE
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
- .label MKNAME(machdep_sys_)
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi MKNAME(SYS_),%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- bv,n %r0(%r2)
- .PROCEND
- .EXPORT MKNAME(machdep_sys_)
diff --git a/mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S b/mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S
deleted file mode 100644
index 3299f49195f..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x##; \
- \
-_machdep_sys_##x##:; \
- \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x/**/; \
- \
-_machdep_sys_/**/x/**/:; \
- \
- movl $(SYS_/**/x/**/), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S b/mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S
deleted file mode 100644
index 1906a949c8b..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYS(X) SYS_##X
-#ifdef __ELF__
-#define NAME(X) machdep_sys_##X
-#else
-#define NAME(X) _machdep_sys_##X
-#endif
-
-#else
-
-#define SYS(X) SYS_/**/X
-#ifdef __ELF__
-#define NAME(X) machdep_sys_/**/X
-#else
-#define NAME(X) _machdep_sys_/**/X
-#endif
-
-#endif
-
-#ifdef __ELF__
-#define END(X) 5: ; .type NAME(X),@function ; .size NAME(X),5b - NAME(X)
-#define KERNCALL int $0x80
-#else
-#define END(X)
-#define KERNCALL .byte 0x9a; .long 0; .word 7;
-#endif
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x):; \
- movl $(SYS(x)), %eax; \
- KERNCALL; \
- jb 1b; \
- ret; \
- END(x)
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S b/mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S
deleted file mode 100644
index c5e76bb4538..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- movl $(SYS_##x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S
deleted file mode 100644
index d6dffc35132..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- movl $(SYS_##x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#else
-
-#define _SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_/**/x); \
- \
-_C_LABEL(machdep_sys_/**/x):; \
- \
- movl $(SYS_/**/x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S b/mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S
deleted file mode 100644
index 83a2405ed51..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- movl $(SYS_##x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S b/mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S
deleted file mode 100644
index 34fb5caaa43..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x##; \
- \
-_machdep_sys_##x:##; \
- \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S b/mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S
deleted file mode 100644
index 753475b5c3d..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <sys/errno.h>
-#include <sys/syscall.h>
-
-#ifdef _SCO_ELF
-
-#define NAME(X) machdep_sys_##X
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-#define GETBX(X) \
- push %ebx; \
- call 1f; \
-1: \
- popl %ebx;
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x):; \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jae 1f; \
- cmp $(ERESTART), %eax; \
- je NAME(x); \
- neg %eax; \
-1: \
- ret; \
- END(x)
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jae 1f; \
- neg %eax;
-1: \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S b/mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S
deleted file mode 100644
index 722b001671b..00000000000
--- a/mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <sys.s>
-#include <sys/regdef.h>
-/* #include <sys/asm.h> */
-
-/*
- Kernel syscall interface:
- Input:
- v0 syscall number
- Output:
-
- This macro is similar to SYSCALL in sys/syscall.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- Compile with -DPIC for pic code.
-*/
-
-#ifdef PIC
-#define PICOPT .option pic2
-#else
-#define PICOPT
-#endif
-
-
-#define YSYSCALL(x) \
- PICOPT; \
- .globl machdep_sys_##x; \
- .ent machdep_sys_##x, 0; \
-machdep_sys_##x:; \
- .frame sp,0,ra; \
- .set noreorder; \
- li v0, SYS_##x; \
- syscall; \
- bne a3, zero, 1b; \
- nop; \
- j ra; \
- nop; \
- .end machdep_sys_##x
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- subu v0,zero,v0;
- j ra;
-
-#define XSYSCALL(x) YSYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-m68000-netbsd.S b/mit-pthreads/machdep/syscall-template-m68000-netbsd.S
deleted file mode 100644
index ce16bb5523c..00000000000
--- a/mit-pthreads/machdep/syscall-template-m68000-netbsd.S
+++ /dev/null
@@ -1,43 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-
-#ifdef __STDC__
-#define IMM #
-#define SYSCALL(x) .even; \
- ENTRY(machdep_sys_ ## x); \
- movl IMM SYS_ ## x,d0; \
- trap IMM 0; \
- jcs err; \
- rts
-#else /* !__STDC__ */
-#define SYSCALL(x) .even; ENTRY(machdep_sys_/**/x); \
- movl #SYS_/**/x,d0; trap #0; jcs err; rts
-#endif /* !__STDC__ */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .even
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-err:
- negl d0
- rts
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-powerpc-netbsd.S b/mit-pthreads/machdep/syscall-template-powerpc-netbsd.S
deleted file mode 100644
index 1755c1ab2e8..00000000000
--- a/mit-pthreads/machdep/syscall-template-powerpc-netbsd.S
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-
-#ifdef SYS___sigaction14
-#define SYS_sigaction SYS___sigaction14
-#endif
-
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- 0 - system call number
- 3-8 - arguments, as in C
- Output:
- so - (summary overflow) clear iff successful
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- ENTRY(machdep_sys_ ## x) \
- li 0, SYS_ ## x ; \
- sc ; \
- bnslr ; \
- b PIC_PLT(_C_LABEL(machdep_cerror))
-
-#define XSYSCALL(x) SYSCALL(x) ; blr
-
- XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S b/mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S
deleted file mode 100644
index 575fe3c3d74..00000000000
--- a/mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for decstation with r2000/r3000
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- */
-
- .text
- .ascii "$Id$";
-
-#include <syscall.h>
-#include <machine/regdef.h>
-
-#define SYSCALL(x) \
- \
- .globl machdep_sys_##x; \
- .ent machdep_sys_##x; \
- \
-machdep_sys_##x:; \
- \
- .frame sp,0,ra; /* No frame, return address in ra */ \
- \
- li v0,SYS_##x; /* Load syscall # into v0 */ \
- syscall; \
- bne a3,zero,machdep_error; /* Error if a3 != 0 */ \
- j ra; \
- \
- .end machdep_sys_##x
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value. Eventually I want to load the errno value directly
- * into pthread_run->error but until then ...
- */
-machdep_error:
- negu v0, v0 /* Return negative of errno value. */
- j ra
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S b/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S
deleted file mode 100644
index 2d07892a315..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl; \
- nop
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S
deleted file mode 100644
index 2caad5c3437..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl; \
- nop
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S b/mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S
deleted file mode 100644
index 65a796a057d..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#define _ASM
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define concat2(a,b) a ## b
-#define concat(a,b) concat2(a,b)
-#define SYSval concat(SYS_,SYSCALL_NAME)
-#define procname concat(machdep_sys_,SYSCALL_NAME)
-
- .globl procname
-
-procname:
- mov SYSval, %g1
- ta 0
- bcs,a 2b
- sub %r0,%o0,%o0
- retl
- nop
diff --git a/mit-pthreads/machdep/syscall-template-sparc-sunos4.S b/mit-pthreads/machdep/syscall-template-sparc-sunos4.S
deleted file mode 100644
index 2d07892a315..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-sunos4.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl; \
- nop
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/ultrix-4.2/__math.h b/mit-pthreads/machdep/ultrix-4.2/__math.h
deleted file mode 100755
index 6249d720039..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__math.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#define HUGE_VAL 1.8e+308
-
diff --git a/mit-pthreads/machdep/ultrix-4.2/__signal.h b/mit-pthreads/machdep/ultrix-4.2/__signal.h
deleted file mode 100755
index 68364772a6a..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__signal.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <ansi_compat.h>
-
-#define NSIG 32
-
-#define SIGHUP 1 /* hangup */
-#define SIGINT 2 /* interrupt */
-#define SIGQUIT 3 /* quit */
-#define SIGILL 4 /* illegal instruction (not reset when caught) */
-#define SIGTRAP 5 /* trace trap (not reset when caught) */
-#define SIGIOT 6 /* IOT instruction */
-#define SIGEMT 7 /* EMT instruction */
-#define SIGFPE 8 /* floating point exception */
-#define SIGKILL 9 /* kill (cannot be caught or ignored) */
-#define SIGBUS 10 /* bus error */
-#define SIGSEGV 11 /* segmentation violation */
-#define SIGSYS 12 /* bad argument to system call */
-#define SIGPIPE 13 /* write on a pipe with no one to read it */
-#define SIGALRM 14 /* alarm clock */
-#define SIGTERM 15 /* software termination signal from kill */
-#define SIGURG 16 /* urgent condition on IO channel */
-#define SIGSTOP 17 /* sendable stop signal not from tty */
-#define SIGTSTP 18 /* stop signal from tty */
-#define SIGCONT 19 /* continue a stopped process */
-#define SIGCHLD 20 /* to parent on child stop or exit */
-#define SIGTTIN 21 /* to readers pgrp upon background tty read */
-#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
-#define SIGIO 23 /* input/output possible signal */
-#define SIGXCPU 24 /* exceeded CPU time limit */
-#define SIGXFSZ 25 /* exceeded file size limit */
-#define SIGVTALRM 26 /* virtual time alarm */
-#define SIGPROF 27 /* profiling time alarm */
-#define SIGWINCH 28 /* window size changes */
-#define SIGLOST 29 /* Sys-V rec lock: notify user upon server crash */
-#define SIGUSR1 30 /* User signal 1 (from SysV) */
-#define SIGUSR2 31 /* User signal 2 (from SysV) */
-
-/* Add System V signal definitions (DLB001) */
-#define SIGCLD SIGCHLD /* System V name for SIGCHLD */
-#define SIGABRT SIGIOT
-
-typedef long sig_atomic_t;
-typedef unsigned int sigset_t;
-
-struct sigaction {
- void (*sa_handler)(); /* signal handler */
- sigset_t sa_mask; /* signal mask to apply */
- int sa_flags; /* see signal options below */
-};
-
-/* Defines for sigprocmask() call. POSIX.
- */
-#define SIG_BLOCK 1 /* Add these signals to block mask */
-#define SIG_UNBLOCK 2 /* Remove these signals from block mask */
-#define SIG_SETMASK 3 /* Set block mask to this mask */
-
-#define SIG_ERR ((void (*)())(-1))
-#define SIG_DFL ((void (*)())( 0))
-#define SIG_IGN ((void (*)())( 1))
-
-
-#define __SIGFILLSET 0xffffffff
-#define __SIGEMPTYSET 0
-#define __SIGADDSET(s,n) ((*s) |= (1 << ((n) - 1)))
-#define __SIGDELSET(s,n) ((*s) &= ~(1 << ((n) - 1)))
-#define __SIGISMEMBER(s,n) ((*s) & (1 << ((n) - 1)))
-
diff --git a/mit-pthreads/machdep/ultrix-4.2/__stdio.h b/mit-pthreads/machdep/ultrix-4.2/__stdio.h
deleted file mode 100755
index 3f6aee47de3..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__stdio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#if ! defined(_SIZE_T_)
-#define _SIZE_T_
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/ultrix-4.2/__stdlib.h b/mit-pthreads/machdep/ultrix-4.2/__stdlib.h
deleted file mode 100755
index e2e52cc41c9..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__stdlib.h
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <ansi_compat.h>
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef unsigned int size_t;
-#endif
-
-#ifndef _WCHAR_T_
-#define _WCHAR_T_
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/__string.h b/mit-pthreads/machdep/ultrix-4.2/__string.h
deleted file mode 100755
index 03039b5cf73..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__string.h
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#if ! defined(_SIZE_T_)
-#define _SIZE_T_
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard Ultrix string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/ultrix-4.2/__time.h b/mit-pthreads/machdep/ultrix-4.2/__time.h
deleted file mode 100755
index dddc54430bc..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <ansi_compat.h>
-
-#ifndef _CLOCK_T_
-#define _CLOCK_T_
-typedef int clock_t;
-#endif
-
-#ifndef _TIME_T_
-#define _TIME_T_
-typedef int time_t;
-#endif
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef unsigned int size_t;
-#endif
-
-#define CLOCKS_PER_SEC 1000000
-
-#if !defined(_ANSI_SOURCE)
-#define CLK_TCK 60
-#endif /* not ANSI */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/ultrix-4.2/__unistd.h b/mit-pthreads/machdep/ultrix-4.2/__unistd.h
deleted file mode 100755
index f570242ef0d..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__unistd.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef _SSIZE_T_
-#define _SSIZE_T_
-typedef int ssize_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/cdefs.h b/mit-pthreads/machdep/ultrix-4.2/cdefs.h
deleted file mode 100755
index 4e1dc1c280d..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/cdefs.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __INLINE static
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#ifndef _SSIZE_T_
-#define _SSIZE_T_
-typedef int ssize_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/compat.h b/mit-pthreads/machdep/ultrix-4.2/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/dirent.h b/mit-pthreads/machdep/ultrix-4.2/dirent.h
deleted file mode 100755
index 5f17af345db..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/dirent.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/ultrix-4.2/errno.h b/mit-pthreads/machdep/ultrix-4.2/errno.h
deleted file mode 100755
index b47633a9456..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/errno.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)errno.h 7.13 (Berkeley) 2/19/91
- * errno.h,v 1.3 1993/05/20 16:22:09 cgd Exp
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EAGAIN 11 /* No more processes */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-/* 15 Non POSIX */
-/* 16 Non POSIX */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-/* 26 Non POSIX */
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-/* 35 Non POSIX */
-/* 36 Non POSIX */
-/* 37 Non POSIX */
-/* 38 Non POSIX */
-/* 39 Non POSIX */
-/* 40 Non POSIX */
-/* 41 Non POSIX */
-/* 42 Non POSIX */
-/* 43 Non POSIX */
-/* 44 Non POSIX */
-/* 45 Non POSIX */
-/* 46 Non POSIX */
-/* 47 Non POSIX */
-/* 48 Non POSIX */
-/* 49 Non POSIX */
-/* 50 Non POSIX */
-/* 51 Non POSIX */
-/* 52 Non POSIX */
-/* 53 Non POSIX */
-/* 54 Non POSIX */
-/* 55 Non POSIX */
-/* 56 Non POSIX */
-/* 57 Non POSIX */
-/* 58 Non POSIX */
-/* 59 Non POSIX */
-/* 60 Non POSIX */
-/* 61 Non POSIX */
-/* 62 Non POSIX */
-#define ENAMETOOLONG 63 /* File name too long */
-/* 64 Non POSIX */
-/* 65 Non POSIX */
-#define ENOTEMPTY 66 /* Directory not empty */
-/* 67 Non POSIX */
-/* 68 Non POSIX */
-/* 69 Non POSIX */
-/* 70 Non POSIX */
-/* 71 Non POSIX */
-/* 72 Non POSIX */
-/* 73 Non POSIX */
-/* 74 Non POSIX */
-#define ENOLCK 75 /* No locks available */
-#define ENOSYS 76 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#define EBUSY 16 /* Device busy */
-#define ETXTBSY 26 /* Text file busy */
-
-/* non-blocking and interrupt i/o */
-#define EWOULDBLOCK 35 /* Operation would block */
-#define EDEADLK EWOULDBLOCK /* Resource deadlock avoided */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported on socket */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Connection timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-
-/* quotas & mush */
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-
-/* IPC errors */
-#define ENOMSG 72 /* RPC struct is bad */
-#define EIDRM 73 /* RPC version wrong */
-
-/* Alignment error of some type (i.e., cluster, page, block ...) */
-#define EALIGN 74 /* RPC prog. not avail */
-#endif /* _POSIX_SOURCE */
-
-#endif /* _SYS_ERRNO_H_ */
diff --git a/mit-pthreads/machdep/ultrix-4.2/time.h b/mit-pthreads/machdep/ultrix-4.2/time.h
deleted file mode 100755
index 1dbb32b67a4..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/time.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-#include <time.h>
-#include <sys/cdefs.h>
-
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* microseconds */
-};
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* dst correction */
-};
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-/*
- * Functions
- */
-__BEGIN_DECLS
-
-int gettimeofday __P_((struct timeval *, struct timezone *));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/timers.h b/mit-pthreads/machdep/ultrix-4.2/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/wait.h b/mit-pthreads/machdep/ultrix-4.2/wait.h
deleted file mode 100755
index 8114f7e461d..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/wait.h
+++ /dev/null
@@ -1,121 +0,0 @@
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-#include <ansi_compat.h>
-#include <sys/cdefs.h>
-
-#if !defined(_POSIX_SOURCE)
-union wait {
-#else
-union __wait {
-#endif /* !defined(_POSIX_SOURCE) */
-#ifdef __vax
- int w_status; /* used in syscall */
-#endif /* __vax */
-#ifdef __mips__
- unsigned int w_status; /* used in syscall */
-#endif /* __mips */
- /*
- * Terminated process status.
- */
- struct {
-#ifdef __vax
- unsigned short w_Termsig:7; /* termination signal */
- unsigned short w_Coredump:1; /* core dump indicator */
- unsigned short w_Retcode:8; /* exit code if w_termsig==0 */
-#endif /* __vax */
-#ifdef __mips__
-#ifdef __MIPSEL__
- unsigned int w_Termsig:7; /* termination signal */
- unsigned int w_Coredump:1; /* core dump indicator */
- unsigned int w_Retcode:8; /* exit code if w_termsig==0 */
- unsigned int w_Filler:16; /* pad to word boundary */
-#endif /* __MIPSEL */
-#ifdef __MIPSEB__
- unsigned int w_Filler:16; /* pad to word boundary */
- unsigned int w_Retcode:8; /* exit code if w_termsig==0 */
- unsigned int w_Coredump:1; /* core dump indicator */
- unsigned int w_Termsig:7; /* termination signal */
-#endif /* __MIPSEB */
-#endif /* __mips */
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#ifdef __vax
- unsigned short w_Stopval:8; /* == W_STOPPED if stopped */
- unsigned short w_Stopsig:8; /* signal that stopped us */
-#endif /* __vax */
-#ifdef __mips__
-#ifdef __MIPSEL__
- unsigned int w_Stopval:8; /* == W_STOPPED if stopped */
- unsigned int w_Stopsig:8; /* signal that stopped us */
- unsigned int w_Filler:16; /* pad to word boundary */
-#endif /* __MIPSEL */
-#ifdef __MIPSEB__
- unsigned int w_Filler:16; /* pad to word boundary */
- unsigned int w_Stopsig:8; /* signal that stopped us */
- unsigned int w_Stopval:8; /* == W_STOPPED if stopped */
-#endif /* __MIPSEB */
-#endif /* __mips */
- } w_S;
-};
-
-#if !defined(_POSIX_SOURCE)
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-#define WSTOPPED 0177 /* value of s.stopval if process is stopped */
-#endif /* !defined(_POSIX_SOURCE) */
-
-#ifdef WSTOPPED
-#define _WSTOPPED WSTOPPED
-#else
-#define _WSTOPPED 0177
-#endif
-
-/*
- * Option bits for the second argument of wait3. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-/*
- * Must cast as union wait * because POSIX defines the input to these macros
- * as int.
- */
-
-#ifdef _POSIX_SOURCE
-#define WIFSTOPPED(x) (((union __wait *)&(x))->w_S.w_Stopval == _WSTOPPED)
-#define WIFSIGNALED(x) (((union __wait *)&(x))->w_S.w_Stopval != _WSTOPPED && ((union __wait *)&(x))->w_T.w_Termsig != 0)
-#define WIFEXITED(x) (((union __wait *)&(x))->w_S.w_Stopval != _WSTOPPED && ((union __wait *)&(x))->w_T.w_Termsig == 0)
-#define WEXITSTATUS(x) (((union __wait *)&(x))->w_T.w_Retcode)
-#define WTERMSIG(x) (((union __wait *)&(x))->w_T.w_Termsig)
-#define WSTOPSIG(x) (((union __wait *)&(x))->w_S.w_Stopsig)
-#endif /* _POSIX_SOURCE */
-
-#if !defined(_POSIX_SOURCE)
-#define WIFSTOPPED(x) (((union wait *)&(x))->w_stopval == WSTOPPED)
-#define WIFSIGNALED(x) (((union wait *)&(x))->w_stopval != WSTOPPED && ((union wait *)&(x))->w_termsig != 0)
-#define WIFEXITED(x) (((union wait *)&(x))->w_stopval != WSTOPPED && ((union wait *)&(x))->w_termsig == 0)
-#define WEXITSTATUS(x) (((union wait *)&(x))->w_retcode)
-#define WTERMSIG(x) (((union wait *)&(x))->w_termsig)
-#define WSTOPSIG(x) (((union wait *)&(x))->w_stopsig)
-#endif /* !defined(_POSIX_SOURCE) */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#endif /* _SYS_WAIT_H_ */
diff --git a/mit-pthreads/machdep/unistd-i386-freebsd-1.1.h b/mit-pthreads/machdep/unistd-i386-freebsd-1.1.h
deleted file mode 100644
index 033e70de5e5..00000000000
--- a/mit-pthreads/machdep/unistd-i386-freebsd-1.1.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#ifndef NULL
-#define NULL 0 /* null pointer constant */
-#endif
-
-typedef int ssize_t; /* count of bytes or error indication */
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-u_int alarm __P_((u_int));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-char *cuserid __P_((char *));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execve __P_((const char *, char * const *, char * const *));
-int execvp __P_((const char *, char * const *));
-pid_t fork __P_((void));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, int *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-u_int sleep __P_((u_int));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-#ifndef _POSIX_SOURCE
-
-/* structure timeval required for select() */
-#include <sys/time.h>
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-int chflags __P_((const char *, long));
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-int des_setkey __P_((const char *key));
-int encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-int fchflags __P_((int, long));
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, int));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((u_int, const char *));
-extern char *sys_siglist[];
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int select __P_((int, fd_set *, fd_set *, fd_set *, struct timeval *));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const int *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-int setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-u_int ualarm __P_((u_int, u_int));
-void usleep __P_((u_int));
-void *valloc __P_((size_t)); /* obsoleted by malloc() */
-int vfork __P_((void));
-
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/machdep/unistd-i386-linux-1.0.h b/mit-pthreads/machdep/unistd-i386-linux-1.0.h
deleted file mode 100644
index e7a3c5de1e4..00000000000
--- a/mit-pthreads/machdep/unistd-i386-linux-1.0.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-
-#include <posix_opt.h>
-#include <sys/types.h>
-#include <stddef.h>
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#include <pthread/unistd.h>
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/machdep/unistd-i386-linux-2.0.h b/mit-pthreads/machdep/unistd-i386-linux-2.0.h
deleted file mode 100644
index e7a3c5de1e4..00000000000
--- a/mit-pthreads/machdep/unistd-i386-linux-2.0.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-
-#include <posix_opt.h>
-#include <sys/types.h>
-#include <stddef.h>
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#include <pthread/unistd.h>
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h b/mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h
deleted file mode 100644
index 4d2161b628f..00000000000
--- a/mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)unistd.h 5.13 (Berkeley) 6/17/91
- * $Id$
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#define _NO_STDIO_SIZE_T
-
-#define _SC_ARG_MAX 1 /* space for argv & envp */
-#define _SC_CHILD_MAX 2 /* maximum children per process??? */
-#define _SC_CLK_TCK 3 /* clock ticks/sec */
-#define _SC_NGROUPS_MAX 4 /* number of groups if multple supp. */
-#define _SC_OPEN_MAX 5 /* max open files per process */
-#define _SC_JOB_CONTROL 6 /* do we have job control */
-#define _SC_SAVED_IDS 7 /* do we have saved uid/gids */
-#define _SC_VERSION 8 /* POSIX version supported */
-
-#define _POSIX_JOB_CONTROL 1
-#define _POSIX_SAVED_IDS 1
-#define _POSIX_VERSION 198808
-
-#define _PC_LINK_MAX 1 /* max links to file/dir */
-#define _PC_MAX_CANON 2 /* max line length */
-#define _PC_MAX_INPUT 3 /* max "packet" to a tty device */
-#define _PC_NAME_MAX 4 /* max pathname component length */
-#define _PC_PATH_MAX 5 /* max pathname length */
-#define _PC_PIPE_BUF 6 /* size of a pipe */
-#define _PC_CHOWN_RESTRICTED 7 /* can we give away files */
-#define _PC_NO_TRUNC 8 /* trunc or error on >NAME_MAX */
-#define _PC_VDISABLE 9 /* best char to shut off tty c_cc */
-#define _PC_LAST 9 /* highest value of any _PC_* */
-
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#ifndef NULL
-#define NULL 0 /* null pointer constant */
-#endif
-
-typedef int ssize_t;
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-unsigned alarm __P_((unsigned));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-size_t confstr __P_((int, char *, size_t));
-char *cuserid __P_((char *));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execve __P_((const char *, char * const *, char * const *));
-int execvp __P_((const char *, char * const *));
-pid_t fork __P_((void));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, int *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-unsigned sleep __P_((unsigned));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-#ifndef _POSIX_SOURCE
-
-/* structure timeval required for select() */
-#include <sys/time.h>
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-int chflags __P_((const char *, long));
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-int des_setkey __P_((const char *key));
-int encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-int fchflags __P_((int, long));
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdomainname __P_((char *, int));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, int));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((u_int, const char *));
-extern const char *const sys_siglist[];
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int select __P_((int, fd_set *, fd_set *, fd_set *, struct timeval *));
-int setdomainname __P_((const char *, int));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const int *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-int setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-u_int ualarm __P_((u_int, u_int));
-void usleep __P_((u_int));
-void *valloc __P_((size_t)); /* obsoleted by malloc() */
-pid_t vfork __P_((void));
-
-int getopt __P_((int, char * const *, const char *));
-extern char *optarg; /* getopt(3) external variables */
-extern int opterr;
-extern int optind;
-extern int optopt;
-int getsubopt __P_((char **, char * const *, char **));
-extern char *suboptarg; /* getsubopt(3) external variable */
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/net/GNUmakefile.inc b/mit-pthreads/net/GNUmakefile.inc
deleted file mode 100644
index 6b89617f63b..00000000000
--- a/mit-pthreads/net/GNUmakefile.inc
+++ /dev/null
@@ -1,14 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-VPATH:= ${VPATH}:${srcdir}/net
-
-SRCS:= gethostbyaddr.c gethostbyname.c gethostent.c getnetbyaddr.c \
- getnetbyname.c getnetent.c getproto.c getprotoent.c getprotoname.c \
- getservbyname.c getservbyport.c getservent.c herror.c inet_addr.c \
- inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \
- net_internal.c proto_internal.c res_comp.c res_init.c res_internal.c \
- res_mkquery.c res_query.c res_querydomain.c res_search.c res_send.c \
- res_debug.c serv_internal.c $(SRCS)
-
diff --git a/mit-pthreads/net/Makefile.inc b/mit-pthreads/net/Makefile.inc
deleted file mode 100644
index 08be88c808f..00000000000
--- a/mit-pthreads/net/Makefile.inc
+++ /dev/null
@@ -1,13 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-.PATH: ${srcdir}/net
-
-SRCS+= gethostbyaddr.c gethostbyname.c gethostent.c getnetbyaddr.c \
- getnetbyname.c getnetent.c getproto.c getprotoent.c getprotoname.c \
- getservbyname.c getservbyport.c getservent.c herror.c inet_addr.c \
- inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \
- net_internal.c proto_internal.c res_comp.c res_init.c res_internal.c \
- res_mkquery.c res_query.c res_querydomain.c res_search.c res_send.c \
- serv_internal.c gethostname.c
diff --git a/mit-pthreads/net/gethostbyaddr.c b/mit-pthreads/net/gethostbyaddr.c
deleted file mode 100644
index f80e47ffd99..00000000000
--- a/mit-pthreads/net/gethostbyaddr.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gethostbyaddr.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include "res_internal.h"
-
-static struct hostent *file_find_addr(const char *addr, int len, int type,
- struct hostent *result, char *buf,
- int bufsize, int *errval);
-
-struct hostent *gethostbyaddr(const char *addr, int len, int type)
-{
- struct res_data *data = _res_init();
-
- if (!data)
- return NULL;
- if (!data->buf) {
- data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE);
- if (!data->buf) {
- errno = 0;
- data->errval = NO_RECOVERY;
- return NULL;
- }
- }
- return gethostbyaddr_r(addr, len, type, (struct hostent *) data->buf,
- data->buf + sizeof(struct hostent), HOST_BUFSIZE,
- &data->errval);
-}
-
-struct hostent *gethostbyaddr_r(const char *addr, int len, int type,
- struct hostent *result, char *buf, int bufsize,
- int *errval)
-{
- struct res_data *data;
- querybuf qbuf;
- char lookups[MAXDNSLUS], addrbuf[MAXDNAME], *abuf;
- struct hostent *hp;
- int n, i;
-
- /* Default failure condition is not a range error and not recoverable. */
- errno = 0;
- *errval = NO_RECOVERY;
-
- data = _res_init();
- if (!data)
- return NULL;
-
- if (type != AF_INET)
- return NULL;
- sprintf(addrbuf, "%u.%u.%u.%u.in-addr.arpa",
- (unsigned)addr[3] & 0xff, (unsigned)addr[2] & 0xff,
- (unsigned)addr[1] & 0xff, (unsigned)addr[0] & 0xff);
-
- memcpy(lookups, data->state.lookups, sizeof(lookups));
- if (*lookups == 0)
- strncpy(lookups, "bf", sizeof(lookups));
-
- hp = NULL;
- for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
- switch (lookups[i]) {
- case 'b':
-
- /* Allocate space for a one-item list of addresses. */
- abuf = SP(SP(buf, char *, 2), struct in_addr, 1);
- if (abuf > buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
-
- /* Perform and parse the query. */
- n = res_query(addrbuf, C_IN, T_PTR, (char *)&qbuf, sizeof(qbuf));
- if (n < 0)
- break;
- hp = _res_parse_answer(&qbuf, n, 1, result, abuf,
- bufsize - (abuf - buf), errval);
- if (hp == NULL)
- break;
-
- /* Fill in our own address list. */
- result->h_addrtype = type;
- result->h_length = len;
- result->h_addr_list = (char **) ALIGN(buf, char *);
- result->h_addr_list[0] = ALIGN(&result->h_addr_list[2],
- struct in_addr);
- result->h_addr_list[1] = NULL;
- break;
-
- case 'f':
- hp = file_find_addr(addr, len, type, result, buf, bufsize, errval);
- break;
- }
- }
-
- return hp;
-}
-
-static struct hostent *file_find_addr(const char *addr, int len, int type,
- struct hostent *result, char *buf,
- int bufsize, int *errval)
-{
- FILE *fp = NULL;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
- while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
- /* Check the entry against the given address. */
- if (result->h_addrtype == type &&
- memcmp(result->h_addr, addr, len) == 0)
- break;
- }
- pthread_mutex_unlock(&host_iterate_lock);
- if (!result && errno != ERANGE)
- *errval = HOST_NOT_FOUND;
- return result;
-}
-
diff --git a/mit-pthreads/net/gethostbyname.c b/mit-pthreads/net/gethostbyname.c
deleted file mode 100644
index aaaaf79b31b..00000000000
--- a/mit-pthreads/net/gethostbyname.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gethostbyname.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <resolv.h>
-#include "res_internal.h"
-
-static struct hostent *fake_hostent(const char *hostname, struct in_addr addr,
- struct hostent *result, char *buf,
- int bufsize, int *errval);
-static struct hostent *file_find_name(const char *name, struct hostent *result,
- char *buf, int bufsize, int *errval);
-
-struct hostent *gethostbyname(const char *hostname)
-{
- struct res_data *data = _res_init();
-
- if (!data)
- return NULL;
- if (!data->buf) {
- data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE);
- if (!data->buf) {
- errno = 0;
- data->errval = NO_RECOVERY;
- return NULL;
- }
- }
- return gethostbyname_r(hostname, (struct hostent *) data->buf,
- data->buf + sizeof(struct hostent), HOST_BUFSIZE,
- &data->errval);
-}
-
-struct hostent *gethostbyname_r(const char *hostname, struct hostent *result,
- char *buf, int bufsize, int *errval)
-{
- struct in_addr addr;
- querybuf qbuf;
- const char *p;
- int n;
-
- /* Default failure condition is not a range error and not recoverable. */
- errno = 0;
- *errval = NO_RECOVERY;
-
- /* Check for all-numeric hostname with no trailing dot. */
- if (isdigit(hostname[0])) {
- p = hostname;
- while (*p && (isdigit(*p) || *p == '.'))
- p++;
- if (!*p && p[-1] != '.') {
- /* Looks like an IP address; convert it. */
- if (inet_aton(hostname, &addr) == -1) {
- *errval = HOST_NOT_FOUND;
- return NULL;
- }
- return fake_hostent(hostname, addr, result, buf, bufsize, errval);
- }
- }
-
- /* Do the search. */
- n = res_search(hostname, C_IN, T_A, qbuf.buf, sizeof(qbuf));
- if (n >= 0)
- return _res_parse_answer(&qbuf, n, 0, result, buf, bufsize, errval);
- else if (errno == ECONNREFUSED)
- return file_find_name(hostname, result, buf, bufsize, errval);
- else
- return NULL;
-}
-
-static struct hostent *fake_hostent(const char *hostname, struct in_addr addr,
- struct hostent *result, char *buf,
- int bufsize, int *errval)
-{
- int len = strlen(hostname);
- char *name, *addr_ptr;
-
- if (SP(SP(SP(buf, char, len + 1), addr, 1), char *, 3) > buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
-
- /* Copy faked name and address into buffer. */
- strcpy(buf, hostname);
- name = buf;
- buf = ALIGN(buf + len + 1, addr);
- *((struct in_addr *) buf) = addr;
- addr_ptr = buf;
- buf = ALIGN(buf + sizeof(addr), char *);
- ((char **) buf)[0] = addr_ptr;
- ((char **) buf)[1] = NULL;
- ((char **) buf)[2] = NULL;
-
- result->h_name = name;
- result->h_aliases = ((char **) buf) + 2;
- result->h_addrtype = AF_INET;
- result->h_length = sizeof(addr);
- result->h_addr_list = (char **) buf;
-
- return result;
-}
-
-static struct hostent *file_find_name(const char *name, struct hostent *result,
- char *buf, int bufsize, int *errval)
-{
- char **alias;
- FILE *fp = NULL;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
- while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
- if (strcasecmp(*alias, name) == 0)
- goto end; /* Josip Gracin */
- }
- }
-end:
- pthread_mutex_unlock(&host_iterate_lock);
- if (!result && errno != ERANGE)
- *errval = HOST_NOT_FOUND;
- return result;
-}
-
diff --git a/mit-pthreads/net/gethostent.c b/mit-pthreads/net/gethostent.c
deleted file mode 100644
index d6feb7aa164..00000000000
--- a/mit-pthreads/net/gethostent.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gethostent.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include "res_internal.h"
-
-static pthread_mutex_t res_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int res_file_stayopen;
-static FILE *res_file;
-
-void sethostent(int stayopen)
-{
- pthread_mutex_lock(&res_file_lock);
- res_file_stayopen |= stayopen;
- if (res_file)
- rewind(res_file);
- else
- res_file = fopen(_PATH_HOSTS, "r");
- pthread_mutex_unlock(&res_file_lock);
-}
-
-void endhostent()
-{
- pthread_mutex_lock(&res_file_lock);
- if (res_file)
- fclose(res_file);
- pthread_mutex_unlock(&res_file_lock);
-}
-
-struct hostent *gethostent()
-{
- struct res_data *data = _res_init();
-
- if (!data)
- return NULL;
- if (!data->buf) {
- data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE);
- if (!data->buf) {
- data->errval = NO_RECOVERY;
- return NULL;
- }
- }
- return gethostent_r((struct hostent *) data->buf,
- data->buf + sizeof(struct hostent), HOST_BUFSIZE,
- &data->errval);
-}
-
-struct hostent *gethostent_r(struct hostent *result, char *buf, int bufsize,
- int *errval)
-{
- char *p, **alias;
- struct in_addr *addr;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&res_file_lock);
- if (res_file == NULL && (res_file = fopen(_PATH_HOSTS, "r")) == NULL) {
- pthread_mutex_unlock(&res_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, res_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- l = strlen(buf) + 1;
- *p = '\0';
- p = strpbrk(buf, " \t");
- if (p == NULL)
- continue;
- *p++ = '\0';
-
- /* THIS STUFF IS INTERNET SPECIFIC */
- if (SP(SP(SP(buf, char, l), *addr, 1), char *, 3) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- addr = (struct in_addr *) ALIGN(buf + l, struct in_addr);
- if (inet_aton(buf, addr) == 0)
- continue;
- result->h_length = sizeof(*addr);
- result->h_addrtype = AF_INET;
- result->h_addr_list = (char **) ALIGN(addr + sizeof(*addr), char *);
- result->h_addr_list[0] = (char *) addr;
- result->h_addr_list[1] = NULL;
- result->h_aliases = result->h_addr_list + 2;
- while (*p == ' ' || *p == '\t')
- p++;
- result->h_name = p;
- alias = result->h_aliases;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- if (p && *p)
- break;
- *alias = NULL;
- pthread_mutex_unlock(&res_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&res_file_lock);
- *errval = (errno == ERANGE) ? NO_RECOVERY : 0;
- return NULL;
-}
-
diff --git a/mit-pthreads/net/gethostname.c b/mit-pthreads/net/gethostname.c
deleted file mode 100644
index 8bec0793296..00000000000
--- a/mit-pthreads/net/gethostname.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright Abandoned 2000 TCX DataKonsult AB & Monty Program KB & Detron HB
- This file is public domain and comes with NO WARRANTY of any kind */
-
-#include "config.h"
-#include <pthread.h>
-#include <sys/utsname.h>
-
-#ifdef HAVE_SYSCALL_UNAME
-int gethostname(char *name, int len)
-{
- int ret;
- struct utsname buf;
-
- if ((ret = machdep_sys_chroot(&buf)) < OK)
- {
- SET_ERRNO(-ret);
- }
- else
- strncpy(name,uname->sysname, len);
- return(ret);
-}
-#endif
diff --git a/mit-pthreads/net/getnetbyaddr.c b/mit-pthreads/net/getnetbyaddr.c
deleted file mode 100644
index 6fba661c92e..00000000000
--- a/mit-pthreads/net/getnetbyaddr.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getnetbyaddr.c 5.7 (Berkeley) 6/1/90";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <netdb.h>
-#include "net_internal.h"
-
-struct netent *getnetbyaddr(long net, int type)
-{
- char *buf = _net_buf();
-
- if (!buf)
- return NULL;
- return getnetbyaddr_r(net, type, (struct netent *) buf,
- buf + sizeof(struct netent), NET_BUFSIZE);
-}
-
-struct netent *getnetbyaddr_r(long net, int type, struct netent *result,
- char *buf, int bufsize)
-{
- pthread_mutex_lock(&net_iterate_lock);
- setnetent(0);
- while ((result = getnetent_r(result, buf, bufsize)) != NULL) {
- if (result->n_addrtype == type && result->n_net == net)
- break;
- }
- pthread_mutex_unlock(&net_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getnetbyname.c b/mit-pthreads/net/getnetbyname.c
deleted file mode 100644
index 5b044ceb7a7..00000000000
--- a/mit-pthreads/net/getnetbyname.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getnetbyname.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <netdb.h>
-#include <string.h>
-#include "net_internal.h"
-
-struct netent *getnetbyname(const char *name)
-{
- char *buf = _net_buf();
-
- if (!buf)
- return NULL;
- return getnetbyname_r(name, (struct netent *) buf,
- buf + sizeof(struct netent), NET_BUFSIZE);
-}
-
-struct netent *getnetbyname_r(const char *name, struct netent *result,
- char *buf, int bufsize)
-{
- char **alias;
-
- pthread_mutex_lock(&net_iterate_lock);
- setnetent(0);
- while ((result = getnetent_r(result, buf, bufsize)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcmp(result->n_name, name) == 0)
- break;
- for (alias = result->n_aliases; *alias != 0; alias++) {
- if (strcmp(*alias, name) == 0)
- break;
- }
- }
- pthread_mutex_unlock(&net_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getnetent.c b/mit-pthreads/net/getnetent.c
deleted file mode 100644
index 05af0b09159..00000000000
--- a/mit-pthreads/net/getnetent.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getnetent.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include "net_internal.h"
-
-static pthread_mutex_t net_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int net_file_stayopen;
-static FILE *net_file;
-
-void setnetent(int stayopen)
-{
- pthread_mutex_lock(&net_file_lock);
- net_file_stayopen |= stayopen;
- if (net_file)
- rewind(net_file);
- else
- net_file = fopen(_PATH_NETWORKS, "r");
- pthread_mutex_unlock(&net_file_lock);
-}
-
-void endnetent()
-{
- pthread_mutex_lock(&net_file_lock);
- if (net_file)
- fclose(net_file);
- pthread_mutex_unlock(&net_file_lock);
-}
-
-struct netent *getnetent()
-{
- char *buf = _net_buf();
-
- return getnetent_r((struct netent *) buf, buf + sizeof(struct netent),
- NET_BUFSIZE);
-}
-
-struct netent *getnetent_r(struct netent *result, char *buf, int bufsize)
-{
- char *p, *q, **alias;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&net_file_lock);
- if (net_file == NULL && (net_file = fopen(_PATH_NETWORKS, "r")) == NULL) {
- pthread_mutex_unlock(&net_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, net_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- *p = '\0';
- l = strlen(buf) + 1;
- result->n_name = buf;
- p = strpbrk(buf, " \t");
- if (p == NULL)
- continue;
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- q = strpbrk(p, " \t");
- if (q != NULL)
- *q++ = '\0';
- if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- result->n_net = inet_network(p);
- result->n_addrtype = AF_INET;
- result->n_aliases = (char **) ALIGN(buf + l, char *);
- alias = result->n_aliases;
- if (q != NULL) {
- p = q;
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- if (p && *p)
- break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&net_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&net_file_lock);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/getproto.c b/mit-pthreads/net/getproto.c
deleted file mode 100644
index f6313bf1510..00000000000
--- a/mit-pthreads/net/getproto.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getproto.c 5.6 (Berkeley) 6/1/90";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <netdb.h>
-#include "proto_internal.h"
-
-struct protoent *getprotobynumber(int proto)
-{
- char *buf = _proto_buf();
-
- if (!buf)
- return NULL;
- return getprotobynumber_r(proto, (struct protoent *) buf,
- buf + sizeof(struct protoent), PROTO_BUFSIZE);
-}
-
-struct protoent *getprotobynumber_r(int proto, struct protoent *result,
- char *buf, int bufsize)
-{
- pthread_mutex_lock(&proto_iterate_lock);
- setprotoent(0);
- while ((result = getprotoent_r(result, buf, bufsize)) != NULL) {
- if (result->p_proto == proto)
- break;
- }
- pthread_mutex_unlock(&proto_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getprotoent.c b/mit-pthreads/net/getprotoent.c
deleted file mode 100644
index 8bd8d95ec14..00000000000
--- a/mit-pthreads/net/getprotoent.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getprotoent.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include "proto_internal.h"
-
-static pthread_mutex_t proto_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int proto_file_stayopen;
-static FILE *proto_file;
-
-void setprotoent(int stayopen)
-{
- pthread_mutex_lock(&proto_file_lock);
- proto_file_stayopen |= stayopen;
- if (proto_file)
- rewind(proto_file);
- else
- proto_file = fopen(_PATH_PROTOCOLS, "r");
- pthread_mutex_unlock(&proto_file_lock);
-}
-
-void endprotoent()
-{
- pthread_mutex_lock(&proto_file_lock);
- if (proto_file)
- fclose(proto_file);
- pthread_mutex_unlock(&proto_file_lock);
-}
-
-struct protoent *getprotoent()
-{
- char *buf = _proto_buf();
-
- return getprotoent_r((struct protoent *) buf,
- buf + sizeof(struct protoent), PROTO_BUFSIZE);
-}
-
-struct protoent *getprotoent_r(struct protoent *result, char *buf, int bufsize)
-{
- char *p, *q, **alias;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&proto_file_lock);
- if (proto_file == NULL && !(proto_file = fopen(_PATH_PROTOCOLS, "r"))) {
- pthread_mutex_unlock(&proto_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, proto_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- *p = '\0';
- l = strlen(buf) + 1;
- result->p_name = buf;
- p = strpbrk(buf, " \t");
- if (p == NULL)
- continue;
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- q = strpbrk(p, " \t");
- if (q != NULL)
- *q++ = '\0';
- if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- result->p_proto = atoi(p);
- result->p_aliases = (char **) ALIGN(buf + l, char *);
- alias = result->p_aliases;
- if (q != NULL) {
- p = q;
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- if (p && *p)
- break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&proto_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&proto_file_lock);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/getprotoname.c b/mit-pthreads/net/getprotoname.c
deleted file mode 100644
index 7bd7b925091..00000000000
--- a/mit-pthreads/net/getprotoname.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getprotoname.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <netdb.h>
-#include <string.h>
-#include "proto_internal.h"
-
-struct protoent *getprotobyname(const char *name)
-{
- char *buf = _proto_buf();
-
- if (!buf)
- return NULL;
- return getprotobyname_r(name, (struct protoent *) buf,
- buf + sizeof(struct protoent), PROTO_BUFSIZE);
-}
-
-struct protoent *getprotobyname_r(const char *name, struct protoent *result,
- char *buf, int bufsize)
-{
- char **alias;
-
- pthread_mutex_lock(&proto_iterate_lock);
- setprotoent(0);
- while ((result = getprotoent_r(result, buf, bufsize)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcmp(result->p_name, name) == 0)
- break;
- for (alias = result->p_aliases; *alias != 0; alias++) {
- if (strcmp(*alias, name) == 0)
- break;
- }
- }
- pthread_mutex_unlock(&proto_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getservbyname.c b/mit-pthreads/net/getservbyname.c
deleted file mode 100644
index f482b544fd0..00000000000
--- a/mit-pthreads/net/getservbyname.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getservbyname.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <netdb.h>
-#include <string.h>
-#include "serv_internal.h"
-
-struct servent *getservbyname(const char *name, const char *proto)
-{
- char *buf = _serv_buf();
-
- if (!buf)
- return NULL;
- return getservbyname_r(name, proto, (struct servent *) buf,
- buf + sizeof(struct servent), SERV_BUFSIZE);
-}
-
-struct servent *getservbyname_r(const char *name, const char *proto,
- struct servent *result, char *buf, int bufsize)
-{
- char **alias;
-
- pthread_mutex_lock(&serv_iterate_lock);
- setservent(0);
- while ((result = getservent_r(result, buf, bufsize)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcmp(result->s_name, name) != 0) {
- for (alias = result->s_aliases; *alias != NULL; alias++) {
- if (strcmp(*alias, name) == 0)
- break;
- }
- if (*alias == NULL)
- continue;
- }
- if (proto == NULL || strcmp(result->s_proto, proto) == 0)
- break;
- }
- pthread_mutex_unlock(&serv_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getservbyport.c b/mit-pthreads/net/getservbyport.c
deleted file mode 100644
index e3418212c0b..00000000000
--- a/mit-pthreads/net/getservbyport.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getservbyport.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include "serv_internal.h"
-
-struct servent *getservbyport(int port, const char *proto)
-{
- char *buf = _serv_buf();
-
- if (!buf)
- return NULL;
- return getservbyport_r(port, proto, (struct servent *) buf,
- buf + sizeof(struct servent), SERV_BUFSIZE);
-}
-
-struct servent *getservbyport_r(int port, const char *proto,
- struct servent *result, char *buf, int bufsize)
-{
- pthread_mutex_lock(&serv_iterate_lock);
- setservent(0);
- while ((result = getservent_r(result, buf, bufsize)) != NULL) {
- if (result->s_port != port)
- continue;
- if (proto == NULL || strcmp(result->s_proto, proto) == 0)
- break;
- }
- pthread_mutex_unlock(&serv_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getservent.c b/mit-pthreads/net/getservent.c
deleted file mode 100644
index b0a7e039f69..00000000000
--- a/mit-pthreads/net/getservent.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getservent.c 5.9 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "serv_internal.h"
-
-static pthread_mutex_t serv_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int serv_file_stayopen=0;
-static FILE *serv_file=NULL;
-
-void setservent(int stayopen)
-{
- pthread_mutex_lock(&serv_file_lock);
- serv_file_stayopen |= stayopen;
- if (serv_file)
- rewind(serv_file);
- else
- serv_file = fopen(_PATH_SERVICES, "r");
- pthread_mutex_unlock(&serv_file_lock);
-}
-
-void endservent()
-{
- pthread_mutex_lock(&serv_file_lock);
- if (serv_file)
- {
- fclose(serv_file);
- serv_file=NULL;
- }
- pthread_mutex_unlock(&serv_file_lock);
-}
-
-struct servent *getservent()
-{
- char *buf = _serv_buf();
-
- return getservent_r((struct servent *) buf, buf + sizeof(struct servent),
- SERV_BUFSIZE);
-}
-
-struct servent *getservent_r(struct servent *result, char *buf, int bufsize)
-{
- char *p, *q, **alias;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&serv_file_lock);
- if (serv_file == NULL && !(serv_file = fopen(_PATH_SERVICES, "r"))) {
- pthread_mutex_unlock(&serv_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, serv_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- *p = '\0';
- l = strlen(buf) + 1;
- result->s_name = buf;
- q = strpbrk(buf, " \t");
- if (q == NULL)
- continue;
- *q++ = '\0';
- while (*q == ' ' || *q == '\t')
- q++;
- p = strpbrk(q, ",/");
- if (p == NULL)
- continue;
- *p++ = '\0';
- if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- result->s_port = htons((u_short)atoi(q));
- result->s_proto = p;
- result->s_aliases = (char **) ALIGN(buf + l, char *);
- alias = result->s_aliases;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- *alias = NULL;
- pthread_mutex_unlock(&serv_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&serv_file_lock);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/herror.c b/mit-pthreads/net/herror.c
deleted file mode 100644
index 935c8e7ea38..00000000000
--- a/mit-pthreads/net/herror.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)herror.c 6.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <string.h>
-#include <resolv.h>
-
-char *h_errlist[] = {
- "Error 0",
- "Unknown host", /* 1 HOST_NOT_FOUND */
- "Host name lookup failure", /* 2 TRY_AGAIN */
- "Unknown server error", /* 3 NO_RECOVERY */
- "No address associated with name", /* 4 NO_ADDRESS */
-};
-int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
-
-/*
- * herror --
- * print the error indicated by the h_errno value.
- */
-void
-herror(s)
- const char *s;
-{
- struct iovec iov[4];
- register struct iovec *v = iov;
- int error = h_errno;
-
- if (s && *s) {
- v->iov_base = (char *)s;
- v->iov_len = strlen(s);
- v++;
- v->iov_base = ": ";
- v->iov_len = 2;
- v++;
- }
- v->iov_base = ((unsigned int)(error) < h_nerr) ?
- h_errlist[error] : "Unknown error";
- v->iov_len = strlen(v->iov_base);
- v++;
- v->iov_base = "\n";
- v->iov_len = 1;
- writev(STDERR_FILENO, iov, (v - iov) + 1);
-}
-
-char *
-hstrerror(err)
- int err;
-{
- return ((unsigned int)(err) < h_nerr) ? h_errlist[err]
- : "Unknown resolver error";
-}
-
diff --git a/mit-pthreads/net/inet_addr.c b/mit-pthreads/net/inet_addr.c
deleted file mode 100644
index 75ca154d4c2..00000000000
--- a/mit-pthreads/net/inet_addr.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 1983, 1990 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_addr.c 5.10 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-/*
- * Ascii internet address interpretation routine.
- * The value returned is in network order.
- */
-pthread_ipaddr_type
-inet_addr(cp)
- register const char *cp;
-{
- struct in_addr val;
-
- if (inet_aton(cp, &val))
- return (val.s_addr);
- return (INADDR_NONE);
-}
-
-/*
- * Check whether "cp" is a valid ascii representation
- * of an Internet address and convert to a binary address.
- * Returns 1 if the address is valid, 0 if not.
- * This replaces inet_addr, the return value from which
- * cannot distinguish between failure and a local broadcast address.
- */
-
-inet_aton(cp, addr)
- const register char *cp;
- struct in_addr *addr;
-{
- pthread_ipaddr_type parts[4], *pp = parts;
- pthread_ipaddr_type val, base, n;
- register char c;
-
- for (;;) {
- /*
- * Collect number up to ``.''.
- * Values are specified as for C:
- * 0x=hex, 0=octal, other=decimal.
- */
- val = 0; base = 10;
- if (*cp == '0') {
- if (*++cp == 'x' || *cp == 'X')
- base = 16, cp++;
- else
- base = 8;
- }
- while ((c = *cp) != '\0') {
- if (isascii(c) && isdigit(c)) {
- val = (val * base) + (c - '0');
- cp++;
- continue;
- }
- if (base == 16 && isascii(c) && isxdigit(c)) {
- val = (val << 4) +
- (c + 10 - (islower(c) ? 'a' : 'A'));
- cp++;
- continue;
- }
- break;
- }
- if (*cp == '.') {
- /*
- * Internet format:
- * a.b.c.d
- * a.b.c (with c treated as 16-bits)
- * a.b (with b treated as 24 bits)
- */
- if (pp >= parts + 3 || val > 0xff)
- return (0);
- *pp++ = val, cp++;
- } else
- break;
- }
- /*
- * Check for trailing characters.
- */
- if (*cp && (!isascii(*cp) || !isspace(*cp)))
- return (0);
- /*
- * Concoct the address according to
- * the number of parts specified.
- */
- n = pp - parts + 1;
- switch (n) {
-
- case 1: /* a -- 32 bits */
- break;
-
- case 2: /* a.b -- 8.24 bits */
- if (val > 0xffffff)
- return (0);
- val |= parts[0] << 24;
- break;
-
- case 3: /* a.b.c -- 8.8.16 bits */
- if (val > 0xffff)
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16);
- break;
-
- case 4: /* a.b.c.d -- 8.8.8.8 bits */
- if (val > 0xff)
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
- break;
- }
- if (addr)
- addr->s_addr = htonl(val);
- return (1);
-}
-
diff --git a/mit-pthreads/net/inet_lnaof.c b/mit-pthreads/net/inet_lnaof.c
deleted file mode 100644
index 752a5f03f79..00000000000
--- a/mit-pthreads/net/inet_lnaof.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_lnaof.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/*
- * Return the local network address portion of an
- * internet address; handles class a/b/c network
- * number formats.
- */
-pthread_ipaddr_type
-inet_lnaof(in)
- struct in_addr in;
-{
- register pthread_ipaddr_type i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return ((i)&IN_CLASSA_HOST);
- else if (IN_CLASSB(i))
- return ((i)&IN_CLASSB_HOST);
- else
- return ((i)&IN_CLASSC_HOST);
-}
diff --git a/mit-pthreads/net/inet_makeaddr.c b/mit-pthreads/net/inet_makeaddr.c
deleted file mode 100644
index a4995e2b4c4..00000000000
--- a/mit-pthreads/net/inet_makeaddr.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_makeaddr.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/*
- * Formulate an Internet address from network + host. Used in
- * building addresses stored in the ifnet structure.
- */
-struct in_addr
-inet_makeaddr(net, host)
- pthread_ipaddr_type net, host;
-{
- pthread_ipaddr_type addr;
-
- if (net < 128)
- addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
- else if (net < 65536)
- addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
- else if (net < 16777216L)
- addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
- else
- addr = net | host;
- addr = htonl(addr);
- return (*(struct in_addr *)&addr);
-}
diff --git a/mit-pthreads/net/inet_netof.c b/mit-pthreads/net/inet_netof.c
deleted file mode 100644
index 40d3f4c3385..00000000000
--- a/mit-pthreads/net/inet_netof.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_netof.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/*
- * Return the network number from an internet
- * address; handles class a/b/c network #'s.
- */
-pthread_ipaddr_type
-inet_netof(in)
- struct in_addr in;
-{
- register pthread_ipaddr_type i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
- else if (IN_CLASSB(i))
- return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
- else
- return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
-}
diff --git a/mit-pthreads/net/inet_network.c b/mit-pthreads/net/inet_network.c
deleted file mode 100644
index cc0f1b4e603..00000000000
--- a/mit-pthreads/net/inet_network.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_network.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-/*
- * Internet network address interpretation routine.
- * The library routines call this routine to interpret
- * network numbers.
- */
-pthread_ipaddr_type
-inet_network(cp)
- register const char *cp;
-{
- pthread_ipaddr_type parts[4], *pp = parts;
- pthread_ipaddr_type val, base, n;
- register char c;
- register int i;
-
-again:
- val = 0; base = 10;
- if (*cp == '0')
- base = 8, cp++;
- if (*cp == 'x' || *cp == 'X')
- base = 16, cp++;
- while (c = *cp) {
- if (isdigit(c)) {
- val = (val * base) + (c - '0');
- cp++;
- continue;
- }
- if (base == 16 && isxdigit(c)) {
- val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
- cp++;
- continue;
- }
- break;
- }
- if (*cp == '.') {
- if (pp >= parts + 4)
- return (INADDR_NONE);
- *pp++ = val, cp++;
- goto again;
- }
- if (*cp && !isspace(*cp))
- return (INADDR_NONE);
- *pp++ = val;
- n = pp - parts;
- if (n > 4)
- return (INADDR_NONE);
- for (val = 0, i = 0; i < n; i++) {
- val <<= 8;
- val |= parts[i] & 0xff;
- }
- return (val);
-}
diff --git a/mit-pthreads/net/inet_ntoa.c b/mit-pthreads/net/inet_ntoa.c
deleted file mode 100644
index cd206afcf2a..00000000000
--- a/mit-pthreads/net/inet_ntoa.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_ntoa.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Convert network-format internet address
- * to base 256 d.d.d.d representation.
- */
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-char *inet_ntoa(struct in_addr in)
-{
- static pthread_mutex_t inet_ntoa_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t inet_ntoa_key = -1;
- char *buf, *inet_ntoa_r();
-
- if (inet_ntoa_key < 0) {
- pthread_mutex_lock(&inet_ntoa_mutex);
- if (inet_ntoa_key < 0) {
- if (pthread_key_create(&inet_ntoa_key, free) < 0) {
- pthread_mutex_unlock(&inet_ntoa_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&inet_ntoa_mutex);
- }
- if ((buf = pthread_getspecific(inet_ntoa_key)) == NULL) {
- if ((buf = (char *) malloc(18)) == NULL) {
- return(NULL);
- }
- pthread_setspecific(inet_ntoa_key, buf);
- }
- return inet_ntoa_r(in, buf, 18);
-}
-
-char *inet_ntoa_r(struct in_addr in, char *buf, int bufsize)
-{
- register char *p;
-
- p = (char *)&in;
-#define UC(b) (((int)b)&0xff)
- (void)snprintf(buf, bufsize,
- "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
- return (buf);
-}
-
diff --git a/mit-pthreads/net/net_internal.c b/mit-pthreads/net/net_internal.c
deleted file mode 100644
index 2c25ff76693..00000000000
--- a/mit-pthreads/net/net_internal.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)net_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "net_internal.h"
-
-static void _net_init_global(void);
-
-pthread_mutex_t net_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-/* Performs global initialization. */
-char *_net_buf()
-{
- char *buf;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _net_init_global);
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- buf = (char *) pthread_getspecific(key);
- if (!buf) {
- buf = (char *) malloc(NET_BUFSIZE);
- if (buf == NULL)
- return NULL;
- if (pthread_setspecific(key, buf) < 0) {
- free(buf);
- return NULL;
- }
- }
- return buf;
-}
-
-static void _net_init_global()
-{
- init_status = pthread_key_create(&key, free);
-}
-
diff --git a/mit-pthreads/net/net_internal.h b/mit-pthreads/net/net_internal.h
deleted file mode 100644
index 0dc5c866e5d..00000000000
--- a/mit-pthreads/net/net_internal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)net_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _NET_INTERNAL_H
-#define _NET_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define NET_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-extern pthread_mutex_t net_iterate_lock;
-
-__BEGIN_DECLS
-char *_net_buf(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/net/proto_internal.c b/mit-pthreads/net/proto_internal.c
deleted file mode 100644
index db3ab04ec77..00000000000
--- a/mit-pthreads/net/proto_internal.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)proto_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "proto_internal.h"
-
-static void _proto_init_global(void);
-
-pthread_mutex_t proto_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-/* Performs global initialization. */
-char *_proto_buf()
-{
- char *buf;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _proto_init_global);
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- buf = (char *) pthread_getspecific(key);
- if (!buf) {
- buf = (char *) malloc(PROTO_BUFSIZE);
- if (buf == NULL)
- return NULL;
- if (pthread_setspecific(key, buf) < 0) {
- free(buf);
- return NULL;
- }
- }
- return buf;
-}
-
-static void _proto_init_global()
-{
- init_status = pthread_key_create(&key, free);
-}
-
diff --git a/mit-pthreads/net/proto_internal.h b/mit-pthreads/net/proto_internal.h
deleted file mode 100644
index 4ed06883f25..00000000000
--- a/mit-pthreads/net/proto_internal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)proto_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _PROTO_INTERNAL_H
-#define _PROTO_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define PROTO_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-extern pthread_mutex_t proto_iterate_lock;
-
-__BEGIN_DECLS
-char *_proto_buf(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/net/res_comp.c b/mit-pthreads/net/res_comp.c
deleted file mode 100644
index 45a4bcafed2..00000000000
--- a/mit-pthreads/net/res_comp.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_comp.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <sys/cdefs.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <stdio.h>
-
-static dn_find();
-
-/*
- * Expand compressed domain name 'comp_dn' to full domain name.
- * 'msg' is a pointer to the begining of the message,
- * 'eomorig' points to the first location after the message,
- * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
- * Return size of compressed name or -1 if there was an error.
- */
-dn_expand(msg, eomorig, comp_dn, exp_dn, length)
- const u_char *msg, *eomorig, *comp_dn;
- u_char *exp_dn;
- int length;
-{
- register u_char *cp, *dn;
- register int n, c;
- u_char *eom;
- int len = -1, checked = 0;
-
- dn = exp_dn;
- cp = (u_char *)comp_dn;
- eom = exp_dn + length;
- /*
- * fetch next label in domain name
- */
- while (n = *cp++) {
- /*
- * Check for indirection
- */
- switch (n & INDIR_MASK) {
- case 0:
- if (dn != exp_dn) {
- if (dn >= eom)
- return (-1);
- *dn++ = '.';
- }
- if (dn+n >= eom)
- return (-1);
- checked += n + 1;
- while (--n >= 0) {
- if ((c = *cp++) == '.') {
- if (dn + n + 2 >= eom)
- return (-1);
- *dn++ = '\\';
- }
- *dn++ = c;
- if (cp >= eomorig) /* out of range */
- return(-1);
- }
- break;
-
- case INDIR_MASK:
- if (len < 0)
- len = cp - comp_dn + 1;
- cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
- if (cp < msg || cp >= eomorig) /* out of range */
- return(-1);
- checked += 2;
- /*
- * Check for loops in the compressed name;
- * if we've looked at the whole message,
- * there must be a loop.
- */
- if (checked >= eomorig - msg)
- return (-1);
- break;
-
- default:
- return (-1); /* flag error */
- }
- }
- *dn = '\0';
- if (len < 0)
- len = cp - comp_dn;
- return (len);
-}
-
-/*
- * Compress domain name 'exp_dn' into 'comp_dn'.
- * Return the size of the compressed name or -1.
- * 'length' is the size of the array pointed to by 'comp_dn'.
- * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
- * is a pointer to the beginning of the message. The list ends with NULL.
- * 'lastdnptr' is a pointer to the end of the arrary pointed to
- * by 'dnptrs'. Side effect is to update the list of pointers for
- * labels inserted into the message as we compress the name.
- * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
- * is NULL, we don't update the list.
- */
-dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
- const u_char *exp_dn;
- u_char *comp_dn, **dnptrs, **lastdnptr;
- int length;
-{
- register u_char *cp, *dn;
- register int c, l;
- u_char **cpp, **lpp, *sp, *eob;
- u_char *msg;
-
- dn = (u_char *)exp_dn;
- cp = comp_dn;
- eob = cp + length;
- if (dnptrs != NULL) {
- if ((msg = *dnptrs++) != NULL) {
- for (cpp = dnptrs; *cpp != NULL; cpp++)
- ;
- lpp = cpp; /* end of list to search */
- }
- } else
- msg = NULL;
- for (c = *dn++; c != '\0'; ) {
- /* look to see if we can use pointers */
- if (msg != NULL) {
- if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
- if (cp+1 >= eob)
- return (-1);
- *cp++ = (l >> 8) | INDIR_MASK;
- *cp++ = l % 256;
- return (cp - comp_dn);
- }
- /* not found, save it */
- if (lastdnptr != NULL && cpp < lastdnptr-1) {
- *cpp++ = cp;
- *cpp = NULL;
- }
- }
- sp = cp++; /* save ptr to length byte */
- do {
- if (c == '.') {
- c = *dn++;
- break;
- }
- if (c == '\\') {
- if ((c = *dn++) == '\0')
- break;
- }
- if (cp >= eob) {
- if (msg != NULL)
- *lpp = NULL;
- return (-1);
- }
- *cp++ = c;
- } while ((c = *dn++) != '\0');
- /* catch trailing '.'s but not '..' */
- if ((l = cp - sp - 1) == 0 && c == '\0') {
- cp--;
- break;
- }
- if (l <= 0 || l > MAXLABEL) {
- if (msg != NULL)
- *lpp = NULL;
- return (-1);
- }
- *sp = l;
- }
- if (cp >= eob) {
- if (msg != NULL)
- *lpp = NULL;
- return (-1);
- }
- *cp++ = '\0';
- return (cp - comp_dn);
-}
-
-/*
- * Skip over a compressed domain name. Return the size or -1.
- */
-__dn_skipname(comp_dn, eom)
- const u_char *comp_dn, *eom;
-{
- register u_char *cp;
- register int n;
-
- cp = (u_char *)comp_dn;
- while (cp < eom && (n = *cp++)) {
- /*
- * check for indirection
- */
- switch (n & INDIR_MASK) {
- case 0: /* normal case, n == len */
- cp += n;
- continue;
- case INDIR_MASK: /* indirection */
- cp++;
- break;
- default: /* illegal type */
- return (-1);
- }
- break;
- }
- if (cp > eom)
- return -1;
- return (cp - comp_dn);
-}
-
-/*
- * Search for expanded name from a list of previously compressed names.
- * Return the offset from msg if found or -1.
- * dnptrs is the pointer to the first name on the list,
- * not the pointer to the start of the message.
- */
-static int
-dn_find(exp_dn, msg, dnptrs, lastdnptr)
- u_char *exp_dn, *msg;
- u_char **dnptrs, **lastdnptr;
-{
- register u_char *dn, *cp, **cpp;
- register int n;
- u_char *sp;
-
- for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
- dn = exp_dn;
- sp = cp = *cpp;
- while (n = *cp++) {
- /*
- * check for indirection
- */
- switch (n & INDIR_MASK) {
- case 0: /* normal case, n == len */
- while (--n >= 0) {
- if (*dn == '.')
- goto next;
- if (*dn == '\\')
- dn++;
- if (*dn++ != *cp++)
- goto next;
- }
- if ((n = *dn++) == '\0' && *cp == '\0')
- return (sp - msg);
- if (n == '.')
- continue;
- goto next;
-
- default: /* illegal type */
- return (-1);
-
- case INDIR_MASK: /* indirection */
- cp = msg + (((n & 0x3f) << 8) | *cp);
- }
- }
- if (*dn == '\0')
- return (sp - msg);
- next: ;
- }
- return (-1);
-}
-
-/*
- * Routines to insert/extract short/long's. Must account for byte
- * order and non-alignment problems. This code at least has the
- * advantage of being portable.
- *
- * used by sendmail.
- */
-
-u_short
-_getshort(msgp)
- register const u_char *msgp;
-{
- register u_short u;
-
- GETSHORT(u, msgp);
- return (u);
-}
-
-pthread_ipaddr_type
-_getlong(msgp)
- const u_char *msgp;
-{
- pthread_ipaddr_type u;
-
- GETLONG(u, msgp);
- return (u);
-}
-
-void
-#ifdef __STDC__
-__putshort(register u_short s, register u_char *msgp)
-#else
- __putshort(s, msgp)
- register u_short s;
- register u_char *msgp;
-#endif
-{
- PUTSHORT(s, msgp);
-}
-
-void
-__putlong(l, msgp)
- register pthread_ipaddr_type l;
- register u_char *msgp;
-{
- PUTLONG(l, msgp);
-}
-
diff --git a/mit-pthreads/net/res_debug.c b/mit-pthreads/net/res_debug.c
deleted file mode 100644
index 3e2084fccf8..00000000000
--- a/mit-pthreads/net/res_debug.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- * Copyright (c) 1985, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <stdio.h>
-#include <string.h>
-#include <resolv.h>
-#include <arpa/inet.h>
-
-void __fp_query();
-char *__p_class(), *__p_time(), *__p_type();
-char *p_cdname(), *p_fqname(), *p_rr();
-static char *p_option __P_((u_long));
-
-char *_res_opcodes[] = {
- "QUERY",
- "IQUERY",
- "CQUERYM",
- "CQUERYU",
- "4",
- "5",
- "6",
- "7",
- "8",
- "UPDATEA",
- "UPDATED",
- "UPDATEDA",
- "UPDATEM",
- "UPDATEMA",
- "ZONEINIT",
- "ZONEREF",
-};
-
-char *_res_resultcodes[] = {
- "NOERROR",
- "FORMERR",
- "SERVFAIL",
- "NXDOMAIN",
- "NOTIMP",
- "REFUSED",
- "6",
- "7",
- "8",
- "9",
- "10",
- "11",
- "12",
- "13",
- "14",
- "NOCHANGE",
-};
-
-static char retbuf[16];
-
-static char *
-dewks(wks)
- int wks;
-{
- switch (wks) {
- case 5: return("rje");
- case 7: return("echo");
- case 9: return("discard");
- case 11: return("systat");
- case 13: return("daytime");
- case 15: return("netstat");
- case 17: return("qotd");
- case 19: return("chargen");
- case 20: return("ftp-data");
- case 21: return("ftp");
- case 23: return("telnet");
- case 25: return("smtp");
- case 37: return("time");
- case 39: return("rlp");
- case 42: return("name");
- case 43: return("whois");
- case 53: return("domain");
- case 57: return("apts");
- case 59: return("apfs");
- case 67: return("bootps");
- case 68: return("bootpc");
- case 69: return("tftp");
- case 77: return("rje");
- case 79: return("finger");
- case 87: return("link");
- case 95: return("supdup");
- case 100: return("newacct");
- case 101: return("hostnames");
- case 102: return("iso-tsap");
- case 103: return("x400");
- case 104: return("x400-snd");
- case 105: return("csnet-ns");
- case 109: return("pop-2");
- case 111: return("sunrpc");
- case 113: return("auth");
- case 115: return("sftp");
- case 117: return("uucp-path");
- case 119: return("nntp");
- case 121: return("erpc");
- case 123: return("ntp");
- case 133: return("statsrv");
- case 136: return("profile");
- case 144: return("NeWS");
- case 161: return("snmp");
- case 162: return("snmp-trap");
- case 170: return("print-srv");
- default: (void) sprintf(retbuf, "%d", wks); return(retbuf);
- }
-}
-
-static char *
-deproto(protonum)
- int protonum;
-{
- switch (protonum) {
- case 1: return("icmp");
- case 2: return("igmp");
- case 3: return("ggp");
- case 5: return("st");
- case 6: return("tcp");
- case 7: return("ucl");
- case 8: return("egp");
- case 9: return("igp");
- case 11: return("nvp-II");
- case 12: return("pup");
- case 16: return("chaos");
- case 17: return("udp");
- default: (void) sprintf(retbuf, "%d", protonum); return(retbuf);
- }
-}
-
-static char *
-do_rrset(msg, cp, cnt, pflag, file, hs)
- int cnt, pflag;
- char *cp,*msg, *hs;
- FILE *file;
-{
- int n;
- int sflag;
- /*
- * Print answer records
- */
- sflag = (_res.pfcode & pflag);
- if (n = ntohs(cnt)) {
- if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
- fprintf(file, hs);
- while (--n >= 0) {
- cp = p_rr(cp, msg, file);
- if ((cp-msg) > PACKETSZ)
- return (NULL);
- }
- if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
- putc('\n', file);
- }
- return(cp);
-}
-
-__p_query(msg)
- char *msg;
-{
- __fp_query(msg, stdout);
-}
-
-/*
- * Print the current options.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_resstat(statp, file)
- struct __res_state *statp;
- FILE *file;
-{
- int bit;
-
- fprintf(file, ";; res options:");
- if (!statp)
- statp = &_res;
- for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */
- if (statp->options & (1<<bit))
- fprintf(file, " %s", p_option(1<<bit));
- }
- putc('\n', file);
-}
-
-/*
- * Print the contents of a query.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_query(msg,file)
- char *msg;
- FILE *file;
-{
- register char *cp;
- register HEADER *hp;
- register int n;
-
- /*
- * Print header fields.
- */
- hp = (HEADER *)msg;
- cp = msg + sizeof(HEADER);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
- fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
- _res_opcodes[hp->opcode],
- _res_resultcodes[hp->rcode],
- ntohs(hp->id));
- putc('\n', file);
- }
- putc(';', file);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
- fprintf(file,"; flags:");
- if (hp->qr)
- fprintf(file," qr");
- if (hp->aa)
- fprintf(file," aa");
- if (hp->tc)
- fprintf(file," tc");
- if (hp->rd)
- fprintf(file," rd");
- if (hp->ra)
- fprintf(file," ra");
- if (hp->pr)
- fprintf(file," pr");
- }
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
- fprintf(file,"; Ques: %d", ntohs(hp->qdcount));
- fprintf(file,", Ans: %d", ntohs(hp->ancount));
- fprintf(file,", Auth: %d", ntohs(hp->nscount));
- fprintf(file,", Addit: %d", ntohs(hp->arcount));
- }
-#if 1
- if ((!_res.pfcode) || (_res.pfcode &
- (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
- putc('\n',file);
- }
-#endif
- /*
- * Print question records.
- */
- if (n = ntohs(hp->qdcount)) {
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file,";; QUESTIONS:\n");
- while (--n >= 0) {
- fprintf(file,";;\t");
- cp = p_cdname(cp, msg, file);
- if (cp == NULL)
- return;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ", type = %s",
- __p_type(_getshort(cp)));
- cp += sizeof(u_short);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ", class = %s\n",
- __p_class(_getshort(cp)));
- cp += sizeof(u_short);
- putc('\n', file);
- }
- }
- /*
- * Print authoritative answer records
- */
- cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
- ";; ANSWERS:\n");
- if (cp == NULL)
- return;
-
- /*
- * print name server records
- */
- cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
- ";; AUTHORITY RECORDS:\n");
- if (!cp)
- return;
-
- /*
- * print additional records
- */
- cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
- ";; ADDITIONAL RECORDS:\n");
- if (!cp)
- return;
-}
-
-char *
-p_cdname(cp, msg, file)
- char *cp, *msg;
- FILE *file;
-{
- char name[MAXDNAME];
- int n;
-
- if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
- (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
- return (NULL);
- if (name[0] == '\0')
- putc('.', file);
- else
- fputs(name, file);
- return (cp + n);
-}
-
-char *
-p_fqname(cp, msg, file)
- char *cp, *msg;
- FILE *file;
-{
- char name[MAXDNAME];
- int n, len;
-
- if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
- (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
- return (NULL);
- if (name[0] == '\0') {
- putc('.', file);
- } else {
- fputs(name, file);
- if (name[strlen(name) - 1] != '.')
- putc('.', file);
- }
- return (cp + n);
-}
-
-/*
- * Print resource record fields in human readable form.
- *
- * Removed calls to non-reentrant routines to simplify varifying
- * POSIX thread-safe implementations. (mevans).
- */
-char *
-p_rr(cp, msg, file)
- char *cp, *msg;
- FILE *file;
-{
- int type, class, dlen, n, c;
- struct in_addr inaddr;
- char *cp1, *cp2;
- u_long tmpttl, t;
- int lcnt;
- char buf[32];
-
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL); /* compression error */
- type = _getshort(cp);
- cp += sizeof(u_short);
- class = _getshort(cp);
- cp += sizeof(u_short);
- tmpttl = _getlong(cp);
- cp += sizeof(u_long);
- dlen = _getshort(cp);
- cp += sizeof(u_short);
- cp1 = cp;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
- fprintf(file, "\t%lu", tmpttl);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
- fprintf(file, "\t%s", __p_class(class));
- fprintf(file, "\t%s", __p_type(type));
- /*
- * Print type specific data, if appropriate
- */
- switch (type) {
- case T_A:
- switch (class) {
- case C_IN:
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
- fprintf(file,"\t%s",
- inet_ntoa_r(inaddr, buf, sizeof(buf)));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
- address = inet_ntoa_r(inaddr,
- buf, sizeof(buf));
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
- port = _getshort(cp);
- cp += sizeof(u_short);
- fprintf(file, "\t%s\t; proto %d, port %d",
- address, protocol, port);
- }
- break;
- default:
- cp += dlen;
- }
- break;
- case T_CNAME:
- case T_MB:
- case T_MG:
- case T_MR:
- case T_NS:
- case T_PTR:
- putc('\t', file);
- cp = p_fqname(cp, msg, file);
- break;
-
- case T_HINFO:
- if (n = *cp++) {
- fprintf(file,"\t%.*s", n, cp);
- cp += n;
- }
- if (n = *cp++) {
- fprintf(file,"\t%.*s", n, cp);
- cp += n;
- }
- break;
-
- case T_SOA:
- putc('\t', file);
- cp = p_fqname(cp, msg, file); /* origin */
- putc(' ', file);
- cp = p_fqname(cp, msg, file); /* mail addr */
- fputs(" (\n", file);
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; serial\n", t);
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
- break;
-
- case T_MX:
- case T_AFSDB:
- fprintf(file,"\t%d ", _getshort(cp));
- cp += sizeof(u_short);
- cp = p_fqname(cp, msg, file);
- break;
-
- case T_TXT:
- (void) fputs("\t\"", file);
- cp2 = cp1 + dlen;
- while (cp < cp2) {
- if (n = (unsigned char) *cp++) {
- for (c = n; c > 0 && cp < cp2; c--)
- if (*cp == '\n') {
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- } else
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- break;
-
- case T_MINFO:
- case T_RP:
- putc('\t', file);
- cp = p_fqname(cp, msg, file);
- putc(' ', file);
- cp = p_fqname(cp, msg, file);
- break;
-
- case T_UINFO:
- putc('\t', file);
- fputs(cp, file);
- cp += dlen;
- break;
-
- case T_UID:
- case T_GID:
- if (dlen == 4) {
- fprintf(file,"\t%u", _getlong(cp));
- cp += sizeof(long);
- }
- break;
-
- case T_WKS:
- if (dlen < sizeof(u_long) + 1)
- break;
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "\t%s %s ( ",
- inet_ntoa_r(inaddr, buf, sizeof(buf)),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
- lcnt = 0;
- while (cp < cp1 + dlen) {
- c = *cp++;
- do {
- if (c & 0200) {
- if (lcnt == 0) {
- fputs("\n\t\t\t", file);
- lcnt = 5;
- }
- fputs(dewks(n), file);
- putc(' ', file);
- lcnt--;
- }
- c <<= 1;
- } while (++n & 07);
- }
- putc(')', file);
- break;
-
-#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- {
- int NumBytes = 8;
- char *DataPtr;
- int i;
-
- if (dlen < NumBytes) NumBytes = dlen;
- fprintf(file, "\tFirst %d bytes of hex data:",
- NumBytes);
- for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
- fprintf(file, " %x", *DataPtr);
- cp += dlen;
- }
- break;
-#endif /* ALLOW_T_UNSPEC */
-
- default:
- fprintf(file,"\t?%d?", type);
- cp += dlen;
- }
-#if 0
- fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
-#else
- putc('\n', file);
-#endif
- if (cp - cp1 != dlen) {
- fprintf(file,";; packet size error (found %d, dlen was %d)\n",
- cp - cp1, dlen);
- cp = NULL;
- }
- return (cp);
-}
-
-static char nbuf[40];
-
-/*
- * Return a string for the type
- */
-char *
-__p_type(type)
- int type;
-{
- switch (type) {
- case T_A:
- return("A");
- case T_NS: /* authoritative server */
- return("NS");
- case T_CNAME: /* canonical name */
- return("CNAME");
- case T_SOA: /* start of authority zone */
- return("SOA");
- case T_MB: /* mailbox domain name */
- return("MB");
- case T_MG: /* mail group member */
- return("MG");
- case T_MR: /* mail rename name */
- return("MR");
- case T_NULL: /* null resource record */
- return("NULL");
- case T_WKS: /* well known service */
- return("WKS");
- case T_PTR: /* domain name pointer */
- return("PTR");
- case T_HINFO: /* host information */
- return("HINFO");
- case T_MINFO: /* mailbox information */
- return("MINFO");
- case T_MX: /* mail routing info */
- return("MX");
- case T_TXT: /* text */
- return("TXT");
- case T_RP: /* responsible person */
- return("RP");
- case T_AFSDB: /* AFS cell database */
- return("AFSDB");
- case T_AXFR: /* zone transfer */
- return("AXFR");
- case T_MAILB: /* mail box */
- return("MAILB");
- case T_MAILA: /* mail address */
- return("MAILA");
- case T_ANY: /* matches any type */
- return("ANY");
- case T_UINFO:
- return("UINFO");
- case T_UID:
- return("UID");
- case T_GID:
- return("GID");
-#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- return("UNSPEC");
-#endif /* ALLOW_T_UNSPEC */
-
- default:
- (void)sprintf(nbuf, "%d", type);
- return(nbuf);
- }
-}
-
-/*
- * Return a mnemonic for class
- */
-char *
-__p_class(class)
- int class;
-{
-
- switch (class) {
- case C_IN: /* internet class */
- return("IN");
- case C_HS: /* hesiod class */
- return("HS");
- case C_ANY: /* matches any class */
- return("ANY");
- default:
- (void)sprintf(nbuf, "%d", class);
- return(nbuf);
- }
-}
-
-/*
- * Return a mnemonic for an option
- */
-static char *
-p_option(option)
- u_long option;
-{
- switch (option) {
- case RES_INIT: return "init";
- case RES_DEBUG: return "debug";
- case RES_AAONLY: return "aaonly";
- case RES_USEVC: return "usevc";
- case RES_PRIMARY: return "primry";
- case RES_IGNTC: return "igntc";
- case RES_RECURSE: return "recurs";
- case RES_DEFNAMES: return "defnam";
- case RES_STAYOPEN: return "styopn";
- case RES_DNSRCH: return "dnsrch";
- default: sprintf(nbuf, "?0x%x?", option); return nbuf;
- }
-}
-
-/*
- * Return a mnemonic for a time to live
- */
-char *
-__p_time(value)
- u_long value;
-{
- int secs, mins, hours, days;
- register char *p;
-
- if (value == 0) {
- strcpy(nbuf, "0 secs");
- return(nbuf);
- }
-
- secs = value % 60;
- value /= 60;
- mins = value % 60;
- value /= 60;
- hours = value % 24;
- value /= 24;
- days = value;
- value = 0;
-
-#define PLURALIZE(x) x, (x == 1) ? "" : "s"
- p = nbuf;
- if (days) {
- (void)sprintf(p, "%d day%s", PLURALIZE(days));
- while (*++p);
- }
- if (hours) {
- if (days)
- *p++ = ' ';
- (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
- while (*++p);
- }
- if (mins) {
- if (days || hours)
- *p++ = ' ';
- (void)sprintf(p, "%d min%s", PLURALIZE(mins));
- while (*++p);
- }
- if (secs || ! (days || hours || mins)) {
- if (days || hours || mins)
- *p++ = ' ';
- (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
- }
- return(nbuf);
-}
diff --git a/mit-pthreads/net/res_init.c b/mit-pthreads/net/res_init.c
deleted file mode 100644
index 0a5c944c974..00000000000
--- a/mit-pthreads/net/res_init.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_init.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <resolv.h>
-#include <netdb.h>
-#include "res_internal.h"
-
-int res_init()
-{
- if (_res_init()) {
- return 0;
- } else {
- /* Due to clever tricks in _res_init(), a check for h_errno will
- * return NO_RECOVERY even if the next try at initialization
- * succeeds, so it's okay that we can't set an error value here. */
- return -1;
- }
-}
-
diff --git a/mit-pthreads/net/res_internal.c b/mit-pthreads/net/res_internal.c
deleted file mode 100644
index 4eab65bf5aa..00000000000
--- a/mit-pthreads/net/res_internal.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <resolv.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include "res_internal.h"
-
-#define DEFAULT_RETRIES 4
-
-pthread_mutex_t host_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-static void _res_init_global(void);
-static void set_options(const char *options, const char *source);
-static pthread_ipaddr_type net_mask(struct in_addr in);
-static int qcomp(const void *arg1, const void *arg2);
-
-static struct __res_state start;
-/* We want to define _res for partial binary compatibility with libraries. */
-#undef _res
-struct __res_state _res = {
- RES_TIMEOUT, /* retransmition time interval */
- 4, /* number of times to retransmit */
- RES_DEFAULT, /* options flags */
- 1, /* number of name servers */
-};
-
-struct hostent *_res_parse_answer(querybuf *answer, int anslen, int iquery,
- struct hostent *result, char *buf,
- int bufsize, int *errval)
-{
- struct res_data *data = _res_init();
- register HEADER *hp;
- register u_char *cp;
- register int n;
- u_char *eom;
- char *aliases[__NETDB_MAXALIASES], *addrs[__NETDB_MAXADDRS];
- char *bp = buf, **ap = aliases, **hap = addrs;
- int type, class, ancount, qdcount, getclass = C_ANY, iquery_done = 0;
-
- eom = answer->buf + anslen;
- /*
- * find first satisfactory answer
- */
- hp = &answer->hdr;
- ancount = ntohs(hp->ancount);
- qdcount = ntohs(hp->qdcount);
- bp = buf;
- cp = answer->buf + sizeof(HEADER);
-
- /* Read in the hostname if this is an address lookup. */
- if (qdcount) {
- if (iquery) {
- if ((n = dn_expand((u_char *) answer->buf,
- (u_char *) eom, (u_char *) cp, (u_char *) bp,
- bufsize - (bp - buf))) < 0) {
- *errval = NO_RECOVERY;
- return ((struct hostent *) NULL);
- }
- cp += n + QFIXEDSZ;
- result->h_name = bp;
- bp += strlen(bp) + 1;
- } else {
- cp += __dn_skipname(cp, eom) + QFIXEDSZ;
- }
- while (--qdcount > 0)
- cp += __dn_skipname(cp, eom) + QFIXEDSZ;
- } else if (iquery) {
- *errval = (hp->aa) ? HOST_NOT_FOUND : TRY_AGAIN;
- return ((struct hostent *) NULL);
- }
-
- /* Read in the answers. */
- *ap = NULL;
- *hap = NULL;
- while (--ancount >= 0 && cp < eom) {
- if ((n = dn_expand((u_char *) answer->buf, (u_char *) eom,
- (u_char *) cp, (u_char *) bp,
- bufsize - (bp - buf))) < 0)
- break;
- cp += n;
- type = _getshort(cp);
- cp += sizeof(u_short);
- class = _getshort(cp);
- cp += sizeof(u_short) + sizeof(pthread_ipaddr_type);
- n = _getshort(cp);
- cp += sizeof(u_short);
- if (type == T_CNAME) {
- cp += n;
- if (ap >= aliases + __NETDB_MAXALIASES - 1)
- continue;
- *ap++ = bp;
- bp += strlen(bp) + 1;
- continue;
- }
- if (iquery && type == T_PTR) {
- if ((n = dn_expand((u_char *) answer->buf, (u_char *) eom,
- (u_char *) cp, (u_char *) bp,
- bufsize - (bp - buf))) < 0)
- break;
- cp += n;
- result->h_name = bp;
- bp += strlen(bp) + 1;
- iquery_done = 1;
- break;
- }
- if (iquery || type != T_A) {
-#ifdef DEBUG_RESOLVER
- if (data->state.options & RES_DEBUG)
- printf("unexpected answer type %d, size %d\n",
- type, n);
-#endif
- cp += n;
- continue;
- }
- if (hap > addrs) {
- if (n != result->h_length) {
- cp += n;
- continue;
- }
- if (class != getclass) {
- cp += n;
- continue;
- }
- } else {
- result->h_length = n;
- getclass = class;
- result->h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
- if (!iquery) {
- result->h_name = bp;
- bp += strlen(bp) + 1;
- }
- }
- bp = ALIGN(bp, pthread_ipaddr_type);
- if (bp + n >= buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
- memcpy(bp, cp, n);
- cp += n;
- if (hap >= addrs + __NETDB_MAXADDRS - 1)
- continue;
- *hap++ = bp;
- bp += n;
- cp += n;
- }
-
- if (hap > addrs || iquery_done) {
- *ap++ = NULL;
- *hap++ = NULL;
- if (data->state.nsort)
- qsort(addrs, hap - addrs, sizeof(struct in_addr), qcomp);
- if (SP(bp, char *, (hap - addrs) + (ap - aliases)) > buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
- result->h_addr_list = (char **) ALIGN(bp, char *);
- memcpy(result->h_addr_list, addrs, (hap - addrs) * sizeof(char *));
- result->h_aliases = result->h_addr_list + (hap - addrs);
- memcpy(result->h_aliases, aliases, (ap - aliases) * sizeof(char *));
- return result;
- } else {
- *errval = TRY_AGAIN;
- return NULL;
- }
-}
-
-/* Performs global initialization. */
-struct res_data *_res_init()
-{
- struct res_data *data;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _res_init_global);
- if (init_status < 0)
- return NULL;
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- data = (struct res_data *) pthread_getspecific(key);
- if (!data) {
- data = (struct res_data *) malloc(sizeof(struct res_data));
- if (data == NULL)
- return NULL;
- if (pthread_setspecific(key, data) < 0) {
- free(data);
- return NULL;
- }
- data->buf = NULL;
- data->state = start;
- data->errval = NO_RECOVERY;
- data->sock = -1;
- }
- return data;
-}
-
-static void _res_init_global()
-{
- int result;
- char line[BUFSIZ], buf[BUFSIZ], *domain, *p, *net;
- int i, localdomain_set = 0, num_servers = 0, num_sorts = 0;
- FILE *fp;
- struct in_addr addr;
-
- /* Assume an error state until we finish. */
- init_status = -1;
-
- /* Initialize the key for thread-specific data. */
- result = pthread_key_create(&key, free);
- if (result < 0)
- return;
-
- /* Initialize starting state. */
- start.retrans = RES_TIMEOUT;
- start.retry = DEFAULT_RETRIES;
- start.options = RES_DEFAULT;
- start.id = 0;
- start.nscount = 1;
- start.nsaddr.sin_addr.s_addr = INADDR_ANY;
- start.nsaddr.sin_family = AF_INET;
- start.nsaddr.sin_port = htons(NAMESERVER_PORT);
- start.nscount = 1;
- start.ndots = 1;
- start.pfcode = 0;
- strncpy(start.lookups, "f", sizeof(start.lookups));
-
- /* Look for a LOCALDOMAIN definition. */
- domain = getenv("LOCALDOMAIN");
- if (domain != NULL) {
- strncpy(start.defdname, domain, sizeof(start.defdname));
- domain = start.defdname;
- localdomain_set = 1;
-
- /* Construct a search path from the LOCALDOMAIN value, which is
- * a space-separated list of strings. For backwards-compatibility,
- * a newline terminates the list. */
- i = 0;
- while (*domain && i < MAXDNSRCH) {
- start.dnsrch[i] = domain;
- while (*domain && !isspace(*domain))
- domain++;
- if (!*domain || *domain == '\n') {
- *domain = 0;
- break;
- }
- *domain++ = 0;
- while (isspace(*domain))
- domain++;
- i++;
- }
- }
-
- /* Look for a config file and read it in. */
- fp = fopen(_PATH_RESCONF, "r");
- if (fp != NULL) {
- strncpy(start.lookups, "bf", sizeof(start.lookups));
-
- /* Read in the configuration file. */
- while (fgets(line, sizeof(line), fp)) {
-
- /* Ignore blank lines and comments. */
- if (*line == ';' || *line == '#' || !*line)
- continue;
-
- if (strncmp(line, "domain", 6) == 0) {
-
- /* Read in the default domain, and initialize a one-
- * element search path. Skip the domain line if we
- * already got one from the LOCALDOMAIN environment
- * variable. */
- if (localdomain_set)
- continue;
-
- /* Look for the next word in the line. */
- p = line + 6;
- while (*p == ' ' || *p == '\t')
- p++;
- if (!*p || *p == '\n')
- continue;
-
- /* Copy in the domain, and null-terminate it at the
- * first tab or newline. */
- strncpy(start.defdname, p, sizeof(start.defdname) - 1);
- p = strpbrk(start.defdname, "\t\n");
- if (p)
- *p = 0;
-
- start.dnsrch[0] = start.defdname;
- start.dnsrch[1] = NULL;
-
- } else if (strncmp(line, "lookup", 6) == 0) {
-
- /* Get a list of lookup types. */
- memset(start.lookups, 0, sizeof(start.lookups));
-
- /* Find the next word in the line. */
- p = line + 6;
- while (isspace(*p))
- p++;
-
- i = 0;
- while (*p && i < MAXDNSLUS) {
- /* Add a lookup type. */
- if (*p == 'y' || *p == 'b' || *p == 'f')
- start.lookups[i++] = *p;
-
- /* Find the next word. */
- while (*p && !isspace(*p))
- p++;
- while (isspace(*p))
- p++;
- }
-
- } else if (strncmp(line, "search", 6) == 0) {
-
- /* Read in a space-separated list of domains to search
- * when a name is not fully-qualified. Skip this line
- * if the LOCALDOMAIN environment variable was set. */
- if (localdomain_set)
- continue;
-
- /* Look for the next word on the line. */
- p = line + 6;
- while (*p == ' ' || *p == '\t')
- p++;
- if (!*p || *p == '\n')
- continue;
-
- /* Copy the rest of the line into start.defdname. */
- strncpy(start.defdname, p, sizeof(start.defdname) - 1);
- domain = start.defdname;
- p = strchr(domain, '\n');
- if (*p)
- *p = 0;
-
- /* Construct a search path from the line, which is a
- * space-separated list of strings. */
- i = 0;
- while (*domain && i < MAXDNSRCH) {
- start.dnsrch[i] = domain;
- while (*domain && !isspace(*domain))
- domain++;
- if (!*domain || *domain == '\n') {
- *domain = 0;
- break;
- }
- *domain++ = 0;
- while (isspace(*domain))
- domain++;
- i++;
- }
-
- } else if (strncmp(line, "nameserver", 10) == 0) {
-
- /* Add an address to the list of name servers we can
- * connect to. */
-
- /* Look for the next word in the line. */
- p = line + 10;
- while (*p == ' ' || *p == '\t')
- p++;
- if (*p && *p != '\n' && inet_aton(p, &addr)) {
- start.nsaddr_list[num_servers].sin_addr = addr;
- start.nsaddr_list[num_servers].sin_family = AF_INET;
- start.nsaddr_list[num_servers].sin_port =
- htons(NAMESERVER_PORT);
- if (++num_servers >= MAXNS)
- break;
- }
-
- } else if (strncmp(line, "sortlist", 8) == 0) {
-
- p = line + 8;
- while (num_sorts < MAXRESOLVSORT) {
-
- /* Find the next word in the line. */
- p = line + 8;
- while (*p == ' ' || *p == '\t')
- p++;
-
- /* Read in an IP address and netmask. */
- if (sscanf(p, "%[0-9./]s", buf) != 1)
- break;
- net = strchr(buf, '/');
- if (net)
- *net = 0;
-
- /* Translate the address into an IP address
- * and netmask. */
- if (inet_aton(buf, &addr)) {
- start.sort_list[num_sorts].addr = addr;
- if (net && inet_aton(net + 1, &addr)) {
- start.sort_list[num_sorts].mask = addr.s_addr;
- } else {
- start.sort_list[num_sorts].mask =
- net_mask(start.sort_list[num_sorts].addr);
- }
- num_sorts++;
- }
-
- /* Skip past this word. */
- if (net)
- *net = '/';
- p += strlen(buf);
- }
-
- }
- }
- fclose(fp);
- }
-
- /* If we don't have a default domain, strip off the first
- * component of this machine's domain name, and make a one-
- * element search path consisting of the default domain. */
- if (*start.defdname == 0) {
- if (gethostname(buf, sizeof(start.defdname) - 1) == 0) {
- p = strchr(buf, '.');
- if (p)
- strcpy(start.defdname, p + 1);
- }
- start.dnsrch[0] = start.defdname;
- start.dnsrch[1] = NULL;
- }
-
- p = getenv("RES_OPTIONS");
- if (p)
- set_options(p, "env");
-
- start.options |= RES_INIT;
- _res = start;
- init_status = 0;
-}
-
-static void set_options(const char *options, const char *source)
-{
- const char *p = options;
- int i;
-
- while (*p) {
-
- /* Skip leading and inner runs of spaces. */
- while (*p == ' ' || *p == '\t')
- p++;
-
- /* Search for and process individual options. */
- if (strncmp(p, "ndots:", 6) == 0) {
- i = atoi(p + 6);
- start.ndots = (i <= RES_MAXNDOTS) ? i : RES_MAXNDOTS;
- } else if (!strncmp(p, "debug", 5))
- start.options |= RES_DEBUG;
- else if (!strncmp(p, "usevc", 5))
- start.options |= RES_USEVC;
- else if (!strncmp(p, "stayopen", 8))
- start.options |= RES_STAYOPEN;
-
- /* Skip to next run of spaces */
- while (*p && *p != ' ' && *p != '\t')
- p++;
- }
-}
-
-static pthread_ipaddr_type net_mask(struct in_addr in)
-{
- pthread_ipaddr_type i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return htonl(IN_CLASSA_NET);
- if (IN_CLASSB(i))
- return htonl(IN_CLASSB_NET);
- return htonl(IN_CLASSC_NET);
-}
-
-/* Get the error value for this thread, or NO_RECOVERY if none has been
- * successfully set. The screw case to worry about here is if
- * __res_init() fails for a resolver routine because it can't allocate
- * or set the thread-specific data, and then __res_init() succeeds here.
- * Because __res_init() sets errval to NO_RECOVERY after a successful
- * initialization, we return NO_RECOVERY in that case, which is correct. */
-int _res_get_error()
-{
- struct res_data *data;
-
- data = _res_init();
- return (data) ? data->errval : NO_RECOVERY;
-}
-
-struct __res_state *_res_status()
-{
- struct res_data *data;
-
- data = _res_init();
- return (data) ? &data->state : NULL;
-}
-
-static int qcomp(const void *arg1, const void *arg2)
-{
- const struct in_addr **a1 = (const struct in_addr **) arg1;
- const struct in_addr **a2 = (const struct in_addr **) arg2;
- struct __res_state *state = _res_status();
-
- int pos1, pos2;
-
- for (pos1 = 0; pos1 < state->nsort; pos1++) {
- if (state->sort_list[pos1].addr.s_addr ==
- ((*a1)->s_addr & state->sort_list[pos1].mask))
- break;
- }
- for (pos2 = 0; pos2 < state->nsort; pos2++) {
- if (state->sort_list[pos2].addr.s_addr ==
- ((*a2)->s_addr & state->sort_list[pos2].mask))
- break;
- }
- return pos1 - pos2;
-}
-
-/*
- * This routine is for closing the socket if a virtual circuit is used and
- * the program wants to close it. We don't use this routine, but libc
- * might reference it.
- *
- * This routine is not expected to be user visible.
- */
-void _res_close()
-{
- struct res_data *data;
-
- data = _res_init();
- if (data && data->sock != -1) {
- (void) close(data->sock);
- data->sock = -1;
- }
-}
diff --git a/mit-pthreads/net/res_internal.h b/mit-pthreads/net/res_internal.h
deleted file mode 100644
index 24e70278644..00000000000
--- a/mit-pthreads/net/res_internal.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _RES_INTERNAL_H
-#define _RES_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define HOST_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-struct res_data {
- char *buf;
- struct __res_state state;
- int errval;
- int sock;
-};
-
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
-
-typedef union {
- HEADER hdr;
- unsigned char buf[MAXPACKET];
-} querybuf;
-
-typedef union {
- long al;
- char ac;
-} align;
-
-extern pthread_mutex_t host_iterate_lock;
-
-__BEGIN_DECLS
-struct hostent *_res_parse_answer(querybuf *answer, int anslen, int iquery,
- struct hostent *result, char *buf,
- int buflen, int *errval);
-void _res_set_error(int val);
-struct res_data *_res_init(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/net/res_mkquery.c b/mit-pthreads/net/res_mkquery.c
deleted file mode 100644
index 42f27318368..00000000000
--- a/mit-pthreads/net/res_mkquery.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_mkquery.c 6.16 (Berkeley) 3/6/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <sys/cdefs.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <string.h>
-
-/*
- * Form all types of queries.
- * Returns the size of the result or -1.
- */
-res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
- int op; /* opcode of query */
- const char *dname; /* domain name */
- int class, type; /* class and type of query */
- const char *data; /* resource record data */
- int datalen; /* length of data */
- const char *newrr_in; /* new rr for modify or append */
- char *buf; /* buffer to put query */
- int buflen; /* size of buffer */
-{
- register HEADER *hp;
- register char *cp;
- register int n;
- struct rrec *newrr = (struct rrec *) newrr_in;
- char *dnptrs[10], **dpp, **lastdnptr;
- struct __res_state *_rs;
-
- /*
- * Initialize header fields.
- */
-
- _rs = _res_status();
- if (!_rs)
- return -1;
- if ((buf == NULL) || (buflen < sizeof(HEADER)))
- return(-1);
- memset(buf, 0, sizeof(HEADER));
- hp = (HEADER *) buf;
- hp->id = htons(++_rs->id);
- hp->opcode = op;
- hp->pr = (_rs->options & RES_PRIMARY) != 0;
- hp->rd = (_rs->options & RES_RECURSE) != 0;
- hp->rcode = NOERROR;
- cp = buf + sizeof(HEADER);
- buflen -= sizeof(HEADER);
- dpp = dnptrs;
- *dpp++ = buf;
- *dpp++ = NULL;
- lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
- /*
- * perform opcode specific processing
- */
- switch (op) {
- case QUERY:
- if ((buflen -= QFIXEDSZ) < 0)
- return(-1);
- if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
- (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
- return (-1);
- cp += n;
- buflen -= n;
- __putshort(type, (u_char *)cp);
- cp += sizeof(u_short);
- __putshort(class, (u_char *)cp);
- cp += sizeof(u_short);
- hp->qdcount = htons(1);
- if (op == QUERY || data == NULL)
- break;
- /*
- * Make an additional record for completion domain.
- */
- buflen -= RRFIXEDSZ;
- if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
- (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
- return (-1);
- cp += n;
- buflen -= n;
- __putshort(T_NULL, (u_char *)cp);
- cp += sizeof(u_short);
- __putshort(class, (u_char *)cp);
- cp += sizeof(u_short);
- __putlong(0, (u_char *)cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(0, (u_char *)cp);
- cp += sizeof(u_short);
- hp->arcount = htons(1);
- break;
-
- case IQUERY:
- /*
- * Initialize answer section
- */
- if (buflen < 1 + RRFIXEDSZ + datalen)
- return (-1);
- *cp++ = '\0'; /* no domain name */
- __putshort(type, (u_char *)cp);
- cp += sizeof(u_short);
- __putshort(class, (u_char *)cp);
- cp += sizeof(u_short);
- __putlong(0, (u_char *)cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(datalen, (u_char *)cp);
- cp += sizeof(u_short);
- if (datalen) {
- memcpy(cp, data, datalen);
- cp += datalen;
- }
- hp->ancount = htons(1);
- break;
-
-#ifdef ALLOW_UPDATES
- /*
- * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
- * (Record to be modified is followed by its replacement in msg.)
- */
- case UPDATEM:
- case UPDATEMA:
-
- case UPDATED:
- /*
- * The res code for UPDATED and UPDATEDA is the same; user
- * calls them differently: specifies data for UPDATED; server
- * ignores data if specified for UPDATEDA.
- */
- case UPDATEDA:
- buflen -= RRFIXEDSZ + datalen;
- if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
- return (-1);
- cp += n;
- __putshort(type, cp);
- cp += sizeof(u_short);
- __putshort(class, cp);
- cp += sizeof(u_short);
- __putlong(0, cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(datalen, cp);
- cp += sizeof(u_short);
- if (datalen) {
- memcpy(cp, data, datalen);
- cp += datalen;
- }
- if ( (op == UPDATED) || (op == UPDATEDA) ) {
- hp->ancount = htons(0);
- break;
- }
- /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
-
- case UPDATEA: /* Add new resource record */
- buflen -= RRFIXEDSZ + datalen;
- if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
- return (-1);
- cp += n;
- __putshort(newrr->r_type, cp);
- cp += sizeof(u_short);
- __putshort(newrr->r_class, cp);
- cp += sizeof(u_short);
- __putlong(0, cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(newrr->r_size, cp);
- cp += sizeof(u_short);
- if (newrr->r_size) {
- memcpy(cp, newrr->r_data, newrr->r_size);
- cp += newrr->r_size;
- }
- hp->ancount = htons(0);
- break;
-
-#endif /* ALLOW_UPDATES */
- }
- return (cp - buf);
-}
-
diff --git a/mit-pthreads/net/res_query.c b/mit-pthreads/net/res_query.c
deleted file mode 100644
index 1727e6d1179..00000000000
--- a/mit-pthreads/net/res_query.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_query.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <resolv.h>
-#include <netdb.h>
-#include "res_internal.h"
-
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
-
-int res_query(char *name, int class, int type, unsigned char *answer,
- int anslen)
-{
- struct res_data *data;
- char buf[MAXPACKET];
- int result;
- HEADER *hp;
-
- data = _res_init();
- if (!data)
- return -1;
-
- /* Make the query. */
- result = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf,
- sizeof(buf));
- if (result <= 0) {
- data->errval = NO_RECOVERY;
- return result;
- }
-
- result = res_send(buf, result, (char *) answer, anslen);
- if (result < 0) {
- data->errval = TRY_AGAIN;
- return result;
- }
-
- hp = (HEADER *) answer;
- if (hp->rcode == NOERROR && ntohs(hp->ancount) != 0)
- return result;
-
- /* Translate the error code and return. */
- switch(hp->rcode) {
- case NOERROR:
- data->errval = NO_DATA;
- break;
- case SERVFAIL:
- data->errval = TRY_AGAIN;
- break;
- case NXDOMAIN:
- data->errval = HOST_NOT_FOUND;
- break;
- default:
- data->errval = NO_RECOVERY;
- break;
- }
- return -1;
-}
-
diff --git a/mit-pthreads/net/res_querydomain.c b/mit-pthreads/net/res_querydomain.c
deleted file mode 100644
index 31beeb7a62c..00000000000
--- a/mit-pthreads/net/res_querydomain.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_querydomain.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <resolv.h>
-#include <string.h>
-
-/* For backwards compatibility. */
-int res_querydomain(char *name, char *domain, int class, int type,
- unsigned char *answer, int anslen)
-{
- char buf[2 * MAXDNAME + 2];
- char *longname = buf;
- int len;
-
- if (domain == NULL) {
- /* Check for trailing '.'; copy without '.' if present. */
- len = strlen(name);
- if (len > 0 && name[len - 1] == '.' && len < sizeof(buf)) {
- memcpy(buf, name, len - 1);
- buf[len - 1] = '\0';
- } else {
- longname = name;
- }
- } else {
- sprintf(buf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
- }
-
- return (res_query(longname, class, type, answer, anslen));
-}
-
diff --git a/mit-pthreads/net/res_search.c b/mit-pthreads/net/res_search.c
deleted file mode 100644
index 2c84f0d68f3..00000000000
--- a/mit-pthreads/net/res_search.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_search.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <resolv.h>
-#include <netdb.h>
-#include "res_internal.h"
-
-static char *search_aliases(const char *name, char *buf, int bufsize);
-
-int res_search(const char *name, int class, int type, unsigned char *answer,
- int anslen)
-{
- struct res_data *data;
- const char *p;
- int num_dots, len, result, no_data = 0, error;
- char buf[2 * MAXDNAME + 2], *domain, **dptr, *alias;
-
- data = _res_init();
- if (!data)
- return -1;
-
- /* Count the dots in name, and get a pointer to the end of name. */
- num_dots = 0;
- for (p = name; *p; p++) {
- if (*p == '.')
- num_dots++;
- }
- len = p - name;
-
- /* If there aren't any dots, check to see if name is an alias for
- * another host. If so, try the resolved alias as a fully-qualified
- * name. */
- alias = search_aliases(name, buf, sizeof(buf));
- if (alias != NULL)
- return res_query(alias, class, type, answer, anslen);
-
- /* If there's a trailing dot, try to strip it off and query the name. */
- if (len > 0 && p[-1] == '.') {
- if (len > sizeof(buf)) {
- /* It's too long; just query the original name. */
- return res_query(name, class, type, answer, anslen);
- } else {
- /* Copy the name without the trailing dot and query. */
- memcpy(buf, name, len - 1);
- buf[len] = 0;
- return res_query(buf, class, type, answer, anslen);
- }
- }
-
- if (data->state.options & RES_DNSRCH) {
- /* If RES_DNSRCH is set, query all the domains until we get a
- * definitive answer. */
- for (dptr = data->state.dnsrch; *dptr; dptr++) {
- domain = *dptr;
- sprintf(buf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
- result = res_query(buf, class, type, answer, anslen);
- if (result > 0)
- return result;
- if (data->errval == NO_DATA)
- no_data = 1;
- else if (data->errval != HOST_NOT_FOUND)
- break;
- }
- } else if (num_dots == 0 && data->state.options & RES_DEFNAMES) {
- /* If RES_DEFNAMES is set and there is no dot, query the default
- * domain. */
- domain = data->state.defdname;
- sprintf(buf, "%.*s.%.%s", MAXDNAME, name, MAXDNAME, domain);
- result = res_query(buf, class, type, answer, anslen);
- if (result > 0)
- return result;
- if (data->errval == NO_DATA)
- no_data = 1;
- }
-
- /* If all the domain queries failed, try the name as fully-qualified.
- * Only do this if there is at least one dot in the name. */
- if (num_dots > 0) {
- result = res_query(name, class, type, answer, anslen);
- if (result > 0)
- return result;
- }
-
- if (no_data)
- data->errval = NO_DATA;
-
- return -1;
-}
-
-static char *search_aliases(const char *name, char *buf, int bufsize)
-{
- FILE *fp;
- char *filename, *p;
- int len;
-
- filename = getenv("HOSTALIASES");
- if (filename == NULL)
- return NULL;
-
- fp = fopen(filename, "r");
- if (fp == NULL)
- return NULL;
-
- len = strlen(name);
- while (fgets(buf, bufsize, fp)) {
-
- /* Get the first word from the buffer. */
- p = buf;
- while (*p && !isspace(*p))
- p++;
- if (!*p)
- break;
-
- /* Null-terminate the first word and compare it with the name. */
- *p = 0;
- if (strcasecmp(buf, name) != 0)
- continue;
-
- p++;
- while (isspace(*p))
- p++;
- fclose(fp);
- return (*p) ? p : NULL;
- }
-
- fclose(fp);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/res_send.c b/mit-pthreads/net/res_send.c
deleted file mode 100644
index 84162e8e387..00000000000
--- a/mit-pthreads/net/res_send.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_send.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-#include <resolv.h>
-#include <netdb.h>
-#include <time.h>
-#include <sys/timers.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include "res_internal.h"
-
-enum { SEND_GIVE_UP = -1, SEND_TRY_NEXT = -2, SEND_TRY_SAME = -3,
- SEND_TIMEOUT = -4, SEND_TRUNCATED = -5 };
-
-static int send_datagram(int server, int sock, const char *buf, int buflen,
- char *answer, int anslen, int try,
- struct res_data *data);
-static int send_circuit(int server, const char *buf, int buflen, char *answer,
- int anslen, struct res_data *data);
-static int close_save_errno(int sock);
-
-int res_send(const char *buf, int buflen, char *answer, int anslen)
-{
- struct res_data *data;
- struct sockaddr_in local;
- int use_virtual_circuit, result, udp_sock, have_seen_same, terrno = 0;
- int try, server;
-
- data = _res_init();
- if (!data)
- return -1;
-
- try = 0;
- server = 0;
-
- /* Try doing connectionless queries if appropriate. */
- if (!(data->state.options & RES_USEVC) && buflen <= PACKETSZ) {
- /* Create and bind a local UDP socket. */
- udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (udp_sock < 0)
- return -1;
- local.sin_family = AF_INET;
- local.sin_addr.s_addr = htonl(INADDR_ANY);
- local.sin_port = htons(0);
- if (bind(udp_sock, (struct sockaddr *) &local, sizeof(local)) < 0) {
- close(udp_sock);
- return -1;
- }
-
- /* Cycle through the retries and servers, sending off queries and
- * waiting for responses. */
- for (; try < data->state.retry; try++) {
- for (; server < data->state.nscount; server++) {
- result = send_datagram(server, udp_sock, buf, buflen, answer,
- anslen, try, data);
- if (result == SEND_TIMEOUT)
- terrno = ETIMEDOUT;
- else if (result != SEND_TRY_NEXT)
- break;
- }
- if (server < data->state.nscount)
- break;
- }
-
- close(udp_sock);
- if (result < 0)
- errno = (terrno == ETIMEDOUT) ? ETIMEDOUT : ECONNREFUSED;
- else
- errno = 0;
- if (result != SEND_TRUNCATED)
- return (result >= 0) ? result : -1;
- }
-
- /* Either we have to use the virtual circuit, or the server couldn't
- * fit its response in a UDP packet. Cycle through the retries and
- * servers, sending off queries and waiting for responses. Allow a
- * response of SEND_TRY_SAME to cause an extra retry once. */
- for (; try < data->state.retry; try++) {
- for (; server < data->state.nscount; server++) {
- result = send_circuit(server, buf, buflen, answer, anslen, data);
- terrno = errno;
- if (result == SEND_TRY_SAME) {
- if (!have_seen_same)
- server--;
- have_seen_same = 1;
- } else if (result != SEND_TRY_NEXT) {
- break;
- }
- }
- }
-
- errno = terrno;
- return (result >= 0) ? result : -1;
-}
-
-static int send_datagram(int server, int sock, const char *buf, int buflen,
- char *answer, int anslen, int try,
- struct res_data *data)
-{
- int count, interval;
- struct sockaddr_in local_addr;
- HEADER *request = (HEADER *) buf, *response = (HEADER *) answer;
- struct timespec timeout;
- struct timeval current;
- struct timezone zone;
-
-#ifdef DEBUG_RESOLVER
- if (_res.options & RES_DEBUG) {
- printf("res_send: request:\n");
- __p_query(buf);
- }
-#endif /* DEBUG_RESOLVER */
- /* Send a packet to the server. */
- count = sendto(sock, buf, buflen, 0,
- (struct sockaddr *) &data->state.nsaddr_list[server],
- sizeof(struct sockaddr_in));
-
- if (count != buflen) {
-#ifdef DEBUG_RESOLVER
- if (count < 0){
- if (_res.options & RES_DEBUG)
- perror("send_datagram:sendto");
- }
-#endif /* DEBUG_RESOLVER */
- return SEND_TRY_NEXT;
- }
-
- /* Await a reply with the correct ID. */
- while (1) {
- struct sockaddr_in from;
- int from_len;
-
- from_len = sizeof(from);
- interval = data->state.retrans << try;
- if (try > 0)
- interval /= data->state.nscount;
- gettimeofday(&current, &zone);
- current.tv_sec += interval;
- TIMEVAL_TO_TIMESPEC(&current, &timeout);
- count = recvfrom_timedwait(sock, answer, anslen, 0,
- &from, &from_len, &timeout);
- if (count < 0)
- return SEND_TRY_NEXT;
- /* If the ID is wrong, it's from an old query; ignore it. */
- if (response->id == request->id)
- break;
-#ifdef DEBUG_RESOLVER
- if (_res.options & RES_DEBUG) {
- printf("res_sendto: count=%d, response:\n", count);
- __p_query(answer);
- }
-#endif /* DEBUG_RESOLVER */
- }
-
- /* Report a truncated response unless RES_IGNTC is set. This will
- * cause the res_send() loop to fall back to TCP. */
- if (response->tc && !(data->state.options & RES_IGNTC))
- return SEND_TRUNCATED;
-
- return count;
-}
-
-static int send_circuit(int server, const char *buf, int buflen, char *answer,
- int anslen, struct res_data *data)
-{
- HEADER *response = (HEADER *) answer;
- int sock = -1, result, n, response_len, count;
- unsigned short len;
- struct iovec iov[2];
- char *p, junk[512];
-
- /* If data->sock is valid, then it's an open connection to the
- * first server. Grab it if it's appropriate; close it if not. */
- if (data->sock) {
- if (server == 0)
- sock = data->sock;
- else
- close(data->sock);
- data->sock = -1;
- }
-
- /* Initialize our socket if we didn't grab it from data. */
- if (sock == -1) {
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- return SEND_GIVE_UP;
- result = connect(sock,
- (struct sockaddr *) &data->state.nsaddr_list[server],
- sizeof(struct sockaddr_in));
- if (result < 0) {
- close_save_errno(sock);
- return SEND_TRY_NEXT;
- }
- }
-
- /* Send length and message. */
- len = htons((unsigned short) buflen);
- iov[0].iov_base = (caddr_t) &len;
- iov[0].iov_len = sizeof(len);
- iov[1].iov_base = (char *) buf;
- iov[1].iov_len = buflen;
- if (writev(sock, iov, 2) != sizeof(len) + buflen) {
- close_save_errno(sock);
- return SEND_TRY_NEXT;
- }
-
- /* Receive length. */
- p = (char *) &len;
- n = sizeof(len);
- while (n) {
- count = read(sock, p, n);
- if (count <= 0) {
- /* If we got ECONNRESET, the remote server may have restarted,
- * and we report SEND_TRY_SAME. (The main loop will only
- * allow one of these, so we don't have to worry about looping
- * indefinitely.) */
- close_save_errno(sock);
- return (errno == ECONNRESET) ? SEND_TRY_SAME : SEND_TRY_NEXT;
- }
- p += count;
- n -= count;
- }
- len = ntohs(len);
- response_len = (len > anslen) ? anslen : len;
- len -= response_len;
-
- /* Receive message. */
- p = answer;
- n = response_len;
- while (n) {
- count = read(sock, p, n);
- if (count <= 0) {
- close_save_errno(sock);
- return SEND_TRY_NEXT;
- }
- p += count;
- n -= count;
- }
-
- /* If the reply is longer than our answer buffer, set the truncated
- * bit and flush the rest of the reply, to keep the connection in
- * sync. */
- if (len) {
- response->tc = 1;
- while (len) {
- n = (len > sizeof(junk)) ? sizeof(junk) : len;
- count = read(sock, junk, n);
- if (count <= 0) {
- close_save_errno(sock);
- return response_len;
- }
- len -= count;
- }
- }
-
- /* If this is the first server, and RES_USEVC and RES_STAYOPEN are
- * both set, save the connection. Otherwise, close it. */
- if (server == 0 && (data->state.options & RES_USEVC &&
- data->state.options & RES_STAYOPEN))
- data->sock = sock;
- else
- close_save_errno(sock);
-
- return response_len;
-}
-
-static int close_save_errno(int sock)
-{
- int terrno;
-
- terrno = errno;
- close(sock);
- errno = terrno;
-}
diff --git a/mit-pthreads/net/serv_internal.c b/mit-pthreads/net/serv_internal.c
deleted file mode 100644
index f4acc8697ae..00000000000
--- a/mit-pthreads/net/serv_internal.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)serv_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "serv_internal.h"
-
-#define DEFAULT_RETRIES 4
-
-static void _serv_init_global();
-
-pthread_mutex_t serv_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-/* Performs global initialization. */
-char *_serv_buf()
-{
- char *buf;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _serv_init_global);
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- buf = (char *) pthread_getspecific(key);
- if (!buf) {
- buf = (char *) malloc(sizeof(struct servent) + SERV_BUFSIZE);
- if (buf == NULL)
- return NULL;
- if (pthread_setspecific(key, buf) < 0) {
- free(buf);
- return NULL;
- }
- }
- return buf;
-}
-
-static void _serv_init_global()
-{
- init_status = pthread_key_create(&key, free);
-}
-
diff --git a/mit-pthreads/net/serv_internal.h b/mit-pthreads/net/serv_internal.h
deleted file mode 100644
index 60a7c02c2ea..00000000000
--- a/mit-pthreads/net/serv_internal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)serv_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _SERV_INTERNAL_H
-#define _SERV_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define SERV_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-extern pthread_mutex_t serv_iterate_lock;
-
-__BEGIN_DECLS
-char *_serv_buf(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/patches/Streepy.html b/mit-pthreads/patches/Streepy.html
deleted file mode 100755
index a3b4faa815f..00000000000
--- a/mit-pthreads/patches/Streepy.html
+++ /dev/null
@@ -1,2873 +0,0 @@
-diff -c -r1.1.1.1 pthread.h
-*** pthread.h 1996/03/13 04:30:57 1.1.1.1
---- pthread.h 1996/10/02 17:52:47
-***************
-*** 35,40 ****
---- 35,43 ----
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
-+ *
-+ * 93/9/28 streepy - Added support for pthread cancel
-+ *
- */
-
- #ifndef _PTHREAD_H_
-***************
-*** 65,70 ****
---- 68,82 ----
- /* More includes, that need size_t */
- #include <pthread/pthread_attr.h>
-
-+ /* Constants for use with pthread_setcancelstate and pthread_setcanceltype */
-+ #define PTHREAD_CANCEL_DISABLE 0
-+ #define PTHREAD_CANCEL_ENABLE 1
-+ #define PTHREAD_CANCEL_DEFERRED 0
-+ #define PTHREAD_CANCEL_ASYNCHRONOUS 1
-+
-+ #define PTHREAD_CANCELLED (void *)1 /* Exit status of a cancelled thread */
-+
-+
- #ifdef PTHREAD_KERNEL
-
- #include <signal.h> /* for sigset_t */
-***************
-*** 78,120 ****
- PS_STATE_MAX
- };
-
-- #define PF_WAIT_EVENT 0x01
-- #define PF_DONE_EVENT 0x02
--
- /* Put PANIC inside an expression that evaluates to non-void type, to
- make it easier to combine it in expressions. */
-! #define DO_PANIC() (PANIC (), 0)
-! #define PANICIF(x) ((x) ? DO_PANIC () : 0)
-
-! #define SET_PF_DONE_EVENT(x) \
-! ( !(x->flags & PF_DONE_EVENT) \
-! ? ( (x->flags & PF_WAIT_EVENT) \
-! ? (x->flags = PF_DONE_EVENT, OK) \
-! : DO_PANIC ()) \
- : NOTOK )
-
-! #define SET_PF_WAIT_EVENT(x) \
-! ( PANICIF (x->flags & (PF_WAIT_EVENT | PF_DONE_EVENT)), \
-! (x->flags = PF_WAIT_EVENT), 0)
-!
-! #define CLEAR_PF_DONE_EVENT(x) \
-! ( PANICIF (!(x->flags & PF_DONE_EVENT)), \
-! x->flags = 0 )
-
- struct pthread_select_data {
-! int nfds;
-! fd_set readfds;
-! fd_set writefds;
-! fd_set exceptfds;
- };
-
- union pthread_wait_data {
-! pthread_mutex_t * mutex;
-! pthread_cond_t * cond;
-! const sigset_t * sigwait; /* Waiting on a signal in sigwait */
- struct {
-! short fd; /* Used when thread waiting on fd */
-! short branch; /* line number, for debugging */
- } fd;
- struct pthread_select_data * select_data;
- };
---- 90,185 ----
- PS_STATE_MAX
- };
-
- /* Put PANIC inside an expression that evaluates to non-void type, to
- make it easier to combine it in expressions. */
-! #define DO_PANIC() (PANIC (), 0)
-! #define PANICIF(x) ((x) ? DO_PANIC () : 0)
-!
-! /* In the thread flag field, we use a series of bit flags. Flags can
-! * organized into "groups" of mutually exclusive flags. Other flags
-! * are unrelated and can be set and cleared with a single bit operation.
-! */
-
-! #define PF_WAIT_EVENT 0x01
-! #define PF_DONE_EVENT 0x02
-! #define PF_EVENT_GROUP 0x03 /* All event bits */
-!
-! #define PF_CANCEL_STATE 0x04 /* cancellability state */
-! #define PF_CANCEL_TYPE 0x08 /* cancellability type */
-! #define PF_THREAD_CANCELLED 0x10 /* thread has been cancelled */
-! #define PF_RUNNING_TO_CANCEL 0x20 /* Thread is running so it can cancel*/
-! #define PF_AT_CANCEL_POINT 0x40 /* Thread is at a cancel point */
-!
-! /* Flag operations */
-!
-! #define SET_PF_FLAG(x,f) ( (x)->flags |= (f) )
-! #define TEST_PF_FLAG(x,f) ( (x)->flags & (f) )
-! #define CLEAR_PF_FLAG(x,f) ( (x)->flags &= ~(f) )
-! #define CLEAR_PF_GROUP(x,g) ( (x)->flags &= ~(g) )
-! #define SET_PF_FLAG_IN_GROUP(x,g,f) ( CLEAR_PF_GROUP(x,g),SET_PF_FLAG(x,f))
-! #define TEST_PF_GROUP(x,g) ( (x)->flags & (g) )
-!
-! #define SET_PF_DONE_EVENT(x) \
-! ( !TEST_PF_FLAG(x,PF_DONE_EVENT) \
-! ? ( TEST_PF_FLAG(x,PF_WAIT_EVENT) \
-! ? (SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_DONE_EVENT), OK) \
-! : DO_PANIC ()) \
- : NOTOK )
-
-! #define SET_PF_WAIT_EVENT(x) \
-! ( PANICIF (TEST_PF_GROUP(x,PF_EVENT_GROUP) ), \
-! SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_WAIT_EVENT), 0)
-!
-! #define CLEAR_PF_DONE_EVENT(x) \
-! ( PANICIF (!TEST_PF_FLAG(x,PF_DONE_EVENT)), \
-! CLEAR_PF_GROUP(x,PF_EVENT_GROUP) )
-!
-! #define SET_PF_CANCELLED(x) ( SET_PF_FLAG(x,PF_THREAD_CANCELLED) )
-! #define TEST_PF_CANCELLED(x) ( TEST_PF_FLAG(x,PF_THREAD_CANCELLED) )
-!
-! #define SET_PF_RUNNING_TO_CANCEL(x) ( SET_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-! #define CLEAR_PF_RUNNING_TO_CANCEL(x)( CLEAR_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-! #define TEST_PF_RUNNING_TO_CANCEL(x)( TEST_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-!
-! #define SET_PF_AT_CANCEL_POINT(x) ( SET_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-! #define CLEAR_PF_AT_CANCEL_POINT(x) ( CLEAR_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-! #define TEST_PF_AT_CANCEL_POINT(x) ( TEST_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-!
-! #define SET_PF_CANCEL_STATE(x,f) \
-! ( (f) ? SET_PF_FLAG(x,PF_CANCEL_STATE) : CLEAR_PF_FLAG(x,PF_CANCEL_STATE) )
-! #define TEST_PF_CANCEL_STATE(x) \
-! ( (TEST_PF_FLAG(x,PF_CANCEL_STATE)) ? PTHREAD_CANCEL_ENABLE \
-! : PTHREAD_CANCEL_DISABLE )
-!
-! #define SET_PF_CANCEL_TYPE(x,f) \
-! ( (f) ? SET_PF_FLAG(x,PF_CANCEL_TYPE) : CLEAR_PF_FLAG(x,PF_CANCEL_TYPE) )
-! #define TEST_PF_CANCEL_TYPE(x) \
-! ( (TEST_PF_FLAG(x,PF_CANCEL_TYPE)) ? PTHREAD_CANCEL_ASYNCHRONOUS \
-! : PTHREAD_CANCEL_DEFERRED )
-!
-! /* See if a thread is in a state that it can be cancelled */
-! #define TEST_PTHREAD_IS_CANCELLABLE(x) \
-! ( (TEST_PF_CANCEL_STATE(x) == PTHREAD_CANCEL_ENABLE && TEST_PF_CANCELLED(x)) \
-! ? ((TEST_PF_CANCEL_TYPE(x) == PTHREAD_CANCEL_ASYNCHRONOUS) \
-! ? 1 \
-! : TEST_PF_AT_CANCEL_POINT(x)) \
-! : 0 )
-!
-
- struct pthread_select_data {
-! int nfds;
-! fd_set readfds;
-! fd_set writefds;
-! fd_set exceptfds;
- };
-
- union pthread_wait_data {
-! pthread_mutex_t * mutex;
-! pthread_cond_t * cond;
-! const sigset_t * sigwait; /* Waiting on a signal in sigwait */
- struct {
-! short fd; /* Used when thread waiting on fd */
-! short branch; /* line number, for debugging */
- } fd;
- struct pthread_select_data * select_data;
- };
-***************
-*** 122,143 ****
- #define PTT_USER_THREAD 0x0001
-
- struct pthread {
-! int thread_type;
- struct machdep_pthread machdep_data;
-! pthread_attr_t attr;
-
- /* Signal interface */
-! sigset_t sigmask;
-! sigset_t sigpending;
-! int sigcount; /* Number of signals pending */
-
- /* Timeout time */
-! struct timespec wakeup_time;
-
- /* Join queue for waiting threads */
- struct pthread_queue join_queue;
-
--
- /*
- * Thread implementations are just multiple queue type implemenations,
- * Below are the various link lists currently necessary
---- 187,207 ----
- #define PTT_USER_THREAD 0x0001
-
- struct pthread {
-! int thread_type;
- struct machdep_pthread machdep_data;
-! pthread_attr_t attr;
-
- /* Signal interface */
-! sigset_t sigmask;
-! sigset_t sigpending;
-! int sigcount; /* Number of signals pending */
-
- /* Timeout time */
-! struct timespec wakeup_time;
-
- /* Join queue for waiting threads */
- struct pthread_queue join_queue;
-
- /*
- * Thread implementations are just multiple queue type implemenations,
- * Below are the various link lists currently necessary
-***************
-*** 152,165 ****
- * ALL threads, in any state.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * pll;
-
- /*
- * Standard link list for running threads, mutexes, etc ...
- * It can't be on both a running link list and a wait queue.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * next;
- union pthread_wait_data data;
-
- /*
---- 216,229 ----
- * ALL threads, in any state.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * pll;
-
- /*
- * Standard link list for running threads, mutexes, etc ...
- * It can't be on both a running link list and a wait queue.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * next;
- union pthread_wait_data data;
-
- /*
-***************
-*** 167,197 ****
- * (Note: "priority" is a reserved word in Concurrent C, please
- * don't use it. --KR)
- */
-! struct pthread_queue * queue;
-! enum pthread_state state;
-! char flags;
-! char pthread_priority;
-
- /*
- * Sleep queue, this is different from the standard link list
- * because it is possible to be on both (pthread_cond_timedwait();
- * Must lock sleep mutex before manipulating
- */
-! struct pthread *sll; /* For sleeping threads */
-
- /*
- * Data that doesn't need to be locked
-! * Mostly it's because only the thread owning the data can manipulate it
- */
-! void * ret;
-! int error;
-! int * error_p;
-! const void ** specific_data;
-! int specific_data_count;
-
- /* Cleanup handlers Link List */
- struct pthread_cleanup *cleanup;
--
- };
-
- #else /* not PTHREAD_KERNEL */
---- 231,261 ----
- * (Note: "priority" is a reserved word in Concurrent C, please
- * don't use it. --KR)
- */
-! struct pthread_queue * queue;
-! enum pthread_state state;
-! enum pthread_state old_state; /* Used when cancelled */
-! char flags;
-! char pthread_priority;
-
- /*
- * Sleep queue, this is different from the standard link list
- * because it is possible to be on both (pthread_cond_timedwait();
- * Must lock sleep mutex before manipulating
- */
-! struct pthread *sll; /* For sleeping threads */
-
- /*
- * Data that doesn't need to be locked
-! * Mostly because only the thread owning the data can manipulate it
- */
-! void * ret;
-! int error;
-! int * error_p;
-! const void ** specific_data;
-! int specific_data_count;
-
- /* Cleanup handlers Link List */
- struct pthread_cleanup *cleanup;
- };
-
- #else /* not PTHREAD_KERNEL */
-***************
-*** 200,223 ****
-
- #endif
-
-! typedef struct pthread * pthread_t;
-
- /*
- * Globals
- */
- #ifdef PTHREAD_KERNEL
-
-! extern struct pthread * pthread_run;
-! extern struct pthread * pthread_initial;
-! extern struct pthread * pthread_link_list;
- extern struct pthread_queue pthread_dead_queue;
- extern struct pthread_queue pthread_alloc_queue;
-
-! extern pthread_attr_t pthread_attr_default;
-! extern volatile int fork_lock;
-! extern pthread_size_t pthread_pagesize;
-!
-! extern sigset_t * uthread_sigmask;
-
- #endif
-
---- 264,293 ----
-
- #endif
-
-! typedef struct pthread *pthread_t;
-
- /*
- * Globals
- */
- #ifdef PTHREAD_KERNEL
-
-! extern struct pthread * pthread_run;
-! extern struct pthread * pthread_initial;
-! extern struct pthread * pthread_link_list;
- extern struct pthread_queue pthread_dead_queue;
- extern struct pthread_queue pthread_alloc_queue;
-
-! extern pthread_attr_t pthread_attr_default;
-! extern volatile int fork_lock;
-! extern pthread_size_t pthread_pagesize;
-!
-! extern sigset_t * uthread_sigmask;
-!
-! /* Kernel global functions */
-! extern void pthread_sched_prevent(void);
-! extern void pthread_sched_resume(void);
-! extern int __pthread_is_valid( pthread_t );
-! extern void pthread_cancel_internal( int freelocks );
-
- #endif
-
-***************
-*** 229,271 ****
-
- #if defined(DCE_COMPAT)
-
-! typedef void * (*pthread_startroutine_t)(void *)
-! typedef void * pthread_addr_t
-
-! int pthread_create __P((pthread_t *, pthread_attr_t,
-! pthread_startroutine_t,
-! pthread_addr_t));
-! void pthread_exit __P((pthread_addr_t));
-! int pthread_join __P((pthread_t, pthread_addr_t *));
-
- #else
-
-! void pthread_init __P((void));
-! int pthread_create __P((pthread_t *,
-! const pthread_attr_t *,
-! void * (*start_routine)(void *),
-! void *));
-! void pthread_exit __P((void *));
-! pthread_t pthread_self __P((void));
-! int pthread_equal __P((pthread_t, pthread_t));
-! int pthread_join __P((pthread_t, void **));
-! int pthread_detach __P((pthread_t));
-! void pthread_yield __P((void));
-!
-! int pthread_setschedparam __P((pthread_t pthread, int policy,
-! struct sched_param * param));
-! int pthread_getschedparam __P((pthread_t pthread, int * policy,
-! struct sched_param * param));
-!
-! int pthread_kill __P((struct pthread *, int));
-! int pthread_signal __P((int, void (*)(int)));
-
- #endif
-
- #if defined(PTHREAD_KERNEL)
-
- /* Not valid, but I can't spell so this will be caught at compile time */
-! #define pthread_yeild(notvalid)
-
- #endif
-
---- 299,343 ----
-
- #if defined(DCE_COMPAT)
-
-! typedef void * (*pthread_startroutine_t)(void *);
-! typedef void * pthread_addr_t;
-
-! int pthread_create __P((pthread_t *, pthread_attr_t,
-! pthread_startroutine_t, pthread_addr_t));
-! void pthread_exit __P((pthread_addr_t));
-! int pthread_join __P((pthread_t, pthread_addr_t *));
-
- #else
-
-! void pthread_init __P((void));
-! int pthread_create __P((pthread_t *, const pthread_attr_t *,
-! void * (*start_routine)(void *), void *));
-! void pthread_exit __P((void *));
-! pthread_t pthread_self __P((void));
-! int pthread_equal __P((pthread_t, pthread_t));
-! int pthread_join __P((pthread_t, void **));
-! int pthread_detach __P((pthread_t));
-! void pthread_yield __P((void));
-!
-! int pthread_setschedparam __P((pthread_t pthread, int policy,
-! struct sched_param * param));
-! int pthread_getschedparam __P((pthread_t pthread, int * policy,
-! struct sched_param * param));
-!
-! int pthread_kill __P((struct pthread *, int));
-! int pthread_signal __P((int, void (*)(int)));
-!
-! int pthread_cancel __P(( pthread_t pthread ));
-! int pthread_setcancelstate __P(( int state, int *oldstate ));
-! int pthread_setcanceltype __P(( int type, int *oldtype ));
-! void pthread_testcancel __P(( void ));
-
- #endif
-
- #if defined(PTHREAD_KERNEL)
-
- /* Not valid, but I can't spell so this will be caught at compile time */
-! #define pthread_yeild(notvalid)
-
- #endif
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/include/signal.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 signal.h
-*** signal.h 1995/12/25 03:03:09 1.1.1.1
---- signal.h 1996/09/26 21:46:04
-***************
-*** 43,48 ****
---- 43,49 ----
- __BEGIN_DECLS
-
- int raise __P((int));
-+ __sighandler_t signal __P((int __sig, __sighandler_t));
-
- #ifndef _ANSI_SOURCE
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/include/pthread/kernel.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 kernel.h
-*** kernel.h 1994/12/13 07:09:01 1.1.1.1
---- kernel.h 1996/10/02 19:08:41
-***************
-*** 42,48 ****
- */
- #if defined(PTHREAD_KERNEL)
-
-! #define PANIC() abort()
-
- /* Time each rr thread gets */
- #define PTHREAD_RR_TIMEOUT 100000000
---- 42,54 ----
- */
- #if defined(PTHREAD_KERNEL)
-
-! #ifdef __GNUC__
-! #include <assert.h>
-! #define PANIC() panic_kernel( __FILE__, __LINE__, __ASSERT_FUNCTION )
-! #else
-! #define PANIC() panic_kernel( __FILE__, __LINE__, (const char *)0 )
-! #endif
-!
-
- /* Time each rr thread gets */
- #define PTHREAD_RR_TIMEOUT 100000000
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/syscall-i386-linux-1.0.S,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 syscall-i386-linux-1.0.S
-*** syscall-i386-linux-1.0.S 1995/09/27 04:38:55 1.1.1.1
---- syscall-i386-linux-1.0.S 1996/06/04 19:20:17
-***************
-*** 147,154 ****
-
- /* =========================================================================
- * exit 1 select 82
-! * fork 2 socketcall 102
-! * read 3
- * write 4
- * open 5
- * creat 8
---- 147,154 ----
-
- /* =========================================================================
- * exit 1 select 82
-! * fork 2 fstatfs 100
-! * read 3 socketcall 102
- * write 4
- * open 5
- * creat 8
-***************
-*** 160,166 ****
- * chown 16
- * lseek 19
- * rename 38
-! * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
---- 160,166 ----
- * chown 16
- * lseek 19
- * rename 38
-! * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
-***************
-*** 302,314 ****
- #endif
-
- /* ==========================================================================
-! * machdep_sys_fstat()
- */
- #ifdef __ELF__
- STATCALL2(lstat)
- #else
- SYSCALL2(lstat)
- #endif
-
- /* ==========================================================================
- * machdep_sys_ftruncate()
---- 302,320 ----
- #endif
-
- /* ==========================================================================
-! * machdep_sys_lstat()
- */
- #ifdef __ELF__
- STATCALL2(lstat)
- #else
- SYSCALL2(lstat)
- #endif
-+
-+ /* ==========================================================================
-+ * machdep_sys_fstatfs()
-+ */
-+ SYSCALL2(fstatfs)
-+
-
- /* ==========================================================================
- * machdep_sys_ftruncate()
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/linux-1.0/socket.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 socket.h
-*** socket.h 1995/12/26 02:28:03 1.1.1.1
---- socket.h 1996/09/27 18:12:45
-***************
-*** 26,32 ****
-
- #endif
-
-! /* #include <asm/socket.h> /* arch-dependent defines */
- #include <linux/sockios.h> /* the SIOCxxx I/O controls */
- #include <pthread/posix.h>
-
---- 26,32 ----
-
- #endif
-
-! /* #include <asm/socket.h> arch-dependent defines */
- #include <linux/sockios.h> /* the SIOCxxx I/O controls */
- #include <pthread/posix.h>
-
-***************
-*** 161,166 ****
---- 161,188 ----
- int connect __P((int, const struct sockaddr *, int));
- int listen __P((int, int));
- int socket __P((int, int, int));
-+
-+ int getsockopt __P ((int __s, int __level, int __optname,
-+ void *__optval, int *__optlen));
-+ int setsockopt __P ((int __s, int __level, int __optname,
-+ __const void *__optval, int optlen));
-+ int getsockname __P ((int __sockfd, struct sockaddr *__addr,
-+ int *__paddrlen));
-+ int getpeername __P ((int __sockfd, struct sockaddr *__peer,
-+ int *__paddrlen));
-+ ssize_t send __P ((int __sockfd, __const void *__buff, size_t __len, int __flags));
-+ ssize_t recv __P ((int __sockfd, void *__buff, size_t __len, int __flags));
-+ ssize_t sendto __P ((int __sockfd, __const void *__buff, size_t __len,
-+ int __flags, __const struct sockaddr *__to,
-+ int __tolen));
-+ ssize_t recvfrom __P ((int __sockfd, void *__buff, size_t __len,
-+ int __flags, struct sockaddr *__from,
-+ int *__fromlen));
-+ extern ssize_t sendmsg __P ((int __fd, __const struct msghdr *__message,
-+ int __flags));
-+ extern ssize_t recvmsg __P ((int __fd, struct msghdr *__message,
-+ int __flags));
-+ int shutdown __P ((int __sockfd, int __how));
-
- __END_DECLS
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/linux-1.0/timers.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 timers.h
-*** timers.h 1996/03/05 08:28:36 1.1.1.1
---- timers.h 1996/05/25 21:30:08
-***************
-*** 43,52 ****
---- 43,54 ----
- #include <sys/types.h>
- #include <time.h>
-
-+ #ifndef _LINUX_TIME_H
- struct timespec {
- time_t tv_sec;
- long tv_nsec;
- };
-+ #endif /* _LINUX_TIME_H */
-
- #define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/getprotoent.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 getprotoent.c
-*** getprotoent.c 1996/02/09 05:39:41 1.1.1.1
---- getprotoent.c 1996/05/27 01:11:27
-***************
-*** 128,135 ****
- if (p != NULL)
- *p++ = '\0';
- }
-! if (p && *p);
-! break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&proto_file_lock);
---- 128,135 ----
- if (p != NULL)
- *p++ = '\0';
- }
-! if (p && *p)
-! break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&proto_file_lock);
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/proto_internal.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 proto_internal.c
-*** proto_internal.c 1996/02/09 05:39:49 1.1.1.1
---- proto_internal.c 1996/06/04 16:25:57
-***************
-*** 49,55 ****
- static int init_status;
-
- /* Performs global initialization. */
-! char *_proto_init()
- {
- char *buf;
-
---- 49,55 ----
- static int init_status;
-
- /* Performs global initialization. */
-! char *_proto_buf()
- {
- char *buf;
-
-***************
-*** 75,78 ****
- {
- init_status = pthread_key_create(&key, free);
- }
--
---- 75,77 ----
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/res_internal.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 res_internal.c
-*** res_internal.c 1996/02/09 05:39:53 1.1.1.1
---- res_internal.c 1996/09/25 23:31:11
-***************
-*** 144,149 ****
---- 144,150 ----
- break;
- cp += n;
- result->h_name = bp;
-+ bp += strlen(bp) + 1;
- iquery_done = 1;
- break;
- }
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/GNUmakefile.inc,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 GNUmakefile.inc
-*** GNUmakefile.inc 1995/08/30 22:27:04 1.1.1.1
---- GNUmakefile.inc 1996/10/02 19:04:29
-***************
-*** 8,14 ****
- syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
- specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c $(SRCS)
-
- ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
- SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
---- 8,15 ----
- syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
- specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c \
-! pthread_cancel.c panic.c $(SRCS)
-
- ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
- SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/Makefile.inc,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 Makefile.inc
-*** Makefile.inc 1995/08/22 22:09:07 1.1.1.1
---- Makefile.inc 1996/10/02 19:04:38
-***************
-*** 8,14 ****
- pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
- process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c condattr.c
-
- .if $(HAVE_SYSCALL_TEMPLATE) == yes
- OBJS+= syscalls.o
---- 8,14 ----
- pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
- process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c condattr.c pthread_cancel.c panic.c
-
- .if $(HAVE_SYSCALL_TEMPLATE) == yes
- OBJS+= syscalls.o
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/cond.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 cond.c
-*** cond.c 1996/03/05 08:29:12 1.1.1.1
---- cond.c 1996/10/03 18:19:04
-***************
-*** 188,197 ****
---- 188,204 ----
- pthread_queue_enq(&cond->c_queue, pthread_run);
- pthread_mutex_unlock(mutex);
-
-+ pthread_run->data.mutex = mutex;
-+
- SET_PF_WAIT_EVENT(pthread_run);
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-+
-+ pthread_run->data.mutex = NULL;
-+
- rval = pthread_mutex_lock(mutex);
- return(rval);
- break;
-***************
-*** 203,212 ****
---- 210,226 ----
- pthread_mutex_unlock(mutex);
- mutex->m_data.m_count = 1;
-
-+ pthread_run->data.mutex = mutex;
-+
- SET_PF_WAIT_EVENT(pthread_run);
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-+
-+ pthread_run->data.mutex = NULL;
-+
- rval = pthread_mutex_lock(mutex);
- mutex->m_data.m_count = count;
- return(rval);
-***************
-*** 258,265 ****
---- 272,285 ----
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
-+ pthread_run->data.mutex = mutex;
-+
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-+
-+ pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
-***************
-*** 285,292 ****
---- 305,318 ----
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
-+ pthread_run->data.mutex = mutex;
-+
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-+
-+ pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/fd.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 fd.c
-*** fd.c 1996/02/09 02:54:19 1.1.1.1
---- fd.c 1996/10/03 01:33:03
-***************
-*** 48,54 ****
---- 48,59 ----
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/uio.h>
-+ #include <sys/ioctl.h>
-+ #if __STDC__
- #include <stdarg.h>
-+ #else
-+ #include <varargs.h>
-+ #endif
- #include <fcntl.h>
- #include <errno.h>
- #include <pthread/posix.h>
-***************
-*** 62,67 ****
---- 67,74 ----
- static const int dtablecount = 4096/sizeof(struct fd_table_entry);
- int dtablesize;
-
-+ static int fd_get_pthread_fd_from_kernel_fd( int );
-+
- /* ==========================================================================
- * Allocate dtablecount entries at once and populate the fd_table.
- *
-***************
-*** 199,204 ****
---- 206,244 ----
- return(NOTOK);
- }
-
-+ /*----------------------------------------------------------------------
-+ * Function: fd_get_pthread_fd_from_kernel_fd
-+ * Purpose: get the fd_table index of a kernel fd
-+ * Args: fd = kernel fd to convert
-+ * Returns: fd_table index, -1 if not found
-+ * Notes:
-+ *----------------------------------------------------------------------*/
-+ static int
-+ fd_get_pthread_fd_from_kernel_fd( int kfd )
-+ {
-+ int j;
-+
-+ /* This is *SICK*, but unless there is a faster way to
-+ * turn a kernel fd into an fd_table index, this has to do.
-+ */
-+ for( j=0; j < dtablesize; j++ ) {
-+ if( fd_table[j] &&
-+ fd_table[j]->type != FD_NT &&
-+ fd_table[j]->type != FD_NIU &&
-+ fd_table[j]->fd.i == kfd ) {
-+ return j;
-+ }
-+ }
-+
-+ /* Not listed byfd, Check for kernel fd == pthread fd */
-+ if( fd_table[kfd] == NULL || fd_table[kfd]->type == FD_NT ) {
-+ /* Assume that the kernel fd is the same */
-+ return kfd;
-+ }
-+
-+ return NOTOK; /* Not found */
-+ }
-+
- /* ==========================================================================
- * fd_basic_basic_unlock()
- *
-***************
-*** 288,293 ****
---- 328,334 ----
- switch (fd_table[fd]->type) {
- case FD_NIU:
- /* If not in use return EBADF error */
-+ SET_ERRNO(EBADF);
- return(NOTOK);
- break;
- case FD_NT:
-***************
-*** 297,302 ****
---- 338,344 ----
- */
- fd_kern_init(fd);
- if (fd_table[fd]->type == FD_NIU) {
-+ SET_ERRNO(EBADF);
- return(NOTOK);
- }
- break;
-***************
-*** 409,414 ****
---- 451,545 ----
- return(OK);
- }
-
-+ /*----------------------------------------------------------------------
-+ * Function: fd_unlock_for_cancel
-+ * Purpose: Unlock all fd locks held prior to being cancelled
-+ * Args: void
-+ * Returns:
-+ * OK or NOTOK
-+ * Notes:
-+ * Assumes the kernel is locked on entry
-+ *----------------------------------------------------------------------*/
-+ int
-+ fd_unlock_for_cancel( void )
-+ {
-+ int i, fd;
-+ struct pthread_select_data *data;
-+ int rdlk, wrlk, lktype;
-+ int found;
-+
-+ /* What we do depends on the previous state of the thread */
-+ switch( pthread_run->old_state ) {
-+ case PS_RUNNING:
-+ case PS_JOIN:
-+ case PS_SLEEP_WAIT:
-+ case PS_WAIT_WAIT:
-+ case PS_SIGWAIT:
-+ case PS_FDLR_WAIT:
-+ case PS_FDLW_WAIT:
-+ case PS_DEAD:
-+ case PS_UNALLOCED:
-+ break; /* Nothing to do */
-+
-+ case PS_COND_WAIT:
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP );
-+ /* Must reaquire the mutex according to the standard */
-+ if( pthread_run->data.mutex == NULL ) {
-+ PANIC();
-+ }
-+ pthread_mutex_lock( pthread_run->data.mutex );
-+ break;
-+
-+ case PS_FDR_WAIT:
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-+ /* Free the lock on the fd being used */
-+ fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
-+ if( fd == NOTOK ) {
-+ PANIC(); /* Can't find fd */
-+ }
-+ fd_unlock( fd, FD_READ );
-+ break;
-+
-+ case PS_FDW_WAIT: /* Waiting on i/o */
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-+ /* Free the lock on the fd being used */
-+ fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
-+ if( fd == NOTOK ) {
-+ PANIC(); /* Can't find fd */
-+ }
-+ fd_unlock( fd, FD_WRITE );
-+ break;
-+
-+ case PS_SELECT_WAIT:
-+ data = pthread_run->data.select_data;
-+
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-+
-+ for( i = 0; i < data->nfds; i++) {
-+ rdlk =(FD_ISSET(i,&data->readfds)
-+ || FD_ISSET(i,&data->exceptfds));
-+ wrlk = FD_ISSET(i, &data->writefds);
-+ lktype = rdlk ? (wrlk ? FD_RDWR : FD_READ) : FD_WRITE;
-+
-+ if( ! (rdlk || wrlk) )
-+ continue; /* No locks, no unlock */
-+
-+ if( (fd = fd_get_pthread_fd_from_kernel_fd( i )) == NOTOK ) {
-+ PANIC(); /* Can't find fd */
-+ }
-+
-+ fd_unlock( fd, lktype );
-+ }
-+ break;
-+
-+ case PS_MUTEX_WAIT:
-+ PANIC(); /* Should never cancel a mutex wait */
-+
-+ default:
-+ PANIC(); /* Unknown thread status */
-+ }
-+ }
-+
- /* ==========================================================================
- * fd_lock()
- */
-***************
-*** 476,481 ****
---- 607,616 ----
- ret = fd_table[fd]->ops->read(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes, timeout);
- fd_unlock(fd, FD_READ);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 500,505 ****
---- 635,644 ----
- ret = fd_table[fd]->ops->readv(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_READ);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 524,529 ****
---- 663,672 ----
- ret = fd_table[fd]->ops->write(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes, timeout);
- fd_unlock(fd, FD_WRITE);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 548,553 ****
---- 691,700 ----
- ret = fd_table[fd]->ops->writev(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_WRITE);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 599,677 ****
- union fd_data realfd;
- int ret, flags;
-
- /* Need to lock the newfd by hand */
-! if (fd < dtablesize) {
-! pthread_mutex_lock(&fd_table_mutex);
-! if (fd_table[fd]) {
-! pthread_mutex_unlock(&fd_table_mutex);
-! mutex = &(fd_table[fd]->mutex);
-! pthread_mutex_lock(mutex);
-
-! /*
-! * XXX Gross hack ... because of fork(), any fd closed by the
-! * parent should not change the fd of the child, unless it owns it.
- */
-! switch(fd_table[fd]->type) {
-! case FD_NIU:
-! pthread_mutex_unlock(mutex);
-! ret = -EINVAL;
-! break;
-! case FD_NT:
-! /*
-! * If it's not tested then the only valid possibility is it's
-! * kernel fd.
-! */
-! ret = machdep_sys_close(fd);
-! fd_table[fd]->type = FD_NIU;
-! pthread_mutex_unlock(mutex);
-! break;
-! case FD_TEST_FULL_DUPLEX:
-! case FD_TEST_HALF_DUPLEX:
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
- if ((entry = fd_free(fd)) == NULL) {
-! ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
-! /* There can't be any others waiting for fd. */
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
-- mutex = &(fd_table[fd]->mutex);
- }
- pthread_mutex_unlock(mutex);
-- break;
-- default:
-- ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
-- if (ret == OK) {
-- realfd = fd_table[fd]->fd;
-- flags = fd_table[fd]->flags;
-- pthread_mutex_unlock(mutex);
-- if ((entry = fd_free(fd)) == NULL) {
-- ret = fd_table[fd]->ops->close(realfd, flags);
-- } else {
-- fd_basic_basic_unlock(entry, FD_RDWR);
-- pthread_mutex_unlock(&entry->mutex);
-- /* Note: entry->mutex = mutex */
-- }
-- fd_unlock(fd, FD_RDWR);
-- } else {
-- pthread_mutex_unlock(mutex);
-- }
-- break;
- }
-! } else {
-! /* Don't bother creating a table entry */
-! pthread_mutex_unlock(&fd_table_mutex);
-! ret = machdep_sys_close(fd);
- }
-! return(ret);
- }
-! return(-EINVAL);
- }
-
- /* ==========================================================================
- * fd_basic_dup()
- *
- * Might need to do more than just what's below.
- */
- static inline void fd_basic_dup(int fd, int newfd)
- {
---- 746,836 ----
- union fd_data realfd;
- int ret, flags;
-
-+ if( fd < 0 || fd >= dtablesize ) {
-+ SET_ERRNO(EBADF);
-+ return -1;
-+ }
-+
- /* Need to lock the newfd by hand */
-! pthread_mutex_lock(&fd_table_mutex);
-! if (fd_table[fd]) {
-! pthread_mutex_unlock(&fd_table_mutex);
-! mutex = &(fd_table[fd]->mutex);
-! pthread_mutex_lock(mutex);
-
-! /*
-! * XXX Gross hack ... because of fork(), any fd closed by the
-! * parent should not change the fd of the child, unless it owns it.
-! */
-! switch(fd_table[fd]->type) {
-! case FD_NIU:
-! pthread_mutex_unlock(mutex);
-! ret = -EBADF;
-! break;
-! case FD_NT:
-! /*
-! * If it's not tested then the only valid possibility is it's
-! * kernel fd.
- */
-! ret = machdep_sys_close(fd);
-! fd_table[fd]->type = FD_NIU;
-! pthread_mutex_unlock(mutex);
-! break;
-! case FD_TEST_FULL_DUPLEX:
-! case FD_TEST_HALF_DUPLEX:
-! realfd = fd_table[fd]->fd;
-! flags = fd_table[fd]->flags;
-! if ((entry = fd_free(fd)) == NULL) {
-! ret = fd_table[fd]->ops->close(realfd, flags);
-! } else {
-! /* There can't be any others waiting for fd. */
-! pthread_mutex_unlock(&entry->mutex);
-! /* Note: entry->mutex = mutex */
-! mutex = &(fd_table[fd]->mutex);
-! }
-! pthread_mutex_unlock(mutex);
-! break;
-! default:
-! ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
-! if (ret == OK) {
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
-+ pthread_mutex_unlock(mutex);
- if ((entry = fd_free(fd)) == NULL) {
-! ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
-! fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
-+ fd_unlock(fd, FD_RDWR);
-+ } else {
- pthread_mutex_unlock(mutex);
- }
-! break;
- }
-! } else {
-! /* Don't bother creating a table entry */
-! pthread_mutex_unlock(&fd_table_mutex);
-! ret = machdep_sys_close(fd);
-! }
-!
-! if( ret < 0 ) {
-! SET_ERRNO(-ret);
-! ret = -1;
- }
-!
-! return ret;
- }
-
- /* ==========================================================================
- * fd_basic_dup()
- *
- * Might need to do more than just what's below.
-+ *
-+ * This is a MAJOR guess!! I don't know if the mutext unlock is valid
-+ * in the BIG picture. But it seems to be needed to avoid deadlocking
-+ * with ourselves when we try to close the duped file descriptor.
- */
- static inline void fd_basic_dup(int fd, int newfd)
- {
-***************
-*** 679,684 ****
---- 838,845 ----
- fd_table[fd]->next = fd_table[newfd];
- fd_table[newfd] = fd_table[fd];
- fd_table[fd]->count++;
-+ pthread_mutex_unlock(&fd_table[newfd]->next->mutex);
-+
- }
-
- /* ==========================================================================
-***************
-*** 896,904 ****
- * ala select()... --SNL
- */
- int
-! ioctl(int fd, unsigned long request, caddr_t arg)
- {
- int ret;
-
- if (fd < 0 || fd >= dtablesize)
- ret = NOTOK;
---- 1057,1071 ----
- * ala select()... --SNL
- */
- int
-! ioctl(int fd, int request, ...)
- {
- int ret;
-+ pthread_va_list ap;
-+ caddr_t arg;
-+
-+ va_start( ap, request ); /* Get the arg */
-+ arg = va_arg(ap,caddr_t);
-+ va_end( ap );
-
- if (fd < 0 || fd >= dtablesize)
- ret = NOTOK;
-***************
-*** 906,911 ****
---- 1073,1086 ----
- ret = machdep_sys_ioctl(fd, request, arg);
- else if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = machdep_sys_ioctl(fd_table[fd]->fd.i, request, arg);
-+ if( ret == 0 && request == FIONBIO ) {
-+ /* Properly set NONBLOCK flag */
-+ int v = *(int *)arg;
-+ if( v )
-+ fd_table[fd]->flags |= __FD_NONBLOCK;
-+ else
-+ fd_table[fd]->flags &= ~__FD_NONBLOCK;
-+ }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/fd_kern.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 fd_kern.c
-*** fd_kern.c 1996/02/12 00:58:30 1.1.1.1
---- fd_kern.c 1996/10/03 01:54:15
-***************
-*** 128,134 ****
-
-
- if ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, NULL, &__fd_kern_poll_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
---- 128,134 ----
-
-
- if ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, &fd_set_except, &__fd_kern_poll_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
-***************
-*** 167,200 ****
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if ((FD_ISSET(i, &pthread->data.select_data->exceptfds) &&
-! ! FD_ISSET(i, &fd_set_except))) {
-! FD_CLR(i, &pthread->data.select_data->exceptfds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->writefds) &&
-! ! FD_ISSET(i, &fd_set_write))) {
-! FD_CLR(i, &pthread->data.select_data->writefds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->readfds) &&
-! ! FD_ISSET(i, &fd_set_read))) {
-! FD_CLR(i, &pthread->data.select_data->readfds);
-! } else {
-! count_dec++;
- }
- if (count_dec) {
- found_one++;
- count--;
- }
- }
- if (found_one) {
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
---- 167,223 ----
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-+ fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
-+
-+ memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
-+ sizeof(fd_set));
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if( (FD_ISSET(i, &tmp_exceptfds)) ) {
-! if( FD_ISSET(i, &fd_set_except) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_exceptfds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_writefds)) ) {
-! if( FD_ISSET(i, &fd_set_write) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_writefds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_readfds)) ) {
-! if( FD_ISSET(i, &fd_set_read) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_readfds);
-! }
- }
-+
- if (count_dec) {
- found_one++;
- count--;
- }
- }
-+
- if (found_one) {
-+ /* Update the threads saved select data fd sets */
-+ memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
-+ sizeof(fd_set));
-+
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
-***************
-*** 266,272 ****
- */
-
- while ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, NULL, &__fd_kern_wait_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
---- 289,295 ----
- */
-
- while ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, &fd_set_except, &__fd_kern_wait_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
-***************
-*** 305,338 ****
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if ((FD_ISSET(i, &pthread->data.select_data->exceptfds) &&
-! ! FD_ISSET(i, &fd_set_except))) {
-! FD_CLR(i, &pthread->data.select_data->exceptfds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->writefds) &&
-! ! FD_ISSET(i, &fd_set_write))) {
-! FD_CLR(i, &pthread->data.select_data->writefds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->readfds) &&
-! ! FD_ISSET(i, &fd_set_read))) {
-! FD_CLR(i, &pthread->data.select_data->readfds);
-! } else {
-! count_dec++;
- }
- if (count_dec) {
- found_one++;
- count--;
- }
- }
- if (found_one) {
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
---- 328,383 ----
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-+ fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
-+
-+ memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
-+ sizeof(fd_set));
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if( (FD_ISSET(i, &tmp_exceptfds)) ) {
-! if( FD_ISSET(i, &fd_set_except) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_exceptfds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_writefds)) ) {
-! if( FD_ISSET(i, &fd_set_write) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_writefds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_readfds)) ) {
-! if( FD_ISSET(i, &fd_set_read) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_readfds);
-! }
- }
-+
- if (count_dec) {
- found_one++;
- count--;
- }
- }
- if (found_one) {
-+ /* Update the threads saved select data fd sets */
-+ memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
-+ sizeof(fd_set));
-+
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
-***************
-*** 380,404 ****
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 425,450 ----
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- break;
- }
- }
-***************
-*** 437,443 ****
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
---- 483,488 ----
-***************
-*** 447,454 ****
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 492,497 ----
-***************
-*** 480,504 ****
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 523,548 ----
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- break;
- }
- }
-***************
-*** 537,543 ****
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
---- 581,586 ----
-***************
-*** 547,554 ****
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 590,595 ----
-***************
-*** 662,668 ****
- */
- int create(const char *path, mode_t mode)
- {
-! return creat (path, mode);
- }
-
- /* ==========================================================================
---- 703,709 ----
- */
- int create(const char *path, mode_t mode)
- {
-! return creat (path, mode);
- }
-
- /* ==========================================================================
-***************
-*** 672,678 ****
-
- int creat(const char *path, mode_t mode)
- {
-! return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
- }
-
- /* ==========================================================================
---- 713,719 ----
-
- int creat(const char *path, mode_t mode)
- {
-! return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
- }
-
- /* ==========================================================================
-***************
-*** 1079,1090 ****
- int bind(int fd, const struct sockaddr *name, int namelen)
- {
- /* Not much to do in bind */
-- semaphore *plock;
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
- SET_ERRNO(-ret);
- }
- fd_unlock(fd, FD_RDWR);
- }
---- 1120,1131 ----
- int bind(int fd, const struct sockaddr *name, int namelen)
- {
- /* Not much to do in bind */
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
- SET_ERRNO(-ret);
-+ ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
-***************
-*** 1100,1113 ****
- */
- int connect(int fd, const struct sockaddr *name, int namelen)
- {
-! struct sockaddr tmpname;
-! int ret, tmpnamelen;
-
-! if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
-! ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
-! (ret == -EALREADY) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
---- 1141,1154 ----
- */
- int connect(int fd, const struct sockaddr *name, int namelen)
- {
-! struct sockaddr tmpname;
-! int ret, tmpnamelen;
-
-! if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
-! ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
-! (ret == -EALREADY) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
-***************
-*** 1121,1131 ****
- tmpnamelen = sizeof(tmpname);
- /* OK now lets see if it really worked */
- if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! &tmpname, &tmpnamelen)) < OK) && (ret == -ENOTCONN)) {
-
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
-! SO_ERROR, &pthread_run->error, &tmpnamelen);
- }
- } else {
- SET_ERRNO(-ret);
---- 1162,1180 ----
- tmpnamelen = sizeof(tmpname);
- /* OK now lets see if it really worked */
- if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! &tmpname, &tmpnamelen)) < OK)
-! && (ret == -ENOTCONN)) {
-
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
-! SO_ERROR, &ret, &tmpnamelen);
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! } else {
-! if( ret < 0 ) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
- }
- } else {
- SET_ERRNO(-ret);
-***************
-*** 1133,1140 ****
- }
- }
- fd_unlock(fd, FD_RDWR);
-! }
-! return(ret);
- }
-
- #endif
---- 1182,1189 ----
- }
- }
- fd_unlock(fd, FD_RDWR);
-! }
-! return(ret);
- }
-
- #endif
-***************
-*** 1164,1170 ****
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-fd_kern);
-! return(fd_kern);
- }
- }
- fd_unlock(fd, FD_RDWR);
---- 1213,1219 ----
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-fd_kern);
-! return(NOTOK);
- }
- }
- fd_unlock(fd, FD_RDWR);
-***************
-*** 1198,1205 ****
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
-! ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog);
-! if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
---- 1247,1253 ----
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
-! if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
-***************
-*** 1246,1252 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1294,1300 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1311,1317 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1359,1365 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1405,1411 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1453,1459 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1471,1477 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1519,1525 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1536,1542 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1584,1590 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1603,1609 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1651,1657 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1734,1744 ****
- */
- int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
-! optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
---- 1782,1792 ----
- */
- int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
-! optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
-***************
-*** 1756,1772 ****
- */
- int getsockname(int fd, struct sockaddr * name, int * naddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
-! name, naddrlen)) < OK) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! fd_unlock(fd, FD_RDWR);
-! }
-! return ret;
- }
-
- #endif
---- 1804,1820 ----
- */
- int getsockname(int fd, struct sockaddr * name, int * naddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
-! name, naddrlen)) < OK) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! fd_unlock(fd, FD_RDWR);
-! }
-! return ret;
- }
-
- #endif
-***************
-*** 1778,1793 ****
- */
- int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! peer, paddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
-! }
-! fd_unlock(fd, FD_READ);
-! }
- return ret;
- }
-
---- 1826,1841 ----
- */
- int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! peer, paddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
-! }
-! fd_unlock(fd, FD_READ);
-! }
- return ret;
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 pthread.c
-*** pthread.c 1995/12/13 05:53:01 1.1.1.1
---- pthread.c 1996/10/01 21:42:01
-***************
-*** 129,134 ****
---- 129,160 ----
-
- }
-
-+ /*----------------------------------------------------------------------
-+ * Function: __pthread_is_valid
-+ * Purpose: Scan the list of threads to see if a specified thread exists
-+ * Args:
-+ * pthread = The thread to scan for
-+ * Returns:
-+ * int = 1 if found, 0 if not
-+ * Notes:
-+ * The kernel is assumed to be locked
-+ *----------------------------------------------------------------------*/
-+ int
-+ __pthread_is_valid( pthread_t pthread )
-+ {
-+ int rtn = 0; /* Assume not found */
-+ pthread_t t;
-+
-+ for( t = pthread_link_list; t; t = t->pll ) {
-+ if( t == pthread ) {
-+ rtn = 1; /* Found it */
-+ break;
-+ }
-+ }
-+
-+ return rtn;
-+ }
-+
- /* ==========================================================================
- * __pthread_free()
- */
-***************
-*** 242,247 ****
---- 268,277 ----
- new_thread->next = NULL;
- new_thread->flags = 0;
-
-+ /* PTHREADS spec says we start with cancellability on and deferred */
-+ SET_PF_CANCEL_STATE(new_thread, PTHREAD_CANCEL_ENABLE);
-+ SET_PF_CANCEL_TYPE(new_thread, PTHREAD_CANCEL_DEFERRED);
-+
- new_thread->error_p = NULL;
- new_thread->sll = NULL;
-
-***************
-*** 261,269 ****
- }
- return(retval);
- }
--
-- /* ==========================================================================
-- * pthread_cancel()
-- *
-- * This routine will also require a sig_prevent/sig_check_and_resume()
-- */
---- 291,293 ----
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_init.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 pthread_init.c
-*** pthread_init.c 1996/03/13 04:33:10 1.1.1.1
---- pthread_init.c 1996/10/01 21:43:59
-***************
-*** 92,99 ****
- pthread_initial->next = NULL;
- pthread_initial->flags = 0;
- pthread_initial->pll = NULL;
-- pthread_initial->flags = 0;
- pthread_initial->sll = NULL;
-
- /* Ugly errno hack */
- pthread_initial->error_p = &errno;
---- 92,103 ----
- pthread_initial->next = NULL;
- pthread_initial->flags = 0;
- pthread_initial->pll = NULL;
- pthread_initial->sll = NULL;
-+
-+ /* PTHREADS spec says we start with cancellability on and deferred */
-+ SET_PF_CANCEL_STATE(pthread_initial, PTHREAD_CANCEL_ENABLE);
-+ SET_PF_CANCEL_TYPE(pthread_initial, PTHREAD_CANCEL_DEFERRED);
-+
-
- /* Ugly errno hack */
- pthread_initial->error_p = &errno;
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_join.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 pthread_join.c
-*** pthread_join.c 1995/12/13 05:53:07 1.1.1.1
---- pthread_join.c 1996/10/02 16:54:36
-***************
-*** 42,47 ****
---- 42,49 ----
- #include <pthread.h>
- #include <errno.h>
-
-+ static int testDeadlock( struct pthread_queue *queue, pthread_t target );
-+
- /* ==========================================================================
- * pthread_join()
- */
-***************
-*** 51,56 ****
---- 53,64 ----
-
- pthread_sched_prevent();
-
-+ /* Ensure they gave us a legal pthread pointer */
-+ if( ! __pthread_is_valid( pthread ) ) {
-+ pthread_sched_resume();
-+ return(EINVAL);
-+ }
-+
- /* Check that thread isn't detached already */
- if (pthread->attr.flags & PTHREAD_DETACHED) {
- pthread_sched_resume();
-***************
-*** 62,81 ****
- * Note: This must happen after checking detached state.
- */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
-! pthread_queue_enq(&(pthread->join_queue), pthread_run);
-! pthread_resched_resume(PS_JOIN);
-! pthread_sched_prevent();
-!
-! if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
-! pthread_queue_enq(&pthread_alloc_queue, pthread);
-! pthread->attr.flags |= PTHREAD_DETACHED;
-! pthread->state = PS_UNALLOCED;
-! if (thread_return) {
-! *thread_return = pthread->ret;
-! }
-! ret = OK;
- } else {
-! ret = ESRCH;
- }
- } else {
- /* Just get the return value and detach the thread */
---- 70,98 ----
- * Note: This must happen after checking detached state.
- */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
-!
-! /* Before we pend on the join, ensure there is no dead lock */
-!
-! if( testDeadlock( &pthread_run->join_queue, pthread ) == NOTOK ) {
-! ret = EDEADLK;
- } else {
-! pthread_queue_enq(&(pthread->join_queue), pthread_run);
-! SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
-! pthread_resched_resume(PS_JOIN);
-! CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-! pthread_sched_prevent();
-!
-! if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
-! pthread_queue_enq(&pthread_alloc_queue, pthread);
-! pthread->attr.flags |= PTHREAD_DETACHED;
-! pthread->state = PS_UNALLOCED;
-! if (thread_return) {
-! *thread_return = pthread->ret;
-! }
-! ret = OK;
-! } else {
-! ret = ESRCH;
-! }
- }
- } else {
- /* Just get the return value and detach the thread */
-***************
-*** 89,92 ****
---- 106,139 ----
- }
- pthread_sched_resume();
- return(ret);
-+ }
-+
-+ /*----------------------------------------------------------------------
-+ * Function: testDeadlock
-+ * Purpose: recursive queue walk to check for deadlocks
-+ * Args:
-+ * queue = the queue to walk
-+ * pthread = target to scan for
-+ * Returns:
-+ * OK = no deadlock, NOTOK = deadlock
-+ * Notes:
-+ *----------------------------------------------------------------------*/
-+ static int
-+ testDeadlock( struct pthread_queue *queue, pthread_t target )
-+ {
-+ pthread_t t;
-+
-+ if( queue == NULL )
-+ return OK; /* Empty queue, obviously ok */
-+
-+ for( t = queue->q_next; t; t = t->next ) {
-+ if( t == target )
-+ return NOTOK; /* bang, your dead */
-+
-+ if( testDeadlock( &t->join_queue, target ) == NOTOK ) {
-+ return NOTOK;
-+ }
-+ }
-+
-+ return OK; /* No deadlock */
- }
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/select.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 select.c
-*** select.c 1996/03/05 08:29:14 1.1.1.1
---- select.c 1996/10/02 16:56:27
-***************
-*** 56,220 ****
- int select(int numfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
- {
-! fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
-! fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
-! fd_set read_locks, write_locks, rdwr_locks;
-! struct timespec timeout_time, current_time;
-! struct timeval zero_timeout = { 0, 0 };
-! int i, j, ret = 0, got_all_locks = 1;
-! struct pthread_select_data data;
-!
-! if (numfds > dtablesize) {
-! numfds = dtablesize;
-! }
-!
-! data.nfds = 0;
-! FD_ZERO(&data.readfds);
-! FD_ZERO(&data.writefds);
-! FD_ZERO(&data.exceptfds);
-
-! /* Do this first */
-! if (timeout) {
- machdep_gettimeofday(&current_time);
-! timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
-! if ((timeout_time.tv_nsec = current_time.tv_nsec +
-! (timeout->tv_usec * 1000)) > 1000000000) {
-! timeout_time.tv_nsec -= 1000000000;
-! timeout_time.tv_sec++;
-! }
-! }
-!
-! FD_ZERO(&read_locks);
-! FD_ZERO(&write_locks);
-! FD_ZERO(&rdwr_locks);
-! FD_ZERO(&real_readfds);
-! FD_ZERO(&real_writefds);
-! FD_ZERO(&real_exceptfds);
-!
-! /* lock readfds */
-! if (readfds || writefds || exceptfds) {
-! for (i = 0; i < numfds; i++) {
-! if ((readfds && (FD_ISSET(i, readfds))) ||
-! (exceptfds && FD_ISSET(i, exceptfds))) {
-! if (writefds && FD_ISSET(i ,writefds)) {
-! if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &rdwr_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! } else {
-! if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &read_locks);
-! }
-! if (readfds && FD_ISSET(i,readfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_readfds);
-! }
-! if (exceptfds && FD_ISSET(i,exceptfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_exceptfds);
-! }
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! } else {
-! if (writefds && FD_ISSET(i, writefds)) {
-! if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &write_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! }
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! }
-! }
-! }
-!
-! if (got_all_locks) {
-!
-! memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
-! memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
-! memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
-!
-! real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
-!
-! if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
-! real_writefds_p, real_exceptfds_p, &zero_timeout)) == OK) {
-!
-! pthread_sched_prevent();
-!
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
-! real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
-!
-! pthread_queue_enq(&fd_wait_select, pthread_run);
-! pthread_run->data.select_data = &data;
-! SET_PF_WAIT_EVENT(pthread_run);
-!
-! if (timeout) {
-! machdep_gettimeofday(&current_time);
-! sleep_schedule(&current_time, &timeout_time);
-!
-! pthread_resched_resume(PS_SELECT_WAIT);
-!
-! /* We're awake */
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! if (sleep_cancel(pthread_run) == NOTOK) {
-! ret = OK;
-! } else {
-! ret = data.nfds;
-! }
-! } else {
-! pthread_resched_resume(PS_SELECT_WAIT);
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! ret = data.nfds; /* XXX ??? snl */
-! }
-! } else if (ret < 0) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! }
-!
-! /* clean up the locks */
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
-!
-! if (ret > 0) {
-! if (readfds != NULL) {
-! for (i = 0; i < numfds; i++) {
-! if (! (FD_ISSET(i,readfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
-! FD_CLR(i,readfds);
-! }
-! }
-! if (writefds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,writefds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
-! FD_CLR(i,writefds);
-! }
-! if (exceptfds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,exceptfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
-! FD_CLR(i,exceptfds);
-! }
-! } else {
-! if (exceptfds != NULL) FD_ZERO(exceptfds);
-! if (writefds != NULL) FD_ZERO(writefds);
-! if (readfds != NULL) FD_ZERO(readfds);
- }
-
-! return(ret);
- }
---- 56,223 ----
- int select(int numfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
- {
-! fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
-! fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
-! fd_set read_locks, write_locks, rdwr_locks;
-! struct timespec timeout_time, current_time;
-! struct timeval zero_timeout = { 0, 0 };
-! int i, j, ret = 0, got_all_locks = 1;
-! struct pthread_select_data data;
-!
-! if (numfds > dtablesize) {
-! numfds = dtablesize;
-! }
-!
-! data.nfds = 0;
-! FD_ZERO(&data.readfds);
-! FD_ZERO(&data.writefds);
-! FD_ZERO(&data.exceptfds);
-!
-! /* Do this first */
-! if (timeout) {
-! machdep_gettimeofday(&current_time);
-! timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
-! if ((timeout_time.tv_nsec = current_time.tv_nsec +
-! (timeout->tv_usec * 1000)) > 1000000000) {
-! timeout_time.tv_nsec -= 1000000000;
-! timeout_time.tv_sec++;
-! }
-! }
-!
-! FD_ZERO(&read_locks);
-! FD_ZERO(&write_locks);
-! FD_ZERO(&rdwr_locks);
-! FD_ZERO(&real_readfds);
-! FD_ZERO(&real_writefds);
-! FD_ZERO(&real_exceptfds);
-!
-! /* lock readfds */
-! if (readfds || writefds || exceptfds) {
-! for (i = 0; i < numfds; i++) {
-! if ((readfds && (FD_ISSET(i, readfds))) ||
-! (exceptfds && FD_ISSET(i, exceptfds))) {
-! if (writefds && FD_ISSET(i ,writefds)) {
-! if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &rdwr_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! } else {
-! if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &read_locks);
-! }
-! if (readfds && FD_ISSET(i,readfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_readfds);
-! }
-! if (exceptfds && FD_ISSET(i,exceptfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_exceptfds);
-! }
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! } else {
-! if (writefds && FD_ISSET(i, writefds)) {
-! if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &write_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! }
-! }
-! }
-! }
-!
-! if (got_all_locks) {
-! memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
-! memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
-! memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
-!
-! real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
-!
-! if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
-! real_writefds_p, real_exceptfds_p,
-! &zero_timeout)) == OK) {
-! pthread_sched_prevent();
-!
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
-! real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
-!
-! pthread_queue_enq(&fd_wait_select, pthread_run);
-! pthread_run->data.select_data = &data;
-! SET_PF_WAIT_EVENT(pthread_run);
-
-! if (timeout) {
- machdep_gettimeofday(&current_time);
-! sleep_schedule(&current_time, &timeout_time);
-!
-! SET_PF_AT_CANCEL_POINT(pthread_run);
-! pthread_resched_resume(PS_SELECT_WAIT);
-! CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-!
-! /* We're awake */
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! if (sleep_cancel(pthread_run) == NOTOK) {
-! ret = OK;
-! } else {
-! ret = data.nfds;
-! }
-! } else {
-! SET_PF_AT_CANCEL_POINT(pthread_run);
-! pthread_resched_resume(PS_SELECT_WAIT);
-! CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! ret = data.nfds; /* XXX ??? snl */
-! }
-! } else if (ret < 0) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! }
-!
-! /* clean up the locks */
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
-!
-! if (ret > 0) {
-! if (readfds != NULL) {
-! for (i = 0; i < numfds; i++) {
-! if (! (FD_ISSET(i,readfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
-! FD_CLR(i,readfds);
-! }
-! }
-! if (writefds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,writefds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
-! FD_CLR(i,writefds);
-! }
-! if (exceptfds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,exceptfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
-! FD_CLR(i,exceptfds);
- }
-+ } else {
-+ if (exceptfds != NULL) FD_ZERO(exceptfds);
-+ if (writefds != NULL) FD_ZERO(writefds);
-+ if (readfds != NULL) FD_ZERO(readfds);
-+ }
-
-! return(ret);
- }
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/sig.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 sig.c
-*** sig.c 1996/03/13 04:33:13 1.1.1.1
---- sig.c 1996/10/03 01:07:54
-***************
-*** 301,307 ****
---- 301,310 ----
- pthread_run->data.sigwait = set;
- pthread_run->ret = sig;
-
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SIGWAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-+
- return(OK);
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/signal.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 signal.c
-*** signal.c 1996/03/13 04:33:17 1.1.1.1
---- signal.c 1996/10/03 17:30:16
-***************
-*** 72,77 ****
---- 72,78 ----
-
- static void sig_handler(int signal);
- static void set_thread_timer();
-+ static void __cleanup_after_resume( void );
- void sig_prevent(void);
- void sig_resume(void);
-
-***************
-*** 482,502 ****
- }
- }
-
-! /* Only bother if we are truly unlocking the kernel */
-! while (!(--pthread_kernel_lock)) {
-! if (sig_to_process) {
-! /* if (SIG_ANY(sig_to_process)) { */
-! pthread_kernel_lock++;
-! sig_handler(0);
-! continue;
-! }
-! if (pthread_run && pthread_run->sigcount) {
-! pthread_kernel_lock++;
-! pthread_sig_process();
-! continue;
-! }
-! break;
-! }
- }
-
- /* ==========================================================================
---- 483,489 ----
- }
- }
-
-! __cleanup_after_resume();
- }
-
- /* ==========================================================================
-***************
-*** 508,530 ****
- void pthread_resched_resume(enum pthread_state state)
- {
- pthread_run->state = state;
-- sig_handler(SIGVTALRM);
-
-! /* Only bother if we are truely unlocking the kernel */
-! while (!(--pthread_kernel_lock)) {
-! if (sig_to_process) {
-! /* if (SIG_ANY(sig_to_process)) { */
-! pthread_kernel_lock++;
-! sig_handler(0);
-! continue;
-! }
-! if (pthread_run && pthread_run->sigcount) {
-! pthread_kernel_lock++;
-! pthread_sig_process();
-! continue;
-! }
-! break;
- }
- }
-
- /* ==========================================================================
---- 495,523 ----
- void pthread_resched_resume(enum pthread_state state)
- {
- pthread_run->state = state;
-
-! /* Since we are about to block this thread, lets see if we are
-! * at a cancel point and if we've been cancelled.
-! * Avoid cancelling dead or unalloced threads.
-! */
-! if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
-! TEST_PTHREAD_IS_CANCELLABLE(pthread_run) &&
-! state != PS_DEAD && state != PS_UNALLOCED ) {
-!
-! /* Set this flag to avoid recursively calling pthread_exit */
-! /* We have to set this flag here because we will unlock the
-! * kernel prior to calling pthread_cancel_internal.
-! */
-! SET_PF_RUNNING_TO_CANCEL(pthread_run);
-!
-! pthread_run->old_state = state; /* unlock needs this data */
-! pthread_sched_resume(); /* Unlock kernel before cancel */
-! pthread_cancel_internal( 1 ); /* free locks and exit */
- }
-+
-+ sig_handler(SIGVTALRM);
-+
-+ __cleanup_after_resume();
- }
-
- /* ==========================================================================
-***************
-*** 532,537 ****
---- 525,543 ----
- */
- void pthread_sched_resume()
- {
-+ __cleanup_after_resume();
-+ }
-+
-+ /*----------------------------------------------------------------------
-+ * Function: __cleanup_after_resume
-+ * Purpose: cleanup kernel locks after a resume
-+ * Args: void
-+ * Returns: void
-+ * Notes:
-+ *----------------------------------------------------------------------*/
-+ static void
-+ __cleanup_after_resume( void )
-+ {
- /* Only bother if we are truely unlocking the kernel */
- while (!(--pthread_kernel_lock)) {
- /* if (SIG_ANY(sig_to_process)) { */
-***************
-*** 546,551 ****
---- 552,568 ----
- continue;
- }
- break;
-+ }
-+
-+ if( pthread_run == NULL )
-+ return; /* Must be during init processing */
-+
-+ /* Test for cancel that should be handled now */
-+
-+ if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
-+ TEST_PTHREAD_IS_CANCELLABLE(pthread_run) ) {
-+ /* Kernel is already unlocked */
-+ pthread_cancel_internal( 1 ); /* free locks and exit */
- }
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/sleep.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 sleep.c
-*** sleep.c 1996/03/11 08:33:32 1.1.1.1
---- sleep.c 1996/10/03 01:14:58
-***************
-*** 249,255 ****
---- 249,257 ----
-
- /* Reschedule thread */
- SET_PF_WAIT_EVENT(pthread_run);
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SLEEP_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- /* Return actual time slept */
-***************
-*** 332,338 ****
- current_time.tv_sec++;
- }
- machdep_start_timer(&(current_time),
-! &(pthread_sleep->wakeup_time));
- }
- } else {
- for (pthread_last = pthread_sleep; pthread_last;
---- 334,340 ----
- current_time.tv_sec++;
- }
- machdep_start_timer(&(current_time),
-! &(pthread_sleep->wakeup_time));
- }
- } else {
- for (pthread_last = pthread_sleep; pthread_last;
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/stat.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 stat.c
-*** stat.c 1995/09/21 02:36:05 1.1.1.1
---- stat.c 1996/06/04 19:17:33
-***************
-*** 43,48 ****
---- 43,49 ----
- #include <errno.h>
-
- struct stat;
-+ struct statfs;
-
- /* ==========================================================================
- * fstat()
-***************
-*** 91,95 ****
---- 92,115 ----
- }
- return(ret);
-
-+ }
-+
-+ /* ==========================================================================
-+ * fstatfs()
-+ *
-+ * Might want to indirect this.
-+ */
-+ int fstatfs(int fd, struct statfs *buf)
-+ {
-+ int ret;
-+
-+ if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-+ if ((ret = machdep_sys_fstatfs(fd_table[fd]->fd.i, buf)) < OK) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
-+ fd_unlock(fd, FD_READ);
-+ }
-+ return(ret);
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/wait.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 wait.c
-*** wait.c 1995/02/21 08:07:24 1.1.1.1
---- wait.c 1996/10/03 01:20:02
-***************
-*** 103,109 ****
---- 103,111 ----
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
- }
-***************
-*** 126,132 ****
---- 128,136 ----
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
- }
-<pre><font size=-1>
diff --git a/mit-pthreads/patches/Streepy2.html b/mit-pthreads/patches/Streepy2.html
deleted file mode 100755
index 80d44d6440c..00000000000
--- a/mit-pthreads/patches/Streepy2.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<html>
-<head>
- <title>Diffs on diffs :-) by Larry V. Streepy, Jr.</title>
- <base target=_top>
- <meta name="GENERATOR" content="FindMail Communications">
- <meta name="Date" content="Monday, October 07, 1996 02:03 PM PST">
- <meta name="Author" content="Larry V. Streepy, Jr.">
-</head>
-<body background="/gifs/betafm.gif" bgcolor="#ffffff" text="#000000" link="#0000ee" vlink="#ff0000" alink="#000099">
-<h3>Diffs on diffs :-)</h3>
-Larry V. Streepy, Jr. (<a href="mailto.html?mid=2079859748&num=398" target="_top">@healthcare.com</a>)<br>Monday, October 07, 1996 02:03 PM PST<br>
-<p>
-This is a multi-part message in MIME format.<p>
---------------65BE18E23639BCDD7BE55F7F <br>
-Content-Type: text/plain; charset=us-ascii <br>
-Content-Transfer-Encoding: 7bit<p>
-Unfortunately, there are a couple of bugs in my pthread_cancel support (no, say it isn't so :-)<p>
-Oh well, I cam across a couple of cases that I missed in my testing last week. Here are the bugs:<p>
-1. If a thread calls pthread_testcancel during it's cleanup processing after being cancelled, the pthread kernel would hang.<p>
-2. I didn't realize that threads in PS_SLEEP_WAIT state are *NOT* on any queue, they are handled using a linked list. So, when cancelling a thread that was sleeping, a PANIC() I put in possiblymakeRunnable would go off.<p>
-Both of these are fixed. The diffs are attached.<br>
--- <br>
-Larry V. Streepy, Jr. <br>
-Chief Technical Officer, Healthcare Communications, Inc. mailto:<a href="mailto.html?mid=2079859748&num=398" target="_top">@healthcare.com</a> <br>
-(214) 851-7033 (Dallas Main #) <br>
-(970) 626-5028 (My office #) (970) 626-4425 (Fax)<p>
---------------65BE18E23639BCDD7BE55F7F <br>
-Content-Type: text/plain; charset=us-ascii; name=&#34;cancel.diffs&#34; Content-Transfer-Encoding: 7bit <br>
-Content-Disposition: inline; filename=&#34;cancel.diffs&#34;<p>
-Index: pthread_cancel.c<br>
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_cancel.c,v retrieving revision 1.1 <br>
-diff -c -r1.1 pthread_cancel.c<br>
-*** pthread_cancel.c 1996/10/06 00:31:27 1.1<br>
---- pthread_cancel.c 1996/10/07 18:33:27<br>
-***************<br>
-*** 187,192 ****<br>
---- 187,197 ----<br>
- return; /* Can't be cancelled */<br>
- }<br>
- <br>
-+ /* Ensure that we aren't in the process of exiting already */<br>
-+ if( TEST_PF_RUNNING_TO_CANCEL(pthread_run) ) {<br>
-+ return;<br>
-+ }<br>
-+ <br>
- /* See if we have been cancelled */<br>
- if( TEST_PF_CANCELLED(pthread_run) ) {<br>
- /* Set this flag to avoid recursively calling pthread_exit */<br>
-***************<br>
-*** 266,277 ****<br>
- if( pthread-&gt;state == PS_RUNNING )<br>
- return; /* will happen at context switch */<br>
- <br>
-! /* Otherwise, we need to take it off the queue and make it runnable */<br>
-! if( pthread-&gt;queue == NULL ) {<br>
-! PANIC(); /* Must be on a queue */<br>
-! }<br>
- <br>
-- pthread_queue_remove(pthread-&gt;queue, pthread);<br>
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);<br>
- pthread-&gt;old_state = pthread-&gt;state;<br>
- pthread-&gt;state = PS_RUNNING;<br>
---- 271,291 ----<br>
- if( pthread-&gt;state == PS_RUNNING )<br>
- return; /* will happen at context switch */<br>
- <br>
-! /* If the thread is sleeping, the it isn't on a queue. */<br>
-! if( pthread-&gt;state == PS_SLEEP_WAIT ) {<br>
-! sleep_cancel( pthread ); /* Remove from sleep list */<br>
-! } else {<br>
-! /* Otherwise, we need to take it off the queue and make it runnable */<br>
-! <br>
-! if( pthread-&gt;queue == NULL ) {<br>
-! PANIC(); /* Must be on a queue */<br>
-! }<br>
-! <br>
-! pthread_queue_remove(pthread-&gt;queue, pthread);<br>
-! }<br>
-! <br>
-! /* And make it runnable */<br>
- <br>
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);<br>
- pthread-&gt;old_state = pthread-&gt;state;<br>
- pthread-&gt;state = PS_RUNNING;<p>
-<pre><font size=-1>
---------------65BE18E23639BCDD7BE55F7F--
-
-</pre><p></pre>
-<hr>
-<a href="http://www.findmail.com/" target="_top"><font size=-1>Powered by FindMail Communications</font><br></a>
-<br>Please email comments and suggestions to:<a href="/cgi-bin/comments.py" target="_top">comments@findmail.com</a>
-<br><font size=-3 color="#ffffff">xmlarchive</font>
-</body></html> \ No newline at end of file
diff --git a/mit-pthreads/patches/bill_lear b/mit-pthreads/patches/bill_lear
deleted file mode 100755
index f49b79c4272..00000000000
--- a/mit-pthreads/patches/bill_lear
+++ /dev/null
@@ -1,70 +0,0 @@
-From rael@dejanews.com Wed Jan 29 06:06:14 1997
-X-VM-v5-Data: ([nil nil nil t nil nil nil nil nil]
- ["1497" "Tue" "28" "January" "1997" "21:52:57" "-0600" "William S. Lear" "rael@dejanews.com" "<199701290352.VAA08678@homer.dejanews.com>" "53" "Patches for linux2.0" "^From:" nil nil "1" "1997012903:52:57" "Patches for linux2.0" nil nil]
- nil)
-Received: from MIT.EDU (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.69.0.28])
- by analytik.analytikerna.se (8.8.4/8.8.4) with SMTP
- id GAA23245 for <monty@analytikerna.se>; Wed, 29 Jan 1997 06:06:12 +0100 (MET)
-Received: from host-205-238-143-2.dejanews.com by MIT.EDU with SMTP
- id AA25254; Tue, 28 Jan 97 22:53:08 EST
-Received: (from rael@localhost) by homer.dejanews.com (8.7.6/8.6.12) id VAA08678 for pthreads@mit.edu; Tue, 28 Jan 1997 21:52:57 -0600 (CST)
-Message-Id: <199701290352.VAA08678@homer.dejanews.com>
-Content-Length: 1496
-From: "William S. Lear" <rael@dejanews.com>
-To: pthreads@MIT.EDU
-Subject: Patches for linux2.0
-Date: Tue, 28 Jan 1997 21:52:57 -0600 (CST)
-
-
-The following are some patches I found necessary to run smoothly
-under linux2.0. The PTEST directory below refers to the original
-pthreads 1.60 beta 6 release. Of course, the '-O2' "fix" is not strictly
-needed.
-
-#============================================================
-# < pthreads-1_60beta6/config/configure
-# > PTEST/pthreads-1_60beta6/config/configure
-#------------------------------------------------------------
-642c642
-< CFLAGS="-g -O2"
----
-> CFLAGS="-g -O"
-1104,1106d1103
-< cat >> confdefs.h <<EOF
-< #define BSD_TM 1
-< EOF
-
-# Diff for:
-#============================================================
-# < pthreads-1_60beta6/config/config.h.in
-# > PTEST/pthreads-1_60beta6/config/config.h.in
-#------------------------------------------------------------
-3,8d2
-< /* Does the OS have tm needing bsd'ish initialization? */
-< #undef BSD_TM
-<
-< /* Does the OS already support struct timespec */
-< #undef _OS_HAS_TIMESPEC
-<
-
-# Diff for:
-#============================================================
-# < pthreads-1_60beta6/gen/ctime.c
-# > PTEST/pthreads-1_60beta6/gen/ctime.c
-#------------------------------------------------------------
-49c49
-< #include "config.h"
----
->
-
-# Diff for:
-#============================================================
-# < pthreads-1_60beta6/include/math.h
-# > PTEST/pthreads-1_60beta6/include/math.h
-#------------------------------------------------------------
-54d53
-< double hypot __P((double, double));
-
-
-Bill Lear (rael@dejanews.com)
-
diff --git a/mit-pthreads/patches/chris_demetriou b/mit-pthreads/patches/chris_demetriou
deleted file mode 100755
index 283d6c1999c..00000000000
--- a/mit-pthreads/patches/chris_demetriou
+++ /dev/null
@@ -1,149 +0,0 @@
-From cgd@pa.dec.com Fri Aug 15 04:22:21 1997
-X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
- ["3982" "Thu" "14" "August" "1997" "18:57:55" "-0700" "Chris G. Demetriou" "cgd@pa.dec.com" "<15218.871610275@dnaunix.pa.dec.com>" "126" "patches to get 1.60 beta6 to build on ELF NetBSD/alpha systems" "^From:" nil nil "8" "1997081501:57:55" "patches to get 1.60 beta6 to build on ELF NetBSD/alpha systems" nil nil]
- nil)
-Received: from MIT.EDU (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.69.0.28])
- by analytik.analytikerna.se (8.8.4/8.8.4) with SMTP
- id EAA10207 for <monty@analytikerna.se>; Fri, 15 Aug 1997 04:22:19 +0200 (MET DST)
-Received: from mail2.digital.com by MIT.EDU with SMTP
- id AA13470; Thu, 14 Aug 97 22:01:37 EDT
-Received: from dnaunix.pa.dec.com (dnaunix.pa.dec.com [16.4.208.21])
- by mail2.digital.com (8.7.5/UNX 1.5/1.0/WV) with SMTP id SAA15366;
- Thu, 14 Aug 1997 18:58:16 -0700 (PDT)
-Received: by dnaunix.pa.dec.com; id AA15044; Thu, 14 Aug 1997 18:57:56 -0700
-Message-Id: <15218.871610275@dnaunix.pa.dec.com>
-X-Mts: smtp
-Content-Length: 3981
-From: "Chris G. Demetriou" <cgd@pa.dec.com>
-Sender: cgd@pa.dec.com
-To: pthreads-bugs@MIT.EDU
-Cc: "Chris G. Demetriou" <cgd@pa.dec.com>, pthreads@MIT.EDU
-Subject: patches to get 1.60 beta6 to build on ELF NetBSD/alpha systems
-Date: Thu, 14 Aug 97 18:57:55 -0700
-
-Enclosed below are patches to pthreads 1.60 beta6 to build on
-current NetBSD/alpha systems (which use ELF). With these patches,
-pthreads passes 'make check.'
-
-As an aside, the test_switch test generates _340k_ of output ("a"
-for a while, then "ab" for a while) when run one the machine I was
-testing on. In my opinion, that's a ... bit excessive, especially
-since 'make check' has to be run interactively!
-
-
-
-chris
-============================================================================
-diff -rc pthreads-1_60_beta6.orig/config/Makefile.in pthreads-1_60_beta6/config/Makefile.in
-*** pthreads-1_60_beta6.orig/config/Makefile.in Thu Mar 21 20:29:54 1996
---- pthreads-1_60_beta6/config/Makefile.in Thu Aug 14 17:56:55 1997
-***************
-*** 29,35 ****
- # pathname for srcdir here, and live with it.
- srcdir = $(srctop)
-
-! beforeinstall:: install-dirs
-
- .include "${srcdir}/pthreads/Makefile.inc"
- .include "${srcdir}/stdlib/Makefile.inc"
---- 29,35 ----
- # pathname for srcdir here, and live with it.
- srcdir = $(srctop)
-
-! beforeinstall: install-dirs
-
- .include "${srcdir}/pthreads/Makefile.inc"
- .include "${srcdir}/stdlib/Makefile.inc"
-diff -rc pthreads-1_60_beta6.orig/machdep/syscall-alpha-netbsd-1.1.S pthreads-1_60_beta6/machdep/syscall-alpha-netbsd-1.1.S
-*** pthreads-1_60_beta6.orig/machdep/syscall-alpha-netbsd-1.1.S Wed Nov 13 13:03:28 1996
---- pthreads-1_60_beta6/machdep/syscall-alpha-netbsd-1.1.S Thu Aug 14 18:03:27 1997
-***************
-*** 35,54 ****
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
-! beq a3, 2f ;\
-! br gp, 1f ;\
-! 1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! 2:
-
- #define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
- machdep_cerror:
-! br t0, 1f
-! 1:
- ldgp gp, 0(t0)
- stl v0, errno
- #if 0
---- 35,54 ----
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
-! beq a3, CONCAT(Lsys_noerr_,x) ;\
-! br gp, CONCAT(Lsys_err_,x) ;\
-! CONCAT(Lsys_err_,x): ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! CONCAT(Lsys_noerr_,x):
-
- #define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
- machdep_cerror:
-! br t0, Lmachdep_cerror_setgp
-! Lmachdep_cerror_setgp:
- ldgp gp, 0(t0)
- stl v0, errno
- #if 0
-diff -rc pthreads-1_60_beta6.orig/machdep/syscall-template-alpha-netbsd-1.1.S pthreads-1_60_beta6/machdep/syscall-template-alpha-netbsd-1.1.S
-*** pthreads-1_60_beta6.orig/machdep/syscall-template-alpha-netbsd-1.1.S Mon Apr 22 23:15:42 1996
---- pthreads-1_60_beta6/machdep/syscall-template-alpha-netbsd-1.1.S Thu Aug 14 17:58:14 1997
-***************
-*** 31,43 ****
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
-! beq a3, 2f ;\
-! br gp, 1f ;\
-! 1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! 2:
-
- #define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
---- 31,43 ----
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
-! beq a3, Lsys_noerr_##x ;\
-! br gp, Lsys_err_##x ;\
-! Lsys_err_##x: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! Lsys_noerr_##x:
-
- #define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-diff -rc pthreads-1_60_beta6.orig/pthreads/process.c pthreads-1_60_beta6/pthreads/process.c
-*** pthreads-1_60_beta6.orig/pthreads/process.c Tue Nov 12 05:45:16 1996
---- pthreads-1_60_beta6/pthreads/process.c Thu Aug 14 18:12:49 1997
-***************
-*** 40,45 ****
---- 40,47 ----
- #include <stdarg.h>
- #include <unistd.h>
-
-+ extern void *alloca();
-+
- #ifndef lint
- static const char rcsid[] = "$Id$";
- #endif
-
diff --git a/mit-pthreads/patches/mevans b/mit-pthreads/patches/mevans
deleted file mode 100755
index d5ff2f27610..00000000000
--- a/mit-pthreads/patches/mevans
+++ /dev/null
@@ -1,642 +0,0 @@
-=A0
-Attached are several patches for pthreads-1_60_beta6. The patches fall
-into 3 catagories:
-
- 1. Crashes and hangs.
- 2. Missing functionality (namely flock())
- 3. Use of POSIX reentrant safe routines.
-
-Most of the patches contain a comment as to why the change was made.
-The one major exception is to fd_kern.c at line 257 (unpatched). The
-change to that line is to fix a "hang" that prevents threads for
-scheduling for an hour if there is no external I/O event.
-
-I also include patches that modify several functions to use POSIX
-reentrant safe routines. I know that MIT pthreads implements routine
-like gethostbyname in a thread safe manner, but we're pretty, um, anal
-about trying to keep our code as portable as possible. By excluding
-using routines that are not reentrant safe according to the PTHREAD
-safe, it's easy for us to stub out the unsafe routines and catch
-non-compliant code. I almost left these patches out, but I'm hoping
-they'll be adopted. :-)
-
-WARNING: None of the MIT pthreads routines that convert floats/doubles
-between their native forms and strings are thread safe! (i.e printf,
-sprintf, fprintf, atod, strtod, etc) I have replacements, but I need to
-check with the author of the replacements and my employer.
-
-Mark Evans
-
-------------69CDAAF52A3566916F8ED01A0
-Content-Disposition: inline; filename="pthreads-1_60_beta6.patch"
-Content-Type: text/plain; charset=us-ascii; name="pthreads-1_60_beta6.patch"
-Content-Transfer-Encoding: 7bit
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/config.h.in pthreads-1_60_beta6+/config/config.h.in
-*** pthreads-1_60_beta6/config/config.h.in Thu Mar 21 21:30:04 1996
---- pthreads-1_60_beta6+/config/config.h.in Sat Mar 15 14:08:55 1997
-***************
-*** 137,142 ****
---- 137,145 ----
- /* Define if you have the syscall_ftruncate function. */
- #undef HAVE_SYSCALL_FTRUNCATE
-
-+ /* Define if you have the syscall_flock function. */
-+ #undef HAVE_SYSCALL_FLOCK
-+
- /* Define if you have the syscall_getdents function. */
- #undef HAVE_SYSCALL_GETDENTS
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/configure.in pthreads-1_60_beta6+/config/configure.in
-*** pthreads-1_60_beta6/config/configure.in Wed Nov 13 14:03:08 1996
---- pthreads-1_60_beta6+/config/configure.in Sat Mar 15 14:08:55 1997
-***************
-*** 241,247 ****
-
- PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
-! rename select getdtablesize ioctl ftruncate
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
---- 241,247 ----
-
- PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
-! rename select getdtablesize ioctl ftruncate flock
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/directory.c pthreads-1_60_beta6+/gen/directory.c
-*** pthreads-1_60_beta6/gen/directory.c Sat May 20 10:55:34 1995
---- pthreads-1_60_beta6+/gen/directory.c Sat Mar 15 14:08:55 1997
-***************
-*** 251,262 ****
---- 251,266 ----
- /*
- * Seek to an entry in a directory.
- * _seekdir is in telldir.c so that it can share opaque data structures.
-+ *
-+ * Use the POSIX reentrant safe readdir_r to simplify varifying POSIX
-+ * thread-safe compliance.
- */
- void seekdir(DIR * dirp, long loc)
- {
- register struct ddloc ** prevlp;
- register struct ddloc * lp;
- struct dirent * dp;
-+ struct dirent de;
-
- pthread_mutex_lock (dirp->dd_lock);
- prevlp = (struct ddloc **)&(dirp->dd_ddloc);
-***************
-*** 277,283 ****
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
-! if (!(dp = readdir(dirp))) {
- *prevlp = lp->loc_next;
- break;
- }
---- 281,287 ----
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
-! if (readdir_r(dirp, &de, &dp)) {
- *prevlp = lp->loc_next;
- break;
- }
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/getcwd.c pthreads-1_60_beta6+/gen/getcwd.c
-*** pthreads-1_60_beta6/gen/getcwd.c Sat Sep 2 17:39:30 1995
---- pthreads-1_60_beta6+/gen/getcwd.c Sat Mar 15 14:08:55 1997
-***************
-*** 50,67 ****
- (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
- dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
-
- char *
- getcwd(pt, size)
- char *pt;
- size_t size;
- {
-- register struct dirent *dp;
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
---- 50,71 ----
- (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
- dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
-
-+ /* Only use reentrant safe routines to simplify varifying POSIX thread-safe
-+ * compliance. (mevans).
-+ */
- char *
- getcwd(pt, size)
- char *pt;
- size_t size;
- {
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
-+ struct dirent *dp;
-+ struct dirent de;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
-***************
-*** 166,179 ****
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
-! if (!(dp = readdir(dir)))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
-! if (!(dp = readdir(dir)))
- goto notfound;
- if (ISDOT(dp))
- continue;
---- 170,183 ----
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
-! if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
-! if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (ISDOT(dp))
- continue;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/include/syslog.h pthreads-1_60_beta6+/include/syslog.h
-*** pthreads-1_60_beta6/include/syslog.h Mon Sep 26 21:26:29 1994
---- pthreads-1_60_beta6+/include/syslog.h Sat Mar 15 14:08:56 1997
-***************
-*** 9,14 ****
---- 9,16 ----
- #ifndef SYSLOG_H
- #define SYSLOG_H
-
-+ /* Added __[BEGIN/END]_DECLS so this file would work with C++. (mevans) */
-+ #include <sys/cdefs.h>
- #include <stdarg.h>
-
- /* Discipline: openlog(), closelog(), and setlogmask() are not thread-safe
-***************
-*** 84,95 ****
---- 86,101 ----
- #define LOG_NDELAY 0x08 /* don't delay open */
- #define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */
-
-+ __BEGIN_DECLS
-+
- /* Syslogging functions. */
- void syslog(int pri, char *fmt, ...);
- void vsyslog(int pri, char *fmt, va_list args);
- void openlog(char *ident, int logstat, int logfac);
- void closelog(void);
- int setlogmask(int pmask);
-+
-+ __END_DECLS
-
- #endif
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c
-*** pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c Mon Oct 21 20:39:13 1996
---- pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c Sat Mar 15 14:08:56 1997
-***************
-*** 142,147 ****
---- 142,149 ----
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->__pc = (char *)machdep_pthread_start;
-+ machdep_pthread->machdep_state->__bp = (char *)0;/* So the backtrace
-+ * is sensible (mevans) */
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->__sp =
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S
-*** pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S Mon Oct 21 22:17:32 1996
---- pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S Sat Mar 15 14:08:56 1997
-***************
-*** 148,156 ****
- /* =========================================================================
- * exit 1 select 82
- * fork 2 socketcall 102
-! * read 3 readv 145
-! * write 4 writev 146
-! * open 5
- * creat 8
- * link 9
- * unlink 10
---- 148,156 ----
- /* =========================================================================
- * exit 1 select 82
- * fork 2 socketcall 102
-! * read 3 flock 143
-! * write 4 readv 145
-! * open 5 writev 146
- * creat 8
- * link 9
- * unlink 10
-***************
-*** 390,394 ****
---- 390,401 ----
- */
- #ifdef HAVE_SYSCALL_WRITEV
- SYSCALL3(writev)
-+ #endif
-+
-+ /* ==========================================================================
-+ * machdep_sys_flock()
-+ */
-+ #ifdef HAVE_SYSCALL_FLOCK
-+ SYSCALL2(flock)
- #endif
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/gethostbyname.c pthreads-1_60_beta6+/net/gethostbyname.c
-*** pthreads-1_60_beta6/net/gethostbyname.c Mon Apr 22 22:41:21 1996
---- pthreads-1_60_beta6+/net/gethostbyname.c Sat Mar 15 14:08:58 1997
-***************
-*** 146,161 ****
- {
- char **alias;
- FILE *fp = NULL;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
-! while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
-! if (strcasecmp(*alias, name) == 0)
- break;
- }
- }
- pthread_mutex_unlock(&host_iterate_lock);
---- 146,166 ----
- {
- char **alias;
- FILE *fp = NULL;
-+ int fFound = FALSE;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
-! while (!fFound && (result = gethostent_r(result, buf, bufsize, errval))
-! != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
-! if (strcasecmp(*alias, name) == 0) {
-! /* fFound will exit while loop. (mevans). */
-! fFound = TRUE;
- break;
-+ }
- }
- }
- pthread_mutex_unlock(&host_iterate_lock);
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/res_debug.c pthreads-1_60_beta6+/net/res_debug.c
-*** pthreads-1_60_beta6/net/res_debug.c Thu Feb 23 22:42:35 1995
---- pthreads-1_60_beta6+/net/res_debug.c Sat Mar 15 14:08:58 1997
-***************
-*** 375,380 ****
---- 375,383 ----
-
- /*
- * Print resource record fields in human readable form.
-+ *
-+ * Removed calls to non-reentrant routines to simplify varifying
-+ * POSIX thread-safe implementations. (mevans).
- */
- char *
- p_rr(cp, msg, file)
-***************
-*** 386,391 ****
---- 389,395 ----
- char *cp1, *cp2;
- u_long tmpttl, t;
- int lcnt;
-+ char buf[32];
-
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL); /* compression error */
-***************
-*** 413,426 ****
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
-! fprintf(file,"\t%s", inet_ntoa(inaddr));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
-! address = inet_ntoa(inaddr);
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
---- 417,432 ----
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
-! fprintf(file,"\t%s",
-! inet_ntoa_r(inaddr, buf, sizeof(buf)));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
-! address = inet_ntoa_r(inaddr,
-! buf, sizeof(buf));
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
-***************
-*** 524,530 ****
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "\t%s %s ( ",
-! inet_ntoa(inaddr),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
---- 530,536 ----
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "\t%s %s ( ",
-! inet_ntoa_r(inaddr, buf, sizeof(buf)),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/fd_kern.c pthreads-1_60_beta6+/pthreads/fd_kern.c
-*** pthreads-1_60_beta6/pthreads/fd_kern.c Tue Oct 1 12:26:48 1996
---- pthreads-1_60_beta6+/pthreads/fd_kern.c Sat Mar 15 14:09:00 1997
-***************
-*** 215,221 ****
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-!
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
---- 215,221 ----
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-! extern volatile sig_atomic_t sig_to_process;
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
-***************
-*** 254,260 ****
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-
---- 254,260 ----
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-
-***************
-*** 726,731 ****
---- 726,753 ----
- return(ret);
- }
-
-+ #if defined (HAVE_SYSCALL_FLOCK)
-+ /* ==========================================================================
-+ * flock()
-+ *
-+ * Added (mevans)
-+ */
-+ int flock(int fd, int operation)
-+ {
-+ int ret;
-+
-+ if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
-+ if ((ret = machdep_sys_flock(fd_table[fd]->fd.i,
-+ operation)) < OK) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
-+ fd_unlock(fd, FD_RDWR);
-+ }
-+ return(ret);
-+ }
-+ #endif
-+
- /* ==========================================================================
- * pipe()
- */
-***************
-*** 1126,1132 ****
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
- SO_ERROR, &ret, &tmpnamelen);
-! SET_ERRNO(-ret);
- ret = NOTOK;
- }
- } else {
---- 1148,1155 ----
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
- SO_ERROR, &ret, &tmpnamelen);
-! /* ret is already positive (mevans) */
-! SET_ERRNO(ret);
- ret = NOTOK;
- }
- } else {
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/malloc.c pthreads-1_60_beta6+/pthreads/malloc.c
-*** pthreads-1_60_beta6/pthreads/malloc.c Thu Mar 9 21:06:43 1995
---- pthreads-1_60_beta6+/pthreads/malloc.c Sat Mar 15 14:09:00 1997
-***************
-*** 196,204 ****
- else
- n = n - x;
- if (n) {
-! if (sbrk(n) == (char *)-1)
- return (NULL);
- }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
---- 196,207 ----
- else
- n = n - x;
- if (n) {
-! if (sbrk(n) == (char *)-1) {
-! /* Unlock before returning (mevans) */
-! pthread_mutex_unlock(mutex);
- return (NULL);
- }
-+ }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
-***************
-*** 363,366 ****
---- 366,382 ----
- free(cp);
-
- return (res);
-+ }
-+ /* ==========================================================================
-+ * calloc()
-+ *
-+ * Added to ensure pthread's allocation is used (mevans).
-+ */
-+ void *calloc(size_t nmemb, size_t size)
-+ {
-+ void *p;
-+ size *= nmemb;
-+ p = malloc(size);
-+ if (p) memset(p, 0, size);
-+ return (p);
- }
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/select.c pthreads-1_60_beta6+/pthreads/select.c
-*** pthreads-1_60_beta6/pthreads/select.c Sat Jul 6 21:58:55 1996
---- pthreads-1_60_beta6+/pthreads/select.c Sat Mar 15 14:09:00 1997
-***************
-*** 165,176 ****
- pthread_resched_resume(PS_SELECT_WAIT);
-
- /* We're awake */
-- CLEAR_PF_DONE_EVENT(pthread_run);
- if (sleep_cancel(pthread_run) == NOTOK) {
- ret = OK;
- } else {
- ret = data.nfds;
- }
- } else {
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
---- 165,180 ----
- pthread_resched_resume(PS_SELECT_WAIT);
-
- /* We're awake */
- if (sleep_cancel(pthread_run) == NOTOK) {
- ret = OK;
- } else {
- ret = data.nfds;
- }
-+ /* Moving this after the sleep_cancel() seemed
-+ * to fix intermittent crashes during heavy
-+ * socket use. (mevans)
-+ */
-+ CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/signal.c pthreads-1_60_beta6+/pthreads/signal.c
-*** pthreads-1_60_beta6/pthreads/signal.c Tue Mar 12 21:33:17 1996
---- pthreads-1_60_beta6+/pthreads/signal.c Sat Mar 15 14:09:00 1997
-***************
-*** 65,71 ****
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! static sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
---- 65,71 ----
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! volatile sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
-***************
-*** 303,309 ****
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
-! sigdefault(sig);
- break;
- }
- break;
---- 303,317 ----
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
-! /* There is a timing window that gets
-! * here when no threads are on the
-! * sleep queue. This is a quick fix.
-! * The real problem is possibly related
-! * to heavy use of condition variables
-! * with time outs.
-! * (mevans)
-! *sigdefault(sig);
-! */
- break;
- }
- break;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdio/setvbuf.c pthreads-1_60_beta6+/stdio/setvbuf.c
-*** pthreads-1_60_beta6/stdio/setvbuf.c Sat Sep 3 20:58:36 1994
---- pthreads-1_60_beta6+/stdio/setvbuf.c Sat Mar 15 14:09:00 1997
-***************
-*** 142,148 ****
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
-! fp->_w = 0;
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
---- 142,148 ----
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
-! fp->_w = size; /* Was 0 (mevans) */
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdlib/system.c pthreads-1_60_beta6+/stdlib/system.c
-*** pthreads-1_60_beta6/stdlib/system.c Wed Apr 24 21:18:56 1996
---- pthreads-1_60_beta6+/stdlib/system.c Sat Mar 15 14:09:01 1997
-***************
-*** 62,68 ****
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
-! pthread_sigmask(SIG_BLOCK, tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
---- 62,69 ----
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
-! /* Pass the address of tmp_mask to avoid a sigfault. (mevans). */
-! pthread_sigmask(SIG_BLOCK, &tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
diff --git a/mit-pthreads/patches/p153 b/mit-pthreads/patches/p153
deleted file mode 100755
index 4e374e29a10..00000000000
--- a/mit-pthreads/patches/p153
+++ /dev/null
@@ -1,90 +0,0 @@
-<HEAD><TITLE>discuss@charon.mit.edu: [153] in "Pthreads Bugs"</TITLE>
-<H1>[153] in Pthreads Bugs</H1></HEAD>
-<A HREF="/"><IMG SRC="/i-d.gif" ALT="root"></A>
-<A HREF="?153"><IMG SRC="/i-back.gif" ALT="meeting"></A>
-<A HREF="/help.html"><IMG SRC="/i-help.gif" ALT="help"></A>
-<A HREF="1"><IMG SRC="/i-first.gif" ALT="first"></A>
-<A HREF="151"><IMG SRC="/i-fref.gif" ALT="first in chain"></A>
-<A HREF="152"><IMG SRC="/i-pref.gif" ALT="previous in chain"></A>
-<A HREF="152"><IMG SRC="/i-prev.gif" ALT="previous"></A>
-<A HREF="154"><IMG SRC="/i-next.gif" ALT="next"></A>
-<IMG SRC="/n-nref.gif" ALT="">
-<IMG SRC="/n-lref.gif" ALT="">
-<A HREF="161"><IMG SRC="/i-last.gif" ALT="last"></A>
-<HR><H2>Re: sleep / SIGALRM problem in 1_60_beta6</H2>
-<H3>daemon@ATHENA.MIT.EDU (Mon Dec 9 19:32:22 1996
-)</H3>
-<PRE>
-Date: Mon, 09 Dec 1996 17:22:50 -0700
-From: "Mark M. Evans" &lt;mevans@cti-ltd.com&gt;
-To: Tim Hinderliter &lt;kyd@internap.com&gt;
-Cc: pthreads-bugs@MIT.EDU
-
-I think I found what caused fd_kern_wait() to block for the entire
-hour (instead of waking up due to the SIGALRM). Basically, the
-SIGALRM that would move the sleeping thread to the run queue occurs
-while pthread_kernel_lock is set, but *before* the critical section in
-fd_kern_wait() that sets __fd_kern_wait_timeout.tv_sec to 3600. So,
-sig_handler_real() clears __fd_kern_wait_timeout.tv_sec "too soon."
-
-I've worked around this by checking sig_to_process in the critical
-section to determine if we are truly idle. To do this I had to make
-sig_to_process publicly available.
-
-Here are the diffs (relative to the pthreads/pthreads directory):
-
-diff -c -r1.2 -r1.3
-*** signal.c 1996/11/20 05:09:50 1.2
---- signal.c 1996/12/09 23:14:52 1.3
-***************
-*** 65,71 ****
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! static sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
---- 65,71 ----
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
-*** fd_kern.c 1996/12/03 04:14:59 1.6
---- fd_kern.c 1996/12/09 23:14:51 1.7
-***************
-*** 215,221 ****
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-!
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
---- 215,221 ----
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-! extern volatile sig_atomic_t sig_to_process;
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
-***************
-*** 254,260 ****
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &amp;sig_to_block, &amp;oset);
-
---- 254,260 ----
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &amp;sig_to_block, &amp;oset);
diff --git a/mit-pthreads/patches/p155 b/mit-pthreads/patches/p155
deleted file mode 100755
index dbdfa7de899..00000000000
--- a/mit-pthreads/patches/p155
+++ /dev/null
@@ -1,96 +0,0 @@
-<HEAD><TITLE>discuss@charon.mit.edu: [155] in "Pthreads Bugs"</TITLE>
-<H1>[155] in Pthreads Bugs</H1></HEAD>
-<A HREF="/"><IMG SRC="/i-d.gif" ALT="root"></A>
-<A HREF="?155"><IMG SRC="/i-back.gif" ALT="meeting"></A>
-<A HREF="/help.html"><IMG SRC="/i-help.gif" ALT="help"></A>
-<A HREF="1"><IMG SRC="/i-first.gif" ALT="first"></A>
-<IMG SRC="/n-fref.gif" ALT="">
-<IMG SRC="/n-pref.gif" ALT="">
-<A HREF="154"><IMG SRC="/i-prev.gif" ALT="previous"></A>
-<A HREF="156"><IMG SRC="/i-next.gif" ALT="next"></A>
-<IMG SRC="/n-nref.gif" ALT="">
-<IMG SRC="/n-lref.gif" ALT="">
-<A HREF="161"><IMG SRC="/i-last.gif" ALT="last"></A>
-<HR><H2>pthread_kill() Bug</H2>
-<H3>daemon@ATHENA.MIT.EDU (Thu Dec 26 20:34:45 1996
-)</H3>
-<PRE>
-From: Chris Colohan &lt;colohan@eecg.toronto.edu&gt;
-To: pthreads-bugs@MIT.EDU, proven@MIT.EDU
-Date: Thu, 26 Dec 1996 20:33:48 -0500
-
-pthread_kill() has a problem in PThreads 1.60beta6. It checks to see
-if the target thread is in the state PS_SIGWAIT, and if it is it
-reschedules it. But it does not check if there is more than one
-thread in the PS_SIGWAIT state, and hence mangles the pthread_sigwait
-linked list, potentially resulting in threads getting blocked forever,
-and signals never being delivered. I have a *very* contrived test
-case that demonstrates this problem if you would like it. Please let
-me know...
-
-Chris
-===
-
-Diffs created with diff -c:
-
-*** /home/colohan/thesis/t/pthreads-1_60_beta6/pthreads/pthread_kill.c Tue Feb 21 03:07:18 1995
---- pthread_kill.c Thu Dec 26 19:50:22 1996
-***************
-*** 41,51 ****
---- 41,58 ----
-
- #include &lt;pthread.h&gt;
-
-+ /* Defined in sig.c, a linked list of threads currently
-+ * blocked in sigwait(): */
-+ extern struct pthread * pthread_sigwait;
-+
-+
- /* ==========================================================================
- * pthread_kill()
- */
- int pthread_kill(struct pthread * pthread, int sig)
- {
-+ struct pthread ** pthread_ptr;
-+
- pthread_sched_prevent();
-
- /* Check who is the current owner of pthread */
-***************
-*** 53,62 ****
- if (0) {
- } else {
- if (pthread-&gt;state == PS_SIGWAIT) {
-! if (sigismember(pthread-&gt;data.sigwait, sig)) {
-! *(int *)(pthread-&gt;ret) = sig;
-! pthread_sched_other_resume(pthread);
-! return(OK);
- }
- }
- sigaddset(&amp;(pthread-&gt;sigpending), sig);
---- 60,84 ----
- if (0) {
- } else {
- if (pthread-&gt;state == PS_SIGWAIT) {
-! if(sigismember(pthread-&gt;data.sigwait, sig)) {
-! for (pthread_ptr = &amp;pthread_sigwait;
-! (*pthread_ptr);
-! pthread_ptr = &amp;((*pthread_ptr)-&gt;next)) {
-! if ((*pthread_ptr) == pthread) {
-!
-! /* Take the thread out of the
-! * pthread_sigwait linked list: */
-! *pthread_ptr=(*pthread_ptr)-&gt;next;
-!
-! *(int *)(pthread-&gt;ret) = sig;
-! pthread_sched_other_resume(pthread);
-! return(OK);
-! }
-! }
-! /* A thread should not be in the state PS_SIGWAIT
-! * without being in the pthread_sigwait linked
-! * list: */
-! PANIC();
- }
- }
- sigaddset(&amp;(pthread-&gt;sigpending), sig);
diff --git a/mit-pthreads/pthreads/GNUmakefile.inc b/mit-pthreads/pthreads/GNUmakefile.inc
deleted file mode 100644
index c8621495bac..00000000000
--- a/mit-pthreads/pthreads/GNUmakefile.inc
+++ /dev/null
@@ -1,46 +0,0 @@
-# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# pthread sources
-VPATH := $(VPATH):${srcdir}/pthreads
-
-SRCS:= cleanup.c cond.c fd.c fd_kern.c fd_pipe.c fd_sysv.c file.c globals.c \
- malloc.c mutex.c pthread.c pthread_attr.c queue.c signal.c machdep.c \
- syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
- specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
- dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c \
- pthread_cancel.c panic.c $(SRCS)
-
-ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
-SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
- case " $(SYSCALL_EXCEPTIONS) " in \
- *" "$$s" "*) ;; \
- *) echo $$s ;; \
- esac ; \
- done
-STD_SYSCALLS:=$(shell $(SYSCALL_FILTER_RULE))
-STD_SYSCALL_FILES:= $(addprefix S,$(addsuffix .o,$(STD_SYSCALLS)))
-EXTRA_OBJS := $(EXTRA_OBJS) syscalls.o
-# EXTRA_OBJS := $(EXTRA_OBJS) $(STD_SYSCALL_FILES)
-
-ifndef SYSCALL_PIC_COMPILE
-SYSCALL_PIC_COMPILE=true
-endif
-
-obj/syscalls.o: syscall-template.S
- -rm -rf obj/syscalls
- mkdir obj/syscalls
- for syscall in $(STD_SYSCALLS) ; do \
- echo $$syscall ; \
- $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -c syscall-template.S -o obj/syscalls/S$$syscall.o ; \
- $(SYSCALL_PIC_COMPILE) ; \
- done
- x=`pwd` && cd obj/syscalls && ld -r -o ../syscalls.o S*.o && cd $$x
- rm -r obj/syscalls
-endif
-
-syscall.o: ${.CURDIR}/pthreads/syscall.S
- cpp ${CPPFLAGS} ${.CURDIR}/pthreads/syscall.S > syscall.i
- as syscall.i
- rm syscall.i
- mv a.out syscall.o
diff --git a/mit-pthreads/pthreads/Makefile.inc b/mit-pthreads/pthreads/Makefile.inc
deleted file mode 100644
index 3939d57de6e..00000000000
--- a/mit-pthreads/pthreads/Makefile.inc
+++ /dev/null
@@ -1,75 +0,0 @@
-# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# pthread sources
-.PATH: ${srcdir}/pthreads
-
-SRCS+= cleanup.c cond.c fd.c fd_kern.c fd_pipe.c file.c globals.c malloc.c \
- mutex.c pthread.c pthread_attr.c queue.c signal.c machdep.c syscall.S \
- pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
- process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
- dump_state.c pthread_kill.c condattr.c pthread_cancel.c panic.c
-
-.if $(HAVE_SYSCALL_TEMPLATE) == yes
-OBJS+= syscalls.o
-.if !defined(NOPIC)
-SOBJS+= syscalls.so
-SYSCALL_PIC_COMPILE= $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -DPIC -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.so
-.else
-SYSCALL_PIC_COMPILE= true
-.endif
-.if !defined(NOPROFILE)
-POBJS+= syscalls.po
-SYSCALL_PROF_COMPILE= $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -pg -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.po
-.else
-SYSCALL_PROF_COMPILE= true
-.endif
-
-OPSYS!= uname -s
-
-syscalls.o syscalls.so syscalls.po : syscall-template.S
- -rm -rf ${.OBJDIR}/syscalls
- mkdir ${.OBJDIR}/syscalls
- for syscall in $(AVAILABLE_SYSCALLS) ; do \
- case " $(SYSCALL_EXCEPTIONS) " in \
- *" "$$syscall" "*) ;; \
- *) echo $$syscall ; \
- $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.o ; \
- $(SYSCALL_PIC_COMPILE) ; \
- $(SYSCALL_PROF_COMPILE) ;; \
- esac ; \
- done
- x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.o *.o && cd $$x
-.if !defined(NOPIC)
- x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.so *.so && cd $$x
-.endif
-.if !defined(NOPROFILE)
- x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.po *.po && cd $$x
-.endif
- rm -r ${.OBJDIR}/syscalls
-.endif
-
-syscall.o: syscall.S
-.if (${OPSYS} == "FreeBSD")
- $(CC) -c -x assembler-with-cpp -o syscall.o ${.CURDIR}/syscall.S
-.else
- cpp ${CPPFLAGS} ${.CURDIR}/syscall.S > syscall.i
- as syscall.i
- rm syscall.i
- mv a.out syscall.o
-.endif
-
-syscall.po: syscall.S
-.if (${OPSYS} == "FreeBSD")
- $(CC) -c -x assembler-with-cpp -o syscall.po ${.CURDIR}/syscall.S
-.else
- cpp ${CPPFLAGS} ${.CURDIR}/syscall.S > syscall.i
- as syscall.i
- rm syscall.i
- mv a.out syscall.po
-.endif
-
-MAN2+=
-
-MAN3+=
-
diff --git a/mit-pthreads/pthreads/_exit.c b/mit-pthreads/pthreads/_exit.c
deleted file mode 100644
index fde795011ce..00000000000
--- a/mit-pthreads/pthreads/_exit.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* ==== _exit.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : The locking functions for stdio.
- *
- * 1.00 94/09/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <fcntl.h>
-
-/* ==========================================================================
- * _exit()
- *
- * Change all file descriptors back to their original state,
- * before exiting for good.
- */
-void _exit(int status)
-{
- int fd;
-
- pthread_sched_prevent();
-
- for (fd = 0; fd < dtablesize; fd++) {
- if (fd_table[fd] == NULL) {
- continue;
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[fd]->ops) || (fd_table[fd]->ops->use_kfds != 1)) {
- continue;
- }
- switch (fd_table[fd]->type) {
- case FD_HALF_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_HALF_DUPLEX;
- break;
- case FD_FULL_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_FULL_DUPLEX;
- break;
- default:
- break;
- }
- }
- machdep_sys_exit(status);
-}
-
diff --git a/mit-pthreads/pthreads/cleanup.c b/mit-pthreads/pthreads/cleanup.c
deleted file mode 100644
index 3eb096b8337..00000000000
--- a/mit-pthreads/pthreads/cleanup.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ==== cleanup.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread attribute functions.
- *
- * 1.20 94/02/13 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* ==========================================================================
- * pthread_cleanup_push()
- */
-int pthread_cleanup_push(void (*routine)(void *), void *routine_arg)
-{
- struct pthread_cleanup *new;
- int ret;
-
- if ((new = (struct pthread_cleanup*)malloc(sizeof(struct pthread_cleanup))))
- {
- new->routine = routine;
- new->routine_arg = routine_arg;
- new->next = pthread_run->cleanup;
-
- pthread_run->cleanup = new;
- ret = OK;
- } else {
- ret = ENOMEM;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_cleanup_pop()
- */
-void pthread_cleanup_pop(int execute)
-{
- struct pthread_cleanup *old;
-
- if ((old = pthread_run->cleanup))
- {
- pthread_run->cleanup = old->next;
- if (execute) {
- old->routine(old->routine_arg);
- }
- free(old);
- }
-}
-
diff --git a/mit-pthreads/pthreads/cond.c b/mit-pthreads/pthreads/cond.c
deleted file mode 100644
index 8dacd0397ce..00000000000
--- a/mit-pthreads/pthreads/cond.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/* ==== cond.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Condition variable functions.
- *
- * 1.00 93/10/28 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <timers.h>
-#include <errno.h>
-
-#ifndef ETIME
-#define ETIME ETIMEDOUT
-#endif
-
-/* ==========================================================================
- * pthread_cond_is_debug()
- *
- * Check that cond is a debug cond and if so returns entry number into
- * array of debug condes.
- */
-static int pthread_cond_debug_count = 0;
-static pthread_cond_t ** pthread_cond_debug_ptrs = NULL;
-static pthread_mutex_t pthread_cond_debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static inline int pthread_cond_is_debug(pthread_cond_t * cond)
-{
- int i;
-
- for (i = 0; i < pthread_cond_debug_count; i++) {
- if (pthread_cond_debug_ptrs[i] == cond) {
- return(i);
- }
- }
- return(NOTOK);
-}
-/* ==========================================================================
- * pthread_cond_init()
- *
- * In this implementation I don't need to allocate memory.
- * ENOMEM, EAGAIN should never be returned. Arch that have
- * weird constraints may need special coding.
- */
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
-{
- enum pthread_condtype type;
-
- /* Only check if attr specifies some mutex type other than fast */
- if ((cond_attr) && (cond_attr->c_type != COND_TYPE_FAST)) {
- if (cond_attr->c_type >= COND_TYPE_MAX) {
- return(EINVAL);
- }
- type = cond_attr->c_type;
- } else {
- type = COND_TYPE_FAST;
- }
-
- switch (type) {
- case COND_TYPE_FAST:
- case COND_TYPE_COUNTING_FAST:
- break;
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_cond_t ** new;
-
- if ((new = (pthread_cond_t **)realloc(pthread_cond_debug_ptrs,
- (pthread_cond_debug_count + 1) * (sizeof(void *)))) == NULL) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- return(ENOMEM);
- }
- pthread_cond_debug_ptrs = new;
- pthread_cond_debug_ptrs[pthread_cond_debug_count++] = cond;
- } else {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- return(EBUSY);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- break;
- case COND_TYPE_STATIC_FAST:
- defualt:
- return(EINVAL);
- break;
- }
-
- /* Set all other paramaters */
- pthread_queue_init(&cond->c_queue);
- cond->c_flags |= COND_FLAGS_INITED;
- cond->c_type = type;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_cond_destroy()
- */
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
- int i;
-
- /* Only check if cond is of type other than fast */
- switch(cond->c_type) {
- case COND_TYPE_FAST:
- case COND_TYPE_COUNTING_FAST:
- break;
- case COND_TYPE_DEBUG:
- if (pthread_queue_get(&(cond->c_queue))) {
- return(EBUSY);
- }
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if ((i = pthread_cond_is_debug(cond)) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- return(EINVAL);
- }
-
- /* Remove the cond from the list of debug condition variables */
- pthread_cond_debug_ptrs[i] =
- pthread_cond_debug_ptrs[--pthread_cond_debug_count];
- pthread_cond_debug_ptrs[pthread_cond_debug_count] = NULL;
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- break;
- case COND_TYPE_STATIC_FAST:
- default:
- return(EINVAL);
- break;
- }
-
- /* Cleanup cond, others might want to use it. */
- pthread_queue_init(&cond->c_queue);
- cond->c_flags = 0;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_cond_wait()
- */
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- int rval;
-
- pthread_sched_prevent();
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- /*
- * Fast condition variables do not check for any error conditions.
- */
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
- pthread_queue_enq(&cond->c_queue, pthread_run);
- pthread_mutex_unlock(mutex);
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_WAIT_EVENT(pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- pthread_run->data.mutex = NULL;
-
- rval = pthread_mutex_lock(mutex);
- return(rval);
- break;
- case COND_TYPE_COUNTING_FAST:
- {
- int count = mutex->m_data.m_count;
-
- pthread_queue_enq(&cond->c_queue, pthread_run);
- pthread_mutex_unlock(mutex);
- mutex->m_data.m_count = 1;
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_WAIT_EVENT(pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- pthread_run->data.mutex = NULL;
-
- rval = pthread_mutex_lock(mutex);
- mutex->m_data.m_count = count;
- return(rval);
- break;
- }
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_cond_timedwait()
- */
-int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
- const struct timespec * abstime)
-{
- struct timespec current_time, new_time;
- int rval = OK;
-
- pthread_sched_prevent();
- machdep_gettimeofday(& current_time);
-
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- /*
- * Fast condition variables do not check for any error conditions.
- */
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
-
- /* Set pthread wakeup time*/
- pthread_run->wakeup_time = *abstime;
-
- /* Install us on the sleep queue */
- sleep_schedule (&current_time, &(pthread_run->wakeup_time));
-
- pthread_queue_enq(&cond->c_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
- SET_ERRNO(ETIME);
- rval = ETIME;
- }
-
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_mutex_lock(mutex);
- return(rval);
- break;
- case COND_TYPE_COUNTING_FAST:
- {
- int count = mutex->m_data.m_count;
-
- /* Set pthread wakeup time*/
- pthread_run->wakeup_time = *abstime;
-
- /* Install us on the sleep queue */
- sleep_schedule (&current_time, &(pthread_run->wakeup_time));
-
- pthread_queue_enq(&cond->c_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
- SET_ERRNO(ETIME);
- rval = ETIME;
- }
-
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_mutex_lock(mutex);
- mutex->m_data.m_count = count;
- return(rval);
- break;
- }
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_cond_signal()
- */
-int pthread_cond_signal(pthread_cond_t *cond)
-{
- struct pthread *pthread;
- int rval;
-
- pthread_sched_prevent();
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
- if (pthread = pthread_queue_deq(&cond->c_queue)) {
- if ((SET_PF_DONE_EVENT(pthread)) == OK) {
- pthread_sched_other_resume(pthread);
- } else {
- pthread_sched_resume();
- }
- return(OK);
- }
- rval = OK;
- break;
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_cond_broadcast()
- *
- * Not much different then the above routine.
- */
-int pthread_cond_broadcast(pthread_cond_t *cond)
-{
- struct pthread * pthread, * high_pthread, * low_pthread;
- int rval;
-
- pthread_sched_prevent();
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
- if (pthread = pthread_queue_deq(&cond->c_queue)) {
- pthread->state = PS_RUNNING;
- high_pthread = pthread;
-
- while (pthread = pthread_queue_deq(&cond->c_queue)) {
- if (pthread->pthread_priority >
- high_pthread->pthread_priority) {
- low_pthread = high_pthread;
- high_pthread = pthread;
- } else {
- low_pthread = pthread;
- }
- if ((SET_PF_DONE_EVENT(low_pthread)) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue,
- low_pthread);
- low_pthread->state = PS_RUNNING;
- }
- }
- if ((SET_PF_DONE_EVENT(high_pthread)) == OK) {
- pthread_sched_other_resume(high_pthread);
- } else {
- pthread_sched_resume();
- }
- return(OK);
- }
- rval = OK;
- break;
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
diff --git a/mit-pthreads/pthreads/condattr.c b/mit-pthreads/pthreads/condattr.c
deleted file mode 100644
index ac010bdf4b1..00000000000
--- a/mit-pthreads/pthreads/condattr.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* ==== condattr.c ===========================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Mutex functions.
- *
- * 1.00 95/08/22 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-/* ==========================================================================
- * pthread_condattr_init()
- */
-int pthread_condattr_init(pthread_condattr_t *attr)
-{
- attr->c_type = COND_TYPE_FAST;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_condattr_destroy()
- */
-int pthread_condattr_destroy(pthread_condattr_t *attr)
-{
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_condattr_settype()
- */
-int pthread_condattr_settype(pthread_condattr_t *attr, unsigned int type)
-{
- switch(type) {
- case PTHREAD_CONDTYPE_FAST:
- attr->c_type = COND_TYPE_FAST;
- break;
- case PTHREAD_CONDTYPE_RECURSIVE:
- attr->c_type = COND_TYPE_COUNTING_FAST;
- break;
- case PTHREAD_CONDTYPE_DEBUG:
- attr->c_type = COND_TYPE_DEBUG;
- break;
- default:
- return(EINVAL);
- }
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_condattr_gettype()
- */
-int pthread_condattr_gettype(pthread_condattr_t *attr, unsigned int * type)
-{
- *type = (unsigned int)attr->c_type;
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/dump_state.c b/mit-pthreads/pthreads/dump_state.c
deleted file mode 100644
index 3d9840bad64..00000000000
--- a/mit-pthreads/pthreads/dump_state.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ==== dump_state.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Bogus debugging output routines.
- *
- * 1.00 95/02/08 snl
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * pthread_dump_state()
- *
- * Totally, totally bogus routine to dump the state of pthreads.
- */
-
-void
-pthread_dump_state()
-{
- pthread_t thread;
-
- for (thread = pthread_link_list; thread; thread = thread->pll) {
- printf("Thread %lx", thread);
- if (thread == pthread_initial)
- printf("*");
- if (thread == pthread_run)
- printf("^");
- printf(" ");
- switch (thread->state) {
- case PS_RUNNING: printf("RUNNING "); break;
- case PS_MUTEX_WAIT: printf("MUTEX_WAIT "); break;
- case PS_COND_WAIT: printf("COND_WAIT "); break;
- case PS_FDLR_WAIT: printf("FDLR_WAIT "); break;
- case PS_FDLW_WAIT: printf("FDLW_WAIT "); break;
- case PS_FDR_WAIT: printf("FDR_WAIT "); break;
- case PS_FDW_WAIT: printf("FDW_WAIT "); break;
- case PS_SELECT_WAIT: printf("SELECT "); break;
- case PS_SLEEP_WAIT: printf("SLEEP_WAIT "); break;
- case PS_WAIT_WAIT: printf("WAIT_WAIT "); break;
- case PS_SIGWAIT: printf("SIGWAIT "); break;
- case PS_JOIN: printf("JOIN "); break;
- case PS_DEAD: printf("DEAD "); break;
- default: printf("*UNKNOWN %d* ", thread->state);
- break;
- }
- switch (thread->attr.schedparam_policy) {
- case SCHED_RR: printf("RR "); break;
- case SCHED_IO: printf("IO "); break;
- case SCHED_FIFO: printf("FIFO "); break;
- case SCHED_OTHER: printf("OTHER "); break;
- default: printf("*UNKNOWN %d* ",
- thread->attr.schedparam_policy);
- break;
- }
- }
-}
diff --git a/mit-pthreads/pthreads/errno.c b/mit-pthreads/pthreads/errno.c
deleted file mode 100644
index bc680235424..00000000000
--- a/mit-pthreads/pthreads/errno.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ==== errno.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Return the pointer to the threads errno address.
- *
- * 1.32 94/05/25 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* ==========================================================================
- * __error()
- */
-int * __error()
-{
- if (!pthread_run->error_p) {
- pthread_run->error_p = &pthread_run->error;
- }
- return(pthread_run->error_p);
-}
diff --git a/mit-pthreads/pthreads/fd.c b/mit-pthreads/pthreads/fd.c
deleted file mode 100644
index 3eb59c11bd1..00000000000
--- a/mit-pthreads/pthreads/fd.c
+++ /dev/null
@@ -1,1083 +0,0 @@
-/* ==== fd.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the syscalls dealing with fds.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h> /* For ioctl */
-#endif
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread/posix.h>
-
-/*
- * These first functions really should not be called by the user.
- *
- * I really should dynamically figure out what the table size is.
- */
-static pthread_mutex_t fd_table_mutex = PTHREAD_MUTEX_INITIALIZER;
-static const int dtablecount = 4096/sizeof(struct fd_table_entry);
-int dtablesize;
-
-static int fd_get_pthread_fd_from_kernel_fd( int );
-
-/* ==========================================================================
- * Allocate dtablecount entries at once and populate the fd_table.
- *
- * fd_init_entry()
- */
-int fd_init_entry(int entry)
-{
- struct fd_table_entry *fd_entry;
- int i, round;
-
- if (fd_table[entry] == NULL) {
- round = entry - entry % dtablecount;
-
- if ((fd_entry = (struct fd_table_entry *)malloc(
- sizeof(struct fd_table_entry) * dtablecount)) == NULL) {
- return(NOTOK);
- }
-
- for (i = 0; i < dtablecount && round+i < dtablesize; i++) {
- fd_table[round + i] = &fd_entry[i];
-
- fd_table[round + i]->ops = NULL;
- fd_table[round + i]->type = FD_NT;
- fd_table[round + i]->fd.i = NOTOK;
- fd_table[round + i]->flags = 0;
- fd_table[round + i]->count = 0;
-
- pthread_mutex_init(&(fd_table[round + i]->mutex), NULL);
- pthread_queue_init(&(fd_table[round + i]->r_queue));
- pthread_queue_init(&(fd_table[round + i]->w_queue));
- fd_table[round + i]->r_owner = NULL;
- fd_table[round + i]->w_owner = NULL;
- fd_table[round + i]->r_lockcount= 0;
- fd_table[round + i]->w_lockcount= 0;
-
- fd_table[round + i]->next = NULL;
- }
- }
- return(OK);
-}
-
-/* ==========================================================================
- * fd_check_entry()
- */
-int fd_check_entry(unsigned int entry)
-{
- int ret = OK;
-
- pthread_mutex_lock(&fd_table_mutex);
-
- if (entry < dtablesize) {
- if (fd_table[entry] == NULL) {
- if (fd_init_entry(entry)) {
- SET_ERRNO(EBADF);
- ret = -EBADF;
- }
- }
- } else {
- SET_ERRNO(EBADF);
- ret = -EBADF;
- }
-
- pthread_mutex_unlock(&fd_table_mutex);
- return(ret);
-}
-
-/* ==========================================================================
- * fd_init()
- */
-void fd_init(void)
-{
- int i;
-
- if ((dtablesize = machdep_sys_getdtablesize()) < 0) {
- /* Can't figure out the table size. */
- PANIC();
- }
-
- /* select() can only handle FD_SETSIZE descriptors, so our inner loop will
- * break if dtablesize is higher than that. This should be removed if and
- * when the inner loop is rewritten to use poll(). */
- if (dtablesize > FD_SETSIZE) {
- dtablesize = FD_SETSIZE;
- }
-
- if (fd_table = (struct fd_table_entry **)malloc(
- sizeof(struct fd_table_entry) * dtablesize)) {
- memset(fd_table, 0, sizeof(struct fd_table_entry) * dtablesize);
- if (fd_check_entry(0) == OK) {
- return;
- }
- }
-
- /*
- * There isn't enough memory to allocate a fd table at init time.
- * This is a problem.
- */
- PANIC();
-
-}
-
-/* ==========================================================================
- * fd_allocate()
- */
-int fd_allocate()
-{
- pthread_mutex_t * mutex;
- int i;
-
- for (i = 0; i < dtablesize; i++) {
- if (fd_check_entry(i) == OK) {
- mutex = &(fd_table[i]->mutex);
- if (pthread_mutex_trylock(mutex)) {
- continue;
- }
- if (fd_table[i]->count || fd_table[i]->r_owner
- || fd_table[i]->w_owner) {
- pthread_mutex_unlock(mutex);
- continue;
- }
- if (fd_table[i]->type == FD_NT) {
- /* Test to see if the kernel version is in use */
- if ((machdep_sys_fcntl(i, F_GETFL, NULL)) >= OK) {
- /* If so continue; */
- pthread_mutex_unlock(mutex);
- continue;
- }
- }
- fd_table[i]->count++;
- pthread_mutex_unlock(mutex);
- return(i);
- }
- }
- SET_ERRNO(ENFILE);
- return(NOTOK);
-}
-
-/*----------------------------------------------------------------------
- * Function: fd_get_pthread_fd_from_kernel_fd
- * Purpose: get the fd_table index of a kernel fd
- * Args: fd = kernel fd to convert
- * Returns: fd_table index, -1 if not found
- * Notes:
- *----------------------------------------------------------------------*/
-static int
-fd_get_pthread_fd_from_kernel_fd( int kfd )
-{
- int j;
-
- /* This is *SICK*, but unless there is a faster way to
- * turn a kernel fd into an fd_table index, this has to do.
- */
- for( j=0; j < dtablesize; j++ ) {
- if( fd_table[j] &&
- fd_table[j]->type != FD_NT &&
- fd_table[j]->type != FD_NIU &&
- fd_table[j]->fd.i == kfd ) {
- return j;
- }
- }
-
- /* Not listed byfd, Check for kernel fd == pthread fd */
- if( fd_table[kfd] == NULL || fd_table[kfd]->type == FD_NT ) {
- /* Assume that the kernel fd is the same */
- return kfd;
- }
-
- return NOTOK; /* Not found */
-}
-
-/* ==========================================================================
- * fd_basic_basic_unlock()
- *
- * The real work of unlock without the locking of fd_table[fd].lock.
- */
-void fd_basic_basic_unlock(struct fd_table_entry * entry, int lock_type)
-{
- struct pthread *pthread;
-
- if (entry->r_owner == pthread_run) {
- if ((entry->type == FD_HALF_DUPLEX) ||
- (entry->type == FD_TEST_HALF_DUPLEX) ||
- (lock_type == FD_READ) || (lock_type == FD_RDWR)) {
- if (entry->r_lockcount == 0) {
- if (pthread = pthread_queue_deq(&entry->r_queue)) {
- pthread_sched_prevent();
- entry->r_owner = pthread;
- if ((SET_PF_DONE_EVENT(pthread)) == OK) {
- pthread_sched_other_resume(pthread);
- } else {
- pthread_sched_resume();
- }
- } else {
- entry->r_owner = NULL;
- }
- } else {
- entry->r_lockcount--;
- }
- }
- }
-
- if (entry->w_owner == pthread_run) {
- if ((entry->type != FD_HALF_DUPLEX) &&
- (entry->type != FD_TEST_HALF_DUPLEX) &&
- ((lock_type == FD_WRITE) || (lock_type == FD_RDWR))) {
- if (entry->w_lockcount == 0) {
- if (pthread = pthread_queue_deq(&entry->w_queue)) {
- pthread_sched_prevent();
- entry->w_owner = pthread;
- if ((SET_PF_DONE_EVENT(pthread)) == OK) {
- pthread_sched_other_resume(pthread);
- } else {
- pthread_sched_resume();
- }
- } else {
- entry->w_owner = NULL;
- }
- } else {
- entry->w_lockcount--;
- }
- }
- }
-}
-
-/* ==========================================================================
- * fd_basic_unlock()
- */
-void fd_basic_unlock(int fd, int lock_type)
-{
- fd_basic_basic_unlock(fd_table[fd], lock_type);
-}
-
-/* ==========================================================================
- * fd_unlock()
- */
-void fd_unlock(int fd, int lock_type)
-{
- pthread_mutex_t *mutex;
-
- mutex = &(fd_table[fd]->mutex);
- pthread_mutex_lock(mutex);
- fd_basic_basic_unlock(fd_table[fd], lock_type);
- pthread_mutex_unlock(mutex);
-}
-
-/* ==========================================================================
- * fd_basic_lock()
- *
- * The real work of lock without the locking of fd_table[fd].lock.
- * Be sure to leave the lock the same way you found it. i.e. locked.
- */
-int fd_basic_lock(unsigned int fd, int lock_type, pthread_mutex_t * mutex,
- struct timespec * timeout)
-{
- semaphore *plock;
-
- switch (fd_table[fd]->type) {
- case FD_NIU:
- /* If not in use return EBADF error */
- SET_ERRNO(EBADF);
- return(NOTOK);
- break;
- case FD_NT:
- /*
- * If not tested, test it and see if it is valid
- * If not ok return EBADF error
- */
- fd_kern_init(fd);
- if (fd_table[fd]->type == FD_NIU) {
- SET_ERRNO(EBADF);
- return(NOTOK);
- }
- break;
- case FD_TEST_HALF_DUPLEX:
- case FD_TEST_FULL_DUPLEX:
- /* If a parent process reset the fd to its proper state */
- if (!fork_lock) {
- /* It had better be a kernel fd */
- fd_kern_reset(fd);
- }
- break;
- default:
- break;
- }
-
- if ((fd_table[fd]->type == FD_HALF_DUPLEX) ||
- (fd_table[fd]->type == FD_TEST_HALF_DUPLEX) ||
- (lock_type == FD_READ) || (lock_type == FD_RDWR)) {
- if (fd_table[fd]->r_owner) {
- if (fd_table[fd]->r_owner != pthread_run) {
- pthread_sched_prevent();
- pthread_queue_enq(&fd_table[fd]->r_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
-
- /* If we're the owner then we have to cancel the sleep */
- if (fd_table[fd]->r_owner != pthread_run) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- SET_ERRNO(ETIMEDOUT);
- return(NOTOK);
- }
- sleep_cancel(pthread_run);
- } else {
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- fd_table[fd]->r_lockcount++;
- }
- }
- fd_table[fd]->r_owner = pthread_run;
- }
- if ((fd_table[fd]->type != FD_HALF_DUPLEX) &&
- (fd_table[fd]->type != FD_TEST_HALF_DUPLEX) &&
- ((lock_type == FD_WRITE) || (lock_type == FD_RDWR))) {
- if (fd_table[fd]->w_owner) {
- if (fd_table[fd]->w_owner != pthread_run) {
- pthread_sched_prevent();
- pthread_queue_enq(&fd_table[fd]->w_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
-
- /* If we're the owner then we have to cancel the sleep */
- if (fd_table[fd]->w_owner != pthread_run) {
- if (lock_type == FD_RDWR) {
- /* Unlock current thread */
- fd_basic_unlock(fd, FD_READ);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- SET_ERRNO(ETIMEDOUT);
- return(NOTOK);
- }
- sleep_cancel(pthread_run);
- } else {
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- fd_table[fd]->w_lockcount++;
- }
- }
- fd_table[fd]->w_owner = pthread_run;
- }
- if (!fd_table[fd]->count) {
- fd_basic_unlock(fd, lock_type);
- return(NOTOK);
- }
- return(OK);
-}
-
-/*----------------------------------------------------------------------
- * Function: fd_unlock_for_cancel
- * Purpose: Unlock all fd locks held prior to being cancelled
- * Args: void
- * Returns:
- * OK or NOTOK
- * Notes:
- * Assumes the kernel is locked on entry
- *----------------------------------------------------------------------*/
-int
-fd_unlock_for_cancel( void )
-{
- int i, fd;
- struct pthread_select_data *data;
- int rdlk, wrlk, lktype;
- int found;
-
- /* What we do depends on the previous state of the thread */
- switch( pthread_run->old_state ) {
- case PS_RUNNING:
- case PS_JOIN:
- case PS_SLEEP_WAIT:
- case PS_WAIT_WAIT:
- case PS_SIGWAIT:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_DEAD:
- case PS_UNALLOCED:
- break; /* Nothing to do */
-
- case PS_COND_WAIT:
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP );
- /* Must reaquire the mutex according to the standard */
- if( pthread_run->data.mutex == NULL ) {
- PANIC();
- }
- pthread_mutex_lock( pthread_run->data.mutex );
- break;
-
- case PS_FDR_WAIT:
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
- /* Free the lock on the fd being used */
- fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
- if( fd == NOTOK ) {
- PANIC(); /* Can't find fd */
- }
- fd_unlock( fd, FD_READ );
- break;
-
- case PS_FDW_WAIT: /* Waiting on i/o */
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
- /* Free the lock on the fd being used */
- fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
- if( fd == NOTOK ) {
- PANIC(); /* Can't find fd */
- }
- fd_unlock( fd, FD_WRITE );
- break;
-
- case PS_SELECT_WAIT:
- data = pthread_run->data.select_data;
-
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-
- for( i = 0; i < data->nfds; i++) {
- rdlk =(FD_ISSET(i,&data->readfds)
- || FD_ISSET(i,&data->exceptfds));
- wrlk = FD_ISSET(i, &data->writefds);
- lktype = rdlk ? (wrlk ? FD_RDWR : FD_READ) : FD_WRITE;
-
- if( ! (rdlk || wrlk) )
- continue; /* No locks, no unlock */
-
- if( (fd = fd_get_pthread_fd_from_kernel_fd( i )) == NOTOK ) {
- PANIC(); /* Can't find fd */
- }
-
- fd_unlock( fd, lktype );
- }
- break;
-
- case PS_MUTEX_WAIT:
- PANIC(); /* Should never cancel a mutex wait */
-
- default:
- PANIC(); /* Unknown thread status */
- }
-}
-
-/* ==========================================================================
- * fd_lock()
- */
-#define pthread_mutex_lock_timedwait(a, b) pthread_mutex_lock(a)
-
-int fd_lock(unsigned int fd, int lock_type, struct timespec * timeout)
-{
- struct timespec current_time;
- pthread_mutex_t *mutex;
- int error;
-
- if ((error = fd_check_entry(fd)) == OK) {
- mutex = &(fd_table[fd]->mutex);
- if (pthread_mutex_lock_timedwait(mutex, timeout)) {
- SET_ERRNO(ETIMEDOUT);
- return(-ETIMEDOUT);
- }
- error = fd_basic_lock(fd, lock_type, mutex, timeout);
- pthread_mutex_unlock(mutex);
- }
- return(error);
-}
-
-/* ==========================================================================
- * fd_free()
- *
- * Assumes fd is locked and owner by pthread_run
- * Don't clear the queues, fd_unlock will do that.
- */
-struct fd_table_entry * fd_free(int fd)
-{
- struct fd_table_entry *fd_valid;
-
- fd_valid = NULL;
- fd_table[fd]->r_lockcount = 0;
- fd_table[fd]->w_lockcount = 0;
- if (--fd_table[fd]->count) {
- fd_valid = fd_table[fd];
- fd_table[fd] = fd_table[fd]->next;
- fd_valid->next = fd_table[fd]->next;
- /* Don't touch queues of fd_valid */
- }
-
- fd_table[fd]->type = FD_NIU;
- fd_table[fd]->fd.i = NOTOK;
- fd_table[fd]->next = NULL;
- fd_table[fd]->flags = 0;
- fd_table[fd]->count = 0;
- return(fd_valid);
-}
-
-
-/* ==========================================================================
- * ======================================================================= */
-
-/* ==========================================================================
- * read_timedwait()
- */
-ssize_t read_timedwait(int fd, void *buf, size_t nbytes,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = fd_table[fd]->ops->read(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes, timeout);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * read()
- */
-ssize_t read(int fd, void *buf, size_t nbytes)
-{
- return(read_timedwait(fd, buf, nbytes, NULL));
-}
-
-/* ==========================================================================
- * readv_timedwait()
- */
-int readv_timedwait(int fd, const struct iovec *iov, int iovcnt,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = fd_table[fd]->ops->readv(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * readv()
- */
-ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
-{
- return(readv_timedwait(fd, iov, iovcnt, NULL));
-}
-
-/* ==========================================================================
- * write()
- */
-ssize_t write_timedwait(int fd, const void *buf, size_t nbytes,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK)
- {
- ret = fd_table[fd]->ops->write(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes,
- timeout);
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * write()
- */
-ssize_t write(int fd, const void * buf, size_t nbytes)
-{
- return(write_timedwait(fd, buf, nbytes, NULL));
-}
-
-/* ==========================================================================
- * writev_timedwait()
- */
-int writev_timedwait(int fd, const struct iovec *iov, int iovcnt,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- ret = fd_table[fd]->ops->writev(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * writev()
- */
-ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
-{
- return(writev_timedwait(fd, iov, iovcnt, NULL));
-}
-
-/* ==========================================================================
- * lseek()
- */
-off_t lseek(int fd, off_t offset, int whence)
-{
- off_t ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = fd_table[fd]->ops->seek(fd_table[fd]->fd,
- fd_table[fd]->flags, offset, whence);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * close()
- *
- * The whole close procedure is a bit odd and needs a bit of a rethink.
- * For now close() locks the fd, calls fd_free() which checks to see if
- * there are any other fd values poinging to the same real fd. If so
- * It breaks the wait queue into two sections those that are waiting on fd
- * and those waiting on other fd's. Those that are waiting on fd are connected
- * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT
- * RELEASED). close() then calls fd_unlock which give the fd to the next queued
- * element which determins that the fd is closed and then calls fd_unlock etc...
- *
- * XXX close() is even uglier now. You may assume that the kernel fd is the
- * same as fd if fd_table[fd] == NULL or if fd_table[fd]->type == FD_NT.
- * This is true because before any fd_table[fd] is allocated the corresponding
- * kernel fd must be checks to see if it's valid.
- */
-int close(int fd)
-{
- struct fd_table_entry * entry;
- pthread_mutex_t *mutex;
- union fd_data realfd;
- int ret, flags;
-
- if(fd < 0 || fd >= dtablesize)
- {
- SET_ERRNO(EBADF);
- return -1;
- }
- /* Need to lock the newfd by hand */
- pthread_mutex_lock(&fd_table_mutex);
- if (fd_table[fd]) {
- pthread_mutex_unlock(&fd_table_mutex);
- mutex = &(fd_table[fd]->mutex);
- pthread_mutex_lock(mutex);
-
- /*
- * XXX Gross hack ... because of fork(), any fd closed by the
- * parent should not change the fd of the child, unless it owns it.
- */
- switch(fd_table[fd]->type) {
- case FD_NIU:
- pthread_mutex_unlock(mutex);
- ret = -EBADF;
- break;
- case FD_NT:
- /*
- * If it's not tested then the only valid possibility is it's
- * kernel fd.
- */
- ret = machdep_sys_close(fd);
- fd_table[fd]->type = FD_NIU;
- pthread_mutex_unlock(mutex);
- break;
- case FD_TEST_FULL_DUPLEX:
- case FD_TEST_HALF_DUPLEX:
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
- if ((entry = fd_free(fd)) == NULL) {
- ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
- /* There can't be any others waiting for fd. */
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- mutex = &(fd_table[fd]->mutex);
- }
- pthread_mutex_unlock(mutex);
- break;
- default:
- ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
- if (ret == OK) {
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
- pthread_mutex_unlock(mutex);
- if ((entry = fd_free(fd)) == NULL) {
- ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
- fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
- fd_unlock(fd, FD_RDWR);
- } else {
- pthread_mutex_unlock(mutex);
- }
- break;
- }
- } else {
- /* Don't bother creating a table entry */
- pthread_mutex_unlock(&fd_table_mutex);
- ret = machdep_sys_close(fd);
- }
- if( ret < 0) {
- SET_ERRNO(-ret);
- ret = -1;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * fd_basic_dup()
- *
- *
- * This is a MAJOR guess!! I don't know if the mutext unlock is valid
- * in the BIG picture. But it seems to be needed to avoid deadlocking
- * with ourselves when we try to close the duped file descriptor.
- */
-static inline void fd_basic_dup(int fd, int newfd)
-{
- fd_table[newfd]->next = fd_table[fd]->next;
- fd_table[fd]->next = fd_table[newfd];
- fd_table[newfd] = fd_table[fd];
- fd_table[fd]->count++;
- pthread_mutex_unlock(&fd_table[newfd]->next->mutex);
-
-}
-
-/* ==========================================================================
- * dup2()
- *
- * Note: Always lock the lower number fd first to avoid deadlocks.
- * Note: Leave the newfd locked. It will be unlocked at close() time.
- * Note: newfd must be locked by hand so it can be closed if it is open,
- * or it won't be opened while dup is in progress.
- */
-int dup2(fd, newfd)
-{
- struct fd_table_entry * entry;
- pthread_mutex_t *mutex;
- union fd_data realfd;
- int ret, flags;
-
- if ((ret = fd_check_entry(newfd)) != OK)
- return ret;
-
- if (newfd < dtablesize) {
- if (fd < newfd) {
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- /* Need to lock the newfd by hand */
- mutex = &(fd_table[newfd]->mutex);
- pthread_mutex_lock(mutex);
-
- /* Is it inuse */
- if (fd_basic_lock(newfd, FD_RDWR, mutex, NULL) == OK) {
- realfd = fd_table[newfd]->fd;
- flags = fd_table[newfd]->flags;
- /* free it and check close status */
- if ((entry = fd_free(newfd)) == NULL) {
- entry = fd_table[newfd];
- entry->ops->close(realfd, flags);
- if (entry->r_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->r_queue.q_last->next =
- entry->r_queue.q_next;
- } else {
- fd_table[fd]->r_queue.q_next =
- entry->r_queue.q_next;
- }
- fd_table[fd]->r_queue.q_last =
- entry->r_queue.q_last;
- }
- if (entry->w_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->w_queue.q_last->next =
- entry->w_queue.q_next;
- } else {
- fd_table[fd]->w_queue.q_next =
- entry->w_queue.q_next;
- }
- fd_table[fd]->w_queue.q_last =
- entry->w_queue.q_last;
- }
- entry->r_queue.q_next = NULL;
- entry->w_queue.q_next = NULL;
- entry->r_queue.q_last = NULL;
- entry->w_queue.q_last = NULL;
- entry->r_owner = NULL;
- entry->w_owner = NULL;
- ret = OK;
- } else {
- fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
- }
- fd_basic_dup(fd, newfd);
- }
- fd_unlock(fd, FD_RDWR);
- } else {
- /* Need to lock the newfd by hand */
- mutex = &(fd_table[newfd]->mutex);
- pthread_mutex_lock(mutex);
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- /* Is newfd inuse */
- if ((ret = fd_basic_lock(newfd, FD_RDWR, mutex, NULL)) == OK) {
- realfd = fd_table[newfd]->fd;
- flags = fd_table[newfd]->flags;
- /* free it and check close status */
- if ((entry = fd_free(newfd)) == NULL) {
- entry = fd_table[newfd];
- entry->ops->close(realfd, flags);
- if (entry->r_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->r_queue.q_last->next =
- entry->r_queue.q_next;
- } else {
- fd_table[fd]->r_queue.q_next =
- entry->r_queue.q_next;
- }
- fd_table[fd]->r_queue.q_last =
- entry->r_queue.q_last;
- }
- if (entry->w_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->w_queue.q_last->next =
- entry->w_queue.q_next;
- } else {
- fd_table[fd]->w_queue.q_next =
- entry->w_queue.q_next;
- }
- fd_table[fd]->w_queue.q_last =
- entry->w_queue.q_last;
- }
- entry->r_queue.q_next = NULL;
- entry->w_queue.q_next = NULL;
- entry->r_queue.q_last = NULL;
- entry->w_queue.q_last = NULL;
- entry->r_owner = NULL;
- entry->w_owner = NULL;
- ret = OK;
- } else {
- fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
- fd_basic_dup(fd, newfd);
- }
- fd_unlock(fd, FD_RDWR);
- }
- }
- } else {
- ret = NOTOK;
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * dup()
- */
-int dup(int fd)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = fd_allocate();
- fd_basic_dup(fd, ret);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * fcntl()
- */
-int fcntl(int fd, int cmd, ...)
-{
- int ret, realfd, flags;
- struct flock *flock;
- semaphore *plock;
- va_list ap;
-
- flags = 0;
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- va_start(ap, cmd);
- switch(cmd) {
- case F_DUPFD:
- ret = fd_allocate();
- fd_basic_dup(va_arg(ap, int), ret);
- break;
- case F_SETFD:
- break;
- case F_GETFD:
- break;
- case F_GETFL:
- ret = fd_table[fd]->flags;
- break;
- case F_SETFL:
- flags = va_arg(ap, int);
- if ((ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
- fd_table[fd]->flags, cmd, flags | __FD_NONBLOCK)) == OK) {
- fd_table[fd]->flags = flags;
- }
- break;
-/* case F_SETLKW: */
- /*
- * Do the same as SETLK but if it fails with EACCES or EAGAIN
- * block the thread and try again later, not implemented yet
- */
-/* case F_SETLK: */
-/* case F_GETLK:
- flock = va_arg(ap, struct flock*);
- ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
- fd_table[fd]->flags, cmd, flock);
- break; */
- default:
- /* Might want to make va_arg use a union */
- ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
- fd_table[fd]->flags, cmd, va_arg(ap, void*));
- break;
- }
- va_end(ap);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * getdtablesize()
- */
-int getdtablesize()
-{
- return dtablesize;
-}
-
-/* ==========================================================================
- * ioctl()
- *
- * Really want to do a real implementation of this that parses the args ala
- * fcntl(), above, but it will have to be a totally platform-specific,
- * nightmare-on-elm-st-style sort of thing. Might even deserve its own file
- * ala select()... --SNL
- */
-#ifndef ioctl_request_type
-#define ioctl_request_type unsigned long /* Dummy patch by Monty */
-#endif
-
-int
-ioctl(int fd, ioctl_request_type request, ...)
-{
- int ret;
- pthread_va_list ap;
- caddr_t arg;
-
- va_start( ap, request ); /* Get the arg */
- arg = va_arg(ap,caddr_t);
- va_end( ap );
-
- if (fd < 0 || fd >= dtablesize)
- ret = NOTOK;
- else if (fd_table[fd]->fd.i == NOTOK)
- ret = machdep_sys_ioctl(fd, request, arg);
- else if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = machdep_sys_ioctl(fd_table[fd]->fd.i, request, arg);
- if( ret == 0 && request == FIONBIO ) {
- /* Properly set NONBLOCK flag */
- int v = *(int *)arg;
- if( v )
- fd_table[fd]->flags |= __FD_NONBLOCK;
- else
- fd_table[fd]->flags &= ~__FD_NONBLOCK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
diff --git a/mit-pthreads/pthreads/fd_kern.c b/mit-pthreads/pthreads/fd_kern.c
deleted file mode 100644
index f4ada4e4fd4..00000000000
--- a/mit-pthreads/pthreads/fd_kern.c
+++ /dev/null
@@ -1,1950 +0,0 @@
-/* ==== fd_kern.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Deals with the valid kernel fds.
- *
- * 1.00 93/09/27 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/compat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread/posix.h>
-#include <string.h>
-
-#if defined (HAVE_SYSCALL_SENDTO) && !defined (HAVE_SYSCALL_SEND)
-
-pthread_ssize_t machdep_sys_send (int fd, const void *msg, size_t len,
- int flags)
-{
- return machdep_sys_sendto (fd, msg, len, flags,
- (const struct sockaddr *) 0, 0);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECVFROM) && !defined (HAVE_SYSCALL_RECV)
-
-pthread_ssize_t machdep_sys_recv (int fd, void *buf, size_t len, int flags)
-{
- return machdep_sys_recvfrom (fd, buf, len, flags,
- (struct sockaddr *) 0, (int *) 0);
-}
-
-#endif
-
-/* ==========================================================================
- * Check if there is any signal with must be handled. Added by Monty
- * This could be somewhat system dependent but it should work.
- */
-
-static int fd_check_if_pending_signal(struct pthread *pthread)
-{
- int i;
- unsigned long *pending,*mask;
- if (!pthread->sigcount)
- return 0;
- pending= (unsigned long*) &pthread->sigpending;
- mask= (unsigned long*) &pthread->sigmask;
-
- for (i=0 ; i < sizeof(pthread->sigpending)/sizeof(unsigned long); i++)
- {
- if (*pending && (*mask ^ (unsigned) ~0L))
- return 1;
- pending++;
- mask++;
- }
- return 0;
-}
-
-/* ==========================================================================
- * Variables used by both fd_kern_poll and fd_kern_wait
- */
-struct pthread_queue fd_wait_read = PTHREAD_QUEUE_INITIALIZER;
-struct pthread_queue fd_wait_write = PTHREAD_QUEUE_INITIALIZER;
-struct pthread_queue fd_wait_select = PTHREAD_QUEUE_INITIALIZER;
-
-static struct timeval __fd_kern_poll_timeout = { 0, 0 }; /* Moved by monty */
-extern struct timeval __fd_kern_wait_timeout;
-extern volatile sig_atomic_t sig_to_process;
-
-/*
- * ==========================================================================
- * Do a select if there is someting to wait for.
- * This is to a combination of the old fd_kern_poll() and fd_kern_wait()
- * Return 1 if nothing to do.
- */
-
-static int fd_kern_select(struct timeval *timeout)
-{
- fd_set fd_set_read, fd_set_write, fd_set_except;
- struct pthread *pthread, *deq;
- int count, i;
-
- if (!fd_wait_read.q_next && !fd_wait_write.q_next && !fd_wait_select.q_next)
- return 1; /* Nothing to do */
-
- FD_ZERO(&fd_set_read);
- FD_ZERO(&fd_set_write);
- FD_ZERO(&fd_set_except);
- for (pthread = fd_wait_read.q_next; pthread; pthread = pthread->next)
- FD_SET(pthread->data.fd.fd, &fd_set_read);
- for (pthread = fd_wait_write.q_next; pthread; pthread = pthread->next)
- FD_SET(pthread->data.fd.fd, &fd_set_write);
- for (pthread = fd_wait_select.q_next; pthread; pthread = pthread->next)
- {
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- if (FD_ISSET(i, &pthread->data.select_data->exceptfds))
- FD_SET(i, &fd_set_except);
- if (FD_ISSET(i, &pthread->data.select_data->writefds))
- FD_SET(i, &fd_set_write);
- if (FD_ISSET(i, &pthread->data.select_data->readfds))
- FD_SET(i, &fd_set_read);
- }
- }
-
- /* Turn off interrupts for real while we set the timer. */
-
- if (timeout == &__fd_kern_wait_timeout)
- { /* from fd_kern_wait() */
- sigset_t sig_to_block, oset;
- sigfillset(&sig_to_block);
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
- __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
- }
- /*
- * There is a small but finite chance that an interrupt will
- * occure between the unblock and the select. Because of this
- * sig_handler_real() sets the value of __fd_kern_wait_timeout
- * to zero causing the select to do a poll instead of a wait.
- */
-
- while ((count = machdep_sys_select(dtablesize, &fd_set_read,
- &fd_set_write, &fd_set_except,
- timeout)) < OK)
- {
- if (count == -EINTR)
- return 0;
- PANIC();
- }
-
- for (pthread = fd_wait_read.q_next; pthread; ) {
- if (count && FD_ISSET(pthread->data.fd.fd, &fd_set_read) ||
- fd_check_if_pending_signal(pthread))
- {
- if (FD_ISSET(pthread->data.fd.fd, &fd_set_read))
- count--;
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_read, deq);
- if (SET_PF_DONE_EVENT(deq) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue, deq);
- deq->state = PS_RUNNING;
- }
- continue;
- }
- pthread = pthread->next;
- }
-
- for (pthread = fd_wait_write.q_next; pthread; ) {
- if (count && FD_ISSET(pthread->data.fd.fd, &fd_set_write) ||
- fd_check_if_pending_signal(pthread))
- {
- if (FD_ISSET(pthread->data.fd.fd, &fd_set_read))
- count--;
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_write, deq);
- if (SET_PF_DONE_EVENT(deq) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue, deq);
- deq->state = PS_RUNNING;
- }
- continue;
- }
- pthread = pthread->next;
- }
-
- for (pthread = fd_wait_select.q_next; pthread; )
- {
- int found_one=0; /* Loop fixed by monty */
- if (count)
- {
- fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
- memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
- sizeof(fd_set));
- memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
- sizeof(fd_set));
- memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
- sizeof(fd_set));
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- if (FD_ISSET(i, &tmp_exceptfds))
- {
- if (! FD_ISSET(i, &fd_set_except))
- FD_CLR(i, &tmp_exceptfds);
- else
- found_one=1;
- }
- if (FD_ISSET(i, &tmp_writefds))
- {
- if (! FD_ISSET(i, &fd_set_write))
- FD_CLR(i, &tmp_writefds);
- else
- found_one=1;
- }
- if (FD_ISSET(i, &tmp_readfds))
- {
- if (! FD_ISSET(i, &fd_set_read))
- FD_CLR(i, &tmp_readfds);
- else
- found_one=1;
- }
- }
- if (found_one)
- {
- memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
- sizeof(fd_set));
- memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
- sizeof(fd_set));
- memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
- sizeof(fd_set));
- }
- }
- if (found_one || fd_check_if_pending_signal(pthread))
- {
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
- if (SET_PF_DONE_EVENT(deq) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue, deq);
- deq->state = PS_RUNNING;
- }
- } else {
- pthread = pthread->next;
- }
- }
- return 0;
-}
-
-
-/* ==========================================================================
- * fd_kern_poll()
- *
- * Called only from context_switch(). The kernel must be locked.
- *
- * This function uses a linked list of waiting pthreads, NOT a queue.
- */
-
-void fd_kern_poll()
-{
- fd_kern_select(&__fd_kern_poll_timeout);
-}
-
-
-/* ==========================================================================
- * fd_kern_wait()
- *
- * Called when there is no active thread to run.
- */
-
-void fd_kern_wait()
-{
- if (fd_kern_select(&__fd_kern_wait_timeout))
- /* No threads, waiting on I/O, do a sigsuspend */
- sig_handler_pause();
-}
-
-
-/* ==========================================================================
- * Special Note: All operations return the errno as a negative of the errno
- * listed in errno.h
- * ======================================================================= */
-
-/* ==========================================================================
- * read()
- */
-pthread_ssize_t __fd_kern_read(union fd_data fd_data, int flags, void *buf,
- size_t nbytes, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_read(fd, buf, nbytes)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret= NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * readv()
- */
-int __fd_kern_readv(union fd_data fd_data, int flags, const struct iovec *iov,
- int iovcnt, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_readv(fd, iov, iovcnt)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * write()
- */
-pthread_ssize_t __fd_kern_write(union fd_data fd_data, int flags,
- const void *buf, size_t nbytes, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_write(fd, buf, nbytes)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * writev()
- */
-int __fd_kern_writev(union fd_data fd_data, int flags, const struct iovec *iov,
- int iovcnt, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_writev(fd, iov, iovcnt)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * For blocking version we really should set an interrupt
- * fcntl()
- */
-int __fd_kern_fcntl(union fd_data fd_data, int flags, int cmd, int arg)
-{
- int fd = fd_data.i;
-
- return(machdep_sys_fcntl(fd, cmd, arg));
-}
-
-/* ==========================================================================
- * close()
- */
-int __fd_kern_close(union fd_data fd_data, int flags)
-{
- int fd = fd_data.i;
-
- return(machdep_sys_close(fd));
-}
-
-/* ==========================================================================
- * lseek()
- * Assume that error number is in the range 0- 255 to get bigger
- * range of seek. ; Monty
- */
-off_t __fd_kern_lseek(union fd_data fd_data, int f, off_t offset, int whence)
-{
- int fd = fd_data.i;
- extern off_t machdep_sys_lseek(int, off_t, int);
- off_t ret=machdep_sys_lseek(fd, offset, whence);
- if ((long) ret < 0L && (long) ret >= -255L)
- {
- SET_ERRNO(ret);
- ret= NOTOK;
- }
- return ret;
-}
-
-/*
- * File descriptor operations
- */
-extern machdep_sys_close();
-
-/* Normal file operations */
-static struct fd_ops __fd_kern_ops = {
- __fd_kern_write, __fd_kern_read, __fd_kern_close, __fd_kern_fcntl,
- __fd_kern_writev, __fd_kern_readv, __fd_kern_lseek, 1
-};
-
-/* NFS file opperations */
-
-/* FIFO file opperations */
-
-/* Device operations */
-
-/* ==========================================================================
- * open()
- *
- * Because open could potentially block opening a file from a remote
- * system, we want to make sure the call will timeout. We then try and open
- * the file, and stat the file to determine what operations we should
- * associate with the fd.
- *
- * This is not done yet
- *
- * A regular file on the local system needs no special treatment.
- */
-int open(const char *path, int flags, ...)
-{
- int fd, mode, fd_kern;
- struct stat stat_buf;
- va_list ap;
-
- /* If pthread scheduling == FIFO set a virtual timer */
- if (flags & O_CREAT) {
- va_start(ap, flags);
- mode = va_arg(ap, int);
- va_end(ap);
- } else {
- mode = 0;
- }
-
- if (!((fd = fd_allocate()) < OK)) {
- fd_table[fd]->flags = flags;
- flags |= __FD_NONBLOCK;
-
- if (!((fd_kern = machdep_sys_open(path, flags, mode)) < OK)) {
-
- /* fstat the file to determine what type it is */
- if (machdep_sys_fstat(fd_kern, &stat_buf)) {
- PANIC();
- }
- if (S_ISREG(stat_buf.st_mode)) {
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->type = FD_HALF_DUPLEX;
- } else {
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->type = FD_FULL_DUPLEX;
- }
- fd_table[fd]->fd.i = fd_kern;
- return(fd);
- }
-
- fd_table[fd]->count = 0;
- SET_ERRNO(-fd_kern);
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * create()
- */
-int create(const char *path, mode_t mode)
-{
- return creat (path, mode);
-}
-
-/* ==========================================================================
- * creat()
- */
-#undef creat
-
-int creat(const char *path, mode_t mode)
-{
- return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
-}
-
-/* ==========================================================================
- * fchown()
- */
-int fchown(int fd, uid_t owner, gid_t group)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_fchown(fd_table[fd]->fd.i, owner, group)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * fchmod()
- */
-int fchmod(int fd, mode_t mode)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_fchmod(fd_table[fd]->fd.i, mode)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * ftruncate()
- */
-int ftruncate(int fd, off_t length)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_ftruncate(fd_table[fd]->fd.i, length)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-#if defined (HAVE_SYSCALL_FLOCK)
-/* ==========================================================================
- * flock()
- *
- * Added (mevans)
- */
-int flock(int fd, int operation)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_flock(fd_table[fd]->fd.i,
- operation)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-#endif
-
-/* ==========================================================================
- * pipe()
- */
-int pipe(int fds[2])
-{
- int kfds[2];
- int ret;
-
- if ((fds[0] = fd_allocate()) >= OK) {
- if ((fds[1] = fd_allocate()) >= OK) {
- if ((ret = machdep_sys_pipe(kfds)) >= OK) {
- fd_table[fds[0]]->flags = machdep_sys_fcntl(kfds[0], F_GETFL, NULL);
- machdep_sys_fcntl(kfds[0], F_SETFL, fd_table[fds[0]]->flags | __FD_NONBLOCK);
- fd_table[fds[1]]->flags = machdep_sys_fcntl(kfds[1], F_GETFL, NULL);
- machdep_sys_fcntl(kfds[1], F_SETFL, fd_table[fds[1]]->flags | __FD_NONBLOCK);
-
- fd_table[fds[0]]->ops = &(__fd_kern_ops);
- fd_table[fds[1]]->ops = &(__fd_kern_ops);
-
- /* Not really full duplex but ... */
- fd_table[fds[0]]->type = FD_FULL_DUPLEX;
- fd_table[fds[1]]->type = FD_FULL_DUPLEX;
-
- fd_table[fds[0]]->fd.i = kfds[0];
- fd_table[fds[1]]->fd.i = kfds[1];
-
- return(OK);
- } else {
- SET_ERRNO(-ret);
- }
- fd_table[fds[1]]->count = 0;
- }
- fd_table[fds[0]]->count = 0;
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * fd_kern_reset()
- * Change the fcntl blocking flag back to NONBLOCKING. This should only
- * be called after a fork.
- */
-void fd_kern_reset(int fd)
-{
- switch (fd_table[fd]->type) {
- case FD_TEST_HALF_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL,
- fd_table[fd]->flags | __FD_NONBLOCK);
- fd_table[fd]->type = FD_HALF_DUPLEX;
- break;
- case FD_TEST_FULL_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL,
- fd_table[fd]->flags | __FD_NONBLOCK);
- fd_table[fd]->type = FD_FULL_DUPLEX;
- break;
- default:
- break;
- }
-}
-
-/* ==========================================================================
- * fd_kern_init()
- *
- * Assume the entry is locked before routine is invoked
- *
- * This may change. The problem is setting the fd to nonblocking changes
- * the parents fd too, which may not be the desired result.
- *
- * New added feature: If the fd in question is a tty then we open it again
- * and close the original, this way we don't have to worry about the
- * fd being NONBLOCKING to the outside world.
- */
-void fd_kern_init(int fd)
-{
- if ((fd_table[fd]->flags = machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) {
- if (isatty_basic(fd)) {
- int new_fd;
-
- if ((new_fd = machdep_sys_open(__ttyname_basic(fd), O_RDWR)) >= OK){
- if (machdep_sys_dup2(new_fd, fd) == OK) {
- /* Should print a warning */
-
- /* Should also set the flags to that of opened outside of
- process */
- }
- machdep_sys_close(new_fd);
- }
- }
- /* We do these things regaurdless of the above results */
- machdep_sys_fcntl(fd, F_SETFL, fd_table[fd]->flags | __FD_NONBLOCK);
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->type = FD_HALF_DUPLEX;
- fd_table[fd]->fd.i = fd;
- fd_table[fd]->count = 1;
-
- }
-}
-
-/* ==========================================================================
- * fd_kern_gettableentry()
- *
- * Remember only return a a file descriptor that I will modify later.
- * Don't return file descriptors that aren't owned by the child, or don't
- * have kernel operations.
- */
-static int fd_kern_gettableentry(const int child, int fd)
-{
- int i;
-
- for (i = 0; i < dtablesize; i++) {
- if (fd_table[i]) {
- if (fd_table[i]->fd.i == fd) {
- if (child) {
- if ((fd_table[i]->type != FD_TEST_HALF_DUPLEX) &&
- (fd_table[i]->type != FD_TEST_FULL_DUPLEX)) {
- continue;
- }
- } else {
- if ((fd_table[i]->type == FD_NT) ||
- (fd_table[i]->type == FD_NIU)) {
- continue;
- }
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[i]->ops) ||
- (fd_table[i]->ops->use_kfds != 1)) {
- continue;
- }
- return(i);
- }
- }
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * fd_kern_exec()
- *
- * Fixup the fd_table such that (fd == fd_table[fd]->fd.i) this way
- * the new immage will be OK.
- *
- * Only touch those that won't be used by the parent if we're in a child
- * otherwise fixup all.
- *
- * Returns:
- * 0 no fixup necessary
- * 1 fixup without problems
- * 2 failed fixup on some descriptors, and clobbered them.
- */
-int fd_kern_exec(const int child)
-{
- int ret = 0;
- int fd, i;
-
- for (fd = 0; fd < dtablesize; fd++) {
- if (fd_table[fd] == NULL) {
- continue;
- }
- /* Is the fd already in use ? */
- if (child) {
- if ((fd_table[fd]->type != FD_TEST_HALF_DUPLEX) &&
- (fd_table[fd]->type != FD_TEST_FULL_DUPLEX)) {
- continue;
- }
- } else {
- if ((fd_table[fd]->type == FD_NT) ||
- (fd_table[fd]->type == FD_NIU)) {
- continue;
- }
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[fd]->ops) ||
- (fd_table[fd]->ops->use_kfds != 1)) {
- continue;
- }
- /* Does it match ? */
- if (fd_table[fd]->fd.i == fd) {
- continue;
- }
- /* OK, fixup entry: Read comments before changing. This isn't obvious */
-
- /* i is the real file descriptor fd currently represents */
- if (((i = fd_table[fd]->fd.i) >= dtablesize) || (i < 0)) {
- /* This should never happen */
- PANIC();
- }
-
- /*
- * if the real file descriptor with the same number as the fake file
- * descriptor number fd is actually in use by the program, we have
- * to move it out of the way
- */
- if ((machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) {
- /* fd is busy */
- int j;
-
- /*
- * j is the fake file descriptor that represents the real file
- * descriptor that we want to move. This way the fake file
- * descriptor fd can move its real file descriptor i such that
- * fd == i.
- */
- if ((j = fd_kern_gettableentry(child, fd)) >= OK) {
-
- /*
- * Since j represents a fake file descriptor and fd represents
- * a fake file descriptor. If j < fd then a previous pass
- * should have set fd_table[j]->fd.i == j.
- */
- if (fd < j) {
- if ((fd_table[j]->fd.i = machdep_sys_dup(fd)) < OK) {
- /* Close j, there is nothing else we can do */
- fd_table[j]->type = FD_NIU;
- ret = 2;
- }
- } else {
- /* This implies fd_table[j]->fd.i != j */
- PANIC();
- }
- }
- }
-
- /*
- * Here the real file descriptor i is set to equel the fake file
- * descriptor fd
- */
- machdep_sys_dup2(i, fd);
-
- /*
- * Now comes the really complicated part: UNDERSTAND before changing
- *
- * Here are the things this routine wants to do ...
- *
- * Case 1. The real file descriptor has only one fake file descriptor
- * representing it.
- * fd -> i, fd != i ===> fd -> fd, close(i)
- * Example fd = 4, i = 2: then close(2), set fd -> i = 4
- *
- * Case 2. The real file descriptor has more than one fake file
- * descriptor representing it, and this is the first fake file
- * descriptor representing the real file descriptor
- * fd -> i, fd' -> i, fd != i ===> fd -> fd, fd' -> fd, close(i)
- *
- * The problem is achiving the above is very messy and difficult,
- * but I should be able to take a short cut. If fd > i then there
- * will be no need to ever move i, this is because the fake file
- * descriptor foo that we would have wanted to represent the real
- * file descriptor i has already been processed. If fd < i then by
- * moving i to fd all subsequent fake file descriptors fd' should fall
- * into the previous case and won't need aditional adjusting.
- *
- * Does this break the above fd < j check .... It shouldn't because j
- * is a fake file descriptor and if j < fd then j has already moved
- * its real file descriptor foo such that foo <= j therefore foo < fd
- * and not foo == fd therefor j cannot represent the real
- * filedescriptor that fd want to move to and be less than fd
- */
- if (fd < i) {
- fd_table[fd]->fd.i = fd;
- machdep_sys_close(i);
- }
- if (ret < 1) {
- ret = 1;
- }
- }
-}
-
-/* ==========================================================================
- * fd_kern_fork()
- */
-void fd_kern_fork()
-{
- pthread_mutex_t *mutex;
- int fd;
-
- for (fd = 0; fd < dtablesize; fd++) {
- if (fd_table[fd] == NULL) {
- continue;
- }
- mutex = & (fd_table[fd]->mutex);
- if (pthread_mutex_trylock(mutex)) {
- continue;
- }
- if ((fd_table[fd]->r_owner) || (fd_table[fd]->w_owner)) {
- pthread_mutex_unlock(mutex);
- continue;
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[fd]->ops) || (fd_table[fd]->ops->use_kfds != 1)) {
- pthread_mutex_unlock(mutex);
- continue;
- }
- switch (fd_table[fd]->type) {
- case FD_HALF_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_HALF_DUPLEX;
- break;
- case FD_FULL_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_FULL_DUPLEX;
- break;
- default:
- break;
- }
- pthread_mutex_unlock(mutex);
- }
-}
-
-/* ==========================================================================
- * Here are the berkeley socket functions. These are not POSIX.
- * ======================================================================= */
-
-#if defined (HAVE_SYSCALL_SOCKET) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * socket()
- */
-int socket(int af, int type, int protocol)
-{
- int fd, fd_kern;
-
- if (!((fd = fd_allocate()) < OK)) {
-
- if (!((fd_kern = machdep_sys_socket(af, type, protocol)) < OK)) {
- int tmp_flags;
-
- tmp_flags = machdep_sys_fcntl(fd_kern, F_GETFL, 0);
- machdep_sys_fcntl(fd_kern, F_SETFL, tmp_flags | __FD_NONBLOCK);
-
- /* Should fstat the file to determine what type it is */
- fd_table[fd]->ops = & __fd_kern_ops;
- fd_table[fd]->type = FD_FULL_DUPLEX;
- fd_table[fd]->fd.i = fd_kern;
- fd_table[fd]->flags = tmp_flags;
- return(fd);
- }
-
- fd_table[fd]->count = 0;
- SET_ERRNO(-fd_kern);
- }
- return(NOTOK);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_BIND) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * bind()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int bind(int fd, const struct sockaddr *name, socklen_t namelen)
-#else
-int bind(int fd, const struct sockaddr *name, int namelen)
-#endif
-{
- /* Not much to do in bind */
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_CONNECT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * connect()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int connect(int fd, const struct sockaddr *name, socklen_t namelen)
-#else
-int connect(int fd, const struct sockaddr *name, int namelen)
-#endif
-{
- struct sockaddr tmpname;
- int ret, tmpnamelen;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
- (ret == -EALREADY) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- pthread_resched_resume(PS_FDW_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- tmpnamelen = sizeof(tmpname);
- /* OK now lets see if it really worked */
- if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
- &tmpname, &tmpnamelen)) < OK) &&
- (ret == -ENOTCONN))
- {
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
- SO_ERROR, &ret, &tmpnamelen);
- SET_ERRNO(ret); /* ret is already positive (mevans) */
- ret = NOTOK;
- }
- } else {
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- }
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_ACCEPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * accept()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int accept(int fd, struct sockaddr *name, socklen_t *namelen)
-#else
-int accept(int fd, struct sockaddr *name, int *namelen)
-#endif
-{
- int ret, fd_kern;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- while ((fd_kern = machdep_sys_accept(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((fd_kern == -EWOULDBLOCK) || (fd_kern == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- pthread_resched_resume(PS_FDR_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-fd_kern);
- return(NOTOK);
- }
- }
- fd_unlock(fd, FD_RDWR);
-
- if (!((ret = fd_allocate()) < OK)) {
-
- /* This may be unnecessary */
- machdep_sys_fcntl(fd_kern, F_SETFL, __FD_NONBLOCK);
-
- /* Should fstat the file to determine what type it is */
- fd_table[ret]->ops = & __fd_kern_ops;
- fd_table[ret]->type = FD_FULL_DUPLEX;
- fd_table[ret]->fd.i = fd_kern;
-
- /* XXX Flags should be the same as those on the listening fd */
- fd_table[ret]->flags = fd_table[fd]->flags;
- }
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_LISTEN) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * listen()
- */
-int listen(int fd, int backlog)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SEND) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * send_timedwait()
- */
-ssize_t send_timedwait(int fd, const void * msg, size_t len, int flags,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- while ((ret = machdep_sys_send(fd_table[fd]->fd.i,
- msg, len, flags)) < OK)
- {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN)))
- {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
- } else {
- break;
- }
- }
- fd_unlock(fd, FD_WRITE);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return ret;
-}
-
-/* ==========================================================================
- * send()
- */
-ssize_t send(int fd, const void * msg, size_t len, int flags)
-{
- return(send_timedwait(fd, msg, len, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SENDTO) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * sendto_timedwait()
- */
-ssize_t sendto_timedwait(int fd, const void * msg, size_t len,
- int flags, const struct sockaddr *to, int to_len,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- while ((ret = machdep_sys_sendto(fd_table[fd]->fd.i,
- msg, len, flags, to, to_len)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret= -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
- }
- else
- break; /* ret contains the errorcode */
- }
- fd_unlock(fd, FD_WRITE);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * sendto()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-ssize_t sendto(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *to, socklen_t to_len)
-#else
-ssize_t sendto(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *to, int to_len)
-#endif
-{
- return(sendto_timedwait(fd, msg, len, flags, to, to_len, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SENDMSG) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * sendmsg_timedwait()
- */
-ssize_t sendmsg_timedwait(int fd, const struct msghdr *msg, int flags,
- struct timespec * timeout)
-{
- int passed_fd, ret, i;
-
- /* Handle getting the real file descriptor */
- for(i = 0; i < (((struct omsghdr *)msg)->msg_accrightslen/sizeof(i)); i++) {
- passed_fd = *(((int *)((struct omsghdr *)msg)->msg_accrights) + i);
- if ((ret = fd_lock(passed_fd, FD_RDWR, NULL)) == OK) {
- *(((int *)((struct omsghdr *)msg)->msg_accrights) + i)
- = fd_table[passed_fd]->fd.i;
- machdep_sys_fcntl(fd_table[passed_fd]->fd.i, F_SETFL,
- fd_table[passed_fd]->flags);
- switch(fd_table[passed_fd]->type) {
- case FD_TEST_FULL_DUPLEX:
- case FD_TEST_HALF_DUPLEX:
- break;
- case FD_FULL_DUPLEX:
- fd_table[passed_fd]->type = FD_TEST_FULL_DUPLEX;
- break;
- case FD_HALF_DUPLEX:
- fd_table[passed_fd]->type = FD_TEST_HALF_DUPLEX;
- break;
- default:
- PANIC();
- }
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(EBADF);
- return(NOTOK);
- }
- fd_unlock(fd, FD_RDWR);
- }
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- while((ret = machdep_sys_sendmsg(fd_table[fd]->fd.i, msg, flags)) < OK){
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
-
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * sendmsg()
- */
-ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
-{
- return(sendmsg_timedwait(fd, msg, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECV) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * recv_timedwait()
- */
-ssize_t recv_timedwait(int fd, void * buf, size_t len, int flags,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- while ((ret = machdep_sys_recv(fd_table[fd]->fd.i,
- buf, len, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
-
- } else {
- break;
- }
- }
- fd_unlock(fd, FD_READ);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * recv()
- */
-ssize_t recv(int fd, void * buf, size_t len, int flags)
-{
- return(recv_timedwait(fd, buf, len, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECVFROM) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * recvfrom_timedwait()
- */
-ssize_t recvfrom_timedwait(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- while ((ret = machdep_sys_recvfrom(fd_table[fd]->fd.i,
- buf, len, flags, from, from_len)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret= -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
-
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
- } else {
- break;
- }
- }
- fd_unlock(fd, FD_READ);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * recvfrom()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-ssize_t recvfrom(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, socklen_t * from_len)
-#else
-ssize_t recvfrom(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len)
-#endif
-{
- return(recvfrom_timedwait(fd, buf, len, flags, from, from_len, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECVMSG) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * recvmsg_timedwait()
- */
-ssize_t recvmsg_timedwait(int fd, struct msghdr *msg, int flags,
- struct timespec * timeout)
-{
- struct stat stat_buf;
- int passed_fd, ret, i;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- while ((ret = machdep_sys_recvmsg(fd_table[fd]->fd.i, msg, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- fd_unlock(fd, FD_READ);
-
- /* Handle getting the real file descriptor */
- for (i = 0; i < (((struct omsghdr *)msg)->msg_accrightslen / sizeof(i));
- i++) {
- passed_fd = *(((int *)((struct omsghdr *)msg)->msg_accrights) + i);
- if (!((fd = fd_allocate()) < OK)) {
- fd_table[fd]->flags = machdep_sys_fcntl(passed_fd, F_GETFL);
-
- if (!( fd_table[fd]->flags & __FD_NONBLOCK)) {
- machdep_sys_fcntl(passed_fd, F_SETFL,
- fd_table[fd]->flags | __FD_NONBLOCK);
- }
-
- /* fstat the file to determine what type it is */
- machdep_sys_fstat(passed_fd, &stat_buf);
- if (S_ISREG(stat_buf.st_mode)) {
- fd_table[fd]->type = FD_HALF_DUPLEX;
- } else {
- fd_table[fd]->type = FD_FULL_DUPLEX;
- }
- *(((int *)((struct omsghdr *)msg)->msg_accrights) + i) = fd;
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->fd.i = passed_fd;
- } else {
- SET_ERRNO(EBADF);
- return(NOTOK);
- break;
- }
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * recvmsg()
- */
-ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
-{
- return(recvmsg_timedwait(fd, msg, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SHUTDOWN) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * shutdown()
- */
-int shutdown(int fd, int how)
-{
- int ret;
-
- switch(how) {
- case 0: /* Read */
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- case 1: /* Write */
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- case 2: /* Read-Write */
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- default:
- SET_ERRNO(EBADF);
- ret = NOTOK;
- break;
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * setsockopt()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int setsockopt(int fd, int level, int optname, const void * optval, socklen_t optlen)
-#else
-int setsockopt(int fd, int level, int optname, const void * optval, int optlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_setsockopt(fd_table[fd]->fd.i, level,
- optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_GETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * getsockopt()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int getsockopt(int fd, int level, int optname, void * optval, socklen_t * optlen)
-#else
-int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
- optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_GETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * getsockname()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int getsockname(int fd, struct sockaddr * name, socklen_t * naddrlen)
-#else
-int getsockname(int fd, struct sockaddr * name, int * naddrlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
- name, naddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_GETPEERNAME) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * getpeername()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int getpeername(int fd, struct sockaddr * peer, socklen_t * paddrlen)
-#else
-int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
- peer, paddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SOCKETPAIR) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * socketpair()
- */
-int socketpair(int af, int type, int protocol, int pair[2])
-{
- int ret, fd[2];
-
- if (!((pair[0] = fd_allocate()) < OK)) {
- if (!((pair[1] = fd_allocate()) < OK)) {
- if (!((ret = machdep_sys_socketpair(af, type, protocol, fd)) < OK)){
- int tmp_flags;
-
- tmp_flags = machdep_sys_fcntl(fd[0], F_GETFL, 0);
- machdep_sys_fcntl(fd[0], F_SETFL, tmp_flags | __FD_NONBLOCK);
- fd_table[pair[0]]->ops = & __fd_kern_ops;
- fd_table[pair[0]]->type = FD_FULL_DUPLEX;
- fd_table[pair[0]]->flags = tmp_flags;
- fd_table[pair[0]]->fd.i = fd[0];
-
- tmp_flags = machdep_sys_fcntl(fd[1], F_GETFL, 0);
- machdep_sys_fcntl(fd[1], F_SETFL, tmp_flags | __FD_NONBLOCK);
- fd_table[pair[1]]->ops = & __fd_kern_ops;
- fd_table[pair[1]]->type = FD_FULL_DUPLEX;
- fd_table[pair[1]]->flags = tmp_flags;
- fd_table[pair[1]]->fd.i = fd[1];
-
- return(ret);
- }
- fd_table[pair[1]]->count = 0;
- }
- fd_table[pair[0]]->count = 0;
- SET_ERRNO(-ret);
- }
- return(NOTOK);
-}
-
-#endif
diff --git a/mit-pthreads/pthreads/fd_pipe.c b/mit-pthreads/pthreads/fd_pipe.c
deleted file mode 100644
index e8bc20857ed..00000000000
--- a/mit-pthreads/pthreads/fd_pipe.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/* ==== fd_pipe.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : The new fast ITC pipe routines.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <pthread/fd_pipe.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread/posix.h>
-#include <string.h>
-#include <stdlib.h>
-
-#ifndef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-
-/* ==========================================================================
- * The pipe lock is never unlocked until all pthreads waiting are done with it
- * read()
- */
-pthread_ssize_t __pipe_read(union fd_data fd_data, int flags, void *buf,
- size_t nbytes, struct timespec * timeout)
-{
- struct __pipe *fd = (struct __pipe *)fd_data.ptr;
- struct pthread * pthread;
- int ret = 0;
-
- if (flags & O_ACCMODE) { return(NOTOK); }
-
- /* If there is nothing to read, go to sleep */
- if (fd->count == 0) {
- if (flags == WR_CLOSED) {
- return(0);
- }
-
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- pthread_run->next = NULL;
- fd->wait = pthread_run;
-
- pthread_resched_resume(PS_FDR_WAIT);
- ret = fd->size;
- } else {
- ret = MIN(nbytes, fd->count);
- memcpy(buf, fd->buf + fd->offset, ret);
- if (!(fd->count -= ret)) {
- fd->offset = 0;
- }
-
- if (pthread = fd->wait) {
- fd->wait = NULL;
- pthread_sched_prevent();
- pthread_sched_other_resume(pthread);
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * __pipe_write()
- *
- * First check to see if the read side is still open, then
- * check to see if there is a thread in a read wait for this pipe, if so
- * copy as much data as possible directly into the read waiting threads
- * buffer. The write thread(whether or not there was a read thread)
- * copies as much data as it can into the pipe buffer and it there
- * is still data it goes to sleep.
- */
-pthread_ssize_t __pipe_write(union fd_data fd_data, int flags, const void *buf,
- size_t nbytes, struct timespec * timeout) {
- struct __pipe *fd = (struct __pipe *)fd_data.ptr;
- struct pthread * pthread;
- int ret, count;
-
- if (!(flags & O_ACCMODE)) { return(NOTOK); }
-
- while (fd->flags != RD_CLOSED) {
- if (pthread = fd->wait) {
-
- pthread_sched_prevent();
-
- /* Copy data directly into waiting pthreads buf */
- fd->wait_size = MIN(nbytes, fd->wait_size);
- memcpy(fd->wait_buf, buf, fd->wait_size);
- buf = (const char *)buf + fd->wait_size;
- nbytes -= fd->wait_size;
- ret = fd->wait_size;
- fd->wait = NULL;
-
- /* Wake up waiting pthread */
- pthread_sched_other_resume(pthread);
- }
-
- if (count = MIN(nbytes, fd->size - (fd->offset + fd->count))) {
- memcpy(fd->buf + (fd->offset + fd->count), buf, count);
- buf = (const char *)buf + count;
- nbytes -= count;
- ret += count;
- }
- if (nbytes) {
- pthread_sched_prevent();
- fd->wait = pthread_run;
- pthread_resched_resume(PS_FDW_WAIT);
- } else {
- return(ret);
- }
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * __pipe_close()
- *
- * The whole close procedure is a bit odd and needs a bit of a rethink.
- * For now close() locks the fd, calls fd_free() which checks to see if
- * there are any other fd values poinging to the same real fd. If so
- * It breaks the wait queue into two sections those that are waiting on fd
- * and those waiting on other fd's. Those that are waiting on fd are connected
- * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT
- * RELEASED). close() then calls fd_unlock which give the fd to the next queued
- * element which determins that the fd is closed and then calls fd_unlock etc...
- */
-int __pipe_close(struct __pipe *fd, int flags)
-{
- struct pthread * pthread;
-
- if (!(fd->flags)) {
- if (pthread = fd->wait) {
- if (flags & O_ACCMODE) {
- fd->count = 0;
- fd->wait = NULL;
- fd->flags |= WR_CLOSED;
- pthread_sched_prevent();
- pthread_resched_resume(pthread);
- } else {
- /* Should send a signal */
- fd->flags |= RD_CLOSED;
- }
- }
- } else {
- free(fd);
- return(OK);
- }
-}
-
-/* ==========================================================================
- * For fcntl() which isn't implemented yet
- * __pipe_enosys()
- */
-static int __pipe_enosys()
-{
- SET_ERRNO(ENOSYS);
- return(NOTOK);
-}
-
-/* ==========================================================================
- * For writev() and readv() which aren't implemented yet
- * __pipe_enosys_v()
- */
-static int __pipe_enosys_v(union fd_data fd, int flags,
- const struct iovec *vec, int nvec,
- struct timespec *timeout)
-{
- SET_ERRNO(ENOSYS);
- return(NOTOK);
-}
-
-/* ==========================================================================
- * For lseek() which isn't implemented yet
- * __pipe_enosys_o()
- */
-static off_t __pipe_enosys_o()
-{
- SET_ERRNO(ENOSYS);
- return(NOTOK);
-}
-
-/*
- * File descriptor operations
- */
-struct fd_ops fd_ops[] = {
-{ __pipe_write, __pipe_read, __pipe_close, __pipe_enosys,
- __pipe_enosys_v, __pipe_enosys_v, __pipe_enosys_o, 0 },
-};
-
-/* ==========================================================================
- * open()
- */
-/* int __pipe_open(const char *path, int flags, ...) */
-int newpipe(int fd[2])
-{
- struct __pipe *fd_data;
-
- if ((!((fd[0] = fd_allocate()) < OK)) && (!((fd[1] = fd_allocate()) < OK))) {
- fd_data = malloc(sizeof(struct __pipe));
- fd_data->buf = malloc(4096);
- fd_data->size = 4096;
- fd_data->count = 0;
- fd_data->offset = 0;
-
- fd_data->wait = NULL;
- fd_data->flags = 0;
-
- fd_table[fd[0]]->fd.ptr = fd_data;
- fd_table[fd[0]]->flags = O_RDONLY;
- fd_table[fd[1]]->fd.ptr = fd_data;
- fd_table[fd[1]]->flags = O_WRONLY;
-
- return(OK);
- }
- return(NOTOK);
-}
-
diff --git a/mit-pthreads/pthreads/fd_sysv.c b/mit-pthreads/pthreads/fd_sysv.c
deleted file mode 100644
index 6dc01a49aa4..00000000000
--- a/mit-pthreads/pthreads/fd_sysv.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/* ==== fd_sysv.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Transforms BSD socket calls to SYSV streams.
- *
- * 1.00 94/11/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <config.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#if defined (HAVE_SYSCALL_PUTMSG) && defined (HAVE_SYSCALL_GETMSG) && !defined(HAVE_SYSCALL_SOCKETCALL) && !defined(HAVE_SYSCALL_SOCKET)
-#define HAVE_STREAMS 1
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#include <tiuser.h>
-#include <sys/tihdr.h>
-#include <netinet/in.h>
-#include <sys/timod.h>
-
-#define STREAM_BUF_SIZE sizeof(union T_primitives) + sizeof(struct sockaddr)
-
-extern struct pthread_queue fd_wait_read, fd_wait_write;
-
-/* ==========================================================================
- * putmsg_timedwait_basic()
- */
-static int putmsg_timedwait_basic(int fd, struct strbuf * ctlptr,
- struct strbuf * dataptr, int flags, struct timespec * timeout)
-{
-
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_putmsg(fd_table[fd]->fd.i,
- ctlptr, dataptr, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(& current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= -EINTR;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * putmsg_timedwait()
- */
-int putmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int flags, struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- ret = putmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout);
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * putmsg()
- */
-int putmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int flags)
-{
- return(putmsg_timedwait(fd, ctlptr, dataptr, flags, NULL));
-}
-
-/* ==========================================================================
- * getmsg_timedwait_basic()
- */
-int getmsg_timedwait_basic(int fd, struct strbuf * ctlptr,
- struct strbuf * dataptr, int * flags, struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_getmsg(fd_table[fd]->fd.i,
- ctlptr, dataptr, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(& current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= -EINTR;
- break;
- }
-
- } else {
- SET_ERRNO(-ret);
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * getmsg_timedwait()
- */
-int getmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int * flags, struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- ret = getmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout);
- fd_unlock(fd, FD_READ);
- }
- return (ret);
-}
-
-/* ==========================================================================
- * getmsg()
- */
-int getmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int * flags)
-{
- return(getmsg_timedwait(fd, ctlptr, dataptr, flags, NULL));
-}
-
-#endif
-
-/* ==========================================================================
- * Here are the berkeley socket functions implemented with stream calls.
- * These are not POSIX.
- * ======================================================================= */
-
-#if (!defined (HAVE_SYSCALL_BIND)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * bind()
- */
-int bind(int fd, const struct sockaddr *name, int namelen)
-{
- char buf[STREAM_BUF_SIZE];
- union T_primitives * res;
- struct T_bind_req * req;
- struct T_bind_ack * ack;
- struct strbuf strbuf;
- int flags, ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
- {
- req = (struct T_bind_req *)buf;
- req->PRIM_type = T_BIND_REQ;
- req->ADDR_length = namelen;
- req->ADDR_offset = sizeof(struct T_bind_req);
- req->CONIND_number = 4;
- memcpy(buf + sizeof(struct T_bind_req), name, namelen);
-
- strbuf.len = sizeof(struct T_bind_req) + namelen;
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.buf = buf;
-
- if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) == OK)
- {
- memset(buf, 0, STREAM_BUF_SIZE);
-
- strbuf.len = sizeof(struct T_bind_ack) + namelen;
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret = getmsg_timedwait_basic(fd, &strbuf, NULL,
- &flags, NULL)) >= OK)
- {
- res = (union T_primitives *)buf;
-
- switch(res->type) {
- case T_BIND_ACK:
- ret = OK;
- break;
- default:
- SET_ERRNO(EPROTO); /* What should this be? */
- ret = NOTOK;
- break;
- }
- }
- else
- {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- }
- else
- {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_CONNECT)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * connect()
- */
-int connect(int fd, const struct sockaddr *name, int namelen)
-{
- char buf[STREAM_BUF_SIZE];
- union T_primitives * res;
- struct T_conn_req * req;
- struct T_conn_con * con;
- struct T_ok_ack * ok;
- struct strbuf strbuf;
- int flags, ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
- {
- req = (struct T_conn_req *)buf;
- req->PRIM_type = T_CONN_REQ;
- req->DEST_length = namelen;
- req->DEST_offset = sizeof(struct T_conn_req);
- req->OPT_length = 0;
- req->OPT_offset = 0;
- memcpy(buf + sizeof(struct T_conn_req), name, namelen);
-
- strbuf.len = sizeof(struct T_conn_req) + namelen;
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.buf = buf;
-
- if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) != OK)
- goto err;
-
- memset(buf, 0, STREAM_BUF_SIZE);
- ok = (struct T_ok_ack *)buf;
-
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.len = STREAM_BUF_SIZE;
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK)
- goto err; /* Fixed by monty */
- if (ok->PRIM_type != T_OK_ACK)
- {
- ret= -EPROTO; /* What should this be? */
- goto err;
- }
-
- memset(buf, 0, STREAM_BUF_SIZE);
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.len = STREAM_BUF_SIZE;
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL) < OK))
- goto err;
-
- res = (union T_primitives *) buf;
- switch(res->type) {
- case T_CONN_CON:
- ret = OK;
- break;
- case T_DISCON_IND:
- ret= -ECONNREFUSED;
- goto err;
- default:
- ret= -EPROTO; /* What should this be? */
- goto err;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-
- err:
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-ret); /* Proably not needed... */
- return NOTOK;
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_LISTEN)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * listen()
- */
-int listen(int fd, int backlog)
-{
- return(OK);
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_SOCKET)) && defined(HAVE_STREAMS)
-
-extern ssize_t __fd_kern_write();
-static pthread_ssize_t __fd_sysv_read();
-extern int __fd_kern_close();
-extern int __fd_kern_fcntl();
-extern int __fd_kern_writev();
-extern int __fd_kern_readv();
-extern off_t __fd_kern_lseek();
-
-/* Normal file operations */
-static struct fd_ops __fd_sysv_ops = {
- __fd_kern_write, __fd_sysv_read, __fd_kern_close, __fd_kern_fcntl,
- __fd_kern_writev, __fd_kern_readv, __fd_kern_lseek, 1
-};
-
-/* ==========================================================================
- * read()
- */
-static pthread_ssize_t __fd_sysv_read(union fd_data fd_data, int flags,
- void *buf, size_t nbytes, struct timespec * timeout)
-{
- struct strbuf dataptr;
- int fd = fd_data.i;
- int getmsg_flags;
- int ret;
-
- getmsg_flags = 0;
- dataptr.len = 0;
- dataptr.buf = buf;
- dataptr.maxlen = nbytes;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_getmsg(fd, NULL, &dataptr, &getmsg_flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(& current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- return(NOTOK);
- }
- } else {
- SET_ERRNO(-ret);
- return(NOTOK);
- break;
- }
- }
- return(dataptr.len);
-}
-
-/* ==========================================================================
- * socket_tcp()
- */
-static int socket_tcp(int fd)
-{
- int ret;
-
- if ((ret = machdep_sys_open("/dev/tcp", O_RDWR | O_NONBLOCK, 0)) >= OK) {
- /* Should fstat the file to determine what type it is */
- fd_table[fd]->ops = & __fd_sysv_ops;
- fd_table[fd]->type = FD_FULL_DUPLEX;
- fd_table[fd]->fd.i = ret;
- fd_table[fd]->flags = 0;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * socket()
- */
-int socket(int af, int type, int protocol)
-{
- int fd, fd_kern;
-
- if ((fd = fd_allocate()) < OK)
- return (fd);
-
- switch(af) {
- case AF_INET:
- switch(type) {
- case SOCK_STREAM:
- if ((fd_kern = socket_tcp(fd)) >= OK)
- return(fd);
- SET_ERRNO(-fd_kern);
- break;
- case SOCK_DGRAM:
- if ((fd_kern = machdep_sys_open("/dev/udp",
- O_RDWR | O_NONBLOCK, 0)) >= OK) {
- /* Should fstat the file to determine what type it is */
- fd_table[fd]->ops = & __fd_sysv_ops;
- fd_table[fd]->type = FD_FULL_DUPLEX;
- fd_table[fd]->fd.i = fd_kern;
- fd_table[fd]->flags = 0;
- return(fd);
- }
- SET_ERRNO(-fd_kern);
- break;
- default:
- SET_ERRNO(EPROTONOSUPPORT);
- break;
- }
- break;
- case AF_UNIX:
- case AF_ISO:
- case AF_NS:
- default:
- SET_ERRNO(EPROTONOSUPPORT);
- break;
- }
- fd_table[fd]->count = 0;
- return(NOTOK); /* Fixed by monty */
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_ACCEPT)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * accept_fd()
- */
-static int accept_fd(int fd, struct sockaddr *name, int *namelen, char * buf,
- int SEQ_number)
-{
- struct T_conn_res * res;
- struct strbuf strbuf;
- int fd_new, fd_kern;
-
- /* Get a new table entry */
- if ((fd_new = fd_allocate()) < OK)
- return(NOTOK);
-
- /* Get the new kernel entry */
- if (!((fd_kern = socket_tcp(fd_new)) < OK)) {
- res = (struct T_conn_res *)buf;
- res->PRIM_type = T_CONN_RES;
- /* res->QUEUE_ptr = (queue_t *)&fd_kern; */
- res->OPT_length = 0;
- res->OPT_offset = 0;
- res->SEQ_number = SEQ_number;
-
- strbuf.maxlen = sizeof(union T_primitives) +sizeof(struct sockaddr);
- strbuf.len = sizeof(struct T_conn_ind) + (*namelen);
- strbuf.buf = buf;
-
- {
- struct strfdinsert insert;
-
- insert.ctlbuf.maxlen = (sizeof(union T_primitives) +
- sizeof(struct sockaddr));
- insert.ctlbuf.len = sizeof(struct T_conn_ind);
- insert.ctlbuf.buf = buf;
- insert.databuf.maxlen = 0;
- insert.databuf.len = 0;
- insert.databuf.buf = NULL;
- insert.flags = 0;
- insert.fildes = fd_kern;
- insert.offset = 4;
- /* Should the following be checked ? */
- machdep_sys_ioctl(fd_table[fd]->fd.i, I_FDINSERT, &insert);
- }
-
- /* if (putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL) == OK) {
- /* return(fd_new); */
- {
- int flags = 0;
- int ret;
-
- /* Should the following be checked ? */
- ret = getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL);
- return(fd_new);
-
- }
- machdep_sys_close(fd_kern);
- }
- fd_table[fd_new]->count = 0;
- return(NOTOK);
-}
-
-
-/* ==========================================================================
- * accept()
- */
-int accept(int fd, struct sockaddr *name, int *namelen)
-{
- char buf[sizeof(union T_primitives) + sizeof(struct sockaddr)];
- struct T_conn_ind * ind;
- struct strbuf strbuf;
- int flags, ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
- {
- ind = (struct T_conn_ind *)buf;
- ind->PRIM_type = T_CONN_IND;
- ind->SRC_length = (*namelen);
- ind->SRC_offset = sizeof(struct T_conn_ind);
- ind->OPT_length = 0;
- ind->OPT_offset = 0;
- ind->SEQ_number = 0;
-
- strbuf.maxlen = sizeof(union T_primitives) + sizeof(struct sockaddr);
- strbuf.len = sizeof(struct T_conn_ind) + (*namelen);
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK)
- {
- SET_ERRNO(-ret);
- ret= NOTOK;
- }
- else
- ret = accept_fd(fd, name, namelen, buf, ind->SEQ_number);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif /* HAVE_SYSCALL_ACCEPT */
-
-#if (!defined (HAVE_SYSCALL_SENDTO)) && defined (HAVE_STREAMS)
-
-/* ==========================================================================
- * sendto_timedwait()
- */
-ssize_t sendto_timedwait(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *name, int namelen, struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_req * req;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- ssize_t ret, prio;
-
- req = (struct T_unitdata_req *)buf;
- req->PRIM_type = T_UNITDATA_REQ;
- req->DEST_length = namelen;
- req->DEST_offset = sizeof(struct T_unitdata_req);
- req->OPT_length = 0;
- req->OPT_offset = 0;
- memcpy(buf + sizeof(struct T_unitdata_req), name, namelen);
-
- ctlptr.len = sizeof(struct T_unitdata_req) + namelen;
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.len = len;
- dataptr.maxlen = len;
- dataptr.buf = (void *)msg;
-
- if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) {
- ret = len;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * sendto()
- */
-ssize_t sendto(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *to, int to_len)
-{
- return(sendto_timedwait(fd, msg, len, flags, to, to_len, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_SEND)) && defined (HAVE_STREAMS)
-
-/* ==========================================================================
- * send_timedwait()
- */
-ssize_t send_timedwait(int fd, const void * msg, size_t len, int flags,
- struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_req * req;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- ssize_t ret, prio;
-
- req = (struct T_unitdata_req *)buf;
- req->PRIM_type = T_UNITDATA_REQ;
- req->DEST_length = 0;
- req->DEST_offset = 0;
- req->OPT_length = 0;
- req->OPT_offset = 0;
-
- ctlptr.len = sizeof(struct T_unitdata_req);
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.len = len;
- dataptr.maxlen = len;
- dataptr.buf = (void *)msg;
-
- if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) {
- ret = len;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * send()
- */
-ssize_t send(int fd, const void * msg, size_t len, int flags)
-{
- return(send_timedwait(fd, msg, len, flags, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_RECVFROM)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * recvfrom_timedwait()
- */
-ssize_t recvfrom_timedwait(int fd, void * msg, size_t len, int flags,
- struct sockaddr * name, int * namelen, struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_ind * ind;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- int ret, prio;
-
- ctlptr.len = 0;
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.maxlen = len;
- dataptr.len = 0;
- dataptr.buf = msg;
-
- prio = 0;
-
- ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout);
- if (ret >= OK) {
- if (name != NULL) {
- ind = (struct T_unitdata_ind *)buf;
-
- if (*namelen > ind->SRC_length)
- *namelen = ind->SRC_length;
- memcpy(name, buf + ind->SRC_offset, *namelen);
- }
- ret = dataptr.len;
- }
-
- return(ret);
-}
-
-/* ==========================================================================
- * recvfrom()
- */
-ssize_t recvfrom(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len)
-{
- return(recvfrom_timedwait(fd, buf, len, flags, from, from_len, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_RECV)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * recv_timedwait()
- */
-ssize_t recv_timedwait(int fd, void * msg, size_t len, int flags,
- struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_ind * ind;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- int ret, prio;
-
- ctlptr.len = 0;
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.maxlen = len;
- dataptr.len = 0;
- dataptr.buf = msg;
-
- prio = 0;
-
- ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout);
- if (ret >= OK)
- ret = dataptr.len;
-
- return(ret);
-}
-
-/* ==========================================================================
- * recv()
- */
-ssize_t recv(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len)
-{
- return(recv_timedwait(fd, buf, len, flags, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_SETSOCKOPT)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * setsockopt()
- */
-int setsockopt(int s, int level, int optname, const void *optval, int optlen)
-{
- return(0);
-}
-#endif
-
-struct foo { /* Used by getsockname and getpeername */
- long a;
- int b;
- struct sockaddr *name;
-};
-
-#if (!defined (HAVE_SYSCALL_GETSOCKNAME)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * getsockname()
- */
-
-
-int getsockname(int s, struct sockaddr *name, int *namelen)
-{
- struct foo foo;
- int i;
- if (*namelen < sizeof(struct sockaddr)) {
- SET_ERRNO(ENOMEM);
- return(-1);
- }
- foo.a = 0x84;
- foo.b = 0;
- foo.name = name;
- i = ioctl(s, TI_GETMYNAME, &foo);
- *namelen = foo.b;
- return(i);
-}
-#endif
-
-#if (!defined (HAVE_SYSCALL_GETPEERNAME)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * getpeername() ; Added by Monty
- */
-
-int getpeername(int s, struct sockaddr *name, int *namelen)
-{
- struct foo foo;
- int i;
- if (*namelen < sizeof(struct sockaddr)) {
- SET_ERRNO(ENOMEM);
- return(-1);
- }
- foo.a = 0x84; /* Max length ? */
- foo.b = 0; /* Return length */
- foo.name = name; /* Return buffer */
- i = ioctl(s, TI_GETPEERNAME, &foo);
- *namelen = foo.b;
- return(i);
-}
-#endif
-
-
-#if (!defined (HAVE_SYSCALL_SHUTDOWN)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * shutdown()
- */
-
-int shutdown(int s, int how)
-{
- return(0);
-}
-#endif
diff --git a/mit-pthreads/pthreads/file.c b/mit-pthreads/pthreads/file.c
deleted file mode 100644
index 4b8a8aad6db..00000000000
--- a/mit-pthreads/pthreads/file.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* ==== file.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : The locking functions for stdio.
- *
- * 1.00 93/09/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * flockfile()
- */
-void flockfile(FILE *fp)
-{
- pthread_mutex_t *mutex;
- int fd, flags;
-
- if ((fd = fileno(fp)) >= 0) {
- pthread_mutex_lock(mutex = &(fd_table[fd]->mutex));
-
- if (fp->_flags & __SRW) {
- flags = FD_READ | FD_WRITE;
- } else {
- if (fp->_flags & __SWR) {
- flags = FD_WRITE;
- } else {
- flags = FD_READ;
- }
- }
-
- /* This might fail but POSIX doesn't give a damn. */
- fd_basic_lock(fd, flags, mutex, NULL);
- pthread_mutex_unlock(mutex);
- }
-}
-
-/* ==========================================================================
- * ftrylockfile()
- */
-int ftrylockfile(FILE *fp)
-{
- pthread_mutex_t *mutex;
- int fd, flags;
-
- if ((fd = fileno(fp)) >= 0) {
- pthread_mutex_lock(mutex = &(fd_table[fd]->mutex));
-
- if (fp->_flags & __SRW) {
- flags = FD_READ | FD_WRITE;
- } else {
- if (fp->_flags & __SWR) {
- flags = FD_WRITE;
- } else {
- flags = FD_READ;
- }
- }
- if (!(fd_table[fd]->r_owner && fd_table[fd]->w_owner)) {
- fd_basic_lock(fd, flags, mutex, NULL);
- fd = OK;
- } else {
- fd = NOTOK;
- }
- pthread_mutex_unlock(mutex);
- } else {
- fd = OK;
- }
- return(fd);
-}
-
-/* ==========================================================================
- * funlockfile()
- */
-void funlockfile(FILE *fp)
-{
- pthread_mutex_t *mutex;
- int fd, flags;
-
- if ((fd = fileno(fp)) >= 0) {
- pthread_mutex_lock(mutex = &(fd_table[fd]->mutex));
-
- if (fp->_flags & __SRW) {
- flags = FD_READ | FD_WRITE;
- } else {
- if (fp->_flags & __SWR) {
- flags = FD_WRITE;
- } else {
- flags = FD_READ;
- }
- }
- fd_basic_unlock(fd, flags);
- pthread_mutex_unlock(mutex);
- }
-}
-
diff --git a/mit-pthreads/pthreads/globals.c b/mit-pthreads/pthreads/globals.c
deleted file mode 100644
index 921588fb220..00000000000
--- a/mit-pthreads/pthreads/globals.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ==== globals.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Global variables.
- *
- * 1.00 93/07/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/*
- * Initial thread, running thread, and top of link list of all threads.
- */
-struct pthread *pthread_run=NULL;
-struct pthread *pthread_initial=NULL;
-struct pthread *pthread_link_list=NULL;
-
-sigset_t * uthread_sigmask; /* Current process signal mask */
-
-/*
- * Dead thread queue, and threads elligible to be alloced queue.
- */
-struct pthread_queue pthread_dead_queue;
-struct pthread_queue pthread_alloc_queue;
-
-/*
- * Queue for all threads elidgeable to run this scheduling round.
- */
-struct pthread_prio_queue * pthread_current_prio_queue=NULL;
-
-/*
- * default thread attributes
- */
-pthread_attr_t pthread_attr_default = { SCHED_RR, PTHREAD_DEFAULT_PRIORITY,
- PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
-
-/*
- * File table information
- */
-struct fd_table_entry **fd_table=NULL;
-
-/*
- * A we a fork()ed process
- */
-volatile int fork_lock = 0;
-volatile int pthread_kernel_lock=0;
-
-/*
- * The page size, as returned by getpagesize()
- */
-size_t pthread_pagesize=0;
-
diff --git a/mit-pthreads/pthreads/info.c b/mit-pthreads/pthreads/info.c
deleted file mode 100644
index 2b9722ba291..00000000000
--- a/mit-pthreads/pthreads/info.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* hello */
-
-#include <stdio.h>
-#include <pthread.h>
-#include <signal.h>
-
-static const char *const state_names[] = {
-#define __pthread_defstate(S,NAME) NAME,
-#include "pthread/state.def"
-#undef __pthread_defstate
- 0
-};
-
-void (*dump_thread_info_fn) (struct pthread *, FILE *);
-
-static void
-dump_thread_info (thread, file)
- struct pthread *thread;
- FILE *file;
-{
- /* machdep */
- /* attr */
- /* signals */
- /* wakeup_time */
- /* join */
- fprintf (file, " thread @%p prio %3d %s", thread,
- thread->pthread_priority, state_names[(int) thread->state]);
- switch (thread->state) {
- case PS_FDLR_WAIT:
- fprintf (file, " fd %d[%d]", thread->data.fd.fd,
- thread->data.fd.branch);
- fprintf (file, " owner %pr/%pw",
- fd_table[thread->data.fd.fd]->r_owner,
- fd_table[thread->data.fd.fd]->w_owner);
- break;
- }
- /* show where the signal handler gets run */
- if (thread == pthread_run)
- fprintf (file, "\t\t[ME!]");
- fprintf (file, "\n");
- if (dump_thread_info_fn)
- (*dump_thread_info_fn) (thread, file);
-}
-
-static void
-pthread_dump_info_to_file (file)
- FILE *file;
-{
- pthread_t t;
- for (t = pthread_link_list; t; t = t->pll)
- dump_thread_info (t, file);
-}
-
-void
-pthread_dump_info ()
-{
- if (ftrylockfile (stderr) != 0)
- return;
- fprintf (stderr, "process id %ld:\n", (long) getpid ());
- pthread_dump_info_to_file (stderr);
- funlockfile (stderr);
-}
-
-#ifdef SIGINFO
-static void
-sig_handler (sig)
- int sig;
-{
- pthread_dump_info ();
-}
-
-void
-pthread_setup_siginfo ()
-{
- (void) signal (SIGINFO, sig_handler);
-}
-#endif
diff --git a/mit-pthreads/pthreads/init.cc b/mit-pthreads/pthreads/init.cc
deleted file mode 100644
index 24a131a60a5..00000000000
--- a/mit-pthreads/pthreads/init.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/*
- * DO not delete this file. The hack here ensures that pthread_init() gets
- * called before main does. This doesn't fix everything. It is still
- * possible for a c++ module to reley on constructors that need pthreads.
- */
-#include <pthread.h>
-
-char __pthread_init_hack = 42;
diff --git a/mit-pthreads/pthreads/malloc.c b/mit-pthreads/pthreads/malloc.c
deleted file mode 100644
index 76fe03824ac..00000000000
--- a/mit-pthreads/pthreads/malloc.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* ==== malloc.c ============================================================
- * Copyright (c) 1983 Regents of the University of California.
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Malloc functions.
- * This is a very fast storage allocator. It allocates blocks of a small
- * number of different sizes, and keeps free lists of each size. Blocks that
- * don't exactly fit are passed up to the next larger size. In this
- * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
- * This is designed for use in a virtual memory environment.
- *
- * 0.00 82/02/21 Chris Kingsley kingsley@cit-20
- *
- * 1.00 93/11/06 proven
- * -Modified BSD libc malloc to be threadsafe.
- *
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <string.h>
-#include <pthread/posix.h>
-
-/*
- * The overhead on a block is at least 4 bytes. When free, this space
- * contains a pointer to the next free block, and the bottom two bits must
- * be zero. When in use, the first byte is set to MAGIC, and the second
- * byte is the size index. The remaining bytes are for alignment.
- * If range checking is enabled then a second word holds the size of the
- * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
- * The order of elements is critical: ov_magic must overlay the low order
- * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
- */
-#ifdef __alpha
-#define _MOST_RESTRICTIVE_ALIGNMENT_TYPE char*
-#else
-#define _MOST_RESTRICTIVE_ALIGNMENT_TYPE double
-#endif /* __alpha */
-union overhead {
- _MOST_RESTRICTIVE_ALIGNMENT_TYPE __alignment_pad0;
- union overhead *ov_next; /* when free */
- struct {
- u_char ovu_magic; /* magic number */
- u_char ovu_index; /* bucket # */
-#ifdef RCHECK
- u_short ovu_rmagic; /* range magic number */
- size_t ovu_size; /* actual block size */
-#endif
- } ovu;
-#define ov_magic ovu.ovu_magic
-#define ov_index ovu.ovu_index
-#define ov_rmagic ovu.ovu_rmagic
-#define ov_size ovu.ovu_size
-};
-
-#define MAGIC 0xef /* magic # on accounting info */
-#define RMAGIC 0x5555 /* magic # on range info */
-
-#ifdef RCHECK
-#define RSLOP sizeof (u_short)
-#else
-#define RSLOP 0
-#endif
-
-/*
- * nextf[i] is the pointer to the next free block of size 2^(i+3). The
- * smallest allocatable block is 8 bytes. The overhead information
- * precedes the data area returned to the user.
- */
-#define NBUCKETS 30
-static union overhead *nextf[NBUCKETS];
-#ifndef hpux
-extern char *sbrk();
-#endif
-
-static size_t pagesz; /* page size */
-static int pagebucket; /* page size bucket */
-static pthread_mutex_t malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-#if defined(DEBUG) || defined(RCHECK)
-#define ASSERT(p) if (!(p)) botch("p")
-#include <stdio.h>
-static
-botch(s)
- char *s;
-{
- fprintf(stderr, "\r\nassertion botched: %s\r\n", s);
- (void) fflush(stderr); /* just in case user buffered it */
- abort();
-}
-#else
-#define ASSERT(p)
-#endif
-
-/* ==========================================================================
- * morecore()
- *
- * Allocate more memory to the indicated bucket
- */
-static inline void morecore(int bucket)
-{
- register union overhead *op;
- register size_t sz; /* size of desired block */
- size_t amt; /* amount to allocate */
- size_t nblks; /* how many blocks we get */
-
- /*
- * sbrk_size <= 0 only for big, FLUFFY, requests (about
- * 2^30 bytes on a VAX, I think) or for a negative arg.
- */
- sz = 1L << (bucket + 3);
-#ifdef DEBUG
- ASSERT(sz > 0);
-#else
- if (sz <= 0)
- return;
-#endif
- if (sz < pagesz) {
- amt = pagesz;
- nblks = amt / sz;
- } else {
- amt = sz + pagesz;
- nblks = 1;
- }
- op = (union overhead *)sbrk(amt);
- /* no more room! */
- if (op == (union overhead *) -1)
- return;
- /*
- * Add new memory allocated to that on
- * free list for this hash bucket.
- */
- nextf[bucket] = op;
- while (--nblks > 0) {
- op->ov_next = (union overhead *)((caddr_t)op + sz);
- op = (union overhead *)((caddr_t)op + sz);
- }
-}
-
-/* ==========================================================================
- * malloc()
- */
-void *malloc(size_t nbytes)
-{
- pthread_mutex_t *mutex;
- union overhead *op;
- size_t amt;
- size_t bucket, n;
-
- mutex = &malloc_mutex;
- pthread_mutex_lock(mutex);
- /*
- * First time malloc is called, setup page size and
- * align break pointer so all data will be page aligned.
- */
- if (pagesz == 0) {
- size_t x;
- pagesz = n = getpagesize();
- op = (union overhead *)sbrk(0);
- x = sizeof (*op) - ((long)op & (n - 1));
- if (n < x)
- n = n + pagesz - x;
- else
- n = n - x;
- if (n) {
- if (sbrk(n) == (char *)-1) {
- /* Unlock before returning (mevans) */
- pthread_mutex_unlock(mutex);
- return (NULL);
- }
- }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
- amt <<= 1;
- bucket++;
- }
- pagebucket = bucket;
- }
- /*
- * Convert amount of memory requested into closest block size
- * stored in hash buckets which satisfies request.
- * Account for space used per block for accounting.
- */
- if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
-#ifndef RCHECK
- amt = 8; /* size of first bucket */
- bucket = 0;
-#else
- amt = 16; /* size of first bucket */
- bucket = 1;
-#endif
- n = -(sizeof (*op) + RSLOP);
- } else {
- amt = pagesz;
- bucket = pagebucket;
- }
- while (nbytes > amt + n) {
- amt <<= 1;
- if (amt == 0) {
- pthread_mutex_unlock(mutex);
- return (NULL);
- }
- bucket++;
- }
- ASSERT (bucket < NBUCKETS);
- /*
- * If nothing in hash bucket right now,
- * request more memory from the system.
- */
- if ((op = nextf[bucket]) == NULL) {
- morecore(bucket);
- if ((op = nextf[bucket]) == NULL) {
- pthread_mutex_unlock(mutex);
- return (NULL);
- }
- }
- /* remove from linked list */
- nextf[bucket] = op->ov_next;
- op->ov_magic = MAGIC;
- op->ov_index = bucket;
-#ifdef RCHECK
- /*
- * Record allocated size of block and
- * bound space with magic numbers.
- */
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- op->ov_rmagic = RMAGIC;
- *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
-#endif
- pthread_mutex_unlock(mutex);
- return ((char *)(op + 1));
-}
-
-/* ==========================================================================
- * free()
- */
-void free(void *cp)
-{
- pthread_mutex_t *mutex;
- union overhead *op;
- int size;
-
- mutex = &malloc_mutex;
- pthread_mutex_lock(mutex);
- if (cp == NULL) {
- pthread_mutex_unlock(mutex);
- return;
- }
- op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
-#ifdef DEBUG
- ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
-#else
- if (op->ov_magic != MAGIC) {
- pthread_mutex_unlock(mutex);
- return; /* sanity */
- }
-#endif
-#ifdef RCHECK
- ASSERT(op->ov_rmagic == RMAGIC);
- ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
-#endif
- size = op->ov_index;
- ASSERT(size < NBUCKETS);
- op->ov_next = nextf[size]; /* also clobbers ov_magic */
- nextf[size] = op;
-
- pthread_mutex_unlock(mutex);
-}
-
-/* ==========================================================================
- * realloc()
- *
- * Storage compaction is no longer supported, fix program and try again.
- */
-void *realloc(void *cp, size_t nbytes)
-{
- pthread_mutex_t *mutex;
- size_t onb;
- size_t i;
- union overhead *op;
- char *res;
-
- if (cp == NULL)
- return (malloc(nbytes));
- op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
-
- if (op->ov_magic == MAGIC) {
- i = op->ov_index;
- } else {
- /*
- * This will cause old programs using storage compaction feature of
- * realloc to break in a pseudo resonable way that is easy to debug.
- * Returning a malloced buffer without the copy may cause
- * indeterministic behavior.
- */
- return(NULL);
- }
-
- mutex = &malloc_mutex;
- pthread_mutex_lock(mutex);
- onb = 1L << (i + 3);
- if (onb < pagesz)
- onb -= sizeof (*op) + RSLOP;
- else
- onb += pagesz - sizeof (*op) - RSLOP;
-
- /* avoid the copy if same size block */
- if (i) {
- i = 1L << (i + 2);
- if (i < pagesz)
- i -= sizeof (*op) + RSLOP;
- else
- i += pagesz - sizeof (*op) - RSLOP;
- }
-
- if (nbytes <= onb && nbytes > i) {
-#ifdef RCHECK
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
-#endif
- pthread_mutex_unlock(mutex);
- return(cp);
- }
- pthread_mutex_unlock(mutex);
-
- if ((res = malloc(nbytes)) == NULL) {
- free(cp);
- return (NULL);
- }
-
- memcpy(res, cp, (nbytes < onb) ? nbytes : onb);
- free(cp);
-
- return (res);
-}
-
-/* ==========================================================================
- * calloc()
- *
- * Added to ensure pthread's allocation is used (mevans).
- */
-void *calloc(size_t nmemb, size_t size)
-{
- void *p;
- size *= nmemb;
- p = malloc(size);
- if (p) memset(p, 0, size);
- return (p);
-}
diff --git a/mit-pthreads/pthreads/mutex.c b/mit-pthreads/pthreads/mutex.c
deleted file mode 100644
index 1a2ca6fa1c1..00000000000
--- a/mit-pthreads/pthreads/mutex.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* ==== mutex.c ==============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Mutex functions.
- *
- * 1.00 93/07/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* ==========================================================================
- * pthread_mutex_is_debug()
- *
- * Check that mutex is a debug mutex and if so returns entry number into
- * array of debug mutexes.
- */
-static int pthread_mutex_debug_count = 0;
-static pthread_mutex_t ** pthread_mutex_debug_ptrs = NULL;
-
-static inline int pthread_mutex_is_debug(pthread_mutex_t * mutex)
-{
- int i;
-
- for (i = 0; i < pthread_mutex_debug_count; i++) {
- if (pthread_mutex_debug_ptrs[i] == mutex) {
- return(i);
- }
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * pthread_mutex_init()
- *
- * In this implementation I don't need to allocate memory.
- * ENOMEM, EAGAIN should never be returned. Arch that have
- * weird constraints may need special coding.
- */
-int pthread_mutex_init(pthread_mutex_t *mutex,
- const pthread_mutexattr_t *mutex_attr)
-{
- enum pthread_mutextype type;
-
- /* Only check if attr specifies some mutex type other than fast */
- if ((mutex_attr) && (mutex_attr->m_type != MUTEX_TYPE_FAST)) {
- if (mutex_attr->m_type >= MUTEX_TYPE_MAX) {
- return(EINVAL);
- }
- type = mutex_attr->m_type;
- } else {
- type = MUTEX_TYPE_FAST;
- }
- mutex->m_flags = 0;
-
- pthread_sched_prevent();
-
- switch(type) {
- case MUTEX_TYPE_FAST:
- break;
- case MUTEX_TYPE_STATIC_FAST:
- pthread_sched_resume();
- return(EINVAL);
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- mutex->m_data.m_count = 0;
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) == NOTOK) {
- pthread_mutex_t ** new;
-
- if ((new = (pthread_mutex_t **)realloc(pthread_mutex_debug_ptrs,
- (pthread_mutex_debug_count + 1) * (sizeof(void *)))) == NULL) {
- pthread_sched_resume();
- return(ENOMEM);
- }
- pthread_mutex_debug_ptrs = new;
- pthread_mutex_debug_ptrs[pthread_mutex_debug_count++] = mutex;
- } else {
- pthread_sched_resume();
- return(EBUSY);
- }
- break;
- default:
- pthread_sched_resume();
- return(EINVAL);
- break;
- }
- /* Set all other paramaters */
- pthread_queue_init(&mutex->m_queue);
- mutex->m_flags |= MUTEX_FLAGS_INITED;
- mutex->m_owner = NULL;
- mutex->m_type = type;
-
- pthread_sched_resume();
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutex_destroy()
- */
-int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
- int i;
-
- pthread_sched_prevent();
-
- /* Only check if mutex is of type other than fast */
- switch(mutex->m_type) {
- case MUTEX_TYPE_FAST:
- break;
- case MUTEX_TYPE_STATIC_FAST:
- pthread_sched_resume();
- return(EINVAL);
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- mutex->m_data.m_count = 0;
- break;
- case MUTEX_TYPE_DEBUG:
- if ((i = pthread_mutex_is_debug(mutex)) == NOTOK) {
- pthread_sched_resume();
- return(EINVAL);
- }
- if (mutex->m_owner) {
- pthread_sched_resume();
- return(EBUSY);
- }
-
- /* Remove the mutex from the list of debug mutexes */
- pthread_mutex_debug_ptrs[i] =
- pthread_mutex_debug_ptrs[--pthread_mutex_debug_count];
- pthread_mutex_debug_ptrs[pthread_mutex_debug_count] = NULL;
- break;
- default:
- pthread_sched_resume();
- return(EINVAL);
- break;
- }
-
- /* Cleanup mutex, others might want to use it. */
- pthread_queue_init(&mutex->m_queue);
- mutex->m_owner = NULL;
- mutex->m_flags = 0;
-
- pthread_sched_resume();
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutex_trylock()
- */
-int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
- int rval;
-
- pthread_sched_prevent();
- switch (mutex->m_type) {
- /*
- * Fast mutexes do not check for any error conditions.
- */
- case MUTEX_TYPE_FAST:
- case MUTEX_TYPE_STATIC_FAST:
- if (!mutex->m_owner) {
- mutex->m_owner = pthread_run;
- rval = OK;
- } else {
- rval = EBUSY;
- }
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- if (mutex->m_owner) {
- if (mutex->m_owner == pthread_run) {
- mutex->m_data.m_count++;
- rval = OK;
- } else {
- rval = EBUSY;
- }
- } else {
- mutex->m_owner = pthread_run;
- rval = OK;
- }
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) != NOTOK) {
- if (!mutex->m_owner) {
- mutex->m_owner = pthread_run;
- rval = OK;
- } else {
- rval = EBUSY;
- }
- } else {
- rval = EINVAL;
- }
- break;
- default:
- rval = EINVAL;
- break;
- }
-
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_mutex_lock()
- */
-int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
- int rval;
-
- pthread_sched_prevent();
- switch (mutex->m_type) {
- /*
- * Fast mutexes do not check for any error conditions.
- */
- case MUTEX_TYPE_FAST:
- case MUTEX_TYPE_STATIC_FAST:
- if (mutex->m_owner) {
- pthread_queue_enq(&mutex->m_queue, pthread_run);
-
- /* Reschedule will unlock scheduler */
- pthread_resched_resume(PS_MUTEX_WAIT);
- return(OK);
- }
- mutex->m_owner = pthread_run;
- rval = OK;
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- if (mutex->m_owner) {
- if (mutex->m_owner != pthread_run) {
- pthread_queue_enq(&mutex->m_queue, pthread_run);
-
- /* Reschedule will unlock scheduler */
- pthread_resched_resume(PS_MUTEX_WAIT);
- return(OK);
- } else {
- mutex->m_data.m_count++;
- }
- } else {
- mutex->m_owner = pthread_run;
- }
- rval = OK;
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) != NOTOK) {
- if (mutex->m_owner) {
- if (mutex->m_owner != pthread_run) {
- pthread_queue_enq(&mutex->m_queue, pthread_run);
-
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_MUTEX_WAIT);
-
- if (mutex->m_owner != pthread_run) {
- PANIC();
- }
- return(OK);
- }
- rval = EDEADLK;
- break;
- }
- mutex->m_owner = pthread_run;
- rval = OK;
- break;
- }
- rval = EINVAL;
- break;
- default:
- rval = EINVAL;
- break;
- }
-
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_mutex_unlock()
- */
-int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
- struct pthread *pthread;
- int rval;
-
- pthread_sched_prevent();
-
- switch (mutex->m_type) {
- /*
- * Fast mutexes do not check for any error conditions.
- */
- case MUTEX_TYPE_FAST:
- case MUTEX_TYPE_STATIC_FAST:
- if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) {
-
- /* Reschedule will unlock scheduler */
- pthread_sched_other_resume(mutex->m_owner);
- return(OK);
- }
- rval = OK;
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- if (mutex->m_data.m_count) {
- mutex->m_data.m_count--;
- rval = OK;
- break;
- }
- if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) {
-
- /* Reschedule will unlock scheduler */
- pthread_sched_other_resume(mutex->m_owner);
- return(OK);
- }
- rval = OK;
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) != NOTOK) {
- if (mutex->m_owner == pthread_run) {
- if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) {
-
- /* Reschedule will unlock scheduler */
- pthread_sched_other_resume(mutex->m_owner);
- return(OK);
- }
- rval = OK;
- } else {
- rval = EPERM;
- }
- } else {
- rval = EINVAL;
- }
- break;
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
diff --git a/mit-pthreads/pthreads/mutexattr.c b/mit-pthreads/pthreads/mutexattr.c
deleted file mode 100644
index d045b5041a0..00000000000
--- a/mit-pthreads/pthreads/mutexattr.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* ==== mutexattr.c ===========================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Mutex functions.
- *
- * 1.00 93/07/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-/* ==========================================================================
- * pthread_mutexattr_init()
- */
-int pthread_mutexattr_init(pthread_mutexattr_t *attr)
-{
- attr->m_type = MUTEX_TYPE_FAST;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutexattr_destroy()
- */
-int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
-{
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutexattr_settype()
- */
-int pthread_mutexattr_settype(pthread_mutexattr_t *attr, unsigned int type)
-{
- switch(type) {
- case PTHREAD_MUTEXTYPE_FAST:
- attr->m_type = MUTEX_TYPE_FAST;
- break;
- case PTHREAD_MUTEXTYPE_RECURSIVE:
- attr->m_type = MUTEX_TYPE_COUNTING_FAST;
- break;
- case PTHREAD_MUTEXTYPE_DEBUG:
- attr->m_type = MUTEX_TYPE_DEBUG;
- break;
- default:
- return(EINVAL);
- }
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutexattr_gettype()
- */
-int pthread_mutexattr_gettype(pthread_mutexattr_t *attr, unsigned int * type)
-{
- *type = (unsigned int)attr->m_type;
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/panic.c b/mit-pthreads/pthreads/panic.c
deleted file mode 100644
index 6b963acd651..00000000000
--- a/mit-pthreads/pthreads/panic.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ==== panic.c =======================================================
- * Copyright (c) 1996 by Larry V. Streepy, Jr.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Larry V. Streepy, Jr.
- * 4. The name of Larry V. Streepy, Jr. may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Larry V. Streepy, Jr. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Larry V. Streepy, Jr. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread kernel panic
- *
- * 02 Oct 1996 - Larry V. Streepy, Jr.
- * - Initial coding
- */
-
-#include <pthread.h>
-#include <stdio.h>
-/*----------------------------------------------------------------------
- * Function: panic_kernel
- * Purpose: print a message and panic the pthreads kernel
- * Args: file name, line number, and function
- * Returns: doesn't
- * Notes:
- *----------------------------------------------------------------------*/ void
-panic_kernel( const char *file, unsigned int line, const char *func )
-{
-#ifdef __GNUC__
- (void) fprintf( stderr, "%s:%u: %s%sPhtreads kernel panic.\n",
- file, line, func ? func : "", func ? ": " : "" );
- (void) fflush (stderr);
-#else
- (void) fprintf( stderr, "%s:%u: Phtreads kernel panic.\n", file, line );
- (void) fflush (stderr);
-#endif
- abort();
-}
diff --git a/mit-pthreads/pthreads/prio_queue.c b/mit-pthreads/pthreads/prio_queue.c
deleted file mode 100644
index d976f9cd68f..00000000000
--- a/mit-pthreads/pthreads/prio_queue.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ==== prio_queue.c ==========================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Priority Queue functions.
- *
- * 1.00 94/09/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* A thread when it becomes eligeble to run is placed on the run queue.
- This requires locking the kernel lock
-*/
-
-/* ==========================================================================
- * pthread_prio_queue_init()
- */
-void pthread_prio_queue_init(struct pthread_prio_queue * queue)
-{
- int i;
-
- for (i = 0; i <= PTHREAD_MAX_PRIORITY; i++) {
- queue->level[i].first = NULL;
- queue->level[i].last = NULL;
- }
- queue->next = NULL;
- queue->data = NULL;
-}
-
-/* ==========================================================================
- * pthread_priority_enq()
- */
-void pthread_prio_queue_enq(struct pthread_prio_queue * queue,
- struct pthread * pthread)
-{
- int priority = pthread->pthread_priority;
-
- if (queue->next) {
- if (queue->level[priority].first) {
- pthread->next = (queue->level[priority].last)->next;
- (queue->level[priority].last)->next = pthread;
- queue->level[priority].last = pthread;
- return;
- }
- if (priority != PTHREAD_MAX_PRIORITY) {
- int prev_priority;
- /* Find first higher priority thread queued on queue */
- for (prev_priority = priority + 1; prev_priority <=
- PTHREAD_MAX_PRIORITY; prev_priority++) {
- if (queue->level[prev_priority].first) {
- pthread->next = (queue->level[prev_priority].last)->next;
- (queue->level[prev_priority].last)->next = pthread;
- queue->level[priority].first = pthread;
- queue->level[priority].last = pthread;
- return;
- }
- }
- }
- }
- queue->level[priority].first = pthread;
- queue->level[priority].last = pthread;
- pthread->next = queue->next;
- queue->next = pthread;
-}
-
-/* ==========================================================================
- * pthread_prio_queue_deq()
- */
-struct pthread * pthread_prio_queue_deq(struct pthread_prio_queue * queue)
-{
- struct pthread * pthread;
- int priority;
-
- if (pthread = queue->next) {
- priority = queue->next->pthread_priority;
- if (queue->level[priority].first == queue->level[priority].last) {
- queue->level[priority].first = NULL;
- queue->level[priority].last = NULL;
- } else {
- queue->level[priority].first = pthread->next;
- }
- queue->next = pthread->next;
- pthread->next = NULL;
- }
- return(pthread);
-}
-
-/* ==========================================================================
- * pthread_prio_queue_remove()
- */
-int pthread_prio_queue_remove(struct pthread_prio_queue *queue,
- struct pthread *thread)
-{
- /* XXX This is slow, should start with thread priority */
- int priority = thread->pthread_priority;
- struct pthread **current = &(queue->level[priority].first);
- struct pthread *prev = NULL;
-
- if (thread==*current) {
- int current_priority=priority+1;
-
- if (*current == queue->next){
- pthread_prio_queue_deq(queue);
- thread->next = NULL;
- return(OK);
- }
- for (current_priority; current_priority <= PTHREAD_MAX_PRIORITY;
- current_priority++) {
- if (queue->level[current_priority].last) {
- queue->level[current_priority].last->next = (*current)->next;
- if ((*current)->next &&
- (*current)->next->pthread_priority == priority)
- queue->level[priority].first = (*current)->next;
- else {
- queue->level[priority].first = NULL;
- queue->level[priority].last = NULL;
- }
- thread->next = NULL;
- return(OK);
- }
- }
- }
-
- if (*current == NULL) /* Mati Sauks */
- {
- return (NOTOK);
- }
- for (prev=*current,current=&((*current)->next);
- *current && ((*current)->pthread_priority == priority);
- prev=*current,current=&((*current)->next)) {
- if (*current == thread) {
- if (*current == queue->level[priority].last) {
- queue->level[priority].last = prev;
- }
-
- *current = (*current)->next;
- thread->next=NULL;
- return(OK);
- }
- }
- return(NOTOK);
-}
-
diff --git a/mit-pthreads/pthreads/process.c b/mit-pthreads/pthreads/process.c
deleted file mode 100644
index 9b3abb3384b..00000000000
--- a/mit-pthreads/pthreads/process.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ==== process.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Process functions (fork, exec, ...).
- *
- * 1.23 94/04/18 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <unistd.h>
-#ifdef HAVE_ALLOC_H
-#include <alloc.h>
-#endif
-
-extern void *alloca();
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-/* ==========================================================================
- * fork()
- *
- * This function requires a sig_prevent()/sig_check_and_resume() for the
- * parent. The child never unlocks.
- */
-pid_t fork()
-{
- pid_t ret;
-
- pthread_sched_prevent();
-
- fd_kern_fork();
- if (ret = machdep_sys_fork()) { /* Parent or error */
- pthread_sched_resume();
- } else { /* Child */
- machdep_unset_thread_timer(NULL);
- machdep_stop_timer(NULL);
- fork_lock++;
- pthread_kernel_lock--;
- }
- return(ret);
-}
-
-#ifdef HAVE_VFORK
-/* The semantics of vfork probably won't mix well with the pthread
- library code. Don't even try. */
-pid_t vfork ()
-{
- return fork ();
-}
-#endif
-
-/* ==========================================================================
- * execve()
- *
- * This function requires a sig_prevent()/sig_check_and_resume() if one
- * hasn't been done in the fork routine. Normally machdep_sys_execve()
- * should never return.
- */
-int execve(const char *name, char * const *argv, char * const *envp)
-{
- int ret;
-
- if (!fork_lock) {
- pthread_sched_prevent();
- fd_kern_exec(0);
- ret = machdep_sys_execve(name, argv, envp);
- pthread_sched_resume();
- } else {
- fd_kern_exec(1);
- ret = machdep_sys_execve(name, argv, envp);
- }
- return(ret);
-}
-
-/* Variants of execve. Define them here so that the system versions
- don't get used and drag in the system version of execve. */
-#include <sys/stat.h>
-#include <string.h>
-#include <sys/param.h>
-extern char **environ;
-
-static const char *find (const char *name, char *buf)
-{
- char *p1, *p2;
- extern char *getenv ();
- struct stat sb;
-
- if (strchr (name, '/'))
- return name;
- p1 = getenv ("PATH");
- if (p1 == 0)
- p1 = "/bin:/usr/bin:";
- while (*p1) {
- memset (buf, 0, MAXPATHLEN);
- p2 = strchr (p1, ':');
- if (p2 == 0)
- p2 = p1 + strlen (p1);
- strncpy (buf, p1, p2 - p1);
- buf[p2 - p1] = 0;
- strcat (buf, "/");
- strcat (buf, name);
- if (lstat (buf, &sb) == 0)
- return buf;
-
- if (*p2 == ':')
- p2++;
- p1 = p2;
- }
- return name;
-}
-
-int execl (const char *path, const char *arg, ...)
-{
-#ifdef SCO_3_5
- return execve (path, (char *const *) &arg, environ);
-#else
- char ** argv;
- va_list ap;
- int i;
-
- va_start(ap, arg);
- for (i = 1; va_arg(ap, char *) != NULL; i++);
- va_end(ap);
-
- argv = alloca (i * sizeof (char *));
-
- va_start(ap, arg);
- argv[0] = (char *) arg;
- for (i = 1; (argv[i] = (char *) va_arg(ap, char *)) != NULL; i++);
- va_end(ap);
-
- return execve (path, argv, environ);
-#endif
-}
-
-int execlp (const char *name, const char *arg, ...)
-{
-#ifdef SCO_3_5
- char buf[MAXPATHLEN];
- return execve (find (name, buf), (char *const *) &arg, environ);
-#else
- char buf[MAXPATHLEN];
- char ** argv;
- va_list ap;
- int i;
-
- va_start(ap, arg);
- for (i = 1; va_arg(ap, char *) != NULL; i++);
- va_end(ap);
-
- argv = alloca (i * sizeof (char *));
-
- va_start(ap, arg);
- argv[0] = (char *) arg;
- for (i = 1; (argv[i] = (char *) va_arg(ap, char *)) != NULL; i++);
- va_end(ap);
-
- return execve (find (name, buf), argv, environ);
-#endif
-}
-
-int execle (const char *name, const char *arg, ... /* , char *const envp[] */);
-
-/* This one turns on ptrace-style tracing? */
-int exect (const char *path, char *const argv[], char *const envp[]);
-
-int execv (const char *path, char *const argv[]) {
- return execve (path, argv, environ);
-}
-
-int execvp (const char *name, char *const argv[]) {
- char buf[MAXPATHLEN];
- return execve (find (name, buf), argv, environ);
-}
diff --git a/mit-pthreads/pthreads/pthread.c b/mit-pthreads/pthreads/pthread.c
deleted file mode 100644
index 6f7e2d53980..00000000000
--- a/mit-pthreads/pthreads/pthread.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ==== pthread.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread functions.
- *
- * 1.00 93/07/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sched.h>
-
-/* ==========================================================================
- * sched_yield()
- */
-int sched_yield()
-{
- sig_handler_fake(SIGVTALRM);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_yield()
- */
-void pthread_yield()
-{
- sig_handler_fake(SIGVTALRM);
-}
-
-/* ==========================================================================
- * pthread_self()
- */
-pthread_t pthread_self()
-{
- return(pthread_run);
-}
-
-/* ==========================================================================
- * pthread_equal()
- */
-int pthread_equal(pthread_t t1, pthread_t t2)
-{
- return(t1 == t2);
-}
-
-/* ==========================================================================
- * pthread_exit()
- */
-extern void pthread_cleanupspecific(void);
-
-void pthread_exit(void *status)
-{
- pthread_t pthread;
-
- /* Save return value */
- pthread_run->ret = status;
-
- /* First execute all cleanup handlers */
- while (pthread_run->cleanup) {
- pthread_cleanup_pop(1);
- }
-
- /* Don't forget the cleanup attr */
- if (pthread_run->attr.cleanup_attr) {
- pthread_run->attr.cleanup_attr(pthread_run->attr.arg_attr);
- }
-
- /* Next run thread-specific data desctructors */
- if (pthread_run->specific_data) {
- pthread_cleanupspecific();
- }
-
- pthread_sched_prevent();
-
- if (!(pthread_run->attr.flags & PTHREAD_DETACHED)) {
- /*
- * Are there any threads joined to this one,
- * if so wake them and let them detach this thread.
- */
- while (pthread = pthread_queue_deq(&(pthread_run->join_queue))) {
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- pthread->state = PS_RUNNING;
- }
- pthread_queue_enq(&pthread_dead_queue, pthread_run);
- pthread_resched_resume(PS_DEAD);
- } else {
- pthread_queue_enq(&pthread_alloc_queue, pthread_run);
- pthread_resched_resume(PS_UNALLOCED);
- }
-
- /* This thread will never run again */
- PANIC();
-
-}
-
-/*----------------------------------------------------------------------
- * Function: __pthread_is_valid
- * Purpose: Scan the list of threads to see if a specified thread exists
- * Args:
- * pthread = The thread to scan for
- * Returns:
- * int = 1 if found, 0 if not
- * Notes:
- * The kernel is assumed to be locked
- *----------------------------------------------------------------------*/
-int
-__pthread_is_valid( pthread_t pthread )
-{
- int rtn = 0; /* Assume not found */
- pthread_t t;
-
- for( t = pthread_link_list; t; t = t->pll ) {
- if( t == pthread ) {
- rtn = 1; /* Found it */
- break;
- }
- }
-
- return rtn;
-}
-
-/* ==========================================================================
- * __pthread_free()
- */
-static inline void __pthread_free(pthread_t new_thread)
-{
- pthread_sched_prevent();
- new_thread->state = PS_UNALLOCED;
- new_thread->attr.stacksize_attr = 0;
- new_thread->attr.stackaddr_attr = NULL;
- pthread_queue_enq(&pthread_alloc_queue, new_thread);
- pthread_sched_resume();
-}
-/* ==========================================================================
- * __pthread_alloc()
- */
-/* static inline pthread_t __pthread_alloc(const pthread_attr_t *attr) */
-static pthread_t __pthread_alloc(const pthread_attr_t *attr)
-{
- pthread_t thread;
- void * stack;
- void * old;
-
- pthread_sched_prevent();
- thread = pthread_queue_deq(&pthread_alloc_queue);
- pthread_sched_resume();
-
- if (thread) {
- if (stack = attr->stackaddr_attr) {
- __machdep_stack_repl(&(thread->machdep_data), stack);
- } else {
- if ((__machdep_stack_get(&(thread->machdep_data)) == NULL)
- || (attr->stacksize_attr > thread->attr.stacksize_attr)) {
- if (stack = __machdep_stack_alloc(attr->stacksize_attr)) {
- __machdep_stack_repl(&(thread->machdep_data), stack);
- } else {
- __pthread_free(thread);
- thread = NULL;
- }
- }
- }
- } else {
- /* We should probable allocate several for efficiency */
- if (thread = (pthread_t)malloc(sizeof(struct pthread))) {
- /* Link new thread into list of all threads */
-
- pthread_sched_prevent();
- thread->state = PS_UNALLOCED;
- thread->pll = pthread_link_list;
- pthread_link_list = thread;
- pthread_sched_resume();
-
- if ((stack = attr->stackaddr_attr) ||
- (stack = __machdep_stack_alloc(attr->stacksize_attr))) {
- __machdep_stack_set(&(thread->machdep_data), stack);
- } else {
- __machdep_stack_set(&(thread->machdep_data), NULL);
- __pthread_free(thread);
- thread = NULL;
- }
- }
- }
- return(thread);
-}
-
-/* ==========================================================================
- * pthread_create()
- *
- * After the new thread structure is allocated and set up, it is added to
- * pthread_run_next_queue, which requires a sig_prevent(),
- * sig_check_and_resume()
- */
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
- void * (*start_routine)(void *), void *arg)
-{
- pthread_t new_thread;
- int nsec = 100000000;
- int retval = OK;
-
- if (! attr)
- attr = &pthread_attr_default;
-
- if (new_thread = __pthread_alloc(attr)) {
-
- __machdep_pthread_create(&(new_thread->machdep_data),
- start_routine, arg, attr->stacksize_attr, nsec, 0);
-
- memcpy(&new_thread->attr, attr, sizeof(pthread_attr_t));
- if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
- new_thread->pthread_priority = pthread_run->pthread_priority;
- new_thread->attr.sched_priority = pthread_run->pthread_priority;
- new_thread->attr.schedparam_policy =
- pthread_run->attr.schedparam_policy;
- } else {
- new_thread->pthread_priority = new_thread->attr.sched_priority;
- }
-
- if (!(new_thread->attr.flags & PTHREAD_NOFLOAT)) {
- machdep_save_float_state(new_thread);
- }
-
- /* Initialize signalmask */
- new_thread->sigmask = pthread_run->sigmask;
- sigemptyset(&(new_thread->sigpending));
- new_thread->sigcount = 0;
-
- pthread_queue_init(&(new_thread->join_queue));
- new_thread->specific_data = NULL;
- new_thread->specific_data_count = 0;
- new_thread->cleanup = NULL;
- new_thread->queue = NULL;
- new_thread->next = NULL;
- new_thread->flags = 0;
-
- /* PTHREADS spec says we start with cancellability on and deferred */
- SET_PF_CANCEL_STATE(new_thread, PTHREAD_CANCEL_ENABLE);
- SET_PF_CANCEL_TYPE(new_thread, PTHREAD_CANCEL_DEFERRED);
-
- new_thread->error_p = NULL;
- new_thread->sll = NULL;
-
- pthread_sched_prevent();
-
-
- pthread_sched_other_resume(new_thread);
- /*
- * Assignment must be outside of the locked pthread kernel incase
- * thread is a bogus address resulting in a seg-fault. We want the
- * original thread to be capable of handling the resulting signal.
- * --proven
- */
- (*thread) = new_thread;
- } else {
- retval = EAGAIN;
- }
- return(retval);
-}
diff --git a/mit-pthreads/pthreads/pthread_attr.c b/mit-pthreads/pthreads/pthread_attr.c
deleted file mode 100644
index 5e1c0302227..00000000000
--- a/mit-pthreads/pthreads/pthread_attr.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* ==== pthread_attr.c =======================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread attribute functions.
- *
- * 1.00 93/11/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <string.h>
-
-/* Currently we do no locking, should we just to be safe? CAP */
-/* ==========================================================================
- * pthread_attr_init()
- */
-int pthread_attr_init(pthread_attr_t *attr)
-{
- memcpy(attr, &pthread_attr_default, sizeof(pthread_attr_t));
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_destroy()
- */
-int pthread_attr_destroy(pthread_attr_t *attr)
-{
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getstacksize()
- */
-int pthread_attr_getstacksize(pthread_attr_t *attr, size_t * stacksize)
-{
- *stacksize = attr->stacksize_attr;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setstacksize()
- */
-int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
-{
- if (stacksize >= PTHREAD_STACK_MIN) {
- attr->stacksize_attr = stacksize;
- return(OK);
- }
- return(EINVAL);
-}
-
-/* ==========================================================================
- * pthread_attr_getstackaddr()
- */
-int pthread_attr_getstackaddr(pthread_attr_t *attr, void ** stackaddr)
-{
- *stackaddr = attr->stackaddr_attr;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setstackaddr()
- */
-int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr)
-{
- attr->stackaddr_attr = stackaddr;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setcleanup()
- */
-int pthread_attr_setcleanup(pthread_attr_t *attr, void (*routine)(void *),
- void * arg)
-{
- attr->cleanup_attr = routine;
- attr->arg_attr = arg;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getdetachstate()
- */
-int pthread_attr_getdetachstate(pthread_attr_t *attr, int * detachstate)
-{
- *detachstate = attr->flags & PTHREAD_DETACHED;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setdetachstate()
- */
-int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
-{
- attr->flags = (attr->flags & ~(PTHREAD_DETACHED)) |
- (detachstate & PTHREAD_DETACHED);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getfloatstate()
- */
-int pthread_attr_getfloatstate(pthread_attr_t *attr, int * floatstate)
-{
- *floatstate = attr->flags & PTHREAD_NOFLOAT;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setfloatstate()
- */
-int pthread_attr_setfloatstate(pthread_attr_t *attr, int floatstate)
-{
- attr->flags = (attr->flags & ~(PTHREAD_NOFLOAT)) |
- (floatstate & PTHREAD_NOFLOAT);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getscope()
- */
-int pthread_attr_getscope(pthread_attr_t *attr, int * contentionscope)
-{
- *contentionscope = attr->flags & PTHREAD_SCOPE_SYSTEM;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setscope()
- */
-int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
-{
- int ret;
-
- switch (contentionscope) {
- case PTHREAD_SCOPE_PROCESS:
- attr->flags = (attr->flags & ~(PTHREAD_SCOPE_PROCESS))
- | PTHREAD_SCOPE_PROCESS;
- ret = OK;
- break;
- case PTHREAD_SCOPE_SYSTEM:
- ret = ENOSYS;
- break;
- default:
- ret = EINVAL;
- break;
- }
-
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_attr_getinheritsched()
- */
-int pthread_attr_getinheritsched(pthread_attr_t *attr, int * inheritsched)
-{
- *inheritsched = attr->flags & PTHREAD_INHERIT_SCHED;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setinheritsched()
- */
-int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
-{
- attr->flags = (attr->flags & ~(PTHREAD_INHERIT_SCHED)) |
- (inheritsched & PTHREAD_INHERIT_SCHED);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getschedpolicy()
- */
-int pthread_attr_getschedpolicy(pthread_attr_t *attr, int * schedpolicy)
-{
- *schedpolicy = (int)attr->schedparam_policy;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setschedpolicy()
- */
-int pthread_attr_setschedpolicy(pthread_attr_t *attr, int schedpolicy)
-{
- int ret;
-
- switch(schedpolicy) {
- case SCHED_FIFO:
- case SCHED_IO:
- case SCHED_RR:
- attr->schedparam_policy = schedpolicy;
- ret = OK;
- break;
- default:
- ret = EINVAL;
- break;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_attr_getschedparam()
- */
-int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param * param)
-{
- param->sched_priority = attr->sched_priority;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setschedparam()
- */
-int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param * param)
-{
- if ((param->sched_priority >= PTHREAD_MIN_PRIORITY) &&
- (param->sched_priority <= PTHREAD_MAX_PRIORITY)) {
- attr->sched_priority = param->sched_priority;
- return(OK);
- }
- return(EINVAL);
-}
-
diff --git a/mit-pthreads/pthreads/pthread_cancel.c b/mit-pthreads/pthreads/pthread_cancel.c
deleted file mode 100644
index 4191a269027..00000000000
--- a/mit-pthreads/pthreads/pthread_cancel.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* ==== pthread_cancel.c ====================================================
- * Copyright (c) 1996 by Larry V. Streepy, Jr.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Larry V. Streepy, Jr.
- * 4. The name of Larry V. Streepy, Jr. may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Larry V. Streepy, Jr. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Larry V. Streepy, Jr. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_cancel operations
- *
- * 27 Sep 1996 - Larry V. Streepy, Jr.
- * - Initial coding
- */
-#ifndef lint
-static const char rcsid[] = "$Id:";
-#endif
-#include <pthread.h>
-#include <errno.h>
-static void possiblyMakeRunnable( pthread_t pthread );
-
-/*----------------------------------------------------------------------
- * Function: pthread_cancel
- * Purpose: Allows a thread to request that it or another thread
- * terminate execution
- * Args:
- * thread = thread to mark as cancelled
- * Returns:
- * int 0 = ok, -1 = some error (see errno)
- * Notes:
- * The thread is simply marked as CANCELLED, it is up to the cancelled
- * thread to decide how to handle it.
- *----------------------------------------------------------------------*/ int
-pthread_cancel( pthread_t pthread )
-{
- int rtn = 0; /* Assume all ok */
- pthread_sched_prevent();
- /* Ensure they gave us a legal pthread pointer */
- if( ! __pthread_is_valid( pthread ) ) {
- rtn = ESRCH; /* No such thread */
- } else if( pthread->state == PS_UNALLOCED || pthread->state == PS_DEAD ) {
- /* The standard doesn't call these out as errors, so return 0 */
- rtn = 0;
- } else {
- SET_PF_CANCELLED(pthread); /* Set the flag */
- /* If the thread is in the right state, then stick it on the
- * run queue so it will get a chance to process the cancel.
- */
- if( pthread != pthread_run ) {
- possiblyMakeRunnable( pthread );
- }
- }
- pthread_sched_resume();
- if( rtn == 0 )
- pthread_testcancel(); /* See if we cancelled ourself */
- return rtn;
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_setcancelstate
- * Purpose: Set the current thread's cancellability state
- * Args:
- * state = PTHREAD_CANCEL_DISABLE or PTHREAD_CANCEL_ENABLE
- * oldstate= pointer to holder for old state or NULL (*MODIFIED*)
- * Returns:
- * int 0 = ok
- * EINVAL = state is neither of the legal states
- * Notes:
- * This has to be async-cancel safe, so we prevent scheduling in
- * here
- *----------------------------------------------------------------------*/
-
-int
-pthread_setcancelstate( int newstate, int *oldstate )
-{
- int ostate = TEST_PF_CANCEL_STATE(pthread_run);
- int rtn = 0;
- pthread_sched_prevent();
- if( newstate == PTHREAD_CANCEL_ENABLE ||
- newstate == PTHREAD_CANCEL_DISABLE ) {
- SET_PF_CANCEL_STATE(pthread_run, newstate);
- if( oldstate != NULL )
- *oldstate = ostate;
- } else { /* Invalid new state */
- rtn = EINVAL;
- }
- pthread_sched_resume();
- if( rtn == 0 ) {
- /* Test to see if we have a pending cancel to handle */
- pthread_testcancel();
- }
- return rtn;
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_setcanceltype
- * Purpose: Set the current thread's cancellability type
- * Args:
- * type = PTHREAD_CANCEL_DEFERRED or PTHREAD_CANCEL_ASYNCHRONOUS
- * oldtype = pointer to holder for old type or NULL (*MODIFIED*)
- * Returns:
- * int 0 = ok
- * EINVAL = type is neither of the legal states
- * Notes:
- * This has to be async-cancel safe, so we prevent scheduling in
- * here
- *----------------------------------------------------------------------*/
-
-int
-pthread_setcanceltype( int newtype, int *oldtype )
-{
- int otype = TEST_PF_CANCEL_TYPE(pthread_run);
- int rtn = 0;
- pthread_sched_prevent();
- if( newtype == PTHREAD_CANCEL_DEFERRED ||
- newtype == PTHREAD_CANCEL_ASYNCHRONOUS) {
- SET_PF_CANCEL_TYPE(pthread_run, newtype);
- if( oldtype != NULL )
- *oldtype = otype;
- } else { /* Invalid new type */
- rtn = EINVAL;
- }
- pthread_sched_resume();
- if( rtn == 0 ) {
- /* Test to see if we have a pending cancel to handle */
- pthread_testcancel();
- }
- return rtn;
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_testcancel
- * Purpose: Requests delivery of a pending cancel to the current thread
- * Args: void
- * Returns: void
- * Notes:
- * If the current thread has been cancelled, this function will not
- * return and the threads exit processing will be initiated.
- *----------------------------------------------------------------------*/
-
-void
-pthread_testcancel( void )
-{
- if( TEST_PF_CANCEL_STATE(pthread_run) == PTHREAD_CANCEL_DISABLE ) {
- return; /* Can't be cancelled */
- }
- /* Ensure that we aren't in the process of exiting already */
- if( TEST_PF_RUNNING_TO_CANCEL(pthread_run) )
- return;
-
- /* See if we have been cancelled */
- if( TEST_PF_CANCELLED(pthread_run) ) {
- /* Set this flag to avoid recursively calling pthread_exit */
- SET_PF_RUNNING_TO_CANCEL(pthread_run);
- pthread_exit( PTHREAD_CANCELLED ); /* Easy - just call pthread_exit */
- }
- return; /* Not cancelled */
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_cancel_internal
- * Purpose: An internal routine to begin the cancel processing
- * Args: freelocks = do we need to free locks before exiting
- * Returns: void
- * Notes:
- * This routine is called from pthread_resched_resume
- * prior to a context switch, and after a thread has resumed.
- *
- * The kernel must *NOT* be locked on entry here
- *----------------------------------------------------------------------*/
-
-void
-pthread_cancel_internal( int freelocks )
-{
- pthread_sched_prevent(); /* gotta stay focused */
- /* Since we can be called from pthread_resched_resume(), our
- * state is currently not PS_RUNNING. Since we side stepped
- * the actually blocking, we need to be removed from the queue
- * and marked as running.
- */
- if( pthread_run->state != PS_RUNNING ) {
- if( pthread_run->queue == NULL ) {
- PANIC(); /* Must be on a queue */
- }
- /* We MUST NOT put the thread on the prio_queue here. It
- * is already running (although it's state has changed) and if we
- * put it on the run queue, it will get resumed after it is dead
- * and we end up with a nice panic.
- */
- pthread_queue_remove(pthread_run->queue, pthread_run);
- pthread_run->state = PS_RUNNING; /* we are running */
- }
- /* Set this flag to avoid recursively calling pthread_exit */
- SET_PF_RUNNING_TO_CANCEL(pthread_run);
- /* Free up any locks we hold if told to. */
- if( freelocks ) {
- fd_unlock_for_cancel();
- }
- pthread_sched_resume();
- pthread_exit( PTHREAD_CANCELLED ); /* Easy - just call pthread_exit */
-}
-
-/*----------------------------------------------------------------------
- * Function: possiblyMakeRunnable
- * Purpose: Make a thread runnable so it can be cancelled if state allows
- * Args:
- * pthread = thread to process
- * Returns:
- * Notes:
- *----------------------------------------------------------------------*/
-
-static void
-possiblyMakeRunnable( pthread_t pthread )
-{
- if( ! TEST_PTHREAD_IS_CANCELLABLE(pthread) )
- return; /* Not currently cancellable */
- /* If the thread is currently runnable, then we just let things
- * take their course when it is next resumed.
- */
- if( pthread->state == PS_RUNNING )
- return; /* will happen at context switch */
- /* If the thread is sleeping, the it isn't on a queue. */
- if( pthread->state == PS_SLEEP_WAIT ) {
- sleep_cancel( pthread ); /* Remove from sleep list */
- } else {
- /* Otherwise, we need to take it off the queue and make it runnable */
- if( pthread->queue == NULL ) {
- PANIC(); /* Must be on a queue */
- }
- pthread_queue_remove(pthread->queue, pthread);
- }
- /* And make it runnable */
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- pthread->old_state = pthread->state;
- pthread->state = PS_RUNNING;
-}
diff --git a/mit-pthreads/pthreads/pthread_detach.c b/mit-pthreads/pthreads/pthread_detach.c
deleted file mode 100644
index d3ae8c03bb3..00000000000
--- a/mit-pthreads/pthreads/pthread_detach.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ==== pthread_detach.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_join function.
- *
- * 1.00 94/01/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-
-/* ==========================================================================
- * pthread_detach()
- */
-int pthread_detach(pthread_t pthread)
-{
- struct pthread * next_thread, * high_thread, * low_thread;
- int ret;
-
- pthread_sched_prevent();
-
- /* Check that thread isn't detached already */
- if (!(pthread->attr.flags & PTHREAD_DETACHED)) {
-
- pthread->attr.flags |= PTHREAD_DETACHED;
-
- /* Wakeup all threads waiting on a join */
- if (next_thread = pthread_queue_deq(&(pthread->join_queue))) {
- high_thread = next_thread;
-
- while (next_thread = pthread_queue_deq(&(pthread->join_queue))) {
- if (high_thread->pthread_priority < next_thread->pthread_priority) {
- low_thread = high_thread;
- high_thread = next_thread;
- } else {
- low_thread = next_thread;
- }
- pthread_prio_queue_enq(pthread_current_prio_queue, low_thread);
- low_thread->state = PS_RUNNING;
- }
- /* If the thread is dead then move it to the alloc queue */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- }
- pthread_sched_other_resume(high_thread);
- return(OK);
- }
- /* If the thread is dead then move it to the alloc queue */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- pthread->state = PS_UNALLOCED;
- }
- ret = OK;
- } else {
- ret = ESRCH;
- }
- pthread_sched_resume();
- return(ret);
-}
diff --git a/mit-pthreads/pthreads/pthread_init.c b/mit-pthreads/pthreads/pthread_init.c
deleted file mode 100644
index 83e19fe0229..00000000000
--- a/mit-pthreads/pthreads/pthread_init.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ==== pthread_init.c ========================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread_init routine.
- *
- * 1.00 94/09/20 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * errno is declared here to prevent the linker from pulling in errno
- * from the C library (and whatever else is in that file). I also use
- * errno as the default location for error numbers for the initial thread
- * giving some backwards compatibility.
- */
-#ifdef errno
-#undef errno
-#endif
-
-#if !defined(M_UNIX)
-int errno;
-#else
-extern int errno;
-#endif
-
-/* ==========================================================================
- * pthread_init()
- *
- * We use features of the C++ linker to make sure this function is called
- * before anything else is done in the program. See init.cc.
- */
-void pthread_init(void)
-{
- struct machdep_pthread machdep_data = MACHDEP_PTHREAD_INIT;
-
- /* Only call this once */
- if (pthread_initial) {
- return;
- }
-
- pthread_pagesize = getpagesize();
-
- /* Initialize the first thread */
- if ((pthread_initial = (pthread_t)malloc(sizeof(struct pthread))) &&
- (pthread_current_prio_queue = (struct pthread_prio_queue *)
- malloc(sizeof(struct pthread_prio_queue)))) {
- memcpy(&(pthread_initial->machdep_data), &machdep_data,
- sizeof(machdep_data));
- memcpy(&pthread_initial->attr, &pthread_attr_default,
- sizeof(pthread_attr_t));
-
- pthread_initial->pthread_priority = PTHREAD_DEFAULT_PRIORITY;
- pthread_initial->state = PS_RUNNING;
-
- pthread_queue_init(&(pthread_initial->join_queue));
- pthread_initial->specific_data = NULL;
- pthread_initial->specific_data_count = 0;
- pthread_initial->cleanup = NULL;
- pthread_initial->queue = NULL;
- pthread_initial->next = NULL;
- pthread_initial->flags = 0;
- pthread_initial->pll = NULL;
- pthread_initial->sll = NULL;
-
- /* PTHREADS spec says we start with cancellability on and deferred */
- SET_PF_CANCEL_STATE(pthread_initial, PTHREAD_CANCEL_ENABLE);
- SET_PF_CANCEL_TYPE(pthread_initial, PTHREAD_CANCEL_DEFERRED);
-
-
- /* Ugly errno hack */
- pthread_initial->error_p = &errno;
- pthread_initial->error = 0;
-
- pthread_prio_queue_init(pthread_current_prio_queue);
- pthread_link_list = pthread_initial;
- pthread_run = pthread_initial;
-
- uthread_sigmask = &(pthread_run->sigmask);
-
- /* XXX can I assume the mask and pending siganl sets are empty. */
- sigemptyset(&(pthread_initial->sigpending));
- sigemptyset(&(pthread_initial->sigmask));
- pthread_initial->sigcount = 0;
-
- /* Initialize the signal handler. */
- sig_init();
-
- /* Initialize the fd table. */
- fd_init();
-
- /* Start the scheduler */
- machdep_set_thread_timer(&(pthread_run->machdep_data));
-#ifdef M_UNIX
- machdep_sys_init();
-#endif
- return;
- }
- PANIC();
-}
diff --git a/mit-pthreads/pthreads/pthread_join.c b/mit-pthreads/pthreads/pthread_join.c
deleted file mode 100644
index 879250020a1..00000000000
--- a/mit-pthreads/pthreads/pthread_join.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* ==== pthread_join.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_join function.
- *
- * 1.00 94/01/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-static int testDeadlock( struct pthread_queue *queue, pthread_t target );
-
-/* ==========================================================================
- * pthread_join()
- */
-int pthread_join(pthread_t pthread, void **thread_return)
-{
- int ret;
-
- pthread_sched_prevent();
-
- /* Ensure they gave us a legal pthread pointer */
- if( ! __pthread_is_valid( pthread ) ) {
- pthread_sched_resume();
- return(EINVAL);
- }
-
- /* Check that thread isn't detached already */
- if (pthread->attr.flags & PTHREAD_DETACHED) {
- pthread_sched_resume();
- return(ESRCH);
- }
-
- /*
- * Now check if other thread has exited
- * Note: This must happen after checking detached state.
- */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
-
- /* Before we pend on the join, ensure there is no dead lock */
-
- if( testDeadlock( &pthread_run->join_queue, pthread ) == NOTOK ) {
- ret = EDEADLK;
- } else {
- pthread_queue_enq(&(pthread->join_queue), pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_JOIN);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- pthread_sched_prevent();
-
- if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- pthread->attr.flags |= PTHREAD_DETACHED;
- pthread->state = PS_UNALLOCED;
- if (thread_return) {
- *thread_return = pthread->ret;
- }
- ret = OK;
- } else {
- ret = ESRCH;
- }
- }
- } else {
- /* Just get the return value and detach the thread */
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- pthread->attr.flags |= PTHREAD_DETACHED;
- pthread->state = PS_UNALLOCED;
- if (thread_return) {
- *thread_return = pthread->ret;
- }
- ret = OK;
- }
- pthread_sched_resume();
- return(ret);
-}
-
-/*----------------------------------------------------------------------
- * Function: testDeadlock
- * Purpose: recursive queue walk to check for deadlocks
- * Args:
- * queue = the queue to walk
- * pthread = target to scan for
- * Returns:
- * OK = no deadlock, NOTOK = deadlock
- * Notes:
- *----------------------------------------------------------------------*/
-static int
-testDeadlock( struct pthread_queue *queue, pthread_t target )
-{
- pthread_t t;
-
- if( queue == NULL )
- return OK; /* Empty queue, obviously ok */
-
- for( t = queue->q_next; t; t = t->next ) {
- if( t == target )
- return NOTOK; /* bang, your dead */
-
- if( testDeadlock( &t->join_queue, target ) == NOTOK ) {
- return NOTOK;
- }
- }
-
- return OK; /* No deadlock */
-}
diff --git a/mit-pthreads/pthreads/pthread_kill.c b/mit-pthreads/pthreads/pthread_kill.c
deleted file mode 100644
index 9e3e61488a3..00000000000
--- a/mit-pthreads/pthreads/pthread_kill.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* ==== pthread_kill.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_kill function.
- *
- * 1.32 94/06/12 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* Defined in sig.c, a linked list of threads currently
- * blocked in sigwait(): */
-extern struct pthread * pthread_sigwait;
-
-
-/* ==========================================================================
- * pthread_kill()
- */
-int pthread_kill(struct pthread * pthread, int sig)
-{
- struct pthread ** pthread_ptr;
-
- pthread_sched_prevent();
-
- /* Check who is the current owner of pthread */
-/* if (pthread->kthread != pthread_run->kthread) { */
- if (0) {
- } else {
- if (pthread->state == PS_SIGWAIT) {
- if(sigismember(pthread->data.sigwait, sig)) {
- for (pthread_ptr = &pthread_sigwait;
- (*pthread_ptr);
- pthread_ptr = &((*pthread_ptr)->next)) {
- if ((*pthread_ptr) == pthread) {
-
- /* Take the thread out of the
- * pthread_sigwait linked list: */
- *pthread_ptr=(*pthread_ptr)->next;
-
- *(int *)(pthread->ret) = sig;
- pthread_sched_other_resume(pthread);
- return(OK);
- }
- }
- /* A thread should not be in the state PS_SIGWAIT
- * without being in the pthread_sigwait linked
- * list: */
- PANIC();
- }
- }
- if (!sigismember(&pthread->sigpending,sig)) /* Added by monty */
- {
- sigaddset(&(pthread->sigpending), sig);
- pthread->sigcount++;
- }
- }
-
- pthread_sched_resume();
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/pthread_once.c b/mit-pthreads/pthreads/pthread_once.c
deleted file mode 100644
index 0a3dcd23fae..00000000000
--- a/mit-pthreads/pthreads/pthread_once.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== pthread_once.c =======================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_once function.
- *
- * 1.00 93/12/12 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* ==========================================================================
- * pthread_once()
- */
-int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
-{
- /* Check first for speed */
- if (once_control->state == PTHREAD_NEEDS_INIT) {
- pthread_mutex_lock(&(once_control->mutex));
- if (once_control->state == PTHREAD_NEEDS_INIT) {
- init_routine();
- once_control->state = PTHREAD_DONE_INIT;
- }
- pthread_mutex_unlock(&(once_control->mutex));
- }
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/queue.c b/mit-pthreads/pthreads/queue.c
deleted file mode 100644
index c33774bf4dd..00000000000
--- a/mit-pthreads/pthreads/queue.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ==== queue.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Queue functions.
- *
- * 1.00 93/07/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/*
- * All routines in this file assume that the queue has been appropriatly
- * locked.
- */
-
-/* ==========================================================================
- * pthread_queue_init()
- */
-void pthread_queue_init(struct pthread_queue *queue)
-{
- queue->q_next = NULL;
- queue->q_last = NULL;
- queue->q_data = NULL;
-}
-
-/* ==========================================================================
- * pthread_queue_enq()
- */
-void pthread_queue_enq(struct pthread_queue *queue, struct pthread *thread)
-{
- if (queue->q_last) {
- queue->q_last->next = thread;
- } else {
- queue->q_next = thread;
- }
- queue->q_last = thread;
- thread->queue = queue;
- thread->next = NULL;
-
-}
-
-/* ==========================================================================
- * pthread_queue_get()
- */
-struct pthread *pthread_queue_get(struct pthread_queue *queue)
-{
- return(queue->q_next);
-}
-
-/* ==========================================================================
- * pthread_queue_deq()
- */
-struct pthread *pthread_queue_deq(struct pthread_queue *queue)
-{
- struct pthread *thread = NULL;
-
- if (queue->q_next) {
- thread = queue->q_next;
- if (!(queue->q_next = queue->q_next->next)) {
- queue->q_last = NULL;
- }
- thread->queue = NULL;
- thread->next = NULL;
- }
- return(thread);
-}
-
-/* ==========================================================================
- * pthread_queue_remove()
- */
-int pthread_queue_remove(struct pthread_queue *queue, struct pthread *thread)
-{
- struct pthread **current = &(queue->q_next);
- struct pthread *prev = NULL;
- int ret = NOTOK;
-
- while (*current) {
- if (*current == thread) {
- if ((*current)->next) {
- *current = (*current)->next;
- } else {
- queue->q_last = prev;
- *current = NULL;
- }
- thread->queue = NULL;
- thread->next = NULL;
- ret = OK;
- break;
- }
- prev = *current;
- current = &((*current)->next);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_llist_remove()
- */
-int pthread_llist_remove(struct pthread **llist, struct pthread *thread)
-{
- while (*llist) {
- if (*llist == thread) {
- *llist = thread->next;
- return(OK);
- }
- llist = &(*llist)->next;
- }
- return(NOTOK);
-}
-
diff --git a/mit-pthreads/pthreads/readv.c b/mit-pthreads/pthreads/readv.c
deleted file mode 100644
index fd63d31cf94..00000000000
--- a/mit-pthreads/pthreads/readv.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ==== readv.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Implementation of readv().
- *
- * 1.00 95/06/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-
-#ifndef HAVE_SYSCALL_READV
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-int machdep_sys_readv(int fd, struct iovec * vector, int count)
-{
- size_t bytes, i;
- char *buffer;
- int ret = 0;
-
- /* Find the total number of bytes to be read. */
- for (bytes = 0, i = 0; i < count; ++i)
- bytes += vector[i].iov_len;
-
- if (bytes) {
- /*
- * Allocate a temporary buffer to hold the data.
- * Don't use alloca because threads tend to have smaller stacks.
- */
- if ((buffer = (char *)malloc(bytes)) == NULL) {
- return(-ENOMEM);
- }
- ret = (int)machdep_sys_read(fd, buffer, bytes);
-
- /* Copy the data from memory specified by VECTOR to BUFFER */
- for (i = 0, bytes = 0; ret > 0; ret -= vector[i].iov_len) {
- memcpy(vector[i].iov_base, buffer + bytes,
- ret > vector[i].iov_len ? vector[i].iov_len : ret);
- bytes += vector[i].iov_len;
- }
- free(buffer);
- }
- return(ret);
-}
-
-#endif
diff --git a/mit-pthreads/pthreads/schedparam.c b/mit-pthreads/pthreads/schedparam.c
deleted file mode 100644
index b4b28577022..00000000000
--- a/mit-pthreads/pthreads/schedparam.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* ==== schedparam.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread schedparam functions.
- *
- * 1.38 94/06/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sched.h>
-#include <errno.h>
-
-/* ==========================================================================
- * sched_get_priority_max
- */
-int sched_get_priority_max(int policy)
-{
- return PTHREAD_MAX_PRIORITY;
-}
-
-/* ==========================================================================
- * sched_get_priority_min
- */
-int sched_get_priority_min(int policy)
-{
- return PTHREAD_MIN_PRIORITY;
-}
-
-/* Currently only policy is supported */
-/* ==========================================================================
- * pthread_setschedparam()
- */
-int pthread_setschedparam(pthread_t pthread, int policy,
- struct sched_param * param)
-{
- enum schedparam_policy new_policy, old_policy;
- int ret = OK;
- int prio;
-
- new_policy = policy;
- pthread_sched_prevent();
- old_policy = pthread->attr.schedparam_policy;
-
- if (param) {
- if ((param->sched_priority < PTHREAD_MIN_PRIORITY) ||
- (param->sched_priority > PTHREAD_MAX_PRIORITY)) {
- pthread_sched_resume();
- return(EINVAL);
- }
- prio = param->sched_priority;
- } else {
- prio = pthread->pthread_priority;
- }
-
- if (pthread == pthread_run) {
- switch(new_policy) {
- case SCHED_RR:
- pthread->attr.schedparam_policy = new_policy;
- switch (old_policy) {
- case SCHED_FIFO:
- machdep_unset_thread_timer(NULL);
- default:
- pthread->pthread_priority = prio;
- break;
- }
- break;
- case SCHED_FIFO:
- pthread->attr.schedparam_policy = new_policy;
- switch (old_policy) {
- case SCHED_IO:
- case SCHED_RR:
- if (pthread->pthread_priority < prio) {
- pthread->pthread_priority = prio;
- pthread_sched_resume();
- pthread_yield();
- return(OK);
- }
- default:
- pthread->pthread_priority = prio;
- break;
- }
- break;
- case SCHED_IO:
- pthread->attr.schedparam_policy = new_policy;
- switch (old_policy) {
- case SCHED_FIFO:
- machdep_unset_thread_timer(NULL);
- default:
- pthread->pthread_priority = prio;
- break;
- }
- break;
- default:
- SET_ERRNO(EINVAL);
- ret = EINVAL;
- break;
- }
- } else {
- switch(new_policy) {
- case SCHED_FIFO:
- case SCHED_IO:
- case SCHED_RR:
- if(pthread_prio_queue_remove(pthread_current_prio_queue,pthread) == OK) {
- pthread->attr.schedparam_policy = new_policy;
- pthread->pthread_priority = prio;
- pthread_sched_other_resume(pthread);
- } else {
- pthread->attr.schedparam_policy = new_policy;
- pthread->pthread_priority = prio;
- pthread_sched_resume();
- }
- return(OK);
- break;
- default:
- SET_ERRNO(EINVAL);
- ret = EINVAL;
- break;
- }
- }
-
- pthread_sched_resume();
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_getschedparam()
- */
-int pthread_getschedparam(pthread_t pthread, int * policy,
- struct sched_param * param)
-{
- *policy = pthread->attr.schedparam_policy;
- if (param) {
- param->sched_priority = pthread->pthread_priority;
- }
- return(OK);
-}
-
diff --git a/mit-pthreads/pthreads/select.c b/mit-pthreads/pthreads/select.c
deleted file mode 100644
index eaafce31f19..00000000000
--- a/mit-pthreads/pthreads/select.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* ==== select.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This code based on code contributed by
- * Peter Hofmann <peterh@prz.tu-berlin.d400.de>
- *
- * Description : Select.
- *
- * 1.23 94/04/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <string.h>
-#include <errno.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-extern struct pthread_queue fd_wait_select;
-static struct timeval zero_timeout = { 0, 0 }; /* Moved by monty */
-
-/* ==========================================================================
- * select()
- */
-int select(int numfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
-{
- fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
- fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
- fd_set read_locks, write_locks, rdwr_locks;
- struct timespec timeout_time, current_time;
- int i, j, ret = 0, got_all_locks = 1;
- struct pthread_select_data data;
-
- if (numfds > dtablesize) {
- numfds = dtablesize;
- }
-
- data.nfds = 0;
- FD_ZERO(&data.readfds);
- FD_ZERO(&data.writefds);
- FD_ZERO(&data.exceptfds);
-
- /* Do this first */
- if (timeout) {
- machdep_gettimeofday(&current_time);
- timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
- if ((timeout_time.tv_nsec = current_time.tv_nsec +
- (timeout->tv_usec * 1000)) > 1000000000) {
- timeout_time.tv_nsec -= 1000000000;
- timeout_time.tv_sec++;
- }
- }
-
- FD_ZERO(&read_locks);
- FD_ZERO(&write_locks);
- FD_ZERO(&rdwr_locks);
- FD_ZERO(&real_readfds);
- FD_ZERO(&real_writefds);
- FD_ZERO(&real_exceptfds);
-
- /* lock readfds */
- if (readfds || writefds || exceptfds) {
- for (i = 0; i < numfds; i++) {
- if ((readfds && (FD_ISSET(i, readfds))) ||
- (exceptfds && FD_ISSET(i, exceptfds))) {
- if (writefds && FD_ISSET(i ,writefds)) {
- if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &rdwr_locks);
- FD_SET(fd_table[i]->fd.i,&real_writefds);
- } else {
- if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &read_locks);
- }
- if (readfds && FD_ISSET(i,readfds)) {
- FD_SET(fd_table[i]->fd.i, &real_readfds);
- }
- if (exceptfds && FD_ISSET(i,exceptfds)) {
- FD_SET(fd_table[i]->fd.i, &real_exceptfds);
- }
- if (fd_table[i]->fd.i >= data.nfds) {
- data.nfds = fd_table[i]->fd.i + 1;
- }
- } else {
- if (writefds && FD_ISSET(i, writefds)) {
- if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &write_locks);
- FD_SET(fd_table[i]->fd.i,&real_writefds);
- if (fd_table[i]->fd.i >= data.nfds) {
- data.nfds = fd_table[i]->fd.i + 1;
- }
- }
- }
- }
- }
-
- if (got_all_locks)
- {
- memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
- memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
- memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
-
- real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
- real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
- real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
-
- pthread_run->sighandled=0;
- if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
- real_writefds_p, real_exceptfds_p,
- &zero_timeout)) == OK) {
- pthread_sched_prevent();
-
- real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
- real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
- real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
-
- pthread_queue_enq(&fd_wait_select, pthread_run);
- pthread_run->data.select_data = &data;
- SET_PF_WAIT_EVENT(pthread_run);
-
- if (timeout) {
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, &timeout_time);
-
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- if (sleep_cancel(pthread_run) == NOTOK) {
- ret = OK;
- }
- else
- {
- int count = 0;
- for (i = 0; i < numfds; i++)
- {
- if (real_readfds_p && (FD_ISSET(i, real_readfds_p)))
- count++;
- if (real_writefds_p && (FD_ISSET(i, real_writefds_p)))
- count++;
- if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p)))
- count++;
- }
- ret = count;
- }
- /* Moving this after the sleep_cancel() seemed
- * to fix intermittent crashes during heavy
- * socket use. (mevans)
- */
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- int count = 0;
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- CLEAR_PF_DONE_EVENT(pthread_run);
- for (i = 0; i < numfds; i++)
- {
- if (real_readfds_p && (FD_ISSET(i, real_readfds_p)))
- count++;
- if (real_writefds_p && (FD_ISSET(i, real_writefds_p)))
- count++;
- if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p)))
- count++;
- }
- ret = count;
- }
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= NOTOK;
- SET_ERRNO(EINTR);
- }
- } else if (ret < 0) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- }
-
- /* clean up the locks */
- for (i = 0; i < numfds; i++)
- { /* Changed by monty */
- if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
- if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
- if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
- }
- if (ret > 0) {
- if (readfds != NULL) {
- for (i = 0; i < numfds; i++) {
- if (! (FD_ISSET(i,readfds) &&
- FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
- FD_CLR(i,readfds);
- }
- }
- if (writefds != NULL) {
- for (i = 0; i < numfds; i++)
- if (! (FD_ISSET(i,writefds) &&
- FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
- FD_CLR(i,writefds);
- }
- if (exceptfds != NULL) {
- for (i = 0; i < numfds; i++)
- if (! (FD_ISSET(i,exceptfds) &&
- FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
- FD_CLR(i,exceptfds);
- }
- } else {
- if (exceptfds != NULL) FD_ZERO(exceptfds);
- if (writefds != NULL) FD_ZERO(writefds);
- if (readfds != NULL) FD_ZERO(readfds);
- }
-
- return(ret);
-}
diff --git a/mit-pthreads/pthreads/sig.c b/mit-pthreads/pthreads/sig.c
deleted file mode 100644
index 85d4465bf1c..00000000000
--- a/mit-pthreads/pthreads/sig.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/* ==== sig.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the thread signal functions.
- *
- * 1.32 94/06/12 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-
-#if defined(M_UNIX)
-#define signal(A,B) machdep_sys_signal((A),(B))
-#endif
-
-extern void sig_handler_real();
-
-struct pthread * pthread_sigwait;
-static sigset_t pending_signals;
-
-struct pthread_sigvec {
- void (*vector)();
- sigset_t mask;
- int flags;
-} pthread_sigvec[SIGMAX];
-
-/* ==========================================================================
- * pthread_sig_register()
- *
- * Assumes the kernel is locked.
- */
-int pthread_sig_register(int sig)
-{
- struct pthread ** pthread_ptr, * pthread;
- int ret;
-
- /*
- * If we have a siginfo structure and the signal is synchronous then
- * only deliver the signal to the current thread.
- */
-
- /* Check waiting threads for delivery */
- for (pthread_ptr = &pthread_sigwait; (*pthread_ptr);
- pthread_ptr = &((*pthread_ptr)->next)) {
- if (sigismember((*pthread_ptr)->data.sigwait, sig)) {
- pthread=*pthread_ptr;
- *pthread_ptr=(*pthread_ptr)->next;
-
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- ret = pthread->pthread_priority;
- *(int *)(pthread->ret) = sig;
- pthread->state = PS_RUNNING;
-
- return(ret);
- }
- }
-
- /* Check current running thread */
- if (pthread_run) {
- if (!sigismember(&pthread_run->sigmask, sig)) {
- sigaddset(&pthread_run->sigpending, sig);
- pthread_run->sigcount++;
- return(0);
- }
- }
-
- /* Check any running thread */
- for (pthread = pthread_current_prio_queue->next;
- pthread; pthread = pthread->next) {
- if (!sigismember(&pthread->sigmask, sig)) {
- sigaddset(&pthread->sigpending, sig);
- pthread->sigcount++;
- return(0);
- }
- }
-
- /* Check any thread */
- for (pthread = pthread_link_list; pthread; pthread = pthread->pll) {
- if (!sigismember(&pthread->sigmask, sig)) {
- sigaddset(&pthread->sigpending, sig);
- pthread->sigcount++;
- return(0);
- }
- }
-
- sigaddset(&pending_signals, sig);
- return(0);
-}
-
-/* ==========================================================================
- * pthread_sig_default()
- */
-void pthread_sig_default(int sig)
-{
- sigset_t mask, omask;
-
- if (pthread_sigvec[sig].vector == SIG_DFL) {
- /* Set the signal handler to default before issueing the kill */
- signal(sig, SIG_DFL);
- kill(getpid(), sig);
- sigemptyset(&mask);
- sigaddset(&mask, sig);
- machdep_sys_sigprocmask(SIG_UNBLOCK, &mask, &omask);
- signal(sig, sig_handler_real);
- }
-}
-
-/* ==========================================================================
- * pthread_sig_process()
- *
- * Assumes the kernel is locked.
- */
-void pthread_sig_process()
-{
- void (*vector)();
- int i, j;
-
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(&(pthread_run->sigpending), i)) {
- if (! sigismember(&(pthread_run->sigmask), i)) {
- sigdelset(&(pthread_run->sigpending), i);
- pthread_run->sigcount--;
-
- if (pthread_sigvec[i].vector == SIG_IGN) {
- continue;
- }
- if (pthread_sigvec[i].vector == SIG_DFL) {
- pthread_sig_default(i);
- continue;
- }
-
- {
- sigset_t omask;
-
- sigemptyset(&omask);
- /* Save old mask */
- for (j = 1; j < SIGMAX; j++) {
- if (sigismember(&(pthread_run->sigmask), j)) {
- if (sigismember(&(pthread_sigvec[i].mask), j))
- sigaddset(&(pthread_run->sigmask), j);
- sigaddset(&omask, j);
- }
- }
- /* The signal is masked while handling the signal */
- sigaddset(&(pthread_run->sigmask), i);
-
- /*
- * Allow interrupts during a signal,
- * but not a change in the vector
- */
- vector = pthread_sigvec[i].vector;
- if (--pthread_kernel_lock) {
- PANIC();
- }
- vector(i);
- pthread_run->sighandled=1; /* Mark for select; Monty */
- pthread_kernel_lock++;
-
- memcpy(&(pthread_run->sigmask), &omask, sizeof(omask));
- }
- }
- }
- }
-}
-
-/* ==========================================================================
- * pthread_sigmask()
- *
- * It is unclear wheather this call should be implemented as an atomic
- * operation. The resulting mask could be wrong if in the signal
- * handler the thread calls sigprocmask for any signal other than the
- * signal the handler is dealing with.
- */
-int pthread_sigmask(int how, const sigset_t *set, sigset_t * oset)
-{
- int i;
-
- if (oset) {
- sigemptyset(oset);
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(&(pthread_run->sigmask), i)) {
- sigaddset(oset, i);
- }
- }
- }
-
- if (set) {
- switch(how) {
- case SIG_BLOCK:
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(set, i)) {
- sigaddset(&(pthread_run->sigmask), i);
- }
- }
- break;
- case SIG_UNBLOCK:
- pthread_sched_prevent();
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(set, i)) {
- sigdelset(&(pthread_run->sigmask), i);
- if (sigismember(&pending_signals, i)) {
- sigaddset(&(pthread_run->sigpending), i);
- sigdelset(&pending_signals, i);
- pthread_run->sigcount++;
- }
- }
- }
- pthread_sched_resume();
- break;
- case SIG_SETMASK:
- sigfillset(&(pthread_run->sigmask));
- pthread_sched_prevent();
- for (i = 1; i < SIGMAX; i++) {
- if (! sigismember(set, i)) {
- sigdelset(&(pthread_run->sigmask), i);
- if (sigismember(&pending_signals, i)) {
- sigaddset(&(pthread_run->sigpending), i);
- sigdelset(&pending_signals, i);
- pthread_run->sigcount++;
- }
- }
- }
- pthread_sched_resume();
- break;
- default:
- SET_ERRNO(EINVAL);
- return(NOTOK);
- }
- }
- return(OK);
-}
-
-int sigprocmask(int how, const sigset_t *set, sigset_t * oset)
-{
- return(pthread_sigmask(how, set, oset));
-}
-
-/* ==========================================================================
- * sigwait()
- */
-int sigwait(const sigset_t * set, int * sig)
-{
- int i;
-
- /* Check that sig is valid */
- *sig = 0;
-
- pthread_sched_prevent();
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(set, i)) {
- /* Check personal signals */
- if (sigismember(&(pthread_run->sigpending), i)) {
- sigdelset(&(pthread_run->sigpending), i);
- pthread_sched_resume();
- *sig = i;
- return(OK);
- }
- /* Check kernel signals */
- if (sigismember(&pending_signals, i)) {
- sigdelset(&pending_signals, i);
- pthread_sched_resume();
- *sig = i;
- return(OK);
- }
- }
- }
-
- /* No pending signals, wait for one */
- pthread_run->next = pthread_sigwait;
- pthread_sigwait = pthread_run;
- pthread_run->data.sigwait = set;
- pthread_run->ret = sig;
-
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SIGWAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- return(OK);
-}
-
-/* ==========================================================================
- * raise()
- */
-int raise(int sig)
-{
- return(pthread_kill(pthread_self(), sig));
-}
-
-/* ==========================================================================
- * sigsuspend()
- */
-int sigsuspend(const sigset_t * mask)
-{
- int ret_sig, ret;
- sigset_t nm, om;
-
- sigfillset(&nm);
- for(ret_sig = 1; ret_sig < SIGMAX; ret_sig++) {
- if (sigismember(mask, ret_sig)) {
- sigdelset(&nm, ret_sig);
- }
- }
- pthread_sigmask(SIG_BLOCK, &nm, &om);
- if ((ret = sigwait(&nm, &ret_sig)) == OK) {
- sigemptyset(&nm);
- sigaddset(&nm, ret_sig);
- pthread_kill(pthread_self(), ret_sig);
- pthread_sigmask(SIG_UNBLOCK, &nm, NULL);
- /* There is a race condition here, it's not worth worring about */
- pthread_sigmask(SIG_BLOCK, &nm, NULL);
- SET_ERRNO(EINTR);
- ret = NOTOK;
- }
- pthread_sigmask(SIG_SETMASK, &om, NULL);
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_signal()
- */
-void (*pthread_signal(int sig, void (*dispatch)(int)))()
-{
- void (*odispatch)(int);
-
- odispatch = pthread_sigvec[sig].vector;
- if ((sig > 0) && (sig < SIGMAX)) {
- pthread_sigvec[sig].vector = dispatch;
- sigemptyset(&(pthread_sigvec[sig].mask));
- pthread_sigvec[sig].flags = 0;
- }
- return(odispatch);
-}
-
-/* ==========================================================================
- * pthread_sigprocmask()
- */
-int pthread_sigaction(int sig, const struct sigaction * act,
- struct sigaction * oact)
-{
- if ((sig > 0) && (sig < SIGMAX)) {
- if (oact) {
- memcpy(&(oact->sa_mask), &(pthread_sigvec[sig].mask),
- sizeof(sigset_t));
- oact->sa_handler = pthread_sigvec[sig].vector;
- oact->sa_flags = pthread_sigvec[sig].flags;
- }
- if (act) {
- memcpy(&(pthread_sigvec[sig].mask), &(act->sa_mask),
- sizeof(sigset_t));
- pthread_sigvec[sig].vector = act->sa_handler;
- pthread_sigvec[sig].flags = act->sa_flags;
- }
- return(OK);
- }
- SET_ERRNO(EINVAL);
- return(NOTOK);
-}
-
-/*
- * The following here are stolen from BSD because I get mutiply defined
- * symbols between sig.o and posix_sig.o in Sun's libc.a under Sunos 4.1.3.
- * The problem is that sigprocmask() is defined in posix_sig.o, in the same
- * module that a lot of other sigset-primitives are defined, and we have
- * our definition of sigprocmask() here, but use those other primitives.
- */
-
-#undef sigemptyset
-#undef sigfillset
-#undef sigaddset
-#undef sigdelset
-#undef sigismember
-
-static const sigset_t __sigemptyset = __SIGEMPTYSET;
-int sigemptyset(sigset_t *set)
-{
- *set = __sigemptyset;
- return (0);
-}
-
-static const sigset_t __sigfillset = __SIGFILLSET;
-int sigfillset(sigset_t * set)
-{
- *set = __sigfillset;
- return (0);
-}
-
-#define _MAXIMUM_SIG NSIG
-
-int sigaddset(sigset_t *set, int signo)
-{
- if (signo <= 0 || signo >= _MAXIMUM_SIG) {
- errno = EINVAL;
- return -1;
- }
- __SIGADDSET(set, signo);
- return (0);
-}
-
-int sigdelset(sigset_t *set, int signo)
-{
- if (signo <= 0 || signo >= _MAXIMUM_SIG) {
- errno = EINVAL;
- return -1;
- }
- __SIGDELSET(set, signo);
- return (0);
-}
-
-int sigismember(const sigset_t *set, int signo)
-{
- if (signo <= 0 || signo >= _MAXIMUM_SIG) {
- errno = EINVAL;
- return -1;
- }
- return(__SIGISMEMBER(set, signo));
-}
-
diff --git a/mit-pthreads/pthreads/signal.c b/mit-pthreads/pthreads/signal.c
deleted file mode 100644
index 7da4183c1cb..00000000000
--- a/mit-pthreads/pthreads/signal.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/* ==== signal.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Queue functions.
- *
- * 1.00 93/07/21 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <config.h>
-#include <pthread.h>
-#include <signal.h>
-
-/* This will force init.o to get dragged in; if you've got support for
- C++ initialization, that'll cause pthread_init to be called at
- program startup automatically, so the application won't need to
- call it explicitly. */
-
-extern char __pthread_init_hack;
-char *__pthread_init_hack_2 = &__pthread_init_hack;
-
-/*
- * Time which select in fd_kern_wait() will sleep.
- * If there are no threads to run we sleep for an hour or until
- * we get an interrupt or an fd thats awakens. To make sure we
- * don't miss an interrupt this variable gets reset too zero in
- * sig_handler_real().
- */
-struct timeval __fd_kern_wait_timeout = { 0, 0 };
-
-/*
- * Global for user-kernel lock, and blocked signals
- */
-
-static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-volatile sig_atomic_t sig_to_process = 0;
-
-/* static volatile sigset_t sig_to_process; */
-static volatile int sig_count = 0;
-
-static void sig_handler(int signal);
-static void set_thread_timer();
-static void __cleanup_after_resume( void );
-void sig_prevent(void);
-void sig_resume(void);
-
-/* ==========================================================================
- * context_switch()
- *
- * This routine saves the current state of the running thread gets
- * the next thread to run and restores it's state. To allow different
- * processors to work with this routine, I allow the machdep_restore_state()
- * to either return or have it return from machdep_save_state with a value
- * other than 0, this is for implementations which use setjmp/longjmp.
- */
-static void context_switch()
-{
- struct pthread **current, *next, *last, **dead;
-
- if (pthread_run->state == PS_RUNNING) {
- /* Put current thread back on the queue */
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread_run);
- }
-
- /* save floating point registers if necessary */
- if (!(pthread_run->attr.flags & PTHREAD_NOFLOAT)) {
- machdep_save_float_state(pthread_run);
- }
- /* save state of current thread */
- if (machdep_save_state()) {
- return;
- }
-
- last = pthread_run;
-
- /* Poll all fds */
- fd_kern_poll();
-
-context_switch_reschedule:;
- /* Are there any threads to run */
- if (pthread_run = pthread_prio_queue_deq(pthread_current_prio_queue)) {
- /* restore floating point registers if necessary */
- if (!(pthread_run->attr.flags & PTHREAD_NOFLOAT)) {
- machdep_restore_float_state();
- }
- uthread_sigmask = &(pthread_run->sigmask);
- /* restore state of new current thread */
- machdep_restore_state();
- return;
- }
-
- /* Are there any threads at all */
- for (next = pthread_link_list; next; next = next->pll) {
- if ((next->state != PS_UNALLOCED) && (next->state != PS_DEAD)) {
- sigset_t sig_to_block, oset;
-
- sigfillset(&sig_to_block);
-
- /*
- * Check sig_to_process before calling fd_kern_wait, to handle
- * things like zero timeouts to select() which would register
- * a signal with the sig_handler_fake() call.
- *
- * This case should ignore SIGVTALRM
- */
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
- signum_to_process[SIGVTALRM] = 0;
- if (sig_to_process) {
- /* Process interrupts */
- /*
- * XXX pthread_run should not be set!
- * Places where it dumps core should be fixed to
- * check for the existance of pthread_run --proven
- */
- sig_handler(0);
- } else {
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
- /*
- * Do a wait, timeout is set to a hour unless we get an
- * intr. before the select in wich case it polls.
- */
- fd_kern_wait();
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
- /* Check for interrupts, but ignore SIGVTALR */
- signum_to_process[SIGVTALRM] = 0;
- if (sig_to_process) {
- /* Process interrupts */
- sig_handler(0);
- }
- }
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
- goto context_switch_reschedule;
- }
- }
-
- /* There are no threads alive. */
- pthread_run = last;
- exit(0);
-}
-
-#if !defined(HAVE_SYSCALL_SIGSUSPEND) && defined(HAVE_SYSCALL_SIGPAUSE)
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
-int machdep_sys_sigsuspend(sigset_t * set)
-{
- return(machdep_sys_sigpause(* set));
-}
-
-#endif
-
-/* ==========================================================================
- * sig_handler_pause()
- *
- * Wait until a signal is sent to the process.
- */
-void sig_handler_pause()
-{
- sigset_t sig_to_block, sig_to_pause, oset;
-
- sigfillset(&sig_to_block);
- sigemptyset(&sig_to_pause);
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
-/* if (!(SIG_ANY(sig_to_process))) { */
- if (!sig_to_process) {
- machdep_sys_sigsuspend(&sig_to_pause);
- }
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-}
-
-/* ==========================================================================
- * context_switch_done()
- *
- * This routine does all the things that are necessary after a context_switch()
- * calls the machdep_restore_state(). DO NOT put this in the context_switch()
- * routine because sometimes the machdep_restore_state() doesn't return
- * to context_switch() but instead ends up in machdep_thread_start() or
- * some such routine, which will need to call this routine and
- * sig_check_and_resume().
- */
-void context_switch_done()
-{
- /* sigdelset((sigset_t *)&sig_to_process, SIGVTALRM); */
- signum_to_process[SIGVTALRM] = 0;
- set_thread_timer();
-}
-
-/* ==========================================================================
- * set_thread_timer()
- *
- * Assums kernel is locked.
- */
-static void set_thread_timer()
-{
- static int last_sched_attr = SCHED_RR;
-
- switch (pthread_run->attr.schedparam_policy) {
- case SCHED_RR:
- machdep_set_thread_timer(&(pthread_run->machdep_data));
- break;
- case SCHED_FIFO:
- if (last_sched_attr != SCHED_FIFO) {
- machdep_unset_thread_timer(NULL);
- }
- break;
- case SCHED_IO:
- if ((last_sched_attr != SCHED_IO) && (!sig_count)) {
- machdep_set_thread_timer(&(pthread_run->machdep_data));
- }
- break;
- default:
- machdep_set_thread_timer(&(pthread_run->machdep_data));
- break;
- }
- last_sched_attr = pthread_run->attr.schedparam_policy;
-}
-
-/* ==========================================================================
- * sigvtalrm()
- */
-static inline void sigvtalrm()
-{
- if (sig_count) {
- sigset_t sigall, oset;
-
- sig_count = 0;
-
- /* Unblock all signals */
- sigemptyset(&sigall);
- machdep_sys_sigprocmask(SIG_SETMASK, &sigall, &oset);
- }
- context_switch();
- context_switch_done();
-}
-
-/* ==========================================================================
- * sigdefault()
- */
-static inline void sigdefault(int sig)
-{
- int ret;
-
- ret = pthread_sig_register(sig);
- if (pthread_run && (ret > pthread_run->pthread_priority)) {
- sigvtalrm();
- }
-}
-
-/* ==========================================================================
- * sig_handler_switch()
- */
-static inline void sig_handler_switch(int sig)
-{
- int ret;
-
- switch(sig) {
- case 0:
- break;
- case SIGVTALRM:
- sigvtalrm();
- break;
- case SIGALRM:
-/* sigdelset((sigset_t *)&sig_to_process, SIGALRM); */
- signum_to_process[SIGALRM] = 0;
- switch (ret = sleep_wakeup()) {
- default:
- if (pthread_run && (ret > pthread_run->pthread_priority)) {
- sigvtalrm();
- }
- case 0:
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
- /* There is a timing window that gets
- * here when no threads are on the
- * sleep queue. This is a quick fix.
- * The real problem is possibly related
- * to heavy use of condition variables
- * with time outs.
- * (mevans)
- *sigdefault(sig);
- */
- break;
- }
- break;
- case SIGCHLD:
-/* sigdelset((sigset_t *)&sig_to_process, SIGCHLD); */
- signum_to_process[SIGCHLD] = 0;
- switch (ret = wait_wakeup()) {
- default:
- if (pthread_run && (ret > pthread_run->pthread_priority)) {
- sigvtalrm();
- }
- case 0:
- break;
- case NOTOK:
- /* Do the registered action, no threads were waiting */
- sigdefault(sig);
- break;
- }
- break;
-
-#ifdef SIGINFO
- case SIGINFO:
- pthread_dump_info ();
- /* Then fall through, invoking the application's
- signal handler after printing our info out.
-
- I'm not convinced that this is right, but I'm not
- 100% convinced that it is wrong, and this is how
- Chris wants it done... */
-#endif
-
- default:
- /* Do the registered action */
- if (!sigismember(uthread_sigmask, sig)) {
- /*
- * If the signal isn't masked by the last running thread and
- * the signal behavior is default or ignore then we can
- * execute it immediatly. --proven
- */
- pthread_sig_default(sig);
- }
- signum_to_process[sig] = 0;
- sigdefault(sig);
- break;
- }
-
-}
-
-/* ==========================================================================
- * sig_handler()
- *
- * Process signal that just came in, plus any pending on the signal mask.
- * All of these must be resolved.
- *
- * Assumes the kernel is locked.
- */
-static void sig_handler(int sig)
-{
- if (pthread_kernel_lock != 1) {
- PANIC();
- }
-
- if (sig) {
- sig_handler_switch(sig);
- }
-
- while (sig_to_process) {
- for (sig_to_process = 0, sig = 1; sig <= SIGMAX; sig++) {
- if (signum_to_process[sig]) {
- sig_handler_switch(sig);
- }
- }
- }
-
-
-/*
- if (SIG_ANY(sig_to_process)) {
- for (sig = 1; sig <= SIGMAX; sig++) {
- if (sigismember((sigset_t *)&sig_to_process, sig)) {
- goto sig_handler_top;
- }
- }
- }
-*/
-}
-
-/* ==========================================================================
- * sig_handler_real()
- *
- * On a multi-processor this would need to use the test and set instruction
- * otherwise the following will work.
- */
-void sig_handler_real(int sig)
-{
- /*
- * Get around systems with BROKEN signal handlers.
- *
- * Some systems will reissue SIGCHLD if the handler explicitly
- * clear the signal pending by either doing a wait() or
- * ignoring the signal.
- */
-#if defined BROKEN_SIGNALS
- if (sig == SIGCHLD) {
- sigignore(SIGCHLD);
- signal(SIGCHLD, sig_handler_real);
- }
-#endif
-
- if (pthread_kernel_lock) {
- /* sigaddset((sigset_t *)&sig_to_process, sig); */
- __fd_kern_wait_timeout.tv_sec = 0;
- signum_to_process[sig] = 1;
- sig_to_process = 1;
- return;
- }
- pthread_kernel_lock++;
-
- sig_count++;
- sig_handler(sig);
-
- /* Handle any signals the current thread might have just gotten */
- if (pthread_run && pthread_run->sigcount) {
- pthread_sig_process();
- }
- pthread_kernel_lock--;
-}
-
-/* ==========================================================================
- * sig_handler_fake()
- */
-void sig_handler_fake(int sig)
-{
- if (pthread_kernel_lock) {
- /* sigaddset((sigset_t *)&sig_to_process, sig); */
- signum_to_process[sig] = 1;
- sig_to_process = 1;
- return;
- }
- pthread_kernel_lock++;
- sig_handler(sig);
- while (!(--pthread_kernel_lock)) {
- if (sig_to_process) {
- /* if (SIG_ANY(sig_to_process)) { */
- pthread_kernel_lock++;
- sig_handler(0);
- } else {
- break;
- }
- }
-}
-
-/* ==========================================================================
- * __pthread_signal_delete(int sig)
- *
- * Assumes the kernel is locked.
- */
-void __pthread_signal_delete(int sig)
-{
- signum_to_process[sig] = 0;
-}
-
-/* ==========================================================================
- * pthread_sched_other_resume()
- *
- * Check if thread to be resumed is of higher priority and if so
- * stop current thread and start new thread.
- */
-pthread_sched_other_resume(struct pthread * pthread)
-{
- pthread->state = PS_RUNNING;
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
-
- if (pthread->pthread_priority > pthread_run->pthread_priority) {
- if (pthread_kernel_lock == 1) {
- sig_handler(SIGVTALRM);
- }
- }
-
- __cleanup_after_resume();
-}
-
-/* ==========================================================================
- * pthread_resched_resume()
- *
- * This routine assumes that the caller is the current pthread, pthread_run
- * and that it has a lock the kernel thread and it wants to reschedule itself.
- */
-void pthread_resched_resume(enum pthread_state state)
-{
- pthread_run->state = state;
-
- /* Since we are about to block this thread, lets see if we are
- * at a cancel point and if we've been cancelled.
- * Avoid cancelling dead or unalloced threads.
- */
- if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
- TEST_PTHREAD_IS_CANCELLABLE(pthread_run) &&
- state != PS_DEAD && state != PS_UNALLOCED ) {
-
- /* Set this flag to avoid recursively calling pthread_exit */
- /* We have to set this flag here because we will unlock the
- * kernel prior to calling pthread_cancel_internal.
- */
- SET_PF_RUNNING_TO_CANCEL(pthread_run);
-
- pthread_run->old_state = state; /* unlock needs this data */
- pthread_sched_resume(); /* Unlock kernel before cancel */
- pthread_cancel_internal( 1 ); /* free locks and exit */
- }
-
- sig_handler(SIGVTALRM);
-
- __cleanup_after_resume();
-}
-
-/* ==========================================================================
- * pthread_sched_resume()
- */
-void pthread_sched_resume()
-{
- __cleanup_after_resume();
-}
-
-/*----------------------------------------------------------------------
- * Function: __cleanup_after_resume
- * Purpose: cleanup kernel locks after a resume
- * Args: void
- * Returns: void
- * Notes:
- *----------------------------------------------------------------------*/
-static void
-__cleanup_after_resume( void )
-{
- /* Only bother if we are truely unlocking the kernel */
- while (!(--pthread_kernel_lock)) {
- /* if (SIG_ANY(sig_to_process)) { */
- if (sig_to_process) {
- pthread_kernel_lock++;
- sig_handler(0);
- continue;
- }
- if (pthread_run && pthread_run->sigcount) {
- pthread_kernel_lock++;
- pthread_sig_process();
- continue;
- }
- break;
- }
-
- if( pthread_run == NULL )
- return; /* Must be during init processing */
-
- /* Test for cancel that should be handled now */
-
- if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
- TEST_PTHREAD_IS_CANCELLABLE(pthread_run) ) {
- /* Kernel is already unlocked */
- pthread_cancel_internal( 1 ); /* free locks and exit */
- }
-}
-
-/* ==========================================================================
- * pthread_sched_prevent()
- */
-void pthread_sched_prevent(void)
-{
- pthread_kernel_lock++;
-}
-
-/* ==========================================================================
- * sig_init()
- *
- * SIGVTALRM (NOT POSIX) needed for thread timeslice timeouts.
- * Since it's not POSIX I will replace it with a
- * virtual timer for threads.
- * SIGALRM (IS POSIX) so some special handling will be
- * necessary to fake SIGALRM signals
- */
-#ifndef SIGINFO
-#define SIGINFO 0
-#endif
-void sig_init(void)
-{
- static const int signum_to_initialize[] =
- { SIGCHLD, SIGALRM, SIGVTALRM, SIGINFO, 0 };
- static const int signum_to_ignore[] = { SIGKILL, SIGSTOP, 0 };
- int i, j;
-
-#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION)
- struct sigaction act;
-
- act.sa_handler = sig_handler_real;
- sigemptyset(&(act.sa_mask));
- act.sa_flags = 0;
-#endif
-
- /* Initialize the important signals */
- for (i = 0; signum_to_initialize[i]; i++) {
-
-#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION)
- if (sigaction(signum_to_initialize[i], &act, NULL)) {
-#else
- if (signal(signum_to_initialize[i], sig_handler_real)) {
-#endif
- PANIC();
- }
- }
-
- /* Initialize the rest of the signals */
- for (j = 1; j < SIGMAX; j++) {
- for (i = 0; signum_to_initialize[i]; i++) {
- if (signum_to_initialize[i] == j) {
- goto sig_next;
- }
- }
- /* Because Solaris 2.4 can't deal -- proven */
- for (i = 0; signum_to_ignore[i]; i++) {
- if (signum_to_ignore[i] == j) {
- goto sig_next;
- }
- }
- pthread_signal(j, SIG_DFL);
-
-#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION)
- sigaction(j, &act, NULL);
-#else
- signal(j, sig_handler_real);
-#endif
-
- sig_next:;
- }
-
-#if defined BROKEN_SIGNALS
- signal(SIGCHLD, sig_handler_real);
-#endif
-
-}
-
diff --git a/mit-pthreads/pthreads/sleep.c b/mit-pthreads/pthreads/sleep.c
deleted file mode 100644
index 1c13dd2eb1d..00000000000
--- a/mit-pthreads/pthreads/sleep.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/* ==== sleep.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the appropriate sleep routines.
- *
- * 1.00 93/12/28 proven
- * -Started coding this file.
- *
- * 1.36 94/06/04 proven
- * -Use new timer structure pthread_timer, that uses seconds
- * -nano seconds. Rewrite all routines completely.
- *
- * 1.38 94/06/13 proven
- * -switch pthread_timer to timespec
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/compat.h>
-
-struct pthread * pthread_sleep = NULL;
-
-/* ==========================================================================
- * sleep_compare_time()
- */
-/* static inline int sleep_compare_time(struct timespec * time1,
- struct timespec * time2) */
-static int sleep_compare_time(struct timespec * time1, struct timespec * time2)
-{
- if ((time1->tv_sec < time2->tv_sec) ||
- ((time1->tv_sec == time2->tv_sec) && (time1->tv_nsec < time2->tv_nsec))) {
- return(-1);
- }
- if ((time1->tv_sec == time2->tv_sec) && (time1->tv_nsec == time2->tv_nsec)){
- return(0);
- }
- return(1);
-}
-
-/* ==========================================================================
- * machdep_stop_timer()
- *
- * Returns the time left on the timer.
- */
-static struct itimerval timestop = { { 0, 0 }, { 0, 0 } };
-
-void machdep_stop_timer(struct timespec *current)
-{
- struct itimerval timenow;
-
- setitimer(ITIMER_REAL, & timestop, & timenow);
- __pthread_signal_delete(SIGALRM);
- if (current) {
- current->tv_nsec = timenow.it_value.tv_usec * 1000;
- current->tv_sec = timenow.it_value.tv_sec;
- }
-}
-
-/* ==========================================================================
- * machdep_start_timer()
- */
-int machdep_start_timer(struct timespec *current, struct timespec *wakeup)
-{
- struct itimerval timeout;
-
- timeout.it_value.tv_usec = (wakeup->tv_nsec - current->tv_nsec) / 1000;
- timeout.it_value.tv_sec = wakeup->tv_sec - current->tv_sec;
- timeout.it_interval.tv_usec = 0;
- timeout.it_interval.tv_sec = 0;
- if (timeout.it_value.tv_usec < 0) {
- timeout.it_value.tv_usec += 1000000;
- timeout.it_value.tv_sec--;
- }
-
- if (((long) timeout.it_value.tv_sec >= 0) &&
- ((timeout.it_value.tv_usec) || (timeout.it_value.tv_sec))) {
- if (setitimer(ITIMER_REAL, & timeout, NULL) < 0)
- {
- fprintf(stderr,"Got error %d from setitimer with:\n\
- wakeup: tv_sec: %ld tv_nsec: %ld\n\
- current: tv_sec: %ld tv_nsec: %ld\n\
- argument: tv_sec: %ld tv_usec: %ld\n",
- errno,
- wakeup->tv_sec, wakeup->tv_nsec,
- current->tv_sec, current->tv_nsec,
- timeout.it_value.tv_sec, timeout.it_value.tv_usec);
- PANIC();
- }
- } else {
- /*
- * There is no time on the timer.
- * This shouldn't happen,
- * but isn't fatal.
- */
- sig_handler_fake(SIGALRM);
- }
- return(OK);
-}
-
-/* ==========================================================================
- * sleep_schedule()
- *
- * Assumes that the current thread is the thread to be scheduled
- * and that the kthread is already locked.
- */
-void sleep_schedule(struct timespec *current_time, struct timespec *new_time)
-{
- struct pthread * pthread_sleep_current, * pthread_sleep_prev;
-
- /* Record the new time as the current thread's wakeup time. */
- pthread_run->wakeup_time = *new_time;
-
- /* any threads? */
- if (pthread_sleep_current = pthread_sleep) {
- if (sleep_compare_time(&(pthread_sleep_current->wakeup_time),
- new_time) <= 0) {
- /* Don't need to restart timer */
- while (pthread_sleep_current->sll) {
-
- pthread_sleep_prev = pthread_sleep_current;
- pthread_sleep_current = pthread_sleep_current->sll;
-
- if (sleep_compare_time(&(pthread_sleep_current->wakeup_time),
- new_time) > 0) {
- pthread_run->sll = pthread_sleep_current;
- pthread_sleep_prev->sll = pthread_run;
- return;
- }
- }
-
- /* No more threads in queue, attach pthread_run to end of list */
- pthread_sleep_current->sll = pthread_run;
- pthread_run->sll = NULL;
-
- } else {
- /* Start timer and enqueue thread */
- machdep_start_timer(current_time, new_time);
- pthread_run->sll = pthread_sleep_current;
- pthread_sleep = pthread_run;
- }
- } else {
- /* Start timer and enqueue thread */
- machdep_start_timer(current_time, new_time);
- pthread_sleep = pthread_run;
- pthread_run->sll = NULL;
- }
-}
-
-/* ==========================================================================
- * sleep_wakeup()
- *
- * This routine is called by the interrupt handler, which has already
- * locked the current kthread. Since all threads on this list are owned
- * by the current kthread, rescheduling won't be a problem.
- */
-int sleep_spurious_wakeup = 0;
-int sleep_wakeup()
-{
- struct pthread *pthread_sleep_next;
- struct timespec current_time;
- int ret = 0;
-
- if (pthread_sleep == NULL) {
- return(NOTOK);
- }
-
- machdep_gettimeofday(&current_time);
- if (sleep_compare_time(&(pthread_sleep->wakeup_time), &current_time) > 0) {
- machdep_start_timer(&current_time, &(pthread_sleep->wakeup_time));
- sleep_spurious_wakeup++;
- return(OK);
- }
-
- do {
- if (pthread_sleep->pthread_priority > ret) {
- ret = pthread_sleep->pthread_priority;
- }
-
- /*
- * Clean up removed thread and start it running again.
- *
- * Note: It is VERY important to remove the thread form the
- * current queue before putting it on the run queue.
- * Both queues use pthread_sleep->next, and the thread that points
- * to pthread_sleep should point to pthread_sleep->next then
- * pthread_sleep should be put on the run queue.
- */
- if ((SET_PF_DONE_EVENT(pthread_sleep)) == OK) {
- if (pthread_sleep->queue)
- pthread_queue_remove(pthread_sleep->queue, pthread_sleep);
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread_sleep);
- pthread_sleep->state = PS_RUNNING;
- }
-
- pthread_sleep_next = pthread_sleep->sll;
- pthread_sleep->sll = NULL;
-
- if ((pthread_sleep = pthread_sleep_next) == NULL) {
- /* No more threads on sleep queue */
- return(ret);
- }
- } while (sleep_compare_time(&(pthread_sleep->wakeup_time), &(current_time)) <= 0);
-
- /* Start timer for next time interval */
- machdep_start_timer(&current_time, &(pthread_sleep->wakeup_time));
- return(ret);
-}
-
-
-/* ==========================================================================
- * __sleep()
- */
-void __sleep(struct timespec * time_to_sleep)
-{
- struct pthread *pthread_sleep_prev;
- struct timespec current_time, wakeup_time;
-
- pthread_sched_prevent();
-
- /* Get real time */
- machdep_gettimeofday(&current_time);
- wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec;
- wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec;
-
- sleep_schedule(&current_time, &wakeup_time);
-
- /* Reschedule thread */
- SET_PF_WAIT_EVENT(pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SLEEP_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- /* Return actual time slept */
- time_to_sleep->tv_sec = pthread_run->wakeup_time.tv_sec;
- time_to_sleep->tv_nsec = pthread_run->wakeup_time.tv_nsec;
-}
-
-/* ==========================================================================
- * pthread_nanosleep()
- */
-unsigned int pthread_nanosleep(unsigned int nseconds)
-{
- struct timespec time_to_sleep;
-
- if (nseconds) {
- time_to_sleep.tv_nsec = nseconds;
- time_to_sleep.tv_sec = 0;
- __sleep(&time_to_sleep);
- nseconds = time_to_sleep.tv_nsec;
- }
- return(nseconds);
-}
-
-/* ==========================================================================
- * usleep()
- */
-void usleep(unsigned int useconds)
-{
- struct timespec time_to_sleep;
-
- if (useconds) {
- time_to_sleep.tv_nsec = (useconds % 1000000) * 1000;
- time_to_sleep.tv_sec = useconds / 1000000;
- __sleep(&time_to_sleep);
- }
-}
-
-/* ==========================================================================
- * sleep()
- */
-unsigned int sleep(unsigned int seconds)
-{
- struct timespec time_to_sleep;
-
- if (seconds) {
- time_to_sleep.tv_sec = seconds;
- time_to_sleep.tv_nsec = 0;
- __sleep(&time_to_sleep);
- seconds = time_to_sleep.tv_sec;
- }
- return(seconds);
-}
-
-/* ==========================================================================
- * sleep_cancel()
- *
- * Cannot be called while kernel is locked.
- * Does not wake sleeping thread up, just remove it from the sleep queue.
- */
-int sleep_cancel(struct pthread * pthread)
-{
- struct timespec current_time, delta_time;
- struct pthread * pthread_last;
- int rval = NOTOK;
-
- /* Lock sleep queue, Note this may be on a different kthread queue */
- pthread_sched_prevent();
-
- if (pthread_sleep) {
- if (pthread == pthread_sleep) {
- rval = OK;
- machdep_stop_timer(&delta_time);
- if (pthread_sleep = pthread_sleep->sll) {
- current_time.tv_sec = delta_time.tv_sec;
- current_time.tv_nsec = delta_time.tv_nsec;
- current_time.tv_sec += pthread_sleep->wakeup_time.tv_sec;
- current_time.tv_nsec += pthread_sleep->wakeup_time.tv_nsec;
- while (current_time.tv_nsec > 1000000000) {
- current_time.tv_nsec -= 1000000000;
- current_time.tv_sec++;
- }
- machdep_start_timer(&(current_time),
- &(pthread_sleep->wakeup_time));
- }
- } else {
- for (pthread_last = pthread_sleep; pthread_last;
- pthread_last = pthread_last->sll) {
- if (pthread_last->sll == pthread) {
- pthread_last->sll = pthread->sll;
- rval = OK;
- break;
- }
- }
- }
- }
-
- pthread_sched_resume();
- pthread->sll = NULL;
- return(rval);
-}
diff --git a/mit-pthreads/pthreads/specific.c b/mit-pthreads/pthreads/specific.c
deleted file mode 100644
index 898f9b0cd1b..00000000000
--- a/mit-pthreads/pthreads/specific.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* ==== specific.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread thread specific data management.
- *
- * 1.20 94/03/30 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-static struct pthread_key key_table[PTHREAD_DATAKEYS_MAX];
-static pthread_mutex_t key_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/* ==========================================================================
- * pthread_key_create()
- */
-int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
-{
- pthread_mutex_lock(&key_mutex);
- for ((*key) = 0; (*key) < PTHREAD_DATAKEYS_MAX; (*key)++) {
- if (key_table[(*key)].count == 0) {
- key_table[(*key)].count++;
- key_table[(*key)].destructor = destructor;
- pthread_mutex_init(&(key_table[(*key)].mutex), NULL);
- pthread_mutex_unlock(&key_mutex);
- return(OK);
- }
- }
- pthread_mutex_unlock(&key_mutex);
- return(EAGAIN);
-}
-
-/* ==========================================================================
- * pthread_key_delete()
- */
-int pthread_key_delete(pthread_key_t key)
-{
- int ret;
-
- if (key < PTHREAD_DATAKEYS_MAX) {
- pthread_mutex_lock(&(key_table[key].mutex));
- switch (key_table[key].count) {
- case 1:
- pthread_mutex_destroy(&(key_table[key].mutex));
- key_table[key].destructor = NULL;
- key_table[key].count = 0;
- case 0:
- ret = OK;
- break;
- default:
- ret = EBUSY;
- }
- pthread_mutex_unlock(&(key_table[key].mutex));
- } else {
- ret = EINVAL;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_cleanupspecific()
- */
-void pthread_cleanupspecific(void)
-{
- void * data;
- int key;
- int itr;
-
- pthread_mutex_lock(&key_mutex);
- for (itr = 0; itr < _POSIX_THREAD_DESTRUTOR_ITERATIONS; itr++) {
- for (key = 0; key < PTHREAD_DATAKEYS_MAX; key++) {
- if (pthread_run->specific_data_count) {
- if (pthread_run->specific_data[key]) {
- data = (void *)pthread_run->specific_data[key];
- pthread_run->specific_data[key] = NULL;
- pthread_run->specific_data_count--;
- if (key_table[key].destructor) {
- pthread_mutex_unlock(&key_mutex);
- key_table[key].destructor(data);
- pthread_mutex_lock(&key_mutex);
- }
- key_table[key].count--;
- }
- } else {
- free(pthread_run->specific_data);
- pthread_mutex_unlock(&key_mutex);
- return;
- }
- }
- }
- free(pthread_run->specific_data);
- pthread_mutex_unlock(&key_mutex);
-}
-
-static inline const void ** pthread_key_allocate_data(void)
-{
- const void ** new_data;
- if(new_data = (const void**)malloc(sizeof(void *) * PTHREAD_DATAKEYS_MAX)) {
- memset((void *)new_data, 0, sizeof(void *) * PTHREAD_DATAKEYS_MAX);
- }
- return(new_data);
-}
-
-/* ==========================================================================
- * pthread_setspecific()
- */
-int pthread_setspecific(pthread_key_t key, const void * value)
-{
- int ret;
-
- if ((pthread_run->specific_data) ||
- (pthread_run->specific_data = pthread_key_allocate_data())) {
- if ((key < PTHREAD_DATAKEYS_MAX) && (key_table)) {
- pthread_mutex_lock(&(key_table[key].mutex));
- if (key_table[key].count) {
- if (pthread_run->specific_data[key] == NULL) {
- if (value != NULL) {
- pthread_run->specific_data_count++;
- key_table[key].count++;
- }
- } else {
- if (value == NULL) {
- pthread_run->specific_data_count--;
- key_table[key].count--;
- }
- }
- pthread_run->specific_data[key] = value;
- ret = OK;
- } else {
- ret = EINVAL;
- }
- pthread_mutex_unlock(&(key_table[key].mutex));
- } else {
- ret = EINVAL;
- }
- } else {
- ret = ENOMEM;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_getspecific()
- */
-void * pthread_getspecific(pthread_key_t key)
-{
- void *ret;
-
- if ((pthread_run->specific_data) && (key < PTHREAD_DATAKEYS_MAX)
- && (key_table)) {
- pthread_mutex_lock(&(key_table[key].mutex));
- if (key_table[key].count) {
- ret = (void *)pthread_run->specific_data[key];
- } else {
- ret = NULL;
- }
- pthread_mutex_unlock(&(key_table[key].mutex));
- } else {
- ret = NULL;
- }
- return(ret);
-}
diff --git a/mit-pthreads/pthreads/stat.c b/mit-pthreads/pthreads/stat.c
deleted file mode 100644
index f18b7c6bd24..00000000000
--- a/mit-pthreads/pthreads/stat.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* ==== stat.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the syscalls dealing with fds.
- *
- * 1.00 93/05/27 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-struct stat;
-struct statfs;
-
-/* ==========================================================================
- * fstat()
- *
- * Might want to indirect this.
- */
-int fstat(int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * stat()
- */
-int stat(const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * lstat()
- */
-int lstat(const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- return(ret);
-
-}
-
-#ifdef HAVE_SYSCALL_FSTATFS
-/* ==========================================================================
- * fstatfs()
- *
- * Might want to indirect this.
- */
-int fstatfs(int fd, struct statfs *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_fstatfs(fd_table[fd]->fd.i, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-#endif
diff --git a/mit-pthreads/pthreads/wait.c b/mit-pthreads/pthreads/wait.c
deleted file mode 100644
index 9f0418ca8a1..00000000000
--- a/mit-pthreads/pthreads/wait.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* ==== wait.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the appropriate wait routines.
- *
- * 1.38 94/06/13 proven
- * -Started coding this file.
- *
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <pthread/posix.h>
-#include <sys/compat.h>
-#include <sys/wait.h>
-
-/* This is an UGLY hack to get wait to compile, something better is needed. */
-/* #define _POSIX_SOURCE
-#undef _POSIX_SOURCE
-*/
-
-struct pthread_queue wait_queue = { NULL, NULL, NULL };
-extern void sig_handler_real();
-
-/* ==========================================================================
- * wait_wakeup()
- *
- * This routine is called by the interrupt handler which has locked
- * the current kthread semaphore. Since only threads owned by the
- * current kthread can be queue here, no additional locks are necessary.
- */
-int wait_wakeup()
-{
- struct pthread *pthread;
- int ret = 0;
-
- if (pthread = pthread_queue_deq(& wait_queue)) {
- /* Wakeup all threads, and enqueue them on the run queue */
- do {
- pthread->state = PS_RUNNING;
- if (pthread->pthread_priority > ret) {
- ret = pthread->pthread_priority;
- }
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- } while (pthread = pthread_queue_deq(&wait_queue));
- return(ret);
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * For the wait calls, it is important that the current kthread is locked
- * before the apropriate wait syscall is preformed. This way we ensure
- * that there is never a case where a thread is waiting for a child but
- * missed the interrupt for that child.
- * Patched by William S. Lear 1997-02-02
- */
-
-/* ==========================================================================
- * waitpid()
- */
-pid_t waitpid(pid_t pid, int *status, int options)
-{
- pid_t ret;
-
- pthread_sched_prevent();
- ret = machdep_sys_waitpid(pid, status, options | WNOHANG);
- /* If we are not doing nohang, try again, else return immediately */
- if (!(options & WNOHANG)) {
- while (ret == OK) {
- /* Enqueue thread on wait queue */
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
-
- ret = machdep_sys_waitpid(pid, status, options | WNOHANG);
- }
- }
- pthread_sched_resume();
- return(ret);
-}
-
-/* ==========================================================================
- * wait3()
- * Patched by Monty 1997-02-02
- */
-pid_t wait3(__WAIT_STATUS status, int options, void * rusage)
-{
- semaphore * lock;
- pid_t ret;
-
- pthread_sched_prevent();
- ret = machdep_sys_wait3(status, options | WNOHANG, rusage);
- /* If we are not doing nohang, try again, else return immediately */
- if (!(options & WNOHANG)) {
- while (ret == OK) {
- /* Enqueue thread on wait queue */
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
-
- machdep_sys_wait3(status, options | WNOHANG, rusage);
- }
- }
- pthread_sched_resume();
- return(ret);
-}
-
-/* ==========================================================================
- * wait()
- */
-pid_t wait(__WAIT_STATUS status)
-{
- return(waitpid((pid_t)-1, (int *)status, 0));
-}
diff --git a/mit-pthreads/pthreads/wrapper.c b/mit-pthreads/pthreads/wrapper.c
deleted file mode 100644
index 6e3f4478fcf..00000000000
--- a/mit-pthreads/pthreads/wrapper.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* ==== wrapper.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Wrapper functions for syscalls that only need errno redirected
- *
- * 1.4x 94/07/23 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pthread/posix.h>
-
-/* ==========================================================================
- * link()
- */
-int link(const char * name1, const char * name2)
-{
- int ret;
-
- if ((ret = machdep_sys_link(name1, name2)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * unlink()
- */
-int unlink(const char * path)
-{
- int ret;
-
- if ((ret = machdep_sys_unlink(path)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * chdir()
- */
-int chdir(const char * path)
-{
- int ret;
-
- if ((ret = machdep_sys_chdir(path)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * chmod()
- */
-int chmod(const char * path, mode_t mode)
-{
- int ret;
-
- if ((ret = machdep_sys_chmod(path, mode)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * chown()
- */
-int chown(const char * path, uid_t owner, gid_t group)
-{
- int ret;
-
- if ((ret = machdep_sys_chown(path, owner, group)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * rename()
- */
-int rename(const char * name1, const char * name2)
-{
- int ret;
-
- if ((ret = machdep_sys_rename(name1, name2)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-
-/* ==========================================================================
- * chroot()
- */
-
-#ifdef HAVE_SYSCALL_CHROOT
-int chroot(const char * name)
-{
- int ret;
-
- if ((ret = machdep_sys_chroot(name)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-#endif
diff --git a/mit-pthreads/pthreads/writev.c b/mit-pthreads/pthreads/writev.c
deleted file mode 100644
index 9823d5ad201..00000000000
--- a/mit-pthreads/pthreads/writev.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ==== writev.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Implementation of writev().
- *
- * 1.00 95/06/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-
-#ifndef HAVE_SYSCALL_WRITEV
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-
-/* ==========================================================================
- * machdep_sys_writev()
- *
- * modified from the GNU C Library posix/writev.c
- */
-int machdep_sys_writev(int fd, struct iovec * vector, int count)
-{
- size_t bytes, i;
- char *buffer;
- int ret;
-
- /* Find the total number of bytes to be written. */
- for (bytes = 0, i = 0; i < count; ++i)
- bytes += vector[i].iov_len;
-
- if (bytes) {
- /*
- * Allocate a temporary buffer to hold the data.
- * Don't use alloca because threads tend to have smaller stacks.
- */
- if ((buffer = (char *)malloc(bytes)) == NULL) {
- return(-ENOMEM);
- }
- /* Copy the data from memory specified by VECTOR to BUFFER */
- for (ret = 0, i = 0; i < count; ++i) {
- memcpy(buffer + ret, vector[i].iov_base, vector[i].iov_len);
- ret += vector[i].iov_len;
- }
- } else {
- buffer = NULL;
- }
-
- ret = (int)machdep_sys_write(fd, buffer, bytes);
- if (buffer)
- free(buffer);
- return(ret);
-}
-
-#endif
diff --git a/mit-pthreads/scripts/GNUmakefile.inc b/mit-pthreads/scripts/GNUmakefile.inc
deleted file mode 100755
index 6309f28ca55..00000000000
--- a/mit-pthreads/scripts/GNUmakefile.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-VPATH := $(VPATH):${srcdir}/scripts
-SCRIPTS= pgcc pg++
-
-abspath := $(shell pwd)
-
-all-bin: $(SCRIPTS)
-
-pgcc: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(abspath)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!gcc!g' \
- < $(srcdir)/scripts/pgcc.sh > pgcc.new
- chmod a+x pgcc.new
- mv -f pgcc.new pgcc
-
-pg++: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(abspath)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!g++!g' \
- < $(srcdir)/scripts/pgcc.sh > pg++.new
- chmod a+x pg++.new
- mv -f pg++.new pg++
diff --git a/mit-pthreads/scripts/Makefile.inc b/mit-pthreads/scripts/Makefile.inc
deleted file mode 100644
index 441f6b51d29..00000000000
--- a/mit-pthreads/scripts/Makefile.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-.PATH : ${srcdir}/scripts
-SCRIPTS= pgcc pg++
-
-abspath != pwd
-
-all-bin: $(SCRIPTS)
-
-#
-# Objects go in the obj directory for both BSD and GNU make but these
-# scripts get put in the obj dir for BSD and the root dir for GNU.
-#
-pgcc: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(.CURDIR)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!gcc!g' \
- < $(srcdir)/scripts/pgcc.sh > pgcc.new
- chmod a+x pgcc.new
- mv -f pgcc.new pgcc
- ln -fs obj/pgcc ../pgcc
-
-pg++: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(.CURDIR)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!g++!g' \
- < $(srcdir)/scripts/pgcc.sh > pg++.new
- chmod a+x pg++.new
- mv -f pg++.new pg++
- ln -fs obj/pg++ ../pg++
diff --git a/mit-pthreads/scripts/pgcc.sh b/mit-pthreads/scripts/pgcc.sh
deleted file mode 100755
index 6bd6cbeccdb..00000000000
--- a/mit-pthreads/scripts/pgcc.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-
-pthreads_root=EXEC_PREFIX
-build_root=BUILD_PREFIX
-src_root=SRC_PREFIX
-
-include_dir='-I$pthreads_root/include'
-lib_dir='-L$pthreads_root/lib'
-libs='-lpthread -lm -lgcc -lpthread'
-
-# Might be a good idea to also provide a way to override pthreads_root
-# so that we can use this script in the build tree, before installation.
-if arg="$1" ; then
- case $arg in
- -notinstalled)
- include_dir='-I$build_root/include -I$src_root/include'
- lib_dir='-L$build_root/obj'
- shift
- ;;
- esac
-fi
-
-for arg in "$@" ; do
- case $arg in
- -nostdinc) include_dir= ;;
- -nostdlib | -c) libs= ;;
- esac
-done
-
-# Include the -L option in any case, just in case the user provided the
-# names of some libraries we've built threaded versions of.
-eval exec COMPILER '"$@"' $include_dir $lib_dir $libs
diff --git a/mit-pthreads/stdio/GNUmakefile.inc b/mit-pthreads/stdio/GNUmakefile.inc
deleted file mode 100755
index 7cb1371661d..00000000000
--- a/mit-pthreads/stdio/GNUmakefile.inc
+++ /dev/null
@@ -1,26 +0,0 @@
-
-# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91
-# $Id$
-
-# Thread safe stdio sources
-VPATH:= ${VPATH}:${srcdir}/stdio
-
-SRCS:= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
- fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
- fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
- fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
- getc.c getchar.c gets.c getw.c makebuf.c perror.c putc.c \
- putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \
- setbuf.c setbuffer.c setvbuf.c sscanf.c \
- stdio.c ungetc.c \
- vfscanf.c vscanf.c vsscanf.c \
- wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \
- getchar_unlocked.c strerror.c wbuf.c xprintf.c $(SRCS)
-
-# tempnam.c tmpnam.c tmpfile.c
-#
-# SRCS:= sys_errlist.c $(SRCS)
-# sys_errlist.c: make_errlist
-# (FOO=`pwd`; cd ${srcdir}/stdio/make_errlist; \
-# $(MAKE) CC=$(CC) srcdir=${srcdir} objdir=$${FOO})
-# `pwd`/make_errlist;
diff --git a/mit-pthreads/stdio/Makefile.inc b/mit-pthreads/stdio/Makefile.inc
deleted file mode 100644
index 10c598c328f..00000000000
--- a/mit-pthreads/stdio/Makefile.inc
+++ /dev/null
@@ -1,20 +0,0 @@
-
-# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91
-# $Id$
-
-# Thread safe stdio sources
-.PATH: ${srcdir}/stdio
-
-# SRCS+= tempnam.c tmpfile.c tmpnam.c
-
-SRCS+= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
- fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
- fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
- fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
- getc.c getchar.c gets.c getw.c makebuf.c perror.c putc.c \
- putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \
- setbuf.c setbuffer.c setvbuf.c sscanf.c \
- stdio.c ungetc.c \
- vfscanf.c vscanf.c vsscanf.c \
- wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \
- getchar_unlocked.c strerror.c wbuf.c xprintf.c
diff --git a/mit-pthreads/stdio/README b/mit-pthreads/stdio/README
deleted file mode 100755
index 8e4c07909e9..00000000000
--- a/mit-pthreads/stdio/README
+++ /dev/null
@@ -1,41 +0,0 @@
-Copyright (c) 1993, 1994 Chris Provenzano. All rights reserved.
-
-This is a threadsafe stdio based on the BSD stdio written by Chris Torek.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-INCLUDE FILES AND PORTING
-To continue to make this package portable, some basic rules on includes
-files must be followed.
-
-pthread.h should be included first (if it is to be included).
-stdio.h should be included.
-
-INTERNAL LOCKING
-1. All functions that can be called by the user must have flockfile() at the
- begining and a funlockfile() at the end. The routine flockfile() is a
- counting mutex, The thread that owns the lock can call flockfile() as
- many times as it wants, but must call an equal number of funlockfile()
- before the lock will be released.
-2. All functions starting with __ shouldn't need addtional locking.
-3. Anything that writes the variable __sglue should lock __sfp_mutex,
- check __sfp_state, and do a condion wait if it is set.
-4. Anything that checks fp->_flag for valididity should also lock
- __sfp_mutex.
-5. Anything that reads the variable __sglue should lock __sfp_mutex, increment
- __sfp_state, and then unlock the mutex. At function return it should
- lock the mutex again decrement __sfp_state and check if zero. If so
- do a cond_signal, and unlock the mutex.
-6. The functions fopen, fdopen, and freopen are the only functions that
- will change a fp->_file
-7. fdopen and fopen both allocate the next fp by locking __sfp_mutex
- checking fp->_flags and then setting it if free.
-8. freopen tries to preserve fp->_file. It sets __sfp_mutex, then it
- tries to lock fp->_file and close it.
-9. __sinit is done with a pthread_once routine.
-
-
-
-Things to do.
-
-Fix printf so it uses the ininf function.
diff --git a/mit-pthreads/stdio/clrerr.c b/mit-pthreads/stdio/clrerr.c
deleted file mode 100644
index e809cfb8efd..00000000000
--- a/mit-pthreads/stdio/clrerr.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)clrerr.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-void clearerr(FILE *fp)
-{
- flockfile(fp);
- fp->_flags &= ~(__SERR|__SEOF);
- funlockfile(fp);
-}
diff --git a/mit-pthreads/stdio/fclose.c b/mit-pthreads/stdio/fclose.c
deleted file mode 100644
index c5db0808f6a..00000000000
--- a/mit-pthreads/stdio/fclose.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fclose.c 5.2 (Berkeley) 2/1/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/* Do not reset the fd */
-fclose(fp)
- register FILE *fp;
-{
- register int r;
-
- if (fp->_flags) {
- flockfile(fp);
- r = fp->_flags & __SWR ? __sflush(fp) : 0;
- if (fp->_flags & __SMBF)
- free((char *)fp->_bf._base);
- if (HASUB(fp))
- FREEUB(fp);
- if (HASLB(fp))
- FREELB(fp);
- if (__sclose(fp) < 0)
- r = EOF;
-/* funlockfile(fp); Don't unlock. The close() already has. */
- fp->_file = -1;
- fp->_flags = 0; /* release this FILE for reuse, DO THIS LAST */
- return(r);
- }
- errno = EBADF;
- return(EOF);
-}
diff --git a/mit-pthreads/stdio/fdopen.c b/mit-pthreads/stdio/fdopen.c
deleted file mode 100644
index 4c006f24c7c..00000000000
--- a/mit-pthreads/stdio/fdopen.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fdopen.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-FILE *fdopen(int fd, const char *mode)
-{
- register FILE *fp;
- int flags, oflags, fdflags, tmp;
-
- if ((flags = __sflags(mode, &oflags)) == 0)
- return (NULL);
-
- /* Make sure the mode the user wants is a subset of the actual mode. */
- if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
- return (NULL);
- tmp = fdflags & O_ACCMODE;
- if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
- errno = EINVAL;
- return (NULL);
- }
-
- __sinit ();
- pthread_mutex_lock(&__sfp_mutex);
- while (__sfp_state) {
- pthread_cond_wait(&__sfp_cond, &__sfp_mutex);
- }
-
- if (fp = __sfp()) {
- fp->_flags = flags;
-
- /*
- * If opened for appending, but underlying descriptor does not have
- * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
- * end before each write.
- */
- if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
- fp->_flags |= __SAPP;
- fp->_file = fd;
-
- }
- pthread_mutex_unlock(&__sfp_mutex);
- return (fp);
-}
diff --git a/mit-pthreads/stdio/feof.c b/mit-pthreads/stdio/feof.c
deleted file mode 100644
index 10946fee581..00000000000
--- a/mit-pthreads/stdio/feof.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)feof.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro feof.
- */
-#undef feof
-
-feof(fp)
- FILE *fp;
-{
- return (__sfeof(fp));
-}
diff --git a/mit-pthreads/stdio/ferror.c b/mit-pthreads/stdio/ferror.c
deleted file mode 100644
index b80ddab037e..00000000000
--- a/mit-pthreads/stdio/ferror.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)ferror.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro ferror.
- */
-#undef ferror
-
-ferror(fp)
- FILE *fp;
-{
- return (__sferror(fp));
-}
diff --git a/mit-pthreads/stdio/fflush.c b/mit-pthreads/stdio/fflush.c
deleted file mode 100644
index 766691045b5..00000000000
--- a/mit-pthreads/stdio/fflush.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fflush.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include "local.h"
-
-/* Flush a single file, or (if fp is NULL) all files. */
-fflush(fp)
- register FILE *fp;
-{
- int retval;
-
- if (fp == NULL)
- return (__swalk_sflush());
- flockfile(fp);
-
- if ((fp->_flags & (__SWR | __SRW)) == 0) {
- errno = EBADF;
- retval = EOF;
- } else {
- retval = __sflush(fp);
- }
- funlockfile(fp);
- return(retval);
-}
-
-__sflush(fp)
- register FILE *fp;
-{
- register unsigned char *p;
- register int n, t;
-
- t = fp->_flags;
- if ((t & __SWR) == 0)
- return (0);
-
- if ((p = fp->_bf._base) == NULL)
- return (0);
-
- n = fp->_p - p; /* write this much */
-
- /*
- * Set these immediately to avoid problems with longjmp and to allow
- * exchange buffering (via setvbuf) in user write function.
- */
- fp->_p = p;
- fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
-
- for (; n > 0; n -= t, p += t) {
- t = __swrite(fp, (char *)p, n);
- if (t <= 0) {
- fp->_flags |= __SERR;
- return (EOF);
- }
- }
- return (0);
-}
diff --git a/mit-pthreads/stdio/fgetc.c b/mit-pthreads/stdio/fgetc.c
deleted file mode 100644
index c5eb2ee5986..00000000000
--- a/mit-pthreads/stdio/fgetc.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgetc.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-fgetc(fp)
- FILE *fp;
-{
- int ret;
-
- flockfile(fp);
- ret = __sgetc(fp);
- funlockfile(fp);
- return(ret);
-}
-
-int __getc(FILE *_p)
-{
- int ret;
- flockfile(_p);
- ret = __sgetc(_p);
- funlockfile(_p);
- return(ret);
-}
-
diff --git a/mit-pthreads/stdio/fgetline.c b/mit-pthreads/stdio/fgetline.c
deleted file mode 100644
index 219660612f1..00000000000
--- a/mit-pthreads/stdio/fgetline.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgetline.c 5.2 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-
-/*
- * Expand the line buffer. Return -1 on error.
- * The `new size' does not account for a terminating '\0',
- * so we add 1 here.
- */
-__slbexpand(fp, newsize)
- FILE *fp;
- size_t newsize;
-{
- void *p;
-
- if (fp->_lb._size >= ++newsize)
- return (0);
- if ((p = realloc(fp->_lb._base, newsize)) == NULL)
- return (-1);
- fp->_lb._base = p;
- fp->_lb._size = newsize;
- return (0);
-}
-
-/*
- * Get an input line. The returned pointer often (but not always)
- * points into a stdio buffer. Fgetline smashes the newline (if any)
- * in the stdio buffer; callers must not use it on streams that
- * have `magic' setvbuf() games happening.
- */
-char *
-fgetline(fp, lenp)
- register FILE *fp;
- size_t *lenp;
-{
- register unsigned char *p;
- register size_t len;
- size_t off;
-
- flockfile(fp);
-
- /* make sure there is input */
- if (fp->_r <= 0 && __srefill(fp)) {
- if (lenp != NULL)
- *lenp = 0;
- funlockfile(fp);
- return (NULL);
- }
-
- /* look for a newline in the input */
- if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
- register char *ret;
-
- /*
- * Found one. Flag buffer as modified to keep
- * fseek from `optimising' a backward seek, since
- * the newline is about to be trashed. (We should
- * be able to get away with doing this only if
- * p is not pointing into an ungetc buffer, since
- * fseek discards ungetc data, but this is the
- * usual case anyway.)
- */
- ret = (char *)fp->_p;
- len = p - fp->_p;
- fp->_flags |= __SMOD;
- *p = 0;
- fp->_r -= len + 1;
- fp->_p = p + 1;
- if (lenp != NULL)
- *lenp = len;
- funlockfile(fp);
- return (ret);
- }
-
- /*
- * We have to copy the current buffered data to the line buffer.
- *
- * OPTIMISTIC is length that we (optimistically)
- * expect will accomodate the `rest' of the string,
- * on each trip through the loop below.
- */
-#define OPTIMISTIC 80
-
- for (len = fp->_r, off = 0;; len += fp->_r) {
- register size_t diff;
-
- /*
- * Make sure there is room for more bytes.
- * Copy data from file buffer to line buffer,
- * refill file and look for newline. The
- * loop stops only when we find a newline.
- */
- if (__slbexpand(fp, len + OPTIMISTIC))
- goto error;
- (void) memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
- len - off);
- off = len;
- if (__srefill(fp))
- break; /* EOF or error: return partial line */
- if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
- continue;
-
- /* got it: finish up the line (like code above) */
- fp->_flags |= __SMOD; /* soon */
- diff = p - fp->_p;
- len += diff;
- if (__slbexpand(fp, len))
- goto error;
- (void) memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, diff);
- fp->_r -= diff + 1;
- fp->_p = p + 1;
- break;
- }
- if (lenp != NULL)
- *lenp = len;
- fp->_lb._base[len] = 0;
-
- funlockfile(fp);
- return ((char *)fp->_lb._base);
-
-error:
- if (lenp != NULL)
- *lenp = 0; /* ??? */
- funlockfile(fp);
- return (NULL); /* ??? */
-}
diff --git a/mit-pthreads/stdio/fgetpos.c b/mit-pthreads/stdio/fgetpos.c
deleted file mode 100644
index c81b48e3cc8..00000000000
--- a/mit-pthreads/stdio/fgetpos.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgetpos.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
-#include "local.h"
-
-fgetpos(fp, pos)
- FILE *fp;
- fpos_t *pos;
-{
- flockfile(fp);
-
- /*
- * Find offset of underlying I/O object, then
- * adjust for buffered bytes.
- */
- if (fp->_flags & __SOFF) {
- *pos = fp->_offset;
- } else {
- *pos = __sseek(fp, (off_t)0, SEEK_CUR);
- }
-
- if (*pos != (fpos_t)-1) {
- if (fp->_flags & __SRD) {
- /*
- * Reading. Any unread characters (including
- * those from ungetc) cause the position to be
- * smaller than that in the underlying object.
- */
- *pos -= fp->_r;
- if (HASUB(fp))
- *pos -= fp->_ur;
- } else if (fp->_flags & __SWR && fp->_p != NULL) {
- /*
- * Writing. Any buffered characters cause the
- * position to be greater than that in the
- * underlying object.
- */
- *pos += fp->_p - fp->_bf._base;
- }
- }
- funlockfile(fp);
- return ((*pos) == (fpos_t)-1);
-}
diff --git a/mit-pthreads/stdio/fgets.c b/mit-pthreads/stdio/fgets.c
deleted file mode 100644
index 5ee5c4d6608..00000000000
--- a/mit-pthreads/stdio/fgets.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgets.c 5.4 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * Read at most n-1 characters from the given file.
- * Stop when a newline has been read, or the count runs out.
- * Return first argument, or NULL if no characters were read.
- */
-char *
-fgets(buf, n, fp)
- char *buf;
- register size_t n;
- register FILE *fp;
-{
- register size_t len;
- register char *s;
- register unsigned char *p, *t;
-
- if (n < 2) /* sanity check */
- return (NULL);
-
- flockfile(fp);
- s = buf;
- n--; /* leave space for NUL */
- do {
- /*
- * If the buffer is empty, refill it.
- */
- if ((len = fp->_r) <= 0) {
- if (__srefill(fp)) {
- /* EOF/error: stop with partial or no line */
- if (s == buf)
- buf = NULL;
- break;
- }
- len = fp->_r;
- }
- p = fp->_p;
-
- /*
- * Scan through at most n bytes of the current buffer,
- * looking for '\n'. If found, copy up to and including
- * newline, and stop. Otherwise, copy entire chunk
- * and loop.
- */
- if (len > n)
- len = n;
- t = memchr((void *)p, '\n', len);
- if (t != NULL) {
- len = ++t - p;
- fp->_r -= len;
- fp->_p = t;
- (void) memcpy((void *)s, (void *)p, len);
- s += len;
- break;
- }
- fp->_r -= len;
- fp->_p += len;
- (void) memcpy((void *)s, (void *)p, len);
- s += len;
- } while ((n -= len) != 0);
-
- *s = 0;
- funlockfile(fp);
- return (buf);
-}
diff --git a/mit-pthreads/stdio/fileno.c b/mit-pthreads/stdio/fileno.c
deleted file mode 100644
index 475bd509993..00000000000
--- a/mit-pthreads/stdio/fileno.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fileno.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro fileno.
- */
-#undef fileno
-
-fileno(fp)
- FILE *fp;
-{
- return (__sfileno(fp));
-}
diff --git a/mit-pthreads/stdio/findfp.c b/mit-pthreads/stdio/findfp.c
deleted file mode 100644
index 35817eb6a5f..00000000000
--- a/mit-pthreads/stdio/findfp.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)findfp.c 5.10 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include "local.h"
-#include "glue.h"
-
-
-#define NSTATIC 20 /* stdin + stdout + stderr + the usual */
-#define NDYNAMIC 10 /* add ten more whenever necessary */
-
-#define std(flags, file) \
- {0,0,0,flags,file,{0},0 }
-/* p r w flags file _bf z */
-
-static FILE usual[NSTATIC - 3]; /* the usual */
-static struct glue uglue = { 0, NSTATIC - 3, usual };
-
-FILE __sF[3] = {
- std(__SRD, 0), /* stdin */
- std(__SWR, 1), /* stdout */
- std(__SWR|__SNBF, 2) /* stderr */
-};
-struct glue __sglue = { &uglue, 3, __sF };
-FILE *__iob = __sF;
-FILE *_iob = __sF;
-
-pthread_mutex_t __sfp_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t __sfp_cond = PTHREAD_COND_INITIALIZER;
-/*
- * __sfp_state = 0, when free, > 0 when in _fwalk
- * This allows multiple readers in _fwalk, but only one writer __sfp,
- * or freopen() at a time.
- */
-int __sfp_state = 0;
-
-static struct glue *moreglue(register int n)
-{
- register struct glue *g;
- register FILE *p;
- static FILE empty;
-
- g = (struct glue *)malloc(sizeof(struct glue) + n * sizeof(FILE));
- if (g == NULL)
- return (NULL);
- p = (FILE *)(g + 1);
- g->next = NULL;
- g->niobs = n;
- g->iobs = p;
- while (--n >= 0)
- *p++ = empty;
- return (g);
-}
-
-/*
- * Find a free FILE for fopen et al.
- */
-FILE *__sfp()
-{
- register FILE *fp;
- register int n;
- register struct glue *g;
-
- for (g = &__sglue;; g = g->next) {
- for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
- if (fp->_flags == 0) {
- fp->_flags = 1; /* reserve this slot; caller sets real flags */
- fp->_p = NULL; /* no current pointer */
- fp->_w = 0; /* nothing to read or write */
- fp->_r = 0;
- fp->_bf._base = NULL; /* no buffer */
- fp->_bf._size = 0;
- fp->_lbfsize = 0; /* not line buffered */
- fp->_file = -1; /* no file */
- fp->_ub._base = NULL; /* no ungetc buffer */
- fp->_ub._size = 0;
- fp->_lb._base = NULL; /* no line buffer */
- fp->_lb._size = 0;
- goto __sfp_done;
- }
- if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL) {
- fp = NULL;
- break;
- }
- }
-__sfp_done:;
- return (fp);
-}
-
-/*
- * exit() calls _cleanup() through *__cleanup, set whenever we
- * open or buffer a file. This chicanery is done so that programs
- * that do not use stdio need not link it all in.
- *
- * The name `_cleanup' is, alas, fairly well known outside stdio.
- */
-void _cleanup()
-{
- (void) __swalk_sflush();
-}
-
-/*
- * __sinit() is called whenever stdio's internal variables must be set up.
- * Do the pthread_once stuff here to keep pthread_once_t out of the
- * header files. No reason sprintf.c &c should need to include pthread.h...
- */
-static void __s_real_init ()
-{
- /* make sure we clean up on exit */
- __cleanup = _cleanup;
-}
-
-static pthread_once_t sdidinit = PTHREAD_ONCE_INIT;
-
-void __sinit ()
-{
- pthread_once (&sdidinit, __s_real_init);
-}
diff --git a/mit-pthreads/stdio/flags.c b/mit-pthreads/stdio/flags.c
deleted file mode 100644
index c0971003312..00000000000
--- a/mit-pthreads/stdio/flags.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)flags.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-
-/*
- * Return the (stdio) flags for a given mode. Store the flags
- * to be passed to an open() syscall through *optr.
- * Return 0 on error.
- */
-__sflags(mode, optr)
- register char *mode;
- int *optr;
-{
- register int ret, m, o;
-
- switch (*mode++) {
-
- case 'r': /* open for reading */
- ret = __SRD;
- m = O_RDONLY;
- o = 0;
- break;
-
- case 'w': /* open for writing */
- ret = __SWR;
- m = O_WRONLY;
- o = O_CREAT | O_TRUNC;
- break;
-
- case 'a': /* open for appending */
- ret = __SWR;
- m = O_WRONLY;
- o = O_CREAT | O_APPEND;
- break;
-
- default: /* illegal mode */
- errno = EINVAL;
- return (0);
- }
-
- /* [rwa]\+ or [rwa]b\+ means read and write */
- if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
- ret = __SRW;
- m = O_RDWR;
- }
- *optr = m | o;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/floatio.h b/mit-pthreads/stdio/floatio.h
deleted file mode 100644
index cf3821488ae..00000000000
--- a/mit-pthreads/stdio/floatio.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)floatio.h 5.1 (Berkeley) 1/20/91
- * $Id$
- */
-
-/*
- * Floating point scanf/printf (input/output) definitions.
- */
-
-/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
-#define MAXEXP 308
-/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
-#define MAXFRACT 39
diff --git a/mit-pthreads/stdio/fopen.c b/mit-pthreads/stdio/fopen.c
deleted file mode 100644
index d44c17b633f..00000000000
--- a/mit-pthreads/stdio/fopen.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fopen.c 5.5 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-FILE *fopen(const char *file, const char *mode)
-{
- register FILE *fp;
- register int f;
- int flags, oflags;
-
- if ((flags = __sflags(mode, &oflags)) == 0)
- return (NULL);
- if ((f = open(file, oflags, 0666)) < 0) {
- return (NULL);
- }
-
- __sinit ();
- pthread_mutex_lock(&__sfp_mutex);
- while (__sfp_state) {
- pthread_cond_wait(&__sfp_cond, &__sfp_mutex);
- }
-
- if (fp = __sfp()) {
- fp->_file = f;
- fp->_flags = flags;
-
- /*
- * When opening in append mode, even though we use O_APPEND,
- * we need to seek to the end so that ftell() gets the right
- * answer. If the user then alters the seek pointer, or
- * the file extends, this will fail, but there is not much
- * we can do about this. (We could set __SAPP and check in
- * fseek and ftell.)
- */
- if (oflags & O_APPEND)
- (void) __sseek((void *)fp, (off_t)0, SEEK_END);
- }
- pthread_mutex_unlock(&__sfp_mutex);
- return (fp);
-}
diff --git a/mit-pthreads/stdio/fprintf.c b/mit-pthreads/stdio/fprintf.c
deleted file mode 100644
index bdeb49c054d..00000000000
--- a/mit-pthreads/stdio/fprintf.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fprintf.c 5.6 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-fprintf(FILE *fp, const char *fmt, ...)
-#else
-fprintf(fp, fmt, va_alist)
- FILE *fp;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
-
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- ret = vfprintf(fp, fmt, ap);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/fpurge.c b/mit-pthreads/stdio/fpurge.c
deleted file mode 100644
index 7edbb0b30cd..00000000000
--- a/mit-pthreads/stdio/fpurge.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fpurge.c 5.2 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/*
- * fpurge: like fflush, but without writing anything: leave the
- * given FILE's buffer empty.
- */
-int
-fpurge(fp)
- register FILE *fp;
-{
- int ret;
-
- flockfile(fp);
- if (fp->_flags) {
- if (HASUB(fp))
- FREEUB(fp);
- fp->_p = fp->_bf._base;
- fp->_r = 0;
- fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
- ret = 0;
- } else {
- errno = EBADF;
- ret = EOF;
- }
- funlockfile(fp);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/fputc.c b/mit-pthreads/stdio/fputc.c
deleted file mode 100644
index e6dd752f81b..00000000000
--- a/mit-pthreads/stdio/fputc.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fputc.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-fputc(c, fp)
- int c;
- register FILE *fp;
-{
- int ret;
- flockfile(fp);
- ret = __sputc(c, fp);
- funlockfile(fp);
- return(ret);
-}
-
-int __putc(int _c, FILE *_p)
-{
- int ret;
- flockfile(_p);
- ret = __sputc(_c, _p);
- funlockfile(_p);
- return(ret);
-}
-
-int __sputc(int _c, FILE *_p)
-{
- if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
- return (*_p->_p++ = _c);
- else
- return (__swbuf(_c, _p));
-}
-
diff --git a/mit-pthreads/stdio/fputs.c b/mit-pthreads/stdio/fputs.c
deleted file mode 100644
index 882b828409e..00000000000
--- a/mit-pthreads/stdio/fputs.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fputs.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include "fvwrite.h"
-
-/*
- * Write the given string to the given file.
- */
-fputs(s, fp)
- const char *s;
- FILE *fp;
-{
- struct __suio uio;
- struct __siov iov;
- int ret;
-
- iov.iov_base = (void *)s;
- iov.iov_len = uio.uio_resid = strlen(s);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- flockfile(fp);
- ret = __sfvwrite(fp, &uio);
- funlockfile(fp);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/fread.c b/mit-pthreads/stdio/fread.c
deleted file mode 100644
index 0d8ec6186c7..00000000000
--- a/mit-pthreads/stdio/fread.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fread.c 5.4 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-
-size_t
-fread(buf, size, count, fp)
- void *buf;
- size_t size, count;
- register FILE *fp;
-{
- register size_t resid;
- register char *p;
- register int r;
- size_t total;
-
- if ((resid = count * size) == 0)
- return (count);
-
- flockfile(fp);
- if (fp->_r < 0)
- fp->_r = 0;
- total = resid;
- p = buf;
- while (resid > (r = fp->_r)) {
- (void) memcpy((void *)p, (void *)fp->_p, (size_t)r);
- fp->_p += r;
- /* fp->_r = 0 ... done in __srefill */
- p += r;
- resid -= r;
- if (__srefill(fp)) {
- /* no more input: return partial result */
- count = (total - resid) / size;
- goto done_fread;
- }
- }
- (void) memcpy((void *)p, (void *)fp->_p, resid);
- fp->_r -= resid;
- fp->_p += resid;
-done_fread:;
- funlockfile(fp);
- return (count);
-}
diff --git a/mit-pthreads/stdio/freopen.c b/mit-pthreads/stdio/freopen.c
deleted file mode 100644
index f45571c8ea0..00000000000
--- a/mit-pthreads/stdio/freopen.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)freopen.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-/*
- * Re-direct an existing, open (probably) file to some other file.
- * ANSI is written such that the original file gets closed if at
- * all possible, no matter what.
- */
-FILE *
-freopen(file, mode, fp)
- const char *file, *mode;
- register FILE *fp;
-{
- int f, flags, oflags;
- FILE *ret;
-
- if ((flags = __sflags(mode, &oflags)) == 0) {
- (void) fclose(fp);
- return (NULL);
- }
-
- __sinit ();
-
- /*
- * There are actually programs that depend on being able to "freopen"
- * descriptors that weren't originally open. Keep this from breaking.
- * Remember whether the stream was open to begin with, and which file
- * descriptor (if any) was associated with it. If it was attached to
- * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
- * should work. This is unnecessary if it was not a Unix file.
- */
- /* while lock __sfp_mutex, to block out fopen, and other freopen calls */
- while (pthread_mutex_lock(&__sfp_mutex) == OK) {
- if (ftrylockfile(fp) == OK) {
- if (fp->_flags) {
- /* flush the stream; ANSI doesn't require this. */
- if (fp->_flags & __SWR)
- (void) __sflush(fp);
- __sclose(fp);
- /*
- * Finish closing fp. We cannot keep fp->_base:
- * it may be the wrong size. This loses the effect
- * of any setbuffer calls, but stdio has always done
- * this before.
- * NOTE: We do this even if __ftrylockfilr failed with
- * an error to avoid memory leaks.
- */
- if (fp->_flags & __SMBF)
- free((char *)fp->_bf._base);
- fp->_w = 0;
- fp->_r = 0;
- fp->_p = NULL;
- fp->_bf._base = NULL;
- fp->_bf._size = 0;
- fp->_lbfsize = 0;
- if (HASUB(fp))
- FREEUB(fp);
- fp->_ub._size = 0;
- if (HASLB(fp))
- FREELB(fp);
- fp->_lb._size = 0;
- }
- /* Get a new descriptor to refer to the new file. */
- if ((f = open(file, oflags, 0666)) < OK)
- ret = NULL;
- /*
- * If reopening something that was open before on a real file, try
- * to maintain the descriptor. Various C library routines (perror)
- * assume stderr is always fd STDERR_FILENO, even if being
- * freopen'd.
- */
- /* Testing f == fp->_file may no longer be necessary */
- if (fp->_file >= 0 && f != fp->_file) {
- if (dup2(f, fp->_file) >= OK) {
- (void)close(f);
- f = fp->_file;
- }
- }
- fp->_flags = flags;
- fp->_file = f;
- ret = fp;
- } else {
- /* unlock __sfp_mutex, and try again later */
- pthread_mutex_unlock(&__sfp_mutex);
- pthread_yield();
- continue;
- }
- /* @@ Yo, Chris! Between the "break" and "continue" statements
- above, the program will never get here. What gives? */
- pthread_mutex_unlock(&__sfp_mutex);
- funlockfile(fp);
- return(ret);
- }
- (void)fclose(fp);
- return(NULL);
-}
diff --git a/mit-pthreads/stdio/fscanf.c b/mit-pthreads/stdio/fscanf.c
deleted file mode 100644
index 8fbbac5d102..00000000000
--- a/mit-pthreads/stdio/fscanf.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fscanf.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-fscanf(FILE *fp, char const *fmt, ...) {
- int r;
- va_list ap;
-
- va_start(ap, fmt);
-#else
-fscanf(fp, fmt, va_alist)
- FILE *fp;
- char *fmt;
- va_dcl
-{
- int r;
- va_list ap;
-
- va_start(ap);
-#endif
- flockfile(fp);
- r = __svfscanf(fp, fmt, ap);
- funlockfile(fp);
- va_end(ap);
- return(r);
-}
diff --git a/mit-pthreads/stdio/fseek.c b/mit-pthreads/stdio/fseek.c
deleted file mode 100644
index 5c7feda638f..00000000000
--- a/mit-pthreads/stdio/fseek.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fseek.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "local.h"
-
-#define POS_ERR (-(fpos_t)1)
-
-/*
- * Seek the given file to the given offset.
- * `Whence' must be one of the three SEEK_* macros.
- */
-fseek(fp, offset, whence)
- register FILE *fp;
- long offset;
- int whence;
-{
-#if __STDC__
- register fpos_t (*seekfn)(void *, fpos_t, int);
-#else
- register fpos_t (*seekfn)();
-#endif
- fpos_t target, curoff;
- size_t n;
- struct stat st;
- int havepos;
-
- /* make sure stdio is set up */
- __sinit ();
-
- flockfile(fp);
-
- /*
- * Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
- * After this, whence is either SEEK_SET or SEEK_END.
- */
- switch (whence) {
- case SEEK_CUR:
- /*
- * In order to seek relative to the current stream offset,
- * we have to first find the current stream offset a la
- * ftell (see ftell for details).
- */
- if (fp->_flags & __SOFF)
- curoff = fp->_offset;
- else {
- curoff = __sseek(fp, (off_t)0, SEEK_CUR);
- if (curoff == -1L) {
- funlockfile(fp);
- return (EOF);
- }
- }
- if (fp->_flags & __SRD) {
- curoff -= fp->_r;
- if (HASUB(fp))
- curoff -= fp->_ur;
- } else if (fp->_flags & __SWR && fp->_p != NULL)
- curoff += fp->_p - fp->_bf._base;
-
- offset += curoff;
- whence = SEEK_SET;
- havepos = 1;
- break;
-
- case SEEK_SET:
- case SEEK_END:
- curoff = 0; /* XXX just to keep gcc quiet */
- havepos = 0;
- break;
-
- default:
- errno = EINVAL;
- funlockfile(fp);
- return (EOF);
- }
-
- /*
- * Can only optimise if:
- * reading (and not reading-and-writing);
- * not unbuffered; and
- * this is a `regular' Unix file (and hence seekfn==__sseek).
- * We must check __NBF first, because it is possible to have __NBF
- * and __SOPT both set.
- */
- if (fp->_bf._base == NULL)
- __smakebuf(fp);
- if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
- goto dumb;
- if ((fp->_flags & __SOPT) == 0) {
- if (fp->_file < 0 || fstat(fp->_file, &st) ||
- (st.st_mode & S_IFMT) != S_IFREG) {
- fp->_flags |= __SNPT;
- goto dumb;
- }
- fp->_blksize = st.st_blksize;
- fp->_flags |= __SOPT;
- }
-
- /*
- * We are reading; we can try to optimise.
- * Figure out where we are going and where we are now.
- */
- if (whence == SEEK_SET)
- target = offset;
- else {
- if (fstat(fp->_file, &st))
- goto dumb;
- target = st.st_size + offset;
- }
-
- if (!havepos) {
- if (fp->_flags & __SOFF)
- curoff = fp->_offset;
- else {
- curoff = __sseek(fp, (off_t)0, SEEK_CUR);
- if (curoff == POS_ERR)
- goto dumb;
- }
- curoff -= fp->_r;
- if (HASUB(fp))
- curoff -= fp->_ur;
- }
-
- /*
- * Compute the number of bytes in the input buffer (pretending
- * that any ungetc() input has been discarded). Adjust current
- * offset backwards by this count so that it represents the
- * file offset for the first byte in the current input buffer.
- */
- if (HASUB(fp)) {
- n = fp->_up - fp->_bf._base;
- curoff -= n;
- n += fp->_ur;
- } else {
- n = fp->_p - fp->_bf._base;
- curoff -= n;
- n += fp->_r;
- }
-
- /*
- * If the target offset is within the current buffer,
- * simply adjust the pointers, clear EOF, undo ungetc(),
- * and return. (If the buffer was modified, we have to
- * skip this; see fgetline.c.)
- */
- if ((fp->_flags & __SMOD) == 0 &&
- target >= curoff && target < curoff + n) {
- register int o = target - curoff;
-
- fp->_p = fp->_bf._base + o;
- fp->_r = n - o;
- if (HASUB(fp))
- FREEUB(fp);
- fp->_flags &= ~__SEOF;
- funlockfile(fp);
- return (0);
- }
-
- /*
- * The place we want to get to is not within the current buffer,
- * but we can still be kind to the kernel copyout mechanism.
- * By aligning the file offset to a block boundary, we can let
- * the kernel use the VM hardware to map pages instead of
- * copying bytes laboriously. Using a block boundary also
- * ensures that we only read one block, rather than two.
- */
- curoff = target & ~(fp->_blksize - 1);
- if (__sseek(fp, (off_t)curoff, SEEK_SET) != POS_ERR) {
- fp->_r = 0;
- fp->_p = fp->_bf._base;
- if (HASUB(fp))
- FREEUB(fp);
- fp->_flags &= ~__SEOF;
- n = target - curoff;
- if (n) {
- if (__srefill(fp) || fp->_r < n)
- goto dumb;
- fp->_p += n;
- fp->_r -= n;
- }
- funlockfile(fp);
- return (0);
- }
-
- /*
- * We get here if we cannot optimise the seek ... just
- * do it. Allow the seek function to change fp->_bf._base.
- */
-dumb:
- if (__sflush(fp) || __sseek(fp, (off_t)offset, whence) == POS_ERR) {
- funlockfile(fp);
- return (EOF);
- }
- /* success: clear EOF indicator and discard ungetc() data */
- if (HASUB(fp))
- FREEUB(fp);
- fp->_p = fp->_bf._base;
- fp->_r = 0;
- /* fp->_w = 0; */ /* unnecessary (I think...) */
- fp->_flags &= ~__SEOF;
- funlockfile(fp);
- return (0);
-}
diff --git a/mit-pthreads/stdio/fsetpos.c b/mit-pthreads/stdio/fsetpos.c
deleted file mode 100644
index a421d405f51..00000000000
--- a/mit-pthreads/stdio/fsetpos.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fsetpos.c 5.2 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-/*
- * fsetpos: like fseek.
- * Don't bother locking, fseek does it.
- */
-fsetpos(iop, pos)
- FILE *iop;
- const fpos_t *pos;
-{
- return (fseek(iop, (long)*pos, SEEK_SET));
-}
diff --git a/mit-pthreads/stdio/ftell.c b/mit-pthreads/stdio/ftell.c
deleted file mode 100644
index e5961fa50b6..00000000000
--- a/mit-pthreads/stdio/ftell.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)ftell.c 5.4 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-/*
- * ftell: return current offset.
- */
-long
-ftell(fp)
- register const FILE *fp;
-{
- long pos;
-
- flockfile((FILE *)fp);
-
- /*
- * Find offset of underlying I/O object, then
- * adjust for buffered bytes.
- */
- if (fp->_flags & __SOFF) {
- pos = fp->_offset;
- } else {
- pos = (long)__sseek((FILE *)fp, (off_t)0, SEEK_CUR);
- }
-
- if (pos != -1L) {
- if (fp->_flags & __SRD) {
- /*
- * Reading. Any unread characters (including
- * those from ungetc) cause the position to be
- * smaller than that in the underlying object.
- */
- pos -= fp->_r;
- if (HASUB(fp))
- pos -= fp->_ur;
- } else if (fp->_flags & __SWR && fp->_p != NULL) {
- /*
- * Writing. Any buffered characters cause the
- * position to be greater than that in the
- * underlying object.
- */
- pos += fp->_p - fp->_bf._base;
- }
- }
- funlockfile((FILE *)fp);
- return (pos);
-}
diff --git a/mit-pthreads/stdio/funopen.c b/mit-pthreads/stdio/funopen.c
deleted file mode 100644
index f8b37ed0ae4..00000000000
--- a/mit-pthreads/stdio/funopen.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)funopen.c 5.2 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-FILE *
-funopen(cookie, readfn, writefn, seekfn, closefn)
- const void *cookie;
- int (*readfn)(), (*writefn)();
-#if __STDC__
- fpos_t (*seekfn)(void *cookie, fpos_t off, int whence);
-#else
- fpos_t (*seekfn)();
-#endif
- int (*closefn)();
-{
- struct fd_ops *fd_ops;
- char *flags;
- FILE *fp;
- int fd;
-
- if (readfn == NULL) {
- if (writefn == NULL) { /* illegal */
- errno = EINVAL;
- return (NULL);
- } else
- flags = "w"; /* write only */
- } else {
- if (writefn == NULL)
- flags = "r"; /* read only */
- else
- flags = "r+"; /* read-write */
- }
-
- if (fd_ops = (struct fd_ops*)malloc(sizeof(struct fd_ops))) {
- if ((fd = fd_allocate()) >= OK) {
-
- /* Set functions */
- fd_ops->seek = (off_t(*)())seekfn;
- fd_ops->read = (pthread_ssize_t(*)())readfn;
- fd_ops->write = (pthread_ssize_t(*)())writefn;
- fd_ops->close = closefn;
- fd_ops->use_kfds = 2;
-
- /* Alloc space for funtion pointer table */
- fd_table[fd]->type = FD_HALF_DUPLEX;
- fd_table[fd]->ops = fd_ops;
- fd_table[fd]->flags = O_RDWR;
-
- /* Save the cookie, it's important */
- fd_table[fd]->fd.ptr = (void *)cookie;
-
- if (fp = fdopen(fd, flags))
- return(fp);
-
- fd_free(fd);
- }
- free(fd_ops);
- }
- return(NULL);
-}
diff --git a/mit-pthreads/stdio/fvwrite.c b/mit-pthreads/stdio/fvwrite.c
deleted file mode 100644
index 5ed25b4e7b4..00000000000
--- a/mit-pthreads/stdio/fvwrite.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fvwrite.c 5.3 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-#include "fvwrite.h"
-
-/*
- * Write some memory regions. Return zero on success, EOF on error.
- *
- * This routine is large and unsightly, but most of the ugliness due
- * to the three different kinds of output buffering is handled here.
- */
-__sfvwrite(fp, uio)
- register FILE *fp;
- register struct __suio *uio;
-{
- register size_t len;
- register char *p;
- register struct __siov *iov;
- register int w, s;
- char *nl;
- int nlknown, nldist;
-
- if ((len = uio->uio_resid) == 0)
- return (0);
- /* make sure we can write */
- if (cantwrite(fp))
- return (EOF);
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define COPY(n) (void) memcpy((void *)fp->_p, (void *)p, (size_t)(n));
-
- iov = uio->uio_iov;
- p = iov->iov_base;
- len = iov->iov_len;
- iov++;
-#define GETIOV(extra_work) \
- while (len == 0) { \
- extra_work; \
- p = iov->iov_base; \
- len = iov->iov_len; \
- iov++; \
- }
- if (fp->_flags & __SNBF) {
- /*
- * Unbuffered: write up to BUFSIZ bytes at a time.
- */
- do {
- GETIOV(;);
- w = __swrite(fp, p, MIN(len, BUFSIZ));
- if (w <= 0)
- goto err;
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- } else if ((fp->_flags & __SLBF) == 0) {
- /*
- * Fully buffered: fill partially full buffer, if any,
- * and then flush. If there is no partial buffer, write
- * one _bf._size byte chunk directly (without copying).
- *
- * String output is a special case: write as many bytes
- * as fit, but pretend we wrote everything. This makes
- * snprintf() return the number of bytes needed, rather
- * than the number used, and avoids its write function
- * (so that the write function can be invalid).
- */
- do {
- GETIOV(;);
- w = fp->_w;
- if (fp->_flags & __SSTR) {
- if (len < w)
- w = len;
- COPY(w); /* copy MIN(fp->_w,len), */
- fp->_w -= w;
- fp->_p += w;
- w = len; /* but pretend copied all */
- } else if (fp->_p > fp->_bf._base && len > w) {
- /* fill and flush */
- COPY(w);
- /* fp->_w -= w; */ /* unneeded */
- fp->_p += w;
- if (fflush(fp))
- goto err;
- } else if (len >= (w = fp->_bf._size)) {
- if ((w = __swrite(fp, p, w)) <= 0)
- goto err;
- } else {
- /* fill and done */
- w = len;
- COPY(w);
- fp->_w -= w;
- fp->_p += w;
- }
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- } else {
- /*
- * Line buffered: like fully buffered, but we
- * must check for newlines. Compute the distance
- * to the first newline (including the newline),
- * or `infinity' if there is none, then pretend
- * that the amount to write is MIN(len,nldist).
- */
- nlknown = 0;
- nldist = 0; /* XXX just to keep gcc happy */
- do {
- GETIOV(nlknown = 0);
- if (!nlknown) {
- nl = memchr((void *)p, '\n', len);
- nldist = nl ? nl + 1 - p : len + 1;
- nlknown = 1;
- }
- s = MIN(len, nldist);
- w = fp->_w + fp->_bf._size;
- if (fp->_p > fp->_bf._base && s > w) {
- COPY(w);
- /* fp->_w -= w; */
- fp->_p += w;
- if (fflush(fp))
- goto err;
- } else if (s >= (w = fp->_bf._size)) {
- if ((w = __swrite(fp, p, w)) <= 0)
- goto err;
- } else {
- w = s;
- COPY(w);
- fp->_w -= w;
- fp->_p += w;
- }
- if ((nldist -= w) == 0) {
- /* copied the newline: flush and forget */
- if (fflush(fp))
- goto err;
- nlknown = 0;
- }
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- }
- return (0);
-
-err:
- fp->_flags |= __SERR;
- return (EOF);
-}
diff --git a/mit-pthreads/stdio/fvwrite.h b/mit-pthreads/stdio/fvwrite.h
deleted file mode 100644
index b3474563a4e..00000000000
--- a/mit-pthreads/stdio/fvwrite.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)fvwrite.h 5.1 (Berkeley) 1/20/91
- * $Id$
- */
-
-/*
- * I/O descriptors for __sfvwrite().
- */
-struct __siov {
- void *iov_base;
- size_t iov_len;
-};
-
-struct __suio {
- struct __siov *uio_iov;
- int uio_iovcnt;
- int uio_resid;
-};
-
-extern int __sfvwrite __P_(( FILE *, struct __suio *));
diff --git a/mit-pthreads/stdio/fwalk.c b/mit-pthreads/stdio/fwalk.c
deleted file mode 100644
index 58a199e0707..00000000000
--- a/mit-pthreads/stdio/fwalk.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fwalk.c 5.2 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include "local.h"
-#include "glue.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-/*
- * fwalk now can only be used for flushing the buffers.
- * This is all it was originally used for.
- * The function has also become much more complicated.
- * The first time through we flush everything we can.
- * If this fails to flush everything because we couldn't get a lock
- * we wait on the locksfor the second pass. Why this works ...
- *
- * This function must allow for multiple threads to flush everything.
- * This function cannot flush buffers locked by another thread.
- * So we flush everything we can the first pass. This includes all
- * buffers locked by this thread, and wait on buffers that are locked.
- * Eventually other threads willl unlock there buffers or flush them themselves
- * at which point this thread will notice that it's empty or be able to
- * flush the buffer. This is fine so long as no other thread tries to flush
- * all buffers. Here is the possible deadlock condition, but since this thread
- * has flushed all buffers it can, there are NO buffers locked by this thread
- * that need flushing so any other thread flushing won't block waiting on this
- * thread thereby eliminating the deadlock condition.
- */
-
-int __swalk_sflush()
-{
- register FILE *fp, *savefp;
- register int n, ret, saven;
- register struct glue *g, *saveg;
-
- /* Only allow other threads to read __sglue */
- pthread_mutex_lock(&__sfp_mutex);
- __sfp_state++;
- pthread_mutex_unlock(&__sfp_mutex);
-
- ret = 0;
- saven = 0;
- saveg = NULL;
- savefp = NULL;
- for (g = &__sglue; g != NULL; g = g->next) {
- for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
- if (fp->_flags != 0) {
- /* Is there anything to flush? */
- if (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- if (ftrylockfile(fp)) { /* Can we flush it */
- if (!saven) { /* No, save first fp we can't flush */
- saven = n;
- saveg = g;
- savefp = fp;
- continue;
- }
- } else {
- ret |= __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
- if (savefp) {
- for (g = saveg; g != NULL; g = g->next) {
- for (fp = savefp, n = saven + 1; --n >= 0; fp++) {
- if (fp->_flags != 0) {
- /* Anything to flush */
- while (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- flockfile(fp);
- ret |= __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
-
- /* If no other readers wakeup a thread waiting to do __sfp */
- pthread_mutex_lock(&__sfp_mutex);
- if (! (--__sfp_state)) {
- pthread_cond_signal(&__sfp_cond);
- }
- pthread_mutex_unlock(&__sfp_mutex);
- return (ret);
-}
-
diff --git a/mit-pthreads/stdio/fwrite.c b/mit-pthreads/stdio/fwrite.c
deleted file mode 100644
index 5eada4ee84b..00000000000
--- a/mit-pthreads/stdio/fwrite.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fwrite.c 5.5 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include "local.h"
-#include "fvwrite.h"
-
-/*
- * Write `count' objects (each size `size') from memory to the given file.
- * Return the number of whole objects written.
- */
-size_t
-fwrite(buf, size, count, fp)
- const void *buf;
- size_t size, count;
- FILE *fp;
-{
- struct __suio uio;
- struct __siov iov;
- size_t n;
-
- iov.iov_base = (void *)buf;
- uio.uio_resid = iov.iov_len = n = count * size;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- if (! n)
- return(0);
-
- flockfile(fp);
-
- /*
- * The usual case is success (__sfvwrite returns 0);
- * skip the divide if this happens, since divides are
- * generally slow and since this occurs whenever size==0.
- */
- if (__sfvwrite(fp, &uio) == 0)
- count = (n - uio.uio_resid) / size;
- funlockfile(fp);
- return(count);
-}
diff --git a/mit-pthreads/stdio/getc.c b/mit-pthreads/stdio/getc.c
deleted file mode 100644
index 6896e78bc7e..00000000000
--- a/mit-pthreads/stdio/getc.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro getc.
- */
-#undef getc
-
-getc(fp)
- register FILE *fp;
-{
- int ret;
- flockfile(fp);
- ret = __sgetc(fp);
- funlockfile(fp);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/getc_unlocked.c b/mit-pthreads/stdio/getc_unlocked.c
deleted file mode 100644
index 01db3bcea2a..00000000000
--- a/mit-pthreads/stdio/getc_unlocked.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro getc.
- */
-#undef getc_unlocked
-
-getc_unlocked(fp)
- register FILE *fp;
-{
- return (__sgetc(fp));
-}
diff --git a/mit-pthreads/stdio/getchar.c b/mit-pthreads/stdio/getchar.c
deleted file mode 100644
index 6e631c6c1b1..00000000000
--- a/mit-pthreads/stdio/getchar.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * A subroutine version of the macro getchar.
- */
-#include <pthread.h>
-#include <stdio.h>
-
-#undef getchar
-
-getchar()
-{
- int ret;
- flockfile(stdin);
- ret = getc(stdin);
- funlockfile(stdin);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/getchar_unlocked.c b/mit-pthreads/stdio/getchar_unlocked.c
deleted file mode 100644
index 40945c5dd57..00000000000
--- a/mit-pthreads/stdio/getchar_unlocked.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * A subroutine version of the macro getchar.
- */
-#include <pthread.h>
-#include <stdio.h>
-
-#undef getchar_unlocked
-
-getchar_unlocked()
-{
- return (getc(stdin));
-}
diff --git a/mit-pthreads/stdio/gets.c b/mit-pthreads/stdio/gets.c
deleted file mode 100644
index 0e7967ae3fe..00000000000
--- a/mit-pthreads/stdio/gets.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gets.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
-
-char *
-gets(buf)
- char *buf;
-{
- register int c;
- register char *s;
- static int warned;
- static char w[] =
- "warning: this program uses gets(), which is unsafe.\r\n";
-
- if (!warned) {
- (void) write(STDERR_FILENO, w, sizeof(w) - 1);
- warned = 1;
- }
- for (s = buf; (c = getchar()) != '\n';)
- if (c == EOF)
- if (s == buf)
- return (NULL);
- else
- break;
- else
- *s++ = c;
- *s = 0;
- return (buf);
-}
diff --git a/mit-pthreads/stdio/getw.c b/mit-pthreads/stdio/getw.c
deleted file mode 100644
index 623ba6258a1..00000000000
--- a/mit-pthreads/stdio/getw.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getw.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-getw(fp)
- FILE *fp;
-{
- int x;
-
- return (fread((void *)&x, sizeof(x), 1, fp) == 1 ? x : EOF);
-}
diff --git a/mit-pthreads/stdio/glue.h b/mit-pthreads/stdio/glue.h
deleted file mode 100644
index e5103bbb0b3..00000000000
--- a/mit-pthreads/stdio/glue.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)glue.h 5.1 (Berkeley) 1/20/91
- * $Id$
- */
-
-/*
- * The first few FILEs are statically allocated; others are dynamically
- * allocated and linked in via this glue structure.
- */
-typedef struct glue {
- struct glue *next;
- int niobs;
- FILE *iobs;
-} __sglue_type;
-extern struct glue __sglue;
diff --git a/mit-pthreads/stdio/local.h b/mit-pthreads/stdio/local.h
deleted file mode 100644
index 068754fad38..00000000000
--- a/mit-pthreads/stdio/local.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)local.h 5.3 (Berkeley) 5/6/93
- * $Id$
- */
-
-/*
- * Information local to this implementation of stdio,
- * in particular, macros and private variables.
- */
-
-#include <sys/types.h>
-#include <stddef.h>
-
-extern FILE *__sfp __P_((void));
-extern int __sflush __P_((FILE *));
-extern int __srefill __P_((FILE *));
-extern int __swrite __P_((FILE *, const char *, int));
-extern int __sread __P_((FILE *, char *, int));
-extern fpos_t __sseek __P_((FILE *, off_t, int));
-extern int __sclose __P_((FILE *));
-extern void __sinit __P_((void));
-extern void _cleanup __P_((void));
-extern void __smakebuf __P_((FILE *));
-extern int __swhatbuf __P_((FILE *, size_t *, int *));
-extern int __swalk_sflush __P_(());
-extern int __swsetup __P_((FILE *));
-extern int __sflags __P_((const char *, int *));
-
-extern void (*__cleanup) __P_((void));
-
-/*
- * Return true iff the given FILE cannot be written now.
- */
-#define cantwrite(fp) \
- ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
- __swsetup(fp))
-
-/*
- * Test whether the given stdio file has an active ungetc buffer;
- * release such a buffer, without restoring ordinary unread data.
- */
-#define HASUB(fp) ((fp)->_ub._base != NULL)
-#define FREEUB(fp) { \
- if ((fp)->_ub._base != (fp)->_ubuf) \
- free((char *)(fp)->_ub._base); \
- (fp)->_ub._base = NULL; \
-}
-
-/*
- * test for an fgetline() buffer.
- */
-#define HASLB(fp) ((fp)->_lb._base != NULL)
-#define FREELB(fp) { \
- free((char *)(fp)->_lb._base); \
- (fp)->_lb._base = NULL; \
-}
diff --git a/mit-pthreads/stdio/makebuf.c b/mit-pthreads/stdio/makebuf.c
deleted file mode 100644
index 316abe054b6..00000000000
--- a/mit-pthreads/stdio/makebuf.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)makebuf.c 5.3 (Berkeley) 5/6/93";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-void (*__cleanup) __P_((void));
-
-/*
- * Allocate a file buffer, or switch to unbuffered I/O.
- * Per the ANSI C standard, ALL tty devices default to line buffered.
- *
- * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
- * optimisation) right after the fstat() that finds the buffer size.
- */
-void
-__smakebuf(fp)
- register FILE *fp;
-{
- register void *p;
- register int flags;
- size_t size;
- int couldbetty;
-
- if (fp->_flags & __SNBF) {
- fp->_bf._base = fp->_p = fp->_nbuf;
- fp->_bf._size = 1;
- return;
- }
- flags = __swhatbuf(fp, &size, &couldbetty);
- if ((p = malloc(size)) == NULL) {
- fp->_flags |= __SNBF;
- fp->_bf._base = fp->_p = fp->_nbuf;
- fp->_bf._size = 1;
- return;
- }
- __cleanup = _cleanup;
- flags |= __SMBF;
- fp->_bf._base = fp->_p = p;
- fp->_bf._size = size;
- if (couldbetty && isatty(fp->_file))
- flags |= __SLBF;
- fp->_flags |= flags;
-}
-
-/*
- * Internal routine to determine `proper' buffering for a file.
- */
-int
-__swhatbuf(fp, bufsize, couldbetty)
- register FILE *fp;
- size_t *bufsize;
- int *couldbetty;
-{
- struct stat st;
-
- if (fp->_file < 0 || fstat(fp->_file, &st) < 0) {
- *couldbetty = 0;
- *bufsize = BUFSIZ;
- return (__SNPT);
- }
-
- /* could be a tty iff it is a character device */
- *couldbetty = (st.st_mode & S_IFMT) == S_IFCHR;
- if (st.st_blksize <= 0) {
- *bufsize = BUFSIZ;
- return (__SNPT);
- }
-
- /*
- * Optimise fseek() only if it is a regular file. (The test for
- * __sseek is mainly paranoia.) It is safe to set _blksize
- * unconditionally; it will only be used if __SOPT is also set.
- */
- *bufsize = st.st_blksize;
- fp->_blksize = st.st_blksize;
- return ((st.st_mode & S_IFMT) == S_IFREG ? __SOPT : __SNPT);
-}
diff --git a/mit-pthreads/stdio/mktemp.c b/mit-pthreads/stdio/mktemp.c
deleted file mode 100644
index 7fdc631ad0b..00000000000
--- a/mit-pthreads/stdio/mktemp.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)mktemp.c 5.10 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-
-static int _gettemp();
-
-mkstemp(path)
- char *path;
-{
- int fd;
-
- return (_gettemp(path, &fd) ? fd : -1);
-}
-
-char *
-mktemp(path)
- char *path;
-{
- return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
-}
-
-static
-_gettemp(path, doopen)
- char *path;
- register int *doopen;
-{
- extern int errno;
- register char *start, *trv;
- struct stat sbuf;
- u_int pid;
-
- pid = getpid();
- for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
- while (*--trv == 'X') {
- *trv = (pid % 10) + '0';
- pid /= 10;
- }
-
- /*
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
- */
- for (start = trv + 1;; --trv) {
- if (trv <= path)
- break;
- if (*trv == '/') {
- *trv = '\0';
- if (stat(path, &sbuf))
- return(0);
- if (!S_ISDIR(sbuf.st_mode)) {
- errno = ENOTDIR;
- return(0);
- }
- *trv = '/';
- break;
- }
- }
-
- for (;;) {
- if (doopen) {
- if ((*doopen =
- open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
- return(1);
- if (errno != EEXIST)
- return(0);
- }
- else if (stat(path, &sbuf))
- return(errno == ENOENT ? 1 : 0);
-
- /* tricky little algorithm for backward compatibility */
- for (trv = start;;) {
- if (!*trv)
- return(0);
- if (*trv == 'z')
- *trv++ = 'a';
- else {
- if (isdigit(*trv))
- *trv = 'a';
- else
- ++*trv;
- break;
- }
- }
- }
- /*NOTREACHED*/
-}
diff --git a/mit-pthreads/stdio/perror.c b/mit-pthreads/stdio/perror.c
deleted file mode 100644
index 19fe52f5010..00000000000
--- a/mit-pthreads/stdio/perror.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)perror.c 5.11 (Berkeley) 2/24/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-char *strerror(int); /* For systems that don't prototype it in string.h */
-
-void
-perror(s)
- const char *s;
-{
- char * e;
-
- if (fd_lock(STDERR_FILENO, FD_WRITE, NULL) == OK) {
- if (s && *s) {
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, s, strlen(s), NULL);
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, ": ", 2, NULL);
- }
- e = strerror(errno);
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, e, strlen(e), NULL);
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, "\n", 1, NULL);
- fd_unlock(STDERR_FILENO, FD_WRITE);
- }
-}
diff --git a/mit-pthreads/stdio/printf.c b/mit-pthreads/stdio/printf.c
deleted file mode 100644
index a298509d341..00000000000
--- a/mit-pthreads/stdio/printf.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)printf.c 5.6 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <pthread.h>
-#include <stdio.h>
-
-printf(char const *fmt, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = vfprintf(stdout, fmt, ap);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/putc.c b/mit-pthreads/stdio/putc.c
deleted file mode 100644
index ac71e35ff25..00000000000
--- a/mit-pthreads/stdio/putc.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro putc.
- */
-#undef putc
-
-putc(c, fp)
- int c;
- register FILE *fp;
-{
- int ret;
- flockfile(fp);
- ret = __sputc(c, fp);
- funlockfile(fp);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/putc_unlocked.c b/mit-pthreads/stdio/putc_unlocked.c
deleted file mode 100644
index 7c9c78ff1e8..00000000000
--- a/mit-pthreads/stdio/putc_unlocked.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro putc.
- */
-#undef putc_unlocked
-
-putc_unlocked(c, fp)
- int c;
- register FILE *fp;
-{
- return (__sputc(c, fp));
-}
diff --git a/mit-pthreads/stdio/putchar.c b/mit-pthreads/stdio/putchar.c
deleted file mode 100644
index c22a11ea25d..00000000000
--- a/mit-pthreads/stdio/putchar.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-#undef putchar
-
-/*
- * A subroutine version of the macro putchar
- */
-putchar(c)
- int c;
-{
- register FILE *so = stdout;
- int ret;
-
- flockfile(so);
- ret = __sputc(c, so);
- funlockfile(so);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/putchar_unlocked.c b/mit-pthreads/stdio/putchar_unlocked.c
deleted file mode 100644
index df27a501211..00000000000
--- a/mit-pthreads/stdio/putchar_unlocked.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-#undef putchar_unlocked
-/*
- * A subroutine version of the macro putchar
- */
-putchar_unlocked(c)
- int c;
-{
- register FILE *so = stdout;
-
- return (__sputc(c, so));
-}
diff --git a/mit-pthreads/stdio/puts.c b/mit-pthreads/stdio/puts.c
deleted file mode 100644
index 97f8b3599f2..00000000000
--- a/mit-pthreads/stdio/puts.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)puts.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include "fvwrite.h"
-
-/*
- * Write the given string to stdout, appending a newline.
- */
-puts(s)
- char const *s;
-{
- size_t c = strlen(s);
- struct __suio uio;
- struct __siov iov[2];
- int r;
-
- iov[0].iov_base = (void *)s;
- iov[0].iov_len = c;
- iov[1].iov_base = "\n";
- iov[1].iov_len = 1;
- uio.uio_resid = c + 1;
- uio.uio_iov = &iov[0];
- uio.uio_iovcnt = 2;
-
- flockfile(stdout);
- r = (__sfvwrite(stdout, &uio) ? EOF : '\n');
- funlockfile(stdout);
- return(r);
-}
diff --git a/mit-pthreads/stdio/putw.c b/mit-pthreads/stdio/putw.c
deleted file mode 100644
index 79473f0e243..00000000000
--- a/mit-pthreads/stdio/putw.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putw.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include "fvwrite.h"
-
-putw(w, fp)
- int w;
- FILE *fp;
-{
- struct __suio uio;
- struct __siov iov;
- int r;
-
- iov.iov_base = &w;
- iov.iov_len = uio.uio_resid = sizeof(w);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
-
- flockfile(fp);
- r = (__sfvwrite(fp, &uio));
- funlockfile(fp);
- return(r);
-}
diff --git a/mit-pthreads/stdio/refill.c b/mit-pthreads/stdio/refill.c
deleted file mode 100644
index 396895e56ff..00000000000
--- a/mit-pthreads/stdio/refill.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)refill.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-#include "glue.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern struct glue __sglue;
-extern int __sfp_state;
-
-/* This function is very similar to __swalk_sflush */
-static void __swalk_lflush()
-{
- register FILE *fp, *savefp;
- register int n, saven;
- register struct glue *g, *saveg;
-
- /* Only allow other threads to read __sglue */
- pthread_mutex_lock(&__sfp_mutex);
- __sfp_state++;
- pthread_mutex_unlock(&__sfp_mutex);
-
- saven = 0;
- saveg = NULL;
- savefp = NULL;
- for (g = &__sglue; g != NULL; g = g->next) {
- for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
- if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) {
- /* Is there anything to flush? */
- if (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- if (ftrylockfile(fp)) { /* Can we flush it */
- if (!saven) { /* No, save first fp we can't flush */
- saven = n;
- saveg = g;
- savefp = fp;
- continue;
- }
- } else {
- (void) __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
- if (savefp) {
- for (g = saveg; g != NULL; g = g->next) {
- for (fp = savefp, n = saven + 1; --n >= 0; fp++) {
- if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) {
- /* Anything to flush */
- while (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- flockfile(fp);
- (void) __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
-
- /* If no other readers wakeup a thread waiting to do __sfp */
- pthread_mutex_lock(&__sfp_mutex);
- if (! (--__sfp_state)) {
- pthread_cond_signal(&__sfp_cond);
- }
- pthread_mutex_unlock(&__sfp_mutex);
-}
-
-/*
- * Refill a stdio buffer.
- * Return EOF on eof or error, 0 otherwise.
- */
-__srefill(fp)
- register FILE *fp;
-{
-
- /* make sure stdio is set up */
- __sinit ();
-
- fp->_r = 0; /* largely a convenience for callers */
-
- /* SysV does not make this test; take it out for compatibility */
- if (fp->_flags & __SEOF)
- return (EOF);
-
- /* if not already reading, have to be reading and writing */
- if ((fp->_flags & __SRD) == 0) {
- if ((fp->_flags & __SRW) == 0) {
- errno = EBADF;
- return (EOF);
- }
- /* switch to reading */
- if (fp->_flags & __SWR) {
- if (__sflush(fp))
- return (EOF);
- fp->_flags &= ~__SWR;
- fp->_w = 0;
- fp->_lbfsize = 0;
- }
- fp->_flags |= __SRD;
- } else {
- /*
- * We were reading. If there is an ungetc buffer,
- * we must have been reading from that. Drop it,
- * restoring the previous buffer (if any). If there
- * is anything in that buffer, return.
- */
- if (HASUB(fp)) {
- FREEUB(fp);
- if ((fp->_r = fp->_ur) != 0) {
- fp->_p = fp->_up;
- return (0);
- }
- }
- }
-
- if (fp->_file == -1) {
- fp->_flags |= __SEOF;
- return(EOF);
- }
-
- if (fp->_bf._base == NULL)
- __smakebuf(fp);
-
- /*
- * Before reading from a line buffered or unbuffered file,
- * flush all line buffered output files, per the ANSI C
- * standard.
- */
- if (fp->_flags & (__SLBF|__SNBF))
- __swalk_lflush();
- fp->_p = fp->_bf._base;
- fp->_r = __sread(fp, (char *)fp->_p, fp->_bf._size);
- fp->_flags &= ~__SMOD; /* buffer contents are again pristine */
- if (fp->_r <= 0) {
- if (fp->_r == 0)
- fp->_flags |= __SEOF;
- else {
- fp->_r = 0;
- fp->_flags |= __SERR;
- }
- return (EOF);
- }
- return (0);
-}
diff --git a/mit-pthreads/stdio/remove.c b/mit-pthreads/stdio/remove.c
deleted file mode 100644
index 116537e3a0f..00000000000
--- a/mit-pthreads/stdio/remove.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)remove.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-
-remove(file)
- const char *file;
-{
- return (unlink(file));
-}
diff --git a/mit-pthreads/stdio/rewind.c b/mit-pthreads/stdio/rewind.c
deleted file mode 100644
index 17d4418db39..00000000000
--- a/mit-pthreads/stdio/rewind.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)rewind.c 5.6 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <errno.h>
-#include <stdio.h>
-
-void
-rewind(fp)
- register FILE *fp;
-{
- flockfile(fp);
- (void) fseek(fp, 0L, SEEK_SET);
- fp->_flags &= ~(__SERR|__SEOF); /* clearerr */
- funlockfile(fp);
- errno = 0; /* not required, but seems reasonable */
-}
diff --git a/mit-pthreads/stdio/rget.c b/mit-pthreads/stdio/rget.c
deleted file mode 100644
index a2b19afb130..00000000000
--- a/mit-pthreads/stdio/rget.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)rget.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-/*
- * Handle getc() when the buffer ran out:
- * Refill, then return the first character
- * in the newly-filled buffer.
- */
-__srget(fp)
- register FILE *fp;
-{
- if (__srefill(fp) == 0) {
- fp->_r--;
- return (*fp->_p++);
- }
- return (EOF);
-}
diff --git a/mit-pthreads/stdio/scanf.c b/mit-pthreads/stdio/scanf.c
deleted file mode 100644
index 9f9f5a6665e..00000000000
--- a/mit-pthreads/stdio/scanf.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)scanf.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-scanf(char const *fmt, ...)
-#else
-scanf(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
-
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- flockfile(stdin);
- ret = __svfscanf(stdin, fmt, ap);
- funlockfile(stdin);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/setbuf.c b/mit-pthreads/stdio/setbuf.c
deleted file mode 100644
index af8d088089d..00000000000
--- a/mit-pthreads/stdio/setbuf.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)setbuf.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include "local.h"
-
-void
-setbuf(fp, buf)
- FILE *fp;
- char *buf;
-{
- (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
-}
diff --git a/mit-pthreads/stdio/setbuffer.c b/mit-pthreads/stdio/setbuffer.c
deleted file mode 100644
index 0c79e55fd93..00000000000
--- a/mit-pthreads/stdio/setbuffer.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)setbuffer.c 5.5 (Berkeley) 3/18/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-void
-setbuffer(fp, buf, size)
- register FILE *fp;
- char *buf;
- int size;
-{
-
- (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
-}
-
-/*
- * set line buffering
- */
-setlinebuf(fp)
- FILE *fp;
-{
-
- (void) setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0);
- return (0); /* ??? */
-}
diff --git a/mit-pthreads/stdio/setvbuf.c b/mit-pthreads/stdio/setvbuf.c
deleted file mode 100644
index 288d8c32db0..00000000000
--- a/mit-pthreads/stdio/setvbuf.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)setvbuf.c 5.5 (Berkeley) 5/6/93";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/*
- * Set one of the three kinds of buffering, optionally including
- * a buffer.
- */
-setvbuf(fp, buf, mode, size)
- register FILE *fp;
- char *buf;
- register int mode;
- register size_t size;
-{
- register int ret, flags;
- size_t iosize;
- int ttyflag;
-
- /*
- * Verify arguments. The `int' limit on `size' is due to this
- * particular implementation. Note, buf and size are ignored
- * when setting _IONBF.
- */
- if (mode != _IONBF)
- if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
- return (EOF);
-
- flockfile(fp);
- /*
- * Write current buffer, if any. Discard unread input, cancel
- * line buffering, and free old buffer if malloc()ed.
- */
- ret = 0;
- (void)__sflush(fp);
- fp->_r = fp->_lbfsize = 0;
- flags = fp->_flags;
- if (flags & __SMBF)
- free((void *)fp->_bf._base);
- flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT);
-
- /* If setting unbuffered mode, skip all the hard work. */
- if (mode == _IONBF)
- goto nbf;
-
- /*
- * Find optimal I/O size for seek optimization. This also returns
- * a `tty flag' to suggest that we check isatty(fd), but we do not
- * care since our caller told us how to buffer.
- */
- flags |= __swhatbuf(fp, &iosize, &ttyflag);
- if (size == 0) {
- buf = NULL; /* force local allocation */
- size = iosize;
- }
-
- /* Allocate buffer if needed. */
- if (buf == NULL) {
- if ((buf = malloc(size)) == NULL) {
- /*
- * Unable to honor user's request. We will return
- * failure, but try again with file system size.
- */
- ret = EOF;
- if (size != iosize) {
- size = iosize;
- buf = malloc(size);
- }
- }
- if (buf == NULL) {
- /* No luck; switch to unbuffered I/O. */
-nbf:
- fp->_flags = flags | __SNBF;
- fp->_w = 0;
- fp->_bf._base = fp->_p = fp->_nbuf;
- fp->_bf._size = 1;
- funlockfile(fp);
- return (ret);
- }
- flags |= __SMBF;
- }
-
- /*
- * Kill any seek optimization if the buffer is not the
- * right size.
- *
- * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)?
- */
- if (size != iosize)
- flags |= __SNPT;
-
- /*
- * Fix up the FILE fields, and set __cleanup for output flush on
- * exit (since we are buffered in some way). If in r/w mode, go
- * to the intermediate state, so that everyone has to call
- * __srefill or __swsetup on the first operation -- it is more
- * trouble than it is worth to set things up correctly here.
- */
- if (mode == _IOLBF)
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
- fp->_w = size; /* Was 0 (mevans) */
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
- fp->_lbfsize = 0;
- __cleanup = _cleanup;
-
- funlockfile(fp);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/snprintf.c b/mit-pthreads/stdio/snprintf.c
deleted file mode 100644
index dd9bca24f73..00000000000
--- a/mit-pthreads/stdio/snprintf.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)snprintf.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-snprintf(char *str, size_t n, char const *fmt, ...)
-#else
-snprintf(str, n, fmt, va_alist)
- char *str;
- size_t n;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
- FILE f;
-
- if ((int)n < 1)
- return (EOF);
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = n - 1;
- ret = vfprintf(&f, fmt, ap);
- *f._p = 0;
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/sprintf.c b/mit-pthreads/stdio/sprintf.c
deleted file mode 100644
index a500e8d4afa..00000000000
--- a/mit-pthreads/stdio/sprintf.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)sprintf.c 5.7 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <limits.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "local.h"
-
-#if __STDC__
-sprintf(char *str, char const *fmt, ...)
-#else
-sprintf(str, fmt, va_alist)
- char *str;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
- FILE f;
-
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = INT_MAX;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- ret = vfprintf(&f, fmt, ap);
- va_end(ap);
- *f._p = 0;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/sscanf.c b/mit-pthreads/stdio/sscanf.c
deleted file mode 100644
index 50148192b9c..00000000000
--- a/mit-pthreads/stdio/sscanf.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)sscanf.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <string.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "local.h"
-
-#if __STDC__
-sscanf(const char *str, char const *fmt, ...)
-#else
-sscanf(str, fmt, va_alist)
- const char *str;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
- FILE f;
-
- f._flags = __SRD;
- f._file = -1;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._r = strlen(str);
- f._ub._base = NULL;
- f._lb._base = NULL;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- ret = __svfscanf(&f, fmt, ap);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/stdio.c b/mit-pthreads/stdio/stdio.c
deleted file mode 100644
index 0b676eeb09b..00000000000
--- a/mit-pthreads/stdio/stdio.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)stdio.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include "local.h"
-
-/*
- * Small standard I/O/seek/close functions.
- * These maintain the `known seek offset' for seek optimisation.
- */
-int __sread(FILE *fp, char *buf, int n)
-{
- register int ret;
-
- /* if the read succeeded, update the current offset */
- if (fd_table[fp->_file]->ops->use_kfds < 2) {
- ret = fd_table[fp->_file]->ops->read(fd_table[fp->_file]->fd,
- fd_table[fp->_file]->flags, buf, n, NULL);
- } else {
- pthread_ssize_t (*readfn)() = fd_table[fp->_file]->ops->read;
- ret = readfn(fd_table[fp->_file]->fd, buf, n);
- }
- if (ret >= 0) {
- fp->_offset += ret;
- } else {
- fp->_flags &= ~__SOFF; /* paranoia */
- }
- return (ret);
-}
-
-int __swrite(FILE *fp, const char *buf, int n)
-{
- if (fp->_flags & __SAPP)
- (void) lseek(fp->_file, (off_t)0, SEEK_END);
- fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */
- if (fd_table[fp->_file]->ops->use_kfds < 2) {
- return(fd_table[fp->_file]->ops->write(fd_table[fp->_file]->fd,
- fd_table[fp->_file]->flags, buf, n, NULL));
- } else {
- pthread_ssize_t (*writefn)() = fd_table[fp->_file]->ops->write;
- return(writefn(fd_table[fp->_file]->fd,buf,n));
- }
-}
-
-fpos_t __sseek(FILE *fp, off_t offset, int whence)
-{
- register fpos_t ret;
-
- ret = (fpos_t)lseek(fp->_file, offset, whence);
- if (ret == -1L)
- fp->_flags &= ~__SOFF;
- else {
- fp->_flags |= __SOFF;
- fp->_offset = ret;
- }
- return (ret);
-}
-
-int __sclose(FILE *fp)
-{
- return (close(fp->_file));
-}
diff --git a/mit-pthreads/stdio/strerror.c b/mit-pthreads/stdio/strerror.c
deleted file mode 100644
index d35235e63b0..00000000000
--- a/mit-pthreads/stdio/strerror.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <string.h>
-#if defined(__NetBSD__)
-#include <errno.h>
-#endif
-
-char *
-strerror(num)
- int num;
-{
-#if !defined(__NetBSD__)
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif
-#define UPREFIX "Unknown error: "
- static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
- register unsigned int errnum;
- register char *p, *t;
- char tmp[40];
-
- errnum = num; /* convert to unsigned */
- if (errnum < sys_nerr)
- return((char *)sys_errlist[errnum]);
-
- /* Do this by hand, so we don't include stdio(3). */
- t = tmp;
- do {
- *t++ = "0123456789"[errnum % 10];
- } while (errnum /= 10);
- for (p = ebuf + sizeof(UPREFIX) - 1;;) {
- *p++ = *--t;
- if (t <= tmp)
- break;
- }
- return(ebuf);
-}
diff --git a/mit-pthreads/stdio/tempnam.c b/mit-pthreads/stdio/tempnam.c
deleted file mode 100644
index 88150a18019..00000000000
--- a/mit-pthreads/stdio/tempnam.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)tempnam.c 5.1 (Berkeley) 2/22/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-/* #include <paths.h> */
-
-char *
-tempnam(dir, pfx)
- const char *dir, *pfx;
-{
- int sverrno;
- char *f, *name;
-
- if (!(name = malloc(MAXPATHLEN)))
- return(NULL);
-
- if (!pfx)
- pfx = "tmp.";
-
- if (f = getenv("TMPDIR")) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
- if (f = mktemp(name))
- return(f);
- }
-
- if (f = (char *)dir) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
- if (f = mktemp(name))
- return(f);
- }
-
- f = P_tmpdir;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
- if (f = mktemp(name))
- return(f);
-
- f = _PATH_TMP;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
- if (f = mktemp(name))
- return(f);
-
- sverrno = errno;
- free(name);
- errno = sverrno;
- return(NULL);
-}
diff --git a/mit-pthreads/stdio/tmpfile.c b/mit-pthreads/stdio/tmpfile.c
deleted file mode 100644
index 471bed33716..00000000000
--- a/mit-pthreads/stdio/tmpfile.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)tmpfile.c 5.4 (Berkeley) 5/27/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <paths.h>
-
-FILE *
-tmpfile()
-{
- sigset_t set, oset;
- FILE *fp;
- int fd, sverrno;
-#define TRAILER "tmp.XXXXXX"
- char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)];
-
- memcpy(buf, _PATH_TMP, sizeof(_PATH_TMP) - 1);
- memcpy( buf + sizeof(_PATH_TMP) - 1, TRAILER, sizeof(TRAILER));
-
- sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
-
- fd = mkstemp(buf);
- if (fd != -1)
- (void)unlink(buf);
-
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
-
- if (fd == -1)
- return (NULL);
-
- if (!(fp = fdopen(fd, "w+"))) {
- sverrno = errno;
- (void)close(fd);
- errno = sverrno;
- return (NULL);
- }
- return (fp);
-}
diff --git a/mit-pthreads/stdio/tmpnam.c b/mit-pthreads/stdio/tmpnam.c
deleted file mode 100644
index 8d65b21b037..00000000000
--- a/mit-pthreads/stdio/tmpnam.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)tmpnam.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <unistd.h>
-#include <stdio.h>
-
-char *
-tmpnam(s)
- char *s;
-{
- static char buf[L_tmpnam];
-
- if (s == NULL)
- s = buf;
- (void)snprintf(s, L_tmpnam, "%stmp.XXXXXX", P_tmpdir);
- return(mktemp(s));
-}
diff --git a/mit-pthreads/stdio/ungetc.c b/mit-pthreads/stdio/ungetc.c
deleted file mode 100644
index e035f93d5f2..00000000000
--- a/mit-pthreads/stdio/ungetc.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)ungetc.c 5.6 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-
-/*
- * Expand the ungetc buffer `in place'. That is, adjust fp->_p when
- * the buffer moves, so that it points the same distance from the end,
- * and move the bytes in the buffer around as necessary so that they
- * are all at the end (stack-style).
- */
-static
-__submore(fp)
- register FILE *fp;
-{
- register int i;
- register unsigned char *p;
-
- if (fp->_ub._base == fp->_ubuf) {
- /*
- * Get a new buffer (rather than expanding the old one).
- */
- if ((p = malloc((size_t)BUFSIZ)) == NULL)
- return (EOF);
- fp->_ub._base = p;
- fp->_ub._size = BUFSIZ;
- p += BUFSIZ - sizeof(fp->_ubuf);
- for (i = sizeof(fp->_ubuf); --i >= 0;)
- p[i] = fp->_ubuf[i];
- fp->_p = p;
- return (0);
- }
- i = fp->_ub._size;
- p = realloc(fp->_ub._base, i << 1);
- if (p == NULL)
- return (EOF);
- (void) memcpy((void *)(p + i), (void *)p, (size_t)i);
- fp->_p = p + i;
- fp->_ub._base = p;
- fp->_ub._size = i << 1;
- return (0);
-}
-
-ungetc(c, fp)
- int c;
- register FILE *fp;
-{
- if (c == EOF)
- return (EOF);
- __sinit ();
-
- flockfile(fp);
- if ((fp->_flags & __SRD) == 0) {
- /*
- * Not already reading: no good unless reading-and-writing.
- * Otherwise, flush any current write stuff.
- */
- if ((fp->_flags & __SRW) == 0)
- c = EOF;
- goto ungetc_end;
- if (fp->_flags & __SWR) {
- if (__sflush(fp))
- c = EOF;
- goto ungetc_end;
- fp->_flags &= ~__SWR;
- fp->_w = 0;
- fp->_lbfsize = 0;
- }
- fp->_flags |= __SRD;
- }
- c = (unsigned char)c;
-
- /*
- * If we are in the middle of ungetc'ing, just continue.
- * This may require expanding the current ungetc buffer.
- */
- if (HASUB(fp)) {
- if (fp->_r >= fp->_ub._size && __submore(fp))
- return (EOF);
- *--fp->_p = c;
- fp->_r++;
- goto ungetc_end;
- }
-
- /*
- * If we can handle this by simply backing up, do so,
- * but never replace the original character.
- * (This makes sscanf() work when scanning `const' data.)
- */
- if (fp->_bf._base != NULL && fp->_p > fp->_bf._base &&
- fp->_p[-1] == c) {
- fp->_p--;
- fp->_r++;
- goto ungetc_end;
- }
-
- /*
- * Create an ungetc buffer.
- * Initially, we will use the `reserve' buffer.
- */
- fp->_ur = fp->_r;
- fp->_up = fp->_p;
- fp->_ub._base = fp->_ubuf;
- fp->_ub._size = sizeof(fp->_ubuf);
- fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
- fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
- fp->_r = 1;
-
-ungetc_end:;
- funlockfile(fp);
- return (c);
-}
diff --git a/mit-pthreads/stdio/vfprintf.c b/mit-pthreads/stdio/vfprintf.c
deleted file mode 100644
index fd990bb1889..00000000000
--- a/mit-pthreads/stdio/vfprintf.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Actual printf innards.
- *
- * This code is large and complicated...
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "local.h"
-#include "fvwrite.h"
-
-/* Define FLOATING_POINT to get floating point. */
-#define FLOATING_POINT
-
-/*
- * Flush out all the vectors defined by the given uio,
- * then reset it so that it can be reused.
- */
-static int
-__sprint(fp, uio)
- register FILE* fp;
- register struct __suio *uio;
-{
- register int err;
-
- if (uio->uio_resid == 0) {
- uio->uio_iovcnt = 0;
- return (0);
- }
- err = __sfvwrite(fp, uio);
- uio->uio_resid = 0;
- uio->uio_iovcnt = 0;
- return (err);
-}
-
-/*
- * Helper function for `fprintf to unbuffered unix file': creates a
- * temporary buffer. We only work on write-only files; this avoids
- * worries about ungetc buffers and so forth.
- */
-static int
-__sbprintf(fp, fmt, ap)
- FILE *fp;
- const char *fmt;
- pthread_va_list ap;
-{
- unsigned char buf[BUFSIZ];
- FILE fake;
- int ret;
-
- /* copy the important variables */
- fake._flags = fp->_flags & ~__SNBF;
- fake._file = fp->_file;
-
- /* set up the buffer */
- fake._bf._base = fake._p = buf;
- fake._bf._size = fake._w = sizeof(buf);
- fake._lbfsize = 0; /* not actually used, but Just In Case */
-
- /* do the work, then copy any error status */
- ret = vfprintf(&fake, fmt, ap);
- if (ret >= 0 && fflush(&fake))
- ret = EOF;
- if (fake._flags & __SERR)
- fp->_flags |= __SERR;
- return (ret);
-}
-
-
-#ifdef FLOATING_POINT
-#include <locale.h>
-#include <math.h>
-#include "floatio.h"
-
-#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
-#define DEFPREC 6
-
-static char *cvt __P_((double, int, int, char *, int *, int, int *));
-static int exponent __P_((char *, int, int));
-
-#else /* no FLOATING_POINT */
-
-#define BUF 40
-
-#endif /* FLOATING_POINT */
-
-
-/*
- * Macros for converting digits to letters and vice versa
- */
-#define to_digit(c) ((c) - '0')
-#define is_digit(c) ((unsigned)to_digit(c) <= 9)
-#define to_char(n) ((n) + '0')
-
-/*
- * Flags used during conversion.
- */
-#define ALT 0x001 /* alternate form */
-#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
-#define LADJUST 0x004 /* left adjustment */
-#define LONGDBL 0x008 /* long double; unimplemented */
-#define LONGINT 0x010 /* long integer */
-#define QUADINT 0x020 /* quad integer */
-#define SHORTINT 0x040 /* short integer */
-#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
-#define FPT 0x100 /* Floating point number */
-int
-vfprintf(fp, fmt0, ap)
- FILE *fp;
- const char *fmt0;
- pthread_va_list ap;
-{
- register char *fmt; /* format string */
- register int ch; /* character from fmt */
- register int n; /* handy integer (short term usage) */
- register char *cp; /* handy char pointer (short term usage) */
- register struct __siov *iovp;/* for PRINT macro */
- register int flags; /* flags as above */
- int ret; /* return value accumulator */
- int width; /* width from format (%8d), or 0 */
- int prec; /* precision from format (%.3d), or -1 */
- char sign; /* sign prefix (' ', '+', '-', or \0) */
-#ifdef FLOATING_POINT
- char softsign; /* temporary negative sign for floats */
- double _double; /* double precision arguments %[eEfgG] */
- int expt; /* integer value of exponent */
- int expsize; /* character count for expstr */
- int ndig; /* actual number of digits returned by cvt */
- char expstr[7]; /* buffer for exponent string */
-#endif
-
-#if defined (__alpha) && !defined(_GNUC_)
-#define quad_t long
-#define u_quad_t unsigned long
-#else /* gcc has builtin quad type (long long) SOS */
-#define quad_t long long
-#define u_quad_t unsigned long long
-#endif
-
- u_quad_t _uquad; /* integer arguments %[diouxX] */
- enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
- int dprec; /* a copy of prec if [diouxX], 0 otherwise */
- int fieldsz; /* field size expanded by sign, etc */
- int realsz; /* field size expanded by dprec */
- int size; /* size of converted field or string */
- char *xdigs; /* digits for [xX] conversion */
-#define NIOV 8
- struct __suio uio; /* output information: summary */
- struct __siov iov[NIOV];/* ... and individual io vectors */
- char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
- char ox[2]; /* space for 0x hex-prefix */
-
- /*
- * Choose PADSIZE to trade efficiency vs. size. If larger printf
- * fields occur frequently, increase PADSIZE and make the initialisers
- * below longer.
- */
-#define PADSIZE 16 /* pad chunk size */
- static char blanks[PADSIZE] =
- {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
- static char zeroes[PADSIZE] =
- {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-
- /*
- * BEWARE, these `goto error' on error, and PAD uses `n'.
- */
-#define PRINT(ptr, len) { \
- iovp->iov_base = (ptr); \
- iovp->iov_len = (len); \
- uio.uio_resid += (len); \
- iovp++; \
- if (++uio.uio_iovcnt >= NIOV) { \
- if (__sprint(fp, &uio)) \
- goto error; \
- iovp = iov; \
- } \
-}
-#define PAD(howmany, with) { \
- if ((n = (howmany)) > 0) { \
- while (n > PADSIZE) { \
- PRINT(with, PADSIZE); \
- n -= PADSIZE; \
- } \
- PRINT(with, n); \
- } \
-}
-#define FLUSH() { \
- if (uio.uio_resid && __sprint(fp, &uio)) \
- goto error; \
- uio.uio_iovcnt = 0; \
- iovp = iov; \
-}
-
- /*
- * To extend shorts properly, we need both signed and unsigned
- * argument extraction methods.
- */
-#define SARG() \
- (flags&QUADINT ? va_arg(ap, quad_t) : \
- flags&LONGINT ? va_arg(ap, long) : \
- flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
- (long)va_arg(ap, int))
-#define UARG() \
- (flags&QUADINT ? va_arg(ap, u_quad_t) : \
- flags&LONGINT ? va_arg(ap, u_long) : \
- flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
- (u_long)va_arg(ap, u_int))
-
- flockfile(fp);
-
- /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
- if (cantwrite(fp))
- return (EOF);
-
- /* optimise fprintf(stderr) (and other unbuffered Unix files) */
- if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
- fp->_file >= 0) {
- ret = (__sbprintf(fp, fmt0, ap));
- funlockfile(fp);
- return(ret);
- }
-
- fmt = (char *)fmt0;
- uio.uio_iov = iovp = iov;
- uio.uio_resid = 0;
- uio.uio_iovcnt = 0;
- ret = 0;
-
- /*
- * Scan the format for conversions (`%' character).
- */
- for (;;) {
- for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
- /* void */;
- if ((n = fmt - cp) != 0) {
- PRINT(cp, n);
- ret += n;
- }
- if (ch == '\0')
- goto done;
- fmt++; /* skip over '%' */
-
- flags = 0;
- dprec = 0;
- width = 0;
- prec = -1;
- sign = '\0';
-
-rflag: ch = *fmt++;
-reswitch: switch (ch) {
- case ' ':
- /*
- * ``If the space and + flags both appear, the space
- * flag will be ignored.''
- * -- ANSI X3J11
- */
- if (!sign)
- sign = ' ';
- goto rflag;
- case '#':
- flags |= ALT;
- goto rflag;
- case '*':
- /*
- * ``A negative field width argument is taken as a
- * - flag followed by a positive field width.''
- * -- ANSI X3J11
- * They don't exclude field widths read from args.
- */
- if ((width = va_arg(ap, int)) >= 0)
- goto rflag;
- width = -width;
- /* FALLTHROUGH */
- case '-':
- flags |= LADJUST;
- goto rflag;
- case '+':
- sign = '+';
- goto rflag;
- case '.':
- if ((ch = *fmt++) == '*') {
- n = va_arg(ap, int);
- prec = n < 0 ? -1 : n;
- goto rflag;
- }
- n = 0;
- while (is_digit(ch)) {
- n = 10 * n + to_digit(ch);
- ch = *fmt++;
- }
- prec = n < 0 ? -1 : n;
- goto reswitch;
- case '0':
- /*
- * ``Note that 0 is taken as a flag, not as the
- * beginning of a field width.''
- * -- ANSI X3J11
- */
- flags |= ZEROPAD;
- goto rflag;
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- n = 0;
- do {
- n = 10 * n + to_digit(ch);
- ch = *fmt++;
- } while (is_digit(ch));
- width = n;
- goto reswitch;
-#ifdef FLOATING_POINT
- case 'L':
- flags |= LONGDBL;
- goto rflag;
-#endif
- case 'h':
- flags |= SHORTINT;
- goto rflag;
- case 'l':
- flags |= LONGINT;
- goto rflag;
- case 'q':
- flags |= QUADINT;
- goto rflag;
- case 'c':
- *(cp = buf) = va_arg(ap, int);
- size = 1;
- sign = '\0';
- break;
- case 'D':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'd':
- case 'i':
- _uquad = SARG();
- if ((quad_t)_uquad < 0) {
- _uquad = -_uquad;
- sign = '-';
- }
- base = DEC;
- goto number;
-#ifdef FLOATING_POINT
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
- if (prec == -1) {
- prec = DEFPREC;
- } else if ((ch == 'g' || ch == 'G') && prec == 0) {
- prec = 1;
- }
-
- if (flags & LONGDBL) {
- _double = (double) va_arg(ap, long double);
- } else {
- _double = va_arg(ap, double);
- }
-
- /* do this before tricky precision changes */
- /* if (isinf(_double)) {
- if (_double < 0)
- sign = '-';
- cp = "Inf";
- size = 3;
- break;
- } */
-/* if (isnan(_double)) {
- cp = "NaN";
- size = 3;
- break;
- } */
-
- flags |= FPT;
- cp = cvt(_double, prec, flags, &softsign,
- &expt, ch, &ndig);
- if (ch == 'g' || ch == 'G') {
- if (expt <= -4 || expt > prec)
- ch = (ch == 'g') ? 'e' : 'E';
- else
- ch = 'g';
- }
- if (ch <= 'e') { /* 'e' or 'E' fmt */
- --expt;
- expsize = exponent(expstr, expt, ch);
- size = expsize + ndig;
- if (ndig > 1 || flags & ALT)
- ++size;
- } else if (ch == 'f') { /* f fmt */
- if (expt > 0) {
- size = expt;
- if (prec || flags & ALT)
- size += prec + 1;
- } else /* "0.X" */
- size = prec + 2;
- } else if (expt >= ndig) { /* fixed g fmt */
- size = expt;
- if (flags & ALT)
- ++size;
- } else
- size = ndig + (expt > 0 ?
- 1 : 2 - expt);
-
- if (softsign)
- sign = '-';
- break;
-#endif /* FLOATING_POINT */
- case 'n':
- if (flags & QUADINT)
- *va_arg(ap, quad_t *) = ret;
- else if (flags & LONGINT)
- *va_arg(ap, long *) = ret;
- else if (flags & SHORTINT)
- *va_arg(ap, short *) = ret;
- else
- *va_arg(ap, int *) = ret;
- continue; /* no output */
- case 'O':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'o':
- _uquad = UARG();
- base = OCT;
- goto nosign;
- case 'p':
- /*
- * ``The argument shall be a pointer to void. The
- * value of the pointer is converted to a sequence
- * of printable characters, in an implementation-
- * defined manner.''
- * -- ANSI X3J11
- */
- /* NOSTRICT */
- _uquad = (u_quad_t)(size_t)va_arg(ap, void *);
- base = HEX;
- xdigs = "0123456789abcdef";
- flags |= HEXPREFIX;
- ch = 'x';
- goto nosign;
- case 's':
- if ((cp = va_arg(ap, char *)) == NULL)
- cp = "(null)";
- if (prec >= 0) {
- /*
- * can't use strlen; can only look for the
- * NUL in the first `prec' characters, and
- * strlen() will go further.
- */
- char *p = memchr(cp, 0, prec);
-
- if (p != NULL) {
- size = p - cp;
- if (size > prec)
- size = prec;
- } else
- size = prec;
- } else
- size = strlen(cp);
- sign = '\0';
- break;
- case 'U':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'u':
- _uquad = UARG();
- base = DEC;
- goto nosign;
- case 'X':
- xdigs = "0123456789ABCDEF";
- goto hex;
- case 'x':
- xdigs = "0123456789abcdef";
-hex: _uquad = UARG();
- base = HEX;
- /* leading 0x/X only if non-zero */
- if (flags & ALT && _uquad != 0)
- flags |= HEXPREFIX;
-
- /* unsigned conversions */
-nosign: sign = '\0';
- /*
- * ``... diouXx conversions ... if a precision is
- * specified, the 0 flag will be ignored.''
- * -- ANSI X3J11
- */
-number: if ((dprec = prec) >= 0)
- flags &= ~ZEROPAD;
-
- /*
- * ``The result of converting a zero value with an
- * explicit precision of zero is no characters.''
- * -- ANSI X3J11
- */
- cp = buf + BUF;
- if (_uquad != 0 || prec != 0) {
- /*
- * Unsigned mod is hard, and unsigned mod
- * by a constant is easier than that by
- * a variable; hence this switch.
- */
- switch (base) {
- case OCT:
- do {
- *--cp = to_char(_uquad & 7);
- _uquad >>= 3;
- } while (_uquad);
- /* handle octal leading 0 */
- if (flags & ALT && *cp != '0')
- *--cp = '0';
- break;
-
- case DEC:
- /* many numbers are 1 digit */
- while (_uquad >= 10) {
- *--cp = to_char(_uquad % 10);
- _uquad /= 10;
- }
- *--cp = to_char(_uquad);
- break;
-
- case HEX:
- do {
- *--cp = xdigs[_uquad & 15];
- _uquad >>= 4;
- } while (_uquad);
- break;
-
- default:
- cp = "bug in vfprintf: bad base";
- size = strlen(cp);
- goto skipsize;
- }
- }
- size = buf + BUF - cp;
- skipsize:
- break;
- default: /* "%?" prints ?, unless ? is NUL */
- if (ch == '\0')
- goto done;
- /* pretend it was %c with argument ch */
- cp = buf;
- *cp = ch;
- size = 1;
- sign = '\0';
- break;
- }
-
- /*
- * All reasonable formats wind up here. At this point, `cp'
- * points to a string which (if not flags&LADJUST) should be
- * padded out to `width' places. If flags&ZEROPAD, it should
- * first be prefixed by any sign or other prefix; otherwise,
- * it should be blank padded before the prefix is emitted.
- * After any left-hand padding and prefixing, emit zeroes
- * required by a decimal [diouxX] precision, then print the
- * string proper, then emit zeroes required by any leftover
- * floating precision; finally, if LADJUST, pad with blanks.
- *
- * Compute actual size, so we know how much to pad.
- * fieldsz excludes decimal prec; realsz includes it.
- */
- fieldsz = size;
- if (sign)
- fieldsz++;
- else if (flags & HEXPREFIX)
- fieldsz += 2;
- realsz = dprec > fieldsz ? dprec : fieldsz;
-
- /* right-adjusting blank padding */
- if ((flags & (LADJUST|ZEROPAD)) == 0)
- PAD(width - realsz, blanks);
-
- /* prefix */
- if (sign) {
- PRINT(&sign, 1);
- } else if (flags & HEXPREFIX) {
- ox[0] = '0';
- ox[1] = ch;
- PRINT(ox, 2);
- }
-
- /* right-adjusting zero padding */
- if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
- PAD(width - realsz, zeroes);
-
- /* leading zeroes from decimal precision */
- PAD(dprec - fieldsz, zeroes);
-
- /* the string or number proper */
-#ifdef FLOATING_POINT
- if ((flags & FPT) == 0) {
- PRINT(cp, size);
- } else { /* glue together f_p fragments */
- if (ch >= 'f') { /* 'f' or 'g' */
- if (_double == 0) {
- /* kludge for __dtoa irregularity */
- if (expt >= ndig && (flags & ALT) == 0) {
- PRINT("0", 1);
- } else {
- PRINT("0.", 2);
- PAD(ndig - 1, zeroes);
- }
- } else if (expt <= 0) {
- PRINT("0.", 2);
- PAD(-expt, zeroes);
- PRINT(cp, ndig);
- } else if (expt >= ndig) {
- PRINT(cp, ndig);
- PAD(expt - ndig, zeroes);
- if (flags & ALT)
- PRINT(".", 1);
- } else {
- PRINT(cp, expt);
- cp += expt;
- PRINT(".", 1);
- PRINT(cp, ndig-expt);
- }
- } else { /* 'e' or 'E' */
- if (ndig > 1 || flags & ALT) {
- ox[0] = *cp++;
- ox[1] = '.';
- PRINT(ox, 2);
- if (_double || flags & ALT == 0) {
- PRINT(cp, ndig-1);
- } else /* 0.[0..] */
- /* __dtoa irregularity */
- PAD(ndig - 1, zeroes);
- } else /* XeYYY */
- PRINT(cp, 1);
- PRINT(expstr, expsize);
- }
- }
-#else
- PRINT(cp, size);
-#endif
- /* left-adjusting padding (always blank) */
- if (flags & LADJUST)
- PAD(width - realsz, blanks);
-
- /* finally, adjust ret */
- ret += width > realsz ? width : realsz;
-
- FLUSH(); /* copy out the I/O vectors */
- }
-done:
- FLUSH();
-error:
- if (__sferror(fp))
- ret = EOF;
- funlockfile(fp);
- return (ret);
-}
-
-#ifdef FLOATING_POINT
-
-extern char *__dtoa __P_((double, int, int, int *, int *, char **));
-
-static char *
-cvt(value, ndigits, flags, sign, decpt, ch, length)
- double value;
- int ndigits, flags, *decpt, ch, *length;
- char *sign;
-{
- int mode, dsgn;
- char *digits, *bp, *rve;
-
- if (ch == 'f') {
- mode = 3; /* ndigits after the decimal point */
- } else {
- /* To obtain ndigits after the decimal point for the 'e'
- * and 'E' formats, round to ndigits + 1 significant
- * figures.
- */
- if (ch == 'e' || ch == 'E') {
- ndigits++;
- }
- mode = 2; /* ndigits significant digits */
- }
-
- if (value < 0) {
- value = -value;
- *sign = '-';
- } else
- *sign = '\000';
-/* #if !defined(__alpha__) && !defined(hpux) */
-#ifndef THIS_IS_NEVER_DEFINED
- digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
-#else
- { char *ecvt(double,int,int*,int*);
-
- digits = ecvt(value, ndigits, decpt, &dsgn);
- rve = (digits + (int)strlen(digits));
- }
-#endif
- if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
- bp = digits + ndigits;
- if (ch == 'f') {
- if (*digits == '0' && value)
- *decpt = -ndigits + 1;
- bp += *decpt;
- }
- if (value == 0) /* kludge for __dtoa irregularity */
- rve = bp;
- while (rve < bp)
- *rve++ = '0';
- }
- *length = rve - digits;
- return (digits);
-}
-
-static int
-exponent(p0, exp, fmtch)
- char *p0;
- int exp, fmtch;
-{
- register char *p, *t;
- char expbuf[MAXEXP];
-
- p = p0;
- *p++ = fmtch;
- if (exp < 0) {
- exp = -exp;
- *p++ = '-';
- }
- else
- *p++ = '+';
- t = expbuf + MAXEXP;
- if (exp > 9) {
- do {
- *--t = to_char(exp % 10);
- } while ((exp /= 10) > 9);
- *--t = to_char(exp);
- for (; t < expbuf + MAXEXP; *p++ = *t++);
- }
- else {
- *p++ = '0';
- *p++ = to_char(exp);
- }
- return (p - p0);
-}
-#endif /* FLOATING_POINT */
diff --git a/mit-pthreads/stdio/vfscanf.c b/mit-pthreads/stdio/vfscanf.c
deleted file mode 100644
index f6d0a40aa51..00000000000
--- a/mit-pthreads/stdio/vfscanf.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vfscanf.c 5.7 (Berkeley) 12/14/92";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "local.h"
-
-#define FLOATING_POINT
-
-#include "floatio.h"
-#define BUF 513 /* Maximum length of numeric string. */
-
-/*
- * Flags used during conversion.
- */
-#define LONG 0x01 /* l: long or double */
-#define LONGDBL 0x02 /* L: long double; unimplemented */
-#define SHORT 0x04 /* h: short */
-#define SUPPRESS 0x08 /* suppress assignment */
-#define POINTER 0x10 /* weird %p pointer (`fake hex') */
-#define NOSKIP 0x20 /* do not skip blanks */
-
-/*
- * The following are used in numeric conversions only:
- * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
- * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
- */
-#define SIGNOK 0x40 /* +/- is (still) legal */
-#define NDIGITS 0x80 /* no digits detected */
-
-#define DPTOK 0x100 /* (float) decimal point is still legal */
-#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
-
-#define PFXOK 0x100 /* 0x prefix is (still) legal */
-#define NZDIGITS 0x200 /* no zero digits detected */
-
-/*
- * Conversion types.
- */
-#define CT_CHAR 0 /* %c conversion */
-#define CT_CCL 1 /* %[...] conversion */
-#define CT_STRING 2 /* %s conversion */
-#define CT_INT 3 /* integer, i.e., strtol or strtoul */
-#define CT_FLOAT 4 /* floating, i.e., strtod */
-
-#define u_char unsigned char
-#define u_long unsigned long
-
-static u_char *__sccl();
-
-/*
- * vfscanf
- */
-__svfscanf(fp, fmt0, ap)
- register FILE *fp;
- char const *fmt0;
- pthread_va_list ap;
-{
- register u_char *fmt = (u_char *)fmt0;
- register int c; /* character from format, or conversion */
- register size_t width; /* field width, or 0 */
- register char *p; /* points into all kinds of strings */
- register int n; /* handy integer */
- register int flags; /* flags as defined above */
- register char *p0; /* saves original value of p when necessary */
- int nassigned; /* number of fields assigned */
- int nread; /* number of characters consumed from fp */
- int base; /* base argument to strtol/strtoul */
- u_long (*ccfn)(); /* conversion function (strtol/strtoul) */
- char ccltab[256]; /* character class table for %[...] */
- char buf[BUF]; /* buffer for numeric conversions */
-
- /* `basefix' is used to avoid `if' tests in the integer scanner */
- static short basefix[17] =
- { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
-
- nassigned = 0;
- nread = 0;
- base = 0; /* XXX just to keep gcc happy */
- ccfn = NULL; /* XXX just to keep gcc happy */
- for (;;) {
- c = *fmt++;
- if (c == 0)
- return (nassigned);
- if (isspace(c)) {
- for (;;) {
- if (fp->_r <= 0 && __srefill(fp))
- return (nassigned);
- if (!isspace(*fp->_p))
- break;
- nread++, fp->_r--, fp->_p++;
- }
- continue;
- }
- if (c != '%')
- goto literal;
- width = 0;
- flags = 0;
- /*
- * switch on the format. continue if done;
- * break once format type is derived.
- */
-again: c = *fmt++;
- switch (c) {
- case '%':
-literal:
- if (fp->_r <= 0 && __srefill(fp))
- goto input_failure;
- if (*fp->_p != c)
- goto match_failure;
- fp->_r--, fp->_p++;
- nread++;
- continue;
-
- case '*':
- flags |= SUPPRESS;
- goto again;
- case 'l':
- flags |= LONG;
- goto again;
- case 'L':
- flags |= LONGDBL;
- goto again;
- case 'h':
- flags |= SHORT;
- goto again;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- width = width * 10 + c - '0';
- goto again;
-
- /*
- * Conversions.
- * Those marked `compat' are for 4.[123]BSD compatibility.
- *
- * (According to ANSI, E and X formats are supposed
- * to the same as e and x. Sorry about that.)
- */
- case 'D': /* compat */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'd':
- c = CT_INT;
- ccfn = (u_long (*)())strtol;
- base = 10;
- break;
-
- case 'i':
- c = CT_INT;
- ccfn = (u_long (*)())strtol;
- base = 0;
- break;
-
- case 'O': /* compat */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'o':
- c = CT_INT;
- ccfn = strtoul;
- base = 8;
- break;
-
- case 'u':
- c = CT_INT;
- ccfn = strtoul;
- base = 10;
- break;
-
- case 'X': /* compat XXX */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'x':
- flags |= PFXOK; /* enable 0x prefixing */
- c = CT_INT;
- ccfn = strtoul;
- base = 16;
- break;
-
-#ifdef FLOATING_POINT
- case 'E': /* compat XXX */
- case 'F': /* compat */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'e': case 'f': case 'g':
- c = CT_FLOAT;
- break;
-#endif
-
- case 's':
- c = CT_STRING;
- break;
-
- case '[':
- fmt = __sccl(ccltab, fmt);
- flags |= NOSKIP;
- c = CT_CCL;
- break;
-
- case 'c':
- flags |= NOSKIP;
- c = CT_CHAR;
- break;
-
- case 'p': /* pointer format is like hex */
- flags |= POINTER | PFXOK;
- c = CT_INT;
- ccfn = strtoul;
- base = 16;
- break;
-
- case 'n':
- if (flags & SUPPRESS) /* ??? */
- continue;
- if (flags & SHORT)
- *va_arg(ap, short *) = nread;
- else if (flags & LONG)
- *va_arg(ap, long *) = nread;
- else
- *va_arg(ap, int *) = nread;
- continue;
-
- /*
- * Disgusting backwards compatibility hacks. XXX
- */
- case '\0': /* compat */
- return (EOF);
-
- default: /* compat */
- if (isupper(c))
- flags |= LONG;
- c = CT_INT;
- ccfn = (u_long (*)())strtol;
- base = 10;
- break;
- }
-
- /*
- * We have a conversion that requires input.
- */
- if (fp->_r <= 0 && __srefill(fp))
- goto input_failure;
-
- /*
- * Consume leading white space, except for formats
- * that suppress this.
- */
- if ((flags & NOSKIP) == 0) {
- while (isspace(*fp->_p)) {
- nread++;
- if (--fp->_r > 0)
- fp->_p++;
- else if (__srefill(fp))
- goto input_failure;
- }
- /*
- * Note that there is at least one character in
- * the buffer, so conversions that do not set NOSKIP
- * ca no longer result in an input failure.
- */
- }
-
- /*
- * Do the conversion.
- */
- switch (c) {
-
- case CT_CHAR:
- /* scan arbitrary characters (sets NOSKIP) */
- if (width == 0)
- width = 1;
- if (flags & SUPPRESS) {
- size_t sum = 0;
- for (;;) {
- if ((n = fp->_r) < width) {
- sum += n;
- width -= n;
- fp->_p += n;
- if (__srefill(fp)) {
- if (sum == 0)
- goto input_failure;
- break;
- }
- } else {
- sum += width;
- fp->_r -= width;
- fp->_p += width;
- break;
- }
- }
- nread += sum;
- } else {
- size_t r = fread((void *)va_arg(ap, char *), 1,
- width, fp);
-
- if (r == 0)
- goto input_failure;
- nread += r;
- nassigned++;
- }
- break;
-
- case CT_CCL:
- /* scan a (nonempty) character class (sets NOSKIP) */
- if (width == 0)
- width = ~0; /* `infinity' */
- /* take only those things in the class */
- if (flags & SUPPRESS) {
- n = 0;
- while (ccltab[*fp->_p]) {
- n++, fp->_r--, fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp)) {
- if (n == 0)
- goto input_failure;
- break;
- }
- }
- if (n == 0)
- goto match_failure;
- } else {
- p0 = p = va_arg(ap, char *);
- while (ccltab[*fp->_p]) {
- fp->_r--;
- *p++ = *fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp)) {
- if (p == p0)
- goto input_failure;
- break;
- }
- }
- n = p - p0;
- if (n == 0)
- goto match_failure;
- *p = 0;
- nassigned++;
- }
- nread += n;
- break;
-
- case CT_STRING:
- /* like CCL, but zero-length string OK, & no NOSKIP */
- if (width == 0)
- width = ~0;
- if (flags & SUPPRESS) {
- n = 0;
- while (!isspace(*fp->_p)) {
- n++, fp->_r--, fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp))
- break;
- }
- nread += n;
- } else {
- p0 = p = va_arg(ap, char *);
- while (!isspace(*fp->_p)) {
- fp->_r--;
- *p++ = *fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp))
- break;
- }
- *p = 0;
- nread += p - p0;
- nassigned++;
- }
- continue;
-
- case CT_INT:
- /* scan an integer as if by strtol/strtoul */
-#ifdef hardway
- if (width == 0 || width > sizeof(buf) - 1)
- width = sizeof(buf) - 1;
-#else
- /* size_t is unsigned, hence this optimisation */
- if (--width > sizeof(buf) - 2)
- width = sizeof(buf) - 2;
- width++;
-#endif
- flags |= SIGNOK | NDIGITS | NZDIGITS;
- for (p = buf; width; width--) {
- c = *fp->_p;
- /*
- * Switch on the character; `goto ok'
- * if we accept it as a part of number.
- */
- switch (c) {
-
- /*
- * The digit 0 is always legal, but is
- * special. For %i conversions, if no
- * digits (zero or nonzero) have been
- * scanned (only signs), we will have
- * base==0. In that case, we should set
- * it to 8 and enable 0x prefixing.
- * Also, if we have not scanned zero digits
- * before this, do not turn off prefixing
- * (someone else will turn it off if we
- * have scanned any nonzero digits).
- */
- case '0':
- if (base == 0) {
- base = 8;
- flags |= PFXOK;
- }
- if (flags & NZDIGITS)
- flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
- else
- flags &= ~(SIGNOK|PFXOK|NDIGITS);
- goto ok;
-
- /* 1 through 7 always legal */
- case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- base = basefix[base];
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* digits 8 and 9 ok iff decimal or hex */
- case '8': case '9':
- base = basefix[base];
- if (base <= 8)
- break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* letters ok iff hex */
- case 'A': case 'B': case 'C':
- case 'D': case 'E': case 'F':
- case 'a': case 'b': case 'c':
- case 'd': case 'e': case 'f':
- /* no need to fix base here */
- if (base <= 10)
- break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* sign ok only as first character */
- case '+': case '-':
- if (flags & SIGNOK) {
- flags &= ~SIGNOK;
- goto ok;
- }
- break;
-
- /* x ok iff flag still set & 2nd char */
- case 'x': case 'X':
- if (flags & PFXOK && p == buf + 1) {
- base = 16; /* if %i */
- flags &= ~PFXOK;
- goto ok;
- }
- break;
- }
-
- /*
- * If we got here, c is not a legal character
- * for a number. Stop accumulating digits.
- */
- break;
- ok:
- /*
- * c is legal: store it and look at the next.
- */
- *p++ = c;
- if (--fp->_r > 0)
- fp->_p++;
- else if (__srefill(fp))
- break; /* EOF */
- }
- /*
- * If we had only a sign, it is no good; push
- * back the sign. If the number ends in `x',
- * it was [sign] '0' 'x', so push back the x
- * and treat it as [sign] '0'.
- */
- if (flags & NDIGITS) {
- if (p > buf)
- (void) ungetc(*(u_char *)--p, fp);
- goto match_failure;
- }
- c = ((u_char *)p)[-1];
- if (c == 'x' || c == 'X') {
- --p;
- (void) ungetc(c, fp);
- }
- if ((flags & SUPPRESS) == 0) {
- u_long res;
-
- *p = 0;
- res = (*ccfn)(buf, (char **)NULL, base);
- if (flags & POINTER)
- *va_arg(ap, void **) = (void *)res;
- else if (flags & SHORT)
- *va_arg(ap, short *) = res;
- else if (flags & LONG)
- *va_arg(ap, long *) = res;
- else
- *va_arg(ap, int *) = res;
- nassigned++;
- }
- nread += p - buf;
- break;
-
-#ifdef FLOATING_POINT
- case CT_FLOAT:
- /* scan a floating point number as if by strtod */
-#ifdef hardway
- if (width == 0 || width > sizeof(buf) - 1)
- width = sizeof(buf) - 1;
-#else
- /* size_t is unsigned, hence this optimisation */
- if (--width > sizeof(buf) - 2)
- width = sizeof(buf) - 2;
- width++;
-#endif
- flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
- for (p = buf; width; width--) {
- c = *fp->_p;
- /*
- * This code mimicks the integer conversion
- * code, but is much simpler.
- */
- switch (c) {
-
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- case '8': case '9':
- flags &= ~(SIGNOK | NDIGITS);
- goto fok;
-
- case '+': case '-':
- if (flags & SIGNOK) {
- flags &= ~SIGNOK;
- goto fok;
- }
- break;
- case '.':
- if (flags & DPTOK) {
- flags &= ~(SIGNOK | DPTOK);
- goto fok;
- }
- break;
- case 'e': case 'E':
- /* no exponent without some digits */
- if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
- flags =
- (flags & ~(EXPOK|DPTOK)) |
- SIGNOK | NDIGITS;
- goto fok;
- }
- break;
- }
- break;
- fok:
- *p++ = c;
- if (--fp->_r > 0)
- fp->_p++;
- else if (__srefill(fp))
- break; /* EOF */
- }
- /*
- * If no digits, might be missing exponent digits
- * (just give back the exponent) or might be missing
- * regular digits, but had sign and/or decimal point.
- */
- if (flags & NDIGITS) {
- if (flags & EXPOK) {
- /* no digits at all */
- while (p > buf)
- ungetc(*(u_char *)--p, fp);
- goto match_failure;
- }
- /* just a bad exponent (e and maybe sign) */
- c = *(u_char *)--p;
- if (c != 'e' && c != 'E') {
- (void) ungetc(c, fp);/* sign */
- c = *(u_char *)--p;
- }
- (void) ungetc(c, fp);
- }
- if ((flags & SUPPRESS) == 0) {
- double res;
-
- *p = 0;
- res = strtod(buf, (char **) NULL);
- if (flags & LONG)
- *va_arg(ap, double *) = res;
- else
- *va_arg(ap, float *) = res;
- nassigned++;
- }
- nread += p - buf;
- break;
-#endif /* FLOATING_POINT */
- }
- }
-input_failure:
- return (nassigned ? nassigned : -1);
-match_failure:
- return (nassigned);
-}
-
-/*
- * Fill in the given table from the scanset at the given format
- * (just after `['). Return a pointer to the character past the
- * closing `]'. The table has a 1 wherever characters should be
- * considered part of the scanset.
- */
-static u_char *
-__sccl(tab, fmt)
- register char *tab;
- register u_char *fmt;
-{
- register int c, n, v;
-
- /* first `clear' the whole table */
- c = *fmt++; /* first char hat => negated scanset */
- if (c == '^') {
- v = 1; /* default => accept */
- c = *fmt++; /* get new first char */
- } else
- v = 0; /* default => reject */
- /* should probably use memset here */
- for (n = 0; n < 256; n++)
- tab[n] = v;
- if (c == 0)
- return (fmt - 1);/* format ended before closing ] */
-
- /*
- * Now set the entries corresponding to the actual scanset
- * to the opposite of the above.
- *
- * The first character may be ']' (or '-') without being special;
- * the last character may be '-'.
- */
- v = 1 - v;
- for (;;) {
- tab[c] = v; /* take character c */
-doswitch:
- n = *fmt++; /* and examine the next */
- switch (n) {
-
- case 0: /* format ended too soon */
- return (fmt - 1);
-
- case '-':
- /*
- * A scanset of the form
- * [01+-]
- * is defined as `the digit 0, the digit 1,
- * the character +, the character -', but
- * the effect of a scanset such as
- * [a-zA-Z0-9]
- * is implementation defined. The V7 Unix
- * scanf treats `a-z' as `the letters a through
- * z', but treats `a-a' as `the letter a, the
- * character -, and the letter a'.
- *
- * For compatibility, the `-' is not considerd
- * to define a range if the character following
- * it is either a close bracket (required by ANSI)
- * or is not numerically greater than the character
- * we just stored in the table (c).
- */
- n = *fmt;
- if (n == ']' || n < c) {
- c = '-';
- break; /* resume the for(;;) */
- }
- fmt++;
- do { /* fill in the range */
- tab[++c] = v;
- } while (c < n);
-#if 1 /* XXX another disgusting compatibility hack */
- /*
- * Alas, the V7 Unix scanf also treats formats
- * such as [a-c-e] as `the letters a through e'.
- * This too is permitted by the standard....
- */
- goto doswitch;
-#else
- c = *fmt++;
- if (c == 0)
- return (fmt - 1);
- if (c == ']')
- return (fmt);
-#endif
- break;
-
- case ']': /* end of scanset */
- return (fmt);
-
- default: /* just another character */
- c = n;
- break;
- }
- }
- /* NOTREACHED */
-}
diff --git a/mit-pthreads/stdio/vprintf.c b/mit-pthreads/stdio/vprintf.c
deleted file mode 100644
index 4999c4fb239..00000000000
--- a/mit-pthreads/stdio/vprintf.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vprintf.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stdio.h>
-
-vprintf(fmt, ap)
- char const *fmt;
- pthread_va_list ap;
-{
- return (vfprintf(stdout, fmt, ap));
-}
diff --git a/mit-pthreads/stdio/vscanf.c b/mit-pthreads/stdio/vscanf.c
deleted file mode 100644
index 5a562f89528..00000000000
--- a/mit-pthreads/stdio/vscanf.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Donn Seeley at UUNET Technologies, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vscanf.c 5.1 (Berkeley) 4/15/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stdio.h>
-
-vscanf(fmt, ap)
- const char *fmt;
- pthread_va_list ap;
-{
- int r;
- flockfile(stdin);
- r = __svfscanf(stdin, fmt, ap);
- funlockfile(stdin);
- return(r);
-}
diff --git a/mit-pthreads/stdio/vsnprintf.c b/mit-pthreads/stdio/vsnprintf.c
deleted file mode 100644
index 8fd1e6d8613..00000000000
--- a/mit-pthreads/stdio/vsnprintf.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vsnprintf.c 5.2 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-
-vsnprintf(str, n, fmt, ap)
- char *str;
- size_t n;
- const char *fmt;
- pthread_va_list ap;
-{
- int ret;
- FILE f;
-
- if ((int)n < 1)
- return (EOF);
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = n - 1;
- ret = vfprintf(&f, fmt, ap);
- *f._p = 0;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/vsprintf.c b/mit-pthreads/stdio/vsprintf.c
deleted file mode 100644
index c6cdb708be3..00000000000
--- a/mit-pthreads/stdio/vsprintf.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vsprintf.c 5.5 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <limits.h>
-#include <stdio.h>
-
-vsprintf(str, fmt, ap)
- char *str;
- const char *fmt;
- pthread_va_list ap;
-{
- int ret;
- FILE f;
-
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = INT_MAX;
- ret = vfprintf(&f, fmt, ap);
- *f._p = 0;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/vsscanf.c b/mit-pthreads/stdio/vsscanf.c
deleted file mode 100644
index 9d9cdcffeeb..00000000000
--- a/mit-pthreads/stdio/vsscanf.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Donn Seeley at UUNET Technologies, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vsscanf.c 5.1 (Berkeley) 4/15/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-vsscanf(str, fmt, ap)
- const char *str;
- const char *fmt;
- pthread_va_list ap;
-{
- int ret;
- FILE f;
-
- f._flags = __SRD;
- f._file = -1; /* This will do the right thing */
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._r = strlen(str);
- f._ub._base = NULL;
- f._lb._base = NULL;
- return (__svfscanf(&f, fmt, ap));
-}
diff --git a/mit-pthreads/stdio/wbuf.c b/mit-pthreads/stdio/wbuf.c
deleted file mode 100644
index 58cb9ad058e..00000000000
--- a/mit-pthreads/stdio/wbuf.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)wbuf.c 5.6 (Berkeley) 1/20/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include "local.h"
-
-/*
- * Write the given character into the (probably full) buffer for
- * the given file. Flush the buffer out if it is or becomes full,
- * or if c=='\n' and the file is line buffered.
- */
-__swbuf(c, fp)
- register int c;
- register FILE *fp;
-{
- register int n;
-
- /*
- * In case we cannot write, or longjmp takes us out early,
- * make sure _w is 0 (if fully- or un-buffered) or -_bf._size
- * (if line buffered) so that we will get called again.
- * If we did not do this, a sufficient number of putc()
- * calls might wrap _w from negative to positive.
- */
- fp->_w = fp->_lbfsize;
- if (cantwrite(fp))
- return (EOF);
- c = (unsigned char)c;
-
- /*
- * If it is completely full, flush it out. Then, in any case,
- * stuff c into the buffer. If this causes the buffer to fill
- * completely, or if c is '\n' and the file is line buffered,
- * flush it (perhaps a second time). The second flush will always
- * happen on unbuffered streams, where _bf._size==1; fflush()
- * guarantees that putc() will always call wbuf() by setting _w
- * to 0, so we need not do anything else.
- */
- n = fp->_p - fp->_bf._base;
- if (n >= fp->_bf._size) {
- if (fflush(fp))
- return (EOF);
- n = 0;
- }
- fp->_w--;
- *fp->_p++ = c;
- if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
- if (fflush(fp))
- return (EOF);
- return (c);
-}
diff --git a/mit-pthreads/stdio/wsetup.c b/mit-pthreads/stdio/wsetup.c
deleted file mode 100644
index 1c86f45a973..00000000000
--- a/mit-pthreads/stdio/wsetup.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)wsetup.c 5.2 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/*
- * Various output routines call wsetup to be sure it is safe to write,
- * because either _flags does not include __SWR, or _buf is NULL.
- * _wsetup returns 0 if OK to write, nonzero otherwise.
- */
-__swsetup(fp)
- register FILE *fp;
-{
- /* make sure stdio is set up */
- __sinit ();
-
- /*
- * If we are not writing, we had better be reading and writing.
- */
- if ((fp->_flags & __SWR) == 0) {
- if ((fp->_flags & __SRW) == 0)
- return (EOF);
- if (fp->_flags & __SRD) {
- /* clobber any ungetc data */
- if (HASUB(fp))
- FREEUB(fp);
- fp->_flags &= ~(__SRD|__SEOF);
- fp->_r = 0;
- fp->_p = fp->_bf._base;
- }
- fp->_flags |= __SWR;
- }
-
- /*
- * Make a buffer if necessary, then set _w.
- */
- if (fp->_bf._base == NULL)
- __smakebuf(fp);
- if (fp->_flags & __SLBF) {
- /*
- * It is line buffered, so make _lbfsize be -_bufsize
- * for the putc() macro. We will change _lbfsize back
- * to 0 whenever we turn off __SWR.
- */
- fp->_w = 0;
- fp->_lbfsize = -fp->_bf._size;
- } else
- fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
- return (0);
-}
diff --git a/mit-pthreads/stdio/xprintf.c b/mit-pthreads/stdio/xprintf.c
deleted file mode 100644
index 668e8bc0605..00000000000
--- a/mit-pthreads/stdio/xprintf.c
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
-** It turns out that the printf functions in the stock MIT pthread library
-** is busted. It isn't thread safe. If two threads try to do a printf
-** of a floating point value at the same time, a core-dump might result.
-** So this code is substituted.
-*/
-/*
-** NAME: $Source$
-** VERSION: $Revision$
-** DATE: $Date$
-**
-** ONELINER: A replacement for formatted printing programs.
-**
-** COPYRIGHT:
-** Copyright (c) 1990 by D. Richard Hipp. This code is an original
-** work and has been prepared without reference to any prior
-** implementations of similar functions. No part of this code is
-** subject to licensing restrictions of any telephone company or
-** university.
-**
-** This copyright was released and the code placed in the public domain
-** by the author, D. Richard Hipp, on October 3, 1996.
-**
-** DESCRIPTION:
-** This program is an enhanced replacement for the "printf" programs
-** found in the standard library. The following enhancements are
-** supported:
-**
-** + Additional functions. The standard set of "printf" functions
-** includes printf, fprintf, sprintf, vprintf, vfprintf, and
-** vsprintf. This module adds the following:
-**
-** * snprintf -- Works like sprintf, but has an extra argument
-** which is the size of the buffer written to.
-**
-** * mprintf -- Similar to sprintf. Writes output to memory
-** obtained from mem_alloc.
-**
-** * xprintf -- Calls a function to dispose of output.
-**
-** * nprintf -- No output, but returns the number of characters
-** that would have been output by printf.
-**
-** * A v- version (ex: vsnprintf) of every function is also
-** supplied.
-**
-** + A few extensions to the formatting notation are supported:
-**
-** * The "=" flag (similar to "-") causes the output to be
-** be centered in the appropriately sized field.
-**
-** * The %b field outputs an integer in binary notation.
-**
-** * The %c field now accepts a precision. The character output
-** is repeated by the number of times the precision specifies.
-**
-** * The %' field works like %c, but takes as its character the
-** next character of the format string, instead of the next
-** argument. For example, printf("%.78'-") prints 78 minus
-** signs, the same as printf("%.78c",'-').
-**
-** + When compiled using GCC on a SPARC, this version of printf is
-** faster than the library printf for SUN OS 4.1.
-**
-** + All functions are fully reentrant.
-**
-*/
-/*
-** Undefine COMPATIBILITY to make some slight changes in the way things
-** work. I think the changes are an improvement, but they are not
-** backwards compatible.
-*/
-/* #define COMPATIBILITY / * Compatible with SUN OS 4.1 */
-#include <stdio.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-/*
-** The maximum number of digits of accuracy in a floating-point conversion.
-*/
-#define MAXDIG 20
-
-/*
-** Conversion types fall into various categories as defined by the
-** following enumeration.
-*/
-enum e_type { /* The type of the format field */
- RADIX, /* Integer types. %d, %x, %o, and so forth */
- FLOAT, /* Floating point. %f */
- EXP, /* Exponentional notation. %e and %E */
- GENERIC, /* Floating or exponential, depending on exponent. %g */
- SIZE, /* Return number of characters processed so far. %n */
- STRING, /* Strings. %s */
- PERCENT, /* Percent symbol. %% */
- CHAR, /* Characters. %c */
- ERROR, /* Used to indicate no such conversion type */
-/* The rest are extensions, not normally found in printf() */
- CHARLIT, /* Literal characters. %' */
- SEEIT, /* Strings with visible control characters. %S */
- MEM_STRING, /* A string which should be deleted after use. %z */
- ORDINAL, /* 1st, 2nd, 3rd and so forth */
-};
-
-/*
-** Each builtin conversion character (ex: the 'd' in "%d") is described
-** by an instance of the following structure
-*/
-typedef struct s_info { /* Information about each format field */
- int fmttype; /* The format field code letter */
- int base; /* The base for radix conversion */
- char *charset; /* The character set for conversion */
- int flag_signed; /* Is the quantity signed? */
- char *prefix; /* Prefix on non-zero values in alt format */
- enum e_type type; /* Conversion paradigm */
-} info;
-
-/*
-** The following table is searched linearly, so it is good to put the
-** most frequently used conversion types first.
-*/
-static info fmtinfo[] = {
- { 'd', 10, "0123456789", 1, 0, RADIX, },
- { 's', 0, 0, 0, 0, STRING, },
- { 'S', 0, 0, 0, 0, SEEIT, },
- { 'z', 0, 0, 0, 0, MEM_STRING, },
- { 'c', 0, 0, 0, 0, CHAR, },
- { 'o', 8, "01234567", 0, "0", RADIX, },
- { 'u', 10, "0123456789", 0, 0, RADIX, },
- { 'x', 16, "0123456789abcdef", 0, "x0", RADIX, },
- { 'X', 16, "0123456789ABCDEF", 0, "X0", RADIX, },
- { 'r', 10, "0123456789", 0, 0, ORDINAL, },
- { 'f', 0, 0, 1, 0, FLOAT, },
- { 'e', 0, "e", 1, 0, EXP, },
- { 'E', 0, "E", 1, 0, EXP, },
- { 'g', 0, "e", 1, 0, GENERIC, },
- { 'G', 0, "E", 1, 0, GENERIC, },
- { 'i', 10, "0123456789", 1, 0, RADIX, },
- { 'n', 0, 0, 0, 0, SIZE, },
- { 'S', 0, 0, 0, 0, SEEIT, },
- { '%', 0, 0, 0, 0, PERCENT, },
- { 'b', 2, "01", 0, "b0", RADIX, }, /* Binary notation */
- { 'p', 10, "0123456789", 0, 0, RADIX, }, /* Pointers */
- { '\'', 0, 0, 0, 0, CHARLIT, }, /* Literal char */
-};
-#define NINFO (sizeof(fmtinfo)/sizeof(info)) /* Size of the fmtinfo table */
-
-/*
-** If NOFLOATINGPOINT is defined, then none of the floating point
-** conversions will work.
-*/
-#ifndef NOFLOATINGPOINT
-/*
-** "*val" is a double such that 0.1 <= *val < 10.0
-** Return the ascii code for the leading digit of *val, then
-** multiply "*val" by 10.0 to renormalize.
-**
-** Example:
-** input: *val = 3.14159
-** output: *val = 1.4159 function return = '3'
-**
-** The counter *cnt is incremented each time. After counter exceeds
-** 16 (the number of significant digits in a 64-bit float) '0' is
-** always returned.
-*/
-static int getdigit(long double *val, int *cnt){
- int digit;
- long double d;
- if( (*cnt)++ >= MAXDIG ) return '0';
- digit = (int)*val;
- d = digit;
- digit += '0';
- *val = (*val - d)*10.0;
- return digit;
-}
-#endif
-
-/*
-** Setting the size of the BUFFER involves trade-offs. No %d or %f
-** conversion can have more than BUFSIZE characters. If the field
-** width is larger than BUFSIZE, it is silently shortened. On the
-** other hand, this routine consumes more stack space with larger
-** BUFSIZEs. If you have some threads for which you want to minimize
-** stack space, you should keep BUFSIZE small.
-*/
-#define BUFSIZE 100 /* Size of the output buffer */
-
-/*
-** The root program. All variations call this core.
-**
-** INPUTS:
-** func This is a pointer to a function taking three arguments
-** 1. A pointer to the list of characters to be output
-** (Note, this list is NOT null terminated.)
-** 2. An integer number of characters to be output.
-** (Note: This number might be zero.)
-** 3. A pointer to anything. Same as the "arg" parameter.
-**
-** arg This is the pointer to anything which will be passed as the
-** third argument to "func". Use it for whatever you like.
-**
-** fmt This is the format string, as in the usual print.
-**
-** ap This is a pointer to a list of arguments. Same as in
-** vfprint.
-**
-** OUTPUTS:
-** The return value is the total number of characters sent to
-** the function "func". Returns -1 on a error.
-**
-** Note that the order in which automatic variables are declared below
-** seems to make a big difference in determining how fast this beast
-** will run.
-*/
-static int vxprintf(func,arg,format,ap)
- void (*func)(char*,int,void*);
- void *arg;
- const char *format;
- va_list ap;
-{
- register const char *fmt; /* The format string. */
- register int c; /* Next character in the format string */
- register char *bufpt; /* Pointer to the conversion buffer */
- register int precision; /* Precision of the current field */
- register int length; /* Length of the field */
- register int idx; /* A general purpose loop counter */
- int count; /* Total number of characters output */
- int width; /* Width of the current field */
- int flag_leftjustify; /* True if "-" flag is present */
- int flag_plussign; /* True if "+" flag is present */
- int flag_blanksign; /* True if " " flag is present */
- int flag_alternateform; /* True if "#" flag is present */
- int flag_zeropad; /* True if field width constant starts with zero */
- int flag_long; /* True if "l" flag is present */
- int flag_center; /* True if "=" flag is present */
- unsigned long longvalue; /* Value for integer types */
- long double realvalue; /* Value for real types */
- info *infop; /* Pointer to the appropriate info structure */
- char buf[BUFSIZE]; /* Conversion buffer */
- char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
- int errorflag = 0; /* True if an error is encountered */
- enum e_type xtype; /* Conversion paradigm */
- char *zMem; /* String to be freed */
- static char spaces[] =
- " ";
-#define SPACESIZE (sizeof(spaces)-1)
-#ifndef NOFLOATINGPOINT
- int exp; /* exponent of real numbers */
- long double rounder; /* Used for rounding floating point values */
- int flag_dp; /* True if decimal point should be shown */
- int flag_rtz; /* True if trailing zeros should be removed */
- int flag_exp; /* True to force display of the exponent */
- int nsd; /* Number of significant digits returned */
-#endif
-
- fmt = format; /* Put in a register for speed */
- count = length = 0;
- bufpt = 0;
- for(; (c=(*fmt))!=0; ++fmt){
- if( c!='%' ){
- register int amt;
- bufpt = (char *)fmt;
- amt = 1;
- while( (c=(*++fmt))!='%' && c!=0 ) amt++;
- (*func)(bufpt,amt,arg);
- count += amt;
- if( c==0 ) break;
- }
- if( (c=(*++fmt))==0 ){
- errorflag = 1;
- (*func)("%",1,arg);
- count++;
- break;
- }
- /* Find out what flags are present */
- flag_leftjustify = flag_plussign = flag_blanksign =
- flag_alternateform = flag_zeropad = flag_center = 0;
- do{
- switch( c ){
- case '-': flag_leftjustify = 1; c = 0; break;
- case '+': flag_plussign = 1; c = 0; break;
- case ' ': flag_blanksign = 1; c = 0; break;
- case '#': flag_alternateform = 1; c = 0; break;
- case '0': flag_zeropad = 1; c = 0; break;
- case '=': flag_center = 1; c = 0; break;
- default: break;
- }
- }while( c==0 && (c=(*++fmt))!=0 );
- if( flag_center ) flag_leftjustify = 0;
- /* Get the field width */
- width = 0;
- if( c=='*' ){
- width = va_arg(ap,int);
- if( width<0 ){
- flag_leftjustify = 1;
- width = -width;
- }
- c = *++fmt;
- }else{
- while( isdigit(c) ){
- width = width*10 + c - '0';
- c = *++fmt;
- }
- }
- if( width > BUFSIZE-10 ){
- width = BUFSIZE-10;
- }
- /* Get the precision */
- if( c=='.' ){
- precision = 0;
- c = *++fmt;
- if( c=='*' ){
- precision = va_arg(ap,int);
-#ifndef COMPATIBILITY
- /* This is sensible, but SUN OS 4.1 doesn't do it. */
- if( precision<0 ) precision = -precision;
-#endif
- c = *++fmt;
- }else{
- while( isdigit(c) ){
- precision = precision*10 + c - '0';
- c = *++fmt;
- }
- }
- /* Limit the precision to prevent overflowing buf[] during conversion */
- if( precision>BUFSIZE-40 ) precision = BUFSIZE-40;
- }else{
- precision = -1;
- }
- /* Get the conversion type modifier */
- if( c=='l' ){
- flag_long = 1;
- c = *++fmt;
- }else{
- flag_long = 0;
- }
- /* Fetch the info entry for the field */
- infop = 0;
- for(idx=0; idx<NINFO; idx++){
- if( c==fmtinfo[idx].fmttype ){
- infop = &fmtinfo[idx];
- break;
- }
- }
- /* No info entry found. It must be an error. */
- if( infop==0 ){
- xtype = ERROR;
- }else{
- xtype = infop->type;
- }
-
- /*
- ** At this point, variables are initialized as follows:
- **
- ** flag_alternateform TRUE if a '#' is present.
- ** flag_plussign TRUE if a '+' is present.
- ** flag_leftjustify TRUE if a '-' is present or if the
- ** field width was negative.
- ** flag_zeropad TRUE if the width began with 0.
- ** flag_long TRUE if the letter 'l' (ell) prefixed
- ** the conversion character.
- ** flag_blanksign TRUE if a ' ' is present.
- ** width The specified field width. This is
- ** always non-negative. Zero is the default.
- ** precision The specified precision. The default
- ** is -1.
- ** xtype The class of the conversion.
- ** infop Pointer to the appropriate info struct.
- */
- switch( xtype ){
- case ORDINAL:
- case RADIX:
- if( flag_long ) longvalue = va_arg(ap,long);
- else longvalue = va_arg(ap,int);
-#ifdef COMPATIBILITY
- /* For the format %#x, the value zero is printed "0" not "0x0".
- ** I think this is stupid. */
- if( longvalue==0 ) flag_alternateform = 0;
-#else
- /* More sensible: turn off the prefix for octal (to prevent "00"),
- ** but leave the prefix for hex. */
- if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
-#endif
- if( infop->flag_signed ){
- if( *(long*)&longvalue<0 ){
- longvalue = -*(long*)&longvalue;
- prefix = '-';
- }else if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }else prefix = 0;
- if( flag_zeropad && precision<width-(prefix!=0) ){
- precision = width-(prefix!=0);
- }
- bufpt = &buf[BUFSIZE];
- if( xtype==ORDINAL ){
- long a,b;
- a = longvalue%10;
- b = longvalue%100;
- bufpt -= 2;
- if( a==0 || a>3 || (b>10 && b<14) ){
- bufpt[0] = 't';
- bufpt[1] = 'h';
- }else if( a==1 ){
- bufpt[0] = 's';
- bufpt[1] = 't';
- }else if( a==2 ){
- bufpt[0] = 'n';
- bufpt[1] = 'd';
- }else if( a==3 ){
- bufpt[0] = 'r';
- bufpt[1] = 'd';
- }
- }
- {
- register char *cset; /* Use registers for speed */
- register int base;
- cset = infop->charset;
- base = infop->base;
- do{ /* Convert to ascii */
- *(--bufpt) = cset[longvalue%base];
- longvalue = longvalue/base;
- }while( longvalue>0 );
- }
- length = (int)(&buf[BUFSIZE]-bufpt);
- for(idx=precision-length; idx>0; idx--){
- *(--bufpt) = '0'; /* Zero pad */
- }
- if( prefix ) *(--bufpt) = prefix; /* Add sign */
- if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
- char *pre, x;
- pre = infop->prefix;
- if( *bufpt!=pre[0] ){
- for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
- }
- }
- length = (int)(&buf[BUFSIZE]-bufpt);
- break;
- case FLOAT:
- case EXP:
- case GENERIC:
- realvalue = va_arg(ap,double);
-#ifndef NOFLOATINGPOINT
- if( precision<0 ) precision = 6; /* Set default precision */
- if( precision>BUFSIZE-10 ) precision = BUFSIZE-10;
- if( realvalue<0.0 ){
- realvalue = -realvalue;
- prefix = '-';
- }else{
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }
- if( infop->type==GENERIC && precision>0 ) precision--;
- rounder = 0.0;
-#ifdef COMPATIBILITY
- /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
- for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
-#else
- /* It makes more sense to use 0.5 */
- if( precision>MAXDIG-1 ) idx = MAXDIG-1;
- else idx = precision;
- for(rounder=0.5; idx>0; idx--, rounder*=0.1);
-#endif
- if( infop->type==FLOAT ) realvalue += rounder;
- /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
- exp = 0;
- if( realvalue>0.0 ){
- int k = 0;
- while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; }
- while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; }
- while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; }
- while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; }
- if( k>=100 ){
- bufpt = "NaN";
- length = 3;
- break;
- }
- }
- bufpt = buf;
- /*
- ** If the field type is GENERIC, then convert to either EXP
- ** or FLOAT, as appropriate.
- */
- flag_exp = xtype==EXP;
- if( xtype!=FLOAT ){
- realvalue += rounder;
- if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
- }
- if( xtype==GENERIC ){
- flag_rtz = !flag_alternateform;
- if( exp<-4 || exp>precision ){
- xtype = EXP;
- }else{
- precision = precision - exp;
- xtype = FLOAT;
- }
- }else{
- flag_rtz = 0;
- }
- /*
- ** The "exp+precision" test causes output to be of type EXP if
- ** the precision is too large to fit in buf[].
- */
- nsd = 0;
- if( xtype==FLOAT && exp+precision<BUFSIZE-30 ){
- flag_dp = (precision>0 || flag_alternateform);
- if( prefix ) *(bufpt++) = prefix; /* Sign */
- if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */
- else for(; exp>=0; exp--) *(bufpt++) = getdigit(&realvalue,&nsd);
- if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */
- for(exp++; exp<0 && precision>0; precision--, exp++){
- *(bufpt++) = '0';
- }
- while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd);
- *(bufpt--) = 0; /* Null terminate */
- if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */
- while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
- if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
- }
- bufpt++; /* point to next free slot */
- }else{ /* EXP or GENERIC */
- flag_dp = (precision>0 || flag_alternateform);
- if( prefix ) *(bufpt++) = prefix; /* Sign */
- *(bufpt++) = getdigit(&realvalue,&nsd); /* First digit */
- if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */
- while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd);
- bufpt--; /* point to last digit */
- if( flag_rtz && flag_dp ){ /* Remove tail zeros */
- while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
- if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
- }
- bufpt++; /* point to next free slot */
- if( exp || flag_exp ){
- *(bufpt++) = infop->charset[0];
- if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
- else { *(bufpt++) = '+'; }
- if( exp>=100 ){
- *(bufpt++) = (exp/100)+'0'; /* 100's digit */
- exp %= 100;
- }
- *(bufpt++) = exp/10+'0'; /* 10's digit */
- *(bufpt++) = exp%10+'0'; /* 1's digit */
- }
- }
- /* The converted number is in buf[] and zero terminated. Output it.
- ** Note that the number is in the usual order, not reversed as with
- ** integer conversions. */
- length = (int)(bufpt-buf);
- bufpt = buf;
-
- /* Special case: Add leading zeros if the flag_zeropad flag is
- ** set and we are not left justified */
- if( flag_zeropad && !flag_leftjustify && length < width){
- int i;
- int nPad = width - length;
- for(i=width; i>=nPad; i--){
- bufpt[i] = bufpt[i-nPad];
- }
- i = prefix!=0;
- while( nPad-- ) bufpt[i++] = '0';
- length = width;
- }
-#endif
- break;
- case SIZE:
- *(va_arg(ap,int*)) = count;
- length = width = 0;
- break;
- case PERCENT:
- buf[0] = '%';
- bufpt = buf;
- length = 1;
- break;
- case CHARLIT:
- case CHAR:
- c = buf[0] = (xtype==CHAR ? va_arg(ap,int) : *++fmt);
- if( precision>=0 ){
- for(idx=1; idx<precision; idx++) buf[idx] = c;
- length = precision;
- }else{
- length =1;
- }
- bufpt = buf;
- break;
- case STRING:
- case MEM_STRING:
- zMem = bufpt = va_arg(ap,char*);
- if( bufpt==0 ) bufpt = "(null)";
- length = strlen(bufpt);
- if( precision>=0 && precision<length ) length = precision;
- break;
- case SEEIT:
- {
- int i;
- int c;
- char *arg = va_arg(ap,char*);
- for(i=0; i<BUFSIZE-1 && (c = *arg++)!=0; i++){
- if( c<0x20 || c>=0x7f ){
- buf[i++] = '^';
- buf[i] = (c&0x1f)+0x40;
- }else{
- buf[i] = c;
- }
- }
- bufpt = buf;
- length = i;
- if( precision>=0 && precision<length ) length = precision;
- }
- break;
- case ERROR:
- buf[0] = '%';
- buf[1] = c;
- errorflag = 0;
- idx = 1+(c!=0);
- (*func)("%",idx,arg);
- count += idx;
- if( c==0 ) fmt--;
- break;
- }/* End switch over the format type */
- /*
- ** The text of the conversion is pointed to by "bufpt" and is
- ** "length" characters long. The field width is "width". Do
- ** the output.
- */
- if( !flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- if( flag_center ){
- nspace = nspace/2;
- width -= nspace;
- flag_leftjustify = 1;
- }
- count += nspace;
- while( nspace>=SPACESIZE ){
- (*func)(spaces,SPACESIZE,arg);
- nspace -= SPACESIZE;
- }
- if( nspace>0 ) (*func)(spaces,nspace,arg);
- }
- }
- if( length>0 ){
- (*func)(bufpt,length,arg);
- count += length;
- }
- if( xtype==MEM_STRING && zMem ){
- free(zMem);
- }
- if( flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- count += nspace;
- while( nspace>=SPACESIZE ){
- (*func)(spaces,SPACESIZE,arg);
- nspace -= SPACESIZE;
- }
- if( nspace>0 ) (*func)(spaces,nspace,arg);
- }
- }
- }/* End for loop over the format string */
- return errorflag ? -1 : count;
-} /* End of function */
-
-/*
-** This non-standard function is still occasionally useful....
-*/
-int xprintf(
- void (*func)(char*,int,void*),
- void *arg,
- const char *format,
- ...
-){
- va_list ap;
- va_start(ap,format);
- return vxprintf(func,arg,format,ap);
-}
-
-/*
-** Now for string-print, also as found in any standard library.
-** Add to this the snprint function which stops added characters
-** to the string at a given length.
-**
-** Note that snprint returns the length of the string as it would
-** be if there were no limit on the output.
-*/
-struct s_strargument { /* Describes the string being written to */
- char *next; /* Next free slot in the string */
- char *last; /* Last available slot in the string */
-};
-
-static void sout(txt,amt,arg)
- char *txt;
- int amt;
- void *arg;
-{
- register char *head;
- register const char *t;
- register int a;
- register char *tail;
- a = amt;
- t = txt;
- head = ((struct s_strargument*)arg)->next;
- tail = ((struct s_strargument*)arg)->last;
- if( tail ){
- while( a-- >0 && head<tail ) *(head++) = *(t++);
- }else{
- while( a-- >0 ) *(head++) = *(t++);
- }
- *head = 0;
- ((struct s_strargument*)arg)->next = head;
-}
-
-int sprintf(char *buf, const char *fmt, ...){
- int rc;
- va_list ap;
- struct s_strargument arg;
-
- va_start(ap,fmt);
- arg.next = buf;
- arg.last = 0;
- *arg.next = 0;
- rc = vxprintf(sout,&arg,fmt,ap);
- va_end(ap);
-}
-int vsprintf(char *buf,const char *fmt,va_list ap){
- struct s_strargument arg;
- arg.next = buf;
- arg.last = 0;
- *buf = 0;
- return vxprintf(sout,&arg,fmt,ap);
-}
-int snprintf(char *buf, size_t n, const char *fmt, ...){
- int rc;
- va_list ap;
- struct s_strargument arg;
-
- va_start(ap,fmt);
- arg.next = buf;
- arg.last = &arg.next[n-1];
- *arg.next = 0;
- rc = vxprintf(sout,&arg,fmt,ap);
- va_end(ap);
-}
-int vsnprintf(char *buf, size_t n, const char *fmt, va_list ap){
- struct s_strargument arg;
- arg.next = buf;
- arg.last = &buf[n-1];
- *buf = 0;
- return vxprintf(sout,&arg,fmt,ap);
-}
-
-/*
-** The following section of code handles the mprintf routine, that
-** writes to memory obtained from malloc().
-*/
-
-/* This structure is used to store state information about the
-** write in progress
-*/
-struct sgMprintf {
- char *zBase; /* A base allocation */
- char *zText; /* The string collected so far */
- int nChar; /* Length of the string so far */
- int nAlloc; /* Amount of space allocated in zText */
-};
-
-/* The xprintf callback function. */
-static void mout(zNewText,nNewChar,arg)
- char *zNewText;
- int nNewChar;
- void *arg;
-{
- struct sgMprintf *pM = (struct sgMprintf*)arg;
- if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
- pM->nAlloc = pM->nChar + nNewChar*2 + 1;
- if( pM->zText==pM->zBase ){
- pM->zText = malloc(pM->nAlloc);
- if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar);
- }else{
- pM->zText = realloc(pM->zText, pM->nAlloc);
- }
- }
- if( pM->zText ){
- memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
- pM->nChar += nNewChar;
- pM->zText[pM->nChar] = 0;
- }
-}
-
-/*
-** mprintf() works like printf(), but allocations memory to hold the
-** resulting string and returns a pointer to the allocated memory.
-**
-** We changed the name to TclMPrint() to conform with the Tcl private
-** routine naming conventions.
-*/
-char *mprintf(const char *zFormat, ...){
- va_list ap;
- struct sgMprintf sMprintf;
- char *zNew;
- char zBuf[200];
-
- va_start(ap,zFormat);
- sMprintf.nChar = 0;
- sMprintf.nAlloc = sizeof(zBuf);
- sMprintf.zText = zBuf;
- sMprintf.zBase = zBuf;
- vxprintf(mout,&sMprintf,zFormat,ap);
- va_end(ap);
- if( sMprintf.zText==sMprintf.zBase ){
- zNew = malloc( sMprintf.nChar+1 );
- if( zNew ) strcpy(zNew,zBuf);
- }else{
- zNew = realloc(sMprintf.zText,sMprintf.nChar+1);
- }
-
- return zNew;
-}
-
-/* This is the varargs version of mprintf.
-**
-** The name is changed to TclVMPrintf() to conform with Tcl naming
-** conventions.
-*/
-char *vmprintf(const char *zFormat,va_list ap){
- struct sgMprintf sMprintf;
- char zBuf[200];
- sMprintf.nChar = 0;
- sMprintf.zText = zBuf;
- sMprintf.nAlloc = sizeof(zBuf);
- sMprintf.zBase = zBuf;
- vxprintf(mout,&sMprintf,zFormat,ap);
- if( sMprintf.zText==sMprintf.zBase ){
- sMprintf.zText = malloc( strlen(zBuf)+1 );
- if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf);
- }else{
- sMprintf.zText = realloc(sMprintf.zText,sMprintf.nChar+1);
- }
- return sMprintf.zText;
-}
-
-/*
-** The following section of code handles the standard fprintf routines
-** for pthreads.
-*/
-
-/* The xprintf callback function. */
-static void fout(zNewText,nNewChar,arg)
- char *zNewText;
- int nNewChar;
- void *arg;
-{
- fwrite(zNewText,1,nNewChar,(FILE*)arg);
-}
-
-/* The public interface routines */
-int fprintf(FILE *pOut, const char *zFormat, ...){
- va_list ap;
- int retc;
-
- va_start(ap,zFormat);
- retc = vxprintf(fout,pOut,zFormat,ap);
- va_end(ap);
- return retc;
-}
-int vfprintf(FILE *pOut, const char *zFormat, va_list ap){
- return vxprintf(fout,pOut,zFormat,ap);
-}
-int printf(const char *zFormat, ...){
- va_list ap;
- int retc;
-
- va_start(ap,zFormat);
- retc = vxprintf(fout,stdout,zFormat,ap);
- va_end(ap);
- return retc;
-}
-int vprintf(const char *zFormat, va_list ap){
- return vxprintf(fout,stdout,zFormat,ap);
-}
diff --git a/mit-pthreads/stdlib/GNUmakefile.inc b/mit-pthreads/stdlib/GNUmakefile.inc
deleted file mode 100755
index 2f55ce8b217..00000000000
--- a/mit-pthreads/stdlib/GNUmakefile.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-# @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# stdlib sources
-VPATH:= ${VPATH}:${srcdir}/stdlib
-
-SRCS:= abort.c exit.c strtod.c getopt.c rand.c random.c strtol.c strtoul.c \
- system.c $(SRCS)
diff --git a/mit-pthreads/stdlib/Makefile.inc b/mit-pthreads/stdlib/Makefile.inc
deleted file mode 100644
index cc323d1d0e1..00000000000
--- a/mit-pthreads/stdlib/Makefile.inc
+++ /dev/null
@@ -1,10 +0,0 @@
-# @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# stdlib sources
-.PATH: ${srcdir}/${MACHINE}/stdlib ${srcdir}/stdlib
-
-SRCS+= exit.c strtod.c getopt.c rand.c random.c strtol.c strtoul.c
-
-# SRCS+=abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c div.c \
-# getenv.c heapsort.c labs.c ldiv.c malloc.c multibyte.c \
-# putenv.c qsort.c radixsort.c setenv.c system.c
diff --git a/mit-pthreads/stdlib/abort.c b/mit-pthreads/stdlib/abort.c
deleted file mode 100644
index 474c35f6107..00000000000
--- a/mit-pthreads/stdlib/abort.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)abort.c 5.11 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-
-void
-abort()
-{
- sigset_t mask;
-
- sigfillset(&mask);
- /*
- * don't block SIGABRT to give any handler a chance; we ignore
- * any errors -- X3J11 doesn't allow abort to return anyway.
- */
- sigdelset(&mask, SIGABRT);
- pthread_sigmask(SIG_SETMASK, &mask, NULL);
- kill(getpid(), SIGABRT);
-
- /*
- * if SIGABRT ignored, or caught and the handler returns, do
- * it again, only harder.
- */
- pthread_signal(SIGABRT, SIG_DFL);
- pthread_sigmask(SIG_SETMASK, &mask, NULL);
- kill(getpid(), SIGABRT);
- exit(1);
-}
diff --git a/mit-pthreads/stdlib/atexit.h b/mit-pthreads/stdlib/atexit.h
deleted file mode 100644
index d13dc588781..00000000000
--- a/mit-pthreads/stdlib/atexit.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)atexit.h 5.1 (Berkeley) 5/15/90
- * $Id$
- */
-
-/* must be at least 32 to guarantee ANSI conformance */
-#define ATEXIT_SIZE 32
-
-struct atexit {
- struct atexit *next; /* next in list */
- int ind; /* next index in this table */
- void (*fns[ATEXIT_SIZE])(); /* the table itself */
-};
-
-struct atexit *__atexit; /* points to head of LIFO stack */
diff --git a/mit-pthreads/stdlib/exit.c b/mit-pthreads/stdlib/exit.c
deleted file mode 100644
index 159a066d797..00000000000
--- a/mit-pthreads/stdlib/exit.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)exit.c 5.4 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/cdefs.h>
-#include <pthread/posix.h>
-#include "atexit.h"
-
-void (*__cleanup)();
-
-/*
- * Exit, flushing stdio buffers if necessary.
- */
-void __NORETURN exit(int status)
-{
- register struct atexit *p;
- register int n;
-
- for (p = __atexit; p; p = p->next)
- for (n = p->ind; --n >= 0;)
- (*p->fns[n])();
- if (__cleanup)
- (*__cleanup)();
- _exit(status);
-
- /* This is to shut up gcc, which complains about this function
- * returning even if _exit() is declared noreturn. */
- while (1);
-}
-
-
-/*
- * Register a function to be performed at exit.
- */
-int atexit(void (*fn)())
-{
- static struct atexit __atexit0; /* one guaranteed table */
- register struct atexit *p;
-
- if ((p = __atexit) == NULL)
- __atexit = p = &__atexit0;
- else if (p->ind >= ATEXIT_SIZE) {
- if ((p = malloc(sizeof(*p))) == NULL)
- return (-1);
- p->ind = 0;
- p->next = __atexit;
- __atexit = p;
- }
- p->fns[p->ind++] = fn;
- return (0);
-}
diff --git a/mit-pthreads/stdlib/getopt.c b/mit-pthreads/stdlib/getopt.c
deleted file mode 100644
index 71fafd49490..00000000000
--- a/mit-pthreads/stdlib/getopt.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <config.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * get option letter from argument vector
- */
-
-#ifndef LD_LINKS_STATIC_DATA
-/*
- * Under the Solaris ld, some data sections are linked in regaurdless of
- * whether or not the name has been resolved.
- */
-int opterr = 1, /* if error message should be printed */
- optind = 1, /* index into parent argv vector */
- optopt = 0; /* character checked for validity */
-char * optarg = NULL; /* argument associated with option */
-
-#else
-
-extern int opterr, optind, optopt;
-extern char *optarg;
-
-#endif
-
-#define BADCH (int)'?'
-#define EMSG ""
-
-int
-getopt(nargc, nargv, ostr)
- int nargc;
- char * const *nargv;
- const char *ostr;
-{
- static char *place = EMSG; /* option letter processing */
- register char *oli; /* option letter list index */
- char *p;
-
- if (!*place) { /* update scanning pointer */
- if (optind >= nargc || *(place = nargv[optind]) != '-') {
- place = EMSG;
- return(EOF);
- }
- if (place[1] && *++place == '-') { /* found "--" */
- ++optind;
- place = EMSG;
- return(EOF);
- }
- } /* option letter okay? */
- if ((optopt = (int)*place++) == (int)':' ||
- !(oli = strchr(ostr, optopt))) {
- /*
- * if the user didn't specify '-' as an option,
- * assume it means EOF.
- */
- if (optopt == (int)'-')
- return(EOF);
- if (!*place)
- ++optind;
- if (opterr) {
- if (!(p = strrchr(*nargv, '/')))
- p = *nargv;
- else
- ++p;
- (void)fprintf(stderr, "%s: illegal option -- %c\n",
- p, optopt);
- }
- return(BADCH);
- }
- if (*++oli != ':') { /* don't need argument */
- optarg = NULL;
- if (!*place)
- ++optind;
- }
- else { /* need an argument */
- if (*place) /* no white space */
- optarg = place;
- else if (nargc <= ++optind) { /* no arg */
- place = EMSG;
- if (!(p = strrchr(*nargv, '/')))
- p = *nargv;
- else
- ++p;
- if (opterr)
- (void)fprintf(stderr,
- "%s: option requires an argument -- %c\n",
- p, optopt);
- return(BADCH);
- }
- else /* white space */
- optarg = nargv[optind];
- place = EMSG;
- ++optind;
- }
- return(optopt); /* dump back option letter */
-}
diff --git a/mit-pthreads/stdlib/rand.c b/mit-pthreads/stdlib/rand.c
deleted file mode 100644
index 9367dceed25..00000000000
--- a/mit-pthreads/stdlib/rand.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rand.c 5.6 (Berkeley) 6/24/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <stdlib.h>
-
-static u_long next = 1;
-
-int rand_r(u_int * next_r)
-{
- int ret;
-
- (*next_r) = (*next_r) * 1103515245 + 12345;
- ret = (*next_r) & RAND_MAX;
- return(ret);
-}
-
-#undef rand
-int rand(void)
-{
- return ((next = next * 1103515245 + 12345) & RAND_MAX);
-}
-
-#undef srand
-void srand(unsigned int seed)
-{
- next = seed;
-}
diff --git a/mit-pthreads/stdlib/random.c b/mit-pthreads/stdlib/random.c
deleted file mode 100644
index 8cba96e7534..00000000000
--- a/mit-pthreads/stdlib/random.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)random.c 5.9 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/*
- * random.c:
- *
- * An improved random number generation package. In addition to the standard
- * rand()/srand() like interface, this package also has a special state info
- * interface. The initstate() routine is called with a seed, an array of
- * bytes, and a count of how many bytes are being passed in; this array is
- * then initialized to contain information for random number generation with
- * that much state information. Good sizes for the amount of state
- * information are 32, 64, 128, and 256 bytes. The state can be switched by
- * calling the setstate() routine with the same array as was initiallized
- * with initstate(). By default, the package runs with 128 bytes of state
- * information and generates far better random numbers than a linear
- * congruential generator. If the amount of state information is less than
- * 32 bytes, a simple linear congruential R.N.G. is used.
- *
- * Internally, the state information is treated as an array of longs; the
- * zeroeth element of the array is the type of R.N.G. being used (small
- * integer); the remainder of the array is the state information for the
- * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
- * state information, which will allow a degree seven polynomial. (Note:
- * the zeroeth word of state information also has some other information
- * stored in it -- see setstate() for details).
- *
- * The random number generation technique is a linear feedback shift register
- * approach, employing trinomials (since there are fewer terms to sum up that
- * way). In this approach, the least significant bit of all the numbers in
- * the state table will act as a linear feedback shift register, and will
- * have period 2^deg - 1 (where deg is the degree of the polynomial being
- * used, assuming that the polynomial is irreducible and primitive). The
- * higher order bits will have longer periods, since their values are also
- * influenced by pseudo-random carries out of the lower bits. The total
- * period of the generator is approximately deg*(2**deg - 1); thus doubling
- * the amount of state information has a vast influence on the period of the
- * generator. Note: the deg*(2**deg - 1) is an approximation only good for
- * large deg, when the period of the shift register is the dominant factor.
- * With deg equal to seven, the period is actually much longer than the
- * 7*(2**7 - 1) predicted by this formula.
- */
-
-/*
- * For each of the currently supported random number generators, we have a
- * break value on the amount of state information (you need at least this
- * many bytes of state info to support this random number generator), a degree
- * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
- * the separation between the two lower order coefficients of the trinomial.
- */
-#define TYPE_0 0 /* linear congruential */
-#define BREAK_0 8
-#define DEG_0 0
-#define SEP_0 0
-
-#define TYPE_1 1 /* x**7 + x**3 + 1 */
-#define BREAK_1 32
-#define DEG_1 7
-#define SEP_1 3
-
-#define TYPE_2 2 /* x**15 + x + 1 */
-#define BREAK_2 64
-#define DEG_2 15
-#define SEP_2 1
-
-#define TYPE_3 3 /* x**31 + x**3 + 1 */
-#define BREAK_3 128
-#define DEG_3 31
-#define SEP_3 3
-
-#define TYPE_4 4 /* x**63 + x + 1 */
-#define BREAK_4 256
-#define DEG_4 63
-#define SEP_4 1
-
-/*
- * Array versions of the above information to make code run faster --
- * relies on fact that TYPE_i == i.
- */
-#define MAX_TYPES 5 /* max number of types above */
-
-static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
-static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
-
-/*
- * Initially, everything is set up as if from:
- *
- * initstate(1, &randtbl, 128);
- *
- * Note that this initialization takes advantage of the fact that srandom()
- * advances the front and rear pointers 10*rand_deg times, and hence the
- * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
- * element of the state information, which contains info about the current
- * position of the rear pointer is just
- *
- * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
- */
-
-static long randtbl[DEG_3 + 1] = {
- TYPE_3,
- 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
- 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
- 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
- 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
- 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
- 0x27fb47b9,
-};
-
-/*
- * fptr and rptr are two pointers into the state info, a front and a rear
- * pointer. These two pointers are always rand_sep places aparts, as they
- * cycle cyclically through the state information. (Yes, this does mean we
- * could get away with just one pointer, but the code for random() is more
- * efficient this way). The pointers are left positioned as they would be
- * from the call
- *
- * initstate(1, randtbl, 128);
- *
- * (The position of the rear pointer, rptr, is really 0 (as explained above
- * in the initialization of randtbl) because the state table pointer is set
- * to point to randtbl[1] (as explained below).
- */
-static long *fptr = &randtbl[SEP_3 + 1];
-static long *rptr = &randtbl[1];
-
-/*
- * The following things are the pointer to the state information table, the
- * type of the current generator, the degree of the current polynomial being
- * used, and the separation between the two pointers. Note that for efficiency
- * of random(), we remember the first location of the state information, not
- * the zeroeth. Hence it is valid to access state[-1], which is used to
- * store the type of the R.N.G. Also, we remember the last location, since
- * this is more efficient than indexing every time to find the address of
- * the last element to see if the front and rear pointers have wrapped.
- */
-static long *state = &randtbl[1];
-static int rand_type = TYPE_3;
-static int rand_deg = DEG_3;
-static int rand_sep = SEP_3;
-static long *end_ptr = &randtbl[DEG_3 + 1];
-
-/*
- * State info won't be corrupted by multiple simultaneous calls,
- * but srandom(), initstate(), and setstate() affect all threads
- */
-static pthread_mutex_t random_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/*
- * random:
- *
- * If we are using the trivial TYPE_0 R.N.G., just do the old linear
- * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
- * the same in all the other cases due to all the global variables that have
- * been set up. The basic operation is to add the number at the rear pointer
- * into the one at the front pointer. Then both pointers are advanced to
- * the next location cyclically in the table. The value returned is the sum
- * generated, reduced to 31 bits by throwing away the "least random" low bit.
- *
- * Note: the code takes advantage of the fact that both the front and
- * rear pointers can't wrap on the same call by not testing the rear
- * pointer if the front one has wrapped.
- *
- * Returns a 31-bit random number.
- */
-static long random_basic()
-{
- long i;
-
- if (rand_type == TYPE_0)
- i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
- else {
- *fptr += *rptr;
- i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
- if (++fptr >= end_ptr) {
- fptr = state;
- ++rptr;
- } else if (++rptr >= end_ptr)
- rptr = state;
- }
- return(i);
-}
-
-long random()
-{
- long ret;
-
- pthread_mutex_lock(&random_mutex);
- ret = random_basic();
- pthread_mutex_unlock(&random_mutex);
- return(ret);
-}
-/*
- * srandom:
- *
- * Initialize the random number generator based on the given seed. If the
- * type is the trivial no-state-information type, just remember the seed.
- * Otherwise, initializes state[] based on the given "seed" via a linear
- * congruential generator. Then, the pointers are set to known locations
- * that are exactly rand_sep places apart. Lastly, it cycles the state
- * information a given number of times to get rid of any initial dependencies
- * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
- * for default usage relies on values produced by this routine.
- */
-static void srandom_basic(u_int x)
-{
- int i;
-
- state[0] = x;
- for (i = 1; i < rand_deg; i++)
- state[i] = 1103515245 * state[i - 1] + 12345;
- fptr = &state[rand_sep];
- rptr = &state[0];
-
- for (i = 0; i < 10 * rand_deg; i++)
- (void)random_basic();
-}
-
-void srandom(u_int x)
-{
- pthread_mutex_lock(&random_mutex);
- srandom_basic(x);
- pthread_mutex_unlock(&random_mutex);
-}
-
-/*
- * initstate:
- *
- * Initialize the state information in the given array of n bytes for future
- * random number generation. Based on the number of bytes we are given, and
- * the break values for the different R.N.G.'s, we choose the best (largest)
- * one we can and set things up for it. srandom() is then called to
- * initialize the state information.
- *
- * Note that on return from srandom(), we set state[-1] to be the type
- * multiplexed with the current value of the rear pointer; this is so
- * successive calls to initstate() won't lose this information and will be
- * able to restart with setstate().
- *
- * Note: the first thing we do is save the current state, if any, just like
- * setstate() so that it doesn't matter when initstate is called.
- *
- * Returns a pointer to the old state.
- */
-#ifdef initstate
-#undef initstate
-#endif
-char * initstate(u_int seed, char * arg_state, int n)
-{
- register char *ostate = (char *)(&state[-1]);
-
- pthread_mutex_lock(&random_mutex);
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
- if (n < BREAK_0) {
- (void)fprintf(stderr,
- "random: not enough state (%d bytes); ignored.\n", n);
- pthread_mutex_unlock(&random_mutex);
- return(0);
- }
- if (n < BREAK_1) {
- rand_type = TYPE_0;
- rand_deg = DEG_0;
- rand_sep = SEP_0;
- } else if (n < BREAK_2) {
- rand_type = TYPE_1;
- rand_deg = DEG_1;
- rand_sep = SEP_1;
- } else if (n < BREAK_3) {
- rand_type = TYPE_2;
- rand_deg = DEG_2;
- rand_sep = SEP_2;
- } else if (n < BREAK_4) {
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- } else {
- rand_type = TYPE_4;
- rand_deg = DEG_4;
- rand_sep = SEP_4;
- }
- state = &(((long *)arg_state)[1]); /* first location */
- end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
- srandom_basic(seed);
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES*(rptr - state) + rand_type;
- pthread_mutex_unlock(&random_mutex);
- return(ostate);
-}
-
-/*
- * setstate:
- *
- * Restore the state from the given state array.
- *
- * Note: it is important that we also remember the locations of the pointers
- * in the current state information, and restore the locations of the pointers
- * from the old state information. This is done by multiplexing the pointer
- * location into the zeroeth word of the state information.
- *
- * Note that due to the order in which things are done, it is OK to call
- * setstate() with the same state as the current state.
- *
- * Returns a pointer to the old state information.
- */
-#ifdef setstate
-#undef setstate
-#endif
-char * setstate(char * arg_state)
-{
- register long *new_state = (long *)arg_state;
- register int type = new_state[0] % MAX_TYPES;
- register int rear = new_state[0] / MAX_TYPES;
- char *ostate = (char *)(&state[-1]);
-
- pthread_mutex_lock(&random_mutex);
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
- switch(type) {
- case TYPE_0:
- case TYPE_1:
- case TYPE_2:
- case TYPE_3:
- case TYPE_4:
- rand_type = type;
- rand_deg = degrees[type];
- rand_sep = seps[type];
- break;
- default:
- (void)fprintf(stderr,
- "random: state info corrupted; not changed.\n");
- }
- state = &new_state[1];
- if (rand_type != TYPE_0) {
- rptr = &state[rear];
- fptr = &state[(rear + rand_sep) % rand_deg];
- }
- end_ptr = &state[rand_deg]; /* set end_ptr too */
-
- pthread_mutex_unlock(&random_mutex);
- return(ostate);
-}
-
diff --git a/mit-pthreads/stdlib/strtod.c b/mit-pthreads/stdlib/strtod.c
deleted file mode 100644
index 173ca1e4bdf..00000000000
--- a/mit-pthreads/stdlib/strtod.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
-** An alternative implemtation of "strtod()" that is both
-** simplier, and thread-safe.
-*/
-#include <pthread.h>
-#include <ctype.h>
-#include <math.h>
-
-#ifdef TEST
-# define strtod NewStrtod
-#include <stdio.h>
-#endif
-
-static double scaler10[] = {
- 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
-};
-static double scaler1[] = {
- 1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9
-};
-static double pastpoint[] = {
- 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
- 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17, 1e-18, 1e-19,
- 1e-20, 1e-21, 1e-22, 1e-23, 1e-24, 1e-25, 1e-26, 1e-27, 1e-28, 1e-29,
- 1e-30, 1e-31, 1e-32, 1e-33, 1e-34, 1e-35, 1e-36, 1e-37, 1e-38, 1e-39,
- 1e-40, 1e-41, 1e-42, 1e-43, 1e-44, 1e-45, 1e-46, 1e-47, 1e-48, 1e-49,
- 1e-50, 1e-51, 1e-52, 1e-53, 1e-54, 1e-55, 1e-56, 1e-57, 1e-58, 1e-59,
-};
-
-#ifndef DBL_MAX
-#define DBL_MAX 1.7976931348623157e+308
-#endif
-
-double strtod(const char *zNum, char **pzEnd){
- double rResult = 0.0;
- int isNegative = 0;
-
- while( isspace(*zNum) ){
- zNum++;
- }
- if( *zNum=='-' ){
- zNum++;
- isNegative = 1;
- }else if( *zNum=='+' ){
- zNum++;
- }
- while( isdigit(*zNum) ){
- rResult = rResult*10.0 + (*zNum - '0');
- zNum++;
- }
- if( *zNum=='.' ){
- int n = 0;
- zNum++;
- while( isdigit(*zNum) ){
- if( n<sizeof(pastpoint)/sizeof(pastpoint[0]) ){
- rResult += pastpoint[n] * (*zNum - '0');
- n++;
- }
- zNum++;
- }
- }
- if( *zNum=='e' || *zNum=='E' ){
- int expVal = 0;
- int isNegExp = 0;
- const char *zExpStart = zNum;
- zNum++;
- if( *zNum=='-' ){
- isNegExp = 1;
- zNum++;
- }else if( *zNum=='+' ){
- zNum++;
- }
- if( !isdigit(*zNum) ){
- zNum = zExpStart;
- }else{
- double scaler = 1.0;
- while( isdigit(*zNum) ){
- expVal = expVal*10 + *zNum - '0';
- zNum++;
- }
- if( expVal >= 1000 ){
- if( isNegExp ){
- rResult = 0.0;
- }else{
- rResult = DBL_MAX;
- }
- goto done;
- }
- while( expVal >= 100 ){
- scaler *= 1.0e100;
- expVal -= 100;
- }
- scaler *= scaler10[expVal/10]*scaler1[expVal%10];
- if( isNegExp ){
- scaler = 1.0/scaler;
- }
- rResult *= scaler;
- }
-
- }
-
-done:
- if( pzEnd ){
- *pzEnd = (char *)zNum;
- }
- if( isNegative && rResult!=0.0 ){
- rResult = -rResult;
- }
- return rResult;
-}
-
-double atof(const char *nptr)
-{
- return (strtod(nptr, 0));
-}
-
-#ifdef TEST
-#undef strtod
-
-double strtod(const char*,char**);
-double NewStrtod(const char*,char**);
-
-int main(int argc, char **argv){
- int nTest = 0;
- int nFail = 0;
- int nBigFail = 0;
- char zBuf[1000];
-
- while( fgets(zBuf,sizeof(zBuf),stdin) ){
- double old, new;
- char *zTailOld, *zTailNew;
- int i;
-
- for(i=0; zBuf[i] && zBuf[i]!='\n'; i++){}
- zBuf[i] = 0;
-
-#if TEST==1
- printf("Input line: [%s]\n",zBuf);
- old = strtod(zBuf,&zTailOld);
- printf("value=%g\n",old);
- printf("Old: 0x%08x%08x tail=[%s]\n",
- ((int*)&old)[1], ((int*)&old)[0], zTailOld);
- new = NewStrtod(zBuf,&zTailNew);
- printf("value=%g\n",new);
- printf("New: 0x%08x%08x tail=[%s]\n\n",
- ((int*)&new)[1], ((int*)&new)[0], zTailNew);
-#else
- old = strtod(zBuf,&zTailOld);
- new = NewStrtod(zBuf,&zTailNew);
- nTest++;
- if( strcmp(zTailOld,zTailNew)
- || ((int*)&old)[0]!=((int*)&new)[0]
- || ((int*)&old)[1]!=((int*)&new)[1]
- ){
- int olda, oldb, newa, newb;
-
- nFail++;
- olda = ((int*)&old)[1];
- oldb = ((int*)&old)[0];
- newa = ((int*)&new)[1];
- newb = ((int*)&new)[0];
-
- if( olda!=newa || abs(oldb-newb)>2 ){
- nBigFail++;
- printf("******* Big failure \n");
- }
- printf("Input = [%s]\n",zBuf);
- printf("old: val=%g 0x%08x%08x tail=[%s]\n",
- old, olda, oldb, zTailOld);
- printf("new: val=%g 0x%08x%08x tail=[%s]\n\n",
- new, newa, newb, zTailNew);
- }
-#endif
- }
-
- printf("Out of %d tests, %d failures and %d big failurs\n",
- nTest,nFail, nBigFail);
-}
-#endif
diff --git a/mit-pthreads/stdlib/strtol.c b/mit-pthreads/stdlib/strtol.c
deleted file mode 100644
index 91be90cc94c..00000000000
--- a/mit-pthreads/stdlib/strtol.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-
-
-/*
- * Convert a string to a long integer.
- *
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
-long
-strtol(nptr, endptr, base)
- const char *nptr;
- char **endptr;
- register int base;
-{
- register const char *s = nptr;
- register unsigned long acc;
- register int c;
- register unsigned long cutoff;
- register int neg = 0, any, cutlim;
-
- /*
- * Skip white space and pick up leading +/- sign if any.
- * If base is 0, allow 0x for hex and 0 for octal, else
- * assume decimal; if base is already 16, allow 0x.
- */
- do {
- c = *s++;
- } while (isspace(c));
- if (c == '-') {
- neg = 1;
- c = *s++;
- } else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
- c = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
-
- /*
- * Compute the cutoff value between legal numbers and illegal
- * numbers. That is the largest legal value, divided by the
- * base. An input number that is greater than this value, if
- * followed by a legal input character, is too big. One that
- * is equal to this value may be valid or not; the limit
- * between valid and invalid numbers is then based on the last
- * digit. For instance, if the range for longs is
- * [-2147483648..2147483647] and the input base is 10,
- * cutoff will be set to 214748364 and cutlim to either
- * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
- * a value > 214748364, or equal but the next digit is > 7 (or 8),
- * the number is too big, and we will return a range error.
- *
- * Set any if any `digits' consumed; make it negative to indicate
- * overflow.
- */
- cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
- cutlim = cutoff % (unsigned long)base;
- cutoff /= (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++) {
- if (isdigit(c))
- c -= '0';
- else if (isalpha(c))
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
- any = -1;
- else {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0) {
- acc = neg ? LONG_MIN : LONG_MAX;
- errno = ERANGE;
- } else if (neg)
- acc = -acc;
- if (endptr != 0)
- *endptr = (char *) (any ? s - 1 : nptr);
- return (acc);
-}
diff --git a/mit-pthreads/stdlib/strtoul.c b/mit-pthreads/stdlib/strtoul.c
deleted file mode 100644
index c6b6b01a0f2..00000000000
--- a/mit-pthreads/stdlib/strtoul.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 1990 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/*
- * Convert a string to an unsigned long integer.
- *
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
-unsigned long
-strtoul(nptr, endptr, base)
- const char *nptr;
- char **endptr;
- register int base;
-{
- register const char *s = nptr;
- register unsigned long acc;
- register int c;
- register unsigned long cutoff;
- register int neg = 0, any, cutlim;
-
- /*
- * See strtol for comments as to the logic used.
- */
- do {
- c = *s++;
- } while (isspace(c));
- if (c == '-') {
- neg = 1;
- c = *s++;
- } else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
- c = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
- cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
- cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++) {
- if (isdigit(c))
- c -= '0';
- else if (isalpha(c))
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
- any = -1;
- else {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0) {
- acc = ULONG_MAX;
- errno = ERANGE;
- } else if (neg)
- acc = -acc;
- if (endptr != 0)
- *endptr = (char *) (any ? s - 1 : nptr);
- return (acc);
-}
diff --git a/mit-pthreads/stdlib/system.c b/mit-pthreads/stdlib/system.c
deleted file mode 100644
index e7cc164fbc7..00000000000
--- a/mit-pthreads/stdlib/system.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <pthread/paths.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-
-extern char **environ;
-
-system(command)
- const char *command;
-{
- char *argp[] = {"sh", "-c", "*to be filled in*", NULL};
- void (*intsave)(), (*quitsave)(), (*signal())();
- sigset_t tmp_mask, old_mask;
- int pstat;
- pid_t pid;
-
- if (!command) /* just checking... */
- return(1);
-
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
- pthread_sigmask(SIG_BLOCK, &tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- return(-1);
- case 0: /* child */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- execve(_PATH_BSHELL, argp, environ);
- _exit(127);
- }
-
- intsave = pthread_signal(SIGINT, SIG_IGN);
- quitsave = pthread_signal(SIGQUIT, SIG_IGN);
- pid = waitpid(pid, (int *)&pstat, 0);
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- (void)pthread_signal(SIGQUIT, quitsave);
- (void)pthread_signal(SIGINT, intsave);
- return(pid == -1 ? -1 : pstat);
-}
diff --git a/mit-pthreads/string/GNUmakefile.inc b/mit-pthreads/string/GNUmakefile.inc
deleted file mode 100755
index f3994d31479..00000000000
--- a/mit-pthreads/string/GNUmakefile.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-VPATH:= ${VPATH}:${srcdir}/string
-
-SRCS:= strtok.c $(SRCS)
diff --git a/mit-pthreads/string/Makefile.inc b/mit-pthreads/string/Makefile.inc
deleted file mode 100644
index 4a5536bac4a..00000000000
--- a/mit-pthreads/string/Makefile.inc
+++ /dev/null
@@ -1,8 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# string sources
-.PATH: ${srcdir}/string
-
-SRCS+= strtok.c
-
diff --git a/mit-pthreads/string/strtok.c b/mit-pthreads/string/strtok.c
deleted file mode 100644
index 4c08dcc4d37..00000000000
--- a/mit-pthreads/string/strtok.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)strtok.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <string.h>
-#include <stdlib.h>
-
-char *
-strtok(s, delim)
- register char *s;
- register const char *delim;
-{
- static pthread_mutex_t strtok_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t strtok_key = -1;
- char **lasts;
-
- pthread_mutex_lock(&strtok_mutex);
- if (strtok_key < 0) {
- if (pthread_key_create(&strtok_key, free) < 0) {
- pthread_mutex_unlock(&strtok_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&strtok_mutex);
- if ((lasts = pthread_getspecific(strtok_key)) == NULL) {
- if ((lasts = (char **)malloc(sizeof(char *))) == NULL) {
- return(NULL);
- }
- pthread_setspecific(strtok_key, lasts);
- }
-
- return(strtok_r(s, delim, lasts));
-}
-
-char *
-strtok_r(s, delim, lasts)
- register char *s;
- register const char *delim;
- register char **lasts;
-{
- register char *spanp;
- register int c, sc;
- char *tok;
-
-
- if (s == NULL && (s = *lasts) == NULL)
- return (NULL);
-
- /*
- * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
- */
-cont:
- c = *s++;
- for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
- if (c == sc)
- goto cont;
- }
-
- if (c == 0) { /* no non-delimiter characters */
- *lasts = NULL;
- return (NULL);
- }
- tok = s - 1;
-
- /*
- * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
- * Note that delim must have one NUL; we stop if we see that, too.
- */
- for (;;) {
- c = *s++;
- spanp = (char *)delim;
- do {
- if ((sc = *spanp++) == c) {
- if (c == 0)
- s = NULL;
- else
- s[-1] = 0;
- *lasts = s;
- return (tok);
- }
- } while (sc != 0);
- }
- /* NOTREACHED */
-}
diff --git a/mit-pthreads/tests/.cvsignore b/mit-pthreads/tests/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/tests/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/tests/Makefile.in b/mit-pthreads/tests/Makefile.in
deleted file mode 100644
index 6e01b6bffc3..00000000000
--- a/mit-pthreads/tests/Makefile.in
+++ /dev/null
@@ -1,164 +0,0 @@
-# === GNUmakefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-CC = ../pgcc -notinstalled
-CPP = @CPP@
-srctop = @srctop@
-srcdir = @srctop@/tests
-VPATH = @srctop@/tests
-CDEBUGFLAGS = @CFLAGS@
-
-INCLUDES= -I../include -I.. -I$(srctop)/include
-CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
-LIBS = -lm -lgcc -L../obj/ -lpthread
-#LIBS = -static
-
-# This list used to include test_select, but that test doesn't terminate.
-TESTS = test_create test_pthread_join test_switch test_sleep test_readdir \
- test_fork test_execve test_preemption test_preemption_float \
- test_sock_1 test_sock_2 test_stdio_1 test_pthread_mutex \
- test_pthread_cond_timedwait test_netdb test_pw test_cwd
-# This list used to include p_bench_semaphore, but the semaphore support isn't
-# defined for all targets (or used for any).
-BENCHMARKS = p_bench_read p_bench_mutex p_bench_yield \
- p_bench_getpid p_bench_pthread_create
-
-all : $(TESTS) $(BENCHMARKS)
-
-check : $(TESTS)
- set -e ; \
- for i in $(TESTS) ; do \
- echo Running test $$i ... ; \
- ./$$i ; \
- done
-
-# More flags
-ADDITIONALFLAGS = -DPTHREAD_INITIAL_PORT
-################################################################################
-#
-
-clean:
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install:
-
-realclean: clean
- rm -f Makefile
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
-Makefile: Makefile.in
- (cd .. ; sh config.status)
-
-test_create : test_create.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_create test_create.o $(LIBS)
-
-test_pthread_join : test_pthread_join.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_pthread_join test_pthread_join.o $(LIBS)
-
-test_switch : test_switch.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_switch test_switch.o $(LIBS)
-
-test_sleep : test_sleep.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sleep test_sleep.o $(LIBS)
-
-test_readdir : test_readdir.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_readdir test_readdir.o $(LIBS)
-
-test_fork : test_fork.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_fork test_fork.o $(LIBS)
-
-test_execve : test_execve.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_execve test_execve.o $(LIBS)
-
-test_preemption : test_preemption.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_preemption test_preemption.o $(LIBS)
-
-test_preemption_float : test_preemption_float.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_preemption_float test_preemption_float.o $(LIBS)
-
-test_stdio_1 : test_stdio_1.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_stdio_1 test_stdio_1.o $(LIBS)
-
-test_sock_1 : test_sock_1.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sock_1 test_sock_1.o $(LIBS)
-
-test_sock_2 : test_sock_2a test_sock_2.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sock_2 test_sock_2.o $(LIBS)
-
-test_sock_2a : test_sock_2a.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sock_2a test_sock_2a.o $(LIBS)
-
-test_pthread_mutex : test_pthread_mutex.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_pthread_mutex test_pthread_mutex.o $(LIBS)
-
-test_pthread_cond_timedwait : test_pthread_cond_timedwait.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_pthread_cond_timedwait test_pthread_cond_timedwait.o $(LIBS)
-
-test_netdb : test_netdb.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_netdb test_netdb.o $(LIBS)
-
-test_select : test_select.o ../obj/libpthread.a
- $(CC) $(CFLAGS) -o test_select test_select.o $(LIBS)
-
-test_pw : test_pw.o ../obj/libpthread.a
- $(CC) $(CFLAGS) -o test_pw test_pw.o $(LIBS)
-
-test_cwd : test_cwd.o ../obj/libpthread.a
- $(CC) $(CFLAGS) -o test_cwd test_cwd.o $(LIBS)
-
-p_bench_read : p_bench_read.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_read p_bench_read.o $(LIBS)
-
-p_bench_semaphore : p_bench_semaphore.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_semaphore p_bench_semaphore.o $(LIBS)
-
-p_bench_mutex : p_bench_mutex.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_mutex p_bench_mutex.o $(LIBS)
-
-p_bench_yield : p_bench_yield.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_yield p_bench_yield.o $(LIBS)
-
-p_bench_getpid : p_bench_getpid.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_getpid p_bench_getpid.o $(LIBS)
-
-p_bench_pthread_create : p_bench_pthread_create.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_pthread_create p_bench_pthread_create.o $(LIBS)
-
-test_create.o : test_create.c
-test_pthread_join.o : test_pthread_join.c
-test_switch.o : test_switch.c
-test_sleep.o : test_sleep.c
-test_readdir.o : test_readdir.c
-test_fork.o : test_fork.c
-test_execve.o : test_execve.c
-test_preemption.o : test_preemption.c
-test_preemption_float.o : test_preemption_float.c
-test_sock_1.o : test_sock_1.c
-test_sock_2.o : test_sock_2.c
-test_sock_3.o : test_sock_3.c
-test_stdio_1.o : test_stdio_1.c
-test_pthread_mutex.o : test_pthread_mutex.c
-test_pthread_cond_timedwait.o : test_pthread_cond_timedwait.c
-p_bench_read.o : p_bench_read.c
-p_bench_semaphore.o : p_bench_semaphore.c
-p_bench_mutex.o : p_bench_mutex.c
-p_bench_yield.o : p_bench_yield.c
-p_bench_getpid.o : p_bench_getpid.c
-p_bench_pthread_create.o : p_bench_pthread_create.c
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/tests/README b/mit-pthreads/tests/README
deleted file mode 100755
index bb4a3e7ce01..00000000000
--- a/mit-pthreads/tests/README
+++ /dev/null
@@ -1,26 +0,0 @@
-This directory contains a few test and benchmark programs that I've
-developed to help me test the consistancy of the libpthread.a.
-
-TEST
-----------------------
-test_create Tests the pthread_create() routine. The stack addresses
- should be very different (ie the upper values of the
- address should be different) and the arg should be
- 0xdeadbeaf.
-
-test_switch A nondeterministic test. It should show context switching,
- by displaying different letters.
-
-test_sleep Timing this test should result in a time of about 20 seconds.
- It should sleep for 10 seconds and then print ba 10 times
- at the rate of about once a second.
-
-p_bench_* Benchmarks for various routines.
-
-------------------------------------------------------------------------------
-Copyright (c) 1994 Chris Provenzano. All rights reserved.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-For further licencing and distribution restrictions see the file COPYRIGHT
-included in the parent directory.
diff --git a/mit-pthreads/tests/bench_fcntl.c b/mit-pthreads/tests/bench_fcntl.c
deleted file mode 100644
index 046046adda4..00000000000
--- a/mit-pthreads/tests/bench_fcntl.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* ==== bench_read.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- int count = 1000000;
- int debug = 0;
- int flags;
- int fd;
- int i;
-
- char word[8192];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if ((fd = open("/dev/zero", O_RDONLY)) < OK) {
- printf("Error: open\n");
- exit(0);
- }
-
- if (gettimeofday(&starttime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
- for (i = 0; i < count; i++) {
- if ((flags = fcntl(0, F_GETFL)) < 0) {
- perror("fcntl 1st GETFL");
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
-
- printf("%d fcntls of /dev/null took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-}
diff --git a/mit-pthreads/tests/bench_pipe.c b/mit-pthreads/tests/bench_pipe.c
deleted file mode 100644
index 8555cf37f67..00000000000
--- a/mit-pthreads/tests/bench_pipe.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ==== bench_pipe.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("bench_pipe [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- char buf[1];
- int count = 1000;
- int debug = 0;
- int fd0[2];
- int fd1[2];
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if ((pipe(fd0) < OK) || (pipe(fd1) < OK)) {
- printf("Error: pipe\n");
- exit(0);
- }
-
- switch (fork()) {
- case NOTOK:
- printf("Error: fork\n");
- exit(0);
- case OK: /* Child */
- for (i = 0; i < count; i++) {
- if (read(fd1[0], buf, 1) < OK) {
- printf("Error: child read\n");
- exit(0);
- }
- if (write(fd0[1], buf, 1) < OK) {
- printf("Error: child write\n");
- exit(0);
- }
- }
- exit(0);
- break;
- default:
- break;
- }
-
- if (gettimeofday(&starttime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
- count --;
- if (write(fd1[1], buf, 1) < OK) {
- perror("first parent write");
- exit(0);
- }
- for (i = 0; i < count; i++) {
- if (read(fd0[0], buf, 1) < OK) {
- printf("Error: parent read\n");
- exit(0);
- }
- if (write(fd1[1], buf, 1) < OK) {
- printf("Error: parent write\n");
- exit(0);
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
-
- printf("%d ping pong tests took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-}
diff --git a/mit-pthreads/tests/bench_read.c b/mit-pthreads/tests/bench_read.c
deleted file mode 100644
index 28c8469e270..00000000000
--- a/mit-pthreads/tests/bench_read.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ==== bench_read.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count] [-s size]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- int count = 1000000;
- int debug = 0;
- int size = 1;
- int fd;
- int i;
-
- char word[8192];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while ((word[0] = getopt(argc, argv, "s:c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case 's':
- if ((size = atoi(optarg)) > 8192) {
- size = 8192;
- }
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if ((fd = open("/netbsd", O_RDONLY)) < OK) {
- printf("Error: open\n");
- exit(0);
- }
-
- if (gettimeofday(&starttime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
- for (i = 0; i < count; i++) {
- if (read(fd, word, size) < OK) {
- printf("Error: read\n");
- exit(0);
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
-
- printf("%d reads of /netbsd took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-}
diff --git a/mit-pthreads/tests/p_bench_getpid.c b/mit-pthreads/tests/p_bench_getpid.c
deleted file mode 100644
index d972d075c1d..00000000000
--- a/mit-pthreads/tests/p_bench_getpid.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== p_bench_getpid.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_getpid [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- pid_t process_id;
- int count = 1000000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- process_id = getpid();
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d getpid calls took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_mutex.c b/mit-pthreads/tests/p_bench_mutex.c
deleted file mode 100644
index e3179f08072..00000000000
--- a/mit-pthreads/tests/p_bench_mutex.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== p_bench_mutex.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- int count = 1000000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- pthread_mutex_init(&lock, NULL);
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- pthread_mutex_lock(&lock);
- pthread_mutex_unlock(&lock);
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d mutex locks/unlocks no contention took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_pthread_create.c b/mit-pthreads/tests/p_bench_pthread_create.c
deleted file mode 100644
index b31b680c665..00000000000
--- a/mit-pthreads/tests/p_bench_pthread_create.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ==== p_bench_pthread_create.c =============================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-extern pthread_attr_t pthread_attr_default;
-
-/* ==========================================================================
- * new_thread();
- */
-void * new_thread(void * arg)
-{
- PANIC();
-}
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_getpid [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- pthread_t thread_id;
- int count = 10000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
- /* Shut timer off */
- machdep_unset_thread_timer(NULL);
- pthread_attr_default.stackaddr_attr = &word;
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- if (pthread_create(&thread_id, & pthread_attr_default, new_thread, NULL)) {
- printf("Bad pthread create routine\n");
- exit(1);
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d getpid calls took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_read.c b/mit-pthreads/tests/p_bench_read.c
deleted file mode 100644
index 52a6aca7706..00000000000
--- a/mit-pthreads/tests/p_bench_read.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* ==== p_bench_read.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_read [-d?] [-c count] [-s size] [-f file]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- char *infile = "/dev/null";
- int count = 1000000;
- int debug = 0;
- int size = 1;
- int fd;
- int i;
-
- char word[16384], *word_ptr;
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:df:s:?")) != (char)EOF) {
- switch (word[0]) {
- case 'c':
- count = atoi(optarg);
- break;
- case 'd':
- debug++;
- break;
- case 'f':
- infile = optarg;
- break;
- case 's':
- if ((size = atoi(optarg)) > 8192) {
- size = 8192;
- }
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- /* Align buffer boundary to a page boundary */
- word_ptr = (char *)(((size_t) word + 4095) & ~4095);
-
- if ((fd = open(infile, O_RDONLY)) < OK) {
- perror ("open");
- return 1;
- }
-
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- for (i = 0; i < count; i++) {
- if (read(fd, word_ptr, size) < OK) {
- printf("Error: read\n");
- exit(0);
- }
- }
-
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d reads of %s took %d usecs.\n", count, infile,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_semaphore.c b/mit-pthreads/tests/p_bench_semaphore.c
deleted file mode 100644
index b3bce340b95..00000000000
--- a/mit-pthreads/tests/p_bench_semaphore.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* ==== p_bench_semaphore.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark semaphore Test and Set/ CLear times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- semaphore lock = SEMAPHORE_CLEAR;
- semaphore *lock_addr;
- int count = 1000000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- lock_addr = &lock;
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- if (SEMAPHORE_TEST_AND_SET(lock_addr)) {
- printf("Semaphore already locked error\n");
- return 1;
- }
- SEMAPHORE_RESET(lock_addr);
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d locks/unlocks of a semaphore took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_yield.c b/mit-pthreads/tests/p_bench_yield.c
deleted file mode 100644
index bb6d86be09e..00000000000
--- a/mit-pthreads/tests/p_bench_yield.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* ==== p_bench_mutex.c =================================================
- * Copyright (c) 1993-1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_yield [-d?] \\\n");
- printf("\t[-c count] \\\n");
- printf("\t[-C thread count] \\\n");
- printf("\t[-O optimization level]\n");
- errno = 0;
-}
-
-void *yield(void * arg)
-{
- int i, * count;
-
- count = (int *)arg;
- for (i = 0; i < *count; i++) {
- pthread_yield();
- }
- return(NULL);
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- pthread_attr_t attr;
- pthread_t thread_id;
- int thread_count = 1;
- int optimization = 0;
- int count = 1000000;
- int i, debug = 0;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "C:O:c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'C':
- thread_count = atoi(optarg);
- break;
- case 'O':
- optimization = atoi(optarg);
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case 'd':
- debug++;
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- pthread_attr_init(&attr);
- if (optimization > 0) {
- pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
- }
- if (optimization > 1) {
- pthread_attr_setfloatstate(&attr, PTHREAD_NOFLOAT);
- }
-
- pthread_mutex_init(&lock, NULL);
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 1; i < thread_count; i++) {
- if (pthread_create(&thread_id, &attr, yield, &count)) {
- perror ("pthread_create");
- return 1;
- }
- if (pthread_detach(thread_id)) {
- perror ("pthread_detach");
- return 1;
- }
- }
- if (pthread_create(&thread_id, &attr, yield, &count)) {
- perror ("pthread_create");
- return 1;
- }
- if (pthread_join(thread_id, NULL)) {
- perror ("pthread_join");
- return 1;
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d pthread_yields took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/test_create.c b/mit-pthreads/tests/test_create.c
deleted file mode 100644
index 2d82db07c5f..00000000000
--- a/mit-pthreads/tests/test_create.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ==== test_create.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <stdio.h>
-
-void* new_thread(void* arg)
-{
- int i;
-
- printf("New thread was passed arg address %x\n", arg);
- printf("New thread stack at %x\n", &i);
- return(NULL);
- PANIC();
-}
-
-main()
-{
- pthread_t thread;
- int i;
-
- printf("Original thread stack at %x\n", &i);
- if (pthread_create(&thread, NULL, new_thread, (void *)0xdeadbeef)) {
- printf("Error: creating new thread\n");
- }
- pthread_exit(NULL);
- PANIC();
-}
diff --git a/mit-pthreads/tests/test_cwd.c b/mit-pthreads/tests/test_cwd.c
deleted file mode 100644
index 979c173d5fc..00000000000
--- a/mit-pthreads/tests/test_cwd.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-
-main(int argc, char **argv)
-{
- char wd[1024], *getcwd(), *getwd();
-
- pthread_init();
- printf("getcwd => %s\n", getcwd(wd, 1024));
- printf("getwd => %s\n", getwd(wd));
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_execve.c b/mit-pthreads/tests/test_execve.c
deleted file mode 100644
index f7988457df9..00000000000
--- a/mit-pthreads/tests/test_execve.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ==== test_execve.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test execve() and dup2() calls.
- *
- * 1.00 94/04/29 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-extern char **environ;
-char *argv[] = {
- "/bin/echo",
- "This message should be displayed after the execve system call",
- NULL
-};
-
-char * should_succeed = "This line should be displayed\n";
-char * should_fail = "Error: This line should NOT be displayed\n";
-
-main()
-{
- pthread_t thread;
- int fd;
-
- pthread_init();
-
- printf("This is the first message\n");
- if (isatty(1)) {
- if ((fd = open(ttyname(1), O_RDWR)) < OK) {
- printf("Error: opening tty\n");
- exit(1);
- }
- } else {
- printf("Error: stdout not a tty\n");
- exit(1);
- }
-
- printf("This output is necessary to set the stdout fd to NONBLOCKING\n");
-
- /* do a dup2 */
- dup2(fd, 1);
- write(1, should_succeed, (size_t)strlen(should_succeed));
- machdep_sys_write(1, should_fail, strlen(should_fail));
-
- if (execve(argv[0], argv, environ) < OK) {
- printf("Error: execve\n");
- exit(1);
- }
- PANIC();
-}
diff --git a/mit-pthreads/tests/test_fcntl.c b/mit-pthreads/tests/test_fcntl.c
deleted file mode 100644
index 60bc77ce464..00000000000
--- a/mit-pthreads/tests/test_fcntl.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdio.h>
-#include <fcntl.h>
-
-main()
-{
- int flags, child;
-
- if ((flags = fcntl(0, F_GETFL)) < 0) {
- perror("fcntl 1st GETFL");
- }
- printf ("flags = %x\n", flags);
-
- switch(child = fork()) {
- case -1:
- printf("error during fork\n");
- break;
- case 0: /* child */
- execlp("test_create", "test_create", NULL);
- break;
- default: /* parent */
- wait(NULL);
- break;
- }
-
- while(1){
- if ((flags = fcntl(0, F_GETFL)) < 0) {
- perror("fcntl parent GETFL");
- }
- printf ("parent %d flags = %x\n", child, flags);
- sleep(1);
- }
-}
diff --git a/mit-pthreads/tests/test_fork.c b/mit-pthreads/tests/test_fork.c
deleted file mode 100644
index 4c2125e678a..00000000000
--- a/mit-pthreads/tests/test_fork.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ==== test_fork.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test fork() and dup2() calls.
- *
- * 1.00 94/04/29 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-main()
-{
- pthread_t thread;
- int flags, pid;
-
- pthread_init();
-
- if (((flags = machdep_sys_fcntl(1, F_GETFL, NULL)) >= OK) &&
- (flags & __FD_NONBLOCK | O_NDELAY)) {
- machdep_sys_fcntl(1, F_SETFL, flags & (~__FD_NONBLOCK | O_NDELAY));
- }
- printf("parent process %d\n", getpid());
-
- switch(pid = fork()) {
- case OK:
- exit(OK);
- break;
- case NOTOK:
- printf("fork() FAILED\n");
- exit(2);
- break;
- default:
- if ((flags = machdep_sys_fcntl(1, F_GETFL, NULL)) >= OK) {
- if (flags & (__FD_NONBLOCK | O_NDELAY)) {
- printf("fd flags not set to BLOCKING ERROR\n");
- printf("test_fork FAILED\n");
- exit(1);
- break;
- }
- printf("The stdout fd was set to BLOCKING\n");
- printf("child process %d\n", pid);
- flags = machdep_sys_fcntl(1, F_GETFL, NULL);
- if (flags & (__FD_NONBLOCK | O_NDELAY)) {
- printf("The stdout fd was reset to O_NDELAY\n");
- } else {
- printf("Error: the stdout fd was not reset\n");
- printf("test_fork FAILED\n");
- exit(1);
- }
- }
- break;
- }
-
- printf("test_fork PASSED\n");
- pthread_exit(NULL);
-}
diff --git a/mit-pthreads/tests/test_netdb.c b/mit-pthreads/tests/test_netdb.c
deleted file mode 100644
index a944579237f..00000000000
--- a/mit-pthreads/tests/test_netdb.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ==== test_netdb.c =========================================================
- * Copyright (c) 1995 by Greg Hudson, ghudson@.mit.edu
- *
- * Description : Test netdb calls.
- *
- * 1.00 95/01/05 ghudson
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL /* Needed for OK and NOTOK defines */
-#include <pthread.h>
-#include <string.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <errno.h>
-
-int debug = 0;
-
-static int test_serv()
-{
- struct servent *serv;
- char answer[1024];
-
- if (serv = getservbyname("telnet", "tcp"))
- printf("getservbyname -> port %d\n", ntohs(serv->s_port));
- else
- printf("getservbyname -> NULL (bad)\n");
-
- if (serv = getservbyname_r("telnet", "tcp", serv, answer, 1024))
- printf("getservbyname_r -> port %d\n", ntohs(serv->s_port));
- else
- printf("getservbyname_r -> NULL (bad)\n");
- return(OK);
-}
-
-static int test_host()
-{
- struct hostent *host;
- struct in_addr addr;
- char answer[1024];
- int error;
-
- if (host = gethostbyname("maze.mit.edu")) {
- memcpy(&addr, host->h_addr, sizeof(addr));
- printf("gethostbyname -> %s\n", inet_ntoa(addr));
- } else {
- printf("gethostbyname -> NULL (bad)\n");
- host = (struct hostent *)answer;
- }
-
- if (host = gethostbyname_r("maze.mit.edu", host, answer, 1024, &error)) {
- memcpy(&addr, host->h_addr, sizeof(addr));
- printf("gethostbyname_r -> %s\n", inet_ntoa(addr));
- } else {
- printf("gethostbyname_r -> NULL (bad)\n");
- }
- return(OK);
-}
-
-static int test_localhost()
-{
- struct hostent *host;
-
- if (host = gethostbyname("127.0.0.1")) {
- return(OK);
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("test_netdb [-d?]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
- char ch;
-
- while ((ch = getopt(argc, argv, "d?")) != (char)EOF) {
- switch (ch) {
- case 'd':
- debug++;
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- printf("test_netdb START\n");
-
- if (test_serv() || test_localhost() || test_host()) {
- printf("test_netdb FAILED\n");
- exit(1);
- }
-
- printf("test_netdb PASSED\n");
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_pause.c b/mit-pthreads/tests/test_pause.c
deleted file mode 100644
index 46c5080e43e..00000000000
--- a/mit-pthreads/tests/test_pause.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <stdio.h>
-#include <signal.h>
-
-foo(int sig)
-{
- return;
-}
-
-main()
-{
- sigset_t all;
-
- signal (1, foo);
- sigfillset(&all);
- sigprocmask(SIG_BLOCK, &all, NULL);
- printf("Begin pause\n");
- pause();
- printf("Done pause\n");
-}
diff --git a/mit-pthreads/tests/test_preemption.c b/mit-pthreads/tests/test_preemption.c
deleted file mode 100644
index 9181c127fe4..00000000000
--- a/mit-pthreads/tests/test_preemption.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* ==== test_pthread_cond.c =========================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_cond(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-
-void* new_thread(void * new_buf)
-{
- int i;
-
- for (i = 0; i < 10; i++) {
- pthread_yield();
- }
- printf("test_preemption PASSED\n");
- exit(0);
-}
-
-main()
-{
- pthread_t thread;
- int error;
-
- printf("test_preemption START\n");
-
- if (pthread_create(&thread, NULL, new_thread, NULL)) {
- printf("pthread_create failed\n");
- exit(2);
- }
-
- while(1);
- exit(1);
-}
diff --git a/mit-pthreads/tests/test_preemption_float.c b/mit-pthreads/tests/test_preemption_float.c
deleted file mode 100644
index e12192044c6..00000000000
--- a/mit-pthreads/tests/test_preemption_float.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Test to see if floating point state is being properly maintained
- for each thread. Different threads doing floating point operations
- simultaneously should not interfere with one another. This
- includes operations that might change some FPU flags, such as
- rounding modes, at least implicitly. */
-
-#include <pthread.h>
-#include <math.h>
-#include <stdio.h>
-
-int limit = 2;
-int float_passed = 0;
-int float_failed = 1;
-
-void *log_loop (void *x) {
- int i;
- double d, d1, d2;
- /* sleep (1); */
- for (i = 0; i < limit; i++) {
- d = 42.0;
- d = log (exp (d));
- d = (d + 39.0) / d;
- if (i == 0)
- d1 = d;
- else {
- d2 = d;
- d = sin(d);
- /* if (d2 != d1) { */
- if (memcmp (&d2, &d1, 8)) {
- pthread_exit(&float_failed);
- }
- }
- }
- pthread_exit(&float_passed);
-}
-
-void *trig_loop (void *x) {
- int i;
- double d, d1, d2;
- /* sleep (1); */
- for (i = 0; i < limit; i++) {
- d = 35.0;
- d *= M_PI;
- d /= M_LN2;
- d = sin (d);
- d = cos (1 / d);
- if (i == 0)
- d1 = d;
- else {
- d2 = d;
- d = sin(d);
- /* if (d2 != d1) { */
- if (memcmp (&d2, &d1, 8)) {
- pthread_exit(&float_failed);
- }
- }
- }
- pthread_exit(&float_passed);
-}
-
-#define N 10
-int main () {
- int i;
- pthread_t thread[2];
- pthread_attr_t attr;
- int *x, *y;
-
- pthread_init ();
- pthread_attr_init(&attr);
- pthread_attr_setfloatstate(&attr, PTHREAD_NOFLOAT);
-
- while(limit < 100000) {
- pthread_create (&thread[0], &attr, trig_loop, 0);
- pthread_create (&thread[1], &attr, log_loop, 0);
- pthread_join(thread[0], (void **) &x);
- pthread_join(thread[1], (void **) &y);
- if ((*x == float_failed) || (*y == float_failed)) {
- limit *= 4;
- break;
- }
- limit *= 4;
- }
- if ((*x == float_passed) && (*y == float_passed)) {
- printf("test_preemption_float INDETERMINATE\n");
- return(0);
- }
- pthread_create (&thread[0], NULL, trig_loop, 0);
- pthread_create (&thread[1], NULL, log_loop, 0);
- pthread_join(thread[0], (void **) &x);
- pthread_join(thread[1], (void **) &y);
-
- if ((*x == float_failed) || (*y == float_failed)) {
- printf("test_preemption_float FAILED\n");
- return(1);
- }
- printf("test_preemption_float PASSED\n");
- return(0);
-}
diff --git a/mit-pthreads/tests/test_pthread_cond_timedwait.c b/mit-pthreads/tests/test_pthread_cond_timedwait.c
deleted file mode 100644
index fe21408f11e..00000000000
--- a/mit-pthreads/tests/test_pthread_cond_timedwait.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* ==== test_pthread_cond.c =========================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_cond(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef ETIME
-#define ETIME ETIMEDOUT
-#endif
-
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
-void* thread_1(void * new_buf)
-{
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- pthread_exit(NULL);
-}
-
-void* thread_2(void * new_buf)
-{
- sleep(1);
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- pthread_exit(NULL);
-}
-
-main()
-{
- struct timespec abstime = { 0, 0 };
- struct timeval curtime;
- pthread_t thread;
- int error;
-
- pthread_init();
- printf("pthread_cond_timedwait START\n");
-
- pthread_mutex_lock(&mutex);
- gettimeofday(&curtime, NULL);
- abstime.tv_sec = curtime.tv_sec + 5;
-
- /* Test a condition timeout */
- if (pthread_cond_timedwait(&cond, &mutex, &abstime) != ETIME) {
- printf("pthread_cond_timedwait failed to timeout\n");
- printf("pthread_cond_timedwait FAILED\n");
- pthread_mutex_unlock(&mutex);
- exit(1);
- }
- printf("Got first timeout ok\n"); /* Added by monty */
- /* Test a normal condition signal */
- if (pthread_create(&thread, NULL, thread_1, NULL)) {
- printf("pthread_create failed\n");
- exit(2);
- }
-
- abstime.tv_sec = curtime.tv_sec + 10;
- if (pthread_cond_timedwait(&cond, &mutex, &abstime)) {
- printf("pthread_cond_timedwait #1 timedout\n");
- printf("pthread_cond_timedwait FAILED\n");
- pthread_mutex_unlock(&mutex);
- exit(1);
- }
-
- /* Test a normal condition signal after a sleep */
- if (pthread_create(&thread, NULL, thread_2, NULL)) {
- printf("pthread_create failed\n");
- exit(2);
- }
-
- pthread_yield();
-
- abstime.tv_sec = curtime.tv_sec + 10;
- if (pthread_cond_timedwait(&cond, &mutex, &abstime)) {
- printf("pthread_cond_timedwait #2 timedout\n");
- printf("pthread_cond_timedwait FAILED\n");
- pthread_mutex_unlock(&mutex);
- exit(1);
- }
-
- printf("pthread_cond_timedwait PASSED\n");
- pthread_mutex_unlock(&mutex);
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_pthread_join.c b/mit-pthreads/tests/test_pthread_join.c
deleted file mode 100644
index fd2ec6a78b2..00000000000
--- a/mit-pthreads/tests/test_pthread_join.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== test_pthread_join.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_join(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <stdio.h>
-
-/* This thread yields so the creator has a live thread to wait on */
-void* new_thread_1(void * new_buf)
-{
- int i;
-
- sprintf((char *)new_buf, "New thread %%d stack at %x\n", &i);
- pthread_yield();
- return(new_buf);
- PANIC();
-}
-
-/* This thread doesn't yield so the creator has a dead thread to wait on */
-void* new_thread_2(void * new_buf)
-{
- int i;
-
- sprintf((char *)new_buf, "New thread %%d stack at %x\n", &i);
- return(new_buf);
- PANIC();
-}
-
-main()
-{
- char buf[256], *status;
- pthread_t thread;
- int debug = 1;
- int i = 0;
-
- pthread_init();
-
- printf("Original thread stack at %x\n", &i);
- if (pthread_create(&thread, NULL, new_thread_1, (void *)buf) == OK) {
- if (pthread_join(thread, (void **)(&status)) == OK) {
- if (debug) { printf(status, ++i); }
- } else {
- printf("ERROR: Joining with new thread #1.\n");
- printf("FAILED: test_pthread_join\n");
- exit(1);
- }
- } else {
- printf("ERROR: Creating new thread #1\n");
- printf("FAILED: test_pthread_join\n");
- exit(2);
- }
-
-
- /* Now have the created thread finishing before the join. */
- if (pthread_create(&thread, NULL, new_thread_2, (void *)buf) == OK){
- pthread_yield();
- if (pthread_join(thread, (void **)(&status)) == OK) {
- if (debug) { printf(status, ++i); }
- } else {
- printf("ERROR: Joining with new thread #2.\n");
- printf("FAILED: test_pthread_join\n");
- exit(1);
- }
- } else {
- printf("ERROR: Creating new thread #2\n");
- printf("FAILED: test_pthread_join\n");
- exit(2);
- }
- printf("test_pthread_join PASSED\n");
- pthread_exit(NULL);
-}
-
diff --git a/mit-pthreads/tests/test_pthread_mutex.c b/mit-pthreads/tests/test_pthread_mutex.c
deleted file mode 100644
index 2fb0574f5cb..00000000000
--- a/mit-pthreads/tests/test_pthread_mutex.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* ==== test_pthread_cond.c =========================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_cond(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-int contention_variable;
-
-void * thread_contention(void * arg)
-{
- pthread_mutex_t * mutex = arg;
-
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- pthread_exit(NULL);
- }
-
- if (contention_variable != 1) {
- printf("contention_variable != 1 ERROR\n");
- pthread_exit(NULL);
- }
- contention_variable = 2;
-
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- pthread_exit(NULL);
- }
- pthread_exit(NULL);
-}
-
-int test_contention_lock(pthread_mutex_t * mutex)
-{
- pthread_t thread;
-
- printf("test_contention_lock()\n");
-
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- contention_variable = 0;
-
- if (pthread_create(&thread, NULL, thread_contention, mutex)) {
- printf("pthread_create() FAILED\n");
- exit(2);
- }
-
- pthread_yield();
-
- contention_variable = 1;
-
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
-
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
-
- if (contention_variable != 2) {
- printf("contention_variable != 2 ERROR\n");
- return(NOTOK);
- }
-
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
-
- return(OK);
-}
-
-int test_nocontention_lock(pthread_mutex_t * mutex)
-{
- printf("test_nocontention_lock()\n");
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_debug_double_lock(pthread_mutex_t * mutex)
-{
- printf("test_debug_double_lock()\n");
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_lock(mutex) != EDEADLK) {
- printf("double lock error not detected ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_debug_double_unlock(pthread_mutex_t * mutex)
-{
- printf("test_debug_double_unlock()\n");
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex) != EPERM) {
- printf("double unlock error not detected ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_nocontention_trylock(pthread_mutex_t * mutex)
-{
- printf("test_nocontention_trylock()\n");
- if (pthread_mutex_trylock(mutex)) {
- printf("pthread_mutex_trylock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_mutex_static(void)
-{
- pthread_mutex_t mutex_static = PTHREAD_MUTEX_INITIALIZER;
-
- printf("test_mutex_static()\n");
- if (test_nocontention_lock(&mutex_static) ||
- test_contention_lock(&mutex_static)) {
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_mutex_fast(void)
-{
- pthread_mutex_t mutex_fast;
-
- printf("test_mutex_fast()\n");
- if (pthread_mutex_init(&mutex_fast, NULL)) {
- printf("pthread_mutex_init() ERROR\n");
- return(NOTOK);
- }
- if (test_nocontention_lock(&mutex_fast) ||
- test_contention_lock(&mutex_fast)) {
- return(NOTOK);
- }
- if (pthread_mutex_destroy(&mutex_fast)) {
- printf("pthread_mutex_destroy() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_mutex_debug()
-{
- pthread_mutexattr_t mutex_debug_attr;
- pthread_mutex_t mutex_debug;
-
- printf("test_mutex_debug()\n");
- pthread_mutexattr_init(&mutex_debug_attr);
- pthread_mutexattr_settype(&mutex_debug_attr, PTHREAD_MUTEXTYPE_DEBUG);
-
- if (pthread_mutex_init(&mutex_debug, &mutex_debug_attr)) {
- printf("pthread_mutex_init() ERROR\n");
- return(NOTOK);
- }
- if (test_nocontention_lock(&mutex_debug) ||
- test_contention_lock(&mutex_debug) ||
- test_debug_double_lock(&mutex_debug) ||
- test_debug_double_unlock(&mutex_debug)) {
- return(NOTOK);
- }
- if (pthread_mutex_destroy(&mutex_debug)) {
- printf("pthread_mutex_destroy() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-main()
-{
- pthread_init();
-
- printf("test_pthread_mutex START\n");
-
- if (test_mutex_static() || test_mutex_fast() || test_mutex_debug()) {
- printf("test_pthread_mutex FAILED\n");
- exit(1);
- }
-
- printf("test_pthread_mutex PASSED\n");
- exit(0);
-}
-
diff --git a/mit-pthreads/tests/test_pw.c b/mit-pthreads/tests/test_pw.c
deleted file mode 100644
index 0ef6d428180..00000000000
--- a/mit-pthreads/tests/test_pw.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <pwd.h>
-
-main()
-{
- struct passwd *pw;
-
- pthread_init();
- pw = getpwuid(getuid());
- if (!pw) {
- printf("getpwuid(%d) died!\n", getuid());
- exit(1);
- }
- printf("getpwuid(%d) => %lx\n", getuid(), pw);
- printf(" you are: %s\n uid: %d\n gid: %d\n class: %s\n gecos: %s\n dir: %s\n shell: %s\n",
- pw->pw_name, pw->pw_uid, pw->pw_gid, pw->pw_class, pw->pw_gecos, pw->pw_dir,
- pw->pw_shell);
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_readdir.c b/mit-pthreads/tests/test_readdir.c
deleted file mode 100644
index 6de1841bdbc..00000000000
--- a/mit-pthreads/tests/test_readdir.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* ==== test_readdir.c ========================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 94/05/19 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <stdio.h>
-
-main()
-{
- struct dirent * file;
- DIR * dot_dir;
- int i, found = 0;
-
- pthread_init();
-
- if (dot_dir = opendir(".")) {
- while (file = readdir(dot_dir)) {
- if (!strcmp("test_readdir", file->d_name)) {
- found = 1;
- }
- }
- closedir(dot_dir);
- if (found) {
- printf("test_readdir PASSED\n");
- exit(0);
- } else {
- printf("Couldn't find file test_readdir ERROR\n");
- }
- } else {
- printf("opendir() ERROR\n");
- }
- printf("test_readdir FAILED\n");
- exit(1);
-}
-
diff --git a/mit-pthreads/tests/test_select.c b/mit-pthreads/tests/test_select.c
deleted file mode 100644
index 0401d77a666..00000000000
--- a/mit-pthreads/tests/test_select.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#ifndef ultrix
-#include <sys/fcntl.h>
-#else /* ultrix */
-#include <fcntl.h>
-#endif /* !ultrix */
-#include <sys/types.h>
-#include <sys/time.h>
-#ifdef hpux
-#include <sys/file.h>
-#endif /* hpux */
-#include <errno.h>
-#define NLOOPS 1000
-
-int ntouts = 0;
-
-void *
-bg_routine(void *arg)
-{
- write(1,"bg routine running\n",19);
- /*pthread_dump_state();*/
- while (1) {
- int n;
- char dot;
-
- dot = '.';
- pthread_yield();
- write(1,&dot,1);
- pthread_yield();
- n = NLOOPS;
- while (n-- > 0)
- pthread_yield();
- }
-}
-
-void *
-fg_routine(void *arg)
-{
- int flags, stat, nonblock_flag;
- static struct timeval tout = { 0, 500000 };
-
-#if 0
-#if defined(hpux) || defined(__alpha)
- nonblock_flag = O_NONBLOCK;
-#else
- nonblock_flag = FNDELAY;
-#endif
- printf("fg_routine running\n");
- flags = fcntl(0, F_GETFL, 0);
- printf("stdin flags b4 anything = %x\n", flags);
- stat = fcntl(0, F_SETFL, flags | nonblock_flag);
- if (stat < 0) {
- printf("fcntl(%x) => %d\n", nonblock_flag, errno);
- printf("could not set nonblocking i/o on stdin [oldf %x, stat %d]\n",
- flags, stat);
- exit(1);
- }
- printf("stdin flags = 0x%x after turning on %x\n", flags, nonblock_flag);
-#endif
- while (1) {
- int n;
- fd_set r;
-
- FD_ZERO(&r);
- FD_SET(0,&r);
- printf("select>");
- n = select(1, &r, (fd_set*)0, (fd_set*)0, (struct timeval *)0);
- if (n < 0) {
- perror ("select");
- exit(1);
- } else if (n > 0) {
- int nb;
- char buf[128];
-
- printf("=> select returned: %d\n", n);
- while ((nb = read(0, buf, sizeof(buf)-1)) >= 0) {
- buf[nb] = '\0';
- printf("read %d: |%s|\n", nb, buf);
- }
- printf("=> out of read loop: %d / %d\n", nb, errno);
- if (nb < 0) {
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- perror ("read");
- exit(1);
- }
- }
- } else
- ntouts++;
- }
-}
-
-main(int argc, char **argv)
-{
- pthread_t bg_thread, fg_thread;
- int junk;
-
- pthread_init();
- setbuf(stdout,NULL);
- setbuf(stderr,NULL);
- if (argc > 1) {
- if (pthread_create(&bg_thread, NULL, bg_routine, 0) < 0) {
- printf("error: could not create bg thread\n");
- exit(1);
- }
- }
- if (pthread_create(&fg_thread, NULL, fg_routine, 0) < 0) {
- printf("error: could not create fg thread\n");
- exit(1);
- }
- printf("threads forked: bg=%lx fg=%lx\n", bg_thread, fg_thread);
- /*pthread_dump_state();*/
- printf("initial thread %lx joining fg...\n", pthread_self());
- pthread_join(fg_thread, (void **)&junk);
-}
diff --git a/mit-pthreads/tests/test_setjmp.c b/mit-pthreads/tests/test_setjmp.c
deleted file mode 100644
index ea24ecd63bc..00000000000
--- a/mit-pthreads/tests/test_setjmp.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <setjmp.h>
-
-main()
-{
-jmp_buf foo;
-
-if (setjmp(foo)) {
- exit(0);
-}
-printf("Hi mom\n");
-longjmp(foo, 1);
-printf("Should never reach here\n");
-}
diff --git a/mit-pthreads/tests/test_sleep.c b/mit-pthreads/tests/test_sleep.c
deleted file mode 100644
index f228d08a2ca..00000000000
--- a/mit-pthreads/tests/test_sleep.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* ==== test_switch.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test context switch functionality.
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-
-const char buf[] = "abcdefghijklimnopqrstuvwxyz";
-int fd = 1;
-
-void* new_thread(void* arg)
-{
- int i;
-
- for (i = 0; i < 10; i++) {
- write(fd, buf + (long) arg, 1);
- sleep(1);
- }
-}
-
-main()
-{
- pthread_t thread;
- int count = 2;
- long i;
-
- pthread_init();
-
- printf("Going to sleep\n");
- sleep(10);
- printf("Done sleeping\n");
-
- for(i = 0; i < count; i++) {
- if (pthread_create(&thread, NULL, new_thread, (void *) i)) {
- printf("error creating new thread %d\n", i);
- }
- }
- pthread_exit(NULL);
- fprintf(stderr, "pthread_exit returned\n");
- exit(1);
-}
diff --git a/mit-pthreads/tests/test_sock_1.c b/mit-pthreads/tests/test_sock_1.c
deleted file mode 100644
index e23755a67dc..00000000000
--- a/mit-pthreads/tests/test_sock_1.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ==== test_sock_1.c =========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-struct sockaddr_in a_sout;
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_attr_t attr;
-
-#define MESSAGE5 "This should be message #5"
-#define MESSAGE6 "This should be message #6"
-
-void * sock_connect(void* arg)
-{
- char buf[1024];
- int fd, tmp;
-
- /* Ensure sock_read runs first */
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: sock_connect:pthread_mutex_lock()\n");
- exit(1);
- }
-
- a_sout.sin_addr.s_addr = htonl(0x7f000001); /* loopback */
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #2\n");
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
- close(fd);
-
- if (pthread_mutex_unlock(&mutex)) {
- printf("Error: sock_connect:pthread_mutex_lock()\n");
- exit(1);
- }
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #3\n");
-
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
-
- /* Ensure sock_read runs again */
- pthread_yield();
- pthread_yield();
- pthread_yield();
- pthread_yield();
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: sock_connect:pthread_mutex_lock()\n");
- exit(1);
- }
-
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- printf("Error: sock_connect:read() == %d\n", tmp);
- exit(1);
- }
- write(fd, MESSAGE6, sizeof(MESSAGE6));
- printf("%s\n", buf);
- close(fd);
-}
-
-extern struct fd_table_entry ** fd_table;
-void * sock_write(void* arg)
-{
- int fd = *(int *)arg;
-
- write(fd, MESSAGE5, sizeof(MESSAGE5));
- return(NULL);
-}
-
-void * sock_accept(void* arg)
-{
- pthread_t thread;
- struct sockaddr a_sin;
- int a_sin_size, a_fd, fd, tmp;
- short port;
- char buf[1024];
-
- if (pthread_mutex_unlock(&mutex)) {
- printf("Error: sock_accept:pthread_mutex_lock()\n");
- exit(1);
- }
-
- port = 3276;
- a_sout.sin_family = AF_INET;
- a_sout.sin_port = htons(port);
- a_sout.sin_addr.s_addr = INADDR_ANY;
-
- if ((a_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_accept:socket()\n");
- exit(1);
- }
-
- while (bind(a_fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- if (errno == EADDRINUSE) {
- a_sout.sin_port = htons((++port));
- continue;
- }
- printf("Error: sock_accept:bind()\n");
- exit(1);
- }
-
- if (listen(a_fd, 2)) {
- printf("Error: sock_accept:listen()\n");
- exit(1);
- }
-
- a_sin_size = sizeof(a_sin);
- printf("This should be message #1\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
-
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: sock_accept:pthread_mutex_lock()\n");
- exit(1);
- }
- close(fd);
-
- a_sin_size = sizeof(a_sin);
- printf("This should be message #4\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
-
- if (pthread_mutex_unlock(&mutex)) {
- printf("Error: sock_accept:pthread_mutex_lock()\n");
- exit(1);
- }
-
- /* Setup a write thread */
- if (pthread_create(&thread, &attr, sock_write, &fd)) {
- printf("Error: sock_accept:pthread_create(sock_write)\n");
- exit(1);
- }
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- printf("Error: sock_accept:read() == %d\n", tmp);
- exit(1);
- }
- printf("%s\n", buf);
- close(fd);
-}
-
-main()
-{
- pthread_t thread;
- int i;
-
- pthread_init();
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- /* Ensure sock_read runs first */
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: main:pthread_mutex_lock()\n");
- exit(1);
- }
-
- if (pthread_attr_init(&attr)) {
- printf("Error: main:pthread_attr_init()\n");
- exit(1);
- }
- if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
- printf("Error: main:pthread_attr_setschedpolicy()\n");
- exit(1);
- }
- if (pthread_create(&thread, &attr, sock_accept, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_accept)\n");
- exit(1);
- }
- if (pthread_create(&thread, &attr, sock_connect, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_connect)\n");
- exit(1);
- }
- printf("initial thread %lx going to sleep\n", pthread_self());
- sleep(10);
- printf("done sleeping\n");
- return 0;
-}
diff --git a/mit-pthreads/tests/test_sock_2.c b/mit-pthreads/tests/test_sock_2.c
deleted file mode 100644
index 5ec82fd7499..00000000000
--- a/mit-pthreads/tests/test_sock_2.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* ==== test_sock_1.c =========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-struct sockaddr_in a_sout;
-
-#define MESSAGE5 "This should be message #5"
-#define MESSAGE6 "This should be message #6"
-
-void * sock_write(void* arg)
-{
- int fd = *(int *)arg;
-
- write(fd, MESSAGE5, sizeof(MESSAGE5));
- return(NULL);
-}
-
-void * sock_accept(void* arg)
-{
- pthread_t thread;
- struct sockaddr a_sin;
- int a_sin_size, a_fd, fd, tmp;
- short port;
- char buf[1024];
-
- port = 3276;
- a_sout.sin_family = AF_INET;
- a_sout.sin_port = htons(port);
- a_sout.sin_addr.s_addr = INADDR_ANY;
-
- if ((a_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_accept:socket()\n");
- exit(1);
- }
-
- while (bind(a_fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- if (errno == EADDRINUSE) {
- a_sout.sin_port = htons((++port));
- continue;
- }
- printf("Error: sock_accept:bind()\n");
- exit(1);
- }
-
- if (listen(a_fd, 2)) {
- printf("Error: sock_accept:listen()\n");
- exit(1);
- }
-
- a_sin_size = sizeof(a_sin);
- printf("This should be message #1\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
- close(fd);
- sleep(1);
-
- a_sin_size = sizeof(a_sin);
- memset(&a_sin, 0, sizeof(a_sin));
- printf("This should be message #4\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
-
- /* Setup a write thread */
- if (pthread_create(&thread, NULL, sock_write, &fd)) {
- printf("Error: sock_accept:pthread_create(sock_write)\n");
- exit(1);
- }
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- tmp = read(fd, buf, 1024);
- printf("Error: sock_accept:read() == %d\n", tmp);
- exit(1);
- }
- printf("%s\n", buf);
- close(fd);
-}
-
-main()
-{
- pthread_t thread;
- int i;
-
- switch(fork()) {
- case -1:
- printf("Error: main:fork()\n");
- break;
- case 0:
- execl("test_sock_2a", "test_sock_2a", "fork okay", NULL);
- default:
- break;
- }
-
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- if (pthread_create(&thread, NULL, sock_accept, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_accept)\n");
- exit(1);
- }
- pthread_exit(NULL);
-}
diff --git a/mit-pthreads/tests/test_sock_2a.c b/mit-pthreads/tests/test_sock_2a.c
deleted file mode 100644
index 9f767b7c675..00000000000
--- a/mit-pthreads/tests/test_sock_2a.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ==== test_sock_1.c =========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-struct sockaddr_in a_sout;
-
-#define MESSAGE5 "This should be message #5"
-#define MESSAGE6 "This should be message #6"
-
-void * sock_connect(void* arg)
-{
- char buf[1024];
- int fd, tmp;
- short port;
-
- port = 3276;
- a_sout.sin_family = AF_INET;
- a_sout.sin_port = htons(port);
- a_sout.sin_addr.s_addr = htonl(0x7f000001); /* loopback */
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #2\n");
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
- close(fd);
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #3\n");
-
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
-
- /* Ensure sock_read runs again */
-
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- printf("Error: sock_connect:read() == %d\n", tmp);
- exit(1);
- }
- write(fd, MESSAGE6, sizeof(MESSAGE6));
- printf("%s\n", buf);
- close(fd);
-}
-
-main(int argc, char **argv)
-{
- pthread_t thread;
- int i;
-
- if (argv[1] && (!strcmp(argv[1], "fork okay"))) {
- sleep(1);
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- if (pthread_create(&thread, NULL, sock_connect, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_connect)\n");
- exit(1);
- }
- pthread_exit(NULL);
- }
- printf("test_sock_2a needs to be execed from test_sock_2.\n");
- printf("It is not a stand alone test.\n");
- exit(1);
-}
diff --git a/mit-pthreads/tests/test_stdio_1.c b/mit-pthreads/tests/test_stdio_1.c
deleted file mode 100644
index 648343a2c9d..00000000000
--- a/mit-pthreads/tests/test_stdio_1.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-char * base_name = "test_stdio_1.c";
-char * dir_name = SRCDIR;
-char * fullname;
-
-#define OK 0
-#define NOTOK -1
-
-/* Test fopen()/ftell()/getc() */
-int test_1(void)
-{
- struct stat statbuf;
- FILE * fp;
- int i;
-
- if (stat(fullname, &statbuf) < OK) {
- printf("ERROR: Couldn't stat %s\n", fullname);
- return(NOTOK);
- }
-
- if ((fp = fopen(fullname, "r")) == NULL) {
- printf("ERROR: Couldn't open %s\n", fullname);
- return(NOTOK);
- }
-
- /* Get the entire file */
- while ((i = getc(fp)) != EOF);
-
- if (ftell(fp) != statbuf.st_size) {
- printf("ERROR: ftell() and stat() don't agree.");
- return(NOTOK);
- }
-
- if (fclose(fp) < OK) {
- printf("ERROR: fclose() failed.");
- return(NOTOK);
- }
- return(OK);
-}
-
-/* Test fopen()/fclose() */
-int test_2(void)
-{
- FILE *fp1, *fp2;
-
- if ((fp1 = fopen(fullname, "r")) == NULL) {
- printf("ERROR: Couldn't fopen %s\n", fullname);
- return(NOTOK);
- }
-
- if (fclose(fp1) < OK) {
- printf("ERROR: fclose() failed.");
- return(NOTOK);
- }
-
- if ((fp2 = fopen(fullname, "r")) == NULL) {
- printf("ERROR: Couldn't fopen %s\n", fullname);
- return(NOTOK);
- }
-
- if (fclose(fp2) < OK) {
- printf("ERROR: fclose() failed.");
- return(NOTOK);
- }
-
- if (fp1 != fp2) {
- printf("ERROR: FILE table leak.\n");
- return(NOTOK);
- }
-
- return(OK);
-}
-
-/* Test sscanf()/sprintf() */
-int test_3(void)
-{
- char * str = "10 4.53";
- char buf[64];
- double d;
- int i;
-
- if (sscanf(str, "%d %lf", &i, &d) != 2) {
- printf("ERROR: sscanf didn't parse input string correctly\n");
- return(NOTOK);
- }
-
- /* Should have a check */
- sprintf(buf, "%d %2.2lf", i, d);
-
- if (strcmp(buf, str)) {
- printf("ERROR: sscanf()/sprintf() didn't parse unparse correctly\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-main()
-{
-
- printf("test_stdio_1 START\n");
-
- if (fullname = malloc (strlen (dir_name) + strlen (base_name) + 2)) {
- sprintf (fullname, "%s/%s", dir_name, base_name);
- } else {
- perror ("malloc");
- exit(1);
- }
-
- if (test_1() || test_2() || test_3()) {
- printf("test_stdio_1 FAILED\n");
- exit(1);
- }
-
- printf("test_stdio_1 PASSED\n");
- exit(0);
-}
-
-
diff --git a/mit-pthreads/tests/test_switch.c b/mit-pthreads/tests/test_switch.c
deleted file mode 100644
index 4c184158fb8..00000000000
--- a/mit-pthreads/tests/test_switch.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== test_switch.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test context switch functionality.
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-
-const char buf[] = "abcdefghijklmnopqrstuvwxyz";
-char x[sizeof(buf)];
-int fd = 1;
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("test_switch [-d?] [-c count]\n");
- printf("count must be between 2 and 26\n");
- errno = 0;
-}
-
-void* new_thread(void* arg)
-{
- while(1) {
- write (fd, (char *) arg, 1);
- x[(char *)arg - buf] = 1;
- }
- fprintf(stderr, "Compiler error\n");
- exit(1);
-}
-
-main(int argc, char **argv)
-{
- pthread_t thread;
- int count = 2;
- int debug = 0;
- int eof = 0;
- long i;
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while (!eof)
- switch (getopt (argc, argv, "c:d?"))
- {
- case EOF:
- eof = 1;
- break;
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- if ((count > 26) || (count < 2)) {
- count = 2;
- }
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
-
- for (i = 0; i < count; i++) {
- if (pthread_create(&thread, NULL, new_thread, (void*)(buf+i))) {
- fprintf (stderr, "error creating new thread %d\n", i);
- exit (1);
- }
- }
-#if 0 /* This would cause the program to loop forever, and "make
- check" would never complete. */
- pthread_exit (NULL);
- fprintf(stderr, "pthread_exit returned\n");
- exit(1);
-#else
- sleep (10);
- for (i = 0; i < count; i++)
- if (x[i] == 0) {
- fprintf (stderr, "thread %d never ran\n", i);
- return 1;
- }
- printf ("\n%s PASSED\n", argv[0]);
- return 0;
-#endif
-}
diff --git a/myisam/Makefile.am b/myisam/Makefile.am
index a18ff55ba9e..6802bcb115f 100644
--- a/myisam/Makefile.am
+++ b/myisam/Makefile.am
@@ -1,15 +1,15 @@
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-#
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -17,7 +17,7 @@
EXTRA_DIST = mi_test_all.sh mi_test_all.res
pkgdata_DATA = mi_test_all mi_test_all.res
-INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
+INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a ../mysys/libmysys.a \
../dbug/libdbug.a ../strings/libmystrings.a
pkglib_LIBRARIES = libmyisam.a
@@ -25,13 +25,14 @@ bin_PROGRAMS = myisamchk myisamlog myisampack
myisamchk_DEPENDENCIES= $(LIBRARIES)
myisamlog_DEPENDENCIES= $(LIBRARIES)
myisampack_DEPENDENCIES=$(LIBRARIES)
-noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 ft_test1 ft_eval
+noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 ft_dump #ft_test1 ft_eval
noinst_HEADERS = myisamdef.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
mi_test1_DEPENDENCIES= $(LIBRARIES)
mi_test2_DEPENDENCIES= $(LIBRARIES)
mi_test3_DEPENDENCIES= $(LIBRARIES)
-ft_test1_DEPENDENCIES= $(LIBRARIES)
-ft_eval_DEPENDENCIES= $(LIBRARIES)
+#ft_test1_DEPENDENCIES= $(LIBRARIES)
+#ft_eval_DEPENDENCIES= $(LIBRARIES)
+ft_dump_DEPENDENCIES= $(LIBRARIES)
libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_rnext.c mi_rnext_same.c \
mi_search.c mi_page.c mi_key.c mi_locking.c \
@@ -44,8 +45,8 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_range.c mi_dbug.c mi_checksum.c mi_log.c \
mi_changed.c mi_static.c mi_delete_all.c \
mi_delete_table.c mi_rename.c mi_check.c \
- ft_parser.c ft_search.c ft_stopwords.c ft_static.c \
- ft_update.c sort.c
+ ft_parser.c ft_stopwords.c ft_static.c \
+ ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c
CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all
DEFS = -DMAP_TO_USE_RAID
# Omit dependency for ../mit-pthreads/include/sys that only exits if
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c
new file mode 100644
index 00000000000..031d5e847e8
--- /dev/null
+++ b/myisam/ft_boolean_search.c
@@ -0,0 +1,603 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+
+/* TODO: add caching - pre-read several index entries at once */
+
+#define FT_CORE
+#include "ftdefs.h"
+#include <queues.h>
+
+/* search with boolean queries */
+
+static double _wghts[11]=
+{
+ 0.131687242798354,
+ 0.197530864197531,
+ 0.296296296296296,
+ 0.444444444444444,
+ 0.666666666666667,
+ 1.000000000000000,
+ 1.500000000000000,
+ 2.250000000000000,
+ 3.375000000000000,
+ 5.062500000000000,
+ 7.593750000000000};
+static double *wghts=_wghts+5; /* wghts[i] = 1.5**i */
+
+static double _nwghts[11]=
+{
+ -0.065843621399177,
+ -0.098765432098766,
+ -0.148148148148148,
+ -0.222222222222222,
+ -0.333333333333334,
+ -0.500000000000000,
+ -0.750000000000000,
+ -1.125000000000000,
+ -1.687500000000000,
+ -2.531250000000000,
+ -3.796875000000000};
+static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */
+
+#define FTB_FLAG_TRUNC 1 /* MUST be 1 */
+#define FTB_FLAG_YES 2 /* These two - YES and NO */
+#define FTB_FLAG_NO 4 /* should NEVER be set both */
+
+typedef struct st_ftb_expr FTB_EXPR;
+struct st_ftb_expr
+{
+ FTB_EXPR *up;
+ byte *quot, *qend;
+ float weight;
+ uint flags;
+ my_off_t docid[2]; /* for index search and for scan */
+ float cur_weight;
+ int yesses; /* number of "yes" words matched */
+ int nos; /* number of "no" words matched */
+ int ythresh; /* number of "yes" words in expr */
+ int yweaks; /* number of "yes" words for scan only */
+};
+
+typedef struct st_ftb_word
+{
+ FTB_EXPR *up;
+ float weight;
+ uint flags;
+ my_off_t docid[2]; /* for index search and for scan */
+ uint ndepth;
+ int len;
+ /* ... docid cache can be added here. SerG */
+ byte word[1];
+} FTB_WORD;
+
+typedef struct st_ft_info
+{
+ struct _ft_vft *please;
+ MI_INFO *info;
+ uint keynr;
+ CHARSET_INFO *charset;
+ enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE /*, SCAN*/ } state;
+ uint with_scan;
+ FTB_EXPR *root;
+ QUEUE queue;
+ TREE no_dupes;
+ FTB_WORD **list;
+ MEM_ROOT mem_root;
+} FTB;
+
+int FTB_WORD_cmp(void *v __attribute__((unused)), FTB_WORD *a, FTB_WORD *b)
+{
+ /* ORDER BY docid, ndepth DESC */
+ int i=CMP_NUM(a->docid[0], b->docid[0]);
+ if (!i)
+ i=CMP_NUM(b->ndepth,a->ndepth);
+ return i;
+}
+
+int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
+{
+ /* ORDER BY word DESC, ndepth DESC */
+ int i=_mi_compare_text(cs, (*b)->word+1,(*b)->len-1,
+ (*a)->word+1,(*a)->len-1,0);
+ if (!i)
+ i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
+ return i;
+}
+
+void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
+ FTB_EXPR *up, uint depth)
+{
+ byte res;
+ FTB_PARAM param;
+ FT_WORD w;
+ FTB_WORD *ftbw;
+ FTB_EXPR *ftbe;
+ uint extra=HA_FT_WLEN+ftb->info->s->rec_reflength; /* just a shortcut */
+
+ if (ftb->state != UNINITIALIZED)
+ return;
+
+ param.prev=' ';
+ param.quot=up->quot;
+ while ((res=ft_get_word(start,end,&w,&param)))
+ {
+ int r=param.plusminus;
+ float weight= (float) (param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)];
+ switch (res) {
+ case 1: /* word found */
+ ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
+ sizeof(FTB_WORD) +
+ (param.trunc ? MI_MAX_KEY_BUFF :
+ w.len+extra));
+ ftbw->len=w.len+1;
+ ftbw->flags=0;
+ if (param.yesno>0) ftbw->flags|=FTB_FLAG_YES;
+ if (param.yesno<0) ftbw->flags|=FTB_FLAG_NO;
+ if (param.trunc) ftbw->flags|=FTB_FLAG_TRUNC;
+ ftbw->weight=weight;
+ ftbw->up=up;
+ ftbw->docid[0]=ftbw->docid[1]=HA_POS_ERROR;
+ ftbw->ndepth= (param.yesno<0) + depth;
+ memcpy(ftbw->word+1, w.pos, w.len);
+ ftbw->word[0]=w.len;
+ if (param.yesno > 0) up->ythresh++;
+ queue_insert(& ftb->queue, (byte *)ftbw);
+ ftb->with_scan|=(param.trunc & FTB_FLAG_TRUNC);
+ break;
+ case 2: /* left bracket */
+ ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR));
+ ftbe->flags=0;
+ if (param.yesno>0) ftbe->flags|=FTB_FLAG_YES;
+ if (param.yesno<0) ftbe->flags|=FTB_FLAG_NO;
+ ftbe->weight=weight;
+ ftbe->up=up;
+ ftbe->ythresh=ftbe->yweaks=0;
+ ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
+ if ((ftbe->quot=param.quot)) ftb->with_scan|=2;
+ if (param.yesno > 0) up->ythresh++;
+ _ftb_parse_query(ftb, start, end, ftbe, depth+1);
+ param.quot=0;
+ break;
+ case 3: /* right bracket */
+ if (up->quot) up->qend=param.quot;
+ return;
+ }
+ }
+ return;
+}
+
+static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)),
+ const void *a,const void *b)
+{
+ return CMP_NUM((*((my_off_t*)a)), (*((my_off_t*)b)));
+}
+
+void _ftb_init_index_search(FT_INFO *ftb)
+{
+ int i, r;
+ FTB_WORD *ftbw;
+ MI_INFO *info=ftb->info;
+ MI_KEYDEF *keyinfo;
+ my_off_t keyroot;
+
+ if (ftb->state != READY || ftb->keynr == NO_SUCH_KEY)
+ return;
+ ftb->state=INDEX_SEARCH;
+
+ keyinfo=info->s->keyinfo+ftb->keynr;
+ keyroot=info->s->state.key_root[ftb->keynr];
+
+ for (i=ftb->queue.elements; i; i--)
+ {
+ ftbw=(FTB_WORD *)(ftb->queue.root[i]);
+
+ if (ftbw->flags & FTB_FLAG_TRUNC)
+ {
+ /*
+ special treatment for truncation operator :((
+ 1. +trunc* and there're other (not +trunc*) words
+ | no need to search in the index, it can never ADD new rows
+ | to the result, and to remove half-matched rows we do scan anyway
+ 2. -trunc*
+ | same as 1.
+ 3. trunc*
+ | We have to index-search for this prefix.
+ | It may cause duplicates, as in the index (sorted by <word,docid>)
+ | <aaaa,row1>
+ | <aabb,row2>
+ | <aacc,row1>
+ | Searching for "aa*" will find row1 twice...
+ */
+ if ( test(ftbw->flags&FTB_FLAG_NO) || /* 2 */
+ (test(ftbw->flags&FTB_FLAG_YES) && /* 1 */
+ ftbw->up->ythresh - ftbw->up->yweaks >1)) /* 1 */
+ {
+ ftbw->docid[0]=HA_POS_ERROR;
+ ftbw->up->yweaks++;
+ continue;
+ }
+ else /* 3 */
+ {
+ if (!is_tree_inited(& ftb->no_dupes))
+ {
+ init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t),
+ _ftb_no_dupes_cmp,0,0,0);
+ }
+ }
+ }
+ r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len,
+ SEARCH_FIND | SEARCH_BIGGER, keyroot);
+ if (!r)
+ {
+ r=_mi_compare_text(ftb->charset,
+ info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ 0);
+ }
+ if (r) /* not found */
+ {
+ if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0)
+ {
+ /*
+ This word MUST BE present in every document returned,
+ so we can abort the search right now
+ */
+ ftb->state=INDEX_DONE;
+ return;
+ }
+ }
+ else
+ {
+ memcpy(ftbw->word, info->lastkey, info->lastkey_length);
+ ftbw->docid[0]=info->lastpos;
+ }
+ }
+ queue_fix(& ftb->queue);
+}
+
+
+FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
+ uint query_len,
+ my_bool presort __attribute__((unused)))
+{
+ FTB *ftb;
+ FTB_EXPR *ftbe;
+ uint res;
+
+ if (!(ftb=(FTB *)my_malloc(sizeof(FTB), MYF(MY_WME))))
+ return 0;
+ ftb->please= (struct _ft_vft *) & _ft_vft_boolean;
+ ftb->state=UNINITIALIZED;
+ ftb->info=info;
+ ftb->keynr=keynr;
+ ftb->charset= ((keynr==NO_SUCH_KEY) ?
+ default_charset_info :
+ info->s->keyinfo[keynr].seg->charset);
+ ftb->with_scan=0;
+ bzero(& ftb->no_dupes, sizeof(TREE));
+
+ init_alloc_root(&ftb->mem_root, 1024, 1024);
+
+ /*
+ Hack: instead of init_queue, we'll use reinit queue to be able
+ to alloc queue with alloc_root()
+ */
+ res=ftb->queue.max_elements=1+query_len/(ft_min_word_len+1);
+ ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*));
+ reinit_queue(& ftb->queue, res, 0, 0,
+ (int (*)(void*,byte*,byte*))FTB_WORD_cmp, ftb);
+ ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR));
+ ftbe->weight=1;
+ ftbe->flags=FTB_FLAG_YES;
+ ftbe->nos=1;
+ ftbe->quot=0;
+ ftbe->up=0;
+ ftbe->ythresh=ftbe->yweaks=0;
+ ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
+ ftb->root=ftbe;
+ _ftb_parse_query(ftb, &query, query+query_len, ftbe, 0);
+ ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
+ sizeof(FTB_WORD *)*ftb->queue.elements);
+ memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements);
+ qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *),
+ (qsort2_cmp)FTB_WORD_cmp_list, ftb->charset);
+ if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC;
+ ftb->state=READY;
+ return ftb;
+}
+
+
+/* returns 1 if str0 contain str1 */
+int _ftb_strstr(const byte *s0, const byte *e0,
+ const byte *s1, const byte *e1,
+ CHARSET_INFO *cs)
+{
+ const byte *p;
+
+ while (s0 < e0)
+ {
+ while (s0 < e0 && cs->to_upper[(uint) (uchar) *s0++] !=
+ cs->to_upper[(uint) (uchar) *s1])
+ /* no-op */;
+ if (s0 >= e0)
+ return 0;
+ p=s1+1;
+ while (s0 < e0 && p < e1 && cs->to_upper[(uint) (uchar) *s0++] ==
+ cs->to_upper[(uint) (uchar) *p++])
+ /* no-op */;
+ if (p >= e1)
+ return 1;
+ }
+ return 0;
+}
+
+
+void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
+{
+ FT_SEG_ITERATOR ftsi;
+ FTB_EXPR *ftbe;
+ float weight=ftbw->weight;
+ int yn=ftbw->flags, ythresh, mode=(ftsi_orig != 0);
+ my_off_t curdoc=ftbw->docid[mode];
+
+ for (ftbe=ftbw->up; ftbe; ftbe=ftbe->up)
+ {
+ ythresh = ftbe->ythresh - (mode ? 0 : ftbe->yweaks);
+ if (ftbe->docid[mode] != curdoc)
+ {
+ ftbe->cur_weight=0;
+ ftbe->yesses=ftbe->nos=0;
+ ftbe->docid[mode]=curdoc;
+ }
+ if (ftbe->nos)
+ break;
+ if (yn & FTB_FLAG_YES)
+ {
+ weight /= ftbe->ythresh;
+ ftbe->cur_weight += weight;
+ if (++ftbe->yesses == ythresh)
+ {
+ yn=ftbe->flags;
+ weight=ftbe->cur_weight*ftbe->weight;
+ if (mode && ftbe->quot)
+ {
+ int not_found=1;
+
+ memcpy(&ftsi, ftsi_orig, sizeof(ftsi));
+ while (_mi_ft_segiterator(&ftsi) && not_found)
+ {
+ if (!ftsi.pos)
+ continue;
+ not_found = ! _ftb_strstr(ftsi.pos, ftsi.pos+ftsi.len,
+ ftbe->quot, ftbe->qend, ftb->charset);
+ }
+ if (not_found) break;
+ } /* ftbe->quot */
+ }
+ else
+ break;
+ }
+ else
+ if (yn & FTB_FLAG_NO)
+ {
+ /*
+ NOTE: special sort function of queue assures that all
+ (yn & FTB_FLAG_NO) != 0
+ events for every particular subexpression will
+ "auto-magically" happen BEFORE all the
+ (yn & FTB_FLAG_YES) != 0 events. So no
+ already matched expression can become not-matched again.
+ */
+ ++ftbe->nos;
+ break;
+ }
+ else
+ {
+ if (ftbe->ythresh)
+ weight/=3;
+ ftbe->cur_weight += weight;
+ if (ftbe->yesses < ythresh)
+ break;
+ yn= (ftbe->yesses++ == ythresh) ? ftbe->flags : 0 ;
+ weight*= ftbe->weight;
+ }
+ }
+}
+
+
+int ft_boolean_read_next(FT_INFO *ftb, char *record)
+{
+ FTB_EXPR *ftbe;
+ FTB_WORD *ftbw;
+ MI_INFO *info=ftb->info;
+ MI_KEYDEF *keyinfo=info->s->keyinfo+ftb->keynr;
+ my_off_t keyroot=info->s->state.key_root[ftb->keynr];
+ my_off_t curdoc;
+ int r;
+
+ if (ftb->state != INDEX_SEARCH && ftb->state != INDEX_DONE)
+ return -1;
+
+ /* black magic ON */
+ if ((int) _mi_check_index(info, ftb->keynr) < 0)
+ return my_errno;
+ if (_mi_readinfo(info, F_RDLCK, 1))
+ return my_errno;
+ /* black magic OFF */
+
+ if (!ftb->queue.elements)
+ return my_errno=HA_ERR_END_OF_FILE;
+
+ while (ftb->state == INDEX_SEARCH &&
+ (curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) !=
+ HA_POS_ERROR)
+ {
+ while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
+ {
+ _ftb_climb_the_tree(ftb, ftbw, 0);
+
+ /* update queue */
+ r=_mi_search(info, keyinfo, (uchar*) ftbw->word, USE_WHOLE_KEY,
+ SEARCH_BIGGER , keyroot);
+ if (!r)
+ {
+ r=_mi_compare_text(ftb->charset,
+ info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ 0);
+ }
+ if (r) /* not found */
+ {
+ ftbw->docid[0]=HA_POS_ERROR;
+ if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0)
+ {
+ /*
+ This word MUST BE present in every document returned,
+ so we can stop the search right now
+ */
+ ftb->state=INDEX_DONE;
+ }
+ }
+ else
+ {
+ memcpy(ftbw->word, info->lastkey, info->lastkey_length);
+ ftbw->docid[0]=info->lastpos;
+ }
+ queue_replaced(& ftb->queue);
+ }
+
+ ftbe=ftb->root;
+ if (ftbe->docid[0]==curdoc && ftbe->cur_weight>0 &&
+ ftbe->yesses>=(ftbe->ythresh-ftbe->yweaks) && !ftbe->nos)
+ {
+ /* curdoc matched ! */
+ if (is_tree_inited(& ftb->no_dupes) &&
+ tree_insert(& ftb->no_dupes, &curdoc, 0)->count >1)
+ /* but it managed to get past this line once */
+ continue;
+
+ info->lastpos=curdoc;
+ info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+
+ if (!(*info->read_record)(info,curdoc,record))
+ {
+ info->update|= HA_STATE_AKTIV; /* Record is read */
+ if (ftb->with_scan && ft_boolean_find_relevance(ftb,record,0)==0)
+ continue; /* no match */
+ return 0;
+ }
+ return my_errno;
+ }
+ }
+ ftb->state=INDEX_DONE;
+ return my_errno=HA_ERR_END_OF_FILE;
+}
+
+
+float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
+{
+ FT_WORD word;
+ FTB_WORD *ftbw;
+ FTB_EXPR *ftbe;
+ FT_SEG_ITERATOR ftsi, ftsi2;
+ const byte *end;
+ my_off_t docid=ftb->info->lastpos;
+
+ if (docid == HA_POS_ERROR)
+ return -2.0;
+ if (!ftb->queue.elements)
+ return 0;
+
+ if (ftb->keynr==NO_SUCH_KEY)
+ _mi_ft_segiterator_dummy_init(record, length, &ftsi);
+ else
+ _mi_ft_segiterator_init(ftb->info, ftb->keynr, record, &ftsi);
+ memcpy(&ftsi2, &ftsi, sizeof(ftsi));
+
+ while (_mi_ft_segiterator(&ftsi))
+ {
+ if (!ftsi.pos)
+ continue;
+
+ end=ftsi.pos+ftsi.len;
+ while (ft_simple_get_word((byte **) &ftsi.pos,(byte *) end, &word))
+ {
+ int a, b, c;
+ for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
+ {
+ ftbw=(FTB_WORD *)(ftb->list[c]);
+ if (_mi_compare_text(ftb->charset, word.pos, word.len,
+ (uchar*) ftbw->word+1, ftbw->len-1,
+ (my_bool) (ftbw->flags&FTB_FLAG_TRUNC)) >0)
+ b=c;
+ else
+ a=c;
+ }
+ for (; c>=0; c--)
+ {
+ ftbw=(FTB_WORD *)(ftb->list[c]);
+ if (_mi_compare_text(ftb->charset, word.pos,word.len,
+ (uchar*) ftbw->word+1,ftbw->len-1,
+ (my_bool) (ftbw->flags&FTB_FLAG_TRUNC)))
+ break;
+ if (ftbw->docid[1] == docid)
+ continue;
+ ftbw->docid[1]=docid;
+ _ftb_climb_the_tree(ftb, ftbw, &ftsi2);
+ }
+ }
+ }
+
+ ftbe=ftb->root;
+ if (ftbe->docid[1]==docid && ftbe->cur_weight>0 &&
+ ftbe->yesses>=ftbe->ythresh && !ftbe->nos)
+ { /* row matched ! */
+ return ftbe->cur_weight;
+ }
+ else
+ { /* match failed ! */
+ return 0.0;
+ }
+}
+
+
+void ft_boolean_close_search(FT_INFO *ftb)
+{
+ if (is_tree_inited(& ftb->no_dupes))
+ {
+ delete_tree(& ftb->no_dupes);
+ }
+ free_root(& ftb->mem_root, MYF(0));
+ my_free((gptr)ftb,MYF(0));
+}
+
+
+float ft_boolean_get_relevance(FT_INFO *ftb)
+{
+ return ftb->root->cur_weight;
+}
+
+
+void ft_boolean_reinit_search(FT_INFO *ftb)
+{
+ _ftb_init_index_search(ftb);
+}
diff --git a/myisam/ft_dump.c b/myisam/ft_dump.c
new file mode 100644
index 00000000000..d95e719e234
--- /dev/null
+++ b/myisam/ft_dump.c
@@ -0,0 +1,270 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code
+ added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
+
+#include "ftdefs.h"
+#include <my_getopt.h>
+
+static void get_options(int *argc,char **argv[]);
+static void usage();
+static void complain(int val);
+
+static int count=0, stats=0, dump=0, lstats=0;
+static my_bool verbose;
+static char *query=NULL;
+static uint lengths[256];
+
+#define MAX_LEN (HA_FT_MAXLEN+10)
+#define HOW_OFTEN_TO_WRITE 10000
+
+static struct my_option my_long_options[] =
+{
+ {"dump", 'd', "Dump index (incl. data offsets and word weights)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"stats", 's', "Report global stats",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Be verbose",
+ (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"count", 'c', "Calculate per-word stats (counts and global weights)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"length", 'l', "Report length distribution",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"execute", 'e', "Execute given query", (gptr*) &query, (gptr*) &query, 0,
+ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", 'h', "Display help and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Synonym for -h",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+
+int main(int argc,char *argv[])
+{
+ int error=0;
+ uint keylen, keylen2=0, inx, doc_cnt=0;
+ float weight;
+ double gws, min_gws=0, avg_gws=0;
+ MI_INFO *info;
+ char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN];
+ ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0;
+ struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */
+
+ MY_INIT(argv[0]);
+ get_options(&argc, &argv);
+ if (count || dump)
+ verbose=0;
+ if (!count && !dump && !lstats && !query)
+ stats=1;
+
+ if (verbose)
+ setbuf(stdout,NULL);
+
+ if (argc < 2)
+ usage();
+
+ if (!(info=mi_open(argv[0],2,HA_OPEN_ABORT_IF_LOCKED)))
+ goto err;
+
+ inx=atoi(argv[1]);
+ *buf2=0;
+ aio->info=info;
+
+ if ((inx >= info->s->base.keys) ||
+ !(info->s->keyinfo[inx].flag & HA_FULLTEXT))
+ {
+ printf("Key %d in table %s is not a FULLTEXT key\n", inx, info->filename);
+ goto err;
+ }
+
+ if (query)
+ {
+#if 0
+ FT_DOCLIST *result;
+ int i;
+
+ ft_init_stopwords(ft_precompiled_stopwords);
+
+ result=ft_nlq_init_search(info,inx,query,strlen(query),1);
+ if(!result)
+ goto err;
+
+ if (verbose)
+ printf("%d rows matched\n",result->ndocs);
+
+ for(i=0 ; i<result->ndocs ; i++)
+ printf("%9qx %20.7f\n",result->doc[i].dpos,result->doc[i].weight);
+
+ ft_nlq_close_search(result);
+#else
+ printf("-e option is disabled\n");
+#endif
+ }
+ else
+ {
+ info->lastpos= HA_OFFSET_ERROR;
+ info->update|= HA_STATE_PREV_FOUND;
+
+ while (!(error=mi_rnext(info,NULL,inx)))
+ {
+ keylen=*(info->lastkey);
+
+#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
+ mi_float4get(weight,info->lastkey+keylen+1);
+#else
+#error
+#endif
+
+ snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1);
+ casedn_str(buf);
+ total++;
+ lengths[keylen]++;
+
+ if (count || stats)
+ {
+ doc_cnt++;
+ if (strcmp(buf, buf2))
+ {
+ if (*buf2)
+ {
+ uniq++;
+ avg_gws+=gws=GWS_IN_USE;
+ if (count)
+ printf("%9u %20.7f %s\n",doc_cnt,gws,buf2);
+ if (maxlen<keylen2)
+ {
+ maxlen=keylen2;
+ strmov(buf_maxlen, buf2);
+ }
+ if (max_doc_cnt < doc_cnt)
+ {
+ max_doc_cnt=doc_cnt;
+ strmov(buf_min_gws, buf2);
+ min_gws=gws;
+ }
+ }
+ strmov(buf2, buf);
+ keylen2=keylen;
+ doc_cnt=0;
+ }
+ }
+ if (dump)
+ printf("%9qx %20.7f %s\n",info->lastpos,weight,buf);
+
+ if(verbose && (total%HOW_OFTEN_TO_WRITE)==0)
+ printf("%10ld\r",total);
+ }
+
+ if (stats)
+ {
+ count=0;
+ for (inx=0;inx<256;inx++)
+ {
+ count+=lengths[inx];
+ if ((ulong) count >= total/2)
+ break;
+ }
+ printf("Total rows: %qu\nTotal words: %lu\n"
+ "Unique words: %lu\nLongest word: %lu chars (%s)\n"
+ "Median length: %u\n"
+ "Average global weight: %f\n"
+ "Most common word: %lu times, weight: %f (%s)\n",
+ (ulonglong)info->state->records, total, uniq, maxlen, buf_maxlen,
+ inx, avg_gws/uniq, max_doc_cnt, min_gws, buf_min_gws);
+ }
+ if (lstats)
+ {
+ count=0;
+ for (inx=0; inx<256; inx++)
+ {
+ count+=lengths[inx];
+ if (count && lengths[inx])
+ printf("%3u: %10lu %5.2f%% %20lu %4.1f%%\n", inx,
+ (ulong) lengths[inx],100.0*lengths[inx]/total,(ulong) count,
+ 100.0*count/total);
+ }
+ }
+ }
+
+err:
+ if (error && error != HA_ERR_END_OF_FILE)
+ printf("got error %d\n",my_errno);
+ if (info)
+ mi_close(info);
+ return 0;
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch(optid) {
+ case 'd':
+ dump=1;
+ complain(count || query);
+ break;
+ case 's':
+ stats=1;
+ complain(query!=0);
+ break;
+ case 'c':
+ count= 1;
+ complain(dump || query);
+ break;
+ case 'l':
+ lstats=1;
+ complain(query!=0);
+ break;
+ case 'e':
+ complain(dump || count || stats);
+ break;
+ case '?':
+ case 'h':
+ usage();
+ }
+ return 0;
+}
+
+
+static void get_options(int *argc, char **argv[])
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+} /* get options */
+
+
+static void usage()
+{
+ printf("Use: ft_dump <table_name> <index_no>\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+ exit(1);
+}
+
+
+static void complain(int val) /* Kinda assert :-) */
+{
+ if (val)
+ {
+ printf("You cannot use these options together!\n");
+ exit(1);
+ }
+}
diff --git a/myisam/ft_eval.c b/myisam/ft_eval.c
index 9466104100a..34248c69f20 100644
--- a/myisam/ft_eval.c
+++ b/myisam/ft_eval.c
@@ -11,18 +11,32 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code
+ added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
#include "ftdefs.h"
#include "ft_eval.h"
#include <stdarg.h>
-#include <getopt.h>
+#include <my_getopt.h>
static void print_error(int exit_code, const char *fmt,...);
static void get_options(int argc, char *argv[]);
static int create_record(char *pos, FILE *file);
+static void usage();
-int main(int argc,char *argv[])
+static struct my_option my_long_options[] =
+{
+ {"", 's', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'q', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '#', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
{
MI_INFO *file;
int i,j;
@@ -32,7 +46,7 @@ int main(int argc,char *argv[])
bzero((char*)recinfo,sizeof(recinfo));
/* First define 2 columns */
- recinfo[0].type=FIELD_SKIPP_ENDSPACE;
+ recinfo[0].type=FIELD_SKIP_ENDSPACE;
recinfo[0].length=docid_length;
recinfo[1].type=FIELD_BLOB;
recinfo[1].length= 4+mi_portable_sizeof_char_ptr;
@@ -65,7 +79,7 @@ int main(int argc,char *argv[])
my_errno=0;
i=0;
- while(create_record(record,df))
+ while (create_record(record,df))
{
error=mi_write(file,record);
if (error)
@@ -80,102 +94,125 @@ int main(int argc,char *argv[])
if (!(file=mi_open(filename,2,0))) goto err;
if (!silent)
printf("- Reading rows with key\n");
- for(i=1;create_record(record,qf);i++) {
- FT_DOCLIST *result; double w; int t,err;
+ for (i=1;create_record(record,qf);i++)
+ {
+ FT_DOCLIST *result;
+ double w;
+ int t, err;
- result=ft_init_search(file,0,blob_record,(uint) strlen(blob_record),1);
- if(!result) {
+ result=ft_nlq_init_search(file,0,blob_record,(uint) strlen(blob_record),1);
+ if (!result)
+ {
printf("Query %d failed with errno %3d\n",i,my_errno);
goto err;
}
if (!silent)
printf("Query %d. Found: %d.\n",i,result->ndocs);
- for(j=0;(err=ft_read_next(result, read_record))==0;j++) {
+ for (j=0;(err=ft_nlq_read_next(result, read_record))==0;j++)
+ {
t=uint2korr(read_record);
- w=ft_get_relevance(result);
+ w=ft_nlq_get_relevance(result);
printf("%d %.*s %f\n",i,t,read_record+2,w);
}
- if(err != HA_ERR_END_OF_FILE) {
+ if (err != HA_ERR_END_OF_FILE)
+ {
printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
goto err;
}
- ft_close_search(result);
+ ft_nlq_close_search(result);
}
if (mi_close(file)) goto err;
my_end(MY_CHECK_ERROR);
return (0);
-err:
+
+ err:
printf("got error: %3d when using myisam-database\n",my_errno);
- return 1; /* skipp warning */
+ return 1; /* skip warning */
}
-static void get_options(int argc,char *argv[])
-{
- int c;
- char *options=(char*) "Vh#:qSs:";
- while ((c=getopt(argc,argv,options)) != -1)
- {
- switch(c) {
- case 's':
- if(stopwordlist && stopwordlist!=ft_precompiled_stopwords) break;
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case 's':
+ if (stopwordlist && stopwordlist != ft_precompiled_stopwords)
+ break;
+ {
+ FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT;
+
+ if (!(stopwordlist=(const char**) malloc(n*sizeof(char *))))
+ print_error(1,"malloc(%d)",n*sizeof(char *));
+ if (!(f=fopen(argument,"r")))
+ print_error(1,"fopen(%s)",argument);
+ while (!feof(f))
{
- FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT;
-
- if(!(stopwordlist=(const char**) malloc(n*sizeof(char *))))
- print_error(1,"malloc(%d)",n*sizeof(char *));
- if(!(f=fopen(optarg,"r")))
- print_error(1,"fopen(%s)",optarg);
- while(!feof(f)) {
- if(!(fgets(s,HA_FT_MAXLEN,f)))
- print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,optarg);
- if(!(stopwordlist[i++]=strdup(s)))
- print_error(1,"strdup(%s)",s);
- if(i>=n) {
- n+=SWL_PLUS;
- if(!(stopwordlist=(const char**) realloc((char*) stopwordlist,n*sizeof(char *))))
- print_error(1,"realloc(%d)",n*sizeof(char *));
- }
+ if (!(fgets(s,HA_FT_MAXLEN,f)))
+ print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,argument);
+ if (!(stopwordlist[i++]=strdup(s)))
+ print_error(1,"strdup(%s)",s);
+ if (i >= n)
+ {
+ n+=SWL_PLUS;
+ if (!(stopwordlist=(const char**) realloc((char*) stopwordlist,
+ n*sizeof(char *))))
+ print_error(1,"realloc(%d)",n*sizeof(char *));
}
- fclose(f);
- stopwordlist[i]=NULL;
- break;
}
- case 'q': silent=1; break;
- case 'S': if(stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break;
- case '#':
- DEBUGGER_ON;
- DBUG_PUSH (optarg);
+ fclose(f);
+ stopwordlist[i]=NULL;
break;
- case 'V':
- case '?':
- case 'h':
- default:
- printf("%s -[%s] <d_file> <q_file>\n", argv[0], options);
- exit(0);
}
+ case 'q': silent=1; break;
+ case 'S': if (stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break;
+ case '#':
+ DEBUGGER_ON;
+ DBUG_PUSH (argument);
+ break;
+ case 'V':
+ case '?':
+ case 'h':
+ usage();
+ exit(1);
}
- if(!(d_file=argv[optind])) print_error(1,"No d_file");
- if(!(df=fopen(d_file,"r")))
+ return 0;
+}
+
+
+static void get_options(int argc, char *argv[])
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ if (!(d_file=argv[optind])) print_error(1,"No d_file");
+ if (!(df=fopen(d_file,"r")))
print_error(1,"fopen(%s)",d_file);
- if(!(q_file=argv[optind+1])) print_error(1,"No q_file");
- if(!(qf=fopen(q_file,"r")))
+ if (!(q_file=argv[optind+1])) print_error(1,"No q_file");
+ if (!(qf=fopen(q_file,"r")))
print_error(1,"fopen(%s)",q_file);
return;
} /* get options */
+
static int create_record(char *pos, FILE *file)
-{ uint tmp; char *ptr;
+{
+ uint tmp; char *ptr;
bzero((char *)pos,MAX_REC_LENGTH);
/* column 1 - VARCHAR */
- if(!(fgets(pos+2,MAX_REC_LENGTH-32,file)))
+ if (!(fgets(pos+2,MAX_REC_LENGTH-32,file)))
{
- if(feof(file)) return 0; else print_error(1,"fgets(docid) - 1");
+ if (feof(file))
+ return 0;
+ else
+ print_error(1,"fgets(docid) - 1");
}
tmp=(uint) strlen(pos+2)-1;
int2store(pos,tmp);
@@ -183,7 +220,7 @@ static int create_record(char *pos, FILE *file)
/* column 2 - BLOB */
- if(!(fgets(blob_record,MAX_BLOB_LENGTH,file)))
+ if (!(fgets(blob_record,MAX_BLOB_LENGTH,file)))
print_error(1,"fgets(docid) - 2");
tmp=(uint) strlen(blob_record);
int4store(pos,tmp);
@@ -206,3 +243,11 @@ static void print_error(int exit_code, const char *fmt,...)
va_end(args);
exit(exit_code);
}
+
+
+static void usage()
+{
+ printf("%s [options]\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
diff --git a/myisam/ft_eval.h b/myisam/ft_eval.h
index d87b6be9c7c..68be3a39f33 100644
--- a/myisam/ft_eval.h
+++ b/myisam/ft_eval.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & Sergei A. Golubchik
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -40,4 +40,3 @@ MI_KEYSEG keyseg[10];
#define MAX_LINE_LENGTH 128
char line[MAX_LINE_LENGTH];
-
diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c
new file mode 100644
index 00000000000..5670edde7c0
--- /dev/null
+++ b/myisam/ft_nlq_search.c
@@ -0,0 +1,308 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+
+#define FT_CORE
+#include "ftdefs.h"
+
+/* search with natural language queries */
+
+typedef struct ft_doc_rec
+{
+ my_off_t dpos;
+ double weight;
+} FT_DOC;
+
+struct st_ft_info
+{
+ struct _ft_vft *please;
+ MI_INFO *info;
+ int ndocs;
+ int curdoc;
+ FT_DOC doc[1];
+};
+
+typedef struct st_all_in_one
+{
+ MI_INFO *info;
+ uint keynr;
+ CHARSET_INFO *charset;
+ uchar *keybuff;
+ MI_KEYDEF *keyinfo;
+ my_off_t key_root;
+ TREE dtree;
+} ALL_IN_ONE;
+
+typedef struct st_ft_superdoc
+{
+ FT_DOC doc;
+ FT_WORD *word_ptr;
+ double tmp_weight;
+} FT_SUPERDOC;
+
+static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)),
+ FT_SUPERDOC *p1, FT_SUPERDOC *p2)
+{
+ if (p1->doc.dpos < p2->doc.dpos)
+ return -1;
+ if (p1->doc.dpos == p2->doc.dpos)
+ return 0;
+ return 1;
+}
+
+static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
+{
+ uint keylen, r, doc_cnt;
+#ifdef EVAL_RUN
+ uint cnt;
+ double sum, sum2, suml;
+#endif /* EVAL_RUN */
+ FT_SUPERDOC sdoc, *sptr;
+ TREE_ELEMENT *selem;
+#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
+ float tmp_weight;
+#else
+#error
+#endif
+
+ word->weight=LWS_FOR_QUERY;
+
+ keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,word,0);
+#ifdef EVAL_RUN
+ keylen-=1+HA_FT_WLEN;
+#else /* EVAL_RUN */
+ keylen-=HA_FT_WLEN;
+#endif /* EVAL_RUN */
+
+#ifdef EVAL_RUN
+ sum=sum2=suml=
+#endif /* EVAL_RUN */
+ doc_cnt=0;
+
+ r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
+ SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
+
+ while (!r)
+ {
+ if (_mi_compare_text(aio->charset,
+ aio->info->lastkey,keylen,
+ aio->keybuff,keylen,0)) break;
+
+#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
+#ifdef EVAL_RUN
+ mi_float4get(tmp_weight,aio->info->lastkey+keylen+1);
+#else /* EVAL_RUN */
+ mi_float4get(tmp_weight,aio->info->lastkey+keylen);
+#endif /* EVAL_RUN */
+#else
+#error
+#endif
+ if(tmp_weight==0) return doc_cnt; /* stopword, doc_cnt should be 0 */
+
+#ifdef EVAL_RUN
+ cnt=*(byte *)(aio->info->lastkey+keylen);
+#endif /* EVAL_RUN */
+
+ sdoc.doc.dpos=aio->info->lastpos;
+
+ /* saving document matched into dtree */
+ if (!(selem=tree_insert(&aio->dtree, &sdoc, 0)))
+ return 1;
+
+ sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
+
+ if (selem->count==1) /* document's first match */
+ sptr->doc.weight=0;
+ else
+ sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight;
+
+ sptr->word_ptr=word;
+ sptr->tmp_weight=tmp_weight;
+
+ doc_cnt++;
+#ifdef EVAL_RUN
+ sum +=cnt;
+ sum2+=cnt*cnt;
+ suml+=cnt*log(cnt);
+#endif /* EVAL_RUN */
+
+ if (_mi_test_if_changed(aio->info) == 0)
+ r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
+ aio->info->lastkey_length, SEARCH_BIGGER,
+ aio->key_root);
+ else
+ r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
+ aio->info->lastkey_length, SEARCH_BIGGER,
+ aio->key_root);
+ }
+ if (doc_cnt)
+ {
+ word->weight*=GWS_IN_USE;
+ if (word->weight < 0)
+ word->weight=0;
+ }
+ return 0;
+}
+
+
+static int walk_and_copy(FT_SUPERDOC *from,
+ uint32 count __attribute__((unused)), FT_DOC **to)
+{
+ from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
+ (*to)->dpos=from->doc.dpos;
+ (*to)->weight=from->doc.weight;
+ (*to)++;
+ return 0;
+}
+
+
+static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b)
+{
+ return sgn(b->weight - a->weight);
+}
+
+
+FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
+ uint query_len, my_bool presort)
+{
+ TREE allocated_wtree, *wtree=&allocated_wtree;
+ ALL_IN_ONE aio;
+ FT_DOC *dptr;
+ FT_INFO *dlist=NULL;
+ my_off_t saved_lastpos=info->lastpos;
+
+/* black magic ON */
+ if ((int) (keynr = _mi_check_index(info,keynr)) < 0)
+ return NULL;
+ if (_mi_readinfo(info,F_RDLCK,1))
+ return NULL;
+/* black magic OFF */
+
+ aio.info=info;
+ aio.keynr=keynr;
+ aio.keyinfo=info->s->keyinfo+keynr;
+ aio.charset=aio.keyinfo->seg->charset;
+ aio.keybuff=info->lastkey+info->s->base.max_key_length;
+ aio.key_root=info->s->state.key_root[keynr];
+
+ bzero(&allocated_wtree,sizeof(allocated_wtree));
+
+ init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,0,
+ NULL, NULL);
+
+ ft_parse_init(&allocated_wtree, aio.charset);
+ if (ft_parse(&allocated_wtree,query,query_len))
+ goto err;
+
+ if (tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio,
+ left_root_right))
+ goto err2;
+
+ dlist=(FT_INFO *)my_malloc(sizeof(FT_INFO)+
+ sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),
+ MYF(0));
+ if(!dlist)
+ goto err2;
+
+ dlist->please= (struct _ft_vft *) & _ft_vft_nlq;
+ dlist->ndocs=aio.dtree.elements_in_tree;
+ dlist->curdoc=-1;
+ dlist->info=aio.info;
+ dptr=dlist->doc;
+
+ tree_walk(&aio.dtree, (tree_walk_action) &walk_and_copy,
+ &dptr, left_root_right);
+
+ if (presort)
+ qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp);
+
+err2:
+ delete_tree(wtree);
+ delete_tree(&aio.dtree);
+
+err:
+ info->lastpos=saved_lastpos;
+ return dlist;
+}
+
+
+int ft_nlq_read_next(FT_INFO *handler, char *record)
+{
+ MI_INFO *info= (MI_INFO *) handler->info;
+
+ if (++handler->curdoc >= handler->ndocs)
+ {
+ --handler->curdoc;
+ return HA_ERR_END_OF_FILE;
+ }
+
+ info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+
+ info->lastpos=handler->doc[handler->curdoc].dpos;
+ if (!(*info->read_record)(info,info->lastpos,record))
+ {
+ info->update|= HA_STATE_AKTIV; /* Record is read */
+ return 0;
+ }
+ return my_errno;
+}
+
+
+float ft_nlq_find_relevance(FT_INFO *handler,
+ byte *record __attribute__((unused)),
+ uint length __attribute__((unused)))
+{
+ int a,b,c;
+ FT_DOC *docs=handler->doc;
+ my_off_t docid=handler->info->lastpos;
+
+ if (docid == HA_POS_ERROR)
+ return -5.0;
+
+ /* Assuming docs[] is sorted by dpos... */
+
+ for (a=0, b=handler->ndocs, c=(a+b)/2; b-a>1; c=(a+b)/2)
+ {
+ if (docs[c].dpos > docid)
+ b=c;
+ else
+ a=c;
+ }
+ if (docs[a].dpos == docid)
+ return (float) docs[a].weight;
+ else
+ return 0.0;
+}
+
+
+void ft_nlq_close_search(FT_INFO *handler)
+{
+ my_free((gptr)handler,MYF(0));
+}
+
+
+float ft_nlq_get_relevance(FT_INFO *handler)
+{
+ return (float) handler->doc[handler->curdoc].weight;
+}
+
+
+void ft_nlq_reinit_search(FT_INFO *handler)
+{
+ handler->curdoc=-1;
+}
+
diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c
index 7ea2e240c36..283216762e1 100644
--- a/myisam/ft_parser.c
+++ b/myisam/ft_parser.c
@@ -33,16 +33,12 @@ typedef struct st_ft_docstat {
double max, nsum, nsum2;
#endif /* EVAL_RUN */
- MI_INFO *info;
- uint keynr;
- byte *keybuf;
} FT_DOCSTAT;
-static int FT_WORD_cmp(FT_WORD *w1, FT_WORD *w2)
+static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2)
{
- return _mi_compare_text(default_charset_info,
- (uchar*) w1->pos,w1->len,
- (uchar*) w2->pos, w2->len,0);
+ return _mi_compare_text(cs, (uchar*) w1->pos, w1->len,
+ (uchar*) w2->pos, w2->len, 0);
}
static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat)
@@ -63,17 +59,15 @@ static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat)
/* transforms tree of words into the array, applying normalization */
-FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
+FT_WORD * ft_linearize(TREE *wtree)
{
FT_WORD *wlist,*p;
FT_DOCSTAT docstat;
+ DBUG_ENTER("ft_linearize");
if ((wlist=(FT_WORD *) my_malloc(sizeof(FT_WORD)*
(1+wtree->elements_in_tree),MYF(0))))
{
- docstat.info=info;
- docstat.keynr=keynr;
- docstat.keybuf=keybuf;
docstat.list=wlist;
docstat.uniq=wtree->elements_in_tree;
#ifdef EVAL_RUN
@@ -83,13 +77,12 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
tree_walk(wtree,(tree_walk_action)&walk_and_copy,&docstat,left_root_right);
}
delete_tree(wtree);
- my_free((char*) wtree,MYF(0));
if (!wlist)
- return NULL;
+ DBUG_RETURN(NULL);
docstat.list->pos=NULL;
- for(p=wlist;p->pos;p++)
+ for (p=wlist;p->pos;p++)
{
p->weight=PRENORM_IN_USE;
#ifdef EVAL_RUN
@@ -104,48 +97,142 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
#endif
#endif /* EVAL_RUN */
- for(p=wlist;p->pos;p++)
+ for (p=wlist;p->pos;p++)
{
p->weight/=NORM_IN_USE;
}
- return wlist;
+ DBUG_RETURN(wlist);
}
+#define true_word_char(X) (isalnum(X) || (X)=='_')
#ifdef HYPHEN_IS_DELIM
-#define word_char(X) (isalnum(X) || (X)=='_' || (X)=='\'')
+#define misc_word_char(X) ((X)=='\'')
#else
-#define word_char(X) (isalnum(X) || (X)=='_' || (X)=='\'' || (X)=='-')
+#define misc_word_char(X) ((X)=='\'' || (X)=='-')
#endif
+#define word_char(X) (true_word_char(X) || misc_word_char(X))
-/* this is rather dumb first version of the parser */
-TREE * ft_parse(TREE *wtree, byte *doc, int doclen)
+
+/* returns:
+ * 0 - eof
+ * 1 - word found
+ * 2 - left bracket
+ * 3 - right bracket
+ */
+byte ft_get_word(byte **start, byte *end, FT_WORD *word, FTB_PARAM *param)
{
- byte *end=doc+doclen;
- FT_WORD w;
+ byte *doc=*start;
+ int mwc;
+
+ param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0);
+ param->plusminus=param->pmsign=0;
- if (!wtree)
+ while (doc<end)
{
- if (!(wtree=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) return NULL;
- init_tree(wtree,0,sizeof(FT_WORD),(qsort_cmp)&FT_WORD_cmp,0,NULL);
+ for (;doc<end;doc++)
+ {
+ if (true_word_char(*doc)) break;
+ if (*doc == FTB_RQUOT && param->quot) {
+ param->quot=doc;
+ *start=doc+1;
+ return 3; /* FTB_RBR */
+ }
+ if ((*doc == FTB_LBR || *doc == FTB_RBR || *doc == FTB_LQUOT)
+ && !param->quot)
+ {
+ /* param->prev=' '; */
+ *start=doc+1;
+ if (*doc == FTB_LQUOT) param->quot=*start;
+ return (*doc == FTB_RBR)+2;
+ }
+ if (param->prev == ' ' && !param->quot)
+ {
+ if (*doc == FTB_YES ) { param->yesno=+1; continue; } else
+ if (*doc == FTB_EGAL) { param->yesno= 0; continue; } else
+ if (*doc == FTB_NO ) { param->yesno=-1; continue; } else
+ if (*doc == FTB_INC ) { param->plusminus++; continue; } else
+ if (*doc == FTB_DEC ) { param->plusminus--; continue; } else
+ if (*doc == FTB_NEG ) { param->pmsign=!param->pmsign; continue; }
+ }
+ param->prev=*doc;
+ param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0);
+ param->plusminus=param->pmsign=0;
+ }
+
+ mwc=0;
+ for (word->pos=doc; doc<end; doc++)
+ if (true_word_char(*doc))
+ mwc=0;
+ else if (!misc_word_char(*doc) || mwc++)
+ break;
+
+ param->prev='A'; /* be sure *prev is true_word_char */
+ word->len= (uint)(doc-word->pos) - mwc;
+ if ((param->trunc=(doc<end && *doc == FTB_TRUNC)))
+ doc++;
+
+ if (((word->len >= ft_min_word_len && !is_stopword(word->pos, word->len))
+ || param->trunc) && word->len < ft_max_word_len)
+ {
+ *start=doc;
+ return 1;
+ }
}
+ return 0;
+}
+
+byte ft_simple_get_word(byte **start, byte *end, FT_WORD *word)
+{
+ byte *doc=*start;
+ int mwc;
- w.weight=0;
while (doc<end)
{
for (;doc<end;doc++)
- if (word_char(*doc)) break;
- for (w.pos=doc; doc<end; doc++)
- if (!word_char(*doc)) break;
- if ((w.len= (uint) (doc-w.pos)) < MIN_WORD_LEN) continue;
- if (w.len >= HA_FT_MAXLEN) continue;
- if (is_stopword(w.pos, w.len)) continue;
- if (!tree_insert(wtree, &w, 0))
{
- delete_tree(wtree);
- my_free((char*) wtree,MYF(0));
- return NULL;
+ if (true_word_char(*doc)) break;
+ }
+
+ mwc=0;
+ for(word->pos=doc; doc<end; doc++)
+ if (true_word_char(*doc))
+ mwc=0;
+ else if (!misc_word_char(*doc) || mwc++)
+ break;
+
+ word->len= (uint)(doc-word->pos) - mwc;
+
+ if (word->len >= ft_min_word_len && word->len < ft_max_word_len &&
+ !is_stopword(word->pos, word->len))
+ {
+ *start=doc;
+ return 1;
}
}
- return wtree;
+ return 0;
}
+
+void ft_parse_init(TREE *wtree, CHARSET_INFO *cs)
+{
+ if (!is_tree_inited(wtree))
+ init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, cs);
+}
+
+int ft_parse(TREE *wtree, byte *doc, int doclen)
+{
+ byte *end=doc+doclen;
+ FT_WORD w;
+
+ while (ft_simple_get_word(&doc,end,&w))
+ {
+ if (!tree_insert(wtree, &w, 0))
+ goto err;
+ }
+ return 0;
+
+err:
+ delete_tree(wtree);
+ return 1;
+}
+
diff --git a/myisam/ft_search.c b/myisam/ft_search.c
deleted file mode 100644
index 9a728a4c211..00000000000
--- a/myisam/ft_search.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
-
-#include "ftdefs.h"
-
-/* queries isam and returns list of documents matched */
-
-typedef struct st_all_in_one {
- MI_INFO *info;
- uint keynr;
- uchar *keybuff;
- MI_KEYDEF *keyinfo;
- my_off_t key_root;
- TREE dtree;
-} ALL_IN_ONE;
-
-typedef struct st_ft_superdoc {
- FT_DOC doc;
- FT_WORD *word_ptr;
- double tmp_weight;
-} FT_SUPERDOC;
-
-static int FT_SUPERDOC_cmp(FT_SUPERDOC *p1, FT_SUPERDOC *p2)
-{
- if (p1->doc.dpos < p2->doc.dpos)
- return -1;
- if (p1->doc.dpos == p2->doc.dpos)
- return 0;
- return 1;
-}
-
-static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
-{
- uint keylen, r, doc_cnt;
-#ifdef EVAL_RUN
- uint cnt;
- double sum, sum2, suml;
-#endif /* EVAL_RUN */
- FT_SUPERDOC sdoc, *sptr;
- TREE_ELEMENT *selem;
-#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
- float tmp_weight;
-#else
-#error
-#endif
-
- word->weight=LWS_FOR_QUERY;
-
- keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,word,0);
-#ifdef EVAL_RUN
- keylen-=1+HA_FT_WLEN;
-#else /* EVAL_RUN */
- keylen-=HA_FT_WLEN;
-#endif /* EVAL_RUN */
-
-#ifdef EVAL_RUN
- sum=sum2=suml=
-#endif /* EVAL_RUN */
- doc_cnt=0;
-
- r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
- SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
-
- while(!r)
- {
- if (_mi_compare_text(default_charset_info,
- aio->info->lastkey,keylen,
- aio->keybuff,keylen,0)) break;
-
-#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
-#ifdef EVAL_RUN
- mi_float4get(tmp_weight,aio->info->lastkey+keylen+1);
-#else /* EVAL_RUN */
- mi_float4get(tmp_weight,aio->info->lastkey+keylen);
-#endif /* EVAL_RUN */
-#else
-#error
-#endif
- if(tmp_weight==0) return doc_cnt; /* stopword, doc_cnt should be 0 */
-
-#ifdef EVAL_RUN
- cnt=*(byte *)(aio->info->lastkey+keylen);
-#endif /* EVAL_RUN */
-
- sdoc.doc.dpos=aio->info->lastpos;
-
- /* saving document matched into dtree */
- if(!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1;
-
- sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
-
- if(selem->count==1) /* document's first match */
- sptr->doc.weight=0;
- else
- sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight;
-
- sptr->word_ptr=word;
- sptr->tmp_weight=tmp_weight;
-
- doc_cnt++;
-#ifdef EVAL_RUN
- sum +=cnt;
- sum2+=cnt*cnt;
- suml+=cnt*log(cnt);
-#endif /* EVAL_RUN */
-
- if (_mi_test_if_changed(aio->info) == 0)
- r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
- aio->info->lastkey_length, SEARCH_BIGGER,
- aio->key_root);
- else
- r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
- aio->info->lastkey_length, SEARCH_BIGGER,
- aio->key_root);
- }
- if(doc_cnt) {
- word->weight*=GWS_IN_USE;
- if(word->weight < 0) word->weight=0;
- }
-
- return 0;
-}
-
-static int walk_and_copy(FT_SUPERDOC *from,
- uint32 count __attribute__((unused)), FT_DOC **to)
-{
- from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
- (*to)->dpos=from->doc.dpos;
- (*to)->weight=from->doc.weight;
- (*to)++;
- return 0;
-}
-
-static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b)
-{
- return sgn(b->weight - a->weight);
-}
-
-FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
- uint key_len, my_bool presort)
-{
- TREE *wtree;
- ALL_IN_ONE aio;
- FT_DOCLIST *dlist;
- FT_DOC *dptr;
- my_off_t saved_lastpos=((MI_INFO *)info)->lastpos;
-
-/* black magic ON */
- if ((int) (keynr = _mi_check_index((MI_INFO *)info,keynr)) < 0)
- return NULL;
- if (_mi_readinfo((MI_INFO *)info,F_RDLCK,1))
- return NULL;
-/* black magic OFF */
-
- dlist=NULL;
- aio.info=(MI_INFO *)info;
- aio.keynr=keynr;
- aio.keybuff=aio.info->lastkey+aio.info->s->base.max_key_length;
- aio.keyinfo=aio.info->s->keyinfo+keynr;
- aio.key_root=aio.info->s->state.key_root[keynr];
-
- if (!(wtree=ft_parse(NULL,key,key_len))) return NULL;
-
- init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
- NULL);
-
- if (tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio,
- left_root_right))
- goto err;
-
- dlist=(FT_DOCLIST *) my_malloc(sizeof(FT_DOCLIST)+sizeof(FT_DOC)*
- (aio.dtree.elements_in_tree-1),MYF(0));
- if (!dlist)
- goto err;
-
- dlist->ndocs=aio.dtree.elements_in_tree;
- dlist->curdoc=-1;
- dlist->info=aio.info;
- dptr=dlist->doc;
-
- tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, &dptr,
- left_root_right);
-
- if (presort)
- {
- qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp);
- }
-
-err:
- delete_tree(&aio.dtree);
- delete_tree(wtree);
- my_free((char*) wtree,MYF(0));
- ((MI_INFO *)info)->lastpos=saved_lastpos;
- return dlist;
-}
-
-int ft_read_next(FT_DOCLIST *handler, char *record)
-{
- MI_INFO *info= (MI_INFO *) handler->info;
-
- if (++handler->curdoc >= handler->ndocs)
- {
- --handler->curdoc;
- return HA_ERR_END_OF_FILE;
- }
-
- info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
-
- info->lastpos=handler->doc[handler->curdoc].dpos;
- if (!(*info->read_record)(info,info->lastpos,record))
- {
- info->update|= HA_STATE_AKTIV; /* Record is read */
- return 0;
- }
- return my_errno;
-}
diff --git a/myisam/ft_static.c b/myisam/ft_static.c
index 00d9d4ed19a..3efb3a3ec74 100644
--- a/myisam/ft_static.c
+++ b/myisam/ft_static.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,6 +18,11 @@
#include "ftdefs.h"
+ulong ft_min_word_len=4;
+ulong ft_max_word_len=HA_FT_MAXLEN;
+ulong ft_max_word_len_for_sort=20;
+const char *ft_boolean_syntax="+ -><()~*:\"\"&|";
+
const MI_KEYSEG ft_keysegs[FT_SEGS]={
{
HA_KEYTYPE_VARTEXT, /* type */
@@ -39,10 +44,29 @@ const MI_KEYSEG ft_keysegs[FT_SEGS]={
},
#endif /* EVAL_RUN */
{
- HA_FT_WTYPE, 7, 0, 0, 0, 0, HA_FT_WLEN, 0, 0, NULL
+ HA_FT_WTYPE, 7, 0, 0, 0, HA_NO_SORT, HA_FT_WLEN, 0, 0, NULL
}
};
+const struct _ft_vft _ft_vft_nlq = {
+ ft_nlq_read_next, ft_nlq_find_relevance, ft_nlq_close_search,
+ ft_nlq_get_relevance, ft_nlq_reinit_search
+};
+const struct _ft_vft _ft_vft_boolean = {
+ ft_boolean_read_next, ft_boolean_find_relevance, ft_boolean_close_search,
+ ft_boolean_get_relevance, ft_boolean_reinit_search
+};
+
+FT_INFO *(*_ft_init_vft[2])(MI_INFO *, uint, byte *, uint, my_bool) =
+{ ft_init_nlq_search, ft_init_boolean_search };
+
+FT_INFO *ft_init_search(uint mode, void *info, uint keynr,
+ byte *query, uint query_len, my_bool presort)
+{
+ return (*_ft_init_vft[mode])((MI_INFO *)info, keynr,
+ query, query_len, presort);
+}
+
const char *ft_precompiled_stopwords[] = {
#ifdef COMPILE_STOPWORDS_IN
diff --git a/myisam/ft_stem.c b/myisam/ft_stem.c
index bdfc73b774b..846d5d2247f 100644
--- a/myisam/ft_stem.c
+++ b/myisam/ft_stem.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -17,4 +17,3 @@
/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
/* mulitingual stem */
-
diff --git a/myisam/ft_stopwords.c b/myisam/ft_stopwords.c
index d796b87ed71..9c2047c3b56 100644
--- a/myisam/ft_stopwords.c
+++ b/myisam/ft_stopwords.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,7 +25,8 @@ typedef struct st_ft_stopwords {
static TREE *stopwords3=NULL;
-static int FT_STOPWORD_cmp(FT_STOPWORD *w1, FT_STOPWORD *w2)
+static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)),
+ FT_STOPWORD *w1, FT_STOPWORD *w2)
{
return _mi_compare_text(default_charset_info,
(uchar *)w1->pos,w1->len,
@@ -40,15 +41,15 @@ int ft_init_stopwords(const char **sws)
if(!stopwords3)
{
if(!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) return -1;
- init_tree(stopwords3,0,sizeof(FT_STOPWORD),(qsort_cmp)&FT_STOPWORD_cmp,0,
- NULL);
+ init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,0,
+ NULL, NULL);
}
if(!sws) return 0;
for(;*sws;sws++)
{
- if( (sw.len= (uint) strlen(sw.pos=*sws)) < MIN_WORD_LEN) continue;
+ if( (sw.len= (uint) strlen(sw.pos=*sws)) < ft_min_word_len) continue;
if(!tree_insert(stopwords3, &sw, 0))
{
delete_tree(stopwords3); /* purecov: inspected */
diff --git a/myisam/ft_test1.c b/myisam/ft_test1.c
index 5093b591fb2..cb0b6054f0a 100644
--- a/myisam/ft_test1.c
+++ b/myisam/ft_test1.c
@@ -14,13 +14,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code
+ added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
#include "ftdefs.h"
#include "ft_test1.h"
-#include <getopt.h>
+#include <my_getopt.h>
-static int key_field=FIELD_VARCHAR,extra_field=FIELD_SKIPP_ENDSPACE;
+static int key_field=FIELD_VARCHAR,extra_field=FIELD_SKIP_ENDSPACE;
static uint key_length=200,extra_length=50;
static int key_type=HA_KEYTYPE_TEXT;
static int verbose=0,silent=0,skip_update=0,
@@ -33,8 +34,26 @@ static char record[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH];
static int run_test(const char *filename);
static void get_options(int argc, char *argv[]);
static void create_record(char *, int);
+static void usage();
-int main(int argc,char *argv[])
+static struct my_option my_long_options[] =
+{
+ {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 's', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'N', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'K', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'F', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'U', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '#', "", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
{
MY_INIT(argv[0]);
@@ -137,7 +156,7 @@ static int run_test(const char *filename)
printf("- Reading rows with key\n");
for (i=0 ; i < NQUERIES ; i++)
{ FT_DOCLIST *result;
- result=ft_init_search(file,0,(char*) query[i],strlen(query[i]),1);
+ result=ft_nlq_init_search(file,0,(char*) query[i],strlen(query[i]),1);
if(!result) {
printf("Query %d: `%s' failed with errno %3d\n",i,query[i],my_errno);
continue;
@@ -145,7 +164,7 @@ static int run_test(const char *filename)
printf("Query %d: `%s'. Found: %d. Top five documents:\n",
i,query[i],result->ndocs);
for(j=0;j<5;j++) { double w; int err;
- err=ft_read_next(result, read_record);
+ err=ft_nlq_read_next(result, read_record);
if(err==HA_ERR_END_OF_FILE) {
printf("No more matches!\n");
break;
@@ -153,7 +172,7 @@ static int run_test(const char *filename)
printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
break;
}
- w=ft_get_relevance(result);
+ w=ft_nlq_get_relevance(result);
if(key_field == FIELD_VARCHAR) {
uint l;
char *p;
@@ -164,7 +183,7 @@ static int run_test(const char *filename)
printf("%10.7f: %.*s\n",w,recinfo[1].length,
recinfo[0].length+read_record);
}
- ft_close_search(result);
+ ft_nlq_close_search(result);
}
if (mi_close(file)) goto err;
@@ -173,7 +192,7 @@ static int run_test(const char *filename)
return (0);
err:
printf("got error: %3d when using myisam-database\n",my_errno);
- return 1; /* skipp warning */
+ return 1; /* skip warning */
}
static char blob_key[MAX_REC_LENGTH];
@@ -186,7 +205,7 @@ void create_record(char *pos, int n)
{
uint tmp;
char *ptr;
- strncpy(blob_key,data[n].f0,keyinfo[0].seg[0].length);
+ strnmov(blob_key,data[n].f0,keyinfo[0].seg[0].length);
tmp=strlen(blob_key);
int4store(pos,tmp);
ptr=blob_key;
@@ -196,21 +215,21 @@ void create_record(char *pos, int n)
else if (recinfo[0].type == FIELD_VARCHAR)
{
uint tmp;
- strncpy(pos+2,data[n].f0,keyinfo[0].seg[0].length);
+ strnmov(pos+2,data[n].f0,keyinfo[0].seg[0].length);
tmp=strlen(pos+2);
int2store(pos,tmp);
pos+=recinfo[0].length;
}
else
{
- strncpy(pos,data[n].f0,keyinfo[0].seg[0].length);
+ strnmov(pos,data[n].f0,keyinfo[0].seg[0].length);
pos+=recinfo[0].length;
}
if (recinfo[1].type == FIELD_BLOB)
{
uint tmp;
char *ptr;
- strncpy(blob_key,data[n].f2,keyinfo[0].seg[0].length);
+ strnmov(blob_key,data[n].f2,keyinfo[0].seg[0].length);
tmp=strlen(blob_key);
int4store(pos,tmp);
ptr=blob_key;
@@ -220,46 +239,59 @@ void create_record(char *pos, int n)
else if (recinfo[1].type == FIELD_VARCHAR)
{
uint tmp;
- strncpy(pos+2,data[n].f2,keyinfo[0].seg[0].length);
+ strnmov(pos+2,data[n].f2,keyinfo[0].seg[0].length);
tmp=strlen(pos+2);
int2store(pos,tmp);
pos+=recinfo[1].length;
}
else
{
- strncpy(pos,data[n].f2,keyinfo[0].seg[0].length);
+ strnmov(pos,data[n].f2,keyinfo[0].seg[0].length);
pos+=recinfo[1].length;
}
}
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'v': verbose=1; break;
+ case 's': silent=1; break;
+ case 'F': no_fulltext=1; no_search=1;
+ case 'U': skip_update=1; break;
+ case 'K': no_keys=no_search=1; break;
+ case 'N': no_search=1; break;
+ case 'S': no_stopwords=1; break;
+ case '#':
+ DEBUGGER_ON;
+ DBUG_PUSH (argument);
+ break;
+ case 'V':
+ case '?':
+ case 'h':
+ usage();
+ exit(1);
+ }
+ return 0;
+}
+
/* Read options */
static void get_options(int argc,char *argv[])
{
- int c;
- const char *options="hVvsNSKFU#:";
+ int ho_error;
- while ((c=getopt(argc,argv,options)) != -1)
- {
- switch(c) {
- case 'v': verbose=1; break;
- case 's': silent=1; break;
- case 'F': no_fulltext=1; no_search=1;
- case 'U': skip_update=1; break;
- case 'K': no_keys=no_search=1; break;
- case 'N': no_search=1; break;
- case 'S': no_stopwords=1; break;
- case '#':
- DEBUGGER_ON;
- DBUG_PUSH (optarg);
- break;
- case 'V':
- case '?':
- case 'h':
- default:
- printf("%s -[%s]\n", argv[0], options);
- exit(0);
- }
- }
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
return;
} /* get options */
+
+
+static void usage()
+{
+ printf("%s [options]\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
diff --git a/myisam/ft_test1.h b/myisam/ft_test1.h
index 17b0cae66b7..e360244057b 100644
--- a/myisam/ft_test1.h
+++ b/myisam/ft_test1.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -419,4 +419,3 @@ const char *query[NQUERIES]={
"against about after more right the with/without", /* stopwords test */
"mysql license and copyright"
};
-
diff --git a/myisam/ft_update.c b/myisam/ft_update.c
index 753c4dc4029..a68cc2a4cf4 100644
--- a/myisam/ft_update.c
+++ b/myisam/ft_update.c
@@ -19,6 +19,7 @@
/* functions to work with full-text indices */
#include "ftdefs.h"
+#include <math.h>
/**************************************************************
This is to make ft-code to ignore keyseg.length at all *
@@ -27,46 +28,92 @@
#define set_if_smaller(A,B) /* no op */
/**************************************************************/
+void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const byte *record,
+ FT_SEG_ITERATOR *ftsi)
+{
+ ftsi->num=info->s->keyinfo[keynr].keysegs-FT_SEGS;
+ ftsi->seg=info->s->keyinfo[keynr].seg;
+ ftsi->rec=record;
+}
+
+void _mi_ft_segiterator_dummy_init(const byte *record, uint len,
+ FT_SEG_ITERATOR *ftsi)
+{
+ ftsi->num=1;
+ ftsi->seg=0;
+ ftsi->pos=record;
+ ftsi->len=len;
+}
+
+/*
+ This function breaks convention "return 0 in success"
+ but it's easier to use like this
+
+ while(_mi_ft_segiterator())
+
+ so "1" means "OK", "0" means "EOF"
+*/
-/* parses a document i.e. calls _mi_ft_parse for every keyseg */
-static FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf,
- const byte *record)
+uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi)
{
- TREE *parsed=NULL;
- MI_KEYSEG *keyseg;
- byte *pos;
- uint i;
+ if (!ftsi->num) return 0; else ftsi->num--;
+ if (!ftsi->seg) return 1; else ftsi->seg--;
- keyseg=info->s->keyinfo[keynr].seg;
- for (i=info->s->keyinfo[keynr].keysegs-FT_SEGS ; i-- ; )
+ if (ftsi->seg->null_bit &&
+ (ftsi->rec[ftsi->seg->null_pos] & ftsi->seg->null_bit))
{
- uint len;
+ ftsi->pos=0;
+ return 1;
+ }
+ ftsi->pos= ftsi->rec+ftsi->seg->start;
+ if (ftsi->seg->flag & HA_VAR_LENGTH)
+ {
+ ftsi->len=uint2korr(ftsi->pos);
+ ftsi->pos+=2; /* Skip VARCHAR length */
+ set_if_smaller(ftsi->len,ftsi->seg->length);
+ return 1;
+ }
+ if (ftsi->seg->flag & HA_BLOB_PART)
+ {
+ ftsi->len=_mi_calc_blob_length(ftsi->seg->bit_start,ftsi->pos);
+ memcpy_fixed((char*) &ftsi->pos, ftsi->pos+ftsi->seg->bit_start,
+ sizeof(char*));
+ set_if_smaller(ftsi->len,ftsi->seg->length);
+ return 1;
+ }
+ ftsi->len=ftsi->seg->length;
+ return 1;
+}
- keyseg--;
- if (keyseg->null_bit && (record[keyseg->null_pos] & keyseg->null_bit))
- continue; /* NULL field */
- pos= (byte *)record+keyseg->start;
- if (keyseg->flag & HA_VAR_LENGTH)
- {
- len=uint2korr(pos);
- pos+=2; /* Skip VARCHAR length */
- set_if_smaller(len,keyseg->length);
- }
- else if (keyseg->flag & HA_BLOB_PART)
- {
- len=_mi_calc_blob_length(keyseg->bit_start,pos);
- memcpy_fixed(&pos,pos+keyseg->bit_start,sizeof(char*));
- set_if_smaller(len,keyseg->length);
- }
- else
- len=keyseg->length;
- if (!(parsed=ft_parse(parsed, pos, len)))
- return NULL;
+
+/* parses a document i.e. calls ft_parse for every keyseg */
+
+uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record)
+{
+ FT_SEG_ITERATOR ftsi;
+ _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+
+ ft_parse_init(parsed, info->s->keyinfo[keynr].seg->charset);
+ while (_mi_ft_segiterator(&ftsi))
+ {
+ if (ftsi.pos)
+ if (ft_parse(parsed, (byte *)ftsi.pos, ftsi.len))
+ return 1;
}
- /* Handle the case where all columns are NULL */
- if (!parsed && !(parsed=ft_parse(0, (byte*) "", 0)))
+ return 0;
+}
+
+FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr,
+ byte *keybuf __attribute__((unused)),
+ const byte *record)
+{
+ TREE ptree;
+
+ bzero((char*) &ptree, sizeof(ptree));
+ if (_mi_ft_parse(&ptree, info, keynr, record))
return NULL;
- return ft_linearize(info, keynr, keybuf, parsed);
+
+ return ft_linearize(/*info, keynr, keybuf, */ &ptree);
}
static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf,
@@ -74,88 +121,110 @@ static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf,
{
uint key_length;
- while(wlist->pos)
+ for (; wlist->pos; wlist++)
{
key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos);
if (_mi_ck_write(info,keynr,(uchar*) keybuf,key_length))
return 1;
- wlist++;
}
return 0;
}
-static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wlist, my_off_t filepos)
+static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf,
+ FT_WORD *wlist, my_off_t filepos)
{
uint key_length, err=0;
- while(wlist->pos)
+ for (; wlist->pos; wlist++)
{
key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos);
if (_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length))
err=1;
- wlist++;
}
return err;
}
-/* compares an appropriate parts of two WORD_KEY keys directly out of records */
-/* returns 1 if they are different */
+/*
+ Compares an appropriate parts of two WORD_KEY keys directly out of records
+ returns 1 if they are different
+*/
#define THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT 1
#define GEE_THEY_ARE_ABSOLUTELY_IDENTICAL 0
int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
{
- MI_KEYSEG *keyseg;
- byte *pos1, *pos2;
- uint i;
+ FT_SEG_ITERATOR ftsi1, ftsi2;
+ CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset;
+ _mi_ft_segiterator_init(info, keynr, rec1, &ftsi1);
+ _mi_ft_segiterator_init(info, keynr, rec2, &ftsi2);
- i=info->s->keyinfo[keynr].keysegs-FT_SEGS;
- keyseg=info->s->keyinfo[keynr].seg;
- while(i--)
+ while (_mi_ft_segiterator(&ftsi1) && _mi_ft_segiterator(&ftsi2))
{
- uint len1, len2;
- LINT_INIT(len1); LINT_INIT(len2);
- keyseg--;
- if (keyseg->null_bit)
- {
- if ( (rec1[keyseg->null_pos] ^ rec2[keyseg->null_pos])
- & keyseg->null_bit )
- return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
- if (rec1[keyseg->null_pos] & keyseg->null_bit )
- continue; /* NULL field */
- }
- pos1= (byte *)rec1+keyseg->start;
- pos2= (byte *)rec2+keyseg->start;
- if (keyseg->flag & HA_VAR_LENGTH)
- {
- len1=uint2korr(pos1);
- pos1+=2; /* Skip VARCHAR length */
- set_if_smaller(len1,keyseg->length);
- len2=uint2korr(pos2);
- pos2+=2; /* Skip VARCHAR length */
- set_if_smaller(len2,keyseg->length);
- }
- else if (keyseg->flag & HA_BLOB_PART)
+ if ((ftsi1.pos != ftsi2.pos) &&
+ (!ftsi1.pos || !ftsi2.pos ||
+ _mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len,
+ (uchar*) ftsi2.pos,ftsi2.len,0)))
+ return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
+ }
+ return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL;
+}
+
+
+/* update a document entry */
+
+int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
+ const byte *oldrec, const byte *newrec, my_off_t pos)
+{
+ int error= -1;
+ FT_WORD *oldlist,*newlist, *old_word, *new_word;
+ CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset;
+ uint key_length;
+ int cmp, cmp2;
+
+ if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, keybuf, oldrec)))
+ goto err0;
+ if (!(new_word=newlist=_mi_ft_parserecord(info, keynr, keybuf, newrec)))
+ goto err1;
+
+ error=0;
+ while(old_word->pos && new_word->pos)
+ {
+ cmp=_mi_compare_text(cs, (uchar*) old_word->pos,old_word->len,
+ (uchar*) new_word->pos,new_word->len,0);
+ cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5);
+
+ if (cmp < 0 || cmp2)
{
- len1=_mi_calc_blob_length(keyseg->bit_start,pos1);
- memcpy_fixed(&pos1,pos1+keyseg->bit_start,sizeof(char*));
- set_if_smaller(len1,keyseg->length);
- len2=_mi_calc_blob_length(keyseg->bit_start,pos2);
- memcpy_fixed(&pos2,pos2+keyseg->bit_start,sizeof(char*));
- set_if_smaller(len2,keyseg->length);
+ key_length=_ft_make_key(info,keynr,keybuf,old_word,pos);
+ if ((error=_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length)))
+ goto err2;
}
- else /* fixed length key */
+ if (cmp > 0 || cmp2)
{
- len1=len2=keyseg->length;
+ key_length=_ft_make_key(info,keynr,keybuf,new_word,pos);
+ if ((error=_mi_ck_write(info,keynr,(uchar*) keybuf,key_length)))
+ goto err2;
}
- if ((len1 != len2) || memcmp(pos1, pos2, len1))
- return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
- }
- return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL;
+ if (cmp<=0) old_word++;
+ if (cmp>=0) new_word++;
+ }
+ if (old_word->pos)
+ error=_mi_ft_erase(info,keynr,keybuf,old_word,pos);
+ else if (new_word->pos)
+ error=_mi_ft_store(info,keynr,keybuf,new_word,pos);
+
+err2:
+ my_free((char*) newlist,MYF(0));
+err1:
+ my_free((char*) oldlist,MYF(0));
+err0:
+ return error;
}
+
/* adds a document to the collection */
+
int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
my_off_t pos)
{
@@ -170,7 +239,9 @@ int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
return error;
}
+
/* removes a document from the collection */
+
int _mi_ft_del(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
my_off_t pos)
{
diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h
index d9b4ff6b44d..a1352a13150 100644
--- a/myisam/ftdefs.h
+++ b/myisam/ftdefs.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,15 +22,18 @@
#include <m_ctype.h>
#include <my_tree.h>
-#define MIN_WORD_LEN 4
-
#define HYPHEN_IS_DELIM
#define HYPHEN_IS_CONCAT /* not used for now */
#define COMPILE_STOPWORDS_IN
-/* Most of the formulae were shamelessly stolen from SMART distribution
- ftp://ftp.cs.cornell.edu/pub/smart/smart.11.0.tar.Z
+/* Interested readers may consult SMART
+ (ftp://ftp.cs.cornell.edu/pub/smart/smart.11.0.tar.Z)
+ for an excellent implementation of vector space model we use.
+ It also demonstrate the usage of different weghting techniques.
+ This code, though, is completely original and is not based on the
+ SMART code but was in some cases inspired by it.
+
NORM_PIVOT was taken from the article
A.Singhal, C.Buckley, M.Mitra, "Pivoted Document Length Normalization",
ACM SIGIR'96, 21-29, 1996
@@ -82,6 +85,19 @@ extern ulong collstat;
#define GWS_ENTROPY (1-(suml/sum-log(sum))/log(aio->info->state->records))
/*=================================================================*/
+/* Boolean search operators */
+#define FTB_YES (ft_boolean_syntax[0])
+#define FTB_EGAL (ft_boolean_syntax[1])
+#define FTB_NO (ft_boolean_syntax[2])
+#define FTB_INC (ft_boolean_syntax[3])
+#define FTB_DEC (ft_boolean_syntax[4])
+#define FTB_LBR (ft_boolean_syntax[5])
+#define FTB_RBR (ft_boolean_syntax[6])
+#define FTB_NEG (ft_boolean_syntax[7])
+#define FTB_TRUNC (ft_boolean_syntax[8])
+#define FTB_LQUOT (ft_boolean_syntax[10])
+#define FTB_RQUOT (ft_boolean_syntax[11])
+
typedef struct st_ft_word {
byte * pos;
uint len;
@@ -91,9 +107,52 @@ typedef struct st_ft_word {
#endif /* EVAL_RUN */
} FT_WORD;
+typedef struct st_ftb_param {
+ byte prev;
+ int yesno;
+ int plusminus;
+ bool pmsign;
+ bool trunc;
+ byte *quot;
+} FTB_PARAM;
+
int is_stopword(char *word, uint len);
uint _ft_make_key(MI_INFO *, uint , byte *, FT_WORD *, my_off_t);
-TREE * ft_parse(TREE *, byte *, int);
-FT_WORD * ft_linearize(MI_INFO *, uint, byte *, TREE *);
+byte ft_get_word(byte **, byte *, FT_WORD *, FTB_PARAM *);
+byte ft_simple_get_word(byte **, byte *, FT_WORD *);
+
+typedef struct _st_ft_seg_iterator {
+ uint num, len;
+ MI_KEYSEG *seg;
+ const byte *rec, *pos;
+} FT_SEG_ITERATOR;
+
+void _mi_ft_segiterator_init(MI_INFO *, uint, const byte *, FT_SEG_ITERATOR *);
+void _mi_ft_segiterator_dummy_init(const byte *, uint, FT_SEG_ITERATOR *);
+uint _mi_ft_segiterator(FT_SEG_ITERATOR *);
+
+void ft_parse_init(TREE *, CHARSET_INFO *);
+int ft_parse(TREE *, byte *, int);
+FT_WORD * ft_linearize(TREE *);
+FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, byte *, const byte *);
+uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record);
+
+extern const struct _ft_vft _ft_vft_nlq;
+FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, my_bool);
+int ft_nlq_read_next(FT_INFO *, char *);
+float ft_nlq_find_relevance(FT_INFO *, byte *, uint);
+void ft_nlq_close_search(FT_INFO *);
+float ft_nlq_get_relevance(FT_INFO *);
+my_off_t ft_nlq_get_docid(FT_INFO *);
+void ft_nlq_reinit_search(FT_INFO *);
+
+extern const struct _ft_vft _ft_vft_boolean;
+FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, my_bool);
+int ft_boolean_read_next(FT_INFO *, char *);
+float ft_boolean_find_relevance(FT_INFO *, byte *, uint);
+void ft_boolean_close_search(FT_INFO *);
+float ft_boolean_get_relevance(FT_INFO *);
+my_off_t ft_boolean_get_docid(FT_INFO *);
+void ft_boolean_reinit_search(FT_INFO *);
diff --git a/myisam/fulltext.h b/myisam/fulltext.h
index 8fcac8172b1..f787c9bcfe8 100644
--- a/myisam/fulltext.h
+++ b/myisam/fulltext.h
@@ -24,7 +24,6 @@
/* shoudn't be def'ed when linking with mysql */
#undef EVAL_RUN
-#define HA_FT_MAXLEN 254
#define HA_FT_WTYPE HA_KEYTYPE_FLOAT
#define HA_FT_WLEN 4
#ifdef EVAL_RUN
diff --git a/myisam/mi_cache.c b/myisam/mi_cache.c
index f88725ff04b..7b53f3d50ff 100644
--- a/myisam/mi_cache.c
+++ b/myisam/mi_cache.c
@@ -1,27 +1,39 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Functions for read record cacheing with myisam */
-/* Used instead of my_b_read() to allow for no-cacheed seeks */
+/*
+ Functions for read record cacheing with myisam
+ Used for reading dynamic/compressed records from datafile.
-#include "myisamdef.h"
+ Can fetch data directly from file (outside cache),
+ if reading a small chunk straight before the cached part (with possible
+ overlap).
+
+ Can be explicitly asked not to use cache (by not setting READING_NEXT in
+ flag) - useful for occasional out-of-cache reads, when the next read is
+ expected to hit the cache again.
- /* Copy block from cache if it`s in it. If re_read_if_possibly is */
- /* set read to cache (if after current file-position) else read to */
- /* buff */
+ Allows "partial read" errors in the record header (when READING_HEADER flag
+ is set) - unread part is bzero'ed
+
+ Note: out-of-cache reads are disabled for shared IO_CACHE's
+*/
+
+
+#include "myisamdef.h"
int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length,
int flag)
@@ -31,7 +43,7 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length,
char *in_buff_pos;
DBUG_ENTER("_mi_read_cache");
- if (pos < info->pos_in_file)
+ if (pos < info->pos_in_file && ! info->share)
{
read_length=length;
if ((my_off_t) read_length > (my_off_t) (info->pos_in_file-pos))
@@ -44,12 +56,13 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length,
pos+=read_length;
buff+=read_length;
}
- if ((offset= (my_off_t) (pos - info->pos_in_file)) <
- (my_off_t) (info->rc_end - info->rc_request_pos))
+ if (pos >= info->pos_in_file &&
+ (offset= (my_off_t) (pos - info->pos_in_file)) <
+ (my_off_t) (info->read_end - info->request_pos))
{
- in_buff_pos=info->rc_request_pos+(uint) offset;
- in_buff_length= min(length,(uint) (info->rc_end-in_buff_pos));
- memcpy(buff,info->rc_request_pos+(uint) offset,(size_t) in_buff_length);
+ in_buff_pos=info->request_pos+(uint) offset;
+ in_buff_length= min(length,(uint) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
if (!(length-=in_buff_length))
DBUG_RETURN(0);
pos+=in_buff_length;
@@ -57,41 +70,38 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length,
}
else
in_buff_length=0;
- if (flag & READING_NEXT)
+ if (flag & READING_NEXT || info->share)
{
if (pos != (info->pos_in_file +
(uint) (info->rc_end - info->rc_request_pos)))
{
info->pos_in_file=pos; /* Force start here */
- info->rc_pos=info->rc_end=info->rc_request_pos; /* Everything used */
+ info->read_pos=info->read_end=info->request_pos; /* Everything used */
info->seek_not_done=1;
}
else
- info->rc_pos=info->rc_end; /* All block used */
+ info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length))
DBUG_RETURN(0);
- if (!(flag & READING_HEADER) || info->error == -1 ||
- (uint) info->error+in_buff_length < 3)
- {
- if (!my_errno || my_errno == -1)
- my_errno=HA_ERR_WRONG_IN_RECORD;
- DBUG_RETURN(1);
- }
- bzero(buff+info->error,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length -
- (uint) info->error);
- DBUG_RETURN(0);
+ read_length=info->error;
+ }
+ else
+ {
+ info->seek_not_done=1;
+ if ((read_length=my_pread(info->file,buff,length,pos,MYF(0))) == length)
+ DBUG_RETURN(0);
}
- info->seek_not_done=1;
- if ((read_length=my_pread(info->file,buff,length,pos,MYF(0))) == length)
- DBUG_RETURN(0);
if (!(flag & READING_HEADER) || (int) read_length == -1 ||
read_length+in_buff_length < 3)
{
+ DBUG_PRINT("error",
+ ("Error %d reading next-multi-part block (Got %d bytes)",
+ my_errno, (int) read_length));
if (!my_errno || my_errno == -1)
my_errno=HA_ERR_WRONG_IN_RECORD;
DBUG_RETURN(1);
}
bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length -
- read_length);
+ read_length);
DBUG_RETURN(0);
} /* _mi_read_cache */
diff --git a/myisam/mi_changed.c b/myisam/mi_changed.c
index bd6b14b0c6c..c2ab5568eba 100644
--- a/myisam/mi_changed.c
+++ b/myisam/mi_changed.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -24,7 +24,7 @@ int mi_is_changed(MI_INFO *info)
{
int result;
DBUG_ENTER("mi_is_changed");
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(-1);
VOID(_mi_writeinfo(info,0));
result=(int) info->data_changed;
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 89fcfe74cea..91990dc3b66 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -14,14 +14,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Descript, check and repair of ISAM tables */
+/* Describe, check and repair of MyISAM tables */
-#include "fulltext.h"
+#include "ftdefs.h"
#include <m_ctype.h>
#include <stdarg.h>
-#include <getopt.h>
+#include <my_getopt.h>
#include <assert.h>
-#ifdef HAVE_SYS_VADVICE_H
+#ifdef HAVE_SYS_VADVISE_H
#include <sys/vadvise.h>
#endif
#ifdef HAVE_SYS_MMAN_H
@@ -45,25 +45,22 @@ static int writekeys(MI_CHECK *param, MI_INFO *info,byte *buff,
my_off_t filepos);
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
my_off_t pagepos, File new_file);
-static int sort_key_read(SORT_INFO *sort_info,void *key);
-static int sort_get_next_record(SORT_INFO *sort_info);
-static int sort_key_cmp(SORT_INFO *sort_info, const void *a,const void *b);
-static int sort_key_write(SORT_INFO *sort_info, const void *a);
+static int sort_key_read(MI_SORT_PARAM *sort_param,void *key);
+static int sort_ft_key_read(MI_SORT_PARAM *sort_param,void *key);
+static int sort_get_next_record(MI_SORT_PARAM *sort_param);
+static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b);
+static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a);
static my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo,
uchar *key);
-static int sort_insert_key(MI_CHECK *param, reg1 SORT_KEY_BLOCKS *key_block,
+static int sort_insert_key(MI_SORT_PARAM *sort_param,
+ reg1 SORT_KEY_BLOCKS *key_block,
uchar *key, my_off_t prev_block);
-static int sort_delete_record(MI_CHECK *param);
-static int flush_pending_blocks(MI_CHECK *param);
+static int sort_delete_record(MI_SORT_PARAM *sort_param);
+/*static int flush_pending_blocks(MI_CHECK *param);*/
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
uint buffer_length);
-static void update_key_parts(MI_KEYDEF *keyinfo,
- ulong *rec_per_key_part,
- ulonglong *unique,
- ulonglong records);
static ha_checksum mi_byte_checksum(const byte *buf, uint length);
-static void set_data_file_type(MI_CHECK *param, SORT_INFO *info,
- MYISAM_SHARE *share);
+static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share);
#ifdef __WIN__
static double ulonglong2double(ulonglong value)
@@ -79,7 +76,7 @@ static double ulonglong2double(ulonglong value)
#else
#define my_off_t2double(A) ((double) (A))
#endif /* SIZEOF_OFF_T > 4 */
-#endif
+#endif /* __WIN__ */
void myisamchk_init(MI_CHECK *param)
{
@@ -95,7 +92,6 @@ void myisamchk_init(MI_CHECK *param)
param->sort_key_blocks=BUFFERS_WHEN_SORTING;
param->tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
param->myf_rw=MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL);
- param->sort_info.param=param;
param->start_check_pos=0;
}
@@ -104,6 +100,7 @@ void myisamchk_init(MI_CHECK *param)
int chk_status(MI_CHECK *param, register MI_INFO *info)
{
MYISAM_SHARE *share=info->s;
+
if (mi_is_crashed_on_repair(info))
mi_check_print_warning(param,
"Table is marked as crashed and last repair failed");
@@ -219,7 +216,7 @@ int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
}
DBUG_RETURN(0);
wrong:
- param->retry_without_quick=1; /* Don't use quick repair */
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
if (test_flag & T_VERBOSE) puts("");
mi_check_print_error(param,"record delete-link-chain corrupted");
DBUG_RETURN(1);
@@ -231,7 +228,7 @@ wrong:
static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
{
my_off_t next_link;
- uint block_size=(nr+1)*MI_KEY_BLOCK_LENGTH;
+ uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
ha_rows records;
char llbuff[21],*buff;
DBUG_ENTER("check_k_link");
@@ -319,7 +316,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
error=1;
mi_check_print_error(param,"Size of datafile is: %-9s Should be: %s",
llstr(size,buff), llstr(skr,buff2));
- param->retry_without_quick=1; /* Don't use quick repair */
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
}
else
{
@@ -458,7 +455,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
info->s->state.auto_increment=save_auto_value;
/* Check that there isn't a row with auto_increment = 0 in the table */
- mi_extra(info,HA_EXTRA_KEYREAD);
+ mi_extra(info,HA_EXTRA_KEYREAD,0);
bzero(info->lastkey,keyinfo->seg->length);
if (!mi_rkey(info, info->rec_buff, key, (const byte*) info->lastkey,
keyinfo->seg->length, HA_READ_KEY_EXACT))
@@ -469,7 +466,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
"Found row where the auto_increment column has the value 0");
param->warning_printed=save;
}
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
}
length=(my_off_t) isam_key_length(info,keyinfo)*keys + param->key_blocks*2;
@@ -843,7 +840,9 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
}
if (info->s->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to= mi_alloc_rec_buff(info, block_info.rec_len,
+ &info->rec_buff,
+ &info->alloced_rec_buff_length)))
{
mi_check_print_error(param,"Not enough memory for blob at %s",
llstr(start_recpos,llbuff));
@@ -901,7 +900,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
info->checksum=mi_checksum(info,record);
if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE))
{
- if (_mi_rec_check(info,record))
+ if (_mi_rec_check(info,record, info->rec_buff))
{
mi_check_print_error(param,"Found wrong packed record at %s",
llstr(start_recpos,llbuff));
@@ -1068,7 +1067,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
if (used != 0 && ! param->error_printed)
{
printf("Records:%18s M.recordlength:%9lu Packed:%14.0f%%\n",
- llstr(records,llbuff), (long)((used-link_used)/records),
+ llstr(records,llbuff), (long)((used-link_used)/records),
(info->s->base.blobs ? 0.0 :
(ulonglong2double((ulonglong) info->s->base.reclength*records)-
my_off_t2double(used))/
@@ -1092,7 +1091,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
mi_check_print_error(param,"got error: %d when reading datafile at record: %s",my_errno, llstr(records,llbuff));
err2:
my_free((gptr) record,MYF(0));
- param->retry_without_quick=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1);
} /* chk_data_link */
@@ -1110,37 +1109,45 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
File new_file;
MYISAM_SHARE *share=info->s;
char llbuff[22],llbuff2[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO sort_info;
+ MI_SORT_PARAM sort_param;
DBUG_ENTER("mi_repair");
- sort_info->buff=sort_info->record=0;
+ bzero((char *)&sort_info, sizeof(sort_info));
+ bzero((char *)&sort_param, sizeof(sort_param));
start_records=info->state->records;
new_header_length=(param->testflag & T_UNPACK) ? 0L :
share->pack.header_length;
got_error=1;
new_file= -1;
+ sort_param.sort_info=&sort_info;
+
if (!(param->testflag & T_SILENT))
{
printf("- recovering (with keycache) MyISAM-table '%s'\n",name);
printf("Data records: %s\n", llstr(info->state->records,llbuff));
}
+ param->testflag|=T_REP; /* for easy checking */
if (!param->using_global_keycache)
- VOID(init_key_cache(param->use_buffers,NEAD_MEM));
+ VOID(init_key_cache(param->use_buffers));
if (init_io_cache(&param->read_cache,info->dfile,
(uint) param->read_buffer_length,
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
+ {
+ bzero(&info->rec_cache,sizeof(info->rec_cache));
goto err;
+ }
if (!rep_quick)
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE, new_header_length, 1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
goto err;
info->opt_flag|=WRITE_CACHE_USED;
- sort_info->start_recpos=0;
- sort_info->buff=0; sort_info->buff_length=0;
- if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength,
+ sort_param.rec_buff=info->rec_buff;
+ sort_param.alloced_rec_buff_length=info->alloced_rec_buff_length;
+ if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
MYF(0))))
{
mi_check_print_error(param,"Not enough memory for extra record");
@@ -1149,9 +1156,11 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
if (!rep_quick)
{
- if ((new_file=my_raid_create(fn_format(param->temp_filename,name,"",
- DATA_TMP_EXT,
- 2+4),
+ /* Get real path for data file */
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename,"",
+ DATA_TMP_EXT, 2+4),
0,param->tmpfile_createflag,
share->base.raid_type,
share->base.raid_chunks,
@@ -1173,16 +1182,19 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
mi_int2store(share->state.header.options,share->options);
}
}
- sort_info->info=info;
- sort_info->pos=sort_info->max_pos=share->pack.header_length;
- sort_info->filepos=new_header_length;
- param->read_cache.end_of_file=sort_info->filelength=
+ sort_info.info=info;
+ sort_info.param = param;
+ sort_param.read_cache=param->read_cache;
+ sort_param.pos=sort_param.max_pos=share->pack.header_length;
+ sort_param.filepos=new_header_length;
+ param->read_cache.end_of_file=sort_info.filelength=
my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
- sort_info->dupp=0;
- sort_info->fix_datafile= (my_bool) (! rep_quick);
- sort_info->max_records= ~(ha_rows) 0;
+ sort_info.dupp=0;
+ sort_param.fix_datafile= (my_bool) (! rep_quick);
+ sort_param.master=1;
+ sort_info.max_records= ~(ha_rows) 0;
- set_data_file_type(param, sort_info, share);
+ set_data_file_type(&sort_info, share);
del=info->state->del;
info->state->records=info->state->del=share->state.split=0;
info->state->empty=0;
@@ -1196,10 +1208,11 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
for (i=0 ; i < share->state.header.max_block_size ; i++)
share->state.key_del[i]= HA_OFFSET_ERROR;
- /* I think mi_repair and mi_repair_by_sort should do the same
- (according, e.g. to ha_myisam::repair), but as mi_repair doesn't
- touch key_map it cannot be used to T_CREATE_MISSING_KEYS.
- That is the next line for... (serg)
+ /*
+ I think mi_repair and mi_repair_by_sort should do the same
+ (according, e.g. to ha_myisam::repair), but as mi_repair doesn't
+ touch key_map it cannot be used to T_CREATE_MISSING_KEYS.
+ That is what the next line is for... (serg)
*/
share->state.key_map= ((((ulonglong) 1L << share->base.keys)-1) &
@@ -1208,36 +1221,37 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
info->state->key_file_length=share->base.keystart;
lock_memory(param); /* Everything is alloced */
- while (!(error=sort_get_next_record(sort_info)))
+ while (!(error=sort_get_next_record(&sort_param)))
{
- if (writekeys(param, info,(byte*) sort_info->record,sort_info->filepos))
+ if (writekeys(param,info,(byte*)sort_param.record,sort_param.filepos))
{
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
goto err;
- DBUG_DUMP("record",(byte*) sort_info->record,share->base.pack_reclength);
+ DBUG_DUMP("record",(byte*) sort_param.record,share->base.pack_reclength);
mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
info->errkey+1,
- llstr(sort_info->start_recpos,llbuff),
+ llstr(sort_param.start_recpos,llbuff),
llstr(info->dupp_key_pos,llbuff2));
if (param->testflag & T_VERBOSE)
{
VOID(_mi_make_key(info,(uint) info->errkey,info->lastkey,
- sort_info->record,0L));
+ sort_param.record,0L));
_mi_print_key(stdout,share->keyinfo[info->errkey].seg,info->lastkey,
USE_WHOLE_KEY);
}
- sort_info->dupp++;
- if (rep_quick == 1)
+ sort_info.dupp++;
+ if (!(rep_quick & T_FORCE_UNIQUENESS))
{
- param->error_printed=param->retry_without_quick=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
+ param->error_printed=1;
goto err;
}
continue;
}
- if (sort_write_record(sort_info))
+ if (sort_write_record(&sort_param))
goto err;
}
- if (error > 0 || write_data_suffix(param,info) ||
+ if (error > 0 || write_data_suffix(&sort_info, (my_bool)!rep_quick) ||
flush_io_cache(&info->rec_cache) || param->read_cache.error < 0)
goto err;
@@ -1253,12 +1267,13 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
goto err;
}
- if (rep_quick && del+sort_info->dupp != info->state->del)
+ if (rep_quick && del+sort_info.dupp != info->state->del)
{
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
mi_check_print_error(param,"Run recovery again without -q");
got_error=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
goto err;
}
if (param->testflag & T_SAFE_REPAIR)
@@ -1276,14 +1291,12 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
{
my_close(info->dfile,MYF(0));
info->dfile=new_file;
- info->state->data_file_length=sort_info->filepos;
- /* Only whole records */
- share->state.split=info->state->records+info->state->del;
+ info->state->data_file_length=sort_param.filepos;
share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
}
else
{
- info->state->data_file_length=sort_info->max_pos;
+ info->state->data_file_length=sort_param.max_pos;
}
if (param->testflag & T_CALC_CHECKSUM)
share->state.checksum=param->glob_crc;
@@ -1292,10 +1305,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
{
if (start_records != info->state->records)
printf("Data records: %s\n", llstr(info->state->records,llbuff));
- if (sort_info->dupp)
+ if (sort_info.dupp)
mi_check_print_warning(param,
"%s records have been removed",
- llstr(sort_info->dupp,llbuff));
+ llstr(sort_info.dupp,llbuff));
}
got_error=0;
@@ -1311,11 +1324,11 @@ err:
{
my_close(new_file,MYF(0));
info->dfile=new_file= -1;
- if (change_to_newfile(share->filename,MI_NAME_DEXT,
+ if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share))
+ mi_open_datafile(info,share,-1))
got_error=1;
}
}
@@ -1323,7 +1336,7 @@ err:
{
if (! param->error_printed)
mi_check_print_error(param,"%d for record at pos %s",my_errno,
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param.start_recpos,llbuff));
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
@@ -1332,8 +1345,8 @@ err:
}
mi_mark_crashed_on_repair(info);
}
- my_free(sort_info->record,MYF(MY_ALLOW_ZERO_PTR));
- my_free(sort_info->buff,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
VOID(end_io_cache(&info->rec_cache));
@@ -1342,7 +1355,7 @@ err:
{
share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
share->pack.header_length=0;
- share->data_file_type=sort_info->new_data_file_type;
+ share->data_file_type=sort_info.new_data_file_type;
}
share->state.changed|= (STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES |
STATE_NOT_ANALYZED);
@@ -1501,8 +1514,10 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
if (!(param->testflag & T_SILENT))
printf("- Sorting index for MyISAM-table '%s'\n",name);
- if ((new_file=my_create(fn_format(param->temp_filename,name,"",
- INDEX_TMP_EXT,2+4),
+ /* Get real path for index file */
+ fn_format(param->temp_filename,name,"", MI_NAME_IEXT,2+4+32);
+ if ((new_file=my_create(fn_format(param->temp_filename,param->temp_filename,
+ "", INDEX_TMP_EXT,2+4),
0,param->tmpfile_createflag,MYF(0))) <= 0)
{
mi_check_print_error(param,"Can't create new tempfile: '%s'",
@@ -1522,7 +1537,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
if (share->state.key_root[key] != HA_OFFSET_ERROR)
{
- index_pos[key]=param->new_file_pos; /* Write first block here */
+ index_pos[key]=param->new_file_pos; /* Write first block here */
if (sort_one_index(param,info,keyinfo,share->state.key_root[key],
new_file))
goto err;
@@ -1538,12 +1553,12 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
old_state=share->state; /* save state if not stored */
r_locks=share->r_locks; w_locks=share->w_locks;
/* Put same locks as old file */
- share->r_locks=share->w_locks=0;
+ share->r_locks= share->w_locks= share->tot_locks= 0;
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
VOID(my_close(share->kfile,MYF(MY_WME)));
share->kfile = -1;
VOID(my_close(new_file,MYF(MY_WME)));
- if (change_to_newfile(share->filename,MI_NAME_IEXT,INDEX_TMP_EXT,0,
+ if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
MYF(0)) ||
mi_open_keyfile(share))
goto err2;
@@ -1551,6 +1566,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
_mi_readinfo(info,F_WRLCK,0); /* Will lock the table */
info->lock_type=F_WRLCK;
share->r_locks=r_locks; share->w_locks=w_locks;
+ share->tot_locks= r_locks+w_locks;
share->state=old_state; /* Restore old state */
info->state->key_file_length=param->new_file_pos;
@@ -1643,9 +1659,14 @@ err:
} /* sort_one_index */
- /* Change to use new file */
- /* Copy stats from old file to new file, deletes orginal and */
- /* changes new file name to old file name */
+ /*
+ Let temporary file replace old file.
+ This assumes that the new file was created in the same
+ directory as given by realpath(filename).
+ This will ensure that any symlinks that are used will still work.
+ Copy stats from old file to new file, deletes orignal and
+ changes new file name to old file name
+ */
int change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext,
@@ -1660,8 +1681,10 @@ int change_to_newfile(const char * filename, const char * old_ext,
raid_chunks,
MYF(MY_WME | MY_LINK_WARNING | MyFlags));
#endif
- return my_redel(fn_format(old_filename,filename,"",old_ext,2+4),
- fn_format(new_filename,filename,"",new_ext,2+4),
+ /* Get real path to filename */
+ (void) fn_format(old_filename,filename,"",old_ext,2+4+32);
+ return my_redel(old_filename,
+ fn_format(new_filename,old_filename,"",new_ext,2+4),
MYF(MY_WME | MY_LINK_WARNING | MyFlags));
} /* change_to_newfile */
@@ -1721,8 +1744,21 @@ err:
DBUG_RETURN(1);
}
- /* Fix table or given index using sorting */
- /* saves new table in temp_filename */
+
+/*
+ Repair table or given index using sorting
+
+ SYNOPSIS
+ mi_repair_by_sort()
+ param Repair parameters
+ info MyISAM handler to repair
+ name Name of table (for warnings)
+ rep_quick set to <> 0 if we should not change data file
+
+ RESULT
+ 0 ok
+ <>0 Error
+*/
int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
const char * name, int rep_quick)
@@ -1735,9 +1771,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
File new_file;
MI_SORT_PARAM sort_param;
MYISAM_SHARE *share=info->s;
+ MI_KEYSEG *keyseg;
ulong *rec_per_key_part;
char llbuff[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO sort_info;
ulonglong key_map=share->state.key_map;
DBUG_ENTER("mi_repair_by_sort");
@@ -1751,25 +1788,11 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
printf("- recovering (with sort) MyISAM-table '%s'\n",name);
printf("Data records: %s\n", llstr(start_records,llbuff));
}
+ param->testflag|=T_REP; /* for easy checking */
- /* Hmm, repair_by_sort uses find_all_keys, and find_all_keys strictly
- implies "one row - one key per keynr", while for ft_key one row/keynr
- can produce as many keys as the number of unique words in the text
- that's why I disabled repair_by_sort for ft-keys. (serg)
- */
- for (i=0 ; i < share->base.keys ; i++)
- {
- if ((((ulonglong) 1 << i) & key_map) &&
- (share->keyinfo[i].flag & HA_FULLTEXT))
- {
- mi_check_print_error(param,
- "Can`t use repair_by_sort with FULLTEXT key");
- DBUG_RETURN(1);
- }
- }
-
- bzero((char*) sort_info,sizeof(*sort_info));
- if (!(sort_info->key_block=
+ bzero((char*)&sort_info,sizeof(sort_info));
+ bzero((char *)&sort_param, sizeof(sort_param));
+ if (!(sort_info.key_block=
alloc_key_blocks(param,
(uint) param->sort_key_blocks,
share->base.max_key_block_length))
@@ -1782,11 +1805,13 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
WRITE_CACHE,new_header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
goto err;
- sort_info->key_block_end=sort_info->key_block+param->sort_key_blocks;
+ sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
info->opt_flag|=WRITE_CACHE_USED;
info->rec_cache.file=info->dfile; /* for sort_delete_record */
- if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength,
+ sort_param.rec_buff=info->rec_buff;
+ sort_param.alloced_rec_buff_length=info->alloced_rec_buff_length;
+ if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
MYF(0))))
{
mi_check_print_error(param,"Not enough memory for extra record");
@@ -1794,7 +1819,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
}
if (!rep_quick)
{
- if ((new_file=my_raid_create(fn_format(param->temp_filename,name,"",
+ /* Get real path for data file */
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename, "",
DATA_TMP_EXT,
2+4),
0,param->tmpfile_createflag,
@@ -1841,32 +1869,34 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
key_map= ~key_map; /* Create the missing keys */
}
- sort_info->info=info;
- sort_info->param = param;
+ sort_info.info=info;
+ sort_info.param = param;
- set_data_file_type(param, sort_info, share);
- sort_info->filepos=new_header_length;
- sort_info->dupp=0;
- sort_info->buff=0;
- param->read_cache.end_of_file=sort_info->filelength=
+ set_data_file_type(&sort_info, share);
+ sort_param.filepos=new_header_length;
+ sort_info.dupp=0;
+ sort_info.buff=0;
+ param->read_cache.end_of_file=sort_info.filelength=
my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+ sort_param.wordlist=NULL;
+
if (share->data_file_type == DYNAMIC_RECORD)
length=max(share->base.min_pack_length+1,share->base.min_block_length);
else if (share->data_file_type == COMPRESSED_RECORD)
length=share->base.min_block_length;
else
length=share->base.pack_reclength;
- sort_param.max_records=sort_info->max_records=
- ((param->testflag & T_TRUST_HEADER) ? info->state->records :
- (ha_rows) (sort_info->filelength/length+1));
+ sort_info.max_records=
+ ((param->testflag & T_CREATE_MISSING_KEYS) ? info->state->records :
+ (ha_rows) (sort_info.filelength/length+1));
sort_param.key_cmp=sort_key_cmp;
sort_param.key_write=sort_key_write;
- sort_param.key_read=sort_key_read;
sort_param.lock_in_memory=lock_memory;
sort_param.tmpdir=param->tmpdir;
- sort_param.myf_rw=param->myf_rw;
- sort_param.sort_info=sort_info;
+ sort_param.sort_info=&sort_info;
+ sort_param.fix_datafile= (my_bool) (! rep_quick);
+ sort_param.master =1;
del=info->state->del;
param->glob_crc=0;
@@ -1874,40 +1904,51 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->calc_checksum=1;
rec_per_key_part= param->rec_per_key_part;
- for (sort_info->key=0 ; sort_info->key < share->base.keys ;
- rec_per_key_part+=sort_info->keyinfo->keysegs, sort_info->key++)
+ for (sort_param.key=0 ; sort_param.key < share->base.keys ;
+ rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
{
- sort_info->keyinfo=share->keyinfo+sort_info->key;
- if (!(((ulonglong) 1 << sort_info->key) & key_map))
+ sort_param.read_cache=param->read_cache;
+ sort_param.keyinfo=share->keyinfo+sort_param.key;
+ if (!(((ulonglong) 1 << sort_param.key) & key_map))
{
/* Remember old statistics for key */
memcpy((char*) rec_per_key_part,
(char*) share->state.rec_per_key_part+
(uint) (rec_per_key_part - param->rec_per_key_part),
- sort_info->keyinfo->keysegs*sizeof(*rec_per_key_part));
+ sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
continue;
}
if ((!(param->testflag & T_SILENT)))
- printf ("- Fixing index %d\n",sort_info->key+1);
- sort_info->max_pos=sort_info->pos=share->pack.header_length;
- sort_info->keyseg=sort_info->keyinfo->seg;
- sort_info->fix_datafile= (my_bool) (sort_info->key == 0 && ! rep_quick);
- bzero((char*) sort_info->unique,sizeof(sort_info->unique));
+ printf ("- Fixing index %d\n",sort_param.key+1);
+ sort_param.max_pos=sort_param.pos=share->pack.header_length;
+ keyseg=sort_param.keyinfo->seg;
+ bzero((char*) sort_param.unique,sizeof(sort_param.unique));
sort_param.key_length=share->rec_reflength;
- for (i=0 ; sort_info->keyseg[i].type != HA_KEYTYPE_END; i++)
+ for (i=0 ; keyseg[i].type != HA_KEYTYPE_END; i++)
{
- sort_param.key_length+=sort_info->keyseg[i].length;
- if (sort_info->keyseg[i].flag & HA_SPACE_PACK)
- sort_param.key_length+=get_pack_length(sort_info->keyseg[i].length);
- if (sort_info->keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH))
- sort_param.key_length+=2 + test(sort_info->keyseg[i].length >= 127);
- if (sort_info->keyseg[i].flag & HA_NULL_PART)
+ sort_param.key_length+=keyseg[i].length;
+ if (keyseg[i].flag & HA_SPACE_PACK)
+ sort_param.key_length+=get_pack_length(keyseg[i].length);
+ if (keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH))
+ sort_param.key_length+=2 + test(keyseg[i].length >= 127);
+ if (keyseg[i].flag & HA_NULL_PART)
sort_param.key_length++;
}
info->state->records=info->state->del=share->state.split=0;
info->state->empty=0;
+ if (sort_param.keyinfo->flag & HA_FULLTEXT)
+ {
+ sort_info.max_records=
+ (ha_rows) (sort_info.filelength/ft_max_word_len_for_sort+1);
+
+ sort_param.key_read=sort_ft_key_read;
+ sort_param.key_length+=ft_max_word_len_for_sort-ft_max_word_len;
+ }
+ else
+ sort_param.key_read=sort_key_read;
+
if (_create_index_by_sort(&sort_param,
(my_bool) (!(param->testflag & T_VERBOSE)),
(uint) param->sort_buffer_length))
@@ -1918,18 +1959,17 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->calc_checksum=0; /* No need to calc glob_crc */
/* Set for next loop */
- sort_param.max_records=sort_info->max_records=
- (ha_rows) info->state->records;
+ sort_info.max_records= (ha_rows) info->state->records;
if (param->testflag & T_STATISTICS)
- update_key_parts(sort_info->keyinfo, rec_per_key_part, sort_info->unique,
+ update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
(ulonglong) info->state->records);
- share->state.key_map|=(ulonglong) 1 << sort_info->key;
+ share->state.key_map|=(ulonglong) 1 << sort_param.key;
- if (sort_info->fix_datafile)
+ if (sort_param.fix_datafile)
{
- param->read_cache.end_of_file=sort_info->filepos;
- if (write_data_suffix(param,info) || end_io_cache(&info->rec_cache))
+ param->read_cache.end_of_file=sort_param.filepos;
+ if (write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache))
goto err;
if (param->testflag & T_SAFE_REPAIR)
{
@@ -1940,25 +1980,25 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
goto err;
}
}
- share->state.state.data_file_length = info->state->data_file_length
- = sort_info->filepos;
+ share->state.state.data_file_length = info->state->data_file_length=
+ sort_param.filepos;
/* Only whole records */
- share->state.split=info->state->records+info->state->del;
share->state.version=(ulong) time((time_t*) 0);
my_close(info->dfile,MYF(0));
info->dfile=new_file;
- share->data_file_type=sort_info->new_data_file_type;
+ share->data_file_type=sort_info.new_data_file_type;
share->pack.header_length=(ulong) new_header_length;
+ sort_param.fix_datafile=0;
}
else
- info->state->data_file_length=sort_info->max_pos;
+ info->state->data_file_length=sort_param.max_pos;
- if (flush_pending_blocks(param))
- goto err;
+ /*if (flush_pending_blocks(param))
+ goto err;*/
param->read_cache.file=info->dfile; /* re-init read cache */
- reinit_io_cache(&param->read_cache,READ_CACHE,share->pack.header_length,1,
- 1);
+ reinit_io_cache(&param->read_cache,READ_CACHE,share->pack.header_length,
+ 1,1);
}
if (param->testflag & T_WRITE_LOOP)
@@ -1966,16 +2006,17 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
VOID(fputs(" \r",stdout)); VOID(fflush(stdout));
}
- if (rep_quick && del+sort_info->dupp != info->state->del)
+ if (rep_quick && del+sort_info.dupp != info->state->del)
{
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
mi_check_print_error(param,"Run recovery again without -q");
got_error=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
goto err;
}
- if (rep_quick != 1)
+ if (rep_quick & T_FORCE_UNIQUENESS)
{
my_off_t skr=info->state->data_file_length+
(share->options & HA_OPTION_COMPRESS_RECORD ?
@@ -1985,7 +2026,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
skr < share->base.reloc*share->base.min_pack_length)
skr=share->base.reloc*share->base.min_pack_length;
#endif
- if (skr != sort_info->filelength && !info->s->base.raid_type)
+ if (skr != sort_info.filelength && !info->s->base.raid_type)
if (my_chsize(info->dfile,skr,MYF(0)))
mi_check_print_warning(param,
"Can't change size of datafile, error: %d",
@@ -2003,10 +2044,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
{
if (start_records != info->state->records)
printf("Data records: %s\n", llstr(info->state->records,llbuff));
- if (sort_info->dupp)
+ if (sort_info.dupp)
mi_check_print_warning(param,
"%s records have been removed",
- llstr(sort_info->dupp,llbuff));
+ llstr(sort_info.dupp,llbuff));
}
got_error=0;
@@ -2023,11 +2064,11 @@ err:
{
my_close(new_file,MYF(0));
info->dfile=new_file= -1;
- if (change_to_newfile(share->filename,MI_NAME_DEXT,
+ if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share))
+ mi_open_datafile(info,share,-1))
got_error=1;
}
}
@@ -2049,9 +2090,9 @@ err:
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
share->state.changed|=STATE_NOT_SORTED_PAGES;
- my_free((gptr) sort_info->key_block,MYF(MY_ALLOW_ZERO_PTR));
- my_free(sort_info->record,MYF(MY_ALLOW_ZERO_PTR));
- my_free(sort_info->buff,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
if (!got_error && (param->testflag & T_UNPACK))
@@ -2062,74 +2103,516 @@ err:
DBUG_RETURN(got_error);
}
+/*
+ Threaded repair of table using sorting
+
+ SYNOPSIS
+ mi_repair_by_sort_r()
+ param Repair parameters
+ info MyISAM handler to repair
+ name Name of table (for warnings)
+ rep_quick set to <> 0 if we should not change data file
+
+ DESCRIPTION
+ Same as mi_repair_by_sort but do it multithreaded
+ Each key is handled by a separate thread.
+ TODO: make a number of threads a parameter
+
+ RESULT
+ 0 ok
+ <>0 Error
+*/
+
+int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
+ const char * name, int rep_quick)
+{
+ int got_error;
+ uint i,key, total_key_length;
+ ulong rec_length;
+ ha_rows start_records;
+ my_off_t new_header_length,del;
+ File new_file;
+ MI_SORT_PARAM *sort_param=0;
+ MYISAM_SHARE *share=info->s;
+ ulong *rec_per_key_part;
+ MI_KEYSEG *keyseg;
+ char llbuff[22];
+ IO_CACHE_SHARE io_share;
+ SORT_INFO sort_info;
+ ulonglong key_map=share->state.key_map;
+ pthread_attr_t thr_attr;
+ DBUG_ENTER("mi_repair_parallel");
+
+ start_records=info->state->records;
+ got_error=1;
+ new_file= -1;
+ new_header_length=(param->testflag & T_UNPACK) ? 0 :
+ share->pack.header_length;
+ if (!(param->testflag & T_SILENT))
+ {
+ printf("- parallel recovering (with sort) MyISAM-table '%s'\n",name);
+ printf("Data records: %s\n", llstr(start_records,llbuff));
+ }
+ param->testflag|=T_REP; /* for easy checking */
+
+ bzero((char*)&sort_info,sizeof(sort_info));
+ if (!(sort_info.key_block=
+ alloc_key_blocks(param,
+ (uint) param->sort_key_blocks,
+ share->base.max_key_block_length))
+ || init_io_cache(&param->read_cache,info->dfile,
+ (uint) param->read_buffer_length,
+ READ_CACHE,share->pack.header_length,1,MYF(MY_WME)) ||
+ (! rep_quick &&
+ init_io_cache(&info->rec_cache,info->dfile,
+ (uint) param->write_buffer_length,
+ WRITE_CACHE,new_header_length,1,
+ MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
+ goto err;
+ sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
+ info->opt_flag|=WRITE_CACHE_USED;
+ info->rec_cache.file=info->dfile; /* for sort_delete_record */
+
+ if (!rep_quick)
+ {
+ /* Get real path for data file */
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename, "",
+ DATA_TMP_EXT,
+ 2+4),
+ 0,param->tmpfile_createflag,
+ share->base.raid_type,
+ share->base.raid_chunks,
+ share->base.raid_chunksize,
+ MYF(0))) < 0)
+ {
+ mi_check_print_error(param,"Can't create new tempfile: '%s'",
+ param->temp_filename);
+ goto err;
+ }
+ if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+ "datafile-header"))
+ goto err;
+ if (param->testflag & T_UNPACK)
+ {
+ share->options&= ~HA_OPTION_COMPRESS_RECORD;
+ mi_int2store(share->state.header.options,share->options);
+ }
+ share->state.dellink= HA_OFFSET_ERROR;
+ info->rec_cache.file=new_file;
+ }
+
+ info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+ if (!(param->testflag & T_CREATE_MISSING_KEYS))
+ {
+ /*
+ Flush key cache for this file if we are calling this outside
+ myisamchk
+ */
+ flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
+ /* Clear the pointers to the given rows */
+ for (i=0 ; i < share->base.keys ; i++)
+ share->state.key_root[i]= HA_OFFSET_ERROR;
+ for (i=0 ; i < share->state.header.max_block_size ; i++)
+ share->state.key_del[i]= HA_OFFSET_ERROR;
+ info->state->key_file_length=share->base.keystart;
+ }
+ else
+ {
+ if (flush_key_blocks(share->kfile, FLUSH_FORCE_WRITE))
+ goto err;
+ key_map= ~key_map; /* Create the missing keys */
+ }
+
+ sort_info.info=info;
+ sort_info.param = param;
+
+ set_data_file_type(&sort_info, share);
+ sort_info.dupp=0;
+ sort_info.buff=0;
+ param->read_cache.end_of_file=sort_info.filelength=
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+ rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+ rec_length=share->base.pack_reclength;
+ sort_info.max_records=
+ ((param->testflag & T_CREATE_MISSING_KEYS) ? info->state->records :
+ (ha_rows) (sort_info.filelength/rec_length+1));
+
+ del=info->state->del;
+ param->glob_crc=0;
+ if (param->testflag & T_CALC_CHECKSUM)
+ param->calc_checksum=1;
+
+ if (!(sort_param=(MI_SORT_PARAM *)
+ my_malloc((uint) share->base.keys *
+ (sizeof(MI_SORT_PARAM) + share->base.pack_reclength),
+ MYF(MY_ZEROFILL))))
+ {
+ mi_check_print_error(param,"Not enough memory!");
+ goto err;
+ }
+ total_key_length=0;
+ rec_per_key_part= param->rec_per_key_part;
+ info->state->records=info->state->del=share->state.split=0;
+ info->state->empty=0;
+
+ for (i=key=0 ; key < share->base.keys ;
+ rec_per_key_part+=sort_param[i].keyinfo->keysegs, i++, key++)
+ {
+ sort_param[i].key=key;
+ sort_param[i].keyinfo=share->keyinfo+key;
+ if (!(((ulonglong) 1 << key) & key_map))
+ {
+ /* Remember old statistics for key */
+ memcpy((char*) rec_per_key_part,
+ (char*) share->state.rec_per_key_part+
+ (uint) (rec_per_key_part - param->rec_per_key_part),
+ sort_param[i].keyinfo->keysegs*sizeof(*rec_per_key_part));
+ i--;
+ continue;
+ }
+ if ((!(param->testflag & T_SILENT)))
+ printf ("- Fixing index %d\n",key+1);
+ sort_param[i].key_read= ((sort_param[i].keyinfo->flag & HA_FULLTEXT) ?
+ sort_ft_key_read : sort_key_read);
+ sort_param[i].key_cmp=sort_key_cmp;
+ sort_param[i].key_write=sort_key_write;
+ sort_param[i].lock_in_memory=lock_memory;
+ sort_param[i].tmpdir=param->tmpdir;
+ sort_param[i].sort_info=&sort_info;
+ sort_param[i].master=0;
+ sort_param[i].fix_datafile=0;
+
+ sort_param[i].filepos=new_header_length;
+ sort_param[i].max_pos=sort_param[i].pos=share->pack.header_length;
+
+ sort_param[i].record= (((char *)(sort_param+share->base.keys))+
+ (share->base.pack_reclength * i));
+
+ sort_param[i].key_length=share->rec_reflength;
+ for (keyseg=sort_param[i].keyinfo->seg; keyseg->type != HA_KEYTYPE_END;
+ keyseg++)
+ {
+ sort_param[i].key_length+=keyseg->length;
+ if (keyseg->flag & HA_SPACE_PACK)
+ sort_param[i].key_length+=get_pack_length(keyseg->length);
+ if (keyseg->flag & (HA_BLOB_PART | HA_VAR_LENGTH))
+ sort_param[i].key_length+=2 + test(keyseg->length >= 127);
+ if (keyseg->flag & HA_NULL_PART)
+ sort_param[i].key_length++;
+ }
+ total_key_length+=sort_param[i].key_length;
+
+ if (sort_param[i].keyinfo->flag & HA_FULLTEXT)
+ sort_param[i].key_length+=ft_max_word_len_for_sort-ft_max_word_len;
+ }
+ sort_info.total_keys=i;
+ sort_param[0].master= 1;
+ sort_param[0].fix_datafile= (my_bool)(! rep_quick);
+
+ sort_info.got_error=0;
+ pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&sort_info.cond, 0);
+ pthread_mutex_lock(&sort_info.mutex);
+
+ init_io_cache_share(&param->read_cache, &io_share, i);
+ (void) pthread_attr_init(&thr_attr);
+ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
+
+ for (i=0 ; i < sort_info.total_keys ; i++)
+ {
+ sort_param[i].read_cache=param->read_cache;
+ sort_param[i].sortbuff_size=
+ /*
+ two approaches: the same amount of memory for each thread
+ or the memory for the same number of keys for each thread...
+ In the second one all the threads will fill their sort_buffers
+ (and call write_keys) at the same time, putting more stress on i/o.
+ */
+#ifndef USING_SECOND_APPROACH
+ param->sort_buffer_length/sort_info.total_keys;
+#else
+ param->sort_buffer_length*sort_param[i].key_length/total_key_length;
+#endif
+ if (pthread_create(&sort_param[i].thr, &thr_attr,
+ thr_find_all_keys,
+ (void *) (sort_param+i)))
+ {
+ mi_check_print_error(param,"Cannot start a repair thread");
+ remove_io_thread(&param->read_cache);
+ sort_info.got_error=1;
+ }
+ else
+ sort_info.threads_running++;
+ }
+ (void) pthread_attr_destroy(&thr_attr);
+
+ /* waiting for all threads to finish */
+ while (sort_info.threads_running)
+ pthread_cond_wait(&sort_info.cond, &sort_info.mutex);
+ pthread_mutex_unlock(&sort_info.mutex);
+
+ if ((got_error= thr_write_keys(sort_param)))
+ {
+ param->retry_repair=1;
+ goto err;
+ }
+ got_error=1; /* Assume the following may go wrong */
+
+ if (sort_param[0].fix_datafile)
+ {
+ if (write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache))
+ goto err;
+ if (param->testflag & T_SAFE_REPAIR)
+ {
+ /* Don't repair if we loosed more than one row */
+ if (info->state->records+1 < start_records)
+ {
+ info->state->records=start_records;
+ goto err;
+ }
+ }
+ share->state.state.data_file_length= info->state->data_file_length=
+ sort_param->filepos;
+ /* Only whole records */
+ share->state.version=(ulong) time((time_t*) 0);
+ my_close(info->dfile,MYF(0));
+ info->dfile=new_file;
+ share->data_file_type=sort_info.new_data_file_type;
+ share->pack.header_length=(ulong) new_header_length;
+ }
+ else
+ info->state->data_file_length=sort_param->max_pos;
+
+ if (rep_quick && del+sort_info.dupp != info->state->del)
+ {
+ mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
+ mi_check_print_error(param,"Run recovery again without -q");
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
+ goto err;
+ }
+
+ if (rep_quick & T_FORCE_UNIQUENESS)
+ {
+ my_off_t skr=info->state->data_file_length+
+ (share->options & HA_OPTION_COMPRESS_RECORD ?
+ MEMMAP_EXTRA_MARGIN : 0);
+#ifdef USE_RELOC
+ if (share->data_file_type == STATIC_RECORD &&
+ skr < share->base.reloc*share->base.min_pack_length)
+ skr=share->base.reloc*share->base.min_pack_length;
+#endif
+ if (skr != sort_info.filelength && !info->s->base.raid_type)
+ if (my_chsize(info->dfile,skr,MYF(0)))
+ mi_check_print_warning(param,
+ "Can't change size of datafile, error: %d",
+ my_errno);
+ }
+ if (param->testflag & T_CALC_CHECKSUM)
+ share->state.checksum=param->glob_crc;
+
+ if (my_chsize(share->kfile,info->state->key_file_length,MYF(0)))
+ mi_check_print_warning(param,
+ "Can't change size of indexfile, error: %d", my_errno);
+
+ if (!(param->testflag & T_SILENT))
+ {
+ if (start_records != info->state->records)
+ printf("Data records: %s\n", llstr(info->state->records,llbuff));
+ if (sort_info.dupp)
+ mi_check_print_warning(param,
+ "%s records have been removed",
+ llstr(sort_info.dupp,llbuff));
+ }
+ got_error=0;
+
+ if (&share->state.state != info->state)
+ memcpy( &share->state.state, info->state, sizeof(*info->state));
+
+err:
+ got_error|= flush_blocks(param,share->kfile);
+ VOID(end_io_cache(&info->rec_cache));
+ if (!got_error)
+ {
+ /* Replace the actual file with the temporary file */
+ if (new_file >= 0)
+ {
+ my_close(new_file,MYF(0));
+ info->dfile=new_file= -1;
+ if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
+ DATA_TMP_EXT, share->base.raid_chunks,
+ (param->testflag & T_BACKUP_DATA ?
+ MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
+ mi_open_datafile(info,share,-1))
+ got_error=1;
+ }
+ }
+ if (got_error)
+ {
+ if (! param->error_printed)
+ mi_check_print_error(param,"%d when fixing table",my_errno);
+ if (new_file >= 0)
+ {
+ VOID(my_close(new_file,MYF(0)));
+ VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
+ MYF(MY_WME)));
+ if (info->dfile == new_file)
+ info->dfile= -1;
+ }
+ mi_mark_crashed_on_repair(info);
+ }
+ else if (key_map == share->state.key_map)
+ share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
+ share->state.changed|=STATE_NOT_SORTED_PAGES;
+
+ pthread_cond_destroy (&sort_info.cond);
+ pthread_mutex_destroy(&sort_info.mutex);
+
+ my_free((gptr) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr) sort_param,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
+ VOID(end_io_cache(&param->read_cache));
+ info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
+ if (!got_error && (param->testflag & T_UNPACK))
+ {
+ share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
+ share->pack.header_length=0;
+ }
+ DBUG_RETURN(got_error);
+}
/* Read next record and return next key */
-static int sort_key_read(SORT_INFO *sort_info, void *key)
+static int sort_key_read(MI_SORT_PARAM *sort_param, void *key)
{
int error;
- MI_INFO *info;
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_INFO *info=sort_info->info;
DBUG_ENTER("sort_key_read");
- info=sort_info->info;
-
- if ((error=sort_get_next_record(sort_info)))
+ if ((error=sort_get_next_record(sort_param)))
DBUG_RETURN(error);
if (info->state->records == sort_info->max_records)
{
mi_check_print_error(sort_info->param,
- "Found too many records; Can`t continue");
+ "Key %d - Found too many records; Can't continue",
+ sort_param->key+1);
DBUG_RETURN(1);
}
- (void) _mi_make_key(info,sort_info->key,(uchar*)key,sort_info->record,
- sort_info->filepos);
- DBUG_RETURN(sort_write_record(sort_info));
+ sort_param->real_key_length=
+ (info->s->rec_reflength+
+ _mi_make_key(info, sort_param->key, (uchar*) key,
+ sort_param->record, sort_param->filepos));
+#ifdef HAVE_purify
+ bzero(key+sort_param->real_key_length,
+ (sort_param->key_length-sort_param->real_key_length));
+#endif
+ DBUG_RETURN(sort_write_record(sort_param));
} /* sort_key_read */
+static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key)
+{
+ int error;
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_INFO *info=sort_info->info;
+ FT_WORD *wptr=0;
+ DBUG_ENTER("sort_ft_key_read");
+
+ if (!sort_param->wordlist)
+ {
+ do
+ {
+ my_free((char*) wptr, MYF(MY_ALLOW_ZERO_PTR));
+ if ((error=sort_get_next_record(sort_param)))
+ DBUG_RETURN(error);
+ if (!(wptr=_mi_ft_parserecord(info,sort_param->key,
+ key,sort_param->record)))
+ DBUG_RETURN(1);
+ error=sort_write_record(sort_param);
+ }
+ while (!wptr->pos);
+ sort_param->wordptr=sort_param->wordlist=wptr;
+ }
+ else
+ {
+ error=0;
+ wptr=(FT_WORD*)(sort_param->wordptr);
+ }
+
+ sort_param->real_key_length=(info->s->rec_reflength+
+ _ft_make_key(info, sort_param->key,
+ key, wptr++, sort_param->filepos));
+#ifdef HAVE_purify
+ if (sort_param->key_length > sort_param->real_key_length)
+ bzero(key+sort_param->real_key_length,
+ (sort_param->key_length-sort_param->real_key_length));
+#endif
+ if (!wptr->pos)
+ {
+ my_free((char*) sort_param->wordlist, MYF(0));
+ sort_param->wordlist=0;
+ }
+ else
+ sort_param->wordptr=(void*)wptr;
+
+ DBUG_RETURN(error);
+} /* sort_ft_key_read */
+
+
/* Read next record from file using parameters in sort_info */
/* Return -1 if end of file, 0 if ok and > 0 if error */
-static int sort_get_next_record(SORT_INFO *sort_info)
+static int sort_get_next_record(MI_SORT_PARAM *sort_param)
{
int searching;
uint found_record,b_type,left_length;
my_off_t pos;
byte *to;
MI_BLOCK_INFO block_info;
- MI_INFO *info;
- MYISAM_SHARE *share;
+ SORT_INFO *sort_info=sort_param->sort_info;
MI_CHECK *param=sort_info->param;
+ MI_INFO *info=sort_info->info;
+ MYISAM_SHARE *share=info->s;
char llbuff[22],llbuff2[22];
DBUG_ENTER("sort_get_next_record");
- info=sort_info->info;
- share=info->s;
switch (share->data_file_type) {
case STATIC_RECORD:
for (;;)
{
- if (my_b_read(&param->read_cache,sort_info->record,
+ if (my_b_read(&sort_param->read_cache,sort_param->record,
share->base.pack_reclength))
{
- if (param->read_cache.error)
+ if (sort_param->read_cache.error)
param->out_flag |= O_DATA_LOST;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(-1);
}
- sort_info->start_recpos=sort_info->pos;
- if (!sort_info->fix_datafile)
- sort_info->filepos=sort_info->pos;
- sort_info->max_pos=(sort_info->pos+=share->base.pack_reclength);
- share->state.split++;
- if (*sort_info->record)
+ sort_param->start_recpos=sort_param->pos;
+ if (!sort_param->fix_datafile)
+ {
+ sort_param->filepos=sort_param->pos;
+ if (sort_param->master)
+ share->state.split++;
+ }
+ sort_param->max_pos=(sort_param->pos+=share->base.pack_reclength);
+ if (*sort_param->record)
{
if (param->calc_checksum)
param->glob_crc+= (info->checksum=
- mi_static_checksum(info,sort_info->record));
+ mi_static_checksum(info,sort_param->record));
DBUG_RETURN(0);
}
- if (!sort_info->fix_datafile)
+ if (!sort_param->fix_datafile && sort_param->master)
{
info->state->del++;
info->state->empty+=share->base.pack_reclength;
@@ -2137,8 +2620,8 @@ static int sort_get_next_record(SORT_INFO *sort_info)
}
case DYNAMIC_RECORD:
LINT_INIT(to);
- pos=sort_info->pos;
- searching=(sort_info->fix_datafile && (param->testflag & T_EXTEND));
+ pos=sort_param->pos;
+ searching=(sort_param->fix_datafile && (param->testflag & T_EXTEND));
for (;;)
{
found_record=block_info.second_read= 0;
@@ -2146,13 +2629,13 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (searching)
{
pos=MY_ALIGN(pos,MI_DYN_ALIGN_SIZE);
- param->retry_without_quick=1;
- sort_info->start_recpos=pos;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
+ sort_param->start_recpos=pos;
}
do
{
- if (pos > sort_info->max_pos)
- sort_info->max_pos=pos;
+ if (pos > sort_param->max_pos)
+ sort_param->max_pos=pos;
if (pos & (MI_DYN_ALIGN_SIZE-1))
{
if ((param->testflag & T_VERBOSE) || searching == 0)
@@ -2164,8 +2647,9 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (found_record && pos == param->search_after_block)
mi_check_print_info(param,"Block: %s used by record at %s",
llstr(param->search_after_block,llbuff),
- llstr(sort_info->start_recpos,llbuff2));
- if (_mi_read_cache(&param->read_cache,(byte*) block_info.header,pos,
+ llstr(sort_param->start_recpos,llbuff2));
+ if (_mi_read_cache(&sort_param->read_cache,
+ (byte*) block_info.header,pos,
MI_BLOCK_INFO_HEADER_LENGTH,
(! found_record ? READING_NEXT : 0) |
READING_HEADER))
@@ -2174,20 +2658,21 @@ static int sort_get_next_record(SORT_INFO *sort_info)
{
mi_check_print_info(param,
"Can't read whole record at %s (errno: %d)",
- llstr(sort_info->start_recpos,llbuff),errno);
+ llstr(sort_param->start_recpos,llbuff),errno);
goto try_next;
}
DBUG_RETURN(-1);
}
- if (searching && ! sort_info->fix_datafile)
+ if (searching && ! sort_param->fix_datafile)
{
param->error_printed=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1); /* Something wrong with data */
}
- if (((b_type=_mi_get_block_info(&block_info,-1,pos)) &
- (BLOCK_ERROR | BLOCK_FATAL_ERROR)) ||
- ((b_type & BLOCK_FIRST) &&
+ b_type=_mi_get_block_info(&block_info,-1,pos);
+ if ((b_type & (BLOCK_ERROR | BLOCK_FATAL_ERROR)) ||
+ ((b_type & BLOCK_FIRST) &&
(block_info.rec_len < (uint) share->base.min_pack_length ||
block_info.rec_len > (uint) share->base.max_pack_length)))
{
@@ -2209,7 +2694,7 @@ static int sort_get_next_record(SORT_INFO *sort_info)
block_info.header[i] <= MI_MAX_DYN_HEADER_BYTE)
break;
pos+=(ulong) i;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
continue;
}
if (b_type & BLOCK_DELETED)
@@ -2245,7 +2730,7 @@ static int sort_get_next_record(SORT_INFO *sort_info)
goto try_next;
searching=1;
pos+= MI_DYN_ALIGN_SIZE;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
block_info.second_read=0;
continue;
}
@@ -2266,14 +2751,15 @@ static int sort_get_next_record(SORT_INFO *sort_info)
goto try_next;
searching=1;
pos+= MI_DYN_ALIGN_SIZE;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
block_info.second_read=0;
continue;
}
}
if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
{
- if (!sort_info->fix_datafile && (b_type & BLOCK_DELETED))
+ if (!sort_param->fix_datafile && sort_param->master &&
+ (b_type & BLOCK_DELETED))
{
info->state->empty+=block_info.block_len;
info->state->del++;
@@ -2284,7 +2770,7 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (searching)
{
pos+=MI_DYN_ALIGN_SIZE;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
}
else
pos=block_info.filepos+block_info.block_len;
@@ -2292,43 +2778,46 @@ static int sort_get_next_record(SORT_INFO *sort_info)
continue;
}
- share->state.split++;
+ if (!sort_param->fix_datafile && sort_param->master)
+ share->state.split++;
if (! found_record++)
{
- sort_info->find_length=left_length=block_info.rec_len;
- sort_info->start_recpos=pos;
- if (!sort_info->fix_datafile)
- sort_info->filepos=sort_info->start_recpos;
- if (sort_info->fix_datafile && (param->testflag & T_EXTEND))
- sort_info->pos=block_info.filepos+1;
+ sort_param->find_length=left_length=block_info.rec_len;
+ sort_param->start_recpos=pos;
+ if (!sort_param->fix_datafile)
+ sort_param->filepos=sort_param->start_recpos;
+ if (sort_param->fix_datafile && (param->testflag & T_EXTEND))
+ sort_param->pos=block_info.filepos+1;
else
- sort_info->pos=block_info.filepos+block_info.block_len;
+ sort_param->pos=block_info.filepos+block_info.block_len;
if (share->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to=mi_alloc_rec_buff(info,block_info.rec_len,
+ &(sort_param->rec_buff),
+ &(sort_param->alloced_rec_buff_length))))
{
mi_check_print_error(param,"Not enough memory for blob at %s",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
DBUG_RETURN(1);
}
}
else
- to= info->rec_buff;
+ to= sort_param->rec_buff;
}
if (left_length < block_info.data_len || ! block_info.data_len)
{
mi_check_print_info(param,"Found block with too small length at %s; Skipped",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
if (block_info.filepos + block_info.data_len >
- param->read_cache.end_of_file)
+ sort_param->read_cache.end_of_file)
{
mi_check_print_info(param,"Found block that points outside data file at %s",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
- if (_mi_read_cache(&param->read_cache,to,block_info.filepos,
+ if (_mi_read_cache(&sort_param->read_cache,to,block_info.filepos,
block_info.data_len,
(found_record == 1 ? READING_NEXT : 0)))
{
@@ -2343,31 +2832,31 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (pos == HA_OFFSET_ERROR && left_length)
{
mi_check_print_info(param,"Wrong block with wrong total length starting at %s",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
- if (pos + MI_BLOCK_INFO_HEADER_LENGTH > param->read_cache.end_of_file)
+ if (pos + MI_BLOCK_INFO_HEADER_LENGTH > sort_param->read_cache.end_of_file)
{
mi_check_print_info(param,"Found link that points at %s (outside data file) at %s",
llstr(pos,llbuff2),
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
} while (left_length);
- if (_mi_rec_unpack(info,sort_info->record,info->rec_buff,
- sort_info->find_length) != MY_FILE_ERROR)
+ if (_mi_rec_unpack(info,sort_param->record,sort_param->rec_buff,
+ sort_param->find_length) != MY_FILE_ERROR)
{
- if (param->read_cache.error < 0)
+ if (sort_param->read_cache.error < 0)
DBUG_RETURN(1);
if (info->s->calc_checksum)
- info->checksum=mi_checksum(info,sort_info->record);
+ info->checksum=mi_checksum(info,sort_param->record);
if ((param->testflag & (T_EXTEND | T_REP)) || searching)
{
- if (_mi_rec_check(info, sort_info->record))
+ if (_mi_rec_check(info, sort_param->record, sort_param->rec_buff))
{
mi_check_print_info(param,"Found wrong packed record at %s",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
}
@@ -2376,31 +2865,33 @@ static int sort_get_next_record(SORT_INFO *sort_info)
DBUG_RETURN(0);
}
if (!searching)
- mi_check_print_info(param,"Found wrong stored record at %s",
- llstr(sort_info->start_recpos,llbuff));
+ mi_check_print_info(param,"Key %d - Found wrong stored record at %s",
+ sort_param->key+1,
+ llstr(sort_param->start_recpos,llbuff));
try_next:
- pos=(sort_info->start_recpos+=MI_DYN_ALIGN_SIZE);
+ pos=(sort_param->start_recpos+=MI_DYN_ALIGN_SIZE);
searching=1;
}
case COMPRESSED_RECORD:
- for (searching=0 ;; searching=1, sort_info->pos++)
+ for (searching=0 ;; searching=1, sort_param->pos++)
{
- if (_mi_read_cache(&param->read_cache,(byte*) block_info.header,
- sort_info->pos,
+ if (_mi_read_cache(&sort_param->read_cache,(byte*) block_info.header,
+ sort_param->pos,
share->pack.ref_length,READING_NEXT))
DBUG_RETURN(-1);
- if (searching && ! sort_info->fix_datafile)
+ if (searching && ! sort_param->fix_datafile)
{
param->error_printed=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1); /* Something wrong with data */
}
- sort_info->start_recpos=sort_info->pos;
- if (_mi_pack_get_block_info(info,&block_info,-1,sort_info->pos, NullS))
+ sort_param->start_recpos=sort_param->pos;
+ if (_mi_pack_get_block_info(info,&block_info,-1,sort_param->pos, NullS))
DBUG_RETURN(-1);
if (!block_info.rec_len &&
- sort_info->pos + MEMMAP_EXTRA_MARGIN ==
- param->read_cache.end_of_file)
+ sort_param->pos + MEMMAP_EXTRA_MARGIN ==
+ sort_param->read_cache.end_of_file)
DBUG_RETURN(-1);
if (block_info.rec_len < (uint) share->min_pack_length ||
block_info.rec_len > (uint) share->max_pack_length)
@@ -2408,32 +2899,35 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (! searching)
mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
block_info.rec_len,
- llstr(sort_info->pos,llbuff));
+ llstr(sort_param->pos,llbuff));
continue;
}
- if (_mi_read_cache(&param->read_cache,(byte*) info->rec_buff,
+ if (_mi_read_cache(&sort_param->read_cache,(byte*) sort_param->rec_buff,
block_info.filepos, block_info.rec_len,
READING_NEXT))
{
if (! searching)
mi_check_print_info(param,"Couldn't read whole record from %s",
- llstr(sort_info->pos,llbuff));
+ llstr(sort_param->pos,llbuff));
continue;
}
- if (_mi_pack_rec_unpack(info,sort_info->record,info->rec_buff,
+ if (_mi_pack_rec_unpack(info,sort_param->record,sort_param->rec_buff,
block_info.rec_len))
{
if (! searching)
mi_check_print_info(param,"Found wrong record at %s",
- llstr(sort_info->pos,llbuff));
+ llstr(sort_param->pos,llbuff));
continue;
}
- info->checksum=mi_checksum(info,sort_info->record);
- if (!sort_info->fix_datafile)
- sort_info->filepos=sort_info->pos;
- sort_info->max_pos=(sort_info->pos=block_info.filepos+
+ info->checksum=mi_checksum(info,sort_param->record);
+ if (!sort_param->fix_datafile)
+ {
+ sort_param->filepos=sort_param->pos;
+ if (sort_param->master)
+ share->state.split++;
+ }
+ sort_param->max_pos=(sort_param->pos=block_info.filepos+
block_info.rec_len);
- share->state.split++;
info->packed_length=block_info.rec_len;
if (param->calc_checksum)
param->glob_crc+= info->checksum;
@@ -2446,7 +2940,7 @@ static int sort_get_next_record(SORT_INFO *sort_info)
/* Write record to new file */
-int sort_write_record(SORT_INFO *sort_info)
+int sort_write_record(MI_SORT_PARAM *sort_param)
{
int flag;
uint length;
@@ -2454,33 +2948,35 @@ int sort_write_record(SORT_INFO *sort_info)
byte *from;
byte block_buff[8];
MI_INFO *info;
+ SORT_INFO *sort_info=sort_param->sort_info;
MYISAM_SHARE *share;
MI_CHECK *param=sort_info->param;
DBUG_ENTER("sort_write_record");
info=sort_info->info;
share=info->s;
- if (sort_info->fix_datafile)
+ if (sort_param->fix_datafile)
{
switch (sort_info->new_data_file_type) {
case STATIC_RECORD:
- if (my_b_write(&info->rec_cache,sort_info->record,
+ if (my_b_write(&info->rec_cache,sort_param->record,
share->base.pack_reclength))
{
mi_check_print_error(param,"%d when writing to datafile",my_errno);
DBUG_RETURN(1);
}
- sort_info->filepos+=share->base.pack_reclength;
- /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_info->record); */
+ sort_param->filepos+=share->base.pack_reclength;
+ info->s->state.split++;
+ /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_param->record); */
break;
case DYNAMIC_RECORD:
if (! info->blobs)
- from=info->rec_buff;
+ from=sort_param->rec_buff;
else
{
/* must be sure that local buffer is big enough */
reclength=info->s->base.pack_reclength+
- _my_calc_total_blob_length(info,sort_info->record)+
+ _my_calc_total_blob_length(info,sort_param->record)+
ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
MI_DYN_DELETE_BLOCK_HEADER;
if (sort_info->buff_length < reclength)
@@ -2493,22 +2989,30 @@ int sort_write_record(SORT_INFO *sort_info)
}
from=sort_info->buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
}
- info->checksum=mi_checksum(info,sort_info->record);
- reclength=_mi_rec_pack(info,from,sort_info->record);
- /* sort_info->param->glob_crc+=info->checksum; */
- block_length=reclength+ 3 + test(reclength >= (65520-3));
- if (block_length < share->base.min_block_length)
- block_length=share->base.min_block_length;
+ info->checksum=mi_checksum(info,sort_param->record);
+ reclength=_mi_rec_pack(info,from,sort_param->record);
flag=0;
- info->update|=HA_STATE_WRITE_AT_END;
- block_length=MY_ALIGN(block_length,MI_DYN_ALIGN_SIZE);
- if (_mi_write_part_record(info,0L,block_length,HA_OFFSET_ERROR,
- &from,&reclength,&flag))
+ /* sort_info->param->glob_crc+=info->checksum; */
+
+ do
{
- mi_check_print_error(param,"%d when writing to datafile",my_errno);
- DBUG_RETURN(1);
- }
- sort_info->filepos+=block_length;
+ block_length=reclength+ 3 + test(reclength >= (65520-3));
+ if (block_length < share->base.min_block_length)
+ block_length=share->base.min_block_length;
+ info->update|=HA_STATE_WRITE_AT_END;
+ block_length=MY_ALIGN(block_length,MI_DYN_ALIGN_SIZE);
+ if (block_length > MI_MAX_BLOCK_LENGTH)
+ block_length=MI_MAX_BLOCK_LENGTH;
+ if (_mi_write_part_record(info,0L,block_length,
+ sort_param->filepos+block_length,
+ &from,&reclength,&flag))
+ {
+ mi_check_print_error(param,"%d when writing to datafile",my_errno);
+ DBUG_RETURN(1);
+ }
+ sort_param->filepos+=block_length;
+ info->s->state.split++;
+ } while (reclength);
/* sort_info->param->glob_crc+=info->checksum; */
break;
case COMPRESSED_RECORD:
@@ -2517,22 +3021,26 @@ int sort_write_record(SORT_INFO *sort_info)
if (info->s->base.blobs)
length+=save_pack_length(block_buff+length,info->blob_length);
if (my_b_write(&info->rec_cache,block_buff,length) ||
- my_b_write(&info->rec_cache,(byte*) info->rec_buff,reclength))
+ my_b_write(&info->rec_cache,(byte*) sort_param->rec_buff,reclength))
{
mi_check_print_error(param,"%d when writing to datafile",my_errno);
DBUG_RETURN(1);
}
/* sort_info->param->glob_crc+=info->checksum; */
- sort_info->filepos+=reclength+length;
+ sort_param->filepos+=reclength+length;
+ info->s->state.split++;
break;
}
}
- info->state->records++;
- if ((param->testflag & T_WRITE_LOOP) &&
- (info->state->records % WRITE_COUNT) == 0)
+ if (sort_param->master)
{
- char llbuff[22];
- printf("%s\r", llstr(info->state->records,llbuff)); VOID(fflush(stdout));
+ info->state->records++;
+ if ((param->testflag & T_WRITE_LOOP) &&
+ (info->state->records % WRITE_COUNT) == 0)
+ {
+ char llbuff[22];
+ printf("%s\r", llstr(info->state->records,llbuff)); VOID(fflush(stdout));
+ }
}
DBUG_RETURN(0);
} /* sort_write_record */
@@ -2540,49 +3048,49 @@ int sort_write_record(SORT_INFO *sort_info)
/* Compare two keys from _create_index_by_sort */
-static int sort_key_cmp(SORT_INFO *sort_info, const void *a, const void *b)
+static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
+ const void *b)
{
uint not_used;
- return (_mi_key_cmp(sort_info->keyseg,*((uchar**) a),*((uchar**) b),
+ return (_mi_key_cmp(sort_param->keyinfo->seg,*((uchar**) a),*((uchar**) b),
USE_WHOLE_KEY, SEARCH_SAME,&not_used));
} /* sort_key_cmp */
-static int sort_key_write(SORT_INFO *sort_info, const void *a)
+static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
{
uint diff_pos;
char llbuff[22],llbuff2[22];
+ SORT_INFO *sort_info=sort_param->sort_info;
MI_CHECK *param= sort_info->param;
int cmp;
if (sort_info->key_block->inited)
{
- cmp=_mi_key_cmp(sort_info->keyseg,sort_info->key_block->lastkey,(uchar*) a,
- USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE ,&diff_pos);
- sort_info->unique[diff_pos-1]++;
+ cmp=_mi_key_cmp(sort_param->keyinfo->seg, sort_info->key_block->lastkey,
+ (uchar*) a, USE_WHOLE_KEY, SEARCH_FIND | SEARCH_UPDATE,
+ &diff_pos);
+ sort_param->unique[diff_pos-1]++;
}
else
{
cmp= -1;
}
- if ((sort_info->keyinfo->flag & HA_NOSAME) && cmp == 0)
+ if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
{
sort_info->dupp++;
sort_info->info->lastpos=get_record_for_key(sort_info->info,
- sort_info->keyinfo,
+ sort_param->keyinfo,
(uchar*) a);
mi_check_print_warning(param,
- "Duplicate key for record at %10s against record at %10s",
- llstr(sort_info->info->lastpos,llbuff),
- llstr(get_record_for_key(sort_info->info,
- sort_info->keyinfo,
- sort_info->key_block->
- lastkey),
- llbuff2));
- param->retry_without_quick=1;
+ "Duplicate key for record at %10s against record at %10s",
+ llstr(sort_info->info->lastpos,llbuff),
+ llstr(get_record_for_key(sort_info->info, sort_param->keyinfo,
+ sort_info->key_block->lastkey), llbuff2));
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
if (sort_info->param->testflag & T_VERBOSE)
- _mi_print_key(stdout,sort_info->keyseg,(uchar*) a, USE_WHOLE_KEY);
- return (sort_delete_record(param));
+ _mi_print_key(stdout,sort_param->keyinfo->seg,(uchar*) a, USE_WHOLE_KEY);
+ return (sort_delete_record(sort_param));
}
#ifndef DBUG_OFF
if (cmp > 0)
@@ -2592,8 +3100,8 @@ static int sort_key_write(SORT_INFO *sort_info, const void *a)
return(1);
}
#endif
- return (sort_insert_key(param,sort_info->key_block,(uchar*) a,
- HA_OFFSET_ERROR));
+ return (sort_insert_key(sort_param,sort_info->key_block,
+ (uchar*) a, HA_OFFSET_ERROR));
} /* sort_key_write */
@@ -2608,7 +3116,7 @@ static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
/* Insert a key in sort-key-blocks */
-static int sort_insert_key(MI_CHECK *param,
+static int sort_insert_key(MI_SORT_PARAM *sort_param,
register SORT_KEY_BLOCKS *key_block, uchar *key,
my_off_t prev_block)
{
@@ -2617,14 +3125,16 @@ static int sort_insert_key(MI_CHECK *param,
uchar *anc_buff,*lastkey;
MI_KEY_PARAM s_temp;
MI_INFO *info;
- SORT_INFO *sort_info= &param->sort_info;
+ MI_KEYDEF *keyinfo=sort_param->keyinfo;
+ SORT_INFO *sort_info= sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
DBUG_ENTER("sort_insert_key");
anc_buff=key_block->buff;
info=sort_info->info;
lastkey=key_block->lastkey;
nod_flag= (key_block == sort_info->key_block ? 0 :
- sort_info->info->s->base.key_reflength);
+ info->s->base.key_reflength);
if (!key_block->inited)
{
@@ -2645,17 +3155,16 @@ static int sort_insert_key(MI_CHECK *param,
if (nod_flag)
_mi_kpointer(info,key_block->end_pos,prev_block);
- t_length=(*sort_info->keyinfo->pack_key)(sort_info->keyinfo,nod_flag,
- (uchar*) 0,lastkey,lastkey,key,
- &s_temp);
- (*sort_info->keyinfo->store_key)(sort_info->keyinfo,
- key_block->end_pos+nod_flag,&s_temp);
+ t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
+ (uchar*) 0,lastkey,lastkey,key,
+ &s_temp);
+ (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
a_length+=t_length;
mi_putint(anc_buff,a_length,nod_flag);
key_block->end_pos+=t_length;
- if (a_length <= sort_info->keyinfo->block_length)
+ if (a_length <= keyinfo->block_length)
{
- VOID(_mi_move_key(sort_info->keyinfo,key_block->lastkey,key));
+ VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
key_block->last_length=a_length-t_length;
DBUG_RETURN(0);
}
@@ -2663,52 +3172,50 @@ static int sort_insert_key(MI_CHECK *param,
/* Fill block with end-zero and write filled block */
mi_putint(anc_buff,key_block->last_length,nod_flag);
bzero((byte*) anc_buff+key_block->last_length,
- sort_info->keyinfo->block_length- key_block->last_length);
+ keyinfo->block_length- key_block->last_length);
key_file_length=info->state->key_file_length;
- if ((filepos=_mi_new(info,sort_info->keyinfo)) == HA_OFFSET_ERROR)
+ if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
/* If we read the page from the key cache, we have to write it back to it */
if (key_file_length == info->state->key_file_length)
{
- if (_mi_write_keypage(info, sort_info->keyinfo, filepos,
- anc_buff))
+ if (_mi_write_keypage(info, keyinfo, filepos, anc_buff))
DBUG_RETURN(1);
}
else if (my_pwrite(info->s->kfile,(byte*) anc_buff,
- (uint) sort_info->keyinfo->block_length,filepos,
- param->myf_rw))
+ (uint) keyinfo->block_length,filepos, param->myf_rw))
DBUG_RETURN(1);
DBUG_DUMP("buff",(byte*) anc_buff,mi_getint(anc_buff));
/* Write separator-key to block in next level */
- if (sort_insert_key(param,key_block+1,key_block->lastkey,filepos))
+ if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
DBUG_RETURN(1);
/* clear old block and write new key in it */
key_block->inited=0;
- DBUG_RETURN(sort_insert_key(param, key_block,key,prev_block));
+ DBUG_RETURN(sort_insert_key(sort_param, key_block,key,prev_block));
} /* sort_insert_key */
/* Delete record when we found a duplicated key */
-static int sort_delete_record(MI_CHECK *param)
+static int sort_delete_record(MI_SORT_PARAM *sort_param)
{
uint i;
int old_file,error;
uchar *key;
- MI_INFO *info;
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
+ MI_INFO *info=sort_info->info;
DBUG_ENTER("sort_delete_record");
- if (param->opt_rep_quick == 1)
+ if (!(param->testflag & T_FORCE_UNIQUENESS))
{
mi_check_print_error(param,
- "Quick-recover aborted; Run recovery without switch 'q' or with switch -qq");
+ "Quick-recover aborted; Run recovery without switch -q or with switch -qq");
DBUG_RETURN(1);
}
- info=sort_info->info;
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
{
mi_check_print_error(param,
@@ -2718,10 +3225,10 @@ static int sort_delete_record(MI_CHECK *param)
old_file=info->dfile;
info->dfile=info->rec_cache.file;
- if (sort_info->key)
+ if (sort_info->current_key)
{
key=info->lastkey+info->s->base.max_key_length;
- if ((error=(*info->s->read_rnd)(info,sort_info->record,info->lastpos,0)) &&
+ if ((error=(*info->s->read_rnd)(info,sort_param->record,info->lastpos,0)) &&
error != HA_ERR_RECORD_DELETED)
{
mi_check_print_error(param,"Can't read record to be removed");
@@ -2729,9 +3236,9 @@ static int sort_delete_record(MI_CHECK *param)
DBUG_RETURN(1);
}
- for (i=0 ; i < sort_info->key ; i++)
+ for (i=0 ; i < sort_info->current_key ; i++)
{
- uint key_length=_mi_make_key(info,i,key,sort_info->record,info->lastpos);
+ uint key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
if (_mi_ck_delete(info,i,key,key_length))
{
mi_check_print_error(param,"Can't delete key %d from record to be removed",i+1);
@@ -2740,8 +3247,7 @@ static int sort_delete_record(MI_CHECK *param)
}
}
if (param->calc_checksum)
- param->glob_crc-=(*info->s->calc_checksum)(info,
- sort_info->record);
+ param->glob_crc-=(*info->s->calc_checksum)(info, sort_param->record);
}
error=flush_io_cache(&info->rec_cache) || (*info->s->delete_record)(info);
info->dfile=old_file; /* restore actual value */
@@ -2749,20 +3255,20 @@ static int sort_delete_record(MI_CHECK *param)
DBUG_RETURN(error);
} /* sort_delete_record */
-
/* Fix all pending blocks and flush everything to disk */
-static int flush_pending_blocks(MI_CHECK *param)
+int flush_pending_blocks(MI_SORT_PARAM *sort_param)
{
uint nod_flag,length;
my_off_t filepos,key_file_length;
- MI_INFO *info;
SORT_KEY_BLOCKS *key_block;
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO *sort_info= sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
+ MI_INFO *info=sort_info->info;
+ MI_KEYDEF *keyinfo=sort_param->keyinfo;
DBUG_ENTER("flush_pending_blocks");
filepos= HA_OFFSET_ERROR; /* if empty file */
- info=sort_info->info;
nod_flag=0;
for (key_block=sort_info->key_block ; key_block->inited ; key_block++)
{
@@ -2771,30 +3277,26 @@ static int flush_pending_blocks(MI_CHECK *param)
if (nod_flag)
_mi_kpointer(info,key_block->end_pos,filepos);
key_file_length=info->state->key_file_length;
- bzero((byte*) key_block->buff+length,
- sort_info->keyinfo->block_length-length);
- if ((filepos=_mi_new(info,sort_info->keyinfo)) == HA_OFFSET_ERROR)
+ bzero((byte*) key_block->buff+length, keyinfo->block_length-length);
+ if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
/* If we read the page from the key cache, we have to write it back */
if (key_file_length == info->state->key_file_length)
{
- if (_mi_write_keypage(info, sort_info->keyinfo, filepos,
- key_block->buff))
+ if (_mi_write_keypage(info, keyinfo, filepos, key_block->buff))
DBUG_RETURN(1);
}
else if (my_pwrite(info->s->kfile,(byte*) key_block->buff,
- (uint) sort_info->keyinfo->block_length,filepos,
- param->myf_rw))
+ (uint) keyinfo->block_length,filepos, param->myf_rw))
DBUG_RETURN(1);
DBUG_DUMP("buff",(byte*) key_block->buff,length);
nod_flag=1;
}
- info->s->state.key_root[sort_info->key]=filepos; /* Last is root for tree */
+ info->s->state.key_root[sort_param->key]=filepos; /* Last is root for tree */
DBUG_RETURN(0);
} /* flush_pending_blocks */
-
/* alloc space and pointers for key_blocks */
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
@@ -2846,7 +3348,6 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
MI_STATUS_INFO status_info;
uint unpack,key_parts;
ha_rows max_records;
- char name[FN_REFLEN];
ulonglong file_length,tmp_length;
MI_CREATE_INFO create_info;
@@ -2955,8 +3456,9 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
create_info.language = (param->language ? param->language :
share.state.header.language);
- if (mi_create(fn_format(name,filename,"",MI_NAME_IEXT,
- 4+ (param->opt_follow_links ? 16 : 0)),
+ /* We don't have to handle symlinks here because we are using
+ HA_DONT_TOUCH_DATA */
+ if (mi_create(filename,
share.base.keys - share.state.header.uniques,
keyinfo, share.base.fields, recdef,
share.state.header.uniques, uniquedef,
@@ -2966,7 +3468,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
mi_check_print_error(param,"Got error %d when trying to recreate indexfile",my_errno);
goto end;
}
- *org_info=mi_open(name,O_RDWR,
+ *org_info=mi_open(filename,O_RDWR,
(param->testflag & T_WAIT_FOREVER) ? HA_OPEN_WAIT_IF_LOCKED :
(param->testflag & T_DESCRIPT) ? HA_OPEN_IGNORE_IF_LOCKED :
HA_OPEN_ABORT_IF_LOCKED);
@@ -3004,24 +3506,25 @@ end:
/* write suffix to data file if neaded */
-int write_data_suffix(MI_CHECK *param, MI_INFO *info)
+int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile)
{
- if (info->s->options & HA_OPTION_COMPRESS_RECORD &&
- param->sort_info.fix_datafile)
+ MI_INFO *info=sort_info->info;
+
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
{
char buff[MEMMAP_EXTRA_MARGIN];
bzero(buff,sizeof(buff));
if (my_b_write(&info->rec_cache,buff,sizeof(buff)))
{
- mi_check_print_error(param,"%d when writing to datafile",my_errno);
+ mi_check_print_error(sort_info->param,
+ "%d when writing to datafile",my_errno);
return 1;
}
- param->read_cache.end_of_file+=sizeof(buff);
+ sort_info->param->read_cache.end_of_file+=sizeof(buff);
}
return 0;
}
-
/* Update state and myisamchk_time of indexfile */
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
@@ -3057,9 +3560,11 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
{ /* Force update of status */
int error;
uint r_locks=share->r_locks,w_locks=share->w_locks;
- share->r_locks=share->w_locks=0;
+ share->r_locks= share->w_locks= share->tot_locks= 0;
error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK);
- share->r_locks=r_locks; share->w_locks=w_locks;
+ share->r_locks=r_locks;
+ share->w_locks=w_locks;
+ share->tot_locks=r_locks+w_locks;
if (!error)
return 0;
}
@@ -3095,15 +3600,15 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
return;
}
if (!(param->testflag & T_SILENT) &&
- !(param->testflag & (T_REP | T_REP_BY_SORT)))
+ !(param->testflag & T_REP))
printf("Updating MyISAM file: %s\n", param->isam_file_name);
/* We have to use keyread here as a normal read uses info->rec_buff */
- mi_extra(info,HA_EXTRA_KEYREAD);
+ mi_extra(info,HA_EXTRA_KEYREAD,0);
if (mi_rlast(info,info->rec_buff, info->s->base.auto_key-1))
{
if (my_errno != HA_ERR_END_OF_FILE)
{
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
mi_check_print_error(param,"%d when reading last record",my_errno);
return;
}
@@ -3118,17 +3623,15 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
update_auto_increment(info,info->rec_buff);
set_if_bigger(info->s->state.auto_increment,auto_increment);
}
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
update_state_info(param, info, UPDATE_AUTO_INC);
return;
}
/* calculate unique keys for each part key */
-static void update_key_parts(MI_KEYDEF *keyinfo,
- ulong *rec_per_key_part,
- ulonglong *unique,
- ulonglong records)
+void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
+ ulonglong *unique, ulonglong records)
{
ulonglong count=0,tmp;
uint parts;
@@ -3203,31 +3706,22 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
even if the temporary file would be quite big!
*/
-my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
- ulonglong key_map,
- my_bool force)
+my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
+ ulonglong key_map, my_bool force)
{
MYISAM_SHARE *share=info->s;
MI_KEYDEF *key=share->keyinfo;
uint i;
/*
- repair_by_sort only works if we have at least one key. If we don't
+ mi_repair_by_sort only works if we have at least one key. If we don't
have any keys, we should use the normal repair.
*/
if (!key_map)
return FALSE; /* Can't use sort */
for (i=0 ; i < share->base.keys ; i++,key++)
{
-/* It's to disable repair_by_sort for ft-keys.
- Another solution would be to make ft-keys just too_big_key_for_sort,
- but then they won't be disabled by dectivate_non_unique_index
- and so they will be created at the first stage. As ft-key creation
- is very time-consuming process, it's better to leave it to repair stage
- but this repair shouldn't be repair_by_sort (serg)
- */
- if ((!force && mi_too_big_key_for_sort(key,rows)) ||
- (key->flag & HA_FULLTEXT))
+ if (!force && mi_too_big_key_for_sort(key,rows))
return FALSE;
}
return TRUE;
@@ -3235,10 +3729,10 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
static void
-set_data_file_type(MI_CHECK *param, SORT_INFO *sort_info, MYISAM_SHARE *share)
+set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share)
{
if ((sort_info->new_data_file_type=share->data_file_type) ==
- COMPRESSED_RECORD && param->testflag & T_UNPACK)
+ COMPRESSED_RECORD && sort_info->param->testflag & T_UNPACK)
{
MYISAM_SHARE tmp;
diff --git a/myisam/mi_checksum.c b/myisam/mi_checksum.c
index 9dabe55e239..a760b03a032 100644
--- a/myisam/mi_checksum.c
+++ b/myisam/mi_checksum.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_close.c b/myisam/mi_close.c
index f30119144bc..dbaaebb1143 100644
--- a/myisam/mi_close.c
+++ b/myisam/mi_close.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -29,8 +29,7 @@ int mi_close(register MI_INFO *info)
MYISAM_SHARE *share=info->s;
DBUG_ENTER("mi_close");
DBUG_PRINT("enter",("base: %lx reopen: %u locks: %u",
- info,(uint) share->reopen,
- (uint) (share->w_locks+share->r_locks)));
+ info,(uint) share->reopen, (uint) share->tot_locks));
pthread_mutex_lock(&THR_LOCK_myisam);
if (info->lock_type == F_EXTRA_LCK)
@@ -47,7 +46,10 @@ int mi_close(register MI_INFO *info)
pthread_mutex_lock(&share->intern_lock);
if (share->options & HA_OPTION_READ_ONLY_DATA)
+ {
share->r_locks--;
+ share->tot_locks--;
+ }
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
if (end_io_cache(&info->rec_cache))
@@ -58,6 +60,7 @@ int mi_close(register MI_INFO *info)
myisam_open_list=list_delete(myisam_open_list,&info->open_list);
pthread_mutex_unlock(&share->intern_lock);
+ my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
if (flag)
{
if (share->kfile >= 0 &&
@@ -99,7 +102,6 @@ int mi_close(register MI_INFO *info)
error = my_errno;
myisam_log_command(MI_LOG_CLOSE,info,NULL,0,error);
- my_free((gptr) info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) info,MYF(0));
if (error)
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index 7abf274d621..c87607ee5b6 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -38,12 +38,13 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
register uint i,j;
File dfile,file;
int errpos,save_errno;
+ myf create_flag;
uint fields,length,max_key_length,packed,pointer,
key_length,info_length,key_segs,options,min_key_length_skipp,
base_pos,varchar_count,long_varchar_count,varchar_length,
max_key_block_length,unique_key_parts,offset;
ulong reclength, real_reclength,min_pack_length;
- char buff[FN_REFLEN];
+ char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
ulong pack_reclength;
ulonglong tot_length,max_rows;
enum en_fieldtype type;
@@ -118,8 +119,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
pack_reclength+=(1 << ((rec->length-mi_portable_sizeof_char_ptr)*8)); /* Max blob length */
}
}
- else if (type == FIELD_SKIPP_PRESPACE ||
- type == FIELD_SKIPP_ENDSPACE)
+ else if (type == FIELD_SKIP_PRESPACE ||
+ type == FIELD_SKIP_ENDSPACE)
{
if (pack_reclength != INT_MAX32)
pack_reclength+= rec->length > 255 ? 2 : 1;
@@ -137,7 +138,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
pack_reclength+=2;
}
}
- else if (type != FIELD_SKIPP_ZERO)
+ else if (type != FIELD_SKIP_ZERO)
{
min_pack_length+=rec->length;
packed--; /* Not a pack record type */
@@ -151,7 +152,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
while (rec != recinfo)
{
rec--;
- if (rec->type == (int) FIELD_SKIPP_ZERO && rec->length == 1)
+ if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1)
{
rec->type=(int) FIELD_NORMAL;
packed--;
@@ -163,6 +164,9 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (packed || (flags & HA_PACK_RECORD))
options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
+ /* We can't use checksum with static length rows */
+ if (!(options & HA_OPTION_PACK_RECORD))
+ options&= ~HA_OPTION_CHECKSUM;
if (options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
min_pack_length+=varchar_count; /* Min length to pack */
else
@@ -223,8 +227,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.key_del=key_del;
if (uniques)
{
- max_key_block_length= MI_KEY_BLOCK_LENGTH;
- max_key_length= MI_UNIQUE_HASH_LENGTH;
+ max_key_block_length= myisam_block_size;
+ max_key_length= MI_UNIQUE_HASH_LENGTH;
}
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
@@ -366,7 +370,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.rec_per_key_part[key_segs-1]=1L;
length+=key_length;
keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE);
- if (keydef->block_length/MI_KEY_BLOCK_LENGTH > MI_MAX_KEY_BLOCK_SIZE)
+ if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH)
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
@@ -382,7 +386,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
(length*2)))*
(ulong) keydef->block_length;
}
- for (i=max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; )
+ for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
key_del[i]=HA_OFFSET_ERROR;
unique_key_parts=0;
@@ -392,12 +396,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
uniquedef->key=keys+i;
unique_key_parts+=uniquedef->keysegs;
share.state.key_root[keys+i]= HA_OFFSET_ERROR;
+ tot_length+= (max_rows/(ulong) (((uint) myisam_block_size-5)/
+ ((MI_UNIQUE_HASH_LENGTH + pointer)*2)))*
+ (ulong) myisam_block_size;
}
keys+=uniques; /* Each unique has 1 key */
key_segs+=uniques; /* Each unique has 1 key seg */
base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
- max_key_block_length/MI_KEY_BLOCK_LENGTH*MI_STATE_KEYBLOCK_SIZE+
+ max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH*
+ MI_STATE_KEYBLOCK_SIZE+
key_segs*MI_STATE_KEYSEG_SIZE);
info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
keys * MI_KEYDEF_SIZE+
@@ -416,7 +424,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
mi_int2store(share.state.header.base_pos,base_pos);
share.state.header.language= (ci->language ?
ci->language : MY_CHARSET_CURRENT);
- share.state.header.max_block_size=max_key_block_length/MI_KEY_BLOCK_LENGTH;
+ share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid();
@@ -429,7 +437,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.base.rec_reflength=pointer;
share.base.key_reflength=
mi_get_pointer_length((tot_length + max_key_block_length * keys *
- MI_INDEX_BLOCK_MARGIN) / MI_KEY_BLOCK_LENGTH,
+ MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH,
3);
share.base.keys= share.state.header.keys = keys;
share.state.header.uniques= uniques;
@@ -444,7 +452,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.base.records=ci->max_rows;
share.base.reloc= ci->reloc_rows;
share.base.reclength=real_reclength;
- share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);;
+ share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
share.base.max_pack_length=pack_reclength;
share.base.min_pack_length=min_pack_length;
share.base.pack_bits=packed;
@@ -468,17 +476,40 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (! (flags & HA_DONT_TOUCH_DATA))
share.state.create_time= (long) time((time_t*) 0);
- if ((file = my_create(fn_format(buff,name,"",MI_NAME_IEXT,4),0,
- O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
+ if (ci->index_file_name)
+ {
+ fn_format(filename, ci->index_file_name,"",MI_NAME_IEXT,4);
+ fn_format(linkname,name, "",MI_NAME_IEXT,4);
+ linkname_ptr=linkname;
+ /*
+ Don't create the table if the link or file exists to ensure that one
+ doesn't accidently destroy another table.
+ */
+ create_flag=0;
+ }
+ else
+ {
+ fn_format(filename,name,"",MI_NAME_IEXT,(4+ (flags & HA_DONT_TOUCH_DATA) ?
+ 32 : 0));
+ linkname_ptr=0;
+ /* Replace the current file */
+ create_flag=MY_DELETE_OLD;
+ }
+
+ if ((file= my_create_with_symlink(linkname_ptr,
+ filename,
+ 0, O_RDWR | O_TRUNC,
+ MYF(MY_WME | create_flag))) < 0)
goto err;
errpos=1;
- VOID(fn_format(buff,name,"",MI_NAME_DEXT,2+4));
+
if (!(flags & HA_DONT_TOUCH_DATA))
{
#ifdef USE_RAID
if (share.base.raid_type)
{
- if ((dfile=my_raid_create(buff,0,O_RDWR | O_TRUNC,
+ (void) fn_format(filename,name,"",MI_NAME_DEXT,2+4);
+ if ((dfile=my_raid_create(filename,0,O_RDWR | O_TRUNC,
share.base.raid_type,
share.base.raid_chunks,
share.base.raid_chunksize,
@@ -487,9 +518,26 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
}
else
#endif
- if ((dfile = my_create(buff,0,O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
- goto err;
-
+ {
+ if (ci->data_file_name)
+ {
+ fn_format(filename, ci->data_file_name,"",MI_NAME_DEXT,4);
+ fn_format(linkname, name, "",MI_NAME_DEXT,4);
+ linkname_ptr=linkname;
+ create_flag=0;
+ }
+ else
+ {
+ fn_format(filename,name,"",MI_NAME_DEXT,4);
+ linkname_ptr=0;
+ create_flag=MY_DELETE_OLD;
+ }
+ if ((dfile=
+ my_create_with_symlink(linkname_ptr, filename,
+ 0,O_RDWR | O_TRUNC,
+ MYF(MY_WME | create_flag))) < 0)
+ goto err;
+ }
errpos=3;
}
@@ -508,14 +556,14 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
/* Write key and keyseg definitions */
for (i=0 ; i < share.base.keys - uniques; i++)
{
- uint ft_segs=(keydefs[i].flag & HA_FULLTEXT) ? FT_SEGS : 0; /* SerG */
+ uint ft_segs=(keydefs[i].flag & HA_FULLTEXT) ? FT_SEGS : 0;
if (mi_keydef_write(file, &keydefs[i]))
goto err;
for (j=0 ; j < keydefs[i].keysegs-ft_segs ; j++)
if (mi_keyseg_write(file, &keydefs[i].seg[j]))
goto err;
- for (j=0 ; j < ft_segs ; j++) /* SerG */
+ for (j=0 ; j < ft_segs ; j++)
{
MI_KEYSEG seg=ft_keysegs[j];
seg.language= keydefs[i].seg[0].language;
@@ -531,11 +579,11 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
tmp_keydef.keysegs=1;
tmp_keydef.flag= HA_UNIQUE_CHECK;
- tmp_keydef.block_length= MI_KEY_BLOCK_LENGTH;
+ tmp_keydef.block_length= myisam_block_size;
tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
- tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
- tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH;
+ tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
+ tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH;
tmp_keyseg.start= offset;
offset+= MI_UNIQUE_HASH_LENGTH;
if (mi_keydef_write(file,&tmp_keydef) ||
@@ -596,20 +644,16 @@ err:
VOID(my_close(dfile,MYF(0)));
/* fall through */
case 2:
- if (! (flags & HA_DONT_TOUCH_DATA))
- {
/* QQ: Tõnu should add a call to my_raid_delete() here */
- VOID(fn_format(buff,name,"",MI_NAME_DEXT,2+4));
- my_delete(buff,MYF(0));
- }
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,2+4),
+ MYF(0));
/* fall through */
case 1:
VOID(my_close(file,MYF(0)));
if (! (flags & HA_DONT_TOUCH_DATA))
- {
- VOID(fn_format(buff,name,"",MI_NAME_IEXT,2+4));
- my_delete(buff,MYF(0));
- }
+ my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,2+4),
+ MYF(0));
}
my_free((char*) rec_per_key_part, MYF(0));
DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */
diff --git a/myisam/mi_dbug.c b/myisam/mi_dbug.c
index eda1aafecc8..482287938c0 100644
--- a/myisam/mi_dbug.c
+++ b/myisam/mi_dbug.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -162,7 +162,7 @@ my_bool check_table_is_closed(const char *name, const char *where)
{
MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s;
- if (!strcmp(share->filename,filename))
+ if (!strcmp(share->unique_file_name,filename))
{
if (share->last_version)
{
diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c
index 445e745b07d..6f94e3c4256 100644
--- a/myisam/mi_delete.c
+++ b/myisam/mi_delete.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -97,6 +97,12 @@ int mi_delete(MI_INFO *info,const byte *record)
myisam_log_command(MI_LOG_DELETE,info,(byte*) lastpos,sizeof(lastpos),0);
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
+ if (info->invalidator != 0)
+ {
+ DBUG_PRINT("info", ("invalidator... '%s' (delete)", info->filename));
+ (*info->invalidator)(info->filename);
+ info->invalidator=0;
+ }
DBUG_RETURN(0);
err:
@@ -196,7 +202,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_ENTER("d_search");
DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff));
- flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key,key_length,SEARCH_SAME,
+ flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, USE_WHOLE_KEY,
+ SEARCH_SAME,
&keypos, lastkey, &last_key);
if (flag == MI_FOUND_WRONG_KEY)
{
diff --git a/myisam/mi_delete_all.c b/myisam/mi_delete_all.c
index c3ed9455e12..82cf9e7a406 100644
--- a/myisam/mi_delete_all.c
+++ b/myisam/mi_delete_all.c
@@ -1,21 +1,21 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Remove all rows from a MyISAM table */
-/* This only clears the status information; The files are not truncated */
+/* This only clears the status information and truncates the data file */
#include "myisamdef.h"
@@ -43,13 +43,15 @@ int mi_delete_all_rows(MI_INFO *info)
info->state->empty=info->state->key_empty=0;
state->checksum=0;
- for (i=share->base.max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; )
+ for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
state->key_del[i]= HA_OFFSET_ERROR;
for (i=0 ; i < share->base.keys ; i++)
state->key_root[i]= HA_OFFSET_ERROR;
myisam_log_command(MI_LOG_DELETE_ALL,info,(byte*) 0,0,0);
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
+ if (my_chsize(info->dfile, 0, MYF(MY_WME)))
+ goto err;
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
@@ -62,4 +64,3 @@ err:
DBUG_RETURN(my_errno=save_errno);
}
} /* mi_delete */
-
diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c
index 995106160ef..6d842d7e6a4 100644
--- a/myisam/mi_delete_table.c
+++ b/myisam/mi_delete_table.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -50,12 +50,12 @@ int mi_delete_table(const char *name)
#endif /* USE_RAID */
fn_format(from,name,"",MI_NAME_IEXT,4);
- if (my_delete(from, MYF(MY_WME)))
+ if (my_delete_with_symlink(from, MYF(MY_WME)))
DBUG_RETURN(my_errno);
fn_format(from,name,"",MI_NAME_DEXT,4);
#ifdef USE_RAID
if (raid_type)
DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0);
#endif
- DBUG_RETURN(my_delete(from, MYF(MY_WME)) ? my_errno : 0);
+ DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME)) ? my_errno : 0);
}
diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c
index c9fe493744d..4ef4f80d137 100644
--- a/myisam/mi_dynrec.c
+++ b/myisam/mi_dynrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -60,15 +60,17 @@ int _mi_write_blob_record(MI_INFO *info, const byte *record)
int error;
ulong reclength,extra;
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER+1;
- reclength=info->s->base.pack_reclength+
- _my_calc_total_blob_length(info,record)+ extra;
+ extra= (ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
+ MI_DYN_DELETE_BLOCK_HEADER+1);
+ reclength= (info->s->base.pack_reclength+
+ _my_calc_total_blob_length(info,record)+ extra);
+#ifdef NOT_USED /* We now support big rows */
if (reclength > MI_DYN_MAX_ROW_LENGTH)
{
my_errno=HA_ERR_TO_BIG_ROW;
return -1;
}
+#endif
if (!(rec_buff=(byte*) my_alloca(reclength)))
{
my_errno=ENOMEM;
@@ -89,15 +91,17 @@ int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record)
int error;
ulong reclength,extra;
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER;
- reclength=info->s->base.pack_reclength+
- _my_calc_total_blob_length(info,record)+ extra;
+ extra= (ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
+ MI_DYN_DELETE_BLOCK_HEADER);
+ reclength= (info->s->base.pack_reclength+
+ _my_calc_total_blob_length(info,record)+ extra);
+#ifdef NOT_USED /* We now support big rows */
if (reclength > MI_DYN_MAX_ROW_LENGTH)
{
my_errno=HA_ERR_TO_BIG_ROW;
return -1;
}
+#endif
if (!(rec_buff=(byte*) my_alloca(reclength)))
{
my_errno=ENOMEM;
@@ -130,14 +134,14 @@ static int write_dynamic_record(MI_INFO *info, const byte *record,
DBUG_ENTER("write_dynamic_record");
flag=0;
- while (reclength)
+ do
{
if (_mi_find_writepos(info,reclength,&filepos,&length))
goto err;
if (_mi_write_part_record(info,filepos,length,info->s->state.dellink,
(byte**) &record,&reclength,&flag))
goto err;
- }
+ } while (reclength);
DBUG_RETURN(0);
err:
@@ -190,6 +194,8 @@ static int _mi_find_writepos(MI_INFO *info,
my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(-1);
}
+ if (*length > MI_MAX_BLOCK_LENGTH)
+ *length=MI_MAX_BLOCK_LENGTH;
info->state->data_file_length+= *length;
info->s->state.split++;
info->update|=HA_STATE_WRITE_AT_END;
@@ -370,19 +376,30 @@ int _mi_write_part_record(MI_INFO *info,
info->s->state.dellink : info->state->data_file_length;
if (*flag == 0) /* First block */
{
- head_length=5+8+long_block*2;
- temp[0]=5+(uchar) long_block;
- if (long_block)
+ if (*reclength > MI_MAX_BLOCK_LENGTH)
{
- mi_int3store(temp+1,*reclength);
- mi_int3store(temp+4,length-head_length);
- mi_sizestore((byte*) temp+7,next_filepos);
+ head_length= 16;
+ temp[0]=13;
+ mi_int4store(temp+1,*reclength);
+ mi_int3store(temp+5,length-head_length);
+ mi_sizestore((byte*) temp+8,next_filepos);
}
else
{
- mi_int2store(temp+1,*reclength);
- mi_int2store(temp+3,length-head_length);
- mi_sizestore((byte*) temp+5,next_filepos);
+ head_length=5+8+long_block*2;
+ temp[0]=5+(uchar) long_block;
+ if (long_block)
+ {
+ mi_int3store(temp+1,*reclength);
+ mi_int3store(temp+4,length-head_length);
+ mi_sizestore((byte*) temp+7,next_filepos);
+ }
+ else
+ {
+ mi_int2store(temp+1,*reclength);
+ mi_int2store(temp+3,length-head_length);
+ mi_sizestore((byte*) temp+5,next_filepos);
+ }
}
}
else
@@ -629,7 +646,7 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
}
blob++;
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) from,zero_string,length) == 0)
flag|=bit;
@@ -638,11 +655,11 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
memcpy((byte*) to,from,(size_t) length); to+=length;
}
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) from; end= (byte*) from + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > from && *(end-1) == ' ')
end--;
@@ -707,11 +724,11 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
/*
-** Check if a record was correctly packed. Used only by isamchk
-** Returns 0 if record is ok.
+ Check if a record was correctly packed. Used only by myisamchk
+ Returns 0 if record is ok.
*/
-my_bool _mi_rec_check(MI_INFO *info,const char *record)
+my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff)
{
uint length,new_length,flag,bit,i;
char *pos,*end,*packpos,*to;
@@ -719,7 +736,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
reg3 MI_COLUMNDEF *rec;
DBUG_ENTER("_mi_rec_check");
- packpos=info->rec_buff; to= info->rec_buff+info->s->base.pack_bits;
+ packpos=rec_buff; to= rec_buff+info->s->base.pack_bits;
rec=info->s->rec;
flag= *packpos; bit=1;
@@ -737,7 +754,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
if (blob_length)
to+=length - mi_portable_sizeof_char_ptr+ blob_length;
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) record,zero_string,length) == 0)
{
@@ -747,11 +764,11 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
else
to+=length;
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) record; end= (byte*) record + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > record && *(end-1) == ' ')
end--;
@@ -803,7 +820,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
to+=length;
}
}
- if (info->packed_length != (uint) (to - info->rec_buff)
+ if (info->packed_length != (uint) (to - rec_buff)
+ test(info->s->calc_checksum) ||
(bit != 1 && (flag & ~(bit - 1))))
goto err;
@@ -863,10 +880,10 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
}
if (flag & bit)
{
- if (type == FIELD_BLOB || type == FIELD_SKIPP_ZERO)
+ if (type == FIELD_BLOB || type == FIELD_SKIP_ZERO)
bzero((byte*) to,rec_length);
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
if (rec->length > 255 && *from & 128)
{
@@ -884,7 +901,7 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
if (length >= rec_length ||
min_pack_length + length > (uint) (from_end - from))
goto err;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{
memcpy(to,(byte*) from,(size_t) length);
bfill((byte*) to+length,rec_length-length,' ');
@@ -911,7 +928,7 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
}
else
{
- if (type == FIELD_SKIPP_ENDSPACE || type == FIELD_SKIPP_PRESPACE)
+ if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE)
min_pack_length--;
if (min_pack_length + rec_length > (uint) (from_end - from))
goto err;
@@ -1042,7 +1059,9 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
goto panic;
if (info->s->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to=mi_alloc_rec_buff(info, block_info.rec_len,
+ &info->rec_buff,
+ &info->alloced_rec_buff_length)))
goto err;
}
else
@@ -1059,11 +1078,11 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
} while (left_length);
info->update|= HA_STATE_AKTIV; /* We have a aktive record */
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
DBUG_RETURN(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
MY_FILE_ERROR ? 0 : -1);
}
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
DBUG_RETURN(-1); /* Wrong data to read */
panic:
@@ -1073,32 +1092,12 @@ err:
DBUG_RETURN(-1);
}
-
-byte *mi_fix_rec_buff_for_blob(MI_INFO *info, ulong length)
-{
- uint extra;
- if (! info->rec_buff || length > info->alloced_rec_buff_length)
- {
- byte *newptr;
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER;
- if (!(newptr=(byte*) my_realloc((gptr) info->rec_alloc,length+extra,
- MYF(MY_ALLOW_ZERO_PTR))))
- return newptr;
- info->rec_alloc=newptr;
- info->rec_buff=newptr+ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER);
- info->alloced_rec_buff_length=length;
- }
- return info->rec_buff;
-}
-
-
/* compare unique constraint between stored rows */
int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
const byte *record, my_off_t pos)
{
- byte *rec_buff,*rec_alloc,*old_record;
+ byte *rec_buff,*old_record;
uint alloced_rec_buff_length;
int error;
DBUG_ENTER("_mi_cmp_dynamic_unique");
@@ -1108,12 +1107,10 @@ int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
/* Don't let the compare destroy blobs that may be in use */
rec_buff=info->rec_buff;
- rec_alloc=info->rec_alloc;
alloced_rec_buff_length=info->alloced_rec_buff_length;
if (info->s->base.blobs)
{
info->rec_buff=0;
- info->rec_alloc=0;
info->alloced_rec_buff_length=0;
}
error=_mi_read_dynamic_record(info,pos,old_record);
@@ -1121,9 +1118,8 @@ int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
error=mi_unique_comp(def, record, old_record, def->null_are_equal);
if (info->s->base.blobs)
{
- my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
info->rec_buff=rec_buff;
- info->rec_alloc=rec_alloc;
info->alloced_rec_buff_length=alloced_rec_buff_length;
}
my_afree(old_record);
@@ -1258,7 +1254,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
if (info->lock_type == F_UNLCK)
{
#ifndef UNSAFE_LOCKING
- if (share->r_locks == 0 && share->w_locks == 0)
+ if (share->tot_locks == 0)
{
if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
@@ -1334,7 +1330,9 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
info->lastpos=filepos;
if (share->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to= mi_alloc_rec_buff(info, block_info.rec_len,
+ &info->rec_buff,
+ &info->alloced_rec_buff_length)))
goto err;
}
else
@@ -1393,8 +1391,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
} while (left_len);
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
- if (share->r_locks == 0 && share->w_locks == 0)
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
MY_FILE_ERROR)
DBUG_RETURN(0);
@@ -1429,15 +1426,15 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
DBUG_DUMP("header",(byte*) header,MI_BLOCK_INFO_HEADER_LENGTH);
if (info->second_read)
{
- if (info->header[0] <= 6)
+ if (info->header[0] <= 6 || info->header[0] == 13)
return_val=BLOCK_SYNC_ERROR;
}
else
{
- if (info->header[0] > 6)
+ if (info->header[0] > 6 && info->header[0] != 13)
return_val=BLOCK_SYNC_ERROR;
}
- info->next_filepos= HA_OFFSET_ERROR; /* Dummy ifall no next block */
+ info->next_filepos= HA_OFFSET_ERROR; /* Dummy if no next block */
switch (info->header[0]) {
case 0:
@@ -1471,6 +1468,14 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
info->filepos=filepos+4;
return return_val | BLOCK_FIRST | BLOCK_LAST;
+ case 13:
+ info->rec_len=mi_uint4korr(header+1);
+ info->block_len=info->data_len=mi_uint3korr(header+5);
+ info->next_filepos=mi_sizekorr(header+8);
+ info->second_read=1;
+ info->filepos=filepos+16;
+ return return_val | BLOCK_FIRST;
+
case 3:
info->rec_len=info->data_len=mi_uint2korr(header+1);
info->block_len=info->rec_len+ (uint) header[3];
diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c
index cf075512ac4..8ac65975a5c 100644
--- a/myisam/mi_extra.c
+++ b/myisam/mi_extra.c
@@ -1,24 +1,19 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Extra functions we want to do with a database */
-/* - Set flags for quicker databasehandler */
-/* - Set databasehandler to normal */
-/* - Reset recordpointers as after open database */
-
#include "myisamdef.h"
#ifdef HAVE_MMAP
#include <sys/mman.h>
@@ -27,13 +22,31 @@
#include <errno.h>
#endif
- /* set extra flags for database */
+/*
+ Set options and buffers to optimize table handling
+
+ SYNOPSIS
+ mi_extra()
+ info open table
+ function operation
+ extra_arg Pointer to extra argument (normally pointer to ulong)
+ Used when function is one of:
+ HA_EXTRA_WRITE_CACHE
+ HA_EXTRA_CACHE
+ HA_EXTRA_BULK_INSERT_BEGIN
+ If extra_arg is 0, then the default cache size is used.
+ RETURN VALUES
+ 0 ok
+*/
-int mi_extra(MI_INFO *info, enum ha_extra_function function)
+
+int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
int error=0;
+ ulong cache_size;
MYISAM_SHARE *share=info->s;
DBUG_ENTER("mi_extra");
+ DBUG_PRINT("enter",("function: %d",(int) function));
switch (function) {
case HA_EXTRA_RESET:
@@ -50,7 +63,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
if (info->opt_flag & MEMMAP_USED)
madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
#endif
- info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
+ info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
info->quick_mode=0;
/* Fall through */
@@ -102,11 +115,13 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
if (!(info->opt_flag &
(READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
{
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
if (!(init_io_cache(&info->rec_cache,info->dfile,
(uint) min(info->state->data_file_length+1,
- my_default_record_cache_size),
- READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
- MYF(share->write_flag & MY_WAIT_IF_FULL))))
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
{
info->opt_flag|=READ_CACHE_USED;
info->update&= ~HA_STATE_ROW_CHANGED;
@@ -132,10 +147,12 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
error=1; /* Not possibly if not locked */
break;
}
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
if (!(info->opt_flag &
(READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) &&
!share->state.header.uniques)
- if (!(init_io_cache(&info->rec_cache,info->dfile,0,
+ if (!(init_io_cache(&info->rec_cache,info->dfile, cache_size,
WRITE_CACHE,info->state->data_file_length,
(pbool) (info->lock_type != F_UNLCK),
MYF(share->write_flag & MY_WAIT_IF_FULL))))
@@ -219,9 +236,17 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
}
if (share->state.key_map)
{
- share->state.key_map=0;
- info->state->key_file_length=share->state.state.key_file_length=
- share->base.keystart;
+ MI_KEYDEF *key=share->keyinfo;
+ uint i;
+ for (i=0 ; i < share->base.keys ; i++,key++)
+ {
+ if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1)
+ {
+ share->state.key_map&= ~ ((ulonglong) 1 << i);
+ info->update|= HA_STATE_CHANGED;
+ }
+ }
+
if (!share->changed)
{
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
@@ -237,12 +262,15 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
}
break;
case HA_EXTRA_FORCE_REOPEN:
+ case HA_EXTRA_PREPARE_FOR_DELETE:
pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */
#ifdef __WIN__
/* Close the isam and data files as Win32 can't drop an open table */
pthread_mutex_lock(&share->intern_lock);
- if (flush_key_blocks(share->kfile,FLUSH_RELEASE))
+ if (flush_key_blocks(share->kfile,
+ (function == HA_EXTRA_FORCE_REOPEN ?
+ FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
{
error=my_errno;
share->changed=1;
@@ -316,11 +344,8 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
}
}
if (share->base.blobs)
- {
- my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
- info->rec_alloc=info->rec_buff=0;
- mi_fix_rec_buff_for_blob(info,info->s->base.pack_reclength);
- }
+ mi_alloc_rec_buff(info, -1, &info->rec_buff,
+ &info->alloced_rec_buff_length);
break;
case HA_EXTRA_NORMAL: /* Theese isn't in use */
info->quick_mode=0;
@@ -328,6 +353,25 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
case HA_EXTRA_QUICK:
info->quick_mode=1;
break;
+ case HA_EXTRA_BULK_INSERT_BEGIN:
+ error=_mi_init_bulk_insert(info, (extra_arg ? *(ulong*) extra_arg :
+ myisam_bulk_insert_tree_size));
+ break;
+ case HA_EXTRA_BULK_INSERT_END:
+ if (info->bulk_insert)
+ {
+ uint i;
+ for (i=0 ; i < share->base.keys ; i++)
+ {
+ if (is_tree_inited(& info->bulk_insert[i]))
+ {
+ delete_tree(& info->bulk_insert[i]);
+ }
+ }
+ my_free((void *)info->bulk_insert, MYF(0));
+ info->bulk_insert=0;
+ }
+ break;
case HA_EXTRA_NO_ROWS:
if (!share->state.header.uniques)
info->opt_flag|= OPT_NO_ROWS;
diff --git a/myisam/mi_info.c b/myisam/mi_info.c
index 6e7abfc0914..0be3cc44d80 100644
--- a/myisam/mi_info.c
+++ b/myisam/mi_info.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -45,7 +45,7 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag)
{
pthread_mutex_lock(&share->intern_lock);
VOID(_mi_readinfo(info,F_RDLCK,0));
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
pthread_mutex_unlock(&share->intern_lock);
}
if (flag & HA_STATUS_VARIABLE)
@@ -87,6 +87,8 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag)
x->raid_chunks= share->base.raid_chunks;
x->raid_chunksize= share->base.raid_chunksize;
x->key_map = share->state.key_map;
+ x->data_file_name = share->data_file_name;
+ x->index_file_name = share->index_file_name;
}
if ((flag & HA_STATUS_TIME) && !my_fstat(info->dfile,&state,MYF(0)))
x->update_time=state.st_mtime;
diff --git a/myisam/mi_key.c b/myisam/mi_key.c
index 9f4e2cb1524..3cee1f301e1 100644
--- a/myisam/mi_key.c
+++ b/myisam/mi_key.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,6 +18,9 @@
#include "myisamdef.h"
#include "m_ctype.h"
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
#define CHECK_KEYS
@@ -88,25 +91,28 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
}
else if (keyseg->flag & HA_SWAP_KEY)
{ /* Numerical column */
-#ifdef NAN_TEST
- float float_nr;
- double dbl_nr;
+#ifdef HAVE_ISNAN
if (type == HA_KEYTYPE_FLOAT)
{
- float_nr=float4get(pos);
- if (float_nr == (float) FLT_MAX)
+ float nr;
+ float4get(nr,pos);
+ if (isnan(nr))
{
- float_nr= (float) FLT_MAX;
- pos= (byte*) &float_nr;
+ /* Replace NAN with zero */
+ bzero(key,length);
+ key+=length;
+ continue;
}
}
else if (type == HA_KEYTYPE_DOUBLE)
{
- dbl_nr=float8get(key);
- if (dbl_nr == DBL_MAX)
+ double nr;
+ float8get(nr,pos);
+ if (isnan(nr))
{
- dbl_nr=DBL_MAX;
- pos=(byte*) &dbl_nr;
+ bzero(key,length);
+ key+=length;
+ continue;
}
}
#endif
@@ -244,7 +250,9 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
if (info->blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY)
{
if (!(blob_ptr=
- mi_fix_rec_buff_for_blob(info, info->s->keyinfo[keynr].keylength)))
+ mi_alloc_rec_buff(info, info->s->keyinfo[keynr].keylength,
+ &info->rec_buff,
+ &info->alloced_rec_buff_length)))
goto err;
}
key=(byte*) info->lastkey;
@@ -346,7 +354,7 @@ err:
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
{
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (filepos != HA_OFFSET_ERROR)
{
if (info->lastinx >= 0)
diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c
index de5f0d0c2cf..cbde05d31f5 100644
--- a/myisam/mi_locking.c
+++ b/myisam/mi_locking.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -43,13 +43,13 @@ int mi_lock_database(MI_INFO *info, int lock_type)
pthread_mutex_lock(&share->intern_lock);
if (share->kfile >= 0) /* May only be false on windows */
{
- switch (lock_type)
- {
+ switch (lock_type) {
case F_UNLCK:
if (info->lock_type == F_RDLCK)
count= --share->r_locks;
else
count= --share->w_locks;
+ --share->tot_locks;
if (info->lock_type == F_WRLCK && !share->w_locks &&
!share->delay_key_write && flush_key_blocks(share->kfile,FLUSH_KEEP))
{
@@ -153,6 +153,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
VOID(_mi_test_if_changed(info));
share->r_locks++;
+ share->tot_locks++;
info->lock_type=lock_type;
break;
case F_WRLCK:
@@ -199,7 +200,9 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
VOID(_mi_test_if_changed(info));
info->lock_type=lock_type;
+ info->invalidator=info->s->invalidator;
share->w_locks++;
+ share->tot_locks++;
break;
default:
break; /* Impossible */
@@ -216,7 +219,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
/****************************************************************************
-** The following functions are called by thr_lock() in threaded applications
+ The following functions are called by thr_lock() in threaded applications
****************************************************************************/
void mi_get_status(void* param)
@@ -295,13 +298,12 @@ my_bool mi_check_status(void* param)
int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
{
- MYISAM_SHARE *share;
DBUG_ENTER("_mi_readinfo");
- share=info->s;
if (info->lock_type == F_UNLCK)
{
- if (!share->r_locks && !share->w_locks)
+ MYISAM_SHARE *share=info->s;
+ if (!share->tot_locks)
{
if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
info->lock_wait | MY_SEEK_NOT_DONE))
@@ -317,6 +319,7 @@ int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
}
if (check_keybuffer)
VOID(_mi_test_if_changed(info));
+ info->invalidator=info->s->invalidator;
}
else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK)
{
@@ -338,7 +341,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
DBUG_ENTER("_mi_writeinfo");
error=0;
- if (share->r_locks == 0 && share->w_locks == 0)
+ if (share->tot_locks == 0)
{
olderror=my_errno; /* Remember last error */
if (operation)
@@ -411,11 +414,14 @@ int _mi_mark_file_changed(MI_INFO *info)
share->global_changed=1;
share->state.open_count++;
}
- mi_int2store(buff,share->state.open_count);
- buff[2]=1; /* Mark that it's changed */
- return (my_pwrite(share->kfile,buff,sizeof(buff),
- sizeof(share->state.header),
- MYF(MY_NABP)));
+ if (!share->temporary)
+ {
+ mi_int2store(buff,share->state.open_count);
+ buff[2]=1; /* Mark that it's changed */
+ return (my_pwrite(share->kfile,buff,sizeof(buff),
+ sizeof(share->state.header),
+ MYF(MY_NABP)));
+ }
}
return 0;
}
diff --git a/myisam/mi_log.c b/myisam/mi_log.c
index 5c64c130212..1dcfd5250d2 100644
--- a/myisam/mi_log.c
+++ b/myisam/mi_log.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index 617b1cd8d90..feed8f29df8 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -48,7 +48,7 @@ static MI_INFO *test_if_reopen(char *filename)
{
MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s;
- if (!strcmp(share->filename,filename) && share->last_version)
+ if (!strcmp(share->unique_file_name,filename) && share->last_version)
return info;
}
return 0;
@@ -66,9 +66,11 @@ static MI_INFO *test_if_reopen(char *filename)
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
int lock_error,kfile,open_mode,save_errno;
- uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys,
+ uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
key_parts,unique_key_parts,tmp_length,uniques;
- char name_buff[FN_REFLEN],*disk_cache,*disk_pos;
+ char name_buff[FN_REFLEN], org_name [FN_REFLEN], index_name[FN_REFLEN],
+ data_name[FN_REFLEN];
+ char *disk_cache,*disk_pos;
MI_INFO info,*m_info,*old_info;
MYISAM_SHARE share_buff,*share;
ulong rec_per_key_part[MI_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
@@ -83,7 +85,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
head_length=sizeof(share_buff.state.header);
bzero((byte*) &info,sizeof(info));
- VOID(fn_format(name_buff,name,"",MI_NAME_IEXT,4+16+32));
+ my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
pthread_mutex_lock(&THR_LOCK_myisam);
if (!(old_info=test_if_reopen(name_buff)))
{
@@ -112,7 +114,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
DBUG_PRINT("error",("Wrong header in %s",name_buff));
DBUG_DUMP("error_dump",(char*) share->state.header.file_version,
head_length);
- my_errno=HA_ERR_CRASHED;
+ my_errno=HA_ERR_WRONG_TABLE_DEF;
goto err;
}
share->options= mi_uint2korr(share->state.header.options);
@@ -127,6 +129,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno=HA_ERR_OLD_FILE;
goto err;
}
+ /* Don't call realpath() if the name can't be a link */
+ if (strcmp(name_buff, org_name))
+ (void) my_readlink(index_name, org_name, MYF(0));
+ else
+ (void) strmov(index_name, org_name);
+ (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16);
+
info_length=mi_uint2korr(share->state.header.header_length);
base_pos=mi_uint2korr(share->state.header.base_pos);
if (!(disk_cache=(char*) my_alloca(info_length)))
@@ -207,7 +216,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
(mi_safe_mul(share->base.reclength,
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
max_key_file_length=
- mi_safe_mul(MI_KEY_BLOCK_LENGTH,
+ mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
((ulonglong) 1 << (share->base.key_reflength*8))-1);
#if SIZEOF_OFF_T == 4
set_if_smaller(max_data_file_length, INT_MAX32);
@@ -249,7 +258,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
&share->rec,
(share->base.fields+1)*sizeof(MI_COLUMNDEF),
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
- &share->filename,strlen(name_buff)+1,
+ &share->unique_file_name,strlen(name_buff)+1,
+ &share->index_file_name,strlen(index_name)+1,
+ &share->data_file_name,strlen(data_name)+1,
&share->state.key_root,keys*sizeof(my_off_t),
&share->state.key_del,
(share->state.header.max_block_size*sizeof(my_off_t)),
@@ -267,7 +278,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
memcpy((char*) share->state.key_del,
(char*) key_del, (sizeof(my_off_t) *
share->state.header.max_block_size));
- strmov(share->filename,name_buff);
+ strmov(share->unique_file_name, name_buff);
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
share->blocksize=min(IO_SIZE,myisam_block_size);
{
@@ -354,7 +367,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
lock_error=1; /* Database unlocked */
}
- if (mi_open_datafile(&info, share))
+ if (mi_open_datafile(&info, share, -1))
goto err;
errpos=5;
@@ -427,7 +440,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno=EACCES; /* Can't open in write mode */
goto err;
}
- if (mi_open_datafile(&info, share))
+ if (mi_open_datafile(&info, share, old_info->dfile))
goto err;
errpos=5;
}
@@ -439,12 +452,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
&info.buff,(share->base.max_key_block_length*2+
share->base.max_key_length),
&info.lastkey,share->base.max_key_length*3+1,
- &info.filename,strlen(name)+1,
+ &info.filename,strlen(org_name)+1,
NullS))
goto err;
errpos=6;
- strmov(info.filename,name);
+ strmov(info.filename,org_name);
memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
info.lastkey2=info.lastkey+share->base.max_key_length;
@@ -462,6 +475,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->options|=HA_OPTION_READ_ONLY_DATA;
info.lock_type=F_UNLCK;
info.quick_mode=0;
+ info.bulk_insert=0;
info.errkey= -1;
info.page_changed=1;
pthread_mutex_lock(&share->intern_lock);
@@ -472,6 +486,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
info.lock_type=F_RDLCK;
share->r_locks++;
+ share->tot_locks++;
}
if ((open_flags & HA_OPEN_TMP_TABLE) ||
(share->options & HA_OPTION_TMP_TABLE))
@@ -479,6 +494,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->temporary=share->delay_key_write=1;
share->write_flag=MYF(MY_NABP);
share->w_locks++; /* We don't have to update status */
+ share->tot_locks++;
info.lock_type=F_WRLCK;
}
if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
@@ -490,20 +506,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
/* Allocate buffer for one record */
- extra=0;
- if (share->options & HA_OPTION_PACK_RECORD)
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER;
-
- tmp_length=max(share->base.pack_reclength,share->base.max_key_length);
- info.alloced_rec_buff_length=tmp_length;
- if (!(info.rec_alloc=(byte*) my_malloc(tmp_length+extra+8,
- MYF(MY_WME | MY_ZEROFILL))))
+ /* prerequisites: bzero(info) && info->s=share; are met. */
+ if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff,
+ &info.alloced_rec_buff_length))
goto err;
- if (extra)
- info.rec_buff=info.rec_alloc+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
- else
- info.rec_buff=info.rec_alloc;
+ bzero(info.rec_buff, info.alloced_rec_buff_length);
*m_info=info;
#ifdef THREAD
@@ -515,7 +522,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
pthread_mutex_unlock(&THR_LOCK_myisam);
if (myisam_log_file >= 0)
{
- intern_filename(name_buff,share->filename);
+ intern_filename(name_buff,share->index_file_name);
_myisam_log(MI_LOG_OPEN,m_info,name_buff,(uint) strlen(name_buff));
}
DBUG_RETURN(m_info);
@@ -554,6 +561,42 @@ err:
} /* mi_open */
+gptr mi_get_rec_buff_ptr(MI_INFO *info, byte *buf)
+{
+ if (info->s->options & HA_OPTION_PACK_RECORD && buf)
+ return buf - MI_REC_BUFF_OFFSET;
+ else
+ return buf;
+}
+
+
+byte *mi_alloc_rec_buff(MI_INFO *info, ulong length, byte **buf, uint *buf_len)
+{
+ uint extra;
+
+ if (! *buf || length > *buf_len)
+ {
+ byte *newptr = *buf;
+
+ /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
+ if (length == (ulong) -1)
+ length= max(info->s->base.pack_reclength,info->s->base.max_key_length);
+
+ extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
+ ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
+ MI_REC_BUFF_OFFSET : 0);
+ if (extra && newptr)
+ newptr-=MI_REC_BUFF_OFFSET;
+ if (!(newptr=(byte*) my_realloc((gptr)newptr, length+extra+8,
+ MYF(MY_ALLOW_ZERO_PTR))))
+ return 0;
+ *buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
+ *buf_len= length;
+ }
+ return *buf;
+}
+
+
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
{
ulonglong max_val= ~ (ulonglong) 0; /* my_off_t is unsigned */
@@ -626,15 +669,20 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo)
}
else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
{
- keyinfo->bin_search=_mi_seq_search;
keyinfo->get_key= _mi_get_pack_key;
if (keyinfo->seg[0].flag & HA_PACK_KEY)
{ /* Prefix compression */
+ if (!keyinfo->seg->charset || use_strcoll(keyinfo->seg->charset) ||
+ (keyinfo->seg->flag & HA_NULL_PART))
+ keyinfo->bin_search=_mi_seq_search;
+ else
+ keyinfo->bin_search=_mi_prefix_search;
keyinfo->pack_key=_mi_calc_var_pack_key_length;
keyinfo->store_key=_mi_store_var_pack_key;
}
else
{
+ keyinfo->bin_search=_mi_seq_search;
keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */
keyinfo->store_key=_mi_store_static_key;
}
@@ -773,14 +821,17 @@ uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
{
char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
- if (pRead)
+ if (!myisam_single_user)
{
- if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
+ if (pRead)
+ {
+ if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
+ return (MY_FILE_ERROR);
+ }
+ else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
return (MY_FILE_ERROR);
+ mi_state_info_read(buff, state);
}
- else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
- return (MY_FILE_ERROR);
- mi_state_info_read(buff, state);
return 0;
}
@@ -892,7 +943,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
keydef->keylength = mi_uint2korr(ptr); ptr +=2;
keydef->minlength = mi_uint2korr(ptr); ptr +=2;
keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
- keydef->block_size = keydef->block_length/MI_KEY_BLOCK_LENGTH-1;
+ keydef->block_size = keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
keydef->underflow_block_length=keydef->block_length/3;
keydef->version = 0; /* Not saved */
return ptr;
@@ -988,37 +1039,37 @@ char *mi_recinfo_read(char *ptr, MI_COLUMNDEF *recinfo)
}
/**************************************************************************
- ** Help functions for recover
- *************************************************************************/
+Open data file with or without RAID
+We can't use dup() here as the data file descriptors need to have different
+active seek-positions.
-int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share)
-{
- char name_buff[FN_REFLEN];
- (void) fn_format(name_buff, share->filename,"",MI_NAME_DEXT, 2+4);
+The argument file_to_dup is here for the future if there would on some OS
+exist a dup()-like call that would give us two different file descriptors.
+*************************************************************************/
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attribute__((unused)))
+{
#ifdef USE_RAID
if (share->base.raid_type)
{
- if ((info->dfile=my_raid_open(name_buff,
- share->mode | O_SHARE,
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize,
- MYF(MY_WME | MY_RAID))) < 0)
- return 1;
+ info->dfile=my_raid_open(share->data_file_name,
+ share->mode | O_SHARE,
+ share->base.raid_type,
+ share->base.raid_chunks,
+ share->base.raid_chunksize,
+ MYF(MY_WME | MY_RAID));
}
else
#endif
- if ((info->dfile=my_open(name_buff, share->mode | O_SHARE,
- MYF(MY_WME))) < 0)
- return 1;
- return 0;
+ info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
+ MYF(MY_WME));
+ return info->dfile >= 0 ? 0 : 1;
}
int mi_open_keyfile(MYISAM_SHARE *share)
{
- if ((share->kfile=my_open(share->filename, share->mode | O_SHARE,
+ if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
MYF(MY_WME))) < 0)
return 1;
return 0;
diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c
index 242883a2c4a..07abde07644 100644
--- a/myisam/mi_packrec.c
+++ b/myisam/mi_packrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -465,7 +465,7 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec))
(MI_COLUMNDEF *, MI_BIT_BUFF *, uchar *, uchar *)
{
switch (rec->base_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_skipp_zero;
return &uf_skipp_zero;
@@ -475,7 +475,7 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec))
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_normal;
return &decode_bytes;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
@@ -485,7 +485,7 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec))
if (rec->pack_type & PACK_TYPE_SELECTED)
return &uf_endspace_selected;
return &uf_endspace;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
@@ -1057,7 +1057,9 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file,
info->blob_len=uint3korr(header+head_length+1);
head_length+=4;
}
- if (!(mi_fix_rec_buff_for_blob(myisam,info->rec_len + info->blob_len)))
+ if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len,
+ &myisam->rec_buff,
+ &myisam->alloced_rec_buff_length)))
return BLOCK_FATAL_ERROR; /* not enough memory */
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff+info->rec_len;
myisam->blob_length=info->blob_len;
@@ -1231,8 +1233,10 @@ static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info,
info->blob_len=uint3korr(header+1);
header+=4;
}
- /* mi_fix_rec_buff_for_blob sets my_errno on error */
- if (!(mi_fix_rec_buff_for_blob(myisam,info->blob_len)))
+ /* mi_alloc_rec_buff sets my_errno on error */
+ if (!(mi_alloc_rec_buff(myisam, info->blob_len,
+ &myisam->rec_buff,
+ &myisam->alloced_rec_buff_length)))
return 0; /* not enough memory */
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff;
}
diff --git a/myisam/mi_page.c b/myisam/mi_page.c
index f8e2a977754..064e9239e73 100644
--- a/myisam/mi_page.c
+++ b/myisam/mi_page.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -64,9 +64,9 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
#ifndef FAST /* Safety check */
if (page < info->s->base.keystart ||
page+keyinfo->block_length > info->state->key_file_length ||
- page & (myisam_block_size-1))
+ (page & (MI_MIN_KEY_BLOCK_LENGTH-1)))
{
- DBUG_PRINT("error",("Trying to write outside key region: %lu",
+ DBUG_PRINT("error",("Trying to write inside key status region: %lu",
(long) page));
my_errno=EINVAL;
return(-1);
diff --git a/myisam/mi_panic.c b/myisam/mi_panic.c
index 92fc6f3695c..bd0b07b097e 100644
--- a/myisam/mi_panic.c
+++ b/myisam/mi_panic.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_range.c b/myisam/mi_range.c
index 038f9abc3a6..70694bf4620 100644
--- a/myisam/mi_range.c
+++ b/myisam/mi_range.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -45,7 +45,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
if ((inx = _mi_check_index(info,inx)) < 0)
DBUG_RETURN(HA_POS_ERROR);
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(HA_POS_ERROR);
info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED);
if (info->s->concurrent_insert)
@@ -58,7 +58,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
info->state->records+ (ha_rows) 1);
if (info->s->concurrent_insert)
rw_unlock(&info->s->key_root_lock[inx]);
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
DBUG_RETURN(HA_POS_ERROR);
DBUG_PRINT("info",("records: %ld",(ulong) (end_pos-start_pos)));
@@ -72,7 +72,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
enum ha_rkey_function search_flag)
{
- uint inx=(uint) info->lastinx;
+ uint inx=(uint) info->lastinx, nextflag;
MI_KEYDEF *keyinfo=info->s->keyinfo+inx;
uchar *key_buff;
double pos;
@@ -86,8 +86,12 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len);
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,
(uchar*) key_buff,key_len););
+ nextflag=myisam_read_vec[search_flag];
+ if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
+ key_len=USE_WHOLE_KEY;
+
pos=_mi_search_pos(info,keyinfo,key_buff,key_len,
- myisam_read_vec[search_flag] | SEARCH_SAVE_BUFF,
+ nextflag | SEARCH_SAVE_BUFF,
info->s->state.key_root[inx]);
if (pos >= 0.0)
{
@@ -145,9 +149,9 @@ static double _mi_search_pos(register MI_INFO *info,
** Matches keynr+1
*/
offset=1.0; /* Matches keynr+1 */
- if (nextflag & SEARCH_FIND &&
+ if ((nextflag & SEARCH_FIND) && nod_flag &&
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
- key_len) && nod_flag)
+ key_len != USE_WHOLE_KEY))
{
/*
** There may be identical keys in the tree. Try to match on of those.
diff --git a/myisam/mi_rename.c b/myisam/mi_rename.c
index 5c92db3f7ce..db44b8fe28f 100644
--- a/myisam/mi_rename.c
+++ b/myisam/mi_rename.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -51,7 +51,7 @@ int mi_rename(const char *old_name, const char *new_name)
fn_format(from,old_name,"",MI_NAME_IEXT,4);
fn_format(to,new_name,"",MI_NAME_IEXT,4);
- if (my_rename(from, to, MYF(MY_WME)))
+ if (my_rename_with_symlink(from, to, MYF(MY_WME)))
DBUG_RETURN(my_errno);
fn_format(from,old_name,"",MI_NAME_DEXT,4);
fn_format(to,new_name,"",MI_NAME_DEXT,4);
@@ -60,5 +60,5 @@ int mi_rename(const char *old_name, const char *new_name)
DBUG_RETURN(my_raid_rename(from, to, raid_chunks, MYF(MY_WME)) ? my_errno :
0);
#endif
- DBUG_RETURN(my_rename(from, to,MYF(MY_WME)) ? my_errno : 0);
+ DBUG_RETURN(my_rename_with_symlink(from, to,MYF(MY_WME)) ? my_errno : 0);
}
diff --git a/myisam/mi_rfirst.c b/myisam/mi_rfirst.c
index 8928c6332c5..e30f61801a0 100644
--- a/myisam/mi_rfirst.c
+++ b/myisam/mi_rfirst.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c
index 0df390412b9..86547d3ef04 100644
--- a/myisam/mi_rkey.c
+++ b/myisam/mi_rkey.c
@@ -27,7 +27,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
{
uchar *key_buff;
MYISAM_SHARE *share=info->s;
- uint pack_key_length;
+ uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
info,inx,search_flag));
@@ -55,11 +55,17 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
bmove(key_buff,key,key_len);
}
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
goto err;
if (share->concurrent_insert)
rw_rdlock(&share->key_root_lock[inx]);
- if (!_mi_search(info,info->s->keyinfo+inx,key_buff,pack_key_length,
+
+ nextflag=myisam_read_vec[search_flag];
+ use_key_length=pack_key_length;
+ if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
+ use_key_length=USE_WHOLE_KEY;
+
+ if (!_mi_search(info,info->s->keyinfo+inx,key_buff,use_key_length,
myisam_read_vec[search_flag],info->s->state.key_root[inx]))
{
while (info->lastpos >= info->state->data_file_length)
diff --git a/myisam/mi_rlast.c b/myisam/mi_rlast.c
index c08174e9117..61c3ff58fd5 100644
--- a/myisam/mi_rlast.c
+++ b/myisam/mi_rlast.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_rnext.c b/myisam/mi_rnext.c
index f297740af60..6d135462f96 100644
--- a/myisam/mi_rnext.c
+++ b/myisam/mi_rnext.c
@@ -35,7 +35,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND)
flag=0; /* Read first */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
if (info->s->concurrent_insert)
rw_rdlock(&info->s->key_root_lock[inx]);
@@ -51,7 +51,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
info->s->state.key_root[inx]);
else
error=_mi_search(info,info->s->keyinfo+inx,info->lastkey,
- info->lastkey_length,flag, info->s->state.key_root[inx]);
+ USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
if (!error)
{
diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c
index 0e172894cdf..662bdb154b3 100644
--- a/myisam/mi_rnext_same.c
+++ b/myisam/mi_rnext_same.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -35,7 +35,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
keyinfo=info->s->keyinfo+inx;
flag=SEARCH_BIGGER; /* Read next */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
memcpy(info->lastkey2,info->lastkey,info->last_rkey_length);
diff --git a/myisam/mi_rprev.c b/myisam/mi_rprev.c
index fff2d2257b6..4807e636252 100644
--- a/myisam/mi_rprev.c
+++ b/myisam/mi_rprev.c
@@ -36,7 +36,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_NEXT_FOUND)
flag=0; /* Read last */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
changed=_mi_test_if_changed(info);
if (share->concurrent_insert)
@@ -50,7 +50,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
share->state.key_root[inx]);
else
error=_mi_search(info,share->keyinfo+inx,info->lastkey,
- info->lastkey_length, flag, share->state.key_root[inx]);
+ USE_WHOLE_KEY, flag, share->state.key_root[inx]);
if (!error)
{
diff --git a/myisam/mi_rrnd.c b/myisam/mi_rrnd.c
index 11fa2af59bd..f8009441cff 100644
--- a/myisam/mi_rrnd.c
+++ b/myisam/mi_rrnd.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_rsame.c b/myisam/mi_rsame.c
index a4092b53c0b..56c8d1226ca 100644
--- a/myisam/mi_rsame.c
+++ b/myisam/mi_rsame.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -41,7 +41,7 @@ int mi_rsame(MI_INFO *info, byte *record, int inx)
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
/* Read row from data file */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
if (inx >= 0)
@@ -51,7 +51,8 @@ int mi_rsame(MI_INFO *info, byte *record, int inx)
info->lastpos);
if (info->s->concurrent_insert)
rw_rdlock(&info->s->key_root_lock[inx]);
- VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey,0,SEARCH_SAME,
+ VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey, USE_WHOLE_KEY,
+ SEARCH_SAME,
info->s->state.key_root[inx]));
if (info->s->concurrent_insert)
rw_unlock(&info->s->key_root_lock[inx]);
diff --git a/myisam/mi_rsamepos.c b/myisam/mi_rsamepos.c
index 28a5b6783b2..a1d96fb7104 100644
--- a/myisam/mi_rsamepos.c
+++ b/myisam/mi_rsamepos.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_scan.c b/myisam/mi_scan.c
index c06f092ab17..90bc3430ba7 100644
--- a/myisam/mi_scan.c
+++ b/myisam/mi_scan.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index 2c04679ed4c..4114125d6f7 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,29 +19,27 @@
#include "fulltext.h"
#include "m_ctype.h"
-#define CMP(a,b) (a<b ? -1 : a == b ? 0 : 1)
-
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos,
- uint *return_key_length);
+ uchar *key, uchar *keypos,
+ uint *return_key_length);
- /* Check index */
+ /* Check index */
int _mi_check_index(MI_INFO *info, int inx)
{
- if (inx == -1) /* Use last index */
+ if (inx == -1) /* Use last index */
inx=info->lastinx;
if (inx < 0 || ! (((ulonglong) 1 << inx) & info->s->state.key_map))
{
my_errno=HA_ERR_WRONG_INDEX;
return -1;
}
- if (info->lastinx != inx) /* Index changed */
+ if (info->lastinx != inx) /* Index changed */
{
info->lastinx = inx;
info->page_changed=1;
info->update= ((info->update & (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED)) |
- HA_STATE_NEXT_FOUND | HA_STATE_PREV_FOUND);
+ HA_STATE_NEXT_FOUND | HA_STATE_PREV_FOUND);
}
if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache))
return(-1);
@@ -49,15 +47,15 @@ int _mi_check_index(MI_INFO *info, int inx)
} /* mi_check_index */
- /*
- ** Search after row by a key
- ** Position to row is stored in info->lastpos
- ** Return: -1 if not found
- ** 1 if one should continue search on higher level
- */
+ /*
+ ** Search after row by a key
+ ** Position to row is stored in info->lastpos
+ ** Return: -1 if not found
+ ** 1 if one should continue search on higher level
+ */
int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- uchar *key, uint key_len, uint nextflag, register my_off_t pos)
+ uchar *key, uint key_len, uint nextflag, register my_off_t pos)
{
my_bool last_key;
int error,flag;
@@ -66,25 +64,25 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
uchar lastkey[MI_MAX_KEY_BUFF],*buff;
DBUG_ENTER("_mi_search");
DBUG_PRINT("enter",("pos: %ld nextflag: %d lastpos: %ld",
- pos,nextflag,info->lastpos));
+ pos,nextflag,info->lastpos));
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_len););
if (pos == HA_OFFSET_ERROR)
{
- my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
+ my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
info->lastpos= HA_OFFSET_ERROR;
if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
- DBUG_RETURN(-1); /* Not found ; return error */
- DBUG_RETURN(1); /* Search at upper levels */
+ DBUG_RETURN(-1); /* Not found ; return error */
+ DBUG_RETURN(1); /* Search at upper levels */
}
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)))))
+ test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
DBUG_DUMP("page",(byte*) buff,mi_getint(buff));
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
- &keypos,lastkey, &last_key);
+ &keypos,lastkey, &last_key);
if (flag == MI_FOUND_WRONG_KEY)
DBUG_RETURN(-1);
nod_flag=mi_test_if_nod(buff);
@@ -93,35 +91,36 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (flag)
{
if ((error=_mi_search(info,keyinfo,key,key_len,nextflag,
- _mi_kpos(nod_flag,keypos))) <= 0)
+ _mi_kpos(nod_flag,keypos))) <= 0)
DBUG_RETURN(error);
if (flag >0)
{
if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
- keypos == buff+2+nod_flag)
- DBUG_RETURN(1); /* Bigger than key */
+ keypos == buff+2+nod_flag)
+ DBUG_RETURN(1); /* Bigger than key */
}
else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
- DBUG_RETURN(1); /* Smaller than key */
+ DBUG_RETURN(1); /* Smaller than key */
}
else
{
- if (nextflag & SEARCH_FIND && (!(keyinfo->flag & HA_NOSAME)
- || key_len) && nod_flag)
+ if ((nextflag & SEARCH_FIND) && nod_flag &&
+ ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
+ key_len != USE_WHOLE_KEY))
{
if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
- _mi_kpos(nod_flag,keypos))) >= 0 ||
- my_errno != HA_ERR_KEY_NOT_FOUND)
- DBUG_RETURN(error);
- info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in memory */
+ _mi_kpos(nod_flag,keypos))) >= 0 ||
+ my_errno != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(error);
+ info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
}
}
if (pos != info->last_keypage)
{
uchar *old_buff=buff;
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)))))
+ test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
keypos=buff+(keypos-old_buff);
maxpos=buff+(maxpos-old_buff);
@@ -131,13 +130,13 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
uint not_used;
if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos,
- &info->lastkey_length))
+ &info->lastkey_length))
goto err;
if ((nextflag & SEARCH_LAST) &&
- _mi_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
- &not_used))
+ _mi_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
+ &not_used))
{
- my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
+ my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
goto err;
}
}
@@ -156,7 +155,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
info->int_keytree_version=keyinfo->version;
info->last_search_keypage=info->last_keypage;
info->page_changed=0;
- info->buff_used= (info->buff != buff); /* If we have to reread buff */
+ info->buff_used= (info->buff != buff); /* If we have to reread buff */
DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
DBUG_RETURN(0);
@@ -168,14 +167,14 @@ err:
} /* _mi_search */
- /* Search after key in page-block */
- /* If packed key puts smaller or identical key in buff */
- /* ret_pos point to where find or bigger key starts */
- /* ARGSUSED */
+ /* Search after key in page-block */
+ /* If packed key puts smaller or identical key in buff */
+ /* ret_pos point to where find or bigger key starts */
+ /* ARGSUSED */
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
- uchar *buff __attribute__((unused)), my_bool *last_key)
+ uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
+ uchar *buff __attribute__((unused)), my_bool *last_key)
{
reg4 int start,mid,end,save_end;
int flag;
@@ -193,17 +192,17 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
{
mid= (start+end)/2;
if ((flag=_mi_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len,
- comp_flag,&not_used))
- >= 0)
+ comp_flag,&not_used))
+ >= 0)
end=mid;
else
start=mid+1;
}
if (mid != start)
flag=_mi_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len,
- comp_flag,&not_used);
+ comp_flag,&not_used);
if (flag < 0)
- start++; /* point at next, bigger key */
+ start++; /* point at next, bigger key */
*ret_pos=page+(uint) start*totlength;
*last_key= end == save_end;
DBUG_PRINT("exit",("flag: %d keypos: %d",flag,start));
@@ -211,13 +210,13 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_bin_search */
- /* Used instead of _mi_bin_search() when key is packed */
- /* Puts smaller or identical key in buff */
- /* Key is searched sequentially */
+ /* Used instead of _mi_bin_search() when key is packed */
+ /* Puts smaller or identical key in buff */
+ /* Key is searched sequentially */
int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
- uchar *buff, my_bool *last_key)
+ uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
+ uchar *buff, my_bool *last_key)
{
int flag;
uint nod_flag,length,not_used;
@@ -229,7 +228,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
nod_flag=mi_test_if_nod(page);
page+=2+nod_flag;
*ret_pos=page;
- t_buff[0]=0; /* Avoid bugs */
+ t_buff[0]=0; /* Avoid bugs */
while (page < end)
{
length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff);
@@ -237,11 +236,11 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
{
my_errno=HA_ERR_CRASHED;
DBUG_PRINT("error",("Found wrong key: length: %d page: %lx end: %lx",
- length,page,end));
+ length,page,end));
DBUG_RETURN(MI_FOUND_WRONG_KEY);
}
if ((flag=_mi_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
- &not_used)) >= 0)
+ &not_used)) >= 0)
break;
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("page: %lx key: '%s' flag: %d",page,t_buff,flag));
@@ -250,14 +249,224 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
*ret_pos=page;
}
if (flag == 0)
- memcpy(buff,t_buff,length); /* Result is first key */
+ memcpy(buff,t_buff,length); /* Result is first key */
*last_key= page == end;
DBUG_PRINT("exit",("flag: %d ret_pos: %lx",flag,*ret_pos));
DBUG_RETURN(flag);
} /* _mi_seq_search */
- /* Get pos to a key_block */
+int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
+ uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
+ uchar *buff, my_bool *last_key)
+{
+ /* my_flag is raw comparison result to be changed according to
+ SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
+ flag is the value returned by _mi_key_cmp and as treated as final */
+ int flag=0, my_flag=-1;
+ uint nod_flag, length, len, matched, cmplen, kseg_len;
+ uint prefix_len,suffix_len;
+ int key_len_skip, seg_len_pack, key_len_left;
+ uchar *end, *kseg, *vseg;
+ uchar *sort_order=keyinfo->seg->charset->sort_order;
+ uchar tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
+ uchar *saved_from, *saved_to, *saved_vseg;
+ uint saved_length=0, saved_prefix_len=0;
+ DBUG_ENTER("_mi_prefix_search");
+
+ LINT_INIT(length);
+ LINT_INIT(prefix_len);
+ LINT_INIT(seg_len_pack);
+ LINT_INIT(saved_from);
+ LINT_INIT(saved_to);
+ LINT_INIT(saved_vseg);
+
+ t_buff[0]=0; /* Avoid bugs */
+ end= page+mi_getint(page);
+ nod_flag=mi_test_if_nod(page);
+ page+=2+nod_flag;
+ *ret_pos=page;
+ kseg=key;
+ {
+ uint lenght_pack;
+ get_key_pack_length(kseg_len,lenght_pack,kseg);
+ key_len_skip=lenght_pack+kseg_len;
+ key_len_left=(int) key_len- (int) key_len_skip;
+ cmplen=(key_len_left>=0) ? kseg_len : key_len-lenght_pack;
+ DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg));
+ }
+
+/*
+ Keys are compressed the following way:
+
+ If the max length of first key segment <= 127 characters the prefix is
+ 1 byte else it's 2 byte
+
+ prefix The high bit is set if this is a prefix for the prev key
+ length Packed length if the previous was a prefix byte
+ [length] Length character of data
+ next-key-seg Next key segments
+*/
+
+ matched=0; /* how many char's from prefix were alredy matched */
+ len=0; /* length of previous key unpacked */
+
+ while (page < end)
+ {
+ uint packed= *page & 128;
+
+ vseg=page;
+ if (keyinfo->seg->length >= 127)
+ {
+ suffix_len=mi_uint2korr(vseg) & 32767;
+ vseg+=2;
+ }
+ else
+ suffix_len= *vseg++ & 127;
+
+ if (packed)
+ {
+ if (suffix_len == 0) /* Same key */
+ prefix_len=len;
+ else
+ {
+ prefix_len=suffix_len;
+ get_key_length(suffix_len,vseg);
+ }
+ }
+ else
+ prefix_len=0;
+
+ len=prefix_len+suffix_len;
+ seg_len_pack=get_pack_length(len);
+ t_buff=tt_buff+3-seg_len_pack;
+ store_key_length(t_buff,len);
+
+ if (prefix_len > saved_prefix_len)
+ memcpy(t_buff+seg_len_pack+saved_prefix_len,saved_vseg,
+ prefix_len-saved_prefix_len);
+ saved_vseg=vseg;
+ saved_prefix_len=prefix_len;
+
+ DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,suffix_len,vseg));
+ {
+ uchar *from=vseg+suffix_len;
+ MI_KEYSEG *keyseg;
+ uint l;
+
+ for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ )
+ {
+
+ if (keyseg->flag & HA_NULL_PART)
+ {
+ if (!(*from++))
+ continue;
+ }
+ if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
+ {
+ get_key_length(l,from);
+ }
+ else
+ l=keyseg->length;
+
+ from+=l;
+ }
+ from+=keyseg->length;
+ page=from+nod_flag;
+ length=from-vseg;
+ }
+
+ if (page > end)
+ {
+ my_errno=HA_ERR_CRASHED;
+ DBUG_PRINT("error",("Found wrong key: length: %d page: %lx end: %lx",
+ length,page,end));
+ DBUG_RETURN(MI_FOUND_WRONG_KEY);
+ }
+
+ if (matched >= prefix_len)
+ {
+ /* We have to compare. But we can still skip part of the key */
+ uint left;
+ uchar *k=kseg+prefix_len;
+
+ left=(len>cmplen) ? cmplen-prefix_len : suffix_len;
+
+ matched=prefix_len+left;
+
+ for(my_flag=0;left;left--)
+ if ((my_flag= (int) sort_order[*vseg++] - (int) sort_order[*k++]))
+ break;
+
+ if (my_flag>0) /* mismatch */
+ break;
+ else if (my_flag==0) /* match */
+ { /*
+ ** len cmplen seg_left_len more_segs
+ ** < matched=len; continue search
+ ** > = prefix ? found : (matched=len; continue search)
+ ** > < - ok, found
+ ** = < - ok, found
+ ** = = - ok, found
+ ** = = + next seg
+ */
+ if (len < cmplen)
+ {
+ my_flag= -1;
+ }
+ else if (len > cmplen)
+ {
+ if ((my_flag= (!(nextflag & SEARCH_PREFIX) || key_len_left>0)))
+ break;
+ goto fix_flag;
+ }
+ else if (key_len_left>0)
+ {
+ uint not_used;
+ if ((flag = _mi_key_cmp(keyinfo->seg+1,vseg,
+ k,key_len_left,nextflag,&not_used)) >= 0)
+ break;
+ }
+ else
+ {
+ /* at this line flag==-1 if the following lines were already
+ visited and 0 otherwise, i.e. flag <=0 here always !!! */
+ fix_flag:
+ if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST))
+ flag=(nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
+ if (flag>=0) break;
+ }
+ }
+ matched-=left;
+ }
+ /* else (matched < prefix_len) ---> do nothing. */
+
+ memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
+ saved_to=buff+saved_length;
+ saved_from=saved_vseg;
+ saved_length=length;
+ *ret_pos=page;
+ }
+ if (my_flag)
+ flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag;
+ if (flag == 0)
+ {
+ memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
+ saved_to=buff+saved_length;
+ saved_from=saved_vseg;
+ saved_length=length;
+ }
+ if (saved_length)
+ memcpy(saved_to,saved_from,saved_length);
+
+ *last_key= page == end;
+
+ DBUG_PRINT("exit",("flag: %d ret_pos: %lx",flag,*ret_pos));
+ DBUG_RETURN(flag);
+} /* _mi_prefix_search */
+
+
+ /* Get pos to a key_block */
my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
{
@@ -265,11 +474,11 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
switch (nod_flag) {
#if SIZEOF_OFF_T > 4
case 7:
- return mi_uint7korr(after_key)*MI_KEY_BLOCK_LENGTH;
+ return mi_uint7korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
case 6:
- return mi_uint6korr(after_key)*MI_KEY_BLOCK_LENGTH;
+ return mi_uint6korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
case 5:
- return mi_uint5korr(after_key)*MI_KEY_BLOCK_LENGTH;
+ return mi_uint5korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
#else
case 7:
after_key++;
@@ -279,25 +488,25 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
after_key++;
#endif
case 4:
- return ((my_off_t) mi_uint4korr(after_key))*MI_KEY_BLOCK_LENGTH;
+ return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
case 3:
- return ((my_off_t) mi_uint3korr(after_key))*MI_KEY_BLOCK_LENGTH;
+ return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
case 2:
- return (my_off_t) (mi_uint2korr(after_key)*MI_KEY_BLOCK_LENGTH);
+ return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
case 1:
- return (uint) (*after_key)*MI_KEY_BLOCK_LENGTH;
- case 0: /* At leaf page */
- default: /* Impossible */
+ return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH;
+ case 0: /* At leaf page */
+ default: /* Impossible */
return(HA_OFFSET_ERROR);
}
} /* _kpos */
- /* Save pos to a key_block */
+ /* Save pos to a key_block */
void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
{
- pos/=MI_KEY_BLOCK_LENGTH;
+ pos/=MI_MIN_KEY_BLOCK_LENGTH;
switch (info->s->base.key_reflength) {
#if SIZEOF_OFF_T > 4
case 7: mi_int7store(buff,pos); break;
@@ -315,12 +524,12 @@ void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
case 3: mi_int3store(buff,pos); break;
case 2: mi_int2store(buff,(uint) pos); break;
case 1: buff[0]= (uchar) pos; break;
- default: abort(); /* impossible */
+ default: abort(); /* impossible */
}
} /* _mi_kpointer */
- /* Calc pos to a data-record from a key */
+ /* Calc pos to a data-record from a key */
my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, uchar *after_key)
@@ -335,19 +544,19 @@ my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, uchar *after_key)
case 5: pos= (my_off_t) mi_uint5korr(after_key); break;
#else
case 8: pos= (my_off_t) mi_uint4korr(after_key+4); break;
- case 7: pos= (my_off_t) mi_uint4korr(after_key+3); break;
- case 6: pos= (my_off_t) mi_uint4korr(after_key+2); break;
- case 5: pos= (my_off_t) mi_uint4korr(after_key+1); break;
+ case 7: pos= (my_off_t) mi_uint4korr(after_key+3); break;
+ case 6: pos= (my_off_t) mi_uint4korr(after_key+2); break;
+ case 5: pos= (my_off_t) mi_uint4korr(after_key+1); break;
#endif
case 4: pos= (my_off_t) mi_uint4korr(after_key); break;
case 3: pos= (my_off_t) mi_uint3korr(after_key); break;
case 2: pos= (my_off_t) mi_uint2korr(after_key); break;
default:
- pos=0L; /* Shut compiler up */
+ pos=0L; /* Shut compiler up */
}
return (info->s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
- pos*info->s->base.pack_reclength;
+ (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
+ pos*info->s->base.pack_reclength;
}
@@ -361,22 +570,22 @@ my_off_t _mi_rec_pos(MYISAM_SHARE *s, uchar *ptr)
case 8:
pos= (my_off_t) mi_uint8korr(ptr);
if (pos == HA_OFFSET_ERROR)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
case 7:
pos= (my_off_t) mi_uint7korr(ptr);
if (pos == (((my_off_t) 1) << 56) -1)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
case 6:
pos= (my_off_t) mi_uint6korr(ptr);
if (pos == (((my_off_t) 1) << 48) -1)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
case 5:
pos= (my_off_t) mi_uint5korr(ptr);
if (pos == (((my_off_t) 1) << 40) -1)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
#else
case 8:
@@ -401,20 +610,20 @@ my_off_t _mi_rec_pos(MYISAM_SHARE *s, uchar *ptr)
if (pos == (my_off_t) (1 << 16) -1)
return HA_OFFSET_ERROR;
break;
- default: abort(); /* Impossible */
+ default: abort(); /* Impossible */
}
return ((s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
- pos*s->base.pack_reclength);
+ (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
+ pos*s->base.pack_reclength);
}
- /* save position to record */
+ /* save position to record */
void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
{
if (!(info->s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
+ (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
pos != HA_OFFSET_ERROR)
pos/=info->s->base.pack_reclength;
@@ -437,27 +646,27 @@ void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
case 2: mi_int2store(buff,(uint) pos); break;
- default: abort(); /* Impossible */
+ default: abort(); /* Impossible */
}
} /* _mi_dpointer */
int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
- uchar *b, uint b_length, my_bool part_key)
+ uchar *b, uint b_length, my_bool part_key)
{
- uint length= min(a_length,b_length);
- uchar *end= a+ length;
int flag;
#ifdef USE_STRCOLL
if (use_strcoll(charset_info))
{
- if ((flag = my_strnncoll(charset_info, a, a_length, b, b_length)))
- return flag;
+ /* QQ: This needs to work with part keys at some point */
+ return my_strnncoll(charset_info, a, a_length, b, b_length);
}
else
#endif
{
+ uint length= min(a_length,b_length);
+ uchar *end= a+ length;
uchar *sort_order=charset_info->sort_order;
while (a < end)
if ((flag= (int) sort_order[*a++] - (int) sort_order[*b++]))
@@ -470,7 +679,7 @@ int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
- my_bool part_key)
+ my_bool part_key)
{
uint length= min(a_length,b_length);
uchar *end= a+ length;
@@ -485,19 +694,19 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
}
- /*
- ** Compare two keys with is bigger
- ** Returns <0, 0, >0 acording to with is bigger
- ** Key_length specifies length of key to use. Number-keys can't
- ** be splited
- ** If flag <> SEARCH_FIND compare also position
- */
+ /*
+ ** Compare two keys
+ ** Returns <0, 0, >0 acording to which is bigger
+ ** Key_length specifies length of key to use. Number-keys can't
+ ** be splited
+ ** If flag <> SEARCH_FIND compare also position
+ */
#define FCMP(A,B) ((int) (A) - (int) (B))
int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
- register uchar *b, uint key_length, uint nextflag,
- uint *diff_pos)
+ register uchar *b, uint key_length, uint nextflag,
+ uint *diff_pos)
{
int flag;
int16 s_1,s_2;
@@ -507,129 +716,134 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
double d_1,d_2;
uint next_key_length;
- if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
- key_length=USE_WHOLE_KEY;
*diff_pos=0;
-
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
{
uchar *end;
+ uint piks=! (keyseg->flag & HA_NO_SORT);
(*diff_pos)++;
/* Handle NULL part */
if (keyseg->null_bit)
{
key_length--;
- if (*a != *b)
+ if (*a != *b && piks)
{
- flag = (int) *a - (int) *b;
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ flag = (int) *a - (int) *b;
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
}
b++;
- if (!*a++) /* If key was NULL */
+ if (!*a++) /* If key was NULL */
{
- if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
- nextflag=SEARCH_SAME; /* Allow duplicate keys */
- next_key_length=key_length;
- continue; /* To next key part */
+ if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
+ nextflag=SEARCH_SAME; /* Allow duplicate keys */
+ next_key_length=key_length;
+ continue; /* To next key part */
}
}
end= a+ min(keyseg->length,key_length);
next_key_length=key_length-keyseg->length;
switch ((enum ha_base_keytype) keyseg->type) {
- case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
+ case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
if (keyseg->flag & HA_SPACE_PACK)
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ int a_length,b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ next_key_length=key_length-b_length-pack_length;
+
+ if (piks &&
+ (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
+ (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=a_length;
+ b+=b_length;
+ break;
}
else
{
- uint length=(uint) (end-a);
- if ((flag=_mi_compare_text(keyseg->charset,a,length,b,length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a=end;
- b+=length;
+ uint length=(uint) (end-a), a_length=length, b_length=length;
+ if (!(nextflag & SEARCH_PREFIX))
+ {
+ while (a_length && a[a_length-1] == ' ')
+ a_length--;
+ while (b_length && b[b_length-1] == ' ')
+ b_length--;
+ }
+ if (piks &&
+ (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
+ (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a=end;
+ b+=length;
}
break;
case HA_KEYTYPE_BINARY:
if (keyseg->flag & HA_SPACE_PACK)
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if ((flag=compare_bin(a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ int a_length,b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ next_key_length=key_length-b_length-pack_length;
+
+ if (piks &&
+ (flag=compare_bin(a,a_length,b,b_length,
+ (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=a_length;
+ b+=b_length;
+ break;
}
else
{
- uint length=keyseg->length;
- if ((flag=compare_bin(a,length,b,length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=length;
- b+=length;
+ uint length=keyseg->length;
+ if (piks &&
+ (flag=compare_bin(a,length,b,length,
+ (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=length;
+ b+=length;
}
break;
case HA_KEYTYPE_VARTEXT:
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ int a_length,b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ next_key_length=key_length-b_length-pack_length;
+
+ if (piks &&
+ (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
+ (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=a_length;
+ b+=b_length;
+ break;
}
break;
case HA_KEYTYPE_VARBINARY:
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if ((flag=compare_bin(a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ int a_length,b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ next_key_length=key_length-b_length-pack_length;
+
+ if (piks &&
+ (flag=compare_bin(a,a_length,b,b_length,
+ (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=a_length;
+ b+=b_length;
+ break;
}
break;
case HA_KEYTYPE_INT8:
{
int i_1= (int) *((signed char*) a);
int i_2= (int) *((signed char*) b);
- if ((flag = CMP(i_1,i_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(i_1,i_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b++;
break;
@@ -637,125 +851,132 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
case HA_KEYTYPE_SHORT_INT:
s_1= mi_sint2korr(a);
s_2= mi_sint2korr(b);
- if ((flag = CMP(s_1,s_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(s_1,s_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 2; /* sizeof(short int); */
break;
case HA_KEYTYPE_USHORT_INT:
{
- uint16 us_1,us_2;
- us_1= mi_sint2korr(a);
- us_2= mi_sint2korr(b);
- if ((flag = CMP(us_1,us_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+=2; /* sizeof(short int); */
- break;
+ uint16 us_1,us_2;
+ us_1= mi_sint2korr(a);
+ us_2= mi_sint2korr(b);
+ if (piks && (flag = CMP_NUM(us_1,us_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a= end;
+ b+=2; /* sizeof(short int); */
+ break;
}
case HA_KEYTYPE_LONG_INT:
l_1= mi_sint4korr(a);
l_2= mi_sint4korr(b);
- if ((flag = CMP(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(l_1,l_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 4; /* sizeof(long int); */
break;
case HA_KEYTYPE_ULONG_INT:
u_1= mi_sint4korr(a);
u_2= mi_sint4korr(b);
- if ((flag = CMP(u_1,u_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(u_1,u_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 4; /* sizeof(long int); */
break;
case HA_KEYTYPE_INT24:
l_1=mi_sint3korr(a);
l_2=mi_sint3korr(b);
- if ((flag = CMP(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(l_1,l_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 3;
break;
case HA_KEYTYPE_UINT24:
l_1=mi_uint3korr(a);
l_2=mi_uint3korr(b);
- if ((flag = CMP(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(l_1,l_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 3;
break;
case HA_KEYTYPE_FLOAT:
mi_float4get(f_1,a);
mi_float4get(f_2,b);
- if ((flag = CMP(f_1,f_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(f_1,f_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 4; /* sizeof(float); */
break;
case HA_KEYTYPE_DOUBLE:
mi_float8get(d_1,a);
mi_float8get(d_2,b);
- if ((flag = CMP(d_1,d_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(d_1,d_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 8; /* sizeof(double); */
break;
- case HA_KEYTYPE_NUM: /* Numeric key */
+ case HA_KEYTYPE_NUM: /* Numeric key */
{
int swap_flag= 0;
int alength,blength;
-
+
if (keyseg->flag & HA_REVERSE_SORT)
{
- swap(uchar*,a,b);
- swap_flag=1; /* Remember swap of a & b */
+ swap(uchar*,a,b);
+ swap_flag=1; /* Remember swap of a & b */
end= a+ (int) (end-b);
}
if (keyseg->flag & HA_SPACE_PACK)
{
- alength= *a++; blength= *b++;
- end=a+alength;
- next_key_length=key_length-blength-1;
+ alength= *a++; blength= *b++;
+ end=a+alength;
+ next_key_length=key_length-blength-1;
}
else
{
- alength= (int) (end-a);
- blength=keyseg->length;
- /* remove pre space from keys */
- for ( ; alength && *a == ' ' ; a++, alength--) ;
- for ( ; blength && *b == ' ' ; b++, blength--) ;
+ alength= (int) (end-a);
+ blength=keyseg->length;
+ /* remove pre space from keys */
+ for ( ; alength && *a == ' ' ; a++, alength--) ;
+ for ( ; blength && *b == ' ' ; b++, blength--) ;
}
-
- if (*a == '-')
+ if (piks)
{
- if (*b != '-')
- return -1;
- a++; b++;
- swap(uchar*,a,b);
- swap(int,alength,blength);
- swap_flag=1-swap_flag;
- alength--; blength--;
- end=a+alength;
+ if (*a == '-')
+ {
+ if (*b != '-')
+ return -1;
+ a++; b++;
+ swap(uchar*,a,b);
+ swap(int,alength,blength);
+ swap_flag=1-swap_flag;
+ alength--; blength--;
+ end=a+alength;
+ }
+ else if (*b == '-')
+ return 1;
+ while (alength && (*a == '+' || *a == '0'))
+ {
+ a++; alength--;
+ }
+ while (blength && (*b == '+' || *b == '0'))
+ {
+ b++; blength--;
+ }
+ if (alength != blength)
+ return (alength < blength) ? -1 : 1;
+ while (a < end)
+ if (*a++ != *b++)
+ return ((int) a[-1] - (int) b[-1]);
}
- else if (*b == '-')
- return 1;
- while (alength && (*a == '+' || *a == '0'))
- {
- a++; alength--;
- }
- while (blength && (*b == '+' || *b == '0'))
+ else
{
- b++; blength--;
+ b+=(end-a);
+ a=end;
}
- if (alength != blength)
- return (alength < blength) ? -1 : 1;
- while (a < end)
- if (*a++ != *b++)
- return ((int) a[-1] - (int) b[-1]);
-
- if (swap_flag) /* Restore pointers */
- swap(uchar*,a,b);
+
+ if (swap_flag) /* Restore pointers */
+ swap(uchar*,a,b);
break;
}
#ifdef HAVE_LONG_LONG
@@ -764,8 +985,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
longlong ll_a,ll_b;
ll_a= mi_sint8korr(a);
ll_b= mi_sint8korr(b);
- if ((flag = CMP(ll_a,ll_b)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(ll_a,ll_b)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 8;
break;
@@ -775,15 +996,15 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
ulonglong ll_a,ll_b;
ll_a= mi_uint8korr(a);
ll_b= mi_uint8korr(b);
- if ((flag = CMP(ll_a,ll_b)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(ll_a,ll_b)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 8;
break;
}
#endif
- case HA_KEYTYPE_END: /* Ready */
- goto end; /* diff_pos is incremented */
+ case HA_KEYTYPE_END: /* Ready */
+ goto end; /* diff_pos is incremented */
}
}
(*diff_pos)++;
@@ -798,33 +1019,33 @@ end:
{
if (*a++ != *b++)
{
- flag= FCMP(a[-1],b[-1]);
- break;
+ flag= FCMP(a[-1],b[-1]);
+ break;
}
}
if (nextflag & SEARCH_SAME)
- return (flag); /* read same */
+ return (flag); /* read same */
if (nextflag & SEARCH_BIGGER)
- return (flag <= 0 ? -1 : 1); /* read next */
- return (flag < 0 ? -1 : 1); /* read previous */
+ return (flag <= 0 ? -1 : 1); /* read next */
+ return (flag < 0 ? -1 : 1); /* read previous */
}
return 0;
} /* _mi_key_cmp */
- /* Get key from key-block */
- /* page points at previous key; its advanced to point at next key */
- /* key should contain previous key */
- /* Returns length of found key + pointers */
- /* nod_flag is a flag if we are on nod */
+ /* Get key from key-block */
+ /* page points at previous key; its advanced to point at next key */
+ /* key should contain previous key */
+ /* Returns length of found key + pointers */
+ /* nod_flag is a flag if we are on nod */
- /* same as _mi_get_key but used with fixed length keys */
+ /* same as _mi_get_key but used with fixed length keys */
uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page, register uchar *key)
+ register uchar **page, register uchar *key)
{
memcpy((byte*) key,(byte*) *page,
- (size_t) (keyinfo->keylength+nod_flag));
+ (size_t) (keyinfo->keylength+nod_flag));
*page+=keyinfo->keylength+nod_flag;
return(keyinfo->keylength);
} /* _mi_get_static_key */
@@ -833,7 +1054,7 @@ uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
/* Key with is packed against previous key or key with a NULL column */
uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page_pos, register uchar *key)
+ register uchar **page_pos, register uchar *key)
{
reg1 MI_KEYSEG *keyseg;
uchar *start_key,*page=*page_pos;
@@ -849,11 +1070,11 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
uint packed= *page & 128,tot_length,rest_length;
if (keyseg->length >= 127)
{
- length=mi_uint2korr(page) & 32767;
- page+=2;
+ length=mi_uint2korr(page) & 32767;
+ page+=2;
}
else
- length= *page++ & 127;
+ length= *page++ & 127;
if (packed)
{
@@ -914,23 +1135,23 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
}
else
{
- if (keyseg->flag & HA_NULL_PART)
- {
- if (!length--) /* Null part */
- {
- *key++=0;
- continue;
- }
- *key++=1; /* Not null */
- }
+ if (keyseg->flag & HA_NULL_PART)
+ {
+ if (!length--) /* Null part */
+ {
+ *key++=0;
+ continue;
+ }
+ *key++=1; /* Not null */
+ }
}
if (length > (uint) keyseg->length)
{
- DBUG_PRINT("error",("Found too long packed key: %d of %d at %lx",
- length, keyseg->length, *page_pos));
- DBUG_DUMP("key",(char*) *page_pos,16);
- my_errno=HA_ERR_CRASHED;
- return 0; /* Error */
+ DBUG_PRINT("error",("Found too long packed key: %d of %d at %lx",
+ length, keyseg->length, *page_pos));
+ DBUG_DUMP("key",(char*) *page_pos,16);
+ my_errno=HA_ERR_CRASHED;
+ return 0; /* Error */
}
store_key_length_inc(key,length);
}
@@ -938,18 +1159,18 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
if (keyseg->flag & HA_NULL_PART)
{
- if (!(*key++ = *page++))
- continue;
+ if (!(*key++ = *page++))
+ continue;
}
if (keyseg->flag &
- (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
+ (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
{
- uchar *tmp=page;
- get_key_length(length,tmp);
- length+=(uint) (tmp-page);
+ uchar *tmp=page;
+ get_key_length(length,tmp);
+ length+=(uint) (tmp-page);
}
else
- length=keyseg->length;
+ length=keyseg->length;
}
memcpy((byte*) key,(byte*) page,(size_t) length);
key+=length;
@@ -966,7 +1187,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
/* key that is packed relatively to previous */
uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page_pos, register uchar *key)
+ register uchar **page_pos, register uchar *key)
{
reg1 MI_KEYSEG *keyseg;
uchar *start_key,*page=*page_pos,*page_end,*from,*from_end;
@@ -981,16 +1202,16 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if (length > keyinfo->maxlength)
{
DBUG_PRINT("error",("Found too long binary packed key: %d of %d at %lx",
- length, keyinfo->maxlength, *page_pos));
+ length, keyinfo->maxlength, *page_pos));
DBUG_DUMP("key",(char*) *page_pos,16);
my_errno=HA_ERR_CRASHED;
- return 0; /* Wrong key */
+ return 0; /* Wrong key */
}
from=key; from_end=key+length;
}
else
{
- from=page; from_end=page_end; /* Not packed key */
+ from=page; from_end=page_end; /* Not packed key */
}
/*
@@ -1004,7 +1225,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
if (from == from_end) { from=page; from_end=page_end; }
if (!(*key++ = *from++))
- continue; /* Null part */
+ continue; /* Null part */
}
if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
{
@@ -1012,10 +1233,10 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if (from == from_end) { from=page; from_end=page_end; }
if ((length= (*key++ = *from++)) == 255)
{
- if (from == from_end) { from=page; from_end=page_end; }
- length= (uint) ((*key++ = *from++)) << 8;
- if (from == from_end) { from=page; from_end=page_end; }
- length+= (uint) ((*key++ = *from++));
+ if (from == from_end) { from=page; from_end=page_end; }
+ length= (uint) ((*key++ = *from++)) << 8;
+ if (from == from_end) { from=page; from_end=page_end; }
+ length+= (uint) ((*key++ = *from++));
}
}
else
@@ -1023,7 +1244,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if ((tmp=(uint) (from_end-from)) <= length)
{
- key+=tmp; /* Use old key */
+ key+=tmp; /* Use old key */
length-=tmp;
from=page; from_end=page_end;
}
@@ -1034,7 +1255,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
length=keyseg->length+nod_flag;
if ((tmp=(uint) (from_end-from)) <= length)
{
- memcpy(key+tmp,page,length-tmp); /* Get last part of key */
+ memcpy(key+tmp,page,length-tmp); /* Get last part of key */
*page_pos= page+length-tmp;
}
else
@@ -1043,7 +1264,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
DBUG_PRINT("error",("Error when unpacking key"));
my_errno=HA_ERR_CRASHED;
- return 0; /* Error */
+ return 0; /* Error */
}
memcpy((byte*) key,(byte*) from,(size_t) length);
*page_pos= from+length;
@@ -1052,11 +1273,11 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
}
- /* Get key at position without knowledge of previous key */
- /* Returns pointer to next key */
+ /* Get key at position without knowledge of previous key */
+ /* Returns pointer to next key */
uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos, uint *return_key_length)
+ uchar *key, uchar *keypos, uint *return_key_length)
{
uint nod_flag;
DBUG_ENTER("_mi_get_key");
@@ -1070,14 +1291,14 @@ uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
else
{
page+=2+nod_flag;
- key[0]=0; /* safety */
+ key[0]=0; /* safety */
while (page <= keypos)
{
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
if (*return_key_length == 0)
{
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(0);
+ my_errno=HA_ERR_CRASHED;
+ DBUG_RETURN(0);
}
}
}
@@ -1086,12 +1307,12 @@ uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_get_key */
- /* Get key at position without knowledge of previous key */
- /* Returns 0 if ok */
+ /* Get key at position without knowledge of previous key */
+ /* Returns 0 if ok */
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos,
- uint *return_key_length)
+ uchar *key, uchar *keypos,
+ uint *return_key_length)
{
uint nod_flag;
DBUG_ENTER("_mi_get_prev_key");
@@ -1101,20 +1322,20 @@ static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
{
*return_key_length=keyinfo->keylength;
bmove((byte*) key,(byte*) keypos- *return_key_length-nod_flag,
- *return_key_length);
+ *return_key_length);
DBUG_RETURN(0);
}
else
{
page+=2+nod_flag;
- key[0]=0; /* safety */
+ key[0]=0; /* safety */
while (page < keypos)
{
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
if (*return_key_length == 0)
{
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(1);
+ my_errno=HA_ERR_CRASHED;
+ DBUG_RETURN(1);
}
}
}
@@ -1123,11 +1344,11 @@ static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- /* Get last key from key-page */
- /* Return pointer to where key starts */
+ /* Get last key from key-page */
+ /* Return pointer to where key starts */
uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *lastkey, uchar *endpos, uint *return_key_length)
+ uchar *lastkey, uchar *endpos, uint *return_key_length)
{
uint nod_flag;
uchar *lastpos;
@@ -1152,9 +1373,9 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,lastkey);
if (*return_key_length == 0)
{
- DBUG_PRINT("error",("Couldn't find last key: page: %lx",page));
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(0);
+ DBUG_PRINT("error",("Couldn't find last key: page: %lx",page));
+ my_errno=HA_ERR_CRASHED;
+ DBUG_RETURN(0);
}
}
}
@@ -1163,7 +1384,7 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_get_last_key */
- /* Calculate length of key */
+ /* Calculate length of key */
uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
{
@@ -1178,7 +1399,7 @@ uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
{
if (keyseg->flag & HA_NULL_PART)
if (!*key++)
- continue;
+ continue;
if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH))
{
uint length;
@@ -1192,28 +1413,28 @@ uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
} /* _mi_keylength */
- /* Move a key */
+ /* Move a key */
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
{
reg1 uint length;
memcpy((byte*) to, (byte*) from,
- (size_t) (length=_mi_keylength(keyinfo,from)));
+ (size_t) (length=_mi_keylength(keyinfo,from)));
return to+length;
}
- /* Find next/previous record with same key */
- /* This can't be used when database is touched after last read */
+ /* Find next/previous record with same key */
+ /* This can't be used when database is touched after last read */
int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- uchar *key, uint key_length, uint nextflag, my_off_t pos)
+ uchar *key, uint key_length, uint nextflag, my_off_t pos)
{
int error;
uint nod_flag;
uchar lastkey[MI_MAX_KEY_BUFF];
DBUG_ENTER("_mi_search_next");
DBUG_PRINT("enter",("nextflag: %d lastpos: %ld int_keypos: %lx",
- nextflag,(long) info->lastpos,info->int_keypos));
+ nextflag,(long) info->lastpos,info->int_keypos));
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
/* Force full read if we are at last key or if we are not on a leaf
@@ -1227,51 +1448,53 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
info->page_changed ||
(info->int_keytree_version != keyinfo->version &&
(info->int_nod_flag || info->buff_used)))
- DBUG_RETURN(_mi_search(info,keyinfo,key,key_length,
- nextflag | SEARCH_SAVE_BUFF, pos));
+ DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF, pos));
if (info->buff_used)
{
if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
- info->buff,0))
+ info->buff,0))
DBUG_RETURN(-1);
info->buff_used=0;
}
/* Last used buffer is in info->buff */
nod_flag=mi_test_if_nod(info->buff);
- memcpy(lastkey,key,key_length);
- if (nextflag & SEARCH_BIGGER) /* Next key */
+ if (nextflag & SEARCH_BIGGER) /* Next key */
{
my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
if (tmp_pos != HA_OFFSET_ERROR)
{
- if ((error=_mi_search(info,keyinfo,key,key_length,
- nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
- DBUG_RETURN(error);
+ if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
+ DBUG_RETURN(error);
}
+ memcpy(lastkey,key,key_length);
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
- &info->int_keypos,lastkey)))
+ &info->int_keypos,lastkey)))
DBUG_RETURN(-1);
}
- else /* Previous key */
+ else /* Previous key */
{
uint length;
/* Find start of previous key */
info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
- info->int_keypos, &length);
+ info->int_keypos, &length);
if (!info->int_keypos)
DBUG_RETURN(-1);
if (info->int_keypos == info->buff+2)
- DBUG_RETURN(_mi_search(info,keyinfo,key,key_length,
- nextflag | SEARCH_SAVE_BUFF, pos));
- if ((error=_mi_search(info,keyinfo,key,0,nextflag | SEARCH_SAVE_BUFF,
- _mi_kpos(nod_flag,info->int_keypos))) <= 0)
+ DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF, pos));
+ if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF,
+ _mi_kpos(nod_flag,info->int_keypos))) <= 0)
DBUG_RETURN(error);
+ /* QQ: We should be able to optimize away the following call */
if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
- info->int_keypos,&info->lastkey_length))
+ info->int_keypos,&info->lastkey_length))
DBUG_RETURN(-1);
}
memcpy(info->lastkey,lastkey,info->lastkey_length);
@@ -1281,11 +1504,11 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} /* _mi_search_next */
- /* Search after position for the first row in an index */
- /* This is stored in info->lastpos */
+ /* Search after position for the first row in an index */
+ /* This is stored in info->lastpos */
int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- register my_off_t pos)
+ register my_off_t pos)
{
uint nod_flag;
uchar *page;
@@ -1310,7 +1533,7 @@ int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
- info->lastkey);
+ info->lastkey);
info->int_keypos=page; info->int_maxpos=info->buff+mi_getint(info->buff)-1;
info->int_nod_flag=nod_flag;
info->int_keytree_version=keyinfo->version;
@@ -1323,11 +1546,11 @@ int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} /* _mi_search_first */
- /* Search after position for the last row in an index */
- /* This is stored in info->lastpos */
+ /* Search after position for the last row in an index */
+ /* This is stored in info->lastpos */
int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- register my_off_t pos)
+ register my_off_t pos)
{
uint nod_flag;
uchar *buff,*page;
@@ -1335,7 +1558,7 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (pos == HA_OFFSET_ERROR)
{
- my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
+ my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
info->lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
@@ -1353,7 +1576,7 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
if (!_mi_get_last_key(info,keyinfo,buff,info->lastkey,page,
- &info->lastkey_length))
+ &info->lastkey_length))
DBUG_RETURN(-1);
info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
info->int_keypos=info->int_maxpos=page;
@@ -1373,22 +1596,22 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
** Functions to store and pack a key in a page
**
** mi_calc_xx_key_length takes the following arguments:
-** nod_flag If nod: Length of nod-pointer
-** next_key Position to pos after the new key in buffer
-** org_key Key that was before the next key in buffer
-** prev_key Last key before current key
-** key Key that will be stored
-** s_temp Information how next key will be packed
+** nod_flag If nod: Length of nod-pointer
+** next_key Position to pos after the new key in buffer
+** org_key Key that was before the next key in buffer
+** prev_key Last key before current key
+** key Key that will be stored
+** s_temp Information how next key will be packed
****************************************************************************/
/* Static length key */
int
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
- uchar *next_pos __attribute__((unused)),
- uchar *org_key __attribute__((unused)),
- uchar *prev_key __attribute__((unused)),
- uchar *key, MI_KEY_PARAM *s_temp)
+ uchar *next_pos __attribute__((unused)),
+ uchar *org_key __attribute__((unused)),
+ uchar *prev_key __attribute__((unused)),
+ uchar *key, MI_KEY_PARAM *s_temp)
{
s_temp->key=key;
return (int) (s_temp->totlength=keyinfo->keylength+nod_flag);
@@ -1398,10 +1621,10 @@ _mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
int
_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
- uchar *next_pos __attribute__((unused)),
- uchar *org_key __attribute__((unused)),
- uchar *prev_key __attribute__((unused)),
- uchar *key, MI_KEY_PARAM *s_temp)
+ uchar *next_pos __attribute__((unused)),
+ uchar *org_key __attribute__((unused)),
+ uchar *prev_key __attribute__((unused)),
+ uchar *key, MI_KEY_PARAM *s_temp)
{
s_temp->key=key;
return (int) (s_temp->totlength=_mi_keylength(keyinfo,key)+nod_flag);
@@ -1416,10 +1639,10 @@ _mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
If the max length of first key segment <= 127 characters the prefix is
1 byte else it's 2 byte
- prefix byte The high bit is set if this is a prefix for the prev key
- length Packed length if the previous was a prefix byte
- [length] Length character of data
- next-key-seg Next key segments
+ prefix byte The high bit is set if this is a prefix for the prev key
+ length Packed length if the previous was a prefix byte
+ [length] Length character of data
+ next-key-seg Next key segments
If the first segment can have NULL:
The length is 0 for NULLS and 1+length for not null columns.
@@ -1428,8 +1651,8 @@ _mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
int
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
- uchar *org_key, uchar *prev_key, uchar *key,
- MI_KEY_PARAM *s_temp)
+ uchar *org_key, uchar *prev_key, uchar *key,
+ MI_KEY_PARAM *s_temp)
{
reg1 MI_KEYSEG *keyseg;
int length;
@@ -1470,15 +1693,15 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
s_temp->key=key;
s_temp->ref_length=s_temp->key_length=0;
s_temp->totlength=key_length-1+diff_flag;
- s_temp->next_key_pos=0; /* No next key */
+ s_temp->next_key_pos=0; /* No next key */
return (s_temp->totlength);
}
s_temp->store_not_null=1;
- key_length--; /* We don't store NULL */
+ key_length--; /* We don't store NULL */
if (prev_key && !*prev_key++)
- org_key=prev_key=0; /* Can't pack against prev */
+ org_key=prev_key=0; /* Can't pack against prev */
else if (org_key)
- org_key++; /* Skipp NULL */
+ org_key++; /* Skipp NULL */
}
else
s_temp->store_not_null=0;
@@ -1494,14 +1717,14 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
if (prev_key)
{
get_key_length(org_key_length,prev_key);
- s_temp->prev_key=prev_key; /* Pointer at data */
+ s_temp->prev_key=prev_key; /* Pointer at data */
/* Don't use key-pack if length == 0 */
if (new_key_length && new_key_length == org_key_length)
same_length=1;
else if (new_key_length > org_key_length)
end=key + org_key_length;
- if (sort_order) /* SerG */
+ if (sort_order) /* SerG */
{
while (key < end && sort_order[*key] == sort_order[*prev_key])
{
@@ -1512,7 +1735,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
{
while (key < end && *key == *prev_key)
{
- key++; prev_key++;
+ key++; prev_key++;
}
}
}
@@ -1527,15 +1750,15 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
length=(int) key_length-(int) (key_end-start)-length_pack;
length+= diff_flag;
if (next_key)
- { /* Can't combine with next */
- s_temp->n_length= *next_key; /* Needed by _mi_store_key */
+ { /* Can't combine with next */
+ s_temp->n_length= *next_key; /* Needed by _mi_store_key */
next_key=0;
}
}
else
{
if (start != key)
- { /* Starts as prev key */
+ { /* Starts as prev key */
ref_length= (uint) (key-start);
s_temp->ref_length= ref_length + pack_marker;
length= (int) (key_length - ref_length);
@@ -1546,16 +1769,16 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
}
else
{
- s_temp->key_length+=s_temp->store_not_null; /* If null */
+ s_temp->key_length+=s_temp->store_not_null; /* If null */
length= key_length - length_pack+ diff_flag;
}
}
s_temp->totlength=(uint) length;
s_temp->prev_length=0;
DBUG_PRINT("test",("tot_length: %d length: %d uniq_key_length: %d",
- key_length,length,s_temp->key_length));
+ key_length,length,s_temp->key_length));
- /* If something after that hasn't length=0, test if we can combine */
+ /* If something after that hasn't length=0, test if we can combine */
if ((s_temp->next_key_pos=next_key))
{
uint packed,n_length;
@@ -1571,134 +1794,134 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
if (!packed)
n_length-= s_temp->store_not_null;
- if (n_length || packed) /* Don't pack 0 length keys */
+ if (n_length || packed) /* Don't pack 0 length keys */
{
uint next_length_pack, new_ref_length=s_temp->ref_length;
if (packed)
{
- /* If first key and next key is packed (only on delete) */
- if (!prev_key && org_key)
- {
- get_key_length(org_key_length,org_key);
- key=start;
- if (sort_order) /* SerG */
- {
- while (key < end && sort_order[*key] == sort_order[*org_key])
- {
- key++; org_key++;
- }
- }
- else
- {
- while (key < end && *key == *org_key)
- {
- key++; org_key++;
- }
- }
- if ((new_ref_length= (uint) (key - start)))
- new_ref_length+=pack_marker;
- }
-
- if (!n_length)
- {
- /*
- We put a different key between two identical variable length keys
- Extend next key to have same prefix as this key
- */
- if (new_ref_length) /* prefix of previus key */
- { /* make next key longer */
- s_temp->part_of_prev_key= new_ref_length;
- s_temp->prev_length= org_key_length -
- (new_ref_length-pack_marker);
- s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length;
- n_length= get_pack_length(s_temp->prev_length);
- s_temp->prev_key+= (new_ref_length - pack_marker);
- length+= s_temp->prev_length + n_length;
- }
- else
- { /* Can't use prev key */
- s_temp->part_of_prev_key=0;
- s_temp->prev_length= org_key_length;
- s_temp->n_ref_length=s_temp->n_length= org_key_length;
- length+= org_key_length;
- /* +get_pack_length(org_key_length); */
- }
- return (int) length;
- }
-
- ref_length=n_length;
- get_key_pack_length(n_length,next_length_pack,next_key);
-
- /* Test if new keys has fewer characters that match the previous key */
- if (!new_ref_length)
- { /* Can't use prev key */
- s_temp->part_of_prev_key= 0;
- s_temp->prev_length= ref_length;
- s_temp->n_ref_length= s_temp->n_length= n_length+ref_length;
- /* s_temp->prev_key+= get_pack_length(org_key_length); */
- return (int) length+ref_length-next_length_pack;
- }
- if (ref_length+pack_marker > new_ref_length)
- {
- uint new_pack_length=new_ref_length-pack_marker;
- /* We must copy characters from the original key to the next key */
- s_temp->part_of_prev_key= new_ref_length;
- s_temp->prev_length= ref_length - new_pack_length;
- s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
- s_temp->prev_key+= new_pack_length;
-/* +get_pack_length(org_key_length); */
- length= length-get_pack_length(ref_length)+
- get_pack_length(new_pack_length);
- return (int) length + s_temp->prev_length;
- }
+ /* If first key and next key is packed (only on delete) */
+ if (!prev_key && org_key)
+ {
+ get_key_length(org_key_length,org_key);
+ key=start;
+ if (sort_order) /* SerG */
+ {
+ while (key < end && sort_order[*key] == sort_order[*org_key])
+ {
+ key++; org_key++;
+ }
+ }
+ else
+ {
+ while (key < end && *key == *org_key)
+ {
+ key++; org_key++;
+ }
+ }
+ if ((new_ref_length= (uint) (key - start)))
+ new_ref_length+=pack_marker;
+ }
+
+ if (!n_length)
+ {
+ /*
+ We put a different key between two identical variable length keys
+ Extend next key to have same prefix as this key
+ */
+ if (new_ref_length) /* prefix of previus key */
+ { /* make next key longer */
+ s_temp->part_of_prev_key= new_ref_length;
+ s_temp->prev_length= org_key_length -
+ (new_ref_length-pack_marker);
+ s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length;
+ n_length= get_pack_length(s_temp->prev_length);
+ s_temp->prev_key+= (new_ref_length - pack_marker);
+ length+= s_temp->prev_length + n_length;
+ }
+ else
+ { /* Can't use prev key */
+ s_temp->part_of_prev_key=0;
+ s_temp->prev_length= org_key_length;
+ s_temp->n_ref_length=s_temp->n_length= org_key_length;
+ length+= org_key_length;
+ /* +get_pack_length(org_key_length); */
+ }
+ return (int) length;
+ }
+
+ ref_length=n_length;
+ get_key_pack_length(n_length,next_length_pack,next_key);
+
+ /* Test if new keys has fewer characters that match the previous key */
+ if (!new_ref_length)
+ { /* Can't use prev key */
+ s_temp->part_of_prev_key= 0;
+ s_temp->prev_length= ref_length;
+ s_temp->n_ref_length= s_temp->n_length= n_length+ref_length;
+ /* s_temp->prev_key+= get_pack_length(org_key_length); */
+ return (int) length+ref_length-next_length_pack;
+ }
+ if (ref_length+pack_marker > new_ref_length)
+ {
+ uint new_pack_length=new_ref_length-pack_marker;
+ /* We must copy characters from the original key to the next key */
+ s_temp->part_of_prev_key= new_ref_length;
+ s_temp->prev_length= ref_length - new_pack_length;
+ s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
+ s_temp->prev_key+= new_pack_length;
+/* +get_pack_length(org_key_length); */
+ length= length-get_pack_length(ref_length)+
+ get_pack_length(new_pack_length);
+ return (int) length + s_temp->prev_length;
+ }
}
else
{
- /* Next key wasn't a prefix of previous key */
- ref_length=0;
- next_length_pack=0;
+ /* Next key wasn't a prefix of previous key */
+ ref_length=0;
+ next_length_pack=0;
}
DBUG_PRINT("test",("length: %d next_key: %lx",length,next_key));
{
- uint tmp_length;
- key=(start+=ref_length);
- if (key+n_length < key_end) /* Normalize length based */
- key_end=key+n_length;
- if (sort_order) /* SerG */
- {
+ uint tmp_length;
+ key=(start+=ref_length);
+ if (key+n_length < key_end) /* Normalize length based */
+ key_end=key+n_length;
+ if (sort_order) /* SerG */
+ {
while (key < key_end && sort_order[*key] ==
- sort_order[*next_key])
- {
- key++; next_key++;
- }
- }
- else
- {
- while (key < key_end && *key == *next_key)
- {
- key++; next_key++;
- }
- }
- if (!(tmp_length=(uint) (key-start)))
- { /* Key can't be re-packed */
- s_temp->next_key_pos=0;
- return length;
- }
- ref_length+=tmp_length;
- n_length-=tmp_length;
- length-=tmp_length+next_length_pack; /* We gained these chars */
+ sort_order[*next_key])
+ {
+ key++; next_key++;
+ }
+ }
+ else
+ {
+ while (key < key_end && *key == *next_key)
+ {
+ key++; next_key++;
+ }
+ }
+ if (!(tmp_length=(uint) (key-start)))
+ { /* Key can't be re-packed */
+ s_temp->next_key_pos=0;
+ return length;
+ }
+ ref_length+=tmp_length;
+ n_length-=tmp_length;
+ length-=tmp_length+next_length_pack; /* We gained these chars */
}
if (n_length == 0)
{
- s_temp->n_ref_length=pack_marker; /* Same as prev key */
+ s_temp->n_ref_length=pack_marker; /* Same as prev key */
}
else
{
- s_temp->n_ref_length=ref_length | pack_marker;
- length+= get_pack_length(n_length);
- s_temp->n_length=n_length;
+ s_temp->n_ref_length=ref_length | pack_marker;
+ length+= get_pack_length(n_length);
+ s_temp->n_length=n_length;
}
}
}
@@ -1710,15 +1933,15 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
int
_mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
- uchar *org_key, uchar *prev_key, uchar *key,
- MI_KEY_PARAM *s_temp)
+ uchar *org_key, uchar *prev_key, uchar *key,
+ MI_KEY_PARAM *s_temp)
{
uint length,key_length,ref_length;
s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag;
s_temp->key=key;
s_temp->prev_key=org_key;
- if (prev_key) /* If not first key in block */
+ if (prev_key) /* If not first key in block */
{
/* pack key against previous key */
/*
@@ -1737,7 +1960,7 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
s_temp->ref_length=ref_length=0;
length=key_length+1;
}
- if ((s_temp->next_key_pos=next_key)) /* If another key after */
+ if ((s_temp->next_key_pos=next_key)) /* If another key after */
{
/* pack key against next key */
uint next_length,next_length_pack;
@@ -1748,21 +1971,21 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
{
uchar *end;
for (key= s_temp->key, end=key+next_length ;
- *key == *org_key && key < end;
- key++,org_key++) ;
+ *key == *org_key && key < end;
+ key++,org_key++) ;
ref_length= (uint) (key - s_temp->key);
}
if (next_length > ref_length)
{
/* We put a key with different case between two keys with the same prefix
- Extend next key to have same prefix as
- this key */
+ Extend next key to have same prefix as
+ this key */
s_temp->n_ref_length= ref_length;
s_temp->prev_length= next_length-ref_length;
s_temp->prev_key+= ref_length;
return (int) (length+ s_temp->prev_length - next_length_pack +
- get_pack_length(ref_length));
+ get_pack_length(ref_length));
}
/* Check how many characters are identical to next key */
key= s_temp->key+next_length;
@@ -1770,12 +1993,12 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
{
s_temp->next_key_pos=0;
- return length; /* can't pack next key */
+ return length; /* can't pack next key */
}
s_temp->prev_length=0;
s_temp->n_ref_length=ref_length;
return (int) (length-(ref_length - next_length) - next_length_pack +
- get_pack_length(ref_length));
+ get_pack_length(ref_length));
}
return (int) length;
}
@@ -1788,8 +2011,8 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
/* store key without compression */
void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
- register MI_KEY_PARAM *s_temp)
+ register uchar *key_pos,
+ register MI_KEY_PARAM *s_temp)
{
memcpy((byte*) key_pos,(byte*) s_temp->key,(size_t) s_temp->totlength);
}
@@ -1803,8 +2026,8 @@ void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)),
void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
- register MI_KEY_PARAM *s_temp)
+ register uchar *key_pos,
+ register MI_KEY_PARAM *s_temp)
{
uint length;
uchar *start;
@@ -1825,9 +2048,9 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->key_length);
}
bmove((byte*) key_pos,(byte*) s_temp->key,
- (length=s_temp->totlength-(uint) (key_pos-start)));
+ (length=s_temp->totlength-(uint) (key_pos-start)));
- if (!s_temp->next_key_pos) /* No following key */
+ if (!s_temp->next_key_pos) /* No following key */
return;
key_pos+=length;
@@ -1837,14 +2060,14 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
if (s_temp->part_of_prev_key)
{
store_pack_length(s_temp->pack_marker == 128,key_pos,
- s_temp->part_of_prev_key);
+ s_temp->part_of_prev_key);
store_key_length_inc(key_pos,s_temp->n_length);
}
else
{
s_temp->n_length+= s_temp->store_not_null;
store_pack_length(s_temp->pack_marker == 128,key_pos,
- s_temp->n_length);
+ s_temp->n_length);
}
memcpy(key_pos, s_temp->prev_key, s_temp->prev_length);
}
@@ -1852,7 +2075,7 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
{
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_ref_length);
if (s_temp->n_ref_length == s_temp->pack_marker)
- return; /* Identical key */
+ return; /* Identical key */
store_key_length(key_pos,s_temp->n_length);
}
else
@@ -1866,18 +2089,18 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
/* variable length key with prefix compression */
void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
- register MI_KEY_PARAM *s_temp)
+ register uchar *key_pos,
+ register MI_KEY_PARAM *s_temp)
{
store_key_length_inc(key_pos,s_temp->ref_length);
memcpy((char*) key_pos,(char*) s_temp->key+s_temp->ref_length,
- (size_t) s_temp->totlength-s_temp->ref_length);
+ (size_t) s_temp->totlength-s_temp->ref_length);
if (s_temp->next_key_pos)
{
key_pos+=(uint) (s_temp->totlength-s_temp->ref_length);
store_key_length_inc(key_pos,s_temp->n_ref_length);
- if (s_temp->prev_length) /* If we must extend key */
+ if (s_temp->prev_length) /* If we must extend key */
{
memcpy(key_pos,s_temp->prev_key,s_temp->prev_length);
}
diff --git a/myisam/mi_static.c b/myisam/mi_static.c
index f790f90ca78..37b9ac04b7a 100644
--- a/myisam/mi_static.c
+++ b/myisam/mi_static.c
@@ -1,21 +1,21 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
- Static variables for pisam library. All definied here for easy making of
+ Static variables for MyISAM library. All definied here for easy making of
a shared library
*/
@@ -32,7 +32,7 @@ my_string myisam_log_filename=(char*) "myisam.log";
File myisam_log_file= -1;
uint myisam_quick_table_bits=9;
uint myisam_block_size=MI_KEY_BLOCK_LENGTH; /* Best by test */
-my_bool myisam_flush=0,myisam_delay_key_write=0;
+my_bool myisam_flush=0, myisam_delay_key_write=0, myisam_single_user=0;
#if defined(THREAD) && !defined(DONT_USE_RW_LOCKS)
my_bool myisam_concurrent_insert=1;
#else
@@ -40,10 +40,12 @@ my_bool myisam_concurrent_insert=0;
#endif
my_off_t myisam_max_extra_temp_length= MI_MAX_TEMP_LENGTH;
my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
+ulong myisam_bulk_insert_tree_size=8192*1024;
-
-/* read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ */
-/* Position is , == , >= , <= , > , < */
+/*
+ read_vec[] is used for converting between P_READ_KEY.. and SEARCH_
+ Position is , == , >= , <= , > , <
+*/
uint NEAR myisam_read_vec[]=
{
diff --git a/myisam/mi_statrec.c b/myisam/mi_statrec.c
index 05ff40d8921..9afebce2ae6 100644
--- a/myisam/mi_statrec.c
+++ b/myisam/mi_statrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -27,17 +27,16 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
{
my_off_t filepos=info->s->state.dellink;
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,info->s->state.dellink+1,MY_SEEK_SET,MYF(0)));
-
- if (my_read(info->dfile,(char*) &temp[0],info->s->base.rec_reflength,
- MYF(MY_NABP)))
+ if (my_pread(info->dfile,(char*) &temp[0],info->s->base.rec_reflength,
+ info->s->state.dellink+1,
+ MYF(MY_NABP)))
goto err;
info->s->state.dellink= _mi_rec_pos(info->s,temp);
info->state->del--;
info->state->empty-=info->s->base.pack_reclength;
- VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0)));
- if (my_write(info->dfile, (char*) record, info->s->base.reclength,
- MYF(MY_NABP)))
+ if (my_pwrite(info->dfile, (char*) record, info->s->base.reclength,
+ filepos,
+ MYF(MY_NABP)))
goto err;
}
else
@@ -64,16 +63,18 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
else
{
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,info->state->data_file_length,
- MY_SEEK_SET,MYF(0)));
- if (my_write(info->dfile,(char*) record,info->s->base.reclength,
- info->s->write_flag))
+ if (my_pwrite(info->dfile,(char*) record,info->s->base.reclength,
+ info->state->data_file_length,
+ info->s->write_flag))
goto err;
if (info->s->base.pack_reclength != info->s->base.reclength)
{
uint length=info->s->base.pack_reclength - info->s->base.reclength;
bzero((char*) temp,length);
- if (my_write(info->dfile, (byte*) temp,length, info->s->write_flag))
+ if (my_pwrite(info->dfile, (byte*) temp,length,
+ info->state->data_file_length+
+ info->s->base.reclength,
+ info->s->write_flag))
goto err;
}
}
@@ -88,9 +89,10 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
int _mi_update_static_record(MI_INFO *info, my_off_t pos, const byte *record)
{
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,pos,MY_SEEK_SET,MYF(0)));
- return (my_write(info->dfile,(char*) record,info->s->base.reclength,
- MYF(MY_NABP)) != 0);
+ return (my_pwrite(info->dfile,
+ (char*) record,info->s->base.reclength,
+ pos,
+ MYF(MY_NABP)) != 0);
}
@@ -104,9 +106,8 @@ int _mi_delete_static_record(MI_INFO *info)
_mi_dpointer(info,temp+1,info->s->state.dellink);
info->s->state.dellink = info->lastpos;
info->rec_cache.seek_not_done=1;
- VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0)));
- return (my_write(info->dfile,(byte*) temp, 1+info->s->rec_reflength,
- MYF(MY_NABP)) != 0);
+ return (my_pwrite(info->dfile,(byte*) temp, 1+info->s->rec_reflength,
+ info->lastpos, MYF(MY_NABP)) != 0);
}
@@ -129,9 +130,9 @@ int _mi_cmp_static_record(register MI_INFO *info, register const byte *old)
if ((info->opt_flag & READ_CHECK_USED))
{ /* If check isn't disabled */
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0)));
- if (my_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
- MYF(MY_NABP)))
+ if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
+ info->lastpos,
+ MYF(MY_NABP)))
DBUG_RETURN(-1);
if (memcmp((byte*) info->rec_buff, (byte*) old,
(uint) info->s->base.reclength))
@@ -152,9 +153,8 @@ int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def,
DBUG_ENTER("_mi_cmp_static_unique");
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,pos,MY_SEEK_SET,MYF(0)));
- if (my_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
- MYF(MY_NABP)))
+ if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
+ pos, MYF(MY_NABP)))
DBUG_RETURN(-1);
DBUG_RETURN(mi_unique_comp(def, record, info->rec_buff,
def->null_are_equal));
@@ -181,8 +181,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos,
error=my_pread(info->dfile,(char*) record,info->s->base.reclength,
pos,MYF(MY_NABP)) != 0;
- if (info->s->r_locks == 0 && info->s->w_locks == 0)
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (! error)
{
if (!*record)
@@ -195,7 +194,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos,
}
return(-1); /* Error on read */
}
- VOID(_mi_writeinfo(info,0)); /* No such record */
+ fast_mi_writeinfo(info); /* No such record */
return(-1);
}
@@ -222,7 +221,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf,
(skipp_deleted_blocks || !filepos))
{
cache_read=1; /* Read record using cache */
- cache_length=(uint) (info->rec_cache.rc_end - info->rec_cache.rc_pos);
+ cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos);
}
else
info->rec_cache.seek_not_done=1; /* Filepos is changed */
@@ -240,7 +239,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf,
{ /* We don't nead new info */
#ifndef UNSAFE_LOCKING
if ((! cache_read || share->base.reclength > cache_length) &&
- share->r_locks == 0 && share->w_locks == 0)
+ share->tot_locks == 0)
{ /* record not in cache */
if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
@@ -257,7 +256,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf,
DBUG_PRINT("test",("filepos: %ld (%ld) records: %ld del: %ld",
filepos/share->base.reclength,filepos,
info->state->records, info->state->del));
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE);
}
info->lastpos= filepos;
diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c
index ae09bd4142e..bcb9cd172ec 100644
--- a/myisam/mi_test1.c
+++ b/myisam/mi_test1.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -17,20 +17,23 @@
/* Testing of the basic functions of a MyISAM table */
#include "myisam.h"
-#include <getopt.h>
+#include <my_getopt.h>
#include <m_string.h>
#define MAX_REC_LENGTH 1024
-static int rec_pointer_size=0,verbose=0,flags[50];
-static int key_field=FIELD_SKIPP_PRESPACE,extra_field=FIELD_SKIPP_ENDSPACE;
+static void usage();
+
+static int rec_pointer_size=0, flags[50];
+static int key_field=FIELD_SKIP_PRESPACE,extra_field=FIELD_SKIP_ENDSPACE;
static int key_type=HA_KEYTYPE_NUM;
static int create_flag=0;
-static uint insert_count= 1000,update_count=1000,remove_count=1000;
-static uint pack_keys=0,pack_seg=0,null_fields=0,key_length=6,skip_update=0;
-static uint unique_key=HA_NOSAME,key_cacheing=0,opt_unique=0;
-static uint silent;
+static uint insert_count, update_count, remove_count;
+static uint pack_keys=0, pack_seg=0, key_length;
+static uint unique_key=HA_NOSAME;
+static my_bool key_cacheing, null_fields, silent, skip_update, opt_unique,
+ verbose;
static MI_COLUMNDEF recinfo[4];
static MI_KEYDEF keyinfo[10];
static MI_KEYSEG keyseg[10];
@@ -47,7 +50,7 @@ int main(int argc,char *argv[])
MY_INIT(argv[0]);
my_init();
if (key_cacheing)
- init_key_cache(IO_SIZE*16,(uint) IO_SIZE*4*10);
+ init_key_cache(IO_SIZE*16);
get_options(argc,argv);
exit(run_test("test1"));
@@ -501,139 +504,155 @@ static void update_record(char *record)
}
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"checksum", no_argument, 0, 'c'},
+ {"checksum", 'c', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", required_argument, 0, '#'},
+ {"debug", '#', "Undocumented",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"delete_rows", required_argument, 0, 'd'},
- {"help", no_argument, 0, '?'},
- {"insert_rows", required_argument, 0, 'i'},
- {"key_alpha", no_argument, 0, 'a'},
- {"key_binary_pack", no_argument, 0, 'B'},
- {"key_blob", required_argument, 0, 'b'},
- {"key_cache", no_argument, 0, 'K'},
- {"key_length", required_argument, 0, 'k'},
- {"key_multiple", no_argument, 0, 'm'},
- {"key_prefix_pack", no_argument, 0, 'P'},
- {"key_space_pack", no_argument, 0, 'p'},
- {"key_varchar", no_argument, 0, 'w'},
- {"null_fields", no_argument, 0, 'N'},
- {"row_fixed_size", no_argument, 0, 'S'},
- {"row_pointer_size", required_argument, 0, 'R'},
- {"silent", no_argument, 0, 's'},
- {"skip_update", no_argument, 0, 'U'},
- {"unique", no_argument, 0, 'C'},
- {"update_rows", required_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"delete_rows", 'd', "Undocumented", (gptr*) &remove_count,
+ (gptr*) &remove_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"help", '?', "Display help and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"insert_rows", 'i', "Undocumented", (gptr*) &insert_count,
+ (gptr*) &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"key_alpha", 'a', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_binary_pack", 'B', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_blob", 'b', "Undocumented",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_cache", 'K', "Undocumented", (gptr*) &key_cacheing,
+ (gptr*) &key_cacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_length", 'k', "Undocumented", (gptr*) &key_length, (gptr*) &key_length,
+ 0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0},
+ {"key_multiple", 'm', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_prefix_pack", 'P', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_space_pack", 'p', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_varchar", 'w', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"null_fields", 'N', "Undocumented",
+ (gptr*) &null_fields, (gptr*) &null_fields, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"row_fixed_size", 'S', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"row_pointer_size", 'R', "Undocumented", (gptr*) &rec_pointer_size,
+ (gptr*) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Undocumented",
+ (gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip_update", 'U', "Undocumented", (gptr*) &skip_update,
+ (gptr*) &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"unique", 'C', "Undocumented", (gptr*) &opt_unique, (gptr*) &opt_unique, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"update_rows", 'u', "Undocumented", (gptr*) &update_count,
+ (gptr*) &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Be more verbose", (gptr*) &verbose, (gptr*) &verbose, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Print version number and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'a':
+ key_type= HA_KEYTYPE_TEXT;
+ break;
+ case 'c':
+ create_flag|= HA_CREATE_CHECKSUM;
+ break;
+ case 'R': /* Length of record pointer */
+ if (rec_pointer_size > 3)
+ rec_pointer_size=0;
+ break;
+ case 'P':
+ pack_keys= HA_PACK_KEY; /* Use prefix compression */
+ break;
+ case 'B':
+ pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */
+ break;
+ case 'S':
+ if (key_field == FIELD_VARCHAR)
+ {
+ create_flag=0; /* Static sized varchar */
+ }
+ else if (key_field != FIELD_BLOB)
+ {
+ key_field=FIELD_NORMAL; /* static-size record */
+ extra_field=FIELD_NORMAL;
+ }
+ break;
+ case 'p':
+ pack_keys=HA_PACK_KEY; /* Use prefix + space packing */
+ pack_seg=HA_SPACE_PACK;
+ key_type=HA_KEYTYPE_TEXT;
+ break;
+ case 'm':
+ unique_key=0;
+ break;
+ case 'b':
+ key_field=FIELD_BLOB; /* blob key */
+ extra_field= FIELD_BLOB;
+ pack_seg|= HA_BLOB_PART;
+ key_type= HA_KEYTYPE_VARTEXT;
+ break;
+ case 'k':
+ if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH)
+ {
+ fprintf(stderr,"Wrong key length\n");
+ exit(1);
+ }
+ break;
+ case 'w':
+ key_field=FIELD_VARCHAR; /* varchar keys */
+ extra_field= FIELD_VARCHAR;
+ key_type= HA_KEYTYPE_VARTEXT;
+ pack_seg|= HA_VAR_LENGTH;
+ create_flag|= HA_PACK_RECORD;
+ break;
+ case 'K': /* Use key cacheing */
+ key_cacheing=1;
+ break;
+ case 'V':
+ printf("test1 Ver 1.2 \n");
+ exit(0);
+ case '#':
+ DEBUGGER_ON;
+ DBUG_PUSH (argument);
+ break;
+ case '?':
+ usage();
+ exit(1);
+ }
+ return 0;
+}
+
+
/* Read options */
-static void get_options(int argc,char *argv[])
+static void get_options(int argc, char *argv[])
{
- int c,option_index=0;
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
- while ((c=getopt_long(argc,argv,"abBcCd:i:k:KmPR:SspNu:UvVw#:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
- key_type= HA_KEYTYPE_TEXT;
- break;
- case 'c':
- create_flag|= HA_CREATE_CHECKSUM;
- break;
- case 'C':
- opt_unique=1;
- break;
- case 'R': /* Length of record pointer */
- rec_pointer_size=atoi(optarg);
- if (rec_pointer_size > 3)
- rec_pointer_size=0;
- break;
- case 'P':
- pack_keys= HA_PACK_KEY; /* Use prefix compression */
- break;
- case 'B':
- pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */
- break;
- case 'S':
- if (key_field == FIELD_VARCHAR)
- {
- create_flag=0; /* Static sized varchar */
- }
- else if (key_field != FIELD_BLOB)
- {
- key_field=FIELD_NORMAL; /* static-size record */
- extra_field=FIELD_NORMAL;
- }
- break;
- case 'p':
- pack_keys=HA_PACK_KEY; /* Use prefix + space packing */
- pack_seg=HA_SPACE_PACK;
- key_type=HA_KEYTYPE_TEXT;
- break;
- case 'N':
- null_fields=1; /* First key part may be null */
- break;
- case 'v': /* verbose */
- verbose=1;
- break;
- case 'd':
- remove_count=atoi(optarg);
- break;
- case 'i':
- insert_count=atoi(optarg);
- break;
- case 'u':
- update_count=atoi(optarg);
- break;
- case 'U':
- skip_update=1;
- break;
- case 'm':
- unique_key=0;
- break;
- case 'b':
- key_field=FIELD_BLOB; /* blob key */
- extra_field= FIELD_BLOB;
- pack_seg|= HA_BLOB_PART;
- key_type= HA_KEYTYPE_VARTEXT;
- break;
- case 'k':
- key_length=atoi(optarg);
- if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH)
- {
- fprintf(stderr,"Wrong key length\n");
- exit(1);
- }
- break;
- case 's':
- silent=1;
- break;
- case 'w':
- key_field=FIELD_VARCHAR; /* varchar keys */
- extra_field= FIELD_VARCHAR;
- key_type= HA_KEYTYPE_VARTEXT;
- pack_seg|= HA_VAR_LENGTH;
- create_flag|= HA_PACK_RECORD;
- break;
- case 'K': /* Use key cacheing */
- key_cacheing=1;
- break;
- case 'V':
- printf("test1 Ver 1.0 \n");
- exit(0);
- case '#':
- DEBUGGER_ON;
- DBUG_PUSH (optarg);
- break;
- }
- }
return;
} /* get options */
+
+
+static void usage()
+{
+ printf("Usage: %s [options]\n\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c
index b66b02afdf9..93538e3ead7 100644
--- a/myisam/mi_test2.c
+++ b/myisam/mi_test2.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -148,15 +148,15 @@ int main(int argc, char *argv[])
keyinfo[5].keysegs=1;
keyinfo[5].flag = pack_type;
- recinfo[0].type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[0].length=7;
recinfo[0].null_bit=0;
recinfo[0].null_pos=0;
- recinfo[1].type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[1].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[1].length=5;
recinfo[1].null_bit=0;
recinfo[1].null_pos=0;
- recinfo[2].type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[2].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[2].length=9;
recinfo[2].null_bit=0;
recinfo[2].null_pos=0;
@@ -164,11 +164,11 @@ int main(int argc, char *argv[])
recinfo[3].length=STANDARD_LENGTH-7-5-9-4;
recinfo[3].null_bit=0;
recinfo[3].null_pos=0;
- recinfo[4].type=pack_fields ? FIELD_SKIPP_ZERO : 0;
+ recinfo[4].type=pack_fields ? FIELD_SKIP_ZERO : 0;
recinfo[4].length=4;
recinfo[4].null_bit=0;
recinfo[4].null_pos=0;
- recinfo[5].type=pack_fields ? FIELD_SKIPP_ENDSPACE : 0;
+ recinfo[5].type=pack_fields ? FIELD_SKIP_ENDSPACE : 0;
recinfo[5].length=60;
recinfo[5].null_bit=0;
recinfo[5].null_pos=0;
@@ -208,13 +208,13 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Writing key:s\n");
if (key_cacheing)
- init_key_cache(key_cache_size,(uint) IO_SIZE*4*10); /* Use a small cache */
+ init_key_cache(key_cache_size); /* Use a small cache */
if (locking)
mi_lock_database(file,F_WRLCK);
if (write_cacheing)
- mi_extra(file,HA_EXTRA_WRITE_CACHE);
+ mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
if (opt_quick_mode)
- mi_extra(file,HA_EXTRA_QUICK);
+ mi_extra(file,HA_EXTRA_QUICK,0);
for (i=0 ; i < recant ; i++)
{
@@ -261,11 +261,15 @@ int main(int argc, char *argv[])
if (testflag==1) goto end;
if (write_cacheing)
- if (mi_extra(file,HA_EXTRA_NO_CACHE))
+ {
+ if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
{
puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
goto end;
}
+ if (key_cacheing)
+ resize_key_cache(key_cache_size*2);
+ }
if (!silent)
printf("- Delete\n");
@@ -341,70 +345,81 @@ int main(int argc, char *argv[])
}
}
}
- if (testflag==3) goto end;
+ if (testflag == 3)
+ goto end;
- if (!silent)
- printf("- Same key: first - next -> last - prev -> first\n");
- DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
for (i=999, dupp_keys=j=0 ; i>0 ; i--)
{
- if (key1[i] >dupp_keys) { dupp_keys=key1[i]; j=i; }
+ if (key1[i] > dupp_keys)
+ {
+ dupp_keys=key1[i]; j=i;
+ }
}
sprintf(key,"%6d",j);
- if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err;
- if (mi_rsame(file,read_record2,-1)) goto err;
- if (memcmp(read_record,read_record2,reclength) != 0)
- {
- printf("mi_rsame didn't find same record\n");
- goto end;
- }
- info.recpos=mi_position(file);
- if (mi_rfirst(file,read_record2,0) ||
- mi_rsame_with_pos(file,read_record2,0,info.recpos) ||
- memcmp(read_record,read_record2,reclength) != 0)
+ start=keyinfo[0].seg[0].start;
+ length=keyinfo[0].seg[0].length;
+ if (dupp_keys)
{
- printf("mi_rsame_with_pos didn't find same record\n");
- goto end;
- }
- {
- int skr=mi_rnext(file,read_record2,0);
- if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
- mi_rprev(file,read_record2,-1) ||
+ if (!silent)
+ printf("- Same key: first - next -> last - prev -> first\n");
+ DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
+ if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
+
+ if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ goto err;
+ if (mi_rsame(file,read_record2,-1))
+ goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+ {
+ printf("mi_rsame didn't find same record\n");
+ goto end;
+ }
+ info.recpos=mi_position(file);
+ if (mi_rfirst(file,read_record2,0) ||
+ mi_rsame_with_pos(file,read_record2,0,info.recpos) ||
memcmp(read_record,read_record2,reclength) != 0)
{
- printf("mi_rsame_with_pos lost position\n");
+ printf("mi_rsame_with_pos didn't find same record\n");
+ goto end;
+ }
+ {
+ int skr=mi_rnext(file,read_record2,0);
+ if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
+ mi_rprev(file,read_record2,-1) ||
+ memcmp(read_record,read_record2,reclength) != 0)
+ {
+ printf("mi_rsame_with_pos lost position\n");
+ goto end;
+ }
+ }
+ ant=1;
+ while (mi_rnext(file,read_record2,0) == 0 &&
+ memcmp(read_record2+start,key,length) == 0) ant++;
+ if (ant != dupp_keys)
+ {
+ printf("next: Found: %d keys of %d\n",ant,dupp_keys);
+ goto end;
+ }
+ ant=0;
+ while (mi_rprev(file,read_record3,0) == 0 &&
+ bcmp(read_record3+start,key,length) == 0) ant++;
+ if (ant != dupp_keys)
+ {
+ printf("prev: Found: %d records of %d\n",ant,dupp_keys);
goto end;
}
- }
- ant=1;
- start=keyinfo[0].seg[0].start; length=keyinfo[0].seg[0].length;
- while (mi_rnext(file,read_record2,0) == 0 &&
- memcmp(read_record2+start,key,length) == 0) ant++;
- if (ant != dupp_keys)
- {
- printf("next: Found: %d keys of %d\n",ant,dupp_keys);
- goto end;
- }
- ant=0;
- while (mi_rprev(file,read_record3,0) == 0 &&
- bcmp(read_record3+start,key,length) == 0) ant++;
- if (ant != dupp_keys)
- {
- printf("prev: Found: %d records of %d\n",ant,dupp_keys);
- goto end;
- }
- /* Check of mi_rnext_same */
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
- goto err;
- ant=1;
- while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
- ant++;
- if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
- {
- printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
- goto end;
+ /* Check of mi_rnext_same */
+ if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ goto err;
+ ant=1;
+ while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
+ ant++;
+ if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
+ {
+ printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
+ goto end;
+ }
}
if (!silent)
@@ -666,7 +681,7 @@ int main(int argc, char *argv[])
if (!silent)
printf("- mi_extra(CACHE) + mi_rrnd.... + mi_extra(NO_CACHE)\n");
- if (mi_extra(file,HA_EXTRA_RESET) || mi_extra(file,HA_EXTRA_CACHE))
+ if (mi_extra(file,HA_EXTRA_RESET,0) || mi_extra(file,HA_EXTRA_CACHE,0))
{
if (locking || (!use_blob && !pack_fields))
{
@@ -684,7 +699,7 @@ int main(int argc, char *argv[])
ant,write_count-opt_delete);
goto end;
}
- if (mi_extra(file,HA_EXTRA_NO_CACHE))
+ if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
{
puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
goto end;
@@ -709,7 +724,7 @@ int main(int argc, char *argv[])
DBUG_PRINT("progpos",("Removing keys"));
lastpos = HA_OFFSET_ERROR;
/* DBUG_POP(); */
- mi_extra(file,HA_EXTRA_RESET);
+ mi_extra(file,HA_EXTRA_RESET,0);
found_parts=0;
while ((error=mi_rrnd(file,read_record,HA_OFFSET_ERROR)) !=
HA_ERR_END_OF_FILE)
@@ -776,9 +791,15 @@ end:
printf("\nFollowing test have been made:\n");
printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
if (rec_pointer_size)
- printf("Record pointer size: %d\n",rec_pointer_size);
+ printf("Record pointer size: %d\n",rec_pointer_size);
+ printf("myisam_block_size: %u\n", myisam_block_size);
if (key_cacheing)
- puts("Key cacheing used");
+ {
+ puts("Key cache used");
+ printf("key_cache_block_size: %u\n", key_cache_block_size);
+ if (write_cacheing)
+ puts("Key cache resized");
+ }
if (write_cacheing)
puts("Write cacheing used");
if (write_cacheing)
@@ -801,7 +822,7 @@ reads: %10lu\n",
end_key_cache();
if (blob_buffer)
my_free(blob_buffer,MYF(0));
- my_end(MY_CHECK_ERROR | MY_GIVE_INFO);
+ my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
return(0);
err:
printf("got error: %d when using MyISAM-database\n",my_errno);
@@ -861,7 +882,29 @@ static void get_options(int argc, char **argv)
verbose=1;
break;
case 'm': /* records */
- recant=atoi(++pos);
+ if ((recant=atoi(++pos)) < 10)
+ {
+ fprintf(stderr,"record count must be >= 10\n");
+ exit(1);
+ }
+ break;
+ case 'e': /* myisam_block_length */
+ if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
+ myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH)
+ {
+ fprintf(stderr,"Wrong myisam_block_length\n");
+ exit(1);
+ }
+ myisam_block_size=1 << my_bit_log2(myisam_block_size);
+ break;
+ case 'E': /* myisam_block_length */
+ if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
+ key_cache_block_size > MI_MAX_KEY_BLOCK_LENGTH)
+ {
+ fprintf(stderr,"Wrong key_cache_block_size\n");
+ exit(1);
+ }
+ key_cache_block_size=1 << my_bit_log2(key_cache_block_size);
break;
case 'f':
if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS)
@@ -904,7 +947,7 @@ static void get_options(int argc, char **argv)
case 'V':
printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
puts("By Monty, for your professional use\n");
- printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-t#]\n",
+ printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n",
progname);
exit(0);
case '#':
diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c
index 48325b2dcac..ac36f55a181 100644
--- a/myisam/mi_test3.c
+++ b/myisam/mi_test3.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -173,7 +173,7 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
- init_key_cache(65536L,(uint) IO_SIZE*4*10);
+ init_key_cache(65536L);
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
@@ -302,7 +302,7 @@ int test_rrnd(MI_INFO *file,int id)
return 1;
}
if (rnd(2) == 0)
- mi_extra(file,HA_EXTRA_CACHE);
+ mi_extra(file,HA_EXTRA_CACHE,0);
}
count=0;
@@ -323,7 +323,7 @@ int test_rrnd(MI_INFO *file,int id)
end:
if (lock)
{
- mi_extra(file,HA_EXTRA_NO_CACHE);
+ mi_extra(file,HA_EXTRA_NO_CACHE,0);
if (mi_lock_database(file,F_UNLCK))
{
fprintf(stderr,"%2d: Can't unlock table\n",id);
@@ -355,7 +355,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
return 1;
}
if (rnd(2) == 0)
- mi_extra(file,HA_EXTRA_WRITE_CACHE);
+ mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
}
sprintf(record.id,"%7d",getpid());
@@ -380,7 +380,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
}
if (lock)
{
- mi_extra(file,HA_EXTRA_NO_CACHE);
+ mi_extra(file,HA_EXTRA_NO_CACHE,0);
if (mi_lock_database(file,F_UNLCK))
{
fprintf(stderr,"%2d: Can't unlock table\n",id);
diff --git a/myisam/mi_test_all.res b/myisam/mi_test_all.res
index d6b4703d702..94355bf1aa2 100644
--- a/myisam/mi_test_all.res
+++ b/myisam/mi_test_all.res
@@ -1,48 +1,50 @@
-Maximum memory usage: 545477 bytes (533k)
-Maximum memory usage: 545477 bytes (533k)
-Maximum memory usage: 545369 bytes (533k)
-mi_test2-i686 -s -L -K -R1 -m2000 ; Should give error 135
+mi_test2 -s -L -K -R1 -m2000 ; Should give error 135
Error: 135 in write at record: 1105
got error: 135 when using MyISAM-database
-Maximum memory usage: 29439 bytes (29k)
-Maximum memory usage: 66541 bytes (65k)
-Maximum memory usage: 5101 bytes (5k)
-Maximum memory usage: 545488 bytes (533k)
+myisamchk: MyISAM file test2
+myisamchk: warning: Datafile is almost full, 65532 of 65534 used
+MyISAM-table 'test2' is usable but should be fixed
Commands Used count Errors Recover errors
-open 1 0 0
-write 50 0 0
-update 5 0 0
-delete 50 0 0
-close 1 0 0
-extra 6 0 0
-Total 113 0 0
-Maximum memory usage: 545744 bytes (533k)
+open 17 0 0
+write 850 0 0
+update 85 0 0
+delete 850 0 0
+close 17 0 0
+extra 102 0 0
+Total 1921 0 0
Commands Used count Errors Recover errors
-open 2 0 0
-write 100 0 0
-update 10 0 0
-delete 100 0 0
-close 2 0 0
-extra 12 0 0
-Total 226 0 0
-Maximum memory usage: 5101 bytes (5k)
-1.12user 0.52system 0:01.71elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (214major+25minor)pagefaults 0swaps
-Maximum memory usage: 21189 bytes (21k)
-1.29user 0.55system 0:01.82elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (215major+29minor)pagefaults 0swaps
-Maximum memory usage: 66541 bytes (65k)
-1.10user 0.51system 0:01.66elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (216major+40minor)pagefaults 0swaps
-Maximum memory usage: 82629 bytes (81k)
-1.33user 0.24system 0:01.54elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (216major+44minor)pagefaults 0swaps
-Maximum memory usage: 545477 bytes (533k)
-1.31user 0.24system 0:01.55elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (216major+173minor)pagefaults 0swaps
-Maximum memory usage: 545389 bytes (533k)
-1.37user 0.18system 0:01.57elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (218major+180minor)pagefaults 0swaps
-Maximum memory usage: 109165 bytes (107k)
-1.42user 0.38system 0:01.78elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (218major+51minor)pagefaults 0swaps
+open 18 0 0
+write 900 0 0
+update 90 0 0
+delete 900 0 0
+close 18 0 0
+extra 108 0 0
+Total 2034 0 0
+
+real 0m1.054s
+user 0m0.410s
+sys 0m0.640s
+
+real 0m1.077s
+user 0m0.550s
+sys 0m0.530s
+
+real 0m1.100s
+user 0m0.420s
+sys 0m0.680s
+
+real 0m0.783s
+user 0m0.590s
+sys 0m0.200s
+
+real 0m0.764s
+user 0m0.560s
+sys 0m0.210s
+
+real 0m0.699s
+user 0m0.570s
+sys 0m0.130s
+
+real 0m0.991s
+user 0m0.630s
+sys 0m0.350s
diff --git a/myisam/mi_test_all.sh b/myisam/mi_test_all.sh
index ccc9c39c64e..a2d57ea1a83 100755
--- a/myisam/mi_test_all.sh
+++ b/myisam/mi_test_all.sh
@@ -66,6 +66,14 @@ myisamchk$suffix -rs test1
myisamchk$suffix -se test1
myisamchk$suffix -rqs test1
myisamchk$suffix -se test1
+myisamchk$suffix -rs --correct-checksum test1
+myisamchk$suffix -se test1
+myisamchk$suffix -rqs --correct-checksum test1
+myisamchk$suffix -se test1
+myisamchk$suffix -ros --correct-checksum test1
+myisamchk$suffix -se test1
+myisamchk$suffix -rqos --correct-checksum test1
+myisamchk$suffix -se test1
# check of myisampack / myisamchk
myisampack$suffix --force -s test1
@@ -105,13 +113,25 @@ mi_test1$suffix $silent --key_multiple -P -S
myisamchk$suffix -sm test1
mi_test2$suffix $silent -L -K -W -P
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -W -P -A
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -W -P -S -R1 -m500
echo "mi_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135"
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -R1 -m2000
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -B
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -D -B -c
+myisamchk$suffix -sm test2
+mi_test2$suffix $silent -m10000 -e8192 -K
+myisamchk$suffix -sm test2
+mi_test2$suffix $silent -m10000 -e16384 -E16384 -K -L
+myisamchk$suffix -sm test2
+
mi_test2$suffix $silent -L -K -W -P -m50 -l
myisamlog$suffix
mi_test2$suffix $silent -L -K -W -P -m50 -l -b100
diff --git a/myisam/mi_unique.c b/myisam/mi_unique.c
index e598fbeedb4..5806502823a 100644
--- a/myisam/mi_unique.c
+++ b/myisam/mi_unique.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_update.c b/myisam/mi_update.c
index 185624f3878..2c6bc42bbdb 100644
--- a/myisam/mi_update.c
+++ b/myisam/mi_update.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -98,9 +98,7 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
if ((int) i == info->lastinx)
key_changed|=HA_STATE_WRITTEN;
changed|=((ulonglong) 1 << i);
- if (_mi_ft_del(info,i,(char*) old_key,oldrec,pos))
- goto err;
- if (_mi_ft_add(info,i,(char*) new_key,newrec,pos))
+ if (_mi_ft_update(info,i,(char*) old_key,oldrec,newrec,pos))
goto err;
}
}
@@ -138,6 +136,12 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0);
VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0));
allow_break(); /* Allow SIGHUP & SIGINT */
+ if (info->invalidator != 0)
+ {
+ DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
+ (*info->invalidator)(info->filename);
+ info->invalidator=0;
+ }
DBUG_RETURN(0);
err:
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index f31e43e52ab..cfacd0bc4d5 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,7 +25,8 @@
/* Functions declared in this file */
-static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
+static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo,
+ uint comp_flag, uchar *key,
uint key_length, my_off_t pos, uchar *father_buff,
uchar *father_keypos, my_off_t father_page,
my_bool insert_last);
@@ -35,17 +36,21 @@ static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uint *return_key_length,
uchar **after_key);
-
+int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length);
+int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length);
/* Write new record to database */
int mi_write(MI_INFO *info, byte *record)
{
+ MYISAM_SHARE *share=info->s;
uint i;
int save_errno;
my_off_t filepos;
uchar *buff;
- MYISAM_SHARE *share=info->s;
+ my_bool lock_tree= share->concurrent_insert;
DBUG_ENTER("mi_write");
DBUG_PRINT("enter",("isam: %d data: %d",info->s->kfile,info->dfile));
@@ -96,33 +101,36 @@ int mi_write(MI_INFO *info, byte *record)
{
if (((ulonglong) 1 << i) & share->state.key_map)
{
- if (share->concurrent_insert)
+ bool local_lock_tree= (lock_tree &&
+ !(info->bulk_insert &&
+ is_tree_inited(&info->bulk_insert[i])));
+ if (local_lock_tree)
{
rw_wrlock(&share->key_root_lock[i]);
share->keyinfo[i].version++;
}
- if (share->keyinfo[i].flag & HA_FULLTEXT ) /* SerG */
- { /* SerG */
- if (_mi_ft_add(info,i,(char*) buff,record,filepos)) /* SerG */
- { /* SerG */
- if (share->concurrent_insert)
+ if (share->keyinfo[i].flag & HA_FULLTEXT )
+ {
+ if (_mi_ft_add(info,i,(char*) buff,record,filepos))
+ {
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
- DBUG_PRINT("error",("Got error: %d on write",my_errno)); /* SerG */
- goto err; /* SerG */
- } /* SerG */
- } /* SerG */
- else /* SerG */
+ DBUG_PRINT("error",("Got error: %d on write",my_errno));
+ goto err;
+ }
+ }
+ else
{
uint key_length=_mi_make_key(info,i,buff,record,filepos);
if (_mi_ck_write(info,i,buff,key_length))
{
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
DBUG_PRINT("error",("Got error: %d on write",my_errno));
goto err;
}
}
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
}
}
@@ -142,6 +150,12 @@ int mi_write(MI_INFO *info, byte *record)
info->lastpos=filepos;
myisam_log_record(MI_LOG_WRITE,info,record,filepos,0);
VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
+ if (info->invalidator != 0)
+ {
+ DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
+ (*info->invalidator)(info->filename);
+ info->invalidator=0;
+ }
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
@@ -149,19 +163,32 @@ err:
save_errno=my_errno;
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
{
+ if (info->bulk_insert)
+ {
+ uint j;
+ for (j=0 ; j < share->base.keys ; j++)
+ {
+ if (is_tree_inited(&info->bulk_insert[j]))
+ {
+ reset_tree(&info->bulk_insert[j]);
+ }
+ }
+ }
info->errkey= (int) i;
while ( i-- > 0)
{
if (((ulonglong) 1 << i) & share->state.key_map)
{
- if (share->concurrent_insert)
+ bool local_lock_tree= (lock_tree &&
+ !(info->bulk_insert &&
+ is_tree_inited(&info->bulk_insert[i])));
+ if (local_lock_tree)
rw_wrlock(&share->key_root_lock[i]);
- /* The following code block is for text searching by SerG */
if (share->keyinfo[i].flag & HA_FULLTEXT)
{
if (_mi_ft_del(info,i,(char*) buff,record,filepos))
{
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
break;
}
@@ -171,12 +198,12 @@ err:
uint key_length=_mi_make_key(info,i,buff,record,filepos);
if (_mi_ck_delete(info,i,buff,key_length))
{
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
break;
}
}
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
}
}
@@ -196,19 +223,51 @@ err2:
/* Write one key to btree */
-int _mi_ck_write(register MI_INFO *info, uint keynr, uchar *key,
- uint key_length)
+int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length)
{
- int error;
DBUG_ENTER("_mi_ck_write");
+ if (info->bulk_insert && is_tree_inited(&info->bulk_insert[keynr]))
+ {
+ DBUG_RETURN(_mi_ck_write_tree(info, keynr, key, key_length));
+ }
+ else
+ {
+ DBUG_RETURN(_mi_ck_write_btree(info, keynr, key, key_length));
+ }
+} /* _mi_ck_write */
+
+
+/**********************************************************************
+ * Normal insert code *
+ **********************************************************************/
+
+int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length)
+{
+ int error;
+ uint comp_flag;
+ MI_KEYDEF *keyinfo=info->s->keyinfo+keynr;
+ DBUG_ENTER("_mi_ck_write_btree");
+
+ if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
+ comp_flag=SEARCH_BIGGER; /* Put after same key */
+ else if (keyinfo->flag & HA_NOSAME)
+ {
+ comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No dupplicates */
+ if (keyinfo->flag & HA_NULL_ARE_EQUAL)
+ comp_flag|= SEARCH_NULL_ARE_EQUAL;
+ }
+ else
+ comp_flag=SEARCH_SAME; /* Keys in rec-pos order */
+
if (info->s->state.key_root[keynr] == HA_OFFSET_ERROR ||
- (error=w_search(info,info->s->keyinfo+keynr,key, key_length,
+ (error=w_search(info, keyinfo, comp_flag, key, key_length,
info->s->state.key_root[keynr], (uchar *) 0, (uchar*) 0,
(my_off_t) 0, 1)) > 0)
error=_mi_enlarge_root(info,keynr,key);
DBUG_RETURN(error);
-} /* _mi_ck_write */
+} /* _mi_ck_write_btree */
/* Make a new root with key as only pointer */
@@ -246,13 +305,12 @@ int _mi_enlarge_root(register MI_INFO *info, uint keynr, uchar *key)
*/
static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- uchar *key, uint key_length, my_off_t page,
- uchar *father_buff,
- uchar *father_keypos, my_off_t father_page,
- my_bool insert_last)
+ uint comp_flag, uchar *key, uint key_length, my_off_t page,
+ uchar *father_buff, uchar *father_keypos,
+ my_off_t father_page, my_bool insert_last)
{
int error,flag;
- uint comp_flag,nod_flag;
+ uint nod_flag, search_key_length;
uchar *temp_buff,*keypos;
uchar keybuff[MI_MAX_KEY_BUFF];
my_bool was_last_key;
@@ -260,21 +318,15 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_ENTER("w_search");
DBUG_PRINT("enter",("page: %ld",page));
- if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
- comp_flag=SEARCH_BIGGER; /* Put after same key */
- else if (keyinfo->flag & HA_NOSAME)
- comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No dupplicates */
- else
- comp_flag=SEARCH_SAME; /* Keys in rec-pos order */
-
+ search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MI_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
if (!_mi_fetch_keypage(info,keyinfo,page,temp_buff,0))
goto err;
- flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,key_length,comp_flag,
- &keypos, keybuff, &was_last_key);
+ flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
+ comp_flag, &keypos, keybuff, &was_last_key);
nod_flag=mi_test_if_nod(temp_buff);
if (flag == 0)
{
@@ -295,7 +347,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
insert_last=0;
next_page=_mi_kpos(nod_flag,keypos);
if (next_page == HA_OFFSET_ERROR ||
- (error=w_search(info,keyinfo,key,key_length,next_page,
+ (error=w_search(info, keyinfo, comp_flag, key, key_length, next_page,
temp_buff, keypos, page, insert_last)) >0)
{
error=_mi_insert(info,keyinfo,key,temp_buff,keypos,keybuff,father_buff,
@@ -345,7 +397,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
DBUG_PRINT("test",("t_length: %d ref_len: %d",
t_length,s_temp.ref_length));
- DBUG_PRINT("test",("n_ref_len: %d n_length: %d key: %lx",
+ DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: %lx",
s_temp.n_ref_length,s_temp.n_length,s_temp.key));
}
#endif
@@ -682,3 +734,123 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
err:
DBUG_RETURN(-1);
} /* _mi_balance_page */
+
+/**********************************************************************
+ * Bulk insert code *
+ **********************************************************************/
+
+typedef struct {
+ MI_INFO *info;
+ uint keynr;
+} bulk_insert_param;
+
+int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length)
+{
+ int error;
+ DBUG_ENTER("_mi_ck_write_tree");
+
+ error= tree_insert(&info->bulk_insert[keynr], key,
+ key_length + info->s->rec_reflength) ? 0 : HA_ERR_OUT_OF_MEM ;
+
+ DBUG_RETURN(error);
+} /* _mi_ck_write_tree */
+
+
+/* typeof(_mi_keys_compare)=qsort_cmp2 */
+
+static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
+{
+ uint not_used;
+ return _mi_key_cmp(param->info->s->keyinfo[param->keynr].seg,
+ key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
+ &not_used);
+}
+
+
+static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param)
+{
+ /*
+ Probably I can use info->lastkey here, but I'm not sure,
+ and to be safe I'd better use local lastkey.
+ */
+ uchar lastkey[MI_MAX_KEY_BUFF];
+ uint keylen;
+ MI_KEYDEF *keyinfo;
+
+ switch (mode) {
+ case free_init:
+ if (param->info->s->concurrent_insert)
+ {
+ rw_wrlock(&param->info->s->key_root_lock[param->keynr]);
+ param->info->s->keyinfo[param->keynr].version++;
+ }
+ return 0;
+ case free_free:
+ keyinfo=param->info->s->keyinfo+param->keynr;
+ keylen=_mi_keylength(keyinfo, key);
+ memcpy(lastkey, key, keylen);
+ return _mi_ck_write_btree(param->info,param->keynr,lastkey,
+ keylen - param->info->s->rec_reflength);
+ case free_end:
+ if (param->info->s->concurrent_insert)
+ rw_unlock(&param->info->s->key_root_lock[param->keynr]);
+ return 0;
+ }
+ return -1;
+}
+
+
+int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size)
+{
+ MYISAM_SHARE *share=info->s;
+ MI_KEYDEF *key=share->keyinfo;
+ bulk_insert_param *params;
+ uint i, num_keys;
+ ulonglong key_map=0;
+ DBUG_ENTER("_mi_init_bulk_insert");
+ DBUG_PRINT("enter",("cache_size: %lu", cache_size));
+
+ if (info->bulk_insert)
+ DBUG_RETURN(0);
+
+ for (i=num_keys=0 ; i < share->base.keys ; i++)
+ {
+ if (!(key[i].flag & HA_NOSAME) && share->base.auto_key != i+1
+ && test(share->state.key_map & ((ulonglong) 1 << i)))
+ {
+ num_keys++;
+ key_map |=((ulonglong) 1 << i);
+ }
+ }
+
+ if (num_keys==0 ||
+ num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > cache_size)
+ DBUG_RETURN(0);
+
+ info->bulk_insert=(TREE *)
+ my_malloc((sizeof(TREE)*share->base.keys+
+ sizeof(bulk_insert_param)*num_keys),MYF(0));
+
+ if (!info->bulk_insert)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ params=(bulk_insert_param *)(info->bulk_insert+share->base.keys);
+ for (i=0 ; i < share->base.keys ; i++,key++)
+ {
+ if (test(key_map & ((ulonglong) 1 << i)))
+ {
+ params->info=info;
+ params->keynr=i;
+ init_tree(&info->bulk_insert[i],
+ cache_size / num_keys / 4 + 10,
+ cache_size / num_keys, 0,
+ (qsort_cmp2)keys_compare, 0,
+ (tree_element_free) keys_free, (void *)params++);
+ }
+ else
+ info->bulk_insert[i].root=0;
+ }
+
+ DBUG_RETURN(0);
+}
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index cb321f8fda3..ff8c47f93cc 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -1,27 +1,26 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Descript, check and repair of ISAM tables */
+/* Describe, check and repair of MyISAM tables */
#include "fulltext.h"
#include <m_ctype.h>
#include <stdarg.h>
-#include <getopt.h>
-#include <assert.h>
+#include <my_getopt.h>
#ifdef HAVE_SYS_VADVICE_H
#include <sys/vadvise.h>
#endif
@@ -44,6 +43,7 @@ static char **default_argv;
static const char *load_default_groups[]= { "myisamchk", 0 };
static const char *set_charset_name;
static CHARSET_INFO *set_charset;
+static long opt_myisam_block_size;
static const char *type_names[]=
{ "?","char","binary", "short", "long", "float",
@@ -69,12 +69,11 @@ static void print_version(void);
static void usage(void);
static int myisamchk(MI_CHECK *param, char *filename);
static void descript(MI_CHECK *param, register MI_INFO *info, my_string name);
-static int mi_sort_records(MI_CHECK *param,
- register MI_INFO *info, my_string name,
- uint sort_key,
- my_bool write_info,
- my_bool update_index);
-static int sort_record_index(MI_CHECK *param,MI_INFO *info,MI_KEYDEF *keyinfo,
+static int mi_sort_records(MI_CHECK *param, register MI_INFO *info,
+ my_string name, uint sort_key,
+ my_bool write_info, my_bool update_index);
+static int sort_record_index(MI_SORT_PARAM *sort_param,MI_INFO *info,
+ MI_KEYDEF *keyinfo,
my_off_t page,uchar *buff,uint sortkey,
File new_file, my_bool update_index);
@@ -100,12 +99,13 @@ int main(int argc, char **argv)
while (--argc >= 0)
{
int new_error=myisamchk(&check_param, *(argv++));
+ if ((check_param.testflag & T_REP_ANY) != T_REP)
+ check_param.testflag&= ~T_REP;
VOID(fflush(stdout));
VOID(fflush(stderr));
if ((check_param.error_printed | check_param.warning_printed) &&
(check_param.testflag & T_FORCE_CREATE) &&
- (!(check_param.testflag & (T_REP | T_REP_BY_SORT | T_SORT_RECORDS |
- T_SORT_INDEX))))
+ (!(check_param.testflag & (T_REP | T_SORT_RECORDS | T_SORT_INDEX))))
{
uint old_testflag=check_param.testflag;
if (!(check_param.testflag & T_REP))
@@ -141,76 +141,190 @@ int main(int argc, char **argv)
#endif
} /* main */
+enum options {
+ OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
+ OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE,
+ OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
+ OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
+ OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT
+};
-static CHANGEABLE_VAR changeable_vars[] = {
- { "key_buffer_size",(long*) &check_param.use_buffers,(long) USE_BUFFER_INIT,
- (long) MALLOC_OVERHEAD, (long) ~0L,(long) MALLOC_OVERHEAD,(long) IO_SIZE },
- { "read_buffer_size", (long*) &check_param.read_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "write_buffer_size", (long*) &check_param.write_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_buffer_size",(long*) &check_param.sort_buffer_length,(long) SORT_BUFFER_INIT,
- (long) (MIN_SORT_BUFFER+MALLOC_OVERHEAD),(long) ~0L,
- (long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_key_blocks",(long*) &check_param.sort_key_blocks,BUFFERS_WHEN_SORTING,4L,100L,0L,
- 1L },
- { "decode_bits",(long*) &decode_bits,9L,4L,17L,0L,1L },
- { NullS,(long*) 0,0L,0L,0L,0L,0L,} };
-
-enum options {OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS};
-
-
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"analyze", no_argument, 0, 'a'},
- {"block-search", required_argument,0, 'b'},
- {"backup", no_argument, 0, 'B'},
- {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
- {"check", no_argument, 0, 'c'},
- {"check-only-changed",no_argument, 0, 'C'},
+ {"analyze", 'a',
+ "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"block-search", 'b',
+ "No help available.",
+ 0, 0, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"backup", 'B',
+ "Make a backup of the .MYD file as 'filename-time.BAK'",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are.",
+ (gptr*) &set_charset_name, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"check", 'c',
+ "Check table for errors.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"check-only-changed", 'C',
+ "Check only tables that have changed since last check.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"correct-checksum", OPT_CORRECT_CHECKSUM,
+ "Correct checksum information for table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", optional_argument, 0, '#'},
+ {"debug", '#',
+ "Output debug log. Often this is 'd:t:o,filename'.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"description", 'd',
+ "Prints some information about table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"data-file-length", 'D',
+ "Max length of data file (when recreating data-file when it's full).",
+ (gptr*) &check_param.max_data_file_length,
+ (gptr*) &check_param.max_data_file_length,
+ 0, GET_LL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"extend-check", 'e',
+ "Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"fast", 'F',
+ "Check only tables that haven't been closed properly.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Restart with -r if there are any errors in the table. States will be updated as with --update-state.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"HELP", 'H',
+ "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?',
+ "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"information", 'i',
+ "Print statistics information about table that is checked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"keys-used", 'k',
+ "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!",
+ (gptr*) &check_param.keys_in_use,
+ (gptr*) &check_param.keys_in_use,
+ 0, GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0},
+ {"medium-check", 'm',
+ "Faster than extended-check, but only finds 99.99% of all errors. Should be good enough for most cases.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quick", 'q', "Faster repair by not modifying the data file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"read-only", 'T',
+ "Don't mark table as checked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"recover", 'r',
+ "Can fix almost anything except unique keys that aren't unique.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"parallel-recover", 'p',
+ "Same as '-r' but creates all the keys in parallel",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"safe-recover", 'o',
+ "Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-recover", 'n',
+ "Force recovering with sorting even if the temporary file was very big.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef DEBUG
+ {"start-check-pos", OPT_START_CHECK_POS,
+ "No help available.",
+ 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"description", no_argument, 0, 'd'},
- {"data-file-length", required_argument, 0, 'D'},
- {"extend-check", no_argument, 0, 'e'},
- {"fast", no_argument, 0, 'F'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"information", no_argument, 0, 'i'},
- {"keys-used", required_argument, 0, 'k'},
- {"medium-check", no_argument, 0, 'm'},
- {"no-symlinks", no_argument, 0, 'l'},
- {"quick", no_argument, 0, 'q'},
- {"read-only", no_argument, 0, 'T'},
- {"recover", no_argument, 0, 'r'},
- {"safe-recover", no_argument, 0, 'o'},
- {"start-check-pos", required_argument, 0, OPT_START_CHECK_POS},
- {"set-auto-increment",optional_argument, 0, 'A'},
- {"set-character-set",required_argument,0,OPT_SET_CHARSET},
- {"set-variable", required_argument, 0, 'O'},
- {"silent", no_argument, 0, 's'},
- {"sort-index", no_argument, 0, 'S'},
- {"sort-records", required_argument, 0, 'R'},
- {"sort-recover", no_argument, 0, 'n'},
- {"tmpdir", required_argument, 0, 't'},
- {"update-state", no_argument, 0, 'U'},
- {"unpack", no_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"set-auto-increment", 'A',
+ "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.",
+ (gptr*) &check_param.auto_increment_value,
+ (gptr*) &check_param.auto_increment_value,
+ 0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-character-set", OPT_SET_CHARSET,
+ "Change the character set used by the index",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's',
+ "Only print errors. One can use two -s to make myisamchk very silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-index", 'S',
+ "Sort index blocks. This speeds up 'read-next' in applications.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-records", 'R',
+ "Sort records according to an index. This makes your data much more localized and may speed up things. (It may be VERY slow to do a sort the first time!)",
+ (gptr*) &check_param.opt_sort_key,
+ (gptr*) &check_param.opt_sort_key,
+ 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 't',
+ "Path for temporary files.",
+ (gptr*) &check_param.tmpdir,
+ 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"update-state", 'U',
+ "Mark tables as crashed if any errors were found.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"unpack", 'u',
+ "Unpack file packed with myisampack.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v',
+ "Print more information. This can be used with --description and --check. Use many -v for more verbosity!",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V',
+ "Print version and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w',
+ "Wait if table is locked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { "key_buffer_size", OPT_KEY_BUFFER_SIZE, "",
+ (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0,
+ GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
+ { "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "",
+ (gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0,
+ GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
+ MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
+ { "read_buffer_size", OPT_READ_BUFFER_SIZE, "",
+ (gptr*) &check_param.read_buffer_length,
+ (gptr*) &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
+ (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "",
+ (gptr*) &check_param.write_buffer_length,
+ (gptr*) &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
+ (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "",
+ (gptr*) &check_param.sort_buffer_length,
+ (gptr*) &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
+ (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD),
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "",
+ (gptr*) &check_param.sort_key_blocks,
+ (gptr*) &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG,
+ BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0},
+ { "decode_bits", OPT_DECODE_BITS, "", (gptr*) &decode_bits,
+ (gptr*) &decode_bits, 0, GET_UINT, REQUIRED_ARG, 9L, 4L, 17L, 0L, 1L, 0},
+ { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "", (gptr*) &ft_min_word_len,
+ (gptr*) &ft_min_word_len, 0, GET_ULONG, REQUIRED_ARG, 4, 1, HA_FT_MAXLEN,
+ 0, 1, 0},
+ { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", (gptr*) &ft_max_word_len,
+ (gptr*) &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXLEN, 10,
+ HA_FT_MAXLEN, 0, 1, 0},
+ { "ft_max_word_len_for_sort", OPT_FT_MAX_WORD_LEN_FOR_SORT, "",
+ (gptr*) &ft_max_word_len_for_sort, (gptr*) &ft_max_word_len_for_sort, 0,
+ GET_ULONG, REQUIRED_ARG, 20, 4, HA_FT_MAXLEN, 0, 1, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
+
static void print_version(void)
{
- printf("%s Ver 1.53 for %s at %s\n",my_progname,SYSTEM_TYPE,
+ printf("%s Ver 2.6 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
}
+
static void usage(void)
{
- uint i;
print_version();
puts("By Monty, for your professional use");
puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n");
@@ -218,35 +332,42 @@ static void usage(void)
puts("Used without options all tables on the command will be checked for errors");
printf("Usage: %s [OPTIONS] tables[.MYI]\n", my_progname);
puts("\nGlobal options:\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
+ -#, --debug=... Output debug log. Often this is 'd:t:o,filename'\n\
-?, --help Display this help and exit.\n\
-O, --set-variable var=option\n\
- Change the value of a variable.\n\
+ Change the value of a variable. Please note that\n\
+ this option is deprecated; you can set variables\n\
+ directly with '--variable-name=value'.\n\
+ -t, --tmpdir=path Path for temporary files\n\
-s, --silent Only print errors. One can use two -s to make\n\
myisamchk very silent\n\
-v, --verbose Print more information. This can be used with\n\
- --describe and --check. Use many -v for more verbosity!\n\
+ --description and --check. Use many -v for more verbosity!\n\
-V, --version Print version and exit.\n\
-w, --wait Wait if table is locked.\n");
+#ifdef DEBUG
+ puts(" --start-check-pos=# Start reading file at given offset.\n");
+#endif
puts("Check options (check is the default action for myisamchk):\n\
-c, --check Check table for errors\n\
-e, --extend-check Check the table VERY throughly. Only use this in\n\
extreme cases as myisamchk should normally be able to\n\
find out if the table is ok even without this switch\n\
- -F, --fast Check only tables that hasn't been closed properly\n\
+ -F, --fast Check only tables that haven't been closed properly\n\
-C, --check-only-changed\n\
- Check only tables that has changed since last check\n\
- -f, --force Restart with -r if there are any errors in the table.\n\
- States will be updated as with --update-state\n\
+ Check only tables that have changed since last check\n\
+ -f, --force Restart with '-r' if there are any errors in the table.\n\
+ States will be updated as with '--update-state'\n\
-i, --information Print statistics information about table that is checked\n\
-m, --medium-check Faster than extended-check, but only finds 99.99% of\n\
all errors. Should be good enough for most cases\n\
-U --update-state Mark tables as crashed if you find any errors\n\
-T, --read-only Don't mark table as checked\n");
- puts("Repair options (When using -r or -o) \n\
+ puts("Repair options (When using '-r' or '-o') \n\
-B, --backup Make a backup of the .MYD file as 'filename-time.BAK'\n\
+ --correct-checksum Correct checksum information for table.\n\
-D, --data-file-length=# Max length of data file (when recreating data\n\
file when it's full)\n\
-e, --extend-check Try to recover every possible row from the data file\n\
@@ -256,12 +377,14 @@ static void usage(void)
-k, --keys-used=# Tell MyISAM to update only some specific keys. # is a\n\
bit mask of which keys to use. This can be used to\n\
get faster inserts!\n\
- -l, --no-symlinks Do not follow symbolic links. Normally\n\
- myisamchk repairs the table a symlink points at.\n\
-r, --recover Can fix almost anything except unique keys that aren't\n\
unique.\n\
- -n, --sort-recover Force recovering with sorting even if the temporary\n\
+ -n, --sort-recover Forces recovering with sorting even if the temporary\n\
file would be very big.\n\
+ -p, --parallel-recover\n\
+ Uses the same technique as '-r' and '-n', but creates\n\
+ all the keys in parallel, in different threads.\n\
+ THIS IS ALPHA CODE. USE AT YOUR OWN RISK!\n\
-o, --safe-recover Uses old recovery method; Slower than '-r' but can\n\
handle a couple of cases where '-r' reports that it\n\
can't fix the data file.\n\
@@ -269,7 +392,6 @@ static void usage(void)
Directory where character sets are\n\
--set-character-set=name\n\
Change the character set used by the index\n\
- -t, --tmpdir=path Path for temporary files\n\
-q, --quick Faster repair by not modifying the data file.\n\
One can give a second '-q' to force myisamchk to\n\
modify the original datafile in case of duplicate keys\n\
@@ -279,7 +401,7 @@ static void usage(void)
puts("Other actions:\n\
-a, --analyze Analyze distribution of keys. Will make some joins in\n\
MySQL faster. You can check the calculated distribution\n\
- by using '--describe --verbose table_name'.\n\
+ by using '--description --verbose table_name'.\n\
-d, --description Prints some information about table.\n\
-A, --set-auto-increment[=value]\n\
Force auto_increment to start at this or higher value\n\
@@ -290,126 +412,183 @@ static void usage(void)
-R, --sort-records=#\n\
Sort records according to an index. This makes your\n\
data much more localized and may speed up things\n\
- (It may be VERY slow to do a sort the first time!)");
-
- print_defaults("my",load_default_groups);
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- *changeable_vars[i].varptr);
+ (It may be VERY slow to do a sort the first time!)\n\
+ -b, --block-search=#\n\
+ Find a record, a block at given offset belongs to.");
+
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
}
/* Read options */
-static void get_options(register int *argc,register char ***argv)
+static my_bool
+get_one_option(int optid,
+ const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index=0;
- uint old_testflag;
-
- load_defaults("my",load_default_groups,argc,argv);
- default_argv= *argv;
- set_all_changeable_vars(changeable_vars);
- if (isatty(fileno(stdout)))
- check_param.testflag|=T_WRITE_LOOP;
- while ((c=getopt_long(*argc,*argv,
- "aBcCdeifF?lqrmnosSTuUvVw#:b:D:k:O:R:A::t:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
+ switch (optid) {
+ case 'a':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_STATISTICS;
+ else
check_param.testflag|= T_STATISTICS;
- break;
- case 'A':
- if (optarg)
- check_param.auto_increment_value=strtoull(optarg,NULL,0);
- else
- check_param.auto_increment_value=0; /* Set to max used value */
- check_param.testflag|= T_AUTO_INC;
- break;
- case 'b':
- check_param.search_after_block=strtoul(optarg,NULL,10);
- break;
- case 'B':
+ break;
+ case 'A':
+ if (argument)
+ check_param.auto_increment_value= strtoull(argument, NULL, 0);
+ else
+ check_param.auto_increment_value= 0; /* Set to max used value */
+ check_param.testflag|= T_AUTO_INC;
+ break;
+ case 'b':
+ check_param.search_after_block= strtoul(argument, NULL, 10);
+ break;
+ case 'B':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_BACKUP_DATA;
+ else
check_param.testflag|= T_BACKUP_DATA;
- break;
- case 'c':
+ break;
+ case 'c':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_CHECK;
+ else
check_param.testflag|= T_CHECK;
- break;
- case 'C':
+ break;
+ case 'C':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_CHECK | T_CHECK_ONLY_CHANGED);
+ else
check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED;
- break;
- case 'D':
- check_param.max_data_file_length=strtoll(optarg,NULL,10);
- break;
- case 's': /* silent */
+ break;
+ case 'D':
+ check_param.max_data_file_length=strtoll(argument, NULL, 10);
+ break;
+ case 's': /* silent */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_SILENT | T_VERY_SILENT);
+ else
+ {
if (check_param.testflag & T_SILENT)
- check_param.testflag|=T_VERY_SILENT;
+ check_param.testflag|= T_VERY_SILENT;
check_param.testflag|= T_SILENT;
check_param.testflag&= ~T_WRITE_LOOP;
- break;
- case 'w':
+ }
+ break;
+ case 'w':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_WAIT_FOREVER;
+ else
check_param.testflag|= T_WAIT_FOREVER;
- break;
- case 'd': /* description if isam-file */
+ break;
+ case 'd': /* description if isam-file */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_DESCRIPT;
+ else
check_param.testflag|= T_DESCRIPT;
- break;
- case 'e': /* extend check */
+ break;
+ case 'e': /* extend check */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_EXTEND;
+ else
check_param.testflag|= T_EXTEND;
- break;
- case 'i':
+ break;
+ case 'i':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_INFO;
+ else
check_param.testflag|= T_INFO;
- break;
- case 'f':
+ break;
+ case 'f':
+ if (argument == disabled_my_option)
+ {
+ check_param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL;
+ check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE);
+ }
+ else
+ {
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
- break;
- case 'F':
- check_param.testflag|=T_FAST;
- break;
- case 'k':
- check_param.keys_in_use= (ulonglong) strtoll(optarg,NULL,10);
- break;
- case 'l':
- check_param.opt_follow_links=0;
- break;
- case 'm':
+ }
+ break;
+ case 'F':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_FAST;
+ else
+ check_param.testflag|= T_FAST;
+ break;
+ case 'k':
+ check_param.keys_in_use= (ulonglong) strtoll(argument, NULL, 10);
+ break;
+ case 'm':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_MEDIUM;
+ else
check_param.testflag|= T_MEDIUM; /* Medium check */
- break;
- case 'r': /* Repair table */
- check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
- break;
- case 'o':
- check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
- check_param.force_sort=0;
- my_disable_async_io=1; /* More safety */
- break;
- case 'n':
- check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
- check_param.force_sort=1;
- break;
- case 'q':
- check_param.opt_rep_quick++;
- break;
- case 'u':
+ break;
+ case 'r': /* Repair table */
+ check_param.testflag&= ~T_REP_ANY;
+ if (argument != disabled_my_option)
+ check_param.testflag|= T_REP_BY_SORT;
+ break;
+ case 'p':
+ check_param.testflag&= ~T_REP_ANY;
+ if (argument != disabled_my_option)
+ check_param.testflag|= T_REP_PARALLEL;
+ break;
+ case 'o':
+ check_param.testflag&= ~T_REP_ANY;
+ check_param.force_sort= 0;
+ if (argument != disabled_my_option)
+ {
+ check_param.testflag|= T_REP;
+ my_disable_async_io= 1; /* More safety */
+ }
+ break;
+ case 'n':
+ check_param.testflag&= ~T_REP_ANY;
+ if (argument == disabled_my_option)
+ check_param.force_sort= 0;
+ else
+ {
+ check_param.testflag|= T_REP_BY_SORT;
+ check_param.force_sort= 1;
+ }
+ break;
+ case 'q':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_QUICK | T_FORCE_UNIQUENESS);
+ else
+ check_param.testflag|=
+ (check_param.testflag & T_QUICK) ? T_FORCE_UNIQUENESS : T_QUICK;
+ break;
+ case 'u':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT);
+ else
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
- break;
- case 'v': /* Verbose */
+ break;
+ case 'v': /* Verbose */
+ if (argument == disabled_my_option)
+ {
+ check_param.testflag&= ~T_VERBOSE;
+ check_param.verbose=0;
+ }
+ else
+ {
check_param.testflag|= T_VERBOSE;
check_param.verbose++;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage();
- exit(1);
- }
- break;
- case 'R': /* Sort records */
- old_testflag=check_param.testflag;
+ }
+ break;
+ case 'R': /* Sort records */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_SORT_RECORDS;
+ else
+ {
check_param.testflag|= T_SORT_RECORDS;
- check_param.opt_sort_key=(uint) atoi(optarg)-1;
+ check_param.opt_sort_key= (uint) atoi(argument) - 1;
if (check_param.opt_sort_key >= MI_MAX_KEY)
{
fprintf(stderr,
@@ -417,51 +596,86 @@ static void get_options(register int *argc,register char ***argv)
MI_MAX_KEY);
exit(1);
}
- break;
- case 'S': /* Sort index */
- old_testflag=check_param.testflag;
+ }
+ break;
+ case 'S': /* Sort index */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_SORT_INDEX;
+ else
check_param.testflag|= T_SORT_INDEX;
- break;
- case 't':
- check_param.tmpdir=optarg;
- break;
- case 'T':
+ break;
+ case 'T':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_READONLY;
+ else
check_param.testflag|= T_READONLY;
- break;
- case 'U':
+ break;
+ case 'U':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_UPDATE_STATE;
+ else
check_param.testflag|= T_UPDATE_STATE;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/myisamchk.trace");
- break;
- case 'V':
- print_version();
- exit(0);
- case OPT_CHARSETS_DIR:
- charsets_dir = optarg;
- break;
- case OPT_SET_CHARSET:
- set_charset_name=optarg;
- break;
+ break;
+ case '#':
+ if (argument == disabled_my_option)
+ {
+ DBUG_POP();
+ }
+ else
+ {
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace");
+ }
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case OPT_CORRECT_CHECKSUM:
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_CALC_CHECKSUM;
+ else
+ check_param.testflag|= T_CALC_CHECKSUM;
+ break;
#ifdef DEBUG /* Only useful if debugging */
- case OPT_START_CHECK_POS:
- check_param.start_check_pos=strtoull(optarg,NULL,0);
- break;
+ case OPT_START_CHECK_POS:
+ check_param.start_check_pos= strtoull(argument, NULL, 0);
+ break;
#endif
- case '?':
- usage();
- exit(0);
- }
+ case 'H':
+ my_print_help(my_long_options);
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
}
- (*argc)-=optind;
- (*argv)+=optind;
+ return 0;
+}
+
+
+static void get_options(register int *argc,register char ***argv)
+{
+ int ho_error;
+
+ load_defaults("my", load_default_groups, argc, argv);
+ default_argv= *argv;
+ if (isatty(fileno(stdout)))
+ check_param.testflag|=T_WRITE_LOOP;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ /* If using repair, then update checksum if one uses --update-state */
+ if ((check_param.testflag & T_UPDATE_STATE) &&
+ (check_param.testflag & T_REP_ANY))
+ check_param.testflag|= T_CALC_CHECKSUM;
+
if (*argc == 0)
{
usage();
exit(-1);
}
+
if ((check_param.testflag & T_UNPACK) &&
- (check_param.opt_rep_quick || (check_param.testflag & T_SORT_RECORDS)))
+ (check_param.testflag & (T_QUICK | T_SORT_RECORDS)))
{
VOID(fprintf(stderr,
"%s: --unpack can't be used with --quick or --sort-records\n",
@@ -470,7 +684,7 @@ static void get_options(register int *argc,register char ***argv)
}
if ((check_param.testflag & T_READONLY) &&
(check_param.testflag &
- (T_REP_BY_SORT | T_REP | T_STATISTICS | T_AUTO_INC |
+ (T_REP_ANY | T_STATISTICS | T_AUTO_INC |
T_SORT_RECORDS | T_SORT_INDEX | T_FORCE_CREATE)))
{
VOID(fprintf(stderr,
@@ -483,6 +697,7 @@ static void get_options(register int *argc,register char ***argv)
if (!(set_charset=get_charset_by_name(set_charset_name, MYF(MY_WME))))
exit(1);
+ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
return;
} /* get options */
@@ -492,11 +707,10 @@ static void get_options(register int *argc,register char ***argv)
static int myisamchk(MI_CHECK *param, my_string filename)
{
int error,lock_type,recreate;
- int rep_quick= param->opt_rep_quick;
+ int rep_quick= param->testflag & (T_QUICK | T_FORCE_UNIQUENESS);
uint raid_chunks;
MI_INFO *info;
File datafile;
- char fixed_name[FN_REFLEN];
char llbuff[22],llbuff2[22];
my_bool state_updated=0;
MYISAM_SHARE *share;
@@ -554,11 +768,12 @@ static int myisamchk(MI_CHECK *param, my_string filename)
}
share=info->s;
share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */
+ share->tot_locks-= share->r_locks;
share->r_locks=0;
raid_chunks=share->base.raid_chunks;
/*
- Skipp the checking of the file if:
+ Skip the checking of the file if:
We are using --fast and the table is closed properly
We are using --check-only-changed-tables and the table hasn't changed
*/
@@ -566,7 +781,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
{
my_bool need_to_check= mi_is_crashed(info) || share->state.open_count != 0;
- if ((param->testflag & (T_REP_BY_SORT | T_REP | T_SORT_RECORDS)) &&
+ if ((param->testflag & (T_REP_ANY | T_SORT_RECORDS)) &&
((share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR) ||
!(param->testflag & T_CHECK_ONLY_CHANGED))))
@@ -598,7 +813,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
DBUG_RETURN(0);
}
}
- if ((param->testflag & (T_REP_BY_SORT | T_REP | T_STATISTICS |
+ if ((param->testflag & (T_REP_ANY | T_STATISTICS |
T_SORT_RECORDS | T_SORT_INDEX)) &&
(((param->testflag & T_UNPACK) &&
share->data_file_type == COMPRESSED_RECORD) ||
@@ -610,11 +825,12 @@ static int myisamchk(MI_CHECK *param, my_string filename)
(((ulonglong) 1L << share->base.keys)-1)) ||
test_if_almost_full(info) ||
info->s->state.header.file_version[3] != myisam_file_magic[3] ||
- (set_charset && set_charset->number != share->state.header.language)))
+ (set_charset && set_charset->number != share->state.header.language) ||
+ myisam_block_size != MI_KEY_BLOCK_LENGTH))
{
if (set_charset)
- check_param.language=set_charset->number;
- if (recreate_table(&check_param, &info,filename))
+ param->language=set_charset->number;
+ if (recreate_table(param, &info,filename))
{
VOID(fprintf(stderr,
"MyISAM-table '%s' is not fixed because of errors\n",
@@ -622,15 +838,15 @@ static int myisamchk(MI_CHECK *param, my_string filename)
return(-1);
}
recreate=1;
- if (!(param->testflag & (T_REP | T_REP_BY_SORT)))
+ if (!(param->testflag & T_REP_ANY))
{
param->testflag|=T_REP_BY_SORT; /* if only STATISTICS */
if (!(param->testflag & T_SILENT))
printf("- '%s' has old table-format. Recreating index\n",filename);
- if (!rep_quick)
- rep_quick=1;
+ rep_quick|=T_QUICK;
}
share=info->s;
+ share->tot_locks-= share->r_locks;
share->r_locks=0;
}
@@ -639,7 +855,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
param->total_files++;
param->total_records+=info->state->records;
param->total_deleted+=info->state->del;
- descript(&check_param, info, filename);
+ descript(param, info, filename);
}
else
{
@@ -660,13 +876,14 @@ static int myisamchk(MI_CHECK *param, my_string filename)
goto end2;
}
share->w_locks++; /* Mark for writeinfo */
+ share->tot_locks++;
info->lock_type= F_EXTRA_LCK; /* Simulate as locked */
info->tmp_lock_type=lock_type;
datafile=info->dfile;
- if (param->testflag & (T_REP+T_REP_BY_SORT+T_SORT_RECORDS+T_SORT_INDEX))
+ if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX))
{
- if (param->testflag & (T_REP+T_REP_BY_SORT))
+ if (param->testflag & T_REP_ANY)
{
ulonglong tmp=share->state.key_map;
share->state.key_map= (((ulonglong) 1 << share->base.keys)-1)
@@ -674,11 +891,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (tmp != share->state.key_map)
info->update|=HA_STATE_CHANGED;
}
- VOID(fn_format(fixed_name,filename,"",MI_NAME_IEXT,
- 4+ (param->opt_follow_links ? 16 : 0)));
-
- if (rep_quick && chk_del(&check_param, info,
- param->testflag & ~T_VERBOSE))
+ if (rep_quick && chk_del(param, info, param->testflag & ~T_VERBOSE))
{
if (param->testflag & T_FORCE_CREATE)
{
@@ -694,18 +907,21 @@ static int myisamchk(MI_CHECK *param, my_string filename)
}
if (!error)
{
- if ((param->testflag & T_REP_BY_SORT) &&
+ if ((param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL)) &&
(share->state.key_map ||
(rep_quick && !param->keys_in_use && !recreate)) &&
mi_test_if_sort_rep(info, info->state->records,
info->s->state.key_map,
- check_param.force_sort))
+ param->force_sort))
{
- error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick);
+ if (param->testflag & T_REP_BY_SORT)
+ error=mi_repair_by_sort(param,info,filename,rep_quick);
+ else
+ error=mi_repair_parallel(param,info,filename,rep_quick);
state_updated=1;
}
- else if (param->testflag & (T_REP | T_REP_BY_SORT))
- error=mi_repair(&check_param, info,fixed_name,rep_quick);
+ else if (param->testflag & T_REP_ANY)
+ error=mi_repair(param, info,filename,rep_quick);
}
if (!error && param->testflag & T_SORT_RECORDS)
{
@@ -717,10 +933,10 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (param->out_flag & O_NEW_DATA)
{ /* Change temp file to org file */
VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */
- error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
+ error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
MYF(0));
- if (mi_open_datafile(info,info->s))
+ if (mi_open_datafile(info,info->s, -1))
error=1;
param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */
param->read_cache.file=info->dfile;
@@ -738,20 +954,21 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (share->keyinfo[key].flag & HA_BINARY_PACK_KEY)
update_index=0;
- error=mi_sort_records(param,info,fixed_name,param->opt_sort_key,
+ error=mi_sort_records(param,info,filename,param->opt_sort_key,
+ /* what is the following parameter for ? */
(my_bool) !(param->testflag & T_REP),
update_index);
datafile=info->dfile; /* This is now locked */
if (!error && !update_index)
{
- if (check_param.verbose)
+ if (param->verbose)
puts("Table had a compressed index; We must now recreate the index");
- error=mi_repair_by_sort(&check_param,info,fixed_name,1);
+ error=mi_repair_by_sort(param,info,filename,1);
}
}
}
if (!error && param->testflag & T_SORT_INDEX)
- error=mi_sort_index(param,info,fixed_name);
+ error=mi_sort_index(param,info,filename);
if (!error)
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR);
@@ -786,7 +1003,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
!(param->testflag & (T_FAST | T_FORCE_CREATE)))
{
if (param->testflag & (T_EXTEND | T_MEDIUM))
- VOID(init_key_cache(param->use_buffers,(uint) NEAD_MEM));
+ VOID(init_key_cache(param->use_buffers));
VOID(init_io_cache(&param->read_cache,datafile,
(uint) param->read_buffer_length,
READ_CACHE,
@@ -820,8 +1037,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
}
}
if ((param->testflag & T_AUTO_INC) ||
- ((param->testflag & (T_REP | T_REP_BY_SORT)) &&
- info->s->base.auto_key))
+ ((param->testflag & T_REP_ANY) && info->s->base.auto_key))
update_auto_increment_key(param, info,
(my_bool) !test(param->testflag & T_AUTO_INC));
@@ -830,7 +1046,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (info->update & HA_STATE_CHANGED && ! (param->testflag & T_READONLY))
error|=update_state_info(param, info,
UPDATE_OPEN_COUNT |
- (((param->testflag & (T_REP | T_REP_BY_SORT)) ?
+ (((param->testflag & T_REP_ANY) ?
UPDATE_TIME : 0) |
(state_updated ? UPDATE_STAT : 0) |
((param->testflag & T_SORT_RECORDS) ?
@@ -839,6 +1055,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
info->update&= ~HA_STATE_CHANGED;
}
share->w_locks--;
+ share->tot_locks--;
end2:
if (mi_close(info))
{
@@ -848,23 +1065,23 @@ end2:
if (error == 0)
{
if (param->out_flag & O_NEW_DATA)
- error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
+ error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
((param->testflag & T_BACKUP_DATA) ?
MYF(MY_REDEL_MAKE_BACKUP) : MYF(0)));
if (param->out_flag & O_NEW_INDEX)
- error|=change_to_newfile(fixed_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
+ error|=change_to_newfile(filename,MI_NAME_IEXT,INDEX_TMP_EXT,0,
MYF(0));
}
VOID(fflush(stdout)); VOID(fflush(stderr));
if (param->error_printed)
{
- if (param->testflag & (T_REP+T_REP_BY_SORT+T_SORT_RECORDS+T_SORT_INDEX))
+ if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX))
{
VOID(fprintf(stderr,
"MyISAM-table '%s' is not fixed because of errors\n",
filename));
- if (check_param.testflag & (T_REP_BY_SORT | T_REP))
+ if (param->testflag & T_REP_ANY)
VOID(fprintf(stderr,
"Try fixing it by using the --safe-recover (-o) or the --force (-f) option\n"));
}
@@ -875,7 +1092,7 @@ end2:
filename));
}
else if (param->warning_printed &&
- ! (param->testflag & (T_REP+T_REP_BY_SORT+T_SORT_RECORDS+T_SORT_INDEX+
+ ! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX |
T_FORCE_CREATE)))
VOID(fprintf(stderr, "MyISAM-table '%s' is usable but should be fixed\n",
filename));
@@ -1155,7 +1372,7 @@ static int mi_sort_records(MI_CHECK *param,
register MI_INFO *info, my_string name,
uint sort_key,
my_bool write_info,
- my_bool update_index)
+ my_bool update_index)
{
int got_error;
uint key;
@@ -1165,11 +1382,14 @@ static int mi_sort_records(MI_CHECK *param,
ha_rows old_record_count;
MYISAM_SHARE *share=info->s;
char llbuff[22],llbuff2[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO sort_info;
+ MI_SORT_PARAM sort_param;
DBUG_ENTER("sort_records");
- bzero((char*) sort_info,sizeof(*sort_info));
- sort_info->param=param;
+ bzero((char*)&sort_info,sizeof(sort_info));
+ bzero((char*)&sort_param,sizeof(sort_param));
+ sort_param.sort_info=&sort_info;
+ sort_info.param=param;
keyinfo= &share->keyinfo[sort_key];
got_error=1;
temp_buff=0;
@@ -1193,7 +1413,7 @@ static int mi_sort_records(MI_CHECK *param,
if (share->state.key_root[sort_key] == HA_OFFSET_ERROR)
DBUG_RETURN(0); /* Nothing to do */
- init_key_cache(param->use_buffers,NEAD_MEM);
+ init_key_cache(param->use_buffers);
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
@@ -1205,13 +1425,15 @@ static int mi_sort_records(MI_CHECK *param,
mi_check_print_error(param,"Not enough memory for key block");
goto err;
}
- if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength,
+ if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
MYF(0))))
{
mi_check_print_error(param,"Not enough memory for record");
goto err;
}
- new_file=my_raid_create(fn_format(param->temp_filename,name,"",
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename,"",
DATA_TMP_EXT,2+4),
0,param->tmpfile_createflag,
share->base.raid_type,
@@ -1245,18 +1467,18 @@ static int mi_sort_records(MI_CHECK *param,
}
/* Setup param for sort_write_record */
- sort_info->info=info;
- sort_info->new_data_file_type=share->data_file_type;
- sort_info->fix_datafile=1;
- sort_info->filepos=share->pack.header_length;
+ sort_info.info=info;
+ sort_info.new_data_file_type=share->data_file_type;
+ sort_param.fix_datafile=1;
+ sort_param.filepos=share->pack.header_length;
old_record_count=info->state->records;
info->state->records=0;
- if (sort_info->new_data_file_type != COMPRESSED_RECORD)
+ if (sort_info.new_data_file_type != COMPRESSED_RECORD)
share->state.checksum=0;
- if (sort_record_index(param, info,keyinfo,share->state.key_root[sort_key],
+ if (sort_record_index(&sort_param,info,keyinfo,share->state.key_root[sort_key],
temp_buff, sort_key,new_file,update_index) ||
- write_data_suffix(param, info) ||
+ write_data_suffix(&sort_info,1) ||
flush_io_cache(&info->rec_cache))
goto err;
@@ -1274,7 +1496,7 @@ static int mi_sort_records(MI_CHECK *param,
info->state->del=0;
info->state->empty=0;
share->state.dellink= HA_OFFSET_ERROR;
- info->state->data_file_length=sort_info->filepos;
+ info->state->data_file_length=sort_param.filepos;
share->state.split=info->state->records; /* Only hole records */
share->state.version=(ulong) time((time_t*) 0);
@@ -1298,11 +1520,11 @@ err:
{
my_afree((gptr) temp_buff);
}
- my_free(sort_info->record,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
VOID(end_io_cache(&info->rec_cache));
- my_free(sort_info->buff,MYF(MY_ALLOW_ZERO_PTR));
- sort_info->buff=0;
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
+ sort_info.buff=0;
share->state.sortkey=sort_key;
DBUG_RETURN(flush_blocks(param, share->kfile) | got_error);
} /* sort_records */
@@ -1310,7 +1532,8 @@ err:
/* Sort records recursive using one index */
-static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
+static int sort_record_index(MI_SORT_PARAM *sort_param,MI_INFO *info,
+ MI_KEYDEF *keyinfo,
my_off_t page, uchar *buff, uint sort_key,
File new_file,my_bool update_index)
{
@@ -1319,7 +1542,8 @@ static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
my_off_t next_page,rec_pos;
uchar lastkey[MI_MAX_KEY_BUFF];
char llbuff[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO *sort_info= sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
DBUG_ENTER("sort_record_index");
nod_flag=mi_test_if_nod(buff);
@@ -1350,7 +1574,7 @@ static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
llstr(next_page,llbuff));
goto err;
}
- if (sort_record_index(param, info,keyinfo,next_page,temp_buff,sort_key,
+ if (sort_record_index(sort_param, info,keyinfo,next_page,temp_buff,sort_key,
new_file, update_index))
goto err;
}
@@ -1361,23 +1585,23 @@ static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
break;
rec_pos= _mi_dpos(info,0,lastkey+key_length);
- if ((*info->s->read_rnd)(info,sort_info->record,rec_pos,0))
+ if ((*info->s->read_rnd)(info,sort_param->record,rec_pos,0))
{
mi_check_print_error(param,"%d when reading datafile",my_errno);
goto err;
}
- if (rec_pos != sort_info->filepos && update_index)
+ if (rec_pos != sort_param->filepos && update_index)
{
_mi_dpointer(info,keypos-nod_flag-info->s->rec_reflength,
- sort_info->filepos);
- if (movepoint(info,sort_info->record,rec_pos,sort_info->filepos,
+ sort_param->filepos);
+ if (movepoint(info,sort_param->record,rec_pos,sort_param->filepos,
sort_key))
{
mi_check_print_error(param,"%d when updating key-pointers",my_errno);
goto err;
}
}
- if (sort_write_record(sort_info))
+ if (sort_write_record(sort_param))
goto err;
}
/* Clear end of block to get better compression if the table is backuped */
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index 260e9665b31..73b9a1280a4 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,6 +18,7 @@
#include "myisam.h" /* Structs & some defines */
#include "myisampack.h" /* packing of keys */
+#include <my_tree.h>
#ifdef THREAD
#include <my_pthread.h>
#include <thr_lock.h>
@@ -37,7 +38,7 @@ typedef struct st_mi_status_info
my_off_t key_empty; /* lost space in indexfile */
my_off_t key_file_length;
my_off_t data_file_length;
-} MI_STATUS_INFO;
+} MI_STATUS_INFO;
typedef struct st_mi_state_info
{
@@ -65,8 +66,10 @@ typedef struct st_mi_state_info
ulong unique; /* Unique number for this process */
ulong update_count; /* Updated for each write lock */
ulong status;
+ ulong *rec_per_key_part;
my_off_t *key_root; /* Start of key trees */
my_off_t *key_del; /* delete links for trees */
+ my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
ulong sec_index_changed; /* Updated when new sec_index */
ulong sec_index_used; /* which extra index are in use */
@@ -79,8 +82,6 @@ typedef struct st_mi_state_info
uint sortkey; /* sorted by this key (not used) */
uint open_count;
uint8 changed; /* Changed since myisamchk */
- my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
- ulong *rec_per_key_part;
/* the following isn't saved on disk */
uint state_diff_length; /* Should be 0 */
@@ -159,42 +160,45 @@ typedef struct st_mi_isam_share { /* Shared between opens */
MI_COLUMNDEF *rec; /* Pointer to field information */
MI_PACK pack; /* Data about packed records */
MI_BLOB *blobs; /* Pointer to blobs */
- char *filename; /* Name of indexfile */
+ char *unique_file_name; /* realpath() of index file */
+ char *data_file_name, /* Resolved path names from symlinks */
+ *index_file_name;
byte *file_map; /* mem-map of file if possible */
+ MI_DECODE_TREE *decode_trees;
+ uint16 *decode_tables;
+ int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
+ int (*write_record)(struct st_myisam_info*, const byte*);
+ int (*update_record)(struct st_myisam_info*, my_off_t, const byte*);
+ int (*delete_record)(struct st_myisam_info*);
+ int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool);
+ int (*compare_record)(struct st_myisam_info*, const byte *);
+ ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
+ int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
+ const byte *record, my_off_t pos);
+ invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_process; /* processid */
ulong last_process; /* For table-change-check */
ulong last_version; /* Version on start */
ulong options; /* Options used */
+ ulong min_pack_length; /* Theese are used by packed data */
+ ulong max_pack_length;
+ ulong state_diff_length;
uint rec_reflength; /* rec_reflength in use now */
- int kfile; /* Shared keyfile */
- int data_file; /* Shared data file */
+ File kfile; /* Shared keyfile */
+ File data_file; /* Shared data file */
int mode; /* mode of file on open */
uint reopen; /* How many times reopened */
- uint w_locks,r_locks; /* Number of read/write locks */
+ uint w_locks,r_locks,tot_locks; /* Number of read/write locks */
uint blocksize; /* blocksize of keyfile */
- ulong min_pack_length; /* Theese are used by packed data */
- ulong max_pack_length;
- ulong state_diff_length;
+ myf write_flag;
+ int rnd; /* rnd-counter */
+ enum data_file_type data_file_type;
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
not_flushed,
temporary,delay_key_write,
concurrent_insert,
fulltext_index;
- myf write_flag;
- int rnd; /* rnd-counter */
- MI_DECODE_TREE *decode_trees;
- uint16 *decode_tables;
- enum data_file_type data_file_type;
- int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
- int (*write_record)(struct st_myisam_info*, const byte*);
- int (*update_record)(struct st_myisam_info*, my_off_t, const byte*);
- int (*delete_record)(struct st_myisam_info*);
- int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool);
- int (*compare_record)(struct st_myisam_info*, const byte *);
- ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
- int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
- const byte *record, my_off_t pos);
#ifdef THREAD
THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */
@@ -212,16 +216,21 @@ typedef struct st_mi_bit_buff { /* Used for packing of record */
uint error;
} MI_BIT_BUFF;
-
struct st_myisam_info {
MYISAM_SHARE *s; /* Shared between open:s */
MI_STATUS_INFO *state,save_state;
MI_BLOB *blobs; /* Pointer to blobs */
- int dfile; /* The datafile */
- MI_BIT_BUFF bit_buff;
- uint opt_flag; /* Optim. for space/speed */
- uint update; /* If file changed since open */
+ MI_BIT_BUFF bit_buff;
+ /* accumulate indexfile changes between write's */
+ TREE *bulk_insert;
char *filename; /* parameter to open filename */
+ uchar *buff, /* Temp area for key */
+ *lastkey,*lastkey2; /* Last used search key */
+ byte *rec_buff; /* Tempbuff for recordpack */
+ uchar *int_keypos, /* Save position for next/previous */
+ *int_maxpos; /* -""- */
+ int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
+ invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_unique; /* uniq filenumber or thread */
ulong last_unique; /* last unique number */
ulong this_loop; /* counter for this open */
@@ -230,20 +239,16 @@ struct st_myisam_info {
nextpos; /* Position to next record */
my_off_t save_lastpos;
my_off_t pos; /* Intern variable */
- ha_checksum checksum;
- ulong packed_length,blob_length; /* Length of found, packed record */
- uint alloced_rec_buff_length; /* Max recordlength malloced */
- uchar *buff, /* Temp area for key */
- *lastkey,*lastkey2; /* Last used search key */
- byte *rec_buff, /* Tempbuff for recordpack */
- *rec_alloc; /* Malloced area for record */
- uchar *int_keypos, /* Save position for next/previous */
- *int_maxpos; /* -""- */
- uint32 int_keytree_version; /* -""- */
- uint int_nod_flag; /* -""- */
my_off_t last_keypage; /* Last key page read */
my_off_t last_search_keypage; /* Last keypage when searching */
my_off_t dupp_key_pos;
+ ha_checksum checksum;
+ ulong packed_length,blob_length; /* Length of found, packed record */
+ int dfile; /* The datafile */
+ uint opt_flag; /* Optim. for space/speed */
+ uint update; /* If file changed since open */
+ uint alloced_rec_buff_length; /* Max recordlength malloced */
+ uint int_nod_flag; /* -""- */
int lastinx; /* Last used index */
uint lastkey_length; /* Length of key in lastkey */
uint last_rkey_length; /* Last length in mi_rkey() */
@@ -254,15 +259,15 @@ struct st_myisam_info {
uint data_changed; /* Somebody has changed data */
uint save_update; /* When using KEY_READ */
int save_lastinx;
+ uint32 int_keytree_version; /* -""- */
+ LIST open_list;
+ IO_CACHE rec_cache; /* When cacheing records */
+ myf lock_wait; /* is 0 or MY_DONT_WAIT */
my_bool was_locked; /* Was locked in panic */
my_bool quick_mode;
my_bool page_changed; /* If info->buff can't be used for rnext */
my_bool buff_used; /* If info->buff has to be reread for rnext */
my_bool use_packed_key; /* For MYISAMMRG */
- myf lock_wait; /* is 0 or MY_DONT_WAIT */
- int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
- LIST open_list;
- IO_CACHE rec_cache; /* When cacheing records */
#ifdef THREAD
THR_LOCK_DATA lock;
#endif
@@ -285,7 +290,7 @@ struct st_myisam_info {
#define STATE_CHANGED 1
#define STATE_CRASHED 2
-#define STATE_CRASHED_ON_REPAIR 4
+#define STATE_CRASHED_ON_REPAIR 4
#define STATE_NOT_ANALYZED 8
#define STATE_NOT_OPTIMIZED_KEYS 16
#define STATE_NOT_SORTED_PAGES 32
@@ -352,7 +357,9 @@ struct st_myisam_info {
#define MI_DYN_MAX_BLOCK_LENGTH ((1L << 24)-4L)
#define MI_DYN_MAX_ROW_LENGTH (MI_DYN_MAX_BLOCK_LENGTH - MI_SPLIT_LENGTH)
#define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */
-#define MI_MAX_DYN_HEADER_BYTE 12 /* max header byte for dynamic rows */
+#define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */
+#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
+#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER)
#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */
@@ -361,12 +368,12 @@ struct st_myisam_info {
#define PACK_TYPE_ZERO_FILL 4
#define MI_FOUND_WRONG_KEY 32738 /* Impossible value from _mi_key_cmp */
-#define MI_KEY_BLOCK_LENGTH 1024 /* Min key block length */
-#define MI_MAX_KEY_BLOCK_LENGTH 8192
-#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_KEY_BLOCK_LENGTH)
-#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/MI_KEY_BLOCK_LENGTH+1)*MI_KEY_BLOCK_LENGTH)
-#define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */
-#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */
+#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH)
+#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/myisam_block_size+1)*myisam_block_size)
+#define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */
+#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */
+
+#define MI_MIN_SIZE_BULK_INSERT_TREE 16384 /* this is per key */
/* The UNIQUE check is done with a hashed long key */
@@ -473,6 +480,9 @@ extern int _mi_bin_search(struct st_myisam_info *info,MI_KEYDEF *keyinfo,
extern int _mi_seq_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page,
uchar *key,uint key_len,uint comp_flag,
uchar **ret_pos,uchar *buff, my_bool *was_last_key);
+extern int _mi_prefix_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page,
+ uchar *key,uint key_len,uint comp_flag,
+ uchar **ret_pos,uchar *buff, my_bool *was_last_key);
extern int _mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
my_bool);
extern my_off_t _mi_kpos(uint nod_flag,uchar *after_key);
@@ -513,10 +523,11 @@ extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf);
extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos,
uint length,int re_read_if_possibly);
extern void update_auto_increment(MI_INFO *info,const byte *record);
-extern byte *mi_fix_rec_buff_for_blob(MI_INFO *info,ulong blob_length);
+extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**, uint*);
+extern gptr mi_get_rec_buff_ptr(MI_INFO *, byte *);
extern ulong _mi_rec_unpack(MI_INFO *info,byte *to,byte *from,
ulong reclength);
-extern my_bool _mi_rec_check(MI_INFO *info,const char *from);
+extern my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *packpos);
extern int _mi_write_part_record(MI_INFO *info,my_off_t filepos,ulong length,
my_off_t next_filepos,byte **record,
ulong *reclength,int *flag);
@@ -528,6 +539,8 @@ extern int _mi_read_rnd_pack_record(MI_INFO*, byte *,my_off_t, my_bool);
extern int _mi_pack_rec_unpack(MI_INFO *info,byte *to,byte *from,
ulong reclength);
extern ulonglong mi_safe_mul(ulonglong a,ulonglong b);
+extern int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
+ const byte *oldrec, const byte *newrec, my_off_t pos);
struct st_sort_info;
@@ -554,7 +567,7 @@ typedef struct st_mi_block_info { /* Parameter to _mi_get_block_info */
#define BLOCK_SYNC_ERROR 16 /* Right data at wrong place */
#define BLOCK_FATAL_ERROR 32 /* hardware-error */
-#define NEAD_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
+#define NEED_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
#define MAXERR 20
#define BUFFERS_WHEN_SORTING 16 /* Alloc for sort-key-tree */
#define WRITE_COUNT MY_HOW_OFTEN_TO_WRITE
@@ -580,6 +593,9 @@ enum myisam_log_commands {
#define myisam_log_command(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_command(a,b,c,d,e)
#define myisam_log_record(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_record(a,b,c,d,e)
+#define fast_mi_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _mi_writeinfo((INFO),0)
+#define fast_mi_readinfo(INFO) ((INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO),F_RDLCK,1)
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -633,14 +649,21 @@ my_bool mi_check_status(void* param);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
my_bool check_table_is_closed(const char *name, const char *where);
-int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share);
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share);
-/* Functions needed by mi_check */
+int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size);
+
+ /* Functions needed by mi_check */
void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...));
void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...));
void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...));
+int flush_pending_blocks(MI_SORT_PARAM *param);
+int thr_write_keys(MI_SORT_PARAM *sort_param);
+#ifdef THREAD
+pthread_handler_decl(thr_find_all_keys,arg);
+#endif
#ifdef __cplusplus
}
diff --git a/myisam/myisamlog.c b/myisam/myisamlog.c
index ddfafb91430..ceca8d2a0e3 100644
--- a/myisam/myisamlog.c
+++ b/myisam/myisamlog.c
@@ -56,7 +56,7 @@ extern int main(int argc,char * *argv);
static void get_options(int *argc,char ***argv);
static int examine_log(my_string file_name,char **table_names);
static int read_string(IO_CACHE *file,gptr *to,uint length);
-static int file_info_compare(void *a,void *b);
+static int file_info_compare(void *cmp_arg, void *a,void *b);
static int test_if_open(struct file_info *key,element_count count,
struct test_if_open_param *param);
static void fix_blob_pointers(MI_INFO *isam,byte *record);
@@ -331,9 +331,9 @@ static int examine_log(my_string file_name, char **table_names)
init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0));
bzero((gptr) com_count,sizeof(com_count));
- init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,1,
- (void(*)(void*)) file_info_free);
- VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
+ init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
+ (tree_element_free) file_info_free, NULL);
+ VOID(init_key_cache(KEY_CACHE_SIZE));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
@@ -404,11 +404,7 @@ static int examine_log(my_string file_name, char **table_names)
}
to=isam_file_name;
if (filepath)
- {
- strmov(isam_file_name,filepath);
- convert_dirname(isam_file_name);
- to=strend(isam_file_name);
- }
+ to=convert_dirname(isam_file_name,filepath,NullS);
strmov(to,pos);
fn_ext(isam_file_name)[0]=0; /* Remove extension */
}
@@ -488,7 +484,7 @@ static int examine_log(my_string file_name, char **table_names)
command_name[command], (int) extra_command,result);
if (update && curr_file_info && !curr_file_info->closed)
{
- if (mi_extra(curr_file_info->isam, extra_command) != (int) result)
+ if (mi_extra(curr_file_info->isam, extra_command, 0) != (int) result)
{
fflush(stdout);
VOID(fprintf(stderr,
@@ -695,7 +691,8 @@ static int read_string(IO_CACHE *file, register gptr *to, register uint length)
} /* read_string */
-static int file_info_compare(void *a, void *b)
+static int file_info_compare(void* cmp_arg __attribute__((unused)),
+ void *a, void *b)
{
long lint;
diff --git a/myisam/myisampack.c b/myisam/myisampack.c
index cd18cebbda0..14fde9aa8b3 100644
--- a/myisam/myisampack.c
+++ b/myisam/myisampack.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,7 +30,7 @@
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ /* Skip warnings in getopt.h */
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#if INT_MAX > 32767
#define BITS_SAVED 32
@@ -124,7 +124,8 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees,
uint trees,
HUFF_COUNTS *huff_counts,
uint fields);
-static int compare_tree(const uchar *s,const uchar *t);
+static int compare_tree(void* cmp_arg __attribute__((unused)),
+ const uchar *s,const uchar *t);
static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts);
static void check_counts(HUFF_COUNTS *huff_counts,uint trees,
my_off_t records);
@@ -168,9 +169,10 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf);
static void mrg_reset(PACK_MRG_INFO *mrg);
-static int backup=0,error_on_write=0,test_only=0,verbose=0,silent=0,
- write_loop=0,force_pack=0,opt_wait=0,isamchk_neaded=0;
+static int error_on_write=0,test_only=0,verbose=0,silent=0,
+ write_loop=0,force_pack=0, isamchk_neaded=0;
static int tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
+static my_bool backup, opt_wait;
static uint tree_buff_length=8196-MALLOC_OVERHEAD;
static char tmp_dir[FN_REFLEN]={0},*join_table;
static my_off_t intervall_length;
@@ -231,32 +233,49 @@ int main(int argc, char **argv)
enum options_mp {OPT_CHARSETS_DIR_MP=256};
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"backup", no_argument, 0, 'b'},
- {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR_MP},
- {"debug", optional_argument, 0, '#'},
- {"force", no_argument, 0, 'f'},
- {"join", required_argument, 0, 'j'},
- {"help", no_argument, 0, '?'},
- {"silent", no_argument, 0, 's'},
- {"tmpdir", required_argument, 0, 'T'},
- {"test", no_argument, 0, 't'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"backup", 'b', "Make a backup of the table as table_name.OLD",
+ (gptr*) &backup, (gptr*) &backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR_MP,
+ "Directory where character sets are.", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Force packing of table even if it gets bigger or if tempfile exists.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"join", 'j',
+ "Join all given tables into 'new_table_name'. All tables MUST have identical layouts.",
+ (gptr*) &join_table, (gptr*) &join_table, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 'T', "Use temporary directory to store temporary table.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"test", 't', "Don't pack table, only test packing it.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write info about progress and packing result.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w', "Wait and retry if table is in use.", (gptr*) &opt_wait,
+ (gptr*) &opt_wait, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void print_version(void)
{
- printf("%s Ver 1.13 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
+ printf("%s Ver 1.21 for %s on %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
static void usage(void)
{
print_version();
- puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB");
+ puts("Copyright (C) 2002 MySQL AB");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
puts("and you are welcome to modify and redistribute it under the GPL license\n");
@@ -266,22 +285,54 @@ static void usage(void)
puts("You should give the .MSI file as the filename argument.");
printf("\nUsage: %s [OPTIONS] filename...\n", my_progname);
- puts("\n\
- -b, --backup Make a backup of the table as table_name.OLD\n\
- -f, --force Force packing of table even if it gets bigger or if\n\
- tempfile exists.\n\
- -j, --join='new_table_name'\n\
- Join all given tables into 'new_table_name'.\n\
- All tables MUST have identical layouts.\n\
- -s, --silent Be more silent.\n\
- -t, --test Don't pack table, only test packing it.\n\
- -v, --verbose Write info about progress and packing result.\n\
- -w, --wait Wait and retry if table is in use.\n\
- -T, --tmpdir=... Use temporary directory to store temporary table.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help Display this help and exit.\n\
- -V, --version Output version information and exit.");
- print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ uint length;
+
+ switch(optid) {
+ case 'f':
+ force_pack= 1;
+ tmpfile_createflag= O_RDWR | O_TRUNC;
+ break;
+ case 's':
+ write_loop= verbose= 0;
+ silent= 1;
+ break;
+ case 't':
+ test_only= verbose= 1;
+ break;
+ case 'T':
+ length= (uint) (strmov(tmp_dir, argument) - tmp_dir);
+ if (length != dirname_length(tmp_dir))
+ {
+ tmp_dir[length]=FN_LIBCHAR;
+ tmp_dir[length+1]=0;
+ }
+ break;
+ case 'v':
+ verbose= 1;
+ silent= 0;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
}
/* reads options */
@@ -289,66 +340,15 @@ static void usage(void)
static void get_options(int *argc,char ***argv)
{
- int c,option_index=0;
- uint length;
+ int ho_error;
my_progname= argv[0][0];
if (isatty(fileno(stdout)))
write_loop=1;
- while ((c=getopt_long(*argc,*argv,"bfj:stvwT:#::?V",long_options,
- &option_index)) != EOF)
- {
- switch(c) {
- case 'b':
- backup=1;
- break;
- case 'f':
- force_pack=1;
- tmpfile_createflag=O_RDWR | O_TRUNC;
- break;
- case 'j':
- join_table=optarg;
- break;
- case 's':
- write_loop=verbose=0; silent=1;
- break;
- case 't':
- test_only=verbose=1;
- break;
- case 'T':
- length=(uint) (strmov(tmp_dir,optarg)-tmp_dir);
- if (length != dirname_length(tmp_dir))
- {
- tmp_dir[length]=FN_LIBCHAR;
- tmp_dir[length+1]=0;
- }
- break;
- case 'v':
- verbose=1; silent=0;
- break;
- case 'w':
- opt_wait=1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case OPT_CHARSETS_DIR_MP:
- charsets_dir = optarg;
- break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- default:
- fprintf(stderr,"%s: Illegal option: -%c\n",my_progname,opterr);
- usage();
- exit(1);
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (!*argc)
{
usage();
@@ -663,9 +663,9 @@ static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records)
type = FIELD_NORMAL;
if (count[i].field_length <= 8 &&
(type == FIELD_NORMAL ||
- type == FIELD_SKIPP_ZERO))
+ type == FIELD_SKIP_ZERO))
count[i].max_zero_fill= count[i].field_length;
- init_tree(&count[i].int_tree,0,-1,(qsort_cmp) compare_tree,0,NULL);
+ init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,NULL,NULL);
if (records && type != FIELD_BLOB && type != FIELD_VARCHAR)
count[i].tree_pos=count[i].tree_buff =
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,
@@ -787,7 +787,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
/* Save character counters and space-counts and zero-field-counts */
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ENDSPACE)
+ count->field_type == FIELD_SKIP_ENDSPACE)
{
for ( ; end_pos > pos ; end_pos--)
if (end_pos[-1] != ' ')
@@ -806,7 +806,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
count->max_end_space = length;
}
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_PRESPACE)
+ count->field_type == FIELD_SKIP_PRESPACE)
{
for (pos=start_pos; pos < end_pos ; pos++)
if (pos[0] != ' ')
@@ -842,7 +842,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
}
if (count->field_length <= 8 &&
(count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ZERO))
+ count->field_type == FIELD_SKIP_ZERO))
{
uint i;
if (!memcmp((byte*) start_pos,zero_string,count->field_length))
@@ -947,7 +947,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
new_length=calc_packed_length(huff_counts,0);
if (old_length < new_length && huff_counts->field_length > 1)
{
- huff_counts->field_type=FIELD_SKIPP_ZERO;
+ huff_counts->field_type=FIELD_SKIP_ZERO;
huff_counts->counts[0]-=length;
huff_counts->bytes_packed=old_length- records/8;
goto found_pack;
@@ -991,7 +991,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
huff_counts->counts[' ']+=huff_counts->tot_pre_space;
if (test_space_compress(huff_counts,records,huff_counts->max_end_space,
huff_counts->end_space,
- huff_counts->tot_end_space,FIELD_SKIPP_ENDSPACE))
+ huff_counts->tot_end_space,FIELD_SKIP_ENDSPACE))
goto found_pack;
huff_counts->counts[' ']-=huff_counts->tot_pre_space;
}
@@ -999,7 +999,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
{
if (test_space_compress(huff_counts,records,huff_counts->max_pre_space,
huff_counts->pre_space,
- huff_counts->tot_pre_space,FIELD_SKIPP_PRESPACE))
+ huff_counts->tot_pre_space,FIELD_SKIP_PRESPACE))
goto found_pack;
}
@@ -1009,10 +1009,10 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
if (huff_counts->max_zero_fill &&
(huff_counts->field_type == FIELD_NORMAL ||
- huff_counts->field_type == FIELD_SKIPP_ZERO))
+ huff_counts->field_type == FIELD_SKIP_ZERO))
{
huff_counts->counts[0]-=huff_counts->max_zero_fill*
- (huff_counts->field_type == FIELD_SKIPP_ZERO ?
+ (huff_counts->field_type == FIELD_SKIP_ZERO ?
records - huff_counts->zero_fields : records);
huff_counts->pack_type|=PACK_TYPE_ZERO_FILL;
huff_counts->bytes_packed=calc_packed_length(huff_counts,0);
@@ -1052,9 +1052,9 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
if (verbose)
printf("\nnormal: %3d empty-space: %3d empty-zero: %3d empty-fill: %3d\npre-space: %3d end-space: %3d intervall-fields: %3d zero: %3d\n",
field_count[FIELD_NORMAL],space_fields,
- field_count[FIELD_SKIPP_ZERO],fill_zero_fields,
- field_count[FIELD_SKIPP_PRESPACE],
- field_count[FIELD_SKIPP_ENDSPACE],
+ field_count[FIELD_SKIP_ZERO],fill_zero_fields,
+ field_count[FIELD_SKIP_PRESPACE],
+ field_count[FIELD_SKIP_ENDSPACE],
field_count[FIELD_INTERVALL],
field_count[FIELD_ZERO]);
DBUG_VOID_RETURN;
@@ -1282,7 +1282,8 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
return 0;
}
-static int compare_tree(register const uchar *s, register const uchar *t)
+static int compare_tree(void* cmp_arg __attribute__((unused)),
+ register const uchar *s, register const uchar *t)
{
uint length;
for (length=global_count->field_length; length-- ;)
@@ -1719,7 +1720,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
field_length-=count->max_zero_fill;
switch(count->field_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (!memcmp((byte*) start_pos,zero_string,field_length))
{
write_bits(1,1);
@@ -1733,7 +1734,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
write_bits(tree->code[(uchar) *start_pos],
(uint) tree->code_len[(uchar) *start_pos]);
break;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
for (pos=end_pos ; pos > start_pos && pos[-1] == ' ' ; pos--) ;
length=(uint) (end_pos-pos);
if (count->pack_type & PACK_TYPE_SELECTED)
@@ -1756,7 +1757,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
(uint) tree->code_len[(uchar) *start_pos]);
start_pos=end_pos;
break;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
for (pos=start_pos ; pos < end_pos && pos[0] == ' ' ; pos++) ;
length=(uint) (pos-start_pos);
if (count->pack_type & PACK_TYPE_SELECTED)
@@ -2087,7 +2088,7 @@ static void mrg_reset(PACK_MRG_INFO *mrg)
{
if (mrg->current)
{
- mi_extra(*mrg->current,HA_EXTRA_NO_CACHE);
+ mi_extra(*mrg->current, HA_EXTRA_NO_CACHE, 0);
mrg->current=0;
}
}
@@ -2102,8 +2103,8 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
{
isam_info= *(info->current=info->file);
info->end=info->current+info->count;
- mi_extra(isam_info,HA_EXTRA_RESET);
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info, HA_EXTRA_RESET, 0);
+ mi_extra(isam_info, HA_EXTRA_CACHE, 0);
filepos=isam_info->s->pack.header_length;
}
else
@@ -2119,14 +2120,14 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
filepos, 1)) ||
error != HA_ERR_END_OF_FILE)
return (error);
- mi_extra(isam_info,HA_EXTRA_NO_CACHE);
+ mi_extra(isam_info,HA_EXTRA_NO_CACHE, 0);
if (info->current+1 == info->end)
return(HA_ERR_END_OF_FILE);
info->current++;
isam_info= *info->current;
filepos=isam_info->s->pack.header_length;
- mi_extra(isam_info,HA_EXTRA_RESET);
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info,HA_EXTRA_RESET, 0);
+ mi_extra(isam_info,HA_EXTRA_CACHE, 0);
}
}
diff --git a/myisam/sort.c b/myisam/sort.c
index 161a5f92bf5..79d31147bfc 100644
--- a/myisam/sort.c
+++ b/myisam/sort.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,7 +19,7 @@
them in sorted order through SORT_INFO functions.
*/
-#include "myisamdef.h"
+#include "fulltext.h"
#if defined(MSDOS) || defined(__WIN__)
#include <fcntl.h>
#else
@@ -27,7 +27,8 @@
#endif
#include <queues.h>
- /* static variabels */
+/* static variables */
+
#undef MIN_SORT_MEMORY
#undef MYF_RW
#undef DISK_BUFFER_SIZE
@@ -35,64 +36,80 @@
#define MERGEBUFF 15
#define MERGEBUFF2 31
#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD)
-#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
+#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
#define DISK_BUFFER_SIZE (IO_SIZE*16)
typedef struct st_buffpek {
- my_off_t file_pos; /* Where we are in the sort file */
- uchar *base,*key; /* Key pointers */
- ha_rows count; /* Number of rows in table */
- ulong mem_count; /* numbers of keys in memory */
- ulong max_keys; /* Max keys in buffert */
+ my_off_t file_pos; /* Where we are in the sort file */
+ uchar *base,*key; /* Key pointers */
+ ha_rows count; /* Number of rows in table */
+ ulong mem_count; /* numbers of keys in memory */
+ ulong max_keys; /* Max keys in buffert */
} BUFFPEK;
extern void print_error _VARARGS((const char *fmt,...));
- /* functions defined in this file */
+/* Functions defined in this file */
static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info,uint keys,
- uchar **sort_keys,
- BUFFPEK *buffpek,int *maxbuffer,
- IO_CACHE *tempfile);
+ uchar **sort_keys,
+ DYNAMIC_ARRAY *buffpek,int *maxbuffer,
+ IO_CACHE *tempfile,
+ IO_CACHE *tempfile_for_exceptions);
static int NEAR_F write_keys(MI_SORT_PARAM *info,uchar * *sort_keys,
- uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
+ uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
+static int NEAR_F write_key(MI_SORT_PARAM *info, uchar *key,
+ IO_CACHE *tempfile);
static int NEAR_F write_index(MI_SORT_PARAM *info,uchar * *sort_keys,
- uint count);
+ uint count);
static int NEAR_F merge_many_buff(MI_SORT_PARAM *info,uint keys,
- uchar * *sort_keys,
- BUFFPEK *buffpek,int *maxbuffer,
- IO_CACHE *t_file);
+ uchar * *sort_keys,
+ BUFFPEK *buffpek,int *maxbuffer,
+ IO_CACHE *t_file);
static uint NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
- uint sort_length);
+ uint sort_length);
static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys,
- IO_CACHE *from_file, IO_CACHE *to_file,
- uchar * *sort_keys, BUFFPEK *lastbuff,
- BUFFPEK *Fb, BUFFPEK *Tb);
+ IO_CACHE *from_file, IO_CACHE *to_file,
+ uchar * *sort_keys, BUFFPEK *lastbuff,
+ BUFFPEK *Fb, BUFFPEK *Tb);
static int NEAR_F merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
- IO_CACHE *);
-static char **make_char_array(uint fields,uint length,myf my_flag);
+ IO_CACHE *);
+
- /* Creates a index of sorted keys */
- /* Returns 0 if everything went ok */
+/*
+ Creates a index of sorted keys
+
+ SYNOPSIS
+ _create_index_by_sort()
+ info Sort parameters
+ no_messages Set to 1 if no output
+ sortbuff_size Size if sortbuffer to allocate
+
+ RESULT
+ 0 ok
+ <> 0 Error
+*/
int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
ulong sortbuff_size)
{
int error,maxbuffer,skr;
uint memavl,old_memavl,keys,sort_length;
- BUFFPEK *buffpek;
+ DYNAMIC_ARRAY buffpek;
ha_rows records;
uchar **sort_keys;
- IO_CACHE tempfile;
+ IO_CACHE tempfile, tempfile_for_exceptions;
DBUG_ENTER("_create_index_by_sort");
DBUG_PRINT("enter",("sort_length: %d", info->key_length));
my_b_clear(&tempfile);
- buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
+ my_b_clear(&tempfile_for_exceptions);
+ bzero((char*) &buffpek,sizeof(buffpek));
+ sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
memavl=max(sortbuff_size,MIN_SORT_MEMORY);
- records= info->max_records;
+ records= info->sort_info->max_records;
sort_length= info->key_length;
LINT_INIT(keys);
@@ -116,14 +133,14 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
}
while ((maxbuffer= (int) (records/(keys-1)+1)) != skr);
- if ((sort_keys= (uchar **) make_char_array(keys,sort_length,MYF(0))))
+ if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
+ HA_FT_MAXLEN, MYF(0))))
{
- if ((buffpek = (BUFFPEK*) my_malloc((uint) (sizeof(BUFFPEK)*
- (uint) maxbuffer),
- MYF(0))))
- break;
- else
+ if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer,
+ maxbuffer/2))
my_free((gptr) sort_keys,MYF(0));
+ else
+ break;
}
old_memavl=memavl;
if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
@@ -139,7 +156,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (!no_messages)
printf(" - Searching for keys, allocating buffer for %d keys\n",keys);
- if ((records=find_all_keys(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile))
+ if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
+ &tempfile,&tempfile_for_exceptions))
== HA_POS_ERROR)
goto err; /* purecov: tested */
if (maxbuffer == 0)
@@ -156,111 +174,442 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
{
if (!no_messages)
printf(" - Merging %lu keys\n",records); /* purecov: tested */
- if (merge_many_buff(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile))
- goto err; /* purecov: inspected */
+ if (merge_many_buff(info,keys,sort_keys,
+ dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
+ goto err; /* purecov: inspected */
}
if (flush_io_cache(&tempfile) ||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
- goto err; /* purecov: inspected */
+ goto err; /* purecov: inspected */
if (!no_messages)
- puts(" - Last merge and dumping keys"); /* purecov: tested */
- if (merge_index(info,keys,sort_keys,buffpek,maxbuffer,&tempfile))
- goto err; /* purecov: inspected */
+ puts(" - Last merge and dumping keys\n"); /* purecov: tested */
+ if (merge_index(info,keys,sort_keys,dynamic_element(&buffpek,0,BUFFPEK *),
+ maxbuffer,&tempfile))
+ goto err; /* purecov: inspected */
}
+
+ if (flush_pending_blocks(info))
+ goto err;
+
+ if (my_b_inited(&tempfile_for_exceptions))
+ {
+ MI_INFO *index=info->sort_info->info;
+ uint keyno=info->key;
+ uint key_length, ref_length=index->s->rec_reflength;
+
+ if (flush_io_cache(&tempfile_for_exceptions) ||
+ reinit_io_cache(&tempfile_for_exceptions,READ_CACHE,0L,0,0))
+ goto err;
+
+ while (!my_b_read(&tempfile_for_exceptions,(byte*)&key_length,
+ sizeof(key_length))
+ && !my_b_read(&tempfile_for_exceptions,(byte*)sort_keys,
+ (uint) key_length))
+ {
+ if (_mi_ck_write(index,keyno,(uchar*) sort_keys,key_length-ref_length))
+ goto err;
+ }
+ }
+
error =0;
err:
if (sort_keys)
my_free((gptr) sort_keys,MYF(0));
- if (buffpek)
- my_free((gptr) buffpek,MYF(0));
+ delete_dynamic(&buffpek);
close_cached_file(&tempfile);
+ close_cached_file(&tempfile_for_exceptions);
DBUG_RETURN(error ? -1 : 0);
} /* _create_index_by_sort */
- /* Search after all keys and place them in a temp. file */
+/* Search after all keys and place them in a temp. file */
static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
- uchar **sort_keys, BUFFPEK *buffpek,
- int *maxbuffer, IO_CACHE *tempfile)
+ uchar **sort_keys, DYNAMIC_ARRAY *buffpek,
+ int *maxbuffer, IO_CACHE *tempfile,
+ IO_CACHE *tempfile_for_exceptions)
{
int error;
- uint idx,indexpos;
+ uint idx;
DBUG_ENTER("find_all_keys");
- idx=indexpos=error=0;
+ idx=error=0;
+ sort_keys[0]=(uchar*) (sort_keys+keys);
- while (!(error=(*info->key_read)(info->sort_info,sort_keys[idx])))
+ while (!(error=(*info->key_read)(info,sort_keys[idx])))
{
- if ((uint) ++idx == keys)
+ if (info->real_key_length > info->key_length)
{
- if (indexpos >= (uint) *maxbuffer ||
- write_keys(info,sort_keys,idx-1,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+ if (write_key(info,sort_keys[idx],tempfile_for_exceptions))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+ continue;
+ }
+
+ if (++idx == keys)
+ {
+ if (write_keys(info,sort_keys,idx-1,(BUFFPEK *)alloc_dynamic(buffpek),
+ tempfile))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+
+ sort_keys[0]=(uchar*) (sort_keys+keys);
memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
- idx=1; indexpos++;
+ idx=1;
}
+ sort_keys[idx]=sort_keys[idx-1]+info->key_length;
}
if (error > 0)
DBUG_RETURN(HA_POS_ERROR); /* Aborted by get_key */ /* purecov: inspected */
- if (indexpos)
- if (indexpos >= (uint) *maxbuffer ||
- write_keys(info,sort_keys,idx,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
- *maxbuffer=(int) indexpos;
- DBUG_RETURN(indexpos*(keys-1)+idx);
+ if (buffpek->elements)
+ {
+ if (write_keys(info,sort_keys,idx,(BUFFPEK *)alloc_dynamic(buffpek),
+ tempfile))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+ *maxbuffer=buffpek->elements-1;
+ }
+ else
+ *maxbuffer=0;
+
+ DBUG_RETURN((*maxbuffer)*(keys-1)+idx);
} /* find_all_keys */
- /* Write all keys in memory to file for later merge */
+/* Search after all keys and place them in a temp. file */
+
+pthread_handler_decl(thr_find_all_keys,arg)
+{
+ MI_SORT_PARAM *info= (MI_SORT_PARAM*) arg;
+ int error;
+ uint memavl,old_memavl,keys,sort_length;
+ uint idx, maxbuffer;
+ uchar **sort_keys=0;
+
+ error=1;
+
+ if (my_thread_init())
+ goto err;
+ if (info->sort_info->got_error)
+ goto err;
+
+ my_b_clear(&info->tempfile);
+ my_b_clear(&info->tempfile_for_exceptions);
+ bzero((char*) &info->buffpek,sizeof(info->buffpek));
+ bzero((char*) &info->unique, sizeof(info->unique));
+ sort_keys= (uchar **) NULL;
+
+ memavl=max(info->sortbuff_size, MIN_SORT_MEMORY);
+ idx= info->sort_info->max_records;
+ sort_length= info->key_length;
+ maxbuffer= 1;
+
+ while (memavl >= MIN_SORT_MEMORY)
+ {
+ if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
+ (my_off_t) memavl)
+ keys= idx+1;
+ else
+ {
+ uint skr;
+ do
+ {
+ skr=maxbuffer;
+ if (memavl < sizeof(BUFFPEK)*maxbuffer ||
+ (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
+ (sort_length+sizeof(char*))) <= 1)
+ {
+ mi_check_print_error(info->sort_info->param,
+ "sort_buffer_size is to small");
+ goto err;
+ }
+ }
+ while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
+ }
+ if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
+ ((info->keyinfo->flag & HA_FULLTEXT) ?
+ HA_FT_MAXLEN : 0), MYF(0))))
+ {
+ if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK),
+ maxbuffer, maxbuffer/2))
+ my_free((gptr) sort_keys,MYF(0));
+ else
+ break;
+ }
+ old_memavl=memavl;
+ if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
+ memavl=MIN_SORT_MEMORY;
+ }
+ if (memavl < MIN_SORT_MEMORY)
+ {
+ mi_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */
+ goto err; /* purecov: tested */
+ }
+// (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
+
+ if (info->sort_info->param->testflag & T_VERBOSE)
+ printf("Key %d - Allocating buffer for %d keys\n",info->key+1,keys);
+ info->sort_keys=sort_keys;
+
+ idx=error=0;
+ sort_keys[0]=(uchar*) (sort_keys+keys);
+
+ while (!(error=info->sort_info->got_error) &&
+ !(error=(*info->key_read)(info,sort_keys[idx])))
+ {
+ if (info->real_key_length > info->key_length)
+ {
+ if (write_key(info,sort_keys[idx], &info->tempfile_for_exceptions))
+ goto err;
+ continue;
+ }
+
+ if (++idx == keys)
+ {
+ if (write_keys(info,sort_keys,idx-1,
+ (BUFFPEK *)alloc_dynamic(&info->buffpek),
+ &info->tempfile))
+ goto err;
+ sort_keys[0]=(uchar*) (sort_keys+keys);
+ memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
+ idx=1;
+ }
+ sort_keys[idx]=sort_keys[idx-1]+info->key_length;
+ }
+ if (error > 0)
+ goto err;
+ if (info->buffpek.elements)
+ {
+ if (write_keys(info,sort_keys, idx,
+ (BUFFPEK *) alloc_dynamic(&info->buffpek), &info->tempfile))
+ goto err;
+ info->keys=(info->buffpek.elements-1)*(keys-1)+idx;
+ }
+ else
+ info->keys=idx;
+
+ info->sort_keys_length=keys;
+ goto ok;
+
+err:
+ info->sort_info->got_error=1; /* no need to protect this with a mutex */
+ if (sort_keys)
+ my_free((gptr) sort_keys,MYF(0));
+ info->sort_keys=0;
+ delete_dynamic(& info->buffpek);
+ close_cached_file(&info->tempfile);
+ close_cached_file(&info->tempfile_for_exceptions);
+
+ok:
+ remove_io_thread(&info->read_cache);
+ pthread_mutex_lock(&info->sort_info->mutex);
+ info->sort_info->threads_running--;
+ pthread_cond_signal(&info->sort_info->cond);
+ pthread_mutex_unlock(&info->sort_info->mutex);
+ my_thread_end();
+ return NULL;
+}
+
+
+int thr_write_keys(MI_SORT_PARAM *sort_param)
+{
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
+ ulong length, keys;
+ ulong *rec_per_key_part=param->rec_per_key_part;
+ int got_error=sort_info->got_error;
+ uint i;
+ MI_INFO *info=sort_info->info;
+ MYISAM_SHARE *share=info->s;
+ MI_SORT_PARAM *sinfo;
+ byte *mergebuf=0;
+ LINT_INIT(length);
+
+ for (i=0, sinfo=sort_param ; i<sort_info->total_keys ; i++,
+ rec_per_key_part+=sinfo->keyinfo->keysegs,
+ sinfo++)
+ {
+ if (!sinfo->sort_keys)
+ {
+ got_error=1;
+ continue;
+ }
+ if (!got_error)
+ {
+ share->state.key_map|=(ulonglong) 1 << sinfo->key;
+ if (param->testflag & T_STATISTICS)
+ update_key_parts(sinfo->keyinfo, rec_per_key_part,
+ sinfo->unique, (ulonglong) info->state->records);
+ if (!sinfo->buffpek.elements)
+ {
+ if (param->testflag & T_VERBOSE)
+ {
+ printf("Key %d - Dumping %u keys\n",sinfo->key+1, sinfo->keys);
+ fflush(stdout);
+ }
+ if (write_index(sinfo, sinfo->sort_keys, sinfo->keys) ||
+ flush_pending_blocks(sinfo))
+ got_error=1;
+ }
+ }
+ my_free((gptr) sinfo->sort_keys,MYF(0));
+ my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
+ sinfo->sort_keys=0;
+ }
+
+ for (i=0, sinfo=sort_param ; i<sort_info->total_keys ; i++,
+ delete_dynamic(&sinfo->buffpek),
+ close_cached_file(&sinfo->tempfile),
+ close_cached_file(&sinfo->tempfile_for_exceptions),
+ sinfo++)
+ {
+ if (got_error)
+ continue;
+ if (sinfo->buffpek.elements)
+ {
+ uint maxbuffer=sinfo->buffpek.elements-1;
+ if (!mergebuf)
+ {
+ length=param->sort_buffer_length;
+ while (length >= MIN_SORT_MEMORY && !mergebuf)
+ {
+ mergebuf=my_malloc(length, MYF(0));
+ length=length*3/4;
+ }
+ if (!mergebuf)
+ {
+ got_error=1;
+ continue;
+ }
+ }
+ keys=length/sinfo->key_length;
+ if (maxbuffer >= MERGEBUFF2)
+ {
+ if (param->testflag & T_VERBOSE)
+ printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys);
+ if (merge_many_buff(sinfo, keys, (uchar **)mergebuf,
+ dynamic_element(&sinfo->buffpek, 0, BUFFPEK *),
+ &maxbuffer, &sinfo->tempfile))
+ {
+ got_error=1;
+ continue;
+ }
+ }
+ if (flush_io_cache(&sinfo->tempfile) ||
+ reinit_io_cache(&sinfo->tempfile,READ_CACHE,0L,0,0))
+ {
+ got_error=1;
+ continue;
+ }
+ if (param->testflag & T_VERBOSE)
+ printf("Key %d - Last merge and dumping keys\n", sinfo->key+1);
+ if (merge_index(sinfo, keys, (uchar **)mergebuf,
+ dynamic_element(&sinfo->buffpek,0,BUFFPEK *),
+ maxbuffer,&sinfo->tempfile) ||
+ flush_pending_blocks(sinfo))
+ {
+ got_error=1;
+ continue;
+ }
+ }
+ if (my_b_inited(&sinfo->tempfile_for_exceptions))
+ {
+ uint key_length;
+
+ if (param->testflag & T_VERBOSE)
+ printf("Key %d - Dumping 'long' keys\n", sinfo->key+1);
+
+ if (flush_io_cache(&sinfo->tempfile_for_exceptions) ||
+ reinit_io_cache(&sinfo->tempfile_for_exceptions,READ_CACHE,0L,0,0))
+ {
+ got_error=1;
+ continue;
+ }
+
+ while (!got_error &&
+ !my_b_read(&sinfo->tempfile_for_exceptions,(byte*)&key_length,
+ sizeof(key_length)) &&
+ !my_b_read(&sinfo->tempfile_for_exceptions,(byte*)mergebuf,
+ (uint) key_length))
+ {
+ if (_mi_ck_write(info,sinfo->key,(uchar*) mergebuf,
+ key_length - info->s->rec_reflength))
+ got_error=1;
+ }
+ }
+ }
+ my_free((gptr) mergebuf,MYF(MY_ALLOW_ZERO_PTR));
+ return got_error;
+}
+
+ /* Write all keys in memory to file for later merge */
static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
- uint count, BUFFPEK *buffpek,
- IO_CACHE *tempfile)
+ uint count, BUFFPEK *buffpek, IO_CACHE *tempfile)
{
uchar **end;
uint sort_length=info->key_length;
DBUG_ENTER("write_keys");
qsort2((byte*) sort_keys,count,sizeof(byte*),(qsort2_cmp) info->key_cmp,
- info->sort_info);
+ info);
if (!my_b_inited(tempfile) &&
open_cached_file(tempfile, info->tmpdir, "ST", DISK_BUFFER_SIZE,
- info->myf_rw))
+ info->sort_info->param->myf_rw))
DBUG_RETURN(1); /* purecov: inspected */
+
buffpek->file_pos=my_b_tell(tempfile);
buffpek->count=count;
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
+ {
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
DBUG_RETURN(1); /* purecov: inspected */
+ }
DBUG_RETURN(0);
} /* write_keys */
- /* Write index */
+static int NEAR_F write_key(MI_SORT_PARAM *info, uchar *key,
+ IO_CACHE *tempfile)
+{
+ uint key_length=info->real_key_length;
+ DBUG_ENTER("write_key");
+
+ if (!my_b_inited(tempfile) &&
+ open_cached_file(tempfile, info->tmpdir, "ST", DISK_BUFFER_SIZE,
+ info->sort_info->param->myf_rw))
+ DBUG_RETURN(1);
+
+ if (my_b_write(tempfile,(byte*)&key_length,sizeof(key_length)) ||
+ my_b_write(tempfile,(byte*)key,(uint) key_length))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+} /* write_key */
+
+
+/* Write index */
static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
- register uint count)
+ register uint count)
{
DBUG_ENTER("write_index");
qsort2((gptr) sort_keys,(size_t) count,sizeof(byte*),
- (qsort2_cmp) info->key_cmp,info->sort_info);
+ (qsort2_cmp) info->key_cmp,info);
while (count--)
- if ((*info->key_write)(info->sort_info,*sort_keys++))
+ {
+ if ((*info->key_write)(info,*sort_keys++))
DBUG_RETURN(-1); /* purecov: inspected */
+ }
DBUG_RETURN(0);
} /* write_index */
- /* Merge buffers to make < MERGEBUFF2 buffers */
+ /* Merge buffers to make < MERGEBUFF2 buffers */
static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
- uchar **sort_keys, BUFFPEK *buffpek,
- int *maxbuffer, IO_CACHE *t_file)
+ uchar **sort_keys, BUFFPEK *buffpek,
+ int *maxbuffer, IO_CACHE *t_file)
{
register int i;
IO_CACHE t_file2, *from_file, *to_file, *temp;
@@ -268,11 +617,11 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
DBUG_ENTER("merge_many_buff");
if (*maxbuffer < MERGEBUFF2)
- DBUG_RETURN(0); /* purecov: inspected */
+ DBUG_RETURN(0); /* purecov: inspected */
if (flush_io_cache(t_file) ||
open_cached_file(&t_file2,info->tmpdir,"ST",DISK_BUFFER_SIZE,
- info->myf_rw))
- DBUG_RETURN(1); /* purecov: inspected */
+ info->sort_info->param->myf_rw))
+ DBUG_RETURN(1); /* purecov: inspected */
from_file= t_file ; to_file= &t_file2;
while (*maxbuffer >= MERGEBUFF2)
@@ -283,30 +632,40 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
{
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
- buffpek+i,buffpek+i+MERGEBUFF-1))
- break; /* purecov: inspected */
+ buffpek+i,buffpek+i+MERGEBUFF-1))
+ break; /* purecov: inspected */
}
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
- buffpek+i,buffpek+ *maxbuffer))
+ buffpek+i,buffpek+ *maxbuffer))
break; /* purecov: inspected */
if (flush_io_cache(to_file))
- break; /* purecov: inspected */
+ break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp;
*maxbuffer= (int) (lastbuff-buffpek)-1;
}
- close_cached_file(to_file); /* This holds old result */
+ close_cached_file(to_file); /* This holds old result */
if (to_file == t_file)
- *t_file=t_file2; /* Copy result file */
+ *t_file=t_file2; /* Copy result file */
- DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
+ DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
} /* merge_many_buff */
- /* Read data to buffer */
- /* This returns (uint) -1 if something goes wrong */
+/*
+ Read data to buffer
+
+ SYNOPSIS
+ read_to_buffer()
+ fromfile File to read from
+ buffpek Where to read from
+ sort_length max length to read
+ RESULT
+ > 0 Ammount of bytes read
+ -1 Error
+*/
static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+ uint sort_length)
{
register uint count;
uint length;
@@ -314,24 +673,26 @@ static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
{
if (my_pread(fromfile->file,(byte*) buffpek->base,
- (length= sort_length*count),buffpek->file_pos,MYF_RW))
- return((uint) -1); /* purecov: inspected */
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+ return((uint) -1); /* purecov: inspected */
buffpek->key=buffpek->base;
- buffpek->file_pos+= length; /* New filepos */
- buffpek->count-= count;
+ buffpek->file_pos+= length; /* New filepos */
+ buffpek->count-= count;
buffpek->mem_count= count;
}
return (count*sort_length);
} /* read_to_buffer */
- /* Merge buffers to one buffer */
- /* If to_file == 0 then use info->key_write */
+/*
+ Merge buffers to one buffer
+ If to_file == 0 then use info->key_write
+*/
static int NEAR_F
-merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
- IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
- BUFFPEK *Fb, BUFFPEK *Tb)
+merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
+ IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
+ BUFFPEK *Fb, BUFFPEK *Tb)
{
int error;
uint sort_length,maxcount;
@@ -351,8 +712,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
sort_length=info->key_length;
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
- (int (*)(void*, byte *,byte*)) info->key_cmp,
- (void*) info->sort_info))
+ (int (*)(void*, byte *,byte*)) info->key_cmp,
+ (void*) info))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
@@ -361,7 +722,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
buffpek->base= strpos;
buffpek->max_keys=maxcount;
strpos+= (uint) (error=(int) read_to_buffer(from_file,buffpek,
- sort_length));
+ sort_length));
if (error == -1)
goto err; /* purecov: inspected */
queue_insert(&queue,(char*) buffpek);
@@ -374,52 +735,52 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
buffpek=(BUFFPEK*) queue_top(&queue);
if (to_file)
{
- if (my_b_write(to_file,(byte*) buffpek->key,(uint) sort_length))
- {
- error=1; goto err; /* purecov: inspected */
- }
+ if (my_b_write(to_file,(byte*) buffpek->key,(uint) sort_length))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
}
else
{
- if ((*info->key_write)(info->sort_info,(void*) buffpek->key))
- {
- error=1; goto err; /* purecov: inspected */
- }
+ if ((*info->key_write)(info,(void*) buffpek->key))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
}
buffpek->key+=sort_length;
if (! --buffpek->mem_count)
{
- if (!(error=(int) read_to_buffer(from_file,buffpek,sort_length)))
- {
- uchar *base=buffpek->base;
- uint max_keys=buffpek->max_keys;
-
- VOID(queue_remove(&queue,0));
-
- /* Put room used by buffer to use in other buffer */
- for (refpek= (BUFFPEK**) &queue_top(&queue);
- refpek <= (BUFFPEK**) &queue_end(&queue);
- refpek++)
- {
- buffpek= *refpek;
- if (buffpek->base+buffpek->max_keys*sort_length == base)
- {
- buffpek->max_keys+=max_keys;
- break;
- }
- else if (base+max_keys*sort_length == buffpek->base)
- {
- buffpek->base=base;
- buffpek->max_keys+=max_keys;
- break;
- }
- }
- break; /* One buffer have been removed */
- }
+ if (!(error=(int) read_to_buffer(from_file,buffpek,sort_length)))
+ {
+ uchar *base=buffpek->base;
+ uint max_keys=buffpek->max_keys;
+
+ VOID(queue_remove(&queue,0));
+
+ /* Put room used by buffer to use in other buffer */
+ for (refpek= (BUFFPEK**) &queue_top(&queue);
+ refpek <= (BUFFPEK**) &queue_end(&queue);
+ refpek++)
+ {
+ buffpek= *refpek;
+ if (buffpek->base+buffpek->max_keys*sort_length == base)
+ {
+ buffpek->max_keys+=max_keys;
+ break;
+ }
+ else if (base+max_keys*sort_length == buffpek->base)
+ {
+ buffpek->base=base;
+ buffpek->max_keys+=max_keys;
+ break;
+ }
+ }
+ break; /* One buffer have been removed */
+ }
}
else if (error == -1)
- goto err; /* purecov: inspected */
- queue_replaced(&queue); /* Top element has been replaced */
+ goto err; /* purecov: inspected */
+ queue_replaced(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
@@ -430,9 +791,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
if (to_file)
{
if (my_b_write(to_file,(byte*) buffpek->key,
- (sort_length*buffpek->mem_count)))
+ (sort_length*buffpek->mem_count)))
{
- error=1; goto err; /* purecov: inspected */
+ error=1; goto err; /* purecov: inspected */
}
}
else
@@ -440,18 +801,18 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
register uchar *end;
strpos= buffpek->key;
for (end=strpos+buffpek->mem_count*sort_length;
- strpos != end ;
- strpos+=sort_length)
+ strpos != end ;
+ strpos+=sort_length)
{
- if ((*info->key_write)(info->sort_info,(void*) strpos))
- {
- error=1; goto err; /* purecov: inspected */
- }
+ if ((*info->key_write)(info,(void*) strpos))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
}
}
}
while ((error=(int) read_to_buffer(from_file,buffpek,sort_length)) != -1 &&
- error != 0);
+ error != 0);
lastbuff->count=count;
if (to_file)
@@ -462,34 +823,16 @@ err:
} /* merge_buffers */
- /* Do a merge to output-file (save only positions) */
+ /* Do a merge to output-file (save only positions) */
static int NEAR_F
merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
- BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
+ BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
{
DBUG_ENTER("merge_index");
if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
- buffpek+maxbuffer))
+ buffpek+maxbuffer))
DBUG_RETURN(1); /* purecov: inspected */
DBUG_RETURN(0);
} /* merge_index */
-
- /* Make a pointer of arrays to keys */
-
-static char **make_char_array(register uint fields, uint length, myf my_flag)
-{
- register char **pos;
- char **old_pos,*char_pos;
- DBUG_ENTER("make_char_array");
-
- if ((old_pos= (char**) my_malloc( fields*(length+sizeof(char*)), my_flag)))
- {
- pos=old_pos; char_pos=((char*) (pos+fields)) -length;
- while (fields--)
- *(pos++) = (char_pos+= length);
- }
-
- DBUG_RETURN(old_pos);
-} /* make_char_array */
diff --git a/myisammrg/Makefile.am b/myisammrg/Makefile.am
index b09d7d70191..5355534eb77 100644
--- a/myisammrg/Makefile.am
+++ b/myisammrg/Makefile.am
@@ -16,12 +16,12 @@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
pkglib_LIBRARIES = libmyisammrg.a
-noinst_HEADERS = mymrgdef.h
+noinst_HEADERS = myrg_def.h
libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \
myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \
myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
- myrg_rprev.c myrg_queue.c
+ myrg_rprev.c myrg_queue.c myrg_write.c
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
__math.h time.h __time.h unistd.h __unistd.h types.h \
xtypes.h ac-types.h posix.h string.h __string.h \
diff --git a/myisammrg/mymrgdef.h b/myisammrg/mymrgdef.h
deleted file mode 100644
index aae1d07cd64..00000000000
--- a/myisammrg/mymrgdef.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* This file is included by all myisam-merge files */
-
-#ifndef N_MAXKEY
-#include "../myisam/myisamdef.h"
-#endif
-
-#include "myisammrg.h"
-
-extern LIST *myrg_open_list;
-
-#ifdef THREAD
-extern pthread_mutex_t THR_LOCK_open;
-#endif
-
-int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
diff --git a/myisammrg/myrg_close.c b/myisammrg/myrg_close.c
index 7ab73c5ded4..897020c6865 100644
--- a/myisammrg/myrg_close.c
+++ b/myisammrg/myrg_close.c
@@ -1,22 +1,22 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* close a isam-database */
-#include "mymrgdef.h"
+#include "myrg_def.h"
int myrg_close(MYRG_INFO *info)
{
diff --git a/myisammrg/myrg_create.c b/myisammrg/myrg_create.c
index 113831b9d7f..5fc3c60ff32 100644
--- a/myisammrg/myrg_create.c
+++ b/myisammrg/myrg_create.c
@@ -1,29 +1,30 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Create a MYMERGE_-file */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* create file named 'name' and save filenames in it
table_names should be NULL or a vector of string-pointers with
a NULL-pointer last
*/
-int myrg_create(const char *name, const char **table_names, my_bool fix_names)
+int myrg_create(const char *name, const char **table_names,
+ uint insert_method, my_bool fix_names)
{
int save_errno;
uint errpos;
@@ -50,6 +51,13 @@ int myrg_create(const char *name, const char **table_names, my_bool fix_names)
goto err;
}
}
+ if (insert_method != MERGE_INSERT_DISABLED)
+ {
+ end=strxmov(buff,"#INSERT_METHOD=",
+ get_type(&merge_insert_method,insert_method-1),"\n",NullS);
+ if (my_write(file,buff,(uint) (end-buff),MYF(MY_WME | MY_NABP)))
+ goto err;
+ }
if (my_close(file,MYF(0)))
goto err;
DBUG_RETURN(0);
diff --git a/myisammrg/myrg_def.h b/myisammrg/myrg_def.h
new file mode 100644
index 00000000000..d56cf4aa8d8
--- /dev/null
+++ b/myisammrg/myrg_def.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* This file is included by all myisam-merge files */
+
+#ifndef N_MAXKEY
+#include "../myisam/myisamdef.h"
+#endif
+
+#include "myisammrg.h"
+
+extern LIST *myrg_open_list;
+
+#ifdef THREAD
+extern pthread_mutex_t THR_LOCK_open;
+#endif
+
+int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
diff --git a/myisammrg/myrg_delete.c b/myisammrg/myrg_delete.c
index 9ac32655172..8b89ed62ac1 100644
--- a/myisammrg/myrg_delete.c
+++ b/myisammrg/myrg_delete.c
@@ -1,30 +1,27 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Delete last read record */
-#include "mymrgdef.h"
+#include "myrg_def.h"
-int myrg_delete(
-MYRG_INFO *info,
-const byte *record)
+int myrg_delete(MYRG_INFO *info, const byte *record)
{
if (!info->current_table)
- {
- return(my_errno=HA_ERR_NO_ACTIVE_RECORD);
- }
+ return (my_errno= HA_ERR_NO_ACTIVE_RECORD);
+
return mi_delete(info->current_table->table,record);
}
diff --git a/myisammrg/myrg_extra.c b/myisammrg/myrg_extra.c
index c8a634e748f..ad17b0f82f2 100644
--- a/myisammrg/myrg_extra.c
+++ b/myisammrg/myrg_extra.c
@@ -20,9 +20,10 @@
record-cache-flags are set in myrg_rrnd when we are changing database.
*/
-#include "mymrgdef.h"
+#include "myrg_def.h"
-int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
+int myrg_extra(MYRG_INFO *info,enum ha_extra_function function,
+ void *extra_arg)
{
int error,save_error=0;
MYRG_TABLE *file;
@@ -30,7 +31,11 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
DBUG_PRINT("info",("function: %d",(ulong) function));
if (function == HA_EXTRA_CACHE)
+ {
info->cache_in_use=1;
+ info->cache_size= (extra_arg ? *(long*) extra_arg :
+ my_default_record_cache_size);
+ }
else
{
if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET)
@@ -41,8 +46,22 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
info->last_used_table=info->open_tables;
}
for (file=info->open_tables ; file != info->end_table ; file++)
- if ((error=mi_extra(file->table,function)))
+ {
+ if ((error=mi_extra(file->table, function, extra_arg)))
save_error=error;
+ }
}
DBUG_RETURN(save_error);
}
+
+
+void myrg_extrafunc(MYRG_INFO *info, invalidator_by_filename inv)
+{
+ MYRG_TABLE *file;
+ DBUG_ENTER("myrg_extrafunc");
+
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ file->table->s->invalidator = inv;
+
+ DBUG_VOID_RETURN;
+}
diff --git a/myisammrg/myrg_info.c b/myisammrg/myrg_info.c
index 8ca830339b9..14bc228cc1f 100644
--- a/myisammrg/myrg_info.c
+++ b/myisammrg/myrg_info.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
ulonglong myrg_position(MYRG_INFO *info)
{
diff --git a/myisammrg/myrg_locking.c b/myisammrg/myrg_locking.c
index c89acca3918..e5a8d3f3d9d 100644
--- a/myisammrg/myrg_locking.c
+++ b/myisammrg/myrg_locking.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,11 +18,9 @@
Lock databases against read or write.
*/
-#include "mymrgdef.h"
+#include "myrg_def.h"
-int myrg_lock_database(
-MYRG_INFO *info,
-int lock_type)
+int myrg_lock_database(MYRG_INFO *info, int lock_type)
{
int error,new_error;
MYRG_TABLE *file;
diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c
index df94fb680cb..9360f582958 100644
--- a/myisammrg/myrg_open.c
+++ b/myisammrg/myrg_open.c
@@ -14,29 +14,26 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* open a MYMERGE_-database */
+/* open a MyISAM MERGE table */
-#include "mymrgdef.h"
+#include "myrg_def.h"
#include <stddef.h>
#include <errno.h>
#ifdef VMS
#include "mrg_static.c"
#endif
-/* open a MYMERGE_-database.
-
- if handle_locking is 0 then exit with error if some database is locked
- if handle_locking is 1 then wait if database is locked
+/*
+ open a MyISAM MERGE table
+ if handle_locking is 0 then exit with error if some table is locked
+ if handle_locking is 1 then wait if table is locked
*/
-MYRG_INFO *myrg_open(
-const char *name,
-int mode,
-int handle_locking)
+MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
int save_errno,i,errpos;
- uint files,dir_length,length;
+ uint files,dir_length,length,options;
ulonglong file_offset;
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
MYRG_INFO info,*m_info;
@@ -63,25 +60,34 @@ int handle_locking)
{
if ((end=buff+length)[-1] == '\n')
end[-1]='\0';
- if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
+ if (!buff[0])
+ continue; /* Skip empty lines */
+ if (buff[0] == '#')
{
- if (!test_if_hard_path(buff))
- {
- VOID(strmake(name_buff+dir_length,buff,
- sizeof(name_buff)-1-dir_length));
- VOID(cleanup_dirname(buff,name_buff));
+ if( !strncmp(buff+1,"INSERT_METHOD=",14))
+ { /* Lookup insert method */
+ int tmp=find_type(buff+15,&merge_insert_method,2);
+ info.merge_insert_method = (uint) (tmp >= 0 ? tmp : 0);
}
- if (!(isam=mi_open(buff,mode,test(handle_locking))))
- goto err;
- files++;
- last_isam=isam;
- if (info.reclength && info.reclength != isam->s->base.reclength)
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
+ continue; /* Skip comments */
+ }
+
+ if (!test_if_hard_path(buff))
+ {
+ VOID(strmake(name_buff+dir_length,buff,
+ sizeof(name_buff)-1-dir_length));
+ VOID(cleanup_dirname(buff,name_buff));
+ }
+ if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
goto err;
- }
- info.reclength=isam->s->base.reclength;
+ files++;
+ last_isam=isam;
+ if (info.reclength && info.reclength != isam->s->base.reclength)
+ {
+ my_errno=HA_ERR_WRONG_IN_RECORD;
+ goto err;
}
+ info.reclength=isam->s->base.reclength;
}
if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO)+
files*sizeof(MYRG_TABLE),
@@ -92,16 +98,22 @@ int handle_locking)
m_info->tables=files;
errpos=2;
+ options= (uint) ~0;
for (i=files ; i-- > 0 ; )
{
m_info->open_tables[i].table=isam;
m_info->options|=isam->s->options;
+ options&=isam->s->options;
m_info->records+=isam->state->records;
m_info->del+=isam->state->del;
m_info->data_file_length+=isam->state->data_file_length;
if (i)
isam=(MI_INFO*) (isam->open_list.next->data);
}
+ /* Don't force readonly if not all tables are readonly */
+ if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA)))
+ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);
+
/* Fix fileinfo for easyer debugging (actually set by rrnd) */
file_offset=0;
for (i=0 ; (uint) i < files ; i++)
diff --git a/myisammrg/myrg_panic.c b/myisammrg/myrg_panic.c
index 99a1f6828d1..ab08b8082c3 100644
--- a/myisammrg/myrg_panic.c
+++ b/myisammrg/myrg_panic.c
@@ -1,20 +1,20 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* if flag == HA_PANIC_CLOSE then all misam files are closed */
/* if flag == HA_PANIC_WRITE then all misam files are unlocked and
diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c
index d6f831db48c..b4f729fc2cf 100644
--- a/myisammrg/myrg_queue.c
+++ b/myisammrg/myrg_queue.c
@@ -16,7 +16,7 @@
/* Read record based on a key */
-#include "mymrgdef.h"
+#include "myrg_def.h"
static int queue_key_cmp(void *keyseg, byte *a, byte *b)
{
diff --git a/myisammrg/myrg_rfirst.c b/myisammrg/myrg_rfirst.c
index 0625e848660..2ee9c015a84 100644
--- a/myisammrg/myrg_rfirst.c
+++ b/myisammrg/myrg_rfirst.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* Read first row according to specific key */
diff --git a/myisammrg/myrg_rkey.c b/myisammrg/myrg_rkey.c
index cd2c73c8ec2..ba042352a51 100644
--- a/myisammrg/myrg_rkey.c
+++ b/myisammrg/myrg_rkey.c
@@ -27,7 +27,7 @@
*/
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* todo: we could store some additional info to speedup lookups:
column (key, keyseg) can be constant per table
diff --git a/myisammrg/myrg_rlast.c b/myisammrg/myrg_rlast.c
index f41844dfd5c..e03a07c295a 100644
--- a/myisammrg/myrg_rlast.c
+++ b/myisammrg/myrg_rlast.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* Read last row with the same key as the previous read. */
diff --git a/myisammrg/myrg_rnext.c b/myisammrg/myrg_rnext.c
index 703ca29632b..6d657b5926c 100644
--- a/myisammrg/myrg_rnext.c
+++ b/myisammrg/myrg_rnext.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/*
Read next row with the same key as previous read
diff --git a/myisammrg/myrg_rprev.c b/myisammrg/myrg_rprev.c
index 8c43b40035a..c21ca06dacd 100644
--- a/myisammrg/myrg_rprev.c
+++ b/myisammrg/myrg_rprev.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/*
Read previous row with the same key as previous read
diff --git a/myisammrg/myrg_rrnd.c b/myisammrg/myrg_rrnd.c
index de731e58d5b..d623ea8ea9c 100644
--- a/myisammrg/myrg_rrnd.c
+++ b/myisammrg/myrg_rrnd.c
@@ -19,12 +19,12 @@
get by myrg_info(). The next record can be read with pos= -1 */
-#include "mymrgdef.h"
+#include "myrg_def.h"
static MYRG_TABLE *find_table(MYRG_TABLE *start,MYRG_TABLE *end,ulonglong pos);
/*
- If filepos == HA_OFFSET_ERROR, read next
+ If filepos == HA_OFFSET_ERROR, read next
Returns same as mi_rrnd:
0 = Ok.
HA_ERR_RECORD_DELETED = Record is deleted.
@@ -48,7 +48,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
}
isam_info=(info->current_table=info->open_tables)->table;
if (info->cache_in_use)
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info,HA_EXTRA_CACHE,(byte*) &info->cache_size);
filepos=isam_info->s->pack.header_length;
isam_info->lastinx= (uint) -1; /* Can't forward or backward */
}
@@ -66,13 +66,15 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
HA_ERR_END_OF_FILE)
DBUG_RETURN(error);
if (info->cache_in_use)
- mi_extra(info->current_table->table,HA_EXTRA_NO_CACHE);
+ mi_extra(info->current_table->table, HA_EXTRA_NO_CACHE,
+ (byte*) &info->cache_size);
if (info->current_table+1 == info->end_table)
DBUG_RETURN(HA_ERR_END_OF_FILE);
info->current_table++;
info->last_used_table=info->current_table;
if (info->cache_in_use)
- mi_extra(info->current_table->table,HA_EXTRA_CACHE);
+ mi_extra(info->current_table->table, HA_EXTRA_CACHE,
+ (byte*) &info->cache_size);
info->current_table->file_offset=
info->current_table[-1].file_offset+
info->current_table[-1].table->state->data_file_length;
diff --git a/myisammrg/myrg_rsame.c b/myisammrg/myrg_rsame.c
index 301b96e667b..f6b2164dc21 100644
--- a/myisammrg/myrg_rsame.c
+++ b/myisammrg/myrg_rsame.c
@@ -1,30 +1,28 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
int myrg_rsame(MYRG_INFO *info,byte *record,int inx)
{
if (inx) /* not yet used, should be 0 */
- {
- return(my_errno=HA_ERR_WRONG_INDEX);
- }
+ return (my_errno=HA_ERR_WRONG_INDEX);
+
if (!info->current_table)
- {
- return(my_errno=HA_ERR_NO_ACTIVE_RECORD);
- }
+ return (my_errno=HA_ERR_NO_ACTIVE_RECORD);
+
return mi_rsame(info->current_table->table,record,inx);
}
diff --git a/myisammrg/myrg_static.c b/myisammrg/myrg_static.c
index 88eb095382b..b21b834ac24 100644
--- a/myisammrg/myrg_static.c
+++ b/myisammrg/myrg_static.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,11 @@
*/
#ifndef stdin
-#include "mymrgdef.h"
+#include "myrg_def.h"
#endif
LIST *myrg_open_list=0;
+static const char *merge_insert_methods[] =
+{ "FIRST", "LAST", NullS };
+TYPELIB merge_insert_method= { array_elements(merge_insert_methods)-1,"",
+ merge_insert_methods};
diff --git a/myisammrg/myrg_update.c b/myisammrg/myrg_update.c
index b75c6ea6f9b..7b9f614b965 100644
--- a/myisammrg/myrg_update.c
+++ b/myisammrg/myrg_update.c
@@ -1,26 +1,27 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Update last read record */
-#include "mymrgdef.h"
+#include "myrg_def.h"
int myrg_update(register MYRG_INFO *info,const byte *oldrec, byte *newrec)
{
if (!info->current_table)
- return(my_errno=HA_ERR_NO_ACTIVE_RECORD);
+ return (my_errno=HA_ERR_NO_ACTIVE_RECORD);
+
return mi_update(info->current_table->table,oldrec,newrec);
}
diff --git a/myisammrg/myrg_write.c b/myisammrg/myrg_write.c
new file mode 100644
index 00000000000..0f191edc23c
--- /dev/null
+++ b/myisammrg/myrg_write.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2001 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Write a row to a MyISAM MERGE table */
+
+#include "myrg_def.h"
+
+int myrg_write(register MYRG_INFO *info, byte *rec)
+{
+ /* [phi] MERGE_WRITE_DISABLED is handled by the else case */
+ if (info->merge_insert_method == MERGE_INSERT_TO_FIRST)
+ return mi_write(info->open_tables[0].table,rec);
+ else if (info->merge_insert_method == MERGE_INSERT_TO_LAST)
+ return mi_write(info->end_table[-1].table,rec);
+ else /* unsupported insertion method */
+ return (my_errno= HA_ERR_WRONG_COMMAND);
+}
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index d98c10a29a9..91333dfad9b 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -59,6 +59,8 @@ SUFFIXES = .sh
-e 's!@''libexecdir''@!$(libexecdir)!g' \
-e 's!@''PERL''@!@PERL@!' \
-e 's!@''VERSION''@!@VERSION@!' \
+ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \
+ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \
-e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \
$< > $@-t
@CHMOD@ +x $@-t
diff --git a/mysql-test/create-test-result b/mysql-test/create-test-result
index 24c3d175303..bfd64f32fc5 100755
--- a/mysql-test/create-test-result
+++ b/mysql-test/create-test-result
@@ -5,7 +5,7 @@
# If you have a spare moment feel free to improve it - the right way is
# to start mysqld yourself and run mysqltest -r
-RESULT_DIR=r/3.23
+RESULT_DIR=r
if [ -z $EDITOR] ; then
EDITOR=vi
fi
@@ -32,7 +32,7 @@ result_file=$RESULT_DIR/$test_name.result
touch $result_file
echo "Running the test case against empty file, will fail, but don't worry"
-./mysql-test-run $test_name
+./mysql-test-run --do-test=$test_name
reject_file=$result_file.reject
diff --git a/mysql-test/fix-result b/mysql-test/fix-result
new file mode 100755
index 00000000000..bd380332ff5
--- /dev/null
+++ b/mysql-test/fix-result
@@ -0,0 +1,22 @@
+#! /bin/sh
+
+# Sasha's hack to fix results generated with mysql-test-run --record
+# to be version and test port independent. In some cases, further minor
+# manual edititing may be required, but most of the time it should not
+# happen
+
+#It is assumed we are running the script in mysql-test directory
+
+VERSION=4.0.1-alpha-debug-log
+TEST_CASE=$1
+
+if [ -z "$TEST_CASE" ] ;
+then
+ echo "usage: $0 test_case_name"
+ exit 1
+fi
+
+../extra/replace $VERSION '$VERSION' 9306 '$MASTER_MYPORT' 9307 \
+'$SLAVE_MYPORT' \\ \\\\ -- r/$TEST_CASE.result
+
+
diff --git a/mysql-test/include/have_bdb.inc b/mysql-test/include/have_bdb.inc
index 0126e30210f..3f7377e7515 100644
--- a/mysql-test/include/have_bdb.inc
+++ b/mysql-test/include/have_bdb.inc
@@ -1,2 +1,4 @@
-- require r/have_bdb.require
+disable_query_log;
show variables like "have_bdb";
+enable_query_log;
diff --git a/mysql-test/include/have_gemini.inc b/mysql-test/include/have_gemini.inc
deleted file mode 100644
index 78a84ac6f3e..00000000000
--- a/mysql-test/include/have_gemini.inc
+++ /dev/null
@@ -1,2 +0,0 @@
--- require r/have_gemini.require
-show variables like "have_gemini";
diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc
index 7dcaef44878..4f83d378cbc 100644
--- a/mysql-test/include/have_innodb.inc
+++ b/mysql-test/include/have_innodb.inc
@@ -1,2 +1,4 @@
-- require r/have_innodb.require
+disable_query_log;
show variables like "have_innodb";
+enable_query_log;
diff --git a/mysql-test/include/have_isam.inc b/mysql-test/include/have_isam.inc
index d83328f70f4..830170c921f 100644
--- a/mysql-test/include/have_isam.inc
+++ b/mysql-test/include/have_isam.inc
@@ -1,2 +1,4 @@
-- require r/have_isam.require
+disable_query_log;
show variables like "have_isam";
+enable_query_log;
diff --git a/mysql-test/include/have_openssl.inc b/mysql-test/include/have_openssl.inc
new file mode 100644
index 00000000000..54c5b04b3e4
--- /dev/null
+++ b/mysql-test/include/have_openssl.inc
@@ -0,0 +1,4 @@
+-- require r/have_openssl.require
+disable_query_log;
+show variables like "have_openssl";
+enable_query_log;
diff --git a/mysql-test/include/have_openssl_1.inc b/mysql-test/include/have_openssl_1.inc
new file mode 100644
index 00000000000..4d3646abdc2
--- /dev/null
+++ b/mysql-test/include/have_openssl_1.inc
@@ -0,0 +1,4 @@
+-- require r/have_openssl_1.require
+disable_query_log;
+show variables like "have_openssl";
+enable_query_log;
diff --git a/mysql-test/include/have_openssl_2.inc b/mysql-test/include/have_openssl_2.inc
new file mode 100644
index 00000000000..724d295a398
--- /dev/null
+++ b/mysql-test/include/have_openssl_2.inc
@@ -0,0 +1,4 @@
+-- require r/have_openssl_2.require
+disable_query_log;
+SHOW STATUS LIKE "SSL_get_cipher";
+enable_query_log;
diff --git a/mysql-test/include/have_query_cache.inc b/mysql-test/include/have_query_cache.inc
new file mode 100644
index 00000000000..e5e6052c9a7
--- /dev/null
+++ b/mysql-test/include/have_query_cache.inc
@@ -0,0 +1,4 @@
+-- require r/have_query_cache.require
+disable_query_log;
+show variables like "have_query_cache";
+enable_query_log;
diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc
index 61077f898f6..23392690239 100644
--- a/mysql-test/include/master-slave.inc
+++ b/mysql-test/include/master-slave.inc
@@ -1,8 +1,9 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (master1,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
-connect (slave1,localhost,root,,test,0,mysql-slave.sock);
+connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (master1,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
+connect (slave1,127.0.0.1,root,,test,$SLAVE_MYPORT,);
connection slave;
+--error 0,1199
!slave stop;
@r/slave-stopped.result show status like 'Slave_running';
connection master;
diff --git a/mysql-test/include/not_embedded.inc b/mysql-test/include/not_embedded.inc
new file mode 100644
index 00000000000..52ae026ece3
--- /dev/null
+++ b/mysql-test/include/not_embedded.inc
@@ -0,0 +1,5 @@
+-- require r/not_embedded.require
+disable_query_log;
+select version() like "%embedded%" as "have_embedded";
+enable_query_log;
+
diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh
index 6fe736644d3..104242cc3b1 100644
--- a/mysql-test/install_test_db.sh
+++ b/mysql-test/install_test_db.sh
@@ -30,7 +30,7 @@ else
fi
mdata=$data/mysql
-
+EXTRA_ARG=""
if test ! -x $execdir/mysqld
then
@@ -57,9 +57,7 @@ if [ x$BINARY_DIST = x1 ] ; then
basedir=..
else
basedir=.
-rm -rf share
-mkdir share
-ln -f -s ../../sql/share share/mysql
+EXTRA_ARG="--language=../sql/share/english/"
fi
# Initialize variables
@@ -119,9 +117,9 @@ fi
if test ! -f $mdata/user.frm
then
c_u="$c_u CREATE TABLE user ("
- c_u="$c_u Host char(60) DEFAULT '' NOT NULL,"
- c_u="$c_u User char(16) DEFAULT '' NOT NULL,"
- c_u="$c_u Password char(16) DEFAULT '' NOT NULL,"
+ c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u User char(16) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u Password char(16) binary DEFAULT '' NOT NULL,"
c_u="$c_u Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
@@ -136,16 +134,29 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
+ c_u="$c_u ssl_cipher BLOB NOT NULL,"
+ c_u="$c_u x509_issuer BLOB NOT NULL,"
+ c_u="$c_u x509_subject BLOB NOT NULL,"
+ c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
c_u="$c_u PRIMARY KEY Host (Host,User)"
c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';"
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
-
- INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');
- INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');"
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user (host,user) values ('localhost','');
+ INSERT INTO user (host,user) values ('$hostname','');"
fi
if test ! -f $mdata/func.frm
@@ -192,8 +203,11 @@ then
c_c="$c_c comment='Column privileges';"
fi
-if $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
- --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb --skip-gemini << END_OF_DATA
+mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
+ --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $EXTRA_ARG"
+echo "running $mysqld_boot"
+
+if $mysqld_boot << END_OF_DATA
use mysql;
$c_d
$i_d
@@ -213,5 +227,6 @@ END_OF_DATA
then
exit 0
else
+ echo "Error executing mysqld --bootstrap"
exit 1
fi
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 4898d9c5464..66bc7f5069b 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -12,13 +12,15 @@
DB=test
DBPASSWD=
VERBOSE=""
+USE_MANAGER=0
TZ=GMT-3; export TZ # for UNIX_TIMESTAMP tests to work
#++
# Program Definitions
#--
-PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin
+PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin
+MASTER_40_ARGS="--rpl-recovery-rank=1 --init-rpl-role=master"
# Standard functions
@@ -42,6 +44,39 @@ which ()
}
+sleep_until_file_deleted ()
+{
+ file=$1
+ loop=$SLEEP_TIME_FOR_DELETE
+ while (test $loop -gt 0)
+ do
+ if [ ! -r $file ]
+ then
+ sleep $SLEEP_TIME_AFTER_RESTART
+ return
+ fi
+ loop=`expr $loop - 1`
+ done
+}
+
+sleep_until_file_created ()
+{
+ file=$1
+ loop=$2
+ org_time=$2
+ while (test $loop -gt 0)
+ do
+ if [ -r $file ]
+ then
+ return
+ fi
+ sleep 1
+ loop=`expr $loop - 1`
+ done
+ echo "ERROR: $file was not created in $org_time seconds; Aborting"
+ exit 1;
+}
+
# No paths below as we can't be sure where the program is!
SED=sed
@@ -50,6 +85,7 @@ BASENAME=`which basename | $SED q`
DIFF=`which diff | $SED q`
CAT=cat
CUT=cut
+HEAD=head
TAIL=tail
ECHO=echo # use internal echo if possible
EXPR=expr # use internal if possible
@@ -90,7 +126,7 @@ else
BINARY_DIST=1
fi
-#BASEDIR is always one above mysql-test directory
+#BASEDIR is always one above mysql-test directory
CWD=`pwd`
cd ..
BASEDIR=`pwd`
@@ -99,7 +135,8 @@ MYSQL_TEST_DIR=$BASEDIR/mysql-test
export MYSQL_TEST_DIR
STD_DATA=$MYSQL_TEST_DIR/std_data
hostname=`hostname` # Installed in the mysql privilege table
-
+
+MANAGER_QUIET_OPT="-q"
TESTDIR="$MYSQL_TEST_DIR/t"
TESTSUFFIX=test
TOT_SKIP=0
@@ -114,16 +151,21 @@ SLAVE_LOAD_TMPDIR=../../var/tmp #needs to be same length to test logging
RES_SPACE=" "
MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \
myisammrg heap sql"
+MY_LOG_DIR="$MYSQL_TEST_DIR/var/log"
#
# Set LD_LIBRARY_PATH if we are using shared libraries
#
-LD_LIBRARY_PATH="$BASEDIR/lib:$LD_LIBRARY_PATH"
+LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
MASTER_RUNNING=0
MASTER_MYPORT=9306
SLAVE_RUNNING=0
SLAVE_MYPORT=9307
+MYSQL_MANAGER_PORT=9305 # needs to be out of the way of slaves
+MYSQL_MANAGER_PW_FILE=$MYSQL_TEST_DIR/var/tmp/manager.pwd
+MYSQL_MANAGER_LOG=$MYSQL_TEST_DIR/var/log/manager.log
+MYSQL_MANAGER_USER=root
NO_SLAVE=0
USER_TEST=
@@ -132,19 +174,40 @@ EXTRA_MYSQL_TEST_OPT=""
USE_RUNNING_SERVER=1
DO_GCOV=""
DO_GDB=""
+MANUAL_GDB=""
DO_DDD=""
DO_CLIENT_GDB=""
-SLEEP_TIME=2
+SLEEP_TIME_AFTER_RESTART=1
+SLEEP_TIME_FOR_DELETE=10
+SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables
+SLEEP_TIME_FOR_SECOND_MASTER=30
+SLEEP_TIME_FOR_FIRST_SLAVE=400
+SLEEP_TIME_FOR_SECOND_SLAVE=30
+CHARACTER_SET=latin1
DBUSER=""
+START_WAIT_TIMEOUT=10
+STOP_WAIT_TIMEOUT=10
while test $# -gt 0; do
case "$1" in
--user=*) DBUSER=`$ECHO "$1" | $SED -e "s;--user=;;"` ;;
--force) FORCE=1 ;;
+ --verbose-manager) MANAGER_QUIET_OPT="" ;;
+ --old-master) MASTER_40_ARGS="";;
+ --master-binary=*)
+ MASTER_MYSQLD=`$ECHO "$1" | $SED -e "s;--master-binary=;;"` ;;
+ --slave-binary=*)
+ SLAVE_MYSQLD=`$ECHO "$1" | $SED -e "s;--slave-binary=;;"` ;;
--local) USE_RUNNING_SERVER="" ;;
--tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;;
+ --local-master)
+ MASTER_MYPORT=3306;
+ EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT --host=127.0.0.1 \
+ --port=$MYSQL_MYPORT"
+ LOCAL_MASTER=1 ;;
--master_port=*) MASTER_MYPORT=`$ECHO "$1" | $SED -e "s;--master_port=;;"` ;;
--slave_port=*) SLAVE_MYPORT=`$ECHO "$1" | $SED -e "s;--slave_port=;;"` ;;
+ --manager-port=*) MYSQL_MANAGER_PORT=`$ECHO "$1" | $SED -e "s;--manager_port=;;"` ;;
--with-openssl)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT \
--ssl-ca=$BASEDIR/SSL/cacert.pem \
@@ -154,27 +217,40 @@ while test $# -gt 0; do
--ssl-ca=$BASEDIR/SSL/cacert.pem \
--ssl-cert=$BASEDIR/SSL/server-cert.pem \
--ssl-key=$BASEDIR/SSL/server-key.pem" ;;
- --skip-innobase)
- EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-innobase"
- EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-innobase" ;;
+ --no-manager | --skip-manager) USE_MANAGER=0 ;;
+ --manager)
+ USE_MANAGER=1
+ USE_RUNNING_SERVER=
+ ;;
+ --start-and-exit)
+ START_AND_EXIT=1
+ ;;
+ --skip-innodb)
+ EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-innodb"
+ EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-innodb" ;;
--skip-bdb)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-bdb"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-bdb" ;;
--skip-rpl) NO_SLAVE=1 ;;
--skip-test=*) SKIP_TEST=`$ECHO "$1" | $SED -e "s;--skip-test=;;"`;;
--do-test=*) DO_TEST=`$ECHO "$1" | $SED -e "s;--do-test=;;"`;;
+ --wait-timeout=*)
+ START_WAIT_TIMEOUT=`$ECHO "$1" | $SED -e "s;--wait-timeout=;;"`
+ STOP_WAIT_TIMEOUT=$START_WAIT_TIMEOUT;;
--record)
RECORD=1;
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;;
--bench)
DO_BENCH=1
NO_SLAVE=1
- ;;
+ ;;
--big*) # Actually --big-test
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;;
+ --compress)
+ EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;;
--sleep=*)
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1"
- SLEEP_TIME=`$ECHO "$1" | $SED -e "s;--sleep=;;"`
+ SLEEP_TIME_AFTER_RESTART=`$ECHO "$1" | $SED -e "s;--sleep=;;"`
;;
--user-test=*)
USER_TEST=`$ECHO "$1" | $SED -e "s;--user-test=;;"`
@@ -193,12 +269,16 @@ while test $# -gt 0; do
;;
--gprof )
DO_GPROF=1
- ;;
+ ;;
--gdb )
+ START_WAIT_TIMEOUT=300
+ STOP_WAIT_TIMEOUT=300
if [ x$BINARY_DIST = x1 ] ; then
$ECHO "Note: you will get more meaningful output on a source distribution compiled with debugging option when running tests with --gdb option"
fi
DO_GDB=1
+ # This needs to be checked properly
+ # USE_MANAGER=1
USE_RUNNING_SERVER=""
;;
--client-gdb )
@@ -207,6 +287,11 @@ while test $# -gt 0; do
fi
DO_CLIENT_GDB=1
;;
+ --manual-gdb )
+ DO_GDB=1
+ MANUAL_GDB=1
+ USE_RUNNING_SERVER=""
+ ;;
--ddd )
if [ x$BINARY_DIST = x1 ] ; then
$ECHO "Note: you will get more meaningful output on a source distribution compiled with debugging option when running tests with --ddd option"
@@ -218,6 +303,9 @@ while test $# -gt 0; do
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $1"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $1"
;;
+ --strace-client )
+ STRACE_CLIENT=1
+ ;;
--debug)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT \
--debug=d:t:i:O,$MYSQL_TEST_DIR/var/log/master.trace"
@@ -237,17 +325,19 @@ done
#--
MYRUN_DIR=$MYSQL_TEST_DIR/var/run
+MANAGER_PID_FILE="$MYRUN_DIR/manager.pid"
+
MASTER_MYDDIR="$MYSQL_TEST_DIR/var/master-data"
-MASTER_MYSOCK="$MYSQL_TMP_DIR/mysql-master.sock"
-MASTER_MYPID="$MYRUN_DIR/mysqld.pid"
-MASTER_MYLOG="$MYSQL_TEST_DIR/var/log/mysqld.log"
-MASTER_MYERR="$MYSQL_TEST_DIR/var/log/mysqld.err"
+MASTER_MYSOCK="$MYSQL_TMP_DIR/master.sock"
+MASTER_MYPID="$MYRUN_DIR/master.pid"
+MASTER_MYLOG="$MYSQL_TEST_DIR/var/log/master.log"
+MASTER_MYERR="$MYSQL_TEST_DIR/var/log/master.err"
SLAVE_MYDDIR="$MYSQL_TEST_DIR/var/slave-data"
-SLAVE_MYSOCK="$MYSQL_TMP_DIR/mysql-slave.sock"
-SLAVE_MYPID="$MYRUN_DIR/mysqld-slave.pid"
-SLAVE_MYLOG="$MYSQL_TEST_DIR/var/log/mysqld-slave.log"
-SLAVE_MYERR="$MYSQL_TEST_DIR/var/log/mysqld-slave.err"
+SLAVE_MYSOCK="$MYSQL_TMP_DIR/slave.sock"
+SLAVE_MYPID="$MYRUN_DIR/slave.pid"
+SLAVE_MYLOG="$MYSQL_TEST_DIR/var/log/slave.log"
+SLAVE_MYERR="$MYSQL_TEST_DIR/var/log/slave.err"
SMALL_SERVER="-O key_buffer_size=1M -O sort_buffer=256K -O max_heap_table_size=1M"
@@ -258,7 +348,7 @@ if [ x$SOURCE_DIST = x1 ] ; then
MY_BASEDIR=$MYSQL_TEST_DIR
else
MY_BASEDIR=$BASEDIR
-fi
+fi
# Create the directories
@@ -269,7 +359,7 @@ fi
[ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp
[ -d $MYSQL_TEST_DIR/var/run ] || mkdir $MYSQL_TEST_DIR/var/run
-[ -z "$COLUMNS" ] && COLUMNS=80
+if test ${COLUMNS:-0} -lt 80 ; then COLUMNS=80 ; fi
E=`$EXPR $COLUMNS - 8`
DASH72=`$ECHO '------------------------------------------------------------------------'|$CUT -c 1-$E`
@@ -279,10 +369,19 @@ if [ x$SOURCE_DIST = x1 ] ; then
MYSQLD="$BASEDIR/sql/mysqld"
if [ -f "$BASEDIR/client/.libs/lt-mysqltest" ] ; then
MYSQL_TEST="$BASEDIR/client/.libs/lt-mysqltest"
+ elif [ -f "$BASEDIR/client/.libs/mysqltest" ] ; then
+ MYSQL_TEST="$BASEDIR/client/.libs/mysqltest"
else
MYSQL_TEST="$BASEDIR/client/mysqltest"
fi
+ if [ -n "$STRACE_CLIENT" ]; then
+ MYSQL_TEST="strace -o $MYSQL_TEST_DIR/var/log/mysqltest.strace $MYSQL_TEST"
+ fi
+
MYSQLADMIN="$BASEDIR/client/mysqladmin"
+ MYSQL_MANAGER_CLIENT="$BASEDIR/client/mysqlmanagerc"
+ MYSQL_MANAGER="$BASEDIR/tools/mysqlmanager"
+ MYSQL_MANAGER_PWGEN="$BASEDIR/client/mysqlmanager-pwgen"
MYSQL="$BASEDIR/client/mysql"
LANGUAGE="$BASEDIR/sql/share/english/"
CHARSETSDIR="$BASEDIR/sql/share/charsets"
@@ -291,9 +390,12 @@ else
MYSQLD="$BASEDIR/bin/mysqld"
MYSQL_TEST="$BASEDIR/bin/mysqltest"
MYSQLADMIN="$BASEDIR/bin/mysqladmin"
+ MYSQL_MANAGER="$BASEDIR/bin/mysqlmanager"
+ MYSQL_MANAGER_CLIENT="$BASEDIR/bin/mysqlmanagerc"
+ MYSQL_MANAGER_PWGEN="$BASEDIR/bin/mysqlmanager-pwgen"
MYSQL="$BASEDIR/bin/mysql"
INSTALL_DB="./install_test_db -bin"
- if test -d "$BASEDIR/share/mysql/english"
+ if test -d "$BASEDIR/share/mysql/english"
then
LANGUAGE="$BASEDIR/share/mysql/english/"
CHARSETSDIR="$BASEDIR/share/mysql/charsets"
@@ -303,6 +405,16 @@ else
fi
fi
+if [ -z "$MASTER_MYSQLD" ]
+then
+MASTER_MYSQLD=$MYSQLD
+fi
+
+if [ -z "$SLAVE_MYSQLD" ]
+then
+SLAVE_MYSQLD=$MYSQLD
+fi
+
# If we should run all tests cases, we will use a local server for that
if [ -z "$1" ]
@@ -325,7 +437,9 @@ then
fi
-MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB --user=$DBUSER --password=$DBPASSWD --silent -v --tmpdir=$MYSQL_TMP_DIR"
+MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \
+ --user=$DBUSER --password=$DBPASSWD --silent -v \
+ --tmpdir=$MYSQL_TMP_DIR"
MYSQL_TEST_BIN=$MYSQL_TEST
MYSQL_TEST="$MYSQL_TEST $MYSQL_TEST_ARGS"
GDB_CLIENT_INIT=$MYSQL_TMP_DIR/gdbinit.client
@@ -336,8 +450,8 @@ GCOV_ERR=$MYSQL_TMP_DIR/mysqld-gcov.err
GPROF_DIR=$MYSQL_TMP_DIR/gprof
GPROF_MASTER=$GPROF_DIR/master.gprof
GPROF_SLAVE=$GPROF_DIR/slave.gprof
-TIMEFILE="$MYSQL_TMP_DIR/mysqltest-time"
-SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov
+TIMEFILE="$MYSQL_TEST_DIR/var/log/mysqltest-time"
+XTERM=`which xterm`
#++
# Function Definitions
@@ -360,12 +474,12 @@ show_failed_diff ()
reject_file=r/$1.reject
result_file=r/$1.result
eval_file=r/$1.eval
-
+
if [ -f $eval_file ]
then
result_file=$eval_file
fi
-
+
if [ -x "$DIFF" ] && [ -f $reject_file ]
then
echo "Below are the diffs between actual and expected results:"
@@ -375,7 +489,7 @@ show_failed_diff ()
echo "Please follow the instructions outlined at"
echo "http://www.mysql.com/doc/R/e/Reporting_mysqltest_bugs.html"
echo "to find the reason to this problem and how to report this."
- fi
+ fi
}
do_gdb_test ()
@@ -384,7 +498,7 @@ do_gdb_test ()
$ECHO "set args $mysql_test_args < $2" > $GDB_CLIENT_INIT
echo "Set breakpoints ( if needed) and type 'run' in gdb window"
#this xterm should not be backgrounded
- xterm -title "Client" -e gdb -x $GDB_CLIENT_INIT $MYSQL_TEST_BIN
+ $XTERM -title "Client" -e gdb -x $GDB_CLIENT_INIT $MYSQL_TEST_BIN
}
error () {
@@ -393,7 +507,7 @@ error () {
}
error_is () {
- $TR "\n" " " < $TIMEFILE | $SED -e 's/.* At line \(.*\)\: \(.*\)Command .*$/ \>\> Error at line \1: \2<\</'
+ $CAT < $TIMEFILE | $SED -e 's/.* At line \(.*\)\: \(.*\)/ \>\> Error at line \1: \2<\</' | $HEAD -1
}
prefix_to_8() {
@@ -420,15 +534,15 @@ report_stats () {
if [ $TOT_FAIL = 0 ]; then
$ECHO "All $TOT_TEST tests were successful."
else
- xten=`$EXPR $TOT_PASS \* 10000`
- raw=`$EXPR $xten / $TOT_TEST`
- raw=`$PRINTF %.4d $raw`
- whole=`$PRINTF %.2s $raw`
- xwhole=`$EXPR $whole \* 100`
- deci=`$EXPR $raw - $xwhole`
+ xten=`$EXPR $TOT_PASS \* 10000`
+ raw=`$EXPR $xten / $TOT_TEST`
+ raw=`$PRINTF %.4d $raw`
+ whole=`$PRINTF %.2s $raw`
+ xwhole=`$EXPR $whole \* 100`
+ deci=`$EXPR $raw - $xwhole`
$ECHO "Failed ${TOT_FAIL}/${TOT_TEST} tests, ${whole}.${deci}% successful."
$ECHO ""
- $ECHO "The log files in $MYSQL_TEST_DIR/var/log may give you some hint"
+ $ECHO "The log files in $MY_LOG_DIR may give you some hint"
$ECHO "of what when wrong."
$ECHO "If you want to report this error, please read first the documentation at"
$ECHO "http://www.mysql.com/doc/M/y/MySQL_test_suite.html"
@@ -437,8 +551,7 @@ report_stats () {
mysql_install_db () {
$ECHO "Removing Stale Files"
- $RM -rf $MASTER_MYDDIR $SLAVE_MYDDIR $SLAVE_MYLOG $MASTER_MYLOG \
- $SLAVE_MYERR $MASTER_MYERR
+ $RM -rf $MASTER_MYDDIR $SLAVE_MYDDIR $MY_LOG_DIR/*
$ECHO "Installing Master Databases"
$INSTALL_DB
if [ $? != 0 ]; then
@@ -451,25 +564,31 @@ mysql_install_db () {
error "Could not install slave test DBs"
exit 1
fi
- # Give mysqld some time to die.
- sleep $SLEEP_TIME
+
+ for slave_num in 1 2 ;
+ do
+ $RM -rf var/slave$slave_num-data/
+ mkdir -p var/slave$slave_num-data/mysql
+ mkdir -p var/slave$slave_num-data/test
+ cp var/slave-data/mysql/* var/slave$slave_num-data/mysql
+ done
return 0
}
gprof_prepare ()
{
- rm -rf $GPROF_DIR
- mkdir -p $GPROF_DIR
+ $RM -rf $GPROF_DIR
+ mkdir -p $GPROF_DIR
}
gprof_collect ()
{
if [ -f $MASTER_MYDDIR/gmon.out ]; then
- gprof $MYSQLD $MASTER_MYDDIR/gmon.out > $GPROF_MASTER
+ gprof $MASTER_MYSQLD $MASTER_MYDDIR/gmon.out > $GPROF_MASTER
echo "Master execution profile has been saved in $GPROF_MASTER"
fi
if [ -f $SLAVE_MYDDIR/gmon.out ]; then
- gprof $MYSQLD $SLAVE_MYDDIR/gmon.out > $GPROF_SLAVE
+ gprof $SLAVE_MYSQLD $SLAVE_MYDDIR/gmon.out > $GPROF_SLAVE
echo "Slave execution profile has been saved in $GPROF_SLAVE"
fi
}
@@ -494,173 +613,368 @@ gcov_collect () {
$ECHO "gcov info in $GCOV_MSG, errors in $GCOV_ERR"
}
+abort_if_failed()
+{
+ if [ ! $? = 0 ] ; then
+ echo $1
+ exit 1
+ fi
+}
-start_master()
+start_manager()
{
- [ x$MASTER_RUNNING = 1 ] && return
- #run master initialization shell script if one exists
- if [ -f "$master_init_script" ] ;
- then
- /bin/sh $master_init_script
+ if [ $USE_MANAGER = 0 ] ; then
+ echo "Manager disabled, skipping manager start."
+ $RM -f $MYSQL_MANAGER_LOG
+ return
+ fi
+ $ECHO "Starting MySQL Manager"
+ if [ -f "$MANAGER_PID_FILE" ] ; then
+ kill `cat $MANAGER_PID_FILE`
+ sleep 1
+ if [ -f "$MANAGER_PID_FILE" ] ; then
+ kill -9 `cat $MANAGER_PID_FILE`
+ sleep 1
fi
- cd $BASEDIR # for gcov
- # Remove old berkeley db log files that can confuse the server
- $RM -f $MASTER_MYDDIR/log.*
- #start master
- if [ -z "$DO_BENCH" ]
- then
- master_args="--no-defaults --log-bin=master-bin \
- --server-id=1 \
- --basedir=$MY_BASEDIR \
- --port=$MASTER_MYPORT \
- --exit-info=256 \
- --core \
- --datadir=$MASTER_MYDDIR \
- --pid-file=$MASTER_MYPID \
- --socket=$MASTER_MYSOCK \
- --log=$MASTER_MYLOG \
- --character-sets-dir=$CHARSETSDIR \
- --tmpdir=$MYSQL_TMP_DIR \
- --language=$LANGUAGE \
- --innodb_data_file_path=ibdata1:50M \
- $SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
- else
- master_args="--no-defaults --log-bin=master-bin --server-id=1 \
- --basedir=$MY_BASEDIR \
- --port=$MASTER_MYPORT \
- --datadir=$MASTER_MYDDIR \
- --pid-file=$MASTER_MYPID \
- --socket=$MASTER_MYSOCK \
- --default-character-set=$CHARACTER_SET \
- --core \
- --tmpdir=$MYSQL_TMP_DIR \
- --language=$LANGUAGE \
- --innodb_data_file_path=ibdata1:50M \
- $SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
- fi
- if [ x$DO_DDD = x1 ]
- then
- $ECHO "set args $master_args" > $GDB_MASTER_INIT
- ddd --debugger "gdb -x $GDB_MASTER_INIT" $MYSQLD &
- prompt_user "Hit enter to continue after you've started the master"
- elif [ x$DO_GDB = x1 ]
+ fi
+
+ $RM -f $MANAGER_PID_FILE
+ MYSQL_MANAGER_PW=`$MYSQL_MANAGER_PWGEN -u $MYSQL_MANAGER_USER \
+ -o $MYSQL_MANAGER_PW_FILE`
+ $MYSQL_MANAGER --log=$MYSQL_MANAGER_LOG --port=$MYSQL_MANAGER_PORT \
+ --password-file=$MYSQL_MANAGER_PW_FILE --pid-file=$MANAGER_PID_FILE
+ abort_if_failed "Could not start MySQL manager"
+ mysqltest_manager_args="--manager-host=localhost \
+ --manager-user=$MYSQL_MANAGER_USER \
+ --manager-password=$MYSQL_MANAGER_PW \
+ --manager-port=$MYSQL_MANAGER_PORT \
+ --manager-wait-timeout=$START_WAIT_TIMEOUT"
+ MYSQL_TEST="$MYSQL_TEST $mysqltest_manager_args"
+ MYSQL_TEST_ARGS="$MYSQL_TEST_ARGS $mysqltest_manager_args"
+ while [ ! -f $MANAGER_PID_FILE ] ; do
+ sleep 1
+ done
+ echo "Manager started"
+}
+
+stop_manager()
+{
+ if [ $USE_MANAGER = 0 ] ; then
+ return
+ fi
+ $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT -u$MYSQL_MANAGER_USER \
+ -p$MYSQL_MANAGER_PW -P $MYSQL_MANAGER_PORT <<EOF
+shutdown
+EOF
+ echo "Manager terminated"
+
+}
+
+manager_launch()
+{
+ ident=$1
+ shift
+ if [ $USE_MANAGER = 0 ] ; then
+ $@ >$CUR_MYERR 2>&1 &
+ sleep 2 #hack
+ return
+ fi
+ $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \
+ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF
+def_exec $ident $@
+set_exec_stdout $ident $CUR_MYERR
+set_exec_stderr $ident $CUR_MYERR
+set_exec_con $ident root localhost $CUR_MYSOCK
+start_exec $ident $START_WAIT_TIMEOUT
+EOF
+ abort_if_failed "Could not execute manager command"
+}
+
+manager_term()
+{
+ ident=$1
+ shift
+ if [ $USE_MANAGER = 0 ] ; then
+ $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock -O \
+ connect_timeout=5 -O shutdown_timeout=20 shutdown >> $MYSQL_MANAGER_LOG 2>&1
+ return
+ fi
+ $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \
+ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF
+stop_exec $ident $STOP_WAIT_TIMEOUT
+EOF
+ abort_if_failed "Could not execute manager command"
+}
+
+
+start_master()
+{
+ if [ x$MASTER_RUNNING = x1 ] || [ x$LOCAL_MASTER = x1 ] ; then
+ return
+ fi
+ # Remove old berkeley db log files that can confuse the server
+ $RM -f $MASTER_MYDDIR/log.*
+ # Remove stale binary logs
+ $RM -f $MYSQL_TEST_DIR/var/log/master-bin.*
+
+ #run master initialization shell script if one exists
+
+ if [ -f "$master_init_script" ] ;
+ then
+ /bin/sh $master_init_script
+ fi
+ cd $BASEDIR # for gcov
+ #start master
+ if [ -z "$DO_BENCH" ]
+ then
+ master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin \
+ --server-id=1 \
+ --basedir=$MY_BASEDIR \
+ --port=$MASTER_MYPORT \
+ --local-infile \
+ --exit-info=256 \
+ --core \
+ --datadir=$MASTER_MYDDIR \
+ --pid-file=$MASTER_MYPID \
+ --socket=$MASTER_MYSOCK \
+ --log=$MASTER_MYLOG \
+ --character-sets-dir=$CHARSETSDIR \
+ --default-character-set=$CHARACTER_SET \
+ --tmpdir=$MYSQL_TMP_DIR \
+ --language=$LANGUAGE \
+ --innodb_data_file_path=ibdata1:50M \
+ $MASTER_40_ARGS \
+ $SMALL_SERVER \
+ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
+ else
+ master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin \
+ --server-id=1 --rpl-recovery-rank=1 \
+ --basedir=$MY_BASEDIR --init-rpl-role=master \
+ --port=$MASTER_MYPORT \
+ --local-infile \
+ --datadir=$MASTER_MYDDIR \
+ --pid-file=$MASTER_MYPID \
+ --socket=$MASTER_MYSOCK \
+ --character-sets-dir=$CHARSETSDIR \
+ --default-character-set=$CHARACTER_SET \
+ --core \
+ --tmpdir=$MYSQL_TMP_DIR \
+ --language=$LANGUAGE \
+ --innodb_data_file_path=ibdata1:50M \
+ $MASTER_40_ARGS \
+ $SMALL_SERVER \
+ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
+ fi
+
+ CUR_MYERR=$MASTER_MYERR
+ CUR_MYSOCK=$MASTER_MYSOCK
+
+ if [ x$DO_DDD = x1 ]
+ then
+ $ECHO "set args $master_args" > $GDB_MASTER_INIT
+ manager_launch master ddd -display $DISPLAY --debugger \
+ "gdb -x $GDB_MASTER_INIT" $MASTER_MYSQLD
+ elif [ x$DO_GDB = x1 ]
+ then
+ if [ x$MANUAL_GDB = x1 ]
then
$ECHO "set args $master_args" > $GDB_MASTER_INIT
- xterm -title "Master" -e gdb -x $GDB_MASTER_INIT $MYSQLD &
- prompt_user "Hit enter to continue after you've started the master"
- else
- $MYSQLD $master_args >> $MASTER_MYERR 2>&1 &
- fi
- wait_for_server_start $MASTER_MYPORT
+ $ECHO "To start gdb for the master , type in another window:"
+ $ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD"
+ wait_for_master=1500
+ else
+ ( $ECHO set args $master_args;
+ if [ $USE_MANAGER = 0 ] ; then
+ cat <<EOF
+b mysql_parse
+commands 1
+disa 1
+end
+r
+EOF
+ fi ) > $GDB_MASTER_INIT
+ manager_launch master $XTERM -display $DISPLAY \
+ -title "Master" -e gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD
+ fi
+ else
+ manager_launch master $MASTER_MYSQLD $master_args
+ fi
+ sleep_until_file_created $MASTER_MYPID $wait_for_master
+ wait_for_master=$SLEEP_TIME_FOR_SECOND_MASTER
MASTER_RUNNING=1
}
start_slave()
{
- [ x$SKIP_SLAVE = x1 ] && return
- [ x$SLAVE_RUNNING = 1 ] && return
-
- #run slave initialization shell script if one exists
- if [ -f "$slave_init_script" ] ;
- then
- /bin/sh $slave_init_script
- fi
-
- if [ -z "$SLAVE_MASTER_INFO" ] ; then
- master_info="--master-user=root \
- --master-connect-retry=1 \
- --master-host=127.0.0.1 \
- --master-password= \
- --master-port=$MASTER_MYPORT \
- --server-id=2"
- else
- master_info=$SLAVE_MASTER_INFO
- fi
-
- $RM -f $SLAVE_MYDDIR/log.*
- slave_args="--no-defaults $master_info \
- --exit-info=256 \
- --log-bin=slave-bin --log-slave-updates \
- --log=$SLAVE_MYLOG \
- --basedir=$MY_BASEDIR \
- --datadir=$SLAVE_MYDDIR \
- --pid-file=$SLAVE_MYPID \
- --port=$SLAVE_MYPORT \
- --socket=$SLAVE_MYSOCK \
- --character-sets-dir=$CHARSETSDIR \
- --core \
- --tmpdir=$MYSQL_TMP_DIR \
- --language=$LANGUAGE \
- --skip-innodb --skip-slave-start \
- --master-retry-count=5 \
- $SMALL_SERVER \
- $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
- if [ x$DO_DDD = x1 ]
- then
- $ECHO "set args $master_args" > $GDB_SLAVE_INIT
- ddd --debugger "gdb -x $GDB_SLAVE_INIT" $SLAVE_MYSQLD &
- prompt_user "Hit enter to continue after you've started the slave"
- elif [ x$DO_GDB = x1 ]
+ [ x$SKIP_SLAVE = x1 ] && return
+ eval "this_slave_running=\$SLAVE$1_RUNNING"
+ [ x$this_slave_running = 1 ] && return
+ #when testing fail-safe replication, we will have more than one slave
+ #in this case, we start secondary slaves with an argument
+ slave_ident="slave$1"
+ if [ -n "$1" ] ;
+ then
+ slave_server_id=`$EXPR 2 + $1`
+ slave_rpl_rank=$slave_server_id
+ slave_port=`expr $SLAVE_MYPORT + $1`
+ slave_log="$SLAVE_MYLOG.$1"
+ slave_err="$SLAVE_MYERR.$1"
+ slave_datadir="var/$slave_ident-data/"
+ slave_pid="$MYRUN_DIR/mysqld-$slave_ident.pid"
+ slave_sock="$SLAVE_MYSOCK-$1"
+ else
+ slave_server_id=2
+ slave_rpl_rank=2
+ slave_port=$SLAVE_MYPORT
+ slave_log=$SLAVE_MYLOG
+ slave_err=$SLAVE_MYERR
+ slave_datadir=$SLAVE_MYDDIR
+ slave_pid=$SLAVE_MYPID
+ slave_sock="$SLAVE_MYSOCK"
+ fi
+ # Remove stale binary logs
+ $RM -f $MYSQL_TEST_DIR/var/log/$slave_ident-bin.*
+
+ #run slave initialization shell script if one exists
+ if [ -f "$slave_init_script" ] ;
+ then
+ /bin/sh $slave_init_script
+ fi
+
+ if [ -z "$SLAVE_MASTER_INFO" ] ; then
+ master_info="--master-user=root \
+ --master-connect-retry=1 \
+ --master-host=127.0.0.1 \
+ --master-password= \
+ --master-port=$MASTER_MYPORT \
+ --server-id=$slave_server_id --rpl-recovery-rank=$slave_rpl_rank"
+ else
+ master_info=$SLAVE_MASTER_INFO
+ fi
+
+ $RM -f $slave_datadir/log.*
+ slave_args="--no-defaults $master_info \
+ --exit-info=256 \
+ --log-bin=$MYSQL_TEST_DIR/var/log/$slave_ident-bin \
+ --relay-log=$MYSQL_TEST_DIR/var/log/$slave_ident-relay-bin \
+ --log-slave-updates \
+ --log=$slave_log \
+ --basedir=$MY_BASEDIR \
+ --datadir=$slave_datadir \
+ --pid-file=$slave_pid \
+ --port=$slave_port \
+ --socket=$slave_sock \
+ --character-sets-dir=$CHARSETSDIR \
+ --default-character-set=$CHARACTER_SET \
+ --core --init-rpl-role=slave \
+ --tmpdir=$MYSQL_TMP_DIR \
+ --language=$LANGUAGE \
+ --skip-innodb --skip-slave-start \
+ --slave-load-tmpdir=$SLAVE_LOAD_TMPDIR \
+ --report-host=127.0.0.1 --report-user=root \
+ --report-port=$slave_port \
+ --master-retry-count=5 \
+ -O slave_net_timeout=10 \
+ $SMALL_SERVER \
+ $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
+ CUR_MYERR=$slave_err
+ CUR_MYSOCK=$slave_sock
+
+ if [ x$DO_DDD = x1 ]
+ then
+ $ECHO "set args $master_args" > $GDB_SLAVE_INIT
+ manager_launch $slave_ident ddd -display $DISPLAY --debugger \
+ "gdb -x $GDB_SLAVE_INIT" $SLAVE_MYSQLD
+ elif [ x$DO_GDB = x1 ]
+ then
+ if [ x$MANUAL_GDB = x1 ]
then
$ECHO "set args $slave_args" > $GDB_SLAVE_INIT
- xterm -title "Slave" -e gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD &
- prompt_user "Hit enter to continue after you've started the slave"
+ echo "To start gdb for the slave, type in another window:"
+ echo "cd $CWD ; gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD"
+ wait_for_slave=1500
else
- $SLAVE_MYSQLD $slave_args >> $SLAVE_MYERR 2>&1 &
+ ( $ECHO set args $slave_args;
+ if [ $USE_MANAGER = 0 ] ; then
+ cat <<EOF
+b mysql_parse
+commands 1
+disa 1
+end
+r
+EOF
+ fi ) > $GDB_SLAVE_INIT
+ manager_launch $slave_ident $XTERM -display $DISPLAY -title "Slave" -e \
+ gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD
fi
- wait_for_server_start $SLAVE_MYPORT
- SLAVE_RUNNING=1
+ else
+ manager_launch $slave_ident $SLAVE_MYSQLD $slave_args
+ fi
+ eval "SLAVE$1_RUNNING=1"
+ sleep_until_file_created $slave_pid $wait_for_slave
+ wait_for_slave=$SLEEP_TIME_FOR_SECOND_SLAVE
}
-mysql_start () {
- $ECHO "Starting MySQL daemon"
- start_master
- start_slave
- cd $MYSQL_TEST_DIR
- return 1
+mysql_start ()
+{
+ $ECHO "Starting MySQL daemon"
+ start_master
+ start_slave
+ cd $MYSQL_TEST_DIR
+ return 1
}
stop_slave ()
{
- if [ x$SLAVE_RUNNING = x1 ]
+ eval "this_slave_running=\$SLAVE$1_RUNNING"
+ slave_ident="slave$1"
+ if [ -n "$1" ] ;
+ then
+ slave_pid="$MYRUN_DIR/mysqld-$slave_ident.pid"
+ else
+ slave_pid=$SLAVE_MYPID
+ fi
+ if [ x$this_slave_running = x1 ]
then
- $MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O shutdown_timeout=20 shutdown
- if [ $? != 0 ] && [ -f $SLAVE_MYPID ]
+ manager_term $slave_ident
+ if [ $? != 0 ] && [ -f $slave_pid ]
then # try harder!
- $ECHO "slave not cooperating with mysqladmin, will try manual kill"
- kill `$CAT $SLAVE_MYPID`
- sleep $SLEEP_TIME
- if [ -f $SLAVE_MYPID ] ; then
- $ECHO "slave refused to die. Sending SIGKILL"
- kill -9 `$CAT $SLAVE_MYPID`
- $RM -f $SLAVE_MYPID
- else
- $ECHO "slave responded to SIGTERM "
- fi
+ $ECHO "slave not cooperating with mysqladmin, will try manual kill"
+ kill `$CAT $slave_pid`
+ sleep_until_file_deleted $slave_pid
+ if [ -f $slave_pid ] ; then
+ $ECHO "slave refused to die. Sending SIGKILL"
+ kill -9 `$CAT $slave_pid`
+ $RM -f $slave_pid
+ else
+ $ECHO "slave responded to SIGTERM "
+ fi
+ else
+ sleep $SLEEP_TIME_AFTER_RESTART
fi
- SLAVE_RUNNING=0
- fi
+ eval "SLAVE$1_RUNNING=0"
+ fi
}
stop_master ()
{
if [ x$MASTER_RUNNING = x1 ]
then
- $MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK -u root -O shutdown_timeout=20 shutdown
+ manager_term master
if [ $? != 0 ] && [ -f $MASTER_MYPID ]
then # try harder!
- $ECHO "master not cooperating with mysqladmin, will try manual kill"
- kill `$CAT $MASTER_MYPID`
- sleep $SLEEP_TIME
- if [ -f $MASTER_MYPID ] ; then
- $ECHO "master refused to die. Sending SIGKILL"
- kill -9 `$CAT $MASTER_MYPID`
- $RM -f $MASTER_MYPID
- else
- $ECHO "master responded to SIGTERM "
- fi
+ $ECHO "master not cooperating with mysqladmin, will try manual kill"
+ kill `$CAT $MASTER_MYPID`
+ sleep_until_file_deleted $MASTER_MYPID
+ if [ -f $MASTER_MYPID ] ; then
+ $ECHO "master refused to die. Sending SIGKILL"
+ kill -9 `$CAT $MASTER_MYPID`
+ $RM -f $MASTER_MYPID
+ else
+ $ECHO "master responded to SIGTERM "
+ fi
+ else
+ sleep $SLEEP_TIME_AFTER_RESTART
fi
MASTER_RUNNING=0
fi
@@ -674,22 +988,23 @@ mysql_stop ()
stop_master
$ECHO "Master shutdown finished"
stop_slave
+ stop_slave 1
+ stop_slave 2
$ECHO "Slave shutdown finished"
-
+
return 1
}
-mysql_restart () {
-
- mysql_stop
- mysql_start
-
- return 1
+mysql_restart ()
+{
+ mysql_stop
+ mysql_start
+ return 1
}
mysql_loadstd () {
-
- # cp $STD_DATA/*.frm $STD_DATA/*.MRG $MASTER_MYDDIR/test
+
+ # cp $STD_DATA/*.frm $STD_DATA/*.MRG $MASTER_MYDDIR/test
return 1
}
@@ -703,7 +1018,11 @@ run_testcase ()
slave_init_script=$TESTDIR/$tname-slave.sh
slave_master_info_file=$TESTDIR/$tname-slave-master-info.opt
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0`
- if [ -n "$SKIP_TEST" ] ; then
+ if [ $USE_MANAGER = 1 ] ; then
+ many_slaves=`$EXPR \( $tname : rpl_failsafe \) != 0`
+ fi
+
+ if [ -n "$SKIP_TEST" ] ; then
SKIP_THIS_TEST=`$EXPR \( $tname : "$SKIP_TEST" \) != 0`
if [ x$SKIP_THIS_TEST = x1 ] ;
then
@@ -711,7 +1030,7 @@ run_testcase ()
fi
fi
- if [ -n "$DO_TEST" ] ; then
+ if [ -n "$DO_TEST" ] ; then
DO_THIS_TEST=`$EXPR \( $tname : "$DO_TEST" \) != 0`
if [ x$DO_THIS_TEST = x0 ] ;
then
@@ -737,7 +1056,7 @@ run_testcase ()
then
if [ -f $master_opt_file ] ;
then
- EXTRA_MASTER_OPT=`$CAT $master_opt_file`
+ EXTRA_MASTER_OPT=`$CAT $master_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
stop_master
start_master
else
@@ -746,20 +1065,20 @@ run_testcase ()
EXTRA_MASTER_OPT=""
stop_master
start_master
- fi
+ fi
fi
do_slave_restart=0
-
+
if [ -f $slave_opt_file ] ;
then
- EXTRA_SLAVE_OPT=`$CAT $slave_opt_file`
+ EXTRA_SLAVE_OPT=`$CAT $slave_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
do_slave_restart=1
else
if [ ! -z "$EXTRA_SLAVE_OPT" ] || [ x$SLAVE_RUNNING != x1 ] ;
then
EXTRA_SLAVE_OPT=""
- do_slave_restart=1
- fi
+ do_slave_restart=1
+ fi
fi
if [ -f $slave_master_info_file ] ; then
@@ -769,26 +1088,30 @@ run_testcase ()
if [ ! -z "$SLAVE_MASTER_INFO" ] || [ x$SLAVE_RUNNING != x1 ] ;
then
SLAVE_MASTER_INFO=""
- do_slave_restart=1
- fi
+ do_slave_restart=1
+ fi
fi
if [ x$do_slave_restart = x1 ] ; then
stop_slave
start_slave
fi
+ if [ x$many_slaves = x1 ]; then
+ start_slave 1
+ start_slave 2
+ fi
fi
cd $MYSQL_TEST_DIR
-
+
if [ -f $tf ] ; then
$RM -f r/$tname.*reject
mysql_test_args="-R r/$tname.result $EXTRA_MYSQL_TEST_OPT"
- if [ -z "$DO_CLIENT_GDB" ] ; then
- mytime=`$TIME -p $MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE`
+ if [ -z "$DO_CLIENT_GDB" ] ; then
+ mytime=`$TIME -p $MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE`
else
- do_gdb_test "$mysql_test_args" "$tf"
+ do_gdb_test "$mysql_test_args" "$tf"
fi
-
+
res=$?
if [ $res = 0 ]; then
@@ -810,6 +1133,11 @@ run_testcase ()
pname=`$ECHO "$tname "|$CUT -c 1-24`
RES="$pname $timestr"
+ if [ x$many_slaves = x1 ] ; then
+ stop_slave 1
+ stop_slave 2
+ fi
+
if [ $res = 0 ]; then
total_inc
pass_inc
@@ -833,10 +1161,11 @@ run_testcase ()
if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && [ -z "$DO_DDD" ]
then
mysql_stop
+ stop_manager
fi
exit 1
fi
-
+
if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && [ -z "$DO_DDD" ]
then
mysql_restart
@@ -848,26 +1177,49 @@ run_testcase ()
fi
}
-
######################################################################
# Main script starts here
######################################################################
[ "$DO_GCOV" -a ! -x "$GCOV" ] && error "No gcov found"
-[ "$DO_GCOV" ] && gcov_prepare
-[ "$DO_GPROF" ] && gprof_prepare
+[ "$DO_GCOV" ] && gcov_prepare
+[ "$DO_GPROF" ] && gprof_prepare
-# Ensure that no old mysqld test servers are running
if [ -z "$USE_RUNNING_SERVER" ]
then
- $MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK -u root -O connect_timeout=5 shutdown > /dev/null 2>&1
- $MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O connect_timeout=5 shutdown > /dev/null 2>&1
+ # Ensure that no old mysqld test servers are running
+ $MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --host=$hostname --port=$MASTER_MYPORT -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --host=$hostname --port=$SLAVE_MYPORT -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --host=$hostname --port=`expr $SLAVE_MYPORT + 1` -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ sleep_until_file_deleted $MASTER_MYPID
+ sleep_until_file_deleted $SLAVE_MYPID
+
+ # Kill any running managers
+ if [ -f "$MANAGER_PID_FILE" ]
+ then
+ kill `cat $MANAGER_PID_FILE`
+ sleep 1
+ if [ -f "$MANAGER_PID_FILE" ]
+ then
+ kill -9 `cat $MANAGER_PID_FILE`
+ sleep 1
+ fi
+ fi
+
+ # Remove files that can cause problems
+ $RM -f $MYSQL_TEST_DIR/var/run/* $MYSQL_TEST_DIR/var/tmp/*
+
+ wait_for_master=$SLEEP_TIME_FOR_FIRST_MASTER
+ wait_for_slave=$SLEEP_TIME_FOR_FIRST_SLAVE
$ECHO "Installing Test Databases"
mysql_install_db
+ start_manager
-#do not automagically start deamons if we are in gdb or running only one test
-#case
+# Do not automagically start deamons if we are in gdb or running only one test
+# case
if [ -z "$DO_GDB" ] && [ -z "$DO_DDD" ]
then
mysql_start
@@ -876,31 +1228,35 @@ then
mysql_loadstd
fi
+if [ "x$START_AND_EXIT" = "x1" ] ; then
+ echo "Servers started, exiting"
+ exit
+fi
$ECHO "Starting Tests"
if [ "$DO_BENCH" = 1 ]
then
- BENCHDIR=$BASEDIR/sql-bench/
- savedir=`pwd`
- cd $BENCHDIR
- if [ -z "$1" ]
- then
- ./run-all-tests --socket=$MASTER_MYSOCK --user=root
- else
- if [ -x "./$1" ]
+ BENCHDIR=$BASEDIR/sql-bench/
+ savedir=`pwd`
+ cd $BENCHDIR
+ if [ -z "$1" ]
then
- ./$1 --socket=$MASTER_MYSOCK --user=root
+ ./run-all-tests --socket=$MASTER_MYSOCK --user=root
else
- echo "benchmark $1 not found"
+ if [ -x "./$1" ]
+ then
+ ./$1 --socket=$MASTER_MYSOCK --user=root
+ else
+ echo "benchmark $1 not found"
+ fi
fi
- fi
- cd $savedir
- mysql_stop
- exit
+ cd $savedir
+ mysql_stop
+ stop_manager
+ exit
fi
-
$ECHO
$ECHO " TEST USER SYSTEM ELAPSED RESULT"
$ECHO $DASH72
@@ -910,25 +1266,23 @@ then
if [ x$RECORD = x1 ]; then
$ECHO "Will not run in record mode without a specific test case."
else
- if [ -z "$USER_TEST" ]
- then
- for tf in $TESTDIR/*.$TESTSUFFIX
- do
- run_testcase $tf
- done
- $RM -f $TIMEFILE # Remove for full test
- else
- $USER_TEST
- fi
- fi
-else
-tname=`$BASENAME $1 .test`
- tf=$TESTDIR/$tname.$TESTSUFFIX
- if [ -f $tf ] ; then
- run_testcase $tf
- else
- $ECHO "Test case $tf does not exist."
+ for tf in $TESTDIR/*.$TESTSUFFIX
+ do
+ run_testcase $tf
+ done
+ $RM -f $TIMEFILE # Remove for full test
fi
+else
+ while [ ! -z "$1" ]; do
+ tname=`$BASENAME $1 .test`
+ tf=$TESTDIR/$tname.$TESTSUFFIX
+ if [ -f $tf ] ; then
+ run_testcase $tf
+ else
+ $ECHO "Test case $tf does not exist."
+ fi
+ shift
+ done
fi
$ECHO $DASH72
@@ -939,6 +1293,7 @@ then
mysql_stop
fi
+stop_manager
report_stats
$ECHO
diff --git a/mysql-test/r/alias.result b/mysql-test/r/alias.result
index 61a65f68007..3954c2d0170 100644
--- a/mysql-test/r/alias.result
+++ b/mysql-test/r/alias.result
@@ -1,2 +1,61 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+cont_nr int(11) NOT NULL auto_increment,
+ver_nr int(11) NOT NULL default '0',
+aufnr int(11) NOT NULL default '0',
+username varchar(50) NOT NULL default '',
+hdl_nr int(11) NOT NULL default '0',
+eintrag date NOT NULL default '0000-00-00',
+st_klasse varchar(40) NOT NULL default '',
+st_wert varchar(40) NOT NULL default '',
+st_zusatz varchar(40) NOT NULL default '',
+st_bemerkung varchar(255) NOT NULL default '',
+kunden_art varchar(40) NOT NULL default '',
+mcbs_knr int(11) default NULL,
+mcbs_aufnr int(11) NOT NULL default '0',
+schufa_status char(1) default '?',
+bemerkung text,
+wirknetz text,
+wf_igz int(11) NOT NULL default '0',
+tarifcode varchar(80) default NULL,
+recycle char(1) default NULL,
+sim varchar(30) default NULL,
+mcbs_tpl varchar(30) default NULL,
+emp_nr int(11) NOT NULL default '0',
+laufzeit int(11) default NULL,
+hdl_name varchar(30) default NULL,
+prov_hdl_nr int(11) NOT NULL default '0',
+auto_wirknetz varchar(50) default NULL,
+auto_billing varchar(50) default NULL,
+touch timestamp(14) NOT NULL,
+kategorie varchar(50) default NULL,
+kundentyp varchar(20) NOT NULL default '',
+sammel_rech_msisdn varchar(30) NOT NULL default '',
+p_nr varchar(9) NOT NULL default '',
+suffix char(3) NOT NULL default '',
+PRIMARY KEY (cont_nr),
+KEY idx_aufnr(aufnr),
+KEY idx_hdl_nr(hdl_nr),
+KEY idx_st_klasse(st_klasse),
+KEY ver_nr(ver_nr),
+KEY eintrag_idx(eintrag),
+KEY emp_nr_idx(emp_nr),
+KEY wf_igz(wf_igz),
+KEY touch(touch),
+KEY hdl_tag(eintrag,hdl_nr),
+KEY prov_hdl_nr(prov_hdl_nr),
+KEY mcbs_aufnr(mcbs_aufnr),
+KEY kundentyp(kundentyp),
+KEY p_nr(p_nr,suffix)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (3359356,405,3359356,'Mustermann Musterfrau',52500,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1485525,2122316,'+','','N',1909160,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',3,24,'MobilCom Shop Koeln',52500,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359357,468,3359357,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1503580,2139699,'+','','P',1909171,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359358,407,3359358,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1501358,2137473,'N','','N',1909159,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359359,468,3359359,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1507831,2143894,'+','','P',1909162,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359360,0,0,'Mustermann Musterfrau',29674907,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1900169997,2414578,'+',NULL,'N',1909148,'',NULL,NULL,'RV99066_2',20,NULL,'POS',29674907,NULL,NULL,20010202105916,'Mobilfunk','','','97317481','007');
+INSERT INTO t1 VALUES (3359361,406,3359361,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag storniert','','(7001-84):Storno, Kd. möchte nicht mehr','privat',NULL,0,'+','','P',1909150,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1509984,2145874,'+','','P',1909154,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie;
Kundentyp kategorie
Privat (Private Nutzung) Mobilfunk
+drop table t1;
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index dbdbb7f57a9..1d6d69465da 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -1,3 +1,26 @@
+drop table if exists t1;
+create table t1 (
+col1 int not null auto_increment primary key,
+col2 varchar(30) not null,
+col3 varchar (20) not null,
+col4 varchar(4) not null,
+col5 enum('PENDING', 'ACTIVE', 'DISABLED') not null,
+col6 int not null, to_be_deleted int);
+insert into t1 values (2,4,3,5,"PENDING",1,7);
+alter table t1
+add column col4_5 varchar(20) not null after col4,
+add column col7 varchar(30) not null after col5,
+add column col8 datetime not null, drop column to_be_deleted,
+change column col2 fourth varchar(30) not null after col3,
+modify column col6 int not null first;
+select * from t1;
+col6 col1 col3 fourth col4 col4_5 col5 col7 col8
+1 2 3 4 5 PENDING 0000-00-00 00:00:00
+drop table t1;
+create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
+insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
+alter table t1 add column new_col int, order by payoutid,bandid;
+select * from t1;
bandID payoutID new_col
6 1 NULL
3 4 NULL
@@ -7,6 +30,8 @@ bandID payoutID new_col
5 10 NULL
7 12 NULL
8 12 NULL
+alter table t1 order by bandid,payoutid;
+select * from t1;
bandID payoutID new_col
1 6 NULL
2 6 NULL
@@ -16,19 +41,84 @@ bandID payoutID new_col
6 1 NULL
7 12 NULL
8 12 NULL
+drop table t1;
+CREATE TABLE t1 (
+GROUP_ID int(10) unsigned DEFAULT '0' NOT NULL,
+LANG_ID smallint(5) unsigned DEFAULT '0' NOT NULL,
+NAME varchar(80) DEFAULT '' NOT NULL,
+PRIMARY KEY (GROUP_ID,LANG_ID),
+KEY NAME (NAME));
+ALTER TABLE t1 CHANGE NAME NAME CHAR(80) not null;
+SHOW FULL COLUMNS FROM t1;
Field Type Null Key Default Extra Privileges
GROUP_ID int(10) unsigned PRI 0 select,insert,update,references
LANG_ID smallint(5) unsigned PRI 0 select,insert,update,references
NAME char(80) MUL select,insert,update,references
+DROP TABLE t1;
+create table t1 (n int);
+insert into t1 values(9),(3),(12),(10);
+alter table t1 order by n;
+select * from t1;
n
3
9
10
12
+drop table t1;
+CREATE TABLE t1 (
+id int(11) unsigned NOT NULL default '0',
+category_id tinyint(4) unsigned NOT NULL default '0',
+type_id tinyint(4) unsigned NOT NULL default '0',
+body text NOT NULL,
+user_id int(11) unsigned NOT NULL default '0',
+status enum('new','old') NOT NULL default 'new',
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+ALTER TABLE t1 ORDER BY t1.id, t1.status, t1.type_id, t1.user_id, t1.body;
+DROP TABLE t1;
+CREATE TABLE t1 (AnamneseId int(10) unsigned NOT NULL auto_increment,B BLOB,PRIMARY KEY (AnamneseId)) type=myisam;
+insert into t1 values (null,"hello");
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 ADD Column new_col int not null;
+UNLOCK TABLES;
+OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+DROP TABLE t1;
+create table t1 (n1 int not null, n2 int, n3 int, n4 float,
+unique(n1),
+key (n1, n2, n3, n4),
+key (n2, n3, n4, n1),
+key (n3, n4, n1, n2),
+key (n4, n1, n2, n3) );
+alter table t1 disable keys;
+insert into t1 values(10,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(9,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(8,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(7,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(6,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(5,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(4,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(3,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(2,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(1,RAND()*1000,RAND()*1000,RAND());
+alter table t1 enable keys;
+drop table t1;
+create table t1 (i int unsigned not null auto_increment primary key);
+insert into t1 values (null),(null),(null),(null);
+alter table t1 drop i,add i int unsigned not null auto_increment, drop primary key, add primary key (i);
+select * from t1;
i
1
2
3
4
+drop table t1;
+create table t1 (i int unsigned not null auto_increment primary key);
+alter table t1 rename t2;
+alter table t2 rename t1, add c char(10) comment "no comment";
+show columns from t1;
+Field Type Null Key Default Extra
+i int(10) unsigned PRI NULL auto_increment
+c char(10) YES NULL
+drop table t1;
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index f6b8cc2fcbf..c183530df48 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -1,6 +1,13 @@
+drop table if exists t1,t2;
+create table t1 (i int, j int);
+insert into t1 values (1,2), (3,4), (5,6), (7,8);
+select * from t1 procedure analyse();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL
t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL
+create table t2 select * from t1 procedure analyse();
+select * from t2;
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL
t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL
+drop table t1,t2;
diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result
index bf6265e5b64..66efd2ba567 100644
--- a/mysql-test/r/auto_increment.result
+++ b/mysql-test/r/auto_increment.result
@@ -1,32 +1,52 @@
+drop table if exists t1;
+create table t1 (a int not null auto_increment,b int, primary key (a)) type=myisam auto_increment=3;
+insert into t1 values (1,1),(NULL,3),(NULL,4);
+delete from t1 where a=4;
+insert into t1 values (NULL,5),(NULL,6);
+select * from t1;
a b
1 1
3 3
5 5
6 6
+delete from t1 where a=6;
+replace t1 values (3,1);
+ALTER TABLE t1 add c int;
+replace t1 values (3,3,3);
+insert into t1 values (NULL,7,7);
+update t1 set a=8,b=b+1,c=c+1 where a=7;
+insert into t1 values (NULL,9,9);
+select * from t1;
a b c
1 1 NULL
3 3 3
5 5 NULL
8 8 8
9 9 9
-a b
-1 1
-5 5
-3 3
-4 4
-6 6
-a b c
-1 1 NULL
-5 5 NULL
-3 3 NULL
-4 4 NULL
-6 6 6
+drop table t1;
+create table t1 (
+skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY,
+sval char(20)
+);
+insert into t1 values (NULL, "hello");
+insert into t1 values (NULL, "hey");
+select * from t1;
skey sval
1 hello
2 hey
+select _rowid,t1._rowid,skey,sval from t1;
_rowid _rowid skey sval
1 1 1 hello
2 2 2 hey
+drop table t1;
+create table t1 (a char(10) not null, b int not null auto_increment, primary key(a,b));
+insert into t1 values ("a",1),("b",2),("a",2),("c",1);
+insert into t1 values ("a",NULL),("b",NULL),("c",NULL),("e",NULL);
+insert into t1 (a) values ("a"),("b"),("c"),("d");
+insert into t1 (a) values ('k'),('d');
+insert into t1 (a) values ("a");
+insert into t1 values ("d",last_insert_id());
+select * from t1;
a b
a 1
a 2
@@ -44,9 +64,17 @@ d 2
d 5
e 1
k 1
+drop table t1;
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ordid), index(ord,ordid));
+insert into t1 (ordid,ord) values (NULL,'sdj'),(NULL,'sdj');
+select * from t1;
ordid ord
1 sdj
2 sdj
+drop table t1;
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid));
+insert into t1 values (NULL,'sdj'),(NULL,'sdj'),(NULL,"abc"),(NULL,'abc'),(NULL,'zzz'),(NULL,'sdj'),(NULL,'abc');
+select * from t1;
ordid ord
1 abc
2 abc
@@ -55,8 +83,15 @@ ordid ord
2 sdj
3 sdj
1 zzz
+drop table t1;
+create table t1 (a int not null primary key auto_increment);
+insert into t1 values (0);
+update t1 set a=0;
+select * from t1;
a
0
+check table t1;
Table Op Msg_type Msg_text
test.t1 check warning Found row where the auto_increment column has the value 0
test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/backup.result b/mysql-test/r/backup.result
index 2bbe15954dc..43d57d2d4f7 100644
--- a/mysql-test/r/backup.result
+++ b/mysql-test/r/backup.result
@@ -1,43 +1,73 @@
+set SQL_LOG_BIN=0;
+drop table if exists t1;
+create table t1(n int);
+backup table t1 to '../bogus';
Table Op Msg_type Msg_text
test.t1 backup error Failed copying .frm file: errno = X
test.t1 backup status Operation failed
+backup table t1 to '../tmp';
Table Op Msg_type Msg_text
test.t1 backup status OK
+drop table t1;
+restore table t1 from '../tmp';
Table Op Msg_type Msg_text
test.t1 restore status OK
+select count(*) from t1;
count(*)
0
+insert into t1 values (23),(45),(67);
+backup table t1 to '../tmp';
Table Op Msg_type Msg_text
test.t1 backup status OK
+drop table t1;
+restore table t1 from '../bogus';
Table Op Msg_type Msg_text
t1 restore error Failed copying .frm file
+restore table t1 from '../tmp';
Table Op Msg_type Msg_text
test.t1 restore status OK
+select n from t1;
n
23
45
67
+create table t2(m int not null primary key);
+create table t3(k int not null primary key);
+insert into t2 values (123),(145),(167);
+insert into t3 values (223),(245),(267);
+backup table t1,t2,t3 to '../tmp';
Table Op Msg_type Msg_text
test.t1 backup status OK
test.t2 backup status OK
test.t3 backup status OK
+drop table t1,t2,t3;
+restore table t1,t2,t3 from '../tmp';
Table Op Msg_type Msg_text
test.t1 restore status OK
test.t2 restore status OK
test.t3 restore status OK
+select n from t1;
n
23
45
67
+select m from t2;
m
123
145
167
+select k from t3;
k
223
245
267
+drop table t1,t2,t3;
+restore table t1 from '../tmp';
Table Op Msg_type Msg_text
test.t1 restore status OK
+lock tables t1 write;
+backup table t1 to '../tmp';
+unlock tables;
Table Op Msg_type Msg_text
test.t1 backup status OK
+drop table t1;
diff --git a/mysql-test/r/bdb-crash.result b/mysql-test/r/bdb-crash.result
index 8fa8378640b..42c826d55da 100644
--- a/mysql-test/r/bdb-crash.result
+++ b/mysql-test/r/bdb-crash.result
@@ -1,3 +1,32 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+ChargeID int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
+ServiceID int(10) unsigned DEFAULT '0' NOT NULL,
+ChargeDate date DEFAULT '0000-00-00' NOT NULL,
+ChargeAmount decimal(20,2) DEFAULT '0.00' NOT NULL,
+FedTaxes decimal(20,2) DEFAULT '0.00' NOT NULL,
+ProvTaxes decimal(20,2) DEFAULT '0.00' NOT NULL,
+ChargeStatus enum('New','Auth','Unauth','Sale','Denied','Refund')
+DEFAULT 'New' NOT NULL,
+ChargeAuthorizationMessage text,
+ChargeComment text,
+ChargeTimeStamp varchar(20),
+PRIMARY KEY (ChargeID),
+KEY ServiceID (ServiceID),
+KEY ChargeDate (ChargeDate)
+) type=BDB;
+BEGIN;
+INSERT INTO t1
+VALUES(NULL,1,'2001-03-01',1,1,1,'New',NULL,NULL,'now');
+COMMIT;
+BEGIN;
+UPDATE t1 SET ChargeAuthorizationMessage = 'blablabla' WHERE
+ChargeID = 1;
+COMMIT;
+INSERT INTO t1
+VALUES(NULL,1,'2001-03-01',1,1,1,'New',NULL,NULL,'now');
+select * from t1;
ChargeID ServiceID ChargeDate ChargeAmount FedTaxes ProvTaxes ChargeStatus ChargeAuthorizationMessage ChargeComment ChargeTimeStamp
1 1 2001-03-01 1.00 1.00 1.00 New blablabla NULL now
2 1 2001-03-01 1.00 1.00 1.00 New NULL NULL now
+drop table t1;
diff --git a/mysql-test/r/bdb-deadlock.result b/mysql-test/r/bdb-deadlock.result
index 89077d16980..55b3d3ea2a5 100644
--- a/mysql-test/r/bdb-deadlock.result
+++ b/mysql-test/r/bdb-deadlock.result
@@ -1,10 +1,31 @@
+drop table if exists t1,t2;
+create table t1 (id integer, x integer) type=BDB;
+create table t2 (id integer, x integer) type=BDB;
+insert into t1 values(0, 0);
+insert into t2 values(0, 0);
+set autocommit=0;
+update t1 set x = 1 where id = 0;
+set autocommit=0;
+update t2 set x = 1 where id = 0;
+select x from t1 where id = 0;
+select x from t2 where id = 0;
+Deadlock found when trying to get lock; Try restarting transaction
+commit;
x
1
+commit;
+select * from t1;
id x
0 1
+select * from t2;
id x
0 1
+commit;
+select * from t1;
id x
0 1
+select * from t2;
id x
0 1
+commit;
+drop table t1,t2;
diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result
index 4d26304db4c..7374e936c36 100644
--- a/mysql-test/r/bdb.result
+++ b/mysql-test/r/bdb.result
@@ -1,3 +1,7 @@
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=bdb;
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
id code name
1 1 Tim
2 1 Monty
@@ -6,6 +10,8 @@ id code name
5 3 Sasha
6 3 Jeremy
7 4 Matt
+update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
+select id, code, name from t1 order by id;
id code name
2 1 Monty
3 2 David
@@ -14,6 +20,8 @@ id code name
6 3 Jeremy
7 4 Matt
8 1 Sinisa
+update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
+select id, code, name from t1 order by id;
id code name
3 2 David
4 2 Erik
@@ -22,10 +30,26 @@ id code name
7 4 Matt
8 1 Sinisa
12 1 Ralph
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=bdb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+Duplicate entry '1024' for key 1
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -66,6 +90,8 @@ id parent_id level
1193 105 2
1202 107 2
1203 107 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -106,16 +132,22 @@ id parent_id level
1194 105 2
1202 107 2
1204 107 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
id parent_id level
1008 102 2
1015 102 2
1010 102 2
+explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used; Using index
+explain select level,id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used; Using index
+explain select level,id,parent_id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used
+select level,id from t1 where level=1;
level id
1 1002
1 1003
@@ -123,6 +155,7 @@ level id
1 1005
1 1006
1 1007
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1002 101
1 1003 101
@@ -130,31 +163,77 @@ level id parent_id
1 1005 101
1 1006 101
1 1007 101
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 id A 39 NULL NULL
-t1 1 parent_id 1 parent_id A 9 NULL NULL
-t1 1 level 1 level A 3 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 id A 39 NULL NULL BTREE
+t1 1 parent_id 1 parent_id A 9 NULL NULL BTREE
+t1 1 level 1 level A 3 NULL NULL BTREE
+drop table t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) type=BDB;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+select * from t1;
gesuchnr benutzer_id
1 1
2 1
+drop table t1;
+create table t1 (id int not null primary key, x int not null, key (x)) type=bdb;
+insert into t1 (id, x) values (1, 1);
+replace into t1 (id, x) values (1, 2);
+select * from t1;
id x
1 2
+drop table t1;
+create table t1 (a int) type=bdb;
+insert into t1 values (1), (2);
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+delete from t1 where a = 1;
+select * from t1;
a
2
+check table t1;
Table Op Msg_type Msg_text
test.t1 check error The handler for the table doesn't support check/repair
+drop table t1;
+create table t1 (a int,b varchar(20)) type=bdb;
+insert into t1 values (1,""), (2,"testing");
+delete from t1 where a = 1;
+select * from t1;
a b
2 testing
+create index skr on t1 (a);
+insert into t1 values (3,""), (4,"testing");
+analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 1 skr 1 a A 3 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 skr 1 a A 3 NULL NULL YES BTREE
+drop table t1;
+create table t1 (a int,b varchar(20),key(a)) type=bdb;
+insert into t1 values (1,""), (2,"testing");
+select * from t1 where a = 1;
a b
1
+drop table t1;
+create table t1 (a char(10) not null, b int not null auto_increment, primary key(a,b)) type=BDB;
+insert into t1 values ("a",1),("b",2),("a",2),("c",1);
+insert into t1 values ("a",NULL),("b",NULL),("c",NULL),("e",NULL);
+insert into t1 (a) values ("a"),("b"),("c"),("d");
+insert into t1 (a) values ('k'),('d');
+insert into t1 (a) values ("a");
+insert into t1 values ("d",last_insert_id());
+select * from t1;
a b
a 1
a 2
@@ -172,121 +251,290 @@ d 2
d 5
e 1
k 1
+flush tables;
+select count(*) from t1;
count(*)
16
+drop table t1;
+create table t1 (n int not null primary key) type=bdb;
+set autocommit=0;
+insert into t1 values (4);
+rollback;
+select n, "after rollback" from t1;
n after rollback
+insert into t1 values (4);
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
+commit;
+insert into t1 values (5);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
5 after commit
+set autocommit=1;
+insert into t1 values (6);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+select n from t1;
n
4
5
6
+rollback;
+drop table t1;
+create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) type=BDB;
+begin;
+insert into t1 values(1,'hamdouni');
+select id as afterbegin_id,nom as afterbegin_nom from t1;
afterbegin_id afterbegin_nom
1 hamdouni
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=0;
+insert into t1 values(2,'mysql');
+select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
afterautocommit0_id afterautocommit0_nom
2 mysql
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=1;
+drop table t1;
+CREATE TABLE t1 (id char(8) not null primary key, val int not null) type=bdb;
+insert into t1 values ('pippo', 12);
+insert into t1 values ('pippo', 12);
+Duplicate entry 'pippo' for key 1
+delete from t1;
+delete from t1 where id = 'pippo';
+select * from t1;
id val
+insert into t1 values ('pippo', 12);
+set autocommit=0;
+delete from t1;
+rollback;
+select * from t1;
id val
pippo 12
+delete from t1;
+commit;
+select * from t1;
id val
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) TYPE=BDB;
+INSERT INTO t1 VALUES (1, 'Jochen');
+select * from t1;
ID NAME
1 Jochen
+drop table t1;
+CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) TYPE=BDB;
+set autocommit=0;
+INSERT INTO t1 SET _userid='marc@anyware.co.uk';
+COMMIT;
+SELECT * FROM t1;
_userid
marc@anyware.co.uk
+SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
_userid
marc@anyware.co.uk
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (
+user_id int(10) DEFAULT '0' NOT NULL,
+name varchar(100),
+phone varchar(100),
+ref_email varchar(100) DEFAULT '' NOT NULL,
+detail varchar(200),
+PRIMARY KEY (user_id,ref_email)
+)type=bdb;
+INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+select * from t1 where user_id>=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id>10292;
user_id name phone ref_email detail
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id<10292;
user_id name phone ref_email detail
10291 sanjeev 29153373 sansh777@hotmail.com xxx
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A NULL NULL NULL
-t1 0 PRIMARY 2 b A 0 NULL NULL
-t1 0 b 1 b A 0 NULL NULL
-t1 0 c 1 c A 0 NULL NULL
-t1 1 a 1 a A NULL NULL NULL
-t1 1 a_2 1 a A NULL NULL NULL
+drop table t1;
+CREATE TABLE t1 (a int not null, b int not null,c int not null,
+key(a),primary key(a,b), unique(c),key(a),unique(b));
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 b A 0 NULL NULL BTREE
+t1 0 c 1 c A 0 NULL NULL BTREE
+t1 0 b 1 b A 0 NULL NULL BTREE
+t1 1 a 1 a A NULL NULL NULL BTREE
+t1 1 a_2 1 a A NULL NULL NULL BTREE
+drop table t1;
+create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
+alter table t1 type=BDB;
+insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
+select * from t1;
col1 col2
1 1
2 3
3 4
4 4
5 2
+update t1 set col2='7' where col1='4';
+select * from t1;
col1 col2
1 1
2 3
3 4
4 7
5 2
+alter table t1 add co3 int not null;
+select * from t1;
col1 col2 co3
1 1 0
2 3 0
3 4 0
4 7 0
5 2 0
+update t1 set col2='9' where col1='2';
+select * from t1;
col1 col2 co3
1 1 0
2 9 0
3 4 0
4 7 0
5 2 0
+drop table t1;
+create table t1 (a int not null , b int, primary key (a)) type = BDB;
+create table t2 (a int not null , b int, primary key (a)) type = myisam;
+insert into t1 VALUES (1,3) , (2,3), (3,3);
+select * from t1;
a b
1 3
2 3
3 3
+insert into t2 select * from t1;
+select * from t2;
a b
1 3
2 3
3 3
+delete from t1 where b = 3;
+select * from t1;
a b
+insert into t1 select * from t2;
+select * from t1;
a b
1 3
2 3
3 3
+select * from t2;
a b
1 3
2 3
3 3
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+ggid varchar(32) binary DEFAULT '' NOT NULL,
+email varchar(64) DEFAULT '' NOT NULL,
+passwd varchar(32) binary DEFAULT '' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE ggid (ggid)
+) TYPE=BDB;
+insert into t1 (ggid,passwd) values ('test1','xxx');
+insert into t1 (ggid,passwd) values ('test2','yyy');
+insert into t1 (ggid,passwd) values ('test2','this will fail');
+Duplicate entry 'test2' for key 2
+insert into t1 (ggid,id) values ('this will fail',1);
+Duplicate entry '1' for key 1
+select * from t1 where ggid='test1';
id ggid email passwd
1 test1 xxx
+select * from t1 where passwd='xxx';
id ggid email passwd
1 test1 xxx
+select * from t1 where id=2;
id ggid email passwd
2 test2 yyy
+replace into t1 (ggid,id) values ('this will work',1);
+replace into t1 (ggid,passwd) values ('test2','this will work');
+update t1 set id=100,ggid='test2' where id=1;
+Duplicate entry 'test2' for key 2
+select * from t1;
id ggid email passwd
1 this will work
3 test2 this will work
+select * from t1 where id=1;
id ggid email passwd
1 this will work
+select * from t1 where id=999;
id ggid email passwd
+drop table t1;
+CREATE TABLE t1 (
+user_name varchar(12),
+password text,
+subscribed char(1),
+user_id int(11) DEFAULT '0' NOT NULL,
+quota bigint(20),
+weight double,
+access_date date,
+access_time time,
+approved datetime,
+dummy_primary_key int(11) NOT NULL auto_increment,
+PRIMARY KEY (dummy_primary_key)
+) TYPE=BDB;
+INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
+INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
+INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
+INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
+INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
+select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
user_name password subscribed user_id quota weight access_date access_time approved dummy_primary_key
user_0 somepassword N 0 0 0 2000-09-07 23:06:59 2000-09-07 23:06:59 1
user_1 somepassword Y 1 1 1 2000-09-07 23:06:59 2000-09-07 23:06:59 2
user_2 somepassword N 2 2 1.4142135623731 2000-09-07 23:06:59 2000-09-07 23:06:59 3
user_3 somepassword Y 3 3 1.7320508075689 2000-09-07 23:06:59 2000-09-07 23:06:59 4
user_4 somepassword N 4 4 2 2000-09-07 23:06:59 2000-09-07 23:06:59 5
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=bdb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
+INSERT INTO t1 values (179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+select * from t1;
id parent_id level
1001 100 0
1003 101 1
@@ -327,6 +575,8 @@ id parent_id level
1019 103 2
1005 101 1
1179 105 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1002 100 0
1004 101 1
@@ -367,12 +617,16 @@ id parent_id level
1020 103 2
1006 101 1
1180 105 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
id parent_id level
1009 102 2
1025 102 2
1016 102 2
+explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used; Using index
+select level,id from t1 where level=1;
level id
1 1004
1 1005
@@ -380,6 +634,7 @@ level id
1 1007
1 1008
1 1006
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1004 101
1 1005 101
@@ -387,6 +642,7 @@ level id parent_id
1 1007 101
1 1008 101
1 1006 101
+select level,id from t1 where level=1 order by id;
level id
1 1003
1 1004
@@ -394,6 +650,8 @@ level id
1 1006
1 1007
1 1008
+delete from t1 where level=1;
+select * from t1;
id parent_id level
1002 100 0
1009 102 2
@@ -428,43 +686,86 @@ id parent_id level
1022 104 2
1020 103 2
1180 105 2
+drop table t1;
+CREATE TABLE t1 (
+sca_code char(6) NOT NULL,
+cat_code char(6) NOT NULL,
+sca_desc varchar(50),
+lan_code char(2) NOT NULL,
+sca_pic varchar(100),
+sca_sdesc varchar(50),
+sca_sch_desc varchar(16),
+PRIMARY KEY (sca_code, cat_code, lan_code),
+INDEX sca_pic (sca_pic)
+) type = bdb ;
+INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'N', 'RING', 'EN', 'not null', NULL, 'RING');
+select count(*) from t1 where sca_code = 'PD';
count(*)
1
+select count(*) from t1 where sca_code <= 'PD';
count(*)
1
+select count(*) from t1 where sca_pic is null;
count(*)
2
+alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where cat_code='E';
count(*)
0
+alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where sca_pic >= 'n';
count(*)
1
+select sca_pic from t1 where sca_pic is null;
sca_pic
NULL
NULL
+update t1 set sca_pic="test" where sca_pic is null;
+delete from t1 where sca_code='pd';
+drop table t1;
+set @a:=now();
+CREATE TABLE t1 (a int not null, b timestamp not null, primary key (a)) type=bdb;
+insert into t1 (a) values(1),(2),(3);
+select t1.a from t1 natural join t1 as t2 where t1.b >= @a order by t1.a;
a
1
2
3
+update t1 set a=5 where a=1;
+select a from t1;
a
2
3
5
+drop table t1;
+flush logs;
+create table t1 (b blob, i int, key (b(100)), key (i), key (i, b(20))) type=bdb;
+insert into t1 values ('this is a blob', 1), (null, -1), (null, null),("",1),("",2),("",3);
+select b from t1 where b = 'this is a blob';
b
this is a blob
+select * from t1 where b like 't%';
b i
this is a blob 1
+select b, i from t1 where b is not null;
b i
this is a blob 1
1
2
3
+select * from t1 where b is null and i > 0;
b i
+select * from t1 where i is NULL;
b i
NULL NULL
+update t1 set b='updated' where i=1;
+select * from t1;
b i
updated 1
NULL -1
@@ -472,63 +773,353 @@ NULL NULL
updated 1
2
3
+drop table t1;
+create table t1 (a varchar(100) not null, primary key(a), b int not null) type=bdb;
+insert into t1 values("hello",1),("world",2);
+select * from t1 order by b desc;
a b
world 2
hello 1
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 2 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 2 NULL NULL BTREE
+drop table t1;
+create table t1 (i int, j int )TYPE=BDB;
+insert into t1 values (1,2);
+select * from t1 where i=1 and j=2;
i j
1 2
+create index ax1 on t1 (i,j);
+select * from t1 where i=1 and j=2;
i j
1 2
+drop table t1;
+drop table if exists t1, t2, t3, t4, t5, t6, t7;
+create table t1
+(
+branch_id int auto_increment primary key,
+branch_name varchar(255) not null,
+branch_active int not null default 1,
+unique branch_name(branch_name),
+index branch_active(branch_active)
+) type=bdb;
+drop table if exists t2 ;
+create table t2
+(
+target_id int auto_increment primary key,
+target_name varchar(255) not null,
+target_active int not null default 1,
+unique target_name(target_name),
+index target_active(target_active)
+) type=bdb;
+drop table if exists t3 ;
+create table t3
+(
+platform_id int auto_increment primary key,
+platform_name varchar(255) not null,
+platform_active int not null default 1,
+unique platform_name(platform_name),
+index platform_active(platform_active)
+) type=bdb;
+drop table if exists t4 ;
+create table t4
+(
+product_id int auto_increment primary key,
+product_name varchar(255) not null,
+version_file varchar(255) not null,
+product_active int not null default 1,
+unique product_name(product_name),
+index product_active(product_active)
+) type=bdb;
+drop table if exists t5 ;
+create table t5
+(
+product_file_id int auto_increment primary key,
+product_id int not null,
+file_name varchar(255) not null,
+/* cvs module used to find the file version */
+module_name varchar(255) not null,
+/* flag whether the file is still included in the product */
+file_included int not null default 1,
+unique product_file(product_id,file_name),
+index file_included(file_included)
+) type=bdb;
+drop table if exists t6 ;
+create table t6
+(
+file_platform_id int auto_increment primary key,
+product_file_id int not null,
+platform_id int not null,
+branch_id int not null,
+/* filename in the build system */
+build_filename varchar(255) not null,
+/* default filename in the build archive */
+archive_filename varchar(255) not null,
+unique file_platform(product_file_id,platform_id,branch_id)
+) type=bdb;
+drop table if exists t8 ;
+create table t8
+(
+archive_id int auto_increment primary key,
+branch_id int not null,
+target_id int not null,
+platform_id int not null,
+product_id int not null,
+status_id int not null default 1,
+unique archive(branch_id,target_id,platform_id,product_id),
+index status_id(status_id)
+) type=bdb;
+drop table if exists t7 ;
+create table t7
+(
+build_id int auto_increment primary key,
+branch_id int not null,
+target_id int not null,
+build_number int not null,
+build_date date not null,
+/* build system tag, e.g. 'rmanight-022301-1779' */
+build_tag varchar(255) not null,
+/* path relative to the build archive root, e.g. 'current' */
+build_path text not null,
+unique build(branch_id,target_id,build_number)
+) type=bdb;
+insert into t1 (branch_name)
+values ('RealMedia');
+insert into t1 (branch_name)
+values ('RP8REV');
+insert into t1 (branch_name)
+values ('SERVER_8_0_GOLD');
+insert into t2 (target_name)
+values ('rmanight');
+insert into t2 (target_name)
+values ('playerall');
+insert into t2 (target_name)
+values ('servproxyall');
+insert into t3 (platform_name)
+values ('linux-2.0-libc6-i386');
+insert into t3 (platform_name)
+values ('win32-i386');
+insert into t4 (product_name, version_file)
+values ('realserver', 'servinst');
+insert into t4 (product_name, version_file)
+values ('realproxy', 'prxyinst');
+insert into t4 (product_name, version_file)
+values ('realplayer', 'playinst');
+insert into t4 (product_name, version_file)
+values ('plusplayer', 'plusinst');
+create temporary table tmp1
+select branch_id, target_id, platform_id, product_id
+from t1, t2, t3, t4 ;
+create temporary table tmp2
+select tmp1.branch_id, tmp1.target_id, tmp1.platform_id, tmp1.product_id
+from tmp1 left join t8
+using (branch_id,target_id,platform_id,product_id)
+where t8.archive_id is null ;
+insert into t8
+(branch_id, target_id, platform_id, product_id, status_id)
+select branch_id, target_id, platform_id, product_id, 1
+from tmp2 ;
+drop table tmp1 ;
+drop table tmp2 ;
+insert into t5 (product_id, file_name, module_name)
+values (1, 'servinst', 'server');
+insert into t5 (product_id, file_name, module_name)
+values (2, 'prxyinst', 'server');
+insert into t5 (product_id, file_name, module_name)
+values (3, 'playinst', 'rpapp');
+insert into t5 (product_id, file_name, module_name)
+values (4, 'plusinst', 'rpapp');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (1, 2, 3, 'servinst.exe', 'win32-servinst.exe');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (1, 1, 3, 'v80_linux-2.0-libc6-i386_servinst.bin', 'linux2-servinst.exe');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (3, 2, 2, 'playinst.exe', 'win32-playinst.exe');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (4, 2, 2, 'playinst.exe', 'win32-playinst.exe');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (2, 2, 1071, 'playerall-022101-1071', '2001-02-21', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (2, 2, 1072, 'playerall-022201-1072', '2001-02-22', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (3, 3, 388, 'servproxyall-022201-388', '2001-02-22', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (3, 3, 389, 'servproxyall-022301-389', '2001-02-23', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (4, 4, 100, 'foo target-010101-100', '2001-01-01', 'current');
+update t8
+set status_id=2
+where branch_id=2 and target_id=2 and platform_id=2 and product_id=1;
+select t7.build_path
+from
+t1,
+t7,
+t2,
+t3,
+t4,
+t5,
+t6
+where
+t7.branch_id = t1.branch_id and
+t7.target_id = t2.target_id and
+t5.product_id = t4.product_id and
+t6.product_file_id = t5.product_file_id and
+t6.platform_id = t3.platform_id and
+t6.branch_id = t6.branch_id and
+t7.build_id = 1 and
+t4.product_id = 3 and
+t5.file_name = 'playinst' and
+t3.platform_id = 2;
build_path
current
+drop table t1, t2, t3, t4, t5, t6, t7, t8;
+CREATE TABLE t1 (
+a tinytext NOT NULL,
+b tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (a(32),b)
+) TYPE=BDB;
+INSERT INTO t1 VALUES ('a',1),('a',2);
+SELECT * FROM t1 WHERE a='a' AND b=2;
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (2);
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (1,2);
a b
a 1
a 2
+drop table t1;
+CREATE TABLE t1 (
+a int3 unsigned NOT NULL,
+b int1 unsigned NOT NULL,
+UNIQUE (a, b)
+) TYPE = BDB;
+INSERT INTO t1 VALUES (1, 1);
+SELECT MIN(B),MAX(b) FROM t1 WHERE t1.a = 1;
MIN(B) MAX(b)
1 1
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+select id from t1;
id
0
1
2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+begin;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
+commit;
+select id,id3 from t1;
id id3
0 0
1 1
2 2
100 2
+UNLOCK TABLES;
+DROP TABLE t1;
+CREATE TABLE t1 (SYAIN_NO char(5) NOT NULL default '', KINMU_DATE char(6) NOT NULL default '', PRIMARY KEY (SYAIN_NO,KINMU_DATE)) TYPE=BerkeleyDB;
+CREATE TABLE t2 ( SYAIN_NO char(5) NOT NULL default '',STR_DATE char(8) NOT NULL default '',PRIMARY KEY (SYAIN_NO,STR_DATE) ) TYPE=BerkeleyDB;
+select T1.KINMU_DATE from t1 T1 ,t2 T2 where T1.SYAIN_NO = '12345' and T1.KINMU_DATE = '200106' and T2.SYAIN_NO = T1.SYAIN_NO;
KINMU_DATE
+select T1.KINMU_DATE from t1 T1 ,t2 T2 where T1.SYAIN_NO = '12345' and T1.KINMU_DATE = '200106' and T2.SYAIN_NO = T1.SYAIN_NO;
KINMU_DATE
+DROP TABLE t1,t2;
+drop table if exists t1;
+create table t1 (a int(11) not null, b int(11) not null, unique (a,b)) type=bdb;
+insert into t1 values (1,1), (1,2);
+select * from t1 where a = 1;
a b
1 1
1 2
+select t1.*, t2.* from t1, t1 t2 where t1.a = t2.a and t2.a = 1;
a b a b
1 1 1 1
1 1 1 2
1 2 1 1
1 2 1 2
+select * from t1 where a = 1;
a b
1 1
1 2
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ');
+create table t2 (id int NOT NULL,primary key (id)) type=bdb;
+LOCK TABLES t1 WRITE, t2 WRITE;
+insert into t2 values(1);
+SELECT t1.* FROM t1 WHERE id IN (1);
id id2 id3 dummy1
+SELECT t1.* FROM t2 left outer join t1 on (t1.id=t2.id);
id id2 id3 dummy1
NULL NULL NULL NULL
+delete from t1 where id3 >= 0 and id3 <= 0;
+drop table t1,t2;
+CREATE TABLE t1 (i varchar(48) NOT NULL default '', p varchar(255) default NULL,s varchar(48) NOT NULL default '', PRIMARY KEY (i), UNIQUE(p,s)) TYPE=BDB;
+INSERT INTO t1 VALUES ('00000000-e6c4ddeaa6-003b8-83458387','programs/xxxxxxxx.wmv','00000000-e6c4ddeb32-003bc-83458387');
+SELECT * FROM t1 WHERE p='programs/xxxxxxxx.wmv';
i p s
00000000-e6c4ddeaa6-003b8-83458387 programs/xxxxxxxx.wmv 00000000-e6c4ddeb32-003bc-83458387
+drop table t1;
+CREATE TABLE t1 ( STR_DATE varchar(8) NOT NULL default '',INFO_NOTE varchar(200) default NULL,PRIMARY KEY (STR_DATE) ) TYPE=BerkeleyDB;
+select INFO_NOTE from t1 where STR_DATE = '20010610';
INFO_NOTE
+select INFO_NOTE from t1 where STR_DATE < '20010610';
INFO_NOTE
+select INFO_NOTE from t1 where STR_DATE > '20010610';
INFO_NOTE
+drop table t1;
+create table t1 (a int not null, b int, primary key (a)) type =bdb;
+create table t2 (a int not null, b int, primary key (a)) type =bdb;
+insert into t1 values (2, 3),(1, 7),(10, 7);
+insert into t2 values (2, 3),(1, 7),(10, 7);
+select * from t1;
+a b
+1 7
+2 3
+10 7
+select * from t2;
+a b
+1 7
+2 3
+10 7
+delete t1, t2 from t1, t2 where t1.a = t2.a;
+select * from t1;
+a b
+select * from t2;
+a b
+select * from t2;
+a b
+drop table t1,t2;
diff --git a/mysql-test/r/bench_count_distinct.result b/mysql-test/r/bench_count_distinct.result
index 20f23c0abbe..d414e8e466e 100644
--- a/mysql-test/r/bench_count_distinct.result
+++ b/mysql-test/r/bench_count_distinct.result
@@ -1,2 +1,6 @@
+drop table if exists t1;
+create table t1(n int not null, key(n)) delay_key_write = 1;
+select count(distinct n) from t1;
count(distinct n)
100
+drop table t1;
diff --git a/mysql-test/r/big_test.require b/mysql-test/r/big_test.require
new file mode 100644
index 00000000000..001b903496b
--- /dev/null
+++ b/mysql-test/r/big_test.require
@@ -0,0 +1,2 @@
+using_big_test
+1
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index 46ce0fda2c1..f2cb6437f8f 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -1,15 +1,78 @@
+select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296;
0 256 00000000000000065536 2147483647 -2147483648 2147483648 +4294967296
0 256 65536 2147483647 -2147483648 2147483648 4294967296
+select 9223372036854775807,-009223372036854775808;
9223372036854775807 -009223372036854775808
9223372036854775807 -9223372036854775808
+select +9999999999999999999,-9999999999999999999;
+9999999999999999999 -9999999999999999999
10000000000000000000 -10000000000000000000
+drop table if exists t1;
+create table t1 (a bigint unsigned not null, primary key(a));
+insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE);
+select * from t1;
a
18446744073709551614
18446744073709551615
+select * from t1 where a=18446744073709551615;
a
18446744073709551615
+select * from t1 where a='18446744073709551615';
a
18446744073709551615
+delete from t1 where a=18446744073709551615;
+select * from t1;
a
18446744073709551614
+drop table t1;
+create table t1 ( a int not null default 1, big bigint );
+insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615);
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+alter table t1 modify big bigint unsigned not null;
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+alter table t1 add key (big);
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+alter table t1 modify big bigint not null;
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+drop table t1;
+select CAST(1-2 AS UNSIGNED);
+CAST(1-2 AS UNSIGNED)
+18446744073709551615
+select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
+CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
+-1
+select CONVERT('-1',UNSIGNED);
+CONVERT('-1',UNSIGNED)
+18446744073709551615
+select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
+cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
+18446744073709551611 18446744073709551611
+select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
+cast(-5 as unsigned) -1 cast(-5 as unsigned) + 1
+18446744073709551610 18446744073709551612
+select ~5, cast(~5 as signed);
+~5 cast(~5 as signed)
+18446744073709551610 -6
+select cast(5 as unsigned) -6.0;
+cast(5 as unsigned) -6.0
+-1.0
diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result
index c5f9961699d..9f1c8ffac41 100644
--- a/mysql-test/r/binary.result
+++ b/mysql-test/r/binary.result
@@ -1,33 +1,55 @@
+create table t1 (name char(20) not null, primary key (name));
+create table t2 (name char(20) binary not null, primary key (name));
+insert into t1 values ("å");
+insert into t1 values ("ä");
+insert into t1 values ("ö");
+insert into t2 select * from t1;
+select * from t1 order by name;
name
å
ä
ö
+select concat("*",name,"*") from t1 order by 1;
concat("*",name,"*")
*å*
*ä*
*ö*
+select min(name),min(concat("*",name,"*")),max(name),max(concat("*",name,"*")) from t1;
min(name) min(concat("*",name,"*")) max(name) max(concat("*",name,"*"))
å *å* ö *ö*
+select * from t2 order by name;
name
ä
å
ö
+select concat("*",name,"*") from t2 order by 1;
concat("*",name,"*")
*ä*
*å*
*ö*
+select min(name),min(concat("*",name,"*")),max(name),max(concat("*",name,"*")) from t2;
min(name) min(concat("*",name,"*")) max(name) max(concat("*",name,"*"))
ä *ä* ö *ö*
+select name from t1 where name between 'Ä' and 'Ö';
name
ä
ö
+select name from t2 where name between 'ä' and 'ö';
name
ä
å
ö
+select name from t2 where name between 'Ä' and 'Ö';
name
+drop table t1,t2;
+create table t1 (a char(10) not null, b char(10) binary not null,index (a));
+insert into t1 values ("hello ","hello "),("hello2 ","hello2 ");
+select * from t1 where a="hello ";
a b
hello hello
+select * from t1 where b="hello ";
a b
+select * from t1 where b="hello";
a b
hello hello
+drop table t1;
diff --git a/mysql-test/r/bulk_replace.result b/mysql-test/r/bulk_replace.result
new file mode 100644
index 00000000000..0a079965b82
--- /dev/null
+++ b/mysql-test/r/bulk_replace.result
@@ -0,0 +1,11 @@
+drop table if exists t1;
+CREATE TABLE t1 (a int, unique (a), b int not null, unique(b), c int not null, index(c));
+replace into t1 values (1,1,1),(2,2,2),(3,1,3);
+select * from t1;
+a b c
+3 1 3
+2 2 2
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 073164aa035..ec37c9a5763 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -1,42 +1,65 @@
+drop table if exists t1;
+select CASE "b" when "a" then 1 when "b" then 2 END;
CASE "b" when "a" then 1 when "b" then 2 END
2
+select CASE "c" when "a" then 1 when "b" then 2 END;
CASE "c" when "a" then 1 when "b" then 2 END
NULL
+select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END;
CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END
3
+select CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END;
CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END
ok
+select CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END;
CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END
ok
+select CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end;
CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end
a
+select CASE when 1=0 then "true" else "false" END;
CASE when 1=0 then "true" else "false" END
false
+select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END;
CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END
one
+select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END;
CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END
two
+select (CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0;
(CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0
2
+select (CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0;
(CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0
2.00
+select case 1/0 when "a" then "true" else "false" END;
case 1/0 when "a" then "true" else "false" END
false
+select case 1/0 when "a" then "true" END;
case 1/0 when "a" then "true" END
NULL
+select (case 1/0 when "a" then "true" END) | 0;
(case 1/0 when "a" then "true" END) | 0
NULL
+select (case 1/0 when "a" then "true" END) + 0.0;
(case 1/0 when "a" then "true" END) + 0.0
NULL
+select case when 1>0 then "TRUE" else "FALSE" END;
case when 1>0 then "TRUE" else "FALSE" END
TRUE
+select case when 1<0 then "TRUE" else "FALSE" END;
case when 1<0 then "TRUE" else "FALSE" END
FALSE
+create table t1 (a int);
+insert into t1 values(1),(2),(3),(4);
+select case a when 1 then 2 when 2 then 3 else 0 end as fcase, count(*) from t1 group by fcase;
fcase count(*)
0 2
2 1
3 1
+select case a when 1 then "one" when 2 then "two" else "nothing" end as fcase, count(*) from t1 group by fcase;
fcase count(*)
nothing 2
one 1
two 1
+drop table t1;
diff --git a/mysql-test/r/check.result b/mysql-test/r/check.result
index 694d7429a14..ecaa13642bd 100644
--- a/mysql-test/r/check.result
+++ b/mysql-test/r/check.result
@@ -1,2 +1,7 @@
+drop table if exists t1;
+create table t1(n int not null, key(n), key(n), key(n), key(n));
+ check table t1 extended;
+insert into t1 values (200000);
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result
index 7044667e4af..8092f789954 100644
--- a/mysql-test/r/comments.result
+++ b/mysql-test/r/comments.result
@@ -1,15 +1,28 @@
+select 1+2/*hello*/+3;
1+2/*hello*/+3
6
+select 1 /* long
+multi line comment */;
1
1
+;
+Query was empty
+select 1 /*!32301 +1 */;
1 /*!32301 +1
2
+select 1 /*!52301 +1 */;
1
1
+select 1--1;
1--1
2
+select 1 --2
++1;
1 --2
+1
4
+select 1 # The rest of the row will be ignored
+;
1
1
+/* line with only comment */;
diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result
index 6af85c16dff..07f9ce4e81a 100644
--- a/mysql-test/r/compare.result
+++ b/mysql-test/r/compare.result
@@ -1,6 +1,14 @@
+drop table if exists t1;
+CREATE TABLE t1 (id CHAR(12) not null, PRIMARY KEY (id));
+insert into t1 values ('000000000001'),('000000000002');
+explain select * from t1 where id=000000000001;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 12 NULL 2 where used; Using index
+select * from t1 where id=000000000001;
id
000000000001
+delete from t1 where id=000000000002;
+select * from t1;
id
000000000001
+drop table t1;
diff --git a/mysql-test/r/count_distinct.result b/mysql-test/r/count_distinct.result
index 97d7b57f249..3bff6c6ad88 100644
--- a/mysql-test/r/count_distinct.result
+++ b/mysql-test/r/count_distinct.result
@@ -1,11 +1,46 @@
+drop table if exists t1,t2,t3;
+create table t1 (libname varchar(21) not null, city text, primary key (libname));
+create table t2 (isbn varchar(21) not null, author text, title text, primary key (isbn));
+create table t3 (isbn varchar(21) not null, libname varchar(21) not null, quantity int ,primary key (isbn,libname));
+insert into t2 values ('001','Daffy','A duck''s life');
+insert into t2 values ('002','Bugs','A rabbit\'s life');
+insert into t2 values ('003','Cowboy','Life on the range');
+insert into t2 values ('000','Anonymous','Wanna buy this book?');
+insert into t2 values ('004','Best Seller','One Heckuva book');
+insert into t2 values ('005','EveryoneBuys','This very book');
+insert into t2 values ('006','San Fran','It is a san fran lifestyle');
+insert into t2 values ('007','BerkAuthor','Cool.Berkley.the.book');
+insert into t3 values('000','New York Public Libra','1');
+insert into t3 values('001','New York Public Libra','2');
+insert into t3 values('002','New York Public Libra','3');
+insert into t3 values('003','New York Public Libra','4');
+insert into t3 values('004','New York Public Libra','5');
+insert into t3 values('005','New York Public Libra','6');
+insert into t3 values('006','San Fransisco Public','5');
+insert into t3 values('007','Berkeley Public1','3');
+insert into t3 values('007','Berkeley Public2','3');
+insert into t3 values('001','NYC Lib','8');
+insert into t1 values ('New York Public Libra','New York');
+insert into t1 values ('San Fransisco Public','San Fran');
+insert into t1 values ('Berkeley Public1','Berkeley');
+insert into t1 values ('Berkeley Public2','Berkeley');
+insert into t1 values ('NYC Lib','New York');
+select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname;
isbn city libname a
007 Berkeley Berkeley Public1 1
007 Berkeley Berkeley Public2 1
000 New York New York Public Libra 6
001 New York NYC Lib 1
006 San Fran San Fransisco Public 1
+select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1;
isbn city libname a
007 Berkeley Berkeley Public1 2
000 New York New York Public Libra 2
+drop table t1, t2, t3;
+create table t1 (f1 int);
+insert into t1 values (1);
+create table t2 (f1 int,f2 int);
+select t1.f1,count(distinct t2.f2),count(distinct 1,NULL) from t1 left join t2 on t1.f1=t2.f1 group by t1.f1;
f1 count(distinct t2.f2) count(distinct 1,NULL)
1 0 0
+drop table t1,t2;
diff --git a/mysql-test/r/count_distinct2.result b/mysql-test/r/count_distinct2.result
new file mode 100644
index 00000000000..131e3b325ec
--- /dev/null
+++ b/mysql-test/r/count_distinct2.result
@@ -0,0 +1,129 @@
+drop table if exists t1;
+create table t1(n1 int, n2 int, s char(20), vs varchar(20), t text);
+insert into t1 values (1,11, 'one','eleven', 'eleven'),
+(1,11, 'one','eleven', 'eleven'),
+(2,11, 'two','eleven', 'eleven'),
+(2,12, 'two','twevle', 'twelve'),
+(2,13, 'two','thirteen', 'foo'),
+(2,13, 'two','thirteen', 'foo'),
+(2,13, 'two','thirteen', 'bar'),
+(NULL,13, 'two','thirteen', 'bar'),
+(2,NULL, 'two','thirteen', 'bar'),
+(2,13, NULL,'thirteen', 'bar'),
+(2,13, 'two',NULL, 'bar'),
+(2,13, 'two','thirteen', NULL);
+select distinct n1 from t1;
+n1
+1
+2
+NULL
+select count(distinct n1) from t1;
+count(distinct n1)
+2
+select distinct n2 from t1;
+n2
+11
+12
+13
+NULL
+select count(distinct n2) from t1;
+count(distinct n2)
+3
+select distinct s from t1;
+s
+one
+two
+NULL
+select count(distinct s) from t1;
+count(distinct s)
+2
+select distinct vs from t1;
+vs
+eleven
+twevle
+thirteen
+NULL
+select count(distinct vs) from t1;
+count(distinct vs)
+3
+select distinct t from t1;
+t
+eleven
+twelve
+foo
+bar
+NULL
+select count(distinct t) from t1;
+count(distinct t)
+4
+select distinct n1,n2 from t1;
+n1 n2
+1 11
+2 11
+2 12
+2 13
+NULL 13
+2 NULL
+select count(distinct n1,n2) from t1;
+count(distinct n1,n2)
+4
+select distinct n1,s from t1;
+n1 s
+1 one
+2 two
+NULL two
+2 NULL
+select count(distinct n1,s) from t1;
+count(distinct n1,s)
+2
+select distinct s,n1,vs from t1;
+s n1 vs
+one 1 eleven
+two 2 eleven
+two 2 twevle
+two 2 thirteen
+two NULL thirteen
+NULL 2 thirteen
+two 2 NULL
+select count(distinct s,n1,vs) from t1;
+count(distinct s,n1,vs)
+4
+select distinct s,t from t1;
+s t
+one eleven
+two eleven
+two twelve
+two foo
+two bar
+NULL bar
+two NULL
+select count(distinct s,t) from t1;
+count(distinct s,t)
+5
+select count(distinct n1), count(distinct n2) from t1;
+count(distinct n1) count(distinct n2)
+2 3
+select count(distinct n2), n1 from t1 group by n1;
+count(distinct n2) n1
+1 NULL
+1 1
+3 2
+drop table t1;
+create table t1 (n int default NULL);
+flush status;
+select count(distinct n) from t1;
+count(distinct n)
+5000
+show status like 'Created_tmp_disk_tables';
+Variable_name Value
+Created_tmp_disk_tables 1
+drop table t1;
+create table t1 (s text);
+flush status;
+select count(distinct s) from t1;
+count(distinct s)
+5000
+show status like 'Created_tmp_disk_tables';
+Variable_name Value
+Created_tmp_disk_tables 1
+drop table t1;
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 88d597bd3d7..ef44e840a79 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1,17 +1,101 @@
+drop table if exists t1,t2;
+create table t1 (b char(0));
+insert into t1 values (""),(null);
+select * from t1;
b
NULL
+drop table if exists t1;
+create table t1 (b char(0) not null);
+create table if not exists t1 (b char(0) not null);
+insert into t1 values (""),(null);
+select * from t1;
b
+drop table if exists t1;
+create table t2 type=heap select * from t1;
+Table 'test.t1' doesn't exist
+create table t2 select auto+1 from t1;
+Table 'test.t1' doesn't exist
+drop table if exists t1,t2;
+create table t1 (b char(0) not null, index(b));
+The used table handler can't index column 'b'
+create table t1 (a int not null auto_increment,primary key (a)) type=heap;
+The used table type doesn't support AUTO_INCREMENT columns
+create table t1 (a int not null,b text) type=heap;
+The used table type doesn't support BLOB/TEXT columns
+create table t1 (a int ,primary key(a)) type=heap;
+All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead
+drop table if exists t1;
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
+The used table type doesn't support AUTO_INCREMENT columns
+create table t1 (ordid int(8), primary key (ordid));
+All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead
+create table not_existing_database.test (a int);
+Got one of the listed errors
+create table `a/a` (a int);
+Incorrect table name 'a/a'
+create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
+Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
+Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
+create table 1ea10 (1a20 int,1e int);
+insert into 1ea10 values(1,1);
+select 1ea10.1a20,1e+ 1e+10 from 1ea10;
1a20 1e+ 1e+10
1 10000000001
+drop table 1ea10;
+create table t1 (t1.index int);
+drop table t1;
+drop database if exists test_$1;
+create database test_$1;
+create table test_$1.$test1 (a$1 int, $b int, c$ int);
+insert into test_$1.$test1 values (1,2,3);
+select a$1, $b, c$ from test_$1.$test1;
a$1 $b c$
1 2 3
+create table test_$1.test2$ (a int);
+drop table test_$1.test2$;
+drop database test_$1;
+create table t1 (a int auto_increment not null primary key, B CHAR(20));
+insert into t1 (b) values ("hello"),("my"),("world");
+create table t2 (key (b)) select * from t1;
+explain select * from t2 where b="world";
table type possible_keys key key_len ref rows Extra
t2 ref B B 21 const 1 where used
+select * from t2 where b="world";
a B
3 world
+drop table t1,t2;
+create table t1(x varchar(50) );
+create table t2 select x from t1 where 1=2;
+describe t1;
+Field Type Null Key Default Extra
+x varchar(50) YES NULL
+describe t2;
+Field Type Null Key Default Extra
+x char(50) YES NULL
+drop table t2;
+create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
+describe t2;
+Field Type Null Key Default Extra
+a datetime 0000-00-00 00:00:00
+b time 00:00:00
+c date 0000-00-00
+d bigint(17) 0
+e double(18,1) 0.0
+f bigint(17) 0
+drop table t2;
+create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt;
+describe t2;
+Field Type Null Key Default Extra
+d date 0000-00-00
+t time 00:00:00
+dt datetime 0000-00-00 00:00:00
+drop table t1,t2;
+create table t1 (a int not null, b int, primary key(a), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b));
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
@@ -49,3 +133,4 @@ t1 CREATE TABLE `t1` (
KEY `b_30` (`b`),
KEY `b_31` (`b`)
) TYPE=MyISAM
+drop table t1;
diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result
new file mode 100644
index 00000000000..58ed0dfdbf3
--- /dev/null
+++ b/mysql-test/r/ctype_latin1_de.result
@@ -0,0 +1,207 @@
+drop table if exists t1;
+create table t1 (a char (20) not null, b int not null auto_increment, index (a,b),index(b));
+insert into t1 (a) values ('ä'),('ac'),('ae'),('ad'),('Äc'),('aeb');
+insert into t1 (a) values ('üc'),('uc'),('ue'),('ud'),('Ü'),('ueb'),('uf');
+insert into t1 (a) values ('ö'),('oc'),('Öa'),('oe'),('od'),('Öc'),('oeb');
+insert into t1 (a) values ('s'),('ss'),('ß'),('ßb'),('ssa'),('ssc'),('ßa');
+insert into t1 (a) values ('eä'),('uü'),('öo'),('ää'),('ääa'),('aeae');
+insert into t1 (a) values ('q'),('a'),('u'),('o'),('é'),('É');
+select a,b from t1 order by a,b;
+a b
+a 35
+ac 2
+ad 4
+ä 1
+ae 3
+ää 31
+aeae 33
+ääa 32
+aeb 6
+Äc 5
+é 38
+É 39
+eä 28
+o 37
+oc 15
+od 18
+ö 14
+oe 17
+Öa 16
+oeb 20
+Öc 19
+öo 30
+q 34
+s 21
+ss 22
+ß 23
+ssa 25
+ßa 27
+ßb 24
+ssc 26
+u 36
+uc 8
+ud 10
+ue 9
+Ü 11
+ueb 12
+üc 7
+uf 13
+uü 29
+select a,b from t1 order by upper(a),b;
+a b
+a 35
+ac 2
+ad 4
+ä 1
+ae 3
+ää 31
+aeae 33
+ääa 32
+aeb 6
+Äc 5
+é 38
+É 39
+eä 28
+o 37
+oc 15
+od 18
+ö 14
+oe 17
+Öa 16
+oeb 20
+Öc 19
+öo 30
+q 34
+s 21
+ss 22
+ß 23
+ssa 25
+ßa 27
+ßb 24
+ssc 26
+u 36
+uc 8
+ud 10
+ue 9
+Ü 11
+ueb 12
+üc 7
+uf 13
+uü 29
+select a from t1 order by a desc;
+a
+uü
+uf
+üc
+ueb
+ue
+ud
+uc
+u
+ssc
+ßb
+ßa
+ssa
+ss
+s
+q
+öo
+Öc
+oeb
+Öa
+oe
+od
+oc
+o
+eä
+Äc
+aeb
+ääa
+aeae
+ää
+ae
+ad
+ac
+a
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1 where a like "ö%";
+a b
+ö 14
+Öa 16
+Öc 19
+öo 30
+select * from t1 where a like binary "%É%";
+a b
+É 39
+select * from t1 where a like "%Á%";
+a b
+a 35
+ac 2
+ad 4
+ae 3
+aeae 33
+ääa 32
+aeb 6
+Öa 16
+ssa 25
+ßa 27
+select * from t1 where a like "%U%";
+a b
+u 36
+uc 8
+ud 10
+ue 9
+ueb 12
+uf 13
+uü 29
+select * from t1 where a like "%ss%";
+a b
+ss 22
+ssa 25
+ssc 26
+drop table t1;
+select strcmp('ä','ae'),strcmp('ae','ä'),strcmp('aeq','äq'),strcmp('äq','aeq');
+strcmp('ä','ae') strcmp('ae','ä') strcmp('aeq','äq') strcmp('äq','aeq')
+0 0 0 0
+select strcmp('ss','ß'),strcmp('ß','ss'),strcmp('ßs','sss'),strcmp('ßq','ssq');
+strcmp('ss','ß') strcmp('ß','ss') strcmp('ßs','sss') strcmp('ßq','ssq')
+0 0 0 0
+select strcmp('ä','af'),strcmp('a','ä'),strcmp('ää','aeq'),strcmp('ää','aeaeq');
+strcmp('ä','af') strcmp('a','ä') strcmp('ää','aeq') strcmp('ää','aeaeq')
+-1 -1 -1 -1
+select strcmp('ss','ßa'),strcmp('ß','ssa'),strcmp('sßa','sssb'),strcmp('s','ß');
+strcmp('ss','ßa') strcmp('ß','ssa') strcmp('sßa','sssb') strcmp('s','ß')
+-1 -1 -1 -1
+select strcmp('ö','oö'),strcmp('Ü','uü'),strcmp('ö','oeb');
+strcmp('ö','oö') strcmp('Ü','uü') strcmp('ö','oeb')
+-1 -1 -1
+select strcmp('af','ä'),strcmp('ä','a'),strcmp('aeq','ää'),strcmp('aeaeq','ää');
+strcmp('af','ä') strcmp('ä','a') strcmp('aeq','ää') strcmp('aeaeq','ää')
+1 1 1 1
+select strcmp('ßa','ss'),strcmp('ssa','ß'),strcmp('sssb','sßa'),strcmp('ß','s');
+strcmp('ßa','ss') strcmp('ssa','ß') strcmp('sssb','sßa') strcmp('ß','s')
+1 1 1 1
+select strcmp('u','öa'),strcmp('u','ö');
+strcmp('u','öa') strcmp('u','ö')
+1 1
+create table t1 (a varchar(10), key(a));
+insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
+select * from t1 where a like "abc%";
+a
+abc
+abcd
+select * from t1 where a like "test%";
+a
+test
+select * from t1 where a like "te_t";
+a
+test
+drop table t1;
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result
index d1914341a8d..44aef139ad2 100644
--- a/mysql-test/r/delayed.result
+++ b/mysql-test/r/delayed.result
@@ -1,10 +1,30 @@
+create table t1 (a char(10), tmsp timestamp);
+insert into t1 set a = 1;
+insert delayed into t1 set a = 2;
+insert into t1 set a = 3, tmsp=NULL;
+insert delayed into t1 set a = 4;
+insert delayed into t1 set a = 5, tmsp = 19711006010203;
+insert delayed into t1 (a, tmsp) values (6, 19711006010203);
+insert delayed into t1 (a, tmsp) values (7, NULL);
+insert into t1 set a = 8,tmsp=19711006010203;
+select * from t1 where tmsp=0;
a tmsp
+select * from t1 where tmsp=19711006010203;
a tmsp
5 19711006010203
6 19711006010203
8 19711006010203
+drop table t1;
+create table t1 (a int not null auto_increment primary key, b char(10));
+insert delayed into t1 values (1,"b");
+insert delayed into t1 values (null,"c");
+insert delayed into t1 values (3,"d"),(null,"e");
+insert delayed into t1 values (3,"this will give an","error");
+Column count doesn't match value count at row 1
+select * from t1;
a b
1 b
2 c
3 d
4 e
+drop table t1;
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
new file mode 100644
index 00000000000..c2230722aa6
--- /dev/null
+++ b/mysql-test/r/delete.result
@@ -0,0 +1,26 @@
+drop table if exists t1;
+CREATE TABLE t1 (a tinyint(3), b tinyint(5));
+INSERT INTO t1 VALUES (1,1);
+INSERT LOW_PRIORITY INTO t1 VALUES (1,2);
+INSERT INTO t1 VALUES (1,3);
+DELETE from t1 where a=1 limit 1;
+DELETE LOW_PRIORITY from t1 where a=1;
+INSERT INTO t1 VALUES (1,1);
+DELETE from t1;
+LOCK TABLE t1 write;
+INSERT INTO t1 VALUES (1,2);
+DELETE from t1;
+UNLOCK TABLES;
+INSERT INTO t1 VALUES (1,2);
+SET AUTOCOMMIT=0;
+DELETE from t1;
+SET AUTOCOMMIT=1;
+drop table t1;
+create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
+insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23);
+delete from t1 where a=26;
+drop table t1;
+create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
+insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
+delete from t1 where a=27;
+drop table t1;
diff --git a/mysql-test/r/dirty-close.result b/mysql-test/r/dirty-close.result
deleted file mode 100644
index f85b057eefa..00000000000
--- a/mysql-test/r/dirty-close.result
+++ /dev/null
@@ -1,4 +0,0 @@
-n
-1
-2
-3
diff --git a/mysql-test/r/dirty_close.result b/mysql-test/r/dirty_close.result
new file mode 100644
index 00000000000..c4fc19a35f8
--- /dev/null
+++ b/mysql-test/r/dirty_close.result
@@ -0,0 +1,9 @@
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values (1),(2),(3);
+select * from t1;
+n
+1
+2
+3
+drop table t1;
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index 8f8770e5602..e347a95b037 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -1,3 +1,21 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (id int,facility char(20));
+CREATE TABLE t2 (facility char(20));
+INSERT INTO t1 VALUES (NULL,NULL);
+INSERT INTO t1 VALUES (-1,'');
+INSERT INTO t1 VALUES (0,'');
+INSERT INTO t1 VALUES (1,'/L');
+INSERT INTO t1 VALUES (2,'A01');
+INSERT INTO t1 VALUES (3,'ANC');
+INSERT INTO t1 VALUES (4,'F01');
+INSERT INTO t1 VALUES (5,'FBX');
+INSERT INTO t1 VALUES (6,'MT');
+INSERT INTO t1 VALUES (7,'P');
+INSERT INTO t1 VALUES (8,'RV');
+INSERT INTO t1 VALUES (9,'SRV');
+INSERT INTO t1 VALUES (10,'VMT');
+INSERT INTO t2 SELECT DISTINCT FACILITY FROM t1;
+select id from t1 group by id;
id
NULL
-1
@@ -12,6 +30,7 @@ NULL
8
9
10
+select * from t1 order by id;
id facility
NULL NULL
-1
@@ -26,6 +45,7 @@ NULL NULL
8 RV
9 SRV
10 VMT
+select id-5,facility from t1 order by "id-5";
id-5 facility
NULL NULL
-6
@@ -40,6 +60,7 @@ NULL NULL
3 RV
4 SRV
5 VMT
+select id,concat(facility) from t1 group by id ;
id concat(facility)
NULL NULL
-1
@@ -54,7 +75,9 @@ NULL NULL
8 RV
9 SRV
10 VMT
+select id+0 as a,max(id),concat(facility) as b from t1 group by a order by b desc,a;
a max(id) b
+NULL NULL NULL
10 10 VMT
9 9 SRV
8 8 RV
@@ -67,10 +90,11 @@ a max(id) b
1 1 /L
-1 -1
0 0
-NULL NULL NULL
+select id >= 0 and id <= 5 as grp,count(*) from t1 group by grp;
grp count(*)
0 7
1 6
+SELECT DISTINCT FACILITY FROM t1;
FACILITY
NULL
@@ -84,6 +108,7 @@ P
RV
SRV
VMT
+SELECT FACILITY FROM t2;
FACILITY
NULL
@@ -97,52 +122,157 @@ P
RV
SRV
VMT
+SELECT count(*) from t1,t2 where t1.facility=t2.facility;
count(*)
12
+select count(facility) from t1;
count(facility)
12
+select count(*) from t1;
count(*)
13
+select count(*) from t1 where facility IS NULL;
count(*)
1
+select count(*) from t1 where facility = NULL;
count(*)
0
+select count(*) from t1 where facility IS NOT NULL;
count(*)
12
+select count(*) from t1 where id IS NULL;
count(*)
1
+select count(*) from t1 where id IS NOT NULL;
count(*)
12
+drop table t1,t2;
+CREATE TABLE t1 (UserId int(11) DEFAULT '0' NOT NULL);
+INSERT INTO t1 VALUES (20);
+INSERT INTO t1 VALUES (27);
+SELECT UserId FROM t1 WHERE Userid=22;
UserId
+SELECT UserId FROM t1 WHERE UserId=22 group by Userid;
UserId
+SELECT DISTINCT UserId FROM t1 WHERE UserId=22 group by Userid;
UserId
+SELECT DISTINCT UserId FROM t1 WHERE UserId=22;
UserId
+drop table t1;
+CREATE TABLE t1 (a int(10) unsigned not null primary key,b int(10) unsigned);
+INSERT INTO t1 VALUES (1,1),(2,1);
+CREATE TABLE t2 (a int(10) unsigned not null, key (A));
+INSERT INTO t2 VALUES (1),(2);
+CREATE TABLE t3 (a int(10) unsigned, key(A), b text);
+INSERT INTO t3 VALUES (1,'1'),(2,'2');
+SELECT DISTINCT t3.b FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
b
1
+INSERT INTO t2 values (1),(2),(3);
+INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2');
+explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
table type possible_keys key key_len ref rows Extra
t3 index a a 5 NULL 6 Using index; Using temporary
t2 index a a 4 NULL 5 Using index; Distinct
t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 where used; Distinct
+SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
a
1
+create temporary table t4 select * from t3;
+insert into t3 select * from t4;
+insert into t4 select * from t3;
+insert into t3 select * from t4;
+insert into t4 select * from t3;
+insert into t3 select * from t4;
+insert into t4 select * from t3;
+insert into t3 select * from t4;
+explain select distinct t1.a from t1,t3 where t1.a=t3.a;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary
t3 ref a a 5 t1.a 10 Using index; Distinct
+select distinct t1.a from t1,t3 where t1.a=t3.a;
a
1
2
+select distinct 1 from t1,t3 where t1.a=t3.a;
1
1
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (name varchar(255));
+INSERT INTO t1 VALUES ('aa'),('ab'),('ac'),('ad'),('ae');
+SELECT DISTINCT * FROM t1 LIMIT 2;
name
aa
ab
+SELECT DISTINCT name FROM t1 LIMIT 2;
name
aa
ab
+SELECT DISTINCT 1 FROM t1 LIMIT 2;
1
1
+drop table t1;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(75) DEFAULT '' NOT NULL,
+LINK_ID int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME),
+KEY LINK_ID (LINK_ID)
+);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (1,'Mike',0),(2,'Jack',0),(3,'Bill',0);
+CREATE TABLE t2 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(150) DEFAULT '' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME)
+);
+SELECT DISTINCT
+t2.id AS key_link_id,
+t2.name AS link
+FROM t1
+LEFT JOIN t2 ON t1.link_id=t2.id
+GROUP BY t1.id
+ORDER BY link;
key_link_id link
NULL NULL
+drop table t1,t2;
+create table t1 (
+id int not null,
+name tinytext not null,
+unique (id)
+);
+create table t2 (
+id int not null,
+idx int not null,
+unique (id, idx)
+);
+create table t3 (
+id int not null,
+idx int not null,
+unique (id, idx)
+);
+insert into t1 values (1,'yes'), (2,'no');
+insert into t2 values (1,1);
+insert into t3 values (1,1);
+EXPLAIN
+SELECT DISTINCT
+t1.id
+from
+t1
+straight_join
+t2
+straight_join
+t3
+straight_join
+t1 as j_lj_t2 left join t2 as t2_lj
+on j_lj_t2.id=t2_lj.id
+straight_join
+t1 as j_lj_t3 left join t3 as t3_lj
+on j_lj_t3.id=t3_lj.id
+WHERE
+((t1.id=j_lj_t2.id AND t2_lj.id IS NULL) OR (t1.id=t2.id AND t2.idx=2))
+AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
table type possible_keys key key_len ref rows Extra
t1 index id id 4 NULL 2 Using index; Using temporary
t2 index id id 8 NULL 1 Using index; Distinct
@@ -151,25 +281,71 @@ j_lj_t2 index id id 4 NULL 2 where used; Using index; Distinct
t2_lj index id id 8 NULL 1 where used; Using index; Distinct
j_lj_t3 index id id 4 NULL 2 where used; Using index; Distinct
t3_lj index id id 8 NULL 1 where used; Using index; Distinct
+SELECT DISTINCT
+t1.id
+from
+t1
+straight_join
+t2
+straight_join
+t3
+straight_join
+t1 as j_lj_t2 left join t2 as t2_lj
+on j_lj_t2.id=t2_lj.id
+straight_join
+t1 as j_lj_t3 left join t3 as t3_lj
+on j_lj_t3.id=t3_lj.id
+WHERE
+((t1.id=j_lj_t2.id AND t2_lj.id IS NULL) OR (t1.id=t2.id AND t2.idx=2))
+AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
id
2
+drop table t1,t2,t3;
+drop table if exists t1;
+create table t1 (a int not null, b int not null, t time);
+insert into t1 values (1,1,"00:06:15"),(1,2,"00:06:15"),(1,2,"00:30:15"),(1,3,"00:06:15"),(1,3,"00:30:15");
+select a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
1 00:36:30
+select distinct a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
+create table t2 (a int not null primary key, b int);
+insert into t2 values (1,1),(2,2),(3,3);
+select t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
1 00:36:30
+select distinct t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
+drop table t1,t2;
+create table t1 (a int not null,b char(5), c text);
+insert into t1 (a) values (1),(2),(3),(4),(1),(2),(3),(4);
+select distinct a from t1 group by b,a having a > 2 order by a desc;
a
4
3
+select distinct a,c from t1 group by b,c,a having a > 2 order by a desc;
a c
4 NULL
3 NULL
+drop table t1;
+create table t1 (a char(1), key(a)) type=myisam;
+insert into t1 values('1'),('1');
+select * from t1 where a >= '1';
+a
+1
+1
+select distinct a from t1 order by a desc;
+a
+1
+select distinct a from t1 where a >= '1' order by a desc;
+a
+1
+drop table t1;
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index 741fc6bba85..178c3a8cb4f 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -1,11 +1,48 @@
+drop table if exists t1;
+drop table if exists t1;
+drop table t1;
+Unknown table 't1'
+create table t1(n int);
+insert into t1 values(1);
+create temporary table t1( n int);
+insert into t1 values(2);
+create table t1(n int);
+Table 't1' already exists
+drop table t1;
+select * from t1;
n
1
+drop database if exists mysqltest;
+create database mysqltest;
+drop database if exists mysqltest;
+create database mysqltest;
+create table mysqltest.mysqltest (n int);
+insert into mysqltest.mysqltest values (4);
+select * from mysqltest.mysqltest;
n
4
+drop database if exists mysqltest;
+create database mysqltest;
+drop database mysqltest;
+drop database if exists mysqltest;
+flush tables with read lock;
+create database mysqltest;
+Got one of the listed errors
+unlock tables;
+create database mysqltest;
+show databases;
Database
-foo
mysql
+mysqltest
test
+flush tables with read lock;
+drop database mysqltest;
+Got one of the listed errors
+unlock tables;
+drop database mysqltest;
+show databases;
Database
mysql
test
+drop database mysqltest;
+Can't drop database 'mysqltest'. Database doesn't exist
diff --git a/mysql-test/r/empty_table.result b/mysql-test/r/empty_table.result
index 284ed65ee3b..cea787f4abd 100644
--- a/mysql-test/r/empty_table.result
+++ b/mysql-test/r/empty_table.result
@@ -1,4 +1,10 @@
+drop table if exists t1;
+create table t1 (nr int(5) not null auto_increment,b blob,str char(10), primary key (nr));
+select count(*) from t1;
count(*)
0
+select * from t1;
nr b str
+select * from t1 limit 0;
nr b str
+drop table t1;
diff --git a/mysql-test/r/err000001.result b/mysql-test/r/err000001.result
new file mode 100644
index 00000000000..5afecc6d600
--- /dev/null
+++ b/mysql-test/r/err000001.result
@@ -0,0 +1,25 @@
+drop table if exists t1;
+insert into t1 values(1);
+Table 'test.t1' doesn't exist
+delete from t1;
+Table 'test.t1' doesn't exist
+update t1 set a=1;
+Table 'test.t1' doesn't exist
+create table t1 (a int);
+select count(test.t1.b) from t1;
+Unknown column 'test.t1.b' in 'field list'
+select count(not_existing_database.t1) from t1;
+Unknown table 'not_existing_database' in field list
+select count(not_existing_database.t1.a) from t1;
+Unknown table 'not_existing_database.t1' in field list
+select count(not_existing_database.t1.a) from not_existing_database.t1;
+Got one of the listed errors
+select 1 from t1 order by 2;
+Unknown column '2' in 'order clause'
+select 1 from t1 group by 2;
+Unknown column '2' in 'group statement'
+select 1 from t1 order by t1.b;
+Unknown column 't1.b' in 'order clause'
+select count(*),b from t1;
+Unknown column 'b' in 'field list'
+drop table t1;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 558feb10f84..5b4da25d535 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -1,15 +1,30 @@
+drop table if exists t1;
+create table t1 (id int not null, str char(10), unique(str));
+insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
+select * from t1 where str is null;
id str
1 NULL
2 NULL
+select * from t1 where str="foo";
id str
3 foo
+explain select * from t1 where str is null;
table type possible_keys key key_len ref rows Extra
t1 ref str str 11 const 1 where used
+explain select * from t1 where str="foo";
table type possible_keys key key_len ref rows Extra
t1 const str str 11 const 1
+explain select * from t1 ignore key (str) where str="foo";
table type possible_keys key key_len ref rows Extra
-t1 ALL str NULL NULL NULL 4 where used
+t1 ALL NULL NULL NULL NULL 4 where used
+explain select * from t1 use key (str,str) where str="foo";
table type possible_keys key key_len ref rows Extra
t1 const str str 11 const 1
+explain select * from t1 use key (str,str,foo) where str="foo";
+Key column 'foo' doesn't exist in table
+explain select * from t1 ignore key (str,str,foo) where str="foo";
+Key column 'foo' doesn't exist in table
+drop table t1;
+explain select 1;
Comment
No tables used
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index fca84de710c..7080f2b6145 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -1,6 +1,30 @@
+drop table if exists t1;
+create temporary table t1(n int not null primary key);
+drop table if exists t2;
+create table t2(n int);
+insert into t2 values(3);
+select * from t1;
n
3
+flush tables with read lock;
+drop table t2;
+Table 't2' was locked with a READ lock and can't be updated
+ drop table t2;
+unlock tables;
+drop database if exists mysqltest;
+create database mysqltest;
+create table mysqltest.t1(n int);
+insert into mysqltest.t1 values (23);
+flush tables with read lock;
+ drop database mysqltest;
+select * from mysqltest.t1;
n
23
+unlock tables;
+create table t1 (n int);
+flush tables with read lock;
+insert into t1 values (345);
+select * from t1;
n
345
+drop table t1;
diff --git a/mysql-test/r/foreign_key.result b/mysql-test/r/foreign_key.result
new file mode 100644
index 00000000000..ece53db2e9a
--- /dev/null
+++ b/mysql-test/r/foreign_key.result
@@ -0,0 +1,15 @@
+drop table if exists t1;
+create table t1 (
+a int not null references t2,
+b int not null references t2 (c),
+primary key (a,b),
+foreign key (a) references t3 match full,
+foreign key (a) references t3 match partial,
+foreign key (a,b) references t3 (c,d) on delete no action
+on update no action,
+foreign key (a,b) references t3 (c,d) on update cascade,
+foreign key (a,b) references t3 (c,d) on delete set default,
+foreign key (a,b) references t3 (c,d) on update set null);
+create index a on t1 (a);
+create unique index b on t1 (a,b);
+drop table t1;
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index c39210107ae..b312f5fbc3d 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -1,22 +1,140 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b));
+INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
+('Full-text indexes', 'are called collections'),
+('Only MyISAM tables','support collections'),
+('Function MATCH ... AGAINST()','is used to do a search'),
+('Full-text search in MySQL', 'implements vector space model');
+select * from t1 where MATCH(a,b) AGAINST ("collections");
a b
Only MyISAM tables support collections
Full-text indexes are called collections
+select * from t1 where MATCH(a,b) AGAINST ("indexes");
a b
Full-text indexes are called collections
+select * from t1 where MATCH(a,b) AGAINST ("indexes collections");
a b
Full-text indexes are called collections
Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes");
+a b
+Only MyISAM tables support collections
+Full-text indexes are called collections
+Full-text indexes are called collections
+select * from t1 where MATCH(a,b) AGAINST("support -collections" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+select * from t1 where MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Full-text indexes are called collections
+Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST("support +collections" IN BOOLEAN MODE);
+a b
+Full-text indexes are called collections
+Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST("sear*" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Function MATCH ... AGAINST() is used to do a search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE);
+a b
+Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Function MATCH ... AGAINST() is used to do a search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE);
+a b
+Function MATCH ... AGAINST() is used to do a search
+select *, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1;
+a b x
+MySQL has now support for full-text search 1
+Full-text indexes are called collections 1
+Only MyISAM tables support collections 2
+Function MATCH ... AGAINST() is used to do a search 0
+Full-text search in MySQL implements vector space model 0
+select *, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
+a b x
+MySQL has now support for full-text search 1
+Full-text indexes are called collections 1
+Only MyISAM tables support collections 2
+Function MATCH ... AGAINST() is used to do a search 0
+Full-text search in MySQL implements vector space model 0
+select * from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE);
+a b
+Full-text indexes are called collections
+select * from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE);
+a b
+select * from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE);
+a b
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+select * from t1 where MATCH a AGAINST ("search" IN BOOLEAN MODE);
+a b
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Function MATCH ... AGAINST() is used to do a search
+delete from t1 where a like "MySQL%";
+update t1 set a='some test foobar' where MATCH a,b AGAINST ('model');
+delete from t1 where MATCH(a,b) AGAINST ("indexes");
+select * from t1;
a b
Only MyISAM tables support collections
Function MATCH ... AGAINST() is used to do a search
some test foobar implements vector space model
+drop table t1;
+CREATE TABLE t1 (
+id int(11),
+ticket int(11),
+KEY ti (id),
+KEY tit (ticket)
+);
+INSERT INTO t1 VALUES (2,3),(1,2);
+CREATE TABLE t2 (
+ticket int(11),
+inhalt text,
+KEY tig (ticket),
+fulltext index tix (inhalt)
+);
+INSERT INTO t2 VALUES (1,'foo'),(2,'bar'),(3,'foobar');
+select t1.id FROM t2 as ttxt,t1,t1 as ticket2
+WHERE ticket2.id = ttxt.ticket AND t1.id = ticket2.ticket and
+match(ttxt.inhalt) against ('foobar');
id
+select t1.id FROM t2 as ttxt,t1 INNER JOIN t1 as ticket2 ON
+ticket2.id = ttxt.ticket
+WHERE t1.id = ticket2.ticket and match(ttxt.inhalt) against ('foobar');
id
+INSERT INTO t1 VALUES (3,3);
+select t1.id FROM t2 as ttxt,t1
+INNER JOIN t1 as ticket2 ON ticket2.id = ttxt.ticket
+WHERE t1.id = ticket2.ticket and
+match(ttxt.inhalt) against ('foobar');
id
3
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t2 1 tig 1 ticket A NULL NULL NULL
-t2 1 tix 1 inhalt A NULL 1 NULL FULLTEXT
+show keys from t2;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 1 tig 1 ticket A NULL NULL NULL YES BTREE
+t2 1 tix 1 inhalt A NULL 1 NULL YES FULLTEXT
+show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`ticket` int(11) default NULL,
@@ -24,8 +142,64 @@ t2 CREATE TABLE `t2` (
KEY `tig` (`ticket`),
FULLTEXT KEY `tix` (`inhalt`)
) TYPE=MyISAM
+select * from t2 where MATCH inhalt AGAINST (NULL);
ticket inhalt
+select * from t2 where MATCH inhalt AGAINST ('foobar');
ticket inhalt
3 foobar
+select * from t2 having MATCH inhalt AGAINST ('foobar');
ticket inhalt
3 foobar
+CREATE TABLE t3 (
+ticket int(11),
+inhalt text,
+KEY tig (ticket),
+fulltext index tix (inhalt)
+);
+select * from t2 where MATCH inhalt AGAINST (t2.inhalt);
+Wrong arguments to AGAINST
+select * from t2 where MATCH ticket AGAINST ('foobar');
+Can't find FULLTEXT index matching the column list
+select * from t2,t3 where MATCH (t2.inhalt,t3.inhalt) AGAINST ('foobar');
+Wrong arguments to MATCH
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+id int(11) auto_increment,
+title varchar(100) default '',
+PRIMARY KEY (id),
+KEY ind5 (title),
+FULLTEXT KEY FT1 (title)
+) TYPE=MyISAM;
+insert into t1 (title) values ('this is a test');
+select * from t1 where match title against ('test' in boolean mode);
+id title
+1 this is a test
+update t1 set title='this is A test' where id=1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+update t1 set title='this test once revealed a bug' where id=1;
+select * from t1;
+id title
+1 this test once revealed a bug
+update t1 set title=NULL where id=1;
+drop table t1;
+CREATE TABLE t1 (a int(11), b text, FULLTEXT KEY (b)) TYPE=MyISAM;
+insert into t1 values (1,"I wonder why the fulltext index doesnt work?");
+SELECT * from t1 where MATCH (b) AGAINST ('apples');
+a b
+insert into t1 values (2,"fullaaa fullzzz");
+select * from t1 where match b against ('full*' in boolean mode);
+a b
+2 fullaaa fullzzz
+1 I wonder why the fulltext index doesnt work?
+drop table t1;
+CREATE TABLE t1 ( id int(11) NOT NULL auto_increment primary key, mytext text NOT NULL, FULLTEXT KEY mytext (mytext)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'my small mouse'),(2,'la-la-la'),(3,'It is so funny'),(4,'MySQL Tutorial');
+select 8 from t1;
+8
+8
+8
+8
+8
+drop table t1;
diff --git a/mysql-test/r/fulltext_cache.result b/mysql-test/r/fulltext_cache.result
index a580437b0ce..c489bdefeb8 100644
--- a/mysql-test/r/fulltext_cache.result
+++ b/mysql-test/r/fulltext_cache.result
@@ -1,5 +1,30 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL auto_increment,
+q varchar(255) default NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (1,'aaaaaaaaa dsaass de');
+INSERT INTO t1 VALUES (2,'ssde df s fsda sad er');
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL auto_increment,
+id2 int(10) unsigned default NULL,
+item varchar(255) default NULL,
+PRIMARY KEY (id),
+FULLTEXT KEY item(item)
+);
+INSERT INTO t2 VALUES (1,1,'sushi');
+INSERT INTO t2 VALUES (2,1,'Bolo de Chocolate');
+INSERT INTO t2 VALUES (3,1,'Feijoada');
+INSERT INTO t2 VALUES (4,1,'Mousse de Chocolate');
+INSERT INTO t2 VALUES (5,2,'um copo de Vodka');
+INSERT INTO t2 VALUES (6,2,'um chocolate Snickers');
+INSERT INTO t2 VALUES (7,1,'Bife');
+INSERT INTO t2 VALUES (8,1,'Pizza de Salmao');
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x
-aaaaaaaaa dsaass de sushi 1 1.92378665219675
+aaaaaaaaa dsaass de sushi 1 1.92378664016724
aaaaaaaaa dsaass de Bolo de Chocolate 2 0
aaaaaaaaa dsaass de Feijoada 3 0
aaaaaaaaa dsaass de Mousse de Chocolate 4 0
@@ -7,8 +32,10 @@ ssde df s fsda sad er um copo de Vodka 5 0
ssde df s fsda sad er um chocolate Snickers 6 0
aaaaaaaaa dsaass de Bife 7 0
aaaaaaaaa dsaass de Pizza de Salmao 8 0
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x
-aaaaaaaaa dsaass de sushi 1 1.92378665219675
+aaaaaaaaa dsaass de sushi 1 1
aaaaaaaaa dsaass de Bolo de Chocolate 2 0
aaaaaaaaa dsaass de Feijoada 3 0
aaaaaaaaa dsaass de Mousse de Chocolate 4 0
@@ -16,3 +43,26 @@ ssde df s fsda sad er um copo de Vodka 5 0
ssde df s fsda sad er um chocolate Snickers 6 0
aaaaaaaaa dsaass de Bife 7 0
aaaaaaaaa dsaass de Pizza de Salmao 8 0
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+q item id x
+aaaaaaaaa dsaass de sushi 1 1.92378664016724
+aaaaaaaaa dsaass de Bolo de Chocolate 2 0
+aaaaaaaaa dsaass de Feijoada 3 0
+aaaaaaaaa dsaass de Mousse de Chocolate 4 0
+ssde df s fsda sad er um copo de Vodka 5 0
+ssde df s fsda sad er um chocolate Snickers 6 0
+aaaaaaaaa dsaass de Bife 7 0
+aaaaaaaaa dsaass de Pizza de Salmao 8 0
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+q item id x
+aaaaaaaaa dsaass de sushi 1 1
+aaaaaaaaa dsaass de Bolo de Chocolate 2 0
+aaaaaaaaa dsaass de Feijoada 3 0
+aaaaaaaaa dsaass de Mousse de Chocolate 4 0
+ssde df s fsda sad er um copo de Vodka 5 0
+ssde df s fsda sad er um chocolate Snickers 6 0
+aaaaaaaaa dsaass de Bife 7 0
+aaaaaaaaa dsaass de Pizza de Salmao 8 0
+drop table t1, t2;
diff --git a/mysql-test/r/fulltext_distinct.result b/mysql-test/r/fulltext_distinct.result
new file mode 100644
index 00000000000..abb4929d0ec
--- /dev/null
+++ b/mysql-test/r/fulltext_distinct.result
@@ -0,0 +1,43 @@
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+id mediumint unsigned NOT NULL auto_increment,
+tag char(6) NOT NULL default '',
+value text NOT NULL default '',
+PRIMARY KEY (id),
+KEY kt(tag),
+KEY kv(value(15)),
+FULLTEXT KEY kvf(value)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+id_t2 mediumint unsigned NOT NULL default '0',
+id_t1 mediumint unsigned NOT NULL default '0',
+field_number tinyint unsigned NOT NULL default '0',
+PRIMARY KEY (id_t2,id_t1,field_number),
+KEY id_t1(id_t1)
+) TYPE=MyISAM;
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar111');
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar222');
+INSERT INTO t1 (tag,value) VALUES ('bar345','baz333 ar');
+INSERT INTO t2 VALUES (2231626,64280,0);
+INSERT INTO t2 VALUES (2231626,64281,0);
+INSERT INTO t2 VALUES (12346, 3, 1);
+SELECT * FROM t1;
+id tag value
+1 foo123 bar111
+2 foo123 bar222
+3 bar345 baz333 ar
+SELECT * FROM t2;
+id_t2 id_t1 field_number
+12346 3 1
+2231626 64280 0
+2231626 64281 0
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333') AND t1.id = t2.id_t1;
+id_t2
+12346
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333' IN BOOLEAN MODE)
+AND t1.id = t2.id_t1;
+id_t2
+12346
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/fulltext_left_join.result b/mysql-test/r/fulltext_left_join.result
index 04244e309e5..9f2ba6a5947 100644
--- a/mysql-test/r/fulltext_left_join.result
+++ b/mysql-test/r/fulltext_left_join.result
@@ -1,5 +1,32 @@
+CREATE TABLE t1 (
+id VARCHAR(255) NOT NULL PRIMARY KEY,
+sujet VARCHAR(255),
+motsclefs TEXT,
+texte MEDIUMTEXT,
+FULLTEXT(sujet, motsclefs, texte)
+);
+INSERT INTO t1 VALUES('123','toto','essai','test');
+INSERT INTO t1 VALUES('456','droit','penal','lawyer');
+INSERT INTO t1 VALUES('789','aaaaa','bbbbb','cccccc');
+CREATE TABLE t2 (
+id VARCHAR(255) NOT NULL,
+author VARCHAR(255) NOT NULL
+);
+INSERT INTO t2 VALUES('123', 'moi');
+INSERT INTO t2 VALUES('123', 'lui');
+INSERT INTO t2 VALUES('456', 'lui');
+select match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
+from t1 left join t2 on t2.id=t1.id;
match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
0
0
-0.67003110026735
+0.67003107070923
0
+select match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
+from t1 left join t2 on t2.id=t1.id;
+match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
+0
+0
+1
+0
+drop table t1, t2;
diff --git a/mysql-test/r/fulltext_multi.result b/mysql-test/r/fulltext_multi.result
index d78d88172b5..72b7102fd3f 100644
--- a/mysql-test/r/fulltext_multi.result
+++ b/mysql-test/r/fulltext_multi.result
@@ -1,12 +1,30 @@
+use test;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a int(11) NOT NULL auto_increment,
+b text,
+c varchar(254) default NULL,
+PRIMARY KEY (a),
+FULLTEXT KEY bb(b),
+FULLTEXT KEY cc(c),
+FULLTEXT KEY a(b,c)
+);
+INSERT INTO t1 VALUES (1,'lala lolo lili','oooo aaaa pppp');
+INSERT INTO t1 VALUES (2,'asdf fdsa','lkjh fghj');
+INSERT INTO t1 VALUES (3,'qpwoei','zmxnvb');
+SELECT a, MATCH b AGAINST ('lala lkjh') FROM t1;
a MATCH b AGAINST ('lala lkjh')
-1 0.67003110026735
+1 0.67003107070923
2 0
3 0
+SELECT a, MATCH c AGAINST ('lala lkjh') FROM t1;
a MATCH c AGAINST ('lala lkjh')
1 0
-2 0.67756324121582
+2 0.67756325006485
3 0
+SELECT a, MATCH b,c AGAINST ('lala lkjh') FROM t1;
a MATCH b,c AGAINST ('lala lkjh')
-1 0.64840710366884
-2 0.66266459031789
+1 0.64840710163116
+2 0.66266459226608
3 0
+drop table t1;
diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result
index 3ac5285151b..8d88b8d6ebf 100644
--- a/mysql-test/r/fulltext_order_by.result
+++ b/mysql-test/r/fulltext_order_by.result
@@ -1,19 +1,66 @@
+use test;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a INT AUTO_INCREMENT PRIMARY KEY,
+message CHAR(20),
+FULLTEXT(message)
+) comment = 'original testcase by sroussey@network54.com';
+INSERT INTO t1 (message) VALUES ("Testing"),("table"),("testbug"),
+("steve"),("is"),("cool"),("steve is cool");
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve');
a MATCH (message) AGAINST ('steve')
-4 0.90587321329654
-7 0.89568988462614
+4 0.90587323904037
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve');
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+4 1
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
a MATCH (message) AGAINST ('steve')
-4 0.90587321329654
-7 0.89568988462614
+4 0.90587323904037
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+4 1
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
a MATCH (message) AGAINST ('steve')
-7 0.89568988462614
-4 0.90587321329654
+4 0.90587323904037
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a;
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+4 1
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
a MATCH (message) AGAINST ('steve')
-7 0.89568988462614
+7 0.89568990468979
+4 0.90587323904037
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a DESC;
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+7 1
+4 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
+a MATCH (message) AGAINST ('steve')
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel;
+a rel
+1 0
+2 0
+3 0
+5 0
+6 0
+7 0.89568990468979
+4 0.90587323904037
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
a rel
1 0
2 0
3 0
5 0
6 0
-7 0.89568988462614
-4 0.90587321329654
+4 1
+7 1
+drop table t1;
diff --git a/mysql-test/r/fulltext_update.result b/mysql-test/r/fulltext_update.result
index 77ee76ad30d..5d3f95b318c 100644
--- a/mysql-test/r/fulltext_update.result
+++ b/mysql-test/r/fulltext_update.result
@@ -1,2 +1,22 @@
+drop table if exists test;
+CREATE TABLE test (
+gnr INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+url VARCHAR(80) DEFAULT '' NOT NULL,
+shortdesc VARCHAR(200) DEFAULT '' NOT NULL,
+longdesc text DEFAULT '' NOT NULL,
+description VARCHAR(80) DEFAULT '' NOT NULL,
+name VARCHAR(80) DEFAULT '' NOT NULL,
+FULLTEXT(url,description,shortdesc,longdesc),
+PRIMARY KEY(gnr)
+);
+insert into test (url,shortdesc,longdesc,description,name) VALUES
+("http:/test.at", "kurz", "lang","desc", "name");
+insert into test (url,shortdesc,longdesc,description,name) VALUES
+("http:/test.at", "kurz", "","desc", "name");
+update test set url='test', description='ddd', name='nam' where gnr=2;
+update test set url='test', shortdesc='ggg', longdesc='mmm',
+description='ddd', name='nam' where gnr=2;
+check table test;
Table Op Msg_type Msg_text
test.test check status OK
+drop table test;
diff --git a/mysql-test/r/fulltext_var.result b/mysql-test/r/fulltext_var.result
new file mode 100644
index 00000000000..eb71e87538d
--- /dev/null
+++ b/mysql-test/r/fulltext_var.result
@@ -0,0 +1,6 @@
+show variables like "ft\_%";
+Variable_name Value
+ft_min_word_len 4
+ft_max_word_len 254
+ft_max_word_len_for_sort 20
+ft_boolean_syntax + -><()~*:""&|
diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result
index 75ee8f2bf79..17afd49b54c 100644
--- a/mysql-test/r/func_concat.result
+++ b/mysql-test/r/func_concat.result
@@ -1,13 +1,28 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL );
+INSERT INTO t1 VALUES (1413006,'idlfmv'),
+(1413065,'smpsfz'),(1413127,'sljrhx'),(1413304,'qerfnd');
+SELECT number, alpha, CONCAT_WS('<---->',number,alpha) AS new
+FROM t1 GROUP BY number;
number alpha new
1413006 idlfmv 1413006<---->idlfmv
1413065 smpsfz 1413065<---->smpsfz
1413127 sljrhx 1413127<---->sljrhx
1413304 qerfnd 1413304<---->qerfnd
+SELECT CONCAT_WS('<---->',number,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
new
1413006<---->idlfmv
+SELECT number, alpha, CONCAT_WS('<->',number,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
number alpha new
1413006 idlfmv 1413006<->idlfmv
+SELECT number, alpha, CONCAT_WS('-',number,alpha,alpha,alpha,alpha,alpha,alpha,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
number alpha new
1413006 idlfmv 1413006-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv
+SELECT number, alpha, CONCAT_WS('<------------------>',number,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
number alpha new
1413006 idlfmv 1413006<------------------>idlfmv
+drop table t1;
diff --git a/mysql-test/r/func_crypt.result b/mysql-test/r/func_crypt.result
index 021989add8d..cf464ec21b2 100644
--- a/mysql-test/r/func_crypt.result
+++ b/mysql-test/r/func_crypt.result
@@ -1,2 +1,6 @@
+select length(encrypt('foo', 'ff')) <> 0;
length(encrypt('foo', 'ff')) <> 0
1
+select password('test'),length(encrypt('test')),encrypt('test','aa');
+password('test') length(encrypt('test')) encrypt('test','aa')
+378b243e220ca493 13 aaqPiZY5xR5l.
diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result
index 3bc0fb1aff3..acdf2c5d7be 100644
--- a/mysql-test/r/func_date_add.result
+++ b/mysql-test/r/func_date_add.result
@@ -1,12 +1,47 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+visitor_id int(10) unsigned DEFAULT '0' NOT NULL,
+group_id int(10) unsigned DEFAULT '0' NOT NULL,
+hits int(10) unsigned DEFAULT '0' NOT NULL,
+sessions int(10) unsigned DEFAULT '0' NOT NULL,
+ts timestamp(14),
+PRIMARY KEY (visitor_id,group_id)
+)/*! type=MyISAM */;
+INSERT INTO t1 VALUES (465931136,7,2,2,20000318160952);
+INSERT INTO t1 VALUES (173865424,2,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,8,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,39,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,7,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,3,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,6,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,60,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,1502,2,2,20000318233615);
+INSERT INTO t1 VALUES (48985536,2,2,2,20000319013932);
+INSERT INTO t1 VALUES (48985536,8,2,2,20000319013932);
+INSERT INTO t1 VALUES (48985536,39,2,2,20000319013932);
+INSERT INTO t1 VALUES (48985536,7,2,2,20000319013932);
+INSERT INTO t1 VALUES (465931136,3,2,2,20000318160951);
+INSERT INTO t1 VALUES (465931136,119,1,1,20000318160953);
+INSERT INTO t1 VALUES (465931136,2,1,1,20000318160950);
+INSERT INTO t1 VALUES (465931136,8,1,1,20000318160950);
+INSERT INTO t1 VALUES (465931136,39,1,1,20000318160950);
+INSERT INTO t1 VALUES (1092858576,14,1,1,20000319013445);
+INSERT INTO t1 VALUES (357917728,3,2,2,20000319145026);
+INSERT INTO t1 VALUES (357917728,7,2,2,20000319145027);
+select visitor_id,max(ts) as mts from t1 group by visitor_id
+having mts < DATE_SUB(NOW(),INTERVAL 3 MONTH);
visitor_id mts
48985536 20000319013932
173865424 20000318233615
357917728 20000319145027
465931136 20000318160953
1092858576 20000319013445
+select visitor_id,max(ts) as mts from t1 group by visitor_id
+having DATE_ADD(mts,INTERVAL 3 MONTH) < NOW();
visitor_id mts
48985536 20000319013932
173865424 20000318233615
357917728 20000319145027
465931136 20000318160953
1092858576 20000319013445
+drop table t1;
diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result
new file mode 100644
index 00000000000..39c734999b2
--- /dev/null
+++ b/mysql-test/r/func_encrypt.result
@@ -0,0 +1,136 @@
+drop table if exists t1;
+create table t1 (x blob);
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('a','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','a'));
+insert into t1 values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab'));
+insert into t1 values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc'));
+insert into t1 values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd'));
+insert into t1 values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde'));
+insert into t1 values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef'));
+insert into t1 values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg'));
+insert into t1 values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh'));
+insert into t1 values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi'));
+insert into t1 values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij'));
+insert into t1 values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('brown dog','sabakala'));
+insert into t1 values (des_encrypt('dog','sabakala'));
+insert into t1 values (des_encrypt('dog!','sabakala'));
+insert into t1 values (des_encrypt('dog!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!!','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+select hex(x), hex(des_decrypt(x,'sabakala')) from t1;
+hex(x) hex(des_decrypt(x,'sabakala'))
+FFA185A4656D113445E31D7A5B31BB57671A4CA9E21E63FE5D9C801E0CC7AA6190C13E269C2AE8D8060D3FB3FEA94FEC7FB006B9DCAC3E3E41 NULL
+FFC620C3B84E926A54 NULL
+FFA4F77D4220A16C980AF7CB576F8DC0A864F357825C16F329F24F66EBA775765B7C1538B90970740F853B556AEBD35AC31B962EA9B12B5AD4 NULL
+FFACFF5921BB876A90 NULL
+FFA6F18760E7CC5A4C325244B8486F692AAA11D229AF9ED4E4C9D56D7C0278C0DDA58F73E15E2B5F6C1DDD19B22B8071C454C930585449AAEB NULL
+FF3736DFEDC4B765F4 NULL
+FF598681EA5F03CD6D6AEA2B118DF4885DD78BECDFB012BBB05386E436DC403D3CB9DE3BE8D5D3BB7FD90A1F9F9A3E055BB3B4FD3F6A869473 NULL
+FF15B8B5952D630CAE NULL
+FF11EE3A400685226B76D5EC567681FA90247CE3C9DBE43341311C22F74562B1199957D80E300737791F6345BBC61AE03F28F52E5A6DCC78B2 NULL
+FF0A832AE10DC85483 NULL
+FF6F5C0BF4C5F899B4E7C091D9B1F1E92A7623B651B150CA3E7F420B4DD316D2C1BF76FCF9F9A046C000A9E21C106591E8C1930201B1750269 NULL
+FFA08D5FB849A9FC90 NULL
+FFF7331312FE153A39B1EC0D65BC1D3A0B6FCD49DA8C95D6161F53B11D297BAE142BCA6B9492DAE9A02AF455F16CA2C1CF4E1AD17297E947E2 NULL
+FFDEE60A938478E059 NULL
+FF95A729E73D5D87416A53055029E8CAA95B4F7B49F3D2D821A95D1FCE70F4B7A3226077176723F3DCC0A44D3B2EE9EFBC4D31AA87C948916C NULL
+FF1C78557F542A1FDC91943761B2EED14F NULL
+FF1E35B0775EEE512544A75BDAF58EA1655F5C899D3C5191A47263E2D11C3E688F662AB79F66D3B1DF9C75BD869EB8E04FDAE85719CB573A43 NULL
+FF1C78557F542A1FDCDC4182B5314185E5 NULL
+FF783123DCB36F98A51C39A560C92E129F1DDEEAB170825406A61260FBFBBFB0F2E48DB3282588A975C9C71E0EACA71A2B642A8C9C2E921A9F NULL
+FF1C78557F542A1FDCAC4B1B6B47206306 NULL
+FF6D9B450837017D06CA1F1C9A0E700D03DEF06A4F954527A961CA805F70320E9F3F0007636B80768A253A5F7ADABC18B78F1A2FA560CC0B21 NULL
+FF1C78557F542A1FDCE9038BD99DD43F2E NULL
+FF23FD03BA7548DD0957EBA7A8FBF7A18589762F3913E9A935BDA72F6F28202DC64572E0D633A54EA55BFD2C749E408C8632CCE36A7AE00619 NULL
+FFD8DD3C4ABCB02FCDFE1383ECC0F61E7D02CD3BA72BBAEA26384D14835796501B3DC9A2F7EC2FC1633BDA6D56464536FE12010049C53A1991 54686520717569636B2072656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FFACC5C5479575CBCA518B05778139B1BFC10F07299C98D04F580BC2F816828722D65A89C1831BD29DA626D319813BD374 717569636B2072656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF128D5517241DEEC631ABD2A47FA66E57930001417F18204328B0B2CB13F7AD2F50B8336EFAE7DE21 72656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF7CF971283B4DC2D050B3DB22684737B74B5B1CF12CF2FAC5A5995A298505F56D82BBFB9FC3E70059 666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67
+FFE8CB7FD80E6262C5FEB042A2DCC73B699CEEDCA6DC4458A0 6F76657220746865206C617A792062726F776E20646F67
+FFA29334D7CDB1B403DF3EB992067DD524C7D568E8D98EBFE5 746865206C617A792062726F776E20646F67
+FF4F0C5858FE2358D400E38831D5577C85 6C617A792062726F776E20646F67
+FFB370CD6BAFD1CB95974D21DCCA2DD9D7 62726F776E20646F67
+FF8F7777B28C7A459A 646F67
+FF75213A4D7D01D715 646F6721
+FF2DCAF574B173FB4D 646F672121
+FFFA775787BE776B15 646F67212121
+FF3FC2E42D7C840905 646F6721212121
+FF9723312D26D9E6DA01D01A784A64DB9D 646F672121212121
+FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67
+select des_decrypt(x,'sabakala') as s from t1 having s like '%dog%';
+s
+The quick red fox jumped over the lazy brown dog
+quick red fox jumped over the lazy brown dog
+red fox jumped over the lazy brown dog
+fox jumped over the lazy brown dog
+jumped over the lazy brown dog
+over the lazy brown dog
+the lazy brown dog
+lazy brown dog
+brown dog
+dog
+dog!
+dog!!
+dog!!!
+dog!!!!
+dog!!!!!
+jumped over the lazy brown dog
+jumped over the lazy brown dog
+drop table t1;
+select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello"));
+hex(des_encrypt("hello")) des_decrypt(des_encrypt("hello"))
+85D6DC8859F9759BBB hello
+select des_decrypt(des_encrypt("hello",4));
+des_decrypt(des_encrypt("hello",4))
+hello
+select des_decrypt(des_encrypt("hello",'test'),'test');
+des_decrypt(des_encrypt("hello",'test'),'test')
+hello
+select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password'));
+hex(des_encrypt("hello")) hex(des_encrypt("hello",5)) hex(des_encrypt("hello",'default_password'))
+85D6DC8859F9759BBB 85D6DC8859F9759BBB FFD6DC8859F9759BBB
+select des_decrypt(des_encrypt("hello"),'default_password');
+des_decrypt(des_encrypt("hello"),'default_password')
+hello
+select des_decrypt(des_encrypt("hello",4),'password4');
+des_decrypt(des_encrypt("hello",4),'password4')
+hello
+SET @a=des_decrypt(des_encrypt("hello"));
+flush des_key_file;
+select @a = des_decrypt(des_encrypt("hello"));
+@a = des_decrypt(des_encrypt("hello"))
+1
+select hex("hello");
+hex("hello")
+68656C6C6F
+select hex(des_decrypt(des_encrypt("hello",4),'password2'));
+hex(des_decrypt(des_encrypt("hello",4),'password2'))
+NULL
+select hex(des_decrypt(des_encrypt("hello","hidden")));
+hex(des_decrypt(des_encrypt("hello","hidden")))
+NULL
diff --git a/mysql-test/r/func_equal.result b/mysql-test/r/func_equal.result
index 6e2933641aa..32a911eedf8 100644
--- a/mysql-test/r/func_equal.result
+++ b/mysql-test/r/func_equal.result
@@ -1,15 +1,29 @@
+select 0<=>0,0.0<=>0.0,"A"<=>"A",NULL<=>NULL;
0<=>0 0.0<=>0.0 "A"<=>"A" NULL<=>NULL
1 1 1 1
+select 1<=>0,0<=>NULL,NULL<=>0;
1<=>0 0<=>NULL NULL<=>0
0 0 0
+select 1.0<=>0.0,0.0<=>NULL,NULL<=>0.0;
1.0<=>0.0 0.0<=>NULL NULL<=>0.0
0 0 0
+select "A"<=>"B","A"<=>NULL,NULL<=>"A";
"A"<=>"B" "A"<=>NULL NULL<=>"A"
0 0 0
+drop table if exists t1,t2;
+create table t1 (id int, value int);
+create table t2 (id int, value int);
+insert into t1 values (1,null);
+insert into t2 values (1,null);
+select t1.*, t2.*, t1.value<=>t2.value from t1, t2 where t1.id=t2.id and t1.id=1;
id value id value t1.value<=>t2.value
1 NULL 1 NULL 1
+select * from t1 where id <=>id;
id value
1 NULL
+select * from t1 where value <=> value;
id value
1 NULL
+select * from t1 where id <=> value or value<=>id;
id value
+drop table t1,t2;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index ea9a06123ae..2d24b8ffd4e 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -1,3 +1,11 @@
+create table t1 (grp int, a bigint unsigned, c char(10) not null);
+insert into t1 values (1,1,"a");
+insert into t1 values (2,2,"b");
+insert into t1 values (2,3,"c");
+insert into t1 values (3,4,"E");
+insert into t1 values (3,5,"C");
+insert into t1 values (3,6,"D");
+select a,c,sum(a) from t1 group by a;
a c sum(a)
1 a 1
2 b 2
@@ -5,82 +13,140 @@ a c sum(a)
4 E 4
5 C 5
6 D 6
+select a,c,sum(a) from t1 where a > 10 group by a;
a c sum(a)
+select sum(a) from t1 where a > 10;
sum(a)
NULL
+select a from t1 order by rand(10);
a
+2
+6
1
3
-6
5
-2
4
+select distinct a from t1 order by rand(10);
a
+2
+6
1
3
-6
5
-2
4
+select count(distinct a),count(distinct grp) from t1;
count(distinct a) count(distinct grp)
6 3
+insert into t1 values (null,null,'');
+select count(distinct a),count(distinct grp) from t1;
count(distinct a) count(distinct grp)
6 3
+select sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1;
sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
21 6 3.5000 1.7078 7 0 1 6 E
+select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
grp sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
NULL 0 0 NULL NULL 0 0 NULL NULL
1 1 1 1.0000 0.0000 1 1 1 1 a a
2 5 2 2.5000 0.5000 3 2 2 3 b c
3 15 3 5.0000 0.8165 7 4 4 6 C E
+select grp, sum(a)+count(a)+avg(a)+std(a)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum from t1 group by grp;
grp sum
NULL NULL
1 7
2 20
3 44.816496580928
+create table t2 (grp int, a bigint unsigned, c char(10));
+insert into t2 select grp,max(a)+max(grp),max(c) from t1 group by grp;
+replace into t2 select grp, a, c from t1 limit 2,1;
+select * from t2;
grp a c
NULL NULL
1 2 a
2 5 c
3 9 E
2 3 c
+drop table t1,t2;
+CREATE TABLE t1 (id int(11),value1 float(10,2));
+INSERT INTO t1 VALUES (1,0.00),(1,1.00), (1,2.00), (2,10.00), (2,11.00), (2,12.00);
+CREATE TABLE t2 (id int(11),name char(20));
+INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two');
+select id, avg(value1), std(value1) from t1 group by id;
id avg(value1) std(value1)
1 1.000000 0.816497
2 11.000000 0.816497
+select name, avg(value1), std(value1) from t1, t2 where t1.id = t2.id group by t1.id;
name avg(value1) std(value1)
Set One 1.000000 0.816497
Set Two 11.000000 0.816497
+drop table t1,t2;
+create table t1 (id int not null);
+create table t2 (id int not null,rating int null);
+insert into t1 values(1),(2),(3);
+insert into t2 values(1, 3),(2, NULL),(2, NULL),(3, 2),(3, NULL);
+select t1.id, avg(rating) from t1 left join t2 on ( t1.id = t2.id ) group by t1.id;
id avg(rating)
1 3.0000
2 NULL
3 2.0000
+drop table t1,t2;
+create table t1 (a smallint(6) primary key, c char(10), b text);
+INSERT INTO t1 VALUES (1,'1','1');
+INSERT INTO t1 VALUES (2,'2','2');
+INSERT INTO t1 VALUES (4,'4','4');
+select count(*) from t1;
count(*)
3
+select count(*) from t1 where a = 1;
count(*)
1
+select count(*) from t1 where a = 100;
count(*)
0
+select count(*) from t1 where a >= 10;
count(*)
0
+select count(a) from t1 where a = 1;
count(a)
1
+select count(a) from t1 where a = 100;
count(a)
0
+select count(a) from t1 where a >= 10;
count(a)
0
+select count(b) from t1 where b >= 2;
count(b)
2
+select count(b) from t1 where b >= 10;
count(b)
0
+select count(c) from t1 where c = 10;
count(c)
0
+drop table t1;
+CREATE TABLE t1 (d DATETIME, i INT);
+INSERT INTO t1 VALUES (NOW(), 1);
+SELECT COUNT(i), i, COUNT(i)*i FROM t1 GROUP BY i;
COUNT(i) i COUNT(i)*i
1 1 1
+SELECT COUNT(i), (i+0), COUNT(i)*(i+0) FROM t1 GROUP BY i;
COUNT(i) (i+0) COUNT(i)*(i+0)
1 1 1
+DROP TABLE t1;
+create table t1 (
+num float(5,2),
+user char(20)
+);
+insert into t1 values (10.3,'nem'),(20.53,'monty'),(30.23,'sinisa');
+insert into t1 values (30.13,'nem'),(20.98,'monty'),(10.45,'sinisa');
+insert into t1 values (5.2,'nem'),(8.64,'monty'),(11.12,'sinisa');
+select sum(num) from t1;
sum(num)
147.58
+select sum(num) from t1 group by user;
sum(num)
50.15
45.63
51.80
+drop table t1;
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index 85c4007f63c..16fb0358d51 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -1,5 +1,10 @@
+drop table if exists t1;
+select IF(0,"ERROR","this"),IF(1,"is","ERROR"),IF(NULL,"ERROR","a"),IF(1,2,3)|0,IF(1,2.0,3.0)+0 ;
IF(0,"ERROR","this") IF(1,"is","ERROR") IF(NULL,"ERROR","a") IF(1,2,3)|0 IF(1,2.0,3.0)+0
this is a 2 2.0
+CREATE TABLE t1 (st varchar(255) NOT NULL, u int(11) NOT NULL) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('a',1),('A',1),('aa',1),('AA',1),('a',1),('aaa',0),('BBB',0);
+select if(1,st,st) s from t1 order by s;
s
a
A
@@ -8,6 +13,7 @@ aa
AA
aaa
BBB
+select if(u=1,st,st) s from t1 order by s;
s
a
A
@@ -16,6 +22,7 @@ aa
AA
aaa
BBB
+select if(u=1,binary st,st) s from t1 order by s;
s
A
AA
@@ -24,6 +31,7 @@ a
a
aa
aaa
+select if(u=1,st,binary st) s from t1 where st like "%a%" order by s;
s
A
AA
@@ -31,5 +39,10 @@ a
a
aa
aaa
+drop table t1;
+create table t1 (num double(12,2));
+insert into t1 values (144.54);
+select sum(if(num is null,0.00,num)) from t1;
sum(if(num is null,0.00,num))
144.54
+drop table t1;
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index f201d371876..8c991dee8d8 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -1,14 +1,27 @@
+CREATE TABLE t1 (field char(1));
+INSERT INTO t1 VALUES ('A'),(NULL);
+SELECT * from t1 WHERE field IN (NULL);
field
+SELECT * from t1 WHERE field NOT IN (NULL);
field
A
+SELECT * from t1 where field = field;
field
A
+SELECT * from t1 where field <=> field;
field
A
NULL
+DELETE FROM t1 WHERE field NOT IN (NULL);
+SELECT * FROM t1;
field
NULL
+drop table t1;
+create table t1 (id int(10) primary key);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+select * from t1 where id in (2,5,9);
id
2
5
9
+drop table t1;
diff --git a/mysql-test/r/func_isnull.result b/mysql-test/r/func_isnull.result
index deaeaaf71c9..20ddc87ee78 100644
--- a/mysql-test/r/func_isnull.result
+++ b/mysql-test/r/func_isnull.result
@@ -1 +1,7 @@
+drop table if exists t1;
+create table t1 (id int auto_increment primary key not null, mydate date not null);
+insert into t1 values (0,"2002-05-01"),(0,"2002-05-01"),(0,"2002-05-01");
+flush tables;
+select * from t1 where isnull(to_days(mydate));
id mydate
+drop table t1;
diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result
index 78bede19762..c2085ba12da 100644
--- a/mysql-test/r/func_like.result
+++ b/mysql-test/r/func_like.result
@@ -1,7 +1,29 @@
+drop table if exists t1;
+create table t1 (a varchar(10), key(a));
+insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
+select * from t1 where a like "abc%";
a
abc
abcd
+select * from t1 where a like "ABC%";
+a
+abc
+abcd
+select * from t1 where a like "test%";
a
test
+select * from t1 where a like "te_t";
a
test
+select * from t1 where a like "%a%";
+a
+a
+abc
+abcd
+select * from t1 where a like "%abcd%";
+a
+abcd
+select * from t1 where a like "%abc\d%";
+a
+abcd
+drop table t1;
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index e2723311682..f067d1f651e 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -1,22 +1,33 @@
+select floor(5.5),floor(-5.5);
floor(5.5) floor(-5.5)
5 -6
+select ceiling(5.5),ceiling(-5.5);
ceiling(5.5) ceiling(-5.5)
6 -5
+select truncate(52.64,1),truncate(52.64,2),truncate(52.64,-1),truncate(52.64,-2), truncate(-52.64,1),truncate(-52.64,-1);
truncate(52.64,1) truncate(52.64,2) truncate(52.64,-1) truncate(52.64,-2) truncate(-52.64,1) truncate(-52.64,-1)
52.6 52.64 50 0 -52.6 -50
+select round(5.5),round(-5.5);
round(5.5) round(-5.5)
6 -6
+select round(5.64,1),round(5.64,2),round(5.64,-1),round(5.64,-2);
round(5.64,1) round(5.64,2) round(5.64,-1) round(5.64,-2)
5.6 5.64 10 0
+select abs(-10), sign(-5), sign(5), sign(0);
abs(-10) sign(-5) sign(5) sign(0)
10 -1 1 0
+select log(exp(10)),exp(log(sqrt(10))*2);
log(exp(10)) exp(log(sqrt(10))*2)
10.000000 10.000000
+select pow(10,log10(10)),power(2,4);
pow(10,log10(10)) power(2,4)
10.000000 16.000000
+select rand(999999),rand();
rand(999999) rand()
-0.18435012473199 0.76373626176616
+0.014231365187309 0.8078568166195
+select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1);
PI() sin(pi()/2) cos(pi()/2) abs(tan(pi())) cot(1) asin(1) acos(0) atan(1)
3.141593 1.000000 0.000000 0.000000 0.64209262 1.570796 1.570796 0.785398
+select degrees(pi()),radians(360);
degrees(pi()) radians(360)
180 6.2831853071796
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 5448127548b..4eed80c4cc9 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -1,8 +1,12 @@
+select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.5555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
format(1.5555,0) format(123.5555,1) format(1234.5555,2) format(12345.5555,3) format(123456.5555,4) format(1234567.5555,5) format("12345.2399",2)
2 123.6 1,234.56 12,345.556 123,456.5555 1,234,567.55550 12,345.24
+select inet_ntoa(inet_aton("255.255.255.255.255.255.255.255"));
inet_ntoa(inet_aton("255.255.255.255.255.255.255.255"))
-255.255.255.255.255.255.255.255
+NULL
+select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255");
inet_aton("255.255.255.255.255") inet_aton("255.255.1.255") inet_aton("0.1.255")
1099511627775 4294902271 511
+select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511);
inet_ntoa(1099511627775) inet_ntoa(4294902271) inet_ntoa(511)
-255.255.255.255.255 255.255.1.255 0.0.1.255
+NULL 255.255.1.255 0.0.1.255
diff --git a/mysql-test/r/func_op.result b/mysql-test/r/func_op.result
index b14f575c998..9f49b5809df 100644
--- a/mysql-test/r/func_op.result
+++ b/mysql-test/r/func_op.result
@@ -1,6 +1,9 @@
+select 1+1,1-1,1+1*2,8/5,8%5,mod(8,5),mod(8,5)|0,-(1+1)*-2;
1+1 1-1 1+1*2 8/5 8%5 mod(8,5) mod(8,5)|0 -(1+1)*-2
2 0 3 1.60 3 3 3 4
+select 1 | (1+1),5 & 3,bit_count(7) ;
1 | (1+1) 5 & 3 bit_count(7)
3 1 3
+select 1 << 32,1 << 63, 1 << 64, 4 >> 2, 4 >> 63, 1<< 63 >> 60;
1 << 32 1 << 63 1 << 64 4 >> 2 4 >> 63 1<< 63 >> 60
-4294967296 -9223372036854775808 0 1 0 8
+4294967296 9223372036854775808 0 1 0 8
diff --git a/mysql-test/r/func_regexp.result b/mysql-test/r/func_regexp.result
index 5927dba0974..8d22994ef2b 100644
--- a/mysql-test/r/func_regexp.result
+++ b/mysql-test/r/func_regexp.result
@@ -1,3 +1,20 @@
+drop table if exists t1;
+create table t1 (s1 char(64),s2 char(64));
+insert into t1 values('aaa','aaa');
+insert into t1 values('aaa|qqq','qqq');
+insert into t1 values('gheis','^[^a-dXYZ]+$');
+insert into t1 values('aab','^aa?b');
+insert into t1 values('Baaan','^Ba*n');
+insert into t1 values('aaa','qqq|aaa');
+insert into t1 values('qqq','qqq|aaa');
+insert into t1 values('bbb','qqq|aaa');
+insert into t1 values('bbb','qqq');
+insert into t1 values('aaa','aba');
+insert into t1 values(null,'abc');
+insert into t1 values('def',null);
+insert into t1 values(null,null);
+insert into t1 values('ghi','ghi[');
+select HIGH_PRIORITY s1 regexp s2 from t1;
s1 regexp s2
1
1
@@ -13,13 +30,25 @@ NULL
NULL
NULL
NULL
+drop table t1;
+create table t1 (xxx char(128));
+insert into t1 (xxx) values('this is a test of some long text to see what happens');
+select * from t1 where xxx regexp('is a test of some long text to');
xxx
this is a test of some long text to see what happens
+select * from t1 where xxx regexp('is a test of some long text to ');
xxx
this is a test of some long text to see what happens
+select * from t1 where xxx regexp('is a test of some long text to s');
xxx
this is a test of some long text to see what happens
+select * from t1 where xxx regexp('is a test of some long text to se');
xxx
this is a test of some long text to see what happens
+drop table t1;
+create table t1 (xxx char(128));
+insert into t1 (xxx) values('this is some text: to test - out.reg exp (22/45)');
+select * from t1 where xxx REGEXP '^this is some text: to test - out\\.reg exp [[(][0-9]+[/\\][0-9]+[])][ ]*$';
xxx
this is some text: to test - out.reg exp (22/45)
+drop table t1;
diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result
index b82fffc3dbd..5305c16c5d9 100644
--- a/mysql-test/r/func_set.result
+++ b/mysql-test/r/func_set.result
@@ -1,18 +1,27 @@
+select interval(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0;
interval(55,10,20,30,40,50,60,70,80,90,100) interval(3,1,1+1,1+1+1+1) field("IBM","NCA","ICL","SUN","IBM","DIGITAL") field("A","B","C") elt(2,"ONE","TWO","THREE") interval(0,1,2,3,4) elt(1,1,2,3)|0 elt(1,1.1,1.2,1.3)+0
5 2 4 0 TWO 0 1 1.1
+select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd");
find_in_set("b","a,b,c") find_in_set("c","a,b,c") find_in_set("dd","a,bbb,dd") find_in_set("bbb","a,bbb,dd")
2 3 3 2
+select find_in_set("d","a,b,c"),find_in_set("dd","a,bbb,d"),find_in_set("bb","a,bbb,dd");
find_in_set("d","a,b,c") find_in_set("dd","a,bbb,d") find_in_set("bb","a,bbb,dd")
0 0 0
+select make_set(0,'a','b','c'),make_set(-1,'a','b','c'),make_set(1,'a','b','c'),make_set(2,'a','b','c'),make_set(1+2,concat('a','b'),'c');
make_set(0,'a','b','c') make_set(-1,'a','b','c') make_set(1,'a','b','c') make_set(2,'a','b','c') make_set(1+2,concat('a','b'),'c')
a,b,c a b ab,c
+select make_set(NULL,'a','b','c'),make_set(1|4,'a',NULL,'c'),make_set(1+2,'a',NULL,'c');
make_set(NULL,'a','b','c') make_set(1|4,'a',NULL,'c') make_set(1+2,'a',NULL,'c')
NULL a,c a
+select export_set(9,"Y","N","-",5),export_set(9,"Y","N"),export_set(9,"Y","N","");
export_set(9,"Y","N","-",5) export_set(9,"Y","N") export_set(9,"Y","N","")
Y-N-N-Y-N Y,N,N,Y,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N YNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+select elt(2,1),field(NULL,"a","b","c");
elt(2,1) field(NULL,"a","b","c")
NULL 0
+select find_in_set("","a,b,c"),find_in_set("","a,b,c,"),find_in_set("",",a,b,c");
find_in_set("","a,b,c") find_in_set("","a,b,c,") find_in_set("",",a,b,c")
0 4 1
+select find_in_set("abc","abc"),find_in_set("ab","abc"),find_in_set("abcd","abc");
find_in_set("abc","abc") find_in_set("ab","abc") find_in_set("abcd","abc")
1 0 0
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index ec421e9f31b..e02ee3a7343 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1,112 +1,216 @@
+drop table if exists t1;
+select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo';
hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo
hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo
+select 'hello' 'monty';
hello
hellomonty
+select length('\n\t\r\b\0\_\%\\');
length('\n\t\r\b\0\_\%\\')
10
+select bit_length('\n\t\r\b\0\_\%\\');
+bit_length('\n\t\r\b\0\_\%\\')
+80
+select concat('monty',' was here ','again'),length('hello'),char(ascii('h'));
concat('monty',' was here ','again') length('hello') char(ascii('h'))
monty was here again 5 h
+select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
locate('he','hello') locate('he','hello',2) locate('lo','hello',2)
1 0 4
-instr('hello','he')
-1
-position('ll' in 'hello') position('a' in 'hello')
+select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
+instr('hello','HE') instr('hello',binary 'HE') instr(binary 'hello','HE')
+1 0 0
+select position(binary 'll' in 'hello'),position('a' in binary 'hello');
+position(binary 'll' in 'hello') position('a' in binary 'hello')
3 0
+select left('hello',2),right('hello',2),substring('hello',2,2),mid('hello',1,5) ;
left('hello',2) right('hello',2) substring('hello',2,2) mid('hello',1,5)
he lo el hello
+select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1)) ;
concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1))
happy
+select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1);
substring_index('www.tcx.se','.',-2) substring_index('www.tcx.se','.',1)
tcx.se www
+select substring_index('www.tcx.se','tcx',1),substring_index('www.tcx.se','tcx',-1);
substring_index('www.tcx.se','tcx',1) substring_index('www.tcx.se','tcx',-1)
www. .se
+select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1);
substring_index('.tcx.se','.',-2) substring_index('.tcx.se','.tcx',-1)
tcx.se .se
+select concat(':',ltrim(' left '),':',rtrim(' right '),':');
concat(':',ltrim(' left '),':',rtrim(' right '),':')
:left : right:
+select concat(':',trim(LEADING FROM ' left'),':',trim(TRAILING FROM ' right '),':');
concat(':',trim(LEADING FROM ' left'),':',trim(TRAILING FROM ' right '),':')
:left: right:
+select concat(':',trim(' m '),':',trim(BOTH FROM ' y '),':',trim('*' FROM '*s*'),':');
concat(':',trim(' m '),':',trim(BOTH FROM ' y '),':',trim('*' FROM '*s*'),':')
:m:y:s:
+select concat(':',trim(BOTH 'ab' FROM 'ababmyabab'),':',trim(BOTH '*' FROM '***sql'),':');
concat(':',trim(BOTH 'ab' FROM 'ababmyabab'),':',trim(BOTH '*' FROM '***sql'),':')
:my:sql:
+select concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*'),':');
concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*'),':')
:my:sql:
+select TRIM("foo" FROM "foo"), TRIM("foo" FROM "foook"), TRIM("foo" FROM "okfoo");
TRIM("foo" FROM "foo") TRIM("foo" FROM "foook") TRIM("foo" FROM "okfoo")
ok ok
+select concat_ws(', ','monty','was here','again');
concat_ws(', ','monty','was here','again')
monty, was here, again
+select concat_ws(NULL,'a'),concat_ws(',',NULL,'');
concat_ws(NULL,'a') concat_ws(',',NULL,'')
NULL
+select concat_ws(',','',NULL,'a');
concat_ws(',','',NULL,'a')
a
+SELECT CONCAT('"',CONCAT_WS('";"',repeat('a',60),repeat('b',60),repeat('c',60),repeat('d',100)), '"');
CONCAT('"',CONCAT_WS('";"',repeat('a',60),repeat('b',60),repeat('c',60),repeat('d',100)), '"')
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
insert('txs',2,1,'hi') insert('is ',4,0,'a') insert('txxxxt',2,4,'es')
this is a test
+select replace('aaaa','a','b'),replace('aaaa','aa','b'),replace('aaaa','a','bb'),replace('aaaa','','b'),replace('bbbb','a','c');
replace('aaaa','a','b') replace('aaaa','aa','b') replace('aaaa','a','bb') replace('aaaa','','b') replace('bbbb','a','c')
bbbb bb bbbbbbbb aaaa bbbb
+select replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL')
this is a REAL test
+select soundex(''),soundex('he'),soundex('hello all folks');
soundex('') soundex('he') soundex('hello all folks')
H000 H4142
-password('test') length(encrypt('test')) encrypt('test','aa')
-378b243e220ca493 13 aaqPiZY5xR5l.
+select md5('hello');
md5('hello')
5d41402abc4b2a76b9719d911017c592
+select sha('abc');
+sha('abc')
+a9993e364706816aba3e25717850c26c9cd0d89d
+select sha1('abc');
+sha1('abc')
+a9993e364706816aba3e25717850c26c9cd0d89d
+select aes_decrypt(aes_encrypt('abc','1'),'1');
+aes_decrypt(aes_encrypt('abc','1'),'1')
+abc
+select aes_decrypt(aes_encrypt('abc','1'),1);
+aes_decrypt(aes_encrypt('abc','1'),1)
+abc
+select aes_encrypt(NULL,"a");
+aes_encrypt(NULL,"a")
+NULL
+select aes_encrypt("a",NULL);
+aes_encrypt("a",NULL)
+NULL
+select aes_decrypt(NULL,"a");
+aes_decrypt(NULL,"a")
+NULL
+select aes_decrypt("a",NULL);
+aes_decrypt("a",NULL)
+NULL
+select aes_decrypt("a","a");
+aes_decrypt("a","a")
+NULL
+select aes_decrypt(aes_encrypt("","a"),"a");
+aes_decrypt(aes_encrypt("","a"),"a")
+
+select repeat('monty',5),concat('*',space(5),'*');
repeat('monty',5) concat('*',space(5),'*')
montymontymontymontymonty * *
+select reverse('abc'),reverse('abcd');
reverse('abc') reverse('abcd')
cba dcba
+select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12');
rpad('a',4,'1') rpad('a',4,'12') rpad('abcd',3,'12')
a111 a121 abc
+select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12');
lpad('a',4,'1') lpad('a',4,'12') lpad('abcd',3,'12')
111a 121a abc
+select rpad(741653838,17,'0'),lpad(741653838,17,'0');
rpad(741653838,17,'0') lpad(741653838,17,'0')
74165383800000000 00000000741653838
+select rpad('abcd',7,'ab'),lpad('abcd',7,'ab');
rpad('abcd',7,'ab') lpad('abcd',7,'ab')
abcdaba abaabcd
+select rpad('abcd',1,'ab'),lpad('abcd',1,'ab');
rpad('abcd',1,'ab') lpad('abcd',1,'ab')
a a
+select LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'),GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD');
LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD') GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD')
HAROLD HARRY
+select least(1,2,3) | greatest(16,32,8), least(5,4)*1,greatest(-1.0,1.0)*1,least(3,2,1)*1.0,greatest(1,1.1,1.0),least("10",9),greatest("A","B","0");
least(1,2,3) | greatest(16,32,8) least(5,4)*1 greatest(-1.0,1.0)*1 least(3,2,1)*1.0 greatest(1,1.1,1.0) least("10",9) greatest("A","B","0")
33 4 1.0 1.0 1.1 9 B
+select decode(encode(repeat("a",100000),"monty"),"monty")=repeat("a",100000);
decode(encode(repeat("a",100000),"monty"),"monty")=repeat("a",100000)
1
+select decode(encode("abcdef","monty"),"monty")="abcdef";
decode(encode("abcdef","monty"),"monty")="abcdef"
1
+select reverse("");
reverse("")
+select insert("aa",100,1,"b"),insert("aa",1,3,"b"),left("aa",-1),substring("a",1,2);
insert("aa",100,1,"b") insert("aa",1,3,"b") left("aa",-1) substring("a",1,2)
aa b a
+select elt(2,1),field(NULL,"a","b","c"),reverse("");
elt(2,1) field(NULL,"a","b","c") reverse("")
NULL 0
+select locate("a","b",2),locate("","a",1);
locate("a","b",2) locate("","a",1)
0 1
+select ltrim("a"),rtrim("a"),trim(BOTH "" from "a"),trim(BOTH " " from "a");
ltrim("a") rtrim("a") trim(BOTH "" from "a") trim(BOTH " " from "a")
a a a a
+select concat("1","2")|0,concat("1",".5")+0.0;
concat("1","2")|0 concat("1",".5")+0.0
12 1.5
+select substring_index("www.tcx.se","",3);
substring_index("www.tcx.se","",3)
+select length(repeat("a",100000000)),length(repeat("a",1000*64));
length(repeat("a",100000000)) length(repeat("a",1000*64))
NULL 64000
+select position("0" in "baaa" in (1)),position("0" in "1" in (1,2,3)),position("sql" in ("mysql"));
position("0" in "baaa" in (1)) position("0" in "1" in (1,2,3)) position("sql" in ("mysql"))
1 0 3
+select position(("1" in (1,2,3)) in "01");
position(("1" in (1,2,3)) in "01")
2
+select length(repeat("a",65500)),length(concat(repeat("a",32000),repeat("a",32000))),length(replace("aaaaa","a",concat(repeat("a",10000)))),length(insert(repeat("a",40000),1,30000,repeat("b",50000)));
length(repeat("a",65500)) length(concat(repeat("a",32000),repeat("a",32000))) length(replace("aaaaa","a",concat(repeat("a",10000)))) length(insert(repeat("a",40000),1,30000,repeat("b",50000)))
65500 64000 50000 60000
+select length(repeat("a",1000000)),length(concat(repeat("a",32000),repeat("a",32000),repeat("a",32000))),length(replace("aaaaa","a",concat(repeat("a",32000)))),length(insert(repeat("a",48000),1,1000,repeat("a",48000)));
length(repeat("a",1000000)) length(concat(repeat("a",32000),repeat("a",32000),repeat("a",32000))) length(replace("aaaaa","a",concat(repeat("a",32000)))) length(insert(repeat("a",48000),1,1000,repeat("a",48000)))
1000000 96000 160000 95000
+create table t1 ( domain char(50) );
+insert into t1 VALUES ("hello.de" ), ("test.de" );
+select domain from t1 where concat('@', trim(leading '.' from concat('.', domain))) = '@hello.de';
domain
hello.de
+select domain from t1 where concat('@', trim(leading '.' from concat('.', domain))) = '@test.de';
domain
test.de
+drop table t1;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL,
+title varchar(255) default NULL,
+prio int(10) unsigned default NULL,
+category int(10) unsigned default NULL,
+program int(10) unsigned default NULL,
+bugdesc text,
+created datetime default NULL,
+modified timestamp(14) NOT NULL,
+bugstatus int(10) unsigned default NULL,
+submitter int(10) unsigned default NULL
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'Link',1,1,1,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa','2001-02-28 08:40:16',20010228084016,0,4);
+SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter), '"') FROM t1;
CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter), '"')
"Link";"1";"1";"1";"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"2001-02-28 08:40:16";"20010228084016";"0";"4"
+SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"') FROM t1;
CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"')
"Link";"1";"1";"1";"0";"4"
+SELECT CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter) FROM t1;
CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter)
Link";"1";"1";"1";"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"2001-02-28 08:40:16";"20010228084016";"0";"4
+drop table t1;
diff --git a/mysql-test/r/func_system.result b/mysql-test/r/func_system.result
index c6ec28bfd34..5ea4ed5e4e0 100644
--- a/mysql-test/r/func_system.result
+++ b/mysql-test/r/func_system.result
@@ -1,4 +1,6 @@
-database() user()
-test root@localhost
+select database(),user() like "%@%";
+database() user() like "%@%"
+test 1
+select version()>="3.23.29";
version()>="3.23.29"
1
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index 586e345ea10..8cfae44b9dd 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -1,34 +1,57 @@
+select 0=0,1>0,1>=1,1<0,1<=0,1!=0,strcmp("abc","abcd"),strcmp("b","a"),strcmp("a","a") ;
0=0 1>0 1>=1 1<0 1<=0 1!=0 strcmp("abc","abcd") strcmp("b","a") strcmp("a","a")
1 1 1 0 0 1 -1 1 0
+select "a"<"b","a"<="b","b">="a","b">"a","a"="A","a"<>"b";
"a"<"b" "a"<="b" "b">="a" "b">"a" "a"="A" "a"<>"b"
1 1 1 1 1 1
+select "a "="A", "A "="a", "a " <= "A b";
"a "="A" "A "="a" "a " <= "A b"
1 1 1
+select "abc" like "a%", "abc" not like "%d%", "a%" like "a\%","abc%" like "a%\%","abcd" like "a%b_%d", "a" like "%%a","abcde" like "a%_e","abc" like "abc%";
"abc" like "a%" "abc" not like "%d%" "a%" like "a\%" "abc%" like "a%\%" "abcd" like "a%b_%d" "a" like "%%a" "abcde" like "a%_e" "abc" like "abc%"
1 1 1 1 1 1 1 1
+select "a" like "%%b","a" like "%%ab","ab" like "a\%", "ab" like "_", "ab" like "ab_", "abc" like "%_d", "abc" like "abc%d";
"a" like "%%b" "a" like "%%ab" "ab" like "a\%" "ab" like "_" "ab" like "ab_" "abc" like "%_d" "abc" like "abc%d"
0 0 0 0 0 0 0
+select '?' like '|%', '?' like '|%' ESCAPE '|', '%' like '|%', '%' like '|%' ESCAPE '|', '%' like '%';
'?' like '|%' '?' like '|%' ESCAPE '|' '%' like '|%' '%' like '|%' ESCAPE '|' '%' like '%'
0 0 0 1 1
+select 'abc' like '%c','abcabc' like '%c', "ab" like "", "ab" like "a", "ab" like "ab";
'abc' like '%c' 'abcabc' like '%c' "ab" like "" "ab" like "a" "ab" like "ab"
1 1 0 0 1
+select "Det här är svenska" regexp "h[[:alpha:]]+r", "aba" regexp "^(a|b)*$";
"Det här är svenska" regexp "h[[:alpha:]]+r" "aba" regexp "^(a|b)*$"
1 1
+select "aba" regexp concat("^","a");
"aba" regexp concat("^","a")
1
+select !0,NOT 0=1,!(0=0),1 AND 1,1 && 0,0 OR 1,1 || NULL, 1=1 or 1=1 and 1=0;
!0 NOT 0=1 !(0=0) 1 AND 1 1 && 0 0 OR 1 1 || NULL 1=1 or 1=1 and 1=0
1 1 0 1 0 1 1 1
+select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between "max" and "my" and 3=3;
2 between 1 and 3 "monty" between "max" and "my" 2=2 and "monty" between "max" and "my" and 3=3
1 1 1
+select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
'b' between 'a' and 'c' 'B' between 'a' and 'c'
1 1
+select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
2 in (3,2,5,9,5,1) "monty" in ("david","monty","allan") 1.2 in (1.4,1.2,1.0)
1 1 1
+select -1.49 or -1.49,0.6 or 0.6;
-1.49 or -1.49 0.6 or 0.6
1 1
+select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
+3 ^ 11 1 ^ 1 1 ^ 0 1 ^ NULL NULL ^ 1
+8 0 1 NULL NULL
+select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
+1 XOR 1 1 XOR 0 0 XOR 1 0 XOR 0 NULL XOR 1 1 XOR NULL 0 XOR NULL
+0 1 1 0 NULL NULL NULL
+select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1
0 1
+select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1;
1 and 2 between 2 and 10 2 between 2 and 10 and 1
1 1
+select 1 and 0 or 2, 2 or 1 and 0;
1 and 0 or 2 2 or 1 and 0
1 1
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 71fc7e4b90b..5433194c719 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1,222 +1,374 @@
+drop table if exists t1,t2;
+select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29");
from_days(to_days("960101")) to_days(960201)-to_days("19960101") to_days(date_add(curdate(), interval 1 day))-to_days(curdate()) weekday("1997-11-29")
1996-01-01 31 1 5
+select period_add("9602",-12),period_diff(199505,"9404") ;
period_add("9602",-12) period_diff(199505,"9404")
199502 13
+select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now());
now()-now() weekday(curdate())-weekday(now()) unix_timestamp()-unix_timestamp(now())
0 0 0
+select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0;
from_unixtime(unix_timestamp("1994-03-02 10:11:12")) from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0
1994-03-02 10:11:12 1994-03-02 10:11:12 19940302101112
+select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
+sec_to_time(time_to_sec("0:30:47")/6.21);
sec_to_time(9001) sec_to_time(9001)+0 time_to_sec("15:12:22") sec_to_time(time_to_sec("0:30:47")/6.21)
02:30:01 23001 54742 00:04:57
+select sec_to_time(time_to_sec('-838:59:59'));
sec_to_time(time_to_sec('-838:59:59'))
-838:59:59
+select now()-curdate()*1000000-curtime();
now()-curdate()*1000000-curtime()
0
+select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
strcmp(current_timestamp(),concat(current_date()," ",current_time()))
0
+select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")
January Thursday 2nd 1997 97 01 02 03 04 05 4
+select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"));
date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"))
January Thursday 2nd 1997 97 01 02 12 00 00 4
+select dayofmonth("1997-01-02"),dayofmonth(19970323);
dayofmonth("1997-01-02") dayofmonth(19970323)
2 23
+select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31");
month("1997-01-02") year("98-02-03") dayofyear("1997-12-31")
1 1998 365
+select month("2001-02-00"),year("2001-00-00");
month("2001-02-00") year("2001-00-00")
2 2001
+select DAYOFYEAR("1997-03-03"), WEEK("1998-03-03"), QUARTER(980303);
DAYOFYEAR("1997-03-03") WEEK("1998-03-03") QUARTER(980303)
62 9 1
+select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322);
HOUR("1997-03-03 23:03:22") MINUTE("23:03:22") SECOND(230322)
23 3 22
+select week(19980101),week(19970101),week(19980101,1),week(19970101,1);
week(19980101) week(19970101) week(19980101,1) week(19970101,1)
-0 1 1 1
+0 0 1 1
+select week(19981231),week(19971231),week(19981231,1),week(19971231,1);
week(19981231) week(19971231) week(19981231,1) week(19971231,1)
-52 53 53 53
+52 52 53 53
+select week(19950101),week(19950101,1);
week(19950101) week(19950101,1)
1 0
+select yearweek('1981-12-31',1),yearweek('1982-01-01',1),yearweek('1982-12-31',1),yearweek('1983-01-01',1);
yearweek('1981-12-31',1) yearweek('1982-01-01',1) yearweek('1982-12-31',1) yearweek('1983-01-01',1)
198153 198153 198252 198252
+select yearweek('1987-01-01',1),yearweek('1987-01-01');
+yearweek('1987-01-01',1) yearweek('1987-01-01')
+198701 198652
+select week("2000-01-01",0) as '2000', week("2001-01-01",0) as '2001', week("2002-01-01",0) as '2002',week("2003-01-01",0) as '2003', week("2004-01-01",0) as '2004', week("2005-01-01",0) as '2005', week("2006-01-01",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+0 0 0 0 0 0 1
+select week("2000-01-06",0) as '2000', week("2001-01-06",0) as '2001', week("2002-01-06",0) as '2002',week("2003-01-06",0) as '2003', week("2004-01-06",0) as '2004', week("2005-01-06",0) as '2005', week("2006-01-06",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+1 0 1 1 1 1 1
+select week("2000-01-01",1) as '2000', week("2001-01-01",1) as '2001', week("2002-01-01",1) as '2002',week("2003-01-01",1) as '2003', week("2004-01-01",1) as '2004', week("2005-01-01",1) as '2005', week("2006-01-01",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+0 1 1 1 1 0 0
+select week("2000-01-06",1) as '2000', week("2001-01-06",1) as '2001', week("2002-01-06",1) as '2002',week("2003-01-06",1) as '2003', week("2004-01-06",1) as '2004', week("2005-01-06",1) as '2005', week("2006-01-06",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+1 1 1 2 2 1 1
+select yearweek("2000-01-01",0) as '2000', yearweek("2001-01-01",0) as '2001', yearweek("2002-01-01",0) as '2002',yearweek("2003-01-01",0) as '2003', yearweek("2004-01-01",0) as '2004', yearweek("2005-01-01",0) as '2005', yearweek("2006-01-01",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+199952 200053 200152 200252 200352 200452 200601
+select yearweek("2000-01-06",0) as '2000', yearweek("2001-01-06",0) as '2001', yearweek("2002-01-06",0) as '2002',yearweek("2003-01-06",0) as '2003', yearweek("2004-01-06",0) as '2004', yearweek("2005-01-06",0) as '2005', yearweek("2006-01-06",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+200001 200053 200201 200301 200401 200501 200601
+select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', yearweek("2002-01-01",1) as '2002',yearweek("2003-01-01",1) as '2003', yearweek("2004-01-01",1) as '2004', yearweek("2005-01-01",1) as '2005', yearweek("2006-01-01",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+199952 200101 200201 200301 200401 200453 200552
+select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+200001 200101 200201 200302 200402 200501 200601
+select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v')
1998-53 1998-53
+select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
date_format('1999-12-31','%x-%v') date_format('2000-01-01','%x-%v')
1999-52 1999-52
-yearweek('1987-01-01',1) yearweek('1987-01-01')
-198701 198653
+select dayname("1962-03-03"),dayname("1962-03-03")+0;
dayname("1962-03-03") dayname("1962-03-03")+0
Saturday 5
+select monthname("1972-03-04"),monthname("1972-03-04")+0;
monthname("1972-03-04") monthname("1972-03-04")+0
March 3
+select time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
00|12|0|12|00|AM|12:00:00 AM|00|00:00:00
+select time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
01|01|1|1|02|AM|01:02:03 AM|03|01:02:03
+select time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
13|01|13|1|14|PM|01:14:15 PM|15|13:14:15
+select time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
01|01|1|1|00|AM|01:00:15 AM|15|01:00:15
+select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w')
13|01|13|1|14|PM|01:14:15 PM|15|13:14:15| January|Saturday|31st|1998|98|Sat|Jan|031|01|31|01|15|6
+select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w')
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND);
date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)
1998-01-01 00:00:00
+select date_add("1997-12-31 23:59:59",INTERVAL 1 MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL 1 MINUTE)
1998-01-01 00:00:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 HOUR);
date_add("1997-12-31 23:59:59",INTERVAL 1 HOUR)
1998-01-01 00:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 DAY);
date_add("1997-12-31 23:59:59",INTERVAL 1 DAY)
1998-01-01 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 MONTH);
date_add("1997-12-31 23:59:59",INTERVAL 1 MONTH)
1998-01-31 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 YEAR);
date_add("1997-12-31 23:59:59",INTERVAL 1 YEAR)
1998-12-31 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1" MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" MINUTE_SECOND)
1998-01-01 00:01:00
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1" HOUR_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" HOUR_MINUTE)
1998-01-01 01:00:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1" DAY_HOUR);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" DAY_HOUR)
1998-01-02 00:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1 1" YEAR_MONTH);
date_add("1997-12-31 23:59:59",INTERVAL "1 1" YEAR_MONTH)
1999-01-31 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1:1" HOUR_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1:1:1" HOUR_SECOND)
1998-01-01 01:01:00
+select date_add("1997-12-31 23:59:59",INTERVAL "1 1:1" DAY_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "1 1:1" DAY_MINUTE)
1998-01-02 01:00:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1 1:1:1" DAY_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1 1:1:1" DAY_SECOND)
1998-01-02 01:01:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL 1 SECOND)
1997-12-31 23:59:59
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL 1 MINUTE)
1997-12-31 23:59:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 HOUR);
date_sub("1998-01-01 00:00:00",INTERVAL 1 HOUR)
1997-12-31 23:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 DAY);
date_sub("1998-01-01 00:00:00",INTERVAL 1 DAY)
1997-12-31 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 MONTH);
date_sub("1998-01-01 00:00:00",INTERVAL 1 MONTH)
1997-12-01 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 YEAR);
date_sub("1998-01-01 00:00:00",INTERVAL 1 YEAR)
1997-01-01 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" MINUTE_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" MINUTE_SECOND)
1997-12-31 23:58:59
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" HOUR_MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" HOUR_MINUTE)
1997-12-31 22:59:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" DAY_HOUR);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" DAY_HOUR)
1997-12-30 23:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1 1" YEAR_MONTH);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1" YEAR_MONTH)
1996-12-01 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1:1" HOUR_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1:1" HOUR_SECOND)
1997-12-31 22:58:59
+select date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1" DAY_MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1" DAY_MINUTE)
1997-12-30 22:59:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1:1" DAY_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1:1" DAY_SECOND)
1997-12-30 22:58:59
+select date_add("1997-12-31 23:59:59",INTERVAL 100000 SECOND);
date_add("1997-12-31 23:59:59",INTERVAL 100000 SECOND)
1998-01-02 03:46:39
+select date_add("1997-12-31 23:59:59",INTERVAL -100000 MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL -100000 MINUTE)
1997-10-23 13:19:59
+select date_add("1997-12-31 23:59:59",INTERVAL 100000 HOUR);
date_add("1997-12-31 23:59:59",INTERVAL 100000 HOUR)
2009-05-29 15:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL -100000 DAY);
date_add("1997-12-31 23:59:59",INTERVAL -100000 DAY)
1724-03-17 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 100000 MONTH);
date_add("1997-12-31 23:59:59",INTERVAL 100000 MONTH)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL -100000 YEAR);
date_add("1997-12-31 23:59:59",INTERVAL -100000 YEAR)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000:1" MINUTE_SECOND)
1998-01-07 22:40:00
+select date_add("1997-12-31 23:59:59",INTERVAL "-10000:1" HOUR_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "-10000:1" HOUR_MINUTE)
1996-11-10 07:58:59
+select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR);
date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR)
2025-05-19 00:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH);
date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH)
1897-11-30 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND)
1999-02-21 17:40:38
+select date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE)
1970-08-11 19:20:59
+select date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND)
2025-05-23 04:40:38
+select "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
"1997-12-31 23:59:59" + INTERVAL 1 SECOND
1998-01-01 00:00:00
+select INTERVAL 1 DAY + "1997-12-31";
INTERVAL 1 DAY + "1997-12-31"
1998-01-01
+select "1998-01-01 00:00:00" - INTERVAL 1 SECOND;
"1998-01-01 00:00:00" - INTERVAL 1 SECOND
1997-12-31 23:59:59
+select date_sub("1998-01-02",INTERVAL 31 DAY);
date_sub("1998-01-02",INTERVAL 31 DAY)
1997-12-02
+select date_add("1997-12-31",INTERVAL 1 SECOND);
date_add("1997-12-31",INTERVAL 1 SECOND)
1997-12-31 00:00:01
+select date_add("1997-12-31",INTERVAL 1 DAY);
date_add("1997-12-31",INTERVAL 1 DAY)
1998-01-01
+select date_add(NULL,INTERVAL 100000 SECOND);
date_add(NULL,INTERVAL 100000 SECOND)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL NULL SECOND);
date_add("1997-12-31 23:59:59",INTERVAL NULL SECOND)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL NULL MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL NULL MINUTE_SECOND)
NULL
+select date_add("9999-12-31 23:59:59",INTERVAL 1 SECOND);
date_add("9999-12-31 23:59:59",INTERVAL 1 SECOND)
NULL
+select date_sub("0000-00-00 00:00:00",INTERVAL 1 SECOND);
date_sub("0000-00-00 00:00:00",INTERVAL 1 SECOND)
NULL
+select date_add('1998-01-30',Interval 1 month);
date_add('1998-01-30',Interval 1 month)
1998-02-28
+select date_add('1998-01-30',Interval '2:1' year_month);
date_add('1998-01-30',Interval '2:1' year_month)
2000-02-29
+select date_add('1996-02-29',Interval '1' year);
date_add('1996-02-29',Interval '1' year)
1997-02-28
+select extract(YEAR FROM "1999-01-02 10:11:12");
extract(YEAR FROM "1999-01-02 10:11:12")
1999
+select extract(YEAR_MONTH FROM "1999-01-02");
extract(YEAR_MONTH FROM "1999-01-02")
199901
+select extract(DAY FROM "1999-01-02");
extract(DAY FROM "1999-01-02")
2
+select extract(DAY_HOUR FROM "1999-01-02 10:11:12");
extract(DAY_HOUR FROM "1999-01-02 10:11:12")
210
+select extract(DAY_MINUTE FROM "02 10:11:12");
extract(DAY_MINUTE FROM "02 10:11:12")
21011
+select extract(DAY_SECOND FROM "225 10:11:12");
extract(DAY_SECOND FROM "225 10:11:12")
225101112
+select extract(HOUR FROM "1999-01-02 10:11:12");
extract(HOUR FROM "1999-01-02 10:11:12")
10
+select extract(HOUR_MINUTE FROM "10:11:12");
extract(HOUR_MINUTE FROM "10:11:12")
1011
+select extract(HOUR_SECOND FROM "10:11:12");
extract(HOUR_SECOND FROM "10:11:12")
101112
+select extract(MINUTE FROM "10:11:12");
extract(MINUTE FROM "10:11:12")
11
+select extract(MINUTE_SECOND FROM "10:11:12");
extract(MINUTE_SECOND FROM "10:11:12")
1112
+select extract(SECOND FROM "1999-01-02 10:11:12");
extract(SECOND FROM "1999-01-02 10:11:12")
12
+select extract(MONTH FROM "2001-02-00");
extract(MONTH FROM "2001-02-00")
2
+create table t1 (ctime varchar(20));
+insert into t1 values ('2001-01-12 12:23:40');
+select ctime, hour(ctime) from t1;
ctime hour(ctime)
2001-01-12 12:23:40 12
+drop table t1;
+create table t1 (id int);
+create table t2 (id int, date date);
+insert into t1 values (1);
+insert into t2 values (1, "0000-00-00");
+insert into t1 values (2);
+insert into t2 values (2, "2000-01-01");
+select monthname(date) from t1 inner join t2 on t1.id = t2.id;
monthname(date)
NULL
January
+select monthname(date) from t1 inner join t2 on t1.id = t2.id order by t1.id;
monthname(date)
NULL
January
+drop table t1,t2;
+CREATE TABLE t1 (updated text) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('');
+SELECT month(updated) from t1;
month(updated)
NULL
+SELECT year(updated) from t1;
year(updated)
NULL
+drop table t1;
+create table t1 (d date, dt datetime, t timestamp, c char(10));
+insert into t1 values ("0000-00-00", "0000-00-00", "0000-00-00", "0000-00-00");
+select dayofyear("0000-00-00"),dayofyear(d),dayofyear(dt),dayofyear(t),dayofyear(c) from t1;
dayofyear("0000-00-00") dayofyear(d) dayofyear(dt) dayofyear(t) dayofyear(c)
NULL NULL NULL NULL NULL
+select dayofmonth("0000-00-00"),dayofmonth(d),dayofmonth(dt),dayofmonth(t),dayofmonth(c) from t1;
dayofmonth("0000-00-00") dayofmonth(d) dayofmonth(dt) dayofmonth(t) dayofmonth(c)
0 0 0 0 0
+select month("0000-00-00"),month(d),month(dt),month(t),month(c) from t1;
month("0000-00-00") month(d) month(dt) month(t) month(c)
0 0 0 0 0
+select quarter("0000-00-00"),quarter(d),quarter(dt),quarter(t),quarter(c) from t1;
quarter("0000-00-00") quarter(d) quarter(dt) quarter(t) quarter(c)
0 0 0 0 0
+select week("0000-00-00"),week(d),week(dt),week(t),week(c) from t1;
week("0000-00-00") week(d) week(dt) week(t) week(c)
NULL NULL NULL NULL NULL
+select year("0000-00-00"),year(d),year(dt),year(t),year(c) from t1;
year("0000-00-00") year(d) year(dt) year(t) year(c)
0 0 0 0 0
+select yearweek("0000-00-00"),yearweek(d),yearweek(dt),yearweek(t),yearweek(c) from t1;
yearweek("0000-00-00") yearweek(d) yearweek(dt) yearweek(t) yearweek(c)
NULL NULL NULL NULL NULL
+select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t1;
to_days("0000-00-00") to_days(d) to_days(dt) to_days(t) to_days(c)
NULL NULL NULL NULL NULL
+select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1;
extract(MONTH FROM "0000-00-00") extract(MONTH FROM d) extract(MONTH FROM dt) extract(MONTH FROM t) extract(MONTH FROM c)
0 0 0 0 0
+drop table t1;
diff --git a/mysql-test/r/func_timestamp.result b/mysql-test/r/func_timestamp.result
index 4d4a5b541ac..d9912f08b72 100644
--- a/mysql-test/r/func_timestamp.result
+++ b/mysql-test/r/func_timestamp.result
@@ -1,3 +1,11 @@
+drop table if exists t1;
+create table t1 (Zeit time, Tag tinyint not null, Monat tinyint not null,
+Jahr smallint not null, index(Tag), index(Monat), index(Jahr) );
+insert into t1 values ("09:26:00",16,9,1998),("09:26:00",16,9,1998);
+SELECT CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit) AS Date,
+UNIX_TIMESTAMP(CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit)) AS Unix
+FROM t1;
Date Unix
1998-9-16 09:26:00 905927160
1998-9-16 09:26:00 905927160
+drop table t1;
diff --git a/mysql-test/r/gcc296.result b/mysql-test/r/gcc296.result
index 7184bfb9cdc..8f78f70cc1f 100644
--- a/mysql-test/r/gcc296.result
+++ b/mysql-test/r/gcc296.result
@@ -1,5 +1,20 @@
+drop table if exists obory;
+CREATE TABLE obory (
+kodoboru varchar(10) default NULL,
+obor tinytext,
+aobor tinytext,
+UNIQUE INDEX kodoboru (kodoboru),
+FULLTEXT KEY obor (obor),
+FULLTEXT KEY aobor (aobor)
+);
+INSERT INTO obory VALUES ('0101000000','aaa','AAA');
+INSERT INTO obory VALUES ('0102000000','bbb','BBB');
+INSERT INTO obory VALUES ('0103000000','ccc','CCC');
+INSERT INTO obory VALUES ('0104000000','xxx','XXX');
+select * from obory;
kodoboru obor aobor
0101000000 aaa AAA
0102000000 bbb BBB
0103000000 ccc CCC
0104000000 xxx XXX
+drop table obory;
diff --git a/mysql-test/r/gemini.result b/mysql-test/r/gemini.result
deleted file mode 100644
index 0b43b4f5192..00000000000
--- a/mysql-test/r/gemini.result
+++ /dev/null
@@ -1,370 +0,0 @@
-id code name
-1 1 Tim
-2 1 Monty
-3 2 David
-4 2 Erik
-5 3 Sasha
-6 3 Jeremy
-7 4 Matt
-id code name
-2 1 Monty
-3 2 David
-4 2 Erik
-5 3 Sasha
-6 3 Jeremy
-7 4 Matt
-8 1 Sinisa
-id code name
-3 2 David
-4 2 Erik
-5 3 Sasha
-6 3 Jeremy
-7 4 Matt
-8 1 Sinisa
-12 1 Ralph
-id parent_id level
-8 102 2
-9 102 2
-15 102 2
-id parent_id level
-1001 100 0
-1003 101 1
-1004 101 1
-1008 102 2
-1009 102 2
-1017 103 2
-1022 104 2
-1024 104 2
-1028 105 2
-1029 105 2
-1030 105 2
-1031 106 2
-1032 106 2
-1033 106 2
-1203 107 2
-1202 107 2
-1020 103 2
-1157 100 0
-1193 105 2
-1040 107 2
-1002 101 1
-1015 102 2
-1006 101 1
-1034 106 2
-1035 106 2
-1016 103 2
-1007 101 1
-1036 107 2
-1018 103 2
-1026 105 2
-1027 105 2
-1183 104 2
-1038 107 2
-1025 105 2
-1037 107 2
-1021 104 2
-1019 103 2
-1005 101 1
-1179 105 2
-id parent_id level
-1001 100 0
-1003 101 1
-1004 101 1
-1008 102 2
-1010 102 2
-1017 103 2
-1023 104 2
-1024 104 2
-1028 105 2
-1029 105 2
-1030 105 2
-1031 106 2
-1032 106 2
-1033 106 2
-1204 107 2
-1203 107 2
-1020 103 2
-1158 100 0
-1194 105 2
-1041 107 2
-1002 101 1
-1015 102 2
-1006 101 1
-1034 106 2
-1035 106 2
-1016 103 2
-1007 101 1
-1036 107 2
-1018 103 2
-1026 105 2
-1027 105 2
-1184 104 2
-1039 107 2
-1025 105 2
-1038 107 2
-1022 104 2
-1019 103 2
-1005 101 1
-1180 105 2
-id parent_id level
-1008 102 2
-1010 102 2
-1015 102 2
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used; Using index
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used
-level id
-1 1003
-1 1004
-1 1002
-1 1006
-1 1007
-1 1005
-level id parent_id
-1 1003 101
-1 1004 101
-1 1002 101
-1 1006 101
-1 1007 101
-1 1005 101
-gesuchnr benutzer_id
-1 1
-2 1
-a
-2
-user_id name phone ref_email detail
-10292 sanjeev 29153373 sansh777@hotmail.com xxx
-10292 shirish 2333604 shirish@yahoo.com ddsds
-10292 sonali 323232 sonali@bolly.com filmstar
-user_id name phone ref_email detail
-10292 sanjeev 29153373 sansh777@hotmail.com xxx
-10292 shirish 2333604 shirish@yahoo.com ddsds
-10292 sonali 323232 sonali@bolly.com filmstar
-user_id name phone ref_email detail
-10292 sanjeev 29153373 sansh777@hotmail.com xxx
-10292 shirish 2333604 shirish@yahoo.com ddsds
-10292 sonali 323232 sonali@bolly.com filmstar
-10293 shirish 2333604 shirish@yahoo.com ddsds
-user_id name phone ref_email detail
-10293 shirish 2333604 shirish@yahoo.com ddsds
-user_id name phone ref_email detail
-10291 sanjeev 29153373 sansh777@hotmail.com xxx
-a b
-1 3
-2 3
-3 3
-a b
-1 3
-2 3
-3 3
-a b
-a b
-1 3
-2 3
-3 3
-a b
-1 3
-2 3
-3 3
-id ggid email passwd
-1 test1 xxx
-id ggid email passwd
-1 test1 xxx
-id ggid email passwd
-2 test2 yyy
-id parent_id level
-8 102 2
-9 102 2
-15 102 2
-id parent_id level
-1001 100 0
-1003 101 1
-1004 101 1
-1008 102 2
-1024 102 2
-1017 103 2
-1022 104 2
-1024 104 2
-1028 105 2
-1029 105 2
-1030 105 2
-1031 106 2
-1032 106 2
-1033 106 2
-1203 107 2
-1202 107 2
-1020 103 2
-1157 100 0
-1193 105 2
-1040 107 2
-1002 101 1
-1015 102 2
-1006 101 1
-1034 106 2
-1035 106 2
-1016 103 2
-1007 101 1
-1036 107 2
-1018 103 2
-1026 105 2
-1027 105 2
-1183 104 2
-1038 107 2
-1025 105 2
-1037 107 2
-1021 104 2
-1019 103 2
-1005 101 1
-1179 105 2
-id parent_id level
-1002 100 0
-1004 101 1
-1005 101 1
-1009 102 2
-1025 102 2
-1018 103 2
-1023 104 2
-1025 104 2
-1029 105 2
-1030 105 2
-1031 105 2
-1032 106 2
-1033 106 2
-1034 106 2
-1204 107 2
-1203 107 2
-1021 103 2
-1158 100 0
-1194 105 2
-1041 107 2
-1003 101 1
-1016 102 2
-1007 101 1
-1035 106 2
-1036 106 2
-1017 103 2
-1008 101 1
-1037 107 2
-1019 103 2
-1027 105 2
-1028 105 2
-1184 104 2
-1039 107 2
-1026 105 2
-1038 107 2
-1022 104 2
-1020 103 2
-1006 101 1
-1180 105 2
-id parent_id level
-1009 102 2
-1025 102 2
-1016 102 2
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used; Using index
-level id
-1 1004
-1 1005
-1 1003
-1 1007
-1 1008
-1 1006
-level id parent_id
-1 1004 101
-1 1005 101
-1 1003 101
-1 1007 101
-1 1008 101
-1 1006 101
-level id
-1 1003
-1 1004
-1 1005
-1 1006
-1 1007
-1 1008
-id parent_id level
-1002 100 0
-1009 102 2
-1025 102 2
-1018 103 2
-1023 104 2
-1025 104 2
-1029 105 2
-1030 105 2
-1031 105 2
-1032 106 2
-1033 106 2
-1034 106 2
-1204 107 2
-1203 107 2
-1021 103 2
-1158 100 0
-1194 105 2
-1041 107 2
-1016 102 2
-1035 106 2
-1036 106 2
-1017 103 2
-1037 107 2
-1019 103 2
-1027 105 2
-1028 105 2
-1184 104 2
-1039 107 2
-1026 105 2
-1038 107 2
-1022 104 2
-1020 103 2
-1180 105 2
-count(*)
-1
-a
-1
-2
-3
-test for rollback
-test for rollback
-n after rollback
-4 after rollback
-n after commit
-4 after commit
-5 after commit
-n after commit
-4 after commit
-5 after commit
-6 after commit
-n
-4
-5
-6
-7
-afterbegin_id afterbegin_nom
-1 first
-2 hamdouni
-afterrollback_id afterrollback_nom
-1 first
-afterautocommit0_id afterautocommit0_nom
-1 first
-3 mysql
-afterrollback_id afterrollback_nom
-1 first
-id val
-id val
-pippo 12
-id val
-ID NAME
-1 Jochen
-_userid
-marc@anyware.co.uk
-_userid
-marc@anyware.co.uk
-f1
-65
-379
-468
-469
-508
diff --git a/mysql-test/r/grant_cache.result b/mysql-test/r/grant_cache.result
new file mode 100644
index 00000000000..3892765f587
--- /dev/null
+++ b/mysql-test/r/grant_cache.result
@@ -0,0 +1,153 @@
+drop table if exists test.t1,mysqltest.t1,mysqltest.t2;
+reset query cache;
+flush status;
+create database if not exists mysqltest;
+create table mysqltest.t1 (a int,b int,c int);
+create table mysqltest.t2 (a int,b int,c int);
+insert into mysqltest.t1 values (1,1,1),(2,2,2);
+insert into mysqltest.t2 values (3,3,3);
+create table test.t1 (a char (10));
+insert into test.t1 values ("test.t1");
+select * from t1;
+a
+test.t1
+select * from t1;
+a b c
+1 1 1
+2 2 2
+select a from t1;
+a
+1
+2
+select c from t1;
+c
+1
+2
+select * from t2;
+a b c
+3 3 3
+select * from mysqltest.t1,test.t1;
+a b c a
+1 1 1 test.t1
+2 2 2 test.t1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits%";
+Variable_name Value
+Qcache_hits 0
+grant SELECT on mysqltest.* to mysqltest_1@localhost;
+grant SELECT on mysqltest.t1 to mysqltest_2@localhost;
+grant SELECT on test.t1 to mysqltest_2@localhost;
+grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost;
+select "user1";
+user1
+user1
+select * from t1;
+a b c
+1 1 1
+2 2 2
+select a from t1 ;
+a
+1
+2
+select c from t1;
+c
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 3
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 1
+select "user2";
+user2
+user2
+select * from t1;
+a b c
+1 1 1
+2 2 2
+select a from t1;
+a
+1
+2
+select c from t1;
+c
+1
+2
+select * from mysqltest.t1,test.t1;
+a b c a
+1 1 1 test.t1
+2 2 2 test.t1
+select * from t2;
+select command denied to user: 'mysqltest_2@localhost' for table 't2'
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 7
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 3
+select "user3";
+user3
+user3
+select * from t1;
+select command denied to user: 'mysqltest_3@localhost' for column 'b' in table 't1'
+select a from t1;
+a
+1
+2
+select c from t1;
+SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
+select * from t2;
+select command denied to user: 'mysqltest_3@localhost' for table 't2'
+select mysqltest.t1.c from test.t1,mysqltest.t1;
+SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 7
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 8
+select "user4";
+user4
+user4
+select a from t1;
+No Database Selected
+select * from mysqltest.t1,test.t1;
+a b c a
+1 1 1 test.t1
+2 2 2 test.t1
+select a from mysqltest.t1;
+a
+1
+2
+select a from mysqltest.t1;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 8
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 8
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 9
+delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+flush privileges;
+drop table test.t1,mysqltest.t1,mysqltest.t2;
+drop database mysqltest;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index aafeb64ee2a..0ec1c03c467 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -1,15 +1,189 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 (
+spID int(10) unsigned,
+userID int(10) unsigned,
+score smallint(5) unsigned,
+lsg char(40),
+date date
+);
+INSERT INTO t1 VALUES (1,1,1,'','0000-00-00');
+INSERT INTO t1 VALUES (2,2,2,'','0000-00-00');
+INSERT INTO t1 VALUES (2,1,1,'','0000-00-00');
+INSERT INTO t1 VALUES (3,3,3,'','0000-00-00');
+CREATE TABLE t2 (
+userID int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
+niName char(15),
+passwd char(8),
+mail char(50),
+isAukt enum('N','Y') DEFAULT 'N',
+vName char(30),
+nName char(40),
+adr char(60),
+plz char(5),
+ort char(35),
+land char(20),
+PRIMARY KEY (userID)
+);
+INSERT INTO t2 VALUES (1,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (2,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (3,'name','pass','mail','Y','v','n','adr','1','1','1');
+SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid;
userid MIN(t1.score)
1 1
2 2
3 3
+SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid;
userid MIN(t1.score)
1 1
2 2
+SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid;
userid MIN(t1.score+0.0)
1 1.0
2 2.0
+drop table test.t1,test.t2;
+CREATE TABLE t1 (
+PID int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
+payDate date DEFAULT '0000-00-00' NOT NULL,
+recDate datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+URID int(10) unsigned DEFAULT '0' NOT NULL,
+CRID int(10) unsigned DEFAULT '0' NOT NULL,
+amount int(10) unsigned DEFAULT '0' NOT NULL,
+operator int(10) unsigned,
+method enum('unknown','cash','dealer','check','card','lazy','delayed','test') DEFAULT 'unknown' NOT NULL,
+DIID int(10) unsigned,
+reason char(1) binary DEFAULT '' NOT NULL,
+code_id int(10) unsigned,
+qty mediumint(8) unsigned DEFAULT '0' NOT NULL,
+PRIMARY KEY (PID),
+KEY URID (URID),
+KEY reason (reason),
+KEY method (method),
+KEY payDate (payDate)
+);
+INSERT INTO t1 VALUES (1,'1970-01-01','1997-10-17 00:00:00',2529,1,21000,11886,'check',0,'F',16200,6);
+SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew;
+Can't group on 'IsNew'
+drop table t1;
+CREATE TABLE t1 (
+cid mediumint(9) DEFAULT '0' NOT NULL auto_increment,
+firstname varchar(32) DEFAULT '' NOT NULL,
+surname varchar(32) DEFAULT '' NOT NULL,
+PRIMARY KEY (cid)
+);
+INSERT INTO t1 VALUES (1,'That','Guy');
+INSERT INTO t1 VALUES (2,'Another','Gent');
+CREATE TABLE t2 (
+call_id mediumint(8) DEFAULT '0' NOT NULL auto_increment,
+contact_id mediumint(8) DEFAULT '0' NOT NULL,
+PRIMARY KEY (call_id),
+KEY contact_id (contact_id)
+);
+lock tables t1 read,t2 write;
+INSERT INTO t2 VALUES (10,2);
+INSERT INTO t2 VALUES (18,2);
+INSERT INTO t2 VALUES (62,2);
+INSERT INTO t2 VALUES (91,2);
+INSERT INTO t2 VALUES (92,2);
+SELECT cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid;
cid CONCAT(firstname, ' ', surname) COUNT(call_id)
+SELECT HIGH_PRIORITY cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY surname, firstname;
cid CONCAT(firstname, ' ', surname) COUNT(call_id)
+drop table t1,t2;
+unlock tables;
+CREATE TABLE t1 (
+bug_id mediumint(9) DEFAULT '0' NOT NULL auto_increment,
+groupset bigint(20) DEFAULT '0' NOT NULL,
+assigned_to mediumint(9) DEFAULT '0' NOT NULL,
+bug_file_loc text,
+bug_severity enum('blocker','critical','major','normal','minor','trivial','enhancement') DEFAULT 'blocker' NOT NULL,
+bug_status enum('NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED') DEFAULT 'NEW' NOT NULL,
+creation_ts datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+delta_ts timestamp(14),
+short_desc mediumtext,
+long_desc mediumtext,
+op_sys enum('All','Windows 3.1','Windows 95','Windows 98','Windows NT','Windows 2000','Linux','other') DEFAULT 'All' NOT NULL,
+priority enum('P1','P2','P3','P4','P5') DEFAULT 'P1' NOT NULL,
+product varchar(64) DEFAULT '' NOT NULL,
+rep_platform enum('All','PC','VTD-8','Other'),
+reporter mediumint(9) DEFAULT '0' NOT NULL,
+version varchar(16) DEFAULT '' NOT NULL,
+component varchar(50) DEFAULT '' NOT NULL,
+resolution enum('','FIXED','INVALID','WONTFIX','LATER','REMIND','DUPLICATE','WORKSFORME') DEFAULT '' NOT NULL,
+target_milestone varchar(20) DEFAULT '' NOT NULL,
+qa_contact mediumint(9) DEFAULT '0' NOT NULL,
+status_whiteboard mediumtext NOT NULL,
+votes mediumint(9) DEFAULT '0' NOT NULL,
+PRIMARY KEY (bug_id),
+KEY assigned_to (assigned_to),
+KEY creation_ts (creation_ts),
+KEY delta_ts (delta_ts),
+KEY bug_severity (bug_severity),
+KEY bug_status (bug_status),
+KEY op_sys (op_sys),
+KEY priority (priority),
+KEY product (product),
+KEY reporter (reporter),
+KEY version (version),
+KEY component (component),
+KEY resolution (resolution),
+KEY target_milestone (target_milestone),
+KEY qa_contact (qa_contact),
+KEY votes (votes)
+);
+INSERT INTO t1 VALUES (1,0,0,'','normal','','2000-02-10 09:25:12',20000321114747,'','','Linux','P1','TestProduct','PC',3,'other','TestComponent','','M1',0,'',0);
+INSERT INTO t1 VALUES (9,0,0,'','enhancement','','2000-03-10 11:49:36',20000321114747,'','','All','P5','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - conversion','','',0,'',0);
+INSERT INTO t1 VALUES (10,0,0,'','enhancement','','2000-03-10 18:10:16',20000321114747,'','','All','P4','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - conversion','','',0,'',0);
+INSERT INTO t1 VALUES (7,0,0,'','critical','','2000-03-09 10:50:21',20000321114747,'','','All','P1','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - generic','','',0,'',0);
+INSERT INTO t1 VALUES (6,0,0,'','normal','','2000-03-09 10:42:44',20000321114747,'','','All','P2','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0);
+INSERT INTO t1 VALUES (8,0,0,'','major','','2000-03-09 11:32:14',20000321114747,'','','All','P3','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0);
+INSERT INTO t1 VALUES (5,0,0,'','enhancement','','2000-03-09 10:38:59',20000321114747,'','','All','P5','CCC/CCCCCC','PC',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (4,0,0,'','normal','','2000-03-08 18:32:14',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent2','','',0,'',0);
+INSERT INTO t1 VALUES (3,0,0,'','normal','','2000-03-08 18:30:52',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent','','',0,'',0);
+INSERT INTO t1 VALUES (2,0,0,'','enhancement','','2000-03-08 18:24:51',20000321114747,'','','All','P2','TestProduct','Other',4,'other','TestComponent2','','',0,'',0);
+INSERT INTO t1 VALUES (11,0,0,'','blocker','','2000-03-13 09:43:41',20000321114747,'','','All','P2','CCC/CCCCCC','PC',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (12,0,0,'','normal','','2000-03-13 16:14:31',20000321114747,'','','All','P2','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0);
+INSERT INTO t1 VALUES (13,0,0,'','normal','','2000-03-15 16:20:44',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent','','',0,'',0);
+INSERT INTO t1 VALUES (14,0,0,'','blocker','','2000-03-15 18:13:47',20000321114747,'','','All','P1','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - generic','','',0,'',0);
+INSERT INTO t1 VALUES (15,0,0,'','minor','','2000-03-16 18:03:28',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (16,0,0,'','normal','','2000-03-16 18:33:41',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (17,0,0,'','normal','','2000-03-16 18:34:18',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (18,0,0,'','normal','','2000-03-16 18:34:56',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (19,0,0,'','enhancement','','2000-03-16 18:35:34',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (20,0,0,'','enhancement','','2000-03-16 18:36:23',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (21,0,0,'','enhancement','','2000-03-16 18:37:23',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (22,0,0,'','enhancement','','2000-03-16 18:38:16',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (23,0,0,'','normal','','2000-03-16 18:58:12',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (24,0,0,'','normal','','2000-03-17 11:08:10',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+INSERT INTO t1 VALUES (25,0,0,'','normal','','2000-03-17 11:10:45',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+INSERT INTO t1 VALUES (26,0,0,'','normal','','2000-03-17 11:15:47',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+INSERT INTO t1 VALUES (27,0,0,'','normal','','2000-03-17 17:45:41',20000321114747,'','','All','P2','CCC/CCCCCC','PC',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (28,0,0,'','normal','','2000-03-20 09:51:45',20000321114747,'','','Windows NT','P2','TestProduct','PC',8,'other','TestComponent','','',0,'',0);
+INSERT INTO t1 VALUES (29,0,0,'','normal','','2000-03-20 11:15:09',20000321114747,'','','All','P5','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+CREATE TABLE t2 (
+value tinytext,
+program varchar(64),
+initialowner tinytext NOT NULL,
+initialqacontact tinytext NOT NULL,
+description mediumtext NOT NULL
+);
+INSERT INTO t2 VALUES ('TestComponent','TestProduct','id0001','','');
+INSERT INTO t2 VALUES ('BBBBBBBBBBBBB - conversion','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('BBBBBBBBBBBBB - generic','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('TestComponent2','TestProduct','id0001','','');
+INSERT INTO t2 VALUES ('BBBBBBBBBBBBB - eeeeeeeee','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('kkkkkkkkkkk lllllllllll','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('Test Procedures','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('Documentation','AAAAA','id0003','','');
+INSERT INTO t2 VALUES ('DDDDDDDDD','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Eeeeeeee Lite','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Eeeeeeee Full','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Administration','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Distribution','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Setup','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Unspecified','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Web Interface','AAAAAAAA-AAA','id0001','','');
+INSERT INTO t2 VALUES ('Host communication','AAAAA','id0001','','');
+select value,description,bug_id from t2 left join t1 on t2.program=t1.product and t2.value=t1.component where program="AAAAA";
value description bug_id
BBBBBBBBBBBBB - conversion 9
BBBBBBBBBBBBB - conversion 10
@@ -22,6 +196,7 @@ kkkkkkkkkkk lllllllllll 12
Test Procedures NULL
Documentation NULL
Host communication NULL
+select value,description,COUNT(bug_id) from t2 left join t1 on t2.program=t1.product and t2.value=t1.component where program="AAAAA" group by value;
value description COUNT(bug_id)
BBBBBBBBBBBBB - conversion 2
BBBBBBBBBBBBB - eeeeeeeee 0
@@ -30,41 +205,193 @@ Documentation 0
Host communication 0
kkkkkkkkkkk lllllllllll 3
Test Procedures 0
+drop table t1,t2;
+create table t1 (foo int);
+insert into t1 values (1);
+select 1+1, "a",count(*) from t1 where foo in (2);
1+1 a count(*)
2 a 0
+insert into t1 values (1);
+select 1+1,"a",count(*) from t1 where foo in (2);
1+1 a count(*)
2 a 0
+drop table t1;
+CREATE TABLE t1 (
+spID int(10) unsigned,
+userID int(10) unsigned,
+score smallint(5) unsigned,
+key (spid),
+key (score)
+);
+INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3);
+explain select userid,count(*) from t1 group by userid desc;
table type possible_keys key key_len ref rows Extra
-t1 ALL NULL NULL NULL NULL 6 Using temporary
+t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+select userid,count(*) from t1 group by userid desc;
userid count(*)
3 3
2 1
1 2
+explain select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
table type possible_keys key key_len ref rows Extra
-t1 range spID spID 5 NULL 2 where used; Using index; Using temporary
+t1 range spID spID 5 NULL 2 where used; Using index
+explain select spid,count(*) from t1 where spid between 1 and 2 group by spid;
table type possible_keys key key_len ref rows Extra
t1 range spID spID 5 NULL 2 where used; Using index
+select spid,count(*) from t1 where spid between 1 and 2 group by spid;
spid count(*)
1 1
2 2
+select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
spid count(*)
2 2
1 1
+explain select sql_big_result spid,sum(userid) from t1 group by spid desc;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 6 Using filesort
+select sql_big_result spid,sum(userid) from t1 group by spid desc;
spid sum(userid)
5 3
4 3
3 3
2 3
1 1
+explain select sql_big_result score,count(*) from t1 group by score desc;
table type possible_keys key key_len ref rows Extra
t1 index NULL score 3 NULL 6 Using index
+select sql_big_result score,count(*) from t1 group by score desc;
score count(*)
3 3
2 1
1 2
+drop table t1;
+CREATE TABLE t1 (a char(1));
+INSERT INTO t1 VALUES ('A'),('B'),('A'),('B'),('A'),('B'),(NULL),('a'),('b'),(NULL),('A'),('B'),(NULL);
+SELECT a FROM t1 GROUP BY a;
+a
+NULL
+A
+B
+SELECT a,count(*) FROM t1 GROUP BY a;
+a count(*)
+NULL 3
+A 5
+B 5
+SELECT a FROM t1 GROUP BY binary a;
+a
+NULL
+A
+B
+a
+b
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SELECT binary a FROM t1 GROUP BY 1;
+binary a
+NULL
+A
+B
+a
+b
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+binary a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SET SQL_BIG_TABLES=1;
+SELECT a FROM t1 GROUP BY a;
+a
+NULL
+A
+B
+SELECT a,count(*) FROM t1 GROUP BY a;
+a count(*)
+NULL 3
+A 5
+B 5
+SELECT a FROM t1 GROUP BY binary a;
+a
+NULL
+A
+B
+a
+b
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SELECT binary a FROM t1 GROUP BY 1;
+binary a
+NULL
+A
+B
+a
+b
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+binary a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SET SQL_BIG_TABLES=0;
+drop table t1;
+CREATE TABLE t1 (
+`a` char(193) default NULL,
+`b` char(63) default NULL
+);
+INSERT INTO t1 VALUES ('abc','def'),('hij','klm');
+SELECT CONCAT(a, b) FROM t1 GROUP BY 1;
+CONCAT(a, b)
+abcdef
+hijklm
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+CONCAT(a, b) count(*)
+abcdef 1
+hijklm 1
+SELECT CONCAT(a, b),count(distinct a) FROM t1 GROUP BY 1;
+CONCAT(a, b) count(distinct a)
+abcdef 1
+hijklm 1
+SELECT 1 FROM t1 GROUP BY CONCAT(a, b);
+1
+1
+1
+INSERT INTO t1 values ('hij','klm');
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+CONCAT(a, b) count(*)
+abcdef 1
+hijklm 2
+DROP TABLE t1;
+drop table if exists t1;
+create table t1 (One int unsigned, Two int unsigned, Three int unsigned, Four int unsigned);
+insert into t1 values (1,2,1,4),(1,2,2,4),(1,2,3,4),(1,2,4,4),(1,1,1,4),(1,1,2,4),(1,1,3,4),(1,1,4,4),(1,3,1,4),(1,3,2,4),(1,3,3,4),(1,3,4,4);
+select One, Two, sum(Four) from t1 group by One,Two;
One Two sum(Four)
1 1 16
1 2 16
1 3 16
+drop table t1;
+create table t1 (id integer primary key not null auto_increment, gender char(1));
+insert into t1 values (NULL, 'M'), (NULL, 'F'),(NULL, 'F'),(NULL, 'F'),(NULL, 'M');
+create table t2 (user_id integer not null, date date);
+insert into t2 values (1, '2002-06-09'),(2, '2002-06-09'),(1, '2002-06-09'),(3, '2002-06-09'),(4, '2002-06-09'),(4, '2002-06-09');
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender;
+gender dist_count percentage
+F 3 60.00
+M 1 20.00
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender order by percentage;
+gender dist_count percentage
+M 1 20.00
+F 3 60.00
+drop table t1,t2;
diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result
new file mode 100644
index 00000000000..d495dde75bf
--- /dev/null
+++ b/mysql-test/r/handler.result
@@ -0,0 +1,139 @@
+drop table if exists t1;
+create table t1 (a int, b char(10), key a(a), key b(a,b));
+insert into t1 values
+(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
+(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
+(20,"ggg"),(21,"hhh"),(22,"iii");
+handler t1 open as t2;
+handler t2 read a first;
+a b
+14 aaa
+handler t2 read a next;
+a b
+15 bbb
+handler t2 read a next;
+a b
+16 ccc
+handler t2 read a prev;
+a b
+15 bbb
+handler t2 read a last;
+a b
+22 iii
+handler t2 read a prev;
+a b
+21 hhh
+handler t2 read a prev;
+a b
+20 ggg
+handler t2 read a first;
+a b
+14 aaa
+handler t2 read a prev;
+a b
+handler t2 read a last;
+a b
+22 iii
+handler t2 read a prev;
+a b
+21 hhh
+handler t2 read a next;
+a b
+22 iii
+handler t2 read a next;
+a b
+handler t2 read a=(15);
+a b
+15 bbb
+handler t2 read a=(16);
+a b
+16 ccc
+handler t2 read a=(19,"fff");
+Too many key parts specified. Max 1 parts allowed
+handler t2 read b=(19,"fff");
+a b
+19 fff
+handler t2 read b=(19,"yyy");
+a b
+19 yyy
+handler t2 read b=(19);
+a b
+19 fff
+handler t1 read a last;
+Unknown table 't1' in HANDLER
+handler t2 read a=(11);
+a b
+handler t2 read a>=(11);
+a b
+14 aaa
+handler t2 read a=(18);
+a b
+18 eee
+handler t2 read a>=(18);
+a b
+18 eee
+handler t2 read a>(18);
+a b
+19 fff
+handler t2 read a<=(18);
+a b
+18 eee
+handler t2 read a<(18);
+a b
+17 ddd
+handler t2 read a first limit 5;
+a b
+14 aaa
+15 bbb
+16 ccc
+16 xxx
+17 ddd
+handler t2 read a next limit 3;
+a b
+18 eee
+19 fff
+19 yyy
+handler t2 read a prev limit 10;
+a b
+19 fff
+18 eee
+17 ddd
+16 xxx
+16 ccc
+15 bbb
+14 aaa
+handler t2 read a>=(16) limit 4;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+handler t2 read a>=(16) limit 2,2;
+a b
+17 ddd
+18 eee
+handler t2 read a last limit 3;
+a b
+22 iii
+21 hhh
+20 ggg
+handler t2 read a=(19);
+a b
+19 fff
+handler t2 read a=(19) where b="yyy";
+a b
+19 yyy
+handler t2 read first;
+a b
+17 ddd
+handler t2 read next;
+a b
+18 eee
+alter table t1 type=MyISAM;
+handler t2 read next;
+a b
+19 fff
+handler t2 read last;
+You have an error in your SQL syntax near '' at line 1
+handler t2 close;
+drop table if exists t1;
diff --git a/mysql-test/r/have_gemini.require b/mysql-test/r/have_gemini.require
deleted file mode 100644
index 0ffe0e40d3b..00000000000
--- a/mysql-test/r/have_gemini.require
+++ /dev/null
@@ -1,2 +0,0 @@
-Variable_name Value
-have_gemini YES
diff --git a/mysql-test/r/have_openssl.require b/mysql-test/r/have_openssl.require
new file mode 100644
index 00000000000..dae48a472b5
--- /dev/null
+++ b/mysql-test/r/have_openssl.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_openssl YES
diff --git a/mysql-test/r/have_openssl_1.require b/mysql-test/r/have_openssl_1.require
new file mode 100644
index 00000000000..dae48a472b5
--- /dev/null
+++ b/mysql-test/r/have_openssl_1.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_openssl YES
diff --git a/mysql-test/r/have_openssl_2.require b/mysql-test/r/have_openssl_2.require
new file mode 100644
index 00000000000..09a65d7d9bc
--- /dev/null
+++ b/mysql-test/r/have_openssl_2.require
@@ -0,0 +1,2 @@
+Variable_name Value
+jkhjkhfs
diff --git a/mysql-test/r/have_query_cache.require b/mysql-test/r/have_query_cache.require
new file mode 100644
index 00000000000..312d837fed3
--- /dev/null
+++ b/mysql-test/r/have_query_cache.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_query_cache YES
diff --git a/mysql-test/r/have_symlink.require b/mysql-test/r/have_symlink.require
new file mode 100644
index 00000000000..55ad9437034
--- /dev/null
+++ b/mysql-test/r/have_symlink.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_symlink YES
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index 69943c505f0..a33ce457176 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -1,6 +1,65 @@
+drop table if exists t1,t2;
+create table t1 (a int);
+select count(a) as b from t1 where a=0 having b > 0;
b
+insert into t1 values (null);
+select count(a) as b from t1 where a=0 having b > 0;
b
+select count(a) as b from t1 where a=0 having b >=0;
b
0
+drop table t1;
+CREATE TABLE t1 (
+raw_id int(10) NOT NULL default '0',
+chr_start int(10) NOT NULL default '0',
+chr_end int(10) NOT NULL default '0',
+raw_start int(10) NOT NULL default '0',
+raw_end int(10) NOT NULL default '0',
+raw_ori int(2) NOT NULL default '0'
+);
+INSERT INTO t1 VALUES (469713,1,164123,1,164123,1),(317330,164124,317193,101,153170,1),(469434,317194,375620,101,58527,1),(591816,375621,484273,1,108653,1),(591807,484274,534671,91,50488,1),(318885,534672,649362,101,114791,1),(318728,649363,775520,102,126259,1),(336829,775521,813997,101,38577,1),(317740,813998,953227,101,139330,1),(1,813998,953227,101,139330,1);
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL default '0',
+contig_id int(10) unsigned NOT NULL default '0',
+seq_start int(10) NOT NULL default '0',
+seq_end int(10) NOT NULL default '0',
+strand tinyint(2) NOT NULL default '0',
+KEY id (id)
+);
+INSERT INTO t2 VALUES (133195,469713,61327,61384,1),(133196,469713,64113,64387,1),(133197,1,1,1,0),(133197,1,1,1,-2);
+SELECT e.id,
+MIN( IF(sgp.raw_ori=1,
+(e.seq_start+sgp.chr_start-sgp.raw_start),
+(sgp.chr_start+sgp.raw_end-e.seq_end))) as start,
+MAX( IF(sgp.raw_ori=1,
+(e.seq_end+sgp.chr_start-sgp.raw_start),
+(sgp.chr_start+sgp.raw_end-e.seq_start))) as end,
+AVG(IF (sgp.raw_ori=1,e.strand,(-e.strand))) as chr_strand
+FROM t1 sgp,
+t2 e
+WHERE sgp.raw_id=e.contig_id
+GROUP BY e.id
+HAVING chr_strand= -1 and end >= 0
+AND start <= 999660;
id start end chr_strand
133197 813898 813898 -1.0000
+drop table t1,t2;
+CREATE TABLE t1 (Fld1 int(11) default NULL,Fld2 int(11) default NULL);
+INSERT INTO t1 VALUES (1,10),(1,20),(2,NULL),(2,NULL),(3,50);
+select Fld1, max(Fld2) as q from t1 group by Fld1 having q is not null;
+Fld1 q
+1 20
+3 50
+select Fld1, max(Fld2) from t1 group by Fld1 having max(Fld2) is not null;
+Fld1 max(Fld2)
+1 20
+3 50
+select Fld1, max(Fld2) from t1 group by Fld1 having avg(Fld2) is not null;
+Fld1 max(Fld2)
+1 20
+3 50
+select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null;
+Fld1 max(Fld2)
+1 20
+3 50
+drop table t1;
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index d3d16128ebd..13f452e26d8 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -1,41 +1,81 @@
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a NULL NULL NULL NULL
+drop table if exists t1;
+create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps" avg_row_length=100 min_rows=1 max_rows=100;
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
+delete from t1 where a=1 or a=0;
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a NULL NULL NULL NULL HASH
+select * from t1;
a b
2 2
3 3
4 4
+select * from t1 where a=4;
a b
4 4
+update t1 set b=5 where a=4;
+update t1 set b=b+1 where a>=3;
+replace t1 values (3,3);
+select * from t1;
a b
2 2
3 3
4 6
+alter table t1 add c int not null, add key (c,a);
+drop table t1;
+create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps";
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
+delete from t1 where a > 0;
+select * from t1;
+a b
+drop table t1;
+create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps";
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
+alter table t1 modify a int not null auto_increment, type=myisam, comment="new myisam table";
+select * from t1;
a b
1 1
2 2
3 3
4 4
+drop table t1;
+create table t1 (a int not null) type=heap;
+insert into t1 values (869751),(736494),(226312),(802616);
+select * from t1 where a > 736494;
a
869751
802616
+alter table t1 add unique uniq_id(a);
+select * from t1 where a > 736494;
a
869751
802616
+select * from t1 where a = 736494;
a
736494
+select * from t1 where a=869751 or a=736494;
a
736494
869751
+select * from t1 where a in (869751,736494,226312,802616);
a
226312
736494
802616
869751
+alter table t1 type=myisam;
+explain select * from t1 where a in (869751,736494,226312,802616);
table type possible_keys key key_len ref rows Extra
t1 range uniq_id uniq_id 4 NULL 4 where used; Using index
+drop table t1;
+create table t1 (x int not null, y int not null, key x(x), unique y(y))
+type=heap;
+insert into t1 values (1,1),(2,2),(1,3),(2,4),(2,5),(2,6);
+select * from t1 where x=1;
x y
1 3
1 1
+select * from t1,t1 as t2 where t1.x=t2.y;
x y x y
1 1 1 1
2 2 2 2
@@ -43,11 +83,20 @@ x y x y
2 4 2 2
2 5 2 2
2 6 2 2
+explain select * from t1,t1 as t2 where t1.x=t2.y;
table type possible_keys key key_len ref rows Extra
t1 ALL x NULL NULL NULL 6
t2 eq_ref y y 4 t1.x 1
+drop table t1;
+create table t1 (a int) type=heap;
+insert into t1 values(1);
+select max(a) from t1;
max(a)
1
+drop table t1;
+CREATE TABLE t1 ( a int not null default 0, b int not null default 0, key(a), key(b) ) TYPE=HEAP;
+insert into t1 values(1,1),(1,2),(2,3),(1,3),(1,4),(1,5),(1,6);
+select * from t1 where a=1;
a b
1 6
1 5
@@ -55,6 +104,8 @@ a b
1 3
1 2
1 1
+insert into t1 values(1,1),(1,2),(2,3),(1,3),(1,4),(1,5),(1,6);
+select * from t1 where a=1;
a b
1 6
1 5
@@ -68,20 +119,87 @@ a b
1 3
1 2
1 1
+drop table t1;
+create table t1 (id int unsigned not null, primary key (id)) type=HEAP;
+insert into t1 values(1);
+select max(id) from t1;
max(id)
1
+insert into t1 values(2);
+select max(id) from t1;
max(id)
2
+replace into t1 values(1);
+drop table t1;
+create table t1 (n int) type=heap;
+drop table t1;
+create table t1 (n int) type=heap;
+drop table if exists t1;
+CREATE table t1(f1 int not null,f2 char(20) not
+null,index(f2)) type=heap;
+INSERT into t1 set f1=12,f2="bill";
+INSERT into t1 set f1=13,f2="bill";
+INSERT into t1 set f1=14,f2="bill";
+INSERT into t1 set f1=15,f2="bill";
+INSERT into t1 set f1=16,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+delete from t1 where f2="bill";
+select * from t1;
f1 f2
16 ted
12 ted
12 ted
12 ted
12 ted
+drop table t1;
+create table t1 (btn char(10) not null, key(btn)) type=heap;
+insert into t1 values ("hello"),("hello"),("hello"),("hello"),("hello"),("a"),("b"),("c"),("d"),("e"),("f"),("g"),("h"),("i");
+explain select * from t1 where btn like "q%";
table type possible_keys key key_len ref rows Extra
t1 ALL btn NULL NULL NULL 14 where used
+select * from t1 where btn like "q%";
btn
+alter table t1 add column new_col char(1) not null, add key (btn,new_col), drop key btn;
+update t1 set new_col=btn;
+explain select * from t1 where btn="a";
table type possible_keys key key_len ref rows Extra
t1 ALL btn NULL NULL NULL 14 where used
+explain select * from t1 where btn="a" and new_col="a";
table type possible_keys key key_len ref rows Extra
t1 ref btn btn 11 const,const 10 where used
+drop table t1;
+CREATE TABLE t1 (
+a int default NULL,
+b int default NULL,
+KEY a (a),
+UNIQUE b (b)
+) type=heap;
+INSERT INTO t1 VALUES (NULL,99),(99,NULL),(1,1),(2,2),(1,3);
+SELECT * FROM t1 WHERE a=NULL;
+a b
+explain SELECT * FROM t1 WHERE a IS NULL;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 5 const 10 where used
+SELECT * FROM t1 WHERE a<=>NULL;
+a b
+NULL 99
+SELECT * FROM t1 WHERE b=NULL;
+a b
+explain SELECT * FROM t1 WHERE b IS NULL;
+table type possible_keys key key_len ref rows Extra
+t1 ref b b 5 const 1 where used
+SELECT * FROM t1 WHERE b<=>NULL;
+a b
+99 NULL
+INSERT INTO t1 VALUES (1,3);
+Duplicate entry '3' for key 1
+DROP TABLE t1;
+CREATE TABLE t1 (a int not null, primary key(a)) type=heap;
+INSERT into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11);
+DELETE from t1 where a < 100;
+SELECT * from t1;
+a
+DROP TABLE t1;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 0930e3aa5fd..89a857ef098 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1,3 +1,7 @@
+drop table if exists t1,t2;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb;
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
id code name
1 1 Tim
2 1 Monty
@@ -6,6 +10,8 @@ id code name
5 3 Sasha
6 3 Jeremy
7 4 Matt
+update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
+select id, code, name from t1 order by id;
id code name
2 1 Monty
3 2 David
@@ -14,6 +20,8 @@ id code name
6 3 Jeremy
7 4 Matt
8 1 Sinisa
+update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
+select id, code, name from t1 order by id;
id code name
3 2 David
4 2 Erik
@@ -22,10 +30,26 @@ id code name
7 4 Matt
8 1 Sinisa
12 1 Ralph
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+Got one of the listed errors
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -66,6 +90,8 @@ id parent_id level
1193 105 2
1202 107 2
1203 107 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -106,16 +132,22 @@ id parent_id level
1194 105 2
1202 107 2
1204 107 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
id parent_id level
1008 102 2
1010 102 2
1015 102 2
+explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 12 where used; Using index
+explain select level,id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 12 where used; Using index
+explain select level,id,parent_id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 12 where used
+select level,id from t1 where level=1;
level id
1 1002
1 1003
@@ -123,6 +155,7 @@ level id
1 1005
1 1006
1 1007
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1002 101
1 1003 101
@@ -130,142 +163,350 @@ level id parent_id
1 1005 101
1 1006 101
1 1007 101
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support check/repair
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 id A 87 NULL NULL
-t1 1 parent_id 1 parent_id A 43 NULL NULL
-t1 1 level 1 level A 6 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 id A 87 NULL NULL BTREE
+t1 1 parent_id 1 parent_id A 43 NULL NULL BTREE
+t1 1 level 1 level A 6 NULL NULL BTREE
+drop table t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) type=innodb;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+select * from t1;
gesuchnr benutzer_id
1 1
2 1
+drop table t1;
+create table t1 (a int) type=innodb;
+insert into t1 values (1), (2);
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support check/repair
+delete from t1 where a = 1;
+select * from t1;
a
2
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+create table t1 (a int,b varchar(20)) type=innodb;
+insert into t1 values (1,""), (2,"testing");
+delete from t1 where a = 1;
+select * from t1;
a b
2 testing
+create index skr on t1 (a);
+insert into t1 values (3,""), (4,"testing");
+analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze error The handler for the table doesn't support check/repair
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 1 skr 1 a A 3 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 skr 1 a A 3 NULL NULL YES BTREE
+drop table t1;
+create table t1 (a int,b varchar(20),key(a)) type=innodb;
+insert into t1 values (1,""), (2,"testing");
+select * from t1 where a = 1;
a b
1
+drop table t1;
+create table t1 (n int not null primary key) type=innodb;
+set autocommit=0;
+insert into t1 values (4);
+rollback;
+select n, "after rollback" from t1;
n after rollback
+insert into t1 values (4);
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
+commit;
+insert into t1 values (5);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
5 after commit
+set autocommit=1;
+insert into t1 values (6);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+select n from t1;
n
4
5
6
+rollback;
+drop table t1;
+create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) type=innodb;
+begin;
+insert into t1 values(1,'hamdouni');
+select id as afterbegin_id,nom as afterbegin_nom from t1;
afterbegin_id afterbegin_nom
1 hamdouni
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=0;
+insert into t1 values(2,'mysql');
+select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
afterautocommit0_id afterautocommit0_nom
2 mysql
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=1;
+drop table t1;
+CREATE TABLE t1 (id char(8) not null primary key, val int not null) type=innodb;
+insert into t1 values ('pippo', 12);
+insert into t1 values ('pippo', 12);
+Duplicate entry 'pippo' for key 1
+delete from t1;
+delete from t1 where id = 'pippo';
+select * from t1;
id val
+insert into t1 values ('pippo', 12);
+set autocommit=0;
+delete from t1;
+rollback;
+select * from t1;
id val
pippo 12
+delete from t1;
+commit;
+select * from t1;
id val
+drop table t1;
+create table t1 (a integer) type=innodb;
+begin;
+rename table t1 to t2;
+create table t1 (b integer) type=innodb;
+insert into t1 values (1);
+rollback;
+drop table t1;
+rename table t2 to t1;
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) TYPE=innodb;
+INSERT INTO t1 VALUES (1, 'Jochen');
+select * from t1;
ID NAME
1 Jochen
+drop table t1;
+CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) TYPE=innodb;
+set autocommit=0;
+INSERT INTO t1 SET _userid='marc@anyware.co.uk';
+COMMIT;
+SELECT * FROM t1;
_userid
marc@anyware.co.uk
+SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
_userid
marc@anyware.co.uk
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (
+user_id int(10) DEFAULT '0' NOT NULL,
+name varchar(100),
+phone varchar(100),
+ref_email varchar(100) DEFAULT '' NOT NULL,
+detail varchar(200),
+PRIMARY KEY (user_id,ref_email)
+)type=innodb;
+INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+select * from t1 where user_id>=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id>10292;
user_id name phone ref_email detail
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id<10292;
user_id name phone ref_email detail
10291 sanjeev 29153373 sansh777@hotmail.com xxx
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A NULL NULL NULL
-t1 0 PRIMARY 2 b A 0 NULL NULL
-t1 0 b 1 b A 0 NULL NULL
-t1 0 c 1 c A 0 NULL NULL
-t1 1 a 1 a A NULL NULL NULL
-t1 1 a_2 1 a A NULL NULL NULL
+drop table t1;
+CREATE TABLE t1 (a int not null, b int not null,c int not null,
+key(a),primary key(a,b), unique(c),key(a),unique(b));
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 b A 0 NULL NULL BTREE
+t1 0 c 1 c A 0 NULL NULL BTREE
+t1 0 b 1 b A 0 NULL NULL BTREE
+t1 1 a 1 a A NULL NULL NULL BTREE
+t1 1 a_2 1 a A NULL NULL NULL BTREE
+drop table t1;
+create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
+alter table t1 type=innodb;
+insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
+select * from t1;
col1 col2
1 1
2 3
3 4
4 4
5 2
+update t1 set col2='7' where col1='4';
+select * from t1;
col1 col2
1 1
2 3
3 4
4 7
5 2
+alter table t1 add co3 int not null;
+select * from t1;
col1 col2 co3
1 1 0
2 3 0
3 4 0
4 7 0
5 2 0
+update t1 set col2='9' where col1='2';
+select * from t1;
col1 col2 co3
1 1 0
2 9 0
3 4 0
4 7 0
5 2 0
+drop table t1;
+create table t1 (a int not null , b int, primary key (a)) type = innodb;
+create table t2 (a int not null , b int, primary key (a)) type = myisam;
+insert into t1 VALUES (1,3) , (2,3), (3,3);
+select * from t1;
a b
1 3
2 3
3 3
+insert into t2 select * from t1;
+select * from t2;
a b
1 3
2 3
3 3
+delete from t1 where b = 3;
+select * from t1;
a b
+insert into t1 select * from t2;
+select * from t1;
a b
1 3
2 3
3 3
+select * from t2;
a b
1 3
2 3
3 3
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+ggid varchar(32) binary DEFAULT '' NOT NULL,
+email varchar(64) DEFAULT '' NOT NULL,
+passwd varchar(32) binary DEFAULT '' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE ggid (ggid)
+) TYPE=innodb;
+insert into t1 (ggid,passwd) values ('test1','xxx');
+insert into t1 (ggid,passwd) values ('test2','yyy');
+insert into t1 (ggid,passwd) values ('test2','this will fail');
+Duplicate entry 'test2' for key 2
+insert into t1 (ggid,id) values ('this will fail',1);
+Duplicate entry '1' for key 1
+select * from t1 where ggid='test1';
id ggid email passwd
1 test1 xxx
+select * from t1 where passwd='xxx';
id ggid email passwd
1 test1 xxx
+select * from t1 where id=2;
id ggid email passwd
2 test2 yyy
+replace into t1 (ggid,id) values ('this will work',1);
+replace into t1 (ggid,passwd) values ('test2','this will work');
+update t1 set id=100,ggid='test2' where id=1;
+Duplicate entry 'test2' for key 2
+select * from t1;
id ggid email passwd
1 this will work
4 test2 this will work
+select * from t1 where id=1;
id ggid email passwd
1 this will work
+select * from t1 where id=999;
id ggid email passwd
+drop table t1;
+CREATE TABLE t1 (
+user_name varchar(12),
+password text,
+subscribed char(1),
+user_id int(11) DEFAULT '0' NOT NULL,
+quota bigint(20),
+weight double,
+access_date date,
+access_time time,
+approved datetime,
+dummy_primary_key int(11) NOT NULL auto_increment,
+PRIMARY KEY (dummy_primary_key)
+) TYPE=innodb;
+INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
+INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
+INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
+INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
+INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
+select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
user_name password subscribed user_id quota weight access_date access_time approved dummy_primary_key
user_0 somepassword N 0 0 0 2000-09-07 23:06:59 2000-09-07 23:06:59 1
user_1 somepassword Y 1 1 1 2000-09-07 23:06:59 2000-09-07 23:06:59 2
user_2 somepassword N 2 2 1.4142135623731 2000-09-07 23:06:59 2000-09-07 23:06:59 3
user_3 somepassword Y 3 3 1.7320508075689 2000-09-07 23:06:59 2000-09-07 23:06:59 4
user_4 somepassword N 4 4 2 2000-09-07 23:06:59 2000-09-07 23:06:59 5
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
+INSERT INTO t1 values (179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+select * from t1;
id parent_id level
1001 100 0
1003 101 1
@@ -306,6 +547,8 @@ id parent_id level
1019 103 2
1005 101 1
1179 105 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1002 100 0
1004 101 1
@@ -346,12 +589,16 @@ id parent_id level
1020 103 2
1006 101 1
1180 105 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
id parent_id level
1009 102 2
1025 102 2
1016 102 2
+explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 6 where used; Using index
+select level,id from t1 where level=1;
level id
1 1004
1 1005
@@ -359,6 +606,7 @@ level id
1 1007
1 1008
1 1006
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1004 101
1 1005 101
@@ -366,6 +614,7 @@ level id parent_id
1 1007 101
1 1008 101
1 1006 101
+select level,id from t1 where level=1 order by id;
level id
1 1003
1 1004
@@ -373,6 +622,8 @@ level id
1 1006
1 1007
1 1008
+delete from t1 where level=1;
+select * from t1;
id parent_id level
1002 100 0
1009 102 2
@@ -407,97 +658,334 @@ id parent_id level
1022 104 2
1020 103 2
1180 105 2
+drop table t1;
+CREATE TABLE t1 (
+sca_code char(6) NOT NULL,
+cat_code char(6) NOT NULL,
+sca_desc varchar(50),
+lan_code char(2) NOT NULL,
+sca_pic varchar(100),
+sca_sdesc varchar(50),
+sca_sch_desc varchar(16),
+PRIMARY KEY (sca_code, cat_code, lan_code),
+INDEX sca_pic (sca_pic)
+) type = innodb ;
+INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'N', 'RING', 'EN', 'not null', NULL, 'RING');
+select count(*) from t1 where sca_code = 'PD';
count(*)
1
+select count(*) from t1 where sca_code <= 'PD';
count(*)
1
+select count(*) from t1 where sca_pic is null;
count(*)
2
+alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where cat_code='E';
count(*)
0
+alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where sca_pic >= 'n';
count(*)
1
+select sca_pic from t1 where sca_pic is null;
sca_pic
NULL
NULL
+update t1 set sca_pic="test" where sca_pic is null;
+delete from t1 where sca_code='pd';
+drop table t1;
+set @a:=now();
+CREATE TABLE t1 (a int not null, b timestamp not null, primary key (a)) type=innodb;
+insert into t1 (a) values(1),(2),(3);
+select t1.a from t1 natural join t1 as t2 where t1.b >= @a order by t1.a;
a
1
2
3
+update t1 set a=5 where a=1;
+select a from t1;
a
2
3
5
+drop table t1;
+create table t1 (a varchar(100) not null, primary key(a), b int not null) type=innodb;
+insert into t1 values("hello",1),("world",2);
+select * from t1 order by b desc;
a b
world 2
hello 1
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support check/repair
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 2 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 2 NULL NULL BTREE
+drop table t1;
+create table t1 (i int, j int ) TYPE=innodb;
+insert into t1 values (1,2);
+select * from t1 where i=1 and j=2;
i j
1 2
+create index ax1 on t1 (i,j);
+select * from t1 where i=1 and j=2;
i j
1 2
+drop table t1;
+CREATE TABLE t1 (
+a int3 unsigned NOT NULL,
+b int1 unsigned NOT NULL,
+UNIQUE (a, b)
+) TYPE = innodb;
+INSERT INTO t1 VALUES (1, 1);
+SELECT MIN(B),MAX(b) FROM t1 WHERE t1.a = 1;
MIN(B) MAX(b)
1 1
+drop table t1;
+CREATE TABLE t1 (a int unsigned NOT NULL) type=innodb;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
a
1
+DROP TABLE t1;
+create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h int, i int, j int, k int, l int, m int, n int, o int, p int, q int, r int, s int, t int, u int, v int, w int, x int, y int, z int, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int) type = innodb;
+insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+explain select * from t1 where a > 0 and a < 50;
table type possible_keys key key_len ref rows Extra
t1 range PRIMARY PRIMARY 4 NULL 1 where used
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+select id from t1;
id
0
1
2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+begin;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
+commit;
+select id,id3 from t1;
id id3
0 0
1 1
2 2
100 2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (a char(20), unique (a(5))) type=innodb;
+Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the table handler doesn't support unique sub keys
+create table t1 (a char(20), index (a(5))) type=innodb;
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(20) default NULL,
KEY `a` (`a`)
) TYPE=InnoDB
+drop table t1;
+create temporary table t1 (a int not null auto_increment, primary key(a)) type=innodb;
+insert into t1 values (NULL),(NULL),(NULL);
+delete from t1 where a=3;
+insert into t1 values (NULL);
+select * from t1;
a
1
2
4
+alter table t1 add b int;
+select * from t1;
a b
1 NULL
2 NULL
4 NULL
+drop table t1;
+create table t1
+(
+id int auto_increment primary key,
+name varchar(32) not null,
+value text not null,
+uid int not null,
+unique key(name,uid)
+) type=innodb;
+insert into t1 values (1,'one','one value',101),
+(2,'two','two value',102),(3,'three','three value',103);
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+delete from t1 where uid=102;
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+set insert_id=6;
+replace into t1 (value,name,uid) values ('other value','two',102);
+select * from t1;
id name value uid
1 one one value 101
3 three three value 103
6 two other value 102
+drop table t1;
+create database mysqltest;
+create table mysqltest.t1 (a int not null) type= innodb;
+insert into mysqltest.t1 values(1);
+create table mysqltest.t2 (a int not null) type= myisam;
+insert into mysqltest.t2 values(1);
+create table mysqltest.t3 (a int not null) type= heap;
+insert into mysqltest.t3 values(1);
+commit;
+drop database mysqltest;
+show tables from mysqltest;
+Got one of the listed errors
+set autocommit=0;
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+Can't execute the given command because you have active locked tables or an active transaction
+commit;
+truncate table t1;
+select * from t1;
+a
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+commit;
+drop table t1;
+set autocommit=1;
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+insert into t1 values(1),(2);
+select * from t1;
+a
+1
+2
+truncate table t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+drop table t1;
+create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=innodb;
+insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
+explain select * from t1 order by a;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 4
+explain select * from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 index NULL b 4 NULL 4
+explain select * from t1 order by c;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select a from t1 order by a;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 4 Using index
+explain select b from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 index NULL b 4 NULL 4 Using index
+explain select a,b from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 index NULL b 4 NULL 4 Using index
+explain select a,b from t1;
table type possible_keys key key_len ref rows Extra
t1 index NULL b 4 NULL 4 Using index
+explain select a,b,c from t1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4
+drop table t1;
+create table t1 (t int not null default 1, key (t)) type=innodb;
+desc t1;
Field Type Null Key Default Extra
-testint int(11) 1
+t int(11) MUL 1
+handler t1 open t1;
+Table handler for 't1' doesn't have this option
+handler t1 read t first;
+Unknown table 't1' in HANDLER
+handler t1 close;
+Unknown table 't1' in HANDLER
+drop table t1;
+CREATE TABLE t1 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp(14) NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp(14) NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t1 VALUES (4077711111,'SeanWheeler',90,2,20020111112846,500,00000000000000,-1,2,3,1);
+INSERT INTO t1 VALUES (9197722223,'berry',90,3,20020111112809,500,20020102114532,501,4,10,0);
+INSERT INTO t1 VALUES (650,'San Francisco',0,0,20011227111336,342,00000000000000,-1,1,24,1);
+INSERT INTO t1 VALUES (302467,'Sue\'s Subshop',90,3,20020109113241,500,20020102115111,501,7,24,0);
+INSERT INTO t1 VALUES (6014911113,'SudzCarwash',520,1,20020102115234,500,20020102115259,501,33,32768,0);
+INSERT INTO t1 VALUES (333,'tubs',99,2,20020109113440,501,20020109113440,500,3,10,0);
+CREATE TABLE t2 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp(14) NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp(14) NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t2 VALUES (4077711111,'SeanWheeler',0,2,20020111112853,500,00000000000000,-1,2,3,1);
+INSERT INTO t2 VALUES (9197722223,'berry',90,3,20020111112818,500,20020102114532,501,4,10,0);
+INSERT INTO t2 VALUES (650,'San Francisco',90,0,20020109113158,342,00000000000000,-1,1,24,1);
+INSERT INTO t2 VALUES (333,'tubs',99,2,20020109113453,501,20020109113453,500,3,10,0);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 90 2 20020111112846 500 00000000000000 -1 2 3 1
+9197722223 berry 90 3 20020111112809 500 20020102114532 501 4 10 0
+650 San Francisco 0 0 20011227111336 342 00000000000000 -1 1 24 1
+302467 Sue's Subshop 90 3 20020109113241 500 20020102115111 501 7 24 0
+6014911113 SudzCarwash 520 1 20020102115234 500 20020102115259 501 33 32768 0
+333 tubs 99 2 20020109113440 501 20020109113440 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 0 2 20020111112853 500 00000000000000 -1 2 3 1
+9197722223 berry 90 3 20020111112818 500 20020102114532 501 4 10 0
+650 San Francisco 90 0 20020109113158 342 00000000000000 -1 1 24 1
+333 tubs 99 2 20020109113453 501 20020109113453 500 3 10 0
+delete t1, t2 from t1 left join t2 on t1.number=t2.number where (t1.carrier_id=90 and t1.number=t2.number) or (t2.carrier_id=90 and t1.number=t2.number) or (t1.carrier_id=90 and t2.number is null);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+6014911113 SudzCarwash 520 1 20020102115234 500 20020102115259 501 33 32768 0
+333 tubs 99 2 20020109113440 501 20020109113440 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 20020109113453 501 20020109113453 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 20020109113453 501 20020109113453 500 3 10 0
+drop table t1,t2;
diff --git a/mysql-test/r/innodb_cache.result b/mysql-test/r/innodb_cache.result
new file mode 100644
index 00000000000..eaa030046da
--- /dev/null
+++ b/mysql-test/r/innodb_cache.result
@@ -0,0 +1,100 @@
+drop table if exists t1, t2, t3;
+flush status;
+set autocommit=0;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+commit;
+set autocommit=1;
+begin;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+commit;
+create table t1 (a int not null) type=innodb;
+create table t2 (a int not null) type=innodb;
+create table t3 (a int not null) type=innodb;
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+select * from t1;
+a
+1
+2
+select * from t2;
+a
+1
+2
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+begin;
+select * from t1;
+a
+1
+2
+select * from t2;
+a
+1
+2
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+insert into t1 values (3);
+insert into t2 values (3);
+insert into t1 values (4);
+select * from t1;
+a
+1
+2
+3
+4
+select * from t2;
+a
+1
+2
+3
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+commit;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
diff --git a/mysql-test/r/ins000001.result b/mysql-test/r/ins000001.result
index 283f31ffb43..ec4f73e7a5d 100644
--- a/mysql-test/r/ins000001.result
+++ b/mysql-test/r/ins000001.result
@@ -1,3 +1,12 @@
+use test;
+drop table if exists t1,t2;
+create table t1 (email varchar(50));
+insert into t1 values ('sasha@mysql.com'),('monty@mysql.com'),
+('foo@hotmail.com'),('foo@aol.com'),('bar@aol.com');
+create table t2(id int not null auto_increment primary key,
+t2 varchar(50), unique(t2));
+insert into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1;
+select * from t2;
id t2
1 mysql.com
2 hotmail.com
diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result
index 145ec8a5cf4..a1eff07f4d5 100644
--- a/mysql-test/r/insert.result
+++ b/mysql-test/r/insert.result
@@ -1,6 +1,47 @@
+drop table if exists t1;
+create table t1 (a int not null);
+insert into t1 values (1);
+insert into t1 values (a+2);
+insert into t1 values (a+3);
+insert into t1 values (4),(a+5);
+select * from t1;
a
1
2
3
4
5
+drop table t1;
+create table t1 (id int not null auto_increment primary key, username varchar(32) not null, unique (username));
+insert into t1 values (0,"mysql");
+insert into t1 values (0,"mysql ab");
+insert into t1 values (0,"mysql a");
+insert into t1 values (0,"r1manic");
+insert into t1 values (0,"r1man");
+drop table t1;
+create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello");
+insert into t1 values (default,default,default), (default,default,default), (4,0,"a"),(default,default,default);
+select a,t>0,c from t1;
+a t>0 c
+1 1 hello
+2 1 hello
+4 0 a
+5 1 hello
+truncate table t1;
+insert into t1 set a=default,t=default,c=default;
+insert into t1 set a=default,t=default,c=default;
+insert into t1 set a=4,t=0,c="a";
+insert into t1 set a=default,t=default,c=default;
+select a,t>0,c from t1;
+a t>0 c
+1 1 hello
+2 1 hello
+4 0 a
+5 1 hello
+drop table t1;
+drop database if exists foo;
+create database foo;
+use foo;
+create table t1 (c int);
+insert into foo.t1 set foo.t1.c = '1';
+drop database foo;
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index c754085ccb3..e24c3179a0c 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -1,3 +1,12 @@
+drop table if exists t1,t2;
+create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
+insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
+create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY);
+insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1;
+insert into t2 (payoutID) SELECT payoutID+10 FROM t1;
+Duplicate entry '16' for key 1
+insert ignore into t2 (payoutID) SELECT payoutID+10 FROM t1;
+select * from t2;
payoutID
1
4
@@ -11,3 +20,49 @@ payoutID
19
20
22
+drop table t1,t2;
+DROP TABLE IF EXISTS crash1,crash2;
+CREATE TABLE `crash1` (
+`numeropost` bigint(20) unsigned NOT NULL default '0',
+`icone` tinyint(4) unsigned NOT NULL default '0',
+`numreponse` bigint(20) unsigned NOT NULL auto_increment,
+`contenu` text NOT NULL,
+`pseudo` varchar(50) NOT NULL default '',
+`date` datetime NOT NULL default '0000-00-00 00:00:00',
+`ip` bigint(11) NOT NULL default '0',
+`signature` tinyint(1) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`,`numreponse`)
+,KEY `ip` (`ip`),
+KEY `date` (`date`),
+KEY `pseudo` (`pseudo`),
+KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+CREATE TABLE `crash2` (
+`numeropost` bigint(20) unsigned NOT NULL default '0',
+`icone` tinyint(4) unsigned NOT NULL default '0',
+`numreponse` bigint(20) unsigned NOT NULL auto_increment,
+`contenu` text NOT NULL,
+`pseudo` varchar(50) NOT NULL default '',
+`date` datetime NOT NULL default '0000-00-00 00:00:00',
+`ip` bigint(11) NOT NULL default '0',
+`signature` tinyint(1) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`,`numreponse`),
+KEY `ip` (`ip`),
+KEY `date` (`date`),
+KEY `pseudo` (`pseudo`),
+KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+INSERT INTO crash2
+(numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES
+(9,1,56,'test','joce','2001-07-25 13:50:53'
+,3649052399,0);
+INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM crash2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+show variables like '%bulk%';
+Variable_name Value
+bulk_insert_buffer_size 8388608
+INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM crash2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+DROP TABLE IF EXISTS crash1,crash2;
diff --git a/mysql-test/r/isam.result b/mysql-test/r/isam.result
index ba12ca05feb..d19352aad42 100644
--- a/mysql-test/r/isam.result
+++ b/mysql-test/r/isam.result
@@ -1,10 +1,79 @@
+drop table if exists t1,t2;
+create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a)) type=isam;
+delete from t1 where (a & 1);
+select sum(length(b)) from t1;
+sum(length(b))
+3274494
+drop table t1;
+create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam;
+insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
+delete from t1 where a=4 or a=2;
+insert into t1 values (NULL,4),(NULL,5),(6,6);
+select * from t1;
+a b
+1 1
+5 5
+3 3
+4 4
+6 6
+delete from t1 where a=6;
+replace t1 values (3,1);
+replace t1 values (3,3);
+ALTER TABLE t1 add c int;
+insert into t1 values (NULL,6,6);
+select * from t1;
+a b c
+1 1 NULL
+5 5 NULL
+3 3 NULL
+4 4 NULL
+6 6 6
+drop table t1;
+create table t1 (a int,b text, index(a)) type=isam;
+Column 'a' is used with UNIQUE or INDEX but is not defined as NOT NULL
+create table t1 (a int,b text, index(b)) type=isam;
+BLOB column 'b' can't be used in key specification with the used table type
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam;
+Incorrect table definition; There can only be one auto column and it must be defined as a key
+create table t1 (ordid int(8), unique (ordid)) type=isam;
+Column 'ordid' is used with UNIQUE or INDEX but is not defined as NOT NULL
+drop table if exists t1;
+create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
+insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
+create table t2 type=isam select * from t1;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+check table t1,t2;
Table Op Msg_type Msg_text
test.t1 check status OK
+test.t2 check error The handler for the table doesn't support check/repair
+repair table t1,t2;
Table Op Msg_type Msg_text
test.t1 repair status OK
+test.t2 repair error The handler for the table doesn't support check/repair
+check table t2,t1;
Table Op Msg_type Msg_text
+test.t2 check error The handler for the table doesn't support check/repair
test.t1 check status OK
+lock tables t1 write;
+check table t2,t1;
Table Op Msg_type Msg_text
-test.t1 repair status OK
-Table Op Msg_type Msg_text
+test.t2 check error Table 't2' was not locked with LOCK TABLES
test.t1 check status OK
+show columns from t1;
+Field Type Null Key Default Extra
+a int(11) PRI 0
+b int(11) MUL 0
+c int(11) 0
+show full columns from t1;
+Field Type Null Key Default Extra Privileges
+a int(11) PRI 0 select,insert,update,references
+b int(11) MUL 0 select,insert,update,references
+c int(11) 0 select,insert,update,references
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 4 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+t1 1 b 2 c A 4 NULL NULL BTREE
+drop table t1,t2;
diff --git a/mysql-test/r/isolation.result b/mysql-test/r/isolation.result
deleted file mode 100644
index 60b71e217bb..00000000000
--- a/mysql-test/r/isolation.result
+++ /dev/null
@@ -1,61 +0,0 @@
-f1
-test1
-bar
-f1
-test2
-bar
-f1
-test3
-bar
-f1
-f1
-test4
-bar
-f1
-test5
-bar
-f1
-test6
-bar
-f1
-test7
-bar
-f1
-test8
-bar
-f1
-test9
-bar
-f1
-test10
-bar
-f1
-test11
-bar
-f1
-test12
-bar
-f1
-test13
-bar
-f1
-test14
-bar
-f1
-test15
-bar
-f1
-test16
-bar
-f1
-test17
-bar
-f1
-test18
-bar
-f1
-test19
-bar
-f1
-test20
-bar
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 39331fc68e4..96113dcdc8b 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1,39 +1,214 @@
+drop table if exists t1,t2,t3;
+create table t1 (id int primary key);
+create table t2 (id int);
+insert into t1 values (75);
+insert into t1 values (79);
+insert into t1 values (78);
+insert into t1 values (77);
+replace into t1 values (76);
+replace into t1 values (76);
+insert into t1 values (104);
+insert into t1 values (103);
+insert into t1 values (102);
+insert into t1 values (101);
+insert into t1 values (105);
+insert into t1 values (106);
+insert into t1 values (107);
+insert into t2 values (107);
+insert into t2 values (75);
+select t1.id, t2.id from t1, t2 where t2.id = t1.id;
id id
107 107
75 75
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
id count(t2.id)
75 1
107 1
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
id count(t2.id)
75 1
107 1
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+token varchar(100) DEFAULT '' NOT NULL,
+count int(11) DEFAULT '0' NOT NULL,
+qty int(11),
+phone char(1) DEFAULT '' NOT NULL,
+timestamp datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+PRIMARY KEY (id),
+KEY token (token(15)),
+KEY timestamp (timestamp),
+UNIQUE token_2 (token(75),count,phone)
+);
+INSERT INTO t1 VALUES (21,'e45703b64de71482360de8fec94c3ade',3,7800,'n','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (22,'e45703b64de71482360de8fec94c3ade',4,5000,'y','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (18,'346d1cb63c89285b2351f0ca4de40eda',3,13200,'b','1999-12-23 11:58:04');
+INSERT INTO t1 VALUES (17,'ca6ddeb689e1b48a04146b1b5b6f936a',4,15000,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (16,'ca6ddeb689e1b48a04146b1b5b6f936a',3,13200,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (26,'a71250b7ed780f6ef3185bfffe027983',5,1500,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (24,'4d75906f3c37ecff478a1eb56637aa09',3,5400,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (25,'4d75906f3c37ecff478a1eb56637aa09',4,6500,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (27,'a71250b7ed780f6ef3185bfffe027983',3,6200,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (28,'a71250b7ed780f6ef3185bfffe027983',3,5400,'y','1999-12-27 09:44:36');
+INSERT INTO t1 VALUES (29,'a71250b7ed780f6ef3185bfffe027983',4,17700,'b','1999-12-27 09:45:05');
+CREATE TABLE t2 (
+id int(11) NOT NULL auto_increment,
+category int(11) DEFAULT '0' NOT NULL,
+county int(11) DEFAULT '0' NOT NULL,
+state int(11) DEFAULT '0' NOT NULL,
+phones int(11) DEFAULT '0' NOT NULL,
+nophones int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY category (category,county,state)
+);
+INSERT INTO t2 VALUES (3,2,11,12,5400,7800);
+INSERT INTO t2 VALUES (4,2,25,12,6500,11200);
+INSERT INTO t2 VALUES (5,1,37,6,10000,12000);
+select a.id, b.category as catid, b.state as stateid, b.county as
+countyid from t1 a, t2 b where (a.token =
+'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id);
id catid stateid countyid
27 2 12 11
28 2 12 11
29 2 12 25
26 1 6 37
+select a.id, b.category as catid, b.state as stateid, b.county as
+countyid from t1 a, t2 b where (a.token =
+'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id) order by a.id;
id catid stateid countyid
26 1 6 37
27 2 12 11
28 2 12 11
29 2 12 25
+drop table t1, t2;
+create table t1 (a int primary key);
+insert into t1 values(1),(2);
+select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a);
a
1
2
+select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a);
+Too many tables. MySQL can only use XX tables in a join
+drop table t1;
+CREATE TABLE t1 (
+a int(11) NOT NULL,
+b int(11) NOT NULL,
+PRIMARY KEY (a,b)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(2,3);
+CREATE TABLE t2 (
+a int(11) default NULL
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (2),(3);
+SELECT t1.a,t2.a,b FROM t1,t2 WHERE t1.a=t2.a AND (t1.a=1 OR t1.a=2) AND b>=1 AND b<=3;
a a b
2 2 3
+DROP TABLE t1, t2;
+CREATE TABLE t1 (d DATE NOT NULL);
+CREATE TABLE t2 (d DATE NOT NULL);
+INSERT INTO t1 (d) VALUES ('2001-08-01'),('0000-00-00');
+SELECT * FROM t1 LEFT JOIN t2 USING (d) WHERE t2.d IS NULL;
d d
2001-08-01 NULL
0000-00-00 NULL
+SELECT * from t1 WHERE t1.d IS NULL;
d
0000-00-00
+SELECT * FROM t1 WHERE 1/0 IS NULL;
d
2001-08-01
0000-00-00
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+Document_ID varchar(50) NOT NULL default '',
+Contractor_ID varchar(6) NOT NULL default '',
+Language_ID char(3) NOT NULL default '',
+Expiration_Date datetime default NULL,
+Publishing_Date datetime default NULL,
+Title text,
+Column_ID varchar(50) NOT NULL default '',
+PRIMARY KEY (Language_ID,Document_ID,Contractor_ID)
+);
+INSERT INTO t1 VALUES ('xep80','1','ger','2001-12-31 20:00:00','2001-11-12 10:58:00','Kartenbestellung - jetzt auch online','anle'),('','999998','',NULL,NULL,NULL,'');
+CREATE TABLE t2 (
+Contractor_ID char(6) NOT NULL default '',
+Language_ID char(3) NOT NULL default '',
+Document_ID char(50) NOT NULL default '',
+CanRead char(1) default NULL,
+Customer_ID int(11) NOT NULL default '0',
+PRIMARY KEY (Contractor_ID,Language_ID,Document_ID,Customer_ID)
+);
+INSERT INTO t2 VALUES ('5','ger','xep80','1',999999),('1','ger','xep80','1',999999);
+CREATE TABLE t3 (
+Language_ID char(3) NOT NULL default '',
+Column_ID char(50) NOT NULL default '',
+Contractor_ID char(6) NOT NULL default '',
+CanRead char(1) default NULL,
+Active char(1) default NULL,
+PRIMARY KEY (Language_ID,Column_ID,Contractor_ID)
+);
+INSERT INTO t3 VALUES ('ger','home','1','1','1'),('ger','Test','1','0','0'),('ger','derclu','1','0','0'),('ger','clubne','1','0','0'),('ger','philos','1','0','0'),('ger','clubko','1','0','0'),('ger','clubim','1','1','1'),('ger','progra','1','0','0'),('ger','progvo','1','0','0'),('ger','progsp','1','0','0'),('ger','progau','1','0','0'),('ger','progku','1','0','0'),('ger','progss','1','0','0'),('ger','nachl','1','0','0'),('ger','mitgli','1','0','0'),('ger','mitsu','1','0','0'),('ger','mitbus','1','0','0'),('ger','ergmar','1','1','1'),('ger','home','4','1','1'),('ger','derclu','4','1','1'),('ger','clubne','4','0','0'),('ger','philos','4','1','1'),('ger','clubko','4','1','1'),('ger','clubim','4','1','1'),('ger','progra','4','1','1'),('ger','progvo','4','1','1'),('ger','progsp','4','1','1'),('ger','progau','4','0','0'),('ger','progku','4','1','1'),('ger','progss','4','1','1'),('ger','nachl','4','1','1'),('ger','mitgli','4','0','0'),('ger','mitsu','4','0','0'),('ger','mitbus','4','0','0'),('ger','ergmar','4','1','1'),('ger','progra2','1','0','0'),('ger','archiv','4','1','1'),('ger','anmeld','4','1','1'),('ger','thema','4','1','1'),('ger','edito','4','1','1'),('ger','madis','4','1','1'),('ger','enma','4','1','1'),('ger','madis','1','1','1'),('ger','enma','1','1','1'),('ger','vorsch','4','0','0'),('ger','veranst','4','0','0'),('ger','anle','4','1','1'),('ger','redak','4','1','1'),('ger','nele','4','1','1'),('ger','aukt','4','1','1'),('ger','callcenter','4','1','1'),('ger','anle','1','0','0');
+delete from t1 where Contractor_ID='999998';
+insert into t1 (Contractor_ID) Values ('999998');
+SELECT DISTINCT COUNT(t1.Title) FROM t1,
+t2, t3 WHERE
+t1.Document_ID='xep80' AND t1.Contractor_ID='1' AND
+t1.Language_ID='ger' AND '2001-12-21 23:14:24' >=
+Publishing_Date AND '2001-12-21 23:14:24' <= Expiration_Date AND
+t1.Document_ID = t2.Document_ID AND
+t1.Language_ID = t2.Language_ID AND
+t1.Contractor_ID = t2.Contractor_ID AND (
+t2.Customer_ID = '4' OR
+t2.Customer_ID = '999999' OR
+t2.Customer_ID = '1' )AND t2.CanRead
+= '1' AND t1.Column_ID=t3.Column_ID AND
+t1.Language_ID=t3.Language_ID AND (
+t3.Contractor_ID = '4' OR
+t3.Contractor_ID = '999999' OR
+t3.Contractor_ID = '1') AND
+t3.CanRead='1' AND t3.Active='1';
COUNT(t1.Title)
1
+SELECT DISTINCT COUNT(t1.Title) FROM t1,
+t2, t3 WHERE
+t1.Document_ID='xep80' AND t1.Contractor_ID='1' AND
+t1.Language_ID='ger' AND '2001-12-21 23:14:24' >=
+Publishing_Date AND '2001-12-21 23:14:24' <= Expiration_Date AND
+t1.Document_ID = t2.Document_ID AND
+t1.Language_ID = t2.Language_ID AND
+t1.Contractor_ID = t2.Contractor_ID AND (
+t2.Customer_ID = '4' OR
+t2.Customer_ID = '999999' OR
+t2.Customer_ID = '1' )AND t2.CanRead
+= '1' AND t1.Column_ID=t3.Column_ID AND
+t1.Language_ID=t3.Language_ID AND (
+t3.Contractor_ID = '4' OR
+t3.Contractor_ID = '999999' OR
+t3.Contractor_ID = '1') AND
+t3.CanRead='1' AND t3.Active='1';
COUNT(t1.Title)
1
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+t1_id int(11) default NULL,
+t2_id int(11) default NULL,
+type enum('Cost','Percent') default NULL,
+cost_unit enum('Cost','Unit') default NULL,
+min_value double default NULL,
+max_value double default NULL,
+t3_id int(11) default NULL,
+item_id int(11) default NULL
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (12,5,'Percent','Cost',-1,0,-1,-1),(14,4,'Percent','Cost',-1,0,-1,-1),(18,5,'Percent','Cost',-1,0,-1,-1),(19,4,'Percent','Cost',-1,0,-1,-1),(20,5,'Percent','Cost',100,-1,22,291),(21,5,'Percent','Cost',100,-1,18,291),(22,1,'Percent','Cost',100,-1,6,291),(23,1,'Percent','Cost',100,-1,21,291),(24,1,'Percent','Cost',100,-1,9,291),(25,1,'Percent','Cost',100,-1,4,291),(26,1,'Percent','Cost',100,-1,20,291),(27,4,'Percent','Cost',100,-1,7,202),(28,1,'Percent','Cost',50,-1,-1,137),(29,2,'Percent','Cost',100,-1,4,354),(30,2,'Percent','Cost',100,-1,9,137),(93,2,'Cost','Cost',-1,10000000,-1,-1);
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL auto_increment,
+name varchar(255) default NULL,
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'s1'),(2,'s2'),(3,'s3'),(4,'s4'),(5,'s5');
+select t1.*, t2.* from t1, t2 where t2.id=t1.t2_id limit 2;
t1_id t2_id type cost_unit min_value max_value t3_id item_id id name
22 1 Percent Cost 100 -1 6 291 1 s1
23 1 Percent Cost 100 -1 21 291 1 s1
+drop table t1,t2;
diff --git a/mysql-test/r/join_crash.result b/mysql-test/r/join_crash.result
index f7bef8af8ec..c7bca9f7497 100644
--- a/mysql-test/r/join_crash.result
+++ b/mysql-test/r/join_crash.result
@@ -1 +1,110 @@
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+CREATE TABLE t1 (
+project_id int(11) NOT NULL auto_increment,
+project_row_lock int(11) NOT NULL default '0',
+project_name varchar(80) NOT NULL default '',
+client_ptr int(11) NOT NULL default '0',
+project_contact_ptr int(11) default NULL,
+client_contact_ptr int(11) default NULL,
+billing_contact_ptr int(11) default NULL,
+comments mediumtext,
+PRIMARY KEY (project_id),
+UNIQUE KEY project (client_ptr,project_name)
+) TYPE=MyISAM PACK_KEYS=1;
+INSERT INTO t1 VALUES (1,0,'Rejected Time',1,NULL,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (209,0,'MDGRAD Proposal/Investigation',97,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (208,0,'Font 9 Design',84,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (207,0,'Web Based Order Processing',95,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (205,0,'Mac Screen Saver',95,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (206,0,'Web Site',96,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (204,0,'Magnafire Glue',94,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (203,0,'Print Bid',93,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (202,0,'EPOC Port',92,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (201,0,'TravelMate',88,NULL,NULL,NULL,'');
+CREATE TABLE t2 (
+period_id int(11) NOT NULL auto_increment,
+period_type enum('user_table','client_table','role_table','member_table','project_table') default NULL,
+period_key int(11) default NULL,
+start_date datetime default NULL,
+end_date datetime default NULL,
+work_load int(11) default NULL,
+PRIMARY KEY (period_id),
+KEY period_index (period_type,period_key),
+KEY date_index (start_date,end_date)
+) TYPE=MyISAM PACK_KEYS=1;
+INSERT INTO t2 VALUES (1,'user_table',98,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (2,'user_table',99,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (3,'user_table',100,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (49,'project_table',148,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (50,'client_table',68,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (51,'project_table',149,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (52,'project_table',150,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (53,'client_table',69,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (54,'project_table',151,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (55,'client_table',70,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (155,'role_table',1,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (156,'role_table',2,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (160,'member_table',1,'2000-01-01 00:00:00',NULL,1);
+INSERT INTO t2 VALUES (161,'member_table',2,'2000-01-01 00:00:00',NULL,1);
+INSERT INTO t2 VALUES (162,'member_table',3,'2000-01-01 00:00:00',NULL,1);
+CREATE TABLE t3 (
+budget_id int(11) NOT NULL auto_increment,
+project_ptr int(11) NOT NULL default '0',
+po_number varchar(20) NOT NULL default '',
+status enum('open','closed') default NULL,
+date_received datetime default NULL,
+amount_received float(10,2) default NULL,
+adjustment float(10,2) default NULL,
+PRIMARY KEY (budget_id),
+UNIQUE KEY po (project_ptr,po_number)
+) TYPE=MyISAM PACK_KEYS=1;
+CREATE TABLE t4 (
+client_id int(11) NOT NULL auto_increment,
+client_row_lock int(11) NOT NULL default '0',
+client_name varchar(80) NOT NULL default '',
+contact_ptr int(11) default NULL,
+comments mediumtext,
+PRIMARY KEY (client_id),
+UNIQUE KEY client_name (client_name)
+) TYPE=MyISAM PACK_KEYS=1;
+INSERT INTO t4 VALUES (1,0,'CPS',NULL,NULL);
+select distinct
+t1.project_id as project_id,
+t1.project_name as project_name,
+t1.client_ptr as client_ptr,
+t1.comments as comments,
+sum( t3.amount_received ) + sum( t3.adjustment ) as total_budget
+from
+t1 ,
+t2 as client_period ,
+t2 as project_period
+left join
+t3
+on
+t3.project_ptr = t1.project_id
+and t3.date_received <= '2001-03-22 14:15:09'
+ left join
+t4
+on
+t4.client_id = t1.client_ptr
+where
+1
+and ( client_period.period_type = 'client_table'
+ and client_period.period_key = t4.client_id
+and ( client_period.start_date <= '2001-03-22 14:15:09' or isnull( client_period.start_date ))
+and ( client_period.end_date > '2001-03-21 14:15:09' or isnull( client_period.end_date ))
+)
+and ( project_period.period_type = 'project_table'
+ and project_period.period_key = t1.project_id
+and ( project_period.start_date <= '2001-03-22 14:15:09' or isnull( project_period.start_date ))
+and ( project_period.end_date > '2001-03-21 14:15:09' or isnull( project_period.end_date )) )
+group by
+client_id,
+project_id ,
+client_period.period_id ,
+project_period.period_id
+order by
+client_name asc,
+project_name asc;
project_id project_name client_ptr comments total_budget
+DROP TABLE t1,t2,t3,t4;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index f5e643a9bbf..9d3c152e516 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1,8 +1,19 @@
+drop table if exists t1,t2,t3,t4,t5;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a bigint(20) unsigned default NULL,
+c char(10) NOT NULL default ''
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1,'a'),(2,2,'b'),(2,3,'c'),(3,4,'E'),(3,5,'C'),(3,6,'D'),(NULL,NULL,'');
+create table t2 (id int, a bigint unsigned not null, c char(10), d int, primary key (a));
+insert into t2 values (1,1,"a",1),(3,4,"A",4),(3,5,"B",5),(3,6,"C",6),(4,7,"D",7);
+select t1.*,t2.* from t1 JOIN t2 where t1.a=t2.a;
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) order by t1.grp,t1.a,t2.c;
grp a c id a c d
NULL NULL NULL NULL NULL NULL
1 1 a 1 1 a 1
@@ -11,18 +22,21 @@ NULL NULL NULL NULL NULL NULL
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) };
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
NULL NULL NULL 4 7 D 7
+select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2;
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
NULL NULL NULL 4 7 D 7
+select t1.*,t2.* from t1 left join t2 using (a);
grp a c id a c d
1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL
@@ -31,11 +45,13 @@ grp a c id a c d
3 5 C 3 5 B 5
3 6 D 3 6 C 6
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 using (a) where t1.a=t2.a;
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 using (a,c);
grp a c id a c d
1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL
@@ -44,6 +60,7 @@ grp a c id a c d
3 5 C NULL NULL NULL NULL
3 6 D NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 using (c);
grp a c id a c d
1 1 a 1 1 a 1
1 1 a 3 4 A 4
@@ -53,6 +70,7 @@ grp a c id a c d
3 5 C 3 6 C 6
3 6 D 4 7 D 7
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 natural left outer join t2;
grp a c id a c d
1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL
@@ -61,19 +79,24 @@ grp a c id a c d
3 5 C NULL NULL NULL NULL
3 6 D NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id=3;
grp a c id a c d
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id is null;
grp a c id a c d
2 2 b NULL NULL NULL NULL
2 3 c NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
+explain select t1.*,t2.* from t1,t2 where t1.a=t2.a and isnull(t2.a)=1;
Comment
Impossible WHERE noticed after reading const tables
+explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 7
t2 eq_ref PRIMARY PRIMARY 8 t1.a 1 where used
+select t1.*,t2.*,t3.a from t1 left join t2 on (t1.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
grp a c id a c d a
1 1 a 1 1 a 1 1
2 2 b NULL NULL NULL NULL NULL
@@ -82,28 +105,161 @@ grp a c id a c d a
3 5 C 3 5 B 5 5
3 6 D 3 6 C 6 6
NULL NULL NULL NULL NULL NULL NULL
+explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+select t1.*,t2.* from t1 inner join t2 using (a);
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 inner join t2 on (t1.a=t2.a);
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 natural join t2;
grp a c id a c d
1 1 a 1 1 a 1
+drop table t1,t2;
+CREATE TABLE t1 (
+usr_id INT unsigned NOT NULL,
+uniq_id INT unsigned NOT NULL AUTO_INCREMENT,
+start_num INT unsigned NOT NULL DEFAULT 1,
+increment INT unsigned NOT NULL DEFAULT 1,
+PRIMARY KEY (uniq_id),
+INDEX usr_uniq_idx (usr_id, uniq_id),
+INDEX uniq_usr_idx (uniq_id, usr_id)
+);
+CREATE TABLE t2 (
+id INT unsigned NOT NULL DEFAULT 0,
+usr2_id INT unsigned NOT NULL DEFAULT 0,
+max INT unsigned NOT NULL DEFAULT 0,
+c_amount INT unsigned NOT NULL DEFAULT 0,
+d_max INT unsigned NOT NULL DEFAULT 0,
+d_num INT unsigned NOT NULL DEFAULT 0,
+orig_time INT unsigned NOT NULL DEFAULT 0,
+c_time INT unsigned NOT NULL DEFAULT 0,
+active ENUM ("no","yes") NOT NULL,
+PRIMARY KEY (id,usr2_id),
+INDEX id_idx (id),
+INDEX usr2_idx (usr2_id)
+);
+INSERT INTO t1 VALUES (3,NULL,0,50),(3,NULL,0,200),(3,NULL,0,25),(3,NULL,0,84676),(3,NULL,0,235),(3,NULL,0,10),(3,NULL,0,3098),(3,NULL,0,2947),(3,NULL,0,8987),(3,NULL,0,8347654),(3,NULL,0,20398),(3,NULL,0,8976),(3,NULL,0,500),(3,NULL,0,198);
+SELECT t1.usr_id,t1.uniq_id,t1.increment,
+t2.usr2_id,t2.c_amount,t2.max
+FROM t1
+LEFT JOIN t2 ON t2.id = t1.uniq_id
+WHERE t1.uniq_id = 4
+ORDER BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,
+t2.usr2_id,t2.c_amount,t2.max
+FROM t2
+RIGHT JOIN t1 ON t2.id = t1.uniq_id
+WHERE t1.uniq_id = 4
+ORDER BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
+INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
+Duplicate entry '2-3' for key 1
+INSERT INTO t2 VALUES (7,3,1000,2000,0,0,746294,937484,'yes');
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 ORDER BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 GROUP BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+drop table t1,t2;
+drop table if exists t1,t2,t3,t4;
+CREATE TABLE t1 (
+cod_asig int(11) DEFAULT '0' NOT NULL,
+desc_larga_cat varchar(80) DEFAULT '' NOT NULL,
+desc_larga_cas varchar(80) DEFAULT '' NOT NULL,
+desc_corta_cat varchar(40) DEFAULT '' NOT NULL,
+desc_corta_cas varchar(40) DEFAULT '' NOT NULL,
+cred_total double(3,1) DEFAULT '0.0' NOT NULL,
+pre_requisit int(11),
+co_requisit int(11),
+preco_requisit int(11),
+PRIMARY KEY (cod_asig)
+);
+INSERT INTO t1 VALUES (10360,'asdfggfg','Introduccion a los Ordenadores I','asdfggfg','Introduccio Ordinadors I',6.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10361,'Components i Circuits Electronics I','Componentes y Circuitos Electronicos I','Components i Circuits Electronics I','Comp. i Circ. Electr. I',6.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10362,'Laboratori d`Ordinadors','Laboratorio de Ordenadores','Laboratori d`Ordinadors','Laboratori Ordinadors',4.5,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10363,'Tecniques de Comunicacio Oral i Escrita','Tecnicas de Comunicacion Oral y Escrita','Tecniques de Comunicacio Oral i Escrita','Tec. Com. Oral i Escrita',4.5,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11403,'Projecte Fi de Carrera','Proyecto Fin de Carrera','Projecte Fi de Carrera','PFC',9.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11404,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',15.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11405,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',18.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11406,'Calcul Infinitesimal','Cßlculo Infinitesimal','Calcul Infinitesimal','Calcul Infinitesimal',15.0,NULL,NULL,NULL);
+CREATE TABLE t2 (
+idAssignatura int(11) DEFAULT '0' NOT NULL,
+Grup int(11) DEFAULT '0' NOT NULL,
+Places smallint(6) DEFAULT '0' NOT NULL,
+PlacesOcupades int(11) DEFAULT '0',
+PRIMARY KEY (idAssignatura,Grup)
+);
+INSERT INTO t2 VALUES (10360,12,333,0);
+INSERT INTO t2 VALUES (10361,30,2,0);
+INSERT INTO t2 VALUES (10361,40,3,0);
+INSERT INTO t2 VALUES (10360,45,10,0);
+INSERT INTO t2 VALUES (10362,10,12,0);
+INSERT INTO t2 VALUES (10360,55,2,0);
+INSERT INTO t2 VALUES (10360,70,0,0);
+INSERT INTO t2 VALUES (10360,565656,0,0);
+INSERT INTO t2 VALUES (10360,32767,7,0);
+INSERT INTO t2 VALUES (10360,33,8,0);
+INSERT INTO t2 VALUES (10360,7887,85,0);
+INSERT INTO t2 VALUES (11405,88,8,0);
+INSERT INTO t2 VALUES (10360,0,55,0);
+INSERT INTO t2 VALUES (10360,99,0,0);
+INSERT INTO t2 VALUES (11411,30,10,0);
+INSERT INTO t2 VALUES (11404,0,0,0);
+INSERT INTO t2 VALUES (10362,11,111,0);
+INSERT INTO t2 VALUES (10363,33,333,0);
+INSERT INTO t2 VALUES (11412,55,0,0);
+INSERT INTO t2 VALUES (50003,66,6,0);
+INSERT INTO t2 VALUES (11403,5,0,0);
+INSERT INTO t2 VALUES (11406,11,11,0);
+INSERT INTO t2 VALUES (11410,11410,131,0);
+INSERT INTO t2 VALUES (11416,11416,32767,0);
+INSERT INTO t2 VALUES (11409,0,0,0);
+CREATE TABLE t3 (
+id int(11) DEFAULT '0' NOT NULL auto_increment,
+dni_pasaporte char(16) DEFAULT '' NOT NULL,
+idPla int(11) DEFAULT '0' NOT NULL,
+cod_asig int(11) DEFAULT '0' NOT NULL,
+any smallint(6) DEFAULT '0' NOT NULL,
+quatrimestre smallint(6) DEFAULT '0' NOT NULL,
+estat char(1) DEFAULT 'M' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE dni_pasaporte (dni_pasaporte,idPla),
+UNIQUE dni_pasaporte_2 (dni_pasaporte,idPla,cod_asig,any,quatrimestre)
+);
+INSERT INTO t3 VALUES (1,'11111111',1,10362,98,1,'M');
+CREATE TABLE t4 (
+id int(11) DEFAULT '0' NOT NULL auto_increment,
+papa int(11) DEFAULT '0' NOT NULL,
+fill int(11) DEFAULT '0' NOT NULL,
+idPla int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY papa (idPla,papa),
+UNIQUE papa_2 (idPla,papa,fill)
+);
+INSERT INTO t4 VALUES (1,-1,10360,1);
+INSERT INTO t4 VALUES (2,-1,10361,1);
+INSERT INTO t4 VALUES (3,-1,10362,1);
+SELECT DISTINCT fill,desc_larga_cat,cred_total,Grup,Places,PlacesOcupades FROM t4 LEFT JOIN t3 ON t3.cod_asig=fill AND estat='S' AND dni_pasaporte='11111111' AND t3.idPla=1 , t2,t1 WHERE fill=t1.cod_asig AND Places>PlacesOcupades AND fill=idAssignatura AND t4.idPla=1 AND papa=-1;
fill desc_larga_cat cred_total Grup Places PlacesOcupades
10360 asdfggfg 6.0 0 55 0
10360 asdfggfg 6.0 12 333 0
@@ -116,49 +272,82 @@ fill desc_larga_cat cred_total Grup Places PlacesOcupades
10361 Components i Circuits Electronics I 6.0 40 3 0
10362 Laboratori d`Ordinadors 4.5 10 12 0
10362 Laboratori d`Ordinadors 4.5 11 111 0
+SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ;
fill idPla
10360 NULL
10361 NULL
10362 NULL
+INSERT INTO t3 VALUES (3,'1234',1,10360,98,1,'S');
+SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ;
fill idPla
10360 1
10361 NULL
10362 NULL
+drop table t1,t2,t3,test.t4;
+CREATE TABLE t1 (
+id smallint(5) unsigned DEFAULT '0' NOT NULL auto_increment,
+name char(60) DEFAULT '' NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (1,'Antonio Paz');
+INSERT INTO t1 VALUES (2,'Lilliana Angelovska');
+INSERT INTO t1 VALUES (3,'Thimble Smith');
+CREATE TABLE t2 (
+id smallint(5) unsigned DEFAULT '0' NOT NULL auto_increment,
+owner smallint(5) unsigned DEFAULT '0' NOT NULL,
+name char(60),
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES (1,1,'El Gato');
+INSERT INTO t2 VALUES (2,1,'Perrito');
+INSERT INTO t2 VALUES (3,3,'Happy');
+select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner);
name name id
Antonio Paz El Gato 1
Antonio Paz Perrito 2
Lilliana Angelovska NULL NULL
Thimble Smith Happy 3
+select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
name name id
Lilliana Angelovska NULL NULL
+explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
t2 ALL NULL NULL NULL NULL 3 where used; Not exists
+explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.name is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
t2 ALL NULL NULL NULL NULL 3 where used
+select count(*) from t1 left join t2 on (t1.id = t2.owner);
count(*)
4
+select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner);
name name id
Antonio Paz El Gato 1
Antonio Paz Perrito 2
Lilliana Angelovska NULL NULL
Thimble Smith Happy 3
+select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
name name id
Lilliana Angelovska NULL NULL
+explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
t2 ALL NULL NULL NULL NULL 3 where used; Not exists
+explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.name is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
t2 ALL NULL NULL NULL NULL 3 where used
+select count(*) from t2 right join t1 on (t1.id = t2.owner);
count(*)
4
+select t1.name, t2.name, t2.id,t3.id from t2 right join t1 on (t1.id = t2.owner) left join t1 as t3 on t3.id=t2.owner;
name name id id
Antonio Paz El Gato 1 1
Antonio Paz Perrito 2 1
Lilliana Angelovska NULL NULL NULL
Thimble Smith Happy 3 3
+select t1.name, t2.name, t2.id,t3.id from t1 right join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner;
name name id id
Antonio Paz El Gato 1 1
Antonio Paz Perrito 2 1
@@ -169,6 +358,7 @@ NULL Happy 3 2
NULL El Gato 1 3
NULL Perrito 2 3
Thimble Smith Happy 3 3
+select t1.name, t2.name, t2.id, t2.owner, t3.id from t1 left join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner;
name name id owner id
Antonio Paz El Gato 1 1 1
Antonio Paz Perrito 2 1 1
@@ -180,49 +370,136 @@ Thimble Smith NULL NULL NULL 2
Antonio Paz NULL NULL NULL 3
Lilliana Angelovska NULL NULL NULL 3
Thimble Smith Happy 3 3 3
+drop table t1,t2;
+create table t1 (id int not null, str char(10), index(str));
+insert into t1 values (1, null), (2, null), (3, "foo"), (4, "bar");
+select * from t1 where str is not null;
id str
4 bar
3 foo
+select * from t1 where str is null;
id str
1 NULL
2 NULL
+drop table t1;
+CREATE TABLE t1 (
+t1_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+PRIMARY KEY (t1_id)
+);
+CREATE TABLE t2 (
+t2_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+PRIMARY KEY (t2_id)
+);
+CREATE TABLE t3 (
+t3_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+PRIMARY KEY (t3_id)
+);
+CREATE TABLE t4 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+KEY seq_0_id (seq_0_id),
+KEY seq_1_id (seq_1_id)
+);
+CREATE TABLE t5 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+KEY seq_1_id (seq_1_id),
+KEY seq_0_id (seq_0_id)
+);
+insert into t1 values (1);
+insert into t2 values (1);
+insert into t3 values (1);
+insert into t4 values (1,1);
+insert into t5 values (1,1);
+explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23;
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+drop table t1,t2,t3,t4,t5;
+create table t1 (n int, m int, o int, key(n));
+create table t2 (n int not null, m int, o int, primary key(n));
+insert into t1 values (1, 2, 11), (1, 2, 7), (2, 2, 8), (1,2,9),(1,3,9);
+insert into t2 values (1, 2, 3),(2, 2, 8), (4,3,9),(3,2,10);
+select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
+t1.m = t2.m where t1.n = 1;
n m o n m o
1 2 11 1 2 3
1 2 7 1 2 3
1 2 9 1 2 3
1 3 9 NULL NULL NULL
+select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
+t1.m = t2.m where t1.n = 1 order by t1.o;
n m o n m o
1 2 7 1 2 3
1 2 9 1 2 3
1 3 9 NULL NULL NULL
1 2 11 1 2 3
+drop table t1,t2;
+CREATE TABLE t1 (id1 INT NOT NULL PRIMARY KEY, dat1 CHAR(1), id2 INT);
+INSERT INTO t1 VALUES (1,'a',1);
+INSERT INTO t1 VALUES (2,'b',1);
+INSERT INTO t1 VALUES (3,'c',2);
+CREATE TABLE t2 (id2 INT NOT NULL PRIMARY KEY, dat2 CHAR(1));
+INSERT INTO t2 VALUES (1,'x');
+INSERT INTO t2 VALUES (2,'y');
+INSERT INTO t2 VALUES (3,'z');
+SELECT t2.id2 FROM t2 LEFT OUTER JOIN t1 ON t1.id2 = t2.id2 WHERE id1 IS NULL;
id2
3
+SELECT t2.id2 FROM t2 NATURAL LEFT OUTER JOIN t1 WHERE id1 IS NULL;
id2
3
+drop table t1,t2;
+create table t1 ( color varchar(20), name varchar(20) );
+insert into t1 values ( 'red', 'apple' );
+insert into t1 values ( 'yellow', 'banana' );
+insert into t1 values ( 'green', 'lime' );
+insert into t1 values ( 'black', 'grape' );
+insert into t1 values ( 'blue', 'blueberry' );
+create table t2 ( count int, color varchar(20) );
+insert into t2 values (10, 'green');
+insert into t2 values (5, 'black');
+insert into t2 values (15, 'white');
+insert into t2 values (7, 'green');
+select * from t1;
color name
red apple
yellow banana
green lime
black grape
blue blueberry
+select * from t2;
count color
10 green
5 black
15 white
7 green
+select * from t2 natural join t1;
count color color name
10 green green lime
7 green green lime
5 black black grape
+select t2.count, t1.name from t2 natural join t1;
count name
10 lime
7 lime
5 grape
+select t2.count, t1.name from t2 inner join t1 using (color);
count name
10 lime
7 lime
5 grape
+drop table t1;
+drop table t2;
+CREATE TABLE t1 (
+pcode varchar(8) DEFAULT '' NOT NULL
+);
+INSERT INTO t1 VALUES ('kvw2000'),('kvw2001'),('kvw3000'),('kvw3001'),('kvw3002'),('kvw3500'),('kvw3501'),('kvw3502'),('kvw3800'),('kvw3801'),('kvw3802'),('kvw3900'),('kvw3901'),('kvw3902'),('kvw4000'),('kvw4001'),('kvw4002'),('kvw4200'),('kvw4500'),('kvw5000'),('kvw5001'),('kvw5500'),('kvw5510'),('kvw5600'),('kvw5601'),('kvw6000'),('klw1000'),('klw1020'),('klw1500'),('klw2000'),('klw2001'),('klw2002'),('kld2000'),('klw2500'),('kmw1000'),('kmw1500'),('kmw2000'),('kmw2001'),('kmw2100'),('kmw3000'),('kmw3200');
+CREATE TABLE t2 (
+pcode varchar(8) DEFAULT '' NOT NULL,
+KEY pcode (pcode)
+);
+INSERT INTO t2 VALUES ('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw6000'),('kvw6000'),('kld2000');
+SELECT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1
+LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode;
pcode count
kld2000 1
klw1000 0
@@ -265,6 +542,7 @@ kvw5510 0
kvw5600 0
kvw5601 0
kvw6000 2
+SELECT SQL_BIG_RESULT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1 LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode;
pcode count
kld2000 1
klw1000 0
@@ -307,27 +585,70 @@ kvw5510 0
kvw5600 0
kvw5601 0
kvw6000 2
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11),
+pid int(11),
+rep_del tinyint(4),
+KEY id (id),
+KEY pid (pid)
+);
+INSERT INTO t1 VALUES (1,NULL,NULL);
+INSERT INTO t1 VALUES (2,1,NULL);
+select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL;
id pid rep_del id pid rep_del
1 NULL NULL 2 1 NULL
2 1 NULL NULL NULL NULL
+create index rep_del ON t1(rep_del);
+select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL;
id pid rep_del id pid rep_del
1 NULL NULL 2 1 NULL
2 1 NULL NULL NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+id int(11) DEFAULT '0' NOT NULL,
+name tinytext DEFAULT '' NOT NULL,
+UNIQUE id (id)
+);
+INSERT INTO t1 VALUES (1,'yes'),(2,'no');
+CREATE TABLE t2 (
+id int(11) DEFAULT '0' NOT NULL,
+idx int(11) DEFAULT '0' NOT NULL,
+UNIQUE id (id,idx)
+);
+INSERT INTO t2 VALUES (1,1);
+explain SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 2
t2 index id id 8 NULL 1 where used; Using index; Not exists
+SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL;
id name id idx
2 no NULL NULL
+drop table t1,t2;
+create table t1 (bug_id mediumint, reporter mediumint);
+create table t2 (bug_id mediumint, who mediumint, index(who));
+insert into t2 values (1,1),(1,2);
+insert into t1 values (1,1),(2,1);
+SELECT * FROM t1 LEFT JOIN t2 ON (t1.bug_id = t2.bug_id AND t2.who = 2) WHERE (t1.reporter = 2 OR t2.who = 2);
bug_id reporter bug_id who
1 1 1 2
+drop table t1,t2;
+create table t1 (fooID smallint unsigned auto_increment, primary key (fooID));
+create table t2 (fooID smallint unsigned not null, barID smallint unsigned not null, primary key (fooID,barID));
+insert into t1 (fooID) values (10),(20),(30);
+insert into t2 values (10,1),(20,2),(30,3);
+explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
table type possible_keys key key_len ref rows Extra
t2 index NULL PRIMARY 4 NULL 3 Using index
t1 eq_ref PRIMARY PRIMARY 2 const 1 where used; Using index
+select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID
10 1 NULL
20 2 NULL
30 3 30
+select * from t2 left join t1 ignore index(primary) on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID
10 1 NULL
20 2 NULL
30 3 30
+drop table t1,t2;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index dbdec824d3b..1cd9c9dfe79 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -1,19 +1,180 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+ID CHAR(32) NOT NULL,
+name CHAR(32) NOT NULL,
+value CHAR(255),
+INDEX indexIDname (ID(8),name(8))
+) ;
+INSERT INTO t1 VALUES
+('keyword','indexdir','/export/home/local/www/database/indexes/keyword');
+INSERT INTO t1 VALUES ('keyword','urlprefix','text/ /text');
+INSERT INTO t1 VALUES ('keyword','urlmap','/text/ /');
+INSERT INTO t1 VALUES ('keyword','attr','personal employee company');
+INSERT INTO t1 VALUES
+('emailgids','indexdir','/export/home/local/www/database/indexes/emailgids');
+INSERT INTO t1 VALUES ('emailgids','urlprefix','text/ /text');
+INSERT INTO t1 VALUES ('emailgids','urlmap','/text/ /');
+INSERT INTO t1 VALUES ('emailgids','attr','personal employee company');
+SELECT value FROM t1 WHERE ID='emailgids' AND name='attr';
value
personal employee company
+drop table t1;
+CREATE TABLE t1 (
+price int(5) DEFAULT '0' NOT NULL,
+area varchar(40) DEFAULT '' NOT NULL,
+type varchar(40) DEFAULT '' NOT NULL,
+transityes enum('Y','N') DEFAULT 'Y' NOT NULL,
+shopsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
+schoolsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
+petsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
+KEY price (price,area,type,transityes,shopsyes,schoolsyes,petsyes)
+);
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','N','N','N','N');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','N','N','N','N');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','','','','');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+SELECT * FROM t1 WHERE area='Vancouver' and transityes='y' and schoolsyes='y' and ( ((type='1 Bedroom' or type='Studio/Bach') and (price<=500)) or ((type='2 Bedroom') and (price<=550)) or ((type='Shared/Roomate') and (price<=300)) or ((type='Room and Board') and (price<=500)) ) and price <= 400;
price area type transityes shopsyes schoolsyes petsyes
+drop table t1;
+CREATE TABLE t1 (program enum('signup','unique','sliding') not null, type enum('basic','sliding','signup'), sites set('mt'), PRIMARY KEY (program));
+ALTER TABLE t1 modify program enum('signup','unique','sliding');
+All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead
+drop table t1;
+CREATE TABLE t1 (
+name varchar(50) DEFAULT '' NOT NULL,
+author varchar(50) DEFAULT '' NOT NULL,
+category decimal(10,0) DEFAULT '0' NOT NULL,
+email varchar(50),
+password varchar(50),
+proxy varchar(50),
+bitmap varchar(20),
+msg varchar(255),
+urlscol varchar(127),
+urlhttp varchar(127),
+timeout decimal(10,0),
+nbcnx decimal(10,0),
+creation decimal(10,0),
+livinguntil decimal(10,0),
+lang decimal(10,0),
+type decimal(10,0),
+subcat decimal(10,0),
+subtype decimal(10,0),
+reg char(1),
+scs varchar(255),
+capacity decimal(10,0),
+userISP varchar(50),
+CCident varchar(50) DEFAULT '' NOT NULL,
+PRIMARY KEY (name,author,category)
+);
+INSERT INTO t1 VALUES
+('patnom','patauteur',0,'p.favre@cryo-networks.fr',NULL,NULL,'#p2sndnq6ae5g1u6t','essai\nsalut','scol://195.242.78.119:patauteur.patnom',NULL,NULL,NULL,950036174,-882087474,NULL,3,0,3,'1','Pub/patnom/futur_divers.scs',NULL,'pat','CC1');
+INSERT INTO t1 VALUES
+('LeNomDeMonSite','Marc',0,'m.barilley@cryo-networks.fr',NULL,NULL,NULL,NULL,'scol://195.242.78.119:Marc.LeNomDeMonSite',NULL,NULL,NULL,950560434,-881563214,NULL,3,0,3,'1','Pub/LeNomDeMonSite/domus_hibere.scs',NULL,'Marq','CC1');
+select * from t1 where name='patnom' and author='patauteur' and category=0;
name author category email password proxy bitmap msg urlscol urlhttp timeout nbcnx creation livinguntil lang type subcat subtype reg scs capacity userISP CCident
patnom patauteur 0 p.favre@cryo-networks.fr NULL NULL #p2sndnq6ae5g1u6t essai
salut scol://195.242.78.119:patauteur.patnom NULL NULL NULL 950036174 -882087474 NULL 3 0 3 1 Pub/patnom/futur_divers.scs NULL pat CC1
+drop table t1;
+create table t1
+(
+name_id int not null auto_increment,
+name blob,
+INDEX name_idx (name(5)),
+primary key (name_id)
+);
+INSERT t1 VALUES(NULL,'/');
+INSERT t1 VALUES(NULL,'[T,U]_axpby');
+SELECT * FROM t1 WHERE name='[T,U]_axpy';
name_id name
+SELECT * FROM t1 WHERE name='[T,U]_axpby';
name_id name
2 [T,U]_axpby
+create table t2
+(
+name_id int not null auto_increment,
+name char(255) binary,
+INDEX name_idx (name(5)),
+primary key (name_id)
+);
+INSERT t2 select * from t1;
+SELECT * FROM t2 WHERE name='[T,U]_axpy';
name_id name
+SELECT * FROM t2 WHERE name='[T,U]_axpby';
name_id name
2 [T,U]_axpby
+drop table t1,t2;
+create table t1
+(
+SEQNO numeric(12 ) not null,
+MOTYPEID numeric(12 ) not null,
+MOINSTANCEID numeric(12 ) not null,
+ATTRID numeric(12 ) not null,
+VALUE varchar(120) not null,
+primary key (SEQNO, MOTYPEID, MOINSTANCEID, ATTRID, VALUE )
+);
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'b');
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
+Duplicate entry '1-1-1-1-a' for key 1
+drop table t1;
+CREATE TABLE t1 (
+a tinytext NOT NULL,
+b tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (a(32),b)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('a',1),('a',2);
+SELECT * FROM t1 WHERE a='a' AND b=2;
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (2);
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (1,2);
a b
a 1
a 2
+drop table t1;
+create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique);
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 d A 0 NULL NULL BTREE
+t1 0 a 1 a A 0 NULL NULL BTREE
+t1 0 e 1 e A 0 NULL NULL BTREE
+t1 0 b 1 b A NULL NULL NULL YES BTREE
+t1 1 c 1 c A NULL NULL NULL YES BTREE
+drop table t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+c i
+ 1
+ 2
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+c i
+ 1
+ 2
+a 1
+a 2
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NULL, i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+c i
+NULL 1
+NULL 2
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+c i
+NULL 1
+NULL 2
+a 1
+a 2
+drop table t1;
diff --git a/mysql-test/r/key_diff.result b/mysql-test/r/key_diff.result
index ab5b9bcc0e7..0886850f38a 100644
--- a/mysql-test/r/key_diff.result
+++ b/mysql-test/r/key_diff.result
@@ -1,3 +1,12 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+a char(5) NOT NULL,
+b char(4) NOT NULL,
+KEY (a),
+KEY (b)
+);
+INSERT INTO t1 VALUES ('A','B'),('b','A'),('C','c'),('D','E'),('a','a');
+select * from t1,t1 as t2;
a b a b
A B A B
b A A B
@@ -24,9 +33,11 @@ b A a a
C c a a
D E a a
a a a a
+explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
table type possible_keys key key_len ref rows Extra
t1 ALL a NULL NULL NULL 5
t2 ALL b NULL NULL NULL 5 where used
+select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
a b a b
A B a a
A B b A
@@ -34,6 +45,8 @@ C c C c
a a a a
a a b A
b A A B
+select * from t1 where a='a';
a b
A B
a a
+drop table t1;
diff --git a/mysql-test/r/key_primary.result b/mysql-test/r/key_primary.result
index ee0c1c957dc..10771a134fc 100644
--- a/mysql-test/r/key_primary.result
+++ b/mysql-test/r/key_primary.result
@@ -1,9 +1,19 @@
+create table t1 (t1 char(3) primary key);
+insert into t1 values("ABC");
+insert into t1 values("ABA");
+insert into t1 values("AB%");
+select * from t1 where t1="ABC";
t1
ABC
+select * from t1 where t1="ABCD";
t1
+select * from t1 where t1 like "a_\%";
t1
AB%
+describe select * from t1 where t1="ABC";
table type possible_keys key key_len ref rows Extra
t1 const PRIMARY PRIMARY 3 const 1
+describe select * from t1 where t1="ABCD";
Comment
Impossible WHERE noticed after reading const tables
+drop table t1;
diff --git a/mysql-test/r/keywords.result b/mysql-test/r/keywords.result
index f49681ad93b..2ca36425841 100644
--- a/mysql-test/r/keywords.result
+++ b/mysql-test/r/keywords.result
@@ -1,4 +1,16 @@
+drop table if exists t1;
+create table t1 (time time, date date, timestamp timestamp);
+insert into t1 values ("12:22:22","97:02:03","1997-01-02");
+select * from t1;
time date timestamp
12:22:22 1997-02-03 19970102000000
+select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1;
t1.time+0 t1.date+0 t1.timestamp+0 concat(date," ",time)
122222 19970203 19970102000000 1997-02-03 12:22:22
+drop table t1;
+create table events(binlog int);
+insert into events values(1);
+select events.binlog from events;
+binlog
+1
+drop table events;
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index 628c6d21094..788fab8d31a 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -1,4 +1,11 @@
+drop table if exists t1;
+create table t1 (kill_id int);
+insert into t1 values(connection_id());
+select ((@id := kill_id) - kill_id) from t1;
((@id := kill_id) - kill_id)
0
+kill @id;
+select 4;
4
4
+drop table t1;
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index 6c3a1ed17e4..5a8edc99c12 100644
--- a/mysql-test/r/limit.result
+++ b/mysql-test/r/limit.result
@@ -1,25 +1,52 @@
+drop table if exists t1;
+create table t1 (a int primary key, b int not null);
+insert into t1 () values ();
+insert into t1 values (1,1),(2,1),(3,1);
+update t1 set a=4 where b=1 limit 1;
+select * from t1;
a b
0 0
4 1
2 1
3 1
+update t1 set b=2 where b=1 limit 2;
+select * from t1;
a b
0 0
4 2
2 2
3 1
+update t1 set b=4 where b=1;
+select * from t1;
a b
0 0
4 2
2 2
3 4
+delete from t1 where b=2 limit 1;
+select * from t1;
a b
0 0
2 2
3 4
+delete from t1 limit 1;
+select * from t1;
a b
2 2
3 4
+drop table t1;
+create table t1 (i int);
+insert into t1 (i) values(1);
+insert into t1 (i) values(1);
+insert into t1 (i) values(1);
+delete from t1 limit 1;
+update t1 set i=2 limit 1;
+delete from t1 limit 0;
+update t1 set i=3 limit 0;
+select * from t1;
i
2
1
+drop table t1;
+select 0 limit 0;
+0
diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result
index ccd3c02558d..ad5251b9110 100644
--- a/mysql-test/r/lock.result
+++ b/mysql-test/r/lock.result
@@ -1,10 +1,45 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY (`id`,`id2`), KEY `index_id3` (`id3`)) TYPE=MyISAM;
+insert into t1 (id,id2) values (1,1),(1,2),(1,3);
+LOCK TABLE t1 WRITE;
+select dummy1,count(distinct id) from t1 group by dummy1;
dummy1 count(distinct id)
NULL 1
+update t1 set id=-1 where id=1;
+LOCK TABLE t1 READ;
+update t1 set id=1 where id=1;
+Table 't1' was locked with a READ lock and can't be updated
+create table t2 SELECT * from t1;
+Table 't2' was not locked with LOCK TABLES
+create temporary table t2 SELECT * from t1;
+drop table if exists t2;
+unlock tables;
+create table t2 SELECT * from t1;
+LOCK TABLE t1 WRITE,t2 write;
+insert into t2 SELECT * from t1;
+update t1 set id=1 where id=-1;
+drop table t1,t2;
+CREATE TABLE t1 (
+index1 smallint(6) default NULL,
+nr smallint(6) default NULL,
+KEY index1(index1)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+nr smallint(6) default NULL,
+name varchar(20) default NULL
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'item1');
+INSERT INTO t2 VALUES (2,'item2');
+lock tables t1 write, t2 read;
+insert into t1 select 1,nr from t2 where name='item1';
+insert into t1 select 2,nr from t2 where name='item2';
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write;
+check table t2;
Table Op Msg_type Msg_text
test.t2 check error Table 't2' was not locked with LOCK TABLES
-n
-4
-n
-1
+unlock tables;
+drop table t1,t2;
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
new file mode 100644
index 00000000000..6fe8cc71185
--- /dev/null
+++ b/mysql-test/r/lock_multi.result
@@ -0,0 +1,18 @@
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 write;
+ update low_priority t1 set n = 4;
+ select n from t1;
+unlock tables;
+n
+4
+drop table t1;
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 read;
+ update low_priority t1 set n = 4;
+ select n from t1;
+unlock tables;
+n
+1
+drop table t1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 653e25af799..b95352a9eaa 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -1,3 +1,10 @@
+drop table if exists t1,t2,t3,t4,t5,t6;
+create table t1 (a int not null primary key auto_increment, message char(20));
+create table t2 (a int not null primary key auto_increment, message char(20));
+INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
+INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2");
+create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(t1,t2);
+select * from t3;
a b
1 Testing
2 table
@@ -5,6 +12,7 @@ a b
1 Testing
2 table
3 t2
+select * from t3 order by a desc;
a b
3 t1
3 t2
@@ -12,13 +20,30 @@ a b
2 table
1 Testing
1 Testing
+drop table t3;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(test.t1,test.t2);
+explain select * from t3 where a < 10;
table type possible_keys key key_len ref rows Extra
t3 range a a 4 NULL 10 where used
+explain select * from t3 where a > 10 and a < 20;
table type possible_keys key key_len ref rows Extra
t3 range a a 4 NULL 10 where used
+select * from t3 where a = 10;
a b
10 Testing
10 Testing
+select * from t3 where a < 10;
a b
1 Testing
1 Testing
@@ -38,6 +63,7 @@ a b
8 table
9 t2
9 t2
+select * from t3 where a > 10 and a < 20;
a b
11 table
11 table
@@ -57,8 +83,10 @@ a b
18 t2
19 Testing
19 Testing
+explain select a from t3 order by a desc limit 10;
table type possible_keys key key_len ref rows Extra
t3 index NULL a 4 NULL 1131 Using index
+select a from t3 order by a desc limit 10;
a
699
698
@@ -70,6 +98,7 @@ a
692
691
690
+select a from t3 order by a desc limit 300,10;
a
416
415
@@ -81,12 +110,87 @@ a
412
412
411
+delete from t3 where a=3;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+4 Testing
+4 Testing
+5 table
+5 table
+6 t2
+6 t1
+7 Testing
+7 Testing
+8 table
+8 table
+9 t2
+9 t2
+delete from t3 where a >= 6 and a <= 8;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+4 Testing
+4 Testing
+5 table
+5 table
+9 t2
+9 t2
+update t3 set a=3 where a=9;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+3 t2
+3 t2
+4 Testing
+4 Testing
+5 table
+5 table
+update t3 set a=6 where a=7;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+3 t2
+3 t2
+4 Testing
+4 Testing
+5 table
+5 table
+show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` int(11) NOT NULL default '0',
`b` char(20) default NULL,
KEY `a` (`a`)
) TYPE=MRG_MyISAM UNION=(t1,t2)
+create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
+select * from t4;
+Can't open file: 't4.MRG'. (errno: 143)
+create table t5 (a int not null, b char(10), key(a)) type=MERGE UNION=(test.t1,test_2.t2);
+Incorrect table definition; All MERGE tables must be in the same database
+drop table if exists t5,t4,t3,t1,t2;
+create table t1 (c char(10)) type=myisam;
+create table t2 (c char(10)) type=myisam;
+create table t3 (c char(10)) union=(t1,t2) type=merge;
+insert into t1 (c) values ('test1');
+insert into t1 (c) values ('test1');
+insert into t1 (c) values ('test1');
+insert into t2 (c) values ('test2');
+insert into t2 (c) values ('test2');
+insert into t2 (c) values ('test2');
+select * from t3;
c
test1
test1
@@ -94,6 +198,7 @@ test1
test2
test2
test2
+select * from t3;
c
test1
test1
@@ -101,32 +206,338 @@ test1
test2
test2
test2
+delete from t3 where 1=1;
+select * from t3;
c
+select * from t1;
c
+drop table t3,t2,t1;
+CREATE TABLE t1 (incr int not null, othr int not null, primary key(incr));
+CREATE TABLE t2 (incr int not null, othr int not null, primary key(incr));
+CREATE TABLE t3 (incr int not null, othr int not null, primary key(incr))
+TYPE=MERGE UNION=(t1,t2);
+SELECT * from t3;
incr othr
+INSERT INTO t1 VALUES ( 1,10),( 3,53),( 5,21),( 7,12),( 9,17);
+INSERT INTO t2 VALUES ( 2,24),( 4,33),( 6,41),( 8,26),( 0,32);
+INSERT INTO t1 VALUES (11,20),(13,43),(15,11),(17,22),(19,37);
+INSERT INTO t2 VALUES (12,25),(14,31),(16,42),(18,27),(10,30);
+SELECT * from t3 where incr in (1,2,3,4) order by othr;
incr othr
1 10
2 24
4 33
3 53
+alter table t3 UNION=(t1);
+select count(*) from t3;
count(*)
10
+alter table t3 UNION=(t1,t2);
+select count(*) from t3;
count(*)
20
+alter table t3 TYPE=MYISAM;
+select count(*) from t3;
count(*)
20
+drop table t3;
+CREATE TABLE t3 (incr int not null, othr int not null, primary key(incr))
+TYPE=MERGE UNION=(t1,t2);
+show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`incr` int(11) NOT NULL default '0',
`othr` int(11) NOT NULL default '0',
PRIMARY KEY (`incr`)
) TYPE=MRG_MyISAM UNION=(t1,t2)
+alter table t3 drop primary key;
+show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`incr` int(11) NOT NULL default '0',
`othr` int(11) NOT NULL default '0'
) TYPE=MRG_MyISAM UNION=(t1,t2)
+drop table t3,t2,t1;
+create table t1 (a int not null) type=merge;
+select * from t1;
a
+drop table t1;
+drop table if exists t3, t2, t1;
+create table t1 (a int not null, b int not null, key(a,b));
+create table t2 (a int not null, b int not null, key(a,b));
+create table t3 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2);
+insert into t1 values (1,2),(2,1),(0,0),(4,4),(5,5),(6,6);
+insert into t2 values (1,1),(2,2),(0,0),(4,4),(5,5),(6,6);
+flush tables;
+select * from t3 where a=1 order by b limit 2;
+a b
+1 1
+1 2
+drop table t3,t1,t2;
+drop table if exists t6, t5, t4, t3, t2, t1;
+create table t1 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t2 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t3 (a int not null, b int not null, key(a,b)) UNION=(t1,t2) INSERT_METHOD=NO;
+create table t4 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=NO;
+create table t5 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+create table t6 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MyISAM
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MRG_MyISAM UNION=(t1,t2)
+show create table t5;
+Table Create Table
+t5 CREATE TABLE `t5` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL auto_increment,
+ PRIMARY KEY (`a`,`b`)
+) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2)
+show create table t6;
+Table Create Table
+t6 CREATE TABLE `t6` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL auto_increment,
+ PRIMARY KEY (`a`,`b`)
+) TYPE=MRG_MyISAM INSERT_METHOD=LAST UNION=(t1,t2)
+insert into t1 values (1,NULL),(1,NULL),(1,NULL),(1,NULL);
+insert into t2 values (2,NULL),(2,NULL),(2,NULL),(2,NULL);
+select * from t3 order by b,a limit 3;
+a b
+select * from t4 order by b,a limit 3;
+a b
+1 1
+2 1
+1 2
+select * from t5 order by b,a limit 3,3;
+a b
+2 2
+1 3
+2 3
+select * from t6 order by b,a limit 6,3;
+a b
+1 4
+2 4
+insert into t5 values (5,1),(5,2);
+insert into t6 values (6,1),(6,2);
+select * from t1 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+5 1
+5 2
+select * from t2 order by a,b;
+a b
+2 1
+2 2
+2 3
+2 4
+6 1
+6 2
+select * from t4 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+5 1
+5 2
+6 1
+6 2
+insert into t3 values (3,1),(3,2),(3,3),(3,4);
+select * from t3 order by a,b;
+a b
+3 1
+3 2
+3 3
+3 4
+alter table t4 UNION=(t1,t2,t3);
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MRG_MyISAM UNION=(t1,t2,t3)
+select * from t4 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+3 1
+3 2
+3 3
+3 4
+5 1
+5 2
+6 1
+6 2
+alter table t4 INSERT_METHOD=FIRST;
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2,t3)
+insert into t4 values (4,1),(4,2);
+select * from t1 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+4 1
+4 2
+5 1
+5 2
+select * from t2 order by a,b;
+a b
+2 1
+2 2
+2 3
+2 4
+6 1
+6 2
+select * from t3 order by a,b;
+a b
+3 1
+3 2
+3 3
+3 4
+select * from t4 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+3 1
+3 2
+3 3
+3 4
+4 1
+4 2
+5 1
+5 2
+6 1
+6 2
+select * from t5 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+4 1
+4 2
+5 1
+5 2
+6 1
+6 2
+select 1;
+1
+1
+insert into t5 values (1,NULL),(5,NULL);
+insert into t6 values (2,NULL),(6,NULL);
+select * from t1 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+1 5
+4 1
+4 2
+5 1
+5 2
+5 3
+select * from t2 order by a,b;
+a b
+2 1
+2 2
+2 3
+2 4
+2 5
+6 1
+6 2
+6 3
+select * from t5 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+1 5
+2 1
+2 2
+2 3
+2 4
+2 5
+4 1
+4 2
+5 1
+5 2
+5 3
+6 1
+6 2
+6 3
+select * from t6 order by a,b;
a b
1 1
1 2
+1 3
+1 4
+1 5
+2 1
+2 2
+2 3
+2 4
+2 5
+4 1
+4 2
+5 1
+5 2
+5 3
+6 1
+6 2
+6 3
+drop table if exists t6, t5, t4, t3, t2, t1;
+CREATE TABLE t1 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE t2 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,2), (2,2);
+CREATE TABLE t ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', KEY a (a,b)) TYPE=MRG_MyISAM UNION=(t1,t2);
+select max(b) from t where a = 2;
+max(b)
+NULL
+select max(b) from t1 where a = 2;
+max(b)
+1
+drop table if exists t,t1,t2;
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
new file mode 100644
index 00000000000..e6622916252
--- /dev/null
+++ b/mysql-test/r/multi_update.result
@@ -0,0 +1,72 @@
+drop table if exists t1,t2,t3;
+create table t1(id1 int not null auto_increment primary key, t char(12));
+create table t2(id2 int not null, t char(12));
+create table t3(id3 int not null, t char(12), index(id3));
+select count(*) from t1 where id1 > 95;
+count(*)
+5
+select count(*) from t2 where id2 > 95;
+count(*)
+25
+select count(*) from t3 where id3 > 95;
+count(*)
+250
+update t1,t2,t3 set t1.t="aaa", t2.t="bbb", t3.t="cc" where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 90;
+select count(*) from t1 where t = "aaa";
+count(*)
+10
+select count(*) from t1 where id1 > 90;
+count(*)
+10
+select count(*) from t2 where t = "bbb";
+count(*)
+10
+select count(*) from t2 where id2 > 90;
+count(*)
+50
+select count(*) from t3 where t = "cc";
+count(*)
+500
+select count(*) from t3 where id3 > 90;
+count(*)
+500
+delete t1.*, t2.*, t3.* from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 95;
+check table t1, t2, t3;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+select count(*) from t1 where id1 > 95;
+count(*)
+0
+select count(*) from t2 where id2 > 95;
+count(*)
+0
+select count(*) from t3 where id3 > 95;
+count(*)
+0
+delete t1, t2, t3 from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 5;
+select count(*) from t1 where id1 > 5;
+count(*)
+0
+select count(*) from t2 where id2 > 5;
+count(*)
+0
+select count(*) from t3 where id3 > 5;
+count(*)
+0
+delete from t1, t2, t3 using t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 0;
+select count(*) from t1 where id1;
+count(*)
+0
+select count(*) from t2 where id2;
+count(*)
+0
+select count(*) from t3 where id3;
+count(*)
+0
+drop table t1,t2,t3;
+create table t1(id1 int not null primary key, t varchar(100)) pack_keys = 1;
+create table t2(id2 int not null, t varchar(100), index(id2)) pack_keys = 1;
+delete t1 from t1,t2 where t1.id1 = t2.id2 and t1.id1 > 500;
+drop table t1,t2;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index a8f97c57d33..8750ea94125 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1,38 +1,102 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+STRING_DATA char(255) default NULL,
+KEY STRING_DATA (STRING_DATA)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
+INSERT INTO t1 VALUES ('DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD');
+INSERT INTO t1 VALUES ('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF');
+INSERT INTO t1 VALUES ('FGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG');
+INSERT INTO t1 VALUES ('HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH');
+INSERT INTO t1 VALUES ('WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW');
+CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
+delete from t1 where (a & 1);
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+create table t1 (a int not null auto_increment, b int not null, primary key (a), index(b));
+insert into t1 (b) values (1),(2),(2),(2),(2);
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status Table is already up to date
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+drop table t1;
+create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=myisam;
+insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
+explain select * from t1 order by a;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select * from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select * from t1 order by c;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select a from t1 order by a;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 4 Using index
+explain select b from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 index NULL b 4 NULL 4 Using index
+explain select a,b from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select a,b from t1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4
+explain select a,b,c from t1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4
+drop table t1;
+CREATE TABLE `t1` (
+`post_id` mediumint(8) unsigned NOT NULL auto_increment,
+`topic_id` mediumint(8) unsigned NOT NULL default '0',
+`post_time` datetime NOT NULL default '0000-00-00 00:00:00',
+`post_text` text NOT NULL,
+`icon_url` varchar(10) NOT NULL default '',
+`sign` tinyint(1) unsigned NOT NULL default '0',
+`post_edit` varchar(150) NOT NULL default '',
+`poster_login` varchar(35) NOT NULL default '',
+`ip` varchar(15) NOT NULL default '',
+PRIMARY KEY (`post_id`),
+KEY `post_time` (`post_time`),
+KEY `ip` (`ip`),
+KEY `poster_login` (`poster_login`),
+KEY `topic_id` (`topic_id`),
+FULLTEXT KEY `post_text` (`post_text`)
+) TYPE=MyISAM;
+INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/not_embedded.require b/mysql-test/r/not_embedded.require
new file mode 100644
index 00000000000..b2ea98bcd0a
--- /dev/null
+++ b/mysql-test/r/not_embedded.require
@@ -0,0 +1,2 @@
+have_embedded
+0
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index 9f0bdb07973..e6e3b7155a3 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -1,32 +1,58 @@
+select null,\N,isnull(null),isnull(1/0),isnull(1/0 = null),ifnull(null,1),ifnull(null,"TRUE"),ifnull("TRUE","ERROR"),1/0 is null,1 is not null;
NULL NULL isnull(null) isnull(1/0) isnull(1/0 = null) ifnull(null,1) ifnull(null,"TRUE") ifnull("TRUE","ERROR") 1/0 is null 1 is not null
NULL NULL 1 1 1 1 TRUE TRUE 1 1
+select 1 | NULL,1 & NULL,1+NULL,1-NULL;
1 | NULL 1 & NULL 1+NULL 1-NULL
NULL NULL NULL NULL
+select NULL=NULL,NULL<>NULL,IFNULL(NULL,1.1)+0,IFNULL(NULL,1) | 0;
NULL=NULL NULL<>NULL IFNULL(NULL,1.1)+0 IFNULL(NULL,1) | 0
NULL NULL 1.1 1
+select strcmp("a",NULL),(1<NULL)+0.0,NULL regexp "a",null like "a%","a%" like null;
strcmp("a",NULL) (1<NULL)+0.0 NULL regexp "a" null like "a%" "a%" like null
NULL NULL NULL NULL NULL
+select concat("a",NULL),replace(NULL,"a","b"),replace("string","i",NULL),replace("string",NULL,"i"),insert("abc",1,1,NULL),left(NULL,1);
concat("a",NULL) replace(NULL,"a","b") replace("string","i",NULL) replace("string",NULL,"i") insert("abc",1,1,NULL) left(NULL,1)
NULL NULL NULL NULL NULL NULL
+select repeat("a",0),repeat("ab",5+5),repeat("ab",-1),reverse(NULL);
repeat("a",0) repeat("ab",5+5) repeat("ab",-1) reverse(NULL)
abababababababababab NULL
+select field(NULL,"a","b","c");
field(NULL,"a","b","c")
0
+select 2 between null and 1,2 between 3 AND NULL,NULL between 1 and 2,2 between NULL and 3, 2 between 1 AND null;
2 between null and 1 2 between 3 AND NULL NULL between 1 and 2 2 between NULL and 3 2 between 1 AND null
0 0 NULL NULL NULL
+SELECT NULL AND NULL, 1 AND NULL, NULL AND 1, NULL OR NULL, 0 OR NULL, NULL OR 0;
NULL AND NULL 1 AND NULL NULL AND 1 NULL OR NULL 0 OR NULL NULL OR 0
NULL NULL NULL NULL NULL NULL
+SELECT (NULL OR NULL) IS NULL;
(NULL OR NULL) IS NULL
1
+select NULL AND 0, 0 and NULL;
NULL AND 0 0 and NULL
NULL 0
+select inet_ntoa(null),inet_aton(null),inet_aton("122.256"),inet_aton("122.226."),inet_aton("");
inet_ntoa(null) inet_aton(null) inet_aton("122.256") inet_aton("122.226.") inet_aton("")
NULL NULL NULL NULL NULL
+drop table if exists t1;
+create table t1 (x int);
+insert into t1 values (null);
+select * from t1 where x != 0;
x
+drop table t1;
+CREATE TABLE t1 (
+indexed_field int default NULL,
+KEY indexed_field (indexed_field)
+);
+INSERT INTO t1 VALUES (NULL),(NULL);
+SELECT * FROM t1 WHERE indexed_field=NULL;
indexed_field
+SELECT * FROM t1 WHERE indexed_field IS NULL;
indexed_field
NULL
NULL
+SELECT * FROM t1 WHERE indexed_field<=>NULL;
indexed_field
NULL
NULL
+DROP TABLE t1;
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index ead1dc29326..a28830a696d 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -1,101 +1,164 @@
+drop table if exists t1;
+create table t1 (a int, b int not null,unique key (a,b),index(b)) type=myisam;
+insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6);
+explain select * from t1 where a is null;
table type possible_keys key key_len ref rows Extra
t1 ref a a 5 const 3 where used; Using index
+explain select * from t1 where a is null and b = 2;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 9 const,const 1 where used; Using index
+explain select * from t1 where a is null and b = 7;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 9 const,const 1 where used; Using index
+explain select * from t1 where a=2 and b = 2;
table type possible_keys key key_len ref rows Extra
t1 const a,b a 9 const,const 1
+explain select * from t1 where a<=>b limit 2;
table type possible_keys key key_len ref rows Extra
t1 index NULL a 9 NULL 12 where used; Using index
+explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3;
table type possible_keys key key_len ref rows Extra
t1 range a,b a 9 NULL 3 where used; Using index
+explain select * from t1 where (a is null or a = 7) and b=7;
table type possible_keys key key_len ref rows Extra
t1 ref a,b b 4 const 2 where used
+explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 5 const 3 where used; Using index
+explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
table type possible_keys key key_len ref rows Extra
t1 range a,b a 9 NULL 2 where used; Using index
+explain select * from t1 where a > 1 and a < 3 limit 1;
table type possible_keys key key_len ref rows Extra
t1 range a a 5 NULL 1 where used; Using index
+explain select * from t1 where a > 8 and a < 9;
table type possible_keys key key_len ref rows Extra
t1 range a a 5 NULL 1 where used; Using index
+select * from t1 where a is null;
a b
NULL 7
NULL 9
NULL 9
+select * from t1 where a is null and b = 7;
a b
NULL 7
+select * from t1 where a<=>b limit 2;
a b
1 1
2 2
+select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3;
a b
1 1
2 2
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
a b
NULL 9
NULL 9
+select * from t1 where (a is null or a = 7) and b=7;
a b
NULL 7
7 7
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
a b
NULL 7
NULL 9
NULL 9
+alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10));
+explain select * from t1 where a is null and b = 2;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 5 const 3 where used
+explain select * from t1 where a is null and b = 2 and c=0;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 5 const 3 where used
+explain select * from t1 where a is null and b = 7 and c=0;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 5 const 3 where used
+explain select * from t1 where a=2 and b = 2;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 5 const 1 where used
+explain select * from t1 where a<=>b limit 2;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 12 where used
+explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 and c=0 limit 3;
table type possible_keys key key_len ref rows Extra
-t1 range a,b a 5 NULL 12 where used
+t1 range a,b a 5 NULL 5 where used
+explain select * from t1 where (a is null or a = 7) and b=7 and c=0;
table type possible_keys key key_len ref rows Extra
t1 range a,b a 5 NULL 4 where used
+explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 5 const 3 where used
+explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
table type possible_keys key key_len ref rows Extra
t1 ref a,b a 5 const 3 where used
+explain select * from t1 where a > 1 and a < 3 limit 1;
table type possible_keys key key_len ref rows Extra
t1 range a a 5 NULL 1 where used
+explain select * from t1 where a is null and b=7 or a > 1 and a < 3 limit 1;
table type possible_keys key key_len ref rows Extra
t1 range a,b a 5 NULL 4 where used
+explain select * from t1 where a > 8 and a < 9;
table type possible_keys key key_len ref rows Extra
t1 range a a 5 NULL 1 where used
+explain select * from t1 where b like "6%";
table type possible_keys key key_len ref rows Extra
t1 range b b 12 NULL 1 where used
+select * from t1 where a is null;
a b c
NULL 7 0
NULL 9 0
NULL 9 0
+select * from t1 where a is null and b = 7 and c=0;
a b c
NULL 7 0
+select * from t1 where a<=>b limit 2;
a b c
1 1 0
2 2 0
+select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3;
a b c
1 1 0
2 2 0
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
a b c
NULL 9 0
NULL 9 0
+select * from t1 where (a is null or a = 7) and b=7 and c=0;
a b c
NULL 7 0
7 7 0
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
a b c
NULL 7 0
NULL 9 0
NULL 9 0
+select * from t1 where b like "6%";
a b c
6 6 0
+drop table t1;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL auto_increment,
+uniq_id int(10) unsigned default NULL,
+PRIMARY KEY (id),
+UNIQUE KEY idx1 (uniq_id)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL auto_increment,
+uniq_id int(10) unsigned default NULL,
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
+INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
+explain select id from t1 where uniq_id is null;
table type possible_keys key key_len ref rows Extra
t1 ref idx1 idx1 5 const 1 where used
+explain select id from t1 where uniq_id =1;
table type possible_keys key key_len ref rows Extra
t1 const idx1 idx1 5 const 1
+UPDATE t1 SET id=id+100 where uniq_id is null;
+UPDATE t2 SET id=id+100 where uniq_id is null;
+select id from t1 where uniq_id is null;
id
101
102
@@ -103,6 +166,7 @@ id
106
109
110
+select id from t2 where uniq_id is null;
id
101
102
@@ -110,13 +174,18 @@ id
106
109
110
+DELETE FROM t1 WHERE uniq_id IS NULL;
+DELETE FROM t2 WHERE uniq_id IS NULL;
+SELECT * FROM t1 ORDER BY uniq_id, id;
id uniq_id
3 1
4 2
7 3
8 4
+SELECT * FROM t2 ORDER BY uniq_id, id;
id uniq_id
3 1
4 2
7 3
8 4
+DROP table t1,t2;
diff --git a/mysql-test/r/odbc.result b/mysql-test/r/odbc.result
index 753d80e4539..c696cf94e9d 100644
--- a/mysql-test/r/odbc.result
+++ b/mysql-test/r/odbc.result
@@ -1,7 +1,15 @@
+select {fn length("hello")}, { date "1997-10-20" };
{fn length("hello")} 1997-10-20
5 1997-10-20
+create table t1 (a int not null auto_increment,b int not null,primary key (a,b));
+insert into t1 SET A=NULL,B=1;
+insert into t1 SET a=null,b=2;
+select * from t1 where a is null and b=2;
a b
2 2
+select * from t1 where a is null;
a b
+explain select * from t1 where b is null;
Comment
Impossible WHERE noticed after reading const tables
+drop table t1;
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
new file mode 100644
index 00000000000..fa6008e99f7
--- /dev/null
+++ b/mysql-test/r/olap.result
@@ -0,0 +1,27 @@
+drop table if exists sales;
+create table sales ( product varchar(32), country varchar(32), year int, profit int);
+insert into sales values ( 'Computer', 'India',2000, 1200),
+( 'TV', 'United States', 1999, 150),
+( 'Calculator', 'United States', 1999,50),
+( 'Computer', 'United States', 1999,1500),
+( 'Computer', 'United States', 2000,1500),
+( 'TV', 'United States', 2000, 150),
+( 'TV', 'India', 2000, 100),
+( 'TV', 'India', 2000, 100),
+( 'Calculator', 'United States', 2000,75),
+( 'Calculator', 'India', 2000,75),
+( 'TV', 'India', 1999, 100),
+( 'Computer', 'India', 1999,1200),
+( 'Computer', 'United States', 2000,1500),
+( 'Calculator', 'United States', 2000,75);
+select product, country , year, sum(profit) from sales group by product, country, year with cube;
+This version of MySQL doesn't yet support 'CUBE',
+explain select product, country , year, sum(profit) from sales group by product, country, year with cube;
+This version of MySQL doesn't yet support 'CUBE',
+select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+This version of MySQL doesn't yet support 'ROLLUP',
+explain select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+This version of MySQL doesn't yet support 'ROLLUP',
+select product, country , year, sum(profit) from sales group by product, country, year with cube union all select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+This version of MySQL doesn't yet support 'CUBE',
+drop table sales;
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
new file mode 100644
index 00000000000..b5c67dfbcb0
--- /dev/null
+++ b/mysql-test/r/openssl_1.result
@@ -0,0 +1,2 @@
+SHOW STATUS LIKE 'SSL%';
+Variable_name Value
diff --git a/mysql-test/r/openssl_2.result b/mysql-test/r/openssl_2.result
new file mode 100644
index 00000000000..b5c67dfbcb0
--- /dev/null
+++ b/mysql-test/r/openssl_2.result
@@ -0,0 +1,2 @@
+SHOW STATUS LIKE 'SSL%';
+Variable_name Value
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 1a292b1203c..9bc716ee8b9 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -1,3 +1,39 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+id int(6) DEFAULT '0' NOT NULL,
+idservice int(5),
+clee char(20) NOT NULL,
+flag char(1),
+KEY id (id),
+PRIMARY KEY (clee)
+);
+INSERT INTO t1 VALUES (2,4,'6067169d','Y');
+INSERT INTO t1 VALUES (2,5,'606716d1','Y');
+INSERT INTO t1 VALUES (2,1,'606717c1','Y');
+INSERT INTO t1 VALUES (3,1,'6067178d','Y');
+INSERT INTO t1 VALUES (2,6,'60671515','Y');
+INSERT INTO t1 VALUES (2,7,'60671569','Y');
+INSERT INTO t1 VALUES (2,3,'dd','Y');
+CREATE TABLE t2 (
+id int(6) DEFAULT '0' NOT NULL auto_increment,
+description varchar(40) NOT NULL,
+idform varchar(40),
+ordre int(6) unsigned DEFAULT '0' NOT NULL,
+image varchar(60),
+PRIMARY KEY (id),
+KEY id (id,ordre)
+);
+INSERT INTO t2 VALUES (1,'Emettre un appel d''offres','en_construction.html',10,'emettre.gif');
+INSERT INTO t2 VALUES (2,'Emettre des soumissions','en_construction.html',20,'emettre.gif');
+INSERT INTO t2 VALUES (7,'Liste des t2','t2_liste_form.phtml',51060,'link.gif');
+INSERT INTO t2 VALUES (8,'Consulter les soumissions','consulter_soumissions.phtml',200,'link.gif');
+INSERT INTO t2 VALUES (9,'Ajouter un type de materiel','typeMateriel_ajoute_form.phtml',51000,'link.gif');
+INSERT INTO t2 VALUES (10,'Lister/modifier un type de materiel','typeMateriel_liste_form.phtml',51010,'link.gif');
+INSERT INTO t2 VALUES (3,'Créer une fiche de client','clients_ajoute_form.phtml',40000,'link.gif');
+INSERT INTO t2 VALUES (4,'Modifier des clients','en_construction.html',40010,'link.gif');
+INSERT INTO t2 VALUES (5,'Effacer des clients','en_construction.html',40020,'link.gif');
+INSERT INTO t2 VALUES (6,'Ajouter un service','t2_ajoute_form.phtml',51050,'link.gif');
+select t1.id,t1.idservice,t2.ordre,t2.description from t1, t2 where t1.id = 2 and t1.idservice = t2.id order by t2.ordre;
id idservice ordre description
2 1 10 Emettre un appel d'offres
2 3 40000 Créer une fiche de client
@@ -5,34 +41,53 @@ id idservice ordre description
2 5 40020 Effacer des clients
2 6 51050 Ajouter un service
2 7 51060 Liste des t2
+drop table t1,t2;
+create table t1 (first char(10),last char(10));
+insert into t1 values ("Michael","Widenius");
+insert into t1 values ("Allan","Larsson");
+insert into t1 values ("David","Axmark");
+select concat(first," ",last) as name from t1 order by name;
name
Allan Larsson
David Axmark
Michael Widenius
+select concat(last," ",first) as name from t1 order by name;
name
Axmark David
Larsson Allan
Widenius Michael
+drop table t1;
+create table t1 (i int);
+insert into t1 values(1),(2),(1),(2),(1),(2),(3);
+select distinct i from t1;
i
1
2
3
+select distinct i from t1 order by rand(5);
i
1
3
2
+select distinct i from t1 order by i desc;
i
3
2
1
+select distinct i from t1 order by 1-i;
i
3
2
1
+select distinct i from t1 order by mod(i,2),i;
i
2
1
3
+drop table t1;
+create table t1 (id int not null,col1 int not null,col2 int not null,index(col1));
+insert into t1 values(1,2,2),(2,2,1),(3,1,2),(4,1,1),(5,1,4),(6,2,3),(7,3,1),(8,2,4);
+select * from t1 order by col1,col2;
id col1 col2
4 1 1
3 1 2
@@ -42,6 +97,7 @@ id col1 col2
6 2 3
8 2 4
7 3 1
+select col1 from t1 order by id;
col1
2
2
@@ -51,6 +107,7 @@ col1
2
3
2
+select col1 as id from t1 order by t1.id;
id
1
1
@@ -60,6 +117,7 @@ id
2
2
3
+select concat(col1) as id from t1 order by t1.id;
id
2
2
@@ -69,21 +127,75 @@ id
2
3
2
+drop table t1;
+CREATE TABLE t1 (id int auto_increment primary key,aika varchar(40),aikakentta timestamp);
+insert into t1 (aika) values ('Keskiviikko');
+insert into t1 (aika) values ('Tiistai');
+insert into t1 (aika) values ('Maanantai');
+insert into t1 (aika) values ('Sunnuntai');
+SELECT FIELD(SUBSTRING(t1.aika,1,2),'Ma','Ti','Ke','To','Pe','La','Su') AS test FROM t1 ORDER by test;
test
1
2
3
7
+drop table t1;
+CREATE TABLE t1
+(
+a int unsigned NOT NULL,
+b int unsigned NOT NULL,
+c int unsigned NOT NULL,
+UNIQUE(a),
+INDEX(b),
+INDEX(c)
+);
+CREATE TABLE t2
+(
+c int unsigned NOT NULL,
+i int unsigned NOT NULL,
+INDEX(c)
+);
+CREATE TABLE t3
+(
+c int unsigned NOT NULL,
+v varchar(64),
+INDEX(c)
+);
+INSERT INTO t1 VALUES (1,1,1);
+INSERT INTO t1 VALUES (2,1,2);
+INSERT INTO t1 VALUES (3,2,1);
+INSERT INTO t1 VALUES (4,2,2);
+INSERT INTO t2 VALUES (1,50);
+INSERT INTO t2 VALUES (2,25);
+INSERT INTO t3 VALUES (1,'123 Park Place');
+INSERT INTO t3 VALUES (2,'453 Boardwalk');
+SELECT a,b,if(b = 1,i,if(b = 2,v,''))
+FROM t1
+LEFT JOIN t2 USING(c)
+LEFT JOIN t3 ON t3.c = t1.c;
a b if(b = 1,i,if(b = 2,v,''))
1 1 50
2 1 25
3 2 123 Park Place
4 2 453 Boardwalk
+SELECT a,b,if(b = 1,i,if(b = 2,v,''))
+FROM t1
+LEFT JOIN t2 USING(c)
+LEFT JOIN t3 ON t3.c = t1.c
+ORDER BY a;
a b if(b = 1,i,if(b = 2,v,''))
1 1 50
2 1 25
3 2 123 Park Place
4 2 453 Boardwalk
+drop table t1,t2,t3;
+create table t1 (ID int not null primary key, TransactionID int not null);
+insert into t1 (ID, TransactionID) values (1, 87), (2, 89), (3, 92), (4, 94), (5, 486), (6, 490), (7, 753), (9, 828), (10, 832), (11, 834), (12, 840);
+create table t2 (ID int not null primary key, GroupID int not null);
+insert into t2 (ID, GroupID) values (87, 87), (89, 89), (92, 92), (94, 94), (486, 486), (490, 490),(753, 753), (828, 828), (832, 832), (834, 834), (840, 840);
+create table t3 (ID int not null primary key, DateOfAction date not null);
+insert into t3 (ID, DateOfAction) values (87, '1999-07-19'), (89, '1999-07-19'), (92, '1999-07-19'), (94, '1999-07-19'), (486, '1999-07-18'), (490, '2000-03-27'), (753, '2000-03-28'), (828, '1999-07-27'), (832, '1999-07-27'),(834, '1999-07-27'), (840, '1999-07-27');
+select t3.DateOfAction, t1.TransactionID from t1 join t2 join t3 where t2.ID = t1.TransactionID and t3.ID = t2.GroupID order by t3.DateOfAction, t1.TransactionID;
DateOfAction TransactionID
1999-07-18 486
1999-07-19 87
@@ -96,6 +208,7 @@ DateOfAction TransactionID
1999-07-27 840
2000-03-27 490
2000-03-28 753
+select t3.DateOfAction, t1.TransactionID from t1 join t2 join t3 where t2.ID = t1.TransactionID and t3.ID = t2.GroupID order by t1.TransactionID,t3.DateOfAction;
DateOfAction TransactionID
1999-07-19 87
1999-07-19 89
@@ -108,9 +221,218 @@ DateOfAction TransactionID
1999-07-27 832
1999-07-27 834
1999-07-27 840
+drop table t1,t2,t3;
+drop table if exists t1;
+CREATE TABLE t1 (
+member_id int(11) NOT NULL auto_increment,
+inschrijf_datum varchar(20) NOT NULL default '',
+lastchange_datum varchar(20) NOT NULL default '',
+nickname varchar(20) NOT NULL default '',
+password varchar(8) NOT NULL default '',
+voornaam varchar(30) NOT NULL default '',
+tussenvoegsels varchar(10) NOT NULL default '',
+achternaam varchar(50) NOT NULL default '',
+straat varchar(100) NOT NULL default '',
+postcode varchar(10) NOT NULL default '',
+wijk varchar(40) NOT NULL default '',
+plaats varchar(50) NOT NULL default '',
+telefoon varchar(10) NOT NULL default '',
+geboortedatum date NOT NULL default '0000-00-00',
+geslacht varchar(5) NOT NULL default '',
+email varchar(80) NOT NULL default '',
+uin varchar(15) NOT NULL default '',
+homepage varchar(100) NOT NULL default '',
+internet varchar(15) NOT NULL default '',
+scherk varchar(30) NOT NULL default '',
+favo_boek varchar(50) NOT NULL default '',
+favo_tijdschrift varchar(50) NOT NULL default '',
+favo_tv varchar(50) NOT NULL default '',
+favo_eten varchar(50) NOT NULL default '',
+favo_muziek varchar(30) NOT NULL default '',
+info text NOT NULL,
+ipnr varchar(30) NOT NULL default '',
+PRIMARY KEY (member_id)
+) TYPE=MyISAM PACK_KEYS=1;
+insert into t1 (member_id) values (1),(2),(3);
+select member_id, nickname, voornaam FROM t1
+ORDER by lastchange_datum DESC LIMIT 2;
member_id nickname voornaam
1
2
+drop table t1;
+create table t1 (a int not null, b int, c varchar(10), key (a, b, c));
+insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b');
+explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 20 NULL 2 where used; Using index
+select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+a b c
+1 NULL b
+explain select * from t1 where a >= 1 and a < 3 order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 4 NULL 10 where used; Using index
+select * from t1 where a >= 1 and a < 3 order by a desc;
+a b c
+2 3 c
+2 2 b
+2 2 a
+2 1 b
+2 1 a
+1 3 b
+1 1 b
+1 1 b
+1 1 NULL
+1 NULL b
+1 NULL NULL
+explain select * from t1 where a = 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 4 const 5 where used; Using index
+select * from t1 where a = 1 order by a desc, b desc;
+a b c
+1 3 b
+1 1 b
+1 1 b
+1 1 NULL
+1 NULL b
+1 NULL NULL
+explain select * from t1 where a = 1 and b is null order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 9 const,const 2 where used; Using index; Using filesort
+select * from t1 where a = 1 and b is null order by a desc, b desc;
+a b c
+1 NULL NULL
+1 NULL b
+explain select * from t1 where a >= 1 and a < 3 and b >0 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 8 where used; Using index; Using filesort
+explain select * from t1 where a = 2 and b >0 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 5 where used; Using index
+explain select * from t1 where a = 2 and b is null order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 9 const,const 1 where used; Using index; Using filesort
+explain select * from t1 where a = 2 and (b is null or b > 0) order by a
+desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 6 where used; Using index
+explain select * from t1 where a = 2 and b > 0 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 5 where used; Using index
+explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 2 where used; Using index; Using filesort
+alter table t1 modify b int not null, modify c varchar(10) not null;
+explain select * from t1 order by a, b, c;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL a 18 NULL 11 Using index
+select * from t1 order by a, b, c;
+a b c
+1 0
+1 0 b
+1 1
+1 1 b
+1 1 b
+1 3 b
+2 1 a
+2 1 b
+2 2 a
+2 2 b
+2 3 c
+explain select * from t1 order by a desc, b desc, c desc;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL a 18 NULL 11 Using index
+select * from t1 order by a desc, b desc, c desc;
+a b c
+2 3 c
+2 2 b
+2 2 a
+2 1 b
+2 1 a
+1 3 b
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+explain select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 18 NULL 3 where used; Using index
+select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+a b c
+1 1 b
+1 1 b
+explain select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 4 NULL 6 where used; Using index
+select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+a b c
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+select count(*) from t1 where a < 5 and b > 0;
+count(*)
+9
+select * from t1 where a < 5 and b > 0 order by a desc,b desc;
+a b c
+2 3 c
+2 2 b
+2 2 a
+2 1 b
+2 1 a
+1 3 b
+1 1 b
+1 1 b
+1 1
+explain select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 8 NULL 10 where used; Using index
+select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+a b c
+2 1 b
+2 1 a
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+explain select * from t1 where a between 0 and 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 4 NULL 5 where used; Using index
+select * from t1 where a between 0 and 1 order by a desc, b desc;
+a b c
+1 3 b
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+drop table t1;
+CREATE TABLE t1 (
+gid int(10) unsigned NOT NULL auto_increment,
+cid smallint(5) unsigned NOT NULL default '0',
+PRIMARY KEY (gid),
+KEY component_id (cid)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (103853,108),(103867,108),(103962,108),(104505,108),(104619,108),(104620,108);
+ALTER TABLE t1 add skr int(10) not null;
+CREATE TABLE t2 (
+gid int(10) unsigned NOT NULL default '0',
+uid smallint(5) unsigned NOT NULL default '1',
+sid tinyint(3) unsigned NOT NULL default '1',
+PRIMARY KEY (gid),
+KEY uid (uid),
+KEY status_id (sid)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (103853,250,5),(103867,27,5),(103962,27,5),(104505,117,5),(104619,75,5),(104620,15,5);
+CREATE TABLE t3 (
+uid smallint(6) NOT NULL auto_increment,
+PRIMARY KEY (uid)
+) TYPE=MyISAM;
+INSERT INTO t3 VALUES (1),(15),(27),(75),(117),(250);
+ALTER TABLE t3 add skr int(10) not null;
+select t1.gid, t2.sid, t3.uid from t2, t1, t3 where t2.gid = t1.gid and t2.uid = t3.uid order by t3.uid, t1.gid;
gid sid uid
104620 5 15
103867 5 27
@@ -118,6 +440,7 @@ gid sid uid
104619 5 75
104505 5 117
103853 5 250
+select t1.gid, t2.sid, t3.uid from t3, t2, t1 where t2.gid = t1.gid and t2.uid = t3.uid order by t3.uid, t1.gid;
gid sid uid
104620 5 15
103867 5 27
@@ -125,20 +448,26 @@ gid sid uid
104619 5 75
104505 5 117
103853 5 250
+EXPLAIN select t1.gid, t2.sid, t3.uid from t3, t2, t1 where t2.gid = t1.gid and t2.uid = t3.uid order by t1.gid, t3.uid;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 6 Using index
t2 eq_ref PRIMARY,uid PRIMARY 4 t1.gid 1
t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 where used; Using index
+EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t1.gid,t3.skr;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 6 Using index
t3 eq_ref PRIMARY PRIMARY 2 t1.gid 1 where used
+EXPLAIN SELECT t1.gid, t2.sid, t3.uid from t2, t1, t3 where t2.gid = t1.gid and t2.uid = t3.uid order by t3.uid, t1.gid;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 6 Using index; Using temporary; Using filesort
t2 eq_ref PRIMARY,uid PRIMARY 4 t1.gid 1
t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 where used; Using index
+EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t3.skr,t1.gid;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 6 Using index; Using temporary; Using filesort
t3 eq_ref PRIMARY PRIMARY 2 t1.gid 1 where used
+EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,t3.skr;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
t3 eq_ref PRIMARY PRIMARY 2 t1.skr 1 where used
+drop table t1,t2,t3;
diff --git a/mysql-test/r/order_fill_sortbuf.result b/mysql-test/r/order_fill_sortbuf.result
new file mode 100644
index 00000000000..2226e842901
--- /dev/null
+++ b/mysql-test/r/order_fill_sortbuf.result
@@ -0,0 +1,10 @@
+drop table if exists t1,t2;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL default '0',
+`id2` int(11) NOT NULL default '0',
+`id3` int(11) NOT NULL default '0');
+create table t2 select id2 from t1 order by id3;
+select count(*) from t2;
+count(*)
+4000
+drop table t1,t2;
diff --git a/mysql-test/r/overflow.result b/mysql-test/r/overflow.result
new file mode 100644
index 00000000000..a5fa7154833
--- /dev/null
+++ b/mysql-test/r/overflow.result
@@ -0,0 +1,2 @@
+drop database AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
+Got one of the listed errors
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
new file mode 100644
index 00000000000..3afe1cd62cc
--- /dev/null
+++ b/mysql-test/r/query_cache.result
@@ -0,0 +1,492 @@
+flush query cache;
+flush query cache;
+reset query cache;
+flush status;
+drop table if exists t1,t2,t3,t11,t21, mysqltest.t1;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+select * from t1;
+a
+1
+2
+3
+select sql_no_cache * from t1;
+a
+1
+2
+3
+select length(now()) from t1;
+length(now())
+19
+19
+19
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 1
+drop table t1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (4),(5),(6);
+create table t3 (a int not null) type=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+select * from t3;
+a
+1
+2
+3
+4
+5
+6
+select * from t3;
+a
+1
+2
+3
+4
+5
+6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+insert into t2 values (7);
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1;
+a
+1
+2
+3
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+insert into t3 values (8);
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t3;
+a
+1
+2
+3
+8
+4
+5
+6
+7
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+update t2 set a=9 where a=7;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1;
+a
+1
+2
+3
+8
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+update t3 set a=10 where a=1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t3;
+a
+10
+2
+3
+8
+4
+5
+6
+9
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+delete from t2 where a=9;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1;
+a
+10
+2
+3
+8
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+delete from t3 where a=10;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1, t2, t3;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+select * from t2;
+a
+1
+2
+3
+insert into t1 values (4);
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 2
+flush query cache;
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+drop table t1, t2;
+create table t1 (a text not null);
+create table t11 (a text not null);
+create table t2 (a text not null);
+create table t21 (a text not null);
+create table t3 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+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 t2 select * from t1;
+insert into t1 select * from t2;
+insert into t3 select * from t1;
+insert into t3 select * from t2;
+insert into t3 select * from t1;
+select * from t11;
+select * from t21;
+show status like "Qcache_total_blocks";
+Variable_name Value
+Qcache_total_blocks 7
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+insert into t11 values("");
+select * from t3;
+show status like "Qcache_total_blocks";
+Variable_name Value
+Qcache_total_blocks 8
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+flush query cache;
+show status like "Qcache_total_blocks";
+Variable_name Value
+Qcache_total_blocks 7
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+drop table t1, t2, t3, t11, t21;
+set query_cache_type=demand;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select sql_cache * from t1;
+a
+1
+2
+3
+set query_cache_type=2;
+select sql_cache * from t1;
+a
+1
+2
+3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+set query_cache_type=on;
+reset query cache;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select sql_no_cache * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+create table t1 (a text not null);
+select CONNECTION_ID() from t1;
+CONNECTION_ID()
+select FOUND_ROWS();
+FOUND_ROWS()
+0
+select NOW() from t1;
+NOW()
+select CURDATE() from t1;
+CURDATE()
+select CURTIME() from t1;
+CURTIME()
+select DATABASE() from t1;
+DATABASE()
+select ENCRYPT("test") from t1;
+ENCRYPT("test")
+select LAST_INSERT_ID() from t1;
+last_insert_id()
+select RAND() from t1;
+RAND()
+select UNIX_TIMESTAMP() from t1;
+UNIX_TIMESTAMP()
+select USER() from t1;
+USER()
+select benchmark(1,1) from t1;
+benchmark(1,1)
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+create table t2 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+select a as a1, a as a2 from t1;
+select a as a2, a as a3 from t1;
+select a as a3, a as a4 from t1;
+select a as a1, a as a2 from t1;
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+reset query cache;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+select * from t1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1,t2;
+create database if not exists mysqltest;
+create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i));
+insert into mysqltest.t1 (a) values (1);
+select * from mysqltest.t1 where i is null;
+i a
+1 1
+select * from mysqltest.t1;
+i a
+1 1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+drop database mysqltest;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+create table t1 (a char(1) not null);
+insert into t1 values("á");
+select * from t1;
+a
+set CHARACTER SET cp1251_koi8;
+select * from t1;
+a
+set CHARACTER SET DEFAULT;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+drop table t1;
+create database if not exists mysqltest;
+create table mysqltest.t1 (i int not null);
+create table t1 (i int not null);
+insert into mysqltest.t1 (i) values (1);
+insert into t1 (i) values (2);
+select * from t1;
+i
+2
+use mysqltest;
+select * from t1;
+i
+1
+select * from t1;
+i
+1
+use test;
+select * from t1;
+i
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+drop database mysqltest;
+drop table t1;
+create table t1 (i int not null);
+insert into t1 (i) values (1),(2),(3),(4);
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+i
+1
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+4
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+select * from t1 where i=1;
+i
+1
+select FOUND_ROWS();
+FOUND_ROWS()
+1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+i
+1
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+4
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 7
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+select * from t1 where i=1;
+i
+1
+select FOUND_ROWS();
+FOUND_ROWS()
+1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 8
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+drop table t1;
+flush query cache;
+reset query cache;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+insert delayed into t1 values (4);
+select a from t1;
+a
+1
+2
+3
+4
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+drop table t1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
diff --git a/mysql-test/r/raid.result b/mysql-test/r/raid.result
index ffda2a6966d..41af50851e9 100644
--- a/mysql-test/r/raid.result
+++ b/mysql-test/r/raid.result
@@ -1,8 +1,196 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (
+id int unsigned not null auto_increment primary key,
+c char(255) not null
+) RAID_TYPE=STRIPED RAID_CHUNKS=2 RAID_CHUNKSIZE=123;
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+select count(*) from t1;
count(*)
450
+ALTER TABLE t1 ADD COLUMN x INT UNSIGNED NOT NULL;
+ALTER TABLE t1 ADD KEY c (c);
+ALTER TABLE t1 DROP KEY c;
+ALTER TABLE t1 DROP COLUMN x;
+ALTER TABLE t1 RENAME t2;
+select count(*) from t2;
count(*)
450
+DROP TABLE t2;
+/* variable rows */
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1 (
+id int unsigned not null auto_increment primary key,
+c varchar(255) not null
+) RAID_TYPE=STRIPED RAID_CHUNKS=5 RAID_CHUNKSIZE=121;
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+select count(*) from t1;
count(*)
450
+ALTER TABLE t1 ADD COLUMN x INT UNSIGNED NOT NULL;
+ALTER TABLE t1 ADD KEY c (c);
+ALTER TABLE t1 DROP KEY c;
+ALTER TABLE t1 DROP COLUMN x;
+ALTER TABLE t1 RENAME t2;
+ALTER TABLE t2 CHANGE COLUMN c c VARCHAR(251) NOT NULL;
+select count(*) from t2;
count(*)
450
+DROP TABLE t2;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 1a45c252b7c..a1d258455dc 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1,3 +1,12 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+event_date date DEFAULT '0000-00-00' NOT NULL,
+type int(11) DEFAULT '0' NOT NULL,
+event_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (event_date,type,event_id)
+);
+INSERT INTO t1 VALUES ('1999-07-10',100100,24),('1999-07-11',100100,25),('1999-07-13',100600,0),('1999-07-13',100600,4),('1999-07-13',100600,26),('1999-07-14',100600,10),('1999-07-15',100600,16),('1999-07-15',100800,45),('1999-07-15',101000,47),('1999-07-16',100800,46),('1999-07-20',100600,5),('1999-07-20',100600,27),('1999-07-21',100600,11),('1999-07-22',100600,17),('1999-07-23',100100,39),('1999-07-24',100100,39),('1999-07-24',100500,40),('1999-07-25',100100,39),('1999-07-27',100600,1),('1999-07-27',100600,6),('1999-07-27',100600,28),('1999-07-28',100600,12),('1999-07-29',100500,41),('1999-07-29',100600,18),('1999-07-30',100500,41),('1999-07-31',100500,41),('1999-08-01',100700,34),('1999-08-03',100600,7),('1999-08-03',100600,29),('1999-08-04',100600,13),('1999-08-05',100500,42),('1999-08-05',100600,19),('1999-08-06',100500,42),('1999-08-07',100500,42),('1999-08-08',100500,42),('1999-08-10',100600,2),('1999-08-10',100600,9),('1999-08-10',100600,30),('1999-08-11',100600,14),('1999-08-12',100600,20),('1999-08-17',100500,8),('1999-08-17',100600,31),('1999-08-18',100600,15),('1999-08-19',100600,22),('1999-08-24',100600,3),('1999-08-24',100600,32),('1999-08-27',100500,43),('1999-08-31',100600,33),('1999-09-17',100100,37),('1999-09-18',100100,37),('1999-09-19',100100,37),('2000-12-18',100700,38);
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
event_date type event_id
1999-07-10 100100 24
1999-07-11 100100 25
@@ -5,8 +14,10 @@ event_date type event_id
1999-07-13 100600 4
1999-07-13 100600 26
1999-07-14 100600 10
+explain select event_date,type,event_id from t1 WHERE type = 100601 and event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
Comment
Impossible WHERE
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND (type=100600 OR type=100100) or event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND type=100099;
event_date type event_id
1999-07-10 100100 24
1999-07-11 100100 25
@@ -15,6 +26,45 @@ event_date type event_id
1999-07-13 100600 26
1999-07-14 100600 10
1999-07-15 100600 16
+drop table t1;
+CREATE TABLE t1 (
+PAPER_ID smallint(6) DEFAULT '0' NOT NULL,
+YEAR smallint(6) DEFAULT '0' NOT NULL,
+ISSUE smallint(6) DEFAULT '0' NOT NULL,
+CLOSED tinyint(4) DEFAULT '0' NOT NULL,
+ISS_DATE date DEFAULT '0000-00-00' NOT NULL,
+PRIMARY KEY (PAPER_ID,YEAR,ISSUE)
+);
+INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12');
+INSERT INTO t1 VALUES (1,1999,111,0,'1999-03-23');
+INSERT INTO t1 VALUES (1,1999,222,0,'1999-03-23');
+INSERT INTO t1 VALUES (3,1999,33,0,'1999-07-12');
+INSERT INTO t1 VALUES (3,1999,32,0,'1999-07-12');
+INSERT INTO t1 VALUES (3,1999,31,0,'1999-07-12');
+INSERT INTO t1 VALUES (3,1999,30,0,'1999-07-12');
+INSERT INTO t1 VALUES (3,1999,29,0,'1999-07-12');
+INSERT INTO t1 VALUES (3,1999,28,0,'1999-07-12');
+INSERT INTO t1 VALUES (1,1999,40,1,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,41,1,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,42,1,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,46,1,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,47,1,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,48,1,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,49,1,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,50,0,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,51,0,'1999-05-01');
+INSERT INTO t1 VALUES (1,1999,200,0,'1999-06-28');
+INSERT INTO t1 VALUES (1,1999,52,0,'1999-06-28');
+INSERT INTO t1 VALUES (1,1999,53,0,'1999-06-28');
+INSERT INTO t1 VALUES (1,1999,54,0,'1999-06-28');
+INSERT INTO t1 VALUES (1,1999,55,0,'1999-06-28');
+INSERT INTO t1 VALUES (1,1999,56,0,'1999-07-01');
+INSERT INTO t1 VALUES (1,1999,57,0,'1999-07-01');
+INSERT INTO t1 VALUES (1,1999,58,0,'1999-07-01');
+INSERT INTO t1 VALUES (1,1999,59,0,'1999-07-01');
+INSERT INTO t1 VALUES (1,1999,60,0,'1999-07-01');
+INSERT INTO t1 VALUES (3,1999,35,0,'1999-07-12');
+select YEAR,ISSUE from t1 where PAPER_ID=3 and (YEAR>1999 or (YEAR=1999 and ISSUE>28)) order by YEAR,ISSUE;
YEAR ISSUE
1999 29
1999 30
@@ -23,10 +73,23 @@ YEAR ISSUE
1999 33
1999 34
1999 35
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+);
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1;
id parent_id level
3 1 1
4 1 1
@@ -34,6 +97,7 @@ id parent_id level
6 1 1
7 1 1
5 1 1
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1 order by id;
id parent_id level
2 1 1
3 1 1
@@ -41,27 +105,105 @@ id parent_id level
5 1 1
6 1 1
7 1 1
+drop table t1;
+create table t1(
+Satellite varchar(25) not null,
+SensorMode varchar(25) not null,
+FullImageCornersUpperLeftLongitude double not null,
+FullImageCornersUpperRightLongitude double not null,
+FullImageCornersUpperRightLatitude double not null,
+FullImageCornersLowerRightLatitude double not null,
+index two (Satellite, SensorMode, FullImageCornersUpperLeftLongitude, FullImageCornersUpperRightLongitude, FullImageCornersUpperRightLatitude, FullImageCornersLowerRightLatitude));
+insert into t1 values("OV-3","PAN1",91,-92,40,50);
+insert into t1 values("OV-4","PAN1",91,-92,40,50);
+select * from t1 where t1.Satellite = "OV-3" and t1.SensorMode = "PAN1" and t1.FullImageCornersUpperLeftLongitude > -90.000000 and t1.FullImageCornersUpperRightLongitude < -82.000000;
Satellite SensorMode FullImageCornersUpperLeftLongitude FullImageCornersUpperRightLongitude FullImageCornersUpperRightLatitude FullImageCornersLowerRightLatitude
OV-3 PAN1 91 -92 40 50
+drop table t1;
+create table t1 ( aString char(100) not null default "", key aString (aString(10)) );
+insert t1 (aString) values ( "believe in myself" ), ( "believe" ), ("baaa" ), ( "believe in love");
+select * from t1 where aString < "believe in myself" order by aString;
aString
baaa
believe
believe in love
+select * from t1 where aString > "believe in love" order by aString;
aString
believe in myself
+alter table t1 drop key aString;
+select * from t1 where aString < "believe in myself" order by aString;
aString
baaa
believe
believe in love
+select * from t1 where aString > "believe in love" order by aString;
aString
believe in myself
+drop table t1;
+CREATE TABLE t1 (
+t1ID int(10) unsigned NOT NULL auto_increment,
+art char(1) binary NOT NULL default '',
+KNR char(5) NOT NULL default '',
+RECHNR char(6) NOT NULL default '',
+POSNR char(2) NOT NULL default '',
+ARTNR char(10) NOT NULL default '',
+TEX char(70) NOT NULL default '',
+PRIMARY KEY (t1ID),
+KEY IdxArt (art),
+KEY IdxKnr (KNR),
+KEY IdxArtnr (ARTNR)
+) TYPE=MyISAM;
+INSERT INTO t1 (art) VALUES ('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j');
+select count(*) from t1 where upper(art) = 'J';
count(*)
602
+select count(*) from t1 where art = 'J' or art = 'j';
count(*)
602
+select count(*) from t1 where art = 'j' or art = 'J';
count(*)
602
+select count(*) from t1 where art = 'j';
count(*)
389
+select count(*) from t1 where art = 'J';
count(*)
213
+drop table t1;
diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result
index 57ef20e41b1..b2bb659502a 100644
--- a/mysql-test/r/rename.result
+++ b/mysql-test/r/rename.result
@@ -1,14 +1,39 @@
+drop table if exists t0,t1,t2,t3,t4;
+create table t0 SELECT 1,"table 1";
+create table t2 SELECT 2,"table 2";
+create table t3 SELECT 3,"table 3";
+rename table t0 to t1;
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
+select * from t1;
3 table 3
3 table 3
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
+select * from t1;
1 table 1
1 table 1
+rename table t1 to t2;
+Got one of the listed errors
+rename table t1 to t1;
+Got one of the listed errors
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
+Got one of the listed errors
+show tables like "t_";
Tables_in_test (t_)
t1
t2
t3
+rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
+Got one of the listed errors
+rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
+Got one of the listed errors
+select * from t1;
1 table 1
1 table 1
+select * from t2;
2 table 2
2 table 2
+select * from t3;
3 table 3
3 table 3
+drop table if exists t1,t2,t3,t4;
diff --git a/mysql-test/r/replace.result b/mysql-test/r/replace.result
index 25a6a17da35..0aa80e18ccc 100644
--- a/mysql-test/r/replace.result
+++ b/mysql-test/r/replace.result
@@ -1,3 +1,26 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) type=ISAM;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+alter table t1 type=myisam;
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+alter table t1 type=heap;
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+drop table t1;
+create table t1 (a tinyint not null auto_increment primary key, b char(20));
+insert into t1 values (126,"first"),(0,"last");
+insert into t1 values (0,"error");
+Duplicate entry '127' for key 1
+replace into t1 values (0,"error");
+Duplicate entry '127' for key 1
+replace into t1 values (126,"first updated");
+select * from t1;
a b
126 first updated
127 last
+drop table t1;
diff --git a/mysql-test/r/rollback.result b/mysql-test/r/rollback.result
index ac3743e1dc7..a5eb6f8729f 100644
--- a/mysql-test/r/rollback.result
+++ b/mysql-test/r/rollback.result
@@ -1,3 +1,12 @@
+drop table if exists t1;
+create table t1 (n int not null primary key) type=myisam;
+begin work;
+insert into t1 values (4);
+insert into t1 values (5);
+rollback;
+Warning: Some non-transactional changed tables couldn't be rolled back
+select * from t1;
n
4
5
+drop table t1;
diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl000001.result
index ebccb1e1e6b..2c36df65ca9 100644
--- a/mysql-test/r/rpl000001.result
+++ b/mysql-test/r/rpl000001.result
@@ -1,17 +1,95 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists t1,t3;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1;
+load data local infile 'MYSQL_TEST_DIR/std_data/words.dat' into table t1;
+select * from t1;
+word
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+set password for root@"localhost" = password('foo');
+set password for root@"localhost" = password('');
+create table t3(n int);
+insert into t3 values(1),(2);
+use test;
+select * from t3;
n
1
2
+select sum(length(word)) from t1;
sum(length(word))
-71
+141
+drop table t1,t3;
+reset master;
+slave stop;
+reset slave;
+drop table if exists t1,t2;
+create table t1(n int);
+select get_lock("hold_slave",10);
+get_lock("hold_slave",10)
+1
+slave start;
+select release_lock("hold_slave");
+release_lock("hold_slave")
+1
+unlock tables;
+create table t2(id int);
+insert into t2 values(connection_id());
+create temporary table t1_temp(n int);
+insert into t1_temp select get_lock('crash_lock%20C', 1) from t2;
+ update t1 set n = n + get_lock('crash_lock%20C', 2);
+select (@id := id) - id from t2;
(@id := id) - id
0
+kill @id;
+drop table t2;
+Server shutdown in progress
+set global sql_slave_skip_counter=1;
+slave start;
+select count(*) from t1;
count(*)
-10
+5000
+drop table t1;
+create table t1 (n int);
+insert into t1 values(3456);
+use mysql;
+insert into user (Host, User, Password)
+VALUES ("10.10.10.%", "blafasel2", password("blafasel2"));
+select select_priv,user from mysql.user where user = 'blafasel2';
select_priv user
N blafasel2
+update user set Select_priv = "Y" where User="blafasel2";
+select select_priv,user from mysql.user where user = 'blafasel2';
select_priv user
Y blafasel2
+use test;
+select n from t1;
n
3456
+select select_priv,user from mysql.user where user = 'blafasel2';
select_priv user
Y blafasel2
+drop table t1;
diff --git a/mysql-test/r/rpl000002.result b/mysql-test/r/rpl000002.result
index a68ef517708..88228321897 100644
--- a/mysql-test/r/rpl000002.result
+++ b/mysql-test/r/rpl000002.result
@@ -1,8 +1,33 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists t1;
+create table t1 (n int auto_increment primary key);
+set insert_id = 2000;
+insert into t1 values (NULL),(NULL),(NULL);
+use test;
+select * from t1;
n
2000
2001
2002
+show slave hosts;
+Server_id Host Port Rpl_recovery_rank Master_id
+2 127.0.0.1 $SLAVE_MYPORT 2 1
+drop table t1;
+slave stop;
+drop table if exists t2;
+create table t2(id int auto_increment primary key, created datetime);
+set timestamp=12345;
+insert into t2 set created=now();
+select * from t2;
id created
1 1970-01-01 06:25:45
+slave start;
+select * from t2;
id created
1 1970-01-01 06:25:45
+drop table t2;
diff --git a/mysql-test/r/rpl000003.result b/mysql-test/r/rpl000003.result
index f85b057eefa..eb64d1855b1 100644
--- a/mysql-test/r/rpl000003.result
+++ b/mysql-test/r/rpl000003.result
@@ -1,4 +1,16 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1(n int primary key);
+insert into t1 values (1),(2),(2);
+Duplicate entry '2' for key 1
+insert into t1 values (3);
+select * from t1;
n
1
2
3
+drop table t1;
diff --git a/mysql-test/r/rpl000004.result b/mysql-test/r/rpl000004.result
index a1c135a142e..e5dee880f73 100644
--- a/mysql-test/r/rpl000004.result
+++ b/mysql-test/r/rpl000004.result
@@ -1,6 +1,34 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+set SQL_LOG_BIN=0;
+drop table if exists t1;
+create table t1 (word char(20) not null, index(word));
+load data infile '../../std_data/words.dat' into table t1;
+drop table if exists t2;
+create table t2 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t2;
+create table t3 (word char(20) not null primary key);
+use test;
+drop table if exists t1;
+load table t1 from master;
+drop table if exists t2;
+load table t2 from master;
+drop table if exists t3;
+load table t3 from master;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+select count(*) from t2;
count(*)
10
+select count(*) from t3;
count(*)
0
+set SQL_LOG_BIN=1;
+drop table if exists t1,t2,t3;
+create table t1(n int);
+drop table t1;
diff --git a/mysql-test/r/rpl000005.result b/mysql-test/r/rpl000005.result
index 4f1541c75ca..0c91f984db1 100644
--- a/mysql-test/r/rpl000005.result
+++ b/mysql-test/r/rpl000005.result
@@ -1,8 +1,22 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+CREATE TABLE t1 (name varchar(64), age smallint(3));
+INSERT INTO t1 SET name='Andy', age=31;
+INSERT t1 SET name='Jacob', age=2;
+INSERT into t1 SET name='Caleb', age=1;
+ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
+select * from t1;
name age id
Andy 31 00000001
Jacob 2 00000002
Caleb 1 00000003
+select * from t1;
name age id
Andy 31 00000001
Jacob 2 00000002
Caleb 1 00000003
+drop table t1;
diff --git a/mysql-test/r/rpl000006.result b/mysql-test/r/rpl000006.result
index 56cd7166510..f4e965236af 100644
--- a/mysql-test/r/rpl000006.result
+++ b/mysql-test/r/rpl000006.result
@@ -1,6 +1,30 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+set SQL_LOG_BIN=0,timestamp=200006;
+drop table if exists t1;
+create table t1(t timestamp not null,a char(1));
+insert into t1 ( a) values ('F');
+select unix_timestamp(t) from t1;
unix_timestamp(t)
200006
+drop table if exists t1;
+load table t1 from master;
+select unix_timestamp(t) from t1;
unix_timestamp(t)
200006
+set SQL_LOG_BIN=1,timestamp=default;
+drop table t1;
+set SQL_LOG_BIN=0;
+CREATE TABLE t1 (
+a int not null
+) TYPE=MyISAM MAX_ROWS=4000 CHECKSUM=1;
+INSERT INTO t1 VALUES (1);
+load table t1 from master;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+drop table t1;
diff --git a/mysql-test/r/rpl000007.result b/mysql-test/r/rpl000007.result
index d5b4cdf3bee..7b2b9939228 100644
--- a/mysql-test/r/rpl000007.result
+++ b/mysql-test/r/rpl000007.result
@@ -1,2 +1,21 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists foo;
+create table foo (n int);
+insert into foo values(4);
+use test;
+drop table if exists foo;
+create table foo (s char(20));
+load data infile '../../std_data/words.dat' into table foo;
+insert into foo values('five');
+drop table if exists bar;
+create table bar (m int);
+insert into bar values(15);
+select foo.n,bar.m from foo,bar;
n m
4 15
+drop table if exists bar,foo;
diff --git a/mysql-test/r/rpl000008.result b/mysql-test/r/rpl000008.result
index 870e8a5510d..5ca156fecf0 100644
--- a/mysql-test/r/rpl000008.result
+++ b/mysql-test/r/rpl000008.result
@@ -1,2 +1,24 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists foo;
+create table foo (n int);
+insert into foo values(4);
+use test;
+drop table if exists foo;
+create table foo (n int);
+insert into foo values(5);
+drop table if exists bar;
+create table bar (m int);
+insert into bar values(15);
+drop table if exists choo;
+create table choo (k int);
+insert into choo values(55);
+select foo.n,bar.m,choo.k from foo,bar,choo;
n m k
4 15 55
+drop table if exists foo,bar,choo;
+drop table if exists foo,bar,choo;
diff --git a/mysql-test/r/rpl000009.result b/mysql-test/r/rpl000009.result
index d5b4cdf3bee..5246dadc06b 100644
--- a/mysql-test/r/rpl000009.result
+++ b/mysql-test/r/rpl000009.result
@@ -1,2 +1,82 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop database if exists foo;
+create database foo;
+drop database if exists bar;
+create database bar;
+drop table if exists foo.foo;
+create table foo.foo (n int);
+insert into foo.foo values(4);
+drop table if exists foo.foo;
+create table foo.foo (n int);
+insert into foo.foo values(5);
+drop table if exists bar.bar;
+create table bar.bar (m int);
+insert into bar.bar values(15);
+select foo.foo.n,bar.bar.m from foo.foo,bar.bar;
n m
4 15
+drop database if exists bar;
+drop database if exists foo;
+drop database if exists bar;
+drop database if exists foo;
+set sql_log_bin = 0;
+create database foo;
+create database bar;
+show databases;
+Database
+bar
+foo
+mysql
+test
+create table foo.t1(n int, s char(20));
+create table foo.t2(n int, s text);
+insert into foo.t1 values (1, 'one'), (2, 'two'), (3, 'three');
+insert into foo.t2 values (11, 'eleven'), (12, 'twelve'), (13, 'thirteen');
+create table bar.t1(n int, s char(20));
+create table bar.t2(n int, s text);
+insert into bar.t1 values (1, 'one bar'), (2, 'two bar'), (3, 'three bar');
+insert into bar.t2 values (11, 'eleven bar'), (12, 'twelve bar'),
+(13, 'thirteen bar');
+set sql_log_bin = 1;
+show databases;
+Database
+mysql
+test
+load data from master;
+show databases;
+Database
+bar
+foo
+mysql
+test
+use foo;
+show tables;
+Tables_in_foo
+use bar;
+show tables;
+Tables_in_bar
+t1
+t2
+select * from bar.t1;
+n s
+1 one bar
+2 two bar
+3 three bar
+select * from bar.t2;
+n s
+11 eleven bar
+12 twelve bar
+13 thirteen bar
+insert into bar.t1 values (4, 'four bar');
+select * from bar.t1;
+n s
+1 one bar
+2 two bar
+3 three bar
+4 four bar
+drop database bar;
+drop database foo;
diff --git a/mysql-test/r/rpl000010.result b/mysql-test/r/rpl000010.result
index c52b83d729a..95792a72a6d 100644
--- a/mysql-test/r/rpl000010.result
+++ b/mysql-test/r/rpl000010.result
@@ -1,3 +1,15 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+drop table if exists t1;
+create table t1 (n int not null auto_increment primary key);
+insert into t1 values(NULL);
+insert into t1 values(2);
+select n from t1;
n
1
2
+drop table t1;
diff --git a/mysql-test/r/rpl000011.result b/mysql-test/r/rpl000011.result
index c52b83d729a..1a46f479677 100644
--- a/mysql-test/r/rpl000011.result
+++ b/mysql-test/r/rpl000011.result
@@ -1,3 +1,17 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values(1);
+slave stop;
+slave start;
+insert into t1 values(2);
+select * from t1;
n
1
2
+drop table t1;
diff --git a/mysql-test/r/rpl000012.result b/mysql-test/r/rpl000012.result
index 9ce7037101e..c7f3ab8f578 100644
--- a/mysql-test/r/rpl000012.result
+++ b/mysql-test/r/rpl000012.result
@@ -1,3 +1,26 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1,t2,t3;
+create table t2 (n int);
+create temporary table t1 (n int);
+insert into t1 values(1),(2),(3);
+insert into t2 select * from t1;
+drop table if exists test.t3;
+create temporary table test.t3 (n int not null);
+alter table test.t3 add primary key(n);
+flush logs;
+insert into t3 values (100);
+insert into t2 select * from t3;
+drop table if exists test.t3;
+insert into t2 values (101);
+create temporary table t1 (n int);
+insert into t1 values (4),(5);
+insert into t2 select * from t1;
+insert into t2 values(6);
+select * from t2;
n
1
2
@@ -7,5 +30,7 @@ n
4
5
6
+show status like 'Slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 0
+drop table if exists t1,t2;
diff --git a/mysql-test/r/rpl000013.result b/mysql-test/r/rpl000013.result
index ec2bd0684f1..5e4b4159e3a 100644
--- a/mysql-test/r/rpl000013.result
+++ b/mysql-test/r/rpl000013.result
@@ -1,3 +1,18 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t2;
+create table t2(n int);
+create temporary table t1 (n int);
+insert into t1 values(1),(2),(3);
+insert into t2 select * from t1;
+create temporary table t1 (n int);
+insert into t1 values (4),(5);
+insert into t2 select * from t1 as t10;
+insert into t2 values(6);
+select * from t2;
n
1
2
@@ -5,5 +20,7 @@ n
4
5
6
+show status like 'Slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 0
+drop table if exists t1,t2;
diff --git a/mysql-test/r/rpl000014.result b/mysql-test/r/rpl000014.result
index a47c3c91c1d..c9926c92a4f 100644
--- a/mysql-test/r/rpl000014.result
+++ b/mysql-test/r/rpl000014.result
@@ -1,16 +1,39 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+show master status;
File Position Binlog_do_db Binlog_ignore_db
-master-bin.001 73
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 73 Yes 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 73 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 73 Yes 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 173 Yes 0 0
+master-bin.001 79
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 128
+change master to master_log_pos=73;
+slave stop;
+change master to master_log_pos=73;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 No No 0 0 73 4
+slave start;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 Yes Yes 0 0 73 4
+change master to master_log_pos=173;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 173 slave-relay-bin.001 4 master-bin.001 Yes Yes 0 0 173 4
+show master status;
File Position Binlog_do_db Binlog_ignore_db
-master-bin.001 73
+master-bin.001 79
+create table if not exists foo(n int);
+drop table if exists foo;
+create table foo (n int);
+insert into foo values (1),(2),(3);
+change master to master_log_pos=79;
+select * from foo;
n
1
2
3
+drop table foo;
diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl000015.result
index 58487af27f8..a35004298e0 100644
--- a/mysql-test/r/rpl000015.result
+++ b/mysql-test/r/rpl000015.result
@@ -1,14 +1,30 @@
+reset master;
+show master status;
File Position Binlog_do_db Binlog_ignore_db
-master-bin.001 73
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
- 0 0 0 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 test 9998 60 4 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 4 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.001 73 Yes 0 0
+master-bin.001 79
+reset slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+ 0 0 0 0 No No 0 0 0 0
+change master to master_host='127.0.0.1';
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.001 4 No No 0 0 0 4
+change master to master_host='127.0.0.1',master_user='root',
+master_password='',master_port=MASTER_PORT;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.001 4 No No 0 0 0 4
+slave start;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 7 master-bin.001 79 slave-relay-bin.001 120 master-bin.001 Yes Yes 0 0 79 120
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values (10),(45),(90);
+select * from t1;
n
10
45
90
+drop table t1;
diff --git a/mysql-test/r/rpl000016.result b/mysql-test/r/rpl000016.result
index 1390291f1e8..ccd584bfcdc 100644
--- a/mysql-test/r/rpl000016.result
+++ b/mysql-test/r/rpl000016.result
@@ -1,30 +1,74 @@
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.001 216 Yes 0 0
+slave start;
+Could not initialize master info structure, check permisions on master.info
+slave start;
+Could not initialize master info structure, check permisions on master.info
+change master to master_host='127.0.0.1',master_port=MASTER_PORT,
+master_user='root';
+Could not initialize master info
+reset slave;
+change master to master_host='127.0.0.1',master_port=MASTER_PORT,
+master_user='root';
+reset master;
+slave start;
+drop table if exists t1;
+create table t1 (s text);
+insert into t1 values('Could not break slave'),('Tried hard');
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 60 master-bin.001 234 slave-relay-bin.001 275 master-bin.001 Yes Yes 0 0 234 275
+select * from t1;
s
Could not break slave
Tried hard
+flush logs;
+drop table if exists t2;
+create table t2(m int not null auto_increment primary key);
+insert into t2 values (34),(67),(123);
+flush logs;
+show master logs;
Log_name
master-bin.001
master-bin.002
master-bin.003
+insert into t2 values(1234);
+set insert_id=1234;
+insert into t2 values(NULL);
+set global sql_slave_skip_counter=1;
+slave start;
+purge master logs to 'master-bin.003';
+show master logs;
Log_name
master-bin.003
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.003 206 Yes 0 0
+insert into t2 values (65);
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 60 master-bin.003 155 slave-relay-bin.001 755 master-bin.003 Yes Yes 0 0 155 755
+select * from t2;
m
34
65
67
123
1234
+drop table if exists t3;
+create table t3 (n int);
+show master logs;
Log_name
master-bin.003
master-bin.004
master-bin.005
master-bin.006
+show master status;
File Position Binlog_do_db Binlog_ignore_db
-master-bin.006 131
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.006 131 Yes 0 0
+master-bin.006 445
+slave stop;
+slave start;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 60 master-bin.006 445 slave-relay-bin.004 1229 master-bin.006 Yes Yes 0 0 445 1229
+lock tables t3 read;
+select count(*) from t3 where n >= 4;
count(*)
100
+unlock tables;
+drop table if exists t1,t2,t3;
diff --git a/mysql-test/r/rpl000017.result b/mysql-test/r/rpl000017.result
index e4f324047f8..bac0573165d 100644
--- a/mysql-test/r/rpl000017.result
+++ b/mysql-test/r/rpl000017.result
@@ -1,2 +1,11 @@
+reset master;
+grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
+slave start;
+drop table if exists t1;
+create table t1(n int);
+insert into t1 values(24);
+select * from t1;
n
24
+drop table t1;
diff --git a/mysql-test/r/rpl000018.result b/mysql-test/r/rpl000018.result
index 7c89c2ef2b2..ba51406bba0 100644
--- a/mysql-test/r/rpl000018.result
+++ b/mysql-test/r/rpl000018.result
@@ -1,5 +1,13 @@
+reset slave;
+slave start;
+show master logs;
Log_name
master-bin.001
master-bin.002
+drop table if exists t1;
+create table t1(n int);
+insert into t1 values (3351);
+select * from t1;
n
3351
+drop table t1;
diff --git a/mysql-test/r/rpl_alter.result b/mysql-test/r/rpl_alter.result
index 7883e725e3a..2e42177c140 100644
--- a/mysql-test/r/rpl_alter.result
+++ b/mysql-test/r/rpl_alter.result
@@ -1,4 +1,21 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop database if exists d1;
+create database d1;
+create table d1.t1 ( n int);
+alter table d1.t1 add m int;
+insert into d1.t1 values (1,2);
+create table d1.t2 (n int);
+insert into d1.t2 values (45);
+rename table d1.t2 to d1.t3, d1.t1 to d1.t2;
+select * from d1.t2;
n m
1 2
+select * from d1.t3;
n
45
+drop database d1;
diff --git a/mysql-test/r/rpl_compat.result b/mysql-test/r/rpl_compat.result
new file mode 100644
index 00000000000..5e497791771
--- /dev/null
+++ b/mysql-test/r/rpl_compat.result
@@ -0,0 +1,77 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists t1,t3;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1;
+select * from t1;
+word
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+set password for root@"localhost" = password('foo');
+set password for root@"localhost" = password('');
+create table t3(n int);
+insert into t3 values(1),(2);
+use test;
+select * from t3;
+n
+1
+2
+select sum(length(word)) from t1;
+sum(length(word))
+71
+drop table t1,t3;
+reset master;
+slave stop;
+reset slave;
+create table t1(n int);
+insert into t1 values (1),(2),(3);
+create table t2(id int);
+insert into t2 values(connection_id());
+create temporary table t1_temp(n int);
+insert into t1_temp select get_lock('crash_lock%20C', 1) from t2;
+ update t1 set n = n + get_lock('crash_lock%20C', 2);
+select (@id := id) - id from t2;
+(@id := id) - id
+0
+kill @id;
+drop table t2;
+Server shutdown in progress
+slave start;
+set sql_slave_skip_counter=1;
+slave start;
+select count(*) from t1;
+count(*)
+3
+drop table t1;
+create table t1 (n int);
+insert into t1 values(3456);
+use mysql;
+insert into user (Host, User, Password)
+VALUES ("10.10.10.%", "blafasel2", password("blafasel2"));
+select select_priv,user from mysql.user where user = 'blafasel2';
+select_priv user
+N blafasel2
+update user set Select_priv = "Y" where User="blafasel2";
+select select_priv,user from mysql.user where user = 'blafasel2';
+select_priv user
+Y blafasel2
+use test;
+select n from t1;
+n
+3456
+select select_priv,user from mysql.user where user = 'blafasel2';
+select_priv user
+Y blafasel2
+drop table t1;
diff --git a/mysql-test/r/rpl_empty_master_crash.result b/mysql-test/r/rpl_empty_master_crash.result
index e9111fdb401..6ae5d15031b 100644
--- a/mysql-test/r/rpl_empty_master_crash.result
+++ b/mysql-test/r/rpl_empty_master_crash.result
@@ -1,2 +1,12 @@
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
- 0 0 0 No 0 0
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists t1;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+ 0 0 0 0 No No 0 0 0 0
+load table t1 from master;
+Error in fetch_master_table
diff --git a/mysql-test/r/rpl_failsafe.result b/mysql-test/r/rpl_failsafe.result
new file mode 100644
index 00000000000..14b749fada9
--- /dev/null
+++ b/mysql-test/r/rpl_failsafe.result
@@ -0,0 +1,33 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 1
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status AUTH_MASTER
+create table t1(n int);
+drop table t1;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 2
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status ACTIVE_SLAVE
+slave start;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 3
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status ACTIVE_SLAVE
+slave start;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 4
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status ACTIVE_SLAVE
diff --git a/mysql-test/r/rpl_get_lock.result b/mysql-test/r/rpl_get_lock.result
index 84749c1a9b1..cfbf4351f32 100644
--- a/mysql-test/r/rpl_get_lock.result
+++ b/mysql-test/r/rpl_get_lock.result
@@ -1,8 +1,29 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1(n int);
+insert into t1 values(get_lock("lock",2));
+select get_lock("lock",2);
get_lock("lock",2)
1
+select release_lock("lock");
release_lock("lock")
1
+select get_lock("lock",3);
get_lock("lock",3)
1
+select * from t1;
n
1
+select is_free_lock("lock");
+is_free_lock("lock")
+0
+select is_free_lock("lock2");
+is_free_lock("lock2")
+1
+select is_free_lock(NULL);
+is_free_lock(NULL)
+NULL
+drop table t1;
diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result
new file mode 100644
index 00000000000..f5885085dee
--- /dev/null
+++ b/mysql-test/r/rpl_log.result
@@ -0,0 +1,98 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+slave stop;
+reset master;
+reset slave;
+reset master;
+drop table if exists t1;
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL);
+drop table t1;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1;
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
+master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
+master-bin.001 172 Intvar 1 172 INSERT_ID=1
+master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
+master-bin.001 263 Query 1 263 use test; drop table t1
+master-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null)
+master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
+master-bin.001 556 Exec_load 1 556 ;file_id=1
+master-bin.001 579 Query 1 579 use test; drop table t1
+show binlog events from 79 limit 1;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
+show binlog events from 79 limit 2;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
+master-bin.001 172 Intvar 1 172 INSERT_ID=1
+show binlog events from 79 limit 2,1;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
+flush logs;
+create table t1 (n int);
+insert into t1 values (1);
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
+master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
+master-bin.001 172 Intvar 1 172 INSERT_ID=1
+master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
+master-bin.001 263 Query 1 263 use test; drop table t1
+master-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null)
+master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
+master-bin.001 556 Exec_load 1 556 ;file_id=1
+master-bin.001 579 Query 1 579 use test; drop table t1
+master-bin.001 627 Rotate 1 627 master-bin.002;pos=4
+master-bin.001 668 Stop 1 668
+show binlog events in 'master-bin.002';
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.002 4 Query 1 4 use test; create table t1 (n int)
+master-bin.002 62 Query 1 62 use test; insert into t1 values (1)
+master-bin.002 122 Query 1 122 use test; drop table t1
+show master logs;
+Log_name
+master-bin.001
+master-bin.002
+slave start;
+show master logs;
+Log_name
+slave-bin.001
+slave-bin.002
+show binlog events in 'slave-bin.001' from 4;
+show binlog events in 'slave-bin.002' from 4;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+slave-bin.002 4 Slave 2 627 host=127.0.0.1,port=MASTER_PORT,log=master-bin.002,pos=4
+slave-bin.002 57 Query 1 4 use test; create table t1 (n int)
+slave-bin.002 115 Query 1 62 use test; insert into t1 values (1)
+slave-bin.002 175 Query 1 122 use test; drop table t1
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.002 170 slave-relay-bin.002 916 master-bin.002 Yes Yes 0 0 170 924
+show new master for slave with master_log_file='master-bin.001' and
+master_log_pos=4 and master_server_id=1;
+Log_name Log_pos
+slave-bin.001 132
+show new master for slave with master_log_file='master-bin.001' and
+master_log_pos=79 and master_server_id=1;
+Log_name Log_pos
+slave-bin.001 225
+show new master for slave with master_log_file='master-bin.001' and
+master_log_pos=311 and master_server_id=1;
+Log_name Log_pos
+slave-bin.001 439
+show new master for slave with master_log_file='master-bin.002' and
+master_log_pos=4 and master_server_id=1;
+Log_name Log_pos
+slave-bin.002 57
+show new master for slave with master_log_file='master-bin.002' and
+master_log_pos=122 and master_server_id=1;
+Log_name Log_pos
+slave-bin.002 223
diff --git a/mysql-test/r/rpl_magic.result b/mysql-test/r/rpl_magic.result
new file mode 100644
index 00000000000..b30d40d04eb
--- /dev/null
+++ b/mysql-test/r/rpl_magic.result
@@ -0,0 +1,36 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1 ( n int);
+insert into t1 values (1),(2),(3),(4);
+insert into t1 values(5);
+select * from t1;
+n
+1
+2
+3
+4
+5
+select * from t1;
+n
+1
+2
+3
+4
+select * from t1;
+n
+1
+2
+3
+4
+select * from t1;
+n
+1
+2
+3
+4
+5
+drop table t1;
diff --git a/mysql-test/r/rpl_mystery22.result b/mysql-test/r/rpl_mystery22.result
index f85b057eefa..e798d774380 100644
--- a/mysql-test/r/rpl_mystery22.result
+++ b/mysql-test/r/rpl_mystery22.result
@@ -1,4 +1,23 @@
+drop table if exists t1;
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1(n int auto_increment primary key);
+insert into t1 values (2);
+insert into t1 values(NULL);
+insert into t1 values(NULL);
+delete from t1 where n = 2;
+slave start;
+slave stop;
+create table t2(n int);
+drop table t2;
+insert into t1 values(NULL);
+slave start;
+select * from t1;
n
1
2
3
+drop table t1;
diff --git a/mysql-test/r/rpl_skip_error.result b/mysql-test/r/rpl_skip_error.result
index f85b057eefa..9fe92292178 100644
--- a/mysql-test/r/rpl_skip_error.result
+++ b/mysql-test/r/rpl_skip_error.result
@@ -1,3 +1,14 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1 (n int not null primary key);
+insert into t1 values (1);
+insert into t1 values (1);
+insert into t1 values (2),(3);
+select * from t1;
n
1
2
diff --git a/mysql-test/r/rpl_sporadic_master.result b/mysql-test/r/rpl_sporadic_master.result
index ed616c26b67..ca74904889b 100644
--- a/mysql-test/r/rpl_sporadic_master.result
+++ b/mysql-test/r/rpl_sporadic_master.result
@@ -1,3 +1,21 @@
+slave stop;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1,t2;
+create table t2(n int);
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL),(NULL);
+truncate table t1;
+insert into t1 values (4),(NULL);
+slave stop;
+slave start;
+insert into t1 values (NULL),(NULL);
+flush logs;
+truncate table t1;
+insert into t1 values (10),(NULL),(NULL),(NULL),(NULL),(NULL);
+select * from t1;
n
10
11
@@ -5,3 +23,4 @@ n
13
14
15
+drop table t1,t2;
diff --git a/mysql-test/r/sel000001.result b/mysql-test/r/sel000001.result
index bee97cc7b53..28f6d3d1d5a 100644
--- a/mysql-test/r/sel000001.result
+++ b/mysql-test/r/sel000001.result
@@ -1,2 +1,7 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (s CHAR(20) PRIMARY KEY, id INT);
+INSERT INTO t1 VALUES ('cat', 1), ('mouse', 3), ('dog', 2), ('snake', 77);
+SELECT s, id FROM t1 WHERE s = 'mouse';
s id
mouse 3
+drop table t1;
diff --git a/mysql-test/r/sel000002.result b/mysql-test/r/sel000002.result
index f85b057eefa..b824de8de4a 100644
--- a/mysql-test/r/sel000002.result
+++ b/mysql-test/r/sel000002.result
@@ -1,4 +1,9 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (n INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+SELECT * FROM t1;
n
1
2
3
+drop table t1;
diff --git a/mysql-test/r/sel000003.result b/mysql-test/r/sel000003.result
index 77312414818..c3853832f87 100644
--- a/mysql-test/r/sel000003.result
+++ b/mysql-test/r/sel000003.result
@@ -1,3 +1,8 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (name CHAR(20) NOT NULL PRIMARY KEY, score SMALLINT NOT NULL, KEY(score));
+INSERT INTO t1 VALUES ('Sasha', 20), ('Matt', 20), ('Monty', 10), ('David', 10), ('Tim', 10), ('Jeremy', 10);
+SELECT COUNT(*) as n, score FROM t1 GROUP BY score;
n score
4 10
2 20
+drop table t1;
diff --git a/mysql-test/r/sel000031.result b/mysql-test/r/sel000031.result
index c1caa04a00a..d3f01ab687f 100644
--- a/mysql-test/r/sel000031.result
+++ b/mysql-test/r/sel000031.result
@@ -1,4 +1,12 @@
+drop table if exists t1,t2;
+create table t1 (id int(10) not null unique);
+create table t2 (id int(10) not null primary key,
+val int(10) not null);
+insert into t1 values (1),(2),(4);
+insert into t2 values (1,1),(2,1),(3,1),(4,2);
+select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id;
id elt(two.val,'one','two')
1 one
2 one
4 two
+drop table t1,t2;
diff --git a/mysql-test/r/sel000032.result b/mysql-test/r/sel000032.result
index c1caa04a00a..4cca245d75b 100644
--- a/mysql-test/r/sel000032.result
+++ b/mysql-test/r/sel000032.result
@@ -1,4 +1,12 @@
+drop table if exists t1,t2;
+create table t1 (id int(10) not null unique);
+create table t2 (id int(10) not null primary key,
+val int(10) not null);
+insert into t1 values (1),(2),(4);
+insert into t2 values (1,1),(2,1),(3,1),(4,2);
+select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id;
id elt(two.val,'one','two')
1 one
2 one
4 two
+drop table t1,t2;
diff --git a/mysql-test/r/sel000033.result b/mysql-test/r/sel000033.result
index 689c94082e7..1bfafaf5b27 100644
--- a/mysql-test/r/sel000033.result
+++ b/mysql-test/r/sel000033.result
@@ -1,8 +1,14 @@
+drop table if exists t1;
+create table t1 (id int(10) primary key);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+select id from t1 where id in (2,5,9) ;
id
2
5
9
+select id from t1 where id=2 or id=5 or id=9 ;
id
2
5
9
+drop table t1;
diff --git a/mysql-test/r/sel000100.result b/mysql-test/r/sel000100.result
index e7d8cf0e7ac..f9234815a2b 100644
--- a/mysql-test/r/sel000100.result
+++ b/mysql-test/r/sel000100.result
@@ -1,2 +1,28 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(75) DEFAULT '' NOT NULL,
+LINK_ID int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME),
+KEY LINK_ID (LINK_ID)
+);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (1,'Mike',0);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (2,'Jack',0);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (3,'Bill',0);
+CREATE TABLE t2 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(150) DEFAULT '' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME)
+);
+SELECT DISTINCT
+t2.id AS key_link_id,
+t2.name AS link
+FROM t1
+LEFT JOIN t2 ON t1.link_id=t2.id
+GROUP BY t1.id
+ORDER BY link;
key_link_id link
NULL NULL
+drop table t1,t2;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 413b03130f6..6d26f9aa90a 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -1,13 +1,1237 @@
+use test;
+drop table if exists t1,t2,t3,t4;
+CREATE TABLE t1 (
+Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
+Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
+);
+INSERT INTO t1 VALUES (9410,9412);
+select period from t1;
period
9410
+select * from t1;
Period Varor_period
9410 9412
+select t1.* from t1;
Period Varor_period
9410 9412
+CREATE TABLE t2 (
+auto int not null auto_increment,
+fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL,
+companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL,
+fld3 char(30) DEFAULT '' NOT NULL,
+fld4 char(35) DEFAULT '' NOT NULL,
+fld5 char(35) DEFAULT '' NOT NULL,
+fld6 char(4) DEFAULT '' NOT NULL,
+UNIQUE fld1 (fld1),
+KEY fld3 (fld3),
+PRIMARY KEY (auto)
+);
+INSERT INTO t2 VALUES (1,000001,00,'Omaha','teethe','neat','');
+INSERT INTO t2 VALUES (2,011401,37,'breaking','dreaded','Steinberg','W');
+INSERT INTO t2 VALUES (3,011402,37,'Romans','scholastics','jarring','');
+INSERT INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
+INSERT INTO t2 VALUES (5,011501,37,'bewilderingly','wallet','balled','');
+INSERT INTO t2 VALUES (6,011701,37,'astound','parters','persist','W');
+INSERT INTO t2 VALUES (7,011702,37,'admonishing','eschew','attainments','');
+INSERT INTO t2 VALUES (8,011703,37,'sumac','quitter','fanatic','');
+INSERT INTO t2 VALUES (9,012001,37,'flanking','neat','measures','FAS');
+INSERT INTO t2 VALUES (10,012003,37,'combed','Steinberg','rightfulness','');
+INSERT INTO t2 VALUES (11,012004,37,'subjective','jarring','capably','');
+INSERT INTO t2 VALUES (12,012005,37,'scatterbrain','tinily','impulsive','');
+INSERT INTO t2 VALUES (13,012301,37,'Eulerian','balled','starlet','');
+INSERT INTO t2 VALUES (14,012302,36,'dubbed','persist','terminators','');
+INSERT INTO t2 VALUES (15,012303,37,'Kane','attainments','untying','');
+INSERT INTO t2 VALUES (16,012304,37,'overlay','fanatic','announces','FAS');
+INSERT INTO t2 VALUES (17,012305,37,'perturb','measures','featherweight','FAS');
+INSERT INTO t2 VALUES (18,012306,37,'goblins','rightfulness','pessimist','FAS');
+INSERT INTO t2 VALUES (19,012501,37,'annihilates','capably','daughter','');
+INSERT INTO t2 VALUES (20,012602,37,'Wotan','impulsive','decliner','FAS');
+INSERT INTO t2 VALUES (21,012603,37,'snatching','starlet','lawgiver','');
+INSERT INTO t2 VALUES (22,012604,37,'concludes','terminators','stated','');
+INSERT INTO t2 VALUES (23,012605,37,'laterally','untying','readable','');
+INSERT INTO t2 VALUES (24,012606,37,'yelped','announces','attrition','');
+INSERT INTO t2 VALUES (25,012701,37,'grazing','featherweight','cascade','FAS');
+INSERT INTO t2 VALUES (26,012702,37,'Baird','pessimist','motors','FAS');
+INSERT INTO t2 VALUES (27,012703,37,'celery','daughter','interrogate','');
+INSERT INTO t2 VALUES (28,012704,37,'misunderstander','decliner','pests','W');
+INSERT INTO t2 VALUES (29,013601,37,'handgun','lawgiver','stairway','');
+INSERT INTO t2 VALUES (30,013602,37,'foldout','stated','dopers','FAS');
+INSERT INTO t2 VALUES (31,013603,37,'mystic','readable','testicle','W');
+INSERT INTO t2 VALUES (32,013604,37,'succumbed','attrition','Parsifal','W');
+INSERT INTO t2 VALUES (33,013605,37,'Nabisco','cascade','leavings','');
+INSERT INTO t2 VALUES (34,013606,37,'fingerings','motors','postulation','W');
+INSERT INTO t2 VALUES (35,013607,37,'aging','interrogate','squeaking','');
+INSERT INTO t2 VALUES (36,013608,37,'afield','pests','contrasted','');
+INSERT INTO t2 VALUES (37,013609,37,'ammonium','stairway','leftover','');
+INSERT INTO t2 VALUES (38,013610,37,'boat','dopers','whiteners','');
+INSERT INTO t2 VALUES (39,013801,37,'intelligibility','testicle','erases','W');
+INSERT INTO t2 VALUES (40,013802,37,'Augustine','Parsifal','Punjab','W');
+INSERT INTO t2 VALUES (41,013803,37,'teethe','leavings','Merritt','');
+INSERT INTO t2 VALUES (42,013804,37,'dreaded','postulation','Quixotism','');
+INSERT INTO t2 VALUES (43,013901,37,'scholastics','squeaking','sweetish','FAS');
+INSERT INTO t2 VALUES (44,016001,37,'audiology','contrasted','dogging','FAS');
+INSERT INTO t2 VALUES (45,016201,37,'wallet','leftover','scornfully','FAS');
+INSERT INTO t2 VALUES (46,016202,37,'parters','whiteners','bellow','');
+INSERT INTO t2 VALUES (47,016301,37,'eschew','erases','bills','');
+INSERT INTO t2 VALUES (48,016302,37,'quitter','Punjab','cupboard','FAS');
+INSERT INTO t2 VALUES (49,016303,37,'neat','Merritt','sureties','FAS');
+INSERT INTO t2 VALUES (50,016304,37,'Steinberg','Quixotism','puddings','');
+INSERT INTO t2 VALUES (51,018001,37,'jarring','sweetish','tapestry','');
+INSERT INTO t2 VALUES (52,018002,37,'tinily','dogging','fetters','');
+INSERT INTO t2 VALUES (53,018003,37,'balled','scornfully','bivalves','');
+INSERT INTO t2 VALUES (54,018004,37,'persist','bellow','incurring','');
+INSERT INTO t2 VALUES (55,018005,37,'attainments','bills','Adolph','');
+INSERT INTO t2 VALUES (56,018007,37,'fanatic','cupboard','pithed','');
+INSERT INTO t2 VALUES (57,018008,37,'measures','sureties','emergency','');
+INSERT INTO t2 VALUES (58,018009,37,'rightfulness','puddings','Miles','');
+INSERT INTO t2 VALUES (59,018010,37,'capably','tapestry','trimmings','');
+INSERT INTO t2 VALUES (60,018012,37,'impulsive','fetters','tragedies','W');
+INSERT INTO t2 VALUES (61,018013,37,'starlet','bivalves','skulking','W');
+INSERT INTO t2 VALUES (62,018014,37,'terminators','incurring','flint','');
+INSERT INTO t2 VALUES (63,018015,37,'untying','Adolph','flopping','W');
+INSERT INTO t2 VALUES (64,018016,37,'announces','pithed','relaxing','FAS');
+INSERT INTO t2 VALUES (65,018017,37,'featherweight','emergency','offload','FAS');
+INSERT INTO t2 VALUES (66,018018,37,'pessimist','Miles','suites','W');
+INSERT INTO t2 VALUES (67,018019,37,'daughter','trimmings','lists','FAS');
+INSERT INTO t2 VALUES (68,018020,37,'decliner','tragedies','animized','FAS');
+INSERT INTO t2 VALUES (69,018021,37,'lawgiver','skulking','multilayer','W');
+INSERT INTO t2 VALUES (70,018022,37,'stated','flint','standardizes','FAS');
+INSERT INTO t2 VALUES (71,018023,37,'readable','flopping','Judas','');
+INSERT INTO t2 VALUES (72,018024,37,'attrition','relaxing','vacuuming','W');
+INSERT INTO t2 VALUES (73,018025,37,'cascade','offload','dentally','W');
+INSERT INTO t2 VALUES (74,018026,37,'motors','suites','humanness','W');
+INSERT INTO t2 VALUES (75,018027,37,'interrogate','lists','inch','W');
+INSERT INTO t2 VALUES (76,018028,37,'pests','animized','Weissmuller','W');
+INSERT INTO t2 VALUES (77,018029,37,'stairway','multilayer','irresponsibly','W');
+INSERT INTO t2 VALUES (78,018030,37,'dopers','standardizes','luckily','FAS');
+INSERT INTO t2 VALUES (79,018032,37,'testicle','Judas','culled','W');
+INSERT INTO t2 VALUES (80,018033,37,'Parsifal','vacuuming','medical','FAS');
+INSERT INTO t2 VALUES (81,018034,37,'leavings','dentally','bloodbath','FAS');
+INSERT INTO t2 VALUES (82,018035,37,'postulation','humanness','subschema','W');
+INSERT INTO t2 VALUES (83,018036,37,'squeaking','inch','animals','W');
+INSERT INTO t2 VALUES (84,018037,37,'contrasted','Weissmuller','Micronesia','');
+INSERT INTO t2 VALUES (85,018038,37,'leftover','irresponsibly','repetitions','');
+INSERT INTO t2 VALUES (86,018039,37,'whiteners','luckily','Antares','');
+INSERT INTO t2 VALUES (87,018040,37,'erases','culled','ventilate','W');
+INSERT INTO t2 VALUES (88,018041,37,'Punjab','medical','pityingly','');
+INSERT INTO t2 VALUES (89,018042,37,'Merritt','bloodbath','interdependent','');
+INSERT INTO t2 VALUES (90,018043,37,'Quixotism','subschema','Graves','FAS');
+INSERT INTO t2 VALUES (91,018044,37,'sweetish','animals','neonatal','');
+INSERT INTO t2 VALUES (92,018045,37,'dogging','Micronesia','scribbled','FAS');
+INSERT INTO t2 VALUES (93,018046,37,'scornfully','repetitions','chafe','W');
+INSERT INTO t2 VALUES (94,018048,37,'bellow','Antares','honoring','');
+INSERT INTO t2 VALUES (95,018049,37,'bills','ventilate','realtor','');
+INSERT INTO t2 VALUES (96,018050,37,'cupboard','pityingly','elite','');
+INSERT INTO t2 VALUES (97,018051,37,'sureties','interdependent','funereal','');
+INSERT INTO t2 VALUES (98,018052,37,'puddings','Graves','abrogating','');
+INSERT INTO t2 VALUES (99,018053,50,'tapestry','neonatal','sorters','');
+INSERT INTO t2 VALUES (100,018054,37,'fetters','scribbled','Conley','');
+INSERT INTO t2 VALUES (101,018055,37,'bivalves','chafe','lectured','');
+INSERT INTO t2 VALUES (102,018056,37,'incurring','honoring','Abraham','');
+INSERT INTO t2 VALUES (103,018057,37,'Adolph','realtor','Hawaii','W');
+INSERT INTO t2 VALUES (104,018058,37,'pithed','elite','cage','');
+INSERT INTO t2 VALUES (105,018059,36,'emergency','funereal','hushes','');
+INSERT INTO t2 VALUES (106,018060,37,'Miles','abrogating','Simla','');
+INSERT INTO t2 VALUES (107,018061,37,'trimmings','sorters','reporters','');
+INSERT INTO t2 VALUES (108,018101,37,'tragedies','Conley','Dutchman','FAS');
+INSERT INTO t2 VALUES (109,018102,37,'skulking','lectured','descendants','FAS');
+INSERT INTO t2 VALUES (110,018103,37,'flint','Abraham','groupings','FAS');
+INSERT INTO t2 VALUES (111,018104,37,'flopping','Hawaii','dissociate','');
+INSERT INTO t2 VALUES (112,018201,37,'relaxing','cage','coexist','W');
+INSERT INTO t2 VALUES (113,018202,37,'offload','hushes','Beebe','');
+INSERT INTO t2 VALUES (114,018402,37,'suites','Simla','Taoism','');
+INSERT INTO t2 VALUES (115,018403,37,'lists','reporters','Connally','');
+INSERT INTO t2 VALUES (116,018404,37,'animized','Dutchman','fetched','FAS');
+INSERT INTO t2 VALUES (117,018405,37,'multilayer','descendants','checkpoints','FAS');
+INSERT INTO t2 VALUES (118,018406,37,'standardizes','groupings','rusting','');
+INSERT INTO t2 VALUES (119,018409,37,'Judas','dissociate','galling','');
+INSERT INTO t2 VALUES (120,018601,37,'vacuuming','coexist','obliterates','');
+INSERT INTO t2 VALUES (121,018602,37,'dentally','Beebe','traitor','');
+INSERT INTO t2 VALUES (122,018603,37,'humanness','Taoism','resumes','FAS');
+INSERT INTO t2 VALUES (123,018801,37,'inch','Connally','analyzable','FAS');
+INSERT INTO t2 VALUES (124,018802,37,'Weissmuller','fetched','terminator','FAS');
+INSERT INTO t2 VALUES (125,018803,37,'irresponsibly','checkpoints','gritty','FAS');
+INSERT INTO t2 VALUES (126,018804,37,'luckily','rusting','firearm','W');
+INSERT INTO t2 VALUES (127,018805,37,'culled','galling','minima','');
+INSERT INTO t2 VALUES (128,018806,37,'medical','obliterates','Selfridge','');
+INSERT INTO t2 VALUES (129,018807,37,'bloodbath','traitor','disable','');
+INSERT INTO t2 VALUES (130,018808,37,'subschema','resumes','witchcraft','W');
+INSERT INTO t2 VALUES (131,018809,37,'animals','analyzable','betroth','W');
+INSERT INTO t2 VALUES (132,018810,37,'Micronesia','terminator','Manhattanize','');
+INSERT INTO t2 VALUES (133,018811,37,'repetitions','gritty','imprint','');
+INSERT INTO t2 VALUES (134,018812,37,'Antares','firearm','peeked','');
+INSERT INTO t2 VALUES (135,019101,37,'ventilate','minima','swelling','');
+INSERT INTO t2 VALUES (136,019102,37,'pityingly','Selfridge','interrelationships','W');
+INSERT INTO t2 VALUES (137,019103,37,'interdependent','disable','riser','');
+INSERT INTO t2 VALUES (138,019201,37,'Graves','witchcraft','Gandhian','W');
+INSERT INTO t2 VALUES (139,030501,37,'neonatal','betroth','peacock','A');
+INSERT INTO t2 VALUES (140,030502,50,'scribbled','Manhattanize','bee','A');
+INSERT INTO t2 VALUES (141,030503,37,'chafe','imprint','kanji','');
+INSERT INTO t2 VALUES (142,030504,37,'honoring','peeked','dental','');
+INSERT INTO t2 VALUES (143,031901,37,'realtor','swelling','scarf','FAS');
+INSERT INTO t2 VALUES (144,036001,37,'elite','interrelationships','chasm','A');
+INSERT INTO t2 VALUES (145,036002,37,'funereal','riser','insolence','A');
+INSERT INTO t2 VALUES (146,036004,37,'abrogating','Gandhian','syndicate','');
+INSERT INTO t2 VALUES (147,036005,37,'sorters','peacock','alike','');
+INSERT INTO t2 VALUES (148,038001,37,'Conley','bee','imperial','A');
+INSERT INTO t2 VALUES (149,038002,37,'lectured','kanji','convulsion','A');
+INSERT INTO t2 VALUES (150,038003,37,'Abraham','dental','railway','A');
+INSERT INTO t2 VALUES (151,038004,37,'Hawaii','scarf','validate','A');
+INSERT INTO t2 VALUES (152,038005,37,'cage','chasm','normalizes','A');
+INSERT INTO t2 VALUES (153,038006,37,'hushes','insolence','comprehensive','');
+INSERT INTO t2 VALUES (154,038007,37,'Simla','syndicate','chewing','');
+INSERT INTO t2 VALUES (155,038008,37,'reporters','alike','denizen','');
+INSERT INTO t2 VALUES (156,038009,37,'Dutchman','imperial','schemer','');
+INSERT INTO t2 VALUES (157,038010,37,'descendants','convulsion','chronicle','');
+INSERT INTO t2 VALUES (158,038011,37,'groupings','railway','Kline','');
+INSERT INTO t2 VALUES (159,038012,37,'dissociate','validate','Anatole','');
+INSERT INTO t2 VALUES (160,038013,37,'coexist','normalizes','partridges','');
+INSERT INTO t2 VALUES (161,038014,37,'Beebe','comprehensive','brunch','');
+INSERT INTO t2 VALUES (162,038015,37,'Taoism','chewing','recruited','');
+INSERT INTO t2 VALUES (163,038016,37,'Connally','denizen','dimensions','W');
+INSERT INTO t2 VALUES (164,038017,37,'fetched','schemer','Chicana','W');
+INSERT INTO t2 VALUES (165,038018,37,'checkpoints','chronicle','announced','');
+INSERT INTO t2 VALUES (166,038101,37,'rusting','Kline','praised','FAS');
+INSERT INTO t2 VALUES (167,038102,37,'galling','Anatole','employing','');
+INSERT INTO t2 VALUES (168,038103,37,'obliterates','partridges','linear','');
+INSERT INTO t2 VALUES (169,038104,37,'traitor','brunch','quagmire','');
+INSERT INTO t2 VALUES (170,038201,37,'resumes','recruited','western','A');
+INSERT INTO t2 VALUES (171,038202,37,'analyzable','dimensions','relishing','');
+INSERT INTO t2 VALUES (172,038203,37,'terminator','Chicana','serving','A');
+INSERT INTO t2 VALUES (173,038204,37,'gritty','announced','scheduling','');
+INSERT INTO t2 VALUES (174,038205,37,'firearm','praised','lore','');
+INSERT INTO t2 VALUES (175,038206,37,'minima','employing','eventful','');
+INSERT INTO t2 VALUES (176,038208,37,'Selfridge','linear','arteriole','A');
+INSERT INTO t2 VALUES (177,042801,37,'disable','quagmire','disentangle','');
+INSERT INTO t2 VALUES (178,042802,37,'witchcraft','western','cured','A');
+INSERT INTO t2 VALUES (179,046101,37,'betroth','relishing','Fenton','W');
+INSERT INTO t2 VALUES (180,048001,37,'Manhattanize','serving','avoidable','A');
+INSERT INTO t2 VALUES (181,048002,37,'imprint','scheduling','drains','A');
+INSERT INTO t2 VALUES (182,048003,37,'peeked','lore','detectably','FAS');
+INSERT INTO t2 VALUES (183,048004,37,'swelling','eventful','husky','');
+INSERT INTO t2 VALUES (184,048005,37,'interrelationships','arteriole','impelling','');
+INSERT INTO t2 VALUES (185,048006,37,'riser','disentangle','undoes','');
+INSERT INTO t2 VALUES (186,048007,37,'Gandhian','cured','evened','');
+INSERT INTO t2 VALUES (187,048008,37,'peacock','Fenton','squeezes','');
+INSERT INTO t2 VALUES (188,048101,37,'bee','avoidable','destroyer','FAS');
+INSERT INTO t2 VALUES (189,048102,37,'kanji','drains','rudeness','');
+INSERT INTO t2 VALUES (190,048201,37,'dental','detectably','beaner','FAS');
+INSERT INTO t2 VALUES (191,048202,37,'scarf','husky','boorish','');
+INSERT INTO t2 VALUES (192,048203,37,'chasm','impelling','Everhart','');
+INSERT INTO t2 VALUES (193,048204,37,'insolence','undoes','encompass','A');
+INSERT INTO t2 VALUES (194,048205,37,'syndicate','evened','mushrooms','');
+INSERT INTO t2 VALUES (195,048301,37,'alike','squeezes','Alison','A');
+INSERT INTO t2 VALUES (196,048302,37,'imperial','destroyer','externally','FAS');
+INSERT INTO t2 VALUES (197,048303,37,'convulsion','rudeness','pellagra','');
+INSERT INTO t2 VALUES (198,048304,37,'railway','beaner','cult','');
+INSERT INTO t2 VALUES (199,048305,37,'validate','boorish','creek','A');
+INSERT INTO t2 VALUES (200,048401,37,'normalizes','Everhart','Huffman','');
+INSERT INTO t2 VALUES (201,048402,37,'comprehensive','encompass','Majorca','FAS');
+INSERT INTO t2 VALUES (202,048403,37,'chewing','mushrooms','governing','A');
+INSERT INTO t2 VALUES (203,048404,37,'denizen','Alison','gadfly','FAS');
+INSERT INTO t2 VALUES (204,048405,37,'schemer','externally','reassigned','FAS');
+INSERT INTO t2 VALUES (205,048406,37,'chronicle','pellagra','intentness','W');
+INSERT INTO t2 VALUES (206,048407,37,'Kline','cult','craziness','');
+INSERT INTO t2 VALUES (207,048408,37,'Anatole','creek','psychic','');
+INSERT INTO t2 VALUES (208,048409,37,'partridges','Huffman','squabbled','');
+INSERT INTO t2 VALUES (209,048410,37,'brunch','Majorca','burlesque','');
+INSERT INTO t2 VALUES (210,048411,37,'recruited','governing','capped','');
+INSERT INTO t2 VALUES (211,048412,37,'dimensions','gadfly','extracted','A');
+INSERT INTO t2 VALUES (212,048413,37,'Chicana','reassigned','DiMaggio','');
+INSERT INTO t2 VALUES (213,048601,37,'announced','intentness','exclamation','FAS');
+INSERT INTO t2 VALUES (214,048602,37,'praised','craziness','subdirectory','');
+INSERT INTO t2 VALUES (215,048603,37,'employing','psychic','fangs','');
+INSERT INTO t2 VALUES (216,048604,37,'linear','squabbled','buyer','A');
+INSERT INTO t2 VALUES (217,048801,37,'quagmire','burlesque','pithing','A');
+INSERT INTO t2 VALUES (218,050901,37,'western','capped','transistorizing','A');
+INSERT INTO t2 VALUES (219,051201,37,'relishing','extracted','nonbiodegradable','');
+INSERT INTO t2 VALUES (220,056002,37,'serving','DiMaggio','dislocate','');
+INSERT INTO t2 VALUES (221,056003,37,'scheduling','exclamation','monochromatic','FAS');
+INSERT INTO t2 VALUES (222,056004,37,'lore','subdirectory','batting','');
+INSERT INTO t2 VALUES (223,056102,37,'eventful','fangs','postcondition','A');
+INSERT INTO t2 VALUES (224,056203,37,'arteriole','buyer','catalog','FAS');
+INSERT INTO t2 VALUES (225,056204,37,'disentangle','pithing','Remus','');
+INSERT INTO t2 VALUES (226,058003,37,'cured','transistorizing','devices','A');
+INSERT INTO t2 VALUES (227,058004,37,'Fenton','nonbiodegradable','bike','A');
+INSERT INTO t2 VALUES (228,058005,37,'avoidable','dislocate','qualify','');
+INSERT INTO t2 VALUES (229,058006,37,'drains','monochromatic','detained','');
+INSERT INTO t2 VALUES (230,058007,37,'detectably','batting','commended','');
+INSERT INTO t2 VALUES (231,058101,37,'husky','postcondition','civilize','');
+INSERT INTO t2 VALUES (232,058102,37,'impelling','catalog','Elmhurst','');
+INSERT INTO t2 VALUES (233,058103,37,'undoes','Remus','anesthetizing','');
+INSERT INTO t2 VALUES (234,058105,37,'evened','devices','deaf','');
+INSERT INTO t2 VALUES (235,058111,37,'squeezes','bike','Brigham','');
+INSERT INTO t2 VALUES (236,058112,37,'destroyer','qualify','title','');
+INSERT INTO t2 VALUES (237,058113,37,'rudeness','detained','coarse','');
+INSERT INTO t2 VALUES (238,058114,37,'beaner','commended','combinations','');
+INSERT INTO t2 VALUES (239,058115,37,'boorish','civilize','grayness','');
+INSERT INTO t2 VALUES (240,058116,37,'Everhart','Elmhurst','innumerable','FAS');
+INSERT INTO t2 VALUES (241,058117,37,'encompass','anesthetizing','Caroline','A');
+INSERT INTO t2 VALUES (242,058118,37,'mushrooms','deaf','fatty','FAS');
+INSERT INTO t2 VALUES (243,058119,37,'Alison','Brigham','eastbound','');
+INSERT INTO t2 VALUES (244,058120,37,'externally','title','inexperienced','');
+INSERT INTO t2 VALUES (245,058121,37,'pellagra','coarse','hoarder','A');
+INSERT INTO t2 VALUES (246,058122,37,'cult','combinations','scotch','W');
+INSERT INTO t2 VALUES (247,058123,37,'creek','grayness','passport','A');
+INSERT INTO t2 VALUES (248,058124,37,'Huffman','innumerable','strategic','FAS');
+INSERT INTO t2 VALUES (249,058125,37,'Majorca','Caroline','gated','');
+INSERT INTO t2 VALUES (250,058126,37,'governing','fatty','flog','');
+INSERT INTO t2 VALUES (251,058127,37,'gadfly','eastbound','Pipestone','');
+INSERT INTO t2 VALUES (252,058128,37,'reassigned','inexperienced','Dar','');
+INSERT INTO t2 VALUES (253,058201,37,'intentness','hoarder','Corcoran','');
+INSERT INTO t2 VALUES (254,058202,37,'craziness','scotch','flyers','A');
+INSERT INTO t2 VALUES (255,058303,37,'psychic','passport','competitions','W');
+INSERT INTO t2 VALUES (256,058304,37,'squabbled','strategic','suppliers','FAS');
+INSERT INTO t2 VALUES (257,058602,37,'burlesque','gated','skips','');
+INSERT INTO t2 VALUES (258,058603,37,'capped','flog','institutes','');
+INSERT INTO t2 VALUES (259,058604,37,'extracted','Pipestone','troop','A');
+INSERT INTO t2 VALUES (260,058605,37,'DiMaggio','Dar','connective','W');
+INSERT INTO t2 VALUES (261,058606,37,'exclamation','Corcoran','denies','');
+INSERT INTO t2 VALUES (262,058607,37,'subdirectory','flyers','polka','');
+INSERT INTO t2 VALUES (263,060401,36,'fangs','competitions','observations','FAS');
+INSERT INTO t2 VALUES (264,061701,36,'buyer','suppliers','askers','');
+INSERT INTO t2 VALUES (265,066201,36,'pithing','skips','homeless','FAS');
+INSERT INTO t2 VALUES (266,066501,36,'transistorizing','institutes','Anna','');
+INSERT INTO t2 VALUES (267,068001,36,'nonbiodegradable','troop','subdirectories','W');
+INSERT INTO t2 VALUES (268,068002,36,'dislocate','connective','decaying','FAS');
+INSERT INTO t2 VALUES (269,068005,36,'monochromatic','denies','outwitting','W');
+INSERT INTO t2 VALUES (270,068006,36,'batting','polka','Harpy','W');
+INSERT INTO t2 VALUES (271,068007,36,'postcondition','observations','crazed','');
+INSERT INTO t2 VALUES (272,068008,36,'catalog','askers','suffocate','');
+INSERT INTO t2 VALUES (273,068009,36,'Remus','homeless','provers','FAS');
+INSERT INTO t2 VALUES (274,068010,36,'devices','Anna','technically','');
+INSERT INTO t2 VALUES (275,068011,36,'bike','subdirectories','Franklinizations','');
+INSERT INTO t2 VALUES (276,068202,36,'qualify','decaying','considered','');
+INSERT INTO t2 VALUES (277,068302,36,'detained','outwitting','tinnily','');
+INSERT INTO t2 VALUES (278,068303,36,'commended','Harpy','uninterruptedly','');
+INSERT INTO t2 VALUES (279,068401,36,'civilize','crazed','whistled','A');
+INSERT INTO t2 VALUES (280,068501,36,'Elmhurst','suffocate','automate','');
+INSERT INTO t2 VALUES (281,068502,36,'anesthetizing','provers','gutting','W');
+INSERT INTO t2 VALUES (282,068503,36,'deaf','technically','surreptitious','');
+INSERT INTO t2 VALUES (283,068602,36,'Brigham','Franklinizations','Choctaw','');
+INSERT INTO t2 VALUES (284,068603,36,'title','considered','cooks','');
+INSERT INTO t2 VALUES (285,068701,36,'coarse','tinnily','millivolt','FAS');
+INSERT INTO t2 VALUES (286,068702,36,'combinations','uninterruptedly','counterpoise','');
+INSERT INTO t2 VALUES (287,068703,36,'grayness','whistled','Gothicism','');
+INSERT INTO t2 VALUES (288,076001,36,'innumerable','automate','feminine','');
+INSERT INTO t2 VALUES (289,076002,36,'Caroline','gutting','metaphysically','W');
+INSERT INTO t2 VALUES (290,076101,36,'fatty','surreptitious','sanding','A');
+INSERT INTO t2 VALUES (291,076102,36,'eastbound','Choctaw','contributorily','');
+INSERT INTO t2 VALUES (292,076103,36,'inexperienced','cooks','receivers','FAS');
+INSERT INTO t2 VALUES (293,076302,36,'hoarder','millivolt','adjourn','');
+INSERT INTO t2 VALUES (294,076303,36,'scotch','counterpoise','straggled','A');
+INSERT INTO t2 VALUES (295,076304,36,'passport','Gothicism','druggists','');
+INSERT INTO t2 VALUES (296,076305,36,'strategic','feminine','thanking','FAS');
+INSERT INTO t2 VALUES (297,076306,36,'gated','metaphysically','ostrich','');
+INSERT INTO t2 VALUES (298,076307,36,'flog','sanding','hopelessness','FAS');
+INSERT INTO t2 VALUES (299,076402,36,'Pipestone','contributorily','Eurydice','');
+INSERT INTO t2 VALUES (300,076501,36,'Dar','receivers','excitation','W');
+INSERT INTO t2 VALUES (301,076502,36,'Corcoran','adjourn','presumes','FAS');
+INSERT INTO t2 VALUES (302,076701,36,'flyers','straggled','imaginable','FAS');
+INSERT INTO t2 VALUES (303,078001,36,'competitions','druggists','concoct','W');
+INSERT INTO t2 VALUES (304,078002,36,'suppliers','thanking','peering','W');
+INSERT INTO t2 VALUES (305,078003,36,'skips','ostrich','Phelps','FAS');
+INSERT INTO t2 VALUES (306,078004,36,'institutes','hopelessness','ferociousness','FAS');
+INSERT INTO t2 VALUES (307,078005,36,'troop','Eurydice','sentences','');
+INSERT INTO t2 VALUES (308,078006,36,'connective','excitation','unlocks','');
+INSERT INTO t2 VALUES (309,078007,36,'denies','presumes','engrossing','W');
+INSERT INTO t2 VALUES (310,078008,36,'polka','imaginable','Ruth','');
+INSERT INTO t2 VALUES (311,078101,36,'observations','concoct','tying','');
+INSERT INTO t2 VALUES (312,078103,36,'askers','peering','exclaimers','');
+INSERT INTO t2 VALUES (313,078104,36,'homeless','Phelps','synergy','');
+INSERT INTO t2 VALUES (314,078105,36,'Anna','ferociousness','Huey','W');
+INSERT INTO t2 VALUES (315,082101,36,'subdirectories','sentences','merging','');
+INSERT INTO t2 VALUES (316,083401,36,'decaying','unlocks','judges','A');
+INSERT INTO t2 VALUES (317,084001,36,'outwitting','engrossing','Shylock','W');
+INSERT INTO t2 VALUES (318,084002,36,'Harpy','Ruth','Miltonism','');
+INSERT INTO t2 VALUES (319,086001,36,'crazed','tying','hen','W');
+INSERT INTO t2 VALUES (320,086102,36,'suffocate','exclaimers','honeybee','FAS');
+INSERT INTO t2 VALUES (321,086201,36,'provers','synergy','towers','');
+INSERT INTO t2 VALUES (322,088001,36,'technically','Huey','dilutes','W');
+INSERT INTO t2 VALUES (323,088002,36,'Franklinizations','merging','numerals','FAS');
+INSERT INTO t2 VALUES (324,088003,36,'considered','judges','democracy','FAS');
+INSERT INTO t2 VALUES (325,088004,36,'tinnily','Shylock','Ibero-','');
+INSERT INTO t2 VALUES (326,088101,36,'uninterruptedly','Miltonism','invalids','');
+INSERT INTO t2 VALUES (327,088102,36,'whistled','hen','behavior','');
+INSERT INTO t2 VALUES (328,088103,36,'automate','honeybee','accruing','');
+INSERT INTO t2 VALUES (329,088104,36,'gutting','towers','relics','A');
+INSERT INTO t2 VALUES (330,088105,36,'surreptitious','dilutes','rackets','');
+INSERT INTO t2 VALUES (331,088106,36,'Choctaw','numerals','Fischbein','W');
+INSERT INTO t2 VALUES (332,088201,36,'cooks','democracy','phony','W');
+INSERT INTO t2 VALUES (333,088203,36,'millivolt','Ibero-','cross','FAS');
+INSERT INTO t2 VALUES (334,088204,36,'counterpoise','invalids','cleanup','');
+INSERT INTO t2 VALUES (335,088302,37,'Gothicism','behavior','conspirator','');
+INSERT INTO t2 VALUES (336,088303,37,'feminine','accruing','label','FAS');
+INSERT INTO t2 VALUES (337,088305,37,'metaphysically','relics','university','');
+INSERT INTO t2 VALUES (338,088402,37,'sanding','rackets','cleansed','FAS');
+INSERT INTO t2 VALUES (339,088501,36,'contributorily','Fischbein','ballgown','');
+INSERT INTO t2 VALUES (340,088502,36,'receivers','phony','starlet','');
+INSERT INTO t2 VALUES (341,088503,36,'adjourn','cross','aqueous','');
+INSERT INTO t2 VALUES (342,098001,58,'straggled','cleanup','portrayal','A');
+INSERT INTO t2 VALUES (343,098002,58,'druggists','conspirator','despising','W');
+INSERT INTO t2 VALUES (344,098003,58,'thanking','label','distort','W');
+INSERT INTO t2 VALUES (345,098004,58,'ostrich','university','palmed','');
+INSERT INTO t2 VALUES (346,098005,58,'hopelessness','cleansed','faced','');
+INSERT INTO t2 VALUES (347,098006,58,'Eurydice','ballgown','silverware','');
+INSERT INTO t2 VALUES (348,141903,29,'excitation','starlet','assessor','');
+INSERT INTO t2 VALUES (349,098008,58,'presumes','aqueous','spiders','');
+INSERT INTO t2 VALUES (350,098009,58,'imaginable','portrayal','artificially','');
+INSERT INTO t2 VALUES (351,098010,58,'concoct','despising','reminiscence','');
+INSERT INTO t2 VALUES (352,098011,58,'peering','distort','Mexican','');
+INSERT INTO t2 VALUES (353,098012,58,'Phelps','palmed','obnoxious','');
+INSERT INTO t2 VALUES (354,098013,58,'ferociousness','faced','fragile','');
+INSERT INTO t2 VALUES (355,098014,58,'sentences','silverware','apprehensible','');
+INSERT INTO t2 VALUES (356,098015,58,'unlocks','assessor','births','');
+INSERT INTO t2 VALUES (357,098016,58,'engrossing','spiders','garages','');
+INSERT INTO t2 VALUES (358,098017,58,'Ruth','artificially','panty','');
+INSERT INTO t2 VALUES (359,098018,58,'tying','reminiscence','anteater','');
+INSERT INTO t2 VALUES (360,098019,58,'exclaimers','Mexican','displacement','A');
+INSERT INTO t2 VALUES (361,098020,58,'synergy','obnoxious','drovers','A');
+INSERT INTO t2 VALUES (362,098021,58,'Huey','fragile','patenting','A');
+INSERT INTO t2 VALUES (363,098022,58,'merging','apprehensible','far','A');
+INSERT INTO t2 VALUES (364,098023,58,'judges','births','shrieks','');
+INSERT INTO t2 VALUES (365,098024,58,'Shylock','garages','aligning','W');
+INSERT INTO t2 VALUES (366,098025,37,'Miltonism','panty','pragmatism','');
+INSERT INTO t2 VALUES (367,106001,36,'hen','anteater','fevers','W');
+INSERT INTO t2 VALUES (368,108001,36,'honeybee','displacement','reexamines','A');
+INSERT INTO t2 VALUES (369,108002,36,'towers','drovers','occupancies','');
+INSERT INTO t2 VALUES (370,108003,36,'dilutes','patenting','sweats','FAS');
+INSERT INTO t2 VALUES (371,108004,36,'numerals','far','modulators','');
+INSERT INTO t2 VALUES (372,108005,36,'democracy','shrieks','demand','W');
+INSERT INTO t2 VALUES (373,108007,36,'Ibero-','aligning','Madeira','');
+INSERT INTO t2 VALUES (374,108008,36,'invalids','pragmatism','Viennese','W');
+INSERT INTO t2 VALUES (375,108009,36,'behavior','fevers','chillier','W');
+INSERT INTO t2 VALUES (376,108010,36,'accruing','reexamines','wildcats','FAS');
+INSERT INTO t2 VALUES (377,108011,36,'relics','occupancies','gentle','');
+INSERT INTO t2 VALUES (378,108012,36,'rackets','sweats','Angles','W');
+INSERT INTO t2 VALUES (379,108101,36,'Fischbein','modulators','accuracies','');
+INSERT INTO t2 VALUES (380,108102,36,'phony','demand','toggle','');
+INSERT INTO t2 VALUES (381,108103,36,'cross','Madeira','Mendelssohn','W');
+INSERT INTO t2 VALUES (382,108111,50,'cleanup','Viennese','behaviorally','');
+INSERT INTO t2 VALUES (383,108105,36,'conspirator','chillier','Rochford','');
+INSERT INTO t2 VALUES (384,108106,36,'label','wildcats','mirror','W');
+INSERT INTO t2 VALUES (385,108107,36,'university','gentle','Modula','');
+INSERT INTO t2 VALUES (386,108108,50,'cleansed','Angles','clobbering','');
+INSERT INTO t2 VALUES (387,108109,36,'ballgown','accuracies','chronography','');
+INSERT INTO t2 VALUES (388,108110,36,'starlet','toggle','Eskimoizeds','');
+INSERT INTO t2 VALUES (389,108201,36,'aqueous','Mendelssohn','British','W');
+INSERT INTO t2 VALUES (390,108202,36,'portrayal','behaviorally','pitfalls','');
+INSERT INTO t2 VALUES (391,108203,36,'despising','Rochford','verify','W');
+INSERT INTO t2 VALUES (392,108204,36,'distort','mirror','scatter','FAS');
+INSERT INTO t2 VALUES (393,108205,36,'palmed','Modula','Aztecan','');
+INSERT INTO t2 VALUES (394,108301,36,'faced','clobbering','acuity','W');
+INSERT INTO t2 VALUES (395,108302,36,'silverware','chronography','sinking','W');
+INSERT INTO t2 VALUES (396,112101,36,'assessor','Eskimoizeds','beasts','FAS');
+INSERT INTO t2 VALUES (397,112102,36,'spiders','British','Witt','W');
+INSERT INTO t2 VALUES (398,113701,36,'artificially','pitfalls','physicists','FAS');
+INSERT INTO t2 VALUES (399,116001,36,'reminiscence','verify','folksong','A');
+INSERT INTO t2 VALUES (400,116201,36,'Mexican','scatter','strokes','FAS');
+INSERT INTO t2 VALUES (401,116301,36,'obnoxious','Aztecan','crowder','');
+INSERT INTO t2 VALUES (402,116302,36,'fragile','acuity','merry','');
+INSERT INTO t2 VALUES (403,116601,36,'apprehensible','sinking','cadenced','');
+INSERT INTO t2 VALUES (404,116602,36,'births','beasts','alimony','A');
+INSERT INTO t2 VALUES (405,116603,36,'garages','Witt','principled','A');
+INSERT INTO t2 VALUES (406,116701,36,'panty','physicists','golfing','');
+INSERT INTO t2 VALUES (407,116702,36,'anteater','folksong','undiscovered','');
+INSERT INTO t2 VALUES (408,118001,36,'displacement','strokes','irritates','');
+INSERT INTO t2 VALUES (409,118002,36,'drovers','crowder','patriots','A');
+INSERT INTO t2 VALUES (410,118003,36,'patenting','merry','rooms','FAS');
+INSERT INTO t2 VALUES (411,118004,36,'far','cadenced','towering','W');
+INSERT INTO t2 VALUES (412,118005,36,'shrieks','alimony','displease','');
+INSERT INTO t2 VALUES (413,118006,36,'aligning','principled','photosensitive','');
+INSERT INTO t2 VALUES (414,118007,36,'pragmatism','golfing','inking','');
+INSERT INTO t2 VALUES (415,118008,36,'fevers','undiscovered','gainers','');
+INSERT INTO t2 VALUES (416,118101,36,'reexamines','irritates','leaning','A');
+INSERT INTO t2 VALUES (417,118102,36,'occupancies','patriots','hydrant','A');
+INSERT INTO t2 VALUES (418,118103,36,'sweats','rooms','preserve','');
+INSERT INTO t2 VALUES (419,118202,36,'modulators','towering','blinded','A');
+INSERT INTO t2 VALUES (420,118203,36,'demand','displease','interactions','A');
+INSERT INTO t2 VALUES (421,118204,36,'Madeira','photosensitive','Barry','');
+INSERT INTO t2 VALUES (422,118302,36,'Viennese','inking','whiteness','A');
+INSERT INTO t2 VALUES (423,118304,36,'chillier','gainers','pastimes','W');
+INSERT INTO t2 VALUES (424,118305,36,'wildcats','leaning','Edenization','');
+INSERT INTO t2 VALUES (425,118306,36,'gentle','hydrant','Muscat','');
+INSERT INTO t2 VALUES (426,118307,36,'Angles','preserve','assassinated','');
+INSERT INTO t2 VALUES (427,123101,36,'accuracies','blinded','labeled','');
+INSERT INTO t2 VALUES (428,123102,36,'toggle','interactions','glacial','A');
+INSERT INTO t2 VALUES (429,123301,36,'Mendelssohn','Barry','implied','W');
+INSERT INTO t2 VALUES (430,126001,36,'behaviorally','whiteness','bibliographies','W');
+INSERT INTO t2 VALUES (431,126002,36,'Rochford','pastimes','Buchanan','');
+INSERT INTO t2 VALUES (432,126003,36,'mirror','Edenization','forgivably','FAS');
+INSERT INTO t2 VALUES (433,126101,36,'Modula','Muscat','innuendo','A');
+INSERT INTO t2 VALUES (434,126301,36,'clobbering','assassinated','den','FAS');
+INSERT INTO t2 VALUES (435,126302,36,'chronography','labeled','submarines','W');
+INSERT INTO t2 VALUES (436,126402,36,'Eskimoizeds','glacial','mouthful','A');
+INSERT INTO t2 VALUES (437,126601,36,'British','implied','expiring','');
+INSERT INTO t2 VALUES (438,126602,36,'pitfalls','bibliographies','unfulfilled','FAS');
+INSERT INTO t2 VALUES (439,126702,36,'verify','Buchanan','precession','');
+INSERT INTO t2 VALUES (440,128001,36,'scatter','forgivably','nullified','');
+INSERT INTO t2 VALUES (441,128002,36,'Aztecan','innuendo','affects','');
+INSERT INTO t2 VALUES (442,128003,36,'acuity','den','Cynthia','');
+INSERT INTO t2 VALUES (443,128004,36,'sinking','submarines','Chablis','A');
+INSERT INTO t2 VALUES (444,128005,36,'beasts','mouthful','betterments','FAS');
+INSERT INTO t2 VALUES (445,128007,36,'Witt','expiring','advertising','');
+INSERT INTO t2 VALUES (446,128008,36,'physicists','unfulfilled','rubies','A');
+INSERT INTO t2 VALUES (447,128009,36,'folksong','precession','southwest','FAS');
+INSERT INTO t2 VALUES (448,128010,36,'strokes','nullified','superstitious','A');
+INSERT INTO t2 VALUES (449,128011,36,'crowder','affects','tabernacle','W');
+INSERT INTO t2 VALUES (450,128012,36,'merry','Cynthia','silk','A');
+INSERT INTO t2 VALUES (451,128013,36,'cadenced','Chablis','handsomest','A');
+INSERT INTO t2 VALUES (452,128014,36,'alimony','betterments','Persian','A');
+INSERT INTO t2 VALUES (453,128015,36,'principled','advertising','analog','W');
+INSERT INTO t2 VALUES (454,128016,36,'golfing','rubies','complex','W');
+INSERT INTO t2 VALUES (455,128017,36,'undiscovered','southwest','Taoist','');
+INSERT INTO t2 VALUES (456,128018,36,'irritates','superstitious','suspend','');
+INSERT INTO t2 VALUES (457,128019,36,'patriots','tabernacle','relegated','');
+INSERT INTO t2 VALUES (458,128020,36,'rooms','silk','awesome','W');
+INSERT INTO t2 VALUES (459,128021,36,'towering','handsomest','Bruxelles','');
+INSERT INTO t2 VALUES (460,128022,36,'displease','Persian','imprecisely','A');
+INSERT INTO t2 VALUES (461,128023,36,'photosensitive','analog','televise','');
+INSERT INTO t2 VALUES (462,128101,36,'inking','complex','braking','');
+INSERT INTO t2 VALUES (463,128102,36,'gainers','Taoist','true','FAS');
+INSERT INTO t2 VALUES (464,128103,36,'leaning','suspend','disappointing','FAS');
+INSERT INTO t2 VALUES (465,128104,36,'hydrant','relegated','navally','W');
+INSERT INTO t2 VALUES (466,128106,36,'preserve','awesome','circus','');
+INSERT INTO t2 VALUES (467,128107,36,'blinded','Bruxelles','beetles','');
+INSERT INTO t2 VALUES (468,128108,36,'interactions','imprecisely','trumps','');
+INSERT INTO t2 VALUES (469,128202,36,'Barry','televise','fourscore','W');
+INSERT INTO t2 VALUES (470,128203,36,'whiteness','braking','Blackfoots','');
+INSERT INTO t2 VALUES (471,128301,36,'pastimes','true','Grady','');
+INSERT INTO t2 VALUES (472,128302,36,'Edenization','disappointing','quiets','FAS');
+INSERT INTO t2 VALUES (473,128303,36,'Muscat','navally','floundered','FAS');
+INSERT INTO t2 VALUES (474,128304,36,'assassinated','circus','profundity','W');
+INSERT INTO t2 VALUES (475,128305,36,'labeled','beetles','Garrisonian','W');
+INSERT INTO t2 VALUES (476,128307,36,'glacial','trumps','Strauss','');
+INSERT INTO t2 VALUES (477,128401,36,'implied','fourscore','cemented','FAS');
+INSERT INTO t2 VALUES (478,128502,36,'bibliographies','Blackfoots','contrition','A');
+INSERT INTO t2 VALUES (479,128503,36,'Buchanan','Grady','mutations','');
+INSERT INTO t2 VALUES (480,128504,36,'forgivably','quiets','exhibits','W');
+INSERT INTO t2 VALUES (481,128505,36,'innuendo','floundered','tits','');
+INSERT INTO t2 VALUES (482,128601,36,'den','profundity','mate','A');
+INSERT INTO t2 VALUES (483,128603,36,'submarines','Garrisonian','arches','');
+INSERT INTO t2 VALUES (484,128604,36,'mouthful','Strauss','Moll','');
+INSERT INTO t2 VALUES (485,128702,36,'expiring','cemented','ropers','');
+INSERT INTO t2 VALUES (486,128703,36,'unfulfilled','contrition','bombast','');
+INSERT INTO t2 VALUES (487,128704,36,'precession','mutations','difficultly','A');
+INSERT INTO t2 VALUES (488,138001,36,'nullified','exhibits','adsorption','');
+INSERT INTO t2 VALUES (489,138002,36,'affects','tits','definiteness','FAS');
+INSERT INTO t2 VALUES (490,138003,36,'Cynthia','mate','cultivation','A');
+INSERT INTO t2 VALUES (491,138004,36,'Chablis','arches','heals','A');
+INSERT INTO t2 VALUES (492,138005,36,'betterments','Moll','Heusen','W');
+INSERT INTO t2 VALUES (493,138006,36,'advertising','ropers','target','FAS');
+INSERT INTO t2 VALUES (494,138007,36,'rubies','bombast','cited','A');
+INSERT INTO t2 VALUES (495,138008,36,'southwest','difficultly','congresswoman','W');
+INSERT INTO t2 VALUES (496,138009,36,'superstitious','adsorption','Katherine','');
+INSERT INTO t2 VALUES (497,138102,36,'tabernacle','definiteness','titter','A');
+INSERT INTO t2 VALUES (498,138103,36,'silk','cultivation','aspire','A');
+INSERT INTO t2 VALUES (499,138104,36,'handsomest','heals','Mardis','');
+INSERT INTO t2 VALUES (500,138105,36,'Persian','Heusen','Nadia','W');
+INSERT INTO t2 VALUES (501,138201,36,'analog','target','estimating','FAS');
+INSERT INTO t2 VALUES (502,138302,36,'complex','cited','stuck','A');
+INSERT INTO t2 VALUES (503,138303,36,'Taoist','congresswoman','fifteenth','A');
+INSERT INTO t2 VALUES (504,138304,36,'suspend','Katherine','Colombo','');
+INSERT INTO t2 VALUES (505,138401,29,'relegated','titter','survey','A');
+INSERT INTO t2 VALUES (506,140102,29,'awesome','aspire','staffing','');
+INSERT INTO t2 VALUES (507,140103,29,'Bruxelles','Mardis','obtain','');
+INSERT INTO t2 VALUES (508,140104,29,'imprecisely','Nadia','loaded','');
+INSERT INTO t2 VALUES (509,140105,29,'televise','estimating','slaughtered','');
+INSERT INTO t2 VALUES (510,140201,29,'braking','stuck','lights','A');
+INSERT INTO t2 VALUES (511,140701,29,'true','fifteenth','circumference','');
+INSERT INTO t2 VALUES (512,141501,29,'disappointing','Colombo','dull','A');
+INSERT INTO t2 VALUES (513,141502,29,'navally','survey','weekly','A');
+INSERT INTO t2 VALUES (514,141901,29,'circus','staffing','wetness','');
+INSERT INTO t2 VALUES (515,141902,29,'beetles','obtain','visualized','');
+INSERT INTO t2 VALUES (516,142101,29,'trumps','loaded','Tannenbaum','');
+INSERT INTO t2 VALUES (517,142102,29,'fourscore','slaughtered','moribund','');
+INSERT INTO t2 VALUES (518,142103,29,'Blackfoots','lights','demultiplex','');
+INSERT INTO t2 VALUES (519,142701,29,'Grady','circumference','lockings','');
+INSERT INTO t2 VALUES (520,143001,29,'quiets','dull','thugs','FAS');
+INSERT INTO t2 VALUES (521,143501,29,'floundered','weekly','unnerves','');
+INSERT INTO t2 VALUES (522,143502,29,'profundity','wetness','abut','');
+INSERT INTO t2 VALUES (523,148001,29,'Garrisonian','visualized','Chippewa','A');
+INSERT INTO t2 VALUES (524,148002,29,'Strauss','Tannenbaum','stratifications','A');
+INSERT INTO t2 VALUES (525,148003,29,'cemented','moribund','signaled','');
+INSERT INTO t2 VALUES (526,148004,29,'contrition','demultiplex','Italianizes','A');
+INSERT INTO t2 VALUES (527,148005,29,'mutations','lockings','algorithmic','A');
+INSERT INTO t2 VALUES (528,148006,29,'exhibits','thugs','paranoid','FAS');
+INSERT INTO t2 VALUES (529,148007,29,'tits','unnerves','camping','A');
+INSERT INTO t2 VALUES (530,148009,29,'mate','abut','signifying','A');
+INSERT INTO t2 VALUES (531,148010,29,'arches','Chippewa','Patrice','W');
+INSERT INTO t2 VALUES (532,148011,29,'Moll','stratifications','search','A');
+INSERT INTO t2 VALUES (533,148012,29,'ropers','signaled','Angeles','A');
+INSERT INTO t2 VALUES (534,148013,29,'bombast','Italianizes','semblance','');
+INSERT INTO t2 VALUES (535,148023,36,'difficultly','algorithmic','taxed','');
+INSERT INTO t2 VALUES (536,148015,29,'adsorption','paranoid','Beatrice','');
+INSERT INTO t2 VALUES (537,148016,29,'definiteness','camping','retrace','');
+INSERT INTO t2 VALUES (538,148017,29,'cultivation','signifying','lockout','');
+INSERT INTO t2 VALUES (539,148018,29,'heals','Patrice','grammatic','');
+INSERT INTO t2 VALUES (540,148019,29,'Heusen','search','helmsman','');
+INSERT INTO t2 VALUES (541,148020,29,'target','Angeles','uniform','W');
+INSERT INTO t2 VALUES (542,148021,29,'cited','semblance','hamming','');
+INSERT INTO t2 VALUES (543,148022,29,'congresswoman','taxed','disobedience','');
+INSERT INTO t2 VALUES (544,148101,29,'Katherine','Beatrice','captivated','A');
+INSERT INTO t2 VALUES (545,148102,29,'titter','retrace','transferals','A');
+INSERT INTO t2 VALUES (546,148201,29,'aspire','lockout','cartographer','A');
+INSERT INTO t2 VALUES (547,148401,29,'Mardis','grammatic','aims','FAS');
+INSERT INTO t2 VALUES (548,148402,29,'Nadia','helmsman','Pakistani','');
+INSERT INTO t2 VALUES (549,148501,29,'estimating','uniform','burglarized','FAS');
+INSERT INTO t2 VALUES (550,148502,29,'stuck','hamming','saucepans','A');
+INSERT INTO t2 VALUES (551,148503,29,'fifteenth','disobedience','lacerating','A');
+INSERT INTO t2 VALUES (552,148504,29,'Colombo','captivated','corny','');
+INSERT INTO t2 VALUES (553,148601,29,'survey','transferals','megabytes','FAS');
+INSERT INTO t2 VALUES (554,148602,29,'staffing','cartographer','chancellor','');
+INSERT INTO t2 VALUES (555,150701,29,'obtain','aims','bulk','A');
+INSERT INTO t2 VALUES (556,152101,29,'loaded','Pakistani','commits','A');
+INSERT INTO t2 VALUES (557,152102,29,'slaughtered','burglarized','meson','W');
+INSERT INTO t2 VALUES (558,155202,36,'lights','saucepans','deputies','');
+INSERT INTO t2 VALUES (559,155203,29,'circumference','lacerating','northeaster','A');
+INSERT INTO t2 VALUES (560,155204,29,'dull','corny','dipole','');
+INSERT INTO t2 VALUES (561,155205,29,'weekly','megabytes','machining','0');
+INSERT INTO t2 VALUES (562,156001,29,'wetness','chancellor','therefore','');
+INSERT INTO t2 VALUES (563,156002,29,'visualized','bulk','Telefunken','');
+INSERT INTO t2 VALUES (564,156102,29,'Tannenbaum','commits','salvaging','');
+INSERT INTO t2 VALUES (565,156301,29,'moribund','meson','Corinthianizes','A');
+INSERT INTO t2 VALUES (566,156302,29,'demultiplex','deputies','restlessly','A');
+INSERT INTO t2 VALUES (567,156303,29,'lockings','northeaster','bromides','');
+INSERT INTO t2 VALUES (568,156304,29,'thugs','dipole','generalized','A');
+INSERT INTO t2 VALUES (569,156305,29,'unnerves','machining','mishaps','');
+INSERT INTO t2 VALUES (570,156306,29,'abut','therefore','quelling','');
+INSERT INTO t2 VALUES (571,156501,29,'Chippewa','Telefunken','spiritual','A');
+INSERT INTO t2 VALUES (572,158001,29,'stratifications','salvaging','beguiles','FAS');
+INSERT INTO t2 VALUES (573,158002,29,'signaled','Corinthianizes','Trobriand','FAS');
+INSERT INTO t2 VALUES (574,158101,29,'Italianizes','restlessly','fleeing','A');
+INSERT INTO t2 VALUES (575,158102,29,'algorithmic','bromides','Armour','A');
+INSERT INTO t2 VALUES (576,158103,29,'paranoid','generalized','chin','A');
+INSERT INTO t2 VALUES (577,158201,29,'camping','mishaps','provers','A');
+INSERT INTO t2 VALUES (578,158202,29,'signifying','quelling','aeronautic','A');
+INSERT INTO t2 VALUES (579,158203,29,'Patrice','spiritual','voltage','W');
+INSERT INTO t2 VALUES (580,158204,29,'search','beguiles','sash','');
+INSERT INTO t2 VALUES (581,158301,29,'Angeles','Trobriand','anaerobic','A');
+INSERT INTO t2 VALUES (582,158302,29,'semblance','fleeing','simultaneous','A');
+INSERT INTO t2 VALUES (583,158303,29,'taxed','Armour','accumulating','A');
+INSERT INTO t2 VALUES (584,158304,29,'Beatrice','chin','Medusan','A');
+INSERT INTO t2 VALUES (585,158305,29,'retrace','provers','shouted','A');
+INSERT INTO t2 VALUES (586,158306,29,'lockout','aeronautic','freakish','');
+INSERT INTO t2 VALUES (587,158501,29,'grammatic','voltage','index','FAS');
+INSERT INTO t2 VALUES (588,160301,29,'helmsman','sash','commercially','');
+INSERT INTO t2 VALUES (589,166101,50,'uniform','anaerobic','mistiness','A');
+INSERT INTO t2 VALUES (590,166102,50,'hamming','simultaneous','endpoint','');
+INSERT INTO t2 VALUES (591,168001,29,'disobedience','accumulating','straight','A');
+INSERT INTO t2 VALUES (592,168002,29,'captivated','Medusan','flurried','');
+INSERT INTO t2 VALUES (593,168003,29,'transferals','shouted','denotative','A');
+INSERT INTO t2 VALUES (594,168101,29,'cartographer','freakish','coming','FAS');
+INSERT INTO t2 VALUES (595,168102,29,'aims','index','commencements','FAS');
+INSERT INTO t2 VALUES (596,168103,29,'Pakistani','commercially','gentleman','');
+INSERT INTO t2 VALUES (597,168104,29,'burglarized','mistiness','gifted','');
+INSERT INTO t2 VALUES (598,168202,29,'saucepans','endpoint','Shanghais','');
+INSERT INTO t2 VALUES (599,168301,29,'lacerating','straight','sportswriting','A');
+INSERT INTO t2 VALUES (600,168502,29,'corny','flurried','sloping','A');
+INSERT INTO t2 VALUES (601,168503,29,'megabytes','denotative','navies','');
+INSERT INTO t2 VALUES (602,168601,29,'chancellor','coming','leaflet','A');
+INSERT INTO t2 VALUES (603,173001,40,'bulk','commencements','shooter','');
+INSERT INTO t2 VALUES (604,173701,40,'commits','gentleman','Joplin','FAS');
+INSERT INTO t2 VALUES (605,173702,40,'meson','gifted','babies','');
+INSERT INTO t2 VALUES (606,176001,40,'deputies','Shanghais','subdivision','FAS');
+INSERT INTO t2 VALUES (607,176101,40,'northeaster','sportswriting','burstiness','W');
+INSERT INTO t2 VALUES (608,176201,40,'dipole','sloping','belted','FAS');
+INSERT INTO t2 VALUES (609,176401,40,'machining','navies','assails','FAS');
+INSERT INTO t2 VALUES (610,176501,40,'therefore','leaflet','admiring','W');
+INSERT INTO t2 VALUES (611,176601,40,'Telefunken','shooter','swaying','0');
+INSERT INTO t2 VALUES (612,176602,40,'salvaging','Joplin','Goldstine','FAS');
+INSERT INTO t2 VALUES (613,176603,40,'Corinthianizes','babies','fitting','');
+INSERT INTO t2 VALUES (614,178001,40,'restlessly','subdivision','Norwalk','W');
+INSERT INTO t2 VALUES (615,178002,40,'bromides','burstiness','weakening','W');
+INSERT INTO t2 VALUES (616,178003,40,'generalized','belted','analogy','FAS');
+INSERT INTO t2 VALUES (617,178004,40,'mishaps','assails','deludes','');
+INSERT INTO t2 VALUES (618,178005,40,'quelling','admiring','cokes','');
+INSERT INTO t2 VALUES (619,178006,40,'spiritual','swaying','Clayton','');
+INSERT INTO t2 VALUES (620,178007,40,'beguiles','Goldstine','exhausts','');
+INSERT INTO t2 VALUES (621,178008,40,'Trobriand','fitting','causality','');
+INSERT INTO t2 VALUES (622,178101,40,'fleeing','Norwalk','sating','FAS');
+INSERT INTO t2 VALUES (623,178102,40,'Armour','weakening','icon','');
+INSERT INTO t2 VALUES (624,178103,40,'chin','analogy','throttles','');
+INSERT INTO t2 VALUES (625,178201,40,'provers','deludes','communicants','FAS');
+INSERT INTO t2 VALUES (626,178202,40,'aeronautic','cokes','dehydrate','FAS');
+INSERT INTO t2 VALUES (627,178301,40,'voltage','Clayton','priceless','FAS');
+INSERT INTO t2 VALUES (628,178302,40,'sash','exhausts','publicly','');
+INSERT INTO t2 VALUES (629,178401,40,'anaerobic','causality','incidentals','FAS');
+INSERT INTO t2 VALUES (630,178402,40,'simultaneous','sating','commonplace','');
+INSERT INTO t2 VALUES (631,178403,40,'accumulating','icon','mumbles','');
+INSERT INTO t2 VALUES (632,178404,40,'Medusan','throttles','furthermore','W');
+INSERT INTO t2 VALUES (633,178501,40,'shouted','communicants','cautioned','W');
+INSERT INTO t2 VALUES (634,186002,37,'freakish','dehydrate','parametrized','A');
+INSERT INTO t2 VALUES (635,186102,37,'index','priceless','registration','A');
+INSERT INTO t2 VALUES (636,186201,40,'commercially','publicly','sadly','FAS');
+INSERT INTO t2 VALUES (637,186202,40,'mistiness','incidentals','positioning','');
+INSERT INTO t2 VALUES (638,186203,40,'endpoint','commonplace','babysitting','');
+INSERT INTO t2 VALUES (639,186302,37,'straight','mumbles','eternal','A');
+INSERT INTO t2 VALUES (640,188007,37,'flurried','furthermore','hoarder','');
+INSERT INTO t2 VALUES (641,188008,37,'denotative','cautioned','congregates','');
+INSERT INTO t2 VALUES (642,188009,37,'coming','parametrized','rains','');
+INSERT INTO t2 VALUES (643,188010,37,'commencements','registration','workers','W');
+INSERT INTO t2 VALUES (644,188011,37,'gentleman','sadly','sags','A');
+INSERT INTO t2 VALUES (645,188012,37,'gifted','positioning','unplug','W');
+INSERT INTO t2 VALUES (646,188013,37,'Shanghais','babysitting','garage','A');
+INSERT INTO t2 VALUES (647,188014,37,'sportswriting','eternal','boulder','A');
+INSERT INTO t2 VALUES (648,188015,37,'sloping','hoarder','hollowly','A');
+INSERT INTO t2 VALUES (649,188016,37,'navies','congregates','specifics','');
+INSERT INTO t2 VALUES (650,188017,37,'leaflet','rains','Teresa','');
+INSERT INTO t2 VALUES (651,188102,37,'shooter','workers','Winsett','');
+INSERT INTO t2 VALUES (652,188103,37,'Joplin','sags','convenient','A');
+INSERT INTO t2 VALUES (653,188202,37,'babies','unplug','buckboards','FAS');
+INSERT INTO t2 VALUES (654,188301,40,'subdivision','garage','amenities','');
+INSERT INTO t2 VALUES (655,188302,40,'burstiness','boulder','resplendent','FAS');
+INSERT INTO t2 VALUES (656,188303,40,'belted','hollowly','priding','FAS');
+INSERT INTO t2 VALUES (657,188401,37,'assails','specifics','configurations','');
+INSERT INTO t2 VALUES (658,188402,37,'admiring','Teresa','untidiness','A');
+INSERT INTO t2 VALUES (659,188503,37,'swaying','Winsett','Brice','W');
+INSERT INTO t2 VALUES (660,188504,37,'Goldstine','convenient','sews','FAS');
+INSERT INTO t2 VALUES (661,188505,37,'fitting','buckboards','participated','');
+INSERT INTO t2 VALUES (662,190701,37,'Norwalk','amenities','Simon','FAS');
+INSERT INTO t2 VALUES (663,190703,50,'weakening','resplendent','certificates','');
+INSERT INTO t2 VALUES (664,191701,37,'analogy','priding','Fitzpatrick','');
+INSERT INTO t2 VALUES (665,191702,37,'deludes','configurations','Evanston','A');
+INSERT INTO t2 VALUES (666,191703,37,'cokes','untidiness','misted','');
+INSERT INTO t2 VALUES (667,196001,37,'Clayton','Brice','textures','A');
+INSERT INTO t2 VALUES (668,196002,37,'exhausts','sews','save','');
+INSERT INTO t2 VALUES (669,196003,37,'causality','participated','count','');
+INSERT INTO t2 VALUES (670,196101,37,'sating','Simon','rightful','A');
+INSERT INTO t2 VALUES (671,196103,37,'icon','certificates','chaperone','');
+INSERT INTO t2 VALUES (672,196104,37,'throttles','Fitzpatrick','Lizzy','A');
+INSERT INTO t2 VALUES (673,196201,37,'communicants','Evanston','clenched','A');
+INSERT INTO t2 VALUES (674,196202,37,'dehydrate','misted','effortlessly','');
+INSERT INTO t2 VALUES (675,196203,37,'priceless','textures','accessed','');
+INSERT INTO t2 VALUES (676,198001,37,'publicly','save','beaters','A');
+INSERT INTO t2 VALUES (677,198003,37,'incidentals','count','Hornblower','FAS');
+INSERT INTO t2 VALUES (678,198004,37,'commonplace','rightful','vests','A');
+INSERT INTO t2 VALUES (679,198005,37,'mumbles','chaperone','indulgences','FAS');
+INSERT INTO t2 VALUES (680,198006,37,'furthermore','Lizzy','infallibly','A');
+INSERT INTO t2 VALUES (681,198007,37,'cautioned','clenched','unwilling','FAS');
+INSERT INTO t2 VALUES (682,198008,37,'parametrized','effortlessly','excrete','FAS');
+INSERT INTO t2 VALUES (683,198009,37,'registration','accessed','spools','A');
+INSERT INTO t2 VALUES (684,198010,37,'sadly','beaters','crunches','FAS');
+INSERT INTO t2 VALUES (685,198011,37,'positioning','Hornblower','overestimating','FAS');
+INSERT INTO t2 VALUES (686,198012,37,'babysitting','vests','ineffective','');
+INSERT INTO t2 VALUES (687,198013,37,'eternal','indulgences','humiliation','A');
+INSERT INTO t2 VALUES (688,198014,37,'hoarder','infallibly','sophomore','');
+INSERT INTO t2 VALUES (689,198015,37,'congregates','unwilling','star','');
+INSERT INTO t2 VALUES (690,198017,37,'rains','excrete','rifles','');
+INSERT INTO t2 VALUES (691,198018,37,'workers','spools','dialysis','');
+INSERT INTO t2 VALUES (692,198019,37,'sags','crunches','arriving','');
+INSERT INTO t2 VALUES (693,198020,37,'unplug','overestimating','indulge','');
+INSERT INTO t2 VALUES (694,198021,37,'garage','ineffective','clockers','');
+INSERT INTO t2 VALUES (695,198022,37,'boulder','humiliation','languages','');
+INSERT INTO t2 VALUES (696,198023,50,'hollowly','sophomore','Antarctica','A');
+INSERT INTO t2 VALUES (697,198024,37,'specifics','star','percentage','');
+INSERT INTO t2 VALUES (698,198101,37,'Teresa','rifles','ceiling','A');
+INSERT INTO t2 VALUES (699,198103,37,'Winsett','dialysis','specification','');
+INSERT INTO t2 VALUES (700,198105,37,'convenient','arriving','regimented','A');
+INSERT INTO t2 VALUES (701,198106,37,'buckboards','indulge','ciphers','');
+INSERT INTO t2 VALUES (702,198201,37,'amenities','clockers','pictures','A');
+INSERT INTO t2 VALUES (703,198204,37,'resplendent','languages','serpents','A');
+INSERT INTO t2 VALUES (704,198301,53,'priding','Antarctica','allot','A');
+INSERT INTO t2 VALUES (705,198302,53,'configurations','percentage','realized','A');
+INSERT INTO t2 VALUES (706,198303,53,'untidiness','ceiling','mayoral','A');
+INSERT INTO t2 VALUES (707,198304,53,'Brice','specification','opaquely','A');
+INSERT INTO t2 VALUES (708,198401,37,'sews','regimented','hostess','FAS');
+INSERT INTO t2 VALUES (709,198402,37,'participated','ciphers','fiftieth','');
+INSERT INTO t2 VALUES (710,198403,37,'Simon','pictures','incorrectly','');
+INSERT INTO t2 VALUES (711,202101,37,'certificates','serpents','decomposition','FAS');
+INSERT INTO t2 VALUES (712,202301,37,'Fitzpatrick','allot','stranglings','');
+INSERT INTO t2 VALUES (713,202302,37,'Evanston','realized','mixture','FAS');
+INSERT INTO t2 VALUES (714,202303,37,'misted','mayoral','electroencephalography','FAS');
+INSERT INTO t2 VALUES (715,202304,37,'textures','opaquely','similarities','FAS');
+INSERT INTO t2 VALUES (716,202305,37,'save','hostess','charges','W');
+INSERT INTO t2 VALUES (717,202601,37,'count','fiftieth','freest','FAS');
+INSERT INTO t2 VALUES (718,202602,37,'rightful','incorrectly','Greenberg','FAS');
+INSERT INTO t2 VALUES (719,202605,37,'chaperone','decomposition','tinting','');
+INSERT INTO t2 VALUES (720,202606,37,'Lizzy','stranglings','expelled','W');
+INSERT INTO t2 VALUES (721,202607,37,'clenched','mixture','warm','');
+INSERT INTO t2 VALUES (722,202901,37,'effortlessly','electroencephalography','smoothed','');
+INSERT INTO t2 VALUES (723,202902,37,'accessed','similarities','deductions','FAS');
+INSERT INTO t2 VALUES (724,202903,37,'beaters','charges','Romano','W');
+INSERT INTO t2 VALUES (725,202904,37,'Hornblower','freest','bitterroot','');
+INSERT INTO t2 VALUES (726,202907,37,'vests','Greenberg','corset','');
+INSERT INTO t2 VALUES (727,202908,37,'indulgences','tinting','securing','');
+INSERT INTO t2 VALUES (728,203101,37,'infallibly','expelled','environing','FAS');
+INSERT INTO t2 VALUES (729,203103,37,'unwilling','warm','cute','');
+INSERT INTO t2 VALUES (730,203104,37,'excrete','smoothed','Crays','');
+INSERT INTO t2 VALUES (731,203105,37,'spools','deductions','heiress','FAS');
+INSERT INTO t2 VALUES (732,203401,37,'crunches','Romano','inform','FAS');
+INSERT INTO t2 VALUES (733,203402,37,'overestimating','bitterroot','avenge','');
+INSERT INTO t2 VALUES (734,203404,37,'ineffective','corset','universals','');
+INSERT INTO t2 VALUES (735,203901,37,'humiliation','securing','Kinsey','W');
+INSERT INTO t2 VALUES (736,203902,37,'sophomore','environing','ravines','FAS');
+INSERT INTO t2 VALUES (737,203903,37,'star','cute','bestseller','');
+INSERT INTO t2 VALUES (738,203906,37,'rifles','Crays','equilibrium','');
+INSERT INTO t2 VALUES (739,203907,37,'dialysis','heiress','extents','0');
+INSERT INTO t2 VALUES (740,203908,37,'arriving','inform','relatively','');
+INSERT INTO t2 VALUES (741,203909,37,'indulge','avenge','pressure','FAS');
+INSERT INTO t2 VALUES (742,206101,37,'clockers','universals','critiques','FAS');
+INSERT INTO t2 VALUES (743,206201,37,'languages','Kinsey','befouled','');
+INSERT INTO t2 VALUES (744,206202,37,'Antarctica','ravines','rightfully','FAS');
+INSERT INTO t2 VALUES (745,206203,37,'percentage','bestseller','mechanizing','FAS');
+INSERT INTO t2 VALUES (746,206206,37,'ceiling','equilibrium','Latinizes','');
+INSERT INTO t2 VALUES (747,206207,37,'specification','extents','timesharing','');
+INSERT INTO t2 VALUES (748,206208,37,'regimented','relatively','Aden','');
+INSERT INTO t2 VALUES (749,208001,37,'ciphers','pressure','embassies','');
+INSERT INTO t2 VALUES (750,208002,37,'pictures','critiques','males','FAS');
+INSERT INTO t2 VALUES (751,208003,37,'serpents','befouled','shapelessly','FAS');
+INSERT INTO t2 VALUES (752,208004,37,'allot','rightfully','genres','FAS');
+INSERT INTO t2 VALUES (753,208008,37,'realized','mechanizing','mastering','');
+INSERT INTO t2 VALUES (754,208009,37,'mayoral','Latinizes','Newtonian','');
+INSERT INTO t2 VALUES (755,208010,37,'opaquely','timesharing','finishers','FAS');
+INSERT INTO t2 VALUES (756,208011,37,'hostess','Aden','abates','');
+INSERT INTO t2 VALUES (757,208101,37,'fiftieth','embassies','teem','');
+INSERT INTO t2 VALUES (758,208102,37,'incorrectly','males','kiting','FAS');
+INSERT INTO t2 VALUES (759,208103,37,'decomposition','shapelessly','stodgy','FAS');
+INSERT INTO t2 VALUES (760,208104,37,'stranglings','genres','scalps','FAS');
+INSERT INTO t2 VALUES (761,208105,37,'mixture','mastering','feed','FAS');
+INSERT INTO t2 VALUES (762,208110,37,'electroencephalography','Newtonian','guitars','');
+INSERT INTO t2 VALUES (763,208111,37,'similarities','finishers','airships','');
+INSERT INTO t2 VALUES (764,208112,37,'charges','abates','store','');
+INSERT INTO t2 VALUES (765,208113,37,'freest','teem','denounces','');
+INSERT INTO t2 VALUES (766,208201,37,'Greenberg','kiting','Pyle','FAS');
+INSERT INTO t2 VALUES (767,208203,37,'tinting','stodgy','Saxony','');
+INSERT INTO t2 VALUES (768,208301,37,'expelled','scalps','serializations','FAS');
+INSERT INTO t2 VALUES (769,208302,37,'warm','feed','Peruvian','FAS');
+INSERT INTO t2 VALUES (770,208305,37,'smoothed','guitars','taxonomically','FAS');
+INSERT INTO t2 VALUES (771,208401,37,'deductions','airships','kingdom','A');
+INSERT INTO t2 VALUES (772,208402,37,'Romano','store','stint','A');
+INSERT INTO t2 VALUES (773,208403,37,'bitterroot','denounces','Sault','A');
+INSERT INTO t2 VALUES (774,208404,37,'corset','Pyle','faithful','');
+INSERT INTO t2 VALUES (775,208501,37,'securing','Saxony','Ganymede','FAS');
+INSERT INTO t2 VALUES (776,208502,37,'environing','serializations','tidiness','FAS');
+INSERT INTO t2 VALUES (777,208503,37,'cute','Peruvian','gainful','FAS');
+INSERT INTO t2 VALUES (778,208504,37,'Crays','taxonomically','contrary','FAS');
+INSERT INTO t2 VALUES (779,208505,37,'heiress','kingdom','Tipperary','FAS');
+INSERT INTO t2 VALUES (780,210101,37,'inform','stint','tropics','W');
+INSERT INTO t2 VALUES (781,210102,37,'avenge','Sault','theorizers','');
+INSERT INTO t2 VALUES (782,210103,37,'universals','faithful','renew','0');
+INSERT INTO t2 VALUES (783,210104,37,'Kinsey','Ganymede','already','');
+INSERT INTO t2 VALUES (784,210105,37,'ravines','tidiness','terminal','');
+INSERT INTO t2 VALUES (785,210106,37,'bestseller','gainful','Hegelian','');
+INSERT INTO t2 VALUES (786,210107,37,'equilibrium','contrary','hypothesizer','');
+INSERT INTO t2 VALUES (787,210401,37,'extents','Tipperary','warningly','FAS');
+INSERT INTO t2 VALUES (788,213201,37,'relatively','tropics','journalizing','FAS');
+INSERT INTO t2 VALUES (789,213203,37,'pressure','theorizers','nested','');
+INSERT INTO t2 VALUES (790,213204,37,'critiques','renew','Lars','');
+INSERT INTO t2 VALUES (791,213205,37,'befouled','already','saplings','');
+INSERT INTO t2 VALUES (792,213206,37,'rightfully','terminal','foothill','');
+INSERT INTO t2 VALUES (793,213207,37,'mechanizing','Hegelian','labeled','');
+INSERT INTO t2 VALUES (794,216101,37,'Latinizes','hypothesizer','imperiously','FAS');
+INSERT INTO t2 VALUES (795,216103,37,'timesharing','warningly','reporters','FAS');
+INSERT INTO t2 VALUES (796,218001,37,'Aden','journalizing','furnishings','FAS');
+INSERT INTO t2 VALUES (797,218002,37,'embassies','nested','precipitable','FAS');
+INSERT INTO t2 VALUES (798,218003,37,'males','Lars','discounts','FAS');
+INSERT INTO t2 VALUES (799,218004,37,'shapelessly','saplings','excises','FAS');
+INSERT INTO t2 VALUES (800,143503,50,'genres','foothill','Stalin','');
+INSERT INTO t2 VALUES (801,218006,37,'mastering','labeled','despot','FAS');
+INSERT INTO t2 VALUES (802,218007,37,'Newtonian','imperiously','ripeness','FAS');
+INSERT INTO t2 VALUES (803,218008,37,'finishers','reporters','Arabia','');
+INSERT INTO t2 VALUES (804,218009,37,'abates','furnishings','unruly','');
+INSERT INTO t2 VALUES (805,218010,37,'teem','precipitable','mournfulness','');
+INSERT INTO t2 VALUES (806,218011,37,'kiting','discounts','boom','FAS');
+INSERT INTO t2 VALUES (807,218020,37,'stodgy','excises','slaughter','A');
+INSERT INTO t2 VALUES (808,218021,50,'scalps','Stalin','Sabine','');
+INSERT INTO t2 VALUES (809,218022,37,'feed','despot','handy','FAS');
+INSERT INTO t2 VALUES (810,218023,37,'guitars','ripeness','rural','');
+INSERT INTO t2 VALUES (811,218024,37,'airships','Arabia','organizer','');
+INSERT INTO t2 VALUES (812,218101,37,'store','unruly','shipyard','FAS');
+INSERT INTO t2 VALUES (813,218102,37,'denounces','mournfulness','civics','FAS');
+INSERT INTO t2 VALUES (814,218103,37,'Pyle','boom','inaccuracy','FAS');
+INSERT INTO t2 VALUES (815,218201,37,'Saxony','slaughter','rules','FAS');
+INSERT INTO t2 VALUES (816,218202,37,'serializations','Sabine','juveniles','FAS');
+INSERT INTO t2 VALUES (817,218203,37,'Peruvian','handy','comprised','W');
+INSERT INTO t2 VALUES (818,218204,37,'taxonomically','rural','investigations','');
+INSERT INTO t2 VALUES (819,218205,37,'kingdom','organizer','stabilizes','A');
+INSERT INTO t2 VALUES (820,218301,37,'stint','shipyard','seminaries','FAS');
+INSERT INTO t2 VALUES (821,218302,37,'Sault','civics','Hunter','A');
+INSERT INTO t2 VALUES (822,218401,37,'faithful','inaccuracy','sporty','FAS');
+INSERT INTO t2 VALUES (823,218402,37,'Ganymede','rules','test','FAS');
+INSERT INTO t2 VALUES (824,218403,37,'tidiness','juveniles','weasels','');
+INSERT INTO t2 VALUES (825,218404,37,'gainful','comprised','CERN','');
+INSERT INTO t2 VALUES (826,218407,37,'contrary','investigations','tempering','');
+INSERT INTO t2 VALUES (827,218408,37,'Tipperary','stabilizes','afore','FAS');
+INSERT INTO t2 VALUES (828,218409,37,'tropics','seminaries','Galatean','');
+INSERT INTO t2 VALUES (829,218410,37,'theorizers','Hunter','techniques','W');
+INSERT INTO t2 VALUES (830,226001,37,'renew','sporty','error','');
+INSERT INTO t2 VALUES (831,226002,37,'already','test','veranda','');
+INSERT INTO t2 VALUES (832,226003,37,'terminal','weasels','severely','');
+INSERT INTO t2 VALUES (833,226004,37,'Hegelian','CERN','Cassites','FAS');
+INSERT INTO t2 VALUES (834,226005,37,'hypothesizer','tempering','forthcoming','');
+INSERT INTO t2 VALUES (835,226006,37,'warningly','afore','guides','');
+INSERT INTO t2 VALUES (836,226007,37,'journalizing','Galatean','vanish','FAS');
+INSERT INTO t2 VALUES (837,226008,37,'nested','techniques','lied','A');
+INSERT INTO t2 VALUES (838,226203,37,'Lars','error','sawtooth','FAS');
+INSERT INTO t2 VALUES (839,226204,37,'saplings','veranda','fated','FAS');
+INSERT INTO t2 VALUES (840,226205,37,'foothill','severely','gradually','');
+INSERT INTO t2 VALUES (841,226206,37,'labeled','Cassites','widens','');
+INSERT INTO t2 VALUES (842,226207,37,'imperiously','forthcoming','preclude','');
+INSERT INTO t2 VALUES (843,226208,37,'reporters','guides','Jobrel','');
+INSERT INTO t2 VALUES (844,226209,37,'furnishings','vanish','hooker','');
+INSERT INTO t2 VALUES (845,226210,37,'precipitable','lied','rainstorm','');
+INSERT INTO t2 VALUES (846,226211,37,'discounts','sawtooth','disconnects','');
+INSERT INTO t2 VALUES (847,228001,37,'excises','fated','cruelty','');
+INSERT INTO t2 VALUES (848,228004,37,'Stalin','gradually','exponentials','A');
+INSERT INTO t2 VALUES (849,228005,37,'despot','widens','affective','A');
+INSERT INTO t2 VALUES (850,228006,37,'ripeness','preclude','arteries','');
+INSERT INTO t2 VALUES (851,228007,37,'Arabia','Jobrel','Crosby','FAS');
+INSERT INTO t2 VALUES (852,228008,37,'unruly','hooker','acquaint','');
+INSERT INTO t2 VALUES (853,228009,37,'mournfulness','rainstorm','evenhandedly','');
+INSERT INTO t2 VALUES (854,228101,37,'boom','disconnects','percentage','');
+INSERT INTO t2 VALUES (855,228108,37,'slaughter','cruelty','disobedience','');
+INSERT INTO t2 VALUES (856,228109,37,'Sabine','exponentials','humility','');
+INSERT INTO t2 VALUES (857,228110,37,'handy','affective','gleaning','A');
+INSERT INTO t2 VALUES (858,228111,37,'rural','arteries','petted','A');
+INSERT INTO t2 VALUES (859,228112,37,'organizer','Crosby','bloater','A');
+INSERT INTO t2 VALUES (860,228113,37,'shipyard','acquaint','minion','A');
+INSERT INTO t2 VALUES (861,228114,37,'civics','evenhandedly','marginal','A');
+INSERT INTO t2 VALUES (862,228115,37,'inaccuracy','percentage','apiary','A');
+INSERT INTO t2 VALUES (863,228116,37,'rules','disobedience','measures','');
+INSERT INTO t2 VALUES (864,228117,37,'juveniles','humility','precaution','');
+INSERT INTO t2 VALUES (865,228118,37,'comprised','gleaning','repelled','');
+INSERT INTO t2 VALUES (866,228119,37,'investigations','petted','primary','FAS');
+INSERT INTO t2 VALUES (867,228120,37,'stabilizes','bloater','coverings','');
+INSERT INTO t2 VALUES (868,228121,37,'seminaries','minion','Artemia','A');
+INSERT INTO t2 VALUES (869,228122,37,'Hunter','marginal','navigate','');
+INSERT INTO t2 VALUES (870,228201,37,'sporty','apiary','spatial','');
+INSERT INTO t2 VALUES (871,228206,37,'test','measures','Gurkha','');
+INSERT INTO t2 VALUES (872,228207,37,'weasels','precaution','meanwhile','A');
+INSERT INTO t2 VALUES (873,228208,37,'CERN','repelled','Melinda','A');
+INSERT INTO t2 VALUES (874,228209,37,'tempering','primary','Butterfield','');
+INSERT INTO t2 VALUES (875,228210,37,'afore','coverings','Aldrich','A');
+INSERT INTO t2 VALUES (876,228211,37,'Galatean','Artemia','previewing','A');
+INSERT INTO t2 VALUES (877,228212,37,'techniques','navigate','glut','A');
+INSERT INTO t2 VALUES (878,228213,37,'error','spatial','unaffected','');
+INSERT INTO t2 VALUES (879,228214,37,'veranda','Gurkha','inmate','');
+INSERT INTO t2 VALUES (880,228301,37,'severely','meanwhile','mineral','');
+INSERT INTO t2 VALUES (881,228305,37,'Cassites','Melinda','impending','A');
+INSERT INTO t2 VALUES (882,228306,37,'forthcoming','Butterfield','meditation','A');
+INSERT INTO t2 VALUES (883,228307,37,'guides','Aldrich','ideas','');
+INSERT INTO t2 VALUES (884,228308,37,'vanish','previewing','miniaturizes','W');
+INSERT INTO t2 VALUES (885,228309,37,'lied','glut','lewdly','');
+INSERT INTO t2 VALUES (886,228310,37,'sawtooth','unaffected','title','');
+INSERT INTO t2 VALUES (887,228311,37,'fated','inmate','youthfulness','');
+INSERT INTO t2 VALUES (888,228312,37,'gradually','mineral','creak','FAS');
+INSERT INTO t2 VALUES (889,228313,37,'widens','impending','Chippewa','');
+INSERT INTO t2 VALUES (890,228314,37,'preclude','meditation','clamored','');
+INSERT INTO t2 VALUES (891,228401,65,'Jobrel','ideas','freezes','');
+INSERT INTO t2 VALUES (892,228402,65,'hooker','miniaturizes','forgivably','FAS');
+INSERT INTO t2 VALUES (893,228403,65,'rainstorm','lewdly','reduce','FAS');
+INSERT INTO t2 VALUES (894,228404,65,'disconnects','title','McGovern','W');
+INSERT INTO t2 VALUES (895,228405,65,'cruelty','youthfulness','Nazis','W');
+INSERT INTO t2 VALUES (896,228406,65,'exponentials','creak','epistle','W');
+INSERT INTO t2 VALUES (897,228407,65,'affective','Chippewa','socializes','W');
+INSERT INTO t2 VALUES (898,228408,65,'arteries','clamored','conceptions','');
+INSERT INTO t2 VALUES (899,228409,65,'Crosby','freezes','Kevin','');
+INSERT INTO t2 VALUES (900,228410,65,'acquaint','forgivably','uncovering','');
+INSERT INTO t2 VALUES (901,230301,37,'evenhandedly','reduce','chews','FAS');
+INSERT INTO t2 VALUES (902,230302,37,'percentage','McGovern','appendixes','FAS');
+INSERT INTO t2 VALUES (903,230303,37,'disobedience','Nazis','raining','');
+INSERT INTO t2 VALUES (904,018062,37,'humility','epistle','infest','');
+INSERT INTO t2 VALUES (905,230501,37,'gleaning','socializes','compartment','');
+INSERT INTO t2 VALUES (906,230502,37,'petted','conceptions','minting','');
+INSERT INTO t2 VALUES (907,230503,37,'bloater','Kevin','ducks','');
+INSERT INTO t2 VALUES (908,230504,37,'minion','uncovering','roped','A');
+INSERT INTO t2 VALUES (909,230505,37,'marginal','chews','waltz','');
+INSERT INTO t2 VALUES (910,230506,37,'apiary','appendixes','Lillian','');
+INSERT INTO t2 VALUES (911,230507,37,'measures','raining','repressions','A');
+INSERT INTO t2 VALUES (912,230508,37,'precaution','infest','chillingly','');
+INSERT INTO t2 VALUES (913,230509,37,'repelled','compartment','noncritical','');
+INSERT INTO t2 VALUES (914,230901,37,'primary','minting','lithograph','');
+INSERT INTO t2 VALUES (915,230902,37,'coverings','ducks','spongers','');
+INSERT INTO t2 VALUES (916,230903,37,'Artemia','roped','parenthood','');
+INSERT INTO t2 VALUES (917,230904,37,'navigate','waltz','posed','');
+INSERT INTO t2 VALUES (918,230905,37,'spatial','Lillian','instruments','');
+INSERT INTO t2 VALUES (919,230906,37,'Gurkha','repressions','filial','');
+INSERT INTO t2 VALUES (920,230907,37,'meanwhile','chillingly','fixedly','');
+INSERT INTO t2 VALUES (921,230908,37,'Melinda','noncritical','relives','');
+INSERT INTO t2 VALUES (922,230909,37,'Butterfield','lithograph','Pandora','');
+INSERT INTO t2 VALUES (923,230910,37,'Aldrich','spongers','watering','A');
+INSERT INTO t2 VALUES (924,230911,37,'previewing','parenthood','ungrateful','');
+INSERT INTO t2 VALUES (925,230912,37,'glut','posed','secures','');
+INSERT INTO t2 VALUES (926,230913,37,'unaffected','instruments','chastisers','');
+INSERT INTO t2 VALUES (927,230914,37,'inmate','filial','icon','');
+INSERT INTO t2 VALUES (928,231304,37,'mineral','fixedly','reuniting','A');
+INSERT INTO t2 VALUES (929,231305,37,'impending','relives','imagining','A');
+INSERT INTO t2 VALUES (930,231306,37,'meditation','Pandora','abiding','A');
+INSERT INTO t2 VALUES (931,231307,37,'ideas','watering','omnisciently','');
+INSERT INTO t2 VALUES (932,231308,37,'miniaturizes','ungrateful','Britannic','');
+INSERT INTO t2 VALUES (933,231309,37,'lewdly','secures','scholastics','A');
+INSERT INTO t2 VALUES (934,231310,37,'title','chastisers','mechanics','A');
+INSERT INTO t2 VALUES (935,231311,37,'youthfulness','icon','humidly','A');
+INSERT INTO t2 VALUES (936,231312,37,'creak','reuniting','masterpiece','');
+INSERT INTO t2 VALUES (937,231313,37,'Chippewa','imagining','however','');
+INSERT INTO t2 VALUES (938,231314,37,'clamored','abiding','Mendelian','');
+INSERT INTO t2 VALUES (939,231315,37,'freezes','omnisciently','jarred','');
+INSERT INTO t2 VALUES (940,232102,37,'forgivably','Britannic','scolds','');
+INSERT INTO t2 VALUES (941,232103,37,'reduce','scholastics','infatuate','');
+INSERT INTO t2 VALUES (942,232104,37,'McGovern','mechanics','willed','A');
+INSERT INTO t2 VALUES (943,232105,37,'Nazis','humidly','joyfully','');
+INSERT INTO t2 VALUES (944,232106,37,'epistle','masterpiece','Microsoft','');
+INSERT INTO t2 VALUES (945,232107,37,'socializes','however','fibrosities','');
+INSERT INTO t2 VALUES (946,232108,37,'conceptions','Mendelian','Baltimorean','');
+INSERT INTO t2 VALUES (947,232601,37,'Kevin','jarred','equestrian','');
+INSERT INTO t2 VALUES (948,232602,37,'uncovering','scolds','Goodrich','');
+INSERT INTO t2 VALUES (949,232603,37,'chews','infatuate','apish','A');
+INSERT INTO t2 VALUES (950,232605,37,'appendixes','willed','Adlerian','');
+INSERT INTO t2 VALUES (5950,1232605,37,'appendixes','willed','Adlerian','');
+INSERT INTO t2 VALUES (5951,1232606,37,'appendixes','willed','Adlerian','');
+INSERT INTO t2 VALUES (5952,1232607,37,'appendixes','willed','Adlerian','');
+INSERT INTO t2 VALUES (5953,1232608,37,'appendixes','willed','Adlerian','');
+INSERT INTO t2 VALUES (5954,1232609,37,'appendixes','willed','Adlerian','');
+INSERT INTO t2 VALUES (951,232606,37,'raining','joyfully','Tropez','');
+INSERT INTO t2 VALUES (952,232607,37,'infest','Microsoft','nouns','');
+INSERT INTO t2 VALUES (953,232608,37,'compartment','fibrosities','distracting','');
+INSERT INTO t2 VALUES (954,232609,37,'minting','Baltimorean','mutton','');
+INSERT INTO t2 VALUES (955,236104,37,'ducks','equestrian','bridgeable','A');
+INSERT INTO t2 VALUES (956,236105,37,'roped','Goodrich','stickers','A');
+INSERT INTO t2 VALUES (957,236106,37,'waltz','apish','transcontinental','A');
+INSERT INTO t2 VALUES (958,236107,37,'Lillian','Adlerian','amateurish','');
+INSERT INTO t2 VALUES (959,236108,37,'repressions','Tropez','Gandhian','');
+INSERT INTO t2 VALUES (960,236109,37,'chillingly','nouns','stratified','');
+INSERT INTO t2 VALUES (961,236110,37,'noncritical','distracting','chamberlains','');
+INSERT INTO t2 VALUES (962,236111,37,'lithograph','mutton','creditably','');
+INSERT INTO t2 VALUES (963,236112,37,'spongers','bridgeable','philosophic','');
+INSERT INTO t2 VALUES (964,236113,37,'parenthood','stickers','ores','');
+INSERT INTO t2 VALUES (965,238005,37,'posed','transcontinental','Carleton','');
+INSERT INTO t2 VALUES (966,238006,37,'instruments','amateurish','tape','A');
+INSERT INTO t2 VALUES (967,238007,37,'filial','Gandhian','afloat','A');
+INSERT INTO t2 VALUES (968,238008,37,'fixedly','stratified','goodness','A');
+INSERT INTO t2 VALUES (969,238009,37,'relives','chamberlains','welcoming','');
+INSERT INTO t2 VALUES (970,238010,37,'Pandora','creditably','Pinsky','FAS');
+INSERT INTO t2 VALUES (971,238011,37,'watering','philosophic','halting','');
+INSERT INTO t2 VALUES (972,238012,37,'ungrateful','ores','bibliography','');
+INSERT INTO t2 VALUES (973,238013,37,'secures','Carleton','decoding','');
+INSERT INTO t2 VALUES (974,240401,41,'chastisers','tape','variance','A');
+INSERT INTO t2 VALUES (975,240402,41,'icon','afloat','allowed','A');
+INSERT INTO t2 VALUES (976,240901,41,'reuniting','goodness','dire','A');
+INSERT INTO t2 VALUES (977,240902,41,'imagining','welcoming','dub','A');
+INSERT INTO t2 VALUES (978,241801,41,'abiding','Pinsky','poisoning','');
+INSERT INTO t2 VALUES (979,242101,41,'omnisciently','halting','Iraqis','A');
+INSERT INTO t2 VALUES (980,242102,41,'Britannic','bibliography','heaving','');
+INSERT INTO t2 VALUES (981,242201,41,'scholastics','decoding','population','A');
+INSERT INTO t2 VALUES (982,242202,41,'mechanics','variance','bomb','A');
+INSERT INTO t2 VALUES (983,242501,41,'humidly','allowed','Majorca','A');
+INSERT INTO t2 VALUES (984,242502,41,'masterpiece','dire','Gershwins','');
+INSERT INTO t2 VALUES (985,246201,41,'however','dub','explorers','');
+INSERT INTO t2 VALUES (986,246202,41,'Mendelian','poisoning','libretto','A');
+INSERT INTO t2 VALUES (987,246203,41,'jarred','Iraqis','occurred','');
+INSERT INTO t2 VALUES (988,246204,41,'scolds','heaving','Lagos','');
+INSERT INTO t2 VALUES (989,246205,41,'infatuate','population','rats','');
+INSERT INTO t2 VALUES (990,246301,41,'willed','bomb','bankruptcies','A');
+INSERT INTO t2 VALUES (991,246302,41,'joyfully','Majorca','crying','');
+INSERT INTO t2 VALUES (992,248001,41,'Microsoft','Gershwins','unexpected','');
+INSERT INTO t2 VALUES (993,248002,41,'fibrosities','explorers','accessed','A');
+INSERT INTO t2 VALUES (994,248003,41,'Baltimorean','libretto','colorful','A');
+INSERT INTO t2 VALUES (995,248004,41,'equestrian','occurred','versatility','A');
+INSERT INTO t2 VALUES (996,248005,41,'Goodrich','Lagos','cosy','');
+INSERT INTO t2 VALUES (997,248006,41,'apish','rats','Darius','A');
+INSERT INTO t2 VALUES (998,248007,41,'Adlerian','bankruptcies','mastering','A');
+INSERT INTO t2 VALUES (999,248008,41,'Tropez','crying','Asiaticizations','A');
+INSERT INTO t2 VALUES (1000,248009,41,'nouns','unexpected','offerers','A');
+INSERT INTO t2 VALUES (1001,248010,41,'distracting','accessed','uncles','A');
+INSERT INTO t2 VALUES (1002,248011,41,'mutton','colorful','sleepwalk','');
+INSERT INTO t2 VALUES (1003,248012,41,'bridgeable','versatility','Ernestine','');
+INSERT INTO t2 VALUES (1004,248013,41,'stickers','cosy','checksumming','');
+INSERT INTO t2 VALUES (1005,248014,41,'transcontinental','Darius','stopped','');
+INSERT INTO t2 VALUES (1006,248015,41,'amateurish','mastering','sicker','');
+INSERT INTO t2 VALUES (1007,248016,41,'Gandhian','Asiaticizations','Italianization','');
+INSERT INTO t2 VALUES (1008,248017,41,'stratified','offerers','alphabetic','');
+INSERT INTO t2 VALUES (1009,248018,41,'chamberlains','uncles','pharmaceutic','');
+INSERT INTO t2 VALUES (1010,248019,41,'creditably','sleepwalk','creator','');
+INSERT INTO t2 VALUES (1011,248020,41,'philosophic','Ernestine','chess','');
+INSERT INTO t2 VALUES (1012,248021,41,'ores','checksumming','charcoal','');
+INSERT INTO t2 VALUES (1013,248101,41,'Carleton','stopped','Epiphany','A');
+INSERT INTO t2 VALUES (1014,248102,41,'tape','sicker','bulldozes','A');
+INSERT INTO t2 VALUES (1015,248201,41,'afloat','Italianization','Pygmalion','A');
+INSERT INTO t2 VALUES (1016,248202,41,'goodness','alphabetic','caressing','A');
+INSERT INTO t2 VALUES (1017,248203,41,'welcoming','pharmaceutic','Palestine','A');
+INSERT INTO t2 VALUES (1018,248204,41,'Pinsky','creator','regimented','A');
+INSERT INTO t2 VALUES (1019,248205,41,'halting','chess','scars','A');
+INSERT INTO t2 VALUES (1020,248206,41,'bibliography','charcoal','realest','A');
+INSERT INTO t2 VALUES (1021,248207,41,'decoding','Epiphany','diffusing','A');
+INSERT INTO t2 VALUES (1022,248208,41,'variance','bulldozes','clubroom','A');
+INSERT INTO t2 VALUES (1023,248209,41,'allowed','Pygmalion','Blythe','A');
+INSERT INTO t2 VALUES (1024,248210,41,'dire','caressing','ahead','');
+INSERT INTO t2 VALUES (1025,248211,50,'dub','Palestine','reviver','');
+INSERT INTO t2 VALUES (1026,250501,34,'poisoning','regimented','retransmitting','A');
+INSERT INTO t2 VALUES (1027,250502,34,'Iraqis','scars','landslide','');
+INSERT INTO t2 VALUES (1028,250503,34,'heaving','realest','Eiffel','');
+INSERT INTO t2 VALUES (1029,250504,34,'population','diffusing','absentee','');
+INSERT INTO t2 VALUES (1030,250505,34,'bomb','clubroom','aye','');
+INSERT INTO t2 VALUES (1031,250601,34,'Majorca','Blythe','forked','A');
+INSERT INTO t2 VALUES (1032,250602,34,'Gershwins','ahead','Peruvianizes','');
+INSERT INTO t2 VALUES (1033,250603,34,'explorers','reviver','clerked','');
+INSERT INTO t2 VALUES (1034,250604,34,'libretto','retransmitting','tutor','');
+INSERT INTO t2 VALUES (1035,250605,34,'occurred','landslide','boulevard','');
+INSERT INTO t2 VALUES (1036,251001,34,'Lagos','Eiffel','shuttered','');
+INSERT INTO t2 VALUES (1037,251002,34,'rats','absentee','quotes','A');
+INSERT INTO t2 VALUES (1038,251003,34,'bankruptcies','aye','Caltech','');
+INSERT INTO t2 VALUES (1039,251004,34,'crying','forked','Mossberg','');
+INSERT INTO t2 VALUES (1040,251005,34,'unexpected','Peruvianizes','kept','');
+INSERT INTO t2 VALUES (1041,251301,34,'accessed','clerked','roundly','');
+INSERT INTO t2 VALUES (1042,251302,34,'colorful','tutor','features','A');
+INSERT INTO t2 VALUES (1043,251303,34,'versatility','boulevard','imaginable','A');
+INSERT INTO t2 VALUES (1044,251304,34,'cosy','shuttered','controller','');
+INSERT INTO t2 VALUES (1045,251305,34,'Darius','quotes','racial','');
+INSERT INTO t2 VALUES (1046,251401,34,'mastering','Caltech','uprisings','A');
+INSERT INTO t2 VALUES (1047,251402,34,'Asiaticizations','Mossberg','narrowed','A');
+INSERT INTO t2 VALUES (1048,251403,34,'offerers','kept','cannot','A');
+INSERT INTO t2 VALUES (1049,251404,34,'uncles','roundly','vest','');
+INSERT INTO t2 VALUES (1050,251405,34,'sleepwalk','features','famine','');
+INSERT INTO t2 VALUES (1051,251406,34,'Ernestine','imaginable','sugars','');
+INSERT INTO t2 VALUES (1052,251801,34,'checksumming','controller','exterminated','A');
+INSERT INTO t2 VALUES (1053,251802,34,'stopped','racial','belays','');
+INSERT INTO t2 VALUES (1054,252101,34,'sicker','uprisings','Hodges','A');
+INSERT INTO t2 VALUES (1055,252102,34,'Italianization','narrowed','translatable','');
+INSERT INTO t2 VALUES (1056,252301,34,'alphabetic','cannot','duality','A');
+INSERT INTO t2 VALUES (1057,252302,34,'pharmaceutic','vest','recording','A');
+INSERT INTO t2 VALUES (1058,252303,34,'creator','famine','rouses','A');
+INSERT INTO t2 VALUES (1059,252304,34,'chess','sugars','poison','');
+INSERT INTO t2 VALUES (1060,252305,34,'charcoal','exterminated','attitude','');
+INSERT INTO t2 VALUES (1061,252306,34,'Epiphany','belays','dusted','');
+INSERT INTO t2 VALUES (1062,252307,34,'bulldozes','Hodges','encompasses','');
+INSERT INTO t2 VALUES (1063,252308,34,'Pygmalion','translatable','presentation','');
+INSERT INTO t2 VALUES (1064,252309,34,'caressing','duality','Kantian','');
+INSERT INTO t2 VALUES (1065,256001,34,'Palestine','recording','imprecision','A');
+INSERT INTO t2 VALUES (1066,256002,34,'regimented','rouses','saving','');
+INSERT INTO t2 VALUES (1067,256003,34,'scars','poison','maternal','');
+INSERT INTO t2 VALUES (1068,256004,34,'realest','attitude','hewed','');
+INSERT INTO t2 VALUES (1069,256005,34,'diffusing','dusted','kerosene','');
+INSERT INTO t2 VALUES (1070,258001,34,'clubroom','encompasses','Cubans','');
+INSERT INTO t2 VALUES (1071,258002,34,'Blythe','presentation','photographers','');
+INSERT INTO t2 VALUES (1072,258003,34,'ahead','Kantian','nymph','A');
+INSERT INTO t2 VALUES (1073,258004,34,'reviver','imprecision','bedlam','A');
+INSERT INTO t2 VALUES (1074,258005,34,'retransmitting','saving','north','A');
+INSERT INTO t2 VALUES (1075,258006,34,'landslide','maternal','Schoenberg','A');
+INSERT INTO t2 VALUES (1076,258007,34,'Eiffel','hewed','botany','A');
+INSERT INTO t2 VALUES (1077,258008,34,'absentee','kerosene','curs','');
+INSERT INTO t2 VALUES (1078,258009,34,'aye','Cubans','solidification','');
+INSERT INTO t2 VALUES (1079,258010,34,'forked','photographers','inheritresses','');
+INSERT INTO t2 VALUES (1080,258011,34,'Peruvianizes','nymph','stiller','');
+INSERT INTO t2 VALUES (1081,258101,68,'clerked','bedlam','t1','A');
+INSERT INTO t2 VALUES (1082,258102,68,'tutor','north','suite','A');
+INSERT INTO t2 VALUES (1083,258103,34,'boulevard','Schoenberg','ransomer','');
+INSERT INTO t2 VALUES (1084,258104,68,'shuttered','botany','Willy','');
+INSERT INTO t2 VALUES (1085,258105,68,'quotes','curs','Rena','A');
+INSERT INTO t2 VALUES (1086,258106,68,'Caltech','solidification','Seattle','A');
+INSERT INTO t2 VALUES (1087,258107,68,'Mossberg','inheritresses','relaxes','A');
+INSERT INTO t2 VALUES (1088,258108,68,'kept','stiller','exclaim','');
+INSERT INTO t2 VALUES (1089,258109,68,'roundly','t1','implicated','A');
+INSERT INTO t2 VALUES (1090,258110,68,'features','suite','distinguish','');
+INSERT INTO t2 VALUES (1091,258111,68,'imaginable','ransomer','assayed','');
+INSERT INTO t2 VALUES (1092,258112,68,'controller','Willy','homeowner','');
+INSERT INTO t2 VALUES (1093,258113,68,'racial','Rena','and','');
+INSERT INTO t2 VALUES (1094,258201,34,'uprisings','Seattle','stealth','');
+INSERT INTO t2 VALUES (1095,258202,34,'narrowed','relaxes','coinciding','A');
+INSERT INTO t2 VALUES (1096,258203,34,'cannot','exclaim','founder','A');
+INSERT INTO t2 VALUES (1097,258204,34,'vest','implicated','environing','');
+INSERT INTO t2 VALUES (1098,258205,34,'famine','distinguish','jewelry','');
+INSERT INTO t2 VALUES (1099,258301,34,'sugars','assayed','lemons','A');
+INSERT INTO t2 VALUES (1100,258401,34,'exterminated','homeowner','brokenness','A');
+INSERT INTO t2 VALUES (1101,258402,34,'belays','and','bedpost','A');
+INSERT INTO t2 VALUES (1102,258403,34,'Hodges','stealth','assurers','A');
+INSERT INTO t2 VALUES (1103,258404,34,'translatable','coinciding','annoyers','');
+INSERT INTO t2 VALUES (1104,258405,34,'duality','founder','affixed','');
+INSERT INTO t2 VALUES (1105,258406,34,'recording','environing','warbling','');
+INSERT INTO t2 VALUES (1106,258407,34,'rouses','jewelry','seriously','');
+INSERT INTO t2 VALUES (1107,228123,37,'poison','lemons','boasted','');
+INSERT INTO t2 VALUES (1108,250606,34,'attitude','brokenness','Chantilly','');
+INSERT INTO t2 VALUES (1109,208405,37,'dusted','bedpost','Iranizes','');
+INSERT INTO t2 VALUES (1110,212101,37,'encompasses','assurers','violinist','');
+INSERT INTO t2 VALUES (1111,218206,37,'presentation','annoyers','extramarital','');
+INSERT INTO t2 VALUES (1112,150401,37,'Kantian','affixed','spates','');
+INSERT INTO t2 VALUES (1113,248212,41,'imprecision','warbling','cloakroom','');
+INSERT INTO t2 VALUES (1114,128026,00,'saving','seriously','gazer','');
+INSERT INTO t2 VALUES (1115,128024,00,'maternal','boasted','hand','');
+INSERT INTO t2 VALUES (1116,128027,00,'hewed','Chantilly','tucked','');
+INSERT INTO t2 VALUES (1117,128025,00,'kerosene','Iranizes','gems','');
+INSERT INTO t2 VALUES (1118,128109,00,'Cubans','violinist','clinker','');
+INSERT INTO t2 VALUES (1119,128705,00,'photographers','extramarital','refiner','');
+INSERT INTO t2 VALUES (1120,126303,00,'nymph','spates','callus','');
+INSERT INTO t2 VALUES (1121,128308,00,'bedlam','cloakroom','leopards','');
+INSERT INTO t2 VALUES (1122,128204,00,'north','gazer','comfortingly','');
+INSERT INTO t2 VALUES (1123,128205,00,'Schoenberg','hand','generically','');
+INSERT INTO t2 VALUES (1124,128206,00,'botany','tucked','getters','');
+INSERT INTO t2 VALUES (1125,128207,00,'curs','gems','sexually','');
+INSERT INTO t2 VALUES (1126,118205,00,'solidification','clinker','spear','');
+INSERT INTO t2 VALUES (1127,116801,00,'inheritresses','refiner','serums','');
+INSERT INTO t2 VALUES (1128,116803,00,'stiller','callus','Italianization','');
+INSERT INTO t2 VALUES (1129,116804,00,'t1','leopards','attendants','');
+INSERT INTO t2 VALUES (1130,116802,00,'suite','comfortingly','spies','');
+INSERT INTO t2 VALUES (1131,128605,00,'ransomer','generically','Anthony','');
+INSERT INTO t2 VALUES (1132,118308,00,'Willy','getters','planar','');
+INSERT INTO t2 VALUES (1133,113702,00,'Rena','sexually','cupped','');
+INSERT INTO t2 VALUES (1134,113703,00,'Seattle','spear','cleanser','');
+INSERT INTO t2 VALUES (1135,112103,00,'relaxes','serums','commuters','');
+INSERT INTO t2 VALUES (1136,118009,00,'exclaim','Italianization','honeysuckle','');
+INSERT INTO t2 VALUES (5136,1118009,00,'exclaim','Italianization','honeysuckle','');
+INSERT INTO t2 VALUES (1137,138011,00,'implicated','attendants','orphanage','');
+INSERT INTO t2 VALUES (1138,138010,00,'distinguish','spies','skies','');
+INSERT INTO t2 VALUES (1139,138012,00,'assayed','Anthony','crushers','');
+INSERT INTO t2 VALUES (1140,068304,00,'homeowner','planar','Puritan','');
+INSERT INTO t2 VALUES (1141,078009,00,'and','cupped','squeezer','');
+INSERT INTO t2 VALUES (1142,108013,00,'stealth','cleanser','bruises','');
+INSERT INTO t2 VALUES (1143,084004,00,'coinciding','commuters','bonfire','');
+INSERT INTO t2 VALUES (1144,083402,00,'founder','honeysuckle','Colombo','');
+INSERT INTO t2 VALUES (1145,084003,00,'environing','orphanage','nondecreasing','');
+INSERT INTO t2 VALUES (1146,088504,00,'jewelry','skies','innocents','');
+INSERT INTO t2 VALUES (1147,088005,00,'lemons','crushers','masked','');
+INSERT INTO t2 VALUES (1148,088007,00,'brokenness','Puritan','file','');
+INSERT INTO t2 VALUES (1149,088006,00,'bedpost','squeezer','brush','');
+INSERT INTO t2 VALUES (1150,148025,00,'assurers','bruises','mutilate','');
+INSERT INTO t2 VALUES (1151,148024,00,'annoyers','bonfire','mommy','');
+INSERT INTO t2 VALUES (1152,138305,00,'affixed','Colombo','bulkheads','');
+INSERT INTO t2 VALUES (1153,138306,00,'warbling','nondecreasing','undeclared','');
+INSERT INTO t2 VALUES (1154,152701,00,'seriously','innocents','displacements','');
+INSERT INTO t2 VALUES (1155,148505,00,'boasted','masked','nieces','');
+INSERT INTO t2 VALUES (1156,158003,00,'Chantilly','file','coeducation','');
+INSERT INTO t2 VALUES (1157,156201,00,'Iranizes','brush','brassy','');
+INSERT INTO t2 VALUES (1158,156202,00,'violinist','mutilate','authenticator','');
+INSERT INTO t2 VALUES (1159,158307,00,'extramarital','mommy','Washoe','');
+INSERT INTO t2 VALUES (1160,158402,00,'spates','bulkheads','penny','');
+INSERT INTO t2 VALUES (1161,158401,00,'cloakroom','undeclared','Flagler','');
+INSERT INTO t2 VALUES (1162,068013,00,'gazer','displacements','stoned','');
+INSERT INTO t2 VALUES (1163,068012,00,'hand','nieces','cranes','');
+INSERT INTO t2 VALUES (1164,068203,00,'tucked','coeducation','masterful','');
+INSERT INTO t2 VALUES (1165,088205,00,'gems','brassy','biracial','');
+INSERT INTO t2 VALUES (1166,068704,00,'clinker','authenticator','steamships','');
+INSERT INTO t2 VALUES (1167,068604,00,'refiner','Washoe','windmills','');
+INSERT INTO t2 VALUES (1168,158502,00,'callus','penny','exploit','');
+INSERT INTO t2 VALUES (1169,123103,00,'leopards','Flagler','riverfront','');
+INSERT INTO t2 VALUES (1170,148026,00,'comfortingly','stoned','sisterly','');
+INSERT INTO t2 VALUES (1171,123302,00,'generically','cranes','sharpshoot','');
+INSERT INTO t2 VALUES (1172,076503,00,'getters','masterful','mittens','');
+INSERT INTO t2 VALUES (1173,126304,00,'sexually','biracial','interdependency','');
+INSERT INTO t2 VALUES (1174,068306,00,'spear','steamships','policy','');
+INSERT INTO t2 VALUES (1175,143504,00,'serums','windmills','unleashing','');
+INSERT INTO t2 VALUES (1176,160201,00,'Italianization','exploit','pretenders','');
+INSERT INTO t2 VALUES (1177,148028,00,'attendants','riverfront','overstatements','');
+INSERT INTO t2 VALUES (1178,148027,00,'spies','sisterly','birthed','');
+INSERT INTO t2 VALUES (1179,143505,00,'Anthony','sharpshoot','opportunism','');
+INSERT INTO t2 VALUES (1180,108014,00,'planar','mittens','showroom','');
+INSERT INTO t2 VALUES (1181,076104,00,'cupped','interdependency','compromisingly','');
+INSERT INTO t2 VALUES (1182,078106,00,'cleanser','policy','Medicare','');
+INSERT INTO t2 VALUES (1183,126102,00,'commuters','unleashing','corresponds','');
+INSERT INTO t2 VALUES (1184,128029,00,'honeysuckle','pretenders','hardware','');
+INSERT INTO t2 VALUES (1185,128028,00,'orphanage','overstatements','implant','');
+INSERT INTO t2 VALUES (1186,018410,00,'skies','birthed','Alicia','');
+INSERT INTO t2 VALUES (1187,128110,00,'crushers','opportunism','requesting','');
+INSERT INTO t2 VALUES (1188,148506,00,'Puritan','showroom','produced','');
+INSERT INTO t2 VALUES (1189,123303,00,'squeezer','compromisingly','criticizes','');
+INSERT INTO t2 VALUES (1190,123304,00,'bruises','Medicare','backer','');
+INSERT INTO t2 VALUES (1191,068504,00,'bonfire','corresponds','positively','');
+INSERT INTO t2 VALUES (1192,068305,00,'Colombo','hardware','colicky','');
+INSERT INTO t2 VALUES (1193,000000,00,'nondecreasing','implant','thrillingly','');
+select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
fld3
imaginable
+select fld3 from t2 where fld3 like "%cultivation" ;
fld3
cultivation
+select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3;
fld3 companynr
concoct 58
druggists 58
@@ -32,6 +1256,7 @@ synergy 58
thanking 58
tying 58
unlocks 58
+select fld3,companynr from t2 where companynr = 58 order by fld3;
fld3 companynr
concoct 58
druggists 58
@@ -56,6 +1281,7 @@ synergy 58
thanking 58
tying 58
unlocks 58
+select fld3 from t2 order by fld3 desc limit 10;
fld3
youthfulness
yelped
@@ -67,49 +1293,71 @@ Winsett
Willy
willed
wildcats
+select fld3 from t2 order by fld3 desc limit 5;
fld3
youthfulness
yelped
Wotan
workers
Witt
+select fld3 from t2 order by fld3 desc limit 5,5;
fld3
witchcraft
Winsett
Willy
willed
wildcats
+select t2.fld3 from t2 where fld3 = 'honeysuckle';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'h%le';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_';
fld3
+select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%';
fld3
+explain select t2.fld3 from t2 where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
t2 ref fld3 fld3 30 const 1 where used; Using index
+explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
-t2 index fld3 fld3 30 NULL 1199 where used; Using index
+t2 index NULL fld3 30 NULL 1199 where used; Using index
+explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
-t2 index fld3 fld3 30 NULL 1199 where used; Using index
+t2 index NULL fld3 30 NULL 1199 where used; Using index
+explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
t2 ref fld3 fld3 30 const 1 where used; Using index
+explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
t2 ref fld3 fld3 30 const 1 where used; Using index
+explain select fld3 from t2 ignore index (fld3,not_used);
+Key column 'not_used' doesn't exist in table
+explain select fld3 from t2 use index (not_used);
+Key column 'not_used' doesn't exist in table
+select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
fld3
honeysuckle
honoring
+explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
table type possible_keys key key_len ref rows Extra
t2 range fld3 fld3 30 NULL 2 where used; Using index
+select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
fld1 fld3
148504 Colombo
068305 Colombo
000000 nondecreasing
+select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes';
fld1 fld3
232605 appendixes
1232605 appendixes
@@ -117,18 +1365,23 @@ fld1 fld3
1232607 appendixes
1232608 appendixes
1232609 appendixes
+select fld1 from t2 where fld1=250501 or fld1="250502";
fld1
250501
250502
+explain select fld1 from t2 where fld1=250501 or fld1="250502";
table type possible_keys key key_len ref rows Extra
t2 range fld1 fld1 4 NULL 2 where used; Using index
+select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
fld1
250501
250502
250505
250601
+explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
table type possible_keys key key_len ref rows Extra
t2 range fld1 fld1 4 NULL 4 where used; Using index
+select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
218401 faithful
018007 fanatic
@@ -161,21 +1414,26 @@ fld1 fld3
036002 funereal
226209 furnishings
198006 furthermore
+select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
+select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
fld3
Chantilly
+select fld1,fld3 from t2 where fld1 like "25050%";
fld1 fld3
250501 poisoning
250502 Iraqis
250503 heaving
250504 population
250505 bomb
+select fld1,fld3 from t2 where fld1 like "25050_";
fld1 fld3
250501 poisoning
250502 Iraqis
250503 heaving
250504 population
250505 bomb
+select distinct companynr from t2;
companynr
00
37
@@ -189,6 +1447,7 @@ companynr
41
34
68
+select distinct companynr from t2 order by companynr;
companynr
00
29
@@ -202,6 +1461,7 @@ companynr
58
65
68
+select distinct companynr from t2 order by companynr desc;
companynr
68
65
@@ -215,6 +1475,7 @@ companynr
34
29
00
+select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%";
fld3 period
obliterates 9410
offload 9410
@@ -222,6 +1483,7 @@ opaquely 9410
organizer 9410
overestimating 9410
overlay 9410
+select distinct fld3 from t2 where companynr = 34 order by fld3;
fld3
absentee
accessed
@@ -293,6 +1555,7 @@ unexpected
uprisings
versatility
vest
+select distinct fld3 from t2 limit 10;
fld3
abates
abiding
@@ -304,6 +1567,7 @@ accessed
accruing
accumulating
accuracies
+select distinct fld3 from t2 having fld3 like "A%" limit 10;
fld3
abates
abiding
@@ -315,6 +1579,7 @@ accessed
accruing
accumulating
accuracies
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%";
substring(fld3,1,3)
aba
abi
@@ -378,6 +1643,7 @@ avo
awe
aye
Azt
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10;
a
aba
abi
@@ -389,6 +1655,7 @@ acq
acu
Ade
adj
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10;
substring(fld3,1,3)
aba
abi
@@ -400,6 +1667,7 @@ acq
acu
Ade
adj
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10;
a
aba
abi
@@ -411,6 +1679,47 @@ acq
acu
Ade
adj
+create table t3 (
+period int not null,
+name char(32) not null,
+companynr int not null,
+price double(11,0),
+price2 double(11,0),
+key (period),
+key (name)
+);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1001,"Iranizes",37,5987435,234724);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1002,"violinist",37,28357832,8723648);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1003,"extramarital",37,39654943,235872);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1004,"spates",78,726498,72987523);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1005,"cloakroom",78,98439034,823742);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1006,"gazer",101,834598,27348324);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1007,"hand",154,983543950,29837423);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1008,"tucked",311,234298,3275892);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1009,"gems",447,2374834,9872392);
+INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1010,"clinker",512,786542,76234234);
+create temporary table tmp type = myisam select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+alter table t3 add t2nr int not null auto_increment primary key first;
+drop table tmp;
+SET OPTION SQL_BIG_TABLES=1;
+select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10;
namn
Abraham Abraham
abrogating abrogating
@@ -422,6 +1731,8 @@ ammonium ammonium
analyzable analyzable
animals animals
animized animized
+SET OPTION SQL_BIG_TABLES=0;
+select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10;
concat(fld3," ",fld3)
Abraham Abraham
abrogating abrogating
@@ -433,6 +1744,7 @@ ammonium ammonium
analyzable analyzable
animals animals
animized animized
+select distinct fld5 from t2 limit 10;
fld5
neat
Steinberg
@@ -444,6 +1756,7 @@ attainments
fanatic
measures
rightfulness
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
fld3 count(*)
affixed 1
and 1
@@ -455,6 +1768,8 @@ attendants 1
bedlam 1
bedpost 1
boasted 1
+SET OPTION SQL_BIG_TABLES=1;
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
fld3 count(*)
affixed 1
and 1
@@ -466,6 +1781,8 @@ attendants 1
bedlam 1
bedpost 1
boasted 1
+SET OPTION SQL_BIG_TABLES=0;
+select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10;
fld3 repeat("a",length(fld3)) count(*)
circus aaaaaa 1
cited aaaaa 1
@@ -477,6 +1794,7 @@ cultivation aaaaaaaaaaa 1
definiteness aaaaaaaaaaaa 1
demultiplex aaaaaaaaaaa 1
disappointing aaaaaaaaaaaaa 1
+select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2;
companynr rtrim(space(512+companynr))
37
78
@@ -485,20 +1803,28 @@ companynr rtrim(space(512+companynr))
311
447
512
+select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3;
fld3
+explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3;
table type possible_keys key key_len ref rows Extra
t2 ALL fld1 NULL NULL NULL 1199 where used; Using temporary; Using filesort
t3 eq_ref PRIMARY PRIMARY 4 t2.fld1 1 where used; Using index
+select period from t1;
period
9410
+select period from t1 where period=1900;
period
+select fld3,period from t1,t2 where fld1 = 011401 order by period;
fld3 period
breaking 9410
+select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001;
fld3 period
breaking 1001
+explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period;
table type possible_keys key key_len ref rows Extra
t2 const fld1 fld1 4 const 1
t3 const PRIMARY,period PRIMARY 4 const 1
+select fld3,period from t2,t1 where companynr*10 = 37*10;
fld3 period
breaking 9410
Romans 9410
@@ -1088,6 +2414,7 @@ dusted 9410
encompasses 9410
presentation 9410
Kantian 9410
+select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price;
fld3 period price price2
admonishing 1002 28357832 8723648
analyzable 1002 28357832 8723648
@@ -1148,11 +2475,32 @@ ventilate 1001 5987435 234724
wallet 1001 5987435 234724
Weissmuller 1002 28357832 8723648
Wotan 1002 28357832 8723648
+select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37;
fld1 fld3 period price price2
018201 relaxing 1001 5987435 234724
018601 vacuuming 1001 5987435 234724
018801 inch 1001 5987435 234724
018811 repetitions 1001 5987435 234724
+drop table if exists company;
+create table t4 (
+companynr tinyint(2) unsigned zerofill NOT NULL default '00',
+companyname char(30) NOT NULL default '',
+PRIMARY KEY (companynr),
+UNIQUE KEY companyname(companyname)
+) TYPE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames';
+INSERT INTO t4 (companynr, companyname) VALUES (29,'company 1');
+INSERT INTO t4 (companynr, companyname) VALUES (34,'company 2');
+INSERT INTO t4 (companynr, companyname) VALUES (36,'company 3');
+INSERT INTO t4 (companynr, companyname) VALUES (37,'company 4');
+INSERT INTO t4 (companynr, companyname) VALUES (40,'company 5');
+INSERT INTO t4 (companynr, companyname) VALUES (41,'company 6');
+INSERT INTO t4 (companynr, companyname) VALUES (53,'company 7');
+INSERT INTO t4 (companynr, companyname) VALUES (58,'company 8');
+INSERT INTO t4 (companynr, companyname) VALUES (65,'company 9');
+INSERT INTO t4 (companynr, companyname) VALUES (68,'company 10');
+INSERT INTO t4 (companynr, companyname) VALUES (50,'company 11');
+INSERT INTO t4 (companynr, companyname) VALUES (00,'Unknown');
+select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
companynr companyname
00 Unknown
29 company 1
@@ -1166,6 +2514,7 @@ companynr companyname
58 company 8
65 company 9
68 company 10
+select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
companynr companyname
00 Unknown
29 company 1
@@ -1179,8 +2528,10 @@ companynr companyname
58 company 8
65 company 9
68 company 10
+select * from t1,t1 t12;
Period Varor_period Period Varor_period
9410 9412 9410 9412
+select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505;
fld1 fld1
250501 250501
250502 250501
@@ -1207,44 +2558,58 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
companynr companyname
+explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
table type possible_keys key key_len ref rows Extra
t2 ALL NULL NULL NULL NULL 1199
-t4 eq_ref PRIMARY PRIMARY 1 t2.companynr 1 where used; Not exists
+t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 where used; Not exists
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
table type possible_keys key key_len ref rows Extra
t4 ALL NULL NULL NULL NULL 12
t2 ALL NULL NULL NULL NULL 1199 where used; Not exists
+select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
41 40
+explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
table type possible_keys key key_len ref rows Extra
t2 ALL NULL NULL NULL NULL 1199 Using temporary
t4 index NULL PRIMARY 1 NULL 12 where used; Using index
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
fld1 companynr fld3 period
038008 37 reporters 1008
038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
fld1 companynr fld3 period
038008 37 reporters 1008
038208 37 Selfridge 1008
+select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909);
period
9410
+select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6)));
period
9410
+select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1;
fld1
250501
250502
250503
250505
+select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606);
fld1
250502
250503
+select fld1 from t2 where fld1 between 250502 and 250504;
fld1
250502
250503
250504
+select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ;
fld3
label
labeled
@@ -1255,8 +2620,10 @@ leaflet
lewdly
Lillian
luckily
+select count(*) from t1;
count(*)
1
+select companynr,count(*),sum(fld1) from t2 group by companynr;
companynr count(*) sum(fld1)
00 82 10355753
29 95 14473298
@@ -1270,18 +2637,22 @@ companynr count(*) sum(fld1)
58 23 2254293
65 10 2284055
68 12 3097288
+select companynr,count(*) from t2 group by companynr order by companynr desc limit 5;
companynr count(*)
68 12
65 10
58 23
53 4
50 11
+select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 where companynr = 34 and fld4<>"";
count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1)
70 absentee vest 17788966 254128.0857 3272.5940
+select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757
29 95 abut wetness 14473298 152350.5053 8368.5480
34 70 absentee vest 17788966 254128.0857 3272.5940
+select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 1 1 5987435 5987435 5987435 5987435.0000
37 2 1 28357832 28357832 28357832 28357832.0000
@@ -1293,6 +2664,7 @@ companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 22 1 28357832 28357832 28357832 28357832.0000
37 23 1 39654943 39654943 39654943 39654943.0000
37 31 1 5987435 5987435 5987435 5987435.0000
+select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 1 1 5987435 5987435 5987435 5987435.0000
37 2 1 28357832 28357832 28357832 28357832.0000
@@ -1304,6 +2676,7 @@ companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 22 1 28357832 28357832 28357832 28357832.0000
37 23 1 39654943 39654943 39654943 39654943.0000
37 31 1 5987435 5987435 5987435 5987435.0000
+select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ;
companynr count(price) sum(price) min(price) max(price) avg(price)
37 12543 309394878010 5987435 39654943 24666736.6667
78 8362 414611089292 726498 98439034 49582766.0000
@@ -1312,6 +2685,7 @@ companynr count(price) sum(price) min(price) max(price) avg(price)
311 4181 979599938 234298 234298 234298.0000
447 4181 9929180954 2374834 2374834 2374834.0000
512 4181 3288532102 786542 786542 786542.0000
+select distinct mod(companynr,10) from t4 group by companynr;
mod(companynr,10)
0
9
@@ -1322,10 +2696,13 @@ mod(companynr,10)
3
8
5
+select distinct 1 from t4 group by companynr;
1
1
+select count(distinct fld1) from t2;
count(distinct fld1)
1199
+select companynr,count(distinct fld1) from t2 group by companynr;
companynr count(distinct fld1)
00 82
29 95
@@ -1339,6 +2716,7 @@ companynr count(distinct fld1)
58 23
65 10
68 12
+select companynr,count(*) from t2 group by companynr;
companynr count(*)
00 82
29 95
@@ -1352,6 +2730,7 @@ companynr count(*)
58 23
65 10
68 12
+select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr;
companynr count(distinct concat(fld1,repeat(65,1000)))
00 82
29 95
@@ -1365,6 +2744,7 @@ companynr count(distinct concat(fld1,repeat(65,1000)))
58 23
65 10
68 12
+select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr;
companynr count(distinct concat(fld1,repeat(65,200)))
00 82
29 95
@@ -1378,6 +2758,7 @@ companynr count(distinct concat(fld1,repeat(65,200)))
58 23
65 10
68 12
+select companynr,count(distinct floor(fld1/100)) from t2 group by companynr;
companynr count(distinct floor(fld1/100))
00 47
29 35
@@ -1391,6 +2772,7 @@ companynr count(distinct floor(fld1/100))
58 1
65 1
68 1
+select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr;
companynr count(distinct concat(repeat(65,1000),floor(fld1/100)))
00 47
29 35
@@ -1404,16 +2786,22 @@ companynr count(distinct concat(repeat(65,1000),floor(fld1/100)))
58 1
65 1
68 1
+select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10;
sum(fld1) fld3
11402 Romans
+select name,count(*) from t3 where name='cloakroom' group by name;
name count(*)
cloakroom 4181
+select name,count(*) from t3 where name='cloakroom' and price>10 group by name;
name count(*)
cloakroom 4181
+select count(*) from t3 where name='cloakroom' and price2=823742;
count(*)
4181
+select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name;
name count(*)
cloakroom 4181
+select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name;
name count(*)
extramarital 4181
gazer 4181
@@ -1422,8 +2810,10 @@ Iranizes 4181
spates 4181
tucked 4181
violinist 4181
+select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
fld3 count(*)
spates 4181
+select companynr|0,companyname from t4 group by 1;
companynr|0 companyname
0 Unknown
29 company 1
@@ -1437,6 +2827,7 @@ companynr|0 companyname
58 company 8
65 company 9
68 company 10
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname;
companynr companyname count(*)
29 company 1 95
68 company 10 12
@@ -1450,10 +2841,13 @@ companynr companyname count(*)
58 company 8 23
65 company 9 10
00 Unknown 82
+select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
fld1 count(*)
158402 4181
+select sum(Period)/count(*) from t1;
sum(Period)/count(*)
9410.00
+select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr;
companynr count sum diff func
37 12543 309394878010 0.0000 464091
78 8362 414611089292 0.0000 652236
@@ -1462,8 +2856,10 @@ companynr count sum diff func
311 4181 979599938 0.0000 1300291
447 4181 9929180954 0.0000 1868907
512 4181 3288532102 0.0000 2140672
+select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg;
companynr avg
154 983543950.00
+select companynr,count(*) from t2 group by companynr order by 2 desc;
companynr count(*)
37 588
36 215
@@ -1477,6 +2873,7 @@ companynr count(*)
50 11
65 10
53 4
+select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc;
companynr count(*)
41 52
58 23
@@ -1484,6 +2881,7 @@ companynr count(*)
50 11
65 10
53 4
+select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4;
fld4 fld1 count(price) sum(price) min(price) max(price) avg(price)
teethe 000001 1 5987435 5987435 5987435 5987435.0000
dreaded 011401 1 5987435 5987435 5987435 5987435.0000
@@ -1572,6 +2970,7 @@ partridges 038103 1 39654943 39654943 39654943 39654943.0000
recruited 038201 1 5987435 5987435 5987435 5987435.0000
dimensions 038202 1 28357832 28357832 28357832 28357832.0000
Chicana 038203 1 39654943 39654943 39654943 39654943.0000
+select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3;
companynr fld3 sum(price)
512 boat 786542
512 capably 786542
@@ -1583,11 +2982,13 @@ companynr fld3 sum(price)
512 Micronesia 786542
512 Miles 786542
512 skies 786542
+select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr;
companynr count(*) min(fld3) max(fld3) sum(price) avg(price)
00 1 Omaha Omaha 5987435 5987435.0000
36 1 dubbed dubbed 28357832 28357832.0000
37 83 Abraham Wotan 1908978016 22999735.1325
50 2 scribbled tapestry 68012775 34006387.5000
+select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1;
t3.companynr+0 t2nr fld3 sum(price)
37 1 Omaha 5987435
37 11401 breaking 5987435
@@ -1676,32 +3077,41 @@ t3.companynr+0 t2nr fld3 sum(price)
37 38201 resumes 5987435
37 38202 analyzable 28357832
37 38203 terminator 39654943
+select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008;
sum(price)
234298
+select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1;
fld1 sum(price)
038008 234298
+explain select fld3 from t2 where 1>2 or 2>3;
Comment
Impossible WHERE
+explain select fld3 from t2 where fld1=fld1;
table type possible_keys key key_len ref rows Extra
t2 ALL NULL NULL NULL NULL 1199
+select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502;
companynr fld1
34 250501
34 250502
+select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502;
companynr fld1
34 250501
34 250502
+select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000;
companynr count sum
00 82 10355753
29 95 14473298
34 70 17788966
37 588 83602098
41 52 12816335
+select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ;
companynr
00
29
34
37
41
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40;
companynr companyname count(*)
68 company 10 12
50 company 11 11
@@ -1710,26 +3120,37 @@ companynr companyname count(*)
53 company 7 4
58 company 8 23
65 company 9 10
+select count(*) from t2;
count(*)
1199
+select count(*) from t2 where fld1 < 098024;
count(*)
387
+select min(fld1) from t2 where fld1>= 098024;
min(fld1)
98024
+select max(fld1) from t2 where fld1>= 098024;
max(fld1)
1232609
+select count(*) from t3 where price2=76234234;
count(*)
4181
+select count(*) from t3 where companynr=512 and price2=76234234;
count(*)
4181
+explain select min(fld1),max(fld1),count(*) from t2;
Comment
Select tables optimized away
+select min(fld1),max(fld1),count(*) from t2;
min(fld1) max(fld1) count(*)
0 1232609 1199
+select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742;
min(t2nr) max(t2nr)
2115 2115
+select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78;
count(*) min(t2nr) max(t2nr)
4181 4 41804
+select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20;
t2nr count(*)
9 1
19 1
@@ -1751,29 +3172,41 @@ t2nr count(*)
179 1
189 1
199 1
+select max(t2nr) from t3 where price=983543950;
max(t2nr)
41807
+select t1.period from t3 = t1 limit 1;
period
1001
+select t1.period from t1 as t1 limit 1;
period
9410
+select t1.period as "Nuvarande period" from t1 as t1 limit 1;
Nuvarande period
9410
+select period as ok_period from t1 limit 1;
ok_period
9410
+select period as ok_period from t1 group by ok_period limit 1;
ok_period
9410
+select 1+1 as summa from t1 group by summa limit 1;
summa
2
+select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1;
Nuvarande period
9410
+show tables;
Tables_in_test
t1
t2
t3
t4
+show tables from test like "s%";
Tables_in_test (s%)
+show tables from test like "t?";
Tables_in_test (t?)
+show full columns from t2;
Field Type Null Key Default Extra Privileges
auto int(11) PRI NULL auto_increment select,insert,update,references
fld1 int(6) unsigned zerofill UNI 000000 select,insert,update,references
@@ -1782,14 +3215,28 @@ fld3 char(30) MUL select,insert,update,references
fld4 char(35) select,insert,update,references
fld5 char(35) select,insert,update,references
fld6 char(4) select,insert,update,references
+show full columns from t2 from test like 'f%';
Field Type Null Key Default Extra Privileges
fld1 int(6) unsigned zerofill UNI 000000 select,insert,update,references
fld3 char(30) MUL select,insert,update,references
fld4 char(35) select,insert,update,references
fld5 char(35) select,insert,update,references
fld6 char(4) select,insert,update,references
+show full columns from t2 from test like 's%';
Field Type Null Key Default Extra Privileges
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t2 0 PRIMARY 1 auto A 1199 NULL NULL
-t2 0 fld1 1 fld1 A 1199 NULL NULL
-t2 1 fld3 1 fld3 A NULL NULL NULL
+show keys from t2;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE
+t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE
+t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
+DO 1;
+DO benchmark(100,1+1),1,1;
+drop table t4, t3,t2, t1;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 ( gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp(14) NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
+CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'NULL' AND b.sampletime < 'NULL' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+gvid the_success the_fail the_size the_time
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result
new file mode 100644
index 00000000000..1c2cd7da894
--- /dev/null
+++ b/mysql-test/r/select_found.result
@@ -0,0 +1,171 @@
+drop table if exists t1,t2;
+create table t1 (a int not null auto_increment, b int not null, primary key(a));
+insert into t1 (b) values (2),(3),(5),(5),(5),(6),(7),(9);
+select SQL_CALC_FOUND_ROWS * from t1;
+a b
+1 2
+2 3
+3 5
+4 5
+5 5
+6 6
+7 7
+8 9
+select found_rows();
+FOUND_ROWS()
+8
+select SQL_CALC_FOUND_ROWS * from t1 limit 1;
+a b
+1 2
+select found_rows();
+FOUND_ROWS()
+8
+select SQL_BUFFER_RESULT SQL_CALC_FOUND_ROWS * from t1 limit 1;
+a b
+1 2
+select found_rows();
+FOUND_ROWS()
+8
+select SQL_CALC_FOUND_ROWS * from t1 order by b desc limit 1;
+a b
+8 9
+select found_rows();
+FOUND_ROWS()
+8
+select SQL_CALC_FOUND_ROWS distinct b from t1 limit 1;
+b
+2
+select found_rows();
+FOUND_ROWS()
+6
+select SQL_CALC_FOUND_ROWS b,count(*) as c from t1 group by b order by c desc limit 1;
+b c
+5 3
+select found_rows();
+FOUND_ROWS()
+6
+select SQL_CALC_FOUND_ROWS * from t1 left join t1 as t2 on (t1.b=t2.a) limit 2,1;
+a b a b
+3 5 5 5
+select found_rows();
+FOUND_ROWS()
+8
+drop table t1;
+create table t1 (a int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a desc limit 0,2;
+a
+3
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+3
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a+2 desc limit 0,2;
+a
+3
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+3
+drop table t1;
+CREATE TABLE t1 (
+`id` smallint(5) unsigned NOT NULL auto_increment,
+`kid` smallint(5) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+KEY `kid` (`kid`)
+);
+CREATE TABLE t2 (
+id smallint(5) unsigned NOT NULL auto_increment,
+name varchar(50) NOT NULL default '',
+email varchar(50) NOT NULL default '',
+PRIMARY KEY (id),
+UNIQUE KEY e_n (email,name)
+);
+INSERT INTO t2 VALUES (1,'name1','email1'),(2,'name2','email2'),(3,'name3','email3'),(4,'name4','email4'),(5,'name5','email5'),(6,'name6','email6'),(7,'name7','email7'),(8,'name8','email8'),(9,'name9','email9'),(10,'name10','email10'),(11,'name11','email11'),(12,'name12','email12'),(13,'name13','email13'),(14,'name14','email14'),(15,'name15','email15'),(16,'name16','email16'),(17,'name17','email17'),(18,'name18','email18'),(19,'name19','email19'),(20,'name20','email20'),(21,'name21','email21'),(22,'name22','email22'),(23,'name23','email23'),(24,'name24','email24'),(25,'name25','email25'),(26,'name26','email26'),(27,'name27','email27'),(28,'name28','email28'),(29,'name29','email29'),(30,'name30','email30'),(31,'name31','email31'),(32,'name32','email32'),(33,'name33','email33'),(34,'name34','email34'),(35,'name35','email35'),(36,'name36','email36'),(37,'name37','email37'),(38,'name38','email38'),(39,'name39','email39'),(40,'name40','email40'),(41,'name41','email41'),(42,'name42','email42'),(43,'name43','email43'),(44,'name44','email44'),(45,'name45','email45'),(46,'name46','email46'),(47,'name47','email47'),(48,'name48','email48'),(49,'name49','email49'),(50,'name50','email50'),(51,'name51','email51'),(52,'name52','email52'),(53,'name53','email53'),(54,'name54','email54'),(55,'name55','email55'),(56,'name56','email56'),(57,'name57','email57'),(58,'name58','email58'),(59,'name59','email59'),(60,'name60','email60'),(61,'name61','email61'),(62,'name62','email62'),(63,'name63','email63'),(64,'name64','email64'),(65,'name65','email65'),(66,'name66','email66'),(67,'name67','email67'),(68,'name68','email68'),(69,'name69','email69'),(70,'name70','email70'),(71,'name71','email71'),(72,'name72','email72'),(73,'name73','email73'),(74,'name74','email74'),(75,'name75','email75'),(76,'name76','email76'),(77,'name77','email77'),(78,'name78','email78'),(79,'name79','email79'),(80,'name80','email80'),(81,'name81','email81'),(82,'name82','email82'),(83,'name83','email83'),(84,'name84','email84'),(85,'name85','email85'),(86,'name86','email86'),(87,'name87','email87'),(88,'name88','email88'),(89,'name89','email89'),(90,'name90','email90'),(91,'name91','email91'),(92,'name92','email92'),(93,'name93','email93'),(94,'name94','email94'),(95,'name95','email95'),(96,'name96','email96'),(97,'name97','email97'),(98,'name98','email98'),(99,'name99','email99'),(100,'name100','email100'),(101,'name101','email101'),(102,'name102','email102'),(103,'name103','email103'),(104,'name104','email104'),(105,'name105','email105'),(106,'name106','email106'),(107,'name107','email107'),(108,'name108','email108'),(109,'name109','email109'),(110,'name110','email110'),(111,'name111','email111'),(112,'name112','email112'),(113,'name113','email113'),(114,'name114','email114'),(115,'name115','email115'),(116,'name116','email116'),(117,'name117','email117'),(118,'name118','email118'),(119,'name119','email119'),(120,'name120','email120'),(121,'name121','email121'),(122,'name122','email122'),(123,'name123','email123'),(124,'name124','email124'),(125,'name125','email125'),(126,'name126','email126'),(127,'name127','email127'),(128,'name128','email128'),(129,'name129','email129'),(130,'name130','email130'),(131,'name131','email131'),(132,'name132','email132'),(133,'name133','email133'),(134,'name134','email134'),(135,'name135','email135'),(136,'name136','email136'),(137,'name137','email137'),(138,'name138','email138'),(139,'name139','email139'),(140,'name140','email140'),(141,'name141','email141'),(142,'name142','email142'),(143,'name143','email143'),(144,'name144','email144'),(145,'name145','email145'),(146,'name146','email146'),(147,'name147','email147'),(148,'name148','email148'),(149,'name149','email149'),(150,'name150','email150'),(151,'name151','email151'),(152,'name152','email152'),(153,'name153','email153'),(154,'name154','email154'),(155,'name155','email155'),(156,'name156','email156'),(157,'name157','email157'),(158,'name158','email158'),(159,'name159','email159'),(160,'name160','email160'),(161,'name161','email161'),(162,'name162','email162'),(163,'name163','email163'),(164,'name164','email164'),(165,'name165','email165'),(166,'name166','email166'),(167,'name167','email167'),(168,'name168','email168'),(169,'name169','email169'),(170,'name170','email170'),(171,'name171','email171'),(172,'name172','email172'),(173,'name173','email173'),(174,'name174','email174'),(175,'name175','email175'),(176,'name176','email176'),(177,'name177','email177'),(178,'name178','email178'),(179,'name179','email179'),(180,'name180','email180'),(181,'name181','email181'),(182,'name182','email182'),(183,'name183','email183'),(184,'name184','email184'),(185,'name185','email185'),(186,'name186','email186'),(187,'name187','email187'),(188,'name188','email188'),(189,'name189','email189'),(190,'name190','email190'),(191,'name191','email191'),(192,'name192','email192'),(193,'name193','email193'),(194,'name194','email194'),(195,'name195','email195'),(196,'name196','email196'),(197,'name197','email197'),(198,'name198','email198'),(199,'name199','email199'),(200,'name200','email200');
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+email
+email1
+email10
+email100
+email101
+email102
+email103
+email104
+email105
+email106
+email107
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+200
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL order by email LIMIT 10;
+email
+email1
+email10
+email100
+email101
+email102
+email103
+email104
+email105
+email106
+email107
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+200
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+email
+email1
+email2
+email3
+email4
+email5
+email6
+email7
+email8
+email9
+email10
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL ORDER BY email LIMIT 10;
+email
+email1
+email10
+email100
+email101
+email102
+email103
+email104
+email105
+email106
+email107
+INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150');
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+email
+email1
+email2
+email3
+email4
+email5
+email6
+email7
+email8
+email9
+email10
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+199
+drop table t1,t2;
+CREATE TABLE `t1` (
+`titre` char(80) NOT NULL default '',
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+KEY `maxnumrep` (`maxnumrep`)
+) TYPE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (titre,maxnumrep) VALUES
+('test1','1'),('test2','2'),('test3','3');
+SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1;
+titre numeropost maxnumrep
+test2 2 2
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+2
+drop table t1;
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index 1111ba00cd9..e225a0e3995 100644
--- a/mysql-test/r/select_safe.result
+++ b/mysql-test/r/select_safe.result
@@ -1,10 +1,39 @@
+drop table if exists t1;
+SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9;
+create table t1 (a int primary key, b char(20));
+insert into t1 values(1,"test");
+SELECT SQL_BUFFER_RESULT * from t1;
a b
1 test
+update t1 set b="a" where a=1;
+delete from t1 where a=1;
+insert into t1 values(1,"test"),(2,"test2");
+SELECT SQL_BUFFER_RESULT * from t1;
a b
1 test
2 test2
+update t1 set b="a" where a=1;
+select 1 from t1,t1 as t2,t1 as t3,t1 as t4;
1
1
1
1
1
+update t1 set b="a";
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+update t1 set b="a" where b="test";
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+delete from t1;
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+delete from t1 where b="test";
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+delete from t1 where a+0=1;
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5;
+The SELECT would examine too many records and probably take a very long time. Check your WHERE and use SET OPTION SQL_BIG_SELECTS=1 if the SELECT is ok
+update t1 set b="a" limit 1;
+update t1 set b="a" where b="b" limit 2;
+delete from t1 where b="test" limit 1;
+delete from t1 where a+0=1 limit 2;
+drop table t1;
+SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT;
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index 44e2b2ec1c9..2c32d766a38 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -1,97 +1,153 @@
-Table Op Msg_type Msg_text
-test.t1 optimize status OK
-Table Op Msg_type Msg_text
-test.t1 check status OK
-test.t2 check error The handler for the table doesn't support check/repair
-Table Op Msg_type Msg_text
-test.t1 repair status OK
-test.t2 repair error The handler for the table doesn't support check/repair
-Table Op Msg_type Msg_text
-test.t2 check error The handler for the table doesn't support check/repair
-test.t1 check status OK
-Table Op Msg_type Msg_text
-test.t2 check error Table 't2' was not locked with LOCK TABLES
-test.t1 check status OK
-Field Type Null Key Default Extra
-a int(11) PRI 0
-b int(11) MUL 0
-c int(11) 0
-Field Type Null Key Default Extra Privileges
-a int(11) PRI 0 select,insert,update,references
-b int(11) MUL 0 select,insert,update,references
-c int(11) 0 select,insert,update,references
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 4 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
-t1 1 b 2 c A 4 NULL NULL
+drop table if exists t1,t2;
+create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
+insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
+check table t1 fast;
Table Op Msg_type Msg_text
test.t1 check status Table is already up to date
+check table t1 fast;
Table Op Msg_type Msg_text
test.t1 check status Table is already up to date
+check table t1 changed;
Table Op Msg_type Msg_text
test.t1 check status OK
+insert into t1 values (5,5,5);
+check table t1 changed;
Table Op Msg_type Msg_text
test.t1 check status OK
+check table t1 medium;
Table Op Msg_type Msg_text
test.t1 check status OK
+check table t1 extended;
Table Op Msg_type Msg_text
test.t1 check status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
-t1 1 b 2 c A 5 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+t1 1 b 2 c A 5 NULL NULL BTREE
+insert into t1 values (5,5,5);
+Duplicate entry '5' for key 1
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status Table is already up to date
+drop table t1;
+show variables like "wait_timeout%";
Variable_name Value
wait_timeout 28800
+show variables like "WAIT_timeout%";
Variable_name Value
wait_timeout 28800
+show variables like "this_doesn't_exists%";
Variable_name Value
+show table status from test like "this_doesn't_exists%";
Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Create_options Comment
+show databases;
Database
mysql
test
+show databases like "test%";
Database (test%)
test
+create table t1 (f1 int not null, f2 int not null, f3 int not null, f4 int not null, primary key(f1,f2,f3,f4));
+insert into t1 values (1,1,1,0),(1,1,2,0),(1,1,3,0),(1,2,1,0),(1,2,2,0),(1,2,3,0),(1,3,1,0),(1,3,2,0),(1,3,3,0),(1,1,1,1),(1,1,2,1),(1,1,3,1),(1,2,1,1),(1,2,2,1),(1,2,3,1),(1,3,1,1),(1,3,2,1),(1,3,3,1);
+analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 f1 A 1 NULL NULL
-t1 0 PRIMARY 2 f2 A 3 NULL NULL
-t1 0 PRIMARY 3 f3 A 9 NULL NULL
-t1 0 PRIMARY 4 f4 A 18 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE
+t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE
+t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE
+t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 f1 A 1 NULL NULL
-t1 0 PRIMARY 2 f2 A 3 NULL NULL
-t1 0 PRIMARY 3 f3 A 9 NULL NULL
-t1 0 PRIMARY 4 f4 A 18 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE
+t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE
+t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE
+t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE
+drop table t1;
+create temporary table t1 (a int not null);
+show create table t1;
Table Create Table
t1 CREATE TEMPORARY TABLE `t1` (
`a` int(11) NOT NULL default '0'
) TYPE=MyISAM
+alter table t1 rename t2;
+show create table t2;
Table Create Table
t2 CREATE TEMPORARY TABLE `t2` (
`a` int(11) NOT NULL default '0'
) TYPE=MyISAM
+drop table t2;
+create table t1 (
+test_set set( 'val1', 'val2', 'val3' ) not null default '',
+name char(20) default 'O''Brien'
+ ) comment = 'it\'s a table' ;
+show create table t1 ;
Table Create Table
t1 CREATE TABLE `t1` (
`test_set` set('val1','val2','val3') NOT NULL default '',
`name` char(20) default 'O''Brien'
) TYPE=MyISAM COMMENT='it''s a table'
+drop table t1;
+create table t1 (a int not null, unique aa (a));
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
UNIQUE KEY `aa` (`a`)
) TYPE=MyISAM
+drop table t1;
+create table t1 (a int not null, primary key (a));
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
PRIMARY KEY (`a`)
) TYPE=MyISAM
+drop table t1;
+flush tables;
+show open tables;
+Database Table In_use Name_locked
+create table t1(n int);
+insert into t1 values (1);
+show open tables;
+Database Table In_use Name_locked
+test t1 0 0
+drop table t1;
+create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` char(10) default NULL,
+ KEY `b` (`b`)
+) TYPE=MyISAM MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
+alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` varchar(10) default NULL,
+ KEY `b` (`b`)
+) TYPE=MyISAM MIN_ROWS=10 MAX_ROWS=200 AVG_ROW_LENGTH=10 PACK_KEYS=0 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='test'
+ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` varchar(10) default NULL,
+ KEY `b` (`b`)
+) TYPE=MyISAM
+drop table t1;
+create table t1 (a decimal(9,2), b decimal (9,0), e double(9,2), f double(5,0), h float(3,2), i float(3,0));
+show columns from t1;
Field Type Null Key Default Extra
a decimal(9,2) YES NULL
b decimal(9,0) YES NULL
@@ -99,12 +155,19 @@ e double(9,2) YES NULL
f double(5,0) YES NULL
h float(3,2) YES NULL
i float(3,0) YES NULL
+drop table t1;
+create table t1 (c decimal, d double, f float, r real);
+show columns from t1;
Field Type Null Key Default Extra
c decimal(10,0) YES NULL
d double YES NULL
f float YES NULL
r double YES NULL
+drop table t1;
+create table t1 (c decimal(3,3), d double(3,3), f float(3,3));
+show columns from t1;
Field Type Null Key Default Extra
c decimal(4,3) YES NULL
d double(4,3) YES NULL
f float(4,3) YES NULL
+drop table t1;
diff --git a/mysql-test/r/slave-running.result b/mysql-test/r/slave-running.result
index 794d0935ef4..3699390a7d3 100644
--- a/mysql-test/r/slave-running.result
+++ b/mysql-test/r/slave-running.result
@@ -1,2 +1,3 @@
+show status like 'Slave_running';
Variable_name Value
Slave_running ON
diff --git a/mysql-test/r/slave-stopped.result b/mysql-test/r/slave-stopped.result
index 29ab2ac73e4..90b416b7bd7 100644
--- a/mysql-test/r/slave-stopped.result
+++ b/mysql-test/r/slave-stopped.result
@@ -1,2 +1,3 @@
+show status like 'Slave_running';
Variable_name Value
Slave_running OFF
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index 8f3ad3e0d59..3ef6cec32b3 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -1,6 +1,19 @@
+flush status;
+show status like 'Table_lock%';
Variable_name Value
Table_locks_immediate 0
Table_locks_waited 0
+SET SQL_LOG_BIN=0;
+drop table if exists t1;
+create table t1(n int) type=myisam;
+insert into t1 values(1);
+lock tables t1 read;
+unlock tables;
+lock tables t1 read;
+update t1 set n = 3;
+unlock tables;
+show status like 'Table_lock%';
Variable_name Value
Table_locks_immediate 3
Table_locks_waited 1
+drop table t1;
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
new file mode 100644
index 00000000000..5626bc0fe11
--- /dev/null
+++ b/mysql-test/r/symlink.result
@@ -0,0 +1,65 @@
+drop table if exists t1,t2,t7,t8,t9;
+create table t1 (a int not null auto_increment, b char(16) not null, primary key (a));
+create table t2 (a int not null auto_increment, b char(16) not null, primary key (a));
+insert into t1 (b) values ("test"),("test1"),("test2"),("test3");
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+drop table t2;
+insert into t9 select * from t1;
+check table t9;
+Table Op Msg_type Msg_text
+test.t9 check status OK
+optimize table t9;
+Table Op Msg_type Msg_text
+test.t9 optimize status OK
+repair table t9;
+Table Op Msg_type Msg_text
+test.t9 repair status OK
+alter table t9 add column c int not null;
+show create table t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` char(16) NOT NULL default '',
+ `c` int(11) NOT NULL default '0',
+ PRIMARY KEY (`a`)
+) TYPE=MyISAM
+alter table t9 rename t8, add column d int not null;
+alter table t8 rename t7;
+rename table t7 to t9;
+drop table t1;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+alter table t9 rename test_mysqltest.t9;
+select count(*) from test_mysqltest.t9;
+count(*)
+16724
+show create table test_mysqltest.t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` char(16) NOT NULL default '',
+ `c` int(11) NOT NULL default '0',
+ `d` int(11) NOT NULL default '0',
+ PRIMARY KEY (`a`)
+) TYPE=MyISAM
+drop database test_mysqltest;
diff --git a/mysql-test/r/tablelock.result b/mysql-test/r/tablelock.result
index 4fbeac979b1..2ffd8f928a9 100644
--- a/mysql-test/r/tablelock.result
+++ b/mysql-test/r/tablelock.result
@@ -1,12 +1,48 @@
+drop table if exists t1,t2;
+create table t1 ( n int auto_increment primary key);
+lock tables t1 write;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 read, t1 as t2 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 write, t1 as t2 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 write, t1 as t2 read, t1 as t3 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 write, t1 as t2 write;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+lock tables t1 write,t1 as b write, t2 write, t2 as c read;
+drop table t1,t2;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+lock tables t1 write,t1 as b write, t2 write, t2 as c read;
+drop table t2,t1;
+unlock tables;
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 12e76bba3f7..84a00bfea34 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -1,30 +1,74 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 (c int not null, d char (10) not null);
+insert into t1 values(1,""),(2,"a"),(3,"b");
+CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(4,"e"),(5,"f"),(6,"g");
+alter table t1 rename t2;
+select * from t1;
c d
1
2 a
3 b
+select * from t2;
a b
4 e
5 f
6 g
+CREATE TABLE t2 (x int not null, y int not null);
+alter table t2 rename t1;
+select * from t1;
a b
4 e
5 f
6 g
+create TEMPORARY TABLE t2 type=heap select * from t1;
+create TEMPORARY TABLE IF NOT EXISTS t2 (a int) type=heap;
+CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
+Table 't1' already exists
+ALTER TABLE t1 RENAME t2;
+Table 't2' already exists
+select * from t2;
a b
4 e
5 f
6 g
+alter table t2 add primary key (a,b);
+drop table t1,t2;
+select * from t1;
c d
1
2 a
3 b
+drop table t2;
+create temporary table t1 select *,2 as "e" from t1;
+select * from t1;
c d e
1 2
2 a 2
3 b 2
+drop table t1;
+drop table t1;
+drop table if exists t1;
+CREATE TABLE t1 (pkCrash INTEGER PRIMARY KEY,strCrash VARCHAR(255));
+INSERT INTO t1 ( pkCrash, strCrash ) VALUES ( 1, '1');
+SELECT CONCAT_WS(pkCrash, strCrash) FROM t1;
CONCAT_WS(pkCrash, strCrash)
1
+drop table t1;
+create temporary table t1 select 1 as 'x';
+drop table t1;
+CREATE TABLE t1 (x INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+CREATE TEMPORARY TABLE tmp SELECT *, NULL FROM t1;
+drop table t1;
+create temporary table t1 (id int(10) not null unique);
+create temporary table t2 (id int(10) not null primary key,
+val int(10) not null);
+insert into t1 values (1),(2),(4);
+insert into t2 values (1,1),(2,1),(3,1),(4,2);
+select one.id, two.val, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id;
id val elt(two.val,'one','two')
1 1 one
2 1 one
4 2 two
+drop table t1,t2;
diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result
index 716b38c57c7..e02797cc8e5 100644
--- a/mysql-test/r/truncate.result
+++ b/mysql-test/r/truncate.result
@@ -1,4 +1,22 @@
+create table t1 (a integer, b integer,c1 CHAR(10));
+insert into t1 (a) values (1),(2);
+truncate table t1;
+select count(*) from t1;
count(*)
0
+insert into t1 values(1,2,"test");
+select count(*) from t1;
count(*)
1
+delete from t1;
+select * from t1;
+a b c1
+drop table t1;
+select count(*) from t1;
+Table 'test.t1' doesn't exist
+create temporary table t1 (n int);
+insert into t1 values (1),(2),(3);
+truncate table t1;
+select * from t1;
+n
+drop table t1;
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index bc80ba38452..2047eed6227 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -1,5 +1,12 @@
+drop table if exists t1,t2,t3,t4,t5,t6,t7;
+create table t1 (nr int(5) not null auto_increment,b blob,str char(10), primary key (nr));
+insert into t1 values (null,"a","A");
+insert into t1 values (null,"bbb","BBB");
+insert into t1 values (null,"ccc","CCC");
+select last_insert_id();
last_insert_id()
3
+select * from t1,t1 as t2;
nr b str nr b str
1 a A 1 a A
2 bbb BBB 1 a A
@@ -10,54 +17,88 @@ nr b str nr b str
1 a A 3 ccc CCC
2 bbb BBB 3 ccc CCC
3 ccc CCC 3 ccc CCC
+drop table t1;
+create table t1 (a text);
+insert into t1 values ('where');
+update t1 set a='Where';
+select * from t1;
a
Where
+drop table t1;
+create table t1 (t text,c char(10),b blob, d char(10) binary);
+insert into t1 values (NULL,NULL,NULL,NULL);
+insert into t1 values ("","","","");
+insert into t1 values ("hello","hello","hello","hello");
+insert into t1 values ("HELLO","HELLO","HELLO","HELLO");
+insert into t1 values ("HELLO MY","HELLO MY","HELLO MY","HELLO MY");
+insert into t1 values ("a","a","a","a");
+insert into t1 values (1,1,1,1);
+insert into t1 values (NULL,NULL,NULL,NULL);
+update t1 set c="",b=null where c="1";
+lock tables t1 READ;
+show full fields from t1;
Field Type Null Key Default Extra Privileges
t text YES NULL select,insert,update,references
c varchar(10) YES NULL select,insert,update,references
b blob YES NULL select,insert,update,references
d varchar(10) binary YES NULL select,insert,update,references
+lock tables t1 WRITE;
+show full fields from t1;
Field Type Null Key Default Extra Privileges
t text YES NULL select,insert,update,references
c varchar(10) YES NULL select,insert,update,references
b blob YES NULL select,insert,update,references
d varchar(10) binary YES NULL select,insert,update,references
+unlock tables;
+select t from t1 where t like "hello";
t
hello
HELLO
+select c from t1 where c like "hello";
c
hello
HELLO
+select b from t1 where b like "hello";
b
hello
+select d from t1 where d like "hello";
d
hello
+select c from t1 having c like "hello";
c
hello
HELLO
+select d from t1 having d like "hello";
d
hello
+select t from t1 where t like "%HELLO%";
t
hello
HELLO
HELLO MY
+select c from t1 where c like "%HELLO%";
c
hello
HELLO
HELLO MY
+select b from t1 where b like "%HELLO%";
b
HELLO
HELLO MY
+select d from t1 where d like "%HELLO%";
d
HELLO
HELLO MY
+select c from t1 having c like "%HELLO%";
c
hello
HELLO
HELLO MY
+select d from t1 having d like "%HELLO%";
d
HELLO
HELLO MY
+select t from t1 order by t;
t
NULL
NULL
@@ -67,6 +108,7 @@ a
hello
HELLO
HELLO MY
+select c from t1 order by c;
c
NULL
NULL
@@ -76,6 +118,7 @@ a
hello
HELLO
HELLO MY
+select b from t1 order by b;
b
NULL
NULL
@@ -85,6 +128,7 @@ HELLO
HELLO MY
a
hello
+select d from t1 order by d;
d
NULL
NULL
@@ -94,6 +138,7 @@ HELLO
HELLO MY
a
hello
+select distinct t from t1;
t
NULL
@@ -101,6 +146,7 @@ hello
HELLO MY
a
1
+select distinct b from t1;
b
NULL
@@ -108,6 +154,7 @@ hello
HELLO
HELLO MY
a
+select distinct t from t1 order by t;
t
NULL
@@ -115,6 +162,7 @@ NULL
a
hello
HELLO MY
+select distinct b from t1 order by b;
b
NULL
@@ -122,6 +170,7 @@ HELLO
HELLO MY
a
hello
+select t from t1 group by t;
t
NULL
@@ -129,6 +178,7 @@ NULL
a
hello
HELLO MY
+select b from t1 group by b;
b
NULL
@@ -136,6 +186,8 @@ HELLO
HELLO MY
a
hello
+set option sql_big_tables=1;
+select distinct t from t1;
t
NULL
@@ -143,6 +195,7 @@ hello
HELLO MY
a
1
+select distinct b from t1;
b
NULL
@@ -150,6 +203,7 @@ hello
HELLO
HELLO MY
a
+select distinct t from t1 order by t;
t
NULL
@@ -157,6 +211,7 @@ NULL
a
hello
HELLO MY
+select distinct b from t1 order by b;
b
NULL
@@ -164,12 +219,14 @@ HELLO
HELLO MY
a
hello
+select distinct c from t1;
c
NULL
hello
HELLO MY
a
+select distinct d from t1;
d
NULL
@@ -178,12 +235,14 @@ HELLO
HELLO MY
a
1
+select distinct c from t1 order by c;
c
NULL
a
hello
HELLO MY
+select distinct d from t1 order by d;
d
NULL
@@ -192,12 +251,14 @@ HELLO
HELLO MY
a
hello
+select c from t1 group by c;
c
NULL
a
hello
HELLO MY
+select d from t1 group by d;
d
NULL
@@ -206,6 +267,8 @@ HELLO
HELLO MY
a
hello
+set option sql_big_tables=0;
+select distinct * from t1;
t c b d
NULL NULL NULL NULL
@@ -214,6 +277,7 @@ HELLO HELLO HELLO HELLO
HELLO MY HELLO MY HELLO MY HELLO MY
a a a a
1 NULL 1
+select t,count(*) from t1 group by t;
t count(*)
NULL 2
1
@@ -221,6 +285,7 @@ NULL 2
a 1
hello 2
HELLO MY 1
+select b,count(*) from t1 group by b;
b count(*)
NULL 3
1
@@ -228,12 +293,14 @@ HELLO 1
HELLO MY 1
a 1
hello 1
+select c,count(*) from t1 group by c;
c count(*)
NULL 2
2
a 1
hello 2
HELLO MY 1
+select d,count(*) from t1 group by d;
d count(*)
NULL 2
1
@@ -242,22 +309,142 @@ HELLO 1
HELLO MY 1
a 1
hello 1
+drop table t1;
+create table t1 (a text, key (a(300)));
+Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the table handler doesn't support unique sub keys
+create table t1 (a text, key (a(255)));
+drop table t1;
+CREATE TABLE t1 (
+t1_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+_field_72 varchar(128) DEFAULT '' NOT NULL,
+_field_95 varchar(32),
+_field_115 tinyint(4) DEFAULT '0' NOT NULL,
+_field_122 tinyint(4) DEFAULT '0' NOT NULL,
+_field_126 tinyint(4),
+_field_134 tinyint(4),
+PRIMARY KEY (t1_id),
+UNIQUE _field_72 (_field_72),
+KEY _field_115 (_field_115),
+KEY _field_122 (_field_122)
+);
+INSERT INTO t1 VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',0,1,NULL,NULL);
+INSERT INTO t1 VALUES (2,'hroberts','7415275a8c95952901e42b13a6b78566',0,1,NULL,NULL);
+INSERT INTO t1 VALUES (3,'guest','d41d8cd98f00b204e9800998ecf8427e',1,0,NULL,NULL);
+CREATE TABLE t2 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+PRIMARY KEY (seq_0_id,seq_1_id)
+);
+INSERT INTO t2 VALUES (1,1);
+INSERT INTO t2 VALUES (2,1);
+INSERT INTO t2 VALUES (2,2);
+CREATE TABLE t3 (
+t3_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+_field_131 varchar(128),
+_field_133 tinyint(4) DEFAULT '0' NOT NULL,
+_field_135 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+_field_137 tinyint(4),
+_field_139 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+_field_140 blob,
+_field_142 tinyint(4) DEFAULT '0' NOT NULL,
+_field_145 tinyint(4) DEFAULT '0' NOT NULL,
+_field_148 tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (t3_id),
+KEY _field_133 (_field_133),
+KEY _field_135 (_field_135),
+KEY _field_139 (_field_139),
+KEY _field_142 (_field_142),
+KEY _field_145 (_field_145),
+KEY _field_148 (_field_148)
+);
+INSERT INTO t3 VALUES (1,'test job 1',0,'0000-00-00 00:00:00',0,'1999-02-25 22:43:32','test\r\njob\r\n1',0,0,0);
+INSERT INTO t3 VALUES (2,'test job 2',0,'0000-00-00 00:00:00',0,'1999-02-26 21:08:04','',0,0,0);
+CREATE TABLE t4 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+PRIMARY KEY (seq_0_id,seq_1_id)
+);
+INSERT INTO t4 VALUES (1,1);
+INSERT INTO t4 VALUES (2,1);
+CREATE TABLE t5 (
+t5_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+_field_149 tinyint(4),
+_field_156 varchar(128) DEFAULT '' NOT NULL,
+_field_157 varchar(128) DEFAULT '' NOT NULL,
+_field_158 varchar(128) DEFAULT '' NOT NULL,
+_field_159 varchar(128) DEFAULT '' NOT NULL,
+_field_160 varchar(128) DEFAULT '' NOT NULL,
+_field_161 varchar(128) DEFAULT '' NOT NULL,
+PRIMARY KEY (t5_id),
+KEY _field_156 (_field_156),
+KEY _field_157 (_field_157),
+KEY _field_158 (_field_158),
+KEY _field_159 (_field_159),
+KEY _field_160 (_field_160),
+KEY _field_161 (_field_161)
+);
+INSERT INTO t5 VALUES (1,0,'tomato','','','','','');
+INSERT INTO t5 VALUES (2,0,'cilantro','','','','','');
+CREATE TABLE t6 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+PRIMARY KEY (seq_0_id,seq_1_id)
+);
+INSERT INTO t6 VALUES (1,1);
+INSERT INTO t6 VALUES (1,2);
+INSERT INTO t6 VALUES (2,2);
+CREATE TABLE t7 (
+t7_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+_field_143 tinyint(4),
+_field_165 varchar(32),
+_field_166 smallint(6) DEFAULT '0' NOT NULL,
+PRIMARY KEY (t7_id),
+KEY _field_166 (_field_166)
+);
+INSERT INTO t7 VALUES (1,0,'High',1);
+INSERT INTO t7 VALUES (2,0,'Medium',2);
+INSERT INTO t7 VALUES (3,0,'Low',3);
+select replace(t3._field_140, "\r","^M"),t3_id,min(t3._field_131), min(t3._field_135), min(t3._field_139), min(t3._field_137), min(link_alias_142._field_165), min(link_alias_133._field_72), min(t3._field_145), min(link_alias_148._field_156), replace(min(t3._field_140), "\r","^M"),t3.t3_id from t3 left join t4 on t4.seq_0_id = t3.t3_id left join t7 link_alias_142 on t4.seq_1_id = link_alias_142.t7_id left join t6 on t6.seq_0_id = t3.t3_id left join t1 link_alias_133 on t6.seq_1_id = link_alias_133.t1_id left join t2 on t2.seq_0_id = t3.t3_id left join t5 link_alias_148 on t2.seq_1_id = link_alias_148.t5_id where t3.t3_id in (1) group by t3.t3_id order by link_alias_142._field_166, _field_139, link_alias_133._field_72, _field_135, link_alias_148._field_156;
replace(t3._field_140, "\r","^M") t3_id min(t3._field_131) min(t3._field_135) min(t3._field_139) min(t3._field_137) min(link_alias_142._field_165) min(link_alias_133._field_72) min(t3._field_145) min(link_alias_148._field_156) replace(min(t3._field_140), "\r","^M") t3_id
test^M
job^M
1 1 test job 1 0000-00-00 00:00:00 1999-02-25 22:43:32 0 High admin 0 tomato test^M
job^M
1 1
+drop table t1,t2,t3,t4,t5,t6,t7;
+create table t1 (a blob);
+insert into t1 values ("empty"),("");
+select a,reverse(a) from t1;
a reverse(a)
empty ytpme
+drop table t1;
+create table t1 (a blob, key (a(10)));
+insert into t1 values ("bye"),("hello"),("hello"),("hello word");
+select * from t1 where a like "hello%";
a
hello
hello
hello word
+drop table t1;
+CREATE TABLE t1 (
+f1 int(11) DEFAULT '0' NOT NULL,
+f2 varchar(16) DEFAULT '' NOT NULL,
+f5 text,
+KEY index_name (f1,f2,f5(16))
+);
+INSERT INTO t1 VALUES (0,'traktor','1111111111111');
+INSERT INTO t1 VALUES (1,'traktor','1111111111111111111111111');
+select count(*) from t1 where f2='traktor';
count(*)
2
+drop table t1;
+create table t1 (foobar tinyblob not null, boggle smallint not null, key (foobar(32), boggle));
+insert into t1 values ('fish', 10),('bear', 20);
+select foobar, boggle from t1 where foobar = 'fish';
foobar boggle
fish 10
+select foobar, boggle from t1 where foobar = 'fish' and boggle = 10;
foobar boggle
fish 10
+drop table t1;
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index df8f0ee1814..214328eab47 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -1,24 +1,73 @@
+create table t1 (a char(16), b date, c datetime);
+insert into t1 SET a='test 2000-01-01', b='2000-01-01', c='2000-01-01';
+select * from t1 where c = '2000-01-01';
a b c
test 2000-01-01 2000-01-01 2000-01-01 00:00:00
+select * from t1 where b = '2000-01-01';
a b c
test 2000-01-01 2000-01-01 2000-01-01 00:00:00
+drop table t1;
+drop table if exists t1,t2;
+CREATE TABLE t1 (name char(6),cdate date);
+INSERT INTO t1 VALUES ('name1','1998-01-01');
+INSERT INTO t1 VALUES ('name2','1998-01-01');
+INSERT INTO t1 VALUES ('name1','1998-01-02');
+INSERT INTO t1 VALUES ('name2','1998-01-02');
+CREATE TABLE t2 (cdate date, note char(6));
+INSERT INTO t2 VALUES ('1998-01-01','note01');
+INSERT INTO t2 VALUES ('1998-01-02','note02');
+select name,t1.cdate,note from t1,t2 where t1.cdate=t2.cdate and t1.cdate='1998-01-01';
name cdate note
name1 1998-01-01 note01
name2 1998-01-01 note01
+drop table t1,t2;
+CREATE TABLE t1 ( datum DATE );
+INSERT INTO t1 VALUES ( "2000-1-1" );
+INSERT INTO t1 VALUES ( "2000-1-2" );
+INSERT INTO t1 VALUES ( "2000-1-3" );
+INSERT INTO t1 VALUES ( "2000-1-4" );
+INSERT INTO t1 VALUES ( "2000-1-5" );
+SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
datum
2000-01-02
2000-01-03
2000-01-04
+DROP TABLE t1;
+CREATE TABLE t1 (
+user_id char(10),
+summa int(11),
+rdate date
+);
+INSERT INTO t1 VALUES ('aaa',100,'1998-01-01');
+INSERT INTO t1 VALUES ('aaa',200,'1998-01-03');
+INSERT INTO t1 VALUES ('bbb',50,'1998-01-02');
+INSERT INTO t1 VALUES ('bbb',200,'1998-01-04');
+select max(rdate) as s from t1 where rdate < '1998-01-03' having s> "1998-01-01";
s
1998-01-02
+select max(rdate) as s from t1 having s="1998-01-04";
s
1998-01-04
+select max(rdate+0) as s from t1 having s="19980104";
s
19980104
+drop table t1;
+create table t1 (date date);
+insert into t1 values ("2000-08-10"),("2000-08-11");
+select date_add(date,INTERVAL 1 DAY),date_add(date,INTERVAL 1 SECOND) from t1;
date_add(date,INTERVAL 1 DAY) date_add(date,INTERVAL 1 SECOND)
2000-08-11 2000-08-10 00:00:01
2000-08-12 2000-08-11 00:00:01
+drop table t1;
+CREATE TABLE t1(AFIELD INT);
+INSERT INTO t1 VALUES(1);
+CREATE TABLE t2(GMT VARCHAR(32));
+INSERT INTO t2 VALUES('GMT-0800');
+SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1, t2 GROUP BY t1.AFIELD;
DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT))
Wed, 06 March 2002 10:11:12 GMT-0800
+INSERT INTO t1 VALUES(1);
+SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)), DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1,t2 GROUP BY t1.AFIELD;
DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT))
Wed, 06 March 2002 10:11:12 GMT-0800 Wed, 06 March 2002 10:11:12 GMT-0800
+drop table t1,t2;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index dd34bc1cf86..cae15d4f665 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -1,3 +1,7 @@
+drop table if exists t1;
+create table t1 (t datetime);
+insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959);
+select * from t1;
t
2000-01-01 00:00:00
2069-12-31 00:00:00
@@ -11,10 +15,15 @@ t
1999-12-31 23:59:59
1000-01-01 00:00:00
9999-12-31 23:59:59
+delete from t1 where t > 0;
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959");
+select * from t1;
t
2000-01-01 00:00:00
2069-12-31 00:00:00
@@ -29,14 +38,43 @@ t
1999-12-31 23:59:59
1000-01-01 00:00:00
9999-12-31 23:59:59
+drop table t1;
+CREATE TABLE t1 (a timestamp, b date, c time, d datetime);
+insert into t1 (b,c,d) values(now(),curtime(),now());
+select date_format(a,"%Y-%m-%d")=b,right(a,6)=c+0,a=d+0 from t1;
date_format(a,"%Y-%m-%d")=b right(a,6)=c+0 a=d+0
1 1 1
+drop table t1;
+CREATE TABLE t1 (a datetime not null);
+insert into t1 values (0);
+select * from t1 where a is null;
a
0000-00-00 00:00:00
+drop table t1;
+create table t1 (id int, dt datetime);
+insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00");
+select * from t1 where dt='2001-08-14 00:00:00' and dt = if(id=1,'2001-08-14 00:00:00','1999-08-15');
+id dt
+1 2001-08-14 00:00:00
+drop table t1;
+CREATE TABLE `t1` (
+`date` datetime NOT NULL default '0000-00-00 00:00:00',
+`numfacture` int(6) unsigned NOT NULL default '0',
+`expedition` datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (`numfacture`),
+KEY `date` (`date`),
+KEY `expedition` (`expedition`)
+) TYPE=MyISAM;
+INSERT INTO t1 (expedition) VALUES ('0001-00-00 00:00:00');
+SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
date numfacture expedition
0000-00-00 00:00:00 0 0001-00-00 00:00:00
+INSERT INTO t1 (numfacture,expedition) VALUES ('1212','0001-00-00 00:00:00');
+SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
date numfacture expedition
0000-00-00 00:00:00 0 0001-00-00 00:00:00
0000-00-00 00:00:00 1212 0001-00-00 00:00:00
+EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
table type possible_keys key key_len ref rows Extra
t1 ref expedition expedition 8 const 1 where used
+drop table t1;
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 82b7d155822..5623482aa7f 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -1,8 +1,164 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+id int(11) DEFAULT '0' NOT NULL auto_increment,
+datatype_id int(11) DEFAULT '0' NOT NULL,
+minvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL,
+maxvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL,
+valuename varchar(20),
+forecolor int(11),
+backcolor int(11),
+PRIMARY KEY (id),
+UNIQUE datatype_id (datatype_id, minvalue, maxvalue)
+);
+INSERT INTO t1 VALUES ( '1', '4', '0.0000000000', '0.0000000000', 'Ei saja', '0', '16776960');
+INSERT INTO t1 VALUES ( '2', '4', '1.0000000000', '1.0000000000', 'Sajab', '16777215', '255');
+INSERT INTO t1 VALUES ( '3', '1', '2.0000000000', '49.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '60', '11', '0.0000000000', '0.0000000000', 'Rikkis', '16777215', '16711680');
+INSERT INTO t1 VALUES ( '4', '12', '1.0000000000', '1.0000000000', 'nork sadu', '65280', '14474460');
+INSERT INTO t1 VALUES ( '5', '12', '2.0000000000', '2.0000000000', 'keskmine sadu', '255', '14474460');
+INSERT INTO t1 VALUES ( '6', '12', '3.0000000000', '3.0000000000', 'tugev sadu', '127', '14474460');
+INSERT INTO t1 VALUES ( '43', '39', '6.0000000000', '6.0000000000', 'lobjakas', '13107327', '16763080');
+INSERT INTO t1 VALUES ( '40', '39', '2.0000000000', '2.0000000000', 'vihm', '8355839', '16777215');
+INSERT INTO t1 VALUES ( '53', '1', '-35.0000000000', '-5.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '41', '39', '3.0000000000', '3.0000000000', 'külm vihm', '120', '16763080');
+INSERT INTO t1 VALUES ( '12', '21', '21.0000000000', '21.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '13', '21', '13.0000000000', '13.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '14', '21', '22.0000000000', '22.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '19', '21', '33.0000000000', '33.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '15', '21', '23.0000000000', '23.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '16', '21', '31.0000000000', '31.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '17', '21', '12.0000000000', '12.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '18', '21', '32.0000000000', '32.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '20', '21', '331.0000000000', '331.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '21', '21', '11.0000000000', '11.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '22', '33', '21.0000000000', '21.0000000000', 'Pilves, kuiv', '8355711', '12632256');
+INSERT INTO t1 VALUES ( '23', '33', '13.0000000000', '13.0000000000', 'Sajab, märg', '0', '8355839');
+INSERT INTO t1 VALUES ( '24', '33', '22.0000000000', '22.0000000000', 'Pilves, niiske', '8355711', '12632319');
+INSERT INTO t1 VALUES ( '29', '33', '33.0000000000', '33.0000000000', 'Selge, märg', '16777215', '8355839');
+INSERT INTO t1 VALUES ( '25', '33', '23.0000000000', '23.0000000000', 'Pilves, märg', '8355711', '8355839');
+INSERT INTO t1 VALUES ( '26', '33', '31.0000000000', '31.0000000000', 'Selge, kuiv', '16777215', '12632256');
+INSERT INTO t1 VALUES ( '27', '33', '12.0000000000', '12.0000000000', 'Sajab, niiske', '0', '12632319');
+INSERT INTO t1 VALUES ( '28', '33', '32.0000000000', '32.0000000000', 'Selge, niiske', '16777215', '12632319');
+INSERT INTO t1 VALUES ( '30', '33', '331.0000000000', '331.0000000000', 'Härmatis! selge,kuiv', '16711680', '12632256');
+INSERT INTO t1 VALUES ( '31', '33', '11.0000000000', '11.0000000000', 'Sajab, kuiv', '0', '12632256');
+INSERT INTO t1 VALUES ( '32', '11', '1.0000000000', '1.0000000000', 'Korras', '16777215', '49152');
+INSERT INTO t1 VALUES ( '33', '21', '335.0000000000', '335.0000000000', 'Härmatis!', '14448840', '11842740');
+INSERT INTO t1 VALUES ( '34', '21', '134.0000000000', '134.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '35', '21', '133.0000000000', '133.0000000000', 'Hoiatus, märg!', '5263615', '13158600');
+INSERT INTO t1 VALUES ( '36', '21', '135.0000000000', '135.0000000000', 'Härmatis!', '14448840', '11842740');
+INSERT INTO t1 VALUES ( '37', '21', '334.0000000000', '334.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '38', '21', '132.0000000000', '132.0000000000', 'Hoiatus, niiske!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '39', '39', '1.0000000000', '1.0000000000', 'ei saja', '11206570', '16777215');
+INSERT INTO t1 VALUES ( '44', '39', '4.0000000000', '5.0000000000', 'lumi', '16711680', '16763080');
+INSERT INTO t1 VALUES ( '45', '12', '0.0000000000', '0.0000000000', '', '16777215', '14474460');
+INSERT INTO t1 VALUES ( '46', '39', '8.0000000000', '8.0000000000', 'rahe', '9830400', '16763080');
+INSERT INTO t1 VALUES ( '47', '39', '9.0000000000', '9.0000000000', 'tüüp ebaselge', '12582912', '16777215');
+INSERT INTO t1 VALUES ( '48', '39', '7.0000000000', '7.0000000000', 'lumetuisk', '7209070', '16763080');
+INSERT INTO t1 VALUES ( '142', '15', '2.0000000000', '49.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '52', '1', '-4.9000000000', '-0.1000000000', '', '0', '15774720');
+INSERT INTO t1 VALUES ( '141', '15', '-4.9000000000', '-0.1000000000', '', '0', '15774720');
+INSERT INTO t1 VALUES ( '55', '8', '0.0000000000', '0.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '56', '8', '0.0100000000', '0.1000000000', '', '0', '16770560');
+INSERT INTO t1 VALUES ( '57', '8', '0.1100000000', '25.0000000000', '', '0', '15774720');
+INSERT INTO t1 VALUES ( '58', '2', '90.0000000000', '94.9000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '59', '6', '0.0000000000', '360.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '61', '21', '38.0000000000', '38.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '62', '38', '500.0000000000', '999.0000000000', '', '0', '16770560');
+INSERT INTO t1 VALUES ( '63', '38', '1000.0000000000', '2000.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '64', '17', '0.0000000000', '0.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '65', '17', '0.1000000000', '10.0000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '67', '21', '412.0000000000', '412.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '68', '21', '413.0000000000', '413.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '69', '21', '113.0000000000', '113.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '70', '21', '416.0000000000', '416.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '71', '38', '0.0000000000', '499.0000000000', '', NULL, '16711680');
+INSERT INTO t1 VALUES ( '72', '22', '-49.0000000000', '49.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '73', '13', '0.0000000000', '9.9000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '74', '13', '10.0000000000', '14.9000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '75', '7', '0.0000000000', '50.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '76', '18', '0.0000000000', '0.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '77', '18', '0.1000000000', '10.0000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '78', '19', '300.0000000000', '400.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '79', '19', '0.0000000000', '299.0000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '80', '23', '0.0000000000', '100.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '81', '24', '0.0000000000', '200.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '82', '26', '0.0000000000', '0.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '83', '26', '0.1000000000', '5.0000000000', '', NULL, '16776960');
+INSERT INTO t1 VALUES ( '84', '21', '422.0000000000', '422.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '85', '21', '411.0000000000', '411.0000000000', 'Saju hoiat.,kuiv!', '16777215', '13158600');
+INSERT INTO t1 VALUES ( '86', '21', '423.0000000000', '423.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '144', '16', '-49.0000000000', '-5.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '88', '16', '2.0000000000', '49.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '89', '21', '338.0000000000', '338.0000000000', 'Härm.hoiatus, N+S!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '90', '21', '332.0000000000', '332.0000000000', 'Härm.hoiat., niiske!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '91', '21', '114.0000000000', '114.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '92', '21', '117.0000000000', '117.0000000000', 'Hoiatus, JÄÄ!', '14448840', '16711680');
+INSERT INTO t1 VALUES ( '93', '21', '116.0000000000', '116.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '94', '21', '414.0000000000', '414.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '95', '21', '325.0000000000', '325.0000000000', 'Härmatis!', '14448840', '11842740');
+INSERT INTO t1 VALUES ( '96', '21', '321.0000000000', '321.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '97', '21', '328.0000000000', '328.0000000000', 'Härm.hoiatus, N+S!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '98', '21', '28.0000000000', '28.0000000000', 'Niiske ja sool', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '99', '21', '118.0000000000', '118.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '100', '21', '418.0000000000', '418.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '101', '21', '322.0000000000', '322.0000000000', 'Härm.hoiat., niiske!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '102', '21', '428.0000000000', '428.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '103', '21', '432.0000000000', '432.0000000000', 'Hoiatus, niiske!', '7895240', '13158600');
+INSERT INTO t1 VALUES ( '104', '21', '421.0000000000', '421.0000000000', 'Saju hoiat.,kuiv!', '16777215', '13158600');
+INSERT INTO t1 VALUES ( '105', '21', '24.0000000000', '24.0000000000', 'Märg ja sool', '255', '16777215');
+INSERT INTO t1 VALUES ( '106', '21', '438.0000000000', '438.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '107', '21', '112.0000000000', '112.0000000000', 'Hoiatus, niiske!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '108', '21', '34.0000000000', '34.0000000000', 'Märg ja sool', '255', '16777215');
+INSERT INTO t1 VALUES ( '109', '21', '434.0000000000', '434.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '110', '21', '124.0000000000', '124.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '111', '21', '424.0000000000', '424.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '112', '21', '123.0000000000', '123.0000000000', 'Hoiatus, märg!', '5263615', '13158600');
+INSERT INTO t1 VALUES ( '140', '15', '-49.0000000000', '-5.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '114', '21', '18.0000000000', '18.0000000000', 'Niiske ja sool', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '115', '21', '122.0000000000', '122.0000000000', 'Hoiatus, niiske!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '116', '21', '14.0000000000', '14.0000000000', 'Märg ja sool', '255', '16777215');
+INSERT INTO t1 VALUES ( '117', '21', '311.0000000000', '311.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '121', '2', '95.0000000000', '100.0000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '118', '2', '0.0000000000', '89.9000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '119', '21', '16.0000000000', '16.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '120', '21', '26.0000000000', '26.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '122', '13', '15.0000000000', '50.0000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '123', '5', '0.0000000000', '9.9000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '124', '5', '10.0000000000', '14.9000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '125', '5', '15.0000000000', '50.0000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '126', '21', '128.0000000000', '128.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '127', '21', '318.0000000000', '318.0000000000', 'Härm.hoiatus, N+S!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '128', '21', '312.0000000000', '312.0000000000', 'Härm.hoiat., niiske!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '129', '21', '126.0000000000', '126.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '130', '21', '324.0000000000', '324.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '131', '21', '316.0000000000', '316.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '132', '1', '0.0000000000', '1.9000000000', '', NULL, '16769024');
+INSERT INTO t1 VALUES ( '134', '3', '-50.0000000000', '50.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '135', '8', '26.0000000000', '2000.0000000000', '', '9868950', '15774720');
+INSERT INTO t1 VALUES ( '136', '21', '426.0000000000', '426.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '137', '21', '127.0000000000', '127.0000000000', 'Hoiatus, JÄÄ!', '14448840', '16711680');
+INSERT INTO t1 VALUES ( '138', '21', '121.0000000000', '121.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '139', '21', '326.0000000000', '326.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '143', '16', '-4.9000000000', '-0.1000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '145', '15', '0.0000000000', '1.9000000000', '', '0', '16769024');
+INSERT INTO t1 VALUES ( '146', '16', '0.0000000000', '1.9000000000', '', '0', '16769024');
+select * from t1 where minvalue<=1 and maxvalue>=-1 and datatype_id=16;
id datatype_id minvalue maxvalue valuename forecolor backcolor
143 16 -4.9000000000 -0.1000000000 NULL 15774720
146 16 0.0000000000 1.9000000000 0 16769024
+select * from t1 where minvalue<=-1 and maxvalue>=-1 and datatype_id=16;
id datatype_id minvalue maxvalue valuename forecolor backcolor
143 16 -4.9000000000 -0.1000000000 NULL 15774720
+drop table t1;
+create table t1 (a decimal(10,2));
+insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
+insert into t1 values ("-.1"),("+.1"),(".1");
+insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
+insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
+insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
+select * from t1;
a
0.00
-0.00
@@ -22,6 +178,24 @@ a
-99999999.99
999999999.99
999999999.99
+999999999.99
+0.00
+-99999999.99
+123.40
+12340.00
+1.23
+1230.00
+123.00
+drop table t1;
+create table t1 (a decimal(10,2) unsigned);
+insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
+insert into t1 values ("-.1"),("+.1"),(".1");
+insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
+insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
+insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
+select * from t1;
a
0.00
0.00
@@ -41,6 +215,24 @@ a
0.00
99999999.99
99999999.99
+99999999.99
+0.00
+0.00
+123.40
+12340.00
+1.23
+1230.00
+123.00
+drop table t1;
+create table t1 (a decimal(10,2) zerofill);
+insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
+insert into t1 values ("-.1"),("+.1"),(".1");
+insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
+insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
+insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
+select * from t1;
a
00000000.00
00000000.00
@@ -60,6 +252,24 @@ a
00000000.00
99999999.99
99999999.99
+99999999.99
+00000000.00
+00000000.00
+00000123.40
+00012340.00
+00000001.23
+00001230.00
+00000123.00
+drop table t1;
+create table t1 (a decimal(10,2));
+insert into t1 values (0.0),("-0.0"),(+0.0),(01.0),(+01.0),(-01.0);
+insert into t1 values (-.1),(+.1),(.1);
+insert into t1 values (00000000000001),(+0000000000001),(-0000000000001);
+insert into t1 values (+111111111.11),(111111111.11),(-11111111.11);
+insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11);
+insert into t1 values (1e+1000),(1e-1000),(-1e+1000);
+insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0);
+select * from t1;
a
0.00
-0.00
@@ -79,6 +289,18 @@ a
-99999999.99
999999999.99
999999999.99
+999999999.99
+0.00
+-99999999.99
+123.40
+12340.00
+1.23
+1230.00
+123.00
+drop table t1;
+create table t1 (a decimal);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+12345678901'),(99999999999999);
+select * from t1;
a
-9999999999
-1
@@ -87,6 +309,10 @@ a
+0000000001
12345678901
99999999999
+drop table t1;
+create table t1 (a decimal unsigned);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
+select * from t1;
a
0
0
@@ -95,6 +321,10 @@ a
0000000001
1234567890
9999999999
+drop table t1;
+create table t1 (a decimal zerofill);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
+select * from t1;
a
0000000000
0000000000
@@ -103,6 +333,10 @@ a
0000000001
1234567890
9999999999
+drop table t1;
+create table t1 (a decimal unsigned zerofill);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
+select * from t1;
a
0000000000
0000000000
@@ -111,3 +345,4 @@ a
0000000001
1234567890
9999999999
+drop table t1;
diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result
index 35e27f6dd9e..ee3bd077798 100644
--- a/mysql-test/r/type_enum.result
+++ b/mysql-test/r/type_enum.result
@@ -1,3 +1,10 @@
+DROP TABLE if exists t1;
+CREATE TABLE t1 (
+field enum('001001','001004','001010','001018','001019','001020','001021','001027','001028','001029','001030','001031','001100','002003','002004','002005','002007','002008','002009','002012','002013','002014','003002','003003','003004','003005','003006','003007','003008','003009','003010','003011','003012','003013','003014','003015','003016','003017','003018','003019','004002','004003','004005','004006','004007','004008','004010','004012','004014','004016','004017','004020','004021','004022','004023','004024','004025','004026','006002','006004','006006','006010','006011','006012','006013','006014','007001','007002','007003','007004','007005','007006','007007','007008','007009','007010','007011','007012','007013','007014','007015','007016','007017','007018','007019','007020','007021','007022','007023','007024','007025','007026','007027','007028','007029','007030','007031','007032','007033','007034','007035','007036','007037','007038','007039','007040','007043','007044','009001','009002','009004','009005','009006','009007','009008','009009','009010','009011','009012','009013','010002','010003','010004','010005','010006','010007','010008','010009','010010','010011','010012','010013','010015','010016','010017','010018','010019','010020','010021','010022','010023','010024','010025','010026','010027','010028','011001','011002','011003','011004','011006','011012','011013','011014','011015','011016','012017','012018','012019','012023','012027','012028','012029','012030','012031','012032','012033','012034','012035','012036','012037','012038','012039','014001','016002','016003','016004','016007','016010','016011','016016','016019','016020','016021','016022','016023','016024','016026','016027','016028','016029','016030','016031','016032','016033','016034','017002','018001','019002','019004','020001','020003','020004','020005','020006','020007','020008','020009','022001','022002','022003','023001','023002','023003','023004','023005','023006','023007','023008','023010','023011','023012','023017','023019','023020','023021','023025','023026','023027','023028','023029','023030','023031','023032','023033','023034','023035','025001','025003','025004','025005','025006','025007','025008','025009','025010','025011','025012','025013','025014','025015','025016','025017','025018','025019','025020','025021','025022','025023','025024','025025','025026','025027','025028','025029','025030','025031','025032','025033','025034','025035','025036','025037','025038','025039','025040','025041','025042','025043','025044','025045','025046','025047','025048','025049','025050','025051','025052','025053','025054','025055','025056','025057','025058','025059','025060','025061','025062','025063','027001','027002','027011','035008','035012','036001','037001','037003','037004','037005','037006','037007','037008','037009','038004','038005','038006','038007','038009','039001','039002','039003','039004','039005','039006','046001','046002','046003','046004','046005','046007','046008','046009','046010','046011','046012','046013','046014','047001','047002','048001','051001','051002','051003','051004','052001','052002','052005','053015','053016','053019','053020','053023','053024','053026','053028','053029','053033','053034','053036','053037','053038','053039','053041','053042','053043','053045','053046','053047','053048','053051','053052','053054','053055','053056','053057','053068','053069','053070','053073','053074','053075','053086','053094','053095','053096','053097','053098','053099','053100','053101','053102','053103','053104','053105','053107','053122','053123','053124','053125','053127','053128','054001','054002','054003','054004','054005','054006','054007','054009','054010','056001','056002','056003','056004','056005','056006','056009','056010','056011','056016','056017','056018','056019','056020','056021','056022','057001','057002','057003','057004','058002','058003','058004','058005','060001','060003','060004','060005','060006','060007','061002','061003','061004','061005','061006','069006','069007','069010','069011','069012','069013','069014','069015','069016','069017','069018','069020','069021','069022','069023','069024','071002','071003','071004','071005','071006','071008','071011','071013','071020','071021','071022','072001','073001','073002','073003','073004','074001','074002','074003','074004','074005','074006','074007','074008','074009','074010','074011','074012','075001','075007','076101','076102','076103','077001','077002','077003','077004','077006','077007','077008','077009','078005','079002','079003','079004','079005','079006','079007','081001','082006','082007','082011','082013','082014','082015','082016','082017','082021','082022','082023','082024','082025','082026','082027','082028','082029','082030','082031','082032','082033','082034','082035','082036','082037','082038','082039','082040','082041','082042','082043','082044','084001','084002','084003','084004','084005','084007','084008','084009','084011','084013','084014','084016','084017','084027','084031','084032','084033','084035','084036','084037','084038','084039','084040','084041','084042','084043','084044','084045','084046','084047','084048','084049','084050','084051','085001','085002','085003','085004','085005','085006','085007','085009','085011','085012','085013','085014','085015','085016','085017','085018','085019','085020','085021','085022','085023','085028','085029','085030','085031','085033','085034','085035','085036','085037','085038','085040','085041','085042','085043','085044','085045','085046','085047','085048','085063','085064','085065','085068','085070','085071','085073','085082','085083','085086','085088','085089','085090','085091','085092','085093','085094','085095','085096','085097','085098','085099','085100','085101','085102','085103','085104','085105','085106','085107','085108','085109','085110','085111','085112','085113','085115','085119','085120','085121','085122','085123','085124','085125','085126','085127','085128','085129','085130','085132','085133','085134','085135','085136','085137','086001','086002','086003','086004','086005','088001','088003','088005','088006','088007','088008','088009','089001','090001','090002','090003','090004','090005','090006','090007','090008','090009','090010','090013','090015','090016','090017','090018','090019','090022','090027','090028','091001','091002','091005','091008','091009','091010','091011','091012','091013','091014','091015','091016','091017','091018','093001','093003','093098','093100','093102','093104','093141','093142','093146','093151','093153','093167','093168','093176','094001','094002','094004','094005','095004','099001','099002','100001','101001','102002','102003','105001','105002','106001','113001','113002','113003','113004','113005','113006','113007','113008','113009','113010','113011','113012','113013','113014','113015','113016','113017','113018','113019','113020','113021','113022','113023','113024','113025','113026','113027','113028','114001','115001','115002','115003','115004','115005','115006','115007','115008','115009','115010','115011','115012','115013','115014','115015','115016','115017','115018','115020','115021','115022','115023','115025','115026','115027','115028','115029','115030','115031','115032','115033','115034','115035','115036','115039','115040','115041','115042','115043','115044','115045','115046','115047','115048','115049','115050','115051','115052','115053','115054','115055','115056','115057','115059','115060','115061','115062','115063','115064','115065','115066','115067','115068','115069','115070','115071','115072','115073','115075','115076','115081','115082','115085','115086','115087','115088','115095','115096','115097','115098','115099','115101','115102','115103','115104','115105','115106','115108','115109','115110','115111','115112','115113','115114','115115','115116','115117','115118','115119','115120','115121','115122','116001','116002','116003','116004','116005','116006','116007','116008','116009','116010','116011','116012','117001','117002','117003','123001','124010','124014','124015','124019','124024','124025','124026','124027','124028','124029','124030','124031','124032','124033','124035','124036','124037','124038','124039','124040','124041','124042','124043','124044','124045','124046','124047','124048','124049','124050','124051','124052','124053','124054','124055','124056','124057','124058','124059','124060','124061','124062','124063','124064','124065','126001','126002','126003','126004','126005','126006','126007','126008','126009','126010','126011','126012','130001','132001','132002','132003','133001','133008','133009','133010','133011','133012','133013','133014','133015','133016','133017','133018','133019','133020','133021','133022','133023','133024','133025','133027','133028','133029','133030','133031','134001','135001','135002','135003','135004','135005','135006','135007','135008','135009','135010','136001','137009','137010','137011','137012','137013','137014','137015','137016','137017','137018','137019','138001','138002','138003','138004','139001','139003','140001','141001','141002','141003','141006','141007','141008','141009','141011','141012','141014','141015','141016','141017','141018','141019','141020','141021','141022','141023','141024','141025','141026','141027','141028','142001','142002','142003','142004','142005','142006','142007','142008','142010','142011','142012','144001','145001','145002','145003','145004','145005','145006','145007','145008','145009','145010','145011','145012','145013','145014','145015','145016','147001','150003','150005','150009','150013','150014','150015','150016','150017','150020','150021','152001','152002','152003','152004','152005','152006','152007','154001','154002','154003','155001','155002','155003','155004','155005','155006','159001','159002','159003','159004','160001','160002','160003','161001','162001','162002','162003','162004','162007','162010','162011','162012','163001','163002','163003','163005','163010','163011','163014','163015','163016','165001','165002','165003','165004','165005','165006','165007','165008','165009','165010','165011','165012','165013','165014','165015','165016','165017','165018','165019','165020','165021','165022','165023','165024','165025','165026','165027','165028','165029','165030','165031','165032','165033','165034','165035','165036','167001','168001','168002','168003','168004','168005','168007','168008','168009','168010','168011','168012','168013','168014','169001','169002','169003','169007','169008','169009','169010','170001','171001','171002','171003','171004','171005','171006','171007','171008','171009','172001','174001','174002','174003','176001','176002','176003','177001','177002','179001','179002','179003','179004','179005','179006','179007','179008','179009','179010','179011','179012','179013','179014','179015','179016','179017','179018','179019','179020','179021','179022','179023','179024','179025','179026','179027','179028','179029','179030','179031','179032','179033','179034','179035','179036','179037','179038','179039','179040','179041','179042','179043','179044','179045','179046','179047','180001','180010','180012','180013','180014','180015','180016','180017','180018','180019','180020','180021','180022','180023','180024','180025','180026','180027','180028','180030','180031','180032','180033','180034','180035','180036','180037','180038','180039','180041','180042','180043','180044','180045','180046','180047','180048','180049','180050','180051','180052','180053','180054','180055','180056','180057','180058','180059','180060','180061','180062','180063','180064','180065','180066','180067','180068','180069','180070','180071','182001','184001','184002','184005','184006','184007','184008','184009','184010','184011','185001','185003','187001','188001','188002','188003','188004','188005','188006','188007','188008','188009','188010','188011','191001','191002','192002','194001','194002','194003','194004','194005','194006','194007','195001','195002','195003','195004','195005','195006','195007','196001','196002','197001','197002','197003','197004','197005','197006','198001','198003','198004','198005','198006','198007','198008','198009','198010','198011','198012','198013','198014','198015','198016','198017','201001','201002','201005','202001','203001','203002','203003','203017','203018','203019','204001','204002','204003','205001','208001','208002','208003','208004','208005','209001','209002','209003','210001','210002','210003','210004','210005','210006','210007','210008','210009','210010','210011','210012','210013','211017','212001','212002','212003','212004','212005','212006','212007','212008','212009','212010','212011','212012','212013','218001','218003','218004','218006','218007','218008','218009','218011','218015','218016','218017','218018','218019','218020','218021','218022','218023','218024','218025','218026','218027','218028','218029','218030','218031','218032','218033','218034','218035','218036','221001','221002','221003','221004','221005','221006','221007','221008','221009','221010','221011','221012','221013','223001','223002','223003','224001','224002','224003','224006','224007','224008','225001','225002','225003','225004','225005','225006','225007','225008','225009','225010','225011','225012','225013','226001','226002','226003','226004','226005','226006','226007','226008','226009','227001','227002','227003','227004','227005','227006','227007','227008','227009','227010','227011','227012','227013','227014','227015','227016','227017','227018','227019','227020','227021','227022','227023','227024','227025','227026','227027','227028','227029','227030','227031','227032','227033','227034','227035','227036','227037','227038','227039','227040','227041','227042','227043','227044','227045','227046','227047','227048','227049','227050','227051','227052','227053','227054','227055','227056','227057','227058','227059','227060','227061','227062','227063','227064','227065','227066','227067','227068','227069','227070','227071','227072','227073','227074','227075','227076','227077','227078','227079','227080','227081','227082','227083','227084','227085','227086','227087','227088','227089','227090','227091','227092','227093','227094','227095','227096','227097','227098','227099','227100','227101','227102','227103','227104','227105','227106','227107','227108','227109','227110','227111','227112','227113','227114','227115','227116','227117','227118','227119','227120','227122','227123','227124','227125','227126','227127','227128','227129','227130','227131','227132','227133','227134','227135','227136','227137','227138','227139','227140','227141','227142','227143','227144','227145','227146','227147','227148','227149','227150','227151','227152','228001','229001','229002','229003','229004','229005','230001','230002','232001','233001','233002','233003','233004','233005','233006','233007','233008','234001','234002','234003','234004','234005','234006','234007','234008','234009','234010','234011','234012','234013','234014','234015','234016','234017','234018','234019','234020','234021','234022','234023','234024','234025','234026','234027','234028','234029','234030','235001','235002','235003','235004','235005','236001','236002','236003','237001','238002','238003','238004','238005','238006','238007','238008','333013','333014','333015','333016','333017','333018','333019','333020','333021','333022','333023','333024','333025','333030','333031','333032','333033','333034','333035','334001','334002','334003','334004','334005','334006','334007','336004','337001','337002','337003','337004','339001','339002','343001','344001','344002','344003','344004','344005','345001','345002','345003','347001','347002','348001','348002','348003','348004','348005','349001','349002','349003','350001','353001','353002','353003','353004','355001','355002','355003','355004','355005','355006','356001','358001','359001','359002','360001','360002','360003','360004','360005','366001','366002','366003','366004','369001','373001','373002','373003','373004','373005','373006','373007','373008','373009','373010','373011','373012','373013','373014','373015','373016','373017','373018','373019','373020','373021','374001','374002','374003','374004','374005','374006','374007','374008','374009','374010','374011','374012','374013','374014','374015','374016','376001','376002','376003','376004','376005','376006','376007','376008','376009','376010','376011','376012','376013','376016','376017','376018','376019','376020','376021','379003','382001','382002','383001','384001','384002','385001','385002','386001','386002','386003','386004','386005','386006','386007','386008','386009','386010','386011','386012','386013','386014','387001','389001','389002','389003','389004','392001','393001','393002','393003','393004','395001','396001','397001','397002','399001','399002','399003','400001','400002','401001','401002','401003','402001','402002','402003','402004','402005','403001','403002','403003','504001','504002','504004','504005','504006','504007','504008','504009','504010','504011','504012','504013','504014','504017','504018','504019','504021','504022','504023','504024','504025','506001','506002','508001','508002','511001','511002','511003','511004','511005','511006','511007','511008','511009','511010','511011','511012','511013','511014','511017','511018','511020','511021','511022','511024','511028','511029','513001','513002','513003','513004','514001','515001','515002','515003','515007','515008','515009','515010','515011','515012','515013','515014','515015','518001','518002','518003','520001','520002','521001','521002','521003','521004','521005','521006','521007','521008','521009','521010','521011','521012','521013','521014','521015','521016','523001','523002','523003','523004','523005','523006','523007','524001','700001','701001','701002','701003','702001','702002','702003','702004','702005','702006','702007','702008','703001','703002','703003','704001','704002','704003','704004','705001','706001','706002','707001','707002','707003','708001','709001','709002','710001','710002','711001','711002','712001','713001','713002','714001','714002','715001','716001','718001','718002','719001','719002','991001','991002','991003','991004','991005','991006','991007','991008','992001','995001','996001','996002','996003','998001','998002','998003','998004','998005','998006','998007','999001','999002','011017','011018','034001','034002','071010','208006','239001','519001','519003','126013','184012','053071','374017','374018','374019','374020','374021','404001','405002','405001','405003','405007','405006','405005','405004','240011','240010','240009','240008','240007','240006','240005','240004','240003','240002','240001','240012','240013','240014','240015','240016','240017','357001','235006','235007','712002','355008','355007','056023','999999','046015','019005','126014','241003','241002','241001','240018','240020','240019','242001','242002','242003','242004','242005','242006','089002','406001','406002','406003','406004','406005','406006','243001','243002','243003','243004','243005','243006','243007','243008','010030','010029','407001','407006','407005','407004','407003','407002','408001','366005','133032','016035','077010','996004','025064','011019','407007','407008','407009','409001','115123','504026','039007','039009','039008','039010','039011','039012','180072','240021','240023','408002','405008','235008','525001','525002','525003','525004','410001','410002','410003','410004','410005','410006','410007','410008','410009','410010','410011','410012','410013','410014','410015','410016','344006','240031','240030','240029','240028','240027','240026','240025','240024','240034','240033','240032','410017','410018','411001','411002','411003','411004','411005','411006','411007','411008','203020','203021','203022','412001','412002','412003','412004','069025','244001','244002','244009','244008','244007','244006','244005','244004','244003','244015','244014','244013','244012','244011','244010','244016','244017','240042','240041','240040','240039','240038','240037','240036','240035','405009','405010','240043','504034','504033','504032','504031','504030','504029','504028','504027','504042','504041','504040','504039','504038','504037','504036','504035','800001','410019','410020','410021','244018','244019','244020','399004','413001','504043','198018','198019','344007','082045','010031','010032','010033','010034','010035','504044','515016','801002','801003','801004','801005','802001','801001','414001','414002','414003','141029','141030','803001','803002','803003','803004','803005','803006','803007','803008','803009','803010','803011','803012','803013','803014','803015','803016','803017','410022','410023','803018','803019','803020','415002','415001','244021','011020','011023','011022','011021','025065','165037','165038','165039','416001','416002','416003','417001','418001','504045','803022','803021','240022','419001','420001','804010','804009','804008','804007','804006','804005','804004','804003','804002','804001','804020','804019','804018','804017','804016','804015','804014','804013','804012','804011','804024','804021','804023','804022','511019','511016','511015','511032','511031','511030','511027','511026','511025','511033','511023','133034','133033','169011','344008','344009','244022','244026','244025','244030','244023','244024','244027','244028','244029','244031','082046','082047','082048','126015','126016','416004','416005','421001','421002','016037','016036','115124','115125','115126','240049','240048','240047','240046','240045','240044','244032','244033','422001','422002','422003','422004','422005','184013','239002','805001','805002','805003','805004','805005','056024','423001','344010','235009','212014','056025','056026','802002','244034','244035','244036','244037','244038','244039','515017','504046','203015','245002','245001','071023','056027','056028','056029','056030','056031','056032','424001','056034','056033','805006','805007','805008','805009','805010','422008','422007','422006','422010','422009','422011','209004','150022','150023','100002','056035','023036','185004','185005','246001','247001','247002','425001','416006','165042','165041','165040','165043','010040','010039','010038','010037','010036','422012','422013','422014','422015','426000','248001','248002','248003','248004','248005','249001','249002','249003','249004','249005','249006','250007','250001','250002','250003','250004','250005','250006','250008','250009','250010','250011','250012','250013','251001','251002','422016','422017','422018','806001','806002','116013','235010','235011','091026','091027','091028','091029','091019','091020','091021','091022','091023','091024','091025','252001','243009','249007','249008','249009','011024','011025','427001','428002','428001','169012','429001','429002','429003') DEFAULT '001001' NOT NULL,
+KEY field (field)
+);
+INSERT INTO t1 VALUES ('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001010'),('001010'),('001010'),('001010'),('001010'),('001018'),('001018'),('001018'),('001018'),('001018'),('001018'),('001020'),('001020'),('001020'),('001020'),('001020'),('001020'),('001020'),('001020'),('001021'),('001021'),('001021'),('001021'),('001021'),('001021'),('001027'),('001027'),('001028'),('001030'),('001030'),('001030'),('001030'),('001031'),('001031'),('001031'),('001031'),('001031'),('001100'),('001100'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002005'),('002005'),('002005'),('002005'),('002005'),('002005'),('002005'),('002005'),('002007'),('002007'),('002007'),('002007'),('002007'),('002007'),('002007'),('002008'),('002008'),('002008'),('002008'),('002008'),('002008'),('002008'),('002008'),('002009'),('002009'),('002009'),('002009'),('002009'),('002009'),('002009'),('002009'),('002012'),('002012'),('002012'),('002012'),('002012'),('002012'),('002012'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002014'),('002014'),('002014'),('002014'),('002014'),('002014'),('002014'),('002014'),('003002'),('003002'),('003002'),('003002'),('003002'),('003002'),('003003'),('003003'),('003003'),('003003'),('003003'),('003003'),('003004'),('003004'),('003004'),('003004'),('003004'),('003004'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003006'),('003006'),('003006'),('003006'),('003006'),('003006'),('003006'),('003006'),('003007'),('003007'),('003007'),('003007'),('003007'),('003008'),('003008'),('003008'),('003008'),('003008'),('003008'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003011'),('003011'),('003011'),('003011'),('003011'),('003011'),('003011'),('003011'),('003012'),('003012'),('003012'),('003012'),('003012'),('003012'),('003012'),('003012'),('003013'),('003013'),('003013'),('003013'),('003013'),('003013'),('003013'),('003013'),('003014'),('003014'),('003014'),('003014'),('003014'),('003014'),('003014'),('003014'),('003015'),('003015'),('003015'),('003015'),('003015'),('003015'),('003016'),('003016'),('003016'),('003016'),('003016'),('003016'),('003017'),('003017'),('003017'),('003017'),('003017'),('003018'),('003018'),('003018'),('003018'),('003018'),('003019'),('003019'),('004003'),('004005'),('004005'),('004005'),('004005'),('004005'),('004005'),('004006'),('004008'),('004010'),('004012'),('004012'),('004014'),('004014'),('004014'),('004014'),('004014'),('004016'),('004017'),('004017'),('004017'),('004017'),('004017'),('004017'),('004017'),('004017'),('004020'),('004020'),('004020'),('004020'),('004020'),('004020'),('004021'),('004021'),('004021'),('004021'),('004021'),('004021'),('004021'),('004022'),('004023'),('004023'),('004023'),('004023'),('004023'),('004023'),('004023'),('004025'),('004026'),('004026'),('004026'),('004026'),('004026'),('006004'),('006006'),('006010'),('006010'),('006010'),('006010'),('006010'),('006010'),('006010'),('006011'),('006011'),('006011'),('006011'),('006011'),('006011'),('006012'),('006012'),('006012'),('006012'),('006012'),('006012'),('006014'),('006014'),('006014'),('007001'),('007001'),('007002'),('007003'),('007005'),('007007'),('007008'),('007009'),('007011'),('007012'),('007013'),('007015'),('007016'),('007017'),('007018'),('007019'),('007019'),('007020'),('007021'),('007021'),('007022'),('007023'),('007023'),('007025'),('007025'),('007025'),('007027'),('007029'),('007031'),('007031'),('007032'),('007034'),('007034'),('007036'),('007036'),('007036'),('007037'),('007037'),('007038'),('007040'),('007040'),('007040'),('007043'),('009001'),('009001'),('009001'),('009001'),('009001'),('009001'),('009001'),('009002'),('009002'),('009002'),('009002'),('009002'),('009004'),('009004'),('009004'),('009004'),('009005'),('009005'),('009005'),('009005'),('009005'),('009005'),('009005'),('009005'),('009006'),('009006'),('009006'),('009006'),('009007'),('009007'),('009007'),('009007'),('009007'),('009007'),('009008'),('009010'),('009010'),('009010'),('009010'),('009010'),('009010'),('009011'),('009011'),('009011'),('009011'),('009011'),('009012'),('009013'),('009013'),('009013'),('010002'),('010002'),('010002'),('010002'),('010002'),('010002'),('010002'),('010002'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010005'),('010005'),('010005'),('010005'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010007'),('010007'),('010007'),('010007'),('010007'),('010007'),('010008'),('010008'),('010008'),('010008'),('010008'),('010008'),('010008'),('010009'),('010009'),('010009'),('010009'),('010009'),('010009'),('010010'),('010010'),('010010'),('010010'),('010010'),('010010'),('010010'),('010011'),('010011'),('010011'),('010011'),('010011'),('010011'),('010011'),('010011'),('010012'),('010012'),('010012'),('010012'),('010012'),('010012'),('010012'),('010013'),('010013'),('010013'),('010013'),('010013'),('010013'),('010015'),('010016'),('010016'),('010016'),('010016'),('010016'),('010016'),('010016'),('010016'),('010017'),('010017'),('010017'),('010017'),('010017'),('010017'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010019'),('010019'),('010019'),('010019'),('010019'),('010019'),('010020'),('010020'),('010020'),('010021'),('010021'),('010021'),('010021'),('010021'),('010021'),('010022'),('010022'),('010022'),('010022'),('010022'),('010022'),('010022'),('010022'),('010023'),('010023'),('010023'),('010023'),('010023'),('010023'),('010023'),('010023'),('010026'),('010027'),('010028'),('010028'),('011001'),('011001'),('011001'),('011001'),('011001'),('011001'),('011001'),('011002'),('011002'),('011002'),('011002'),('011002'),('011002'),('011002'),('011003'),('011003'),('011003'),('011003'),('011003'),('011003'),('011003'),('011003'),('011004'),('011004'),('011004'),('011004'),('011004'),('011004'),('011004'),('011006'),('011006'),('011006'),('011006'),('011006'),('011006'),('011006'),('011012'),('011012'),('011012'),('011013'),('011013'),('011013'),('011013'),('011013'),('011013'),('011014'),('011014'),('011014'),('011014'),('011015'),('011015'),('011015'),('011015'),('011015'),('011016'),('011016'),('011016'),('011016'),('011016'),('012017'),('012017'),('012027'),('012027'),('012032'),('012034'),('012036'),('012036'),('012037'),('012037'),('012038'),('012039'),('014001'),('014001'),('016016'),('016016'),('016016'),('016019'),('016020'),('016020'),('016020'),('016020'),('016020'),('016020'),('016020'),('016020'),('016021'),('016021'),('016021'),('016021'),('016021'),('016021'),('016021'),('016022'),('016022'),('016022'),('016023'),('016023'),('016023'),('016024'),('016024'),('016024'),('016024'),('016024'),('016024'),('016024'),('016026'),('016026'),('016026'),('016026'),('016026'),('016026'),('016028'),('016028'),('016028'),('016028'),('016028'),('016028'),('016028'),('016029'),('016029'),('016030'),('016031'),('016032'),('016032'),('016032'),('016032'),('016032'),('016032'),('016032'),('016033'),('016033'),('016033'),('016033'),('016033'),('016034'),('016034'),('016034'),('016034'),('016034'),('017002'),('017002'),('017002'),('017002'),('017002'),('018001'),('018001'),('018001'),('018001'),('018001'),('018001'),('018001'),('018001'),('019002'),('019002'),('019002'),('019002'),('019002'),('019002'),('019004'),('019004'),('019004'),('019004'),('019004'),('019004'),('020001'),('020001'),('020001'),('020001'),('020004'),('020006'),('020006'),('020006'),('020006'),('020006'),('020006'),('020008'),('020009'),('020009'),('020009'),('020009'),('020009'),('022001'),('022001'),('022001'),('022001'),('022002'),('022002'),('022002'),('022002'),('022003'),('022003'),('022003'),('022003'),('023001'),('023002'),('023002'),('023002'),('023002'),('023002'),('023002'),('023003'),('023003'),('023003'),('023003'),('023004'),('023004'),('023005'),('023005'),('023006'),('023006'),('023006'),('023006'),('023006'),('023006'),('023007'),('023007'),('023010'),('023010'),('023011'),('023011'),('023017'),('023019'),('023019'),('023019'),('023020'),('023020'),('023025'),('023025'),('023025'),('023026'),('023026'),('023026'),('023027'),('023027'),('023027'),('023028'),('023028'),('023029'),('023029'),('023030'),('023030'),('023032'),('023033'),('023033'),('023033'),('023033'),('023033'),('023033'),('023034'),('023035'),('023035'),('025001'),('025001'),('025001'),('025001'),('025001'),('025001'),('025001'),('025003'),('025003'),('025004'),('025004'),('025005'),('025005'),('025007'),('025007'),('025008'),('025008'),('025009'),('025010'),('025010'),('025010'),('025011'),('025011'),('025012'),('025012'),('025013'),('025013'),('025013'),('025014'),('025015'),('025016'),('025018'),('025018'),('025019'),('025019'),('025020'),('025020'),('025021'),('025022'),('025022'),('025023'),('025023'),('025024'),('025025'),('025025'),('025026'),('025026'),('025027'),('025027'),('025027'),('025028'),('025030'),('025031'),('025033'),('025034'),('025035'),('025037'),('025041'),('025042'),('025043'),('025046'),('025048'),('025048'),('025048'),('025049'),('025049'),('025049'),('025050'),('025050'),('025050'),('025051'),('025051'),('025052'),('025052'),('025052'),('025053'),('025053'),('025054'),('025054'),('025054'),('025054'),('025055'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025057'),('025057'),('025058'),('025058'),('025060'),('025060'),('025061'),('025062'),('025063'),('027001'),('027002'),('027011'),('036001'),('036001'),('036001'),('036001'),('036001'),('037003'),('037006'),('037007'),('037008'),('037008'),('038009'),('039001'),('039001'),('039001'),('039001'),('039001'),('039001'),('039002'),('039002'),('039002'),('039002'),('039002'),('039003'),('039003'),('039003'),('039003'),('039003'),('039003'),('039004'),('039004'),('039004'),('039004'),('039004'),('039005'),('039005'),('039005'),('039005'),('039005'),('039006'),('039006'),('039006'),('039006'),('046001'),('046001'),('046001'),('046001'),('046001'),('046001'),('046001'),('046001'),('046002'),('046002'),('046002'),('046002'),('046002'),('046002'),('046002'),('046002'),('046003'),('046003'),('046003'),('046003'),('046003'),('046003'),('046003'),('046005'),('046005'),('046005'),('046005'),('046005'),('046005'),('046005'),('046007'),('046007'),('046007'),('046007'),('046007'),('046007'),('046008'),('046008'),('046008'),('046008'),('046008'),('046009'),('046009'),('046009'),('046010'),('046012'),('046012'),('046012'),('046013'),('046014'),('046014'),('046014'),('047001'),('047001'),('047001'),('047001'),('047001'),('047001'),('047001'),('047001'),('047002'),('047002'),('047002'),('047002'),('047002'),('047002'),('047002'),('047002'),('048001'),('048001'),('048001'),('048001'),('048001'),('048001'),('048001'),('048001'),('051003'),('051003'),('051003'),('051003'),('051003'),('051004'),('051004'),('051004'),('051004'),('052001'),('052001'),('052001'),('052001'),('052001'),('052001'),('052001'),('052001'),('052002'),('052002'),('052005'),('052005'),('052005'),('052005'),('052005'),('052005'),('053016'),('053019'),('053019'),('053023'),('053023'),('053023'),('053023'),('053024'),('053024'),('053024'),('053026'),('053026'),('053026'),('053026'),('053028'),('053028'),('053029'),('053029'),('053029'),('053029'),('053033'),('053033'),('053033'),('053045'),('053046'),('053051'),('053051'),('053051'),('053054'),('053054'),('053054'),('053054'),('053057'),('053069'),('053069'),('053097'),('053107'),('053125'),('053125'),('053127'),('054001'),('054001'),('054001'),('054001'),('054001'),('054001'),('054001'),('054002'),('054002'),('054002'),('054002'),('054002'),('054002'),('054003'),('054003'),('054003'),('054003'),('054003'),('054003'),('054003'),('054004'),('054004'),('054004'),('054004'),('054004'),('054004'),('054004'),('054006'),('054006'),('054006'),('054007'),('054007'),('054007'),('054007'),('054007'),('054009'),('054009'),('054009'),('054009'),('054010'),('054010'),('054010'),('054010'),('054010'),('054010'),('054010'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056002'),('056002'),('056002'),('056002'),('056002'),('056002'),('056002'),('056002'),('056003'),('056003'),('056003'),('056003'),('056003'),('056003'),('056004'),('056004'),('056004'),('056004'),('056004'),('056004'),('056004'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056009'),('056009'),('056009'),('056011'),('056016'),('056016'),('056016'),('056016'),('056016'),('056016'),('056016'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056018'),('056018'),('056018'),('056018'),('056018'),('056018'),('056019'),('056019'),('056019'),('056019'),('056019'),('056019'),('056019'),('056019'),('056020'),('056020'),('056020'),('056020'),('056022'),('056022'),('056022'),('056022'),('056022'),('057003'),('057003'),('057004'),('058002'),('058002'),('058002'),('058002'),('058003'),('058003'),('058003'),('058003'),('058004'),('058004'),('058004'),('058005'),('058005'),('058005'),('060001'),('060001'),('060001'),('060001'),('060001'),('060004'),('060004'),('060004'),('060004'),('060004'),('060004'),('060005'),('060005'),('060005'),('060005'),('060005'),('060005'),('060007'),('060007'),('060007'),('060007'),('060007'),('060007'),('060007'),('061004'),('061004'),('061004'),('061004'),('061004'),('061004'),('061006'),('061006'),('061006'),('061006'),('061006'),('061006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069007'),('069007'),('069007'),('069007'),('069007'),('069007'),('069007'),('069007'),('069010'),('069010'),('069010'),('069010'),('069010'),('069010'),('069011'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069016'),('069016'),('069016'),('069016'),('069016'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069020'),('069020'),('069020'),('069020'),('069021'),('069023'),('071002'),('071002'),('071002'),('071002'),('071002'),('071003'),('071003'),('071003'),('071003'),('071003'),('071004'),('071004'),('071004'),('071004'),('071004'),('071005'),('071005'),('071005'),('071005'),('071005'),('071005'),('071006'),('071006'),('071006'),('071006'),('071008'),('071008'),('071008'),('071008'),('071008'),('071008'),('071011'),('071011'),('071011'),('071011'),('071011'),('071020'),('071020'),('071020'),('071020'),('071020'),('071021'),('071022'),('071022'),('071022'),('072001'),('072001'),('074001'),('074002'),('074002'),('074002'),('074002'),('074002'),('074002'),('074002'),('074002'),('074003'),('074003'),('074003'),('074003'),('074003'),('074003'),('074003'),('074003'),('074004'),('074004'),('074004'),('074004'),('074004'),('074004'),('074004'),('074004'),('074005'),('074005'),('074005'),('074005'),('074005'),('074005'),('074005'),('074005'),('074006'),('074006'),('074006'),('074006'),('074006'),('074006'),('074006'),('074006'),('074007'),('074007'),('074007'),('074007'),('074007'),('074007'),('074007'),('074007'),('074008'),('074008'),('074008'),('074008'),('074008'),('074008'),('074008'),('074008'),('074009'),('074009'),('074009'),('074009'),('074009'),('074009'),('074009'),('074009'),('074010'),('074010'),('074010'),('074010'),('074010'),('074010'),('074010'),('074010'),('074011'),('074011'),('074011'),('074011'),('074011'),('074011'),('074011'),('074011'),('074012'),('074012'),('074012'),('074012'),('074012'),('074012'),('074012'),('075001'),('075001'),('075001'),('075007'),('075007'),('075007'),('075007'),('076101'),('076101'),('076101'),('076101'),('076102'),('076102'),('076102'),('076103'),('076103'),('076103'),('076103'),('076103'),('077001'),('077001'),('077001'),('077002'),('077002'),('077002'),('077002'),('077002'),('077002'),('077002'),('077003'),('077003'),('077003'),('077003'),('077003'),('077003'),('077003'),('077004'),('077004'),('077004'),('077004'),('077004'),('077004'),('077006'),('077006'),('077008'),('077008'),('077008'),('077008'),('077008'),('077008'),('077008'),('077009'),('077009'),('077009'),('077009'),('077009'),('077009'),('077009'),('078005'),('078005'),('078005'),('079002'),('079002'),('079002'),('079002'),('079002'),('079002'),('079002'),('079003'),('079003'),('079004'),('079004'),('079005'),('079005'),('079005'),('079005'),('079005'),('079005'),('079006'),('079006'),('079006'),('079006'),('079007'),('079007'),('079007'),('079007'),('079007'),('081001'),('081001'),('081001'),('081001'),('081001'),('082011'),('082011'),('082011'),('082011'),('082011'),('082013'),('082013'),('082013'),('082013'),('082013'),('082013'),('082014'),('082014'),('082014'),('082014'),('082014'),('082014'),('082014'),('082015'),('082015'),('082015'),('082015'),('082015'),('082016'),('082016'),('082016'),('082016'),('082016'),('082016'),('082017'),('082017'),('082017'),('082017'),('082017'),('082017'),('082017'),('082021'),('082021'),('082022'),('082022'),('082022'),('082022'),('082022'),('082023'),('082023'),('082023'),('082023'),('082023'),('082024'),('082024'),('082024'),('082024'),('082024'),('082025'),('082025'),('082025'),('082025'),('082025'),('082026'),('082026'),('082026'),('082026'),('082026'),('082027'),('082027'),('082027'),('082027'),('082027'),('082028'),('082028'),('082028'),('082028'),('082029'),('082029'),('082029'),('082029'),('082029'),('082030'),('082030'),('082030'),('082030'),('082031'),('082031'),('082031'),('082031'),('082031'),('082032'),('082032'),('082032'),('082033'),('082033'),('082034'),('082034'),('082034'),('082034'),('082034'),('082034'),('082034'),('082035'),('082035'),('082035'),('082036'),('082036'),('082036'),('082036'),('082037'),('082037'),('082037'),('082038'),('082038'),('082038'),('082038'),('082039'),('082039'),('082039'),('082039'),('082040'),('082040'),('082040'),('082040'),('082040'),('082041'),('082041'),('082041'),('082041'),('082042'),('082042'),('082043'),('082043'),('082043'),('082043'),('082043'),('082044'),('082044'),('082044'),('082044'),('084001'),('084002'),('084002'),('084002'),('084002'),('084003'),('084003'),('084003'),('084003'),('084003'),('084003'),('084003'),('084003'),('084004'),('084004'),('084004'),('084004'),('084004'),('084005'),('084005'),('084005'),('084005'),('084005'),('084007'),('084007'),('084007'),('084007'),('084007'),('084007'),('084008'),('084008'),('084008'),('084008'),('084008'),('084008'),('084009'),('084009'),('084009'),('084009'),('084009'),('084009'),('084011'),('084013'),('084013'),('084013'),('084013'),('084013'),('084014'),('084014'),('084014'),('084016'),('084016'),('084016'),('084016'),('084016'),('084016'),('084016'),('084016'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084027'),('084027'),('084027'),('084027'),('084027'),('084027'),('084032'),('084032'),('084033'),('084033'),('084033'),('084035'),('084035'),('084035'),('084036'),('084036'),('084036'),('084036'),('084036'),('084036'),('084037'),('084037'),('084038'),('084038'),('084038'),('084038'),('084038'),('084038'),('084039'),('084039'),('084039'),('084039'),('084040'),('084040'),('084040'),('084040'),('084040'),('084041'),('084041'),('084041'),('084041'),('084042'),('084042'),('084043'),('084043'),('084043'),('084043'),('084044'),('084044'),('084044'),('084044'),('084044'),('084045'),('084046'),('084046'),('084046'),('084047'),('084048'),('084048'),('084049'),('084049'),('084050'),('084051'),('084051'),('085001'),('085001'),('085001'),('085001'),('085001'),('085001'),('085002'),('085002'),('085002'),('085002'),('085003'),('085003'),('085003'),('085003'),('085003'),('085003'),('085003'),('085004'),('085004'),('085004'),('085004'),('085004'),('085004'),('085004'),('085005'),('085005'),('085005'),('085005'),('085005'),('085005'),('085006'),('085006'),('085006'),('085006'),('085006'),('085006'),('085006'),('085006'),('085007'),('085007'),('085007'),('085007'),('085007'),('085007'),('085007'),('085009'),('085009'),('085009'),('085009'),('085009'),('085009'),('085011'),('085011'),('085011'),('085011'),('085011'),('085011'),('085011'),('085011'),('085012'),('085012'),('085012'),('085012'),('085012'),('085012'),('085012'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085015'),('085015'),('085015'),('085015'),('085015'),('085015'),('085015'),('085015'),('085016'),('085016'),('085016'),('085016'),('085016'),('085016'),('085016'),('085016'),('085017'),('085017'),('085017'),('085017'),('085017'),('085018'),('085018'),('085018'),('085018'),('085018'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085020'),('085020'),('085020'),('085020'),('085020'),('085020'),('085022'),('085022'),('085022'),('085022'),('085022'),('085022'),('085023'),('085023'),('085023'),('085023'),('085023'),('085028'),('085028'),('085028'),('085028'),('085028'),('085028'),('085028'),('085029'),('085029'),('085029'),('085029'),('085029'),('085029'),('085029'),('085030'),('085030'),('085030'),('085030'),('085030'),('085030'),('085030'),('085031'),('085031'),('085031'),('085031'),('085031'),('085031'),('085031'),('085033'),('085034'),('085034'),('085034'),('085034'),('085034'),('085034'),('085034'),('085035'),('085035'),('085035'),('085035'),('085035'),('085035'),('085036'),('085036'),('085036'),('085036'),('085036'),('085036'),('085037'),('085037'),('085037'),('085037'),('085037'),('085037'),('085038'),('085038'),('085038'),('085038'),('085038'),('085038'),('085038'),('085040'),('085040'),('085040'),('085040'),('085040'),('085040'),('085040'),('085040'),('085041'),('085041'),('085041'),('085041'),('085041'),('085041'),('085041'),('085041'),('085042'),('085042'),('085042'),('085042'),('085042'),('085042'),('085042'),('085043'),('085043'),('085043'),('085043'),('085043'),('085043'),('085044'),('085044'),('085044'),('085044'),('085044'),('085044'),('085044'),('085045'),('085045'),('085045'),('085045'),('085045'),('085046'),('085046'),('085046'),('085046'),('085046'),('085046'),('085046'),('085046'),('085047'),('085047'),('085047'),('085047'),('085047'),('085047'),('085047'),('085047'),('085048'),('085048'),('085048'),('085048'),('085048'),('085048'),('085048'),('085063'),('085063'),('085063'),('085063'),('085063'),('085064'),('085064'),('085064'),('085064'),('085064'),('085065'),('085065'),('085068'),('085068'),('085068'),('085068'),('085068'),('085068'),('085071'),('085071'),('085071'),('085071'),('085071'),('085071'),('085073'),('085073'),('085082'),('085082'),('085082'),('085082'),('085082'),('085086'),('085086'),('085086'),('085088'),('085088'),('085088'),('085088'),('085088'),('085088'),('085088'),('085089'),('085089'),('085090'),('085090'),('085090'),('085090'),('085090'),('085090'),('085090'),('085090'),('085091'),('085091'),('085091'),('085091'),('085091'),('085092'),('085092'),('085092'),('085093'),('085093'),('085095'),('085095'),('085095'),('085095'),('085095'),('085096'),('085096'),('085096'),('085096'),('085096'),('085096'),('085097'),('085097'),('085097'),('085097'),('085097'),('085098'),('085098'),('085098'),('085098'),('085098'),('085098'),('085098'),('085099'),('085099'),('085099'),('085099'),('085099'),('085099'),('085099'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085101'),('085101'),('085101'),('085101'),('085101'),('085101'),('085101'),('085101'),('085102'),('085102'),('085103'),('085103'),('085103'),('085104'),('085104'),('085104'),('085104'),('085104'),('085105'),('085105'),('085106'),('085106'),('085106'),('085106'),('085106'),('085106'),('085108'),('085108'),('085109'),('085109'),('085109'),('085109'),('085109'),('085109'),('085109'),('085109'),('085110'),('085110'),('085110'),('085110'),('085110'),('085111'),('085111'),('085111'),('085112'),('085112'),('085112'),('085112'),('085113'),('085113'),('085113'),('085113'),('085113'),('085115'),('085120'),('085121'),('085121'),('085121'),('085121'),('085122'),('085122'),('085122'),('085122'),('085122'),('085122'),('085122'),('085122'),('085123'),('085123'),('085123'),('085123'),('085123'),('085123'),('085123'),('085123'),('085125'),('085125'),('085125'),('085125'),('085125'),('085126'),('085126'),('085126'),('085126'),('085126'),('085127'),('085127'),('085127'),('085127'),('085127'),('085127'),('085127'),('085127'),('085128'),('085128'),('085128'),('085128'),('085128'),('085129'),('085129'),('085129'),('085129'),('085129'),('085130'),('085130'),('085130'),('085130'),('085130'),('085132'),('085132'),('085132'),('085132'),('085132'),('085132'),('085133'),('085133'),('085133'),('085133'),('085133'),('085134'),('085134'),('085134'),('085135'),('085135'),('085135'),('085136'),('085136'),('085136'),('085136'),('085137'),('085137'),('085137'),('085137'),('085137'),('085137'),('085137'),('086002'),('086002'),('086002'),('086002'),('086003'),('086003'),('086003'),('086003'),('086005'),('088001'),('088001'),('088001'),('088001'),('088001'),('088003'),('088003'),('088003'),('088003'),('088003'),('088003'),('088005'),('088005'),('088005'),('088005'),('088005'),('088006'),('088006'),('088006'),('088006'),('088006'),('088007'),('088007'),('088007'),('088008'),('088008'),('088008'),('088008'),('088009'),('088009'),('088009'),('088009'),('088009'),('089001'),('089001'),('089001'),('089001'),('089001'),('089001'),('089001'),('090001'),('090001'),('090001'),('090001'),('090001'),('090001'),('090001'),('090002'),('090002'),('090002'),('090002'),('090002'),('090002'),('090003'),('090003'),('090003'),('090003'),('090003'),('090003'),('090003'),('090004'),('090004'),('090004'),('090004'),('090004'),('090004'),('090004'),('090006'),('090006'),('090006'),('090006'),('090006'),('090006'),('090006'),('090008'),('090008'),('090008'),('090008'),('090008'),('090009'),('090009'),('090009'),('090009'),('090009'),('090010'),('090010'),('090013'),('090013'),('090013'),('090016'),('090016'),('090017'),('090018'),('090022'),('090027'),('091001'),('091001'),('091001'),('091001'),('091001'),('091001'),('091002'),('091002'),('091002'),('091002'),('091002'),('091002'),('091009'),('091009'),('091009'),('091009'),('091009'),('091011'),('091011'),('091011'),('091011'),('091011'),('091011'),('091011'),('091012'),('091012'),('091013'),('091013'),('091013'),('091013'),('091013'),('091013'),('091015'),('091015'),('091015'),('091015'),('091015'),('091015'),('091016'),('091016'),('091016'),('091016'),('091016'),('091017'),('091017'),('091018'),('091018'),('091018'),('091018'),('093003'),('093003'),('093003'),('093003'),('093003'),('093003'),('099001'),('099001'),('099001'),('099001'),('099001'),('099001'),('099001'),('100001'),('100001'),('100001'),('100001'),('106001'),('113005'),('113005'),('113005'),('113006'),('113006'),('113018'),('113019'),('113020'),('115001'),('115001'),('115001'),('115002'),('115002'),('115003'),('115004'),('115004'),('115004'),('115004'),('115005'),('115005'),('115005'),('115006'),('115006'),('115006'),('115007'),('115007'),('115007'),('115007'),('115007'),('115008'),('115008'),('115008'),('115009'),('115010'),('115010'),('115010'),('115010'),('115010'),('115011'),('115011'),('115011'),('115011'),('115012'),('115012'),('115013'),('115013'),('115013'),('115014'),('115014'),('115014'),('115014'),('115015'),('115015'),('115015'),('115016'),('115016'),('115016'),('115016'),('115017'),('115017'),('115017'),('115017'),('115017'),('115018'),('115018'),('115020'),('115020'),('115021'),('115021'),('115022'),('115022'),('115022'),('115023'),('115023'),('115023'),('115023'),('115023'),('115025'),('115025'),('115025'),('115026'),('115026'),('115027'),('115027'),('115027'),('115028'),('115028'),('115028'),('115028'),('115029'),('115029'),('115029'),('115030'),('115030'),('115030'),('115031'),('115031'),('115032'),('115032'),('115032'),('115033'),('115033'),('115033'),('115033'),('115034'),('115034'),('115034'),('115035'),('115035'),('115036'),('115036'),('115036'),('115036'),('115036'),('115039'),('115040'),('115040'),('115040'),('115041'),('115041'),('115041'),('115041'),('115041'),('115042'),('115042'),('115042'),('115042'),('115042'),('115043'),('115043'),('115043'),('115044'),('115044'),('115044'),('115044'),('115046'),('115046'),('115046'),('115047'),('115048'),('115050'),('115050'),('115050'),('115050'),('115050'),('115051'),('115051'),('115051'),('115052'),('115053'),('115053'),('115054'),('115054'),('115054'),('115055'),('115055'),('115055'),('115057'),('115059'),('115059'),('115059'),('115059'),('115060'),('115060'),('115060'),('115060'),('115060'),('115060'),('115061'),('115061'),('115061'),('115062'),('115062'),('115062'),('115062'),('115064'),('115064'),('115064'),('115065'),('115065'),('115065'),('115065'),('115066'),('115066'),('115066'),('115067'),('115067'),('115067'),('115068'),('115068'),('115068'),('115069'),('115069'),('115069'),('115069'),('115069'),('115070'),('115070'),('115070'),('115071'),('115071'),('115071'),('115072'),('115072'),('115072'),('115073'),('115073'),('115075'),('115075'),('115075'),('115076'),('115076'),('115076'),('115076'),('115076'),('115076'),('115081'),('115081'),('115081'),('115082'),('115082'),('115082'),('115085'),('115085'),('115085'),('115085'),('115085'),('115086'),('115086'),('115086'),('115087'),('115087'),('115088'),('115088'),('115088'),('115088'),('115088'),('115095'),('115095'),('115095'),('115096'),('115096'),('115097'),('115097'),('115098'),('115098'),('115099'),('115101'),('115102'),('115102'),('115102'),('115103'),('115103'),('115104'),('115104'),('115104'),('115104'),('115105'),('115105'),('115106'),('115106'),('115106'),('115106'),('115106'),('115108'),('115109'),('115111'),('115111'),('115111'),('115111'),('115112'),('115112'),('115112'),('115112'),('115112'),('115113'),('115113'),('115113'),('115114'),('115114'),('115114'),('115114'),('115114'),('115115'),('115115'),('115115'),('115115'),('115116'),('115117'),('115117'),('115117'),('115118'),('115118'),('115119'),('115119'),('115119'),('115119'),('115120'),('115121'),('115121'),('115122'),('115122'),('116001'),('116003'),('116003'),('116003'),('116003'),('116004'),('116004'),('116005'),('116005'),('116006'),('116006'),('116006'),('116007'),('116007'),('116008'),('116008'),('116009'),('116009'),('116009'),('116010'),('116010'),('116010'),('116010'),('116011'),('116011'),('116011'),('116011'),('116012'),('116012'),('123001'),('123001'),('123001'),('123001'),('123001'),('124065'),('126001'),('126001'),('126001'),('126001'),('126001'),('126001'),('126001'),('126001'),('126002'),('126002'),('126002'),('126002'),('126002'),('126002'),('126002'),('126002'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126007'),('126007'),('126007'),('126007'),('126007'),('126007'),('126007'),('126008'),('126008'),('126008'),('126008'),('126008'),('126008'),('126008'),('126008'),('126009'),('126009'),('126009'),('126009'),('126009'),('126009'),('126009'),('126009'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126011'),('126011'),('126011'),('126011'),('126011'),('126011'),('126011'),('126012'),('126012'),('126012'),('126012'),('130001'),('130001'),('130001'),('130001'),('132001'),('132001'),('132001'),('132001'),('132001'),('132002'),('132002'),('132002'),('132002'),('132002'),('132002'),('132002'),('133001'),('133001'),('133008'),('133009'),('133010'),('133011'),('133011'),('133011'),('133011'),('133011'),('133011'),('133012'),('133015'),('133015'),('133015'),('133015'),('133016'),('133018'),('133018'),('133018'),('133018'),('133018'),('133019'),('133021'),('133021'),('133022'),('133022'),('133023'),('133023'),('133024'),('133024'),('133024'),('133024'),('133024'),('133024'),('133025'),('133027'),('133027'),('133027'),('133027'),('133027'),('133028'),('133028'),('133028'),('133029'),('133029'),('133029'),('133029'),('133029'),('133029'),('133030'),('133030'),('133031'),('133031'),('133031'),('134001'),('134001'),('134001'),('135001'),('135001'),('135001'),('135001'),('135001'),('135002'),('135002'),('135002'),('135004'),('135010'),('135010'),('135010'),('135010'),('135010'),('135010'),('137010'),('137011'),('137012'),('137014'),('137015'),('137015'),('137016'),('137019'),('139001'),('140001'),('140001'),('140001'),('140001'),('140001'),('140001'),('141001'),('141001'),('141001'),('141001'),('141001'),('141002'),('141002'),('141002'),('141002'),('141002'),('141003'),('141003'),('141003'),('141003'),('141003'),('141003'),('141003'),('141003'),('141006'),('141006'),('141006'),('141006'),('141006'),('141006'),('141006'),('141006'),('141007'),('141007'),('141007'),('141007'),('141007'),('141009'),('141009'),('141009'),('141009'),('141009'),('141011'),('141011'),('141011'),('141011'),('141011'),('141011'),('141012'),('141014'),('141014'),('141014'),('141014'),('141014'),('141014'),('141014'),('141014'),('141015'),('141015'),('141015'),('141015'),('141015'),('141016'),('141016'),('141016'),('141016'),('141016'),('141016'),('141017'),('141017'),('141017'),('141017'),('141017'),('141017'),('141018'),('141018'),('141018'),('141018'),('141019'),('141019'),('141019'),('141019'),('141020'),('141020'),('141020'),('141020'),('141020'),('141020'),('141020'),('141021'),('141021'),('141021'),('141021'),('141021'),('141021'),('141022'),('141022'),('141022'),('141022'),('141022'),('141022'),('141023'),('141023'),('141023'),('141023'),('141023'),('141023'),('141023'),('141024'),('141025'),('141025'),('141025'),('141026'),('141026'),('141026'),('141026'),('141026'),('141026'),('141027'),('141027'),('141027'),('141027'),('141027'),('141028'),('141028'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145008'),('145008'),('145008'),('145008'),('145008'),('145008'),('145008'),('145008'),('145009'),('145009'),('145009'),('145009'),('145009'),('145009'),('145009'),('145011'),('145011'),('145011'),('145011'),('145011'),('145011'),('145011'),('145011'),('145012'),('145012'),('145012'),('145012'),('145012'),('145012'),('145012'),('145012'),('145013'),('145013'),('145013'),('145013'),('145013'),('145013'),('145013'),('150009'),('150013'),('150014'),('150015'),('150015'),('150015'),('150016'),('150016'),('150017'),('150017'),('150017'),('150017'),('150020'),('152001'),('152001'),('152001'),('152002'),('152003'),('152003'),('152003'),('152003'),('152004'),('152005'),('152006'),('152006'),('152006'),('152006'),('152007'),('154001'),('154002'),('154002'),('155001'),('155001'),('155002'),('155003'),('155004'),('155004'),('155006'),('159001'),('159003'),('160001'),('160001'),('160001'),('160001'),('160002'),('160002'),('161001'),('162002'),('162002'),('162003'),('162003'),('162003'),('162003'),('162003'),('162007'),('162012'),('162012'),('162012'),('163001'),('163001'),('163001'),('163011'),('163015'),('163016'),('163016'),('165001'),('165001'),('165001'),('165001'),('165002'),('165002'),('165002'),('165002'),('165003'),('165003'),('165003'),('165004'),('165004'),('165004'),('165005'),('165005'),('165005'),('165006'),('165006'),('165006'),('165006'),('165007'),('165007'),('165007'),('165007'),('165008'),('165008'),('165008'),('165008'),('165009'),('165009'),('165009'),('165009'),('165010'),('165010'),('165010'),('165011'),('165011'),('165012'),('165012'),('165012'),('165013'),('165013'),('165013'),('165014'),('165014'),('165014'),('165015'),('165015'),('165015'),('165015'),('165016'),('165016'),('165016'),('165017'),('165017'),('165017'),('165017'),('165018'),('165018'),('165018'),('165018'),('165019'),('165019'),('165019'),('165019'),('165020'),('165020'),('165020'),('165020'),('165021'),('165021'),('165021'),('165021'),('165022'),('165022'),('165022'),('165023'),('165024'),('165024'),('165024'),('165025'),('165025'),('165025'),('165026'),('165026'),('165026'),('165028'),('165029'),('165030'),('165030'),('165030'),('165031'),('165031'),('165033'),('165033'),('165034'),('165034'),('165034'),('165035'),('165035'),('165035'),('165036'),('165036'),('165036'),('168003'),('168003'),('168004'),('168005'),('168014'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169003'),('169003'),('169003'),('169003'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169008'),('169008'),('169008'),('169008'),('169008'),('169008'),('169008'),('169009'),('169009'),('169009'),('169009'),('169010'),('171006'),('171006'),('171007'),('171007'),('171008'),('171008'),('171008'),('171009'),('171009'),('171009'),('172001'),('176001'),('176001'),('176001'),('176001'),('176001'),('176001'),('176001'),('176002'),('176002'),('176002'),('176002'),('176002'),('176003'),('176003'),('176003'),('176003'),('176003'),('176003'),('177001'),('177001'),('177001'),('177001'),('177001'),('177001'),('179007'),('179007'),('179012'),('179012'),('179012'),('179012'),('179012'),('179012'),('179013'),('179013'),('179013'),('179013'),('179013'),('179013'),('179042'),('179044'),('179045'),('180001'),('180013'),('180014'),('180014'),('180015'),('180017'),('180018'),('180020'),('180020'),('180021'),('180021'),('180027'),('180030'),('180033'),('180035'),('180036'),('180037'),('180038'),('180041'),('180042'),('180045'),('180045'),('180047'),('180048'),('180049'),('180050'),('180054'),('180060'),('180066'),('180067'),('180068'),('180070'),('182001'),('184001'),('184002'),('184005'),('184005'),('184005'),('184005'),('184006'),('184006'),('184006'),('184006'),('184008'),('184008'),('184008'),('184008'),('184009'),('184009'),('184009'),('184009'),('184010'),('184010'),('184010'),('184010'),('184011'),('184011'),('184011'),('184011'),('185001'),('185001'),('185001'),('185001'),('185001'),('185001'),('185001'),('185003'),('185003'),('185003'),('185003'),('185003'),('185003'),('185003'),('187001'),('191002'),('191002'),('192002'),('194003'),('197001'),('197001'),('197001'),('197001'),('197001'),('197001'),('197001'),('197002'),('197002'),('197002'),('197002'),('197002'),('197002'),('197002'),('197003'),('197003'),('197003'),('197003'),('197003'),('197003'),('197003'),('197004'),('197004'),('197004'),('197004'),('197004'),('197004'),('197004'),('197005'),('197005'),('197005'),('197005'),('197005'),('197005'),('197006'),('197006'),('197006'),('197006'),('197006'),('198001'),('198001'),('198001'),('198001'),('198001'),('198001'),('198003'),('198003'),('198003'),('198004'),('198004'),('198004'),('198004'),('198004'),('198004'),('198005'),('198005'),('198005'),('198005'),('198005'),('198005'),('198005'),('198006'),('198006'),('198006'),('198006'),('198006'),('198006'),('198007'),('198007'),('198007'),('198007'),('198007'),('198007'),('198007'),('198008'),('198008'),('198008'),('198008'),('198008'),('198008'),('198009'),('198009'),('198009'),('198009'),('198009'),('198009'),('198009'),('198010'),('198010'),('198010'),('198010'),('198010'),('198010'),('198011'),('198012'),('198012'),('198012'),('198012'),('198015'),('198015'),('198016'),('198016'),('198016'),('198016'),('198016'),('198016'),('198017'),('198017'),('198017'),('198017'),('198017'),('198017'),('201001'),('201001'),('201001'),('201001'),('201001'),('201002'),('202001'),('202001'),('203001'),('203001'),('203001'),('203001'),('203001'),('203001'),('203001'),('203002'),('203002'),('203002'),('203002'),('203003'),('203003'),('203003'),('203003'),('203003'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203018'),('203018'),('203018'),('203018'),('203018'),('203019'),('203019'),('203019'),('203019'),('203019'),('204001'),('204002'),('205001'),('205001'),('205001'),('205001'),('205001'),('205001'),('205001'),('208001'),('208001'),('208002'),('208002'),('208002'),('208003'),('208003'),('208003'),('208004'),('208004'),('208004'),('208004'),('208004'),('208004'),('208004'),('208005'),('208005'),('208005'),('208005'),('208005'),('209001'),('209001'),('209001'),('209001'),('209001'),('209002'),('209002'),('209002'),('209002'),('209002'),('209003'),('209003'),('209003'),('209003'),('209003'),('210001'),('210001'),('210001'),('210001'),('210001'),('210004'),('210004'),('210004'),('210004'),('210004'),('210004'),('210009'),('210010'),('212001'),('212001'),('212002'),('212002'),('212002'),('212002'),('212003'),('212003'),('212003'),('212004'),('212004'),('212004'),('212005'),('212005'),('212005'),('212005'),('212005'),('212006'),('212006'),('212006'),('212007'),('212007'),('212008'),('212008'),('212008'),('212008'),('212009'),('212009'),('212009'),('212009'),('212010'),('212010'),('212010'),('212010'),('212011'),('212011'),('212012'),('212012'),('212013'),('212013'),('212013'),('218001'),('218004'),('218009'),('218011'),('218011'),('218015'),('218020'),('218021'),('218021'),('218022'),('218022'),('218022'),('218023'),('218024'),('218025'),('218026'),('218026'),('218027'),('218028'),('218029'),('218029'),('218029'),('218030'),('218031'),('221001'),('221001'),('221001'),('221001'),('221001'),('221001'),('221002'),('221002'),('221002'),('221002'),('221002'),('221002'),('221003'),('221003'),('221003'),('221003'),('221003'),('221003'),('221004'),('221004'),('221004'),('221004'),('221004'),('221004'),('221005'),('221005'),('221005'),('221005'),('221005'),('221006'),('221006'),('221006'),('221006'),('221006'),('221007'),('221007'),('221007'),('221007'),('221007'),('221007'),('221008'),('221008'),('221008'),('221008'),('221008'),('221008'),('221009'),('221009'),('221009'),('221009'),('221009'),('221009'),('221010'),('221010'),('221010'),('221010'),('221011'),('221011'),('221011'),('221011'),('221012'),('221012'),('221012'),('221012'),('221012'),('221012'),('221013'),('221013'),('221013'),('221013'),('221013'),('221013'),('223003'),('223003'),('224001'),('224001'),('224002'),('224002'),('224003'),('224007'),('224008'),('225001'),('225002'),('225002'),('225002'),('225003'),('225003'),('225003'),('225003'),('225004'),('225004'),('225004'),('225005'),('225005'),('225005'),('225005'),('225005'),('225005'),('225006'),('225006'),('225006'),('225007'),('225007'),('225007'),('225008'),('225008'),('225008'),('225008'),('225008'),('225009'),('225009'),('225009'),('225010'),('225010'),('225010'),('225011'),('225011'),('225011'),('225011'),('225011'),('225012'),('225012'),('225012'),('225012'),('225012'),('225012'),('225013'),('225013'),('226001'),('226002'),('226003'),('226003'),('226005'),('226005'),('226006'),('226007'),('226007'),('226007'),('226007'),('227011'),('227015'),('227015'),('227041'),('227045'),('227052'),('227056'),('227063'),('227064'),('227066'),('227067'),('227069'),('227071'),('227073'),('227085'),('227116'),('227119'),('227131'),('227133'),('227147'),('229005'),('229005'),('229005'),('233003'),('233004'),('235001'),('235001'),('235002'),('235003'),('235003'),('235003'),('235004'),('235005'),('235005'),('235005'),('235005'),('235005'),('235005'),('235005'),('236001'),('236001'),('236001'),('236001'),('236002'),('236003'),('236003'),('236003'),('236003'),('236003'),('236003'),('238002'),('238002'),('238002'),('238002'),('238002'),('238002'),('238003'),('238003'),('238003'),('238003'),('238003'),('238003'),('238004'),('238004'),('238004'),('238004'),('238004'),('238005'),('238005'),('238005'),('238007'),('238007'),('238007'),('238007'),('238007'),('238007'),('238007'),('238008'),('238008'),('238008'),('238008'),('238008'),('238008'),('238008'),('334005'),('334006'),('337001'),('337001'),('337001'),('337002'),('337002'),('337003'),('337003'),('337003'),('337004'),('343001'),('343001'),('344001'),('344002'),('344003'),('344004'),('344005'),('344005'),('345001'),('345001'),('348001'),('348004'),('348005'),('348005'),('349001'),('349001'),('349002'),('349002'),('349002'),('350001'),('353002'),('353002'),('353002'),('353003'),('355001'),('355002'),('355005'),('355006'),('355006'),('356001'),('358001'),('358001'),('358001'),('359001'),('359001'),('359002'),('359002'),('359002'),('359002'),('360001'),('360001'),('360002'),('360002'),('360003'),('360003'),('360004'),('360004'),('360005'),('360005'),('360005'),('366001'),('366002'),('366002'),('366003'),('366004'),('369001'),('369001'),('373001'),('373002'),('373002'),('373003'),('373003'),('373005'),('373007'),('373008'),('373009'),('373009'),('373010'),('373010'),('373010'),('373011'),('373011'),('373011'),('373011'),('373012'),('373012'),('373012'),('373013'),('373013'),('373014'),('373014'),('373015'),('373015'),('373015'),('373015'),('373017'),('373017'),('373017'),('373017'),('373018'),('373021'),('374002'),('374004'),('374006'),('374007'),('374008'),('374009'),('374010'),('374011'),('374012'),('374015'),('374016'),('382001'),('382002'),('382002'),('384001'),('386001'),('386001'),('386001'),('386001'),('386001'),('386001'),('386001'),('386002'),('386002'),('386002'),('386002'),('386002'),('386002'),('386002'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386004'),('386004'),('386004'),('386004'),('386004'),('386004'),('386004'),('386004'),('386005'),('386005'),('386005'),('386005'),('386005'),('386005'),('386005'),('386006'),('386006'),('386006'),('386006'),('386006'),('386006'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386008'),('386008'),('386008'),('386008'),('386008'),('386008'),('386008'),('386008'),('386009'),('386009'),('386009'),('386010'),('386010'),('386010'),('386010'),('386010'),('386010'),('386010'),('386010'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386013'),('386013'),('386013'),('386013'),('386013'),('386013'),('386013'),('386014'),('386014'),('386014'),('386014'),('389001'),('389002'),('389002'),('389003'),('389003'),('389003'),('389003'),('389004'),('389004'),('389004'),('389004'),('392001'),('393001'),('393002'),('393002'),('393003'),('393004'),('395001'),('395001'),('397001'),('397001'),('397001'),('397002'),('399001'),('399001'),('399001'),('399001'),('399001'),('399001'),('399001'),('399002'),('399002'),('399002'),('399002'),('399002'),('399002'),('399002'),('399003'),('400001'),('400001'),('400001'),('400001'),('400002'),('403002'),('504001'),('504001'),('504002'),('504002'),('504002'),('504004'),('504004'),('504005'),('504006'),('504007'),('504007'),('504007'),('504008'),('504008'),('504009'),('504009'),('504009'),('504009'),('504009'),('504010'),('504011'),('504011'),('504012'),('504012'),('504014'),('504014'),('504014'),('504014'),('504014'),('504014'),('504014'),('504014'),('504017'),('504017'),('504021'),('504021'),('504021'),('504021'),('504021'),('504021'),('504021'),('504022'),('504023'),('504023'),('504024'),('504024'),('504025'),('504025'),('506001'),('506001'),('506001'),('506001'),('506001'),('506001'),('506002'),('506002'),('506002'),('506002'),('506002'),('511001'),('511001'),('511001'),('511001'),('511001'),('511001'),('511001'),('511002'),('511002'),('511002'),('511002'),('511002'),('511002'),('511002'),('511003'),('511003'),('511003'),('511003'),('511003'),('511003'),('511004'),('511004'),('511004'),('511004'),('511004'),('511004'),('511004'),('511005'),('511005'),('511005'),('511005'),('511005'),('511005'),('511005'),('511006'),('511006'),('511006'),('511006'),('511006'),('511006'),('511006'),('511007'),('511007'),('511007'),('511007'),('511007'),('511008'),('511008'),('511008'),('511008'),('511008'),('511008'),('511009'),('511009'),('511009'),('511009'),('511009'),('511009'),('511010'),('511010'),('511010'),('511010'),('511010'),('511010'),('511011'),('511011'),('511011'),('511011'),('511011'),('511011'),('511012'),('511012'),('511012'),('511012'),('511012'),('511012'),('511012'),('511013'),('511013'),('511013'),('511013'),('511013'),('511013'),('511013'),('511014'),('511014'),('511014'),('511014'),('511014'),('511017'),('511018'),('511020'),('511021'),('511022'),('511024'),('511028'),('511029'),('511029'),('511029'),('511029'),('511029'),('511029'),('513001'),('513001'),('513001'),('513001'),('513001'),('513001'),('513001'),('513001'),('513002'),('513002'),('513002'),('513002'),('513002'),('513002'),('513003'),('513003'),('513003'),('513003'),('513003'),('513003'),('513003'),('513003'),('513004'),('513004'),('513004'),('515001'),('515001'),('515001'),('515001'),('515001'),('515002'),('515002'),('515003'),('515003'),('515007'),('515007'),('515008'),('515011'),('515011'),('515011'),('515011'),('515011'),('515011'),('515012'),('515012'),('515012'),('515012'),('515013'),('515013'),('515013'),('515013'),('515013'),('515014'),('515014'),('515014'),('515014'),('515014'),('515015'),('515015'),('515015'),('515015'),('515015'),('518001'),('518002'),('521001'),('521002'),('521002'),('521002'),('521003'),('521003'),('521003'),('521003'),('521004'),('521004'),('521004'),('521004'),('521005'),('521005'),('521005'),('521005'),('521006'),('521006'),('521006'),('521009'),('521010'),('521010'),('521010'),('521010'),('521011'),('521011'),('521011'),('521011'),('521012'),('521013'),('521013'),('521015'),('521016'),('521016'),('523001'),('523001'),('523001'),('523001'),('523001'),('523001'),('523001'),('523002'),('523002'),('523002'),('523002'),('523002'),('523002'),('523003'),('523003'),('523003'),('523003'),('523003'),('523003'),('523003'),('523004'),('523004'),('523004'),('523004'),('523004'),('523004'),('523005'),('523005'),('523005'),('523005'),('523005'),('523005'),('523005'),('523005'),('523006'),('523006'),('523006'),('523006'),('523006'),('523006'),('523006'),('523007'),('523007'),('523007'),('523007'),('523007'),('523007'),('523007'),('524001'),('700001'),('701001'),('701002'),('701003'),('702001'),('702002'),('702004'),('702005'),('704001'),('704004'),('705001'),('706001'),('706002'),('707001'),('707002'),('707003'),('708001'),('710001'),('710002'),('711001'),('711002'),('712001'),('714001'),('714002'),('715001'),('719001'),('719002'),('991002'),('991002'),('991002'),('991003'),('991003'),('991003'),('991003'),('991003'),('991003'),('991003'),('991004'),('991004'),('991004'),('991005'),('991005'),('991005'),('991006'),('991007'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996002'),('996002'),('996003'),('996003'),('996003'),('996003'),('996003'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998003'),('998003'),('998003'),('998003'),('998003'),('998003'),('998003'),('998003'),('998004'),('998004'),('998005'),('998005'),('998006'),('998007'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999002'),('999002'),('011017'),('011017'),('011017'),('011017'),('011017'),('011017'),('011017'),('011018'),('011018'),('011018'),('011018'),('034001'),('034001'),('034002'),('034002'),('071010'),('071010'),('071010'),('519001'),('126013'),('126013'),('126013'),('126013'),('126013'),('184012'),('184012'),('184012'),('404001'),('405002'),('405002'),('405001'),('405003'),('405006'),('240011'),('240011'),('240011'),('240011'),('240011'),('240011'),('240010'),('240010'),('240010'),('240009'),('240009'),('240009'),('240009'),('240008'),('240008'),('240008'),('240007'),('240007'),('240007'),('240007'),('240007'),('240007'),('240005'),('240005'),('240005'),('240005'),('240005'),('240004'),('240004'),('240004'),('240004'),('240004'),('240003'),('240003'),('240003'),('240003'),('240002'),('240002'),('240002'),('240002'),('240002'),('240002'),('240002'),('240001'),('240001'),('240001'),('240001'),('240001'),('240012'),('240012'),('240012'),('240012'),('240012'),('240013'),('240014'),('240015'),('240015'),('240015'),('240015'),('240015'),('240015'),('240015'),('240015'),('240016'),('240016'),('240016'),('240016'),('240016'),('240016'),('240017'),('240017'),('240017'),('357001'),('357001'),('235006'),('235006'),('235007'),('235007'),('235007'),('235007'),('235007'),('056023'),('056023'),('056023'),('056023'),('056023'),('046015'),('019005'),('019005'),('126014'),('126014'),('126014'),('126014'),('126014'),('126014'),('241003'),('241003'),('241003'),('241003'),('241003'),('241003'),('241002'),('241002'),('241002'),('241002'),('241002'),('241002'),('241001'),('241001'),('241001'),('241001'),('241001'),('240020'),('240020'),('240020'),('240020'),('240020'),('240020'),('240019'),('240019'),('240019'),('242001'),('242002'),('242004'),('242005'),('242006'),('089002'),('089002'),('089002'),('089002'),('089002'),('089002'),('406001'),('406002'),('406003'),('406004'),('406004'),('243001'),('243005'),('243006'),('243007'),('243008'),('408001'),('408001'),('408001'),('408001'),('408001'),('366005'),('366005'),('016035'),('016035'),('016035'),('016035'),('077010'),('996004'),('996004'),('996004'),('996004'),('996004'),('996004'),('996004'),('996004'),('025064'),('025064'),('025064'),('025064'),('011019'),('011019'),('011019'),('011019'),('011019'),('115123'),('115123'),('504026'),('039007'),('039009'),('039008'),('039008'),('039010'),('039010'),('039011'),('039012'),('180072'),('240021'),('240021'),('240021'),('240021'),('240021'),('240021'),('240021'),('240023'),('240023'),('240023'),('240023'),('405008'),('405008'),('525002'),('410002'),('410002'),('410004'),('410005'),('410005'),('410006'),('410007'),('410007'),('410008'),('410009'),('410010'),('410011'),('410011'),('410012'),('410012'),('410013'),('410013'),('410014'),('410014'),('410016'),('410016'),('344006'),('240031'),('240031'),('240031'),('240031'),('240030'),('240030'),('240030'),('240030'),('240029'),('240029'),('240029'),('240029'),('240028'),('240028'),('240028'),('240028'),('240027'),('240027'),('240026'),('240026'),('240026'),('240025'),('240025'),('240025'),('240025'),('240024'),('240024'),('240034'),('240034'),('240034'),('240033'),('240033'),('240033'),('240032'),('240032'),('240032'),('240032'),('411001'),('411002'),('203020'),('069025'),('069025'),('069025'),('069025'),('069025'),('069025'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244014'),('244014'),('244014'),('244014'),('244014'),('244014'),('244014'),('244014'),('244013'),('244013'),('244013'),('244013'),('244013'),('244013'),('244013'),('244013'),('244012'),('244012'),('244012'),('244012'),('244012'),('244012'),('244012'),('244012'),('244011'),('244011'),('244011'),('244011'),('244011'),('244011'),('244011'),('244011'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('240040'),('240037'),('405009'),('405009'),('405009'),('405010'),('405010'),('240043'),('240043'),('504028'),('504040'),('800001'),('410019'),('410019'),('410020'),('410020'),('410020'),('410021'),('410021'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244020'),('244020'),('244020'),('244020'),('244020'),('244020'),('244020'),('244020'),('413001'),('344007'),('082045'),('082045'),('082045'),('082045'),('082045'),('010031'),('010031'),('010031'),('010031'),('010032'),('010032'),('010032'),('010032'),('010033'),('010033'),('010033'),('010033'),('010033'),('010034'),('010034'),('010034'),('010034'),('010035'),('010035'),('010035'),('010035'),('504044'),('515016'),('515016'),('515016'),('515016'),('801002'),('801003'),('801004'),('801005'),('802001'),('801001'),('414001'),('141029'),('803001'),('803002'),('803004'),('803005'),('803006'),('803007'),('803008'),('803009'),('803013'),('803014'),('803015'),('803016'),('803017'),('410022'),('410023'),('410023'),('803019'),('415002'),('415001'),('244021'),('244021'),('244021'),('244021'),('244021'),('244021'),('244021'),('011020'),('011020'),('011020'),('011020'),('011023'),('011023'),('011023'),('011023'),('011022'),('011022'),('011022'),('011022'),('011022'),('011022'),('011021'),('011021'),('011021'),('011021'),('025065'),('025065'),('025065'),('025065'),('165037'),('165037'),('165038'),('165038'),('165038'),('165039'),('416001'),('416001'),('416001'),('416001'),('416001'),('416002'),('416003'),('417001'),('418001'),('504045'),('504045'),('504045'),('803022'),('240022'),('240022'),('240022'),('240022'),('420001'),('420001'),('420001'),('420001'),('804010'),('804005'),('804002'),('804018'),('804013'),('511019'),('511016'),('511015'),('511032'),('511031'),('511030'),('511027'),('511026'),('511025'),('511033'),('511023'),('133034'),('133034'),('133034'),('133033'),('169011'),('169011'),('169011'),('169011'),('169011'),('344008'),('244022'),('244022'),('244022'),('244022'),('244022'),('244022'),('244022'),('244026'),('244026'),('244026'),('244026'),('244026'),('244026'),('244025'),('244025'),('244025'),('244025'),('244025'),('244025'),('244025'),('244025'),('244030'),('244030'),('244030'),('244030'),('244030'),('244030'),('244030'),('244030'),('244023'),('244023'),('244023'),('244023'),('244023'),('244023'),('244024'),('244024'),('244024'),('244024'),('244024'),('244024'),('244024'),('244024'),('244027'),('244027'),('244027'),('244027'),('244027'),('244027'),('244027'),('244027'),('244028'),('244028'),('244028'),('244028'),('244028'),('244028'),('244028'),('244028'),('244029'),('244029'),('244029'),('244029'),('244029'),('244029'),('244029'),('244029'),('244031'),('244031'),('244031'),('244031'),('244031'),('244031'),('244031'),('244031'),('082046'),('082046'),('082046'),('082046'),('082047'),('082047'),('082048'),('082048'),('126015'),('126015'),('126016'),('126016'),('126016'),('126016'),('126016'),('416005'),('421001'),('421001'),('421002'),('016037'),('016037'),('016037'),('016037'),('016036'),('016036'),('016036'),('016036'),('115124'),('115124'),('115126'),('240049'),('240049'),('240048'),('240048'),('240047'),('240047'),('240046'),('240046'),('240045'),('240044'),('244032'),('244033'),('422002'),('422004'),('422004'),('422004'),('422005'),('422005'),('184013'),('184013'),('184013'),('805001'),('805002'),('805003'),('805004'),('805005'),('056024'),('056024'),('056024'),('423001'),('344010'),('235009'),('235009'),('235009'),('235009'),('212014'),('212014'),('056025'),('056025'),('056025'),('056026'),('056026'),('056026'),('056026'),('056026'),('056026'),('244034'),('244034'),('244034'),('244034'),('244034'),('244034'),('244035'),('244035'),('244035'),('244035'),('244035'),('244035'),('244035'),('244036'),('244036'),('244036'),('244036'),('244036'),('244036'),('244036'),('244037'),('244037'),('244037'),('244037'),('244037'),('244037'),('244037'),('244038'),('244038'),('244038'),('244038'),('244038'),('244038'),('244038'),('244039'),('244039'),('244039'),('244039'),('244039'),('244039'),('244039'),('203015'),('245002'),('245002'),('245001'),('245001'),('056029'),('056030'),('056032'),('424001'),('056034'),('056034'),('056034'),('056034'),('056033'),('056033'),('056033'),('805006'),('805007'),('805008'),('805009'),('805010'),('422008'),('422008'),('422007'),('422007'),('422006'),('422006'),('422010'),('422009'),('422009'),('422011'),('422011'),('209004'),('209004'),('150022'),('100002'),('056035'),('056035'),('056035'),('023036'),('023036'),('185005'),('246001'),('246001'),('247001'),('247001'),('247001'),('247001'),('247001'),('247001'),('247001'),('247002'),('247002'),('425001'),('416006'),('416006'),('165042'),('165041'),('165040'),('165043'),('010040'),('010039'),('010038'),('010036'),('248001'),('248002'),('248003'),('248004'),('248005'),('249001'),('249003'),('249004'),('249005'),('250007'),('250001'),('250002'),('250003'),('250004'),('250005'),('250006'),('250008'),('250009'),('250010'),('250011'),('250012'),('250013'),('251001'),('251002'),('806001'),('806002'),('235010'),('243009'),('249007'),('249008'),('249009'),('011024'),('011025'),('429001'),('429001'),('429002'),('429002'),('429003'),('429003');
+select field from t1 group by field;
field
001001
001010
@@ -1614,11 +1621,18 @@ field
429001
429002
429003
+drop table t1;
+create table t1 (a enum (' ','a','b') not null);
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','a','b') NOT NULL default ''
) TYPE=MyISAM
+drop table t1;
+create table t1 (a enum (' ','a','b ') not null default 'b ');
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','a','b') NOT NULL default 'b'
) TYPE=MyISAM
+drop table t1;
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index d8fbc5bc725..e85bced353a 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -1,12 +1,21 @@
+SELECT 10,10.0,10.,.1e+2,100.0e-1;
10 10.0 10. .1e+2 100.0e-1
10 10.0 10 10 10
+SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000;
6e-05 -6e-05 --6e-05 -6e-05+1.000000
6e-05 -6e-05 6e-05 0.99994
+SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1;
1e1 1.e1 1.0e1 1e+1 1.e+1 1.0e+1 1e-1 1.e-1 1.0e-1
10 10 10 10 10 10 0.1 0.1 0.1
+drop table if exists t1;
+create table t1 (f1 float(24),f2 float(52));
+show full columns from t1;
Field Type Null Key Default Extra Privileges
f1 float YES NULL select,insert,update,references
f2 double YES NULL select,insert,update,references
+insert into t1 values(10,10),(1e+5,1e+5),(1234567890,1234567890),(1e+10,1e+10),(1e+15,1e+15),(1e+20,1e+20),(1e+50,1e+50),(1e+150,1e+150);
+insert into t1 values(-10,-10),(1e-5,1e-5),(1e-10,1e-10),(1e-15,1e-15),(1e-20,1e-20),(1e-50,1e-50),(1e-150,1e-150);
+select * from t1;
f1 f2
10 10
100000 100000
@@ -23,28 +32,43 @@ f1 f2
1e-20 1e-20
0 1e-50
0 1e-150
+drop table t1;
+create table t1 (datum double);
+insert into t1 values (0.5),(1.0),(1.5),(2.0),(2.5);
+select * from t1;
datum
0.5
1
1.5
2
2.5
+select * from t1 where datum < 1.5;
datum
0.5
1
+select * from t1 where datum > 1.5;
datum
2
2.5
+select * from t1 where datum = 1.5;
datum
1.5
+drop table t1;
+create table t1 (a decimal(7,3) not null, key (a));
+insert into t1 values ("0"),("-0.00"),("-0.01"),("-0.002"),("1");
+select a from t1 order by a;
a
-0.010
-0.002
-0.000
0.000
1.000
+select min(a) from t1;
min(a)
-0.010
+drop table t1;
+create table t1 (f float, f2 float(24), f3 float(6,2), d double, d2 float(53), d3 double(10,3), de decimal, de2 decimal(6), de3 decimal(5,2), n numeric, n2 numeric(8), n3 numeric(5,6));
+show full columns from t1;
Field Type Null Key Default Extra Privileges
f float YES NULL select,insert,update,references
f2 float YES NULL select,insert,update,references
@@ -58,11 +82,20 @@ de3 decimal(5,2) YES NULL select,insert,update,references
n decimal(10,0) YES NULL select,insert,update,references
n2 decimal(8,0) YES NULL select,insert,update,references
n3 decimal(7,6) YES NULL select,insert,update,references
+drop table t1;
+create table t1 (a decimal(7,3) not null, key (a));
+insert into t1 values ("0"),("-0.00"),("-0.01"),("-0.002"),("1");
+select a from t1 order by a;
a
-0.010
-0.002
-0.000
0.000
1.000
+select min(a) from t1;
min(a)
-0.010
+drop table t1;
+create table t1 (f float(54));
+Incorrect column specifier for column 'f'
+drop table if exists t1;
diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result
index abb8ef8cb09..fc7cc5255cf 100644
--- a/mysql-test/r/type_ranges.result
+++ b/mysql-test/r/type_ranges.result
@@ -1,3 +1,43 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+auto int(5) unsigned DEFAULT 0 NOT NULL auto_increment,
+string char(10) default "hello",
+tiny tinyint(4) DEFAULT '0' NOT NULL ,
+short smallint(6) DEFAULT '1' NOT NULL ,
+medium mediumint(8) DEFAULT '0' NOT NULL,
+long_int int(11) DEFAULT '0' NOT NULL,
+longlong bigint(13) DEFAULT '0' NOT NULL,
+real_float float(13,1) DEFAULT 0.0 NOT NULL,
+real_double double(16,4),
+utiny tinyint(3) unsigned DEFAULT '0' NOT NULL,
+ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL,
+umedium mediumint(8) unsigned DEFAULT '0' NOT NULL,
+ulong int(11) unsigned DEFAULT '0' NOT NULL,
+ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL,
+time_stamp timestamp,
+date_field date,
+time_field time,
+date_time datetime,
+blob_col blob,
+tinyblob_col tinyblob,
+mediumblob_col mediumblob not null,
+longblob_col longblob not null,
+options enum('one','two','tree') not null,
+flags set('one','two','tree') not null,
+PRIMARY KEY (auto),
+KEY (utiny),
+KEY (tiny),
+KEY (short),
+KEY any_name (medium),
+KEY (longlong),
+KEY (real_float),
+KEY (ushort),
+KEY (umedium),
+KEY (ulong),
+KEY (ulonglong,ulong),
+KEY (options,flags)
+);
+show full fields from t1;
Field Type Null Key Default Extra Privileges
auto int(5) unsigned PRI NULL auto_increment select,insert,update,references
string varchar(10) YES hello select,insert,update,references
@@ -23,21 +63,34 @@ mediumblob_col mediumblob select,insert,update,references
longblob_col longblob select,insert,update,references
options enum('one','two','tree') MUL one select,insert,update,references
flags set('one','two','tree') select,insert,update,references
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 auto A 0 NULL NULL
-t1 1 utiny 1 utiny A NULL NULL NULL
-t1 1 tiny 1 tiny A NULL NULL NULL
-t1 1 short 1 short A NULL NULL NULL
-t1 1 any_name 1 medium A NULL NULL NULL
-t1 1 longlong 1 longlong A NULL NULL NULL
-t1 1 real_float 1 real_float A NULL NULL NULL
-t1 1 ushort 1 ushort A NULL NULL NULL
-t1 1 umedium 1 umedium A NULL NULL NULL
-t1 1 ulong 1 ulong A NULL NULL NULL
-t1 1 ulonglong 1 ulonglong A NULL NULL NULL
-t1 1 ulonglong 2 ulong A NULL NULL NULL
-t1 1 options 1 options A NULL NULL NULL
-t1 1 options 2 flags A NULL NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE
+t1 1 utiny 1 utiny A NULL NULL NULL BTREE
+t1 1 tiny 1 tiny A NULL NULL NULL BTREE
+t1 1 short 1 short A NULL NULL NULL BTREE
+t1 1 any_name 1 medium A NULL NULL NULL BTREE
+t1 1 longlong 1 longlong A NULL NULL NULL BTREE
+t1 1 real_float 1 real_float A NULL NULL NULL BTREE
+t1 1 ushort 1 ushort A NULL NULL NULL BTREE
+t1 1 umedium 1 umedium A NULL NULL NULL BTREE
+t1 1 ulong 1 ulong A NULL NULL NULL BTREE
+t1 1 ulonglong 1 ulonglong A NULL NULL NULL BTREE
+t1 1 ulonglong 2 ulong A NULL NULL NULL BTREE
+t1 1 options 1 options A NULL NULL NULL BTREE
+t1 1 options 2 flags A NULL NULL NULL BTREE
+CREATE UNIQUE INDEX test on t1 ( auto ) ;
+CREATE INDEX test2 on t1 ( ulonglong,ulong) ;
+CREATE INDEX test3 on t1 ( medium ) ;
+DROP INDEX test ON t1;
+insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
+insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one');
+insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303 101010','','','','3',3,3);
+insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1);
+insert into t1 values (0,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,NULL,0,0,0,-4294967295,-4294967295,-4294967295,'-4294967295',0,"one,two,tree");
+insert into t1 values (0,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,NULL,0,0,0,4294967295,4294967295,4294967295,'4294967295',0,0);
+insert into t1 (tiny) values (1);
+select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,utiny,ushort,umedium,ulong,ulonglong,mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000),date_field,time_field,date_time,blob_col,tinyblob_col,mediumblob_col,longblob_col from t1;
auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col
10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1
11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2
@@ -46,6 +99,27 @@ auto string tiny short medium long_int longlong real_float real_double utiny ush
14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 18446744069414584321 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295
15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295
16 hello 1 1 0 0 0 0.0 NULL 0 00000 0 0 0 0 NULL NULL NULL NULL NULL
+ALTER TABLE t1
+add new_field char(10) default "new" not null,
+change blob_col new_blob_col varchar(20),
+change date_field date_field char(10),
+alter column string set default "new default",
+alter short drop default,
+DROP INDEX utiny,
+DROP INDEX ushort,
+DROP PRIMARY KEY,
+DROP FOREIGN KEY any_name,
+ADD INDEX (auto);
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1
+RENAME as t2,
+DROP longblob_col;
+UNLOCK TABLES;
+ALTER TABLE t2 rename as t3;
+LOCK TABLES t3 WRITE ;
+ALTER TABLE t3 rename as t1;
+UNLOCK TABLES;
+select auto,new_field,new_blob_col,date_field from t1 ;
auto new_field new_blob_col date_field
10 new 1 0000-00-00
11 new NULL NULL
@@ -54,6 +128,15 @@ auto new_field new_blob_col date_field
14 new -4294967295 0000-00-00
15 new 4294967295 0000-00-00
16 new NULL NULL
+CREATE TABLE t2 (
+auto int(5) unsigned NOT NULL DEFAULT 0 auto_increment,
+string char(20),
+mediumblob_col mediumblob not null,
+new_field char(2),
+PRIMARY KEY (auto)
+);
+INSERT INTO t2 (string,mediumblob_col,new_field) SELECT string,mediumblob_col,new_field from t1 where auto > 10;
+select * from t2;
auto string mediumblob_col new_field
1 2 2 ne
2 0.33 ne
@@ -61,21 +144,30 @@ auto string mediumblob_col new_field
4 -429496729 -4294967295 ne
5 4294967295 4294967295 ne
6 hello ne
+select distinct flags from t1;
flags
one,two,tree
one
one,two
+select flags from t1 where find_in_set("two",flags)>0;
flags
one,two,tree
one,two,tree
one,two
one,two
+select flags from t1 where find_in_set("unknown",flags)>0;
flags
+select options,flags from t1 where options="ONE" and flags="ONE";
options flags
one one
+select options,flags from t1 where options="one" and flags="one";
options flags
one one
+drop table t2;
+create table t2 select * from t1;
+update t2 set string="changed" where auto=16;
+show full columns from t1;
Field Type Null Key Default Extra Privileges
auto int(5) unsigned MUL NULL auto_increment select,insert,update,references
string varchar(10) YES new defaul select,insert,update,references
@@ -101,6 +193,7 @@ mediumblob_col mediumblob select,insert,update,references
options enum('one','two','tree') MUL one select,insert,update,references
flags set('one','two','tree') select,insert,update,references
new_field varchar(10) new select,insert,update,references
+show full columns from t2;
Field Type Null Key Default Extra Privileges
auto int(5) unsigned 0 select,insert,update,references
string varchar(10) YES new defaul select,insert,update,references
@@ -126,16 +219,22 @@ mediumblob_col mediumblob select,insert,update,references
options enum('one','two','tree') one select,insert,update,references
flags set('one','two','tree') select,insert,update,references
new_field varchar(10) new select,insert,update,references
+select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and ((t1.string<>t2.string and (t1.string is not null or t2.string is not null)) or (t1.tiny<>t2.tiny and (t1.tiny is not null or t2.tiny is not null)) or (t1.short<>t2.short and (t1.short is not null or t2.short is not null)) or (t1.medium<>t2.medium and (t1.medium is not null or t2.medium is not null)) or (t1.long_int<>t2.long_int and (t1.long_int is not null or t2.long_int is not null)) or (t1.longlong<>t2.longlong and (t1.longlong is not null or t2.longlong is not null)) or (t1.real_float<>t2.real_float and (t1.real_float is not null or t2.real_float is not null)) or (t1.real_double<>t2.real_double and (t1.real_double is not null or t2.real_double is not null)) or (t1.utiny<>t2.utiny and (t1.utiny is not null or t2.utiny is not null)) or (t1.ushort<>t2.ushort and (t1.ushort is not null or t2.ushort is not null)) or (t1.umedium<>t2.umedium and (t1.umedium is not null or t2.umedium is not null)) or (t1.ulong<>t2.ulong and (t1.ulong is not null or t2.ulong is not null)) or (t1.ulonglong<>t2.ulonglong and (t1.ulonglong is not null or t2.ulonglong is not null)) or (t1.time_stamp<>t2.time_stamp and (t1.time_stamp is not null or t2.time_stamp is not null)) or (t1.date_field<>t2.date_field and (t1.date_field is not null or t2.date_field is not null)) or (t1.time_field<>t2.time_field and (t1.time_field is not null or t2.time_field is not null)) or (t1.date_time<>t2.date_time and (t1.date_time is not null or t2.date_time is not null)) or (t1.new_blob_col<>t2.new_blob_col and (t1.new_blob_col is not null or t2.new_blob_col is not null)) or (t1.tinyblob_col<>t2.tinyblob_col and (t1.tinyblob_col is not null or t2.tinyblob_col is not null)) or (t1.mediumblob_col<>t2.mediumblob_col and (t1.mediumblob_col is not null or t2.mediumblob_col is not null)) or (t1.options<>t2.options and (t1.options is not null or t2.options is not null)) or (t1.flags<>t2.flags and (t1.flags is not null or t2.flags is not null)) or (t1.new_field<>t2.new_field and (t1.new_field is not null or t2.new_field is not null)));
auto auto
16 16
+select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and not (t1.string<=>t2.string and t1.tiny<=>t2.tiny and t1.short<=>t2.short and t1.medium<=>t2.medium and t1.long_int<=>t2.long_int and t1.longlong<=>t2.longlong and t1.real_float<=>t2.real_float and t1.real_double<=>t2.real_double and t1.utiny<=>t2.utiny and t1.ushort<=>t2.ushort and t1.umedium<=>t2.umedium and t1.ulong<=>t2.ulong and t1.ulonglong<=>t2.ulonglong and t1.time_stamp<=>t2.time_stamp and t1.date_field<=>t2.date_field and t1.time_field<=>t2.time_field and t1.date_time<=>t2.date_time and t1.new_blob_col<=>t2.new_blob_col and t1.tinyblob_col<=>t2.tinyblob_col and t1.mediumblob_col<=>t2.mediumblob_col and t1.options<=>t2.options and t1.flags<=>t2.flags and t1.new_field<=>t2.new_field);
auto auto
16 16
+drop table t2;
+create table t2 (primary key (auto)) select auto+1 as auto,1 as t1, "a" as t2, repeat("a",256) as t3, binary repeat("b",256) as t4 from t1;
+show full columns from t2;
Field Type Null Key Default Extra Privileges
-auto bigint(17) PRI 0 select,insert,update,references
+auto bigint(17) unsigned PRI 0 select,insert,update,references
t1 bigint(1) 0 select,insert,update,references
t2 char(1) select,insert,update,references
t3 mediumtext select,insert,update,references
t4 mediumblob select,insert,update,references
+select * from t2;
auto t1 t2 t3 t4
11 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
12 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
@@ -144,16 +243,39 @@ auto t1 t2 t3 t4
15 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
16 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
17 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+drop table t1,t2;
+create table t1 (c int);
+insert into t1 values(1),(2);
+create table t2 select * from t1;
+create table t3 select * from t1, t2;
+Duplicate column name 'c'
+create table t3 select t1.c AS c1, t2.c AS c2,1 as "const" from t1, t2;
+show full columns from t3;
Field Type Null Key Default Extra Privileges
c1 int(11) YES NULL select,insert,update,references
c2 int(11) YES NULL select,insert,update,references
const bigint(1) 0 select,insert,update,references
+drop table t1,t2,t3;
+create table t1 ( myfield INT NOT NULL, UNIQUE INDEX (myfield), unique (myfield), index(myfield));
+drop table t1;
+create table t1 ( id integer unsigned not null primary key );
+create table t2 ( id integer unsigned not null primary key );
+insert into t1 values (1), (2);
+insert into t2 values (1);
+select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id );
id_A id_B
1 1
2 NULL
+create table t3 (id_A integer unsigned not null, id_B integer unsigned null );
+insert into t3 select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id );
+select * from t3;
id_A id_B
1 1
2 NULL
+drop table t3;
+create table t3 select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id );
+select * from t3;
id_A id_B
1 1
2 NULL
+drop table t1,t2,t3;
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 8b065618742..858bf5f3ba2 100644
--- a/mysql-test/r/type_set.result
+++ b/mysql-test/r/type_set.result
@@ -1,8 +1,14 @@
+create table t1 (a set (' ','a','b') not null);
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','a','b') NOT NULL default ''
) TYPE=MyISAM
+drop table t1;
+create table t1 (a set (' ','a','b ') not null default 'b ');
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','a','b') NOT NULL default 'b'
) TYPE=MyISAM
+drop table t1;
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index 1a137a89b1e..ff700f456ef 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -1,3 +1,7 @@
+create table t1 (t time);
+insert into t1 values("10:22:33"),("12:34:56.78"),(10),(1234),(123456.78),(1234559.99),("1"),("1:23"),("1:23:45"), ("10.22"), ("-10 1:22:33.45"),("20 10:22:33"),("1999-02-03 20:33:34");
+insert t1 values (30),(1230),("1230"),("12:30"),("12:30:35"),("1 12:30:31.32");
+select * from t1;
t
10:22:33
12:34:56
@@ -18,6 +22,8 @@ t
12:30:00
12:30:35
36:30:31
+insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
+select * from t1;
t
10:22:33
12:34:56
@@ -44,6 +50,10 @@ t
838:59:59
262:22:00
00:00:12
+drop table t1;
+create table t1 (t time);
+insert into t1 values ('09:00:00'),('13:00:00'),('19:38:34'), ('13:00:00'),('09:00:00'),('09:00:00'),('13:00:00'),('13:00:00'),('13:00:00'),('09:00:00');
+select t, time_to_sec(t),sec_to_time(time_to_sec(t)) from t1;
t time_to_sec(t) sec_to_time(time_to_sec(t))
09:00:00 32400 09:00:00
13:00:00 46800 13:00:00
@@ -55,6 +65,7 @@ t time_to_sec(t) sec_to_time(time_to_sec(t))
13:00:00 46800 13:00:00
13:00:00 46800 13:00:00
09:00:00 32400 09:00:00
+select sec_to_time(time_to_sec(t)) from t1;
sec_to_time(time_to_sec(t))
09:00:00
13:00:00
@@ -66,3 +77,4 @@ sec_to_time(time_to_sec(t))
13:00:00
13:00:00
09:00:00
+drop table t1;
diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result
index 8996ca59f7f..ab53d27e8f3 100644
--- a/mysql-test/r/type_timestamp.result
+++ b/mysql-test/r/type_timestamp.result
@@ -1,11 +1,29 @@
+CREATE TABLE t1 ( t timestamp);
+SET TIMESTAMP=1234;
+insert into t1 values(NULL);
+select * from t1;
t
19700101032034
+drop table t1;
+CREATE TABLE t1 (value TEXT NOT NULL, id VARCHAR(32) NOT NULL, stamp timestamp, PRIMARY KEY (id));
+INSERT INTO t1 VALUES ("my value", "myKey","1999-04-02 00:00:00");
+SELECT stamp FROM t1 WHERE id="myKey";
stamp
19990402000000
+UPDATE t1 SET value="my value" WHERE id="myKey";
+SELECT stamp FROM t1 WHERE id="myKey";
stamp
19990402000000
+drop table t1;
+create table t1 (a timestamp);
+insert into t1 values (now());
+select date_format(a,"%Y %y"),year(a),year(now()) from t1;
date_format(a,"%Y %y") year(a) year(now())
1970 70 1970 1970
+drop table t1;
+create table t1 (ix timestamp);
+insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000);
+select * from t1;
ix
19991101000000
19990102030405
@@ -16,6 +34,21 @@ ix
19990501000000
19991101000000
19990501000000
+drop table t1;
+CREATE TABLE t1 (date date, date_time datetime, time_stamp timestamp);
+INSERT INTO t1 VALUES ("1998-12-31","1998-12-31 23:59:59",19981231235959);
+INSERT INTO t1 VALUES ("1999-01-01","1999-01-01 00:00:00",19990101000000);
+INSERT INTO t1 VALUES ("1999-09-09","1999-09-09 23:59:59",19990909235959);
+INSERT INTO t1 VALUES ("2000-01-01","2000-01-01 00:00:00",20000101000000);
+INSERT INTO t1 VALUES ("2000-02-28","2000-02-28 00:00:00",20000228000000);
+INSERT INTO t1 VALUES ("2000-02-29","2000-02-29 00:00:00",20000229000000);
+INSERT INTO t1 VALUES ("2000-03-01","2000-03-01 00:00:00",20000301000000);
+INSERT INTO t1 VALUES ("2000-12-31","2000-12-31 23:59:59",20001231235959);
+INSERT INTO t1 VALUES ("2001-01-01","2001-01-01 00:00:00",20010101000000);
+INSERT INTO t1 VALUES ("2004-12-31","2004-12-31 23:59:59",20041231235959);
+INSERT INTO t1 VALUES ("2005-01-01","2005-01-01 00:00:00",20050101000000);
+INSERT INTO t1 VALUES ("2030-01-01","2030-01-01 00:00:00",20300101000000);
+SELECT * FROM t1;
date date_time time_stamp
1998-12-31 1998-12-31 23:59:59 19981231235959
1999-01-01 1999-01-01 00:00:00 19990101000000
@@ -29,3 +62,4 @@ date date_time time_stamp
2004-12-31 2004-12-31 23:59:59 20041231235959
2005-01-01 2005-01-01 00:00:00 20050101000000
2030-01-01 2030-01-01 00:00:00 20300101000000
+drop table t1;
diff --git a/mysql-test/r/type_uint.result b/mysql-test/r/type_uint.result
index 54fa717e0f8..1acfc700d3a 100644
--- a/mysql-test/r/type_uint.result
+++ b/mysql-test/r/type_uint.result
@@ -1,3 +1,9 @@
+drop table if exists t1;
+create table t1 (this int unsigned);
+insert into t1 values (1);
+insert into t1 values (-1);
+select * from t1;
this
1
0
+drop table t1;
diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result
index 7dc15a4dd1b..c892d575ca0 100644
--- a/mysql-test/r/type_year.result
+++ b/mysql-test/r/type_year.result
@@ -1,3 +1,6 @@
+create table t1 (y year,y2 year(2));
+insert into t1 values (0,0),(1999,1999),(2000,2000),(2001,2001),(70,70),(69,69);
+select * from t1;
y y2
0000 00
1999 99
@@ -5,6 +8,7 @@ y y2
2001 01
1970 70
2069 69
+select * from t1 order by y;
y y2
0000 00
1970 70
@@ -12,6 +16,7 @@ y y2
2000 00
2001 01
2069 69
+select * from t1 order by y2;
y y2
1970 70
1999 99
@@ -19,3 +24,4 @@ y y2
2000 00
2001 01
2069 69
+drop table t1;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
new file mode 100644
index 00000000000..896901dd8af
--- /dev/null
+++ b/mysql-test/r/union.result
@@ -0,0 +1,204 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+select a,b from t1 union select a,b from t2;
+a b
+1 a
+2 b
+3 c
+4 d
+5 f
+6 e
+select a,b from t1 union all select a,b from t2;
+a b
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+5 f
+6 e
+select a,b from t1 union all select a,b from t2 order by b;
+a b
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+6 e
+5 f
+select a,b from t1 union all select a,b from t2 union select 7,'g';
+a b
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+5 f
+6 e
+7 g
+select 0,'#' union select a,b from t1 union all select a,b from t2 union select 7,'gg';
+0 #
+0 #
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+5 f
+6 e
+7 g
+select a,b from t1 union select a,b from t1;
+a b
+1 a
+2 b
+3 c
+select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
+t1 b count(*)
+t1 a 1
+t1 b 1
+t1 c 2
+t2 c 1
+t2 d 1
+t2 e 1
+t2 f 1
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
+a b
+1 a
+2 b
+3 c
+4 d
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1);
+a b
+1 a
+2 b
+3 c
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+a b
+3 c
+2 b
+1 a
+explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+t2 ALL NULL NULL NULL NULL 4 Using filesort
+t1 ALL NULL NULL NULL NULL 4
+(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2;
+a b
+1 a
+2 b
+select found_rows();
+FOUND_ROWS()
+6
+explain select a,b from t1 union all select a,b from t2;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+t2 ALL NULL NULL NULL NULL 4
+explain select xx from t1 union select 1;
+Unknown column 'xx' in 'field list'
+explain select a,b from t1 union select 1;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+ 0 0 No tables used
+explain select 1 union select a,b from t1 union select 1;
+table type possible_keys key key_len ref rows Extra
+ 0 0 No tables used
+t1 ALL NULL NULL NULL NULL 4
+ 0 0 No tables used
+explain select a,b from t1 union select 1 limit 0;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+ 0 0 Impossible WHERE
+select a,b from t1 into outfile 'skr' union select a,b from t2;
+Wrong usage of UNION and INTO
+select a,b from t1 order by a union select a,b from t2;
+Wrong usage of UNION and ORDER BY
+insert into t3 select a from t1 order by a union select a from t2;
+Wrong usage of UNION and ORDER BY
+create table t3 select a,b from t1 union select a from t2;
+The used SELECT statements have a different number of columns
+select a,b from t1 union select a from t2;
+The used SELECT statements have a different number of columns
+select * from t1 union select a from t2;
+The used SELECT statements have a different number of columns
+select a from t1 union select * from t2;
+The used SELECT statements have a different number of columns
+select * from t1 union select SQL_BUFFER_RESULT * from t2;
+Wrong usage/placement of 'SQL_BUFFER_RESULT'
+create table t3 select a,b from t1 union all select a,b from t2;
+insert into t3 select a,b from t1 union all select a,b from t2;
+replace into t3 select a,b as c from t1 union all select a,b from t2;
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+`pseudo` char(35) NOT NULL default '',
+`pseudo1` char(35) NOT NULL default '',
+`same` tinyint(1) unsigned NOT NULL default '1',
+PRIMARY KEY (`pseudo1`),
+KEY `pseudo` (`pseudo`)
+) TYPE=MyISAM;
+INSERT INTO t1 (pseudo,pseudo1,same) VALUES ('joce', 'testtt', 1),('joce', 'tsestset', 1),('dekad', 'joce', 1);
+SELECT pseudo FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo FROM t1 WHERE pseudo='joce';
+pseudo
+dekad
+joce
+SELECT pseudo1 FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo1 FROM t1 WHERE pseudo='joce';
+pseudo1
+joce
+testtt
+tsestset
+SELECT * FROM t1 WHERE pseudo1='joce' UNION SELECT * FROM t1 WHERE pseudo='joce' order by pseudo desc,pseudo1 desc;
+pseudo pseudo1 same
+joce tsestset 1
+joce testtt 1
+dekad joce 1
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT pseudo FROM t1 WHERE pseudo1='joce';
+pseudo1
+testtt
+tsestset
+dekad
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION ALL SELECT pseudo FROM t1 WHERE pseudo1='joce';
+pseudo1
+testtt
+tsestset
+dekad
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT 1;
+pseudo1
+testtt
+tsestset
+1
+drop table t1;
+drop table if exists t1,t2;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2),(3),(4),(5);
+insert into t2 values (11),(12),(13),(14),(15);
+(select * from t1 limit 2) union (select * from t2 limit 3) limit 4;
+a
+1
+2
+11
+12
+(select * from t1 limit 2) union (select * from t2 limit 3);
+a
+1
+2
+11
+12
+13
+(select * from t1 limit 2) union (select * from t2 limit 20,3);
+a
+1
+2
+set SQL_SELECT_LIMIT=2;
+(select * from t1 limit 1) union (select * from t2 limit 3);
+a
+1
+11
+set SQL_SELECT_LIMIT=DEFAULT;
+drop table t1,t2;
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index bd34700e5ec..ba5c1c6e28f 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -1,3 +1,16 @@
+drop table if exists t1;
+create table t1 (a int auto_increment , primary key (a));
+insert into t1 values (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+update t1 set a=a+10 where a > 34;
+update t1 set a=a+100 where a > 0;
+update t1 set a=a+100 where a=1 and a=2;
+update t1 set a=b+100 where a=1 and a=2;
+Unknown column 'b' in 'field list'
+update t1 set a=b+100 where c=1 and a=2;
+Unknown column 'c' in 'where clause'
+update t1 set d=a+100 where a=1;
+Unknown column 'd' in 'field list'
+select * from t1;
a
101
102
@@ -35,7 +48,67 @@ a
134
145
146
+drop table t1;
+CREATE TABLE t1
+(
+place_id int (10) unsigned NOT NULL,
+shows int(10) unsigned DEFAULT '0' NOT NULL,
+ishows int(10) unsigned DEFAULT '0' NOT NULL,
+ushows int(10) unsigned DEFAULT '0' NOT NULL,
+clicks int(10) unsigned DEFAULT '0' NOT NULL,
+iclicks int(10) unsigned DEFAULT '0' NOT NULL,
+uclicks int(10) unsigned DEFAULT '0' NOT NULL,
+ts timestamp(14),
+PRIMARY KEY (place_id,ts)
+);
+INSERT INTO t1 (place_id,shows,ishows,ushows,clicks,iclicks,uclicks,ts)
+VALUES (1,0,0,0,0,0,0,20000928174434);
+UPDATE t1 SET shows=shows+1,ishows=ishows+1,ushows=ushows+1,clicks=clicks+1,iclicks=iclicks+1,uclicks=uclicks+1 WHERE place_id=1 AND ts>="2000-09-28 00:00:00";
+select place_id,shows from t1;
place_id shows
1 1
+drop table t1;
+CREATE TABLE t1 (
+lfdnr int(10) unsigned NOT NULL default '0',
+ticket int(10) unsigned NOT NULL default '0',
+client varchar(255) NOT NULL default '',
+replyto varchar(255) NOT NULL default '',
+subject varchar(100) NOT NULL default '',
+timestamp int(10) unsigned NOT NULL default '0',
+tstamp timestamp(14) NOT NULL,
+status int(3) NOT NULL default '0',
+type varchar(15) NOT NULL default '',
+assignment int(10) unsigned NOT NULL default '0',
+fupcount int(4) unsigned NOT NULL default '0',
+parent int(10) unsigned NOT NULL default '0',
+activity int(10) unsigned NOT NULL default '0',
+priority tinyint(1) unsigned NOT NULL default '1',
+cc varchar(255) NOT NULL default '',
+bcc varchar(255) NOT NULL default '',
+body text NOT NULL,
+comment text,
+header text,
+PRIMARY KEY (lfdnr),
+KEY k1 (timestamp),
+KEY k2 (type),
+KEY k3 (parent),
+KEY k4 (assignment),
+KEY ticket (ticket)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (773,773,'','','',980257344,20010318180652,0,'Open',10,0,0,0,1,'','','','','');
+alter table t1 change lfdnr lfdnr int(10) unsigned default 0 not null auto_increment;
+update t1 set status=1 where type='Open';
+select status from t1;
status
1
+drop table t1;
+create table t1 (a int not null, b int not null);
+insert into t1 values (1,1),(1,2),(1,3);
+update t1 set b=4 where a=1 order by b asc limit 1;
+update t1 set b=4 where a=1 order by b desc limit 1;
+select * from t1;
+a b
+1 4
+1 2
+1 4
+drop table t1;
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index e06a113bd29..5643900182e 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -1,16 +1,32 @@
+set @a := foo;
+Unknown column 'foo' in 'field list'
+set @a := connection_id() + 3;
+select @a - connection_id();
@a - connection_id()
3
+drop table if exists t1,t2;
+CREATE TABLE t1 ( i int not null, v int not null,index (i));
+insert into t1 values (1,1),(1,3),(2,1);
+create table t2 (i int not null, unique (i));
+insert into t2 select distinct i from t1;
+select * from t2;
i
1
2
+select distinct t2.i,@vv1:=if(sv1.i,1,0),@vv2:=if(sv2.i,1,0),@vv3:=if(sv3.i,1,0), @vv1+@vv2+@vv3 from t2 left join t1 as sv1 on sv1.i=t2.i and sv1.v=1 left join t1 as sv2 on sv2.i=t2.i and sv2.v=2 left join t1 as sv3 on sv3.i=t2.i and sv3.v=3;
i @vv1:=if(sv1.i,1,0) @vv2:=if(sv2.i,1,0) @vv3:=if(sv3.i,1,0) @vv1+@vv2+@vv3
1 1 0 1 2
2 1 0 0 1
+explain select * from t1 where i=@vv1;
table type possible_keys key key_len ref rows Extra
t1 ref i i 4 const 1 where used
+explain select * from t1 where @vv1:=@vv1+1 and i=@vv1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3 where used
+explain select @vv1:=i from t1 where i=@vv1;
table type possible_keys key key_len ref rows Extra
t1 index NULL i 4 NULL 3 where used; Using index
+explain select * from t1 where i=@vv1;
table type possible_keys key key_len ref rows Extra
t1 ref i i 4 const 1 where used
+drop table t1,t2;
diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result
index 62aeae21970..a63db14b736 100644
--- a/mysql-test/r/varbinary.result
+++ b/mysql-test/r/varbinary.result
@@ -1,6 +1,25 @@
+select 0x41,0x41+0,0x41 | 0x7fffffffffffffff | 0,0xffffffffffffffff | 0 ;
0x41 0x41+0 0x41 | 0x7fffffffffffffff | 0 0xffffffffffffffff | 0
-A 65 9223372036854775807 -1
+A 65 9223372036854775807 18446744073709551615
+select 0x31+1,concat(0x31)+1,-0xf;
0x31+1 concat(0x31)+1 -0xf
50 2 -15
+select x'31',X'ffff'+0;
+x'31' X'ffff'+0
+1 65535
+create table t1 (ID int(8) unsigned zerofill not null auto_increment,UNIQ bigint(21) unsigned zerofill not null,primary key (ID),unique (UNIQ) );
+insert into t1 set UNIQ=0x38afba1d73e6a18a;
+insert into t1 set UNIQ=123;
+explain select * from t1 where UNIQ=0x38afba1d73e6a18a;
table type possible_keys key key_len ref rows Extra
t1 const UNIQ UNIQ 8 const 1
+drop table t1;
+select x'hello';
+You have an error in your SQL syntax near 'x'hello'' at line 1
+select 0xfg;
+Unknown column '0xfg' in 'field list'
+create table t1 select 1 as x, 2 as xx;
+select x,xx from t1;
+x xx
+1 2
+drop table t1;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index adf8100f052..4227ecfdadb 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1,33 +1,320 @@
+drop table if exists t1;
+set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
+select @test,@`select`,@TEST,@not_used;
@test @`select` @TEST @not_used
1 2 3 NULL
+set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
+select @test_int,@test_double,@test_string,@test_string2,@select;
@test_int @test_double @test_string @test_string2 @select
10 1e-10 abcdeghi abcdefghij NULL
+set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";
+select @test_int,@test_double,@test_string,@test_string2;
@test_int @test_double @test_string @test_string2
hello hello hello hello
+set @test_int="hellohello",@test_double="hellohello",@test_string="hellohello",@test_string2="hellohello";
+select @test_int,@test_double,@test_string,@test_string2;
@test_int @test_double @test_string @test_string2
hellohello hellohello hellohello hellohello
+set @test_int=null,@test_double=null,@test_string=null,@test_string2=null;
+select @test_int,@test_double,@test_string,@test_string2;
@test_int @test_double @test_string @test_string2
NULL NULL NULL NULL
+select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
@t1:=(@t2:=1)+@t3:=4 @t1 @t2 @t3
5 5 1 4
+select @t5;
@t5
1.23456
+CREATE TABLE t1 (c_id INT(4) NOT NULL, c_name CHAR(20), c_country CHAR(3), PRIMARY KEY(c_id));
+INSERT INTO t1 VALUES (1,'Bozo','USA'),(2,'Ronald','USA'),(3,'Kinko','IRE'),(4,'Mr. Floppy','GB');
+SELECT @min_cid:=min(c_id), @max_cid:=max(c_id) from t1;
@min_cid:=min(c_id) @max_cid:=max(c_id)
1 4
+SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid;
c_id c_name c_country
1 Bozo USA
4 Mr. Floppy GB
+SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666;
c_id c_name c_country
1 Bozo USA
4 Mr. Floppy GB
+ALTER TABLE t1 DROP PRIMARY KEY;
+select * from t1 where c_id=@min_cid OR c_id=@max_cid;
c_id c_name c_country
1 Bozo USA
4 Mr. Floppy GB
+drop table t1;
+set max_join_size=100;
+show variables like 'max_join_size';
+Variable_name Value
+max_join_size 100
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size 4294967295
+set GLOBAL max_join_size=2000;
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size 2000
+set max_join_size=DEFAULT;
+show variables like 'max_join_size';
+Variable_name Value
+max_join_size 2000
+set GLOBAL max_join_size=DEFAULT;
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size 4294967295
+set @@max_join_size=1000, @@global.max_join_size=2000;
+select @@local.max_join_size, @@global.max_join_size;
+@@max_join_size @@max_join_size
+1000 2000
+select @@identity, length(@@version)>0;
+@@identity length(@@version)>0
+0 1
+select @@VERSION=version();
@@VERSION=version()
1
+select last_insert_id(345);
last_insert_id(345)
345
-@@IDENTITY last_insert_id()
-345 345
-@@IDENTITY
-345
+select @@IDENTITY,last_insert_id(), @@identity;
+@@identity last_insert_id() @@identity
+345 345 345
+set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
+set global concurrent_insert=ON;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set global concurrent_insert=1;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set global concurrent_insert=0;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert OFF
+set global concurrent_insert=OFF;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert OFF
+set global concurrent_insert=DEFAULT;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set table_type=MYISAM, table_type="HEAP", global table_type="INNODB";
+show local variables like 'table_type';
+Variable_name Value
+table_type HEAP
+show global variables like 'table_type';
+Variable_name Value
+table_type INNODB
+set GLOBAL query_cache_size=100000;
+set GLOBAL safe_show_database=0;
+set myisam_max_sort_file_size=10000, GLOBAL myisam_max_sort_file_size=20000;
+show variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size 10000
+show global variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size 20000
+set myisam_max_sort_file_size=default;
+show variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size 20000
+set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
+set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
+show global variables like 'net_%';
+Variable_name Value
+net_buffer_length 1024
+net_read_timeout 300
+net_retry_count 10
+net_write_timeout 200
+show session variables like 'net_%';
+Variable_name Value
+net_buffer_length 2048
+net_read_timeout 600
+net_retry_count 10
+net_write_timeout 500
+set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
+show global variables like 'net_%';
+Variable_name Value
+net_buffer_length 1024
+net_read_timeout 900
+net_retry_count 10
+net_write_timeout 1000
+show session variables like 'net_%';
+Variable_name Value
+net_buffer_length 7168
+net_read_timeout 600
+net_retry_count 10
+net_write_timeout 500
+set net_buffer_length=1;
+show variables like 'net_buffer_length';
+Variable_name Value
+net_buffer_length 1024
+set net_buffer_length=2000000000;
+show variables like 'net_buffer_length';
+Variable_name Value
+net_buffer_length 1048576
+set GLOBAL character set cp1251_koi8;
+show global variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+set character set cp1251_koi8;
+show variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+set global character set default, session character set default;
+show variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+select @@timestamp>0;
+@@timestamp>0
+1
+set big_tables=OFFF;
+Variable 'big_tables' can't be set to the value of 'OFFF'
+set big_tables="OFFF";
+Variable 'big_tables' can't be set to the value of 'OFFF'
+set unknown_variable=1;
+Unknown system variable 'unknown_variable'
+set max_join_size="hello";
+Wrong argument type to variable 'max_join_size'
+set table_type=UNKNOWN_TABLE_TYPE;
+Variable 'table_type' can't be set to the value of 'UNKNOWN_TABLE_TYPE'
+set table_type=INNODB, big_tables=2;
+Variable 'big_tables' can't be set to the value of '2'
+show local variables like 'table_type';
+Variable_name Value
+table_type HEAP
+set SESSION query_cache_size=10000;
+Variable 'query_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
+set GLOBAL table_type=DEFAULT;
+Variable 'table_type' doesn't have a default value
+set convert_character_set=UNKNOWN_CHARACTER_SET;
+Unknown character set: 'UNKNOWN_CHARACTER_SET'
+set character set unknown;
+Unknown character set: 'unknown'
+set character set 0;
+Wrong argument type to variable 'convert_character_set'
+set global autocommit=1;
+Variable 'autocommit' is a LOCAL variable and can't be used with SET GLOBAL
+select @@global.timestamp;
+Variable 'timestamp' is a LOCAL variable and can't be used with SET GLOBAL
+set @@version='';
+Unknown system variable 'version'
+set @@concurrent_insert=1;
+Variable 'concurrent_insert' is a GLOBAL variable and should be set with SET GLOBAL
+set @@global.sql_auto_is_null=1;
+Variable 'sql_auto_is_null' is a LOCAL variable and can't be used with SET GLOBAL
+select @@global.sql_auto_is_null;
+Variable 'sql_auto_is_null' is a LOCAL variable and can't be used with SET GLOBAL
+set autocommit=1;
+set big_tables=1;
+select @@autocommit, @@big_tables;
+@@autocommit @@big_tables
+1 1
+set global binlog_cache_size=100;
+set bulk_insert_buffer_size=100;
+set convert_character_set=cp1251_koi8;
+set convert_character_set=default;
+set @@global.concurrent_insert=1;
+set global connect_timeout=100;
+set global delay_key_write=1;
+set global delayed_insert_limit=100;
+set global delayed_insert_timeout=100;
+set global delayed_queue_size=100;
+set global flush=1;
+set global flush_time=100;
+set insert_id=1;
+set interactive_timeout=100;
+set join_buffer_size=100;
+set last_insert_id=1;
+set global local_infile=1;
+set long_query_time=100;
+set low_priority_updates=1;
+set max_allowed_packet=100;
+set global max_binlog_cache_size=100;
+set global max_binlog_size=100;
+set global max_connect_errors=100;
+set global max_connections=100;
+set global max_delayed_threads=100;
+set max_heap_table_size=100;
+set max_join_size=100;
+set max_sort_length=100;
+set max_tmp_tables=100;
+set global max_user_connections=100;
+select @@max_user_connections;
+@@max_user_connections
+100
+set global max_write_lock_count=100;
+set myisam_max_extra_sort_file_size=100;
+select @@myisam_max_extra_sort_file_size;
+@@myisam_max_extra_sort_file_size
+100
+set myisam_max_sort_file_size=100;
+set myisam_sort_buffer_size=100;
+set net_buffer_length=100;
+set net_read_timeout=100;
+set net_write_timeout=100;
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+set read_buffer_size=100;
+set read_rnd_buffer_size=100;
+set global rpl_recovery_rank=100;
+set global safe_show_database=1;
+set global server_id=100;
+set global slave_net_timeout=100;
+set global slow_launch_time=100;
+set sort_buffer_size=100;
+set sql_auto_is_null=1;
+select @@sql_auto_is_null;
+@@sql_auto_is_null
+1
+set @@sql_auto_is_null=0;
+select @@sql_auto_is_null;
+@@sql_auto_is_null
+0
+set sql_big_selects=1;
+set sql_big_tables=1;
+set sql_buffer_result=1;
+set sql_log_bin=1;
+set sql_log_off=1;
+set sql_log_update=1;
+set sql_low_priority_updates=1;
+set sql_max_join_size=200;
+select @@sql_max_join_size,@@max_join_size;
+@@sql_max_join_size @@max_join_size
+200 200
+set sql_quote_show_create=1;
+set sql_safe_updates=1;
+set sql_select_limit=1;
+set global sql_slave_skip_counter=100;
+set sql_warnings=1;
+set global table_cache=100;
+set table_type=myisam;
+set global thread_cache_size=100;
+set timestamp=1, timestamp=default;
+set tmp_table_size=100;
+set tx_isolation="READ-COMMITTED";
+set wait_timeout=100;
+set log_warnings=1;
+DROP TABLE IF EXISTS t1,t2;
+create table t1 (a int not null auto_increment, primary key(a));
+create table t2 (a int not null auto_increment, primary key(a));
+insert into t1 values(null),(null),(null);
+insert into t2 values(null),(null),(null);
+set global key_buffer_size=100000;
+select @@key_buffer_size;
+@@key_buffer_size
+98304
+select * from t1 where a=2;
+a
+2
+select * from t2 where a=3;
+a
+3
+check table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+drop table t1,t2;
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
new file mode 100644
index 00000000000..d77e98cc635
--- /dev/null
+++ b/mysql-test/r/warnings.result
@@ -0,0 +1,9 @@
+create table t1 (a int);
+insert into t1 values (1);
+insert into t1 values ("hej");
+insert into t1 values ("hej"),("då");
+set SQL_WARNINGS=1;
+insert into t1 values ("hej");
+insert into t1 values ("hej"),("då");
+drop table t1;
+set SQL_WARNINGS=0;
diff --git a/mysql-test/resolve-stack b/mysql-test/resolve-stack
new file mode 100755
index 00000000000..cdbe362c752
--- /dev/null
+++ b/mysql-test/resolve-stack
@@ -0,0 +1,8 @@
+#! /bin/sh
+# A shortcut for resolving stacks when debugging when
+# we cannot duplicate the crash in a debugger and have to
+# resort to using stack traces
+
+nm --numeric-sort ../sql/mysqld > var/tmp/mysqld.sym
+echo "Please type or paste the numeric stack trace,Ctrl-C to quit:"
+../extra/resolve_stack_dump -s var/tmp/mysqld.sym
diff --git a/mysql-test/std_data/des_key_file b/mysql-test/std_data/des_key_file
new file mode 100644
index 00000000000..fa53802d449
--- /dev/null
+++ b/mysql-test/std_data/des_key_file
@@ -0,0 +1,4 @@
+5 default_password
+1 password1
+4 password4
+2 password2
diff --git a/mysql-test/std_data/gemini.dat b/mysql-test/std_data/gemini.dat
deleted file mode 100644
index c2e1045f5ac..00000000000
--- a/mysql-test/std_data/gemini.dat
+++ /dev/null
@@ -1,5 +0,0 @@
-65,-1,1
-379,-1,1
-468,-1,1
-469,-1,1
-508,-1,1
diff --git a/mysql-test/std_data/master-bin.001 b/mysql-test/std_data/master-bin.001
index fa30d8e5302..2ec2397acdd 100644
--- a/mysql-test/std_data/master-bin.001
+++ b/mysql-test/std_data/master-bin.001
Binary files differ
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index dbfbd4267d8..2b329f3ec6e 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -10,10 +10,14 @@ col3 varchar (20) not null,
col4 varchar(4) not null,
col5 enum('PENDING', 'ACTIVE', 'DISABLED') not null,
col6 int not null, to_be_deleted int);
+insert into t1 values (2,4,3,5,"PENDING",1,7);
alter table t1
add column col4_5 varchar(20) not null after col4,
-add column col7 varchar(30) not null after col6,
-add column col8 datetime not null, drop column to_be_deleted;
+add column col7 varchar(30) not null after col5,
+add column col8 datetime not null, drop column to_be_deleted,
+change column col2 fourth varchar(30) not null after col3,
+modify column col6 int not null first;
+select * from t1;
drop table t1;
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
@@ -73,6 +77,26 @@ OPTIMIZE TABLE t1;
DROP TABLE t1;
#
+# ALTER TABLE ... ENABLE/DISABLE KEYS
+
+create table t1 (n1 int not null, n2 int, n3 int, n4 float,
+ unique(n1),
+ key (n1, n2, n3, n4),
+ key (n2, n3, n4, n1),
+ key (n3, n4, n1, n2),
+ key (n4, n1, n2, n3) );
+alter table t1 disable keys;
+#let $1=10000;
+let $1=10;
+while ($1)
+{
+ eval insert into t1 values($1,RAND()*1000,RAND()*1000,RAND());
+ dec $1;
+}
+alter table t1 enable keys;
+drop table t1;
+
+#
# Drop and add an auto_increment column
#
@@ -82,3 +106,12 @@ alter table t1 drop i,add i int unsigned not null auto_increment, drop primary k
select * from t1;
drop table t1;
+#
+# Alter table and rename
+#
+
+create table t1 (i int unsigned not null auto_increment primary key);
+alter table t1 rename t2;
+alter table t2 rename t1, add c char(10) comment "no comment";
+show columns from t1;
+drop table t1;
diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test
index 1b5022f6e4c..3f56b3e47ce 100644
--- a/mysql-test/t/analyse.test
+++ b/mysql-test/t/analyse.test
@@ -2,6 +2,7 @@
# Test of procedure analyse
#
+drop table if exists t1,t2;
create table t1 (i int, j int);
insert into t1 values (1,2), (3,4), (5,6), (7,8);
select * from t1 procedure analyse();
diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test
index b9b8c244699..d86466572d8 100644
--- a/mysql-test/t/auto_increment.test
+++ b/mysql-test/t/auto_increment.test
@@ -2,6 +2,7 @@
# Test of auto_increment; The test for BDB tables is in bdb.test
#
+drop table if exists t1;
create table t1 (a int not null auto_increment,b int, primary key (a)) type=myisam auto_increment=3;
insert into t1 values (1,1),(NULL,3),(NULL,4);
delete from t1 where a=4;
@@ -18,20 +19,6 @@ insert into t1 values (NULL,9,9);
select * from t1;
drop table t1;
-create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam;
-insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
-delete from t1 where a=4 or a=2;
-insert into t1 values (NULL,4),(NULL,5),(6,6);
-select * from t1;
-delete from t1 where a=6;
-#show table status like "t1";
-replace t1 values (3,1);
-replace t1 values (3,3);
-ALTER TABLE t1 add c int;
-insert into t1 values (NULL,6,6);
-select * from t1;
-drop table t1;
-
create table t1 (
skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY,
sval char(20)
diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test
index 71343783d69..ad332cde646 100644
--- a/mysql-test/t/backup.test
+++ b/mysql-test/t/backup.test
@@ -40,9 +40,3 @@ unlock tables;
connection con1;
reap;
drop table t1;
-
-
-
-
-
-
diff --git a/mysql-test/t/bdb-crash.test b/mysql-test/t/bdb-crash.test
index 55e00ad2a5e..cdbc2dbe0e4 100644
--- a/mysql-test/t/bdb-crash.test
+++ b/mysql-test/t/bdb-crash.test
@@ -1,3 +1,4 @@
+-- source include/have_bdb.inc
# test for bug reported by Mark Steele
drop table if exists t1;
diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test
index 50698bb8df6..0df93b5f220 100644
--- a/mysql-test/t/bdb.test
+++ b/mysql-test/t/bdb.test
@@ -767,3 +767,19 @@ select INFO_NOTE from t1 where STR_DATE = '20010610';
select INFO_NOTE from t1 where STR_DATE < '20010610';
select INFO_NOTE from t1 where STR_DATE > '20010610';
drop table t1;
+
+#
+# Test problem with multi table delete which quickly shows up with bdb tables.
+#
+
+create table t1 (a int not null, b int, primary key (a)) type =bdb;
+create table t2 (a int not null, b int, primary key (a)) type =bdb;
+insert into t1 values (2, 3),(1, 7),(10, 7);
+insert into t2 values (2, 3),(1, 7),(10, 7);
+select * from t1;
+select * from t2;
+delete t1, t2 from t1, t2 where t1.a = t2.a;
+select * from t1;
+select * from t2;
+select * from t2;
+drop table t1,t2;
diff --git a/mysql-test/t/bench_count_distinct.test b/mysql-test/t/bench_count_distinct.test
index 62d456a3cf8..9059428bea4 100644
--- a/mysql-test/t/bench_count_distinct.test
+++ b/mysql-test/t/bench_count_distinct.test
@@ -1,12 +1,13 @@
drop table if exists t1;
create table t1(n int not null, key(n)) delay_key_write = 1;
let $1=100;
+disable_query_log;
while ($1)
{
eval insert into t1 values($1);
eval insert into t1 values($1);
dec $1;
}
-
+enable_query_log;
select count(distinct n) from t1;
drop table t1;
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index 6470b6f6a30..cec3e1ca45c 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -14,3 +14,26 @@ select * from t1 where a='18446744073709551615';
delete from t1 where a=18446744073709551615;
select * from t1;
drop table t1;
+
+create table t1 ( a int not null default 1, big bigint );
+insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615);
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+alter table t1 modify big bigint unsigned not null;
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+alter table t1 add key (big);
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+alter table t1 modify big bigint not null;
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+drop table t1;
+
+select CAST(1-2 AS UNSIGNED);
+select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
+select CONVERT('-1',UNSIGNED);
+select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
+select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
+select ~5, cast(~5 as signed);
+select cast(5 as unsigned) -6.0;
diff --git a/mysql-test/t/bulk_replace.test b/mysql-test/t/bulk_replace.test
new file mode 100644
index 00000000000..d366004c16f
--- /dev/null
+++ b/mysql-test/t/bulk_replace.test
@@ -0,0 +1,14 @@
+#
+# this is a test of bulk-insert code
+# as used by REPLACE
+#
+# by Monty
+#
+
+drop table if exists t1;
+CREATE TABLE t1 (a int, unique (a), b int not null, unique(b), c int not null, index(c));
+replace into t1 values (1,1,1),(2,2,2),(3,1,3);
+select * from t1;
+check table t1;
+drop table t1;
+
diff --git a/mysql-test/t/check.test b/mysql-test/t/check.test
index 62af9f92e65..947566e725b 100644
--- a/mysql-test/t/check.test
+++ b/mysql-test/t/check.test
@@ -5,14 +5,17 @@ drop table if exists t1;
#add a lot of keys to slow down check
create table t1(n int not null, key(n), key(n), key(n), key(n));
let $1=10000;
+disable_query_log;
while ($1)
{
eval insert into t1 values ($1);
dec $1;
}
-send check table t1 type=extended;
+enable_query_log;
+send check table t1 extended;
connection con2;
insert into t1 values (200000);
connection con1;
reap;
drop table t1;
+
diff --git a/mysql-test/t/count_distinct2-master.opt b/mysql-test/t/count_distinct2-master.opt
new file mode 100644
index 00000000000..d81cc55090d
--- /dev/null
+++ b/mysql-test/t/count_distinct2-master.opt
@@ -0,0 +1 @@
+--set-variable=max_heap_table_size=16384
diff --git a/mysql-test/t/count_distinct2.test b/mysql-test/t/count_distinct2.test
new file mode 100644
index 00000000000..d1bea7614c8
--- /dev/null
+++ b/mysql-test/t/count_distinct2.test
@@ -0,0 +1,79 @@
+drop table if exists t1;
+
+create table t1(n1 int, n2 int, s char(20), vs varchar(20), t text);
+insert into t1 values (1,11, 'one','eleven', 'eleven'),
+ (1,11, 'one','eleven', 'eleven'),
+ (2,11, 'two','eleven', 'eleven'),
+ (2,12, 'two','twevle', 'twelve'),
+ (2,13, 'two','thirteen', 'foo'),
+ (2,13, 'two','thirteen', 'foo'),
+ (2,13, 'two','thirteen', 'bar'),
+ (NULL,13, 'two','thirteen', 'bar'),
+ (2,NULL, 'two','thirteen', 'bar'),
+ (2,13, NULL,'thirteen', 'bar'),
+ (2,13, 'two',NULL, 'bar'),
+ (2,13, 'two','thirteen', NULL);
+
+select distinct n1 from t1;
+select count(distinct n1) from t1;
+
+select distinct n2 from t1;
+select count(distinct n2) from t1;
+
+select distinct s from t1;
+select count(distinct s) from t1;
+
+select distinct vs from t1;
+select count(distinct vs) from t1;
+
+select distinct t from t1;
+select count(distinct t) from t1;
+
+select distinct n1,n2 from t1;
+select count(distinct n1,n2) from t1;
+
+select distinct n1,s from t1;
+select count(distinct n1,s) from t1;
+
+select distinct s,n1,vs from t1;
+select count(distinct s,n1,vs) from t1;
+
+select distinct s,t from t1;
+select count(distinct s,t) from t1;
+
+select count(distinct n1), count(distinct n2) from t1;
+
+select count(distinct n2), n1 from t1 group by n1;
+drop table t1;
+
+# test the conversion from tree to MyISAM
+create table t1 (n int default NULL);
+let $1=5000;
+disable_query_log;
+while ($1)
+{
+ eval insert into t1 values($1);
+ dec $1;
+}
+enable_query_log;
+
+flush status;
+select count(distinct n) from t1;
+show status like 'Created_tmp_disk_tables';
+drop table t1;
+
+#test conversion from heap to MyISAM
+create table t1 (s text);
+let $1=5000;
+disable_query_log;
+while ($1)
+{
+ eval insert into t1 values('$1');
+ dec $1;
+}
+enable_query_log;
+flush status;
+select count(distinct s) from t1;
+show status like 'Created_tmp_disk_tables';
+drop table t1;
+
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 1a829eec6a3..99d4e5ae229 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -25,14 +25,10 @@ drop table if exists t1,t2;
!$1164 create table t1 (a int not null auto_increment,primary key (a)) type=heap;
!$1163 create table t1 (a int not null,b text) type=heap;
!$1171 create table t1 (a int ,primary key(a)) type=heap;
-!$1121 create table t1 (a int,b text, index(a)) type=isam;
-!$1073 create table t1 (a int,b text, index(b)) type=isam;
drop table if exists t1;
-!$1075 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam;
!$1164 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
!$1171 create table t1 (ordid int(8), primary key (ordid));
-!$1121 create table t1 (ordid int(8), unique (ordid)) type=isam;
-- error 1044,1
create table not_existing_database.test (a int);
@@ -71,6 +67,22 @@ select * from t2 where b="world";
drop table t1,t2;
#
+# Test types after CREATE ... SELECT
+#
+
+create table t1(x varchar(50) );
+create table t2 select x from t1 where 1=2;
+describe t1;
+describe t2;
+drop table t2;
+create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
+describe t2;
+drop table t2;
+create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt;
+describe t2;
+drop table t1,t2;
+
+#
# Test of primary key with 32 index
#
diff --git a/mysql-test/t/ctype_latin1_de-master.opt b/mysql-test/t/ctype_latin1_de-master.opt
new file mode 100644
index 00000000000..98accd58c46
--- /dev/null
+++ b/mysql-test/t/ctype_latin1_de-master.opt
@@ -0,0 +1 @@
+--default-character-set=latin1_de
diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test
new file mode 100644
index 00000000000..d39d7f6e5dd
--- /dev/null
+++ b/mysql-test/t/ctype_latin1_de.test
@@ -0,0 +1,46 @@
+#
+# Test latin_de character set
+#
+drop table if exists t1;
+create table t1 (a char (20) not null, b int not null auto_increment, index (a,b),index(b));
+insert into t1 (a) values ('ä'),('ac'),('ae'),('ad'),('Äc'),('aeb');
+insert into t1 (a) values ('üc'),('uc'),('ue'),('ud'),('Ü'),('ueb'),('uf');
+insert into t1 (a) values ('ö'),('oc'),('Öa'),('oe'),('od'),('Öc'),('oeb');
+insert into t1 (a) values ('s'),('ss'),('ß'),('ßb'),('ssa'),('ssc'),('ßa');
+insert into t1 (a) values ('eä'),('uü'),('öo'),('ää'),('ääa'),('aeae');
+insert into t1 (a) values ('q'),('a'),('u'),('o'),('é'),('É');
+select a,b from t1 order by a,b;
+select a,b from t1 order by upper(a),b;
+select a from t1 order by a desc;
+check table t1;
+select * from t1 where a like "ö%";
+select * from t1 where a like binary "%É%";
+select * from t1 where a like "%Á%";
+select * from t1 where a like "%U%";
+select * from t1 where a like "%ss%";
+drop table t1;
+
+# The following should all be true
+select strcmp('ä','ae'),strcmp('ae','ä'),strcmp('aeq','äq'),strcmp('äq','aeq');
+select strcmp('ss','ß'),strcmp('ß','ss'),strcmp('ßs','sss'),strcmp('ßq','ssq');
+
+# The following should all return -1
+select strcmp('ä','af'),strcmp('a','ä'),strcmp('ää','aeq'),strcmp('ää','aeaeq');
+select strcmp('ss','ßa'),strcmp('ß','ssa'),strcmp('sßa','sssb'),strcmp('s','ß');
+select strcmp('ö','oö'),strcmp('Ü','uü'),strcmp('ö','oeb');
+
+# The following should all return 1
+select strcmp('af','ä'),strcmp('ä','a'),strcmp('aeq','ää'),strcmp('aeaeq','ää');
+select strcmp('ßa','ss'),strcmp('ssa','ß'),strcmp('sssb','sßa'),strcmp('ß','s');
+select strcmp('u','öa'),strcmp('u','ö');
+
+#
+# Some other simple tests with the current character set
+#
+
+create table t1 (a varchar(10), key(a));
+insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
+select * from t1 where a like "abc%";
+select * from t1 where a like "test%";
+select * from t1 where a like "te_t";
+drop table t1;
diff --git a/mysql-test/t/dirty-close.test b/mysql-test/t/dirty_close.test
index 3ed22f26d5b..3ed22f26d5b 100644
--- a/mysql-test/t/dirty-close.test
+++ b/mysql-test/t/dirty_close.test
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index bf8a03ac40d..b850ec5d562 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -207,3 +207,14 @@ insert into t1 (a) values (1),(2),(3),(4),(1),(2),(3),(4);
select distinct a from t1 group by b,a having a > 2 order by a desc;
select distinct a,c from t1 group by b,c,a having a > 2 order by a desc;
drop table t1;
+
+#
+# Test problem with DISTINCT and ORDER BY DESC
+#
+
+create table t1 (a char(1), key(a)) type=myisam;
+insert into t1 values('1'),('1');
+select * from t1 where a >= '1';
+select distinct a from t1 order by a desc;
+select distinct a from t1 where a >= '1' order by a desc;
+drop table t1;
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index 2a45fe8253b..c92f2b1f3b9 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -11,33 +11,33 @@ create table t1(n int);
drop table t1;
select * from t1;
-#now test for a bug in drop database - it is important that the name
-#of the table is the same as the name of the database - in the original
-#code this triggered a bug
-drop database if exists foo;
-create database foo;
-drop database if exists foo;
-create database foo;
-create table foo.foo (n int);
-insert into foo.foo values (4);
-select * from foo.foo;
-drop database if exists foo;
-create database foo;
-drop database foo;
+# now test for a bug in drop database - it is important that the name
+# of the table is the same as the name of the database - in the original
+# code this triggered a bug
+drop database if exists mysqltest;
+create database mysqltest;
+drop database if exists mysqltest;
+create database mysqltest;
+create table mysqltest.mysqltest (n int);
+insert into mysqltest.mysqltest values (4);
+select * from mysqltest.mysqltest;
+drop database if exists mysqltest;
+create database mysqltest;
+drop database mysqltest;
# test drop/create database and FLUSH TABLES WITH READ LOCK
-drop database if exists foo;
+drop database if exists mysqltest;
flush tables with read lock;
---error 1209
-create database foo;
+--error 1209,1223;
+create database mysqltest;
unlock tables;
-create database foo;
+create database mysqltest;
show databases;
flush tables with read lock;
---error 1208
-drop database foo;
+--error 1208,1223;
+drop database mysqltest;
unlock tables;
-drop database foo;
+drop database mysqltest;
show databases;
-
-
+--error 1008
+drop database mysqltest;
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index 4491de1f82b..540aa4235cc 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -1,3 +1,11 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connection con1;
@@ -7,6 +15,7 @@ drop table if exists t2;
create table t2(n int);
insert into t2 values(3);
let $1=100;
+disable_query_log;
while ($1)
{
connection con1;
@@ -19,7 +28,7 @@ while ($1)
reap;
dec $1;
}
-
+enable_query_log;
connection con1;
select * from t1;
connection con2;
@@ -35,15 +44,15 @@ reap;
#test if drop database will wait until we release the global read lock
connection con1;
-drop database if exists foo;
-create database foo;
-create table foo.t1(n int);
-insert into foo.t1 values (23);
+drop database if exists mysqltest;
+create database mysqltest;
+create table mysqltest.t1(n int);
+insert into mysqltest.t1 values (23);
flush tables with read lock;
connection con2;
-send drop database foo;
+send drop database mysqltest;
connection con1;
-select * from foo.t1;
+select * from mysqltest.t1;
unlock tables;
connection con2;
reap;
@@ -57,3 +66,4 @@ connection con2;
insert into t1 values (345);
select * from t1;
drop table t1;
+
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 83e328ca616..65d5381d725 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -5,10 +5,49 @@
drop table if exists t1,t2,t3;
CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b));
-INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),('Full-text indexes', 'are called collections'),('Only MyISAM tables','support collections'),('Function MATCH ... AGAINST()','is used to do a search'),('Full-text search in MySQL', 'implements vector space model');
+INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
+ ('Full-text indexes', 'are called collections'),
+ ('Only MyISAM tables','support collections'),
+ ('Function MATCH ... AGAINST()','is used to do a search'),
+ ('Full-text search in MySQL', 'implements vector space model');
+
+# nl search
+
select * from t1 where MATCH(a,b) AGAINST ("collections");
select * from t1 where MATCH(a,b) AGAINST ("indexes");
select * from t1 where MATCH(a,b) AGAINST ("indexes collections");
+
+# UNION of fulltext's
+select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes");
+
+# boolean search
+
+select * from t1 where MATCH(a,b) AGAINST("support -collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("support +collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("sear*" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE);
+select *, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1;
+select *, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
+
+select * from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE);
+
+select * from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE);
+
+# boolean w/o index:
+
+select * from t1 where MATCH a AGAINST ("search" IN BOOLEAN MODE);
+select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE);
+
+#update/delete with fulltext index
+
delete from t1 where a like "MySQL%";
update t1 set a='some test foobar' where MATCH a,b AGAINST ('model');
delete from t1 where MATCH(a,b) AGAINST ("indexes");
@@ -77,14 +116,47 @@ CREATE TABLE t3 (
--error 1210
select * from t2 where MATCH inhalt AGAINST (t2.inhalt);
-
---error 1210
-select * from t2 where MATCH inhalt AGAINST (t2.inhalt);
-
--error 1191
select * from t2 where MATCH ticket AGAINST ('foobar');
-
--error 1210
select * from t2,t3 where MATCH (t2.inhalt,t3.inhalt) AGAINST ('foobar');
drop table t1,t2,t3;
+
+#
+# three more bugtests
+#
+
+CREATE TABLE t1 (
+ id int(11) auto_increment,
+ title varchar(100) default '',
+ PRIMARY KEY (id),
+ KEY ind5 (title),
+ FULLTEXT KEY FT1 (title)
+) TYPE=MyISAM;
+
+insert into t1 (title) values ('this is a test');
+select * from t1 where match title against ('test' in boolean mode);
+update t1 set title='this is A test' where id=1;
+check table t1;
+update t1 set title='this test once revealed a bug' where id=1;
+select * from t1;
+update t1 set title=NULL where id=1;
+
+drop table t1;
+
+# one more bug - const_table related
+
+CREATE TABLE t1 (a int(11), b text, FULLTEXT KEY (b)) TYPE=MyISAM;
+insert into t1 values (1,"I wonder why the fulltext index doesnt work?");
+SELECT * from t1 where MATCH (b) AGAINST ('apples');
+
+insert into t1 values (2,"fullaaa fullzzz");
+select * from t1 where match b against ('full*' in boolean mode);
+
+drop table t1;
+CREATE TABLE t1 ( id int(11) NOT NULL auto_increment primary key, mytext text NOT NULL, FULLTEXT KEY mytext (mytext)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'my small mouse'),(2,'la-la-la'),(3,'It is so funny'),(4,'MySQL Tutorial');
+select 8 from t1;
+drop table t1;
+
diff --git a/mysql-test/t/fulltext_cache.test b/mysql-test/t/fulltext_cache.test
index fc5f0e266b3..0b15e57a97b 100644
--- a/mysql-test/t/fulltext_cache.test
+++ b/mysql-test/t/fulltext_cache.test
@@ -26,10 +26,16 @@ INSERT INTO t2 VALUES (6,2,'um chocolate Snickers');
INSERT INTO t2 VALUES (7,1,'Bife');
INSERT INTO t2 VALUES (8,1,'Pizza de Salmao');
-SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi') as x FROM t1, t2
-WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
-SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi') as x FROM t2, t1
-WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
drop table t1, t2;
diff --git a/mysql-test/t/fulltext_distinct.test b/mysql-test/t/fulltext_distinct.test
new file mode 100644
index 00000000000..86e2f7ca1b4
--- /dev/null
+++ b/mysql-test/t/fulltext_distinct.test
@@ -0,0 +1,41 @@
+#
+# Test of fulltext index
+# bug reported by Tibor Simko <tibor.simko@cern.ch>
+#
+
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+ id mediumint unsigned NOT NULL auto_increment,
+ tag char(6) NOT NULL default '',
+ value text NOT NULL default '',
+ PRIMARY KEY (id),
+ KEY kt(tag),
+ KEY kv(value(15)),
+ FULLTEXT KEY kvf(value)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+ id_t2 mediumint unsigned NOT NULL default '0',
+ id_t1 mediumint unsigned NOT NULL default '0',
+ field_number tinyint unsigned NOT NULL default '0',
+ PRIMARY KEY (id_t2,id_t1,field_number),
+ KEY id_t1(id_t1)
+) TYPE=MyISAM;
+
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar111');
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar222');
+INSERT INTO t1 (tag,value) VALUES ('bar345','baz333 ar');
+
+INSERT INTO t2 VALUES (2231626,64280,0);
+INSERT INTO t2 VALUES (2231626,64281,0);
+INSERT INTO t2 VALUES (12346, 3, 1);
+
+SELECT * FROM t1; SELECT * FROM t2;
+
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333') AND t1.id = t2.id_t1;
+
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333' IN BOOLEAN MODE)
+AND t1.id = t2.id_t1;
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/fulltext_left_join.test b/mysql-test/t/fulltext_left_join.test
index d09d577d04b..abb1c8e8473 100644
--- a/mysql-test/t/fulltext_left_join.test
+++ b/mysql-test/t/fulltext_left_join.test
@@ -22,6 +22,8 @@ INSERT INTO t2 VALUES('456', 'lui');
select match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
from t1 left join t2 on t2.id=t1.id;
+select match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
+ from t1 left join t2 on t2.id=t1.id;
drop table t1, t2;
diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test
index 9f35d58e699..d5cb99ef0ee 100644
--- a/mysql-test/t/fulltext_order_by.test
+++ b/mysql-test/t/fulltext_order_by.test
@@ -9,17 +9,24 @@ INSERT INTO t1 (message) VALUES ("Testing"),("table"),("testbug"),
("steve"),("is"),("cool"),("steve is cool");
# basic MATCH
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve');
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve');
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
# MATCH + ORDER BY (with ft-ranges)
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a;
# MATCH + ORDER BY (with normal ranges) + UNIQUE
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a DESC;
# MATCH + ORDER BY + UNIQUE (const_table)
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
# ORDER BY MATCH
SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
drop table t1;
diff --git a/mysql-test/t/fulltext_var.test b/mysql-test/t/fulltext_var.test
new file mode 100644
index 00000000000..71213d1195a
--- /dev/null
+++ b/mysql-test/t/fulltext_var.test
@@ -0,0 +1,5 @@
+#
+# Fulltext configurable parameters
+#
+
+show variables like "ft\_%";
diff --git a/mysql-test/t/func_crypt.test b/mysql-test/t/func_crypt.test
index ddc0816e301..f01504d3691 100644
--- a/mysql-test/t/func_crypt.test
+++ b/mysql-test/t/func_crypt.test
@@ -1,2 +1,3 @@
-
select length(encrypt('foo', 'ff')) <> 0;
+--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
+select password('test'),length(encrypt('test')),encrypt('test','aa');
diff --git a/mysql-test/t/func_encrypt-master.opt b/mysql-test/t/func_encrypt-master.opt
new file mode 100644
index 00000000000..ab687810d5f
--- /dev/null
+++ b/mysql-test/t/func_encrypt-master.opt
@@ -0,0 +1 @@
+--loose-des-key-file=$MYSQL_TEST_DIR/std_data/des_key_file
diff --git a/mysql-test/t/func_encrypt.test b/mysql-test/t/func_encrypt.test
new file mode 100644
index 00000000000..3b6acc54ec9
--- /dev/null
+++ b/mysql-test/t/func_encrypt.test
@@ -0,0 +1,67 @@
+-- source include/have_openssl.inc
+
+drop table if exists t1;
+create table t1 (x blob);
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('a','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','a'));
+insert into t1 values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab'));
+insert into t1 values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc'));
+insert into t1 values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd'));
+insert into t1 values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde'));
+insert into t1 values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef'));
+insert into t1 values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg'));
+insert into t1 values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh'));
+insert into t1 values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi'));
+insert into t1 values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij'));
+insert into t1 values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('brown dog','sabakala'));
+insert into t1 values (des_encrypt('dog','sabakala'));
+insert into t1 values (des_encrypt('dog!','sabakala'));
+insert into t1 values (des_encrypt('dog!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!!','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+select hex(x), hex(des_decrypt(x,'sabakala')) from t1;
+select des_decrypt(x,'sabakala') as s from t1 having s like '%dog%';
+drop table t1;
+
+#
+# Test default keys
+#
+select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello"));
+select des_decrypt(des_encrypt("hello",4));
+select des_decrypt(des_encrypt("hello",'test'),'test');
+select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password'));
+select des_decrypt(des_encrypt("hello"),'default_password');
+select des_decrypt(des_encrypt("hello",4),'password4');
+
+# Test flush
+SET @a=des_decrypt(des_encrypt("hello"));
+flush des_key_file;
+select @a = des_decrypt(des_encrypt("hello"));
+
+# Test usage of wrong password
+select hex("hello");
+select hex(des_decrypt(des_encrypt("hello",4),'password2'));
+select hex(des_decrypt(des_encrypt("hello","hidden")));
diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test
index d160b04176c..09746fcc817 100644
--- a/mysql-test/t/func_like.test
+++ b/mysql-test/t/func_like.test
@@ -2,9 +2,19 @@
# Test of like
#
+drop table if exists t1;
create table t1 (a varchar(10), key(a));
insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
select * from t1 where a like "abc%";
+select * from t1 where a like "ABC%";
select * from t1 where a like "test%";
select * from t1 where a like "te_t";
+
+#
+# The following will test the Turbo Boyer-Moore code
+#
+select * from t1 where a like "%a%";
+select * from t1 where a like "%abcd%";
+select * from t1 where a like "%abc\d%";
+
drop table t1;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index b7200b2d144..68b94d2aeff 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -9,10 +9,11 @@ drop table if exists t1;
select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo';
select 'hello' 'monty';
select length('\n\t\r\b\0\_\%\\');
+select bit_length('\n\t\r\b\0\_\%\\');
select concat('monty',' was here ','again'),length('hello'),char(ascii('h'));
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
-select instr('hello','he');
-select position('ll' in 'hello'),position('a' in 'hello');
+select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
+select position(binary 'll' in 'hello'),position('a' in binary 'hello');
select left('hello',2),right('hello',2),substring('hello',2,2),mid('hello',1,5) ;
select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1)) ;
select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1);
@@ -35,8 +36,17 @@ select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
select replace('aaaa','a','b'),replace('aaaa','aa','b'),replace('aaaa','a','bb'),replace('aaaa','','b'),replace('bbbb','a','c');
select replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
select soundex(''),soundex('he'),soundex('hello all folks');
-select password('test'),length(encrypt('test')),encrypt('test','aa');
select md5('hello');
+select sha('abc');
+select sha1('abc');
+select aes_decrypt(aes_encrypt('abc','1'),'1');
+select aes_decrypt(aes_encrypt('abc','1'),1);
+select aes_encrypt(NULL,"a");
+select aes_encrypt("a",NULL);
+select aes_decrypt(NULL,"a");
+select aes_decrypt("a",NULL);
+select aes_decrypt("a","a");
+select aes_decrypt(aes_encrypt("","a"),"a");
select repeat('monty',5),concat('*',space(5),'*');
select reverse('abc'),reverse('abcd');
select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12');
diff --git a/mysql-test/t/func_system.test b/mysql-test/t/func_system.test
index b0bdbe472dd..052e0530cf6 100644
--- a/mysql-test/t/func_system.test
+++ b/mysql-test/t/func_system.test
@@ -2,5 +2,5 @@
# system functions
#
-select database(),user();
+select database(),user() like "%@%";
select version()>="3.23.29";
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index ec44009b1a6..f5ad2e21c73 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -15,6 +15,8 @@ select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between
select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
select -1.49 or -1.49,0.6 or 0.6;
+select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
+select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
#
# Wrong usage of functions
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index ffb0f8bbf1e..a052f5f2d92 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -19,13 +19,23 @@ select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31");
select month("2001-02-00"),year("2001-00-00");
select DAYOFYEAR("1997-03-03"), WEEK("1998-03-03"), QUARTER(980303);
select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322);
+
+# Test of week and yearweek
select week(19980101),week(19970101),week(19980101,1),week(19970101,1);
select week(19981231),week(19971231),week(19981231,1),week(19971231,1);
select week(19950101),week(19950101,1);
select yearweek('1981-12-31',1),yearweek('1982-01-01',1),yearweek('1982-12-31',1),yearweek('1983-01-01',1);
+select yearweek('1987-01-01',1),yearweek('1987-01-01');
+select week("2000-01-01",0) as '2000', week("2001-01-01",0) as '2001', week("2002-01-01",0) as '2002',week("2003-01-01",0) as '2003', week("2004-01-01",0) as '2004', week("2005-01-01",0) as '2005', week("2006-01-01",0) as '2006';
+select week("2000-01-06",0) as '2000', week("2001-01-06",0) as '2001', week("2002-01-06",0) as '2002',week("2003-01-06",0) as '2003', week("2004-01-06",0) as '2004', week("2005-01-06",0) as '2005', week("2006-01-06",0) as '2006';
+select week("2000-01-01",1) as '2000', week("2001-01-01",1) as '2001', week("2002-01-01",1) as '2002',week("2003-01-01",1) as '2003', week("2004-01-01",1) as '2004', week("2005-01-01",1) as '2005', week("2006-01-01",1) as '2006';
+select week("2000-01-06",1) as '2000', week("2001-01-06",1) as '2001', week("2002-01-06",1) as '2002',week("2003-01-06",1) as '2003', week("2004-01-06",1) as '2004', week("2005-01-06",1) as '2005', week("2006-01-06",1) as '2006';
+select yearweek("2000-01-01",0) as '2000', yearweek("2001-01-01",0) as '2001', yearweek("2002-01-01",0) as '2002',yearweek("2003-01-01",0) as '2003', yearweek("2004-01-01",0) as '2004', yearweek("2005-01-01",0) as '2005', yearweek("2006-01-01",0) as '2006';
+select yearweek("2000-01-06",0) as '2000', yearweek("2001-01-06",0) as '2001', yearweek("2002-01-06",0) as '2002',yearweek("2003-01-06",0) as '2003', yearweek("2004-01-06",0) as '2004', yearweek("2005-01-06",0) as '2005', yearweek("2006-01-06",0) as '2006';
+select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', yearweek("2002-01-01",1) as '2002',yearweek("2003-01-01",1) as '2003', yearweek("2004-01-01",1) as '2004', yearweek("2005-01-01",1) as '2005', yearweek("2006-01-01",1) as '2006';
+select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006';
select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
-select yearweek('1987-01-01',1),yearweek('1987-01-01');
select dayname("1962-03-03"),dayname("1962-03-03")+0;
select monthname("1972-03-04"),monthname("1972-03-04")+0;
diff --git a/mysql-test/t/gemini.test b/mysql-test/t/gemini.test
deleted file mode 100644
index 9d4451c3551..00000000000
--- a/mysql-test/t/gemini.test
+++ /dev/null
@@ -1,355 +0,0 @@
--- source include/have_gemini.inc
-
-#
-# Small basic test with ignore
-#
-
-drop table if exists t1;
-create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=gemini;
-
-insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
-select id, code, name from t1 order by id;
-
-update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
-select id, code, name from t1 order by id;
-update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
-select id, code, name from t1 order by id;
-
-drop table t1;
-
-#
-# A bit bigger test
-#
-
-CREATE TABLE t1 (
- id int(11) NOT NULL auto_increment,
- parent_id int(11) DEFAULT '0' NOT NULL,
- level tinyint(4) DEFAULT '0' NOT NULL,
- PRIMARY KEY (id),
- KEY parent_id (parent_id),
- KEY level (level)
-) type=gemini;
-INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
-update t1 set parent_id=parent_id+100;
-select * from t1 where parent_id=102;
-update t1 set id=id+1000;
-!$1062 update t1 set id=1024 where id=1009;
-select * from t1;
-update ignore t1 set id=id+1; # This will change all rows
-select * from t1;
-update ignore t1 set id=1023 where id=1010;
-select * from t1 where parent_id=102;
-explain select level from t1 where level=1;
-explain select level,id from t1 where level=1;
-explain select level,id,parent_id from t1 where level=1;
-select level,id from t1 where level=1;
-select level,id,parent_id from t1 where level=1;
-drop table t1;
-
-#
-# Test replace
-#
-
-CREATE TABLE t1 (
- gesuchnr int(11) DEFAULT '0' NOT NULL,
- benutzer_id int(11) DEFAULT '0' NOT NULL,
- PRIMARY KEY (gesuchnr,benutzer_id)
-) type=gemini;
-
-replace into t1 (gesuchnr,benutzer_id) values (2,1);
-replace into t1 (gesuchnr,benutzer_id) values (1,1);
-replace into t1 (gesuchnr,benutzer_id) values (1,1);
-select * from t1;
-drop table t1;
-
-#
-# test delete using hidden_primary_key
-#
-
-create table t1 (a int) type=gemini;
-insert into t1 values (1), (2);
-delete from t1 where a = 1;
-select * from t1;
-drop table t1;
-
-#
-# Test auto_increment on sub key
-#
-
-#create table t1 (a char(10) not null, b int not null auto_increment, primary key(a,b)) type=gemini;
-#insert into t1 values ("a",1),("b",2),("a",2),("c",1);
-#insert into t1 values ("a",NULL),("b",NULL),("c",NULL),("e",NULL);
-#insert into t1 (a) values ("a"),("b"),("c"),("d");
-#insert into t1 (a) values ('k'),('d');
-#insert into t1 (a) values ("a");
-#insert into t1 values ("d",last_insert_id());
-#select * from t1;
-#drop table t1;
-
-#
-# Test when reading on part of unique key
-#
-CREATE TABLE t1 (
- user_id int(10) DEFAULT '0' NOT NULL,
- name varchar(100),
- phone varchar(100),
- ref_email varchar(100) DEFAULT '' NOT NULL,
- detail varchar(200),
- PRIMARY KEY (user_id,ref_email)
-)type=gemini;
-
-INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
-select * from t1 where user_id=10292;
-INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
-select * from t1 where user_id=10292;
-select * from t1 where user_id>=10292;
-select * from t1 where user_id>10292;
-select * from t1 where user_id<10292;
-drop table t1;
-
-#
-# Test that keys are created in right order
-# - Needs ANALYZE TABLE to work - MikeF 2/12/01
-#
-#CREATE TABLE t1 (a int not null, b int not null,c int not null,
-#key(a),primary key(a,b), unique(c),key(a),unique(b)) type = gemini;
-#show index from t1;
-#drop table t1;
-
-#
-# Test of ALTER TABLE and gemini tables
-#
-
-#create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
-#alter table t1 type=gemini;
-#insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
-#select * from t1;
-#update t1 set col2='7' where col1='4';
-#select * from t1;
-#alter table t1 add co3 int not null;
-#select * from t1;
-#update t1 set col2='9' where col1='2';
-#select * from t1;
-#drop table t1;
-
-#
-# INSERT INTO gemini tables
-#
-
-create table t1 (a int not null , b int, primary key (a)) type = gemini;
-create table t2 (a int not null , b int, primary key (a)) type = myisam;
-insert into t1 VALUES (1,3) , (2,3), (3,3);
-select * from t1;
-insert into t2 select * from t1;
-select * from t2;
-delete from t1 where b = 3;
-select * from t1;
-insert into t1 select * from t2;
-select * from t1;
-select * from t2;
-drop table t1,t2;
-
-#
-# Search on unique key
-#
-
-CREATE TABLE t1 (
- id int(11) NOT NULL auto_increment,
- ggid varchar(32) binary DEFAULT '' NOT NULL,
- email varchar(64) DEFAULT '' NOT NULL,
- passwd varchar(32) binary DEFAULT '' NOT NULL,
- PRIMARY KEY (id),
- UNIQUE ggid (ggid)
-) TYPE=gemini;
-
-insert into t1 (ggid,passwd) values ('test1','xxx');
-insert into t1 (ggid,passwd) values ('test2','yyy');
-
-select * from t1 where ggid='test1';
-select * from t1 where passwd='xxx';
-select * from t1 where id=2;
-drop table t1;
-
-#
-# ORDER BY on not primary key
-#
-
-#CREATE TABLE t1 (
-# user_name varchar(12),
- #password text,
- #subscribed char(1),
- #user_id int(11) DEFAULT '0' NOT NULL,
- #quota bigint(20),
- #weight double,
- #access_date date,
- #access_time time,
- #approved datetime,
- #dummy_primary_key int(11) NOT NULL auto_increment,
- #PRIMARY KEY (dummy_primary_key)
-#) TYPE=gemini;
-#INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
-#INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
-#INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
-#INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
-#INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
-#select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
-#drop table t1;
-
-#
-# Testing of tables without primary keys
-#
-
-CREATE TABLE t1 (
- id int(11) NOT NULL auto_increment,
- parent_id int(11) DEFAULT '0' NOT NULL,
- level tinyint(4) DEFAULT '0' NOT NULL,
- KEY (id),
- KEY parent_id (parent_id),
- KEY level (level)
-) type=gemini;
-INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
-INSERT INTO t1 values (179,5,2);
-update t1 set parent_id=parent_id+100;
-select * from t1 where parent_id=102;
-update t1 set id=id+1000;
-update t1 set id=1024 where id=1009;
-select * from t1;
-update ignore t1 set id=id+1; # This will change all rows
-select * from t1;
-update ignore t1 set id=1023 where id=1010;
-select * from t1 where parent_id=102;
-explain select level from t1 where level=1;
-select level,id from t1 where level=1;
-select level,id,parent_id from t1 where level=1;
-select level,id from t1 where level=1 order by id;
-delete from t1 where level=1;
-select * from t1;
-drop table t1;
-
-#
-# Test of index only reads
-#
-CREATE TABLE t1 (
- sca_code char(6) NOT NULL,
- cat_code char(6) NOT NULL,
- sca_desc varchar(50),
- lan_code char(2) NOT NULL,
- sca_pic varchar(100),
- sca_sdesc varchar(50),
- sca_sch_desc varchar(16),
- PRIMARY KEY (sca_code, cat_code, lan_code)
-) type = gemini ;
-
-INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING');
-select count(*) from t1 where sca_code = 'PD';
-drop table t1;
-
-#
-# Test of opening table twice
-#
-CREATE TABLE t1 (a int not null, primary key (a)) type=gemini;
-insert into t1 values(1),(2),(3);
-select t1.a from t1 natural join t1 as t2 order by t1.a;
-drop table t1;
-
-#
-# Test rollback
-#
-
-select "test for rollback";
-create table t1 (n int not null primary key) type=gemini;
-set autocommit=0;
-insert into t1 values (4);
-commit;
-insert into t1 values (5);
-rollback;
-select n, "after rollback" from t1;
-insert into t1 values (5);
-commit;
-select n, "after commit" from t1;
-commit;
-insert into t1 values (6);
-!$1062 insert into t1 values (4);
-commit;
-select n, "after commit" from t1;
-set autocommit=1;
-insert into t1 values (7);
-!$1062 insert into t1 values (4);
-select n from t1;
-# nop
-rollback;
-drop table t1;
-
-#
-# Testing transactions
-#
-
-create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) type=gemini;
-insert into t1 values(1,'first');
-begin;
-insert into t1 values(2,'hamdouni');
-select id as afterbegin_id,nom as afterbegin_nom from t1;
-rollback;
-select id as afterrollback_id,nom as afterrollback_nom from t1;
-set autocommit=0;
-insert into t1 values(3,'mysql');
-select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
-rollback;
-select id as afterrollback_id,nom as afterrollback_nom from t1;
-set autocommit=1;
-drop table t1;
-
-#
-# Simple not autocommit test
-#
-
-CREATE TABLE t1 (id char(8) not null primary key, val int not null) type=gemini;
-insert into t1 values ('pippo', 12);
-!$1062 insert into t1 values ('pippo', 12); # Gives error
-delete from t1;
-delete from t1 where id = 'pippo';
-select * from t1;
-
-insert into t1 values ('pippo', 12);
-set autocommit=0;
-delete from t1;
-rollback;
-select * from t1;
-delete from t1;
-commit;
-select * from t1;
-drop table t1;
-set autocommit=1;
-
-#
-# The following simple tests failed at some point
-#
-
-CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) TYPE=gemini;
-INSERT INTO t1 VALUES (1, 'Jochen');
-select * from t1;
-drop table t1;
-
-CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) TYPE=gemini;
-set autocommit=0;
-INSERT INTO t1 SET _userid='marc@anyware.co.uk';
-COMMIT;
-SELECT * FROM t1;
-SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
-drop table t1;
-set autocommit=1;
-
-#
-# Test of load data infile
-#
-
-CREATE TABLE if not exists `t1` (
- `f1` int(11) unsigned NOT NULL default '0',
- `f2` tinyint(3) unsigned NOT NULL default '0',
- `f3` tinyint(3) unsigned NOT NULL default '0',
- PRIMARY KEY (`f1`)
-) TYPE=Gemini;
-lock table t1 write;
-load data infile ''../../std_data/gemini.dat' ignore into table t1 fields terminated by ',';
-select f1 from t1;
-drop table t1;
diff --git a/mysql-test/t/grant_cache-master.opt b/mysql-test/t/grant_cache-master.opt
new file mode 100644
index 00000000000..cfdce628e74
--- /dev/null
+++ b/mysql-test/t/grant_cache-master.opt
@@ -0,0 +1 @@
+--set-variable=query_cache_size=1355776
diff --git a/mysql-test/t/grant_cache.test b/mysql-test/t/grant_cache.test
new file mode 100644
index 00000000000..09ce1021fbf
--- /dev/null
+++ b/mysql-test/t/grant_cache.test
@@ -0,0 +1,104 @@
+-- source include/have_query_cache.inc
+
+#
+# Test grants with query cache
+#
+drop table if exists test.t1,mysqltest.t1,mysqltest.t2;
+reset query cache;
+flush status;
+connect (root,localhost,root,,test,0,master.sock);
+connection root;
+create database if not exists mysqltest;
+
+create table mysqltest.t1 (a int,b int,c int);
+create table mysqltest.t2 (a int,b int,c int);
+insert into mysqltest.t1 values (1,1,1),(2,2,2);
+insert into mysqltest.t2 values (3,3,3);
+create table test.t1 (a char (10));
+insert into test.t1 values ("test.t1");
+select * from t1;
+connect (root2,localhost,root,,mysqltest,0,master.sock);
+connection root2;
+# put queries in cache
+select * from t1;
+select a from t1;
+select c from t1;
+select * from t2;
+select * from mysqltest.t1,test.t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits%";
+
+# Create the test users
+grant SELECT on mysqltest.* to mysqltest_1@localhost;
+grant SELECT on mysqltest.t1 to mysqltest_2@localhost;
+grant SELECT on test.t1 to mysqltest_2@localhost;
+grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost;
+
+# The following queries should be fetched from cache
+connect (user1,localhost,mysqltest_1,,mysqltest,0,master.sock);
+connection user1;
+select "user1";
+select * from t1;
+# The pre and end space are intentional
+ select a from t1 ;
+select c from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# The following queries should be fetched from cache
+connect (user2,localhost,mysqltest_2,,mysqltest,0,master.sock);
+connection user2;
+select "user2";
+select * from t1;
+select a from t1;
+select c from t1;
+select * from mysqltest.t1,test.t1;
+--error 1142
+select * from t2;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# The following queries should not be fetched from cache
+connect (user3,localhost,mysqltest_3,,mysqltest,0,master.sock);
+connection user3;
+select "user3";
+--error 1143
+select * from t1;
+select a from t1;
+--error 1143
+select c from t1;
+--error 1142
+select * from t2;
+--error 1143
+select mysqltest.t1.c from test.t1,mysqltest.t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# Connect without a database
+connect (user4,localhost,mysqltest_1,,*NO-ONE*,0,master.sock);
+connection user4;
+select "user4";
+--error 1046
+select a from t1;
+# The following query is not cached before (different database)
+select * from mysqltest.t1,test.t1;
+# Cache a query with 'no database'
+select a from mysqltest.t1;
+select a from mysqltest.t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# Cleanup
+
+connection root;
+delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+flush privileges;
+drop table test.t1,mysqltest.t1,mysqltest.t2;
+drop database mysqltest;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 11408511e99..0c9197febb5 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -243,19 +243,61 @@ select sql_big_result spid,sum(userid) from t1 group by spid desc;
explain select sql_big_result score,count(*) from t1 group by score desc;
select sql_big_result score,count(*) from t1 group by score desc;
drop table t1;
+
+#
+# Compare with hash keys
+#
+
+CREATE TABLE t1 (a char(1));
+INSERT INTO t1 VALUES ('A'),('B'),('A'),('B'),('A'),('B'),(NULL),('a'),('b'),(NULL),('A'),('B'),(NULL);
+SELECT a FROM t1 GROUP BY a;
+SELECT a,count(*) FROM t1 GROUP BY a;
+SELECT a FROM t1 GROUP BY binary a;
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+SELECT binary a FROM t1 GROUP BY 1;
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+# Do the same tests with MyISAM temporary tables
+SET SQL_BIG_TABLES=1;
+SELECT a FROM t1 GROUP BY a;
+SELECT a,count(*) FROM t1 GROUP BY a;
+SELECT a FROM t1 GROUP BY binary a;
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+SELECT binary a FROM t1 GROUP BY 1;
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+SET SQL_BIG_TABLES=0;
+drop table t1;
+
+#
+# Test of key >= 256 bytes
+#
+
+CREATE TABLE t1 (
+ `a` char(193) default NULL,
+ `b` char(63) default NULL
+);
+INSERT INTO t1 VALUES ('abc','def'),('hij','klm');
+SELECT CONCAT(a, b) FROM t1 GROUP BY 1;
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+SELECT CONCAT(a, b),count(distinct a) FROM t1 GROUP BY 1;
+SELECT 1 FROM t1 GROUP BY CONCAT(a, b);
+INSERT INTO t1 values ('hij','klm');
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+DROP TABLE t1;
drop table if exists t1;
+
+#
+# Test problem with ORDER BY on a SUM() column
+#
+
create table t1 (One int unsigned, Two int unsigned, Three int unsigned, Four int unsigned);
-insert into t1 values (1,2,1,4);
-insert into t1 values (1,2,2,4);
-insert into t1 values (1,2,3,4);
-insert into t1 values (1,2,4,4);
-insert into t1 values (1,1,1,4);
-insert into t1 values (1,1,2,4);
-insert into t1 values (1,1,3,4);
-insert into t1 values (1,1,4,4);
-insert into t1 values (1,3,1,4);
-insert into t1 values (1,3,2,4);
-insert into t1 values (1,3,3,4);
-insert into t1 values (1,3,4,4);
+insert into t1 values (1,2,1,4),(1,2,2,4),(1,2,3,4),(1,2,4,4),(1,1,1,4),(1,1,2,4),(1,1,3,4),(1,1,4,4),(1,3,1,4),(1,3,2,4),(1,3,3,4),(1,3,4,4);
select One, Two, sum(Four) from t1 group by One,Two;
-drop table if exists t1;
+drop table t1;
+
+create table t1 (id integer primary key not null auto_increment, gender char(1));
+insert into t1 values (NULL, 'M'), (NULL, 'F'),(NULL, 'F'),(NULL, 'F'),(NULL, 'M');
+create table t2 (user_id integer not null, date date);
+insert into t2 values (1, '2002-06-09'),(2, '2002-06-09'),(1, '2002-06-09'),(3, '2002-06-09'),(4, '2002-06-09'),(4, '2002-06-09');
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender;
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender order by percentage;
+drop table t1,t2;
diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test
new file mode 100644
index 00000000000..4f1b11c80ff
--- /dev/null
+++ b/mysql-test/t/handler.test
@@ -0,0 +1,67 @@
+#
+# test of HANDLER ...
+#
+
+drop table if exists t1;
+create table t1 (a int, b char(10), key a(a), key b(a,b));
+insert into t1 values
+(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
+(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
+(20,"ggg"),(21,"hhh"),(22,"iii");
+handler t1 open as t2;
+handler t2 read a first;
+handler t2 read a next;
+handler t2 read a next;
+handler t2 read a prev;
+handler t2 read a last;
+handler t2 read a prev;
+handler t2 read a prev;
+
+handler t2 read a first;
+handler t2 read a prev;
+
+handler t2 read a last;
+handler t2 read a prev;
+handler t2 read a next;
+handler t2 read a next;
+
+handler t2 read a=(15);
+handler t2 read a=(16);
+
+!$1070 handler t2 read a=(19,"fff");
+
+handler t2 read b=(19,"fff");
+handler t2 read b=(19,"yyy");
+handler t2 read b=(19);
+
+!$1109 handler t1 read a last;
+
+handler t2 read a=(11);
+handler t2 read a>=(11);
+
+handler t2 read a=(18);
+handler t2 read a>=(18);
+handler t2 read a>(18);
+handler t2 read a<=(18);
+handler t2 read a<(18);
+
+handler t2 read a first limit 5;
+handler t2 read a next limit 3;
+handler t2 read a prev limit 10;
+
+handler t2 read a>=(16) limit 4;
+handler t2 read a>=(16) limit 2,2;
+handler t2 read a last limit 3;
+
+handler t2 read a=(19);
+handler t2 read a=(19) where b="yyy";
+
+handler t2 read first;
+handler t2 read next;
+alter table t1 type=MyISAM;
+handler t2 read next;
+!$1064 handler t2 read last;
+
+handler t2 close;
+drop table if exists t1;
+
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index fff5415976c..8dd7606d82b 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -48,3 +48,15 @@ GROUP BY e.id
HAVING chr_strand= -1 and end >= 0
AND start <= 999660;
drop table t1,t2;
+
+#
+# Test problem with having and MAX() IS NOT NULL
+#
+
+CREATE TABLE t1 (Fld1 int(11) default NULL,Fld2 int(11) default NULL);
+INSERT INTO t1 VALUES (1,10),(1,20),(2,NULL),(2,NULL),(3,50);
+select Fld1, max(Fld2) as q from t1 group by Fld1 having q is not null;
+select Fld1, max(Fld2) from t1 group by Fld1 having max(Fld2) is not null;
+select Fld1, max(Fld2) from t1 group by Fld1 having avg(Fld2) is not null;
+select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null;
+drop table t1;
diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test
index abb9e1fd1bc..ef7e3239a96 100644
--- a/mysql-test/t/heap.test
+++ b/mysql-test/t/heap.test
@@ -19,6 +19,12 @@ drop table t1;
create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps";
insert into t1 values(1,1),(2,2),(3,3),(4,4);
+delete from t1 where a > 0;
+select * from t1;
+drop table t1;
+
+create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps";
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
alter table t1 modify a int not null auto_increment, type=myisam, comment="new myisam table";
#show table status like "t1";
select * from t1;
@@ -100,3 +106,35 @@ update t1 set new_col=btn;
explain select * from t1 where btn="a";
explain select * from t1 where btn="a" and new_col="a";
drop table t1;
+
+#
+# Test of NULL keys
+#
+
+CREATE TABLE t1 (
+ a int default NULL,
+ b int default NULL,
+ KEY a (a),
+ UNIQUE b (b)
+) type=heap;
+INSERT INTO t1 VALUES (NULL,99),(99,NULL),(1,1),(2,2),(1,3);
+SELECT * FROM t1 WHERE a=NULL;
+explain SELECT * FROM t1 WHERE a IS NULL;
+SELECT * FROM t1 WHERE a<=>NULL;
+SELECT * FROM t1 WHERE b=NULL;
+explain SELECT * FROM t1 WHERE b IS NULL;
+SELECT * FROM t1 WHERE b<=>NULL;
+
+--error 1062
+INSERT INTO t1 VALUES (1,3);
+DROP TABLE t1;
+
+#
+# Test when deleting all rows
+#
+
+CREATE TABLE t1 (a int not null, primary key(a)) type=heap;
+INSERT into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11);
+DELETE from t1 where a < 100;
+SELECT * from t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index a962f120d4e..1b7ee99e15a 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -515,6 +515,53 @@ select * from t1;
drop table t1;
#
+# Test DROP DATABASE
+#
+
+create database mysqltest;
+create table mysqltest.t1 (a int not null) type= innodb;
+insert into mysqltest.t1 values(1);
+create table mysqltest.t2 (a int not null) type= myisam;
+insert into mysqltest.t2 values(1);
+create table mysqltest.t3 (a int not null) type= heap;
+insert into mysqltest.t3 values(1);
+commit;
+drop database mysqltest;
+# Don't check error message
+--error 12,12
+show tables from mysqltest;
+
+#
+# Test truncate table with and without auto_commit
+#
+
+set autocommit=0;
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+--error 1192
+truncate table t1;
+commit;
+truncate table t1;
+select * from t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+commit;
+drop table t1;
+set autocommit=1;
+
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+insert into t1 values(1),(2);
+select * from t1;
+truncate table t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+drop table t1;
+
+#
# Test of how ORDER BY works when doing it on the whole table
#
@@ -531,9 +578,63 @@ explain select a,b,c from t1;
drop table t1;
#
-# Check describe
+# Check describe & handler
#
-create table t1 (testint int not null default 1) type=innodb;
+create table t1 (t int not null default 1, key (t)) type=innodb;
desc t1;
+--error 1031
+handler t1 open t1;
+--error 1109
+handler t1 read t first;
+--error 1109
+handler t1 close;
drop table t1;
+
+#
+# Test of multi-table-delete
+#
+
+CREATE TABLE t1 (
+ number bigint(20) NOT NULL default '0',
+ cname char(15) NOT NULL default '',
+ carrier_id smallint(6) NOT NULL default '0',
+ privacy tinyint(4) NOT NULL default '0',
+ last_mod_date timestamp(14) NOT NULL,
+ last_mod_id smallint(6) NOT NULL default '0',
+ last_app_date timestamp(14) NOT NULL,
+ last_app_id smallint(6) default '-1',
+ version smallint(6) NOT NULL default '0',
+ assigned_scps int(11) default '0',
+ status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t1 VALUES (4077711111,'SeanWheeler',90,2,20020111112846,500,00000000000000,-1,2,3,1);
+INSERT INTO t1 VALUES (9197722223,'berry',90,3,20020111112809,500,20020102114532,501,4,10,0);
+INSERT INTO t1 VALUES (650,'San Francisco',0,0,20011227111336,342,00000000000000,-1,1,24,1);
+INSERT INTO t1 VALUES (302467,'Sue\'s Subshop',90,3,20020109113241,500,20020102115111,501,7,24,0);
+INSERT INTO t1 VALUES (6014911113,'SudzCarwash',520,1,20020102115234,500,20020102115259,501,33,32768,0);
+INSERT INTO t1 VALUES (333,'tubs',99,2,20020109113440,501,20020109113440,500,3,10,0);
+CREATE TABLE t2 (
+ number bigint(20) NOT NULL default '0',
+ cname char(15) NOT NULL default '',
+ carrier_id smallint(6) NOT NULL default '0',
+ privacy tinyint(4) NOT NULL default '0',
+ last_mod_date timestamp(14) NOT NULL,
+ last_mod_id smallint(6) NOT NULL default '0',
+ last_app_date timestamp(14) NOT NULL,
+ last_app_id smallint(6) default '-1',
+ version smallint(6) NOT NULL default '0',
+ assigned_scps int(11) default '0',
+ status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t2 VALUES (4077711111,'SeanWheeler',0,2,20020111112853,500,00000000000000,-1,2,3,1);
+INSERT INTO t2 VALUES (9197722223,'berry',90,3,20020111112818,500,20020102114532,501,4,10,0);
+INSERT INTO t2 VALUES (650,'San Francisco',90,0,20020109113158,342,00000000000000,-1,1,24,1);
+INSERT INTO t2 VALUES (333,'tubs',99,2,20020109113453,501,20020109113453,500,3,10,0);
+select * from t1;
+select * from t2;
+delete t1, t2 from t1 left join t2 on t1.number=t2.number where (t1.carrier_id=90 and t1.number=t2.number) or (t2.carrier_id=90 and t1.number=t2.number) or (t1.carrier_id=90 and t2.number is null);
+select * from t1;
+select * from t2;
+select * from t2;
+drop table t1,t2;
diff --git a/mysql-test/t/innodb_cache-master.opt b/mysql-test/t/innodb_cache-master.opt
new file mode 100644
index 00000000000..5f0ebff98f6
--- /dev/null
+++ b/mysql-test/t/innodb_cache-master.opt
@@ -0,0 +1 @@
+--set-variable=query_cache_size=1M
diff --git a/mysql-test/t/innodb_cache.test b/mysql-test/t/innodb_cache.test
new file mode 100644
index 00000000000..21d30420eaf
--- /dev/null
+++ b/mysql-test/t/innodb_cache.test
@@ -0,0 +1,50 @@
+-- source include/have_innodb.inc
+-- source include/have_query_cache.inc
+
+#
+# Without auto_commit.
+#
+drop table if exists t1, t2, t3;
+flush status;
+set autocommit=0;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+commit;
+set autocommit=1;
+begin;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+commit;
+create table t1 (a int not null) type=innodb;
+create table t2 (a int not null) type=innodb;
+create table t3 (a int not null) type=innodb;
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+begin;
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+insert into t1 values (3);
+insert into t2 values (3);
+insert into t1 values (4);
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+commit;
+show status like "Qcache_queries_in_cache"; \ No newline at end of file
diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test
index cf6f41d454d..85798ec57f6 100644
--- a/mysql-test/t/insert.test
+++ b/mysql-test/t/insert.test
@@ -10,3 +10,41 @@ insert into t1 values (a+3);
insert into t1 values (4),(a+5);
select * from t1;
drop table t1;
+
+#
+# Test of duplicate key values with packed keys
+#
+
+create table t1 (id int not null auto_increment primary key, username varchar(32) not null, unique (username));
+insert into t1 values (0,"mysql");
+insert into t1 values (0,"mysql ab");
+insert into t1 values (0,"mysql a");
+insert into t1 values (0,"r1manic");
+insert into t1 values (0,"r1man");
+drop table t1;
+
+#
+# Test insert syntax
+#
+
+create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello");
+insert into t1 values (default,default,default), (default,default,default), (4,0,"a"),(default,default,default);
+select a,t>0,c from t1;
+truncate table t1;
+insert into t1 set a=default,t=default,c=default;
+insert into t1 set a=default,t=default,c=default;
+insert into t1 set a=4,t=0,c="a";
+insert into t1 set a=default,t=default,c=default;
+select a,t>0,c from t1;
+drop table t1;
+
+#
+# Test of mysqld crash with fully qualified column names
+#
+
+drop database if exists foo;
+create database foo;
+use foo;
+create table t1 (c int);
+insert into foo.t1 set foo.t1.c = '1';
+drop database foo;
diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test
index 17ecb2d5a1f..42f65858d77 100644
--- a/mysql-test/t/insert_select.test
+++ b/mysql-test/t/insert_select.test
@@ -7,6 +7,64 @@ create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLI
insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY);
insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1;
+--error 1062
insert into t2 (payoutID) SELECT payoutID+10 FROM t1;
+insert ignore into t2 (payoutID) SELECT payoutID+10 FROM t1;
select * from t2;
drop table t1,t2;
+#
+# bug in bulk insert optimization
+# test case by Fournier Jocelyn <joc@presence-pc.com>
+#
+
+DROP TABLE IF EXISTS crash1,crash2;
+CREATE TABLE `crash1` (
+ `numeropost` bigint(20) unsigned NOT NULL default '0',
+ `icone` tinyint(4) unsigned NOT NULL default '0',
+ `numreponse` bigint(20) unsigned NOT NULL auto_increment,
+ `contenu` text NOT NULL,
+ `pseudo` varchar(50) NOT NULL default '',
+ `date` datetime NOT NULL default '0000-00-00 00:00:00',
+ `ip` bigint(11) NOT NULL default '0',
+ `signature` tinyint(1) unsigned NOT NULL default '0',
+ PRIMARY KEY (`numeropost`,`numreponse`)
+ ,KEY `ip` (`ip`),
+ KEY `date` (`date`),
+ KEY `pseudo` (`pseudo`),
+ KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+
+CREATE TABLE `crash2` (
+ `numeropost` bigint(20) unsigned NOT NULL default '0',
+ `icone` tinyint(4) unsigned NOT NULL default '0',
+ `numreponse` bigint(20) unsigned NOT NULL auto_increment,
+ `contenu` text NOT NULL,
+ `pseudo` varchar(50) NOT NULL default '',
+ `date` datetime NOT NULL default '0000-00-00 00:00:00',
+ `ip` bigint(11) NOT NULL default '0',
+ `signature` tinyint(1) unsigned NOT NULL default '0',
+ PRIMARY KEY (`numeropost`,`numreponse`),
+ KEY `ip` (`ip`),
+ KEY `date` (`date`),
+ KEY `pseudo` (`pseudo`),
+ KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+
+INSERT INTO crash2
+(numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES
+(9,1,56,'test','joce','2001-07-25 13:50:53'
+,3649052399,0);
+
+
+INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM crash2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+
+show variables like '%bulk%';
+
+INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM crash2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+
+DROP TABLE IF EXISTS crash1,crash2;
+
diff --git a/mysql-test/t/isam.test b/mysql-test/t/isam.test
index 1cf068b42ba..c7308c4b999 100644
--- a/mysql-test/t/isam.test
+++ b/mysql-test/t/isam.test
@@ -1,19 +1,66 @@
+-- source include/have_isam.inc
+
+drop table if exists t1,t2;
+
#
# Test possible problem with rows that are about 65535 bytes long
#
-create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
+create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a)) type=isam;
let $1=100;
+disable_query_log;
while ($1)
{
eval insert into t1 (b) values(repeat(char(65+$1),65540-$1));
dec $1;
}
-check table t1;
-repair table t1;
+enable_query_log;
delete from t1 where (a & 1);
-check table t1;
-repair table t1;
-check table t1;
+select sum(length(b)) from t1;
+drop table t1;
+
+#
+# Test of auto_increment; The test for BDB tables is in bdb.test
+#
+
+create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam;
+insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
+delete from t1 where a=4 or a=2;
+insert into t1 values (NULL,4),(NULL,5),(6,6);
+select * from t1;
+delete from t1 where a=6;
+#show table status like "t1";
+replace t1 values (3,1);
+replace t1 values (3,3);
+ALTER TABLE t1 add c int;
+insert into t1 values (NULL,6,6);
+select * from t1;
drop table t1;
+
+#
+# Test of some CREATE TABLE's that should fail
+#
+!$1121 create table t1 (a int,b text, index(a)) type=isam;
+!$1073 create table t1 (a int,b text, index(b)) type=isam;
+!$1075 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam;
+!$1121 create table t1 (ordid int(8), unique (ordid)) type=isam;
+drop table if exists t1;
+
+#
+# Test of some show commands
+#
+
+create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
+insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
+create table t2 type=isam select * from t1;
+optimize table t1;
+check table t1,t2;
+repair table t1,t2;
+check table t2,t1;
+lock tables t1 write;
+check table t2,t1;
+show columns from t1;
+show full columns from t1;
+show index from t1;
+drop table t1,t2;
diff --git a/mysql-test/t/isolation.test b/mysql-test/t/isolation.test
deleted file mode 100644
index d9750ecb351..00000000000
--- a/mysql-test/t/isolation.test
+++ /dev/null
@@ -1,208 +0,0 @@
-source include/have_gemini.inc
-source include/master-slave.inc;
-connection master;
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set autocommit=0;
-
-insert into t1 (f1) values ("test1"), ("bar");
-connection master1;
-!$1030 select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-insert into t1 (f1) values ("test2"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-!$-1217 select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-insert into t1 (f1) values ("test3"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-insert into t1 (f1) values ("test4"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test5"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test6"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test7"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test8"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test9"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test10"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test11"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test12"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test13"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test14"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test15"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test16"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test17"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test18"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test19"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test20"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-drop table t1;
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index d31db5c4837..18006e8fd22 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -1,7 +1,6 @@
#
# This failed for lia Perminov
#
-
drop table if exists t1,t2,t3;
create table t1 (id int primary key);
@@ -87,6 +86,7 @@ drop table t1, t2;
create table t1 (a int primary key);
insert into t1 values(1),(2);
select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a);
+--replace_result "31 tables" "XX tables" "63 tables" "XX tables"
--error 1116
select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a);
drop table t1;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index a8417fad876..1996c793880 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -160,3 +160,31 @@ SELECT * FROM t1 WHERE a='a' AND b=2;
SELECT * FROM t1 WHERE a='a' AND b in (2);
SELECT * FROM t1 WHERE a='a' AND b in (1,2);
drop table t1;
+
+#
+# Test of create key order
+#
+
+create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique);
+show keys from t1;
+drop table t1;
+
+#
+# Problem with UNIQUE() with NULL parts and auto increment
+#
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NULL, i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+drop table t1;
diff --git a/mysql-test/t/keywords.test b/mysql-test/t/keywords.test
index b9a1f34c715..3bd757aa069 100644
--- a/mysql-test/t/keywords.test
+++ b/mysql-test/t/keywords.test
@@ -8,3 +8,7 @@ insert into t1 values ("12:22:22","97:02:03","1997-01-02");
select * from t1;
select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1;
drop table t1;
+create table events(binlog int);
+insert into events values(1);
+select events.binlog from events;
+drop table events;
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index be6860a3cc3..6bcc43ac916 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -1,3 +1,11 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
connect (con1, localhost, root,,);
connect (con2, localhost, root,,);
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index 112761abd87..d4f6ce186cf 100644
--- a/mysql-test/t/limit.test
+++ b/mysql-test/t/limit.test
@@ -28,3 +28,5 @@ delete from t1 limit 0;
update t1 set i=3 limit 0;
select * from t1;
drop table t1;
+
+select 0 limit 0;
diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test
index 77354e63252..385713174d2 100644
--- a/mysql-test/t/lock.test
+++ b/mysql-test/t/lock.test
@@ -53,45 +53,3 @@ lock tables t1 write;
check table t2;
unlock tables;
drop table t1,t2;
-
-#test to see if select will get the lock ahead of low priority update
-connect (locker,localhost,root,,);
-connect (reader,localhost,root,,);
-connect (writer,localhost,root,,);
-
-connection locker;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 write;
-connection writer;
-send update low_priority t1 set n = 4;
-connection reader;
---sleep 2
-send select n from t1;
-connection locker;
---sleep 2
-unlock tables;
-connection writer;
-reap;
-connection reader;
-reap;
-drop table t1;
-
-connection locker;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 read;
-connection writer;
-send update low_priority t1 set n = 4;
-connection reader;
---sleep 2
-send select n from t1;
-connection locker;
---sleep 2
-unlock tables;
-connection writer;
-reap;
-connection reader;
-reap;
-drop table t1;
-
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
new file mode 100644
index 00000000000..53e9fd3393c
--- /dev/null
+++ b/mysql-test/t/lock_multi.test
@@ -0,0 +1,49 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
+#test to see if select will get the lock ahead of low priority update
+
+connect (locker,localhost,root,,);
+connect (reader,localhost,root,,);
+connect (writer,localhost,root,,);
+
+connection locker;
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 write;
+connection writer;
+send update low_priority t1 set n = 4;
+connection reader;
+--sleep 2
+send select n from t1;
+connection locker;
+--sleep 2
+unlock tables;
+connection writer;
+reap;
+connection reader;
+reap;
+drop table t1;
+
+connection locker;
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 read;
+connection writer;
+send update low_priority t1 set n = 4;
+connection reader;
+--sleep 2
+send select n from t1;
+connection locker;
+--sleep 2
+unlock tables;
+connection writer;
+reap;
+connection reader;
+reap;
+drop table t1;
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 238dd599664..86e787db0a3 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -2,7 +2,7 @@
# test of MERGE TABLES
#
-drop table if exists t1,t2,t3;
+drop table if exists t1,t2,t3,t4,t5,t6;
create table t1 (a int not null primary key auto_increment, message char(20));
create table t2 (a int not null primary key auto_increment, message char(20));
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
@@ -22,7 +22,7 @@ insert into t2 select NULL,message from t1;
insert into t1 select NULL,message from t2;
insert into t2 select NULL,message from t1;
insert into t1 select NULL,message from t2;
-create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(t1,t2);
+create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(test.t1,test.t2);
explain select * from t3 where a < 10;
explain select * from t3 where a > 10 and a < 20;
select * from t3 where a = 10;
@@ -31,6 +31,14 @@ select * from t3 where a > 10 and a < 20;
explain select a from t3 order by a desc limit 10;
select a from t3 order by a desc limit 10;
select a from t3 order by a desc limit 300,10;
+delete from t3 where a=3;
+select * from t3 where a < 10;
+delete from t3 where a >= 6 and a <= 8;
+select * from t3 where a < 10;
+update t3 set a=3 where a=9;
+select * from t3 where a < 10;
+update t3 set a=6 where a=7;
+select * from t3 where a < 10;
show create table t3;
# The following should give errors
@@ -114,3 +122,66 @@ insert into t2 values (1,1),(2,2),(0,0),(4,4),(5,5),(6,6);
flush tables;
select * from t3 where a=1 order by b limit 2;
drop table t3,t1,t2;
+
+#
+# [phi] testing INSERT_METHOD stuff
+#
+
+drop table if exists t6, t5, t4, t3, t2, t1;
+# first testing of common stuff with new parameters
+create table t1 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t2 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t3 (a int not null, b int not null, key(a,b)) UNION=(t1,t2) INSERT_METHOD=NO;
+create table t4 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=NO;
+create table t5 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+create table t6 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
+show create table t3;
+show create table t4;
+show create table t5;
+show create table t6;
+insert into t1 values (1,NULL),(1,NULL),(1,NULL),(1,NULL);
+insert into t2 values (2,NULL),(2,NULL),(2,NULL),(2,NULL);
+select * from t3 order by b,a limit 3;
+select * from t4 order by b,a limit 3;
+select * from t5 order by b,a limit 3,3;
+select * from t6 order by b,a limit 6,3;
+# now testing inserts and where the data gets written
+insert into t5 values (5,1),(5,2);
+insert into t6 values (6,1),(6,2);
+select * from t1 order by a,b;
+select * from t2 order by a,b;
+select * from t4 order by a,b;
+# preperation for next test
+insert into t3 values (3,1),(3,2),(3,3),(3,4);
+select * from t3 order by a,b;
+# now testing whether options are kept by alter table
+alter table t4 UNION=(t1,t2,t3);
+show create table t4;
+select * from t4 order by a,b;
+# testing switching off insert method and inserts again
+alter table t4 INSERT_METHOD=FIRST;
+show create table t4;
+insert into t4 values (4,1),(4,2);
+select * from t1 order by a,b;
+select * from t2 order by a,b;
+select * from t3 order by a,b;
+select * from t4 order by a,b;
+select * from t5 order by a,b;
+# auto_increment
+select 1;
+insert into t5 values (1,NULL),(5,NULL);
+insert into t6 values (2,NULL),(6,NULL);
+select * from t1 order by a,b;
+select * from t2 order by a,b;
+select * from t5 order by a,b;
+select * from t6 order by a,b;
+drop table if exists t6, t5, t4, t3, t2, t1;
+
+CREATE TABLE t1 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE t2 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,2), (2,2);
+CREATE TABLE t ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', KEY a (a,b)) TYPE=MRG_MyISAM UNION=(t1,t2);
+select max(b) from t where a = 2;
+select max(b) from t1 where a = 2;
+drop table if exists t,t1,t2;
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
new file mode 100644
index 00000000000..dc4d444d463
--- /dev/null
+++ b/mysql-test/t/multi_update.test
@@ -0,0 +1,82 @@
+#
+# Only run the test if we are using --big-test, because this test takes a
+# long time
+#
+#-- require r/big_test.require
+#eval select $BIG_TEST as using_big_test;
+
+drop table if exists t1,t2,t3;
+create table t1(id1 int not null auto_increment primary key, t char(12));
+create table t2(id2 int not null, t char(12));
+create table t3(id3 int not null, t char(12), index(id3));
+disable_query_log;
+let $1 = 100;
+while ($1)
+ {
+ let $2 = 5;
+ eval insert into t1(t) values ('$1');
+ while ($2)
+ {
+ eval insert into t2(id2,t) values ($1,'$2');
+ let $3 = 10;
+ while ($3)
+ {
+ eval insert into t3(id3,t) values ($1,'$2');
+ dec $3;
+ }
+ dec $2;
+ }
+ dec $1;
+ }
+enable_query_log;
+
+select count(*) from t1 where id1 > 95;
+select count(*) from t2 where id2 > 95;
+select count(*) from t3 where id3 > 95;
+
+update t1,t2,t3 set t1.t="aaa", t2.t="bbb", t3.t="cc" where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 90;
+select count(*) from t1 where t = "aaa";
+select count(*) from t1 where id1 > 90;
+select count(*) from t2 where t = "bbb";
+select count(*) from t2 where id2 > 90;
+select count(*) from t3 where t = "cc";
+select count(*) from t3 where id3 > 90;
+delete t1.*, t2.*, t3.* from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 95;
+
+check table t1, t2, t3;
+
+select count(*) from t1 where id1 > 95;
+select count(*) from t2 where id2 > 95;
+select count(*) from t3 where id3 > 95;
+
+delete t1, t2, t3 from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 5;
+select count(*) from t1 where id1 > 5;
+select count(*) from t2 where id2 > 5;
+select count(*) from t3 where id3 > 5;
+
+delete from t1, t2, t3 using t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 0;
+
+# These queries will force a scan of the table
+select count(*) from t1 where id1;
+select count(*) from t2 where id2;
+select count(*) from t3 where id3;
+
+drop table t1,t2,t3;
+create table t1(id1 int not null primary key, t varchar(100)) pack_keys = 1;
+create table t2(id2 int not null, t varchar(100), index(id2)) pack_keys = 1;
+disable_query_log;
+let $1 = 1000;
+while ($1)
+ {
+ let $2 = 5;
+ eval insert into t1 values ($1,'aaaaaaaaaaaaaaaaaaaa');
+ while ($2)
+ {
+ eval insert into t2(id2,t) values ($1,'bbbbbbbbbbbbbbbbb');
+ dec $2;
+ }
+ dec $1;
+ }
+enable_query_log;
+delete t1 from t1,t2 where t1.id1 = t2.id2 and t1.id1 > 500;
+drop table t1,t2;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index eb1d9a01020..c607cb4d63e 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -24,11 +24,13 @@ drop table t1;
create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
let $1=100;
+disable_query_log;
while ($1)
{
eval insert into t1 (b) values(repeat(char(65+$1),65550-$1));
dec $1;
}
+enable_query_log;
check table t1;
repair table t1;
delete from t1 where (a & 1);
@@ -64,3 +66,30 @@ explain select a,b from t1 order by b;
explain select a,b from t1;
explain select a,b,c from t1;
drop table t1;
+
+#
+# Test of REPAIR that once failed
+#
+CREATE TABLE `t1` (
+ `post_id` mediumint(8) unsigned NOT NULL auto_increment,
+ `topic_id` mediumint(8) unsigned NOT NULL default '0',
+ `post_time` datetime NOT NULL default '0000-00-00 00:00:00',
+ `post_text` text NOT NULL,
+ `icon_url` varchar(10) NOT NULL default '',
+ `sign` tinyint(1) unsigned NOT NULL default '0',
+ `post_edit` varchar(150) NOT NULL default '',
+ `poster_login` varchar(35) NOT NULL default '',
+ `ip` varchar(15) NOT NULL default '',
+ PRIMARY KEY (`post_id`),
+ KEY `post_time` (`post_time`),
+ KEY `ip` (`ip`),
+ KEY `poster_login` (`poster_login`),
+ KEY `topic_id` (`topic_id`),
+ FULLTEXT KEY `post_text` (`post_text`)
+) TYPE=MyISAM;
+
+INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
+
+REPAIR TABLE t1;
+CHECK TABLE t1;
+drop table t1;
diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test
index a010ab38e07..8bd9e806118 100644
--- a/mysql-test/t/null.test
+++ b/mysql-test/t/null.test
@@ -25,7 +25,6 @@ drop table t1;
# Test problem med index on NULL columns and testing with =NULL;
#
-DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
indexed_field int default NULL,
KEY indexed_field (indexed_field)
diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test
new file mode 100644
index 00000000000..8fe547db615
--- /dev/null
+++ b/mysql-test/t/olap.test
@@ -0,0 +1,27 @@
+drop table if exists sales;
+create table sales ( product varchar(32), country varchar(32), year int, profit int);
+insert into sales values ( 'Computer', 'India',2000, 1200),
+( 'TV', 'United States', 1999, 150),
+( 'Calculator', 'United States', 1999,50),
+( 'Computer', 'United States', 1999,1500),
+( 'Computer', 'United States', 2000,1500),
+( 'TV', 'United States', 2000, 150),
+( 'TV', 'India', 2000, 100),
+( 'TV', 'India', 2000, 100),
+( 'Calculator', 'United States', 2000,75),
+( 'Calculator', 'India', 2000,75),
+( 'TV', 'India', 1999, 100),
+( 'Computer', 'India', 1999,1200),
+( 'Computer', 'United States', 2000,1500),
+( 'Calculator', 'United States', 2000,75);
+--error 1235
+select product, country , year, sum(profit) from sales group by product, country, year with cube;
+--error 1235
+explain select product, country , year, sum(profit) from sales group by product, country, year with cube;
+--error 1235
+select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+--error 1235
+explain select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+--error 1235
+select product, country , year, sum(profit) from sales group by product, country, year with cube union all select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+drop table sales;
diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test
new file mode 100644
index 00000000000..8dfd0d8c2f9
--- /dev/null
+++ b/mysql-test/t/openssl_1.test
@@ -0,0 +1,6 @@
+# We test openssl. Result set is optimized to be compiled with --with-openssl but
+# SSL is swithced off in some reason
+-- source include/have_openssl_2.inc
+
+SHOW STATUS LIKE 'SSL%';
+
diff --git a/mysql-test/t/openssl_2.test b/mysql-test/t/openssl_2.test
new file mode 100644
index 00000000000..12f1240f3af
--- /dev/null
+++ b/mysql-test/t/openssl_2.test
@@ -0,0 +1,5 @@
+# We want to test everything with SSL turned on.
+-- source include/have_openssl_2.inc
+
+SHOW STATUS LIKE 'SSL%';
+
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 16094206745..baa3fe67f0b 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -206,8 +206,53 @@ ORDER by lastchange_datum DESC LIMIT 2;
drop table t1;
#
-# Test optimizing bug with EQ_REF tables, where some ORDER BY parts where
-# wrongly removed.
+# Test optimization of ORDER BY DESC
+#
+
+create table t1 (a int not null, b int, c varchar(10), key (a, b, c));
+insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b');
+
+explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+explain select * from t1 where a >= 1 and a < 3 order by a desc;
+select * from t1 where a >= 1 and a < 3 order by a desc;
+explain select * from t1 where a = 1 order by a desc, b desc;
+select * from t1 where a = 1 order by a desc, b desc;
+explain select * from t1 where a = 1 and b is null order by a desc, b desc;
+select * from t1 where a = 1 and b is null order by a desc, b desc;
+explain select * from t1 where a >= 1 and a < 3 and b >0 order by a desc,b desc;
+explain select * from t1 where a = 2 and b >0 order by a desc,b desc;
+explain select * from t1 where a = 2 and b is null order by a desc,b desc;
+explain select * from t1 where a = 2 and (b is null or b > 0) order by a
+desc,b desc;
+explain select * from t1 where a = 2 and b > 0 order by a desc,b desc;
+explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
+
+#
+# Test things when we don't have NULL keys
+#
+
+alter table t1 modify b int not null, modify c varchar(10) not null;
+explain select * from t1 order by a, b, c;
+select * from t1 order by a, b, c;
+explain select * from t1 order by a desc, b desc, c desc;
+select * from t1 order by a desc, b desc, c desc;
+# test multiple ranges, NO_MAX_RANGE and EQ_RANGE
+explain select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+# test NEAR_MAX, NO_MIN_RANGE
+explain select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+select count(*) from t1 where a < 5 and b > 0;
+select * from t1 where a < 5 and b > 0 order by a desc,b desc;
+# test HA_READ_AFTER_KEY (at the end of the file), NEAR_MIN
+explain select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+# test HA_READ_AFTER_KEY (in the middle of the file)
+explain select * from t1 where a between 0 and 1 order by a desc, b desc;
+select * from t1 where a between 0 and 1 order by a desc, b desc;
+drop table t1;
+
CREATE TABLE t1 (
gid int(10) unsigned NOT NULL auto_increment,
diff --git a/mysql-test/t/order_fill_sortbuf-master.opt b/mysql-test/t/order_fill_sortbuf-master.opt
new file mode 100644
index 00000000000..116494d4588
--- /dev/null
+++ b/mysql-test/t/order_fill_sortbuf-master.opt
@@ -0,0 +1 @@
+--set-variable=sort_buffer=0
diff --git a/mysql-test/t/order_fill_sortbuf.test b/mysql-test/t/order_fill_sortbuf.test
new file mode 100644
index 00000000000..6419f2a93df
--- /dev/null
+++ b/mysql-test/t/order_fill_sortbuf.test
@@ -0,0 +1,21 @@
+#
+# This test does a create-select with ORDER BY, where there is so many
+# rows MySQL needs to use a merge during the sort phase.
+#
+
+drop table if exists t1,t2;
+CREATE TABLE `t1` (
+ `id` int(11) NOT NULL default '0',
+ `id2` int(11) NOT NULL default '0',
+ `id3` int(11) NOT NULL default '0');
+let $1=4000;
+disable_query_log;
+while ($1)
+ {
+ eval insert into t1 (id,id2,id3) values ($1,$1,$1);
+ dec $1;
+ }
+enable_query_log;
+create table t2 select id2 from t1 order by id3;
+select count(*) from t2;
+drop table t1,t2;
diff --git a/mysql-test/t/query_cache-master.opt b/mysql-test/t/query_cache-master.opt
new file mode 100644
index 00000000000..cfdce628e74
--- /dev/null
+++ b/mysql-test/t/query_cache-master.opt
@@ -0,0 +1 @@
+--set-variable=query_cache_size=1355776
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
new file mode 100644
index 00000000000..e7633f3bae0
--- /dev/null
+++ b/mysql-test/t/query_cache.test
@@ -0,0 +1,338 @@
+-- source include/have_query_cache.inc
+
+#
+# Tests with query cache
+#
+
+# Reset query cache variables.
+
+flush query cache; # This crashed in some versions
+flush query cache; # This crashed in some versions
+reset query cache;
+flush status;
+drop table if exists t1,t2,t3,t11,t21, mysqltest.t1;
+
+#
+# First simple test
+#
+
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+select * from t1;
+select sql_no_cache * from t1;
+select length(now()) from t1;
+
+# Only check the variables that are independent of the machine and startup
+# options
+
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+
+drop table t1;
+
+show status like "Qcache_queries_in_cache";
+
+#
+# MERGE TABLES with INSERT/UPDATE and DELETE
+#
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (4),(5),(6);
+create table t3 (a int not null) type=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+# insert
+select * from t3;
+select * from t3;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+insert into t2 values (7);
+show status like "Qcache_queries_in_cache";
+select * from t1;
+select * from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+insert into t3 values (8);
+show status like "Qcache_queries_in_cache";
+# update
+select * from t3;
+show status like "Qcache_queries_in_cache";
+update t2 set a=9 where a=7;
+show status like "Qcache_queries_in_cache";
+select * from t1;
+show status like "Qcache_queries_in_cache";
+update t3 set a=10 where a=1;
+show status like "Qcache_queries_in_cache";
+#delete
+select * from t3;
+show status like "Qcache_queries_in_cache";
+delete from t2 where a=9;
+show status like "Qcache_queries_in_cache";
+select * from t1;
+show status like "Qcache_queries_in_cache";
+delete from t3 where a=10;
+show status like "Qcache_queries_in_cache";
+drop table t1, t2, t3;
+#
+# FLUSH QUERY CACHE
+#
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (1),(2),(3);
+select * from t1;
+select * from t2;
+insert into t1 values (4);
+show status like "Qcache_free_blocks";
+flush query cache;
+show status like "Qcache_free_blocks";
+drop table t1, t2;
+# With join results...
+create table t1 (a text not null);
+create table t11 (a text not null);
+create table t2 (a text not null);
+create table t21 (a text not null);
+create table t3 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+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 t2 select * from t1;
+insert into t1 select * from t2;
+#results of t3 must be > 0.5Mb
+insert into t3 select * from t1;
+insert into t3 select * from t2;
+insert into t3 select * from t1;
+disable_result_log;
+select * from t11;
+select * from t21;
+enable_result_log;
+show status like "Qcache_total_blocks";
+show status like "Qcache_free_blocks";
+disable_result_log;
+insert into t11 values("");
+select * from t3;
+enable_result_log;
+show status like "Qcache_total_blocks";
+show status like "Qcache_free_blocks";
+flush query cache;
+show status like "Qcache_total_blocks";
+show status like "Qcache_free_blocks";
+drop table t1, t2, t3, t11, t21;
+#
+# SELECT SQL_CACHE ...
+#
+set query_cache_type=demand;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+select sql_cache * from t1;
+set query_cache_type=2;
+select sql_cache * from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+set query_cache_type=on;
+#
+# RESET QUERY CACHE
+#
+reset query cache;
+show status like "Qcache_queries_in_cache";
+#
+# SELECT SQL_NO_CACHE
+#
+select sql_no_cache * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+#
+# Check that queries that uses NOW(), LAST_INSERT_ID()... are not cached.
+#
+create table t1 (a text not null);
+select CONNECTION_ID() from t1;
+#GET_LOCK
+#RELEASE_LOCK
+#LOAD_FILE
+select FOUND_ROWS();
+select NOW() from t1;
+select CURDATE() from t1;
+select CURTIME() from t1;
+select DATABASE() from t1;
+select ENCRYPT("test") from t1;
+select LAST_INSERT_ID() from t1;
+select RAND() from t1;
+select UNIX_TIMESTAMP() from t1;
+select USER() from t1;
+select benchmark(1,1) from t1;
+show status like "Qcache_queries_in_cache";
+#
+# Tests when the cache is filled
+#
+create table t2 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2; # 2
+insert into t2 select * from t1; # 3
+insert into t1 select * from t2; # 5
+insert into t2 select * from t1; # 8
+insert into t1 select * from t2; # 13
+insert into t2 select * from t1; # 21
+insert into t1 select * from t2; # 34
+insert into t2 select * from t1; # 55
+insert into t1 select * from t2; # 89
+insert into t2 select * from t1; # 144
+insert into t1 select * from t2; # 233
+insert into t2 select * from t1; # 357
+insert into t1 select * from t2; # 610
+insert into t2 select * from t1; # 987
+insert into t1 select * from t2; # 1597
+insert into t2 select * from t1; # 2584
+insert into t1 select * from t2; # 4181
+
+show status like "Qcache_hits";
+disable_result_log;
+select a as a1, a as a2 from t1;
+select a as a2, a as a3 from t1;
+select a as a3, a as a4 from t1;
+# next query must be out of 1Mb cache
+select a as a1, a as a2 from t1;
+enable_result_log;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+reset query cache;
+#
+# Query bigger then query_cache_limit
+#
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+disable_result_log;
+select * from t1;
+enable_result_log;
+show status like "Qcache_queries_in_cache";
+drop table t1,t2;
+
+#
+# noncachable ODBC work around (and prepare cache for drop database)
+#
+create database if not exists mysqltest;
+create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i));
+insert into mysqltest.t1 (a) values (1);
+select * from mysqltest.t1 where i is null;
+
+#
+# drop db
+#
+select * from mysqltest.t1;
+show status like "Qcache_queries_in_cache";
+drop database mysqltest;
+show status like "Qcache_queries_in_cache";
+
+#
+# Charset convertion (cp1251_koi8 always present)
+#
+create table t1 (a char(1) not null);
+insert into t1 values("á");
+select * from t1;
+set CHARACTER SET cp1251_koi8;
+select * from t1;
+set CHARACTER SET DEFAULT;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+drop table t1;
+
+# The following tests can't be done as the values differen on 32 and 64 bit
+# machines :(
+#show variables like "query_cache_size";
+#show status like "Qcache_free_memory";
+
+#
+# same tables in different db
+#
+create database if not exists mysqltest;
+create table mysqltest.t1 (i int not null);
+create table t1 (i int not null);
+insert into mysqltest.t1 (i) values (1);
+insert into t1 (i) values (2);
+
+select * from t1;
+use mysqltest;
+select * from t1;
+select * from t1;
+use test;
+select * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+
+drop database mysqltest;
+drop table t1;
+
+#
+# FOUND_ROWS()
+#
+
+create table t1 (i int not null);
+insert into t1 (i) values (1),(2),(3),(4);
+
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select * from t1 where i=1;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select * from t1 where i=1;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+drop table t1;
+
+#
+# Test insert delayed
+#
+
+flush query cache;
+reset query cache;
+
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+select * from t1;
+show status like "Qcache_queries_in_cache";
+insert delayed into t1 values (4);
+--sleep 5 # Wait for insert delayed to be executed.
+select a from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+show status like "Qcache_queries_in_cache";
diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test
index 2a9cf113a47..ce4651d8de3 100644
--- a/mysql-test/t/rename.test
+++ b/mysql-test/t/rename.test
@@ -12,13 +12,19 @@ select * from t1;
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
select * from t1;
+
# The following should give errors
-!$1050 rename table t1 to t2;
-!$1050 rename table t1 to t1;
-!$1050 rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
+--error 1050,1050
+rename table t1 to t2;
+--error 1050,1050
+rename table t1 to t1;
+--error 1050,1050
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
show tables like "t_";
-!$1050 rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
-!$1017 rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
+--error 1050,1050
+rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
+--error 1017,1017
+rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
select * from t1;
select * from t2;
diff --git a/mysql-test/t/rpl000001.test b/mysql-test/t/rpl000001.test
index 113a9637dac..6d46124d238 100644
--- a/mysql-test/t/rpl000001.test
+++ b/mysql-test/t/rpl000001.test
@@ -1,11 +1,15 @@
+eval_result;
source include/master-slave.inc;
connection master;
use test;
drop table if exists t1,t3;
create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
-set password = password('foo');
-set password = password('');
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+eval load data local infile '$MYSQL_TEST_DIR/std_data/words.dat' into table t1;
+select * from t1;
+set password for root@"localhost" = password('foo');
+set password for root@"localhost" = password('');
create table t3(n int);
insert into t3 values(1),(2);
save_master_pos;
@@ -24,21 +28,38 @@ sync_with_master;
connection master;
reset master;
connection slave;
+slave stop;
reset slave;
connection master;
drop table if exists t1,t2;
create table t1(n int);
-let $1=10;
+#we want the log to exceed 16K to test deal with the log that is bigger than
+#IO_SIZE
+let $1=5000;
+disable_query_log;
while ($1)
{
- eval insert into t1 values($1);
+ eval insert into t1 values($1+get_lock("hold_slave",10)*0);
dec $1;
}
+enable_query_log;
+
+#try to cause a large relay log lag on the slave
+connection slave;
+select get_lock("hold_slave",10);
+slave start;
+#hope this is long enough for I/O thread to fetch over 16K relay log data
+sleep 1;
+select release_lock("hold_slave");
+unlock tables;
+
+connection master;
create table t2(id int);
insert into t2 values(connection_id());
save_master_pos;
+
connection master1;
#avoid generating result
create temporary table t1_temp(n int);
@@ -57,14 +78,14 @@ reap;
connection slave;
sync_with_master ;
#give the slave a chance to exit
-sleep 0.5;
+wait_for_slave_to_stop;
# The following test can't be done because the result of Pos will differ
# on different computers
# --replace_result 9306 9999 3334 9999 3335 9999
# show slave status;
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
select count(*) from t1;
connection master1;
diff --git a/mysql-test/t/rpl000002.test b/mysql-test/t/rpl000002.test
index 0c490e6316d..420ae27a337 100644
--- a/mysql-test/t/rpl000002.test
+++ b/mysql-test/t/rpl000002.test
@@ -1,4 +1,5 @@
source include/master-slave.inc;
+eval_result;
connection master;
use test;
drop table if exists t1;
@@ -11,6 +12,7 @@ use test;
sync_with_master;
select * from t1;
connection master;
+show slave hosts;
drop table t1;
save_master_pos;
connection slave;
diff --git a/mysql-test/t/rpl000009.test b/mysql-test/t/rpl000009.test
index 768c6c151b4..d45fe0870ff 100644
--- a/mysql-test/t/rpl000009.test
+++ b/mysql-test/t/rpl000009.test
@@ -1,5 +1,6 @@
-#this one assumes we are ignoring updates on tables in database foo, but doing
-#the ones in database bar
+# This one assumes we are ignoring updates on tables in database foo, but doing
+# the ones in database bar
+
source include/master-slave.inc;
connection master;
drop database if exists foo;
@@ -31,3 +32,57 @@ connection slave;
sync_with_master;
drop database if exists bar;
drop database if exists foo;
+
+# Now let's test load data from master
+
+# First create some databases and tables on the master
+
+connection master;
+set sql_log_bin = 0;
+create database foo;
+create database bar;
+show databases;
+create table foo.t1(n int, s char(20));
+create table foo.t2(n int, s text);
+insert into foo.t1 values (1, 'one'), (2, 'two'), (3, 'three');
+insert into foo.t2 values (11, 'eleven'), (12, 'twelve'), (13, 'thirteen');
+
+create table bar.t1(n int, s char(20));
+create table bar.t2(n int, s text);
+insert into bar.t1 values (1, 'one bar'), (2, 'two bar'), (3, 'three bar');
+insert into bar.t2 values (11, 'eleven bar'), (12, 'twelve bar'),
+ (13, 'thirteen bar');
+set sql_log_bin = 1;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# This should show that the slave is empty at this point
+show databases;
+load data from master;
+
+# Now let's check if we have the right tables and the right data in them
+show databases;
+use foo;
+show tables;
+use bar;
+show tables;
+select * from bar.t1;
+select * from bar.t2;
+
+# Now let's see if replication works
+connection master;
+insert into bar.t1 values (4, 'four bar');
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from bar.t1;
+
+# Now time for cleanup
+connection master;
+drop database bar;
+drop database foo;
+save_master_pos;
+connection slave;
+sync_with_master;
+
diff --git a/mysql-test/t/rpl000014.test b/mysql-test/t/rpl000014.test
index b501d63b10e..df15fa6e600 100644
--- a/mysql-test/t/rpl000014.test
+++ b/mysql-test/t/rpl000014.test
@@ -4,18 +4,19 @@ show master status;
save_master_pos;
connection slave;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
change master to master_log_pos=73;
slave stop;
+
change master to master_log_pos=73;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
slave start;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
change master to master_log_pos=173;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
connection master;
show master status;
@@ -25,7 +26,7 @@ create table foo (n int);
insert into foo values (1),(2),(3);
save_master_pos;
connection slave;
-change master to master_log_pos=73;
+change master to master_log_pos=79;
sync_with_master;
select * from foo;
connection master;
diff --git a/mysql-test/t/rpl000015-slave-master-info.opt b/mysql-test/t/rpl000015-slave-master-info.opt
index 80190bf6d29..28bc753dd56 100644
--- a/mysql-test/t/rpl000015-slave-master-info.opt
+++ b/mysql-test/t/rpl000015-slave-master-info.opt
@@ -1 +1 @@
---server-id=2
+--server-id=22 --master-connect-retry=7
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test
index 73a10bed7b3..c42e14699c5 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl000015.test
@@ -1,22 +1,26 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0, mysql-slave.sock);
+connect (master,localhost,root,,test,0,master.sock);
+connect (slave,localhost,root,,test,0, slave.sock);
connection master;
reset master;
show master status;
save_master_pos;
connection slave;
reset slave;
+--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
+
change master to master_host='127.0.0.1';
---replace_result 3306 9998 9306 9999 3334 9999 3335 9999
+# The following needs to be cleaned up when change master is fixed
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
show slave status;
+--replace_result $MASTER_MYPORT MASTER_PORT
eval change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=$MASTER_MYPORT;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
slave start;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
connection master;
drop table if exists t1;
@@ -31,4 +35,3 @@ drop table t1;
save_master_pos;
connection slave;
sync_with_master;
-
diff --git a/mysql-test/t/rpl000016-slave.opt b/mysql-test/t/rpl000016-slave.opt
new file mode 100644
index 00000000000..f27601e0d7d
--- /dev/null
+++ b/mysql-test/t/rpl000016-slave.opt
@@ -0,0 +1 @@
+-O max_binlog_size=2048
diff --git a/mysql-test/t/rpl000016-slave.sh b/mysql-test/t/rpl000016-slave.sh
index 62748605af1..9259f593e54 100755
--- a/mysql-test/t/rpl000016-slave.sh
+++ b/mysql-test/t/rpl000016-slave.sh
@@ -1 +1,2 @@
rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
+rm -f $MYSQL_TEST_DIR/var/slave-data/*relay*
diff --git a/mysql-test/t/rpl000016.test b/mysql-test/t/rpl000016.test
index c9b6ccabcd2..b830d0b8d91 100644
--- a/mysql-test/t/rpl000016.test
+++ b/mysql-test/t/rpl000016.test
@@ -1,14 +1,16 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
+connect (master,localhost,root,,test,0,master.sock);
+connect (slave,localhost,root,,test,0,slave.sock);
system cat /dev/null > var/slave-data/master.info;
system chmod 000 var/slave-data/master.info;
connection slave;
!slave start;
system chmod 600 var/slave-data/master.info;
!slave start;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
!eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT,
master_user='root';
reset slave;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT,
master_user='root';
connection master;
@@ -22,7 +24,7 @@ insert into t1 values('Could not break slave'),('Tried hard');
save_master_pos;
connection slave;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
select * from t1;
connection master;
@@ -49,11 +51,10 @@ insert into t2 values(NULL);
connection slave;
sync_with_master;
-#the slave may have already stopped, so we ignore the error
-!slave stop;
+wait_for_slave_to_stop;
#restart slave skipping one event
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
connection master;
@@ -69,19 +70,21 @@ insert into t2 values (65);
save_master_pos;
connection slave;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
select * from t2;
connection master;
let $1=100;
drop table if exists t3;
create table t3 (n int);
+disable_query_log;
while ($1)
{
#eval means expand $ expressions
eval insert into t3 values($1 + 4);
dec $1;
}
+enable_query_log;
show master logs;
show master status;
save_master_pos;
@@ -89,7 +92,7 @@ connection slave;
slave stop;
slave start;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
# because of concurrent insert, the table may not be up to date
# if we do not lock
diff --git a/mysql-test/t/rpl000017-slave.sh b/mysql-test/t/rpl000017-slave.sh
index 0588859c591..066b4880cc1 100755
--- a/mysql-test/t/rpl000017-slave.sh
+++ b/mysql-test/t/rpl000017-slave.sh
@@ -1,3 +1,5 @@
+rm -f $MYSQL_TEST_DIR/var/log/*relay*
+rm -f $MYSQL_TEST_DIR/var/slave-data/relay-log.info
cat > $MYSQL_TEST_DIR/var/slave-data/master.info <<EOF
master-bin.001
4
@@ -6,4 +8,5 @@ replicate
aaaaaaaaaaaaaaabthispartofthepasswordisnotused
$MASTER_MYPORT
1
+0
EOF
diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test
index 8e4e61cb9d6..f346ca39ca0 100644
--- a/mysql-test/t/rpl000017.test
+++ b/mysql-test/t/rpl000017.test
@@ -1,9 +1,9 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
+connect (master,localhost,root,,test,0,master.sock);
+connect (slave,localhost,root,,test,0,slave.sock);
connection master;
reset master;
-grant file on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
-grant file on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
connection slave;
slave start;
connection master;
diff --git a/mysql-test/t/rpl000018-master.sh b/mysql-test/t/rpl000018-master.sh
deleted file mode 100755
index e570f106ec6..00000000000
--- a/mysql-test/t/rpl000018-master.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-rm -f $MYSQL_TEST_DIR/var/master-data/master-bin.*
-cp $MYSQL_TEST_DIR/std_data/master-bin.001 $MYSQL_TEST_DIR/var/master-data/
-echo ./master-bin.001 > $MYSQL_TEST_DIR/var/master-data/master-bin.index
diff --git a/mysql-test/t/rpl000018.test b/mysql-test/t/rpl000018.test
index 44236323d1d..30d601bb375 100644
--- a/mysql-test/t/rpl000018.test
+++ b/mysql-test/t/rpl000018.test
@@ -1,5 +1,8 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
+require_manager;
+connect (master,localhost,root,,test,0,master.sock);
+connect (slave,localhost,root,,test,0,slave.sock);
+server_stop master;
+server_start master;
connection slave;
reset slave;
slave start;
diff --git a/mysql-test/t/rpl_compat.test b/mysql-test/t/rpl_compat.test
new file mode 100644
index 00000000000..9c67cce1680
--- /dev/null
+++ b/mysql-test/t/rpl_compat.test
@@ -0,0 +1,86 @@
+eval_result;
+source include/master-slave.inc;
+connection master;
+require_version 3.23;
+use test;
+drop table if exists t1,t3;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1;
+select * from t1;
+set password for root@"localhost" = password('foo');
+set password for root@"localhost" = password('');
+create table t3(n int);
+insert into t3 values(1),(2);
+save_master_pos;
+connection slave;
+sync_with_master;
+use test;
+select * from t3;
+select sum(length(word)) from t1;
+connection master;
+drop table t1,t3;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+#test handling of aborted connection in the middle of update
+connection master;
+reset master;
+connection slave;
+slave stop;
+reset slave;
+
+connection master;
+create table t1(n int);
+insert into t1 values (1),(2),(3);
+create table t2(id int);
+insert into t2 values(connection_id());
+save_master_pos;
+
+connection master1;
+#avoid generating result
+create temporary table t1_temp(n int);
+insert into t1_temp select get_lock('crash_lock%20C', 1) from t2;
+
+connection master;
+send update t1 set n = n + get_lock('crash_lock%20C', 2);
+connection master1;
+sleep 2;
+select (@id := id) - id from t2;
+kill @id;
+drop table t2;
+connection master;
+--error 1053;
+reap;
+connection slave;
+slave start;
+sync_with_master ;
+#now slave will hit an error
+wait_for_slave_to_stop;
+
+set global sql_slave_skip_counter=1;
+slave start;
+select count(*) from t1;
+connection master1;
+drop table t1;
+create table t1 (n int);
+insert into t1 values(3456);
+use mysql;
+insert into user (Host, User, Password)
+ VALUES ("10.10.10.%", "blafasel2", password("blafasel2"));
+select select_priv,user from mysql.user where user = 'blafasel2';
+update user set Select_priv = "Y" where User="blafasel2";
+select select_priv,user from mysql.user where user = 'blafasel2';
+use test;
+save_master_pos;
+connection slave;
+sync_with_master;
+select n from t1;
+select select_priv,user from mysql.user where user = 'blafasel2';
+connection master1;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+
diff --git a/mysql-test/t/rpl_empty_master_crash.test b/mysql-test/t/rpl_empty_master_crash.test
index 7c4437a3657..158b59169ee 100644
--- a/mysql-test/t/rpl_empty_master_crash.test
+++ b/mysql-test/t/rpl_empty_master_crash.test
@@ -3,6 +3,5 @@ connection master;
use test;
drop table if exists t1;
show slave status;
-#--error 1218 # for mysql-4.0
---error 1042
+--error 1218
load table t1 from master;
diff --git a/mysql-test/t/rpl_failsafe.test b/mysql-test/t/rpl_failsafe.test
new file mode 100644
index 00000000000..866efbce5bf
--- /dev/null
+++ b/mysql-test/t/rpl_failsafe.test
@@ -0,0 +1,24 @@
+require_manager;
+source include/master-slave.inc;
+connect (slave_sec,localhost,root,,test,0,slave.sock-1);
+connect (slave_ter,localhost,root,,test,0,slave.sock-2);
+connection master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
+create table t1(n int);
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
+connection slave_sec;
+slave start;
+sync_with_master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
+connection slave_ter;
+slave start;
+sync_with_master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
diff --git a/mysql-test/t/rpl_get_lock.test b/mysql-test/t/rpl_get_lock.test
index 3c33103e4c7..1d98eb16bb0 100644
--- a/mysql-test/t/rpl_get_lock.test
+++ b/mysql-test/t/rpl_get_lock.test
@@ -6,6 +6,8 @@ dirty_close master;
connection master1;
select get_lock("lock",2);
select release_lock("lock");
+#ignore
+disable_query_log;
let $1=2000;
while ($1)
{
@@ -13,11 +15,16 @@ while ($1)
do release_lock("lock");
dec $1;
}
+enable_query_log;
save_master_pos;
connection slave;
sync_with_master;
select get_lock("lock",3);
select * from t1;
+select is_free_lock("lock");
+# Check lock functions
+select is_free_lock("lock2");
+select is_free_lock(NULL);
connection master1;
drop table t1;
save_master_pos;
diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test
new file mode 100644
index 00000000000..3514d435737
--- /dev/null
+++ b/mysql-test/t/rpl_log.test
@@ -0,0 +1,57 @@
+source include/master-slave.inc;
+
+#clean up slave binlogs
+connection slave;
+slave stop;
+reset master;
+reset slave;
+let $VERSION=`select version()`;
+
+connection master;
+reset master;
+drop table if exists t1;
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL);
+drop table t1;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1;
+drop table t1;
+--replace_result $VERSION VERSION
+show binlog events;
+show binlog events from 79 limit 1;
+show binlog events from 79 limit 2;
+show binlog events from 79 limit 2,1;
+flush logs;
+create table t1 (n int);
+insert into t1 values (1);
+drop table t1;
+--replace_result $VERSION VERSION
+show binlog events;
+show binlog events in 'master-bin.002';
+show master logs;
+save_master_pos;
+connection slave;
+slave start;
+sync_with_master;
+show master logs;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION
+# We can't compare binlog from slave as the result differ between
+# machines based on where the LOAD DATA file is stored.
+disable_result_log;
+
+show binlog events in 'slave-bin.001' from 4;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION
+enable_result_log;
+show binlog events in 'slave-bin.002' from 4;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+show slave status;
+show new master for slave with master_log_file='master-bin.001' and
+ master_log_pos=4 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.001' and
+ master_log_pos=79 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.001' and
+ master_log_pos=311 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.002' and
+ master_log_pos=4 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.002' and
+ master_log_pos=122 and master_server_id=1;
diff --git a/mysql-test/t/rpl_magic.test b/mysql-test/t/rpl_magic.test
new file mode 100644
index 00000000000..376edc301d7
--- /dev/null
+++ b/mysql-test/t/rpl_magic.test
@@ -0,0 +1,31 @@
+source include/master-slave.inc;
+
+#first, make sure the slave has had enough time to register
+connection master;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+#discover slaves
+connection master;
+rpl_probe;
+
+#turn on master/slave query direction auto-magic
+enable_rpl_parse;
+drop table if exists t1;
+create table t1 ( n int);
+insert into t1 values (1),(2),(3),(4);
+disable_rpl_parse;
+save_master_pos;
+enable_rpl_parse;
+connection slave;
+sync_with_master;
+insert into t1 values(5);
+connection master;
+select * from t1;
+select * from t1;
+disable_rpl_parse;
+select * from t1;
+connection slave;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/rpl_mystery22.test b/mysql-test/t/rpl_mystery22.test
index 3a48ef84dc1..e987074697b 100644
--- a/mysql-test/t/rpl_mystery22.test
+++ b/mysql-test/t/rpl_mystery22.test
@@ -1,5 +1,6 @@
# test case to make slave thread get ahead by 22 bytes
+drop table if exists t1;
source include/master-slave.inc;
connection master;
# first, cause a duplicate key problem on the slave
diff --git a/mysql-test/t/rpl_sporadic_master.test b/mysql-test/t/rpl_sporadic_master.test
index c1a47781ddf..0487f868436 100644
--- a/mysql-test/t/rpl_sporadic_master.test
+++ b/mysql-test/t/rpl_sporadic_master.test
@@ -7,7 +7,7 @@ drop table if exists t1,t2;
create table t2(n int);
create table t1(n int not null auto_increment primary key);
insert into t1 values (NULL),(NULL);
-delete from t1;
+truncate table t1;
# We have to use 4 in the following to make this test work with all table types
insert into t1 values (4),(NULL);
save_master_pos;
@@ -18,10 +18,8 @@ slave start;
connection master;
insert into t1 values (NULL),(NULL);
flush logs;
-delete from t1;
-insert into t1 values (10),(NULL);
-insert into t1 values (NULL),(NULL);
-insert into t1 values (NULL),(NULL);
+truncate table t1;
+insert into t1 values (10),(NULL),(NULL),(NULL),(NULL),(NULL);
save_master_pos;
connection slave;
sync_with_master;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index cdb6ee57e0f..159746e4dde 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -1713,7 +1713,20 @@ show full columns from t2 from test like 's%';
show keys from t2;
#
+# Test of DO
+
+DO 1;
+DO benchmark(100,1+1),1,1;
+
+#
# Drop the test tables
#
drop table t4, t3,t2, t1;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 ( gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp(14) NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
+CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'NULL' AND b.sampletime < 'NULL' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test
new file mode 100644
index 00000000000..0a483c860cb
--- /dev/null
+++ b/mysql-test/t/select_found.test
@@ -0,0 +1,87 @@
+#
+# Testing of found_rows()
+#
+
+drop table if exists t1,t2;
+create table t1 (a int not null auto_increment, b int not null, primary key(a));
+insert into t1 (b) values (2),(3),(5),(5),(5),(6),(7),(9);
+select SQL_CALC_FOUND_ROWS * from t1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS * from t1 limit 1;
+select found_rows();
+select SQL_BUFFER_RESULT SQL_CALC_FOUND_ROWS * from t1 limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS * from t1 order by b desc limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS distinct b from t1 limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS b,count(*) as c from t1 group by b order by c desc limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS * from t1 left join t1 as t2 on (t1.b=t2.a) limit 2,1;
+select found_rows();
+drop table t1;
+
+#
+# Test SQL_CALC_FOUND_ROWS optimization when used with one table and filesort
+#
+
+create table t1 (a int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a desc limit 0,2;
+select FOUND_ROWS();
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a+2 desc limit 0,2;
+select FOUND_ROWS();
+drop table t1;
+
+#
+# Test of SQL_CALC_FOUND_ROWS with DISTINCT
+#
+
+CREATE TABLE t1 (
+`id` smallint(5) unsigned NOT NULL auto_increment,
+`kid` smallint(5) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+KEY `kid` (`kid`)
+);
+
+CREATE TABLE t2 (
+ id smallint(5) unsigned NOT NULL auto_increment,
+ name varchar(50) NOT NULL default '',
+ email varchar(50) NOT NULL default '',
+ PRIMARY KEY (id),
+ UNIQUE KEY e_n (email,name)
+);
+
+INSERT INTO t2 VALUES (1,'name1','email1'),(2,'name2','email2'),(3,'name3','email3'),(4,'name4','email4'),(5,'name5','email5'),(6,'name6','email6'),(7,'name7','email7'),(8,'name8','email8'),(9,'name9','email9'),(10,'name10','email10'),(11,'name11','email11'),(12,'name12','email12'),(13,'name13','email13'),(14,'name14','email14'),(15,'name15','email15'),(16,'name16','email16'),(17,'name17','email17'),(18,'name18','email18'),(19,'name19','email19'),(20,'name20','email20'),(21,'name21','email21'),(22,'name22','email22'),(23,'name23','email23'),(24,'name24','email24'),(25,'name25','email25'),(26,'name26','email26'),(27,'name27','email27'),(28,'name28','email28'),(29,'name29','email29'),(30,'name30','email30'),(31,'name31','email31'),(32,'name32','email32'),(33,'name33','email33'),(34,'name34','email34'),(35,'name35','email35'),(36,'name36','email36'),(37,'name37','email37'),(38,'name38','email38'),(39,'name39','email39'),(40,'name40','email40'),(41,'name41','email41'),(42,'name42','email42'),(43,'name43','email43'),(44,'name44','email44'),(45,'name45','email45'),(46,'name46','email46'),(47,'name47','email47'),(48,'name48','email48'),(49,'name49','email49'),(50,'name50','email50'),(51,'name51','email51'),(52,'name52','email52'),(53,'name53','email53'),(54,'name54','email54'),(55,'name55','email55'),(56,'name56','email56'),(57,'name57','email57'),(58,'name58','email58'),(59,'name59','email59'),(60,'name60','email60'),(61,'name61','email61'),(62,'name62','email62'),(63,'name63','email63'),(64,'name64','email64'),(65,'name65','email65'),(66,'name66','email66'),(67,'name67','email67'),(68,'name68','email68'),(69,'name69','email69'),(70,'name70','email70'),(71,'name71','email71'),(72,'name72','email72'),(73,'name73','email73'),(74,'name74','email74'),(75,'name75','email75'),(76,'name76','email76'),(77,'name77','email77'),(78,'name78','email78'),(79,'name79','email79'),(80,'name80','email80'),(81,'name81','email81'),(82,'name82','email82'),(83,'name83','email83'),(84,'name84','email84'),(85,'name85','email85'),(86,'name86','email86'),(87,'name87','email87'),(88,'name88','email88'),(89,'name89','email89'),(90,'name90','email90'),(91,'name91','email91'),(92,'name92','email92'),(93,'name93','email93'),(94,'name94','email94'),(95,'name95','email95'),(96,'name96','email96'),(97,'name97','email97'),(98,'name98','email98'),(99,'name99','email99'),(100,'name100','email100'),(101,'name101','email101'),(102,'name102','email102'),(103,'name103','email103'),(104,'name104','email104'),(105,'name105','email105'),(106,'name106','email106'),(107,'name107','email107'),(108,'name108','email108'),(109,'name109','email109'),(110,'name110','email110'),(111,'name111','email111'),(112,'name112','email112'),(113,'name113','email113'),(114,'name114','email114'),(115,'name115','email115'),(116,'name116','email116'),(117,'name117','email117'),(118,'name118','email118'),(119,'name119','email119'),(120,'name120','email120'),(121,'name121','email121'),(122,'name122','email122'),(123,'name123','email123'),(124,'name124','email124'),(125,'name125','email125'),(126,'name126','email126'),(127,'name127','email127'),(128,'name128','email128'),(129,'name129','email129'),(130,'name130','email130'),(131,'name131','email131'),(132,'name132','email132'),(133,'name133','email133'),(134,'name134','email134'),(135,'name135','email135'),(136,'name136','email136'),(137,'name137','email137'),(138,'name138','email138'),(139,'name139','email139'),(140,'name140','email140'),(141,'name141','email141'),(142,'name142','email142'),(143,'name143','email143'),(144,'name144','email144'),(145,'name145','email145'),(146,'name146','email146'),(147,'name147','email147'),(148,'name148','email148'),(149,'name149','email149'),(150,'name150','email150'),(151,'name151','email151'),(152,'name152','email152'),(153,'name153','email153'),(154,'name154','email154'),(155,'name155','email155'),(156,'name156','email156'),(157,'name157','email157'),(158,'name158','email158'),(159,'name159','email159'),(160,'name160','email160'),(161,'name161','email161'),(162,'name162','email162'),(163,'name163','email163'),(164,'name164','email164'),(165,'name165','email165'),(166,'name166','email166'),(167,'name167','email167'),(168,'name168','email168'),(169,'name169','email169'),(170,'name170','email170'),(171,'name171','email171'),(172,'name172','email172'),(173,'name173','email173'),(174,'name174','email174'),(175,'name175','email175'),(176,'name176','email176'),(177,'name177','email177'),(178,'name178','email178'),(179,'name179','email179'),(180,'name180','email180'),(181,'name181','email181'),(182,'name182','email182'),(183,'name183','email183'),(184,'name184','email184'),(185,'name185','email185'),(186,'name186','email186'),(187,'name187','email187'),(188,'name188','email188'),(189,'name189','email189'),(190,'name190','email190'),(191,'name191','email191'),(192,'name192','email192'),(193,'name193','email193'),(194,'name194','email194'),(195,'name195','email195'),(196,'name196','email196'),(197,'name197','email197'),(198,'name198','email198'),(199,'name199','email199'),(200,'name200','email200');
+
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+SELECT FOUND_ROWS();
+
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL order by email LIMIT 10;
+SELECT FOUND_ROWS();
+
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL ORDER BY email LIMIT 10;
+INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150');
+
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+SELECT FOUND_ROWS();
+
+drop table t1,t2;
+
+#
+# Test bug when using range optimization
+#
+
+CREATE TABLE `t1` (
+ `titre` char(80) NOT NULL default '',
+ `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+ `maxnumrep` int(10) unsigned NOT NULL default '0',
+ PRIMARY KEY (`numeropost`),
+ KEY `maxnumrep` (`maxnumrep`)
+) TYPE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (titre,maxnumrep) VALUES
+('test1','1'),('test2','2'),('test3','3');
+SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1;
+SELECT FOUND_ROWS();
+drop table t1;
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index e9c7ffa6bb8..5e10ebf23a3 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -1,30 +1,17 @@
#
# Test of some show commands
#
-drop table if exists t1,t2;
-create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
-insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
-create table t2 type=isam select * from t1;
-optimize table t1;
-check table t1,t2;
-repair table t1,t2;
-check table t2,t1;
-lock tables t1 write;
-check table t2,t1;
-show columns from t1;
-show full columns from t1;
-show index from t1;
-drop table t1,t2;
+drop table if exists t1,t2;
create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
-check table t1 type=fast;
-check table t1 type=fast;
-check table t1 type=changed;
+check table t1 fast;
+check table t1 fast;
+check table t1 changed;
insert into t1 values (5,5,5);
-check table t1 type=changed;
-check table t1 type=medium;
-check table t1 type=extended;
+check table t1 changed;
+check table t1 medium;
+check table t1 extended;
show index from t1;
!$1062 insert into t1 values (5,5,5);
optimize table t1;
@@ -74,6 +61,21 @@ create table t1 (a int not null, primary key (a));
show create table t1;
drop table t1;
+flush tables;
+show open tables;
+create table t1(n int);
+insert into t1 values (1);
+show open tables;
+drop table t1;
+
+create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
+show create table t1;
+alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
+show create table t1;
+ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default;
+show create table t1;
+drop table t1;
+
create table t1 (a decimal(9,2), b decimal (9,0), e double(9,2), f double(5,0), h float(3,2), i float(3,0));
show columns from t1;
drop table t1;
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index 70a7a3ab584..cffca437cf1 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -1,3 +1,11 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
@@ -6,7 +14,7 @@ show status like 'Table_lock%';
connection con1;
SET SQL_LOG_BIN=0;
drop table if exists t1;
-create table t1(n int);
+create table t1(n int) type=myisam;
insert into t1 values(1);
connection con2;
lock tables t1 read;
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
new file mode 100644
index 00000000000..586761921b8
--- /dev/null
+++ b/mysql-test/t/symlink.test
@@ -0,0 +1,89 @@
+-- require r/have_symlink.require
+disable_query_log;
+show variables like "have_symlink";
+enable_query_log;
+
+#
+# First create little data to play with
+#
+drop table if exists t1,t2,t7,t8,t9;
+create table t1 (a int not null auto_increment, b char(16) not null, primary key (a));
+create table t2 (a int not null auto_increment, b char(16) not null, primary key (a));
+insert into t1 (b) values ("test"),("test1"),("test2"),("test3");
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+drop table t2;
+
+#
+# Start the test
+# We use t9 here to not crash with tables generated by the backup test
+#
+
+disable_query_log;
+eval create table t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="$MYSQL_TEST_DIR/var/tmp" index directory="$MYSQL_TEST_DIR/var/run";
+enable_query_log;
+
+insert into t9 select * from t1;
+check table t9;
+optimize table t9;
+repair table t9;
+alter table t9 add column c int not null;
+show create table t9;
+
+# Test renames
+alter table t9 rename t8, add column d int not null;
+alter table t8 rename t7;
+rename table t7 to t9;
+# Drop old t1 table, keep t9
+drop table t1;
+
+#
+# Test error handling
+# Note that we are using the above table t9 here!
+#
+
+disable_query_log;
+--error 1103,1103
+create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="tmp";
+
+# Check that we cannot link over a table from another database.
+
+drop database if exists test_mysqltest;
+create database test_mysqltest;
+
+--error 1,1
+create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="/this-dir-does-not-exist";
+
+--error 1103,1103
+create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="not-hard-path";
+
+--error 1,1
+eval create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="$MYSQL_TEST_DIR/var/run";
+
+--error 1,1
+eval create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="$MYSQL_TEST_DIR/var/tmp";
+enable_query_log;
+
+# Check moving table t9 from default database to test_mysqltest;
+# In this case the symlinks should be removed.
+
+alter table t9 rename test_mysqltest.t9;
+select count(*) from test_mysqltest.t9;
+show create table test_mysqltest.t9;
+drop database test_mysqltest;
diff --git a/mysql-test/t/tablelock.test b/mysql-test/t/tablelock.test
index c32a3f7cd35..fa8c4f03675 100644
--- a/mysql-test/t/tablelock.test
+++ b/mysql-test/t/tablelock.test
@@ -2,6 +2,7 @@
# Test of lock tables
#
+drop table if exists t1,t2;
create table t1 ( n int auto_increment primary key);
lock tables t1 write;
insert into t1 values(NULL);
@@ -36,12 +37,10 @@ drop table t1;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
lock tables t1 write,t1 as b write, t2 write, t2 as c read;
-drop table t1;
-drop table t2;
+drop table t1,t2;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
lock tables t1 write,t1 as b write, t2 write, t2 as c read;
-drop table t2;
-drop table t1;
+drop table t2,t1;
unlock tables;
diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test
index e995517cf1e..1729ddc586a 100644
--- a/mysql-test/t/truncate.test
+++ b/mysql-test/t/truncate.test
@@ -2,10 +2,19 @@
# Test of truncate
#
create table t1 (a integer, b integer,c1 CHAR(10));
+insert into t1 (a) values (1),(2);
truncate table t1;
select count(*) from t1;
insert into t1 values(1,2,"test");
select count(*) from t1;
+delete from t1;
+select * from t1;
drop table t1;
# The following should fail
-!$1146 select count(*) from t1;
+--error 1146
+select count(*) from t1;
+create temporary table t1 (n int);
+insert into t1 values (1),(2),(3);
+truncate table t1;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index 626dedad547..a516bc89f99 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -32,6 +32,15 @@ select * from t1 where a is null;
drop table t1;
#
+# Test with bug when propagating DATETIME to integer and WHERE optimization
+#
+
+create table t1 (id int, dt datetime);
+insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00");
+select * from t1 where dt='2001-08-14 00:00:00' and dt = if(id=1,'2001-08-14 00:00:00','1999-08-15');
+drop table t1;
+
+#
# Test of datetime optimization
#
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 7d4dcf3403e..683ed7239e6 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -160,6 +160,8 @@ insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
select * from t1;
drop table t1;
@@ -169,6 +171,8 @@ insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
select * from t1;
drop table t1;
@@ -178,16 +182,21 @@ insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
select * from t1;
drop table t1;
create table t1 (a decimal(10,2));
+# The -0.0 needs to be quoted as not all platforms supports this
insert into t1 values (0.0),("-0.0"),(+0.0),(01.0),(+01.0),(-01.0);
insert into t1 values (-.1),(+.1),(.1);
insert into t1 values (00000000000001),(+0000000000001),(-0000000000001);
insert into t1 values (+111111111.11),(111111111.11),(-11111111.11);
insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11);
+insert into t1 values (1e+1000),(1e-1000),(-1e+1000);
+insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0);
select * from t1;
drop table t1;
diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test
index 6e90ae437f8..8f399e4364e 100644
--- a/mysql-test/t/type_enum.test
+++ b/mysql-test/t/type_enum.test
@@ -2,6 +2,7 @@
# Problem with many enums
#
+DROP TABLE if exists t1;
CREATE TABLE t1 (
field enum('001001','001004','001010','001018','001019','001020','001021','001027','001028','001029','001030','001031','001100','002003','002004','002005','002007','002008','002009','002012','002013','002014','003002','003003','003004','003005','003006','003007','003008','003009','003010','003011','003012','003013','003014','003015','003016','003017','003018','003019','004002','004003','004005','004006','004007','004008','004010','004012','004014','004016','004017','004020','004021','004022','004023','004024','004025','004026','006002','006004','006006','006010','006011','006012','006013','006014','007001','007002','007003','007004','007005','007006','007007','007008','007009','007010','007011','007012','007013','007014','007015','007016','007017','007018','007019','007020','007021','007022','007023','007024','007025','007026','007027','007028','007029','007030','007031','007032','007033','007034','007035','007036','007037','007038','007039','007040','007043','007044','009001','009002','009004','009005','009006','009007','009008','009009','009010','009011','009012','009013','010002','010003','010004','010005','010006','010007','010008','010009','010010','010011','010012','010013','010015','010016','010017','010018','010019','010020','010021','010022','010023','010024','010025','010026','010027','010028','011001','011002','011003','011004','011006','011012','011013','011014','011015','011016','012017','012018','012019','012023','012027','012028','012029','012030','012031','012032','012033','012034','012035','012036','012037','012038','012039','014001','016002','016003','016004','016007','016010','016011','016016','016019','016020','016021','016022','016023','016024','016026','016027','016028','016029','016030','016031','016032','016033','016034','017002','018001','019002','019004','020001','020003','020004','020005','020006','020007','020008','020009','022001','022002','022003','023001','023002','023003','023004','023005','023006','023007','023008','023010','023011','023012','023017','023019','023020','023021','023025','023026','023027','023028','023029','023030','023031','023032','023033','023034','023035','025001','025003','025004','025005','025006','025007','025008','025009','025010','025011','025012','025013','025014','025015','025016','025017','025018','025019','025020','025021','025022','025023','025024','025025','025026','025027','025028','025029','025030','025031','025032','025033','025034','025035','025036','025037','025038','025039','025040','025041','025042','025043','025044','025045','025046','025047','025048','025049','025050','025051','025052','025053','025054','025055','025056','025057','025058','025059','025060','025061','025062','025063','027001','027002','027011','035008','035012','036001','037001','037003','037004','037005','037006','037007','037008','037009','038004','038005','038006','038007','038009','039001','039002','039003','039004','039005','039006','046001','046002','046003','046004','046005','046007','046008','046009','046010','046011','046012','046013','046014','047001','047002','048001','051001','051002','051003','051004','052001','052002','052005','053015','053016','053019','053020','053023','053024','053026','053028','053029','053033','053034','053036','053037','053038','053039','053041','053042','053043','053045','053046','053047','053048','053051','053052','053054','053055','053056','053057','053068','053069','053070','053073','053074','053075','053086','053094','053095','053096','053097','053098','053099','053100','053101','053102','053103','053104','053105','053107','053122','053123','053124','053125','053127','053128','054001','054002','054003','054004','054005','054006','054007','054009','054010','056001','056002','056003','056004','056005','056006','056009','056010','056011','056016','056017','056018','056019','056020','056021','056022','057001','057002','057003','057004','058002','058003','058004','058005','060001','060003','060004','060005','060006','060007','061002','061003','061004','061005','061006','069006','069007','069010','069011','069012','069013','069014','069015','069016','069017','069018','069020','069021','069022','069023','069024','071002','071003','071004','071005','071006','071008','071011','071013','071020','071021','071022','072001','073001','073002','073003','073004','074001','074002','074003','074004','074005','074006','074007','074008','074009','074010','074011','074012','075001','075007','076101','076102','076103','077001','077002','077003','077004','077006','077007','077008','077009','078005','079002','079003','079004','079005','079006','079007','081001','082006','082007','082011','082013','082014','082015','082016','082017','082021','082022','082023','082024','082025','082026','082027','082028','082029','082030','082031','082032','082033','082034','082035','082036','082037','082038','082039','082040','082041','082042','082043','082044','084001','084002','084003','084004','084005','084007','084008','084009','084011','084013','084014','084016','084017','084027','084031','084032','084033','084035','084036','084037','084038','084039','084040','084041','084042','084043','084044','084045','084046','084047','084048','084049','084050','084051','085001','085002','085003','085004','085005','085006','085007','085009','085011','085012','085013','085014','085015','085016','085017','085018','085019','085020','085021','085022','085023','085028','085029','085030','085031','085033','085034','085035','085036','085037','085038','085040','085041','085042','085043','085044','085045','085046','085047','085048','085063','085064','085065','085068','085070','085071','085073','085082','085083','085086','085088','085089','085090','085091','085092','085093','085094','085095','085096','085097','085098','085099','085100','085101','085102','085103','085104','085105','085106','085107','085108','085109','085110','085111','085112','085113','085115','085119','085120','085121','085122','085123','085124','085125','085126','085127','085128','085129','085130','085132','085133','085134','085135','085136','085137','086001','086002','086003','086004','086005','088001','088003','088005','088006','088007','088008','088009','089001','090001','090002','090003','090004','090005','090006','090007','090008','090009','090010','090013','090015','090016','090017','090018','090019','090022','090027','090028','091001','091002','091005','091008','091009','091010','091011','091012','091013','091014','091015','091016','091017','091018','093001','093003','093098','093100','093102','093104','093141','093142','093146','093151','093153','093167','093168','093176','094001','094002','094004','094005','095004','099001','099002','100001','101001','102002','102003','105001','105002','106001','113001','113002','113003','113004','113005','113006','113007','113008','113009','113010','113011','113012','113013','113014','113015','113016','113017','113018','113019','113020','113021','113022','113023','113024','113025','113026','113027','113028','114001','115001','115002','115003','115004','115005','115006','115007','115008','115009','115010','115011','115012','115013','115014','115015','115016','115017','115018','115020','115021','115022','115023','115025','115026','115027','115028','115029','115030','115031','115032','115033','115034','115035','115036','115039','115040','115041','115042','115043','115044','115045','115046','115047','115048','115049','115050','115051','115052','115053','115054','115055','115056','115057','115059','115060','115061','115062','115063','115064','115065','115066','115067','115068','115069','115070','115071','115072','115073','115075','115076','115081','115082','115085','115086','115087','115088','115095','115096','115097','115098','115099','115101','115102','115103','115104','115105','115106','115108','115109','115110','115111','115112','115113','115114','115115','115116','115117','115118','115119','115120','115121','115122','116001','116002','116003','116004','116005','116006','116007','116008','116009','116010','116011','116012','117001','117002','117003','123001','124010','124014','124015','124019','124024','124025','124026','124027','124028','124029','124030','124031','124032','124033','124035','124036','124037','124038','124039','124040','124041','124042','124043','124044','124045','124046','124047','124048','124049','124050','124051','124052','124053','124054','124055','124056','124057','124058','124059','124060','124061','124062','124063','124064','124065','126001','126002','126003','126004','126005','126006','126007','126008','126009','126010','126011','126012','130001','132001','132002','132003','133001','133008','133009','133010','133011','133012','133013','133014','133015','133016','133017','133018','133019','133020','133021','133022','133023','133024','133025','133027','133028','133029','133030','133031','134001','135001','135002','135003','135004','135005','135006','135007','135008','135009','135010','136001','137009','137010','137011','137012','137013','137014','137015','137016','137017','137018','137019','138001','138002','138003','138004','139001','139003','140001','141001','141002','141003','141006','141007','141008','141009','141011','141012','141014','141015','141016','141017','141018','141019','141020','141021','141022','141023','141024','141025','141026','141027','141028','142001','142002','142003','142004','142005','142006','142007','142008','142010','142011','142012','144001','145001','145002','145003','145004','145005','145006','145007','145008','145009','145010','145011','145012','145013','145014','145015','145016','147001','150003','150005','150009','150013','150014','150015','150016','150017','150020','150021','152001','152002','152003','152004','152005','152006','152007','154001','154002','154003','155001','155002','155003','155004','155005','155006','159001','159002','159003','159004','160001','160002','160003','161001','162001','162002','162003','162004','162007','162010','162011','162012','163001','163002','163003','163005','163010','163011','163014','163015','163016','165001','165002','165003','165004','165005','165006','165007','165008','165009','165010','165011','165012','165013','165014','165015','165016','165017','165018','165019','165020','165021','165022','165023','165024','165025','165026','165027','165028','165029','165030','165031','165032','165033','165034','165035','165036','167001','168001','168002','168003','168004','168005','168007','168008','168009','168010','168011','168012','168013','168014','169001','169002','169003','169007','169008','169009','169010','170001','171001','171002','171003','171004','171005','171006','171007','171008','171009','172001','174001','174002','174003','176001','176002','176003','177001','177002','179001','179002','179003','179004','179005','179006','179007','179008','179009','179010','179011','179012','179013','179014','179015','179016','179017','179018','179019','179020','179021','179022','179023','179024','179025','179026','179027','179028','179029','179030','179031','179032','179033','179034','179035','179036','179037','179038','179039','179040','179041','179042','179043','179044','179045','179046','179047','180001','180010','180012','180013','180014','180015','180016','180017','180018','180019','180020','180021','180022','180023','180024','180025','180026','180027','180028','180030','180031','180032','180033','180034','180035','180036','180037','180038','180039','180041','180042','180043','180044','180045','180046','180047','180048','180049','180050','180051','180052','180053','180054','180055','180056','180057','180058','180059','180060','180061','180062','180063','180064','180065','180066','180067','180068','180069','180070','180071','182001','184001','184002','184005','184006','184007','184008','184009','184010','184011','185001','185003','187001','188001','188002','188003','188004','188005','188006','188007','188008','188009','188010','188011','191001','191002','192002','194001','194002','194003','194004','194005','194006','194007','195001','195002','195003','195004','195005','195006','195007','196001','196002','197001','197002','197003','197004','197005','197006','198001','198003','198004','198005','198006','198007','198008','198009','198010','198011','198012','198013','198014','198015','198016','198017','201001','201002','201005','202001','203001','203002','203003','203017','203018','203019','204001','204002','204003','205001','208001','208002','208003','208004','208005','209001','209002','209003','210001','210002','210003','210004','210005','210006','210007','210008','210009','210010','210011','210012','210013','211017','212001','212002','212003','212004','212005','212006','212007','212008','212009','212010','212011','212012','212013','218001','218003','218004','218006','218007','218008','218009','218011','218015','218016','218017','218018','218019','218020','218021','218022','218023','218024','218025','218026','218027','218028','218029','218030','218031','218032','218033','218034','218035','218036','221001','221002','221003','221004','221005','221006','221007','221008','221009','221010','221011','221012','221013','223001','223002','223003','224001','224002','224003','224006','224007','224008','225001','225002','225003','225004','225005','225006','225007','225008','225009','225010','225011','225012','225013','226001','226002','226003','226004','226005','226006','226007','226008','226009','227001','227002','227003','227004','227005','227006','227007','227008','227009','227010','227011','227012','227013','227014','227015','227016','227017','227018','227019','227020','227021','227022','227023','227024','227025','227026','227027','227028','227029','227030','227031','227032','227033','227034','227035','227036','227037','227038','227039','227040','227041','227042','227043','227044','227045','227046','227047','227048','227049','227050','227051','227052','227053','227054','227055','227056','227057','227058','227059','227060','227061','227062','227063','227064','227065','227066','227067','227068','227069','227070','227071','227072','227073','227074','227075','227076','227077','227078','227079','227080','227081','227082','227083','227084','227085','227086','227087','227088','227089','227090','227091','227092','227093','227094','227095','227096','227097','227098','227099','227100','227101','227102','227103','227104','227105','227106','227107','227108','227109','227110','227111','227112','227113','227114','227115','227116','227117','227118','227119','227120','227122','227123','227124','227125','227126','227127','227128','227129','227130','227131','227132','227133','227134','227135','227136','227137','227138','227139','227140','227141','227142','227143','227144','227145','227146','227147','227148','227149','227150','227151','227152','228001','229001','229002','229003','229004','229005','230001','230002','232001','233001','233002','233003','233004','233005','233006','233007','233008','234001','234002','234003','234004','234005','234006','234007','234008','234009','234010','234011','234012','234013','234014','234015','234016','234017','234018','234019','234020','234021','234022','234023','234024','234025','234026','234027','234028','234029','234030','235001','235002','235003','235004','235005','236001','236002','236003','237001','238002','238003','238004','238005','238006','238007','238008','333013','333014','333015','333016','333017','333018','333019','333020','333021','333022','333023','333024','333025','333030','333031','333032','333033','333034','333035','334001','334002','334003','334004','334005','334006','334007','336004','337001','337002','337003','337004','339001','339002','343001','344001','344002','344003','344004','344005','345001','345002','345003','347001','347002','348001','348002','348003','348004','348005','349001','349002','349003','350001','353001','353002','353003','353004','355001','355002','355003','355004','355005','355006','356001','358001','359001','359002','360001','360002','360003','360004','360005','366001','366002','366003','366004','369001','373001','373002','373003','373004','373005','373006','373007','373008','373009','373010','373011','373012','373013','373014','373015','373016','373017','373018','373019','373020','373021','374001','374002','374003','374004','374005','374006','374007','374008','374009','374010','374011','374012','374013','374014','374015','374016','376001','376002','376003','376004','376005','376006','376007','376008','376009','376010','376011','376012','376013','376016','376017','376018','376019','376020','376021','379003','382001','382002','383001','384001','384002','385001','385002','386001','386002','386003','386004','386005','386006','386007','386008','386009','386010','386011','386012','386013','386014','387001','389001','389002','389003','389004','392001','393001','393002','393003','393004','395001','396001','397001','397002','399001','399002','399003','400001','400002','401001','401002','401003','402001','402002','402003','402004','402005','403001','403002','403003','504001','504002','504004','504005','504006','504007','504008','504009','504010','504011','504012','504013','504014','504017','504018','504019','504021','504022','504023','504024','504025','506001','506002','508001','508002','511001','511002','511003','511004','511005','511006','511007','511008','511009','511010','511011','511012','511013','511014','511017','511018','511020','511021','511022','511024','511028','511029','513001','513002','513003','513004','514001','515001','515002','515003','515007','515008','515009','515010','515011','515012','515013','515014','515015','518001','518002','518003','520001','520002','521001','521002','521003','521004','521005','521006','521007','521008','521009','521010','521011','521012','521013','521014','521015','521016','523001','523002','523003','523004','523005','523006','523007','524001','700001','701001','701002','701003','702001','702002','702003','702004','702005','702006','702007','702008','703001','703002','703003','704001','704002','704003','704004','705001','706001','706002','707001','707002','707003','708001','709001','709002','710001','710002','711001','711002','712001','713001','713002','714001','714002','715001','716001','718001','718002','719001','719002','991001','991002','991003','991004','991005','991006','991007','991008','992001','995001','996001','996002','996003','998001','998002','998003','998004','998005','998006','998007','999001','999002','011017','011018','034001','034002','071010','208006','239001','519001','519003','126013','184012','053071','374017','374018','374019','374020','374021','404001','405002','405001','405003','405007','405006','405005','405004','240011','240010','240009','240008','240007','240006','240005','240004','240003','240002','240001','240012','240013','240014','240015','240016','240017','357001','235006','235007','712002','355008','355007','056023','999999','046015','019005','126014','241003','241002','241001','240018','240020','240019','242001','242002','242003','242004','242005','242006','089002','406001','406002','406003','406004','406005','406006','243001','243002','243003','243004','243005','243006','243007','243008','010030','010029','407001','407006','407005','407004','407003','407002','408001','366005','133032','016035','077010','996004','025064','011019','407007','407008','407009','409001','115123','504026','039007','039009','039008','039010','039011','039012','180072','240021','240023','408002','405008','235008','525001','525002','525003','525004','410001','410002','410003','410004','410005','410006','410007','410008','410009','410010','410011','410012','410013','410014','410015','410016','344006','240031','240030','240029','240028','240027','240026','240025','240024','240034','240033','240032','410017','410018','411001','411002','411003','411004','411005','411006','411007','411008','203020','203021','203022','412001','412002','412003','412004','069025','244001','244002','244009','244008','244007','244006','244005','244004','244003','244015','244014','244013','244012','244011','244010','244016','244017','240042','240041','240040','240039','240038','240037','240036','240035','405009','405010','240043','504034','504033','504032','504031','504030','504029','504028','504027','504042','504041','504040','504039','504038','504037','504036','504035','800001','410019','410020','410021','244018','244019','244020','399004','413001','504043','198018','198019','344007','082045','010031','010032','010033','010034','010035','504044','515016','801002','801003','801004','801005','802001','801001','414001','414002','414003','141029','141030','803001','803002','803003','803004','803005','803006','803007','803008','803009','803010','803011','803012','803013','803014','803015','803016','803017','410022','410023','803018','803019','803020','415002','415001','244021','011020','011023','011022','011021','025065','165037','165038','165039','416001','416002','416003','417001','418001','504045','803022','803021','240022','419001','420001','804010','804009','804008','804007','804006','804005','804004','804003','804002','804001','804020','804019','804018','804017','804016','804015','804014','804013','804012','804011','804024','804021','804023','804022','511019','511016','511015','511032','511031','511030','511027','511026','511025','511033','511023','133034','133033','169011','344008','344009','244022','244026','244025','244030','244023','244024','244027','244028','244029','244031','082046','082047','082048','126015','126016','416004','416005','421001','421002','016037','016036','115124','115125','115126','240049','240048','240047','240046','240045','240044','244032','244033','422001','422002','422003','422004','422005','184013','239002','805001','805002','805003','805004','805005','056024','423001','344010','235009','212014','056025','056026','802002','244034','244035','244036','244037','244038','244039','515017','504046','203015','245002','245001','071023','056027','056028','056029','056030','056031','056032','424001','056034','056033','805006','805007','805008','805009','805010','422008','422007','422006','422010','422009','422011','209004','150022','150023','100002','056035','023036','185004','185005','246001','247001','247002','425001','416006','165042','165041','165040','165043','010040','010039','010038','010037','010036','422012','422013','422014','422015','426000','248001','248002','248003','248004','248005','249001','249002','249003','249004','249005','249006','250007','250001','250002','250003','250004','250005','250006','250008','250009','250010','250011','250012','250013','251001','251002','422016','422017','422018','806001','806002','116013','235010','235011','091026','091027','091028','091029','091019','091020','091021','091022','091023','091024','091025','252001','243009','249007','249008','249009','011024','011025','427001','428002','428001','169012','429001','429002','429003') DEFAULT '001001' NOT NULL,
KEY field (field)
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
new file mode 100644
index 00000000000..6e6b43ebe3b
--- /dev/null
+++ b/mysql-test/t/union.test
@@ -0,0 +1,100 @@
+#
+# Test of unions
+#
+
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+
+select a,b from t1 union select a,b from t2;
+select a,b from t1 union all select a,b from t2;
+select a,b from t1 union all select a,b from t2 order by b;
+select a,b from t1 union all select a,b from t2 union select 7,'g';
+select 0,'#' union select a,b from t1 union all select a,b from t2 union select 7,'gg';
+select a,b from t1 union select a,b from t1;
+select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
+
+#test alternate syntax for unions
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1);
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2;
+select found_rows();
+
+#
+# Test some error conditions with UNION
+#
+
+explain select a,b from t1 union all select a,b from t2;
+
+--error 1054
+explain select xx from t1 union select 1;
+explain select a,b from t1 union select 1;
+explain select 1 union select a,b from t1 union select 1;
+explain select a,b from t1 union select 1 limit 0;
+
+--error 1221
+select a,b from t1 into outfile 'skr' union select a,b from t2;
+
+--error 1221
+select a,b from t1 order by a union select a,b from t2;
+
+--error 1221
+insert into t3 select a from t1 order by a union select a from t2;
+
+--error 1222
+create table t3 select a,b from t1 union select a from t2;
+
+--error 1222
+select a,b from t1 union select a from t2;
+
+--error 1222
+select * from t1 union select a from t2;
+
+--error 1222
+select a from t1 union select * from t2;
+
+--error 1234
+select * from t1 union select SQL_BUFFER_RESULT * from t2;
+
+# Test CREATE, INSERT and REPLACE
+create table t3 select a,b from t1 union all select a,b from t2;
+insert into t3 select a,b from t1 union all select a,b from t2;
+replace into t3 select a,b as c from t1 union all select a,b from t2;
+
+drop table t1,t2,t3;
+
+#
+# Test bug reported by joc@presence-pc.com
+#
+
+CREATE TABLE t1 (
+ `pseudo` char(35) NOT NULL default '',
+ `pseudo1` char(35) NOT NULL default '',
+ `same` tinyint(1) unsigned NOT NULL default '1',
+ PRIMARY KEY (`pseudo1`),
+ KEY `pseudo` (`pseudo`)
+) TYPE=MyISAM;
+INSERT INTO t1 (pseudo,pseudo1,same) VALUES ('joce', 'testtt', 1),('joce', 'tsestset', 1),('dekad', 'joce', 1);
+SELECT pseudo FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo FROM t1 WHERE pseudo='joce';
+SELECT pseudo1 FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo1 FROM t1 WHERE pseudo='joce';
+SELECT * FROM t1 WHERE pseudo1='joce' UNION SELECT * FROM t1 WHERE pseudo='joce' order by pseudo desc,pseudo1 desc;
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT pseudo FROM t1 WHERE pseudo1='joce';
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION ALL SELECT pseudo FROM t1 WHERE pseudo1='joce';
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT 1;
+drop table t1;
+drop table if exists t1,t2;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2),(3),(4),(5);
+insert into t2 values (11),(12),(13),(14),(15);
+(select * from t1 limit 2) union (select * from t2 limit 3) limit 4;
+(select * from t1 limit 2) union (select * from t2 limit 3);
+(select * from t1 limit 2) union (select * from t2 limit 20,3);
+set SQL_SELECT_LIMIT=2;
+(select * from t1 limit 1) union (select * from t2 limit 3);
+set SQL_SELECT_LIMIT=DEFAULT;
+drop table t1,t2;
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index 6f446a11521..5cbbd2a350e 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -76,3 +76,14 @@ alter table t1 change lfdnr lfdnr int(10) unsigned default 0 not null auto_incre
update t1 set status=1 where type='Open';
select status from t1;
drop table t1;
+
+#
+# Test of ORDER BY
+#
+
+create table t1 (a int not null, b int not null);
+insert into t1 values (1,1),(1,2),(1,3);
+update t1 set b=4 where a=1 order by b asc limit 1;
+update t1 set b=4 where a=1 order by b desc limit 1;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 70283446fb3..bb1a9b59611 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -1,4 +1,4 @@
-error 1204;
+error 1054;
set @a := foo;
set @a := connection_id() + 3;
select @a - connection_id();
diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test
index 0ab26f51e65..6d2660271ea 100644
--- a/mysql-test/t/varbinary.test
+++ b/mysql-test/t/varbinary.test
@@ -4,6 +4,7 @@
select 0x41,0x41+0,0x41 | 0x7fffffffffffffff | 0,0xffffffffffffffff | 0 ;
select 0x31+1,concat(0x31)+1,-0xf;
+select x'31',X'ffff'+0;
#
# Test of hex constants in WHERE:
@@ -14,3 +15,18 @@ insert into t1 set UNIQ=0x38afba1d73e6a18a;
insert into t1 set UNIQ=123;
explain select * from t1 where UNIQ=0x38afba1d73e6a18a;
drop table t1;
+
+#
+# Test error conditions
+#
+--error 1064
+select x'hello';
+--error 1054
+select 0xfg;
+
+#
+# Test likely error conditions
+#
+create table t1 select 1 as x, 2 as xx;
+select x,xx from t1;
+drop table t1;
diff --git a/mysql-test/t/variables-master.opt b/mysql-test/t/variables-master.opt
new file mode 100644
index 00000000000..5851d32ec31
--- /dev/null
+++ b/mysql-test/t/variables-master.opt
@@ -0,0 +1 @@
+max_join_size=10
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index b3127402238..967c21f7eab 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -32,9 +32,200 @@ drop table t1;
# Test system variables
#
+set max_join_size=100;
+show variables like 'max_join_size';
+show global variables like 'max_join_size';
+set GLOBAL max_join_size=2000;
+show global variables like 'max_join_size';
+set max_join_size=DEFAULT;
+show variables like 'max_join_size';
+set GLOBAL max_join_size=DEFAULT;
+show global variables like 'max_join_size';
+set @@max_join_size=1000, @@global.max_join_size=2000;
+select @@local.max_join_size, @@global.max_join_size;
+select @@identity, length(@@version)>0;
select @@VERSION=version();
select last_insert_id(345);
-select @@IDENTITY,last_insert_id();
-select @@identity;
+select @@IDENTITY,last_insert_id(), @@identity;
+
+set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
+
+set global concurrent_insert=ON;
+show variables like 'concurrent_insert';
+set global concurrent_insert=1;
+show variables like 'concurrent_insert';
+set global concurrent_insert=0;
+show variables like 'concurrent_insert';
+set global concurrent_insert=OFF;
+show variables like 'concurrent_insert';
+set global concurrent_insert=DEFAULT;
+show variables like 'concurrent_insert';
+
+set table_type=MYISAM, table_type="HEAP", global table_type="INNODB";
+show local variables like 'table_type';
+show global variables like 'table_type';
+set GLOBAL query_cache_size=100000;
+set GLOBAL safe_show_database=0;
+
+set myisam_max_sort_file_size=10000, GLOBAL myisam_max_sort_file_size=20000;
+show variables like 'myisam_max_sort_file_size';
+show global variables like 'myisam_max_sort_file_size';
+set myisam_max_sort_file_size=default;
+show variables like 'myisam_max_sort_file_size';
+
+set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
+set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
+show global variables like 'net_%';
+show session variables like 'net_%';
+set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
+show global variables like 'net_%';
+show session variables like 'net_%';
+set net_buffer_length=1;
+show variables like 'net_buffer_length';
+set net_buffer_length=2000000000;
+show variables like 'net_buffer_length';
+
+set GLOBAL character set cp1251_koi8;
+show global variables like "convert_character_set";
+set character set cp1251_koi8;
+show variables like "convert_character_set";
+set global character set default, session character set default;
+show variables like "convert_character_set";
+select @@timestamp>0;
+
+# The following should give errors
+
+--error 1231
+set big_tables=OFFF;
+--error 1231
+set big_tables="OFFF";
--error 1193
-select @@unknown_variable;
+set unknown_variable=1;
+--error 1232
+set max_join_size="hello";
+--error 1231
+set table_type=UNKNOWN_TABLE_TYPE;
+--error 1231
+set table_type=INNODB, big_tables=2;
+show local variables like 'table_type';
+--error 1229
+set SESSION query_cache_size=10000;
+--error 1230
+set GLOBAL table_type=DEFAULT;
+--error 1115
+set convert_character_set=UNKNOWN_CHARACTER_SET;
+--error 1115
+set character set unknown;
+--error 1232
+set character set 0;
+--error 1228
+set global autocommit=1;
+--error 1228
+select @@global.timestamp;
+--error 1193
+set @@version='';
+--error 1229
+set @@concurrent_insert=1;
+--error 1228
+set @@global.sql_auto_is_null=1;
+--error 1228
+select @@global.sql_auto_is_null;
+
+# Test setting all variables
+
+set autocommit=1;
+set big_tables=1;
+select @@autocommit, @@big_tables;
+set global binlog_cache_size=100;
+set bulk_insert_buffer_size=100;
+set convert_character_set=cp1251_koi8;
+set convert_character_set=default;
+set @@global.concurrent_insert=1;
+set global connect_timeout=100;
+set global delay_key_write=1;
+set global delayed_insert_limit=100;
+set global delayed_insert_timeout=100;
+set global delayed_queue_size=100;
+set global flush=1;
+set global flush_time=100;
+set insert_id=1;
+set interactive_timeout=100;
+set join_buffer_size=100;
+set last_insert_id=1;
+set global local_infile=1;
+set long_query_time=100;
+set low_priority_updates=1;
+set max_allowed_packet=100;
+set global max_binlog_cache_size=100;
+set global max_binlog_size=100;
+set global max_connect_errors=100;
+set global max_connections=100;
+set global max_delayed_threads=100;
+set max_heap_table_size=100;
+set max_join_size=100;
+set max_sort_length=100;
+set max_tmp_tables=100;
+set global max_user_connections=100;
+select @@max_user_connections;
+set global max_write_lock_count=100;
+set myisam_max_extra_sort_file_size=100;
+select @@myisam_max_extra_sort_file_size;
+set myisam_max_sort_file_size=100;
+set myisam_sort_buffer_size=100;
+set net_buffer_length=100;
+set net_read_timeout=100;
+set net_write_timeout=100;
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+set read_buffer_size=100;
+set read_rnd_buffer_size=100;
+set global rpl_recovery_rank=100;
+set global safe_show_database=1;
+set global server_id=100;
+set global slave_net_timeout=100;
+set global slow_launch_time=100;
+set sort_buffer_size=100;
+set sql_auto_is_null=1;
+select @@sql_auto_is_null;
+set @@sql_auto_is_null=0;
+select @@sql_auto_is_null;
+set sql_big_selects=1;
+set sql_big_tables=1;
+set sql_buffer_result=1;
+set sql_log_bin=1;
+set sql_log_off=1;
+set sql_log_update=1;
+set sql_low_priority_updates=1;
+set sql_max_join_size=200;
+select @@sql_max_join_size,@@max_join_size;
+set sql_quote_show_create=1;
+set sql_safe_updates=1;
+set sql_select_limit=1;
+set global sql_slave_skip_counter=100;
+set sql_warnings=1;
+set global table_cache=100;
+set table_type=myisam;
+set global thread_cache_size=100;
+set timestamp=1, timestamp=default;
+set tmp_table_size=100;
+set tx_isolation="READ-COMMITTED";
+set wait_timeout=100;
+set log_warnings=1;
+
+#
+# key buffer
+#
+
+DROP TABLE IF EXISTS t1,t2;
+create table t1 (a int not null auto_increment, primary key(a));
+create table t2 (a int not null auto_increment, primary key(a));
+insert into t1 values(null),(null),(null);
+insert into t2 values(null),(null),(null);
+set global key_buffer_size=100000;
+select @@key_buffer_size;
+select * from t1 where a=2;
+select * from t2 where a=3;
+check table t1,t2;
+drop table t1,t2;
+
diff --git a/mysql-test/xml/README b/mysql-test/xml/README
deleted file mode 100644
index ee1af30db33..00000000000
--- a/mysql-test/xml/README
+++ /dev/null
@@ -1,74 +0,0 @@
-This directory contains all of the test cases for the MySQL Test Suite
-marked up in XML.
-
-To convert these test cases from XML into 'mysqltest' format, one needs
-an XSL translator installed on their system. At MySQL, we use Sablotron
-(http://www.gingerall.com/). Once installed, conversion happens with a
-command like this:
-
- sabcmd xsl/mysqltest.xsl < tests/sel000001.xml > sel000001.test
-
-The file 'sel000001.test' contains the plain text conversion that is
-to be fed into the 'mysqltest' program.
-
-Below is an example of a test case marked up in XML; illustrating all
-of the XML mark-up currently supported in our 'mysqltest.xsl' stylesheet.
-
-----------------------------------------------------
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000001">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test will monkey around trying to kill mysqld.</description>
-
- <connect name="Test_Connect1"
- host="MyHostName"
- user="Matt"
- pass="MattPass"
- db="MyDB"
- port="3306"
- sock="MyDB.sock"
- />
-
- <connection name="Test_Connect1">
- <resultfile name="sel000001.result">
- <sql>SELECT y FROM foo WHERE bar='2'</sql>
- </resultfile>
- <sql>INSERT INTO foo VALUES (y='2') WHERE bar='1'</sql>
- </connection>
-
-</test>
-----------------------------------------------------
-
-
-The converted (mysqltest format) output of this source XML file looks
-like:
-
-
-----------------------------------------------------
-# sel000001
-#
-# Versions
-# --------
-# 3.22
-# 3.23
-#
-# Description
-# -----------
-# This test will monkey around trying to kill mysqld.
-#
-
-
-connect(Test_Connect1, MyHostName, Matt, MattPass, MyDB, 3306, MyDB.sock)
-
-connection Test_Connect1
-INSERT INTO foo VALUES (y='2') WHERE bar='1';
-@sel000001.result SELECT y FROM foo WHERE bar='2';
-----------------------------------------------------
-
-
diff --git a/mysql-test/xml/tests/sel000001.xml b/mysql-test/xml/tests/sel000001.xml
deleted file mode 100644
index 7ce4dae8ee1..00000000000
--- a/mysql-test/xml/tests/sel000001.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000001">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test is just a simple select.</description>
- <description>Testing WHERE clause.</description>
-
- <sql>DROP TABLE IF EXISTS t</sql>
- <sql>CREATE TABLE t (s CHAR(20) PRIMARY KEY, id INT)</sql>
- <sql>INSERT INTO t VALUES ('cat', 1), ('mouse', 3), ('dog', 2), ('snake', 77)</sql>
-
- <resultfile name="r/3.23/sel000001.result">
- <sql>SELECT s, id FROM t WHERE s = 'mouse'</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000002.xml b/mysql-test/xml/tests/sel000002.xml
deleted file mode 100644
index 902233cbbf0..00000000000
--- a/mysql-test/xml/tests/sel000002.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000002">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test is just a simple select.</description>
-
- <sql>DROP TABLE IF EXISTS t</sql>
- <sql>CREATE TABLE t (n INT)</sql>
- <sql>INSERT INTO t VALUES (1), (2), (3)</sql>
-
- <resultfile name="r/3.23/sel000002.result">
- <sql>SELECT * FROM t</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000003.xml b/mysql-test/xml/tests/sel000003.xml
deleted file mode 100644
index c9334c972d8..00000000000
--- a/mysql-test/xml/tests/sel000003.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000003">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test is just a simple select.</description>
- <description>Testing count() function and GROUP BY clause.</description>
-
- <sql>DROP TABLE IF EXISTS t</sql>
- <sql>CREATE TABLE t (name CHAR(20) NOT NULL PRIMARY KEY, score SMALLINT NOT NULL, KEY(score))</sql>
- <sql>INSERT INTO t VALUES ('Sasha', 20), ('Matt', 20), ('Monty', 10), ('David', 10), ('Tim', 10), ('Jeremy', 10)</sql>
-
- <resultfile name="r/3.23/sel000003.result">
- <sql>SELECT COUNT(*) as n, score FROM t GROUP BY score</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000004.xml b/mysql-test/xml/tests/sel000004.xml
deleted file mode 100644
index 9c28c632c32..00000000000
--- a/mysql-test/xml/tests/sel000004.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000004">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Simple arithmetic.</description>
- <description>Testing MOD(), SIGN(), and arithmetic grouping.</description>
-
- <resultfile name="r/3.23/sel000004.result">
- <sql>SELECT 1+1,1-1,1+1*2,8/5,8%5,MOD(8,5),MOD(8,5)|0,-(1+1)*-2,SIGN(-5)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000005.xml b/mysql-test/xml/tests/sel000005.xml
deleted file mode 100644
index 0bcddb2fbb6..00000000000
--- a/mysql-test/xml/tests/sel000005.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000005">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing FLOOR(), CEILING(), ROUND().</description>
-
- <resultfile name="r/3.23/sel000005.result">
- <sql>SELECT FLOOR(5.5),FLOOR(-5.5),CEILING(5.5),CEILING(-5.5),ROUND(5.5),ROUND(-5.5)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000006.xml b/mysql-test/xml/tests/sel000006.xml
deleted file mode 100644
index 3059f8bb7df..00000000000
--- a/mysql-test/xml/tests/sel000006.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000006">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing ROUND(); hundreths precision.</description>
-
- <resultfile name="r/3.23/sel000006.result">
- <sql>SELECT ROUND(5.64,1),ROUND(5.64,2),ROUND(5.64,-1),ROUND(5.64,-2)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000007.xml b/mysql-test/xml/tests/sel000007.xml
deleted file mode 100644
index 8f8bb7162c3..00000000000
--- a/mysql-test/xml/tests/sel000007.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000007">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing TRUNCATE().</description>
-
- <resultfile name="r/3.23/sel000007.result">
- <sql>SELECT TRUNCATE(52.64,1),TRUNCATE(52.64,2),TRUNCATE(52.64,-1),TRUNCATE(52.64,-2)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000008.xml b/mysql-test/xml/tests/sel000008.xml
deleted file mode 100644
index 70a54a15d5b..00000000000
--- a/mysql-test/xml/tests/sel000008.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000008">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing ABS(), LOG(), LOG10(), EXP(), SQRT(), POW(), RAND(), POWER().</description>
-
- <resultfile name="r/3.23/sel000008.result">
- <sql>SELECT ABS(-10),LOG(EXP(10)),EXP(LOG(SQRT(10))*2),POW(10,LOG10(10)),RAND(999999),RAND(),POWER(2,4)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000009.xml b/mysql-test/xml/tests/sel000009.xml
deleted file mode 100644
index 0c79f032112..00000000000
--- a/mysql-test/xml/tests/sel000009.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000009">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing PI(), SIN(), COS(), TAN(), COT(), ASIN(), ACOS(), ATAN().</description>
-
- <resultfile name="r/3.23/sel000009.result">
- <sql>SELECT PI(),SIN(PI()/2),COS(PI()/2),TAN(PI()),COT(1),ASIN(1),ACOS(0),ATAN(1)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000010.xml b/mysql-test/xml/tests/sel000010.xml
deleted file mode 100644
index 6954fef0750..00000000000
--- a/mysql-test/xml/tests/sel000010.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000010">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric bitwise comparisons.</description>
- <description>Testing |, &amp;, BIT_COUNT().</description>
-
- <resultfile name="r/3.23/sel000010.result">
- <sql>SELECT 1 | (1+1),5 &amp; 3,BIT_COUNT(7)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000011.xml b/mysql-test/xml/tests/sel000011.xml
deleted file mode 100644
index 5c981b2f85a..00000000000
--- a/mysql-test/xml/tests/sel000011.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000011">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric bitmoving comparisons.</description>
- <description>Testing &lt;&lt;, >>.</description>
-
- <resultfile name="r/3.23/sel000011.result">
- <sql>SELECT 1 &lt;&lt; 32,1 &lt;&lt; 63, 1 &lt;&lt; 64, 4 >> 2, 4 >> 63, 1&lt;&lt; 63 >> 60</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000012.xml b/mysql-test/xml/tests/sel000012.xml
deleted file mode 100644
index 7abcc498164..00000000000
--- a/mysql-test/xml/tests/sel000012.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000012">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric floating point.</description>
-
- <resultfile name="r/3.23/sel000012.result">
- <sql>SELECT 10,10.0,10.,.1e+2,100.0e-1</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000013.xml b/mysql-test/xml/tests/sel000013.xml
deleted file mode 100644
index fbeca6663fc..00000000000
--- a/mysql-test/xml/tests/sel000013.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000013">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric floating point.</description>
-
- <resultfile name="r/3.23/sel000013.result">
- <sql>SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000014.xml b/mysql-test/xml/tests/sel000014.xml
deleted file mode 100644
index 96a51e671fc..00000000000
--- a/mysql-test/xml/tests/sel000014.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000014">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing pos/neg and zero padding.</description>
-
- <resultfile name="r/3.23/sel000014.result">
- <sql>SELECT 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000015.xml b/mysql-test/xml/tests/sel000015.xml
deleted file mode 100644
index a339330e6b1..00000000000
--- a/mysql-test/xml/tests/sel000015.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000015">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big numbers.</description>
-
- <resultfile name="r/3.23/sel000015.result">
- <sql>SELECT 922337203685477580,92233720368547758000</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000016.xml b/mysql-test/xml/tests/sel000016.xml
deleted file mode 100644
index ae971e6576a..00000000000
--- a/mysql-test/xml/tests/sel000016.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000016">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big negative numbers.</description>
-
- <resultfile name="r/3.23/sel000016.result">
- <sql>SELECT -922337203685477580,-92233720368547758000</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000017.xml b/mysql-test/xml/tests/sel000017.xml
deleted file mode 100644
index 9d06d640ac3..00000000000
--- a/mysql-test/xml/tests/sel000017.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000017">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big pos/neg numbers.</description>
-
- <resultfile name="r/3.23/sel000017.result">
- <sql>SELECT 9223372036854775807,-009223372036854775808</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000018.xml b/mysql-test/xml/tests/sel000018.xml
deleted file mode 100644
index 909728599fa..00000000000
--- a/mysql-test/xml/tests/sel000018.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000018">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big pos/neg numbers.</description>
-
- <resultfile name="r/3.23/sel000018.result">
- <sql>SELECT +9999999999999999999,-9999999999999999999</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000019.xml b/mysql-test/xml/tests/sel000019.xml
deleted file mode 100644
index e0286ae2db7..00000000000
--- a/mysql-test/xml/tests/sel000019.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000019">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing DEGREES(), RADIANS().</description>
-
- <resultfile name="r/3.23/sel000019.result">
- <sql>SELECT DEGREES(PI()),RADIANS(360)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000020.xml b/mysql-test/xml/tests/sel000020.xml
deleted file mode 100644
index 41ad5981cb9..00000000000
--- a/mysql-test/xml/tests/sel000020.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000020">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; STRCMP(), =, >, >=, &lt;=, !=.</description>
-
- <resultfile name="r/3.23/sel000020.result">
- <sql>SELECT 0=0,1>0,1>=1,1&lt;0,1&lt;=0,1!=0,STRCMP("abc","abcd"),STRCMP("b","a"),STRCMP("a","a")</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000021.xml b/mysql-test/xml/tests/sel000021.xml
deleted file mode 100644
index ba2e8149abd..00000000000
--- a/mysql-test/xml/tests/sel000021.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000021">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; =, >, >=, &lt;=, &lt;>.</description>
-
- <resultfile name="r/3.23/sel000021.result">
- <sql>SELECT "a"&lt;"b","a"&lt;="b","b">="a","b">"a","a"="A","a"&lt;>"b"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000022.xml b/mysql-test/xml/tests/sel000022.xml
deleted file mode 100644
index 3dca0eb9b7f..00000000000
--- a/mysql-test/xml/tests/sel000022.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000022">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; =, >, &lt;=.</description>
-
- <resultfile name="r/3.23/sel000022.result">
- <sql>SELECT "a "="A", "A "="a", "a " &lt;= "A b"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000023.xml b/mysql-test/xml/tests/sel000023.xml
deleted file mode 100644
index 7cceb4aabca..00000000000
--- a/mysql-test/xml/tests/sel000023.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000023">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, NOT LIKE, '%'.</description>
-
- <resultfile name="r/3.23/sel000023.result">
- <sql>SELECT "abc" LIKE "a%", "abc" NOT LIKE "%d%", "a%" LIKE "a\%","abc%" LIKE "a%\%","abcd" LIKE "a%b_%d", "a" LIKE "%%a","abcde" LIKE "a%_e","abc" LIKE "abc%"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000024.xml b/mysql-test/xml/tests/sel000024.xml
deleted file mode 100644
index 5bf9c0be7dc..00000000000
--- a/mysql-test/xml/tests/sel000024.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000024">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, '%'.</description>
-
- <resultfile name="r/3.23/sel000024.result">
- <sql>SELECT "a" LIKE "%%b","a" LIKE "%%ab","ab" LIKE "a\%", "ab" LIKE "_", "ab" LIKE "ab_", "abc" LIKE "%_d", "abc" LIKE "abc%d"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000025.xml b/mysql-test/xml/tests/sel000025.xml
deleted file mode 100644
index 4144b65775f..00000000000
--- a/mysql-test/xml/tests/sel000025.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000025">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, ESCAPE, '%'.</description>
-
- <resultfile name="r/3.23/sel000025.result">
- <sql>SELECT '?' LIKE '|%', '?' LIKE '|%' ESCAPE '|', '%' LIKE '|%', '%' LIKE '|%' ESCAPE '|', '%' LIKE '%'</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000026.xml b/mysql-test/xml/tests/sel000026.xml
deleted file mode 100644
index afaa34009fa..00000000000
--- a/mysql-test/xml/tests/sel000026.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000026">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, '%'.</description>
-
- <resultfile name="r/3.23/sel000026.result">
- <sql>SELECT 'abc' LIKE '%c','abcabc' LIKE '%c', "ab" LIKE "", "ab" LIKE "a", "ab" LIKE "ab"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000027.xml b/mysql-test/xml/tests/sel000027.xml
deleted file mode 100644
index 641d5d3a619..00000000000
--- a/mysql-test/xml/tests/sel000027.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000027">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; REGEXP.</description>
-
- <resultfile name="r/3.23/sel000027.result">
- <sql>SELECT "Det här är svenska" REGEXP "h[[:alpha:]]+r", "aba" REGEXP "^(a|b)*$"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000028.xml b/mysql-test/xml/tests/sel000028.xml
deleted file mode 100644
index c8db245c25d..00000000000
--- a/mysql-test/xml/tests/sel000028.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000028">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; REGEXP, CONCAT().</description>
-
- <resultfile name="r/3.23/sel000028.result">
- <sql>SELECT "aba" REGEXP CONCAT("^","a")</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000029.xml b/mysql-test/xml/tests/sel000029.xml
deleted file mode 100644
index 84d12a44dc5..00000000000
--- a/mysql-test/xml/tests/sel000029.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000029">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; NOT, AND, OR, !, &amp;&amp;, ||.</description>
-
- <resultfile name="r/3.23/sel000029.result">
- <sql>SELECT !0,NOT 0=1,!(0=0),1 AND 1,1 &amp;&amp; 0,0 OR 1,1 || NULL, 1=1 OR 1=1 AND 1=0</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000030.xml b/mysql-test/xml/tests/sel000030.xml
deleted file mode 100644
index 8a8a4d5e0d2..00000000000
--- a/mysql-test/xml/tests/sel000030.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000030">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Control flow.</description>
- <description>Testing control flow; IF()</description>
-
- <resultfile name="r/3.23/sel000030.result">
- <sql>SELECT IF(0,"ERROR","this"),IF(1,"is","ERROR"),IF(NULL,"ERROR","a"),IF(1,2,3)|0,IF(1,2.0,3.0)+0</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/xsl/README b/mysql-test/xml/xsl/README
deleted file mode 100644
index fe11b57cf11..00000000000
--- a/mysql-test/xml/xsl/README
+++ /dev/null
@@ -1,4 +0,0 @@
-XML Stylesheets for converting test cases in XML to other forms.
-
- - mysqltest.xsl -> mysqltest format (text)
-
diff --git a/mysql-test/xml/xsl/mysqltest.xsl b/mysql-test/xml/xsl/mysqltest.xsl
deleted file mode 100644
index 8a1e738e611..00000000000
--- a/mysql-test/xml/xsl/mysqltest.xsl
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
-<xsl:output method="text"/>
-
-<xsl:template match="/"><xsl:apply-templates /></xsl:template>
-
-<!-- Main Template -->
-
-<xsl:template match="/test"># <xsl:apply-templates select="@name"/>
-#
-# Versions
-# --------<xsl:apply-templates select="version"/>
-#
-# Description
-# -----------<xsl:apply-templates select="description"/>
-#
-
-<xsl:apply-templates select="connect"/>
-
-<xsl:apply-templates select="connection"/>
-
-<xsl:apply-templates select="sql"/>
-
-<xsl:apply-templates select="resultfile"/>
-
-</xsl:template>
-
-<!-- End Main Template -->
-
-
-<xsl:template match="version">
-# <xsl:apply-templates select="@value"/>
-</xsl:template>
-
-<xsl:template match="description">
-# <xsl:apply-templates />
-</xsl:template>
-
-<xsl:template match="connect">
-connect(<xsl:apply-templates select="@name"/>, <xsl:apply-templates select="@host"/>, <xsl:apply-templates select="@user"/>, <xsl:apply-templates select="@pass"/>, <xsl:apply-templates select="@db"/>, <xsl:apply-templates select="@port"/>, <xsl:apply-templates select="@sock"/>)
-</xsl:template>
-
-<xsl:template match="connection">
-<xsl:text>
-connection </xsl:text><xsl:apply-templates select="@name"/>
-<xsl:text>
-</xsl:text>
-<xsl:apply-templates select="sql"/>
-<xsl:apply-templates select="resultfile"/>
-</xsl:template>
-
-<xsl:template match="resultfile">@<xsl:apply-templates select="@name"/><xsl:text> </xsl:text><xsl:apply-templates select="sql"/>
-</xsl:template>
-
-<xsl:template match="sql">
-<xsl:apply-templates />;
-</xsl:template>
-</xsl:stylesheet>
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 7de59939227..646bedf9603 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -27,7 +27,7 @@ noinst_HEADERS = mysys_priv.h my_static.h \
my_os2thread.c my_os2tls.c
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
mf_path.c mf_loadpath.c\
- my_open.c my_create.c my_seek.c my_read.c \
+ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
my_pread.c my_write.c \
mf_keycache.c \
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
@@ -38,7 +38,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_error.c errors.c my_div.c my_messnc.c \
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
my_symlink.c my_symlink2.c \
- mf_pack.c mf_pack2.c mf_unixpath.c mf_strip.c \
+ mf_pack.c mf_unixpath.c mf_strip.c \
mf_casecnv.c mf_soundex.c mf_wcomp.c mf_wfile.c \
mf_qsort.c mf_qsort2.c mf_sort.c \
ptr_cmp.c mf_radix.c queues.c \
@@ -47,10 +47,11 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_delete.c my_rename.c my_redel.c my_tempnam.c \
my_chsize.c my_lread.c my_lwrite.c my_clock.c \
my_quick.c my_lockmem.c my_static.c \
- getopt.c getopt1.c getvar.c my_mkdir.c \
- default.c my_compress.c checksum.c raid.cc raid2.c \
- my_net.c \
- my_vsnprintf.c charset.c my_bitmap.c my_gethostbyname.c
+ my_getopt.c my_mkdir.c \
+ default.c my_compress.c checksum.c raid.cc \
+ my_net.c my_semaphore.c \
+ my_vsnprintf.c charset.c my_bitmap.c my_bit.c md5.c \
+ my_gethostbyname.c rijndael.c my_aes.c sha1.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
@@ -100,6 +101,10 @@ test_vsnprintf: my_vsnprintf.c $(LIBRARIES)
$(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
$(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
$(RM) -f test_vsnprintf.*
+test_io_cache: mf_iocache.c $(LIBRARIES)
+ $(CP) $(srcdir)/mf_iocache.c test_io_cache.c
+ $(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
+ $(RM) -f test_io_cache.*
test_dir: test_dir.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
diff --git a/mysys/array.c b/mysys/array.c
index cc6710124d7..6d00585f24d 100644
--- a/mysys/array.c
+++ b/mysys/array.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Handling of arrays that can grow dynamicly. */
@@ -25,12 +24,28 @@
#include "m_string.h"
/*
- Initiate array and alloc space for init_alloc elements. Array is usable
- even if space allocation failed
+ Initiate dynamic array
+
+ SYNOPSIS
+ init_dynamic_array()
+ array Pointer to an array
+ element_size Size of element
+ init_alloc Number of initial elements
+ alloc_increment Increment for adding new elements
+
+ DESCRIPTION
+ init_dynamic_array() initiates array and allocate space for
+ init_alloc eilements.
+ Array is usable even if space allocation failed.
+
+ RETURN VALUE
+ TRUE my_malloc_ci() failed
+ FALSE Ok
*/
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
- uint init_alloc, uint alloc_increment CALLER_INFO_PROTO)
+ uint init_alloc,
+ uint alloc_increment CALLER_INFO_PROTO)
{
DBUG_ENTER("init_dynamic_array");
if (!alloc_increment)
@@ -52,8 +67,20 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
-}
+}
+/*
+ Insert element at the end of array. Allocate memory if needed.
+
+ SYNOPSIS
+ insert_dynamic()
+ array
+ element
+
+ RETURN VALUE
+ TRUE Insert failed
+ FALSE Ok
+*/
my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element)
{
@@ -73,7 +100,22 @@ my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element)
}
- /* Alloc room for one element */
+/*
+ Alloc space for next element(s)
+
+ SYNOPSIS
+ alloc_dynamic()
+ array
+
+ DESCRIPTION
+ alloc_dynamic() checks if there is empty space for at least
+ one element if not tries to allocate space for alloc_increment
+ elements at the end of array.
+
+ RETURN VALUE
+ pointer Pointer to empty space for element
+ 0 Error
+*/
byte *alloc_dynamic(DYNAMIC_ARRAY *array)
{
@@ -92,7 +134,17 @@ byte *alloc_dynamic(DYNAMIC_ARRAY *array)
}
- /* remove last element from array and return it */
+/*
+ Pop last element from array.
+
+ SYNOPSIS
+ pop_dynamic()
+ array
+
+ RETURN VALUE
+ pointer Ok
+ 0 Array is empty
+*/
byte *pop_dynamic(DYNAMIC_ARRAY *array)
{
@@ -101,6 +153,23 @@ byte *pop_dynamic(DYNAMIC_ARRAY *array)
return 0;
}
+/*
+ Replace elemnent in array with given element and index
+
+ SYNOPSIS
+ set_dynamic()
+ array
+ element Element to be inserted
+ idx Index where element is to be inserted
+
+ DESCRIPTION
+ set_dynamic() replaces element in array.
+ If idx > max_element insert new element. Allocate memory if needed.
+
+ RETURN VALUE
+ TRUE Idx was out of range and allocation of new memory failed
+ FALSE Ok
+*/
my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
{
@@ -128,6 +197,15 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
return FALSE;
}
+/*
+ Get an element from array by given index
+
+ SYNOPSIS
+ get_dynamic()
+ array
+ gptr Element to be returned. If idx > elements contain zeroes.
+ idx Index of element wanted.
+*/
void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
{
@@ -143,6 +221,14 @@ void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
}
+/*
+ Empty array by freeing all memory
+
+ SYNOPSIS
+ delete_dynamic()
+ array Array to be deleted
+*/
+
void delete_dynamic(DYNAMIC_ARRAY *array)
{
if (array->buffer)
@@ -153,6 +239,14 @@ void delete_dynamic(DYNAMIC_ARRAY *array)
}
}
+/*
+ Delete element by given index
+
+ SYNOPSIS
+ delete_dynamic_element()
+ array
+ idx Index of element to be deleted
+*/
void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
{
@@ -163,6 +257,15 @@ void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
}
+/*
+ Free unused memory
+
+ SYNOPSIS
+ freeze_size()
+ array Array to be freed
+
+*/
+
void freeze_size(DYNAMIC_ARRAY *array)
{
uint elements=max(array->elements,1);
diff --git a/mysys/charset.c b/mysys/charset.c
index 9d9ede2b0c4..1001b76f417 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -44,13 +43,6 @@ struct simpleconfig_buf_st {
char *p;
};
-/* Defined in strings/ctype.c */
-
-CHARSET_INFO *find_compiled_charset(uint cs_number);
-uint compiled_charset_number(const char *name);
-const char *compiled_charset_name(uint charset_number);
-
-
static uint num_from_csname(CS_ID **cs, const char *name)
{
CS_ID **c;
@@ -110,7 +102,7 @@ char *get_charsets_dir(char *buf)
strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR,
NullS);
}
- convert_dirname(buf);
+ convert_dirname(buf,buf,NullS);
DBUG_PRINT("info",("charsets dir='%s'", buf));
DBUG_RETURN(strend(buf));
}
@@ -203,6 +195,7 @@ static my_bool init_available_charsets(myf myflags)
void free_charsets(void)
{
delete_dynamic(&cs_info_table);
+ charset_initialized=0;
}
@@ -264,22 +257,22 @@ static my_bool read_charset_file(uint cs_number, CHARSET_INFO *set,
uint get_charset_number(const char *charset_name)
{
- my_bool error;
- error = init_available_charsets(MYF(0)); /* If it isn't initialized */
- if (error)
- return compiled_charset_number(charset_name);
- else
- return num_from_csname(available_charsets, charset_name);
+ uint number=compiled_charset_number(charset_name);
+ if (number)
+ return number;
+ if (init_available_charsets(MYF(0))) /* If it isn't initialized */
+ return 0;
+ return num_from_csname(available_charsets, charset_name);
}
const char *get_charset_name(uint charset_number)
{
- my_bool error;
- error = init_available_charsets(MYF(0)); /* If it isn't initialized */
- if (error)
- return compiled_charset_name(charset_number);
- else
- return name_from_csnum(available_charsets, charset_number);
+ const char *name=compiled_charset_name(charset_number);
+ if (*name != '?')
+ return name;
+ if (init_available_charsets(MYF(0))) /* If it isn't initialized */
+ return "?";
+ return name_from_csnum(available_charsets, charset_number);
}
@@ -293,8 +286,8 @@ static CHARSET_INFO *find_charset(CHARSET_INFO **table, uint cs_number,
return NULL;
}
-static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, const char *name,
- size_t tablesz)
+static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table,
+ const char *name, size_t tablesz)
{
uint i;
for (i = 0; i < tablesz; ++i)
@@ -303,7 +296,7 @@ static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, const char *name
return NULL;
}
-static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name)
+static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, myf flags)
{
CHARSET_INFO tmp_cs,*cs;
uchar tmp_ctype[CTYPE_TABLE_SIZE];
@@ -318,11 +311,11 @@ static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name)
cs->to_lower=tmp_to_lower;
cs->to_upper=tmp_to_upper;
cs->sort_order=tmp_sort_order;
- if (read_charset_file(cs_number, cs, MYF(MY_WME)))
+ if (read_charset_file(cs_number, cs, flags))
return NULL;
cs = (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),
- MYF(MY_WME));
+ MYF(MY_WME));
*cs=tmp_cs;
cs->name = (char *) my_once_alloc((uint) strlen(cs_name)+1, MYF(MY_WME));
cs->ctype = (uchar*) my_once_alloc(CTYPE_TABLE_SIZE, MYF(MY_WME));
@@ -340,7 +333,7 @@ static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name)
return cs;
}
-static CHARSET_INFO *get_internal_charset(uint cs_number)
+static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
{
CHARSET_INFO *cs;
/*
@@ -351,13 +344,13 @@ static CHARSET_INFO *get_internal_charset(uint cs_number)
if (!(cs = find_charset((CHARSET_INFO**) cs_info_table.buffer, cs_number,
cs_info_table.elements)))
if (!(cs = find_compiled_charset(cs_number)))
- cs=add_charset(cs_number, get_charset_name(cs_number));
+ cs=add_charset(cs_number, get_charset_name(cs_number), flags);
pthread_mutex_unlock(&THR_LOCK_charset);
return cs;
}
-static CHARSET_INFO *get_internal_charset_by_name(const char *name)
+static CHARSET_INFO *get_internal_charset_by_name(const char *name, myf flags)
{
CHARSET_INFO *cs;
/*
@@ -368,7 +361,7 @@ static CHARSET_INFO *get_internal_charset_by_name(const char *name)
if (!(cs = find_charset_by_name((CHARSET_INFO**) cs_info_table.buffer, name,
cs_info_table.elements)))
if (!(cs = find_compiled_charset_by_name(name)))
- cs=add_charset(get_charset_number(name), name);
+ cs=add_charset(get_charset_number(name), name, flags);
pthread_mutex_unlock(&THR_LOCK_charset);
return cs;
}
@@ -378,7 +371,7 @@ CHARSET_INFO *get_charset(uint cs_number, myf flags)
{
CHARSET_INFO *cs;
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
- cs=get_internal_charset(cs_number);
+ cs=get_internal_charset(cs_number, flags);
if (!cs && (flags & MY_WME))
{
@@ -410,7 +403,7 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
{
CHARSET_INFO *cs;
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
- cs=get_internal_charset_by_name(cs_name);
+ cs=get_internal_charset_by_name(cs_name, flags);
if (!cs && (flags & MY_WME))
{
diff --git a/mysys/checksum.c b/mysys/checksum.c
index 00861853945..1dd135c7ad9 100644
--- a/mysys/checksum.c
+++ b/mysys/checksum.c
@@ -1,30 +1,37 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Calculate a long checksum for a memoryblock. Used to verify pack_isam */
-#include <global.h>
+#include <my_global.h>
#include "my_sys.h"
+/*
+ Calculate a long checksum for a memoryblock. Used to verify pack_isam
+
+ SYNOPSIS
+ checksum()
+ mem Pointer to memory block
+ count Count of bytes
+*/
+
ulong checksum(const byte *mem, uint count)
{
ulong crc;
- for (crc=0; count-- ; mem++)
- crc=((crc << 1) + *((uchar*) mem)) +
+ for (crc= 0; count-- ; mem++)
+ crc= ((crc << 1) + *((uchar*) mem)) +
test(crc & ((ulong) 1L << (8*sizeof(ulong)-1)));
return crc;
}
diff --git a/mysys/default.c b/mysys/default.c
index 062711b185d..fdeeabf83eb 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/****************************************************************************
** Add all options from files named "group".cnf from the default_directories
@@ -83,7 +82,7 @@ void load_defaults(const char *conf_file, const char **groups,
char *ptr,**res;
DBUG_ENTER("load_defaults");
- init_alloc_root(&alloc,128,0);
+ init_alloc_root(&alloc,512,0);
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
{
/* remove the --no-defaults argument and return only the other arguments */
@@ -95,6 +94,7 @@ void load_defaults(const char *conf_file, const char **groups,
res[0]= **argv; /* Copy program name */
for (i=2 ; i < (uint) *argc ; i++)
res[i-1]=argv[0][i];
+ res[i-1]=0; /* End pointer */
(*argc)--;
*argv=res;
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
@@ -231,11 +231,10 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
return 0; /* Ignore wrong paths */
if (dir)
{
- strmov(name,dir);
- convert_dirname(name);
+ end=convert_dirname(name, dir, NullS);
if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
- strcat(name,".");
- strxmov(strend(name),config_file,ext,NullS);
+ *end++='.';
+ strxmov(end,config_file,ext,NullS);
}
else
{
@@ -369,16 +368,18 @@ void print_defaults(const char *conf_file, const char **groups)
#endif
for (dirs=default_directories ; *dirs; dirs++)
{
+ const char *pos;
+ char *end;
if (**dirs)
- strmov(name,*dirs);
+ pos= *dirs;
else if (defaults_extra_file)
- strmov(name,defaults_extra_file);
+ pos= defaults_extra_file;
else
continue;
- convert_dirname(name);
+ end=convert_dirname(name, pos, NullS);
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
- strcat(name,".");
- strxmov(strend(name),conf_file,default_ext," ",NullS);
+ *end++='.';
+ strxmov(end,conf_file,default_ext," ",NullS);
fputs(name,stdout);
}
puts("");
@@ -395,4 +396,3 @@ void print_defaults(const char *conf_file, const char **groups)
--defaults-file=# Only read default options from the given file #\n\
--defaults-extra-file=# Read this file after the global files are read");
}
-
diff --git a/mysys/errors.c b/mysys/errors.c
index 77e52c2f0b3..8a120e0e869 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/getopt.c b/mysys/getopt.c
deleted file mode 100644
index 774cf3b82f4..00000000000
--- a/mysys/getopt.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
- before changing it!
-
- Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
- Free Software Foundation, Inc.
-
-Changes by monty:
-- Added include of string.h when nessessary.
-- Removed two warnings from gcc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
- Ditto for AIX 3.2 and <stdlib.h>. */
-#ifndef _NO_PROTO
-#define _NO_PROTO
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2)
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <global.h> /* Changes for mysys */
-#include <m_string.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
- contain conflicting prototypes for getopt. */
-#include <stdlib.h>
-#endif /* GNU C library. */
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable POSIXLY_CORRECT disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = NULL;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* XXX 1003.2 says this must be 1 before any call. */
-int optind = 1;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we scan,
- so that eventually all the non-options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1.
- Using `-' as the first character of the list of option characters
- selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return EOF with `optind' != ARGC. */
-
-static enum
-{
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable. */
-static char *posixly_correct;
-
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
- because there are many ways it can cause trouble.
- On some systems, it contains special magic macros that don't work
- in GCC. */
-#include <string.h>
-#define my_index strchr
-#else
-
-/* Avoid depending on library functions or files
- whose names are inconsistent. */
-
-#ifndef OS2
-char *getenv (const char *);
-#endif
-
-static char *
-my_index (const char *str, int chr)
-{
- while (*str)
- {
- if (*str == chr)
- return (char *) str;
- str++;
- }
- return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
- If not using GCC, it is ok not to declare it. */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
- That was relevant to code that was here before. */
-#if !defined (__STDC__) || !__STDC__
-/* gcc with -traditional declares the built-in strlen to return int,
- and has done so at least since version 2.4.5. -- rms. */
-extern int strlen (const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-static void
-exchange (char **argv)
-{
- int bottom = first_nonopt;
- int middle = last_nonopt;
- int top = optind;
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
- while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
- {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- first_nonopt += (optind - last_nonopt);
- last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made. */
-
-static const char *
-_getopt_initialize (const char *optstring)
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- first_nonopt = last_nonopt = optind = 1;
-
- nextchar = NULL;
-
- posixly_correct = getenv ("POSIXLY_CORRECT");
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (posixly_correct != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns `EOF'.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-int
-_getopt_internal (int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only)
-{
- optarg = NULL;
-
- if (optind == 0)
- optstring = _getopt_initialize (optstring);
-
- if (nextchar == NULL || *nextchar == '\0')
- {
- /* Advance to the next ARGV-element. */
-
- if (ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (optind < argc
- && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
- optind++;
- last_nonopt = optind;
- }
-
- /* The special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp (argv[optind], "--"))
- {
- optind++;
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return EOF;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
- {
- if (ordering == REQUIRE_ORDER)
- return EOF;
- optarg = argv[optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Skip the initial punctuation. */
-
- nextchar = (argv[optind] + 1
- + (longopts != NULL && argv[optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is
- a valid short option, don't consider it an abbreviated form of
- a long option that starts with f. Otherwise there would be no
- way to give the -f short option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an abbreviation of
- the long option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL
- && (argv[optind][1] == '-'
- || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound=0; /* Keep gcc happy */
- int option_index;
-
- for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, nextchar, nameend - nextchar))
- {
- if ((size_t) (nameend - nextchar) == (size_t) strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact)
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' is ambiguous\n",
- argv[0], argv[optind]);
- nextchar += strlen (nextchar);
- optind++;
- return '?';
- }
-
- if (pfound != NULL)
- {
- option_index = indfound;
- optind++;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else
- {
- if (opterr)
- {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf (stderr,
- "%s: option `--%s' doesn't allow an argument\n",
- argv[0], pfound->name);
- else
- /* +option or -option */
- fprintf (stderr,
- "%s: option `%c%s' doesn't allow an argument\n",
- argv[0], argv[optind - 1][0], pfound->name);
- }
- nextchar += strlen (nextchar);
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (optind < argc)
- optarg = argv[optind++];
- else
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' requires an argument\n",
- argv[0], argv[optind - 1]);
- nextchar += strlen (nextchar);
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[optind][1] == '-'
- || my_index (optstring, *nextchar) == NULL)
- {
- if (opterr)
- {
- if (argv[optind][1] == '-')
- /* --option */
- fprintf (stderr, "%s: unrecognized option `--%s'\n",
- argv[0], nextchar);
- else
- /* +option or -option */
- fprintf (stderr, "%s: unrecognized option `%c%s'\n",
- argv[0], argv[optind][0], nextchar);
- }
- nextchar = (char *) "";
- optind++;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *nextchar++;
- char *temp = my_index (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*nextchar == '\0')
- ++optind;
-
- if (temp == NULL || c == ':')
- {
- if (opterr)
- {
- if (posixly_correct)
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
- else
- fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
- }
- optopt = c;
- return '?';
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- optind++;
- }
- else
- optarg = NULL;
- nextchar = NULL;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- }
- else if (optind == argc)
- {
- if (opterr)
- {
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: option requires an argument -- %c\n",
- argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-#ifdef __EMX__
-int getopt (int argc, char **argv, __const__ char *optstring)
-#else
-int
-getopt (int argc, char *const *argv, const char *optstring)
-#endif
-{
- return _getopt_internal (argc, argv, optstring,
- (const struct option *) 0,
- (int *) 0,
- 0);
-}
-
-#endif /* _LIBC or not __GNU_LIBRARY__. */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt (argc, argv, "abc:d:0123456789");
- if (c == EOF)
- break;
-
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/mysys/getopt1.c b/mysys/getopt1.c
deleted file mode 100644
index bff76d6e5b2..00000000000
--- a/mysys/getopt1.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
- Free Software Foundation, Inc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <global.h>
-#include "getopt.h"
-
-#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2)
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
-
-#ifndef __WIN__
-#include <stdlib.h>
-#endif /* __WIN__ */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
- If an option that starts with '-' (not '--') doesn't match a long option,
- but does match a short option, it is parsed as a short option
- instead. */
-
-int
-getopt_long_only (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
-}
-
-
-#endif /* _LIBC or not __GNU_LIBRARY__. */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
- int option_index = 0;
- static struct option long_options[] =
- {
- {"add", 1, 0, 0},
- {"append", 0, 0, 0},
- {"delete", 1, 0, 0},
- {"verbose", 0, 0, 0},
- {"create", 0, 0, 0},
- {"file", 1, 0, 0},
- {0, 0, 0, 0}
- };
-
- c = getopt_long (argc, argv, "abc:d:0123456789",
- long_options, &option_index);
- if (c == EOF)
- break;
-
- switch (c)
- {
- case 0:
- printf ("option %s", long_options[option_index].name);
- if (optarg)
- printf (" with arg %s", optarg);
- printf ("\n");
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case 'd':
- printf ("option d with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/mysys/getvar.c b/mysys/getvar.c
deleted file mode 100644
index 90ab599244d..00000000000
--- a/mysys/getvar.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Allow use of the -O variable= option to set long variables */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <m_ctype.h>
-
- /* set all changeable variables */
-
-void set_all_changeable_vars(CHANGEABLE_VAR *vars)
-{
- for ( ; vars->name ; vars++)
- *vars->varptr= vars->def_value;
-}
-
-
-my_bool set_changeable_varval(const char* var, ulong val,
- CHANGEABLE_VAR *vars)
-{
- char buffer[256];
- sprintf( buffer, "%s=%lu", var, (unsigned long) val );
- return set_changeable_var( buffer, vars );
-}
-
-
-my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars)
-{
- char endchar;
- my_string end;
- DBUG_ENTER("set_changeable_var");
- DBUG_PRINT("enter",("%s",str));
-
- if (str)
- {
- if (!(end=strchr(str,'=')))
- fprintf(stderr,"Can't find '=' in expression '%s' to option -O\n",str);
- else
- {
- uint length,found_count=0;
- CHANGEABLE_VAR *var,*found;
- my_string var_end;
- const char *name;
- longlong num;
-
- /* Skip end space from variable */
- for (var_end=end ; end > str && isspace(var_end[-1]) ; var_end--) ;
- length=(uint) (var_end-str);
- /* Skip start space from argument */
- for (end++ ; isspace(*end) ; end++) ;
-
- for (var=vars,found=0 ; (name=var->name) ; var++)
- {
- if (!my_casecmp(name,str,length))
- {
- found=var; found_count++;
- if (!name[length])
- {
- found_count=1;
- break;
- }
- }
- }
- if (found_count == 0)
- {
- fprintf(stderr,"No variable match for: -O '%s'\n",str);
- DBUG_RETURN(1);
- }
- if (found_count > 1)
- {
- fprintf(stderr,"Variable prefix '%*s' is not unique\n",length,str);
- DBUG_RETURN(1);
- }
-
- num=strtoll(end, (char **)NULL, 10); endchar=strend(end)[-1];
- if (endchar == 'k' || endchar == 'K')
- num*=1024;
- else if (endchar == 'm' || endchar == 'M')
- num*=1024L*1024L;
- else if (endchar == 'g' || endchar == 'G')
- num*=1024L*1024L*1024L;
- else if (!isdigit(endchar))
- {
- fprintf(stderr,"Unknown prefix used for variable value '%s'\n",str);
- DBUG_RETURN(1);
- }
- if (num < (longlong) found->min_value)
- num=(longlong) found->min_value;
- else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) found->max_value)
- num=(longlong) (ulong) found->max_value;
- num=((num- (longlong) found->sub_size) / (ulonglong) found->block_size);
- (*found->varptr)= (long) (num*(ulonglong) found->block_size);
- DBUG_RETURN(0);
- }
- }
- DBUG_RETURN(1);
-}
diff --git a/mysys/hash.c b/mysys/hash.c
index eb74b1f30dd..eaea6d7503f 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* The hash functions used for saveing keys */
/* One of key_length or key_length_offset must be given */
@@ -148,9 +147,7 @@ static uint calc_hashnr_caseup(const byte *key,uint length)
*
* The magic is in the interesting relationship between the special prime
* 16777619 (2^24 + 403) and 2^32 and 2^8.
- *
- * This hash produces the fewest collisions of any function that we've seen so
- * far, and works well on both numbers and strings.
+ * This works well on both numbers and strings.
*/
uint calc_hashnr(const byte *key, uint len)
@@ -517,8 +514,8 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
/* Search after record with key */
idx=hash_mask((*hash->calc_hashnr)(old_key,(old_key_length ?
- old_key_length :
- hash->key_length)),
+ old_key_length :
+ hash->key_length)),
blength,records);
new_index=hash_mask(rec_hashnr(hash,record),blength,records);
if (idx == new_index)
@@ -578,6 +575,18 @@ byte *hash_element(HASH *hash,uint idx)
}
+/*
+ Replace old row with new row. This should only be used when key
+ isn't changed
+*/
+
+void hash_replace(HASH *hash, uint idx, byte *new_row)
+{
+ if (idx != NO_RECORD) /* Safety */
+ dynamic_element(&hash->array,idx,HASH_LINK*)->data=new_row;
+}
+
+
#ifndef DBUG_OFF
my_bool hash_check(HASH *hash)
diff --git a/mysys/list.c b/mysys/list.c
index c9c863d4cc2..ac9e1b979a0 100644
--- a/mysys/list.c
+++ b/mysys/list.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for handling dubble-linked lists in C
diff --git a/mysys/make-conf.c b/mysys/make-conf.c
index 9db766574e2..404299e1726 100644
--- a/mysys/make-conf.c
+++ b/mysys/make-conf.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* make-conf.c
* make a charset .conf file out of a ctype-charset.c file.
@@ -34,7 +33,7 @@
#define CH_INCLUDE STRINGIZE(CH_SRC)
/* aaaah, that's better */
-#include <my_global.h>
+#include <my_my_global.h>
#include CH_INCLUDE
#include <stdio.h>
diff --git a/mysys/md5.c b/mysys/md5.c
new file mode 100644
index 00000000000..5de95288141
--- /dev/null
+++ b/mysys/md5.c
@@ -0,0 +1,369 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+*/
+
+/*
+ Changes by Monty:
+ Replace of MD5_memset and MD5_memcpy with memset & memcpy
+*/
+
+#include <my_global.h>
+#include <m_string.h>
+#include "md5.h"
+
+/* Constants for MD5Transform routine. */
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+ ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+ ((UINT4 *, unsigned char *, unsigned int));
+#ifdef OLD_CODE
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+#else
+#define MD5_memcpy(A,B,C) memcpy((char*) (A),(char*) (B), (C))
+#define MD5_memset(A,B,C) memset((char*) (A),(B), (C))
+#endif
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void my_MD5Init (my_MD5_CTX *context) /* context */
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+*/
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+
+void my_MD5Update (
+my_MD5_CTX *context, /* context */
+unsigned char *input, /* input block */
+unsigned int inputLen) /* length of input block */
+{
+ unsigned int i, idx, partLen;
+
+ /* Compute number of bytes mod 64 */
+ idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - idx;
+
+ /* Transform as many times as possible.
+*/
+ if (inputLen >= partLen) {
+ MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
+ MD5Transform(context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ idx = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+
+void my_MD5Final (
+unsigned char digest[16], /* message digest */
+my_MD5_CTX *context) /* context */
+{
+ unsigned char bits[8];
+ unsigned int idx, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+*/
+ idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (idx < 56) ? (56 - idx) : (120 - idx);
+ my_MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ my_MD5Update (context, bits, 8);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (
+UINT4 state[4],
+unsigned char block[64])
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (
+unsigned char *output,
+UINT4 *input,
+unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (
+UINT4 *output,
+unsigned char *input,
+unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+#ifndef MD5_memcpy
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ output[i] = input[i];
+}
+#endif
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+
+#ifndef MD5_memset
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
+#endif
diff --git a/mysys/mf_brkhant.c b/mysys/mf_brkhant.c
index debf5d9a712..4180bd6df66 100644
--- a/mysys/mf_brkhant.c
+++ b/mysys/mf_brkhant.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Dont let the user break when you are doing something important */
/* Remembers if it got 'SIGINT' and executes it on allow_break */
diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c
index 85b6b19b328..2c5d8658625 100644
--- a/mysys/mf_cache.c
+++ b/mysys/mf_cache.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Open a temporary file and cache it with io_cache. Delete it on close */
diff --git a/mysys/mf_casecnv.c b/mysys/mf_casecnv.c
index 125f54b2594..0302688ad1f 100644
--- a/mysys/mf_casecnv.c
+++ b/mysys/mf_casecnv.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Functions to convert to lover_case and to upper_case in scandinavia.
@@ -25,7 +24,9 @@
#include "mysys_priv.h"
#include <m_ctype.h>
+#ifndef SCO
#include <m_string.h>
+#endif
/* string to uppercase */
@@ -35,7 +36,7 @@ void caseup_str(my_string str)
if (use_mb(default_charset_info))
{
register uint32 l;
- register char *end=str+(uint) strlen(str);
+ register char *end=str+strlen(str);
while (*str)
{
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
@@ -56,7 +57,7 @@ void casedn_str(my_string str)
if (use_mb(default_charset_info))
{
register uint32 l;
- register char *end=str+(uint) strlen(str);
+ register char *end=str+strlen(str);
while (*str)
{
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
@@ -155,7 +156,7 @@ int my_strcasecmp(const char *s, const char *t)
if (use_mb(default_charset_info))
{
register uint32 l;
- register const char *end=s+(uint) strlen(s);
+ register const char *end=s+strlen(s);
while (s<end)
{
if ((l=my_ismbchar(default_charset_info, s,end)))
diff --git a/mysys/mf_dirname.c b/mysys/mf_dirname.c
index 399082a238b..6523abcdb12 100644
--- a/mysys/mf_dirname.c
+++ b/mysys/mf_dirname.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -50,57 +49,70 @@ uint dirname_part(my_string to, const char *name)
DBUG_PRINT("enter",("'%s'",name));
length=dirname_length(name);
- (void) strmake(to,(char*) name,min(length,FN_REFLEN-2));
- convert_dirname(to); /* Convert chars */
+ convert_dirname(to, name, name+length);
DBUG_RETURN(length);
} /* dirname */
- /* convert dirname to use under this system */
- /* If MSDOS converts '/' to '\' */
- /* If VMS converts '<' to '[' and '>' to ']' */
- /* Adds a '/' to end if there isn't one and the last isn't a dev_char */
- /* ARGSUSED */
+ /*
+ Convert directory name to use under this system
+ If MSDOS converts '/' to '\'
+ If VMS converts '<' to '[' and '>' to ']'
+ Adds a FN_LIBCHAR to end if the result string if there isn't one
+ and the last isn't dev_char.
+ Copies data from 'from' until ASCII(0) for until from == from_end
+ If you want to use the whole 'from' string, just send NullS as the
+ last argument.
+ If the result string is larger than FN_REFLEN -1, then it's cut.
+
+ Returns pointer to end \0
+ */
#ifndef FN_DEVCHAR
#define FN_DEVCHAR '\0' /* For easier code */
#endif
-char *convert_dirname(my_string to)
+char *convert_dirname(char *to, const char *from, const char *from_end)
{
- reg1 char *pos;
-#ifdef FN_UPPER_CASE
- caseup_str(to);
-#endif
-#ifdef FN_LOWER_CASE
- casedn_str(to);
-#endif
-#if FN_LIBCHAR != '/'
- {
- pos=to-1; /* Change from '/' */
- while ((pos=strchr(pos+1,'/')) != 0)
- *pos=FN_LIBCHAR;
- }
-#endif
-#ifdef FN_C_BEFORE_DIR_2
+ char *to_org=to;
+
+ /* We use -2 here, becasue we need place for the last FN_LIBCHAR */
+ if (!from_end || (from_end - from) > FN_REFLEN-2)
+ from_end=from+FN_REFLEN -2;
+
+#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
{
- for (pos=to ; *pos ; pos++)
+ for (; *from && from != from_end; from++)
{
- if (*pos == FN_C_BEFORE_DIR_2)
- *pos=FN_C_BEFORE_DIR;
- if (*pos == FN_C_AFTER_DIR_2)
- *pos=FN_C_AFTER_DIR;
+ if (*from == '/')
+ *to++= FN_LIBCHAR;
+#ifdef FN_C_BEFORE_DIR_2
+ else if (*from == FN_C_BEFORE_DIR_2)
+ *to++= FN_C_BEFORE_DIR;
+ else if (*from == FN_C_AFTER_DIR_2)
+ *to++= FN_C_AFTER_DIR;
+#endif
+ else
+ *to++= *from;
}
+ *to=0;
}
#else
- { /* Append FN_LIBCHAR if not there */
- pos=strend(to);
- if (pos != to && (pos[-1] != FN_LIBCHAR && pos[-1] != FN_DEVCHAR))
- {
- *pos++=FN_LIBCHAR;
- *pos=0;
- }
+ /* This is ok even if to == from, becasue we need to cut the string */
+ to= strmake(to, from, (uint) (from_end-from));
+#endif
+
+ /* Add FN_LIBCHAR to the end of directory path */
+ if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR))
+ {
+ *to++=FN_LIBCHAR;
+ *to=0;
}
+#ifdef FN_UPPER_CASE
+ caseup_str(to_org);
+#endif
+#ifdef FN_LOWER_CASE
+ casedn_str(to_org);
#endif
- return pos; /* Pointer to end of dir */
+ return to; /* Pointer to end of dir */
} /* convert_dirname */
diff --git a/mysys/mf_fn_ext.c b/mysys/mf_fn_ext.c
index 6a9b9d18341..3a11f1a247e 100644
--- a/mysys/mf_fn_ext.c
+++ b/mysys/mf_fn_ext.c
@@ -1,30 +1,29 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Returnerar en pekare till filnamnets extension. */
#include "mysys_priv.h"
#include <m_string.h>
- /* Return a pointerto the extension of the filename
- The pointer points at the extension character (normally '.'))
- If there isn't any extension, the pointer points at the end
- NULL of the filename
- */
+/*
+ Return a pointerto the extension of the filename
+ The pointer points at the extension character (normally '.'))
+ If there isn't any extension, the pointer points at the end
+ ASCII(0) of the filename.
+*/
my_string fn_ext(const char *name)
{
diff --git a/mysys/mf_format.c b/mysys/mf_format.c
index 7dac46cf0d0..ab1904da162 100644
--- a/mysys/mf_format.c
+++ b/mysys/mf_format.c
@@ -1,94 +1,84 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
-#ifdef HAVE_REALPATH
-#include <sys/param.h>
-#include <sys/stat.h>
-#endif
- /* format a filename with replace of library and extension */
- /* params to and name may be identicall */
- /* function doesn't change name if name != to */
- /* Flag may be: 1 replace filenames library with 'dsk' */
- /* 2 replace extension with 'form' */
- /* 4 Unpack filename (replace ~ with home) */
- /* 8 Pack filename as short as possibly */
- /* 16 Resolve symbolic links for filename */
- /* 32 Resolve filename to full path */
- /* 64 Return NULL if too long path */
+ /*
+ Formats a filename with possible replace of directory of extension
+ Function can handle the case where 'to' == 'name'
+ For a description of the flag values, consult my_sys.h
+ The arguments should be in unix format.
+ */
-#ifdef SCO
-#define BUFF_LEN 4097
-#else
-#ifdef MAXPATHLEN
-#define BUFF_LEN MAXPATHLEN
-#else
-#define BUFF_LEN FN_LEN
-#endif
-#endif
-my_string fn_format(my_string to, const char *name, const char *dsk,
- const char *form, int flag)
+my_string fn_format(my_string to, const char *name, const char *dir,
+ const char *extension, uint flag)
{
reg1 uint length;
- char dev[FN_REFLEN], buff[BUFF_LEN], *pos, *startpos;
+ char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos;
const char *ext;
DBUG_ENTER("fn_format");
- DBUG_PRINT("enter",("name: %s dsk: %s form: %s flag: %d",
- name,dsk,form,flag));
+ DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d",
+ name,dir,extension,flag));
- /* Kopiera & skippa enheten */
+ /* Copy and skip directory */
name+=(length=dirname_part(dev,(startpos=(my_string) name)));
- if (length == 0 || flag & 1)
+ if (length == 0 || (flag & MY_REPLACE_DIR))
{
- (void) strmake(dev,dsk, sizeof(dev) - 2);
- /* Use given directory */
- convert_dirname(dev); /* Fix to this OS */
+ /* Use given directory */
+ convert_dirname(dev,dir,NullS); /* Fix to this OS */
}
- if (flag & 8)
+ else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(name))
+ {
+ /* Put 'dir' before the given path */
+ strmake(buff,dev,sizeof(buff)-1);
+ pos=convert_dirname(dev,dir,NullS);
+ strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev));
+ }
+
+ if (flag & MY_PACK_FILENAME)
pack_dirname(dev,dev); /* Put in ./.. and ~/.. */
- if (flag & 4)
+ if (flag & MY_UNPACK_FILENAME)
(void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */
- if ((pos=(char*)strchr(name,FN_EXTCHAR)) != NullS)
+ if ((pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
{
- if ((flag & 2) == 0) /* Skall vi byta extension ? */
+ if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */
{
- length=strlength(name); /* Old extension */
+ length=strlength(name); /* Use old extension */
ext = "";
}
else
{
length=(uint) (pos-(char*) name); /* Change extension */
- ext= form;
+ ext= extension;
}
}
else
{
- length=strlength(name); /* Har ingen ext- tag nya */
- ext=form;
+ length=strlength(name); /* No ext, use the now one */
+ ext=extension;
}
if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
- { /* To long path, return original */
+ {
+ /* To long path, return original or NULL */
uint tmp_length;
- if (flag & 64)
- return 0;
+ if (flag & MY_SAFE_PATH)
+ return NullS;
tmp_length=strlength(startpos);
DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %d",dev,ext,length));
(void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
@@ -109,18 +99,18 @@ my_string fn_format(my_string to, const char *name, const char *dsk,
#endif
(void) strmov(pos,ext); /* Don't convert extension */
}
- /* Purify gives a lot of UMR errors when using realpath */
-#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
- if (flag & 16)
+ /*
+ If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do
+ realpath if the file is a symbolic link
+ */
+ if (flag & MY_RETURN_REAL_PATH)
+ (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ?
+ MY_RESOLVE_LINK: 0));
+ else if (flag & MY_RESOLVE_SYMLINKS)
{
- struct stat stat_buff;
- if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
- {
- if (realpath(to,buff))
- strmake(to,buff,FN_REFLEN-1);
- }
+ strmov(buff,to);
+ (void) my_readlink(to, buff, MYF(0));
}
-#endif
DBUG_RETURN (to);
} /* fn_format */
diff --git a/mysys/mf_getdate.c b/mysys/mf_getdate.c
index f01d1d7633a..189d43e782a 100644
--- a/mysys/mf_getdate.c
+++ b/mysys/mf_getdate.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Get date in a printable form: yyyy-mm-dd hh:mm:ss */
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 0d1c227c2b2..b6e721cbd57 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Cashing of files with only does (sequential) read or writes of fixed-
@@ -23,12 +22,30 @@
Possibly use of asyncronic io.
macros for read and writes for faster io.
Used instead of FILE when reading or writing whole files.
- This will make mf_rec_cache obsolete.
+ This code makes mf_rec_cache obsolete (currently only used by ISAM)
One can change info->pos_in_file to a higher value to skip bytes in file if
- also info->rc_pos is set to info->rc_end.
+ also info->read_pos is set to info->read_end.
If called through open_cached_file(), then the temporary file will
only be created if a write exeeds the file buffer or if one calls
- flush_io_cache().
+ flush_io_cache().
+
+ If one uses SEQ_READ_APPEND, then two buffers are allocated, one for
+ reading and another for writing. Reads are first done from disk and
+ then done from the write buffer. This is an efficient way to read
+ from a log file when one is writing to it at the same time.
+ For this to work, the file has to be opened in append mode!
+ Note that when one uses SEQ_READ_APPEND, one MUST write using
+ my_b_append ! This is needed because we need to lock the mutex
+ every time we access the write buffer.
+
+TODO:
+ When one SEQ_READ_APPEND and we are reading and writing at the same time,
+ each time the write buffer gets full and it's written to disk, we will
+ always do a disk read to read a part of the buffer from disk to the
+ read buffer.
+ This should be fixed so that when we do a flush_io_cache() and
+ we have been reading the write buffer, we should transfer the rest of the
+ write buffer to the read buffer before we start to reuse it.
*/
#define MAP_TO_USE_RAID
@@ -36,10 +53,62 @@
#include <m_string.h>
#ifdef HAVE_AIOWAIT
#include "mysys_err.h"
-#include <errno.h>
static void my_aiowait(my_aio_result *result);
#endif
+#include <assert.h>
+#include <errno.h>
+
+#ifdef THREAD
+#define lock_append_buffer(info) \
+ pthread_mutex_lock(&(info)->append_buffer_lock)
+#define unlock_append_buffer(info) \
+ pthread_mutex_unlock(&(info)->append_buffer_lock)
+#else
+#define lock_append_buffer(info)
+#define unlock_append_buffer(info)
+#endif
+
+#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
+#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
+
+static void
+init_functions(IO_CACHE* info, enum cache_type type)
+{
+ switch (type) {
+ case READ_NET:
+ /*
+ Must be initialized by the caller. The problem is that
+ _my_b_net_read has to be defined in sql directory because of
+ the dependency on THD, and therefore cannot be visible to
+ programs that link against mysys but know nothing about THD, such
+ as myisamchk
+ */
+ break;
+ case SEQ_READ_APPEND:
+ info->read_function = _my_b_seq_read;
+ info->write_function = 0; /* Force a core if used */
+ break;
+ default:
+ info->read_function =
+#ifdef THREAD
+ info->share ? _my_b_read_r :
+#endif
+ _my_b_read;
+ info->write_function = _my_b_write;
+ }
+ /* Ensure that my_b_tell() and my_b_bytes_in_cache works */
+ if (type == WRITE_CACHE)
+ {
+ info->current_pos= &info->write_pos;
+ info->current_end= &info->write_end;
+ }
+ else
+ {
+ info->current_pos= &info->read_pos;
+ info->current_end= &info->read_end;
+ }
+}
/*
** if cachesize == 0 then use default cachesize (from s-file)
@@ -52,70 +121,96 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
pbool use_async_io, myf cache_myflags)
{
uint min_cache;
+ my_off_t end_of_file= ~(my_off_t) 0;
DBUG_ENTER("init_io_cache");
DBUG_PRINT("enter",("type: %d pos: %ld",(int) type, (ulong) seek_offset));
- info->file=file;
+ info->file= file;
+ info->type=type;
+ info->pos_in_file= seek_offset;
+ info->pre_close = info->pre_read = info->post_read = 0;
+ info->arg = 0;
+ info->alloced_buffer = 0;
+ info->buffer=0;
+ info->seek_not_done= test(file >= 0);
+#ifdef THREAD
+ info->share=0;
+#endif
+
if (!cachesize)
if (! (cachesize= my_default_record_cache_size))
DBUG_RETURN(1); /* No cache requested */
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
- if (type == READ_CACHE)
+ if (type == READ_CACHE || type == SEQ_READ_APPEND)
{ /* Assume file isn't growing */
- if (cache_myflags & MY_DONT_CHECK_FILESIZE)
- {
- cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
- }
- else
+ if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
{
- my_off_t file_pos,end_of_file;
- if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
- DBUG_RETURN(1);
+ /* Calculate end of file to not allocate to big buffers */
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
if (end_of_file < seek_offset)
end_of_file=seek_offset;
- VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
+ /* Trim cache size if the file is very small */
if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
{
cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No nead to use async */
+ use_async_io=0; /* No need to use async */
}
}
}
-
- for (;;)
+ cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
+ if (type != READ_NET && type != WRITE_NET)
{
- cachesize=(uint) ((ulong) (cachesize + min_cache-1) &
- (ulong) ~(min_cache-1));
- if (cachesize < min_cache)
- cachesize = min_cache;
- if ((info->buffer=
- (byte*) my_malloc(cachesize,
- MYF((cache_myflags & ~ MY_WME) |
- (cachesize == min_cache ? MY_WME : 0)))) != 0)
- break; /* Enough memory found */
- if (cachesize == min_cache)
- DBUG_RETURN(2); /* Can't alloc cache */
- cachesize= (uint) ((long) cachesize*3/4); /* Try with less memory */
+ /* Retry allocating memory in smaller blocks until we get one */
+ for (;;)
+ {
+ uint buffer_block;
+ cachesize=(uint) ((ulong) (cachesize + min_cache-1) &
+ (ulong) ~(min_cache-1));
+ if (cachesize < min_cache)
+ cachesize = min_cache;
+ buffer_block = cachesize;
+ if (type == SEQ_READ_APPEND)
+ buffer_block *= 2;
+ if ((info->buffer=
+ (byte*) my_malloc(buffer_block,
+ MYF((cache_myflags & ~ MY_WME) |
+ (cachesize == min_cache ? MY_WME : 0)))) != 0)
+ {
+ info->write_buffer=info->buffer;
+ if (type == SEQ_READ_APPEND)
+ info->write_buffer = info->buffer + cachesize;
+ info->alloced_buffer=1;
+ break; /* Enough memory found */
+ }
+ if (cachesize == min_cache)
+ DBUG_RETURN(2); /* Can't alloc cache */
+ cachesize= (uint) ((long) cachesize*3/4); /* Try with less memory */
+ }
}
- info->pos_in_file=seek_offset;
+
+ DBUG_PRINT("info",("init_io_cache: cachesize = %u",cachesize));
info->read_length=info->buffer_length=cachesize;
- info->seek_not_done= test(file >= 0); /* Seek not done */
info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
- info->rc_request_pos=info->rc_pos=info->buffer;
-
- if (type == READ_CACHE)
- {
- info->rc_end=info->buffer; /* Nothing in cache */
- }
- else /* type == WRITE_CACHE */
+ info->request_pos= info->read_pos= info->write_pos = info->buffer;
+ if (type == SEQ_READ_APPEND)
{
- info->rc_end=info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
+ info->append_read_pos = info->write_pos = info->write_buffer;
+ info->write_end = info->write_buffer + info->buffer_length;
+#ifdef THREAD
+ pthread_mutex_init(&info->append_buffer_lock,MY_MUTEX_INIT_FAST);
+#endif
}
- info->end_of_file=MY_FILEPOS_ERROR; /* May be changed by user */
- info->type=type;
+
+ if (type == WRITE_CACHE)
+ info->write_end=
+ info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
+ else
+ info->read_end=info->buffer; /* Nothing in cache */
+
+ /* End_of_file may be changed by user later */
+ info->end_of_file= end_of_file;
info->error=0;
- info->read_function=_my_b_read;
+ init_functions(info,type);
#ifdef HAVE_AIOWAIT
if (use_async_io && ! my_disable_async_io)
{
@@ -128,7 +223,6 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
DBUG_RETURN(0);
} /* init_io_cache */
-
/* Wait until current request is ready */
#ifdef HAVE_AIOWAIT
@@ -156,8 +250,13 @@ static void my_aiowait(my_aio_result *result)
}
#endif
- /* Use this to reset cache to start or other type */
- /* Some simple optimizing is done when reinit in current buffer */
+
+/*
+ Use this to reset cache to re-start reading or to change the type
+ between READ_CACHE <-> WRITE_CACHE
+ If we are doing a reinit of a cache where we have the start of the file
+ in the cache, we are reusing this memory without flushing it to disk.
+*/
my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
my_off_t seek_offset,
@@ -165,47 +264,71 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
pbool clear_cache)
{
DBUG_ENTER("reinit_io_cache");
+ DBUG_PRINT("enter",("type: %d seek_offset: %lu clear_cache: %d",
+ type, (ulong) seek_offset, (int) clear_cache));
+
+ /* One can't do reinit with the following types */
+ DBUG_ASSERT(type != READ_NET && info->type != READ_NET &&
+ type != WRITE_NET && info->type != WRITE_NET &&
+ type != SEQ_READ_APPEND && info->type != SEQ_READ_APPEND);
- info->seek_not_done= test(info->file >= 0); /* Seek not done */
+ /* If the whole file is in memory, avoid flushing to disk */
if (! clear_cache &&
seek_offset >= info->pos_in_file &&
- seek_offset <= info->pos_in_file +
- (uint) (info->rc_end - info->rc_request_pos))
- { /* use current buffer */
+ seek_offset <= my_b_tell(info))
+ {
+ /* Reuse current buffer without flushing it to disk */
+ byte *pos;
if (info->type == WRITE_CACHE && type == READ_CACHE)
{
- info->rc_end=info->rc_pos;
+ info->read_end=info->write_pos;
info->end_of_file=my_b_tell(info);
}
- else if (info->type == READ_CACHE && type == WRITE_CACHE)
- info->rc_end=info->buffer+info->buffer_length;
- info->rc_pos=info->rc_request_pos+(seek_offset-info->pos_in_file);
+ else if (type == WRITE_CACHE)
+ {
+ if (info->type == READ_CACHE)
+ info->write_end=info->write_buffer+info->buffer_length;
+ info->end_of_file = ~(my_off_t) 0;
+ }
+ pos=info->request_pos+(seek_offset-info->pos_in_file);
+ if (type == WRITE_CACHE)
+ info->write_pos=pos;
+ else
+ info->read_pos= pos;
#ifdef HAVE_AIOWAIT
my_aiowait(&info->aio_result); /* Wait for outstanding req */
#endif
}
else
{
+ /*
+ If we change from WRITE_CACHE to READ_CACHE, assume that everything
+ after the current positions should be ignored
+ */
if (info->type == WRITE_CACHE && type == READ_CACHE)
info->end_of_file=my_b_tell(info);
- if (flush_io_cache(info))
+ /* flush cache if we want to reuse it */
+ if (!clear_cache && flush_io_cache(info))
DBUG_RETURN(1);
info->pos_in_file=seek_offset;
- info->rc_request_pos=info->rc_pos=info->buffer;
+ /* Better to do always do a seek */
+ info->seek_not_done=1;
+ info->request_pos=info->read_pos=info->write_pos=info->buffer;
if (type == READ_CACHE)
{
- info->rc_end=info->buffer; /* Nothing in cache */
+ info->read_end=info->buffer; /* Nothing in cache */
}
else
{
- info->rc_end=info->buffer+info->buffer_length-
- (seek_offset & (IO_SIZE-1));
- info->end_of_file=MY_FILEPOS_ERROR; /* May be changed by user */
+ info->write_end=(info->buffer + info->buffer_length -
+ (seek_offset & (IO_SIZE-1)));
+ info->end_of_file= ~(my_off_t) 0;
}
}
info->type=type;
info->error=0;
- info->read_function=_my_b_read;
+ init_functions(info,type);
+
#ifdef HAVE_AIOWAIT
if (use_async_io && ! my_disable_async_io &&
((ulong) info->buffer_length <
@@ -217,23 +340,34 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
info->inited=0;
#endif
DBUG_RETURN(0);
-} /* init_io_cache */
+} /* reinit_io_cache */
- /* Read buffered. Returns 1 if can't read requested characters */
- /* Returns 0 if record read */
+/*
+ Read buffered. Returns 1 if can't read requested characters
+ This function is only called from the my_b_read() macro
+ when there isn't enough characters in the buffer to
+ satisfy the request.
+ Returns 0 we succeeded in reading all data
+*/
int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
uint length,diff_length,left_length;
my_off_t max_length, pos_in_file;
+ DBUG_ENTER("_my_b_read");
- memcpy(Buffer,info->rc_pos,
- (size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
- Buffer+=left_length;
- Count-=left_length;
- pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
+ if ((left_length=(uint) (info->read_end-info->read_pos)))
+ {
+ DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
+ memcpy(Buffer,info->read_pos, (size_t) (left_length));
+ Buffer+=left_length;
+ Count-=left_length;
+ }
+
+ /* pos_in_file always point on where info->buffer was read */
+ pos_in_file=info->pos_in_file+(uint) (info->read_end - info->buffer);
if (info->seek_not_done)
{ /* File touched, do seek */
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
@@ -246,7 +380,7 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
if (info->end_of_file == pos_in_file)
{ /* End of file */
info->error=(int) left_length;
- return 1;
+ DBUG_RETURN(1);
}
length=(Count & (uint) ~(IO_SIZE-1))-diff_length;
if ((read_length=my_read(info->file,Buffer,(uint) length,info->myflags))
@@ -254,7 +388,7 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
info->error= read_length == (uint) -1 ? -1 :
(int) (read_length+left_length);
- return 1;
+ DBUG_RETURN(1);
}
Count-=length;
Buffer+=length;
@@ -262,16 +396,17 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
left_length+=length;
diff_length=0;
}
- max_length=info->end_of_file - pos_in_file;
- if (max_length > info->read_length-diff_length)
- max_length=info->read_length-diff_length;
+ max_length=info->read_length-diff_length;
+ if (info->type != READ_FIFO &&
+ max_length > (info->end_of_file - pos_in_file))
+ max_length = info->end_of_file - pos_in_file;
if (!max_length)
{
if (Count)
{
info->error= left_length; /* We only got this many char */
- return 1;
+ DBUG_RETURN(1);
}
length=0; /* Didn't read any chars */
}
@@ -282,13 +417,292 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
if (length != (uint) -1)
memcpy(Buffer,info->buffer,(size_t) length);
info->error= length == (uint) -1 ? -1 : (int) (length+left_length);
+ info->read_pos=info->read_end=info->buffer;
+ DBUG_RETURN(1);
+ }
+ info->read_pos=info->buffer+Count;
+ info->read_end=info->buffer+length;
+ info->pos_in_file=pos_in_file;
+ memcpy(Buffer,info->buffer,(size_t) Count);
+ DBUG_RETURN(0);
+}
+
+#ifdef THREAD
+/* Prepare IO_CACHE for shared use */
+void init_io_cache_share(IO_CACHE *info, IO_CACHE_SHARE *s, uint num_threads)
+{
+ DBUG_ASSERT(info->type == READ_CACHE);
+ pthread_mutex_init(&s->mutex, MY_MUTEX_INIT_FAST);
+ pthread_cond_init (&s->cond, 0);
+ s->count=num_threads-1;
+ s->active=0; /* to catch errors */
+ info->share=s;
+ info->read_function=_my_b_read_r;
+}
+
+/*
+ Remove a thread from shared access to IO_CACHE
+ Every thread should do that on exit for not
+ to deadlock other threads
+*/
+void remove_io_thread(IO_CACHE *info)
+{
+ pthread_mutex_lock(&info->share->mutex);
+ if (! info->share->count--)
+ pthread_cond_signal(&info->share->cond);
+ pthread_mutex_unlock(&info->share->mutex);
+}
+
+static int lock_io_cache(IO_CACHE *info)
+{
+ pthread_mutex_lock(&info->share->mutex);
+ if (!info->share->count)
return 1;
+
+ --(info->share->count);
+ pthread_cond_wait(&info->share->cond, &info->share->mutex);
+ /*
+ count can be -1 here, if one thread was removed (remove_io_thread)
+ while all others were locked (lock_io_cache).
+ If this is the case, this thread behaves as if count was 0 from the
+ very beginning, that is returns 1 and does not unlock the mutex.
+ */
+ if (++(info->share->count))
+ {
+ pthread_mutex_unlock(&info->share->mutex);
+ return 0;
+ }
+ return 1;
+}
+
+static void unlock_io_cache(IO_CACHE *info)
+{
+ pthread_cond_broadcast(&info->share->cond);
+ pthread_mutex_unlock(&info->share->mutex);
+}
+
+
+/*
+ Read from IO_CACHE when it is shared between several threads.
+ It works as follows: when a thread tries to read from a file
+ (that is, after using all the data from the (shared) buffer),
+ it just hangs on lock_io_cache(), wating for other threads.
+ When the very last thread attempts a read, lock_io_cache()
+ returns 1, the thread does actual IO and unlock_io_cache(),
+ which signals all the waiting threads that data is in the buffer.
+*/
+
+int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
+{
+ my_off_t pos_in_file;
+ uint length,diff_length,read_len;
+ DBUG_ENTER("_my_b_read_r");
+
+ if ((read_len=(uint) (info->read_end-info->read_pos)))
+ {
+ DBUG_ASSERT(Count >= read_len); /* User is not using my_b_read() */
+ memcpy(Buffer,info->read_pos, (size_t) (read_len));
+ Buffer+=read_len;
+ Count-=read_len;
}
- info->rc_pos=info->buffer+Count;
- info->rc_end=info->buffer+length;
+ while (Count)
+ {
+ int cnt, len;
+
+ pos_in_file= info->pos_in_file + (uint)(info->read_end - info->buffer);
+ diff_length= (uint) (pos_in_file & (IO_SIZE-1));
+ length=IO_ROUND_UP(Count+diff_length)-diff_length;
+ length=(length <= info->read_length) ?
+ length + IO_ROUND_DN(info->read_length - length) :
+ length - IO_ROUND_UP(length - info->read_length) ;
+ if (info->type != READ_FIFO && (length > info->end_of_file - pos_in_file))
+ length=info->end_of_file - pos_in_file;
+ if (length == 0)
+ {
+ info->error=(int) read_len;
+ DBUG_RETURN(1);
+ }
+ if (lock_io_cache(info))
+ {
+ info->share->active=info;
+ if (info->seek_not_done) /* File touched, do seek */
+ VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
+ len=(int)my_read(info->file,info->buffer, length, info->myflags);
+ info->read_end=info->buffer + (len == -1 ? 0 : len);
+ info->error=(len == (int)length ? 0 : len);
+ info->pos_in_file=pos_in_file;
+ unlock_io_cache(info);
+ }
+ else
+ {
+ info->error= info->share->active->error;
+ info->read_end= info->share->active->read_end;
+ info->pos_in_file= info->share->active->pos_in_file;
+ len= (info->error == -1 ? -1 : info->read_end-info->buffer);
+ }
+ info->read_pos=info->buffer;
+ info->seek_not_done=0;
+ if (len <= 0)
+ {
+ info->error=(int) read_len;
+ DBUG_RETURN(1);
+ }
+ cnt=((uint) len > Count) ? (int) Count : len;
+ memcpy(Buffer,info->read_pos, (size_t)cnt);
+ Count -=cnt;
+ Buffer+=cnt;
+ read_len+=cnt;
+ info->read_pos+=cnt;
+ }
+ DBUG_RETURN(0);
+}
+#endif
+
+
+/*
+ Do sequential read from the SEQ_READ_APPEND cache
+ we do this in three stages:
+ - first read from info->buffer
+ - then if there are still data to read, try the file descriptor
+ - afterwards, if there are still data to read, try append buffer
+*/
+
+int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
+{
+ uint length,diff_length,left_length,save_count;
+ my_off_t max_length, pos_in_file;
+ save_count=Count;
+
+ /* first, read the regular buffer */
+ if ((left_length=(uint) (info->read_end-info->read_pos)))
+ {
+ DBUG_ASSERT(Count > left_length); /* User is not using my_b_read() */
+ memcpy(Buffer,info->read_pos, (size_t) (left_length));
+ Buffer+=left_length;
+ Count-=left_length;
+ }
+ lock_append_buffer(info);
+
+ /* pos_in_file always point on where info->buffer was read */
+ if ((pos_in_file=info->pos_in_file+(uint) (info->read_end - info->buffer)) >=
+ info->end_of_file)
+ goto read_append_buffer;
+
+ /*
+ With read-append cache we must always do a seek before we read,
+ because the write could have moved the file pointer astray
+ */
+ VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
+ info->seek_not_done=0;
+
+ diff_length=(uint) (pos_in_file & (IO_SIZE-1));
+
+ /* now the second stage begins - read from file descriptor */
+ if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length)))
+ { /* Fill first intern buffer */
+ uint read_length;
+
+ length=(Count & (uint) ~(IO_SIZE-1))-diff_length;
+ if ((read_length=my_read(info->file,Buffer,(uint) length,info->myflags)) ==
+ (uint)-1)
+ {
+ info->error= -1;
+ unlock_append_buffer(info);
+ return 1;
+ }
+ Count-=read_length;
+ Buffer+=read_length;
+ pos_in_file+=read_length;
+
+ if (read_length != (uint) length)
+ {
+ /*
+ We only got part of data; Read the rest of the data from the
+ write buffer
+ */
+ goto read_append_buffer;
+ }
+ left_length+=length;
+ diff_length=0;
+ }
+
+ max_length=info->read_length-diff_length;
+ if (max_length > (info->end_of_file - pos_in_file))
+ max_length = info->end_of_file - pos_in_file;
+ if (!max_length)
+ {
+ if (Count)
+ goto read_append_buffer;
+ length=0; /* Didn't read any more chars */
+ }
+ else
+ {
+ length=my_read(info->file,info->buffer,(uint) max_length,
+ info->myflags);
+ if (length == (uint) -1)
+ {
+ info->error= -1;
+ unlock_append_buffer(info);
+ return 1;
+ }
+ if (length < Count)
+ {
+ memcpy(Buffer,info->buffer,(size_t) length);
+ Count -= length;
+ Buffer += length;
+
+ /*
+ added the line below to make
+ DBUG_ASSERT(pos_in_file==info->end_of_file) pass.
+ otherwise this does not appear to be needed
+ */
+ pos_in_file += length;
+ goto read_append_buffer;
+ }
+ }
+ unlock_append_buffer(info);
+ info->read_pos=info->buffer+Count;
+ info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
memcpy(Buffer,info->buffer,(size_t) Count);
return 0;
+
+read_append_buffer:
+
+ /*
+ Read data from the current write buffer.
+ Count should never be == 0 here (The code will work even if count is 0)
+ */
+
+ {
+ /* First copy the data to Count */
+ uint len_in_buff = (uint) (info->write_pos - info->append_read_pos);
+ uint copy_len;
+ uint transfer_len;
+
+ DBUG_ASSERT(info->append_read_pos <= info->write_pos);
+ /*
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+ copy_len=min(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+ if (Count)
+ info->error = save_count - Count;
+
+ /* Fill read buffer with data from write buffer */
+ memcpy(info->buffer, info->append_read_pos,
+ (size_t) (transfer_len=len_in_buff - copy_len));
+ info->read_pos= info->buffer;
+ info->read_end= info->buffer+transfer_len;
+ info->append_read_pos=info->write_pos;
+ info->pos_in_file=pos_in_file+copy_len;
+ info->end_of_file+=len_in_buff;
+ }
+ unlock_append_buffer(info);
+ return Count ? 1 : 0;
}
@@ -301,8 +715,8 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
my_off_t next_pos_in_file;
byte *read_buffer;
- memcpy(Buffer,info->rc_pos,
- (size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
+ memcpy(Buffer,info->read_pos,
+ (size_t) (left_length=(uint) (info->read_end-info->read_pos)));
Buffer+=left_length;
org_Count=Count;
Count-=left_length;
@@ -329,13 +743,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
(int) (read_length+left_length));
return(1);
}
- info->pos_in_file+=(uint) (info->rc_end - info->rc_request_pos);
+ info->pos_in_file+=(uint) (info->read_end - info->request_pos);
- if (info->rc_request_pos != info->buffer)
- info->rc_request_pos=info->buffer;
+ if (info->request_pos != info->buffer)
+ info->request_pos=info->buffer;
else
- info->rc_request_pos=info->buffer+info->read_length;
- info->rc_pos=info->rc_request_pos;
+ info->request_pos=info->buffer+info->read_length;
+ info->read_pos=info->request_pos;
next_pos_in_file=info->aio_read_pos+read_length;
/* Check if pos_in_file is changed
@@ -352,8 +766,8 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
my_off_t offset= (info->pos_in_file - info->aio_read_pos);
info->pos_in_file=info->aio_read_pos; /* Whe are here */
- info->rc_pos=info->rc_request_pos+offset;
- read_length-=offset; /* Bytes left from rc_pos */
+ info->read_pos=info->request_pos+offset;
+ read_length-=offset; /* Bytes left from read_pos */
}
}
#ifndef DBUG_OFF
@@ -365,16 +779,16 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
#endif
/* Copy found bytes to buffer */
length=min(Count,read_length);
- memcpy(Buffer,info->rc_pos,(size_t) length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
Buffer+=length;
Count-=length;
left_length+=length;
- info->rc_end=info->rc_pos+read_length;
- info->rc_pos+=length;
+ info->read_end=info->rc_pos+read_length;
+ info->read_pos+=length;
}
else
next_pos_in_file=(info->pos_in_file+ (uint)
- (info->rc_end - info->rc_request_pos));
+ (info->read_end - info->request_pos));
/* If reading large blocks, or first read or read with skipp */
if (Count)
@@ -388,13 +802,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
read_length=IO_SIZE*2- (uint) (next_pos_in_file & (IO_SIZE-1));
if (Count < read_length)
{ /* Small block, read to cache */
- if ((read_length=my_read(info->file,info->rc_request_pos,
+ if ((read_length=my_read(info->file,info->request_pos,
read_length, info->myflags)) == (uint) -1)
return info->error= -1;
use_length=min(Count,read_length);
- memcpy(Buffer,info->rc_request_pos,(size_t) use_length);
- info->rc_pos=info->rc_request_pos+Count;
- info->rc_end=info->rc_request_pos+read_length;
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
info->pos_in_file=next_pos_in_file; /* Start of block in cache */
next_pos_in_file+=read_length;
@@ -415,7 +829,7 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
info->error= read_length == (uint) -1 ? -1 : read_length+left_length;
return 1;
}
- info->rc_pos=info->rc_end=info->rc_request_pos;
+ info->read_pos=info->read_end=info->request_pos;
info->pos_in_file=(next_pos_in_file+=Count);
}
}
@@ -426,7 +840,7 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
if (max_length > (my_off_t) info->read_length - diff_length)
max_length= (my_off_t) info->read_length - diff_length;
- if (info->rc_request_pos != info->buffer)
+ if (info->request_pos != info->buffer)
read_buffer=info->buffer;
else
read_buffer=info->buffer+info->read_length;
@@ -443,13 +857,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
my_errno=errno;
DBUG_PRINT("error",("got error: %d, aio_result: %d from aioread, async skipped",
errno, info->aio_result.result.aio_errno));
- if (info->rc_request_pos != info->buffer)
+ if (info->request_pos != info->buffer)
{
- bmove(info->buffer,info->rc_request_pos,
- (uint) (info->rc_end - info->rc_pos));
- info->rc_request_pos=info->buffer;
- info->rc_pos-=info->read_length;
- info->rc_end-=info->read_length;
+ bmove(info->buffer,info->request_pos,
+ (uint) (info->read_end - info->read_pos));
+ info->request_pos=info->buffer;
+ info->read_pos-=info->read_length;
+ info->read_end-=info->read_length;
}
info->read_length=info->buffer_length; /* Use hole buffer */
info->read_function=_my_b_read; /* Use normal IO_READ next */
@@ -467,8 +881,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
int _my_b_get(IO_CACHE *info)
{
byte buff;
+ IO_CACHE_CALLBACK pre_read,post_read;
+ if ((pre_read = info->pre_read))
+ (*pre_read)(info);
if ((*(info)->read_function)(info,&buff,1))
return my_b_EOF;
+ if ((post_read = info->post_read))
+ (*post_read)(info);
return (int) (uchar) buff;
}
@@ -478,11 +897,17 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
{
uint rest_length,length;
- rest_length=(uint) (info->rc_end - info->rc_pos);
- memcpy(info->rc_pos,Buffer,(size_t) rest_length);
+ if (info->pos_in_file+info->buffer_length > info->end_of_file)
+ {
+ my_errno=errno=EFBIG;
+ return info->error = -1;
+ }
+
+ rest_length=(uint) (info->write_end - info->write_pos);
+ memcpy(info->write_pos,Buffer,(size_t) rest_length);
Buffer+=rest_length;
Count-=rest_length;
- info->rc_pos+=rest_length;
+ info->write_pos+=rest_length;
if (flush_io_cache(info))
return 1;
if (Count >= IO_SIZE)
@@ -499,8 +924,52 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
Buffer+=length;
info->pos_in_file+=length;
}
- memcpy(info->rc_pos,Buffer,(size_t) Count);
- info->rc_pos+=Count;
+ memcpy(info->write_pos,Buffer,(size_t) Count);
+ info->write_pos+=Count;
+ return 0;
+}
+
+
+/*
+ Append a block to the write buffer.
+ This is done with the buffer locked to ensure that we don't read from
+ the write buffer before we are ready with it.
+*/
+
+int my_b_append(register IO_CACHE *info, const byte *Buffer, uint Count)
+{
+ uint rest_length,length;
+
+ lock_append_buffer(info);
+ rest_length=(uint) (info->write_end - info->write_pos);
+ if (Count <= rest_length)
+ goto end;
+ memcpy(info->write_pos,Buffer,(size_t) rest_length);
+ Buffer+=rest_length;
+ Count-=rest_length;
+ info->write_pos+=rest_length;
+ if (_flush_io_cache(info,0))
+ {
+ unlock_append_buffer(info);
+ return 1;
+ }
+ if (Count >= IO_SIZE)
+ { /* Fill first intern buffer */
+ length=Count & (uint) ~(IO_SIZE-1);
+ if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
+ {
+ unlock_append_buffer(info);
+ return info->error= -1;
+ }
+ Count-=length;
+ Buffer+=length;
+ info->end_of_file+=length;
+ }
+
+end:
+ memcpy(info->write_pos,Buffer,(size_t) Count);
+ info->write_pos+=Count;
+ unlock_append_buffer(info);
return 0;
}
@@ -530,10 +999,13 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
Buffer+=length;
pos+= length;
Count-= length;
+#ifndef HAVE_PREAD
+ info->seek_not_done=1;
+#endif
}
/* Check if we want to write inside the used part of the buffer.*/
- length= (uint) (info->rc_end - info->buffer);
+ length= (uint) (info->write_end - info->buffer);
if (pos < info->pos_in_file + length)
{
uint offset= (uint) (pos - info->pos_in_file);
@@ -544,8 +1016,8 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
Buffer+=length;
Count-= length;
/* Fix length of buffer if the new data was larger */
- if (info->buffer+length > info->rc_pos)
- info->rc_pos=info->buffer+length;
+ if (info->buffer+length > info->write_pos)
+ info->write_pos=info->buffer+length;
if (!Count)
return (error);
}
@@ -555,46 +1027,90 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
return error;
}
+
/* Flush write cache */
-int flush_io_cache(IO_CACHE *info)
+#ifdef THREAD
+#define LOCK_APPEND_BUFFER if (need_append_buffer_lock) \
+ lock_append_buffer(info);
+#define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \
+ unlock_append_buffer(info);
+#else
+#define LOCK_APPEND_BUFFER
+#define UNLOCK_APPEND_BUFFER
+#endif
+
+
+int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
{
uint length;
- DBUG_ENTER("flush_io_cache");
+ my_bool append_cache;
+ my_off_t pos_in_file;
+ DBUG_ENTER("_flush_io_cache");
+
+ if (!(append_cache = (info->type == SEQ_READ_APPEND)))
+ need_append_buffer_lock=0;
- if (info->type == WRITE_CACHE)
+ if (info->type == WRITE_CACHE || append_cache)
{
if (info->file == -1)
{
if (real_open_cached_file(info))
DBUG_RETURN((info->error= -1));
}
- if (info->rc_pos != info->buffer)
+ LOCK_APPEND_BUFFER;
+
+ if ((length=(uint) (info->write_pos - info->write_buffer)))
{
- length=(uint) (info->rc_pos - info->buffer);
- if (info->seek_not_done)
+ pos_in_file=info->pos_in_file;
+ /*
+ If we have append cache, we always open the file with
+ O_APPEND which moves the pos to EOF automatically on every write
+ */
+ if (!append_cache && info->seek_not_done)
{ /* File touched, do seek */
- if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
+ if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
+ {
+ UNLOCK_APPEND_BUFFER;
DBUG_RETURN((info->error= -1));
- info->seek_not_done=0;
+ }
+ if (!append_cache)
+ info->seek_not_done=0;
}
- info->rc_pos=info->buffer;
- info->pos_in_file+=length;
- info->rc_end=(info->buffer+info->buffer_length-
- (info->pos_in_file & (IO_SIZE-1)));
- if (my_write(info->file,info->buffer,length,info->myflags | MY_NABP))
- DBUG_RETURN((info->error= -1));
- DBUG_RETURN(0);
+ if (!append_cache)
+ info->pos_in_file+=length;
+ info->write_end= (info->write_buffer+info->buffer_length-
+ ((pos_in_file+length) & (IO_SIZE-1)));
+
+ if (my_write(info->file,info->write_buffer,length,
+ info->myflags | MY_NABP))
+ info->error= -1;
+ else
+ info->error= 0;
+ if (!append_cache)
+ {
+ set_if_bigger(info->end_of_file,(pos_in_file+length));
+ }
+ else
+ {
+ info->end_of_file+=(info->write_pos-info->append_read_pos);
+ DBUG_ASSERT(info->end_of_file == my_tell(info->file,MYF(0)));
+ }
+
+ info->append_read_pos=info->write_pos=info->write_buffer;
+ UNLOCK_APPEND_BUFFER;
+ DBUG_RETURN(info->error);
}
}
#ifdef HAVE_AIOWAIT
- else
+ else if (info->type != READ_NET)
{
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
+ my_aiowait(&info->aio_result); /* Wait for outstanding req */
info->inited=0;
}
#endif
+ UNLOCK_APPEND_BUFFER;
DBUG_RETURN(0);
}
@@ -602,13 +1118,136 @@ int flush_io_cache(IO_CACHE *info)
int end_io_cache(IO_CACHE *info)
{
int error=0;
+ IO_CACHE_CALLBACK pre_close;
DBUG_ENTER("end_io_cache");
- if (info->buffer)
+
+#ifdef THREAD
+ if (info->share)
+ {
+#ifdef SAFE_MUTEX
+ /* simple protection against multi-close: destroying share first */
+ if (pthread_cond_destroy (&info->share->cond) |
+ pthread_mutex_destroy(&info->share->mutex))
+ {
+ DBUG_RETURN(1);
+ }
+#else
+ pthread_cond_destroy (&info->share->cond);
+ pthread_mutex_destroy(&info->share->mutex);
+#endif
+ info->share=0;
+ }
+#endif
+
+ if ((pre_close=info->pre_close))
+ (*pre_close)(info);
+ if (info->alloced_buffer)
{
+ info->alloced_buffer=0;
if (info->file != -1) /* File doesn't exist */
error=flush_io_cache(info);
my_free((gptr) info->buffer,MYF(MY_WME));
- info->buffer=info->rc_pos=(byte*) 0;
+ info->buffer=info->read_pos=(byte*) 0;
+ }
+ if (info->type == SEQ_READ_APPEND)
+ {
+ /* Destroy allocated mutex */
+ info->type=0;
+#ifdef THREAD
+ pthread_mutex_destroy(&info->append_buffer_lock);
+#endif
}
DBUG_RETURN(error);
} /* end_io_cache */
+
+
+/**********************************************************************
+ Testing of MF_IOCACHE
+**********************************************************************/
+
+#ifdef MAIN
+
+#include <my_dir.h>
+
+void die(const char* fmt, ...)
+{
+ va_list va_args;
+ va_start(va_args,fmt);
+ fprintf(stderr,"Error:");
+ vfprintf(stderr, fmt,va_args);
+ fprintf(stderr,", errno=%d\n", errno);
+ exit(1);
+}
+
+int open_file(const char* fname, IO_CACHE* info, int cache_size)
+{
+ int fd;
+ if ((fd=my_open(fname,O_CREAT | O_RDWR,MYF(MY_WME))) < 0)
+ die("Could not open %s", fname);
+ if (init_io_cache(info, fd, cache_size, SEQ_READ_APPEND, 0,0,MYF(MY_WME)))
+ die("failed in init_io_cache()");
+ return fd;
+}
+
+void close_file(IO_CACHE* info)
+{
+ end_io_cache(info);
+ my_close(info->file, MYF(MY_WME));
+}
+
+int main(int argc, char** argv)
+{
+ IO_CACHE sra_cache; /* SEQ_READ_APPEND */
+ MY_STAT status;
+ const char* fname="/tmp/iocache.test";
+ int cache_size=16384;
+ char llstr_buf[22];
+ int max_block,total_bytes=0;
+ int i,num_loops=100,error=0;
+ char *p;
+ char* block, *block_end;
+ MY_INIT(argv[0]);
+ max_block = cache_size*3;
+ if (!(block=(char*)my_malloc(max_block,MYF(MY_WME))))
+ die("Not enough memory to allocate test block");
+ block_end = block + max_block;
+ for (p = block,i=0; p < block_end;i++)
+ {
+ *p++ = (char)i;
+ }
+ if (my_stat(fname,&status, MYF(0)) &&
+ my_delete(fname,MYF(MY_WME)))
+ {
+ die("Delete of %s failed, aborting", fname);
+ }
+ open_file(fname,&sra_cache, cache_size);
+ for (i = 0; i < num_loops; i++)
+ {
+ char buf[4];
+ int block_size = abs(rand() % max_block);
+ int4store(buf, block_size);
+ if (my_b_append(&sra_cache,buf,4) ||
+ my_b_append(&sra_cache, block, block_size))
+ die("write failed");
+ total_bytes += 4+block_size;
+ }
+ close_file(&sra_cache);
+ my_free(block,MYF(MY_WME));
+ if (!my_stat(fname,&status,MYF(MY_WME)))
+ die("%s failed to stat, but I had just closed it,\
+ wonder how that happened");
+ printf("Final size of %s is %s, wrote %d bytes\n",fname,
+ llstr(status.st_size,llstr_buf),
+ total_bytes);
+ my_delete(fname, MYF(MY_WME));
+ /* check correctness of tests */
+ if (total_bytes != status.st_size)
+ {
+ fprintf(stderr,"Not the same number of bytes acutally in file as bytes \
+supposedly written\n");
+ error=1;
+ }
+ exit(error);
+ return 0;
+}
+#endif
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 3e9cc74e0a2..b19ca391672 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
More functions to be used with IO_CACHE files
@@ -24,58 +23,118 @@
#include <m_string.h>
#include <stdarg.h>
#include <m_ctype.h>
+#include <assert.h>
+
+my_off_t my_b_append_tell(IO_CACHE* info)
+{
+ /*
+ Prevent optimizer from putting res in a register when debugging
+ we need this to be able to see the value of res when the assert fails
+ */
+ dbug_volatile my_off_t res;
+
+ /*
+ We need to lock the append buffer mutex to keep flush_io_cache()
+ from messing with the variables that we need in order to provide the
+ answer to the question.
+ */
+#ifdef THREAD
+ pthread_mutex_lock(&info->append_buffer_lock);
+#endif
+#ifndef DBUG_OFF
+ /*
+ Make sure EOF is where we think it is. Note that we cannot just use
+ my_tell() because we have a reader thread that could have left the
+ file offset in a non-EOF location
+ */
+ {
+ volatile my_off_t save_pos;
+ save_pos = my_tell(info->file,MYF(0));
+ my_seek(info->file,(my_off_t)0,MY_SEEK_END,MYF(0));
+ /*
+ Save the value of my_tell in res so we can see it when studying coredump
+ */
+ DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
+ == (res=my_tell(info->file,MYF(0))));
+ my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
+ }
+#endif
+ res = info->end_of_file + (info->write_pos-info->append_read_pos);
+#ifdef THREAD
+ pthread_mutex_unlock(&info->append_buffer_lock);
+#endif
+ return res;
+}
/*
-** Fix that next read will be made at certain position
-** For write cache, make next write happen at a certain position
+ Make next read happen at the given position
+ For write cache, make next write happen at the given position
*/
void my_b_seek(IO_CACHE *info,my_off_t pos)
{
- my_off_t offset = (pos - info->pos_in_file);
+ my_off_t offset;
DBUG_ENTER("my_b_seek");
DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
- if (info->type == READ_CACHE)
+ /*
+ TODO:
+ Verify that it is OK to do seek in the non-append
+ area in SEQ_READ_APPEND cache
+ a) see if this always works
+ b) see if there is a better way to make it work
+ */
+ if (info->type == SEQ_READ_APPEND)
+ flush_io_cache(info);
+
+ offset=(pos - info->pos_in_file);
+
+ if (info->type == READ_CACHE || info->type == SEQ_READ_APPEND)
{
- if ((ulonglong) offset < (ulonglong) (info->rc_end - info->buffer))
+ /* TODO: explain why this works if pos < info->pos_in_file */
+ if ((ulonglong) offset < (ulonglong) (info->read_end - info->buffer))
{
/* The read is in the current buffer; Reuse it */
- info->rc_pos = info->buffer + offset;
+ info->read_pos = info->buffer + offset;
DBUG_VOID_RETURN;
}
else
{
/* Force a new read on next my_b_read */
- info->rc_pos=info->rc_end=info->buffer;
+ info->read_pos=info->read_end=info->buffer;
}
}
else if (info->type == WRITE_CACHE)
{
/* If write is in current buffer, reuse it */
if ((ulonglong) offset <
- (ulonglong) (info->rc_end - info->buffer))
+ (ulonglong) (info->write_end - info->write_buffer))
{
- info->rc_pos = info->buffer + offset;
+ info->write_pos = info->write_buffer + offset;
DBUG_VOID_RETURN;
}
flush_io_cache(info);
- info->rc_end=(info->buffer+info->buffer_length-(pos & (IO_SIZE-1)));
+ /* Correct buffer end so that we write in increments of IO_SIZE */
+ info->write_end=(info->write_buffer+info->buffer_length-
+ (pos & (IO_SIZE-1)));
}
info->pos_in_file=pos;
info->seek_not_done=1;
+ DBUG_VOID_RETURN;
}
+
/*
-** Fill buffer. Note that this assumes that you have already used
-** all characters in the CACHE, independent of the rc_pos value!
-** return: 0 on error or EOF (info->error = -1 on error)
-** number of characters
+ Fill buffer. Note that this assumes that you have already used
+ all characters in the CACHE, independent of the read_pos value!
+ return: 0 on error or EOF (info->error = -1 on error)
+ number of characters
*/
uint my_b_fill(IO_CACHE *info)
{
- my_off_t pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
+ my_off_t pos_in_file=(info->pos_in_file+
+ (uint) (info->read_end - info->buffer));
my_off_t max_length;
uint diff_length,length;
if (info->seek_not_done)
@@ -103,16 +162,18 @@ uint my_b_fill(IO_CACHE *info)
info->error= -1;
return 0;
}
- info->rc_pos=info->buffer;
- info->rc_end=info->buffer+length;
+ info->read_pos=info->buffer;
+ info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
return length;
}
+
/*
-** Read a string ended by '\n' into a buffer of 'max_length' size.
-** Returns number of characters read, 0 on error.
-** last byte is set to '\0'
+ Read a string ended by '\n' into a buffer of 'max_length' size.
+ Returns number of characters read, 0 on error.
+ last byte is set to '\0'
+ If buffer is full then to[max_length-1] will be set to \0.
*/
uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
@@ -129,11 +190,11 @@ uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
char *pos,*end;
if (length > max_length)
length=max_length;
- for (pos=info->rc_pos,end=pos+length ; pos < end ;)
+ for (pos=info->read_pos,end=pos+length ; pos < end ;)
{
if ((*to++ = *pos++) == '\n')
{
- info->rc_pos=pos;
+ info->read_pos=pos;
*to='\0';
return (uint) (to-start);
}
@@ -141,7 +202,7 @@ uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
if (!(max_length-=length))
{
/* Found enough charcters; Return found string */
- info->rc_pos=pos;
+ info->read_pos=pos;
*to='\0';
return (uint) (to-start);
}
@@ -150,6 +211,7 @@ uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
}
}
+
/*
Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
Used for logging in MySQL
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 5b8ec96b4d1..5a573bff0f7 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
This functions is handle keyblock cacheing for NISAM, MISAM and PISAM
@@ -53,17 +52,19 @@ typedef struct sec_link {
} SEC_LINK;
-static uint find_next_bigger_power(uint value);
static SEC_LINK *find_key_block(int file,my_off_t filepos,int *error);
+static int flush_all_key_blocks();
/* static variables in this file */
static SEC_LINK *_my_block_root,**_my_hash_root,
*_my_used_first,*_my_used_last;
static int _my_disk_blocks;
static uint _my_disk_blocks_used, _my_hash_blocks;
+static uint key_cache_shift;
ulong _my_blocks_used,_my_blocks_changed;
ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests,
_my_cache_read;
+uint key_cache_block_size=DEFAULT_KEYCACHE_BLOCK_SIZE;
static byte HUGE_PTR *_my_block_mem;
static SEC_LINK *changed_blocks[CHANGED_BLOCKS_HASH];
static SEC_LINK *file_blocks[CHANGED_BLOCKS_HASH];
@@ -76,11 +77,9 @@ static my_bool _my_printed;
/* Returns blocks in use */
/* ARGSUSED */
-int init_key_cache(ulong use_mem,
- ulong leave_this_much_mem __attribute__((unused)))
+int init_key_cache(ulong use_mem)
{
uint blocks,length;
- byte *extra_mem=0;
DBUG_ENTER("init_key_cache");
if (key_cache_inited && _my_disk_blocks > 0)
@@ -92,28 +91,30 @@ int init_key_cache(ulong use_mem,
{
key_cache_inited=TRUE;
_my_disk_blocks= -1;
+ key_cache_shift=my_bit_log2(key_cache_block_size);
+ DBUG_PRINT("info",("key_cache_block_size: %u key_cache_shift: %u",
+ key_cache_block_size, key_cache_shift));
#ifndef DBUG_OFF
_my_printed=0;
#endif
}
- blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+KEYCACHE_BLOCK_SIZE));
+ blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+
+ key_cache_block_size));
/* No use to have very few blocks */
if (blocks >= 8 && _my_disk_blocks < 0)
{
-#if !defined(HAVE_ALLOCA) && !defined(THREAD)
- if ((extra_mem=my_malloc((uint) leave_this_much_mem,MYF(0))) == 0)
- goto err;
-#endif
for (;;)
{
- if ((_my_hash_blocks=find_next_bigger_power((uint) blocks)) < blocks*5/4)
- _my_hash_blocks<<=1;
+ /* Set my_hash_blocks to the next bigger 2 power */
+ _my_hash_blocks=(uint) 1 << (my_bit_log2(blocks*5/4)+1);
while ((length=(uint) blocks*sizeof(SEC_LINK)+
- sizeof(SEC_LINK*)*_my_hash_blocks)+(ulong) blocks*KEYCACHE_BLOCK_SIZE >
+ sizeof(SEC_LINK*)*_my_hash_blocks)+
+ ((ulong) blocks << key_cache_shift) >
use_mem)
blocks--;
- if ((_my_block_mem=my_malloc_lock((ulong) blocks * KEYCACHE_BLOCK_SIZE,MYF(0))))
+ if ((_my_block_mem=my_malloc_lock((ulong) blocks << key_cache_shift,
+ MYF(0))))
{
if ((_my_block_root=(SEC_LINK*) my_malloc((uint) length,MYF(0))) != 0)
break;
@@ -132,21 +133,48 @@ int init_key_cache(ulong use_mem,
DBUG_PRINT("exit",("disk_blocks: %d block_root: %lx _my_hash_blocks: %d hash_root: %lx",
_my_disk_blocks,_my_block_root,_my_hash_blocks,
_my_hash_root));
-#if !defined(HAVE_ALLOCA) && !defined(THREAD)
- my_free(extra_mem,MYF(0));
-#endif
}
bzero((gptr) changed_blocks,sizeof(changed_blocks[0])*CHANGED_BLOCKS_HASH);
bzero((gptr) file_blocks,sizeof(file_blocks[0])*CHANGED_BLOCKS_HASH);
DBUG_RETURN((int) blocks);
+
err:
- if (extra_mem) /* purecov: inspected */
- my_free(extra_mem,MYF(0));
my_errno=ENOMEM;
DBUG_RETURN(0);
} /* init_key_cache */
+/*
+ Resize the key cache
+
+ SYNOPSIS
+ resize_key_cache()
+ use_mem Bytes to use for new key cache
+
+ RETURN VALUES
+ 0 Error
+ # number of blocks in key cache
+*/
+
+
+int resize_key_cache(ulong use_mem)
+{
+ int block;
+ pthread_mutex_lock(&THR_LOCK_keycache);
+ if (flush_all_key_blocks())
+ {
+ /* TODO: If this happens, we should write a warning in the log file ! */
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return 0;
+ }
+ end_key_cache();
+ /* The following will work even if memory is 0 */
+ block=init_key_cache(use_mem);
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return block;
+}
+
+
/* Remove key_cache from memory */
void end_key_cache(void)
@@ -162,6 +190,7 @@ void end_key_cache(void)
}
}
key_cache_inited=0;
+ _my_hash_blocks=_my_blocks_used=0;
DBUG_PRINT("status",
("used: %d changed: %d w_requests: %ld writes: %ld r_requests: %ld reads: %ld",
_my_blocks_used,_my_blocks_changed,_my_cache_w_requests,
@@ -170,17 +199,6 @@ void end_key_cache(void)
} /* end_key_cache */
-static uint find_next_bigger_power(uint value)
-{
- uint old_value=1;
- while (value)
- {
- old_value=value;
- value&= value-1;
- }
- return (old_value << 1);
-}
-
static inline void link_into_file_blocks(SEC_LINK *next, int file)
{
reg1 SEC_LINK **ptr= &file_blocks[(uint) file & CHANGED_BLOCKS_MASK];
@@ -243,7 +261,7 @@ static void test_key_cache(const char *where, my_bool lock);
/*
** read a key_buffer
- ** filepos must point at a even KEYCACHE_BLOCK_SIZE block
+ ** filepos must point at a even key_cache_block_size block
** if return_buffer is set then the intern buffer is returned if
** it can be used
** Returns adress to where data is read
@@ -255,9 +273,12 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
{
reg1 SEC_LINK *next;
int error=0;
+ DBUG_ENTER("key_cache_read");
+ DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
+ (uint) file, (ulong) filepos, length));
#ifndef THREAD
- if (block_length > KEYCACHE_BLOCK_SIZE)
+ if (block_length > key_cache_block_size)
return_buffer=0;
#endif
if (_my_disk_blocks > 0)
@@ -265,21 +286,27 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
byte *start=buff;
uint read_length;
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* Resize failed */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto no_key_cache;
+ }
do
{
_my_cache_r_requests++;
- read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length;
+ read_length= (length > key_cache_block_size ? key_cache_block_size :
+ length);
if (!(next=find_key_block(file,filepos,&error)))
{
pthread_mutex_unlock(&THR_LOCK_keycache);
- return (byte*) 0; /* Got a fatal error */
+ DBUG_RETURN ((byte*) 0); /* Got a fatal error */
}
if (error)
{ /* Didn't find it in cache */
if (my_pread(file,next->buffer,read_length,filepos,MYF(MY_NABP)))
{
pthread_mutex_unlock(&THR_LOCK_keycache);
- return((byte*) 0);
+ DBUG_RETURN((byte*) 0);
}
_my_cache_read++;
}
@@ -287,7 +314,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
if (return_buffer)
{
pthread_mutex_unlock(&THR_LOCK_keycache);
- return (next->buffer);
+ DBUG_RETURN (next->buffer);
}
#endif
if (! (read_length & 511))
@@ -298,19 +325,21 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
filepos+=read_length;
} while ((length-= read_length));
pthread_mutex_unlock(&THR_LOCK_keycache);
- return(start);
+ DBUG_RETURN(start);
}
+
+no_key_cache:
_my_cache_r_requests++;
_my_cache_read++;
if (my_pread(file,(byte*) buff,length,filepos,MYF(MY_NABP)))
error=1;
- return (error ? (byte*) 0 : buff);
+ DBUG_RETURN(error ? (byte*) 0 : buff);
} /* key_cache_read */
/* write a key_buffer */
/* We don't have to use pwrite because of write locking */
- /* buff must point at a even KEYCACHE_BLOCK_SIZE block */
+ /* buff must point at a even key_cache_block_size block */
int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
uint block_length __attribute__((unused)),
@@ -318,12 +347,15 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
{
reg1 SEC_LINK *next;
int error=0;
+ DBUG_ENTER("key_cache_write");
+ DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
+ (uint) file, (ulong) filepos, length));
if (!dont_write)
{ /* Forced write of buffer */
_my_cache_write++;
if (my_pwrite(file,buff,length,filepos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
- return(1);
+ DBUG_RETURN(1);
}
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
@@ -333,10 +365,16 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
{ /* We have key_cacheing */
uint read_length;
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* If resize failed */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto no_key_cache;
+ }
+
_my_cache_w_requests++;
do
{
- read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length;
+ read_length= length > key_cache_block_size ? key_cache_block_size : length;
if (!(next=find_key_block(file,filepos,&error)))
goto end; /* Fatal error */
if (!dont_write) /* If we wrote buff at start */
@@ -356,8 +394,11 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
} while ((length-= read_length));
error=0;
pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto end;
}
- else if (dont_write)
+
+no_key_cache:
+ if (dont_write)
{ /* We must write, no cache */
_my_cache_w_requests++;
_my_cache_write++;
@@ -365,11 +406,12 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
error=1;
}
+
end:
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache",test_key_cache("end of key_cache_write",1););
#endif
- return(error);
+ DBUG_RETURN(error);
} /* key_cache_write */
@@ -379,13 +421,16 @@ end:
static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
{
reg1 SEC_LINK *next,**start;
+ DBUG_ENTER("find_key_block");
+ DBUG_PRINT("enter", ("file %u, filepos %lu",
+ (uint) file, (ulong) filepos));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("start of find_key_block",0););
#endif
*error=0;
- next= *(start= &_my_hash_root[((ulong) (filepos/KEYCACHE_BLOCK_SIZE)+(ulong) file) &
+ next= *(start= &_my_hash_root[((ulong) (filepos >> key_cache_shift)+(ulong) file) &
(_my_hash_blocks-1)]);
while (next && (next->diskpos != filepos || next->file != file))
next= next->next_hash;
@@ -411,7 +456,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
{ /* There are unused blocks */
next= &_my_block_root[_my_blocks_used++]; /* Link in hash-chain */
next->buffer=ADD_TO_PTR(_my_block_mem,
- (ulong) _my_disk_blocks_used*KEYCACHE_BLOCK_SIZE,byte*);
+ ((ulong) _my_disk_blocks_used << key_cache_shift),
+ byte*);
/* link first in file_blocks */
next->changed=0;
link_into_file_blocks(next,file);
@@ -426,7 +472,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
next= _my_used_first;
if (next->changed)
{
- if (my_pwrite(next->file,next->buffer,KEYCACHE_BLOCK_SIZE,next->diskpos,
+ if (my_pwrite(next->file,next->buffer,key_cache_block_size,
+ next->diskpos,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
{
*error=1;
@@ -461,7 +508,7 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0););
#endif
- return next;
+ DBUG_RETURN(next);
} /* find_key_block */
@@ -499,13 +546,15 @@ static int cmp_sec_link(SEC_LINK **a, SEC_LINK **b)
((*a)->diskpos > (*b)->diskpos) ? 1 : 0);
}
+
static int flush_cached_blocks(File file, SEC_LINK **cache, uint count)
{
uint last_errno=0;
qsort((byte*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link);
for ( ; count-- ; cache++)
{
- if (my_pwrite(file,(*cache)->buffer,KEYCACHE_BLOCK_SIZE,(*cache)->diskpos,
+ if (my_pwrite(file,(*cache)->buffer,key_cache_block_size,
+ (*cache)->diskpos,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
{
if (!last_errno)
@@ -516,25 +565,23 @@ static int flush_cached_blocks(File file, SEC_LINK **cache, uint count)
}
-int flush_key_blocks(File file, enum flush_type type)
+static int flush_key_blocks_int(File file, enum flush_type type)
{
int error=0,last_errno=0;
uint count=0;
SEC_LINK *cache_buff[FLUSH_CACHE],**cache,**pos,**end;
SEC_LINK *used,*next;
- DBUG_ENTER("flush_key_blocks");
+ DBUG_ENTER("flush_key_blocks_int");
DBUG_PRINT("enter",("file: %d blocks_used: %d blocks_changed: %d",
file,_my_blocks_used,_my_blocks_changed));
- pthread_mutex_lock(&THR_LOCK_keycache);
-
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("check_keycache",test_key_cache("start of flush_key_blocks",0););
-#endif
cache=cache_buff; /* If no key cache */
if (_my_disk_blocks > 0 &&
(!my_disable_flush_key_blocks || type != FLUSH_KEEP))
{
+#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
+ DBUG_EXECUTE("check_keycache",test_key_cache("start of flush_key_blocks",0););
+#endif
if (type != FLUSH_IGNORE_CHANGED)
{
/* Count how many key blocks we have to cache to be able to
@@ -605,22 +652,69 @@ int flush_key_blocks(File file, enum flush_type type)
free_block(used);
}
}
- }
#ifndef DBUG_OFF
- DBUG_EXECUTE("check_keycache",test_key_cache("end of flush_key_blocks",0););
+ DBUG_EXECUTE("check_keycache",test_key_cache("end of flush_key_blocks",0););
#endif
- pthread_mutex_unlock(&THR_LOCK_keycache);
+ }
if (cache != cache_buff)
my_free((gptr) cache,MYF(0));
if (last_errno)
errno=last_errno; /* Return first error */
DBUG_RETURN(last_errno != 0);
-} /* flush_key_blocks */
+}
+
+
+/*
+ Flush all blocks for a specific file to disk
+
+ SYNOPSIS
+ flush_all_key_blocks()
+ file File descriptor
+ type Type of flush operation
+
+ RETURN VALUES
+ 0 Ok
+ 1 Error
+*/
+
+int flush_key_blocks(File file, enum flush_type type)
+{
+ int res;
+ pthread_mutex_lock(&THR_LOCK_keycache);
+ res=flush_key_blocks_int(file, type);
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return res;
+}
+
+
+/*
+ Flush all blocks in the key cache to disk
+
+ SYNOPSIS
+ flush_all_key_blocks()
+
+ NOTE
+ We must have a lock on THR_LOCK_keycache before calling this function
+
+ RETURN VALUES
+ 0 Ok
+ 1 Error
+*/
+
+
+static int flush_all_key_blocks()
+{
+ int error=0;
+ while (_my_blocks_changed > 0)
+ if (flush_key_blocks_int(_my_used_first->file, FLUSH_RELEASE))
+ error=1;
+ return error;
+}
#ifndef DBUG_OFF
- /* Test if disk-cachee is ok */
+ /* Test if disk-cache is ok */
static void test_key_cache(const char *where, my_bool lock)
{
@@ -629,7 +723,14 @@ static void test_key_cache(const char *where, my_bool lock)
SEC_LINK *pos,**prev;
if (lock)
+ {
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* No active key cache */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return;
+ }
+ }
found=error=0;
for (i= 0 ; i < _my_hash_blocks ; i++)
{
@@ -646,7 +747,7 @@ static void test_key_cache(const char *where, my_bool lock)
i,(ulong) pos,(ulong) prev,(ulong) pos->prev_hash));
}
- if (((pos->diskpos/KEYCACHE_BLOCK_SIZE)+pos->file) % _my_hash_blocks != i)
+ if (((pos->diskpos >> key_cache_shift)+pos->file) % _my_hash_blocks != i)
{
DBUG_PRINT("error",("hash: %d pos: %lx : Wrong disk_buffer %ld",
i,(ulong) pos,(ulong) pos->diskpos));
diff --git a/mysys/mf_loadpath.c b/mysys/mf_loadpath.c
index 641528b8b5d..291ad62e297 100644
--- a/mysys/mf_loadpath.c
+++ b/mysys/mf_loadpath.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -37,8 +36,7 @@ my_string my_load_path(my_string to, const char *path,
test_if_hard_path(path))
VOID(strmov(buff,path));
else if ((path[0] == FN_CURLIB && path[1] == FN_LIBCHAR) ||
- (is_prefix((gptr) path,FN_PARENTDIR) &&
- path[strlen(FN_PARENTDIR)] == FN_LIBCHAR) ||
+ (is_prefix((gptr) path,FN_PARENTDIR)) ||
! own_path_prefix)
{
if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)),MYF(0)))
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index b442af7e9e5..8fba14f626b 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -40,6 +39,7 @@ void pack_dirname(my_string to, const char *from)
char buff[FN_REFLEN];
DBUG_ENTER("pack_dirname");
+ LINT_INIT(buff_length);
(void) intern_filename(to,from); /* Change to intern name */
#ifdef FN_DEVCHAR
@@ -49,7 +49,6 @@ void pack_dirname(my_string to, const char *from)
#endif
start=to;
- LINT_INIT(buff_length);
if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
{
buff_length= (uint) strlen(buff);
@@ -218,7 +217,7 @@ uint cleanup_dirname(register my_string to, const char *from)
to the directory. This will be used if the directory name
doesn't exists
*/
-
+
my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
@@ -459,8 +458,7 @@ my_string intern_filename(my_string to, const char *from)
my_string pos,from_pos,to_pos,end_pos;
char buff[FN_REFLEN];
- (void) strmov(buff,from);
- convert_dirname(buff); /* change '<>' to '[]' */
+ convert_dirname(buff,from,NullS); /* change '<>' to '[]' */
from_pos=buff;
if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skipp device part */
{
diff --git a/mysys/mf_pack2.c b/mysys/mf_pack2.c
deleted file mode 100644
index 1cda7797457..00000000000
--- a/mysys/mf_pack2.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
- /* Pack a filename for output on screen */
- /* Changes long paths to .../ */
- /* Removes pathname and extension */
- /* If not possibly to pack returns '?' in to and returns 1*/
-
-int pack_filename(my_string to, const char *name, size_s max_length)
- /* to may be name */
-
-{
- int i;
- char buff[FN_REFLEN];
-
- if (strlen(fn_format(to,name,"","",0)) <= max_length)
- return 0;
- if (strlen(fn_format(to,name,"","",8)) <= max_length)
- return 0;
- if (strlen(fn_format(buff,name,".../","",1)) <= max_length)
- {
- VOID(strmov(to,buff));
- return 0;
- }
- for (i= 0 ; i < 3 ; i++)
- {
- if (strlen(fn_format(buff,to,"","", i == 0 ? 2 : i == 1 ? 1 : 3 ))
- <= max_length)
- {
- VOID(strmov(to,buff));
- return 0;
- }
- }
- to[0]='?'; to[1]=0; /* Can't pack filename */
- return 1;
-} /* pack_filename */
diff --git a/mysys/mf_path.c b/mysys/mf_path.c
index 9a88b938e2c..23eadd2acce 100644
--- a/mysys/mf_path.c
+++ b/mysys/mf_path.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
diff --git a/mysys/mf_qsort2.c b/mysys/mf_qsort2.c
index 7b1ca4e39ab..160bb6df817 100644
--- a/mysys/mf_qsort2.c
+++ b/mysys/mf_qsort2.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* qsort that sends one extra argument to the compare subrutine */
diff --git a/mysys/mf_radix.c b/mysys/mf_radix.c
index 99aa4d0b073..7ee96b966b9 100644
--- a/mysys/mf_radix.c
+++ b/mysys/mf_radix.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Radixsort for pointers to fixed length strings.
diff --git a/mysys/mf_same.c b/mysys/mf_same.c
index c1a5cae11cb..efd6e7b2ca4 100644
--- a/mysys/mf_same.c
+++ b/mysys/mf_same.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Kopierar biblioteksstrukturen och extensionen fr}n ett filnamn */
diff --git a/mysys/mf_sleep.c b/mysys/mf_sleep.c
index f33a904cf5a..49db465e7c5 100644
--- a/mysys/mf_sleep.c
+++ b/mysys/mf_sleep.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Wait a given time (On systems that dont have sleep !!; MSDOS) */
diff --git a/mysys/mf_sort.c b/mysys/mf_sort.c
index 754a1deb1a7..0dc6c78a589 100644
--- a/mysys/mf_sort.c
+++ b/mysys/mf_sort.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Sort of string pointers in string-order with radix or qsort */
@@ -25,7 +24,7 @@ void my_string_ptr_sort(void *base, uint items, size_s size)
#if INT_MAX > 65536L
uchar **ptr=0;
- if (size <= 20 && items >= 1000 &&
+ if (size <= 20 && items >= 1000 && items < 100000 &&
(ptr= (uchar**) my_malloc(items*sizeof(char*),MYF(0))))
{
radixsort_for_str_ptr((uchar**) base,items,size,ptr);
diff --git a/mysys/mf_soundex.c b/mysys/mf_soundex.c
index 827385a1466..4f7aa7da601 100644
--- a/mysys/mf_soundex.c
+++ b/mysys/mf_soundex.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/****************************************************************
* SOUNDEX ALGORITHM in C *
diff --git a/mysys/mf_strip.c b/mysys/mf_strip.c
index 682c9c32cb0..ef2aab2c0a3 100644
--- a/mysys/mf_strip.c
+++ b/mysys/mf_strip.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* T|mmer en str{ng p{ slut_space */
diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index 465311088c1..09fde27afd6 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -90,9 +89,10 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
uint pfx_len;
File org_file;
- pfx_len=(strmov(strnmov(prefix_buff,
- prefix ? prefix : "tmp.",
- sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff);
+ pfx_len= (uint) (strmov(strnmov(prefix_buff,
+ prefix ? prefix : "tmp.",
+ sizeof(prefix_buff)-7),"XXXXXX") -
+ prefix_buff);
if (!dir && ! (dir =getenv("TMPDIR")))
dir=P_tmpdir;
if (strlen(dir)+ pfx_len > FN_REFLEN-2)
@@ -100,8 +100,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
errno=my_errno= ENAMETOOLONG;
return 1;
}
- strmov(to,dir);
- strmov(convert_dirname(to),prefix_buff);
+ strmov(convert_dirname(to,dir,NullS),prefix_buff);
org_file=mkstemp(to);
file=my_register_filename(org_file, to, FILE_BY_MKSTEMP,
EE_CANTCREATEFILE, MyFlags);
@@ -123,10 +122,10 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
dir=to;
}
#ifdef OS2
- // changing environ variable doesn't work with VACPP
+ /* changing environ variable doesn't work with VACPP */
char buffer[256];
sprintf( buffer, "TMP=%s", dir);
- // remove ending backslash
+ /* remove ending backslash */
if (buffer[strlen(buffer)-1] == '\\')
buffer[strlen(buffer)-1] = '\0';
putenv( buffer);
@@ -178,7 +177,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
if (end_pos != to && end_pos[-1] != FN_LIBCHAR)
*end_pos++=FN_LIBCHAR;
end_pos=strmov(end_pos,pfx);
-
+
for (length=0 ; length < 8 && uniq ; length++)
{
*end_pos++= _dig_vec[(int) (uniq & 31)];
diff --git a/mysys/mf_unixpath.c b/mysys/mf_unixpath.c
index 6ae29f99136..9efc3e5d9b8 100644
--- a/mysys/mf_unixpath.c
+++ b/mysys/mf_unixpath.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
diff --git a/mysys/mf_util.c b/mysys/mf_util.c
index 12af323680e..132c83b4623 100644
--- a/mysys/mf_util.c
+++ b/mysys/mf_util.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Utilities with are missing on some systems */
diff --git a/mysys/mf_wcomp.c b/mysys/mf_wcomp.c
index 5f1ab9b813e..bdcfb0501d8 100644
--- a/mysys/mf_wcomp.c
+++ b/mysys/mf_wcomp.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Funktions for comparing with wild-cards */
diff --git a/mysys/mf_wfile.c b/mysys/mf_wfile.c
index 87d1392250a..e9e12c72755 100644
--- a/mysys/mf_wfile.c
+++ b/mysys/mf_wfile.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions for finding files with wildcards */
diff --git a/mysys/mulalloc.c b/mysys/mulalloc.c
index 8a7ee312aa9..6b025bca699 100644
--- a/mysys/mulalloc.c
+++ b/mysys/mulalloc.c
@@ -1,26 +1,35 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- /* Malloc many pointers at the same time */
- /* format myFlags,ptr,length,ptr,length ... until null ptr */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <stdarg.h>
+/*
+ Malloc many pointers at the same time
+
+ SYNOPSIS
+ my_multi_malloc()
+ myFlags Flags
+ ... Multiple arguments terminated by null ptr
+
+ ptr, length
+ ptr, length
+ NULL
+*/
+
gptr my_multi_malloc(myf myFlags, ...)
{
va_list args;
diff --git a/mysys/my_aes.c b/mysys/my_aes.c
new file mode 100644
index 00000000000..b67166f8367
--- /dev/null
+++ b/mysys/my_aes.c
@@ -0,0 +1,199 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ Implementation of AES Encryption for MySQL
+ Initial version by Peter Zaitsev June 2002
+*/
+
+
+#include <my_global.h>
+#include <m_string.h>
+#include "my_aes.h"
+
+enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT };
+
+#define AES_BLOCK_SIZE 16 /* Block size in bytes */
+
+#define AES_BAD_DATA -1 /* If bad data discovered during decoding */
+
+
+/* The structure for key information */
+typedef struct {
+ int nr; /* Number of rounds */
+ uint32 rk[4*(AES_MAXNR + 1)]; /* key schedule */
+} KEYINSTANCE;
+
+
+/*
+ This is internal function just keeps joint code of Key generation
+
+ SYNOPSIS
+ my_aes_create_key()
+ aes_key Address of Key Instance to be created
+ direction Direction (are we encoding or decoding)
+ key Key to use for real key creation
+ key_length Length of the key
+
+ DESCRIPTION
+
+ RESULT
+ 0 ok
+ -1 Error Note: The current impementation never returns this
+*/
+
+static int my_aes_create_key(KEYINSTANCE *aes_key,
+ enum encrypt_dir direction, const char *key,
+ int key_length)
+{
+ char rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */
+ char *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */
+ char *ptr; /* Start of the real key*/
+ const char *sptr; /* Start of the working key */
+ const char *key_end=key+key_length; /* Working key boundary*/
+
+ bzero(rkey,AES_KEY_LENGTH/8); /* Set initial key */
+
+ for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++)
+ {
+ if (ptr == rkey_end)
+ ptr= rkey; /* Just loop over tmp_key until we used all key */
+ *ptr^= *sptr;
+ }
+ if (direction == AES_DECRYPT)
+ aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH);
+ else
+ aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH);
+ return 0;
+}
+
+
+/*
+ Crypt buffer with AES encryption algorithm.
+
+ SYNOPSIS
+ my_aes_encrypt()
+ source Pointer to data for encryption
+ source_length Size of encryption data
+ dest Buffer to place encrypted data (must be large enough)
+ key Key to be used for encryption
+ key_length Length of the key. Will handle keys of any length
+
+ RETURN
+ >= 0 Size of encrypted data
+ < 0 Error
+*/
+
+int my_aes_encrypt(const char* source, int source_length, char* dest,
+ const char* key, int key_length)
+{
+ KEYINSTANCE aes_key;
+ char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
+ int rc; /* result codes */
+ int num_blocks; /* number of complete blocks */
+ char pad_len; /* pad size for the last block */
+ int i;
+
+ if ((rc= my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length)))
+ return rc;
+
+ num_blocks = source_length/AES_BLOCK_SIZE;
+
+ for (i = num_blocks; i > 0; i--) /* Encode complete blocks */
+ {
+ rijndaelEncrypt(aes_key.rk, aes_key.nr, source, dest);
+ source+= AES_BLOCK_SIZE;
+ dest+= AES_BLOCK_SIZE;
+ }
+
+ /* Encode the rest. We always have incomplete block */
+ pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks);
+ memcpy(block, source, 16 - pad_len);
+ bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len);
+ rijndaelEncrypt(aes_key.rk, aes_key.nr, block, dest);
+ return AES_BLOCK_SIZE*(num_blocks + 1);
+}
+
+
+/*
+ DeCrypt buffer with AES encryption algorithm.
+
+ SYNOPSIS
+ my_aes_decrypt()
+ source Pointer to data for decryption
+ source_length Size of encrypted data
+ dest Buffer to place decrypted data (must be large enough)
+ key Key to be used for decryption
+ key_length Length of the key. Will handle keys of any length
+
+ RETURN
+ >= 0 Size of encrypted data
+ < 0 Error
+*/
+
+int my_aes_decrypt(const char *source, int source_length, char *dest,
+ const char *key, int key_length)
+{
+ KEYINSTANCE aes_key;
+ char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
+ int rc; /* Result codes */
+ int num_blocks; /* Number of complete blocks */
+ char pad_len; /* Pad size for the last block */
+ int i;
+
+ if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length)))
+ return rc;
+
+ num_blocks = source_length/AES_BLOCK_SIZE;
+
+ if ((source_length != num_blocks*AES_BLOCK_SIZE) || num_blocks ==0 )
+ return AES_BAD_DATA; /* Input size has to be even and at least one block */
+
+ for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */
+ {
+ rijndaelDecrypt(aes_key.rk, aes_key.nr, source, dest);
+ source+= AES_BLOCK_SIZE;
+ dest+= AES_BLOCK_SIZE;
+ }
+
+ rijndaelDecrypt(aes_key.rk, aes_key.nr, source, block);
+ pad_len = block[AES_BLOCK_SIZE-1]; /* Use last char in the block as size */
+
+ if (pad_len > AES_BLOCK_SIZE)
+ return AES_BAD_DATA;
+ /* We could also check whole padding but we do not really need this */
+
+ memcpy(dest, block, AES_BLOCK_SIZE - pad_len);
+ return AES_BLOCK_SIZE*num_blocks - pad_len;
+}
+
+
+/*
+ Get size of buffer which will be large enough for encrypted data
+
+ SYNOPSIS
+ my_aes_get_size()
+ source_length Length of data to be encrypted
+
+ RETURN
+ Size of buffer required to store encrypted data
+*/
+
+int my_aes_get_size(int source_length)
+{
+ return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE;
+}
diff --git a/mysys/my_alarm.c b/mysys/my_alarm.c
index aab01ad77f4..70daf4a9dd0 100644
--- a/mysys/my_alarm.c
+++ b/mysys/my_alarm.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Function to set a varible when we got a alarm */
/* Used by my_lock samt functions in m_alarm.h */
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index db482454e69..f494cce8dbe 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -1,42 +1,46 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Routines to handle mallocing of results which will be freed the same time */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
+#undef EXTRA_DEBUG
+#define EXTRA_DEBUG
-void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size)
+void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
+ uint pre_alloc_size __attribute__((unused)))
{
- mem_root->free=mem_root->used=0;
- mem_root->min_malloc=32;
- mem_root->block_size=block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
- mem_root->error_handler=0;
+ mem_root->free= mem_root->used= 0;
+ mem_root->min_malloc= 32;
+ mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
+ mem_root->error_handler= 0;
+ mem_root->block_num= 0;
+ mem_root->first_block_usage= 0;
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
if (pre_alloc_size)
{
- if ((mem_root->free = mem_root->pre_alloc=
+ if ((mem_root->free= mem_root->pre_alloc=
(USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
MYF(0))))
{
- mem_root->free->size=pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
- mem_root->free->left=pre_alloc_size;
- mem_root->free->next=0;
+ mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
+ mem_root->free->left= pre_alloc_size;
+ mem_root->free->next= 0;
}
}
#endif
@@ -54,29 +58,36 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
(*mem_root->error_handler)();
return((gptr) 0); /* purecov: inspected */
}
- next->next=mem_root->used;
- mem_root->used=next;
+ next->next= mem_root->used;
+ next->size= Size;
+ mem_root->used= next;
return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
#else
- uint get_size,max_left;
+ uint get_size, block_size;
gptr point;
- reg1 USED_MEM *next;
+ reg1 USED_MEM *next= 0;
reg2 USED_MEM **prev;
Size= ALIGN_SIZE(Size);
- prev= &mem_root->free;
- max_left=0;
- for (next= *prev ; next && next->left < Size ; next= next->next)
+ if ( (*(prev= &mem_root->free)) != NULL )
{
- if (next->left > max_left)
- max_left=next->left;
- prev= &next->next;
+ if( (*prev)->left < Size &&
+ mem_root->first_block_usage++ >= MAX_BLOCK_USAGE_BEFORE_DROP )
+ {
+ next= *prev;
+ *prev= next->next; /* Remove block from list */
+ next->next= mem_root->used;
+ mem_root->used= next;
+ mem_root->first_block_usage= 0;
+ }
+ for (next= *prev ; next && next->left < Size ; next= next->next)
+ prev= &next->next;
}
if (! next)
{ /* Time to alloc new block */
+ block_size= mem_root->block_size*((mem_root->block_num>>2)+1);
get_size= Size+ALIGN_SIZE(sizeof(USED_MEM));
- if (max_left*4 < mem_root->block_size && get_size < mem_root->block_size)
- get_size=mem_root->block_size; /* Normal alloc */
+ get_size= max(get_size, block_size);
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
{
@@ -84,23 +95,54 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
(*mem_root->error_handler)();
return((gptr) 0); /* purecov: inspected */
}
+ mem_root->block_num++;
next->next= *prev;
next->size= get_size;
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
*prev=next;
}
+
point= (gptr) ((char*) next+ (next->size-next->left));
+ /*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
if ((next->left-= Size) < mem_root->min_malloc)
{ /* Full block */
- *prev=next->next; /* Remove block from list */
- next->next=mem_root->used;
- mem_root->used=next;
+ *prev= next->next; /* Remove block from list */
+ next->next= mem_root->used;
+ mem_root->used= next;
+ mem_root->first_block_usage= 0;
}
return(point);
#endif
}
- /* deallocate everything used by alloc_root */
+/* Mark all data in blocks free for reusage */
+
+static inline void mark_blocks_free(MEM_ROOT* root)
+{
+ reg1 USED_MEM *next;
+ reg2 USED_MEM **last;
+
+ /* iterate through (partially) free blocks, mark them free */
+ last= &root->free;
+ for (next= root->free; next; next= *(last= &next->next))
+ next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
+
+ /* Combine the free and the used list */
+ *last= next=root->used;
+
+ /* now go through the used blocks and mark them free */
+ for (; next; next= next->next)
+ next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
+
+ /* Now everything is set; Indicate that nothing is used anymore */
+ root->used= 0;
+}
+
+
+/*
+ Deallocate everything used by alloc_root or just move
+ used blocks to free list if called with MY_USED_TO_FREE
+*/
void free_root(MEM_ROOT *root, myf MyFlags)
{
@@ -109,18 +151,23 @@ void free_root(MEM_ROOT *root, myf MyFlags)
if (!root)
DBUG_VOID_RETURN; /* purecov: inspected */
+ if (MyFlags & MY_MARK_BLOCKS_FREE)
+ {
+ mark_blocks_free(root);
+ DBUG_VOID_RETURN;
+ }
if (!(MyFlags & MY_KEEP_PREALLOC))
root->pre_alloc=0;
- for ( next=root->used; next ;)
+ for (next=root->used; next ;)
{
old=next; next= next->next ;
if (old != root->pre_alloc)
my_free((gptr) old,MYF(0));
}
- for (next= root->free ; next ; )
+ for (next=root->free ; next ;)
{
- old=next; next= next->next ;
+ old=next; next= next->next;
if (old != root->pre_alloc)
my_free((gptr) old,MYF(0));
}
@@ -130,17 +177,53 @@ void free_root(MEM_ROOT *root, myf MyFlags)
root->free=root->pre_alloc;
root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
root->free->next=0;
+ root->block_num= 1;
}
+ else
+ root->block_num= 0;
+ root->first_block_usage= 0;
DBUG_VOID_RETURN;
}
+/*
+ Find block that contains an object and set the pre_alloc to it
+*/
+
+void set_prealloc_root(MEM_ROOT *root, char *ptr)
+{
+ USED_MEM *next;
+ for (next=root->used; next ; next=next->next)
+ {
+ if ((char*) next <= ptr && (char*) next + next->size > ptr)
+ {
+ root->pre_alloc=next;
+ return;
+ }
+ }
+ for (next=root->free ; next ; next=next->next)
+ {
+ if ((char*) next <= ptr && (char*) next + next->size > ptr)
+ {
+ root->pre_alloc=next;
+ return;
+ }
+ }
+}
+
char *strdup_root(MEM_ROOT *root,const char *str)
{
- uint len= (uint) strlen(str)+1;
+ return strmake_root(root, str, strlen(str));
+}
+
+char *strmake_root(MEM_ROOT *root,const char *str, uint len)
+{
char *pos;
- if ((pos=alloc_root(root,len)))
+ if ((pos=alloc_root(root,len+1)))
+ {
memcpy(pos,str,len);
+ pos[len]=0;
+ }
return pos;
}
diff --git a/mysys/my_append.c b/mysys/my_append.c
index 0d3296fb278..2e08b4b4c05 100644
--- a/mysys/my_append.c
+++ b/mysys/my_append.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
diff --git a/mysys/my_bit.c b/mysys/my_bit.c
new file mode 100644
index 00000000000..0ff487afe03
--- /dev/null
+++ b/mysys/my_bit.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Some useful bit functions */
+
+#include "mysys_priv.h"
+
+/*
+ Find smallest X in 2^X >= value
+ This can be used to divide a number with value by doing a shift instead
+*/
+
+uint my_bit_log2(ulong value)
+{
+ uint bit;
+ for (bit=0 ; value > 1 ; value>>=1, bit++) ;
+ return bit;
+}
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index a18fcba0b60..8834dda98e1 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Handling of uchar arrays as large bitmaps.
@@ -26,7 +25,6 @@
#include "mysys_priv.h"
#include <my_bitmap.h>
#include <assert.h>
-#include <string.h>
#include <m_string.h>
inline void bitmap_lock(MY_BITMAP* map)
@@ -50,7 +48,7 @@ my_bool bitmap_init(MY_BITMAP *map, uint bitmap_size, my_bool thread_safe)
if (!(map->bitmap=(uchar*) my_malloc((bitmap_size+7)/8,
MYF(MY_WME | MY_ZEROFILL))))
return 1;
- dbug_assert(bitmap_size != ~(uint) 0);
+ DBUG_ASSERT(bitmap_size != ~(uint) 0);
#ifdef THREAD
if ((map->thread_safe = thread_safe))
pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST);
@@ -123,6 +121,7 @@ void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit)
}
}
+
void bitmap_set_all(MY_BITMAP* map)
{
bitmap_lock(map);
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index 2c07e8d136f..54129f12897 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -1,26 +1,39 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include "m_string.h"
- /* Change size of file. Truncate file if shorter, */
- /* else expand with zero. */
+/*
+ Change size of file.
+
+ SYNOPSIS
+ my_chsize()
+ fd File descriptor
+ new_length New file size
+ MyFlags Flags
+
+ DESCRIPTION
+ my_chsize() truncates file if shorter, else expand with zero.
+
+ RETURN VALUE
+ 0 Ok
+ 1 Error
+*/
int my_chsize(File fd, my_off_t newlength, myf MyFlags)
{
diff --git a/mysys/my_clock.c b/mysys/my_clock.c
index e7d1758fa2e..e49b2f85b66 100644
--- a/mysys/my_clock.c
+++ b/mysys/my_clock.c
@@ -1,22 +1,21 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
-#include "global.h"
+#include "my_global.h"
#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(OS2)
#include "mysys_priv.h"
diff --git a/mysys/my_compress.c b/mysys/my_compress.c
index f97d28c25ea..1e46584d525 100644
--- a/mysys/my_compress.c
+++ b/mysys/my_compress.c
@@ -1,26 +1,27 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Written by Sinisa Milivojevic <sinisa@coresinc.com> */
+/* Written by Sinisa Milivojevic <sinisa@mysql.com> */
-#include <global.h>
+#include <my_global.h>
#ifdef HAVE_COMPRESS
#include <my_sys.h>
+#ifndef SCO
#include <m_string.h>
+#endif
#include <zlib.h>
/*
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 9b02d84d063..253608c5306 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
diff --git a/mysys/my_create.c b/mysys/my_create.c
index 5a10b0fd8b5..5fa97a9ca78 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
#include "mysys_priv.h"
diff --git a/mysys/my_delete.c b/mysys/my_delete.c
index 77d5f311418..5670f03da64 100644
--- a/mysys/my_delete.c
+++ b/mysys/my_delete.c
@@ -1,22 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-#include "mysys_priv.h"
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#include "mysys_priv.h"
#include "mysys_err.h"
int my_delete(const char *name, myf MyFlags)
diff --git a/mysys/my_div.c b/mysys/my_div.c
index 24794679376..777ffe403d7 100644
--- a/mysys/my_div.c
+++ b/mysys/my_div.c
@@ -1,22 +1,29 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
+/*
+ Get filename of file
+
+ SYNOPSIS
+ my_filename()
+ fd File descriptor
+*/
+
my_string my_filename(File fd)
{
DBUG_ENTER("my_filename");
diff --git a/mysys/my_dup.c b/mysys/my_dup.c
new file mode 100644
index 00000000000..df298780e3e
--- /dev/null
+++ b/mysys/my_dup.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define USES_TYPES
+#include "mysys_priv.h"
+#include "mysys_err.h"
+#include <my_dir.h>
+#include <errno.h>
+#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
+#include <share.h>
+#endif
+
+ /* Open a file */
+
+File my_dup(File file, myf MyFlags)
+{
+ File fd;
+ const char *filename;
+ DBUG_ENTER("my_dup");
+ DBUG_PRINT("my",("file: %d MyFlags: %d", MyFlags));
+ fd = dup(file);
+ filename= (((int) file < MY_NFILE) ?
+ my_file_info[(int) file].name : "Unknown");
+ DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
+ EE_FILENOTFOUND, MyFlags));
+} /* my_open */
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 4aa946aa6c3..5ce061212b5 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -26,8 +25,15 @@
const char ** NEAR my_errmsg[MAXMAPS]={0,0,0,0};
char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE];
-/* Error message to user */
-/*VARARGS2*/
+/*
+ Error message to user
+
+ SYNOPSIS
+ my_error()
+ nr Errno
+ MyFlags Flags
+ ... variable list
+*/
int my_error(int nr,myf MyFlags, ...)
{
@@ -103,7 +109,16 @@ int my_error(int nr,myf MyFlags, ...)
DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags));
}
- /* Error as printf */
+/*
+ Error as printf
+
+ SYNOPSIS
+ my_printf_error()
+ error Errno
+ format Format string
+ MyFlags Flags
+ ... variable list
+*/
int my_printf_error (uint error, const char *format, myf MyFlags, ...)
{
@@ -116,7 +131,15 @@ int my_printf_error (uint error, const char *format, myf MyFlags, ...)
return (*error_handler_hook)(error, ebuff, MyFlags);
}
- /* Give message using error_handler_hook */
+/*
+ Give message using error_handler_hook
+
+ SYNOPSIS
+ my_message()
+ error Errno
+ str Error message
+ MyFlags Flags
+*/
int my_message(uint error, const char *str, register myf MyFlags)
{
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index e1575b0af48..d3b0b90f9c5 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "my_static.h"
diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c
index d93caadbcdc..94f3aaf3464 100644
--- a/mysys/my_fstream.c
+++ b/mysys/my_fstream.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* USE_MY_STREAM isn't set because we can't thrust my_fclose! */
@@ -147,7 +146,8 @@ uint my_fwrite(FILE *stream, const byte *Buffer, uint Count, myf MyFlags)
/* Seek to position in file */
/* ARGSUSED */
-my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags)
+my_off_t my_fseek(FILE *stream, my_off_t pos, int whence,
+ myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fseek");
DBUG_PRINT("my",("stream: %lx pos: %lu whence: %d MyFlags: %d",
@@ -160,7 +160,7 @@ my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags)
/* Tell current position of file */
/* ARGSUSED */
-my_off_t my_ftell(FILE *stream, myf MyFlags)
+my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused)))
{
off_t pos;
DBUG_ENTER("my_ftell");
diff --git a/mysys/my_gethostbyname.c b/mysys/my_gethostbyname.c
index f30591d9fe3..f21a880350b 100644
--- a/mysys/my_gethostbyname.c
+++ b/mysys/my_gethostbyname.c
@@ -18,7 +18,9 @@
/* Thread safe version of gethostbyname_r() */
#include "mysys_priv.h"
+#ifdef THREAD
#include "my_pthread.h"
+#endif
#include <assert.h>
#if !defined(MSDOS) && !defined(__WIN__)
#include <netdb.h>
@@ -28,11 +30,6 @@
/* This file is not needed if my_gethostbyname_r is a macro */
#if !defined(my_gethostbyname_r)
-#ifndef THREAD
-#define pthread_mutex_lock(A)
-#define pthread_mutex_unlock(A)
-#endif
-
/*
Emulate SOLARIS style calls, not because it's better, but just to make the
usage of getbostbyname_r simpler.
@@ -47,7 +44,7 @@ struct hostent *my_gethostbyname_r(const char *name,
int buflen, int *h_errnop)
{
struct hostent *hp;
- dbug_assert((size_t) buflen >= sizeof(*result));
+ DBUG_ASSERT((size_t) buflen >= sizeof(*result));
if (gethostbyname_r(name,result, buffer, (size_t) buflen, &hp, h_errnop))
return 0;
return hp;
@@ -59,7 +56,6 @@ struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
int buflen, int *h_errnop)
{
- dbug_assert(buflen >= sizeof(struct hostent_data));
if (gethostbyname_r(name,result,(struct hostent_data *) buffer) == -1)
{
*h_errnop= errno;
@@ -77,7 +73,7 @@ struct hostent *my_gethostbyname_r(const char *name,
int buflen, int *h_errnop)
{
struct hostent *hp;
- dbug_assert(buflen >= sizeof(struct hostent_data));
+ DBUG_ASSERT(buflen >= sizeof(struct hostent_data));
hp= gethostbyname_r(name,result,(struct hostent_data *) buffer);
*h_errnop= errno;
return hp;
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
new file mode 100644
index 00000000000..436e557c914
--- /dev/null
+++ b/mysys/my_getopt.c
@@ -0,0 +1,796 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#include <m_string.h>
+#include <stdlib.h>
+#include <my_getopt.h>
+#include <assert.h>
+#include <my_sys.h>
+#include <mysys_err.h>
+
+static int findopt(char *optpat, uint length,
+ const struct my_option **opt_res,
+ char **ffname);
+my_bool getopt_compare_strings(const char *s,
+ const char *t,
+ uint length);
+static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
+static ulonglong getopt_ull(char *arg, const struct my_option *optp,
+ int *err);
+static void init_variables(const struct my_option *options);
+static int setval(const struct my_option *opts, char *argument,
+ my_bool set_maximum_value);
+
+/*
+ The following three variables belong to same group and the number and
+ order of their arguments must correspond to each other.
+*/
+static const char *special_opt_prefix[]=
+{"skip", "disable", "enable", "maximum", "loose", 0};
+static const uint special_opt_prefix_lengths[]=
+{ 4, 7, 6, 7, 5, 0};
+enum enum_special_opt
+{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
+
+char *disabled_my_option= (char*) "0";
+
+/*
+ This is a flag that can be set in client programs. 0 means that
+ my_getopt will not print error messages, but the client should do
+ it by itself
+*/
+
+my_bool my_getopt_print_errors= 1;
+
+
+/*
+ function: handle_options
+
+ Sort options; put options first, until special end of options (--), or
+ until end of argv. Parse options; check that the given option matches with
+ one of the options in struct 'my_option', return error in case of ambiguous
+ or unknown option. Check that option was given an argument if it requires
+ one. Call function 'get_one_option()' once for each option.
+*/
+
+int handle_options(int *argc, char ***argv,
+ const struct my_option *longopts,
+ my_bool (*get_one_option)(int,
+ const struct my_option *,
+ char *))
+{
+ uint opt_found, argvpos= 0, length, i;
+ my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used,
+ option_is_loose;
+ char *progname= *(*argv), **pos, **pos_end, *optend, *prev_found;
+ const struct my_option *optp;
+ int error;
+
+ LINT_INIT(opt_found);
+ (*argc)--; /* Skip the program name */
+ (*argv)++; /* --- || ---- */
+ init_variables(longopts);
+
+ for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
+ {
+ char *cur_arg= *pos;
+ if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
+ {
+ char *argument= 0;
+ must_be_var= 0;
+ set_maximum_value= 0;
+ special_used= 0;
+ option_is_loose= 0;
+
+ cur_arg++; /* skip '-' */
+ if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
+ { /* --set-variable, or -O */
+ if (*cur_arg == 'O')
+ {
+ must_be_var= 1;
+
+ if (!(*++cur_arg)) /* If not -Ovar=# */
+ {
+ /* the argument must be in next argv */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: Option '-O' requires an argument\n",
+ progname);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ cur_arg= *pos;
+ (*argc)--;
+ }
+ }
+ else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
+ {
+ must_be_var= 1;
+ if (cur_arg[13] == '=')
+ {
+ cur_arg+= 14;
+ if (!*cur_arg)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: Option '--set-variable' requires an argument\n",
+ progname);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ }
+ else if (cur_arg[14]) /* garbage, or another option. break out */
+ must_be_var= 0;
+ else
+ {
+ /* the argument must be in next argv */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: Option '--set-variable' requires an argument\n",
+ progname);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ cur_arg= *pos;
+ (*argc)--;
+ }
+ }
+ else if (!must_be_var)
+ {
+ if (!*++cur_arg) /* skip the double dash */
+ {
+ /* '--' means end of options, look no further */
+ end_of_options= 1;
+ (*argc)--;
+ continue;
+ }
+ }
+ optend= strcend(cur_arg, '=');
+ length= optend - cur_arg;
+ if (*optend == '=')
+ optend++;
+ else
+ optend=0;
+
+ /*
+ Find first the right option. Return error in case of an ambiguous,
+ or unknown option
+ */
+ optp= longopts;
+ if (!(opt_found= findopt(cur_arg, length, &optp, &prev_found)))
+ {
+ /*
+ Didn't find any matching option. Let's see if someone called
+ option with a special option prefix
+ */
+ if (!must_be_var)
+ {
+ if (optend)
+ must_be_var= 1; /* option is followed by an argument */
+ for (i= 0; special_opt_prefix[i]; i++)
+ {
+ if (!getopt_compare_strings(special_opt_prefix[i], cur_arg,
+ special_opt_prefix_lengths[i]) &&
+ cur_arg[special_opt_prefix_lengths[i]] == '-')
+ {
+ /*
+ We were called with a special prefix, we can reuse opt_found
+ */
+ special_used= 1;
+ cur_arg+= (special_opt_prefix_lengths[i] + 1);
+ if (i == OPT_LOOSE)
+ option_is_loose= 1;
+ if ((opt_found= findopt(cur_arg, length -
+ (special_opt_prefix_lengths[i] + 1),
+ &optp, &prev_found)))
+ {
+ if (opt_found > 1)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: ambiguous option '--%s-%s' (--%s-%s)\n",
+ progname, special_opt_prefix[i], cur_arg,
+ special_opt_prefix[i], prev_found);
+ return EXIT_AMBIGUOUS_OPTION;
+ }
+ switch (i) {
+ case OPT_SKIP:
+ case OPT_DISABLE: /* fall through */
+ optend= disabled_my_option;
+ break;
+ case OPT_ENABLE:
+ optend= (char*) "1";
+ break;
+ case OPT_MAXIMUM:
+ set_maximum_value= 1;
+ must_be_var= 1;
+ break;
+ }
+ break; /* break from the inner loop, main loop continues */
+ }
+ }
+ }
+ }
+ if (!opt_found)
+ {
+ if (must_be_var)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: %s: unknown variable '%s'\n", progname,
+ option_is_loose ? "WARNING" : "ERROR", cur_arg);
+ if (!option_is_loose)
+ return EXIT_UNKNOWN_VARIABLE;
+ }
+ else
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: %s: unknown option '--%s'\n", progname,
+ option_is_loose ? "WARNING" : "ERROR", cur_arg);
+ if (!option_is_loose)
+ return EXIT_UNKNOWN_OPTION;
+ }
+ if (option_is_loose)
+ {
+ (*argc)--;
+ continue;
+ }
+ }
+ }
+ if (opt_found > 1)
+ {
+ if (must_be_var)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: variable prefix '%s' is not unique\n",
+ progname, cur_arg);
+ return EXIT_VAR_PREFIX_NOT_UNIQUE;
+ }
+ else
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: ambiguous option '--%s' (%s, %s)\n",
+ progname, cur_arg, prev_found, optp->name);
+ return EXIT_AMBIGUOUS_OPTION;
+ }
+ }
+ if (must_be_var && (!optp->value || optp->var_type == GET_BOOL))
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: option '%s' cannot take an argument\n",
+ progname, optp->name);
+ return EXIT_NO_ARGUMENT_ALLOWED;
+ }
+ if (optp->arg_type == NO_ARG)
+ {
+ if (optend && !special_used)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: option '--%s' cannot take an argument\n",
+ progname, optp->name);
+ return EXIT_NO_ARGUMENT_ALLOWED;
+ }
+ if (optp->var_type == GET_BOOL)
+ {
+ /*
+ Set bool to 1 if no argument or if the user has used
+ --enable-'option-name'.
+ *optend was set to '0' if one used --disable-option
+ */
+ *((my_bool*) optp->value)= (my_bool) (!optend || *optend == '1');
+ (*argc)--;
+ continue; /* For GET_BOOL get_one_option() shouldn't be called */
+ }
+ argument= optend;
+ }
+ else if (optp->arg_type == OPT_ARG && optp->var_type == GET_BOOL)
+ {
+ if (optend == disabled_my_option)
+ *((my_bool*) optp->value)= (my_bool) 0;
+ else
+ {
+ if (!optend) /* No argument -> enable option */
+ *((my_bool*) optp->value)= (my_bool) 1;
+ else /* If argument differs from 0, enable option, else disable */
+ *((my_bool*) optp->value)= (my_bool) atoi(optend) != 0;
+ }
+ (*argc)--;
+ continue;
+ }
+ else if (optp->arg_type == REQUIRED_ARG && !optend)
+ {
+ /* Check if there are more arguments after this one */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: option '--%s' requires an argument\n",
+ progname, optp->name);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ argument= *pos;
+ (*argc)--;
+ }
+ else
+ argument= optend;
+ }
+ else /* must be short option */
+ {
+ for (optend= cur_arg; *optend; optend++)
+ {
+ opt_found= 0;
+ for (optp= longopts; optp->id; optp++)
+ {
+ if (optp->id == (int) (uchar) *optend)
+ {
+ /* Option recognized. Find next what to do with it */
+ opt_found= 1;
+ if (optp->var_type == GET_BOOL && optp->arg_type == NO_ARG)
+ {
+ *((my_bool*) optp->value)= (my_bool) 1;
+ continue; /* For GET_BOOL get_one_option() shouldn't be called */
+ }
+ else if (optp->arg_type == REQUIRED_ARG ||
+ optp->arg_type == OPT_ARG)
+ {
+ if (*(optend + 1))
+ {
+ /* The rest of the option is option argument */
+ argument= optend + 1;
+ /* This is in effect a jump out of the outer loop */
+ optend= (char*) " ";
+ }
+ else if (optp->arg_type == REQUIRED_ARG)
+ {
+ /* Check if there are more arguments after this one */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: option '-%c' requires an argument\n",
+ progname, optp->id);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ argument= *pos;
+ (*argc)--;
+ /* the other loop will break, because *optend + 1 == 0 */
+ }
+ }
+ if ((error= setval(optp, argument, set_maximum_value)))
+ {
+ fprintf(stderr,
+ "%s: Error while setting value '%s' to '%s'\n",
+ progname, argument, optp->name);
+ return error;
+ }
+ get_one_option(optp->id, optp, argument);
+ break;
+ }
+ }
+ if (!opt_found)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: unknown option '-%c'\n", progname, *optend);
+ return EXIT_UNKNOWN_OPTION;
+ }
+ }
+ (*argc)--; /* option handled (short), decrease argument count */
+ continue;
+ }
+ if ((error= setval(optp, argument, set_maximum_value)))
+ {
+ fprintf(stderr,
+ "%s: Error while setting value '%s' to '%s'\n",
+ progname, argument, optp->name);
+ return error;
+ }
+ get_one_option(optp->id, optp, argument);
+
+ (*argc)--; /* option handled (short or long), decrease argument count */
+ }
+ else /* non-option found */
+ (*argv)[argvpos++]= cur_arg;
+ }
+ /*
+ Destroy the first, already handled option, so that programs that look
+ for arguments in 'argv', without checking 'argc', know when to stop.
+ Items in argv, before the destroyed one, are all non-option -arguments
+ to the program, yet to be (possibly) handled.
+ */
+ (*argv)[argvpos]= 0;
+ return 0;
+}
+
+/*
+ function: setval
+
+ Arguments: opts, argument
+ Will set the option value to given value
+*/
+
+static int setval (const struct my_option *opts, char *argument,
+ my_bool set_maximum_value)
+{
+ int err= 0;
+
+ if (opts->value && argument)
+ {
+ gptr *result_pos= ((set_maximum_value) ?
+ opts->u_max_value : opts->value);
+
+ if (!result_pos)
+ return EXIT_NO_PTR_TO_VARIABLE;
+
+ switch (opts->var_type) {
+ case GET_INT:
+ case GET_UINT: /* fall through */
+ *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
+ break;
+ case GET_LONG:
+ case GET_ULONG: /* fall through */
+ *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
+ break;
+ case GET_LL:
+ *((longlong*) result_pos)= getopt_ll(argument, opts, &err);
+ break;
+ case GET_ULL:
+ *((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
+ break;
+ case GET_STR:
+ *((char**) result_pos)= argument;
+ break;
+ case GET_STR_ALLOC:
+ if ((*((char**) result_pos)))
+ my_free((*(char**) result_pos),
+ MYF(MY_WME | MY_FAE));
+ if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
+ return EXIT_OUT_OF_MEMORY;
+ break;
+ default: /* dummy default to avoid compiler warnings */
+ break;
+ }
+ if (err)
+ return EXIT_UNKNOWN_SUFFIX;
+ }
+ return 0;
+}
+
+/*
+ function: findopt
+
+ Arguments: opt_pattern, length of opt_pattern, opt_struct, first found
+ name (ffname)
+
+ Go through all options in the my_option struct. Return number
+ of options found that match the pattern and in the argument
+ list the option found, if any. In case of ambiguous option, store
+ the name in ffname argument
+*/
+
+static int findopt(char *optpat, uint length,
+ const struct my_option **opt_res,
+ char **ffname)
+{
+ int count;
+ struct my_option *opt= (struct my_option *) *opt_res;
+
+ for (count= 0; opt->name; opt++)
+ {
+ if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
+ {
+ (*opt_res)= opt;
+ if (!count)
+ *ffname= (char *) opt->name; /* We only need to know one prev */
+ if (!opt->name[length]) /* Exact match */
+ return 1;
+ count++;
+ }
+ }
+ return count;
+}
+
+
+/*
+ function: compare_strings
+
+ Works like strncmp, other than 1.) considers '-' and '_' the same.
+ 2.) Returns -1 if strings differ, 0 if they are equal
+*/
+
+my_bool getopt_compare_strings(register const char *s, register const char *t,
+ uint length)
+{
+ char const *end= s + length;
+ for (;s != end ; s++, t++)
+ {
+ if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ function: eval_num_suffix
+
+ Transforms a number with a suffix to real number. Suffix can
+ be k|K for kilo, m|M for mega or g|G for giga.
+*/
+
+static longlong eval_num_suffix (char *argument, int *error, char *option_name)
+{
+ char *endchar;
+ longlong num;
+
+ *error= 0;
+ num= strtoll(argument, &endchar, 10);
+ if (*endchar == 'k' || *endchar == 'K')
+ num*= 1024L;
+ else if (*endchar == 'm' || *endchar == 'M')
+ num*= 1024L * 1024L;
+ else if (*endchar == 'g' || *endchar == 'G')
+ num*= 1024L * 1024L * 1024L;
+ else if (*endchar)
+ {
+ fprintf(stderr,
+ "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
+ *endchar, option_name, argument);
+ *error= 1;
+ return 0;
+ }
+ return num;
+}
+
+/*
+ function: getopt_ll
+
+ Evaluates and returns the value that user gave as an argument
+ to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
+ and G as GIGA bytes. Some values must be in certain blocks, as
+ defined in the given my_option struct, this function will check
+ that those values are honored.
+ In case of an error, set error value in *err.
+*/
+
+longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
+{
+ longlong num;
+
+ num= eval_num_suffix(arg, err, (char*) optp->name);
+ if (num < (longlong) optp->min_value)
+ num= (longlong) optp->min_value;
+ else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
+ && optp->max_value) /* if max value is not set -> no upper limit */
+ num= (longlong) (ulong) optp->max_value;
+ num= ((num - (longlong) optp->sub_size) / (optp->block_size ?
+ (ulonglong) optp->block_size :
+ 1L));
+ return (longlong) (num * (optp->block_size ? (ulonglong) optp->block_size :
+ 1L));
+}
+
+/*
+ function: getopt_ull
+
+ This is the same as getopt_ll, but is meant for unsigned long long
+ values.
+*/
+
+static ulonglong getopt_ull (char *arg, const struct my_option *optp, int *err)
+{
+ ulonglong num;
+
+ num= eval_num_suffix(arg, err, (char*) optp->name);
+ return getopt_ull_limit_value(num, optp);
+}
+
+
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
+{
+ if ((ulonglong) num > (ulonglong) (ulong) optp->max_value &&
+ optp->max_value) /* if max value is not set -> no upper limit */
+ num= (ulonglong) (ulong) optp->max_value;
+ if (optp->block_size > 1)
+ {
+ num/= (ulonglong) optp->block_size;
+ num*= (ulonglong) optp->block_size;
+ }
+ if (num < (ulonglong) optp->min_value)
+ num= (ulonglong) optp->min_value;
+ return num;
+}
+
+/*
+ function: init_variables
+
+ initialize all variables to their default values
+*/
+
+static void init_variables(const struct my_option *options)
+{
+ for (; options->name; options++)
+ {
+ if (options->value)
+ {
+ switch (options->var_type) {
+ case GET_BOOL:
+ *((my_bool*) options->u_max_value)= (my_bool) options->max_value;
+ *((my_bool*) options->value)= (my_bool) options->def_value;
+ break;
+ case GET_INT:
+ *((int*) options->u_max_value)= (int) options->max_value;
+ *((int*) options->value)= (int) options->def_value;
+ break;
+ case GET_UINT:
+ *((uint*) options->u_max_value)= (uint) options->max_value;
+ *((uint*) options->value)= (uint) options->def_value;
+ break;
+ case GET_LONG:
+ *((long*) options->u_max_value)= (long) options->max_value;
+ *((long*) options->value)= (long) options->def_value;
+ break;
+ case GET_ULONG:
+ *((ulong*) options->u_max_value)= (ulong) options->max_value;
+ *((ulong*) options->value)= (ulong) options->def_value;
+ break;
+ case GET_LL:
+ *((longlong*) options->u_max_value)= (longlong) options->max_value;
+ *((longlong*) options->value)= (longlong) options->def_value;
+ break;
+ case GET_ULL:
+ *((ulonglong*) options->u_max_value)= (ulonglong) options->max_value;
+ *((ulonglong*) options->value)= (ulonglong) options->def_value;
+ break;
+ default: /* dummy default to avoid compiler warnings */
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ function: my_print_options
+
+ Print help for all options and variables.
+*/
+
+void my_print_help(const struct my_option *options)
+{
+ uint col, name_space= 22, comment_space= 57;
+ const char *line_end;
+ const struct my_option *optp;
+
+ for (optp= options; optp->id; optp++)
+ {
+ if (optp->id < 256)
+ {
+ printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
+ col= 6;
+ }
+ else
+ {
+ printf(" ");
+ col= 2;
+ }
+ if (strlen(optp->name))
+ {
+ printf("--%s", optp->name);
+ col+= 2 + strlen(optp->name);
+ if (optp->var_type == GET_STR || optp->var_type == GET_STR_ALLOC)
+ {
+ printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
+ optp->arg_type == OPT_ARG ? "]" : "");
+ col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
+ }
+ else if (optp->var_type == GET_NO_ARG || optp->var_type == GET_BOOL)
+ {
+ putchar(' ');
+ col++;
+ }
+ else
+ {
+ printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
+ optp->arg_type == OPT_ARG ? "]" : "");
+ col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
+ }
+ if (col > name_space && optp->comment && *optp->comment)
+ {
+ putchar('\n');
+ col= 0;
+ }
+ }
+ for (; col < name_space; col++)
+ putchar(' ');
+ if (optp->comment && *optp->comment)
+ {
+ const char *comment= optp->comment, *end= strend(comment);
+
+ while ((uint) (end - comment) > comment_space)
+ {
+ for (line_end= comment + comment_space; *line_end != ' '; line_end--);
+ for (; comment != line_end; comment++)
+ putchar(*comment);
+ comment++; /* skip the space, as a newline will take it's place now */
+ putchar('\n');
+ for (col= 0; col < name_space; col++)
+ putchar(' ');
+ }
+ printf("%s", comment);
+ }
+ putchar('\n');
+ }
+}
+
+
+/*
+ function: my_print_options
+
+ Print variables.
+*/
+
+void my_print_variables(const struct my_option *options)
+{
+ uint name_space= 34, length;
+ char buff[255];
+ const struct my_option *optp;
+
+ printf("\nVariables (--variable-name=value)\n");
+ printf("and boolean options {FALSE|TRUE} Value (after reading options)\n");
+ printf("--------------------------------- -----------------------------\n");
+ for (optp= options; optp->id; optp++)
+ {
+ if (optp->value)
+ {
+ printf("%s", optp->name);
+ length= strlen(optp->name);
+ for (; length < name_space; length++)
+ putchar(' ');
+ switch (optp->var_type) {
+ case GET_STR:
+ case GET_STR_ALLOC: /* fall through */
+ printf("%s\n", *((char**) optp->value) ? *((char**) optp->value) :
+ "(No default value)");
+ break;
+ case GET_BOOL:
+ printf("%s\n", *((my_bool*) optp->value) ? "TRUE" : "FALSE");
+ break;
+ case GET_INT:
+ printf("%d\n", *((int*) optp->value));
+ break;
+ case GET_UINT:
+ printf("%d\n", *((uint*) optp->value));
+ break;
+ case GET_LONG:
+ printf("%lu\n", *((long*) optp->value));
+ break;
+ case GET_ULONG:
+ printf("%lu\n", *((ulong*) optp->value));
+ break;
+ case GET_LL:
+ printf("%s\n", llstr(*((longlong*) optp->value), buff));
+ break;
+ case GET_ULL:
+ longlong2str(*((ulonglong*) optp->value), buff, 10);
+ printf("%s\n", buff);
+ break;
+ default: /* dummy default to avoid compiler warnings */
+ break;
+ }
+ }
+ }
+}
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index 6bdea813fe4..22c6a4dbc2b 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* my_setwd() and my_getwd() works with intern_filenames !! */
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 3bc87fd179d..c4e6132aa9c 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "my_static.h"
@@ -45,9 +44,8 @@ static my_bool win32_init_tcp_ip();
#else
#define my_win_init()
#endif
-static my_bool my_init_done=0;
-
+my_bool my_init_done=0;
static ulong atoi_octal(const char *str)
{
@@ -169,6 +167,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
pthread_mutex_destroy(&THR_LOCK_malloc);
pthread_mutex_destroy(&THR_LOCK_open);
DBUG_POP(); /* Must be done before my_thread_end */
+ my_once_free();
my_thread_end();
my_thread_global_end();
#endif
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index f9774d8a4aa..a06120894c5 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* TODO: check for overun of memory for names. */
/* Convert MSDOS-TIME to standar time_t */
@@ -112,6 +111,10 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
dirp = opendir(directory_file_name(tmp_path,(my_string) path));
size = STARTSIZE;
+#if defined(__amiga__)
+ if ((dirp->dd_fd) < 0) /* Directory doesn't exists */
+ goto error;
+#endif
if (dirp == NULL || ! (buffer = (char *) my_malloc(size, MyFlags)))
goto error;
@@ -183,7 +186,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
my_errno=errno;
if (dirp)
(void) closedir(dirp);
- if (MyFlags & (MY_FAE+MY_WME))
+ if (MyFlags & (MY_FAE | MY_WME))
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
DBUG_RETURN((MY_DIR *) NULL);
} /* my_dir */
@@ -580,13 +583,15 @@ error:
** Note that MY_STAT is assumed to be same as struct stat
****************************************************************************/
-int my_fstat(int Filedes, MY_STAT *stat_area, myf MyFlags )
+int my_fstat(int Filedes, MY_STAT *stat_area,
+ myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fstat");
DBUG_PRINT("my",("fd: %d MyFlags: %d",Filedes,MyFlags));
DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
}
+
MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
{
int m_used;
@@ -611,4 +616,3 @@ error:
}
DBUG_RETURN((MY_STAT *) NULL);
} /* my_stat */
-
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index c002f447f59..44ac53677ba 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_lockmem.c b/mysys/my_lockmem.c
index 9c77c885797..6712c387a71 100644
--- a/mysys/my_lockmem.c
+++ b/mysys/my_lockmem.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Alloc a block of locked memory */
diff --git a/mysys/my_lread.c b/mysys/my_lread.c
index 94ed258151e..601d772b844 100644
--- a/mysys/my_lread.c
+++ b/mysys/my_lread.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_lwrite.c b/mysys/my_lwrite.c
index 734916173ce..e1a3decd053 100644
--- a/mysys/my_lwrite.c
+++ b/mysys/my_lwrite.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index c2df22ec7ec..1e7cdd3a3b5 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
#undef SAFEMALLOC
diff --git a/mysys/my_messnc.c b/mysys/my_messnc.c
index 0dd3be5ba98..6bb88443109 100644
--- a/mysys/my_messnc.c
+++ b/mysys/my_messnc.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
diff --git a/mysys/my_mkdir.c b/mysys/my_mkdir.c
index 3685312132c..ba1f4c1f2d8 100644
--- a/mysys/my_mkdir.c
+++ b/mysys/my_mkdir.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_net.c b/mysys/my_net.c
index 1c91f7ff802..a4a842ac15e 100644
--- a/mysys/my_net.c
+++ b/mysys/my_net.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* thread safe version of some common functions */
diff --git a/mysys/my_once.c b/mysys/my_once.c
index 0b8b5addc16..1250ce24994 100644
--- a/mysys/my_once.c
+++ b/mysys/my_once.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Not MT-SAFE */
@@ -25,8 +24,17 @@
#include "my_static.h"
#include "mysys_err.h"
- /* alloc for things we don't nead to free */
- /* No DBUG_ENTER... here to get smaller dbug-startup */
+/*
+ Alloc for things we don't nead to free
+
+ SYNOPSIS
+ my_once_alloc()
+ Size
+ MyFlags
+
+ NOTES
+ No DBUG_ENTER... here to get smaller dbug-startup
+*/
gptr my_once_alloc(unsigned int Size, myf MyFlags)
{
@@ -70,7 +78,12 @@ gptr my_once_alloc(unsigned int Size, myf MyFlags)
} /* my_once_alloc */
- /* deallocate everything used by my_once_alloc */
+/*
+ Deallocate everything used by my_once_alloc
+
+ SYNOPSIS
+ my_once_free()
+*/
void my_once_free(void)
{
diff --git a/mysys/my_open.c b/mysys/my_open.c
index 748113528a1..97f21724e1c 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
#include "mysys_priv.h"
@@ -24,7 +23,18 @@
#include <share.h>
#endif
- /* Open a file */
+/*
+ Open a file
+
+ SYNOPSIS
+ my_open()
+ FileName Fully qualified file name
+ Flags Read | write
+ MyFlags Special flags
+
+ RETURN VALUE
+ File descriptor
+*/
File my_open(const char *FileName, int Flags, myf MyFlags)
/* Path-name of file */
@@ -52,7 +62,15 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
} /* my_open */
- /* Close a file */
+/*
+ Close a file
+
+ SYNOPSIS
+ my_close()
+ fd File sescriptor
+ myf Special Flags
+
+*/
int my_close(File fd, myf MyFlags)
{
@@ -82,6 +100,16 @@ int my_close(File fd, myf MyFlags)
} /* my_close */
+/*
+ Register file in my_file_info[]
+
+ SYNOPSIS
+ my_register_filename()
+ fd
+ FileName
+ type_file_type
+*/
+
File my_register_filename(File fd, const char *FileName, enum file_type
type_of_file, uint error_message_number, myf MyFlags)
{
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 5c7d0be5854..661ef48ab3e 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index 696b62f8b0e..38451f1f79a 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -1,22 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions to get threads more portable */
+#define DONT_REMAP_PTHREAD_FUNCTIONS
#include "mysys_priv.h"
#ifdef THREAD
#include <signal.h>
@@ -407,13 +407,21 @@ int my_pthread_cond_init(pthread_cond_t *mp, const pthread_condattr_t *attr)
#endif
-/* Change functions on HP to work according to POSIX */
-#ifdef HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT
+/*****************************************************************************
+ Patches for HPUX
+ We need these because the pthread_mutex.. code returns -1 on error,
+ instead of the error code.
+
+ Note that currently we only remap pthread_ functions used by MySQL.
+ If we are depending on the value for some other pthread_xxx functions,
+ this has to be added here.
+****************************************************************************/
+
+#if defined(HPUX) || defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
#undef pthread_cond_timedwait
-int my_pthread_cond_timedwait(pthread_cond_t *cond,
- pthread_mutex_t *mutex,
+int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime)
{
int error=pthread_cond_timedwait(cond, mutex, abstime);
@@ -426,8 +434,21 @@ int my_pthread_cond_timedwait(pthread_cond_t *cond,
error= ETIMEDOUT;
return error;
}
-#endif /* HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT */
+#endif
+
+#ifdef HPUX
+int my_pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+ int error=pthread_mutex_trylock(mutex);
+ if (error == 1) /* Safety if the lib is fixed */
+ return 0; /* Mutex was locked */
+ if (error == -1) /* Safety if the lib is fixed */
+ error=errno;
+ return error;
+}
+
+#endif
/* Some help functions */
diff --git a/mysys/my_quick.c b/mysys/my_quick.c
index 6151d5037ae..44ed3fc0b2c 100644
--- a/mysys/my_quick.c
+++ b/mysys/my_quick.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Quicker interface to read & write. Used with my_nosys.h */
diff --git a/mysys/my_read.c b/mysys/my_read.c
index b317630f4bd..b7621ac99eb 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -1,37 +1,46 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <errno.h>
- /* Read a chunk of bytes from a file */
+/*
+ Read a chunk of bytes from a file with retry's if needed
+
+ The parameters are:
+ File descriptor
+ Buffer to hold at least Count bytes
+ Bytes to read
+ Flags on what to do on error
+
+ Return:
+ -1 on error
+ 0 if flag has bits MY_NABP or MY_FNABP set
+ N number of bytes read.
+*/
uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags)
- /* File descriptor */
- /* Buffer must be at least count bytes */
- /* Max number of bytes returnd */
- /* Flags on what to do on error */
{
- uint readbytes;
+ uint readbytes,save_count;
DBUG_ENTER("my_read");
DBUG_PRINT("my",("Fd: %d Buffer: %lx Count: %u MyFlags: %d",
Filedes, Buffer, Count, MyFlags));
+ save_count=Count;
for (;;)
{
@@ -54,12 +63,21 @@ uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags)
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
my_filename(Filedes),my_errno);
}
- if ((int) readbytes == -1 || (MyFlags & (MY_FNABP | MY_NABP)))
+ if ((int) readbytes == -1 ||
+ ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO)))
DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
+ if (readbytes > 0 && (MyFlags & MY_FULL_IO))
+ {
+ Buffer+=readbytes;
+ Count-=readbytes;
+ continue;
+ }
}
if (MyFlags & (MY_NABP | MY_FNABP))
readbytes=0; /* Ok on read */
+ else if (MyFlags & MY_FULL_IO)
+ readbytes=save_count;
break;
}
DBUG_RETURN(readbytes);
diff --git a/mysys/my_realloc.c b/mysys/my_realloc.c
index 7ab75d47619..49d96c2eb4f 100644
--- a/mysys/my_realloc.c
+++ b/mysys/my_realloc.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
#undef SAFEMALLOC
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index 16ec77394d2..8474dab0d13 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
diff --git a/mysys/my_rename.c b/mysys/my_rename.c
index ea895ffcf76..fde45eba456 100644
--- a/mysys/my_rename.c
+++ b/mysys/my_rename.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
#include "mysys_priv.h"
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 7c4da4f6010..177a5cee953 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
@@ -26,7 +25,8 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
reg1 os_off_t newpos;
DBUG_ENTER("my_seek");
DBUG_PRINT("my",("Fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
- fd, ((ulonglong) pos) >> 32, (ulong) pos, whence, MyFlags));
+ fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos,
+ whence, MyFlags));
newpos=lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
@@ -34,6 +34,10 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
DBUG_PRINT("error",("lseek: %lu, errno: %d",newpos,errno));
DBUG_RETURN(MY_FILEPOS_ERROR);
}
+ if ((my_off_t) newpos != pos)
+ {
+ DBUG_PRINT("exit",("pos: %lu", (ulong) newpos));
+ }
DBUG_RETURN((my_off_t) newpos);
} /* my_seek */
@@ -53,6 +57,6 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
#endif
if (pos == (os_off_t) -1)
my_errno=errno;
- DBUG_PRINT("exit",("pos: %lu",pos));
+ DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
DBUG_RETURN((my_off_t) pos);
} /* my_tell */
diff --git a/mysys/my_semaphore.c b/mysys/my_semaphore.c
new file mode 100644
index 00000000000..de4aac1cdbd
--- /dev/null
+++ b/mysys/my_semaphore.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Simple implementation of semaphores, needed to compile MySQL on systems
+ that doesn't support semaphores.
+*/
+
+#include <my_global.h>
+#include <my_semaphore.h>
+
+#if !defined(__WIN__) && !defined(HAVE_SEMAPHORE_H)
+
+int sem_init(sem_t * sem, int pshared, uint value)
+{
+ sem->count=value;
+ pthread_cond_init(&sem->cond, 0);
+ pthread_mutex_init(&sem->mutex, 0);
+ return 0;
+}
+
+int sem_destroy(sem_t * sem)
+{
+ int err1,err2;
+ err1=pthread_cond_destroy(&sem->cond);
+ err2=pthread_mutex_destroy(&sem->mutex);
+ if (err1 || err2)
+ {
+ errno=err1 ? err1 : err2;
+ return -1;
+ }
+ return 0;
+}
+
+int sem_wait(sem_t * sem)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ while (!sem->count)
+ pthread_cond_wait(&sem->cond, &sem->mutex);
+ if (errno)
+ return -1;
+ sem->count--; /* mutex is locked here */
+ pthread_mutex_unlock(&sem->mutex);
+ return 0;
+}
+
+int sem_trywait(sem_t * sem)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ if (sem->count)
+ sem->count--;
+ else
+ errno=EAGAIN;
+ pthread_mutex_unlock(&sem->mutex);
+ return errno ? -1 : 0;
+}
+
+
+int sem_post(sem_t * sem)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ sem->count++;
+ pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */
+ pthread_cond_signal(&sem->cond); /* first: x_unlock or x_signal ? */
+ return 0;
+}
+
+int sem_post_multiple(sem_t * sem, uint count)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ sem->count+=count;
+ pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */
+ pthread_cond_broadcast(&sem->cond); /* first: x_unlock or x_broadcast ? */
+ return 0;
+}
+
+int sem_getvalue(sem_t * sem, uint *sval)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ *sval=sem->count;
+ pthread_mutex_unlock(&sem->mutex);
+ return 0;
+}
+
+#endif /* !defined(__WIN__) && !defined(HAVE_SEMAPHORE_H) */
diff --git a/mysys/my_static.c b/mysys/my_static.c
index 00061893cdc..1eb6220f185 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Static variables for mysys library. All definied here for easy making of
@@ -83,6 +82,13 @@ struct remember *pRememberRoot = NULL;
int volatile my_have_got_alarm=0; /* declare variable to reset */
ulong my_time_to_wait_for_lock=2; /* In seconds */
+ /*
+ We need to have this define here as otherwise linking will fail
+ on OSF1 when compiling --without-raid --with-debug
+ */
+
+const char *raid_type_string[]={"none","striped"};
+
/* from errors.c */
#ifdef SHARED_LIBRARY
char * NEAR globerrs[GLOBERRS]; /* my_error_messages is here */
diff --git a/mysys/my_static.h b/mysys/my_static.h
index e9d1a30b786..8360728b057 100644
--- a/mysys/my_static.h
+++ b/mysys/my_static.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Static variables for mysys library. All definied here for easy making of
@@ -39,6 +38,9 @@ struct irem {
my_string _sFileName; /* File in which memory was new'ed */
uint _uLineNum; /* Line number in above file */
uint _uDataSize; /* Size requested */
+#ifdef THREAD
+ pthread_t thread_id;
+#endif
long _lSpecialValue; /* Underrun marker value */
};
@@ -57,6 +59,14 @@ extern const char *soundex_map;
extern USED_MEM* my_once_root_block;
extern uint my_once_extra;
+#ifdef THREAD
+/*
+ These threads are exempt from safemalloc leak scrutiny unless
+ PEDANTIC_SAFEMALLOC is defined
+*/
+extern pthread_t signal_th, kill_th, main_th;
+#endif
+
#ifndef HAVE_TEMPNAM
extern int _my_tempnam_used;
#endif
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index 65d165fc026..5cc22b6bfbc 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c
index f1e90abaa9b..68b034bec5c 100644
--- a/mysys/my_symlink2.c
+++ b/mysys/my_symlink2.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Advanced symlink handling.
@@ -23,6 +22,7 @@
*/
#include "mysys_priv.h"
+#include "mysys_err.h"
#include <m_string.h>
File my_create_with_symlink(const char *linkname, const char *filename,
@@ -30,11 +30,27 @@ File my_create_with_symlink(const char *linkname, const char *filename,
{
File file;
int tmp_errno;
+ /* Test if we should create a link */
+ int create_link=(linkname && strcmp(linkname,filename));
DBUG_ENTER("my_create_with_symlink");
+
+ if (!(MyFlags & MY_DELETE_OLD))
+ {
+ if (!access(filename,F_OK))
+ {
+ my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST);
+ DBUG_RETURN(-1);
+ }
+ if (create_link && !access(linkname,F_OK))
+ {
+ my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST);
+ DBUG_RETURN(-1);
+ }
+ }
+
if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0)
{
- /* Test if we should create a link */
- if (linkname && strcmp(linkname,filename))
+ if (create_link)
{
/* Delete old link/file */
if (MyFlags & MY_DELETE_OLD)
diff --git a/mysys/my_tempnam.c b/mysys/my_tempnam.c
index fdaf018af0d..6c17aa5b165 100644
--- a/mysys/my_tempnam.c
+++ b/mysys/my_tempnam.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
This function is only used by some old ISAM code.
@@ -110,13 +109,13 @@ my_string my_tempnam(const char *dir, const char *pfx,
old_env=(char**)environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
- environ=(const char**)temp_env; /* May give warning */
+ ((char**) environ)=(char**) temp_env;
temp_env[0]=0;
}
#endif
res=tempnam((char*) dir,(my_string) pfx); /* Use stand. dir with prefix */
#ifndef OS2
- environ=(const char**)old_env; /* May give warning */
+ ((char**) environ)=(char**) old_env;
#endif
if (!res)
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 2782576d8cd..45c10e5a7b6 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
-** Functions to handle initializating and allocationg of all mysys & debug
-** thread variables.
+ Functions to handle initializating and allocationg of all mysys & debug
+ thread variables.
*/
#include "mysys_priv.h"
@@ -45,10 +44,6 @@ pthread_mutexattr_t my_fast_mutexattr;
pthread_mutexattr_t my_errchk_mutexattr;
#endif
-/* FIXME Note. TlsAlloc does not set an auto destructor, so
- the function my_thread_global_free must be called from
- somewhere before final exit of the library */
-
my_bool my_thread_global_init(void)
{
if (pthread_key_create(&THR_KEY_mysys,free))
@@ -60,7 +55,7 @@ my_bool my_thread_global_init(void)
pthread_mutexattr_init(&my_fast_mutexattr);
pthread_mutexattr_setkind_np(&my_fast_mutexattr,PTHREAD_MUTEX_ADAPTIVE_NP);
#endif
-#ifdef PPTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
pthread_mutexattr_init(&my_errchk_mutexattr);
pthread_mutexattr_setkind_np(&my_errchk_mutexattr,
PTHREAD_MUTEX_ERRORCHECK_NP);
@@ -87,6 +82,7 @@ my_bool my_thread_global_init(void)
return my_thread_init();
}
+
void my_thread_global_end(void)
{
#if defined(USE_TLS)
@@ -115,50 +111,62 @@ static long thread_id=0;
my_bool my_thread_init(void)
{
struct st_my_thread_var *tmp;
+ my_bool error=0;
+
+#ifdef EXTRA_DEBUG_THREADS
+ fprintf(stderr,"my_thread_init(): thread_id=%ld\n",pthread_self());
+#endif
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_lock(&THR_LOCK_lock);
#endif
+
#if !defined(__WIN__) || defined(USE_TLS)
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
{
- pthread_mutex_unlock(&THR_LOCK_lock);
- return 0; /* Safequard */
+#ifdef EXTRA_DEBUG_THREADS
+ fprintf(stderr,"my_thread_init() called more than once in thread %ld\n",
+ pthread_self());
+#endif
+ goto end;
}
- /* We must have many calloc() here because these are freed on
- pthread_exit */
- if (!(tmp=(struct st_my_thread_var *)
- calloc(1,sizeof(struct st_my_thread_var))))
+ if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
{
- pthread_mutex_unlock(&THR_LOCK_lock);
- return 1;
+ error= 1;
+ goto end;
}
pthread_setspecific(THR_KEY_mysys,tmp);
#else
- if (THR_KEY_mysys.id) /* Already initialized */
- {
-#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
- pthread_mutex_unlock(&THR_LOCK_lock);
-#endif
- return 0;
- }
+ /*
+ Skip initialization if the thread specific variable is already initialized
+ */
+ if (THR_KEY_mysys.id)
+ goto end;
tmp= &THR_KEY_mysys;
#endif
tmp->id= ++thread_id;
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&tmp->suspend, NULL);
+
+end:
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_unlock(&THR_LOCK_lock);
#endif
- return 0;
+ return error;
}
+
void my_thread_end(void)
{
struct st_my_thread_var *tmp=my_thread_var;
+#ifdef EXTRA_DEBUG_THREADS
+ fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
+ tmp,pthread_self());
+#endif
if (tmp)
{
#if !defined(DBUG_OFF)
+ /* tmp->dbug is allocated inside DBUG library */
if (tmp->dbug)
{
free(tmp->dbug);
@@ -173,6 +181,7 @@ void my_thread_end(void)
free(tmp);
#endif
}
+ /* The following free has to be done, even if my_thread_var() is 0 */
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
pthread_setspecific(THR_KEY_mysys,0);
#endif
@@ -193,8 +202,9 @@ struct st_my_thread_var *_my_thread_var(void)
return tmp;
}
+
/****************************************************************************
-** Get name of current thread.
+ Get name of current thread.
****************************************************************************/
#define UNKNOWN_THREAD -1
diff --git a/mysys/my_vsnprintf.c b/mysys/my_vsnprintf.c
index ab8edec4d7b..7490ab4a9f2 100644
--- a/mysys/my_vsnprintf.c
+++ b/mysys/my_vsnprintf.c
@@ -1,25 +1,25 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <m_string.h>
#include <stdarg.h>
#include <m_ctype.h>
+#include <assert.h>
int my_snprintf(char* to, size_t n, const char* fmt, ...)
{
@@ -40,7 +40,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
*to++= *fmt; /* Copy ordinary char */
continue;
}
- /* Skipp if max size is used (to be compatible with printf) */
+ /* Skip if max size is used (to be compatible with printf) */
fmt++;
while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
fmt++;
@@ -49,14 +49,13 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
if (*fmt == 's') /* String parameter */
{
reg2 char *par = va_arg(ap, char *);
- uint plen;
+ uint plen,left_len = (uint)(end-to);
if (!par) par = (char*)"(null)";
plen = (uint) strlen(par);
- if ((uint) (end-to) > plen) /* Replace if possible */
- {
- to=strmov(to,par);
- continue;
- }
+ if (left_len <= plen)
+ plen = left_len - 1;
+ to=strnmov(to,par,plen);
+ continue;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{
@@ -75,26 +74,34 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
break;
*to++='%'; /* % used as % or unknown code */
}
+ DBUG_ASSERT(to <= end);
*to='\0'; /* End of errmessage */
return (uint) (to - start);
}
#ifdef MAIN
+#define OVERRUN_SENTRY 250
static void my_printf(const char * fmt, ...)
{
- char buf[32];
+ char buf[33];
int n;
va_list ar;
va_start(ar, fmt);
- n = my_vsnprintf(buf, sizeof(buf),fmt, ar);
+ buf[sizeof(buf)-1]=OVERRUN_SENTRY;
+ n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar);
printf(buf);
printf("n=%d, strlen=%d\n", n, strlen(buf));
+ if (buf[sizeof(buf)-1] != OVERRUN_SENTRY)
+ {
+ fprintf(stderr, "Buffer overrun\n");
+ abort();
+ }
va_end(ar);
}
int main()
{
-
+
my_printf("Hello\n");
my_printf("Hello int, %d\n", 1);
my_printf("Hello string '%s'\n", "I am a string");
@@ -109,4 +116,3 @@ int main()
return 0;
}
#endif
-
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index 0c5b01f90d8..8c497e8f250 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*****************************************************************************
** The following is a simple implementation of posix conditions
diff --git a/mysys/my_winsem.c b/mysys/my_winsem.c
new file mode 100644
index 00000000000..e2713d189b2
--- /dev/null
+++ b/mysys/my_winsem.c
@@ -0,0 +1,406 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: my_semaphore.c (Original: semaphore.c from pthreads library)
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA
+ */
+
+/*
+ NEED_SEM is not used in MySQL and should only be needed under
+ Windows CE.
+
+ The big changes compared to the original version was to not allocate
+ any additional memory in sem_init() but to instead store everthing
+ we need in sem_t.
+
+ TODO:
+ To get HAVE_CREATESEMAPHORE we have to define the struct
+ in my_semaphore.h
+*/
+
+#include "mysys_priv.h"
+#ifdef __WIN__
+#include "my_semaphore.h"
+#include <errno.h>
+
+/*
+ DOCPUBLIC
+ This function initializes an unnamed semaphore. the
+ initial value of the semaphore is 'value'
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ pshared If zero, this semaphore may only be shared between
+ threads in the same process.
+ If nonzero, the semaphore can be shared between
+ processes
+
+ value Initial value of the semaphore counter
+
+ RESULTS
+ 0 Successfully created semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSPC A required resource has been exhausted,
+ ENOSYS Semaphores are not supported,
+ EPERM The process lacks appropriate privilege
+
+*/
+
+int
+sem_init (sem_t *sem, int pshared, unsigned int value)
+{
+ int result = 0;
+
+ if (pshared != 0)
+ {
+ /*
+ We don't support creating a semaphore that can be shared between
+ processes
+ */
+ result = EPERM;
+ }
+ else
+ {
+#ifndef HAVE_CREATESEMAPHORE
+ sem->value = value;
+ sem->event = CreateEvent(NULL,
+ FALSE, /* manual reset */
+ FALSE, /* initial state */
+ NULL);
+ if (!sem->event)
+ result = ENOSPC;
+ else
+ {
+ if (value)
+ SetEvent(sem->event);
+ InitializeCriticalSection(&sem->sem_lock_cs);
+ }
+#else /* HAVE_CREATESEMAPHORE */
+ *sem = CreateSemaphore (NULL, /* Always NULL */
+ value, /* Initial value */
+ 0x7FFFFFFFL, /* Maximum value */
+ NULL); /* Name */
+ if (!*sem)
+ result = ENOSPC;
+#endif /* HAVE_CREATESEMAPHORE */
+ }
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+ return 0;
+} /* sem_init */
+
+
+/*
+ DOCPUBLIC
+ This function destroys an unnamed semaphore.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully destroyed semaphore,
+ -1 Failed, error in errno
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+ EBUSY Threads (or processes) are currently blocked on 'sem'
+*/
+
+int
+sem_destroy (sem_t * sem)
+{
+ int result = 0;
+
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return;
+ }
+#endif /* EXTRA_DEBUG */
+
+#ifndef HAVE_CREATESEMAPHORE
+ if (! CloseHandle(sem->event))
+ result = EINVAL;
+ else
+ DeleteCriticalSection(&sem->sem_lock_cs);
+#else /* HAVE_CREATESEMAPHORE */
+ if (!CloseHandle(*sem))
+ result = EINVAL;
+#endif /* HAVE_CREATESEMAPHORE */
+ if (result)
+ {
+ errno = result;
+ return -1;
+ }
+ *sem=0; /* Safety */
+ return 0;
+} /* sem_destroy */
+
+
+/*
+ DOCPUBLIC
+ This function tries to wait on a semaphore. If the
+ semaphore value is greater than zero, it decreases
+ its value by one. If the semaphore value is zero, then
+ this function returns immediately with the error EAGAIN
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully decreased semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EAGAIN The semaphore was already locked,
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+ EINTR The function was interrupted by a signal,
+ EDEADLK A deadlock condition was detected.
+*/
+
+int
+sem_trywait(sem_t * sem)
+{
+#ifndef HAVE_CREATESEMAPHORE
+ /* not yet implemented! */
+ int errno = EINVAL;
+ return -1;
+#else /* HAVE_CREATESEMAPHORE */
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+ if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)
+ {
+ errno= EAGAIN;
+ return -1;
+ }
+ return 0;
+#endif /* HAVE_CREATESEMAPHORE */
+
+} /* sem_trywait */
+
+
+#ifndef HAVE_CREATESEMAPHORE
+
+static void
+ptw32_decrease_semaphore(sem_t * sem)
+{
+ EnterCriticalSection(&sem->sem_lock_cs);
+ DBUG_ASSERT(sem->value != 0);
+ sem->value--;
+ if (sem->value != 0)
+ SetEvent(sem->event);
+ LeaveCriticalSection(&sem->sem_lock_cs);
+}
+
+static BOOL
+ptw32_increase_semaphore(sem_t * sem, unsigned int n)
+{
+ BOOL result=FALSE;
+
+ EnterCriticalSection(&sem->sem_lock_cs);
+ if (sem->value + n > sem->value)
+ {
+ sem->value += n;
+ SetEvent(sem->event);
+ result = TRUE;
+ }
+ LeaveCriticalSection(&sem->sem_lock_cs);
+ return result;
+}
+
+#endif /* HAVE_CREATESEMAPHORE */
+
+
+/*
+ ------------------------------------------------------
+ DOCPUBLIC
+ This function waits on a semaphore. If the
+ semaphore value is greater than zero, it decreases
+ its value by one. If the semaphore value is zero, then
+ the calling thread (or process) is blocked until it can
+ successfully decrease the value or until interrupted by
+ a signal.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully decreased semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'Sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+ EINTR The function was interrupted by a signal,
+ EDEADLK A deadlock condition was detected.
+*/
+
+int
+sem_wait(sem_t *sem)
+{
+ int result;
+
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+
+#ifndef HAVE_CREATESEMAPHORE
+ result=WaitForSingleObject(sem->event, INFINITE);
+#else
+ result=WaitForSingleObject(*sem, INFINITE);
+#endif
+ if (result == WAIT_FAILED || result == WAIT_ABANDONED_0)
+ result = EINVAL;
+ else if (result == WAIT_TIMEOUT)
+ result = ETIMEDOUT;
+ else
+ result=0;
+ if (result)
+ {
+ errno = result;
+ return -1;
+ }
+#ifndef HAVE_CREATESEMAPHORE
+ ptw32_decrease_semaphore(sem);
+#endif /* HAVE_CREATESEMAPHORE */
+ return 0;
+}
+
+
+/*
+ ------------------------------------------------------
+ DOCPUBLIC
+ This function posts a wakeup to a semaphore. If there
+ are waiting threads (or processes), one is awakened;
+ otherwise, the semaphore value is incremented by one.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully posted semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+
+*/
+
+int
+sem_post (sem_t * sem)
+{
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+
+#ifndef HAVE_CREATESEMAPHORE
+ if (! ptw32_increase_semaphore(sem, 1))
+#else /* HAVE_CREATESEMAPHORE */
+ if (! ReleaseSemaphore(*sem, 1, 0))
+#endif /* HAVE_CREATESEMAPHORE */
+ {
+ errno=EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ ------------------------------------------------------
+ DOCPUBLIC
+ This function posts multiple wakeups to a semaphore. If there
+ are waiting threads (or processes), n <= count are awakened;
+ the semaphore value is incremented by count - n.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+ count Counter, must be greater than zero.
+
+ RESULTS
+ 0 Successfully posted semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore or count is less
+ than or equal to zero.
+*/
+
+int
+sem_post_multiple (sem_t * sem, unsigned int count)
+{
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL || count <= 0)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+#ifndef HAVE_CREATESEMAPHORE
+ if (! ptw32_increase_semaphore (sem, count))
+#else /* HAVE_CREATESEMAPHORE */
+ if (! ReleaseSemaphore(*sem, count, 0))
+#endif /* HAVE_CREATESEMAPHORE */
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+int
+sem_getvalue (sem_t *sem, unsigned int *sval)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_getvalue */
+
+#endif /* __WIN__ */
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index a77167c23e4..eebc07df180 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*****************************************************************************
** Simulation of posix threads calls for WIN95 and NT
diff --git a/mysys/my_write.c b/mysys/my_write.c
index 5d5a48a3dda..61fd6097e28 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 20fda270658..ba16e8820fe 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -1,21 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#ifdef USE_SYSTEM_WRAPPERS
diff --git a/mysys/ptr_cmp.c b/mysys/ptr_cmp.c
index 65b2c51aafd..5fc7ccab4fa 100644
--- a/mysys/ptr_cmp.c
+++ b/mysys/ptr_cmp.c
@@ -1,27 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
get_ptr_compare(len) returns a pointer to a optimal byte-compare function
for a array of stringpointer where all strings have size len.
The bytes are compare as unsigned chars.
- Because the size is saved in a static variable.
- When using threads the program must have called my_init and the thread
- my_init_thread()
*/
#include "mysys_priv.h"
diff --git a/mysys/queues.c b/mysys/queues.c
index 1c7a1a4a618..c458c96e998 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for generell handling of priority Queues.
@@ -124,7 +123,6 @@ byte *queue_remove(register QUEUE *queue, uint idx)
}
}
-
/* Fix when element on top has been replaced */
#ifndef queue_replaced
@@ -166,3 +164,24 @@ void _downheap(register QUEUE *queue, uint idx)
}
queue->root[idx]=element;
}
+
+
+static int queue_fix_cmp(QUEUE *queue, void **a, void **b)
+{
+ return queue->compare(queue->first_cmp_arg,
+ (char*) (*a)+queue->offset_to_key,
+ (char*) (*b)+queue->offset_to_key);
+}
+
+/*
+ Fix heap when every element was changed
+ actually, it can be done in linear time,
+ not in n*log(n), but some code (myisam/ft_boolean_search.c)
+ requires a strict order here, not just a queue property
+*/
+
+void queue_fix(QUEUE *queue)
+{
+ qsort2(queue->root+1,queue->elements, sizeof(void *),
+ (qsort2_cmp)queue_fix_cmp, queue);
+}
diff --git a/mysys/raid.cc b/mysys/raid.cc
index 47326f29f60..6196e1f1aa6 100644
--- a/mysys/raid.cc
+++ b/mysys/raid.cc
@@ -1,75 +1,74 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* --------------------------------------------------------*
-*
-* RAID support for MySQL. Raid 0 (stiping) only implemented yet.
-*
-* Why RAID? Why it must be in MySQL?
-*
-* This is because then you can:
-* 1. Have bigger tables than your OS limit. In time of writing this
-* we are hitting to 2GB limit under linux/ext2
-* 2. You can get more speed from IO bottleneck by putting
-* Raid dirs on different physical disks.
-* 3. Getting more fault tolerance (not implemented yet)
-*
-* Why not to use RAID:
-*
-* 1. You are losing some processor power to calculate things,
-* do more syscalls and interrupts.
-*
-* Functionality is supplied by two classes: RaidFd and RaidName.
-* RaidFd supports funtionality over file descriptors like
-* open/create/write/seek/close. RaidName supports functionality
-* like rename/delete where we have no relations to filedescriptors.
-* RaidName can be prorably unchanged for different Raid levels. RaidFd
-* have to be virtual I think ;).
-* You can speed up some calls in MySQL code by skipping RAID code.
-* For example LOAD DATA INFILE never needs to read RAID-ed files.
-* This can be done adding proper "#undef my_read" or similar undef-s
-* in your code. Check out the raid.h!
-*
-* Some explanation about _seek_vector[]
-* This is seek cache. RAID seeks too much and we cacheing this. We
-* fool it and just storing new position in file to _seek_vector.
-* When there is no seeks to do, we are putting RAID_SEEK_DONE into it.
-* Any other value requires seeking to that position.
-*
-* TODO:
-*
-*
-* - Implement other fancy things like RAID 1 (mirroring) and RAID 5.
-* Should not to be very complex.
-*
-* - Optimize big blob writes by resorting write buffers and writing
-* big chunks at once instead of doing many syscalls. - after thinking I
-* found this is useless. This is because same thing one can do with just
-* increasing RAID_CHUNKSIZE. Monty, what do you think? tonu.
-*
-* - If needed, then implement missing syscalls. One known to miss is stat();
-*
-* - Make and use a thread safe dynamic_array buffer. The used one
-* will not work if needs to be extended at the same time someone is
-* accessing it.
-*
-*
-* tonu@mysql.com & monty@mysql.com
-* --------------------------------------------------------*/
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+
+ RAID support for MySQL. Raid 0 (stiping) only implemented yet.
+
+ Why RAID? Why it must be in MySQL?
+
+ This is because then you can:
+ 1. Have bigger tables than your OS limit. In time of writing this
+ we are hitting to 2GB limit under linux/ext2
+ 2. You can get more speed from IO bottleneck by putting
+ Raid dirs on different physical disks.
+ 3. Getting more fault tolerance (not implemented yet)
+
+ Why not to use RAID:
+
+ 1. You are losing some processor power to calculate things,
+ do more syscalls and interrupts.
+
+ Functionality is supplied by two classes: RaidFd and RaidName.
+ RaidFd supports funtionality over file descriptors like
+ open/create/write/seek/close. RaidName supports functionality
+ like rename/delete where we have no relations to filedescriptors.
+ RaidName can be prorably unchanged for different Raid levels. RaidFd
+ have to be virtual I think ;).
+ You can speed up some calls in MySQL code by skipping RAID code.
+ For example LOAD DATA INFILE never needs to read RAID-ed files.
+ This can be done adding proper "#undef my_read" or similar undef-s
+ in your code. Check out the raid.h!
+
+ Some explanation about _seek_vector[]
+ This is seek cache. RAID seeks too much and we cacheing this. We
+ fool it and just storing new position in file to _seek_vector.
+ When there is no seeks to do, we are putting RAID_SEEK_DONE into it.
+ Any other value requires seeking to that position.
+
+ TODO:
+
+
+ - Implement other fancy things like RAID 1 (mirroring) and RAID 5.
+ Should not to be very complex.
+
+ - Optimize big blob writes by resorting write buffers and writing
+ big chunks at once instead of doing many syscalls. - after thinking I
+ found this is useless. This is because same thing one can do with just
+ increasing RAID_CHUNKSIZE. Monty, what do you think? tonu.
+
+ - If needed, then implement missing syscalls. One known to miss is stat();
+
+ - Make and use a thread safe dynamic_array buffer. The used one
+ will not work if needs to be extended at the same time someone is
+ accessing it.
+
+
+ tonu@mysql.com & monty@mysql.com
+*/
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
@@ -410,8 +409,8 @@ IsRaid(File fd)
RaidFd::
RaidFd(uint raid_type, uint raid_chunks, ulong raid_chunksize)
:_raid_type(raid_type), _raid_chunks(raid_chunks),
- _raid_chunksize(raid_chunksize), _position(0), _fd_vector(0),
- _size(RAID_SIZE_UNKNOWN)
+ _raid_chunksize(raid_chunksize), _position(0), _size(RAID_SIZE_UNKNOWN),
+ _fd_vector(0)
{
DBUG_ENTER("RaidFd::RaidFd");
DBUG_PRINT("enter",("RaidFd_type: %u Disks: %u Chunksize: %d",
diff --git a/mysys/rijndael.c b/mysys/rijndael.c
new file mode 100644
index 00000000000..dd0c45445d5
--- /dev/null
+++ b/mysys/rijndael.c
@@ -0,0 +1,1397 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ Based on version 3.0 (December 2000)
+
+ Optimised ANSI C code for the Rijndael cipher (now AES)
+
+ author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ author Paulo Barreto <paulo.barreto@terra.com.br>
+*/
+
+#include <my_global.h>
+#include <assert.h>
+#include "rijndael.h"
+
+/*
+ Define the following to use fastest and much larger code (~10K extra code)
+ #define FULL_UNROLL
+*/
+
+
+#ifdef NOT_USED
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+#endif
+
+
+static const uint32 Te0[256]=
+{
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+
+static const uint32 Te1[256]=
+{
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+
+static const uint32 Te2[256]=
+{
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+
+static const uint32 Te3[256]=
+{
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const uint32 Te4[256]=
+{
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+
+static const uint32 Td0[256]=
+{
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+
+static const uint32 Td1[256]=
+{
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+
+static const uint32 Td2[256]=
+{
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+
+static const uint32 Td3[256]=
+{
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+
+static const uint32 Td4[256]=
+{
+ 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+ 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+ 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+ 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+ 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+ 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+ 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+ 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+ 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+ 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+ 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+ 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+ 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+ 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+ 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+ 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+ 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+ 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+ 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+ 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+ 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+ 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+ 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+ 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+ 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+ 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+ 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+ 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+ 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+ 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+ 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+ 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+ 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+ 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+ 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+ 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+ 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+ 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+ 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+ 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+ 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+ 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+ 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+ 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+ 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+ 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+ 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+ 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+ 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+ 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+ 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+ 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+ 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+ 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+ 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+ 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+ 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+ 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+ 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+ 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+ 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+ 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+ 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+ 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+
+
+/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+static const uint32 rcon[]=
+{
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000,
+};
+
+#if defined(_MSC_VER) && defined(__i386__)
+
+#define RJ_SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+#define GETuint32(p) RJ_SWAP(*((uint32 *)(p)))
+#define PUTuint32(ct, st) { *((uint32 *)(ct)) = RJ_SWAP((st)); }
+
+#else
+
+#define GETuint32(pt) (((uint32)(pt)[0] << 24) ^ ((uint32)(pt)[1] << 16)\
+ ^ ((uint32)(pt)[2] << 8) ^ ((uint32)(pt)[3]))
+#define PUTuint32(ct, st) { (ct)[0] = (uint8)((st) >> 24); (ct)[1]\
+= (uint8)((st) >> 16); (ct)[2] = (uint8)((st) >> 8); (ct)[3] = (uint8)(st); }
+
+#endif /* defined(_MSC_VER) && defined(__i386__) */
+
+
+/*
+ Expand the cipher key into the encryption key schedule.
+
+ RETURN
+ The number of rounds for the given cipher key size.
+*/
+
+int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits)
+{
+ int i = 0;
+ uint32 temp;
+
+ rk[0] = GETuint32(cipherKey );
+ rk[1] = GETuint32(cipherKey + 4);
+ rk[2] = GETuint32(cipherKey + 8);
+ rk[3] = GETuint32(cipherKey + 12);
+ if (keyBits == 128)
+ {
+ for (;;)
+ {
+ temp = rk[3];
+ rk[4] = (rk[0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i]);
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ if (++i == 10)
+ return 10;
+ rk += 4;
+ }
+ }
+ rk[4] = GETuint32(cipherKey + 16);
+ rk[5] = GETuint32(cipherKey + 20);
+ if (keyBits == 192)
+ {
+ for (;;)
+ {
+ temp = rk[ 5];
+ rk[ 6] = (rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i]);
+ rk[ 7] = rk[ 1] ^ rk[ 6];
+ rk[ 8] = rk[ 2] ^ rk[ 7];
+ rk[ 9] = rk[ 3] ^ rk[ 8];
+ if (++i == 8)
+ {
+ return 12;
+ }
+ rk[10] = rk[ 4] ^ rk[ 9];
+ rk[11] = rk[ 5] ^ rk[10];
+ rk += 6;
+ }
+ }
+ rk[6] = GETuint32(cipherKey + 24);
+ rk[7] = GETuint32(cipherKey + 28);
+ if (keyBits == 256)
+ {
+ for (;;)
+ {
+ temp = rk[ 7];
+ rk[ 8] = (rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i]);
+ rk[ 9] = rk[ 1] ^ rk[ 8];
+ rk[10] = rk[ 2] ^ rk[ 9];
+ rk[11] = rk[ 3] ^ rk[10];
+ if (++i == 7)
+ {
+ return 14;
+ }
+ temp = rk[11];
+ rk[12] = (rk[ 4] ^
+ (Te4[(temp >> 24) ] & 0xff000000) ^
+ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp ) & 0xff] & 0x000000ff));
+ rk[13] = rk[ 5] ^ rk[12];
+ rk[14] = rk[ 6] ^ rk[13];
+ rk[15] = rk[ 7] ^ rk[14];
+ rk += 8;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Expand the cipher key into the decryption key schedule.
+
+ RETURN
+ The number of rounds for the given cipher key size.
+*/
+
+int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits)
+{
+ int nr, i, j;
+ uint32 temp;
+
+ /* expand the cipher key: */
+ nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
+ /* invert the order of the round keys: */
+ for (i = 0, j = 4*nr; i < j; i += 4, j -= 4)
+ {
+ temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
+ temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+ temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+ temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+ }
+ /*
+ Apply the inverse MixColumn transform to all round keys but the first
+ and the last:
+ */
+ for (i = 1; i < nr; i++)
+ {
+ rk += 4;
+
+ rk[0]= (
+ Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[0] ) & 0xff] & 0xff]);
+
+ rk[1]= (Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[1] ) & 0xff] & 0xff]);
+
+ rk[2]= (Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[2] ) & 0xff] & 0xff]);
+
+ rk[3]= (Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[3] ) & 0xff] & 0xff]);
+ }
+ return nr;
+}
+
+
+void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 pt[16], uint8 ct[16])
+{
+ uint32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* FULL_UNROLL */
+
+ /* map byte array block to cipher state and add initial round key: */
+ s0 = GETuint32(pt ) ^ rk[0];
+ s1 = GETuint32(pt + 4) ^ rk[1];
+ s2 = GETuint32(pt + 8) ^ rk[2];
+ s3 = GETuint32(pt + 12) ^ rk[3];
+
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[ 4]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[ 5]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[ 6]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[ 7]);
+
+ /* round 2: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[ 8]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[ 9]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[10]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[11]);
+
+ /* round 3: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[12]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[13]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[14]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[15]);
+
+ /* round 4: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[16]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[17]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[18]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[19]);
+
+ /* round 5: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[20]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[21]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[22]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[23]);
+
+ /* round 6: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[24]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[25]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[26]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[27]);
+
+ /* round 7: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[28]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[29]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[30]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[31]);
+
+ /* round 8: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[32]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[33]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[34]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[35]);
+
+ /* round 9: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[36]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[37]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[38]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[39]);
+
+ if (Nr > 10)
+ {
+ /* round 10: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[40]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[41]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[42]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[43]);
+
+ /* round 11: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[44]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[45]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[46]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[47]);
+
+ if (Nr > 12)
+ {
+ /* round 12: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[48]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[49]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[50]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[51]);
+
+ /* round 13: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[52]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[53]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[54]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[55]);
+ }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+
+ /* Nr - 1 full rounds: */
+
+ r = Nr >> 1;
+ for (;;)
+ {
+ t0= (Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[4]);
+
+ t1= (Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[5]);
+
+ t2= (Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[6]);
+
+ t3= (Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[7]);
+
+ rk+= 8;
+ if (--r == 0)
+ break;
+
+ s0= (Te0[(t0 >> 24) ] ^
+ Te1[(t1 >> 16) & 0xff] ^
+ Te2[(t2 >> 8) & 0xff] ^
+ Te3[(t3 ) & 0xff] ^
+ rk[0]);
+
+ s1= (Te0[(t1 >> 24) ] ^
+ Te1[(t2 >> 16) & 0xff] ^
+ Te2[(t3 >> 8) & 0xff] ^
+ Te3[(t0 ) & 0xff] ^
+ rk[1]);
+
+ s2= (Te0[(t2 >> 24) ] ^
+ Te1[(t3 >> 16) & 0xff] ^
+ Te2[(t0 >> 8) & 0xff] ^
+ Te3[(t1 ) & 0xff] ^
+ rk[2]);
+
+ s3= (Te0[(t3 >> 24) ] ^
+ Te1[(t0 >> 16) & 0xff] ^
+ Te2[(t1 >> 8) & 0xff] ^
+ Te3[(t2 ) & 0xff] ^
+ rk[3]);
+ }
+#endif /* FULL_UNROLL */
+
+ /* Apply last round and map cipher state to byte array block: */
+ s0= ((Te4[(t0 >> 24) ] & 0xff000000) ^
+ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[0]);
+ PUTuint32(ct , s0);
+
+ s1= ((Te4[(t1 >> 24) ] & 0xff000000) ^
+ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[1]);
+ PUTuint32(ct + 4, s1);
+
+ s2= ((Te4[(t2 >> 24) ] & 0xff000000) ^
+ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[2]);
+ PUTuint32(ct + 8, s2);
+
+ s3= ((Te4[(t3 >> 24) ] & 0xff000000) ^
+ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[3]);
+ PUTuint32(ct + 12, s3);
+}
+
+
+void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 ct[16], uint8 pt[16])
+{
+ uint32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* FULL_UNROLL */
+
+ /* Map byte array block to cipher state and add initial round key: */
+
+ s0 = GETuint32(ct ) ^ rk[0];
+ s1 = GETuint32(ct + 4) ^ rk[1];
+ s2 = GETuint32(ct + 8) ^ rk[2];
+ s3 = GETuint32(ct + 12) ^ rk[3];
+
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[ 4]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[ 5]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[ 6]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[ 7]);
+
+ /* round 2: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[ 8]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[ 9]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[10]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[11]);
+
+ /* round 3: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[12]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[13]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[14]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[15]);
+
+ /* round 4: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[16]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[17]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[18]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[19]);
+
+ /* round 5: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[20]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[21]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[22]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[23]);
+
+ /* round 6: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[24]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[25]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[26]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[27]);
+
+ /* round 7: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[28]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[29]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[30]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[31]);
+
+ /* round 8: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[32]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[33]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[34]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[35]);
+
+ /* round 9: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[36]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[37]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[38]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[39]);
+
+ if (Nr > 10)
+ {
+ /* round 10: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[40]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[41]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[42]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[43]);
+
+ /* round 11: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[44]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[45]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[46]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[47]);
+
+ if (Nr > 12)
+ {
+ /* round 12: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[48]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[49]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[50]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[51]);
+
+ /* round 13: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[52]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[53]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[54]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[55]);
+ }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+
+ /* Nr - 1 full rounds: */
+ r= (Nr >> 1);
+ for (;;)
+ {
+ t0= (Td0[(s0 >> 24) ] ^
+ Td1[(s3 >> 16) & 0xff] ^
+ Td2[(s2 >> 8) & 0xff] ^
+ Td3[(s1 ) & 0xff] ^
+ rk[4]);
+
+ t1= (Td0[(s1 >> 24) ] ^
+ Td1[(s0 >> 16) & 0xff] ^
+ Td2[(s3 >> 8) & 0xff] ^
+ Td3[(s2 ) & 0xff] ^
+ rk[5]);
+
+ t2= (Td0[(s2 >> 24) ] ^
+ Td1[(s1 >> 16) & 0xff] ^
+ Td2[(s0 >> 8) & 0xff] ^
+ Td3[(s3 ) & 0xff] ^
+ rk[6]);
+
+ t3= (Td0[(s3 >> 24) ] ^
+ Td1[(s2 >> 16) & 0xff] ^
+ Td2[(s1 >> 8) & 0xff] ^
+ Td3[(s0 ) & 0xff] ^
+ rk[7]);
+
+ rk+= 8;
+ if (--r == 0)
+ break;
+
+ s0= (Td0[(t0 >> 24) ] ^
+ Td1[(t3 >> 16) & 0xff] ^
+ Td2[(t2 >> 8) & 0xff] ^
+ Td3[(t1 ) & 0xff] ^
+ rk[0]);
+
+ s1= (Td0[(t1 >> 24) ] ^
+ Td1[(t0 >> 16) & 0xff] ^
+ Td2[(t3 >> 8) & 0xff] ^
+ Td3[(t2 ) & 0xff] ^
+ rk[1]);
+
+ s2= (Td0[(t2 >> 24) ] ^
+ Td1[(t1 >> 16) & 0xff] ^
+ Td2[(t0 >> 8) & 0xff] ^
+ Td3[(t3 ) & 0xff] ^
+ rk[2]);
+
+ s3= (Td0[(t3 >> 24) ] ^
+ Td1[(t2 >> 16) & 0xff] ^
+ Td2[(t1 >> 8) & 0xff] ^
+ Td3[(t0 ) & 0xff] ^
+ rk[3]);
+ }
+
+#endif /* FULL_UNROLL */
+
+ /* Apply last round and map cipher state to byte array block: */
+
+ s0= ((Td4[(t0 >> 24) ] & 0xff000000) ^
+ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[0]);
+ PUTuint32(pt , s0);
+
+ s1= ((Td4[(t1 >> 24) ] & 0xff000000) ^
+ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[1]);
+ PUTuint32(pt + 4, s1);
+
+ s2= ((Td4[(t2 >> 24) ] & 0xff000000) ^
+ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[2]);
+ PUTuint32(pt + 8, s2);
+
+ s3= ((Td4[(t3 >> 24) ] & 0xff000000) ^
+ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[3]);
+ PUTuint32(pt + 12, s3);
+}
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index 34fcfff756c..07a19504604 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -1,68 +1,64 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000 MySQL AB
-/*
- * [This posting refers to an article entitled "oops, corrupted memory
- * again!" in net.lang.c. I am posting it here because it is source.]
- *
- * My tool for approaching this problem is to build another level of data
- * abstraction on top of malloc() and free() that implements some checking.
- * This does a number of things for you:
- * - Checks for overruns and underruns on allocated data
- * - Keeps track of where in the program the memory was malloc'ed
- * - Reports on pieces of memory that were not free'ed
- * - Records some statistics such as maximum memory used
- * - Marks newly malloc'ed and newly free'ed memory with special values
- * You can use this scheme to:
- * - Find bugs such as overrun, underrun, etc because you know where
- * a piece of data was malloc'ed and where it was free'ed
- * - Find bugs where memory was not free'ed
- * - Find bugs where newly malloc'ed memory is used without initializing
- * - Find bugs where newly free'ed memory is still used
- * - Determine how much memory your program really uses
- * - and other things
- */
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-/*
- * To implement my scheme you must have a C compiler that has __LINE__ and
- * __FILE__ macros. If your compiler doesn't have these then (a) buy another:
- * compilers that do are available on UNIX 4.2bsd based systems and the PC,
- * and probably on other machines; or (b) change my scheme somehow. I have
- * recomendations on both these points if you would like them (e-mail please).
- *
- * There are 4 functions in my package:
- * char *NEW( uSize ) Allocate memory of uSize bytes
- * (equivalent to malloc())
- * char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and
- * free pPtr.
- * (equivalent to realloc())
- * FREE( pPtr ) Free memory allocated by NEW
- * (equivalent to free())
- * TERMINATE(file) End system, report errors and stats on file
- * I personally use two more functions, but have not included them here:
- * char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory
- * char *RENEW( pPtr, uSize )
- * (equivalent to realloc())
- */
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* Memory sub-system, written by Bjorn Benson
Fixed to use my_sys scheme by Michael Widenius
- */
+
+ [This posting refers to an article entitled "oops, corrupted memory
+ again!" in net.lang.c. I am posting it here because it is source.]
+
+ My tool for approaching this problem is to build another level of data
+ abstraction on top of malloc() and free() that implements some checking.
+ This does a number of things for you:
+ - Checks for overruns and underruns on allocated data
+ - Keeps track of where in the program the memory was malloc'ed
+ - Reports on pieces of memory that were not free'ed
+ - Records some statistics such as maximum memory used
+ - Marks newly malloc'ed and newly free'ed memory with special values
+ You can use this scheme to:
+ - Find bugs such as overrun, underrun, etc because you know where
+ a piece of data was malloc'ed and where it was free'ed
+ - Find bugs where memory was not free'ed
+ - Find bugs where newly malloc'ed memory is used without initializing
+ - Find bugs where newly free'ed memory is still used
+ - Determine how much memory your program really uses
+ - and other things
+
+ To implement my scheme you must have a C compiler that has __LINE__ and
+ __FILE__ macros. If your compiler doesn't have these then (a) buy another:
+ compilers that do are available on UNIX 4.2bsd based systems and the PC,
+ and probably on other machines; or (b) change my scheme somehow. I have
+ recomendations on both these points if you would like them (e-mail please).
+
+ There are 4 functions in my package:
+ char *NEW( uSize ) Allocate memory of uSize bytes
+ (equivalent to malloc())
+ char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and
+ free pPtr.
+ (equivalent to realloc())
+ FREE( pPtr ) Free memory allocated by NEW
+ (equivalent to free())
+ TERMINATE(file) End system, report errors and stats on file
+ I personally use two more functions, but have not included them here:
+ char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory
+ char *RENEW( pPtr, uSize )
+ (equivalent to realloc())
+
+*/
#ifndef SAFEMALLOC
#define SAFEMALLOC /* Get protos from my_sys */
@@ -75,13 +71,28 @@
ulonglong safemalloc_mem_limit = ~(ulonglong)0;
+#ifdef THREAD
+pthread_t shutdown_th,main_th,signal_th;
+#endif
+
#define pNext tInt._pNext
#define pPrev tInt._pPrev
#define sFileName tInt._sFileName
#define uLineNum tInt._uLineNum
#define uDataSize tInt._uDataSize
+#define thread_id tInt.thread_id
#define lSpecialValue tInt._lSpecialValue
+#ifndef PEDANTIC_SAFEMALLOC
+/*
+ Set to 1 after TERMINATE() if we had to fiddle with cNewCount and
+ the linked list of blocks so that _sanity() will not fuss when it
+ is not supposed to
+*/
+static int sf_malloc_tampered = 0;
+#endif
+
+
/* Static functions prototypes */
static int check_ptr(const char *where, byte *ptr, const char *sFile,
@@ -89,37 +100,37 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
/*
- * Note: both these refer to the NEW'ed
- * data only. They do not include
- * malloc() roundoff or the extra
- * space required by the remember
- * structures.
- */
-
-#define ALLOC_VAL (uchar) 0xA5 /* NEW'ed memory is filled with this */
- /* value so that references to it will */
- /* end up being very strange. */
-#define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */
- /* value so that references to it will */
- /* also end up being strange. */
+ Note: both these refer to the NEW'ed data only. They do not include
+ malloc() roundoff or the extra space required by the remember
+ structures.
+*/
+/*
+ NEW'ed memory is filled with this value so that references to it will
+ end up being very strange.
+*/
+#define ALLOC_VAL (uchar) 0xA5
+/*
+ FEEE'ed memory is filled with this value so that references to it will
+ end up being very strange.
+*/
+#define FREE_VAL (uchar) 0x8F
#define MAGICKEY 0x14235296 /* A magic value for underrun key */
+
+/*
+ Warning: do not change the MAGICEND? values to something with the
+ high bit set. Various C compilers (like the 4.2bsd one) do not do
+ the sign extension right later on in this code and you will get
+ erroneous errors.
+*/
+
#define MAGICEND0 0x68 /* Magic values for overrun keys */
#define MAGICEND1 0x34 /* " */
#define MAGICEND2 0x7A /* " */
#define MAGICEND3 0x15 /* " */
- /* Warning: do not change the MAGICEND? values to */
- /* something with the high bit set. Various C */
- /* compilers (like the 4.2bsd one) do not do the */
- /* sign extension right later on in this code and */
- /* you will get erroneous errors. */
-
-/*
- * gptr _mymalloc( uint uSize, my_string sFile, uint uLine, MyFlags )
- * Allocate some memory.
- */
+/* Allocate some memory. */
gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
{
@@ -131,9 +142,10 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
if (!sf_malloc_quick)
(void) _sanity (sFile, uLine);
- if(uSize + lCurMemory > safemalloc_mem_limit)
+ if (uSize + lCurMemory > safemalloc_mem_limit)
pTmp = 0;
else
+ {
/* Allocate the physical memory */
pTmp = (struct remember *) malloc (
sizeof (struct irem) /* remember data */
@@ -142,7 +154,7 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
+ 4 /* overrun mark */
+ sf_malloc_endhunc
);
-
+ }
/* Check if there isn't anymore memory avaiable */
if (pTmp == NULL)
{
@@ -175,6 +187,9 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
pTmp -> sFileName = (my_string) sFile;
pTmp -> uLineNum = uLine;
pTmp -> uDataSize = uSize;
+#ifdef THREAD
+ pTmp->thread_id = pthread_self();
+#endif
pTmp -> pPrev = NULL;
/* Add this remember structure to the linked list */
@@ -209,9 +224,9 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
}
/*
- * Allocate some new memory and move old memoryblock there.
- * Free then old memoryblock
- */
+ Allocate some new memory and move old memoryblock there.
+ Free then old memoryblock
+*/
gptr _myrealloc (register gptr pPtr, register uint uSize,
const char *sFile, uint uLine, myf MyFlags)
@@ -242,7 +257,7 @@ gptr _myrealloc (register gptr pPtr, register uint uSize,
DBUG_RETURN((gptr) NULL);
}
- if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */
+ if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */
{
uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */
memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */
@@ -259,10 +274,7 @@ gptr _myrealloc (register gptr pPtr, register uint uSize,
} /* _myrealloc */
-/*
- * void _myfree( my_string pPtr, my_string sFile, uint uLine, myf myflags)
- * Deallocate some memory.
- */
+/* Deallocate some memory. */
void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
{
@@ -281,12 +293,14 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
pRec = (struct remember *) ((byte*) pPtr-sizeof(struct irem)-
sf_malloc_prehunc);
- /* Check to make sure that we have a real remember structure */
- /* Note: this test could fail for four reasons: */
- /* (1) The memory was already free'ed */
- /* (2) The memory was never new'ed */
- /* (3) There was an underrun */
- /* (4) A stray pointer hit this location */
+ /*
+ Check to make sure that we have a real remember structure.
+ Note: this test could fail for four reasons:
+ (1) The memory was already free'ed
+ (2) The memory was never new'ed
+ (3) There was an underrun
+ (4) A stray pointer hit this location
+ */
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
@@ -361,10 +375,22 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
}
+#if !defined(PEDANTIC_SAFEMALLOC) && defined(THREAD)
+static int legal_leak(struct remember* pPtr)
+{
+ /* TODO: This code needs to be made more general */
+ return (pthread_equal(pthread_self(), pPtr->thread_id) ||
+ pthread_equal(main_th, pPtr->thread_id) ||
+ pthread_equal(shutdown_th,pPtr->thread_id) ||
+ pthread_equal(signal_th,pPtr->thread_id));
+}
+#endif /* THREAD */
+
+
/*
- * TERMINATE(FILE *file)
- * Report on all the memory pieces that have not been
- * free'ed as well as the statistics.
+ TERMINATE(FILE *file)
+ Report on all the memory pieces that have not been
+ free'ed as well as the statistics.
*/
void TERMINATE (FILE *file)
@@ -373,10 +399,54 @@ void TERMINATE (FILE *file)
DBUG_ENTER("TERMINATE");
pthread_mutex_lock(&THR_LOCK_malloc);
- /* Report the difference between number of calls to */
- /* NEW and the number of calls to FREE. >0 means more */
- /* NEWs than FREEs. <0, etc. */
-
+ /*
+ Report the difference between number of calls to
+ NEW and the number of calls to FREE. >0 means more
+ NEWs than FREEs. <0, etc.
+ */
+
+#if !defined(PEDANTIC_SAFEMALLOC) && defined(THREAD)
+ /*
+ Avoid false alarms for blocks that we cannot free before my_end()
+ This does miss some positives, but that is ok. This will only miss
+ failures to free things allocated in the main thread which
+ performs only one-time allocations. If you really need to
+ debug memory allocations in the main thread,
+ #define PEDANTIC_SAFEMALLOC
+ */
+ if ((pPtr=pRememberRoot))
+ {
+ while (pPtr)
+ {
+ if (legal_leak(pPtr))
+ {
+ sf_malloc_tampered=1;
+ cNewCount--;
+ lCurMemory -= pPtr->uDataSize;
+ if (pPtr->pPrev)
+ {
+ struct remember* tmp;
+ tmp = pPtr->pPrev->pNext = pPtr->pNext;
+ if (tmp)
+ tmp->pPrev = pPtr->pPrev;
+ pPtr->pNext = pPtr->pPrev = 0;
+ pPtr = tmp;
+ }
+ else
+ {
+ pRememberRoot = pPtr->pNext;
+ pPtr->pNext = pPtr->pPrev = 0;
+ pPtr = pRememberRoot;
+ if (pPtr)
+ pPtr->pPrev=0;
+ }
+ }
+ else
+ pPtr = pPtr->pNext;
+ }
+ }
+#endif
+
if (cNewCount)
{
if (file)
@@ -387,8 +457,10 @@ void TERMINATE (FILE *file)
DBUG_PRINT("safe",("cNewCount: %d",cNewCount));
}
- /* Report on all the memory that was allocated with NEW */
- /* but not free'ed with FREE. */
+ /*
+ Report on all the memory that was allocated with NEW
+ but not free'ed with FREE.
+ */
if ((pPtr=pRememberRoot))
{
@@ -403,10 +475,14 @@ void TERMINATE (FILE *file)
if (file)
{
fprintf (file,
- "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n",
+ "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
pPtr -> uDataSize,
(ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName);
+#ifdef THREAD
+ fprintf(file, " in thread %ld", pPtr->thread_id);
+#endif
+ fprintf(file, "\n");
(void) fflush(file);
}
DBUG_PRINT("safe",
@@ -485,6 +561,10 @@ int _sanity (const char *sFile, uint uLine)
uint count=0;
pthread_mutex_lock(&THR_LOCK_malloc);
+#ifndef PEDANTIC_SAFEMALLOC
+ if (sf_malloc_tampered && cNewCount < 0)
+ cNewCount=0;
+#endif
count=cNewCount;
for (pTmp = pRememberRoot; pTmp != NULL && count-- ; pTmp = pTmp -> pNext)
flag+=_checkchunk (pTmp, sFile, uLine);
@@ -493,6 +573,7 @@ int _sanity (const char *sFile, uint uLine)
{
const char *format="Safemalloc link list destroyed, discovered at '%s:%d'";
fprintf (stderr, format, sFile, uLine); fputc('\n',stderr);
+ fprintf (stderr, "root=%p,count=%d,pTmp=%p\n", pRememberRoot,count,pTmp);
(void) fflush(stderr);
DBUG_PRINT("safe",(format, sFile, uLine));
flag=1;
diff --git a/mysys/sha1.c b/mysys/sha1.c
new file mode 100644
index 00000000000..5271b369b6c
--- /dev/null
+++ b/mysys/sha1.c
@@ -0,0 +1,392 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Original Source from: http://www.faqs.org/rfcs/rfc3174.html
+
+ DESCRIPTION
+ This file implements the Secure Hashing Algorithm 1 as
+ defined in FIPS PUB 180-1 published April 17, 1995.
+
+ The SHA-1, produces a 160-bit message digest for a given data
+ stream. It should take about 2**n steps to find a message with the
+ same digest as a given message and 2**(n/2) to find any two
+ messages with the same digest, when n is the digest size in bits.
+ Therefore, this algorithm can serve as a means of providing a
+ "fingerprint" for a message.
+
+ PORTABILITY ISSUES
+ SHA-1 is defined in terms of 32-bit "words". This code uses
+ <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
+ integer types. If your C compiler does not support 32 bit unsigned
+ integers, this code is not appropriate.
+
+ CAVEATS
+ SHA-1 is designed to work with messages less than 2^64 bits long.
+ Although SHA-1 allows a message digest to be generated for messages
+ of any number of bits less than 2^64, this implementation only
+ works with messages with a length that is a multiple of the size of
+ an 8-bit character.
+
+ CHANGES
+ 2002 by Peter Zaitsev to
+ - fit to new prototypes according to MySQL standard
+ - Some optimizations
+ - All checking is now done in debug only mode
+ - More comments
+*/
+
+#include "my_global.h"
+#include "m_string.h"
+#include "sha1.h"
+
+/*
+ Define the SHA1 circular left shift macro
+*/
+
+#define SHA1CircularShift(bits,word) \
+ (((word) << (bits)) | ((word) >> (32-(bits))))
+
+/* Local Function Prototyptes */
+static void SHA1PadMessage(SHA1_CONTEXT*);
+static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
+
+
+/*
+ Initialize SHA1Context
+
+ SYNOPSIS
+ sha1_reset()
+ context [in/out] The context to reset.
+
+ DESCRIPTION
+ This function will initialize the SHA1Context in preparation
+ for computing a new SHA1 message digest.
+
+ RETURN
+ SHA_SUCCESS ok
+ != SHA_SUCCESS sha Error Code.
+*/
+
+
+const uint32 sha_const_key[5]=
+{
+ 0x67452301,
+ 0xEFCDAB89,
+ 0x98BADCFE,
+ 0x10325476,
+ 0xC3D2E1F0
+};
+
+
+int sha1_reset(SHA1_CONTEXT *context)
+{
+#ifndef DBUG_OFF
+ if (!context)
+ return SHA_NULL;
+#endif
+
+ context->Length = 0;
+ context->Message_Block_Index = 0;
+
+ context->Intermediate_Hash[0] = sha_const_key[0];
+ context->Intermediate_Hash[1] = sha_const_key[1];
+ context->Intermediate_Hash[2] = sha_const_key[2];
+ context->Intermediate_Hash[3] = sha_const_key[3];
+ context->Intermediate_Hash[4] = sha_const_key[4];
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+
+ return SHA_SUCCESS;
+}
+
+
+/*
+ Return the 160-bit message digest into the array provided by the caller
+
+ SYNOPSIS
+ sha1_result()
+ context [in/out] The context to use to calculate the SHA-1 hash.
+ Message_Digest: [out] Where the digest is returned.
+
+ DESCRIPTION
+ NOTE: The first octet of hash is stored in the 0th element,
+ the last octet of hash in the 19th element.
+
+ RETURN
+ SHA_SUCCESS ok
+ != SHA_SUCCESS sha Error Code.
+*/
+
+int sha1_result(SHA1_CONTEXT *context,
+ uint8 Message_Digest[SHA1_HASH_SIZE])
+{
+ int i;
+
+#ifndef DBUG_OFF
+ if (!context || !Message_Digest)
+ return SHA_NULL;
+
+ if (context->Corrupted)
+ return context->Corrupted;
+#endif
+
+ if (!context->Computed)
+ {
+ SHA1PadMessage(context);
+ /* message may be sensitive, clear it out */
+ bzero((char*) context->Message_Block,64);
+ context->Length = 0; /* and clear length */
+ context->Computed = 1;
+ }
+
+ for (i = 0; i < SHA1_HASH_SIZE; i++)
+ Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8
+ * ( 3 - ( i & 0x03 ) )));
+ return SHA_SUCCESS;
+}
+
+
+/*
+ Accepts an array of octets as the next portion of the message.
+
+ SYNOPSIS
+ sha1_input()
+ context [in/out] The SHA context to update
+ message_array An array of characters representing the next portion
+ of the message.
+ length The length of the message in message_array
+
+ RETURN
+ SHA_SUCCESS ok
+ != SHA_SUCCESS sha Error Code.
+*/
+
+int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
+ unsigned length)
+{
+ if (!length)
+ return SHA_SUCCESS;
+
+#ifndef DBUG_OFF
+ /* We assume client konows what it is doing in non-debug mode */
+ if (!context || !message_array)
+ return SHA_NULL;
+ if (context->Computed)
+ return (context->Corrupted= SHA_STATE_ERROR);
+ if (context->Corrupted)
+ return context->Corrupted;
+#endif
+
+ while (length--)
+ {
+ context->Message_Block[context->Message_Block_Index++]=
+ (*message_array & 0xFF);
+ context->Length += 8; /* Length is in bits */
+
+#ifndef DBUG_OFF
+ /*
+ Then we're not debugging we assume we never will get message longer
+ 2^64 bits.
+ */
+ if (context->Length == 0)
+ return (context->Corrupted= 1); /* Message is too long */
+#endif
+
+ if (context->Message_Block_Index == 64)
+ {
+ SHA1ProcessMessageBlock(context);
+ }
+ message_array++;
+ }
+ return SHA_SUCCESS;
+}
+
+
+/*
+ Process the next 512 bits of the message stored in the Message_Block array.
+
+ SYNOPSIS
+ SHA1ProcessMessageBlock()
+
+ DESCRIPTION
+ Many of the variable names in this code, especially the single
+ character names, were used because those were the names used in
+ the publication.
+*/
+
+/* Constants defined in SHA-1 */
+static const uint32 K[]=
+{
+ 0x5A827999,
+ 0x6ED9EBA1,
+ 0x8F1BBCDC,
+ 0xCA62C1D6
+};
+
+
+static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
+{
+ int t; /* Loop counter */
+ uint32 temp; /* Temporary word value */
+ uint32 W[80]; /* Word sequence */
+ uint32 A, B, C, D, E; /* Word buffers */
+ int index;
+
+ /*
+ Initialize the first 16 words in the array W
+ */
+
+ for (t = 0; t < 16; t++)
+ {
+ index=t*4;
+ W[t] = context->Message_Block[index] << 24;
+ W[t] |= context->Message_Block[index + 1] << 16;
+ W[t] |= context->Message_Block[index + 2] << 8;
+ W[t] |= context->Message_Block[index + 3];
+ }
+
+
+ for (t = 16; t < 80; t++)
+ {
+ W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+ }
+
+ A = context->Intermediate_Hash[0];
+ B = context->Intermediate_Hash[1];
+ C = context->Intermediate_Hash[2];
+ D = context->Intermediate_Hash[3];
+ E = context->Intermediate_Hash[4];
+
+ for (t = 0; t < 20; t++)
+ {
+ temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 20; t < 40; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 40; t < 60; t++)
+ {
+ temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
+ K[2]);
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 60; t < 80; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ context->Intermediate_Hash[0] += A;
+ context->Intermediate_Hash[1] += B;
+ context->Intermediate_Hash[2] += C;
+ context->Intermediate_Hash[3] += D;
+ context->Intermediate_Hash[4] += E;
+
+ context->Message_Block_Index = 0;
+}
+
+
+/*
+ Pad message
+
+ SYNOPSIS
+ SHA1PadMessage()
+ context: [in/out] The context to pad
+
+ DESCRIPTION
+ According to the standard, the message must be padded to an even
+ 512 bits. The first padding bit must be a '1'. The last 64 bits
+ represent the length of the original message. All bits in between
+ should be 0. This function will pad the message according to
+ those rules by filling the Message_Block array accordingly. It
+ will also call the ProcessMessageBlock function provided
+ appropriately. When it returns, it can be assumed that the message
+ digest has been computed.
+
+*/
+
+void SHA1PadMessage(SHA1_CONTEXT *context)
+{
+ /*
+ Check to see if the current message block is too small to hold
+ the initial padding bits and length. If so, we will pad the
+ block, process it, and then continue padding into a second
+ block.
+ */
+
+ int i=context->Message_Block_Index;
+
+ if (i > 55)
+ {
+ context->Message_Block[i++] = 0x80;
+ bzero((char*) &context->Message_Block[i],
+ sizeof(context->Message_Block[0])*(64-i));
+ context->Message_Block_Index=64;
+
+ /* This function sets context->Message_Block_Index to zero */
+ SHA1ProcessMessageBlock(context);
+
+ bzero((char*) &context->Message_Block[0],
+ sizeof(context->Message_Block[0])*56);
+ context->Message_Block_Index=56;
+ }
+ else
+ {
+ context->Message_Block[i++] = 0x80;
+ bzero((char*) &context->Message_Block[i],
+ sizeof(context->Message_Block[0])*(56-i));
+ context->Message_Block_Index=56;
+ }
+
+ /*
+ Store the message length as the last 8 octets
+ */
+
+ context->Message_Block[56] = (int8) (context->Length >> 56);
+ context->Message_Block[57] = (int8) (context->Length >> 48);
+ context->Message_Block[58] = (int8) (context->Length >> 40);
+ context->Message_Block[59] = (int8) (context->Length >> 32);
+ context->Message_Block[60] = (int8) (context->Length >> 24);
+ context->Message_Block[61] = (int8) (context->Length >> 16);
+ context->Message_Block[62] = (int8) (context->Length >> 8);
+ context->Message_Block[63] = (int8) (context->Length);
+
+ SHA1ProcessMessageBlock(context);
+}
diff --git a/mysys/string.c b/mysys/string.c
index 96a503c1179..ea747bc9847 100644
--- a/mysys/string.c
+++ b/mysys/string.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for handling strings with can grow dynamicly.
@@ -51,7 +50,7 @@ my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str)
{
- uint length;
+ uint length=0;
DBUG_ENTER("dynstr_set");
if (init_str && (length= (uint) strlen(init_str)+1) > str->max_length)
diff --git a/mysys/test_charset.c b/mysys/test_charset.c
index 6a5183d2cd3..15e46f3ff82 100644
--- a/mysys/test_charset.c
+++ b/mysys/test_charset.c
@@ -1,21 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#include <global.h>
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <mysql_version.h>
diff --git a/mysys/test_dir.c b/mysys/test_dir.c
index fafdde137b6..f3d220e942f 100644
--- a/mysys/test_dir.c
+++ b/mysys/test_dir.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* TODO: Test all functions */
diff --git a/mysys/test_fn.c b/mysys/test_fn.c
index 224b899ebe1..5a0546392ab 100644
--- a/mysys/test_fn.c
+++ b/mysys/test_fn.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
diff --git a/mysys/testhash.c b/mysys/testhash.c
index a8fbf800595..a1d14dc225d 100644
--- a/mysys/testhash.c
+++ b/mysys/testhash.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Test av hash libarary: stor test */
+/* Test of hash library: big test */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <hash.h>
#include <m_string.h>
@@ -37,6 +36,7 @@ static uint16 key1[1000];
#else
my_bool hash_check(HASH *hash);
#endif
+
void free_record(void *record);
static byte *hash2_key(const byte *rec,uint *length,
@@ -46,7 +46,7 @@ static byte *hash2_key(const byte *rec,uint *length,
return (byte*) rec;
}
- /* Huvudprogrammet */
+/* main program */
int main(int argc,char *argv[])
{
@@ -76,7 +76,7 @@ static int do_test()
printf("- Creating hash\n");
if (hash_init(&hash,recant/2,0,6,0,free_record,0))
goto err;
- printf("- Writing records:s\n");
+ printf("- Writing records:\n");
for (i=0 ; i < recant ; i++)
{
@@ -243,8 +243,8 @@ err:
} /* main */
- /* l{ser optioner */
- /* OBS! intierar endast DEBUG - ingen debuggning h{r ! */
+/* read options */
+/* NOTE! DBUG not initialised - no debugging here! */
static int get_options(int argc, char **argv)
{
@@ -265,7 +265,7 @@ static int get_options(int argc, char **argv)
case 'I':
case '?':
printf("%s Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
- puts("TCX Datakonsult AB, by Monty, for your professional use\n");
+ printf("MySQL AB, by Monty\n\n");
printf("Usage: %s [-?ABIKLWv] [-m#] [-t#]\n",progname);
exit(0);
case '#':
@@ -275,9 +275,10 @@ static int get_options(int argc, char **argv)
}
}
return 0;
-} /* get options */
+} /* get_options */
+
- /* Ge ett randomv{rde inom ett intervall 0 <=x <= n */
+/* Get a random number in the interval 0 <= x <= n */
static int rnd(int max_value)
{
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index f51f27b7f51..c75b43ad0fc 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -1,21 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-#include <global.h>
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* To avoid problems with alarms in debug code, we disable DBUG here */
+#undef DBUG_OFF
+#define DBUG_OFF
+#include <my_global.h>
#if defined(THREAD) && !defined(DONT_USE_THR_ALARM)
#include <errno.h>
@@ -42,6 +44,7 @@ my_bool thr_alarm_inited=0;
static pthread_mutex_t LOCK_alarm;
static sigset_t full_signal_set;
static QUEUE alarm_queue;
+static uint max_used_alarms=0;
pthread_t alarm_thread;
#ifdef USE_ALARM_THREAD
@@ -114,10 +117,10 @@ void init_thr_alarm(uint max_alarms)
}
/*
-** Request alarm after sec seconds.
-** A pointer is returned with points to a non-zero int when the alarm has been
-** given. This can't be called from the alarm-handling thread.
-** Returns 0 if no more alarms are allowed (aborted by process)
+ Request alarm after sec seconds.
+ A pointer is returned with points to a non-zero int when the alarm has been
+ given. This can't be called from the alarm-handling thread.
+ Returns 0 if no more alarms are allowed (aborted by process)
*/
bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
@@ -138,13 +141,17 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
DBUG_RETURN(1);
}
- if (alarm_queue.elements == alarm_queue.max_elements)
+ if (alarm_queue.elements >= max_used_alarms)
{
- DBUG_PRINT("info", ("alarm queue full"));
- fprintf(stderr,"Warning: thr_alarm queue is full\n");
- pthread_mutex_unlock(&LOCK_alarm);
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
- DBUG_RETURN(1);
+ if (alarm_queue.elements == alarm_queue.max_elements)
+ {
+ DBUG_PRINT("info", ("alarm queue full"));
+ fprintf(stderr,"Warning: thr_alarm queue is full\n");
+ pthread_mutex_unlock(&LOCK_alarm);
+ pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+ DBUG_RETURN(1);
+ }
+ max_used_alarms=alarm_queue.elements+1;
}
reschedule= (!alarm_queue.elements ||
(int) (((ALARM*) queue_top(&alarm_queue))->expire_time - now) >
@@ -184,7 +191,7 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
/*
-** Remove alarm from list of alarms
+ Remove alarm from list of alarms
*/
void thr_end_alarm(thr_alarm_t *alarmed)
@@ -225,13 +232,13 @@ void thr_end_alarm(thr_alarm_t *alarmed)
DBUG_VOID_RETURN;
}
- /*
- Come here when some alarm in queue is due.
- Mark all alarms with are finnished in list.
- Shedule alarms to be sent again after 1-10 sec (many alarms at once)
- If alarm_aborted is set then all alarms are given and resent
- every second.
- */
+/*
+ Come here when some alarm in queue is due.
+ Mark all alarms with are finnished in list.
+ Shedule alarms to be sent again after 1-10 sec (many alarms at once)
+ If alarm_aborted is set then all alarms are given and resent
+ every second.
+*/
sig_handler process_alarm(int sig __attribute__((unused)))
{
@@ -332,8 +339,8 @@ sig_handler process_alarm(int sig __attribute__((unused)))
/*
-** Shedule all alarms now.
-** When all alarms are given, Free alarm memory and don't allow more alarms.
+ Shedule all alarms now.
+ When all alarms are given, Free alarm memory and don't allow more alarms.
*/
void end_thr_alarm(void)
@@ -357,7 +364,7 @@ void end_thr_alarm(void)
/*
-** Remove another thread from the alarm
+ Remove another thread from the alarm
*/
void thr_alarm_kill(pthread_t thread_id)
@@ -380,9 +387,25 @@ void thr_alarm_kill(pthread_t thread_id)
}
+void thr_alarm_info(ALARM_INFO *info)
+{
+ pthread_mutex_lock(&LOCK_alarm);
+ info->next_alarm_time= 0;
+ info->max_used_alarms= max_used_alarms;
+ if ((info->active_alarms= alarm_queue.elements))
+ {
+ ulong now=(ulong) time((time_t*) 0);
+ long time_diff;
+ ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
+ time_diff= (long) (alarm_data->expire_time - now);
+ info->next_alarm_time= (ulong) (time_diff < 0 ? 0 : time_diff);
+ }
+ pthread_mutex_unlock(&LOCK_alarm);
+}
+
/*
-** This is here for thread to get interruptet from read/write/fcntl
-** ARGSUSED
+ This is here for thread to get interruptet from read/write/fcntl
+ ARGSUSED
*/
#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD)
@@ -457,7 +480,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
#endif /* USE_ALARM_THREAD */
/*****************************************************************************
-** thr_alarm for OS/2
+ thr_alarm for OS/2
*****************************************************************************/
#elif defined(__EMX__) || defined(OS2)
@@ -488,7 +511,7 @@ sig_handler process_alarm(int sig __attribute__((unused)))
/*
-** Remove another thread from the alarm
+ Remove another thread from the alarm
*/
void thr_alarm_kill(pthread_t thread_id)
@@ -586,8 +609,14 @@ void init_thr_alarm(uint max_alarm)
DBUG_VOID_RETURN;
}
+void thr_alarm_info(ALARM_INFO *info)
+{
+ bzero((char*) info, sizeof(*info));
+}
+
+
/*****************************************************************************
-** thr_alarm for win95
+ thr_alarm for win95
*****************************************************************************/
#else /* __WIN__ */
@@ -659,13 +688,18 @@ void init_thr_alarm(uint max_alarm)
DBUG_VOID_RETURN;
}
+void thr_alarm_info(ALARM_INFO *info)
+{
+ bzero((char*) info, sizeof(*info));
+}
+
#endif /* __WIN__ */
#endif /* THREAD */
/****************************************************************************
-** Handling of MAIN
+ Handling of test case (when compiled with -DMAIN)
***************************************************************************/
#ifdef MAIN
@@ -865,6 +899,7 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
pthread_attr_t thr_attr;
int i,*param,error;
sigset_t set;
+ ALARM_INFO alarm_info;
MY_INIT(argv[0]);
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
@@ -925,6 +960,10 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
pthread_attr_destroy(&thr_attr);
pthread_mutex_lock(&LOCK_thread_count);
+ thr_alarm_info(&alarm_info);
+ printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n",
+ alarm_info.active_alarms, alarm_info.max_used_alarms,
+ alarm_info.next_alarm_time);
while (thread_count)
{
VOID(pthread_cond_wait(&COND_thread_count,&LOCK_thread_count));
@@ -935,6 +974,10 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
}
}
pthread_mutex_unlock(&LOCK_thread_count);
+ thr_alarm_info(&alarm_info);
+ printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n",
+ alarm_info.active_alarms, alarm_info.max_used_alarms,
+ alarm_info.next_alarm_time);
printf("Test succeeded\n");
return 0;
}
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index aa50877072d..0288c7c1cbe 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Read and write locks for Posix threads. All tread must acquire
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index fa7ae4f1e82..4493c54069f 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This makes a wrapper for mutex handling to make it easier to debug mutex */
-#include <global.h>
+#include <my_global.h>
#if defined(HAVE_LINUXTHREADS) && !defined (__USE_UNIX98)
#define __USE_UNIX98 /* To get rw locks under Linux */
#endif
@@ -70,7 +69,8 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
}
if (mp->count++)
{
- fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 time\n", file,line);
+ fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, \
+line %d more than 1 time\n", file,line);
fflush(stderr);
abort();
}
@@ -108,7 +108,7 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
error=pthread_mutex_unlock(&mp->mutex);
if (error)
{
- fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %d\n", error, file, line);
+ fprintf(stderr,"safe_mutex: Got error: %d (%d) when trying to unlock mutex at %s, line %d\n", error, errno, file, line);
fflush(stderr);
abort();
}
@@ -149,7 +149,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
pthread_mutex_lock(&mp->global);
if (error)
{
- fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_wait at %s, line %d\n", error, file, line);
+ fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_wait at %s, line %d\n", error, errno, file, line);
fflush(stderr);
abort();
}
@@ -187,15 +187,15 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
#ifdef EXTRA_DEBUG
if (error && (error != EINTR && error != ETIMEDOUT))
{
- fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_timedwait at %s, line %d\n", error, file, line);
+ fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_timedwait at %s, line %d\n", error, errno, file, line);
}
#endif
pthread_mutex_lock(&mp->global);
if (mp->count++)
{
fprintf(stderr,
- "safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d)\n",
- mp->count-1, my_thread_id(), file, line, error);
+ "safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d (%d))\n",
+ mp->count-1, my_thread_id(), file, line, error, error);
fflush(stderr);
abort();
}
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index 866948a1c23..f1f70b5c4ac 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -1,30 +1,31 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Synchronization - readers / writer thread locks */
#include "mysys_priv.h"
#include <my_pthread.h>
#if defined(THREAD) && !defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && !defined(HAVE_RWLOCK_INIT)
+#include <errno.h>
/*
- * Source base from Sun Microsystems SPILT, simplified
- * for MySQL use -- Joshua Chamas
- */
+ Source base from Sun Microsystems SPILT, simplified for MySQL use
+ -- Joshua Chamas
+ Some cleanup and additional code by Monty
+*/
/*
* Multithreaded Demo Source
@@ -59,7 +60,7 @@
* Mountain View, California 94043
*/
-int my_rwlock_init( rw_lock_t *rwp, void *arg __attribute__((unused)))
+int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
{
pthread_condattr_t cond_attr;
@@ -72,64 +73,101 @@ int my_rwlock_init( rw_lock_t *rwp, void *arg __attribute__((unused)))
rwp->state = 0;
rwp->waiters = 0;
- return( 0 );
+ return(0);
}
-int my_rwlock_destroy( rw_lock_t *rwp ) {
+
+int my_rwlock_destroy(rw_lock_t *rwp)
+{
pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers );
pthread_cond_destroy( &rwp->writers );
-
- return( 0 );
+ return(0);
}
-int my_rw_rdlock( rw_lock_t *rwp ) {
+
+int my_rw_rdlock(rw_lock_t *rwp)
+{
pthread_mutex_lock(&rwp->lock);
- /* active or queued writers */
- while ( ( rwp->state < 0 ) || rwp->waiters )
+ /* active or queued writers */
+ while (( rwp->state < 0 ) || rwp->waiters)
pthread_cond_wait( &rwp->readers, &rwp->lock);
rwp->state++;
pthread_mutex_unlock(&rwp->lock);
+ return(0);
+}
- return( 0 );
+int my_rw_tryrdlock(rw_lock_t *rwp)
+{
+ int res;
+ pthread_mutex_lock(&rwp->lock);
+ if ((rwp->state < 0 ) || rwp->waiters)
+ res= EBUSY; /* Can't get lock */
+ else
+ {
+ res=0;
+ rwp->state++;
+ }
+ pthread_mutex_unlock(&rwp->lock);
+ return(res);
}
-int my_rw_wrlock( rw_lock_t *rwp ) {
+int my_rw_wrlock(rw_lock_t *rwp)
+{
pthread_mutex_lock(&rwp->lock);
- rwp->waiters++; /* another writer queued */
+ rwp->waiters++; /* another writer queued */
- while ( rwp->state )
- pthread_cond_wait( &rwp->writers, &rwp->lock);
+ while (rwp->state)
+ pthread_cond_wait(&rwp->writers, &rwp->lock);
rwp->state = -1;
- --rwp->waiters;
- pthread_mutex_unlock( &rwp->lock );
+ rwp->waiters--;
+ pthread_mutex_unlock(&rwp->lock);
+ return(0);
+}
- return( 0 );
+
+int my_rw_trywrlock(rw_lock_t *rwp)
+{
+ int res;
+ pthread_mutex_lock(&rwp->lock);
+ if (rwp->state)
+ res= EBUSY; /* Can't get lock */
+ else
+ {
+ res=0;
+ rwp->state = -1;
+ }
+ pthread_mutex_unlock(&rwp->lock);
+ return(res);
}
-int my_rw_unlock( rw_lock_t *rwp ) {
+
+int my_rw_unlock(rw_lock_t *rwp)
+{
DBUG_PRINT("rw_unlock",
("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock);
- if ( rwp->state == -1 ) { /* writer releasing */
- rwp->state = 0; /* mark as available */
+ if (rwp->state == -1) /* writer releasing */
+ {
+ rwp->state= 0; /* mark as available */
- if ( rwp->waiters ) /* writers queued */
+ if ( rwp->waiters ) /* writers queued */
pthread_cond_signal( &rwp->writers );
else
pthread_cond_broadcast( &rwp->readers );
- } else {
- if ( --rwp->state == 0 ) /* no more readers */
+ }
+ else
+ {
+ if ( --rwp->state == 0 ) /* no more readers */
pthread_cond_signal( &rwp->writers );
}
pthread_mutex_unlock( &rwp->lock );
-
- return( 0 );
+ return(0);
}
#endif
diff --git a/mysys/tree.c b/mysys/tree.c
index cd05a17fd72..2ac2c88fd66 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for handling red-black (balanced) binary trees.
@@ -62,28 +61,35 @@ static void rb_delete_fixup(TREE *tree,TREE_ELEMENT ***parent);
/* The actuall code for handling binary trees */
-void init_tree(TREE *tree, uint default_alloc_size, int size,
- qsort_cmp compare, my_bool with_delete,
- void (*free_element) (void *))
+#ifndef DBUG_OFF
+static int test_rb_tree(TREE_ELEMENT *element);
+#endif
+
+void init_tree(TREE *tree, uint default_alloc_size, uint memory_limit,
+ int size, qsort_cmp2 compare, my_bool with_delete,
+ tree_element_free free_element, void *custom_arg)
{
DBUG_ENTER("init_tree");
DBUG_PRINT("enter",("tree: %lx size: %d",tree,size));
- if (!default_alloc_size)
- default_alloc_size= DEFAULT_ALLOC_SIZE;
+ if (!default_alloc_size)
+ default_alloc_size= DEFAULT_ALLOC_SIZE;
bzero((gptr) &tree->null_element,sizeof(tree->null_element));
tree->root= &tree->null_element;
tree->compare=compare;
tree->size_of_element=size > 0 ? (uint) size : 0;
+ tree->memory_limit=memory_limit;
tree->free=free_element;
+ tree->allocated=0;
tree->elements_in_tree=0;
+ tree->custom_arg = custom_arg;
tree->null_element.colour=BLACK;
tree->null_element.left=tree->null_element.right=0;
if (!free_element && size >= 0 &&
((uint) size <= sizeof(void*) || ((uint) size & (sizeof(void*)-1))))
{
tree->offset_to_key=sizeof(TREE_ELEMENT); /* Put key after element */
- /* Fix allocation size so that we don't loose any memory */
+ /* Fix allocation size so that we don't lose any memory */
default_alloc_size/=(sizeof(TREE_ELEMENT)+size);
if (!default_alloc_size)
default_alloc_size=1;
@@ -102,9 +108,9 @@ void init_tree(TREE *tree, uint default_alloc_size, int size,
DBUG_VOID_RETURN;
}
-void delete_tree(TREE *tree)
+static void free_tree(TREE *tree, myf free_flags)
{
- DBUG_ENTER("delete_tree");
+ DBUG_ENTER("free_tree");
DBUG_PRINT("enter",("tree: %lx",tree));
if (tree->root) /* If initialized */
@@ -114,24 +120,43 @@ void delete_tree(TREE *tree)
else
{
if (tree->free)
+ {
+ if (tree->memory_limit)
+ (*tree->free)(NULL, free_init, tree->custom_arg);
delete_tree_element(tree,tree->root);
- free_root(&tree->mem_root,MYF(0));
+ if (tree->memory_limit)
+ (*tree->free)(NULL, free_end, tree->custom_arg);
+ }
+ free_root(&tree->mem_root, free_flags);
}
}
tree->root= &tree->null_element;
tree->elements_in_tree=0;
+ tree->allocated=0;
DBUG_VOID_RETURN;
}
+void delete_tree(TREE* tree)
+{
+ free_tree(tree, MYF(0)); /* my_free() mem_root if applicable */
+}
+
+void reset_tree(TREE* tree)
+{
+ free_tree(tree, MYF(MY_MARK_BLOCKS_FREE));
+ /* do not my_free() mem_root if applicable, just mark blocks as free */
+}
+
+
static void delete_tree_element(TREE *tree, TREE_ELEMENT *element)
{
if (element != &tree->null_element)
{
delete_tree_element(tree,element->left);
- delete_tree_element(tree,element->right);
if (tree->free)
- (*tree->free)(ELEMENT_KEY(tree,element));
+ (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
+ delete_tree_element(tree,element->right);
if (tree->with_delete)
my_free((char*) element,MYF(0));
}
@@ -152,7 +177,8 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
for (;;)
{
if (element == &tree->null_element ||
- (cmp=(*tree->compare)(ELEMENT_KEY(tree,element),key)) == 0)
+ (cmp=(*tree->compare)(tree->custom_arg,
+ ELEMENT_KEY(tree,element),key)) == 0)
break;
if (cmp < 0)
{
@@ -165,13 +191,22 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
}
if (element == &tree->null_element)
{
+ uint alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
+ tree->allocated+=alloc_size;
+
+ if (tree->memory_limit && tree->elements_in_tree
+ && tree->allocated > tree->memory_limit)
+ {
+ reset_tree(tree);
+ return tree_insert(tree, key, key_size);
+ }
+
key_size+=tree->size_of_element;
if (tree->with_delete)
- element=(TREE_ELEMENT *) my_malloc(sizeof(TREE_ELEMENT)+key_size,
- MYF(MY_WME));
+ element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME));
else
element=(TREE_ELEMENT *)
- alloc_root(&tree->mem_root,sizeof(TREE_ELEMENT)+key_size);
+ alloc_root(&tree->mem_root,alloc_size);
if (!element)
return(NULL);
**parent=element;
@@ -195,6 +230,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
}
else
element->count++;
+ DBUG_EXECUTE("check_tree", test_rb_tree(tree->root););
return element;
}
@@ -212,7 +248,8 @@ int tree_delete(TREE *tree, void *key)
{
if (element == &tree->null_element)
return 1; /* Was not in tree */
- if ((cmp=(*tree->compare)(ELEMENT_KEY(tree,element),key)) == 0)
+ if ((cmp=(*tree->compare)(tree->custom_arg,
+ ELEMENT_KEY(tree,element),key)) == 0)
break;
if (cmp < 0)
{
@@ -252,7 +289,7 @@ int tree_delete(TREE *tree, void *key)
if (remove_colour == BLACK)
rb_delete_fixup(tree,parent);
if (tree->free)
- (*tree->free)(ELEMENT_KEY(tree,element));
+ (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
my_free((gptr) element,MYF(0));
tree->elements_in_tree--;
return 0;
@@ -268,7 +305,8 @@ void *tree_search(TREE *tree, void *key)
{
if (element == &tree->null_element)
return (void*) 0;
- if ((cmp=(*tree->compare)(ELEMENT_KEY(tree,element),key)) == 0)
+ if ((cmp=(*tree->compare)(tree->custom_arg,
+ ELEMENT_KEY(tree,element),key)) == 0)
return ELEMENT_KEY(tree,element);
if (cmp < 0)
element=element->right;
@@ -484,8 +522,7 @@ static void rb_delete_fixup(TREE *tree, TREE_ELEMENT ***parent)
x->colour=BLACK;
}
-
-#ifdef TESTING_TREES
+#ifndef DBUG_OFF
/* Test that the proporties for a red-black tree holds */
@@ -511,5 +548,4 @@ static int test_rb_tree(TREE_ELEMENT *element)
}
return -1;
}
-
#endif
diff --git a/mysys/typelib.c b/mysys/typelib.c
index b18959442ae..e2c8eade5c8 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions to handle typelib */
@@ -84,7 +83,8 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name)
/* Get name of type nr 'nr' */
/* Warning first type is 1, 0 = empty field */
-void make_type(register my_string to, register uint nr, register TYPELIB *typelib)
+void make_type(register my_string to, register uint nr,
+ register TYPELIB *typelib)
{
DBUG_ENTER("make_type");
if (!nr)
diff --git a/pstack/Makefile.am b/pstack/Makefile.am
new file mode 100644
index 00000000000..863a52f4488
--- /dev/null
+++ b/pstack/Makefile.am
@@ -0,0 +1,36 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# As pstack doesn't work on all configurations, we have to use
+# the USE_PSTACK hack to get all files into distribution
+#
+
+SUBDIRS = aout
+INCLUDES = -I$(srcdir)/../include -I../include
+noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \
+ linuxthreads.h pstack.h pstacktrace.h
+SRC= bucomm.c filemode.c linuxthreads.c rddbg.c \
+ debug.c ieee.c pstack.c stabs.c
+EXTRA_DIST= $(SRC)
+
+if COMPILE_PSTACK
+pkglib_LIBRARIES = libpstack.a
+libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c debug.c ieee.c pstack.c stabs.c
+endif
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/pstack/aout/Makefile.am b/pstack/aout/Makefile.am
new file mode 100644
index 00000000000..0b02cb7b643
--- /dev/null
+++ b/pstack/aout/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS = aout64.h stab.def stab_gnu.h
diff --git a/pstack/aout/aout64.h b/pstack/aout/aout64.h
new file mode 100644
index 00000000000..76f1140b682
--- /dev/null
+++ b/pstack/aout/aout64.h
@@ -0,0 +1,475 @@
+/* `a.out' object-file definitions, including extensions to 64-bit fields */
+
+#ifndef __A_OUT_64_H__
+#define __A_OUT_64_H__
+
+/* This is the layout on disk of the 32-bit or 64-bit exec header. */
+
+#ifndef external_exec
+struct external_exec
+{
+ bfd_byte e_info[4]; /* magic number and stuff */
+ bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */
+ bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */
+ bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */
+ bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */
+ bfd_byte e_entry[BYTES_IN_WORD]; /* start address */
+ bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */
+ bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */
+};
+
+#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7)
+
+/* Magic numbers for a.out files */
+
+#if ARCH_SIZE==64
+#define OMAGIC 0x1001 /* Code indicating object file */
+#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */
+#define NMAGIC 0x1003 /* Code indicating pure executable. */
+
+/* There is no 64-bit QMAGIC as far as I know. */
+
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+#else
+#define OMAGIC 0407 /* ...object file or impure executable. */
+#define NMAGIC 0410 /* Code indicating pure executable. */
+#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
+#define BMAGIC 0415 /* Used by a b.out object. */
+
+/* This indicates a demand-paged executable with the header in the text.
+ It is used by 386BSD (and variants) and Linux, at least. */
+#ifndef QMAGIC
+#define QMAGIC 0314
+#endif
+# ifndef N_BADMAG
+# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC \
+ && N_MAGIC(x) != QMAGIC)
+# endif /* N_BADMAG */
+#endif
+
+#endif
+
+#ifdef QMAGIC
+#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC)
+#else
+#define N_IS_QMAGIC(x) (0)
+#endif
+
+/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is
+ the finest granularity at which you can page something, thus it
+ controls the padding (if any) before the text segment of a ZMAGIC
+ file. N_SEGSIZE is the resolution at which things can be marked as
+ read-only versus read/write, so it controls the padding between the
+ text segment and the data segment (in memory; on disk the padding
+ between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same
+ for most machines, but different for sun3. */
+
+/* By default, segment size is constant. But some machines override this
+ to be a function of the a.out header (e.g. machine type). */
+
+#ifndef N_SEGSIZE
+#define N_SEGSIZE(x) SEGMENT_SIZE
+#endif
+
+/* Virtual memory address of the text section.
+ This is getting very complicated. A good reason to discard a.out format
+ for something that specifies these fields explicitly. But til then...
+
+ * OMAGIC and NMAGIC files:
+ (object files: text for "relocatable addr 0" right after the header)
+ start at 0, offset is EXEC_BYTES_SIZE, size as stated.
+ * The text address, offset, and size of ZMAGIC files depend
+ on the entry point of the file:
+ * entry point below TEXT_START_ADDR:
+ (hack for SunOS shared libraries)
+ start at 0, offset is 0, size as stated.
+ * If N_HEADER_IN_TEXT(x) is true (which defaults to being the
+ case when the entry point is EXEC_BYTES_SIZE or further into a page):
+ no padding is needed; text can start after exec header. Sun
+ considers the text segment of such files to include the exec header;
+ for BFD's purposes, we don't, which makes more work for us.
+ start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE,
+ size as stated minus EXEC_BYTES_SIZE.
+ * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when
+ the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page
+ aligned)): (padding is needed so that text can start at a page boundary)
+ start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated.
+
+ Specific configurations may want to hardwire N_HEADER_IN_TEXT,
+ for efficiency or to allow people to play games with the entry point.
+ In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos,
+ and as 0 for most other hosts (Sony News, Vax Ultrix, etc).
+ (Do this in the appropriate bfd target file.)
+ (The default is a heuristic that will break if people try changing
+ the entry point, perhaps with the ld -e flag.)
+
+ * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true,
+ and for which the starting address is TARGET_PAGE_SIZE (or should this be
+ SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC).
+ */
+
+/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header
+ in the text. */
+#ifndef N_HEADER_IN_TEXT
+#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
+#endif
+
+/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC
+ files. */
+#ifndef N_SHARED_LIB
+#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR)
+#endif
+
+/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on
+ the assumption that we are dealing with a .o file, not an
+ executable. This is necessary for OMAGIC (but means we don't work
+ right on the output from ld -N); more questionable for NMAGIC. */
+
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) \
+ (/* The address of a QMAGIC file is always one page in, */ \
+ /* with the header in the text. */ \
+ N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \
+ N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\
+ N_SHARED_LIB(x) ? 0 : \
+ N_HEADER_IN_TEXT(x) ? \
+ TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\
+ TEXT_START_ADDR /* a page of padding */\
+ )
+#endif
+
+/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding
+ to make the text segment start at a certain boundary. For most
+ systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the
+ time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is
+ not what TARGET_PAGE_SIZE needs to be for QMAGIC. */
+
+#ifndef ZMAGIC_DISK_BLOCK_SIZE
+#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE
+#endif
+
+#define N_DISK_BLOCK_SIZE(x) \
+ (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE)
+
+/* Offset in an a.out of the start of the text section. */
+#ifndef N_TXTOFF
+#define N_TXTOFF(x) \
+ (/* For {O,N,Q}MAGIC, no padding. */ \
+ N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \
+ N_SHARED_LIB(x) ? 0 : \
+ N_HEADER_IN_TEXT(x) ? \
+ EXEC_BYTES_SIZE : /* no padding */\
+ ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\
+ )
+#endif
+/* Size of the text section. It's always as stated, except that we
+ offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF
+ for ZMAGIC files that nominally include the exec header
+ as part of the first page of text. (BFD doesn't consider the
+ exec header to be part of the text segment.) */
+#ifndef N_TXTSIZE
+#define N_TXTSIZE(x) \
+ (/* For QMAGIC, we don't consider the header part of the text section. */\
+ N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \
+ (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \
+ N_HEADER_IN_TEXT(x) ? \
+ (x).a_text - EXEC_BYTES_SIZE: /* no padding */\
+ (x).a_text /* a page of padding */\
+ )
+#endif
+/* The address of the data segment in virtual memory.
+ It is the text segment address, plus text segment size, rounded
+ up to a N_SEGSIZE boundary for pure or pageable files. */
+#ifndef N_DATADDR
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \
+ : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1))))
+#endif
+/* The address of the BSS segment -- immediately after the data segment. */
+
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+
+/* Offsets of the various portions of the file after the text segment. */
+
+/* For {Q,Z}MAGIC, there is padding to make the data segment start on
+ a page boundary. Most of the time the a_text field (and thus
+ N_TXTSIZE) already contains this padding. It is possible that for
+ BSDI and/or 386BSD it sometimes doesn't contain the padding, and
+ perhaps we should be adding it here. But this seems kind of
+ questionable and probably should be BSDI/386BSD-specific if we do
+ do it.
+
+ For NMAGIC (at least for hp300 BSD, probably others), there is
+ padding in memory only, not on disk, so we must *not* ever pad here
+ for NMAGIC. */
+
+#ifndef N_DATOFF
+#define N_DATOFF(x) \
+ (N_TXTOFF(x) + N_TXTSIZE(x))
+#endif
+
+#ifndef N_TRELOFF
+#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
+#endif
+#ifndef N_DRELOFF
+#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#endif
+#ifndef N_SYMOFF
+#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
+#endif
+#ifndef N_STROFF
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#endif
+
+/* Symbols */
+#ifndef external_nlist
+struct external_nlist {
+ bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */
+ bfd_byte e_type[1]; /* type of symbol */
+ bfd_byte e_other[1]; /* misc info (usually empty) */
+ bfd_byte e_desc[2]; /* description field */
+ bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */
+};
+#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
+#endif
+
+struct internal_nlist {
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
+};
+
+/* The n_type field is the symbol type, containing: */
+
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol -- defined at particular addr */
+#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
+#define N_DATA 6 /* Data sym -- defined at offset in data seg */
+#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
+#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
+#define N_FN 0x1f /* File name of .o file */
+#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
+/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
+ N_DATA, or N_BSS. When the low-order bit of other types is set,
+ (e.g. N_WARNING versus N_FN), they are two different types. */
+#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
+#define N_TYPE 0x1e
+#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */
+
+#define N_INDR 0x0a
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ elements value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+/* Warning symbol. The text gives a warning message, the next symbol
+ in the table will be undefined. When the symbol is referenced, the
+ message is printed. */
+
+#define N_WARNING 0x1e
+
+/* Weak symbols. These are a GNU extension to the a.out format. The
+ semantics are those of ELF weak symbols. Weak symbols are always
+ externally visible. The N_WEAK? values are squeezed into the
+ available slots. The value of a N_WEAKU symbol is 0. The values
+ of the other types are the definitions. */
+#define N_WEAKU 0x0d /* Weak undefined symbol. */
+#define N_WEAKA 0x0e /* Weak absolute symbol. */
+#define N_WEAKT 0x0f /* Weak text symbol. */
+#define N_WEAKD 0x10 /* Weak data symbol. */
+#define N_WEAKB 0x11 /* Weak bss symbol. */
+
+/* Relocations
+
+ There are two types of relocation flavours for a.out systems,
+ standard and extended. The standard form is used on systems where the
+ instruction has room for all the bits of an offset to the operand, whilst
+ the extended form is used when an address operand has to be split over n
+ instructions. Eg, on the 68k, each move instruction can reference
+ the target with a displacement of 16 or 32 bits. On the sparc, move
+ instructions use an offset of 14 bits, so the offset is stored in
+ the reloc field, and the data in the section is ignored.
+*/
+
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct reloc_std_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+};
+
+#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80)
+#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01)
+
+#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60)
+#define RELOC_STD_BITS_LENGTH_SH_BIG 5
+#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06)
+#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
+
+#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10)
+#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08)
+
+#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08)
+#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10)
+
+#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04)
+#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20)
+
+#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02)
+#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40)
+
+#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
+
+struct reloc_std_internal
+{
+ bfd_vma r_address; /* Address (within segment) to be relocated. */
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in files the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* The next three bits are for SunOS shared libraries, and seem to
+ be undocumented. */
+ unsigned int r_baserel:1; /* Linkage table relative */
+ unsigned int r_jmptable:1; /* pc-relative to jump table */
+ unsigned int r_relative:1; /* "relative relocation" */
+ /* unused */
+ unsigned int r_pad:1; /* Padding -- set to zero */
+};
+
+
+/* EXTENDED RELOCS */
+
+struct reloc_ext_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+ bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
+};
+
+#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80)
+#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01)
+
+#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F)
+#define RELOC_EXT_BITS_TYPE_SH_BIG 0
+#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8)
+#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
+
+/* Bytes per relocation entry */
+#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
+
+enum reloc_type
+{
+ /* simple relocations */
+ RELOC_8, /* data[0:7] = addend + sv */
+ RELOC_16, /* data[0:15] = addend + sv */
+ RELOC_32, /* data[0:31] = addend + sv */
+ /* pc-rel displacement */
+ RELOC_DISP8, /* data[0:7] = addend - pc + sv */
+ RELOC_DISP16, /* data[0:15] = addend - pc + sv */
+ RELOC_DISP32, /* data[0:31] = addend - pc + sv */
+ /* Special */
+ RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */
+ RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */
+ RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */
+ RELOC_22, /* data[0:21] = (addend + sv) */
+ RELOC_13, /* data[0:12] = (addend + sv) */
+ RELOC_LO10, /* data[0:9] = (addend + sv) */
+ RELOC_SFA_BASE,
+ RELOC_SFA_OFF13,
+ /* P.I.C. (base-relative) */
+ RELOC_BASE10, /* Not sure - maybe we can do this the */
+ RELOC_BASE13, /* right way now */
+ RELOC_BASE22,
+ /* for some sort of pc-rel P.I.C. (?) */
+ RELOC_PC10,
+ RELOC_PC22,
+ /* P.I.C. jump table */
+ RELOC_JMP_TBL,
+ /* reputedly for shared libraries somehow */
+ RELOC_SEGOFF16,
+ RELOC_GLOB_DAT,
+ RELOC_JMP_SLOT,
+ RELOC_RELATIVE,
+
+ RELOC_11,
+ RELOC_WDISP2_14,
+ RELOC_WDISP19,
+ RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */
+ RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */
+
+ /* 29K relocation types */
+ RELOC_JUMPTARG,
+ RELOC_CONST,
+ RELOC_CONSTH,
+
+ /* All the new ones I can think of, for sparc v9 */
+
+ RELOC_64, /* data[0:63] = addend + sv */
+ RELOC_DISP64, /* data[0:63] = addend - pc + sv */
+ RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */
+ RELOC_DISP21, /* data[0:20] = addend - pc + sv */
+ RELOC_DISP14, /* data[0:13] = addend - pc + sv */
+ /* Q .
+ What are the other ones,
+ Since this is a clean slate, can we throw away the ones we dont
+ understand ? Should we sort the values ? What about using a
+ microcode format like the 68k ?
+ */
+ NO_RELOC
+ };
+
+
+struct reloc_internal {
+ bfd_vma r_address; /* offset of of data to relocate */
+ long r_index; /* symbol table index of symbol */
+ enum reloc_type r_type; /* relocation type */
+ bfd_vma r_addend; /* datum addend */
+};
+
+/* Q.
+ Should the length of the string table be 4 bytes or 8 bytes ?
+
+ Q.
+ What about archive indexes ?
+
+ */
+
+#endif /* __A_OUT_64_H__ */
diff --git a/pstack/aout/stab.def b/pstack/aout/stab.def
new file mode 100644
index 00000000000..3c6b456d3a9
--- /dev/null
+++ b/pstack/aout/stab.def
@@ -0,0 +1,264 @@
+/* Table of DBX symbol codes for the GNU system.
+ Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files
+ overlaps the N_UNDF used for ordinary symbols. In ELF files, the
+ debug information is in a different file section, so there is no conflict.
+ This symbol's n_value gives the size of the string section associated
+ with this file. The symbol's n_strx (relative to the just-updated
+ string section start address) gives the name of the source file,
+ e.g. "foo.c", without any path information. The symbol's n_desc gives
+ the count of upcoming symbols associated with this file (not including
+ this one). */
+/* __define_stab (N_UNDF, 0x00, "UNDF") */
+
+/* Global variable. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C. Value is its address.
+ Desc is supposedly starting line number, but GCC doesn't set it
+ and DBX seems not to miss it. */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage. Value is its address.
+ "Static Sym". */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage. Value is its address. */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine. Only the name is significant. */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Solaris2: Read-only data symbols. */
+__define_stab (N_ROSYM, 0x2c, "ROSYM")
+
+/* Global symbol in Pascal.
+ Supposedly the value is its line number; I'm skeptical. */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris 2. Like N_SO, but for the object file. Two in
+ a row provide the build directory and the relative path of the .o from it.
+ Solaris2 uses this to avoid putting the stabs info into the linked
+ executable; this stab goes into the ".stab.index" section, and the debugger
+ reads the real stabs directly from the .o files instead. */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris 2. Options for the debugger, related to the
+ source language for this module. E.g. whether to use ANSI
+ integral promotions or traditional integral promotions. */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable. Value is number of register. */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit. Can someone say what info it contains? */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment. Desc is the line number;
+ value is corresponding address. On Solaris2, the line number is
+ relative to the start of the current function. */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment. */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment. */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs. ?? Don't know what the fields are.
+ Supposedly the field is "path to associated .cb file". THIS VALUE
+ OVERLAPS WITH N_BSLINE! */
+__define_stab_duplicate (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency. Value is the modification time
+ of the definition file. Other is non-zero if it is imported with the
+ GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
+ are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* New in Solaris2. Function start/body/end line numbers. */
+__define_stab(N_FLINE, 0x4C, "FLINE")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
+ and one is for C++. Still,... */
+/* GNU C++ exception variable. Name is variable name. */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
+__define_stab_duplicate (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
+ this entry is immediately followed by a CAUGHT stab saying what exception
+ was caught. Multiple CAUGHT stabs means that multiple exceptions
+ can be caught here. If Desc is 0, it means all exceptions are caught
+ here. */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element. Value is offset in the structure. */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Solaris2: Last stab emitted for module. */
+__define_stab (N_ENDM, 0x62, "ENDM")
+
+/* Name of main source file.
+ Value is starting text address of the compilation.
+ If multiple N_SO's appear, the first to contain a trailing / is the
+ compilation directory. The first to not contain a trailing / is the
+ source file name, relative to the compilation directory. Others (perhaps
+ resulting from cfront) are ignored.
+ On Solaris2, value is undefined, but desc is a source-language code. */
+
+__define_stab (N_SO, 0x64, "SO")
+
+/* Automatic variable in the stack. Value is offset from frame pointer.
+ Also used for type descriptions. */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file. Only Sun uses this.
+ In an object file, only the name is significant.
+ The Sun linker puts data into some of the other fields. */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+ Value is starting text address of the compilation. */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable. Value is offset from argument pointer.
+ (On most machines the argument pointer is the same as the frame pointer. */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file. No name.
+ This and N_BINCL act as brackets around the file's output.
+ In an object file, there is no significant data in this entry.
+ The Sun linker puts data into some of the fields. */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point. Value is its address. */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+ The desc is the nesting level in lexical blocks.
+ The value is the address of the start of the text for the block.
+ The variables declared inside the block *precede* the N_LBRAC symbol.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file. Replaces a N_BINCL and everything
+ up to the corresponding N_EINCL. The Sun linker generates these when
+ it finds multiple identical copies of the symbols from an include file.
+ This appears only in output from the Sun linker. */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information. Can someone say what info it contains? */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block. Desc matches the N_LBRAC's desc.
+ The value is the address of the end of the text for the block.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block. Only the name is significant. */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block. Only the name is significant
+ (and it should match the N_BCOMM). */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* Member of a common block; value is offset within the common block.
+ This should occur within a BCOMM/ECOMM pair. */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* Solaris2: Pascal "with" statement: type,,0,0,offset */
+__define_stab (N_WITH, 0xea, "WITH")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+ or something like that. FIXME. I have assigned the values at random
+ since I don't have a Gould here. Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS, 0xF4, "NBBSS")
+__define_stab (N_NBSTS, 0xF6, "NBSTS")
+__define_stab (N_NBLCS, 0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+ The value is the length. */
+__define_stab (N_LENG, 0xfe, "LENG")
+
+/* The above information, in matrix format.
+
+ STAB MATRIX
+ _________________________________________________
+ | 00 - 1F are not dbx stab symbols |
+ | In most cases, the low bit is the EXTernal bit|
+
+ | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
+ | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
+
+ | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
+ | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
+
+ | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
+ | 11 WEAKB | 13 | 15 | 17 |
+
+ | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
+ | 19 | 1B | 1D | 1F FN |
+
+ |_______________________________________________|
+ | Debug entries with bit 01 set are unused. |
+ | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
+ | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E |
+ | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
+ | 38 OBJ | 3A | 3C OPT | 3E |
+ | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
+ | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E |
+ | 50 EHDECL*| 52 | 54 CATCH | 56 |
+ | 58 | 5A | 5C | 5E |
+ | 60 SSYM | 62 ENDM | 64 SO | 66 |
+ | 68 | 6A | 6C | 6E |
+ | 70 | 72 | 74 | 76 |
+ | 78 | 7A | 7C | 7E |
+ | 80 LSYM | 82 BINCL | 84 SOL | 86 |
+ | 88 | 8A | 8C | 8E |
+ | 90 | 92 | 94 | 96 |
+ | 98 | 9A | 9C | 9E |
+ | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
+ | A8 | AA | AC | AE |
+ | B0 | B2 | B4 | B6 |
+ | B8 | BA | BC | BE |
+ | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
+ | C8 | CA | CC | CE |
+ | D0 | D2 | D4 | D6 |
+ | D8 | DA | DC | DE |
+ | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
+ | E8 ECOML | EA WITH | EC | EE |
+ | F0 | F2 | F4 | F6 |
+ | F8 | FA | FC | FE LENG |
+ +-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
diff --git a/pstack/aout/stab_gnu.h b/pstack/aout/stab_gnu.h
new file mode 100644
index 00000000000..7d18e14a263
--- /dev/null
+++ b/pstack/aout/stab_gnu.h
@@ -0,0 +1,37 @@
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use. */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "aout/stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+/* Definitions of "desc" field for N_SO stabs in Solaris2. */
+
+#define N_SO_AS 1
+#define N_SO_C 2
+#define N_SO_ANSI_C 3
+#define N_SO_CC 4 /* C++ */
+#define N_SO_FORTRAN 5
+#define N_SO_PASCAL 6
+
+/* Solaris2: Floating point type values in basic types. */
+
+#define NF_NONE 0
+#define NF_SINGLE 1 /* IEEE 32-bit */
+#define NF_DOUBLE 2 /* IEEE 64-bit */
+#define NF_COMPLEX 3 /* Fortran complex */
+#define NF_COMPLEX16 4 /* Fortran double complex */
+#define NF_COMPLEX32 5 /* Fortran complex*16 */
+#define NF_LDOUBLE 6 /* Long double (whatever that is) */
+
+#endif /* __GNU_STAB_ */
diff --git a/pstack/bucomm.c b/pstack/bucomm.c
new file mode 100644
index 00000000000..d3231e71747
--- /dev/null
+++ b/pstack/bucomm.c
@@ -0,0 +1,238 @@
+/* bucomm.c -- Bin Utils COMmon code.
+ Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* We might put this in a library someday so it could be dynamically
+ loaded, but for now it's not necessary. */
+
+#include <bfd.h>
+#include <libiberty.h>
+#include "bucomm.h"
+
+#include <sys/stat.h>
+#include <time.h> /* ctime, maybe time_t */
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* Error reporting */
+
+char *program_name;
+
+void
+bfd_nonfatal (string)
+ CONST char *string;
+{
+ CONST char *errmsg = bfd_errmsg (bfd_get_error ());
+
+ if (string)
+ fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
+ else
+ fprintf (stderr, "%s: %s\n", program_name, errmsg);
+}
+
+void
+bfd_fatal (string)
+ CONST char *string;
+{
+ bfd_nonfatal (string);
+ xexit (1);
+}
+
+#ifdef ANSI_PROTOTYPES
+void
+fatal (const char *format, ...)
+{
+ va_list args;
+
+ fprintf (stderr, "%s: ", program_name);
+ va_start (args, format);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ putc ('\n', stderr);
+ xexit (1);
+}
+#else
+void
+fatal (va_alist)
+ va_dcl
+{
+ char *Format;
+ va_list args;
+
+ fprintf (stderr, "%s: ", program_name);
+ va_start (args);
+ Format = va_arg (args, char *);
+ vfprintf (stderr, Format, args);
+ va_end (args);
+ putc ('\n', stderr);
+ xexit (1);
+}
+#endif
+
+/* Set the default BFD target based on the configured target. Doing
+ this permits the binutils to be configured for a particular target,
+ and linked against a shared BFD library which was configured for a
+ different target. */
+
+#define TARGET "elf32-i386" /* FIXME: hard-coded! */
+void
+set_default_bfd_target ()
+{
+ /* The macro TARGET is defined by Makefile. */
+ const char *target = TARGET;
+
+ if (! bfd_set_default_target (target))
+ {
+ char *errmsg;
+
+ errmsg = (char *) xmalloc (100 + strlen (target));
+ sprintf (errmsg, "can't set BFD default target to `%s'", target);
+ bfd_fatal (errmsg);
+ }
+}
+
+/* After a false return from bfd_check_format_matches with
+ bfd_get_error () == bfd_error_file_ambiguously_recognized, print
+ the possible matching targets. */
+
+void
+list_matching_formats (p)
+ char **p;
+{
+ fprintf(stderr, "%s: Matching formats:", program_name);
+ while (*p)
+ fprintf(stderr, " %s", *p++);
+ fprintf(stderr, "\n");
+}
+
+/* List the supported targets. */
+
+void
+list_supported_targets (name, f)
+ const char *name;
+ FILE *f;
+{
+ extern bfd_target *bfd_target_vector[];
+ int t;
+
+ if (name == NULL)
+ fprintf (f, "Supported targets:");
+ else
+ fprintf (f, "%s: supported targets:", name);
+ for (t = 0; bfd_target_vector[t] != NULL; t++)
+ fprintf (f, " %s", bfd_target_vector[t]->name);
+ fprintf (f, "\n");
+}
+
+/* Display the archive header for an element as if it were an ls -l listing:
+
+ Mode User\tGroup\tSize\tDate Name */
+
+void
+print_arelt_descr (file, abfd, verbose)
+ FILE *file;
+ bfd *abfd;
+ boolean verbose;
+{
+ struct stat buf;
+
+ if (verbose)
+ {
+ if (bfd_stat_arch_elt (abfd, &buf) == 0)
+ {
+ char modebuf[11];
+ char timebuf[40];
+ time_t when = buf.st_mtime;
+ CONST char *ctime_result = (CONST char *) ctime (&when);
+
+ /* POSIX format: skip weekday and seconds from ctime output. */
+ sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
+
+ mode_string (buf.st_mode, modebuf);
+ modebuf[10] = '\0';
+ /* POSIX 1003.2/D11 says to skip first character (entry type). */
+ fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
+ (long) buf.st_uid, (long) buf.st_gid,
+ (long) buf.st_size, timebuf);
+ }
+ }
+
+ fprintf (file, "%s\n", bfd_get_filename (abfd));
+}
+
+/* Return the name of a temporary file in the same directory as FILENAME. */
+
+char *
+make_tempname (filename)
+ char *filename;
+{
+ static char template[] = "stXXXXXX";
+ char *tmpname;
+ char *slash = strrchr (filename, '/');
+
+#if defined (__DJGPP__) || defined (__GO32__) || defined (_WIN32)
+ if (slash == NULL)
+ slash = strrchr (filename, '\\');
+#endif
+
+ if (slash != (char *) NULL)
+ {
+ char c;
+
+ c = *slash;
+ *slash = 0;
+ tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
+ strcpy (tmpname, filename);
+ strcat (tmpname, "/");
+ strcat (tmpname, template);
+ mkstemp (tmpname);
+ *slash = c;
+ }
+ else
+ {
+ tmpname = xmalloc (sizeof (template));
+ strcpy (tmpname, template);
+ mkstemp (tmpname);
+ }
+ return tmpname;
+}
+
+/* Parse a string into a VMA, with a fatal error if it can't be
+ parsed. */
+
+bfd_vma
+parse_vma (s, arg)
+ const char *s;
+ const char *arg;
+{
+ bfd_vma ret;
+ const char *end;
+
+ ret = bfd_scan_vma (s, &end, 0);
+ if (*end != '\0')
+ {
+ fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s);
+ exit (1);
+ }
+ return ret;
+}
diff --git a/pstack/bucomm.h b/pstack/bucomm.h
new file mode 100644
index 00000000000..7712a70f5a2
--- /dev/null
+++ b/pstack/bucomm.h
@@ -0,0 +1,85 @@
+/* bucomm.h -- binutils common include file.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+
+This file is part of GNU Binutils.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _BUCOMM_H
+#define _BUCOMM_H
+
+#include "ansidecl.h"
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+
+#include <fcntl.h>
+
+#ifdef __GNUC__
+# undef alloca
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+char *alloca ();
+# else
+void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* HAVE_ALLOCA_H */
+#endif
+
+/* bucomm.c */
+void bfd_nonfatal PARAMS ((CONST char *));
+
+void bfd_fatal PARAMS ((CONST char *));
+
+void fatal PARAMS ((CONST char *, ...));
+
+void set_default_bfd_target PARAMS ((void));
+
+void list_matching_formats PARAMS ((char **p));
+
+void list_supported_targets PARAMS ((const char *, FILE *));
+
+void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose));
+
+char *make_tempname PARAMS ((char *));
+
+bfd_vma parse_vma PARAMS ((const char *, const char *));
+
+extern char *program_name;
+
+/* filemode.c */
+void mode_string PARAMS ((unsigned long mode, char *buf));
+
+/* version.c */
+extern void print_version PARAMS ((const char *));
+
+/* libiberty */
+PTR xmalloc PARAMS ((size_t));
+
+PTR xrealloc PARAMS ((PTR, size_t));
+
+#endif /* _BUCOMM_H */
diff --git a/pstack/budbg.h b/pstack/budbg.h
new file mode 100644
index 00000000000..d8ee8895e76
--- /dev/null
+++ b/pstack/budbg.h
@@ -0,0 +1,58 @@
+/* budbg.c -- Interfaces to the generic debugging information routines.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef BUDBG_H
+#define BUDBG_H
+
+#include <stdio.h>
+
+/* Routine used to read generic debugging information. */
+
+extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long));
+
+/* Routine used to print generic debugging information. */
+
+extern boolean print_debugging_info PARAMS ((FILE *, PTR));
+
+/* Routines used to read and write stabs information. */
+
+extern PTR start_stab PARAMS ((PTR, bfd *, boolean, asymbol **, long));
+
+extern boolean finish_stab PARAMS ((PTR, PTR));
+
+extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *));
+
+extern boolean write_stabs_in_sections_debugging_info
+ PARAMS ((bfd *, PTR, bfd_byte **, bfd_size_type *, bfd_byte **,
+ bfd_size_type *));
+
+/* Routines used to read and write IEEE debugging information. */
+
+extern boolean parse_ieee
+ PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type));
+
+extern boolean write_ieee_debugging_info PARAMS ((bfd *, PTR));
+
+/* Routine used to read COFF debugging information. */
+
+extern boolean parse_coff PARAMS ((bfd *, asymbol **, long, PTR));
+
+#endif
diff --git a/pstack/debug.c b/pstack/debug.c
new file mode 100644
index 00000000000..73412ae3f03
--- /dev/null
+++ b/pstack/debug.c
@@ -0,0 +1,3509 @@
+/* debug.c -- Handle generic debugging information.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file implements a generic debugging format. We may eventually
+ have readers which convert different formats into this generic
+ format, and writers which write it out. The initial impetus for
+ this was writing a convertor from stabs to HP IEEE-695 debugging
+ format. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <bfd.h>
+#include "bucomm.h"
+#include <libiberty.h>
+#include "debug.h"
+
+/* Global information we keep for debugging. A pointer to this
+ structure is the debugging handle passed to all the routines. */
+
+struct debug_handle
+{
+ /* A linked list of compilation units. */
+ struct debug_unit *units;
+ /* The current compilation unit. */
+ struct debug_unit *current_unit;
+ /* The current source file. */
+ struct debug_file *current_file;
+ /* The current function. */
+ struct debug_function *current_function;
+ /* The current block. */
+ struct debug_block *current_block;
+ /* The current line number information for the current unit. */
+ struct debug_lineno *current_lineno;
+ /* Mark. This is used by debug_write. */
+ unsigned int mark;
+ /* A struct/class ID used by debug_write. */
+ unsigned int class_id;
+ /* The base for class_id for this call to debug_write. */
+ unsigned int base_id;
+ /* The current line number in debug_write. */
+ struct debug_lineno *current_write_lineno;
+ unsigned int current_write_lineno_index;
+ /* A list of classes which have assigned ID's during debug_write.
+ This is linked through the next_id field of debug_class_type. */
+ struct debug_class_id *id_list;
+ /* A list used to avoid recursion during debug_type_samep. */
+ struct debug_type_compare_list *compare_list;
+};
+
+/* Information we keep for a single compilation unit. */
+
+struct debug_unit
+{
+ /* The next compilation unit. */
+ struct debug_unit *next;
+ /* A list of files included in this compilation unit. The first
+ file is always the main one, and that is where the main file name
+ is stored. */
+ struct debug_file *files;
+ /* Line number information for this compilation unit. This is not
+ stored by function, because assembler code may have line number
+ information without function information. */
+ struct debug_lineno *linenos;
+};
+
+/* Information kept for a single source file. */
+
+struct debug_file
+{
+ /* The next source file in this compilation unit. */
+ struct debug_file *next;
+ /* The name of the source file. */
+ const char *filename;
+ /* Global functions, variables, types, etc. */
+ struct debug_namespace *globals;
+};
+
+/* A type. */
+
+struct debug_type
+{
+ /* Kind of type. */
+ enum debug_type_kind kind;
+ /* Size of type (0 if not known). */
+ unsigned int size;
+ /* Type which is a pointer to this type. */
+ debug_type pointer;
+ /* Tagged union with additional information about the type. */
+ union
+ {
+ /* DEBUG_KIND_INDIRECT. */
+ struct debug_indirect_type *kindirect;
+ /* DEBUG_KIND_INT. */
+ /* Whether the integer is unsigned. */
+ boolean kint;
+ /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS,
+ DEBUG_KIND_UNION_CLASS. */
+ struct debug_class_type *kclass;
+ /* DEBUG_KIND_ENUM. */
+ struct debug_enum_type *kenum;
+ /* DEBUG_KIND_POINTER. */
+ struct debug_type *kpointer;
+ /* DEBUG_KIND_FUNCTION. */
+ struct debug_function_type *kfunction;
+ /* DEBUG_KIND_REFERENCE. */
+ struct debug_type *kreference;
+ /* DEBUG_KIND_RANGE. */
+ struct debug_range_type *krange;
+ /* DEBUG_KIND_ARRAY. */
+ struct debug_array_type *karray;
+ /* DEBUG_KIND_SET. */
+ struct debug_set_type *kset;
+ /* DEBUG_KIND_OFFSET. */
+ struct debug_offset_type *koffset;
+ /* DEBUG_KIND_METHOD. */
+ struct debug_method_type *kmethod;
+ /* DEBUG_KIND_CONST. */
+ struct debug_type *kconst;
+ /* DEBUG_KIND_VOLATILE. */
+ struct debug_type *kvolatile;
+ /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */
+ struct debug_named_type *knamed;
+ } u;
+};
+
+/* Information kept for an indirect type. */
+
+struct debug_indirect_type
+{
+ /* Slot where the final type will appear. */
+ debug_type *slot;
+ /* Tag. */
+ const char *tag;
+};
+
+/* Information kept for a struct, union, or class. */
+
+struct debug_class_type
+{
+ /* NULL terminated array of fields. */
+ debug_field *fields;
+ /* A mark field which indicates whether the struct has already been
+ printed. */
+ unsigned int mark;
+ /* This is used to uniquely identify unnamed structs when printing. */
+ unsigned int id;
+ /* The remaining fields are only used for DEBUG_KIND_CLASS and
+ DEBUG_KIND_UNION_CLASS. */
+ /* NULL terminated array of base classes. */
+ debug_baseclass *baseclasses;
+ /* NULL terminated array of methods. */
+ debug_method *methods;
+ /* The type of the class providing the virtual function table for
+ this class. This may point to the type itself. */
+ debug_type vptrbase;
+};
+
+/* Information kept for an enum. */
+
+struct debug_enum_type
+{
+ /* NULL terminated array of names. */
+ const char **names;
+ /* Array of corresponding values. */
+ bfd_signed_vma *values;
+};
+
+/* Information kept for a function. FIXME: We should be able to
+ record the parameter types. */
+
+struct debug_function_type
+{
+ /* Return type. */
+ debug_type return_type;
+ /* NULL terminated array of argument types. */
+ debug_type *arg_types;
+ /* Whether the function takes a variable number of arguments. */
+ boolean varargs;
+};
+
+/* Information kept for a range. */
+
+struct debug_range_type
+{
+ /* Range base type. */
+ debug_type type;
+ /* Lower bound. */
+ bfd_signed_vma lower;
+ /* Upper bound. */
+ bfd_signed_vma upper;
+};
+
+/* Information kept for an array. */
+
+struct debug_array_type
+{
+ /* Element type. */
+ debug_type element_type;
+ /* Range type. */
+ debug_type range_type;
+ /* Lower bound. */
+ bfd_signed_vma lower;
+ /* Upper bound. */
+ bfd_signed_vma upper;
+ /* Whether this array is really a string. */
+ boolean stringp;
+};
+
+/* Information kept for a set. */
+
+struct debug_set_type
+{
+ /* Base type. */
+ debug_type type;
+ /* Whether this set is really a bitstring. */
+ boolean bitstringp;
+};
+
+/* Information kept for an offset type (a based pointer). */
+
+struct debug_offset_type
+{
+ /* The type the pointer is an offset from. */
+ debug_type base_type;
+ /* The type the pointer points to. */
+ debug_type target_type;
+};
+
+/* Information kept for a method type. */
+
+struct debug_method_type
+{
+ /* The return type. */
+ debug_type return_type;
+ /* The object type which this method is for. */
+ debug_type domain_type;
+ /* A NULL terminated array of argument types. */
+ debug_type *arg_types;
+ /* Whether the method takes a variable number of arguments. */
+ boolean varargs;
+};
+
+/* Information kept for a named type. */
+
+struct debug_named_type
+{
+ /* Name. */
+ struct debug_name *name;
+ /* Real type. */
+ debug_type type;
+};
+
+/* A field in a struct or union. */
+
+struct debug_field
+{
+ /* Name of the field. */
+ const char *name;
+ /* Type of the field. */
+ struct debug_type *type;
+ /* Visibility of the field. */
+ enum debug_visibility visibility;
+ /* Whether this is a static member. */
+ boolean static_member;
+ union
+ {
+ /* If static_member is false. */
+ struct
+ {
+ /* Bit position of the field in the struct. */
+ unsigned int bitpos;
+ /* Size of the field in bits. */
+ unsigned int bitsize;
+ } f;
+ /* If static_member is true. */
+ struct
+ {
+ const char *physname;
+ } s;
+ } u;
+};
+
+/* A base class for an object. */
+
+struct debug_baseclass
+{
+ /* Type of the base class. */
+ struct debug_type *type;
+ /* Bit position of the base class in the object. */
+ unsigned int bitpos;
+ /* Whether the base class is virtual. */
+ boolean virtual;
+ /* Visibility of the base class. */
+ enum debug_visibility visibility;
+};
+
+/* A method of an object. */
+
+struct debug_method
+{
+ /* The name of the method. */
+ const char *name;
+ /* A NULL terminated array of different types of variants. */
+ struct debug_method_variant **variants;
+};
+
+/* The variants of a method function of an object. These indicate
+ which method to run. */
+
+struct debug_method_variant
+{
+ /* The physical name of the function. */
+ const char *physname;
+ /* The type of the function. */
+ struct debug_type *type;
+ /* The visibility of the function. */
+ enum debug_visibility visibility;
+ /* Whether the function is const. */
+ boolean constp;
+ /* Whether the function is volatile. */
+ boolean volatilep;
+ /* The offset to the function in the virtual function table. */
+ bfd_vma voffset;
+ /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */
+#define VOFFSET_STATIC_METHOD ((bfd_vma) -1)
+ /* Context of a virtual method function. */
+ struct debug_type *context;
+};
+
+/* A variable. This is the information we keep for a variable object.
+ This has no name; a name is associated with a variable in a
+ debug_name structure. */
+
+struct debug_variable
+{
+ /* Kind of variable. */
+ enum debug_var_kind kind;
+ /* Type. */
+ debug_type type;
+ /* Value. The interpretation of the value depends upon kind. */
+ bfd_vma val;
+};
+
+/* A function. This has no name; a name is associated with a function
+ in a debug_name structure. */
+
+struct debug_function
+{
+ /* Return type. */
+ debug_type return_type;
+ /* Parameter information. */
+ struct debug_parameter *parameters;
+ /* Block information. The first structure on the list is the main
+ block of the function, and describes function local variables. */
+ struct debug_block *blocks;
+};
+
+/* A function parameter. */
+
+struct debug_parameter
+{
+ /* Next parameter. */
+ struct debug_parameter *next;
+ /* Name. */
+ const char *name;
+ /* Type. */
+ debug_type type;
+ /* Kind. */
+ enum debug_parm_kind kind;
+ /* Value (meaning depends upon kind). */
+ bfd_vma val;
+};
+
+/* A typed constant. */
+
+struct debug_typed_constant
+{
+ /* Type. */
+ debug_type type;
+ /* Value. FIXME: We may eventually need to support non-integral
+ values. */
+ bfd_vma val;
+};
+
+/* Information about a block within a function. */
+
+struct debug_block
+{
+ /* Next block with the same parent. */
+ struct debug_block *next;
+ /* Parent block. */
+ struct debug_block *parent;
+ /* List of child blocks. */
+ struct debug_block *children;
+ /* Start address of the block. */
+ bfd_vma start;
+ /* End address of the block. */
+ bfd_vma end;
+ /* Local variables. */
+ struct debug_namespace *locals;
+};
+
+/* Line number information we keep for a compilation unit. FIXME:
+ This structure is easy to create, but can be very space
+ inefficient. */
+
+struct debug_lineno
+{
+ /* More line number information for this block. */
+ struct debug_lineno *next;
+ /* Source file. */
+ struct debug_file *file;
+ /* Line numbers, terminated by a -1 or the end of the array. */
+#define DEBUG_LINENO_COUNT 10
+ unsigned long linenos[DEBUG_LINENO_COUNT];
+ /* Addresses for the line numbers. */
+ bfd_vma addrs[DEBUG_LINENO_COUNT];
+};
+
+/* A namespace. This is a mapping from names to objects. FIXME: This
+ should be implemented as a hash table. */
+
+struct debug_namespace
+{
+ /* List of items in this namespace. */
+ struct debug_name *list;
+ /* Pointer to where the next item in this namespace should go. */
+ struct debug_name **tail;
+};
+
+/* Kinds of objects that appear in a namespace. */
+
+enum debug_object_kind
+{
+ /* A type. */
+ DEBUG_OBJECT_TYPE,
+ /* A tagged type (really a different sort of namespace). */
+ DEBUG_OBJECT_TAG,
+ /* A variable. */
+ DEBUG_OBJECT_VARIABLE,
+ /* A function. */
+ DEBUG_OBJECT_FUNCTION,
+ /* An integer constant. */
+ DEBUG_OBJECT_INT_CONSTANT,
+ /* A floating point constant. */
+ DEBUG_OBJECT_FLOAT_CONSTANT,
+ /* A typed constant. */
+ DEBUG_OBJECT_TYPED_CONSTANT
+};
+
+/* Linkage of an object that appears in a namespace. */
+
+enum debug_object_linkage
+{
+ /* Local variable. */
+ DEBUG_LINKAGE_AUTOMATIC,
+ /* Static--either file static or function static, depending upon the
+ namespace is. */
+ DEBUG_LINKAGE_STATIC,
+ /* Global. */
+ DEBUG_LINKAGE_GLOBAL,
+ /* No linkage. */
+ DEBUG_LINKAGE_NONE
+};
+
+/* A name in a namespace. */
+
+struct debug_name
+{
+ /* Next name in this namespace. */
+ struct debug_name *next;
+ /* Name. */
+ const char *name;
+ /* Mark. This is used by debug_write. */
+ unsigned int mark;
+ /* Kind of object. */
+ enum debug_object_kind kind;
+ /* Linkage of object. */
+ enum debug_object_linkage linkage;
+ /* Tagged union with additional information about the object. */
+ union
+ {
+ /* DEBUG_OBJECT_TYPE. */
+ struct debug_type *type;
+ /* DEBUG_OBJECT_TAG. */
+ struct debug_type *tag;
+ /* DEBUG_OBJECT_VARIABLE. */
+ struct debug_variable *variable;
+ /* DEBUG_OBJECT_FUNCTION. */
+ struct debug_function *function;
+ /* DEBUG_OBJECT_INT_CONSTANT. */
+ bfd_vma int_constant;
+ /* DEBUG_OBJECT_FLOAT_CONSTANT. */
+ double float_constant;
+ /* DEBUG_OBJECT_TYPED_CONSTANT. */
+ struct debug_typed_constant *typed_constant;
+ } u;
+};
+
+/* During debug_write, a linked list of these structures is used to
+ keep track of ID numbers that have been assigned to classes. */
+
+struct debug_class_id
+{
+ /* Next ID number. */
+ struct debug_class_id *next;
+ /* The type with the ID. */
+ struct debug_type *type;
+ /* The tag; NULL if no tag. */
+ const char *tag;
+};
+
+/* During debug_type_samep, a linked list of these structures is kept
+ on the stack to avoid infinite recursion. */
+
+struct debug_type_compare_list
+{
+ /* Next type on list. */
+ struct debug_type_compare_list *next;
+ /* The types we are comparing. */
+ struct debug_type *t1;
+ struct debug_type *t2;
+};
+
+/* Local functions. */
+
+static void debug_error PARAMS ((const char *));
+static struct debug_name *debug_add_to_namespace
+ PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,
+ enum debug_object_kind, enum debug_object_linkage));
+static struct debug_name *debug_add_to_current_namespace
+ PARAMS ((struct debug_handle *, const char *, enum debug_object_kind,
+ enum debug_object_linkage));
+static struct debug_type *debug_make_type
+ PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));
+static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type));
+static boolean debug_write_name
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_name *));
+static boolean debug_write_type
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_type *, struct debug_name *));
+static boolean debug_write_class_type
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_type *, const char *));
+static boolean debug_write_function
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ const char *, enum debug_object_linkage, struct debug_function *));
+static boolean debug_write_block
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_block *));
+static boolean debug_write_linenos
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ bfd_vma));
+static boolean debug_set_class_id
+ PARAMS ((struct debug_handle *, const char *, struct debug_type *));
+static boolean debug_type_samep
+ PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
+static boolean debug_class_type_samep
+ PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
+
+/* Issue an error message. */
+
+static void
+debug_error (message)
+ const char *message;
+{
+ fprintf (stderr, "%s\n", message);
+}
+
+/* Add an object to a namespace. */
+
+static struct debug_name *
+debug_add_to_namespace (info, nsp, name, kind, linkage)
+ struct debug_handle *info;
+ struct debug_namespace **nsp;
+ const char *name;
+ enum debug_object_kind kind;
+ enum debug_object_linkage linkage;
+{
+ struct debug_name *n;
+ struct debug_namespace *ns;
+
+ n = (struct debug_name *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->name = name;
+ n->kind = kind;
+ n->linkage = linkage;
+
+ ns = *nsp;
+ if (ns == NULL)
+ {
+ ns = (struct debug_namespace *) xmalloc (sizeof *ns);
+ memset (ns, 0, sizeof *ns);
+
+ ns->tail = &ns->list;
+
+ *nsp = ns;
+ }
+
+ *ns->tail = n;
+ ns->tail = &n->next;
+
+ return n;
+}
+
+/* Add an object to the current namespace. */
+
+static struct debug_name *
+debug_add_to_current_namespace (info, name, kind, linkage)
+ struct debug_handle *info;
+ const char *name;
+ enum debug_object_kind kind;
+ enum debug_object_linkage linkage;
+{
+ struct debug_namespace **nsp;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error ("debug_add_to_current_namespace: no current file");
+ return NULL;
+ }
+
+ if (info->current_block != NULL)
+ nsp = &info->current_block->locals;
+ else
+ nsp = &info->current_file->globals;
+
+ return debug_add_to_namespace (info, nsp, name, kind, linkage);
+}
+
+/* Return a handle for debugging information. */
+
+PTR
+debug_init ()
+{
+ struct debug_handle *ret;
+
+ ret = (struct debug_handle *) xmalloc (sizeof *ret);
+ memset (ret, 0, sizeof *ret);
+ return (PTR) ret;
+}
+
+/* Set the source filename. This implicitly starts a new compilation
+ unit. */
+
+boolean
+debug_set_filename (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_file *nfile;
+ struct debug_unit *nunit;
+
+ if (name == NULL)
+ name = "";
+
+ nfile = (struct debug_file *) xmalloc (sizeof *nfile);
+ memset (nfile, 0, sizeof *nfile);
+
+ nfile->filename = name;
+
+ nunit = (struct debug_unit *) xmalloc (sizeof *nunit);
+ memset (nunit, 0, sizeof *nunit);
+
+ nunit->files = nfile;
+ info->current_file = nfile;
+
+ if (info->current_unit != NULL)
+ info->current_unit->next = nunit;
+ else
+ {
+ assert (info->units == NULL);
+ info->units = nunit;
+ }
+
+ info->current_unit = nunit;
+
+ info->current_function = NULL;
+ info->current_block = NULL;
+ info->current_lineno = NULL;
+
+ return true;
+}
+
+/* Change source files to the given file name. This is used for
+ include files in a single compilation unit. */
+
+boolean
+debug_start_source (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_file *f, **pf;
+
+ if (name == NULL)
+ name = "";
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_start_source: no debug_set_filename call");
+ return false;
+ }
+
+ for (f = info->current_unit->files; f != NULL; f = f->next)
+ {
+ if (f->filename[0] == name[0]
+ && f->filename[1] == name[1]
+ && strcmp (f->filename, name) == 0)
+ {
+ info->current_file = f;
+ return true;
+ }
+ }
+
+ f = (struct debug_file *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->filename = name;
+
+ for (pf = &info->current_file->next;
+ *pf != NULL;
+ pf = &(*pf)->next)
+ ;
+ *pf = f;
+
+ info->current_file = f;
+
+ return true;
+}
+
+/* Record a function definition. This implicitly starts a function
+ block. The debug_type argument is the type of the return value.
+ The boolean indicates whether the function is globally visible.
+ The bfd_vma is the address of the start of the function. Currently
+ the parameter types are specified by calls to
+ debug_record_parameter. FIXME: There is no way to specify nested
+ functions. */
+
+boolean
+debug_record_function (handle, name, return_type, global, addr)
+ PTR handle;
+ const char *name;
+ debug_type return_type;
+ boolean global;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_function *f;
+ struct debug_block *b;
+ struct debug_name *n;
+
+ if (name == NULL)
+ name = "";
+ if (return_type == NULL)
+ return false;
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_record_function: no debug_set_filename call");
+ return false;
+ }
+
+ f = (struct debug_function *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->return_type = return_type;
+
+ b = (struct debug_block *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->start = addr;
+ b->end = (bfd_vma) -1;
+
+ f->blocks = b;
+
+ info->current_function = f;
+ info->current_block = b;
+
+ /* FIXME: If we could handle nested functions, this would be the
+ place: we would want to use a different namespace. */
+ n = debug_add_to_namespace (info,
+ &info->current_file->globals,
+ name,
+ DEBUG_OBJECT_FUNCTION,
+ (global
+ ? DEBUG_LINKAGE_GLOBAL
+ : DEBUG_LINKAGE_STATIC));
+ if (n == NULL)
+ return false;
+
+ n->u.function = f;
+
+ return true;
+}
+
+/* Record a parameter for the current function. */
+
+boolean
+debug_record_parameter (handle, name, type, kind, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_parameter *p, **pp;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ if (info->current_unit == NULL
+ || info->current_function == NULL)
+ {
+ debug_error ("debug_record_parameter: no current function");
+ return false;
+ }
+
+ p = (struct debug_parameter *) xmalloc (sizeof *p);
+ memset (p, 0, sizeof *p);
+
+ p->name = name;
+ p->type = type;
+ p->kind = kind;
+ p->val = val;
+
+ for (pp = &info->current_function->parameters;
+ *pp != NULL;
+ pp = &(*pp)->next)
+ ;
+ *pp = p;
+
+ return true;
+}
+
+/* End a function. FIXME: This should handle function nesting. */
+
+boolean
+debug_end_function (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ if (info->current_unit == NULL
+ || info->current_block == NULL
+ || info->current_function == NULL)
+ {
+ debug_error ("debug_end_function: no current function");
+ return false;
+ }
+
+ if (info->current_block->parent != NULL)
+ {
+ debug_error ("debug_end_function: some blocks were not closed");
+ return false;
+ }
+
+ info->current_block->end = addr;
+
+ info->current_function = NULL;
+ info->current_block = NULL;
+
+ return true;
+}
+
+/* Start a block in a function. All local information will be
+ recorded in this block, until the matching call to debug_end_block.
+ debug_start_block and debug_end_block may be nested. The bfd_vma
+ argument is the address at which this block starts. */
+
+boolean
+debug_start_block (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *b, **pb;
+
+ /* We must always have a current block: debug_record_function sets
+ one up. */
+ if (info->current_unit == NULL
+ || info->current_block == NULL)
+ {
+ debug_error ("debug_start_block: no current block");
+ return false;
+ }
+
+ b = (struct debug_block *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->parent = info->current_block;
+ b->start = addr;
+ b->end = (bfd_vma) -1;
+
+ /* This new block is a child of the current block. */
+ for (pb = &info->current_block->children;
+ *pb != NULL;
+ pb = &(*pb)->next)
+ ;
+ *pb = b;
+
+ info->current_block = b;
+
+ return true;
+}
+
+/* Finish a block in a function. This matches the call to
+ debug_start_block. The argument is the address at which this block
+ ends. */
+
+boolean
+debug_end_block (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *parent;
+
+ if (info->current_unit == NULL
+ || info->current_block == NULL)
+ {
+ debug_error ("debug_end_block: no current block");
+ return false;
+ }
+
+ parent = info->current_block->parent;
+ if (parent == NULL)
+ {
+ debug_error ("debug_end_block: attempt to close top level block");
+ return false;
+ }
+
+ info->current_block->end = addr;
+
+ info->current_block = parent;
+
+ return true;
+}
+
+/* Associate a line number in the current source file and function
+ with a given address. */
+
+boolean
+debug_record_line (handle, lineno, addr)
+ PTR handle;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_lineno *l;
+ unsigned int i;
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_record_line: no current unit");
+ return false;
+ }
+
+ l = info->current_lineno;
+ if (l != NULL && l->file == info->current_file)
+ {
+ for (i = 0; i < DEBUG_LINENO_COUNT; i++)
+ {
+ if (l->linenos[i] == (unsigned long) -1)
+ {
+ l->linenos[i] = lineno;
+ l->addrs[i] = addr;
+ return true;
+ }
+ }
+ }
+
+ /* If we get here, then either 1) there is no current_lineno
+ structure, which means this is the first line number in this
+ compilation unit, 2) the current_lineno structure is for a
+ different file, or 3) the current_lineno structure is full.
+ Regardless, we want to allocate a new debug_lineno structure, put
+ it in the right place, and make it the new current_lineno
+ structure. */
+
+ l = (struct debug_lineno *) xmalloc (sizeof *l);
+ memset (l, 0, sizeof *l);
+
+ l->file = info->current_file;
+ l->linenos[0] = lineno;
+ l->addrs[0] = addr;
+ for (i = 1; i < DEBUG_LINENO_COUNT; i++)
+ l->linenos[i] = (unsigned long) -1;
+
+ if (info->current_lineno != NULL)
+ info->current_lineno->next = l;
+ else
+ info->current_unit->linenos = l;
+
+ info->current_lineno = l;
+
+ return true;
+}
+
+/* Start a named common block. This is a block of variables that may
+ move in memory. */
+
+boolean
+debug_start_common_block (handle, name)
+ PTR handle;
+ const char *name;
+{
+ /* FIXME */
+ debug_error ("debug_start_common_block: not implemented");
+ return false;
+}
+
+/* End a named common block. */
+
+boolean
+debug_end_common_block (handle, name)
+ PTR handle;
+ const char *name;
+{
+ /* FIXME */
+ debug_error ("debug_end_common_block: not implemented");
+ return false;
+}
+
+/* Record a named integer constant. */
+
+boolean
+debug_record_int_const (handle, name, val)
+ PTR handle;
+ const char *name;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+
+ if (name == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ n->u.int_constant = val;
+
+ return true;
+}
+
+/* Record a named floating point constant. */
+
+boolean
+debug_record_float_const (handle, name, val)
+ PTR handle;
+ const char *name;
+ double val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+
+ if (name == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ n->u.float_constant = val;
+
+ return true;
+}
+
+/* Record a typed constant with an integral value. */
+
+boolean
+debug_record_typed_const (handle, name, type, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+ struct debug_typed_constant *tc;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
+ memset (tc, 0, sizeof *tc);
+
+ tc->type = type;
+ tc->val = val;
+
+ n->u.typed_constant = tc;
+
+ return true;
+}
+
+/* Record a label. */
+
+boolean
+debug_record_label (handle, name, type, addr)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma addr;
+{
+ /* FIXME. */
+ debug_error ("debug_record_label not implemented");
+ return false;
+}
+
+/* Record a variable. */
+
+boolean
+debug_record_variable (handle, name, type, kind, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_namespace **nsp;
+ enum debug_object_linkage linkage;
+ struct debug_name *n;
+ struct debug_variable *v;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error ("debug_record_variable: no current file");
+ return false;
+ }
+
+ if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
+ {
+ nsp = &info->current_file->globals;
+ if (kind == DEBUG_GLOBAL)
+ linkage = DEBUG_LINKAGE_GLOBAL;
+ else
+ linkage = DEBUG_LINKAGE_STATIC;
+ }
+ else
+ {
+ if (info->current_block == NULL)
+ {
+ debug_error ("debug_record_variable: no current block");
+ return false;
+ }
+ nsp = &info->current_block->locals;
+ linkage = DEBUG_LINKAGE_AUTOMATIC;
+ }
+
+ n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
+ if (n == NULL)
+ return false;
+
+ v = (struct debug_variable *) xmalloc (sizeof *v);
+ memset (v, 0, sizeof *v);
+
+ v->kind = kind;
+ v->type = type;
+ v->val = val;
+
+ n->u.variable = v;
+
+ return true;
+}
+
+/* Make a type with a given kind and size. */
+
+/*ARGSUSED*/
+static struct debug_type *
+debug_make_type (info, kind, size)
+ struct debug_handle *info;
+ enum debug_type_kind kind;
+ unsigned int size;
+{
+ struct debug_type *t;
+
+ t = (struct debug_type *) xmalloc (sizeof *t);
+ memset (t, 0, sizeof *t);
+
+ t->kind = kind;
+ t->size = size;
+
+ return t;
+}
+
+/* Make an indirect type which may be used as a placeholder for a type
+ which is referenced before it is defined. */
+
+debug_type
+debug_make_indirect_type (handle, slot, tag)
+ PTR handle;
+ debug_type *slot;
+ const char *tag;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_indirect_type *i;
+
+ t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ i = (struct debug_indirect_type *) xmalloc (sizeof *i);
+ memset (i, 0, sizeof *i);
+
+ i->slot = slot;
+ i->tag = tag;
+
+ t->u.kindirect = i;
+
+ return t;
+}
+
+/* Make a void type. There is only one of these. */
+
+debug_type
+debug_make_void_type (handle)
+ PTR handle;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_VOID, 0);
+}
+
+/* Make an integer type of a given size. The boolean argument is true
+ if the integer is unsigned. */
+
+debug_type
+debug_make_int_type (handle, size, unsignedp)
+ PTR handle;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ t = debug_make_type (info, DEBUG_KIND_INT, size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kint = unsignedp;
+
+ return t;
+}
+
+/* Make a floating point type of a given size. FIXME: On some
+ platforms, like an Alpha, you probably need to be able to specify
+ the format. */
+
+debug_type
+debug_make_float_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_FLOAT, size);
+}
+
+/* Make a boolean type of a given size. */
+
+debug_type
+debug_make_bool_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_BOOL, size);
+}
+
+/* Make a complex type of a given size. */
+
+debug_type
+debug_make_complex_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_COMPLEX, size);
+}
+
+/* Make a structure type. The second argument is true for a struct,
+ false for a union. The third argument is the size of the struct.
+ The fourth argument is a NULL terminated array of fields. */
+
+debug_type
+debug_make_struct_type (handle, structp, size, fields)
+ PTR handle;
+ boolean structp;
+ bfd_vma size;
+ debug_field *fields;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_class_type *c;
+
+ t = debug_make_type (info,
+ structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION,
+ size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ c = (struct debug_class_type *) xmalloc (sizeof *c);
+ memset (c, 0, sizeof *c);
+
+ c->fields = fields;
+
+ t->u.kclass = c;
+
+ return t;
+}
+
+/* Make an object type. The first three arguments after the handle
+ are the same as for debug_make_struct_type. The next arguments are
+ a NULL terminated array of base classes, a NULL terminated array of
+ methods, the type of the object holding the virtual function table
+ if it is not this object, and a boolean which is true if this
+ object has its own virtual function table. */
+
+debug_type
+debug_make_object_type (handle, structp, size, fields, baseclasses,
+ methods, vptrbase, ownvptr)
+ PTR handle;
+ boolean structp;
+ bfd_vma size;
+ debug_field *fields;
+ debug_baseclass *baseclasses;
+ debug_method *methods;
+ debug_type vptrbase;
+ boolean ownvptr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_class_type *c;
+
+ t = debug_make_type (info,
+ structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS,
+ size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ c = (struct debug_class_type *) xmalloc (sizeof *c);
+ memset (c, 0, sizeof *c);
+
+ c->fields = fields;
+ c->baseclasses = baseclasses;
+ c->methods = methods;
+ if (ownvptr)
+ c->vptrbase = t;
+ else
+ c->vptrbase = vptrbase;
+
+ t->u.kclass = c;
+
+ return t;
+}
+
+/* Make an enumeration type. The arguments are a null terminated
+ array of strings, and an array of corresponding values. */
+
+debug_type
+debug_make_enum_type (handle, names, values)
+ PTR handle;
+ const char **names;
+ bfd_signed_vma *values;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_enum_type *e;
+
+ t = debug_make_type (info, DEBUG_KIND_ENUM, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ e = (struct debug_enum_type *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->names = names;
+ e->values = values;
+
+ t->u.kenum = e;
+
+ return t;
+}
+
+/* Make a pointer to a given type. */
+
+debug_type
+debug_make_pointer_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (type->pointer != DEBUG_TYPE_NULL)
+ return type->pointer;
+
+ t = debug_make_type (info, DEBUG_KIND_POINTER, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kpointer = type;
+
+ type->pointer = t;
+
+ return t;
+}
+
+/* Make a function returning a given type. FIXME: We should be able
+ to record the parameter types. */
+
+debug_type
+debug_make_function_type (handle, type, arg_types, varargs)
+ PTR handle;
+ debug_type type;
+ debug_type *arg_types;
+ boolean varargs;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_function_type *f;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ f = (struct debug_function_type *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->return_type = type;
+ f->arg_types = arg_types;
+ f->varargs = varargs;
+
+ t->u.kfunction = f;
+
+ return t;
+}
+
+/* Make a reference to a given type. */
+
+debug_type
+debug_make_reference_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kreference = type;
+
+ return t;
+}
+
+/* Make a range of a given type from a lower to an upper bound. */
+
+debug_type
+debug_make_range_type (handle, type, lower, upper)
+ PTR handle;
+ debug_type type;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_range_type *r;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_RANGE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ r = (struct debug_range_type *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+
+ r->type = type;
+ r->lower = lower;
+ r->upper = upper;
+
+ t->u.krange = r;
+
+ return t;
+}
+
+/* Make an array type. The second argument is the type of an element
+ of the array. The third argument is the type of a range of the
+ array. The fourth and fifth argument are the lower and upper
+ bounds, respectively. The sixth argument is true if this array is
+ actually a string, as in C. */
+
+debug_type
+debug_make_array_type (handle, element_type, range_type, lower, upper,
+ stringp)
+ PTR handle;
+ debug_type element_type;
+ debug_type range_type;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+ boolean stringp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_array_type *a;
+
+ if (element_type == NULL || range_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_ARRAY, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ a = (struct debug_array_type *) xmalloc (sizeof *a);
+ memset (a, 0, sizeof *a);
+
+ a->element_type = element_type;
+ a->range_type = range_type;
+ a->lower = lower;
+ a->upper = upper;
+ a->stringp = stringp;
+
+ t->u.karray = a;
+
+ return t;
+}
+
+/* Make a set of a given type. For example, a Pascal set type. The
+ boolean argument is true if this set is actually a bitstring, as in
+ CHILL. */
+
+debug_type
+debug_make_set_type (handle, type, bitstringp)
+ PTR handle;
+ debug_type type;
+ boolean bitstringp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_set_type *s;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_SET, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ s = (struct debug_set_type *) xmalloc (sizeof *s);
+ memset (s, 0, sizeof *s);
+
+ s->type = type;
+ s->bitstringp = bitstringp;
+
+ t->u.kset = s;
+
+ return t;
+}
+
+/* Make a type for a pointer which is relative to an object. The
+ second argument is the type of the object to which the pointer is
+ relative. The third argument is the type that the pointer points
+ to. */
+
+debug_type
+debug_make_offset_type (handle, base_type, target_type)
+ PTR handle;
+ debug_type base_type;
+ debug_type target_type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_offset_type *o;
+
+ if (base_type == NULL || target_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_OFFSET, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ o = (struct debug_offset_type *) xmalloc (sizeof *o);
+ memset (o, 0, sizeof *o);
+
+ o->base_type = base_type;
+ o->target_type = target_type;
+
+ t->u.koffset = o;
+
+ return t;
+}
+
+/* Make a type for a method function. The second argument is the
+ return type, the third argument is the domain, and the fourth
+ argument is a NULL terminated array of argument types. */
+
+debug_type
+debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
+ PTR handle;
+ debug_type return_type;
+ debug_type domain_type;
+ debug_type *arg_types;
+ boolean varargs;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_method_type *m;
+
+ if (return_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_METHOD, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ m = (struct debug_method_type *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->return_type = return_type;
+ m->domain_type = domain_type;
+ m->arg_types = arg_types;
+ m->varargs = varargs;
+
+ t->u.kmethod = m;
+
+ return t;
+}
+
+/* Make a const qualified version of a given type. */
+
+debug_type
+debug_make_const_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_CONST, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kconst = type;
+
+ return t;
+}
+
+/* Make a volatile qualified version of a given type. */
+
+debug_type
+debug_make_volatile_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kvolatile = type;
+
+ return t;
+}
+
+/* Make an undefined tagged type. For example, a struct which has
+ been mentioned, but not defined. */
+
+debug_type
+debug_make_undefined_tagged_type (handle, name, kind)
+ PTR handle;
+ const char *name;
+ enum debug_type_kind kind;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (name == NULL)
+ return DEBUG_TYPE_NULL;
+
+ switch (kind)
+ {
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ case DEBUG_KIND_ENUM:
+ break;
+
+ default:
+ debug_error ("debug_make_undefined_type: unsupported kind");
+ return DEBUG_TYPE_NULL;
+ }
+
+ t = debug_make_type (info, kind, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ return debug_tag_type (handle, name, t);
+}
+
+/* Make a base class for an object. The second argument is the base
+ class type. The third argument is the bit position of this base
+ class in the object (always 0 unless doing multiple inheritance).
+ The fourth argument is whether this is a virtual class. The fifth
+ argument is the visibility of the base class. */
+
+/*ARGSUSED*/
+debug_baseclass
+debug_make_baseclass (handle, type, bitpos, virtual, visibility)
+ PTR handle;
+ debug_type type;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct debug_baseclass *b;
+
+ b = (struct debug_baseclass *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->type = type;
+ b->bitpos = bitpos;
+ b->virtual = virtual;
+ b->visibility = visibility;
+
+ return b;
+}
+
+/* Make a field for a struct. The second argument is the name. The
+ third argument is the type of the field. The fourth argument is
+ the bit position of the field. The fifth argument is the size of
+ the field (it may be zero). The sixth argument is the visibility
+ of the field. */
+
+/*ARGSUSED*/
+debug_field
+debug_make_field (handle, name, type, bitpos, bitsize, visibility)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct debug_field *f;
+
+ f = (struct debug_field *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->name = name;
+ f->type = type;
+ f->static_member = false;
+ f->u.f.bitpos = bitpos;
+ f->u.f.bitsize = bitsize;
+ f->visibility = visibility;
+
+ return f;
+}
+
+/* Make a static member of an object. The second argument is the
+ name. The third argument is the type of the member. The fourth
+ argument is the physical name of the member (i.e., the name as a
+ global variable). The fifth argument is the visibility of the
+ member. */
+
+/*ARGSUSED*/
+debug_field
+debug_make_static_member (handle, name, type, physname, visibility)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct debug_field *f;
+
+ f = (struct debug_field *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->name = name;
+ f->type = type;
+ f->static_member = true;
+ f->u.s.physname = physname;
+ f->visibility = visibility;
+
+ return f;
+}
+
+/* Make a method. The second argument is the name, and the third
+ argument is a NULL terminated array of method variants. */
+
+/*ARGSUSED*/
+debug_method
+debug_make_method (handle, name, variants)
+ PTR handle;
+ const char *name;
+ debug_method_variant *variants;
+{
+ struct debug_method *m;
+
+ m = (struct debug_method *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->name = name;
+ m->variants = variants;
+
+ return m;
+}
+
+/* Make a method argument. The second argument is the real name of
+ the function. The third argument is the type of the function. The
+ fourth argument is the visibility. The fifth argument is whether
+ this is a const function. The sixth argument is whether this is a
+ volatile function. The seventh argument is the offset in the
+ virtual function table, if any. The eighth argument is the virtual
+ function context. FIXME: Are the const and volatile arguments
+ necessary? Could we just use debug_make_const_type? */
+
+/*ARGSUSED*/
+debug_method_variant
+debug_make_method_variant (handle, physname, type, visibility, constp,
+ volatilep, voffset, context)
+ PTR handle;
+ const char *physname;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ debug_type context;
+{
+ struct debug_method_variant *m;
+
+ m = (struct debug_method_variant *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->physname = physname;
+ m->type = type;
+ m->visibility = visibility;
+ m->constp = constp;
+ m->volatilep = volatilep;
+ m->voffset = voffset;
+ m->context = context;
+
+ return m;
+}
+
+/* Make a static method argument. The arguments are the same as for
+ debug_make_method_variant, except that the last two are omitted
+ since a static method can not also be virtual. */
+
+debug_method_variant
+debug_make_static_method_variant (handle, physname, type, visibility,
+ constp, volatilep)
+ PTR handle;
+ const char *physname;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct debug_method_variant *m;
+
+ m = (struct debug_method_variant *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->physname = physname;
+ m->type = type;
+ m->visibility = visibility;
+ m->constp = constp;
+ m->volatilep = volatilep;
+ m->voffset = VOFFSET_STATIC_METHOD;
+
+ return m;
+}
+
+/* Name a type. */
+
+debug_type
+debug_name_type (handle, name, type)
+ PTR handle;
+ const char *name;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_named_type *n;
+ struct debug_name *nm;
+
+ if (name == NULL || type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error ("debug_name_type: no current file");
+ return DEBUG_TYPE_NULL;
+ /* return false; */
+ }
+
+ t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ n = (struct debug_named_type *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = type;
+
+ t->u.knamed = n;
+
+ /* We always add the name to the global namespace. This is probably
+ wrong in some cases, but it seems to be right for stabs. FIXME. */
+
+ nm = debug_add_to_namespace (info, &info->current_file->globals, name,
+ DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
+ if (nm == NULL)
+ return DEBUG_TYPE_NULL;
+
+ nm->u.type = t;
+
+ n->name = nm;
+
+ return t;
+}
+
+/* Tag a type. */
+
+debug_type
+debug_tag_type (handle, name, type)
+ PTR handle;
+ const char *name;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_named_type *n;
+ struct debug_name *nm;
+
+ if (name == NULL || type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (info->current_file == NULL)
+ {
+ debug_error ("debug_tag_type: no current file");
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (type->kind == DEBUG_KIND_TAGGED)
+ {
+ if (strcmp (type->u.knamed->name->name, name) == 0)
+ return type;
+ debug_error ("debug_tag_type: extra tag attempted");
+ return DEBUG_TYPE_NULL;
+ }
+
+ t = debug_make_type (info, DEBUG_KIND_TAGGED, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ n = (struct debug_named_type *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = type;
+
+ t->u.knamed = n;
+
+ /* We keep a global namespace of tags for each compilation unit. I
+ don't know if that is the right thing to do. */
+
+ nm = debug_add_to_namespace (info, &info->current_file->globals, name,
+ DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
+ if (nm == NULL)
+ return DEBUG_TYPE_NULL;
+
+ nm->u.tag = t;
+
+ n->name = nm;
+
+ return t;
+}
+
+/* Record the size of a given type. */
+
+/*ARGSUSED*/
+boolean
+debug_record_type_size (handle, type, size)
+ PTR handle;
+ debug_type type;
+ unsigned int size;
+{
+#if 0
+ if (type->size != 0 && type->size != size)
+ fprintf (stderr, "Warning: changing type size from %d to %d\n",
+ type->size, size);
+#endif
+
+ type->size = size;
+
+ return true;
+}
+
+/* Find a named type. */
+
+debug_type
+debug_find_named_type (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *b;
+ struct debug_file *f;
+
+ /* We only search the current compilation unit. I don't know if
+ this is right or not. */
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_find_named_type: no current compilation unit");
+ return DEBUG_TYPE_NULL;
+ }
+
+ for (b = info->current_block; b != NULL; b = b->parent)
+ {
+ if (b->locals != NULL)
+ {
+ struct debug_name *n;
+
+ for (n = b->locals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TYPE
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.type;
+ }
+ }
+ }
+
+ for (f = info->current_unit->files; f != NULL; f = f->next)
+ {
+ if (f->globals != NULL)
+ {
+ struct debug_name *n;
+
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TYPE
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.type;
+ }
+ }
+ }
+
+ return DEBUG_TYPE_NULL;
+}
+
+/* Find a tagged type. */
+
+debug_type
+debug_find_tagged_type (handle, name, kind)
+ PTR handle;
+ const char *name;
+ enum debug_type_kind kind;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_unit *u;
+
+ /* We search the globals of all the compilation units. I don't know
+ if this is correct or not. It would be easy to change. */
+
+ for (u = info->units; u != NULL; u = u->next)
+ {
+ struct debug_file *f;
+
+ for (f = u->files; f != NULL; f = f->next)
+ {
+ struct debug_name *n;
+
+ if (f->globals != NULL)
+ {
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TAG
+ && (kind == DEBUG_KIND_ILLEGAL
+ || n->u.tag->kind == kind)
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.tag;
+ }
+ }
+ }
+ }
+
+ return DEBUG_TYPE_NULL;
+}
+
+/* Get a base type. */
+
+static struct debug_type *
+debug_get_real_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ switch (type->kind)
+ {
+ default:
+ return type;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_real_type (handle, *type->u.kindirect->slot);
+ return type;
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ return debug_get_real_type (handle, type->u.knamed->type);
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the kind of a type. */
+
+enum debug_type_kind
+debug_get_type_kind (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return DEBUG_KIND_ILLEGAL;
+ type = debug_get_real_type (handle, type);
+ return type->kind;
+}
+
+/* Get the name of a type. */
+
+const char *
+debug_get_type_name (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type->kind == DEBUG_KIND_INDIRECT)
+ {
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_type_name (handle, *type->u.kindirect->slot);
+ return type->u.kindirect->tag;
+ }
+ if (type->kind == DEBUG_KIND_NAMED
+ || type->kind == DEBUG_KIND_TAGGED)
+ return type->u.knamed->name->name;
+ return NULL;
+}
+
+/* Get the size of a type. */
+
+bfd_vma
+debug_get_type_size (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return 0;
+
+ /* We don't call debug_get_real_type, because somebody might have
+ called debug_record_type_size on a named or indirect type. */
+
+ if (type->size != 0)
+ return type->size;
+
+ switch (type->kind)
+ {
+ default:
+ return 0;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_type_size (handle, *type->u.kindirect->slot);
+ return 0;
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ return debug_get_type_size (handle, type->u.knamed->type);
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the return type of a function or method type. */
+
+debug_type
+debug_get_return_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return DEBUG_TYPE_NULL;
+ case DEBUG_KIND_FUNCTION:
+ return type->u.kfunction->return_type;
+ case DEBUG_KIND_METHOD:
+ return type->u.kmethod->return_type;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the parameter types of a function or method type (except that
+ we don't currently store the parameter types of a function). */
+
+const debug_type *
+debug_get_parameter_types (handle, type, pvarargs)
+ PTR handle;
+ debug_type type;
+ boolean *pvarargs;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_FUNCTION:
+ *pvarargs = type->u.kfunction->varargs;
+ return type->u.kfunction->arg_types;
+ case DEBUG_KIND_METHOD:
+ *pvarargs = type->u.kmethod->varargs;
+ return type->u.kmethod->arg_types;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the target type of a type. */
+
+debug_type
+debug_get_target_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_POINTER:
+ return type->u.kpointer;
+ case DEBUG_KIND_REFERENCE:
+ return type->u.kreference;
+ case DEBUG_KIND_CONST:
+ return type->u.kconst;
+ case DEBUG_KIND_VOLATILE:
+ return type->u.kvolatile;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the NULL terminated array of fields for a struct, union, or
+ class. */
+
+const debug_field *
+debug_get_fields (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ return type->u.kclass->fields;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the type of a field. */
+
+/*ARGSUSED*/
+debug_type
+debug_get_field_type (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return NULL;
+ return field->type;
+}
+
+/* Get the name of a field. */
+
+/*ARGSUSED*/
+const char *
+debug_get_field_name (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return NULL;
+ return field->name;
+}
+
+/* Get the bit position of a field. */
+
+/*ARGSUSED*/
+bfd_vma
+debug_get_field_bitpos (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || field->static_member)
+ return (bfd_vma) -1;
+ return field->u.f.bitpos;
+}
+
+/* Get the bit size of a field. */
+
+/*ARGSUSED*/
+bfd_vma
+debug_get_field_bitsize (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || field->static_member)
+ return (bfd_vma) -1;
+ return field->u.f.bitsize;
+}
+
+/* Get the visibility of a field. */
+
+/*ARGSUSED*/
+enum debug_visibility
+debug_get_field_visibility (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return DEBUG_VISIBILITY_IGNORE;
+ return field->visibility;
+}
+
+/* Get the physical name of a field. */
+
+const char *
+debug_get_field_physname (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || ! field->static_member)
+ return NULL;
+ return field->u.s.physname;
+}
+
+/* Write out the debugging information. This is given a handle to
+ debugging information, and a set of function pointers to call. */
+
+boolean
+debug_write (handle, fns, fhandle)
+ PTR handle;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_unit *u;
+
+ /* We use a mark to tell whether we have already written out a
+ particular name. We use an integer, so that we don't have to
+ clear the mark fields if we happen to write out the same
+ information more than once. */
+ ++info->mark;
+
+ /* The base_id field holds an ID value which will never be used, so
+ that we can tell whether we have assigned an ID during this call
+ to debug_write. */
+ info->base_id = info->class_id;
+
+ /* We keep a linked list of classes for which was have assigned ID's
+ during this call to debug_write. */
+ info->id_list = NULL;
+
+ for (u = info->units; u != NULL; u = u->next)
+ {
+ struct debug_file *f;
+ boolean first_file;
+
+ info->current_write_lineno = u->linenos;
+ info->current_write_lineno_index = 0;
+
+ if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
+ return false;
+
+ first_file = true;
+ for (f = u->files; f != NULL; f = f->next)
+ {
+ struct debug_name *n;
+
+ if (first_file)
+ first_file = false;
+ else
+ {
+ if (! (*fns->start_source) (fhandle, f->filename))
+ return false;
+ }
+
+ if (f->globals != NULL)
+ {
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (! debug_write_name (info, fns, fhandle, n))
+ return false;
+ }
+ }
+ }
+
+ /* Output any line number information which hasn't already been
+ handled. */
+ if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out an element in a namespace. */
+
+static boolean
+debug_write_name (info, fns, fhandle, n)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_name *n;
+{
+ switch (n->kind)
+ {
+ case DEBUG_OBJECT_TYPE:
+ if (! debug_write_type (info, fns, fhandle, n->u.type, n)
+ || ! (*fns->typdef) (fhandle, n->name))
+ return false;
+ return true;
+ case DEBUG_OBJECT_TAG:
+ if (! debug_write_type (info, fns, fhandle, n->u.tag, n))
+ return false;
+ return (*fns->tag) (fhandle, n->name);
+ case DEBUG_OBJECT_VARIABLE:
+ if (! debug_write_type (info, fns, fhandle, n->u.variable->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->variable) (fhandle, n->name, n->u.variable->kind,
+ n->u.variable->val);
+ case DEBUG_OBJECT_FUNCTION:
+ return debug_write_function (info, fns, fhandle, n->name,
+ n->linkage, n->u.function);
+ case DEBUG_OBJECT_INT_CONSTANT:
+ return (*fns->int_constant) (fhandle, n->name, n->u.int_constant);
+ case DEBUG_OBJECT_FLOAT_CONSTANT:
+ return (*fns->float_constant) (fhandle, n->name, n->u.float_constant);
+ case DEBUG_OBJECT_TYPED_CONSTANT:
+ if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->typed_constant) (fhandle, n->name,
+ n->u.typed_constant->val);
+ default:
+ abort ();
+ return false;
+ }
+ /*NOTREACHED*/
+}
+
+/* Write out a type. If the type is DEBUG_KIND_NAMED or
+ DEBUG_KIND_TAGGED, then the name argument is the name for which we
+ are about to call typedef or tag. If the type is anything else,
+ then the name argument is a tag from a DEBUG_KIND_TAGGED type which
+ points to this one. */
+
+static boolean
+debug_write_type (info, fns, fhandle, type, name)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_type *type;
+ struct debug_name *name;
+{
+ unsigned int i;
+ int is;
+ const char *tag;
+
+ /* If we have a name for this type, just output it. We only output
+ typedef names after they have been defined. We output type tags
+ whenever we are not actually defining them. */
+ if ((type->kind == DEBUG_KIND_NAMED
+ || type->kind == DEBUG_KIND_TAGGED)
+ && (type->u.knamed->name->mark == info->mark
+ || (type->kind == DEBUG_KIND_TAGGED
+ && type->u.knamed->name != name)))
+ {
+ if (type->kind == DEBUG_KIND_NAMED)
+ return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);
+ else
+ {
+ struct debug_type *real;
+ unsigned int id;
+
+ real = debug_get_real_type ((PTR) info, type);
+ id = 0;
+ if ((real->kind == DEBUG_KIND_STRUCT
+ || real->kind == DEBUG_KIND_UNION
+ || real->kind == DEBUG_KIND_CLASS
+ || real->kind == DEBUG_KIND_UNION_CLASS)
+ && real->u.kclass != NULL)
+ {
+ if (real->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info,
+ type->u.knamed->name->name,
+ real))
+ return false;
+ }
+ id = real->u.kclass->id;
+ }
+
+ return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id,
+ real->kind);
+ }
+ }
+
+ /* Mark the name after we have already looked for a known name, so
+ that we don't just define a type in terms of itself. We need to
+ mark the name here so that a struct containing a pointer to
+ itself will work. */
+ if (name != NULL)
+ name->mark = info->mark;
+
+ tag = NULL;
+ if (name != NULL
+ && type->kind != DEBUG_KIND_NAMED
+ && type->kind != DEBUG_KIND_TAGGED)
+ {
+ assert (name->kind == DEBUG_OBJECT_TAG);
+ tag = name->name;
+ }
+
+ switch (type->kind)
+ {
+ case DEBUG_KIND_ILLEGAL:
+ debug_error ("debug_write_type: illegal type encountered");
+ return false;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
+ return (*fns->empty_type) (fhandle);
+ return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot,
+ name);
+ case DEBUG_KIND_VOID:
+ return (*fns->void_type) (fhandle);
+ case DEBUG_KIND_INT:
+ return (*fns->int_type) (fhandle, type->size, type->u.kint);
+ case DEBUG_KIND_FLOAT:
+ return (*fns->float_type) (fhandle, type->size);
+ case DEBUG_KIND_COMPLEX:
+ return (*fns->complex_type) (fhandle, type->size);
+ case DEBUG_KIND_BOOL:
+ return (*fns->bool_type) (fhandle, type->size);
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ if (type->u.kclass != NULL)
+ {
+ if (type->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info, tag, type))
+ return false;
+ }
+
+ if (info->mark == type->u.kclass->mark)
+ {
+ /* We are currently outputting this struct, or we have
+ already output it. I don't know if this can happen,
+ but it can happen for a class. */
+ assert (type->u.kclass->id > info->base_id);
+ return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
+ type->kind);
+ }
+ type->u.kclass->mark = info->mark;
+ }
+
+ if (! (*fns->start_struct_type) (fhandle, tag,
+ (type->u.kclass != NULL
+ ? type->u.kclass->id
+ : 0),
+ type->kind == DEBUG_KIND_STRUCT,
+ type->size))
+ return false;
+ if (type->u.kclass != NULL
+ && type->u.kclass->fields != NULL)
+ {
+ for (i = 0; type->u.kclass->fields[i] != NULL; i++)
+ {
+ struct debug_field *f;
+
+ f = type->u.kclass->fields[i];
+ if (! debug_write_type (info, fns, fhandle, f->type,
+ (struct debug_name *) NULL)
+ || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
+ f->u.f.bitsize, f->visibility))
+ return false;
+ }
+ }
+ return (*fns->end_struct_type) (fhandle);
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ return debug_write_class_type (info, fns, fhandle, type, tag);
+ case DEBUG_KIND_ENUM:
+ if (type->u.kenum == NULL)
+ return (*fns->enum_type) (fhandle, tag, (const char **) NULL,
+ (bfd_signed_vma *) NULL);
+ return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
+ type->u.kenum->values);
+ case DEBUG_KIND_POINTER:
+ if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->pointer_type) (fhandle);
+ case DEBUG_KIND_FUNCTION:
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kfunction->return_type,
+ (struct debug_name *) NULL))
+ return false;
+ if (type->u.kfunction->arg_types == NULL)
+ is = -1;
+ else
+ {
+ for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kfunction->arg_types[is],
+ (struct debug_name *) NULL))
+ return false;
+ }
+ return (*fns->function_type) (fhandle, is,
+ type->u.kfunction->varargs);
+ case DEBUG_KIND_REFERENCE:
+ if (! debug_write_type (info, fns, fhandle, type->u.kreference,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->reference_type) (fhandle);
+ case DEBUG_KIND_RANGE:
+ if (! debug_write_type (info, fns, fhandle, type->u.krange->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->range_type) (fhandle, type->u.krange->lower,
+ type->u.krange->upper);
+ case DEBUG_KIND_ARRAY:
+ if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type,
+ (struct debug_name *) NULL)
+ || ! debug_write_type (info, fns, fhandle,
+ type->u.karray->range_type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->array_type) (fhandle, type->u.karray->lower,
+ type->u.karray->upper,
+ type->u.karray->stringp);
+ case DEBUG_KIND_SET:
+ if (! debug_write_type (info, fns, fhandle, type->u.kset->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->set_type) (fhandle, type->u.kset->bitstringp);
+ case DEBUG_KIND_OFFSET:
+ if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type,
+ (struct debug_name *) NULL)
+ || ! debug_write_type (info, fns, fhandle,
+ type->u.koffset->target_type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->offset_type) (fhandle);
+ case DEBUG_KIND_METHOD:
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->return_type,
+ (struct debug_name *) NULL))
+ return false;
+ if (type->u.kmethod->arg_types == NULL)
+ is = -1;
+ else
+ {
+ for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->arg_types[is],
+ (struct debug_name *) NULL))
+ return false;
+ }
+ if (type->u.kmethod->domain_type != NULL)
+ {
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->domain_type,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ return (*fns->method_type) (fhandle,
+ type->u.kmethod->domain_type != NULL,
+ is,
+ type->u.kmethod->varargs);
+ case DEBUG_KIND_CONST:
+ if (! debug_write_type (info, fns, fhandle, type->u.kconst,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->const_type) (fhandle);
+ case DEBUG_KIND_VOLATILE:
+ if (! debug_write_type (info, fns, fhandle, type->u.kvolatile,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->volatile_type) (fhandle);
+ case DEBUG_KIND_NAMED:
+ return debug_write_type (info, fns, fhandle, type->u.knamed->type,
+ (struct debug_name *) NULL);
+ case DEBUG_KIND_TAGGED:
+ return debug_write_type (info, fns, fhandle, type->u.knamed->type,
+ type->u.knamed->name);
+ default:
+ abort ();
+ return false;
+ }
+}
+
+/* Write out a class type. */
+
+static boolean
+debug_write_class_type (info, fns, fhandle, type, tag)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_type *type;
+ const char *tag;
+{
+ unsigned int i;
+ unsigned int id;
+ struct debug_type *vptrbase;
+
+ if (type->u.kclass == NULL)
+ {
+ id = 0;
+ vptrbase = NULL;
+ }
+ else
+ {
+ if (type->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info, tag, type))
+ return false;
+ }
+
+ if (info->mark == type->u.kclass->mark)
+ {
+ /* We are currently outputting this class, or we have
+ already output it. This can happen when there are
+ methods for an anonymous class. */
+ assert (type->u.kclass->id > info->base_id);
+ return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
+ type->kind);
+ }
+ type->u.kclass->mark = info->mark;
+ id = type->u.kclass->id;
+
+ vptrbase = type->u.kclass->vptrbase;
+ if (vptrbase != NULL && vptrbase != type)
+ {
+ if (! debug_write_type (info, fns, fhandle, vptrbase,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ }
+
+ if (! (*fns->start_class_type) (fhandle, tag, id,
+ type->kind == DEBUG_KIND_CLASS,
+ type->size,
+ vptrbase != NULL,
+ vptrbase == type))
+ return false;
+
+ if (type->u.kclass != NULL)
+ {
+ if (type->u.kclass->fields != NULL)
+ {
+ for (i = 0; type->u.kclass->fields[i] != NULL; i++)
+ {
+ struct debug_field *f;
+
+ f = type->u.kclass->fields[i];
+ if (! debug_write_type (info, fns, fhandle, f->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (f->static_member)
+ {
+ if (! (*fns->class_static_member) (fhandle, f->name,
+ f->u.s.physname,
+ f->visibility))
+ return false;
+ }
+ else
+ {
+ if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
+ f->u.f.bitsize, f->visibility))
+ return false;
+ }
+ }
+ }
+
+ if (type->u.kclass->baseclasses != NULL)
+ {
+ for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
+ {
+ struct debug_baseclass *b;
+
+ b = type->u.kclass->baseclasses[i];
+ if (! debug_write_type (info, fns, fhandle, b->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
+ b->visibility))
+ return false;
+ }
+ }
+
+ if (type->u.kclass->methods != NULL)
+ {
+ for (i = 0; type->u.kclass->methods[i] != NULL; i++)
+ {
+ struct debug_method *m;
+ unsigned int j;
+
+ m = type->u.kclass->methods[i];
+ if (! (*fns->class_start_method) (fhandle, m->name))
+ return false;
+ for (j = 0; m->variants[j] != NULL; j++)
+ {
+ struct debug_method_variant *v;
+
+ v = m->variants[j];
+ if (v->context != NULL)
+ {
+ if (! debug_write_type (info, fns, fhandle, v->context,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ if (! debug_write_type (info, fns, fhandle, v->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (v->voffset != VOFFSET_STATIC_METHOD)
+ {
+ if (! (*fns->class_method_variant) (fhandle, v->physname,
+ v->visibility,
+ v->constp,
+ v->volatilep,
+ v->voffset,
+ v->context != NULL))
+ return false;
+ }
+ else
+ {
+ if (! (*fns->class_static_method_variant) (fhandle,
+ v->physname,
+ v->visibility,
+ v->constp,
+ v->volatilep))
+ return false;
+ }
+ }
+ if (! (*fns->class_end_method) (fhandle))
+ return false;
+ }
+ }
+ }
+
+ return (*fns->end_class_type) (fhandle);
+}
+
+/* Write out information for a function. */
+
+static boolean
+debug_write_function (info, fns, fhandle, name, linkage, function)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ const char *name;
+ enum debug_object_linkage linkage;
+ struct debug_function *function;
+{
+ struct debug_parameter *p;
+ struct debug_block *b;
+
+ if (! debug_write_linenos (info, fns, fhandle, function->blocks->start))
+ return false;
+
+ if (! debug_write_type (info, fns, fhandle, function->return_type,
+ (struct debug_name *) NULL))
+ return false;
+
+ if (! (*fns->start_function) (fhandle, name,
+ linkage == DEBUG_LINKAGE_GLOBAL))
+ return false;
+
+ for (p = function->parameters; p != NULL; p = p->next)
+ {
+ if (! debug_write_type (info, fns, fhandle, p->type,
+ (struct debug_name *) NULL)
+ || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val))
+ return false;
+ }
+
+ for (b = function->blocks; b != NULL; b = b->next)
+ {
+ if (! debug_write_block (info, fns, fhandle, b))
+ return false;
+ }
+
+ return (*fns->end_function) (fhandle);
+}
+
+/* Write out information for a block. */
+
+static boolean
+debug_write_block (info, fns, fhandle, block)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_block *block;
+{
+ struct debug_name *n;
+ struct debug_block *b;
+
+ if (! debug_write_linenos (info, fns, fhandle, block->start))
+ return false;
+
+ /* I can't see any point to writing out a block with no local
+ variables, so we don't bother, except for the top level block. */
+ if (block->locals != NULL || block->parent == NULL)
+ {
+ if (! (*fns->start_block) (fhandle, block->start))
+ return false;
+ }
+
+ if (block->locals != NULL)
+ {
+ for (n = block->locals->list; n != NULL; n = n->next)
+ {
+ if (! debug_write_name (info, fns, fhandle, n))
+ return false;
+ }
+ }
+
+ for (b = block->children; b != NULL; b = b->next)
+ {
+ if (! debug_write_block (info, fns, fhandle, b))
+ return false;
+ }
+
+ if (! debug_write_linenos (info, fns, fhandle, block->end))
+ return false;
+
+ if (block->locals != NULL || block->parent == NULL)
+ {
+ if (! (*fns->end_block) (fhandle, block->end))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out line number information up to ADDRESS. */
+
+static boolean
+debug_write_linenos (info, fns, fhandle, address)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ bfd_vma address;
+{
+ while (info->current_write_lineno != NULL)
+ {
+ struct debug_lineno *l;
+
+ l = info->current_write_lineno;
+
+ while (info->current_write_lineno_index < DEBUG_LINENO_COUNT)
+ {
+ if (l->linenos[info->current_write_lineno_index]
+ == (unsigned long) -1)
+ break;
+
+ if (l->addrs[info->current_write_lineno_index] >= address)
+ return true;
+
+ if (! (*fns->lineno) (fhandle, l->file->filename,
+ l->linenos[info->current_write_lineno_index],
+ l->addrs[info->current_write_lineno_index]))
+ return false;
+
+ ++info->current_write_lineno_index;
+ }
+
+ info->current_write_lineno = l->next;
+ info->current_write_lineno_index = 0;
+ }
+
+ return true;
+}
+
+/* Get the ID number for a class. If during the same call to
+ debug_write we find a struct with the same definition with the same
+ name, we use the same ID. This type of things happens because the
+ same struct will be defined by multiple compilation units. */
+
+static boolean
+debug_set_class_id (info, tag, type)
+ struct debug_handle *info;
+ const char *tag;
+ struct debug_type *type;
+{
+ struct debug_class_type *c;
+ struct debug_class_id *l;
+
+ assert (type->kind == DEBUG_KIND_STRUCT
+ || type->kind == DEBUG_KIND_UNION
+ || type->kind == DEBUG_KIND_CLASS
+ || type->kind == DEBUG_KIND_UNION_CLASS);
+
+ c = type->u.kclass;
+
+ if (c->id > info->base_id)
+ return true;
+
+ for (l = info->id_list; l != NULL; l = l->next)
+ {
+ if (l->type->kind != type->kind)
+ continue;
+
+ if (tag == NULL)
+ {
+ if (l->tag != NULL)
+ continue;
+ }
+ else
+ {
+ if (l->tag == NULL
+ || l->tag[0] != tag[0]
+ || strcmp (l->tag, tag) != 0)
+ continue;
+ }
+
+ if (debug_type_samep (info, l->type, type))
+ {
+ c->id = l->type->u.kclass->id;
+ return true;
+ }
+ }
+
+ /* There are no identical types. Use a new ID, and add it to the
+ list. */
+ ++info->class_id;
+ c->id = info->class_id;
+
+ l = (struct debug_class_id *) xmalloc (sizeof *l);
+ memset (l, 0, sizeof *l);
+
+ l->type = type;
+ l->tag = tag;
+
+ l->next = info->id_list;
+ info->id_list = l;
+
+ return true;
+}
+
+/* See if two types are the same. At this point, we don't care about
+ tags and the like. */
+
+static boolean
+debug_type_samep (info, t1, t2)
+ struct debug_handle *info;
+ struct debug_type *t1;
+ struct debug_type *t2;
+{
+ struct debug_type_compare_list *l;
+ struct debug_type_compare_list top;
+ boolean ret;
+
+ if (t1 == NULL)
+ return t2 == NULL;
+ if (t2 == NULL)
+ return false;
+
+ while (t1->kind == DEBUG_KIND_INDIRECT)
+ {
+ t1 = *t1->u.kindirect->slot;
+ if (t1 == NULL)
+ return false;
+ }
+ while (t2->kind == DEBUG_KIND_INDIRECT)
+ {
+ t2 = *t2->u.kindirect->slot;
+ if (t2 == NULL)
+ return false;
+ }
+
+ if (t1 == t2)
+ return true;
+
+ /* As a special case, permit a typedef to match a tag, since C++
+ debugging output will sometimes add a typedef where C debugging
+ output will not. */
+ if (t1->kind == DEBUG_KIND_NAMED
+ && t2->kind == DEBUG_KIND_TAGGED)
+ return debug_type_samep (info, t1->u.knamed->type, t2);
+ else if (t1->kind == DEBUG_KIND_TAGGED
+ && t2->kind == DEBUG_KIND_NAMED)
+ return debug_type_samep (info, t1, t2->u.knamed->type);
+
+ if (t1->kind != t2->kind
+ || t1->size != t2->size)
+ return false;
+
+ /* Get rid of the trivial cases first. */
+ switch (t1->kind)
+ {
+ default:
+ break;
+ case DEBUG_KIND_VOID:
+ case DEBUG_KIND_FLOAT:
+ case DEBUG_KIND_COMPLEX:
+ case DEBUG_KIND_BOOL:
+ return true;
+ case DEBUG_KIND_INT:
+ return t1->u.kint == t2->u.kint;
+ }
+
+ /* We have to avoid an infinite recursion. We do this by keeping a
+ list of types which we are comparing. We just keep the list on
+ the stack. If we encounter a pair of types we are currently
+ comparing, we just assume that they are equal. */
+ for (l = info->compare_list; l != NULL; l = l->next)
+ {
+ if (l->t1 == t1 && l->t2 == t2)
+ return true;
+ }
+
+ top.t1 = t1;
+ top.t2 = t2;
+ top.next = info->compare_list;
+ info->compare_list = &top;
+
+ switch (t1->kind)
+ {
+ default:
+ abort ();
+ ret = false;
+ break;
+
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ if (t1->u.kclass == NULL)
+ ret = t2->u.kclass == NULL;
+ else if (t2->u.kclass == NULL)
+ ret = false;
+ else if (t1->u.kclass->id > info->base_id
+ && t1->u.kclass->id == t2->u.kclass->id)
+ ret = true;
+ else
+ ret = debug_class_type_samep (info, t1, t2);
+ break;
+
+ case DEBUG_KIND_ENUM:
+ if (t1->u.kenum == NULL)
+ ret = t2->u.kenum == NULL;
+ else if (t2->u.kenum == NULL)
+ ret = false;
+ else
+ {
+ const char **pn1, **pn2;
+ bfd_signed_vma *pv1, *pv2;
+
+ pn1 = t1->u.kenum->names;
+ pn2 = t2->u.kenum->names;
+ pv1 = t1->u.kenum->values;
+ pv2 = t2->u.kenum->values;
+ while (*pn1 != NULL && *pn2 != NULL)
+ {
+ if (**pn1 != **pn2
+ || *pv1 != *pv2
+ || strcmp (*pn1, *pn2) != 0)
+ break;
+ ++pn1;
+ ++pn2;
+ ++pv1;
+ ++pv2;
+ }
+ ret = *pn1 == NULL && *pn2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_POINTER:
+ ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer);
+ break;
+
+ case DEBUG_KIND_FUNCTION:
+ if (t1->u.kfunction->varargs != t2->u.kfunction->varargs
+ || ! debug_type_samep (info, t1->u.kfunction->return_type,
+ t2->u.kfunction->return_type)
+ || ((t1->u.kfunction->arg_types == NULL)
+ != (t2->u.kfunction->arg_types == NULL)))
+ ret = false;
+ else if (t1->u.kfunction->arg_types == NULL)
+ ret = true;
+ else
+ {
+ struct debug_type **a1, **a2;
+
+ a1 = t1->u.kfunction->arg_types;
+ a2 = t2->u.kfunction->arg_types;
+ while (*a1 != NULL && *a2 != NULL)
+ if (! debug_type_samep (info, *a1, *a2))
+ break;
+ ret = *a1 == NULL && *a2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_REFERENCE:
+ ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference);
+ break;
+
+ case DEBUG_KIND_RANGE:
+ ret = (t1->u.krange->lower == t2->u.krange->lower
+ && t1->u.krange->upper == t2->u.krange->upper
+ && debug_type_samep (info, t1->u.krange->type,
+ t2->u.krange->type));
+
+ case DEBUG_KIND_ARRAY:
+ ret = (t1->u.karray->lower == t2->u.karray->lower
+ && t1->u.karray->upper == t2->u.karray->upper
+ && t1->u.karray->stringp == t2->u.karray->stringp
+ && debug_type_samep (info, t1->u.karray->element_type,
+ t2->u.karray->element_type));
+ break;
+
+ case DEBUG_KIND_SET:
+ ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp
+ && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type));
+ break;
+
+ case DEBUG_KIND_OFFSET:
+ ret = (debug_type_samep (info, t1->u.koffset->base_type,
+ t2->u.koffset->base_type)
+ && debug_type_samep (info, t1->u.koffset->target_type,
+ t2->u.koffset->target_type));
+ break;
+
+ case DEBUG_KIND_METHOD:
+ if (t1->u.kmethod->varargs != t2->u.kmethod->varargs
+ || ! debug_type_samep (info, t1->u.kmethod->return_type,
+ t2->u.kmethod->return_type)
+ || ! debug_type_samep (info, t1->u.kmethod->domain_type,
+ t2->u.kmethod->domain_type)
+ || ((t1->u.kmethod->arg_types == NULL)
+ != (t2->u.kmethod->arg_types == NULL)))
+ ret = false;
+ else if (t1->u.kmethod->arg_types == NULL)
+ ret = true;
+ else
+ {
+ struct debug_type **a1, **a2;
+
+ a1 = t1->u.kmethod->arg_types;
+ a2 = t2->u.kmethod->arg_types;
+ while (*a1 != NULL && *a2 != NULL)
+ if (! debug_type_samep (info, *a1, *a2))
+ break;
+ ret = *a1 == NULL && *a2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_CONST:
+ ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst);
+ break;
+
+ case DEBUG_KIND_VOLATILE:
+ ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile);
+ break;
+
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0
+ && debug_type_samep (info, t1->u.knamed->type,
+ t2->u.knamed->type));
+ break;
+ }
+
+ info->compare_list = top.next;
+
+ return ret;
+}
+
+/* See if two classes are the same. This is a subroutine of
+ debug_type_samep. */
+
+static boolean
+debug_class_type_samep (info, t1, t2)
+ struct debug_handle *info;
+ struct debug_type *t1;
+ struct debug_type *t2;
+{
+ struct debug_class_type *c1, *c2;
+
+ c1 = t1->u.kclass;
+ c2 = t2->u.kclass;
+
+ if ((c1->fields == NULL) != (c2->fields == NULL)
+ || (c1->baseclasses == NULL) != (c2->baseclasses == NULL)
+ || (c1->methods == NULL) != (c2->methods == NULL)
+ || (c1->vptrbase == NULL) != (c2->vptrbase == NULL))
+ return false;
+
+ if (c1->fields != NULL)
+ {
+ struct debug_field **pf1, **pf2;
+
+ for (pf1 = c1->fields, pf2 = c2->fields;
+ *pf1 != NULL && *pf2 != NULL;
+ pf1++, pf2++)
+ {
+ struct debug_field *f1, *f2;
+
+ f1 = *pf1;
+ f2 = *pf2;
+ if (f1->name[0] != f2->name[0]
+ || f1->visibility != f2->visibility
+ || f1->static_member != f2->static_member)
+ return false;
+ if (f1->static_member)
+ {
+ if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0)
+ return false;
+ }
+ else
+ {
+ if (f1->u.f.bitpos != f2->u.f.bitpos
+ || f1->u.f.bitsize != f2->u.f.bitsize)
+ return false;
+ }
+ /* We do the checks which require function calls last. We
+ don't require that the types of fields have the same
+ names, since that sometimes fails in the presence of
+ typedefs and we really don't care. */
+ if (strcmp (f1->name, f2->name) != 0
+ || ! debug_type_samep (info,
+ debug_get_real_type ((PTR) info,
+ f1->type),
+ debug_get_real_type ((PTR) info,
+ f2->type)))
+ return false;
+ }
+ if (*pf1 != NULL || *pf2 != NULL)
+ return false;
+ }
+
+ if (c1->vptrbase != NULL)
+ {
+ if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase))
+ return false;
+ }
+
+ if (c1->baseclasses != NULL)
+ {
+ struct debug_baseclass **pb1, **pb2;
+
+ for (pb1 = c1->baseclasses, pb2 = c2->baseclasses;
+ *pb1 != NULL && *pb2 != NULL;
+ ++pb1, ++pb2)
+ {
+ struct debug_baseclass *b1, *b2;
+
+ b1 = *pb1;
+ b2 = *pb2;
+ if (b1->bitpos != b2->bitpos
+ || b1->virtual != b2->virtual
+ || b1->visibility != b2->visibility
+ || ! debug_type_samep (info, b1->type, b2->type))
+ return false;
+ }
+ if (*pb1 != NULL || *pb2 != NULL)
+ return false;
+ }
+
+ if (c1->methods != NULL)
+ {
+ struct debug_method **pm1, **pm2;
+
+ for (pm1 = c1->methods, pm2 = c2->methods;
+ *pm1 != NULL && *pm2 != NULL;
+ ++pm1, ++pm2)
+ {
+ struct debug_method *m1, *m2;
+
+ m1 = *pm1;
+ m2 = *pm2;
+ if (m1->name[0] != m2->name[0]
+ || strcmp (m1->name, m2->name) != 0
+ || (m1->variants == NULL) != (m2->variants == NULL))
+ return false;
+ if (m1->variants == NULL)
+ {
+ struct debug_method_variant **pv1, **pv2;
+
+ for (pv1 = m1->variants, pv2 = m2->variants;
+ *pv1 != NULL && *pv2 != NULL;
+ ++pv1, ++pv2)
+ {
+ struct debug_method_variant *v1, *v2;
+
+ v1 = *pv1;
+ v2 = *pv2;
+ if (v1->physname[0] != v2->physname[0]
+ || v1->visibility != v2->visibility
+ || v1->constp != v2->constp
+ || v1->volatilep != v2->volatilep
+ || v1->voffset != v2->voffset
+ || (v1->context == NULL) != (v2->context == NULL)
+ || strcmp (v1->physname, v2->physname) != 0
+ || ! debug_type_samep (info, v1->type, v2->type))
+ return false;
+ if (v1->context != NULL)
+ {
+ if (! debug_type_samep (info, v1->context,
+ v2->context))
+ return false;
+ }
+ }
+ if (*pv1 != NULL || *pv2 != NULL)
+ return false;
+ }
+ }
+ if (*pm1 != NULL || *pm2 != NULL)
+ return false;
+ }
+
+ return true;
+}
diff --git a/pstack/debug.h b/pstack/debug.h
new file mode 100644
index 00000000000..a4d3d8306cd
--- /dev/null
+++ b/pstack/debug.h
@@ -0,0 +1,798 @@
+/* debug.h -- Describe generic debugging information.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/* This header file describes a generic debugging information format.
+ We may eventually have readers which convert different formats into
+ this generic format, and writers which write it out. The initial
+ impetus for this was writing a convertor from stabs to HP IEEE-695
+ debugging format. */
+
+/* Different kinds of types. */
+
+enum debug_type_kind
+{
+ /* Not used. */
+ DEBUG_KIND_ILLEGAL,
+ /* Indirect via a pointer. */
+ DEBUG_KIND_INDIRECT,
+ /* Void. */
+ DEBUG_KIND_VOID,
+ /* Integer. */
+ DEBUG_KIND_INT,
+ /* Floating point. */
+ DEBUG_KIND_FLOAT,
+ /* Complex. */
+ DEBUG_KIND_COMPLEX,
+ /* Boolean. */
+ DEBUG_KIND_BOOL,
+ /* Struct. */
+ DEBUG_KIND_STRUCT,
+ /* Union. */
+ DEBUG_KIND_UNION,
+ /* Class. */
+ DEBUG_KIND_CLASS,
+ /* Union class (can this really happen?). */
+ DEBUG_KIND_UNION_CLASS,
+ /* Enumeration type. */
+ DEBUG_KIND_ENUM,
+ /* Pointer. */
+ DEBUG_KIND_POINTER,
+ /* Function. */
+ DEBUG_KIND_FUNCTION,
+ /* Reference. */
+ DEBUG_KIND_REFERENCE,
+ /* Range. */
+ DEBUG_KIND_RANGE,
+ /* Array. */
+ DEBUG_KIND_ARRAY,
+ /* Set. */
+ DEBUG_KIND_SET,
+ /* Based pointer. */
+ DEBUG_KIND_OFFSET,
+ /* Method. */
+ DEBUG_KIND_METHOD,
+ /* Const qualified type. */
+ DEBUG_KIND_CONST,
+ /* Volatile qualified type. */
+ DEBUG_KIND_VOLATILE,
+ /* Named type. */
+ DEBUG_KIND_NAMED,
+ /* Tagged type. */
+ DEBUG_KIND_TAGGED
+};
+
+/* Different kinds of variables. */
+
+enum debug_var_kind
+{
+ /* Not used. */
+ DEBUG_VAR_ILLEGAL,
+ /* A global variable. */
+ DEBUG_GLOBAL,
+ /* A static variable. */
+ DEBUG_STATIC,
+ /* A local static variable. */
+ DEBUG_LOCAL_STATIC,
+ /* A local variable. */
+ DEBUG_LOCAL,
+ /* A register variable. */
+ DEBUG_REGISTER
+};
+
+/* Different kinds of function parameters. */
+
+enum debug_parm_kind
+{
+ /* Not used. */
+ DEBUG_PARM_ILLEGAL,
+ /* A stack based parameter. */
+ DEBUG_PARM_STACK,
+ /* A register parameter. */
+ DEBUG_PARM_REG,
+ /* A stack based reference parameter. */
+ DEBUG_PARM_REFERENCE,
+ /* A register reference parameter. */
+ DEBUG_PARM_REF_REG
+};
+
+/* Different kinds of visibility. */
+
+enum debug_visibility
+{
+ /* A public field (e.g., a field in a C struct). */
+ DEBUG_VISIBILITY_PUBLIC,
+ /* A protected field. */
+ DEBUG_VISIBILITY_PROTECTED,
+ /* A private field. */
+ DEBUG_VISIBILITY_PRIVATE,
+ /* A field which should be ignored. */
+ DEBUG_VISIBILITY_IGNORE
+};
+
+/* A type. */
+
+typedef struct debug_type *debug_type;
+
+#define DEBUG_TYPE_NULL ((debug_type) NULL)
+
+/* A field in a struct or union. */
+
+typedef struct debug_field *debug_field;
+
+#define DEBUG_FIELD_NULL ((debug_field) NULL)
+
+/* A base class for an object. */
+
+typedef struct debug_baseclass *debug_baseclass;
+
+#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL)
+
+/* A method of an object. */
+
+typedef struct debug_method *debug_method;
+
+#define DEBUG_METHOD_NULL ((debug_method) NULL)
+
+/* The arguments to a method function of an object. These indicate
+ which method to run. */
+
+typedef struct debug_method_variant *debug_method_variant;
+
+#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL)
+
+/* This structure is passed to debug_write. It holds function
+ pointers that debug_write will call based on the accumulated
+ debugging information. */
+
+struct debug_write_fns
+{
+ /* This is called at the start of each new compilation unit with the
+ name of the main file in the new unit. */
+ boolean (*start_compilation_unit) PARAMS ((PTR, const char *));
+
+ /* This is called at the start of each source file within a
+ compilation unit, before outputting any global information for
+ that file. The argument is the name of the file. */
+ boolean (*start_source) PARAMS ((PTR, const char *));
+
+ /* Each writer must keep a stack of types. */
+
+ /* Push an empty type onto the type stack. This type can appear if
+ there is a reference to a type which is never defined. */
+ boolean (*empty_type) PARAMS ((PTR));
+
+ /* Push a void type onto the type stack. */
+ boolean (*void_type) PARAMS ((PTR));
+
+ /* Push an integer type onto the type stack, given the size and
+ whether it is unsigned. */
+ boolean (*int_type) PARAMS ((PTR, unsigned int, boolean));
+
+ /* Push a floating type onto the type stack, given the size. */
+ boolean (*float_type) PARAMS ((PTR, unsigned int));
+
+ /* Push a complex type onto the type stack, given the size. */
+ boolean (*complex_type) PARAMS ((PTR, unsigned int));
+
+ /* Push a boolean type onto the type stack, given the size. */
+ boolean (*bool_type) PARAMS ((PTR, unsigned int));
+
+ /* Push an enum type onto the type stack, given the tag, a NULL
+ terminated array of names and the associated values. If there is
+ no tag, the tag argument will be NULL. If this is an undefined
+ enum, the names and values arguments will be NULL. */
+ boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
+ bfd_signed_vma *));
+
+ /* Pop the top type on the type stack, and push a pointer to that
+ type onto the type stack. */
+ boolean (*pointer_type) PARAMS ((PTR));
+
+ /* Push a function type onto the type stack. The second argument
+ indicates the number of argument types that have been pushed onto
+ the stack. If the number of argument types is passed as -1, then
+ the argument types of the function are unknown, and no types have
+ been pushed onto the stack. The third argument is true if the
+ function takes a variable number of arguments. The return type
+ of the function is pushed onto the type stack below the argument
+ types, if any. */
+ boolean (*function_type) PARAMS ((PTR, int, boolean));
+
+ /* Pop the top type on the type stack, and push a reference to that
+ type onto the type stack. */
+ boolean (*reference_type) PARAMS ((PTR));
+
+ /* Pop the top type on the type stack, and push a range of that type
+ with the given lower and upper bounds onto the type stack. */
+ boolean (*range_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+
+ /* Push an array type onto the type stack. The top type on the type
+ stack is the range, and the next type on the type stack is the
+ element type. These should be popped before the array type is
+ pushed. The arguments are the lower bound, the upper bound, and
+ whether the array is a string. */
+ boolean (*array_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma,
+ boolean));
+
+ /* Pop the top type on the type stack, and push a set of that type
+ onto the type stack. The argument indicates whether this set is
+ a bitstring. */
+ boolean (*set_type) PARAMS ((PTR, boolean));
+
+ /* Push an offset type onto the type stack. The top type on the
+ type stack is the target type, and the next type on the type
+ stack is the base type. These should be popped before the offset
+ type is pushed. */
+ boolean (*offset_type) PARAMS ((PTR));
+
+ /* Push a method type onto the type stack. If the second argument
+ is true, the top type on the stack is the class to which the
+ method belongs; otherwise, the class must be determined by the
+ class to which the method is attached. The third argument is the
+ number of argument types; these are pushed onto the type stack in
+ reverse order (the first type popped is the last argument to the
+ method). A value of -1 for the third argument means that no
+ argument information is available. The fourth argument is true
+ if the function takes a variable number of arguments. The next
+ type on the type stack below the domain and the argument types is
+ the return type of the method. All these types must be popped,
+ and then the method type must be pushed. */
+ boolean (*method_type) PARAMS ((PTR, boolean, int, boolean));
+
+ /* Pop the top type off the type stack, and push a const qualified
+ version of that type onto the type stack. */
+ boolean (*const_type) PARAMS ((PTR));
+
+ /* Pop the top type off the type stack, and push a volatile
+ qualified version of that type onto the type stack. */
+ boolean (*volatile_type) PARAMS ((PTR));
+
+ /* Start building a struct. This is followed by calls to the
+ struct_field function, and finished by a call to the
+ end_struct_type function. The second argument is the tag; this
+ will be NULL if there isn't one. If the second argument is NULL,
+ the third argument is a constant identifying this struct for use
+ with tag_type. The fourth argument is true for a struct, false
+ for a union. The fifth argument is the size. If this is an
+ undefined struct or union, the size will be 0 and struct_field
+ will not be called before end_struct_type is called. */
+ boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int,
+ boolean, unsigned int));
+
+ /* Add a field to the struct type currently being built. The type
+ of the field should be popped off the type stack. The arguments
+ are the name, the bit position, the bit size (may be zero if the
+ field is not packed), and the visibility. */
+ boolean (*struct_field) PARAMS ((PTR, const char *, bfd_vma, bfd_vma,
+ enum debug_visibility));
+
+ /* Finish building a struct, and push it onto the type stack. */
+ boolean (*end_struct_type) PARAMS ((PTR));
+
+ /* Start building a class. This is followed by calls to several
+ functions: struct_field, class_static_member, class_baseclass,
+ class_start_method, class_method_variant,
+ class_static_method_variant, and class_end_method. The class is
+ finished by a call to end_class_type. The first five arguments
+ are the same as for start_struct_type. The sixth argument is
+ true if there is a virtual function table; if there is, the
+ seventh argument is true if the virtual function table can be
+ found in the type itself, and is false if the type of the object
+ holding the virtual function table should be popped from the type
+ stack. */
+ boolean (*start_class_type) PARAMS ((PTR, const char *, unsigned int,
+ boolean, unsigned int, boolean,
+ boolean));
+
+ /* Add a static member to the class currently being built. The
+ arguments are the field name, the physical name, and the
+ visibility. The type must be popped off the type stack. */
+ boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
+ enum debug_visibility));
+
+ /* Add a baseclass to the class currently being built. The type of
+ the baseclass must be popped off the type stack. The arguments
+ are the bit position, whether the class is virtual, and the
+ visibility. */
+ boolean (*class_baseclass) PARAMS ((PTR, bfd_vma, boolean,
+ enum debug_visibility));
+
+ /* Start adding a method to the class currently being built. This
+ is followed by calls to class_method_variant and
+ class_static_method_variant to describe different variants of the
+ method which take different arguments. The method is finished
+ with a call to class_end_method. The argument is the method
+ name. */
+ boolean (*class_start_method) PARAMS ((PTR, const char *));
+
+ /* Describe a variant to the class method currently being built.
+ The type of the variant must be popped off the type stack. The
+ second argument is the physical name of the function. The
+ following arguments are the visibility, whether the variant is
+ const, whether the variant is volatile, the offset in the virtual
+ function table, and whether the context is on the type stack
+ (below the variant type). */
+ boolean (*class_method_variant) PARAMS ((PTR, const char *,
+ enum debug_visibility,
+ boolean, boolean,
+ bfd_vma, boolean));
+
+ /* Describe a static variant to the class method currently being
+ built. The arguments are the same as for class_method_variant,
+ except that the last two arguments are omitted. The type of the
+ variant must be popped off the type stack. */
+ boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
+ enum debug_visibility,
+ boolean, boolean));
+
+ /* Finish describing a class method. */
+ boolean (*class_end_method) PARAMS ((PTR));
+
+ /* Finish describing a class, and push it onto the type stack. */
+ boolean (*end_class_type) PARAMS ((PTR));
+
+ /* Push a type on the stack which was given a name by an earlier
+ call to typdef. */
+ boolean (*typedef_type) PARAMS ((PTR, const char *));
+
+ /* Push a tagged type on the stack which was defined earlier. If
+ the second argument is not NULL, the type was defined by a call
+ to tag. If the second argument is NULL, the type was defined by
+ a call to start_struct_type or start_class_type with a tag of
+ NULL and the number of the third argument. Either way, the
+ fourth argument is the tag kind. Note that this may be called
+ for a struct (class) being defined, in between the call to
+ start_struct_type (start_class_type) and the call to
+ end_struct_type (end_class_type). */
+ boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int,
+ enum debug_type_kind));
+
+ /* Pop the type stack, and typedef it to the given name. */
+ boolean (*typdef) PARAMS ((PTR, const char *));
+
+ /* Pop the type stack, and declare it as a tagged struct or union or
+ enum or whatever. The tag passed down here is redundant, since
+ was also passed when enum_type, start_struct_type, or
+ start_class_type was called. */
+ boolean (*tag) PARAMS ((PTR, const char *));
+
+ /* This is called to record a named integer constant. */
+ boolean (*int_constant) PARAMS ((PTR, const char *, bfd_vma));
+
+ /* This is called to record a named floating point constant. */
+ boolean (*float_constant) PARAMS ((PTR, const char *, double));
+
+ /* This is called to record a typed integer constant. The type is
+ popped off the type stack. */
+ boolean (*typed_constant) PARAMS ((PTR, const char *, bfd_vma));
+
+ /* This is called to record a variable. The type is popped off the
+ type stack. */
+ boolean (*variable) PARAMS ((PTR, const char *, enum debug_var_kind,
+ bfd_vma));
+
+ /* Start writing out a function. The return type must be popped off
+ the stack. The boolean is true if the function is global. This
+ is followed by calls to function_parameter, followed by block
+ information. */
+ boolean (*start_function) PARAMS ((PTR, const char *, boolean));
+
+ /* Record a function parameter for the current function. The type
+ must be popped off the stack. */
+ boolean (*function_parameter) PARAMS ((PTR, const char *,
+ enum debug_parm_kind, bfd_vma));
+
+ /* Start writing out a block. There is at least one top level block
+ per function. Blocks may be nested. The argument is the
+ starting address of the block. */
+ boolean (*start_block) PARAMS ((PTR, bfd_vma));
+
+ /* Finish writing out a block. The argument is the ending address
+ of the block. */
+ boolean (*end_block) PARAMS ((PTR, bfd_vma));
+
+ /* Finish writing out a function. */
+ boolean (*end_function) PARAMS ((PTR));
+
+ /* Record line number information for the current compilation unit. */
+ boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+};
+
+/* Exported functions. */
+
+/* The first argument to most of these functions is a handle. This
+ handle is returned by the debug_init function. The purpose of the
+ handle is to permit the debugging routines to not use static
+ variables, and hence to be reentrant. This would be useful for a
+ program which wanted to handle two executables simultaneously. */
+
+/* Return a debugging handle. */
+
+extern PTR debug_init PARAMS ((void));
+
+/* Set the source filename. This implicitly starts a new compilation
+ unit. */
+
+extern boolean debug_set_filename PARAMS ((PTR, const char *));
+
+/* Change source files to the given file name. This is used for
+ include files in a single compilation unit. */
+
+extern boolean debug_start_source PARAMS ((PTR, const char *));
+
+/* Record a function definition. This implicitly starts a function
+ block. The debug_type argument is the type of the return value.
+ The boolean indicates whether the function is globally visible.
+ The bfd_vma is the address of the start of the function. Currently
+ the parameter types are specified by calls to
+ debug_record_parameter. */
+
+extern boolean debug_record_function
+ PARAMS ((PTR, const char *, debug_type, boolean, bfd_vma));
+
+/* Record a parameter for the current function. */
+
+extern boolean debug_record_parameter
+ PARAMS ((PTR, const char *, debug_type, enum debug_parm_kind, bfd_vma));
+
+/* End a function definition. The argument is the address where the
+ function ends. */
+
+extern boolean debug_end_function PARAMS ((PTR, bfd_vma));
+
+/* Start a block in a function. All local information will be
+ recorded in this block, until the matching call to debug_end_block.
+ debug_start_block and debug_end_block may be nested. The argument
+ is the address at which this block starts. */
+
+extern boolean debug_start_block PARAMS ((PTR, bfd_vma));
+
+/* Finish a block in a function. This matches the call to
+ debug_start_block. The argument is the address at which this block
+ ends. */
+
+extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
+
+/* Associate a line number in the current source file with a given
+ address. */
+
+extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
+
+/* Start a named common block. This is a block of variables that may
+ move in memory. */
+
+extern boolean debug_start_common_block PARAMS ((PTR, const char *));
+
+/* End a named common block. */
+
+extern boolean debug_end_common_block PARAMS ((PTR, const char *));
+
+/* Record a named integer constant. */
+
+extern boolean debug_record_int_const PARAMS ((PTR, const char *, bfd_vma));
+
+/* Record a named floating point constant. */
+
+extern boolean debug_record_float_const PARAMS ((PTR, const char *, double));
+
+/* Record a typed constant with an integral value. */
+
+extern boolean debug_record_typed_const
+ PARAMS ((PTR, const char *, debug_type, bfd_vma));
+
+/* Record a label. */
+
+extern boolean debug_record_label
+ PARAMS ((PTR, const char *, debug_type, bfd_vma));
+
+/* Record a variable. */
+
+extern boolean debug_record_variable
+ PARAMS ((PTR, const char *, debug_type, enum debug_var_kind, bfd_vma));
+
+/* Make an indirect type. The first argument is a pointer to the
+ location where the real type will be placed. The second argument
+ is the type tag, if there is one; this may be NULL; the only
+ purpose of this argument is so that debug_get_type_name can return
+ something useful. This function may be used when a type is
+ referenced before it is defined. */
+
+extern debug_type debug_make_indirect_type
+ PARAMS ((PTR, debug_type *, const char *));
+
+/* Make a void type. */
+
+extern debug_type debug_make_void_type PARAMS ((PTR));
+
+/* Make an integer type of a given size. The boolean argument is true
+ if the integer is unsigned. */
+
+extern debug_type debug_make_int_type PARAMS ((PTR, unsigned int, boolean));
+
+/* Make a floating point type of a given size. FIXME: On some
+ platforms, like an Alpha, you probably need to be able to specify
+ the format. */
+
+extern debug_type debug_make_float_type PARAMS ((PTR, unsigned int));
+
+/* Make a boolean type of a given size. */
+
+extern debug_type debug_make_bool_type PARAMS ((PTR, unsigned int));
+
+/* Make a complex type of a given size. */
+
+extern debug_type debug_make_complex_type PARAMS ((PTR, unsigned int));
+
+/* Make a structure type. The second argument is true for a struct,
+ false for a union. The third argument is the size of the struct.
+ The fourth argument is a NULL terminated array of fields. */
+
+extern debug_type debug_make_struct_type
+ PARAMS ((PTR, boolean, bfd_vma, debug_field *));
+
+/* Make an object type. The first three arguments after the handle
+ are the same as for debug_make_struct_type. The next arguments are
+ a NULL terminated array of base classes, a NULL terminated array of
+ methods, the type of the object holding the virtual function table
+ if it is not this object, and a boolean which is true if this
+ object has its own virtual function table. */
+
+extern debug_type debug_make_object_type
+ PARAMS ((PTR, boolean, bfd_vma, debug_field *, debug_baseclass *,
+ debug_method *, debug_type, boolean));
+
+/* Make an enumeration type. The arguments are a null terminated
+ array of strings, and an array of corresponding values. */
+
+extern debug_type debug_make_enum_type
+ PARAMS ((PTR, const char **, bfd_signed_vma *));
+
+/* Make a pointer to a given type. */
+
+extern debug_type debug_make_pointer_type
+ PARAMS ((PTR, debug_type));
+
+/* Make a function type. The second argument is the return type. The
+ third argument is a NULL terminated array of argument types. The
+ fourth argument is true if the function takes a variable number of
+ arguments. If the third argument is NULL, then the argument types
+ are unknown. */
+
+extern debug_type debug_make_function_type
+ PARAMS ((PTR, debug_type, debug_type *, boolean));
+
+/* Make a reference to a given type. */
+
+extern debug_type debug_make_reference_type PARAMS ((PTR, debug_type));
+
+/* Make a range of a given type from a lower to an upper bound. */
+
+extern debug_type debug_make_range_type
+ PARAMS ((PTR, debug_type, bfd_signed_vma, bfd_signed_vma));
+
+/* Make an array type. The second argument is the type of an element
+ of the array. The third argument is the type of a range of the
+ array. The fourth and fifth argument are the lower and upper
+ bounds, respectively (if the bounds are not known, lower should be
+ 0 and upper should be -1). The sixth argument is true if this
+ array is actually a string, as in C. */
+
+extern debug_type debug_make_array_type
+ PARAMS ((PTR, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma,
+ boolean));
+
+/* Make a set of a given type. For example, a Pascal set type. The
+ boolean argument is true if this set is actually a bitstring, as in
+ CHILL. */
+
+extern debug_type debug_make_set_type PARAMS ((PTR, debug_type, boolean));
+
+/* Make a type for a pointer which is relative to an object. The
+ second argument is the type of the object to which the pointer is
+ relative. The third argument is the type that the pointer points
+ to. */
+
+extern debug_type debug_make_offset_type
+ PARAMS ((PTR, debug_type, debug_type));
+
+/* Make a type for a method function. The second argument is the
+ return type. The third argument is the domain. The fourth
+ argument is a NULL terminated array of argument types. The fifth
+ argument is true if the function takes a variable number of
+ arguments, in which case the array of argument types indicates the
+ types of the first arguments. The domain and the argument array
+ may be NULL, in which case this is a stub method and that
+ information is not available. Stabs debugging uses this, and gets
+ the argument types from the mangled name. */
+
+extern debug_type debug_make_method_type
+ PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean));
+
+/* Make a const qualified version of a given type. */
+
+extern debug_type debug_make_const_type PARAMS ((PTR, debug_type));
+
+/* Make a volatile qualified version of a given type. */
+
+extern debug_type debug_make_volatile_type PARAMS ((PTR, debug_type));
+
+/* Make an undefined tagged type. For example, a struct which has
+ been mentioned, but not defined. */
+
+extern debug_type debug_make_undefined_tagged_type
+ PARAMS ((PTR, const char *, enum debug_type_kind));
+
+/* Make a base class for an object. The second argument is the base
+ class type. The third argument is the bit position of this base
+ class in the object. The fourth argument is whether this is a
+ virtual class. The fifth argument is the visibility of the base
+ class. */
+
+extern debug_baseclass debug_make_baseclass
+ PARAMS ((PTR, debug_type, bfd_vma, boolean, enum debug_visibility));
+
+/* Make a field for a struct. The second argument is the name. The
+ third argument is the type of the field. The fourth argument is
+ the bit position of the field. The fifth argument is the size of
+ the field (it may be zero). The sixth argument is the visibility
+ of the field. */
+
+extern debug_field debug_make_field
+ PARAMS ((PTR, const char *, debug_type, bfd_vma, bfd_vma,
+ enum debug_visibility));
+
+/* Make a static member of an object. The second argument is the
+ name. The third argument is the type of the member. The fourth
+ argument is the physical name of the member (i.e., the name as a
+ global variable). The fifth argument is the visibility of the
+ member. */
+
+extern debug_field debug_make_static_member
+ PARAMS ((PTR, const char *, debug_type, const char *,
+ enum debug_visibility));
+
+/* Make a method. The second argument is the name, and the third
+ argument is a NULL terminated array of method variants. Each
+ method variant is a method with this name but with different
+ argument types. */
+
+extern debug_method debug_make_method
+ PARAMS ((PTR, const char *, debug_method_variant *));
+
+/* Make a method variant. The second argument is the physical name of
+ the function. The third argument is the type of the function,
+ probably constructed by debug_make_method_type. The fourth
+ argument is the visibility. The fifth argument is whether this is
+ a const function. The sixth argument is whether this is a volatile
+ function. The seventh argument is the index in the virtual
+ function table, if any. The eighth argument is the virtual
+ function context. */
+
+extern debug_method_variant debug_make_method_variant
+ PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
+ boolean, bfd_vma, debug_type));
+
+/* Make a static method argument. The arguments are the same as for
+ debug_make_method_variant, except that the last two are omitted
+ since a static method can not also be virtual. */
+
+extern debug_method_variant debug_make_static_method_variant
+ PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
+ boolean));
+
+/* Name a type. This returns a new type with an attached name. */
+
+extern debug_type debug_name_type PARAMS ((PTR, const char *, debug_type));
+
+/* Give a tag to a type, such as a struct or union. This returns a
+ new type with an attached tag. */
+
+extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type));
+
+/* Record the size of a given type. */
+
+extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int));
+
+/* Find a named type. */
+
+extern debug_type debug_find_named_type PARAMS ((PTR, const char *));
+
+/* Find a tagged type. */
+
+extern debug_type debug_find_tagged_type
+ PARAMS ((PTR, const char *, enum debug_type_kind));
+
+/* Get the kind of a type. */
+
+extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type));
+
+/* Get the name of a type. */
+
+extern const char *debug_get_type_name PARAMS ((PTR, debug_type));
+
+/* Get the size of a type. */
+
+extern bfd_vma debug_get_type_size PARAMS ((PTR, debug_type));
+
+/* Get the return type of a function or method type. */
+
+extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
+
+/* Get the NULL terminated array of parameter types for a function or
+ method type (actually, parameter types are not currently stored for
+ function types). This may be used to determine whether a method
+ type is a stub method or not. The last argument points to a
+ boolean which is set to true if the function takes a variable
+ number of arguments. */
+
+extern const debug_type *debug_get_parameter_types PARAMS ((PTR,
+ debug_type,
+ boolean *));
+
+/* Get the target type of a pointer or reference or const or volatile
+ type. */
+
+extern debug_type debug_get_target_type PARAMS ((PTR, debug_type));
+
+/* Get the NULL terminated array of fields for a struct, union, or
+ class. */
+
+extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type));
+
+/* Get the type of a field. */
+
+extern debug_type debug_get_field_type PARAMS ((PTR, debug_field));
+
+/* Get the name of a field. */
+
+extern const char *debug_get_field_name PARAMS ((PTR, debug_field));
+
+/* Get the bit position of a field within the containing structure.
+ If the field is a static member, this will return (bfd_vma) -1. */
+
+extern bfd_vma debug_get_field_bitpos PARAMS ((PTR, debug_field));
+
+/* Get the bit size of a field. If the field is a static member, this
+ will return (bfd_vma) -1. */
+
+extern bfd_vma debug_get_field_bitsize PARAMS ((PTR, debug_field));
+
+/* Get the visibility of a field. */
+
+extern enum debug_visibility debug_get_field_visibility
+ PARAMS ((PTR, debug_field));
+
+/* Get the physical name of a field, if it is a static member. If the
+ field is not a static member, this will return NULL. */
+
+extern const char *debug_get_field_physname PARAMS ((PTR, debug_field));
+
+/* Write out the recorded debugging information. This takes a set of
+ function pointers which are called to do the actual writing. The
+ first PTR is the debugging handle. The second PTR is a handle
+ which is passed to the functions. */
+
+extern boolean debug_write PARAMS ((PTR, const struct debug_write_fns *, PTR));
+
+#endif /* DEBUG_H */
diff --git a/pstack/demangle.h b/pstack/demangle.h
new file mode 100644
index 00000000000..a961436ca77
--- /dev/null
+++ b/pstack/demangle.h
@@ -0,0 +1,90 @@
+/* Defs for interface to demanglers.
+ Copyright 1992, 1995, 1996 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#if !defined (DEMANGLE_H)
+#define DEMANGLE_H
+
+#ifdef IN_GCC
+#include "gansidecl.h"
+#define PARAMS(ARGS) PROTO(ARGS)
+#else /* ! IN_GCC */
+#include <ansidecl.h>
+#endif /* IN_GCC */
+
+/* Options passed to cplus_demangle (in 2nd parameter). */
+
+#define DMGL_NO_OPTS 0 /* For readability... */
+#define DMGL_PARAMS (1 << 0) /* Include function args */
+#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
+#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
+
+#define DMGL_AUTO (1 << 8)
+#define DMGL_GNU (1 << 9)
+#define DMGL_LUCID (1 << 10)
+#define DMGL_ARM (1 << 11)
+/* If none of these are set, use 'current_demangling_style' as the default. */
+#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM)
+
+/* Enumeration of possible demangling styles.
+
+ Lucid and ARM styles are still kept logically distinct, even though
+ they now both behave identically. The resulting style is actual the
+ union of both. I.E. either style recognizes both "__pt__" and "__rf__"
+ for operator "->", even though the first is lucid style and the second
+ is ARM style. (FIXME?) */
+
+extern enum demangling_styles
+{
+ unknown_demangling = 0,
+ auto_demangling = DMGL_AUTO,
+ gnu_demangling = DMGL_GNU,
+ lucid_demangling = DMGL_LUCID,
+ arm_demangling = DMGL_ARM
+} current_demangling_style;
+
+/* Define string names for the various demangling styles. */
+
+#define AUTO_DEMANGLING_STYLE_STRING "auto"
+#define GNU_DEMANGLING_STYLE_STRING "gnu"
+#define LUCID_DEMANGLING_STYLE_STRING "lucid"
+#define ARM_DEMANGLING_STYLE_STRING "arm"
+
+/* Some macros to test what demangling style is active. */
+
+#define CURRENT_DEMANGLING_STYLE current_demangling_style
+#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
+#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
+#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
+#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM)
+
+extern char *
+cplus_demangle PARAMS ((const char *mangled, int options));
+
+extern int
+cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
+
+extern const char *
+cplus_mangle_opname PARAMS ((const char *opname, int options));
+
+/* Note: This sets global state. FIXME if you care about multi-threading. */
+
+extern void
+set_cplus_marker_for_demangling PARAMS ((int ch));
+
+#endif /* DEMANGLE_H */
diff --git a/pstack/filemode.c b/pstack/filemode.c
new file mode 100644
index 00000000000..58b52ba7489
--- /dev/null
+++ b/pstack/filemode.c
@@ -0,0 +1,266 @@
+/* filemode.c -- make a string describing file modes
+ Copyright (C) 1985, 90, 91, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "bucomm.h"
+
+static char ftypelet PARAMS ((unsigned long));
+static void setst PARAMS ((unsigned long, char *));
+
+/* filemodestring - fill in string STR with an ls-style ASCII
+ representation of the st_mode field of file stats block STATP.
+ 10 characters are stored in STR; no terminating null is added.
+ The characters stored in STR are:
+
+ 0 File type. 'd' for directory, 'c' for character
+ special, 'b' for block special, 'm' for multiplex,
+ 'l' for symbolic link, 's' for socket, 'p' for fifo,
+ '-' for any other file type
+
+ 1 'r' if the owner may read, '-' otherwise.
+
+ 2 'w' if the owner may write, '-' otherwise.
+
+ 3 'x' if the owner may execute, 's' if the file is
+ set-user-id, '-' otherwise.
+ 'S' if the file is set-user-id, but the execute
+ bit isn't set.
+
+ 4 'r' if group members may read, '-' otherwise.
+
+ 5 'w' if group members may write, '-' otherwise.
+
+ 6 'x' if group members may execute, 's' if the file is
+ set-group-id, '-' otherwise.
+ 'S' if it is set-group-id but not executable.
+
+ 7 'r' if any user may read, '-' otherwise.
+
+ 8 'w' if any user may write, '-' otherwise.
+
+ 9 'x' if any user may execute, 't' if the file is "sticky"
+ (will be retained in swap space after execution), '-'
+ otherwise.
+ 'T' if the file is sticky but not executable. */
+
+#if 0
+
+/* This is not used; only mode_string is used. */
+
+void
+filemodestring (statp, str)
+ struct stat *statp;
+ char *str;
+{
+ mode_string ((unsigned long) statp->st_mode, str);
+}
+
+#endif
+
+/* Get definitions for the file permission bits. */
+
+#ifndef S_IRWXU
+#define S_IRWXU 0700
+#endif
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#endif
+#ifndef S_IWUSR
+#define S_IWUSR 0200
+#endif
+#ifndef S_IXUSR
+#define S_IXUSR 0100
+#endif
+
+#ifndef S_IRWXG
+#define S_IRWXG 0070
+#endif
+#ifndef S_IRGRP
+#define S_IRGRP 0040
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP 0020
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP 0010
+#endif
+
+#ifndef S_IRWXO
+#define S_IRWXO 0007
+#endif
+#ifndef S_IROTH
+#define S_IROTH 0004
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH 0002
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0001
+#endif
+
+/* Like filemodestring, but only the relevant part of the `struct stat'
+ is given as an argument. */
+
+void
+mode_string (mode, str)
+ unsigned long mode;
+ char *str;
+{
+ str[0] = ftypelet ((unsigned long) mode);
+ str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
+ str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
+ str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
+ str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
+ str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
+ str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
+ str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
+ str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
+ str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
+ setst ((unsigned long) mode, str);
+}
+
+/* Return a character indicating the type of file described by
+ file mode BITS:
+ 'd' for directories
+ 'b' for block special files
+ 'c' for character special files
+ 'm' for multiplexor files
+ 'l' for symbolic links
+ 's' for sockets
+ 'p' for fifos
+ '-' for any other file type. */
+
+#ifndef S_ISDIR
+#ifdef S_IFDIR
+#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
+#else /* ! defined (S_IFDIR) */
+#define S_ISDIR(i) (((i) & 0170000) == 040000)
+#endif /* ! defined (S_IFDIR) */
+#endif /* ! defined (S_ISDIR) */
+
+#ifndef S_ISBLK
+#ifdef S_IFBLK
+#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
+#else /* ! defined (S_IFBLK) */
+#define S_ISBLK(i) 0
+#endif /* ! defined (S_IFBLK) */
+#endif /* ! defined (S_ISBLK) */
+
+#ifndef S_ISCHR
+#ifdef S_IFCHR
+#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
+#else /* ! defined (S_IFCHR) */
+#define S_ISCHR(i) 0
+#endif /* ! defined (S_IFCHR) */
+#endif /* ! defined (S_ISCHR) */
+
+#ifndef S_ISFIFO
+#ifdef S_IFIFO
+#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
+#else /* ! defined (S_IFIFO) */
+#define S_ISFIFO(i) 0
+#endif /* ! defined (S_IFIFO) */
+#endif /* ! defined (S_ISFIFO) */
+
+#ifndef S_ISSOCK
+#ifdef S_IFSOCK
+#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
+#else /* ! defined (S_IFSOCK) */
+#define S_ISSOCK(i) 0
+#endif /* ! defined (S_IFSOCK) */
+#endif /* ! defined (S_ISSOCK) */
+
+#ifndef S_ISLNK
+#ifdef S_IFLNK
+#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
+#else /* ! defined (S_IFLNK) */
+#define S_ISLNK(i) 0
+#endif /* ! defined (S_IFLNK) */
+#endif /* ! defined (S_ISLNK) */
+
+static char
+ftypelet (bits)
+ unsigned long bits;
+{
+ if (S_ISDIR (bits))
+ return 'd';
+ if (S_ISLNK (bits))
+ return 'l';
+ if (S_ISBLK (bits))
+ return 'b';
+ if (S_ISCHR (bits))
+ return 'c';
+ if (S_ISSOCK (bits))
+ return 's';
+ if (S_ISFIFO (bits))
+ return 'p';
+
+#ifdef S_IFMT
+#ifdef S_IFMPC
+ if ((bits & S_IFMT) == S_IFMPC
+ || (bits & S_IFMT) == S_IFMPB)
+ return 'm';
+#endif
+#ifdef S_IFNWK
+ if ((bits & S_IFMT) == S_IFNWK)
+ return 'n';
+#endif
+#endif
+
+ return '-';
+}
+
+/* Set the 's' and 't' flags in file attributes string CHARS,
+ according to the file mode BITS. */
+
+static void
+setst (bits, chars)
+ unsigned long bits;
+ char *chars;
+{
+#ifdef S_ISUID
+ if (bits & S_ISUID)
+ {
+ if (chars[3] != 'x')
+ /* Set-uid, but not executable by owner. */
+ chars[3] = 'S';
+ else
+ chars[3] = 's';
+ }
+#endif
+#ifdef S_ISGID
+ if (bits & S_ISGID)
+ {
+ if (chars[6] != 'x')
+ /* Set-gid, but not executable by group. */
+ chars[6] = 'S';
+ else
+ chars[6] = 's';
+ }
+#endif
+#ifdef S_ISVTX
+ if (bits & S_ISVTX)
+ {
+ if (chars[9] != 'x')
+ /* Sticky, but not executable by others. */
+ chars[9] = 'T';
+ else
+ chars[9] = 't';
+ }
+#endif
+}
diff --git a/pstack/ieee.c b/pstack/ieee.c
new file mode 100644
index 00000000000..8084656a5ef
--- /dev/null
+++ b/pstack/ieee.c
@@ -0,0 +1,7602 @@
+/* ieee.c -- Read and write IEEE-695 debugging information.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file reads and writes IEEE-695 debugging information. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <bfd.h>
+#include "ieee.h"
+#include "bucomm.h"
+#include <libiberty.h>
+#include "debug.h"
+#include "budbg.h"
+
+/* This structure holds an entry on the block stack. */
+
+struct ieee_block
+{
+ /* The kind of block. */
+ int kind;
+ /* The source file name, for a BB5 block. */
+ const char *filename;
+ /* The index of the function type, for a BB4 or BB6 block. */
+ unsigned int fnindx;
+ /* True if this function is being skipped. */
+ boolean skip;
+};
+
+/* This structure is the block stack. */
+
+#define BLOCKSTACK_SIZE (16)
+
+struct ieee_blockstack
+{
+ /* The stack pointer. */
+ struct ieee_block *bsp;
+ /* The stack. */
+ struct ieee_block stack[BLOCKSTACK_SIZE];
+};
+
+/* This structure holds information for a variable. */
+
+struct ieee_var
+{
+ /* Start of name. */
+ const char *name;
+ /* Length of name. */
+ unsigned long namlen;
+ /* Type. */
+ debug_type type;
+ /* Slot if we make an indirect type. */
+ debug_type *pslot;
+ /* Kind of variable or function. */
+ enum
+ {
+ IEEE_UNKNOWN,
+ IEEE_EXTERNAL,
+ IEEE_GLOBAL,
+ IEEE_STATIC,
+ IEEE_LOCAL,
+ IEEE_FUNCTION
+ } kind;
+};
+
+/* This structure holds all the variables. */
+
+struct ieee_vars
+{
+ /* Number of slots allocated. */
+ unsigned int alloc;
+ /* Variables. */
+ struct ieee_var *vars;
+};
+
+/* This structure holds information for a type. We need this because
+ we don't want to represent bitfields as real types. */
+
+struct ieee_type
+{
+ /* Type. */
+ debug_type type;
+ /* Slot if this is type is referenced before it is defined. */
+ debug_type *pslot;
+ /* Slots for arguments if we make indirect types for them. */
+ debug_type *arg_slots;
+ /* If this is a bitfield, this is the size in bits. If this is not
+ a bitfield, this is zero. */
+ unsigned long bitsize;
+};
+
+/* This structure holds all the type information. */
+
+struct ieee_types
+{
+ /* Number of slots allocated. */
+ unsigned int alloc;
+ /* Types. */
+ struct ieee_type *types;
+ /* Builtin types. */
+#define BUILTIN_TYPE_COUNT (60)
+ debug_type builtins[BUILTIN_TYPE_COUNT];
+};
+
+/* This structure holds a linked last of structs with their tag names,
+ so that we can convert them to C++ classes if necessary. */
+
+struct ieee_tag
+{
+ /* Next tag. */
+ struct ieee_tag *next;
+ /* This tag name. */
+ const char *name;
+ /* The type of the tag. */
+ debug_type type;
+ /* The tagged type is an indirect type pointing at this slot. */
+ debug_type slot;
+ /* This is an array of slots used when a field type is converted
+ into a indirect type, in case it needs to be later converted into
+ a reference type. */
+ debug_type *fslots;
+};
+
+/* This structure holds the information we pass around to the parsing
+ functions. */
+
+struct ieee_info
+{
+ /* The debugging handle. */
+ PTR dhandle;
+ /* The BFD. */
+ bfd *abfd;
+ /* The start of the bytes to be parsed. */
+ const bfd_byte *bytes;
+ /* The end of the bytes to be parsed. */
+ const bfd_byte *pend;
+ /* The block stack. */
+ struct ieee_blockstack blockstack;
+ /* Whether we have seen a BB1 or BB2. */
+ boolean saw_filename;
+ /* The variables. */
+ struct ieee_vars vars;
+ /* The global variables, after a global typedef block. */
+ struct ieee_vars *global_vars;
+ /* The types. */
+ struct ieee_types types;
+ /* The global types, after a global typedef block. */
+ struct ieee_types *global_types;
+ /* The list of tagged structs. */
+ struct ieee_tag *tags;
+};
+
+/* Basic builtin types, not including the pointers. */
+
+enum builtin_types
+{
+ builtin_unknown = 0,
+ builtin_void = 1,
+ builtin_signed_char = 2,
+ builtin_unsigned_char = 3,
+ builtin_signed_short_int = 4,
+ builtin_unsigned_short_int = 5,
+ builtin_signed_long = 6,
+ builtin_unsigned_long = 7,
+ builtin_signed_long_long = 8,
+ builtin_unsigned_long_long = 9,
+ builtin_float = 10,
+ builtin_double = 11,
+ builtin_long_double = 12,
+ builtin_long_long_double = 13,
+ builtin_quoted_string = 14,
+ builtin_instruction_address = 15,
+ builtin_int = 16,
+ builtin_unsigned = 17,
+ builtin_unsigned_int = 18,
+ builtin_char = 19,
+ builtin_long = 20,
+ builtin_short = 21,
+ builtin_unsigned_short = 22,
+ builtin_short_int = 23,
+ builtin_signed_short = 24,
+ builtin_bcd_float = 25
+};
+
+/* These are the values found in the derivation flags of a 'b'
+ component record of a 'T' type extension record in a C++ pmisc
+ record. These are bitmasks. */
+
+/* Set for a private base class, clear for a public base class.
+ Protected base classes are not supported. */
+#define BASEFLAGS_PRIVATE (0x1)
+/* Set for a virtual base class. */
+#define BASEFLAGS_VIRTUAL (0x2)
+/* Set for a friend class, clear for a base class. */
+#define BASEFLAGS_FRIEND (0x10)
+
+/* These are the values found in the specs flags of a 'd', 'm', or 'v'
+ component record of a 'T' type extension record in a C++ pmisc
+ record. The same flags are used for a 'M' record in a C++ pmisc
+ record. */
+
+/* The lower two bits hold visibility information. */
+#define CXXFLAGS_VISIBILITY (0x3)
+/* This value in the lower two bits indicates a public member. */
+#define CXXFLAGS_VISIBILITY_PUBLIC (0x0)
+/* This value in the lower two bits indicates a private member. */
+#define CXXFLAGS_VISIBILITY_PRIVATE (0x1)
+/* This value in the lower two bits indicates a protected member. */
+#define CXXFLAGS_VISIBILITY_PROTECTED (0x2)
+/* Set for a static member. */
+#define CXXFLAGS_STATIC (0x4)
+/* Set for a virtual override. */
+#define CXXFLAGS_OVERRIDE (0x8)
+/* Set for a friend function. */
+#define CXXFLAGS_FRIEND (0x10)
+/* Set for a const function. */
+#define CXXFLAGS_CONST (0x20)
+/* Set for a volatile function. */
+#define CXXFLAGS_VOLATILE (0x40)
+/* Set for an overloaded function. */
+#define CXXFLAGS_OVERLOADED (0x80)
+/* Set for an operator function. */
+#define CXXFLAGS_OPERATOR (0x100)
+/* Set for a constructor or destructor. */
+#define CXXFLAGS_CTORDTOR (0x400)
+/* Set for a constructor. */
+#define CXXFLAGS_CTOR (0x200)
+/* Set for an inline function. */
+#define CXXFLAGS_INLINE (0x800)
+
+/* Local functions. */
+
+static void ieee_error
+ PARAMS ((struct ieee_info *, const bfd_byte *, const char *));
+static void ieee_eof PARAMS ((struct ieee_info *));
+static char *savestring PARAMS ((const char *, unsigned long));
+static boolean ieee_read_number
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static boolean ieee_read_optional_number
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *));
+static boolean ieee_read_id
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *));
+static boolean ieee_read_optional_id
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *, boolean *));
+static boolean ieee_read_expression
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static debug_type ieee_builtin_type
+ PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int));
+static boolean ieee_alloc_type
+ PARAMS ((struct ieee_info *, unsigned int, boolean));
+static boolean ieee_read_type_index
+ PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *));
+static int ieee_regno_to_genreg PARAMS ((bfd *, int));
+static int ieee_genreg_to_regno PARAMS ((bfd *, int));
+static boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean ieee_read_cxx_misc
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_cxx_class
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_cxx_defaults
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_reference
+ PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean ieee_require_asn
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static boolean ieee_require_atn65
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *));
+
+/* Report an error in the IEEE debugging information. */
+
+static void
+ieee_error (info, p, s)
+ struct ieee_info *info;
+ const bfd_byte *p;
+ const char *s;
+{
+ if (p != NULL)
+ fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd),
+ (unsigned long) (p - info->bytes), s, *p);
+ else
+ fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s);
+}
+
+/* Report an unexpected EOF in the IEEE debugging information. */
+
+static void
+ieee_eof (info)
+ struct ieee_info *info;
+{
+ ieee_error (info, (const bfd_byte *) NULL,
+ "unexpected end of debugging information");
+}
+
+/* Save a string in memory. */
+
+static char *
+savestring (start, len)
+ const char *start;
+ unsigned long len;
+{
+ char *ret;
+
+ ret = (char *) xmalloc (len + 1);
+ memcpy (ret, start, len);
+ ret[len] = '\0';
+ return ret;
+}
+
+/* Read a number which must be present in an IEEE file. */
+
+static boolean
+ieee_read_number (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ return ieee_read_optional_number (info, pp, pv, (boolean *) NULL);
+}
+
+/* Read a number in an IEEE file. If ppresent is not NULL, the number
+ need not be there. */
+
+static boolean
+ieee_read_optional_number (info, pp, pv, ppresent)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+ boolean *ppresent;
+{
+ ieee_record_enum_type b;
+
+ if (*pp >= info->pend)
+ {
+ if (ppresent != NULL)
+ {
+ *ppresent = false;
+ return true;
+ }
+ ieee_eof (info);
+ return false;
+ }
+
+ b = (ieee_record_enum_type) **pp;
+ ++*pp;
+
+ if (b <= ieee_number_end_enum)
+ {
+ *pv = (bfd_vma) b;
+ if (ppresent != NULL)
+ *ppresent = true;
+ return true;
+ }
+
+ if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum)
+ {
+ unsigned int i;
+
+ i = (int) b - (int) ieee_number_repeat_start_enum;
+ if (*pp + i - 1 >= info->pend)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ *pv = 0;
+ for (; i > 0; i--)
+ {
+ *pv <<= 8;
+ *pv += **pp;
+ ++*pp;
+ }
+
+ if (ppresent != NULL)
+ *ppresent = true;
+
+ return true;
+ }
+
+ if (ppresent != NULL)
+ {
+ --*pp;
+ *ppresent = false;
+ return true;
+ }
+
+ ieee_error (info, *pp - 1, "invalid number");
+ return false;
+}
+
+/* Read a required string from an IEEE file. */
+
+static boolean
+ieee_read_id (info, pp, pname, pnamlen)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+{
+ return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL);
+}
+
+/* Read a string from an IEEE file. If ppresent is not NULL, the
+ string is optional. */
+
+static boolean
+ieee_read_optional_id (info, pp, pname, pnamlen, ppresent)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+ boolean *ppresent;
+{
+ bfd_byte b;
+ unsigned long len;
+
+ if (*pp >= info->pend)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ b = **pp;
+ ++*pp;
+
+ if (b <= 0x7f)
+ len = b;
+ else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum)
+ {
+ len = **pp;
+ ++*pp;
+ }
+ else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum)
+ {
+ len = (**pp << 8) + (*pp)[1];
+ *pp += 2;
+ }
+ else
+ {
+ if (ppresent != NULL)
+ {
+ --*pp;
+ *ppresent = false;
+ return true;
+ }
+ ieee_error (info, *pp - 1, "invalid string length");
+ return false;
+ }
+
+ if ((unsigned long) (info->pend - *pp) < len)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ *pname = (const char *) *pp;
+ *pnamlen = len;
+ *pp += len;
+
+ if (ppresent != NULL)
+ *ppresent = true;
+
+ return true;
+}
+
+/* Read an expression from an IEEE file. Since this code is only used
+ to parse debugging information, I haven't bothered to write a full
+ blown IEEE expression parser. I've only thrown in the things I've
+ seen in debugging information. This can be easily extended if
+ necessary. */
+
+static boolean
+ieee_read_expression (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ const bfd_byte *expr_start;
+#define EXPR_STACK_SIZE (10)
+ bfd_vma expr_stack[EXPR_STACK_SIZE];
+ bfd_vma *esp;
+
+ expr_start = *pp;
+
+ esp = expr_stack;
+
+ while (1)
+ {
+ const bfd_byte *start;
+ bfd_vma val;
+ boolean present;
+ ieee_record_enum_type c;
+
+ start = *pp;
+
+ if (! ieee_read_optional_number (info, pp, &val, &present))
+ return false;
+
+ if (present)
+ {
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (info, start, "expression stack overflow");
+ return false;
+ }
+ *esp++ = val;
+ continue;
+ }
+
+ c = (ieee_record_enum_type) **pp;
+
+ if (c >= ieee_module_beginning_enum)
+ break;
+
+ ++*pp;
+
+ if (c == ieee_comma)
+ break;
+
+ switch (c)
+ {
+ default:
+ ieee_error (info, start, "unsupported IEEE expression operator");
+ break;
+
+ case ieee_variable_R_enum:
+ {
+ bfd_vma indx;
+ asection *s;
+
+ if (! ieee_read_number (info, pp, &indx))
+ return false;
+ for (s = info->abfd->sections; s != NULL; s = s->next)
+ if ((bfd_vma) s->target_index == indx)
+ break;
+ if (s == NULL)
+ {
+ ieee_error (info, start, "unknown section");
+ return false;
+ }
+
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (info, start, "expression stack overflow");
+ return false;
+ }
+
+ *esp++ = bfd_get_section_vma (info->abfd, s);
+ }
+ break;
+
+ case ieee_function_plus_enum:
+ case ieee_function_minus_enum:
+ {
+ bfd_vma v1, v2;
+
+ if (esp - expr_stack < 2)
+ {
+ ieee_error (info, start, "expression stack underflow");
+ return false;
+ }
+
+ v1 = *--esp;
+ v2 = *--esp;
+ *esp++ = v1 + v2;
+ }
+ break;
+ }
+ }
+
+ if (esp - 1 != expr_stack)
+ {
+ ieee_error (info, expr_start, "expression stack mismatch");
+ return false;
+ }
+
+ *pv = *--esp;
+
+ return true;
+}
+
+/* Return an IEEE builtin type. */
+
+static debug_type
+ieee_builtin_type (info, p, indx)
+ struct ieee_info *info;
+ const bfd_byte *p;
+ unsigned int indx;
+{
+ PTR dhandle;
+ debug_type type;
+ const char *name;
+
+ if (indx < BUILTIN_TYPE_COUNT
+ && info->types.builtins[indx] != DEBUG_TYPE_NULL)
+ return info->types.builtins[indx];
+
+ dhandle = info->dhandle;
+
+ if (indx >= 32 && indx < 64)
+ {
+ type = debug_make_pointer_type (dhandle,
+ ieee_builtin_type (info, p, indx - 32));
+ assert (indx < BUILTIN_TYPE_COUNT);
+ info->types.builtins[indx] = type;
+ return type;
+ }
+
+ switch ((enum builtin_types) indx)
+ {
+ default:
+ ieee_error (info, p, "unknown builtin type");
+ return NULL;
+
+ case builtin_unknown:
+ type = debug_make_void_type (dhandle);
+ name = NULL;
+ break;
+
+ case builtin_void:
+ type = debug_make_void_type (dhandle);
+ name = "void";
+ break;
+
+ case builtin_signed_char:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "signed char";
+ break;
+
+ case builtin_unsigned_char:
+ type = debug_make_int_type (dhandle, 1, true);
+ name = "unsigned char";
+ break;
+
+ case builtin_signed_short_int:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short int";
+ break;
+
+ case builtin_unsigned_short_int:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short int";
+ break;
+
+ case builtin_signed_long:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "signed long";
+ break;
+
+ case builtin_unsigned_long:
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned long";
+ break;
+
+ case builtin_signed_long_long:
+ type = debug_make_int_type (dhandle, 8, false);
+ name = "signed long long";
+ break;
+
+ case builtin_unsigned_long_long:
+ type = debug_make_int_type (dhandle, 8, true);
+ name = "unsigned long long";
+ break;
+
+ case builtin_float:
+ type = debug_make_float_type (dhandle, 4);
+ name = "float";
+ break;
+
+ case builtin_double:
+ type = debug_make_float_type (dhandle, 8);
+ name = "double";
+ break;
+
+ case builtin_long_double:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_float_type (dhandle, 12);
+ name = "long double";
+ break;
+
+ case builtin_long_long_double:
+ type = debug_make_float_type (dhandle, 16);
+ name = "long long double";
+ break;
+
+ case builtin_quoted_string:
+ type = debug_make_array_type (dhandle,
+ ieee_builtin_type (info, p,
+ ((unsigned int)
+ builtin_char)),
+ ieee_builtin_type (info, p,
+ ((unsigned int)
+ builtin_int)),
+ 0, -1, true);
+ name = "QUOTED STRING";
+ break;
+
+ case builtin_instruction_address:
+ /* FIXME: This should be a code address. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "instruction address";
+ break;
+
+ case builtin_int:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "int";
+ break;
+
+ case builtin_unsigned:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned";
+ break;
+
+ case builtin_unsigned_int:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned int";
+ break;
+
+ case builtin_char:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "char";
+ break;
+
+ case builtin_long:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "long";
+ break;
+
+ case builtin_short:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short";
+ break;
+
+ case builtin_unsigned_short:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short";
+ break;
+
+ case builtin_short_int:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short int";
+ break;
+
+ case builtin_signed_short:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short";
+ break;
+
+ case builtin_bcd_float:
+ ieee_error (info, p, "BCD float type not supported");
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (name != NULL)
+ type = debug_name_type (dhandle, name, type);
+
+ assert (indx < BUILTIN_TYPE_COUNT);
+
+ info->types.builtins[indx] = type;
+
+ return type;
+}
+
+/* Allocate more space in the type table. If ref is true, this is a
+ reference to the type; if it is not already defined, we should set
+ up an indirect type. */
+
+static boolean
+ieee_alloc_type (info, indx, ref)
+ struct ieee_info *info;
+ unsigned int indx;
+ boolean ref;
+{
+ unsigned int nalloc;
+ register struct ieee_type *t;
+ struct ieee_type *tend;
+
+ if (indx >= info->types.alloc)
+ {
+ nalloc = info->types.alloc;
+ if (nalloc == 0)
+ nalloc = 4;
+ while (indx >= nalloc)
+ nalloc *= 2;
+
+ info->types.types = ((struct ieee_type *)
+ xrealloc (info->types.types,
+ nalloc * sizeof *info->types.types));
+
+ memset (info->types.types + info->types.alloc, 0,
+ (nalloc - info->types.alloc) * sizeof *info->types.types);
+
+ tend = info->types.types + nalloc;
+ for (t = info->types.types + info->types.alloc; t < tend; t++)
+ t->type = DEBUG_TYPE_NULL;
+
+ info->types.alloc = nalloc;
+ }
+
+ if (ref)
+ {
+ t = info->types.types + indx;
+ if (t->type == NULL)
+ {
+ t->pslot = (debug_type *) xmalloc (sizeof *t->pslot);
+ *t->pslot = DEBUG_TYPE_NULL;
+ t->type = debug_make_indirect_type (info->dhandle, t->pslot,
+ (const char *) NULL);
+ if (t->type == NULL)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read a type index and return the corresponding type. */
+
+static boolean
+ieee_read_type_index (info, pp, ptype)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ debug_type *ptype;
+{
+ const bfd_byte *start;
+ bfd_vma indx;
+
+ start = *pp;
+
+ if (! ieee_read_number (info, pp, &indx))
+ return false;
+
+ if (indx < 256)
+ {
+ *ptype = ieee_builtin_type (info, start, indx);
+ if (*ptype == NULL)
+ return false;
+ return true;
+ }
+
+ indx -= 256;
+ if (! ieee_alloc_type (info, indx, true))
+ return false;
+
+ *ptype = info->types.types[indx].type;
+
+ return true;
+}
+
+/* Parse IEEE debugging information for a file. This is passed the
+ bytes which compose the Debug Information Part of an IEEE file. */
+
+boolean
+parse_ieee (dhandle, abfd, bytes, len)
+ PTR dhandle;
+ bfd *abfd;
+ const bfd_byte *bytes;
+ bfd_size_type len;
+{
+ struct ieee_info info;
+ unsigned int i;
+ const bfd_byte *p, *pend;
+
+ info.dhandle = dhandle;
+ info.abfd = abfd;
+ info.bytes = bytes;
+ info.pend = bytes + len;
+ info.blockstack.bsp = info.blockstack.stack;
+ info.saw_filename = false;
+ info.vars.alloc = 0;
+ info.vars.vars = NULL;
+ info.types.alloc = 0;
+ info.types.types = NULL;
+ info.tags = NULL;
+ for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
+ info.types.builtins[i] = DEBUG_TYPE_NULL;
+
+ p = bytes;
+ pend = info.pend;
+ while (p < pend)
+ {
+ const bfd_byte *record_start;
+ ieee_record_enum_type c;
+
+ record_start = p;
+
+ c = (ieee_record_enum_type) *p++;
+
+ if (c == ieee_at_record_enum)
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++);
+
+ if (c <= ieee_number_repeat_end_enum)
+ {
+ ieee_error (&info, record_start, "unexpected number");
+ return false;
+ }
+
+ switch (c)
+ {
+ default:
+ ieee_error (&info, record_start, "unexpected record type");
+ return false;
+
+ case ieee_bb_record_enum:
+ if (! parse_ieee_bb (&info, &p))
+ return false;
+ break;
+
+ case ieee_be_record_enum:
+ if (! parse_ieee_be (&info, &p))
+ return false;
+ break;
+
+ case ieee_nn_record:
+ if (! parse_ieee_nn (&info, &p))
+ return false;
+ break;
+
+ case ieee_ty_record_enum:
+ if (! parse_ieee_ty (&info, &p))
+ return false;
+ break;
+
+ case ieee_atn_record_enum:
+ if (! parse_ieee_atn (&info, &p))
+ return false;
+ break;
+ }
+ }
+
+ if (info.blockstack.bsp != info.blockstack.stack)
+ {
+ ieee_error (&info, (const bfd_byte *) NULL,
+ "blocks left on stack at end");
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle an IEEE BB record. */
+
+static boolean
+parse_ieee_bb (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *block_start;
+ bfd_byte b;
+ bfd_vma size;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy = NULL;
+ unsigned int fnindx;
+ boolean skip;
+
+ block_start = *pp;
+
+ b = **pp;
+ ++*pp;
+
+ if (! ieee_read_number (info, pp, &size)
+ || ! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ fnindx = (unsigned int) -1;
+ skip = false;
+
+ switch (b)
+ {
+ case 1:
+ /* BB1: Type definitions local to a module. */
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_set_filename (info->dhandle, namcopy))
+ return false;
+ info->saw_filename = true;
+
+ /* Discard any variables or types we may have seen before. */
+ if (info->vars.vars != NULL)
+ free (info->vars.vars);
+ info->vars.vars = NULL;
+ info->vars.alloc = 0;
+ if (info->types.types != NULL)
+ free (info->types.types);
+ info->types.types = NULL;
+ info->types.alloc = 0;
+
+ /* Initialize the types to the global types. */
+ if (info->global_types != NULL)
+ {
+ info->types.alloc = info->global_types->alloc;
+ info->types.types = ((struct ieee_type *)
+ xmalloc (info->types.alloc
+ * sizeof (*info->types.types)));
+ memcpy (info->types.types, info->global_types->types,
+ info->types.alloc * sizeof (*info->types.types));
+ }
+
+ break;
+
+ case 2:
+ /* BB2: Global type definitions. The name is supposed to be
+ empty, but we don't check. */
+ if (! debug_set_filename (info->dhandle, "*global*"))
+ return false;
+ info->saw_filename = true;
+ break;
+
+ case 3:
+ /* BB3: High level module block begin. We don't have to do
+ anything here. The name is supposed to be the same as for
+ the BB1, but we don't check. */
+ break;
+
+ case 4:
+ /* BB4: Global function. */
+ {
+ bfd_vma stackspace, typindx, offset;
+ debug_type return_type;
+
+ if (! ieee_read_number (info, pp, &stackspace)
+ || ! ieee_read_number (info, pp, &typindx)
+ || ! ieee_read_expression (info, pp, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (info, block_start, typindx);
+ if (return_type == DEBUG_TYPE_NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (! ieee_alloc_type (info, typindx, true))
+ return false;
+ fnindx = typindx;
+ return_type = info->types.types[typindx].type;
+ if (debug_get_type_kind (info->dhandle, return_type)
+ == DEBUG_KIND_FUNCTION)
+ return_type = debug_get_return_type (info->dhandle,
+ return_type);
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (info->dhandle, namcopy, return_type,
+ true, offset))
+ return false;
+ }
+ break;
+
+ case 5:
+ /* BB5: File name for source line numbers. */
+ {
+ unsigned int i;
+
+ /* We ignore the date and time. FIXME. */
+ for (i = 0; i < 6; i++)
+ {
+ bfd_vma ignore;
+ boolean present;
+
+ if (! ieee_read_optional_number (info, pp, &ignore, &present))
+ return false;
+ if (! present)
+ break;
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_start_source (info->dhandle, namcopy))
+ return false;
+ }
+ break;
+
+ case 6:
+ /* BB6: Local function or block. */
+ {
+ bfd_vma stackspace, typindx, offset;
+
+ if (! ieee_read_number (info, pp, &stackspace)
+ || ! ieee_read_number (info, pp, &typindx)
+ || ! ieee_read_expression (info, pp, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (namlen == 0)
+ {
+ if (! debug_start_block (info->dhandle, offset))
+ return false;
+ /* Change b to indicate that this is a block
+ rather than a function. */
+ b = 0x86;
+ }
+ else
+ {
+ /* The MRI C++ compiler will output a fake function named
+ __XRYCPP to hold C++ debugging information. We skip
+ that function. This is not crucial, but it makes
+ converting from IEEE to other debug formats work
+ better. */
+ if (strncmp (name, "__XRYCPP", namlen) == 0)
+ skip = true;
+ else
+ {
+ debug_type return_type;
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (info, block_start,
+ typindx);
+ if (return_type == NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (! ieee_alloc_type (info, typindx, true))
+ return false;
+ fnindx = typindx;
+ return_type = info->types.types[typindx].type;
+ if (debug_get_type_kind (info->dhandle, return_type)
+ == DEBUG_KIND_FUNCTION)
+ return_type = debug_get_return_type (info->dhandle,
+ return_type);
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (info->dhandle, namcopy,
+ return_type, false, offset))
+ return false;
+ }
+ }
+ }
+ break;
+
+ case 10:
+ /* BB10: Assembler module scope. In the normal case, we
+ completely ignore all this information. FIXME. */
+ {
+ const char *inam, *vstr;
+ unsigned long inamlen, vstrlen;
+ bfd_vma tool_type;
+ boolean present;
+ unsigned int i;
+
+ if (! info->saw_filename)
+ {
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_set_filename (info->dhandle, namcopy))
+ return false;
+ info->saw_filename = true;
+ }
+
+ if (! ieee_read_id (info, pp, &inam, &inamlen)
+ || ! ieee_read_number (info, pp, &tool_type)
+ || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
+ return false;
+ for (i = 0; i < 6; i++)
+ {
+ bfd_vma ignore;
+
+ if (! ieee_read_optional_number (info, pp, &ignore, &present))
+ return false;
+ if (! present)
+ break;
+ }
+ }
+ break;
+
+ case 11:
+ /* BB11: Module section. We completely ignore all this
+ information. FIXME. */
+ {
+ bfd_vma sectype, secindx, offset, map;
+ boolean present;
+
+ if (! ieee_read_number (info, pp, &sectype)
+ || ! ieee_read_number (info, pp, &secindx)
+ || ! ieee_read_expression (info, pp, &offset)
+ || ! ieee_read_optional_number (info, pp, &map, &present))
+ return false;
+ }
+ break;
+
+ default:
+ ieee_error (info, block_start, "unknown BB type");
+ return false;
+ }
+
+
+ /* Push this block on the block stack. */
+
+ if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
+ {
+ ieee_error (info, (const bfd_byte *) NULL, "stack overflow");
+ return false;
+ }
+
+ info->blockstack.bsp->kind = b;
+ if (b == 5)
+ info->blockstack.bsp->filename = namcopy;
+ info->blockstack.bsp->fnindx = fnindx;
+ info->blockstack.bsp->skip = skip;
+ ++info->blockstack.bsp;
+
+ return true;
+}
+
+/* Handle an IEEE BE record. */
+
+static boolean
+parse_ieee_be (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ bfd_vma offset;
+
+ if (info->blockstack.bsp <= info->blockstack.stack)
+ {
+ ieee_error (info, *pp, "stack underflow");
+ return false;
+ }
+ --info->blockstack.bsp;
+
+ switch (info->blockstack.bsp->kind)
+ {
+ case 2:
+ /* When we end the global typedefs block, we copy out the the
+ contents of info->vars. This is because the variable indices
+ may be reused in the local blocks. However, we need to
+ preserve them so that we can locate a function returning a
+ reference variable whose type is named in the global typedef
+ block. */
+ info->global_vars = ((struct ieee_vars *)
+ xmalloc (sizeof *info->global_vars));
+ info->global_vars->alloc = info->vars.alloc;
+ info->global_vars->vars = ((struct ieee_var *)
+ xmalloc (info->vars.alloc
+ * sizeof (*info->vars.vars)));
+ memcpy (info->global_vars->vars, info->vars.vars,
+ info->vars.alloc * sizeof (*info->vars.vars));
+
+ /* We also copy out the non builtin parts of info->types, since
+ the types are discarded when we start a new block. */
+ info->global_types = ((struct ieee_types *)
+ xmalloc (sizeof *info->global_types));
+ info->global_types->alloc = info->types.alloc;
+ info->global_types->types = ((struct ieee_type *)
+ xmalloc (info->types.alloc
+ * sizeof (*info->types.types)));
+ memcpy (info->global_types->types, info->types.types,
+ info->types.alloc * sizeof (*info->types.types));
+ memset (info->global_types->builtins, 0,
+ sizeof (info->global_types->builtins));
+
+ break;
+
+ case 4:
+ case 6:
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ if (! info->blockstack.bsp->skip)
+ {
+ if (! debug_end_function (info->dhandle, offset + 1))
+ return false;
+ }
+ break;
+
+ case 0x86:
+ /* This is BE6 when BB6 started a block rather than a local
+ function. */
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ if (! debug_end_block (info->dhandle, offset + 1))
+ return false;
+ break;
+
+ case 5:
+ /* When we end a BB5, we look up the stack for the last BB5, if
+ there is one, so that we can call debug_start_source. */
+ if (info->blockstack.bsp > info->blockstack.stack)
+ {
+ struct ieee_block *bl;
+
+ bl = info->blockstack.bsp;
+ do
+ {
+ --bl;
+ if (bl->kind == 5)
+ {
+ if (! debug_start_source (info->dhandle, bl->filename))
+ return false;
+ break;
+ }
+ }
+ while (bl != info->blockstack.stack);
+ }
+ break;
+
+ case 11:
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ /* We just ignore the module size. FIXME. */
+ break;
+
+ default:
+ /* Other block types do not have any trailing information. */
+ break;
+ }
+
+ return true;
+}
+
+/* Parse an NN record. */
+
+static boolean
+parse_ieee_nn (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *nn_start;
+ bfd_vma varindx;
+ const char *name;
+ unsigned long namlen;
+
+ nn_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx)
+ || ! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (info, nn_start, "illegal variable index");
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= info->vars.alloc)
+ {
+ unsigned int alloc;
+
+ alloc = info->vars.alloc;
+ if (alloc == 0)
+ alloc = 4;
+ while (varindx >= alloc)
+ alloc *= 2;
+ info->vars.vars = ((struct ieee_var *)
+ xrealloc (info->vars.vars,
+ alloc * sizeof *info->vars.vars));
+ memset (info->vars.vars + info->vars.alloc, 0,
+ (alloc - info->vars.alloc) * sizeof *info->vars.vars);
+ info->vars.alloc = alloc;
+ }
+
+ info->vars.vars[varindx].name = name;
+ info->vars.vars[varindx].namlen = namlen;
+
+ return true;
+}
+
+/* Parse a TY record. */
+
+static boolean
+parse_ieee_ty (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
+ bfd_vma typeindx, varindx, tc;
+ PTR dhandle;
+ boolean tag, typdef;
+ debug_type *arg_slots;
+ unsigned long type_bitsize;
+ debug_type type;
+
+ ty_start = *pp;
+
+ if (! ieee_read_number (info, pp, &typeindx))
+ return false;
+
+ if (typeindx < 256)
+ {
+ ieee_error (info, ty_start, "illegal type index");
+ return false;
+ }
+
+ typeindx -= 256;
+ if (! ieee_alloc_type (info, typeindx, false))
+ return false;
+
+ if (**pp != 0xce)
+ {
+ ieee_error (info, *pp, "unknown TY code");
+ return false;
+ }
+ ++*pp;
+
+ ty_var_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (info, ty_var_start, "illegal variable index");
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
+ {
+ ieee_error (info, ty_var_start, "undefined variable in TY");
+ return false;
+ }
+
+ ty_code_start = *pp;
+
+ if (! ieee_read_number (info, pp, &tc))
+ return false;
+
+ dhandle = info->dhandle;
+
+ tag = false;
+ typdef = false;
+ arg_slots = NULL;
+ type_bitsize = 0;
+ switch (tc)
+ {
+ default:
+ ieee_error (info, ty_code_start, "unknown TY code");
+ return false;
+
+ case '!':
+ /* Unknown type, with size. We treat it as int. FIXME. */
+ {
+ bfd_vma size;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+ type = debug_make_int_type (dhandle, size, false);
+ }
+ break;
+
+ case 'A': /* Array. */
+ case 'a': /* FORTRAN array in column/row order. FIXME: Not
+ distinguished from normal array. */
+ {
+ debug_type ele_type;
+ bfd_vma lower, upper;
+
+ if (! ieee_read_type_index (info, pp, &ele_type)
+ || ! ieee_read_number (info, pp, &lower)
+ || ! ieee_read_number (info, pp, &upper))
+ return false;
+ type = debug_make_array_type (dhandle, ele_type,
+ ieee_builtin_type (info, ty_code_start,
+ ((unsigned int)
+ builtin_int)),
+ (bfd_signed_vma) lower,
+ (bfd_signed_vma) upper,
+ false);
+ }
+ break;
+
+ case 'E':
+ /* Simple enumeration. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ const char **names;
+ unsigned int c;
+ bfd_signed_vma *vals;
+ unsigned int i;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+ /* FIXME: we ignore the enumeration size. */
+
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ memset (names, 0, alloc * sizeof *names);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc (names, alloc * sizeof *names));
+ }
+
+ names[c] = savestring (name, namlen);
+ if (names[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ names[c] = NULL;
+
+ vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals);
+ for (i = 0; i < c; i++)
+ vals[i] = i;
+
+ type = debug_make_enum_type (dhandle, names, vals);
+ tag = true;
+ }
+ break;
+
+ case 'G':
+ /* Struct with bit fields. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ debug_field *fields;
+ unsigned int c;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ debug_type ftype;
+ bfd_vma bitpos, bitsize;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_type_index (info, pp, &ftype)
+ || ! ieee_read_number (info, pp, &bitpos)
+ || ! ieee_read_number (info, pp, &bitsize))
+ return false;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, alloc * sizeof *fields));
+ }
+
+ fields[c] = debug_make_field (dhandle, savestring (name, namlen),
+ ftype, bitpos, bitsize,
+ DEBUG_VISIBILITY_PUBLIC);
+ if (fields[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ fields[c] = NULL;
+
+ type = debug_make_struct_type (dhandle, true, size, fields);
+ tag = true;
+ }
+ break;
+
+ case 'N':
+ /* Enumeration. */
+ {
+ unsigned int alloc;
+ const char **names;
+ bfd_signed_vma *vals;
+ unsigned int c;
+
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ bfd_vma val;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (info, pp, &val))
+ return false;
+
+ /* If the length of the name is zero, then the value is
+ actually the size of the enum. We ignore this
+ information. FIXME. */
+ if (namlen == 0)
+ continue;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc (names, alloc * sizeof *names));
+ vals = ((bfd_signed_vma *)
+ xrealloc (vals, alloc * sizeof *vals));
+ }
+
+ names[c] = savestring (name, namlen);
+ if (names[c] == NULL)
+ return false;
+ vals[c] = (bfd_signed_vma) val;
+ ++c;
+ }
+
+ names[c] = NULL;
+
+ type = debug_make_enum_type (dhandle, names, vals);
+ tag = true;
+ }
+ break;
+
+ case 'O': /* Small pointer. We don't distinguish small and large
+ pointers. FIXME. */
+ case 'P': /* Large pointer. */
+ {
+ debug_type t;
+
+ if (! ieee_read_type_index (info, pp, &t))
+ return false;
+ type = debug_make_pointer_type (dhandle, t);
+ }
+ break;
+
+ case 'R':
+ /* Range. */
+ {
+ bfd_vma low, high, signedp, size;
+
+ if (! ieee_read_number (info, pp, &low)
+ || ! ieee_read_number (info, pp, &high)
+ || ! ieee_read_number (info, pp, &signedp)
+ || ! ieee_read_number (info, pp, &size))
+ return false;
+
+ type = debug_make_range_type (dhandle,
+ debug_make_int_type (dhandle, size,
+ ! signedp),
+ (bfd_signed_vma) low,
+ (bfd_signed_vma) high);
+ }
+ break;
+
+ case 'S': /* Struct. */
+ case 'U': /* Union. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ debug_field *fields;
+ unsigned int c;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ bfd_vma tindx;
+ bfd_vma offset;
+ debug_type ftype;
+ bfd_vma bitsize;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (info, pp, &tindx)
+ || ! ieee_read_number (info, pp, &offset))
+ return false;
+
+ if (tindx < 256)
+ {
+ ftype = ieee_builtin_type (info, ty_code_start, tindx);
+ bitsize = 0;
+ offset *= 8;
+ }
+ else
+ {
+ struct ieee_type *t;
+
+ tindx -= 256;
+ if (! ieee_alloc_type (info, tindx, true))
+ return false;
+ t = info->types.types + tindx;
+ ftype = t->type;
+ bitsize = t->bitsize;
+ if (bitsize == 0)
+ offset *= 8;
+ }
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, alloc * sizeof *fields));
+ }
+
+ fields[c] = debug_make_field (dhandle, savestring (name, namlen),
+ ftype, offset, bitsize,
+ DEBUG_VISIBILITY_PUBLIC);
+ if (fields[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ fields[c] = NULL;
+
+ type = debug_make_struct_type (dhandle, tc == 'S', size, fields);
+ tag = true;
+ }
+ break;
+
+ case 'T':
+ /* Typedef. */
+ if (! ieee_read_type_index (info, pp, &type))
+ return false;
+ typdef = true;
+ break;
+
+ case 'X':
+ /* Procedure. FIXME: This is an extern declaration, which we
+ have no way of representing. */
+ {
+ bfd_vma attr;
+ debug_type rtype;
+ bfd_vma nargs;
+ boolean present;
+ struct ieee_var *pv;
+
+ /* FIXME: We ignore the attribute and the argument names. */
+
+ if (! ieee_read_number (info, pp, &attr)
+ || ! ieee_read_type_index (info, pp, &rtype)
+ || ! ieee_read_number (info, pp, &nargs))
+ return false;
+ do
+ {
+ const char *name;
+ unsigned long namlen;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ }
+ while (present);
+
+ pv = info->vars.vars + varindx;
+ pv->kind = IEEE_EXTERNAL;
+ if (pv->namlen > 0
+ && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
+ {
+ /* Set up the return type as an indirect type pointing to
+ the variable slot, so that we can change it to a
+ reference later if appropriate. */
+ pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
+ *pv->pslot = rtype;
+ rtype = debug_make_indirect_type (dhandle, pv->pslot,
+ (const char *) NULL);
+ }
+
+ type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
+ false);
+ }
+ break;
+
+ case 'V':
+ /* Void. This is not documented, but the MRI compiler emits it. */
+ type = debug_make_void_type (dhandle);
+ break;
+
+ case 'Z':
+ /* Array with 0 lower bound. */
+ {
+ debug_type etype;
+ bfd_vma high;
+
+ if (! ieee_read_type_index (info, pp, &etype)
+ || ! ieee_read_number (info, pp, &high))
+ return false;
+
+ type = debug_make_array_type (dhandle, etype,
+ ieee_builtin_type (info, ty_code_start,
+ ((unsigned int)
+ builtin_int)),
+ 0, (bfd_signed_vma) high, false);
+ }
+ break;
+
+ case 'c': /* Complex. */
+ case 'd': /* Double complex. */
+ {
+ const char *name;
+ unsigned long namlen;
+
+ /* FIXME: I don't know what the name means. */
+
+ if (! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
+ }
+ break;
+
+ case 'f':
+ /* Pascal file name. FIXME. */
+ ieee_error (info, ty_code_start, "Pascal file name not supported");
+ return false;
+
+ case 'g':
+ /* Bitfield type. */
+ {
+ bfd_vma signedp, bitsize, dummy;
+ const bfd_byte *hold;
+ boolean present;
+
+ if (! ieee_read_number (info, pp, &signedp)
+ || ! ieee_read_number (info, pp, &bitsize))
+ return false;
+
+ /* I think the documentation says that there is a type index,
+ but some actual files do not have one. */
+ hold = *pp;
+ if (! ieee_read_optional_number (info, pp, &dummy, &present))
+ return false;
+ if (! present)
+ {
+ /* FIXME: This is just a guess. */
+ type = debug_make_int_type (dhandle, 4,
+ signedp ? false : true);
+ }
+ else
+ {
+ *pp = hold;
+ if (! ieee_read_type_index (info, pp, &type))
+ return false;
+ }
+ type_bitsize = bitsize;
+ }
+ break;
+
+ case 'n':
+ /* Qualifier. */
+ {
+ bfd_vma kind;
+ debug_type t;
+
+ if (! ieee_read_number (info, pp, &kind)
+ || ! ieee_read_type_index (info, pp, &t))
+ return false;
+
+ switch (kind)
+ {
+ default:
+ ieee_error (info, ty_start, "unsupported qualifer");
+ return false;
+
+ case 1:
+ type = debug_make_const_type (dhandle, t);
+ break;
+
+ case 2:
+ type = debug_make_volatile_type (dhandle, t);
+ break;
+ }
+ }
+ break;
+
+ case 's':
+ /* Set. */
+ {
+ bfd_vma size;
+ debug_type etype;
+
+ if (! ieee_read_number (info, pp, &size)
+ || ! ieee_read_type_index (info, pp, &etype))
+ return false;
+
+ /* FIXME: We ignore the size. */
+
+ type = debug_make_set_type (dhandle, etype, false);
+ }
+ break;
+
+ case 'x':
+ /* Procedure with compiler dependencies. */
+ {
+ struct ieee_var *pv;
+ bfd_vma attr, frame_type, push_mask, nargs, level, father;
+ debug_type rtype;
+ debug_type *arg_types;
+ boolean varargs;
+ boolean present;
+
+ /* FIXME: We ignore some of this information. */
+
+ pv = info->vars.vars + varindx;
+
+ if (! ieee_read_number (info, pp, &attr)
+ || ! ieee_read_number (info, pp, &frame_type)
+ || ! ieee_read_number (info, pp, &push_mask)
+ || ! ieee_read_type_index (info, pp, &rtype)
+ || ! ieee_read_number (info, pp, &nargs))
+ return false;
+ if (nargs == (bfd_vma) -1)
+ {
+ arg_types = NULL;
+ varargs = false;
+ }
+ else
+ {
+ unsigned int i;
+
+ arg_types = ((debug_type *)
+ xmalloc ((nargs + 1) * sizeof *arg_types));
+ for (i = 0; i < nargs; i++)
+ if (! ieee_read_type_index (info, pp, arg_types + i))
+ return false;
+
+ /* If the last type is pointer to void, this is really a
+ varargs function. */
+ varargs = false;
+ if (nargs > 0)
+ {
+ debug_type last;
+
+ last = arg_types[nargs - 1];
+ if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
+ && (debug_get_type_kind (dhandle,
+ debug_get_target_type (dhandle,
+ last))
+ == DEBUG_KIND_VOID))
+ {
+ --nargs;
+ varargs = true;
+ }
+ }
+
+ /* If there are any pointer arguments, turn them into
+ indirect types in case we later need to convert them to
+ reference types. */
+ for (i = 0; i < nargs; i++)
+ {
+ if (debug_get_type_kind (dhandle, arg_types[i])
+ == DEBUG_KIND_POINTER)
+ {
+ if (arg_slots == NULL)
+ {
+ arg_slots = ((debug_type *)
+ xmalloc (nargs * sizeof *arg_slots));
+ memset (arg_slots, 0, nargs * sizeof *arg_slots);
+ }
+ arg_slots[i] = arg_types[i];
+ arg_types[i] =
+ debug_make_indirect_type (dhandle,
+ arg_slots + i,
+ (const char *) NULL);
+ }
+ }
+
+ arg_types[nargs] = DEBUG_TYPE_NULL;
+ }
+ if (! ieee_read_number (info, pp, &level)
+ || ! ieee_read_optional_number (info, pp, &father, &present))
+ return false;
+
+ /* We can't distinguish between a global function and a static
+ function. */
+ pv->kind = IEEE_FUNCTION;
+
+ if (pv->namlen > 0
+ && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
+ {
+ /* Set up the return type as an indirect type pointing to
+ the variable slot, so that we can change it to a
+ reference later if appropriate. */
+ pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
+ *pv->pslot = rtype;
+ rtype = debug_make_indirect_type (dhandle, pv->pslot,
+ (const char *) NULL);
+ }
+
+ type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
+ }
+ break;
+ }
+
+ /* Record the type in the table. */
+
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ info->vars.vars[varindx].type = type;
+
+ if ((tag || typdef)
+ && info->vars.vars[varindx].namlen > 0)
+ {
+ const char *name;
+
+ name = savestring (info->vars.vars[varindx].name,
+ info->vars.vars[varindx].namlen);
+ if (typdef)
+ type = debug_name_type (dhandle, name, type);
+ else if (tc == 'E' || tc == 'N')
+ type = debug_tag_type (dhandle, name, type);
+ else
+ {
+ struct ieee_tag *it;
+
+ /* We must allocate all struct tags as indirect types, so
+ that if we later see a definition of the tag as a C++
+ record we can update the indirect slot and automatically
+ change all the existing references. */
+ it = (struct ieee_tag *) xmalloc (sizeof *it);
+ memset (it, 0, sizeof *it);
+ it->next = info->tags;
+ info->tags = it;
+ it->name = name;
+ it->slot = type;
+
+ type = debug_make_indirect_type (dhandle, &it->slot, name);
+ type = debug_tag_type (dhandle, name, type);
+
+ it->type = type;
+ }
+ if (type == NULL)
+ return false;
+ }
+
+ info->types.types[typeindx].type = type;
+ info->types.types[typeindx].arg_slots = arg_slots;
+ info->types.types[typeindx].bitsize = type_bitsize;
+
+ /* We may have already allocated type as an indirect type pointing
+ to slot. It does no harm to replace the indirect type with the
+ real type. Filling in slot as well handles the indirect types
+ which are already hanging around. */
+ if (info->types.types[typeindx].pslot != NULL)
+ *info->types.types[typeindx].pslot = type;
+
+ return true;
+}
+
+/* Parse an ATN record. */
+
+static boolean
+parse_ieee_atn (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *atn_start, *atn_code_start;
+ bfd_vma varindx;
+ struct ieee_var *pvar;
+ debug_type type;
+ bfd_vma atn_code;
+ PTR dhandle;
+ bfd_vma v, v2, v3, v4, v5;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy;
+ boolean present;
+ int blocktype;
+
+ atn_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx)
+ || ! ieee_read_type_index (info, pp, &type))
+ return false;
+
+ atn_code_start = *pp;
+
+ if (! ieee_read_number (info, pp, &atn_code))
+ return false;
+
+ if (varindx == 0)
+ {
+ pvar = NULL;
+ name = "";
+ namlen = 0;
+ }
+ else if (varindx < 32)
+ {
+ ieee_error (info, atn_start, "illegal variable index");
+ return false;
+ }
+ else
+ {
+ varindx -= 32;
+ if (varindx >= info->vars.alloc
+ || info->vars.vars[varindx].name == NULL)
+ {
+ /* The MRI compiler or linker sometimes omits the NN record
+ for a pmisc record. */
+ if (atn_code == 62)
+ {
+ if (varindx >= info->vars.alloc)
+ {
+ unsigned int alloc;
+
+ alloc = info->vars.alloc;
+ if (alloc == 0)
+ alloc = 4;
+ while (varindx >= alloc)
+ alloc *= 2;
+ info->vars.vars = ((struct ieee_var *)
+ xrealloc (info->vars.vars,
+ (alloc
+ * sizeof *info->vars.vars)));
+ memset (info->vars.vars + info->vars.alloc, 0,
+ ((alloc - info->vars.alloc)
+ * sizeof *info->vars.vars));
+ info->vars.alloc = alloc;
+ }
+
+ pvar = info->vars.vars + varindx;
+ pvar->name = "";
+ pvar->namlen = 0;
+ }
+ else
+ {
+ ieee_error (info, atn_start, "undefined variable in ATN");
+ return false;
+ }
+ }
+
+ pvar = info->vars.vars + varindx;
+
+ pvar->type = type;
+
+ name = pvar->name;
+ namlen = pvar->namlen;
+ }
+
+ dhandle = info->dhandle;
+
+ /* If we are going to call debug_record_variable with a pointer
+ type, change the type to an indirect type so that we can later
+ change it to a reference type if we encounter a C++ pmisc 'R'
+ record. */
+ if (pvar != NULL
+ && type != DEBUG_TYPE_NULL
+ && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER)
+ {
+ switch (atn_code)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 8:
+ case 10:
+ pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot);
+ *pvar->pslot = type;
+ type = debug_make_indirect_type (dhandle, pvar->pslot,
+ (const char *) NULL);
+ pvar->type = type;
+ break;
+ }
+ }
+
+ switch (atn_code)
+ {
+ default:
+ ieee_error (info, atn_code_start, "unknown ATN type");
+ return false;
+
+ case 1:
+ /* Automatic variable. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v);
+
+ case 2:
+ /* Register variable. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER,
+ ieee_regno_to_genreg (info->abfd, v));
+
+ case 3:
+ /* Static variable. */
+ if (! ieee_require_asn (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (info->blockstack.bsp <= info->blockstack.stack)
+ blocktype = 0;
+ else
+ blocktype = info->blockstack.bsp[-1].kind;
+ if (pvar != NULL)
+ {
+ if (blocktype == 4 || blocktype == 6)
+ pvar->kind = IEEE_LOCAL;
+ else
+ pvar->kind = IEEE_STATIC;
+ }
+ return debug_record_variable (dhandle, namcopy, type,
+ (blocktype == 4 || blocktype == 6
+ ? DEBUG_LOCAL_STATIC
+ : DEBUG_STATIC),
+ v);
+
+ case 4:
+ /* External function. We don't currently record these. FIXME. */
+ if (pvar != NULL)
+ pvar->kind = IEEE_EXTERNAL;
+ return true;
+
+ case 5:
+ /* External variable. We don't currently record these. FIXME. */
+ if (pvar != NULL)
+ pvar->kind = IEEE_EXTERNAL;
+ return true;
+
+ case 7:
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_number (info, pp, &v3, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v4, &present))
+ return false;
+ }
+
+ /* We just ignore the two optional fields in v3 and v4, since
+ they are not defined. */
+
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+
+ /* We have no way to record the column number. FIXME. */
+
+ return debug_record_line (dhandle, v, v3);
+
+ case 8:
+ /* Global variable. */
+ if (! ieee_require_asn (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_GLOBAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v);
+
+ case 9:
+ /* Variable lifetime information. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+
+ /* We have no way to record this information. FIXME. */
+ return true;
+
+ case 10:
+ /* Locked register. The spec says that there are two required
+ fields, but at least on occasion the MRI compiler only emits
+ one. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+
+ /* I think this means a variable that is both in a register and
+ a frame slot. We ignore the frame slot. FIXME. */
+
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v);
+
+ case 11:
+ /* Reserved for FORTRAN common. */
+ ieee_error (info, atn_code_start, "unsupported ATN11");
+
+ /* Return true to keep going. */
+ return true;
+
+ case 12:
+ /* Based variable. */
+ v3 = 0;
+ v4 = 0x80;
+ v5 = 0;
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_number (info, pp, &v3, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v4, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v5, &present))
+ return false;
+ }
+ }
+
+ /* We have no way to record this information. FIXME. */
+
+ ieee_error (info, atn_code_start, "unsupported ATN12");
+
+ /* Return true to keep going. */
+ return true;
+
+ case 16:
+ /* Constant. The description of this that I have is ambiguous,
+ so I'm not going to try to implement it. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ }
+ }
+
+ if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum)
+ {
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+ }
+
+ return true;
+
+ case 19:
+ /* Static variable from assembler. */
+ v2 = 0;
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present)
+ || ! ieee_require_asn (info, pp, &v3))
+ return false;
+ namcopy = savestring (name, namlen);
+ /* We don't really handle this correctly. FIXME. */
+ return debug_record_variable (dhandle, namcopy,
+ debug_make_void_type (dhandle),
+ v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC,
+ v3);
+
+ case 62:
+ /* Procedure miscellaneous information. */
+ case 63:
+ /* Variable miscellaneous information. */
+ case 64:
+ /* Module miscellaneous information. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+
+ if (atn_code == 62 && v == 80)
+ {
+ if (present)
+ {
+ ieee_error (info, atn_code_start,
+ "unexpected string in C++ misc");
+ return false;
+ }
+ return ieee_read_cxx_misc (info, pp, v2);
+ }
+
+ /* We just ignore all of this stuff. FIXME. */
+
+ for (; v2 > 0; --v2)
+ {
+ switch ((ieee_record_enum_type) **pp)
+ {
+ default:
+ ieee_error (info, *pp, "bad misc record");
+ return false;
+
+ case ieee_at_record_enum:
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+ break;
+
+ case ieee_e2_first_byte_enum:
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ /*NOTREACHED*/
+}
+
+/* Handle C++ debugging miscellaneous records. This is called for
+ procedure miscellaneous records of type 80. */
+
+static boolean
+ieee_read_cxx_misc (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ bfd_vma category;
+
+ start = *pp;
+
+ /* Get the category of C++ misc record. */
+ if (! ieee_require_asn (info, pp, &category))
+ return false;
+ --count;
+
+ switch (category)
+ {
+ default:
+ ieee_error (info, start, "unrecognized C++ misc record");
+ return false;
+
+ case 'T':
+ if (! ieee_read_cxx_class (info, pp, count))
+ return false;
+ break;
+
+ case 'M':
+ {
+ bfd_vma flags;
+ const char *name;
+ unsigned long namlen;
+
+ /* The IEEE spec indicates that the 'M' record only has a
+ flags field. The MRI compiler also emits the name of the
+ function. */
+
+ if (! ieee_require_asn (info, pp, &flags))
+ return false;
+ if (*pp < info->pend
+ && (ieee_record_enum_type) **pp == ieee_at_record_enum)
+ {
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+ }
+
+ /* This is emitted for method functions, but I don't think we
+ care very much. It might help if it told us useful
+ information like the class with which this function is
+ associated, but it doesn't, so it isn't helpful. */
+ }
+ break;
+
+ case 'B':
+ if (! ieee_read_cxx_defaults (info, pp, count))
+ return false;
+ break;
+
+ case 'z':
+ {
+ const char *name, *mangled, *class;
+ unsigned long namlen, mangledlen, classlen;
+ bfd_vma control;
+
+ /* Pointer to member. */
+
+ if (! ieee_require_atn65 (info, pp, &name, &namlen)
+ || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)
+ || ! ieee_require_atn65 (info, pp, &class, &classlen)
+ || ! ieee_require_asn (info, pp, &control))
+ return false;
+
+ /* FIXME: We should now track down name and change its type. */
+ }
+ break;
+
+ case 'R':
+ if (! ieee_read_reference (info, pp))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/* Read a C++ class definition. This is a pmisc type 80 record of
+ category 'T'. */
+
+static boolean
+ieee_read_cxx_class (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ bfd_vma class;
+ const char *tag;
+ unsigned long taglen;
+ struct ieee_tag *it;
+ PTR dhandle;
+ debug_field *fields;
+ unsigned int field_count, field_alloc;
+ debug_baseclass *baseclasses;
+ unsigned int baseclasses_count, baseclasses_alloc;
+ const debug_field *structfields;
+ struct ieee_method
+ {
+ const char *name;
+ unsigned long namlen;
+ debug_method_variant *variants;
+ unsigned count;
+ unsigned int alloc;
+ } *methods;
+ unsigned int methods_count, methods_alloc;
+ debug_type vptrbase;
+ boolean ownvptr;
+ debug_method *dmethods;
+
+ start = *pp;
+
+ if (! ieee_require_asn (info, pp, &class))
+ return false;
+ --count;
+
+ if (! ieee_require_atn65 (info, pp, &tag, &taglen))
+ return false;
+ --count;
+
+ /* Find the C struct with this name. */
+ for (it = info->tags; it != NULL; it = it->next)
+ if (it->name[0] == tag[0]
+ && strncmp (it->name, tag, taglen) == 0
+ && strlen (it->name) == taglen)
+ break;
+ if (it == NULL)
+ {
+ ieee_error (info, start, "undefined C++ object");
+ return false;
+ }
+
+ dhandle = info->dhandle;
+
+ fields = NULL;
+ field_count = 0;
+ field_alloc = 0;
+ baseclasses = NULL;
+ baseclasses_count = 0;
+ baseclasses_alloc = 0;
+ methods = NULL;
+ methods_count = 0;
+ methods_alloc = 0;
+ vptrbase = DEBUG_TYPE_NULL;
+ ownvptr = false;
+
+ structfields = debug_get_fields (dhandle, it->type);
+
+ while (count > 0)
+ {
+ bfd_vma id;
+ const bfd_byte *spec_start;
+
+ spec_start = *pp;
+
+ if (! ieee_require_asn (info, pp, &id))
+ return false;
+ --count;
+
+ switch (id)
+ {
+ default:
+ ieee_error (info, spec_start, "unrecognized C++ object spec");
+ return false;
+
+ case 'b':
+ {
+ bfd_vma flags, cinline;
+ const char *basename, *fieldname;
+ unsigned long baselen, fieldlen;
+ char *basecopy;
+ debug_type basetype;
+ bfd_vma bitpos;
+ boolean virtualp;
+ enum debug_visibility visibility;
+ debug_baseclass baseclass;
+
+ /* This represents a base or friend class. */
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &basename, &baselen)
+ || ! ieee_require_asn (info, pp, &cinline)
+ || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen))
+ return false;
+ count -= 4;
+
+ /* We have no way of recording friend information, so we
+ just ignore it. */
+ if ((flags & BASEFLAGS_FRIEND) != 0)
+ break;
+
+ /* I assume that either all of the members of the
+ baseclass are included in the object, starting at the
+ beginning of the object, or that none of them are
+ included. */
+
+ if ((fieldlen == 0) == (cinline == 0))
+ {
+ ieee_error (info, start, "unsupported C++ object type");
+ return false;
+ }
+
+ basecopy = savestring (basename, baselen);
+ basetype = debug_find_tagged_type (dhandle, basecopy,
+ DEBUG_KIND_ILLEGAL);
+ free (basecopy);
+ if (basetype == DEBUG_TYPE_NULL)
+ {
+ ieee_error (info, start, "C++ base class not defined");
+ return false;
+ }
+
+ if (fieldlen == 0)
+ bitpos = 0;
+ else
+ {
+ const debug_field *pf;
+
+ if (structfields == NULL)
+ {
+ ieee_error (info, start, "C++ object has no fields");
+ return false;
+ }
+
+ for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (fname[0] == fieldname[0]
+ && strncmp (fname, fieldname, fieldlen) == 0
+ && strlen (fname) == fieldlen)
+ break;
+ }
+ if (*pf == DEBUG_FIELD_NULL)
+ {
+ ieee_error (info, start,
+ "C++ base class not found in container");
+ return false;
+ }
+
+ bitpos = debug_get_field_bitpos (dhandle, *pf);
+ }
+
+ if ((flags & BASEFLAGS_VIRTUAL) != 0)
+ virtualp = true;
+ else
+ virtualp = false;
+ if ((flags & BASEFLAGS_PRIVATE) != 0)
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ else
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+
+ baseclass = debug_make_baseclass (dhandle, basetype, bitpos,
+ virtualp, visibility);
+ if (baseclass == DEBUG_BASECLASS_NULL)
+ return false;
+
+ if (baseclasses_count + 1 >= baseclasses_alloc)
+ {
+ baseclasses_alloc += 10;
+ baseclasses = ((debug_baseclass *)
+ xrealloc (baseclasses,
+ (baseclasses_alloc
+ * sizeof *baseclasses)));
+ }
+
+ baseclasses[baseclasses_count] = baseclass;
+ ++baseclasses_count;
+ baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL;
+ }
+ break;
+
+ case 'd':
+ {
+ bfd_vma flags;
+ const char *fieldname, *mangledname;
+ unsigned long fieldlen, mangledlen;
+ char *fieldcopy;
+ boolean staticp;
+ debug_type ftype;
+ const debug_field *pf = NULL;
+ enum debug_visibility visibility;
+ debug_field field;
+
+ /* This represents a data member. */
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)
+ || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen))
+ return false;
+ count -= 3;
+
+ fieldcopy = savestring (fieldname, fieldlen);
+
+ staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false;
+
+ if (staticp)
+ {
+ struct ieee_var *pv, *pvend;
+
+ /* See if we can find a definition for this variable. */
+ pv = info->vars.vars;
+ pvend = pv + info->vars.alloc;
+ for (; pv < pvend; pv++)
+ if (pv->namlen == mangledlen
+ && strncmp (pv->name, mangledname, mangledlen) == 0)
+ break;
+ if (pv < pvend)
+ ftype = pv->type;
+ else
+ {
+ /* This can happen if the variable is never used. */
+ ftype = ieee_builtin_type (info, start,
+ (unsigned int) builtin_void);
+ }
+ }
+ else
+ {
+ unsigned int findx;
+
+ if (structfields == NULL)
+ {
+ ieee_error (info, start, "C++ object has no fields");
+ return false;
+ }
+
+ for (pf = structfields, findx = 0;
+ *pf != DEBUG_FIELD_NULL;
+ pf++, findx++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (fname[0] == mangledname[0]
+ && strncmp (fname, mangledname, mangledlen) == 0
+ && strlen (fname) == mangledlen)
+ break;
+ }
+ if (*pf == DEBUG_FIELD_NULL)
+ {
+ ieee_error (info, start,
+ "C++ data member not found in container");
+ return false;
+ }
+
+ ftype = debug_get_field_type (dhandle, *pf);
+
+ if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER)
+ {
+ /* We might need to convert this field into a
+ reference type later on, so make it an indirect
+ type. */
+ if (it->fslots == NULL)
+ {
+ unsigned int fcnt;
+ const debug_field *pfcnt;
+
+ fcnt = 0;
+ for (pfcnt = structfields;
+ *pfcnt != DEBUG_FIELD_NULL;
+ pfcnt++)
+ ++fcnt;
+ it->fslots = ((debug_type *)
+ xmalloc (fcnt * sizeof *it->fslots));
+ memset (it->fslots, 0,
+ fcnt * sizeof *it->fslots);
+ }
+
+ if (ftype == DEBUG_TYPE_NULL)
+ return false;
+ it->fslots[findx] = ftype;
+ ftype = debug_make_indirect_type (dhandle,
+ it->fslots + findx,
+ (const char *) NULL);
+ }
+ }
+ if (ftype == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (flags & CXXFLAGS_VISIBILITY)
+ {
+ default:
+ ieee_error (info, start, "unknown C++ visibility");
+ return false;
+
+ case CXXFLAGS_VISIBILITY_PUBLIC:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PRIVATE:
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PROTECTED:
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ }
+
+ if (staticp)
+ {
+ char *mangledcopy;
+
+ mangledcopy = savestring (mangledname, mangledlen);
+
+ field = debug_make_static_member (dhandle, fieldcopy,
+ ftype, mangledcopy,
+ visibility);
+ }
+ else
+ {
+ bfd_vma bitpos, bitsize;
+
+ bitpos = debug_get_field_bitpos (dhandle, *pf);
+ bitsize = debug_get_field_bitsize (dhandle, *pf);
+ if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
+ {
+ ieee_error (info, start, "bad C++ field bit pos or size");
+ return false;
+ }
+ field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
+ bitsize, visibility);
+ }
+
+ if (field == DEBUG_FIELD_NULL)
+ return false;
+
+ if (field_count + 1 >= field_alloc)
+ {
+ field_alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, field_alloc * sizeof *fields));
+ }
+
+ fields[field_count] = field;
+ ++field_count;
+ fields[field_count] = DEBUG_FIELD_NULL;
+ }
+ break;
+
+ case 'm':
+ case 'v':
+ {
+ bfd_vma flags, voffset, control;
+ const char *name, *mangled;
+ unsigned long namlen, mangledlen;
+ struct ieee_var *pv, *pvend;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp, volatilep;
+ char *mangledcopy;
+ debug_method_variant mv;
+ struct ieee_method *meth;
+ unsigned int im;
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &name, &namlen)
+ || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
+ return false;
+ count -= 3;
+ if (id != 'v')
+ voffset = 0;
+ else
+ {
+ if (! ieee_require_asn (info, pp, &voffset))
+ return false;
+ --count;
+ }
+ if (! ieee_require_asn (info, pp, &control))
+ return false;
+ --count;
+
+ /* We just ignore the control information. */
+
+ /* We have no way to represent friend information, so we
+ just ignore it. */
+ if ((flags & CXXFLAGS_FRIEND) != 0)
+ break;
+
+ /* We should already have seen a type for the function. */
+ pv = info->vars.vars;
+ pvend = pv + info->vars.alloc;
+ for (; pv < pvend; pv++)
+ if (pv->namlen == mangledlen
+ && strncmp (pv->name, mangled, mangledlen) == 0)
+ break;
+
+ if (pv >= pvend)
+ {
+ /* We won't have type information for this function if
+ it is not included in this file. We don't try to
+ handle this case. FIXME. */
+ type = (debug_make_function_type
+ (dhandle,
+ ieee_builtin_type (info, start,
+ (unsigned int) builtin_void),
+ (debug_type *) NULL,
+ false));
+ }
+ else
+ {
+ debug_type return_type;
+ const debug_type *arg_types;
+ boolean varargs;
+
+ if (debug_get_type_kind (dhandle, pv->type)
+ != DEBUG_KIND_FUNCTION)
+ {
+ ieee_error (info, start,
+ "bad type for C++ method function");
+ return false;
+ }
+
+ return_type = debug_get_return_type (dhandle, pv->type);
+ arg_types = debug_get_parameter_types (dhandle, pv->type,
+ &varargs);
+ if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
+ {
+ ieee_error (info, start,
+ "no type information for C++ method function");
+ return false;
+ }
+
+ type = debug_make_method_type (dhandle, return_type, it->type,
+ (debug_type *) arg_types,
+ varargs);
+ }
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (flags & CXXFLAGS_VISIBILITY)
+ {
+ default:
+ ieee_error (info, start, "unknown C++ visibility");
+ return false;
+
+ case CXXFLAGS_VISIBILITY_PUBLIC:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PRIVATE:
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PROTECTED:
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ }
+
+ constp = (flags & CXXFLAGS_CONST) != 0 ? true : false;
+ volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false;
+
+ mangledcopy = savestring (mangled, mangledlen);
+
+ if ((flags & CXXFLAGS_STATIC) != 0)
+ {
+ if (id == 'v')
+ {
+ ieee_error (info, start, "C++ static virtual method");
+ return false;
+ }
+ mv = debug_make_static_method_variant (dhandle, mangledcopy,
+ type, visibility,
+ constp, volatilep);
+ }
+ else
+ {
+ debug_type vcontext;
+
+ if (id != 'v')
+ vcontext = DEBUG_TYPE_NULL;
+ else
+ {
+ /* FIXME: How can we calculate this correctly? */
+ vcontext = it->type;
+ }
+ mv = debug_make_method_variant (dhandle, mangledcopy, type,
+ visibility, constp,
+ volatilep, voffset,
+ vcontext);
+ }
+ if (mv == DEBUG_METHOD_VARIANT_NULL)
+ return false;
+
+ for (meth = methods, im = 0; im < methods_count; meth++, im++)
+ if (meth->namlen == namlen
+ && strncmp (meth->name, name, namlen) == 0)
+ break;
+ if (im >= methods_count)
+ {
+ if (methods_count >= methods_alloc)
+ {
+ methods_alloc += 10;
+ methods = ((struct ieee_method *)
+ xrealloc (methods,
+ methods_alloc * sizeof *methods));
+ }
+ methods[methods_count].name = name;
+ methods[methods_count].namlen = namlen;
+ methods[methods_count].variants = NULL;
+ methods[methods_count].count = 0;
+ methods[methods_count].alloc = 0;
+ meth = methods + methods_count;
+ ++methods_count;
+ }
+
+ if (meth->count + 1 >= meth->alloc)
+ {
+ meth->alloc += 10;
+ meth->variants = ((debug_method_variant *)
+ xrealloc (meth->variants,
+ (meth->alloc
+ * sizeof *meth->variants)));
+ }
+
+ meth->variants[meth->count] = mv;
+ ++meth->count;
+ meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL;
+ }
+ break;
+
+ case 'o':
+ {
+ bfd_vma spec;
+
+ /* We have no way to store this information, so we just
+ ignore it. */
+ if (! ieee_require_asn (info, pp, &spec))
+ return false;
+ --count;
+ if ((spec & 4) != 0)
+ {
+ const char *filename;
+ unsigned long filenamlen;
+ bfd_vma lineno;
+
+ if (! ieee_require_atn65 (info, pp, &filename, &filenamlen)
+ || ! ieee_require_asn (info, pp, &lineno))
+ return false;
+ count -= 2;
+ }
+ else if ((spec & 8) != 0)
+ {
+ const char *mangled;
+ unsigned long mangledlen;
+
+ if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
+ return false;
+ --count;
+ }
+ else
+ {
+ ieee_error (info, start,
+ "unrecognized C++ object overhead spec");
+ return false;
+ }
+ }
+ break;
+
+ case 'z':
+ {
+ const char *vname, *basename;
+ unsigned long vnamelen, baselen;
+ bfd_vma vsize, control;
+
+ /* A virtual table pointer. */
+
+ if (! ieee_require_atn65 (info, pp, &vname, &vnamelen)
+ || ! ieee_require_asn (info, pp, &vsize)
+ || ! ieee_require_atn65 (info, pp, &basename, &baselen)
+ || ! ieee_require_asn (info, pp, &control))
+ return false;
+ count -= 4;
+
+ /* We just ignore the control number. We don't care what
+ the virtual table name is. We have no way to store the
+ virtual table size, and I don't think we care anyhow. */
+
+ /* FIXME: We can't handle multiple virtual table pointers. */
+
+ if (baselen == 0)
+ ownvptr = true;
+ else
+ {
+ char *basecopy;
+
+ basecopy = savestring (basename, baselen);
+ vptrbase = debug_find_tagged_type (dhandle, basecopy,
+ DEBUG_KIND_ILLEGAL);
+ free (basecopy);
+ if (vptrbase == DEBUG_TYPE_NULL)
+ {
+ ieee_error (info, start, "undefined C++ vtable");
+ return false;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ /* Now that we have seen all the method variants, we can call
+ debug_make_method for each one. */
+
+ if (methods_count == 0)
+ dmethods = NULL;
+ else
+ {
+ unsigned int i;
+
+ dmethods = ((debug_method *)
+ xmalloc ((methods_count + 1) * sizeof *dmethods));
+ for (i = 0; i < methods_count; i++)
+ {
+ char *namcopy;
+
+ namcopy = savestring (methods[i].name, methods[i].namlen);
+ dmethods[i] = debug_make_method (dhandle, namcopy,
+ methods[i].variants);
+ if (dmethods[i] == DEBUG_METHOD_NULL)
+ return false;
+ }
+ dmethods[i] = DEBUG_METHOD_NULL;
+ free (methods);
+ }
+
+ /* The struct type was created as an indirect type pointing at
+ it->slot. We update it->slot to automatically update all
+ references to this struct. */
+ it->slot = debug_make_object_type (dhandle,
+ class != 'u',
+ debug_get_type_size (dhandle,
+ it->slot),
+ fields, baseclasses, dmethods,
+ vptrbase, ownvptr);
+ if (it->slot == DEBUG_TYPE_NULL)
+ return false;
+
+ return true;
+}
+
+/* Read C++ default argument value and reference type information. */
+
+static boolean
+ieee_read_cxx_defaults (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ const char *fnname;
+ unsigned long fnlen;
+ bfd_vma defcount;
+
+ start = *pp;
+
+ /* Giving the function name before the argument count is an addendum
+ to the spec. The function name is demangled, though, so this
+ record must always refer to the current function. */
+
+ if (info->blockstack.bsp <= info->blockstack.stack
+ || info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
+ {
+ ieee_error (info, start, "C++ default values not in a function");
+ return false;
+ }
+
+ if (! ieee_require_atn65 (info, pp, &fnname, &fnlen)
+ || ! ieee_require_asn (info, pp, &defcount))
+ return false;
+ count -= 2;
+
+ while (defcount-- > 0)
+ {
+ bfd_vma type, val;
+ const char *strval;
+ unsigned long strvallen;
+
+ if (! ieee_require_asn (info, pp, &type))
+ return false;
+ --count;
+
+ switch (type)
+ {
+ case 0:
+ case 4:
+ break;
+
+ case 1:
+ case 2:
+ if (! ieee_require_asn (info, pp, &val))
+ return false;
+ --count;
+ break;
+
+ case 3:
+ case 7:
+ if (! ieee_require_atn65 (info, pp, &strval, &strvallen))
+ return false;
+ --count;
+ break;
+
+ default:
+ ieee_error (info, start, "unrecognized C++ default type");
+ return false;
+ }
+
+ /* We have no way to record the default argument values, so we
+ just ignore them. FIXME. */
+ }
+
+ /* Any remaining arguments are indices of parameters that are really
+ reference type. */
+ if (count > 0)
+ {
+ PTR dhandle;
+ debug_type *arg_slots;
+
+ dhandle = info->dhandle;
+ arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots;
+ while (count-- > 0)
+ {
+ bfd_vma indx;
+ debug_type target;
+
+ if (! ieee_require_asn (info, pp, &indx))
+ return false;
+ /* The index is 1 based. */
+ --indx;
+ if (arg_slots == NULL
+ || arg_slots[indx] == DEBUG_TYPE_NULL
+ || (debug_get_type_kind (dhandle, arg_slots[indx])
+ != DEBUG_KIND_POINTER))
+ {
+ ieee_error (info, start, "reference parameter is not a pointer");
+ return false;
+ }
+
+ target = debug_get_target_type (dhandle, arg_slots[indx]);
+ arg_slots[indx] = debug_make_reference_type (dhandle, target);
+ if (arg_slots[indx] == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read a C++ reference definition. */
+
+static boolean
+ieee_read_reference (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *start;
+ bfd_vma flags;
+ const char *class, *name;
+ unsigned long classlen, namlen;
+ debug_type *pslot;
+ debug_type target;
+
+ start = *pp;
+
+ if (! ieee_require_asn (info, pp, &flags))
+ return false;
+
+ /* Giving the class name before the member name is in an addendum to
+ the spec. */
+ if (flags == 3)
+ {
+ if (! ieee_require_atn65 (info, pp, &class, &classlen))
+ return false;
+ }
+
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+
+ pslot = NULL;
+ if (flags != 3)
+ {
+ int pass;
+
+ /* We search from the last variable indices to the first in
+ hopes of finding local variables correctly. We search the
+ local variables on the first pass, and the global variables
+ on the second. FIXME: This probably won't work in all cases.
+ On the other hand, I don't know what will. */
+ for (pass = 0; pass < 2; pass++)
+ {
+ struct ieee_vars *vars;
+ int i;
+ struct ieee_var *pv = NULL;
+
+ if (pass == 0)
+ vars = &info->vars;
+ else
+ {
+ vars = info->global_vars;
+ if (vars == NULL)
+ break;
+ }
+
+ for (i = (int) vars->alloc - 1; i >= 0; i--)
+ {
+ boolean found;
+
+ pv = vars->vars + i;
+
+ if (pv->pslot == NULL
+ || pv->namlen != namlen
+ || strncmp (pv->name, name, namlen) != 0)
+ continue;
+
+ found = false;
+ switch (flags)
+ {
+ default:
+ ieee_error (info, start,
+ "unrecognized C++ reference type");
+ return false;
+
+ case 0:
+ /* Global variable or function. */
+ if (pv->kind == IEEE_GLOBAL
+ || pv->kind == IEEE_EXTERNAL
+ || pv->kind == IEEE_FUNCTION)
+ found = true;
+ break;
+
+ case 1:
+ /* Global static variable or function. */
+ if (pv->kind == IEEE_STATIC
+ || pv->kind == IEEE_FUNCTION)
+ found = true;
+ break;
+
+ case 2:
+ /* Local variable. */
+ if (pv->kind == IEEE_LOCAL)
+ found = true;
+ break;
+ }
+
+ if (found)
+ break;
+ }
+
+ if (i >= 0)
+ {
+ pslot = pv->pslot;
+ break;
+ }
+ }
+ }
+ else
+ {
+ struct ieee_tag *it;
+
+ for (it = info->tags; it != NULL; it = it->next)
+ {
+ if (it->name[0] == class[0]
+ && strncmp (it->name, class, classlen) == 0
+ && strlen (it->name) == classlen)
+ {
+ if (it->fslots != NULL)
+ {
+ const debug_field *pf;
+ unsigned int findx;
+
+ pf = debug_get_fields (info->dhandle, it->type);
+ if (pf == NULL)
+ {
+ ieee_error (info, start,
+ "C++ reference in class with no fields");
+ return false;
+ }
+
+ for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (info->dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (strncmp (fname, name, namlen) == 0
+ && strlen (fname) == namlen)
+ {
+ pslot = it->fslots + findx;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (pslot == NULL)
+ {
+ ieee_error (info, start, "C++ reference not found");
+ return false;
+ }
+
+ /* We allocated the type of the object as an indirect type pointing
+ to *pslot, which we can now update to be a reference type. */
+ if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
+ {
+ ieee_error (info, start, "C++ reference is not pointer");
+ return false;
+ }
+
+ target = debug_get_target_type (info->dhandle, *pslot);
+ *pslot = debug_make_reference_type (info->dhandle, target);
+ if (*pslot == DEBUG_TYPE_NULL)
+ return false;
+
+ return true;
+}
+
+/* Require an ASN record. */
+
+static boolean
+ieee_require_asn (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ const bfd_byte *start;
+ ieee_record_enum_type c;
+ bfd_vma varindx;
+
+ start = *pp;
+
+ c = (ieee_record_enum_type) **pp;
+ if (c != ieee_e2_first_byte_enum)
+ {
+ ieee_error (info, start, "missing required ASN");
+ return false;
+ }
+ ++*pp;
+
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
+ if (c != ieee_asn_record_enum)
+ {
+ ieee_error (info, start, "missing required ASN");
+ return false;
+ }
+ ++*pp;
+
+ /* Just ignore the variable index. */
+ if (! ieee_read_number (info, pp, &varindx))
+ return false;
+
+ return ieee_read_expression (info, pp, pv);
+}
+
+/* Require an ATN65 record. */
+
+static boolean
+ieee_require_atn65 (info, pp, pname, pnamlen)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+{
+ const bfd_byte *start;
+ ieee_record_enum_type c;
+ bfd_vma name_indx, type_indx, atn_code;
+
+ start = *pp;
+
+ c = (ieee_record_enum_type) **pp;
+ if (c != ieee_at_record_enum)
+ {
+ ieee_error (info, start, "missing required ATN65");
+ return false;
+ }
+ ++*pp;
+
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
+ if (c != ieee_atn_record_enum)
+ {
+ ieee_error (info, start, "missing required ATN65");
+ return false;
+ }
+ ++*pp;
+
+ if (! ieee_read_number (info, pp, &name_indx)
+ || ! ieee_read_number (info, pp, &type_indx)
+ || ! ieee_read_number (info, pp, &atn_code))
+ return false;
+
+ /* Just ignore name_indx. */
+
+ if (type_indx != 0 || atn_code != 65)
+ {
+ ieee_error (info, start, "bad ATN65 record");
+ return false;
+ }
+
+ return ieee_read_id (info, pp, pname, pnamlen);
+}
+
+/* Convert a register number in IEEE debugging information into a
+ generic register number. */
+
+static int
+ieee_regno_to_genreg (abfd, r)
+ bfd *abfd;
+ int r;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ /* For some reasons stabs adds 2 to the floating point register
+ numbers. */
+ if (r >= 16)
+ r += 2;
+ break;
+
+ case bfd_arch_i960:
+ /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+ 32 to 35 for fp0 to fp3. */
+ --r;
+ break;
+
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/* Convert a generic register number to an IEEE specific one. */
+
+static int
+ieee_genreg_to_regno (abfd, r)
+ bfd *abfd;
+ int r;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ /* For some reason stabs add 2 to the floating point register
+ numbers. */
+ if (r >= 18)
+ r -= 2;
+ break;
+
+ case bfd_arch_i960:
+ /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+ 32 to 35 for fp0 to fp3. */
+ ++r;
+ break;
+
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/* These routines build IEEE debugging information out of the generic
+ debugging information. */
+
+/* We build the IEEE debugging information byte by byte. Rather than
+ waste time copying data around, we use a linked list of buffers to
+ hold the data. */
+
+#define IEEE_BUFSIZE (490)
+
+struct ieee_buf
+{
+ /* Next buffer. */
+ struct ieee_buf *next;
+ /* Number of data bytes in this buffer. */
+ unsigned int c;
+ /* Bytes. */
+ bfd_byte buf[IEEE_BUFSIZE];
+};
+
+/* A list of buffers. */
+
+struct ieee_buflist
+{
+ /* Head of list. */
+ struct ieee_buf *head;
+ /* Tail--last buffer on list. */
+ struct ieee_buf *tail;
+};
+
+/* In order to generate the BB11 blocks required by the HP emulator,
+ we keep track of ranges of addresses which correspond to a given
+ compilation unit. */
+
+struct ieee_range
+{
+ /* Next range. */
+ struct ieee_range *next;
+ /* Low address. */
+ bfd_vma low;
+ /* High address. */
+ bfd_vma high;
+};
+
+/* This structure holds information for a class on the type stack. */
+
+struct ieee_type_class
+{
+ /* The name index in the debugging information. */
+ unsigned int indx;
+ /* The pmisc records for the class. */
+ struct ieee_buflist pmiscbuf;
+ /* The number of pmisc records. */
+ unsigned int pmisccount;
+ /* The name of the class holding the virtual table, if not this
+ class. */
+ const char *vclass;
+ /* Whether this class holds its own virtual table. */
+ boolean ownvptr;
+ /* The largest virtual table offset seen so far. */
+ bfd_vma voffset;
+ /* The current method. */
+ const char *method;
+ /* Additional pmisc records used to record fields of reference type. */
+ struct ieee_buflist refs;
+};
+
+/* This is how we store types for the writing routines. Most types
+ are simply represented by a type index. */
+
+struct ieee_write_type
+{
+ /* Type index. */
+ unsigned int indx;
+ /* The size of the type, if known. */
+ unsigned int size;
+ /* The name of the type, if any. */
+ const char *name;
+ /* If this is a function or method type, we build the type here, and
+ only add it to the output buffers if we need it. */
+ struct ieee_buflist fndef;
+ /* If this is a struct, this is where the struct definition is
+ built. */
+ struct ieee_buflist strdef;
+ /* If this is a class, this is where the class information is built. */
+ struct ieee_type_class *classdef;
+ /* Whether the type is unsigned. */
+ unsigned int unsignedp : 1;
+ /* Whether this is a reference type. */
+ unsigned int referencep : 1;
+ /* Whether this is in the local type block. */
+ unsigned int localp : 1;
+ /* Whether this is a duplicate struct definition which we are
+ ignoring. */
+ unsigned int ignorep : 1;
+};
+
+/* This is the type stack used by the debug writing routines. FIXME:
+ We could generate more efficient output if we remembered when we
+ have output a particular type before. */
+
+struct ieee_type_stack
+{
+ /* Next entry on stack. */
+ struct ieee_type_stack *next;
+ /* Type information. */
+ struct ieee_write_type type;
+};
+
+/* This is a list of associations between a name and some types.
+ These are used for typedefs and tags. */
+
+struct ieee_name_type
+{
+ /* Next type for this name. */
+ struct ieee_name_type *next;
+ /* ID number. For a typedef, this is the index of the type to which
+ this name is typedefed. */
+ unsigned int id;
+ /* Type. */
+ struct ieee_write_type type;
+ /* If this is a tag which has not yet been defined, this is the
+ kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */
+ enum debug_type_kind kind;
+};
+
+/* We use a hash table to associate names and types. */
+
+struct ieee_name_type_hash_table
+{
+ struct bfd_hash_table root;
+};
+
+struct ieee_name_type_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Information for this name. */
+ struct ieee_name_type *types;
+};
+
+/* This is a list of enums. */
+
+struct ieee_defined_enum
+{
+ /* Next enum. */
+ struct ieee_defined_enum *next;
+ /* Type index. */
+ unsigned int indx;
+ /* Whether this enum has been defined. */
+ boolean defined;
+ /* Tag. */
+ const char *tag;
+ /* Names. */
+ const char **names;
+ /* Values. */
+ bfd_signed_vma *vals;
+};
+
+/* We keep a list of modified versions of types, so that we don't
+ output them more than once. */
+
+struct ieee_modified_type
+{
+ /* Pointer to this type. */
+ unsigned int pointer;
+ /* Function with unknown arguments returning this type. */
+ unsigned int function;
+ /* Const version of this type. */
+ unsigned int const_qualified;
+ /* Volatile version of this type. */
+ unsigned int volatile_qualified;
+ /* List of arrays of this type of various bounds. */
+ struct ieee_modified_array_type *arrays;
+};
+
+/* A list of arrays bounds. */
+
+struct ieee_modified_array_type
+{
+ /* Next array bounds. */
+ struct ieee_modified_array_type *next;
+ /* Type index with these bounds. */
+ unsigned int indx;
+ /* Low bound. */
+ bfd_signed_vma low;
+ /* High bound. */
+ bfd_signed_vma high;
+};
+
+/* This is a list of pending function parameter information. We don't
+ output them until we see the first block. */
+
+struct ieee_pending_parm
+{
+ /* Next pending parameter. */
+ struct ieee_pending_parm *next;
+ /* Name. */
+ const char *name;
+ /* Type index. */
+ unsigned int type;
+ /* Whether the type is a reference. */
+ boolean referencep;
+ /* Kind. */
+ enum debug_parm_kind kind;
+ /* Value. */
+ bfd_vma val;
+};
+
+/* This is the handle passed down by debug_write. */
+
+struct ieee_handle
+{
+ /* BFD we are writing to. */
+ bfd *abfd;
+ /* Whether we got an error in a subroutine called via traverse or
+ map_over_sections. */
+ boolean error;
+ /* Current data buffer list. */
+ struct ieee_buflist *current;
+ /* Current data buffer. */
+ struct ieee_buf *curbuf;
+ /* Filename of current compilation unit. */
+ const char *filename;
+ /* Module name of current compilation unit. */
+ const char *modname;
+ /* List of buffer for global types. */
+ struct ieee_buflist global_types;
+ /* List of finished data buffers. */
+ struct ieee_buflist data;
+ /* List of buffers for typedefs in the current compilation unit. */
+ struct ieee_buflist types;
+ /* List of buffers for variables and functions in the current
+ compilation unit. */
+ struct ieee_buflist vars;
+ /* List of buffers for C++ class definitions in the current
+ compilation unit. */
+ struct ieee_buflist cxx;
+ /* List of buffers for line numbers in the current compilation unit. */
+ struct ieee_buflist linenos;
+ /* Ranges for the current compilation unit. */
+ struct ieee_range *ranges;
+ /* Ranges for all debugging information. */
+ struct ieee_range *global_ranges;
+ /* Nested pending ranges. */
+ struct ieee_range *pending_ranges;
+ /* Type stack. */
+ struct ieee_type_stack *type_stack;
+ /* Next unallocated type index. */
+ unsigned int type_indx;
+ /* Next unallocated name index. */
+ unsigned int name_indx;
+ /* Typedefs. */
+ struct ieee_name_type_hash_table typedefs;
+ /* Tags. */
+ struct ieee_name_type_hash_table tags;
+ /* Enums. */
+ struct ieee_defined_enum *enums;
+ /* Modified versions of types. */
+ struct ieee_modified_type *modified;
+ /* Number of entries allocated in modified. */
+ unsigned int modified_alloc;
+ /* 4 byte complex type. */
+ unsigned int complex_float_index;
+ /* 8 byte complex type. */
+ unsigned int complex_double_index;
+ /* The depth of block nesting. This is 0 outside a function, and 1
+ just after start_function is called. */
+ unsigned int block_depth;
+ /* The name of the current function. */
+ const char *fnname;
+ /* List of buffers for the type of the function we are currently
+ writing out. */
+ struct ieee_buflist fntype;
+ /* List of buffers for the parameters of the function we are
+ currently writing out. */
+ struct ieee_buflist fnargs;
+ /* Number of arguments written to fnargs. */
+ unsigned int fnargcount;
+ /* Pending function parameters. */
+ struct ieee_pending_parm *pending_parms;
+ /* Current line number filename. */
+ const char *lineno_filename;
+ /* Line number name index. */
+ unsigned int lineno_name_indx;
+ /* Filename of pending line number. */
+ const char *pending_lineno_filename;
+ /* Pending line number. */
+ unsigned long pending_lineno;
+ /* Address of pending line number. */
+ bfd_vma pending_lineno_addr;
+ /* Highest address seen at end of procedure. */
+ bfd_vma highaddr;
+};
+
+static boolean ieee_init_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *));
+static boolean ieee_change_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *));
+static boolean ieee_append_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *,
+ struct ieee_buflist *));
+static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int));
+static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int));
+static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *));
+static boolean ieee_write_asn
+ PARAMS ((struct ieee_handle *, unsigned int, bfd_vma));
+static boolean ieee_write_atn65
+ PARAMS ((struct ieee_handle *, unsigned int, const char *));
+static boolean ieee_push_type
+ PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean,
+ boolean));
+static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *));
+static void ieee_pop_unused_type PARAMS ((struct ieee_handle *));
+static unsigned int ieee_pop_type_used
+ PARAMS ((struct ieee_handle *, boolean));
+static boolean ieee_add_range
+ PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma));
+static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_define_type
+ PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean));
+static boolean ieee_define_named_type
+ PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int,
+ boolean, boolean, struct ieee_buflist *));
+static struct ieee_modified_type *ieee_get_modified_info
+ PARAMS ((struct ieee_handle *, unsigned int));
+static struct bfd_hash_entry *ieee_name_type_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean ieee_write_undefined_tag
+ PARAMS ((struct ieee_name_type_hash_entry *, PTR));
+static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *));
+static void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR));
+static boolean ieee_add_bb11
+ PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma));
+static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
+static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility));
+static boolean ieee_class_method_var
+ PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean,
+ boolean, boolean, bfd_vma, boolean));
+
+static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
+static boolean ieee_start_source PARAMS ((PTR, const char *));
+static boolean ieee_empty_type PARAMS ((PTR));
+static boolean ieee_void_type PARAMS ((PTR));
+static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
+static boolean ieee_float_type PARAMS ((PTR, unsigned int));
+static boolean ieee_complex_type PARAMS ((PTR, unsigned int));
+static boolean ieee_bool_type PARAMS ((PTR, unsigned int));
+static boolean ieee_enum_type
+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
+static boolean ieee_pointer_type PARAMS ((PTR));
+static boolean ieee_function_type PARAMS ((PTR, int, boolean));
+static boolean ieee_reference_type PARAMS ((PTR));
+static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+static boolean ieee_array_type
+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
+static boolean ieee_set_type PARAMS ((PTR, boolean));
+static boolean ieee_offset_type PARAMS ((PTR));
+static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean));
+static boolean ieee_const_type PARAMS ((PTR));
+static boolean ieee_volatile_type PARAMS ((PTR));
+static boolean ieee_start_struct_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
+static boolean ieee_struct_field
+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
+static boolean ieee_end_struct_type PARAMS ((PTR));
+static boolean ieee_start_class_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
+ boolean));
+static boolean ieee_class_static_member
+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
+static boolean ieee_class_baseclass
+ PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
+static boolean ieee_class_start_method PARAMS ((PTR, const char *));
+static boolean ieee_class_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
+ bfd_vma, boolean));
+static boolean ieee_class_static_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
+static boolean ieee_class_end_method PARAMS ((PTR));
+static boolean ieee_end_class_type PARAMS ((PTR));
+static boolean ieee_typedef_type PARAMS ((PTR, const char *));
+static boolean ieee_tag_type
+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
+static boolean ieee_typdef PARAMS ((PTR, const char *));
+static boolean ieee_tag PARAMS ((PTR, const char *));
+static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean ieee_float_constant PARAMS ((PTR, const char *, double));
+static boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean ieee_variable
+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
+static boolean ieee_start_function PARAMS ((PTR, const char *, boolean));
+static boolean ieee_function_parameter
+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
+static boolean ieee_start_block PARAMS ((PTR, bfd_vma));
+static boolean ieee_end_block PARAMS ((PTR, bfd_vma));
+static boolean ieee_end_function PARAMS ((PTR));
+static boolean ieee_lineno
+ PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+
+static const struct debug_write_fns ieee_fns =
+{
+ ieee_start_compilation_unit,
+ ieee_start_source,
+ ieee_empty_type,
+ ieee_void_type,
+ ieee_int_type,
+ ieee_float_type,
+ ieee_complex_type,
+ ieee_bool_type,
+ ieee_enum_type,
+ ieee_pointer_type,
+ ieee_function_type,
+ ieee_reference_type,
+ ieee_range_type,
+ ieee_array_type,
+ ieee_set_type,
+ ieee_offset_type,
+ ieee_method_type,
+ ieee_const_type,
+ ieee_volatile_type,
+ ieee_start_struct_type,
+ ieee_struct_field,
+ ieee_end_struct_type,
+ ieee_start_class_type,
+ ieee_class_static_member,
+ ieee_class_baseclass,
+ ieee_class_start_method,
+ ieee_class_method_variant,
+ ieee_class_static_method_variant,
+ ieee_class_end_method,
+ ieee_end_class_type,
+ ieee_typedef_type,
+ ieee_tag_type,
+ ieee_typdef,
+ ieee_tag,
+ ieee_int_constant,
+ ieee_float_constant,
+ ieee_typed_constant,
+ ieee_variable,
+ ieee_start_function,
+ ieee_function_parameter,
+ ieee_start_block,
+ ieee_end_block,
+ ieee_end_function,
+ ieee_lineno
+};
+
+/* Initialize a buffer to be empty. */
+
+/*ARGSUSED*/
+static boolean
+ieee_init_buffer (info, buflist)
+ struct ieee_handle *info;
+ struct ieee_buflist *buflist;
+{
+ buflist->head = NULL;
+ buflist->tail = NULL;
+ return true;
+}
+
+/* See whether a buffer list has any data. */
+
+#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL)
+
+/* Change the current buffer to a specified buffer chain. */
+
+static boolean
+ieee_change_buffer (info, buflist)
+ struct ieee_handle *info;
+ struct ieee_buflist *buflist;
+{
+ if (buflist->head == NULL)
+ {
+ struct ieee_buf *buf;
+
+ buf = (struct ieee_buf *) xmalloc (sizeof *buf);
+ buf->next = NULL;
+ buf->c = 0;
+ buflist->head = buf;
+ buflist->tail = buf;
+ }
+
+ info->current = buflist;
+ info->curbuf = buflist->tail;
+
+ return true;
+}
+
+/* Append a buffer chain. */
+
+/*ARGSUSED*/
+static boolean
+ieee_append_buffer (info, mainbuf, newbuf)
+ struct ieee_handle *info;
+ struct ieee_buflist *mainbuf;
+ struct ieee_buflist *newbuf;
+{
+ if (newbuf->head != NULL)
+ {
+ if (mainbuf->head == NULL)
+ mainbuf->head = newbuf->head;
+ else
+ mainbuf->tail->next = newbuf->head;
+ mainbuf->tail = newbuf->tail;
+ }
+ return true;
+}
+
+/* Write a byte into the buffer. We use a macro for speed and a
+ function for the complex cases. */
+
+#define ieee_write_byte(info, b) \
+ ((info)->curbuf->c < IEEE_BUFSIZE \
+ ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \
+ : ieee_real_write_byte ((info), (b)))
+
+static boolean
+ieee_real_write_byte (info, b)
+ struct ieee_handle *info;
+ int b;
+{
+ if (info->curbuf->c >= IEEE_BUFSIZE)
+ {
+ struct ieee_buf *n;
+
+ n = (struct ieee_buf *) xmalloc (sizeof *n);
+ n->next = NULL;
+ n->c = 0;
+ if (info->current->head == NULL)
+ info->current->head = n;
+ else
+ info->current->tail->next = n;
+ info->current->tail = n;
+ info->curbuf = n;
+ }
+
+ info->curbuf->buf[info->curbuf->c] = b;
+ ++info->curbuf->c;
+
+ return true;
+}
+
+/* Write out two bytes. */
+
+static boolean
+ieee_write_2bytes (info, i)
+ struct ieee_handle *info;
+ int i;
+{
+ return (ieee_write_byte (info, i >> 8)
+ && ieee_write_byte (info, i & 0xff));
+}
+
+/* Write out an integer. */
+
+static boolean
+ieee_write_number (info, v)
+ struct ieee_handle *info;
+ bfd_vma v;
+{
+ bfd_vma t;
+ bfd_byte ab[20];
+ bfd_byte *p;
+ unsigned int c;
+
+ if (v <= (bfd_vma) ieee_number_end_enum)
+ return ieee_write_byte (info, (int) v);
+
+ t = v;
+ p = ab + sizeof ab;
+ while (t != 0)
+ {
+ *--p = t & 0xff;
+ t >>= 8;
+ }
+ c = (ab + 20) - p;
+
+ if (c > (unsigned int) (ieee_number_repeat_end_enum
+ - ieee_number_repeat_start_enum))
+ {
+ fprintf (stderr, "IEEE numeric overflow: 0x");
+ fprintf_vma (stderr, v);
+ fprintf (stderr, "\n");
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c))
+ return false;
+ for (; c > 0; --c, ++p)
+ {
+ if (! ieee_write_byte (info, *p))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out a string. */
+
+static boolean
+ieee_write_id (info, s)
+ struct ieee_handle *info;
+ const char *s;
+{
+ unsigned int len;
+
+ len = strlen (s);
+ if (len <= 0x7f)
+ {
+ if (! ieee_write_byte (info, len))
+ return false;
+ }
+ else if (len <= 0xff)
+ {
+ if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum)
+ || ! ieee_write_byte (info, len))
+ return false;
+ }
+ else if (len <= 0xffff)
+ {
+ if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum)
+ || ! ieee_write_2bytes (info, len))
+ return false;
+ }
+ else
+ {
+ fprintf (stderr, "IEEE string length overflow: %u\n", len);
+ return false;
+ }
+
+ for (; *s != '\0'; s++)
+ if (! ieee_write_byte (info, *s))
+ return false;
+
+ return true;
+}
+
+/* Write out an ASN record. */
+
+static boolean
+ieee_write_asn (info, indx, val)
+ struct ieee_handle *info;
+ unsigned int indx;
+ bfd_vma val;
+{
+ return (ieee_write_2bytes (info, (int) ieee_asn_record_enum)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, val));
+}
+
+/* Write out an ATN65 record. */
+
+static boolean
+ieee_write_atn65 (info, indx, s)
+ struct ieee_handle *info;
+ unsigned int indx;
+ const char *s;
+{
+ return (ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, 0)
+ && ieee_write_number (info, 65)
+ && ieee_write_id (info, s));
+}
+
+/* Push a type index onto the type stack. */
+
+static boolean
+ieee_push_type (info, indx, size, unsignedp, localp)
+ struct ieee_handle *info;
+ unsigned int indx;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+{
+ struct ieee_type_stack *ts;
+
+ ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
+ memset (ts, 0, sizeof *ts);
+
+ ts->type.indx = indx;
+ ts->type.size = size;
+ ts->type.unsignedp = unsignedp;
+ ts->type.localp = localp;
+
+ ts->next = info->type_stack;
+ info->type_stack = ts;
+
+ return true;
+}
+
+/* Pop a type index off the type stack. */
+
+static unsigned int
+ieee_pop_type (info)
+ struct ieee_handle *info;
+{
+ return ieee_pop_type_used (info, true);
+}
+
+/* Pop an unused type index off the type stack. */
+
+static void
+ieee_pop_unused_type (info)
+ struct ieee_handle *info;
+{
+ (void) ieee_pop_type_used (info, false);
+}
+
+/* Pop a used or unused type index off the type stack. */
+
+static unsigned int
+ieee_pop_type_used (info, used)
+ struct ieee_handle *info;
+ boolean used;
+{
+ struct ieee_type_stack *ts;
+ unsigned int ret;
+
+ ts = info->type_stack;
+ assert (ts != NULL);
+
+ /* If this is a function type, and we need it, we need to append the
+ actual definition to the typedef block now. */
+ if (used && ! ieee_buffer_emptyp (&ts->type.fndef))
+ {
+ struct ieee_buflist *buflist;
+
+ if (ts->type.localp)
+ {
+ /* Make sure we have started the types block. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ buflist = &info->types;
+ }
+ else
+ {
+ /* Make sure we started the global type block. */
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ buflist = &info->global_types;
+ }
+
+ if (! ieee_append_buffer (info, buflist, &ts->type.fndef))
+ return false;
+ }
+
+ ret = ts->type.indx;
+ info->type_stack = ts->next;
+ free (ts);
+ return ret;
+}
+
+/* Add a range of bytes included in the current compilation unit. */
+
+static boolean
+ieee_add_range (info, global, low, high)
+ struct ieee_handle *info;
+ boolean global;
+ bfd_vma low;
+ bfd_vma high;
+{
+ struct ieee_range **plist, *r, **pr;
+
+ if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high)
+ return true;
+
+ if (global)
+ plist = &info->global_ranges;
+ else
+ plist = &info->ranges;
+
+ for (r = *plist; r != NULL; r = r->next)
+ {
+ if (high >= r->low && low <= r->high)
+ {
+ /* The new range overlaps r. */
+ if (low < r->low)
+ r->low = low;
+ if (high > r->high)
+ r->high = high;
+ pr = &r->next;
+ while (*pr != NULL && (*pr)->low <= r->high)
+ {
+ struct ieee_range *n;
+
+ if ((*pr)->high > r->high)
+ r->high = (*pr)->high;
+ n = (*pr)->next;
+ free (*pr);
+ *pr = n;
+ }
+ return true;
+ }
+ }
+
+ r = (struct ieee_range *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+
+ r->low = low;
+ r->high = high;
+
+ /* Store the ranges sorted by address. */
+ for (pr = plist; *pr != NULL; pr = &(*pr)->next)
+ if ((*pr)->low > high)
+ break;
+ r->next = *pr;
+ *pr = r;
+
+ return true;
+}
+
+/* Start a new range for which we only have the low address. */
+
+static boolean
+ieee_start_range (info, low)
+ struct ieee_handle *info;
+ bfd_vma low;
+{
+ struct ieee_range *r;
+
+ r = (struct ieee_range *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+ r->low = low;
+ r->next = info->pending_ranges;
+ info->pending_ranges = r;
+ return true;
+}
+
+/* Finish a range started by ieee_start_range. */
+
+static boolean
+ieee_end_range (info, high)
+ struct ieee_handle *info;
+ bfd_vma high;
+{
+ struct ieee_range *r;
+ bfd_vma low;
+
+ assert (info->pending_ranges != NULL);
+ r = info->pending_ranges;
+ low = r->low;
+ info->pending_ranges = r->next;
+ free (r);
+ return ieee_add_range (info, false, low, high);
+}
+
+/* Start defining a type. */
+
+static boolean
+ieee_define_type (info, size, unsignedp, localp)
+ struct ieee_handle *info;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+{
+ return ieee_define_named_type (info, (const char *) NULL,
+ (unsigned int) -1, size, unsignedp,
+ localp, (struct ieee_buflist *) NULL);
+}
+
+/* Start defining a named type. */
+
+static boolean
+ieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist)
+ struct ieee_handle *info;
+ const char *name;
+ unsigned int indx;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+ struct ieee_buflist *buflist;
+{
+ unsigned int type_indx;
+ unsigned int name_indx;
+
+ if (indx != (unsigned int) -1)
+ type_indx = indx;
+ else
+ {
+ type_indx = info->type_indx;
+ ++info->type_indx;
+ }
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+
+ if (name == NULL)
+ name = "";
+
+ /* If we were given a buffer, use it; otherwise, use either the
+ local or the global type information, and make sure that the type
+ block is started. */
+ if (buflist != NULL)
+ {
+ if (! ieee_change_buffer (info, buflist))
+ return false;
+ }
+ else if (localp)
+ {
+ if (! ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types))
+ return false;
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ }
+ else
+ {
+ if (! ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types))
+ return false;
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ }
+
+ /* Push the new type on the type stack, write out an NN record, and
+ write out the start of a TY record. The caller will then finish
+ the TY record. */
+ if (! ieee_push_type (info, type_indx, size, unsignedp, localp))
+ return false;
+
+ return (ieee_write_byte (info, (int) ieee_nn_record)
+ && ieee_write_number (info, name_indx)
+ && ieee_write_id (info, name)
+ && ieee_write_byte (info, (int) ieee_ty_record_enum)
+ && ieee_write_number (info, type_indx)
+ && ieee_write_byte (info, 0xce)
+ && ieee_write_number (info, name_indx));
+}
+
+/* Get an entry to the list of modified versions of a type. */
+
+static struct ieee_modified_type *
+ieee_get_modified_info (info, indx)
+ struct ieee_handle *info;
+ unsigned int indx;
+{
+ if (indx >= info->modified_alloc)
+ {
+ unsigned int nalloc;
+
+ nalloc = info->modified_alloc;
+ if (nalloc == 0)
+ nalloc = 16;
+ while (indx >= nalloc)
+ nalloc *= 2;
+ info->modified = ((struct ieee_modified_type *)
+ xrealloc (info->modified,
+ nalloc * sizeof *info->modified));
+ memset (info->modified + info->modified_alloc, 0,
+ (nalloc - info->modified_alloc) * sizeof *info->modified);
+ info->modified_alloc = nalloc;
+ }
+
+ return info->modified + indx;
+}
+
+/* Routines for the hash table mapping names to types. */
+
+/* Initialize an entry in the hash table. */
+
+static struct bfd_hash_entry *
+ieee_name_type_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct ieee_name_type_hash_entry *ret =
+ (struct ieee_name_type_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct ieee_name_type_hash_entry *)
+ bfd_hash_allocate (table, sizeof *ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct ieee_name_type_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->types = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Look up an entry in the hash table. */
+
+#define ieee_name_type_hash_lookup(table, string, create, copy) \
+ ((struct ieee_name_type_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* Traverse the hash table. */
+
+#define ieee_name_type_hash_traverse(table, func, info) \
+ (bfd_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* The general routine to write out IEEE debugging information. */
+
+boolean
+write_ieee_debugging_info (abfd, dhandle)
+ bfd *abfd;
+ PTR dhandle;
+{
+ struct ieee_handle info;
+ asection *s;
+ const char *err;
+ struct ieee_buf *b;
+
+ memset (&info, 0, sizeof info);
+ info.abfd = abfd;
+ info.type_indx = 256;
+ info.name_indx = 32;
+
+ if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc)
+ || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc))
+ return false;
+
+ if (! ieee_init_buffer (&info, &info.global_types)
+ || ! ieee_init_buffer (&info, &info.data)
+ || ! ieee_init_buffer (&info, &info.types)
+ || ! ieee_init_buffer (&info, &info.vars)
+ || ! ieee_init_buffer (&info, &info.cxx)
+ || ! ieee_init_buffer (&info, &info.linenos)
+ || ! ieee_init_buffer (&info, &info.fntype)
+ || ! ieee_init_buffer (&info, &info.fnargs))
+ return false;
+
+ if (! debug_write (dhandle, &ieee_fns, (PTR) &info))
+ return false;
+
+ if (info.filename != NULL)
+ {
+ if (! ieee_finish_compilation_unit (&info))
+ return false;
+ }
+
+ /* Put any undefined tags in the global typedef information. */
+ info.error = false;
+ ieee_name_type_hash_traverse (&info.tags,
+ ieee_write_undefined_tag,
+ (PTR) &info);
+ if (info.error)
+ return false;
+
+ /* Prepend the global typedef information to the other data. */
+ if (! ieee_buffer_emptyp (&info.global_types))
+ {
+ /* The HP debugger seems to have a bug in which it ignores the
+ last entry in the global types, so we add a dummy entry. */
+ if (! ieee_change_buffer (&info, &info.global_types)
+ || ! ieee_write_byte (&info, (int) ieee_nn_record)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_id (&info, "")
+ || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (&info, info.type_indx)
+ || ! ieee_write_byte (&info, 0xce)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_number (&info, 'P')
+ || ! ieee_write_number (&info, (int) builtin_void + 32)
+ || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
+ return false;
+
+ if (! ieee_append_buffer (&info, &info.global_types, &info.data))
+ return false;
+ info.data = info.global_types;
+ }
+
+ /* Make sure that we have declare BB11 blocks for each range in the
+ file. They are added to info->vars. */
+ info.error = false;
+ if (! ieee_init_buffer (&info, &info.vars))
+ return false;
+ bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info);
+ if (info.error)
+ return false;
+ if (! ieee_buffer_emptyp (&info.vars))
+ {
+ if (! ieee_change_buffer (&info, &info.vars)
+ || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
+ return false;
+
+ if (! ieee_append_buffer (&info, &info.data, &info.vars))
+ return false;
+ }
+
+ /* Now all the data is in info.data. Write it out to the BFD. We
+ normally would need to worry about whether all the other sections
+ are set up yet, but the IEEE backend will handle this particular
+ case correctly regardless. */
+ if (ieee_buffer_emptyp (&info.data))
+ {
+ /* There is no debugging information. */
+ return true;
+ }
+ err = NULL;
+ s = bfd_make_section (abfd, ".debug");
+ if (s == NULL)
+ err = "bfd_make_section";
+ if (err == NULL)
+ {
+ if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS))
+ err = "bfd_set_section_flags";
+ }
+ if (err == NULL)
+ {
+ bfd_size_type size;
+
+ size = 0;
+ for (b = info.data.head; b != NULL; b = b->next)
+ size += b->c;
+ if (! bfd_set_section_size (abfd, s, size))
+ err = "bfd_set_section_size";
+ }
+ if (err == NULL)
+ {
+ file_ptr offset;
+
+ offset = 0;
+ for (b = info.data.head; b != NULL; b = b->next)
+ {
+ if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c))
+ {
+ err = "bfd_set_section_contents";
+ break;
+ }
+ offset += b->c;
+ }
+ }
+
+ if (err != NULL)
+ {
+ fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ bfd_hash_table_free (&info.typedefs.root);
+ bfd_hash_table_free (&info.tags.root);
+
+ return true;
+}
+
+/* Write out information for an undefined tag. This is called via
+ ieee_name_type_hash_traverse. */
+
+static boolean
+ieee_write_undefined_tag (h, p)
+ struct ieee_name_type_hash_entry *h;
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_name_type *nt;
+
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ unsigned int name_indx;
+ char code;
+
+ if (nt->kind == DEBUG_KIND_ILLEGAL)
+ continue;
+
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->global_types))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_id (info, nt->type.name)
+ || ! ieee_write_byte (info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (info, nt->type.indx)
+ || ! ieee_write_byte (info, 0xce)
+ || ! ieee_write_number (info, name_indx))
+ {
+ info->error = true;
+ return false;
+ }
+
+ switch (nt->kind)
+ {
+ default:
+ abort ();
+ info->error = true;
+ return false;
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_CLASS:
+ code = 'S';
+ break;
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_UNION_CLASS:
+ code = 'U';
+ break;
+ case DEBUG_KIND_ENUM:
+ code = 'E';
+ break;
+ }
+ if (! ieee_write_number (info, code)
+ || ! ieee_write_number (info, 0))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Start writing out information for a compilation unit. */
+
+static boolean
+ieee_start_compilation_unit (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *modname;
+ char *c, *s;
+ unsigned int nindx;
+
+ if (info->filename != NULL)
+ {
+ if (! ieee_finish_compilation_unit (info))
+ return false;
+ }
+
+ info->filename = filename;
+ modname = strrchr (filename, '/');
+ if (modname != NULL)
+ ++modname;
+ else
+ {
+ modname = strrchr (filename, '\\');
+ if (modname != NULL)
+ ++modname;
+ else
+ modname = filename;
+ }
+ c = xstrdup (modname);
+ s = strrchr (c, '.');
+ if (s != NULL)
+ *s = '\0';
+ info->modname = c;
+
+ if (! ieee_init_buffer (info, &info->types)
+ || ! ieee_init_buffer (info, &info->vars)
+ || ! ieee_init_buffer (info, &info->cxx)
+ || ! ieee_init_buffer (info, &info->linenos))
+ return false;
+ info->ranges = NULL;
+
+ /* Always include a BB1 and a BB3 block. That is what the output of
+ the MRI linker seems to look like. */
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 3)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+
+ return true;
+}
+
+/* Finish up a compilation unit. */
+
+static boolean
+ieee_finish_compilation_unit (info)
+ struct ieee_handle *info;
+{
+ struct ieee_range *r;
+
+ if (! ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+
+ if (! ieee_buffer_emptyp (&info->cxx))
+ {
+ /* Append any C++ information to the global function and
+ variable information. */
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ /* We put the pmisc records in a dummy procedure, just as the
+ MRI compiler does. */
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 6)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "__XRYCPP")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, info->highaddr - 1)
+ || ! ieee_append_buffer (info, &info->vars, &info->cxx)
+ || ! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, info->highaddr - 1))
+ return false;
+ }
+
+ if (! ieee_buffer_emptyp (&info->vars))
+ {
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+
+ if (info->pending_lineno_filename != NULL)
+ {
+ /* Force out the pending line number. */
+ if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1))
+ return false;
+ }
+ if (! ieee_buffer_emptyp (&info->linenos))
+ {
+ if (! ieee_change_buffer (info, &info->linenos)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ if (strcmp (info->filename, info->lineno_filename) != 0)
+ {
+ /* We were not in the main file. We just closed the
+ included line number block, and now we must close the
+ main line number block. */
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+ }
+
+ if (! ieee_append_buffer (info, &info->data, &info->types)
+ || ! ieee_append_buffer (info, &info->data, &info->vars)
+ || ! ieee_append_buffer (info, &info->data, &info->linenos))
+ return false;
+
+ /* Build BB10/BB11 blocks based on the ranges we recorded. */
+ if (! ieee_change_buffer (info, &info->data))
+ return false;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 10)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "GNU objcopy"))
+ return false;
+
+ for (r = info->ranges; r != NULL; r = r->next)
+ {
+ bfd_vma low, high;
+ asection *s;
+ int kind;
+
+ low = r->low;
+ high = r->high;
+
+ /* Find the section corresponding to this range. */
+ for (s = info->abfd->sections; s != NULL; s = s->next)
+ {
+ if (bfd_get_section_vma (info->abfd, s) <= low
+ && high <= (bfd_get_section_vma (info->abfd, s)
+ + bfd_section_size (info->abfd, s)))
+ break;
+ }
+
+ if (s == NULL)
+ {
+ /* Just ignore this range. */
+ continue;
+ }
+
+ /* Coalesce ranges if it seems reasonable. */
+ while (r->next != NULL
+ && high + 0x1000 >= r->next->low
+ && (r->next->high
+ <= (bfd_get_section_vma (info->abfd, s)
+ + bfd_section_size (info->abfd, s))))
+ {
+ r = r->next;
+ high = r->high;
+ }
+
+ if ((s->flags & SEC_CODE) != 0)
+ kind = 1;
+ else if ((s->flags & SEC_READONLY) != 0)
+ kind = 3;
+ else
+ kind = 2;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 11)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, kind)
+ || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE)
+ || ! ieee_write_number (info, low)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, high - low))
+ return false;
+
+ /* Add this range to the list of global ranges. */
+ if (! ieee_add_range (info, true, low, high))
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+
+ return true;
+}
+
+/* Add BB11 blocks describing each range that we have not already
+ described. */
+
+static void
+ieee_add_bb11_blocks (abfd, sec, data)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+{
+ struct ieee_handle *info = (struct ieee_handle *) data;
+ bfd_vma low, high;
+ struct ieee_range *r;
+
+ low = bfd_get_section_vma (abfd, sec);
+ high = low + bfd_section_size (abfd, sec);
+
+ /* Find the first range at or after this section. The ranges are
+ sorted by address. */
+ for (r = info->global_ranges; r != NULL; r = r->next)
+ if (r->high > low)
+ break;
+
+ while (low < high)
+ {
+ if (r == NULL || r->low >= high)
+ {
+ if (! ieee_add_bb11 (info, sec, low, high))
+ info->error = true;
+ return;
+ }
+
+ if (low < r->low
+ && r->low - low > 0x100)
+ {
+ if (! ieee_add_bb11 (info, sec, low, r->low))
+ {
+ info->error = true;
+ return;
+ }
+ }
+ low = r->high;
+
+ r = r->next;
+ }
+}
+
+/* Add a single BB11 block for a range. We add it to info->vars. */
+
+static boolean
+ieee_add_bb11 (info, sec, low, high)
+ struct ieee_handle *info;
+ asection *sec;
+ bfd_vma low;
+ bfd_vma high;
+{
+ int kind;
+
+ if (! ieee_buffer_emptyp (&info->vars))
+ {
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+ }
+ else
+ {
+ const char *filename, *modname;
+ char *c, *s;
+
+ /* Start the enclosing BB10 block. */
+ filename = bfd_get_filename (info->abfd);
+ modname = strrchr (filename, '/');
+ if (modname != NULL)
+ ++modname;
+ else
+ {
+ modname = strrchr (filename, '\\');
+ if (modname != NULL)
+ ++modname;
+ else
+ modname = filename;
+ }
+ c = xstrdup (modname);
+ s = strrchr (c, '.');
+ if (s != NULL)
+ *s = '\0';
+
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 10)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, c)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "GNU objcopy"))
+ return false;
+
+ free (c);
+ }
+
+ if ((sec->flags & SEC_CODE) != 0)
+ kind = 1;
+ else if ((sec->flags & SEC_READONLY) != 0)
+ kind = 3;
+ else
+ kind = 2;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 11)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, kind)
+ || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE)
+ || ! ieee_write_number (info, low)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, high - low))
+ return false;
+
+ return true;
+}
+
+/* Start recording information from a particular source file. This is
+ used to record which file defined which types, variables, etc. It
+ is not used for line numbers, since the lineno entry point passes
+ down the file name anyhow. IEEE debugging information doesn't seem
+ to store this information anywhere. */
+
+/*ARGSUSED*/
+static boolean
+ieee_start_source (p, filename)
+ PTR p;
+ const char *filename;
+{
+ return true;
+}
+
+/* Make an empty type. */
+
+static boolean
+ieee_empty_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_push_type (info, (int) builtin_unknown, 0, false, false);
+}
+
+/* Make a void type. */
+
+static boolean
+ieee_void_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_push_type (info, (int) builtin_void, 0, false, false);
+}
+
+/* Make an integer type. */
+
+static boolean
+ieee_int_type (p, size, unsignedp)
+ PTR p;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int indx;
+
+ switch (size)
+ {
+ case 1:
+ indx = (int) builtin_signed_char;
+ break;
+ case 2:
+ indx = (int) builtin_signed_short_int;
+ break;
+ case 4:
+ indx = (int) builtin_signed_long;
+ break;
+ case 8:
+ indx = (int) builtin_signed_long_long;
+ break;
+ default:
+ fprintf (stderr, "IEEE unsupported integer type size %u\n", size);
+ return false;
+ }
+
+ if (unsignedp)
+ ++indx;
+
+ return ieee_push_type (info, indx, size, unsignedp, false);
+}
+
+/* Make a floating point type. */
+
+static boolean
+ieee_float_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int indx;
+
+ switch (size)
+ {
+ case 4:
+ indx = (int) builtin_float;
+ break;
+ case 8:
+ indx = (int) builtin_double;
+ break;
+ case 12:
+ /* FIXME: This size really depends upon the processor. */
+ indx = (int) builtin_long_double;
+ break;
+ case 16:
+ indx = (int) builtin_long_long_double;
+ break;
+ default:
+ fprintf (stderr, "IEEE unsupported float type size %u\n", size);
+ return false;
+ }
+
+ return ieee_push_type (info, indx, size, false, false);
+}
+
+/* Make a complex type. */
+
+static boolean
+ieee_complex_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ char code;
+
+ switch (size)
+ {
+ case 4:
+ if (info->complex_float_index != 0)
+ return ieee_push_type (info, info->complex_float_index, size * 2,
+ false, false);
+ code = 'c';
+ break;
+ case 12:
+ case 16:
+ /* These cases can be output by gcc -gstabs. Outputting the
+ wrong type is better than crashing. */
+ case 8:
+ if (info->complex_double_index != 0)
+ return ieee_push_type (info, info->complex_double_index, size * 2,
+ false, false);
+ code = 'd';
+ break;
+ default:
+ fprintf (stderr, "IEEE unsupported complex type size %u\n", size);
+ return false;
+ }
+
+ /* FIXME: I don't know what the string is for. */
+ if (! ieee_define_type (info, size * 2, false, false)
+ || ! ieee_write_number (info, code)
+ || ! ieee_write_id (info, ""))
+ return false;
+
+ if (size == 4)
+ info->complex_float_index = info->type_stack->type.indx;
+ else
+ info->complex_double_index = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a boolean type. IEEE doesn't support these, so we just make
+ an integer type instead. */
+
+static boolean
+ieee_bool_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ return ieee_int_type (p, size, true);
+}
+
+/* Make an enumeration. */
+
+static boolean
+ieee_enum_type (p, tag, names, vals)
+ PTR p;
+ const char *tag;
+ const char **names;
+ bfd_signed_vma *vals;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_defined_enum *e;
+ boolean localp, simple;
+ unsigned int indx;
+ int i = 0;
+
+ localp = false;
+ indx = (unsigned int) -1;
+ for (e = info->enums; e != NULL; e = e->next)
+ {
+ if (tag == NULL)
+ {
+ if (e->tag != NULL)
+ continue;
+ }
+ else
+ {
+ if (e->tag == NULL
+ || tag[0] != e->tag[0]
+ || strcmp (tag, e->tag) != 0)
+ continue;
+ }
+
+ if (! e->defined)
+ {
+ /* This enum tag has been seen but not defined. */
+ indx = e->indx;
+ break;
+ }
+
+ if (names != NULL && e->names != NULL)
+ {
+ for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
+ {
+ if (names[i][0] != e->names[i][0]
+ || vals[i] != e->vals[i]
+ || strcmp (names[i], e->names[i]) != 0)
+ break;
+ }
+ }
+
+ if ((names == NULL && e->names == NULL)
+ || (names != NULL
+ && e->names != NULL
+ && names[i] == NULL
+ && e->names[i] == NULL))
+ {
+ /* We've seen this enum before. */
+ return ieee_push_type (info, e->indx, 0, true, false);
+ }
+
+ if (tag != NULL)
+ {
+ /* We've already seen an enum of the same name, so we must make
+ sure to output this one locally. */
+ localp = true;
+ break;
+ }
+ }
+
+ /* If this is a simple enumeration, in which the values start at 0
+ and always increment by 1, we can use type E. Otherwise we must
+ use type N. */
+
+ simple = true;
+ if (names != NULL)
+ {
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (vals[i] != i)
+ {
+ simple = false;
+ break;
+ }
+ }
+ }
+
+ if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
+ (struct ieee_buflist *) NULL)
+ || ! ieee_write_number (info, simple ? 'E' : 'N'))
+ return false;
+ if (simple)
+ {
+ /* FIXME: This is supposed to be the enumeration size, but we
+ don't store that. */
+ if (! ieee_write_number (info, 4))
+ return false;
+ }
+ if (names != NULL)
+ {
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (! ieee_write_id (info, names[i]))
+ return false;
+ if (! simple)
+ {
+ if (! ieee_write_number (info, vals[i]))
+ return false;
+ }
+ }
+ }
+
+ if (! localp)
+ {
+ if (indx == (unsigned int) -1)
+ {
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+ e->indx = info->type_stack->type.indx;
+ e->tag = tag;
+
+ e->next = info->enums;
+ info->enums = e;
+ }
+
+ e->names = names;
+ e->vals = vals;
+ e->defined = true;
+ }
+
+ return true;
+}
+
+/* Make a pointer type. */
+
+static boolean
+ieee_pointer_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ /* A pointer to a simple builtin type can be obtained by adding 32.
+ FIXME: Will this be a short pointer, and will that matter? */
+ if (indx < 32)
+ return ieee_push_type (info, indx + 32, 0, true, false);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (p, indx);
+ if (m == NULL)
+ return false;
+
+ /* FIXME: The size should depend upon the architecture. */
+ if (m->pointer > 0)
+ return ieee_push_type (info, m->pointer, 4, true, false);
+ }
+
+ if (! ieee_define_type (info, 4, true, localp)
+ || ! ieee_write_number (info, 'P')
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->pointer = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a function type. This will be called for a method, but we
+ don't want to actually add it to the type table in that case. We
+ handle this by defining the type in a private buffer, and only
+ adding that buffer to the typedef block if we are going to use it. */
+
+static boolean
+ieee_function_type (p, argcount, varargs)
+ PTR p;
+ int argcount;
+ boolean varargs;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int *args = NULL;
+ int i;
+ unsigned int retindx;
+ struct ieee_buflist fndef;
+ struct ieee_modified_type *m;
+
+ localp = false;
+
+ if (argcount > 0)
+ {
+ args = (unsigned int *) xmalloc (argcount * sizeof *args);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (info->type_stack->type.localp)
+ localp = true;
+ args[i] = ieee_pop_type (info);
+ }
+ }
+ else if (argcount < 0)
+ varargs = false;
+
+ if (info->type_stack->type.localp)
+ localp = true;
+ retindx = ieee_pop_type (info);
+
+ m = NULL;
+ if (argcount < 0 && ! localp)
+ {
+ m = ieee_get_modified_info (p, retindx);
+ if (m == NULL)
+ return false;
+
+ if (m->function > 0)
+ return ieee_push_type (info, m->function, 0, true, false);
+ }
+
+ /* An attribute of 0x41 means that the frame and push mask are
+ unknown. */
+ if (! ieee_init_buffer (info, &fndef)
+ || ! ieee_define_named_type (info, (const char *) NULL,
+ (unsigned int) -1, 0, true, localp,
+ &fndef)
+ || ! ieee_write_number (info, 'x')
+ || ! ieee_write_number (info, 0x41)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, retindx)
+ || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
+ return false;
+ if (argcount > 0)
+ {
+ for (i = 0; i < argcount; i++)
+ if (! ieee_write_number (info, args[i]))
+ return false;
+ free (args);
+ }
+ if (varargs)
+ {
+ /* A varargs function is represented by writing out the last
+ argument as type void *, although this makes little sense. */
+ if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
+ return false;
+ }
+
+ if (! ieee_write_number (info, 0))
+ return false;
+
+ /* We wrote the information into fndef, in case we don't need it.
+ It will be appended to info->types by ieee_pop_type. */
+ info->type_stack->type.fndef = fndef;
+
+ if (m != NULL)
+ m->function = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a reference type. */
+
+static boolean
+ieee_reference_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* IEEE appears to record a normal pointer type, and then use a
+ pmisc record to indicate that it is really a reference. */
+
+ if (! ieee_pointer_type (p))
+ return false;
+ info->type_stack->type.referencep = true;
+ return true;
+}
+
+/* Make a range type. */
+
+static boolean
+ieee_range_type (p, low, high)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ ieee_pop_unused_type (info);
+ return (ieee_define_type (info, size, unsignedp, localp)
+ && ieee_write_number (info, 'R')
+ && ieee_write_number (info, (bfd_vma) low)
+ && ieee_write_number (info, (bfd_vma) high)
+ && ieee_write_number (info, unsignedp ? 0 : 1)
+ && ieee_write_number (info, size));
+}
+
+/* Make an array type. */
+
+/*ARGSUSED*/
+static boolean
+ieee_array_type (p, low, high, stringp)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+ boolean stringp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int eleindx;
+ boolean localp;
+ unsigned int size;
+ struct ieee_modified_type *m = NULL;
+ struct ieee_modified_array_type *a;
+
+ /* IEEE does not store the range, so we just ignore it. */
+ ieee_pop_unused_type (info);
+ localp = info->type_stack->type.localp;
+ size = info->type_stack->type.size;
+ eleindx = ieee_pop_type (info);
+
+ /* If we don't know the range, treat the size as exactly one
+ element. */
+ if (low < high)
+ size *= (high - low) + 1;
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, eleindx);
+ if (m == NULL)
+ return false;
+
+ for (a = m->arrays; a != NULL; a = a->next)
+ {
+ if (a->low == low && a->high == high)
+ return ieee_push_type (info, a->indx, size, false, false);
+ }
+ }
+
+ if (! ieee_define_type (info, size, false, localp)
+ || ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
+ || ! ieee_write_number (info, eleindx))
+ return false;
+ if (low != 0)
+ {
+ if (! ieee_write_number (info, low))
+ return false;
+ }
+
+ if (! ieee_write_number (info, high + 1))
+ return false;
+
+ if (! localp)
+ {
+ a = (struct ieee_modified_array_type *) xmalloc (sizeof *a);
+ memset (a, 0, sizeof *a);
+
+ a->indx = info->type_stack->type.indx;
+ a->low = low;
+ a->high = high;
+
+ a->next = m->arrays;
+ m->arrays = a;
+ }
+
+ return true;
+}
+
+/* Make a set type. */
+
+static boolean
+ieee_set_type (p, bitstringp)
+ PTR p;
+ boolean bitstringp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int eleindx;
+
+ localp = info->type_stack->type.localp;
+ eleindx = ieee_pop_type (info);
+
+ /* FIXME: We don't know the size, so we just use 4. */
+
+ return (ieee_define_type (info, 0, true, localp)
+ && ieee_write_number (info, 's')
+ && ieee_write_number (info, 4)
+ && ieee_write_number (info, eleindx));
+}
+
+/* Make an offset type. */
+
+static boolean
+ieee_offset_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int targetindx, baseindx;
+
+ targetindx = ieee_pop_type (info);
+ baseindx = ieee_pop_type (info);
+
+ /* FIXME: The MRI C++ compiler does not appear to generate any
+ useful type information about an offset type. It just records a
+ pointer to member as an integer. The MRI/HP IEEE spec does
+ describe a pmisc record which can be used for a pointer to
+ member. Unfortunately, it does not describe the target type,
+ which seems pretty important. I'm going to punt this for now. */
+
+ return ieee_int_type (p, 4, true);
+}
+
+/* Make a method type. */
+
+static boolean
+ieee_method_type (p, domain, argcount, varargs)
+ PTR p;
+ boolean domain;
+ int argcount;
+ boolean varargs;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
+ method, but the definition is incomplete. We just output an 'x'
+ type. */
+
+ if (domain)
+ ieee_pop_unused_type (info);
+
+ return ieee_function_type (p, argcount, varargs);
+}
+
+/* Make a const qualified type. */
+
+static boolean
+ieee_const_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, indx);
+ if (m == NULL)
+ return false;
+
+ if (m->const_qualified > 0)
+ return ieee_push_type (info, m->const_qualified, size, unsignedp,
+ false);
+ }
+
+ if (! ieee_define_type (info, size, unsignedp, localp)
+ || ! ieee_write_number (info, 'n')
+ || ! ieee_write_number (info, 1)
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->const_qualified = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a volatile qualified type. */
+
+static boolean
+ieee_volatile_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, indx);
+ if (m == NULL)
+ return false;
+
+ if (m->volatile_qualified > 0)
+ return ieee_push_type (info, m->volatile_qualified, size, unsignedp,
+ false);
+ }
+
+ if (! ieee_define_type (info, size, unsignedp, localp)
+ || ! ieee_write_number (info, 'n')
+ || ! ieee_write_number (info, 2)
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->volatile_qualified = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Convert an enum debug_visibility into a CXXFLAGS value. */
+
+static unsigned int
+ieee_vis_to_flags (visibility)
+ enum debug_visibility visibility;
+{
+ switch (visibility)
+ {
+ default:
+ abort ();
+ case DEBUG_VISIBILITY_PUBLIC:
+ return CXXFLAGS_VISIBILITY_PUBLIC;
+ case DEBUG_VISIBILITY_PRIVATE:
+ return CXXFLAGS_VISIBILITY_PRIVATE;
+ case DEBUG_VISIBILITY_PROTECTED:
+ return CXXFLAGS_VISIBILITY_PROTECTED;
+ }
+ /*NOTREACHED*/
+}
+
+/* Start defining a struct type. We build it in the strdef field on
+ the stack, to avoid confusing type definitions required by the
+ fields with the struct type itself. */
+
+static boolean
+ieee_start_struct_type (p, tag, id, structp, size)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp, ignorep;
+ boolean copy;
+ char ab[20];
+ const char *look;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt, *ntlook;
+ struct ieee_buflist strdef;
+
+ localp = false;
+ ignorep = false;
+
+ /* We need to create a tag for internal use even if we don't want
+ one for external use. This will let us refer to an anonymous
+ struct. */
+ if (tag != NULL)
+ {
+ look = tag;
+ copy = false;
+ }
+ else
+ {
+ sprintf (ab, "__anon%u", id);
+ look = ab;
+ copy = true;
+ }
+
+ /* If we already have references to the tag, we must use the
+ existing type index. */
+ h = ieee_name_type_hash_lookup (&info->tags, look, true, copy);
+ if (h == NULL)
+ return false;
+
+ nt = NULL;
+ for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next)
+ {
+ if (ntlook->id == id)
+ nt = ntlook;
+ else if (! ntlook->type.localp)
+ {
+ /* We are creating a duplicate definition of a globally
+ defined tag. Force it to be local to avoid
+ confusion. */
+ localp = true;
+ }
+ }
+
+ if (nt != NULL)
+ {
+ assert (localp == nt->type.localp);
+ if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp)
+ {
+ /* We've already seen a global definition of the type.
+ Ignore this new definition. */
+ ignorep = true;
+ }
+ }
+ else
+ {
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+ nt->id = id;
+ nt->type.name = h->root.string;
+ nt->next = h->types;
+ h->types = nt;
+ nt->type.indx = info->type_indx;
+ ++info->type_indx;
+ }
+
+ nt->kind = DEBUG_KIND_ILLEGAL;
+
+ if (! ieee_init_buffer (info, &strdef)
+ || ! ieee_define_named_type (info, tag, nt->type.indx, size, true,
+ localp, &strdef)
+ || ! ieee_write_number (info, structp ? 'S' : 'U')
+ || ! ieee_write_number (info, size))
+ return false;
+
+ if (! ignorep)
+ {
+ const char *hold;
+
+ /* We never want nt->type.name to be NULL. We want the rest of
+ the type to be the object set up on the type stack; it will
+ have a NULL name if tag is NULL. */
+ hold = nt->type.name;
+ nt->type = info->type_stack->type;
+ nt->type.name = hold;
+ }
+
+ info->type_stack->type.name = tag;
+ info->type_stack->type.strdef = strdef;
+ info->type_stack->type.ignorep = ignorep;
+
+ return true;
+}
+
+/* Add a field to a struct. */
+
+static boolean
+ieee_struct_field (p, name, bitpos, bitsize, visibility)
+ PTR p;
+ const char *name;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp;
+ boolean referencep;
+ boolean localp;
+ unsigned int indx;
+ bfd_vma offset;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->next != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
+
+ /* If we are ignoring this struct definition, just pop and ignore
+ the type. */
+ if (info->type_stack->next->type.ignorep)
+ {
+ ieee_pop_unused_type (info);
+ return true;
+ }
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ referencep = info->type_stack->type.referencep;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (localp)
+ info->type_stack->type.localp = true;
+
+ if (info->type_stack->type.classdef != NULL)
+ {
+ unsigned int flags;
+ unsigned int nindx;
+
+ /* This is a class. We must add a description of this field to
+ the class records we are building. */
+
+ flags = ieee_vis_to_flags (visibility);
+ nindx = info->type_stack->type.classdef->indx;
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'd')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, name)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 4;
+
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ /* We need to output a record recording that this field is
+ really of reference type. We put this on the refs field
+ of classdef, so that it can be appended to the C++
+ records after the class is defined. */
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->refs)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 4)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, 3)
+ || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+ }
+
+ /* If the bitsize doesn't match the expected size, we need to output
+ a bitfield type. */
+ if (size == 0 || bitsize == 0 || bitsize == size * 8)
+ offset = bitpos / 8;
+ else
+ {
+ if (! ieee_define_type (info, 0, unsignedp,
+ info->type_stack->type.localp)
+ || ! ieee_write_number (info, 'g')
+ || ! ieee_write_number (info, unsignedp ? 0 : 1)
+ || ! ieee_write_number (info, bitsize)
+ || ! ieee_write_number (info, indx))
+ return false;
+ indx = ieee_pop_type (info);
+ offset = bitpos;
+ }
+
+ /* Switch to the struct we are building in order to output this
+ field definition. */
+ return (ieee_change_buffer (info, &info->type_stack->type.strdef)
+ && ieee_write_id (info, name)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, offset));
+}
+
+/* Finish up a struct type. */
+
+static boolean
+ieee_end_struct_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_buflist *pb;
+
+ assert (info->type_stack != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->type.strdef));
+
+ /* If we were ignoring this struct definition because it was a
+ duplicate defintion, just through away whatever bytes we have
+ accumulated. Leave the type on the stack. */
+ if (info->type_stack->type.ignorep)
+ return true;
+
+ /* If this is not a duplicate definition of this tag, then localp
+ will be false, and we can put it in the global type block.
+ FIXME: We should avoid outputting duplicate definitions which are
+ the same. */
+ if (! info->type_stack->type.localp)
+ {
+ /* Make sure we have started the global type block. */
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ pb = &info->global_types;
+ }
+ else
+ {
+ /* Make sure we have started the types block. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ pb = &info->types;
+ }
+
+ /* Append the struct definition to the types. */
+ if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef)
+ || ! ieee_init_buffer (info, &info->type_stack->type.strdef))
+ return false;
+
+ /* Leave the struct on the type stack. */
+
+ return true;
+}
+
+/* Start a class type. */
+
+static boolean
+ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+ boolean vptr;
+ boolean ownvptr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *vclass;
+ struct ieee_buflist pmiscbuf;
+ unsigned int indx;
+ struct ieee_type_class *classdef;
+
+ /* A C++ class is output as a C++ struct along with a set of pmisc
+ records describing the class. */
+
+ /* We need to have a name so that we can associate the struct and
+ the class. */
+ if (tag == NULL)
+ {
+ char *t;
+
+ t = (char *) xmalloc (20);
+ sprintf (t, "__anon%u", id);
+ tag = t;
+ }
+
+ /* We can't write out the virtual table information until we have
+ finished the class, because we don't know the virtual table size.
+ We get the size from the largest voffset we see. */
+ vclass = NULL;
+ if (vptr && ! ownvptr)
+ {
+ vclass = info->type_stack->type.name;
+ assert (vclass != NULL);
+ /* We don't call ieee_pop_unused_type, since the class should
+ get defined. */
+ (void) ieee_pop_type (info);
+ }
+
+ if (! ieee_start_struct_type (p, tag, id, structp, size))
+ return false;
+
+ indx = info->name_indx;
+ ++info->name_indx;
+
+ /* We write out pmisc records into the classdef field. We will
+ write out the pmisc start after we know the number of records we
+ need. */
+ if (! ieee_init_buffer (info, &pmiscbuf)
+ || ! ieee_change_buffer (info, &pmiscbuf)
+ || ! ieee_write_asn (info, indx, 'T')
+ || ! ieee_write_asn (info, indx, structp ? 'o' : 'u')
+ || ! ieee_write_atn65 (info, indx, tag))
+ return false;
+
+ classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef);
+ memset (classdef, 0, sizeof *classdef);
+
+ classdef->indx = indx;
+ classdef->pmiscbuf = pmiscbuf;
+ classdef->pmisccount = 3;
+ classdef->vclass = vclass;
+ classdef->ownvptr = ownvptr;
+
+ info->type_stack->type.classdef = classdef;
+
+ return true;
+}
+
+/* Add a static member to a class. */
+
+static boolean
+ieee_class_static_member (p, name, physname, visibility)
+ PTR p;
+ const char *name;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int flags;
+ unsigned int nindx;
+
+ /* We don't care about the type. Hopefully there will be a call to
+ ieee_variable declaring the physical name and the type, since
+ that is where an IEEE consumer must get the type. */
+ ieee_pop_unused_type (info);
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL);
+
+ flags = ieee_vis_to_flags (visibility);
+ flags |= CXXFLAGS_STATIC;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'd')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, name)
+ || ! ieee_write_atn65 (info, nindx, physname))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 4;
+
+ return true;
+}
+
+/* Add a base class to a class. */
+
+static boolean
+ieee_class_baseclass (p, bitpos, virtual, visibility)
+ PTR p;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *bname;
+ boolean localp;
+ unsigned int bindx;
+ char *fname;
+ unsigned int flags;
+ unsigned int nindx;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.name != NULL
+ && info->type_stack->next != NULL
+ && info->type_stack->next->type.classdef != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
+
+ bname = info->type_stack->type.name;
+ localp = info->type_stack->type.localp;
+ bindx = ieee_pop_type (info);
+
+ /* We are currently defining both a struct and a class. We must
+ write out a field definition in the struct which holds the base
+ class. The stabs debugging reader will create a field named
+ _vb$CLASS for a virtual base class, so we just use that. FIXME:
+ we should not depend upon a detail of stabs debugging. */
+ if (virtual)
+ {
+ fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$");
+ sprintf (fname, "_vb$%s", bname);
+ flags = BASEFLAGS_VIRTUAL;
+ }
+ else
+ {
+ if (localp)
+ info->type_stack->type.localp = true;
+
+ fname = (char *) xmalloc (strlen (bname) + sizeof "_b$");
+ sprintf (fname, "_b$%s", bname);
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.strdef)
+ || ! ieee_write_id (info, fname)
+ || ! ieee_write_number (info, bindx)
+ || ! ieee_write_number (info, bitpos / 8))
+ return false;
+ flags = 0;
+ }
+
+ if (visibility == DEBUG_VISIBILITY_PRIVATE)
+ flags |= BASEFLAGS_PRIVATE;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'b')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, bname)
+ || ! ieee_write_asn (info, nindx, 0)
+ || ! ieee_write_atn65 (info, nindx, fname))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 5;
+
+ free (fname);
+
+ return true;
+}
+
+/* Start building a method for a class. */
+
+static boolean
+ieee_class_start_method (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method == NULL);
+
+ info->type_stack->type.classdef->method = name;
+
+ return true;
+}
+
+/* Define a new method variant, either static or not. */
+
+static boolean
+ieee_class_method_var (info, physname, visibility, staticp, constp,
+ volatilep, voffset, context)
+ struct ieee_handle *info;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean staticp;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ unsigned int flags;
+ unsigned int nindx;
+ boolean virtual;
+
+ /* We don't need the type of the method. An IEEE consumer which
+ wants the type must track down the function by the physical name
+ and get the type from that. */
+ ieee_pop_unused_type (info);
+
+ /* We don't use the context. FIXME: We probably ought to use it to
+ adjust the voffset somehow, but I don't really know how. */
+ if (context)
+ ieee_pop_unused_type (info);
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method != NULL);
+
+ flags = ieee_vis_to_flags (visibility);
+
+ /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR,
+ CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */
+
+ if (staticp)
+ flags |= CXXFLAGS_STATIC;
+ if (constp)
+ flags |= CXXFLAGS_CONST;
+ if (volatilep)
+ flags |= CXXFLAGS_VOLATILE;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ virtual = context || voffset > 0;
+
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx,
+ info->type_stack->type.classdef->method)
+ || ! ieee_write_atn65 (info, nindx, physname))
+ return false;
+
+ if (virtual)
+ {
+ if (voffset > info->type_stack->type.classdef->voffset)
+ info->type_stack->type.classdef->voffset = voffset;
+ if (! ieee_write_asn (info, nindx, voffset))
+ return false;
+ ++info->type_stack->type.classdef->pmisccount;
+ }
+
+ if (! ieee_write_asn (info, nindx, 0))
+ return false;
+
+ info->type_stack->type.classdef->pmisccount += 5;
+
+ return true;
+}
+
+/* Define a new method variant. */
+
+static boolean
+ieee_class_method_variant (p, physname, visibility, constp, volatilep,
+ voffset, context)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_class_method_var (info, physname, visibility, false, constp,
+ volatilep, voffset, context);
+}
+
+/* Define a new static method variant. */
+
+static boolean
+ieee_class_static_method_variant (p, physname, visibility, constp, volatilep)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_class_method_var (info, physname, visibility, true, constp,
+ volatilep, 0, false);
+}
+
+/* Finish up a method. */
+
+static boolean
+ieee_class_end_method (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method != NULL);
+
+ info->type_stack->type.classdef->method = NULL;
+
+ return true;
+}
+
+/* Finish up a class. */
+
+static boolean
+ieee_end_class_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int nindx;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL);
+
+ /* If we were ignoring this class definition because it was a
+ duplicate definition, just through away whatever bytes we have
+ accumulated. Leave the type on the stack. */
+ if (info->type_stack->type.ignorep)
+ return true;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ /* If we have a virtual table, we can write out the information now. */
+ if (info->type_stack->type.classdef->vclass != NULL
+ || info->type_stack->type.classdef->ownvptr)
+ {
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'z')
+ || ! ieee_write_atn65 (info, nindx, "")
+ || ! ieee_write_asn (info, nindx,
+ info->type_stack->type.classdef->voffset))
+ return false;
+ if (info->type_stack->type.classdef->ownvptr)
+ {
+ if (! ieee_write_atn65 (info, nindx, ""))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_atn65 (info, nindx,
+ info->type_stack->type.classdef->vclass))
+ return false;
+ }
+ if (! ieee_write_asn (info, nindx, 0))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 5;
+ }
+
+ /* Now that we know the number of pmisc records, we can write out
+ the atn62 which starts the pmisc records, and append them to the
+ C++ buffers. */
+
+ if (! ieee_change_buffer (info, &info->cxx)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info,
+ info->type_stack->type.classdef->pmisccount))
+ return false;
+
+ if (! ieee_append_buffer (info, &info->cxx,
+ &info->type_stack->type.classdef->pmiscbuf))
+ return false;
+ if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs))
+ {
+ if (! ieee_append_buffer (info, &info->cxx,
+ &info->type_stack->type.classdef->refs))
+ return false;
+ }
+
+ return ieee_end_struct_type (p);
+}
+
+/* Push a previously seen typedef onto the type stack. */
+
+static boolean
+ieee_typedef_type (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false);
+
+ /* h should never be NULL, since that would imply that the generic
+ debugging code has asked for a typedef which it has not yet
+ defined. */
+ assert (h != NULL);
+
+ /* We always use the most recently defined type for this name, which
+ will be the first one on the list. */
+
+ nt = h->types;
+ if (! ieee_push_type (info, nt->type.indx, nt->type.size,
+ nt->type.unsignedp, nt->type.localp))
+ return false;
+
+ /* Copy over any other type information we may have. */
+ info->type_stack->type = nt->type;
+
+ return true;
+}
+
+/* Push a tagged type onto the type stack. */
+
+static boolean
+ieee_tag_type (p, name, id, kind)
+ PTR p;
+ const char *name;
+ unsigned int id;
+ enum debug_type_kind kind;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ boolean copy;
+ char ab[20];
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ if (kind == DEBUG_KIND_ENUM)
+ {
+ struct ieee_defined_enum *e;
+
+ if (name == NULL)
+ abort ();
+ for (e = info->enums; e != NULL; e = e->next)
+ if (e->tag != NULL && strcmp (e->tag, name) == 0)
+ return ieee_push_type (info, e->indx, 0, true, false);
+
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->indx = info->type_indx;
+ ++info->type_indx;
+ e->tag = name;
+ e->defined = false;
+
+ e->next = info->enums;
+ info->enums = e;
+
+ return ieee_push_type (info, e->indx, 0, true, false);
+ }
+
+ localp = false;
+
+ copy = false;
+ if (name == NULL)
+ {
+ sprintf (ab, "__anon%u", id);
+ name = ab;
+ copy = true;
+ }
+
+ h = ieee_name_type_hash_lookup (&info->tags, name, true, copy);
+ if (h == NULL)
+ return false;
+
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ if (nt->id == id)
+ {
+ if (! ieee_push_type (info, nt->type.indx, nt->type.size,
+ nt->type.unsignedp, nt->type.localp))
+ return false;
+ /* Copy over any other type information we may have. */
+ info->type_stack->type = nt->type;
+ return true;
+ }
+
+ if (! nt->type.localp)
+ {
+ /* This is a duplicate of a global type, so it must be
+ local. */
+ localp = true;
+ }
+ }
+
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+
+ nt->id = id;
+ nt->type.name = h->root.string;
+ nt->type.indx = info->type_indx;
+ nt->type.localp = localp;
+ ++info->type_indx;
+ nt->kind = kind;
+
+ nt->next = h->types;
+ h->types = nt;
+
+ if (! ieee_push_type (info, nt->type.indx, 0, false, localp))
+ return false;
+
+ info->type_stack->type.name = h->root.string;
+
+ return true;
+}
+
+/* Output a typedef. */
+
+static boolean
+ieee_typdef (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_write_type type;
+ unsigned int indx;
+ boolean found;
+ boolean localp;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ type = info->type_stack->type;
+ indx = type.indx;
+
+ /* If this is a simple builtin type using a builtin name, we don't
+ want to output the typedef itself. We also want to change the
+ type index to correspond to the name being used. We recognize
+ names used in stabs debugging output even if they don't exactly
+ correspond to the names used for the IEEE builtin types. */
+ found = false;
+ if (indx <= (unsigned int) builtin_bcd_float)
+ {
+ switch ((enum builtin_types) indx)
+ {
+ default:
+ break;
+
+ case builtin_void:
+ if (strcmp (name, "void") == 0)
+ found = true;
+ break;
+
+ case builtin_signed_char:
+ case builtin_char:
+ if (strcmp (name, "signed char") == 0)
+ {
+ indx = (unsigned int) builtin_signed_char;
+ found = true;
+ }
+ else if (strcmp (name, "char") == 0)
+ {
+ indx = (unsigned int) builtin_char;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_char:
+ if (strcmp (name, "unsigned char") == 0)
+ found = true;
+ break;
+
+ case builtin_signed_short_int:
+ case builtin_short:
+ case builtin_short_int:
+ case builtin_signed_short:
+ if (strcmp (name, "signed short int") == 0)
+ {
+ indx = (unsigned int) builtin_signed_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "short") == 0)
+ {
+ indx = (unsigned int) builtin_short;
+ found = true;
+ }
+ else if (strcmp (name, "short int") == 0)
+ {
+ indx = (unsigned int) builtin_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "signed short") == 0)
+ {
+ indx = (unsigned int) builtin_signed_short;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_short_int:
+ case builtin_unsigned_short:
+ if (strcmp (name, "unsigned short int") == 0
+ || strcmp (name, "short unsigned int") == 0)
+ {
+ indx = builtin_unsigned_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned short") == 0)
+ {
+ indx = builtin_unsigned_short;
+ found = true;
+ }
+ break;
+
+ case builtin_signed_long:
+ case builtin_int: /* FIXME: Size depends upon architecture. */
+ case builtin_long:
+ if (strcmp (name, "signed long") == 0)
+ {
+ indx = builtin_signed_long;
+ found = true;
+ }
+ else if (strcmp (name, "int") == 0)
+ {
+ indx = builtin_int;
+ found = true;
+ }
+ else if (strcmp (name, "long") == 0
+ || strcmp (name, "long int") == 0)
+ {
+ indx = builtin_long;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_long:
+ case builtin_unsigned: /* FIXME: Size depends upon architecture. */
+ case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */
+ if (strcmp (name, "unsigned long") == 0
+ || strcmp (name, "long unsigned int") == 0)
+ {
+ indx = builtin_unsigned_long;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned") == 0)
+ {
+ indx = builtin_unsigned;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned int") == 0)
+ {
+ indx = builtin_unsigned_int;
+ found = true;
+ }
+ break;
+
+ case builtin_signed_long_long:
+ if (strcmp (name, "signed long long") == 0
+ || strcmp (name, "long long int") == 0)
+ found = true;
+ break;
+
+ case builtin_unsigned_long_long:
+ if (strcmp (name, "unsigned long long") == 0
+ || strcmp (name, "long long unsigned int") == 0)
+ found = true;
+ break;
+
+ case builtin_float:
+ if (strcmp (name, "float") == 0)
+ found = true;
+ break;
+
+ case builtin_double:
+ if (strcmp (name, "double") == 0)
+ found = true;
+ break;
+
+ case builtin_long_double:
+ if (strcmp (name, "long double") == 0)
+ found = true;
+ break;
+
+ case builtin_long_long_double:
+ if (strcmp (name, "long long double") == 0)
+ found = true;
+ break;
+ }
+
+ if (found)
+ type.indx = indx;
+ }
+
+ h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false);
+ if (h == NULL)
+ return false;
+
+ /* See if we have already defined this type with this name. */
+ localp = type.localp;
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ if (nt->id == indx)
+ {
+ /* If this is a global definition, then we don't need to
+ do anything here. */
+ if (! nt->type.localp)
+ {
+ ieee_pop_unused_type (info);
+ return true;
+ }
+ }
+ else
+ {
+ /* This is a duplicate definition, so make this one local. */
+ localp = true;
+ }
+ }
+
+ /* We need to add a new typedef for this type. */
+
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+ nt->id = indx;
+ nt->type = type;
+ nt->type.name = name;
+ nt->type.localp = localp;
+ nt->kind = DEBUG_KIND_ILLEGAL;
+
+ nt->next = h->types;
+ h->types = nt;
+
+ if (found)
+ {
+ /* This is one of the builtin typedefs, so we don't need to
+ actually define it. */
+ ieee_pop_unused_type (info);
+ return true;
+ }
+
+ indx = ieee_pop_type (info);
+
+ if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size,
+ type.unsignedp, localp,
+ (struct ieee_buflist *) NULL)
+ || ! ieee_write_number (info, 'T')
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ /* Remove the type we just added to the type stack. This should not
+ be ieee_pop_unused_type, since the type is used, we just don't
+ need it now. */
+ (void) ieee_pop_type (info);
+
+ return true;
+}
+
+/* Output a tag for a type. We don't have to do anything here. */
+
+static boolean
+ieee_tag (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* This should not be ieee_pop_unused_type, since we want the type
+ to be defined. */
+ (void) ieee_pop_type (info);
+ return true;
+}
+
+/* Output an integer constant. */
+
+static boolean
+ieee_int_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ /* FIXME. */
+ return true;
+}
+
+/* Output a floating point constant. */
+
+static boolean
+ieee_float_constant (p, name, val)
+ PTR p;
+ const char *name;
+ double val;
+{
+ /* FIXME. */
+ return true;
+}
+
+/* Output a typed constant. */
+
+static boolean
+ieee_typed_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* FIXME. */
+ ieee_pop_unused_type (info);
+ return true;
+}
+
+/* Output a variable. */
+
+static boolean
+ieee_variable (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int name_indx;
+ unsigned int size;
+ boolean referencep;
+ unsigned int type_indx;
+ boolean asn;
+ int refflag;
+
+ size = info->type_stack->type.size;
+ referencep = info->type_stack->type.referencep;
+ type_indx = ieee_pop_type (info);
+
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+
+ /* Write out an NN and an ATN record for this variable. */
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_id (info, name)
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_number (info, type_indx))
+ return false;
+ switch (kind)
+ {
+ default:
+ abort ();
+ return false;
+ case DEBUG_GLOBAL:
+ if (! ieee_write_number (info, 8)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 0;
+ asn = true;
+ break;
+ case DEBUG_STATIC:
+ if (! ieee_write_number (info, 3)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 1;
+ asn = true;
+ break;
+ case DEBUG_LOCAL_STATIC:
+ if (! ieee_write_number (info, 3)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 2;
+ asn = true;
+ break;
+ case DEBUG_LOCAL:
+ if (! ieee_write_number (info, 1)
+ || ! ieee_write_number (info, val))
+ return false;
+ refflag = 2;
+ asn = false;
+ break;
+ case DEBUG_REGISTER:
+ if (! ieee_write_number (info, 2)
+ || ! ieee_write_number (info,
+ ieee_genreg_to_regno (info->abfd, val)))
+ return false;
+ refflag = 2;
+ asn = false;
+ break;
+ }
+
+ if (asn)
+ {
+ if (! ieee_write_asn (info, name_indx, val))
+ return false;
+ }
+
+ /* If this is really a reference type, then we just output it with
+ pointer type, and must now output a C++ record indicating that it
+ is really reference type. */
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+
+ /* If this is a global variable, we want to output the misc
+ record in the C++ misc record block. Otherwise, we want to
+ output it just after the variable definition, which is where
+ the current buffer is. */
+ if (refflag != 2)
+ {
+ if (! ieee_change_buffer (info, &info->cxx))
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 3)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, refflag)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+
+ return true;
+}
+
+/* Start outputting information for a function. */
+
+static boolean
+ieee_start_function (p, name, global)
+ PTR p;
+ const char *name;
+ boolean global;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean referencep;
+ unsigned int retindx, typeindx;
+
+ referencep = info->type_stack->type.referencep;
+ retindx = ieee_pop_type (info);
+
+ /* Besides recording a BB4 or BB6 block, we record the type of the
+ function in the BB1 typedef block. We can't write out the full
+ type until we have seen all the parameters, so we accumulate it
+ in info->fntype and info->fnargs. */
+ if (! ieee_buffer_emptyp (&info->fntype))
+ {
+ /* FIXME: This might happen someday if we support nested
+ functions. */
+ abort ();
+ }
+
+ info->fnname = name;
+
+ /* An attribute of 0x40 means that the push mask is unknown. */
+ if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true,
+ &info->fntype)
+ || ! ieee_write_number (info, 'x')
+ || ! ieee_write_number (info, 0x40)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, retindx))
+ return false;
+
+ typeindx = ieee_pop_type (info);
+
+ if (! ieee_init_buffer (info, &info->fnargs))
+ return false;
+ info->fnargcount = 0;
+
+ /* If the function return value is actually a reference type, we
+ must add a record indicating that. */
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->cxx)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 3)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, global ? 0 : 1)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ /* The address is written out as the first block. */
+
+ ++info->block_depth;
+
+ return (ieee_write_byte (info, (int) ieee_bb_record_enum)
+ && ieee_write_byte (info, global ? 4 : 6)
+ && ieee_write_number (info, 0)
+ && ieee_write_id (info, name)
+ && ieee_write_number (info, 0)
+ && ieee_write_number (info, typeindx));
+}
+
+/* Add a function parameter. This will normally be called before the
+ first block, so we postpone them until we see the block. */
+
+static boolean
+ieee_function_parameter (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_pending_parm *m, **pm;
+
+ assert (info->block_depth == 1);
+
+ m = (struct ieee_pending_parm *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->next = NULL;
+ m->name = name;
+ m->referencep = info->type_stack->type.referencep;
+ m->type = ieee_pop_type (info);
+ m->kind = kind;
+ m->val = val;
+
+ for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next)
+ ;
+ *pm = m;
+
+ /* Add the type to the fnargs list. */
+ if (! ieee_change_buffer (info, &info->fnargs)
+ || ! ieee_write_number (info, m->type))
+ return false;
+ ++info->fnargcount;
+
+ return true;
+}
+
+/* Output pending function parameters. */
+
+static boolean
+ieee_output_pending_parms (info)
+ struct ieee_handle *info;
+{
+ struct ieee_pending_parm *m;
+ unsigned int refcount;
+
+ refcount = 0;
+ for (m = info->pending_parms; m != NULL; m = m->next)
+ {
+ enum debug_var_kind vkind;
+
+ switch (m->kind)
+ {
+ default:
+ abort ();
+ return false;
+ case DEBUG_PARM_STACK:
+ case DEBUG_PARM_REFERENCE:
+ vkind = DEBUG_LOCAL;
+ break;
+ case DEBUG_PARM_REG:
+ case DEBUG_PARM_REF_REG:
+ vkind = DEBUG_REGISTER;
+ break;
+ }
+
+ if (! ieee_push_type (info, m->type, 0, false, false))
+ return false;
+ info->type_stack->type.referencep = m->referencep;
+ if (m->referencep)
+ ++refcount;
+ if (! ieee_variable ((PTR) info, m->name, vkind, m->val))
+ return false;
+ }
+
+ /* If there are any reference parameters, we need to output a
+ miscellaneous record indicating them. */
+ if (refcount > 0)
+ {
+ unsigned int nindx, varindx;
+
+ /* FIXME: The MRI compiler outputs the demangled function name
+ here, but we are outputting the mangled name. */
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, refcount + 3)
+ || ! ieee_write_asn (info, nindx, 'B')
+ || ! ieee_write_atn65 (info, nindx, info->fnname)
+ || ! ieee_write_asn (info, nindx, 0))
+ return false;
+ for (m = info->pending_parms, varindx = 1;
+ m != NULL;
+ m = m->next, varindx++)
+ {
+ if (m->referencep)
+ {
+ if (! ieee_write_asn (info, nindx, varindx))
+ return false;
+ }
+ }
+ }
+
+ m = info->pending_parms;
+ while (m != NULL)
+ {
+ struct ieee_pending_parm *next;
+
+ next = m->next;
+ free (m);
+ m = next;
+ }
+
+ info->pending_parms = NULL;
+
+ return true;
+}
+
+/* Start a block. If this is the first block, we output the address
+ to finish the BB4 or BB6, and then output the function parameters. */
+
+static boolean
+ieee_start_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ if (info->block_depth == 1)
+ {
+ if (! ieee_write_number (info, addr)
+ || ! ieee_output_pending_parms (info))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 6)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, addr))
+ return false;
+ }
+
+ if (! ieee_start_range (info, addr))
+ return false;
+
+ ++info->block_depth;
+
+ return true;
+}
+
+/* End a block. */
+
+static boolean
+ieee_end_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* The address we are given is the end of the block, but IEEE seems
+ to want to the address of the last byte in the block, so we
+ subtract one. */
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, addr - 1))
+ return false;
+
+ if (! ieee_end_range (info, addr))
+ return false;
+
+ --info->block_depth;
+
+ if (addr > info->highaddr)
+ info->highaddr = addr;
+
+ return true;
+}
+
+/* End a function. */
+
+static boolean
+ieee_end_function (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->block_depth == 1);
+
+ --info->block_depth;
+
+ /* Now we can finish up fntype, and add it to the typdef section.
+ At this point, fntype is the 'x' type up to the argument count,
+ and fnargs is the argument types. We must add the argument
+ count, and we must add the level. FIXME: We don't record varargs
+ functions correctly. In fact, stabs debugging does not give us
+ enough information to do so. */
+ if (! ieee_change_buffer (info, &info->fntype)
+ || ! ieee_write_number (info, info->fnargcount)
+ || ! ieee_change_buffer (info, &info->fnargs)
+ || ! ieee_write_number (info, 0))
+ return false;
+
+ /* Make sure the typdef block has been started. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+
+ if (! ieee_append_buffer (info, &info->types, &info->fntype)
+ || ! ieee_append_buffer (info, &info->types, &info->fnargs))
+ return false;
+
+ info->fnname = NULL;
+ if (! ieee_init_buffer (info, &info->fntype)
+ || ! ieee_init_buffer (info, &info->fnargs))
+ return false;
+ info->fnargcount = 0;
+
+ return true;
+}
+
+/* Record line number information. */
+
+static boolean
+ieee_lineno (p, filename, lineno, addr)
+ PTR p;
+ const char *filename;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->filename != NULL);
+
+ /* The HP simulator seems to get confused when more than one line is
+ listed for the same address, at least if they are in different
+ files. We handle this by always listing the last line for a
+ given address, since that seems to be the one that gdb uses. */
+ if (info->pending_lineno_filename != NULL
+ && addr != info->pending_lineno_addr)
+ {
+ /* Make sure we have a line number block. */
+ if (! ieee_buffer_emptyp (&info->linenos))
+ {
+ if (! ieee_change_buffer (info, &info->linenos))
+ return false;
+ }
+ else
+ {
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->linenos)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 5)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->filename)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ info->lineno_filename = info->filename;
+ }
+
+ if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0)
+ {
+ if (strcmp (info->filename, info->lineno_filename) != 0)
+ {
+ /* We were not in the main file. Close the block for the
+ included file. */
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ if (strcmp (info->filename, info->pending_lineno_filename) == 0)
+ {
+ /* We need a new NN record, and we aren't about to
+ output one. */
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ }
+ if (strcmp (info->filename, info->pending_lineno_filename) != 0)
+ {
+ /* We are not changing to the main file. Open a block for
+ the new included file. */
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 5)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->pending_lineno_filename)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ info->lineno_filename = info->pending_lineno_filename;
+ }
+
+ if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 7)
+ || ! ieee_write_number (info, info->pending_lineno)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_asn (info, info->lineno_name_indx,
+ info->pending_lineno_addr))
+ return false;
+ }
+
+ info->pending_lineno_filename = filename;
+ info->pending_lineno = lineno;
+ info->pending_lineno_addr = addr;
+
+ return true;
+}
diff --git a/pstack/ieee.h b/pstack/ieee.h
new file mode 100644
index 00000000000..56634b2819a
--- /dev/null
+++ b/pstack/ieee.h
@@ -0,0 +1,138 @@
+/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file
+ Contributed by Cygnus Support. */
+
+#define N_W_VARIABLES 8
+#define Module_Beginning 0xe0
+
+typedef struct ieee_module {
+ char *processor;
+ char *module_name;
+} ieee_module_begin_type;
+
+#define Address_Descriptor 0xec
+typedef struct ieee_address {
+bfd_vma number_of_bits_mau;
+ bfd_vma number_of_maus_in_address;
+
+ unsigned char byte_order;
+#define IEEE_LITTLE 0xcc
+#define IEEE_BIG 0xcd
+} ieee_address_descriptor_type;
+
+typedef union ieee_w_variable {
+ file_ptr offset[N_W_VARIABLES];
+ struct {
+ file_ptr extension_record;
+ file_ptr environmental_record;
+ file_ptr section_part;
+ file_ptr external_part;
+ file_ptr debug_information_part;
+ file_ptr data_part;
+ file_ptr trailer_part;
+ file_ptr me_record;
+ } r;
+} ieee_w_variable_type;
+
+
+
+
+
+typedef enum ieee_record
+{
+ ieee_number_start_enum = 0x00,
+ ieee_number_end_enum=0x7f,
+ ieee_number_repeat_start_enum = 0x80,
+ ieee_number_repeat_end_enum = 0x88,
+ ieee_number_repeat_4_enum = 0x84,
+ ieee_number_repeat_3_enum = 0x83,
+ ieee_number_repeat_2_enum = 0x82,
+ ieee_number_repeat_1_enum = 0x81,
+ ieee_module_beginning_enum = 0xe0,
+ ieee_module_end_enum = 0xe1,
+ ieee_extension_length_1_enum = 0xde,
+ ieee_extension_length_2_enum = 0xdf,
+ ieee_section_type_enum = 0xe6,
+ ieee_section_alignment_enum = 0xe7,
+ ieee_external_symbol_enum = 0xe8,
+ ieee_comma = 0x90,
+ ieee_external_reference_enum = 0xe9,
+ ieee_set_current_section_enum = 0xe5,
+ ieee_address_descriptor_enum = 0xec,
+ ieee_load_constant_bytes_enum = 0xed,
+ ieee_load_with_relocation_enum = 0xe4,
+
+ ieee_variable_A_enum = 0xc1,
+ ieee_variable_B_enum = 0xc2,
+ ieee_variable_C_enum = 0xc3,
+ ieee_variable_D_enum = 0xc4,
+ ieee_variable_E_enum = 0xc5,
+ ieee_variable_F_enum = 0xc6,
+ ieee_variable_G_enum = 0xc7,
+ ieee_variable_H_enum = 0xc8,
+ ieee_variable_I_enum = 0xc9,
+ ieee_variable_J_enum = 0xca,
+ ieee_variable_K_enum = 0xcb,
+ ieee_variable_L_enum = 0xcc,
+ ieee_variable_M_enum = 0xcd,
+ ieee_variable_N_enum = 0xce,
+ ieee_variable_O_enum = 0xcf,
+ ieee_variable_P_enum = 0xd0,
+ ieee_variable_Q_enum = 0xd1,
+ ieee_variable_R_enum = 0xd2,
+ ieee_variable_S_enum = 0xd3,
+ ieee_variable_T_enum = 0xd4,
+ ieee_variable_U_enum = 0xd5,
+ ieee_variable_V_enum = 0xd6,
+ ieee_variable_W_enum = 0xd7,
+ ieee_variable_X_enum = 0xd8,
+ ieee_variable_Y_enum = 0xd9,
+ ieee_variable_Z_enum = 0xda,
+ ieee_function_plus_enum = 0xa5,
+ ieee_function_minus_enum = 0xa6,
+ ieee_function_signed_open_b_enum = 0xba,
+ ieee_function_signed_close_b_enum = 0xbb,
+
+ ieee_function_unsigned_open_b_enum = 0xbc,
+ ieee_function_unsigned_close_b_enum = 0xbd,
+
+ ieee_function_either_open_b_enum = 0xbe,
+ ieee_function_either_close_b_enum = 0xbf,
+ ieee_record_seperator_enum = 0xdb,
+
+ ieee_e2_first_byte_enum = 0xe2,
+ ieee_section_size_enum = 0xe2d3,
+ ieee_physical_region_size_enum = 0xe2c1,
+ ieee_region_base_address_enum = 0xe2c2,
+ ieee_mau_size_enum = 0xe2c6,
+ ieee_m_value_enum = 0xe2cd,
+ ieee_section_base_address_enum = 0xe2cc,
+ ieee_asn_record_enum = 0xe2ce,
+ ieee_section_offset_enum = 0xe2d2,
+ ieee_value_starting_address_enum = 0xe2c7,
+ ieee_assign_value_to_variable_enum = 0xe2d7,
+ ieee_set_current_pc_enum = 0xe2d0,
+ ieee_value_record_enum = 0xe2c9,
+ ieee_nn_record = 0xf0,
+ ieee_at_record_enum = 0xf1,
+ ieee_ty_record_enum = 0xf2,
+ ieee_attribute_record_enum = 0xf1c9,
+ ieee_atn_record_enum = 0xf1ce,
+ ieee_external_reference_info_record_enum = 0xf1d8,
+ ieee_weak_external_reference_enum= 0xf4,
+ ieee_repeat_data_enum = 0xf7,
+ ieee_bb_record_enum = 0xf8,
+ ieee_be_record_enum = 0xf9
+} ieee_record_enum_type;
+
+
+typedef struct ieee_section {
+ unsigned int section_index;
+ unsigned int section_type;
+ char *section_name;
+ unsigned int parent_section_index;
+ unsigned int sibling_section_index;
+ unsigned int context_index;
+} ieee_section_type;
+#define IEEE_REFERENCE_BASE 11
+#define IEEE_PUBLIC_BASE 32
+#define IEEE_SECTION_NUMBER_BASE 1
diff --git a/pstack/libiberty.h b/pstack/libiberty.h
new file mode 100644
index 00000000000..ca0043d31c6
--- /dev/null
+++ b/pstack/libiberty.h
@@ -0,0 +1,180 @@
+/* Function declarations for libiberty.
+ Written by Cygnus Support, 1994.
+
+ The libiberty library provides a number of functions which are
+ missing on some operating systems. We do not declare those here,
+ to avoid conflicts with the system header files on operating
+ systems that do support those functions. In this file we only
+ declare those functions which are specific to libiberty. */
+
+#ifndef LIBIBERTY_H
+#define LIBIBERTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+
+/* Build an argument vector from a string. Allocates memory using
+ malloc. Use freeargv to free the vector. */
+
+extern char **buildargv PARAMS ((char *));
+
+/* Free a vector returned by buildargv. */
+
+extern void freeargv PARAMS ((char **));
+
+/* Duplicate an argument vector. Allocates memory using malloc. Use
+ freeargv to free the vector. */
+
+extern char **dupargv PARAMS ((char **));
+
+
+/* Return the last component of a path name. Note that we can't use a
+ prototype here because the parameter is declared inconsistently
+ across different systems, sometimes as "char *" and sometimes as
+ "const char *" */
+
+#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__)
+extern char *basename PARAMS ((const char *));
+#else
+extern char *basename ();
+#endif
+
+/* Concatenate an arbitrary number of strings, up to (char *) NULL.
+ Allocates memory using xmalloc. */
+
+extern char *concat PARAMS ((const char *, ...));
+
+/* Check whether two file descriptors refer to the same file. */
+
+extern int fdmatch PARAMS ((int fd1, int fd2));
+
+/* Get the amount of time the process has run, in microseconds. */
+
+extern long get_run_time PARAMS ((void));
+
+/* Choose a temporary directory to use for scratch files. */
+
+extern char *choose_temp_base PARAMS ((void));
+
+/* Allocate memory filled with spaces. Allocates using malloc. */
+
+extern const char *spaces PARAMS ((int count));
+
+/* Return the maximum error number for which strerror will return a
+ string. */
+
+extern int errno_max PARAMS ((void));
+
+/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
+ "EINVAL"). */
+
+extern const char *strerrno PARAMS ((int));
+
+/* Given the name of an errno value, return the value. */
+
+extern int strtoerrno PARAMS ((const char *));
+
+/* ANSI's strerror(), but more robust. */
+
+extern char *xstrerror PARAMS ((int));
+
+/* Return the maximum signal number for which strsignal will return a
+ string. */
+
+extern int signo_max PARAMS ((void));
+
+/* Return a signal message string for a signal number
+ (e.g., strsignal (SIGHUP) returns something like "Hangup"). */
+/* This is commented out as it can conflict with one in system headers.
+ We still document its existence though. */
+
+/*extern const char *strsignal PARAMS ((int));*/
+
+/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
+ "SIGHUP"). */
+
+extern const char *strsigno PARAMS ((int));
+
+/* Given the name of a signal, return its number. */
+
+extern int strtosigno PARAMS ((const char *));
+
+/* Register a function to be run by xexit. Returns 0 on success. */
+
+extern int xatexit PARAMS ((void (*fn) (void)));
+
+/* Exit, calling all the functions registered with xatexit. */
+
+#ifndef __GNUC__
+extern void xexit PARAMS ((int status));
+#else
+void xexit PARAMS ((int status)) __attribute__ ((noreturn));
+#endif
+
+/* Set the program name used by xmalloc. */
+
+extern void xmalloc_set_program_name PARAMS ((const char *));
+
+/* Allocate memory without fail. If malloc fails, this will print a
+ message to stderr (using the name set by xmalloc_set_program_name,
+ if any) and then call xexit. */
+
+#ifdef ANSI_PROTOTYPES
+/* Get a definition for size_t. */
+#include <stddef.h>
+#endif
+extern PTR xmalloc PARAMS ((size_t));
+
+/* Reallocate memory without fail. This works like xmalloc.
+
+ FIXME: We do not declare the parameter types for the same reason as
+ xmalloc. */
+
+extern PTR xrealloc PARAMS ((PTR, size_t));
+
+/* Allocate memory without fail and set it to zero. This works like
+ xmalloc. */
+
+extern PTR xcalloc PARAMS ((size_t, size_t));
+
+/* Copy a string into a memory buffer without fail. */
+
+extern char *xstrdup PARAMS ((const char *));
+
+/* hex character manipulation routines */
+
+#define _hex_array_size 256
+#define _hex_bad 99
+extern char _hex_value[_hex_array_size];
+extern void hex_init PARAMS ((void));
+#define hex_p(c) (hex_value (c) != _hex_bad)
+/* If you change this, note well: Some code relies on side effects in
+ the argument being performed exactly once. */
+#define hex_value(c) (_hex_value[(unsigned char) (c)])
+
+/* Definitions used by the pexecute routine. */
+
+#define PEXECUTE_FIRST 1
+#define PEXECUTE_LAST 2
+#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
+#define PEXECUTE_SEARCH 4
+#define PEXECUTE_VERBOSE 8
+
+/* Execute a program. */
+
+extern int pexecute PARAMS ((const char *, char * const *, const char *,
+ const char *, char **, char **, int));
+
+/* Wait for pexecute to finish. */
+
+extern int pwait PARAMS ((int, int *, int));
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* ! defined (LIBIBERTY_H) */
diff --git a/pstack/linuxthreads.c b/pstack/linuxthreads.c
new file mode 100644
index 00000000000..8624bd21782
--- /dev/null
+++ b/pstack/linuxthreads.c
@@ -0,0 +1,90 @@
+/* $Header$ */
+
+/*
+ * LinuxThreads specific stuff.
+ */
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <limits.h> /* PTHREAD_THREADS_MAX */
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sched.h>
+
+#include "linuxthreads.h"
+
+#define AT_INT(intval) *((int32_t*)(intval))
+
+/*
+ * Internal LinuxThreads variables.
+ * Official interface exposed to GDB.
+ */
+#if 1
+extern volatile int __pthread_threads_debug;
+extern volatile char __pthread_handles;
+extern char __pthread_initial_thread;
+/*extern volatile Elf32_Sym* __pthread_manager_thread;*/
+extern const int __pthread_sizeof_handle;
+extern const int __pthread_offsetof_descr;
+extern const int __pthread_offsetof_pid;
+extern volatile int __pthread_handles_num;
+#endif /* 0 */
+
+/*
+ * Notify others.
+ */
+int
+linuxthreads_notify_others( const int signotify)
+{
+ const pid_t mypid = getpid();
+ //const pthread_t mytid = pthread_self();
+ int i;
+ int threadcount = 0;
+ int threads[PTHREAD_THREADS_MAX];
+ int pid;
+
+ TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num));
+ if (__pthread_handles_num==2) {
+ /* no threads beside the initial thread */
+ return 0;
+ }
+ /*assert(maxthreads>=3);
+ assert(maxthreads>=__pthread_handles_num+2);*/
+
+ // take the initial thread with us
+ pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid);
+ if (pid!=mypid && pid!=0)
+ threads[threadcount++] = pid;
+ // don't know why, but always handles[0]==handles[1]
+ for (i=1; i<__pthread_handles_num; ++i) {
+ const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr);
+ assert(descr!=0);
+ pid = AT_INT(descr+__pthread_offsetof_pid);
+ if (pid!=mypid && pid!=0)
+ threads[threadcount++] = pid;
+ }
+ /* TRACE_FPRINTF((stderr, "Stopping threads...")); */
+ //for (i=0; i<threadcount; ++i) {
+ // /* TRACE_FPRINTF((stderr, "%d ", threads[i])); */
+ // fflush(stdout);
+ // kill(threads[i], SIGSTOP); /* Tell thread to stop */
+ //}
+ /* TRACE_FPRINTF((stderr, " done!\n")); */
+ for (i=0; i<threadcount; ++i) {
+ TRACE_FPRINTF((stderr, "--- NOTIFYING %d\n", threads[i]));
+ kill(threads[i], signotify); /* Tell to print stack trace */
+ /* TRACE_FPRINTF((stderr, "--- WAITING FOR %d\n", threads[i])); */
+ /*pause(); Wait for confirmation. */
+ }
+ for (i=0; i<threadcount; ++i)
+ sched_yield();
+ for (i=0; i<threadcount; ++i) {
+ TRACE_FPRINTF((stderr, "--- KILLING %d\n", threads[i]));
+ kill(threads[i], SIGKILL); /* Tell thread die :) */
+ }
+ return __pthread_handles_num;
+}
+
diff --git a/pstack/linuxthreads.h b/pstack/linuxthreads.h
new file mode 100644
index 00000000000..f5eb0f652d8
--- /dev/null
+++ b/pstack/linuxthreads.h
@@ -0,0 +1,28 @@
+/* $Header$ */
+
+/*
+ * LinuxThreads specific stuff.
+ */
+
+#ifndef pstack_linuxthreads_h_
+#define pstack_linuxthreads_h_
+
+#include <pthread.h>
+#include "pstacktrace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Tell other threads to dump stacks...
+ */
+int
+linuxthreads_notify_others( const int signotify);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pstack_linuxthreads_h_ */
+
diff --git a/pstack/pstack.c b/pstack/pstack.c
new file mode 100644
index 00000000000..48280d4aedb
--- /dev/null
+++ b/pstack/pstack.c
@@ -0,0 +1,2745 @@
+/*
+ pstack.c -- asynchronous stack trace of a running process
+ Copyright (c) 1999 Ross Thompson
+ Author: Ross Thompson <ross@whatsis.com>
+ Critical bug fix: Tim Waugh
+*/
+
+/*
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* RESTRICTIONS:
+
+ pstack currently works only on Linux, only on an x86 machine running
+ 32 bit ELF binaries (64 bit not supported). Also, for symbolic
+ information, you need to use a GNU compiler to generate your
+ program, and you can't strip symbols from the binaries. For thread
+ information to be dumped, you have to use the debug-aware version
+ of libpthread.so. (To check, run 'nm' on your libpthread.so, and
+ make sure that the symbol "__pthread_threads_debug" is defined.)
+
+ The details of pulling stuff out of ELF files and running through
+ program images is very platform specific, and I don't want to
+ try to support modes or machine types I can't test in or on.
+ If someone wants to generalize this to other architectures, I would
+ be happy to help and coordinate the activity. Please send me whatever
+ changes you make to support these machines, so that I can own the
+ central font of all truth (at least as regards this program).
+
+ Thanks
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include <assert.h>
+#include <fcntl.h>
+#include <link.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <pthread.h>
+#include <limits.h> /* PTHREAD_THREADS_MAX */
+
+
+#include <bfd.h>
+
+#include "libiberty.h"
+
+#include "pstack.h" /* just one function */
+#include "budbg.h" /* binutils stuff related to debugging symbols. */
+#include "bucomm.h" /* some common stuff */
+#include "debug.h" /* and more binutils stuff... */
+#include "budbg.h"
+#include "linuxthreads.h" /* LinuxThreads specific stuff... */
+
+
+/*
+ * fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)(
+ * due to malloc's unavalaibility.
+ */
+int
+fdprintf( int fd,
+ const char* fmt,...)
+{
+ char xbuf[2048];// FIXME: enough?
+ va_list ap;
+ int r;
+ if (fd<0)
+ return -1;
+ va_start(ap, fmt);
+ r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap);
+ va_end(ap);
+ return write(fd, xbuf, r);
+}
+
+int
+fdputc( char c,
+ int fd)
+{
+ if (fd<0)
+ return -1;
+ return write(fd, &c, sizeof(c));
+}
+
+int
+fdputs( const char* s,
+ int fd)
+{
+ if (fd<0)
+ return -1;
+ return write(fd, s, strlen(s));
+}
+
+/*
+ * Use this function to open log file.
+ * Flags: truncate on opening.
+ */
+static const char* path_format = "stack-trace-on-segv-%d.txt";
+static int
+open_log_file( const pthread_t tid,
+ const pid_t pid)
+{
+ char fname[PATH_MAX];
+ int r;
+ snprintf(fname, sizeof(fname), path_format, tid, pid);
+ r = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR|S_IWUSR);
+ if (r<0)
+ perror("open");
+ return r;
+}
+/*
+ * Add additional debugging information for functions.
+ */
+
+/*
+ * Lineno
+ */
+typedef struct {
+ int lineno;
+ bfd_vma addr;
+} debug_lineno_t;
+
+/*
+ * Block - a {} pair.
+ */
+typedef struct debug_block_st {
+ bfd_vma begin_addr; /* where did it start */
+ bfd_vma end_addr; /* where did it end */
+ struct debug_block_st* parent;
+ struct debug_block_st* childs;
+ int childs_count;
+} debug_block_t;
+
+/*
+ * Function parameter.
+ */
+typedef struct {
+ bfd_vma offset; /* Offset in the stack */
+ const char* name; /* And name. */
+} debug_parameter_t;
+
+/*
+ * Extra information about functions.
+ */
+typedef struct {
+ asymbol* symbol; /* mangled function name, addr */
+ debug_lineno_t* lines;
+ int lines_count;
+ int max_lines_count;
+ const char* name;
+ const char* filename;/* a file name it occured in... */
+ debug_block_t* block; /* each function has a block, or not, you know */
+ debug_parameter_t* argv; /* argument types. */
+ int argc;
+ int max_argc;
+} debug_function_t;
+
+/* This is the structure we use as a handle for these routines. */
+struct pr_handle
+{
+ /* File to print information to. */
+ FILE *f;
+ /* Current indentation level. */
+ unsigned int indent;
+ /* Type stack. */
+ struct pr_stack *stack;
+ /* Parameter number we are about to output. */
+ int parameter;
+ debug_block_t* block; /* current block */
+ debug_function_t* function; /* current function */
+ debug_function_t* functions; /* all functions */
+ int functions_size; /* current size */
+ int functions_maxsize; /* maximum size */
+};
+
+/* The type stack. */
+
+struct pr_stack
+{
+ /* Next element on the stack. */
+ struct pr_stack *next;
+ /* This element. */
+ char *type;
+ /* Current visibility of fields if this is a class. */
+ enum debug_visibility visibility;
+ /* Name of the current method we are handling. */
+ const char *method;
+};
+
+static void indent PARAMS ((struct pr_handle *));
+static boolean push_type PARAMS ((struct pr_handle *, const char *));
+static boolean prepend_type PARAMS ((struct pr_handle *, const char *));
+static boolean append_type PARAMS ((struct pr_handle *, const char *));
+static boolean substitute_type PARAMS ((struct pr_handle *, const char *));
+static boolean indent_type PARAMS ((struct pr_handle *));
+static char *pop_type PARAMS ((struct pr_handle *));
+static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
+static boolean pr_fix_visibility
+ PARAMS ((struct pr_handle *, enum debug_visibility));
+
+static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
+static boolean pr_start_source PARAMS ((PTR, const char *));
+static boolean pr_empty_type PARAMS ((PTR));
+static boolean pr_void_type PARAMS ((PTR));
+static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
+static boolean pr_float_type PARAMS ((PTR, unsigned int));
+static boolean pr_complex_type PARAMS ((PTR, unsigned int));
+static boolean pr_bool_type PARAMS ((PTR, unsigned int));
+static boolean pr_enum_type
+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
+static boolean pr_pointer_type PARAMS ((PTR));
+static boolean pr_function_type PARAMS ((PTR, int, boolean));
+static boolean pr_reference_type PARAMS ((PTR));
+static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+static boolean pr_array_type
+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
+static boolean pr_set_type PARAMS ((PTR, boolean));
+static boolean pr_offset_type PARAMS ((PTR));
+static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
+static boolean pr_const_type PARAMS ((PTR));
+static boolean pr_volatile_type PARAMS ((PTR));
+static boolean pr_start_struct_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
+static boolean pr_struct_field
+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
+static boolean pr_end_struct_type PARAMS ((PTR));
+static boolean pr_start_class_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
+ boolean));
+static boolean pr_class_static_member
+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
+static boolean pr_class_baseclass
+ PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
+static boolean pr_class_start_method PARAMS ((PTR, const char *));
+static boolean pr_class_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
+ bfd_vma, boolean));
+static boolean pr_class_static_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
+static boolean pr_class_end_method PARAMS ((PTR));
+static boolean pr_end_class_type PARAMS ((PTR));
+static boolean pr_typedef_type PARAMS ((PTR, const char *));
+static boolean pr_tag_type
+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
+static boolean pr_typdef PARAMS ((PTR, const char *));
+static boolean pr_tag PARAMS ((PTR, const char *));
+static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean pr_float_constant PARAMS ((PTR, const char *, double));
+static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean pr_variable
+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
+static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
+static boolean pr_function_parameter
+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
+static boolean pr_start_block PARAMS ((PTR, bfd_vma));
+static boolean pr_end_block PARAMS ((PTR, bfd_vma));
+static boolean pr_end_function PARAMS ((PTR));
+static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+
+static const struct debug_write_fns pr_fns =
+{
+ pr_start_compilation_unit,
+ pr_start_source,
+ pr_empty_type,
+ pr_void_type,
+ pr_int_type,
+ pr_float_type,
+ pr_complex_type,
+ pr_bool_type,
+ pr_enum_type,
+ pr_pointer_type,
+ pr_function_type,
+ pr_reference_type,
+ pr_range_type,
+ pr_array_type,
+ pr_set_type,
+ pr_offset_type,
+ pr_method_type,
+ pr_const_type,
+ pr_volatile_type,
+ pr_start_struct_type,
+ pr_struct_field,
+ pr_end_struct_type,
+ pr_start_class_type,
+ pr_class_static_member,
+ pr_class_baseclass,
+ pr_class_start_method,
+ pr_class_method_variant,
+ pr_class_static_method_variant,
+ pr_class_end_method,
+ pr_end_class_type,
+ pr_typedef_type,
+ pr_tag_type,
+ pr_typdef,
+ pr_tag,
+ pr_int_constant,
+ pr_float_constant,
+ pr_typed_constant,
+ pr_variable,
+ pr_start_function,
+ pr_function_parameter,
+ pr_start_block,
+ pr_end_block,
+ pr_end_function,
+ pr_lineno
+};
+
+
+/* Indent to the current indentation level. */
+
+static void
+indent (info)
+ struct pr_handle *info;
+{
+ unsigned int i;
+
+ for (i = 0; i < info->indent; i++)
+ TRACE_PUTC ((' ', info->f));
+}
+
+/* Push a type on the type stack. */
+
+static boolean
+push_type (info, type)
+ struct pr_handle *info;
+ const char *type;
+{
+ struct pr_stack *n;
+
+ if (type == NULL)
+ return false;
+
+ n = (struct pr_stack *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = xstrdup (type);
+ n->visibility = DEBUG_VISIBILITY_IGNORE;
+ n->method = NULL;
+ n->next = info->stack;
+ info->stack = n;
+
+ return true;
+}
+
+/* Prepend a string onto the type on the top of the type stack. */
+
+static boolean
+prepend_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ char *n;
+
+ assert (info->stack != NULL);
+
+ n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
+ sprintf (n, "%s%s", s, info->stack->type);
+ free (info->stack->type);
+ info->stack->type = n;
+
+ return true;
+}
+
+/* Append a string to the type on the top of the type stack. */
+
+static boolean
+append_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ unsigned int len;
+
+ if (s == NULL)
+ return false;
+
+ assert (info->stack != NULL);
+
+ len = strlen (info->stack->type);
+ info->stack->type = (char *) xrealloc (info->stack->type,
+ len + strlen (s) + 1);
+ strcpy (info->stack->type + len, s);
+
+ return true;
+}
+
+/* We use an underscore to indicate where the name should go in a type
+ string. This function substitutes a string for the underscore. If
+ there is no underscore, the name follows the type. */
+
+static boolean
+substitute_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ char *u;
+
+ assert (info->stack != NULL);
+
+ u = strchr (info->stack->type, '|');
+ if (u != NULL)
+ {
+ char *n;
+
+ n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
+
+ memcpy (n, info->stack->type, u - info->stack->type);
+ strcpy (n + (u - info->stack->type), s);
+ strcat (n, u + 1);
+
+ free (info->stack->type);
+ info->stack->type = n;
+
+ return true;
+ }
+
+ if (strchr (s, '|') != NULL
+ && (strchr (info->stack->type, '{') != NULL
+ || strchr (info->stack->type, '(') != NULL))
+ {
+ if (! prepend_type (info, "(")
+ || ! append_type (info, ")"))
+ return false;
+ }
+
+ if (*s == '\0')
+ return true;
+
+ return (append_type (info, " ")
+ && append_type (info, s));
+}
+
+/* Indent the type at the top of the stack by appending spaces. */
+
+static boolean
+indent_type (info)
+ struct pr_handle *info;
+{
+ unsigned int i;
+
+ for (i = 0; i < info->indent; i++)
+ {
+ if (! append_type (info, " "))
+ return false;
+ }
+
+ return true;
+}
+
+/* Pop a type from the type stack. */
+
+static char *
+pop_type (info)
+ struct pr_handle *info;
+{
+ struct pr_stack *o;
+ char *ret;
+
+ assert (info->stack != NULL);
+
+ o = info->stack;
+ info->stack = o->next;
+ ret = o->type;
+ free (o);
+
+ return ret;
+}
+
+/* Print a VMA value into a string. */
+
+static void
+print_vma (vma, buf, unsignedp, hexp)
+ bfd_vma vma;
+ char *buf;
+ boolean unsignedp;
+ boolean hexp;
+{
+ if (sizeof (vma) <= sizeof (unsigned long))
+ {
+ if (hexp)
+ sprintf (buf, "0x%lx", (unsigned long) vma);
+ else if (unsignedp)
+ sprintf (buf, "%lu", (unsigned long) vma);
+ else
+ sprintf (buf, "%ld", (long) vma);
+ }
+ else
+ {
+ buf[0] = '0';
+ buf[1] = 'x';
+ sprintf_vma (buf + 2, vma);
+ }
+}
+
+/* Start a new compilation unit. */
+
+static boolean
+pr_start_compilation_unit (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->indent == 0);
+/*
+ TRACE_FPRINTF( (info->f, "%s:\n", filename));
+*/
+ return true;
+}
+
+/* Start a source file within a compilation unit. */
+
+static boolean
+pr_start_source (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->indent == 0);
+/*
+ TRACE_FPRINTF( (info->f, " %s:\n", filename));
+*/
+ return true;
+}
+
+/* Push an empty type onto the type stack. */
+
+static boolean
+pr_empty_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, "<undefined>");
+}
+
+/* Push a void type onto the type stack. */
+
+static boolean
+pr_void_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, "void");
+}
+
+/* Push an integer type onto the type stack. */
+
+static boolean
+pr_int_type (p, size, unsignedp)
+ PTR p;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
+ return push_type (info, ab);
+}
+
+/* Push a floating type onto the type stack. */
+
+static boolean
+pr_float_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ if (size == 4)
+ return push_type (info, "float");
+ else if (size == 8)
+ return push_type (info, "double");
+
+ sprintf (ab, "float%d", size * 8);
+ return push_type (info, ab);
+}
+
+/* Push a complex type onto the type stack. */
+
+static boolean
+pr_complex_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ if (! pr_float_type (p, size))
+ return false;
+
+ return prepend_type (info, "complex ");
+}
+
+/* Push a boolean type onto the type stack. */
+
+static boolean
+pr_bool_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ sprintf (ab, "bool%d", size * 8);
+
+ return push_type (info, ab);
+}
+
+/* Push an enum type onto the type stack. */
+
+static boolean
+pr_enum_type (p, tag, names, values)
+ PTR p;
+ const char *tag;
+ const char **names;
+ bfd_signed_vma *values;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ unsigned int i;
+ bfd_signed_vma val;
+
+ if (! push_type (info, "enum "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag)
+ || ! append_type (info, " "))
+ return false;
+ }
+ if (! append_type (info, "{ "))
+ return false;
+
+ if (names == NULL)
+ {
+ if (! append_type (info, "/* undefined */"))
+ return false;
+ }
+ else
+ {
+ val = 0;
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (i > 0)
+ {
+ if (! append_type (info, ", "))
+ return false;
+ }
+
+ if (! append_type (info, names[i]))
+ return false;
+
+ if (values[i] != val)
+ {
+ char ab[20];
+
+ print_vma (values[i], ab, false, false);
+ if (! append_type (info, " = ")
+ || ! append_type (info, ab))
+ return false;
+ val = values[i];
+ }
+
+ ++val;
+ }
+ }
+
+ return append_type (info, " }");
+}
+
+/* Turn the top type on the stack into a pointer. */
+
+static boolean
+pr_pointer_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ assert (info->stack != NULL);
+
+ s = strchr (info->stack->type, '|');
+ if (s != NULL && s[1] == '[')
+ return substitute_type (info, "(*|)");
+ return substitute_type (info, "*|");
+}
+
+/* Turn the top type on the stack into a function returning that type. */
+
+static boolean
+pr_function_type (p, argcount, varargs)
+ PTR p;
+ int argcount;
+ boolean varargs;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char **arg_types;
+ unsigned int len;
+ char *s;
+
+ assert (info->stack != NULL);
+
+ len = 10;
+
+ if (argcount <= 0)
+ {
+ arg_types = NULL;
+ len += 15;
+ }
+ else
+ {
+ int i;
+
+ arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ arg_types[i] = pop_type (info);
+ if (arg_types[i] == NULL)
+ return false;
+ len += strlen (arg_types[i]) + 2;
+ }
+ if (varargs)
+ len += 5;
+ }
+
+ /* Now the return type is on the top of the stack. */
+
+ s = (char *) xmalloc (len);
+ strcpy (s, "(|) (");
+
+ if (argcount < 0)
+ {
+#if 0
+ /* Turn off unknown arguments. */
+ strcat (s, "/* unknown */");
+#endif
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < argcount; i++)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, arg_types[i]);
+ }
+ if (varargs)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, "...");
+ }
+ if (argcount > 0)
+ free (arg_types);
+ }
+
+ strcat (s, ")");
+
+ if (! substitute_type (info, s))
+ return false;
+
+ free (s);
+
+ return true;
+}
+
+/* Turn the top type on the stack into a reference to that type. */
+
+static boolean
+pr_reference_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->stack != NULL);
+
+ return substitute_type (info, "&|");
+}
+
+/* Make a range type. */
+
+static boolean
+pr_range_type (p, lower, upper)
+ PTR p;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char abl[20], abu[20];
+
+ assert (info->stack != NULL);
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ print_vma (lower, abl, false, false);
+ print_vma (upper, abu, false, false);
+
+ return (prepend_type (info, "range (")
+ && append_type (info, "):")
+ && append_type (info, abl)
+ && append_type (info, ":")
+ && append_type (info, abu));
+}
+
+/* Make an array type. */
+
+/*ARGSUSED*/
+static boolean
+pr_array_type (p, lower, upper, stringp)
+ PTR p;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+ boolean stringp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *range_type;
+ char abl[20], abu[20], ab[50];
+
+ range_type = pop_type (info);
+ if (range_type == NULL)
+ return false;
+
+ if (lower == 0)
+ {
+ if (upper == -1)
+ sprintf (ab, "|[]");
+ else
+ {
+ print_vma (upper + 1, abu, false, false);
+ sprintf (ab, "|[%s]", abu);
+ }
+ }
+ else
+ {
+ print_vma (lower, abl, false, false);
+ print_vma (upper, abu, false, false);
+ sprintf (ab, "|[%s:%s]", abl, abu);
+ }
+
+ if (! substitute_type (info, ab))
+ return false;
+
+ if (strcmp (range_type, "int") != 0)
+ {
+ if (! append_type (info, ":")
+ || ! append_type (info, range_type))
+ return false;
+ }
+
+ if (stringp)
+ {
+ if (! append_type (info, " /* string */"))
+ return false;
+ }
+
+ return true;
+}
+
+/* Make a set type. */
+
+/*ARGSUSED*/
+static boolean
+pr_set_type (p, bitstringp)
+ PTR p;
+ boolean bitstringp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ if (! prepend_type (info, "set { ")
+ || ! append_type (info, " }"))
+ return false;
+
+ if (bitstringp)
+ {
+ if (! append_type (info, "/* bitstring */"))
+ return false;
+ }
+
+ return true;
+}
+
+/* Make an offset type. */
+
+static boolean
+pr_offset_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ return (substitute_type (info, "")
+ && prepend_type (info, " ")
+ && prepend_type (info, t)
+ && append_type (info, "::|"));
+}
+
+/* Make a method type. */
+
+static boolean
+pr_method_type (p, domain, argcount, varargs)
+ PTR p;
+ boolean domain;
+ int argcount;
+ boolean varargs;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ unsigned int len;
+ char *domain_type;
+ char **arg_types;
+ char *s;
+
+ len = 10;
+
+ if (! domain)
+ domain_type = NULL;
+ else
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ domain_type = pop_type (info);
+ if (domain_type == NULL)
+ return false;
+ if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
+ && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
+ domain_type += sizeof "class " - 1;
+ else if (strncmp (domain_type, "union class ",
+ sizeof "union class ") == 0
+ && (strchr (domain_type + sizeof "union class " - 1, ' ')
+ == NULL))
+ domain_type += sizeof "union class " - 1;
+ len += strlen (domain_type);
+ }
+
+ if (argcount <= 0)
+ {
+ arg_types = NULL;
+ len += 15;
+ }
+ else
+ {
+ int i;
+
+ arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ arg_types[i] = pop_type (info);
+ if (arg_types[i] == NULL)
+ return false;
+ len += strlen (arg_types[i]) + 2;
+ }
+ if (varargs)
+ len += 5;
+ }
+
+ /* Now the return type is on the top of the stack. */
+
+ s = (char *) xmalloc (len);
+ if (! domain)
+ *s = '\0';
+ else
+ strcpy (s, domain_type);
+ strcat (s, "::| (");
+
+ if (argcount < 0)
+ strcat (s, "/* unknown */");
+ else
+ {
+ int i;
+
+ for (i = 0; i < argcount; i++)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, arg_types[i]);
+ }
+ if (varargs)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, "...");
+ }
+ if (argcount > 0)
+ free (arg_types);
+ }
+
+ strcat (s, ")");
+
+ if (! substitute_type (info, s))
+ return false;
+
+ free (s);
+
+ return true;
+}
+
+/* Make a const qualified type. */
+
+static boolean
+pr_const_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return substitute_type (info, "const |");
+}
+
+/* Make a volatile qualified type. */
+
+static boolean
+pr_volatile_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return substitute_type (info, "volatile |");
+}
+
+/* Start accumulating a struct type. */
+
+static boolean
+pr_start_struct_type (p, tag, id, structp, size)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ info->indent += 2;
+
+ if (! push_type (info, structp ? "struct " : "union "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag))
+ return false;
+ }
+ else
+ {
+ char idbuf[20];
+
+ sprintf (idbuf, "%%anon%u", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ if (! append_type (info, " {"))
+ return false;
+ if (size != 0 || tag != NULL)
+ {
+ char ab[30];
+
+ if (! append_type (info, " /*"))
+ return false;
+
+ if (size != 0)
+ {
+ sprintf (ab, " size %u", size);
+ if (! append_type (info, ab))
+ return false;
+ }
+ if (tag != NULL)
+ {
+ sprintf (ab, " id %u", id);
+ if (! append_type (info, ab))
+ return false;
+ }
+ if (! append_type (info, " */"))
+ return false;
+ }
+ if (! append_type (info, "\n"))
+ return false;
+
+ info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
+
+ return indent_type (info);
+}
+
+/* Output the visibility of a field in a struct. */
+
+static boolean
+pr_fix_visibility (info, visibility)
+ struct pr_handle *info;
+ enum debug_visibility visibility;
+{
+ const char *s;
+ char *t;
+ unsigned int len;
+
+ assert (info->stack != NULL);
+
+ if (info->stack->visibility == visibility)
+ return true;
+
+ assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
+
+ switch (visibility)
+ {
+ case DEBUG_VISIBILITY_PUBLIC:
+ s = "public";
+ break;
+ case DEBUG_VISIBILITY_PRIVATE:
+ s = "private";
+ break;
+ case DEBUG_VISIBILITY_PROTECTED:
+ s = "protected";
+ break;
+ case DEBUG_VISIBILITY_IGNORE:
+ s = "/* ignore */";
+ break;
+ default:
+ abort ();
+ return false;
+ }
+
+ /* Trim off a trailing space in the struct string, to make the
+ output look a bit better, then stick on the visibility string. */
+
+ t = info->stack->type;
+ len = strlen (t);
+ assert (t[len - 1] == ' ');
+ t[len - 1] = '\0';
+
+ if (! append_type (info, s)
+ || ! append_type (info, ":\n")
+ || ! indent_type (info))
+ return false;
+
+ info->stack->visibility = visibility;
+
+ return true;
+}
+
+/* Add a field to a struct type. */
+
+static boolean
+pr_struct_field (p, name, bitpos, bitsize, visibility)
+ PTR p;
+ const char *name;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ if (! append_type (info, "; /* "))
+ return false;
+
+ if (bitsize != 0)
+ {
+ print_vma (bitsize, ab, true, false);
+ if (! append_type (info, "bitsize ")
+ || ! append_type (info, ab)
+ || ! append_type (info, ", "))
+ return false;
+ }
+
+ print_vma (bitpos, ab, true, false);
+ if (! append_type (info, "bitpos ")
+ || ! append_type (info, ab)
+ || ! append_type (info, " */\n")
+ || ! indent_type (info))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return append_type (info, t);
+}
+
+/* Finish a struct type. */
+
+static boolean
+pr_end_struct_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ assert (info->stack != NULL);
+ assert (info->indent >= 2);
+
+ info->indent -= 2;
+
+ /* Change the trailing indentation to have a close brace. */
+ s = info->stack->type + strlen (info->stack->type) - 2;
+ assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
+
+ *s++ = '}';
+ *s = '\0';
+
+ return true;
+}
+
+/* Start a class type. */
+
+static boolean
+pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+ boolean vptr;
+ boolean ownvptr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *tv = NULL;
+
+ info->indent += 2;
+
+ if (vptr && ! ownvptr)
+ {
+ tv = pop_type (info);
+ if (tv == NULL)
+ return false;
+ }
+
+ if (! push_type (info, structp ? "class " : "union class "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag))
+ return false;
+ }
+ else
+ {
+ char idbuf[20];
+
+ sprintf (idbuf, "%%anon%u", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ if (! append_type (info, " {"))
+ return false;
+ if (size != 0 || vptr || ownvptr || tag != NULL)
+ {
+ if (! append_type (info, " /*"))
+ return false;
+
+ if (size != 0)
+ {
+ char ab[20];
+
+ sprintf (ab, "%u", size);
+ if (! append_type (info, " size ")
+ || ! append_type (info, ab))
+ return false;
+ }
+
+ if (vptr)
+ {
+ if (! append_type (info, " vtable "))
+ return false;
+ if (ownvptr)
+ {
+ if (! append_type (info, "self "))
+ return false;
+ }
+ else
+ {
+ if (! append_type (info, tv)
+ || ! append_type (info, " "))
+ return false;
+ }
+ }
+
+ if (tag != NULL)
+ {
+ char ab[30];
+
+ sprintf (ab, " id %u", id);
+ if (! append_type (info, ab))
+ return false;
+ }
+
+ if (! append_type (info, " */"))
+ return false;
+ }
+
+ info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
+
+ return (append_type (info, "\n")
+ && indent_type (info));
+}
+
+/* Add a static member to a class. */
+
+static boolean
+pr_class_static_member (p, name, physname, visibility)
+ PTR p;
+ const char *name;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ if (! prepend_type (info, "static ")
+ || ! append_type (info, "; /* ")
+ || ! append_type (info, physname)
+ || ! append_type (info, " */\n")
+ || ! indent_type (info))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return append_type (info, t);
+}
+
+/* Add a base class to a class. */
+
+static boolean
+pr_class_baseclass (p, bitpos, virtual, visibility)
+ PTR p;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ const char *prefix;
+ char ab[20];
+ char *s, *l, *n;
+
+ assert (info->stack != NULL && info->stack->next != NULL);
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (strncmp (t, "class ", sizeof "class " - 1) == 0)
+ t += sizeof "class " - 1;
+
+ /* Push it back on to take advantage of the prepend_type and
+ append_type routines. */
+ if (! push_type (info, t))
+ return false;
+
+ if (virtual)
+ {
+ if (! prepend_type (info, "virtual "))
+ return false;
+ }
+
+ switch (visibility)
+ {
+ case DEBUG_VISIBILITY_PUBLIC:
+ prefix = "public ";
+ break;
+ case DEBUG_VISIBILITY_PROTECTED:
+ prefix = "protected ";
+ break;
+ case DEBUG_VISIBILITY_PRIVATE:
+ prefix = "private ";
+ break;
+ default:
+ prefix = "/* unknown visibility */ ";
+ break;
+ }
+
+ if (! prepend_type (info, prefix))
+ return false;
+
+ if (bitpos != 0)
+ {
+ print_vma (bitpos, ab, true, false);
+ if (! append_type (info, " /* bitpos ")
+ || ! append_type (info, ab)
+ || ! append_type (info, " */"))
+ return false;
+ }
+
+ /* Now the top of the stack is something like "public A / * bitpos
+ 10 * /". The next element on the stack is something like "class
+ xx { / * size 8 * /\n...". We want to substitute the top of the
+ stack in before the {. */
+ s = strchr (info->stack->next->type, '{');
+ assert (s != NULL);
+ --s;
+
+ /* If there is already a ':', then we already have a baseclass, and
+ we must append this one after a comma. */
+ for (l = info->stack->next->type; l != s; l++)
+ if (*l == ':')
+ break;
+ if (! prepend_type (info, l == s ? " : " : ", "))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
+ memcpy (n, info->stack->type, s - info->stack->type);
+ strcpy (n + (s - info->stack->type), t);
+ strcat (n, s);
+
+ free (info->stack->type);
+ info->stack->type = n;
+
+ free (t);
+
+ return true;
+}
+
+/* Start adding a method to a class. */
+
+static boolean
+pr_class_start_method (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->stack != NULL);
+ info->stack->method = name;
+ return true;
+}
+
+/* Add a variant to a method. */
+
+static boolean
+pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
+ context)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *method_type;
+ char *context_type;
+
+ assert (info->stack != NULL);
+ assert (info->stack->next != NULL);
+
+ /* Put the const and volatile qualifiers on the type. */
+ if (volatilep)
+ {
+ if (! append_type (info, " volatile"))
+ return false;
+ }
+ if (constp)
+ {
+ if (! append_type (info, " const"))
+ return false;
+ }
+
+ /* Stick the name of the method into its type. */
+ if (! substitute_type (info,
+ (context
+ ? info->stack->next->next->method
+ : info->stack->next->method)))
+ return false;
+
+ /* Get the type. */
+ method_type = pop_type (info);
+ if (method_type == NULL)
+ return false;
+
+ /* Pull off the context type if there is one. */
+ if (! context)
+ context_type = NULL;
+ else
+ {
+ context_type = pop_type (info);
+ if (context_type == NULL)
+ return false;
+ }
+
+ /* Now the top of the stack is the class. */
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ if (! append_type (info, method_type)
+ || ! append_type (info, " /* ")
+ || ! append_type (info, physname)
+ || ! append_type (info, " "))
+ return false;
+ if (context || voffset != 0)
+ {
+ char ab[20];
+
+ if (context)
+ {
+ if (! append_type (info, "context ")
+ || ! append_type (info, context_type)
+ || ! append_type (info, " "))
+ return false;
+ }
+ print_vma (voffset, ab, true, false);
+ if (! append_type (info, "voffset ")
+ || ! append_type (info, ab))
+ return false;
+ }
+
+ return (append_type (info, " */;\n")
+ && indent_type (info));
+}
+
+/* Add a static variant to a method. */
+
+static boolean
+pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *method_type;
+
+ assert (info->stack != NULL);
+ assert (info->stack->next != NULL);
+ assert (info->stack->next->method != NULL);
+
+ /* Put the const and volatile qualifiers on the type. */
+ if (volatilep)
+ {
+ if (! append_type (info, " volatile"))
+ return false;
+ }
+ if (constp)
+ {
+ if (! append_type (info, " const"))
+ return false;
+ }
+
+ /* Mark it as static. */
+ if (! prepend_type (info, "static "))
+ return false;
+
+ /* Stick the name of the method into its type. */
+ if (! substitute_type (info, info->stack->next->method))
+ return false;
+
+ /* Get the type. */
+ method_type = pop_type (info);
+ if (method_type == NULL)
+ return false;
+
+ /* Now the top of the stack is the class. */
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return (append_type (info, method_type)
+ && append_type (info, " /* ")
+ && append_type (info, physname)
+ && append_type (info, " */;\n")
+ && indent_type (info));
+}
+
+/* Finish up a method. */
+
+static boolean
+pr_class_end_method (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ info->stack->method = NULL;
+ return true;
+}
+
+/* Finish up a class. */
+
+static boolean
+pr_end_class_type (p)
+ PTR p;
+{
+ return pr_end_struct_type (p);
+}
+
+/* Push a type on the stack using a typedef name. */
+
+static boolean
+pr_typedef_type (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, name);
+}
+
+/* Push a type on the stack using a tag name. */
+
+static boolean
+pr_tag_type (p, name, id, kind)
+ PTR p;
+ const char *name;
+ unsigned int id;
+ enum debug_type_kind kind;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ const char *t, *tag;
+ char idbuf[20];
+
+ switch (kind)
+ {
+ case DEBUG_KIND_STRUCT:
+ t = "struct ";
+ break;
+ case DEBUG_KIND_UNION:
+ t = "union ";
+ break;
+ case DEBUG_KIND_ENUM:
+ t = "enum ";
+ break;
+ case DEBUG_KIND_CLASS:
+ t = "class ";
+ break;
+ case DEBUG_KIND_UNION_CLASS:
+ t = "union class ";
+ break;
+ default:
+ abort ();
+ return false;
+ }
+
+ if (! push_type (info, t))
+ return false;
+ if (name != NULL)
+ tag = name;
+ else
+ {
+ sprintf (idbuf, "%%anon%u", id);
+ tag = idbuf;
+ }
+
+ if (! append_type (info, tag))
+ return false;
+ if (name != NULL && kind != DEBUG_KIND_ENUM)
+ {
+ sprintf (idbuf, " /* id %u */", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ return true;
+}
+
+/* Output a typedef. */
+
+static boolean
+pr_typdef (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ s = pop_type (info);
+ if (s == NULL)
+ return false;
+/*
+ indent (info);
+ TRACE_FPRINTF( (info->f, "typedef %s;\n", s));
+*/
+ free (s);
+
+ return true;
+}
+
+/* Output a tag. The tag should already be in the string on the
+ stack, so all we have to do here is print it out. */
+
+/*ARGSUSED*/
+static boolean
+pr_tag (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+/*
+ indent (info);
+ TRACE_FPRINTF( (info->f, "%s;\n", t));
+*/
+ free (t);
+
+ return true;
+}
+
+/* Output an integer constant. */
+
+static boolean
+pr_int_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+/*
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ indent (info);
+ print_vma (val, ab, false, false);
+ TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab));
+ */
+ return true;
+}
+
+/* Output a floating point constant. */
+
+static boolean
+pr_float_constant (p, name, val)
+ PTR p;
+ const char *name;
+ double val;
+{
+/*
+ struct pr_handle *info = (struct pr_handle *) p;
+ indent (info);
+ TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val));
+ */
+ return true;
+}
+
+/* Output a typed constant. */
+
+static boolean
+pr_typed_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+/*
+ char ab[20];
+ indent (info);
+ print_vma (val, ab, false, false);
+ TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab));
+*/
+ free (t);
+
+ return true;
+}
+
+/* Output a variable. */
+
+static boolean
+pr_variable (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ char ab[20];
+ (void)ab;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+#if 0
+ indent (info);
+ switch (kind)
+ {
+ case DEBUG_STATIC:
+ case DEBUG_LOCAL_STATIC:
+ TRACE_FPRINTF( (info->f, "static "));
+ break;
+ case DEBUG_REGISTER:
+ TRACE_FPRINTF( (info->f, "register "));
+ break;
+ default:
+ break;
+ }
+ print_vma (val, ab, true, true);
+ TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab));
+#else /* 0 */
+#if 0
+ if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) {
+ print_vma (val, ab, true, true);
+ TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab));
+ }
+#endif /* 0 */
+#endif /* !0 */
+
+ free (t);
+
+ return true;
+}
+
+/* Start outputting a function. */
+
+static boolean
+pr_start_function (p, name, global)
+ PTR p;
+ const char *name;
+ boolean global;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+#if 0
+ indent (info);
+ if (! global)
+ TRACE_FPRINTF( (info->f, "static "));
+ TRACE_FPRINTF( (info->f, "%s (", t));
+ info->parameter = 1;
+#else /* 0 */
+ if (info->functions_size==info->functions_maxsize) {
+ info->functions_maxsize *= 2;
+ info->functions = xrealloc(info->functions,
+ info->functions_maxsize*sizeof(debug_function_t));
+ assert(info->functions!=0);
+ }
+ /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */
+ info->function = &info->functions[info->functions_size];
+ ++info->functions_size;
+ info->function->symbol = NULL;
+ info->function->lines = NULL;
+ info->function->lines_count = 0;
+ info->function->max_lines_count = 0;
+ info->function->name = t;
+ info->function->filename = NULL;
+ info->function->block = NULL;
+ info->function->argv = NULL;
+ info->function->argc = 0;
+ info->function->max_argc = 0;
+#endif /* !0 */
+ return true;
+}
+
+/* Output a function parameter. */
+
+static boolean
+pr_function_parameter (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ debug_function_t* f = info->function;
+ char *t;
+ char ab[20];
+ (void)ab;
+
+ if (kind == DEBUG_PARM_REFERENCE
+ || kind == DEBUG_PARM_REF_REG)
+ {
+ if (! pr_reference_type (p))
+ return false;
+ }
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+#if 0
+ if (info->parameter != 1)
+ TRACE_FPRINTF( (info->f, ", "));
+
+ if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
+ TRACE_FPRINTF( (info->f, "register "));
+
+ print_vma (val, ab, true, true);
+ TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab));
+ free (t);
+ ++info->parameter;
+#else /* 0 */
+ assert(f!=NULL);
+ if (f->argv==NULL) {
+ f->max_argc = 7; /* rarely anyone has more than that many args... */
+ f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc);
+ } else if (f->argc==f->max_argc) {
+ f->max_argc *= 2;
+ f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc);
+ }
+ f->argv[f->argc].offset = val;
+ f->argv[f->argc].name = t;
+ ++f->argc;
+#endif /* !0 */
+ return true;
+}
+
+/* Start writing out a block. */
+
+static boolean
+pr_start_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ debug_block_t* block = 0;
+ (void)ab;
+#if 0
+ if (info->parameter > 0)
+ {
+ TRACE_FPRINTF( (info->f, ")\n"));
+ info->parameter = 0;
+ }
+ indent (info);
+ print_vma (addr, ab, true, true);
+ TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab));
+ info->indent += 2;
+#else
+ if (info->block) {
+ if (info->block->childs_count==0)
+ info->block->childs = xmalloc(sizeof(debug_block_t));
+ else
+ info->block->childs = xrealloc(info->block->childs,
+ info->block->childs_count*sizeof(debug_block_t));
+ block = &info->block->childs[info->block->childs_count];
+ } else {
+ block = xmalloc(sizeof(debug_block_t));
+ info->function->block = block;
+ }
+ block->begin_addr = addr;
+ block->end_addr = 0;
+ block->parent = info->block;
+ block->childs = NULL;
+ block->childs_count = 0;
+ info->block = block;
+#endif
+ return true;
+}
+
+/* Write out line number information. */
+
+static boolean
+pr_lineno (p, filename, lineno, addr)
+ PTR p;
+ const char *filename;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ debug_function_t* f = info->function;
+ (void)ab;
+
+#if 0
+ indent (info);
+ print_vma (addr, ab, true, true);
+ TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab));
+#else /* 0 */
+ if (f==NULL) /* FIXME: skips junk silently. */
+ return true;
+ /* assert(f!=NULL); */
+ if (f->filename==NULL) {
+ f->filename = filename;
+ assert(f->lines==0);
+ f->max_lines_count = 4;
+ f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count);
+ }
+ if (f->lines_count==f->max_lines_count) {
+ f->max_lines_count *= 2;
+ f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count);
+ }
+ f->lines[f->lines_count].lineno = lineno;
+ f->lines[f->lines_count].addr = addr;
+ ++f->lines_count;
+#endif /* !0 */
+
+ return true;
+}
+
+/* Finish writing out a block. */
+
+static boolean
+pr_end_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+#if 0
+ char ab[20];
+
+ info->indent -= 2;
+ indent (info);
+ print_vma (addr, ab, true, true);
+ TRACE_FPRINTF( (info->f, "} /* %s */\n", ab));
+#else /* 0 */
+ assert(info->block!=0);
+ info->block->end_addr = addr;
+ info->block = info->block->parent;
+#endif /* !0 */
+
+ return true;
+}
+
+/* Finish writing out a function. */
+
+/*ARGSUSED*/
+static boolean
+pr_end_function (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ assert(info->block==0);
+ info->function = NULL;
+ return true;
+}
+
+/* third parameter to segv_action. */
+/* Got it after a bit of head scratching and stack dumping. */
+typedef struct {
+ u_int32_t foo1; /* +0x00 */
+ u_int32_t foo2;
+ u_int32_t foo3;
+ u_int32_t foo4; /* usually 2 */
+ u_int32_t foo5; /* +0x10 */
+ u_int32_t xgs; /* always zero */
+ u_int32_t xfs; /* always zero */
+ u_int32_t xes; /* always es=ds=ss */
+ u_int32_t xds; /* +0x20 */
+ u_int32_t edi;
+ u_int32_t esi;
+ u_int32_t ebp;
+ u_int32_t esp; /* +0x30 */
+ u_int32_t ebx;
+ u_int32_t edx;
+ u_int32_t ecx;
+ u_int32_t eax; /* +0x40 */
+ u_int32_t foo11; /* usually 0xe */
+ u_int32_t foo12; /* usually 0x6 */
+ u_int32_t eip; /* instruction pointer */
+ u_int32_t xcs; /* +0x50 */
+ u_int32_t foo21; /* usually 0x2 */
+ u_int32_t foo22; /* second stack pointer?! Probably. */
+ u_int32_t xss;
+ u_int32_t foo31; /* +0x60 */ /* usually 0x0 */
+ u_int32_t foo32; /* usually 0x2 */
+ u_int32_t fault_addr; /* Address which caused a fault */
+ u_int32_t foo41; /* usually 0x2 */
+} signal_regs_t;
+
+signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */
+/*
+ * my_ptrace: small wrapper around ptrace.
+ * Act as normal ptrace if ptrace_regs==0.
+ * Read data from current process if ptrace_regs!=0.
+ */
+static int
+my_ptrace( int request,
+ int pid,
+ int addr,
+ int data)
+{
+ if (ptrace_regs==0)
+ return ptrace(request, pid, addr, data);
+ /* we are tracing ourselves! */
+ switch (request) {
+ case PTRACE_ATTACH: return 0;
+ case PTRACE_CONT: return 0;
+ case PTRACE_DETACH: return 0;
+ case PTRACE_PEEKUSER:
+ switch (addr / 4) {
+ case EIP: return ptrace_regs->eip;
+ case EBP: return ptrace_regs->ebp;
+ default: assert(0);
+ }
+ case PTRACE_PEEKTEXT: /* FALLTHROUGH */
+ case PTRACE_PEEKDATA: return *(int*)(addr);
+ default: assert(0);
+ }
+ errno = 1; /* what to do here? */
+ return 1; /* failed?! */
+}
+
+#define MAXARGS 6
+
+/*
+ * To minimize the number of parameters.
+ */
+typedef struct {
+ asymbol** syms; /* Sorted! */
+ int symcount;
+ debug_function_t** functions;
+ int functions_size;
+} symbol_data_t;
+
+/*
+ * Perform a search. A binary search for a symbol.
+ */
+static void
+decode_symbol( symbol_data_t* symbol_data,
+ const unsigned long addr,
+ char* buf,
+ const int bufsize)
+{
+ asymbol** syms = symbol_data->syms;
+ const int symcount = symbol_data->symcount;
+ int bottom = 0;
+ int top = symcount - 1;
+ int i;
+ if (symcount==0) {
+ sprintf(buf, "????");
+ return;
+ }
+ while (top>bottom+1) {
+ i = (top+bottom) / 2;
+ if (bfd_asymbol_value(syms[i])==addr) {
+ sprintf(buf, "%s", syms[i]->name);
+ return;
+ } else if (bfd_asymbol_value(syms[i]) > addr)
+ top = i;
+ else
+ bottom = i;
+ }
+ i = bottom;
+ if (addr<bfd_asymbol_value(syms[i]) || addr>(syms[i]->section->vma+syms[i]->section->_cooked_size))
+ sprintf(buf, "????");
+ else
+ sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i]));
+}
+
+/*
+ * 1. Perform a binary search for an debug_function_t.
+ * 2. Fill buf/bufsize with name, parameters and lineno, if found
+ * Or with '????' otherwise.
+ */
+static debug_function_t*
+find_debug_function_t( symbol_data_t* symbol_data,
+ const pid_t pid,
+ const unsigned long fp, /* frame pointer */
+ const unsigned long addr,
+ char* buf, /* string buffer */
+ const int bufsize)/* FIXME: not used! */
+{
+ debug_function_t** syms = symbol_data->functions;
+ debug_function_t* f = NULL;
+ debug_block_t* block = NULL;
+ debug_lineno_t* lineno = NULL;
+ const int symcount = symbol_data->functions_size;
+ int bottom = 0;
+ int top = symcount - 1;
+ int i;
+ char* bufptr = buf;
+
+ if (symcount==0) {
+ sprintf(buf, "????");
+ return NULL;
+ }
+ while (top>bottom+1) {
+ i = (top+bottom) / 2;
+ if (syms[i]->block->begin_addr==addr) {
+ f = syms[i];
+ break;
+ } else if (syms[i]->block->begin_addr > addr)
+ top = i;
+ else
+ if (syms[i]->block->end_addr >= addr) {
+ f = syms[i];
+ break;
+ } else
+ bottom = i;
+ }
+ i = bottom;
+ if (f!=0)
+ block = f->block;
+ else {
+ block = syms[i]->block;
+ if (block->begin_addr>=addr && block->end_addr<=addr)
+ f = syms[i];
+ }
+ if (f==0)
+ sprintf(buf, "????");
+ else {
+ /*
+ * Do the backtrace the GDB way...
+ */
+ unsigned long arg;
+ /* assert(f->lines_count>0); */
+ if (f->lines_count>0) {
+ lineno = &f->lines[f->lines_count-1];
+ for (i=1; i<f->lines_count; ++i)
+ if (f->lines[i].addr>addr) {
+ lineno = &f->lines[i-1];
+ break;
+ }
+ }
+ bufptr[0] = 0;
+ bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr);
+ for (i=0; i<f->argc; ++i) {
+ bufptr += sprintf(bufptr, "%s = ", f->argv[i].name);
+ /* FIXME: better parameter printing */
+ errno = 0;
+ arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0);
+ assert(errno==0);
+ bufptr += sprintf(bufptr, "0x%x", arg);
+ if (i!=f->argc-1)
+ bufptr += sprintf(bufptr, ", ");
+ }
+ if (lineno!=0)
+ bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno);
+ }
+ return f;
+}
+
+/*
+ * Advance through the stacks and display frames as needed.
+ */
+static int
+my_crawl( int pid,
+ symbol_data_t* symbol_data,
+ int fout)
+{
+ unsigned long pc = 0;
+ unsigned long fp = 0;
+ unsigned long nextfp;
+ unsigned long nargs;
+ unsigned long i;
+ unsigned long arg;
+ char buf[8096]; // FIXME: enough?
+ debug_function_t* f = 0;
+
+ errno = 0;
+
+ pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0);
+ if (!errno)
+ fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0);
+
+ if (!errno) {
+#if 1
+ f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ for ( ; !errno && fp; ) {
+ nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
+ if (errno)
+ break;
+
+ if (f==0) {
+ nargs = (nextfp - fp - 8) / 4;
+ if (nargs > MAXARGS)
+ nargs = MAXARGS;
+ if (nargs > 0) {
+ fdputs(" (", fout);
+ for (i = 1; i <= nargs; i++) {
+ arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
+ if (errno)
+ break;
+ fdprintf(fout,"%lx", arg);
+ if (i < nargs)
+ fdputs(", ", fout);
+ }
+ fdputc(')', fout);
+ nargs = nextfp - fp - 8 - (4 * nargs);
+ if (!errno && nargs > 0)
+ fdprintf(fout," + %lx\n", nargs);
+ else
+ fdputc('\n', fout);
+ } else
+ fdputc('\n', fout);
+ } else
+ fdputc('\n', fout);
+
+ if (errno || !nextfp)
+ break;
+ pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
+ fp = nextfp;
+ if (errno)
+ break;
+ f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ }
+#else /* 1 */
+ decode_symbol(symbol_data, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ for ( ; !errno && fp; ) {
+ nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
+ if (errno)
+ break;
+
+ nargs = (nextfp - fp - 8) / 4;
+ if (nargs > MAXARGS)
+ nargs = MAXARGS;
+ if (nargs > 0) {
+ fputs(" (", fout);
+ for (i = 1; i <= nargs; i++) {
+ arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
+ if (errno)
+ break;
+ fdprintf(fout,"%lx", arg);
+ if (i < nargs)
+ fputs(", ", fout);
+ }
+ fdputc(')', fout);
+ nargs = nextfp - fp - 8 - (4 * nargs);
+ if (!errno && nargs > 0)
+ fdprintf(fout," + %lx\n", nargs);
+ else
+ fdputc('\n', fout);
+ } else
+ fdputc('\n', fout);
+
+ if (errno || !nextfp)
+ break;
+ pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
+ fp = nextfp;
+ if (errno)
+ break;
+ decode_symbol(symbol_data, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ }
+#endif /* !1 */
+ }
+ if (errno)
+ perror("my_crawl");
+ return errno;
+}
+
+/* layout from /usr/src/linux/arch/i386/kernel/process.c */
+static void
+show_regs( signal_regs_t* regs,
+ int fd)
+{
+ /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */
+
+ fdprintf(fd,"\n");
+ fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr);
+ fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip);
+ if (regs->xcs & 3)
+ fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp);
+ /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */
+ fdprintf(fd, "\n");
+ fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n",
+ regs->eax,regs->ebx,regs->ecx,regs->edx);
+ fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x",
+ regs->esi, regs->edi, regs->ebp);
+ fdprintf(fd," DS: %04x ES: %04x\n",
+ 0xffff & regs->xds,0xffff & regs->xes);
+ /*
+ __asm__("movl %%cr0, %0": "=r" (cr0));
+ __asm__("movl %%cr2, %0": "=r" (cr2));
+ __asm__("movl %%cr3, %0": "=r" (cr3));
+ fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */
+}
+
+/*
+ * Load a BFD for an executable based on PID. Return 0 on failure.
+ */
+static bfd*
+load_bfd( const int pid)
+{
+ char filename[512];
+ bfd* abfd = 0;
+
+ /* Get the contents from procfs. */
+#if 1
+ sprintf(filename, "/proc/%d/exe", pid);
+#else
+ sprintf(filename, "crashing");
+#endif
+
+ if ((abfd = bfd_openr (filename, 0))== NULL)
+ bfd_nonfatal (filename);
+ else {
+ char** matching;
+ assert(bfd_check_format(abfd, bfd_archive)!=true);
+
+ /*
+ * There is no indication in BFD documentation that it should be done.
+ * God knows why...
+ */
+ if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
+ bfd_nonfatal (bfd_get_filename (abfd));
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized) {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ }
+ }
+ return abfd;
+}
+
+/*
+ * Those are for qsort. We need only function addresses, so all the others don't count.
+ */
+/*
+ * Compare two BFD::asymbol-s.
+ */
+static int
+compare_symbols(const void* ap,
+ const void* bp)
+{
+ const asymbol *a = *(const asymbol **)ap;
+ const asymbol *b = *(const asymbol **)bp;
+ if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
+ return 1;
+ else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
+ return -1;
+ return 0;
+}
+
+/*
+ * Compare two debug_asymbol_t-s.
+ */
+static int
+compare_debug_function_t(const void* ap,
+ const void* bp)
+{
+ const debug_function_t *a = *(const debug_function_t **)ap;
+ const debug_function_t *b = *(const debug_function_t **)bp;
+ assert(a->block!=0);
+ assert(b->block!=0);
+ {
+ const bfd_vma addr1 = a->block->begin_addr;
+ const bfd_vma addr2 = b->block->begin_addr;
+ if (addr1 > addr2)
+ return 1;
+ else if (addr2 > addr1)
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Filter out (in place) symbols that are useless for stack tracing.
+ * COUNT is the number of elements in SYMBOLS.
+ * Return the number of useful symbols.
+ */
+
+static long
+remove_useless_symbols( asymbol** symbols,
+ long count)
+{
+ asymbol** in_ptr = symbols;
+ asymbol** out_ptr = symbols;
+
+ while (--count >= 0) {
+ asymbol *sym = *in_ptr++;
+
+ if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0)
+ continue;
+ if (sym->flags & (BSF_DEBUGGING))
+ continue;
+ if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section))
+ continue;
+ *out_ptr++ = sym;
+ }
+ return out_ptr - symbols;
+}
+
+/*
+ * Debugging information.
+ */
+static bfd* abfd = 0;
+static PTR dhandle = 0;
+static asymbol** syms = 0;
+static long symcount = 0;
+static asymbol** sorted_syms = 0;
+static long sorted_symcount = 0;
+static debug_function_t** functions = 0;
+static int functions_size = 0;
+static int sigreport = SIGUSR1;
+static pthread_t segv_tid; /* What thread did SEGV? */
+static pid_t segv_pid;
+
+/*
+ * We'll get here after a SIGSEGV. But you can install it on other signals, too :)
+ * Because we are in the middle of the SIGSEGV, we are on our own. We can't do
+ * any malloc(), any fopen(), nothing. The last is actually a sin. We event can't
+ * fprintf(stderr,...)!!!
+ */
+static void
+segv_action(int signo, siginfo_t* siginfo, void* ptr)
+{
+ symbol_data_t symbol_data;
+ int fd = -1;
+
+ segv_pid = getpid();
+ segv_tid = pthread_self();
+ fd = open_log_file(segv_tid, segv_pid);
+ /* signal(SIGSEGV, SIG_DFL); */
+ ptrace_regs = (signal_regs_t*)ptr;
+ assert(ptrace_regs!=0);
+
+ /* Show user how guilty we are. */
+ fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self());
+ show_regs(ptrace_regs, fd);
+
+ /* Some form of stack trace, too. */
+ fdprintf(fd, "STACK TRACE:\n");
+
+ symbol_data.syms = sorted_syms;
+ symbol_data.symcount = sorted_symcount;
+ symbol_data.functions = functions;
+ symbol_data.functions_size = functions_size;
+ my_crawl(segv_pid, &symbol_data, fd);
+ //fflush(stdout);
+ close(fd);
+ linuxthreads_notify_others(sigreport);
+}
+
+
+static void
+report_action(int signo, siginfo_t* siginfo, void* ptr)
+{
+ const int pid = getpid();
+ pthread_t tid = pthread_self();
+ symbol_data_t symbol_data;
+ int fd;
+ if (pthread_equal(tid, segv_tid)) {
+ /* We have already printed our stack trace... */
+ return;
+ }
+
+ fd = open_log_file(tid, pid);
+ fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self());
+ /* signal(SIGSEGV, SIG_DFL); */
+ ptrace_regs = (signal_regs_t*)ptr;
+ assert(ptrace_regs!=0);
+
+ /* Show user how guilty we are. */
+ fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self());
+ show_regs(ptrace_regs, fd);
+
+ /* Some form of stack trace, too. */
+ fdprintf(fd, "STACK TRACE:\n");
+
+ symbol_data.syms = sorted_syms;
+ symbol_data.symcount = sorted_symcount;
+ symbol_data.functions = functions;
+ symbol_data.functions_size = functions_size;
+ my_crawl(pid, &symbol_data, fd);
+ //fflush(stdout);
+ close(fd);
+ /* Tell segv_thread to proceed after pause(). */
+ /*pthread_kill(segv_tid, sigreport);
+ kill(segv_pid, sigreport);
+ pthread_cancel(tid); */
+}
+
+/*
+ * Main library routine. Just call it on your program.
+ */
+int
+pstack_install_segv_action( const char* path_format_)
+{
+ const int pid = getpid();
+ struct sigaction act;
+
+ /* Store what we have to for later usage. */
+ path_format = path_format_;
+
+ /* We need a signal action for SIGSEGV and sigreport ! */
+ sigreport = SIGUSR1;
+ act.sa_handler = 0;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */
+ act.sa_sigaction = segv_action;
+ act.sa_restorer = NULL;
+ if (sigaction(SIGSEGV, &act, NULL)!=0) {
+ perror("sigaction");
+ return 1;
+ }
+ act.sa_sigaction = report_action;
+ act.sa_flags = SA_SIGINFO; /* But many sigreports. */
+ if (sigaction(sigreport, &act, NULL)!=0) {
+ perror("sigaction");
+ return 1;
+ }
+
+ /* And a little setup for libiberty. */
+ program_name = "crashing";
+ xmalloc_set_program_name (program_name);
+
+ /* Umm, and initialize BFD, too */
+ bfd_init();
+#if 0
+ list_supported_targets(0, stdout);
+ set_default_bfd_target();
+#endif /* 0 */
+
+ if ((abfd = load_bfd(pid))==0)
+ fprintf(stderr, "BFD load failed..\n");
+ else {
+ long storage_needed = bfd_get_symtab_upper_bound (abfd);
+ long i;
+ (void)i;
+
+ if (storage_needed < 0)
+ fprintf(stderr, "Symbol table size estimation failure.\n");
+ else if (storage_needed > 0) {
+ syms = (asymbol **) xmalloc (storage_needed);
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+
+ TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount));
+ /* We need debugging info, too! */
+ if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0)
+ fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n");
+
+ /* We make a copy of syms to sort. We don't want to sort syms
+ because that will screw up the relocs. */
+ sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
+ memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
+
+#if 0
+ for (i=0; i<symcount; ++i)
+ if (syms[i]->name!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0)
+ printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name);
+#endif
+ sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
+ TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount));
+
+ /* Sort the symbols into section and symbol order */
+ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
+#if 0
+ for (i=0; i<sorted_symcount; ++i)
+ if (sorted_syms[i]->name!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0)
+ printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name);
+#endif
+ /* We have symbols, we need debugging info somehow sorted out. */
+ if (dhandle==0) {
+ fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n");
+ } else {
+ /* Start collecting the debugging information.... */
+ struct pr_handle info;
+
+ info.f = stdout;
+ info.indent = 0;
+ info.stack = NULL;
+ info.parameter = 0;
+ info.block = NULL;
+ info.function = NULL;
+ info.functions_size = 0;
+ info.functions_maxsize = 1000;
+ info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize);
+ debug_write (dhandle, &pr_fns, (PTR) &info);
+ TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size));
+ assert(info.functions_size!=0);
+ functions = xmalloc(sizeof(debug_function_t*)*info.functions_size);
+ functions_size = info.functions_size;
+ for (i=0; i<functions_size; ++i)
+ functions[i] = &info.functions[i];
+ /* Sort the symbols into section and symbol order */
+ qsort (functions, functions_size, sizeof(debug_function_t*),
+ compare_debug_function_t);
+#if 0
+ for (i=0; i<info.functions_size; ++i)
+ fprintf(stdout, "%08lx T %s\n", info.functions[i].block->begin_addr, info.functions[i].name);
+#endif
+ fflush(stdout);
+ }
+ } else /* storage_needed == 0 */
+ fprintf(stderr, "NO SYMBOLS FOUND.\n");
+ }
+ return 0;
+}
+
+/*********************************************************************/
+/*********************************************************************/
+/*********************************************************************/
diff --git a/pstack/pstack.h b/pstack/pstack.h
new file mode 100644
index 00000000000..4c4fad7e754
--- /dev/null
+++ b/pstack/pstack.h
@@ -0,0 +1,22 @@
+/* $Header$ */
+
+#ifndef pstack_pstack_h_
+#define pstack_pstack_h_
+
+#include "pstacktrace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Install the stack-trace-on-SEGV handler....
+ */
+extern int
+pstack_install_segv_action( const char* path_format);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pstack_pstack_h_ */
+
diff --git a/pstack/pstacktrace.h b/pstack/pstacktrace.h
new file mode 100644
index 00000000000..c884bcb9f87
--- /dev/null
+++ b/pstack/pstacktrace.h
@@ -0,0 +1,24 @@
+/* $Header$ */
+
+/*
+ * Debugging macros.
+ */
+
+#ifndef pstacktrace_h_
+#define pstacktrace_h_
+
+#define PSTACK_DEBUG 1
+#undef PSTACK_DEBUG
+
+#ifdef PSTACK_DEBUG
+# define TRACE_PUTC(a) putc a
+# define TRACE_FPUTS(a) fputs a
+# define TRACE_FPRINTF(a) fprintf a
+#else /* PSTACK_DEBUG */
+# define TRACE_PUTC(a) (void)0
+# define TRACE_FPUTS(a) (void)0
+# define TRACE_FPRINTF(a) (void)0
+#endif /* !PSTACK_DEBUG */
+
+#endif /* pstacktrace_h_ */
+
diff --git a/pstack/rddbg.c b/pstack/rddbg.c
new file mode 100644
index 00000000000..be3dfc21c57
--- /dev/null
+++ b/pstack/rddbg.c
@@ -0,0 +1,462 @@
+/* rddbg.c -- Read debugging information into a generic form.
+ Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file reads debugging information into a generic form. This
+ file knows how to dig the debugging information out of an object
+ file. */
+
+#include <bfd.h>
+#include "bucomm.h"
+#include <libiberty.h>
+#include "debug.h"
+#include "budbg.h"
+
+static boolean read_section_stabs_debugging_info
+ PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
+static boolean read_symbol_stabs_debugging_info
+ PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
+static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
+static void save_stab PARAMS ((int, int, bfd_vma, const char *));
+static void stab_context PARAMS ((void));
+static void free_saved_stabs PARAMS ((void));
+
+/* Read debugging information from a BFD. Returns a generic debugging
+ pointer. */
+
+PTR
+read_debugging_info (abfd, syms, symcount)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+{
+ PTR dhandle;
+ boolean found;
+
+ dhandle = debug_init ();
+ if (dhandle == NULL)
+ return NULL;
+
+ if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
+ &found))
+ return NULL;
+
+ if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
+ {
+ if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
+ &found))
+ return NULL;
+ }
+
+ if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
+ {
+ if (! read_ieee_debugging_info (abfd, dhandle, &found))
+ return NULL;
+ }
+
+ /* Try reading the COFF symbols if we didn't find any stabs in COFF
+ sections. */
+ if (! found
+ && bfd_get_flavour (abfd) == bfd_target_coff_flavour
+ && symcount > 0)
+ {
+#if 0
+/*
+ * JZ: Do we need coff?
+ */
+ if (! parse_coff (abfd, syms, symcount, dhandle))
+#else
+ fprintf (stderr, "%s: COFF support temporarily disabled\n",
+ bfd_get_filename (abfd));
+ return NULL;
+#endif
+ return NULL;
+ found = true;
+ }
+
+ if (! found)
+ {
+ fprintf (stderr, "%s: no recognized debugging information\n",
+ bfd_get_filename (abfd));
+ return NULL;
+ }
+
+ return dhandle;
+}
+
+/* Read stabs in sections debugging information from a BFD. */
+
+static boolean
+read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+ PTR dhandle;
+ boolean *pfound;
+{
+ static struct
+ {
+ const char *secname;
+ const char *strsecname;
+ } names[] = { { ".stab", ".stabstr" } };
+ unsigned int i;
+ PTR shandle;
+
+ *pfound = false;
+ shandle = NULL;
+
+ for (i = 0; i < sizeof names / sizeof names[0]; i++)
+ {
+ asection *sec, *strsec;
+
+ sec = bfd_get_section_by_name (abfd, names[i].secname);
+ strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
+ if (sec != NULL && strsec != NULL)
+ {
+ bfd_size_type stabsize, strsize;
+ bfd_byte *stabs, *strings;
+ bfd_byte *stab;
+ bfd_size_type stroff, next_stroff;
+
+ stabsize = bfd_section_size (abfd, sec);
+ stabs = (bfd_byte *) xmalloc (stabsize);
+ if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
+ {
+ fprintf (stderr, "%s: %s: %s\n",
+ bfd_get_filename (abfd), names[i].secname,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ strsize = bfd_section_size (abfd, strsec);
+ strings = (bfd_byte *) xmalloc (strsize);
+ if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
+ {
+ fprintf (stderr, "%s: %s: %s\n",
+ bfd_get_filename (abfd), names[i].strsecname,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ if (shandle == NULL)
+ {
+ shandle = start_stab (dhandle, abfd, true, syms, symcount);
+ if (shandle == NULL)
+ return false;
+ }
+
+ *pfound = true;
+
+ stroff = 0;
+ next_stroff = 0;
+ for (stab = stabs; stab < stabs + stabsize; stab += 12)
+ {
+ bfd_size_type strx;
+ int type;
+ int other;
+ int desc;
+ bfd_vma value;
+
+ /* This code presumes 32 bit values. */
+
+ strx = bfd_get_32 (abfd, stab);
+ type = bfd_get_8 (abfd, stab + 4);
+ other = bfd_get_8 (abfd, stab + 5);
+ desc = bfd_get_16 (abfd, stab + 6);
+ value = bfd_get_32 (abfd, stab + 8);
+
+ if (type == 0)
+ {
+ /* Special type 0 stabs indicate the offset to the
+ next string table. */
+ stroff = next_stroff;
+ next_stroff += value;
+ }
+ else
+ {
+ char *f, *s;
+
+ f = NULL;
+ s = (char *) strings + stroff + strx;
+ while (s[strlen (s) - 1] == '\\'
+ && stab + 12 < stabs + stabsize)
+ {
+ char *p;
+
+ stab += 12;
+ p = s + strlen (s) - 1;
+ *p = '\0';
+ s = concat (s,
+ ((char *) strings
+ + stroff
+ + bfd_get_32 (abfd, stab)),
+ (const char *) NULL);
+
+ /* We have to restore the backslash, because, if
+ the linker is hashing stabs strings, we may
+ see the same string more than once. */
+ *p = '\\';
+
+ if (f != NULL)
+ free (f);
+ f = s;
+ }
+
+ save_stab (type, desc, value, s);
+
+ if (! parse_stab (dhandle, shandle, type, desc, value, s))
+ {
+#if 0
+/*
+ * JZ: skip the junk.
+ */
+ stab_context ();
+ free_saved_stabs ();
+ return false;
+#endif
+ }
+
+ /* Don't free f, since I think the stabs code
+ expects strings to hang around. This should be
+ straightened out. FIXME. */
+ }
+ }
+
+ free_saved_stabs ();
+ free (stabs);
+
+ /* Don't free strings, since I think the stabs code expects
+ the strings to hang around. This should be straightened
+ out. FIXME. */
+ }
+ }
+
+ if (shandle != NULL)
+ {
+ if (! finish_stab (dhandle, shandle))
+ return false;
+ }
+
+ return true;
+}
+
+/* Read stabs in the symbol table. */
+
+static boolean
+read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+ PTR dhandle;
+ boolean *pfound;
+{
+ PTR shandle;
+ asymbol **ps, **symend;
+
+ shandle = NULL;
+ symend = syms + symcount;
+ for (ps = syms; ps < symend; ps++)
+ {
+ symbol_info i;
+
+ bfd_get_symbol_info (abfd, *ps, &i);
+
+ if (i.type == '-')
+ {
+ const char *s;
+ char *f;
+
+ if (shandle == NULL)
+ {
+ shandle = start_stab (dhandle, abfd, false, syms, symcount);
+ if (shandle == NULL)
+ return false;
+ }
+
+ *pfound = true;
+
+ s = i.name;
+ f = NULL;
+ while (s[strlen (s) - 1] == '\\'
+ && ps + 1 < symend)
+ {
+ char *sc, *n;
+
+ ++ps;
+ sc = xstrdup (s);
+ sc[strlen (sc) - 1] = '\0';
+ n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
+ free (sc);
+ if (f != NULL)
+ free (f);
+ f = n;
+ s = n;
+ }
+
+ save_stab (i.stab_type, i.stab_desc, i.value, s);
+
+ if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
+ i.value, s))
+ {
+ stab_context ();
+ free_saved_stabs ();
+ return false;
+ }
+
+ /* Don't free f, since I think the stabs code expects
+ strings to hang around. This should be straightened out.
+ FIXME. */
+ }
+ }
+
+ free_saved_stabs ();
+
+ if (shandle != NULL)
+ {
+ if (! finish_stab (dhandle, shandle))
+ return false;
+ }
+
+ return true;
+}
+
+/* Read IEEE debugging information. */
+
+static boolean
+read_ieee_debugging_info (abfd, dhandle, pfound)
+ bfd *abfd;
+ PTR dhandle;
+ boolean *pfound;
+{
+ asection *dsec;
+ bfd_size_type size;
+ bfd_byte *contents;
+
+ /* The BFD backend puts the debugging information into a section
+ named .debug. */
+
+ dsec = bfd_get_section_by_name (abfd, ".debug");
+ if (dsec == NULL)
+ return true;
+
+ size = bfd_section_size (abfd, dsec);
+ contents = (bfd_byte *) xmalloc (size);
+ if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
+ return false;
+
+ if (! parse_ieee (dhandle, abfd, contents, size))
+ return false;
+
+ free (contents);
+
+ *pfound = true;
+
+ return true;
+}
+
+/* Record stabs strings, so that we can give some context for errors. */
+
+#define SAVE_STABS_COUNT (16)
+
+struct saved_stab
+{
+ int type;
+ int desc;
+ bfd_vma value;
+ char *string;
+};
+
+static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
+static int saved_stabs_index;
+
+/* Save a stabs string. */
+
+static void
+save_stab (type, desc, value, string)
+ int type;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ if (saved_stabs[saved_stabs_index].string != NULL)
+ free (saved_stabs[saved_stabs_index].string);
+ saved_stabs[saved_stabs_index].type = type;
+ saved_stabs[saved_stabs_index].desc = desc;
+ saved_stabs[saved_stabs_index].value = value;
+ saved_stabs[saved_stabs_index].string = xstrdup (string);
+ saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
+}
+
+/* Provide context for an error. */
+
+static void
+stab_context ()
+{
+ int i;
+
+ fprintf (stderr, "Last stabs entries before error:\n");
+ fprintf (stderr, "n_type n_desc n_value string\n");
+
+ i = saved_stabs_index;
+ do
+ {
+ struct saved_stab *stabp;
+
+ stabp = saved_stabs + i;
+ if (stabp->string != NULL)
+ {
+ const char *s;
+
+ s = bfd_get_stab_name (stabp->type);
+ if (s != NULL)
+ fprintf (stderr, "%-6s", s);
+ else if (stabp->type == 0)
+ fprintf (stderr, "HdrSym");
+ else
+ fprintf (stderr, "%-6d", stabp->type);
+ fprintf (stderr, " %-6d ", stabp->desc);
+ fprintf_vma (stderr, stabp->value);
+ if (stabp->type != 0)
+ fprintf (stderr, " %s", stabp->string);
+ fprintf (stderr, "\n");
+ }
+ i = (i + 1) % SAVE_STABS_COUNT;
+ }
+ while (i != saved_stabs_index);
+}
+
+/* Free the saved stab strings. */
+
+static void
+free_saved_stabs ()
+{
+ int i;
+
+ for (i = 0; i < SAVE_STABS_COUNT; i++)
+ {
+ if (saved_stabs[i].string != NULL)
+ {
+ free (saved_stabs[i].string);
+ saved_stabs[i].string = NULL;
+ }
+ }
+
+ saved_stabs_index = 0;
+}
diff --git a/pstack/stabs.c b/pstack/stabs.c
new file mode 100644
index 00000000000..076231d19cb
--- /dev/null
+++ b/pstack/stabs.c
@@ -0,0 +1,5082 @@
+/* stabs.c -- Parse stabs debugging information
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains code which parses stabs debugging information.
+ The organization of this code is based on the gdb stabs reading
+ code. The job it does is somewhat different, because it is not
+ trying to identify the correct address for anything. */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include <bfd.h>
+#include "bucomm.h"
+#include <libiberty.h>
+#include "demangle.h"
+#include "debug.h"
+#include "budbg.h"
+
+/* Meaningless definition needs by aout64.h. FIXME. */
+#define BYTES_IN_WORD 4
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+
+/* The number of predefined XCOFF types. */
+
+#define XCOFF_TYPE_COUNT 34
+
+/* This structure is used as a handle so that the stab parsing doesn't
+ need to use any static variables. */
+
+struct stab_handle
+{
+ /* The BFD. */
+ bfd *abfd;
+ /* True if this is stabs in sections. */
+ boolean sections;
+ /* The symbol table. */
+ asymbol **syms;
+ /* The number of symbols. */
+ long symcount;
+ /* The accumulated file name string. */
+ char *so_string;
+ /* The value of the last N_SO symbol. */
+ bfd_vma so_value;
+ /* The value of the start of the file, so that we can handle file
+ relative N_LBRAC and N_RBRAC symbols. */
+ bfd_vma file_start_offset;
+ /* The offset of the start of the function, so that we can handle
+ function relative N_LBRAC and N_RBRAC symbols. */
+ bfd_vma function_start_offset;
+ /* The version number of gcc which compiled the current compilation
+ unit, 0 if not compiled by gcc. */
+ int gcc_compiled;
+ /* Whether an N_OPT symbol was seen that was not generated by gcc,
+ so that we can detect the SunPRO compiler. */
+ boolean n_opt_found;
+ /* The main file name. */
+ char *main_filename;
+ /* A stack of unfinished N_BINCL files. */
+ struct bincl_file *bincl_stack;
+ /* A list of finished N_BINCL files. */
+ struct bincl_file *bincl_list;
+ /* Whether we are inside a function or not. */
+ boolean within_function;
+ /* The address of the end of the function, used if we have seen an
+ N_FUN symbol while in a function. This is -1 if we have not seen
+ an N_FUN (the normal case). */
+ bfd_vma function_end;
+ /* The depth of block nesting. */
+ int block_depth;
+ /* List of pending variable definitions. */
+ struct stab_pending_var *pending;
+ /* Number of files for which we have types. */
+ unsigned int files;
+ /* Lists of types per file. */
+ struct stab_types **file_types;
+ /* Predefined XCOFF types. */
+ debug_type xcoff_types[XCOFF_TYPE_COUNT];
+ /* Undefined tags. */
+ struct stab_tag *tags;
+};
+
+/* A list of these structures is used to hold pending variable
+ definitions seen before the N_LBRAC of a block. */
+
+struct stab_pending_var
+{
+ /* Next pending variable definition. */
+ struct stab_pending_var *next;
+ /* Name. */
+ const char *name;
+ /* Type. */
+ debug_type type;
+ /* Kind. */
+ enum debug_var_kind kind;
+ /* Value. */
+ bfd_vma val;
+};
+
+/* A list of these structures is used to hold the types for a single
+ file. */
+
+struct stab_types
+{
+ /* Next set of slots for this file. */
+ struct stab_types *next;
+ /* Types indexed by type number. */
+#define STAB_TYPES_SLOTS (16)
+ debug_type types[STAB_TYPES_SLOTS];
+};
+
+/* We keep a list of undefined tags that we encounter, so that we can
+ fill them in if the tag is later defined. */
+
+struct stab_tag
+{
+ /* Next undefined tag. */
+ struct stab_tag *next;
+ /* Tag name. */
+ const char *name;
+ /* Type kind. */
+ enum debug_type_kind kind;
+ /* Slot to hold real type when we discover it. If we don't, we fill
+ in an undefined tag type. */
+ debug_type slot;
+ /* Indirect type we have created to point at slot. */
+ debug_type type;
+};
+
+static char *savestring PARAMS ((const char *, int));
+static bfd_vma parse_number PARAMS ((const char **, boolean *));
+static void bad_stab PARAMS ((const char *));
+static void warn_stab PARAMS ((const char *, const char *));
+static boolean parse_stab_string
+ PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *));
+static debug_type parse_stab_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ debug_type **));
+static boolean parse_stab_type_number
+ PARAMS ((const char **, int *));
+static debug_type parse_stab_range_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ const int *));
+static debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **));
+static debug_type parse_stab_sun_floating_type
+ PARAMS ((PTR, const char **));
+static debug_type parse_stab_enum_type PARAMS ((PTR, const char **));
+static debug_type parse_stab_struct_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **, boolean,
+ const int *));
+static boolean parse_stab_baseclasses
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **));
+static boolean parse_stab_struct_fields
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_field **,
+ boolean *));
+static boolean parse_stab_cpp_abbrev
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_field *));
+static boolean parse_stab_one_struct_field
+ PARAMS ((PTR, struct stab_handle *, const char **, const char *,
+ debug_field *, boolean *));
+static boolean parse_stab_members
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ const int *, debug_method **));
+static debug_type parse_stab_argtypes
+ PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *,
+ debug_type, const char *, boolean, boolean, const char **));
+static boolean parse_stab_tilde_field
+ PARAMS ((PTR, struct stab_handle *, const char **, const int *,
+ debug_type *, boolean *));
+static debug_type parse_stab_array_type
+ PARAMS ((PTR, struct stab_handle *, const char **, boolean));
+static void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma));
+static const char *pop_bincl PARAMS ((struct stab_handle *));
+static boolean find_excl
+ PARAMS ((struct stab_handle *, const char *, bfd_vma));
+static boolean stab_record_variable
+ PARAMS ((PTR, struct stab_handle *, const char *, debug_type,
+ enum debug_var_kind, bfd_vma));
+static boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *));
+static debug_type *stab_find_slot
+ PARAMS ((struct stab_handle *, const int *));
+static debug_type stab_find_type
+ PARAMS ((PTR, struct stab_handle *, const int *));
+static boolean stab_record_type
+ PARAMS ((PTR, struct stab_handle *, const int *, debug_type));
+static debug_type stab_xcoff_builtin_type
+ PARAMS ((PTR, struct stab_handle *, int));
+static debug_type stab_find_tagged_type
+ PARAMS ((PTR, struct stab_handle *, const char *, int,
+ enum debug_type_kind));
+static debug_type *stab_demangle_argtypes
+ PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
+
+/* Save a string in memory. */
+
+static char *
+savestring (start, len)
+ const char *start;
+ int len;
+{
+ char *ret;
+
+ ret = (char *) xmalloc (len + 1);
+ memcpy (ret, start, len);
+ ret[len] = '\0';
+ return ret;
+}
+
+/* Read a number from a string. */
+
+static bfd_vma
+parse_number (pp, poverflow)
+ const char **pp;
+ boolean *poverflow;
+{
+ unsigned long ul;
+ const char *orig;
+
+ if (poverflow != NULL)
+ *poverflow = false;
+
+ orig = *pp;
+
+ errno = 0;
+ ul = strtoul (*pp, (char **) pp, 0);
+ if (ul + 1 != 0 || errno == 0)
+ return (bfd_vma) ul;
+
+ /* Note that even though strtoul overflowed, it should have set *pp
+ to the end of the number, which is where we want it. */
+
+ if (sizeof (bfd_vma) > sizeof (unsigned long))
+ {
+ const char *p;
+ boolean neg;
+ int base;
+ bfd_vma over, lastdig;
+ boolean overflow;
+ bfd_vma v;
+
+ /* Our own version of strtoul, for a bfd_vma. */
+
+ p = orig;
+
+ neg = false;
+ if (*p == '+')
+ ++p;
+ else if (*p == '-')
+ {
+ neg = true;
+ ++p;
+ }
+
+ base = 10;
+ if (*p == '0')
+ {
+ if (p[1] == 'x' || p[1] == 'X')
+ {
+ base = 16;
+ p += 2;
+ }
+ else
+ {
+ base = 8;
+ ++p;
+ }
+ }
+
+ over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
+ lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;
+
+ overflow = false;
+ v = 0;
+ while (1)
+ {
+ int d;
+
+ d = *p++;
+ if (isdigit ((unsigned char) d))
+ d -= '0';
+ else if (isupper ((unsigned char) d))
+ d -= 'A';
+ else if (islower ((unsigned char) d))
+ d -= 'a';
+ else
+ break;
+
+ if (d >= base)
+ break;
+
+ if (v > over || (v == over && (bfd_vma) d > lastdig))
+ {
+ overflow = true;
+ break;
+ }
+ }
+
+ if (! overflow)
+ {
+ if (neg)
+ v = - v;
+ return v;
+ }
+ }
+
+ /* If we get here, the number is too large to represent in a
+ bfd_vma. */
+
+ if (poverflow != NULL)
+ *poverflow = true;
+ else
+ warn_stab (orig, "numeric overflow");
+
+ return 0;
+}
+
+/* Give an error for a bad stab string. */
+
+static void
+bad_stab (p)
+ const char *p;
+{
+ fprintf (stderr, "Bad stab: %s\n", p);
+}
+
+/* Warn about something in a stab string. */
+
+static void
+warn_stab (p, err)
+ const char *p;
+ const char *err;
+{
+ fprintf (stderr, "Warning: %s: %s\n", err, p);
+}
+
+/* Create a handle to parse stabs symbols with. */
+
+/*ARGSUSED*/
+PTR
+start_stab (dhandle, abfd, sections, syms, symcount)
+ PTR dhandle;
+ bfd *abfd;
+ boolean sections;
+ asymbol **syms;
+ long symcount;
+{
+ struct stab_handle *ret;
+
+ ret = (struct stab_handle *) xmalloc (sizeof *ret);
+ memset (ret, 0, sizeof *ret);
+ ret->abfd = abfd;
+ ret->sections = sections;
+ ret->syms = syms;
+ ret->symcount = symcount;
+ ret->files = 1;
+ ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
+ ret->file_types[0] = NULL;
+ ret->function_end = (bfd_vma) -1;
+ return (PTR) ret;
+}
+
+/* When we have processed all the stabs information, we need to go
+ through and fill in all the undefined tags. */
+
+boolean
+finish_stab (dhandle, handle)
+ PTR dhandle;
+ PTR handle;
+{
+ struct stab_handle *info = (struct stab_handle *) handle;
+ struct stab_tag *st;
+
+ if (info->within_function)
+ {
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, info->function_end))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+
+ for (st = info->tags; st != NULL; st = st->next)
+ {
+ enum debug_type_kind kind;
+
+ kind = st->kind;
+ if (kind == DEBUG_KIND_ILLEGAL)
+ kind = DEBUG_KIND_STRUCT;
+ st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
+ if (st->slot == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle a single stabs symbol. */
+
+boolean
+parse_stab (dhandle, handle, type, desc, value, string)
+ PTR dhandle;
+ PTR handle;
+ int type;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ struct stab_handle *info = (struct stab_handle *) handle;
+
+ /* gcc will emit two N_SO strings per compilation unit, one for the
+ directory name and one for the file name. We just collect N_SO
+ strings as we see them, and start the new compilation unit when
+ we see a non N_SO symbol. */
+ if (info->so_string != NULL
+ && (type != N_SO || *string == '\0' || value != info->so_value))
+ {
+ if (! debug_set_filename (dhandle, info->so_string))
+ return false;
+ info->main_filename = info->so_string;
+
+ info->gcc_compiled = 0;
+ info->n_opt_found = false;
+
+ /* Generally, for stabs in the symbol table, the N_LBRAC and
+ N_RBRAC symbols are relative to the N_SO symbol value. */
+ if (! info->sections)
+ info->file_start_offset = info->so_value;
+
+ /* We need to reset the mapping from type numbers to types. We
+ can't free the old mapping, because of the use of
+ debug_make_indirect_type. */
+ info->files = 1;
+ info->file_types = ((struct stab_types **)
+ xmalloc (sizeof *info->file_types));
+ info->file_types[0] = NULL;
+
+ info->so_string = NULL;
+
+ /* Now process whatever type we just got. */
+ }
+
+ switch (type)
+ {
+ case N_FN:
+ case N_FN_SEQ:
+ break;
+
+ case N_LBRAC:
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (info->n_opt_found && desc == 1)
+ break;
+
+ if (! info->within_function)
+ {
+ fprintf (stderr, "N_LBRAC not within function\n");
+ return false;
+ }
+
+ /* Start an inner lexical block. */
+ if (! debug_start_block (dhandle,
+ (value
+ + info->file_start_offset
+ + info->function_start_offset)))
+ return false;
+
+ /* Emit any pending variable definitions. */
+ if (! stab_emit_pending_vars (dhandle, info))
+ return false;
+
+ ++info->block_depth;
+ break;
+
+ case N_RBRAC:
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (info->n_opt_found && desc == 1)
+ break;
+
+ /* We shouldn't have any pending variable definitions here, but,
+ if we do, we probably need to emit them before closing the
+ block. */
+ if (! stab_emit_pending_vars (dhandle, info))
+ return false;
+
+ /* End an inner lexical block. */
+ if (! debug_end_block (dhandle,
+ (value
+ + info->file_start_offset
+ + info->function_start_offset)))
+ return false;
+
+ --info->block_depth;
+ if (info->block_depth < 0)
+ {
+ fprintf (stderr, "Too many N_RBRACs\n");
+ return false;
+ }
+ break;
+
+ case N_SO:
+ /* This always ends a function. */
+ if (info->within_function)
+ {
+ bfd_vma endval;
+
+ endval = value;
+ if (*string != '\0'
+ && info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, endval))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+
+ /* An empty string is emitted by gcc at the end of a compilation
+ unit. */
+ if (*string == '\0')
+ return true;
+
+ /* Just accumulate strings until we see a non N_SO symbol. If
+ the string starts with '/', we discard the previously
+ accumulated strings. */
+ if (info->so_string == NULL)
+ info->so_string = xstrdup (string);
+ else
+ {
+ char *f;
+
+ f = info->so_string;
+ if (*string == '/')
+ info->so_string = xstrdup (string);
+ else
+ info->so_string = concat (info->so_string, string,
+ (const char *) NULL);
+ free (f);
+ }
+
+ info->so_value = value;
+
+ break;
+
+ case N_SOL:
+ /* Start an include file. */
+ if (! debug_start_source (dhandle, string))
+ return false;
+ break;
+
+ case N_BINCL:
+ /* Start an include file which may be replaced. */
+ push_bincl (info, string, value);
+ if (! debug_start_source (dhandle, string))
+ return false;
+ break;
+
+ case N_EINCL:
+ /* End an N_BINCL include. */
+ if (! debug_start_source (dhandle, pop_bincl (info)))
+ return false;
+ break;
+
+ case N_EXCL:
+ /* This is a duplicate of a header file named by N_BINCL which
+ was eliminated by the linker. */
+ if (! find_excl (info, string, value))
+ return false;
+ break;
+
+ case N_SLINE:
+ if (! debug_record_line (dhandle, desc,
+ value + info->function_start_offset))
+ return false;
+ break;
+
+ case N_BCOMM:
+ if (! debug_start_common_block (dhandle, string))
+ return false;
+ break;
+
+ case N_ECOMM:
+ if (! debug_end_common_block (dhandle, string))
+ return false;
+ break;
+
+ case N_FUN:
+ if (*string == '\0')
+ {
+ if (info->within_function)
+ {
+ /* This always marks the end of a function; we don't
+ need to worry about info->function_end. */
+ if (info->sections)
+ value += info->function_start_offset;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, value))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+ break;
+ }
+
+ /* A const static symbol in the .text section will have an N_FUN
+ entry. We need to use these to mark the end of the function,
+ in case we are looking at gcc output before it was changed to
+ always emit an empty N_FUN. We can't call debug_end_function
+ here, because it might be a local static symbol. */
+ if (info->within_function
+ && (info->function_end == (bfd_vma) -1
+ || value < info->function_end))
+ info->function_end = value;
+
+ /* Fall through. */
+ /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
+ symbols, and if it does not start with :S, gdb relocates the
+ value to the start of the section. gcc always seems to use
+ :S, so we don't worry about this. */
+ /* Fall through. */
+ default:
+ {
+ const char *colon;
+
+ colon = strchr (string, ':');
+ if (colon != NULL
+ && (colon[1] == 'f' || colon[1] == 'F'))
+ {
+ if (info->within_function)
+ {
+ bfd_vma endval;
+
+ endval = value;
+ if (info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, endval))
+ return false;
+ info->function_end = (bfd_vma) -1;
+ }
+ /* For stabs in sections, line numbers and block addresses
+ are offsets from the start of the function. */
+ if (info->sections)
+ info->function_start_offset = value;
+ info->within_function = true;
+ }
+
+ if (! parse_stab_string (dhandle, info, type, desc, value, string))
+ return false;
+ }
+ break;
+
+ case N_OPT:
+ if (string != NULL && strcmp (string, "gcc2_compiled.") == 0)
+ info->gcc_compiled = 2;
+ else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
+ info->gcc_compiled = 1;
+ else
+ info->n_opt_found = true;
+ break;
+
+ case N_OBJ:
+ case N_ENDM:
+ case N_MAIN:
+ break;
+ }
+
+ return true;
+}
+
+/* Parse the stabs string. */
+
+static boolean
+parse_stab_string (dhandle, info, stabtype, desc, value, string)
+ PTR dhandle;
+ struct stab_handle *info;
+ int stabtype;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ const char *p;
+ char *name;
+ int type;
+ debug_type dtype;
+ boolean synonym;
+ unsigned int lineno;
+ debug_type *slot;
+
+ p = strchr (string, ':');
+ if (p == NULL)
+ return true;
+
+ while (p[1] == ':')
+ {
+ p += 2;
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (string);
+ return false;
+ }
+ }
+
+ /* GCC 2.x puts the line number in desc. SunOS apparently puts in
+ the number of bytes occupied by a type or object, which we
+ ignore. */
+ if (info->gcc_compiled >= 2)
+ lineno = desc;
+ else
+ lineno = 0;
+
+ /* FIXME: Sometimes the special C++ names start with '.'. */
+ name = NULL;
+ if (string[0] == '$')
+ {
+ switch (string[1])
+ {
+ case 't':
+ name = "this";
+ break;
+ case 'v':
+ /* Was: name = "vptr"; */
+ break;
+ case 'e':
+ name = "eh_throw";
+ break;
+ case '_':
+ /* This was an anonymous type that was never fixed up. */
+ break;
+ case 'X':
+ /* SunPRO (3.0 at least) static variable encoding. */
+ break;
+ default:
+ warn_stab (string, "unknown C++ encoded name");
+ break;
+ }
+ }
+
+ if (name == NULL)
+ {
+ if (p == string || (string[0] == ' ' && p == string + 1))
+ name = NULL;
+ else
+ name = savestring (string, p - string);
+ }
+
+ ++p;
+ if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+ type = 'l';
+ else
+ type = *p++;
+
+ switch (type)
+ {
+ case 'c':
+ /* c is a special case, not followed by a type-number.
+ SYMBOL:c=iVALUE for an integer constant symbol.
+ SYMBOL:c=rVALUE for a floating constant symbol.
+ SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ if (*p != '=')
+ {
+ bad_stab (string);
+ return false;
+ }
+ ++p;
+ switch (*p++)
+ {
+ case 'r':
+ /* Floating point constant. */
+ if (! debug_record_float_const (dhandle, name, atof (p)))
+ return false;
+ break;
+ case 'i':
+ /* Integer constant. */
+ /* Defining integer constants this way is kind of silly,
+ since 'e' constants allows the compiler to give not only
+ the value, but the type as well. C has at least int,
+ long, unsigned int, and long long as constant types;
+ other languages probably should have at least unsigned as
+ well as signed constants. */
+ if (! debug_record_int_const (dhandle, name, atoi (p)))
+ return false;
+ break;
+ case 'e':
+ /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
+ can be represented as integral.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ &p, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (*p != ',')
+ {
+ bad_stab (string);
+ return false;
+ }
+ if (! debug_record_typed_const (dhandle, name, dtype, atoi (p)))
+ return false;
+ break;
+ default:
+ bad_stab (string);
+ return false;
+ }
+
+ break;
+
+ case 'C':
+ /* The name of a caught exception. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ &p, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_label (dhandle, name, dtype, value))
+ return false;
+ break;
+
+ case 'f':
+ case 'F':
+ /* A function definition. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
+ return false;
+
+ /* Sun acc puts declared types of arguments here. We don't care
+ about their actual types (FIXME -- we should remember the whole
+ function prototype), but the list may define some new types
+ that we have to remember, so we must scan it now. */
+ while (*p == ';')
+ {
+ ++p;
+ if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL)
+ == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ break;
+
+ case 'G':
+ {
+ char leading;
+ long c;
+ asymbol **ps;
+
+ /* A global symbol. The value must be extracted from the
+ symbol table. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ leading = bfd_get_symbol_leading_char (info->abfd);
+ for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+ {
+ const char *n;
+
+ n = bfd_asymbol_name (*ps);
+ if (leading != '\0' && *n == leading)
+ ++n;
+ if (*n == *name && strcmp (n, name) == 0)
+ break;
+ }
+ if (c > 0)
+ value = bfd_asymbol_value (*ps);
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
+ value))
+ return false;
+ }
+ break;
+
+ /* This case is faked by a conditional above, when there is no
+ code letter in the dbx data. Dbx data never actually
+ contains 'l'. */
+ case 'l':
+ case 's':
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
+ value))
+ return false;
+ break;
+
+ case 'p':
+ /* A function parameter. */
+ if (*p != 'F')
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ else
+ {
+ /* pF is a two-letter code that means a function parameter in
+ Fortran. The type-number specifies the type of the return
+ value. Translate it into a pointer-to-function type. */
+ ++p;
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype != DEBUG_TYPE_NULL)
+ {
+ debug_type ftype;
+
+ ftype = debug_make_function_type (dhandle, dtype,
+ (debug_type *) NULL, false);
+ dtype = debug_make_pointer_type (dhandle, ftype);
+ }
+ }
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
+ value))
+ return false;
+
+ /* FIXME: At this point gdb considers rearranging the parameter
+ address on a big endian machine if it is smaller than an int.
+ We have no way to do that, since we don't really know much
+ about the target. */
+
+ break;
+
+ case 'P':
+ if (stabtype == N_FUN)
+ {
+ /* Prototype of a function referenced by this file. */
+ while (*p == ';')
+ {
+ ++p;
+ if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL)
+ == DEBUG_TYPE_NULL)
+ return false;
+ }
+ break;
+ }
+ /* Fall through. */
+ case 'R':
+ /* Parameter which is in a register. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
+ value))
+ return false;
+ break;
+
+ case 'r':
+ /* Register variable (either global or local). */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
+ value))
+ return false;
+
+ /* FIXME: At this point gdb checks to combine pairs of 'p' and
+ 'r' stabs into a single 'P' stab. */
+
+ break;
+
+ case 'S':
+ /* Static symbol at top level of file */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
+ value))
+ return false;
+ break;
+
+ case 't':
+ /* A typedef. */
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (name == NULL)
+ {
+ /* A nameless type. Nothing to do. */
+ return true;
+ }
+
+ dtype = debug_name_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+
+ if (slot != NULL)
+ *slot = dtype;
+
+ break;
+
+ case 'T':
+ /* Struct, union, or enum tag. For GNU C++, this can be be followed
+ by 't' which means we are typedef'ing it as well. */
+ if (*p != 't')
+ {
+ synonym = false;
+ /* FIXME: gdb sets synonym to true if the current language
+ is C++. */
+ }
+ else
+ {
+ synonym = true;
+ ++p;
+ }
+
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (name == NULL)
+ return true;
+
+ dtype = debug_tag_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (slot != NULL)
+ *slot = dtype;
+
+ /* See if we have a cross reference to this tag which we can now
+ fill in. */
+ {
+ register struct stab_tag **pst;
+
+ for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next)
+ {
+ if ((*pst)->name[0] == name[0]
+ && strcmp ((*pst)->name, name) == 0)
+ {
+ (*pst)->slot = dtype;
+ *pst = (*pst)->next;
+ break;
+ }
+ }
+ }
+
+ if (synonym)
+ {
+ dtype = debug_name_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+
+ if (slot != NULL)
+ *slot = dtype;
+ }
+
+ break;
+
+ case 'V':
+ /* Static symbol of local scope */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ /* FIXME: gdb checks os9k_stabs here. */
+ if (! stab_record_variable (dhandle, info, name, dtype,
+ DEBUG_LOCAL_STATIC, value))
+ return false;
+ break;
+
+ case 'v':
+ /* Reference parameter. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
+ value))
+ return false;
+ break;
+
+ case 'a':
+ /* Reference parameter which is in a register. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
+ value))
+ return false;
+ break;
+
+ case 'X':
+ /* This is used by Sun FORTRAN for "function result value".
+ Sun claims ("dbx and dbxtool interfaces", 2nd ed)
+ that Pascal uses it too, but when I tried it Pascal used
+ "x:3" (local symbol) instead. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
+ value))
+ return false;
+ break;
+
+ default:
+ bad_stab (string);
+ return false;
+ }
+
+ /* FIXME: gdb converts structure values to structure pointers in a
+ couple of cases, depending upon the target. */
+
+ return true;
+}
+
+/* Parse a stabs type. The typename argument is non-NULL if this is a
+ typedef or a tag definition. The pp argument points to the stab
+ string, and is updated. The slotp argument points to a place to
+ store the slot used if the type is being defined. */
+
+static debug_type
+parse_stab_type (dhandle, info, typename, pp, slotp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *typename;
+ const char **pp;
+ debug_type **slotp;
+{
+ const char *orig;
+ int typenums[2];
+ int size;
+ boolean stringp;
+ int descriptor;
+ debug_type dtype;
+
+ if (slotp != NULL)
+ *slotp = NULL;
+
+ orig = *pp;
+
+ size = -1;
+ stringp = false;
+
+ /* Read type number if present. The type number may be omitted.
+ for instance in a two-dimensional array declared with type
+ "ar1;1;10;ar1;1;10;4". */
+ if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-')
+ {
+ /* 'typenums=' not present, type is anonymous. Read and return
+ the definition, but don't put it in the type vector. */
+ typenums[0] = typenums[1] = -1;
+ }
+ else
+ {
+ if (! parse_stab_type_number (pp, typenums))
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != '=')
+ {
+ /* Type is not being defined here. Either it already
+ exists, or this is a forward reference to it. */
+ return stab_find_type (dhandle, info, typenums);
+ }
+
+ /* Only set the slot if the type is being defined. This means
+ that the mapping from type numbers to types will only record
+ the name of the typedef which defines a type. If we don't do
+ this, then something like
+ typedef int foo;
+ int i;
+ will record that i is of type foo. Unfortunately, stabs
+ information is ambiguous about variable types. For this code,
+ typedef int foo;
+ int i;
+ foo j;
+ the stabs information records both i and j as having the same
+ type. This could be fixed by patching the compiler. */
+ if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0)
+ *slotp = stab_find_slot (info, typenums);
+
+ /* Type is being defined here. */
+ /* Skip the '='. */
+ ++*pp;
+
+ while (**pp == '@')
+ {
+ const char *p = *pp + 1;
+ const char *attr;
+
+ if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+ {
+ /* Member type. */
+ break;
+ }
+
+ /* Type attributes. */
+ attr = p;
+
+ for (; *p != ';'; ++p)
+ {
+ if (*p == '\0')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ }
+ *pp = p + 1;
+
+ switch (*attr)
+ {
+ case 's':
+ size = atoi (attr + 1);
+ if (size <= 0)
+ size = -1;
+ break;
+
+ case 'S':
+ stringp = true;
+ break;
+
+ default:
+ /* Ignore unrecognized type attributes, so future
+ compilers can invent new ones. */
+ break;
+ }
+ }
+ }
+
+ descriptor = **pp;
+ ++*pp;
+
+ switch (descriptor)
+ {
+ case 'x':
+ {
+ enum debug_type_kind code;
+ const char *q1, *q2, *p;
+
+ /* A cross reference to another type. */
+
+ switch (**pp)
+ {
+ case 's':
+ code = DEBUG_KIND_STRUCT;
+ break;
+ case 'u':
+ code = DEBUG_KIND_UNION;
+ break;
+ case 'e':
+ code = DEBUG_KIND_ENUM;
+ break;
+ default:
+ /* Complain and keep going, so compilers can invent new
+ cross-reference types. */
+ warn_stab (orig, "unrecognized cross reference type");
+ code = DEBUG_KIND_STRUCT;
+ break;
+ }
+ ++*pp;
+
+ q1 = strchr (*pp, '<');
+ p = strchr (*pp, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ while (q1 != NULL && p > q1 && p[1] == ':')
+ {
+ q2 = strchr (q1, '>');
+ if (q2 == NULL || q2 < p)
+ break;
+ p += 2;
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ }
+
+ dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
+
+ *pp = p + 1;
+ }
+ break;
+
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '(':
+ {
+ const char *hold;
+ int xtypenums[2];
+
+ /* This type is defined as another type. */
+
+ (*pp)--;
+ hold = *pp;
+
+ /* Peek ahead at the number to detect void. */
+ if (! parse_stab_type_number (pp, xtypenums))
+ return DEBUG_TYPE_NULL;
+
+ if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
+ {
+ /* This type is being defined as itself, which means that
+ it is void. */
+ dtype = debug_make_void_type (dhandle);
+ }
+ else
+ {
+ *pp = hold;
+
+ /* Go back to the number and have parse_stab_type get it.
+ This means that we can deal with something like
+ t(1,2)=(3,4)=... which the Lucid compiler uses. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (typenums[0] != -1)
+ {
+ if (! stab_record_type (dhandle, info, typenums, dtype))
+ return DEBUG_TYPE_NULL;
+ }
+
+ break;
+ }
+
+ case '*':
+ dtype = debug_make_pointer_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL));
+ break;
+
+ case '&':
+ /* Reference to another type. */
+ dtype = (debug_make_reference_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL)));
+ break;
+
+ case 'f':
+ /* Function returning another type. */
+ /* FIXME: gdb checks os9k_stabs here. */
+ dtype = (debug_make_function_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL),
+ (debug_type *) NULL, false));
+ break;
+
+ case 'k':
+ /* Const qualifier on some type (Sun). */
+ /* FIXME: gdb accepts 'c' here if os9k_stabs. */
+ dtype = debug_make_const_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL));
+ break;
+
+ case 'B':
+ /* Volatile qual on some type (Sun). */
+ /* FIXME: gdb accepts 'i' here if os9k_stabs. */
+ dtype = (debug_make_volatile_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL)));
+ break;
+
+ case '@':
+ /* Offset (class & variable) type. This is used for a pointer
+ relative to an object. */
+ {
+ debug_type domain;
+ debug_type memtype;
+
+ /* Member type. */
+
+ domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (domain == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (memtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ dtype = debug_make_offset_type (dhandle, domain, memtype);
+ }
+ break;
+
+ case '#':
+ /* Method (class & fn) type. */
+ if (**pp == '#')
+ {
+ debug_type return_type;
+
+ ++*pp;
+ return_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (return_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+ dtype = debug_make_method_type (dhandle, return_type,
+ DEBUG_TYPE_NULL,
+ (debug_type *) NULL, false);
+ }
+ else
+ {
+ debug_type domain;
+ debug_type return_type;
+ debug_type *args;
+ unsigned int n;
+ unsigned int alloc;
+ boolean varargs;
+
+ domain = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (domain == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ return_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (return_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ alloc = 10;
+ args = (debug_type *) xmalloc (alloc * sizeof *args);
+ n = 0;
+ while (**pp != ';')
+ {
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (n + 1 >= alloc)
+ {
+ alloc += 10;
+ args = ((debug_type *)
+ xrealloc ((PTR) args, alloc * sizeof *args));
+ }
+
+ args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (args[n] == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ ++n;
+ }
+ ++*pp;
+
+ /* If the last type is not void, then this function takes a
+ variable number of arguments. Otherwise, we must strip
+ the void type. */
+ if (n == 0
+ || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
+ varargs = true;
+ else
+ {
+ --n;
+ varargs = false;
+ }
+
+ args[n] = DEBUG_TYPE_NULL;
+
+ dtype = debug_make_method_type (dhandle, return_type, domain, args,
+ varargs);
+ }
+ break;
+
+ case 'r':
+ /* Range type. */
+ dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
+ break;
+
+ case 'b':
+ /* FIXME: gdb checks os9k_stabs here. */
+ /* Sun ACC builtin int type. */
+ dtype = parse_stab_sun_builtin_type (dhandle, pp);
+ break;
+
+ case 'R':
+ /* Sun ACC builtin float type. */
+ dtype = parse_stab_sun_floating_type (dhandle, pp);
+ break;
+
+ case 'e':
+ /* Enumeration type. */
+ dtype = parse_stab_enum_type (dhandle, pp);
+ break;
+
+ case 's':
+ case 'u':
+ /* Struct or union type. */
+ dtype = parse_stab_struct_type (dhandle, info, typename, pp,
+ descriptor == 's', typenums);
+ break;
+
+ case 'a':
+ /* Array type. */
+ if (**pp != 'r')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ dtype = parse_stab_array_type (dhandle, info, pp, stringp);
+ break;
+
+ case 'S':
+ dtype = debug_make_set_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL),
+ stringp);
+ break;
+
+ default:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (dtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (typenums[0] != -1)
+ {
+ if (! stab_record_type (dhandle, info, typenums, dtype))
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (size != -1)
+ {
+ if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
+ return DEBUG_TYPE_NULL;
+ }
+
+ return dtype;
+}
+
+/* Read a number by which a type is referred to in dbx data, or
+ perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a
+ single number N is equivalent to (0,N). Return the two numbers by
+ storing them in the vector TYPENUMS. */
+
+static boolean
+parse_stab_type_number (pp, typenums)
+ const char **pp;
+ int *typenums;
+{
+ const char *orig;
+
+ orig = *pp;
+
+ if (**pp != '(')
+ {
+ typenums[0] = 0;
+ typenums[1] = (int) parse_number (pp, (boolean *) NULL);
+ }
+ else
+ {
+ ++*pp;
+ typenums[0] = (int) parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ typenums[1] = (int) parse_number (pp, (boolean *) NULL);
+ if (**pp != ')')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ }
+
+ return true;
+}
+
+/* Parse a range type. */
+
+static debug_type
+parse_stab_range_type (dhandle, info, typename, pp, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *typename;
+ const char **pp;
+ const int *typenums;
+{
+ const char *orig;
+ int rangenums[2];
+ boolean self_subrange;
+ debug_type index_type;
+ const char *s2, *s3;
+ bfd_signed_vma n2, n3;
+ boolean ov2, ov3;
+
+ orig = *pp;
+
+ index_type = DEBUG_TYPE_NULL;
+
+ /* First comes a type we are a subrange of.
+ In C it is usually 0, 1 or the type being defined. */
+ if (! parse_stab_type_number (pp, rangenums))
+ return DEBUG_TYPE_NULL;
+
+ self_subrange = (rangenums[0] == typenums[0]
+ && rangenums[1] == typenums[1]);
+
+ if (**pp == '=')
+ {
+ *pp = orig;
+ index_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (index_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (**pp == ';')
+ ++*pp;
+
+ /* The remaining two operands are usually lower and upper bounds of
+ the range. But in some special cases they mean something else. */
+ s2 = *pp;
+ n2 = parse_number (pp, &ov2);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ s3 = *pp;
+ n3 = parse_number (pp, &ov3);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (ov2 || ov3)
+ {
+ /* gcc will emit range stabs for long long types. Handle this
+ as a special case. FIXME: This needs to be more general. */
+#define LLLOW "01000000000000000000000;"
+#define LLHIGH "0777777777777777777777;"
+#define ULLHIGH "01777777777777777777777;"
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
+ && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
+ return debug_make_int_type (dhandle, 8, false);
+ if (! ov2
+ && n2 == 0
+ && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
+ return debug_make_int_type (dhandle, 8, true);
+ }
+
+ warn_stab (orig, "numeric overflow");
+ }
+
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ /* A type defined as a subrange of itself, with both bounds 0,
+ is void. */
+ if (self_subrange && n2 == 0 && n3 == 0)
+ return debug_make_void_type (dhandle);
+
+ /* A type defined as a subrange of itself, with n2 positive and
+ n3 zero, is a complex type, and n2 is the number of bytes. */
+ if (self_subrange && n3 == 0 && n2 > 0)
+ return debug_make_complex_type (dhandle, n2);
+
+ /* If n3 is zero and n2 is positive, this is a floating point
+ type, and n2 is the number of bytes. */
+ if (n3 == 0 && n2 > 0)
+ return debug_make_float_type (dhandle, n2);
+
+ /* If the upper bound is -1, this is an unsigned int. */
+ if (n2 == 0 && n3 == -1)
+ {
+ /* When gcc is used with -gstabs, but not -gstabs+, it will emit
+ long long int:t6=r1;0;-1;
+ long long unsigned int:t7=r1;0;-1;
+ We hack here to handle this reasonably. */
+ if (typename != NULL)
+ {
+ if (strcmp (typename, "long long int") == 0)
+ return debug_make_int_type (dhandle, 8, false);
+ else if (strcmp (typename, "long long unsigned int") == 0)
+ return debug_make_int_type (dhandle, 8, true);
+ }
+ /* FIXME: The size here really depends upon the target. */
+ return debug_make_int_type (dhandle, 4, true);
+ }
+
+ /* A range of 0 to 127 is char. */
+ if (self_subrange && n2 == 0 && n3 == 127)
+ return debug_make_int_type (dhandle, 1, false);
+
+ /* FIXME: gdb checks for the language CHILL here. */
+
+ if (n2 == 0)
+ {
+ if (n3 < 0)
+ return debug_make_int_type (dhandle, - n3, true);
+ else if (n3 == 0xff)
+ return debug_make_int_type (dhandle, 1, true);
+ else if (n3 == 0xffff)
+ return debug_make_int_type (dhandle, 2, true);
+ /* -1 is used for the upper bound of (4 byte) "unsigned int"
+ and "unsigned long", and we already checked for that, so
+ don't need to test for it here. */
+ }
+ else if (n3 == 0
+ && n2 < 0
+ && (self_subrange || n2 == -8))
+ return debug_make_int_type (dhandle, - n2, true);
+ else if (n2 == - n3 - 1)
+ {
+ if (n3 == 0x7f)
+ return debug_make_int_type (dhandle, 1, false);
+ else if (n3 == 0x7fff)
+ return debug_make_int_type (dhandle, 2, false);
+ else if (n3 == 0x7fffffff)
+ return debug_make_int_type (dhandle, 4, false);
+ }
+ }
+
+ /* At this point I don't have the faintest idea how to deal with a
+ self_subrange type; I'm going to assume that this is used as an
+ idiom, and that all of them are special cases. So . . . */
+ if (self_subrange)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ index_type = stab_find_type (dhandle, info, rangenums);
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ /* Does this actually ever happen? Is that why we are worrying
+ about dealing with it rather than just calling error_type? */
+ warn_stab (orig, "missing index type");
+ index_type = debug_make_int_type (dhandle, 4, false);
+ }
+
+ return debug_make_range_type (dhandle, index_type, n2, n3);
+}
+
+/* Sun's ACC uses a somewhat saner method for specifying the builtin
+ typedefs in every file (for int, long, etc):
+
+ type = b <signed> <width>; <offset>; <nbits>
+ signed = u or s. Possible c in addition to u or s (for char?).
+ offset = offset from high order bit to start bit of type.
+ width is # bytes in object of this type, nbits is # bits in type.
+
+ The width/offset stuff appears to be for small objects stored in
+ larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
+ FIXME. */
+
+static debug_type
+parse_stab_sun_builtin_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ boolean unsignedp;
+ bfd_vma bits;
+
+ orig = *pp;
+
+ switch (**pp)
+ {
+ case 's':
+ unsignedp = false;
+ break;
+ case 'u':
+ unsignedp = true;
+ break;
+ default:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* For some odd reason, all forms of char put a c here. This is strange
+ because no other type has this honor. We can safely ignore this because
+ we actually determine 'char'acterness by the number of bits specified in
+ the descriptor. */
+ if (**pp == 'c')
+ ++*pp;
+
+ /* The first number appears to be the number of bytes occupied
+ by this type, except that unsigned short is 4 instead of 2.
+ Since this information is redundant with the third number,
+ we will ignore it. */
+ (void) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* The second number is always 0, so ignore it too. */
+ (void) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* The third number is the number of bits for this type. */
+ bits = parse_number (pp, (boolean *) NULL);
+
+ /* The type *should* end with a semicolon. If it are embedded
+ in a larger type the semicolon may be the only way to know where
+ the type ends. If this type is at the end of the stabstring we
+ can deal with the omitted semicolon (but we don't have to like
+ it). Don't bother to complain(), Sun's compiler omits the semicolon
+ for "void". */
+ if (**pp == ';')
+ ++*pp;
+
+ if (bits == 0)
+ return debug_make_void_type (dhandle);
+
+ return debug_make_int_type (dhandle, bits / 8, unsignedp);
+}
+
+/* Parse a builtin floating type generated by the Sun compiler. */
+
+static debug_type
+parse_stab_sun_floating_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ bfd_vma details;
+ bfd_vma bytes;
+
+ orig = *pp;
+
+ /* The first number has more details about the type, for example
+ FN_COMPLEX. */
+ details = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ /* The second number is the number of bytes occupied by this type */
+ bytes = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (details == NF_COMPLEX
+ || details == NF_COMPLEX16
+ || details == NF_COMPLEX32)
+ return debug_make_complex_type (dhandle, bytes);
+
+ return debug_make_float_type (dhandle, bytes);
+}
+
+/* Handle an enum type. */
+
+static debug_type
+parse_stab_enum_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ const char **names;
+ bfd_signed_vma *values;
+ unsigned int n;
+ unsigned int alloc;
+
+ orig = *pp;
+
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ /* The aix4 compiler emits an extra field before the enum members;
+ my guess is it's a type of some sort. Just ignore it. */
+ if (**pp == '-')
+ {
+ while (**pp != ':')
+ ++*pp;
+ ++*pp;
+ }
+
+ /* Read the value-names and their values.
+ The input syntax is NAME:VALUE,NAME:VALUE, and so on.
+ A semicolon or comma instead of a NAME means the end. */
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values);
+ n = 0;
+ while (**pp != '\0' && **pp != ';' && **pp != ',')
+ {
+ const char *p;
+ char *name;
+ bfd_signed_vma val;
+
+ p = *pp;
+ while (*p != ':')
+ ++p;
+
+ name = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+ val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (n + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc ((PTR) names, alloc * sizeof *names));
+ values = ((bfd_signed_vma *)
+ xrealloc ((PTR) values, alloc * sizeof *values));
+ }
+
+ names[n] = name;
+ values[n] = val;
+ ++n;
+ }
+
+ names[n] = NULL;
+ values[n] = 0;
+
+ if (**pp == ';')
+ ++*pp;
+
+ return debug_make_enum_type (dhandle, names, values);
+}
+
+/* Read the description of a structure (or union type) and return an object
+ describing the type.
+
+ PP points to a character pointer that points to the next unconsumed token
+ in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
+ *PP will point to "4a:1,0,32;;". */
+
+static debug_type
+parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *tagname;
+ const char **pp;
+ boolean structp;
+ const int *typenums;
+{
+ const char *orig;
+ bfd_vma size;
+ debug_baseclass *baseclasses;
+ debug_field *fields;
+ boolean statics;
+ debug_method *methods;
+ debug_type vptrbase;
+ boolean ownvptr;
+
+ orig = *pp;
+
+ /* Get the size. */
+ size = parse_number (pp, (boolean *) NULL);
+
+ /* Get the other information. */
+ if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
+ || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
+ || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
+ || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
+ &ownvptr))
+ return DEBUG_TYPE_NULL;
+
+ if (! statics
+ && baseclasses == NULL
+ && methods == NULL
+ && vptrbase == DEBUG_TYPE_NULL
+ && ! ownvptr)
+ return debug_make_struct_type (dhandle, structp, size, fields);
+
+ return debug_make_object_type (dhandle, structp, size, fields, baseclasses,
+ methods, vptrbase, ownvptr);
+}
+
+/* The stabs for C++ derived classes contain baseclass information which
+ is marked by a '!' character after the total size. This function is
+ called when we encounter the baseclass marker, and slurps up all the
+ baseclass information.
+
+ Immediately following the '!' marker is the number of base classes that
+ the class is derived from, followed by information for each base class.
+ For each base class, there are two visibility specifiers, a bit offset
+ to the base class information within the derived class, a reference to
+ the type for the base class, and a terminating semicolon.
+
+ A typical example, with two base classes, would be "!2,020,19;0264,21;".
+ ^^ ^ ^ ^ ^ ^ ^
+ Baseclass information marker __________________|| | | | | | |
+ Number of baseclasses __________________________| | | | | | |
+ Visibility specifiers (2) ________________________| | | | | |
+ Offset in bits from start of class _________________| | | | |
+ Type number for base class ___________________________| | | |
+ Visibility specifiers (2) _______________________________| | |
+ Offset in bits from start of class ________________________| |
+ Type number of base class ____________________________________|
+
+ Return true for success, false for failure. */
+
+static boolean
+parse_stab_baseclasses (dhandle, info, pp, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_baseclass **retp;
+{
+ const char *orig;
+ unsigned int c, i;
+ debug_baseclass *classes;
+
+ *retp = NULL;
+
+ orig = *pp;
+
+ if (**pp != '!')
+ {
+ /* No base classes. */
+ return true;
+ }
+ ++*pp;
+
+ c = (unsigned int) parse_number (pp, (boolean *) NULL);
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp));
+
+ for (i = 0; i < c; i++)
+ {
+ boolean virtual;
+ enum debug_visibility visibility;
+ bfd_vma bitpos;
+ debug_type type;
+
+ switch (**pp)
+ {
+ case '0':
+ virtual = false;
+ break;
+ case '1':
+ virtual = true;
+ break;
+ default:
+ warn_stab (orig, "unknown virtual character for baseclass");
+ virtual = false;
+ break;
+ }
+ ++*pp;
+
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ case '2':
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ default:
+ warn_stab (orig, "unknown visibility character for baseclass");
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+
+ /* The remaining value is the bit offset of the portion of the
+ object corresponding to this baseclass. Always zero in the
+ absence of multiple inheritance. */
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
+ visibility);
+ if (classes[i] == DEBUG_BASECLASS_NULL)
+ return false;
+
+ if (**pp != ';')
+ return false;
+ ++*pp;
+ }
+
+ classes[i] = DEBUG_BASECLASS_NULL;
+
+ *retp = classes;
+
+ return true;
+}
+
+/* Read struct or class data fields. They have the form:
+
+ NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
+
+ At the end, we see a semicolon instead of a field.
+
+ In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
+ a static field.
+
+ The optional VISIBILITY is one of:
+
+ '/0' (VISIBILITY_PRIVATE)
+ '/1' (VISIBILITY_PROTECTED)
+ '/2' (VISIBILITY_PUBLIC)
+ '/9' (VISIBILITY_IGNORE)
+
+ or nothing, for C style fields with public visibility.
+
+ Returns 1 for success, 0 for failure. */
+
+static boolean
+parse_stab_struct_fields (dhandle, info, pp, retp, staticsp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_field **retp;
+ boolean *staticsp;
+{
+ const char *orig;
+ const char *p;
+ debug_field *fields;
+ unsigned int c;
+ unsigned int alloc;
+
+ *retp = NULL;
+ *staticsp = false;
+
+ orig = *pp;
+
+ c = 0;
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ while (**pp != ';')
+ {
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ p = *pp;
+
+ /* Add 1 to c to leave room for NULL pointer at end. */
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc ((PTR) fields, alloc * sizeof *fields));
+ }
+
+ /* If it starts with CPLUS_MARKER it is a special abbreviation,
+ unless the CPLUS_MARKER is followed by an underscore, in
+ which case it is just the name of an anonymous type, which we
+ should handle like any other type name. We accept either '$'
+ or '.', because a field name can never contain one of these
+ characters except as a CPLUS_MARKER. */
+
+ if ((*p == '$' || *p == '.') && p[1] != '_')
+ {
+ ++*pp;
+ if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
+ return false;
+ ++c;
+ continue;
+ }
+
+ /* Look for the ':' that separates the field name from the field
+ values. Data members are delimited by a single ':', while member
+ functions are delimited by a pair of ':'s. When we hit the member
+ functions (if any), terminate scan loop and return. */
+
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ if (p[1] == ':')
+ break;
+
+ if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
+ staticsp))
+ return false;
+
+ ++c;
+ }
+
+ fields[c] = DEBUG_FIELD_NULL;
+
+ *retp = fields;
+
+ return true;
+}
+
+/* Special GNU C++ name. */
+
+static boolean
+parse_stab_cpp_abbrev (dhandle, info, pp, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_field *retp;
+{
+ const char *orig;
+ int cpp_abbrev;
+ debug_type context;
+ const char *name;
+ const char *typename;
+ debug_type type;
+ bfd_vma bitpos;
+
+ *retp = DEBUG_FIELD_NULL;
+
+ orig = *pp;
+
+ if (**pp != 'v')
+ {
+ bad_stab (*pp);
+ return false;
+ }
+ ++*pp;
+
+ cpp_abbrev = **pp;
+ ++*pp;
+
+ /* At this point, *pp points to something like "22:23=*22...", where
+ the type number before the ':' is the "context" and everything
+ after is a regular type definition. Lookup the type, find it's
+ name, and construct the field name. */
+
+ context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (context == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (cpp_abbrev)
+ {
+ case 'f':
+ /* $vf -- a virtual function table pointer. */
+ name = "_vptr$";
+ break;
+ case 'b':
+ /* $vb -- a virtual bsomethingorother */
+ typename = debug_get_type_name (dhandle, context);
+ if (typename == NULL)
+ {
+ warn_stab (orig, "unnamed $vb type");
+ typename = "FOO";
+ }
+ name = concat ("_vb$", typename, (const char *) NULL);
+ break;
+ default:
+ warn_stab (orig, "unrecognized C++ abbreviation");
+ name = "INVALID_CPLUSPLUS_ABBREV";
+ break;
+ }
+
+ if (**pp != ':')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ *retp = debug_make_field (dhandle, name, type, bitpos, 0,
+ DEBUG_VISIBILITY_PRIVATE);
+ if (*retp == DEBUG_FIELD_NULL)
+ return false;
+
+ return true;
+}
+
+/* Parse a single field in a struct or union. */
+
+static boolean
+parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ const char *p;
+ debug_field *retp;
+ boolean *staticsp;
+{
+ const char *orig;
+ char *name;
+ enum debug_visibility visibility;
+ debug_type type;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+
+ orig = *pp;
+
+ /* FIXME: gdb checks ARM_DEMANGLING here. */
+
+ name = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+
+ if (**pp != '/')
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ else
+ {
+ ++*pp;
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ case '2':
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ default:
+ warn_stab (orig, "unknown visibility character for field");
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+ }
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (**pp == ':')
+ {
+ char *varname;
+
+ /* This is a static class member. */
+ ++*pp;
+ p = strchr (*pp, ';');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ varname = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+
+ *retp = debug_make_static_member (dhandle, name, type, varname,
+ visibility);
+ *staticsp = true;
+
+ return true;
+ }
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitsize = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (bitpos == 0 && bitsize == 0)
+ {
+ /* This can happen in two cases: (1) at least for gcc 2.4.5 or
+ so, it is a field which has been optimized out. The correct
+ stab for this case is to use VISIBILITY_IGNORE, but that is a
+ recent invention. (2) It is a 0-size array. For example
+ union { int num; char str[0]; } foo. Printing "<no value>"
+ for str in "p foo" is OK, since foo.str (and thus foo.str[3])
+ will continue to work, and a 0-size array as a whole doesn't
+ have any contents to print.
+
+ I suspect this probably could also happen with gcc -gstabs
+ (not -gstabs+) for static fields, and perhaps other C++
+ extensions. Hopefully few people use -gstabs with gdb, since
+ it is intended for dbx compatibility. */
+ visibility = DEBUG_VISIBILITY_IGNORE;
+ }
+
+ /* FIXME: gdb does some stuff here to mark fields as unpacked. */
+
+ *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility);
+
+ return true;
+}
+
+/* Read member function stabs info for C++ classes. The form of each member
+ function data is:
+
+ NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
+
+ An example with two member functions is:
+
+ afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
+
+ For the case of overloaded operators, the format is op$::*.funcs, where
+ $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
+ name (such as `+=') and `.' marks the end of the operator name. */
+
+static boolean
+parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *tagname;
+ const char **pp;
+ const int *typenums;
+ debug_method **retp;
+{
+ const char *orig;
+ debug_method *methods;
+ unsigned int c;
+ unsigned int alloc;
+
+ *retp = NULL;
+
+ orig = *pp;
+
+ alloc = 0;
+ methods = NULL;
+ c = 0;
+
+ while (**pp != ';')
+ {
+ const char *p;
+ char *name;
+ debug_method_variant *variants;
+ unsigned int cvars;
+ unsigned int allocvars;
+ debug_type look_ahead_type;
+
+ p = strchr (*pp, ':');
+ if (p == NULL || p[1] != ':')
+ break;
+
+ /* FIXME: Some systems use something other than '$' here. */
+ if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$')
+ {
+ name = savestring (*pp, p - *pp);
+ *pp = p + 2;
+ }
+ else
+ {
+ /* This is a completely wierd case. In order to stuff in the
+ names that might contain colons (the usual name delimiter),
+ Mike Tiemann defined a different name format which is
+ signalled if the identifier is "op$". In that case, the
+ format is "op$::XXXX." where XXXX is the name. This is
+ used for names like "+" or "=". YUUUUUUUK! FIXME! */
+ *pp = p + 2;
+ for (p = *pp; *p != '.' && *p != '\0'; p++)
+ ;
+ if (*p != '.')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ name = savestring (*pp, p - *pp);
+ *pp = p + 1;
+ }
+
+ allocvars = 10;
+ variants = ((debug_method_variant *)
+ xmalloc (allocvars * sizeof *variants));
+ cvars = 0;
+
+ look_ahead_type = DEBUG_TYPE_NULL;
+
+ do
+ {
+ debug_type type;
+ boolean stub;
+ char *argtypes;
+ enum debug_visibility visibility;
+ boolean constp, volatilep, staticp;
+ bfd_vma voffset;
+ debug_type context;
+ const char *physname;
+ boolean varargs;
+
+ if (look_ahead_type != DEBUG_TYPE_NULL)
+ {
+ /* g++ version 1 kludge */
+ type = look_ahead_type;
+ look_ahead_type = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ if (**pp != ':')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ }
+
+ ++*pp;
+ p = strchr (*pp, ';');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ stub = false;
+ if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
+ && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
+ stub = true;
+
+ argtypes = savestring (*pp, p - *pp);
+ *pp = p + 1;
+
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ default:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+
+ constp = false;
+ volatilep = false;
+ switch (**pp)
+ {
+ case 'A':
+ /* Normal function. */
+ ++*pp;
+ break;
+ case 'B':
+ /* const member function. */
+ constp = true;
+ ++*pp;
+ break;
+ case 'C':
+ /* volatile member function. */
+ volatilep = true;
+ ++*pp;
+ break;
+ case 'D':
+ /* const volatile member function. */
+ constp = true;
+ volatilep = true;
+ ++*pp;
+ break;
+ case '*':
+ case '?':
+ case '.':
+ /* File compiled with g++ version 1; no information. */
+ break;
+ default:
+ warn_stab (orig, "const/volatile indicator missing");
+ break;
+ }
+
+ staticp = false;
+ switch (**pp)
+ {
+ case '*':
+ /* virtual member function, followed by index. The sign
+ bit is supposedly set to distinguish
+ pointers-to-methods from virtual function indicies. */
+ ++*pp;
+ voffset = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ voffset &= 0x7fffffff;
+
+ if (**pp == ';' || *pp == '\0')
+ {
+ /* Must be g++ version 1. */
+ context = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ /* Figure out from whence this virtual function
+ came. It may belong to virtual function table of
+ one of its baseclasses. */
+ look_ahead_type = parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL);
+ if (**pp == ':')
+ {
+ /* g++ version 1 overloaded methods. */
+ context = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ context = look_ahead_type;
+ look_ahead_type = DEBUG_TYPE_NULL;
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ }
+ }
+ break;
+
+ case '?':
+ /* static member function. */
+ ++*pp;
+ staticp = true;
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ if (strncmp (argtypes, name, strlen (name)) != 0)
+ stub = true;
+ break;
+
+ default:
+ warn_stab (orig, "member function type missing");
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ break;
+
+ case '.':
+ ++*pp;
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ break;
+ }
+
+ /* If the type is not a stub, then the argtypes string is
+ the physical name of the function. Otherwise the
+ argtypes string is the mangled form of the argument
+ types, and the full type and the physical name must be
+ extracted from them. */
+ if (! stub)
+ physname = argtypes;
+ else
+ {
+ debug_type class_type, return_type;
+
+ class_type = stab_find_type (dhandle, info, typenums);
+ if (class_type == DEBUG_TYPE_NULL)
+ return false;
+ return_type = debug_get_return_type (dhandle, type);
+ if (return_type == DEBUG_TYPE_NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+ type = parse_stab_argtypes (dhandle, info, class_type, name,
+ tagname, return_type, argtypes,
+ constp, volatilep, &physname);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ if (cvars + 1 >= allocvars)
+ {
+ allocvars += 10;
+ variants = ((debug_method_variant *)
+ xrealloc ((PTR) variants,
+ allocvars * sizeof *variants));
+ }
+
+ if (! staticp)
+ variants[cvars] = debug_make_method_variant (dhandle, physname,
+ type, visibility,
+ constp, volatilep,
+ voffset, context);
+ else
+ variants[cvars] = debug_make_static_method_variant (dhandle,
+ physname,
+ type,
+ visibility,
+ constp,
+ volatilep);
+ if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
+ return false;
+
+ ++cvars;
+ }
+ while (**pp != ';' && **pp != '\0');
+
+ variants[cvars] = DEBUG_METHOD_VARIANT_NULL;
+
+ if (**pp != '\0')
+ ++*pp;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ methods = ((debug_method *)
+ xrealloc ((PTR) methods, alloc * sizeof *methods));
+ }
+
+ methods[c] = debug_make_method (dhandle, name, variants);
+
+ ++c;
+ }
+
+ if (methods != NULL)
+ methods[c] = DEBUG_METHOD_NULL;
+
+ *retp = methods;
+
+ return true;
+}
+
+/* Parse a string representing argument types for a method. Stabs
+ tries to save space by packing argument types into a mangled
+ string. This string should give us enough information to extract
+ both argument types and the physical name of the function, given
+ the tag name. */
+
+static debug_type
+parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
+ return_type, argtypes, constp, volatilep, pphysname)
+ PTR dhandle;
+ struct stab_handle *info;
+ debug_type class_type;
+ const char *fieldname;
+ const char *tagname;
+ debug_type return_type;
+ const char *argtypes;
+ boolean constp;
+ boolean volatilep;
+ const char **pphysname;
+{
+ boolean is_full_physname_constructor;
+ boolean is_constructor;
+ boolean is_destructor;
+ debug_type *args;
+ boolean varargs;
+
+ /* Constructors are sometimes handled specially. */
+ is_full_physname_constructor = ((argtypes[0] == '_'
+ && argtypes[1] == '_'
+ && (isdigit ((unsigned char) argtypes[2])
+ || argtypes[2] == 'Q'
+ || argtypes[2] == 't'))
+ || strncmp (argtypes, "__ct", 4) == 0);
+
+ is_constructor = (is_full_physname_constructor
+ || (tagname != NULL
+ && strcmp (fieldname, tagname) == 0));
+ is_destructor = ((argtypes[0] == '_'
+ && (argtypes[1] == '$' || argtypes[1] == '.')
+ && argtypes[2] == '_')
+ || strncmp (argtypes, "__dt", 4) == 0);
+
+ if (is_destructor || is_full_physname_constructor)
+ *pphysname = argtypes;
+ else
+ {
+ unsigned int len;
+ const char *const_prefix;
+ const char *volatile_prefix;
+ char buf[20];
+ unsigned int mangled_name_len;
+ char *physname;
+
+ len = tagname == NULL ? 0 : strlen (tagname);
+ const_prefix = constp ? "C" : "";
+ volatile_prefix = volatilep ? "V" : "";
+
+ if (len == 0)
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ else if (tagname != NULL && strchr (tagname, '<') != NULL)
+ {
+ /* Template methods are fully mangled. */
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ tagname = NULL;
+ len = 0;
+ }
+ else
+ sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+
+ mangled_name_len = ((is_constructor ? 0 : strlen (fieldname))
+ + strlen (buf)
+ + len
+ + strlen (argtypes)
+ + 1);
+
+ if (fieldname[0] == 'o'
+ && fieldname[1] == 'p'
+ && (fieldname[2] == '$' || fieldname[2] == '.'))
+ {
+ const char *opname;
+
+ opname = cplus_mangle_opname (fieldname + 3, 0);
+ if (opname == NULL)
+ {
+ fprintf (stderr, "No mangling for \"%s\"\n", fieldname);
+ return DEBUG_TYPE_NULL;
+ }
+ mangled_name_len += strlen (opname);
+ physname = (char *) xmalloc (mangled_name_len);
+ strncpy (physname, fieldname, 3);
+ strcpy (physname + 3, opname);
+ }
+ else
+ {
+ physname = (char *) xmalloc (mangled_name_len);
+ if (is_constructor)
+ physname[0] = '\0';
+ else
+ strcpy (physname, fieldname);
+ }
+
+ strcat (physname, buf);
+ if (tagname != NULL)
+ strcat (physname, tagname);
+ strcat (physname, argtypes);
+
+ *pphysname = physname;
+ }
+
+ if (*argtypes == '\0' || is_destructor)
+ {
+ args = (debug_type *) xmalloc (sizeof *args);
+ *args = NULL;
+ return debug_make_method_type (dhandle, return_type, class_type, args,
+ false);
+ }
+
+ args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
+ if (args == NULL)
+ return DEBUG_TYPE_NULL;
+
+ return debug_make_method_type (dhandle, return_type, class_type, args,
+ varargs);
+}
+
+/* The tail end of stabs for C++ classes that contain a virtual function
+ pointer contains a tilde, a %, and a type number.
+ The type number refers to the base class (possibly this class itself) which
+ contains the vtable pointer for the current class.
+
+ This function is called when we have parsed all the method declarations,
+ so we can look for the vptr base class info. */
+
+static boolean
+parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ const int *typenums;
+ debug_type *retvptrbase;
+ boolean *retownvptr;
+{
+ const char *orig;
+ const char *hold;
+ int vtypenums[2];
+
+ *retvptrbase = DEBUG_TYPE_NULL;
+ *retownvptr = false;
+
+ orig = *pp;
+
+ /* If we are positioned at a ';', then skip it. */
+ if (**pp == ';')
+ ++*pp;
+
+ if (**pp != '~')
+ return true;
+
+ ++*pp;
+
+ if (**pp == '=' || **pp == '+' || **pp == '-')
+ {
+ /* Obsolete flags that used to indicate the presence of
+ constructors and/or destructors. */
+ ++*pp;
+ }
+
+ if (**pp != '%')
+ return true;
+
+ ++*pp;
+
+ hold = *pp;
+
+ /* The next number is the type number of the base class (possibly
+ our own class) which supplies the vtable for this class. */
+ if (! parse_stab_type_number (pp, vtypenums))
+ return false;
+
+ if (vtypenums[0] == typenums[0]
+ && vtypenums[1] == typenums[1])
+ *retownvptr = true;
+ else
+ {
+ debug_type vtype;
+ const char *p;
+
+ *pp = hold;
+
+ vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ for (p = *pp; *p != ';' && *p != '\0'; p++)
+ ;
+ if (*p != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ *retvptrbase = vtype;
+
+ *pp = p + 1;
+ }
+
+ return true;
+}
+
+/* Read a definition of an array type. */
+
+static debug_type
+parse_stab_array_type (dhandle, info, pp, stringp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ boolean stringp;
+{
+ const char *orig;
+ const char *p;
+ int typenums[2];
+ debug_type index_type;
+ boolean adjustable;
+ bfd_signed_vma lower, upper;
+ debug_type element_type;
+
+ /* Format of an array type:
+ "ar<index type>;lower;upper;<array_contents_type>".
+ OS9000: "arlower,upper;<array_contents_type>".
+
+ Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
+ for these, produce a type like float[][]. */
+
+ orig = *pp;
+
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ /* If the index type is type 0, we take it as int. */
+ p = *pp;
+ if (! parse_stab_type_number (&p, typenums))
+ return DEBUG_TYPE_NULL;
+ if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
+ {
+ index_type = debug_find_named_type (dhandle, "int");
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ index_type = debug_make_int_type (dhandle, 4, false);
+ if (index_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+ *pp = p;
+ }
+ else
+ {
+ index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ }
+
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ adjustable = false;
+
+ if (! isdigit ((unsigned char) **pp) && **pp != '-')
+ {
+ ++*pp;
+ adjustable = true;
+ }
+
+ lower = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (! isdigit ((unsigned char) **pp) && **pp != '-')
+ {
+ ++*pp;
+ adjustable = true;
+ }
+
+ upper = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (element_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (adjustable)
+ {
+ lower = 0;
+ upper = -1;
+ }
+
+ return debug_make_array_type (dhandle, element_type, index_type, lower,
+ upper, stringp);
+}
+
+/* This struct holds information about files we have seen using
+ N_BINCL. */
+
+struct bincl_file
+{
+ /* The next N_BINCL file. */
+ struct bincl_file *next;
+ /* The next N_BINCL on the stack. */
+ struct bincl_file *next_stack;
+ /* The file name. */
+ const char *name;
+ /* The hash value. */
+ bfd_vma hash;
+ /* The file index. */
+ unsigned int file;
+ /* The list of types defined in this file. */
+ struct stab_types *file_types;
+};
+
+/* Start a new N_BINCL file, pushing it onto the stack. */
+
+static void
+push_bincl (info, name, hash)
+ struct stab_handle *info;
+ const char *name;
+ bfd_vma hash;
+{
+ struct bincl_file *n;
+
+ n = (struct bincl_file *) xmalloc (sizeof *n);
+ n->next = info->bincl_list;
+ n->next_stack = info->bincl_stack;
+ n->name = name;
+ n->hash = hash;
+ n->file = info->files;
+ n->file_types = NULL;
+ info->bincl_list = n;
+ info->bincl_stack = n;
+
+ ++info->files;
+ info->file_types = ((struct stab_types **)
+ xrealloc ((PTR) info->file_types,
+ (info->files
+ * sizeof *info->file_types)));
+ info->file_types[n->file] = NULL;
+}
+
+/* Finish an N_BINCL file, at an N_EINCL, popping the name off the
+ stack. */
+
+static const char *
+pop_bincl (info)
+ struct stab_handle *info;
+{
+ struct bincl_file *o;
+
+ o = info->bincl_stack;
+ if (o == NULL)
+ return info->main_filename;
+ info->bincl_stack = o->next_stack;
+
+ o->file_types = info->file_types[o->file];
+
+ if (info->bincl_stack == NULL)
+ return info->main_filename;
+ return info->bincl_stack->name;
+}
+
+/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */
+
+static boolean
+find_excl (info, name, hash)
+ struct stab_handle *info;
+ const char *name;
+ bfd_vma hash;
+{
+ struct bincl_file *l;
+
+ ++info->files;
+ info->file_types = ((struct stab_types **)
+ xrealloc ((PTR) info->file_types,
+ (info->files
+ * sizeof *info->file_types)));
+
+ for (l = info->bincl_list; l != NULL; l = l->next)
+ if (l->hash == hash && strcmp (l->name, name) == 0)
+ break;
+ if (l == NULL)
+ {
+ warn_stab (name, "Undefined N_EXCL");
+ info->file_types[info->files - 1] = NULL;
+ return true;
+ }
+
+ info->file_types[info->files - 1] = l->file_types;
+
+ return true;
+}
+
+/* Handle a variable definition. gcc emits variable definitions for a
+ block before the N_LBRAC, so we must hold onto them until we see
+ it. The SunPRO compiler emits variable definitions after the
+ N_LBRAC, so we can call debug_record_variable immediately. */
+
+static boolean
+stab_record_variable (dhandle, info, name, type, kind, val)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *name;
+ debug_type type;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct stab_pending_var *v;
+
+ if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
+ || ! info->within_function
+ || (info->gcc_compiled == 0 && info->n_opt_found))
+ return debug_record_variable (dhandle, name, type, kind, val);
+
+ v = (struct stab_pending_var *) xmalloc (sizeof *v);
+ memset (v, 0, sizeof *v);
+
+ v->next = info->pending;
+ v->name = name;
+ v->type = type;
+ v->kind = kind;
+ v->val = val;
+ info->pending = v;
+
+ return true;
+}
+
+/* Emit pending variable definitions. This is called after we see the
+ N_LBRAC that starts the block. */
+
+static boolean
+stab_emit_pending_vars (dhandle, info)
+ PTR dhandle;
+ struct stab_handle *info;
+{
+ struct stab_pending_var *v;
+
+ v = info->pending;
+ while (v != NULL)
+ {
+ struct stab_pending_var *next;
+
+ if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val))
+ return false;
+
+ next = v->next;
+ free (v);
+ v = next;
+ }
+
+ info->pending = NULL;
+
+ return true;
+}
+
+/* Find the slot for a type in the database. */
+
+static debug_type *
+stab_find_slot (info, typenums)
+ struct stab_handle *info;
+ const int *typenums;
+{
+ int filenum;
+ int index;
+ struct stab_types **ps;
+
+ filenum = typenums[0];
+ index = typenums[1];
+
+ if (filenum < 0 || (unsigned int) filenum >= info->files)
+ {
+ fprintf (stderr, "Type file number %d out of range\n", filenum);
+ return NULL;
+ }
+ if (index < 0)
+ {
+ fprintf (stderr, "Type index number %d out of range\n", index);
+ return NULL;
+ }
+
+ ps = info->file_types + filenum;
+
+ while (index >= STAB_TYPES_SLOTS)
+ {
+ if (*ps == NULL)
+ {
+ *ps = (struct stab_types *) xmalloc (sizeof **ps);
+ memset (*ps, 0, sizeof **ps);
+ }
+ ps = &(*ps)->next;
+ index -= STAB_TYPES_SLOTS;
+ }
+ if (*ps == NULL)
+ {
+ *ps = (struct stab_types *) xmalloc (sizeof **ps);
+ memset (*ps, 0, sizeof **ps);
+ }
+
+ return (*ps)->types + index;
+}
+
+/* Find a type given a type number. If the type has not been
+ allocated yet, create an indirect type. */
+
+static debug_type
+stab_find_type (dhandle, info, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const int *typenums;
+{
+ debug_type *slot;
+
+ if (typenums[0] == 0 && typenums[1] < 0)
+ {
+ /* A negative type number indicates an XCOFF builtin type. */
+ return stab_xcoff_builtin_type (dhandle, info, typenums[1]);
+ }
+
+ slot = stab_find_slot (info, typenums);
+ if (slot == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (*slot == DEBUG_TYPE_NULL)
+ return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
+
+ return *slot;
+}
+
+/* Record that a given type number refers to a given type. */
+
+static boolean
+stab_record_type (dhandle, info, typenums, type)
+ PTR dhandle;
+ struct stab_handle *info;
+ const int *typenums;
+ debug_type type;
+{
+ debug_type *slot;
+
+ slot = stab_find_slot (info, typenums);
+ if (slot == NULL)
+ return false;
+
+ /* gdb appears to ignore type redefinitions, so we do as well. */
+
+ *slot = type;
+
+ return true;
+}
+
+/* Return an XCOFF builtin type. */
+
+static debug_type
+stab_xcoff_builtin_type (dhandle, info, typenum)
+ PTR dhandle;
+ struct stab_handle *info;
+ int typenum;
+{
+ debug_type rettype;
+ const char *name;
+
+ if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
+ {
+ fprintf (stderr, "Unrecognized XCOFF type %d\n", typenum);
+ return DEBUG_TYPE_NULL;
+ }
+ if (info->xcoff_types[-typenum] != NULL)
+ return info->xcoff_types[-typenum];
+
+ switch (-typenum)
+ {
+ case 1:
+ /* The size of this and all the other types are fixed, defined
+ by the debugging format. */
+ name = "int";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 2:
+ name = "char";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 3:
+ name = "short";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 4:
+ name = "long";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 5:
+ name = "unsigned char";
+ rettype = debug_make_int_type (dhandle, 1, true);
+ break;
+ case 6:
+ name = "signed char";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 7:
+ name = "unsigned short";
+ rettype = debug_make_int_type (dhandle, 2, true);
+ break;
+ case 8:
+ name = "unsigned int";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ break;
+ case 9:
+ name = "unsigned";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ case 10:
+ name = "unsigned long";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ break;
+ case 11:
+ name = "void";
+ rettype = debug_make_void_type (dhandle);
+ break;
+ case 12:
+ /* IEEE single precision (32 bit). */
+ name = "float";
+ rettype = debug_make_float_type (dhandle, 4);
+ break;
+ case 13:
+ /* IEEE double precision (64 bit). */
+ name = "double";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 14:
+ /* This is an IEEE double on the RS/6000, and different machines
+ with different sizes for "long double" should use different
+ negative type numbers. See stabs.texinfo. */
+ name = "long double";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 15:
+ name = "integer";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 16:
+ name = "boolean";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 17:
+ name = "short real";
+ rettype = debug_make_float_type (dhandle, 4);
+ break;
+ case 18:
+ name = "real";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 19:
+ /* FIXME */
+ name = "stringptr";
+ rettype = NULL;
+ break;
+ case 20:
+ /* FIXME */
+ name = "character";
+ rettype = debug_make_int_type (dhandle, 1, true);
+ break;
+ case 21:
+ name = "logical*1";
+ rettype = debug_make_bool_type (dhandle, 1);
+ break;
+ case 22:
+ name = "logical*2";
+ rettype = debug_make_bool_type (dhandle, 2);
+ break;
+ case 23:
+ name = "logical*4";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 24:
+ name = "logical";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 25:
+ /* Complex type consisting of two IEEE single precision values. */
+ name = "complex";
+ rettype = debug_make_complex_type (dhandle, 8);
+ break;
+ case 26:
+ /* Complex type consisting of two IEEE double precision values. */
+ name = "double complex";
+ rettype = debug_make_complex_type (dhandle, 16);
+ break;
+ case 27:
+ name = "integer*1";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 28:
+ name = "integer*2";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 29:
+ name = "integer*4";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 30:
+ /* FIXME */
+ name = "wchar";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 31:
+ name = "long long";
+ rettype = debug_make_int_type (dhandle, 8, false);
+ break;
+ case 32:
+ name = "unsigned long long";
+ rettype = debug_make_int_type (dhandle, 8, true);
+ break;
+ case 33:
+ name = "logical*8";
+ rettype = debug_make_bool_type (dhandle, 8);
+ break;
+ case 34:
+ name = "integer*8";
+ rettype = debug_make_int_type (dhandle, 8, false);
+ break;
+ default:
+ abort ();
+ }
+
+ rettype = debug_name_type (dhandle, name, rettype);
+
+ info->xcoff_types[-typenum] = rettype;
+
+ return rettype;
+}
+
+/* Find or create a tagged type. */
+
+static debug_type
+stab_find_tagged_type (dhandle, info, p, len, kind)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *p;
+ int len;
+ enum debug_type_kind kind;
+{
+ char *name;
+ debug_type dtype;
+ struct stab_tag *st;
+
+ name = savestring (p, len);
+
+ /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same
+ namespace. This is right for C, and I don't know how to handle
+ other languages. FIXME. */
+ dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL);
+ if (dtype != DEBUG_TYPE_NULL)
+ {
+ free (name);
+ return dtype;
+ }
+
+ /* We need to allocate an entry on the undefined tag list. */
+ for (st = info->tags; st != NULL; st = st->next)
+ {
+ if (st->name[0] == name[0]
+ && strcmp (st->name, name) == 0)
+ {
+ if (st->kind == DEBUG_KIND_ILLEGAL)
+ st->kind = kind;
+ free (name);
+ break;
+ }
+ }
+ if (st == NULL)
+ {
+ st = (struct stab_tag *) xmalloc (sizeof *st);
+ memset (st, 0, sizeof *st);
+
+ st->next = info->tags;
+ st->name = name;
+ st->kind = kind;
+ st->slot = DEBUG_TYPE_NULL;
+ st->type = debug_make_indirect_type (dhandle, &st->slot, name);
+ info->tags = st;
+ }
+
+ return st->type;
+}
+
+/* In order to get the correct argument types for a stubbed method, we
+ need to extract the argument types from a C++ mangled string.
+ Since the argument types can refer back to the return type, this
+ means that we must demangle the entire physical name. In gdb this
+ is done by calling cplus_demangle and running the results back
+ through the C++ expression parser. Since we have no expression
+ parser, we must duplicate much of the work of cplus_demangle here.
+
+ We assume that GNU style demangling is used, since this is only
+ done for method stubs, and only g++ should output that form of
+ debugging information. */
+
+/* This structure is used to hold a pointer to type information which
+ demangling a string. */
+
+struct stab_demangle_typestring
+{
+ /* The start of the type. This is not null terminated. */
+ const char *typestring;
+ /* The length of the type. */
+ unsigned int len;
+};
+
+/* This structure is used to hold information while demangling a
+ string. */
+
+struct stab_demangle_info
+{
+ /* The debugging information handle. */
+ PTR dhandle;
+ /* The stab information handle. */
+ struct stab_handle *info;
+ /* The array of arguments we are building. */
+ debug_type *args;
+ /* Whether the method takes a variable number of arguments. */
+ boolean varargs;
+ /* The array of types we have remembered. */
+ struct stab_demangle_typestring *typestrings;
+ /* The number of typestrings. */
+ unsigned int typestring_count;
+ /* The number of typestring slots we have allocated. */
+ unsigned int typestring_alloc;
+};
+
+static void stab_bad_demangle PARAMS ((const char *));
+static unsigned int stab_demangle_count PARAMS ((const char **));
+static boolean stab_demangle_get_count
+ PARAMS ((const char **, unsigned int *));
+static boolean stab_demangle_prefix
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_function_name
+ PARAMS ((struct stab_demangle_info *, const char **, const char *));
+static boolean stab_demangle_signature
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_qualified
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_template
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_class
+ PARAMS ((struct stab_demangle_info *, const char **, const char **));
+static boolean stab_demangle_args
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+ boolean *));
+static boolean stab_demangle_arg
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+ unsigned int *, unsigned int *));
+static boolean stab_demangle_type
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_fund_type
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_remember_type
+ PARAMS ((struct stab_demangle_info *, const char *, int));
+
+/* Warn about a bad demangling. */
+
+static void
+stab_bad_demangle (s)
+ const char *s;
+{
+ fprintf (stderr, "bad mangled name `%s'\n", s);
+}
+
+/* Get a count from a stab string. */
+
+static unsigned int
+stab_demangle_count (pp)
+ const char **pp;
+{
+ unsigned int count;
+
+ count = 0;
+ while (isdigit ((unsigned char) **pp))
+ {
+ count *= 10;
+ count += **pp - '0';
+ ++*pp;
+ }
+ return count;
+}
+
+/* Require a count in a string. The count may be multiple digits, in
+ which case it must end in an underscore. */
+
+static boolean
+stab_demangle_get_count (pp, pi)
+ const char **pp;
+ unsigned int *pi;
+{
+ if (! isdigit ((unsigned char) **pp))
+ return false;
+
+ *pi = **pp - '0';
+ ++*pp;
+ if (isdigit ((unsigned char) **pp))
+ {
+ unsigned int count;
+ const char *p;
+
+ count = *pi;
+ p = *pp;
+ do
+ {
+ count *= 10;
+ count += *p - '0';
+ ++p;
+ }
+ while (isdigit ((unsigned char) *p));
+ if (*p == '_')
+ {
+ *pp = p + 1;
+ *pi = count;
+ }
+ }
+
+ return true;
+}
+
+/* This function demangles a physical name, returning a NULL
+ terminated array of argument types. */
+
+static debug_type *
+stab_demangle_argtypes (dhandle, info, physname, pvarargs)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *physname;
+ boolean *pvarargs;
+{
+ struct stab_demangle_info minfo;
+
+ minfo.dhandle = dhandle;
+ minfo.info = info;
+ minfo.args = NULL;
+ minfo.varargs = false;
+ minfo.typestring_alloc = 10;
+ minfo.typestrings = ((struct stab_demangle_typestring *)
+ xmalloc (minfo.typestring_alloc
+ * sizeof *minfo.typestrings));
+ minfo.typestring_count = 0;
+
+ /* cplus_demangle checks for special GNU mangled forms, but we can't
+ see any of them in mangled method argument types. */
+
+ if (! stab_demangle_prefix (&minfo, &physname))
+ goto error_return;
+
+ if (*physname != '\0')
+ {
+ if (! stab_demangle_signature (&minfo, &physname))
+ goto error_return;
+ }
+
+ free (minfo.typestrings);
+ minfo.typestrings = NULL;
+
+ if (minfo.args == NULL)
+ fprintf (stderr, "no argument types in mangled string\n");
+
+ *pvarargs = minfo.varargs;
+ return minfo.args;
+
+ error_return:
+ if (minfo.typestrings != NULL)
+ free (minfo.typestrings);
+ return NULL;
+}
+
+/* Demangle the prefix of the mangled name. */
+
+static boolean
+stab_demangle_prefix (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *scan;
+ unsigned int i;
+
+ /* cplus_demangle checks for global constructors and destructors,
+ but we can't see them in mangled argument types. */
+
+ /* Look for `__'. */
+ scan = *pp;
+ do
+ {
+ scan = strchr (scan, '_');
+ }
+ while (scan != NULL && *++scan != '_');
+
+ if (scan == NULL)
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+
+ --scan;
+
+ /* We found `__'; move ahead to the last contiguous `__' pair. */
+ i = strspn (scan, "_");
+ if (i > 2)
+ scan += i - 2;
+
+ if (scan == *pp
+ && (isdigit ((unsigned char) scan[2])
+ || scan[2] == 'Q'
+ || scan[2] == 't'))
+ {
+ /* This is a GNU style constructor name. */
+ *pp = scan + 2;
+ return true;
+ }
+ else if (scan == *pp
+ && ! isdigit ((unsigned char) scan[2])
+ && scan[2] != 't')
+ {
+ /* Look for the `__' that separates the prefix from the
+ signature. */
+ while (*scan == '_')
+ ++scan;
+ scan = strstr (scan, "__");
+ if (scan == NULL || scan[2] == '\0')
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+
+ return stab_demangle_function_name (minfo, pp, scan);
+ }
+ else if (scan[2] != '\0')
+ {
+ /* The name doesn't start with `__', but it does contain `__'. */
+ return stab_demangle_function_name (minfo, pp, scan);
+ }
+ else
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+ /*NOTREACHED*/
+}
+
+/* Demangle a function name prefix. The scan argument points to the
+ double underscore which separates the function name from the
+ signature. */
+
+static boolean
+stab_demangle_function_name (minfo, pp, scan)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ const char *scan;
+{
+ const char *name;
+
+ /* The string from *pp to scan is the name of the function. We
+ don't care about the name, since we just looking for argument
+ types. However, for conversion operators, the name may include a
+ type which we must remember in order to handle backreferences. */
+
+ name = *pp;
+ *pp = scan + 2;
+
+ if (*pp - name >= 5
+ && strncmp (name, "type", 4) == 0
+ && (name[4] == '$' || name[4] == '.'))
+ {
+ const char *tem;
+
+ /* This is a type conversion operator. */
+ tem = name + 5;
+ if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
+ return false;
+ }
+ else if (name[0] == '_'
+ && name[1] == '_'
+ && name[2] == 'o'
+ && name[3] == 'p')
+ {
+ const char *tem;
+
+ /* This is a type conversion operator. */
+ tem = name + 4;
+ if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
+ return false;
+ }
+
+ return true;
+}
+
+/* Demangle the signature. This is where the argument types are
+ found. */
+
+static boolean
+stab_demangle_signature (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *orig;
+ boolean expect_func, func_done;
+ const char *hold;
+
+ orig = *pp;
+
+ expect_func = false;
+ func_done = false;
+ hold = NULL;
+
+ while (**pp != '\0')
+ {
+ switch (**pp)
+ {
+ case 'Q':
+ hold = *pp;
+ if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ expect_func = true;
+ hold = NULL;
+ break;
+
+ case 'S':
+ /* Static member function. FIXME: Can this happen? */
+ if (hold == NULL)
+ hold = *pp;
+ ++*pp;
+ break;
+
+ case 'C':
+ /* Const member function. */
+ if (hold == NULL)
+ hold = *pp;
+ ++*pp;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (hold == NULL)
+ hold = *pp;
+ if (! stab_demangle_class (minfo, pp, (const char **) NULL)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ expect_func = true;
+ hold = NULL;
+ break;
+
+ case 'F':
+ /* Function. I don't know if this actually happens with g++
+ output. */
+ hold = NULL;
+ func_done = true;
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ break;
+
+ case 't':
+ /* Template. */
+ if (hold == NULL)
+ hold = *pp;
+ if (! stab_demangle_template (minfo, pp)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ hold = NULL;
+ expect_func = true;
+ break;
+
+ case '_':
+ /* At the outermost level, we cannot have a return type
+ specified, so if we run into another '_' at this point we
+ are dealing with a mangled name that is either bogus, or
+ has been mangled by some algorithm we don't know how to
+ deal with. So just reject the entire demangling. */
+ stab_bad_demangle (orig);
+ return false;
+
+ default:
+ /* Assume we have stumbled onto the first outermost function
+ argument token, and start processing args. */
+ func_done = true;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ break;
+ }
+
+ if (expect_func)
+ {
+ func_done = true;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ }
+ }
+
+ if (! func_done)
+ {
+ /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
+ bar__3fooi is 'foo::bar(int)'. We get here when we find the
+ first case, and need to ensure that the '(void)' gets added
+ to the current declp. */
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ }
+
+ return true;
+}
+
+/* Demangle a qualified name, such as "Q25Outer5Inner" which is the
+ mangled form of "Outer::Inner". */
+
+static boolean
+stab_demangle_qualified (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+ const char *p;
+ unsigned int qualifiers;
+ debug_type context;
+
+ orig = *pp;
+
+ switch ((*pp)[1])
+ {
+ case '_':
+ /* GNU mangled name with more than 9 classes. The count is
+ preceded by an underscore (to distinguish it from the <= 9
+ case) and followed by an underscore. */
+ p = *pp + 2;
+ if (! isdigit ((unsigned char) *p) || *p == '0')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ qualifiers = atoi (p);
+ while (isdigit ((unsigned char) *p))
+ ++p;
+ if (*p != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp = p + 1;
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ qualifiers = (*pp)[1] - '0';
+ /* Skip an optional underscore after the count. */
+ if ((*pp)[2] == '_')
+ ++*pp;
+ *pp += 2;
+ break;
+
+ case '0':
+ default:
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ context = DEBUG_TYPE_NULL;
+
+ /* Pick off the names. */
+ while (qualifiers-- > 0)
+ {
+ if (**pp == '_')
+ ++*pp;
+ if (**pp == 't')
+ {
+ /* FIXME: I don't know how to handle the ptype != NULL case
+ here. */
+ if (! stab_demangle_template (minfo, pp))
+ return false;
+ }
+ else
+ {
+ unsigned int len;
+
+ len = stab_demangle_count (pp);
+ if (strlen (*pp) < len)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (ptype != NULL)
+ {
+ const debug_field *fields;
+
+ fields = NULL;
+ if (context != DEBUG_TYPE_NULL)
+ fields = debug_get_fields (minfo->dhandle, context);
+
+ context = DEBUG_TYPE_NULL;
+
+ if (fields != NULL)
+ {
+ char *name;
+
+ /* Try to find the type by looking through the
+ fields of context until we find a field with the
+ same type. This ought to work for a class
+ defined within a class, but it won't work for,
+ e.g., an enum defined within a class. stabs does
+ not give us enough information to figure out the
+ latter case. */
+
+ name = savestring (*pp, len);
+
+ for (; *fields != DEBUG_FIELD_NULL; fields++)
+ {
+ debug_type ft;
+ const char *dn;
+
+ ft = debug_get_field_type (minfo->dhandle, *fields);
+ if (ft == NULL)
+ return false;
+ dn = debug_get_type_name (minfo->dhandle, ft);
+ if (dn != NULL && strcmp (dn, name) == 0)
+ {
+ context = ft;
+ break;
+ }
+ }
+
+ free (name);
+ }
+
+ if (context == DEBUG_TYPE_NULL)
+ {
+ /* We have to fall back on finding the type by name.
+ If there are more types to come, then this must
+ be a class. Otherwise, it could be anything. */
+
+ if (qualifiers == 0)
+ {
+ char *name;
+
+ name = savestring (*pp, len);
+ context = debug_find_named_type (minfo->dhandle,
+ name);
+ free (name);
+ }
+
+ if (context == DEBUG_TYPE_NULL)
+ {
+ context = stab_find_tagged_type (minfo->dhandle,
+ minfo->info,
+ *pp, len,
+ (qualifiers == 0
+ ? DEBUG_KIND_ILLEGAL
+ : DEBUG_KIND_CLASS));
+ if (context == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+ }
+
+ *pp += len;
+ }
+ }
+
+ if (ptype != NULL)
+ *ptype = context;
+
+ return true;
+}
+
+/* Demangle a template. */
+
+static boolean
+stab_demangle_template (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *orig;
+ unsigned int r, i;
+
+ orig = *pp;
+
+ ++*pp;
+
+ /* Skip the template name. */
+ r = stab_demangle_count (pp);
+ if (r == 0 || strlen (*pp) < r)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp += r;
+
+ /* Get the size of the parameter list. */
+ if (stab_demangle_get_count (pp, &r) == 0)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ for (i = 0; i < r; i++)
+ {
+ if (**pp == 'Z')
+ {
+ /* This is a type parameter. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
+ return false;
+ }
+ else
+ {
+ const char *old_p;
+ boolean pointerp, realp, integralp, charp, boolp;
+ boolean done;
+
+ old_p = *pp;
+ pointerp = false;
+ realp = false;
+ integralp = false;
+ charp = false;
+ boolp = false;
+ done = false;
+
+ /* This is a value parameter. */
+
+ if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
+ return false;
+
+ while (*old_p != '\0' && ! done)
+ {
+ switch (*old_p)
+ {
+ case 'P':
+ case 'p':
+ case 'R':
+ pointerp = true;
+ done = true;
+ break;
+ case 'C': /* Const. */
+ case 'S': /* Signed. */
+ case 'U': /* Unsigned. */
+ case 'V': /* Volatile. */
+ case 'F': /* Function. */
+ case 'M': /* Member function. */
+ case 'O': /* ??? */
+ ++old_p;
+ break;
+ case 'Q': /* Qualified name. */
+ integralp = true;
+ done = true;
+ break;
+ case 'T': /* Remembered type. */
+ abort ();
+ case 'v': /* Void. */
+ abort ();
+ case 'x': /* Long long. */
+ case 'l': /* Long. */
+ case 'i': /* Int. */
+ case 's': /* Short. */
+ case 'w': /* Wchar_t. */
+ integralp = true;
+ done = true;
+ break;
+ case 'b': /* Bool. */
+ boolp = true;
+ done = true;
+ break;
+ case 'c': /* Char. */
+ charp = true;
+ done = true;
+ break;
+ case 'r': /* Long double. */
+ case 'd': /* Double. */
+ case 'f': /* Float. */
+ realp = true;
+ done = true;
+ break;
+ default:
+ /* Assume it's a user defined integral type. */
+ integralp = true;
+ done = true;
+ break;
+ }
+ }
+
+ if (integralp)
+ {
+ if (**pp == 'm')
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ else if (charp)
+ {
+ unsigned int val;
+
+ if (**pp == 'm')
+ ++*pp;
+ val = stab_demangle_count (pp);
+ if (val == 0)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+ else if (boolp)
+ {
+ unsigned int val;
+
+ val = stab_demangle_count (pp);
+ if (val != 0 && val != 1)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+ else if (realp)
+ {
+ if (**pp == 'm')
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ if (**pp == '.')
+ {
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ if (**pp == 'e')
+ {
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ }
+ else if (pointerp)
+ {
+ unsigned int len;
+
+ if (! stab_demangle_get_count (pp, &len))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp += len;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Demangle a class name. */
+
+static boolean
+stab_demangle_class (minfo, pp, pstart)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ const char **pstart;
+{
+ const char *orig;
+ unsigned int n;
+
+ orig = *pp;
+
+ n = stab_demangle_count (pp);
+ if (strlen (*pp) < n)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (pstart != NULL)
+ *pstart = *pp;
+
+ *pp += n;
+
+ return true;
+}
+
+/* Demangle function arguments. If the pargs argument is not NULL, it
+ is set to a NULL terminated array holding the arguments. */
+
+static boolean
+stab_demangle_args (minfo, pp, pargs, pvarargs)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type **pargs;
+ boolean *pvarargs;
+{
+ const char *orig;
+ unsigned int alloc, count;
+
+ orig = *pp;
+
+ alloc = 10;
+ if (pargs != NULL)
+ {
+ *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
+ *pvarargs = false;
+ }
+ count = 0;
+
+ while (**pp != '_' && **pp != '\0' && **pp != 'e')
+ {
+ if (**pp == 'N' || **pp == 'T')
+ {
+ char temptype;
+ unsigned int r, t;
+
+ temptype = **pp;
+ ++*pp;
+
+ if (temptype == 'T')
+ r = 1;
+ else
+ {
+ if (! stab_demangle_get_count (pp, &r))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+
+ if (! stab_demangle_get_count (pp, &t))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (t >= minfo->typestring_count)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ while (r-- > 0)
+ {
+ const char *tem;
+
+ tem = minfo->typestrings[t].typestring;
+ if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc))
+ return false;
+ }
+ }
+ else
+ {
+ if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc))
+ return false;
+ }
+ }
+
+ if (pargs != NULL)
+ (*pargs)[count] = DEBUG_TYPE_NULL;
+
+ if (**pp == 'e')
+ {
+ if (pargs != NULL)
+ *pvarargs = true;
+ ++*pp;
+ }
+
+ return true;
+}
+
+/* Demangle a single argument. */
+
+static boolean
+stab_demangle_arg (minfo, pp, pargs, pcount, palloc)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type **pargs;
+ unsigned int *pcount;
+ unsigned int *palloc;
+{
+ const char *start;
+ debug_type type;
+
+ start = *pp;
+ if (! stab_demangle_type (minfo, pp,
+ pargs == NULL ? (debug_type *) NULL : &type)
+ || ! stab_demangle_remember_type (minfo, start, *pp - start))
+ return false;
+
+ if (pargs != NULL)
+ {
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (*pcount + 1 >= *palloc)
+ {
+ *palloc += 10;
+ *pargs = ((debug_type *)
+ xrealloc (*pargs, *palloc * sizeof **pargs));
+ }
+ (*pargs)[*pcount] = type;
+ ++*pcount;
+ }
+
+ return true;
+}
+
+/* Demangle a type. If the ptype argument is not NULL, *ptype is set
+ to the newly allocated type. */
+
+static boolean
+stab_demangle_type (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+
+ orig = *pp;
+
+ switch (**pp)
+ {
+ case 'P':
+ case 'p':
+ /* A pointer type. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_pointer_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'R':
+ /* A reference type. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_reference_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'A':
+ /* An array. */
+ {
+ unsigned long high;
+
+ ++*pp;
+ high = 0;
+ while (**pp != '\0' && **pp != '_')
+ {
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ high *= 10;
+ high += **pp - '0';
+ ++*pp;
+ }
+ if (**pp != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ {
+ debug_type int_type;
+
+ int_type = debug_find_named_type (minfo->dhandle, "int");
+ if (int_type == NULL)
+ int_type = debug_make_int_type (minfo->dhandle, 4, false);
+ *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type,
+ 0, high, false);
+ }
+ }
+ break;
+
+ case 'T':
+ /* A back reference to a remembered type. */
+ {
+ unsigned int i;
+ const char *p;
+
+ ++*pp;
+ if (! stab_demangle_get_count (pp, &i))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ if (i >= minfo->typestring_count)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ p = minfo->typestrings[i].typestring;
+ if (! stab_demangle_type (minfo, &p, ptype))
+ return false;
+ }
+ break;
+
+ case 'F':
+ /* A function. */
+ {
+ debug_type *args;
+ boolean varargs;
+
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp,
+ (ptype == NULL
+ ? (debug_type **) NULL
+ : &args),
+ (ptype == NULL
+ ? (boolean *) NULL
+ : &varargs)))
+ return false;
+ if (**pp != '_')
+ {
+ /* cplus_demangle will accept a function without a return
+ type, but I don't know when that will happen, or what
+ to do if it does. */
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
+ varargs);
+
+ }
+ break;
+
+ case 'M':
+ case 'O':
+ {
+ boolean memberp, constp, volatilep;
+ debug_type *args;
+ boolean varargs;
+ unsigned int n;
+ const char *name;
+
+ memberp = **pp == 'M';
+ constp = false;
+ volatilep = false;
+ args = NULL;
+ varargs = false;
+
+ ++*pp;
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ n = stab_demangle_count (pp);
+ if (strlen (*pp) < n)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ name = *pp;
+ *pp += n;
+
+ if (memberp)
+ {
+ if (**pp == 'C')
+ {
+ constp = true;
+ ++*pp;
+ }
+ else if (**pp == 'V')
+ {
+ volatilep = true;
+ ++*pp;
+ }
+ if (**pp != 'F')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp,
+ (ptype == NULL
+ ? (debug_type **) NULL
+ : &args),
+ (ptype == NULL
+ ? (boolean *) NULL
+ : &varargs)))
+ return false;
+ }
+
+ if (**pp != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+
+ if (ptype != NULL)
+ {
+ debug_type class_type;
+
+ class_type = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ name, (int) n,
+ DEBUG_KIND_CLASS);
+ if (class_type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (! memberp)
+ *ptype = debug_make_offset_type (minfo->dhandle, class_type,
+ *ptype);
+ else
+ {
+ /* FIXME: We have no way to record constp or
+ volatilep. */
+ *ptype = debug_make_method_type (minfo->dhandle, *ptype,
+ class_type, args, varargs);
+ }
+ }
+ }
+ break;
+
+ case 'G':
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ break;
+
+ case 'C':
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_const_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'Q':
+ {
+ const char *hold;
+
+ hold = *pp;
+ if (! stab_demangle_qualified (minfo, pp, ptype))
+ return false;
+ }
+ break;
+
+ default:
+ if (! stab_demangle_fund_type (minfo, pp, ptype))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/* Demangle a fundamental type. If the ptype argument is not NULL,
+ *ptype is set to the newly allocated type. */
+
+static boolean
+stab_demangle_fund_type (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+ boolean constp, volatilep, unsignedp, signedp;
+ boolean done;
+
+ orig = *pp;
+
+ constp = false;
+ volatilep = false;
+ unsignedp = false;
+ signedp = false;
+
+ done = false;
+ while (! done)
+ {
+ switch (**pp)
+ {
+ case 'C':
+ constp = true;
+ ++*pp;
+ break;
+
+ case 'U':
+ unsignedp = true;
+ ++*pp;
+ break;
+
+ case 'S':
+ signedp = true;
+ ++*pp;
+ break;
+
+ case 'V':
+ volatilep = true;
+ ++*pp;
+ break;
+
+ default:
+ done = true;
+ break;
+ }
+ }
+
+ switch (**pp)
+ {
+ case '\0':
+ case '_':
+ /* cplus_demangle permits this, but I don't know what it means. */
+ stab_bad_demangle (orig);
+ break;
+
+ case 'v': /* void */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "void");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_void_type (minfo->dhandle);
+ }
+ ++*pp;
+ break;
+
+ case 'x': /* long long */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "long long unsigned int"
+ : "long long int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'l': /* long */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "long unsigned int"
+ : "long int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'i': /* int */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "unsigned int"
+ : "int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 's': /* short */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "short unsigned int"
+ : "short int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'b': /* bool */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "bool");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_bool_type (minfo->dhandle, 4);
+ }
+ ++*pp;
+ break;
+
+ case 'c': /* char */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "unsigned char"
+ : (signedp
+ ? "signed char"
+ : "char")));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'w': /* wchar_t */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 2, true);
+ }
+ ++*pp;
+ break;
+
+ case 'r': /* long double */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "long double");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 8);
+ }
+ ++*pp;
+ break;
+
+ case 'd': /* double */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "double");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 8);
+ }
+ ++*pp;
+ break;
+
+ case 'f': /* float */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "float");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 4);
+ }
+ ++*pp;
+ break;
+
+ case 'G':
+ ++*pp;
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ /* Fall through. */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ const char *hold;
+
+ if (! stab_demangle_class (minfo, pp, &hold))
+ return false;
+ if (ptype != NULL)
+ {
+ char *name;
+
+ name = savestring (hold, *pp - hold);
+ *ptype = debug_find_named_type (minfo->dhandle, name);
+ if (*ptype == DEBUG_TYPE_NULL)
+ {
+ /* FIXME: It is probably incorrect to assume that
+ undefined types are tagged types. */
+ *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ hold, *pp - hold,
+ DEBUG_KIND_ILLEGAL);
+ }
+ free (name);
+ }
+ }
+ break;
+
+ case 't':
+ if (! stab_demangle_template (minfo, pp))
+ return false;
+ if (ptype != NULL)
+ {
+ debug_type t;
+
+ /* FIXME: I really don't know how a template should be
+ represented in the current type system. Perhaps the
+ template should be demangled into a string, and the type
+ should be represented as a named type. However, I don't
+ know what the base type of the named type should be. */
+ t = debug_make_void_type (minfo->dhandle);
+ t = debug_make_pointer_type (minfo->dhandle, t);
+ t = debug_name_type (minfo->dhandle, "TEMPLATE", t);
+ *ptype = t;
+ }
+ break;
+
+ default:
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (ptype != NULL)
+ {
+ if (constp)
+ *ptype = debug_make_const_type (minfo->dhandle, *ptype);
+ if (volatilep)
+ *ptype = debug_make_volatile_type (minfo->dhandle, *ptype);
+ }
+
+ return true;
+}
+
+/* Remember a type string in a demangled string. */
+
+static boolean
+stab_demangle_remember_type (minfo, p, len)
+ struct stab_demangle_info *minfo;
+ const char *p;
+ int len;
+{
+ if (minfo->typestring_count >= minfo->typestring_alloc)
+ {
+ minfo->typestring_alloc += 10;
+ minfo->typestrings = ((struct stab_demangle_typestring *)
+ xrealloc (minfo->typestrings,
+ (minfo->typestring_alloc
+ * sizeof *minfo->typestrings)));
+ }
+
+ minfo->typestrings[minfo->typestring_count].typestring = p;
+ minfo->typestrings[minfo->typestring_count].len = (unsigned int) len;
+ ++minfo->typestring_count;
+
+ return true;
+}
diff --git a/readline/bind.c b/readline/bind.c
index 57383239098..f122bdf4860 100644
--- a/readline/bind.c
+++ b/readline/bind.c
@@ -108,7 +108,7 @@ Keymap rl_binding_keymap;
/* Forward declarations */
void rl_set_keymap_from_edit_mode ();
-static int _rl_read_init_file ();
+static int _rl_read_init_file (const char *filename, int include_level);
static int glean_key_from_name ();
static int substring_member_of_array ();
@@ -570,10 +570,7 @@ rl_named_function (string)
type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap),
or ISMACR (macro). */
Function *
-rl_function_of_keyseq (keyseq, map, type)
- char *keyseq;
- Keymap map;
- int *type;
+rl_function_of_keyseq (const char *keyseq, Keymap map, int *type)
{
register int i;
@@ -629,7 +626,7 @@ rl_function_of_keyseq (keyseq, map, type)
static char *last_readline_init_file = (char *)NULL;
/* The file we're currently reading key bindings from. */
-static char *current_readline_init_file;
+static const char *current_readline_init_file;
static int current_readline_init_include_level;
static int current_readline_init_lineno;
@@ -685,8 +682,8 @@ _rl_read_file (filename, sizep)
/* Re-read the current keybindings file. */
int
-rl_re_read_init_file (count, ignore)
- int count, ignore;
+rl_re_read_init_file (int count __attribute__((unused)),
+ int ignore __attribute__((unused)))
{
int r;
r = rl_read_init_file ((char *)NULL);
@@ -702,8 +699,7 @@ rl_re_read_init_file (count, ignore)
If the file existed and could be opened and read, 0 is returned,
otherwise errno is returned. */
int
-rl_read_init_file (filename)
- char *filename;
+rl_read_init_file (const char *filename)
{
/* Default the filename. */
if (filename == 0)
@@ -722,9 +718,7 @@ rl_read_init_file (filename)
}
static int
-_rl_read_init_file (filename, include_level)
- char *filename;
- int include_level;
+_rl_read_init_file (const char *filename, int include_level)
{
register int i;
char *buffer, *openname, *line, *end;
@@ -739,7 +733,7 @@ _rl_read_init_file (filename, include_level)
if (buffer == 0)
return (errno);
-
+
if (include_level == 0 && filename != last_readline_init_file)
{
FREE (last_readline_init_file);
@@ -797,7 +791,7 @@ _rl_init_file_error (msg)
/* Conditionals. */
/* Calling programs set this to have their argv[0]. */
-char *rl_readline_name = "other";
+const char *rl_readline_name = "other";
/* Stack of previous values of parsing_conditionalized_out. */
static unsigned char *if_stack = (unsigned char *)NULL;
@@ -881,7 +875,7 @@ parser_if (args)
/* Invert the current parser state if there is anything on the stack. */
static int
parser_else (args)
- char *args;
+char *args __attribute__((unused));
{
register int i;
@@ -906,7 +900,7 @@ parser_else (args)
_rl_parsing_conditionalized_out from the stack. */
static int
parser_endif (args)
- char *args;
+char *args __attribute__((unused));
{
if (if_stack_depth)
_rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
@@ -919,7 +913,8 @@ static int
parser_include (args)
char *args;
{
- char *old_init_file, *e;
+ const char *old_init_file;
+ char *e;
int old_line_number, old_include_level, r;
if (_rl_parsing_conditionalized_out)
@@ -940,10 +935,10 @@ parser_include (args)
return r;
}
-
+
/* Associate textual names with actual functions. */
static struct {
- char *name;
+ const char *name;
Function *function;
} parser_directives [] = {
{ "if", parser_if },
@@ -1233,7 +1228,7 @@ rl_parse_and_bind (string)
false. */
static struct {
- char *name;
+ const char *name;
int *value;
} boolean_varlist [] = {
#if defined (PAREN_MATCHING)
@@ -1375,7 +1370,7 @@ rl_variable_bind (name, value)
_rl_isearch_terminators[end] = '\0';
free (v);
}
-
+
/* For the time being, unknown variable names are simply ignored. */
return 0;
}
@@ -1384,7 +1379,7 @@ rl_variable_bind (name, value)
For example, `Space' returns ' '. */
typedef struct {
- char *name;
+ const char *name;
int value;
} assoc_list;
@@ -1418,7 +1413,7 @@ glean_key_from_name (name)
/* Auxiliary functions to manage keymaps. */
static struct {
- char *name;
+ const char *name;
Keymap map;
} keymap_names[] = {
{ "emacs", emacs_standard_keymap },
@@ -1446,7 +1441,7 @@ rl_get_keymap_by_name (name)
return ((Keymap) NULL);
}
-char *
+const char *
rl_get_keymap_name (map)
Keymap map;
{
@@ -1456,7 +1451,7 @@ rl_get_keymap_name (map)
return (keymap_names[i].name);
return ((char *)NULL);
}
-
+
void
rl_set_keymap (map)
Keymap map;
@@ -1482,7 +1477,7 @@ rl_set_keymap_from_edit_mode ()
#endif /* VI_MODE */
}
-char *
+const char *
rl_get_keymap_name_from_edit_mode ()
{
if (rl_editing_mode == emacs_mode)
@@ -1675,7 +1670,7 @@ rl_invoking_keyseqs_in_map (function, map)
keyname[0] = (char) key;
keyname[1] = '\0';
}
-
+
strcat (keyname, seqs[i]);
free (seqs[i]);
@@ -1780,8 +1775,8 @@ rl_function_dumper (print_readably)
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
-rl_dump_functions (count, key)
- int count, key;
+rl_dump_functions (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@@ -1865,8 +1860,8 @@ rl_macro_dumper (print_readably)
}
int
-rl_dump_macros (count, key)
- int count, key;
+rl_dump_macros (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@@ -1880,7 +1875,7 @@ rl_variable_dumper (print_readably)
int print_readably;
{
int i;
- char *kname;
+ const char *kname;
for (i = 0; boolean_varlist[i].name; i++)
{
@@ -1955,8 +1950,8 @@ rl_variable_dumper (print_readably)
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
-rl_dump_variables (count, key)
- int count, key;
+rl_dump_variables (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
diff --git a/readline/callback.c b/readline/callback.c
index 6915be483a4..200f3cc37f9 100644
--- a/readline/callback.c
+++ b/readline/callback.c
@@ -29,6 +29,7 @@
#if defined (READLINE_CALLBACKS)
+#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
diff --git a/readline/complete.c b/readline/complete.c
index ade317ff578..8810ca06d5f 100644
--- a/readline/complete.c
+++ b/readline/complete.c
@@ -95,7 +95,7 @@ extern int rl_display_fixed;
VFunction *rl_completion_display_matches_hook = (VFunction *)NULL;
/* Forward declarations for functions defined and used in this file. */
-char *filename_completion_function ();
+char *filename_completion_function (const char *text, int state);
char **completion_matches ();
#if defined (VISIBLE_STATS)
@@ -186,15 +186,15 @@ int rl_completion_query_items = 100;
/* The basic list of characters that signal a break between words for the
completer routine. The contents of this variable is what breaks words
in the shell, i.e. " \t\n\"\\'`@$><=" */
-char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
+const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
/* List of basic quoting characters. */
-char *rl_basic_quote_characters = "\"'";
+const char *rl_basic_quote_characters = "\"'";
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
-char *rl_completer_word_break_characters = (char *)NULL;
+const char *rl_completer_word_break_characters = (char *)NULL;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@@ -241,7 +241,7 @@ Function *rl_ignore_some_completions_function = (Function *)NULL;
and a pointer to the quoting character to be used, which the function can
reset if desired. */
CPFunction *rl_filename_quoting_function = rl_quote_filename;
-
+
/* Function to call to remove quoting characters from a filename. Called
before completion is attempted, so the embedded quotes do not interfere
with matching names in the file system. Readline doesn't do anything
@@ -291,14 +291,14 @@ rl_complete (ignore, invoking_key)
/* List the possible completions. See description of rl_complete (). */
int
rl_possible_completions (ignore, invoking_key)
- int ignore, invoking_key;
+ int ignore __attribute__((unused)), invoking_key __attribute__((unused));
{
return (rl_complete_internal ('?'));
}
int
rl_insert_completions (ignore, invoking_key)
- int ignore, invoking_key;
+ int ignore __attribute__((unused)), invoking_key __attribute__((unused));
{
return (rl_complete_internal ('*'));
}
@@ -513,7 +513,7 @@ print_filename (to_print, full_pathname)
static char *
rl_quote_filename (s, rtype, qcp)
char *s;
- int rtype;
+ int rtype __attribute__((unused));
char *qcp;
{
char *r;
@@ -1010,7 +1010,7 @@ display_matches (matches)
(*rl_completion_display_matches_hook) (matches, len, max);
return;
}
-
+
/* If there are many items, then ask the user if she really wants to
see them all. */
if (len >= rl_completion_query_items)
@@ -1356,9 +1356,7 @@ rl_complete_internal (what_to_do)
when there are no more matches.
*/
char **
-completion_matches (text, entry_function)
- char *text;
- CPFunction *entry_function;
+completion_matches (const char *text, CPFunction *entry_function)
{
/* Number of slots in match_list. */
int match_list_size;
@@ -1403,9 +1401,7 @@ completion_matches (text, entry_function)
TEXT contains a partial username preceded by a random
character (usually `~'). */
char *
-username_completion_function (text, state)
- char *text;
- int state;
+username_completion_function (const char *text, int state)
{
#if defined (__GO32__) || defined (__WIN__) || defined (__OPENNT)
return (char *)NULL;
@@ -1460,9 +1456,7 @@ username_completion_function (text, state)
because of all the pathnames that must be followed when looking up the
completion for a command. */
char *
-filename_completion_function (text, state)
- char *text;
- int state;
+filename_completion_function (const char *text, int state)
{
static DIR *directory = (DIR *)NULL;
static char *filename = (char *)NULL;
@@ -1639,8 +1633,7 @@ filename_completion_function (text, state)
hit the end of the match list, we restore the original unmatched text,
ring the bell, and reset the counter to zero. */
int
-rl_menu_complete (count, ignore)
- int count, ignore;
+rl_menu_complete (int count, int ignore __attribute__((unused)))
{
Function *our_func;
int matching_filenames, found_quote;
diff --git a/readline/display.c b/readline/display.c
index 25aba64ca67..e21af1f472d 100644
--- a/readline/display.c
+++ b/readline/display.c
@@ -79,9 +79,9 @@ extern int _rl_output_character_function ();
#endif
extern int _rl_backspace ();
-extern char *term_clreol, *term_clrpag;
-extern char *term_im, *term_ic, *term_ei, *term_DC;
-extern char *term_up, *term_dc, *term_cr, *term_IC;
+extern const char *term_clreol, *term_clrpag;
+extern const char *term_im, *term_ic, *term_ei, *term_DC;
+extern const char *term_up, *term_dc, *term_cr, *term_IC;
extern int screenheight, screenwidth, screenchars;
extern int terminal_can_insert, _rl_term_autowrap;
@@ -141,7 +141,7 @@ int _rl_suppress_redisplay = 0;
/* The stuff that gets printed out before the actual text of the line.
This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
+const char *rl_display_prompt = (char *)NULL;
/* Pseudo-global variables declared here. */
/* The visible cursor position. If you print some text, adjust this. */
@@ -218,7 +218,7 @@ expand_prompt (pmt, lp, lip)
l = strlen (pmt);
r = ret = xmalloc (l + 1);
-
+
for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
{
/* This code strips the invisible character string markers
@@ -315,7 +315,7 @@ rl_redisplay ()
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp;
- char *prompt_this_line;
+ const char *prompt_this_line;
if (!readline_echoing_p)
return;
@@ -831,7 +831,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (old[0] && new[0])
old[0] = new[0];
}
-
+
/* Find first difference. */
for (ofd = old, nfd = new;
(ofd - old < omax) && *ofd && (*ofd == *nfd);
@@ -1229,8 +1229,7 @@ rl_message (va_alist)
}
#else /* !USE_VARARGS */
int
-rl_message (format, arg1, arg2)
- char *format;
+rl_message (char *format, void *arg1, void *arg2)
{
sprintf (msg_buf, format, arg1, arg2);
rl_display_prompt = msg_buf;
@@ -1512,7 +1511,8 @@ cr ()
void
_rl_redisplay_after_sigwinch ()
{
- char *t, *oldp, *oldl, *oldlprefix;
+ char *t, *oldl, *oldlprefix;
+ const char *oldp;
/* Clear the current line and put the cursor at column 0. Make sure
the right thing happens if we have wrapped to a new screen line. */
diff --git a/readline/funmap.c b/readline/funmap.c
index f6b86286fe0..472119bd80a 100644
--- a/readline/funmap.c
+++ b/readline/funmap.c
@@ -180,16 +180,14 @@ static FUNMAP default_funmap[] = {
};
int
-rl_add_funmap_entry (name, function)
- char *name;
- Function *function;
+rl_add_funmap_entry (const char *name, Function *function)
{
if (funmap_entry + 2 >= funmap_size)
{
funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
}
-
+
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function;
@@ -236,7 +234,7 @@ rl_funmap_names ()
result = (char **)xrealloc (result, result_size * sizeof (char *));
}
- result[result_index] = funmap[result_index]->name;
+ result[result_index] = (char*) funmap[result_index]->name;
result[result_index + 1] = (char *)NULL;
}
@@ -245,10 +243,10 @@ rl_funmap_names ()
}
/* Things that mean `Control'. */
-char *possible_control_prefixes[] = {
+const char *possible_control_prefixes[] = {
"Control-", "C-", "CTRL-", (char *)NULL
};
-char *possible_meta_prefixes[] = {
+const char *possible_meta_prefixes[] = {
"Meta", "M-", (char *)NULL
};
diff --git a/readline/histexpand.c b/readline/histexpand.c
index 30c6131801d..f78838ef2ba 100644
--- a/readline/histexpand.c
+++ b/readline/histexpand.c
@@ -87,7 +87,7 @@ char history_comment_char = '\0';
/* The list of characters which inhibit the expansion of text if found
immediately following history_expansion_char. */
-char *history_no_expand_chars = " \t\n\r=";
+const char *history_no_expand_chars = " \t\n\r=";
/* If set to a non-zero value, single quotes inhibit history expansion.
The default is 0. */
@@ -249,7 +249,7 @@ get_history_event (string, caller_index, delimiting_quote)
{
entry = current_history ();
history_offset = history_length;
-
+
/* If this was a substring search, then remember the
string that we matched for word substitution. */
if (substring_okay)
@@ -342,7 +342,8 @@ hist_error(s, start, current, errtype)
char *s;
int start, current, errtype;
{
- char *temp, *emsg;
+ char *temp;
+ const char *emsg;
int ll, elen;
ll = current - start;
@@ -514,7 +515,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
quoted_search_delimiter = string[i - 1];
event = get_history_event (string, &i, quoted_search_delimiter);
}
-
+
if (event == 0)
{
*ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
@@ -825,7 +826,7 @@ history_expand (hstring, output)
*output = savestring (hstring);
return (0);
}
-
+
/* Prepare the buffer for printing error messages. */
result = xmalloc (result_len = 256);
result[0] = '\0';
@@ -904,7 +905,7 @@ history_expand (hstring, output)
i++;
}
}
-
+
if (string[i] != history_expansion_char)
{
free (result);
@@ -1239,7 +1240,7 @@ history_tokenize_internal (string, wind, indp)
return (result);
start = i;
-
+
if (member (string[i], "()\n"))
{
i++;
diff --git a/readline/histfile.c b/readline/histfile.c
index 3325b7fc1f7..1da45b00b58 100644
--- a/readline/histfile.c
+++ b/readline/histfile.c
@@ -84,14 +84,15 @@ static char *
history_filename (filename)
char *filename;
{
- char *return_val, *home;
+ char *return_val;
+ const char *home;
int home_len;
return_val = filename ? savestring (filename) : (char *)NULL;
if (return_val)
return (return_val);
-
+
home = get_env_value ("HOME");
if (home == 0)
@@ -130,11 +131,10 @@ read_history_range (filename, from, to)
char *filename;
int from, to;
{
- register int line_start, line_end;
char *input, *buffer;
int file, current_line;
struct stat finfo;
- size_t file_size;
+ size_t line_start, line_end, file_size;
buffer = (char *)NULL;
input = history_filename (filename);
diff --git a/readline/history.c b/readline/history.c
index d56ffacc6a0..804ffddcd89 100644
--- a/readline/history.c
+++ b/readline/history.c
@@ -161,7 +161,7 @@ history_set_pos (pos)
history_offset = pos;
return (1);
}
-
+
/* Return the current history array. The caller has to be carefull, since this
is the actual array of data, and could be bashed or made corrupt easily.
The array is terminated with a NULL pointer. */
diff --git a/readline/history.h b/readline/history.h
index 8ecce726779..88bf471bb62 100644
--- a/readline/history.h
+++ b/readline/history.h
@@ -116,7 +116,7 @@ extern HIST_ENTRY **history_list __P((void));
/* Returns the number which says what history element we are now
looking at. */
extern int where_history __P((void));
-
+
/* Return the history entry at the current position, as determined by
history_offset. If there is no entry there, return a NULL pointer. */
HIST_ENTRY *current_history __P((void));
@@ -232,8 +232,8 @@ extern int max_input_history;
extern char history_expansion_char;
extern char history_subst_char;
extern char history_comment_char;
-extern char *history_no_expand_chars;
-extern char *history_search_delimiter_chars;
+extern const char *history_no_expand_chars;
+extern const char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
/* If set, this function is called to decide whether or not a particular
diff --git a/readline/histsearch.c b/readline/histsearch.c
index 7e98e950acb..eb17e9332e8 100644
--- a/readline/histsearch.c
+++ b/readline/histsearch.c
@@ -52,7 +52,7 @@ extern int history_offset;
/* The list of alternate characters that can delimit a history search
string. */
-char *history_search_delimiter_chars = (char *)NULL;
+const char *history_search_delimiter_chars = (char *)NULL;
/* Search the history for STRING, starting at history_offset.
If DIRECTION < 0, then the search is through previous entries, else
diff --git a/readline/input.c b/readline/input.c
index e23af552494..ea1342969b0 100644
--- a/readline/input.c
+++ b/readline/input.c
@@ -311,7 +311,7 @@ _rl_input_available ()
void
_rl_insert_typein (c)
int c;
-{
+{
int key, t, i;
char *string;
diff --git a/readline/isearch.c b/readline/isearch.c
index ae8dce520f0..a4a294b6b20 100644
--- a/readline/isearch.c
+++ b/readline/isearch.c
@@ -97,7 +97,8 @@ rl_forward_search_history (sign, key)
static void
rl_display_search (search_string, reverse_p, where)
char *search_string;
- int reverse_p, where;
+ int reverse_p;
+ int where __attribute__((unused));
{
char *message;
int msglen, searchlen;
@@ -144,8 +145,7 @@ rl_display_search (search_string, reverse_p, where)
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
-rl_search_history (direction, invoking_key)
- int direction, invoking_key;
+rl_search_history (int direction, int invoking_key __attribute__((unused)))
{
/* The string that the user types in to search for. */
char *search_string;
diff --git a/readline/kill.c b/readline/kill.c
index 0b4714fafa8..78387e138c2 100644
--- a/readline/kill.c
+++ b/readline/kill.c
@@ -82,8 +82,7 @@ static int rl_kill_ring_length;
/* How to say that you only want to save a certain amount
of kill material. */
int
-rl_set_retained_kills (num)
- int num;
+rl_set_retained_kills (int num __attribute__((unused)))
{
return 0;
}
@@ -285,8 +284,8 @@ rl_backward_kill_line (direction, ignore)
/* Kill the whole line, no matter where point is. */
int
-rl_kill_full_line (count, ignore)
- int count, ignore;
+rl_kill_full_line (int count __attribute__((unused)),
+ int ignore __attribute__((unused)))
{
rl_begin_undo_group ();
rl_point = 0;
@@ -302,8 +301,7 @@ rl_kill_full_line (count, ignore)
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
-rl_unix_word_rubout (count, key)
- int count, key;
+rl_unix_word_rubout (int count, int key __attribute__((unused)))
{
int orig_point;
@@ -336,8 +334,8 @@ rl_unix_word_rubout (count, key)
into the line at all, and if you aren't, then you know what you are
doing. */
int
-rl_unix_line_discard (count, key)
- int count, key;
+rl_unix_line_discard (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_point == 0)
ding ();
@@ -374,16 +372,16 @@ region_kill_internal (delete)
/* Copy the text in the region to the kill ring. */
int
-rl_copy_region_to_kill (count, ignore)
- int count, ignore;
+rl_copy_region_to_kill (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
-rl_kill_region (count, ignore)
- int count, ignore;
+rl_kill_region (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int r;
@@ -442,11 +440,11 @@ rl_copy_backward_word (count, key)
return (_rl_copy_word_as_kill (count, -1));
}
-
+
/* Yank back the last killed text. This ignores arguments. */
int
-rl_yank (count, ignore)
- int count, ignore;
+rl_yank (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_kill_ring == 0)
{
@@ -464,8 +462,8 @@ rl_yank (count, ignore)
delete that text from the line, rotate the index down, and
yank back some other text. */
int
-rl_yank_pop (count, key)
- int count, key;
+rl_yank_pop (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int l, n;
@@ -592,7 +590,7 @@ rl_yank_last_arg (count, key)
if (history_skip < 0)
history_skip = 0;
}
-
+
if (explicit_arg_p)
retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
else
diff --git a/readline/macro.c b/readline/macro.c
index f3c442b41c3..b4d7835c631 100644
--- a/readline/macro.c
+++ b/readline/macro.c
@@ -90,7 +90,7 @@ static int current_macro_index;
It is a linked list of string/index for each saved macro. */
struct saved_macro {
struct saved_macro *next;
- char *string;
+ const char *string;
int sindex;
};
@@ -100,11 +100,10 @@ static struct saved_macro *macro_list = (struct saved_macro *)NULL;
/* Set up to read subsequent input from STRING.
STRING is free ()'ed when we are done with it. */
void
-_rl_with_macro_input (string)
- char *string;
+_rl_with_macro_input (const char *string)
{
_rl_push_executing_macro ();
- _rl_executing_macro = string;
+ _rl_executing_macro = (char*) string;
executing_macro_index = 0;
}
@@ -155,7 +154,7 @@ _rl_pop_executing_macro ()
if (macro_list)
{
macro = macro_list;
- _rl_executing_macro = macro_list->string;
+ _rl_executing_macro = (char*) macro_list->string;
executing_macro_index = macro_list->sindex;
macro_list = macro_list->next;
free (macro);
@@ -206,8 +205,8 @@ _rl_kill_kbd_macro ()
definition to the end of the existing macro, and start by
re-executing the existing macro. */
int
-rl_start_kbd_macro (ignore1, ignore2)
- int ignore1, ignore2;
+rl_start_kbd_macro (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (_rl_defining_kbd_macro)
{
@@ -231,8 +230,7 @@ rl_start_kbd_macro (ignore1, ignore2)
A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */
int
-rl_end_kbd_macro (count, ignore)
- int count, ignore;
+rl_end_kbd_macro (int count, int ignore __attribute__((unused)))
{
if (_rl_defining_kbd_macro == 0)
{
@@ -251,8 +249,7 @@ rl_end_kbd_macro (count, ignore)
/* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */
int
-rl_call_last_kbd_macro (count, ignore)
- int count, ignore;
+rl_call_last_kbd_macro (int count, int key __attribute__((unused)))
{
if (current_macro == 0)
_rl_abort_internal ();
diff --git a/readline/readline.c b/readline/readline.c
index 622811fc11e..1da73250773 100644
--- a/readline/readline.c
+++ b/readline/readline.c
@@ -129,8 +129,8 @@ extern int _rl_suppress_redisplay;
extern char *rl_display_prompt;
/* Variables imported from complete.c. */
-extern char *rl_completer_word_break_characters;
-extern char *rl_basic_word_break_characters;
+extern const char *rl_completer_word_break_characters;
+extern const char *rl_basic_word_break_characters;
extern int rl_completion_query_items;
extern int rl_complete_with_tilde_expansion;
@@ -181,7 +181,7 @@ extern char *xmalloc (), *xrealloc ();
/* */
/* **************************************************************** */
-char *rl_library_version = RL_LIBRARY_VERSION;
+const char *rl_library_version = RL_LIBRARY_VERSION;
/* A pointer to the keymap that is currently in use.
By default, it is the standard emacs keymap. */
@@ -280,7 +280,7 @@ int _rl_mark_modified_lines = 0;
/* The style of `bell' notification preferred. This can be set to NO_BELL,
AUDIBLE_BELL, or VISIBLE_BELL. */
int _rl_bell_preference = AUDIBLE_BELL;
-
+
/* String inserted into the line by rl_insert_comment (). */
char *_rl_comment_begin;
@@ -755,7 +755,7 @@ readline_initialize_everything ()
/* Decide whether we should automatically go into eight-bit mode. */
_rl_init_eightbit ();
-
+
/* Read in the init file. */
rl_read_init_file ((char *)NULL);
@@ -914,7 +914,7 @@ rl_digit_loop ()
/* Add the current digit to the argument in progress. */
int
rl_digit_argument (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
rl_pending_input = key;
return (rl_digit_loop ());
@@ -944,7 +944,7 @@ _rl_init_argument ()
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_numeric_arg *= 4;
return (rl_digit_loop ());
@@ -960,8 +960,7 @@ rl_universal_argument (count, key)
way that you should do insertion. rl_insert () calls this
function. */
int
-rl_insert_text (string)
- char *string;
+rl_insert_text (const char *string)
{
register int i, l = strlen (string);
@@ -1147,7 +1146,7 @@ rl_backward (count, key)
/* Move to the beginning of the line. */
int
rl_beg_of_line (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_point = 0;
return 0;
@@ -1156,7 +1155,7 @@ rl_beg_of_line (count, key)
/* Move to the end of the line. */
int
rl_end_of_line (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_point = rl_end;
return 0;
@@ -1253,7 +1252,7 @@ rl_backward_word (count, key)
/* Clear the current line. Numeric argument to C-l does this. */
int
rl_refresh_line (ignore1, ignore2)
- int ignore1, ignore2;
+ int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
{
int curr_line, nleft;
@@ -1313,7 +1312,7 @@ rl_clear_screen (count, key)
int
rl_arrow_keys (count, c)
- int count, c;
+ int count, c __attribute__((unused));
{
int ch;
@@ -1417,7 +1416,7 @@ rl_insert (count, c)
/* Insert the next typed character verbatim. */
int
rl_quoted_insert (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
int c;
@@ -1428,7 +1427,7 @@ rl_quoted_insert (count, key)
/* Insert a tab character. */
int
rl_tab_insert (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_insert (count, '\t'));
}
@@ -1438,7 +1437,7 @@ rl_tab_insert (count, key)
meaning in the future. */
int
rl_newline (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_done = 1;
@@ -1466,7 +1465,7 @@ rl_newline (count, key)
is special cased. */
int
rl_do_lowercase_version (ignore1, ignore2)
- int ignore1, ignore2;
+ int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
{
return 0;
}
@@ -1548,12 +1547,12 @@ rl_rubout_or_delete (count, key)
return (rl_rubout (count, key));
else
return (rl_delete (count, key));
-}
+}
/* Delete all spaces and tabs around point. */
int
rl_delete_horizontal_space (count, ignore)
- int count, ignore;
+ int count __attribute__((unused)), ignore __attribute__((unused));
{
int start = rl_point;
@@ -1594,7 +1593,7 @@ rl_delete_or_show_completions (count, key)
A K*rn shell style function. */
int
rl_insert_comment (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_beg_of_line (1, key);
rl_insert_text (_rl_comment_begin ? _rl_comment_begin
@@ -1620,7 +1619,7 @@ static int rl_change_case ();
/* Uppercase the word at point. */
int
rl_upcase_word (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_change_case (count, UpCase));
}
@@ -1628,7 +1627,7 @@ rl_upcase_word (count, key)
/* Lowercase the word at point. */
int
rl_downcase_word (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_change_case (count, DownCase));
}
@@ -1636,7 +1635,7 @@ rl_downcase_word (count, key)
/* Upcase the first letter, downcase the rest. */
int
rl_capitalize_word (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_change_case (count, CapCase));
}
@@ -1760,7 +1759,7 @@ rl_transpose_words (count, key)
then transpose the characters before point. */
int
rl_transpose_chars (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
char dummy[2];
@@ -1853,14 +1852,14 @@ _rl_char_search (count, fdir, bdir)
int
rl_char_search (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (_rl_char_search (count, FFIND, BFIND));
}
int
rl_backward_char_search (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (_rl_char_search (count, BFIND, FFIND));
}
@@ -1965,7 +1964,7 @@ maybe_save_line ()
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
return (rl_get_previous_history (1 + where_history (), key));
}
@@ -1973,7 +1972,7 @@ rl_beginning_of_history (count, key)
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
maybe_replace_line ();
using_history ();
@@ -2105,7 +2104,7 @@ _rl_set_mark_at_pos (position)
/* A bindable command to set the mark. */
int
rl_set_mark (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
}
@@ -2113,7 +2112,7 @@ rl_set_mark (count, key)
/* Exchange the position of mark and point. */
int
rl_exchange_point_and_mark (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
if (rl_mark > rl_end)
rl_mark = -1;
@@ -2137,7 +2136,7 @@ rl_exchange_point_and_mark (count, key)
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
#if defined (VI_MODE)
rl_editing_mode = vi_mode;
@@ -2148,7 +2147,7 @@ rl_vi_editing_mode (count, key)
int
rl_emacs_editing_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_editing_mode = emacs_mode;
_rl_keymap = emacs_standard_keymap;
diff --git a/readline/readline.h b/readline/readline.h
index dba1a0fdde9..7804d31efb1 100644
--- a/readline/readline.h
+++ b/readline/readline.h
@@ -60,7 +60,7 @@ extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct _funmap {
- char *name;
+ const char *name;
Function *function;
} FUNMAP;
@@ -286,17 +286,17 @@ extern int rl_translate_keyseq __P((char *, char *, int *));
extern char *rl_untranslate_keyseq __P((int));
extern Function *rl_named_function __P((char *));
-extern Function *rl_function_of_keyseq __P((char *, Keymap, int *));
+extern Function *rl_function_of_keyseq __P((const char *, Keymap, int *));
extern void rl_list_funmap_names __P((void));
extern char **rl_invoking_keyseqs_in_map __P((Function *, Keymap));
extern char **rl_invoking_keyseqs __P((Function *));
-
+
extern void rl_function_dumper __P((int));
extern void rl_macro_dumper __P((int));
extern void rl_variable_dumper __P((int));
-extern int rl_read_init_file __P((char *));
+extern int rl_read_init_file __P((const char *));
extern int rl_parse_and_bind __P((char *));
/* Functions for manipulating keymaps. */
@@ -306,14 +306,14 @@ extern Keymap rl_make_keymap __P((void));
extern void rl_discard_keymap __P((Keymap));
extern Keymap rl_get_keymap_by_name __P((char *));
-extern char *rl_get_keymap_name __P((Keymap));
+extern const char *rl_get_keymap_name __P((Keymap));
extern void rl_set_keymap __P((Keymap));
extern Keymap rl_get_keymap __P((void));
extern void rl_set_keymap_from_edit_mode __P((void));
-extern char *rl_get_keymap_name_from_edit_mode __P((void));
+extern const char *rl_get_keymap_name_from_edit_mode __P((void));
/* Functions for manipulating the funmap, which maps command names to functions. */
-extern int rl_add_funmap_entry __P((char *, Function *));
+extern int rl_add_funmap_entry __P((const char *, Function *));
extern void rl_initialize_funmap __P((void));
extern char **rl_funmap_names __P((void));
@@ -351,7 +351,7 @@ extern void rl_save_prompt __P((void));
extern void rl_restore_prompt __P((void));
/* Modifying text. */
-extern int rl_insert_text __P((char *));
+extern int rl_insert_text __P((const char *));
extern int rl_delete_text __P((int, int));
extern int rl_kill_text __P((int, int));
extern char *rl_copy_text __P((int, int));
@@ -380,7 +380,7 @@ extern int rl_clear_signals __P((void));
extern void rl_cleanup_after_signal __P((void));
extern void rl_reset_after_signal __P((void));
extern void rl_free_line_state __P((void));
-
+
/* Undocumented. */
extern int rl_expand_prompt __P((char *));
@@ -392,9 +392,9 @@ extern int maybe_replace_line __P((void));
extern int rl_complete_internal __P((int));
extern void rl_display_match_list __P((char **, int, int));
-extern char **completion_matches __P((char *, CPFunction *));
-extern char *username_completion_function __P((char *, int));
-extern char *filename_completion_function __P((char *, int));
+extern char **completion_matches __P((const char *, CPFunction *));
+extern char *username_completion_function __P((const char *, int));
+extern char *filename_completion_function __P((const char *, int));
/* **************************************************************** */
/* */
@@ -403,11 +403,11 @@ extern char *filename_completion_function __P((char *, int));
/* **************************************************************** */
/* The version of this incarnation of the readline library. */
-extern char *rl_library_version;
+extern const char *rl_library_version;
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
-extern char *rl_readline_name;
+extern const char *rl_readline_name;
/* The prompt readline uses. This is set from the argument to
readline (), and should not be assigned to directly. */
@@ -448,7 +448,7 @@ extern Function *rl_startup_hook;
readline_internal_setup () returns and readline_internal starts
reading input characters. */
extern Function *rl_pre_input_hook;
-
+
/* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */
extern Function *rl_event_hook;
@@ -506,12 +506,12 @@ extern CPPFunction *rl_attempted_completion_function;
/* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what
breaks words in the shell, i.e. "n\"\\'`@$>". */
-extern char *rl_basic_word_break_characters;
+extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
-extern char *rl_completer_word_break_characters;
+extern const char *rl_completer_word_break_characters;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@@ -520,7 +520,7 @@ extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */
-extern char *rl_basic_quote_characters;
+extern const char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */
extern char *rl_filename_quote_characters;
@@ -599,7 +599,7 @@ extern int rl_ignore_completion_duplicates;
/* If this is non-zero, completion is (temporarily) inhibited, and the
completion character will be inserted as any other. */
extern int rl_inhibit_completion;
-
+
/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE '\001'
#define RL_PROMPT_END_IGNORE '\002'
diff --git a/readline/rlstdc.h b/readline/rlstdc.h
index d2c5f874d7a..f79cf89fe76 100644
--- a/readline/rlstdc.h
+++ b/readline/rlstdc.h
@@ -76,4 +76,8 @@
#endif /* !__STDC__ */
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#define __attribute__(A)
+#endif
+
#endif /* !_RL_STDC_H_ */
diff --git a/readline/rltty.c b/readline/rltty.c
index b4d0cf127d5..f87c1c9747f 100644
--- a/readline/rltty.c
+++ b/readline/rltty.c
@@ -368,12 +368,15 @@ static TIOTYPE otio;
# define OUTPUT_BEING_FLUSHED(tp) 0
#endif
+#if defined (_AIX) || (defined (FLUSHO) && defined (_AIX41))
static void
rltty_warning (msg)
char *msg;
{
fprintf (stderr, "readline: warning: %s\n", msg);
}
+#endif
+
#if defined (_AIX)
void
@@ -604,8 +607,8 @@ rl_deprep_terminal ()
/* **************************************************************** */
int
-rl_restart_output (count, key)
- int count, key;
+rl_restart_output (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
@@ -637,8 +640,8 @@ rl_restart_output (count, key)
}
int
-rl_stop_output (count, key)
- int count, key;
+rl_stop_output (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int fildes = fileno (rl_instream);
diff --git a/readline/search.c b/readline/search.c
index f198e7409e5..0179d8da2f1 100644
--- a/readline/search.c
+++ b/readline/search.c
@@ -247,8 +247,7 @@ noninc_search (dir, pchar)
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
int
-rl_noninc_forward_search (count, key)
- int count, key;
+rl_noninc_forward_search (int count __attribute__((unused)), int key)
{
noninc_search (1, (key == '?') ? '?' : 0);
return 0;
@@ -257,8 +256,7 @@ rl_noninc_forward_search (count, key)
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
int
-rl_noninc_reverse_search (count, key)
- int count, key;
+rl_noninc_reverse_search (int count __attribute__((unused)), int key)
{
noninc_search (-1, (key == '/') ? '/' : 0);
return 0;
@@ -267,8 +265,8 @@ rl_noninc_reverse_search (count, key)
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
int
-rl_noninc_forward_search_again (count, key)
- int count, key;
+rl_noninc_forward_search_again (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (!noninc_search_string)
{
@@ -282,8 +280,8 @@ rl_noninc_forward_search_again (count, key)
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
int
-rl_noninc_reverse_search_again (count, key)
- int count, key;
+rl_noninc_reverse_search_again (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (!noninc_search_string)
{
@@ -352,8 +350,7 @@ rl_history_search_internal (count, direction)
from the start of the line to rl_point. This is a non-incremental
search. */
int
-rl_history_search_forward (count, ignore)
- int count, ignore;
+rl_history_search_forward (int count, int ignore __attribute__((unused)))
{
if (count == 0)
return (0);
@@ -366,8 +363,7 @@ rl_history_search_forward (count, ignore)
from the start of the line to rl_point. This is a non-incremental
search. */
int
-rl_history_search_backward (count, ignore)
- int count, ignore;
+rl_history_search_backward (int count, int ignore __attribute__((unused)))
{
if (count == 0)
return (0);
diff --git a/readline/shell.c b/readline/shell.c
index 4d9e0064d3f..becd66e0f9a 100644
--- a/readline/shell.c
+++ b/readline/shell.c
@@ -26,6 +26,7 @@
# include <config.h>
#endif
+#include <stdio.h>
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
diff --git a/readline/terminal.c b/readline/terminal.c
index 6e94bdc4011..1d2fead7768 100644
--- a/readline/terminal.c
+++ b/readline/terminal.c
@@ -99,8 +99,8 @@ char PC, *BC, *UP;
#endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */
-char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
-char *term_pc;
+char *term_goto, *term_clreol, *term_clrpag, *term_backspace;
+char *term_cr, *term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */
int terminal_can_insert = 0;
@@ -245,8 +245,8 @@ rl_resize_terminal ()
}
struct _tc_string {
- char *tc_var;
- char **tc_value;
+ const char *tc_var;
+ char **tc_value;
};
/* This should be kept sorted, just in case we decide to change the
@@ -291,7 +291,7 @@ get_term_capabilities (bp)
{
register int i;
- for (i = 0; i < NUM_TC_STRINGS; i++)
+ for (i = 0; i < (int) NUM_TC_STRINGS; i++)
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
tcap_initialized = 1;
}
@@ -304,7 +304,7 @@ _rl_init_terminal_io (terminal_name)
screenwidth = ScreenCols ();
screenheight = ScreenRows ();
screenchars = screenwidth * screenheight;
- term_cr = "\r";
+ term_cr = (char*) "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
@@ -322,7 +322,8 @@ _rl_init_terminal_io (terminal_name)
return;
#else /* !__GO32__ */
- char *term, *buffer;
+ const char *term;
+ char *buffer;
int tty;
Keymap xkeymap;
@@ -347,7 +348,7 @@ _rl_init_terminal_io (terminal_name)
screenwidth = 79;
screenheight = 24;
screenchars = 79 * 24;
- term_cr = "\r";
+ term_cr = (char*) "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
term_ku = term_kd = term_kl = term_kr = (char *)NULL;
@@ -367,7 +368,7 @@ _rl_init_terminal_io (terminal_name)
UP = term_up;
if (!term_cr)
- term_cr = "\r";
+ term_cr = (char*) "\r";
tty = rl_instream ? fileno (rl_instream) : 0;
@@ -427,7 +428,7 @@ rl_get_termcap (cap)
if (tcap_initialized == 0)
return ((char *)NULL);
- for (i = 0; i < NUM_TC_STRINGS; i++)
+ for (i = 0; i < (int) NUM_TC_STRINGS; i++)
{
if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
return *(tc_strings[i].tc_value);
diff --git a/readline/tilde.c b/readline/tilde.c
index 65a1e2f3902..05c9ed741ed 100644
--- a/readline/tilde.c
+++ b/readline/tilde.c
@@ -82,13 +82,13 @@ extern char *get_env_value ();
/* The default value of tilde_additional_prefixes. This is set to
whitespace preceding a tilde so that simple programs which do not
perform any word separation get desired behaviour. */
-static char *default_prefixes[] =
+static const char *default_prefixes[] =
{ " ~", "\t~", (char *)NULL };
/* The default value of tilde_additional_suffixes. This is set to
whitespace or newline so that simple programs which do not
perform any word separation get desired behaviour. */
-static char *default_suffixes[] =
+static const char *default_suffixes[] =
{ " ", "\n", (char *)NULL };
/* If non-null, this contains the address of a function that the application
@@ -106,12 +106,12 @@ CPFunction *tilde_expansion_failure_hook = (CPFunction *)NULL;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
-char **tilde_additional_prefixes = default_prefixes;
+const char ** tilde_additional_prefixes = default_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
-char **tilde_additional_suffixes = default_suffixes;
+const char **tilde_additional_suffixes = default_suffixes;
/* Find the start of a tilde expansion in STRING, and return the index of
the tilde which starts the expansion. Place the length of the text
@@ -122,7 +122,7 @@ tilde_find_prefix (string, len)
int *len;
{
register int i, j, string_len;
- register char **prefixes = tilde_additional_prefixes;
+ register const char **prefixes = tilde_additional_prefixes;
string_len = strlen (string);
*len = 0;
@@ -154,7 +154,7 @@ tilde_find_suffix (string)
char *string;
{
register int i, j, string_len;
- register char **suffixes;
+ register const char **suffixes;
suffixes = tilde_additional_suffixes;
string_len = strlen (string);
diff --git a/readline/tilde.h b/readline/tilde.h
index 634b95449aa..45eea1b66e5 100644
--- a/readline/tilde.h
+++ b/readline/tilde.h
@@ -48,12 +48,12 @@ extern CPFunction *tilde_expansion_failure_hook;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
-extern char **tilde_additional_prefixes;
+extern const char **tilde_additional_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
-extern char **tilde_additional_suffixes;
+extern const char **tilde_additional_suffixes;
/* Return a new string which is the result of tilde expanding STRING. */
extern char *tilde_expand ();
diff --git a/readline/undo.c b/readline/undo.c
index 68710b667ed..c8f4892b774 100644
--- a/readline/undo.c
+++ b/readline/undo.c
@@ -174,7 +174,7 @@ _rl_fix_last_undo_of_type (type, start, end)
for (rl = rl_undo_list; rl; rl = rl->next)
{
- if (rl->what == type)
+ if ((int) rl->what == type)
{
rl->start = start;
rl->end = end;
@@ -225,8 +225,8 @@ rl_modifying (start, end)
/* Revert the current line to its previous state. */
int
-rl_revert_line (count, key)
- int count, key;
+rl_revert_line (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (!rl_undo_list)
ding ();
@@ -240,8 +240,7 @@ rl_revert_line (count, key)
/* Do some undoing of things that were done. */
int
-rl_undo_command (count, key)
- int count, key;
+rl_undo_command (int count, int key __attribute__((unused)))
{
if (count < 0)
return 0; /* Nothing to do. */
diff --git a/readline/util.c b/readline/util.c
index 1dc3b664f1c..bcd8f3bc5b2 100644
--- a/readline/util.c
+++ b/readline/util.c
@@ -81,7 +81,7 @@ extern char *xmalloc (), *xrealloc ();
in words, or 1 if it is. */
int _rl_allow_pathname_alphabetic_chars = 0;
-static char *pathname_alphabetic_chars = "/-_=~.#$";
+static const char *pathname_alphabetic_chars = "/-_=~.#$";
int
alphabetic (c)
@@ -113,15 +113,15 @@ _rl_abort_internal ()
}
int
-rl_abort (count, key)
- int count, key;
+rl_abort (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
return (_rl_abort_internal ());
}
int
-rl_tty_status (count, key)
- int count, key;
+rl_tty_status (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
@@ -170,8 +170,8 @@ rl_extend_line_buffer (len)
/* A function for simple tilde expansion. */
int
-rl_tilde_expand (ignore, key)
- int ignore, key;
+rl_tilde_expand (int ignore __attribute__((unused)),
+ int key __attribute__((unused)))
{
register int start, end;
char *homedir, *temp;
diff --git a/readline/vi_mode.c b/readline/vi_mode.c
index 2a4f11d28a4..eb392b643ba 100644
--- a/readline/vi_mode.c
+++ b/readline/vi_mode.c
@@ -98,7 +98,7 @@ extern int rl_vi_check ();
static int _rl_vi_doing_insert;
/* Command keys which do movement for xxx_to commands. */
-static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
+static const char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since
rarely used. */
@@ -126,7 +126,7 @@ static int _rl_vi_last_key_before_insert;
static int vi_redoing;
/* Text modification commands. These are the `redoable' commands. */
-static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
+static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
/* Arrays for the saved marks. */
static int vi_mark_chars[27];
@@ -136,7 +136,11 @@ static int rl_digit_loop1 ();
void
_rl_vi_initialize_line ()
{
- register int i;
+#ifndef __QNXNTO__
+ register uint i;
+#else
+ register unsigned int i;
+#endif
for (i = 0; i < (int) sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1;
@@ -183,7 +187,7 @@ _rl_vi_stuff_insert (count)
puts you back into insert mode. */
int
rl_vi_redo (count, c)
- int count, c;
+ int count, c __attribute__((unused));
{
if (!rl_explicit_arg)
{
@@ -215,11 +219,11 @@ rl_vi_undo (count, key)
{
return (rl_undo_command (count, key));
}
-
+
/* Yank the nth arg from the previous line into this line at point. */
int
-rl_vi_yank_arg (count, key)
- int count, key;
+rl_vi_yank_arg (count, key)
+ int count, key __attribute__((unused));
{
/* Readline thinks that the first word on a line is the 0th, while vi
thinks the first word on a line is the 1st. Compensate. */
@@ -300,7 +304,7 @@ rl_vi_search (count, key)
/* Completion, from vi's point of view. */
int
rl_vi_complete (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
{
@@ -329,7 +333,7 @@ rl_vi_complete (ignore, key)
/* Tilde expansion for vi mode. */
int
rl_vi_tilde_expand (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
rl_tilde_expand (0, key);
_rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
@@ -401,7 +405,7 @@ rl_vi_end_word (count, key)
/* Move forward a word the way that 'W' does. */
int
rl_vi_fWord (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < (rl_end - 1))
{
@@ -418,7 +422,7 @@ rl_vi_fWord (count, ignore)
int
rl_vi_bWord (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point > 0)
{
@@ -442,7 +446,7 @@ rl_vi_bWord (count, ignore)
int
rl_vi_eWord (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < (rl_end - 1))
{
@@ -472,7 +476,7 @@ rl_vi_eWord (count, ignore)
int
rl_vi_fword (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < (rl_end - 1))
{
@@ -498,7 +502,7 @@ rl_vi_fword (count, ignore)
int
rl_vi_bword (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point > 0)
{
@@ -537,7 +541,7 @@ rl_vi_bword (count, ignore)
int
rl_vi_eword (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < rl_end - 1)
{
@@ -562,7 +566,7 @@ rl_vi_eword (count, ignore)
int
rl_vi_insert_beg (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_beg_of_line (1, key);
rl_vi_insertion_mode (1, key);
@@ -571,7 +575,7 @@ rl_vi_insert_beg (count, key)
int
rl_vi_append_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
if (rl_point < rl_end)
rl_point++;
@@ -581,7 +585,7 @@ rl_vi_append_mode (count, key)
int
rl_vi_append_eol (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_end_of_line (1, key);
rl_vi_append_mode (1, key);
@@ -591,7 +595,7 @@ rl_vi_append_eol (count, key)
/* What to do in the case of C-d. */
int
rl_vi_eof_maybe (count, c)
- int count, c;
+ int count __attribute__((unused)), c __attribute__((unused));
{
return (rl_newline (1, '\n'));
}
@@ -602,7 +606,7 @@ rl_vi_eof_maybe (count, c)
switching keymaps. */
int
rl_vi_insertion_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
_rl_keymap = vi_insertion_keymap;
_rl_vi_last_key_before_insert = key;
@@ -633,7 +637,7 @@ _rl_vi_save_insert (up)
strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
vi_insert_buffer[len-1] = '\0';
}
-
+
void
_rl_vi_done_inserting ()
{
@@ -664,7 +668,7 @@ _rl_vi_done_inserting ()
int
rl_vi_movement_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
if (rl_point > 0)
rl_backward (1, key);
@@ -686,7 +690,7 @@ rl_vi_arg_digit (count, c)
int
rl_vi_change_case (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
char c = 0;
@@ -724,7 +728,7 @@ rl_vi_change_case (count, ignore)
int
rl_vi_put (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point++;
@@ -881,7 +885,7 @@ rl_digit_loop1 ()
int
rl_vi_delete_to (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
int c;
@@ -961,7 +965,7 @@ rl_vi_change_to (count, key)
int
rl_vi_yank_to (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
int c, save = rl_point;
@@ -1006,7 +1010,7 @@ rl_vi_delete (count, key)
end = rl_end;
rl_kill_text (rl_point, end);
-
+
if (rl_point > 0 && rl_point == rl_end)
rl_backward (1, key);
return (0);
@@ -1014,7 +1018,7 @@ rl_vi_delete (count, key)
int
rl_vi_back_to_indent (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_beg_of_line (1, key);
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
@@ -1024,7 +1028,7 @@ rl_vi_back_to_indent (count, key)
int
rl_vi_first_print (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
return (rl_vi_back_to_indent (1, key));
}
@@ -1071,7 +1075,7 @@ rl_vi_char_search (count, key)
/* Match brackets */
int
rl_vi_match (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
int count = 1, brack, pos;
@@ -1152,7 +1156,7 @@ rl_vi_bracktype (c)
int
rl_vi_change_char (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
int c;
@@ -1278,7 +1282,7 @@ rl_vi_overstrike_delete (count, key)
int
rl_vi_replace (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
int i;
@@ -1339,7 +1343,7 @@ rl_vi_possible_completions()
/* Functions to save and restore marks. */
int
rl_vi_set_mark (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
int ch;
@@ -1356,7 +1360,7 @@ rl_vi_set_mark (count, key)
int
rl_vi_goto_mark (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
int ch;
diff --git a/regex/cclass.h b/regex/cclass.h
index 7d9a7ccc7c2..e0f752f38b8 100644
--- a/regex/cclass.h
+++ b/regex/cclass.h
@@ -15,7 +15,7 @@
#define CCLASS_LAST 12
extern struct cclass {
- char *name;
- char *chars;
- char *multis;
+ const char *name;
+ const char *chars;
+ const char *multis;
} cclasses[];
diff --git a/regex/cname.h b/regex/cname.h
index 2b6a1a8496f..06865f3e102 100644
--- a/regex/cname.h
+++ b/regex/cname.h
@@ -1,7 +1,7 @@
/* character-name table */
static struct cname {
- char *name;
- char code;
+ const char *name;
+ const char code;
} cnames[] = {
{"NUL", '\0'},
{"SOH", '\001'},
diff --git a/regex/debug.c b/regex/debug.c
index 8c6fd14a209..35279941d48 100644
--- a/regex/debug.c
+++ b/regex/debug.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <m_string.h>
#include <sys/types.h>
diff --git a/regex/main.c b/regex/main.c
index 4b607f401ca..7844a4d8384 100644
--- a/regex/main.c
+++ b/regex/main.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <sys/types.h>
#include <regex.h>
@@ -133,9 +133,9 @@ FILE *in;
int i;
char erbuf[100];
size_t ne;
- char *badpat = "invalid regular expression";
+ const char *badpat = "invalid regular expression";
# define SHORT 10
- char *bpname = "REG_BADPAT";
+ const char *bpname = "REG_BADPAT";
regex_t re;
while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
@@ -152,7 +152,7 @@ FILE *in;
}
for (i = 0; i < nf; i++)
if (strcmp(f[i], "\"\"") == 0)
- f[i] = "";
+ f[i] = (char*) "";
if (nf <= 3)
f[3] = NULL;
if (nf <= 4)
@@ -217,7 +217,7 @@ int opts; /* may not match f1 */
char erbuf[100];
int err;
int len;
- char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
+ const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
register int i;
char *grump;
char f0copy[1000];
@@ -291,7 +291,7 @@ int opts; /* may not match f1 */
nshould = split(f4, should+1, NSHOULD-1, ",");
if (nshould == 0) {
nshould = 1;
- should[1] = "";
+ should[1] = (char*) "";
}
for (i = 1; i < NSUBS; i++) {
grump = check(f2, subs[i], should[i]);
@@ -317,7 +317,7 @@ char *s;
{
register char *p;
register int o = (type == 'c') ? copts : eopts;
- register char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
+ register const char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
for (p = s; *p != '\0'; p++)
if (strchr(legal, *p) != NULL)
@@ -417,7 +417,7 @@ char *should;
should = NULL;
if (should != NULL && should[0] == '@') {
at = should + 1;
- should = "";
+ should = (char*) "";
}
/* check rm_so and rm_eo for consistency */
@@ -434,7 +434,7 @@ char *should;
if (sub.rm_so == -1 && should == NULL)
return(NULL);
if (sub.rm_so == -1)
- return("did not match");
+ return((char*) "did not match");
/* check for in range */
if ((int) sub.rm_eo > (int) strlen(str)) {
diff --git a/regex/regcomp.c b/regex/regcomp.c
index 048f45ca71c..6f8221a706d 100644
--- a/regex/regcomp.c
+++ b/regex/regcomp.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
#include <regex.h>
@@ -219,7 +219,7 @@ int stop; /* character this ERE should end at */
conc = HERE();
while (MORE() && (c = PEEK()) != '|' && c != stop)
p_ere_exp(p);
- if(REQUIRE(HERE() != conc, REG_EMPTY)); /* require nonempty */
+ if(REQUIRE(HERE() != conc, REG_EMPTY)) {}/* require nonempty */
if (!EAT('|'))
break; /* NOTE BREAK OUT */
@@ -266,11 +266,11 @@ register struct parse *p;
pos = HERE();
switch (c) {
case '(':
- if(REQUIRE(MORE(), REG_EPAREN));
+ if(REQUIRE(MORE(), REG_EPAREN)) {}
p->g->nsub++;
subno = (sopno) p->g->nsub;
if (subno < NPAREN)
- p->pbegin[subno] = HERE();
+ p->pbegin[subno] = HERE();
EMIT(OLPAREN, subno);
if (!SEE(')'))
p_ere(p, ')');
@@ -279,7 +279,7 @@ register struct parse *p;
assert(p->pend[subno] != 0);
}
EMIT(ORPAREN, subno);
- if(MUSTEAT(')', REG_EPAREN));
+ if(MUSTEAT(')', REG_EPAREN)) {}
break;
#ifndef POSIX_MISTAKE
case ')': /* happens only if no current unmatched ( */
@@ -322,12 +322,12 @@ register struct parse *p;
p_bracket(p);
break;
case '\\':
- if(REQUIRE(MORE(), REG_EESCAPE));
+ if(REQUIRE(MORE(), REG_EESCAPE)) {}
c = GETNEXT();
ordinary(p, c);
break;
case '{': /* okay as ordinary except if digit follows */
- if(REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT));
+ if(REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT)) {}
/* FALLTHROUGH */
default:
ordinary(p, c);
@@ -343,7 +343,7 @@ register struct parse *p;
return; /* no repetition, we're done */
NEXT();
- if(REQUIRE(!wascaret, REG_BADRPT));
+ if(REQUIRE(!wascaret, REG_BADRPT)) {}
switch (c) {
case '*': /* implemented as +? */
/* this case does not require the (y|) trick, noKLUDGE */
@@ -370,7 +370,7 @@ register struct parse *p;
if (EAT(',')) {
if (isdigit(PEEK())) {
count2 = p_count(p);
- if(REQUIRE(count <= count2, REG_BADBR));
+ if(REQUIRE(count <= count2, REG_BADBR)) {}
} else /* single number with comma */
count2 = RE_INFINITY;
} else /* just a single number */
@@ -379,7 +379,7 @@ register struct parse *p;
if (!EAT('}')) { /* error heuristics */
while (MORE() && PEEK() != '}')
NEXT();
- if(REQUIRE(MORE(), REG_EBRACE));
+ if(REQUIRE(MORE(), REG_EBRACE)) {}
SETERROR(REG_BADBR);
}
break;
@@ -402,7 +402,7 @@ static void
p_str(p)
register struct parse *p;
{
- if(REQUIRE(MORE(), REG_EMPTY));
+ if(REQUIRE(MORE(), REG_EMPTY)) {}
while (MORE())
ordinary(p, GETNEXT());
}
@@ -445,7 +445,7 @@ register int end2; /* second terminating character */
p->g->neol++;
}
- if(REQUIRE(HERE() != start, REG_EMPTY)); /* require nonempty */
+ if(REQUIRE(HERE() != start, REG_EMPTY)) {} /* require nonempty */
}
/*
@@ -470,7 +470,7 @@ int starordinary; /* is a leading * an ordinary character? */
assert(MORE()); /* caller should have ensured this */
c = GETNEXT();
if (c == '\\') {
- if(REQUIRE(MORE(), REG_EESCAPE));
+ if(REQUIRE(MORE(), REG_EESCAPE)) {}
c = BACKSL | (unsigned char)GETNEXT();
}
switch (c) {
@@ -500,7 +500,7 @@ int starordinary; /* is a leading * an ordinary character? */
assert(p->pend[subno] != 0);
}
EMIT(ORPAREN, subno);
- if(REQUIRE(EATTWO('\\', ')'), REG_EPAREN));
+ if(REQUIRE(EATTWO('\\', ')'), REG_EPAREN)) {}
break;
case BACKSL|')': /* should not get here -- must be user */
case BACKSL|'}':
@@ -530,7 +530,7 @@ int starordinary; /* is a leading * an ordinary character? */
p->g->backrefs = 1;
break;
case '*':
- if(REQUIRE(starordinary, REG_BADRPT));
+ if(REQUIRE(starordinary, REG_BADRPT)) {}
/* FALLTHROUGH */
default:
ordinary(p, c &~ BACKSL);
@@ -548,7 +548,7 @@ int starordinary; /* is a leading * an ordinary character? */
if (EAT(',')) {
if (MORE() && isdigit(PEEK())) {
count2 = p_count(p);
- if(REQUIRE(count <= count2, REG_BADBR));
+ if(REQUIRE(count <= count2, REG_BADBR)) {}
} else /* single number with comma */
count2 = RE_INFINITY;
} else /* just a single number */
@@ -557,7 +557,7 @@ int starordinary; /* is a leading * an ordinary character? */
if (!EATTWO('\\', '}')) { /* error heuristics */
while (MORE() && !SEETWO('\\', '}'))
NEXT();
- if(REQUIRE(MORE(), REG_EBRACE));
+ if(REQUIRE(MORE(), REG_EBRACE)) {}
SETERROR(REG_BADBR);
}
} else if (c == (unsigned char)'$') /* $ (but not \$) ends it */
@@ -582,7 +582,7 @@ register struct parse *p;
ndigits++;
}
- if(REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR));
+ if(REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR)) {}
return(count);
}
@@ -622,7 +622,7 @@ register struct parse *p;
p_b_term(p, cs);
if (EAT('-'))
CHadd(cs, '-');
- if(MUSTEAT(']', REG_EBRACK));
+ if(MUSTEAT(']', REG_EBRACK)) {}
if (p->error != 0) /* don't mess things up further */
return;
@@ -693,21 +693,21 @@ register cset *cs;
switch (c) {
case ':': /* character class */
NEXT2();
- if(REQUIRE(MORE(), REG_EBRACK));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
c = PEEK();
- if(REQUIRE(c != '-' && c != ']', REG_ECTYPE));
+ if(REQUIRE(c != '-' && c != ']', REG_ECTYPE)) {}
p_b_cclass(p, cs);
- if(REQUIRE(MORE(), REG_EBRACK));
- if(REQUIRE(EATTWO(':', ']'), REG_ECTYPE));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
+ if(REQUIRE(EATTWO(':', ']'), REG_ECTYPE)) {}
break;
case '=': /* equivalence class */
NEXT2();
- if(REQUIRE(MORE(), REG_EBRACK));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
c = PEEK();
- if(REQUIRE(c != '-' && c != ']', REG_ECOLLATE));
+ if(REQUIRE(c != '-' && c != ']', REG_ECOLLATE)) {}
p_b_eclass(p, cs);
- if(REQUIRE(MORE(), REG_EBRACK));
- if(REQUIRE(EATTWO('=', ']'), REG_ECOLLATE));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
+ if(REQUIRE(EATTWO('=', ']'), REG_ECOLLATE)) {}
break;
default: /* symbol, ordinary character, or range */
/* xxx revision needed for multichar stuff */
@@ -722,7 +722,7 @@ register cset *cs;
} else
finish = start;
/* xxx what about signed chars here... */
- if(REQUIRE(start <= finish, REG_ERANGE));
+ if(REQUIRE(start <= finish, REG_ERANGE)) {}
for (i = start; i <= finish; i++)
CHadd(cs, i);
break;
@@ -756,10 +756,10 @@ register cset *cs;
return;
}
- u = cp->chars;
+ u = (char*) cp->chars;
while ((c = *u++) != '\0')
CHadd(cs, c);
- for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
+ for (u = (char*) cp->multis; *u != '\0'; u += strlen(u) + 1)
MCadd(p, cs, u);
}
@@ -790,13 +790,13 @@ register struct parse *p;
{
register char value;
- if(REQUIRE(MORE(), REG_EBRACK));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
if (!EATTWO('[', '.'))
return(GETNEXT());
/* collating symbol */
value = p_b_coll_elem(p, '.');
- if(REQUIRE(EATTWO('.', ']'), REG_ECOLLATE));
+ if(REQUIRE(EATTWO('.', ']'), REG_ECOLLATE)) {}
return(value);
}
@@ -1189,6 +1189,7 @@ register char *cp;
cs->multis[cs->smultis - 1] = '\0';
}
+#ifdef NOT_USED
/*
- mcsub - subtract a collating element from a cset
== static void mcsub(register cset *cs, register char *cp);
@@ -1246,6 +1247,7 @@ register char *cp;
return(p);
return(NULL);
}
+#endif
/*
- mcinvert - invert the list of collating elements in a cset
@@ -1256,8 +1258,8 @@ register char *cp;
*/
static void
mcinvert(p, cs)
-register struct parse *p;
-register cset *cs;
+ register struct parse *p __attribute__((unused));
+ register cset *cs __attribute__((unused));
{
assert(cs->multis == NULL); /* xxx */
}
@@ -1271,8 +1273,8 @@ register cset *cs;
*/
static void
mccase(p, cs)
-register struct parse *p;
-register cset *cs;
+register struct parse *p __attribute__((unused));
+register cset *cs __attribute__((unused));
{
assert(cs->multis == NULL); /* xxx */
}
diff --git a/regex/regcomp.ih b/regex/regcomp.ih
index 0776e7185cd..4ae45bbf4a9 100644
--- a/regex/regcomp.ih
+++ b/regex/regcomp.ih
@@ -28,9 +28,11 @@ static int freezeset(register struct parse *p, register cset *cs);
static int firstch(register struct parse *p, register cset *cs);
static int nch(register struct parse *p, register cset *cs);
static void mcadd(register struct parse *p, register cset *cs, register char *cp);
+#ifdef NOT_USED
static void mcsub(register cset *cs, register char *cp);
static int mcin(register cset *cs, register char *cp);
static char *mcfind(register cset *cs, register char *cp);
+#endif
static void mcinvert(register struct parse *p, register cset *cs);
static void mccase(register struct parse *p, register cset *cs);
static int isinsets(register struct re_guts *g, int c);
diff --git a/regex/regerror.c b/regex/regerror.c
index a356912564a..0a7b7c8da2c 100644
--- a/regex/regerror.c
+++ b/regex/regerror.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
#include <regex.h>
@@ -28,8 +28,8 @@
*/
static struct rerr {
int code;
- char *name;
- char *explain;
+ const char *name;
+ const char *explain;
} rerrs[] = {
{REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
{REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
@@ -83,7 +83,7 @@ size_t errbuf_size;
assert(strlen(convbuf) < sizeof(convbuf));
s = convbuf;
} else
- s = r->explain;
+ s = (char*) r->explain;
}
len = strlen(s) + 1;
@@ -113,7 +113,7 @@ char *localbuf;
if (strcmp(r->name, preg->re_endp) == 0)
break;
if (r->code == 0)
- return("0");
+ return((char*) "0");
sprintf(localbuf, "%d", r->code);
return(localbuf);
diff --git a/regex/regexec.c b/regex/regexec.c
index 853bd7aa263..7f2704f8214 100644
--- a/regex/regexec.c
+++ b/regex/regexec.c
@@ -5,7 +5,7 @@
* macros that code uses. This lets the same code operate on two different
* representations for state sets.
*/
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
#include <regex.h>
diff --git a/regex/regexp.c b/regex/regexp.c
index 706208a6b25..8ddf90f2943 100644
--- a/regex/regexp.c
+++ b/regex/regexp.c
@@ -58,7 +58,7 @@
*/
/* Headers */
-#include "global.h"
+#include "my_global.h"
#include <ctype.h>
#include "regexp.h"
#ifdef __WIN__
diff --git a/regex/regfree.c b/regex/regfree.c
index a0dd8087a45..6ab50735075 100644
--- a/regex/regfree.c
+++ b/regex/regfree.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/regex/reginit.c b/regex/reginit.c
index b5815e7d01c..18647c386fc 100644
--- a/regex/reginit.c
+++ b/regex/reginit.c
@@ -1,6 +1,6 @@
/* Init cclasses array from ctypes */
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <m_string.h>
#include "cclass.h"
@@ -63,7 +63,7 @@ void regex_end()
{
int i;
for (i=0; i < CCLASS_LAST ; i++)
- free(cclasses[i].chars);
+ free((char*) cclasses[i].chars);
regex_inited=0;
}
}
diff --git a/regex/split.c b/regex/split.c
index 188bdb775b9..bd2a53c01e3 100644
--- a/regex/split.c
+++ b/regex/split.c
@@ -27,7 +27,7 @@ char *sep; /* "" white, "c" single char, "ab" [ab]+ */
continue;
p--;
trimtrail = 1;
- sep = " \t"; /* note, code below knows this is 2 long */
+ sep = (char*) " \t"; /* note, code below knows this is 2 long */
sepc = ' ';
} else
trimtrail = 0;
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 18957b6422d..1469f3f2f2d 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -20,7 +20,9 @@ bin_SCRIPTS = @server_scripts@ \
msql2mysql \
mysql_config \
mysql_fix_privilege_tables \
+ mysql_fix_extensions \
mysql_setpermission \
+ mysql_secure_installation \
mysql_zap \
mysqlaccess \
mysqlbug \
@@ -28,14 +30,18 @@ bin_SCRIPTS = @server_scripts@ \
mysql_find_rows \
mysqlhotcopy \
mysqldumpslow \
+ mysql_explain_log \
+ mysql_tableinfo \
mysqld_multi
EXTRA_SCRIPTS = make_binary_distribution.sh \
msql2mysql.sh \
mysql_config.sh \
mysql_fix_privilege_tables.sh \
+ mysql_fix_extensions.sh \
mysql_install_db.sh \
mysql_setpermission.sh \
+ mysql_secure_installation.sh \
mysql_zap.sh \
mysqlaccess.sh \
mysqlbug.sh \
@@ -43,8 +49,10 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \
mysql_find_rows.sh \
mysqlhotcopy.sh \
mysqldumpslow.sh \
+ mysql_explain_log.sh \
mysqld_multi.sh \
- safe_mysqld.sh
+ mysql_tableinfo.sh \
+ mysqld_safe.sh
EXTRA_DIST = $(EXTRA_SCRIPTS) \
mysqlaccess.conf \
@@ -59,7 +67,9 @@ CLEANFILES = @server_scripts@ \
msql2mysql \
mysql_config \
mysql_fix_privilege_tables \
+ mysql_fix_extensions \
mysql_setpermission \
+ mysql_secure_installation \
mysql_zap \
mysqlaccess \
mysql_convert_table_format \
@@ -95,6 +105,8 @@ SUFFIXES = .sh
-e 's!@''CXXFLAGS''@!@SAVE_CXXFLAGS@!'\
-e 's!@''LDFLAGS''@!@SAVE_LDFLAGS@!'\
-e 's!@''CLIENT_LIBS''@!@CLIENT_LIBS@!' \
+ -e 's!@''LIBS''@!@LIBS@!' \
+ -e 's!@''innodb_system_libs''@!@innodb_system_libs@!' \
-e 's!@''VERSION''@!@VERSION@!' \
-e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \
-e 's!@''COMPILATION_COMMENT''@!@COMPILATION_COMMENT@!' \
diff --git a/scripts/explain_log.sh b/scripts/explain_log.sh
new file mode 100644
index 00000000000..c4a4ef21568
--- /dev/null
+++ b/scripts/explain_log.sh
@@ -0,0 +1,383 @@
+#!@PERL@ -w
+use strict;
+use DBI;
+
+use Getopt::Long;
+$Getopt::Long::ignorecase=0;
+
+print "explain_log provided by http://www.mobile.de\n";
+print "=========== ================================\n";
+
+my $Param={};
+
+$Param->{host}='';
+$Param->{user}='';
+$Param->{password}='';
+$Param->{PrintError}=0;
+
+if (!GetOptions ('date|d:i' => \$Param->{ViewDate},
+ 'host|h:s' => \$Param->{host},
+ 'user|u:s' => \$Param->{user},
+ 'password|p:s' => \$Param->{password},
+ 'printerror|e:s' => \$Param->{PrintError},
+ )) {
+ ShowOptions();
+}
+else {
+ $Param->{UpdateCount} = 0;
+ $Param->{SelectCount} = 0;
+ $Param->{IdxUseCount} = 0;
+ $Param->{LineCount} = 0;
+
+ $Param->{Init} = 0;
+ $Param->{Field} = 0;
+ $Param->{Refresh} = 0;
+ $Param->{QueryCount} = 0;
+ $Param->{Statistics} =0;
+
+ $Param->{Query} = undef;
+ $Param->{ALL} = undef ;
+ $Param->{Comment} = undef ;
+
+ @{$Param->{Rows}} = (qw|possible_keys key type|);
+
+ if ($Param->{ViewDate}) {
+ $Param->{View} = 0;
+ }
+ else {
+ $Param->{View} = 1;
+ }
+
+ #print "Date=$Param->{ViewDate}, host=$Param->{host}, user=$Param->{user}, password=$Param->{password}\n";
+
+ $Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}",$Param->{user},$Param->{password},{PrintError=>0});
+ if (DBI::err()) {
+ print "Error: " . DBI::errstr() . "\n";
+ }
+ else {
+ $Param->{Start} = time;
+ while(<STDIN>) {
+ $Param->{LineCount} ++ ;
+
+ if ($Param->{ViewDate} ) {
+ if (m/^(\d{6})\s+\d{1,2}:\d\d:\d\d\s.*$/) { # get date
+ #print "# $1 #\n";
+ if ($1 == $Param->{ViewDate}) {
+ $Param->{View} = 1;
+ }
+ else {
+ $Param->{View} = 0;
+ }
+ }
+ }
+ if ($Param->{View} ) {
+ #print "->>>$_";
+
+ if (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
+ #print "C-$1--$2--$3------\n";
+ RunQuery($Param);
+ if (defined $3) {
+ $Param->{CID}->{$2} = $3 ;
+ #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+$/i) { # get connection ID($2) and database($3)
+ #print "\n <<<<<<<<<<<<<<<<<<----------------------------<<<<<<<<<<<<<<<< \n";
+ #print "Connect \n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Change user .*\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
+ #print "C-$1--$2--$3------\n";
+ RunQuery($Param);
+ if (defined $3) {
+ $Param->{CID}->{$2} = $3 ;
+ #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Quit\s+$/i) { # remove connection ID($2) and querystring
+ #print "Q-$1--$2--------\n";
+ RunQuery($Param);
+ delete $Param->{CID}->{$2} ;
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(select.+)$/i) { # get connection ID($2) and querystring
+ #print "S1-$1--$2--$3------\n";
+ RunQuery($Param);
+ unless ($Param->{CID}->{$2}) {
+ #print "Error: No Database for Handle: $2 found\n";
+ }
+ else {
+ $Param->{DB}=$Param->{CID}->{$2};
+
+ my $s = "$3";
+ $s =~ s/from\s/from $Param->{DB}./i;
+ $Param->{Query}="EXPLAIN $s";
+
+ #$s =~ m/from\s+(\w+[.]\w+)/i;
+ #$Param->{tab} =$1;
+ #print "-- $Param->{tab} -- $s --\n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(update.+)$/i) { # get connection ID($2) and querystring
+ #print "S2--$1--$2--$3------\n";
+ RunQuery($Param);
+ unless ($Param->{CID}->{$2}) {
+ #print "Error: No Database for Handle: $2 found\n";
+ }
+ else {
+ $Param->{DB}=$Param->{CID}->{$2};
+
+ my $ud = $3;
+ $ud =~ m/^update\s+(\w+).+(where.+)$/i;
+ $Param->{Query} ="EXPLAIN SELECT * FROM $1 $2";
+ $Param->{Query} =~ s/from\s/from $Param->{DB}./i;
+
+ #$Param->{Query} =~ m/from\s+(\w+[.]\w+)/i;
+ #$Param->{tab} =$1;
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Statistics\s+(.*)$/i) { # get connection ID($2) and info?
+ $Param->{Statistics} ++;
+ #print "Statistics--$1--$2--$3------\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(.+)$/i) { # get connection ID($2)
+ $Param->{QueryCount} ++;
+ #print "Query-NULL $3\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Refresh\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Refresh} ++;
+ #print "Refresh\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Init\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Init} ++;
+ #print "Init $3\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Field\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Field} ++;
+ #print "Field $3\n";
+ RunQuery($Param);
+ }
+
+ elsif (m/^\s+(.+)$/ ) { # command could be some lines ...
+ #print "multi-lined ($1)\n";
+ my ($A)=$1;
+ chomp $A;
+ $Param->{Query} .= " $1";
+ #print "multi-lined ($1)<<$Param->{Query}>>\n";
+ }
+
+
+ }
+
+ }
+
+ $Param->{dbh}->disconnect();
+
+ if (1 == 0) {
+ print "\nunclosed handles----------------------------------------\n";
+ my $count=0;
+ foreach (sort keys %{$Param->{CID}}) {
+ print "$count | $_ : $Param->{CID}->{$_} \n";
+ $count ++;
+ }
+ }
+
+ print "\nIndex usage ------------------------------------\n";
+ foreach my $t (sort keys %{$Param->{Data}}) {
+ print "\nTable\t$t: ---\n";
+ foreach my $k (sort keys %{$Param->{Data}->{$t}}) {
+ print " count\t$k:\n";
+ my %h = %{$Param->{Data}->{$t}->{$k}};
+ foreach (sort {$h{$a} <=> $h{$b}} keys %h) {
+ print " $Param->{Data}->{$t}->{$k}->{$_}\t$_\n";
+ }
+ }
+ }
+
+ $Param->{AllCount}=0;
+ print "\nQueries causing table scans -------------------\n\n";
+ foreach (@{$Param->{ALL}}) {
+ $Param->{AllCount} ++;
+ print "$_\n";
+ }
+ print "Sum: $Param->{AllCount} table scans\n";
+
+ print "\nSummary ---------------------------------------\n\n";
+ print "Select: \t$Param->{SelectCount} queries\n";
+ print "Update: \t$Param->{UpdateCount} queries\n";
+ print "\n";
+
+ print "Init: \t$Param->{Init} times\n";
+ print "Field: \t$Param->{Field} times\n";
+ print "Refresh: \t$Param->{Refresh} times\n";
+ print "Query: \t$Param->{QueryCount} times\n";
+ print "Statistics:\t$Param->{Statistics} times\n";
+ print "\n";
+
+ print "Logfile: \t$Param->{LineCount} lines\n";
+ print "Started: \t".localtime($Param->{Start})."\n";
+ print "Finished: \t".localtime(time)."\n";
+
+ }
+}
+
+
+###########################################################################
+#
+#
+#
+sub RunQuery {
+ my $Param = shift ;
+
+ if (defined $Param->{Query}) {
+ if (defined $Param->{DB} ) {
+
+ $Param->{Query} =~ m/from\s+(\w+[.]\w+|\w+)/i;
+ $Param->{tab} =$1;
+ #print "||$Param->{tab} -- $Param->{Query}\n";
+
+ my $sth=$Param->{dbh}->prepare("USE $Param->{DB}");
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ $sth->execute();
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ $sth->finish();
+
+ $sth=$Param->{dbh}->prepare($Param->{Query});
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ #print "$Param->{Query}\n";
+ $sth->execute();
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "[$Param->{LineCount}]<<$Param->{Query}>>\n";}
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ my $row = undef;
+ while ($row = $sth->fetchrow_hashref()) {
+ $Param->{SelectCount} ++;
+
+ if (defined $row->{Comment}) {
+ push (@{$Param->{Comment}}, "$row->{Comment}; $_; $Param->{DB}; $Param->{Query}");
+ }
+ foreach (@{$Param->{Rows}}) {
+ if (defined $row->{$_}) {
+ #if (($_ eq 'type' ) and ($row->{$_} eq 'ALL')) {
+ if ($row->{type} eq 'ALL') {
+ push (@{$Param->{ALL}}, "$Param->{Query}");
+ #print ">> $row->{$_} $_ $Param->{DB} $Param->{Query}\n";
+ }
+ $Param->{IdxUseCount} ++;
+ $Param->{Data}->{$Param->{tab}}->{$_}->{$row->{$_}} ++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ $sth->finish();
+ }
+ $Param->{Query} = undef ;
+ }
+}
+
+###########################################################################
+#
+#
+#
+sub ShowOptions {
+ print <<EOF;
+Usage: $0 [OPTIONS] < LOGFILE
+
+--date=YYMMDD select only entrys of date
+-d=YYMMDD
+--host=HOSTNAME db-host to ask
+-h=HOSTNAME
+--user=USERNAME db-user
+-u=USERNAME
+--password=PASSWORD password of db-user
+-p=PASSWORD
+
+Read logfile from STDIN an try to EXPLAIN all SELECT statements. All UPDATE statements are rewritten to an EXPLAIN SELECT statement. The results of the EXPLAIN statement are collected and counted. All results with type=ALL are collected in an separete list. Results are printed to STDOUT.
+
+EOF
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+explain_log.pl
+
+Feed a mysqld general logfile (created with mysqld --log) back into mysql
+and collect statistics about index usage with EXPLAIN.
+
+=head1 DISCUSSION
+
+To optimize your indices, you have to know which ones are actually
+used and what kind of queries are causing table scans. Especially
+if you are generating your queries dynamically and you have a huge
+amount of queries going on, this isn't easy.
+
+Use this tool to take a look at the effects of your real life queries.
+Then add indices to avoid table scans and remove those which aren't used.
+
+=head1 USAGE
+
+explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] < logfile
+
+--date=YYMMDD select only entrys of date
+
+-d=YYMMDD
+
+--host=HOSTNAME db-host to ask
+
+-h=HOSTNAME
+
+--user=USERNAME db-user
+
+-u=USERNAME
+
+--password=PASSWORD password of db-user
+
+-p=PASSWORD
+
+=head1 EXAMPLE
+
+explain_log.pl --host=localhost --user=foo --password=bar < /var/lib/mysql/mobile.log
+
+=head1 AUTHOR
+
+ Stefan Nitz
+ Jan Willamowius <jan@mobile.de>, http://www.mobile.de
+
+=head1 RECRUITING
+
+If you are looking for a MySQL or Perl job, take a look at http://www.mobile.de
+and send me an email with your resume (you must be speaking German!).
+
+=head1 SEE ALSO
+
+mysql documentation
+
+=cut
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index 99eb9e42967..44dc9d44322 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -66,9 +66,12 @@ for i in extra/comp_err extra/replace extra/perror extra/resolveip \
myisam/myisampack sql/mysqld client/mysqlbinlog \
client/mysql sql/mysqld client/mysqlshow client/mysqlcheck \
client/mysqladmin client/mysqldump client/mysqlimport client/mysqltest \
+ client/mysqlmanagerc client/mysqlmanager-pwgen tools/mysqlmanager \
client/.libs/mysql client/.libs/mysqlshow client/.libs/mysqladmin \
client/.libs/mysqldump client/.libs/mysqlimport client/.libs/mysqltest \
- client/.libs/mysqlcheck client/.libs/mysqlbinlog
+ client/.libs/mysqlcheck client/.libs/mysqlbinlog \
+ client/.libs/mysqlmanagerc client/.libs/mysqlmanager-pwgen \
+ tools/.libs/mysqlmanager
do
if [ -f $i ]
then
@@ -88,7 +91,7 @@ do
fi
done
-for i in libmysql/.libs/libmysqlclient.a libmysql/.libs/libmysqlclient.so* libmysql/libmysqlclient.* libmysql_r/.libs/libmysqlclient_r.a libmysql_r/.libs/libmysqlclient_r.so* libmysql_r/libmysqlclient_r.* mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a $BASE/lib
+for i in libmysql/.libs/libmysqlclient.a libmysql/.libs/libmysqlclient.so* libmysql/libmysqlclient.* libmysql_r/.libs/libmysqlclient_r.a libmysql_r/.libs/libmysqlclient_r.so* libmysql_r/libmysqlclient_r.* mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a libmysqld/.libs/libmysqld.a libmysqld/.libs/libmysqld.so* libmysqld/libmysqld.a
do
if [ -f $i ]
then
@@ -118,7 +121,7 @@ rm -f $BASE/bin/Makefile* $BASE/bin/*.in $BASE/bin/*.sh $BASE/bin/mysql_install_
$BASE/bin/replace \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/scripts/mysql_install_db.sh > $BASE/scripts/mysql_install_db
$BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \@MYSQLD_USER\@ root \@localstatedir\@ /usr/local/mysql/data < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server
-$BASE/bin/replace /my/gnu/bin/hostname /bin/hostname -- $BASE/bin/safe_mysqld
+$BASE/bin/replace /my/gnu/bin/hostname /bin/hostname -- $BASE/bin/mysqld_safe
mv $BASE/support-files/binary-configure $BASE/configure
chmod a+x $BASE/bin/* $BASE/scripts/* $BASE/support-files/mysql-* $BASE/configure
diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh
index 9320efdd2a1..6a31db9a2b3 100644
--- a/scripts/mysql_config.sh
+++ b/scripts/mysql_config.sh
@@ -87,16 +87,18 @@ client_libs='@CLIENT_LIBS@'
libs="$ldflags -L'$pkglibdir' -lmysqlclient $client_libs"
libs=`echo $libs | sed -e 's; +;;'`
cflags="-I'$pkgincludedir'"
+embedded_libs="$ldflags -L'$pkglibdir' -lmysqld @LIBS@ @innodb_system_libs@"
usage () {
cat <<EOF
Usage: $0 [OPTIONS]
Options:
- --cflags [$cflags]
- --libs [$libs]
- --socket [$socket]
- --port [$port]
- --version [$version]
+ --cflags [$cflags]
+ --libs [$libs]
+ --socket [$socket]
+ --port [$port]
+ --version [$version]
+ --libmysqld-libs [$embedded_libs]
EOF
exit 1
}
@@ -110,6 +112,7 @@ while test $# -gt 0; do
--socket) echo "$socket" ;;
--port) echo "$port" ;;
--version) echo "$version" ;;
+ --embedded-libs | --embedded | libmysqld-libs) echo "$embedded_libs" ;;
*) usage ;;
esac
diff --git a/scripts/mysql_explain_log.sh b/scripts/mysql_explain_log.sh
new file mode 100644
index 00000000000..d7f6bb97b40
--- /dev/null
+++ b/scripts/mysql_explain_log.sh
@@ -0,0 +1,383 @@
+#!@PERL@ -w
+use strict;
+use DBI;
+
+use Getopt::Long;
+$Getopt::Long::ignorecase=0;
+
+print "explain_log provided by http://www.mobile.de\n";
+print "=========== ================================\n";
+
+my $Param={};
+
+$Param->{host}='';
+$Param->{user}='';
+$Param->{password}='';
+$Param->{PrintError}=0;
+
+if (!GetOptions ('date|d:i' => \$Param->{ViewDate},
+ 'host|h:s' => \$Param->{host},
+ 'user|u:s' => \$Param->{user},
+ 'password|p:s' => \$Param->{password},
+ 'printerror|e:s' => \$Param->{PrintError},
+ )) {
+ ShowOptions();
+}
+else {
+ $Param->{UpdateCount} = 0;
+ $Param->{SelectCount} = 0;
+ $Param->{IdxUseCount} = 0;
+ $Param->{LineCount} = 0;
+
+ $Param->{Init} = 0;
+ $Param->{Field} = 0;
+ $Param->{Refresh} = 0;
+ $Param->{QueryCount} = 0;
+ $Param->{Statistics} =0;
+
+ $Param->{Query} = undef;
+ $Param->{ALL} = undef ;
+ $Param->{Comment} = undef ;
+
+ @{$Param->{Rows}} = (qw|possible_keys key type|);
+
+ if ($Param->{ViewDate}) {
+ $Param->{View} = 0;
+ }
+ else {
+ $Param->{View} = 1;
+ }
+
+ #print "Date=$Param->{ViewDate}, host=$Param->{host}, user=$Param->{user}, password=$Param->{password}\n";
+
+ $Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}",$Param->{user},$Param->{password},{PrintError=>0});
+ if (DBI::err()) {
+ print "Error: " . DBI::errstr() . "\n";
+ }
+ else {
+ $Param->{Start} = time;
+ while(<STDIN>) {
+ $Param->{LineCount} ++ ;
+
+ if ($Param->{ViewDate} ) {
+ if (m/^(\d{6})\s+\d{1,2}:\d\d:\d\d\s.*$/) { # get date
+ #print "# $1 #\n";
+ if ($1 == $Param->{ViewDate}) {
+ $Param->{View} = 1;
+ }
+ else {
+ $Param->{View} = 0;
+ }
+ }
+ }
+ if ($Param->{View} ) {
+ #print "->>>$_";
+
+ if (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
+ #print "C-$1--$2--$3------\n";
+ RunQuery($Param);
+ if (defined $3) {
+ $Param->{CID}->{$2} = $3 ;
+ #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+$/i) { # get connection ID($2) and database($3)
+ #print "\n <<<<<<<<<<<<<<<<<<----------------------------<<<<<<<<<<<<<<<< \n";
+ #print "Connect \n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Change user .*\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
+ #print "C-$1--$2--$3------\n";
+ RunQuery($Param);
+ if (defined $3) {
+ $Param->{CID}->{$2} = $3 ;
+ #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Quit\s+$/i) { # remove connection ID($2) and querystring
+ #print "Q-$1--$2--------\n";
+ RunQuery($Param);
+ delete $Param->{CID}->{$2} ;
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(select.+)$/i) { # get connection ID($2) and querystring
+ #print "S1-$1--$2--$3------\n";
+ RunQuery($Param);
+ unless ($Param->{CID}->{$2}) {
+ #print "Error: No Database for Handle: $2 found\n";
+ }
+ else {
+ $Param->{DB}=$Param->{CID}->{$2};
+
+ my $s = "$3";
+ $s =~ s/from\s/from $Param->{DB}./i;
+ $Param->{Query}="EXPLAIN $s";
+
+ #$s =~ m/from\s+(\w+[.]\w+)/i;
+ #$Param->{tab} =$1;
+ #print "-- $Param->{tab} -- $s --\n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(update.+)$/i) { # get connection ID($2) and querystring
+ #print "S2--$1--$2--$3------\n";
+ RunQuery($Param);
+ unless ($Param->{CID}->{$2}) {
+ #print "Error: No Database for Handle: $2 found\n";
+ }
+ else {
+ $Param->{DB}=$Param->{CID}->{$2};
+
+ my $ud = $3;
+ $ud =~ m/^update\s+(\w+).+(where.+)$/i;
+ $Param->{Query} ="EXPLAIN SELECT * FROM $1 $2";
+ $Param->{Query} =~ s/from\s/from $Param->{DB}./i;
+
+ #$Param->{Query} =~ m/from\s+(\w+[.]\w+)/i;
+ #$Param->{tab} =$1;
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Statistics\s+(.*)$/i) { # get connection ID($2) and info?
+ $Param->{Statistics} ++;
+ #print "Statistics--$1--$2--$3------\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(.+)$/i) { # get connection ID($2)
+ $Param->{QueryCount} ++;
+ #print "Query-NULL $3\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Refresh\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Refresh} ++;
+ #print "Refresh\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Init\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Init} ++;
+ #print "Init $3\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Field\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Field} ++;
+ #print "Field $3\n";
+ RunQuery($Param);
+ }
+
+ elsif (m/^\s+(.+)$/ ) { # command could be some lines ...
+ #print "multi-lined ($1)\n";
+ my ($A)=$1;
+ chomp $A;
+ $Param->{Query} .= " $1";
+ #print "multi-lined ($1)<<$Param->{Query}>>\n";
+ }
+
+
+ }
+
+ }
+
+ $Param->{dbh}->disconnect();
+
+ if (1 == 0) {
+ print "\nunclosed handles----------------------------------------\n";
+ my $count=0;
+ foreach (sort keys %{$Param->{CID}}) {
+ print "$count | $_ : $Param->{CID}->{$_} \n";
+ $count ++;
+ }
+ }
+
+ print "\nIndex usage ------------------------------------\n";
+ foreach my $t (sort keys %{$Param->{Data}}) {
+ print "\nTable\t$t: ---\n";
+ foreach my $k (sort keys %{$Param->{Data}->{$t}}) {
+ print " count\t$k:\n";
+ my %h = %{$Param->{Data}->{$t}->{$k}};
+ foreach (sort {$h{$a} <=> $h{$b}} keys %h) {
+ print " $Param->{Data}->{$t}->{$k}->{$_}\t$_\n";
+ }
+ }
+ }
+
+ $Param->{AllCount}=0;
+ print "\nQueries causing table scans -------------------\n\n";
+ foreach (@{$Param->{ALL}}) {
+ $Param->{AllCount} ++;
+ print "$_\n";
+ }
+ print "Sum: $Param->{AllCount} table scans\n";
+
+ print "\nSummary ---------------------------------------\n\n";
+ print "Select: \t$Param->{SelectCount} queries\n";
+ print "Update: \t$Param->{UpdateCount} queries\n";
+ print "\n";
+
+ print "Init: \t$Param->{Init} times\n";
+ print "Field: \t$Param->{Field} times\n";
+ print "Refresh: \t$Param->{Refresh} times\n";
+ print "Query: \t$Param->{QueryCount} times\n";
+ print "Statistics:\t$Param->{Statistics} times\n";
+ print "\n";
+
+ print "Logfile: \t$Param->{LineCount} lines\n";
+ print "Started: \t".localtime($Param->{Start})."\n";
+ print "Finished: \t".localtime(time)."\n";
+
+ }
+}
+
+
+###########################################################################
+#
+#
+#
+sub RunQuery {
+ my $Param = shift ;
+
+ if (defined $Param->{Query}) {
+ if (defined $Param->{DB} ) {
+
+ $Param->{Query} =~ m/from\s+(\w+[.]\w+|\w+)/i;
+ $Param->{tab} =$1;
+ #print "||$Param->{tab} -- $Param->{Query}\n";
+
+ my $sth=$Param->{dbh}->prepare("USE $Param->{DB}");
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ $sth->execute();
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ $sth->finish();
+
+ $sth=$Param->{dbh}->prepare($Param->{Query});
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ #print "$Param->{Query}\n";
+ $sth->execute();
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "[$Param->{LineCount}]<<$Param->{Query}>>\n";}
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ my $row = undef;
+ while ($row = $sth->fetchrow_hashref()) {
+ $Param->{SelectCount} ++;
+
+ if (defined $row->{Comment}) {
+ push (@{$Param->{Comment}}, "$row->{Comment}; $_; $Param->{DB}; $Param->{Query}");
+ }
+ foreach (@{$Param->{Rows}}) {
+ if (defined $row->{$_}) {
+ #if (($_ eq 'type' ) and ($row->{$_} eq 'ALL')) {
+ if ($row->{type} eq 'ALL') {
+ push (@{$Param->{ALL}}, "$row->{$_} $_ $Param->{DB} $Param->{Query}");
+ #print ">> $row->{$_} $_ $Param->{DB} $Param->{Query}\n";
+ }
+ $Param->{IdxUseCount} ++;
+ $Param->{Data}->{$Param->{tab}}->{$_}->{$row->{$_}} ++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ $sth->finish();
+ }
+ $Param->{Query} = undef ;
+ }
+}
+
+###########################################################################
+#
+#
+#
+sub ShowOptions {
+ print <<EOF;
+Usage: $0 [OPTIONS] < LOGFILE
+
+--date=YYMMDD select only entrys of date
+-d=YYMMDD
+--host=HOSTNAME db-host to ask
+-h=HOSTNAME
+--user=USERNAME db-user
+-u=USERNAME
+--password=PASSWORD password of db-user
+-p=PASSWORD
+
+Read logfile from STDIN an try to EXPLAIN all SELECT statements. All UPDATE statements are rewritten to an EXPLAIN SELECT statement. The results of the EXPLAIN statement are collected and counted. All results with type=ALL are collected in an separete list. Results are printed to STDOUT.
+
+EOF
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+explain_log.pl
+
+Feed a mysqld general logfile (created with mysqld --log) back into mysql
+and collect statistics about index usage with EXPLAIN.
+
+=head1 DISCUSSION
+
+To optimize your indices, you have to know which ones are actually
+used and what kind of queries are causing table scans. Especially
+if you are generating your queries dynamically and you have a huge
+amount of queries going on, this isn't easy.
+
+Use this tool to take a look at the effects of your real life queries.
+Then add indices to avoid table scans and remove those which aren't used.
+
+=head1 USAGE
+
+explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] < logfile
+
+--date=YYMMDD select only entrys of date
+
+-d=YYMMDD
+
+--host=HOSTNAME db-host to ask
+
+-h=HOSTNAME
+
+--user=USERNAME db-user
+
+-u=USERNAME
+
+--password=PASSWORD password of db-user
+
+-p=PASSWORD
+
+=head1 EXAMPLE
+
+explain_log.pl --host=localhost --user=foo --password=bar < /var/lib/mysql/mobile.log
+
+=head1 AUTHOR
+
+ Stefan Nitz
+ Jan Willamowius <jan@mobile.de>, http://www.mobile.de
+
+=head1 RECRUITING
+
+If you are looking for a MySQL or Perl job, take a look at http://www.mobile.de
+and send me an email with your resume (you must be speaking German!).
+
+=head1 SEE ALSO
+
+mysql documentation
+
+=cut
diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh
index 86312fdab52..a492066235b 100644
--- a/scripts/mysql_fix_privilege_tables.sh
+++ b/scripts/mysql_fix_privilege_tables.sh
@@ -12,6 +12,17 @@ echo "and give the MySQL root user password as a argument!"
root_password="$1"
host="localhost"
+echo "Converting all privilege tables to MyISAM format"
+@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+ALTER TABLE user type=MyISAM;
+ALTER TABLE db type=MyISAM;
+ALTER TABLE host type=MyISAM;
+ALTER TABLE func type=MyISAM;
+ALTER TABLE columns_priv type=MyISAM;
+ALTER TABLE tables_priv type=MyISAM;
+END_OF_DATA
+
+
# Fix old password format, add File_priv and func table
echo ""
echo "If your tables are already up to date or partially up to date you will"
@@ -57,6 +68,21 @@ END_OF_DATA
fi
#
+# The second alter changes ssl_type to new 4.0.2 format
+
+echo "Adding columns needed by GRANT .. REQUIRE (openssl)"
+echo "You can ignore any Duplicate column errors"
+@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+ALTER TABLE user
+ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL,
+ADD ssl_cipher BLOB NOT NULL,
+ADD x509_issuer BLOB NOT NULL,
+ADD x509_subject BLOB NOT NULL;
+ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL;
+END_OF_DATA
+echo ""
+
+#
# Create tables_priv and columns_priv if they don't exists
#
@@ -91,11 +117,12 @@ END_OF_DATA
#
echo "Changing name of columns_priv.Type -> columns_priv.Column_priv"
-echo "You can ignore any errors from this"
+echo "You can ignore any Unknown column errors from this"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL;
END_OF_DATA
+echo ""
#
# Add the new 'type' column to the func table.
@@ -107,3 +134,43 @@ echo "You can ignore any Duplicate column errors"
@bindir@/mysql --user=root --password=$root_password mysql <<EOF
alter table func add type enum ('function','aggregate') NOT NULL;
EOF
+echo ""
+
+#
+# Change the user table to MySQL 4.0 format
+#
+
+echo "Adding new fields used by MySQL 4.0.2 to the privilege tables"
+echo "You can ignore any Duplicate column errors"
+
+@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+alter table user
+add Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER alter_priv,
+add Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv,
+add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Super_priv,
+add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_tmp_table_priv,
+add Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv,
+add Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Execute_priv,
+add Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Repl_slave_priv;
+END_OF_DATA
+
+if test $? -eq "0"
+then
+ # Convert privileges so that users have similar privileges as before
+ echo ""
+ echo "Updating new privileges in MySQL 4.0.2 from old ones"
+ @bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+ update user set show_db_priv= select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv;
+END_OF_DATA
+ echo ""
+fi
+
+# Add fields that can be used to limit number of questions and connections
+# for some users.
+
+@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
+alter table user
+add max_questions int(11) NOT NULL AFTER x509_subject,
+add max_updates int(11) unsigned NOT NULL AFTER max_questions,
+add max_connections int(11) unsigned NOT NULL AFTER max_updates;
+END_OF_DATA
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 850432fecc7..6ac54256124 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 1997, 1998, 1999 TCX DataKonsult AB & Monty Program KB & Detron HB
+# Copyright (C) 2002 MySQL AB
# For a more info consult the file COPYRIGHT distributed with this file.
# This scripts creates the privilege tables db, host, user, tables_priv,
@@ -224,18 +224,32 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
+ c_u="$c_u ssl_cipher BLOB NOT NULL,"
+ c_u="$c_u x509_issuer BLOB NOT NULL,"
+ c_u="$c_u x509_subject BLOB NOT NULL,"
+ c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
c_u="$c_u PRIMARY KEY Host (Host,User)"
c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';"
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+ REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');
- INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');"
+ INSERT INTO user (host,user) values ('localhost','');
+ INSERT INTO user (host,user) values ('$hostname','');"
fi
if test ! -f $mdata/func.frm
@@ -290,7 +304,7 @@ fi
echo "Installing all prepared tables"
if eval "$execdir/mysqld $defaults --bootstrap --skip-grant-tables \
- --basedir=$basedir --datadir=$ldata --skip-innodb --skip-gemini --skip-bdb $args" << END_OF_DATA
+ --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $args" << END_OF_DATA
use mysql;
$c_d
$i_d
@@ -317,8 +331,8 @@ then
fi
echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !"
echo "This is done with:"
- echo "$bindir/mysqladmin -u root password 'new-password'"
- echo "$bindir/mysqladmin -u root -h $hostname password 'new-password'"
+ echo "$bindir/mysqladmin -u root password 'new-password'"
+ echo "$bindir/mysqladmin -u root -h $hostname password 'new-password'"
echo "See the manual for more instructions."
#
# Print message about upgrading unless we have created a new db table.
@@ -333,10 +347,10 @@ then
if test "$IN_RPM" -eq 0
then
echo "You can start the MySQL daemon with:"
- echo "cd @prefix@ ; $bindir/safe_mysqld &"
+ echo "cd @prefix@ ; $bindir/mysqld_safe &"
echo
echo "You can test the MySQL daemon with the benchmarks in the 'sql-bench' directory:"
- echo "cd sql-bench ; run-all-tests"
+ echo "cd sql-bench ; perl run-all-tests"
echo
fi
echo "Please report any problems with the @scriptdir@/mysqlbug script!"
diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh
new file mode 100644
index 00000000000..d6392c57731
--- /dev/null
+++ b/scripts/mysql_secure_installation.sh
@@ -0,0 +1,308 @@
+#!/bin/sh
+
+# Copyright (C) 2002 MySQL AB and Jeremy Cole
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+config=".my.cnf.$$"
+command=".mysql.$$"
+
+trap "interrupt" 2
+
+rootpass=""
+
+prepare() {
+ touch $config $command
+ chmod 600 $config $command
+}
+
+do_query() {
+ echo $1 >$command
+ mysql --defaults-file=$config <$command
+ return $?
+}
+
+make_config() {
+ echo "# mysql_secure_installation config file" >$config
+ echo "[mysql]" >>$config
+ echo "user=root" >>$config
+ echo "password=$rootpass" >>$config
+}
+
+get_root_password() {
+ status=1
+ while [ $status -eq 1 ]; do
+ stty -echo
+ echo -n "Enter current password for root (enter for none): "
+ read password
+ echo
+ stty echo
+ if [ "x$password" = "x" ]; then
+ hadpass=0
+ else
+ hadpass=1
+ fi
+ rootpass=$password
+ make_config
+ do_query ""
+ status=$?
+ done
+ echo "OK, successfully used password, moving on..."
+ echo
+}
+
+set_root_password() {
+ stty -echo
+ echo -n "New password: "
+ read password1
+ echo
+ echo -n "Re-enter new password: "
+ read password2
+ echo
+ stty echo
+
+ if [ "$password1" != "$password2" ]; then
+ echo "Sorry, passwords do not match."
+ echo
+ return 1
+ fi
+
+ if [ "$password1" = "" ]; then
+ echo "Sorry, you can't use an empty password here."
+ echo
+ return 1
+ fi
+
+ do_query "SET PASSWORD FOR root=PASSWORD('$password1');"
+ if [ $? -eq 0 ]; then
+ echo "Password updated successfully!"
+ echo
+ rootpass=$password1
+ make_config
+ else
+ echo "Password update failed!"
+ exit 1
+ fi
+
+ return 0
+}
+
+remove_anonymous_users() {
+ do_query "DELETE FROM mysql.user WHERE User='';"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed!"
+ exit 1
+ fi
+
+ return 0
+}
+
+remove_remote_root() {
+ do_query "DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed!"
+ fi
+}
+
+remove_test_database() {
+ echo " - Dropping test database..."
+ do_query "DROP DATABASE test;"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed! Not critical, keep moving..."
+ fi
+
+ echo " - Removing privileges on test database..."
+ do_query "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed! Not critical, keep moving..."
+ fi
+
+ return 0
+}
+
+reload_privilege_tables() {
+ do_query "FLUSH PRIVILEGES;"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed!"
+ fi
+
+ return 0
+}
+
+interrupt() {
+ echo
+ echo "Aborting!"
+ echo
+ cleanup
+ stty echo
+ exit 1
+}
+
+cleanup() {
+ echo "Cleaning up..."
+ rm -f $config $command
+}
+
+
+# The actual script starts here
+
+prepare
+
+echo
+echo
+echo
+echo
+echo "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL"
+echo " SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!"
+echo
+echo
+
+echo "In order to log into MySQL to secure it, we'll need the current"
+echo "password for the root user. If you've just installed MySQL, and"
+echo "you haven't set the root password yet, the password will be blank,"
+echo "so you should just press enter here."
+echo
+
+get_root_password
+
+
+#
+# Set the root password
+#
+
+echo "Setting the root password ensures that nobody can log into the MySQL"
+echo "root user without the proper authorisation."
+echo
+
+if [ $hadpass -eq 0 ]; then
+ echo -n "Set root password? [Y/n] "
+else
+ echo "You already have a root password set, so you can safely answer 'n'."
+ echo
+ echo -n "Change the root password? [Y/n] "
+fi
+
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ status=1
+ while [ $status -eq 1 ]; do
+ set_root_password
+ status=$?
+ done
+fi
+echo
+
+
+#
+# Remove anonymous users
+#
+
+echo "By default, a MySQL installation has an anonymous user, allowing anyone"
+echo "to log into MySQL without having to have a user account created for"
+echo "them. This is intended only for testing, and to make the installation"
+echo "go a bit smoother. You should remove them before moving into a"
+echo "production environment."
+echo
+
+echo -n "Remove anonymous users? [Y/n] "
+
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ remove_anonymous_users
+fi
+echo
+
+
+#
+# Disallow remote root login
+#
+
+echo "Normally, root should only be allowed to connect from 'localhost'. This"
+echo "ensures that someone cannot guess at the root password from the network."
+echo
+
+echo -n "Disallow root login remotely? [Y/n] "
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ remove_remote_root
+fi
+echo
+
+
+#
+# Remove test database
+#
+
+echo "By default, MySQL comes with a database named 'test' that anyone can"
+echo "access. This is also intended only for testing, and should be removed"
+echo "before moving into a production environment."
+echo
+
+echo -n "Remove test database and access to it? [Y/n] "
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ remove_test_database
+fi
+echo
+
+
+#
+# Reload privilege tables
+#
+
+echo "Reloading the privilege tables will ensure that all changes made so far"
+echo "will take effect immediately."
+echo
+
+echo -n "Reload privilege tables now? [Y/n] "
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ reload_privilege_tables
+fi
+echo
+
+cleanup
+
+echo
+echo
+echo
+echo "All done! If you've completed all of the above steps, your MySQL"
+echo "installation should now be secure."
+echo
+echo "Thanks for using MySQL!"
+echo
+echo
+
+
diff --git a/scripts/mysql_tableinfo.sh b/scripts/mysql_tableinfo.sh
new file mode 100644
index 00000000000..bfe9be377c7
--- /dev/null
+++ b/scripts/mysql_tableinfo.sh
@@ -0,0 +1,478 @@
+#!@PERL@ -w
+
+use strict;
+use Getopt::Long;
+use DBI;
+
+=head1 NAME
+
+mysql_tableinfo - creates and populates information tables with
+the output of SHOW DATABASES, SHOW TABLES (or SHOW TABLE STATUS),
+SHOW COLUMNS and SHOW INDEX.
+
+This is version 1.0.
+
+=head1 SYNOPSIS
+
+ mysql_tableinfo [OPTIONS] database_to_write [database_like_wild] [table_like_wild]
+
+ Do not backquote (``) database_to_write,
+ and do not quote ('') database_like_wild or table_like_wild
+
+ Examples:
+
+ mysql_tableinfo info
+
+ mysql_tableinfo info this_db
+
+ mysql_tableinfo info %a% b%
+
+ mysql_tableinfo info --clear-only
+
+ mysql_tableinfo info --col --idx --table-status
+
+=cut
+
+# Documentation continued at end of file
+
+
+sub usage {
+ die @_,"\nExecute 'perldoc $0' for documentation\n";
+}
+
+my %opt = (
+ 'user' => scalar getpwuid($>),
+ 'host' => "localhost",
+ 'prefix' => "", #to avoid 'use of uninitialized value...'
+);
+Getopt::Long::Configure(qw(no_ignore_case)); # disambuguate -p and -P
+GetOptions( \%opt,
+ "help",
+ "user|u=s",
+ "password|p=s",
+ "host|h=s",
+ "port|P=s",
+ "socket|S=s",
+ "tbl-status",
+ "col",
+ "idx",
+ "clear",
+ "clear-only",
+ "prefix=s",
+ "quiet|q",
+) or usage("Invalid option");
+
+if ($opt{help}) {usage();}
+
+my ($db_to_write,$db_like_wild,$tbl_like_wild);
+if (@ARGV==0)
+{
+ usage("Not enough arguments");
+}
+$db_to_write="`$ARGV[0]`"; shift @ARGV;
+$db_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV;
+$tbl_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV;
+if (@ARGV>0) { usage("Too many arguments"); }
+
+my $info_db="`".$opt{'prefix'}."db`";
+my $info_tbl="`".$opt{'prefix'}."tbl".
+ (($opt{'tbl-status'})?"_status":"")."`";
+my $info_col="`".$opt{'prefix'}."col`";
+my $info_idx="`".$opt{'prefix'}."idx`";
+
+
+# --- connect to the database ---
+
+my $dsn = ";host=$opt{'host'}";
+$dsn .= ";port=$opt{port}" if $opt{port};
+$dsn .= ";mysql_socket=$opt{socket}" if $opt{socket};
+
+my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=perl",
+ $opt{user}, $opt{password},
+{
+ RaiseError => 1,
+ PrintError => 0,
+ AutoCommit => 1,
+});
+
+$db_like_wild=$dbh->quote($db_like_wild);
+$tbl_like_wild=$dbh->quote($tbl_like_wild);
+
+#Ask
+
+if (!$opt{'quiet'})
+{
+ print "\n!! This program is doing to do:\n\n";
+ print "**DROP** TABLE ...\n" if ($opt{'clear'} or $opt{'clear-only'});
+ print "**DELETE** FROM ... WHERE `Database LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild
+**INSERT** INTO ...
+
+on the following tables :\n";
+ my $i;
+ foreach $i (($info_db, $info_tbl),
+ (($opt{'col'})?$info_col:()),
+ (($opt{'idx'})?$info_idx:()))
+ {
+ print(" $db_to_write.$i\n");
+ }
+ print "\nContinue (you can skip this confirmation step with --quiet) ? (y|n) [n]";
+ my $answer=<STDIN>;
+ unless ($answer =~ /^\s*y\s*$/i)
+ {
+ print "Nothing done!\n";exit;
+ }
+}
+
+if ($opt{'clear'} or $opt{'clear-only'})
+{
+#do not drop the $db_to_write database !
+ my $i;
+ foreach $i (($info_db, $info_tbl),
+ (($opt{'col'})?$info_col:()),
+ (($opt{'idx'})?$info_idx:()))
+ {
+ $dbh->do("DROP TABLE IF EXISTS $db_to_write.$i");
+ }
+ if ($opt{'clear-only'})
+ {
+ print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'});
+ exit();
+ }
+}
+
+
+my %sth;
+my %extra_col_desc;
+my %row;
+my %done_create_table;
+
+#create the $db_to_write database
+$dbh->do("CREATE DATABASE IF NOT EXISTS $db_to_write");
+$dbh->do("USE $db_to_write");
+
+#get databases
+$sth{db}=$dbh->prepare("SHOW DATABASES LIKE $db_like_wild");
+$sth{db}->execute;
+
+#create $info_db which will receive info about databases.
+#Ensure that the first column to be called "Database" (as SHOW DATABASES LIKE
+#returns a varying
+#column name (of the form "Database (%...)") which is not suitable)
+$extra_col_desc{db}=do_create_table("db",$info_db,undef,"`Database`");
+#we'll remember the type of the `Database` column (as returned by
+#SHOW DATABASES), which we will need when creating the next tables.
+
+#clear out-of-date info from this table
+$dbh->do("DELETE FROM $info_db WHERE `Database` LIKE $db_like_wild");
+
+
+while (@{$row{db}}=$sth{db}->fetchrow_array) #go through all databases
+{
+
+#insert the database name
+ $dbh->do("INSERT INTO $info_db VALUES("
+ .join_quote(@{$row{db}}).")");
+
+#for each database, get tables
+
+ $sth{tbl}=$dbh->prepare("SHOW TABLE"
+ .( ($opt{'tbl-status'}) ?
+ " STATUS"
+ : "S" )
+ ." from `${$row{db}}[0]` LIKE $tbl_like_wild");
+ $sth{tbl}->execute;
+ unless ($done_create_table{$info_tbl})
+
+#tables must be created only once, and out-of-date info must be
+#cleared once
+ {
+ $done_create_table{$info_tbl}=1;
+ $extra_col_desc{table}=
+ do_create_table("tbl",$info_tbl,
+#add an extra column (database name) at the left
+#and ensure that the table name will be called "Table"
+#(this is unncessesary with
+#SHOW TABLE STATUS, but necessary with SHOW TABLES (which returns a column
+#named "Tables_in_..."))
+ "`Database` ".$extra_col_desc{db},"`Table`");
+ $dbh->do("DELETE FROM $info_tbl WHERE `Database` LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild");
+ }
+
+ while (@{$row{tbl}}=$sth{tbl}->fetchrow_array)
+ {
+ $dbh->do("INSERT INTO $info_tbl VALUES("
+ .$dbh->quote(${$row{db}}[0]).",".join_quote(@{$row{tbl}}).")");
+
+#for each table, get columns...
+
+ if ($opt{'col'})
+ {
+ $sth{col}=$dbh->prepare("SHOW COLUMNS FROM `${$row{tbl}}[0]` FROM `${$row{db}}[0]`");
+ $sth{col}->execute;
+ unless ($done_create_table{$info_col})
+ {
+ $done_create_table{$info_col}=1;
+ do_create_table("col",$info_col,
+ "`Database` ".$extra_col_desc{db}.","
+ ."`Table` ".$extra_col_desc{table}.","
+ ."`Seq_in_table` BIGINT(3)");
+#We need to add a sequence number (1 for the first column of the table,
+#2 for the second etc) so that users are able to retrieve columns in order
+#if they want. This is not needed for INDEX
+#(where there is already Seq_in_index)
+ $dbh->do("DELETE FROM $info_col WHERE `Database`
+ LIKE $db_like_wild
+ AND `Table` LIKE $tbl_like_wild");
+ }
+ my $col_number=0;
+ while (@{$row{col}}=$sth{col}->fetchrow_array)
+ {
+ $dbh->do("INSERT INTO $info_col VALUES("
+ .$dbh->quote(${$row{db}}[0]).","
+ .$dbh->quote(${$row{tbl}}[0]).","
+ .++$col_number.","
+ .join_quote(@{$row{col}}).")");
+ }
+ }
+
+#and get index.
+
+ if ($opt{'idx'})
+ {
+ $sth{idx}=$dbh->prepare("SHOW INDEX FROM `${$row{tbl}}[0]` FROM `${$row{db}}[0]`");
+ $sth{idx}->execute;
+ unless ($done_create_table{$info_idx})
+ {
+ $done_create_table{$info_idx}=1;
+ do_create_table("idx",$info_idx,
+ "`Database` ".$extra_col_desc{db});
+ $dbh->do("DELETE FROM $info_idx WHERE `Database`
+ LIKE $db_like_wild
+ AND `Table` LIKE $tbl_like_wild");
+ }
+ while (@{$row{idx}}=$sth{idx}->fetchrow_array)
+ {
+ $dbh->do("INSERT INTO $info_idx VALUES("
+ .$dbh->quote(${$row{db}}[0]).","
+ .join_quote(@{$row{idx}}).")");
+ }
+ }
+ }
+}
+
+print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'});
+exit;
+
+sub join_quote
+{
+ my (@list)=@_; my $i;
+ foreach $i (@list) { $i=$dbh->quote($i); }
+ return (join ',',@list);
+}
+
+sub do_create_table
+{
+ my ($sth_key,$target_tbl,$extra_col_desc,$first_col_name)=@_;
+ my $create_table_query=$extra_col_desc;
+ my ($i,$type,$first_col_desc,$col_desc);
+
+ for ($i=0;$i<$sth{$sth_key}->{NUM_OF_FIELDS};$i++)
+ {
+ if ($create_table_query) { $create_table_query.=", "; }
+ $type=$sth{$sth_key}->{mysql_type_name}->[$i];
+ $col_desc=$type;
+ if ($type =~ /char|int/i)
+ {
+ $col_desc.="($sth{$sth_key}->{PRECISION}->[$i])";
+ }
+ elsif ($type =~ /decimal|numeric/i) #(never seen that)
+ {
+ $col_desc.=
+ "($sth{$sth_key}->{PRECISION}->[$i],$sth{$sth_key}->{SCALE}->[$i])";
+ }
+ elsif ($type !~ /date/i) #date and datetime are OK,
+ #no precision or scale for them
+ {
+ warn "unexpected column type '$type'
+(neither 'char','int','decimal|numeric')
+when creating $target_tbl, hope table creation will go OK\n";
+ }
+ if ($i==0) {$first_col_desc=$col_desc};
+ $create_table_query.=
+ ( ($i==0 and $first_col_name) ?
+ "$first_col_name " :"`$sth{$sth_key}->{NAME}->[$i]` " )
+ .$col_desc;
+ }
+if ($create_table_query)
+{
+ $dbh->do("CREATE TABLE IF NOT EXISTS $target_tbl ($create_table_query)");
+}
+return $first_col_desc;
+}
+
+__END__
+
+
+=head1 DESCRIPTION
+
+mysql_tableinfo asks a MySQL server information about its
+databases, tables, table columns and index, and stores this
+in tables called `db`, `tbl` (or `tbl_status`), `col`, `idx`
+(with an optional prefix specified with --prefix).
+After that, you can query these information tables, for example
+to build your admin scripts with SQL queries, like
+
+SELECT CONCAT("CHECK TABLE ",`database`,".",`table`," EXTENDED;")
+FROM info.tbl WHERE ... ;
+
+as people usually do with some other RDBMS
+(note: to increase the speed of your queries on the info tables,
+you may add some index on them).
+
+The database_like_wild and table_like_wild instructs the program
+to gather information only about databases and tables
+whose names match these patterns. If the info
+tables already exist, their rows matching the patterns are simply
+deleted and replaced by the new ones. That is,
+old rows not matching the patterns are not touched.
+If the database_like_wild and table_like_wild arguments
+are not specified on the command-line they default to "%".
+
+The program :
+
+- does CREATE DATABASE IF NOT EXISTS database_to_write
+where database_to_write is the database name specified on the command-line.
+
+- does CREATE TABLE IF NOT EXISTS database_to_write.`db`
+
+- fills database_to_write.`db` with the output of
+SHOW DATABASES LIKE database_like_wild
+
+- does CREATE TABLE IF NOT EXISTS database_to_write.`tbl`
+(respectively database_to_write.`tbl_status`
+if the --tbl-status option is on)
+
+- for every found database,
+fills database_to_write.`tbl` (respectively database_to_write.`tbl_status`)
+with the output of
+SHOW TABLES FROM found_db LIKE table_like_wild
+(respectively SHOW TABLE STATUS FROM found_db LIKE table_like_wild)
+
+- if the --col option is on,
+ * does CREATE TABLE IF NOT EXISTS database_to_write.`col`
+ * for every found table,
+ fills database_to_write.`col` with the output of
+ SHOW COLUMNS FROM found_tbl FROM found_db
+
+- if the --idx option is on,
+ * does CREATE TABLE IF NOT EXISTS database_to_write.`idx`
+ * for every found table,
+ fills database_to_write.`idx` with the output of
+ SHOW INDEX FROM found_tbl FROM found_db
+
+Some options may modify this general scheme (see below).
+
+As mentioned, the contents of the info tables are the output of
+SHOW commands. In fact the contents are slightly more complete :
+
+- the `tbl` (or `tbl_status`) info table
+ has an extra column which contains the database name,
+
+- the `col` info table
+ has an extra column which contains the table name,
+ and an extra column which contains, for each described column,
+ the number of this column in the table owning it (this extra column
+ is called `Seq_in_table`). `Seq_in_table` makes it possible for you
+ to retrieve your columns in sorted order, when you are querying
+ the `col` table.
+
+- the `index` info table
+ has an extra column which contains the database name.
+
+Caution: info tables contain certain columns (e.g.
+Database, Table, Null...) whose names, as they are MySQL reserved words,
+need to be backquoted (`...`) when used in SQL statements.
+
+=head1 OPTIONS
+
+=over 4
+
+=item --clear
+
+Does DROP TABLE on the info tables (only those that the program is
+going to fill, for example if you do not use --col it won't drop
+the `col` table) and processes normally. Does not drop database_to_write.
+
+=item --clear-only
+
+Same as --clear but exits after the DROPs.
+
+=item --col
+
+Adds columns information (into table `col`).
+
+=item --idx
+
+Adds index information (into table `idx`).
+
+=item --prefix prefix
+
+The info tables are named from the concatenation of prefix and,
+respectively, db, tbl (or tbl_status), col, idx. Do not quote ('')
+or backquote (``) prefix.
+
+=item -q, --quiet
+
+Does not warn you about what the script is going to do (DROP TABLE etc)
+and does not ask for a confirmation before starting.
+
+=item --tbl-status
+
+Instead of using SHOW TABLES, uses SHOW TABLE STATUS
+(much more complete information, but slower).
+
+=item --help
+
+Display helpscreen and exit
+
+=item -u, --user=#
+
+user for database login if not current user. Give a user
+who has sufficient privileges (CREATE, ...).
+
+=item -p, --password=#
+
+password to use when connecting to server
+
+=item -h, --host=#
+
+host to connect to
+
+=item -P, --port=#
+
+port to use when connecting to server
+
+=item -S, --socket=#
+
+UNIX domain socket to use when connecting to server
+
+=head1 WARRANTY
+
+This software is free and comes without warranty of any kind. You
+should never trust backup software without studying the code yourself.
+Study the code inside this script and only rely on it if I<you> believe
+that it does the right thing for you.
+
+Patches adding bug fixes, documentation and new features are welcome.
+
+=head1 TO DO
+
+Use extended inserts to be faster (for servers with many databases
+or tables). But to do that, must care about net-buffer-length.
+
+=head1 AUTHOR
+
+2002-06-18 Guilhem Bichot (guilhem.bichot@mines-paris.org)
+
+And all the authors of mysqlhotcopy, which served as a model for
+the structure of the program.
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 1adaa458271..83d12239472 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -4,7 +4,7 @@ use Getopt::Long;
use POSIX qw(strftime);
$|=1;
-$VER="2.2";
+$VER="2.3";
$opt_config_file = undef();
$opt_example = 0;
@@ -183,7 +183,7 @@ sub report_mysqlds
sub start_mysqlds()
{
- my (@groups, $com, $i, @options, $j);
+ my (@groups, $com, $tmp, $i, @options, $j);
if (!$opt_no_log)
{
@@ -202,11 +202,20 @@ sub start_mysqlds()
@options = `$com`;
chop @options;
- $com = "$mysqld";
- for ($j = 0; defined($options[$j]); $j++)
+ $com= "$mysqld";
+ for ($j = 0, $tmp= ""; defined($options[$j]); $j++)
{
- $com.= " $options[$j]";
+ if ("--mysqld=" eq substr($options[$j], 0, 9))
+ {
+ $options[$j]=~ s/\-\-mysqld\=//;
+ $com= $options[$j];
+ }
+ else
+ {
+ $tmp.= " $options[$j]";
+ }
}
+ $com.= $tmp;
$com.= " >> $opt_log 2>&1" if (!$opt_no_log);
$com.= " &";
system($com);
@@ -457,12 +466,12 @@ sub example
# directory, that you have (just change the socket, -S=...)
# See more detailed information from chapter:
# '6 The MySQL Access Privilege System' from the MySQL manual.
-# 2.pid-file is very important, if you are using safe_mysqld to start mysqld
-# (e.g. --mysqld=safe_mysqld) Every mysqld should have it's own pid-file.
-# The advantage using safe_mysqld instead of mysqld directly here is, that
-# safe_mysqld 'guards' every mysqld process and will restart it, if mysqld
+# 2.pid-file is very important, if you are using mysqld_safe to start mysqld
+# (e.g. --mysqld=mysqld_safe) Every mysqld should have it's own pid-file.
+# The advantage using mysqld_safe instead of mysqld directly here is, that
+# mysqld_safe 'guards' every mysqld process and will restart it, if mysqld
# process fails due to signal kill -9, or similar. (Like segmentation fault,
-# which MySQL should never do, of course ;) Please note that safe_mysqld
+# which MySQL should never do, of course ;) Please note that mysqld_safe
# script may require that you start it from a certain place. This means that
# you may have to CD to a certain directory, before you start the
# mysqld_multi. If you have problems starting, please see the script.
@@ -497,7 +506,7 @@ sub example
# give you extra performance in a threaded system!
#
[mysqld_multi]
-mysqld = @bindir@/safe_mysqld
+mysqld = @bindir@/mysqld_safe
mysqladmin = @bindir@/mysqladmin
user = multi_admin
password = multipass
@@ -591,10 +600,15 @@ Options:
Using: $opt_log
--mysqladmin=... mysqladmin binary to be used for a server shutdown.
Using: $mysqladmin
---mysqld=... mysqld binary to be used. Note that you can give safe_mysqld
+--mysqld=... mysqld binary to be used. Note that you can give mysqld_safe
to this option also. The options are passed to mysqld. Just
- make sure you have mysqld in your PATH or fix safe_mysqld.
+ make sure you have mysqld in your PATH or fix mysqld_safe.
Using: $mysqld
+ Please note: Since mysqld_multi version 2.3 you can also
+ give this option in groups [mysqld#]! This will be
+ recognized as a special option and will not be passed
+ to the mysqld. This will allow one to start different
+ mysqld versions with mysqld_multi.
--no-log Print to stdout instead of the log file. By default the log
file is turned on.
--password=... Password for user for mysqladmin.
diff --git a/scripts/mysqld_safe-watch.sh b/scripts/mysqld_safe-watch.sh
new file mode 100644
index 00000000000..c59b3b2614d
--- /dev/null
+++ b/scripts/mysqld_safe-watch.sh
@@ -0,0 +1,150 @@
+#!/bin/sh
+# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
+# This file is public domain and comes with NO WARRANTY of any kind
+#
+# scripts to start the MySQL demon and restart it if it dies unexpectedly
+#
+# This should be executed in the MySQL base directory if you are using a
+# binary installation that has other paths than you are using.
+#
+# mysql.server works by first doing a cd to the base directory and from there
+# executing mysqld_safe
+
+# Check if we are starting this relative (for the binary release)
+if test -f ./data/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./bin/mysqld
+then
+ MY_BASEDIR_VERSION=`pwd` # Where bin, share and data is
+ DATADIR=$MY_BASEDIR_VERSION/data # Where the databases are
+ ledir=$MY_BASEDIR_VERSION/bin # Where mysqld are
+# Check if this is a 'moved install directory'
+elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./libexec/mysqld
+then
+ MY_BASEDIR_VERSION=`pwd` # Where libexec, share and var is
+ DATADIR=$MY_BASEDIR_VERSION/var # Where the databases are
+ ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld are
+else
+ MY_BASEDIR_VERSION=/usr/local/mysql
+ DATADIR=/usr/local/mysql/var
+ ledir=/usr/local/mysql/libexec
+fi
+
+hostname=`@HOSTNAME@`
+pidfile=$DATADIR/$hostname.pid
+log=$DATADIR/$hostname.log
+err=$DATADIR/$hostname.err
+lockfile=$DATADIR/$hostname.lock
+
+#
+# If there exists an old pid file, check if the demon is already running
+# Note: The switches to 'ps' may depend on your operating system
+
+if test -f $pidfile
+then
+ PID=`cat $pidfile`
+ if /bin/kill -0 $PID
+ then
+ if /bin/ps -p $PID | grep mysqld > /dev/null
+ then # The pid contains a mysqld process
+ echo "A mysqld process already exists"
+ echo "A mysqld process already exists at " `date` >> $log
+ exit 1;
+ fi
+ fi
+ rm -f $pidfile
+ if test -f $pidfile
+ then
+ echo "Fatal error: Can't remove the pid file: $pidfile"
+ echo "Fatal error: Can't remove the pid file: $pidfile at " `date` >> $log
+ echo "Please remove it manually and start $0 again"
+ echo "mysqld demon not started"
+ exit 1;
+ fi
+fi
+
+echo "Starting mysqld demon with databases from $DATADIR"
+
+#Default communication ports
+#MYSQL_TCP_PORT=3306
+if test -z "$MYSQL_UNIX_PORT"
+then
+ MYSQL_UNIX_PORT="/tmp/mysql.sock"
+ export MYSQL_UNIX_PORT
+fi
+#export MYSQL_TCP_PORT
+
+# Does this work on all systems?
+#if type ulimit | grep "shell builtin" > /dev/null
+#then
+# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
+#fi
+
+echo "mysqld started on " `date` >> $log
+bin/zap -f $lockfile < /dev/null > /dev/null 2>&1
+rm -f $lockfile
+$MY_BASEDIR_VERSION/bin/watchdog_mysqld $lockfile $pidfile $MY_BASEDIR_VERSION/bin $DATADIR 3 10 >> $err 2>&1 &
+restart_pid=$!
+
+while true
+do
+ rm -f $MYSQL_UNIX_PORT $pidfile # Some extra safety
+ lockfile -1 -r10 $lockfile >/dev/null 2>&1
+ if test "$#" -eq 0
+ then
+ nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
+ --skip-locking >> $err 2>&1 &
+ else
+ nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
+ --skip-locking "$@" >> $err 2>&1 &
+ fi
+ pid=$!
+ rm -f $lockfile
+ wait $pid;
+
+ lockfile -1 -r10 $lockfile >/dev/null 2>&1
+ rm -f $lockfile
+ if test ! -f $pidfile # This is removed if normal shutdown
+ then
+ break;
+ fi
+ if true
+ then
+ # Test if one proces was hanging.
+ # This is only a fix for Linux (running as base 3 mysqld processes)
+ # but should work for the rest of the servers.
+ # The only thing is ps x => redhat 5 gives warnings when using ps -x.
+ # kill -9 is used or the proces won't react on the kill.
+ numofproces=`ps x | grep -v "grep" | grep -c $ledir/mysqld`
+ echo -e "\nNumber of processes running now: $numofproces" | tee -a $log
+ I=1
+ while test "$I" -le "$numofproces"
+ do
+ PROC=`ps x | grep $ledir/mysqld | grep -v "grep" | tail -1`
+ for T in $PROC
+ do
+ break
+ done
+ # echo "TEST $I - $T **"
+ if kill -9 $T
+ then
+ echo "mysqld proces hanging, pid $T - killed" | tee -a $log
+ else
+ break
+ fi
+ I=`expr $I + 1`
+ done
+ fi
+ echo "mysqld restarted" | tee -a $log
+ # Check all tables and repair any wrong tables.
+ $MY_BASEDIR_VERSION/bin/isamchk -sf $DATADIR/*/*.ISM >> $err 2>&1
+done
+if test $restart_pid -gt 0
+then
+ kill $restart_pid > /dev/null 2>&1
+ sleep 1;
+ kill -9 $restart_pid > /dev/null 2>&1
+fi
+
+echo -n "mysqld ended on " `date` >> $log
+echo "mysqld demon ended"
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
new file mode 100644
index 00000000000..e6ecbf6f729
--- /dev/null
+++ b/scripts/mysqld_safe.sh
@@ -0,0 +1,314 @@
+#!/bin/sh
+# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
+# This file is public domain and comes with NO WARRANTY of any kind
+#
+# scripts to start the MySQL daemon and restart it if it dies unexpectedly
+#
+# This should be executed in the MySQL base directory if you are using a
+# binary installation that has other paths than you are using.
+#
+# mysql.server works by first doing a cd to the base directory and from there
+# executing mysqld_safe
+
+trap '' 1 2 3 15 # we shouldn't let anyone kill us
+
+defaults=
+case "$1" in
+ --no-defaults|--defaults-file=*|--defaults-extra-file=*)
+ defaults="$1"; shift
+ ;;
+esac
+
+parse_arguments() {
+ # We only need to pass arguments through to the server if we don't
+ # handle them here. So, we collect unrecognized options (passed on
+ # the command line) into the args variable.
+ pick_args=
+ if test "$1" = PICK-ARGS-FROM-ARGV
+ then
+ pick_args=1
+ shift
+ fi
+
+ for arg do
+ case "$arg" in
+ # these get passed explicitly to mysqld
+ --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;;
+ --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--datadir=;;"` ;;
+ --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;;
+ --user=*) user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 ;;
+
+ # these two might have been set in a [mysqld_safe] section of my.cnf
+ # they get passed via environment variables to mysqld_safe
+ --socket=*) MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--socket=;;"` ;;
+ --port=*) MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--port=;;"` ;;
+
+ # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])!
+ --ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
+ --err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
+ # QQ The --open-files should be removed
+ --open-files=*) open_files=`echo "$arg" | sed -e "s;--open-files=;;"` ;;
+ --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--open-files-limit=;;"` ;;
+ --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--core_file_size=;;"` ;;
+ --timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;;
+ --mysqld=*) MYSQLD=`echo "$arg" | sed -e "s;--mysqld=;;"` ;;
+ --mysqld-version=*)
+ tmp=`echo "$arg" | sed -e "s;--mysqld-version=;;"`
+ if test -n "$tmp"
+ then
+ MYSQLD="mysqld-$tmp"
+ else
+ MYSQLD="mysqld"
+ fi
+ ;;
+ *)
+ if test -n "$pick_args"
+ then
+ # This sed command makes sure that any special chars are quoted,
+ # so the arg gets passed exactly to the server.
+ args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
+ fi
+ ;;
+ esac
+ done
+}
+
+MY_PWD=`pwd`
+# Check if we are starting this relative (for the binary release)
+if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./bin/mysqld
+then
+ MY_BASEDIR_VERSION=$MY_PWD # Where bin, share and data are
+ ledir=$MY_BASEDIR_VERSION/bin # Where mysqld is
+ DATADIR=$MY_BASEDIR_VERSION/data
+ if test -z "$defaults"
+ then
+ defaults="--defaults-extra-file=$MY_BASEDIR_VERSION/data/my.cnf"
+ fi
+# Check if this is a 'moved install directory'
+elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./libexec/mysqld
+then
+ MY_BASEDIR_VERSION=$MY_PWD # Where libexec, share and var are
+ ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld is
+ DATADIR=$MY_BASEDIR_VERSION/var
+else
+ MY_BASEDIR_VERSION=@prefix@
+ DATADIR=@localstatedir@
+ ledir=@libexecdir@
+fi
+
+MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}
+MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@}
+user=@MYSQLD_USER@
+
+# Use the mysqld-max binary by default if the user doesn't specify a binary
+if test -x $ledir/mysqld-max
+then
+ MYSQLD=mysqld-max
+else
+ MYSQLD=mysqld
+fi
+
+# these rely on $DATADIR by default, so we'll set them later on
+pid_file=
+err_log=
+SET_USER=0
+
+# Get first arguments from the my.cnf file, groups [mysqld] and [mysqld_safe]
+# and then merge with the command line arguments
+if test -x ./bin/my_print_defaults
+then
+ print_defaults="./bin/my_print_defaults"
+elif test -x @bindir@/my_print_defaults
+then
+ print_defaults="@bindir@/my_print_defaults"
+elif test -x @bindir@/mysql_print_defaults
+then
+ print_defaults="@bindir@/mysql_print_defaults"
+else
+ print_defaults="my_print_defaults"
+fi
+
+args=
+parse_arguments `$print_defaults $defaults mysqld server mysqld_safe safe_mysqld`
+parse_arguments PICK-ARGS-FROM-ARGV "$@"
+
+if test ! -x $ledir/$MYSQLD
+then
+ echo "The file $ledir/$MYSQLD doesn't exist or is not executable"
+ echo "Please do a cd to the mysql installation directory and restart"
+ echo "this script from there as follows:"
+ echo "./bin/mysqld_safe".
+ exit 1
+fi
+
+if test -z "$pid_file"
+then
+ pid_file=$DATADIR/`@HOSTNAME@`.pid
+else
+ case "$pid_file" in
+ /* ) ;;
+ * ) pid_file="$DATADIR/$pid_file" ;;
+ esac
+fi
+test -z "$err_log" && err_log=$DATADIR/`@HOSTNAME@`.err
+
+export MYSQL_UNIX_PORT
+export MYSQL_TCP_PORT
+
+
+NOHUP_NICENESS="nohup"
+
+# Using nice with no args to get the niceness level is GNU-specific.
+# This check could be extended for other operating systems (e.g.,
+# BSD could use "nohup sh -c 'ps -o nice -p $$' | tail -1").
+# But, it also seems that GNU nohup is the only one which messes
+# with the priority, so this is okay.
+if nohup nice > /dev/null 2>&1
+then
+ normal_niceness=`nice`
+ nohup_niceness=`nohup nice`
+
+ numeric_nice_values=1
+ for val in $normal_niceness $nohup_niceness
+ do
+ case "$val" in
+ -[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | \
+ [0-9] | [0-9][0-9] | [0-9][0-9][0-9] )
+ ;;
+ * )
+ numeric_nice_values=0 ;;
+ esac
+ done
+
+ if test $numeric_nice_values -eq 1
+ then
+ nice_value_diff=`expr $nohup_niceness - $normal_niceness`
+ if test $? -eq 0 && test $nice_value_diff -gt 0 && \
+ nice --$nice_value_diff echo testing > /dev/null 2>&1
+ then
+ # nohup increases the priority (bad), and we are permitted
+ # to lower the priority
+ NOHUP_NICENESS="nice --$nice_value_diff nohup"
+ fi
+ fi
+else
+ if nohup echo testing > /dev/null 2>&1
+ then
+ :
+ else
+ # nohup doesn't work on this system
+ NOHUP_NICENESS=""
+ fi
+fi
+
+USER_OPTION=""
+if test -w /
+then
+ if test "$user" != "root" -o $SET_USER = 1
+ then
+ USER_OPTION="--user=$user"
+ fi
+ # If we are root, change the err log to the right user.
+ touch $err_log; chown $user $err_log
+ if test -n "$open_files"
+ then
+ ulimit -n $open_files
+ fi
+ if test -n "$core_file_size"
+ then
+ ulimit -c $core_file_size
+ fi
+fi
+
+#
+# If there exists an old pid file, check if the daemon is already running
+# Note: The switches to 'ps' may depend on your operating system
+if test -f $pid_file
+then
+ PID=`cat $pid_file`
+ if @CHECK_PID@
+ then
+ if @FIND_PROC@
+ then # The pid contains a mysqld process
+ echo "A mysqld process already exists"
+ echo "A mysqld process already exists at " `date` >> $err_log
+ exit 1
+ fi
+ fi
+ rm -f $pid_file
+ if test -f $pid_file
+ then
+ echo "Fatal error: Can't remove the pid file: $pid_file"
+ echo "Fatal error: Can't remove the pid file: $pid_file at " `date` >> $err_log
+ echo "Please remove it manually and start $0 again"
+ echo "mysqld daemon not started"
+ exit 1
+ fi
+fi
+
+#
+# Uncomment the following lines if you want all tables to be automaticly
+# checked and repaired at start
+#
+# echo "Checking tables in $DATADIR"
+# $MY_BASEDIR_VERSION/bin/myisamchk --silent --force --fast --medium-check -O key_buffer=64M -O sort_buffer=64M $DATADIR/*/*.MYI
+# $MY_BASEDIR_VERSION/bin/isamchk --silent --force -O sort_buffer=64M $DATADIR/*/*.ISM
+
+echo "Starting $MYSQLD daemon with databases from $DATADIR"
+
+# Does this work on all systems?
+#if type ulimit | grep "shell builtin" > /dev/null
+#then
+# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
+#fi
+
+echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log
+while true
+do
+ rm -f $MYSQL_UNIX_PORT $pid_file # Some extra safety
+ if test -z "$args"
+ then
+ $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1
+ else
+ eval "$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ $args >> $err_log 2>&1"
+ fi
+ if test ! -f $pid_file # This is removed if normal shutdown
+ then
+ break
+ fi
+
+ if @IS_LINUX@
+ then
+ # Test if one process was hanging.
+ # This is only a fix for Linux (running as base 3 mysqld processes)
+ # but should work for the rest of the servers.
+ # The only thing is ps x => redhat 5 gives warnings when using ps -x.
+ # kill -9 is used or the process won't react on the kill.
+ numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD`
+ echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log
+ I=1
+ while test "$I" -le "$numofproces"
+ do
+ PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | sed -n '$p'`
+ for T in $PROC
+ do
+ break
+ done
+ # echo "TEST $I - $T **"
+ if kill -9 $T
+ then
+ echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
+ else
+ break
+ fi
+ I=`expr $I + 1`
+ done
+ fi
+
+ echo "`date +'%y%m%d %H:%M:%S mysqld restarted'`" | tee -a $err_log
+done
+
+echo "`date +'%y%m%d %H:%M:%S mysqld ended'`" | tee -a $err_log
+echo "" | tee -a $err_log
diff --git a/scripts/safe_mysqld-watch.sh b/scripts/safe_mysqld-watch.sh
deleted file mode 100644
index 30f95fd7a86..00000000000
--- a/scripts/safe_mysqld-watch.sh
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/sh
-# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
-# This file is public domain and comes with NO WARRANTY of any kind
-#
-# scripts to start the MySQL demon and restart it if it dies unexpectedly
-#
-# This should be executed in the MySQL base directory if you are using a
-# binary installation that has other paths than you are using.
-#
-# mysql.server works by first doing a cd to the base directory and from there
-# executing safe_mysqld
-
-# Check if we are starting this relative (for the binary release)
-if test -f ./data/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./bin/mysqld
-then
- MY_BASEDIR_VERSION=`pwd` # Where bin, share and data is
- DATADIR=$MY_BASEDIR_VERSION/data # Where the databases are
- ledir=$MY_BASEDIR_VERSION/bin # Where mysqld are
-# Check if this is a 'moved install directory'
-elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./libexec/mysqld
-then
- MY_BASEDIR_VERSION=`pwd` # Where libexec, share and var is
- DATADIR=$MY_BASEDIR_VERSION/var # Where the databases are
- ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld are
-else
- MY_BASEDIR_VERSION=/usr/local/mysql
- DATADIR=/usr/local/mysql/var
- ledir=/usr/local/mysql/libexec
-fi
-
-hostname=`@HOSTNAME@`
-pidfile=$DATADIR/$hostname.pid
-log=$DATADIR/$hostname.log
-err=$DATADIR/$hostname.err
-lockfile=$DATADIR/$hostname.lock
-
-#
-# If there exists an old pid file, check if the demon is already running
-# Note: The switches to 'ps' may depend on your operating system
-
-if test -f $pidfile
-then
- PID=`cat $pidfile`
- if /bin/kill -0 $PID
- then
- if /bin/ps -p $PID | grep mysqld > /dev/null
- then # The pid contains a mysqld process
- echo "A mysqld process already exists"
- echo "A mysqld process already exists at " `date` >> $log
- exit 1;
- fi
- fi
- rm -f $pidfile
- if test -f $pidfile
- then
- echo "Fatal error: Can't remove the pid file: $pidfile"
- echo "Fatal error: Can't remove the pid file: $pidfile at " `date` >> $log
- echo "Please remove it manually and start $0 again"
- echo "mysqld demon not started"
- exit 1;
- fi
-fi
-
-echo "Starting mysqld demon with databases from $DATADIR"
-
-#Default communication ports
-#MYSQL_TCP_PORT=3306
-if test -z "$MYSQL_UNIX_PORT"
-then
- MYSQL_UNIX_PORT="/tmp/mysql.sock"
- export MYSQL_UNIX_PORT
-fi
-#export MYSQL_TCP_PORT
-
-# Does this work on all systems?
-#if type ulimit | grep "shell builtin" > /dev/null
-#then
-# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
-#fi
-
-echo "mysqld started on " `date` >> $log
-bin/zap -f $lockfile < /dev/null > /dev/null 2>&1
-rm -f $lockfile
-$MY_BASEDIR_VERSION/bin/watchdog_mysqld $lockfile $pidfile $MY_BASEDIR_VERSION/bin $DATADIR 3 10 >> $err 2>&1 &
-restart_pid=$!
-
-while true
-do
- rm -f $MYSQL_UNIX_PORT $pidfile # Some extra safety
- lockfile -1 -r10 $lockfile >/dev/null 2>&1
- if test "$#" -eq 0
- then
- nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
- --skip-locking >> $err 2>&1 &
- else
- nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
- --skip-locking "$@" >> $err 2>&1 &
- fi
- pid=$!
- rm -f $lockfile
- wait $pid;
-
- lockfile -1 -r10 $lockfile >/dev/null 2>&1
- rm -f $lockfile
- if test ! -f $pidfile # This is removed if normal shutdown
- then
- break;
- fi
- if true
- then
- # Test if one proces was hanging.
- # This is only a fix for Linux (running as base 3 mysqld processes)
- # but should work for the rest of the servers.
- # The only thing is ps x => redhat 5 gives warnings when using ps -x.
- # kill -9 is used or the proces won't react on the kill.
- numofproces=`ps x | grep -v "grep" | grep -c $ledir/mysqld`
- echo -e "\nNumber of processes running now: $numofproces" | tee -a $log
- I=1
- while test "$I" -le "$numofproces"
- do
- PROC=`ps x | grep $ledir/mysqld | grep -v "grep" | tail -1`
- for T in $PROC
- do
- break
- done
- # echo "TEST $I - $T **"
- if kill -9 $T
- then
- echo "mysqld proces hanging, pid $T - killed" | tee -a $log
- else
- break
- fi
- I=`expr $I + 1`
- done
- fi
- echo "mysqld restarted" | tee -a $log
- # Check all tables and repair any wrong tables.
- $MY_BASEDIR_VERSION/bin/isamchk -sf $DATADIR/*/*.ISM >> $err 2>&1
-done
-if test $restart_pid -gt 0
-then
- kill $restart_pid > /dev/null 2>&1
- sleep 1;
- kill -9 $restart_pid > /dev/null 2>&1
-fi
-
-echo -n "mysqld ended on " `date` >> $log
-echo "mysqld demon ended"
diff --git a/scripts/safe_mysqld.sh b/scripts/safe_mysqld.sh
deleted file mode 100644
index 3494e3d707e..00000000000
--- a/scripts/safe_mysqld.sh
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/bin/sh
-# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
-# This file is public domain and comes with NO WARRANTY of any kind
-#
-# scripts to start the MySQL daemon and restart it if it dies unexpectedly
-#
-# This should be executed in the MySQL base directory if you are using a
-# binary installation that has other paths than you are using.
-#
-# mysql.server works by first doing a cd to the base directory and from there
-# executing safe_mysqld
-
-trap '' 1 2 3 15 # we shouldn't let anyone kill us
-
-defaults=
-case "$1" in
- --no-defaults|--defaults-file=*|--defaults-extra-file=*)
- defaults="$1"; shift
- ;;
-esac
-
-parse_arguments() {
- # We only need to pass arguments through to the server if we don't
- # handle them here. So, we collect unrecognized options (passed on
- # the command line) into the args variable.
- pick_args=$1; shift
-
- for arg do
- case "$arg" in
- # these get passed explicitly to mysqld
- --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --user=*) user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 ;;
-
- # these two might have been set in a [safe_mysqld] section of my.cnf
- # they get passed via environment variables to safe_mysqld
- --socket=*) MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --port=*) MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
-
- # safe_mysqld-specific options
- --ledir=*) ledir=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --err-log=*) err_log=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- # QQ The --open-files should be removed
- --open-files=*) open_files=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --timezone=*) TZ=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; export TZ; ;;
- --mysqld=*) MYSQLD=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --mysqld-version=*)
- tmp=`echo "$arg" | sed -e "s;--[^=]*=;;"`
- if test -n "$tmp"
- then
- MYSQLD="mysqld-$tmp"
- else
- MYSQLD="mysqld"
- fi
- ;;
- *)
- if test $pick_args -eq 1
- then
- # This sed command makes sure that any special chars are quoted,
- # so the arg gets passed exactly to the server.
- args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
- fi
- ;;
- esac
- done
-}
-
-MY_PWD=`pwd`
-# Check if we are starting this relative (for the binary release)
-if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./bin/mysqld
-then
- MY_BASEDIR_VERSION=$MY_PWD # Where bin, share and data are
- ledir=$MY_BASEDIR_VERSION/bin # Where mysqld is
- DATADIR=$MY_BASEDIR_VERSION/data
- if test -z "$defaults"
- then
- defaults="--defaults-extra-file=$MY_BASEDIR_VERSION/data/my.cnf"
- fi
-# Check if this is a 'moved install directory'
-elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./libexec/mysqld
-then
- MY_BASEDIR_VERSION=$MY_PWD # Where libexec, share and var are
- ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld is
- DATADIR=$MY_BASEDIR_VERSION/var
-else
- MY_BASEDIR_VERSION=@prefix@
- DATADIR=@localstatedir@
- ledir=@libexecdir@
-fi
-
-MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}
-MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@}
-user=@MYSQLD_USER@
-
-# Use the mysqld-max binary by default if the user doesn't specify a binary
-if test -x $ledir/mysqld-max
-then
- MYSQLD=mysqld-max
-else
- MYSQLD=mysqld
-fi
-
-# these rely on $DATADIR by default, so we'll set them later on
-pid_file=
-err_log=
-SET_USER=0
-
-# Get first arguments from the my.cnf file, groups [mysqld] and [safe_mysqld]
-# and then merge with the command line arguments
-if test -x ./bin/my_print_defaults
-then
- print_defaults="./bin/my_print_defaults"
-elif test -x @bindir@/my_print_defaults
-then
- print_defaults="@bindir@/my_print_defaults"
-elif test -x @bindir@/mysql_print_defaults
-then
- print_defaults="@bindir@/mysql_print_defaults"
-else
- print_defaults="my_print_defaults"
-fi
-
-args=
-parse_arguments 0 `$print_defaults $defaults mysqld server safe_mysqld`
-parse_arguments 1 "$@"
-
-if test ! -x $ledir/$MYSQLD
-then
- echo "The file $ledir/$MYSQLD doesn't exist or is not executable"
- echo "Please do a cd to the mysql installation directory and restart"
- echo "this script from there as follows:"
- echo "./bin/safe_mysqld".
- exit 1
-fi
-
-if test -z "$pid_file"
-then
- pid_file=$DATADIR/`@HOSTNAME@`.pid
-else
- case "$pid_file" in
- /* ) ;;
- * ) pid_file="$DATADIR/$pid_file" ;;
- esac
-fi
-test -z "$err_log" && err_log=$DATADIR/`@HOSTNAME@`.err
-
-export MYSQL_UNIX_PORT
-export MYSQL_TCP_PORT
-
-
-NOHUP_NICENESS="nohup"
-if test -w /
-then
- NOHUP_NICENESS=`nohup nice 2>&1`
- if test $? -eq 0 && test x"$NOHUP_NICENESS" != x0 && nice --1 echo foo > /dev/null 2>&1
- then
- NOHUP_NICENESS="nice --$NOHUP_NICENESS nohup"
- else
- NOHUP_NICENESS="nohup"
- fi
-fi
-
-USER_OPTION=""
-if test -w /
-then
- if test "$user" != "root" -o $SET_USER = 1
- then
- USER_OPTION="--user=$user"
- fi
- # If we are root, change the err log to the right user.
- touch $err_log; chown $user $err_log
- if test -n "$open_files"
- then
- ulimit -n $open_files
- fi
- if test -n "$core_file_size"
- then
- ulimit -c $core_file_size
- fi
-fi
-
-#
-# If there exists an old pid file, check if the daemon is already running
-# Note: The switches to 'ps' may depend on your operating system
-if test -f $pid_file
-then
- PID=`cat $pid_file`
- if @CHECK_PID@
- then
- if @FIND_PROC@
- then # The pid contains a mysqld process
- echo "A mysqld process already exists"
- echo "A mysqld process already exists at " `date` >> $err_log
- exit 1
- fi
- fi
- rm -f $pid_file
- if test -f $pid_file
- then
- echo "Fatal error: Can't remove the pid file: $pid_file"
- echo "Fatal error: Can't remove the pid file: $pid_file at " `date` >> $err_log
- echo "Please remove it manually and start $0 again"
- echo "mysqld daemon not started"
- exit 1
- fi
-fi
-
-#
-# Uncomment the following lines if you want all tables to be automaticly
-# checked and repaired at start
-#
-# echo "Checking tables in $DATADIR"
-# $MY_BASEDIR_VERSION/bin/myisamchk --silent --force --fast --medium-check -O key_buffer=64M -O sort_buffer=64M $DATADIR/*/*.MYI
-# $MY_BASEDIR_VERSION/bin/isamchk --silent --force -O sort_buffer=64M $DATADIR/*/*.ISM
-
-echo "Starting $MYSQLD daemon with databases from $DATADIR"
-
-# Does this work on all systems?
-#if type ulimit | grep "shell builtin" > /dev/null
-#then
-# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
-#fi
-
-echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log
-while true
-do
- rm -f $MYSQL_UNIX_PORT $pid_file # Some extra safety
- if test -z "$args"
- then
- $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1
- else
- eval "$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ $args >> $err_log 2>&1"
- fi
- if test ! -f $pid_file # This is removed if normal shutdown
- then
- break
- fi
-
- if @IS_LINUX@
- then
- # Test if one process was hanging.
- # This is only a fix for Linux (running as base 3 mysqld processes)
- # but should work for the rest of the servers.
- # The only thing is ps x => redhat 5 gives warnings when using ps -x.
- # kill -9 is used or the process won't react on the kill.
- numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD`
- echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log
- I=1
- while test "$I" -le "$numofproces"
- do
- PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | sed -n '$p'`
- for T in $PROC
- do
- break
- done
- # echo "TEST $I - $T **"
- if kill -9 $T
- then
- echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
- else
- break
- fi
- I=`expr $I + 1`
- done
- fi
-
- echo "`date +'%y%m%d %H:%M:%S mysqld restarted'`" | tee -a $err_log
-done
-
-echo "`date +'%y%m%d %H:%M:%S mysqld ended'`" | tee -a $err_log
-echo "" | tee -a $err_log
diff --git a/sql-bench/Comments/interbase b/sql-bench/Comments/interbase
new file mode 100644
index 00000000000..addaf74b63f
--- /dev/null
+++ b/sql-bench/Comments/interbase
@@ -0,0 +1,18 @@
+Running crash-me on Interbase:
+I
+- got opensource version of interbase 6.0.1
+ (both mode, classic and superserver),
+- set up DBD::InterBase from cpan,
+- created database "test" and set sql_dialect for that database to 3
+- executed crash-me for both interbase's models (classic and superserver).
+
+There were some problems during the execution:
+1) Sometimes client side got SIGSEGV , At that moment server side
+ writes
+ gds__alloc: non-positive size allocation request
+ to log file.
+ This problem has both models. I am not shure if it's interbase or
+ DBD:InterBase problem (though DBD::InterBase made all nesessary
+ tests during the installation without any problem)
+
+2) In "superserver" mode ibserver several times died (and ibguard restarted it)
diff --git a/sql-bench/Makefile.am b/sql-bench/Makefile.am
index 80806f35418..4bfa9868428 100644
--- a/sql-bench/Makefile.am
+++ b/sql-bench/Makefile.am
@@ -21,16 +21,18 @@ benchdir_root= $(prefix)
benchdir = $(benchdir_root)/sql-bench
bench_SCRIPTS = test-ATIS test-connect test-create test-insert \
test-big-tables test-select test-wisconsin \
- test-alter-table graph-compare-results \
+ test-alter-table test-transactions \
+ graph-compare-results \
bench-init.pl compare-results run-all-tests \
- server-cfg crash-me copy-db
+ server-cfg crash-me copy-db bench-count-distinct
CLEANFILES = $(bench_SCRIPTS)
EXTRA_SCRIPTS = test-ATIS.sh test-connect.sh test-create.sh \
test-insert.sh test-big-tables.sh test-select.sh \
test-alter-table.sh test-wisconsin.sh \
+ test-transactions.sh \
bench-init.pl.sh compare-results.sh server-cfg.sh \
run-all-tests.sh crash-me.sh copy-db.sh \
- graph-compare-results.sh
+ bench-count-distinct.sh graph-compare-results.sh
EXTRA_DIST = $(EXTRA_SCRIPTS)
dist-hook:
diff --git a/sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..2b0610da26f
--- /dev/null
+++ b/sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,20 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:34:53
+
+ATIS table test
+
+Creating tables
+Time for create_table (28): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Inserting data
+Time to insert (9768): 2 wallclock secs ( 0.44 usr 0.21 sys + 0.00 cusr 0.00 csys = 0.65 CPU)
+
+Retrieving data
+Time for select_simple_join (500): 2 wallclock secs ( 0.60 usr 0.19 sys + 0.00 cusr 0.00 csys = 0.79 CPU)
+Time for select_join (100): 1 wallclock secs ( 0.46 usr 0.14 sys + 0.00 cusr 0.00 csys = 0.60 CPU)
+Time for select_key_prefix_join (100): 10 wallclock secs ( 3.98 usr 1.52 sys + 0.00 cusr 0.00 csys = 5.50 CPU)
+Time for select_distinct (800): 9 wallclock secs ( 1.59 usr 0.55 sys + 0.00 cusr 0.00 csys = 2.14 CPU)
+Time for select_group (2800): 9 wallclock secs ( 1.34 usr 0.28 sys + 0.00 cusr 0.00 csys = 1.62 CPU)
+
+Removing tables
+Time to drop_table (28): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Total time: 33 wallclock secs ( 8.41 usr 2.89 sys + 0.00 cusr 0.00 csys = 11.30 CPU)
diff --git a/sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..6885ceddcf1
--- /dev/null
+++ b/sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,109 @@
+Benchmark DBD suite: 2.14
+Date of test: 2002-05-20 17:48:45
+Running tests on: Linux 2.4.16-64GB-SMP i686
+Arguments:
+Comments: Intel Xeon 2M cache, 4x700 Mhz, 2G, key_buffer=16M, gcc 3.1
+Limits from:
+Server version: MySQL 4.0.2 alpha
+Optimization: None
+Hardware:
+
+alter-table: Total time: 241 wallclock secs ( 0.17 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.24 CPU)
+ATIS: Total time: 33 wallclock secs ( 8.41 usr 2.89 sys + 0.00 cusr 0.00 csys = 11.30 CPU)
+big-tables: Total time: 27 wallclock secs ( 9.38 usr 5.17 sys + 0.00 cusr 0.00 csys = 14.55 CPU)
+connect: Total time: 156 wallclock secs (71.06 usr 31.02 sys + 0.00 cusr 0.00 csys = 102.08 CPU)
+create: Total time: 90 wallclock secs ( 5.77 usr 1.91 sys + 0.00 cusr 0.00 csys = 7.68 CPU)
+insert: Total time: 1730 wallclock secs (523.67 usr 128.19 sys + 0.00 cusr 0.00 csys = 651.86 CPU)
+select: Total time: 1106 wallclock secs (52.54 usr 11.75 sys + 0.00 cusr 0.00 csys = 64.29 CPU)
+transactions: Test skipped because the database doesn't support transactions
+wisconsin: Total time: 12 wallclock secs ( 3.07 usr 1.20 sys + 0.00 cusr 0.00 csys = 4.27 CPU)
+
+All 9 test executed successfully
+
+Totals per operation:
+Operation seconds usr sys cpu tests
+alter_table_add 134.00 0.12 0.03 0.15 992
+alter_table_drop 102.00 0.04 0.02 0.06 496
+connect 7.00 4.50 1.62 6.12 10000
+connect+select_1_row 10.00 5.09 2.31 7.40 10000
+connect+select_simple 9.00 5.19 2.02 7.21 10000
+count 33.00 0.04 0.00 0.04 100
+count_distinct 34.00 0.24 0.05 0.29 1000
+count_distinct_2 38.00 0.25 0.07 0.32 1000
+count_distinct_big 50.00 7.15 2.75 9.90 120
+count_distinct_group 47.00 1.00 0.27 1.27 1000
+count_distinct_group_on_key 43.00 0.26 0.05 0.31 1000
+count_distinct_group_on_key_parts 47.00 0.98 0.29 1.27 1000
+count_distinct_key_prefix 28.00 0.29 0.03 0.32 1000
+count_group_on_key_parts 43.00 0.96 0.31 1.27 1000
+count_on_key 416.00 11.73 1.70 13.43 50100
+create+drop 17.00 1.49 0.50 1.99 10000
+create_MANY_tables 25.00 1.12 0.28 1.40 10000
+create_index 3.00 0.00 0.00 0.00 8
+create_key+drop 23.00 1.84 0.62 2.46 10000
+create_table 0.00 0.00 0.00 0.00 31
+delete_all_many_keys 51.00 0.02 0.00 0.02 1
+delete_big 0.00 0.00 0.00 0.00 1
+delete_big_many_keys 51.00 0.02 0.00 0.02 128
+delete_key 2.00 0.39 0.26 0.65 10000
+delete_range 11.00 0.01 0.00 0.01 12
+drop_index 2.00 0.00 0.00 0.00 8
+drop_table 0.00 0.00 0.00 0.00 28
+drop_table_when_MANY_tables 11.00 0.34 0.17 0.51 10000
+insert 78.00 14.11 7.05 21.16 350768
+insert_duplicates 16.00 2.42 2.15 4.57 100000
+insert_key 86.00 7.22 2.27 9.49 100000
+insert_many_fields 7.00 0.19 0.07 0.26 2000
+insert_select_1_key 5.00 0.00 0.00 0.00 1
+insert_select_2_keys 6.00 0.00 0.00 0.00 1
+min_max 23.00 0.02 0.00 0.02 60
+min_max_on_key 159.00 19.21 2.78 21.99 85000
+multiple_value_insert 5.00 1.29 0.00 1.29 100000
+order_by_big 40.00 21.73 8.15 29.88 10
+order_by_big_key 33.00 23.12 7.93 31.05 10
+order_by_big_key2 31.00 21.98 7.84 29.82 10
+order_by_big_key_desc 32.00 23.13 8.16 31.29 10
+order_by_big_key_diff 39.00 22.07 7.71 29.78 10
+order_by_big_key_prefix 31.00 21.76 8.21 29.97 10
+order_by_key2_diff 4.00 2.00 0.58 2.58 500
+order_by_key_prefix 3.00 0.98 0.34 1.32 500
+order_by_range 3.00 0.81 0.41 1.22 500
+outer_join 48.00 0.01 0.00 0.01 10
+outer_join_found 46.00 0.01 0.00 0.01 10
+outer_join_not_found 31.00 0.00 0.00 0.00 500
+outer_join_on_key 40.00 0.00 0.00 0.00 10
+select_1_row 22.00 9.63 4.42 14.05 100000
+select_1_row_cache 19.00 6.75 3.55 10.30 100000
+select_2_rows 24.00 9.99 4.11 14.10 100000
+select_big 31.00 21.97 8.10 30.07 80
+select_big_str 13.00 5.10 3.32 8.42 10000
+select_cache 88.00 2.21 0.38 2.59 10000
+select_cache2 89.00 2.49 0.39 2.88 10000
+select_column+column 23.00 8.62 3.65 12.27 100000
+select_diff_key 138.00 0.12 0.02 0.14 500
+select_distinct 9.00 1.59 0.55 2.14 800
+select_group 51.00 1.40 0.29 1.69 2911
+select_group_when_MANY_tables 14.00 0.98 0.34 1.32 10000
+select_join 1.00 0.46 0.14 0.60 100
+select_key 82.00 51.17 8.13 59.30 200000
+select_key2 86.00 50.00 7.89 57.89 200000
+select_key2_return_key 81.00 48.57 6.51 55.08 200000
+select_key2_return_prim 83.00 49.27 7.43 56.70 200000
+select_key_prefix 87.00 51.79 8.42 60.21 200000
+select_key_prefix_join 10.00 3.98 1.52 5.50 100
+select_key_return_key 79.00 48.93 7.01 55.94 200000
+select_many_fields 19.00 9.18 5.10 14.28 2000
+select_range 103.00 8.73 2.95 11.68 410
+select_range_key2 12.00 4.65 0.92 5.57 25010
+select_range_prefix 13.00 5.01 0.99 6.00 25010
+select_simple 15.00 8.15 2.84 10.99 100000
+select_simple_cache 14.00 8.03 3.18 11.21 100000
+select_simple_join 2.00 0.60 0.19 0.79 500
+update_big 44.00 0.00 0.00 0.00 10
+update_of_key 14.00 1.80 0.94 2.74 50000
+update_of_key_big 20.00 0.01 0.01 0.02 501
+update_of_primary_key_many_keys 25.00 0.01 0.00 0.01 256
+update_with_key 60.00 9.66 6.21 15.87 300000
+update_with_key_prefix 21.00 6.04 1.98 8.02 100000
+wisc_benchmark 4.00 2.17 0.52 2.69 114
+TOTALS 3399.00 664.19 179.00 843.19 3227247
diff --git a/sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..f0deae1c1c4
--- /dev/null
+++ b/sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,16 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:30:52
+
+Testing of ALTER TABLE
+Testing with 1000 columns and 1000 rows in 20 steps
+Insert data into the table
+Time for insert (1000) 0 wallclock secs ( 0.01 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.03 CPU)
+
+Time for alter_table_add (992): 134 wallclock secs ( 0.12 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.15 CPU)
+
+Time for create_index (8): 3 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for drop_index (8): 2 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for alter_table_drop (496): 102 wallclock secs ( 0.04 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.06 CPU)
+
+Total time: 241 wallclock secs ( 0.17 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.24 CPU)
diff --git a/sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..afc03860f18
--- /dev/null
+++ b/sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,19 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:35:26
+
+Testing of some unusual tables
+All tests are done 1000 times with 1000 fields
+
+Testing table with 1000 fields
+Testing select * from table with 1 record
+Time to select_many_fields(1000): 8 wallclock secs ( 4.72 usr 2.37 sys + 0.00 cusr 0.00 csys = 7.09 CPU)
+
+Testing select all_fields from table with 1 record
+Time to select_many_fields(1000): 11 wallclock secs ( 4.46 usr 2.73 sys + 0.00 cusr 0.00 csys = 7.19 CPU)
+
+Testing insert VALUES()
+Time to insert_many_fields(1000): 2 wallclock secs ( 0.15 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.20 CPU)
+
+Testing insert (all_fields) VALUES()
+Time to insert_many_fields(1000): 5 wallclock secs ( 0.04 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.06 CPU)
+
+Total time: 27 wallclock secs ( 9.38 usr 5.17 sys + 0.00 cusr 0.00 csys = 14.55 CPU)
diff --git a/sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..d2a4f2eb3b6
--- /dev/null
+++ b/sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,35 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:35:53
+
+Testing the speed of connecting to the server and sending of data
+Connect tests are done 10000 times and other tests 100000 times
+
+Testing connection/disconnect
+Time to connect (10000): 7 wallclock secs ( 4.50 usr 1.62 sys + 0.00 cusr 0.00 csys = 6.12 CPU)
+
+Test connect/simple select/disconnect
+Time for connect+select_simple (10000): 9 wallclock secs ( 5.19 usr 2.02 sys + 0.00 cusr 0.00 csys = 7.21 CPU)
+
+Test simple select
+Time for select_simple (100000): 15 wallclock secs ( 8.15 usr 2.84 sys + 0.00 cusr 0.00 csys = 10.99 CPU)
+
+Test simple select
+Time for select_simple_cache (100000): 14 wallclock secs ( 8.03 usr 3.18 sys + 0.00 cusr 0.00 csys = 11.21 CPU)
+
+Testing connect/select 1 row from table/disconnect
+Time to connect+select_1_row (10000): 10 wallclock secs ( 5.09 usr 2.31 sys + 0.00 cusr 0.00 csys = 7.40 CPU)
+
+Testing select 1 row from table
+Time to select_1_row (100000): 22 wallclock secs ( 9.63 usr 4.42 sys + 0.00 cusr 0.00 csys = 14.05 CPU)
+
+Time to select_1_row_cache (100000): 19 wallclock secs ( 6.75 usr 3.55 sys + 0.00 cusr 0.00 csys = 10.30 CPU)
+
+Testing select 2 rows from table
+Time to select_2_rows (100000): 24 wallclock secs ( 9.99 usr 4.11 sys + 0.00 cusr 0.00 csys = 14.10 CPU)
+
+Test select with aritmetic (+)
+Time for select_column+column (100000): 23 wallclock secs ( 8.62 usr 3.65 sys + 0.00 cusr 0.00 csys = 12.27 CPU)
+
+Testing retrieval of big records (65000 bytes)
+Time to select_big_str (10000): 13 wallclock secs ( 5.10 usr 3.32 sys + 0.00 cusr 0.00 csys = 8.42 CPU)
+
+Total time: 156 wallclock secs (71.06 usr 31.02 sys + 0.00 cusr 0.00 csys = 102.08 CPU)
diff --git a/sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..864a4adb7e6
--- /dev/null
+++ b/sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,18 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:38:29
+
+Testing the speed of creating and droping tables
+Testing with 10000 tables and 10000 loop count
+
+Testing create of tables
+Time for create_MANY_tables (10000): 25 wallclock secs ( 1.12 usr 0.28 sys + 0.00 cusr 0.00 csys = 1.40 CPU)
+
+Accessing tables
+Time to select_group_when_MANY_tables (10000): 14 wallclock secs ( 0.98 usr 0.34 sys + 0.00 cusr 0.00 csys = 1.32 CPU)
+
+Testing drop
+Time for drop_table_when_MANY_tables (10000): 11 wallclock secs ( 0.34 usr 0.17 sys + 0.00 cusr 0.00 csys = 0.51 CPU)
+
+Testing create+drop
+Time for create+drop (10000): 17 wallclock secs ( 1.49 usr 0.50 sys + 0.00 cusr 0.00 csys = 1.99 CPU)
+Time for create_key+drop (10000): 23 wallclock secs ( 1.84 usr 0.62 sys + 0.00 cusr 0.00 csys = 2.46 CPU)
+Total time: 90 wallclock secs ( 5.77 usr 1.91 sys + 0.00 cusr 0.00 csys = 7.68 CPU)
diff --git a/sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..719ed9f11b9
--- /dev/null
+++ b/sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,106 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:39:59
+
+Testing the speed of inserting data into 1 table and do some selects on it.
+The tests are done with a table that has 100000 rows.
+
+Generating random keys
+Creating tables
+Inserting 100000 rows in order
+Inserting 100000 rows in reverse order
+Inserting 100000 rows in random order
+Time for insert (300000): 65 wallclock secs (12.32 usr 5.91 sys + 0.00 cusr 0.00 csys = 18.23 CPU)
+
+Testing insert of duplicates
+Time for insert_duplicates (100000): 16 wallclock secs ( 2.42 usr 2.15 sys + 0.00 cusr 0.00 csys = 4.57 CPU)
+
+Retrieving data from the table
+Time for select_big (10:3000000): 31 wallclock secs (21.84 usr 8.07 sys + 0.00 cusr 0.00 csys = 29.91 CPU)
+Time for order_by_big_key (10:3000000): 33 wallclock secs (23.12 usr 7.93 sys + 0.00 cusr 0.00 csys = 31.05 CPU)
+Time for order_by_big_key_desc (10:3000000): 32 wallclock secs (23.13 usr 8.16 sys + 0.00 cusr 0.00 csys = 31.29 CPU)
+Time for order_by_big_key_prefix (10:3000000): 31 wallclock secs (21.76 usr 8.21 sys + 0.00 cusr 0.00 csys = 29.97 CPU)
+Time for order_by_big_key2 (10:3000000): 31 wallclock secs (21.98 usr 7.84 sys + 0.00 cusr 0.00 csys = 29.82 CPU)
+Time for order_by_big_key_diff (10:3000000): 39 wallclock secs (22.07 usr 7.71 sys + 0.00 cusr 0.00 csys = 29.78 CPU)
+Time for order_by_big (10:3000000): 40 wallclock secs (21.73 usr 8.15 sys + 0.00 cusr 0.00 csys = 29.88 CPU)
+Time for order_by_range (500:125750): 3 wallclock secs ( 0.81 usr 0.41 sys + 0.00 cusr 0.00 csys = 1.22 CPU)
+Time for order_by_key_prefix (500:125750): 3 wallclock secs ( 0.98 usr 0.34 sys + 0.00 cusr 0.00 csys = 1.32 CPU)
+Time for order_by_key2_diff (500:250500): 4 wallclock secs ( 2.00 usr 0.58 sys + 0.00 cusr 0.00 csys = 2.58 CPU)
+Time for select_diff_key (500:1000): 138 wallclock secs ( 0.12 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.14 CPU)
+Time for select_range_prefix (5010:42084): 7 wallclock secs ( 2.28 usr 0.46 sys + 0.00 cusr 0.00 csys = 2.74 CPU)
+Time for select_range_key2 (5010:42084): 7 wallclock secs ( 2.16 usr 0.40 sys + 0.00 cusr 0.00 csys = 2.56 CPU)
+Time for select_key_prefix (200000): 87 wallclock secs (51.79 usr 8.42 sys + 0.00 cusr 0.00 csys = 60.21 CPU)
+Time for select_key (200000): 82 wallclock secs (51.17 usr 8.13 sys + 0.00 cusr 0.00 csys = 59.30 CPU)
+Time for select_key_return_key (200000): 79 wallclock secs (48.93 usr 7.01 sys + 0.00 cusr 0.00 csys = 55.94 CPU)
+Time for select_key2 (200000): 86 wallclock secs (50.00 usr 7.89 sys + 0.00 cusr 0.00 csys = 57.89 CPU)
+Time for select_key2_return_key (200000): 81 wallclock secs (48.57 usr 6.51 sys + 0.00 cusr 0.00 csys = 55.08 CPU)
+Time for select_key2_return_prim (200000): 83 wallclock secs (49.27 usr 7.43 sys + 0.00 cusr 0.00 csys = 56.70 CPU)
+
+Test of compares with simple ranges
+Time for select_range_prefix (20000:43500): 6 wallclock secs ( 2.73 usr 0.53 sys + 0.00 cusr 0.00 csys = 3.26 CPU)
+Time for select_range_key2 (20000:43500): 5 wallclock secs ( 2.49 usr 0.52 sys + 0.00 cusr 0.00 csys = 3.01 CPU)
+Time for select_group (111): 42 wallclock secs ( 0.06 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.07 CPU)
+Time for min_max_on_key (15000): 6 wallclock secs ( 3.53 usr 0.54 sys + 0.00 cusr 0.00 csys = 4.07 CPU)
+Time for min_max (60): 23 wallclock secs ( 0.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+Time for count_on_key (100): 38 wallclock secs ( 0.03 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.04 CPU)
+Time for count (100): 33 wallclock secs ( 0.04 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.04 CPU)
+Time for count_distinct_big (20): 38 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+
+Testing update of keys with functions
+Time for update_of_key (50000): 14 wallclock secs ( 1.80 usr 0.94 sys + 0.00 cusr 0.00 csys = 2.74 CPU)
+Time for update_of_key_big (501): 20 wallclock secs ( 0.01 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+
+Testing update with key
+Time for update_with_key (300000): 60 wallclock secs ( 9.66 usr 6.21 sys + 0.00 cusr 0.00 csys = 15.87 CPU)
+Time for update_with_key_prefix (100000): 21 wallclock secs ( 6.04 usr 1.98 sys + 0.00 cusr 0.00 csys = 8.02 CPU)
+
+Testing update of all rows
+Time for update_big (10): 44 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing left outer join
+Time for outer_join_on_key (10:10): 40 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for outer_join (10:10): 48 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+Time for outer_join_found (10:10): 46 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+Time for outer_join_not_found (500:10): 31 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing SELECT ... WHERE id in (10 values)
+Time for select_in (500:5000) 0 wallclock secs ( 0.19 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.22 CPU)
+
+Time for select_join_in (500:5000) 1 wallclock secs ( 0.18 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.20 CPU)
+
+Testing SELECT ... WHERE id in (100 values)
+Time for select_in (500:50000) 3 wallclock secs ( 0.57 usr 0.11 sys + 0.00 cusr 0.00 csys = 0.68 CPU)
+
+Time for select_join_in (500:50000) 1 wallclock secs ( 0.51 usr 0.19 sys + 0.00 cusr 0.00 csys = 0.70 CPU)
+
+Testing SELECT ... WHERE id in (1000 values)
+Time for select_in (500:500000) 26 wallclock secs ( 4.25 usr 1.40 sys + 0.00 cusr 0.00 csys = 5.65 CPU)
+
+Time for select_join_in (500:500000) 14 wallclock secs ( 4.09 usr 1.42 sys + 0.00 cusr 0.00 csys = 5.51 CPU)
+
+
+Testing INSERT INTO ... SELECT
+Time for insert_select_1_key (1): 5 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for insert_select_2_keys (1): 6 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for drop table(2): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing delete
+Time for delete_key (10000): 2 wallclock secs ( 0.39 usr 0.26 sys + 0.00 cusr 0.00 csys = 0.65 CPU)
+Time for delete_range (12): 11 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+
+Insert into table with 16 keys and with a primary key with 16 parts
+Time for insert_key (100000): 86 wallclock secs ( 7.22 usr 2.27 sys + 0.00 cusr 0.00 csys = 9.49 CPU)
+
+Testing update of keys
+Time for update_of_primary_key_many_keys (256): 25 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+
+Deleting rows from the table
+Time for delete_big_many_keys (128): 51 wallclock secs ( 0.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+
+Deleting everything from table
+Time for delete_all_many_keys (1): 51 wallclock secs ( 0.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+
+Inserting 100000 rows with multiple values
+Time for multiple_value_insert (100000): 5 wallclock secs ( 1.29 usr 0.00 sys + 0.00 cusr 0.00 csys = 1.29 CPU)
+
+Time for drop table(1): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Total time: 1730 wallclock secs (523.67 usr 128.19 sys + 0.00 cusr 0.00 csys = 651.86 CPU)
diff --git a/sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..d6943e5711a
--- /dev/null
+++ b/sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,30 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 16:08:50
+
+Testing the speed of selecting on keys that consist of many parts
+The test-table has 10000 rows and the test is done with 500 ranges.
+
+Creating table
+Inserting 10000 rows
+Time to insert (10000): 3 wallclock secs ( 0.46 usr 0.25 sys + 0.00 cusr 0.00 csys = 0.71 CPU)
+
+Test if the database has a query cache
+Time for select_cache (10000): 88 wallclock secs ( 2.21 usr 0.38 sys + 0.00 cusr 0.00 csys = 2.59 CPU)
+
+Time for select_cache2 (10000): 89 wallclock secs ( 2.49 usr 0.39 sys + 0.00 cusr 0.00 csys = 2.88 CPU)
+
+Testing big selects on the table
+Time for select_big (70:17207): 0 wallclock secs ( 0.13 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.16 CPU)
+Time for select_range (410:1057904): 103 wallclock secs ( 8.73 usr 2.95 sys + 0.00 cusr 0.00 csys = 11.68 CPU)
+Time for min_max_on_key (70000): 153 wallclock secs (15.68 usr 2.24 sys + 0.00 cusr 0.00 csys = 17.92 CPU)
+Time for count_on_key (50000): 378 wallclock secs (11.70 usr 1.69 sys + 0.00 cusr 0.00 csys = 13.39 CPU)
+
+Time for count_group_on_key_parts (1000:100000): 43 wallclock secs ( 0.96 usr 0.31 sys + 0.00 cusr 0.00 csys = 1.27 CPU)
+Testing count(distinct) on the table
+Time for count_distinct_key_prefix (1000:1000): 28 wallclock secs ( 0.29 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.32 CPU)
+Time for count_distinct (1000:1000): 34 wallclock secs ( 0.24 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.29 CPU)
+Time for count_distinct_2 (1000:1000): 38 wallclock secs ( 0.25 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.32 CPU)
+Time for count_distinct_group_on_key (1000:6000): 43 wallclock secs ( 0.26 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.31 CPU)
+Time for count_distinct_group_on_key_parts (1000:100000): 47 wallclock secs ( 0.98 usr 0.29 sys + 0.00 cusr 0.00 csys = 1.27 CPU)
+Time for count_distinct_group (1000:100000): 47 wallclock secs ( 1.00 usr 0.27 sys + 0.00 cusr 0.00 csys = 1.27 CPU)
+Time for count_distinct_big (100:1000000): 12 wallclock secs ( 7.14 usr 2.75 sys + 0.00 cusr 0.00 csys = 9.89 CPU)
+Total time: 1106 wallclock secs (52.54 usr 11.75 sys + 0.00 cusr 0.00 csys = 64.29 CPU)
diff --git a/sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..821d74a7c01
--- /dev/null
+++ b/sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,3 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 16:27:17
+
+Test skipped because the database doesn't support transactions
diff --git a/sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..8b054de0a3d
--- /dev/null
+++ b/sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,14 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 16:27:17
+
+Wisconsin benchmark test
+
+Time for create_table (3): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Inserting data
+Time to insert (31000): 8 wallclock secs ( 0.89 usr 0.68 sys + 0.00 cusr 0.00 csys = 1.57 CPU)
+Time to delete_big (1): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Running the actual benchmark
+Time for wisc_benchmark (114): 4 wallclock secs ( 2.17 usr 0.52 sys + 0.00 cusr 0.00 csys = 2.69 CPU)
+
+Total time: 12 wallclock secs ( 3.07 usr 1.20 sys + 0.00 cusr 0.00 csys = 4.27 CPU)
diff --git a/sql-bench/as3ap.sh b/sql-bench/as3ap.sh
new file mode 100644
index 00000000000..ed796249ebb
--- /dev/null
+++ b/sql-bench/as3ap.sh
@@ -0,0 +1,636 @@
+#!@PERL@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# AS3AP single-user benchmark.
+#
+
+##################### Standard benchmark inits ##############################
+
+use DBI;
+use Benchmark;
+
+chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
+
+$opt_loop_count=1;
+
+#Create tables
+
+$dbh = $server->connect();
+
+#Create Table
+$sth = $dbh->do("drop table uniques");
+$sth = $dbh->do("drop table updates");
+$sth = $dbh->do("drop table hundred");
+$sth = $dbh->do("drop table tenpct");
+$sth = $dbh->do("drop table tiny");
+
+#Temporary table
+$sth = $dbh->do("drop table saveupdates");
+
+@fields=("col_key int not null",
+ "col_int int not null",
+ "col_signed int not null",
+ "col_float float not null",
+ "col_double float not null",
+ "col_decim numeric(18,2) not null",
+ "col_date char(20) not null",
+ "col_code char(10) not null",
+ "col_name char(20) not null",
+ "col_address varchar(80) not null");
+
+do_many($dbh,$server->create("uniques",\@fields,[]));
+do_many($dbh,$server->create("updates",\@fields,[]));
+do_many($dbh,$server->create("hundred",\@fields,[]));
+do_many($dbh,$server->create("tenpct",\@fields,[]));
+do_many($dbh,$server->create("tiny",["col_key int not null"],[]));
+
+print "Start AS3AP benchmark\n\n";
+
+$start_time=new Benchmark;
+
+print "Load DATA\n";
+#Load DATA
+
+@table_names=("uniques","updates","hundred","tenpct","tiny");
+
+$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{'limits'}->{'load_data_infile'})
+{
+ for ($ti = 0; $ti <= $#table_names; $ti++)
+ {
+ my $table_name = $table_names[$ti];
+ my $file = "$pwd/Data/AS3AP/${table_name}\.new";
+ print "$table_name - $file\n" if ($opt_debug);
+ $row_count += $server->insert_file($table_name,$file,$dbh);
+ }
+}
+else
+{
+ for ($ti = 0; $ti <= $#table_names; $ti++)
+ {
+ my $table_name = $table_names[$ti];
+ print "$table_name - $file\n" if ($opt_debug);
+ my $insert_start = "insert into $table_name values (";
+ open(DATA, "$pwd/Data/AS3AP/${table_name}\.new") || die "Can't open text file: $pwd/Data/AS3AP/${table_name}\.new\n";
+ while(<DATA>)
+ {
+ chomp;
+ next unless ( $_ =~ /\w/ ); # skip blank lines
+ $command = $insert_start."$_".")";
+ $command =~ $server->fix_to_insert($command);
+ print "$command\n" if ($opt_debug);
+ $sth = $dbh->do($command) or die "Got error: $DBI::errstr when executing '$command'\n";
+ $row_count++;
+ }
+ close(DATA);
+ }
+}
+
+$end_time=new Benchmark;
+print "Time for Load Data - " . "($row_count): " .
+timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+
+print "Create Index\n";
+
+test_command("create_idx_uniques_key_bt",
+ "time for create_idx_uniques_key_bt",
+ "create unique index uniques_key_bt on uniques (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_key_bt",
+ "time for create_idx_updates_key_bt",
+ "create unique index updates_key_bt on updates (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_hundred_key_bt",
+ "time for create_idx_hundred_key_bt",
+ "create unique index hundred_key_bt on hundred (col_key)",
+ $dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_key_bt",
+ "time for create_idx_tenpct_key_bt",
+ "create unique index tenpct_key_bt on tenpct (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_key_code_bt",
+ "time for create_idx_tenpct_key_code_bt",
+ "create index tenpct_key_code_bt on tenpct (col_key,col_code)",
+ $dbh,$opt_loop_count);
+
+test_command("create_idx_tiny_key_bt",
+ "time for create_idx_tiny_key_bt",
+ "create index tiny_key_bt on tiny (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_int_bt",
+ "time for create_idx_tenpct_int_bt",
+ "create index tenpct_int_bt on tenpct (col_int)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_signed_bt",
+ "time for create_idx_tenpct_signed_bt",
+ "create index tenpct_signed_bt on tenpct (col_signed)",$dbh,$opt_loop_count);
+
+test_command("create_idx_uniques_code_h",
+ "time for create_idx_uniques_code_h",
+ "create index uniques_code_h on uniques (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_double_bt",
+ "time for create_idx_tenpct_double_bt",
+ "create index tenpct_double_bt on tenpct (col_double)",$dbh,$opt_loop_count);
+
+
+test_command("create_idx_updates_decim_bt",
+ "time for create_idx_updates_decim_bt",
+ "create index updates_decim_bt on updates (col_decim)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_float_bt",
+ "time for create_idx_tenpct_float_bt",
+ "create index tenpct_float_bt on tenpct (col_float)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_int_bt",
+ "time for create_idx_updates_int_bt",
+ "create index updates_int_bt on updates (col_int)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_decim_bt",
+ "time for create_idx_tenpct_decim_bt",
+ "create index tenpct_decim_bt on tenpct (col_decim)",$dbh,$opt_loop_count);
+
+test_command("create_idx_hundred_code_h",
+ "time for create_idx_hundred_code_h",
+ "create index hundred_code_h on hundred (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_name_h",
+ "time for create_idx_tenpct_name_h",
+ "create index tenpct_name_h on tenpct (col_name)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_code_h",
+ "time for create_idx_updates_code_h",
+ "create index updates_code_h on updates (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_code_h",
+ "time for create_idx_tenpct_code_h",
+ "create index tenpct_code_h on tenpct (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_double_bt",
+ "time for create_idx_updates_double_bt",
+ "create index updates_double_bt on updates (col_double)",$dbh,$opt_loop_count);
+
+test_command("create_idx_hundred_foreign",
+ "time for create_idx_hundred_foreign",
+ "alter table hundred add constraint fk_hundred_updates foreign key (col_signed)
+ references updates (col_key)",$dbh,$opt_loop_count);
+
+test_query("sel_1_cl",
+ "Time to sel_1_cl",
+ "select col_key, col_int, col_signed, col_code, col_double, col_name
+ from updates where col_key = 1000",$dbh,$opt_loop_count);
+
+test_query("join_3_cl",
+ "Time to join_3_cl",
+ "select uniques.col_signed, uniques.col_date,
+ hundred.col_signed, hundred.col_date,
+ tenpct.col_signed, tenpct.col_date
+ from uniques, hundred, tenpct
+ where uniques.col_key = hundred.col_key
+ and uniques.col_key = tenpct.col_key
+ and uniques.col_key = 1000",$dbh,$opt_loop_count);
+
+test_query("sel_100_ncl",
+ "Time to sel_100_ncl",
+ "select col_key, col_int, col_signed, col_code,col_double, col_name
+ from updates where col_int <= 100",$dbh,$opt_loop_count);
+
+test_query("table_scan",
+ "Time to table_scan",
+ "select * from uniques where col_int = 1",$dbh,$opt_loop_count);
+
+test_query("agg_func",
+ "Time for agg_func",
+ "select min(col_key) from hundred group by col_name",$dbh,$opt_loop_count);
+
+test_query("agg_scal",
+ "Time for agg_scal",
+ "select min(col_key) from uniques",$dbh,$opt_loop_count);
+
+test_query("sel_100_cl",
+ "Time for sel_100_cl",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from updates where col_key <= 100",$dbh,$opt_loop_count);
+
+test_query("join_3_ncl",
+ "Time for join_3_ncl",
+ "select uniques.col_signed, uniques.col_date,
+ hundred.col_signed, hundred.col_date,
+ tenpct.col_signed, tenpct.col_date
+ from uniques, hundred, tenpct
+ where uniques.col_code = hundred.col_code
+ and uniques.col_code = tenpct.col_code
+ and uniques.col_code = 'BENCHMARKS'",$dbh,$opt_loop_count);
+
+test_query("sel_10pct_ncl",
+ "Time for sel_10pct_ncl",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from tenpct
+ where col_name = 'THE+ASAP+BENCHMARKS+'",$dbh,$opt_loop_count);
+
+if ($limits->{'subqueries'}){
+ test_query("agg_simple_report",
+ "Time for agg_simple_report",
+ "select avg(updates.col_decim)
+ from updates
+ where updates.col_key in
+ (select updates.col_key
+ from updates, hundred
+ where hundred.col_key = updates.col_key
+ and updates.col_decim > 980000000)",$dbh,$opt_loop_count);
+}else{
+ print "agg_simple_report - Failed\n\n";
+}
+
+test_query("agg_info_retrieval",
+ "Time for agg_info_retrieval",
+ "select count(col_key)
+ from tenpct
+ where col_name = 'THE+ASAP+BENCHMARKS'
+ and col_int <= 100000000
+ and col_signed between 1 and 99999999
+ and not (col_float between -450000000 and 450000000)
+ and col_double > 600000000
+ and col_decim < -600000000",$dbh,$opt_loop_count);
+
+if ($limits->{'views'}){
+ test_query("agg_create_view",
+ "Time for agg_create_view",
+ "create view
+ reportview(col_key,col_signed,col_date,col_decim,
+ col_name,col_code,col_int) as
+ select updates.col_key, updates.col_signed,
+ updates.col_date, updates.col_decim,
+ hundred.col_name, hundred.col_code,
+ hundred.col_int
+ from updates, hundred
+ where updates.col_key = hundred.col_key",$dbh,$opt_loop_count);
+
+ test_query("agg_subtotal_report",
+ "Time for agg_subtotal_report",
+ "select avg(col_signed), min(col_signed), max(col_signed),
+ max(col_date), min(col_date),
+ count(distinct col_name), count(col_name),
+ col_code, col_int
+ from reportview
+ where col_decim >980000000
+ group by col_code, col_int",$dbh,$opt_loop_count);
+
+
+ test_query("agg_total_report",
+ "Time for agg_total_report",
+ "select avg(col_signed), min(col_signed), max(col_signed),
+ max(col_date), min(col_date),
+ count(distinct col_name), count(col_name),
+ count(col_code), count(col_int)
+ from reportview
+ where col_decim >980000000",$dbh,$opt_loop_count);
+}else{
+ print "agg_create_view - Failed\n\n";
+ print "agg_subtotal_report - Failed\n\n";
+ print "agg_total_report - Failed\n\n";
+}
+
+#fix from here
+test_query("join_2_cl",
+ "Time for join_2_cl",
+ "select uniques.col_signed, uniques.col_name,
+ hundred.col_signed, hundred.col_name
+ from uniques, hundred
+ where uniques.col_key = hundred.col_key
+ and uniques.col_key =1000"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_2",
+ "Time for join_2",
+ "select uniques.col_signed, uniques.col_name,
+ hundred.col_signed, hundred.col_name
+ from uniques, hundred
+ where uniques.col_address = hundred.col_address
+ and uniques.col_address = 'SILICON VALLEY'"
+ ,$dbh,$opt_loop_count);
+
+test_query("sel_variable_select_low",
+ "Time for sel_variable_select_low",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from tenpct
+ where col_signed < -500000000"
+ ,$dbh,$opt_loop_count);
+
+test_query("sel_variable_select_high",
+ "Time for sel_variable_select_high",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from tenpct
+ where col_signed < -250000000"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_4_cl",
+ "Time for join_4_cl",
+ "select uniques.col_date, hundred.col_date,
+ tenpct.col_date, updates.col_date
+ from uniques, hundred, tenpct, updates
+ where uniques.col_key = hundred.col_key
+ and uniques.col_key = tenpct.col_key
+ and uniques.col_key = updates.col_key
+ and uniques.col_key = 1000"
+ ,$dbh,$opt_loop_count);
+
+test_query("proj_100",
+ "Time for proj_100",
+ "select distinct col_address, col_signed from hundred"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_4_ncl",
+ "Time for join_4_ncl",
+ "select uniques.col_date, hundred.col_date,
+ tenpct.col_date, updates.col_date
+ from uniques, hundred, tenpct, updates
+ where uniques.col_code = hundred.col_code
+ and uniques.col_code = tenpct.col_code
+ and uniques.col_code = updates.col_code
+ and uniques.col_code = 'BENCHMARKS'"
+ ,$dbh,$opt_loop_count);
+
+test_query("proj_10pct",
+ "Time for proj_10pct",
+ "select distinct col_signed from tenpct"
+ ,$dbh,$opt_loop_count);
+
+test_query("sel_1_ncl",
+ "Time for sel_1_ncl",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from updates where col_code = 'BENCHMARKS'"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_2_ncl",
+ "Time for join_2_ncl",
+ "select uniques.col_signed, uniques.col_name,
+ hundred.col_signed, hundred.col_name
+ from uniques, hundred
+ where uniques.col_code = hundred.col_code
+ and uniques.col_code = 'BENCHMARKS'"
+ ,$dbh,$opt_loop_count);
+
+if ($limits->{'foreign_key'}){
+ do_many($dbh,$server->create("integrity_temp",\@fields,[]));
+
+ test_query("integrity_test_1",
+ "Time for integrity_test",
+ "insert into integrity_temp select *
+ from hundred where col_int=0",$dbh,$opt_loop_count);
+
+ test_query("integrity_test_2",
+ "Time for integrity_test",
+ "update hundred set col_signed = '-500000000'
+ where col_int = 0",$dbh,$opt_loop_count);
+
+ test_query("integrity_test_3",
+ "Time for integrity_test",
+ "update hundred set col_signed = '-500000000'
+ where col_int = 0",$dbh,$opt_loop_count);
+
+
+}else{
+ print "integrity_test - Failed\n\n";
+}
+
+push @drop_seq_command,$server->drop_index("updates","updates_int_bt");
+push @drop_seq_command,$server->drop_index("updates","updates_double_bt");
+push @drop_seq_command,$server->drop_index("updates","updates_decim_bt");
+push @drop_seq_command,$server->drop_index("updates","updates_code_h");
+
+test_many_command("Drop updates keys",
+ "Time for drop_updates_keys",
+ \@drop_seq_command,$dbh,$opt_loop_count);
+
+do_many($dbh,$server->create("saveupdates",\@fields,[]));
+
+test_command("bulk_save",
+ "Time for bulk_save",
+ "insert into saveupdates select *
+ from updates where col_key between 5000 and 5999"
+ ,$dbh,$opt_loop_count);
+
+test_command("bulk_modify",
+ "Time for bulk_modify",
+ "update updates
+ set col_key = col_key - 100000
+ where col_key between 5000 and 5999"
+ ,$dbh,$opt_loop_count);
+
+safe_command("upd_append_duplicate",
+ "Time for upd_append_duplicate",
+ "insert into updates
+ values (6000, 0, 60000, 39997.90,
+ 50005.00, 50005.00,
+ '11/10/1985', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_remove_duplicate",
+ "Time for upd_remove_duplicate",
+ "delete from updates where col_key = 6000 and col_int = 0"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_app_t_mid",
+ "Time for upd_app_t_mid",
+ "insert into updates
+ values (5005, 5005, 50005, 50005.00, 50005.00,
+ 50005.00, '1/1/1988', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_mid",
+ "Time for upd_mod_t_mid",
+ "update updates set col_key = '-5000'
+ where col_key = 5005"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_mid",
+ "Time for upd_del_t_mid",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_app_t_end",
+ "Time for upd_app_t_end",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_end",
+ "Time for upd_mod_t_end",
+ "update updates
+ set col_key = -1000
+ where col_key = 1000000001"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_end",
+ "Time for upd_del_t_end",
+ "delete from updates where col_key = -1000"
+ ,$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_code_h",
+ "time for create_idx_updates_code_h",
+ "create index updates_code_h on updates (col_code)",
+ $dbh,$opt_loop_count);
+
+test_command("upd_app_t_mid",
+ "Time for upd_app_t_mid",
+ "insert into updates
+ values (5005, 5005, 50005, 50005.00, 50005.00,
+ 50005.00, '1/1/1988', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_cod",
+ "Time for upd_mod_t_cod",
+ "update updates
+ set col_code = 'SQL+GROUPS'
+ where col_key = 5005"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_mid",
+ "Time for upd_del_t_mid",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_int_bt",
+ "time for create_idx_updates_int_bt",
+ "create index updates_int_bt on updates (col_int)",
+ $dbh,$opt_loop_count);
+
+test_command("upd_app_t_mid",
+ "Time for upd_app_t_mid",
+ "insert into updates
+ values (5005, 5005, 50005, 50005.00, 50005.00,
+ 50005.00, '1/1/1988', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_int",
+ "Time for upd_mod_t_int",
+ "update updates set col_int = 50015 where col_key = 5005"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_mid",
+ "Time for upd_del_t_mid",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("bulk_append",
+ "Time for bulk_append",
+ "insert into updates select * from saveupdates"
+ ,$dbh,$opt_loop_count);
+
+test_command("bulk_delete",
+ "Time for bulk_delete",
+ "delete from updates where col_key < 0"
+ ,$dbh,$opt_loop_count);
+
+################################ END ###################################
+####
+#### End of the test...Finally print time used to execute the
+#### whole test.
+
+$dbh->disconnect;
+
+end_benchmark($start_time);
+
+############################ HELP FUNCTIONS ##############################
+
+sub test_query
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ print $test_text . "\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ defined(fetch_all_rows($dbh,$query)) or warn $DBI::errstr;
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+
+sub test_command
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ print $test_text . "\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ $dbh->do($query) or die $DBI::errstr;
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+sub safe_command
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ print $test_text . "\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ safe_do_many($dbh,$query);
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+sub test_many_command
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ safe_do_many($dbh, @$query);
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+
diff --git a/sql-bench/bench-count-distinct.sh b/sql-bench/bench-count-distinct.sh
new file mode 100644
index 00000000000..1359a864ac1
--- /dev/null
+++ b/sql-bench/bench-count-distinct.sh
@@ -0,0 +1,258 @@
+#!@PERL@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# Test of selecting on keys that consist of many parts
+#
+##################### Standard benchmark inits ##############################
+
+use DBI;
+use Getopt::Long;
+use Benchmark;
+
+$opt_loop_count=10000;
+$opt_medium_loop_count=200;
+$opt_small_loop_count=10;
+$opt_regions=6;
+$opt_groups=100;
+
+chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
+
+$columns=min($limits->{'max_columns'},500,($limits->{'query_size'}-50)/24,
+ $limits->{'max_conditions'}/2-3);
+
+if ($opt_small_test)
+{
+ $opt_loop_count/=10;
+ $opt_medium_loop_count/=10;
+ $opt_small_loop_count/=10;
+ $opt_groups/=10;
+}
+
+print "Testing the speed of selecting on keys that consist of many parts\n";
+print "The test-table has $opt_loop_count rows and the test is done with $columns ranges.\n\n";
+
+####
+#### Connect and start timeing
+####
+
+$dbh = $server->connect();
+$start_time=new Benchmark;
+
+####
+#### Create needed tables
+####
+
+goto select_test if ($opt_skip_create);
+
+print "Creating table\n";
+$dbh->do("drop table bench1" . $server->{'drop_attr'});
+
+do_many($dbh,$server->create("bench1",
+ ["region char(1) NOT NULL",
+ "idn integer(6) NOT NULL",
+ "rev_idn integer(6) NOT NULL",
+ "grp integer(6) NOT NULL"],
+ ["primary key (region,idn)",
+ "unique (region,rev_idn)",
+ "unique (region,grp,idn)"]));
+if ($opt_lock_tables)
+{
+ do_query($dbh,"LOCK TABLES bench1 WRITE");
+}
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(1,\$dbh);
+}
+
+####
+#### Insert $opt_loop_count records with
+#### region: "A" -> "E"
+#### idn: 0 -> count
+#### rev_idn: count -> 0,
+#### grp: distributed values 0 - > count/100
+####
+
+print "Inserting $opt_loop_count rows\n";
+
+$loop_time=new Benchmark;
+$query="insert into bench1 values (";
+$half_done=$opt_loop_count/2;
+for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ; $id++,$rev_id--)
+{
+ $grp=$id*3 % $opt_groups;
+ $region=chr(65+$id%$opt_regions);
+ do_query($dbh,"$query'$region',$id,$rev_id,$grp)");
+ if ($id == $half_done)
+ { # Test with different insert
+ $query="insert into bench1 (region,idn,rev_idn,grp) values (";
+ }
+}
+
+$end_time=new Benchmark;
+print "Time to insert ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+if ($opt_lock_tables)
+{
+ do_query($dbh,"UNLOCK TABLES");
+}
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(0,\$dbh,"bench1");
+}
+
+if ($opt_lock_tables)
+{
+ do_query($dbh,"LOCK TABLES bench1 WRITE");
+}
+
+####
+#### Do some selects on the table
+####
+
+select_test:
+
+
+
+if ($limits->{'group_distinct_functions'})
+{
+ print "Testing count(distinct) on the table\n";
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select count(distinct region) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_key_prefix ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select count(distinct grp) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select count(distinct grp),count(distinct rev_idn) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_2 ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select region,count(distinct idn) from bench1 group by region");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_group_on_key ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select grp,count(distinct idn) from bench1 group by grp");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_group_on_key_parts ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select grp,count(distinct rev_idn) from bench1 group by grp");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_group ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ $test_count=$opt_medium_loop_count/10;
+ for ($i=0 ; $i < $test_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select idn,count(distinct region) from bench1 group by idn");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $test_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_big ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+}
+
+####
+#### End of benchmark
+####
+
+if ($opt_lock_tables)
+{
+ do_query($dbh,"UNLOCK TABLES");
+}
+if (!$opt_skip_delete)
+{
+ do_query($dbh,"drop table bench1" . $server->{'drop_attr'});
+}
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(0,\$dbh);
+}
+
+$dbh->disconnect; # close connection
+
+end_benchmark($start_time);
diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh
index 204d15d7ab3..4e7e1c29504 100644
--- a/sql-bench/bench-init.pl.sh
+++ b/sql-bench/bench-init.pl.sh
@@ -38,24 +38,28 @@ require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n";
$|=1; # Output data immediately
-$opt_skip_test=$opt_skip_create=$opt_skip_delete=$opt_verbose=$opt_fast_insert=$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=$opt_log=$opt_use_old_results=$opt_help=$opt_odbc=$opt_small_test=$opt_small_tables=$opt_samll_key_tables=$opt_stage=$opt_old_headers=$opt_die_on_errors=$opt_tcpip=0;
+$opt_skip_test=$opt_skip_create=$opt_skip_delete=$opt_verbose=$opt_fast_insert=$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=$opt_log=$opt_use_old_results=$opt_help=$opt_odbc=$opt_small_test=$opt_small_tables=$opt_samll_key_tables=$opt_stage=$opt_old_headers=$opt_die_on_errors=$opt_tcpip=$opt_random=0;
$opt_cmp=$opt_user=$opt_password="";
$opt_server="mysql"; $opt_dir="output";
$opt_host="localhost";$opt_database="test";
$opt_machine=""; $opt_suffix="";
$opt_create_options=undef;
+$opt_optimization="None";
+$opt_hw="";
+$opt_threads=5;
$opt_time_limit=10*60; # Don't wait more than 10 min for some tests
$log_prog_args=join(" ", skip_arguments(\@ARGV,"comments","cmp","server",
"user", "host", "database", "password",
"use-old-results","skip-test",
+ "optimization","hw",
"machine", "dir", "suffix", "log"));
-GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","old-headers","die-on-errors","create-options=s","hires","tcpip","silent") || usage();
+GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","threads=i","random","old-headers","die-on-errors","create-options=s","hires","tcpip","silent","optimization=s","hw=s","socket=s") || usage();
usage() if ($opt_help);
$server=get_server($opt_server,$opt_host,$opt_database,$opt_odbc,
- machine_part());
+ machine_part(), $opt_socket);
$limits=merge_limits($server,$opt_cmp);
$date=date();
@estimated=(0.0,0.0,0.0); # For estimated time support
@@ -515,6 +519,10 @@ All benchmarks takes the following options:
--password='password'
Password for the current user.
+--socket='socket'
+ If the database supports connecting through a Unix socket,
+ use this socket to connect
+
--regions
This is a test specific option that is only used when debugging a test.
This usually means how AND levels should be tested.
@@ -553,6 +561,13 @@ All benchmarks takes the following options:
different server options without overwritten old files.
When using --fast the suffix is automaticly set to '_fast'.
+--random
+ Inform test suite that we are generate random inital values for sequence of
+ test executions. It should be used for imitation of real conditions.
+
+--threads=# (Default 5)
+ Number of threads for multi-user benchmarks.
+
--tcpip
Inform test suite that we are using TCP/IP to connect to the server. In
this case we can\t do many new connections in a row as we in this case may
@@ -572,6 +587,13 @@ All benchmarks takes the following options:
--verbose
This is a test specific option that is only used when debugging a test.
Print more information about what is going on.
+
+--optimization='some comments'
+ Add coments about optimization of DBMS, which was done before the test.
+
+--hw='some comments'
+ Add coments about hardware used for this test.
+
EOF
exit(0);
}
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index f6985adc5c0..d66e8f47d6a 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -38,7 +38,7 @@
# as such, and clarify ones such as "mediumint" with comments such as
# "3-byte int" or "same as xxx".
-$version="1.57";
+$version="1.58";
use DBI;
use Getopt::Long;
@@ -143,7 +143,15 @@ $longreadlen=16000000; # For retrieval buffer
#
use sigtrap; # Must be removed with perl5.005_2 on Win98
$SIG{PIPE} = 'IGNORE';
-$SIG{SEGV} = sub {warn('SEGFAULT')};
+$problem_counter=0;
+$SIG{SEGV} = sub {
+ $problem_counter +=1;
+ if ($problem_counter >= 100) {
+ die("Too many problems, try to restart");
+ } else {
+ warn('SEGFAULT');
+ };
+};
$dbh=safe_connect();
#
@@ -252,6 +260,8 @@ report("Functions",'functions',"select 1+1 $end_query");
report("Group functions",'group_functions',"select count(*) from crash_me");
report("Group functions with distinct",'group_distinct_functions',
"select count(distinct a) from crash_me");
+report("Group functions with several distinct",'group_many_distinct_functions',
+ "select count(distinct a), count(distinct b) from crash_me");
report("Group by",'group_by',"select a from crash_me group by a");
report("Group by position",'group_by_position',
"select a from crash_me group by 1");
@@ -1438,6 +1448,14 @@ if (!report("case independent table names","table_name_case",
safe_query("drop table crash_q $drop_attr");
}
+if (!report("case independent field names","field_name_case",
+ "create table crash_q (q integer)",
+ "insert into crash_q(Q) values (1)",
+ "drop table crash_q $drop_attr"))
+{
+ safe_query("drop table crash_q $drop_attr");
+}
+
if (!report("drop table if exists","drop_if_exists",
"create table crash_q (q integer)",
"drop table if exists crash_q $drop_attr"))
@@ -2168,20 +2186,20 @@ EOF
print <<EOF;
Some of the tests you are about to execute may require a lot of
-memory. Your tests WILL adversely affect system performance. It's
+memory. Your tests WILL adversely affect system performance. It\'s
not uncommon that either this crash-me test program, or the actual
database back-end, will DIE with an out-of-memory error. So might
any other program on your system if it requests more memory at the
wrong time.
Note also that while crash-me tries to find limits for the database server
-it will make a lot of queries that can't be categorized as 'normal'. It's
+it will make a lot of queries that can\'t be categorized as \'normal\'. It\'s
not unlikely that crash-me finds some limit bug in your server so if you
run this test you have to be prepared that your server may die during it!
We, the creators of this utility, are not responsible in any way if your
database server unexpectedly crashes while this program tries to find the
-limitations of your server. By accepting the following question with 'yes',
+limitations of your server. By accepting the following question with \'yes\',
you agree to the above!
You have been warned!
@@ -2478,6 +2496,7 @@ sub report_one
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$result="no";
foreach $query (@$queries)
{
@@ -2503,6 +2522,7 @@ sub report_result
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$error=safe_query_result($query,"1",2);
save_config_data($limit,$error ? "not supported" : $last_result,$prompt);
}
@@ -2515,6 +2535,7 @@ sub report_trans
my ($limit,$queries,$check,$clear)=@_;
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
eval {undef($dbh->{AutoCommit})};
if (!$@)
{
@@ -2524,21 +2545,21 @@ sub report_trans
if ($rc) {
$dbh->{AutoCommit} = 1;
if (safe_query_result($check,"","")) {
- save_config_data($limit,"yes",$prompt);
+ save_config_data($limit,"yes",$limit);
}
safe_query($clear);
} else {
$dbh->{AutoCommit} = 1;
- save_config_data($limit,"error",$prompt);
+ save_config_data($limit,"error",$limit);
}
} else {
- save_config_data($limit,"error",$prompt);
+ save_config_data($limit,"error",$limit);
}
$dbh->{AutoCommit} = 1;
}
else
{
- save_config_data($limit,"no",$prompt);
+ save_config_data($limit,"no",$limit);
}
safe_query($clear);
}
@@ -2556,9 +2577,11 @@ sub check_and_report
print "$prompt: " if (!defined($skip_prompt));
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$tmp=1-safe_query(\@$pre);
$tmp=safe_query_result($query,$answer,$string_type) if (!$tmp);
safe_query(\@$post);
+ delete $limits{$limit};
if ($function == 3) # Report error as 'no'.
{
$function=0;
@@ -2587,8 +2610,10 @@ sub try_and_report
my ($tmp,$test,$type);
print "$prompt: ";
+
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$type="no"; # Not supported
foreach $test (@tests)
{
@@ -2668,7 +2693,8 @@ sub safe_query_result
$sth->finish;
return ($result_type == 8) ? 0 : 1;
}
- if($result_type == 8) {
+ if ($result_type == 8)
+ {
$sth->finish;
return 1;
}
@@ -2699,7 +2725,7 @@ sub safe_query_result
elsif ($result_type == 5) # Result should have given prefix
{
$result= -1 if (length($row->[0]) < length($answer) &&
- substring($row->[0],1,length($answer)) ne $answer);
+ substr($row->[0],1,length($answer)) ne $answer);
}
elsif ($result_type == 6) # Exact match but ignore errors
{
@@ -2760,6 +2786,8 @@ sub find_limit()
print "$end (cache)\n";
return $end;
}
+ save_incomplete($limit,$prompt);
+
if (defined($query->{'init'}) && !defined($end=$limits{'restart'}{'tohigh'}))
{
if (!safe_query($query->{'init'}))
@@ -2932,6 +2960,16 @@ sub save_all_config_data
close CONFIG_FILE;
}
+#
+# Save 'incomplete' in the limits file to be able to continue if
+# crash-me dies because of a bug in perl/DBI
+
+sub save_incomplete
+{
+ my ($limit,$prompt)= @_;
+ save_config_data($limit,"incompleted",$prompt) if ($opt_restart);
+}
+
sub check_repeat
{
diff --git a/sql-bench/limits/db2.cfg b/sql-bench/limits/db2.cfg
index 31280fbe643..5b2c0e172e7 100644
--- a/sql-bench/limits/db2.cfg
+++ b/sql-bench/limits/db2.cfg
@@ -1,34 +1,68 @@
-#This file is automaticly generated by crash-me 1.19a
+#This file is automaticly generated by crash-me 1.57
NEG=yes # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=no # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
alter_change_col=no # Alter table change column
alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=drop primary key # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
alter_modify_col=no # Alter table modify column
alter_rename_table=no # Alter table rename table
atomic_updates=yes # atomic updates
atomic_updates_with_rollback=yes # atomic_updates_with_rollback
-binary_items=no # binary items (0x41)
-case_insensitive_strings=no # case insensitive compare
-char_is_space_filled=no # char are space filled
+automatic_rowid=no # Automatic row id
+binary_numbers=no # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
column_alias=yes # Column alias
+columns_in_group_by=+64 # number of columns in group by
+columns_in_order_by=+64 # number of columns in order by
comment_#=no # # as comment
-comment_--=yes # -- as comment
+comment_--=yes # -- as comment (ANSI)
comment_/**/=no # /* */ as comment
+comment_//=no # // as comment
compute=no # Compute
-connections=125 # Simultaneous connections
+connections=40 # Simultaneous connections (installation default)
+constraint_check=yes # Column constraints
+constraint_check_table=yes # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
crash_me_safe=no # crash me safe
-crash_me_version=1.19a # crash me version
+crash_me_version=1.57 # crash me version
create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
cross_join=no # cross join (same as from a,b)
date_as_string=no # String functions on date columns
+date_infinity=no # Supports 'infinity dates
+date_last=no # Supports 9999-12-31 dates
+date_one=no # Supports 0001-01-01 dates
date_with_YY=no # Supports YY-MM-DD dates
date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+dont_require_cast_to_float=yes # No need to cast from integer to float
double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
except=yes # except
except_all=yes # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
float_int_expr=yes # mixing of integer and float in expression
foreign_key=yes # foreign keys
foreign_key_syntax=yes # foreign key syntax
@@ -41,6 +75,8 @@ func_extra_<>=no # Function <> in SELECT
func_extra_==no # Function =
func_extra_add_months=no # Function ADD_MONTHS
func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
func_extra_atn2=no # Function ATN2
func_extra_auto_num2string=no # Function automatic num->string convert
func_extra_auto_string2num=no # Function automatic string->num convert
@@ -72,6 +108,7 @@ func_extra_in_num=no # Function IN on numbers in SELECT
func_extra_in_str=no # Function IN on strings in SELECT
func_extra_initcap=no # Function INITCAP
func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
func_extra_instrb=no # Function INSTRB
func_extra_interval=no # Function INTERVAL
func_extra_last_day=no # Function LAST_DAY
@@ -84,16 +121,15 @@ func_extra_ln=yes # Function LN
func_extra_log(m_n)=no # Function LOG(m,n)
func_extra_logn=no # Function LOGN
func_extra_lpad=no # Function LPAD
-func_extra_max_num=no # Function MAX on numbers
func_extra_mdy=no # Function MDY
func_extra_mid=no # Function SUBSTRING as MID
-func_extra_min_num=no # Function MIN on numbers
func_extra_months_between=no # Function MONTHS_BETWEEN
func_extra_not=no # Function NOT in SELECT
func_extra_not_between=no # Function NOT BETWEEN in SELECT
func_extra_not_like=no # Function NOT LIKE in SELECT
func_extra_odbc_convert=no # Function ODBC CONVERT
func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
func_extra_patindex=no # Function PATINDEX
func_extra_period_add=no # Function PERIOD_ADD
func_extra_period_diff=no # Function PERIOD_DIFF
@@ -112,6 +148,8 @@ func_extra_strcmp=no # Function STRCMP
func_extra_stuff=no # Function STUFF
func_extra_substrb=no # Function SUBSTRB
func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
func_extra_tanh=no # Function TANH
func_extra_time_to_sec=no # Function TIME_TO_SEC
func_extra_to_days=no # Function TO_DAYS
@@ -126,6 +164,7 @@ func_extra_version=no # Function VERSION
func_extra_weekday=no # Function WEEKDAY
func_extra_|=no # Function | (bitwise or)
func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
func_odbc_abs=yes # Function ABS
func_odbc_acos=yes # Function ACOS
func_odbc_ascii=yes # Function ASCII
@@ -133,31 +172,30 @@ func_odbc_asin=yes # Function ASIN
func_odbc_atan=yes # Function ATAN
func_odbc_atan2=error # Function ATAN2
func_odbc_ceiling=yes # Function CEILING
-func_odbc_char=error # Function CHAR
+func_odbc_char=yes # Function CHAR
func_odbc_concat=yes # Function CONCAT(2 arg)
func_odbc_cos=yes # Function COS
func_odbc_cot=yes # Function COT
-func_odbc_curdate=no # Function CURDATE
-func_odbc_curtime=no # Function CURTIME
-func_odbc_database=no # Function DATABASE
-func_odbc_dayname=no # Function DAYNAME
-func_odbc_dayofmonth=no # Function DAYOFMONTH
-func_odbc_dayofweek=no # Function DAYOFWEEK
-func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_curdate=yes # Function CURDATE
+func_odbc_curtime=yes # Function CURTIME
+func_odbc_database=yes # Function DATABASE
+func_odbc_dayname=yes # Function DAYNAME
+func_odbc_dayofmonth=yes # Function DAYOFMONTH
+func_odbc_dayofweek=yes # Function DAYOFWEEK
+func_odbc_dayofyear=yes # Function DAYOFYEAR
func_odbc_degrees=yes # Function DEGREES
func_odbc_difference=yes # Function DIFFERENCE()
func_odbc_exp=yes # Function EXP
-func_odbc_extract=no # Function EXTRACT
func_odbc_floor=yes # Function FLOOR
func_odbc_fn_left=yes # Function ODBC syntax LEFT & RIGHT
func_odbc_hour=yes # Function HOUR
-func_odbc_hour_time=no # Function ANSI HOUR
-func_odbc_ifnull=no # Function IFNULL
+func_odbc_hour_time=yes # Function ANSI HOUR
+func_odbc_ifnull=yes # Function IFNULL
func_odbc_insert=yes # Function INSERT
func_odbc_lcase=yes # Function LCASE
func_odbc_left=yes # Function LEFT
func_odbc_length=yes # Function REAL LENGTH
-func_odbc_length_without_space=error # Function ODBC LENGTH
+func_odbc_length_without_space=yes # Function ODBC LENGTH
func_odbc_locate_2=yes # Function LOCATE(2 arg)
func_odbc_locate_3=yes # Function LOCATE(3 arg)
func_odbc_log=yes # Function LOG
@@ -165,12 +203,12 @@ func_odbc_log10=yes # Function LOG10
func_odbc_ltrim=yes # Function LTRIM
func_odbc_minute=yes # Function MINUTE
func_odbc_mod=yes # Function MOD
-func_odbc_month=no # Function MONTH
-func_odbc_monthname=no # Function MONTHNAME
-func_odbc_now=no # Function NOW
-func_odbc_pi=no # Function PI
+func_odbc_month=yes # Function MONTH
+func_odbc_monthname=yes # Function MONTHNAME
+func_odbc_now=yes # Function NOW
+func_odbc_pi=yes # Function PI
func_odbc_power=yes # Function POWER
-func_odbc_quarter=no # Function QUARTER
+func_odbc_quarter=yes # Function QUARTER
func_odbc_radians=yes # Function RADIANS
func_odbc_rand=yes # Function RAND
func_odbc_repeat=yes # Function REPEAT
@@ -184,38 +222,43 @@ func_odbc_sin=yes # Function SIN
func_odbc_soundex=yes # Function SOUNDEX
func_odbc_space=yes # Function SPACE
func_odbc_sqrt=yes # Function SQRT
-func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_substring=yes # Function ODBC SUBSTRING
func_odbc_tan=yes # Function TAN
func_odbc_timestampadd=no # Function TIMESTAMPADD
func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
func_odbc_truncate=yes # Function TRUNCATE
-func_odbc_ucase=no # Function UCASE
-func_odbc_user=yes # Function USER
-func_odbc_user()=no # Function USER()
-func_odbc_week=no # Function WEEK
-func_odbc_year=no # Function YEAR
+func_odbc_ucase=yes # Function UCASE
+func_odbc_user()=yes # Function USER()
+func_odbc_week=yes # Function WEEK
+func_odbc_year=yes # Function YEAR
func_sql_+=yes # Function +, -, * and /
func_sql_bit_length=no # Function BIT_LENGTH
-func_sql_case=yes # Function CASE
func_sql_cast=yes # Function CAST
func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
func_sql_concat_as_||=yes # Function concatenation with ||
func_sql_current_date=no # Function CURRENT_DATE
-func_sql_current_date()=no # Function CURRENT_DATE()
func_sql_current_time=no # Function CURRENT_TIME
-func_sql_current_time()=no # Function CURRENT_TIME()
func_sql_current_timestamp=no # Function CURRENT_TIMESTAMP
-func_sql_current_timestamp()=no # Function CURRENT_TIMESTAMP()
-func_sql_lower=no # Function LOWER
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=no # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=yes # Function LOWER
+func_sql_nullif_num=yes # Function NULLIF with numbers
+func_sql_nullif_string=yes # Function NULLIF with strings
func_sql_octet_length=no # Function OCTET_LENGTH
func_sql_position=no # Function POSITION
+func_sql_searched_case=yes # Function searched CASE
func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=yes # Function simple CASE
func_sql_substring=no # Function ANSI SQL SUBSTRING
-func_extra_sysdate=no # Function SYSDATE
func_sql_system_user=no # Function SYSTEM_USER
func_sql_trim=no # Function TRIM
-func_sql_upper=no # Function UPPER
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
func_where_between=yes # Function BETWEEN
func_where_eq_all=yes # Function = ALL
func_where_eq_any=yes # Function = ANY
@@ -235,36 +278,49 @@ func_where_unique=no # Function UNIQUE
functions=yes # Functions
group_by=yes # Group by
group_by_alias=no # Group by alias
-group_by_null=yes # Test nulls in group by
+group_by_null=yes # Group on column with null values
group_by_position=no # Group by position
group_distinct_functions=yes # Group functions with distinct
group_func_extra_bit_and=no # Group function BIT_AND
group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
group_func_extra_std=no # Group function STD
group_func_extra_stddev=yes # Group function STDDEV
group_func_extra_variance=yes # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
group_func_sql_avg=yes # Group function AVG
group_func_sql_count_*=yes # Group function COUNT (*)
group_func_sql_count_column=yes # Group function COUNT column name
-group_func_sql_count_distinct=yes # Group function COUNT DISTINCT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
group_func_sql_max=yes # Group function MAX on numbers
group_func_sql_max_str=yes # Group function MAX on strings
group_func_sql_min=yes # Group function MIN on numbers
group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
group_func_sql_sum=yes # Group function SUM
group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
having=yes # Having
having_with_alias=no # Having on alias
having_with_group=yes # Having with group function
-ignore_end_space=yes # ignore end space in compare
+hex_numbers=no # hex numbers (0x41)
+hex_strings=yes # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
index_in_create=no # index in create table
index_namespace=no # different namespace for index
index_parts=no # index on column part (extension)
+inner_join=yes # inner join
insert_empty_string=yes # insert empty string
+insert_multi_value=yes # INSERT with Value lists
insert_select=yes # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
intersect=yes # intersect
intersect_all=yes # intersect all
-join_tables=+64 # tables in join
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=10 # tables in join
left_outer_join=yes # left outer join
left_outer_join_using=no # left outer join using
like_with_column=no # column LIKE column
@@ -273,150 +329,194 @@ lock_tables=yes # lock table
logical_value=not supported # Value of logical operation (1=1)
max_big_expressions=1 # big expressions
max_char_size=254 # max char() size
-max_column_name=18 # column name length
+max_column_name=30 # column name length
max_columns=500 # Columns in table
-max_conditions=418 # OR and AND in WHERE
-max_expressions=9820 # simple expressions
+max_conditions=2082 # OR and AND in WHERE
+max_expressions=9543 # simple expressions
max_index=+64 # max index
-max_index_length=255 # index length
+max_index_length=1024 # index length
max_index_name=18 # index name length
max_index_part_length=254 # max index part length
-max_index_parts=15 # index parts
-max_index_varchar_part_length=251 # index varchar part length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=255 # index varchar part length
max_row_length=4005 # max table row length (without blobs)
max_row_length_with_null=3989 # table row length with nulls (without blobs)
-max_select_alias_name=18 # select alias name length
+max_select_alias_name=30 # select alias name length
max_stack_expression=1363 # stacked expressions
-max_table_alias_name=18 # table alias name length
-max_table_name=18 # table name length
+max_table_alias_name=128 # table alias name length
+max_table_name=128 # table name length
max_unique_index=+64 # unique indexes
max_varchar_size=4000 # max varchar() size
minus=no # minus
+minus_incompat=no # minus (incompatible lists)
minus_neg=no # Calculate 1--1
multi_drop=no # many tables to drop table
multi_strings=no # Multiple line strings
multi_table_delete=no # DELETE FROM table1,table2...
multi_table_update=no # Update with many tables
natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
natural_left_outer_join=no # natural left outer join
no_primary_key=yes # Tables without primary key
null_concat_expr=no # Is 'a' || NULL = NULL
null_in_index=yes # null in index
-null_in_unique=no # null in unique
+null_in_unique=no # null in unique index
null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
odbc_left_outer_join=yes # left outer join odbc style
-operating_system=Windows NT Version 4.0 # crash-me tested on
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
order_by=yes # Order by
order_by_alias=yes # Order by alias
+order_by_function=yes # Order by function
order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
primary_key_in_create=yes # primary key in create table
-query_size=19662 # query size
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=65535 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
quote_with_"=no # Allows ' and " as string markers
-recursive_subqueries=22 # recursive subqueries
+recursive_subqueries=8 # recursive subqueries
remember_end_space=no # Remembers end space in char()
remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=yes # rename table
repeat_string_size=4000 # return string size from function
right_outer_join=yes # right outer join
+rowid=no # Type for row id
select_constants=yes # Select constants
-select_string_size=4000 # constant string size in SELECT
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32672 # constant string size in SELECT
select_table_update=yes # Update with sub select
select_without_from=no # SELECT without FROM
-server_version=IBM DB2 5 # server version
+server_version=IBM DB2 7.2 # server version
simple_joins=yes # ANSI SQL simple joins
+storage_of_float=truncate # Storage of float values
subqueries=yes # subqueries
table_alias=yes # Table alias
+table_name_case=yes # case independent table names
table_wildcard=yes # Select table_name.*
-transactions=yes # transactions
+temporary_table=no # temporary tables
+transactions=yes # constant string size in where
+truncate_table=no # truncate
type_extra_abstime=no # Type abstime
type_extra_bfile=no # Type bfile
type_extra_blob=no # Type blob
type_extra_bool=no # Type bool
type_extra_box=no # Type box
type_extra_byte=no # Type byte
-type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
-type_extra_char16=no # Type char16
-type_extra_char2=no # Type char2
-type_extra_char4=no # Type char4
-type_extra_char8=no # Type char8
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
type_extra_circle=no # Type circle
type_extra_clob=no # Type clob
type_extra_datetime=no # Type datetime
-type_extra_enum(1_arg)=no # Type enum(1 arg)
-type_sql_float(1_arg)=yes # Type float(1 arg)
+type_extra_double=yes # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
type_extra_float4=no # Type float4
type_extra_float8=no # Type float8
type_extra_image=no # Type image
-type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
type_extra_int1=no # Type int1
type_extra_int2=no # Type int2
type_extra_int3=no # Type int3
type_extra_int4=no # Type int4
type_extra_int8=no # Type int8
type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
type_extra_line=no # Type line
type_extra_long=no # Type long
type_extra_long_raw=no # Type long raw
type_extra_long_varbinary=no # Type long varbinary
-type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
type_extra_mediumint=no # Type mediumint
type_extra_mediumtext=no # Type mediumtext
type_extra_middleint=no # Type middleint
type_extra_mlslabel=no # Type mlslabel
type_extra_money=no # Type money
-type_sql_nchar(1_arg)=no # Type nchar(1 arg)
type_extra_nclob=no # Type nclob
type_extra_number=no # Type number
-type_extra_number(1_arg)=no # Type number(1 arg)
-type_extra_nvarchar(2_arg)=no # Type nvarchar(2 arg)
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
type_extra_path=no # Type path
type_extra_point=no # Type point
type_extra_polygon=no # Type polygon
-type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_raw(1_arg)=no # Type raw(1 arg)
type_extra_reltime=no # Type reltime
type_extra_rowid=no # Type rowid
type_extra_serial=no # Type serial
-type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_set(1_arg)=no # Type set(1 arg)
type_extra_smalldatetime=no # Type smalldatetime
type_extra_smallfloat=no # Type smallfloat
type_extra_smallmoney=no # Type smallmoney
type_extra_text=no # Type text
-type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_text(1_arg)=no # Type text(1 arg)
type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
type_extra_year=no # Type year
-type_odbc_bigint=no # Type bigint
-type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_bigint=yes # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
type_odbc_datetime=no # Type datetime
-type_sql_smallint=yes # Type smallint
type_odbc_tinyint=no # Type tinyint
type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
type_sql_bit=no # Type bit
type_sql_bit(1_arg)=no # Type bit(1 arg)
type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
-type_sql_char(1_arg)=yes # Type char(1 arg)
-type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
type_sql_character(1_arg)=yes # Type character(1 arg)
type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
type_sql_date=yes # Type date
type_sql_dec(2_arg)=yes # Type dec(2 arg)
-type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
-type_extra_double=yes # Type double
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
type_sql_double_precision=yes # Type double precision
type_sql_float=yes # Type float
-type_extra_float(2_arg)=no # Type float(1 arg)
+type_sql_float(1_arg)=yes # Type float(1 arg)
type_sql_int=yes # Type int
type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
type_sql_interval_year=no # Type interval year
-type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=no # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=no # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=no # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=no # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=no # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
type_sql_time=yes # Type time
type_sql_timestamp=yes # Type timestamp
-type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
union=yes # union
union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
unique_in_create=yes # unique in create table
unique_null_in_create=no # unique null in create
views=yes # views
-where_string_size=4000 # constant string size in where
+where_string_size=32672 # constant string size in where
diff --git a/sql-bench/limits/interbase-dialect1.cfg b/sql-bench/limits/interbase-dialect1.cfg
new file mode 100644
index 00000000000..046627be513
--- /dev/null
+++ b/sql-bench/limits/interbase-dialect1.cfg
@@ -0,0 +1,514 @@
+#This file is automaticly generated by crash-me 1.57
+
+NEG=no # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
+alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=with add # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
+alter_change_col=no # Alter table change column
+alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=no # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
+alter_modify_col=no # Alter table modify column
+alter_rename_table=no # Alter table rename table
+atomic_updates=no # atomic updates
+automatic_rowid=no # Automatic row id
+binary_numbers=yes # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
+column_alias=yes # Column alias
+columns_in_order_by=37 # number of columns in order by
+comment_#=no # # as comment
+comment_--=no # -- as comment (ANSI)
+comment_/**/=yes # /* */ as comment
+comment_//=no # // as comment
+compute=no # Compute
+connections=1000 # Simultaneous connections (installation default)
+constraint_check=no # Column constraints
+constraint_check_table=no # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
+crash_me_safe=yes # crash me safe
+crash_me_version=1.57 # crash me version
+create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
+create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
+cross_join=no # cross join (same as from a,b)
+date_infinity=no # Supports 'infinity dates
+date_last=no # Supports 9999-12-31 dates
+date_one=no # Supports 0001-01-01 dates
+date_with_YY=no # Supports YY-MM-DD dates
+date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
+drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
+except=no # except
+except_all=no # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
+float_int_expr=yes # mixing of integer and float in expression
+foreign_key_syntax=no # foreign key syntax
+full_outer_join=yes # full outer join
+func_extra_!=no # Function NOT as '!' in SELECT
+func_extra_%=no # Function MOD as %
+func_extra_&=no # Function & (bitwise and)
+func_extra_&&=no # Function AND as '&&'
+func_extra_<>=no # Function <> in SELECT
+func_extra_==no # Function =
+func_extra_add_months=no # Function ADD_MONTHS
+func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
+func_extra_atn2=no # Function ATN2
+func_extra_auto_num2string=no # Function automatic num->string convert
+func_extra_auto_string2num=no # Function automatic string->num convert
+func_extra_between=no # Function BETWEEN in SELECT
+func_extra_binary_shifts=no # Function << and >> (bitwise shifts)
+func_extra_bit_count=no # Function BIT_COUNT
+func_extra_ceil=no # Function CEIL
+func_extra_charindex=no # Function CHARINDEX
+func_extra_chr=no # Function CHR
+func_extra_concat_as_+=no # Function concatenation with +
+func_extra_concat_list=no # Function CONCAT(list)
+func_extra_convert=no # Function CONVERT
+func_extra_cosh=no # Function COSH
+func_extra_date_format=no # Function DATE_FORMAT
+func_extra_dateadd=no # Function DATEADD
+func_extra_datediff=no # Function DATEDIFF
+func_extra_datename=no # Function DATENAME
+func_extra_datepart=no # Function DATEPART
+func_extra_elt=no # Function ELT
+func_extra_encrypt=no # Function ENCRYPT
+func_extra_field=no # Function FIELD
+func_extra_format=no # Function FORMAT
+func_extra_from_days=no # Function FROM_DAYS
+func_extra_from_unixtime=no # Function FROM_UNIXTIME
+func_extra_getdate=no # Function GETDATE
+func_extra_greatest=no # Function GREATEST
+func_extra_if=no # Function IF
+func_extra_in_num=no # Function IN on numbers in SELECT
+func_extra_in_str=no # Function IN on strings in SELECT
+func_extra_initcap=no # Function INITCAP
+func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
+func_extra_instrb=no # Function INSTRB
+func_extra_interval=no # Function INTERVAL
+func_extra_last_day=no # Function LAST_DAY
+func_extra_last_insert_id=no # Function LAST_INSERT_ID
+func_extra_least=no # Function LEAST
+func_extra_lengthb=no # Function LENGTHB
+func_extra_like=no # Function LIKE in SELECT
+func_extra_like_escape=no # Function LIKE ESCAPE in SELECT
+func_extra_ln=no # Function LN
+func_extra_log(m_n)=no # Function LOG(m,n)
+func_extra_logn=no # Function LOGN
+func_extra_lpad=no # Function LPAD
+func_extra_mdy=no # Function MDY
+func_extra_mid=no # Function SUBSTRING as MID
+func_extra_months_between=no # Function MONTHS_BETWEEN
+func_extra_not=no # Function NOT in SELECT
+func_extra_not_between=no # Function NOT BETWEEN in SELECT
+func_extra_not_like=no # Function NOT LIKE in SELECT
+func_extra_odbc_convert=no # Function ODBC CONVERT
+func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
+func_extra_patindex=no # Function PATINDEX
+func_extra_period_add=no # Function PERIOD_ADD
+func_extra_period_diff=no # Function PERIOD_DIFF
+func_extra_pow=no # Function POW
+func_extra_range=no # Function RANGE
+func_extra_regexp=no # Function REGEXP in SELECT
+func_extra_replicate=no # Function REPLICATE
+func_extra_reverse=no # Function REVERSE
+func_extra_root=no # Function ROOT
+func_extra_round1=no # Function ROUND(1 arg)
+func_extra_rpad=no # Function RPAD
+func_extra_sec_to_time=no # Function SEC_TO_TIME
+func_extra_sinh=no # Function SINH
+func_extra_str=no # Function STR
+func_extra_strcmp=no # Function STRCMP
+func_extra_stuff=no # Function STUFF
+func_extra_substrb=no # Function SUBSTRB
+func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
+func_extra_tanh=no # Function TANH
+func_extra_time_to_sec=no # Function TIME_TO_SEC
+func_extra_to_days=no # Function TO_DAYS
+func_extra_translate=no # Function TRANSLATE
+func_extra_trim_many_char=no # Function TRIM; Many char extension
+func_extra_trim_substring=no # Function TRIM; Substring extension
+func_extra_trunc=no # Function TRUNC
+func_extra_uid=no # Function UID
+func_extra_unix_timestamp=no # Function UNIX_TIMESTAMP
+func_extra_userenv=no # Function USERENV
+func_extra_version=no # Function VERSION
+func_extra_weekday=no # Function WEEKDAY
+func_extra_|=no # Function | (bitwise or)
+func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
+func_odbc_abs=no # Function ABS
+func_odbc_acos=no # Function ACOS
+func_odbc_ascii=no # Function ASCII
+func_odbc_asin=no # Function ASIN
+func_odbc_atan=no # Function ATAN
+func_odbc_atan2=no # Function ATAN2
+func_odbc_ceiling=no # Function CEILING
+func_odbc_char=no # Function CHAR
+func_odbc_concat=no # Function CONCAT(2 arg)
+func_odbc_cos=no # Function COS
+func_odbc_cot=no # Function COT
+func_odbc_curdate=no # Function CURDATE
+func_odbc_curtime=no # Function CURTIME
+func_odbc_database=no # Function DATABASE
+func_odbc_dayname=no # Function DAYNAME
+func_odbc_dayofmonth=no # Function DAYOFMONTH
+func_odbc_dayofweek=no # Function DAYOFWEEK
+func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_degrees=no # Function DEGREES
+func_odbc_difference=no # Function DIFFERENCE()
+func_odbc_exp=no # Function EXP
+func_odbc_floor=no # Function FLOOR
+func_odbc_fn_left=no # Function ODBC syntax LEFT & RIGHT
+func_odbc_hour=no # Function HOUR
+func_odbc_hour_time=no # Function ANSI HOUR
+func_odbc_ifnull=no # Function IFNULL
+func_odbc_insert=no # Function INSERT
+func_odbc_lcase=no # Function LCASE
+func_odbc_left=no # Function LEFT
+func_odbc_length=no # Function REAL LENGTH
+func_odbc_length_without_space=no # Function ODBC LENGTH
+func_odbc_locate_2=no # Function LOCATE(2 arg)
+func_odbc_locate_3=no # Function LOCATE(3 arg)
+func_odbc_log=no # Function LOG
+func_odbc_log10=no # Function LOG10
+func_odbc_ltrim=no # Function LTRIM
+func_odbc_minute=no # Function MINUTE
+func_odbc_mod=no # Function MOD
+func_odbc_month=no # Function MONTH
+func_odbc_monthname=no # Function MONTHNAME
+func_odbc_now=no # Function NOW
+func_odbc_pi=no # Function PI
+func_odbc_power=no # Function POWER
+func_odbc_quarter=no # Function QUARTER
+func_odbc_radians=no # Function RADIANS
+func_odbc_rand=no # Function RAND
+func_odbc_repeat=no # Function REPEAT
+func_odbc_replace=no # Function REPLACE
+func_odbc_right=no # Function RIGHT
+func_odbc_round=no # Function ROUND(2 arg)
+func_odbc_rtrim=no # Function RTRIM
+func_odbc_second=no # Function SECOND
+func_odbc_sign=no # Function SIGN
+func_odbc_sin=no # Function SIN
+func_odbc_soundex=no # Function SOUNDEX
+func_odbc_space=no # Function SPACE
+func_odbc_sqrt=no # Function SQRT
+func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_tan=no # Function TAN
+func_odbc_timestampadd=no # Function TIMESTAMPADD
+func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
+func_odbc_truncate=no # Function TRUNCATE
+func_odbc_ucase=no # Function UCASE
+func_odbc_user()=no # Function USER()
+func_odbc_week=no # Function WEEK
+func_odbc_year=no # Function YEAR
+func_sql_+=yes # Function +, -, * and /
+func_sql_bit_length=no # Function BIT_LENGTH
+func_sql_cast=yes # Function CAST
+func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
+func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
+func_sql_concat_as_||=yes # Function concatenation with ||
+func_sql_current_date=no # Function CURRENT_DATE
+func_sql_current_time=no # Function CURRENT_TIME
+func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=yes # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=no # Function LOWER
+func_sql_nullif_num=no # Function NULLIF with numbers
+func_sql_nullif_string=no # Function NULLIF with strings
+func_sql_octet_length=no # Function OCTET_LENGTH
+func_sql_position=no # Function POSITION
+func_sql_searched_case=no # Function searched CASE
+func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=no # Function simple CASE
+func_sql_substring=no # Function ANSI SQL SUBSTRING
+func_sql_system_user=no # Function SYSTEM_USER
+func_sql_trim=no # Function TRIM
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
+func_where_between=yes # Function BETWEEN
+func_where_eq_all=yes # Function = ALL
+func_where_eq_any=yes # Function = ANY
+func_where_eq_some=yes # Function = SOME
+func_where_exists=yes # Function EXISTS
+func_where_in_num=yes # Function IN on numbers
+func_where_like=yes # Function LIKE
+func_where_like_escape=yes # Function LIKE ESCAPE
+func_where_match=no # Function MATCH
+func_where_match_unique=no # Function MATCH UNIQUE
+func_where_matches=no # Function MATCHES
+func_where_not_between=yes # Function NOT BETWEEN
+func_where_not_exists=yes # Function NOT EXISTS
+func_where_not_like=yes # Function NOT LIKE
+func_where_not_unique=no # Function NOT UNIQUE
+func_where_unique=no # Function UNIQUE
+functions=yes # Functions
+group_by=yes # Group by
+group_by_alias=no # Group by alias
+group_by_null=yes # Group on column with null values
+group_by_position=no # Group by position
+group_distinct_functions=yes # Group functions with distinct
+group_func_extra_bit_and=no # Group function BIT_AND
+group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
+group_func_extra_std=no # Group function STD
+group_func_extra_stddev=no # Group function STDDEV
+group_func_extra_variance=no # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
+group_func_sql_avg=yes # Group function AVG
+group_func_sql_count_*=yes # Group function COUNT (*)
+group_func_sql_count_column=yes # Group function COUNT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
+group_func_sql_max=yes # Group function MAX on numbers
+group_func_sql_max_str=yes # Group function MAX on strings
+group_func_sql_min=yes # Group function MIN on numbers
+group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
+group_func_sql_sum=yes # Group function SUM
+group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
+having=yes # Having
+having_with_alias=no # Having on alias
+having_with_group=yes # Having with group function
+hex_numbers=yes # hex numbers (0x41)
+hex_strings=no # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
+index_in_create=no # index in create table
+index_namespace=no # different namespace for index
+index_parts=no # index on column part (extension)
+inner_join=yes # inner join
+insert_empty_string=no # insert empty string
+insert_multi_value=no # INSERT with Value lists
+insert_select=no # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
+intersect=no # intersect
+intersect_all=no # intersect all
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=+64 # tables in join
+left_outer_join=yes # left outer join
+left_outer_join_using=no # left outer join using
+like_with_column=no # column LIKE column
+like_with_number=no # LIKE on numbers
+lock_tables=no # lock table
+logical_value=not supported # Value of logical operation (1=1)
+max_big_expressions=1 # big expressions
+max_char_size=32767 # max char() size
+max_column_name=18 # column name length
+max_columns=4759 # Columns in table
+max_conditions=2944 # OR and AND in WHERE
+max_expressions=+10000 # simple expressions
+max_index=+64 # max index
+max_index_name=31 # index name length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=249 # index varchar part length
+max_row_length=64744 # max table row length (without blobs)
+max_row_length_with_null=64744 # table row length with nulls (without blobs)
+max_select_alias_name=132 # select alias name length
+max_stack_expression=165 # stacked expressions
+max_table_alias_name=255 # table alias name length
+max_table_name=31 # table name length
+max_unique_index=+64 # unique indexes
+max_varchar_size=10923 # max varchar() size
+minus=no # minus
+minus_incompat=no # minus (incompatible lists)
+minus_neg=yes # Calculate 1--1
+multi_drop=no # many tables to drop table
+multi_strings=no # Multiple line strings
+multi_table_delete=no # DELETE FROM table1,table2...
+multi_table_update=no # Update with many tables
+natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
+natural_left_outer_join=no # natural left outer join
+no_primary_key=yes # Tables without primary key
+null_concat_expr=no # Is 'a' || NULL = NULL
+null_in_index=yes # null in index
+null_in_unique=no # null in unique index
+null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
+odbc_left_outer_join=no # left outer join odbc style
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
+order_by=yes # Order by
+order_by_alias=no # Order by alias
+order_by_function=no # Order by function
+order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
+primary_key_in_create=yes # primary key in create table
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=65535 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
+quote_with_"=no # Allows ' and " as string markers
+recursive_subqueries=61 # recursive subqueries
+remember_end_space=no # Remembers end space in char()
+remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=no # rename table
+right_outer_join=yes # right outer join
+rowid=no # Type for row id
+select_constants=yes # Select constants
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32767 # constant string size in SELECT
+select_table_update=yes # Update with sub select
+select_without_from=no # SELECT without FROM
+server_version=6.0.1 # server version
+simple_joins=yes # ANSI SQL simple joins
+storage_of_float=round # Storage of float values
+subqueries=yes # subqueries
+table_alias=no # Table alias
+table_name_case=yes # case independent table names
+table_wildcard=yes # Select table_name.*
+temporary_table=no # temporary tables
+transactions=error # constant string size in where
+truncate_table=no # truncate
+type_extra_abstime=no # Type abstime
+type_extra_bfile=no # Type bfile
+type_extra_blob=yes # Type blob
+type_extra_bool=no # Type bool
+type_extra_box=no # Type box
+type_extra_byte=no # Type byte
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
+type_extra_circle=no # Type circle
+type_extra_clob=no # Type clob
+type_extra_datetime=no # Type datetime
+type_extra_double=no # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
+type_extra_float4=no # Type float4
+type_extra_float8=no # Type float8
+type_extra_image=no # Type image
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_int1=no # Type int1
+type_extra_int2=no # Type int2
+type_extra_int3=no # Type int3
+type_extra_int4=no # Type int4
+type_extra_int8=no # Type int8
+type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
+type_extra_line=no # Type line
+type_extra_long=no # Type long
+type_extra_long_raw=no # Type long raw
+type_extra_long_varbinary=no # Type long varbinary
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
+type_extra_mediumint=no # Type mediumint
+type_extra_mediumtext=no # Type mediumtext
+type_extra_middleint=no # Type middleint
+type_extra_mlslabel=no # Type mlslabel
+type_extra_money=no # Type money
+type_extra_nclob=no # Type nclob
+type_extra_number=no # Type number
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
+type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
+type_extra_path=no # Type path
+type_extra_point=no # Type point
+type_extra_polygon=no # Type polygon
+type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_reltime=no # Type reltime
+type_extra_rowid=no # Type rowid
+type_extra_serial=no # Type serial
+type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_smalldatetime=no # Type smalldatetime
+type_extra_smallfloat=no # Type smallfloat
+type_extra_smallmoney=no # Type smallmoney
+type_extra_text=no # Type text
+type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
+type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
+type_extra_year=no # Type year
+type_odbc_bigint=no # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_datetime=no # Type datetime
+type_odbc_tinyint=no # Type tinyint
+type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
+type_sql_bit=no # Type bit
+type_sql_bit(1_arg)=no # Type bit(1 arg)
+type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_character(1_arg)=yes # Type character(1 arg)
+type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
+type_sql_date=no # Type date
+type_sql_dec(2_arg)=yes # Type dec(2 arg)
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
+type_sql_double_precision=yes # Type double precision
+type_sql_float=yes # Type float
+type_sql_float(1_arg)=yes # Type float(1 arg)
+type_sql_int=yes # Type int
+type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
+type_sql_interval_year=no # Type interval year
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=yes # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=yes # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
+type_sql_time=no # Type time
+type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+union=yes # union
+union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
+unique_in_create=yes # unique in create table
+unique_null_in_create=no # unique null in create
+views=no # views
+where_string_size=32767 # constant string size in where
diff --git a/sql-bench/limits/interbase-dialect3.cfg b/sql-bench/limits/interbase-dialect3.cfg
new file mode 100644
index 00000000000..fdc93098688
--- /dev/null
+++ b/sql-bench/limits/interbase-dialect3.cfg
@@ -0,0 +1,514 @@
+#This file is automaticly generated by crash-me 1.57
+
+NEG=no # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
+alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=with add # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
+alter_change_col=no # Alter table change column
+alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=no # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
+alter_modify_col=no # Alter table modify column
+alter_rename_table=no # Alter table rename table
+atomic_updates=no # atomic updates
+automatic_rowid=no # Automatic row id
+binary_numbers=yes # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
+column_alias=yes # Column alias
+columns_in_order_by=37 # number of columns in order by
+comment_#=no # # as comment
+comment_--=no # -- as comment (ANSI)
+comment_/**/=yes # /* */ as comment
+comment_//=no # // as comment
+compute=no # Compute
+connections=1000 # Simultaneous connections (installation default)
+constraint_check=no # Column constraints
+constraint_check_table=no # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
+crash_me_safe=yes # crash me safe
+crash_me_version=1.57 # crash me version
+create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
+create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
+cross_join=no # cross join (same as from a,b)
+date_infinity=no # Supports 'infinity dates
+date_last=error # Supports 9999-12-31 dates
+date_one=error # Supports 0001-01-01 dates
+date_with_YY=no # Supports YY-MM-DD dates
+date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
+drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
+except=no # except
+except_all=no # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
+float_int_expr=yes # mixing of integer and float in expression
+foreign_key_syntax=no # foreign key syntax
+full_outer_join=yes # full outer join
+func_extra_!=no # Function NOT as '!' in SELECT
+func_extra_%=no # Function MOD as %
+func_extra_&=no # Function & (bitwise and)
+func_extra_&&=no # Function AND as '&&'
+func_extra_<>=no # Function <> in SELECT
+func_extra_==no # Function =
+func_extra_add_months=no # Function ADD_MONTHS
+func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
+func_extra_atn2=no # Function ATN2
+func_extra_auto_num2string=no # Function automatic num->string convert
+func_extra_auto_string2num=no # Function automatic string->num convert
+func_extra_between=no # Function BETWEEN in SELECT
+func_extra_binary_shifts=no # Function << and >> (bitwise shifts)
+func_extra_bit_count=no # Function BIT_COUNT
+func_extra_ceil=no # Function CEIL
+func_extra_charindex=no # Function CHARINDEX
+func_extra_chr=no # Function CHR
+func_extra_concat_as_+=no # Function concatenation with +
+func_extra_concat_list=no # Function CONCAT(list)
+func_extra_convert=no # Function CONVERT
+func_extra_cosh=no # Function COSH
+func_extra_date_format=no # Function DATE_FORMAT
+func_extra_dateadd=no # Function DATEADD
+func_extra_datediff=no # Function DATEDIFF
+func_extra_datename=no # Function DATENAME
+func_extra_datepart=no # Function DATEPART
+func_extra_elt=no # Function ELT
+func_extra_encrypt=no # Function ENCRYPT
+func_extra_field=no # Function FIELD
+func_extra_format=no # Function FORMAT
+func_extra_from_days=no # Function FROM_DAYS
+func_extra_from_unixtime=no # Function FROM_UNIXTIME
+func_extra_getdate=no # Function GETDATE
+func_extra_greatest=no # Function GREATEST
+func_extra_if=no # Function IF
+func_extra_in_num=no # Function IN on numbers in SELECT
+func_extra_in_str=no # Function IN on strings in SELECT
+func_extra_initcap=no # Function INITCAP
+func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
+func_extra_instrb=no # Function INSTRB
+func_extra_interval=no # Function INTERVAL
+func_extra_last_day=no # Function LAST_DAY
+func_extra_last_insert_id=no # Function LAST_INSERT_ID
+func_extra_least=no # Function LEAST
+func_extra_lengthb=no # Function LENGTHB
+func_extra_like=no # Function LIKE in SELECT
+func_extra_like_escape=no # Function LIKE ESCAPE in SELECT
+func_extra_ln=no # Function LN
+func_extra_log(m_n)=no # Function LOG(m,n)
+func_extra_logn=no # Function LOGN
+func_extra_lpad=no # Function LPAD
+func_extra_mdy=no # Function MDY
+func_extra_mid=no # Function SUBSTRING as MID
+func_extra_months_between=no # Function MONTHS_BETWEEN
+func_extra_not=no # Function NOT in SELECT
+func_extra_not_between=no # Function NOT BETWEEN in SELECT
+func_extra_not_like=no # Function NOT LIKE in SELECT
+func_extra_odbc_convert=no # Function ODBC CONVERT
+func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
+func_extra_patindex=no # Function PATINDEX
+func_extra_period_add=no # Function PERIOD_ADD
+func_extra_period_diff=no # Function PERIOD_DIFF
+func_extra_pow=no # Function POW
+func_extra_range=no # Function RANGE
+func_extra_regexp=no # Function REGEXP in SELECT
+func_extra_replicate=no # Function REPLICATE
+func_extra_reverse=no # Function REVERSE
+func_extra_root=no # Function ROOT
+func_extra_round1=no # Function ROUND(1 arg)
+func_extra_rpad=no # Function RPAD
+func_extra_sec_to_time=no # Function SEC_TO_TIME
+func_extra_sinh=no # Function SINH
+func_extra_str=no # Function STR
+func_extra_strcmp=no # Function STRCMP
+func_extra_stuff=no # Function STUFF
+func_extra_substrb=no # Function SUBSTRB
+func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
+func_extra_tanh=no # Function TANH
+func_extra_time_to_sec=no # Function TIME_TO_SEC
+func_extra_to_days=no # Function TO_DAYS
+func_extra_translate=no # Function TRANSLATE
+func_extra_trim_many_char=no # Function TRIM; Many char extension
+func_extra_trim_substring=no # Function TRIM; Substring extension
+func_extra_trunc=no # Function TRUNC
+func_extra_uid=no # Function UID
+func_extra_unix_timestamp=no # Function UNIX_TIMESTAMP
+func_extra_userenv=no # Function USERENV
+func_extra_version=no # Function VERSION
+func_extra_weekday=no # Function WEEKDAY
+func_extra_|=no # Function | (bitwise or)
+func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
+func_odbc_abs=no # Function ABS
+func_odbc_acos=no # Function ACOS
+func_odbc_ascii=no # Function ASCII
+func_odbc_asin=no # Function ASIN
+func_odbc_atan=no # Function ATAN
+func_odbc_atan2=no # Function ATAN2
+func_odbc_ceiling=no # Function CEILING
+func_odbc_char=no # Function CHAR
+func_odbc_concat=no # Function CONCAT(2 arg)
+func_odbc_cos=no # Function COS
+func_odbc_cot=no # Function COT
+func_odbc_curdate=no # Function CURDATE
+func_odbc_curtime=no # Function CURTIME
+func_odbc_database=no # Function DATABASE
+func_odbc_dayname=no # Function DAYNAME
+func_odbc_dayofmonth=no # Function DAYOFMONTH
+func_odbc_dayofweek=no # Function DAYOFWEEK
+func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_degrees=no # Function DEGREES
+func_odbc_difference=no # Function DIFFERENCE()
+func_odbc_exp=no # Function EXP
+func_odbc_floor=no # Function FLOOR
+func_odbc_fn_left=no # Function ODBC syntax LEFT & RIGHT
+func_odbc_hour=no # Function HOUR
+func_odbc_hour_time=no # Function ANSI HOUR
+func_odbc_ifnull=no # Function IFNULL
+func_odbc_insert=no # Function INSERT
+func_odbc_lcase=no # Function LCASE
+func_odbc_left=no # Function LEFT
+func_odbc_length=no # Function REAL LENGTH
+func_odbc_length_without_space=no # Function ODBC LENGTH
+func_odbc_locate_2=no # Function LOCATE(2 arg)
+func_odbc_locate_3=no # Function LOCATE(3 arg)
+func_odbc_log=no # Function LOG
+func_odbc_log10=no # Function LOG10
+func_odbc_ltrim=no # Function LTRIM
+func_odbc_minute=no # Function MINUTE
+func_odbc_mod=no # Function MOD
+func_odbc_month=no # Function MONTH
+func_odbc_monthname=no # Function MONTHNAME
+func_odbc_now=no # Function NOW
+func_odbc_pi=no # Function PI
+func_odbc_power=no # Function POWER
+func_odbc_quarter=no # Function QUARTER
+func_odbc_radians=no # Function RADIANS
+func_odbc_rand=no # Function RAND
+func_odbc_repeat=no # Function REPEAT
+func_odbc_replace=no # Function REPLACE
+func_odbc_right=no # Function RIGHT
+func_odbc_round=no # Function ROUND(2 arg)
+func_odbc_rtrim=no # Function RTRIM
+func_odbc_second=no # Function SECOND
+func_odbc_sign=no # Function SIGN
+func_odbc_sin=no # Function SIN
+func_odbc_soundex=no # Function SOUNDEX
+func_odbc_space=no # Function SPACE
+func_odbc_sqrt=no # Function SQRT
+func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_tan=no # Function TAN
+func_odbc_timestampadd=no # Function TIMESTAMPADD
+func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
+func_odbc_truncate=no # Function TRUNCATE
+func_odbc_ucase=no # Function UCASE
+func_odbc_user()=no # Function USER()
+func_odbc_week=no # Function WEEK
+func_odbc_year=no # Function YEAR
+func_sql_+=yes # Function +, -, * and /
+func_sql_bit_length=no # Function BIT_LENGTH
+func_sql_cast=yes # Function CAST
+func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
+func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
+func_sql_concat_as_||=yes # Function concatenation with ||
+func_sql_current_date=yes # Function CURRENT_DATE
+func_sql_current_time=yes # Function CURRENT_TIME
+func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=yes # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=no # Function LOWER
+func_sql_nullif_num=no # Function NULLIF with numbers
+func_sql_nullif_string=no # Function NULLIF with strings
+func_sql_octet_length=no # Function OCTET_LENGTH
+func_sql_position=no # Function POSITION
+func_sql_searched_case=no # Function searched CASE
+func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=no # Function simple CASE
+func_sql_substring=no # Function ANSI SQL SUBSTRING
+func_sql_system_user=no # Function SYSTEM_USER
+func_sql_trim=no # Function TRIM
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
+func_where_between=yes # Function BETWEEN
+func_where_eq_all=yes # Function = ALL
+func_where_eq_any=yes # Function = ANY
+func_where_eq_some=yes # Function = SOME
+func_where_exists=yes # Function EXISTS
+func_where_in_num=yes # Function IN on numbers
+func_where_like=yes # Function LIKE
+func_where_like_escape=yes # Function LIKE ESCAPE
+func_where_match=no # Function MATCH
+func_where_match_unique=no # Function MATCH UNIQUE
+func_where_matches=no # Function MATCHES
+func_where_not_between=yes # Function NOT BETWEEN
+func_where_not_exists=yes # Function NOT EXISTS
+func_where_not_like=yes # Function NOT LIKE
+func_where_not_unique=no # Function NOT UNIQUE
+func_where_unique=no # Function UNIQUE
+functions=yes # Functions
+group_by=yes # Group by
+group_by_alias=no # Group by alias
+group_by_null=yes # Group on column with null values
+group_by_position=no # Group by position
+group_distinct_functions=yes # Group functions with distinct
+group_func_extra_bit_and=no # Group function BIT_AND
+group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
+group_func_extra_std=no # Group function STD
+group_func_extra_stddev=no # Group function STDDEV
+group_func_extra_variance=no # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
+group_func_sql_avg=yes # Group function AVG
+group_func_sql_count_*=yes # Group function COUNT (*)
+group_func_sql_count_column=yes # Group function COUNT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
+group_func_sql_max=yes # Group function MAX on numbers
+group_func_sql_max_str=yes # Group function MAX on strings
+group_func_sql_min=yes # Group function MIN on numbers
+group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
+group_func_sql_sum=yes # Group function SUM
+group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
+having=yes # Having
+having_with_alias=no # Having on alias
+having_with_group=yes # Having with group function
+hex_numbers=yes # hex numbers (0x41)
+hex_strings=no # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
+index_in_create=no # index in create table
+index_namespace=no # different namespace for index
+index_parts=no # index on column part (extension)
+inner_join=yes # inner join
+insert_empty_string=no # insert empty string
+insert_multi_value=no # INSERT with Value lists
+insert_select=no # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
+intersect=no # intersect
+intersect_all=no # intersect all
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=+64 # tables in join
+left_outer_join=yes # left outer join
+left_outer_join_using=no # left outer join using
+like_with_column=no # column LIKE column
+like_with_number=no # LIKE on numbers
+lock_tables=no # lock table
+logical_value=not supported # Value of logical operation (1=1)
+max_big_expressions=1 # big expressions
+max_char_size=32767 # max char() size
+max_columns=4759 # Columns in table
+max_conditions=5888 # OR and AND in WHERE
+max_expressions=+10000 # simple expressions
+max_index=+64 # max index
+max_index_name=31 # index name length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=249 # index varchar part length
+max_row_length=64744 # max table row length (without blobs)
+max_row_length_with_null=64744 # table row length with nulls (without blobs)
+max_select_alias_name=132 # select alias name length
+max_stack_expression=165 # stacked expressions
+max_table_alias_name=255 # table alias name length
+max_table_name=31 # table name length
+max_unique_index=+64 # unique indexes
+max_varchar_size=10923 # max varchar() size
+minus=no # minus
+minus_incompat=no # minus (incompatible lists)
+minus_neg=yes # Calculate 1--1
+multi_drop=no # many tables to drop table
+multi_strings=no # Multiple line strings
+multi_table_delete=no # DELETE FROM table1,table2...
+multi_table_update=no # Update with many tables
+natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
+natural_left_outer_join=no # natural left outer join
+no_primary_key=yes # Tables without primary key
+null_concat_expr=no # Is 'a' || NULL = NULL
+null_in_index=yes # null in index
+null_in_unique=no # null in unique index
+null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
+odbc_left_outer_join=no # left outer join odbc style
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
+order_by=yes # Order by
+order_by_alias=no # Order by alias
+order_by_function=no # Order by function
+order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
+primary_key_in_create=yes # primary key in create table
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=65535 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
+quote_with_"=no # Allows ' and " as string markers
+recursive_subqueries=61 # recursive subqueries
+remember_end_space=no # Remembers end space in char()
+remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=no # rename table
+right_outer_join=yes # right outer join
+rowid=no # Type for row id
+select_constants=yes # Select constants
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32767 # constant string size in SELECT
+select_table_update=yes # Update with sub select
+select_without_from=no # SELECT without FROM
+server_version=6.0.1 # server version
+simple_joins=yes # ANSI SQL simple joins
+storage_of_float=round # Storage of float values
+subqueries=yes # subqueries
+table_alias=no # Table alias
+table_name_case=yes # case independent table names
+table_wildcard=yes # Select table_name.*
+temporary_table=no # temporary tables
+transactions=error # constant string size in where
+truncate_table=no # truncate
+type_extra_abstime=no # Type abstime
+type_extra_bfile=no # Type bfile
+type_extra_blob=yes # Type blob
+type_extra_bool=no # Type bool
+type_extra_box=no # Type box
+type_extra_byte=no # Type byte
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
+type_extra_circle=no # Type circle
+type_extra_clob=no # Type clob
+type_extra_datetime=no # Type datetime
+type_extra_double=no # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
+type_extra_float4=no # Type float4
+type_extra_float8=no # Type float8
+type_extra_image=no # Type image
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_int1=no # Type int1
+type_extra_int2=no # Type int2
+type_extra_int3=no # Type int3
+type_extra_int4=no # Type int4
+type_extra_int8=no # Type int8
+type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
+type_extra_line=no # Type line
+type_extra_long=no # Type long
+type_extra_long_raw=no # Type long raw
+type_extra_long_varbinary=no # Type long varbinary
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
+type_extra_mediumint=no # Type mediumint
+type_extra_mediumtext=no # Type mediumtext
+type_extra_middleint=no # Type middleint
+type_extra_mlslabel=no # Type mlslabel
+type_extra_money=no # Type money
+type_extra_nclob=no # Type nclob
+type_extra_number=no # Type number
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
+type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
+type_extra_path=no # Type path
+type_extra_point=no # Type point
+type_extra_polygon=no # Type polygon
+type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_reltime=no # Type reltime
+type_extra_rowid=no # Type rowid
+type_extra_serial=no # Type serial
+type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_smalldatetime=no # Type smalldatetime
+type_extra_smallfloat=no # Type smallfloat
+type_extra_smallmoney=no # Type smallmoney
+type_extra_text=no # Type text
+type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
+type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
+type_extra_year=no # Type year
+type_odbc_bigint=no # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_datetime=no # Type datetime
+type_odbc_tinyint=no # Type tinyint
+type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
+type_sql_=no # Type
+type_sql_bit=no # Type bit
+type_sql_bit(1_arg)=no # Type bit(1 arg)
+type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_character(1_arg)=yes # Type character(1 arg)
+type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
+type_sql_date=yes # Type date
+type_sql_dec(2_arg)=yes # Type dec(2 arg)
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
+type_sql_double_precision=yes # Type double precision
+type_sql_float=yes # Type float
+type_sql_float(1_arg)=yes # Type float(1 arg)
+type_sql_int=yes # Type int
+type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
+type_sql_interval_year=no # Type interval year
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=yes # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=yes # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
+type_sql_time=yes # Type time
+type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+union=yes # union
+union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
+unique_in_create=yes # unique in create table
+unique_null_in_create=no # unique null in create
+views=no # views
+where_string_size=32767 # constant string size in where
diff --git a/sql-bench/limits/interbase-superserver.cfg b/sql-bench/limits/interbase-superserver.cfg
new file mode 100644
index 00000000000..87da0d0633c
--- /dev/null
+++ b/sql-bench/limits/interbase-superserver.cfg
@@ -0,0 +1,514 @@
+#This file is automaticly generated by crash-me 1.57
+
+NEG=no # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
+alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=with add # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
+alter_change_col=no # Alter table change column
+alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=no # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
+alter_modify_col=no # Alter table modify column
+alter_rename_table=no # Alter table rename table
+atomic_updates=no # atomic updates
+automatic_rowid=no # Automatic row id
+binary_numbers=yes # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
+column_alias=yes # Column alias
+columns_in_order_by=37 # number of columns in order by
+comment_#=no # # as comment
+comment_--=no # -- as comment (ANSI)
+comment_/**/=yes # /* */ as comment
+comment_//=no # // as comment
+compute=no # Compute
+connections=395 # Simultaneous connections (installation default)
+constraint_check=no # Column constraints
+constraint_check_table=no # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
+crash_me_safe=no # crash me safe
+crash_me_version=1.57 # crash me version
+create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
+create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
+cross_join=no # cross join (same as from a,b)
+date_infinity=no # Supports 'infinity dates
+date_last=error # Supports 9999-12-31 dates
+date_one=error # Supports 0001-01-01 dates
+date_with_YY=no # Supports YY-MM-DD dates
+date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
+drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
+except=no # except
+except_all=no # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
+float_int_expr=yes # mixing of integer and float in expression
+foreign_key_syntax=no # foreign key syntax
+full_outer_join=yes # full outer join
+func_extra_!=no # Function NOT as '!' in SELECT
+func_extra_%=no # Function MOD as %
+func_extra_&=no # Function & (bitwise and)
+func_extra_&&=no # Function AND as '&&'
+func_extra_<>=no # Function <> in SELECT
+func_extra_==no # Function =
+func_extra_add_months=no # Function ADD_MONTHS
+func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
+func_extra_atn2=no # Function ATN2
+func_extra_auto_num2string=no # Function automatic num->string convert
+func_extra_auto_string2num=no # Function automatic string->num convert
+func_extra_between=no # Function BETWEEN in SELECT
+func_extra_binary_shifts=no # Function << and >> (bitwise shifts)
+func_extra_bit_count=no # Function BIT_COUNT
+func_extra_ceil=no # Function CEIL
+func_extra_charindex=no # Function CHARINDEX
+func_extra_chr=no # Function CHR
+func_extra_concat_as_+=no # Function concatenation with +
+func_extra_concat_list=no # Function CONCAT(list)
+func_extra_convert=no # Function CONVERT
+func_extra_cosh=no # Function COSH
+func_extra_date_format=no # Function DATE_FORMAT
+func_extra_dateadd=no # Function DATEADD
+func_extra_datediff=no # Function DATEDIFF
+func_extra_datename=no # Function DATENAME
+func_extra_datepart=no # Function DATEPART
+func_extra_elt=no # Function ELT
+func_extra_encrypt=no # Function ENCRYPT
+func_extra_field=no # Function FIELD
+func_extra_format=no # Function FORMAT
+func_extra_from_days=no # Function FROM_DAYS
+func_extra_from_unixtime=no # Function FROM_UNIXTIME
+func_extra_getdate=no # Function GETDATE
+func_extra_greatest=no # Function GREATEST
+func_extra_if=no # Function IF
+func_extra_in_num=no # Function IN on numbers in SELECT
+func_extra_in_str=no # Function IN on strings in SELECT
+func_extra_initcap=no # Function INITCAP
+func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
+func_extra_instrb=no # Function INSTRB
+func_extra_interval=no # Function INTERVAL
+func_extra_last_day=no # Function LAST_DAY
+func_extra_last_insert_id=no # Function LAST_INSERT_ID
+func_extra_least=no # Function LEAST
+func_extra_lengthb=no # Function LENGTHB
+func_extra_like=no # Function LIKE in SELECT
+func_extra_like_escape=no # Function LIKE ESCAPE in SELECT
+func_extra_ln=no # Function LN
+func_extra_log(m_n)=no # Function LOG(m,n)
+func_extra_logn=no # Function LOGN
+func_extra_lpad=no # Function LPAD
+func_extra_mdy=no # Function MDY
+func_extra_mid=no # Function SUBSTRING as MID
+func_extra_months_between=no # Function MONTHS_BETWEEN
+func_extra_not=no # Function NOT in SELECT
+func_extra_not_between=no # Function NOT BETWEEN in SELECT
+func_extra_not_like=no # Function NOT LIKE in SELECT
+func_extra_odbc_convert=no # Function ODBC CONVERT
+func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
+func_extra_patindex=no # Function PATINDEX
+func_extra_period_add=no # Function PERIOD_ADD
+func_extra_period_diff=no # Function PERIOD_DIFF
+func_extra_pow=no # Function POW
+func_extra_range=no # Function RANGE
+func_extra_regexp=no # Function REGEXP in SELECT
+func_extra_replicate=no # Function REPLICATE
+func_extra_reverse=no # Function REVERSE
+func_extra_root=no # Function ROOT
+func_extra_round1=no # Function ROUND(1 arg)
+func_extra_rpad=no # Function RPAD
+func_extra_sec_to_time=no # Function SEC_TO_TIME
+func_extra_sinh=no # Function SINH
+func_extra_str=no # Function STR
+func_extra_strcmp=no # Function STRCMP
+func_extra_stuff=no # Function STUFF
+func_extra_substrb=no # Function SUBSTRB
+func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
+func_extra_tanh=no # Function TANH
+func_extra_time_to_sec=no # Function TIME_TO_SEC
+func_extra_to_days=no # Function TO_DAYS
+func_extra_translate=no # Function TRANSLATE
+func_extra_trim_many_char=no # Function TRIM; Many char extension
+func_extra_trim_substring=no # Function TRIM; Substring extension
+func_extra_trunc=no # Function TRUNC
+func_extra_uid=no # Function UID
+func_extra_unix_timestamp=no # Function UNIX_TIMESTAMP
+func_extra_userenv=no # Function USERENV
+func_extra_version=no # Function VERSION
+func_extra_weekday=no # Function WEEKDAY
+func_extra_|=no # Function | (bitwise or)
+func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
+func_odbc_abs=no # Function ABS
+func_odbc_acos=no # Function ACOS
+func_odbc_ascii=no # Function ASCII
+func_odbc_asin=no # Function ASIN
+func_odbc_atan=no # Function ATAN
+func_odbc_atan2=no # Function ATAN2
+func_odbc_ceiling=no # Function CEILING
+func_odbc_char=no # Function CHAR
+func_odbc_concat=no # Function CONCAT(2 arg)
+func_odbc_cos=no # Function COS
+func_odbc_cot=no # Function COT
+func_odbc_curdate=no # Function CURDATE
+func_odbc_curtime=no # Function CURTIME
+func_odbc_database=no # Function DATABASE
+func_odbc_dayname=no # Function DAYNAME
+func_odbc_dayofmonth=no # Function DAYOFMONTH
+func_odbc_dayofweek=no # Function DAYOFWEEK
+func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_degrees=no # Function DEGREES
+func_odbc_difference=no # Function DIFFERENCE()
+func_odbc_exp=no # Function EXP
+func_odbc_floor=no # Function FLOOR
+func_odbc_fn_left=no # Function ODBC syntax LEFT & RIGHT
+func_odbc_hour=no # Function HOUR
+func_odbc_hour_time=no # Function ANSI HOUR
+func_odbc_ifnull=no # Function IFNULL
+func_odbc_insert=no # Function INSERT
+func_odbc_lcase=no # Function LCASE
+func_odbc_left=no # Function LEFT
+func_odbc_length=no # Function REAL LENGTH
+func_odbc_length_without_space=no # Function ODBC LENGTH
+func_odbc_locate_2=no # Function LOCATE(2 arg)
+func_odbc_locate_3=no # Function LOCATE(3 arg)
+func_odbc_log=no # Function LOG
+func_odbc_log10=no # Function LOG10
+func_odbc_ltrim=no # Function LTRIM
+func_odbc_minute=no # Function MINUTE
+func_odbc_mod=no # Function MOD
+func_odbc_month=no # Function MONTH
+func_odbc_monthname=no # Function MONTHNAME
+func_odbc_now=no # Function NOW
+func_odbc_pi=no # Function PI
+func_odbc_power=no # Function POWER
+func_odbc_quarter=no # Function QUARTER
+func_odbc_radians=no # Function RADIANS
+func_odbc_rand=no # Function RAND
+func_odbc_repeat=no # Function REPEAT
+func_odbc_replace=no # Function REPLACE
+func_odbc_right=no # Function RIGHT
+func_odbc_round=no # Function ROUND(2 arg)
+func_odbc_rtrim=no # Function RTRIM
+func_odbc_second=no # Function SECOND
+func_odbc_sign=no # Function SIGN
+func_odbc_sin=no # Function SIN
+func_odbc_soundex=no # Function SOUNDEX
+func_odbc_space=no # Function SPACE
+func_odbc_sqrt=no # Function SQRT
+func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_tan=no # Function TAN
+func_odbc_timestampadd=no # Function TIMESTAMPADD
+func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
+func_odbc_truncate=no # Function TRUNCATE
+func_odbc_ucase=no # Function UCASE
+func_odbc_user()=no # Function USER()
+func_odbc_week=no # Function WEEK
+func_odbc_year=no # Function YEAR
+func_sql_+=yes # Function +, -, * and /
+func_sql_bit_length=no # Function BIT_LENGTH
+func_sql_cast=yes # Function CAST
+func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
+func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
+func_sql_concat_as_||=yes # Function concatenation with ||
+func_sql_current_date=yes # Function CURRENT_DATE
+func_sql_current_time=yes # Function CURRENT_TIME
+func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=yes # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=no # Function LOWER
+func_sql_nullif_num=no # Function NULLIF with numbers
+func_sql_nullif_string=no # Function NULLIF with strings
+func_sql_octet_length=no # Function OCTET_LENGTH
+func_sql_position=no # Function POSITION
+func_sql_searched_case=no # Function searched CASE
+func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=no # Function simple CASE
+func_sql_substring=no # Function ANSI SQL SUBSTRING
+func_sql_system_user=no # Function SYSTEM_USER
+func_sql_trim=no # Function TRIM
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
+func_where_between=yes # Function BETWEEN
+func_where_eq_all=yes # Function = ALL
+func_where_eq_any=yes # Function = ANY
+func_where_eq_some=yes # Function = SOME
+func_where_exists=yes # Function EXISTS
+func_where_in_num=yes # Function IN on numbers
+func_where_like=yes # Function LIKE
+func_where_like_escape=yes # Function LIKE ESCAPE
+func_where_match=no # Function MATCH
+func_where_match_unique=no # Function MATCH UNIQUE
+func_where_matches=no # Function MATCHES
+func_where_not_between=yes # Function NOT BETWEEN
+func_where_not_exists=yes # Function NOT EXISTS
+func_where_not_like=yes # Function NOT LIKE
+func_where_not_unique=no # Function NOT UNIQUE
+func_where_unique=no # Function UNIQUE
+functions=yes # Functions
+group_by=yes # Group by
+group_by_alias=no # Group by alias
+group_by_null=yes # Group on column with null values
+group_by_position=no # Group by position
+group_distinct_functions=yes # Group functions with distinct
+group_func_extra_bit_and=no # Group function BIT_AND
+group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
+group_func_extra_std=no # Group function STD
+group_func_extra_stddev=no # Group function STDDEV
+group_func_extra_variance=no # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
+group_func_sql_avg=yes # Group function AVG
+group_func_sql_count_*=yes # Group function COUNT (*)
+group_func_sql_count_column=yes # Group function COUNT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
+group_func_sql_max=yes # Group function MAX on numbers
+group_func_sql_max_str=yes # Group function MAX on strings
+group_func_sql_min=yes # Group function MIN on numbers
+group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
+group_func_sql_sum=yes # Group function SUM
+group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
+having=yes # Having
+having_with_alias=no # Having on alias
+having_with_group=yes # Having with group function
+hex_numbers=yes # hex numbers (0x41)
+hex_strings=no # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
+index_in_create=no # index in create table
+index_namespace=no # different namespace for index
+index_parts=no # index on column part (extension)
+inner_join=yes # inner join
+insert_empty_string=no # insert empty string
+insert_multi_value=no # INSERT with Value lists
+insert_select=no # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
+intersect=no # intersect
+intersect_all=no # intersect all
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=+64 # tables in join
+left_outer_join=yes # left outer join
+left_outer_join_using=no # left outer join using
+like_with_column=no # column LIKE column
+like_with_number=no # LIKE on numbers
+lock_tables=no # lock table
+logical_value=not supported # Value of logical operation (1=1)
+max_big_expressions=1 # big expressions
+max_char_size=32745 # max char() size
+max_column_name=18 # column name length
+max_columns=4759 # Columns in table
+max_conditions=441504 # OR and AND in WHERE
+max_expressions=5486 # simple expressions
+max_index=+64 # max index
+max_index_name=31 # index name length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=218 # index varchar part length
+max_row_length=64744 # max table row length (without blobs)
+max_row_length_with_null=64744 # table row length with nulls (without blobs)
+max_select_alias_name=132 # select alias name length
+max_stack_expression=165 # stacked expressions
+max_table_alias_name=255 # table alias name length
+max_table_name=31 # table name length
+max_unique_index=+64 # unique indexes
+max_varchar_size=32745 # max varchar() size
+minus=no # minus
+minus_incompat=no # minus (incompatible lists)
+minus_neg=yes # Calculate 1--1
+multi_drop=no # many tables to drop table
+multi_strings=no # Multiple line strings
+multi_table_delete=no # DELETE FROM table1,table2...
+multi_table_update=no # Update with many tables
+natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
+natural_left_outer_join=no # natural left outer join
+no_primary_key=yes # Tables without primary key
+null_concat_expr=no # Is 'a' || NULL = NULL
+null_in_index=yes # null in index
+null_in_unique=no # null in unique index
+null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
+odbc_left_outer_join=no # left outer join odbc style
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
+order_by=yes # Order by
+order_by_alias=no # Order by alias
+order_by_function=no # Order by function
+order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
+primary_key_in_create=yes # primary key in create table
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=16777216 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
+quote_with_"=no # Allows ' and " as string markers
+recursive_subqueries=61 # recursive subqueries
+remember_end_space=no # Remembers end space in char()
+remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=no # rename table
+right_outer_join=yes # right outer join
+rowid=no # Type for row id
+select_constants=yes # Select constants
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32767 # constant string size in SELECT
+select_table_update=yes # Update with sub select
+select_without_from=no # SELECT without FROM
+server_version=6.0.1 # server version
+simple_joins=yes # ANSI SQL simple joins
+storage_of_float=round # Storage of float values
+subqueries=yes # subqueries
+table_alias=no # Table alias
+table_name_case=yes # case independent table names
+table_wildcard=yes # Select table_name.*
+temporary_table=no # temporary tables
+transactions=error # constant string size in where
+truncate_table=no # truncate
+type_extra_abstime=no # Type abstime
+type_extra_bfile=no # Type bfile
+type_extra_blob=yes # Type blob
+type_extra_bool=no # Type bool
+type_extra_box=no # Type box
+type_extra_byte=no # Type byte
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
+type_extra_circle=no # Type circle
+type_extra_clob=no # Type clob
+type_extra_datetime=no # Type datetime
+type_extra_double=no # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
+type_extra_float4=no # Type float4
+type_extra_float8=no # Type float8
+type_extra_image=no # Type image
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_int1=no # Type int1
+type_extra_int2=no # Type int2
+type_extra_int3=no # Type int3
+type_extra_int4=no # Type int4
+type_extra_int8=no # Type int8
+type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
+type_extra_line=no # Type line
+type_extra_long=no # Type long
+type_extra_long_raw=no # Type long raw
+type_extra_long_varbinary=no # Type long varbinary
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
+type_extra_mediumint=no # Type mediumint
+type_extra_mediumtext=no # Type mediumtext
+type_extra_middleint=no # Type middleint
+type_extra_mlslabel=no # Type mlslabel
+type_extra_money=no # Type money
+type_extra_nclob=no # Type nclob
+type_extra_number=no # Type number
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
+type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
+type_extra_path=no # Type path
+type_extra_point=no # Type point
+type_extra_polygon=no # Type polygon
+type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_reltime=no # Type reltime
+type_extra_rowid=no # Type rowid
+type_extra_serial=no # Type serial
+type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_smalldatetime=no # Type smalldatetime
+type_extra_smallfloat=no # Type smallfloat
+type_extra_smallmoney=no # Type smallmoney
+type_extra_text=no # Type text
+type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
+type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
+type_extra_year=no # Type year
+type_odbc_bigint=no # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_datetime=no # Type datetime
+type_odbc_tinyint=no # Type tinyint
+type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
+type_sql_bit=no # Type bit
+type_sql_bit(1_arg)=no # Type bit(1 arg)
+type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_character(1_arg)=yes # Type character(1 arg)
+type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
+type_sql_date=yes # Type date
+type_sql_dec(2_arg)=yes # Type dec(2 arg)
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
+type_sql_double_precision=yes # Type double precision
+type_sql_float=yes # Type float
+type_sql_float(1_arg)=yes # Type float(1 arg)
+type_sql_int=yes # Type int
+type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
+type_sql_interval_year=no # Type interval year
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=yes # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=yes # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
+type_sql_time=yes # Type time
+type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+union=yes # union
+union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
+unique_in_create=yes # unique in create table
+unique_null_in_create=no # unique null in create
+views=no # views
+where_string_size=32767 # constant string size in where
diff --git a/sql-bench/limits/mysql.cfg b/sql-bench/limits/mysql.cfg
index a496bd7bf4c..306ce2d7b33 100644
--- a/sql-bench/limits/mysql.cfg
+++ b/sql-bench/limits/mysql.cfg
@@ -1,4 +1,4 @@
-#This file is automaticly generated by crash-me 1.57
+#This file is automaticly generated by crash-me 1.58
NEG=yes # update of column= -column
Need_cast_for_null=no # Need to cast NULL for arithmetic
@@ -29,14 +29,14 @@ columns_in_order_by=+64 # number of columns in order by
comment_#=yes # # as comment
comment_--=yes # -- as comment (ANSI)
comment_/**/=yes # /* */ as comment
-comment_//=no # // as comment (ANSI)
+comment_//=no # // as comment
compute=no # Compute
connections=101 # Simultaneous connections (installation default)
constraint_check=no # Column constraints
constraint_check_table=no # Table constraints
constraint_null=yes # NULL constraint (SyBase style)
crash_me_safe=yes # crash me safe
-crash_me_version=1.57 # crash me version
+crash_me_version=1.58 # crash me version
create_default=yes # default value for column
create_default_func=no # default value function for column
create_if_not_exists=yes # create table if not exists
@@ -62,6 +62,7 @@ except=no # except
except_all=no # except all
except_all_incompat=no # except all (incompatible lists)
except_incompat=no # except (incompatible lists)
+field_name_case=yes # case independent field names
float_int_expr=yes # mixing of integer and float in expression
foreign_key=no # foreign keys
foreign_key_syntax=yes # foreign key syntax
@@ -228,10 +229,10 @@ func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
func_odbc_truncate=yes # Function TRUNCATE
func_odbc_ucase=yes # Function UCASE
func_odbc_user()=yes # Function USER()
-func_odbc_week=yes # Function WEEK
+func_odbc_week=error # Function WEEK
func_odbc_year=yes # Function YEAR
func_sql_+=yes # Function +, -, * and /
-func_sql_bit_length=no # Function BIT_LENGTH
+func_sql_bit_length=yes # Function BIT_LENGTH
func_sql_cast=no # Function CAST
func_sql_char_length=error # Function CHAR_LENGTH
func_sql_char_length(constant)=yes # Function CHAR_LENGTH(constant)
@@ -299,13 +300,14 @@ group_func_sql_min_str=yes # Group function MIN on strings
group_func_sql_some=no # Group function SOME
group_func_sql_sum=yes # Group function SUM
group_functions=yes # Group functions
+group_many_distinct_functions=yes # Group functions with several distinct
group_on_unused=yes # Group on unused column
has_true_false=no # TRUE and FALSE
having=yes # Having
having_with_alias=yes # Having on alias
having_with_group=yes # Having with group function
hex_numbers=yes # hex numbers (0x41)
-hex_strings=no # hex strings (x'1ace')
+hex_strings=yes # hex strings (x'1ace')
ignore_end_space=yes # Ignore end space in compare
index_in_create=yes # index in create table
index_namespace=yes # different namespace for index
@@ -319,7 +321,7 @@ intersect=no # intersect
intersect_all=no # intersect all
intersect_all_incompat=no # intersect all (incompatible lists)
intersect_incompat=no # intersect (incompatible lists)
-join_tables=63 # tables in join
+join_tables=31 # tables in join
left_outer_join=yes # left outer join
left_outer_join_using=yes # left outer join using
like_with_column=yes # column LIKE column
@@ -331,7 +333,7 @@ max_char_size=255 # max char() size
max_column_name=64 # column name length
max_columns=3398 # Columns in table
max_conditions=85660 # OR and AND in WHERE
-max_expressions=1837 # simple expressions
+max_expressions=686 # simple expressions
max_index=32 # max index
max_index_length=500 # index length
max_index_name=64 # index name length
@@ -341,7 +343,7 @@ max_index_varchar_part_length=255 # index varchar part length
max_row_length=65534 # max table row length (without blobs)
max_row_length_with_null=65502 # table row length with nulls (without blobs)
max_select_alias_name=+512 # select alias name length
-max_stack_expression=1837 # stacked expressions
+max_stack_expression=490 # stacked expressions
max_table_alias_name=+512 # table alias name length
max_table_name=64 # table name length
max_text_size=1048543 # max text or blob size
@@ -353,8 +355,8 @@ minus_neg=yes # Calculate 1--1
multi_drop=yes # many tables to drop table
multi_null_in_unique=yes # null in unique index
multi_strings=yes # Multiple line strings
-multi_table_delete=no # DELETE FROM table1,table2...
-multi_table_update=no # Update with many tables
+multi_table_delete=yes # DELETE FROM table1,table2...
+multi_table_update=yes # Update with many tables
natural_join=yes # natural join
natural_join_incompat=yes # natural join (incompatible lists)
natural_left_outer_join=yes # natural left outer join
@@ -365,7 +367,7 @@ null_in_unique=yes # null in unique index
null_num_expr=yes # Is 1+NULL = NULL
nulls_in_unique=yes # null combination in unique index
odbc_left_outer_join=yes # left outer join odbc style
-operating_system=Linux 2.2.13-SMP alpha # crash-me tested on
+operating_system=Linux 2.4.16-64GB-SMP i686 # crash-me tested on
order_by=yes # Order by
order_by_alias=yes # Order by alias
order_by_function=yes # Order by function
@@ -385,7 +387,7 @@ quote_with_"=yes # Allows ' and " as string markers
remember_end_space=no # Remembers end space in char()
remember_end_space_varchar=no # Remembers end space in varchar()
rename_table=yes # rename table
-repeat_string_size=1047552 # return string size from function
+repeat_string_size=1048576 # return string size from function
right_outer_join=yes # right outer join
rowid=auto_increment # Type for row id
select_constants=yes # Select constants
@@ -394,7 +396,7 @@ select_limit2=yes # SELECT with LIMIT #,#
select_string_size=1048565 # constant string size in SELECT
select_table_update=no # Update with sub select
select_without_from=yes # SELECT without FROM
-server_version=MySQL 3.23.39 debug # server version
+server_version=MySQL 4.0.2 alpha # server version
simple_joins=yes # ANSI SQL simple joins
storage_of_float=round # Storage of float values
subqueries=no # subqueries
@@ -402,7 +404,7 @@ table_alias=yes # Table alias
table_name_case=no # case independent table names
table_wildcard=yes # Select table_name.*
temporary_table=yes # temporary tables
-transactions=yes # constant string size in where
+transactions=yes # transactions
truncate_table=yes # truncate
type_extra_abstime=no # Type abstime
type_extra_bfile=no # Type bfile
@@ -512,12 +514,11 @@ type_sql_time=yes # Type time
type_sql_timestamp=yes # Type timestamp
type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
-union=no # union
-union_all=no # union all
-union_all_incompat=no # union all (incompatible lists)
-union_incompat=no # union (incompatible lists)
+union=yes # union
+union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
unique_in_create=yes # unique in create table
unique_null_in_create=yes # unique null in create
-user_comment=Alpha DS20 2x500 MHz, 2G memory, key_buffer=16M; ccc + cxx # comment
views=no # views
where_string_size=1048539 # constant string size in where
diff --git a/sql-bench/run-all-tests.sh b/sql-bench/run-all-tests.sh
index c2f687a9375..f392431140c 100644
--- a/sql-bench/run-all-tests.sh
+++ b/sql-bench/run-all-tests.sh
@@ -109,7 +109,9 @@ print "Running tests on: $machine\n";
print "Arguments: $log_prog_args\n";
print "Comments: $opt_comments\n";
print "Limits from: $opt_cmp\n";
-print "Server version: $server_version\n\n";
+print "Server version: $server_version\n";
+print "Optimization: $opt_optimization\n";
+print "Hardware: $opt_hw\n\n";
$estimated=$warning=$got_warning=0;
@@ -195,6 +197,10 @@ while (<test-*>)
print "Summary for $prog: ", join(" ",@prog_sum), "\n";
}
}
+ elsif ($last_line =~ /^Test skipped/i)
+ {
+ print "$last_line\n";
+ }
else
{
$errors++;
@@ -281,10 +287,6 @@ sub read_headers
{
$log_prog_args=$1;
}
- elsif (/^Comments.*:\s+(.*)$/)
- {
- $opt_comments=$1;
- }
elsif (/^Limits.*:\s+(.*)$/)
{
$opt_cmp=$1;
@@ -293,6 +295,14 @@ sub read_headers
{
$server_version=$1;
}
+ elsif (/^Optimiz.*:\s+(.*)$/)
+ {
+ $opt_optimization=$1;
+ }
+ elsif (/^Hardwar.*:\s+(.*)$/)
+ {
+ $opt_hw=$1;
+ }
}
close(TMP);
}
diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh
index 886c428e3b9..d1205d55842 100644
--- a/sql-bench/server-cfg.sh
+++ b/sql-bench/server-cfg.sh
@@ -33,10 +33,10 @@
sub get_server
{
- my ($name,$host,$database,$odbc,$machine)=@_;
+ my ($name,$host,$database,$odbc,$machine,$socket)=@_;
my ($server);
if ($name =~ /mysql/i)
- { $server=new db_MySQL($host, $database, $machine); }
+ { $server=new db_MySQL($host, $database, $machine, $socket); }
elsif ($name =~ /pg/i)
{ $server= new db_Pg($host,$database); }
elsif ($name =~ /msql/i)
@@ -73,7 +73,7 @@ sub get_server
{ $server= new db_interbase($host,$database); }
else
{
- die "Unknown sql server name used: $name\nUse one of: Access, Adabas, AdabasD, Empress, FrontBase, Oracle, Informix, DB2, mSQL, Mimer, MS-SQL, MySQL, Pg, Solid or Sybase.\nIf the connection is done trough ODBC the name must end with _ODBC\n";
+ die "Unknown sql server name used: $name\nUse one of: Access, Adabas, AdabasD, Empress, FrontBase, Oracle, Informix, InterBase, DB2, mSQL, Mimer, MS-SQL, MySQL, Pg, Solid or Sybase.\nIf the connection is done trough ODBC the name must end with _ODBC\n";
}
if ($name =~ /_ODBC$/i || defined($odbc) && $odbc)
{
@@ -106,13 +106,14 @@ package db_MySQL;
sub new
{
- my ($type,$host,$database,$machine)= @_;
+ my ($type,$host,$database,$machine,$socket)= @_;
my $self= {};
my %limits;
bless $self;
$self->{'cmp_name'} = "mysql";
- $self->{'data_source'} = "DBI:mysql:$database:$host";
+ $self->{'data_source'} = "DBI:mysql:database=$database;host=$host";
+ $self->{'data_source'} .= ";mysql_socket=$socket" if($socket);
$self->{'limits'} = \%limits;
$self->{'smds'} = \%smds;
$self->{'blob'} = "blob";
@@ -120,6 +121,7 @@ sub new
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'vacuum'} = 1; # When using with --fast
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 0; # Transactions disabled by default
$limits{'NEG'} = 1; # Supports -id
$limits{'alter_add_multi_col'}= 1; #Have ALTER TABLE t add a int,add b int;
@@ -144,7 +146,8 @@ sub new
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'left_outer_join'} = 1; # Supports left outer joins
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
- $limits{'limit'} = 1; # supports the limit attribute
+ $limits{'limit'} = 1; # supports the limit attribute
+ $limits{'truncate_table'} = 1;
$limits{'load_data_infile'} = 1; # Has load data infile
$limits{'lock_tables'} = 1; # Has lock tables
$limits{'max_column_name'} = 64; # max table and column name
@@ -165,25 +168,6 @@ sub new
$limits{'working_all_fields'} = 1;
$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
if (defined($main::opt_create_options) &&
$main::opt_create_options =~ /type=heap/i)
@@ -194,12 +178,19 @@ sub new
$main::opt_create_options =~ /type=innodb/i)
{
$limits{'max_text_size'} = 8000; # Limit in Innobase
+ $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) &&
$main::opt_create_options =~ /type=gemini/i)
{
$limits{'working_blobs'} = 0; # Blobs not implemented yet
$limits{'max_tables'} = 500;
+ $self->{'transactions'} = 1; # Transactions enabled
}
return $self;
@@ -261,7 +252,6 @@ sub create
{
$field =~ s/ decimal/ double(10,2)/i;
$field =~ s/ big_decimal/ double(10,2)/i;
- $field =~ s/ date/ int/i; # Because of tcp ?
$query.= $field . ',';
}
foreach $index (@$index)
@@ -330,6 +320,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#
# Optimize tables for better performance
#
@@ -349,7 +345,6 @@ sub vacuum
}
}
-
#############################################################################
# Definitions for mSQL
#############################################################################
@@ -368,6 +363,7 @@ sub new
$self->{'limits'} = \%limits;
$self->{'double_quotes'} = 0;
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 0; # No transactions
$self->{'blob'} = "text(" . $limits{'max_text_size'} .")";
$self->{'text'} = "text(" . $limits{'max_text_size'} .")";
@@ -542,6 +538,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Definitions for PostgreSQL #
#############################################################################
@@ -558,11 +560,11 @@ sub new
$self->{'cmp_name'} = "pg";
$self->{'data_source'} = "DBI:Pg:dbname=$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1;
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{"vacuum"} = 1;
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'load_data_infile'} = 0;
@@ -603,31 +605,11 @@ sub new
$limits{'select_without_from'}= 1;
$limits{'subqueries'} = 1;
$limits{'table_wildcard'} = 1;
+ $limits{'truncate_table'} = 1;
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'working_all_fields'} = 1;
$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;
}
@@ -798,6 +780,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
sub vacuum
{
my ($self,$full_vacuum,$dbh_ref,@tables)=@_;
@@ -846,11 +834,11 @@ sub new
$self->{'cmp_name'} = "solid";
$self->{'data_source'} = "DBI:Solid:";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "long varchar";
$self->{'text'} = "long varchar";
$self->{'double_quotes'} = 1;
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 9999; # Probably big enough
$limits{'max_columns'} = 2000; # From crash-me
@@ -896,28 +884,6 @@ sub new
$limits{'order_by_unused'} = 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;
}
@@ -1063,6 +1029,12 @@ sub small_rollback_segment
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
sub reconnect_on_errors
{
return 0;
@@ -1087,11 +1059,11 @@ sub new
$self->{'cmp_name'} = "empress";
$self->{'data_source'} = "DBI:EmpressNet:SERVER=$host;Database=/usr/local/empress/rdbms/bin/$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 1258;
$limits{'max_columns'} = 226; # server is disconnecting????
@@ -1139,28 +1111,6 @@ sub new
$limits{'order_by_unused'} = 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;
}
@@ -1325,6 +1275,14 @@ sub query {
return $sql;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ $cmd =~ s/\'\'/\' \'/g;
+ return $cmd;
+}
+
+
sub drop_index
{
my ($self,$table,$index) = @_;
@@ -1369,11 +1327,11 @@ sub new
$self->{'cmp_name'} = "Oracle";
$self->{'data_source'} = "DBI:Oracle:$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "long";
$self->{'text'} = "long";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{"vacuum"} = 1;
$limits{'max_conditions'} = 9999; # (Actually not a limit)
@@ -1385,6 +1343,7 @@ sub new
$limits{'max_index_parts'} = 16; # Max segments/key
$limits{'max_column_name'} = 32; # max table and column name
+ $limits{'truncate_table'} = 1;
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'load_data_infile'} = 0; # Has load data infile
$limits{'lock_tables'} = 0; # Has lock tables
@@ -1421,24 +1380,6 @@ sub new
$limits{'order_by_unused'} = 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;
}
@@ -1546,6 +1487,14 @@ sub query {
return $sql;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ $cmd =~ s/\'\'/\' \'/g;
+ return $cmd;
+}
+
+
sub drop_index
{
my ($self,$table,$index) = @_;
@@ -1624,11 +1573,11 @@ sub new
$self->{'cmp_name'} = "Informix";
$self->{'data_source'} = "DBI:Informix:$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "byte in table";
$self->{'text'} = "byte in table";
$self->{'double_quotes'} = 0; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'host'} = $host;
$limits{'NEG'} = 1; # Supports -id
@@ -1778,6 +1727,16 @@ sub query {
return $sql;
}
+
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ $cmd =~ s/\\\'//g;
+ return $cmd;
+}
+
+
+
sub drop_index
{
my ($self,$table,$index) = @_;
@@ -1805,6 +1764,7 @@ sub reconnect_on_errors
return 0;
}
+
#############################################################################
# Configuration for Access
#############################################################################
@@ -1825,11 +1785,11 @@ sub new
$self->{'data_source'} .= ":$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "blob";
$self->{'text'} = "blob"; # text ?
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 97; # We get 'Query is too complex'
$limits{'max_columns'} = 255; # Max number of columns in table
@@ -1981,6 +1941,12 @@ sub reconnect_on_errors
return 1;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for Microsoft SQL server
#############################################################################
@@ -2001,11 +1967,11 @@ sub new
$self->{'data_source'} .= ":$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
$limits{'max_columns'} = 250; # Max number of columns in table
@@ -2168,10 +2134,15 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for Sybase
#############################################################################
-
package db_sybase;
sub new
@@ -2182,17 +2153,17 @@ sub new
bless $self;
$self->{'cmp_name'} = "sybase";
- $self->{'data_source'} = "DBI:ODBC:$database";
+ $self->{'data_source'} = "DBI:Sybase:database=$database";
if (defined($host) && $host ne "")
{
- $self->{'data_source'} .= ":$host";
+ $self->{'data_source'} .= ";hostname=$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{"vacuum"} = 1;
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
@@ -2249,7 +2220,19 @@ sub new
sub version
{
my ($self)=@_;
- return "Sybase enterprise 11.5 NT"; #DBI/ODBC can't return the server version
+ my ($dbh,$sth,$version,@row);
+
+ $dbh=$self->connect();
+ $sth = $dbh->prepare('SELECT @@version') or die $DBI::errstr;
+ $version="Sybase (unknown)";
+ if ($sth->execute && (@row = $sth->fetchrow_array))
+ {
+ $version=$row[0];
+ }
+ $sth->finish;
+ $dbh->disconnect;
+ return $version;
+
}
sub connect
@@ -2257,7 +2240,7 @@ sub connect
my ($self)=@_;
my ($dbh);
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
- $main::opt_password,{ PrintError => 0}) ||
+ $main::opt_password,{ PrintError => 0 , AutoCommit => 1}) ||
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
return $dbh;
}
@@ -2342,9 +2325,17 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#
# optimize the tables ....
-#
+# WARNING (from walrus)! This sub will work only from DBD:sybase
+# driver. Because if we use ODBC we don't know actual database name
+# (but DSN name only)
sub vacuum
{
my ($self,$full_vacuum,$dbh_ref)=@_;
@@ -2356,7 +2347,25 @@ sub vacuum
}
$dbh=$$dbh_ref;
$loop_time=new Benchmark;
- $dbh->do("analyze table ?? compute statistics") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
+ my (@tables,$sth,$current_table,$current_base);
+ $dbh->do("dump tran $database with truncate_only");
+ $sth=$dbh->prepare("sp_tables" ) or die "prepere";
+ $sth->execute() or die "execute";
+ while (@row = $sth->fetchrow_array()) {
+ $current_table = $row[2];
+ $current_base = $row[0];
+ next if ($current_table =~ /^sys/);
+ push(@tables,$current_table) if ($database == $current_base);
+ }
+
+ $sth->finish();
+
+ foreach $table (@tables) {
+# print "$table: \n";
+ $dbh->do("update statistics $table") or print "Oops!";
+ }
+
+# $dbh->do("analyze table ?? compute statistics") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
$end_time=new Benchmark;
print "Time for book-keeping (1): " .
Benchmark::timestr(Benchmark::timediff($end_time, $loop_time),"all") . "\n\n";
@@ -2364,6 +2373,8 @@ sub vacuum
}
+
+
#############################################################################
# Definitions for Adabas
#############################################################################
@@ -2380,11 +2391,11 @@ sub new
$self->{'cmp_name'} = "Adabas";
$self->{'data_source'} = "DBI:Adabas:$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "long";
$self->{'text'} = "long";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 50; # (Actually not a limit)
$limits{'max_columns'} = 254; # Max number of columns in table
@@ -2431,24 +2442,6 @@ sub new
$limits{'order_by_unused'} = 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;
}
@@ -2574,6 +2567,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for IBM DB2
#############################################################################
@@ -2594,11 +2593,11 @@ sub new
$self->{'data_source'} .= ":$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "varchar(255)";
$self->{'text'} = "varchar(255)";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 418; # We get 'Query is too complex'
$limits{'max_columns'} = 500; # Max number of columns in table
@@ -2747,6 +2746,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for MIMER
#############################################################################
@@ -2763,11 +2768,11 @@ sub new
$self->{'cmp_name'} = "mimer";
$self->{'data_source'} = "DBI:mimer:$database:$host";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "binary varying(15000)";
$self->{'text'} = "character varying(15000)";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'char_null'} = "cast(NULL as char(1))";
$self->{'numeric_null'} = "cast(NULL as int)";
@@ -2818,25 +2823,6 @@ sub new
$limits{'order_by_unused'} = 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;
}
@@ -2885,23 +2871,35 @@ sub connect
sub create
{
my($self,$table_name,$fields,$index,$options) = @_;
- my($query,@queries);
+ my($query,@queries,@indexes);
$query="create table $table_name (";
foreach $field (@$fields)
{
$field =~ s/ decimal/ double(10,2)/i;
$field =~ s/ big_decimal/ double(10,2)/i;
- $field =~ s/ date/ int/i; # Because of tcp ?
+ $field =~ s/ tinyint\(.*\)/ smallint/i;
+ $field =~ s/ smallint\(.*\)/ smallint/i;
+ $field =~ s/ mediumint/ integer/i;
+ $field =~ s/ float\(.*\)/ float/i;
+# $field =~ s/ date/ int/i; # Because of tcp ?
$query.= $field . ',';
}
foreach $index (@$index)
{
- $query.= $index . ',';
+ if ( $index =~ /\bINDEX\b/i )
+ {
+ my @fields = split(' ',$index);
+ my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
+ push(@indexes,$query);
+
+ } else {
+ $query.= $index . ',';
+ }
}
substr($query,-1)=")"; # Remove last ',';
$query.=" $options" if (defined($options));
- push(@queries,$query);
+ push(@queries,$query,@indexes);
return @queries;
}
@@ -2947,6 +2945,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for InterBase
#############################################################################
@@ -2961,13 +2965,13 @@ sub new
bless $self;
$self->{'cmp_name'} = "interbase";
- $self->{'data_source'} = "DBI:InterBase:database=$database";
+ $self->{'data_source'} = "DBI:InterBase:database=$database:ib_dialect=3";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "blob";
$self->{'text'} = "";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'char_null'} = "";
$self->{'numeric_null'} = "";
@@ -3016,25 +3020,6 @@ sub new
$limits{'order_by_unused'} = 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;
}
@@ -3159,6 +3144,12 @@ sub reconnect_on_errors
return 1;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for FrontBase
#############################################################################
@@ -3175,11 +3166,11 @@ sub new
$self->{'cmp_name'} = "FrontBase";
$self->{'data_source'} = "DBI:FB:dbname=$database;host=$host";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "varchar(8000000)";
$self->{'text'} = "varchar(8000000)";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = ' restrict';
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'error_on_execute_means_zero_rows'}=1;
$limits{'max_conditions'} = 5427; # (Actually not a limit)
@@ -3247,13 +3238,13 @@ sub version
my ($self)=@_;
my ($dbh,$sth,$version,@row);
- $dbh=$self->connect();
+# $dbh=$self->connect();
#
# Pick up SQLGetInfo option SQL_DBMS_VER (18)
#
#$version = $dbh->func(18, GetInfo);
- $version="FrontBase 2.1";
- $dbh->disconnect;
+ $version="FrontBase 3.3";
+# $dbh->disconnect;
return $version;
}
@@ -3288,7 +3279,7 @@ sub connect
sub create
{
my($self,$table_name,$fields,$index,$options) = @_;
- my($query,@queries);
+ my($query,@queries,@indexes,@keys);
$query="create table $table_name (";
foreach $field (@$fields)
@@ -3306,18 +3297,18 @@ sub create
}
foreach $ind (@$index)
{
- my @index;
- if ( $ind =~ /\bKEY\b/i ){
+# my @index;
+ if ( $ind =~ /(\bKEY\b)|(\bUNIQUE\b)/i ){
push(@keys,"ALTER TABLE $table_name ADD $ind");
}else{
- my @fields = split(' ',$index);
+ my @fields = split(' ',$ind);
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
- push(@index,$query);
+ push(@indexes,$query);
}
}
substr($query,-1)=")"; # Remove last ',';
$query.=" $options" if (defined($options));
- push(@queries,$query);
+ push(@queries,$query,@keys,@indexes);
return @queries;
}
@@ -3363,4 +3354,10 @@ sub reconnect_on_errors
return 1;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
1;
diff --git a/sql-bench/test-ATIS.sh b/sql-bench/test-ATIS.sh
index 77e0e7d79bf..ac3d7360198 100644
--- a/sql-bench/test-ATIS.sh
+++ b/sql-bench/test-ATIS.sh
@@ -106,6 +106,12 @@ if (!$opt_skip_create)
}
else
{
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+ }
+
for ($ti = 0; $ti <= $#table_names; $ti++)
{
my $table_name = $table_names[$ti];
@@ -119,8 +125,7 @@ if (!$opt_skip_create)
chomp;
next unless ( $_ =~ /\w/ ); # skip blank lines
my $command = $insert_start . $_ . ")";
- $command =~ s/\'\'/\' \'/g if ($opt_server =~ /empress/i || $opt_server =~ /oracle/i);
- $command =~ s/\\'//g if ($opt_server =~ /informix/i);
+ $command = $server->fix_for_insert($command);
print "$command\n" if ($opt_debug);
$command =~ s/\\'/\'\'/g if ($double_quotes);
@@ -128,8 +133,14 @@ if (!$opt_skip_create)
$row_count++;
}
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
close(DATA);
}
+
if ($opt_lock_tables)
{
$dbh->do("UNLOCK TABLES");
@@ -213,7 +224,7 @@ print "Retrieving data\n";
"SELECT airport.country_name,state.state_name,city.city_name,airport_service.direction FROM airport_service,state,airport,city WHERE airport_service.city_code=city.city_code AND airport_service.airport_code=airport.airport_code AND state.state_code=airport.state_code AND state.state_code=city.state_code AND airport.state_code=city.state_code AND airport.country_name=city.country_name AND airport.country_name=state.country_name AND city.time_zone_code=airport.time_zone_code GROUP BY airport.country_name,state.state_name,city.city_name,airport_service.direction ORDER BY state_name DESC",11,$limits->{'group_functions'},
"SELECT airport.country_name,state.state_name,city.city_name,airport_service.direction FROM airport_service,state,airport,city WHERE airport_service.city_code=city.city_code AND airport_service.airport_code=airport.airport_code AND state.state_code=airport.state_code AND state.state_code=city.state_code AND airport.state_code=city.state_code AND airport.country_name=city.country_name AND airport.country_name=state.country_name AND city.time_zone_code=airport.time_zone_code GROUP BY airport.country_name,state.state_name,city.city_name,airport_service.direction ORDER BY state_name",11,$limits->{'group_functions'},
"SELECT from_airport,to_airport,fare.fare_class,night,one_way_cost,rnd_trip_cost,class_days FROM compound_class,fare WHERE compound_class.fare_class=fare.fare_class AND one_way_cost <= 825 AND one_way_cost >= 280 AND from_airport='SFO' AND to_airport='DFW' GROUP BY from_airport,to_airport,fare.fare_class,night,one_way_cost,rnd_trip_cost,class_days ORDER BY one_way_cost",10,$limits->{'group_functions'},
- "select engines,category,cruising_speed,from_airport,to_airport FROM aircraft,flight WHERE category='JET' AND ENGINES >= 1 AND aircraft.aircraft_code=flight.aircraft_code AND to_airport NOT LIKE from_airport AND stops>0 GROUP BY engines,category,cruising_speed,from_airport,to_airport ORDER BY engines DESC",29,$limits->{'group_functions'} && $limits->{'like_with_column'},
+ "select engines,category,cruising_speed,from_airport,to_airport FROM aircraft,flight WHERE category='JET' AND engines >= 1 AND aircraft.aircraft_code=flight.aircraft_code AND to_airport NOT LIKE from_airport AND stops>0 GROUP BY engines,category,cruising_speed,from_airport,to_airport ORDER BY engines DESC",29,$limits->{'group_functions'} && $limits->{'like_with_column'},
);
@Q=(\@Q1,\@Q2,\@Q21,\@Q3,\@Q4);
diff --git a/sql-bench/test-alter-table.sh b/sql-bench/test-alter-table.sh
index 276c4863d8c..cc6453188de 100644
--- a/sql-bench/test-alter-table.sh
+++ b/sql-bench/test-alter-table.sh
@@ -74,11 +74,25 @@ do_many($dbh,$server->create("bench",\@fields,\@index));
print "Insert data into the table\n";
$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+}
+
for ($i=0 ; $i < $opt_row_count ; $i++)
{
$query="insert into bench values ( " . ("$i," x ($opt_start_field_count-1)) . "$i)";
$dbh->do($query) or die $DBI::errstr;
}
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time for insert ($opt_row_count)",
diff --git a/sql-bench/test-big-tables.sh b/sql-bench/test-big-tables.sh
index ac942f2b571..151a169d31f 100644
--- a/sql-bench/test-big-tables.sh
+++ b/sql-bench/test-big-tables.sh
@@ -127,14 +127,28 @@ end_benchmark($start_time);
sub test_query
{
my($test_text,$result_text,$query,$dbh,$count)=@_;
- my($i,$loop_time,$end_time);
+ my($i,$loop_time,$end_time, $using_transactions);
print $test_text . "\n";
$loop_time=new Benchmark;
+
+ $using_transactions=0;
+ if ($opt_fast && server->{transactions} && $query=~ /^insert /i)
+ {
+ $using_transactions=1;
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+ }
for ($i=0 ; $i < $count ; $i++)
{
defined(fetch_all_rows($dbh,$query)) or die $DBI::errstr;
}
+ if ($using_transactions)
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
+
$end_time=new Benchmark;
print $result_text . "($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
diff --git a/sql-bench/test-connect.sh b/sql-bench/test-connect.sh
index 862161e3a03..0f1aca5aaa7 100644
--- a/sql-bench/test-connect.sh
+++ b/sql-bench/test-connect.sh
@@ -27,7 +27,7 @@
use DBI;
use Benchmark;
-$opt_loop_count=10000; # Change this to make test harder/easier
+$opt_loop_count=100000; # Change this to make test harder/easier
$str_length=65000; # This is the length of blob strings in PART:5
$max_test=20; # How many times to test if the server is busy
@@ -43,9 +43,10 @@ if ($opt_small_test)
}
$opt_loop_count=min(1000, $opt_loop_count) if ($opt_tcpip);
+$small_loop_count=$opt_loop_count/10; # For connect tests
print "Testing the speed of connecting to the server and sending of data\n";
-print "All tests are done $opt_loop_count times\n\n";
+print "Connect tests are done $small_loop_count times and other tests $opt_loop_count times\n\n";
################################# PART:1 ###################################
####
@@ -59,7 +60,7 @@ print "Testing connection/disconnect\n";
$loop_time=new Benchmark;
$errors=0;
-for ($i=0 ; $i < $opt_loop_count ; $i++)
+for ($i=0 ; $i < $small_loop_count ; $i++)
{
print "$i " if (($opt_debug));
for ($j=0; $j < $max_test ; $j++)
@@ -80,27 +81,27 @@ for ($i=0 ; $i < $opt_loop_count ; $i++)
}
$end_time=new Benchmark;
print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
-print "Time to connect ($opt_loop_count): " .
+print "Time to connect ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
################################# PART:2 ###################################
#### Now we shall do first one connect, then simple select
#### (select 1..) and then close connection. This will be
-#### done $opt_loop_count times.
+#### done $small_loop_count times.
if ($limits->{'select_without_from'})
{
print "Test connect/simple select/disconnect\n";
$loop_time=new Benchmark;
- for ($i=0; $i<$opt_loop_count; $i++)
+ for ($i=0; $i < $small_loop_count; $i++)
{
$dbh = DBI->connect($server->{'data_source'}, $opt_user, $opt_password) || die $DBI::errstr;
- $sth = $dbh->do("select 1") or die $DBI::errstr;
+ $sth = $dbh->do("select $i") or die $DBI::errstr;
$dbh->disconnect;
}
$end_time=new Benchmark;
- print "Time for connect+select_simple ($opt_loop_count): " .
+ print "Time for connect+select_simple ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
@@ -116,16 +117,33 @@ if ($limits->{'select_without_from'})
{
print "Test simple select\n";
$loop_time=new Benchmark;
- for ($i=0 ; $i<$opt_loop_count ; $i++)
+ for ($i=0 ; $i < $opt_loop_count ; $i++)
{
- $sth = $dbh->do("select 1") or die $DBI::errstr;
+ $sth = $dbh->do("select $i") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for select_simple ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
-################################# PART:4 ###################################
+###########################################################################
+#### The same as the previous test, but always execute the same select
+#### This is done to test the query cache for real simple selects.
+
+if ($limits->{'select_without_from'})
+{
+ print "Test simple select\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $opt_loop_count ; $i++)
+ {
+ $sth = $dbh->do("select 10000") or die $DBI::errstr;
+ }
+ $end_time=new Benchmark;
+ print "Time for select_simple_cache ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+##########################################################################
#### First, we'll create a simple table 'bench1'
#### Then we shall do $opt_loop_count selects from this table.
#### Table will contain very simple data.
@@ -152,7 +170,7 @@ print "Testing connect/select 1 row from table/disconnect\n";
$loop_time=new Benchmark;
$errors=0;
-for ($i=0 ; $i<$opt_loop_count ; $i++)
+for ($i=0 ; $i < $small_loop_count ; $i++)
{
for ($j=0; $j < $max_test ; $j++)
{
@@ -161,14 +179,14 @@ for ($i=0 ; $i<$opt_loop_count ; $i++)
}
die $DBI::errstr if ($j == $max_test);
- $sth = $dbh->do("select * from bench1") #Select * from table with 1 record
+ $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
or die $DBI::errstr;
$dbh->disconnect;
}
$end_time=new Benchmark;
print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
-print "Time to connect+select_1_row ($opt_loop_count): " .
+print "Time to connect+select_1_row ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
#
@@ -179,9 +197,9 @@ print "Testing select 1 row from table\n";
$dbh = $server->connect();
$loop_time=new Benchmark;
-for ($i=0 ; $i<$opt_loop_count ; $i++)
+for ($i=0 ; $i < $opt_loop_count ; $i++)
{
- $sth = $dbh->do("select * from bench1") # Select * from table with 1 record
+ $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
or die $DBI::errstr;
}
@@ -190,8 +208,24 @@ print "Time to select_1_row ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
#
-# The same test, but with 2 rows.
+# Same test (as with one row) but now with a cacheable query
#
+
+$loop_time=new Benchmark;
+
+for ($i=0 ; $i < $opt_loop_count ; $i++)
+{
+ $sth = $dbh->do("select a,i,s from bench1") # Select * from table with 1 record
+ or die $DBI::errstr;
+}
+$end_time=new Benchmark;
+print "Time to select_1_row_cache ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+#
+# The same test, but with 2 rows (not cacheable).
+#
+
print "Testing select 2 rows from table\n";
$sth = $dbh->do("insert into bench1 values(2,200,'BBB')")
@@ -199,9 +233,9 @@ $sth = $dbh->do("insert into bench1 values(2,200,'BBB')")
$loop_time=new Benchmark;
-for ($i=0 ; $i<$opt_loop_count ; $i++)
+for ($i=0 ; $i < $opt_loop_count ; $i++)
{
- $sth = $dbh->do("select * from bench1") # Select * from table with 2 record
+ $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 2 record
or die $DBI::errstr;
}
@@ -209,14 +243,18 @@ $end_time=new Benchmark;
print "Time to select_2_rows ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+#
+# Simple test to test speed of functions.
+#
+
if ($limits->{'functions'})
{
print "Test select with aritmetic (+)\n";
$loop_time=new Benchmark;
- for ($i=0; $i<$opt_loop_count; $i++)
+ for ($i=0; $i < $opt_loop_count; $i++)
{
- $sth = $dbh->do("select a+a+a+a+a+a+a+a+a+a from bench1") or die $DBI::errstr;
+ $sth = $dbh->do("select a+a+a+a+a+a+a+a+a+$i from bench1") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for select_column+column ($opt_loop_count): " .
@@ -254,9 +292,9 @@ if ($opt_fast && defined($server->{vacuum}))
$loop_time=new Benchmark;
-for ($i=0 ; $i < $opt_loop_count ; $i++)
+for ($i=0 ; $i < $small_loop_count ; $i++)
{
- $sth = $dbh->prepare("select * from bench1");
+ $sth = $dbh->prepare("select b,$i from bench1");
if (!$sth->execute || !(@row = $sth->fetchrow_array) ||
length($row[0]) != $str_length)
{
@@ -266,14 +304,14 @@ for ($i=0 ; $i < $opt_loop_count ; $i++)
}
$end_time=new Benchmark;
-print "Time to select_big_str ($opt_loop_count): " .
+print "Time to select_big_str ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
$sth = $dbh->do("drop table bench1" . $server->{'drop_attr'})
or do
{
# Fix for Access 2000
- die $dbh->errstr if (!$dbh->abort_if_fatal_error());
+ die $dbh->errstr if (!$server->abort_if_fatal_error());
};
if ($opt_fast && defined($server->{vacuum}))
diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh
index 655e38b1b0e..085d7cce7f3 100644
--- a/sql-bench/test-insert.sh
+++ b/sql-bench/test-insert.sh
@@ -29,6 +29,7 @@
use DBI;
use Benchmark;
+use Data::Dumper;
$opt_loop_count=100000; # number of rows/3
$small_loop_count=10; # Loop for full table retrieval
@@ -132,6 +133,12 @@ else
$query="insert into bench1 (id,id2,id3,dummy1) values ";
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+}
+
if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value'})
{
$query_size=$server->{'limits'}->{'query_size'};
@@ -209,6 +216,12 @@ else
}
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time for insert (" . ($total_rows) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -234,6 +247,12 @@ if ($limits->{'unique_index'})
{
print "Testing insert of duplicates\n";
$loop_time=new Benchmark;
+
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ }
+
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count);
@@ -244,6 +263,11 @@ if ($limits->{'unique_index'})
die "Didn't get an error when inserting duplicate record $tmp\n";
}
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
$end_time=new Benchmark;
print "Time for insert_duplicates (" . ($opt_loop_count) . "): " .
@@ -577,7 +601,6 @@ if ($limits->{'group_functions'})
}
$sth->finish;
-
$count++;
$sth=$dbh->prepare($query="select count(*),sum(id+0.0),min(id),max(id),avg(id-0.0) from bench1") or die $DBI::errstr;
$sth->execute or die $DBI::errstr;
@@ -917,13 +940,19 @@ print "Time for update_with_key (" . ($opt_loop_count*3) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
-for ($i=0 ; $i < $opt_loop_count*3 ; $i+=3)
+$count=0;
+for ($i=1 ; $i < $opt_loop_count*3 ; $i+=3)
{
$sth = $dbh->do("update bench1 set dummy1='updated' where id=$i") or die $DBI::errstr;
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$tests,
+ $opt_loop_count));
}
-
-$end_time=new Benchmark;
-print "Time for update_with_key_prefix (" . ($opt_loop_count) . "): " .
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for update_with_key_prefix (" . ($opt_loop_count) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
print "\nTesting update of all rows\n";
@@ -1167,7 +1196,7 @@ if (!$opt_skip_delete)
}
$end_time=new Benchmark;
- print "Time for delete_all ($count): " .
+ print "Time for delete_range ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
if ($opt_lock_tables)
@@ -1203,6 +1232,7 @@ print "Insert into table with $keys keys and with a primary key with $seg parts\
# Make keys on the most important types
@types=(0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1); # A 1 for each char field
push(@fields,"field1 tinyint not null");
+push(@fields,"field_search tinyint not null");
push(@fields,"field2 mediumint not null");
push(@fields,"field3 smallint not null");
push(@fields,"field4 char(16) not null");
@@ -1222,9 +1252,10 @@ for ($i= 1 ; $i <= $seg ; $i++)
}
substr($query,-1)=")";
push (@keys,$query);
+push (@keys,"index index2 (field_search)");
#Create other keys
-for ($i=2 ; $i <= $keys ; $i++)
+for ($i=3 ; $i <= $keys ; $i++)
{
push(@keys,"index index$i (field$i)");
}
@@ -1242,6 +1273,11 @@ if ($server->small_rollback_segment())
}
$loop_time=new Benchmark;
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+}
+
$fields=$#fields;
if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value'})
{
@@ -1250,11 +1286,11 @@ if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value
$res=$query;
for ($i=0; $i < $many_keys_loop_count; $i++)
{
+ $id= $i & 127;
$rand=$random[$i];
- $tmp="(" . ($i & 127) . ",$rand," . ($i & 32766) .
- ",'ABCDEF$rand',0,";
+ $tmp="($id,$id,$rand," . ($i & 32766) . ",'ABCDEF$rand',0,";
- for ($j=5; $j <= $fields ; $j++)
+ for ($j=6; $j <= $fields ; $j++)
{
$tmp.= ($types[$j] == 0) ? "$rand," : "'$rand',";
}
@@ -1275,11 +1311,12 @@ else
{
for ($i=0; $i < $many_keys_loop_count; $i++)
{
+ $id= $i & 127;
$rand=$random[$i];
- $query="insert into bench1 values (" . ($i & 127) . ",$rand," . ($i & 32767) .
+ $query="insert into bench1 values ($id,$id,$rand," . ($i & 32767) .
",'ABCDEF$rand',0,";
- for ($j=5; $j <= $fields ; $j++)
+ for ($j=6; $j <= $fields ; $j++)
{
$query.= ($types[$j] == 0) ? "$rand," : "'$rand',";
}
@@ -1288,6 +1325,13 @@ else
$dbh->do($query) or die "Got error $DBI::errstr with query: $query\n";
}
}
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time for insert_key ($many_keys_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -1316,11 +1360,24 @@ if ($opt_fast && defined($server->{vacuum}))
print "Testing update of keys\n";
$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+}
+
for ($i=0 ; $i< 256; $i++)
{
- $dbh->do("update bench1 set field5=1 where field1=$i")
- or die "Got error $DBI::errstr with query: update bench1 set field5=1 where field1=$i\n";
+ $dbh->do("update bench1 set field5=1 where field_search=$i")
+ or die "Got error $DBI::errstr with query: update bench1 set field5=1 where field_search=$i\n";
+}
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
}
+
$end_time=new Benchmark;
print "Time for update_of_primary_key_many_keys (256): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -1360,29 +1417,31 @@ $count=0;
for ($i=0 ; $i < 128 ; $i++)
{
$count++;
- $dbh->do("delete from bench1 where field1 = $i") or die $DBI::errstr;
+ $dbh->do("delete from bench1 where field_search = $i") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for delete_big_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+if ($opt_lock_tables)
+{
+ $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
+}
+
print "Deleting everything from table\n";
$count=1;
if ($opt_fast)
{
- $dbh->do("delete from bench1") or die $DBI::errstr;
+ $query= ($limits->{'truncate_table'} ? "truncate table bench1" :
+ "delete from bench1");
+ $dbh->do($query) or die $DBI::errstr;
}
else
{
$dbh->do("delete from bench1 where field1 > 0") or die $DBI::errstr;
}
-if ($opt_lock_tables)
-{
- $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
-}
-
$end_time=new Benchmark;
print "Time for delete_all_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -1409,12 +1468,18 @@ if ($limits->{'insert_multi_value'})
"dummy1 char(30)"],
["primary key (id,id2)",
"index index_id3 (id3)"]));
+
+ $loop_time=new Benchmark;
+
if ($opt_lock_tables)
{
$sth = $dbh->do("LOCK TABLES bench1 write") || die $DBI::errstr;
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ }
- $loop_time=new Benchmark;
print "Inserting $opt_loop_count rows with multiple values\n";
$query="insert into bench1 values ";
$res=$query;
@@ -1437,6 +1502,11 @@ if ($limits->{'insert_multi_value'})
{
$sth = $dbh->do("UNLOCK TABLES ") || die $DBI::errstr;
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
$end_time=new Benchmark;
print "Time for multiple_value_insert (" . ($opt_loop_count) . "): " .
diff --git a/sql-bench/test-select.sh b/sql-bench/test-select.sh
index 1ecad5804c5..a5ae1da7283 100644
--- a/sql-bench/test-select.sh
+++ b/sql-bench/test-select.sh
@@ -92,6 +92,12 @@ if ($opt_fast && defined($server->{vacuum}))
print "Inserting $opt_loop_count rows\n";
$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+}
+
$query="insert into bench1 values (";
$half_done=$opt_loop_count/2;
for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ; $id++,$rev_id--)
@@ -105,6 +111,12 @@ for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ; $id++,$rev_id--)
}
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time to insert ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -141,10 +153,10 @@ if ($limits->{'group_functions'})
$loop_time=new Benchmark;
for ($tests=0 ; $tests < $opt_loop_count ; $tests++)
{
- fetch_all_rows($dbh,"select sum(idn+$tests),sum(rev_idn-$tests) from bench1");
+ fetch_all_rows($dbh,"select sum(idn+100),sum(rev_idn-100) from bench1");
}
$end_time=new Benchmark;
- print "Time for select_query_cache ($opt_loop_count): " .
+ print "Time for select_cache ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
# If the database has a query cache, the following loop should be much
@@ -156,7 +168,7 @@ if ($limits->{'group_functions'})
fetch_all_rows($dbh,"select sum(idn+$tests),sum(rev_idn-$tests) from bench1");
}
$end_time=new Benchmark;
- print "Time for select_query_cache2 ($opt_loop_count): " .
+ print "Time for select_cache2 ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
diff --git a/sql-bench/test-transactions.sh b/sql-bench/test-transactions.sh
new file mode 100644
index 00000000000..b081b89fb69
--- /dev/null
+++ b/sql-bench/test-transactions.sh
@@ -0,0 +1,297 @@
+#!@PERL@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# Test of transactions performance.
+#
+
+##################### Standard benchmark inits ##############################
+
+use DBI;
+use Benchmark;
+#use warnings;
+
+$opt_groups=27; # Characters are 'A' -> Z
+
+$opt_loop_count=10000; # Change this to make test harder/easier
+$opt_medium_loop_count=100; # Change this to make test harder/easier
+
+chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
+
+# Avoid warnings for variables in bench-init.pl
+# (Only works with perl 5.6)
+#our ($opt_small_test, $opt_small_tables, $opt_debug, $opt_force);
+
+if ($opt_small_test || $opt_small_tables)
+{
+ $opt_loop_count/=100;
+ $opt_medium_loop_count/=10;
+}
+
+
+if (!$server->{transactions} && !$opt_force)
+{
+ print "Test skipped because the database doesn't support transactions\n";
+ exit(0);
+}
+
+####
+#### Connect and start timeing
+####
+
+$start_time=new Benchmark;
+$dbh = $server->connect();
+
+###
+### Create Table
+###
+
+print "Creating tables\n";
+$dbh->do("drop table bench1");
+$dbh->do("drop table bench2");
+
+do_many($dbh,$server->create("bench1",
+ ["idn int NOT NULL",
+ "rev_idn int NOT NULL",
+ "region char(1) NOT NULL",
+ "grp int NOT NULL",
+ "updated tinyint NOT NULL"],
+ ["primary key (idn)",
+ "unique (region,grp)"]));
+do_many($dbh,$server->create("bench2",
+ ["idn int NOT NULL",
+ "rev_idn int NOT NULL",
+ "region char(1) NOT NULL",
+ "grp int NOT NULL",
+ "updated tinyint NOT NULL"],
+ ["primary key (idn)",
+ "unique (region,grp)"]));
+
+$dbh->{AutoCommit} = 0;
+
+###
+### Test insert perfomance
+###
+
+test_insert("bench1","insert_commit",0);
+test_insert("bench2","insert_autocommit",1);
+
+sub test_insert
+{
+ my ($table, $test_name, $auto_commit)= @_;
+ my ($loop_time,$end_time,$id,$rev_id,$grp,$region);
+
+ $dbh->{AutoCommit}= $auto_commit;
+ $loop_time=new Benchmark;
+
+ for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ;
+ $id++,$rev_id--)
+ {
+ $grp=$id/$opt_groups;
+ $region=chr(65+$id%$opt_groups);
+ do_query($dbh,"insert into $table values ($id,$rev_id,'$region',$grp,0)");
+ }
+
+ $dbh->commit if (!$auto_commit);
+ $end_time=new Benchmark;
+ print "Time for $test_name ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+###
+### Test rollback performance
+###
+
+print "Test transactions rollback performance\n" if($opt_debug);
+
+##
+## Insert rollback test
+##
+
+#
+# Test is done by inserting 100 rows in a table with lots of rows and
+# then doing a rollback on these
+#
+
+{
+ my ($id,$rev_id,$grp,$region,$end,$loop_time,$end_time,$commit_loop,$count);
+
+ $dbh->{AutoCommit} = 0;
+ $loop_time=new Benchmark;
+ $end=$opt_loop_count*2;
+ $count=0;
+
+ for ($commit_loop=1, $id=$opt_loop_count ; $id < $end ;
+ $id++, $commit_loop++)
+ {
+ $rev_id=$end-$id;
+ $grp=$id/$opt_groups;
+ $region=chr(65+$id%$opt_groups);
+ do_query($dbh,"insert into bench1 values ($id,$rev_id,'$region',$grp,0)");
+ if ($commit_loop >= $opt_medium_loop_count)
+ {
+ $dbh->rollback;
+ $commit_loop=0;
+ $count++;
+ }
+ }
+ if ($commit_loop > 1)
+ {
+ $dbh->rollback;
+ $count++;
+ }
+ $end_time=new Benchmark;
+ print "Time for insert_rollback ($count:$opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+##
+## Update rollback test
+##
+
+#
+# Test is done by updating 100 rows in a table with lots of rows and
+# then doing a rollback on these
+#
+
+{
+ my ($id,$loop_time,$end_time,$commit_loop,$count);
+
+ $dbh->{AutoCommit} = 0;
+ $loop_time=new Benchmark;
+ $end=$opt_loop_count*2;
+ $count=0;
+
+ for ($commit_loop=1, $id=0 ; $id < $opt_loop_count ; $id++, $commit_loop++)
+ {
+ do_query($dbh,"update bench1 set updated=2 where idn=$id");
+ if ($commit_loop >= $opt_medium_loop_count)
+ {
+ $dbh->rollback;
+ $commit_loop=0;
+ $count++;
+ }
+ }
+ if ($commit_loop > 1)
+ {
+ $dbh->rollback;
+ $count++;
+ }
+ $end_time=new Benchmark;
+ print "Time for update_rollback ($count:$opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+##
+## Delete rollback test
+##
+
+#
+# Test is done by deleting 100 rows in a table with lots of rows and
+# then doing a rollback on these
+#
+
+{
+ my ($id,$loop_time,$end_time,$commit_loop,$count);
+
+ $dbh->{AutoCommit} = 0;
+ $loop_time=new Benchmark;
+ $end=$opt_loop_count*2;
+ $count=0;
+
+ for ($commit_loop=1, $id=0 ; $id < $opt_loop_count ; $id++, $commit_loop++)
+ {
+ do_query($dbh,"delete from bench1 where idn=$id");
+ if ($commit_loop >= $opt_medium_loop_count)
+ {
+ $dbh->rollback;
+ $commit_loop=0;
+ $count++;
+ }
+ }
+ if ($commit_loop > 1)
+ {
+ $dbh->rollback;
+ $count++;
+ }
+ $end_time=new Benchmark;
+ print "Time for delete_rollback ($count:$opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+
+###
+### Test update perfomance
+###
+
+test_update("bench1","update_commit",0);
+test_update("bench2","update_autocommit",1);
+
+sub test_update
+{
+ my ($table, $test_name, $auto_commit)= @_;
+ my ($loop_time,$end_time,$id);
+
+ $dbh->{AutoCommit}= $auto_commit;
+ $loop_time=new Benchmark;
+
+ for ($id=0 ; $id < $opt_loop_count ; $id++)
+ {
+ do_query($dbh,"update bench1 set updated=1 where idn=$id");
+ }
+
+ $dbh->commit if (!$auto_commit);
+ $end_time=new Benchmark;
+ print "Time for $test_name ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+###
+### Test delete perfomance
+###
+
+test_delete("bench1","delete_commit",0);
+test_delete("bench2","delete_autocommit",1);
+
+sub test_delete
+{
+ my ($table, $test_name, $auto_commit)= @_;
+ my ($loop_time,$end_time,$id);
+
+ $dbh->{AutoCommit}= $auto_commit;
+ $loop_time=new Benchmark;
+
+ for ($id=0 ; $id < $opt_loop_count ; $id++)
+ {
+ do_query($dbh,"delete from $table where idn=$id");
+ }
+ $dbh->commit if (!$auto_commit);
+ $end_time=new Benchmark;
+ print "Time for $test_name ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+####
+#### End of benchmark
+####
+
+$sth = $dbh->do("drop table bench1" . $server->{'drop_attr'}) or die $DBI::errstr;
+$sth = $dbh->do("drop table bench2" . $server->{'drop_attr'}) or die $DBI::errstr;
+
+$dbh->disconnect; # close connection
+end_benchmark($start_time);
diff --git a/sql-bench/test-wisconsin.sh b/sql-bench/test-wisconsin.sh
index a017120259e..adc3e5b5aa4 100644
--- a/sql-bench/test-wisconsin.sh
+++ b/sql-bench/test-wisconsin.sh
@@ -48,27 +48,36 @@ init_query();
print "Wisconsin benchmark test\n\n";
-if (!$opt_skip_create)
+if ($opt_skip_create)
{
- $loop_time= new Benchmark;
- for($ti = 0; $ti <= $#table_names; $ti++)
+ if ($opt_lock_tables)
{
- my $table_name = $table_names[$ti];
- my $array_ref = $tables[$ti];
-
- # This may fail if we have no table so do not check answer
- $sth = $dbh->do("drop table $table_name" . $server->{'drop_attr'});
- print "Creating table $table_name\n" if ($opt_verbose);
- do_many($dbh,@$array_ref);
+ @tmp=@table_names; push(@tmp,@extra_names);
+ $sth = $dbh->do("LOCK TABLES " . join(" WRITE,", @tmp) . " WRITE") ||
+ die $DBI::errstr;
}
- $end_time=new Benchmark;
- print "Time for create_table ($#tables): " .
- timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+ goto start_benchmark;
+}
- if ($opt_fast && defined($server->{vacuum}))
- {
- $server->vacuum(1,\$dbh);
- }
+$loop_time= new Benchmark;
+for($ti = 0; $ti <= $#table_names; $ti++)
+{
+ my $table_name = $table_names[$ti];
+ my $array_ref = $tables[$ti];
+
+ # This may fail if we have no table so do not check answer
+ $sth = $dbh->do("drop table $table_name" . $server->{'drop_attr'});
+ print "Creating table $table_name\n" if ($opt_verbose);
+ do_many($dbh,@$array_ref);
+}
+$end_time=new Benchmark;
+print "Time for create_table ($#tables): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(1,\$dbh);
+}
####
@@ -100,6 +109,11 @@ if ($opt_fast && $server->{'limits'}->{'load_data_infile'})
}
else
{
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ }
+
for ($ti = 0; $ti <= $#table_names; $ti++)
{
my $table_name = $table_names[$ti];
@@ -124,10 +138,17 @@ else
}
close(DATA);
}
+
if ($opt_lock_tables)
{
do_query($dbh,"UNLOCK TABLES");
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time to insert ($row_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
@@ -159,13 +180,6 @@ $sth = $dbh->do("delete from Bprime where Bprime.unique2 >= 1000") or
$end_time=new Benchmark;
print "Time to delete_big (1): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
-}
-elsif ($opt_lock_tables)
-{
- @tmp=@table_names; push(@tmp,@extra_names);
- $sth = $dbh->do("LOCK TABLES " . join(" WRITE,", @tmp) . " WRITE") ||
- die $DBI::errstr;
-}
if ($opt_fast && defined($server->{vacuum}))
{
@@ -176,7 +190,9 @@ if ($opt_fast && defined($server->{vacuum}))
#### Running the benchmark
####
-print "Running actual benchmark\n";
+start_benchmark:
+
+print "Running the actual benchmark\n";
$loop_time= new Benchmark;
$count=0;
@@ -226,7 +242,7 @@ sub init_data
{
@onek=
$server->create("onek",
- ["unique1 int(4) NOT NULL",
+ ["unique1 int(5) NOT NULL",
"unique2 int(4) NOT NULL",
"two int(4)",
"four int(4)",
diff --git a/sql/ChangeLog b/sql/ChangeLog
index 2289765afad..a75e9761766 100644
--- a/sql/ChangeLog
+++ b/sql/ChangeLog
@@ -1,3 +1,8 @@
+2000-12-07 Jeremy Cole <jeremy@mysql.com>
+
+* Added UPDATE ... ORDER BY ...
+* Added DELETE ... ORDER BY ...
+
2000-11-11 Jeremy Cole <jeremy@mysql.com>
* Added ALTER TABLE ... ORDER BY ...
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 47cee300b09..51c0a0f1fe8 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -21,27 +21,29 @@ MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
INCLUDES = @MT_INCLUDES@ \
- @bdb_includes@ @innodb_includes@ @gemini_includes@ \
+ @bdb_includes@ @innodb_includes@ \
-I$(srcdir)/../include \
-I$(srcdir)/../regex \
- -I$(srcdir) -I../include -I.. -I.
+ -I$(srcdir) -I../include -I. $(openssl_includes)
WRAPLIBS= @WRAPLIBS@
SUBDIRS = share
libexec_PROGRAMS = mysqld
noinst_PROGRAMS = gen_lex_hash
-gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
-LDADD = ../isam/libnisam.a \
- ../merge/libmerge.a \
+gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
+LDADD = @isam_libs@ \
../myisam/libmyisam.a \
../myisammrg/libmyisammrg.a \
../heap/libheap.a \
+ ../vio/libvio.a \
../mysys/libmysys.a \
../dbug/libdbug.a \
../regex/libregex.a \
../strings/libmystrings.a
+
mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
- @bdb_libs@ @innodb_libs@ @gemini_libs@ \
- $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@
+ @bdb_libs@ @innodb_libs@ @pstack_libs@ \
+ @innodb_system_libs@ \
+ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h item_uniq.h \
item_create.h mysql_priv.h \
@@ -49,37 +51,37 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_manager.h sql_map.h sql_string.h unireg.h \
field.h handler.h \
ha_isammrg.h ha_isam.h ha_myisammrg.h\
- ha_heap.h ha_myisam.h ha_berkeley.h ha_innobase.h \
- ha_gemini.h opt_range.h opt_ft.h \
+ ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \
+ opt_range.h opt_ft.h \
sql_select.h structs.h table.h sql_udf.h hash_filo.h\
- lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h \
- log_event.h mini_client.h sql_repl.h slave.h \
- stacktrace.h
-mysqld_SOURCES = sql_lex.cc \
+ lex.h lex_symbol.h sql_acl.h sql_crypt.h \
+ log_event.h mini_client.h sql_repl.h slave.h \
+ stacktrace.h sql_sort.h sql_cache.h set_var.h
+mysqld_SOURCES = sql_lex.cc sql_handler.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
thr_malloc.cc item_create.cc \
field.cc key.cc sql_class.cc sql_list.cc \
- net_serv.cc violite.c net_pkg.cc lock.cc my_lock.c \
+ net_serv.cc net_pkg.cc lock.cc my_lock.c \
sql_string.cc sql_manager.cc sql_map.cc \
mysqld.cc password.c hash_filo.cc hostname.cc \
- convert.cc sql_parse.cc sql_yacc.yy \
+ convert.cc set_var.cc sql_parse.cc sql_yacc.yy \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
- sql_update.cc sql_delete.cc sql_do.cc \
+ sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
procedure.cc item_uniq.cc sql_test.cc \
log.cc log_event.cc init.cc derror.cc sql_acl.cc \
- unireg.cc \
+ unireg.cc des_key_file.cc \
time.cc opt_range.cc opt_sum.cc opt_ft.cc \
records.cc filesort.cc handler.cc \
ha_heap.cc ha_myisam.cc ha_myisammrg.cc \
- ha_berkeley.cc ha_innobase.cc ha_gemini.cc \
+ ha_berkeley.cc ha_innodb.cc \
ha_isam.cc ha_isammrg.cc \
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
- slave.cc sql_repl.cc \
+ slave.cc sql_repl.cc sql_union.cc \
mini_client.cc mini_client_errors.c \
- md5.c stacktrace.c
+ stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc
gen_lex_hash_SOURCES = gen_lex_hash.cc
gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
diff --git a/sql/cache_manager.cc b/sql/cache_manager.cc
index 9ea25315f8c..307fe331e5c 100644
--- a/sql/cache_manager.cc
+++ b/sql/cache_manager.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,7 +18,7 @@
#pragma implementation /* gcc: Class implementation */
#endif
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "cache_manager.h"
@@ -117,7 +117,7 @@ void *cache_manager::alloc(uint size)
{
void *llist;
void *abs_ptr;
-
+
size=ALIGN_SIZE(size+HEADER_LENGTH+SUFFIX_LENGTH);
if (!(llist = find_in_llist(size)))
{
@@ -127,7 +127,7 @@ void *cache_manager::alloc(uint size)
}
size_of_found_block=int4korr((char*) llist) & ALLOC_MASK;
// if (size_of_found_block < SMALLEST_BLOCK)
-
+
abs_ptr = link_into_abs(llist);
return abs_ptr;
}
diff --git a/sql/cache_manager.h b/sql/cache_manager.h
index fc3b8f7016a..d422a86ea8e 100644
--- a/sql/cache_manager.h
+++ b/sql/cache_manager.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -59,7 +59,3 @@ class cache_manager {
bool *dealloc(void *); /* Deallocate blocks (with *ptr_arg) */
void clear(void); /* Clear the cache */
};
-
-
-
-
diff --git a/sql/convert.cc b/sql/convert.cc
index 2c8b775dca2..e4ae13d1e07 100644
--- a/sql/convert.cc
+++ b/sql/convert.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -27,7 +27,7 @@
#include "mysql_priv.h"
/****************************************************************************
-** Convert tables
+ Convert tables
****************************************************************************/
/* Windows cp1251->koi8 and reverse conversion by Timur I. Bakeyev <translate@bat.ru> */
@@ -397,19 +397,19 @@ static unsigned char win1251ukr_koi8_ukr[256] = {
****************************************************************************/
-CONVERT conv_cp1251_koi8("cp1251_koi8", cp1251_koi8, koi8_cp1251);
+CONVERT conv_cp1251_koi8("cp1251_koi8", cp1251_koi8, koi8_cp1251, 1);
#ifdef DEFINE_ALL_CHARACTER_SETS
-CONVERT conv_cp1250_latin2("cp1250_latin2", t1250_til2, til2_t1250);
-CONVERT conv_kam_latin2("kam_latin2", tkam_til2, til2_tkam);
-CONVERT conv_mac_latin2("mac_latin2", tmac_til2, til2_tmac);
-CONVERT conv_macce_latin2("macce_latin2", tmacce_til2, til2_tmacce);
-CONVERT conv_pc2_latin2("pc2_latin2", tpc2_til2, til2_tpc2);
-CONVERT conv_vga_latin2("vga_latin2", tvga_til2, til2_tvga);
-CONVERT conv_koi8_cp1251("koi8_cp1251", koi8_cp1251, cp1251_koi8);
+CONVERT conv_cp1250_latin2("cp1250_latin2", t1250_til2, til2_t1250, 2);
+CONVERT conv_kam_latin2("kam_latin2", tkam_til2, til2_tkam, 3);
+CONVERT conv_mac_latin2("mac_latin2", tmac_til2, til2_tmac, 4);
+CONVERT conv_macce_latin2("macce_latin2", tmacce_til2, til2_tmacce, 5);
+CONVERT conv_pc2_latin2("pc2_latin2", tpc2_til2, til2_tpc2, 6);
+CONVERT conv_vga_latin2("vga_latin2", tvga_til2, til2_tvga, 7);
+CONVERT conv_koi8_cp1251("koi8_cp1251", koi8_cp1251, cp1251_koi8, 8);
CONVERT conv_win1251ukr_koi8_ukr("win1251ukr_koi8_ukr", win1251ukr_koi8_ukr,
- koi8_ukr_win1251ukr);
+ koi8_ukr_win1251ukr, 9);
CONVERT conv_koi8_ukr_win1251ukr("koi8_ukr_win1251ukr", koi8_ukr_win1251ukr,
- win1251ukr_koi8_ukr);
+ win1251ukr_koi8_ukr, 10);
#endif /* DEFINE_ALL_CHARACTER_SETS */
CONVERT *convert_tables[]= {
diff --git a/sql/custom_conf.h b/sql/custom_conf.h
index af6012e28ec..19ced12bfbb 100644
--- a/sql/custom_conf.h
+++ b/sql/custom_conf.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/derror.cc b/sql/derror.cc
index 62971fde394..7ebe6e4b3c5 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -44,13 +44,14 @@ static void read_texts(const char *file_name,const char ***point,
uint error_messages)
{
register uint i;
- uint ant,funktpos,length,textant;
+ uint count,funktpos,length,textcount;
File file;
char name[FN_REFLEN];
const char *buff;
uchar head[32],*pos;
DBUG_ENTER("read_texts");
+ *point=0; // If something goes wrong
LINT_INIT(buff);
funktpos=0;
if ((file=my_open(fn_format(name,file_name,language,"",4),
@@ -63,37 +64,38 @@ static void read_texts(const char *file_name,const char ***point,
if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
head[2] != 2 || head[3] != 1)
goto err; /* purecov: inspected */
- textant=head[4];
- length=uint2korr(head+6); ant=uint2korr(head+8);
+ textcount=head[4];
+ length=uint2korr(head+6); count=uint2korr(head+8);
- if (ant < error_messages)
+ if (count < error_messages)
{
- fprintf(stderr,"\n%s: Fatal error: Error message file '%s' had only %d error messages, but it should have at least %d error messages.\n\
-Check that the above file is the right version for this program!\n\n",
- my_progname,name,ant,error_messages);
+ sql_print_error("\
+Error message file '%s' had only %d error messages,\n\
+but it should contain at least %d error messages.\n\
+Check that the above file is the right version for this program!",
+ name,count,error_messages);
VOID(my_close(file,MYF(MY_WME)));
- clean_up(0); /* Clean_up frees everything */
- exit(1); /* We can't continue */
+ unireg_abort(1);
}
x_free((gptr) *point); /* Free old language */
if (!(*point= (const char**)
- my_malloc((uint) (length+ant*sizeof(char*)),MYF(0))))
+ my_malloc((uint) (length+count*sizeof(char*)),MYF(0))))
{
funktpos=2; /* purecov: inspected */
goto err; /* purecov: inspected */
}
- buff= (char*) (*point + ant);
+ buff= (char*) (*point + count);
- if (my_read(file,(byte*) buff,(uint) ant*2,MYF(MY_NABP))) goto err;
- for (i=0, pos= (uchar*) buff ; i< ant ; i++)
+ if (my_read(file,(byte*) buff,(uint) count*2,MYF(MY_NABP))) goto err;
+ for (i=0, pos= (uchar*) buff ; i< count ; i++)
{
(*point)[i]=buff+uint2korr(pos);
pos+=2;
}
if (my_read(file,(byte*) buff,(uint) length,MYF(MY_NABP))) goto err;
- for (i=1 ; i < textant ; i++)
+ for (i=1 ; i < textcount ; i++)
{
point[i]= *point +uint2korr(head+10+i+i);
}
@@ -103,20 +105,19 @@ Check that the above file is the right version for this program!\n\n",
err:
switch (funktpos) {
case 2:
- buff="\n%s: Fatal error: Not enough memory for messagefile '%s'\n\n";
+ buff="Not enough memory for messagefile '%s'";
break;
case 1:
- buff="\n%s: Fatal error: Can't read from messagefile '%s'\n\n";
+ buff="Can't read from messagefile '%s'";
break;
default:
- buff="\n%s: Fatal error: Can't find messagefile '%s'\n\n";
+ buff="Can't find messagefile '%s'";
break;
}
if (file != FERR)
VOID(my_close(file,MYF(MY_WME)));
- fprintf(stderr,buff,my_progname,name);
- clean_up(0); /* Clean_up frees everything */
- exit(1); /* We can't continue */
+ sql_print_error(buff,name);
+ unireg_abort(1);
} /* read_texts */
diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc
new file mode 100644
index 00000000000..d9c924b5a3c
--- /dev/null
+++ b/sql/des_key_file.cc
@@ -0,0 +1,107 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <mysql_priv.h>
+#include <m_ctype.h>
+
+#ifdef HAVE_OPENSSL
+
+struct st_des_keyschedule des_keyschedule[10];
+uint des_default_key;
+pthread_mutex_t LOCK_des_key_file;
+static int initialized;
+
+/*
+ Function which loads DES keys from plaintext file into memory on MySQL
+ server startup and on command FLUSH DES_KEY_FILE.
+ Blame tonu@spam.ee on bugs ;)
+
+ RETURN
+ 0 ok
+ 1 Error
+*/
+
+bool
+load_des_key_file(const char *file_name)
+{
+ bool result=1;
+ File file;
+ IO_CACHE io;
+ DBUG_ENTER("load_des_key_file");
+ DBUG_PRINT("enter",("name: %s",file_name));
+
+ if (!initialized)
+ {
+ initialized=1;
+ pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
+ }
+
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ if ((file=my_open(file_name,O_RDONLY | O_BINARY ,MYF(MY_WME))) < 0 ||
+ init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME)))
+ goto error;
+
+ bzero((char*) des_keyschedule,sizeof(struct st_des_keyschedule) * 10);
+ des_default_key=15; // Impossible key
+ for (;;)
+ {
+ char *start, *end;
+ char buf[1024], offset;
+ st_des_keyblock keyblock;
+ uint length;
+
+ if (!(length=my_b_gets(&io,buf,sizeof(buf)-1)))
+ break; // End of file
+ offset=buf[0];
+ if (offset >= '0' && offset <= '9') // If ok key
+ {
+ offset=(char) (offset - '0');
+ // Remove newline and possible other control characters
+ for (start=buf+1 ; isspace(*start) ; start++) ;
+ end=buf+length;
+ for (end=strend(buf) ; end > start && !isgraph(end[-1]) ; end--) ;
+
+ if (start != end)
+ {
+ des_cblock ivec;
+ bzero((char*) &ivec,sizeof(ivec));
+ // We make good 24-byte (168 bit) key from given plaintext key with MD5
+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
+ (uchar *) start, (int) (end-start),1,
+ (uchar *) &keyblock,
+ ivec);
+ des_set_key_unchecked(&keyblock.key1,des_keyschedule[(int)offset].ks1);
+ des_set_key_unchecked(&keyblock.key2,des_keyschedule[(int)offset].ks2);
+ des_set_key_unchecked(&keyblock.key3,des_keyschedule[(int)offset].ks3);
+ if (des_default_key == 15)
+ des_default_key= (uint) offset; // use first as def.
+ }
+ }
+ else if (offset != '#')
+ sql_print_error("load_des_file: Found wrong key_number: %c",offset);
+ }
+ result=0;
+
+error:
+ if (file >= 0)
+ {
+ my_close(file,MYF(0));
+ end_io_cache(&io);
+ }
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ DBUG_RETURN(result);
+}
+#endif /* HAVE_OPENSSL */
diff --git a/sql/field.cc b/sql/field.cc
index 246427cc2ac..eb3dc7948d4 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -42,7 +42,7 @@
#endif
/*****************************************************************************
-** Instansiate templates and static variables
+ Instansiate templates and static variables
*****************************************************************************/
#ifdef __GNUC__
@@ -50,69 +50,13 @@ template class List<create_field>;
template class List_iterator<create_field>;
#endif
-struct st_decstr {
- uint nr_length,nr_dec,sign,extra;
- char sign_char;
-};
-
uchar Field_null::null[1]={1};
const char field_separator=',';
/*****************************************************************************
-** Static help functions
+ Static help functions
*****************************************************************************/
- /*
- Calculate length of number and it's parts
- Increment cuted_fields if wrong number
- */
-
-static bool
-number_dec(struct st_decstr *sdec, const char *str, const char *end)
-{
- sdec->sign=sdec->extra=0;
- if (str == end)
- {
- current_thd->cuted_fields++;
- sdec->nr_length=sdec->nr_dec=sdec->sign=0;
- sdec->extra=1; // We must put one 0 before .
- return 1;
- }
-
- if (*str == '-' || *str == '+') /* sign */
- {
- sdec->sign_char= *str;
- sdec->sign=1;
- str++;
- }
- const char *start=str;
- while (str != end && isdigit(*str))
- str++;
- if (!(sdec->nr_length=(uint) (str-start)))
- sdec->extra=1; // We must put one 0 before .
- start=str;
- if (str != end && *str == '.')
- {
- str++;
- start=str;
- while (str != end && isdigit(*str))
- str++;
- }
- sdec->nr_dec=(uint) (str-start);
- if (current_thd->count_cuted_fields)
- {
- while (str != end && isspace(*str))
- str++; /* purecov: inspected */
- if (str != end)
- {
- current_thd->cuted_fields++;
- return 1;
- }
- }
- return 0;
-}
-
-
void Field_num::prepend_zeros(String *value)
{
int diff;
@@ -127,8 +71,8 @@ void Field_num::prepend_zeros(String *value)
}
/*
-** Test if given number is a int (or a fixed format float with .000)
-** This is only used to give warnings in ALTER TABLE or LOAD DATA...
+ Test if given number is a int (or a fixed format float with .000)
+ This is only used to give warnings in ALTER TABLE or LOAD DATA...
*/
bool test_if_int(const char *str,int length)
@@ -141,7 +85,7 @@ bool test_if_int(const char *str,int length)
str++;
if (str == end)
return 0; // Error: Empty string
- for ( ; str != end ; str++)
+ for (; str != end ; str++)
{
if (!isdigit(*str))
{
@@ -204,7 +148,7 @@ static bool test_if_real(const char *str,int length)
length--; str++;
}
}
- for ( ; length ; length--, str++)
+ for (; length ; length--, str++)
{ // Allow end space
if (!isspace(*str))
return 0;
@@ -215,18 +159,19 @@ static bool test_if_real(const char *str,int length)
/****************************************************************************
** Functions for the base classes
-** This is a unpacked number.
+** This is an unpacked number.
****************************************************************************/
Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
- :ptr(ptr_arg),null_ptr(null_ptr_arg),null_bit(null_bit_arg),
- table(table_arg),query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0),
- table_name(table_arg ? table_arg->table_name : 0),
- field_name(field_name_arg), unireg_check(unireg_check_arg),
- field_length(length_arg)
+ :ptr(ptr_arg),null_ptr(null_ptr_arg),
+ table(table_arg),table_name(table_arg ? table_arg->table_name : 0),
+ field_name(field_name_arg),
+ query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0),
+ unireg_check(unireg_check_arg),
+ field_length(length_arg),null_bit(null_bit_arg)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
}
@@ -242,13 +187,13 @@ void Field::copy_from_tmp(int row_offset)
memcpy(ptr,ptr+row_offset,pack_length());
if (null_ptr)
{
- *null_ptr= ((null_ptr[0] & (uchar) ~(uint) null_bit) |
- null_ptr[row_offset] & (uchar) null_bit);
+ *null_ptr= (uchar) ((null_ptr[0] & (uchar) ~(uint) null_bit) |
+ null_ptr[row_offset] & (uchar) null_bit);
}
}
-bool Field::send(String *packet)
+bool Field::send(THD *thd, String *packet)
{
if (is_null())
return net_store_null(packet);
@@ -256,7 +201,7 @@ bool Field::send(String *packet)
String tmp(buff,sizeof(buff));
val_str(&tmp,&tmp);
CONVERT *convert;
- if ((convert=current_thd->convert_set))
+ if ((convert=thd->variables.convert_set))
return convert->store(packet,tmp.ptr(),tmp.length());
return net_store_data(packet,tmp.ptr(),tmp.length());
}
@@ -361,14 +306,14 @@ void Field::store_time(TIME *ltime,timestamp_type type)
}
-bool Field::optimize_range()
+bool Field::optimize_range(uint idx)
{
- return test(table->file->option_flag() & HA_READ_NEXT);
+ return test(table->file->index_flags(idx) & HA_READ_NEXT);
}
/****************************************************************************
-** Functions for the Field_decimal class
-** This is a unpacked number.
+ Functions for the Field_decimal class
+ This is an number stored as a pre-space (or pre-zero) string
****************************************************************************/
void
@@ -381,6 +326,8 @@ void Field_decimal::overflow(bool negative)
{
uint len=field_length;
char *to=ptr, filler= '9';
+
+ current_thd->cuted_fields++;
if (negative)
{
if (!unsigned_flag)
@@ -416,99 +363,330 @@ void Field_decimal::overflow(bool negative)
void Field_decimal::store(const char *from,uint len)
{
- reg3 int i;
- uint tmp_dec;
- char fyllchar;
- const char *end=from+len;
- struct st_decstr decstr;
- bool error;
+ const char *end= from+len;
+ /* The pointer where the field value starts (i.e., "where to write") */
+ char *to=ptr;
+ uint tmp_dec, tmp_uint;
+ /*
+ The sign of the number : will be 0 (means positive but sign not
+ specified), '+' or '-'
+ */
+ char sign_char=0;
+ /* The pointers where prezeros start and stop */
+ const char *pre_zeros_from, *pre_zeros_end;
+ /* The pointers where digits at the left of '.' start and stop */
+ const char *int_digits_from, *int_digits_end;
+ /* The pointers where digits at the right of '.' start and stop */
+ const char *frac_digits_from, *frac_digits_end;
+ /* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
+ char expo_sign_char=0;
+ uint exponent=0; // value of the exponent
+ /*
+ Pointers used when digits move from the left of the '.' to the
+ right of the '.' (explained below)
+ */
+ const char *int_digits_tail_from;
+ /* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */
+ uint int_digits_added_zeros;
+ /*
+ Pointer used when digits move from the right of the '.' to the left
+ of the '.'
+ */
+ const char *frac_digits_head_end;
+ /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */
+ uint frac_digits_added_zeros;
+ char *pos,*tmp_left_pos,*tmp_right_pos;
+ /* Pointers that are used as limits (begin and end of the field buffer) */
+ char *left_wall,*right_wall;
+ char tmp_char;
+ /*
+ To remember if current_thd->cuted_fields has already been incremented,
+ to do that only once
+ */
+ bool is_cuted_fields_incr=0;
+
+ LINT_INIT(int_digits_tail_from);
+ LINT_INIT(int_digits_added_zeros);
+ LINT_INIT(frac_digits_head_end);
+ LINT_INIT(frac_digits_added_zeros);
- if ((tmp_dec= dec))
- tmp_dec++; // Calculate pos of '.'
- while (from != end && isspace(*from))
- from++;
- if (zerofill)
- {
- fyllchar = '0';
- if (from != end)
- while (*from == '0' && from != end-1) // Skipp prezero
- from++;
- }
- else
- fyllchar=' ';
- error=number_dec(&decstr,from,end);
- if (decstr.sign)
+ /*
+ There are three steps in this function :
+ - parse the input string
+ - modify the position of digits around the decimal dot '.'
+ according to the exponent value (if specified)
+ - write the formatted number
+ */
+
+ if ((tmp_dec=dec))
+ tmp_dec++;
+
+ for (; from !=end && isspace(*from); from++) ; // Read spaces
+ if (from == end)
{
- from++;
- if (unsigned_flag) // No sign with zerofill
- {
- if (decstr.sign_char == '+') // just remove "+"
- decstr.sign= 0;
- else
+ current_thd->cuted_fields++;
+ is_cuted_fields_incr=1;
+ }
+ else if (*from == '+' || *from == '-') // Found some sign ?
+ {
+ sign_char= *from++;
+ /*
+ Unsigned can't have any flag. So we'll just drop "+"
+ and will overflow on "-"
+ */
+ if (unsigned_flag)
+ {
+ if (sign_char=='-')
{
- if (!error)
- current_thd->cuted_fields++;
- Field_decimal::overflow(1);
- return;
+ Field_decimal::overflow(1);
+ return;
}
+ else
+ sign_char=0;
}
}
+
+ pre_zeros_from= from;
+ for (; from!=end && *from == '0'; from++) ; // Read prezeros
+ pre_zeros_end=int_digits_from=from;
+ /* Read non zero digits at the left of '.'*/
+ for (; from!=end && isdigit(*from);from++) ;
+ int_digits_end=from;
+ if (from!=end && *from == '.') // Some '.' ?
+ from++;
+ frac_digits_from= from;
+ /* Read digits at the right of '.' */
+ for (;from!=end && isdigit(*from); from++) ;
+ frac_digits_end=from;
+ // Some exponentiation symbol ?
+ if (from != end && (*from == 'e' || *from == 'E'))
+ {
+ from++;
+ if (from != end && (*from == '+' || *from == '-')) // Some exponent sign ?
+ expo_sign_char= *from++;
+ else
+ expo_sign_char= '+';
+ /*
+ Read digits of the exponent and compute its value
+ 'exponent' overflow (e.g. if 1E10000000000000000) is not a problem
+ (the value of the field will be overflow anyway, or 0 anyway,
+ it does not change anything if the exponent is 2^32 or more
+ */
+ for (;from!=end && isdigit(*from); from++)
+ exponent=10*exponent+(*from-'0');
+ }
+
/*
- ** Remove pre-zeros if too big number
+ We only have to generate warnings if count_cuted_fields is set.
+ This is to avoid extra checks of the number when they are not needed.
+ Even if this flag is not set, it's ok to increment warnings, if
+ it makes the code easer to read.
*/
- for (i= (int) (decstr.nr_length+decstr.extra -(field_length-tmp_dec)+
- decstr.sign) ;
- i > 0 ;
- i--)
+
+ if (current_thd->count_cuted_fields)
{
- if (*from == '0')
+ for (;from != end && isspace(*from); from++) ; // Read end spaces
+ if (from != end) // If still something left, warn
{
- from++;
- decstr.nr_length--;
- continue;
+ current_thd->cuted_fields++;
+ is_cuted_fields_incr=1;
}
- if (decstr.sign && decstr.sign_char == '+' && i == 1)
- { // Remove pre '+'
- decstr.sign=0;
- break;
+ }
+
+ /*
+ Now "move" digits around the decimal dot according to the exponent value,
+ and add necessary zeros.
+ Examples :
+ - 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3)
+ - 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed
+ between '.' and '1'
+ - 1234.5E-3 : '234' moves at the right of '.'
+ These moves are implemented with pointers which point at the begin
+ and end of each moved segment. Examples :
+ - 1234.5E-3 : before the code below is executed, the int_digits part is
+ from '1' to '4' and the frac_digits part from '5' to '5'. After the code
+ below, the int_digits part is from '1' to '1', the frac_digits_head
+ part is from '2' to '4', and the frac_digits part from '5' to '5'.
+ - 1234.5E3 : before the code below is executed, the int_digits part is
+ from '1' to '4' and the frac_digits part from '5' to '5'. After the code
+ below, the int_digits part is from '1' to '4', the int_digits_tail
+ part is from '5' to '5', the frac_digits part is empty, and
+ int_digits_added_zeros=2 (to make 1234500).
+ */
+
+ if (!expo_sign_char)
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+ tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ }
+ else // (expo_sign_char=='+')
+ {
+ tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+ /*
+ We "eat" the heading zeros of the
+ int_digits.int_digits_tail.int_digits_added_zeros concatenation
+ (for example 0.003e3 must become 3 and not 0003)
+ */
+ if (int_digits_from == int_digits_end)
+ {
+ /*
+ There was nothing in the int_digits part, so continue
+ eating int_digits_tail zeros
+ */
+ for (; int_digits_tail_from != frac_digits_from &&
+ *int_digits_tail_from == '0'; int_digits_tail_from++) ;
+ if (int_digits_tail_from == frac_digits_from)
+ {
+ // there were only zeros in int_digits_tail too
+ int_digits_added_zeros=0;
+ }
}
- current_thd->cuted_fields++;
+ tmp_uint=(tmp_dec+(uint)(int_digits_end-int_digits_from)
+ +(uint)(frac_digits_from-int_digits_tail_from)+
+ int_digits_added_zeros);
+ }
+
+ /*
+ Now write the formated number
+
+ First the digits of the int_% parts.
+ Do we have enough room to write these digits ?
+ If the sign is defined and '-', we need one position for it
+ */
+
+ if (field_length < tmp_uint + (int) (sign_char == '-'))
+ {
// too big number, change to max or min number
- Field_decimal::overflow(decstr.sign && decstr.sign_char == '-');
+ Field_decimal::overflow(sign_char == '-');
return;
}
- char *to=ptr;
- for (i=(int) (field_length-tmp_dec-decstr.nr_length-decstr.extra - decstr.sign) ;
- i-- > 0 ;)
- *to++ = fyllchar;
- if (decstr.sign)
- *to++= decstr.sign_char;
- if (decstr.extra)
- *to++ = '0';
- for (i=(int) decstr.nr_length ; i-- > 0 ; )
- *to++ = *from++;
- if (tmp_dec--)
- {
- *to++ ='.';
- if (decstr.nr_dec) from++; // Skipp '.'
- for (i=(int) min(decstr.nr_dec,tmp_dec) ; i-- > 0 ; ) *to++ = *from++;
- for (i=(int) (tmp_dec-min(decstr.nr_dec,tmp_dec)) ; i-- > 0 ; ) *to++ = '0';
+
+ /*
+ Tmp_left_pos is the position where the leftmost digit of
+ the int_% parts will be written
+ */
+ tmp_left_pos=pos=to+(uint)(field_length-tmp_uint);
+
+ // Write all digits of the int_% parts
+ while (int_digits_from != int_digits_end)
+ *pos++ = *int_digits_from++ ;
+
+ if (expo_sign_char == '+')
+ {
+ while (int_digits_tail_from != frac_digits_from)
+ *pos++= *int_digits_tail_from++;
+ while (int_digits_added_zeros-- >0)
+ *pos++= '0';
}
+ /*
+ Note the position where the rightmost digit of the int_% parts has been
+ written (this is to later check if the int_% parts contained nothing,
+ meaning an extra 0 is needed).
+ */
+ tmp_right_pos=pos;
/*
- ** Check for incorrect string if in batch mode (ALTER TABLE/LOAD DATA...)
+ Step back to the position of the leftmost digit of the int_% parts,
+ to write sign and fill with zeros or blanks or prezeros.
*/
- if (!error && current_thd->count_cuted_fields && from != end)
- { // Check if number was cuted
- for (; from != end ; from++)
+ pos=tmp_left_pos-1;
+ if (zerofill)
+ {
+ left_wall=to-1;
+ while (pos != left_wall) // Fill with zeros
+ *pos--='0';
+ }
+ else
+ {
+ left_wall=to+(sign_char != 0)-1;
+ if (!expo_sign_char) // If exponent was specified, ignore prezeros
+ {
+ for (;pos != left_wall && pre_zeros_from !=pre_zeros_end;
+ pre_zeros_from++)
+ *pos--= '0';
+ }
+ if (pos == tmp_right_pos-1)
+ *pos--= '0'; // no 0 has ever been written, so write one
+ left_wall= to-1;
+ if (sign_char && pos != left_wall)
+ {
+ /* Write sign if possible (it is if sign is '-') */
+ *pos--= sign_char;
+ }
+ while (pos != left_wall)
+ *pos--=' '; //fill with blanks
+ }
+
+ if (tmp_dec) // This field has decimals
+ {
+ /*
+ Write digits of the frac_% parts ;
+ Depending on current_thd->count_cutted_fields, we may also want
+ to know if some non-zero tail of these parts will
+ be truncated (for example, 0.002->0.00 will generate a warning,
+ while 0.000->0.00 will not)
+ (and 0E1000000000 will not, while 1E-1000000000 will)
+ */
+
+ pos=to+(uint)(field_length-tmp_dec); // Calculate post to '.'
+ *pos++='.';
+ right_wall=to+field_length;
+
+ if (expo_sign_char == '-')
{
- if (*from != '0')
+ while (frac_digits_added_zeros-- > 0)
{
- if (!isspace(*from)) // Space is ok
- current_thd->cuted_fields++;
- break;
+ if (pos == right_wall)
+ {
+ if (current_thd->count_cuted_fields && !is_cuted_fields_incr)
+ break; // Go on below to see if we lose non zero digits
+ return;
+ }
+ *pos++='0';
+ }
+ while (int_digits_end != frac_digits_head_end)
+ {
+ tmp_char= *int_digits_end++;
+ if (pos == right_wall)
+ {
+ if (tmp_char != '0') // Losing a non zero digit ?
+ {
+ if (!is_cuted_fields_incr)
+ current_thd->cuted_fields++;
+ return;
+ }
+ continue;
+ }
+ *pos++= tmp_char;
+ }
+ }
+
+ for (;frac_digits_from!=frac_digits_end;)
+ {
+ tmp_char= *frac_digits_from++;
+ if (pos == right_wall)
+ {
+ if (tmp_char != '0') // Losing a non zero digit ?
+ {
+ if (!is_cuted_fields_incr)
+ current_thd->cuted_fields++;
+ return;
+ }
+ continue;
}
+ *pos++= tmp_char;
}
+
+ while (pos != right_wall)
+ *pos++='0'; // Fill with zeros at right of '.'
}
}
@@ -518,9 +696,17 @@ void Field_decimal::store(double nr)
if (unsigned_flag && nr < 0)
{
overflow(1);
- current_thd->cuted_fields++;
return;
}
+
+#ifdef HAVE_FINITE
+ if (!finite(nr)) // Handle infinity as special case
+ {
+ overflow(nr < 0.0);
+ return;
+ }
+#endif
+
reg4 uint i,length;
char fyllchar,*to;
char buff[320];
@@ -535,10 +721,7 @@ void Field_decimal::store(double nr)
length=(uint) strlen(buff);
if (length > field_length)
- {
overflow(nr < 0.0);
- current_thd->cuted_fields++;
- }
else
{
to=ptr;
@@ -554,7 +737,6 @@ void Field_decimal::store(longlong nr)
if (unsigned_flag && nr < 0)
{
overflow(1);
- current_thd->cuted_fields++;
return;
}
char buff[22];
@@ -562,10 +744,7 @@ void Field_decimal::store(longlong nr)
uint int_part=field_length- (dec ? dec+1 : 0);
if (length > int_part)
- {
overflow(test(nr < 0L)); /* purecov: inspected */
- current_thd->cuted_fields++; /* purecov: inspected */
- }
else
{
char fyllchar = zerofill ? (char) '0' : (char) ' ';
@@ -1075,7 +1254,7 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[0];
else
- to[0] = ptr[0] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
to[1] = ptr[1];
}
else
@@ -1084,7 +1263,7 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[1];
else
- to[0] = ptr[1] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[1] ^ 128); /* Revers signbit */
to[1] = ptr[0];
}
}
@@ -1155,12 +1334,12 @@ void Field_medium::store(double nr)
}
else if (nr >= (double) (long) (1L << 24))
{
- ulong tmp=(ulong) (1L << 24)-1L;
+ uint32 tmp=(uint32) (1L << 24)-1L;
int3store(ptr,tmp);
current_thd->cuted_fields++;
}
else
- int3store(ptr,(ulong) nr);
+ int3store(ptr,(uint32) nr);
}
else
{
@@ -1197,7 +1376,7 @@ void Field_medium::store(longlong nr)
current_thd->cuted_fields++;
}
else
- int3store(ptr,(ulong) nr);
+ int3store(ptr,(uint32) nr);
}
else
{
@@ -1475,7 +1654,7 @@ int Field_long::cmp(const char *a_ptr, const char *b_ptr)
longget(b,b_ptr);
}
if (unsigned_flag)
- return ((ulong) a < (ulong) b) ? -1 : ((ulong) a > (ulong) b) ? 1 : 0;
+ return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0;
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -1487,7 +1666,7 @@ void Field_long::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[0];
else
- to[0] = ptr[0] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
to[1] = ptr[1];
to[2] = ptr[2];
to[3] = ptr[3];
@@ -1498,7 +1677,7 @@ void Field_long::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[3];
else
- to[0] = ptr[3] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[3] ^ 128); /* Revers signbit */
to[1] = ptr[2];
to[2] = ptr[1];
to[3] = ptr[0];
@@ -1686,7 +1865,7 @@ void Field_longlong::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[0];
else
- to[0] = ptr[0] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
to[1] = ptr[1];
to[2] = ptr[2];
to[3] = ptr[3];
@@ -1701,7 +1880,7 @@ void Field_longlong::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[7];
else
- to[0] = ptr[7] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[7] ^ 128); /* Revers signbit */
to[1] = ptr[6];
to[2] = ptr[5];
to[3] = ptr[4];
@@ -1738,6 +1917,11 @@ void Field_float::store(double nr)
float j;
if (dec < NOT_FIXED_DEC)
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
+ if (unsigned_flag && nr < 0)
+ {
+ current_thd->cuted_fields++;
+ nr=0;
+ }
if (nr < -FLT_MAX)
{
j= -FLT_MAX;
@@ -1764,6 +1948,11 @@ void Field_float::store(double nr)
void Field_float::store(longlong nr)
{
float j= (float) nr;
+ if (unsigned_flag && j < 0)
+ {
+ current_thd->cuted_fields++;
+ j=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1936,7 +2125,7 @@ void Field_float::sort_string(char *to,uint length __attribute__((unused)))
{ /* make complement */
uint i;
for (i=0 ; i < sizeof(nr); i++)
- tmp[i]=tmp[i] ^ (uchar) 255;
+ tmp[i]= (uchar) (tmp[i] ^ (uchar) 255);
}
else
{
@@ -1970,6 +2159,11 @@ void Field_double::store(const char *from,uint len)
double j= atof(tmp_str.c_ptr());
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
current_thd->cuted_fields++;
+ if (unsigned_flag && j < 0)
+ {
+ current_thd->cuted_fields++;
+ j=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1985,6 +2179,11 @@ void Field_double::store(double nr)
{
if (dec < NOT_FIXED_DEC)
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
+ if (unsigned_flag && nr < 0)
+ {
+ current_thd->cuted_fields++;
+ nr=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1999,6 +2198,11 @@ void Field_double::store(double nr)
void Field_double::store(longlong nr)
{
double j= (double) nr;
+ if (unsigned_flag && j < 0)
+ {
+ current_thd->cuted_fields++;
+ j=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2304,10 +2508,10 @@ void Field_timestamp::store(longlong nr)
{
part1=(long) (nr/LL(1000000));
part2=(long) (nr - (longlong) part1*LL(1000000));
- l_time.year= part1/10000L; part1%=10000L;
+ l_time.year= (int) (part1/10000L); part1%=10000L;
l_time.month= (int) part1 / 100;
- l_time.day= (int) part1 % 100;
- l_time.hour= part2/10000L; part2%=10000L;
+ l_time.day= (int) part1 % 100;
+ l_time.hour= (int) (part2/10000L); part2%=10000L;
l_time.minute=(int) part2 / 100;
l_time.second=(int) part2 % 100;
timestamp=my_gmt_sec(&l_time);
@@ -2321,7 +2525,7 @@ void Field_timestamp::store(longlong nr)
}
else
#endif
- longstore(ptr,(ulong)timestamp);
+ longstore(ptr,(uint32) timestamp);
}
@@ -2622,7 +2826,7 @@ void Field_time::store(longlong nr)
double Field_time::val_real(void)
{
- ulong j= (ulong) uint3korr(ptr);
+ uint32 j= (uint32) uint3korr(ptr);
return (double) j;
}
@@ -2658,19 +2862,19 @@ bool Field_time::get_time(TIME *ltime)
ltime->neg= 1;
tmp=-tmp;
}
- ltime->hour=tmp/10000;
+ ltime->hour= (int) (tmp/10000);
tmp-=ltime->hour*10000;
- ltime->minute= tmp/100;
- ltime->second= tmp % 100;
+ ltime->minute= (int) tmp/100;
+ ltime->second= (int) tmp % 100;
ltime->second_part=0;
return 0;
}
int Field_time::cmp(const char *a_ptr, const char *b_ptr)
{
- long a,b;
- a=(long) sint3korr(a_ptr);
- b=(long) sint3korr(b_ptr);
+ int32 a,b;
+ a=(int32) sint3korr(a_ptr);
+ b=(int32) sint3korr(b_ptr);
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -2781,14 +2985,14 @@ void Field_year::sql_type(String &res) const
** Stored as a 4 byte unsigned int
****************************************************************************/
-void Field_date::store(const char *from,uint len)
+void Field_date::store(const char *from, uint len)
{
TIME l_time;
- ulong tmp;
+ uint32 tmp;
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
tmp=0;
else
- tmp=(ulong) l_time.year*10000L + (ulong) (l_time.month*100+l_time.day);
+ tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2960,7 +3164,7 @@ void Field_newdate::store(double nr)
void Field_newdate::store(longlong nr)
{
- long tmp;
+ int32 tmp;
if (nr >= LL(100000000) && nr <= LL(99991231235959))
nr=nr/LL(1000000); // Timestamp to date
if (nr < 0L || nr > 99991231L)
@@ -2970,16 +3174,16 @@ void Field_newdate::store(longlong nr)
}
else
{
- tmp=(long) nr;
+ tmp=(int32) nr;
if (tmp)
{
if (tmp < YY_PART_YEAR*10000L) // Fix short dates
- tmp+=20000000L;
+ tmp+= (uint32) 20000000L;
else if (tmp < 999999L)
- tmp+=19000000L;
+ tmp+= (uint32) 19000000L;
}
- uint month=((tmp/100) % 100);
- uint day= tmp%100;
+ uint month= (uint) ((tmp/100) % 100);
+ uint day= (uint) (tmp%100);
if (month > 12 || day > 31)
{
tmp=0L; // Don't allow date to change
@@ -2988,7 +3192,7 @@ void Field_newdate::store(longlong nr)
else
tmp= day + month*32 + (tmp/10000)*16*32;
}
- int3store(ptr,tmp);
+ int3store(ptr,(int32) tmp);
}
void Field_newdate::store_time(TIME *ltime,timestamp_type type)
@@ -3013,7 +3217,7 @@ double Field_newdate::val_real(void)
longlong Field_newdate::val_int(void)
{
- ulong j=uint3korr(ptr);
+ ulong j= uint3korr(ptr);
j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
return (longlong) j;
}
@@ -3023,25 +3227,25 @@ String *Field_newdate::val_str(String *val_buffer,
{
val_buffer->alloc(field_length);
val_buffer->length(field_length);
- ulong tmp=(ulong) uint3korr(ptr);
+ uint32 tmp=(uint32) uint3korr(ptr);
int part;
char *pos=(char*) val_buffer->ptr()+10;
/* Open coded to get more speed */
- *pos--=0;
+ *pos--=0; // End NULL
part=(int) (tmp & 31);
- *pos--='0'+part%10;
- *pos--='0'+part/10;
- *pos--='-';
+ *pos--= (char) ('0'+part%10);
+ *pos--= (char) ('0'+part/10);
+ *pos--= '-';
part=(int) (tmp >> 5 & 15);
- *pos--='0'+part%10;
- *pos--='0'+part/10;
- *pos--='-';
+ *pos--= (char) ('0'+part%10);
+ *pos--= (char) ('0'+part/10);
+ *pos--= '-';
part=(int) (tmp >> 9);
- *pos--='0'+part%10; part/=10;
- *pos--='0'+part%10; part/=10;
- *pos--='0'+part%10; part/=10;
- *pos='0'+part;
+ *pos--= (char) ('0'+part%10); part/=10;
+ *pos--= (char) ('0'+part%10); part/=10;
+ *pos--= (char) ('0'+part%10); part/=10;
+ *pos= (char) ('0'+part);
return val_buffer;
}
@@ -3049,7 +3253,7 @@ bool Field_newdate::get_date(TIME *ltime,bool fuzzydate)
{
if (is_null())
return 1;
- ulong tmp=(ulong) uint3korr(ptr);
+ uint32 tmp=(uint32) uint3korr(ptr);
bzero((char*) ltime,sizeof(*ltime));
ltime->day= tmp & 31;
ltime->month= (tmp >> 5) & 15;
@@ -3065,9 +3269,9 @@ bool Field_newdate::get_time(TIME *ltime)
int Field_newdate::cmp(const char *a_ptr, const char *b_ptr)
{
- ulong a,b;
- a=(ulong) uint3korr(a_ptr);
- b=(ulong) uint3korr(b_ptr);
+ uint32 a,b;
+ a=(uint32) uint3korr(a_ptr);
+ b=(uint32) uint3korr(b_ptr);
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -3201,44 +3405,44 @@ String *Field_datetime::val_str(String *val_buffer,
pos=(char*) val_buffer->ptr()+19;
*pos--=0;
- *pos--='0'+(char) (part2%10); part2/=10;
- *pos--='0'+(char) (part2%10); part3= (int) (part2 / 10);
- *pos--=':';
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--=':';
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) part3;
- *pos--=' ';
- *pos--='0'+(char) (part1%10); part1/=10;
- *pos--='0'+(char) (part1%10); part1/=10;
- *pos--='-';
- *pos--='0'+(char) (part1%10); part1/=10;
- *pos--='0'+(char) (part1%10); part3= (int) (part1/10);
- *pos--='-';
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos='0'+(char) part3;
+ *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
+ *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
+ *pos--= ':';
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= ':';
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) part3);
+ *pos--= ' ';
+ *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+ *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+ *pos--= '-';
+ *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+ *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
+ *pos--= '-';
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos=(char) ('0'+(char) part3);
return val_buffer;
}
bool Field_datetime::get_date(TIME *ltime,bool fuzzydate)
{
longlong tmp=Field_datetime::val_int();
- long part1,part2;
- part1=(long) (tmp/LL(1000000));
- part2=(long) (tmp - (ulonglong) part1*LL(1000000));
+ uint32 part1,part2;
+ part1=(uint32) (tmp/LL(1000000));
+ part2=(uint32) (tmp - (ulonglong) part1*LL(1000000));
ltime->time_type= TIMESTAMP_FULL;
- ltime->neg=0;
- ltime->second_part=0;
- ltime->second= part2%100;
- ltime->minute= part2/100%100;
- ltime->hour= part2/10000;
- ltime->day= part1%100;
- ltime->month= part1/100%100;
- ltime->year= part1/10000;
+ ltime->neg= 0;
+ ltime->second_part= 0;
+ ltime->second= (int) (part2%100);
+ ltime->minute= (int) (part2/100%100);
+ ltime->hour= (int) (part2/10000);
+ ltime->day= (int) (part1%100);
+ ltime->month= (int) (part1/100%100);
+ ltime->year= (int) (part1/10000);
return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
@@ -3310,9 +3514,9 @@ void Field_datetime::sql_type(String &res) const
void Field_string::store(const char *from,uint length)
{
#ifdef USE_TIS620
- if(!binary_flag) {
+ if (!binary_flag) {
ThNormalize((uchar *)ptr, field_length, (uchar *)from, length);
- if(length < field_length) {
+ if (length < field_length) {
bfill(ptr + length, field_length - length, ' ');
}
}
@@ -3357,7 +3561,7 @@ void Field_string::store(longlong nr)
{
char buff[22];
char *end=longlong10_to_str(nr,buff,-10);
- Field_string::store(buff,end-buff);
+ Field_string::store(buff,(uint) (end-buff));
}
@@ -3514,7 +3718,7 @@ uint Field_string::max_packed_col_length(uint max_length)
void Field_varstring::store(const char *from,uint length)
{
#ifdef USE_TIS620
- if(!binary_flag)
+ if (!binary_flag)
{
ThNormalize((uchar *) ptr+2, field_length, (uchar *) from, length);
}
@@ -3548,7 +3752,7 @@ void Field_varstring::store(longlong nr)
{
char buff[22];
char *end=longlong10_to_str(nr,buff,-10);
- Field_varstring::store(buff,end-buff);
+ Field_varstring::store(buff,(uint) (end-buff));
}
@@ -3639,9 +3843,9 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length)
uint length=uint2korr(from);
if (length > max_length)
length=max_length;
- *to++= (length & 255);
+ *to++= (char) (length & 255);
if (max_length > 255)
- *to++= (uchar) (length >> 8);
+ *to++= (char) (length >> 8);
if (length)
memcpy(to, from+2, length);
return to+length;
@@ -3730,7 +3934,7 @@ uint Field_varstring::max_packed_col_length(uint max_length)
** packlength slot and may be from 1-4.
****************************************************************************/
-Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint 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,
struct st_table *table_arg,uint blob_pack_length,
bool binary_arg)
@@ -3747,7 +3951,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
}
-void Field_blob::store_length(ulong number)
+void Field_blob::store_length(uint32 number)
{
switch (packlength) {
case 1:
@@ -3774,9 +3978,9 @@ void Field_blob::store_length(ulong number)
shortstore(ptr,(unsigned short) number);
break;
case 3:
- if (number > (ulong) (1L << 24))
+ if (number > (uint32) (1L << 24))
{
- number= (ulong) (1L << 24)-1L;
+ number= (uint32) (1L << 24)-1L;
current_thd->cuted_fields++;
}
int3store(ptr,number);
@@ -3794,11 +3998,11 @@ void Field_blob::store_length(ulong number)
}
-ulong Field_blob::get_length(const char *pos)
+uint32 Field_blob::get_length(const char *pos)
{
switch (packlength) {
case 1:
- return (ulong) (uchar) pos[0];
+ return (uint32) (uchar) pos[0];
case 2:
{
uint16 tmp;
@@ -3808,10 +4012,10 @@ ulong Field_blob::get_length(const char *pos)
else
#endif
shortget(tmp,pos);
- return (ulong) tmp;
+ return (uint32) tmp;
}
case 3:
- return (ulong) uint3korr(pos);
+ return (uint32) uint3korr(pos);
case 4:
{
uint32 tmp;
@@ -3821,7 +4025,7 @@ ulong Field_blob::get_length(const char *pos)
else
#endif
longget(tmp,pos);
- return (ulong) tmp;
+ return (uint32) tmp;
}
}
return 0; // Impossible
@@ -3843,7 +4047,7 @@ void Field_blob::store(const char *from,uint len)
if (table->copy_blobs || len <= MAX_FIELD_WIDTH)
{ // Must make a copy
#ifdef USE_TIS620
- if(!binary_flag)
+ if (!binary_flag)
{
/* If there isn't enough memory, use original string */
if ((th_ptr=(char * ) my_malloc(sizeof(char) * len,MYF(0))))
@@ -3867,14 +4071,14 @@ void Field_blob::store(const char *from,uint len)
void Field_blob::store(double nr)
{
value.set(nr);
- Field_blob::store(value.ptr(),value.length());
+ Field_blob::store(value.ptr(),(uint) value.length());
}
void Field_blob::store(longlong nr)
{
value.set(nr);
- Field_blob::store(value.ptr(),value.length());
+ Field_blob::store(value.ptr(), (uint) value.length());
}
@@ -3885,7 +4089,7 @@ double Field_blob::val_real(void)
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0.0;
- ulong length=get_length(ptr);
+ uint32 length=get_length(ptr);
char save=blob[length]; // Ok to patch blob in NISAM
blob[length]=0;
@@ -3901,7 +4105,7 @@ longlong Field_blob::val_int(void)
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0;
- ulong length=get_length(ptr);
+ uint32 length=get_length(ptr);
char save=blob[length]; // Ok to patch blob in NISAM
blob[length]=0;
@@ -3924,8 +4128,8 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
}
-int Field_blob::cmp(const char *a,ulong a_length, const char *b,
- ulong b_length)
+int Field_blob::cmp(const char *a,uint32 a_length, const char *b,
+ uint32 b_length)
{
int diff;
if (binary_flag)
@@ -3959,11 +4163,11 @@ int Field_blob::cmp_binary_offset(uint row_offset)
int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
- ulong max_length)
+ uint32 max_length)
{
char *a,*b;
uint diff;
- ulong a_length,b_length;
+ uint32 a_length,b_length;
memcpy_fixed(&a,a_ptr+packlength,sizeof(char*));
memcpy_fixed(&b,b_ptr+packlength,sizeof(char*));
a_length=get_length(a_ptr);
@@ -3982,9 +4186,9 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
void Field_blob::get_key_image(char *buff,uint length)
{
length-=HA_KEY_BLOB_LENGTH;
- ulong blob_length=get_length(ptr);
+ uint32 blob_length=get_length(ptr);
char *blob;
- if ((ulong) length > blob_length)
+ if ((uint32) length > blob_length)
{
#ifdef HAVE_purify
bzero(buff+2+blob_length, (length-blob_length));
@@ -4078,7 +4282,7 @@ char *Field_blob::pack(char *to, const char *from, uint max_length)
{
char *save=ptr;
ptr=(char*) from;
- ulong length=get_length(); // Length of from string
+ uint32 length=get_length(); // Length of from string
if (length > max_length)
{
ptr=to;
@@ -4101,7 +4305,7 @@ char *Field_blob::pack(char *to, const char *from, uint max_length)
const char *Field_blob::unpack(char *to, const char *from)
{
memcpy(to,from,packlength);
- ulong length=get_length(from);
+ uint32 length=get_length(from);
from+=packlength;
if (length)
memcpy_fixed(to+packlength, &from, sizeof(from));
@@ -4110,60 +4314,6 @@ const char *Field_blob::unpack(char *to, const char *from)
return from+length;
}
-
-#ifdef HAVE_GEMINI_DB
-/* Blobs in Gemini tables are stored separately from the rows which contain
-** them (except for tiny blobs, which are stored in the row). For all other
-** blob types (blob, mediumblob, longblob), the row contains the length of
-** the blob data and a blob id. These methods (pack_id, get_id, and
-** unpack_id) handle packing and unpacking blob fields in Gemini rows.
-*/
-char *Field_blob::pack_id(char *to, const char *from, ulonglong id, uint max_length)
-{
- char *save=ptr;
- ptr=(char*) from;
- ulong length=get_length(); // Length of from string
- if (length > max_length)
- {
- ptr=to;
- length=max_length;
- store_length(length); // Store max length
- ptr=(char*) from;
- }
- else
- memcpy(to,from,packlength); // Copy length
- if (length)
- {
- int8store(to+packlength, id);
- }
- ptr=save; // Restore org row pointer
- return to+packlength+sizeof(id);
-}
-
-
-ulonglong Field_blob::get_id(const char *from)
-{
- ulonglong id = 0;
- ulong length=get_length(from);
- if (length)
- id=uint8korr(from+packlength);
- return id;
-}
-
-
-const char *Field_blob::unpack_id(char *to, const char *from, const char *bdata)
-{
- memcpy(to,from,packlength);
- ulong length=get_length(from);
- from+=packlength;
- if (length)
- memcpy_fixed(to+packlength, &bdata, sizeof(bdata));
- else
- bzero(to+packlength,sizeof(bdata));
- return from+sizeof(ulonglong);
-}
-#endif /* HAVE_GEMINI_DB */
-
/* Keys for blobs are like keys on varchars */
int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
@@ -4220,7 +4370,7 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length)
{
char *save=ptr;
ptr=(char*) from;
- ulong length=get_length(); // Length of from string
+ uint32 length=get_length(); // Length of from string
if (length > max_length)
length=max_length;
*to++= (uchar) length;
@@ -4243,9 +4393,9 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
uint length=uint2korr(from);
if (length > max_length)
length=max_length;
- *to++= (length & 255);
+ *to++= (char) (length & 255);
if (max_length > 255)
- *to++= (uchar) (length >> 8);
+ *to++= (char) (length >> 8);
if (length)
memcpy(to, from+2, length);
return to+length;
@@ -4358,7 +4508,7 @@ void Field_enum::store(const char *from,uint length)
conv=buff;
}
my_errno=0;
- tmp=strtoul(conv,&end,10);
+ tmp=(uint) strtoul(conv,&end,10);
if (my_errno || end != conv+length || tmp > typelib->count)
{
tmp=0;
@@ -4517,7 +4667,7 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length)
for (;;)
{
const char *pos=start;
- for ( ; pos != end && *pos != field_separator ; pos++) ;
+ for (; pos != end && *pos != field_separator ; pos++) ;
uint find=find_enum(lib,start,(uint) (pos-start));
if (!find)
error=1;
@@ -4628,7 +4778,7 @@ bool Field_enum::eq_def(Field *field)
if (!Field::eq_def(field))
return 0;
TYPELIB *from_lib=((Field_enum*) field)->typelib;
-
+
if (typelib->count < from_lib->count)
return 0;
for (uint i=0 ; i < from_lib->count ; i++)
@@ -4638,7 +4788,7 @@ bool Field_enum::eq_def(Field *field)
}
bool Field_num::eq_def(Field *field)
-{
+{
if (!Field::eq_def(field))
return 0;
Field_num *from_num= (Field_num*) field;
@@ -4656,7 +4806,7 @@ bool Field_num::eq_def(Field *field)
*****************************************************************************/
/*
-** Make a field from the .frm file info
+ Make a field from the .frm file info
*/
uint32 calc_pack_length(enum_field_types type,uint32 length)
@@ -4685,6 +4835,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
case FIELD_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr;
case FIELD_TYPE_SET:
case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen
+ default: return 0;
}
return 0; // This shouldn't happen
}
@@ -4704,7 +4855,7 @@ uint pack_length_to_packflag(uint type)
Field *make_field(char *ptr, uint32 field_length,
- uchar *null_pos, uint null_bit,
+ uchar *null_pos, uchar null_bit,
uint pack_flag,
Field::utype unireg_check,
TYPELIB *interval,
diff --git a/sql/field.h b/sql/field.h
index b138eb772d8..656dd9a592d 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1,23 +1,23 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
-** Because of the function new_field all field classes that have static
-** variables must declare the size_of() member function.
+ Because of the function new_field() all field classes that have static
+ variables must declare the size_of() member function.
*/
#ifdef __GNUC__
@@ -31,27 +31,28 @@ struct st_cache_field;
void field_conv(Field *to,Field *from);
class Field {
- Field(const Item &); /* Prevent use of theese */
+ Field(const Item &); /* Prevent use of these */
void operator=(Field &);
public:
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
static void operator delete(void *ptr_arg, size_t size) {} /*lint -e715 */
- enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
- CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
- BIT_FIELD, TIMESTAMP_FIELD,CAPITALIZE,BLOB_FIELD};
- char *ptr; // Position to field in record
- uchar *null_ptr; // Byte where null_bit is
- uint8 null_bit; // And position to it
- struct st_table *table; // Pointer for table
- ulong query_id; // For quick test of used fields
- key_map key_start,part_of_key,part_of_sortkey;// Field is part of these keys.
- const char *table_name,*field_name;
- utype unireg_check;
- uint32 field_length; // Length of field
- uint16 flags;
-
- Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uint null_bit_arg,
+ char *ptr; /* Position to field in record */
+ uchar *null_ptr; /* Byte where null_bit is */
+ struct st_table *table; /* Pointer for table */
+ const char *table_name,*field_name;
+ ulong query_id; /* For quick test of used fields */
+ /* Field is part of the following keys */
+ key_map key_start,part_of_key,part_of_sortkey;
+ enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
+ CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
+ BIT_FIELD, TIMESTAMP_FIELD,CAPITALIZE,BLOB_FIELD};
+ utype unireg_check;
+ uint32 field_length; /* Length of field */
+ uint16 flags;
+ uchar null_bit; /* Bit used to test null bit */
+
+ Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg);
virtual ~Field() {}
@@ -69,6 +70,10 @@ public:
virtual uint32 pack_length() const { return (uint32) field_length; }
virtual void reset(void) { bzero(ptr,pack_length()); }
virtual void reset_fields() {}
+ virtual void set_default()
+ {
+ memcpy(ptr, ptr + table->rec_buff_length, pack_length());
+ }
virtual bool binary() const { return 1; }
virtual bool zero_pack() const { return 1; }
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
@@ -77,7 +82,7 @@ public:
virtual enum_field_types real_type() const { return type(); }
inline int cmp(const char *str) { return cmp(ptr,str); }
virtual int cmp(const char *,const char *)=0;
- virtual int cmp_binary(const char *a,const char *b, ulong max_length=~0L)
+ virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L)
{ return memcmp(a,b,pack_length()); }
virtual int cmp_offset(uint row_offset)
{ return memcmp(ptr,ptr+row_offset,pack_length()); }
@@ -89,11 +94,12 @@ public:
{ return cmp(ptr,(char*) str); }
virtual uint decimals() const { return 0; }
virtual void sql_type(String &str) const =0;
- // Caller beware: sql_type can change str.Ptr, so check
- // ptr() to see if it changed if you are using your own buffer
- // in str and restore it with set() if needed
-
- virtual uint size_of() const =0; // For new field
+ /*
+ Caller beware: sql_type can change str.Ptr, so check
+ ptr() to see if it changed if you are using your own buffer
+ in str and restore it with set() if needed
+ */
+ virtual uint size_of() const =0; /* For new field */
inline bool is_null(uint row_offset=0)
{ return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : table->null_row; }
inline bool is_real_null(uint row_offset=0)
@@ -101,30 +107,30 @@ public:
inline void set_null(int row_offset=0)
{ if (null_ptr) null_ptr[row_offset]|= null_bit; }
inline void set_notnull(int row_offset=0)
- { if (null_ptr) null_ptr[row_offset]&= ~null_bit; }
+ { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; }
inline bool real_maybe_null(void) { return null_ptr != 0; }
virtual void make_field(Send_field *)=0;
virtual void sort_string(char *buff,uint length)=0;
- virtual bool optimize_range();
+ virtual bool optimize_range(uint idx);
virtual bool store_for_compare() { return 0; }
- inline Field *new_field(struct st_table *new_table)
- {
- Field *tmp= (Field*) sql_memdup((char*) this,size_of());
- if (tmp)
- {
- tmp->table=new_table;
- tmp->key_start=tmp->part_of_key=tmp->part_of_sortkey=0;
- tmp->unireg_check=Field::NONE;
- tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
- tmp->reset_fields();
- }
- return tmp;
- }
- inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uint null_bit_arg)
+ Field *new_field(MEM_ROOT *root, struct st_table *new_table)
+ {
+ Field *tmp= (Field*) memdup_root(root,(char*) this,size_of());
+ if (tmp)
{
- ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
+ tmp->table=new_table;
+ tmp->key_start=tmp->part_of_key=tmp->part_of_sortkey=0;
+ tmp->unireg_check=Field::NONE;
+ tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
+ tmp->reset_fields();
}
+ return tmp;
+ }
+ inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
+ {
+ ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
+ }
inline void move_field(char *ptr_arg) { ptr=ptr_arg; }
inline void move_field(my_ptrdiff_t ptr_diff)
{
@@ -154,10 +160,10 @@ public:
ptr-=row_offset;
return tmp;
}
- bool send(String *packet);
+ bool send(THD *thd, String *packet);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{
- uint length=pack_length();
+ uint32 length=pack_length();
memcpy(to,from,length);
return to+length;
}
@@ -185,7 +191,7 @@ public:
{ return cmp(a,b); }
virtual int pack_cmp(const char *b, uint key_length_arg)
{ return cmp(ptr,b); }
- uint offset(); // Should be inline ...
+ uint offset(); /* Should be inline ... */
void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(TIME *ltime,bool fuzzydate);
@@ -210,12 +216,12 @@ public:
class Field_num :public Field {
public:
const uint8 dec;
- bool zerofill,unsigned_flag; // Purify cannot handle bit fields
+ bool zerofill,unsigned_flag; /* Purify cannot handle bit fields */
Field_num(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg, utype unireg_check_arg,
+ uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
dec(dec_arg),zerofill(zero_arg),unsigned_flag(unsigned_arg)
@@ -230,7 +236,7 @@ public:
void add_zerofill_and_unsigned(String &res) const;
friend class create_field;
void make_field(Send_field *);
- uint decimals() const { return dec; }
+ uint decimals() const { return (uint) dec; }
uint size_of() const { return sizeof(*this); }
bool eq_def(Field *field);
};
@@ -239,7 +245,7 @@ public:
class Field_str :public Field {
public:
Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg, utype unireg_check_arg,
+ uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg,
struct st_table *table_arg)
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -256,10 +262,10 @@ public:
class Field_decimal :public Field_num {
public:
Field_decimal(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg,unsigned_arg)
@@ -285,7 +291,7 @@ public:
class Field_tiny :public Field_num {
public:
Field_tiny(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -314,7 +320,7 @@ public:
class Field_short :public Field_num {
public:
Field_short(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -343,7 +349,7 @@ public:
class Field_medium :public Field_num {
public:
Field_medium(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -372,7 +378,7 @@ public:
class Field_long :public Field_num {
public:
Field_long(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -407,7 +413,7 @@ public:
class Field_longlong :public Field_num {
public:
Field_longlong(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -415,10 +421,11 @@ public:
unireg_check_arg, field_name_arg, table_arg,
0, zero_arg,unsigned_arg)
{}
- Field_longlong(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_arg)
+ Field_longlong(uint32 len_arg,bool maybe_null_arg,
+ const char *field_name_arg,
+ struct st_table *table_arg, bool unsigned_arg)
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, table_arg,0,0,0)
+ NONE, field_name_arg, table_arg,0,0,unsigned_arg)
{}
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return FIELD_TYPE_LONGLONG;}
@@ -441,10 +448,10 @@ public:
class Field_float :public Field_num {
public:
Field_float(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg,unsigned_arg)
@@ -468,16 +475,16 @@ public:
class Field_double :public Field_num {
public:
Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg,unsigned_arg)
{}
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_arg, uint dec_arg)
+ struct st_table *table_arg, uint8 dec_arg)
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
NONE, field_name_arg, table_arg,dec_arg,0,0)
{}
@@ -547,6 +554,10 @@ public:
bool store_for_compare() { return 1; }
bool zero_pack() const { return 0; }
void set_time();
+ virtual void set_default()
+ {
+ set_time();
+ }
inline long get_timestamp()
{
#ifdef WORDS_BIGENDIAN
@@ -566,7 +577,7 @@ public:
class Field_year :public Field_tiny {
public:
Field_year(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -585,12 +596,16 @@ public:
class Field_date :public Field_str {
public:
- Field_date(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_date(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg)
{}
+ Field_date(bool maybe_null_arg, const char *field_name_arg,
+ struct st_table *table_arg)
+ :Field_str((char*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
+ NONE, field_name_arg, table_arg) {}
enum_field_types type() const { return FIELD_TYPE_DATE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
enum Item_result cmp_type () const { return INT_RESULT; }
@@ -611,7 +626,7 @@ public:
class Field_newdate :public Field_str {
public:
- Field_newdate(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_newdate(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
@@ -642,12 +657,16 @@ public:
class Field_time :public Field_str {
public:
- Field_time(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_time(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg)
{}
+ Field_time(bool maybe_null_arg, const char *field_name_arg,
+ struct st_table *table_arg)
+ :Field_str((char*) 0,8, maybe_null_arg ? (uchar*) "": 0,0,
+ NONE, field_name_arg, table_arg) {}
enum_field_types type() const { return FIELD_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
enum Item_result cmp_type () const { return INT_RESULT; }
@@ -670,12 +689,16 @@ public:
class Field_datetime :public Field_str {
public:
- Field_datetime(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_datetime(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg)
{}
+ Field_datetime(bool maybe_null_arg, const char *field_name_arg,
+ struct st_table *table_arg)
+ :Field_str((char*) 0,19, maybe_null_arg ? (uchar*) "": 0,0,
+ NONE, field_name_arg, table_arg) {}
enum_field_types type() const { return FIELD_TYPE_DATETIME;}
#ifdef HAVE_LONG_LONG
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
@@ -704,7 +727,7 @@ class Field_string :public Field_str {
bool binary_flag;
public:
Field_string(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,bool binary_arg)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -759,7 +782,7 @@ class Field_varstring :public Field_str {
bool binary_flag;
public:
Field_varstring(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,bool binary_arg)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -809,10 +832,10 @@ public:
class Field_blob :public Field_str {
uint packlength;
- String value; // For temporaries
+ String value; /* For temporaries */
bool binary_flag;
public:
- Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint 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,
struct st_table *table_arg,uint blob_pack_length,
bool binary_arg);
@@ -836,21 +859,22 @@ public:
longlong val_int(void);
String *val_str(String*,String *);
int cmp(const char *,const char*);
- int cmp(const char *a, ulong a_length, const char *b, ulong b_length);
+ int cmp(const char *a, uint32 a_length, const char *b, uint32 b_length);
int cmp_offset(uint offset);
- int cmp_binary(const char *a,const char *b, ulong max_length=~0L);
+ int cmp_binary(const char *a,const char *b, uint32 max_length=~0L);
int cmp_binary_offset(uint row_offset);
int key_cmp(const byte *,const byte*);
int key_cmp(const byte *str, uint length);
uint32 key_length() const { return 0; }
void sort_string(char *buff,uint length);
- uint32 pack_length() const { return (uint32) (packlength+table->blob_ptr_size); }
- void reset(void) { bzero(ptr,packlength+sizeof(char*)); }
+ uint32 pack_length() const
+ { return (uint32) (packlength+table->blob_ptr_size); }
+ void reset(void) { bzero(ptr, packlength+sizeof(char*)); }
void reset_fields() { bzero((char*) &value,sizeof(value)); }
- void store_length(ulong number);
- inline ulong get_length(uint row_offset=0)
+ void store_length(uint32 number);
+ inline uint32 get_length(uint row_offset=0)
{ return get_length(ptr+row_offset); }
- ulong get_length(const char *ptr);
+ uint32 get_length(const char *ptr);
bool binary() const { return binary_flag; }
inline void get_ptr(char **str)
{
@@ -861,7 +885,7 @@ public:
memcpy(ptr,length,packlength);
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
}
- inline void set_ptr(ulong length,char *data)
+ inline void set_ptr(uint32 length,char *data)
{
store_length(length);
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
@@ -882,21 +906,6 @@ public:
}
char *pack(char *to, const char *from, uint max_length= ~(uint) 0);
const char *unpack(char *to, const char *from);
-#ifdef HAVE_GEMINI_DB
- char *pack_id(char *to, const char *from, ulonglong id,
- uint max_length= ~(uint) 0);
- ulonglong get_id(const char *from);
- const char *unpack_id(char *to, const char *from, const char *bdata);
- inline void get_ptr_from_key_image(char **str,char *key_str)
- {
- *str = key_str + sizeof(uint16);
- }
- inline uint get_length_from_key_image(char *key_str)
- {
- return uint2korr(key_str);
- }
- enum_field_types blobtype() { return (packlength == 1 ? FIELD_TYPE_TINY_BLOB : FIELD_TYPE_BLOB);}
-#endif
char *pack_key(char *to, const char *from, uint max_length);
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
int pack_cmp(const char *a, const char *b, uint key_length);
@@ -916,16 +925,16 @@ protected:
public:
TYPELIB *typelib;
Field_enum(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint packlength_arg,
TYPELIB *typelib_arg)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
packlength(packlength_arg),typelib(typelib_arg)
- {
+ {
flags|=ENUM_FLAG;
- }
+ }
enum_field_types type() const { return FIELD_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
@@ -944,7 +953,7 @@ public:
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_ENUM; }
virtual bool zero_pack() const { return 0; }
- bool optimize_range() { return 0; }
+ bool optimize_range(uint idx) { return 0; }
bool binary() const { return 0; }
bool eq_def(Field *field);
};
@@ -953,7 +962,7 @@ public:
class Field_set :public Field_enum {
public:
Field_set(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint32 packlength_arg,
TYPELIB *typelib_arg)
@@ -975,23 +984,23 @@ public:
/*
-** Create field class for CREATE TABLE
+ Create field class for CREATE TABLE
*/
class create_field :public Sql_alloc {
public:
const char *field_name;
- const char *change; // If done with alter table
- const char *after; // Put column after this one
- Item *def; // Default value
+ const char *change; /* If done with alter table */
+ const char *after; /* Put column after this one */
+ Item *def; /* Default value */
enum enum_field_types sql_type;
uint32 length;
uint decimals,flags,pack_length;
Field::utype unireg_check;
- TYPELIB *interval; // Which interval to use
- Field *field; // For alter table
+ TYPELIB *interval; /* Which interval to use */
+ Field *field; /* For alter table */
- uint8 row,col,sc_length,interval_id; // For rea_create_table
+ uint8 row,col,sc_length,interval_id; /* For rea_create_table */
uint offset,pack_flag;
create_field() :after(0) {}
create_field(Field *field, Field *orig_field);
@@ -999,7 +1008,7 @@ public:
/*
-** A class for sending info to the client
+ A class for sending info to the client
*/
class Send_field {
@@ -1024,19 +1033,19 @@ public:
uint from_bit,to_bit;
uint from_length,to_length;
Field *from_field,*to_field;
- String tmp; // For items
+ String tmp; /* For items */
Copy_field() {}
~Copy_field() {}
- void set(Field *to,Field *from,bool save); // Field to field
- void set(char *to,Field *from); // Field to string
+ void set(Field *to,Field *from,bool save); /* Field to field */
+ void set(char *to,Field *from); /* Field to string */
void (*do_copy)(Copy_field *);
- void (*do_copy2)(Copy_field *); // Used to handle null values
+ void (*do_copy2)(Copy_field *); /* Used to handle null values */
};
Field *make_field(char *ptr, uint32 field_length,
- uchar *null_pos, uint null_bit,
+ uchar *null_pos, uchar null_bit,
uint pack_flag, Field::utype unireg_check,
TYPELIB *interval, const char *field_name,
struct st_table *table);
@@ -1052,18 +1061,18 @@ bool test_if_int(const char *str,int length);
*/
#define FIELDFLAG_DECIMAL 1
-#define FIELDFLAG_BINARY 1 // Shares same flag
+#define FIELDFLAG_BINARY 1 /*Shares same flag */
#define FIELDFLAG_NUMBER 2
#define FIELDFLAG_ZEROFILL 4
-#define FIELDFLAG_PACK 120 // Bits used for packing
+#define FIELDFLAG_PACK 120 /* Bits used for packing */
#define FIELDFLAG_INTERVAL 256
-#define FIELDFLAG_BITFIELD 512 // mangled with dec!
-#define FIELDFLAG_BLOB 1024 // mangled with dec!
+#define FIELDFLAG_BITFIELD 512 /* mangled with dec! */
+#define FIELDFLAG_BLOB 1024 /* mangled with dec! */
#define FIELDFLAG_LEFT_FULLSCREEN 8192
#define FIELDFLAG_RIGHT_FULLSCREEN 16384
-#define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output
-#define FIELDFLAG_SUM ((uint) 32768)// predit: +#fieldflag
-#define FIELDFLAG_MAYBE_NULL ((uint) 32768)// sql
+#define FIELDFLAG_FORMAT_NUMBER 16384 /* predit: ###,,## in output */
+#define FIELDFLAG_SUM ((uint) 32768)/* predit: +#fieldflag */
+#define FIELDFLAG_MAYBE_NULL ((uint) 32768)/* sql */
#define FIELDFLAG_PACK_SHIFT 3
#define FIELDFLAG_DEC_SHIFT 8
#define FIELDFLAG_MAX_DEC 31
@@ -1079,7 +1088,7 @@ bool test_if_int(const char *str,int length);
#define f_is_zerofill(x) ((x) & FIELDFLAG_ZEROFILL)
#define f_is_packed(x) ((x) & FIELDFLAG_PACK)
#define f_packtype(x) (((x) >> FIELDFLAG_PACK_SHIFT) & 15)
-#define f_decimals(x) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC)
+#define f_decimals(x) ((uint8) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC))
#define f_is_alpha(x) (!f_is_num(x))
#define f_is_binary(x) ((x) & FIELDFLAG_BINARY)
#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL)
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 606edd84c74..c7a6d778953 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 86c95395965..c6782aa0d93 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -22,13 +22,11 @@
#include <stddef.h> /* for macro offsetof */
#endif
#include <m_ctype.h>
+#include "sql_sort.h"
+
#ifndef THREAD
-#define SKIPP_DBUG_IN_FILESORT
+#define SKIP_DBUG_IN_FILESORT
#endif
- /* static variabels */
-
-#define MERGEBUFF 7
-#define MERGEBUFF2 15
/* How to write record_ref. */
@@ -36,85 +34,65 @@
if (my_b_write((file),(byte*) (from),param->ref_length)) \
DBUG_RETURN(1);
-typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
- my_off_t file_pos; /* Where we are in the sort file */
- uchar *base,*key; /* key pointers */
- ha_rows count; /* Number of rows in table */
- ulong mem_count; /* numbers of keys in memory */
- ulong max_keys; /* Max keys in buffert */
-} BUFFPEK;
-
-
-typedef struct st_sort_param {
- uint sort_length; /* Length of sortarg */
- uint keys; /* Max antal nycklar / buffert */
- uint ref_length; /* Length of record ref. */
- ha_rows max_rows,examined_rows;
- TABLE *sort_form; /* For quicker make_sortkey */
- SORT_FIELD *local_sortorder;
- SORT_FIELD *end;
-#ifdef USE_STRCOLL
- char* tmp_buffer;
-#endif
-} SORTPARAM;
-
/* functions defined in this file */
static char **make_char_array(register uint fields, uint length, myf my_flag);
+static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffer_file, uint count);
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
- uchar * *sort_keys,
- BUFFPEK *buffpek,uint *maxbuffer,
+ uchar * *sort_keys, IO_CACHE *buffer_file,
IO_CACHE *tempfile,IO_CACHE *indexfile);
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
- uint count,BUFFPEK *buffpek,
- IO_CACHE *tempfile);
-static void make_sortkey(SORTPARAM *param,uchar *to,
- byte *ref_pos);
-static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count);
-static int merge_many_buff(SORTPARAM *param,uchar * *sort_keys,
- BUFFPEK *buffpek,
- uint *maxbuffer, IO_CACHE *t_file);
-static uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
- uint sort_length);
-static int merge_buffers(SORTPARAM *param,IO_CACHE *from_file,
- IO_CACHE *to_file,uchar * *sort_keys,
- BUFFPEK *lastbuff,BUFFPEK *Fb,
- BUFFPEK *Tb,int flag);
-static int merge_index(SORTPARAM *param,uchar * *sort_keys,
+ uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
+static void make_sortkey(SORTPARAM *param,uchar *to, byte *ref_pos);
+static int merge_index(SORTPARAM *param,uchar *sort_buffer,
BUFFPEK *buffpek,
uint maxbuffer,IO_CACHE *tempfile,
IO_CACHE *outfile);
+static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count);
static uint sortlength(SORT_FIELD *sortorder,uint length);
- /* Makes a indexfil of recordnumbers of a sorted database */
- /* outfile is reset before data is written to it, if it wasn't
- open a new file is opened */
+ /*
+ Creates a set of pointers that can be used to read the rows
+ in sorted order. This should be done with the functions
+ in records.cc
+
+ Before calling filesort, one must have done
+ table->file->info(HA_STATUS_VARIABLE)
+
+ The result set is stored in table->io_cache or
+ table->record_pointers
+ */
-ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
+ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
SQL_SELECT *select, ha_rows special, ha_rows max_rows,
ha_rows *examined_rows)
{
int error;
- uint memavl,old_memavl,maxbuffer,skr;
+ ulong memavl;
+ uint maxbuffer;
BUFFPEK *buffpek;
ha_rows records;
uchar **sort_keys;
- IO_CACHE tempfile,*selected_records_file,*outfile;
+ IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
SORTPARAM param;
+ THD *thd= current_thd;
+
DBUG_ENTER("filesort");
- DBUG_EXECUTE("info",TEST_filesort(table,sortorder,s_length,special););
-#ifdef SKIPP_DBUG_IN_FILESORT
+ DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length,special););
+#ifdef SKIP_DBUG_IN_FILESORT
DBUG_PUSH(""); /* No DBUG here */
#endif
- outfile= table[0]->io_cache;
+ outfile= table->io_cache;
my_b_clear(&tempfile);
- buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
- maxbuffer=1;
- param.ref_length= table[0]->file->ref_length;
+ my_b_clear(&buffpek_pointers);
+ buffpek=0;
+ sort_keys= (uchar **) NULL;
+ error= 1;
+ bzero((char*) &param,sizeof(param));
+ param.ref_length= table->file->ref_length;
param.sort_length=sortlength(sortorder,s_length)+ param.ref_length;
param.max_rows= max_rows;
- param.examined_rows=0;
if (select && select->quick)
{
@@ -139,17 +117,14 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
#ifdef CAN_TRUST_RANGE
else if (select && select->quick && select->quick->records > 0L)
{
- /* Get record-count */
- table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
- table[0]->file->records)+EXTRA_RECORDS;
+ table->file->records)+EXTRA_RECORDS;
selected_records_file=0;
}
#endif
else
{
- table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);/* Get record-count */
- records=table[0]->file->estimate_number_of_rows();
+ records=table->file->estimate_number_of_rows();
selected_records_file= 0;
}
if (param.sort_length == param.ref_length && records > param.max_rows)
@@ -161,54 +136,38 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
goto err;
#endif
- memavl=sortbuff_size;
+ memavl= thd->variables.sortbuff_size;
while (memavl >= MIN_SORT_MEMORY)
{
- if ((ulonglong) (records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
- (ulonglong) memavl)
- param.keys=(uint) records+1;
- else
- {
- maxbuffer=1;
- do
- {
- skr=maxbuffer;
- if (memavl < sizeof(BUFFPEK)*maxbuffer)
- {
- my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
- goto err;
- }
- param.keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
- (param.sort_length+sizeof(char*));
- }
- while ((maxbuffer= (uint) (records/param.keys+1)) != skr);
- }
- if ((sort_keys= (uchar **) make_char_array(param.keys,param.sort_length,
+ ulong old_memavl;
+ ulong keys= memavl/(param.sort_length+sizeof(char*));
+ param.keys=(uint) min(records+1, keys);
+ if ((sort_keys= (uchar **) make_char_array(param.keys, param.sort_length,
MYF(0))))
- if ((buffpek = (BUFFPEK*) my_malloc((uint) sizeof(BUFFPEK)*
- (maxbuffer+10),
- MYF(0))))
- break;
- else
- my_free((gptr) sort_keys,MYF(0));
+ break;
old_memavl=memavl;
if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
memavl=MIN_SORT_MEMORY;
}
- param.keys--;
- maxbuffer+=10; /* Some extra range */
-
if (memavl < MIN_SORT_MEMORY)
{
- my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size);
+ my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),
+ thd->variables.sortbuff_size);
goto err;
}
- param.sort_form= table[0];
+ if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
+ DISK_BUFFER_SIZE, MYF(MY_WME)))
+ goto err;
+
+ param.keys--;
+ param.sort_form= table;
param.end=(param.local_sortorder=sortorder)+s_length;
- if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer,
+ if ((records=find_all_keys(&param,select,sort_keys, &buffpek_pointers,
&tempfile, selected_records_file)) ==
HA_POS_ERROR)
goto err;
+ maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
+
if (maxbuffer == 0) // The whole set is in memory
{
if (save_index(&param,sort_keys,(uint) records))
@@ -216,6 +175,9 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
}
else
{
+ if (!(buffpek=read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
+ goto err;
+ close_cached_file(&buffpek_pointers);
/* Open cached file if it isn't open */
if (! my_b_inited(outfile) &&
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
@@ -223,14 +185,21 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
goto err;
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
+ /*
+ Use also the space previously used by string pointers in sort_buffer
+ for temporary key storage.
+ */
param.keys=((param.keys*(param.sort_length+sizeof(char*))) /
param.sort_length-1);
- if (merge_many_buff(&param,sort_keys,buffpek,&maxbuffer,&tempfile))
+ maxbuffer--; // Offset from 0
+ if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
+ &tempfile))
goto err;
if (flush_io_cache(&tempfile) ||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
goto err;
- if (merge_index(&param,sort_keys,buffpek,maxbuffer,&tempfile,outfile))
+ if (merge_index(&param,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
+ outfile))
goto err;
}
if (records > param.max_rows)
@@ -245,6 +214,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
x_free((gptr) sort_keys);
x_free((gptr) buffpek);
close_cached_file(&tempfile);
+ close_cached_file(&buffpek_pointers);
if (my_b_inited(outfile))
{
if (flush_io_cache(outfile))
@@ -262,7 +232,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
else
statistic_add(filesort_rows, records, &LOCK_status);
*examined_rows= param.examined_rows;
-#ifdef SKIPP_DBUG_IN_FILESORT
+#ifdef SKIP_DBUG_IN_FILESORT
DBUG_POP(); /* Ok to DBUG */
#endif
DBUG_PRINT("exit",("records: %ld",records));
@@ -289,11 +259,33 @@ static char **make_char_array(register uint fields, uint length, myf my_flag)
} /* make_char_array */
+ /* Read all buffer pointers into memory */
+
+static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
+{
+ ulong length;
+ BUFFPEK *tmp;
+ DBUG_ENTER("read_buffpek_from_file");
+ tmp=(BUFFPEK*) my_malloc(length=sizeof(BUFFPEK)*count, MYF(MY_WME));
+ if (tmp)
+ {
+ if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
+ my_b_read(buffpek_pointers, (byte*) tmp, length))
+ {
+ my_free((char*) tmp, MYF(0));
+ tmp=0;
+ }
+ }
+ DBUG_RETURN(tmp);
+}
+
+
+
/* Search after sort_keys and place them in a temp. file */
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
uchar **sort_keys,
- BUFFPEK *buffpek, uint *maxbuffer,
+ IO_CACHE *buffpek_pointers,
IO_CACHE *tempfile, IO_CACHE *indexfile)
{
int error,flag,quick_select;
@@ -314,7 +306,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
ref_pos= ref_buff;
quick_select=select && select->quick;
record=0;
- flag= ((!indexfile && file->option_flag() & HA_REC_NOT_IN_SEQ)
+ flag= ((!indexfile && file->table_flags() & HA_REC_NOT_IN_SEQ)
|| quick_select);
if (indexfile || flag)
ref_pos= &file->ref[0];
@@ -326,7 +318,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->extra(HA_EXTRA_KEYREAD); // QQ is removed
next_pos=(byte*) 0; /* Find records in sequence */
file->rnd_init();
- file->extra(HA_EXTRA_CACHE); /* Quicker reads */
+ file->extra_opt(HA_EXTRA_CACHE,
+ current_thd->variables.read_buff_size);
}
for (;;)
@@ -375,9 +368,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
{
if (idx == param->keys)
{
- if (indexpos >= *maxbuffer ||
- write_keys(param,sort_keys,idx,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR);
+ if (write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
+ DBUG_RETURN(HA_POS_ERROR);
idx=0; indexpos++;
if (param->ref_length == param->sort_length &&
my_b_tell(tempfile)/param->sort_length >= param->max_rows)
@@ -399,11 +391,9 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
}
- if (indexpos)
- if (indexpos >= *maxbuffer ||
- write_keys(param,sort_keys,idx,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
- *maxbuffer=indexpos;
+ if (indexpos &&
+ write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
DBUG_RETURN(my_b_inited(tempfile) ?
(ha_rows) (my_b_tell(tempfile)/param->sort_length) :
idx);
@@ -412,10 +402,13 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
/* Skriver en buffert med nycklar till filen */
-static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
- BUFFPEK *buffpek, IO_CACHE *tempfile)
+static int
+write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
+ IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
{
uint sort_length;
+ uchar **end;
+ BUFFPEK buffpek;
DBUG_ENTER("write_keys");
sort_length=param->sort_length;
@@ -427,15 +420,20 @@ static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
if (!my_b_inited(tempfile) &&
open_cached_file(tempfile,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
MYF(MY_WME)))
- DBUG_RETURN(1); /* purecov: inspected */
- buffpek->file_pos=my_b_tell(tempfile);
+ goto err; /* purecov: inspected */
+ buffpek.file_pos=my_b_tell(tempfile);
if ((ha_rows) count > param->max_rows)
count=(uint) param->max_rows; /* purecov: inspected */
- buffpek->count=(ha_rows) count;
- for (uchar **end=sort_keys+count ; sort_keys != end ; sort_keys++)
+ buffpek.count=(ha_rows) count;
+ for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
- DBUG_RETURN(1);
+ goto err;
+ if (my_b_write(buffpek_pointers, (byte*) &buffpek, sizeof(buffpek)))
+ goto err;
DBUG_RETURN(0);
+
+err:
+ DBUG_RETURN(1);
} /* write_keys */
@@ -458,10 +456,7 @@ static void make_sortkey(register SORTPARAM *param,
{
if (field->is_null())
{
- if (sort_field->reverse)
- bfill(to,sort_field->length+1,(char) 255);
- else
- bzero((char*) to,sort_field->length+1);
+ bzero((char*) to,sort_field->length+1);
to+= sort_field->length+1;
continue;
}
@@ -631,8 +626,8 @@ static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count)
/* Merge buffers to make < MERGEBUFF2 buffers */
-static int merge_many_buff(SORTPARAM *param, uchar **sort_keys,
- BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
+int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
+ BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
{
register int i;
IO_CACHE t_file2,*from_file,*to_file,*temp;
@@ -654,11 +649,11 @@ static int merge_many_buff(SORTPARAM *param, uchar **sort_keys,
lastbuff=buffpek;
for (i=0 ; i <= (int) *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
{
- if (merge_buffers(param,from_file,to_file,sort_keys,lastbuff++,
+ if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1,0))
break; /* purecov: inspected */
}
- if (merge_buffers(param,from_file,to_file,sort_keys,lastbuff++,
+ if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
buffpek+i,buffpek+ *maxbuffer,0))
break; /* purecov: inspected */
if (flush_io_cache(to_file))
@@ -677,8 +672,8 @@ static int merge_many_buff(SORTPARAM *param, uchar **sort_keys,
/* Read data to buffer */
/* This returns (uint) -1 if something goes wrong */
-static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
+ uint sort_length)
{
register uint count;
uint length;
@@ -699,39 +694,44 @@ static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
/* Merge buffers to one buffer */
-static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
- IO_CACHE *to_file, uchar **sort_keys,
- BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
- int flag)
+int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
+ IO_CACHE *to_file, uchar *sort_buffer,
+ BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
+ int flag)
{
int error;
uint sort_length,offset;
ulong maxcount;
- ha_rows count,max_rows;
+ ha_rows max_rows,org_max_rows;
my_off_t to_start_filepos;
uchar *strpos;
BUFFPEK *buffpek,**refpek;
QUEUE queue;
+ qsort2_cmp cmp;
volatile bool *killed= &current_thd->killed;
+ bool not_killable;
DBUG_ENTER("merge_buffers");
statistic_increment(filesort_merge_passes, &LOCK_status);
+ if (param->not_killable)
+ {
+ killed= &not_killable;
+ not_killable=0;
+ }
- count=error=0;
- offset=param->sort_length-param->ref_length;
+ error=0;
+ offset=(sort_length=param->sort_length)-param->ref_length;
maxcount=(ulong) (param->keys/((uint) (Tb-Fb) +1));
to_start_filepos=my_b_tell(to_file);
- strpos=(uchar*) sort_keys;
- sort_length=param->sort_length;
- max_rows=param->max_rows;
+ strpos=(uchar*) sort_buffer;
+ org_max_rows=max_rows=param->max_rows;
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*) (void *, byte *,byte*))
- get_ptr_compare(sort_length),(void*) &sort_length))
+ (cmp=get_ptr_compare(sort_length)),(void*) &sort_length))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
{
- count+= buffpek->count;
buffpek->base= strpos;
buffpek->max_keys=maxcount;
strpos+= (uint) (error=(int) read_to_buffer(from_file,buffpek,
@@ -741,15 +741,46 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
queue_insert(&queue,(byte*) buffpek);
}
+ if (param->unique_buff)
+ {
+ /*
+ Called by Unique::get()
+ Copy the first argument to param->unique_buff for unique removal.
+ Store it also in 'to_file'.
+
+ This is safe as we know that there is always more than one element
+ in each block to merge (This is guaranteed by the Unique:: algorithm
+ */
+ buffpek=(BUFFPEK*) queue_top(&queue);
+ memcpy(param->unique_buff, buffpek->key, sort_length);
+ if (my_b_write(to_file,(byte*) buffpek->key, sort_length))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
+ buffpek->key+=sort_length;
+ buffpek->mem_count--;
+ max_rows--;
+ queue_replaced(&queue); // Top element has been used
+ }
+ else
+ cmp=0; // Not unique
+
while (queue.elements > 1)
{
if (*killed)
{
- error=1; goto err; /* purecov: inspected */
+ error=1; goto err; /* purecov: inspected */
}
for (;;)
{
buffpek=(BUFFPEK*) queue_top(&queue);
+ if (cmp) // Remove duplicates
+ {
+ if (!(*cmp)(&sort_length, &(param->unique_buff),
+ (uchar**) &buffpek->key))
+ goto skip_duplicate;
+ memcpy(param->unique_buff, (uchar*) buffpek->key,sort_length);
+ }
if (flag == 0)
{
if (my_b_write(to_file,(byte*) buffpek->key, sort_length))
@@ -766,6 +797,8 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
error=0; /* purecov: inspected */
goto end; /* purecov: inspected */
}
+
+ skip_duplicate:
buffpek->key+=sort_length;
if (! --buffpek->mem_count)
{
@@ -798,14 +831,28 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
break; /* One buffer have been removed */
}
else if (error == -1)
- goto err; /* purecov: inspected */
+ goto err; /* purecov: inspected */
}
queue_replaced(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
- buffpek->base=(uchar *) sort_keys;
+ buffpek->base= sort_buffer;
buffpek->max_keys=param->keys;
+
+ /*
+ As we know all entries in the buffer are unique, we only have to
+ check if the first one is the same as the last one we wrote
+ */
+ if (cmp)
+ {
+ if (!(*cmp)(&sort_length, &(param->unique_buff), (uchar**) &buffpek->key))
+ {
+ buffpek->key+=sort_length; // Remove duplicate
+ --buffpek->mem_count;
+ }
+ }
+
do
{
if ((ha_rows) buffpek->mem_count > max_rows)
@@ -813,6 +860,7 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
buffpek->mem_count=(uint) max_rows;
buffpek->count=0; /* Don't read more */
}
+ max_rows-=buffpek->mem_count;
if (flag == 0)
{
if (my_b_write(to_file,(byte*) buffpek->key,
@@ -837,7 +885,7 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
!= -1 && error != 0);
end:
- lastbuff->count=min(count,param->max_rows);
+ lastbuff->count=min(org_max_rows-max_rows,param->max_rows);
lastbuff->file_pos=to_start_filepos;
err:
delete_queue(&queue);
@@ -847,12 +895,12 @@ err:
/* Do a merge to output-file (save only positions) */
-static int merge_index(SORTPARAM *param, uchar **sort_keys,
+static int merge_index(SORTPARAM *param, uchar *sort_buffer,
BUFFPEK *buffpek, uint maxbuffer,
IO_CACHE *tempfile, IO_CACHE *outfile)
{
DBUG_ENTER("merge_index");
- if (merge_buffers(param,tempfile,outfile,sort_keys,buffpek,buffpek,
+ if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
buffpek+maxbuffer,1))
DBUG_RETURN(1); /* purecov: inspected */
DBUG_RETURN(0);
@@ -865,6 +913,7 @@ static uint
sortlength(SORT_FIELD *sortorder, uint s_length)
{
reg2 uint length;
+ THD *thd= current_thd;
length=0;
for (; s_length-- ; sortorder++)
@@ -872,7 +921,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length)
if (sortorder->field)
{
if (sortorder->field->type() == FIELD_TYPE_BLOB)
- sortorder->length=max_item_sort_length;
+ sortorder->length= thd->variables.max_sort_length;
else
{
sortorder->length=sortorder->field->pack_length();
@@ -908,7 +957,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length)
if (sortorder->item->maybe_null)
length++; // Place for NULL marker
}
- set_if_smaller(sortorder->length,max_item_sort_length);
+ set_if_smaller(sortorder->length, thd->variables.max_sort_length);
length+=sortorder->length;
}
sortorder->field= (Field*) 0; // end marker
diff --git a/sql/frm_crypt.cc b/sql/frm_crypt.cc
index 629e4ffab95..8dd70900648 100644
--- a/sql/frm_crypt.cc
+++ b/sql/frm_crypt.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 7bbf08b50f3..776b6840b45 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -16,18 +16,19 @@
#define NO_YACC_SYMBOLS
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#ifndef __GNU_LIBRARY__
-#define __GNU_LIBRARY__ // Skipp warnings in getopt.h
+#define __GNU_LIBRARY__ // Skip warnings in getopt.h
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#include "mysql_version.h"
#include "lex.h"
-bool opt_search=0,opt_verbose=0;
-ulong opt_count=100000;
+my_bool opt_search;
+int opt_verbose;
+ulong opt_count;
#define max_allowed_array 8000 // Don't generate bigger arrays than this
#define max_symbol 32767 // Use this for 'not found'
@@ -54,6 +55,35 @@ static uchar bits[how_much_and/8+1];
static uint primes[max_allowed_array+1];
static ulong hash_results[type_count][how_much_for_plus+1][total_symbols];
static ulong start_value=0;
+static uint best_type;
+static ulong best_t1,best_t2, best_start_value;
+
+static struct my_option my_long_options[] =
+{
+ {"help", '?', "Display help and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"count", 'c', "Try count times to find a optimal hash table",
+ (gptr*) &opt_count, (gptr*) &opt_count, 0, GET_ULONG, REQUIRED_ARG,
+ 100000, 0, 0, 0, 0, 0},
+ {"search", 'S', "Search after good rnd1 and rnd2 values",
+ (gptr*) &opt_search, (gptr*) &opt_search, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"verbose", 'v', "Write some information while the program executes",
+ (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, GET_INT, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"version", 'V', "Output version information and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"rnd1", 'r', "Set 1 part of rnd value for hash generator",
+ (gptr*) &best_t1, (gptr*) &best_t1, 0, GET_ULONG, REQUIRED_ARG, 6657025L,
+ 0, 0, 0, 0, 0},
+ {"rnd2", 'R', "Set 2 part of rnd value for hash generator",
+ (gptr*) &best_t2, (gptr*) &best_t2, 0, GET_ULONG, REQUIRED_ARG, 6114496L,
+ 0, 0, 0, 0, 0},
+ {"type", 't', "Set type of char table to generate",
+ (gptr*) &best_type, (gptr*) &best_type, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0,
+ 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
struct rand_struct {
unsigned long seed1,seed2,max_value;
@@ -216,7 +246,7 @@ you have to change 'main' to print out the new function\n");
return(1);
}
- if (opt_verbose)
+ if (opt_verbose > 1)
fprintf (stderr,"Info: Possible add values: %d\n",found-type_count);
for (prime=primes; (function_mod=*prime) ; prime++)
@@ -324,86 +354,53 @@ void print_arrays()
}
-static struct option long_options[] =
-{
- {"count", required_argument, 0, 'c'},
- {"search", no_argument, 0, 'S'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"rnd1", required_argument, 0, 'r'},
- {"rnd2", required_argument, 0, 'R'},
- {"type", required_argument, 0, 't'},
- {0, 0, 0, 0}
-};
-
-
static void usage(int version)
{
- printf("%s Ver 3.3 Distrib %s, for %s (%s)\n",
+ printf("%s Ver 3.5 Distrib %s, for %s (%s)\n",
my_progname, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
if (version)
return;
puts("Copyright (C) 2001 MySQL AB, by Sinisa and Monty");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("This program generates a perfect hashing function for the sql_lex.cc");
- printf("Usage: %s [OPTIONS]\n", my_progname);
- printf("\n\
--c, --count=# Try count times to find a optimal hash table\n\
--r, --rnd1=# Set 1 part of rnd value for hash generator\n\
--R, --rnd2=# Set 2 part of rnd value for hash generator\n\
--t, --type=# Set type of char table to generate\n\
--S, --search Search after good rnd1 and rnd2 values\n\
--v, --verbose Write some information while the program executes\n\
--V, --version Output version information and exit\n");
+ printf("Usage: %s [OPTIONS]\n\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case 'v':
+ opt_verbose++;
+ break;
+ case 'V':
+ usage(1);
+ exit(0);
+ case 'I':
+ case '?':
+ usage(0);
+ exit(0);
+ }
+ return 0;
}
-static uint best_type;
-static ulong best_t1,best_t2, best_start_value;
static int get_options(int argc, char **argv)
{
- int c,option_index=0;
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
- while ((c=getopt_long(argc,argv,"?SvVc:r:R:t:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'c':
- opt_count=atol(optarg);
- break;
- case 'r':
- best_t1=atol(optarg);
- break;
- case 'R':
- best_t2=atol(optarg);
- break;
- case 't':
- best_type=atoi(optarg);
- break;
- case 'S':
- opt_search=1;
- break;
- case 'v':
- opt_verbose=1;
- break;
- case 'V': usage(1); exit(0);
- case 'I':
- case '?':
- usage(0);
- exit(0);
- default:
- fprintf(stderr,"illegal option: -%c\n",opterr);
- usage(0);
- exit(1);
- }
- }
- argc-=optind;
- argv+=optind;
if (argc >= 1)
{
+ fprintf(stderr,"%s: Too many arguments\n", my_progname);
usage(0);
- exit(1);
+ exit(1);
}
return(0);
}
@@ -481,7 +478,8 @@ int main(int argc,char **argv)
int error;
MY_INIT(argv[0]);
- start_value=6130115L; best_t1=3632784L; best_t2=86437L; best_type=3; /* mode=4229 add=2 type: 0 */
+
+ start_value=1109118L; /* mode=4903 add=3 type: 0 */
if (get_options(argc,(char **) argv))
exit(1);
@@ -501,7 +499,7 @@ int main(int argc,char **argv)
printf("start_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n",
start_value, best_t1,best_t2,best_type,best_mod,best_add,
best_functype);
-
+ best_start_value=start_value;
for (uint i=1 ; i <= opt_count ; i++)
{
if (i % 10 == 0)
@@ -524,6 +522,10 @@ int main(int argc,char **argv)
best_start_value,best_t1,best_t2,best_type,best_mod,best_add,
best_functype);
}
+ if (opt_verbose && (i % 20000) == 0)
+ printf("\nstart_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n",
+ best_start_value,best_t1,best_t2,best_type,best_mod,best_add,
+ best_functype);
}
}
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index f52b99f5a12..e34bfdea2dd 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -358,7 +358,7 @@ berkeley_cmp_packed_key(DB *file, const DBT *new_key, const DBT *saved_key)
KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts;
uint key_length=new_key->size;
- for ( ; key_part != end && (int) key_length > 0; key_part++)
+ for (; key_part != end && (int) key_length > 0; key_part++)
{
int cmp;
if (key_part->null_bit)
@@ -396,7 +396,7 @@ berkeley_cmp_fix_length_key(DB *file, const DBT *new_key, const DBT *saved_key)
KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts;
uint key_length=new_key->size;
- for ( ; key_part != end && (int) key_length > 0 ; key_part++)
+ for (; key_part != end && (int) key_length > 0 ; key_part++)
{
int cmp;
if ((cmp=key_part->field->pack_cmp(new_key_ptr,saved_key_ptr,0)))
@@ -417,7 +417,7 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
KEY_PART_INFO *key_part= key_info->key_part,
*end=key_part+key_info->key_parts;
- for ( ; key_part != end && (int) key_length > 0; key_part++)
+ for (; key_part != end && (int) key_length > 0; key_part++)
{
int cmp;
if (key_part->null_bit)
@@ -561,7 +561,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
ref_length=0;
KEY_PART_INFO *key_part= table->key_info[primary_key].key_part;
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
ref_length+= key_part->field->max_packed_col_length(key_part->length);
share->fixed_length_primary_key=
(ref_length == table->key_info[primary_key].key_length);
@@ -701,7 +701,7 @@ void ha_berkeley::unpack_key(char *record, DBT *key, uint index)
*end=key_part+key_info->key_parts;
char *pos=(char*) key->data;
- for ( ; key_part != end; key_part++)
+ for (; key_part != end; key_part++)
{
if (key_part->null_bit)
{
@@ -747,7 +747,7 @@ DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
key->data=buff;
key->app_private= key_info;
- for ( ; key_part != end && key_length > 0; key_part++)
+ for (; key_part != end && key_length > 0; key_part++)
{
if (key_part->null_bit)
{
@@ -925,7 +925,7 @@ int ha_berkeley::key_cmp(uint keynr, const byte * old_row,
KEY_PART_INFO *key_part=table->key_info[keynr].key_part;
KEY_PART_INFO *end=key_part+table->key_info[keynr].key_parts;
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
{
if (key_part->null_bit)
{
@@ -1043,9 +1043,9 @@ int ha_berkeley::restore_keys(DB_TXN *trans, key_map changed_keys,
break; /* purecov: inspected */
}
}
-
+
err:
- dbug_assert(error != DB_KEYEXIST);
+ DBUG_ASSERT(error != DB_KEYEXIST);
DBUG_RETURN(error);
}
@@ -1187,7 +1187,7 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record,
((table->key_info[keynr].flags & (HA_NOSAME | HA_NULL_PART_KEY)) ==
HA_NOSAME))
{ // Unique key
- dbug_assert(keynr == primary_key || prim_key->data != key_buff2);
+ DBUG_ASSERT(keynr == primary_key || prim_key->data != key_buff2);
error=key_file[keynr]->del(key_file[keynr], trans,
keynr == primary_key ?
prim_key :
@@ -1201,7 +1201,7 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record,
row to find the key to be delete and delete it.
We will never come here with keynr = primary_key
*/
- dbug_assert(keynr != primary_key && prim_key->data != key_buff2);
+ DBUG_ASSERT(keynr != primary_key && prim_key->data != key_buff2);
DBC *tmp_cursor;
if (!(error=key_file[keynr]->cursor(key_file[keynr], trans,
&tmp_cursor, 0)))
@@ -1454,6 +1454,37 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
DBUG_RETURN(error);
}
+/*
+ Read last key is solved by reading the next key and then reading
+ the previous key
+*/
+
+int ha_berkeley::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ DBT row;
+ int error;
+ KEY *key_info= &table->key_info[active_index];
+ DBUG_ENTER("ha_berkeley::index_read");
+
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ bzero((char*) &row,sizeof(row));
+
+ /* read of partial key */
+ pack_key(&last_key, active_index, key_buff, key, key_len);
+ /* Store for compare */
+ memcpy(key_buff2, key_buff, (key_len=last_key.size));
+ key_info->handler.bdb_return_if_eq= 1;
+ error=read_row(cursor->c_get(cursor, &last_key, &row, DB_SET_RANGE),
+ (char*) buf, active_index, &row, (DBT*) 0, 0);
+ key_info->handler.bdb_return_if_eq= 0;
+ bzero((char*) &row,sizeof(row));
+ if (read_row(cursor->c_get(cursor, &last_key, &row, DB_PREV),
+ (char*) buf, active_index, &row, &last_key, 1) ||
+ berkeley_key_cmp(table, key_info, key_buff2, key_len))
+ error=HA_ERR_KEY_NOT_FOUND;
+ DBUG_RETURN(error);
+}
+
int ha_berkeley::index_next(byte * buf)
{
@@ -1553,7 +1584,7 @@ DBT *ha_berkeley::get_pos(DBT *to, byte *pos)
KEY_PART_INFO *key_part=table->key_info[primary_key].key_part;
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
pos+=key_part->field->packed_col_length((char*) pos,key_part->length);
to->size= (uint) (pos- (byte*) to->data);
}
@@ -1565,12 +1596,13 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos)
{
DBT db_pos;
statistic_increment(ha_read_rnd_count,&LOCK_status);
+ DBUG_ENTER("ha_berkeley::rnd_pos");
active_index= (uint) -1; // Don't delete via cursor
- return read_row(file->get(file, transaction,
- get_pos(&db_pos, pos),
- &current_row, 0),
- (char*) buf, primary_key, &current_row, (DBT*) 0, 0);
+ DBUG_RETURN(read_row(file->get(file, transaction,
+ get_pos(&db_pos, pos),
+ &current_row, 0),
+ (char*) buf, primary_key, &current_row, (DBT*) 0, 0));
}
void ha_berkeley::position(const byte *record)
@@ -1669,7 +1701,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
DBUG_ASSERT(thd->transaction.stmt.bdb_tid == 0);
transaction=0; // Safety
/* First table lock, start transaction */
- if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN |
+ if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK)) &&
!thd->transaction.all.bdb_tid)
{
@@ -1879,13 +1911,14 @@ int ha_berkeley::delete_table(const char *name)
{
int error;
char name_buff[FN_REFLEN];
+ DBUG_ENTER("delete_table");
if ((error=db_create(&file, db_env, 0)))
my_errno=error; /* purecov: inspected */
else
error=file->remove(file,fn_format(name_buff,name,"",ha_berkeley_ext,2 | 4),
NULL,0);
file=0; // Safety
- return error;
+ DBUG_RETURN(error);
}
/*
@@ -2175,7 +2208,7 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table)
char *tmp_name;
DB **key_file;
u_int32_t *key_type;
-
+
if ((share=(BDB_SHARE *)
my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&share, sizeof(*share),
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index ab1ead5a3e9..ae425421c70 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -52,7 +52,7 @@ class ha_berkeley: public handler
u_int32_t *key_type;
DBC *cursor;
BDB_SHARE *share;
- ulong int_option_flag;
+ ulong int_table_flags;
ulong alloced_rec_buff_length;
ulong changed_rows;
uint primary_key,last_dup_key, hidden_primary_key, version;
@@ -86,20 +86,19 @@ class ha_berkeley: public handler
public:
ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV |
- HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_LONGLONG_KEYS | HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY |
- HA_BLOB_KEY | HA_NOT_EXACT_COUNT | HA_NO_FULLTEXT_KEY |
- HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
- HA_AUTO_PART_KEY),
+ int_table_flags(HA_REC_NOT_IN_SEQ |
+ HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
+ HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
+ HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX),
changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0)
{
}
~ha_berkeley() {}
const char *table_type() const { return "BerkeleyDB"; }
+ const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
+ ulong table_flags(void) const { return int_table_flags; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY-1; }
uint max_key_parts() const { return MAX_REF_PARTS; }
@@ -122,6 +121,7 @@ class ha_berkeley: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_next_same(byte * buf, const byte *key, uint keylen);
int index_prev(byte * buf);
diff --git a/sql/ha_gemini.cc b/sql/ha_gemini.cc
deleted file mode 100644
index e8130c55fc7..00000000000
--- a/sql/ha_gemini.cc
+++ /dev/null
@@ -1,3630 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & NuSphere Corporation
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* This file is based on ha_berkeley.cc */
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include "mysql_priv.h"
-#ifdef HAVE_GEMINI_DB
-#include "ha_gemini.h"
-#include "dbconfig.h"
-#include "dsmpub.h"
-#include "recpub.h"
-#include "vststat.h"
-
-#include <m_ctype.h>
-#include <myisampack.h>
-#include <m_string.h>
-#include <assert.h>
-#include <hash.h>
-#include <stdarg.h>
-#include "geminikey.h"
-
-#define gemini_msg MSGD_CALLBACK
-
-pthread_mutex_t gem_mutex;
-
-static HASH gem_open_tables;
-static GEM_SHARE *get_share(const char *table_name, TABLE *table);
-static int free_share(GEM_SHARE *share, bool mutex_is_locked);
-static byte* gem_get_key(GEM_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)));
-static void gemini_lock_table_overflow_error(dsmContext_t *pcontext);
-
-const char *ha_gemini_ext=".gmd";
-const char *ha_gemini_idx_ext=".gmi";
-
-bool gemini_skip=0;
-long gemini_options = 0;
-long gemini_buffer_cache;
-long gemini_io_threads;
-long gemini_log_cluster_size;
-long gemini_locktablesize;
-long gemini_lock_wait_timeout;
-long gemini_spin_retries;
-long gemini_connection_limit;
-char *gemini_basedir;
-
-const char gemini_dbname[] = "gemini";
-dsmContext_t *pfirstContext = NULL;
-
-ulong gemini_recovery_options = GEMINI_RECOVERY_FULL;
-/* bits in gemini_recovery_options */
-const char *gemini_recovery_names[] =
-{ "FULL", "NONE", "FORCE" };
-TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names),"",
- gemini_recovery_names};
-
-const int start_of_name = 2; /* Name passed as ./<db>/<table-name>
- and we're not interested in the ./ */
-static const int keyBufSize = MAXKEYSZ + FULLKEYHDRSZ + MAX_REF_PARTS + 16;
-
-static int gemini_tx_begin(THD *thd);
-static void print_msg(THD *thd, const char *table_name, const char *op_name,
- const char *msg_type, const char *fmt, ...);
-
-static int gemini_helper_threads(dsmContext_t *pContext);
-pthread_handler_decl(gemini_watchdog,arg );
-pthread_handler_decl(gemini_rl_writer,arg );
-pthread_handler_decl(gemini_apw,arg);
-
-/* General functions */
-
-bool gemini_init(void)
-{
- dsmStatus_t rc = 0;
- char pmsgsfile[MAXPATHN];
-
- DBUG_ENTER("gemini_init");
-
- gemini_basedir=mysql_home;
- /* If datadir isn't set, bail out */
- if (*mysql_real_data_home == '\0')
- {
- goto badret;
- }
-
- /* dsmContextCreate and dsmContextSetString(DSM_TAGDB_DBNAME) must
- ** be the first DSM calls we make so that we can log any errors which
- ** occur in subsequent DSM calls. DO NOT INSERT ANY DSM CALLS IN
- ** BETWEEN THIS COMMENT AND THE COMMENT THAT SAYS "END OF CODE..."
- */
- /* Gotta connect to the database regardless of the operation */
- rc = dsmContextCreate(&pfirstContext);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "dsmContextCreate failed %l",rc);
- goto badret;
- }
- /* This call will also open the log file */
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_DBNAME,
- strlen(gemini_dbname), (TEXT *)gemini_dbname);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "Dbname tag failed %l", rc);
- goto badret;
- }
- /* END OF CODE NOT TO MESS WITH */
-
- fn_format(pmsgsfile, GEM_MSGS_FILE, language, ".db", 2 | 4);
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_MSGS_FILE,
- strlen(pmsgsfile), (TEXT *)pmsgsfile);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "MSGS_DIR tag failed %l", rc);
- goto badret;
- }
-
- strxmov(pmsgsfile, gemini_basedir, GEM_SYM_FILE, NullS);
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_SYMFILE,
- strlen(pmsgsfile), (TEXT *)pmsgsfile);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "SYMFILE tag failed %l", rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_STARTUP);
- if ( rc != 0 )
- {
- gemini_msg(pfirstContext, "ACCESS TAG set failed %l",rc);
- goto badret;
- }
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_ENV, DSM_SQL_ENGINE);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "ACCESS_ENV set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_DATADIR,
- strlen(mysql_real_data_home),
- (TEXT *)mysql_real_data_home);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "Datadir tag failed %l", rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_MAX_USERS,
- gemini_connection_limit);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "MAX_USERS tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DEFAULT_LOCK_TIMEOUT,
- gemini_lock_wait_timeout);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "MAX_LOCK_ENTRIES tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_MAX_LOCK_ENTRIES,
- gemini_locktablesize);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "MAX_LOCK_ENTRIES tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_SPIN_AMOUNT,
- gemini_spin_retries);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "SPIN_AMOUNT tag set failed %l",rc);
- goto badret;
- }
-
- /* blocksize is hardcoded to 8K. Buffer cache is in bytes
- need to convert this to 8K blocks */
- gemini_buffer_cache = gemini_buffer_cache / 8192;
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DB_BUFFERS,
- gemini_buffer_cache);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "DB_BUFFERS tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_FLUSH_AT_COMMIT,
- ((gemini_options & GEMOPT_FLUSH_LOG) ? 0 : 1));
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "FLush_Log_At_Commit tag set failed %l",rc);
- goto badret;
- }
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DIRECT_IO,
- ((gemini_options & GEMOPT_UNBUFFERED_IO) ? 1 : 0));
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "DIRECT_IO tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_CRASH_PROTECTION,
- ((gemini_recovery_options & GEMINI_RECOVERY_FULL) ? 1 : 0));
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "CRASH_PROTECTION tag set failed %l",rc);
- goto badret;
- }
-
- if (gemini_recovery_options & GEMINI_RECOVERY_FORCE)
- {
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_FORCE_ACCESS, 1);
- if(rc != 0)
- {
- printf("CRASH_PROTECTION tag set failed %ld",rc);
- goto badret;
- }
- }
-
- /* cluster size will come in bytes, need to convert it to
- 16 K units. */
- gemini_log_cluster_size = (gemini_log_cluster_size + 16383) / 16384;
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_BI_CLUSTER_SIZE,
- gemini_log_cluster_size);
-
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "CRASH_PROTECTION tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmUserConnect(pfirstContext,(TEXT *)"Multi-user",
- DSM_DB_OPENDB | DSM_DB_OPENFILE);
- if( rc != 0 )
- {
- /* Message is output in dbenv() */
- goto badret;
- }
- /* Set access to shared for subsequent user connects */
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_SHARED);
-
- rc = gemini_helper_threads(pfirstContext);
-
-
- (void) hash_init(&gem_open_tables,32,0,0,
- (hash_get_key) gem_get_key,0,0);
- pthread_mutex_init(&gem_mutex,NULL);
-
-
- DBUG_RETURN(0);
-
-badret:
- gemini_skip = 1;
- DBUG_RETURN(0);
-}
-
-static int gemini_helper_threads(dsmContext_t *pContext)
-{
- int rc = 0;
- int i;
- pthread_attr_t thr_attr;
-
- pthread_t hThread;
- DBUG_ENTER("gemini_helper_threads");
-
- (void) pthread_attr_init(&thr_attr);
-#if !defined(HAVE_DEC_3_2_THREADS)
- pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
- (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&thr_attr,32768);
-#endif
- rc = pthread_create (&hThread, &thr_attr, gemini_watchdog, (void *)pContext);
- if (rc)
- {
- gemini_msg(pContext, "Can't Create gemini watchdog thread");
- goto done;
- }
- if(!gemini_io_threads)
- goto done;
-
- rc = pthread_create(&hThread, &thr_attr, gemini_rl_writer, (void *)pContext);
- if(rc)
- {
- gemini_msg(pContext, "Can't create Gemini recovery log writer thread");
- goto done;
- }
-
- for(i = gemini_io_threads - 1;i;i--)
- {
- rc = pthread_create(&hThread, &thr_attr, gemini_apw, (void *)pContext);
- if(rc)
- {
- gemini_msg(pContext, "Can't create Gemini database page writer thread");
- goto done;
- }
- }
-done:
-
- DBUG_RETURN(rc);
-}
-
-pthread_handler_decl(gemini_watchdog,arg )
-{
- int rc = 0;
- dsmContext_t *pcontext = (dsmContext_t *)arg;
- dsmContext_t *pmyContext = NULL;
-
-
- rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmContextCopy failed for Gemini watchdog %d",rc);
-
- return 0;
- }
- rc = dsmUserConnect(pmyContext,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmUserConnect failed for Gemini watchdog %d",rc);
-
- return 0;
- }
-
- my_thread_init();
- pthread_detach_this_thread();
-
- while(rc == 0)
- {
- rc = dsmDatabaseProcessEvents(pmyContext);
- if(!rc)
- rc = dsmWatchdog(pmyContext);
- sleep(1);
- }
- rc = dsmUserDisconnect(pmyContext,0);
- my_thread_end();
- return 0;
-}
-
-pthread_handler_decl(gemini_rl_writer,arg )
-{
- int rc = 0;
- dsmContext_t *pcontext = (dsmContext_t *)arg;
- dsmContext_t *pmyContext = NULL;
-
-
- rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmContextCopy failed for Gemini recovery log writer %d",rc);
-
- return 0;
- }
- rc = dsmUserConnect(pmyContext,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmUserConnect failed for Gemini recovery log writer %d",rc);
-
- return 0;
- }
-
- my_thread_init();
- pthread_detach_this_thread();
-
- while(rc == 0)
- {
- rc = dsmRLwriter(pmyContext);
- }
- rc = dsmUserDisconnect(pmyContext,0);
- my_thread_end();
- return 0;
-}
-
-pthread_handler_decl(gemini_apw,arg )
-{
- int rc = 0;
- dsmContext_t *pcontext = (dsmContext_t *)arg;
- dsmContext_t *pmyContext = NULL;
-
- my_thread_init();
- pthread_detach_this_thread();
-
- rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmContextCopy failed for Gemini page writer %d",rc);
- my_thread_end();
- return 0;
- }
- rc = dsmUserConnect(pmyContext,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmUserConnect failed for Gemini page writer %d",rc);
- my_thread_end();
- return 0;
- }
-
- while(rc == 0)
- {
- rc = dsmAPW(pmyContext);
- }
- rc = dsmUserDisconnect(pmyContext,0);
- my_thread_end();
- return 0;
-}
-
-int gemini_set_option_long(int optid, long optval)
-{
- dsmStatus_t rc = 0;
-
- switch (optid)
- {
- case GEM_OPTID_SPIN_RETRIES:
- /* If we don't have a context yet, skip the set and just save the
- ** value in gemini_spin_retries for a later gemini_init(). This
- ** may not ever happen, but we're covered if it does.
- */
- if (pfirstContext)
- {
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_SPIN_AMOUNT,
- optval);
- }
- if (rc)
- {
- gemini_msg(pfirstContext, "SPIN_AMOUNT tag set failed %l",rc);
- }
- else
- {
- gemini_spin_retries = optval;
- }
- break;
- }
-
- return rc;
-}
-
-static int gemini_connect(THD *thd)
-{
- DBUG_ENTER("gemini_connect");
-
- dsmStatus_t rc;
-
- rc = dsmContextCopy(pfirstContext,(dsmContext_t **)&thd->gemini.context,
- DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "dsmContextCopy failed %l",rc);
-
- return(rc);
- }
- rc = dsmUserConnect((dsmContext_t *)thd->gemini.context,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "dsmUserConnect failed %l",rc);
-
- return(rc);
- }
- rc = (dsmStatus_t)gemini_tx_begin(thd);
-
- DBUG_RETURN(rc);
-}
-
-void gemini_disconnect(THD *thd)
-{
- dsmStatus_t rc;
-
- if(thd->gemini.context)
- {
- rc = dsmUserDisconnect((dsmContext_t *)thd->gemini.context,0);
- }
- return;
-}
-
-bool gemini_end(void)
-{
- dsmStatus_t rc;
- THD *thd;
-
- DBUG_ENTER("gemini_end");
-
- hash_free(&gem_open_tables);
- pthread_mutex_destroy(&gem_mutex);
- if(pfirstContext)
- {
- rc = dsmShutdownSet(pfirstContext, DSM_SHUTDOWN_NORMAL);
- sleep(2);
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_STARTUP);
- rc = dsmShutdown(pfirstContext, DSMNICEBIT,DSMNICEBIT);
- }
- DBUG_RETURN(0);
-}
-
-bool gemini_flush_logs()
-{
- DBUG_ENTER("gemini_flush_logs");
-
- DBUG_RETURN(0);
-}
-
-static int gemini_tx_begin(THD *thd)
-{
- dsmStatus_t rc;
- DBUG_ENTER("gemini_tx_begin");
-
- thd->gemini.savepoint = 1;
-
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_START,0,NULL);
- if(!rc)
- thd->gemini.needSavepoint = 1;
-
- thd->gemini.tx_isolation = thd->tx_isolation;
-
- DBUG_PRINT("trans",("beginning transaction"));
- DBUG_RETURN(rc);
-}
-
-int gemini_commit(THD *thd)
-{
- dsmStatus_t rc;
- LONG txNumber = 0;
-
- DBUG_ENTER("gemini_commit");
-
- if(!thd->gemini.context)
- DBUG_RETURN(0);
-
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- 0,DSMTXN_COMMIT,0,NULL);
- if(!rc)
- rc = gemini_tx_begin(thd);
-
- thd->gemini.lock_count = 0;
-
- DBUG_PRINT("trans",("ending transaction"));
- DBUG_RETURN(rc);
-}
-
-int gemini_rollback(THD *thd)
-{
- dsmStatus_t rc;
- LONG txNumber;
-
- DBUG_ENTER("gemini_rollback");
- DBUG_PRINT("trans",("aborting transaction"));
-
- if(!thd->gemini.context)
- DBUG_RETURN(0);
-
- thd->gemini.savepoint = 0;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_ABORT,0,NULL);
- if(!rc)
- rc = gemini_tx_begin(thd);
-
- thd->gemini.lock_count = 0;
-
- DBUG_RETURN(rc);
-}
-
-int gemini_rollback_to_savepoint(THD *thd)
-{
- dsmStatus_t rc = 0;
- DBUG_ENTER("gemini_rollback_to_savepoint");
- if(thd->gemini.savepoint > 1)
- {
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL);
- }
- DBUG_RETURN(rc);
-}
-
-int gemini_recovery_logging(THD *thd, bool on)
-{
- int error;
- int noLogging;
-
- if(!thd->gemini.context)
- return 0;
-
- if(on)
- noLogging = 0;
- else
- noLogging = 1;
-
- error = dsmContextSetLong((dsmContext_t *)thd->gemini.context,
- DSM_TAGCONTEXT_NO_LOGGING,noLogging);
- return error;
-}
-
-/* gemDataType - translates from mysql data type constant to gemini
- key services data type contstant */
-int gemDataType ( int mysqlType )
-{
- switch (mysqlType)
- {
- case FIELD_TYPE_LONG:
- case FIELD_TYPE_TINY:
- case FIELD_TYPE_SHORT:
- case FIELD_TYPE_TIMESTAMP:
- case FIELD_TYPE_LONGLONG:
- case FIELD_TYPE_INT24:
- case FIELD_TYPE_DATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_YEAR:
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_ENUM:
- case FIELD_TYPE_SET:
- return GEM_INT;
- case FIELD_TYPE_DECIMAL:
- return GEM_DECIMAL;
- case FIELD_TYPE_FLOAT:
- return GEM_FLOAT;
- case FIELD_TYPE_DOUBLE:
- return GEM_DOUBLE;
- case FIELD_TYPE_TINY_BLOB:
- return GEM_TINYBLOB;
- case FIELD_TYPE_MEDIUM_BLOB:
- return GEM_MEDIUMBLOB;
- case FIELD_TYPE_LONG_BLOB:
- return GEM_LONGBLOB;
- case FIELD_TYPE_BLOB:
- return GEM_BLOB;
- case FIELD_TYPE_VAR_STRING:
- case FIELD_TYPE_STRING:
- return GEM_CHAR;
- }
- return -1;
-}
-
-/*****************************************************************************
-** Gemini tables
-*****************************************************************************/
-
-const char **ha_gemini::bas_ext() const
-{ static const char *ext[]= { ha_gemini_ext, ha_gemini_idx_ext, NullS };
- return ext;
-}
-
-
-int ha_gemini::open(const char *name, int mode, uint test_if_locked)
-{
- dsmObject_t tableId = 0;
- THD *thd;
- char name_buff[FN_REFLEN];
- char tabname_buff[FN_REFLEN];
- char dbname_buff[FN_REFLEN];
- unsigned i,nameLen;
- LONG txNumber;
- dsmStatus_t rc;
-
- DBUG_ENTER("ha_gemini::open");
-
- thd = current_thd;
- /* Init shared structure */
- if (!(share=get_share(name,table)))
- {
- DBUG_RETURN(1); /* purecov: inspected */
- }
- thr_lock_data_init(&share->lock,&lock,(void*) 0);
-
- ref_length = sizeof(dsmRecid_t);
-
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- return rc;
- }
- if (!(rec_buff=(byte*)my_malloc(table->rec_buff_length,
- MYF(MY_WME))))
- {
- DBUG_RETURN(1);
- }
-
- /* separate out the name of the table and the database (a VST must be
- ** created in the mysql database)
- */
- rc = gemini_parse_table_name(name, dbname_buff, tabname_buff);
- if (rc == 0)
- {
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- tableId = gemini_is_vst(tabname_buff);
- }
- }
- sprintf(name_buff, "%s.%s", dbname_buff, tabname_buff);
-
- /* if it's not a VST, get the table number the regular way */
- if (!tableId)
- {
- rc = dsmObjectNameToNum((dsmContext_t *)thd->gemini.context,
- (dsmText_t *)name_buff,
- &tableId);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to find table number for %s", name_buff);
- DBUG_RETURN(rc);
- }
- }
- tableNumber = tableId;
-
- if(!rc)
- rc = index_open(name_buff);
-
- fixed_length_row=!(table->db_create_options & HA_OPTION_PACK_RECORD);
- key_read = 0;
- using_ignore = 0;
-
- /* Get the gemini table status -- we want to know if the table
- crashed while being in the midst of a repair operation */
- rc = dsmTableStatus((dsmContext_t *)thd->gemini.context,
- tableNumber,&tableStatus);
- if(tableStatus == DSM_OBJECT_IN_REPAIR)
- tableStatus = HA_ERR_CRASHED;
-
- pthread_mutex_lock(&share->mutex);
- share->use_count++;
- pthread_mutex_unlock(&share->mutex);
-
- if (table->blob_fields)
- {
- /* Allocate room for the blob ids from an unpacked row. Note that
- ** we may not actually need all of this space because tiny blobs
- ** are stored in the packed row, not in a separate storage object
- ** like larger blobs. But we allocate an entry for all blobs to
- ** keep the code simpler.
- */
- pBlobDescs = (gemBlobDesc_t *)my_malloc(
- table->blob_fields * sizeof(gemBlobDesc_t),
- MYF(MY_WME | MY_ZEROFILL));
- }
- else
- {
- pBlobDescs = 0;
- }
-
- get_index_stats(thd);
- info(HA_STATUS_CONST);
-
- DBUG_RETURN (rc);
-}
-
-/* Look up and store the object numbers for the indexes on this table */
-int ha_gemini::index_open(char *tableName)
-{
- dsmStatus_t rc = 0;
- int nameLen;
-
- DBUG_ENTER("ha_gemini::index_open");
- if(table->keys)
- {
- THD *thd = current_thd;
- dsmObject_t objectNumber;
- if (!(pindexNumbers=(dsmIndex_t *)my_malloc(table->keys*sizeof(dsmIndex_t),
- MYF(MY_WME))))
- {
- DBUG_RETURN(1);
- }
- nameLen = strlen(tableName);
- tableName[nameLen] = '.';
- nameLen++;
-
- for( uint i = 0; i < table->keys && !rc; i++)
- {
- strcpy(&tableName[nameLen],table->key_info[i].name);
- rc = dsmObjectNameToNum((dsmContext_t *)thd->gemini.context,
- (dsmText_t *)tableName,
- &objectNumber);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to file Index number for %s", tableName);
- DBUG_RETURN(rc);
- }
- pindexNumbers[i] = objectNumber;
- }
- }
- else
- pindexNumbers = 0;
-
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::close(void)
-{
- DBUG_ENTER("ha_gemini::close");
- my_free((char*)rec_buff,MYF(MY_ALLOW_ZERO_PTR));
- rec_buff = 0;
- my_free((char *)pindexNumbers,MYF(MY_ALLOW_ZERO_PTR));
- pindexNumbers = 0;
-
- if (pBlobDescs)
- {
- for (uint i = 0; i < table->blob_fields; i++)
- {
- my_free((char*)pBlobDescs[i].pBlob, MYF(MY_ALLOW_ZERO_PTR));
- }
- my_free((char *)pBlobDescs, MYF(0));
- pBlobDescs = 0;
- }
-
- DBUG_RETURN(free_share(share, 0));
-}
-
-
-int ha_gemini::write_row(byte * record)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- THD *thd;
-
- DBUG_ENTER("write_row");
-
- if(tableStatus == HA_ERR_CRASHED)
- DBUG_RETURN(tableStatus);
-
- thd = current_thd;
-
- statistic_increment(ha_write_count,&LOCK_status);
- if (table->time_stamp)
- update_timestamp(record+table->time_stamp-1);
-
- if(thd->gemini.needSavepoint || using_ignore)
- {
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- DBUG_RETURN(error);
- thd->gemini.needSavepoint = 0;
- }
-
- if (table->next_number_field && record == table->record[0])
- {
- if(thd->next_insert_id)
- {
- ULONG64 nr;
- /* A set insert-id statement so set the auto-increment value if this
- value is higher than it's current value */
- error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context,
- tableNumber, (ULONG64 *)&nr,1);
- if(thd->next_insert_id > nr)
- {
- error = dsmTableAutoIncrementSet((dsmContext_t *)thd->gemini.context,
- tableNumber,
- (ULONG64)thd->next_insert_id);
- }
- }
-
- update_auto_increment();
- }
-
- dsmRecord.table = tableNumber;
- dsmRecord.maxLength = table->rec_buff_length;
-
- if ((error=pack_row((byte **)&dsmRecord.pbuffer, (int *)&dsmRecord.recLength,
- record, FALSE)))
- {
- DBUG_RETURN(error);
- }
-
- error = dsmRecordCreate((dsmContext_t *)thd->gemini.context,
- &dsmRecord,0);
-
- if(!error)
- {
- error = handleIndexEntries(record, dsmRecord.recid,KEY_CREATE);
- if(error == HA_ERR_FOUND_DUPP_KEY && using_ignore)
- {
- dsmStatus_t rc;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL);
- thd->gemini.needSavepoint = 1;
- }
- }
- if(error == DSM_S_RQSTREJ)
- error = HA_ERR_LOCK_WAIT_TIMEOUT;
-
- DBUG_RETURN(error);
-}
-
-longlong ha_gemini::get_auto_increment()
-{
- longlong nr;
- int error;
- int update;
- THD *thd=current_thd;
-
- if(thd->lex.sql_command == SQLCOM_SHOW_TABLES)
- update = 0;
- else
- update = 1;
-
- error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context,
- tableNumber, (ULONG64 *)&nr,
- update);
- return nr;
-}
-
-/* Put or delete index entries for a row */
-int ha_gemini::handleIndexEntries(const byte * record, dsmRecid_t recid,
- enum_key_string_options option)
-{
- dsmStatus_t rc = 0;
-
- DBUG_ENTER("handleIndexEntries");
-
- for (uint i = 0; i < table->keys && rc == 0; i++)
- {
- rc = handleIndexEntry(record, recid,option, i);
- }
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::handleIndexEntry(const byte * record, dsmRecid_t recid,
- enum_key_string_options option,uint keynr)
-{
- dsmStatus_t rc = 0;
- KEY *key_info;
- int keyStringLen;
- bool thereIsAnull;
- THD *thd;
-
- AUTOKEY(theKey,keyBufSize);
-
- DBUG_ENTER("handleIndexEntry");
-
- thd = current_thd;
- key_info=table->key_info+keynr;
- thereIsAnull = FALSE;
- rc = createKeyString(record, key_info, theKey.akey.keystr,
- sizeof(theKey.apad),&keyStringLen,
- (short)pindexNumbers[keynr],
- &thereIsAnull);
- if(!rc)
- {
- theKey.akey.index = pindexNumbers[keynr];
- theKey.akey.keycomps = (COUNT)key_info->key_parts;
-
- /* We have to subtract three here since cxKeyPrepare
- expects that the three lead bytes of the header are
- not counted in this length -- But cxKeyPrepare also
- expects that these three bytes are present in the keystr */
- theKey.akey.keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
- theKey.akey.unknown_comp = (dsmBoolean_t)thereIsAnull;
- theKey.akey.word_index = 0;
- theKey.akey.descending_key =0;
- if(option == KEY_CREATE)
- {
- rc = dsmKeyCreate((dsmContext_t *)thd->gemini.context, &theKey.akey,
- (dsmTable_t)tableNumber, recid, NULL);
- if(rc == DSM_S_IXDUPKEY)
- {
- last_dup_key=keynr;
- rc = HA_ERR_FOUND_DUPP_KEY;
- }
- }
- else if(option == KEY_DELETE)
- {
- rc = dsmKeyDelete((dsmContext_t *)thd->gemini.context, &theKey.akey,
- (dsmTable_t)tableNumber, recid, 0, NULL);
- }
- else
- {
- /* KEY_CHECK */
- dsmCursid_t aCursorId;
- int error;
-
- rc = dsmCursorCreate((dsmContext_t *)thd->gemini.context,
- (dsmTable_t)tableNumber,
- (dsmIndex_t)pindexNumbers[keynr],
- &aCursorId,NULL);
-
- rc = dsmCursorFind((dsmContext_t *)thd->gemini.context,
- &aCursorId,&theKey.akey,NULL,DSMDBKEY,
- DSMFINDFIRST,DSM_LK_SHARE,0,
- &lastRowid,0);
- error = dsmCursorDelete((dsmContext_t *)thd->gemini.context,
- &aCursorId, 0);
-
- }
- }
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::createKeyString(const byte * record, KEY *pkeyinfo,
- unsigned char *pkeyBuf, int bufSize,
- int *pkeyStringLen,
- short geminiIndexNumber,
- bool *thereIsAnull)
-{
- dsmStatus_t rc = 0;
- int componentLen;
- int fieldType;
- int isNull;
- uint key_part_length;
-
- KEY_PART_INFO *key_part;
-
- DBUG_ENTER("createKeyString");
-
- rc = gemKeyInit(pkeyBuf,pkeyStringLen, geminiIndexNumber);
-
- for(uint i = 0; i < pkeyinfo->key_parts && rc == 0; i++)
- {
- unsigned char *pos;
-
- key_part = pkeyinfo->key_part + i;
- key_part_length = key_part->length;
- fieldType = gemDataType(key_part->field->type());
- switch (fieldType)
- {
- case GEM_CHAR:
- {
- /* Save the current ptr to the field in case we're building a key
- to remove an old key value when an indexed character column
- gets updated. */
- char *ptr = key_part->field->ptr;
- key_part->field->ptr = (char *)record + key_part->offset;
- key_part->field->sort_string((char*)rec_buff, key_part->length);
- key_part->field->ptr = ptr;
- pos = (unsigned char *)rec_buff;
- }
- break;
-
- case GEM_TINYBLOB:
- case GEM_BLOB:
- case GEM_MEDIUMBLOB:
- case GEM_LONGBLOB:
- ((Field_blob*)key_part->field)->get_ptr((char**)&pos);
- key_part_length = ((Field_blob*)key_part->field)->get_length(
- (char*)record + key_part->offset);
- break;
-
- default:
- pos = (unsigned char *)record + key_part->offset;
- break;
- }
-
- isNull = record[key_part->null_offset] & key_part->null_bit;
- if(isNull)
- *thereIsAnull = TRUE;
-
- rc = gemFieldToIdxComponent(pos,
- (unsigned long) key_part_length,
- fieldType,
- isNull ,
- key_part->field->flags & UNSIGNED_FLAG,
- pkeyBuf + *pkeyStringLen,
- bufSize,
- &componentLen);
- *pkeyStringLen += componentLen;
- }
- DBUG_RETURN(rc);
-}
-
-
-int ha_gemini::update_row(const byte * old_record, byte * new_record)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- unsigned long savepoint;
- THD *thd = current_thd;
- DBUG_ENTER("update_row");
-
- statistic_increment(ha_update_count,&LOCK_status);
- if (table->time_stamp)
- update_timestamp(new_record+table->time_stamp-1);
-
- if(thd->gemini.needSavepoint || using_ignore)
- {
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- DBUG_RETURN(error);
- thd->gemini.needSavepoint = 0;
- }
- for (uint keynr=0 ; keynr < table->keys ; keynr++)
- {
- if(key_cmp(keynr,old_record, new_record,FALSE))
- {
- error = handleIndexEntry(old_record,lastRowid,KEY_DELETE,keynr);
- if(error)
- DBUG_RETURN(error);
- error = handleIndexEntry(new_record, lastRowid, KEY_CREATE, keynr);
- if(error)
- {
- if (using_ignore && error == HA_ERR_FOUND_DUPP_KEY)
- {
- dsmStatus_t rc;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL);
- thd->gemini.needSavepoint = 1;
- }
- DBUG_RETURN(error);
- }
- }
- }
-
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
- dsmRecord.maxLength = table->rec_buff_length;
-
- if ((error=pack_row((byte **)&dsmRecord.pbuffer, (int *)&dsmRecord.recLength,
- new_record, TRUE)))
- {
- DBUG_RETURN(error);
- }
- error = dsmRecordUpdate((dsmContext_t *)thd->gemini.context,
- &dsmRecord, 0, NULL);
-
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::delete_row(const byte * record)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- THD *thd = current_thd;
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- DBUG_ENTER("delete_row");
-
- statistic_increment(ha_delete_count,&LOCK_status);
-
- if(thd->gemini.needSavepoint)
- {
- thd->gemini.savepoint++;
- error = dsmTransaction(pcontext, &thd->gemini.savepoint, DSMTXN_SAVE, 0, 0);
- if (error)
- DBUG_RETURN(error);
- thd->gemini.needSavepoint = 0;
- }
-
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
-
- error = handleIndexEntries(record, dsmRecord.recid,KEY_DELETE);
- if(!error)
- {
- error = dsmRecordDelete(pcontext, &dsmRecord, 0, NULL);
- }
-
- /* Delete any blobs associated with this row */
- if (table->blob_fields)
- {
- dsmBlob_t gemBlob;
-
- gemBlob.areaType = DSMOBJECT_BLOB;
- gemBlob.blobObjNo = tableNumber;
- for (uint i = 0; i < table->blob_fields; i++)
- {
- if (pBlobDescs[i].blobId)
- {
- gemBlob.blobId = pBlobDescs[i].blobId;
- my_free((char *)pBlobDescs[i].pBlob, MYF(MY_ALLOW_ZERO_PTR));
- dsmBlobStart(pcontext, &gemBlob);
- dsmBlobDelete(pcontext, &gemBlob, NULL);
- /* according to DSM doc, no need to call dsmBlobEnd() */
- }
- }
- }
-
- DBUG_RETURN(error);
-}
-
-int ha_gemini::index_init(uint keynr)
-{
- int error = 0;
- THD *thd;
- DBUG_ENTER("index_init");
- thd = current_thd;
-
- lastRowid = 0;
- active_index=keynr;
- error = dsmCursorCreate((dsmContext_t *)thd->gemini.context,
- (dsmTable_t)tableNumber,
- (dsmIndex_t)pindexNumbers[keynr],
- &cursorId,NULL);
- pbracketBase = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,
- MYF(MY_WME));
- if(!pbracketBase)
- DBUG_RETURN(1);
- pbracketLimit = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,MYF(MY_WME));
- if(!pbracketLimit)
- {
- my_free((char *)pbracketLimit,MYF(0));
- DBUG_RETURN(1);
- }
- pbracketBase->index = 0;
- pbracketLimit->index = (dsmIndex_t)pindexNumbers[keynr];
- pbracketBase->descending_key = pbracketLimit->descending_key = 0;
- pbracketBase->ksubstr = pbracketLimit->ksubstr = 0;
- pbracketLimit->keycomps = pbracketBase->keycomps = 1;
-
- pfoundKey = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,MYF(MY_WME));
- if(!pfoundKey)
- {
- my_free((char *)pbracketLimit,MYF(0));
- my_free((char *)pbracketBase,MYF(0));
- DBUG_RETURN(1);
- }
-
- DBUG_RETURN(error);
-}
-
-int ha_gemini::index_end()
-{
- int error = 0;
- THD *thd;
- DBUG_ENTER("index_end");
- thd = current_thd;
- error = dsmCursorDelete((dsmContext_t *)thd->gemini.context,
- &cursorId, 0);
- if(pbracketLimit)
- my_free((char *)pbracketLimit,MYF(0));
- if(pbracketBase)
- my_free((char *)pbracketBase,MYF(0));
- if(pfoundKey)
- my_free((char *)pfoundKey,MYF(0));
-
- pbracketLimit = 0;
- pbracketBase = 0;
- pfoundKey = 0;
- DBUG_RETURN(error);
-}
-
-/* This is only used to read whole keys */
-
-int ha_gemini::index_read_idx(byte * buf, uint keynr, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)
-{
- int error = 0;
- DBUG_ENTER("index_read_idx");
- statistic_increment(ha_read_key_count,&LOCK_status);
-
- error = index_init(keynr);
- if (!error)
- error = index_read(buf,key,key_len,find_flag);
-
- if(error == HA_ERR_END_OF_FILE)
- error = HA_ERR_KEY_NOT_FOUND;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-int ha_gemini::pack_key( uint keynr, dsmKey_t *pkey,
- const byte *key_ptr, uint key_length)
-{
- KEY *key_info=table->key_info+keynr;
- KEY_PART_INFO *key_part=key_info->key_part;
- KEY_PART_INFO *end=key_part+key_info->key_parts;
- int rc;
- int componentLen;
- DBUG_ENTER("pack_key");
-
- rc = gemKeyInit(pkey->keystr,&componentLen,
- (short)pindexNumbers[active_index]);
- pkey->keyLen = componentLen;
-
- for (; key_part != end && (int) key_length > 0 && !rc; key_part++)
- {
- uint offset=0;
- unsigned char *pos;
- uint key_part_length = key_part->length;
-
- int fieldType;
- if (key_part->null_bit)
- {
- offset=1;
- if (*key_ptr != 0) // Store 0 if NULL
- {
- key_length-= key_part->store_length;
- key_ptr+= key_part->store_length;
- rc = gemFieldToIdxComponent(
- (unsigned char *)key_ptr + offset,
- (unsigned long) key_part_length,
- 0,
- 1 , /* Tells it to build a null component */
- key_part->field->flags & UNSIGNED_FLAG,
- pkey->keystr + pkey->keyLen,
- keyBufSize,
- &componentLen);
- pkey->keyLen += componentLen;
- continue;
- }
- }
- fieldType = gemDataType(key_part->field->type());
- switch (fieldType)
- {
- case GEM_CHAR:
- key_part->field->store((char*)key_ptr + offset, key_part->length);
- key_part->field->sort_string((char*)rec_buff, key_part->length);
- pos = (unsigned char *)rec_buff;
- break;
-
- case GEM_TINYBLOB:
- case GEM_BLOB:
- case GEM_MEDIUMBLOB:
- case GEM_LONGBLOB:
- ((Field_blob*)key_part->field)->get_ptr((char**)&pos);
- key_part_length = ((Field_blob*)key_part->field)->get_length(
- (char*)key_ptr + offset);
- break;
-
- default:
- pos = (unsigned char *)key_ptr + offset;
- break;
- }
-
- rc = gemFieldToIdxComponent(
- pos,
- (unsigned long) key_part_length,
- fieldType,
- 0 ,
- key_part->field->flags & UNSIGNED_FLAG,
- pkey->keystr + pkey->keyLen,
- keyBufSize,
- &componentLen);
-
- key_ptr+=key_part->store_length;
- key_length-=key_part->store_length;
- pkey->keyLen += componentLen;
- }
- DBUG_RETURN(rc);
-}
-
-void ha_gemini::unpack_key(char *record, dsmKey_t *key, uint index)
-{
- KEY *key_info=table->key_info+index;
- KEY_PART_INFO *key_part= key_info->key_part,
- *end=key_part+key_info->key_parts;
- int fieldIsNull, fieldType;
- int rc = 0;
-
- char unsigned *pos= &key->keystr[FULLKEYHDRSZ+4/* 4 for the index number*/];
-
- for ( ; key_part != end; key_part++)
- {
- fieldType = gemDataType(key_part->field->type());
- if(fieldType == GEM_CHAR)
- {
- /* Can't get data from character indexes since the sort weights
- are in the index and not the characters. */
- key_read = 0;
- }
- rc = gemIdxComponentToField(pos, fieldType,
- (unsigned char *)record + key_part->field->offset(),
- //key_part->field->field_length,
- key_part->length,
- key_part->field->decimals(),
- &fieldIsNull);
- if(fieldIsNull)
- {
- record[key_part->null_offset] |= key_part->null_bit;
- }
- else if (key_part->null_bit)
- {
- record[key_part->null_offset]&= ~key_part->null_bit;
- }
- while(*pos++); /* Advance to next field in key by finding */
- /* a null byte */
- }
-}
-
-int ha_gemini::index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)
-{
- int error = 0;
- THD *thd;
- int componentLen;
-
- DBUG_ENTER("index_read");
- statistic_increment(ha_read_key_count,&LOCK_status);
-
-
- pbracketBase->index = (short)pindexNumbers[active_index];
- pbracketBase->keycomps = 1;
-
-
- /* Its a greater than operation so create a base bracket
- from the input key data. */
- error = pack_key(active_index, pbracketBase, key, key_len);
- if(error)
- goto errorReturn;
-
- if(find_flag == HA_READ_AFTER_KEY)
- {
- /* A greater than operation */
- error = gemKeyAddLow(pbracketBase->keystr + pbracketBase->keyLen,
- &componentLen);
- pbracketBase->keyLen += componentLen;
- }
- if(find_flag == HA_READ_KEY_EXACT)
- {
- /* Need to set up a high bracket for an equality operator
- Which is a copy of the base bracket plus a hi lim term */
- bmove(pbracketLimit,pbracketBase,(size_t)pbracketBase->keyLen + sizeof(dsmKey_t));
- error = gemKeyAddHigh(pbracketLimit->keystr + pbracketLimit->keyLen,
- &componentLen);
- if(error)
- goto errorReturn;
- pbracketLimit->keyLen += componentLen;
- }
- else
- {
- /* Always add a high range -- except for HA_READ_KEY_EXACT this
- is all we need for the upper index bracket */
- error = gemKeyHigh(pbracketLimit->keystr, &componentLen,
- pbracketLimit->index);
-
- pbracketLimit->keyLen = componentLen;
- }
- /* We have to subtract the header size here since cxKeyPrepare
- expects that the three lead bytes of the header are
- not counted in this length -- But cxKeyPrepare also
- expects that these three bytes are present in the keystr */
- pbracketBase->keyLen -= FULLKEYHDRSZ;
- pbracketLimit->keyLen -= FULLKEYHDRSZ;
-
- thd = current_thd;
-
- error = findRow(thd, DSMFINDFIRST, buf);
-
-errorReturn:
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_KEY_NOT_FOUND;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::index_next(byte * buf)
-{
- THD *thd;
- int error = 1;
- int keyStringLen=0;
- dsmMask_t findMode;
- DBUG_ENTER("index_next");
-
- if(tableStatus == HA_ERR_CRASHED)
- DBUG_RETURN(tableStatus);
-
- thd = current_thd;
-
- if(pbracketBase->index == 0)
- {
- error = gemKeyLow(pbracketBase->keystr, &keyStringLen,
- pbracketLimit->index);
-
- pbracketBase->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
- pbracketBase->index = pbracketLimit->index;
- error = gemKeyHigh(pbracketLimit->keystr, &keyStringLen,
- pbracketLimit->index);
- pbracketLimit->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
-
- findMode = DSMFINDFIRST;
- }
- else
- findMode = DSMFINDNEXT;
-
- error = findRow(thd,findMode,buf);
-
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-int ha_gemini::index_next_same(byte * buf, const byte *key, uint keylen)
-{
- int error = 0;
- DBUG_ENTER("index_next_same");
- statistic_increment(ha_read_next_count,&LOCK_status);
- DBUG_RETURN(index_next(buf));
-}
-
-
-int ha_gemini::index_prev(byte * buf)
-{
- int error = 0;
- THD *thd = current_thd;
-
- DBUG_ENTER("index_prev");
- statistic_increment(ha_read_prev_count,&LOCK_status);
-
- error = findRow(thd, DSMFINDPREV, buf);
-
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
-
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::index_first(byte * buf)
-{
- DBUG_ENTER("index_first");
- statistic_increment(ha_read_first_count,&LOCK_status);
- DBUG_RETURN(index_next(buf));
-}
-
-int ha_gemini::index_last(byte * buf)
-{
- int error = 0;
- THD *thd;
- int keyStringLen;
- dsmMask_t findMode;
- thd = current_thd;
-
- DBUG_ENTER("index_last");
- statistic_increment(ha_read_last_count,&LOCK_status);
-
- error = gemKeyLow(pbracketBase->keystr, &keyStringLen,
- pbracketLimit->index);
-
- pbracketBase->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
- pbracketBase->index = pbracketLimit->index;
- error = gemKeyHigh(pbracketLimit->keystr, &keyStringLen,
- pbracketLimit->index);
- pbracketLimit->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
-
- error = findRow(thd,DSMFINDLAST,buf);
-
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-int ha_gemini::rnd_init(bool scan)
-{
- THD *thd = current_thd;
-
- lastRowid = 0;
-
- return 0;
-}
-
-int ha_gemini::rnd_end()
-{
-/*
- return gem_scan_end();
-*/
- return 0;
-}
-
-int ha_gemini::rnd_next(byte *buf)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- THD *thd;
-
- DBUG_ENTER("rnd_next");
-
- if(tableStatus == HA_ERR_CRASHED)
- DBUG_RETURN(tableStatus);
-
- thd = current_thd;
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL)
- && lastRowid)
- error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- tableNumber, DSMOBJECT_RECORD, lastRowid,
- lockMode | DSM_UNLK_FREE, 0);
-
- statistic_increment(ha_read_rnd_next_count,&LOCK_status);
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
- dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff;
- dsmRecord.recLength = table->reclength;
- dsmRecord.maxLength = table->rec_buff_length;
-
- error = dsmTableScan((dsmContext_t *)thd->gemini.context,
- &dsmRecord, DSMFINDNEXT, lockMode, 0);
-
- if(!error)
- {
- lastRowid = dsmRecord.recid;
- error = unpack_row((char *)buf,(char *)dsmRecord.pbuffer);
- }
- if(!error)
- ;
- else
- {
- lastRowid = 0;
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
- else if (error == DSM_S_RQSTREJ)
- error = HA_ERR_LOCK_WAIT_TIMEOUT;
- else if (error == DSM_S_LKTBFULL)
- {
- error = HA_ERR_LOCK_TABLE_FULL;
- gemini_lock_table_overflow_error((dsmContext_t *)thd->gemini.context);
- }
- }
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::rnd_pos(byte * buf, byte *pos)
-{
- int error;
- int rc;
-
- THD *thd;
-
- statistic_increment(ha_read_rnd_count,&LOCK_status);
- thd = current_thd;
- memcpy((void *)&lastRowid,pos,ref_length);
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL))
- {
- /* Lock the row */
-
- error = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,DSMOBJECT_RECORD,lastRowid,
- lockMode, 1, 0);
- if ( error )
- goto errorReturn;
- }
- error = fetch_row(thd->gemini.context, buf);
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL))
- {
- /* Unlock the row */
-
- rc = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,DSMOBJECT_RECORD,lastRowid,
- lockMode | DSM_UNLK_FREE , 0);
- }
- if(error == DSM_S_RMNOTFND)
- error = HA_ERR_RECORD_DELETED;
-
- errorReturn:
- table->status = error ? STATUS_NOT_FOUND : 0;
- return error;
-}
-
-int ha_gemini::fetch_row(void *gemini_context,const byte *buf)
-{
- dsmStatus_t rc = 0;
- dsmRecord_t dsmRecord;
-
- DBUG_ENTER("fetch_row");
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
- dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff;
- dsmRecord.recLength = table->reclength;
- dsmRecord.maxLength = table->rec_buff_length;
-
- rc = dsmRecordGet((dsmContext_t *)gemini_context,
- &dsmRecord, 0);
-
- if(!rc)
- {
- rc = unpack_row((char *)buf,(char *)dsmRecord.pbuffer);
- }
-
- DBUG_RETURN(rc);
-}
-int ha_gemini::findRow(THD *thd, dsmMask_t findMode, byte *buf)
-{
- dsmStatus_t rc;
- dsmKey_t *pkey;
-
- DBUG_ENTER("findRow");
-
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL)
- && lastRowid)
- rc = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- tableNumber, DSMOBJECT_RECORD, lastRowid,
- lockMode | DSM_UNLK_FREE, 0);
- if( key_read )
- pkey = pfoundKey;
- else
- pkey = 0;
-
- rc = dsmCursorFind((dsmContext_t *)thd->gemini.context,
- &cursorId,
- pbracketBase,
- pbracketLimit,
- DSMPARTIAL,
- findMode,
- lockMode,
- NULL,
- &lastRowid,
- pkey);
- if( rc )
- goto errorReturn;
-
- if(key_read)
- {
- unpack_key((char*)buf, pkey, active_index);
- }
- if(!key_read) /* unpack_key may have turned off key_read */
- {
- rc = fetch_row((dsmContext_t *)thd->gemini.context,buf);
- }
-
-errorReturn:
- if(!rc)
- ;
- else
- {
- lastRowid = 0;
- if(rc == DSM_S_RQSTREJ)
- rc = HA_ERR_LOCK_WAIT_TIMEOUT;
- else if (rc == DSM_S_LKTBFULL)
- {
- rc = HA_ERR_LOCK_TABLE_FULL;
- gemini_lock_table_overflow_error((dsmContext_t *)thd->gemini.context);
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-void ha_gemini::position(const byte *record)
-{
- memcpy(ref,&lastRowid,ref_length);
-}
-
-
-void ha_gemini::info(uint flag)
-{
- DBUG_ENTER("info");
-
- if ((flag & HA_STATUS_VARIABLE))
- {
- THD *thd = current_thd;
- dsmStatus_t error;
- ULONG64 rows;
-
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- error = gemini_connect(thd);
- if(error)
- DBUG_VOID_RETURN;
- }
-
- error = dsmRowCount((dsmContext_t *)thd->gemini.context,tableNumber,&rows);
- records = (ha_rows)rows;
- deleted = 0;
- }
- if ((flag & HA_STATUS_CONST))
- {
- ha_rows *rec_per_key = share->rec_per_key;
- for (uint i = 0; i < table->keys; i++)
- for(uint k=0;
- k < table->key_info[i].key_parts; k++,rec_per_key++)
- table->key_info[i].rec_per_key[k] = *rec_per_key;
- }
- if ((flag & HA_STATUS_ERRKEY))
- {
- errkey=last_dup_key;
- }
- if ((flag & HA_STATUS_TIME))
- {
- ;
- }
- if ((flag & HA_STATUS_AUTO))
- {
- THD *thd = current_thd;
- dsmStatus_t error;
-
- error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context,
- tableNumber,
- (ULONG64 *)&auto_increment_value,
- 0);
- /* Should return the next auto-increment value that
- will be given -- so we need to increment the one dsm
- currently reports. */
- auto_increment_value++;
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-int ha_gemini::extra(enum ha_extra_function operation)
-{
- switch (operation)
- {
- case HA_EXTRA_RESET:
- case HA_EXTRA_RESET_STATE:
- key_read=0;
- using_ignore=0;
- break;
- case HA_EXTRA_KEYREAD:
- key_read=1; // Query satisfied with key
- break;
- case HA_EXTRA_NO_KEYREAD:
- key_read=0;
- break;
- case HA_EXTRA_IGNORE_DUP_KEY:
- using_ignore=1;
- break;
- case HA_EXTRA_NO_IGNORE_DUP_KEY:
- using_ignore=0;
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-
-int ha_gemini::reset(void)
-{
- key_read=0; // Reset to state after open
- return 0;
-}
-
-
-/*
- As MySQL will execute an external lock for every new table it uses
- we can use this to start the transactions.
-*/
-
-int ha_gemini::external_lock(THD *thd, int lock_type)
-{
- dsmStatus_t rc = 0;
- LONG txNumber;
-
- DBUG_ENTER("ha_gemini::external_lock");
-
- if (lock_type != F_UNLCK)
- {
- if (!thd->gemini.lock_count)
- {
- thd->gemini.lock_count = 1;
- thd->gemini.tx_isolation = thd->tx_isolation;
- }
- // lockMode has already been set in store_lock
- // If the statement about to be executed calls for
- // exclusive locks and we're running at read uncommitted
- // isolation level then raise an error.
- if(thd->gemini.tx_isolation == ISO_READ_UNCOMMITTED)
- {
- if(lockMode == DSM_LK_EXCL)
- {
- DBUG_RETURN(HA_ERR_READ_ONLY_TRANSACTION);
- }
- else
- {
- lockMode = DSM_LK_NOLOCK;
- }
- }
-
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- return rc;
- }
- /* Set need savepoint flag */
- thd->gemini.needSavepoint = 1;
-
- if(rc)
- DBUG_RETURN(rc);
-
-
- if( thd->in_lock_tables || thd->gemini.tx_isolation == ISO_SERIALIZABLE )
- {
- rc = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,DSMOBJECT_TABLE,0,
- lockMode, 1, 0);
- if(rc == DSM_S_RQSTREJ)
- rc = HA_ERR_LOCK_WAIT_TIMEOUT;
- }
- }
- else /* lock_type == F_UNLK */
- {
- /* Commit the tx if we're in auto-commit mode */
- if (!(thd->options & OPTION_NOT_AUTO_COMMIT)&&
- !(thd->options & OPTION_BEGIN))
- gemini_commit(thd);
- }
-
- DBUG_RETURN(rc);
-}
-
-
-THR_LOCK_DATA **ha_gemini::store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type)
-{
- if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
- {
- /* If we are not doing a LOCK TABLE, then allow multiple writers */
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) &&
- !thd->in_lock_tables)
- lock_type = TL_WRITE_ALLOW_WRITE;
- lock.type=lock_type;
- }
- if(table->reginfo.lock_type > TL_WRITE_ALLOW_READ)
- lockMode = DSM_LK_EXCL;
- else
- lockMode = DSM_LK_SHARE;
-
- *to++= &lock;
- return to;
-}
-
-void ha_gemini::update_create_info(HA_CREATE_INFO *create_info)
-{
- table->file->info(HA_STATUS_AUTO | HA_STATUS_CONST);
- if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
- {
- create_info->auto_increment_value=auto_increment_value;
- }
-}
-
-int ha_gemini::create(const char *name, register TABLE *form,
- HA_CREATE_INFO *create_info)
-{
- THD *thd;
- char name_buff[FN_REFLEN];
- char dbname_buff[FN_REFLEN];
- DBUG_ENTER("ha_gemini::create");
- dsmContext_t *pcontext;
- dsmStatus_t rc;
- dsmArea_t areaNumber;
- dsmObject_t tableNumber = 0;
- dsmDbkey_t dummy = 0;
- unsigned i;
- int baseNameLen;
- dsmObject_t indexNumber;
-
- /* separate out the name of the table and the database (a VST must be
- ** created in the mysql database)
- */
- rc = gemini_parse_table_name(name, dbname_buff, name_buff);
- if (rc == 0)
- {
- /* If the table is a VST, don't create areas or extents */
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- tableNumber = gemini_is_vst(name_buff);
- if (tableNumber)
- {
- return 0;
- }
- }
- }
-
- thd = current_thd;
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- return rc;
- }
- pcontext = (dsmContext_t *)thd->gemini.context;
-
- if(thd->gemini.needSavepoint || using_ignore)
- {
- thd->gemini.savepoint++;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (rc)
- DBUG_RETURN(rc);
- thd->gemini.needSavepoint = 0;
- }
-
- fn_format(name_buff, name, "", ha_gemini_ext, 2 | 4);
- /* Create a storage area */
- rc = dsmAreaNew(pcontext,gemini_blocksize,DSMAREA_TYPE_DATA,
- &areaNumber, gemini_recbits,
- (dsmText_t *)"gemini_data_area");
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmAreaNew failed %l",rc);
- return(rc);
- }
-
- /* Create an extent */
- /* Don't pass in leading ./ in name_buff */
- rc = dsmExtentCreate(pcontext,areaNumber,1,15,5,
- (dsmText_t *)&name_buff[start_of_name]);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmExtentCreate failed %l",rc);
- return(rc);
- }
-
- /* Create the table storage object */
- /* Change slashes in the name to periods */
- for( i = 0; i < strlen(name_buff); i++)
- if(name_buff[i] == '/' || name_buff[i] == '\\')
- name_buff[i] = '.';
-
- /* Get rid of .gmd suffix */
- name_buff[strlen(name_buff) - 4] = '\0';
-
- rc = dsmObjectCreate(pcontext, areaNumber, &tableNumber,
- DSMOBJECT_MIXTABLE,0,0,0,
- (dsmText_t *)&name_buff[start_of_name],
- &dummy,&dummy);
-
- if (rc == 0 && table->blob_fields)
- {
- /* create a storage object record for blob fields */
- rc = dsmObjectCreate(pcontext, areaNumber, &tableNumber,
- DSMOBJECT_BLOB,0,0,0,
- (dsmText_t *)&name_buff[start_of_name],
- &dummy,&dummy);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmObjectCreate for blob object failed %l",rc);
- return(rc);
- }
- }
-
- if(rc == 0 && form->keys)
- {
- fn_format(name_buff, name, "", ha_gemini_idx_ext, 2 | 4);
- /* Create a storage area */
- rc = dsmAreaNew(pcontext,gemini_blocksize,DSMAREA_TYPE_DATA,
- &areaNumber, gemini_recbits,
- (dsmText_t *)"gemini_index_area");
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmAreaNew failed %l",rc);
- return(rc);
- }
- /* Create an extent */
- /* Don't pass in leading ./ in name_buff */
- rc = dsmExtentCreate(pcontext,areaNumber,1,15,5,
- (dsmText_t *)&name_buff[start_of_name]);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmExtentCreate failed %l",rc);
- return(rc);
- }
-
- /* Change slashes in the name to periods */
- for( i = 0; i < strlen(name_buff); i++)
- if(name_buff[i] == '/' || name_buff[i] == '\\')
- name_buff[i] = '.';
-
- /* Get rid of .gmi suffix */
- name_buff[strlen(name_buff) - 4] = '\0';
-
- baseNameLen = strlen(name_buff);
- name_buff[baseNameLen] = '.';
- baseNameLen++;
- for( i = 0; i < form->keys; i++)
- {
- dsmObjectAttr_t indexUnique;
-
- indexNumber = DSMINDEX_INVALID;
- /* Create a storage object record for each index */
- /* Add the index name so the object name is in the form
- <db>.<table>.<index_name> */
- strcpy(&name_buff[baseNameLen],table->key_info[i].name);
- if(table->key_info[i].flags & HA_NOSAME)
- indexUnique = 1;
- else
- indexUnique = 0;
- rc = dsmObjectCreate(pcontext, areaNumber, &indexNumber,
- DSMOBJECT_MIXINDEX,indexUnique,tableNumber,
- DSMOBJECT_MIXTABLE,
- (dsmText_t *)&name_buff[start_of_name],
- &dummy,&dummy);
-
- }
- }
- /* The auto_increment value is the next one to be given
- out so give dsm one less than this value */
- if(create_info->auto_increment_value)
- rc = dsmTableAutoIncrementSet(pcontext,tableNumber,
- create_info->auto_increment_value-1);
-
- /* Get a table lock on this table in case this table is being
- created as part of an alter table statement. We don't want
- the alter table statement to abort because of a lock table overflow
- */
- if (thd->lex.sql_command == SQLCOM_CREATE_INDEX ||
- thd->lex.sql_command == SQLCOM_ALTER_TABLE ||
- thd->lex.sql_command == SQLCOM_DROP_INDEX)
- {
- rc = dsmObjectLock(pcontext,
- (dsmObject_t)tableNumber,DSMOBJECT_TABLE,0,
- DSM_LK_EXCL, 1, 0);
- /* and don't commit so we won't release the table on the table number
- of the table being altered */
- }
- else
- {
- if(!rc)
- rc = gemini_commit(thd);
- }
-
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::delete_table(const char *pname)
-{
- THD *thd;
- dsmStatus_t rc;
- dsmContext_t *pcontext;
- unsigned i,nameLen;
- dsmArea_t indexArea = 0;
- dsmArea_t tableArea = 0;
- dsmObjectAttr_t objectAttr;
- dsmObject_t associate;
- dsmObjectType_t associateType;
- dsmDbkey_t block, root;
- int need_txn = 0;
- dsmObject_t tableNum = 0;
- char name_buff[FN_REFLEN];
- char dbname_buff[FN_REFLEN];
- DBUG_ENTER("ha_gemini::delete_table");
-
- /* separate out the name of the table and the database (a VST must be
- ** located in the mysql database)
- */
- rc = gemini_parse_table_name(pname, dbname_buff, name_buff);
- if (rc == 0)
- {
- /* If the table is a VST, there are no areas or extents to delete */
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- tableNum = gemini_is_vst(name_buff);
- if (tableNum)
- {
- return 0;
- }
- }
- }
-
- thd = current_thd;
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- {
- DBUG_RETURN(rc);
- }
- }
- pcontext = (dsmContext_t *)thd->gemini.context;
-
-
- bzero(name_buff, FN_REFLEN);
-
- nameLen = strlen(pname);
- for( i = start_of_name; i < nameLen; i++)
- {
- if(pname[i] == '/' || pname[i] == '\\')
- name_buff[i-start_of_name] = '.';
- else
- name_buff[i-start_of_name] = pname[i];
- }
-
- rc = dsmObjectNameToNum(pcontext, (dsmText_t *)name_buff,
- (dsmObject_t *)&tableNum);
- if (rc)
- {
- gemini_msg(pcontext, "Unable to find table number for %s", name_buff);
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
-
- rc = dsmObjectInfo(pcontext, tableNum, DSMOBJECT_MIXTABLE, tableNum,
- &tableArea, &objectAttr, &associateType, &block, &root);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to get area number for table %d, %s, return %l",
- tableNum, pname, rc);
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- }
-
- indexArea = DSMAREA_INVALID;
-
- /* Delete the indexes and tables storage objects for with the table */
- rc = dsmObjectDeleteAssociate(pcontext, tableNum, &indexArea);
- if (rc)
- {
- gemini_msg(pcontext, "Error deleting storage objects for table number %d, return %l",
- (int)tableNum, rc);
-
- /* roll back txn and return */
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
-
- if (indexArea != DSMAREA_INVALID)
- {
- /* Delete the extents for both Index and Table */
- rc = dsmExtentDelete(pcontext, indexArea);
- rc = dsmAreaDelete(pcontext, indexArea);
- if (rc)
- {
- gemini_msg(pcontext, "Error deleting Index Area %l, return %l", indexArea, rc);
-
- /* roll back txn and return */
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
- }
-
- rc = dsmExtentDelete(pcontext, tableArea);
- rc = dsmAreaDelete(pcontext, tableArea);
- if (rc)
- {
- gemini_msg(pcontext, "Error deleting table Area %l, name %s, return %l",
- tableArea, pname, rc);
- /* roll back txn and return */
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
-
-
- /* Commit the transaction */
- rc = gemini_commit(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to commit transaction %l",rc);
- }
-
-
- /* now remove all the files that need to be removed and
- cause a checkpoint so recovery will work */
- rc = dsmExtentUnlink(pcontext);
-
- DBUG_RETURN(0);
-}
-
-
-int ha_gemini::rename_table(const char *pfrom, const char *pto)
-{
- THD *thd;
- dsmContext_t *pcontext;
- dsmStatus_t rc;
- char dbname_buff[FN_REFLEN];
- char name_buff[FN_REFLEN];
- char newname_buff[FN_REFLEN];
- char newextname_buff[FN_REFLEN];
- char newidxextname_buff[FN_REFLEN];
- unsigned i, nameLen;
- dsmObject_t tableNum;
- dsmArea_t indexArea = 0;
- dsmArea_t tableArea = 0;
-
- DBUG_ENTER("ha_gemini::rename_table");
-
- /* don't allow rename of VSTs */
- rc = gemini_parse_table_name(pfrom, dbname_buff, name_buff);
- if (rc == 0)
- {
- /* If the table is a VST, don't create areas or extents */
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- if (gemini_is_vst(name_buff))
- {
- return DSM_S_CANT_RENAME_VST;
- }
- }
- }
-
- thd = current_thd;
- if (thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if (rc)
- {
- DBUG_RETURN(rc);
- }
- }
-
- pcontext = (dsmContext_t *)thd->gemini.context;
-
- /* change the slashes to dots in the old and new names */
- nameLen = strlen(pfrom);
- for( i = start_of_name; i < nameLen; i++)
- {
- if(pfrom[i] == '/' || pfrom[i] == '\\')
- name_buff[i-start_of_name] = '.';
- else
- name_buff[i-start_of_name] = pfrom[i];
- }
- name_buff[i-start_of_name] = '\0';
-
- nameLen = strlen(pto);
- for( i = start_of_name; i < nameLen; i++)
- {
- if(pto[i] == '/' || pto[i] == '\\')
- newname_buff[i-start_of_name] = '.';
- else
- newname_buff[i-start_of_name] = pto[i];
- }
- newname_buff[i-start_of_name] = '\0';
-
- /* generate new extent names (for table and index extents) */
- fn_format(newextname_buff, pto, "", ha_gemini_ext, 2 | 4);
- fn_format(newidxextname_buff, pto, "", ha_gemini_idx_ext, 2 | 4);
-
- rc = dsmObjectNameToNum(pcontext, (dsmText_t *)name_buff, &tableNum);
- if (rc)
- {
- gemini_msg(pcontext, "Unable to file Table number for %s", name_buff);
- goto errorReturn;
- }
-
- rc = dsmObjectRename(pcontext, tableNum,
- (dsmText_t *)newname_buff,
- (dsmText_t *)&newidxextname_buff[start_of_name],
- (dsmText_t *)&newextname_buff[start_of_name],
- &indexArea, &tableArea);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to rename %s to %s",name_buff,newname_buff);
- goto errorReturn;
- }
-
- /* Rename the physical table and index files (if necessary).
- ** Close the file, rename it, and reopen it (have to do it this
- ** way so rename works on Windows).
- */
- if (!(rc = dsmAreaClose(pcontext, tableArea)))
- {
- if (!(rc = rename_file_ext(pfrom, pto, ha_gemini_ext)))
- {
- rc = dsmAreaOpen(pcontext, tableArea, 0);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to reopen area %d",tableArea);
- }
- }
- }
-
- if (!rc && indexArea)
- {
- if (!(rc = dsmAreaClose(pcontext, indexArea)))
- {
- if (!(rc = rename_file_ext(pfrom, pto, ha_gemini_idx_ext)))
- {
- rc = dsmAreaOpen(pcontext, indexArea, 0);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to reopen area %d",tableArea);
- }
- }
- }
- }
-
-errorReturn:
- DBUG_RETURN(rc);
-}
-
-
-/*
- How many seeks it will take to read through the table
- This is to be comparable to the number returned by records_in_range so
- that we can decide if we should scan the table or use keys.
-*/
-
-double ha_gemini::scan_time()
-{
- return (double)records /
- (double)((gemini_blocksize / (double)table->reclength));
-}
-
-int ha_gemini::analyze(THD* thd, HA_CHECK_OPT* check_opt)
-{
- int error;
- uint saveIsolation;
- dsmMask_t saveLockMode;
-
- check_opt->quick = TRUE;
- check_opt->optimize = TRUE; // Tells check not to get table lock
- saveLockMode = lockMode;
- saveIsolation = thd->gemini.tx_isolation;
- thd->gemini.tx_isolation = ISO_READ_UNCOMMITTED;
- lockMode = DSM_LK_NOLOCK;
- error = check(thd,check_opt);
- lockMode = saveLockMode;
- thd->gemini.tx_isolation = saveIsolation;
- return (error);
-}
-
-int ha_gemini::check(THD* thd, HA_CHECK_OPT* check_opt)
-{
- int error = 0;
- int checkStatus = HA_ADMIN_OK;
- ha_rows indexCount;
- byte *buf = 0, *indexBuf = 0, *prevBuf = 0;
- int errorCount = 0;
-
- info(HA_STATUS_VARIABLE); // Makes sure row count is up to date
-
- /* Get a shared table lock */
- if(thd->gemini.needSavepoint)
- {
- /* We don't really need a savepoint here but do it anyway
- just to keep the savepoint number correct. */
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- return(error);
- thd->gemini.needSavepoint = 0;
- }
- buf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME));
- indexBuf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME));
- prevBuf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME |MY_ZEROFILL ));
-
- /* Lock the table */
- if (!check_opt->optimize)
- error = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_SHARE, 1, 0);
- if(error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Failed to lock table %d, error %d",tableNumber, error);
- return error;
- }
-
- ha_rows *rec_per_key = share->rec_per_key;
- /* If quick option just scan along index converting and counting entries */
- for (uint i = 0; i < table->keys; i++)
- {
- key_read = 1; // Causes data to be extracted from the keys
- indexCount = 0;
- // Clear the cardinality stats for this index
- memset(table->key_info[i].rec_per_key,0,
- sizeof(table->key_info[0].rec_per_key[0]) *
- table->key_info[i].key_parts);
- error = index_init(i);
- error = index_first(indexBuf);
- while(!error)
- {
- indexCount++;
- if(!check_opt->quick)
- {
- /* Fetch row and compare to data produced from key */
- error = fetch_row(thd->gemini.context,buf);
- if(!error)
- {
- if(key_cmp(i,buf,indexBuf,FALSE))
- {
-
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Check Error! Key does not match row for rowid %d for index %s",
- lastRowid,table->key_info[i].name);
- print_msg(thd,table->real_name,"check","error",
- "Key does not match row for rowid %d for index %s",
- lastRowid,table->key_info[i].name);
- checkStatus = HA_ADMIN_CORRUPT;
- errorCount++;
- if(errorCount > 1000)
- goto error_return;
- }
- else if(error == DSM_S_RMNOTFND)
- {
- errorCount++;
- checkStatus = HA_ADMIN_CORRUPT;
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Check Error! Key does not have a valid row pointer %d for index %s",
- lastRowid,table->key_info[i].name);
- print_msg(thd,table->real_name,"check","error",
- "Key does not have a valid row pointer %d for index %s",
- lastRowid,table->key_info[i].name);
- if(errorCount > 1000)
- goto error_return;
- error = 0;
- }
- }
- }
-
- key_cmp(i,indexBuf,prevBuf,TRUE);
- bcopy((void *)indexBuf,(void *)prevBuf,table->rec_buff_length);
-
- if(!error)
- error = index_next(indexBuf);
- }
-
- for(uint j=1; j < table->key_info[i].key_parts; j++)
- {
- table->key_info[i].rec_per_key[j] += table->key_info[i].rec_per_key[j-1];
- }
- for(uint k=0; k < table->key_info[i].key_parts; k++)
- {
- if (table->key_info[i].rec_per_key[k])
- table->key_info[i].rec_per_key[k] =
- records / table->key_info[i].rec_per_key[k];
- *rec_per_key = table->key_info[i].rec_per_key[k];
- rec_per_key++;
- }
-
- if(error == HA_ERR_END_OF_FILE)
- {
- /* Check count of rows */
-
- if(records != indexCount)
- {
- /* Number of index entries does not agree with the number of
- rows in the index. */
- checkStatus = HA_ADMIN_CORRUPT;
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Check Error! Total rows %d does not match total index entries %d for %s",
- records, indexCount,
- table->key_info[i].name);
- print_msg(thd,table->real_name,"check","error",
- "Total rows %d does not match total index entries %d for %s",
- records, indexCount,
- table->key_info[i].name);
- }
- }
- else
- {
- checkStatus = HA_ADMIN_FAILED;
- goto error_return;
- }
- index_end();
- }
- if(!check_opt->quick)
- {
- /* Now scan the table and for each row generate the keys
- and find them in the index */
- error = fullCheck(thd, buf);
- if(error)
- checkStatus = error;
- }
- // Store the key distribution information
- error = saveKeyStats(thd);
-
-error_return:
- my_free((char*)buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*)indexBuf,MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*)prevBuf,MYF(MY_ALLOW_ZERO_PTR));
-
- index_end();
- key_read = 0;
- if(!check_opt->optimize)
- {
- error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_SHARE,0);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to unlock table %d", tableNumber);
- }
- }
-
- return checkStatus;
-}
-
-int ha_gemini::saveKeyStats(THD *thd)
-{
- dsmStatus_t rc = 0;
-
- /* Insert a row in the indexStats table for each column of
- each index of the table */
-
- for(uint i = 0; i < table->keys; i++)
- {
- for (uint j = 0; j < table->key_info[i].key_parts && !rc ;j++)
- {
- rc = dsmIndexStatsPut((dsmContext_t *)thd->gemini.context,
- tableNumber, pindexNumbers[i],
- j, (LONG64)table->key_info[i].rec_per_key[j]);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Failed to update index stats for table %d, index %d",
- tableNumber, pindexNumbers[i]);
- }
- }
- }
- return rc;
-}
-
-int ha_gemini::fullCheck(THD *thd,byte *buf)
-{
- int error;
- int errorCount = 0;
- int checkStatus = 0;
-
- lastRowid = 0;
-
- while(((error = rnd_next( buf)) != HA_ERR_END_OF_FILE) && errorCount <= 1000)
- {
- if(!error)
- {
- error = handleIndexEntries(buf,lastRowid,KEY_CHECK);
- if(error)
- {
- /* Error finding an index entry for a row. */
- print_msg(thd,table->real_name,"check","error",
- "Unable to find all index entries for row %d",
- lastRowid);
- errorCount++;
- checkStatus = HA_ADMIN_CORRUPT;
- error = 0;
- }
- }
- else
- {
- /* Error reading a row */
- print_msg(thd,table->real_name,"check","error",
- "Error reading row %d status = %d",
- lastRowid,error);
- errorCount++;
- checkStatus = HA_ADMIN_CORRUPT;
- error = 0;
- }
- }
-
- return checkStatus;
-}
-
-int ha_gemini::repair(THD* thd, HA_CHECK_OPT* check_opt)
-{
- int error;
- dsmRecord_t dsmRecord;
- byte *buf;
-
- if(thd->gemini.needSavepoint)
- {
- /* We don't really need a savepoint here but do it anyway
- just to keep the savepoint number correct. */
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Error setting savepoint number %d, error %d",
- thd->gemini.savepoint++, error);
- return(error);
- }
- thd->gemini.needSavepoint = 0;
- }
-
-
- /* Lock the table */
- error = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_EXCL, 1, 0);
- if(error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Failed to lock table %d, error %d",tableNumber, error);
- return error;
- }
-
- error = dsmContextSetLong((dsmContext_t *)thd->gemini.context,
- DSM_TAGCONTEXT_NO_LOGGING,1);
-
- error = dsmTableReset((dsmContext_t *)thd->gemini.context,
- (dsmTable_t)tableNumber, table->keys,
- pindexNumbers);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "dsmTableReset failed for table %d, error %d",tableNumber, error);
- }
-
- buf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME));
- dsmRecord.table = tableNumber;
- dsmRecord.recid = 0;
- dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff;
- dsmRecord.recLength = table->reclength;
- dsmRecord.maxLength = table->rec_buff_length;
- while(!error)
- {
- error = dsmTableScan((dsmContext_t *)thd->gemini.context,
- &dsmRecord, DSMFINDNEXT, DSM_LK_NOLOCK,
- 1);
- if(!error)
- {
- if (!(error = unpack_row((char *)buf,(char *)dsmRecord.pbuffer)))
- {
- error = handleIndexEntries(buf,dsmRecord.recid,KEY_CREATE);
- if(error == HA_ERR_FOUND_DUPP_KEY)
- {
- /* We don't want to stop on duplicate keys -- we're repairing
- here so let's get as much repaired as possible. */
- error = 0;
- }
- }
- }
- }
- error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_EXCL,0);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to unlock table %d", tableNumber);
- }
-
- my_free((char*)buf,MYF(MY_ALLOW_ZERO_PTR));
-
- error = dsmContextSetLong((dsmContext_t *)thd->gemini.context,
- DSM_TAGCONTEXT_NO_LOGGING,0);
-
- return error;
-}
-
-
-int ha_gemini::restore(THD* thd, HA_CHECK_OPT *check_opt)
-{
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- char* backup_dir = thd->lex.backup_dir;
- char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- char* table_name = table->real_name;
- int error = 0;
- int errornum;
- const char* errmsg = "";
- dsmArea_t tableArea = 0;
- dsmObjectAttr_t objectAttr;
- dsmObject_t associate;
- dsmObjectType_t associateType;
- dsmDbkey_t block, root;
- dsmStatus_t rc;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXTABLE, tableNumber,
- &tableArea, &objectAttr, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaFlush(pcontext, tableArea, FLUSH_BUFFERS | FLUSH_SYNC);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaClose(pcontext, tableArea);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaClose (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Restore the data file */
- if (!fn_format(src_path, table_name, backup_dir, ha_gemini_ext, 4 + 64))
- {
- return HA_ADMIN_INVALID;
- }
-
- if (my_copy(src_path, fn_format(dst_path, table->path, "",
- ha_gemini_ext, 4), MYF(MY_WME)))
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in my_copy (.gmd) (Error %d)";
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaFlush(pcontext, tableArea, FREE_BUFFERS);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaOpen(pcontext, tableArea, 1);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaOpen (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
-#ifdef GEMINI_BACKUP_IDX
- dsmArea_t indexArea = 0;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXINDEX, &indexArea,
- &objectAttr, &associate, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaClose(pcontext, indexArea);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaClose (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Restore the index file */
- if (!fn_format(src_path, table_name, backup_dir, ha_gemini_idx_ext, 4 + 64))
- {
- return HA_ADMIN_INVALID;
- }
-
- if (my_copy(src_path, fn_format(dst_path, table->path, "",
- ha_gemini_idx_ext, 4), MYF(MY_WME)))
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in my_copy (.gmi) (Error %d)";
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaOpen(pcontext, indexArea, 1);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaOpen (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- return HA_ADMIN_OK;
-#else /* #ifdef GEMINI_BACKUP_IDX */
- HA_CHECK_OPT tmp_check_opt;
- tmp_check_opt.init();
- /* The following aren't currently implemented in ha_gemini::repair
- ** tmp_check_opt.quick = 1;
- ** tmp_check_opt.flags |= T_VERY_SILENT;
- */
- return (repair(thd, &tmp_check_opt));
-#endif /* #ifdef GEMINI_BACKUP_IDX */
-
- err:
- {
-#if 0
- /* mi_check_print_error is in ha_myisam.cc, so none of the informative
- ** error messages above is currently being printed
- */
- MI_CHECK param;
- myisamchk_init(&param);
- param.thd = thd;
- param.op_name = (char*)"restore";
- param.table_name = table->table_name;
- param.testflag = 0;
- mi_check_print_error(&param,errmsg, errornum);
-#endif
- return error;
- }
-}
-
-
-int ha_gemini::backup(THD* thd, HA_CHECK_OPT *check_opt)
-{
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- char* backup_dir = thd->lex.backup_dir;
- char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- char* table_name = table->real_name;
- int error = 0;
- int errornum;
- const char* errmsg = "";
- dsmArea_t tableArea = 0;
- dsmObjectAttr_t objectAttr;
- dsmObject_t associate;
- dsmObjectType_t associateType;
- dsmDbkey_t block, root;
- dsmStatus_t rc;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXTABLE, tableNumber,
- &tableArea, &objectAttr, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmd) (Error %d)";
- errornum = rc;
- goto err;
- }
-
- /* Flush the buffers before backing up the table */
- dsmAreaFlush((dsmContext_t *)thd->gemini.context, tableArea,
- FLUSH_BUFFERS | FLUSH_SYNC);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Backup the .FRM file */
- if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .frm file: errno = %d";
- error = HA_ADMIN_INVALID;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )))
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed copying .frm file: errno = %d";
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Backup the data file */
- if (!fn_format(dst_path, table_name, backup_dir, ha_gemini_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .GMD file: errno = %d";
- error = HA_ADMIN_INVALID;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- if (my_copy(fn_format(src_path, table->path,"", ha_gemini_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
- {
- errmsg = "Failed copying .GMD file: errno = %d";
- error= HA_ADMIN_FAILED;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
-#ifdef GEMINI_BACKUP_IDX
- dsmArea_t indexArea = 0;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXINDEX, &indexArea,
- &objectAttr, &associate, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Backup the index file */
- if (!fn_format(dst_path, table_name, backup_dir, ha_gemini_idx_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .GMI file: errno = %d";
- error = HA_ADMIN_INVALID;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- if (my_copy(fn_format(src_path, table->path,"", ha_gemini_idx_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
- {
- errmsg = "Failed copying .GMI file: errno = %d";
- error= HA_ADMIN_FAILED;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-#endif /* #ifdef GEMINI_BACKUP_IDX */
-
- return HA_ADMIN_OK;
-
- err:
- {
-#if 0
- /* mi_check_print_error is in ha_myisam.cc, so none of the informative
- ** error messages above is currently being printed
- */
- MI_CHECK param;
- myisamchk_init(&param);
- param.thd = thd;
- param.op_name = (char*)"backup";
- param.table_name = table->table_name;
- param.testflag = 0;
- mi_check_print_error(&param,errmsg, errornum);
-#endif
- return error;
- }
-}
-
-
-int ha_gemini::optimize(THD* thd, HA_CHECK_OPT *check_opt)
-{
- return HA_ADMIN_ALREADY_DONE;
-}
-
-
-ha_rows ha_gemini::records_in_range(int keynr,
- const byte *start_key,uint start_key_len,
- enum ha_rkey_function start_search_flag,
- const byte *end_key,uint end_key_len,
- enum ha_rkey_function end_search_flag)
-{
- int error;
- int componentLen;
- float pctInrange;
- ha_rows rows = 5;
-
- DBUG_ENTER("records_in_range");
-
- error = index_init(keynr);
- if(error)
- DBUG_RETURN(rows);
-
- pbracketBase->index = (short)pindexNumbers[keynr];
- pbracketBase->keycomps = 1;
-
- if(start_key)
- {
- error = pack_key(keynr, pbracketBase, start_key, start_key_len);
- if(start_search_flag == HA_READ_AFTER_KEY)
- {
- /* A greater than operation */
- error = gemKeyAddLow(pbracketBase->keystr + pbracketBase->keyLen,
- &componentLen);
- pbracketBase->keyLen += componentLen;
- }
- }
- else
- {
- error = gemKeyLow(pbracketBase->keystr, &componentLen,
- pbracketBase->index);
- pbracketBase->keyLen = componentLen;
-
- }
- pbracketBase->keyLen -= FULLKEYHDRSZ;
-
- if(end_key)
- {
- error = pack_key(keynr, pbracketLimit, end_key, end_key_len);
- if(!error && end_search_flag == HA_READ_AFTER_KEY)
- {
- error = gemKeyAddHigh(pbracketLimit->keystr + pbracketLimit->keyLen,
- &componentLen);
- pbracketLimit->keyLen += componentLen;
- }
- }
- else
- {
- error = gemKeyHigh(pbracketLimit->keystr,&componentLen,
- pbracketLimit->index);
- pbracketLimit->keyLen = componentLen;
- }
-
- pbracketLimit->keyLen -= FULLKEYHDRSZ;
- error = dsmIndexRowsInRange((dsmContext_t *)current_thd->gemini.context,
- pbracketBase,pbracketLimit,
- tableNumber,
- &pctInrange);
- if(pctInrange >= 1)
- rows = (ha_rows)pctInrange;
- else
- {
- rows = (ha_rows)(records * pctInrange);
- if(!rows && pctInrange > 0)
- rows = 1;
- }
- index_end();
-
- DBUG_RETURN(rows);
-}
-
-
-/*
- Pack a row for storage. If the row is of fixed length, just store the
- row 'as is'.
- If not, we will generate a packed row suitable for storage.
- This will only fail if we don't have enough memory to pack the row, which;
- may only happen in rows with blobs, as the default row length is
- pre-allocated.
-*/
-int ha_gemini::pack_row(byte **pprow, int *ppackedLength, const byte *record,
- bool update)
-{
- THD *thd = current_thd;
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- gemBlobDesc_t *pBlobDesc = pBlobDescs;
-
- if (fixed_length_row)
- {
- *pprow = (byte *)record;
- *ppackedLength=(int)table->reclength;
- return 0;
- }
- /* Copy null bits */
- memcpy(rec_buff, record, table->null_bytes);
- byte *ptr=rec_buff + table->null_bytes;
-
- for (Field **field=table->field ; *field ; field++)
- {
-#ifdef GEMINI_TINYBLOB_IN_ROW
- /* Tiny blobs (255 bytes or less) are stored in the row; larger
- ** blobs are stored in a separate storage object (see ha_gemini::create).
- */
- if ((*field)->type() == FIELD_TYPE_BLOB &&
- ((Field_blob*)*field)->blobtype() != FIELD_TYPE_TINY_BLOB)
-#else
- if ((*field)->type() == FIELD_TYPE_BLOB)
-#endif
- {
- dsmBlob_t gemBlob;
- char *blobptr;
-
- gemBlob.areaType = DSMOBJECT_BLOB;
- gemBlob.blobObjNo = tableNumber;
- gemBlob.blobId = 0;
- gemBlob.totLength = gemBlob.segLength =
- ((Field_blob*)*field)->get_length((char*)record + (*field)->offset());
- ((Field_blob*)*field)->get_ptr((char**) &blobptr);
- gemBlob.pBuffer = (dsmBuffer_t *)blobptr;
- gemBlob.blobContext.blobOffset = 0;
- if (gemBlob.totLength)
- {
- dsmBlobStart(pcontext, &gemBlob);
- if (update && pBlobDesc->blobId)
- {
- gemBlob.blobId = pBlobDesc->blobId;
- dsmBlobUpdate(pcontext, &gemBlob, NULL);
- }
- else
- {
- dsmBlobPut(pcontext, &gemBlob, NULL);
- }
- dsmBlobEnd(pcontext, &gemBlob);
- }
- ptr = (byte*)((Field_blob*)*field)->pack_id((char*) ptr,
- (char*)record + (*field)->offset(), (longlong)gemBlob.blobId);
-
- pBlobDesc++;
- }
- else
- {
- ptr=(byte*) (*field)->pack((char*) ptr, (char*)record + (*field)->offset());
- }
- }
-
- *pprow=rec_buff;
- *ppackedLength= (ptr - rec_buff);
- return 0;
-}
-
-int ha_gemini::unpack_row(char *record, char *prow)
-{
- THD *thd = current_thd;
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- gemBlobDesc_t *pBlobDesc = pBlobDescs;
-
- if (fixed_length_row)
- {
- /* If the table is a VST, the row is in Gemini internal format.
- ** Convert the fields to MySQL format.
- */
- if (RM_IS_VST(tableNumber))
- {
- int i = 2; /* VST fields are numbered sequentially starting at 2 */
- long longValue;
- char *fld;
- unsigned long unknown;
-
- for (Field **field = table->field; *field; field++, i++)
- {
- switch ((*field)->type())
- {
- case FIELD_TYPE_LONG:
- case FIELD_TYPE_TINY:
- case FIELD_TYPE_SHORT:
- case FIELD_TYPE_TIMESTAMP:
- case FIELD_TYPE_LONGLONG:
- case FIELD_TYPE_INT24:
- case FIELD_TYPE_DATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_YEAR:
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_ENUM:
- case FIELD_TYPE_SET:
- recGetLONG((dsmText_t *)prow, i, 0, &longValue, &unknown);
- if (unknown)
- {
- (*field)->set_null();
- }
- else
- {
- (*field)->set_notnull();
- (*field)->store((longlong)longValue);
- }
- break;
-
- case FIELD_TYPE_DECIMAL:
- case FIELD_TYPE_DOUBLE:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_VAR_STRING:
- break;
-
- case FIELD_TYPE_STRING:
- svcByteString_t stringFld;
-
- fld = (char *)my_malloc((*field)->field_length, MYF(MY_WME));
- stringFld.pbyte = (TEXT *)fld;
- stringFld.size = (*field)->field_length;
- recGetBYTES((dsmText_t *)prow, i, 0, &stringFld, &unknown);
- if (unknown)
- {
- (*field)->set_null();
- }
- else
- {
- (*field)->set_notnull();
- (*field)->store(fld, (*field)->field_length);
- }
- my_free(fld, MYF(MY_ALLOW_ZERO_PTR));
- break;
-
- default:
- break;
- }
- }
- }
- else
- {
- memcpy(record,(char*) prow,table->reclength);
- }
- }
- else
- {
- /* Copy null bits */
- const char *ptr= (const char*) prow;
- memcpy(record, ptr, table->null_bytes);
- ptr+=table->null_bytes;
-
- for (Field **field=table->field ; *field ; field++)
- {
-#ifdef GEMINI_TINYBLOB_IN_ROW
- /* Tiny blobs (255 bytes or less) are stored in the row; larger
- ** blobs are stored in a separate storage object (see ha_gemini::create).
- */
- if ((*field)->type() == FIELD_TYPE_BLOB &&
- ((Field_blob*)*field)->blobtype() != FIELD_TYPE_TINY_BLOB)
-#else
- if ((*field)->type() == FIELD_TYPE_BLOB)
-#endif
- {
- dsmBlob_t gemBlob;
-
- gemBlob.areaType = DSMOBJECT_BLOB;
- gemBlob.blobObjNo = tableNumber;
- gemBlob.blobId = (dsmBlobId_t)(((Field_blob*)*field)->get_id(ptr));
- if (gemBlob.blobId)
- {
- gemBlob.totLength =
- gemBlob.segLength = ((Field_blob*)*field)->get_length(ptr);
- /* Allocate memory to store the blob. This memory is freed
- ** the next time unpack_row is called for this table.
- */
- gemBlob.pBuffer = (dsmBuffer_t *)my_malloc(gemBlob.totLength,
- MYF(0));
- if (!gemBlob.pBuffer)
- {
- return HA_ERR_OUT_OF_MEM;
- }
- gemBlob.blobContext.blobOffset = 0;
- dsmBlobStart(pcontext, &gemBlob);
- dsmBlobGet(pcontext, &gemBlob, NULL);
- dsmBlobEnd(pcontext, &gemBlob);
- }
- else
- {
- gemBlob.pBuffer = 0;
- }
- ptr = ((Field_blob*)*field)->unpack_id(record + (*field)->offset(),
- ptr, (char *)gemBlob.pBuffer);
- pBlobDesc->blobId = gemBlob.blobId;
- my_free((char*)pBlobDesc->pBlob, MYF(MY_ALLOW_ZERO_PTR));
- pBlobDesc->pBlob = gemBlob.pBuffer;
- pBlobDesc++;
- }
- else
- {
- ptr= (*field)->unpack(record + (*field)->offset(), ptr);
- }
- }
- }
-
- return 0;
-}
-
-int ha_gemini::key_cmp(uint keynr, const byte * old_row,
- const byte * new_row, bool updateStats)
-{
- KEY_PART_INFO *key_part=table->key_info[keynr].key_part;
- KEY_PART_INFO *end=key_part+table->key_info[keynr].key_parts;
-
- for ( uint i = 0 ; key_part != end ; key_part++, i++)
- {
- if (key_part->null_bit)
- {
- if ((old_row[key_part->null_offset] & key_part->null_bit) !=
- (new_row[key_part->null_offset] & key_part->null_bit))
- {
- if(updateStats)
- table->key_info[keynr].rec_per_key[i]++;
- return 1;
- }
- else if((old_row[key_part->null_offset] & key_part->null_bit) &&
- (new_row[key_part->null_offset] & key_part->null_bit))
- /* Both are null */
- continue;
- }
- if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH))
- {
- if (key_part->field->cmp_binary((char*)(old_row + key_part->offset),
- (char*)(new_row + key_part->offset),
- (ulong) key_part->length))
- {
- if(updateStats)
- table->key_info[keynr].rec_per_key[i]++;
- return 1;
- }
- }
- else
- {
- if (memcmp(old_row+key_part->offset, new_row+key_part->offset,
- key_part->length))
- {
- /* Check for special case of -0 which causes table check
- to find an invalid key when comparing the the index
- value of 0 to the -0 stored in the row */
- if(key_part->field->type() == FIELD_TYPE_DECIMAL)
- {
- double fieldValue;
- char *ptr = key_part->field->ptr;
-
- key_part->field->ptr = (char *)old_row + key_part->offset;
- fieldValue = key_part->field->val_real();
- if(fieldValue == 0)
- {
- key_part->field->ptr = (char *)new_row + key_part->offset;
- fieldValue = key_part->field->val_real();
- if(fieldValue == 0)
- {
- key_part->field->ptr = ptr;
- continue;
- }
- }
- key_part->field->ptr = ptr;
- }
- if(updateStats)
- {
- table->key_info[keynr].rec_per_key[i]++;
- }
- return 1;
- }
- }
- }
- return 0;
-}
-
-int gemini_parse_table_name(const char *fullname, char *dbname, char *tabname)
-{
- char *namestart;
- char *nameend;
-
- /* separate out the name of the table and the database
- */
- namestart = (char *)strchr(fullname + start_of_name, '/');
- if (!namestart)
- {
- /* if on Windows, slashes go the other way */
- namestart = (char *)strchr(fullname + start_of_name, '\\');
- }
- nameend = (char *)strchr(fullname + start_of_name, '.');
- /* sometimes fullname has an extension, sometimes it doesn't */
- if (!nameend)
- {
- nameend = (char *)fullname + strlen(fullname);
- }
- strncpy(dbname, fullname + start_of_name,
- (namestart - fullname) - start_of_name);
- dbname[(namestart - fullname) - start_of_name] = '\0';
- strncpy(tabname, namestart + 1, (nameend - namestart) - 1);
- tabname[nameend - namestart - 1] = '\0';
-
- return 0;
-}
-
-/* PROGRAM: gemini_is_vst - if the name is the name of a VST, return
- * its number
- *
- * RETURNS: Table number if a match is found
- * 0 if not a VST
- */
-int
-gemini_is_vst(const char *pname) /* IN the name */
-{
- int tablenum = 0;
-
- for (int i = 0; i < vstnumfils; i++)
- {
- if (strcmp(pname, vstfil[i].filename) == 0)
- {
- tablenum = vstfil[i].filnum;
- break;
- }
- }
-
- return tablenum;
-}
-
-static void print_msg(THD *thd, const char *table_name, const char *op_name,
- const char *msg_type, const char *fmt, ...)
-{
- String* packet = &thd->packet;
- packet->length(0);
- char msgbuf[256];
- msgbuf[0] = 0;
- va_list args;
- va_start(args,fmt);
-
- my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
- msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
-
- DBUG_PRINT(msg_type,("message: %s",msgbuf));
-
- net_store_data(packet, table_name);
- net_store_data(packet, op_name);
- net_store_data(packet, msg_type);
- net_store_data(packet, msgbuf);
- if (my_net_write(&thd->net, (char*)thd->packet.ptr(),
- thd->packet.length()))
- thd->killed=1;
-}
-
-/* Load shared area with rows per key statistics */
-void
-ha_gemini::get_index_stats(THD *thd)
-{
- dsmStatus_t rc = 0;
- ha_rows *rec_per_key = share->rec_per_key;
-
- for(uint i = 0; i < table->keys && !rc; i++)
- {
- for (uint j = 0; j < table->key_info[i].key_parts && !rc;j++)
- {
- LONG64 rows_per_key;
- rc = dsmIndexStatsGet((dsmContext_t *)thd->gemini.context,
- tableNumber, pindexNumbers[i],(int)j,
- &rows_per_key);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Index Statistics faild for table %d index %d, error %d",
- tableNumber, pindexNumbers[i], rc);
- }
- *rec_per_key = (ha_rows)rows_per_key;
- rec_per_key++;
- }
- }
- return;
-}
-
-/****************************************************************************
- Handling the shared GEM_SHARE structure that is needed to provide
- a global in memory storage location of the rec_per_key stats used
- by the optimizer.
-****************************************************************************/
-
-static byte* gem_get_key(GEM_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)))
-{
- *length=share->table_name_length;
- return (byte*) share->table_name;
-}
-
-static GEM_SHARE *get_share(const char *table_name, TABLE *table)
-{
- GEM_SHARE *share;
-
- pthread_mutex_lock(&gem_mutex);
- uint length=(uint) strlen(table_name);
- if (!(share=(GEM_SHARE*) hash_search(&gem_open_tables, (byte*) table_name,
- length)))
- {
- ha_rows *rec_per_key;
- char *tmp_name;
-
- if ((share=(GEM_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &share, sizeof(*share),
- &rec_per_key, table->key_parts * sizeof(ha_rows),
- &tmp_name, length+1,
- NullS)))
- {
- share->rec_per_key = rec_per_key;
- share->table_name = tmp_name;
- share->table_name_length=length;
- strcpy(share->table_name,table_name);
- if (hash_insert(&gem_open_tables, (byte*) share))
- {
- pthread_mutex_unlock(&gem_mutex);
- my_free((gptr) share,0);
- return 0;
- }
- thr_lock_init(&share->lock);
- pthread_mutex_init(&share->mutex,NULL);
- }
- }
- pthread_mutex_unlock(&gem_mutex);
- return share;
-}
-
-static int free_share(GEM_SHARE *share, bool mutex_is_locked)
-{
- pthread_mutex_lock(&gem_mutex);
- if (mutex_is_locked)
- pthread_mutex_unlock(&share->mutex);
- if (!--share->use_count)
- {
- hash_delete(&gem_open_tables, (byte*) share);
- thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
- my_free((gptr) share, MYF(0));
- }
- pthread_mutex_unlock(&gem_mutex);
- return 0;
-}
-
-static void gemini_lock_table_overflow_error(dsmContext_t *pcontext)
-{
- gemini_msg(pcontext, "The total number of locks exceeds the lock table size");
- gemini_msg(pcontext, "Either increase gemini_lock_table_size or use a");
- gemini_msg(pcontext, "different transaction isolation level");
-}
-
-#endif /* HAVE_GEMINI_DB */
diff --git a/sql/ha_gemini.h b/sql/ha_gemini.h
deleted file mode 100644
index 96c0cdd4241..00000000000
--- a/sql/ha_gemini.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & NuSphere Corporation
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-#include "gem_global.h"
-#include "dstd.h"
-#include "dsmpub.h"
-
-/* class for the the gemini handler */
-
-enum enum_key_string_options{KEY_CREATE,KEY_DELETE,KEY_CHECK};
-typedef struct st_gemini_share {
- ha_rows *rec_per_key;
- THR_LOCK lock;
- pthread_mutex_t mutex;
- char *table_name;
- uint table_name_length,use_count;
-} GEM_SHARE;
-
-typedef struct gemBlobDesc
-{
- dsmBlobId_t blobId;
- dsmBuffer_t *pBlob;
-} gemBlobDesc_t;
-
-class ha_gemini: public handler
-{
- /* define file as an int for now until we have a real file struct */
- int file;
- uint int_option_flag;
- int tableNumber;
- dsmIndex_t *pindexNumbers; // dsm object numbers for the indexes on this table
- dsmRecid_t lastRowid;
- uint last_dup_key;
- bool fixed_length_row, key_read, using_ignore;
- byte *rec_buff;
- dsmKey_t *pbracketBase;
- dsmKey_t *pbracketLimit;
- dsmKey_t *pfoundKey;
- dsmMask_t tableStatus; // Crashed/repair status
- gemBlobDesc_t *pBlobDescs;
-
- int index_open(char *tableName);
- int pack_row(byte **prow, int *ppackedLength, const byte *record,
- bool update);
- int unpack_row(char *record, char *prow);
- int findRow(THD *thd, dsmMask_t findMode, byte *buf);
- int fetch_row(void *gemini_context, const byte *buf);
- int handleIndexEntries(const byte * record, dsmRecid_t recid,
- enum_key_string_options option);
-
- int handleIndexEntry(const byte * record, dsmRecid_t recid,
- enum_key_string_options option,uint keynr);
-
- int createKeyString(const byte * record, KEY *pkeyinfo,
- unsigned char *pkeyBuf, int bufSize,
- int *pkeyStringLen, short geminiIndexNumber,
- bool *thereIsAnull);
- int fullCheck(THD *thd,byte *buf);
-
- int pack_key( uint keynr, dsmKey_t *pkey,
- const byte *key_ptr, uint key_length);
-
- void unpack_key(char *record, dsmKey_t *key, uint index);
-
- int key_cmp(uint keynr, const byte * old_row,
- const byte * new_row, bool updateStats);
-
- int saveKeyStats(THD *thd);
- void get_index_stats(THD *thd);
-
- short cursorId; /* cursorId of active index cursor if any */
- dsmMask_t lockMode; /* Shared or exclusive */
-
- /* FIXFIX Don't know why we need this because I don't know what
- store_lock method does but we core dump without this */
- THR_LOCK_DATA lock;
- GEM_SHARE *share;
-
- public:
- ha_gemini(TABLE *table): handler(table), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV |
- HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_LONGLONG_KEYS | HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY |
- HA_BLOB_KEY |
- HA_NO_TEMP_TABLES | HA_NO_FULLTEXT_KEY |
- /*HA_NOT_EXACT_COUNT | */
- /*HA_KEY_READ_WRONG_STR |*/ HA_DROP_BEFORE_CREATE),
- pbracketBase(0),pbracketLimit(0),pfoundKey(0),
- cursorId(0)
- {
- }
- ~ha_gemini() {}
- const char *table_type() const { return "Gemini"; }
- const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
- uint max_record_length() const { return MAXRECSZ; }
- uint max_keys() const { return MAX_KEY-1; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAXKEYSZ / 2; }
- bool fast_key_read() { return 1;}
- bool has_transactions() { return 1;}
-
- int open(const char *name, int mode, uint test_if_locked);
- int close(void);
- double scan_time();
- int write_row(byte * buf);
- int update_row(const byte * old_data, byte * new_data);
- int delete_row(const byte * buf);
- int index_init(uint index);
- int index_end();
- int index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_read_idx(byte * buf, uint index, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_next(byte * buf);
- int index_next_same(byte * buf, const byte *key, uint keylen);
- int index_prev(byte * buf);
- int index_first(byte * buf);
- int index_last(byte * buf);
- int rnd_init(bool scan=1);
- int rnd_end();
- int rnd_next(byte *buf);
- int rnd_pos(byte * buf, byte *pos);
- void position(const byte *record);
- void info(uint);
- int extra(enum ha_extra_function operation);
- int reset(void);
- int analyze(THD* thd, HA_CHECK_OPT* check_opt);
- int check(THD* thd, HA_CHECK_OPT* check_opt);
- int repair(THD* thd, HA_CHECK_OPT* check_opt);
- int restore(THD* thd, HA_CHECK_OPT* check_opt);
- int backup(THD* thd, HA_CHECK_OPT* check_opt);
- int optimize(THD* thd, HA_CHECK_OPT* check_opt);
- int external_lock(THD *thd, int lock_type);
- virtual longlong get_auto_increment();
- void position(byte *record);
- ha_rows records_in_range(int inx,
- const byte *start_key,uint start_key_len,
- enum ha_rkey_function start_search_flag,
- const byte *end_key,uint end_key_len,
- enum ha_rkey_function end_search_flag);
- void update_create_info(HA_CREATE_INFO *create_info);
- int create(const char *name, register TABLE *form,
- HA_CREATE_INFO *create_info);
- int delete_table(const char *name);
- int rename_table(const char* from, const char* to);
- THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type);
-};
-
-#define GEMOPT_FLUSH_LOG 0x00000001
-#define GEMOPT_UNBUFFERED_IO 0x00000002
-
-#define GEMINI_RECOVERY_FULL 0x00000001
-#define GEMINI_RECOVERY_NONE 0x00000002
-#define GEMINI_RECOVERY_FORCE 0x00000004
-
-#define GEM_OPTID_SPIN_RETRIES 1
-
-extern bool gemini_skip;
-extern SHOW_COMP_OPTION have_gemini;
-extern long gemini_options;
-extern long gemini_buffer_cache;
-extern long gemini_io_threads;
-extern long gemini_log_cluster_size;
-extern long gemini_locktablesize;
-extern long gemini_lock_wait_timeout;
-extern long gemini_spin_retries;
-extern long gemini_connection_limit;
-extern char *gemini_basedir;
-extern TYPELIB gemini_recovery_typelib;
-extern ulong gemini_recovery_options;
-
-bool gemini_init(void);
-bool gemini_end(void);
-bool gemini_flush_logs(void);
-int gemini_commit(THD *thd);
-int gemini_rollback(THD *thd);
-int gemini_recovery_logging(THD *thd, bool on);
-void gemini_disconnect(THD *thd);
-int gemini_rollback_to_savepoint(THD *thd);
-int gemini_parse_table_name(const char *fullname, char *dbname, char *tabname);
-int gemini_is_vst(const char *pname);
-int gemini_set_option_long(int optid, long optval);
-
-const int gemini_blocksize = BLKSIZE;
-const int gemini_recbits = DEFAULT_RECBITS;
-
-extern "C" void uttrace(void);
diff --git a/sql/ha_hash.h b/sql/ha_hash.h
deleted file mode 100644
index 80416611406..00000000000
--- a/sql/ha_hash.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-int ha_hash::create(my_string name, register TABLE *form,
- ulonglong auto_increment_value)
-{
- register uint i,j;
- char buff[FN_REFLEN];
- KEY *pos;
- H_KEYDEF keydef[MAX_KEY];
- DBUG_ENTER("cre_hash");
-
- pos=form->key_info;
- for (i=0; i < form->keys ; i++, pos++)
- {
- keydef[i].hk_flag= pos->flags & HA_NOSAME;
- for (j=0 ; (int7) j < pos->key_parts ; j++)
- {
- uint flag=pos->key_part[j].key_type;
- if (!f_is_packed(flag) && f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
- !(flag & FIELDFLAG_BINARY))
- keydef[i].hk_keyseg[j].key_type= (int) HA_KEYTYPE_TEXT;
- else
- keydef[i].hk_keyseg[j].key_type= (int) HA_KEYTYPE_BINARY;
- keydef[i].hk_keyseg[j].start= pos->key_part[j].offset;
- keydef[i].hk_keyseg[j].length= pos->key_part[j].length;
- }
- keydef[i].hk_keyseg[j].key_type= 0;
- }
- DBUG_RETURN(h_create(fn_format(buff,name,"","",2+4+16),i,
- keydef,form->reclength,form->max_rows,form->min_rows,
- 0));
-} /* cre_hash */
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 13dccc2bf64..e6d7871b016 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -33,10 +33,11 @@ const char **ha_heap::bas_ext() const
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
- uint key,part,parts,mem_per_row=0;
+ uint key,parts,mem_per_row=0;
ulong max_rows;
HP_KEYDEF *keydef;
HP_KEYSEG *seg;
+ THD *thd= current_thd;
for (key=parts=0 ; key < table->keys ; key++)
parts+=table->key_info[key].key_parts;
@@ -48,28 +49,42 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
for (key=0 ; key < table->keys ; key++)
{
KEY *pos=table->key_info+key;
+ KEY_PART_INFO *key_part= pos->key_part;
+ KEY_PART_INFO *key_part_end= key_part+pos->key_parts;
+
mem_per_row += (pos->key_length + (sizeof(char*) * 2));
-
+
keydef[key].keysegs=(uint) pos->key_parts;
- keydef[key].flag = (pos->flags & HA_NOSAME);
+ keydef[key].flag = (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
keydef[key].seg=seg;
-
- for (part=0 ; part < pos->key_parts ; part++)
+
+ for (; key_part != key_part_end ; key_part++, seg++)
{
- uint flag=pos->key_part[part].key_type;
+ uint flag=key_part->key_type;
+ Field *field=key_part->field;
if (!f_is_packed(flag) &&
f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
!(flag & FIELDFLAG_BINARY))
seg->type= (int) HA_KEYTYPE_TEXT;
else
seg->type= (int) HA_KEYTYPE_BINARY;
- seg->start=(uint) pos->key_part[part].offset;
- seg->length=(uint) pos->key_part[part].length;
- seg++;
+ seg->start=(uint) key_part->offset;
+ seg->length=(uint) key_part->length;
+ if (field->null_ptr)
+ {
+ seg->null_bit=field->null_bit;
+ seg->null_pos= (uint) (field->null_ptr-
+ (uchar*) table->record[0]);
+ }
+ else
+ {
+ seg->null_bit=0;
+ seg->null_pos=0;
+ }
}
}
mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*));
- max_rows = (ulong) (max_heap_table_size / mem_per_row);
+ max_rows = (ulong) (thd->variables.max_heap_table_size / mem_per_row);
file=heap_open(name,mode,
table->keys,keydef,
table->reclength,
@@ -77,7 +92,8 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
table->max_rows : max_rows),
table->min_rows);
my_free((gptr) keydef,MYF(0));
- info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ if (file)
+ info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
ref_length=sizeof(HEAP_PTR);
return (!file ? errno : 0);
}
@@ -147,7 +163,7 @@ int ha_heap::index_prev(byte * buf)
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
-
+
int ha_heap::index_first(byte * buf)
{
statistic_increment(ha_read_first_count,&LOCK_status);
@@ -227,7 +243,7 @@ int ha_heap::delete_all_rows()
int ha_heap::external_lock(THD *thd, int lock_type)
{
return 0; // No external locking
-}
+}
THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
THR_LOCK_DATA **to,
@@ -247,7 +263,7 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
int ha_heap::delete_table(const char *name)
{
- int error=heap_delete_all(name);
+ int error=heap_delete_table(name);
return error == ENOENT ? 0 : error;
}
@@ -272,7 +288,6 @@ ha_rows ha_heap::records_in_range(int inx,
return 10; // Good guess
}
-/* We can just delete the heap on creation */
int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index 6b7e9c6c626..aa675cfffea 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -31,11 +31,24 @@ class ha_heap: public handler
ha_heap(TABLE *table): handler(table), file(0) {}
~ha_heap() {}
const char *table_type() const { return "HEAP"; }
+ const char *index_type(uint inx)
+ {
+ return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" :
+ "HASH");
+ }
const char **bas_ext() const;
- ulong option_flag() const
- { return (HA_READ_RND_SAME | HA_NO_INDEX | HA_ONLY_WHOLE_INDEX |
- HA_WRONG_ASCII_ORDER | HA_KEYPOS_TO_RNDPOS | HA_NO_BLOBS |
- HA_REC_NOT_IN_SEQ | HA_NO_FULLTEXT_KEY); }
+ ulong table_flags() const
+ {
+ return (HA_READ_RND_SAME | HA_NO_INDEX | HA_KEYPOS_TO_RNDPOS |
+ HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ |
+ HA_NOT_READ_PREFIX_LAST | HA_NO_AUTO_INCREMENT);
+ }
+ ulong index_flags(uint inx) const
+ {
+ return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
+ (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER) :
+ (HA_ONLY_WHOLE_INDEX | HA_WRONG_ASCII_ORDER));
+ }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc
deleted file mode 100644
index 33bc4613ef5..00000000000
--- a/sql/ha_innobase.cc
+++ /dev/null
@@ -1,3554 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & InnoDB Oy
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* This file defines the InnoDB handler: the interface between MySQL and
-InnoDB */
-
-/* TODO list for the InnoDB handler:
- - Ask Monty if strings of different languages can exist in the same
- database. Answer: in near future yes, but not yet.
-*/
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include "mysql_priv.h"
-#include "slave.h"
-#ifdef HAVE_INNOBASE_DB
-#include <m_ctype.h>
-#include <assert.h>
-#include <hash.h>
-#include <myisampack.h>
-
-#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
-
-#include "ha_innobase.h"
-
-/* We must declare this here because we undef SAFE_MUTEX below */
-pthread_mutex_t innobase_mutex;
-
-/* Store MySQL definition of 'byte': in Linux it is char while InnoDB
-uses unsigned char */
-typedef byte mysql_byte;
-
-#ifdef SAFE_MUTEX
-#undef pthread_mutex_t
-#endif
-
-#define INSIDE_HA_INNOBASE_CC
-
-/* Include necessary InnoDB headers */
-extern "C" {
-#include "../innobase/include/univ.i"
-#include "../innobase/include/os0file.h"
-#include "../innobase/include/srv0start.h"
-#include "../innobase/include/srv0srv.h"
-#include "../innobase/include/trx0roll.h"
-#include "../innobase/include/trx0trx.h"
-#include "../innobase/include/trx0sys.h"
-#include "../innobase/include/row0ins.h"
-#include "../innobase/include/row0mysql.h"
-#include "../innobase/include/row0sel.h"
-#include "../innobase/include/row0upd.h"
-#include "../innobase/include/log0log.h"
-#include "../innobase/include/lock0lock.h"
-#include "../innobase/include/dict0crea.h"
-#include "../innobase/include/btr0cur.h"
-#include "../innobase/include/btr0btr.h"
-#include "../innobase/include/fsp0fsp.h"
-}
-
-#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
-#define HA_INNOBASE_RANGE_COUNT 100
-
-bool innodb_skip = 0;
-uint innobase_init_flags = 0;
-ulong innobase_cache_size = 0;
-
-/* The default values for the following, type long, start-up parameters
-are declared in mysqld.cc: */
-
-long innobase_mirrored_log_groups, innobase_log_files_in_group,
- innobase_log_file_size, innobase_log_buffer_size,
- innobase_buffer_pool_size, innobase_additional_mem_pool_size,
- innobase_file_io_threads, innobase_lock_wait_timeout,
- innobase_thread_concurrency, innobase_force_recovery;
-
-/* The default values for the following char* start-up parameters
-are determined in innobase_init below: */
-
-/* innobase_data_file_path=ibdata:15,idata2:1,... */
-
-char* innobase_data_home_dir = NULL;
-char* innobase_data_file_path = NULL;
-char* innobase_log_group_home_dir = NULL;
-char* innobase_log_arch_dir = NULL;
-char* innobase_unix_file_flush_method = NULL;
-
-/* Below we have boolean-valued start-up parameters, and their default
-values */
-
-my_bool innobase_flush_log_at_trx_commit = FALSE;
-my_bool innobase_log_archive = FALSE;
-my_bool innobase_use_native_aio = FALSE;
-my_bool innobase_fast_shutdown = TRUE;
-
-/* The following counter is used to convey information to InnoDB
-about server activity: in selects it is not sensible to call
-srv_active_wake_master_thread after each fetch or search, we only do
-it every INNOBASE_WAKE_INTERVAL'th step. */
-
-#define INNOBASE_WAKE_INTERVAL 32
-ulong innobase_active_counter = 0;
-
-char* innobase_home = NULL;
-
-char innodb_dummy_stmt_trx_handle = 'D';
-
-static HASH innobase_open_tables;
-
-static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)));
-static INNOBASE_SHARE *get_share(const char *table_name);
-static void free_share(INNOBASE_SHARE *share);
-static void innobase_print_error(const char* db_errpfx, char* buffer);
-
-/* General functions */
-
-/**********************************************************************
-Releases possible search latch, auto inc lock, and InnoDB thread FIFO ticket.
-These should be released at each SQL statement end. */
-static
-void
-innobase_release_stat_resources(
-/*============================*/
- trx_t* trx) /* in: transaction object */
-{
- if (trx->has_search_latch) {
- trx_search_latch_release_if_reserved(trx);
- }
-
- if (trx->auto_inc_lock) {
-
- /* If we had reserved the auto-inc lock for
- some table in this SQL statement, we release it now */
-
- srv_conc_enter_innodb(trx);
- row_unlock_table_autoinc_for_mysql(trx);
- srv_conc_exit_innodb(trx);
- }
-
- if (trx->declared_to_be_inside_innodb) {
- /* Release our possible ticket in the FIFO */
-
- srv_conc_force_exit_innodb(trx);
- }
-}
-
-/************************************************************************
-Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
-time calls srv_active_wake_master_thread. This function should be used
-when a single database operation may introduce a small need for
-server utility activity, like checkpointing. */
-inline
-void
-innobase_active_small(void)
-/*=======================*/
-{
- innobase_active_counter++;
-
- if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
- srv_active_wake_master_thread();
- }
-}
-
-/************************************************************************
-Converts an InnoDB error code to a MySQL error code. */
-static
-int
-convert_error_code_to_mysql(
-/*========================*/
- /* out: MySQL error code */
- int error, /* in: InnoDB error code */
- THD* thd) /* in: user thread handle or NULL */
-{
- if (error == DB_SUCCESS) {
-
- return(0);
-
- } else if (error == (int) DB_DUPLICATE_KEY) {
-
- return(HA_ERR_FOUND_DUPP_KEY);
-
- } else if (error == (int) DB_RECORD_NOT_FOUND) {
-
- return(HA_ERR_NO_ACTIVE_RECORD);
-
- } else if (error == (int) DB_ERROR) {
-
- return(HA_ERR_NO_ACTIVE_RECORD);
-
- } else if (error == (int) DB_DEADLOCK) {
- /* Since we roll back the whole transaction, we must
- tell it also to MySQL so that MySQL knows to empty the
- cached binlog for this transaction */
-
- if (thd) {
- ha_rollback(thd);
- }
-
- return(HA_ERR_LOCK_DEADLOCK);
-
- } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
-
- /* Since we roll back the whole transaction, we must
- tell it also to MySQL so that MySQL knows to empty the
- cached binlog for this transaction */
-
-
- if (thd) {
- ha_rollback(thd);
- }
-
- return(HA_ERR_LOCK_WAIT_TIMEOUT);
-
- } else if (error == (int) DB_NO_REFERENCED_ROW) {
-
- return(HA_ERR_NO_REFERENCED_ROW);
-
- } else if (error == (int) DB_ROW_IS_REFERENCED) {
-
- return(HA_ERR_ROW_IS_REFERENCED);
-
- } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
-
- return(HA_ERR_CANNOT_ADD_FOREIGN);
-
- } else if (error == (int) DB_OUT_OF_FILE_SPACE) {
-
- return(HA_ERR_RECORD_FILE_FULL);
-
- } else if (error == (int) DB_TABLE_IS_BEING_USED) {
-
- return(HA_ERR_WRONG_COMMAND);
-
- } else if (error == (int) DB_TABLE_NOT_FOUND) {
-
- return(HA_ERR_KEY_NOT_FOUND);
-
- } else if (error == (int) DB_TOO_BIG_RECORD) {
-
- return(HA_ERR_TO_BIG_ROW);
- } else {
- dbug_assert(0);
-
- return(-1); // Unknown error
- }
-}
-
-extern "C" {
-/*****************************************************************
-Prints info of a THD object (== user session thread) to the
-standard output. NOTE that mysql/innobase/trx/trx0trx.c must contain
-the prototype for this function! */
-
-void
-innobase_mysql_print_thd(
-/*=====================*/
- char* buf, /* in/out: buffer where to print, must be at least
- 300 bytes */
- void* input_thd)/* in: pointer to a MySQL THD object */
-{
- THD* thd;
-
- thd = (THD*) input_thd;
-
- buf += sprintf(buf, "MySQL thread id %lu, query id %lu",
- thd->thread_id, thd->query_id);
- if (thd->host) {
- buf += sprintf(buf, " %.30s", thd->host);
- }
-
- if (thd->ip) {
- buf += sprintf(buf, " %.20s", thd->ip);
- }
-
- if (thd->user) {
- buf += sprintf(buf, " %.20s", thd->user);
- }
-
- if (thd->proc_info) {
- buf += sprintf(buf, " %.50s", thd->proc_info);
- }
-
- if (thd->query) {
- buf += sprintf(buf, "\n%.150s", thd->query);
- }
-
- buf += sprintf(buf, "\n");
-}
-}
-
-/*************************************************************************
-Gets the InnoDB transaction handle for a MySQL handler object, creates
-an InnoDB transaction struct if the corresponding MySQL thread struct still
-lacks one. */
-static
-trx_t*
-check_trx_exists(
-/*=============*/
- /* out: InnoDB transaction handle */
- THD* thd) /* in: user thread handle */
-{
- trx_t* trx;
-
- ut_a(thd == current_thd);
-
- trx = (trx_t*) thd->transaction.all.innobase_tid;
-
- if (trx == NULL) {
- ut_a(thd != NULL);
- trx = trx_allocate_for_mysql();
-
- trx->mysql_thd = thd;
-
- thd->transaction.all.innobase_tid = trx;
-
- /* The execution of a single SQL statement is denoted by
- a 'transaction' handle which is a dummy pointer: InnoDB
- remembers internally where the latest SQL statement
- started, and if error handling requires rolling back the
- latest statement, InnoDB does a rollback to a savepoint. */
-
- thd->transaction.stmt.innobase_tid =
- (void*)&innodb_dummy_stmt_trx_handle;
- } else {
- if (trx->magic_n != TRX_MAGIC_N) {
- mem_analyze_corruption((byte*)trx);
-
- ut_a(0);
- }
- }
-
- if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
- trx->check_foreigns = FALSE;
- } else {
- trx->check_foreigns = TRUE;
- }
-
- if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
- trx->check_unique_secondary = FALSE;
- } else {
- trx->check_unique_secondary = TRUE;
- }
-
- return(trx);
-}
-
-/*************************************************************************
-Updates the user_thd field in a handle and also allocates a new InnoDB
-transaction handle if needed, and updates the transaction fields in the
-prebuilt struct. */
-inline
-int
-ha_innobase::update_thd(
-/*====================*/
- /* out: 0 or error code */
- THD* thd) /* in: thd to use the handle */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- trx_t* trx;
-
- trx = check_trx_exists(thd);
-
- if (prebuilt->trx != trx) {
-
- row_update_prebuilt_trx(prebuilt, trx);
- }
-
- user_thd = thd;
-
- return(0);
-}
-
-/*************************************************************************
-Opens an InnoDB database. */
-
-bool
-innobase_init(void)
-/*===============*/
- /* out: TRUE if error */
-{
- static char current_dir[3];
- int err;
- bool ret;
-
- DBUG_ENTER("innobase_init");
-
- os_innodb_umask = (ulint)my_umask;
-
- if (specialflag & SPECIAL_NO_PRIOR) {
- srv_set_thread_priorities = FALSE;
- } else {
- srv_set_thread_priorities = TRUE;
- srv_query_thread_priority = QUERY_PRIOR;
- }
-
- /* Use current_dir if no paths are set */
- current_dir[0] = FN_CURLIB;
- current_dir[1] = FN_LIBCHAR;
- current_dir[2] = 0;
-
- /* Set InnoDB initialization parameters according to the values
- read from MySQL .cnf file */
-
- if (!innobase_data_file_path) {
- fprintf(stderr,
- "Cannot initialize InnoDB as 'innodb_data_file_path' is not set.\n"
- "If you do not want to use transactional InnoDB tables, add a line\n"
- "skip-innodb\n"
- "to the [mysqld] section of init parameters in your my.cnf\n"
- "or my.ini. If you want to use InnoDB tables, add to the [mysqld]\n"
- "section, for example,\n"
- "innodb_data_file_path = ibdata1:10M:autoextend\n"
- "But to get good performance you should adjust for your hardware\n"
- "the InnoDB startup options listed in section 2 at\n"
- "http://www.innodb.com/ibman.html\n");
-
- innodb_skip=1;
- DBUG_RETURN(FALSE); /* Continue without InnoDB */
- }
-
- srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
- current_dir);
- srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir :
- current_dir);
-
- ret = (bool)
- srv_parse_data_file_paths_and_sizes(innobase_data_file_path,
- &srv_data_file_names,
- &srv_data_file_sizes,
- &srv_data_file_is_raw_partition,
- &srv_n_data_files,
- &srv_auto_extend_last_data_file,
- &srv_last_file_size_max);
- if (ret == FALSE) {
- fprintf(stderr,
- "InnoDB: syntax error in innodb_data_file_path\n");
- DBUG_RETURN(TRUE);
- }
-
- if (!innobase_log_group_home_dir) {
- innobase_log_group_home_dir = current_dir;
- }
-
- ret = (bool)
- srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
- &srv_log_group_home_dirs);
-
- if (ret == FALSE || innobase_mirrored_log_groups != 1) {
- fprintf(stderr,
- "InnoDB: syntax error in innodb_log_group_home_dir\n"
- "InnoDB: or a wrong number of mirrored log groups\n");
-
- DBUG_RETURN(TRUE);
- }
-
- srv_unix_file_flush_method_str = (innobase_unix_file_flush_method ?
- innobase_unix_file_flush_method :
- (char*)"fdatasync");
-
- srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
- srv_n_log_files = (ulint) innobase_log_files_in_group;
- srv_log_file_size = (ulint) innobase_log_file_size;
-
- srv_log_archive_on = (ulint) innobase_log_archive;
- srv_log_buffer_size = (ulint) innobase_log_buffer_size;
- srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
-
- srv_use_native_aio = 0;
-
- srv_pool_size = (ulint) innobase_buffer_pool_size;
-
- srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
-
- srv_n_file_io_threads = (ulint) innobase_file_io_threads;
-
- srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
- srv_thread_concurrency = (ulint) innobase_thread_concurrency;
- srv_force_recovery = (ulint) innobase_force_recovery;
-
- srv_fast_shutdown = (ibool) innobase_fast_shutdown;
-
- if (strcmp(default_charset_info->name, "latin1") == 0) {
- /* Store the character ordering table to InnoDB.
- For non-latin1 charsets we use the MySQL comparison
- functions, and consequently we do not need to know
- the ordering internally in InnoDB. */
-
- memcpy(srv_latin1_ordering,
- default_charset_info->sort_order, 256);
- }
-
- err = innobase_start_or_create_for_mysql();
-
- if (err != DB_SUCCESS) {
-
- DBUG_RETURN(1);
- }
-
- (void) hash_init(&innobase_open_tables,32,0,0,
- (hash_get_key) innobase_get_key,0,0);
- pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST);
-
- /* If this is a replication slave and we needed to do a crash recovery,
- set the master binlog position to what InnoDB internally knew about
- how far we got transactions durable inside InnoDB. There is a
- problem here: if the user used also MyISAM tables, InnoDB might not
- know the right position for them.
-
- THIS DOES NOT WORK CURRENTLY because replication seems to initialize
- glob_mi also after innobase_init. */
-
-/* if (trx_sys_mysql_master_log_pos != -1) {
- ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name,
- 1 + ut_strlen(trx_sys_mysql_master_log_name));
- glob_mi.pos = trx_sys_mysql_master_log_pos;
- }
-*/
- DBUG_RETURN(0);
-}
-
-/***********************************************************************
-Closes an InnoDB database. */
-
-bool
-innobase_end(void)
-/*==============*/
- /* out: TRUE if error */
-{
- int err;
-
- DBUG_ENTER("innobase_end");
-
- err = innobase_shutdown_for_mysql();
- hash_free(&innobase_open_tables);
-
- if (err != DB_SUCCESS) {
-
- DBUG_RETURN(1);
- }
-
- DBUG_RETURN(0);
-}
-
-/********************************************************************
-Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit
-flushes logs, and the name of this function should be innobase_checkpoint. */
-
-bool
-innobase_flush_logs(void)
-/*=====================*/
- /* out: TRUE if error */
-{
- bool result = 0;
-
- DBUG_ENTER("innobase_flush_logs");
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- DBUG_RETURN(result);
-}
-
-/*************************************************************************
-Gets the free space in an InnoDB database: returned in units of kB. */
-
-uint
-innobase_get_free_space(void)
-/*=========================*/
- /* out: free space in kB */
-{
- return((uint) fsp_get_available_space_in_free_extents(0));
-}
-
-/*********************************************************************
-Commits a transaction in an InnoDB database. */
-
-void
-innobase_commit_low(
-/*================*/
- trx_t* trx) /* in: transaction handle */
-{
- if (current_thd->slave_thread) {
-
- /* Update the replication position info inside InnoDB */
-
- trx->mysql_master_log_file_name = glob_mi.log_file_name;
- trx->mysql_master_log_pos = (ib_longlong)
- (glob_mi.pos + glob_mi.event_len
- + glob_mi.pending);
- }
-
- trx_commit_for_mysql(trx);
-}
-
-/*********************************************************************
-Commits a transaction in an InnoDB database. */
-
-int
-innobase_commit(
-/*============*/
- /* out: 0 or error number */
- THD* thd, /* in: MySQL thread handle of the user for whom
- the transaction should be committed */
- void* trx_handle)/* in: InnoDB trx handle or NULL: NULL means
- that the current SQL statement ended, and we should
- mark the start of a new statement with a savepoint */
-{
- int error = 0;
- trx_t* trx;
-
- DBUG_ENTER("innobase_commit");
- DBUG_PRINT("trans", ("ending transaction"));
-
- trx = check_trx_exists(thd);
-
- if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
- innobase_commit_low(trx);
- }
-
- /* Release possible statement level resources */
- innobase_release_stat_resources(trx);
-
- trx_mark_sql_stat_end(trx);
-
-#ifndef DBUG_OFF
- if (error) {
- DBUG_PRINT("error", ("error: %d", error));
- }
-#endif
- /* Tell InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-This is called when MySQL writes the binlog entry for the current
-transaction. Writes to the InnoDB tablespace info which tells where the
-MySQL binlog entry for the current transaction ended. Also commits the
-transaction inside InnoDB. */
-
-int
-innobase_report_binlog_offset_and_commit(
-/*=====================================*/
- /* out: 0 or error code */
- THD* thd, /* in: user thread */
- void* trx_handle, /* in: InnoDB trx handle */
- char* log_file_name, /* in: latest binlog file name */
- my_off_t end_offset) /* in: the offset in the binlog file
- up to which we wrote */
-{
- trx_t* trx;
-
- trx = (trx_t*)trx_handle;
-
- ut_a(trx != NULL);
-
- trx->mysql_log_file_name = log_file_name;
- trx->mysql_log_offset = (ib_longlong)end_offset;
-
- return(innobase_commit(thd, trx_handle));
-}
-
-/*********************************************************************
-Rolls back a transaction in an InnoDB database. */
-
-int
-innobase_rollback(
-/*==============*/
- /* out: 0 or error number */
- THD* thd, /* in: handle to the MySQL thread of the user
- whose transaction should be rolled back */
- void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle */
-{
- int error = 0;
- trx_t* trx;
-
- DBUG_ENTER("innobase_rollback");
- DBUG_PRINT("trans", ("aborting transaction"));
-
- trx = check_trx_exists(thd);
-
- srv_conc_enter_innodb(trx);
-
- if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
- error = trx_rollback_for_mysql(trx);
- } else {
- error = trx_rollback_last_sql_stat_for_mysql(trx);
- }
-
- srv_conc_exit_innodb(trx);
-
- /* Release possible statement level resources */
- innobase_release_stat_resources(trx);
-
- trx_mark_sql_stat_end(trx);
-
- DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
-}
-
-/*********************************************************************
-Frees a possible InnoDB trx object associated with the current
-THD. */
-
-int
-innobase_close_connection(
-/*======================*/
- /* out: 0 or error number */
- THD* thd) /* in: handle to the MySQL thread of the user
- whose transaction should be rolled back */
-{
- if (NULL != thd->transaction.all.innobase_tid) {
-
- trx_rollback_for_mysql((trx_t*)
- (thd->transaction.all.innobase_tid));
- trx_free_for_mysql((trx_t*)
- (thd->transaction.all.innobase_tid));
- thd->transaction.all.innobase_tid = NULL;
- }
-
- return(0);
-}
-
-/**********************************************************************
-Prints an error message. */
-static
-void
-innobase_print_error(
-/*=================*/
- const char* db_errpfx, /* in: error prefix text */
- char* buffer) /* in: error text */
-{
- sql_print_error("%s: %s", db_errpfx, buffer);
-}
-
-
-/*****************************************************************************
-** InnoDB database tables
-*****************************************************************************/
-
-/********************************************************************
-This function is not relevant since we store the tables and indexes
-into our own tablespace, not as files, whose extension this function would
-give. */
-
-const char**
-ha_innobase::bas_ext() const
-/*========================*/
- /* out: file extension strings, currently not
- used */
-{
- static const char* ext[] = {".InnoDB", NullS};
-
- return(ext);
-}
-
-/*********************************************************************
-Normalizes a table name string. A normalized name consists of the
-database name catenated to '/' and table name. An example:
-test/mytable. On Windows normalization puts both the database name and the
-table name always to lower case. */
-static
-void
-normalize_table_name(
-/*=================*/
- char* norm_name, /* out: normalized name as a
- null-terminated string */
- const char* name) /* in: table name string */
-{
- char* name_ptr;
- char* db_ptr;
- char* ptr;
-
- /* Scan name from the end */
-
- ptr = strend(name)-1;
-
- while (ptr >= name && *ptr != '\\' && *ptr != '/') {
- ptr--;
- }
-
- name_ptr = ptr + 1;
-
- dbug_assert(ptr > name);
-
- ptr--;
-
- while (ptr >= name && *ptr != '\\' && *ptr != '/') {
- ptr--;
- }
-
- db_ptr = ptr + 1;
-
- memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
-
- norm_name[name_ptr - db_ptr - 1] = '/';
-
-#ifdef __WIN__
- /* Put to lower case */
-
- ptr = norm_name;
-
- while (*ptr != '\0') {
- *ptr = tolower(*ptr);
- ptr++;
- }
-#endif
-}
-
-/*********************************************************************
-Creates and opens a handle to a table which already exists in an Innnobase
-database. */
-
-int
-ha_innobase::open(
-/*==============*/
- /* out: 1 if error, 0 if success */
- const char* name, /* in: table name */
- int mode, /* in: not used */
- uint test_if_locked) /* in: not used */
-{
- dict_table_t* ib_table;
- int error = 0;
- uint buff_len;
- char norm_name[1000];
-
- DBUG_ENTER("ha_innobase::open");
-
- UT_NOT_USED(mode);
- UT_NOT_USED(test_if_locked);
-
- normalize_table_name(norm_name, name);
-
- user_thd = NULL;
-
- last_query_id = (ulong)-1;
-
- if (!(share=get_share(name)))
- DBUG_RETURN(1);
-
- /* Create buffers for packing the fields of a record. Why
- table->reclength did not work here? Obviously, because char
- fields when packed actually became 1 byte longer, when we also
- stored the string length as the first byte. */
-
- buff_len = table->reclength + table->max_key_length
- + MAX_REF_PARTS * 3;
- if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME),
- &upd_buff, buff_len,
- &key_val_buff, buff_len,
- NullS)) {
- free_share(share);
- DBUG_RETURN(1);
- }
-
- /* Get pointer to a table object in InnoDB dictionary cache */
-
- ib_table = dict_table_get_and_increment_handle_count(
- norm_name, NULL);
- if (NULL == ib_table) {
-
- fprintf(stderr,
-"InnoDB: Error: cannot find table %s from the internal data dictionary\n"
-"InnoDB: of InnoDB though the .frm file for the table exists. Maybe you\n"
-"InnoDB: have deleted and recreated InnoDB data files but have forgotten\n"
-"InnoDB: to delete the corresponding .frm files of InnoDB tables, or you\n"
-"InnoDB: have moved .frm files to another database?\n",
- norm_name);
-
- free_share(share);
- my_free((char*) upd_buff, MYF(0));
- my_errno = ENOENT;
- DBUG_RETURN(1);
- }
-
- innobase_prebuilt = row_create_prebuilt(ib_table);
-
- ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = table->reclength;
-
- primary_key = MAX_KEY;
-
- if (!row_table_got_default_clust_index(ib_table)) {
-
- /* If we automatically created the clustered index,
- then MySQL does not know about it and it must not be aware
- of the index used on scan, to avoid checking if we update
- the column of the index. The column is the row id in
- the automatical case, and it will not be updated. */
-
- ((row_prebuilt_t*)innobase_prebuilt)
- ->clust_index_was_generated = FALSE;
-
- primary_key = 0;
- key_used_on_scan = 0;
-
- /* MySQL allocates the buffer for ref */
-
- ref_length = table->key_info->key_length
- + table->key_info->key_parts + 10;
-
- /* One byte per key field is consumed to the SQL NULL
- info of the field; we add also 10 bytes of safety margin */
- } else {
- ((row_prebuilt_t*)innobase_prebuilt)
- ->clust_index_was_generated = TRUE;
-
- ref_length = DATA_ROW_ID_LEN + 10;
-
- dbug_assert(key_used_on_scan == MAX_KEY);
- }
-
- auto_inc_counter_for_this_stat = 0;
-
- block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
- in query optimization */
-
- /* Init table lock structure */
- thr_lock_data_init(&share->lock,&lock,(void*) 0);
-
- info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
-
- DBUG_RETURN(0);
-}
-
-/*********************************************************************
-Does nothing. */
-
-void
-ha_innobase::initialize(void)
-/*=========================*/
-{
-}
-
-/**********************************************************************
-Closes a handle to an InnoDB table. */
-
-int
-ha_innobase::close(void)
-/*====================*/
- /* out: error number */
-{
- DBUG_ENTER("ha_innobase::close");
-
- row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt);
-
- my_free((char*) upd_buff, MYF(0));
- free_share(share);
-
- /* Tell InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- DBUG_RETURN(0);
-}
-
-/* The following accessor functions should really be inside MySQL code! */
-
-/******************************************************************
-Gets field offset for a field in a table. */
-inline
-uint
-get_field_offset(
-/*=============*/
- /* out: offset */
- TABLE* table, /* in: MySQL table object */
- Field* field) /* in: MySQL field object */
-{
- return((uint) (field->ptr - (char*) table->record[0]));
-}
-
-/******************************************************************
-Checks if a field in a record is SQL NULL. Uses the record format
-information in table to track the null bit in record. */
-inline
-uint
-field_in_record_is_null(
-/*====================*/
- /* out: 1 if NULL, 0 otherwise */
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
-{
- int null_offset;
-
- if (!field->null_ptr) {
-
- return(0);
- }
-
- null_offset = (uint) ((char*) field->null_ptr
- - (char*) table->record[0]);
-
- if (record[null_offset] & field->null_bit) {
-
- return(1);
- }
-
- return(0);
-}
-
-/******************************************************************
-Sets a field in a record to SQL NULL. Uses the record format
-information in table to track the null bit in record. */
-inline
-void
-set_field_in_record_to_null(
-/*========================*/
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
-{
- int null_offset;
-
- null_offset = (uint) ((char*) field->null_ptr
- - (char*) table->record[0]);
-
- record[null_offset] = record[null_offset] | field->null_bit;
-}
-
-/******************************************************************
-Resets SQL NULL bits in a record to zero. */
-inline
-void
-reset_null_bits(
-/*============*/
- TABLE* table, /* in: MySQL table object */
- char* record) /* in: a row in MySQL format */
-{
- bzero(record, table->null_bytes);
-}
-
-extern "C" {
-/*****************************************************************
-InnoDB uses this function is to compare two data fields for which the
-data type is such that we must use MySQL code to compare them. NOTE that the
-prototype of this function is in rem0cmp.c in InnoDB source code!
-If you change this function, remember to update the prototype there! */
-
-int
-innobase_mysql_cmp(
-/*===============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- int mysql_type, /* in: MySQL type */
- unsigned char* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
- not UNIV_SQL_NULL */
- unsigned char* b, /* in: data field */
- unsigned int b_length) /* in: data field length,
- not UNIV_SQL_NULL */
-{
- enum_field_types mysql_tp;
- int ret;
-
- dbug_assert(a_length != UNIV_SQL_NULL);
- dbug_assert(b_length != UNIV_SQL_NULL);
-
- mysql_tp = (enum_field_types) mysql_type;
-
- switch (mysql_tp) {
-
- case FIELD_TYPE_STRING:
- case FIELD_TYPE_VAR_STRING:
- ret = my_sortncmp((const char*) a, a_length,
- (const char*) b, b_length);
- if (ret < 0) {
- return(-1);
- } else if (ret > 0) {
- return(1);
- } else {
- return(0);
- }
- default:
- assert(0);
- }
-
- return(0);
-}
-}
-
-/******************************************************************
-Converts a MySQL type to an InnoDB type. */
-inline
-ulint
-get_innobase_type_from_mysql_type(
-/*==============================*/
- /* out: DATA_BINARY, DATA_VARCHAR, ... */
- Field* field) /* in: MySQL field */
-{
- /* The following asserts check that MySQL type code fits in
- 8 bits: this is used in ibuf and also when DATA_NOT_NULL is
- ORed to the type */
-
- dbug_assert((ulint)FIELD_TYPE_STRING < 256);
- dbug_assert((ulint)FIELD_TYPE_VAR_STRING < 256);
- dbug_assert((ulint)FIELD_TYPE_DOUBLE < 256);
- dbug_assert((ulint)FIELD_TYPE_FLOAT < 256);
- dbug_assert((ulint)FIELD_TYPE_DECIMAL < 256);
-
- switch (field->type()) {
- case FIELD_TYPE_VAR_STRING: if (field->flags & BINARY_FLAG) {
-
- return(DATA_BINARY);
- } else if (strcmp(
- default_charset_info->name,
- "latin1") == 0) {
- return(DATA_VARCHAR);
- } else {
- return(DATA_VARMYSQL);
- }
- case FIELD_TYPE_STRING: if (field->flags & BINARY_FLAG) {
-
- return(DATA_FIXBINARY);
- } else if (strcmp(
- default_charset_info->name,
- "latin1") == 0) {
- return(DATA_CHAR);
- } else {
- return(DATA_MYSQL);
- }
- case FIELD_TYPE_LONG:
- case FIELD_TYPE_LONGLONG:
- case FIELD_TYPE_TINY:
- case FIELD_TYPE_SHORT:
- case FIELD_TYPE_INT24:
- case FIELD_TYPE_DATE:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_YEAR:
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_ENUM:
- case FIELD_TYPE_SET:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_TIMESTAMP:
- return(DATA_INT);
- case FIELD_TYPE_FLOAT:
- return(DATA_FLOAT);
- case FIELD_TYPE_DOUBLE:
- return(DATA_DOUBLE);
- case FIELD_TYPE_DECIMAL:
- return(DATA_DECIMAL);
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- return(DATA_BLOB);
- default:
- assert(0);
- }
-
- return(0);
-}
-
-/***********************************************************************
-Stores a key value for a row to a buffer. */
-
-uint
-ha_innobase::store_key_val_for_row(
-/*===============================*/
- /* out: key value length as stored in buff */
- uint keynr, /* in: key number */
- char* buff, /* in/out: buffer for the key value (in MySQL
- format) */
- const mysql_byte* record)/* in: row in MySQL format */
-{
- KEY* key_info = table->key_info + keynr;
- KEY_PART_INFO* key_part = key_info->key_part;
- KEY_PART_INFO* end = key_part + key_info->key_parts;
- char* buff_start = buff;
-
- DBUG_ENTER("store_key_val_for_row");
-
- for (; key_part != end; key_part++) {
-
- if (key_part->null_bit) {
- /* Store 0 if the key part is a NULL part */
-
- if (record[key_part->null_offset]
- & key_part->null_bit) {
- *buff++ = 1;
- continue;
- }
-
- *buff++ = 0;
- }
-
- memcpy(buff, record + key_part->offset, key_part->length);
- buff += key_part->length;
- }
-
- DBUG_RETURN(buff - buff_start);
-}
-
-/******************************************************************
-Builds a template to the prebuilt struct. */
-static
-void
-build_template(
-/*===========*/
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- THD* thd, /* in: current user thread, used
- only if templ_type is
- ROW_MYSQL_REC_FIELDS */
- TABLE* table, /* in: MySQL table */
- ulint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
- ROW_MYSQL_REC_FIELDS */
-{
- dict_index_t* index;
- dict_index_t* clust_index;
- mysql_row_templ_t* templ;
- Field* field;
- ulint n_fields;
- ulint n_requested_fields = 0;
- ibool fetch_all_in_key = FALSE;
- ulint i;
-
- clust_index = dict_table_get_first_index_noninline(prebuilt->table);
-
- if (!prebuilt->hint_no_need_to_fetch_extra_cols) {
- /* We have a hint that we should at least fetch all
- columns in the key, or all columns in the table */
-
- if (prebuilt->read_just_key) {
- /* MySQL has instructed us that it is enough to
- fetch the columns in the key */
-
- fetch_all_in_key = TRUE;
- } else {
- /* We are building a temporary table: fetch all
- columns; the reason is that MySQL may use the
- clustered index key to store rows, but the mechanism
- we use below to detect required columns does not
- reveal that. Actually, it might be enough to
- fetch only all in the key also in this case! */
-
- templ_type = ROW_MYSQL_WHOLE_ROW;
- }
- }
-
- if (prebuilt->select_lock_type == LOCK_X) {
- /* We always retrieve the whole clustered index record if we
- use exclusive row level locks, for example, if the read is
- done in an UPDATE statement. */
-
- templ_type = ROW_MYSQL_WHOLE_ROW;
- }
-
- if (templ_type == ROW_MYSQL_REC_FIELDS) {
- /* In versions < 3.23.50 we always retrieved the clustered
- index record if prebuilt->select_lock_type == LOCK_S,
- but there is really not need for that, and in some cases
- performance could be seriously degraded because the MySQL
- optimizer did not know about our convention! */
-
- index = prebuilt->index;
- } else {
- index = clust_index;
- }
-
- if (index == clust_index) {
- prebuilt->need_to_access_clustered = TRUE;
- } else {
- prebuilt->need_to_access_clustered = FALSE;
- /* Below we check column by column if we need to access
- the clustered index */
- }
-
- n_fields = (ulint)table->fields;
-
- if (!prebuilt->mysql_template) {
- prebuilt->mysql_template = (mysql_row_templ_t*)
- mem_alloc_noninline(
- n_fields * sizeof(mysql_row_templ_t));
- }
-
- prebuilt->template_type = templ_type;
- prebuilt->null_bitmap_len = table->null_bytes;
-
- prebuilt->templ_contains_blob = FALSE;
-
- for (i = 0; i < n_fields; i++) {
- templ = prebuilt->mysql_template + n_requested_fields;
- field = table->field[i];
-
- if (templ_type == ROW_MYSQL_REC_FIELDS
- && !(fetch_all_in_key &&
- ULINT_UNDEFINED != dict_index_get_nth_col_pos(
- index, i))
- && thd->query_id != field->query_id
- && thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
- && thd->query_id !=
- (field->query_id ^ (MAX_ULONG_BIT >> 1))) {
-
- /* This field is not needed in the query, skip it */
-
- goto skip_field;
- }
-
- n_requested_fields++;
-
- templ->col_no = i;
-
- if (index == clust_index) {
- templ->rec_field_no = (index->table->cols + i)
- ->clust_pos;
- } else {
- templ->rec_field_no = dict_index_get_nth_col_pos(
- index, i);
- }
-
- if (templ->rec_field_no == ULINT_UNDEFINED) {
- prebuilt->need_to_access_clustered = TRUE;
- }
-
- if (field->null_ptr) {
- templ->mysql_null_byte_offset =
- (ulint) ((char*) field->null_ptr
- - (char*) table->record[0]);
-
- templ->mysql_null_bit_mask = (ulint) field->null_bit;
- } else {
- templ->mysql_null_bit_mask = 0;
- }
-
- templ->mysql_col_offset = (ulint)
- get_field_offset(table, field);
-
- templ->mysql_col_len = (ulint) field->pack_length();
- templ->type = get_innobase_type_from_mysql_type(field);
- templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
-
- if (templ->type == DATA_BLOB) {
- prebuilt->templ_contains_blob = TRUE;
- }
-skip_field:
- ;
- }
-
- prebuilt->n_template = n_requested_fields;
-
- if (prebuilt->need_to_access_clustered) {
- /* Change rec_field_no's to correspond to the clustered index
- record */
- for (i = 0; i < n_requested_fields; i++) {
- templ = prebuilt->mysql_template + i;
-
- templ->rec_field_no =
- (index->table->cols + templ->col_no)->clust_pos;
- }
- }
-}
-
-/************************************************************************
-Stores a row in an InnoDB database, to the table specified in this
-handle. */
-
-int
-ha_innobase::write_row(
-/*===================*/
- /* out: error code */
- mysql_byte* record) /* in: a row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
- int error;
- longlong auto_inc;
-
- DBUG_ENTER("ha_innobase::write_row");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- statistic_increment(ha_write_count, &LOCK_status);
-
- if (table->time_stamp) {
- update_timestamp(record + table->time_stamp - 1);
- }
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- if (table->next_number_field && record == table->record[0]) {
- /* This is the case where the table has an
- auto-increment column */
-
- /* Fetch the value the user possibly has set in the
- autoincrement field */
-
- auto_inc = table->next_number_field->val_int();
-
- /* In replication and also otherwise the auto-inc column
- can be set with SET INSERT_ID. Then we must look at
- user_thd->next_insert_id. If it is nonzero and the user
- has not supplied a value, we must use it, and use values
- incremented by 1 in all subsequent inserts within the
- same SQL statement! */
-
- if (auto_inc == 0 && user_thd->next_insert_id != 0) {
- auto_inc = user_thd->next_insert_id;
- auto_inc_counter_for_this_stat = auto_inc;
- }
-
- if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
- /* The user set the auto-inc counter for
- this SQL statement with SET INSERT_ID. We must
- assign sequential values from the counter. */
-
- auto_inc_counter_for_this_stat++;
-
- auto_inc = auto_inc_counter_for_this_stat;
-
- /* We give MySQL a new value to place in the
- auto-inc column */
- user_thd->next_insert_id = auto_inc;
- }
-
- if (auto_inc != 0) {
- /* This call will calculate the max of the
- current value and the value supplied by the user, if
- the auto_inc counter is already initialized
- for the table */
-
- /* We have to use the transactional lock mechanism
- on the auto-inc counter of the table to ensure
- that replication and roll-forward of the binlog
- exactly imitates also the given auto-inc values.
- The lock is released at each SQL statement's
- end. */
-
- srv_conc_enter_innodb(prebuilt->trx);
- error = row_lock_table_autoinc_for_mysql(prebuilt);
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (error != DB_SUCCESS) {
-
- error = convert_error_code_to_mysql(error,
- user_thd);
- goto func_exit;
- }
-
- dict_table_autoinc_update(prebuilt->table, auto_inc);
- } else {
- srv_conc_enter_innodb(prebuilt->trx);
-
- if (!prebuilt->trx->auto_inc_lock) {
-
- error = row_lock_table_autoinc_for_mysql(
- prebuilt);
- if (error != DB_SUCCESS) {
- srv_conc_exit_innodb(prebuilt->trx);
-
- error = convert_error_code_to_mysql(
- error, user_thd);
- goto func_exit;
- }
- }
-
- auto_inc = dict_table_autoinc_get(prebuilt->table);
- srv_conc_exit_innodb(prebuilt->trx);
-
- /* If auto_inc is now != 0 the autoinc counter
- was already initialized for the table: we can give
- the new value for MySQL to place in the field */
-
- if (auto_inc != 0) {
- user_thd->next_insert_id = auto_inc;
- }
- }
-
- update_auto_increment();
-
- if (auto_inc == 0) {
- /* The autoinc counter for our table was not yet
- initialized, initialize it now */
-
- auto_inc = table->next_number_field->val_int();
-
- srv_conc_enter_innodb(prebuilt->trx);
- error = row_lock_table_autoinc_for_mysql(prebuilt);
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (error != DB_SUCCESS) {
-
- error = convert_error_code_to_mysql(error,
- user_thd);
- goto func_exit;
- }
-
- dict_table_autoinc_initialize(prebuilt->table,
- auto_inc);
- }
-
- /* We have to set sql_stat_start to TRUE because
- update_auto_increment may have called a select, and
- has reset that flag; row_insert_for_mysql has to
- know to set the IX intention lock on the table, something
- it only does at the start of each statement */
-
- prebuilt->sql_stat_start = TRUE;
- }
-
- if (prebuilt->mysql_template == NULL
- || prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
- /* Build the template used in converting quickly between
- the two database formats */
-
- build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
- }
-
- if (user_thd->lex.sql_command == SQLCOM_INSERT
- && user_thd->lex.duplicates == DUP_IGNORE) {
- prebuilt->trx->ignore_duplicates_in_insert = TRUE;
- } else {
- prebuilt->trx->ignore_duplicates_in_insert = FALSE;
- }
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- error = row_insert_for_mysql((byte*) record, prebuilt);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- prebuilt->trx->ignore_duplicates_in_insert = FALSE;
-
- error = convert_error_code_to_mysql(error, user_thd);
-
- /* Tell InnoDB server that there might be work for
- utility threads: */
-func_exit:
- innobase_active_small();
-
- DBUG_RETURN(error);
-}
-
-/******************************************************************
-Converts field data for storage in an InnoDB update vector. */
-inline
-mysql_byte*
-innobase_convert_and_store_changed_col(
-/*===================================*/
- /* out: pointer to the end of the converted
- data in the buffer */
- upd_field_t* ufield, /* in/out: field in the update vector */
- mysql_byte* buf, /* in: buffer we can use in conversion */
- mysql_byte* data, /* in: column data to store */
- ulint len, /* in: data len */
- ulint col_type,/* in: data type in InnoDB type numbers */
- ulint is_unsigned)/* in: != 0 if an unsigned integer type */
-{
- uint i;
-
- if (len == UNIV_SQL_NULL) {
- data = NULL;
- } else if (col_type == DATA_VARCHAR || col_type == DATA_BINARY
- || col_type == DATA_VARMYSQL) {
- /* Remove trailing spaces */
- while (len > 0 && data[len - 1] == ' ') {
- len--;
- }
-
- } else if (col_type == DATA_INT) {
- /* Store integer data in InnoDB in a big-endian
- format, sign bit negated, if signed */
-
- for (i = 0; i < len; i++) {
- buf[len - 1 - i] = data[i];
- }
-
- if (!is_unsigned) {
- buf[0] = buf[0] ^ 128;
- }
-
- data = buf;
-
- buf += len;
- }
-
- ufield->new_val.data = data;
- ufield->new_val.len = len;
-
- return(buf);
-}
-
-/**************************************************************************
-Checks which fields have changed in a row and stores information
-of them to an update vector. */
-static
-int
-calc_row_difference(
-/*================*/
- /* out: error number or 0 */
- upd_t* uvect, /* in/out: update vector */
- mysql_byte* old_row, /* in: old row in MySQL format */
- mysql_byte* new_row, /* in: new row in MySQL format */
- struct st_table* table, /* in: table in MySQL data dictionary */
- mysql_byte* upd_buff, /* in: buffer to use */
- row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
- THD* thd) /* in: user thread */
-{
- Field* field;
- uint n_fields;
- ulint o_len;
- ulint n_len;
- byte* o_ptr;
- byte* n_ptr;
- byte* buf;
- upd_field_t* ufield;
- ulint col_type;
- ulint is_unsigned;
- ulint n_changed = 0;
- uint i;
-
- n_fields = table->fields;
-
- /* We use upd_buff to convert changed fields */
- buf = (byte*) upd_buff;
-
- for (i = 0; i < n_fields; i++) {
- field = table->field[i];
-
- /* if (thd->query_id != field->query_id) { */
- /* TODO: check that these fields cannot have
- changed! */
-
- /* goto skip_field;
- }*/
-
- o_ptr = (byte*) old_row + get_field_offset(table, field);
- n_ptr = (byte*) new_row + get_field_offset(table, field);
- o_len = field->pack_length();
- n_len = field->pack_length();
-
- col_type = get_innobase_type_from_mysql_type(field);
- is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
-
- switch (col_type) {
-
- case DATA_BLOB:
- o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len);
- n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len);
- break;
- case DATA_VARCHAR:
- case DATA_BINARY:
- case DATA_VARMYSQL:
- o_ptr = row_mysql_read_var_ref_noninline(&o_len, o_ptr);
- n_ptr = row_mysql_read_var_ref_noninline(&n_len, n_ptr);
- default:
- ;
- }
-
- if (field->null_ptr) {
- if (field_in_record_is_null(table, field,
- (char*) old_row)) {
- o_len = UNIV_SQL_NULL;
- }
-
- if (field_in_record_is_null(table, field,
- (char*) new_row)) {
- n_len = UNIV_SQL_NULL;
- }
- }
-
- if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
- 0 != memcmp(o_ptr, n_ptr, o_len))) {
- /* The field has changed */
-
- ufield = uvect->fields + n_changed;
-
- buf = (byte*)
- innobase_convert_and_store_changed_col(ufield,
- (mysql_byte*)buf,
- (mysql_byte*)n_ptr, n_len, col_type,
- is_unsigned);
- ufield->exp = NULL;
- ufield->field_no =
- (prebuilt->table->cols + i)->clust_pos;
- n_changed++;
- }
- ;
- }
-
- uvect->n_fields = n_changed;
- uvect->info_bits = 0;
-
- return(0);
-}
-
-/**************************************************************************
-Updates a row given as a parameter to a new value. Note that we are given
-whole rows, not just the fields which are updated: this incurs some
-overhead for CPU when we check which fields are actually updated.
-TODO: currently InnoDB does not prevent the 'Halloween problem':
-in a searched update a single row can get updated several times
-if its index columns are updated! */
-
-int
-ha_innobase::update_row(
-/*====================*/
- /* out: error number or 0 */
- const mysql_byte* old_row,/* in: old row in MySQL format */
- mysql_byte* new_row)/* in: new row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- upd_t* uvect;
- int error = 0;
-
- DBUG_ENTER("ha_innobase::update_row");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (table->time_stamp) {
- update_timestamp(new_row + table->time_stamp - 1);
- }
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- if (prebuilt->upd_node) {
- uvect = prebuilt->upd_node->update;
- } else {
- uvect = row_get_prebuilt_update_vector(prebuilt);
- }
-
- /* Build an update vector from the modified fields in the rows
- (uses upd_buff of the handle) */
-
- calc_row_difference(uvect, (mysql_byte*) old_row, new_row, table,
- upd_buff, prebuilt, user_thd);
- /* This is not a delete */
- prebuilt->upd_node->is_delete = FALSE;
-
- assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- error = row_update_for_mysql((byte*) old_row, prebuilt);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- error = convert_error_code_to_mysql(error, user_thd);
-
- /* Tell InnoDB server that there might be work for
- utility threads: */
-
- innobase_active_small();
-
- DBUG_RETURN(error);
-}
-
-/**************************************************************************
-Deletes a row given as the parameter. */
-
-int
-ha_innobase::delete_row(
-/*====================*/
- /* out: error number or 0 */
- const mysql_byte* record) /* in: a row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error = 0;
-
- DBUG_ENTER("ha_innobase::delete_row");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- if (!prebuilt->upd_node) {
- row_get_prebuilt_update_vector(prebuilt);
- }
-
- /* This is a delete */
-
- prebuilt->upd_node->is_delete = TRUE;
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- error = row_update_for_mysql((byte*) record, prebuilt);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- error = convert_error_code_to_mysql(error, user_thd);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- innobase_active_small();
-
- DBUG_RETURN(error);
-}
-
-/**********************************************************************
-Initializes a handle to use an index. */
-
-int
-ha_innobase::index_init(
-/*====================*/
- /* out: 0 or error number */
- uint keynr) /* in: key (index) number */
-{
- int error = 0;
- DBUG_ENTER("index_init");
-
- error = change_active_index(keynr);
-
- DBUG_RETURN(error);
-}
-
-/**********************************************************************
-Currently does nothing. */
-
-int
-ha_innobase::index_end(void)
-/*========================*/
-{
- int error = 0;
- DBUG_ENTER("index_end");
-
- DBUG_RETURN(error);
-}
-
-/*************************************************************************
-Converts a search mode flag understood by MySQL to a flag understood
-by InnoDB. */
-inline
-ulint
-convert_search_mode_to_innobase(
-/*============================*/
- enum ha_rkey_function find_flag)
-{
- switch (find_flag) {
- case HA_READ_KEY_EXACT: return(PAGE_CUR_GE);
- /* the above does not require the index to be UNIQUE */
- case HA_READ_KEY_OR_NEXT: return(PAGE_CUR_GE);
- case HA_READ_KEY_OR_PREV: return(PAGE_CUR_LE);
- case HA_READ_AFTER_KEY: return(PAGE_CUR_G);
- case HA_READ_BEFORE_KEY: return(PAGE_CUR_L);
- case HA_READ_PREFIX: return(PAGE_CUR_GE);
- case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE);
- /* the above PREFIX flags mean that the last
- field in the key value may just be a prefix
- of the complete fixed length field */
- default: assert(0);
- }
-
- return(0);
-}
-
-/**************************************************************************
-Positions an index cursor to the index specified in the handle. Fetches the
-row if any. */
-
-int
-ha_innobase::index_read(
-/*====================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND,
- or error number */
- mysql_byte* buf, /* in/out: buffer for the returned
- row */
- const mysql_byte* key_ptr,/* in: key value; if this is NULL
- we position the cursor at the
- start or end of index */
- uint key_len,/* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- ulint mode;
- dict_index_t* index;
- ulint match_mode = 0;
- int error;
- ulint ret;
-
- DBUG_ENTER("index_read");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- statistic_increment(ha_read_key_count, &LOCK_status);
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- index = prebuilt->index;
-
- /* Note that if the select is used for an update, we always
- fetch the clustered index record: therefore the index for which the
- template is built is not necessarily prebuilt->index, but can also
- be the clustered index */
-
- if (prebuilt->sql_stat_start) {
- build_template(prebuilt, user_thd, table,
- ROW_MYSQL_REC_FIELDS);
- }
-
- if (key_ptr) {
- row_sel_convert_mysql_key_to_innobase(prebuilt->search_tuple,
- (byte*) key_val_buff,
- index,
- (byte*) key_ptr,
- (ulint) key_len);
- } else {
- /* We position the cursor to the last or the first entry
- in the index */
-
- dtuple_set_n_fields(prebuilt->search_tuple, 0);
- }
-
- mode = convert_search_mode_to_innobase(find_flag);
-
- match_mode = 0;
-
- if (find_flag == HA_READ_KEY_EXACT) {
- match_mode = ROW_SEL_EXACT;
-
- } else if (find_flag == HA_READ_PREFIX
- || find_flag == HA_READ_PREFIX_LAST) {
- match_mode = ROW_SEL_EXACT_PREFIX;
- }
-
- last_match_mode = match_mode;
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (ret == DB_SUCCESS) {
- error = 0;
- table->status = 0;
-
- } else if (ret == DB_RECORD_NOT_FOUND) {
- error = HA_ERR_KEY_NOT_FOUND;
- table->status = STATUS_NOT_FOUND;
-
- } else if (ret == DB_END_OF_INDEX) {
- error = HA_ERR_KEY_NOT_FOUND;
- table->status = STATUS_NOT_FOUND;
- } else {
- error = convert_error_code_to_mysql(ret, user_thd);
- table->status = STATUS_NOT_FOUND;
- }
-
- DBUG_RETURN(error);
-}
-
-/************************************************************************
-Changes the active index of a handle. */
-
-int
-ha_innobase::change_active_index(
-/*=============================*/
- /* out: 0 or error code */
- uint keynr) /* in: use this index; MAX_KEY means always clustered
- index, even if it was internally generated by
- InnoDB */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- KEY* key=0;
-
- statistic_increment(ha_read_key_count, &LOCK_status);
-
- DBUG_ENTER("index_read_idx");
-
- active_index = keynr;
-
- if (keynr != MAX_KEY && table->keys > 0) {
- key = table->key_info + active_index;
-
- prebuilt->index = dict_table_get_index_noninline(
- prebuilt->table, key->name);
- } else {
- prebuilt->index = dict_table_get_first_index_noninline(
- prebuilt->table);
- }
-
- if (!prebuilt->index) {
- fprintf(stderr,
- "InnoDB: Could not find key n:o %u with name %s from dict cache\n"
- "InnoDB: for table %s\n", keynr, key ? key->name : "NULL", prebuilt->table->name);
-
- return(1);
- }
-
- assert(prebuilt->search_tuple);
-
- dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
-
- dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
- prebuilt->index->n_fields);
-
- /* Maybe MySQL changes the active index for a handle also
- during some queries, we do not know: then it is safest to build
- the template such that all columns will be fetched */
-
- build_template(prebuilt, user_thd, table, ROW_MYSQL_WHOLE_ROW);
-
- return(0);
-}
-
-/**************************************************************************
-Positions an index cursor to the index specified in keynr. Fetches the
-row if any. */
-/* ??? This is only used to read whole keys ??? */
-
-int
-ha_innobase::index_read_idx(
-/*========================*/
- /* out: error number or 0 */
- mysql_byte* buf, /* in/out: buffer for the returned
- row */
- uint keynr, /* in: use this index */
- const mysql_byte* key, /* in: key value; if this is NULL
- we position the cursor at the
- start or end of index */
- uint key_len, /* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
-{
- if (change_active_index(keynr)) {
-
- return(1);
- }
-
- return(index_read(buf, key, key_len, find_flag));
-}
-
-/***************************************************************************
-Reads the next or previous row from a cursor, which must have previously been
-positioned using index_read. */
-
-int
-ha_innobase::general_fetch(
-/*=======================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf, /* in/out: buffer for next row in MySQL
- format */
- uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
- uint match_mode) /* in: 0, ROW_SEL_EXACT, or
- ROW_SEL_EXACT_PREFIX */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- ulint ret;
- int error = 0;
-
- DBUG_ENTER("general_fetch");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode,
- direction);
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (ret == DB_SUCCESS) {
- error = 0;
- table->status = 0;
-
- } else if (ret == DB_RECORD_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- table->status = STATUS_NOT_FOUND;
-
- } else if (ret == DB_END_OF_INDEX) {
- error = HA_ERR_END_OF_FILE;
- table->status = STATUS_NOT_FOUND;
- } else {
- error = convert_error_code_to_mysql(ret, user_thd);
- table->status = STATUS_NOT_FOUND;
- }
-
- DBUG_RETURN(error);
-}
-
-/***************************************************************************
-Reads the next row from a cursor, which must have previously been
-positioned using index_read. */
-
-int
-ha_innobase::index_next(
-/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf) /* in/out: buffer for next row in MySQL
- format */
-{
- statistic_increment(ha_read_next_count, &LOCK_status);
-
- return(general_fetch(buf, ROW_SEL_NEXT, 0));
-}
-
-/***********************************************************************
-Reads the next row matching to the key value given as the parameter. */
-
-int
-ha_innobase::index_next_same(
-/*=========================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf, /* in/out: buffer for the row */
- const mysql_byte* key, /* in: key value */
- uint keylen) /* in: key value length */
-{
- statistic_increment(ha_read_next_count, &LOCK_status);
-
- return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
-}
-
-/***************************************************************************
-Reads the previous row from a cursor, which must have previously been
-positioned using index_read. */
-
-int
-ha_innobase::index_prev(
-/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf) /* in/out: buffer for previous row in MySQL
- format */
-{
- return(general_fetch(buf, ROW_SEL_PREV, 0));
-}
-
-/************************************************************************
-Positions a cursor on the first record in an index and reads the
-corresponding row to buf. */
-
-int
-ha_innobase::index_first(
-/*=====================*/
- /* out: 0, HA_ERR_END_OF_FILE,
- or error code */
- mysql_byte* buf) /* in/out: buffer for the row */
-{
- int error;
-
- DBUG_ENTER("index_first");
- statistic_increment(ha_read_first_count, &LOCK_status);
-
- error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
-
- /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
-
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
-
- DBUG_RETURN(error);
-}
-
-/************************************************************************
-Positions a cursor on the last record in an index and reads the
-corresponding row to buf. */
-
-int
-ha_innobase::index_last(
-/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error code */
- mysql_byte* buf) /* in/out: buffer for the row */
-{
- int error;
-
- DBUG_ENTER("index_first");
- statistic_increment(ha_read_last_count, &LOCK_status);
-
- error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
-
- /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
-
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
-
- DBUG_RETURN(error);
-}
-
-/********************************************************************
-Initialize a table scan. */
-
-int
-ha_innobase::rnd_init(
-/*==================*/
- /* out: 0 or error number */
- bool scan) /* in: ???????? */
-{
- int err;
-
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- if (prebuilt->clust_index_was_generated) {
- err = change_active_index(MAX_KEY);
- } else {
- err = change_active_index(primary_key);
- }
-
- start_of_scan = 1;
-
- return(err);
-}
-
-/*********************************************************************
-Ends a table scan ???????????????? */
-
-int
-ha_innobase::rnd_end(void)
-/*======================*/
- /* out: 0 or error number */
-{
- return(index_end());
-}
-
-/*********************************************************************
-Reads the next row in a table scan (also used to read the FIRST row
-in a table scan). */
-
-int
-ha_innobase::rnd_next(
-/*==================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error number */
- mysql_byte* buf)/* in/out: returns the row in this buffer,
- in MySQL format */
-{
- int error;
-
- DBUG_ENTER("rnd_next");
- statistic_increment(ha_read_rnd_next_count, &LOCK_status);
-
- if (start_of_scan) {
- error = index_first(buf);
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
- start_of_scan = 0;
- } else {
- error = general_fetch(buf, ROW_SEL_NEXT, 0);
- }
-
- DBUG_RETURN(error);
-}
-
-/**************************************************************************
-Fetches a row from the table based on a reference. TODO: currently we use
-'ref_stored_len' of the handle as the key length. This may change. */
-
-int
-ha_innobase::rnd_pos(
-/*=================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND,
- or error code */
- mysql_byte* buf, /* in/out: buffer for the row */
- mysql_byte* pos) /* in: primary key value in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error;
- uint keynr = active_index;
-
- DBUG_ENTER("rnd_pos");
- statistic_increment(ha_read_rnd_count, &LOCK_status);
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (prebuilt->clust_index_was_generated) {
- /* No primary key was defined for the table and we
- generated the clustered index from the row id: the
- row reference is the row id, not any key value
- that MySQL knows */
-
- error = change_active_index(MAX_KEY);
- } else {
- error = change_active_index(primary_key);
- }
-
- if (error) {
- DBUG_RETURN(error);
- }
-
- error = index_read(buf, pos, ref_stored_len, HA_READ_KEY_EXACT);
-
- change_active_index(keynr);
-
- DBUG_RETURN(error);
-}
-
-/*************************************************************************
-Stores a reference to the current row to 'ref' field of the handle. Note
-that the function parameter is illogical: we must assume that 'record'
-is the current 'position' of the handle, because if row ref is actually
-the row id internally generated in InnoDB, then 'record' does not contain
-it. We just guess that the row id must be for the record where the handle
-was positioned the last time. */
-
-void
-ha_innobase::position(
-/*==================*/
- const mysql_byte* record) /* in: row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- uint len;
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (prebuilt->clust_index_was_generated) {
- /* No primary key was defined for the table and we
- generated the clustered index from row id: the
- row reference will be the row id, not any key value
- that MySQL knows */
-
- len = DATA_ROW_ID_LEN;
-
- memcpy(ref, prebuilt->row_id, len);
- } else {
- len = store_key_val_for_row(primary_key, (char*) ref, record);
- }
-
- dbug_assert(len <= ref_length);
-
- ref_stored_len = len;
-}
-
-/*********************************************************************
-Creates a table definition to an InnoDB database. */
-static
-int
-create_table_def(
-/*=============*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
- columns and indexes */
- const char* table_name) /* in: table name */
-{
- Field* field;
- dict_table_t* table;
- ulint n_cols;
- int error;
- ulint col_type;
- ulint nulls_allowed;
- ulint unsigned_type;
- ulint i;
-
- DBUG_ENTER("create_table_def");
- DBUG_PRINT("enter", ("table_name: %s", table_name));
-
- n_cols = form->fields;
-
- /* The '0' below specifies that everything is currently
- created in tablespace 0 */
-
- table = dict_mem_table_create((char*) table_name, 0, n_cols);
-
- for (i = 0; i < n_cols; i++) {
- field = form->field[i];
-
- col_type = get_innobase_type_from_mysql_type(field);
- if (field->null_ptr) {
- nulls_allowed = 0;
- } else {
- nulls_allowed = DATA_NOT_NULL;
- }
-
- if (field->flags & UNSIGNED_FLAG) {
- unsigned_type = DATA_UNSIGNED;
- } else {
- unsigned_type = 0;
- }
-
- dict_mem_table_add_col(table, (char*) field->field_name,
- col_type, (ulint)field->type()
- | nulls_allowed | unsigned_type,
- field->pack_length(), 0);
- }
-
- error = row_create_table_for_mysql(table, trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-Creates an index in an InnoDB database. */
-static
-int
-create_index(
-/*=========*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
- columns and indexes */
- const char* table_name, /* in: table name */
- uint key_num) /* in: index number */
-{
- dict_index_t* index;
- int error;
- ulint n_fields;
- KEY* key;
- KEY_PART_INFO* key_part;
- ulint ind_type;
- ulint i;
-
- DBUG_ENTER("create_index");
-
- key = form->key_info + key_num;
-
- n_fields = key->key_parts;
-
- ind_type = 0;
-
- if (strcmp(key->name, "PRIMARY") == 0) {
- ind_type = ind_type | DICT_CLUSTERED;
- }
-
- if (key->flags & HA_NOSAME ) {
- ind_type = ind_type | DICT_UNIQUE;
- }
-
- /* The '0' below specifies that everything in InnoDB is currently
- created in tablespace 0 */
-
- index = dict_mem_index_create((char*) table_name, key->name, 0,
- ind_type, n_fields);
- for (i = 0; i < n_fields; i++) {
- key_part = key->key_part + i;
-
- /* We assume all fields should be sorted in ascending
- order, hence the '0': */
- dict_mem_index_add_field(index,
- (char*) key_part->field->field_name, 0);
- }
-
- error = row_create_index_for_mysql(index, trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-Creates an index to an InnoDB table when the user has defined no
-primary index. */
-static
-int
-create_clustered_index_when_no_primary(
-/*===================================*/
- trx_t* trx, /* in: InnoDB transaction handle */
- const char* table_name) /* in: table name */
-{
- dict_index_t* index;
- int error;
-
- /* The first '0' below specifies that everything in InnoDB is
- currently created in file space 0 */
-
- index = dict_mem_index_create((char*) table_name,
- (char*) "GEN_CLUST_INDEX",
- 0, DICT_CLUSTERED, 0);
- error = row_create_index_for_mysql(index, trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- return(error);
-}
-
-/*********************************************************************
-Creates a new table to an InnoDB database. */
-
-int
-ha_innobase::create(
-/*================*/
- /* out: error number */
- const char* name, /* in: table name */
- TABLE* form, /* in: information on table
- columns and indexes */
- HA_CREATE_INFO* create_info) /* in: more information of the
- created table, contains also the
- create statement string */
-{
- int error;
- dict_table_t* innobase_table;
- trx_t* trx;
- int primary_key_no = -1;
- KEY* key;
- uint i;
- char name2[FN_REFLEN];
- char norm_name[FN_REFLEN];
-
- DBUG_ENTER("ha_innobase::create");
-
- assert(current_thd != NULL);
-
- trx = trx_allocate_for_mysql();
-
- if (current_thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
- trx->check_foreigns = FALSE;
- }
-
- if (current_thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
- trx->check_unique_secondary = FALSE;
- }
-
- fn_format(name2, name, "", "",2); // Remove the .frm extension
-
- normalize_table_name(norm_name, name2);
-
- /* Latch the InnoDB data dictionary exclusive so that no deadlocks
- or lock waits can happen in it during a table create operation.
- (Drop table etc. do this latching in row0mysql.c.) */
-
- row_mysql_lock_data_dictionary();
-
- /* Create the table definition in InnoDB */
-
- error = create_table_def(trx, form, norm_name);
-
- if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
-
- /* Look for a primary key */
-
- for (i = 0; i < form->keys; i++) {
- key = form->key_info + i;
-
- if (strcmp(key->name, "PRIMARY") == 0) {
- primary_key_no = (int) i;
- }
- }
-
- /* Our function row_get_mysql_key_number_for_index assumes
- the primary key is always number 0, if it exists */
-
- assert(primary_key_no == -1 || primary_key_no == 0);
-
- /* Create the keys */
-
- if (form->keys == 0 || primary_key_no == -1) {
- /* Create an index which is used as the clustered index;
- order the rows by their row id which is internally generated
- by InnoDB */
-
- error = create_clustered_index_when_no_primary(trx,
- norm_name);
- if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
- }
-
- if (primary_key_no != -1) {
- /* In InnoDB the clustered index must always be created
- first */
- if ((error = create_index(trx, form, norm_name,
- (uint) primary_key_no))) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
- }
-
- for (i = 0; i < form->keys; i++) {
-
- if (i != (uint) primary_key_no) {
-
- if ((error = create_index(trx, form, norm_name, i))) {
-
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
- }
- }
-
- error = row_table_add_foreign_constraints(trx,
- create_info->create_statement, norm_name);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
-
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- innobase_table = dict_table_get(norm_name, NULL);
-
- assert(innobase_table);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(0);
-}
-
-/*********************************************************************
-Drops a table from an InnoDB database. Before calling this function,
-MySQL calls innobase_commit to commit the transaction of the current user.
-Then the current user cannot have locks set on the table. Drop table
-operation inside InnoDB will remove all locks any user has on the table
-inside InnoDB. */
-
-int
-ha_innobase::delete_table(
-/*======================*/
- /* out: error number */
- const char* name) /* in: table name */
-{
- ulint name_len;
- int error;
- trx_t* trx;
- char norm_name[1000];
-
- DBUG_ENTER("ha_innobase::delete_table");
-
- trx = trx_allocate_for_mysql();
-
- name_len = strlen(name);
-
- assert(name_len < 1000);
-
- /* Strangely, MySQL passes the table name without the '.frm'
- extension, in contrast to ::create */
-
- normalize_table_name(norm_name, name);
-
- /* Drop the table in InnoDB */
-
- error = row_drop_table_for_mysql(norm_name, trx, FALSE);
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- innobase_commit_low(trx);
-
- trx_free_for_mysql(trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-Removes all tables in the named database inside InnoDB. */
-
-int
-innobase_drop_database(
-/*===================*/
- /* out: error number */
- char* path) /* in: database path; inside InnoDB the name
- of the last directory in the path is used as
- the database name: for example, in 'mysql/data/test'
- the database name is 'test' */
-{
- ulint len = 0;
- trx_t* trx;
- char* ptr;
- int error;
- char namebuf[10000];
-
- ptr = strend(path) - 2;
-
- while (ptr >= path && *ptr != '\\' && *ptr != '/') {
- ptr--;
- len++;
- }
-
- ptr++;
-
- memcpy(namebuf, ptr, len);
- namebuf[len] = '/';
- namebuf[len + 1] = '\0';
-
-#ifdef __WIN__
- /* Put to lower case */
-
- ptr = namebuf;
-
- while (*ptr != '\0') {
- *ptr = tolower(*ptr);
- ptr++;
- }
-#endif
- trx = trx_allocate_for_mysql();
-
- error = row_drop_database_for_mysql(namebuf, trx);
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- innobase_commit_low(trx);
- trx_free_for_mysql(trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- return(error);
-}
-
-/*************************************************************************
-Renames an InnoDB table. */
-
-int
-ha_innobase::rename_table(
-/*======================*/
- /* out: 0 or error code */
- const char* from, /* in: old name of the table */
- const char* to) /* in: new name of the table */
-{
- ulint name_len1;
- ulint name_len2;
- int error;
- trx_t* trx;
- char norm_from[1000];
- char norm_to[1000];
-
- DBUG_ENTER("ha_innobase::rename_table");
-
- trx = trx_allocate_for_mysql();
-
- name_len1 = strlen(from);
- name_len2 = strlen(to);
-
- assert(name_len1 < 1000);
- assert(name_len2 < 1000);
-
- normalize_table_name(norm_from, from);
- normalize_table_name(norm_to, to);
-
- /* Rename the table in InnoDB */
-
- error = row_rename_table_for_mysql(norm_from, norm_to, trx);
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- innobase_commit_low(trx);
- trx_free_for_mysql(trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*************************************************************************
-Estimates the number of index records in a range. */
-
-ha_rows
-ha_innobase::records_in_range(
-/*==========================*/
- /* out: estimated number of rows,
- currently 32-bit int or uint */
- int keynr, /* in: index number */
- const mysql_byte* start_key, /* in: start key value of the
- range, may also be empty */
- uint start_key_len, /* in: start key val len, may
- also be 0 */
- enum ha_rkey_function start_search_flag,/* in: start search condition
- e.g., 'greater than' */
- const mysql_byte* end_key, /* in: range end key val, may
- also be empty */
- uint end_key_len, /* in: range end key val len,
- may also be 0 */
- enum ha_rkey_function end_search_flag)/* in: range end search cond */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- KEY* key;
- dict_index_t* index;
- mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc(
- table->reclength
- + table->max_key_length + 100,
- MYF(MY_WME));
- dtuple_t* range_start;
- dtuple_t* range_end;
- ulint n_rows;
- ulint mode1;
- ulint mode2;
- void* heap1;
- void* heap2;
-
- DBUG_ENTER("records_in_range");
-
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
-
- active_index = keynr;
-
- key = table->key_info + active_index;
-
- index = dict_table_get_index_noninline(prebuilt->table, key->name);
-
- range_start = dtuple_create_for_mysql(&heap1, key->key_parts);
- dict_index_copy_types(range_start, index, key->key_parts);
-
- range_end = dtuple_create_for_mysql(&heap2, key->key_parts);
- dict_index_copy_types(range_end, index, key->key_parts);
-
- row_sel_convert_mysql_key_to_innobase(
- range_start, (byte*) key_val_buff, index,
- (byte*) start_key,
- (ulint) start_key_len);
-
- row_sel_convert_mysql_key_to_innobase(
- range_end, (byte*) key_val_buff2, index,
- (byte*) end_key,
- (ulint) end_key_len);
-
- mode1 = convert_search_mode_to_innobase(start_search_flag);
- mode2 = convert_search_mode_to_innobase(end_search_flag);
-
- n_rows = btr_estimate_n_rows_in_range(index, range_start,
- mode1, range_end, mode2);
- dtuple_free_for_mysql(heap1);
- dtuple_free_for_mysql(heap2);
-
- my_free((char*) key_val_buff2, MYF(0));
-
- DBUG_RETURN((ha_rows) n_rows);
-}
-
-/*************************************************************************
-Gives an UPPER BOUND to the number of rows in a table. This is used in
-filesort.cc and the upper bound must hold. TODO: Since the number of
-rows in a table may change after this function is called, we still may
-get a 'Sort aborted' error in filesort.cc of MySQL. The ultimate fix is to
-improve the algorithm of filesort.cc. */
-
-ha_rows
-ha_innobase::estimate_number_of_rows(void)
-/*======================================*/
- /* out: upper bound of rows */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- dict_index_t* index;
- ulonglong estimate;
- ulonglong data_file_length;
-
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
-
- DBUG_ENTER("info");
-
- index = dict_table_get_first_index_noninline(prebuilt->table);
-
- data_file_length = ((ulonglong) index->stat_n_leaf_pages)
- * UNIV_PAGE_SIZE;
-
- /* Calculate a minimum length for a clustered index record and from
- that an upper bound for the number of rows. Since we only calculate
- new statistics in row0mysql.c when a tablehas grown
- by a threshold factor, we must add a safety factor 2 in front
- of the formula below. */
-
- estimate = 2 * data_file_length / dict_index_calc_min_rec_len(index);
-
- return((ha_rows) estimate);
-}
-
-/*************************************************************************
-How many seeks it will take to read through the table. This is to be
-comparable to the number returned by records_in_range so that we can
-decide if we should scan the table or use keys. */
-
-double
-ha_innobase::scan_time()
-/*====================*/
- /* out: estimated time measured in disk seeks */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- /* Since MySQL seems to favor table scans too much over index
- searches, we pretend that a sequential read takes the same time
- as a random disk read, that is, we do not divide the following
- by 10, which would be physically realistic. */
-
- return((double) (prebuilt->table->stat_clustered_index_size));
-}
-
-/*************************************************************************
-Returns statistics information of the table to the MySQL interpreter,
-in various fields of the handle object. */
-
-void
-ha_innobase::info(
-/*==============*/
- uint flag) /* in: what information MySQL requests */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- dict_table_t* ib_table;
- dict_index_t* index;
- ulong rec_per_key;
- ulong j;
- ulong i;
-
- DBUG_ENTER("info");
-
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
-
- ib_table = prebuilt->table;
-
- if (flag & HA_STATUS_TIME) {
- /* In sql_show we call with this flag: update then statistics
- so that they are up-to-date */
-
- dict_update_statistics(ib_table);
- }
-
- if (flag & HA_STATUS_VARIABLE) {
- records = (ha_rows)ib_table->stat_n_rows;
- deleted = 0;
- data_file_length = ((ulonglong)
- ib_table->stat_clustered_index_size)
- * UNIV_PAGE_SIZE;
- index_file_length = ((ulonglong)
- ib_table->stat_sum_of_other_index_sizes)
- * UNIV_PAGE_SIZE;
- delete_length = 0;
- check_time = 0;
-
- if (records == 0) {
- mean_rec_length = 0;
- } else {
- mean_rec_length = (ulong) (data_file_length / records);
- }
- }
-
- if (flag & HA_STATUS_CONST) {
- index = dict_table_get_first_index_noninline(ib_table);
-
- if (prebuilt->clust_index_was_generated) {
- index = dict_table_get_next_index_noninline(index);
- }
-
- for (i = 0; i < table->keys; i++) {
- for (j = 0; j < table->key_info[i].key_parts; j++) {
-
- if (index->stat_n_diff_key_vals[j + 1] == 0) {
-
- rec_per_key = records;
- } else {
- rec_per_key = (ulong)(records /
- index->stat_n_diff_key_vals[j + 1]);
- }
-
- /* Since MySQL seems to favor table scans
- too much over index searches, we pretend
- index selectivity is 2 times better than
- our estimate: */
-
- rec_per_key = rec_per_key / 2;
-
- if (rec_per_key == 0) {
- rec_per_key = 1;
- }
-
- table->key_info[i].rec_per_key[j]
- = rec_per_key;
- }
-
- index = dict_table_get_next_index_noninline(index);
- }
- }
-
- /* The trx struct in InnoDB contains a pthread mutex embedded:
- in the debug version of MySQL that it replaced by a 'safe mutex'
- which is of a different size. We have to use a function to access
- trx fields. Otherwise trx->error_info will be a random
- pointer and cause a seg fault. */
-
- if (flag & HA_STATUS_ERRKEY) {
- ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
-
- errkey = (unsigned int) row_get_mysql_key_number_for_index(
- (dict_index_t*)
- trx_get_error_info(prebuilt->trx));
- }
-
- DBUG_VOID_RETURN;
-}
-
-/***********************************************************************
-Tries to check that an InnoDB table is not corrupted. If corruption is
-noticed, prints to stderr information about it. In case of corruption
-may also assert a failure and crash the server. */
-
-int
-ha_innobase::check(
-/*===============*/
- /* out: HA_ADMIN_CORRUPT or
- HA_ADMIN_OK */
- THD* thd, /* in: user thread handle */
- HA_CHECK_OPT* check_opt) /* in: check options, currently
- ignored */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- ulint ret;
-
- ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (prebuilt->mysql_template == NULL) {
- /* Build the template; we will use a dummy template
- in index scans done in checking */
-
- build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
- }
-
- ret = row_check_table_for_mysql(prebuilt);
-
- if (ret == DB_SUCCESS) {
- return(HA_ADMIN_OK);
- }
-
- return(HA_ADMIN_CORRUPT);
-}
-
-/*****************************************************************
-Adds information about free space in the InnoDB tablespace to a table comment
-which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
-foreign keys. */
-
-char*
-ha_innobase::update_table_comment(
-/*==============================*/
- /* out: table comment + InnoDB free space +
- info on foreign keys */
- const char* comment)/* in: table comment defined by user */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
- uint length = strlen(comment);
- char* str = my_malloc(length + 550, MYF(0));
- char* pos;
-
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
-
- if (!str) {
- return((char*)comment);
- }
-
- pos = str;
- if (length) {
- pos=strmov(str, comment);
- *pos++=';';
- *pos++=' ';
- }
-
- pos += sprintf(pos, "InnoDB free: %lu kB",
- (ulong) innobase_get_free_space());
-
- /* We assume 450 - length bytes of space to print info */
-
- if (length < 450) {
- dict_print_info_on_foreign_keys(FALSE, pos, 450 - length,
- prebuilt->table);
- }
-
- return(str);
-}
-
-/***********************************************************************
-Gets the foreign key create info for a table stored in InnoDB. */
-
-char*
-ha_innobase::get_foreign_key_create_info(void)
-/*==========================================*/
- /* out, own: character string in the form which
- can be inserted to the CREATE TABLE statement,
- MUST be freed with ::free_foreign_key_create_info */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
- char* str;
-
- if (prebuilt == NULL) {
- fprintf(stderr,
-"InnoDB: Error: cannot get create info for foreign keys\n");
-
- return(NULL);
- }
-
- str = (char*)ut_malloc(10000);
-
- str[0] = '\0';
-
- dict_print_info_on_foreign_keys(TRUE, str, 9000, prebuilt->table);
-
- return(str);
-}
-
-/***********************************************************************
-Frees the foreign key create info for a table stored in InnoDB, if it is
-non-NULL. */
-
-void
-ha_innobase::free_foreign_key_create_info(
-/*======================================*/
- char* str) /* in, own: create info string to free */
-{
- if (str) {
- ut_free(str);
- }
-}
-
-/***********************************************************************
-Tells something additional to the handler about how to do things. */
-
-int
-ha_innobase::extra(
-/*===============*/
- /* out: 0 or error number */
- enum ha_extra_function operation)
- /* in: HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
-
- switch (operation) {
- case HA_EXTRA_RESET:
- case HA_EXTRA_RESET_STATE:
- prebuilt->read_just_key = 0;
- break;
- case HA_EXTRA_NO_KEYREAD:
- prebuilt->read_just_key = 0;
- break;
- case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
- break;
- case HA_EXTRA_KEYREAD:
- prebuilt->read_just_key = 1;
- break;
- default:/* Do nothing */
- ;
- }
-
- return(0);
-}
-
-/**********************************************************************
-????????????? */
-
-int
-ha_innobase::reset(void)
-/*====================*/
-{
- return(0);
-}
-
-/**********************************************************************
-As MySQL will execute an external lock for every new table it uses when it
-starts to process an SQL statement, we can use this function to store the
-pointer to the THD in the handle. We will also use this function to communicate
-to InnoDB that a new SQL statement has started and that we must store a
-savepoint to our transaction handle, so that we are able to roll back
-the SQL statement in case of an error. */
-
-int
-ha_innobase::external_lock(
-/*=======================*/
- THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error = 0;
- trx_t* trx;
-
- DBUG_ENTER("ha_innobase::external_lock");
-
- update_thd(thd);
-
- trx = prebuilt->trx;
-
- prebuilt->sql_stat_start = TRUE;
- prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
-
- prebuilt->read_just_key = 0;
-
- if (lock_type == F_WRLCK) {
-
- /* If this is a SELECT, then it is in UPDATE TABLE ...
- or SELECT ... FOR UPDATE */
- prebuilt->select_lock_type = LOCK_X;
- }
-
- if (lock_type != F_UNLCK) {
- if (trx->n_mysql_tables_in_use == 0) {
- trx_mark_sql_stat_end(trx);
- }
-
- thd->transaction.all.innodb_active_trans = 1;
- trx->n_mysql_tables_in_use++;
-
- if (thd->tx_isolation == ISO_SERIALIZABLE
- && prebuilt->select_lock_type == LOCK_NONE) {
-
- /* To get serializable execution we let InnoDB
- conceptually add 'LOCK IN SHARE MODE' to all SELECTs
- which otherwise would have been consistent reads */
-
- prebuilt->select_lock_type = LOCK_S;
- }
-
- if (prebuilt->select_lock_type != LOCK_NONE) {
-
- trx->mysql_n_tables_locked++;
- }
- } else {
- trx->n_mysql_tables_in_use--;
- auto_inc_counter_for_this_stat = 0;
-
- if (trx->n_mysql_tables_in_use == 0) {
-
- trx->mysql_n_tables_locked = 0;
-
- /* Here we release the search latch, auto_inc_lock,
- and InnoDB thread FIFO ticket if they were reserved. */
-
- innobase_release_stat_resources(trx);
-
- if (!(thd->options
- & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) {
-
- innobase_commit(thd, trx);
- }
- }
- }
-
- DBUG_RETURN(error);
-}
-
-/****************************************************************************
-Implements the SHOW INNODB STATUS command. Send the output of the InnoDB
-Monitor to the client. */
-
-int
-innodb_show_status(
-/*===============*/
- THD* thd) /* in: the MySQL query thread of the caller */
-{
- String* packet = &thd->packet;
- char* buf;
-
- DBUG_ENTER("innodb_show_status");
-
- /* We let the InnoDB Monitor to output at most 100 kB of text */
- buf = (char*)ut_malloc(100 * 1024);
-
- srv_sprintf_innodb_monitor(buf, 100 * 1024);
-
- List<Item> field_list;
-
- field_list.push_back(new Item_empty_string("Status", strlen(buf)));
-
- if(send_fields(thd, field_list, 1)) {
- DBUG_RETURN(-1);
- }
-
- packet->length(0);
-
- net_store_data(packet, buf);
-
- if (my_net_write(&thd->net, (char*)thd->packet.ptr(),
- packet->length())) {
- ut_free(buf);
-
- DBUG_RETURN(-1);
- }
-
- ut_free(buf);
-
- send_eof(&thd->net);
-
- DBUG_RETURN(0);
-}
-
-/****************************************************************************
- Handling the shared INNOBASE_SHARE structure that is needed to provide table
- locking.
-****************************************************************************/
-
-static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)))
-{
- *length=share->table_name_length;
- return (mysql_byte*) share->table_name;
-}
-
-static INNOBASE_SHARE *get_share(const char *table_name)
-{
- INNOBASE_SHARE *share;
- pthread_mutex_lock(&innobase_mutex);
- uint length=(uint) strlen(table_name);
- if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
- (mysql_byte*) table_name,
- length)))
- {
- if ((share=(INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
- MYF(MY_WME | MY_ZEROFILL))))
- {
- share->table_name_length=length;
- share->table_name=(char*) (share+1);
- strmov(share->table_name,table_name);
- if (hash_insert(&innobase_open_tables, (mysql_byte*) share))
- {
- pthread_mutex_unlock(&innobase_mutex);
- my_free((gptr) share,0);
- return 0;
- }
- thr_lock_init(&share->lock);
- pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
- }
- }
- share->use_count++;
- pthread_mutex_unlock(&innobase_mutex);
- return share;
-}
-
-static void free_share(INNOBASE_SHARE *share)
-{
- pthread_mutex_lock(&innobase_mutex);
- if (!--share->use_count)
- {
- hash_delete(&innobase_open_tables, (mysql_byte*) share);
- thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
- my_free((gptr) share, MYF(0));
- }
- pthread_mutex_unlock(&innobase_mutex);
-}
-
-/*********************************************************************
-Stores a MySQL lock into a 'lock' field in a handle. */
-
-THR_LOCK_DATA**
-ha_innobase::store_lock(
-/*====================*/
- /* out: pointer to the next
- element in the 'to' array */
- THD* thd, /* in: user thread handle */
- THR_LOCK_DATA** to, /* in: pointer to an array
- of pointers to lock structs;
- pointer to the 'lock' field
- of current handle is stored
- next to this array */
- enum thr_lock_type lock_type) /* in: lock type to store in
- 'lock' */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- if (lock_type == TL_READ_WITH_SHARED_LOCKS ||
- lock_type == TL_READ_NO_INSERT) {
- /* This is a SELECT ... IN SHARE MODE, or
- we are doing a complex SQL statement like
- INSERT INTO ... SELECT ... and the logical logging (MySQL
- binlog) requires the use of a locking read */
-
- prebuilt->select_lock_type = LOCK_S;
- } else {
- /* We set possible LOCK_X value in external_lock, not yet
- here even if this would be SELECT ... FOR UPDATE */
-
- prebuilt->select_lock_type = LOCK_NONE;
- }
-
- if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
-
- /* If we are not doing a LOCK TABLE, then allow multiple
- writers */
-
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) && !thd->in_lock_tables) {
-
- lock_type = TL_WRITE_ALLOW_WRITE;
- }
-
- lock.type=lock_type;
- }
-
- *to++= &lock;
-
- return(to);
-}
-
-/***********************************************************************
-Returns the next auto-increment column value for the table. write_row
-normally fetches the value from the cache in the data dictionary. This
-function in used by SHOW TABLE STATUS and when the first insert to the table
-is done after database startup. */
-
-longlong
-ha_innobase::get_auto_increment()
-/*=============================*/
- /* out: the next auto-increment column value */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- longlong nr;
- int error;
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- /* Also SHOW TABLE STATUS calls this function. Previously, when we did
- always read the max autoinc key value, setting x-locks, users were
- surprised that SHOW TABLE STATUS could end up in a deadlock with
- ordinary SQL queries. We avoid these deadlocks if the auto-inc
- counter for the table has been initialized by fetching the value
- from the table struct in dictionary cache. */
-
- assert(prebuilt->table);
-
- nr = dict_table_autoinc_read(prebuilt->table);
-
- if (nr != 0) {
-
- return(nr + 1);
- }
-
- (void) extra(HA_EXTRA_KEYREAD);
- index_init(table->next_number_index);
-
- /* We use an exclusive lock when we read the max key value from the
- auto-increment column index. This is because then build_template will
- advise InnoDB to fetch all columns. In SHOW TABLE STATUS the query
- id of the auto-increment column is not changed, and previously InnoDB
- did not fetch it, causing SHOW TABLE STATUS to show wrong values
- for the autoinc column. */
-
- prebuilt->select_lock_type = LOCK_X;
-
- /* Play safe and also give in another way the hint to fetch
- all columns in the key: */
-
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
-
- prebuilt->trx->mysql_n_tables_locked += 1;
-
- error = index_last(table->record[1]);
-
- if (error) {
- nr = 1;
- } else {
- nr = (longlong) table->next_number_field->
- val_int_offset(table->rec_buff_length) + 1;
- }
-
- (void) extra(HA_EXTRA_NO_KEYREAD);
-
- index_end();
-
- return(nr);
-}
-
-#endif /* HAVE_INNOBASE_DB */
diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h
deleted file mode 100644
index aa497132b25..00000000000
--- a/sql/ha_innobase.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
- && Innobase Oy
-
- -This file is modified from ha_berkeley.h of MySQL distribution-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-/* This file defines the Innobase handler: the interface between MySQL and
-Innobase */
-
-typedef struct st_innobase_share {
- THR_LOCK lock;
- pthread_mutex_t mutex;
- char *table_name;
- uint table_name_length,use_count;
-} INNOBASE_SHARE;
-
-
-/* The class defining a handle to an Innobase table */
-class ha_innobase: public handler
-{
- void* innobase_prebuilt; /* (row_prebuilt_t*) prebuilt
- struct in Innobase, used to save
- CPU */
- THD* user_thd; /* the thread handle of the user
- currently using the handle; this is
- set in external_lock function */
- ulong last_query_id; /* the latest query id where the
- handle was used */
- THR_LOCK_DATA lock;
- INNOBASE_SHARE *share;
-
- gptr alloc_ptr;
- byte* upd_buff; /* buffer used in updates */
- byte* key_val_buff; /* buffer used in converting
- search key values from MySQL format
- to Innobase format */
- uint ref_stored_len; /* length of the key value stored to
- 'ref' buffer of the handle, if any */
- ulong int_option_flag;
- uint primary_key;
- uint last_dup_key;
- ulong start_of_scan; /* this is set to 1 when we are
- starting a table scan but have not
- yet fetched any row, else 0 */
-
- uint last_match_mode;/* match mode of the latest search:
- ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
- or undefined */
- longlong auto_inc_counter_for_this_stat;
- ulong max_row_length(const byte *buf);
-
- uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
- int update_thd(THD* thd);
- int change_active_index(uint keynr);
- int general_fetch(byte* buf, uint direction, uint match_mode);
-
- /* Init values for the class: */
- public:
- ha_innobase(TABLE *table): handler(table),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER |
- HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
- HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_NULL_KEY |
- HA_NOT_EXACT_COUNT | HA_NO_FULLTEXT_KEY |
- HA_NO_WRITE_DELAYED |
- HA_PRIMARY_KEY_IN_READ_INDEX |
- HA_DROP_BEFORE_CREATE |
- HA_NO_PREFIX_CHAR_KEYS),
- last_dup_key((uint) -1),
- start_of_scan(0)
- {
- }
- ~ha_innobase() {}
-
- const char* table_type() const { return("InnoDB");}
- const char** bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return MAX_KEY; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- /* An InnoDB page must store >= 2 keys;
- a secondary key record must also contain the
- primary key value:
- max key length is therefore set to slightly
- less than 1 / 4 of page size which is 16 kB;
- but currently MySQL does not work with keys
- whose size is > MAX_KEY_LENGTH */
- uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
- MAX_KEY_LENGTH : 3500);}
- bool fast_key_read() { return 1;}
- key_map keys_to_use_for_scanning() { return ~(key_map) 0; }
- bool has_transactions() { return 1;}
-
- int open(const char *name, int mode, uint test_if_locked);
- void initialize(void);
- int close(void);
- double scan_time();
-
- int write_row(byte * buf);
- int update_row(const byte * old_data, byte * new_data);
- int delete_row(const byte * buf);
-
- int index_init(uint index);
- int index_end();
- int index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_read_idx(byte * buf, uint index, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_next(byte * buf);
- int index_next_same(byte * buf, const byte *key, uint keylen);
- int index_prev(byte * buf);
- int index_first(byte * buf);
- int index_last(byte * buf);
-
- int rnd_init(bool scan=1);
- int rnd_end();
- int rnd_next(byte *buf);
- int rnd_pos(byte * buf, byte *pos);
-
- void position(const byte *record);
- void info(uint);
- int extra(enum ha_extra_function operation);
- int reset(void);
- int external_lock(THD *thd, int lock_type);
- void position(byte *record);
- ha_rows records_in_range(int inx,
- const byte *start_key,uint start_key_len,
- enum ha_rkey_function start_search_flag,
- const byte *end_key,uint end_key_len,
- enum ha_rkey_function end_search_flag);
- ha_rows estimate_number_of_rows();
-
- int create(const char *name, register TABLE *form,
- HA_CREATE_INFO *create_info);
- int delete_table(const char *name);
- int rename_table(const char* from, const char* to);
- int check(THD* thd, HA_CHECK_OPT* check_opt);
- char* update_table_comment(const char* comment);
- char* get_foreign_key_create_info();
- void free_foreign_key_create_info(char* str);
- THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type);
- longlong get_auto_increment();
-};
-
-extern bool innodb_skip;
-extern SHOW_COMP_OPTION have_innodb;
-extern uint innobase_init_flags, innobase_lock_type;
-extern ulong innobase_cache_size;
-extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
-extern long innobase_lock_scan_time;
-extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
-extern long innobase_log_file_size, innobase_log_buffer_size;
-extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
-extern long innobase_file_io_threads, innobase_lock_wait_timeout;
-extern long innobase_force_recovery, innobase_thread_concurrency;
-extern char *innobase_data_home_dir, *innobase_data_file_path;
-extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
-extern char *innobase_unix_file_flush_method;
-/* The following variables have to be my_bool for SHOW VARIABLES to work */
-extern my_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
- innobase_use_native_aio, innobase_fast_shutdown;
-
-extern TYPELIB innobase_lock_typelib;
-
-bool innobase_init(void);
-bool innobase_end(void);
-bool innobase_flush_logs(void);
-uint innobase_get_free_space(void);
-
-int innobase_commit(THD *thd, void* trx_handle);
-int innobase_report_binlog_offset_and_commit(
- THD* thd,
- void* trx_handle,
- char* log_file_name,
- my_off_t end_offset);
-int innobase_rollback(THD *thd, void* trx_handle);
-int innobase_close_connection(THD *thd);
-int innobase_drop_database(char *path);
-int innodb_show_status(THD* thd);
-
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
new file mode 100644
index 00000000000..11ebc108874
--- /dev/null
+++ b/sql/ha_innodb.cc
@@ -0,0 +1,3587 @@
+/* Copyright (C) 2000 MySQL AB & InnoDB Oy
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ This file defines the InnoDB handler: the interface between MySQL and InnoDB */
+
+/* TODO list for the InnoDB handler:
+ - Ask Monty if strings of different languages can exist in the same
+ database. Answer: in near future yes, but not yet.
+*/
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "slave.h"
+#ifdef HAVE_INNOBASE_DB
+#include <m_ctype.h>
+#include <assert.h>
+#include <hash.h>
+#include <myisampack.h>
+
+#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
+
+#include "ha_innodb.h"
+
+/* We must declare this here because we undef SAFE_MUTEX below */
+pthread_mutex_t innobase_mutex;
+
+/* Store MySQL definition of 'byte': in Linux it is char while InnoDB
+uses unsigned char */
+typedef byte mysql_byte;
+
+#ifdef SAFE_MUTEX
+#undef pthread_mutex_t
+#endif
+
+#define INSIDE_HA_INNOBASE_CC
+
+/* Include necessary InnoDB headers */
+extern "C" {
+#include "../innobase/include/univ.i"
+#include "../innobase/include/os0file.h"
+#include "../innobase/include/srv0start.h"
+#include "../innobase/include/srv0srv.h"
+#include "../innobase/include/trx0roll.h"
+#include "../innobase/include/trx0trx.h"
+#include "../innobase/include/trx0sys.h"
+#include "../innobase/include/row0ins.h"
+#include "../innobase/include/row0mysql.h"
+#include "../innobase/include/row0sel.h"
+#include "../innobase/include/row0upd.h"
+#include "../innobase/include/log0log.h"
+#include "../innobase/include/lock0lock.h"
+#include "../innobase/include/dict0crea.h"
+#include "../innobase/include/btr0cur.h"
+#include "../innobase/include/btr0btr.h"
+#include "../innobase/include/fsp0fsp.h"
+}
+
+#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
+#define HA_INNOBASE_RANGE_COUNT 100
+
+bool innodb_skip = 0;
+uint innobase_init_flags = 0;
+ulong innobase_cache_size = 0;
+
+/* The default values for the following, type long, start-up parameters
+are declared in mysqld.cc: */
+
+long innobase_mirrored_log_groups, innobase_log_files_in_group,
+ innobase_log_file_size, innobase_log_buffer_size,
+ innobase_buffer_pool_size, innobase_additional_mem_pool_size,
+ innobase_file_io_threads, innobase_lock_wait_timeout,
+ innobase_thread_concurrency, innobase_force_recovery;
+
+/* The default values for the following char* start-up parameters
+are determined in innobase_init below: */
+
+char* innobase_data_home_dir = NULL;
+char* innobase_log_group_home_dir = NULL;
+char* innobase_log_arch_dir = NULL;
+char* innobase_unix_file_flush_method = NULL;
+
+/* Below we have boolean-valued start-up parameters, and their default
+values */
+
+my_bool innobase_flush_log_at_trx_commit = FALSE;
+my_bool innobase_log_archive = FALSE;
+my_bool innobase_use_native_aio = FALSE;
+my_bool innobase_fast_shutdown = TRUE;
+
+/*
+ Set default InnoDB data file size to 10 MB and let it be
+ auto-extending. Thus users can use InnoDB without having to
+ specify any startup options.
+*/
+
+/* innobase_data_file_path=ibdata:15,idata2:1,... */
+
+char *innobase_data_file_path= (char*) "ibdata1:10M:autoextend";
+static char *internal_innobase_data_file_path=0;
+
+/* The following counter is used to convey information to InnoDB
+about server activity: in selects it is not sensible to call
+srv_active_wake_master_thread after each fetch or search, we only do
+it every INNOBASE_WAKE_INTERVAL'th step. */
+
+#define INNOBASE_WAKE_INTERVAL 32
+ulong innobase_active_counter = 0;
+
+char* innobase_home = NULL;
+
+char innodb_dummy_stmt_trx_handle = 'D';
+
+static HASH innobase_open_tables;
+
+static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
+ my_bool not_used __attribute__((unused)));
+static INNOBASE_SHARE *get_share(const char *table_name);
+static void free_share(INNOBASE_SHARE *share);
+static void innobase_print_error(const char* db_errpfx, char* buffer);
+
+/* General functions */
+
+/**********************************************************************
+Releases possible search latch, auto inc lock, and InnoDB thread FIFO ticket.
+These should be released at each SQL statement end. */
+static
+void
+innobase_release_stat_resources(
+/*============================*/
+ trx_t* trx) /* in: transaction object */
+{
+ if (trx->has_search_latch) {
+ trx_search_latch_release_if_reserved(trx);
+ }
+
+ if (trx->auto_inc_lock) {
+
+ /* If we had reserved the auto-inc lock for
+ some table in this SQL statement, we release it now */
+
+ srv_conc_enter_innodb(trx);
+ row_unlock_table_autoinc_for_mysql(trx);
+ srv_conc_exit_innodb(trx);
+ }
+
+ if (trx->declared_to_be_inside_innodb) {
+ /* Release our possible ticket in the FIFO */
+
+ srv_conc_force_exit_innodb(trx);
+ }
+}
+
+/************************************************************************
+Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
+time calls srv_active_wake_master_thread. This function should be used
+when a single database operation may introduce a small need for
+server utility activity, like checkpointing. */
+inline
+void
+innobase_active_small(void)
+/*=======================*/
+{
+ innobase_active_counter++;
+
+ if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
+ srv_active_wake_master_thread();
+ }
+}
+
+/************************************************************************
+Converts an InnoDB error code to a MySQL error code. */
+static
+int
+convert_error_code_to_mysql(
+/*========================*/
+ /* out: MySQL error code */
+ int error, /* in: InnoDB error code */
+ THD* thd) /* in: user thread handle or NULL */
+{
+ if (error == DB_SUCCESS) {
+
+ return(0);
+
+ } else if (error == (int) DB_DUPLICATE_KEY) {
+
+ return(HA_ERR_FOUND_DUPP_KEY);
+
+ } else if (error == (int) DB_RECORD_NOT_FOUND) {
+
+ return(HA_ERR_NO_ACTIVE_RECORD);
+
+ } else if (error == (int) DB_ERROR) {
+
+ return(HA_ERR_NO_ACTIVE_RECORD);
+
+ } else if (error == (int) DB_DEADLOCK) {
+ /* Since we roll back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
+
+ if (thd) {
+ ha_rollback(thd);
+ }
+
+ return(HA_ERR_LOCK_DEADLOCK);
+
+ } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
+
+ /* Since we roll back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
+
+
+ if (thd) {
+ ha_rollback(thd);
+ }
+
+ return(HA_ERR_LOCK_WAIT_TIMEOUT);
+
+ } else if (error == (int) DB_NO_REFERENCED_ROW) {
+
+ return(HA_ERR_NO_REFERENCED_ROW);
+
+ } else if (error == (int) DB_ROW_IS_REFERENCED) {
+
+ return(HA_ERR_ROW_IS_REFERENCED);
+
+ } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
+
+ return(HA_ERR_CANNOT_ADD_FOREIGN);
+
+ } else if (error == (int) DB_OUT_OF_FILE_SPACE) {
+
+ return(HA_ERR_RECORD_FILE_FULL);
+
+ } else if (error == (int) DB_TABLE_IS_BEING_USED) {
+
+ return(HA_ERR_WRONG_COMMAND);
+
+ } else if (error == (int) DB_TABLE_NOT_FOUND) {
+
+ return(HA_ERR_KEY_NOT_FOUND);
+
+ } else if (error == (int) DB_TOO_BIG_RECORD) {
+
+ return(HA_ERR_TO_BIG_ROW);
+ } else {
+ return(-1); // Unknown error
+ }
+}
+
+extern "C" {
+/*****************************************************************
+Prints info of a THD object (== user session thread) to the
+standard output. NOTE that mysql/innobase/trx/trx0trx.c must contain
+the prototype for this function! */
+
+void
+innobase_mysql_print_thd(
+/*=====================*/
+ char* buf, /* in/out: buffer where to print, must be at least
+ 300 bytes */
+ void* input_thd)/* in: pointer to a MySQL THD object */
+{
+ THD* thd;
+
+ thd = (THD*) input_thd;
+
+ /* We can't use value of sprintf() as this is not portable */
+ sprintf(buf, "MySQL thread id %lu, query id %lu",
+ thd->thread_id, thd->query_id);
+ buf=strend(buf);
+
+ if (thd->host)
+ {
+ *buf++=' ';
+ buf=strnmov(buf, thd->host, 30);
+ }
+
+ if (thd->ip)
+ {
+ *buf++=' ';
+ buf=strnmov(buf, thd->ip, 20);
+ }
+
+ if (thd->user)
+ {
+ *buf++=' ';
+ buf=strnmov(buf, thd->user, 20);
+ }
+
+ if (thd->proc_info)
+ {
+ *buf++=' ';
+ buf=strnmov(buf, thd->procinfo, 50);
+ }
+
+ if (thd->query)
+ {
+ *buf++=' ';
+ buf=strnmov(buf, thd->query, 150);
+ }
+ *buf='\n';
+}
+}
+
+/*************************************************************************
+Gets the InnoDB transaction handle for a MySQL handler object, creates
+an InnoDB transaction struct if the corresponding MySQL thread struct still
+lacks one. */
+static
+trx_t*
+check_trx_exists(
+/*=============*/
+ /* out: InnoDB transaction handle */
+ THD* thd) /* in: user thread handle */
+{
+ trx_t* trx;
+
+ ut_a(thd == current_thd);
+
+ trx = (trx_t*) thd->transaction.all.innobase_tid;
+
+ if (trx == NULL) {
+ DBUG_ASSERT(thd != NULL);
+ trx = trx_allocate_for_mysql();
+
+ trx->mysql_thd = thd;
+
+ thd->transaction.all.innobase_tid = trx;
+
+ /* The execution of a single SQL statement is denoted by
+ a 'transaction' handle which is a dummy pointer: InnoDB
+ remembers internally where the latest SQL statement
+ started, and if error handling requires rolling back the
+ latest statement, InnoDB does a rollback to a savepoint. */
+
+ thd->transaction.stmt.innobase_tid =
+ (void*)&innodb_dummy_stmt_trx_handle;
+ } else {
+ if (trx->magic_n != TRX_MAGIC_N) {
+ mem_analyze_corruption((byte*)trx);
+
+ ut_a(0);
+ }
+ }
+
+ if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ trx->check_foreigns = FALSE;
+ } else {
+ trx->check_foreigns = TRUE;
+ }
+
+ if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ trx->check_unique_secondary = FALSE;
+ } else {
+ trx->check_unique_secondary = TRUE;
+ }
+
+ return(trx);
+}
+
+/*************************************************************************
+Updates the user_thd field in a handle and also allocates a new InnoDB
+transaction handle if needed, and updates the transaction fields in the
+prebuilt struct. */
+inline
+int
+ha_innobase::update_thd(
+/*====================*/
+ /* out: 0 or error code */
+ THD* thd) /* in: thd to use the handle */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ trx_t* trx;
+
+ trx = check_trx_exists(thd);
+
+ if (prebuilt->trx != trx) {
+
+ row_update_prebuilt_trx(prebuilt, trx);
+ }
+
+ user_thd = thd;
+
+ return(0);
+}
+
+/*************************************************************************
+Opens an InnoDB database. */
+
+bool
+innobase_init(void)
+/*===============*/
+ /* out: TRUE if error */
+{
+ static char current_dir[3]; // Set if using current lib
+ int err;
+ bool ret;
+ char *default_path;
+
+ DBUG_ENTER("innobase_init");
+
+ os_innodb_umask = (ulint)my_umask;
+
+ /*
+ When using the embedded server, the datadirectory is not
+ in the current directory.
+ */
+ if (mysql_embedded)
+ default_path=mysql_real_data_home;
+ else
+ {
+ /* It's better to use current lib, to keep path's short */
+ current_dir[0] = FN_CURLIB;
+ current_dir[1] = FN_LIBCHAR;
+ current_dir[2] = 0;
+ default_path=current_dir;
+ }
+
+ if (specialflag & SPECIAL_NO_PRIOR) {
+ srv_set_thread_priorities = FALSE;
+ } else {
+ srv_set_thread_priorities = TRUE;
+ srv_query_thread_priority = QUERY_PRIOR;
+ }
+
+ /*
+ Set InnoDB initialization parameters according to the values
+ read from MySQL .cnf file
+ */
+
+ // Make a copy of innobase_data_file_path to not modify the original
+ internal_innobase_data_file_path=my_strdup(innobase_data_file_path,
+ MYF(MY_WME));
+
+ srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
+ default_path);
+ srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir :
+ default_path);
+
+ ret = (bool)
+ srv_parse_data_file_paths_and_sizes(internal_innobase_data_file_path,
+ &srv_data_file_names,
+ &srv_data_file_sizes,
+ &srv_data_file_is_raw_partition,
+ &srv_n_data_files,
+ &srv_auto_extend_last_data_file,
+ &srv_last_file_size_max);
+ if (ret == FALSE) {
+ sql_print_error("InnoDB: syntax error in innodb_data_file_path");
+ DBUG_RETURN(TRUE);
+ }
+
+ if (!innobase_log_group_home_dir)
+ innobase_log_group_home_dir= default_path;
+
+ ret = (bool)
+ srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
+ &srv_log_group_home_dirs);
+
+ if (ret == FALSE || innobase_mirrored_log_groups != 1) {
+ fprintf(stderr,
+ "InnoDB: syntax error in innodb_log_group_home_dir\n"
+ "InnoDB: or a wrong number of mirrored log groups\n");
+
+ DBUG_RETURN(TRUE);
+ }
+ srv_unix_file_flush_method_str = (innobase_unix_file_flush_method ?
+ innobase_unix_file_flush_method :
+ (char*)"fdatasync");
+
+ srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
+ srv_n_log_files = (ulint) innobase_log_files_in_group;
+ srv_log_file_size = (ulint) innobase_log_file_size;
+
+ srv_log_archive_on = (ulint) innobase_log_archive;
+ srv_log_buffer_size = (ulint) innobase_log_buffer_size;
+ srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
+
+ srv_use_native_aio = 0;
+
+ srv_pool_size = (ulint) innobase_buffer_pool_size;
+
+ srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
+
+ srv_n_file_io_threads = (ulint) innobase_file_io_threads;
+
+ srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
+ srv_thread_concurrency = (ulint) innobase_thread_concurrency;
+ srv_force_recovery = (ulint) innobase_force_recovery;
+
+ srv_fast_shutdown = (ibool) innobase_fast_shutdown;
+
+ srv_print_verbose_log = mysql_embedded ? 0 : 1;
+ if (strcmp(default_charset_info->name, "latin1") == 0) {
+ /* Store the character ordering table to InnoDB.
+ For non-latin1 charsets we use the MySQL comparison
+ functions, and consequently we do not need to know
+ the ordering internally in InnoDB. */
+
+ memcpy(srv_latin1_ordering,
+ default_charset_info->sort_order, 256);
+ }
+
+ err = innobase_start_or_create_for_mysql();
+
+ if (err != DB_SUCCESS) {
+
+ DBUG_RETURN(1);
+ }
+
+ (void) hash_init(&innobase_open_tables,32,0,0,
+ (hash_get_key) innobase_get_key,0,0);
+ pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST);
+
+ /* If this is a replication slave and we needed to do a crash recovery,
+ set the master binlog position to what InnoDB internally knew about
+ how far we got transactions durable inside InnoDB. There is a
+ problem here: if the user used also MyISAM tables, InnoDB might not
+ know the right position for them.
+
+ THIS DOES NOT WORK CURRENTLY because replication seems to initialize
+ glob_mi also after innobase_init. */
+
+/* if (trx_sys_mysql_master_log_pos != -1) {
+ ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name,
+ 1 + ut_strlen(trx_sys_mysql_master_log_name));
+ glob_mi.pos = trx_sys_mysql_master_log_pos;
+ }
+*/
+ DBUG_RETURN(0);
+}
+
+/***********************************************************************
+Closes an InnoDB database. */
+
+bool
+innobase_end(void)
+/*==============*/
+ /* out: TRUE if error */
+{
+ int err;
+
+ DBUG_ENTER("innobase_end");
+
+ err = innobase_shutdown_for_mysql();
+ hash_free(&innobase_open_tables);
+ my_free(internal_innobase_data_file_path,MYF(MY_ALLOW_ZERO_PTR));
+
+ if (err != DB_SUCCESS) {
+
+ DBUG_RETURN(1);
+ }
+
+ DBUG_RETURN(0);
+}
+
+/********************************************************************
+Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit
+flushes logs, and the name of this function should be innobase_checkpoint. */
+
+bool
+innobase_flush_logs(void)
+/*=====================*/
+ /* out: TRUE if error */
+{
+ bool result = 0;
+
+ DBUG_ENTER("innobase_flush_logs");
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
+ DBUG_RETURN(result);
+}
+
+/*************************************************************************
+Gets the free space in an InnoDB database: returned in units of kB. */
+
+uint
+innobase_get_free_space(void)
+/*=========================*/
+ /* out: free space in kB */
+{
+ return((uint) fsp_get_available_space_in_free_extents(0));
+}
+
+/*********************************************************************
+Commits a transaction in an InnoDB database. */
+
+void
+innobase_commit_low(
+/*================*/
+ trx_t* trx) /* in: transaction handle */
+{
+ if (current_thd->slave_thread) {
+
+ /* Update the replication position info inside InnoDB */
+
+ trx->mysql_master_log_file_name = glob_mi.log_file_name;
+ trx->mysql_master_log_pos = (ib_longlong)
+ (glob_mi.pos + glob_mi.event_len
+ + glob_mi.pending);
+ }
+
+ trx_commit_for_mysql(trx);
+}
+
+/*********************************************************************
+Commits a transaction in an InnoDB database. */
+
+int
+innobase_commit(
+/*============*/
+ /* out: 0 or error number */
+ THD* thd, /* in: MySQL thread handle of the user for whom
+ the transaction should be committed */
+ void* trx_handle)/* in: InnoDB trx handle or NULL: NULL means
+ that the current SQL statement ended, and we should
+ mark the start of a new statement with a savepoint */
+{
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("innobase_commit");
+ DBUG_PRINT("trans", ("ending transaction"));
+
+ trx = check_trx_exists(thd);
+
+ if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
+ innobase_commit_low(trx);
+ }
+
+ /* Release possible statement level resources */
+ innobase_release_stat_resources(trx);
+ trx_mark_sql_stat_end(trx);
+
+#ifndef DBUG_OFF
+ if (error) {
+ DBUG_PRINT("error", ("error: %d", error));
+ }
+#endif
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ DBUG_RETURN(error);
+}
+
+/*********************************************************************
+This is called when MySQL writes the binlog entry for the current
+transaction. Writes to the InnoDB tablespace info which tells where the
+MySQL binlog entry for the current transaction ended. Also commits the
+transaction inside InnoDB. */
+
+int
+innobase_report_binlog_offset_and_commit(
+/*=====================================*/
+ /* out: 0 or error code */
+ THD* thd, /* in: user thread */
+ void* trx_handle, /* in: InnoDB trx handle */
+ char* log_file_name, /* in: latest binlog file name */
+ my_off_t end_offset) /* in: the offset in the binlog file
+ up to which we wrote */
+{
+ trx_t* trx;
+
+ trx = (trx_t*)trx_handle;
+
+ ut_a(trx != NULL);
+
+ trx->mysql_log_file_name = log_file_name;
+ trx->mysql_log_offset = (ib_longlong)end_offset;
+
+ return(innobase_commit(thd, trx_handle));
+}
+
+/*********************************************************************
+Rolls back a transaction in an InnoDB database. */
+
+int
+innobase_rollback(
+/*==============*/
+ /* out: 0 or error number */
+ THD* thd, /* in: handle to the MySQL thread of the user
+ whose transaction should be rolled back */
+ void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle */
+{
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("innobase_rollback");
+ DBUG_PRINT("trans", ("aborting transaction"));
+
+ trx = check_trx_exists(thd);
+
+ srv_conc_enter_innodb(trx);
+
+ if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
+ error = trx_rollback_for_mysql(trx);
+ } else {
+ error = trx_rollback_last_sql_stat_for_mysql(trx);
+ }
+
+ srv_conc_exit_innodb(trx);
+
+ /* Release possible statement level resources */
+ innobase_release_stat_resources(trx);
+
+ trx_mark_sql_stat_end(trx);
+
+ DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
+}
+
+/*********************************************************************
+Frees a possible InnoDB trx object associated with the current
+THD. */
+
+int
+innobase_close_connection(
+/*======================*/
+ /* out: 0 or error number */
+ THD* thd) /* in: handle to the MySQL thread of the user
+ whose transaction should be rolled back */
+{
+ if (NULL != thd->transaction.all.innobase_tid) {
+
+ trx_rollback_for_mysql((trx_t*)
+ (thd->transaction.all.innobase_tid));
+ trx_free_for_mysql((trx_t*)
+ (thd->transaction.all.innobase_tid));
+ thd->transaction.all.innobase_tid = NULL;
+ }
+
+ return(0);
+}
+
+/**********************************************************************
+Prints an error message. */
+static
+void
+innobase_print_error(
+/*=================*/
+ const char* db_errpfx, /* in: error prefix text */
+ char* buffer) /* in: error text */
+{
+ sql_print_error("%s: %s", db_errpfx, buffer);
+}
+
+
+/*****************************************************************************
+** InnoDB database tables
+*****************************************************************************/
+
+/********************************************************************
+This function is not relevant since we store the tables and indexes
+into our own tablespace, not as files, whose extension this function would
+give. */
+
+const char**
+ha_innobase::bas_ext() const
+/*========================*/
+ /* out: file extension strings, currently not
+ used */
+{
+ static const char* ext[] = {".InnoDB", NullS};
+
+ return(ext);
+}
+
+/*********************************************************************
+Normalizes a table name string. A normalized name consists of the
+database name catenated to '/' and table name. An example:
+test/mytable. On Windows normalization puts both the database name and the
+table name always to lower case. */
+static
+void
+normalize_table_name(
+/*=================*/
+ char* norm_name, /* out: normalized name as a
+ null-terminated string */
+ const char* name) /* in: table name string */
+{
+ char* name_ptr;
+ char* db_ptr;
+ char* ptr;
+
+ /* Scan name from the end */
+
+ ptr = strend(name)-1;
+
+ while (ptr >= name && *ptr != '\\' && *ptr != '/') {
+ ptr--;
+ }
+
+ name_ptr = ptr + 1;
+
+ DBUG_ASSERT(ptr > name);
+
+ ptr--;
+
+ while (ptr >= name && *ptr != '\\' && *ptr != '/') {
+ ptr--;
+ }
+
+ db_ptr = ptr + 1;
+
+ memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
+
+ norm_name[name_ptr - db_ptr - 1] = '/';
+
+#ifdef __WIN__
+ /* Put to lower case */
+
+ ptr = norm_name;
+
+ while (*ptr != '\0') {
+ *ptr = tolower(*ptr);
+ ptr++;
+ }
+#endif
+}
+
+/*********************************************************************
+Creates and opens a handle to a table which already exists in an Innobase
+database. */
+
+int
+ha_innobase::open(
+/*==============*/
+ /* out: 1 if error, 0 if success */
+ const char* name, /* in: table name */
+ int mode, /* in: not used */
+ uint test_if_locked) /* in: not used */
+{
+ dict_table_t* ib_table;
+ int error = 0;
+ uint buff_len;
+ char norm_name[1000];
+
+ DBUG_ENTER("ha_innobase::open");
+
+ UT_NOT_USED(mode);
+ UT_NOT_USED(test_if_locked);
+
+ normalize_table_name(norm_name, name);
+
+ user_thd = NULL;
+
+ last_query_id = (ulong)-1;
+
+ if (!(share=get_share(name)))
+ DBUG_RETURN(1);
+
+ /* Create buffers for packing the fields of a record. Why
+ table->reclength did not work here? Obviously, because char
+ fields when packed actually became 1 byte longer, when we also
+ stored the string length as the first byte. */
+
+ buff_len = table->reclength + table->max_key_length
+ + MAX_REF_PARTS * 3;
+ if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME),
+ &upd_buff, buff_len,
+ &key_val_buff, buff_len,
+ NullS)) {
+ free_share(share);
+ DBUG_RETURN(1);
+ }
+
+ /* Get pointer to a table object in InnoDB dictionary cache */
+
+ ib_table = dict_table_get_and_increment_handle_count(
+ norm_name, NULL);
+ if (NULL == ib_table) {
+
+ sql_print_error("InnoDB error:\n\
+Cannot find table %s from the internal data dictionary\n\
+of InnoDB though the .frm file for the table exists. Maybe you\n\
+have deleted and recreated InnoDB data files but have forgotten\n\
+to delete the corresponding .frm files of InnoDB tables, or you\n\
+have moved .frm files to another database?",
+ norm_name);
+
+ free_share(share);
+ my_free((char*) upd_buff, MYF(0));
+ my_errno = ENOENT;
+ DBUG_RETURN(1);
+ }
+
+ innobase_prebuilt = row_create_prebuilt(ib_table);
+
+ ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = table->reclength;
+
+ primary_key = MAX_KEY;
+
+ if (!row_table_got_default_clust_index(ib_table)) {
+
+ /* If we automatically created the clustered index,
+ then MySQL does not know about it and it must not be aware
+ of the index used on scan, to avoid checking if we update
+ the column of the index. The column is the row id in
+ the automatical case, and it will not be updated. */
+
+ ((row_prebuilt_t*)innobase_prebuilt)
+ ->clust_index_was_generated = FALSE;
+
+ primary_key = 0;
+ key_used_on_scan = 0;
+
+ /*
+ MySQL allocates the buffer for ref.
+ This includes all keys + one byte for each column
+ that may be NULL.
+ The ref_length must be exact as possible as
+ all reference buffers are allocated based on this.
+ */
+
+ ref_length = table->key_info->key_length;
+ } else {
+ ((row_prebuilt_t*)innobase_prebuilt)
+ ->clust_index_was_generated = TRUE;
+
+ ref_length = DATA_ROW_ID_LEN;
+
+ DBUG_ASSERT(key_used_on_scan == MAX_KEY);
+ }
+
+ auto_inc_counter_for_this_stat = 0;
+
+ block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
+ in query optimization */
+
+ /* Init table lock structure */
+ thr_lock_data_init(&share->lock,&lock,(void*) 0);
+
+ info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+
+ DBUG_RETURN(0);
+}
+
+/*********************************************************************
+Does nothing. */
+
+void
+ha_innobase::initialize(void)
+/*=========================*/
+{
+}
+
+/**********************************************************************
+Closes a handle to an InnoDB table. */
+
+int
+ha_innobase::close(void)
+/*====================*/
+ /* out: error number */
+{
+ DBUG_ENTER("ha_innobase::close");
+
+ row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt);
+
+ my_free((char*) upd_buff, MYF(0));
+ free_share(share);
+
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ DBUG_RETURN(0);
+}
+
+/* The following accessor functions should really be inside MySQL code! */
+
+/******************************************************************
+Gets field offset for a field in a table. */
+inline
+uint
+get_field_offset(
+/*=============*/
+ /* out: offset */
+ TABLE* table, /* in: MySQL table object */
+ Field* field) /* in: MySQL field object */
+{
+ return((uint) (field->ptr - (char*) table->record[0]));
+}
+
+/******************************************************************
+Checks if a field in a record is SQL NULL. Uses the record format
+information in table to track the null bit in record. */
+inline
+uint
+field_in_record_is_null(
+/*====================*/
+ /* out: 1 if NULL, 0 otherwise */
+ TABLE* table, /* in: MySQL table object */
+ Field* field, /* in: MySQL field object */
+ char* record) /* in: a row in MySQL format */
+{
+ int null_offset;
+
+ if (!field->null_ptr) {
+
+ return(0);
+ }
+
+ null_offset = (uint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ if (record[null_offset] & field->null_bit) {
+
+ return(1);
+ }
+
+ return(0);
+}
+
+/******************************************************************
+Sets a field in a record to SQL NULL. Uses the record format
+information in table to track the null bit in record. */
+inline
+void
+set_field_in_record_to_null(
+/*========================*/
+ TABLE* table, /* in: MySQL table object */
+ Field* field, /* in: MySQL field object */
+ char* record) /* in: a row in MySQL format */
+{
+ int null_offset;
+
+ null_offset = (uint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ record[null_offset] = record[null_offset] | field->null_bit;
+}
+
+/******************************************************************
+Resets SQL NULL bits in a record to zero. */
+inline
+void
+reset_null_bits(
+/*============*/
+ TABLE* table, /* in: MySQL table object */
+ char* record) /* in: a row in MySQL format */
+{
+ bzero(record, table->null_bytes);
+}
+
+extern "C" {
+/*****************************************************************
+InnoDB uses this function is to compare two data fields for which the
+data type is such that we must use MySQL code to compare them. NOTE that the
+prototype of this function is in rem0cmp.c in InnoDB source code!
+If you change this function, remember to update the prototype there! */
+
+int
+innobase_mysql_cmp(
+/*===============*/
+ /* out: 1, 0, -1, if a is greater,
+ equal, less than b, respectively */
+ int mysql_type, /* in: MySQL type */
+ unsigned char* a, /* in: data field */
+ unsigned int a_length, /* in: data field length,
+ not UNIV_SQL_NULL */
+ unsigned char* b, /* in: data field */
+ unsigned int b_length) /* in: data field length,
+ not UNIV_SQL_NULL */
+{
+ enum_field_types mysql_tp;
+ int ret;
+
+ DBUG_ASSERT(a_length != UNIV_SQL_NULL);
+ DBUG_ASSERT(b_length != UNIV_SQL_NULL);
+
+ mysql_tp = (enum_field_types) mysql_type;
+
+ switch (mysql_tp) {
+
+ case FIELD_TYPE_STRING:
+ case FIELD_TYPE_VAR_STRING:
+ ret = my_sortncmp((const char*) a, a_length,
+ (const char*) b, b_length);
+ if (ret < 0) {
+ return(-1);
+ } else if (ret > 0) {
+ return(1);
+ } else {
+ return(0);
+ }
+ default:
+ assert(0);
+ }
+
+ return(0);
+}
+}
+
+/******************************************************************
+Converts a MySQL type to an InnoDB type. */
+inline
+ulint
+get_innobase_type_from_mysql_type(
+/*==============================*/
+ /* out: DATA_BINARY, DATA_VARCHAR, ... */
+ Field* field) /* in: MySQL field */
+{
+ /* The following asserts check that MySQL type code fits in
+ 8 bits: this is used in ibuf and also when DATA_NOT_NULL is
+ ORed to the type */
+
+ DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_DOUBLE < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256);
+
+ switch (field->type()) {
+ case FIELD_TYPE_VAR_STRING: if (field->flags & BINARY_FLAG) {
+
+ return(DATA_BINARY);
+ } else if (strcmp(
+ default_charset_info->name,
+ "latin1") == 0) {
+ return(DATA_VARCHAR);
+ } else {
+ return(DATA_VARMYSQL);
+ }
+ case FIELD_TYPE_STRING: if (field->flags & BINARY_FLAG) {
+
+ return(DATA_FIXBINARY);
+ } else if (strcmp(
+ default_charset_info->name,
+ "latin1") == 0) {
+ return(DATA_CHAR);
+ } else {
+ return(DATA_MYSQL);
+ }
+ case FIELD_TYPE_LONG:
+ case FIELD_TYPE_LONGLONG:
+ case FIELD_TYPE_TINY:
+ case FIELD_TYPE_SHORT:
+ case FIELD_TYPE_INT24:
+ case FIELD_TYPE_DATE:
+ case FIELD_TYPE_DATETIME:
+ case FIELD_TYPE_YEAR:
+ case FIELD_TYPE_NEWDATE:
+ case FIELD_TYPE_ENUM:
+ case FIELD_TYPE_SET:
+ case FIELD_TYPE_TIME:
+ case FIELD_TYPE_TIMESTAMP:
+ return(DATA_INT);
+ case FIELD_TYPE_FLOAT:
+ return(DATA_FLOAT);
+ case FIELD_TYPE_DOUBLE:
+ return(DATA_DOUBLE);
+ case FIELD_TYPE_DECIMAL:
+ return(DATA_DECIMAL);
+ case FIELD_TYPE_TINY_BLOB:
+ case FIELD_TYPE_MEDIUM_BLOB:
+ case FIELD_TYPE_BLOB:
+ case FIELD_TYPE_LONG_BLOB:
+ return(DATA_BLOB);
+ default:
+ assert(0);
+ }
+
+ return(0);
+}
+
+/***********************************************************************
+Stores a key value for a row to a buffer. */
+
+uint
+ha_innobase::store_key_val_for_row(
+/*===============================*/
+ /* out: key value length as stored in buff */
+ uint keynr, /* in: key number */
+ char* buff, /* in/out: buffer for the key value (in MySQL
+ format) */
+ const mysql_byte* record)/* in: row in MySQL format */
+{
+ KEY* key_info = table->key_info + keynr;
+ KEY_PART_INFO* key_part = key_info->key_part;
+ KEY_PART_INFO* end = key_part + key_info->key_parts;
+ char* buff_start = buff;
+
+ DBUG_ENTER("store_key_val_for_row");
+
+ for (; key_part != end; key_part++) {
+
+ if (key_part->null_bit) {
+ /* Store 0 if the key part is a NULL part */
+
+ if (record[key_part->null_offset]
+ & key_part->null_bit) {
+ *buff++ = 1;
+ continue;
+ }
+
+ *buff++ = 0;
+ }
+
+ memcpy(buff, record + key_part->offset, key_part->length);
+ buff += key_part->length;
+ }
+
+ /*
+ We have to zero-fill the buffer to be able to compare two
+ keys to see if they are equal
+ */
+ bzero(buff, (ref_length- (uint) (buff - buff_start)));
+ DBUG_RETURN(ref_length);
+}
+
+/******************************************************************
+Builds a template to the prebuilt struct. */
+static
+void
+build_template(
+/*===========*/
+ row_prebuilt_t* prebuilt, /* in: prebuilt struct */
+ THD* thd, /* in: current user thread, used
+ only if templ_type is
+ ROW_MYSQL_REC_FIELDS */
+ TABLE* table, /* in: MySQL table */
+ ulint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
+ ROW_MYSQL_REC_FIELDS */
+{
+ dict_index_t* index;
+ dict_index_t* clust_index;
+ mysql_row_templ_t* templ;
+ Field* field;
+ ulint n_fields;
+ ulint n_requested_fields = 0;
+ ibool fetch_all_in_key = FALSE;
+ ulint i;
+
+ clust_index = dict_table_get_first_index_noninline(prebuilt->table);
+
+ if (!prebuilt->hint_no_need_to_fetch_extra_cols) {
+ /* We have a hint that we should at least fetch all
+ columns in the key, or all columns in the table */
+
+ if (prebuilt->read_just_key) {
+ /* MySQL has instructed us that it is enough to
+ fetch the columns in the key */
+
+ fetch_all_in_key = TRUE;
+ } else {
+ /* We are building a temporary table: fetch all
+ columns; the reason is that MySQL may use the
+ clustered index key to store rows, but the mechanism
+ we use below to detect required columns does not
+ reveal that. Actually, it might be enough to
+ fetch only all in the key also in this case! */
+
+ templ_type = ROW_MYSQL_WHOLE_ROW;
+ }
+ }
+
+ if (prebuilt->select_lock_type == LOCK_X) {
+ /* We always retrieve the whole clustered index record if we
+ use exclusive row level locks, for example, if the read is
+ done in an UPDATE statement. */
+
+ templ_type = ROW_MYSQL_WHOLE_ROW;
+ }
+
+ if (templ_type == ROW_MYSQL_REC_FIELDS) {
+ /* In versions < 3.23.50 we always retrieved the clustered
+ index record if prebuilt->select_lock_type == LOCK_S,
+ but there is really not need for that, and in some cases
+ performance could be seriously degraded because the MySQL
+ optimizer did not know about our convention! */
+
+ index = prebuilt->index;
+ } else {
+ index = clust_index;
+ }
+
+ if (index == clust_index) {
+ prebuilt->need_to_access_clustered = TRUE;
+ } else {
+ prebuilt->need_to_access_clustered = FALSE;
+ /* Below we check column by column if we need to access
+ the clustered index */
+ }
+
+ n_fields = (ulint)table->fields;
+
+ if (!prebuilt->mysql_template) {
+ prebuilt->mysql_template = (mysql_row_templ_t*)
+ mem_alloc_noninline(
+ n_fields * sizeof(mysql_row_templ_t));
+ }
+
+ prebuilt->template_type = templ_type;
+ prebuilt->null_bitmap_len = table->null_bytes;
+
+ prebuilt->templ_contains_blob = FALSE;
+
+ for (i = 0; i < n_fields; i++) {
+ templ = prebuilt->mysql_template + n_requested_fields;
+ field = table->field[i];
+
+ if (templ_type == ROW_MYSQL_REC_FIELDS
+ && !(fetch_all_in_key &&
+ ULINT_UNDEFINED != dict_index_get_nth_col_pos(
+ index, i))
+ && thd->query_id != field->query_id
+ && thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
+ && thd->query_id !=
+ (field->query_id ^ (MAX_ULONG_BIT >> 1))) {
+
+ /* This field is not needed in the query, skip it */
+
+ goto skip_field;
+ }
+
+ n_requested_fields++;
+
+ templ->col_no = i;
+
+ if (index == clust_index) {
+ templ->rec_field_no = (index->table->cols + i)
+ ->clust_pos;
+ } else {
+ templ->rec_field_no = dict_index_get_nth_col_pos(
+ index, i);
+ }
+
+ if (templ->rec_field_no == ULINT_UNDEFINED) {
+ prebuilt->need_to_access_clustered = TRUE;
+ }
+
+ if (field->null_ptr) {
+ templ->mysql_null_byte_offset =
+ (ulint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ templ->mysql_null_bit_mask = (ulint) field->null_bit;
+ } else {
+ templ->mysql_null_bit_mask = 0;
+ }
+
+ templ->mysql_col_offset = (ulint)
+ get_field_offset(table, field);
+
+ templ->mysql_col_len = (ulint) field->pack_length();
+ templ->type = get_innobase_type_from_mysql_type(field);
+ templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
+
+ if (templ->type == DATA_BLOB) {
+ prebuilt->templ_contains_blob = TRUE;
+ }
+skip_field:
+ ;
+ }
+
+ prebuilt->n_template = n_requested_fields;
+
+ if (prebuilt->need_to_access_clustered) {
+ /* Change rec_field_no's to correspond to the clustered index
+ record */
+ for (i = 0; i < n_requested_fields; i++) {
+ templ = prebuilt->mysql_template + i;
+
+ templ->rec_field_no =
+ (index->table->cols + templ->col_no)->clust_pos;
+ }
+ }
+}
+
+/************************************************************************
+Stores a row in an InnoDB database, to the table specified in this
+handle. */
+
+int
+ha_innobase::write_row(
+/*===================*/
+ /* out: error code */
+ mysql_byte* record) /* in: a row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ int error;
+ longlong auto_inc;
+
+ DBUG_ENTER("ha_innobase::write_row");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ statistic_increment(ha_write_count, &LOCK_status);
+
+ if (table->time_stamp) {
+ update_timestamp(record + table->time_stamp - 1);
+ }
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ if (table->next_number_field && record == table->record[0]) {
+ /* This is the case where the table has an
+ auto-increment column */
+
+ /* Fetch the value the user possibly has set in the
+ autoincrement field */
+
+ auto_inc = table->next_number_field->val_int();
+
+ /* In replication and also otherwise the auto-inc column
+ can be set with SET INSERT_ID. Then we must look at
+ user_thd->next_insert_id. If it is nonzero and the user
+ has not supplied a value, we must use it, and use values
+ incremented by 1 in all subsequent inserts within the
+ same SQL statement! */
+
+ if (auto_inc == 0 && user_thd->next_insert_id != 0) {
+ auto_inc = user_thd->next_insert_id;
+ auto_inc_counter_for_this_stat = auto_inc;
+ }
+
+ if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
+ /* The user set the auto-inc counter for
+ this SQL statement with SET INSERT_ID. We must
+ assign sequential values from the counter. */
+
+ auto_inc_counter_for_this_stat++;
+
+ auto_inc = auto_inc_counter_for_this_stat;
+
+ /* We give MySQL a new value to place in the
+ auto-inc column */
+ user_thd->next_insert_id = auto_inc;
+ }
+
+ if (auto_inc != 0) {
+ /* This call will calculate the max of the
+ current value and the value supplied by the user, if
+ the auto_inc counter is already initialized
+ for the table */
+
+ /* We have to use the transactional lock mechanism
+ on the auto-inc counter of the table to ensure
+ that replication and roll-forward of the binlog
+ exactly imitates also the given auto-inc values.
+ The lock is released at each SQL statement's
+ end. */
+
+ srv_conc_enter_innodb(prebuilt->trx);
+ error = row_lock_table_autoinc_for_mysql(prebuilt);
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ if (error != DB_SUCCESS) {
+
+ error = convert_error_code_to_mysql(error,
+ user_thd);
+ goto func_exit;
+ }
+
+ dict_table_autoinc_update(prebuilt->table, auto_inc);
+ } else {
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ if (!prebuilt->trx->auto_inc_lock) {
+
+ error = row_lock_table_autoinc_for_mysql(
+ prebuilt);
+ if (error != DB_SUCCESS) {
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(
+ error, user_thd);
+ goto func_exit;
+ }
+ }
+
+ auto_inc = dict_table_autoinc_get(prebuilt->table);
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ /* If auto_inc is now != 0 the autoinc counter
+ was already initialized for the table: we can give
+ the new value for MySQL to place in the field */
+
+ if (auto_inc != 0) {
+ user_thd->next_insert_id = auto_inc;
+ }
+ }
+
+ update_auto_increment();
+
+ if (auto_inc == 0) {
+ /* The autoinc counter for our table was not yet
+ initialized, initialize it now */
+
+ auto_inc = table->next_number_field->val_int();
+
+ srv_conc_enter_innodb(prebuilt->trx);
+ error = row_lock_table_autoinc_for_mysql(prebuilt);
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ if (error != DB_SUCCESS) {
+
+ error = convert_error_code_to_mysql(error,
+ user_thd);
+ goto func_exit;
+ }
+
+ dict_table_autoinc_initialize(prebuilt->table,
+ auto_inc);
+ }
+
+ /* We have to set sql_stat_start to TRUE because
+ update_auto_increment may have called a select, and
+ has reset that flag; row_insert_for_mysql has to
+ know to set the IX intention lock on the table, something
+ it only does at the start of each statement */
+
+ prebuilt->sql_stat_start = TRUE;
+ }
+
+ if (prebuilt->mysql_template == NULL
+ || prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
+ /* Build the template used in converting quickly between
+ the two database formats */
+
+ build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
+ }
+
+ if (user_thd->lex.sql_command == SQLCOM_INSERT
+ && user_thd->lex.duplicates == DUP_IGNORE) {
+ prebuilt->trx->ignore_duplicates_in_insert = TRUE;
+ } else {
+ prebuilt->trx->ignore_duplicates_in_insert = FALSE;
+ }
+
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ error = row_insert_for_mysql((byte*) record, prebuilt);
+
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ prebuilt->trx->ignore_duplicates_in_insert = FALSE;
+
+ error = convert_error_code_to_mysql(error, user_thd);
+
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+func_exit:
+ innobase_active_small();
+
+ DBUG_RETURN(error);
+}
+
+/******************************************************************
+Converts field data for storage in an InnoDB update vector. */
+inline
+mysql_byte*
+innobase_convert_and_store_changed_col(
+/*===================================*/
+ /* out: pointer to the end of the converted
+ data in the buffer */
+ upd_field_t* ufield, /* in/out: field in the update vector */
+ mysql_byte* buf, /* in: buffer we can use in conversion */
+ mysql_byte* data, /* in: column data to store */
+ ulint len, /* in: data len */
+ ulint col_type,/* in: data type in InnoDB type numbers */
+ ulint is_unsigned)/* in: != 0 if an unsigned integer type */
+{
+ uint i;
+
+ if (len == UNIV_SQL_NULL) {
+ data = NULL;
+ } else if (col_type == DATA_VARCHAR || col_type == DATA_BINARY
+ || col_type == DATA_VARMYSQL) {
+ /* Remove trailing spaces */
+ while (len > 0 && data[len - 1] == ' ') {
+ len--;
+ }
+
+ } else if (col_type == DATA_INT) {
+ /* Store integer data in InnoDB in a big-endian
+ format, sign bit negated, if signed */
+
+ for (i = 0; i < len; i++) {
+ buf[len - 1 - i] = data[i];
+ }
+
+ if (!is_unsigned) {
+ buf[0] = buf[0] ^ 128;
+ }
+
+ data = buf;
+
+ buf += len;
+ }
+
+ ufield->new_val.data = data;
+ ufield->new_val.len = len;
+
+ return(buf);
+}
+
+/**************************************************************************
+Checks which fields have changed in a row and stores information
+of them to an update vector. */
+static
+int
+calc_row_difference(
+/*================*/
+ /* out: error number or 0 */
+ upd_t* uvect, /* in/out: update vector */
+ mysql_byte* old_row, /* in: old row in MySQL format */
+ mysql_byte* new_row, /* in: new row in MySQL format */
+ struct st_table* table, /* in: table in MySQL data dictionary */
+ mysql_byte* upd_buff, /* in: buffer to use */
+ row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
+ THD* thd) /* in: user thread */
+{
+ Field* field;
+ uint n_fields;
+ ulint o_len;
+ ulint n_len;
+ byte* o_ptr;
+ byte* n_ptr;
+ byte* buf;
+ upd_field_t* ufield;
+ ulint col_type;
+ ulint is_unsigned;
+ ulint n_changed = 0;
+ uint i;
+
+ n_fields = table->fields;
+
+ /* We use upd_buff to convert changed fields */
+ buf = (byte*) upd_buff;
+
+ for (i = 0; i < n_fields; i++) {
+ field = table->field[i];
+
+ /* if (thd->query_id != field->query_id) { */
+ /* TODO: check that these fields cannot have
+ changed! */
+
+ /* goto skip_field;
+ }*/
+
+ o_ptr = (byte*) old_row + get_field_offset(table, field);
+ n_ptr = (byte*) new_row + get_field_offset(table, field);
+ o_len = field->pack_length();
+ n_len = field->pack_length();
+
+ col_type = get_innobase_type_from_mysql_type(field);
+ is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
+
+ switch (col_type) {
+
+ case DATA_BLOB:
+ o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len);
+ n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len);
+ break;
+ case DATA_VARCHAR:
+ case DATA_BINARY:
+ case DATA_VARMYSQL:
+ o_ptr = row_mysql_read_var_ref_noninline(&o_len, o_ptr);
+ n_ptr = row_mysql_read_var_ref_noninline(&n_len, n_ptr);
+ default:
+ ;
+ }
+
+ if (field->null_ptr) {
+ if (field_in_record_is_null(table, field,
+ (char*) old_row)) {
+ o_len = UNIV_SQL_NULL;
+ }
+
+ if (field_in_record_is_null(table, field,
+ (char*) new_row)) {
+ n_len = UNIV_SQL_NULL;
+ }
+ }
+
+ if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
+ 0 != memcmp(o_ptr, n_ptr, o_len))) {
+ /* The field has changed */
+
+ ufield = uvect->fields + n_changed;
+
+ buf = (byte*)
+ innobase_convert_and_store_changed_col(ufield,
+ (mysql_byte*)buf,
+ (mysql_byte*)n_ptr, n_len, col_type,
+ is_unsigned);
+ ufield->exp = NULL;
+ ufield->field_no =
+ (prebuilt->table->cols + i)->clust_pos;
+ n_changed++;
+ }
+ ;
+ }
+
+ uvect->n_fields = n_changed;
+ uvect->info_bits = 0;
+
+ return(0);
+}
+
+/**************************************************************************
+Updates a row given as a parameter to a new value. Note that we are given
+whole rows, not just the fields which are updated: this incurs some
+overhead for CPU when we check which fields are actually updated.
+TODO: currently InnoDB does not prevent the 'Halloween problem':
+in a searched update a single row can get updated several times
+if its index columns are updated! */
+
+int
+ha_innobase::update_row(
+/*====================*/
+ /* out: error number or 0 */
+ const mysql_byte* old_row,/* in: old row in MySQL format */
+ mysql_byte* new_row)/* in: new row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ upd_t* uvect;
+ int error = 0;
+
+ DBUG_ENTER("ha_innobase::update_row");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (table->time_stamp) {
+ update_timestamp(new_row + table->time_stamp - 1);
+ }
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ if (prebuilt->upd_node) {
+ uvect = prebuilt->upd_node->update;
+ } else {
+ uvect = row_get_prebuilt_update_vector(prebuilt);
+ }
+
+ /* Build an update vector from the modified fields in the rows
+ (uses upd_buff of the handle) */
+
+ calc_row_difference(uvect, (mysql_byte*) old_row, new_row, table,
+ upd_buff, prebuilt, user_thd);
+ /* This is not a delete */
+ prebuilt->upd_node->is_delete = FALSE;
+
+ assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
+
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ error = row_update_for_mysql((byte*) old_row, prebuilt);
+
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+
+ innobase_active_small();
+
+ DBUG_RETURN(error);
+}
+
+/**************************************************************************
+Deletes a row given as the parameter. */
+
+int
+ha_innobase::delete_row(
+/*====================*/
+ /* out: error number or 0 */
+ const mysql_byte* record) /* in: a row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ int error = 0;
+
+ DBUG_ENTER("ha_innobase::delete_row");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ if (!prebuilt->upd_node) {
+ row_get_prebuilt_update_vector(prebuilt);
+ }
+
+ /* This is a delete */
+
+ prebuilt->upd_node->is_delete = TRUE;
+
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ error = row_update_for_mysql((byte*) record, prebuilt);
+
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ innobase_active_small();
+
+ DBUG_RETURN(error);
+}
+
+/**********************************************************************
+Initializes a handle to use an index. */
+
+int
+ha_innobase::index_init(
+/*====================*/
+ /* out: 0 or error number */
+ uint keynr) /* in: key (index) number */
+{
+ int error = 0;
+ DBUG_ENTER("index_init");
+
+ error = change_active_index(keynr);
+
+ DBUG_RETURN(error);
+}
+
+/**********************************************************************
+Currently does nothing. */
+
+int
+ha_innobase::index_end(void)
+/*========================*/
+{
+ int error = 0;
+ DBUG_ENTER("index_end");
+
+ DBUG_RETURN(error);
+}
+
+/*************************************************************************
+Converts a search mode flag understood by MySQL to a flag understood
+by InnoDB. */
+inline
+ulint
+convert_search_mode_to_innobase(
+/*============================*/
+ enum ha_rkey_function find_flag)
+{
+ switch (find_flag) {
+ case HA_READ_KEY_EXACT: return(PAGE_CUR_GE);
+ /* the above does not require the index to be UNIQUE */
+ case HA_READ_KEY_OR_NEXT: return(PAGE_CUR_GE);
+ case HA_READ_KEY_OR_PREV: return(PAGE_CUR_LE);
+ case HA_READ_AFTER_KEY: return(PAGE_CUR_G);
+ case HA_READ_BEFORE_KEY: return(PAGE_CUR_L);
+ case HA_READ_PREFIX: return(PAGE_CUR_GE);
+ case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE);
+ /* the above PREFIX flags mean that the last
+ field in the key value may just be a prefix
+ of the complete fixed length field */
+ default: assert(0);
+ }
+
+ return(0);
+}
+
+/**************************************************************************
+Positions an index cursor to the index specified in the handle. Fetches the
+row if any. */
+
+int
+ha_innobase::index_read(
+/*====================*/
+ /* out: 0, HA_ERR_KEY_NOT_FOUND,
+ or error number */
+ mysql_byte* buf, /* in/out: buffer for the returned
+ row */
+ const mysql_byte* key_ptr,/* in: key value; if this is NULL
+ we position the cursor at the
+ start or end of index */
+ uint key_len,/* in: key value length */
+ enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ ulint mode;
+ dict_index_t* index;
+ ulint match_mode = 0;
+ int error;
+ ulint ret;
+
+ DBUG_ENTER("index_read");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ statistic_increment(ha_read_key_count, &LOCK_status);
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ index = prebuilt->index;
+
+ /* Note that if the select is used for an update, we always
+ fetch the clustered index record: therefore the index for which the
+ template is built is not necessarily prebuilt->index, but can also
+ be the clustered index */
+
+ if (prebuilt->sql_stat_start) {
+ build_template(prebuilt, user_thd, table,
+ ROW_MYSQL_REC_FIELDS);
+ }
+
+ if (key_ptr) {
+ row_sel_convert_mysql_key_to_innobase(prebuilt->search_tuple,
+ (byte*) key_val_buff,
+ index,
+ (byte*) key_ptr,
+ (ulint) key_len);
+ } else {
+ /* We position the cursor to the last or the first entry
+ in the index */
+
+ dtuple_set_n_fields(prebuilt->search_tuple, 0);
+ }
+
+ mode = convert_search_mode_to_innobase(find_flag);
+
+ match_mode = 0;
+
+ if (find_flag == HA_READ_KEY_EXACT) {
+ match_mode = ROW_SEL_EXACT;
+
+ } else if (find_flag == HA_READ_PREFIX
+ || find_flag == HA_READ_PREFIX_LAST) {
+ match_mode = ROW_SEL_EXACT_PREFIX;
+ }
+
+ last_match_mode = match_mode;
+
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0);
+
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ if (ret == DB_SUCCESS) {
+ error = 0;
+ table->status = 0;
+
+ } else if (ret == DB_RECORD_NOT_FOUND) {
+ error = HA_ERR_KEY_NOT_FOUND;
+ table->status = STATUS_NOT_FOUND;
+
+ } else if (ret == DB_END_OF_INDEX) {
+ error = HA_ERR_KEY_NOT_FOUND;
+ table->status = STATUS_NOT_FOUND;
+ } else {
+ error = convert_error_code_to_mysql(ret, user_thd);
+ table->status = STATUS_NOT_FOUND;
+ }
+
+ DBUG_RETURN(error);
+}
+
+
+/*
+ The following functions works like index_read, but it find the last
+ row with the current index prefix.
+ This code is disabled until Heikki has verified that InnoDB support the
+ HA_READ_PREFIX_LAST flag and removed the HA_NOT_READ_PREFIX_LAST
+ flag from ha_innodb.h
+*/
+
+int
+ha_innobase::index_read_last(mysql_byte *buf,
+ const mysql_byte *key_ptr,
+ uint key_len)
+{
+ return index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST);
+}
+
+
+/************************************************************************
+Changes the active index of a handle. */
+
+int
+ha_innobase::change_active_index(
+/*=============================*/
+ /* out: 0 or error code */
+ uint keynr) /* in: use this index; MAX_KEY means always clustered
+ index, even if it was internally generated by
+ InnoDB */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ KEY* key=0;
+ statistic_increment(ha_read_key_count, &LOCK_status);
+ DBUG_ENTER("change_active_index");
+
+ active_index = keynr;
+
+ if (keynr != MAX_KEY && table->keys > 0) {
+ key = table->key_info + active_index;
+
+ prebuilt->index = dict_table_get_index_noninline(
+ prebuilt->table,
+ key->name);
+ } else {
+ prebuilt->index = dict_table_get_first_index_noninline(
+ prebuilt->table);
+ }
+
+ if (!prebuilt->index) {
+ sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key ? key->name : "NULL", prebuilt->table->name);
+ DBUG_RETURN(1);
+ }
+
+ assert(prebuilt->search_tuple != 0);
+
+ dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
+
+ dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
+ prebuilt->index->n_fields);
+
+ /* Maybe MySQL changes the active index for a handle also
+ during some queries, we do not know: then it is safest to build
+ the template such that all columns will be fetched */
+
+ build_template(prebuilt, user_thd, table, ROW_MYSQL_WHOLE_ROW);
+
+ DBUG_RETURN(0);
+}
+
+/**************************************************************************
+Positions an index cursor to the index specified in keynr. Fetches the
+row if any. */
+/* ??? This is only used to read whole keys ??? */
+
+int
+ha_innobase::index_read_idx(
+/*========================*/
+ /* out: error number or 0 */
+ mysql_byte* buf, /* in/out: buffer for the returned
+ row */
+ uint keynr, /* in: use this index */
+ const mysql_byte* key, /* in: key value; if this is NULL
+ we position the cursor at the
+ start or end of index */
+ uint key_len, /* in: key value length */
+ enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+{
+ if (change_active_index(keynr)) {
+
+ return(1);
+ }
+
+ return(index_read(buf, key, key_len, find_flag));
+}
+
+/***************************************************************************
+Reads the next or previous row from a cursor, which must have previously been
+positioned using index_read. */
+
+int
+ha_innobase::general_fetch(
+/*=======================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf, /* in/out: buffer for next row in MySQL
+ format */
+ uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
+ uint match_mode) /* in: 0, ROW_SEL_EXACT, or
+ ROW_SEL_EXACT_PREFIX */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ ulint ret;
+ int error = 0;
+
+ DBUG_ENTER("general_fetch");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ srv_conc_enter_innodb(prebuilt->trx);
+
+ ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode,
+ direction);
+ srv_conc_exit_innodb(prebuilt->trx);
+
+ if (ret == DB_SUCCESS) {
+ error = 0;
+ table->status = 0;
+
+ } else if (ret == DB_RECORD_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ table->status = STATUS_NOT_FOUND;
+
+ } else if (ret == DB_END_OF_INDEX) {
+ error = HA_ERR_END_OF_FILE;
+ table->status = STATUS_NOT_FOUND;
+ } else {
+ error = convert_error_code_to_mysql(ret, user_thd);
+ table->status = STATUS_NOT_FOUND;
+ }
+
+ DBUG_RETURN(error);
+}
+
+/***************************************************************************
+Reads the next row from a cursor, which must have previously been
+positioned using index_read. */
+
+int
+ha_innobase::index_next(
+/*====================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf) /* in/out: buffer for next row in MySQL
+ format */
+{
+ statistic_increment(ha_read_next_count, &LOCK_status);
+
+ return(general_fetch(buf, ROW_SEL_NEXT, 0));
+}
+
+/***********************************************************************
+Reads the next row matching to the key value given as the parameter. */
+
+int
+ha_innobase::index_next_same(
+/*=========================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf, /* in/out: buffer for the row */
+ const mysql_byte* key, /* in: key value */
+ uint keylen) /* in: key value length */
+{
+ statistic_increment(ha_read_next_count, &LOCK_status);
+
+ return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
+}
+
+/***************************************************************************
+Reads the previous row from a cursor, which must have previously been
+positioned using index_read. */
+
+int
+ha_innobase::index_prev(
+/*====================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf) /* in/out: buffer for previous row in MySQL
+ format */
+{
+ return(general_fetch(buf, ROW_SEL_PREV, 0));
+}
+
+/************************************************************************
+Positions a cursor on the first record in an index and reads the
+corresponding row to buf. */
+
+int
+ha_innobase::index_first(
+/*=====================*/
+ /* out: 0, HA_ERR_END_OF_FILE,
+ or error code */
+ mysql_byte* buf) /* in/out: buffer for the row */
+{
+ int error;
+
+ DBUG_ENTER("index_first");
+ statistic_increment(ha_read_first_count, &LOCK_status);
+
+ error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
+
+ /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
+
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
+
+ DBUG_RETURN(error);
+}
+
+/************************************************************************
+Positions a cursor on the last record in an index and reads the
+corresponding row to buf. */
+
+int
+ha_innobase::index_last(
+/*====================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error code */
+ mysql_byte* buf) /* in/out: buffer for the row */
+{
+ int error;
+
+ DBUG_ENTER("index_first");
+ statistic_increment(ha_read_last_count, &LOCK_status);
+
+ error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
+
+ /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
+
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
+
+ DBUG_RETURN(error);
+}
+
+/********************************************************************
+Initialize a table scan. */
+
+int
+ha_innobase::rnd_init(
+/*==================*/
+ /* out: 0 or error number */
+ bool scan) /* in: ???????? */
+{
+ int err;
+
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ if (prebuilt->clust_index_was_generated) {
+ err = change_active_index(MAX_KEY);
+ } else {
+ err = change_active_index(primary_key);
+ }
+
+ start_of_scan = 1;
+
+ return(err);
+}
+
+/*********************************************************************
+Ends a table scan ???????????????? */
+
+int
+ha_innobase::rnd_end(void)
+/*======================*/
+ /* out: 0 or error number */
+{
+ return(index_end());
+}
+
+/*********************************************************************
+Reads the next row in a table scan (also used to read the FIRST row
+in a table scan). */
+
+int
+ha_innobase::rnd_next(
+/*==================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error number */
+ mysql_byte* buf)/* in/out: returns the row in this buffer,
+ in MySQL format */
+{
+ int error;
+
+ DBUG_ENTER("rnd_next");
+ statistic_increment(ha_read_rnd_next_count, &LOCK_status);
+
+ if (start_of_scan) {
+ error = index_first(buf);
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
+ start_of_scan = 0;
+ } else {
+ error = general_fetch(buf, ROW_SEL_NEXT, 0);
+ }
+
+ DBUG_RETURN(error);
+}
+
+/**************************************************************************
+Fetches a row from the table based on a reference. TODO: currently we use
+'ref_stored_len' of the handle as the key length. This may change. */
+
+int
+ha_innobase::rnd_pos(
+/*=================*/
+ /* out: 0, HA_ERR_KEY_NOT_FOUND,
+ or error code */
+ mysql_byte* buf, /* in/out: buffer for the row */
+ mysql_byte* pos) /* in: primary key value in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ int error;
+ uint keynr = active_index;
+ DBUG_ENTER("rnd_pos");
+ DBUG_DUMP("key", (char*) pos, ref_stored_len);
+
+ statistic_increment(ha_read_rnd_count, &LOCK_status);
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (prebuilt->clust_index_was_generated) {
+ /* No primary key was defined for the table and we
+ generated the clustered index from the row id: the
+ row reference is the row id, not any key value
+ that MySQL knows */
+
+ error = change_active_index(MAX_KEY);
+ } else {
+ error = change_active_index(primary_key);
+ }
+
+ if (error) {
+ DBUG_PRINT("error",("Got error: %ld",error));
+ DBUG_RETURN(error);
+ }
+
+ error = index_read(buf, pos, ref_stored_len, HA_READ_KEY_EXACT);
+ if (error)
+ {
+ DBUG_PRINT("error",("Got error: %ld",error));
+ }
+ change_active_index(keynr);
+
+ DBUG_RETURN(error);
+}
+
+/*************************************************************************
+Stores a reference to the current row to 'ref' field of the handle. Note
+that the function parameter is illogical: we must assume that 'record'
+is the current 'position' of the handle, because if row ref is actually
+the row id internally generated in InnoDB, then 'record' does not contain
+it. We just guess that the row id must be for the record where the handle
+was positioned the last time. */
+
+void
+ha_innobase::position(
+/*==================*/
+ const mysql_byte* record) /* in: row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ uint len;
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (prebuilt->clust_index_was_generated) {
+ /* No primary key was defined for the table and we
+ generated the clustered index from row id: the
+ row reference will be the row id, not any key value
+ that MySQL knows */
+
+ len = DATA_ROW_ID_LEN;
+
+ memcpy(ref, prebuilt->row_id, len);
+ } else {
+ len = store_key_val_for_row(primary_key, (char*) ref, record);
+ }
+
+ DBUG_ASSERT(len == ref_length);
+ ref_stored_len = len;
+}
+
+
+/*********************************************************************
+Creates a table definition to an InnoDB database. */
+static
+int
+create_table_def(
+/*=============*/
+ trx_t* trx, /* in: InnoDB transaction handle */
+ TABLE* form, /* in: information on table
+ columns and indexes */
+ const char* table_name) /* in: table name */
+{
+ Field* field;
+ dict_table_t* table;
+ ulint n_cols;
+ int error;
+ ulint col_type;
+ ulint nulls_allowed;
+ ulint unsigned_type;
+ ulint i;
+
+ DBUG_ENTER("create_table_def");
+ DBUG_PRINT("enter", ("table_name: %s", table_name));
+
+ n_cols = form->fields;
+
+ /* The '0' below specifies that everything is currently
+ created in tablespace 0 */
+
+ table = dict_mem_table_create((char*) table_name, 0, n_cols);
+
+ for (i = 0; i < n_cols; i++) {
+ field = form->field[i];
+
+ col_type = get_innobase_type_from_mysql_type(field);
+ if (field->null_ptr) {
+ nulls_allowed = 0;
+ } else {
+ nulls_allowed = DATA_NOT_NULL;
+ }
+
+ if (field->flags & UNSIGNED_FLAG) {
+ unsigned_type = DATA_UNSIGNED;
+ } else {
+ unsigned_type = 0;
+ }
+
+ dict_mem_table_add_col(table, (char*) field->field_name,
+ col_type, (ulint)field->type()
+ | nulls_allowed | unsigned_type,
+ field->pack_length(), 0);
+ }
+
+ error = row_create_table_for_mysql(table, trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*********************************************************************
+Creates an index in an InnoDB database. */
+static
+int
+create_index(
+/*=========*/
+ trx_t* trx, /* in: InnoDB transaction handle */
+ TABLE* form, /* in: information on table
+ columns and indexes */
+ const char* table_name, /* in: table name */
+ uint key_num) /* in: index number */
+{
+ dict_index_t* index;
+ int error;
+ ulint n_fields;
+ KEY* key;
+ KEY_PART_INFO* key_part;
+ ulint ind_type;
+ ulint i;
+
+ DBUG_ENTER("create_index");
+
+ key = form->key_info + key_num;
+
+ n_fields = key->key_parts;
+
+ ind_type = 0;
+
+ if (key_num == form->primary_key)
+ {
+ ind_type = ind_type | DICT_CLUSTERED;
+ }
+
+ if (key->flags & HA_NOSAME ) {
+ ind_type = ind_type | DICT_UNIQUE;
+ }
+
+ /* The '0' below specifies that everything in InnoDB is currently
+ created in tablespace 0 */
+
+ index = dict_mem_index_create((char*) table_name, key->name, 0,
+ ind_type, n_fields);
+ for (i = 0; i < n_fields; i++) {
+ key_part = key->key_part + i;
+
+ /* We assume all fields should be sorted in ascending
+ order, hence the '0': */
+ dict_mem_index_add_field(index,
+ (char*) key_part->field->field_name, 0);
+ }
+
+ error = row_create_index_for_mysql(index, trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*********************************************************************
+Creates an index to an InnoDB table when the user has defined no
+primary index. */
+static
+int
+create_clustered_index_when_no_primary(
+/*===================================*/
+ trx_t* trx, /* in: InnoDB transaction handle */
+ const char* table_name) /* in: table name */
+{
+ dict_index_t* index;
+ int error;
+
+ /* The first '0' below specifies that everything in InnoDB is
+ currently created in file space 0 */
+
+ index = dict_mem_index_create((char*) table_name,
+ (char*) "GEN_CLUST_INDEX",
+ 0, DICT_CLUSTERED, 0);
+ error = row_create_index_for_mysql(index, trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ return(error);
+}
+
+/*********************************************************************
+Creates a new table to an InnoDB database. */
+
+int
+ha_innobase::create(
+/*================*/
+ /* out: error number */
+ const char* name, /* in: table name */
+ TABLE* form, /* in: information on table
+ columns and indexes */
+ HA_CREATE_INFO* create_info) /* in: more information of the
+ created table, contains also the
+ create statement string */
+{
+ int error;
+ dict_table_t* innobase_table;
+ trx_t* trx;
+ int primary_key_no;
+ uint i;
+ char name2[FN_REFLEN];
+ char norm_name[FN_REFLEN];
+ THD *thd= current_thd;
+
+ DBUG_ENTER("ha_innobase::create");
+
+ DBUG_ASSERT(thd != NULL);
+
+ trx = trx_allocate_for_mysql();
+
+ if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ trx->check_foreigns = FALSE;
+ }
+
+ if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ trx->check_unique_secondary = FALSE;
+ }
+
+
+ fn_format(name2, name, "", "",2); // Remove the .frm extension
+
+ normalize_table_name(norm_name, name2);
+
+ /* Latch the InnoDB data dictionary exclusive so that no deadlocks
+ or lock waits can happen in it during a table create operation.
+ (Drop table etc. do this latching in row0mysql.c.) */
+
+ row_mysql_lock_data_dictionary();
+
+ /* Create the table definition in InnoDB */
+
+ error = create_table_def(trx, form, norm_name);
+
+ if (error) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+
+ /* Look for a primary key */
+
+ primary_key_no= (table->primary_key != MAX_KEY ?
+ (int) table->primary_key :
+ -1);
+
+ /* Our function row_get_mysql_key_number_for_index assumes
+ the primary key is always number 0, if it exists */
+
+ assert(primary_key_no == -1 || primary_key_no == 0);
+
+ /* Create the keys */
+
+ if (form->keys == 0 || primary_key_no == -1) {
+ /* Create an index which is used as the clustered index;
+ order the rows by their row id which is internally generated
+ by InnoDB */
+
+ error = create_clustered_index_when_no_primary(trx,
+ norm_name);
+ if (error) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+ }
+
+ if (primary_key_no != -1) {
+ /* In InnoDB the clustered index must always be created
+ first */
+ if ((error = create_index(trx, form, norm_name,
+ (uint) primary_key_no))) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+ }
+
+ for (i = 0; i < form->keys; i++) {
+
+ if (i != (uint) primary_key_no) {
+
+ if ((error = create_index(trx, form, norm_name, i))) {
+
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+ }
+ }
+
+ error = row_table_add_foreign_constraints(trx,
+ create_info->create_statement, norm_name);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ if (error) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
+ innobase_table = dict_table_get(norm_name, NULL);
+
+ assert(innobase_table != 0);
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(0);
+}
+
+/*********************************************************************
+Drops a table from an InnoDB database. Before calling this function,
+MySQL calls innobase_commit to commit the transaction of the current user.
+Then the current user cannot have locks set on the table. Drop table
+operation inside InnoDB will remove all locks any user has on the table
+inside InnoDB. */
+
+int
+ha_innobase::delete_table(
+/*======================*/
+ /* out: error number */
+ const char* name) /* in: table name */
+{
+ ulint name_len;
+ int error;
+ trx_t* trx;
+ char norm_name[1000];
+
+ DBUG_ENTER("ha_innobase::delete_table");
+
+ trx = trx_allocate_for_mysql();
+
+ name_len = strlen(name);
+
+ assert(name_len < 1000);
+
+ /* Strangely, MySQL passes the table name without the '.frm'
+ extension, in contrast to ::create */
+
+ normalize_table_name(norm_name, name);
+
+ /* Drop the table in InnoDB */
+
+ error = row_drop_table_for_mysql(norm_name, trx, FALSE);
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ innobase_commit_low(trx);
+
+ trx_free_for_mysql(trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*********************************************************************
+Removes all tables in the named database inside InnoDB. */
+
+int
+innobase_drop_database(
+/*===================*/
+ /* out: error number */
+ char* path) /* in: database path; inside InnoDB the name
+ of the last directory in the path is used as
+ the database name: for example, in 'mysql/data/test'
+ the database name is 'test' */
+{
+ ulint len = 0;
+ trx_t* trx;
+ char* ptr;
+ int error;
+ char namebuf[10000];
+
+ ptr = strend(path) - 2;
+
+ while (ptr >= path && *ptr != '\\' && *ptr != '/') {
+ ptr--;
+ len++;
+ }
+
+ ptr++;
+
+ memcpy(namebuf, ptr, len);
+ namebuf[len] = '/';
+ namebuf[len + 1] = '\0';
+#ifdef __WIN__
+ casedn_str(namebuf);
+#endif
+ trx = trx_allocate_for_mysql();
+
+ error = row_drop_database_for_mysql(namebuf, trx);
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ innobase_commit_low(trx);
+ trx_free_for_mysql(trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ return(error);
+}
+
+/*************************************************************************
+Renames an InnoDB table. */
+
+int
+ha_innobase::rename_table(
+/*======================*/
+ /* out: 0 or error code */
+ const char* from, /* in: old name of the table */
+ const char* to) /* in: new name of the table */
+{
+ ulint name_len1;
+ ulint name_len2;
+ int error;
+ trx_t* trx;
+ char norm_from[1000];
+ char norm_to[1000];
+
+ DBUG_ENTER("ha_innobase::rename_table");
+
+ trx = trx_allocate_for_mysql();
+
+ name_len1 = strlen(from);
+ name_len2 = strlen(to);
+
+ assert(name_len1 < 1000);
+ assert(name_len2 < 1000);
+
+ normalize_table_name(norm_from, from);
+ normalize_table_name(norm_to, to);
+
+ /* Rename the table in InnoDB */
+
+ error = row_rename_table_for_mysql(norm_from, norm_to, trx);
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ innobase_commit_low(trx);
+ trx_free_for_mysql(trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*************************************************************************
+Estimates the number of index records in a range. */
+
+ha_rows
+ha_innobase::records_in_range(
+/*==========================*/
+ /* out: estimated number of rows,
+ currently 32-bit int or uint */
+ int keynr, /* in: index number */
+ const mysql_byte* start_key, /* in: start key value of the
+ range, may also be empty */
+ uint start_key_len, /* in: start key val len, may
+ also be 0 */
+ enum ha_rkey_function start_search_flag,/* in: start search condition
+ e.g., 'greater than' */
+ const mysql_byte* end_key, /* in: range end key val, may
+ also be empty */
+ uint end_key_len, /* in: range end key val len,
+ may also be 0 */
+ enum ha_rkey_function end_search_flag)/* in: range end search cond */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ KEY* key;
+ dict_index_t* index;
+ mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc(
+ table->reclength
+ + table->max_key_length + 100,
+ MYF(MY_WME));
+ dtuple_t* range_start;
+ dtuple_t* range_end;
+ ulint n_rows;
+ ulint mode1;
+ ulint mode2;
+ void* heap1;
+ void* heap2;
+
+ DBUG_ENTER("records_in_range");
+
+ /* Warning: since it is not sure that MySQL calls external_lock
+ before calling this function, the trx field in prebuilt can be
+ obsolete! */
+
+ active_index = keynr;
+
+ key = table->key_info + active_index;
+
+ index = dict_table_get_index_noninline(prebuilt->table, key->name);
+
+ range_start = dtuple_create_for_mysql(&heap1, key->key_parts);
+ dict_index_copy_types(range_start, index, key->key_parts);
+
+ range_end = dtuple_create_for_mysql(&heap2, key->key_parts);
+ dict_index_copy_types(range_end, index, key->key_parts);
+
+ row_sel_convert_mysql_key_to_innobase(
+ range_start, (byte*) key_val_buff, index,
+ (byte*) start_key,
+ (ulint) start_key_len);
+
+ row_sel_convert_mysql_key_to_innobase(
+ range_end, (byte*) key_val_buff2, index,
+ (byte*) end_key,
+ (ulint) end_key_len);
+
+ mode1 = convert_search_mode_to_innobase(start_search_flag);
+ mode2 = convert_search_mode_to_innobase(end_search_flag);
+
+ n_rows = btr_estimate_n_rows_in_range(index, range_start,
+ mode1, range_end, mode2);
+ dtuple_free_for_mysql(heap1);
+ dtuple_free_for_mysql(heap2);
+
+ my_free((char*) key_val_buff2, MYF(0));
+
+ DBUG_RETURN((ha_rows) n_rows);
+}
+
+/*************************************************************************
+Gives an UPPER BOUND to the number of rows in a table. This is used in
+filesort.cc and the upper bound must hold. TODO: Since the number of
+rows in a table may change after this function is called, we still may
+get a 'Sort aborted' error in filesort.cc of MySQL. The ultimate fix is to
+improve the algorithm of filesort.cc. */
+
+ha_rows
+ha_innobase::estimate_number_of_rows(void)
+/*======================================*/
+ /* out: upper bound of rows */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ dict_index_t* index;
+ ulonglong estimate;
+ ulonglong data_file_length;
+
+ /* Warning: since it is not sure that MySQL calls external_lock
+ before calling this function, the trx field in prebuilt can be
+ obsolete! */
+
+ DBUG_ENTER("info");
+
+ index = dict_table_get_first_index_noninline(prebuilt->table);
+
+ data_file_length = ((ulonglong) index->stat_n_leaf_pages)
+ * UNIV_PAGE_SIZE;
+
+ /* Calculate a minimum length for a clustered index record and from
+ that an upper bound for the number of rows. Since we only calculate
+ new statistics in row0mysql.c when a tablehas grown
+ by a threshold factor, we must add a safety factor 2 in front
+ of the formula below. */
+
+ estimate = 2 * data_file_length / dict_index_calc_min_rec_len(index);
+
+ DBUG_RETURN((ha_rows) estimate);
+}
+
+/*************************************************************************
+How many seeks it will take to read through the table. This is to be
+comparable to the number returned by records_in_range so that we can
+decide if we should scan the table or use keys. */
+
+double
+ha_innobase::scan_time()
+/*====================*/
+ /* out: estimated time measured in disk seeks */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ /* Since MySQL seems to favor table scans too much over index
+ searches, we pretend that a sequential read takes the same time
+ as a random disk read, that is, we do not divide the following
+ by 10, which would be physically realistic. */
+
+ return((double) (prebuilt->table->stat_clustered_index_size));
+}
+
+/*************************************************************************
+Returns statistics information of the table to the MySQL interpreter,
+in various fields of the handle object. */
+
+void
+ha_innobase::info(
+/*==============*/
+ uint flag) /* in: what information MySQL requests */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ dict_table_t* ib_table;
+ dict_index_t* index;
+ ulong rec_per_key;
+ ulong j;
+ ulong i;
+
+ DBUG_ENTER("info");
+
+ /* Warning: since it is not sure that MySQL calls external_lock
+ before calling this function, the trx field in prebuilt can be
+ obsolete! */
+
+ ib_table = prebuilt->table;
+
+ if (flag & HA_STATUS_TIME) {
+ /* In sql_show we call with this flag: update then statistics
+ so that they are up-to-date */
+
+ dict_update_statistics(ib_table);
+ }
+
+ if (flag & HA_STATUS_VARIABLE) {
+ records = (ha_rows)ib_table->stat_n_rows;
+ deleted = 0;
+ data_file_length = ((ulonglong)
+ ib_table->stat_clustered_index_size)
+ * UNIV_PAGE_SIZE;
+ index_file_length = ((ulonglong)
+ ib_table->stat_sum_of_other_index_sizes)
+ * UNIV_PAGE_SIZE;
+ delete_length = 0;
+ check_time = 0;
+
+ if (records == 0) {
+ mean_rec_length = 0;
+ } else {
+ mean_rec_length = (ulong) (data_file_length / records);
+ }
+ }
+
+ if (flag & HA_STATUS_CONST) {
+ index = dict_table_get_first_index_noninline(ib_table);
+
+ if (prebuilt->clust_index_was_generated) {
+ index = dict_table_get_next_index_noninline(index);
+ }
+
+ for (i = 0; i < table->keys; i++) {
+ for (j = 0; j < table->key_info[i].key_parts; j++) {
+
+ if (index->stat_n_diff_key_vals[j + 1] == 0) {
+
+ rec_per_key = records;
+ } else {
+ rec_per_key = (ulong)(records /
+ index->stat_n_diff_key_vals[j + 1]);
+ }
+
+ /* Since MySQL seems to favor table scans
+ too much over index searches, we pretend
+ index selectivity is 2 times better than
+ our estimate: */
+
+ rec_per_key = rec_per_key / 2;
+
+ if (rec_per_key == 0) {
+ rec_per_key = 1;
+ }
+
+ table->key_info[i].rec_per_key[j]
+ = rec_per_key;
+ }
+
+ index = dict_table_get_next_index_noninline(index);
+ }
+ }
+
+ /* The trx struct in InnoDB contains a pthread mutex embedded:
+ in the debug version of MySQL that it replaced by a 'safe mutex'
+ which is of a different size. We have to use a function to access
+ trx fields. Otherwise trx->error_info will be a random
+ pointer and cause a seg fault. */
+
+ if (flag & HA_STATUS_ERRKEY) {
+ ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
+
+ errkey = (unsigned int) row_get_mysql_key_number_for_index(
+ (dict_index_t*)
+ trx_get_error_info(prebuilt->trx));
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+/***********************************************************************
+Tries to check that an InnoDB table is not corrupted. If corruption is
+noticed, prints to stderr information about it. In case of corruption
+may also assert a failure and crash the server. */
+
+int
+ha_innobase::check(
+/*===============*/
+ /* out: HA_ADMIN_CORRUPT or
+ HA_ADMIN_OK */
+ THD* thd, /* in: user thread handle */
+ HA_CHECK_OPT* check_opt) /* in: check options, currently
+ ignored */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ ulint ret;
+
+ ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (prebuilt->mysql_template == NULL) {
+ /* Build the template; we will use a dummy template
+ in index scans done in checking */
+
+ build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
+ }
+
+ ret = row_check_table_for_mysql(prebuilt);
+
+ if (ret == DB_SUCCESS) {
+ return(HA_ADMIN_OK);
+ }
+
+ return(HA_ADMIN_CORRUPT);
+}
+
+/*****************************************************************
+Adds information about free space in the InnoDB tablespace to a table comment
+which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
+foreign keys. */
+
+char*
+ha_innobase::update_table_comment(
+/*==============================*/
+ /* out: table comment + InnoDB free space +
+ info on foreign keys */
+ const char* comment)/* in: table comment defined by user */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ uint length = strlen(comment);
+ char* str = my_malloc(length + 550, MYF(0));
+ char* pos;
+
+ /* Warning: since it is not sure that MySQL calls external_lock
+ before calling this function, the trx field in prebuilt can be
+ obsolete! */
+
+ if (!str) {
+ return((char*)comment);
+ }
+
+ pos = str;
+ if (length) {
+ pos=strmov(str, comment);
+ *pos++=';';
+ *pos++=' ';
+ }
+
+ pos += sprintf(pos, "InnoDB free: %lu kB",
+ (ulong) innobase_get_free_space());
+
+ /* We assume 450 - length bytes of space to print info */
+
+ if (length < 450) {
+ dict_print_info_on_foreign_keys(FALSE, pos, 450 - length,
+ prebuilt->table);
+ }
+
+ return(str);
+}
+
+/***********************************************************************
+Gets the foreign key create info for a table stored in InnoDB. */
+
+char*
+ha_innobase::get_foreign_key_create_info(void)
+/*==========================================*/
+ /* out, own: character string in the form which
+ can be inserted to the CREATE TABLE statement,
+ MUST be freed with ::free_foreign_key_create_info */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ char* str;
+
+ if (prebuilt == NULL) {
+ fprintf(stderr,
+"InnoDB: Error: cannot get create info for foreign keys\n");
+
+ return(NULL);
+ }
+
+ str = (char*)ut_malloc(10000);
+
+ str[0] = '\0';
+
+ dict_print_info_on_foreign_keys(TRUE, str, 9000, prebuilt->table);
+
+ return(str);
+}
+
+/***********************************************************************
+Frees the foreign key create info for a table stored in InnoDB, if it is
+non-NULL. */
+
+void
+ha_innobase::free_foreign_key_create_info(
+/*======================================*/
+ char* str) /* in, own: create info string to free */
+{
+ if (str) {
+ ut_free(str);
+ }
+}
+
+/***********************************************************************
+Tells something additional to the handler about how to do things. */
+
+int
+ha_innobase::extra(
+/*===============*/
+ /* out: 0 or error number */
+ enum ha_extra_function operation)
+ /* in: HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ /* Warning: since it is not sure that MySQL calls external_lock
+ before calling this function, the trx field in prebuilt can be
+ obsolete! */
+
+ switch (operation) {
+ case HA_EXTRA_RESET:
+ case HA_EXTRA_RESET_STATE:
+ prebuilt->read_just_key = 0;
+ break;
+ case HA_EXTRA_NO_KEYREAD:
+ prebuilt->read_just_key = 0;
+ break;
+ case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
+ prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+ break;
+ case HA_EXTRA_KEYREAD:
+ prebuilt->read_just_key = 1;
+ break;
+ default:/* Do nothing */
+ ;
+ }
+
+ return(0);
+}
+
+/**********************************************************************
+????????????? */
+
+int
+ha_innobase::reset(void)
+/*====================*/
+{
+ return(0);
+}
+
+/**********************************************************************
+As MySQL will execute an external lock for every new table it uses when it
+starts to process an SQL statement, we can use this function to store the
+pointer to the THD in the handle. We will also use this function to communicate
+to InnoDB that a new SQL statement has started and that we must store a
+savepoint to our transaction handle, so that we are able to roll back
+the SQL statement in case of an error. */
+
+int
+ha_innobase::external_lock(
+/*=======================*/
+ THD* thd, /* in: handle to the user thread */
+ int lock_type) /* in: lock type */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("ha_innobase::external_lock");
+
+ update_thd(thd);
+
+ trx = prebuilt->trx;
+
+ prebuilt->sql_stat_start = TRUE;
+ prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
+
+ prebuilt->read_just_key = 0;
+
+ if (lock_type == F_WRLCK) {
+
+ /* If this is a SELECT, then it is in UPDATE TABLE ...
+ or SELECT ... FOR UPDATE */
+ prebuilt->select_lock_type = LOCK_X;
+ }
+
+ if (lock_type != F_UNLCK) {
+ if (trx->n_mysql_tables_in_use == 0) {
+ trx_mark_sql_stat_end(trx);
+ }
+
+ thd->transaction.all.innodb_active_trans = 1;
+ trx->n_mysql_tables_in_use++;
+
+ if (thd->variables.tx_isolation == ISO_SERIALIZABLE
+ && prebuilt->select_lock_type == LOCK_NONE) {
+
+ /* To get serializable execution we let InnoDB
+ conceptually add 'LOCK IN SHARE MODE' to all SELECTs
+ which otherwise would have been consistent reads */
+
+ prebuilt->select_lock_type = LOCK_S;
+ }
+
+ if (prebuilt->select_lock_type != LOCK_NONE) {
+
+ trx->mysql_n_tables_locked++;
+ }
+ } else {
+ trx->n_mysql_tables_in_use--;
+ auto_inc_counter_for_this_stat = 0;
+
+ if (trx->n_mysql_tables_in_use == 0) {
+
+ trx->mysql_n_tables_locked = 0;
+
+ /* Here we release the search latch, auto_inc_lock,
+ and InnoDB thread FIFO ticket if they were reserved. */
+
+ innobase_release_stat_resources(trx);
+
+ if (!(thd->options
+ & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+
+ innobase_commit(thd, trx);
+ thd->transaction.all.innodb_active_trans=0;
+ }
+ }
+ }
+
+ DBUG_RETURN(error);
+}
+
+/****************************************************************************
+Implements the SHOW INNODB STATUS command. Send the output of the InnoDB
+Monitor to the client. */
+
+int
+innodb_show_status(
+/*===============*/
+ THD* thd) /* in: the MySQL query thread of the caller */
+{
+ String* packet = &thd->packet;
+ char* buf;
+
+ DBUG_ENTER("innodb_show_status");
+
+ /* We let the InnoDB Monitor to output at most 100 kB of text */
+ buf = (char*)ut_malloc(100 * 1024);
+
+ srv_sprintf_innodb_monitor(buf, 100 * 1024);
+
+ List<Item> field_list;
+
+ field_list.push_back(new Item_empty_string("Status", strlen(buf)));
+
+ if(send_fields(thd, field_list, 1)) {
+ DBUG_RETURN(-1);
+ }
+
+ packet->length(0);
+
+ net_store_data(packet, buf);
+
+ if (my_net_write(&thd->net, (char*)thd->packet.ptr(),
+ packet->length())) {
+ ut_free(buf);
+
+ DBUG_RETURN(-1);
+ }
+
+ ut_free(buf);
+
+ send_eof(&thd->net);
+
+ DBUG_RETURN(0);
+}
+
+/****************************************************************************
+ Handling the shared INNOBASE_SHARE structure that is needed to provide table
+ locking.
+****************************************************************************/
+
+static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length=share->table_name_length;
+ return (mysql_byte*) share->table_name;
+}
+
+static INNOBASE_SHARE *get_share(const char *table_name)
+{
+ INNOBASE_SHARE *share;
+ pthread_mutex_lock(&innobase_mutex);
+ uint length=(uint) strlen(table_name);
+ if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
+ (mysql_byte*) table_name,
+ length)))
+ {
+ if ((share=(INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ share->table_name_length=length;
+ share->table_name=(char*) (share+1);
+ strmov(share->table_name,table_name);
+ if (hash_insert(&innobase_open_tables, (mysql_byte*) share))
+ {
+ pthread_mutex_unlock(&innobase_mutex);
+ my_free((gptr) share,0);
+ return 0;
+ }
+ thr_lock_init(&share->lock);
+ pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
+ }
+ }
+ share->use_count++;
+ pthread_mutex_unlock(&innobase_mutex);
+ return share;
+}
+
+static void free_share(INNOBASE_SHARE *share)
+{
+ pthread_mutex_lock(&innobase_mutex);
+ if (!--share->use_count)
+ {
+ hash_delete(&innobase_open_tables, (mysql_byte*) share);
+ thr_lock_delete(&share->lock);
+ pthread_mutex_destroy(&share->mutex);
+ my_free((gptr) share, MYF(0));
+ }
+ pthread_mutex_unlock(&innobase_mutex);
+}
+
+/*********************************************************************
+Stores a MySQL lock into a 'lock' field in a handle. */
+
+THR_LOCK_DATA**
+ha_innobase::store_lock(
+/*====================*/
+ /* out: pointer to the next
+ element in the 'to' array */
+ THD* thd, /* in: user thread handle */
+ THR_LOCK_DATA** to, /* in: pointer to an array
+ of pointers to lock structs;
+ pointer to the 'lock' field
+ of current handle is stored
+ next to this array */
+ enum thr_lock_type lock_type) /* in: lock type to store in
+ 'lock' */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ if (lock_type == TL_READ_WITH_SHARED_LOCKS ||
+ lock_type == TL_READ_NO_INSERT) {
+ /* This is a SELECT ... IN SHARE MODE, or
+ we are doing a complex SQL statement like
+ INSERT INTO ... SELECT ... and the logical logging (MySQL
+ binlog) requires the use of a locking read */
+
+ prebuilt->select_lock_type = LOCK_S;
+ } else {
+ /* We set possible LOCK_X value in external_lock, not yet
+ here even if this would be SELECT ... FOR UPDATE */
+
+ prebuilt->select_lock_type = LOCK_NONE;
+ }
+
+ if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
+
+ /* If we are not doing a LOCK TABLE, then allow multiple
+ writers */
+
+ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
+ lock_type <= TL_WRITE) && !thd->in_lock_tables) {
+
+ lock_type = TL_WRITE_ALLOW_WRITE;
+ }
+
+ lock.type=lock_type;
+ }
+
+ *to++= &lock;
+
+ return(to);
+}
+
+/***********************************************************************
+Returns the next auto-increment column value for the table. write_row
+normally fetches the value from the cache in the data dictionary. This
+function in used by SHOW TABLE STATUS and when the first insert to the table
+is done after database startup. */
+
+longlong
+ha_innobase::get_auto_increment()
+/*=============================*/
+ /* out: the next auto-increment column value */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ longlong nr;
+ int error;
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ /* Also SHOW TABLE STATUS calls this function. Previously, when we did
+ always read the max autoinc key value, setting x-locks, users were
+ surprised that SHOW TABLE STATUS could end up in a deadlock with
+ ordinary SQL queries. We avoid these deadlocks if the auto-inc
+ counter for the table has been initialized by fetching the value
+ from the table struct in dictionary cache. */
+
+ assert(prebuilt->table);
+
+ nr = dict_table_autoinc_read(prebuilt->table);
+
+ if (nr != 0) {
+
+ return(nr + 1);
+ }
+
+ (void) extra(HA_EXTRA_KEYREAD);
+ index_init(table->next_number_index);
+
+ /* We use an exclusive lock when we read the max key value from the
+ auto-increment column index. This is because then build_template will
+ advise InnoDB to fetch all columns. In SHOW TABLE STATUS the query
+ id of the auto-increment column is not changed, and previously InnoDB
+ did not fetch it, causing SHOW TABLE STATUS to show wrong values
+ for the autoinc column. */
+
+ prebuilt->select_lock_type = LOCK_X;
+
+ /* Play safe and also give in another way the hint to fetch
+ all columns in the key: */
+
+ prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+
+ prebuilt->trx->mysql_n_tables_locked += 1;
+
+ error = index_last(table->record[1]);
+
+ if (error) {
+ nr = 1;
+ } else {
+ nr = (longlong) table->next_number_field->
+ val_int_offset(table->rec_buff_length) + 1;
+ }
+
+ (void) extra(HA_EXTRA_NO_KEYREAD);
+
+ index_end();
+
+ return(nr);
+}
+
+#endif /* HAVE_INNOBASE_DB */
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
new file mode 100644
index 00000000000..7ea297cc362
--- /dev/null
+++ b/sql/ha_innodb.h
@@ -0,0 +1,206 @@
+/* Copyright (C) 2000 MySQL AB && Innobase Oy
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ This file is based on ha_berkeley.h of MySQL distribution
+
+ This file defines the Innodb handler: the interface between MySQL and
+ Innodb
+*/
+
+#ifdef __GNUC__
+#pragma interface /* gcc class implementation */
+#endif
+
+typedef struct st_innobase_share {
+ THR_LOCK lock;
+ pthread_mutex_t mutex;
+ char *table_name;
+ uint table_name_length,use_count;
+} INNOBASE_SHARE;
+
+
+/* The class defining a handle to an Innodb table */
+class ha_innobase: public handler
+{
+ void* innobase_prebuilt; /* (row_prebuilt_t*) prebuilt
+ struct in Innodb, used to save
+ CPU */
+ THD* user_thd; /* the thread handle of the user
+ currently using the handle; this is
+ set in external_lock function */
+ ulong last_query_id; /* the latest query id where the
+ handle was used */
+ THR_LOCK_DATA lock;
+ INNOBASE_SHARE *share;
+
+ gptr alloc_ptr;
+ byte* upd_buff; /* buffer used in updates */
+ byte* key_val_buff; /* buffer used in converting
+ search key values from MySQL format
+ to Innodb format */
+ uint ref_stored_len; /* length of the key value stored to
+ 'ref' buffer of the handle, if any */
+ ulong int_table_flags;
+ uint primary_key;
+ uint last_dup_key;
+ ulong start_of_scan; /* this is set to 1 when we are
+ starting a table scan but have not
+ yet fetched any row, else 0 */
+
+ uint last_match_mode;/* match mode of the latest search:
+ ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
+ or undefined */
+ longlong auto_inc_counter_for_this_stat;
+ ulong max_row_length(const byte *buf);
+
+ uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
+ int update_thd(THD* thd);
+ int change_active_index(uint keynr);
+ int general_fetch(byte* buf, uint direction, uint match_mode);
+
+ /* Init values for the class: */
+ public:
+ ha_innobase(TABLE *table): handler(table),
+ int_table_flags(HA_REC_NOT_IN_SEQ |
+ HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_NULL_KEY |
+ HA_NOT_EXACT_COUNT |
+ HA_NO_WRITE_DELAYED |
+ HA_PRIMARY_KEY_IN_READ_INDEX |
+ HA_DROP_BEFORE_CREATE |
+ HA_NO_PREFIX_CHAR_KEYS |
+ HA_TABLE_SCAN_ON_INDEX),
+ last_dup_key((uint) -1),
+ start_of_scan(0)
+ {
+ }
+ ~ha_innobase() {}
+
+ const char* table_type() const { return("InnoDB");}
+ const char *index_type(uint key_number) { return "BTREE"; }
+ const char** bas_ext() const;
+ ulong table_flags() const { return int_table_flags; }
+ ulong index_flags(uint idx) const
+ {
+ return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER |
+ HA_NOT_READ_PREFIX_LAST | HA_KEY_READ_ONLY);
+ }
+ uint max_record_length() const { return HA_MAX_REC_LENGTH; }
+ uint max_keys() const { return MAX_KEY; }
+ uint max_key_parts() const { return MAX_REF_PARTS; }
+ /* An InnoDB page must store >= 2 keys;
+ a secondary key record must also contain the
+ primary key value:
+ max key length is therefore set to slightly
+ less than 1 / 4 of page size which is 16 kB;
+ but currently MySQL does not work with keys
+ whose size is > MAX_KEY_LENGTH */
+ uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
+ MAX_KEY_LENGTH : 3500);}
+ bool fast_key_read() { return 1;}
+ key_map keys_to_use_for_scanning() { return ~(key_map) 0; }
+ bool has_transactions() { return 1;}
+
+ int open(const char *name, int mode, uint test_if_locked);
+ void initialize(void);
+ int close(void);
+ double scan_time();
+
+ int write_row(byte * buf);
+ int update_row(const byte * old_data, byte * new_data);
+ int delete_row(const byte * buf);
+
+ int index_init(uint index);
+ int index_end();
+ int index_read(byte * buf, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_read_idx(byte * buf, uint index, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
+ int index_next(byte * buf);
+ int index_next_same(byte * buf, const byte *key, uint keylen);
+ int index_prev(byte * buf);
+ int index_first(byte * buf);
+ int index_last(byte * buf);
+
+ int rnd_init(bool scan=1);
+ int rnd_end();
+ int rnd_next(byte *buf);
+ int rnd_pos(byte * buf, byte *pos);
+
+ void position(const byte *record);
+ void info(uint);
+ int extra(enum ha_extra_function operation);
+ int reset(void);
+ int external_lock(THD *thd, int lock_type);
+ void position(byte *record);
+ ha_rows records_in_range(int inx,
+ const byte *start_key,uint start_key_len,
+ enum ha_rkey_function start_search_flag,
+ const byte *end_key,uint end_key_len,
+ enum ha_rkey_function end_search_flag);
+ ha_rows estimate_number_of_rows();
+
+ int create(const char *name, register TABLE *form,
+ HA_CREATE_INFO *create_info);
+ int delete_table(const char *name);
+ int rename_table(const char* from, const char* to);
+ int check(THD* thd, HA_CHECK_OPT* check_opt);
+ char* update_table_comment(const char* comment);
+ char* get_foreign_key_create_info();
+ void free_foreign_key_create_info(char* str);
+ THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type);
+ longlong get_auto_increment();
+};
+
+extern bool innodb_skip;
+extern SHOW_COMP_OPTION have_innodb;
+extern uint innobase_init_flags, innobase_lock_type;
+extern ulong innobase_cache_size;
+extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
+extern long innobase_lock_scan_time;
+extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
+extern long innobase_log_file_size, innobase_log_buffer_size;
+extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
+extern long innobase_file_io_threads, innobase_lock_wait_timeout;
+extern long innobase_force_recovery, innobase_thread_concurrency;
+extern char *innobase_data_home_dir, *innobase_data_file_path;
+extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
+extern char *innobase_unix_file_flush_method;
+/* The following variables have to be my_bool for SHOW VARIABLES to work */
+extern my_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
+ innobase_use_native_aio, innobase_fast_shutdown;
+
+extern TYPELIB innobase_lock_typelib;
+
+bool innobase_init(void);
+bool innobase_end(void);
+bool innobase_flush_logs(void);
+uint innobase_get_free_space(void);
+
+int innobase_commit(THD *thd, void* trx_handle);
+int innobase_report_binlog_offset_and_commit(
+ THD* thd,
+ void* trx_handle,
+ char* log_file_name,
+ my_off_t end_offset);
+int innobase_rollback(THD *thd, void* trx_handle);
+int innobase_close_connection(THD *thd);
+int innobase_drop_database(char *path);
+int innodb_show_status(THD* thd);
+
diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc
index ac37d09e6b4..55d24f5edb9 100644
--- a/sql/ha_isam.cc
+++ b/sql/ha_isam.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,6 +20,7 @@
#endif
#include "mysql_priv.h"
+#ifdef HAVE_ISAM
#include <m_ctype.h>
#include <myisampack.h>
#include "ha_isam.h"
@@ -51,7 +52,7 @@ int ha_isam::open(const char *name, int mode, uint test_if_locked)
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
(void) nisam_extra(file,HA_EXTRA_WAIT_LOCK);
if (!table->db_record_offset)
- int_option_flag|=HA_REC_NOT_IN_SEQ;
+ int_table_flags|=HA_REC_NOT_IN_SEQ;
return (0);
}
@@ -108,6 +109,15 @@ int ha_isam::index_read_idx(byte * buf, uint index, const byte * key,
return !error ? 0 : my_errno ? my_errno : -1;
}
+int ha_isam::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ int error=nisam_rkey(file, buf, active_index, key, key_len,
+ HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
+ return !error ? 0 : my_errno ? my_errno : -1;
+}
+
int ha_isam::index_next(byte * buf)
{
statistic_increment(ha_read_next_count,&LOCK_status);
@@ -123,7 +133,7 @@ int ha_isam::index_prev(byte * buf)
table->status=error ? STATUS_NOT_FOUND: 0;
return !error ? 0 : my_errno ? my_errno : HA_ERR_END_OF_FILE;
}
-
+
int ha_isam::index_first(byte * buf)
{
statistic_increment(ha_read_first_count,&LOCK_status);
@@ -235,7 +245,7 @@ int ha_isam::reset(void)
int ha_isam::external_lock(THD *thd, int lock_type)
{
return nisam_lock_database(file,lock_type);
-}
+}
THR_LOCK_DATA **ha_isam::store_lock(THD *thd,
@@ -315,7 +325,7 @@ int ha_isam::create(const char *name, register TABLE *form,
{
/* skip null fields */
if (!(temp_length= (*field)->pack_length()))
- continue; /* Skipp null-fields */
+ continue; /* Skip null-fields */
if (! found || fieldpos < minpos ||
(fieldpos == minpos && temp_length < length))
{
@@ -343,15 +353,15 @@ int ha_isam::create(const char *name, register TABLE *form,
else if (!(options & HA_OPTION_PACK_RECORD))
recinfo_pos->base.type= (int) FIELD_NORMAL;
else if (found->zero_pack())
- recinfo_pos->base.type= (int) FIELD_SKIPP_ZERO;
+ recinfo_pos->base.type= (int) FIELD_SKIP_ZERO;
else
recinfo_pos->base.type= (int) ((length <= 3 ||
(found->flags & ZEROFILL_FLAG)) ?
FIELD_NORMAL :
found->type() == FIELD_TYPE_STRING ||
found->type() == FIELD_TYPE_VAR_STRING ?
- FIELD_SKIPP_ENDSPACE :
- FIELD_SKIPP_PRESPACE);
+ FIELD_SKIP_ENDSPACE :
+ FIELD_SKIP_PRESPACE);
recinfo_pos++ ->base.length=(uint16) length;
recpos=minpos+length;
DBUG_PRINT("loop",("length: %d type: %d",
@@ -388,3 +398,4 @@ ha_rows ha_isam::records_in_range(int inx,
end_key,end_key_len,
end_search_flag);
}
+#endif /* HAVE_ISAM */
diff --git a/sql/ha_isam.h b/sql/ha_isam.h
index 5e01edcf889..82a243ef5c0 100644
--- a/sql/ha_isam.h
+++ b/sql/ha_isam.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -26,20 +26,21 @@
class ha_isam: public handler
{
N_INFO *file;
- uint int_option_flag;
+ /* We need this as table_flags() may change after open() */
+ ulong int_table_flags;
public:
- ha_isam(TABLE *table): handler(table), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_KEY_READ_WRONG_STR | HA_DUPP_POS |
- HA_NOT_DELETE_WITH_CACHE | HA_NO_FULLTEXT_KEY)
- {}
+ ha_isam(TABLE *table)
+ :handler(table), file(0),
+ int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_KEY_READ_WRONG_STR | HA_DUPP_POS |
+ HA_NOT_DELETE_WITH_CACHE)
+ {}
~ha_isam() {}
const char *table_type() const { return "ISAM"; }
+ const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
+ ulong table_flags() const { return int_table_flags; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return N_MAXKEY; }
uint max_key_parts() const { return N_MAXKEY_SEG; }
@@ -56,6 +57,7 @@ class ha_isam: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_prev(byte * buf);
int index_first(byte * buf);
@@ -78,11 +80,4 @@ class ha_isam: public handler
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
-
};
-
-
-
-
-
-
diff --git a/sql/ha_isammrg.cc b/sql/ha_isammrg.cc
index dd2e4e2f723..b110ffba2f9 100644
--- a/sql/ha_isammrg.cc
+++ b/sql/ha_isammrg.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,11 +20,12 @@
#endif
#include "mysql_priv.h"
+#ifdef HAVE_ISAM
#include <m_ctype.h>
#ifndef MASTER
-#include "../srclib/merge/mrgdef.h"
+#include "../srclib/merge/mrg_def.h"
#else
-#include "../merge/mrgdef.h"
+#include "../merge/mrg_def.h"
#endif
#include "ha_isammrg.h"
@@ -109,7 +110,7 @@ int ha_isammrg::index_prev(byte * buf)
{
return (my_errno=HA_ERR_WRONG_COMMAND);
}
-
+
int ha_isammrg::index_first(byte * buf)
{
return (my_errno=HA_ERR_WRONG_COMMAND);
@@ -178,7 +179,7 @@ int ha_isammrg::reset(void)
int ha_isammrg::external_lock(THD *thd, int lock_type)
{
return !mrg_lock_database(file,lock_type) ? 0 : my_errno ? my_errno : -1;
-}
+}
uint ha_isammrg::lock_count(void) const
{
@@ -208,3 +209,4 @@ int ha_isammrg::create(const char *name, register TABLE *form,
char buff[FN_REFLEN];
return mrg_create(fn_format(buff,name,"","",2+4+16),0);
}
+#endif /* HAVE_ISAM */
diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h
index c8eb7dd9f69..bbe75a74db8 100644
--- a/sql/ha_isammrg.h
+++ b/sql/ha_isammrg.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -32,8 +32,10 @@ class ha_isammrg: public handler
~ha_isammrg() {}
const char *table_type() const { return "MRG_ISAM"; }
const char **bas_ext() const;
- ulong option_flag() const { return HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS
- | HA_REC_NOT_IN_SEQ | HA_NO_FULLTEXT_KEY;}
+ ulong table_flags() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS |
+ HA_NOT_READ_PREFIX_LAST |
+ HA_REC_NOT_IN_SEQ); }
+ ulong index_flags(uint idx) const { return 0; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return 0; }
uint max_key_parts() const { return 0; }
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 595c83ff8ef..6ff59babeb4 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -30,13 +30,12 @@
#include "../myisam/myisamdef.h"
#endif
-ulong myisam_sort_buffer_size;
ulong myisam_recover_options= HA_RECOVER_NONE;
/* bits in myisam_recover_options */
const char *myisam_recover_names[] =
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS};
-TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
+TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
myisam_recover_names};
@@ -45,6 +44,7 @@ TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
*****************************************************************************/
// collect errors printed by mi_check routines
+
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
const char *fmt, va_list args)
{
@@ -66,8 +66,7 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
sql_print_error(msgbuf);
return;
}
- if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR |
- T_AUTO_REPAIR))
+ if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR | T_AUTO_REPAIR))
{
my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
return;
@@ -80,9 +79,8 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
net_store_data(packet, msgbuf);
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), thd->packet.length()))
- fprintf(stderr,
- "Failed on my_net_write, writing to stderr instead: %s\n",
- msgbuf);
+ sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
+ msgbuf);
return;
}
@@ -122,15 +120,22 @@ const char **ha_myisam::bas_ext() const
{ static const char *ext[]= { ".MYD",".MYI", NullS }; return ext; }
+const char *ha_myisam::index_type(uint key_number)
+{
+ return ((table->key_info[key_number].flags & HA_FULLTEXT) ?
+ "FULLTEXT" :
+ "BTREE");
+}
+
int ha_myisam::net_read_dump(NET* net)
{
int data_fd = file->dfile;
int error = 0;
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
- for(;;)
+ for (;;)
{
- uint packet_len = my_net_read(net);
+ ulong packet_len = my_net_read(net);
if (!packet_len)
break ; // end of file
if (packet_len == packet_error)
@@ -139,7 +144,7 @@ int ha_myisam::net_read_dump(NET* net)
error= -1;
goto err;
}
- if (my_write(data_fd, (byte*)net->read_pos, packet_len,
+ if (my_write(data_fd, (byte*)net->read_pos, (uint) packet_len,
MYF(MY_WME|MY_FNABP)))
{
error = errno;
@@ -165,7 +170,7 @@ int ha_myisam::dump(THD* thd, int fd)
int error = 0;
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
- for(; bytes_to_read > 0;)
+ for (; bytes_to_read > 0;)
{
uint bytes = my_read(data_fd, buf, blocksize, MYF(MY_WME));
if (bytes == MY_FILE_ERROR)
@@ -212,12 +217,12 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
return (my_errno ? my_errno : -1);
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
- VOID(mi_extra(file,HA_EXTRA_NO_WAIT_LOCK));
+ VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
- VOID(mi_extra(file,HA_EXTRA_WAIT_LOCK));
+ VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
if (!table->db_record_offset)
- int_option_flag|=HA_REC_NOT_IN_SEQ;
+ int_table_flags|=HA_REC_NOT_IN_SEQ;
return (0);
}
@@ -283,7 +288,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
error = chk_key(&param, file);
if (!error)
{
- if ((!check_opt->quick &&
+ if ((!(param.testflag & T_QUICK) &&
((share->options &
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
(param.testflag & (T_EXTEND | T_MEDIUM)))) ||
@@ -324,7 +329,6 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
mi_mark_crashed(file);
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
}
- check_opt->retry_without_quick=param.retry_without_quick;
thd->proc_info=old_proc_info;
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
@@ -374,14 +378,14 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name;
+ int error;
+ const char* errmsg;
DBUG_ENTER("restore");
- if (!fn_format(src_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
+ if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
+ MI_NAME_DEXT))
DBUG_RETURN(HA_ADMIN_INVALID);
- int error = 0;
- const char* errmsg = "";
-
if (my_copy(src_path, fn_format(dst_path, table->path, "",
MI_NAME_DEXT, 4), MYF(MY_WME)))
{
@@ -391,8 +395,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
}
tmp_check_opt.init();
- tmp_check_opt.quick = 1;
- tmp_check_opt.flags |= T_VERY_SILENT | T_CALC_CHECKSUM;
+ tmp_check_opt.flags |= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
DBUG_RETURN(repair(thd, &tmp_check_opt));
err:
@@ -404,7 +407,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
param.db_name = table->table_cache_key;
param.table_name = table->table_name;
param.testflag = 0;
- mi_check_print_error(&param,errmsg, errno );
+ mi_check_print_error(&param,errmsg, my_errno);
DBUG_RETURN(error);
}
}
@@ -415,41 +418,47 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name;
- int error = 0;
- const char* errmsg = "";
-
- if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .frm file: errno = %d";
- error = HA_ADMIN_INVALID;
- goto err;
- }
-
- if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )))
+ int error;
+ const char *errmsg;
+ DBUG_ENTER("ha_myisam::backup");
+
+ if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir,
+ reg_ext))
+ {
+ errmsg = "Failed in fn_format() for .frm file: errno = %d";
+ error = HA_ADMIN_INVALID;
+ goto err;
+ }
+
+ if (my_copy(fn_format(src_path, table->path,"", reg_ext, MY_UNPACK_FILENAME),
+ dst_path,
+ MYF(MY_WME | MY_HOLD_ORIGINAL_MODES)))
{
error = HA_ADMIN_FAILED;
errmsg = "Failed copying .frm file: errno = %d";
goto err;
}
- if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .MYD file: errno = %d";
- error = HA_ADMIN_INVALID;
- goto err;
- }
+ /* Change extension */
+ if (!fn_format(dst_path, dst_path, "", MI_NAME_DEXT,
+ MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH))
+ {
+ errmsg = "Failed in fn_format() for .MYD file: errno = %d";
+ error = HA_ADMIN_INVALID;
+ goto err;
+ }
- if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4),
+ if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT,
+ MY_UNPACK_FILENAME),
dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
- {
- errmsg = "Failed copying .MYD file: errno = %d";
- error= HA_ADMIN_FAILED;
- goto err;
- }
- return HA_ADMIN_OK;
+ MYF(MY_WME | MY_HOLD_ORIGINAL_MODES)))
+ {
+ errmsg = "Failed copying .MYD file: errno = %d";
+ error= HA_ADMIN_FAILED;
+ goto err;
+ }
+ DBUG_RETURN(HA_ADMIN_OK);
+
err:
{
MI_CHECK param;
@@ -459,8 +468,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
param.db_name = table->table_cache_key;
param.table_name = table->table_name;
param.testflag = 0;
- mi_check_print_error(&param,errmsg, errno );
- return error;
+ mi_check_print_error(&param,errmsg, my_errno);
+ DBUG_RETURN(error);
}
}
@@ -476,24 +485,23 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
myisamchk_init(&param);
param.thd = thd;
param.op_name = (char*) "repair";
- param.testflag = ((check_opt->flags & ~(T_EXTEND)) |
+ param.testflag = ((check_opt->flags & ~(T_EXTEND)) |
T_SILENT | T_FORCE_CREATE |
(check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
- if (check_opt->quick)
- param.opt_rep_quick++;
param.sort_buffer_length= check_opt->sort_buffer_size;
start_records=file->state->records;
while ((error=repair(thd,param,0)) && param.retry_repair)
{
param.retry_repair=0;
- if (param.retry_without_quick && param.opt_rep_quick)
+ if (test_all_bits(param.testflag,
+ (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
- param.opt_rep_quick=0;
+ param.testflag&= ~T_RETRY_WITHOUT_QUICK;
sql_print_error("Warning: Retrying repair of: '%s' without quick",
table->path);
continue;
}
- param.opt_rep_quick=0; // Safety
+ param.testflag&= ~T_QUICK;
if ((param.testflag & T_REP_BY_SORT))
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
@@ -525,8 +533,6 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
param.op_name = (char*) "optimize";
param.testflag = (check_opt->flags | T_SILENT | T_FORCE_CREATE |
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
- if (check_opt->quick)
- param.opt_rep_quick++;
param.sort_buffer_length= check_opt->sort_buffer_size;
return repair(thd,param,1);
}
@@ -537,8 +543,8 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
int error=0;
uint local_testflag=param.testflag;
bool optimize_done= !optimize, statistics_done=0;
- char fixed_name[FN_REFLEN];
const char *old_proc_info=thd->proc_info;
+ char fixed_name[FN_REFLEN];
MYISAM_SHARE* share = file->s;
ha_rows rows= file->state->records;
DBUG_ENTER("ha_myisam::repair");
@@ -550,8 +556,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
param.thd=thd;
param.tmpdir=mysql_tmpdir;
param.out_flag=0;
- VOID(fn_format(fixed_name,file->filename,"",MI_NAME_IEXT,
- 4+ (param.opt_follow_links ? 16 : 0)));
+ strmov(fixed_name,file->filename);
// Don't lock tables if we have used LOCK TABLE
if (!thd->locked_tables && mi_lock_database(file,F_WRLCK))
@@ -562,7 +567,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
if (!optimize ||
((file->state->del || share->state.split != file->state->records) &&
- (!param.opt_rep_quick ||
+ (!(param.testflag & T_QUICK) ||
!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))))
{
ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
@@ -576,13 +581,15 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
param.testflag|= T_STATISTICS; // We get this for free
thd->proc_info="Repair by sorting";
statistics_done=1;
- error = mi_repair_by_sort(&param, file, fixed_name, param.opt_rep_quick);
+ error = mi_repair_by_sort(&param, file, fixed_name,
+ param.testflag & T_QUICK);
}
else
{
thd->proc_info="Repair with keycache";
param.testflag &= ~T_REP_BY_SORT;
- error= mi_repair(&param, file, fixed_name, param.opt_rep_quick);
+ error= mi_repair(&param, file, fixed_name,
+ param.testflag & T_QUICK);
}
param.testflag=testflag;
optimize_done=1;
@@ -653,8 +660,24 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
void ha_myisam::deactivate_non_unique_index(ha_rows rows)
{
- if (!(specialflag & SPECIAL_SAFE_MODE))
- mi_disable_non_unique_index(file,rows);
+ MYISAM_SHARE* share = file->s;
+ if (share->state.key_map == ((ulonglong) 1L << share->base.keys)-1)
+ {
+ if (!(specialflag & SPECIAL_SAFE_MODE))
+ {
+ if (rows == HA_POS_ERROR)
+ mi_extra(file, HA_EXTRA_NO_KEYS, 0);
+ else
+ {
+ mi_disable_non_unique_index(file,rows);
+ ha_myisam::extra_opt(HA_EXTRA_BULK_INSERT_BEGIN,
+ current_thd->variables.bulk_insert_buff_size);
+ }
+ }
+ enable_activate_all_index=1;
+ }
+ else
+ enable_activate_all_index=0;
}
@@ -664,21 +687,25 @@ bool ha_myisam::activate_all_index(THD *thd)
MI_CHECK param;
MYISAM_SHARE* share = file->s;
DBUG_ENTER("activate_all_index");
- if (share->state.key_map != set_bits(ulonglong, share->base.keys))
+
+ mi_extra(file, HA_EXTRA_BULK_INSERT_END, 0);
+ if (enable_activate_all_index &&
+ share->state.key_map != set_bits(ulonglong, share->base.keys))
{
const char *save_proc_info=thd->proc_info;
thd->proc_info="Creating index";
myisamchk_init(&param);
param.op_name = (char*) "recreating_index";
- param.testflag = (T_SILENT | T_REP_BY_SORT |
- T_CREATE_MISSING_KEYS | T_TRUST_HEADER);
+ param.testflag = (T_SILENT | T_REP_BY_SORT | T_QUICK |
+ T_CREATE_MISSING_KEYS);
param.myf_rw&= ~MY_WAIT_IF_FULL;
- param.sort_buffer_length= myisam_sort_buffer_size;
- param.opt_rep_quick++; // Don't copy data file
+ param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
param.tmpdir=mysql_tmpdir;
error=repair(thd,param,0) != HA_ADMIN_OK;
thd->proc_info=save_proc_info;
}
+ else
+ enable_activate_all_index=1;
DBUG_RETURN(error);
}
@@ -694,16 +721,16 @@ bool ha_myisam::check_and_repair(THD *thd)
check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
// Don't use quick if deleted rows
if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
- check_opt.quick=1;
+ check_opt.flags|=T_QUICK;
sql_print_error("Warning: Checking table: '%s'",table->path);
if ((marked_crashed=mi_is_crashed(file)) || check(thd, &check_opt))
{
sql_print_error("Warning: Recovering table: '%s'",table->path);
- check_opt.quick= !check_opt.retry_without_quick && !marked_crashed;
- check_opt.flags=(((myisam_recover_options & HA_RECOVER_BACKUP) ?
- T_BACKUP_DATA : 0) |
- (!(myisam_recover_options & HA_RECOVER_FORCE) ?
- T_SAFE_REPAIR : 0)) | T_AUTO_REPAIR;
+ check_opt.flags=
+ ((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
+ (marked_crashed ? 0 : T_QUICK) |
+ (myisam_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) |
+ T_AUTO_REPAIR);
if (repair(thd, &check_opt))
error=1;
}
@@ -748,6 +775,14 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key,
return error;
}
+int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
+ return error;
+}
+
int ha_myisam::index_next(byte * buf)
{
statistic_increment(ha_read_next_count,&LOCK_status);
@@ -795,8 +830,7 @@ int ha_myisam::rnd_init(bool scan)
{
if (scan)
return mi_scan_init(file);
- else
- return mi_extra(file,HA_EXTRA_RESET);
+ return mi_extra(file, HA_EXTRA_RESET, 0);
}
int ha_myisam::rnd_next(byte *buf)
@@ -829,6 +863,8 @@ void ha_myisam::position(const byte* record)
void ha_myisam::info(uint flag)
{
MI_ISAMINFO info;
+ char name_buff[FN_REFLEN];
+
(void) mi_status(file,&info,flag);
if (flag & HA_STATUS_VARIABLE)
{
@@ -849,7 +885,8 @@ void ha_myisam::info(uint flag)
ref_length=info.reflength;
table->db_options_in_use = info.options;
block_size=myisam_block_size;
- table->keys_in_use &= info.key_map;
+ table->keys_in_use&= info.key_map;
+ table->keys_for_keyread&= info.key_map;
table->db_record_offset=info.record_offset;
if (table->key_parts)
memcpy((char*) table->key_info[0].rec_per_key,
@@ -858,6 +895,18 @@ void ha_myisam::info(uint flag)
raid_type=info.raid_type;
raid_chunks=info.raid_chunks;
raid_chunksize=info.raid_chunksize;
+
+ /*
+ Set data_file_name and index_file_name to point at the symlink value
+ if table is symlinked (Ie; Real name is not same as generated name)
+ */
+ data_file_name=index_file_name=0;
+ fn_format(name_buff, file->filename, "", MI_NAME_DEXT, 2);
+ if (strcmp(name_buff, info.data_file_name))
+ data_file_name=info.data_file_name;
+ strmov(fn_ext(name_buff),MI_NAME_IEXT);
+ if (strcmp(name_buff, info.index_file_name))
+ index_file_name=info.index_file_name;
}
if (flag & HA_STATUS_ERRKEY)
{
@@ -873,16 +922,27 @@ void ha_myisam::info(uint flag)
int ha_myisam::extra(enum ha_extra_function operation)
{
- if (((specialflag & SPECIAL_SAFE_MODE) || (test_flags & TEST_NO_EXTRA)) &&
+ if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_KEYREAD)
+ return 0;
+ return mi_extra(file, operation, 0);
+}
+
+
+/* To be used with WRITE_CACHE, EXTRA_CACHE and BULK_INSERT_BEGIN */
+
+int ha_myisam::extra_opt(enum ha_extra_function operation, ulong cache_size)
+{
+ if ((specialflag & SPECIAL_SAFE_MODE) &
(operation == HA_EXTRA_WRITE_CACHE ||
- operation == HA_EXTRA_KEYREAD))
+ operation == HA_EXTRA_BULK_INSERT_BEGIN))
return 0;
- return mi_extra(file,operation);
+ return mi_extra(file, operation, (void*) &cache_size);
}
+
int ha_myisam::reset(void)
{
- return mi_extra(file,HA_EXTRA_RESET);
+ return mi_extra(file, HA_EXTRA_RESET, 0);
}
int ha_myisam::delete_all_rows()
@@ -924,10 +984,12 @@ void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
create_info->raid_chunks= raid_chunks;
create_info->raid_chunksize= raid_chunksize;
}
+ create_info->data_file_name=data_file_name;
+ create_info->index_file_name=index_file_name;
}
-int ha_myisam::create(const char *name, register TABLE *form,
+int ha_myisam::create(const char *name, register TABLE *table,
HA_CREATE_INFO *info)
{
int error;
@@ -939,20 +1001,20 @@ int ha_myisam::create(const char *name, register TABLE *form,
MI_KEYDEF *keydef;
MI_COLUMNDEF *recinfo,*recinfo_pos;
MI_KEYSEG *keyseg;
- uint options=form->db_options_in_use;
+ uint options=table->db_options_in_use;
DBUG_ENTER("ha_myisam::create");
type=HA_KEYTYPE_BINARY; // Keep compiler happy
if (!(my_multi_malloc(MYF(MY_WME),
- &recinfo,(form->fields*2+2)*sizeof(MI_COLUMNDEF),
- &keydef, form->keys*sizeof(MI_KEYDEF),
+ &recinfo,(table->fields*2+2)*sizeof(MI_COLUMNDEF),
+ &keydef, table->keys*sizeof(MI_KEYDEF),
&keyseg,
- ((form->key_parts + form->keys) * sizeof(MI_KEYSEG)),
+ ((table->key_parts + table->keys) * sizeof(MI_KEYSEG)),
0)))
DBUG_RETURN(1);
- pos=form->key_info;
- for (i=0; i < form->keys ; i++, pos++)
+ pos=table->key_info;
+ for (i=0; i < table->keys ; i++, pos++)
{
keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT));
keydef[i].seg=keyseg;
@@ -995,7 +1057,7 @@ int ha_myisam::create(const char *name, register TABLE *form,
{
keydef[i].seg[j].null_bit=field->null_bit;
keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
- (uchar*) form->record[0]);
+ (uchar*) table->record[0]);
}
else
{
@@ -1013,26 +1075,26 @@ int ha_myisam::create(const char *name, register TABLE *form,
keydef[i].seg[j].flag|=HA_BLOB_PART;
/* save number of bytes used to pack length */
keydef[i].seg[j].bit_start= (uint) (field->pack_length() -
- form->blob_ptr_size);
+ table->blob_ptr_size);
}
}
keyseg+=pos->key_parts;
}
recpos=0; recinfo_pos=recinfo;
- while (recpos < (uint) form->reclength)
+ while (recpos < (uint) table->reclength)
{
Field **field,*found=0;
- minpos=form->reclength; length=0;
+ minpos=table->reclength; length=0;
- for (field=form->field ; *field ; field++)
+ for (field=table->field ; *field ; field++)
{
if ((fieldpos=(*field)->offset()) >= recpos &&
fieldpos <= minpos)
{
/* skip null fields */
if (!(temp_length= (*field)->pack_length()))
- continue; /* Skipp null-fields */
+ continue; /* Skip null-fields */
if (! found || fieldpos < minpos ||
(fieldpos == minpos && temp_length < length))
{
@@ -1058,20 +1120,20 @@ int ha_myisam::create(const char *name, register TABLE *form,
else if (!(options & HA_OPTION_PACK_RECORD))
recinfo_pos->type= (int) FIELD_NORMAL;
else if (found->zero_pack())
- recinfo_pos->type= (int) FIELD_SKIPP_ZERO;
+ recinfo_pos->type= (int) FIELD_SKIP_ZERO;
else
recinfo_pos->type= (int) ((length <= 3 ||
(found->flags & ZEROFILL_FLAG)) ?
FIELD_NORMAL :
found->type() == FIELD_TYPE_STRING ||
found->type() == FIELD_TYPE_VAR_STRING ?
- FIELD_SKIPP_ENDSPACE :
- FIELD_SKIPP_PRESPACE);
+ FIELD_SKIP_ENDSPACE :
+ FIELD_SKIP_PRESPACE);
if (found->null_ptr)
{
recinfo_pos->null_bit=found->null_bit;
recinfo_pos->null_pos= (uint) (found->null_ptr-
- (uchar*) form->record[0]);
+ (uchar*) table->record[0]);
}
else
{
@@ -1086,18 +1148,23 @@ int ha_myisam::create(const char *name, register TABLE *form,
}
MI_CREATE_INFO create_info;
bzero((char*) &create_info,sizeof(create_info));
- create_info.max_rows=form->max_rows;
- create_info.reloc_rows=form->min_rows;
+ create_info.max_rows=table->max_rows;
+ create_info.reloc_rows=table->min_rows;
create_info.auto_increment=(info->auto_increment_value ?
info->auto_increment_value -1 :
(ulonglong) 0);
- create_info.data_file_length=(ulonglong) form->max_rows*form->avg_row_length;
+ create_info.data_file_length= ((ulonglong) table->max_rows *
+ table->avg_row_length);
create_info.raid_type=info->raid_type;
- create_info.raid_chunks=info->raid_chunks ? info->raid_chunks : RAID_DEFAULT_CHUNKS;
- create_info.raid_chunksize=info->raid_chunksize ? info->raid_chunksize : RAID_DEFAULT_CHUNKSIZE;
-
- error=mi_create(fn_format(buff,name,"","",2+4+16),
- form->keys,keydef,
+ create_info.raid_chunks= (info->raid_chunks ? info->raid_chunks :
+ RAID_DEFAULT_CHUNKS);
+ create_info.raid_chunksize=(info->raid_chunksize ? info->raid_chunksize :
+ RAID_DEFAULT_CHUNKSIZE);
+ create_info.data_file_name= info->data_file_name;
+ create_info.index_file_name=info->index_file_name;
+
+ error=mi_create(fn_format(buff,name,"","",2+4),
+ table->keys,keydef,
(uint) (recinfo_pos-recinfo), recinfo,
0, (MI_UNIQUEDEF*) 0,
&create_info,
@@ -1128,7 +1195,7 @@ longlong ha_myisam::get_auto_increment()
longlong nr;
int error;
- byte key[MAX_KEY_LENGTH];
+ byte key[MI_MAX_KEY_LENGTH];
(void) extra(HA_EXTRA_KEYREAD);
key_copy(key,table,table->next_number_index,
table->next_number_key_offset);
@@ -1167,9 +1234,8 @@ int ha_myisam::ft_read(byte * buf)
thread_safe_increment(ha_read_next_count,&LOCK_status); // why ?
- error=ft_read_next((FT_DOCLIST *) ft_handler,(char*) buf);
+ error=ft_handler->please->read_next(ft_handler,(char*) buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
-
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index 6451e2b80ee..215608f8f0a 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -24,11 +24,11 @@
#include <myisam.h>
#include <ft_global.h>
-#define HA_RECOVER_NONE 0 // No automatic recover
-#define HA_RECOVER_DEFAULT 1 // Automatic recover active
-#define HA_RECOVER_BACKUP 2 // Make a backupfile on recover
-#define HA_RECOVER_FORCE 4 // Recover even if we loose rows
-#define HA_RECOVER_QUICK 8 // Don't check rows in data file
+#define HA_RECOVER_NONE 0 /* No automatic recover */
+#define HA_RECOVER_DEFAULT 1 /* Automatic recover active */
+#define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */
+#define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */
+#define HA_RECOVER_QUICK 8 /* Don't check rows in data file */
extern ulong myisam_sort_buffer_size;
extern TYPELIB myisam_recover_typelib;
@@ -37,25 +37,33 @@ extern ulong myisam_recover_options;
class ha_myisam: public handler
{
MI_INFO *file;
- uint int_option_flag;
+ uint int_table_flags;
+ char *data_file_name, *index_file_name;
+ bool enable_activate_all_index;
int repair(THD *thd, MI_CHECK &param, bool optimize);
public:
ha_myisam(TABLE *table): handler(table), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_NULL_KEY |
- HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY)
+ int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
+ HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY),
+ enable_activate_all_index(1)
{}
~ha_myisam() {}
const char *table_type() const { return "MyISAM"; }
+ const char *index_type(uint key_number);
const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
+ ulong table_flags() const { return int_table_flags; }
+ ulong index_flags(uint inx) const
+ {
+ ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
+ return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+ 0 : HA_KEY_READ_ONLY));
+ }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAX_KEY_LENGTH; }
+ uint max_key_length() const { return MI_MAX_KEY_LENGTH; }
int open(const char *name, int mode, uint test_if_locked);
int close(void);
@@ -66,6 +74,7 @@ class ha_myisam: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_prev(byte * buf);
int index_first(byte * buf);
@@ -73,9 +82,15 @@ class ha_myisam: public handler
int index_next_same(byte *buf, const byte *key, uint keylen);
int index_end() { ft_handler=NULL; return 0; }
int ft_init()
- { if(!ft_handler) return 1; ft_reinit_search(ft_handler); return 0; }
- void *ft_init_ext(uint inx,const byte *key, uint keylen, bool presort)
- { return ft_init_search(file,inx,(byte*) key,keylen,presort); }
+ {
+ if (!ft_handler)
+ return 1;
+ ft_handler->please->reinit_search(ft_handler);
+ return 0;
+ }
+ FT_INFO *ft_init_ext(uint mode, uint inx,const byte *key, uint keylen,
+ bool presort)
+ { return ft_init_search(mode, file,inx,(byte*) key,keylen,presort); }
int ft_read(byte *buf);
int rnd_init(bool scan=1);
int rnd_next(byte *buf);
@@ -85,6 +100,7 @@ class ha_myisam: public handler
my_off_t row_position() { return mi_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
+ int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset(void);
int external_lock(THD *thd, int lock_type);
int delete_all_rows(void);
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index e5fb0310a36..ee72216baa5 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -23,9 +23,9 @@
#include <m_ctype.h>
#include "ha_myisammrg.h"
#ifndef MASTER
-#include "../srclib/myisammrg/mymrgdef.h"
+#include "../srclib/myisammrg/myrg_def.h"
#else
-#include "../myisammrg/mymrgdef.h"
+#include "../myisammrg/myrg_def.h"
#endif
/*****************************************************************************
@@ -38,16 +38,21 @@ const char **ha_myisammrg::bas_ext() const
int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
{
char name_buff[FN_REFLEN];
+ DBUG_PRINT("info", ("ha_myisammrg::open"));
if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode,
test_if_locked)))
+ {
+ DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno));
return (my_errno ? my_errno : -1);
-
+ }
+ DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."))
+ myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
test_if_locked == HA_OPEN_ABORT_IF_LOCKED))
- myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK);
+ myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK,0);
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
- myrg_extra(file,HA_EXTRA_WAIT_LOCK);
+ myrg_extra(file,HA_EXTRA_WAIT_LOCK,0);
if (table->reclength != mean_rec_length && mean_rec_length)
{
DBUG_PRINT("error",("reclength: %d mean_rec_length: %d",
@@ -66,7 +71,12 @@ int ha_myisammrg::close(void)
int ha_myisammrg::write_row(byte * buf)
{
- return (my_errno=HA_ERR_WRONG_COMMAND);
+ statistic_increment(ha_write_count,&LOCK_status);
+ if (table->time_stamp)
+ update_timestamp(buf+table->time_stamp-1);
+ if (table->next_number_field && buf == table->record[0])
+ update_auto_increment();
+ return myrg_write(file,buf);
}
int ha_myisammrg::update_row(const byte * old_data, byte * new_data)
@@ -101,6 +111,15 @@ int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key,
return error;
}
+int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ int error=myrg_rkey(file,buf,active_index, key, key_len,
+ HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
+ return error;
+}
+
int ha_myisammrg::index_next(byte * buf)
{
statistic_increment(ha_read_next_count,&LOCK_status);
@@ -135,7 +154,7 @@ int ha_myisammrg::index_last(byte * buf)
int ha_myisammrg::rnd_init(bool scan)
{
- return myrg_extra(file,HA_EXTRA_RESET);
+ return myrg_extra(file,HA_EXTRA_RESET,0);
}
int ha_myisammrg::rnd_next(byte *buf)
@@ -185,12 +204,30 @@ void ha_myisammrg::info(uint flag)
int ha_myisammrg::extra(enum ha_extra_function operation)
{
- return myrg_extra(file,operation);
+ /* As this is just a mapping, we don't have to force the underlying
+ tables to be closed */
+ if (operation == HA_EXTRA_FORCE_REOPEN ||
+ operation == HA_EXTRA_PREPARE_FOR_DELETE)
+ return 0;
+ return myrg_extra(file,operation,0);
}
+
+/* To be used with WRITE_CACHE, EXTRA_CACHE and BULK_INSERT_BEGIN */
+
+int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size)
+{
+ if ((specialflag & SPECIAL_SAFE_MODE) &
+ (operation == HA_EXTRA_WRITE_CACHE ||
+ operation == HA_EXTRA_BULK_INSERT_BEGIN))
+ return 0;
+ return myrg_extra(file, operation, (void*) &cache_size);
+}
+
+
int ha_myisammrg::reset(void)
{
- return myrg_extra(file,HA_EXTRA_RESET);
+ return myrg_extra(file,HA_EXTRA_RESET,0);
}
int ha_myisammrg::external_lock(THD *thd, int lock_type)
@@ -221,6 +258,7 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
{
+ // [phi] auto_increment stuff is missing (but currently not needed)
DBUG_ENTER("ha_myisammrg::update_create_info");
if (!(create_info->used_fields & HA_CREATE_USED_UNION))
{
@@ -231,7 +269,7 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
for (table=file->open_tables ; table != file->end_table ; table++)
{
- char *name=table->table->s->filename;
+ char *name=table->table->filename;
char buff[FN_REFLEN];
TABLE_LIST *ptr;
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
@@ -245,6 +283,10 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
}
*create_info->merge_list.next=0;
}
+ if (!(create_info->used_fields & HA_CREATE_USED_INSERT_METHOD))
+ {
+ create_info->merge_insert_method = file->merge_insert_method;
+ }
DBUG_VOID_RETURN;
err:
@@ -267,18 +309,25 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
*pos++= tables->real_name;
*pos=0;
DBUG_RETURN(myrg_create(fn_format(buff,name,"","",2+4+16),
- (const char **) table_names, (my_bool) 0));
+ (const char **) table_names,
+ create_info->merge_insert_method,
+ (my_bool) 0));
}
void ha_myisammrg::append_create_info(String *packet)
{
char buff[FN_REFLEN];
+ if (file->merge_insert_method != MERGE_INSERT_DISABLED)
+ {
+ packet->append(" INSERT_METHOD=",15);
+ packet->append(get_type(&merge_insert_method,file->merge_insert_method-1));
+ }
packet->append(" UNION=(",8);
MYRG_TABLE *table,*first;
for (first=table=file->open_tables ; table != file->end_table ; table++)
{
- char *name=table->table->s->filename;
+ char *name=table->table->filename;
fn_format(buff,name,"","",3);
if (table != first)
packet->append(',');
diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h
index b97baa0703c..b75d5360097 100644
--- a/sql/ha_myisammrg.h
+++ b/sql/ha_myisammrg.h
@@ -32,13 +32,18 @@ class ha_myisammrg: public handler
~ha_myisammrg() {}
const char *table_type() const { return "MRG_MyISAM"; }
const char **bas_ext() const;
- ulong option_flag() const
- { return (HA_REC_NOT_IN_SEQ | HA_READ_NEXT |
- HA_READ_PREV | HA_READ_RND_SAME |
- HA_HAVE_KEY_READ_ONLY | HA_NO_FULLTEXT_KEY |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER |
- HA_LASTKEY_ORDER | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_NULL_KEY | HA_BLOB_KEY); }
+ ulong table_flags() const
+ {
+ return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | HA_AUTO_PART_KEY |
+ HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_NULL_KEY | HA_BLOB_KEY);
+ }
+ ulong index_flags(uint inx) const
+ {
+ ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
+ return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+ 0 : HA_KEY_READ_ONLY));
+ }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
@@ -55,6 +60,7 @@ class ha_myisammrg: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_prev(byte * buf);
int index_first(byte * buf);
@@ -66,6 +72,7 @@ class ha_myisammrg: public handler
my_off_t row_position() { return myrg_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
+ int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset(void);
int external_lock(THD *thd, int lock_type);
uint lock_count(void) const;
@@ -74,4 +81,5 @@ class ha_myisammrg: public handler
enum thr_lock_type lock_type);
void update_create_info(HA_CREATE_INFO *create_info);
void append_create_info(String *packet);
+ MYRG_INFO *myrg_info() { return file; }
};
diff --git a/sql/handler.cc b/sql/handler.cc
index 564d91aa887..4180d98245c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,7 +25,7 @@
#include "ha_heap.h"
#include "ha_myisam.h"
#include "ha_myisammrg.h"
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
#include "ha_isam.h"
#include "ha_isammrg.h"
#endif
@@ -33,10 +33,7 @@
#include "ha_berkeley.h"
#endif
#ifdef HAVE_INNOBASE_DB
-#include "ha_innobase.h"
-#endif
-#ifdef HAVE_GEMINI_DB
-#include "ha_gemini.h"
+#include "ha_innodb.h"
#endif
#include <myisampack.h>
#include <errno.h>
@@ -48,6 +45,7 @@ static int NEAR_F delete_file(const char *name,const char *ext,int extflag);
ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
ha_read_key_count, ha_read_next_count, ha_read_prev_count,
ha_read_first_count, ha_read_last_count,
+ ha_commit_count, ha_rollback_count,
ha_read_rnd_count, ha_read_rnd_next_count;
const char *ha_table_type[] = {
@@ -55,8 +53,10 @@ const char *ha_table_type[] = {
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNODB", "GEMINI", "?", "?",NullS
};
-TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"",
- ha_table_type+1};
+TYPELIB ha_table_typelib=
+{
+ array_elements(ha_table_type)-3, "", ha_table_type
+};
const char *ha_row_type[] = {
"", "FIXED", "DYNAMIC", "COMPRESSED","?","?","?"
@@ -78,21 +78,15 @@ enum db_type ha_checktype(enum db_type database_type)
return(berkeley_skip ? DB_TYPE_MYISAM : database_type);
#endif
#ifdef HAVE_INNOBASE_DB
- case DB_TYPE_INNOBASE:
+ case DB_TYPE_INNODB:
return(innodb_skip ? DB_TYPE_MYISAM : database_type);
#endif
-#ifdef HAVE_GEMINI_DB
- case DB_TYPE_GEMINI:
- return(gemini_skip ? DB_TYPE_MYISAM : database_type);
-#endif
#ifndef NO_HASH
case DB_TYPE_HASH:
#endif
-#ifndef NO_MERGE
- case DB_TYPE_MRG_ISAM:
-#endif
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
case DB_TYPE_ISAM:
+ case DB_TYPE_MRG_ISAM:
#endif
case DB_TYPE_HEAP:
case DB_TYPE_MYISAM:
@@ -111,11 +105,9 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
#ifndef NO_HASH
return new ha_hash(table);
#endif
-#ifndef NO_MERGE
+#ifdef HAVE_ISAM
case DB_TYPE_MRG_ISAM:
return new ha_isammrg(table);
-#endif
-#ifndef NO_ISAM
case DB_TYPE_ISAM:
return new ha_isam(table);
#endif
@@ -124,13 +116,9 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
return new ha_berkeley(table);
#endif
#ifdef HAVE_INNOBASE_DB
- case DB_TYPE_INNOBASE:
+ case DB_TYPE_INNODB:
return new ha_innobase(table);
#endif
-#ifdef HAVE_GEMINI_DB
- case DB_TYPE_GEMINI:
- return new ha_gemini(table);
-#endif
case DB_TYPE_HEAP:
return new ha_heap(table);
case DB_TYPE_MYISAM:
@@ -166,17 +154,6 @@ int ha_init()
have_innodb=SHOW_OPTION_DISABLED;
}
#endif
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip)
- {
- if (gemini_init())
- return -1;
- if (!gemini_skip) // If we couldn't use handler
- opt_using_transactions=1;
- else
- have_gemini=SHOW_OPTION_DISABLED;
- }
-#endif
return 0;
}
@@ -186,14 +163,14 @@ int ha_init()
int ha_panic(enum ha_panic_function flag)
{
int error=0;
-#ifndef NO_MERGE
- error|=mrg_panic(flag);
-#endif
#ifndef NO_HASH
error|=h_panic(flag); /* fix hash */
#endif
- error|=heap_panic(flag);
+#ifdef HAVE_ISAM
+ error|=mrg_panic(flag);
error|=nisam_panic(flag);
+#endif
+ error|=heap_panic(flag);
error|=mi_panic(flag);
error|=myrg_panic(flag);
#ifdef HAVE_BERKELEY_DB
@@ -204,10 +181,6 @@ int ha_panic(enum ha_panic_function flag)
if (!innodb_skip)
error|=innobase_end();
#endif
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip)
- error|=gemini_end();
-#endif
return error;
} /* ha_panic */
@@ -225,12 +198,6 @@ void ha_close_connection(THD* thd)
if (!innodb_skip)
innobase_close_connection(thd);
#endif
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip && thd->gemini.context)
- {
- gemini_disconnect(thd);
- }
-#endif /* HAVE_GEMINI_DB */
}
/*
@@ -251,8 +218,8 @@ int ha_autocommit_or_rollback(THD *thd, int error)
}
else
(void) ha_rollback_stmt(thd);
-
- thd->tx_isolation=thd->session_tx_isolation;
+
+ thd->variables.tx_isolation=thd->session_tx_isolation;
}
#endif
DBUG_RETURN(error);
@@ -306,6 +273,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
+ bool operation_done= 0;
+ bool transaction_commited= 0;
/* Update the binary log if we have cached some queries */
if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
my_b_tell(&thd->transaction.trans_log))
@@ -353,6 +322,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
+ else
+ transaction_commited= 1;
trans->bdb_tid=0;
}
#endif
@@ -365,25 +336,23 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
error=1;
}
trans->innodb_active_trans=0;
+ if (trans == &thd->transaction.all)
+ operation_done= transaction_commited= 1;
+
}
#endif
-#ifdef HAVE_GEMINI_DB
- /* Commit the transaction in behalf of the commit statement
- or if we're in auto-commit mode */
- if((trans == &thd->transaction.all) ||
- (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))))
- {
- error=gemini_commit(thd);
- if (error)
- {
- my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
- error=1;
- }
- }
-#endif
+#ifdef HAVE_QUERY_CACHE
+ if (transaction_commited)
+ query_cache.invalidate(thd->transaction.changed_tables);
+#endif /*HAVE_QUERY_CACHE*/
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
sql_print_error("Error: Got error during commit; Binlog is not up to date!");
- thd->tx_isolation=thd->session_tx_isolation;
+ thd->variables.tx_isolation=thd->session_tx_isolation;
+ if (operation_done)
+ {
+ statistic_increment(ha_commit_count,&LOCK_status);
+ thd->transaction.cleanup();
+ }
}
#endif // using transactions
DBUG_RETURN(error);
@@ -397,6 +366,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
+ bool operation_done=0;
#ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid)
{
@@ -406,6 +376,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
error=1;
}
trans->bdb_tid=0;
+ operation_done=1;
}
#endif
#ifdef HAVE_INNOBASE_DB
@@ -417,41 +388,24 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
error=1;
}
trans->innodb_active_trans=0;
- }
-#endif
-#ifdef HAVE_GEMINI_DB
- if((trans == &thd->transaction.stmt) &&
- (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
- error = gemini_rollback_to_savepoint(thd);
- else
- error=gemini_rollback(thd);
- if (error)
- {
- my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
- error=1;
+ operation_done=1;
}
#endif
if (trans == &thd->transaction.all)
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
- thd->tx_isolation=thd->session_tx_isolation;
+ thd->variables.tx_isolation=thd->session_tx_isolation;
+ if (operation_done)
+ {
+ statistic_increment(ha_rollback_count,&LOCK_status);
+ thd->transaction.cleanup();
+ }
}
#endif /* USING_TRANSACTIONS */
DBUG_RETURN(error);
}
-void ha_set_spin_retries(uint retries)
-{
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip)
- {
- gemini_set_option_long(GEM_OPTID_SPIN_RETRIES, retries);
- }
-#endif /* HAVE_GEMINI_DB */
-}
-
-
bool ha_flush_logs()
{
bool result=0;
@@ -480,7 +434,7 @@ int ha_delete_table(enum db_type table_type, const char *path)
delete file;
return error;
}
-
+
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos)
{
switch (pack_length) {
@@ -567,9 +521,8 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
{
if (table->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
table->db_stat|=HA_READ_ONLY;
- }
- if (!error)
- {
+ (void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
+
if (!alloc_root_inited(&table->mem_root)) // If temporary table
ref=(byte*) sql_alloc(ALIGN_SIZE(ref_length)*2);
else
@@ -615,17 +568,37 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt)
return HA_ADMIN_NOT_IMPLEMENTED;
}
- /* Read first row from a table */
+/*
+ Read first row (only) from a table
+ This is never called for InnoDB or BDB tables, as these table types
+ has the HA_NOT_EXACT_COUNT set.
+*/
-int handler::rnd_first(byte * buf)
+int handler::read_first_row(byte * buf, uint primary_key)
{
register int error;
- DBUG_ENTER("handler::rnd_first");
+ DBUG_ENTER("handler::read_first_row");
statistic_increment(ha_read_first_count,&LOCK_status);
- (void) rnd_init();
- while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
- (void) rnd_end();
+
+ /*
+ If there is very few deleted rows in the table, find the first row by
+ scanning the table.
+ */
+ if (deleted < 10 || primary_key >= MAX_KEY ||
+ !(index_flags(primary_key) & HA_READ_ORDER))
+ {
+ (void) rnd_init();
+ while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
+ (void) rnd_end();
+ }
+ else
+ {
+ /* Find the first row through the primary key */
+ (void) index_init(primary_key);
+ error=index_first(buf);
+ (void) index_end();
+ }
DBUG_RETURN(error);
}
@@ -641,7 +614,7 @@ int handler::restart_rnd_next(byte *buf, byte *pos)
}
- /* Set a timestamp in record */
+/* Set a timestamp in record */
void handler::update_timestamp(byte *record)
{
@@ -657,9 +630,10 @@ void handler::update_timestamp(byte *record)
return;
}
- /* Updates field with field_type NEXT_NUMBER according to following:
- ** if field = 0 change field to the next free key in database.
- */
+/*
+ Updates field with field_type NEXT_NUMBER according to following:
+ if field = 0 change field to the next free key in database.
+*/
void handler::update_auto_increment()
{
@@ -687,16 +661,29 @@ longlong handler::get_auto_increment()
{
longlong nr;
int error;
+
(void) extra(HA_EXTRA_KEYREAD);
index_init(table->next_number_index);
- error=index_last(table->record[1]);
+ if (!table->next_number_key_offset)
+ { // Autoincrement at key-start
+ error=index_last(table->record[1]);
+ }
+ else
+ {
+ byte key[MAX_KEY_LENGTH];
+ key_copy(key,table,table->next_number_index,
+ table->next_number_key_offset);
+ error=index_read(table->record[1], key, table->next_number_key_offset,
+ HA_READ_PREFIX_LAST);
+ }
+
if (error)
nr=1;
else
nr=(longlong) table->next_number_field->
val_int_offset(table->rec_buff_length)+1;
- (void) extra(HA_EXTRA_NO_KEYREAD);
index_end();
+ (void) extra(HA_EXTRA_NO_KEYREAD);
return nr;
}
@@ -842,22 +829,6 @@ int handler::rename_table(const char * from, const char * to)
DBUG_RETURN(0);
}
-int ha_commit_rename(THD *thd)
-{
- int error=0;
-#ifdef HAVE_GEMINI_DB
- /* Gemini needs to commit the rename; otherwise a rollback will change
- ** the table names back internally but the physical files will still
- ** have the new names.
- */
- if (ha_commit_stmt(thd))
- error= -1;
- if (ha_commit(thd))
- error= -1;
-#endif
- return error;
-}
-
/* Tell the handler to turn on or off logging to the handler's
recovery log
*/
@@ -866,14 +837,6 @@ int ha_recovery_logging(THD *thd, bool on)
int error=0;
DBUG_ENTER("ha_recovery_logging");
-#ifdef USING_TRANSACTIONS
- if (opt_using_transactions)
- {
-#ifdef HAVE_GEMINI_DB
- error = gemini_recovery_logging(thd, on);
-#endif
- }
-#endif
DBUG_RETURN(error);
}
@@ -893,8 +856,10 @@ int handler::index_next_same(byte *buf, const byte *key, uint keylen)
/*
- The following is only needed if we would like to use the database
- for internal temporary tables
+ This is called to delete all rows in a table
+ If the handler don't support this, then this function will
+ return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
+ by one.
*/
int handler::delete_all_rows()
@@ -922,19 +887,21 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
if (update_create_info)
{
update_create_info_from_table(create_info, &table);
- if (table.file->option_flag() & HA_DROP_BEFORE_CREATE)
+ if (table.file->table_flags() & HA_DROP_BEFORE_CREATE)
table.file->delete_table(name); // Needed for BDB tables
}
error=table.file->create(name,&table,create_info);
VOID(closefrm(&table));
- if (error) {
- if (table.db_type == DB_TYPE_INNOBASE) {
+ if (error)
+ {
+ if (table.db_type == DB_TYPE_INNODB)
+ {
/* Creation of InnoDB table cannot fail because of an OS error:
put error as the number */
my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error);
- } else {
- my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno);
}
+ else
+ my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno);
}
DBUG_RETURN(error != 0);
}
@@ -944,13 +911,25 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
void ha_key_cache(void)
{
if (keybuff_size)
- (void) init_key_cache(keybuff_size,0);
-} /* ha_key_cache */
+ (void) init_key_cache(keybuff_size);
+}
+
+
+void ha_resize_key_cache(void)
+{
+ (void) resize_key_cache(keybuff_size);
+}
static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
{
char buff[FN_REFLEN];
VOID(fn_format(buff,name,"",ext,extflag | 4));
- return(my_delete(buff,MYF(MY_WME)));
+ return(my_delete_with_symlink(buff,MYF(MY_WME)));
+}
+
+void st_ha_check_opt::init()
+{
+ flags= sql_flags= 0;
+ sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
}
diff --git a/sql/handler.h b/sql/handler.h
index 89c19993238..fcc6bc261e7 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -21,11 +21,13 @@
#pragma interface /* gcc class implementation */
#endif
+#include <ft_global.h>
+
#ifndef NO_HASH
#define NO_HASH /* Not yet implemented */
#endif
-#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB) || defined(HAVE_GEMINI_DB)
+#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB)
#define USING_TRANSACTIONS
#endif
@@ -39,30 +41,18 @@
#define HA_ADMIN_INTERNAL_ERROR -4
#define HA_ADMIN_INVALID -5
-/* Bits in bas_flag to show what database can do */
-
-#define HA_READ_NEXT 1 /* Read next record with same key */
-#define HA_READ_PREV 2 /* Read prev. record with same key */
-#define HA_READ_ORDER 4 /* Read through record-keys in order */
-#define HA_READ_RND_SAME 8 /* Read RND-record to KEY-record
+/* Bits in table_flags() to show what database can do */
+#define HA_READ_RND_SAME 1 /* Read RND-record to KEY-record
(To update with RND-read) */
-#define HA_KEYPOS_TO_RNDPOS 16 /* ha_info gives pos to record */
-#define HA_LASTKEY_ORDER 32 /* Next record gives next record
- according last record read (even
- if database is updated after read) */
-#define HA_REC_NOT_IN_SEQ 64 /* ha_info don't return recnumber;
+#define HA_KEYPOS_TO_RNDPOS 2 /* ha_info gives pos to record */
+#define HA_TABLE_SCAN_ON_INDEX 4 /* No separate data/index file */
+#define HA_REC_NOT_IN_SEQ 8 /* ha_info don't return recnumber;
It returns a position to ha_r_rnd */
-#define HA_ONLY_WHOLE_INDEX 128 /* Can't use part key searches */
-#define HA_RSAME_NO_INDEX 256 /* RSAME can't restore index */
-#define HA_WRONG_ASCII_ORDER 512 /* Can't use sorting through key */
-#define HA_HAVE_KEY_READ_ONLY 1024 /* Can read only keys (no record) */
-#define HA_READ_NOT_EXACT_KEY 2048 /* Can read record after/before key */
-#define HA_NO_INDEX 4096 /* No index needed for next/prev */
-#define HA_LONGLONG_KEYS 8192 /* Can have longlong as key */
-#define HA_KEY_READ_WRONG_STR 16384 /* keyread returns converted strings */
-#define HA_NULL_KEY 32768 /* One can have keys with NULL */
-#define HA_DUPP_POS 65536 /* ha_position() gives dupp row */
-#define HA_NO_BLOBS 131072 /* Doesn't support blobs */
+#define HA_NO_INDEX 32 /* No index needed for next/prev */
+#define HA_KEY_READ_WRONG_STR 64 /* keyread returns converted strings */
+#define HA_NULL_KEY 128 /* One can have keys with NULL */
+#define HA_DUPP_POS 256 /* ha_position() gives dupp row */
+#define HA_NO_BLOBS 512 /* Doesn't support blobs */
#define HA_BLOB_KEY (HA_NO_BLOBS*2) /* key on blob */
#define HA_AUTO_PART_KEY (HA_BLOB_KEY*2)
#define HA_REQUIRE_PRIMARY_KEY (HA_AUTO_PART_KEY*2)
@@ -74,26 +64,45 @@
#define HA_NOT_DELETE_WITH_CACHE (HA_NOT_READ_AFTER_KEY*2)
#define HA_NO_TEMP_TABLES (HA_NOT_DELETE_WITH_CACHE*2)
#define HA_NO_PREFIX_CHAR_KEYS (HA_NO_TEMP_TABLES*2)
-#define HA_NO_FULLTEXT_KEY (HA_NO_PREFIX_CHAR_KEYS*2)
-
- /* Parameters for open() (in register form->filestat) */
- /* HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED */
+#define HA_CAN_FULLTEXT (HA_NO_PREFIX_CHAR_KEYS*2)
+#define HA_CAN_SQL_HANDLER (HA_CAN_FULLTEXT*2)
+#define HA_NO_AUTO_INCREMENT (HA_CAN_SQL_HANDLER*2)
+
+/*
+ Next record gives next record according last record read (even
+ if database is updated after read). Not used at this point.
+*/
+#define HA_LASTKEY_ORDER (HA_NO_AUTO_INCREMENT*2)
+
+
+/* bits in index_flags(index_number) for what you can do with index */
+#define HA_WRONG_ASCII_ORDER 1 /* Can't use sorting through key */
+#define HA_READ_NEXT 2 /* Read next record with same key */
+#define HA_READ_PREV 4 /* Read prev. record with same key */
+#define HA_READ_ORDER 8 /* Read through record-keys in order */
+#define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
+#define HA_NOT_READ_PREFIX_LAST 32
+#define HA_KEY_READ_ONLY 64 /* Support HA_EXTRA_KEYREAD */
+
+/*
+ Parameters for open() (in register form->filestat)
+ HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
+*/
#define HA_OPEN_KEYFILE 1
#define HA_OPEN_RNDFILE 2
#define HA_GET_INDEX 4
#define HA_GET_INFO 8 /* do a ha_info() after open */
#define HA_READ_ONLY 16 /* File opened as readonly */
-#define HA_TRY_READ_ONLY 32 /* Try readonly if can't */
- /* open with read and write */
+/* Try readonly if can't open with read and write */
+#define HA_TRY_READ_ONLY 32
#define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */
#define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/
#define HA_BLOCK_LOCK 256 /* unlock when reading some records */
#define HA_OPEN_TEMPORARY 512
- /* Error on write which is recoverable (Key exist) */
-
-#define HA_WRITE_SKIPP 121 /* Duplicate key on write */
+ /* Errors on write which is recoverable (Key exist) */
+#define HA_WRITE_SKIP 121 /* Duplicate key on write */
#define HA_READ_CHECK 123 /* Update with is recoverable */
#define HA_CANT_DO_THAT 131 /* Databasehandler can't do it */
@@ -111,23 +120,27 @@ enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
- DB_TYPE_BERKELEY_DB, DB_TYPE_INNOBASE, DB_TYPE_GEMINI,
+ DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, DB_TYPE_GEMINI,
DB_TYPE_DEFAULT };
-enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC,
- ROW_TYPE_COMPRESSED };
+enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
+ ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED};
/* struct to hold information about the table that should be created */
/* Bits in used_fields */
-#define HA_CREATE_USED_AUTO 1
-#define HA_CREATE_USED_RAID 2
-#define HA_CREATE_USED_UNION 4
+#define HA_CREATE_USED_AUTO 1
+#define HA_CREATE_USED_RAID 2
+#define HA_CREATE_USED_UNION 4
+#define HA_CREATE_USED_INSERT_METHOD 8
+#define HA_CREATE_USED_MIN_ROWS 16
+#define HA_CREATE_USED_MAX_ROWS 32
+#define HA_CREATE_USED_AVG_ROW_LENGTH 64
+#define HA_CREATE_USED_PACK_KEYS 128
typedef struct st_thd_trans {
void *bdb_tid;
void *innobase_tid;
- void *gemini_tid;
bool innodb_active_trans;
} THD_TRANS;
@@ -143,6 +156,7 @@ typedef struct st_ha_create_information
ulonglong max_rows,min_rows;
ulonglong auto_increment_value;
char *comment,*password;
+ char *data_file_name, *index_file_name;
char *create_statement;
uint options; /* OR of HA_CREATE_ options */
uint raid_type,raid_chunks;
@@ -150,6 +164,7 @@ typedef struct st_ha_create_information
bool if_not_exists;
ulong used_fields;
SQL_LIST merge_list;
+ uint merge_insert_method;
} HA_CREATE_INFO;
@@ -157,21 +172,13 @@ typedef struct st_ha_create_information
struct st_table;
typedef struct st_table TABLE;
-extern ulong myisam_sort_buffer_size;
typedef struct st_ha_check_opt
{
ulong sort_buffer_size;
- uint flags;
- bool quick;
- bool changed_files;
- bool optimize;
- bool retry_without_quick;
- inline void init()
- {
- flags= 0; quick= optimize= retry_without_quick=0;
- sort_buffer_size = myisam_sort_buffer_size;
- }
+ uint flags; /* isam layer flags (e.g. for myisamchk) */
+ uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
+ void init();
} HA_CHECK_OPT;
class handler :public Sql_alloc
@@ -201,7 +208,7 @@ public:
time_t check_time;
time_t update_time;
ulong mean_rec_length; /* physical reclength */
- void *ft_handler;
+ FT_INFO *ft_handler;
bool auto_increment_column_changed;
handler(TABLE *table_arg) : table(table_arg),active_index(MAX_REF_PARTS),
@@ -227,6 +234,7 @@ public:
virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; }
virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
+ virtual const char *index_type(uint key_number) { return "";}
virtual int index_init(uint idx) { active_index=idx; return 0;}
virtual int index_end() {return 0; }
@@ -238,7 +246,7 @@ public:
virtual int update_row(const byte * old_data, byte * new_data)=0;
virtual int delete_row(const byte * buf)=0;
virtual int index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)=0;
+ uint key_len, enum ha_rkey_function find_flag)=0;
virtual int index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag)=0;
virtual int index_next(byte * buf)=0;
@@ -246,17 +254,21 @@ public:
virtual int index_first(byte * buf)=0;
virtual int index_last(byte * buf)=0;
virtual int index_next_same(byte *buf, const byte *key, uint keylen);
+ virtual int index_read_last(byte * buf, const byte * key, uint key_len)
+ {
+ return (my_errno=HA_ERR_WRONG_COMMAND);
+ }
virtual int ft_init()
{ return -1; }
- virtual void *ft_init_ext(uint inx,const byte *key, uint keylen,
+ virtual FT_INFO *ft_init_ext(uint mode,uint inx,const byte *key, uint keylen,
bool presort)
- { return (void *)NULL; }
+ { return NULL; }
virtual int ft_read(byte *buf) { return -1; }
virtual int rnd_init(bool scan=1)=0;
virtual int rnd_end() { return 0; }
virtual int rnd_next(byte *buf)=0;
virtual int rnd_pos(byte * buf, byte *pos)=0;
- virtual int rnd_first(byte *buf);
+ virtual int read_first_row(byte *buf, uint primary_key);
virtual int restart_rnd_next(byte *buf, byte *pos);
virtual ha_rows records_in_range(int inx,
const byte *start_key,uint start_key_len,
@@ -268,6 +280,10 @@ public:
virtual my_off_t row_position() { return HA_OFFSET_ERROR; }
virtual void info(uint)=0;
virtual int extra(enum ha_extra_function operation)=0;
+ virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
+ {
+ return extra(operation);
+ }
virtual int reset()=0;
virtual int external_lock(THD *thd, int lock_type)=0;
virtual void unlock_row() {}
@@ -281,10 +297,11 @@ public:
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
+ /*
+ restore assumes .frm file must exist, and that generate_table() has been
+ called; It will just copy the data file and run repair.
+ */
virtual int restore(THD* thd, HA_CHECK_OPT* check_opt);
- // assumes .frm file must exist, and you must have already called
- // generate_table() - it will just copy the data file and run repair
-
virtual int dump(THD* thd, int fd = -1) { return ER_DUMP_NOT_IMPLEMENTED; }
virtual void deactivate_non_unique_index(ha_rows rows) {}
virtual bool activate_all_index(THD *thd) {return 0;}
@@ -300,7 +317,11 @@ public:
/* The following can be called without an open handler */
virtual const char *table_type() const =0;
virtual const char **bas_ext() const =0;
- virtual ulong option_flag() const =0;
+ virtual ulong table_flags(void) const =0;
+ virtual ulong index_flags(uint idx) const
+ {
+ return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY);
+ }
virtual uint max_record_length() const =0;
virtual uint max_keys() const =0;
virtual uint max_key_parts() const =0;
@@ -320,17 +341,6 @@ public:
enum thr_lock_type lock_type)=0;
};
-#ifdef HAVE_GEMINI_DB
-struct st_gemini
-{
- void *context;
- unsigned long savepoint;
- bool needSavepoint;
- uint tx_isolation;
- uint lock_count;
-};
-#endif
-
/* Some extern variables used with handlers */
extern const char *ha_row_type[];
@@ -342,6 +352,8 @@ extern TYPELIB ha_table_typelib, tx_isolation_typelib;
#define ha_commit(thd) (ha_commit_trans((thd), &((thd)->transaction.all)))
#define ha_rollback(thd) (ha_rollback_trans((thd), &((thd)->transaction.all)))
+#define ha_supports_generate(T) (T != DB_TYPE_INNODB)
+
handler *get_new_handler(TABLE *table, enum db_type db_type);
my_off_t ha_get_ptr(byte *ptr, uint pack_length);
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos);
@@ -354,15 +366,13 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
int ha_delete_table(enum db_type db_type, const char *path);
void ha_drop_database(char* path);
void ha_key_cache(void);
+void ha_resize_key_cache(void);
int ha_start_stmt(THD *thd);
-int ha_report_binlog_offset_and_commit(
- THD *thd,
- char *log_file_name,
- my_off_t end_offset);
+int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
+ my_off_t end_offset);
int ha_commit_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
int ha_autocommit_or_rollback(THD *thd, int error);
void ha_set_spin_retries(uint retries);
bool ha_flush_logs(void);
-int ha_commit_rename(THD *thd);
int ha_recovery_logging(THD *thd, bool on);
diff --git a/sql/hash_filo.cc b/sql/hash_filo.cc
index 990d2d662d6..b85f8054f10 100644
--- a/sql/hash_filo.cc
+++ b/sql/hash_filo.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/hash_filo.h b/sql/hash_filo.h
index 157c2739add..b8d45f0d3be 100644
--- a/sql/hash_filo.h
+++ b/sql/hash_filo.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -24,7 +24,7 @@
#define HASH_FILO_H
#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
+#pragma interface /* gcc class interface */
#endif
class hash_filo_element
diff --git a/sql/hostname.cc b/sql/hostname.cc
index 21dbd5a2bbe..abccc466a22 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -57,8 +57,11 @@ void hostname_cache_refresh()
bool hostname_cache_init()
{
+ host_entry tmp;
+ uint offset= (uint) ((char*) (&tmp.ip) - (char*) &tmp);
(void) pthread_mutex_init(&LOCK_hostname,MY_MUTEX_INIT_SLOW);
- if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE,offsetof(host_entry,ip),
+
+ if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE, offset,
sizeof(struct in_addr),NULL,
(void (*)(void*)) free)))
return 1;
diff --git a/sql/init.cc b/sql/init.cc
index e6606b82b7c..df06ddd41ef 100644
--- a/sql/init.cc
+++ b/sql/init.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/item.cc b/sql/item.cc
index 0ce37cdd593..bb39a141e9f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -37,7 +37,7 @@ void item_init(void)
Item::Item()
{
marker=0;
- binary=maybe_null=null_value=with_sum_func=0;
+ binary=maybe_null=null_value=with_sum_func=unsigned_flag=0;
name=0;
decimals=0; max_length=0;
next=current_thd->free_list; // Put in free list
@@ -132,6 +132,7 @@ void Item_field::set_field(Field *field_par)
table_name=field_par->table_name;
field_name=field_par->field_name;
binary=field_par->binary();
+ unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
}
const char *Item_ident::full_name() const
@@ -247,6 +248,22 @@ void Item_int::print(String *str)
str->append(name);
}
+String *Item_uint::val_str(String *str)
+{
+ str->set((ulonglong) value);
+ return str;
+}
+
+void Item_uint::print(String *str)
+{
+ if (!name)
+ {
+ str_value.set((ulonglong) value);
+ name=str_value.c_ptr();
+ }
+ str->append(name);
+}
+
String *Item_real::val_str(String *str)
{
@@ -299,13 +316,21 @@ bool Item::fix_fields(THD *thd,
bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
{
- if (!field)
+ if (!field) // If field is not checked
{
Field *tmp;
if (!(tmp=find_field_in_tables(thd,this,tables)))
return 1;
set_field(tmp);
}
+ else if (thd && thd->set_query_id && field->query_id != thd->query_id)
+ {
+ /* We only come here in unions */
+ TABLE *table=field->table;
+ field->query_id=thd->query_id;
+ table->used_fields++;
+ table->used_keys&=field->part_of_key;
+ }
return 0;
}
@@ -319,6 +344,8 @@ void Item::init_make_field(Send_field *tmp_field,
tmp_field->type=field_type;
tmp_field->length=max_length;
tmp_field->decimals=decimals;
+ if (unsigned_flag)
+ tmp_field->flags |= UNSIGNED_FLAG;
}
/* ARGSUSED */
@@ -334,6 +361,13 @@ void Item_int::make_field(Send_field *tmp_field)
init_make_field(tmp_field,FIELD_TYPE_LONGLONG);
}
+void Item_uint::make_field(Send_field *tmp_field)
+{
+ init_make_field(tmp_field,FIELD_TYPE_LONGLONG);
+ tmp_field->flags|= UNSIGNED_FLAG;
+ unsigned_flag=1;
+}
+
void Item_real::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
@@ -349,12 +383,14 @@ void Item_datetime::make_field(Send_field *tmp_field)
init_make_field(tmp_field,FIELD_TYPE_DATETIME);
}
+
void Item_null::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field,FIELD_TYPE_NULL);
tmp_field->length=4;
}
+
void Item_func::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field, ((result_type() == STRING_RESULT) ?
@@ -552,19 +588,19 @@ void Item_varbinary::make_field(Send_field *tmp_field)
** pack data in buffer for sending
*/
-bool Item::send(String *packet)
+bool Item::send(THD *thd, String *packet)
{
char buff[MAX_FIELD_WIDTH];
+ CONVERT *convert;
String s(buff,sizeof(buff)),*res;
if (!(res=val_str(&s)))
return net_store_null(packet);
- CONVERT *convert;
- if ((convert=current_thd->convert_set))
+ if ((convert=thd->variables.convert_set))
return convert->store(packet,res->ptr(),res->length());
return net_store_data(packet,res->ptr(),res->length());
}
-bool Item_null::send(String *packet)
+bool Item_null::send(THD *thd, String *packet)
{
return net_store_null(packet);
}
@@ -578,7 +614,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (!ref)
{
- if (!(ref=find_item_in_list(this,thd->lex.item_list)))
+ if (!(ref=find_item_in_list(this,thd->lex.select->item_list)))
return 1;
max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null;
@@ -694,5 +730,6 @@ bool field_is_equal_to_item(Field *field,Item *item)
#ifdef __GNUC__
template class List<Item>;
template class List_iterator<Item>;
+template class List_iterator_fast<Item>;
template class List<List_item>;
#endif
diff --git a/sql/item.h b/sql/item.h
index b8903756027..70729afe28e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -23,7 +23,7 @@ struct st_table_list;
void item_init(void); /* Init item functions */
class Item {
- Item(const Item &); /* Prevent use of theese */
+ Item(const Item &); /* Prevent use of these */
void operator=(Item &);
public:
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
@@ -31,7 +31,7 @@ public:
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
- COPY_STR_ITEM,FIELD_AVG_ITEM,
+ COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM,
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -43,6 +43,7 @@ public:
my_bool maybe_null; /* If item may be null */
my_bool null_value; /* if item is null */
my_bool binary;
+ my_bool unsigned_flag;
my_bool with_sum_func;
@@ -55,7 +56,7 @@ public:
virtual bool save_in_field(Field *field);
virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field); }
- virtual bool send(String *str);
+ virtual bool send(THD *thd, String *str);
virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; }
virtual enum Type type() const =0;
@@ -63,7 +64,7 @@ public:
virtual longlong val_int()=0;
virtual String *val_str(String*)=0;
virtual void make_field(Send_field *field)=0;
- virtual Field *tmp_table_field() { return 0; }
+ virtual Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return 0; }
virtual const char *full_name() const { return name ? name : "???"; }
virtual double val_result() { return val(); }
virtual longlong val_int_result() { return val_int(); }
@@ -80,6 +81,8 @@ public:
virtual void split_sum_func(List<Item> &fields) {}
virtual bool get_date(TIME *ltime,bool fuzzydate);
virtual bool get_time(TIME *ltime);
+ virtual bool is_null() { return 0; }
+ virtual unsigned int size_of()= 0;
};
@@ -94,8 +97,10 @@ public:
:db_name(db_name_par),table_name(table_name_par),field_name(field_name_par)
{ name = (char*) field_name_par; }
const char *full_name() const;
+ unsigned int size_of() { return sizeof(*this);}
};
+
class Item_field :public Item_ident
{
void set_field(Field *field);
@@ -116,7 +121,10 @@ public:
double val_result();
longlong val_int_result();
String *str_result(String* tmp);
- bool send(String *str_arg) { return result_field->send(str_arg); }
+ bool send(THD *thd, String *str_arg)
+ {
+ return result_field->send(thd,str_arg);
+ }
void make_field(Send_field *field);
bool fix_fields(THD *,struct st_table_list *);
bool save_in_field(Field *field);
@@ -126,9 +134,11 @@ public:
{
return field->result_type();
}
- Field *tmp_table_field() { return result_field; }
+ Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
bool get_date(TIME *ltime,bool fuzzydate);
bool get_time(TIME *ltime);
+ bool is_null() { return field->is_null(); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -146,9 +156,11 @@ public:
bool save_in_field(Field *field);
enum Item_result result_type () const
{ return STRING_RESULT; }
- bool send(String *str);
+ bool send(THD *thd, String *str);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); }
+ bool is_null() { return 1; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -178,6 +190,22 @@ public:
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_int(name,value,max_length); }
void print(String *str);
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_uint :public Item_int
+{
+public:
+ Item_uint(const char *str_arg, uint length) :
+ Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) {}
+ Item_uint(uint32 i) :Item_int((longlong) i, 10) {}
+ double val() { return ulonglong2double(value); }
+ String *val_str(String*);
+ void make_field(Send_field *field);
+ Item *new_item() { return new Item_uint(name,max_length); }
+ void print(String *str);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -189,14 +217,14 @@ public:
Item_real(const char *str_arg,uint length) :value(atof(str_arg))
{
name=(char*) str_arg;
- decimals=nr_of_decimals(str_arg);
+ decimals=(uint8) nr_of_decimals(str_arg);
max_length=length;
}
Item_real(const char *str,double val_arg,uint decimal_par,uint length)
:value(val_arg)
{
name=(char*) str;
- decimals=decimal_par;
+ decimals=(uint8) decimal_par;
max_length=length;
}
Item_real(double value_par) :value(value_par) {}
@@ -208,6 +236,7 @@ public:
void make_field(Send_field *field);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_real(name,value,decimals,max_length); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -219,6 +248,7 @@ public:
decimals=NOT_FIXED_DEC;
max_length=DBL_DIG+8;
}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_string :public Item
@@ -252,8 +282,31 @@ public:
String *const_string() { return &str_value; }
inline void append(char *str,uint length) { str_value.append(str,length); }
void print(String *str);
+ unsigned int size_of() { return sizeof(*this);}
};
+
+/* For INSERT ... VALUES (DEFAULT) */
+
+class Item_default :public Item
+{
+public:
+ Item_default() { name= (char*) "DEFAULT"; }
+ enum Type type() const { return DEFAULT_ITEM; }
+ void make_field(Send_field *field) {}
+ bool save_in_field(Field *field)
+ {
+ field->set_default();
+ return 0;
+ }
+ virtual double val() { return 0.0; }
+ virtual longlong val_int() { return 0; }
+ virtual String *val_str(String *str) { return 0; }
+ bool basic_const_item() const { return 1; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
/* for show tables */
class Item_datetime :public Item_string
@@ -262,6 +315,7 @@ public:
Item_datetime(const char *item_name): Item_string(item_name,"",0)
{ max_length=19;}
void make_field(Send_field *field);
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_empty_string :public Item_string
@@ -269,6 +323,7 @@ class Item_empty_string :public Item_string
public:
Item_empty_string(const char *header,uint length) :Item_string("",0)
{ name=(char*) header; max_length=length;}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_varbinary :public Item
@@ -283,6 +338,7 @@ public:
bool save_in_field(Field *field);
void make_field(Send_field *field);
enum Item_result result_type () const { return INT_RESULT; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -292,9 +348,10 @@ public:
Field *result_field; /* Save result here */
Item_result_field() :result_field(0) {}
~Item_result_field() {} /* Required with gcc 2.95 */
- Field *tmp_table_field() { return result_field; }
+ Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
table_map used_tables() const { return 1; }
virtual void fix_length_and_dec()=0;
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -328,17 +385,23 @@ public:
null_value=(*ref)->null_value;
return tmp;
}
+ bool is_null()
+ {
+ (void) (*ref)->val_int_result();
+ return (*ref)->null_value;
+ }
bool get_date(TIME *ltime,bool fuzzydate)
{
return (null_value=(*ref)->get_date(ltime,fuzzydate));
}
- bool send(String *tmp) { return (*ref)->send(tmp); }
+ bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
void make_field(Send_field *field) { (*ref)->make_field(field); }
bool fix_fields(THD *,struct st_table_list *);
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); }
enum Item_result result_type () const { return (*ref)->result_type(); }
table_map used_tables() const { return (*ref)->used_tables(); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -358,6 +421,7 @@ public:
{
return ref->save_in_field(field);
}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -391,6 +455,8 @@ public:
void copy();
table_map used_tables() const { return (table_map) 1L; }
bool const_item() const { return 0; }
+ bool is_null() { return null_value; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -401,6 +467,7 @@ public:
Item_buff() :null_value(0) {}
virtual bool cmp(void)=0;
virtual ~Item_buff(); /*line -e1509 */
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_str_buff :public Item_buff
@@ -411,6 +478,7 @@ public:
Item_str_buff(Item *arg) :item(arg),value(arg->max_length) {}
bool cmp(void);
~Item_str_buff(); // Deallocate String:s
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -421,6 +489,7 @@ class Item_real_buff :public Item_buff
public:
Item_real_buff(Item *item_par) :item(item_par),value(0.0) {}
bool cmp(void);
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_int_buff :public Item_buff
@@ -430,6 +499,7 @@ class Item_int_buff :public Item_buff
public:
Item_int_buff(Item *item_par) :item(item_par),value(0) {}
bool cmp(void);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -446,10 +516,10 @@ public:
buff= (char*) sql_calloc(length=field->pack_length());
}
bool cmp(void);
+ unsigned int size_of() { return sizeof(*this);}
};
extern Item_buff *new_Item_buff(Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern Item *resolve_const_item(Item *item,Item *cmp_item);
extern bool field_is_equal_to_item(Field *field,Item *item);
-Item *get_system_var(LEX_STRING name);
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index 61e1f5498a9..b55a4dc66a0 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ae50090fea1..90e8a0e451f 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -256,7 +256,7 @@ longlong Item_func_strcmp::val_int()
null_value=1;
return 0;
}
- int value=stringcmp(a,b);
+ int value= binary ? stringcmp(a,b) : sortcmp(a,b);
null_value=0;
return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
}
@@ -549,7 +549,7 @@ Item_func_nullif::fix_length_and_dec()
}
/*
- nullif() returns NULL if arguments are different, else it returns the
+ nullif () returns NULL if arguments are different, else it returns the
first argument.
Note that we have to evaluate the first argument twice as the compare
may have been done with a different type than return value
@@ -797,8 +797,9 @@ String *Item_func_coalesce::val_str(String *str)
null_value=0;
for (uint i=0 ; i < arg_count ; i++)
{
- if (args[i]->val_str(str) != NULL)
- return args[i]->val_str(str);
+ String *res;
+ if ((res=args[i]->val_str(str)))
+ return res;
}
null_value=1;
return 0;
@@ -962,7 +963,7 @@ void Item_func_in::fix_length_and_dec()
for (uint i=0 ; i < arg_count ; i++)
{
array->set(j,args[i]);
- if (!args[i]->null_value) // Skipp NULL values
+ if (!args[i]->null_value) // Skip NULL values
j++;
}
if ((array->used_count=j))
@@ -1136,7 +1137,7 @@ void Item_cond::update_used_tables()
{
used_tables_cache=0;
const_item_cache=1;
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
{
@@ -1150,7 +1151,7 @@ void Item_cond::update_used_tables()
void Item_cond::print(String *str)
{
str->append('(');
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
if ((item=li++))
item->print(str);
@@ -1167,7 +1168,7 @@ void Item_cond::print(String *str)
longlong Item_cond_and::val_int()
{
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
{
@@ -1188,7 +1189,7 @@ longlong Item_cond_and::val_int()
longlong Item_cond_or::val_int()
{
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
null_value=0;
while ((item=li++))
@@ -1212,14 +1213,12 @@ longlong Item_func_isnull::val_int()
*/
if (!used_tables_cache)
return cached_value;
- (void) args[0]->val();
- return (args[0]->null_value) ? 1 : 0;
+ return args[0]->is_null() ? 1: 0;
}
longlong Item_func_isnotnull::val_int()
{
- (void) args[0]->val();
- return !(args[0]->null_value) ? 1 : 0;
+ return args[0]->is_null() ? 0 : 1;
}
@@ -1229,23 +1228,23 @@ void Item_func_like::fix_length_and_dec()
// cmp_type=STRING_RESULT; // For quick select
}
-
longlong Item_func_like::val_int()
{
- String *res,*res2;
- res=args[0]->val_str(&tmp_value1);
+ String* res = args[0]->val_str(&tmp_value1);
if (args[0]->null_value)
{
null_value=1;
return 0;
}
- res2=args[1]->val_str(&tmp_value2);
+ String* res2 = args[1]->val_str(&tmp_value2);
if (args[1]->null_value)
{
null_value=1;
return 0;
}
null_value=0;
+ if (canDoTurboBM)
+ return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
if (binary)
return wild_compare(*res,*res2,escape) ? 0 : 1;
else
@@ -1269,6 +1268,55 @@ Item_func::optimize_type Item_func_like::select_optimize() const
return OPTIMIZE_NONE;
}
+bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist)
+{
+ if (Item_bool_func2::fix_fields(thd, tlist))
+ return 1;
+
+ /*
+ TODO--we could do it for non-const, but we'd have to
+ recompute the tables for each row--probably not worth it.
+ */
+ if (args[1]->const_item() && !(specialflag & SPECIAL_NO_NEW_FUNC))
+ {
+ String* res2 = args[1]->val_str(&tmp_value2);
+ if (!res2)
+ return 0; // Null argument
+
+ const size_t len = res2->length();
+ const char* first = res2->ptr();
+ const char* last = first + len - 1;
+ /*
+ len must be > 2 ('%pattern%')
+ heuristic: only do TurboBM for pattern_len > 2
+ */
+
+ if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
+ *first == wild_many &&
+ *last == wild_many)
+ {
+ const char* tmp = first + 1;
+ for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
+ canDoTurboBM = tmp == last;
+ }
+
+ if (canDoTurboBM)
+ {
+ pattern = first + 1;
+ pattern_len = len - 2;
+ DBUG_PRINT("info", ("Initializing pattern: '%s'", first));
+ int *suff = (int*) thd->alloc(sizeof(int)*((pattern_len + 1)*2+
+ alphabet_size));
+ bmGs = suff + pattern_len + 1;
+ bmBc = bmGs + pattern_len + 1;
+ turboBM_compute_good_suffix_shifts(suff);
+ turboBM_compute_bad_character_shifts();
+ DBUG_PRINT("info",("done"));
+ }
+ }
+ return 0;
+}
+
#ifdef USE_REGEX
bool
@@ -1308,7 +1356,6 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables)
return 0;
}
-
longlong Item_func_regex::val_int()
{
char buff[MAX_FIELD_WIDTH];
@@ -1365,3 +1412,254 @@ Item_func_regex::~Item_func_regex()
}
#endif /* USE_REGEX */
+
+
+#ifdef LIKE_CMP_TOUPPER
+#define likeconv(A) (uchar) toupper(A)
+#else
+#define likeconv(A) (uchar) my_sort_order[(uchar) (A)]
+#endif
+
+
+/**********************************************************************
+ turboBM_compute_suffixes()
+ Precomputation dependent only on pattern_len.
+**********************************************************************/
+
+void Item_func_like::turboBM_compute_suffixes(int* suff)
+{
+ const int plm1 = pattern_len - 1;
+ int f = 0;
+ int g = plm1;
+ int* const splm1 = suff + plm1;
+
+ *splm1 = pattern_len;
+
+ if (binary)
+ {
+ int i;
+ for (i = pattern_len - 2; i >= 0; i--)
+ {
+ int tmp = *(splm1 + i - f);
+ if (g < i && tmp < i - g)
+ suff[i] = tmp;
+ else
+ {
+ if (i < g)
+ g = i; // g = min(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+ suff[i] = f - g;
+ }
+ }
+ }
+ else
+ {
+ int i;
+ for (i = pattern_len - 2; 0 <= i; --i)
+ {
+ int tmp = *(splm1 + i - f);
+ if (g < i && tmp < i - g)
+ suff[i] = tmp;
+ else
+ {
+ if (i < g)
+ g = i; // g = min(i, g)
+ f = i;
+ while (g >= 0 && likeconv(pattern[g]) == likeconv(pattern[g + plm1 - f]))
+ g--;
+ suff[i] = f - g;
+ }
+ }
+ }
+}
+
+
+/**********************************************************************
+ turboBM_compute_good_suffix_shifts()
+ Precomputation dependent only on pattern_len.
+**********************************************************************/
+
+void Item_func_like::turboBM_compute_good_suffix_shifts(int* suff)
+{
+ turboBM_compute_suffixes(suff);
+
+ int* end = bmGs + pattern_len;
+ int* k;
+ for (k = bmGs; k < end; k++)
+ *k = pattern_len;
+
+ int tmp;
+ int i;
+ int j = 0;
+ const int plm1 = pattern_len - 1;
+ for (i = plm1; i > -1; i--)
+ {
+ if (suff[i] == i + 1)
+ {
+ for (tmp = plm1 - i; j < tmp; j++)
+ {
+ int* tmp2 = bmGs + j;
+ if (*tmp2 == pattern_len)
+ *tmp2 = tmp;
+ }
+ }
+ }
+
+ int* tmp2;
+ for (tmp = plm1 - i; j < tmp; j++)
+ {
+ tmp2 = bmGs + j;
+ if (*tmp2 == pattern_len)
+ *tmp2 = tmp;
+ }
+
+ tmp2 = bmGs + plm1;
+ for (i = 0; i <= pattern_len - 2; i++)
+ *(tmp2 - suff[i]) = plm1 - i;
+}
+
+
+/**********************************************************************
+ turboBM_compute_bad_character_shifts()
+ Precomputation dependent on pattern_len.
+**********************************************************************/
+
+void Item_func_like::turboBM_compute_bad_character_shifts()
+{
+ int* i;
+ int* end = bmBc + alphabet_size;
+ for (i = bmBc; i < end; i++)
+ *i = pattern_len;
+
+ int j;
+ const int plm1 = pattern_len - 1;
+ if (binary)
+ for (j = 0; j < plm1; j++)
+ bmBc[pattern[j]] = plm1 - j;
+ else
+ for (j = 0; j < plm1; j++)
+ bmBc[likeconv(pattern[j])] = plm1 - j;
+}
+
+
+/**********************************************************************
+ turboBM_matches()
+ Search for pattern in text, returns true/false for match/no match
+**********************************************************************/
+
+bool Item_func_like::turboBM_matches(const char* text, int text_len) const
+{
+ register int bcShift;
+ register int turboShift;
+ int shift = pattern_len;
+ int j = 0;
+ int u = 0;
+
+ const int plm1 = pattern_len - 1;
+ const int tlmpl = text_len - pattern_len;
+
+ /* Searching */
+ if (binary)
+ {
+ while (j <= tlmpl)
+ {
+ register int i = plm1;
+ while (i >= 0 && pattern[i] == text[i + j])
+ {
+ i--;
+ if (i == plm1 - shift)
+ i -= u;
+ }
+ if (i < 0)
+ return true;
+
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[text[i + j]] - plm1 + i;
+ shift = max(turboShift, bcShift);
+ shift = max(shift, bmGs[i]);
+ if (shift == bmGs[i])
+ u = min(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+ shift = max(shift, u + 1);
+ u = 0;
+ }
+ j += shift;
+ }
+ return false;
+ }
+ else
+ {
+ while (j <= tlmpl)
+ {
+ register int i = plm1;
+ while (i >= 0 && likeconv(pattern[i]) == likeconv(text[i + j]))
+ {
+ i--;
+ if (i == plm1 - shift)
+ i -= u;
+ }
+ if (i < 0)
+ return true;
+
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[likeconv(text[i + j])] - plm1 + i;
+ shift = max(turboShift, bcShift);
+ shift = max(shift, bmGs[i]);
+ if (shift == bmGs[i])
+ u = min(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+ shift = max(shift, u + 1);
+ u = 0;
+ }
+ j += shift;
+ }
+ return false;
+ }
+}
+
+
+/*
+ Make a logical XOR of the arguments.
+
+ SYNOPSIS
+ val_int()
+
+ DESCRIPTION
+ If either operator is NULL, return NULL.
+
+ NOTE
+ As we don't do any index optimization on XOR this is not going to be
+ very fast to use.
+
+ TODO (low priority)
+ Change this to be optimized as:
+ A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
+ To be able to do this, we would however first have to extend the MySQL
+ range optimizer to handle OR better.
+*/
+
+longlong Item_cond_xor::val_int()
+{
+ List_iterator<Item> li(list);
+ Item *item;
+ int result=0;
+ null_value=0;
+ while ((item=li++))
+ {
+ result^= (item->val_int() != 0);
+ if (item->null_value)
+ {
+ null_value=1;
+ return 0;
+ }
+ }
+ return (longlong) result;
+}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index e7c598808e8..9d83a8a9673 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -28,6 +28,7 @@ public:
Item_bool_func(Item *a) :Item_int_func(a) {}
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
void fix_length_and_dec() { decimals=0; max_length=1; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_bool_func2 :public Item_int_func
@@ -46,6 +47,8 @@ public:
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
void print(String *str) { Item_func::print_op(str); }
+ bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -79,6 +82,7 @@ public:
enum Functype rev_functype() const { return EQUAL_FUNC; }
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "<=>"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -184,6 +188,7 @@ public:
~Item_func_interval() { delete item; }
const char *func_name() const { return "interval"; }
void update_used_tables();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -198,6 +203,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "ifnull"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -212,6 +218,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "if"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -226,6 +233,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "nullif"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -240,6 +248,7 @@ public:
void fix_length_and_dec();
enum Item_result result_type () const { return cached_result_type; }
const char *func_name() const { return "coalesce"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_case :public Item_func
@@ -260,6 +269,7 @@ public:
void print(String *str);
bool fix_fields(THD *thd,struct st_table_list *tlist);
Item *find_item(String *str);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -421,6 +431,7 @@ class Item_func_in :public Item_int_func
enum Functype functype() const { return IN_FUNC; }
const char *func_name() const { return " IN "; }
void update_used_tables();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -458,6 +469,7 @@ public:
}
}
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_isnotnull :public Item_bool_func
@@ -466,16 +478,38 @@ public:
Item_func_isnotnull(Item *a) :Item_bool_func(a) {}
longlong val_int();
enum Functype functype() const { return ISNOTNULL_FUNC; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
+ void fix_length_and_dec()
+ {
+ decimals=0; max_length=1; maybe_null=0;
+ }
const char *func_name() const { return "isnotnull"; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_like :public Item_bool_func2
{
char escape;
+
+ // Turbo Boyer-Moore data
+ bool canDoTurboBM; // pattern is '%abcd%' case
+ const char* pattern;
+ int pattern_len;
+
+ // TurboBM buffers, *this is owner
+ int* bmGs; // good suffix shift table, size is pattern_len + 1
+ int* bmBc; // bad character shift table, size is alphabet_size
+
+ void turboBM_compute_suffixes(int* suff);
+ void turboBM_compute_good_suffix_shifts(int* suff);
+ void turboBM_compute_bad_character_shifts();
+ bool turboBM_matches(const char* text, int text_len) const;
+ enum { alphabet_size = 256 };
+
public:
- Item_func_like(Item *a,Item *b, char* escape_arg) :Item_bool_func2(a,b),escape(*escape_arg)
+ Item_func_like(Item *a,Item *b, char* escape_arg)
+ :Item_bool_func2(a,b), escape(*escape_arg), canDoTurboBM(false),
+ pattern(0), pattern_len(0), bmGs(0), bmBc(0)
{}
longlong val_int();
enum Functype functype() const { return LIKE_FUNC; }
@@ -483,6 +517,8 @@ public:
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "like"; }
void fix_length_and_dec();
+ bool fix_fields(THD *thd,struct st_table_list *tlist);
+ unsigned int size_of() { return sizeof(*this);}
};
#ifdef USE_REGEX
@@ -502,6 +538,7 @@ public:
longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist);
const char *func_name() const { return "regex"; }
+ unsigned int size_of() { return sizeof(*this);}
};
#else
@@ -538,6 +575,7 @@ public:
void print(String *str);
void split_sum_func(List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -573,3 +611,13 @@ inline Item *and_conds(Item *a,Item *b)
cond->update_used_tables();
return cond;
}
+
+class Item_cond_xor :public Item_cond
+{
+public:
+ Item_cond_xor() :Item_cond() {}
+ Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
+ enum Functype functype() const { return COND_XOR_FUNC; }
+ longlong val_int();
+ const char *func_name() const { return "xor"; }
+};
diff --git a/sql/item_create.cc b/sql/item_create.cc
index ef9f5f2d38b..62f09f002d1 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -32,6 +32,16 @@ Item *create_func_acos(Item* a)
return new Item_func_acos(a);
}
+Item *create_func_aes_encrypt(Item* a, Item* b)
+{
+ return new Item_func_aes_encrypt(a, b);
+}
+
+Item *create_func_aes_decrypt(Item* a, Item* b)
+{
+ return new Item_func_aes_decrypt(a, b);
+}
+
Item *create_func_ascii(Item* a)
{
return new Item_func_ascii(a);
@@ -65,7 +75,9 @@ Item *create_func_ceiling(Item* a)
Item *create_func_connection_id(void)
{
- return new Item_int("CONNECTION_ID()",(longlong) current_thd->thread_id,10);
+ THD *thd=current_thd;
+ thd->safe_to_cache_query=0;
+ return new Item_int("CONNECTION_ID()",(longlong) thd->thread_id,10);
}
Item *create_func_conv(Item* a, Item *b, Item *c)
@@ -129,6 +141,13 @@ Item *create_func_floor(Item* a)
return new Item_func_floor(a);
}
+Item *create_func_found_rows(void)
+{
+ THD *thd=current_thd;
+ thd->safe_to_cache_query=0;
+ return new Item_int("FOUND_ROWS()",(longlong) thd->found_rows(),21);
+}
+
Item *create_func_from_days(Item* a)
{
return new Item_func_from_days(a);
@@ -136,13 +155,13 @@ Item *create_func_from_days(Item* a)
Item *create_func_get_lock(Item* a, Item *b)
{
+ current_thd->safe_to_cache_query=0;
return new Item_func_get_lock(a, b);
}
Item *create_func_hex(Item *a)
{
- return new Item_func_conv(a,new Item_int((int32) 10,2),
- new Item_int((int32) 16,2));
+ return new Item_func_hex(a);
}
Item *create_func_inet_ntoa(Item* a)
@@ -191,6 +210,11 @@ Item *create_func_length(Item* a)
return new Item_func_length(a);
}
+Item *create_func_bit_length(Item* a)
+{
+ return new Item_func_bit_length(a);
+}
+
Item *create_func_char_length(Item* a)
{
return new Item_func_char_length(a);
@@ -274,6 +298,7 @@ Item *create_func_radians(Item *a)
Item *create_func_release_lock(Item* a)
{
+ current_thd->safe_to_cache_query=0;
return new Item_func_release_lock(a);
}
@@ -312,6 +337,11 @@ Item *create_func_sin(Item* a)
return new Item_func_sin(a);
}
+Item *create_func_sha(Item* a)
+{
+ return new Item_func_sha(a);
+}
+
Item *create_func_space(Item *a)
{
return new Item_func_repeat(new Item_string(" ",1),a);
@@ -374,10 +404,34 @@ Item *create_func_year(Item* a)
Item *create_load_file(Item* a)
{
+ current_thd->safe_to_cache_query=0;
return new Item_load_file(a);
}
Item *create_wait_for_master_pos(Item* a, Item* b)
{
+ current_thd->safe_to_cache_query=0;
return new Item_master_pos_wait(a, b);
}
+
+Item *create_func_cast(Item *a, Item_cast cast_type)
+{
+ Item *res;
+ LINT_INIT(res);
+ switch (cast_type) {
+ case ITEM_CAST_BINARY: res= new Item_func_binary(a); break;
+ case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break;
+ case ITEM_CAST_UNSIGNED_INT: res= new Item_func_unsigned(a); break;
+ case ITEM_CAST_DATE: res= new Item_date_typecast(a); break;
+ case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
+ case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
+ }
+ return res;
+}
+
+Item *create_func_is_free_lock(Item* a)
+{
+ current_thd->safe_to_cache_query=0;
+ return new Item_func_is_free_lock(a);
+}
+
diff --git a/sql/item_create.h b/sql/item_create.h
index cc7497b0183..967de0e2eba 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,10 +18,13 @@
Item *create_func_abs(Item* a);
Item *create_func_acos(Item* a);
+Item *create_func_aes_encrypt(Item* a, Item* b);
+Item *create_func_aes_decrypt(Item* a, Item* b);
Item *create_func_ascii(Item* a);
Item *create_func_asin(Item* a);
Item *create_func_bin(Item* a);
Item *create_func_bit_count(Item* a);
+Item *create_func_bit_length(Item* a);
Item *create_func_ceiling(Item* a);
Item *create_func_char_length(Item* a);
Item *create_func_connection_id(void);
@@ -37,6 +40,7 @@ Item *create_func_degrees(Item *);
Item *create_func_exp(Item* a);
Item *create_func_find_in_set(Item* a, Item *b);
Item *create_func_floor(Item* a);
+Item *create_func_found_rows(void);
Item *create_func_from_days(Item* a);
Item *create_func_get_lock(Item* a, Item *b);
Item *create_func_hex(Item *a);
@@ -73,6 +77,7 @@ Item *create_func_rtrim(Item* a);
Item *create_func_sec_to_time(Item* a);
Item *create_func_sign(Item* a);
Item *create_func_sin(Item* a);
+Item *create_func_sha(Item* a);
Item *create_func_soundex(Item* a);
Item *create_func_space(Item *);
Item *create_func_sqrt(Item* a);
@@ -86,3 +91,4 @@ Item *create_func_version(void);
Item *create_func_weekday(Item* a);
Item *create_load_file(Item* a);
Item *create_wait_for_master_pos(Item* a, Item* b);
+Item *create_func_is_free_lock(Item* a);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index b73436afbcf..45b9b473934 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -43,7 +43,7 @@ Item_func::Item_func(List<Item> &list)
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{
uint i=0;
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
@@ -184,8 +184,10 @@ String *Item_num_func::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0; /* purecov: inspected */
- else
+ else if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
}
else
{
@@ -207,24 +209,31 @@ void Item_func::fix_num_length_and_dec()
max_length=float_length(decimals);
}
-
String *Item_int_func::val_str(String *str)
{
longlong nr=val_int();
if (null_value)
return 0;
- else
+ else if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
return str;
}
-/* Change from REAL_RESULT (default) to INT_RESULT if both arguments are integers */
+/*
+ Change from REAL_RESULT (default) to INT_RESULT if both arguments are
+ integers
+*/
void Item_num_op::find_num_type(void)
{
if (args[0]->result_type() == INT_RESULT &&
args[1]->result_type() == INT_RESULT)
+ {
hybrid_type=INT_RESULT;
+ unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
+ }
}
String *Item_num_op::val_str(String *str)
@@ -234,8 +243,10 @@ String *Item_num_op::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0; /* purecov: inspected */
- else
+ else if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
}
else
{
@@ -269,6 +280,21 @@ longlong Item_func_plus::val_int()
return (longlong) Item_func_plus::val();
}
+
+/*
+ The following function is here to allow the user to force
+ subtraction of UNSIGNED BIGINT to return negative values.
+*/
+
+void Item_func_minus::fix_length_and_dec()
+{
+ Item_num_op::fix_length_and_dec();
+ if (unsigned_flag &&
+ (current_thd->sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
+ unsigned_flag=0;
+}
+
+
double Item_func_minus::val()
{
double value=args[0]->val() - args[1]->val();
@@ -615,8 +641,9 @@ double Item_func_rand::val()
{
if (arg_count)
{ // Only use argument once in query
- ulong tmp=((ulong) args[0]->val_int())+55555555L;
- randominit(&current_thd->rand,tmp,tmp/2);
+ uint32 tmp= (uint32) (args[0]->val_int());
+ randominit(&current_thd->rand,(uint32) (tmp*0x10001L+55555555L),
+ (uint32) (tmp*0x10000001L));
#ifdef DELETE_ITEMS
delete args[0];
#endif
@@ -672,8 +699,10 @@ String *Item_func_min_max::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0;
- else
+ else if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
return str;
}
case REAL_RESULT:
@@ -789,9 +818,7 @@ longlong Item_func_locate::val_int()
{
String *a=args[0]->val_str(&value1);
String *b=args[1]->val_str(&value2);
-#ifdef USE_MB
bool binary_str = args[0]->binary || args[1]->binary;
-#endif
if (!a || !b)
{
null_value=1;
@@ -845,7 +872,8 @@ longlong Item_func_locate::val_int()
return 0;
}
#endif /* USE_MB */
- return (longlong) (a->strstr(*b,start)+1) ;
+ return (longlong) (binary ? a->strstr(*b,start) :
+ (a->strstr_case(*b,start)))+1;
}
@@ -1055,7 +1083,8 @@ udf_handler::~udf_handler()
}
free_udf(u_d);
}
- delete [] buffers;
+ if (buffers) // Because of bug in ecc
+ delete [] buffers;
}
@@ -1311,8 +1340,10 @@ String *Item_func_udf_int::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0;
- else
+ else if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
return str;
}
@@ -1407,19 +1438,19 @@ void item_user_lock_release(ULL *ull)
if (mysql_bin_log.is_open())
{
THD *thd = current_thd;
- int save_errno;
+ uint save_query_length;
char buf[256];
String tmp(buf,sizeof(buf));
tmp.length(0);
tmp.append("DO RELEASE_LOCK(\"");
tmp.append(ull->key,ull->key_length);
tmp.append("\")");
- save_errno=thd->net.last_errno;
- thd->net.last_errno=0;
+ save_query_length=thd->query_length;
thd->query_length=tmp.length();
Query_log_event qev(thd,tmp.ptr());
+ qev.error_code=0; // this query is always safe to run on slave
mysql_bin_log.write(&qev);
- thd->net.last_errno=save_errno;
+ thd->query_length=save_query_length;
}
if (--ull->count)
pthread_cond_signal(&ull->cond);
@@ -1437,7 +1468,7 @@ longlong Item_master_pos_wait::val_int()
THD* thd = current_thd;
String *log_name = args[0]->val_str(&value);
int event_count;
-
+
null_value=0;
if (thd->slave_thread || !log_name || !log_name->length())
{
@@ -1445,14 +1476,86 @@ longlong Item_master_pos_wait::val_int()
return 0;
}
ulong pos = (ulong)args[1]->val_int();
- if ((event_count = glob_mi.wait_for_pos(thd, log_name, pos)) == -1)
+ LOCK_ACTIVE_MI;
+ if ((event_count = active_mi->rli.wait_for_pos(thd, log_name, pos)) == -1)
{
null_value = 1;
event_count=0;
}
+ UNLOCK_ACTIVE_MI;
return event_count;
}
+#ifdef EXTRA_DEBUG
+void debug_sync_point(const char* lock_name, uint lock_timeout)
+{
+ THD* thd=current_thd;
+ ULL* ull;
+ struct timespec abstime;
+ int lock_name_len,error=0;
+ lock_name_len=strlen(lock_name);
+ pthread_mutex_lock(&LOCK_user_locks);
+
+ if (thd->ull)
+ {
+ item_user_lock_release(thd->ull);
+ thd->ull=0;
+ }
+
+ /*
+ If the lock has not been aquired by some client, we do not want to
+ create an entry for it, since we immediately release the lock. In
+ this case, we will not be waiting, but rather, just waste CPU and
+ memory on the whole deal
+ */
+ if (!(ull= ((ULL*) hash_search(&hash_user_locks,lock_name,
+ lock_name_len))))
+ {
+ pthread_mutex_unlock(&LOCK_user_locks);
+ return;
+ }
+ ull->count++;
+
+ /*
+ Structure is now initialized. Try to get the lock.
+ Set up control struct to allow others to abort locks
+ */
+ thd->proc_info="User lock";
+ thd->mysys_var->current_mutex= &LOCK_user_locks;
+ thd->mysys_var->current_cond= &ull->cond;
+
+ set_timespec(abstime,lock_timeout);
+ while (!thd->killed &&
+ (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
+ != ETIME && error != ETIMEDOUT && ull->locked) ;
+ if (ull->locked)
+ {
+ if (!--ull->count)
+ delete ull; // Should never happen
+ }
+ else
+ {
+ ull->locked=1;
+ ull->thread=thd->real_id;
+ thd->ull=ull;
+ }
+ pthread_mutex_unlock(&LOCK_user_locks);
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->proc_info=0;
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+ pthread_mutex_lock(&LOCK_user_locks);
+ if (thd->ull)
+ {
+ item_user_lock_release(thd->ull);
+ thd->ull=0;
+ }
+ pthread_mutex_unlock(&LOCK_user_locks);
+}
+
+#endif
+
/*
Get a user level lock. If the thread has an old lock this is first released.
Returns 1: Got lock
@@ -1503,20 +1606,15 @@ longlong Item_func_get_lock::val_int()
}
ull->count++;
- /* structure is now initialized. Try to get the lock */
- /* Set up control struct to allow others to abort locks */
+ /*
+ Structure is now initialized. Try to get the lock.
+ Set up control struct to allow others to abort locks.
+ */
thd->proc_info="User lock";
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time((time_t*) 0)+(time_t) timeout;
- abstime.ts_nsec=0;
-#else
- abstime.tv_sec=time((time_t*) 0)+(time_t) timeout;
- abstime.tv_nsec=0;
-#endif
-
+ set_timespec(abstime,timeout);
while (!thd->killed &&
(error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
!= ETIME && error != ETIMEDOUT && error != EINVAL && ull->locked) ;
@@ -1552,10 +1650,11 @@ longlong Item_func_get_lock::val_int()
/*
-** Release a user level lock.
-** Returns 1 if lock released
-** 0 if lock wasn't held
-** NULL if no such lock
+ Release a user level lock.
+ Return:
+ 1 if lock released
+ 0 if lock wasn't held
+ (SQL) NULL if no such lock
*/
longlong Item_func_release_lock::val_int()
@@ -1624,6 +1723,7 @@ longlong Item_func_benchmark::val_int()
return 0;
}
+
#define extra_size sizeof(double)
static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
@@ -1661,7 +1761,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (!thd)
- thd=current_thd;
+ thd=current_thd; // Should never happen
if (Item_func::fix_fields(thd,tables) ||
!(entry= get_variable(&thd->user_vars, name, 1)))
return 1;
@@ -1887,6 +1987,7 @@ void Item_func_get_user_var::print(String *str)
str->append(')');
}
+
bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
{
/* Assume we don't have rtti */
@@ -1946,49 +2047,15 @@ err:
return 0;
}
-double Item_func_match::val()
-{
- if (ft_handler==NULL)
- return -1.0;
-
- if (join_key)
- {
- if (table->file->ft_handler)
- return ft_get_relevance(ft_handler);
-
- join_key=0; // Magic here ! See ha_myisam::ft_read()
- }
-
- /* we'll have to find ft_relevance manually in ft_handler array */
-
- int a,b,c;
- FT_DOC *docs=ft_handler->doc;
- my_off_t docid=table->file->row_position();
-
- if ((null_value=(docid==HA_OFFSET_ERROR)))
- return 0.0;
-
- // Assuming docs[] is sorted by dpos...
-
- for (a=0, b=ft_handler->ndocs, c=(a+b)/2; b-a>1; c=(a+b)/2)
- {
- if (docs[c].dpos > docid)
- b=c;
- else
- a=c;
- }
- if (docs[a].dpos == docid)
- return docs[a].weight;
- else
- return 0.0;
-
-}
void Item_func_match::init_search(bool no_order)
{
if (ft_handler)
return;
+ if (key == NO_SUCH_KEY)
+ concat= new Item_func_concat_ws(new Item_string(" ",1), fields);
+
if (master)
{
join_key=master->join_key=join_key|master->join_key;
@@ -2002,16 +2069,17 @@ void Item_func_match::init_search(bool no_order)
char tmp1[FT_QUERY_MAXLEN];
String tmp2(tmp1,sizeof(tmp1));
- // MATCH ... AGAINST (NULL) is meaningless, but possible
+ // MATCH ... AGAINST (NULL) is meaningless, but possible
if (!(ft_tmp=key_item()->val_str(&tmp2)))
{
- ft_tmp=&tmp2;
+ ft_tmp= &tmp2;
tmp2.set("",0);
}
- ft_handler=(FT_DOCLIST *)
- table->file->ft_init_ext(key, (byte*) ft_tmp->ptr(), ft_tmp->length(),
- join_key && !no_order);
+ ft_handler=table->file->ft_init_ext(mode, key,
+ (byte*) ft_tmp->ptr(),
+ ft_tmp->length(),
+ join_key && !no_order);
if (join_key)
{
@@ -2020,6 +2088,7 @@ void Item_func_match::init_search(bool no_order)
}
}
+
bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
{
List_iterator<Item> li(fields);
@@ -2028,12 +2097,12 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
maybe_null=1;
join_key=0;
- /* Serg:
- I'd rather say now that const_item is assumed in quite a bit of
- places, so it would be difficult to remove; If it would ever to be
- removed, this should include modifications to find_best and auto_close
- as complement to auto_init code above.
- */
+ /*
+ const_item is assumed in quite a bit of places, so it would be difficult
+ to remove; If it would ever to be removed, this should include
+ modifications to find_best and auto_close as complement to auto_init code
+ above.
+ */
if (Item_func::fix_fields(thd,tlist) || !const_item())
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
@@ -2047,30 +2116,35 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
if (item->type() == Item::REF_ITEM)
li.replace(item= *((Item_ref *)item)->ref);
if (item->type() != Item::FIELD_ITEM || !item->used_tables())
- {
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
- return 1;
- }
+ key=NO_SUCH_KEY;
used_tables_cache|=item->used_tables();
}
/* check that all columns come from the same table */
if (count_bits(used_tables_cache) != 1)
+ key=NO_SUCH_KEY;
+ const_item_cache=0;
+ table=((Item_field *)fields.head())->field->table;
+ table->fulltext_searched=1;
+ record=table->record[0];
+ if (key == NO_SUCH_KEY && mode != FT_BOOL)
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
return 1;
}
- const_item_cache=0;
- table=((Item_field *)fields.head())->field->table;
- table->fulltext_searched=1;
+
return 0;
}
bool Item_func_match::fix_index()
{
- List_iterator<Item> li(fields);
+ List_iterator_fast<Item> li(fields);
Item_field *item;
uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, key;
+ uint max_cnt=0, mkeys=0;
+
+ if (this->key == NO_SUCH_KEY)
+ return 0;
for (key=0 ; key<table->keys ; key++)
{
@@ -2084,11 +2158,7 @@ bool Item_func_match::fix_index()
}
if (!fts)
- {
- my_printf_error(ER_FT_MATCHING_KEY_NOT_FOUND,
- ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0));
- return 1;
- }
+ goto err;
while ((item=(Item_field*)(li++)))
{
@@ -2105,7 +2175,6 @@ bool Item_func_match::fix_index()
}
}
- uint max_cnt=0, mkeys=0;
for (key=0 ; key<fts ; key++)
{
if (ft_cnt[key] > max_cnt)
@@ -2136,17 +2205,22 @@ bool Item_func_match::fix_index()
return 0;
}
+err:
+ if (mode == FT_BOOL)
+ {
+ this->key=NO_SUCH_KEY;
+ return 0;
+ }
my_printf_error(ER_FT_MATCHING_KEY_NOT_FOUND,
- ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0));
+ ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0));
return 1;
}
+
bool Item_func_match::eq(const Item *item, bool binary_cmp) const
{
- if (item->type() != FUNC_ITEM)
- return 0;
-
- if (func_name() != ((Item_func*)item)->func_name())
+ if (item->type() != FUNC_ITEM ||
+ func_name() != ((Item_func*)item)->func_name())
return 0;
Item_func_match *ifm=(Item_func_match*) item;
@@ -2159,19 +2233,102 @@ bool Item_func_match::eq(const Item *item, bool binary_cmp) const
}
+double Item_func_match::val()
+{
+ if (ft_handler == NULL)
+ return -1.0;
+
+ if (join_key)
+ {
+ if (table->file->ft_handler)
+ return ft_handler->please->get_relevance(ft_handler);
+ join_key=0;
+ }
+
+ if (key == NO_SUCH_KEY)
+ {
+ String *a= concat->val_str(&value);
+ if ((null_value= (a == 0)))
+ return 0;
+ return ft_handler->please->find_relevance(ft_handler,
+ (byte *)a->ptr(), a->length());
+ }
+ else
+ return ft_handler->please->find_relevance(ft_handler, record, 0);
+}
+
+longlong Item_func_bit_xor::val_int()
+{
+ ulonglong arg1= (ulonglong) args[0]->val_int();
+ ulonglong arg2= (ulonglong) args[1]->val_int();
+ if ((null_value= (args[0]->null_value || args[1]->null_value)))
+ return 0;
+ return (longlong) (arg1 ^ arg2);
+}
+
+
/***************************************************************************
System variables
- This has to be recoded after we get more than 3 system variables
****************************************************************************/
-Item *get_system_var(LEX_STRING name)
+Item *get_system_var(enum_var_type var_type, LEX_STRING name)
{
- if (!my_strcasecmp(name.str,"IDENTITY"))
- return new Item_int((char*) "@@IDENTITY",
- current_thd->insert_id(),21);
if (!my_strcasecmp(name.str,"VERSION"))
return new Item_string("@@VERSION",server_version,
(uint) strlen(server_version));
- net_printf(&current_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
+
+ THD *thd=current_thd;
+ Item *item;
+ sys_var *var;
+ char buff[MAX_SYS_VAR_LENGTH+3];
+
+ if (!(var= find_sys_var(name.str)))
+ {
+ net_printf(&thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
+ return 0;
+ }
+ if (!(item=var->item(thd, var_type)))
+ return 0; // Impossible
+ thd->safe_to_cache_query=0;
+ buff[0]='@';
+ buff[1]='@';
+ memcpy(buff+2, var->name, var->name_length+1);
+ item->set_name(buff,var->name_length+2); // Will allocate name
+ return item;
+}
+
+
+/*
+ Check a user level lock.
+
+ SYNOPSIS:
+ val_int()
+
+ RETURN VALUES
+ 1 Available
+ 0 Already taken
+ NULL Error
+*/
+
+longlong Item_func_is_free_lock::val_int()
+{
+ String *res=args[0]->val_str(&value);
+ THD *thd=current_thd;
+ ULL *ull;
+ int error=0;
+
+ null_value=0;
+ if (!res || !res->length())
+ {
+ null_value=1;
+ return 0;
+ }
+
+ pthread_mutex_lock(&LOCK_user_locks);
+ ull= (ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(),
+ res->length());
+ pthread_mutex_unlock(&LOCK_user_locks);
+ if (!ull || !ull->locked)
+ return 1;
return 0;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 1d85973055b..846d99a29d2 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -39,7 +39,7 @@ public:
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
GE_FUNC,GT_FUNC,FT_FUNC,
LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
- COND_AND_FUNC,COND_OR_FUNC,BETWEEN,IN_FUNC,INTERVAL_FUNC};
+ COND_AND_FUNC,COND_OR_FUNC,COND_XOR_FUNC,BETWEEN,IN_FUNC,INTERVAL_FUNC};
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
@@ -119,7 +119,9 @@ public:
{
return (null_value=args[0]->get_time(ltime));
}
+ bool is_null() { (void) val_int(); return null_value; }
friend class udf_handler;
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -134,6 +136,12 @@ public:
longlong val_int() { return (longlong) val(); }
enum Item_result result_type () const { return REAL_RESULT; }
void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_double(max_length, maybe_null, name,t_arg,decimals);
+ }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_num_func :public Item_func
@@ -147,6 +155,8 @@ public:
longlong val_int() { return (longlong) val(); }
enum Item_result result_type () const { return hybrid_type; }
void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool is_null() { (void) val(); return null_value; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -161,23 +171,69 @@ class Item_num_op :public Item_func
enum Item_result result_type () const { return hybrid_type; }
void fix_length_and_dec() { fix_num_length_and_dec(); find_num_type(); }
void find_num_type(void);
+ bool is_null() { (void) val(); return null_value; }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ Field *res;
+ if (!t_arg)
+ return result_field;
+ if (args[0]->result_type() == INT_RESULT)
+ {
+ if (max_length > 11)
+ res= new Field_longlong(max_length, maybe_null, name, t_arg,
+ unsigned_flag);
+ else
+ res= new Field_long(max_length, maybe_null, name, t_arg,
+ unsigned_flag);
+ }
+ else
+ res= new Field_double(max_length, maybe_null, name, t_arg, decimals);
+ return res;
+ }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_int_func :public Item_func
{
public:
- Item_int_func() :Item_func() {}
- Item_int_func(Item *a) :Item_func(a) {}
- Item_int_func(Item *a,Item *b) :Item_func(a,b) {}
- Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) {}
- Item_int_func(List<Item> &list) :Item_func(list) {}
+ Item_int_func() :Item_func() { max_length=21; }
+ Item_int_func(Item *a) :Item_func(a) { max_length=21; }
+ Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length=21; }
+ Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; }
+ Item_int_func(List<Item> &list) :Item_func(list) { max_length=21; }
double val() { return (double) val_int(); }
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ void fix_length_and_dec() {}
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return (max_length > 11) ? (Field *)new Field_longlong(max_length,maybe_null,name, t_arg,unsigned_flag) : (Field *)new Field_long(max_length,maybe_null,name, t_arg,unsigned_flag);
+ }
+};
+
+class Item_func_signed :public Item_int_func
+{
+public:
+ Item_func_signed(Item *a) :Item_int_func(a) {}
+ double val() { return args[0]->val(); }
+ longlong val_int() { return args[0]->val_int(); }
+ void fix_length_and_dec()
+ { max_length=args[0]->max_length; unsigned_flag=0; }
+};
+
+class Item_func_unsigned :public Item_int_func
+{
+public:
+ Item_func_unsigned(Item *a) :Item_int_func(a) {}
+ double val() { return args[0]->val(); }
+ longlong val_int() { return args[0]->val_int(); }
+ void fix_length_and_dec()
+ { max_length=args[0]->max_length; unsigned_flag=1; }
};
+
class Item_func_plus :public Item_num_op
{
public:
@@ -194,8 +250,10 @@ public:
const char *func_name() const { return "-"; }
double val();
longlong val_int();
+ void fix_length_and_dec();
};
+
class Item_func_mul :public Item_num_op
{
public:
@@ -405,6 +463,7 @@ public:
const char *func_name() const { return truncate ? "truncate" : "round"; }
double val();
void fix_length_and_dec();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -440,6 +499,7 @@ class Item_func_units :public Item_real_func
double val();
const char *func_name() const { return name; }
void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -456,6 +516,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
enum Item_result result_type () const { return cmp_type; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_min :public Item_func_min_max
@@ -481,6 +542,15 @@ public:
longlong val_int();
const char *func_name() const { return "length"; }
void fix_length_and_dec() { max_length=10; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_func_bit_length :public Item_func_length
+{
+public:
+ Item_func_bit_length(Item *a) :Item_func_length(a) {}
+ longlong val_int() { return Item_func_length::val_int()*8; }
+ const char *func_name() const { return "bit_length"; }
};
class Item_func_char_length :public Item_int_func
@@ -491,6 +561,7 @@ public:
longlong val_int();
const char *func_name() const { return "char_length"; }
void fix_length_and_dec() { max_length=10; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_locate :public Item_int_func
@@ -502,6 +573,7 @@ public:
const char *func_name() const { return "locate"; }
longlong val_int();
void fix_length_and_dec() { maybe_null=0; max_length=11; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -531,6 +603,7 @@ public:
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -542,6 +615,7 @@ public:
longlong val_int();
const char *func_name() const { return "ascii"; }
void fix_length_and_dec() { max_length=3; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_ord :public Item_int_func
@@ -551,7 +625,7 @@ public:
Item_func_ord(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "ord"; }
- void fix_length_and_dec() { max_length=21; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_find_in_set :public Item_int_func
@@ -564,6 +638,7 @@ public:
longlong val_int();
const char *func_name() const { return "find_in_set"; }
void fix_length_and_dec();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -573,7 +648,7 @@ public:
Item_func_bit_or(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return "|"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ void fix_length_and_dec() { unsigned_flag=1; }
};
class Item_func_bit_and :public Item_int_func
@@ -582,7 +657,7 @@ public:
Item_func_bit_and(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return "&"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ void fix_length_and_dec() { unsigned_flag=1; }
};
class Item_func_bit_count :public Item_int_func
@@ -591,7 +666,7 @@ public:
Item_func_bit_count(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "bit_count"; }
- void fix_length_and_dec() { decimals=0; max_length=2; }
+ void fix_length_and_dec() { max_length=2; }
};
class Item_func_shift_left :public Item_int_func
@@ -600,7 +675,7 @@ public:
Item_func_shift_left(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return "<<"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ void fix_length_and_dec() { unsigned_flag=1; }
};
class Item_func_shift_right :public Item_int_func
@@ -609,7 +684,6 @@ public:
Item_func_shift_right(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return ">>"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
};
class Item_func_bit_neg :public Item_int_func
@@ -618,7 +692,7 @@ public:
Item_func_bit_neg(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "~"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ void fix_length_and_dec() { unsigned_flag=1; }
};
class Item_func_set_last_insert_id :public Item_int_func
@@ -627,7 +701,7 @@ public:
Item_func_set_last_insert_id(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "last_insert_id"; }
- void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length; }
+ void fix_length_and_dec() { max_length=args[0]->max_length; }
};
class Item_func_benchmark :public Item_int_func
@@ -639,7 +713,8 @@ class Item_func_benchmark :public Item_int_func
{}
longlong val_int();
const char *func_name() const { return "benchmark"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
+ void fix_length_and_dec() { max_length=1; maybe_null=0; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -664,6 +739,7 @@ public:
return res;
}
Item_result result_type () const { return udf.result_type(); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -771,7 +847,8 @@ class Item_func_get_lock :public Item_int_func
Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return "get_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_release_lock :public Item_int_func
@@ -781,7 +858,8 @@ class Item_func_release_lock :public Item_int_func
Item_func_release_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "release_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
/* replication functions */
@@ -793,7 +871,8 @@ class Item_master_pos_wait :public Item_int_func
Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return "master_pos_wait"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -819,6 +898,7 @@ public:
void fix_length_and_dec();
void print(String *str);
const char *func_name() const { return "set_user_var"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -843,6 +923,7 @@ public:
table_map used_tables() const
{ return const_var_flag ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -863,35 +944,91 @@ class Item_func_match :public Item_real_func
{
public:
List<Item> fields;
+ String value;
TABLE *table;
- uint key;
- bool join_key;
Item_func_match *master;
- FT_DOCLIST *ft_handler;
+ FT_INFO * ft_handler;
+ Item *concat;
+ byte *record;
+ uint key, mode;
+ bool join_key;
Item_func_match(List<Item> &a, Item *b): Item_real_func(b),
- fields(a), table(0), join_key(0), master(0), ft_handler(0) {}
+ fields(a), table(0), master(0), ft_handler(0),
+ concat(0), key(0), join_key(0)
+ {}
~Item_func_match()
{
- if (!master)
+ if (!master && ft_handler)
{
- if (ft_handler)
- {
- ft_close_search(ft_handler);
- if(join_key)
- table->file->ft_handler=0;
- table->fulltext_searched=0;
- }
+ ft_handler->please->close_search(ft_handler);
+ ft_handler=0;
+ if(join_key)
+ table->file->ft_handler=0;
+ table->fulltext_searched=0;
}
+ if (concat)
+ delete concat;
}
- const char *func_name() const { return "match"; }
enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {}
bool fix_fields(THD *thd,struct st_table_list *tlist);
bool eq(const Item *, bool binary_cmp) const;
- double val();
longlong val_int() { return val()!=0.0; }
+ double val();
bool fix_index();
void init_search(bool no_order);
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_func_match_nl :public Item_func_match
+{
+public:
+ Item_func_match_nl(List<Item> &a, Item *b)
+ :Item_func_match(a,b)
+ { mode=FT_NL; }
+ const char *func_name() const { return "match_nl"; }
+};
+
+
+class Item_func_match_bool :public Item_func_match
+{
+public:
+ Item_func_match_bool(List<Item> &a, Item *b)
+ :Item_func_match(a,b)
+ { mode=FT_BOOL; }
+ const char *func_name() const { return "match_bool"; }
+};
+
+/* For type casts */
+
+enum Item_cast
+{
+ ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
+ ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME
+};
+
+Item *create_func_cast(Item *a, Item_cast cast_type);
+
+
+class Item_func_bit_xor : public Item_int_func
+{
+public:
+ Item_func_bit_xor(Item *a,Item *b) :Item_int_func(a,b) {}
+ longlong val_int();
+ const char *func_name() const { return "^"; }
+ void fix_length_xor_dec() { unsigned_flag=1; }
+};
+
+class Item_func_is_free_lock :public Item_int_func
+{
+ String value;
+public:
+ Item_func_is_free_lock(Item *a) :Item_int_func(a) {}
+ longlong val_int();
+ const char *func_name() const { return "check_lock"; }
+ void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 54fc427edf0..f074629e376 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -17,7 +17,7 @@
/* This file defines all string functions
** Warning: Some string functions doesn't always put and end-null on a String
-** (This shouldn't be neaded)
+** (This shouldn't be needed)
*/
#ifdef __GNUC__
@@ -30,8 +30,12 @@
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
-
+#ifdef HAVE_OPENSSL
+#include <openssl/des.h>
+#endif /* HAVE_OPENSSL */
#include "md5.h"
+#include "sha1.h"
+#include "my_aes.h"
String empty_string("");
@@ -40,7 +44,7 @@ uint nr_of_decimals(const char *str)
if ((str=strchr(str,'.')))
{
const char *start= ++str;
- for ( ; isdigit(*str) ; str++) ;
+ for (; isdigit(*str) ; str++) ;
return (uint) (str-start);
}
return 0;
@@ -66,14 +70,18 @@ String *Item_func_md5::val_str(String *str)
String * sptr= args[0]->val_str(str);
if (sptr)
{
- MD5_CTX context;
+ my_MD5_CTX context;
unsigned char digest[16];
null_value=0;
- MD5Init (&context);
- MD5Update (&context,(unsigned char *) sptr->ptr(), sptr->length());
- MD5Final (digest, &context);
- str->alloc(32); // Ensure that memory is free
+ my_MD5Init (&context);
+ my_MD5Update (&context,(unsigned char *) sptr->ptr(), sptr->length());
+ my_MD5Final (digest, &context);
+ if (str->alloc(32)) // Ensure that memory is free
+ {
+ null_value=1;
+ return 0;
+ }
sprintf((char *) str->ptr(),
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[0], digest[1], digest[2], digest[3],
@@ -93,10 +101,117 @@ void Item_func_md5::fix_length_and_dec()
max_length=32;
}
+
+String *Item_func_sha::val_str(String *str)
+{
+ String * sptr= args[0]->val_str(str);
+ if (sptr) /* If we got value different from NULL */
+ {
+ SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
+ /* Temporary buffer to store 160bit digest */
+ uint8 digest[SHA1_HASH_SIZE];
+ sha1_reset(&context); /* We do not have to check for error here */
+ /* No need to check error as the only case would be too long message */
+ sha1_input(&context,(const unsigned char *) sptr->ptr(), sptr->length());
+ /* Ensure that memory is free and we got result */
+ if ( !( str->alloc(SHA1_HASH_SIZE*2) || (sha1_result(&context,digest)) ) )
+ {
+ sprintf((char *) str->ptr(),
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
+%02x%02x%02x%02x%02x%02x%02x%02x",
+ digest[0], digest[1], digest[2], digest[3],
+ digest[4], digest[5], digest[6], digest[7],
+ digest[8], digest[9], digest[10], digest[11],
+ digest[12], digest[13], digest[14], digest[15],
+ digest[16], digest[17], digest[18], digest[19]);
+
+ str->length((uint) SHA1_HASH_SIZE*2);
+ null_value=0;
+ return str;
+ }
+ }
+ null_value=1;
+ return 0;
+}
+
+void Item_func_sha::fix_length_and_dec()
+{
+ max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
+}
+
+
+/* Implementation of AES encryption routines */
+
+String *Item_func_aes_encrypt::val_str(String *str)
+{
+ String * sptr = args[0]->val_str(str); // String to encrypt
+ String tmp_value; // required to handle second parameter
+ String * key= args[1]->val_str(&tmp_value); // key
+ int aes_length;
+ if (sptr && key) // we need both arguments to be not NULL
+ {
+ null_value=0;
+ aes_length=my_aes_get_size(sptr->length()); // calculate result length
+
+ if (!str->alloc(aes_length)) // Ensure that memory is free
+ {
+ // finally encrypt directly to allocated buffer.
+ if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str->ptr(),
+ key->ptr(), key->length()) == aes_length)
+ {
+ // We got the expected result length
+ str->length((uint) aes_length);
+ return str;
+ }
+ }
+ }
+ null_value=1;
+ return 0;
+}
+
+
+void Item_func_aes_encrypt::fix_length_and_dec()
+{
+ max_length=my_aes_get_size(args[0]->max_length);
+}
+
+
+String *Item_func_aes_decrypt::val_str(String *str)
+{
+ String * sptr= args[0]->val_str(str); // String to decrypt
+ String tmp_value; // temporary string required for parsing
+ String * key= args[1]->val_str(&tmp_value); // key
+ int length; // original length after decrypt
+ if (sptr && key) // Need to have both arguments not NULL
+ {
+ null_value=0;
+ if (!str->alloc(sptr->length())) // Ensure that memory is free
+ {
+ // finally decrypt directly to allocated buffer.
+ length=my_aes_decrypt(sptr->ptr(), sptr->length(), (char*) str->ptr(),
+ key->ptr(), key->length());
+ if (length >= 0) // if we got correct data data
+ {
+ str->length((uint) length);
+ return str;
+ }
+ }
+ }
+ // Bad parameters. No memory or bad data will all go here
+ null_value=1;
+ return 0;
+}
+
+void Item_func_aes_decrypt::fix_length_and_dec()
+{
+ max_length=args[0]->max_length;
+}
+
+
/*
-** Concatinate args with the following premissess
-** If only one arg which is ok, return value of arg
-** Don't reallocate val_str() if not absolute necessary.
+ Concatenate args with the following premises:
+ If only one arg (which is ok), return value of arg
+ Don't reallocate val_str() if not absolute necessary.
*/
String *Item_func_concat::val_str(String *str)
@@ -121,7 +236,8 @@ String *Item_func_concat::val_str(String *str)
goto null;
if (res2->length() == 0)
continue;
- if (res->length()+res2->length() > max_allowed_packet)
+ if (res->length()+res2->length() >
+ current_thd->variables.max_allowed_packet)
goto null; // Error check
if (res->alloced_length() >= res->length()+res2->length())
{ // Use old buffer
@@ -199,11 +315,166 @@ void Item_func_concat::fix_length_and_dec()
}
}
+/*
+ Function des_encrypt() by tonu@spam.ee & monty
+ Works only if compiled with OpenSSL library support.
+ This returns a binary string where first character is CHAR(128 | key-number).
+ If one uses a string key key_number is 127.
+ Encryption result is longer than original by formula:
+ new_length= org_length + (8-(org_length % 8))+1
+*/
+
+String *Item_func_des_encrypt::val_str(String *str)
+{
+#ifdef HAVE_OPENSSL
+ des_cblock ivec;
+ struct st_des_keyblock keyblock;
+ struct st_des_keyschedule keyschedule;
+ const char *append_str="********";
+ uint key_number, res_length, tail;
+ String *res= args[0]->val_str(str);
+
+ if ((null_value=args[0]->null_value))
+ return 0;
+ if ((res_length=res->length()) == 0)
+ return &empty_string;
+
+ if (arg_count == 1)
+ {
+ /* Protect against someone doing FLUSH DES_KEY_FILE */
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ keyschedule= des_keyschedule[key_number=des_default_key];
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ }
+ else if (args[1]->result_type() == INT_RESULT)
+ {
+ key_number= (uint) args[1]->val_int();
+ if (key_number > 9)
+ goto error;
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ keyschedule= des_keyschedule[key_number];
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ }
+ else
+ {
+ String *keystr=args[1]->val_str(&tmp_value);
+ if (!keystr)
+ goto error;
+ key_number=127; // User key string
+
+ /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
+ bzero((char*) &ivec,sizeof(ivec));
+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
+ (uchar*) keystr->ptr(), (int) keystr->length(),
+ 1, (uchar*) &keyblock,ivec);
+ des_set_key_unchecked(&keyblock.key1,keyschedule.ks1);
+ des_set_key_unchecked(&keyblock.key2,keyschedule.ks2);
+ des_set_key_unchecked(&keyblock.key3,keyschedule.ks3);
+ }
+
+ /*
+ The problem: DES algorithm requires original data to be in 8-bytes
+ chunks. Missing bytes get filled with '*'s and result of encryption
+ can be up to 8 bytes longer than original string. When decrypted,
+ we do not know the size of original string :(
+ We add one byte with value 0x1..0x8 as the last byte of the padded
+ string marking change of string length.
+ */
+
+ tail= (8-(res_length) % 8); // 1..8 marking extra length
+ res_length+=tail;
+ if (tail && res->append(append_str, tail) || tmp_value.alloc(res_length+1))
+ goto error;
+ (*res)[res_length-1]=tail; // save extra length
+ tmp_value.length(res_length+1);
+ tmp_value[0]=(char) (128 | key_number);
+ // Real encryption
+ bzero((char*) &ivec,sizeof(ivec));
+ des_ede3_cbc_encrypt((const uchar*) (res->ptr()),
+ (uchar*) (tmp_value.ptr()+1),
+ res_length,
+ keyschedule.ks1,
+ keyschedule.ks2,
+ keyschedule.ks3,
+ &ivec, TRUE);
+ return &tmp_value;
+
+error:
+#endif /* HAVE_OPENSSL */
+ null_value=1;
+ return 0;
+}
+
+
+String *Item_func_des_decrypt::val_str(String *str)
+{
+#ifdef HAVE_OPENSSL
+ des_key_schedule ks1, ks2, ks3;
+ des_cblock ivec;
+ struct st_des_keyblock keyblock;
+ struct st_des_keyschedule keyschedule;
+ String *res= args[0]->val_str(str);
+ uint length=res->length(),tail;
+
+ if ((null_value=args[0]->null_value))
+ return 0;
+ length=res->length();
+ if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128))
+ return res; // Skip decryption if not encrypted
+
+ if (arg_count == 1) // If automatic uncompression
+ {
+ uint key_number=(uint) (*res)[0] & 127;
+ // Check if automatic key and that we have privilege to uncompress using it
+ if (!(current_thd->master_access & SUPER_ACL) || key_number > 9)
+ goto error;
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ keyschedule= des_keyschedule[key_number];
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ }
+ else
+ {
+ // We make good 24-byte (168 bit) key from given plaintext key with MD5
+ String *keystr=args[1]->val_str(&tmp_value);
+ if (!keystr)
+ goto error;
+
+ bzero((char*) &ivec,sizeof(ivec));
+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
+ (uchar*) keystr->ptr(),(int) keystr->length(),
+ 1,(uchar*) &keyblock,ivec);
+ // Here we set all 64-bit keys (56 effective) one by one
+ des_set_key_unchecked(&keyblock.key1,keyschedule.ks1);
+ des_set_key_unchecked(&keyblock.key2,keyschedule.ks2);
+ des_set_key_unchecked(&keyblock.key3,keyschedule.ks3);
+ }
+ if (tmp_value.alloc(length-1))
+ goto error;
+
+ bzero((char*) &ivec,sizeof(ivec));
+ des_ede3_cbc_encrypt((const uchar*) res->ptr()+1,
+ (uchar*) (tmp_value.ptr()),
+ length-1,
+ keyschedule.ks1,
+ keyschedule.ks2,
+ keyschedule.ks3,
+ &ivec, FALSE);
+ /* Restore old length of key */
+ if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
+ goto error; // Wrong key
+ tmp_value.length(length-1-tail);
+ return &tmp_value;
+
+error:
+#endif /* HAVE_OPENSSL */
+ null_value=1;
+ return 0;
+}
/*
-** concat with separator. First arg is the separator
-** concat_ws takes at least two arguments.
+ concat with separator. First arg is the separator
+ concat_ws takes at least two arguments.
*/
String *Item_func_concat_ws::val_str(String *str)
@@ -232,10 +503,10 @@ String *Item_func_concat_ws::val_str(String *str)
for (i++; i < arg_count ; i++)
{
if (!(res2= args[i]->val_str(use_as_buff)) || !res2->length())
- continue; // Skipp NULL and empty string
+ continue; // Skip NULL and empty string
if (res->length() + sep_str->length() + res2->length() >
- max_allowed_packet)
+ current_thd->variables.max_allowed_packet)
goto null; // Error check
if (res->alloced_length() >=
res->length() + sep_str->length() + res2->length())
@@ -385,7 +656,7 @@ void Item_func_reverse::fix_length_and_dec()
/*
** Replace all occurences of string2 in string1 with string3.
-** Don't reallocate val_str() if not neaded
+** Don't reallocate val_str() if not needed
*/
/* TODO: Fix that this works with binary strings when using USE_MB */
@@ -444,7 +715,8 @@ redo:
while (j != search_end)
if (*i++ != *j++) goto skipp;
offset= (int) (ptr-res->ptr());
- if (res->length()-from_length + to_length > max_allowed_packet)
+ if (res->length()-from_length + to_length >
+ current_thd->variables.max_allowed_packet)
goto null;
if (!alloced)
{
@@ -464,7 +736,8 @@ skipp:
#endif /* USE_MB */
do
{
- if (res->length()-from_length + to_length > max_allowed_packet)
+ if (res->length()-from_length + to_length >
+ current_thd->variables.max_allowed_packet)
goto null;
if (!alloced)
{
@@ -521,10 +794,11 @@ String *Item_func_insert::val_str(String *str)
}
#endif
if (start > res->length()+1)
- return res; // Wrong param; skipp insert
+ return res; // Wrong param; skip insert
if (length > res->length()-start)
length=res->length()-start;
- if (res->length() - length + res2->length() > max_allowed_packet)
+ if (res->length() - length + res2->length() >
+ current_thd->variables.max_allowed_packet)
goto null; // OOM check
res=copy_if_not_alloced(str,res,res->length());
res->replace(start,length,*res2);
@@ -1098,7 +1372,7 @@ void Item_func_soundex::fix_length_and_dec()
/*
If alpha, map input letter to soundex code.
- If not alpha and remove_garbage is set then skipp to next char
+ If not alpha and remove_garbage is set then skip to next char
else return 0
*/
@@ -1125,12 +1399,12 @@ String *Item_func_soundex::val_str(String *str)
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
- if (str_value.alloc(max(res->length(),4)))
+ if (tmp_value.alloc(max(res->length(),4)))
return str; /* purecov: inspected */
- char *to= (char *) str_value.ptr();
+ char *to= (char *) tmp_value.ptr();
char *from= (char *) res->ptr(), *end=from+res->length();
- while (from != end && isspace(*from)) // Skipp pre-space
+ while (from != end && isspace(*from)) // Skip pre-space
from++; /* purecov: inspected */
if (from == end)
return &empty_string; // No alpha characters.
@@ -1151,11 +1425,11 @@ String *Item_func_soundex::val_str(String *str)
last_ch = ch; // save code of last input letter
} // for next double-letter check
}
- for (end=(char*) str_value.ptr()+4 ; to < end ; to++)
+ for (end=(char*) tmp_value.ptr()+4 ; to < end ; to++)
*to = '0';
*to=0; // end string
- str_value.length((uint) (to-str_value.ptr()));
- return &str_value;
+ tmp_value.length((uint) (to-tmp_value.ptr()));
+ return &tmp_value;
}
@@ -1305,7 +1579,7 @@ String *Item_func_make_set::val_str(String *str)
if (bits & 1)
{
String *res= (*ptr)->val_str(str);
- if (res) // Skipp nulls
+ if (res) // Skip nulls
{
if (!first_found)
{ // First argument
@@ -1429,7 +1703,8 @@ String *Item_func_repeat::val_str(String *str)
if (count == 1) // To avoid reallocs
return res;
length=res->length();
- if (length > max_allowed_packet/count)// Safe length check
+ // Safe length check
+ if (length > current_thd->variables.max_allowed_packet/count)
goto err; // Probably an error
tot_length= length*(uint) count;
if (!(res= alloc_buffer(res,str,&tmp_value,tot_length)))
@@ -1487,7 +1762,8 @@ String *Item_func_rpad::val_str(String *str)
return (res);
}
length_pad= rpad->length();
- if ((ulong) count > max_allowed_packet || args[2]->null_value || !length_pad)
+ if ((ulong) count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !length_pad)
goto err;
if (!(res= alloc_buffer(res,str,&tmp_value,count)))
goto err;
@@ -1546,7 +1822,8 @@ String *Item_func_lpad::val_str(String *str)
return (res);
}
length_pad= lpad->length();
- if (count > max_allowed_packet || args[2]->null_value || !length_pad)
+ if (count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !length_pad)
goto err;
if (res->alloced_length() < count)
@@ -1610,6 +1887,45 @@ String *Item_func_conv::val_str(String *str)
return str;
}
+
+String *Item_func_hex::val_str(String *str)
+{
+ if (args[0]->result_type() != STRING_RESULT)
+ {
+ /* Return hex of unsigned longlong value */
+ longlong dec= args[0]->val_int();
+ char ans[65],*ptr;
+ if ((null_value= args[0]->null_value))
+ return 0;
+ ptr= longlong2str(dec,ans,16);
+ if (str->copy(ans,(uint32) (ptr-ans)))
+ return &empty_string; // End of memory
+ return str;
+ }
+
+ /* Convert given string to a hex string, character by character */
+ String *res= args[0]->val_str(str);
+ const char *from, *end;
+ char *to;
+ if (!res || tmp_value.alloc(res->length()*2))
+ {
+ null_value=1;
+ return 0;
+ }
+ null_value=0;
+ tmp_value.length(res->length()*2);
+ for (from=res->ptr(), end=from+res->length(), to= (char*) tmp_value.ptr();
+ from != end ;
+ from++, to+=2)
+ {
+ uint tmp=(uint) (uchar) *from;
+ to[0]=_dig_vec[tmp >> 4];
+ to[1]=_dig_vec[tmp & 15];
+ }
+ return &tmp_value;
+}
+
+
#include <my_dir.h> // For my_stat
String *Item_load_file::val_str(String *str)
@@ -1628,7 +1944,7 @@ String *Item_load_file::val_str(String *str)
/* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */
goto err;
}
- if (stat_info.st_size > (long) max_allowed_packet)
+ if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet)
{
/* my_error(ER_TOO_LONG_STRING, MYF(0), file_name->c_ptr()); */
goto err;
@@ -1702,7 +2018,7 @@ String* Item_func_export_set::val_str(String* str)
str->append(*yes);
else
str->append(*no);
- if(i != num_set_values - 1)
+ if (i != num_set_values - 1)
str->append(*sep);
}
return str;
@@ -1720,24 +2036,23 @@ String* Item_func_inet_ntoa::val_str(String* str)
uchar buf[8], *p;
ulonglong n = (ulonglong) args[0]->val_int();
char num[4];
+
/*
- we do not know if args[0] is NULL until we have called
+ We do not know if args[0] is NULL until we have called
some val function on it if args[0] is not a constant!
+
+ Also return null if n > 255.255.255.255
*/
- if ((null_value=args[0]->null_value))
+ if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295))))
return 0; // Null value
str->length(0);
- int8store(buf,n);
+ int4store(buf,n);
- /*
- Now we can assume little endian.
- We handle the possibility of an 8-byte IP address however, we do
- not want to confuse those who are just using 4 byte ones
- */
- for (p= buf + 8; p > buf+4 && p[-1] == 0 ; p-- ) ;
+ /* Now we can assume little endian. */
+
num[3]='.';
- while (p-- > buf)
+ for (p=buf+4 ; p-- > buf ; )
{
uint c = *p;
uint n1,n2; // Try to avoid divisions
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 1b829b19439..482bf499757 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -35,6 +35,12 @@ public:
double val();
enum Item_result result_type () const { return STRING_RESULT; }
void left_right_max_length();
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary);
+ }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_md5 :public Item_str_func
@@ -45,8 +51,37 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "md5"; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_func_sha :public Item_str_func
+{
+public:
+ Item_func_sha(Item *a) :Item_str_func(a) {}
+ String *val_str(String *);
+ void fix_length_and_dec();
+ const char *func_name() const { return "sha"; }
+};
+
+class Item_func_aes_encrypt :public Item_str_func
+{
+public:
+ Item_func_aes_encrypt(Item *a, Item *b) :Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec();
+ const char *func_name() const { return "aes_encrypt"; }
};
+class Item_func_aes_decrypt :public Item_str_func
+{
+public:
+ Item_func_aes_decrypt(Item *a, Item *b) :Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec();
+ const char *func_name() const { return "aes_decrypt"; }
+};
+
+
class Item_func_concat :public Item_str_func
{
String tmp_value;
@@ -56,6 +91,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "concat"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_concat_ws :public Item_str_func
@@ -76,6 +112,7 @@ public:
|| Item_func::fix_fields(thd,tlist));
}
const char *func_name() const { return "concat_ws"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_reverse :public Item_str_func
@@ -96,6 +133,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "replace"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -108,6 +146,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "insert"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -154,6 +193,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "right"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -166,6 +206,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substr"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -177,6 +218,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "substr_index"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -188,6 +230,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "ltrim"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -199,6 +242,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "rtrim"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_trim :public Item_str_func
@@ -209,6 +253,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "trim"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -220,6 +265,32 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length = 16; }
const char *func_name() const { return "password"; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_func_des_encrypt :public Item_str_func
+{
+ String tmp_value;
+public:
+ Item_func_des_encrypt(Item *a) :Item_str_func(a) {}
+ Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec()
+ { maybe_null=1; max_length = args[0]->max_length+8; }
+ const char *func_name() const { return "des_encrypt"; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_func_des_decrypt :public Item_str_func
+{
+ String tmp_value;
+public:
+ Item_func_des_decrypt(Item *a) :Item_str_func(a) {}
+ Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; }
+ const char *func_name() const { return "des_decrypt"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_encrypt :public Item_str_func
@@ -230,6 +301,7 @@ public:
Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length = 13; }
+ unsigned int size_of() { return sizeof(*this);}
};
#include "sql_crypt.h"
@@ -243,6 +315,7 @@ public:
Item_str_func(a),sql_crypt(seed) {}
String *val_str(String *);
void fix_length_and_dec();
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_decode :public Item_func_encode
@@ -274,11 +347,13 @@ public:
class Item_func_soundex :public Item_str_func
{
+ String tmp_value;
public:
Item_func_soundex(Item *a) :Item_str_func(a) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "soundex"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -299,6 +374,7 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "elt"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -318,6 +394,7 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "make_set"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -332,6 +409,7 @@ public:
max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3;
}
const char *func_name() const { return "format"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -353,6 +431,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "repeat"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -365,6 +444,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "rpad"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -377,6 +457,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "lpad"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -389,12 +470,26 @@ public:
void fix_length_and_dec() { decimals=0; max_length=64; }
};
+
+class Item_func_hex :public Item_str_func
+{
+ String tmp_value;
+public:
+ Item_func_hex(Item *a) :Item_str_func(a) {}
+ const char *func_name() const { return "hex"; }
+ String *val_str(String *);
+ void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length*2; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
class Item_func_binary :public Item_str_func
{
public:
Item_func_binary(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "binary"; }
- String *val_str(String *a) { return (args[0]->val_str(a)); }
+ String *val_str(String *a)
+ { a=args[0]->val_str(a); null_value=args[0]->null_value; return a; }
void fix_length_and_dec() { binary=1; max_length=args[0]->max_length; }
void print(String *str) { print_op(str); }
};
@@ -409,6 +504,7 @@ public:
const char *func_name() const { return "load_file"; }
void fix_length_and_dec()
{ binary=1; maybe_null=1; max_length=MAX_BLOB_WIDTH;}
+ unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 5b24a1eda90..bdf48b3ac54 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,7 +30,7 @@ Item_sum::Item_sum(List<Item> &list)
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{
uint i=0;
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
@@ -52,6 +52,8 @@ void Item_sum::make_field(Send_field *tmp_field)
tmp_field->flags=0;
if (!maybe_null)
tmp_field->flags|= NOT_NULL_FLAG;
+ if (unsigned_flag)
+ tmp_field->flags |= UNSIGNED_FLAG;
tmp_field->length=max_length;
tmp_field->decimals=decimals;
tmp_field->type=(result_type() == INT_RESULT ? FIELD_TYPE_LONG :
@@ -150,7 +152,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
return 1;
hybrid_type=item->result_type();
if (hybrid_type == INT_RESULT)
- max_length=21;
+ max_length=20;
else if (hybrid_type == REAL_RESULT)
max_length=float_length(decimals);
else
@@ -158,6 +160,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
decimals=item->decimals;
maybe_null=item->maybe_null;
binary=item->binary;
+ unsigned_flag=item->unsigned_flag;
result_field=0;
null_value=1;
fix_length_and_dec();
@@ -323,12 +326,27 @@ double Item_sum_hybrid::val()
{
if (null_value)
return 0.0;
- if (hybrid_type == STRING_RESULT)
- {
+ switch (hybrid_type) {
+ case STRING_RESULT:
String *res; res=val_str(&str_value);
return res ? atof(res->c_ptr()) : 0.0;
+ case INT_RESULT:
+ if (unsigned_flag)
+ return ulonglong2double(sum_int);
+ return (double) sum_int;
+ case REAL_RESULT:
+ return sum;
}
- return sum;
+ return 0; // Keep compiler happy
+}
+
+longlong Item_sum_hybrid::val_int()
+{
+ if (null_value)
+ return 0;
+ if (hybrid_type == INT_RESULT)
+ return sum_int;
+ return (longlong) Item_sum_hybrid::val();
}
@@ -337,25 +355,26 @@ Item_sum_hybrid::val_str(String *str)
{
if (null_value)
return 0;
- if (hybrid_type == STRING_RESULT)
+ switch (hybrid_type) {
+ case STRING_RESULT:
return &value;
- str->set(sum,decimals);
- return str;
+ case REAL_RESULT:
+ str->set(sum,decimals);
+ break;
+ case INT_RESULT:
+ if (unsigned_flag)
+ str->set((ulonglong) sum_int);
+ else
+ str->set((longlong) sum_int);
+ break;
+ }
+ return str; // Keep compiler happy
}
-
bool Item_sum_min::add()
{
- if (hybrid_type != STRING_RESULT)
- {
- double nr=args[0]->val();
- if (!args[0]->null_value && (null_value || nr < sum))
- {
- sum=nr;
- null_value=0;
- }
- }
- else
+ switch (hybrid_type) {
+ case STRING_RESULT:
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
@@ -366,22 +385,39 @@ bool Item_sum_min::add()
null_value=0;
}
}
- return 0;
-}
-
-
-bool Item_sum_max::add()
-{
- if (hybrid_type != STRING_RESULT)
+ break;
+ case INT_RESULT:
+ {
+ longlong nr=args[0]->val_int();
+ if (!args[0]->null_value && (null_value ||
+ (unsigned_flag &&
+ (ulonglong) nr < (ulonglong) sum_int) ||
+ (!unsigned_flag && nr < sum_int)))
+ {
+ sum_int=nr;
+ null_value=0;
+ }
+ }
+ break;
+ case REAL_RESULT:
{
double nr=args[0]->val();
- if (!args[0]->null_value && (null_value || nr > sum))
+ if (!args[0]->null_value && (null_value || nr < sum))
{
sum=nr;
null_value=0;
}
}
- else
+ break;
+ }
+ return 0;
+}
+
+
+bool Item_sum_max::add()
+{
+ switch (hybrid_type) {
+ case STRING_RESULT:
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
@@ -392,6 +428,31 @@ bool Item_sum_max::add()
null_value=0;
}
}
+ break;
+ case INT_RESULT:
+ {
+ longlong nr=args[0]->val_int();
+ if (!args[0]->null_value && (null_value ||
+ (unsigned_flag &&
+ (ulonglong) nr > (ulonglong) sum_int) ||
+ (!unsigned_flag && nr > sum_int)))
+ {
+ sum_int=nr;
+ null_value=0;
+ }
+ }
+ break;
+ case REAL_RESULT:
+ {
+ double nr=args[0]->val();
+ if (!args[0]->null_value && (null_value || nr > sum))
+ {
+ sum=nr;
+ null_value=0;
+ }
+ }
+ break;
+ }
return 0;
}
@@ -676,9 +737,17 @@ Item_sum_hybrid::min_max_update_int_field(int offset)
nr=args[0]->val_int();
if (!args[0]->null_value)
{
- if (result_field->is_null(offset) ||
- (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
+ if (result_field->is_null(offset))
old_nr=nr;
+ else
+ {
+ bool res=(unsigned_flag ?
+ (ulonglong) old_nr > (ulonglong) nr :
+ old_nr > nr);
+ /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
+ if ((cmp_sign > 0) ^ (!res))
+ old_nr=nr;
+ }
result_field->set_notnull();
}
else if (result_field->is_null(offset))
@@ -788,11 +857,74 @@ String *Item_std_field::val_str(String *str)
#include "sql_select.h"
+static int simple_raw_key_cmp(void* arg, byte* key1, byte* key2)
+{
+ return memcmp(key1, key2, *(uint*) arg);
+}
+
+static int simple_str_key_cmp(void* arg, byte* key1, byte* key2)
+{
+ return my_sortcmp((char*) key1, (char*) key2, *(uint*) arg);
+}
+
+/*
+ Did not make this one static - at least gcc gets confused when
+ I try to declare a static function as a friend. If you can figure
+ out the syntax to make a static function a friend, make this one
+ static
+*/
+
+int composite_key_cmp(void* arg, byte* key1, byte* key2)
+{
+ Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
+ Field **field = item->table->field;
+ Field **field_end= field + item->table->fields;
+ uint32 *lengths=item->field_lengths;
+ for (; field < field_end; ++field)
+ {
+ Field* f = *field;
+ int len = *lengths++;
+ int res = f->key_cmp(key1, key2);
+ if (res)
+ return res;
+ key1 += len;
+ key2 += len;
+ }
+ return 0;
+}
+
+/*
+ helper function for walking the tree when we dump it to MyISAM -
+ tree_walk will call it for each leaf
+*/
+
+int dump_leaf(byte* key, uint32 count __attribute__((unused)),
+ Item_sum_count_distinct* item)
+{
+ byte* buf = item->table->record[0];
+ int error;
+ /*
+ The first item->rec_offset bytes are taken care of with
+ restore_record(table,2) in setup()
+ */
+ memcpy(buf + item->rec_offset, key, item->tree.size_of_element);
+ if ((error = item->table->file->write_row(buf)))
+ {
+ if (error != HA_ERR_FOUND_DUPP_KEY &&
+ error != HA_ERR_FOUND_DUPP_UNIQUE)
+ return 1;
+ }
+ return 0;
+}
+
+
Item_sum_count_distinct::~Item_sum_count_distinct()
{
if (table)
free_tmp_table(current_thd, table);
delete tmp_table_param;
+ if (use_tree)
+ delete_tree(&tree);
}
@@ -829,22 +961,126 @@ bool Item_sum_count_distinct::setup(THD *thd)
tmp_table_param->cleanup();
}
if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
- 0, 0, current_lex->options | thd->options)))
+ 0, 0,
+ current_lex->select->options | thd->options)))
return 1;
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
+ table->no_rows=1;
+
+
+ // no blobs, otherwise it would be MyISAM
+ if (table->db_type == DB_TYPE_HEAP)
+ {
+ qsort_cmp2 compare_key;
+ void* cmp_arg;
+
+ // to make things easier for dump_leaf if we ever have to dump to MyISAM
+ restore_record(table,2);
+
+ if (table->fields == 1)
+ {
+ /*
+ If we have only one field, which is the most common use of
+ count(distinct), it is much faster to use a simpler key
+ compare method that can take advantage of not having to worry
+ about other fields
+ */
+ Field* field = table->field[0];
+ switch(field->type())
+ {
+ /*
+ If we have a string, we must take care of charsets and case
+ sensitivity
+ */
+ case FIELD_TYPE_STRING:
+ case FIELD_TYPE_VAR_STRING:
+ compare_key = (qsort_cmp2)(field->binary() ? simple_raw_key_cmp:
+ simple_str_key_cmp);
+ break;
+ default:
+ /*
+ Since at this point we cannot have blobs anything else can
+ be compared with memcmp
+ */
+ compare_key = (qsort_cmp2)simple_raw_key_cmp;
+ break;
+ }
+ key_length = field->pack_length();
+ cmp_arg = (void*) &key_length;
+ rec_offset = 1;
+ }
+ else // too bad, cannot cheat - there is more than one field
+ {
+ bool all_binary = 1;
+ Field** field, **field_end;
+ field_end = (field = table->field) + table->fields;
+ uint32 *lengths;
+ if (!(field_lengths=
+ (uint32*) thd->alloc(sizeof(uint32) * table->fields)))
+ return 1;
+
+ for (key_length = 0, lengths=field_lengths; field < field_end; ++field)
+ {
+ uint32 length= (*field)->pack_length();
+ key_length += length;
+ *lengths++ = length;
+ if (!(*field)->binary())
+ all_binary = 0; // Can't break loop here
+ }
+ rec_offset = table->reclength - key_length;
+ if (all_binary)
+ {
+ compare_key = (qsort_cmp2)simple_raw_key_cmp;
+ cmp_arg = (void*) &key_length;
+ }
+ else
+ {
+ compare_key = (qsort_cmp2) composite_key_cmp ;
+ cmp_arg = (void*) this;
+ }
+ }
+
+ init_tree(&tree, min(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ key_length, compare_key, 0, NULL, cmp_arg);
+ use_tree = 1;
+
+ /*
+ The only time key_length could be 0 is if someone does
+ count(distinct) on a char(0) field - stupid thing to do,
+ but this has to be handled - otherwise someone can crash
+ the server with a DoS attack
+ */
+ max_elements_in_tree = ((key_length) ?
+ thd->variables.max_heap_table_size/key_length : 1);
+ }
return 0;
}
+int Item_sum_count_distinct::tree_to_myisam()
+{
+ if (create_myisam_from_heap(table, tmp_table_param,
+ HA_ERR_RECORD_FILE_FULL, 1) ||
+ tree_walk(&tree, (tree_walk_action)&dump_leaf, (void*)this,
+ left_root_right))
+ return 1;
+ delete_tree(&tree);
+ use_tree = 0;
+ return 0;
+}
+
void Item_sum_count_distinct::reset()
{
- if (table)
+ if (use_tree)
+ reset_tree(&tree);
+ else if (table)
{
table->file->extra(HA_EXTRA_NO_CACHE);
table->file->delete_all_rows();
table->file->extra(HA_EXTRA_WRITE_CACHE);
- (void) add();
}
+ (void) add();
}
bool Item_sum_count_distinct::add()
@@ -859,7 +1095,21 @@ bool Item_sum_count_distinct::add()
if ((*field)->is_real_null(0))
return 0; // Don't count NULL
- if ((error=table->file->write_row(table->record[0])))
+ if (use_tree)
+ {
+ /*
+ If the tree got too big, convert to MyISAM, otherwise insert into the
+ tree.
+ */
+ if (tree.elements_in_tree > max_elements_in_tree)
+ {
+ if (tree_to_myisam())
+ return 1;
+ }
+ else if (!tree_insert(&tree, table->record[0] + rec_offset, 0))
+ return 1;
+ }
+ else if ((error=table->file->write_row(table->record[0])))
{
if (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)
@@ -875,6 +1125,8 @@ longlong Item_sum_count_distinct::val_int()
{
if (!table) // Empty query
return LL(0);
+ if (use_tree)
+ return tree.elements_in_tree;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
return table->file->records;
}
@@ -897,7 +1149,7 @@ void Item_udf_sum::reset()
bool Item_udf_sum::add()
{
- DBUG_ENTER("Item_udf_sum::reset");
+ DBUG_ENTER("Item_udf_sum::add");
udf.add(&null_value);
DBUG_RETURN(0);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index f68dfee1b61..2cf92343ebb 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,6 +21,8 @@
#pragma interface /* gcc class implementation */
#endif
+#include <my_tree.h>
+
class Item_sum :public Item_result_field
{
public:
@@ -62,11 +64,13 @@ public:
{ return new Item_field(field);}
table_map used_tables() const { return ~(table_map) 0; } /* Not used */
bool const_item() const { return 0; }
+ bool is_null() { return null_value; }
void update_used_tables() { }
void make_field(Send_field *field);
void print(String *str);
void fix_num_length_and_dec();
virtual bool setup(THD *thd) {return 0;}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -81,6 +85,7 @@ public:
longlong val_int() { return (longlong) val(); } /* Real as default */
String *val_str(String*str);
void reset_field();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -95,6 +100,7 @@ public:
double val() { return (double) val_int(); }
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -112,6 +118,7 @@ class Item_sum_sum :public Item_sum_num
void reset_field();
void update_field(int offset);
const char *func_name() const { return "sum"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -134,6 +141,7 @@ class Item_sum_count :public Item_sum_int
void reset_field();
void update_field(int offset);
const char *func_name() const { return "count"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -144,13 +152,36 @@ class Item_sum_count_distinct :public Item_sum_int
TABLE *table;
table_map used_table_cache;
bool fix_fields(THD *thd,TABLE_LIST *tables);
+ uint32 *field_lengths;
TMP_TABLE_PARAM *tmp_table_param;
- bool always_null;
+ TREE tree;
+ uint key_length;
+
+ // calculated based on max_heap_table_size. If reached,
+ // walk the tree and dump it into MyISAM table
+ uint max_elements_in_tree;
+
+ // the first few bytes of record ( at least one)
+ // are just markers for deleted and NULLs. We want to skip them since
+ // they will just bloat the tree without providing any valuable info
+ int rec_offset;
+
+ // If there are no blobs, we can use a tree, which
+ // is faster than heap table. In that case, we still use the table
+ // to help get things set up, but we insert nothing in it
+ bool use_tree;
+ bool always_null; // Set to 1 if the result is always NULL
+
+ int tree_to_myisam();
+
+ friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
+ friend int dump_leaf(byte* key, uint32 count __attribute__((unused)),
+ Item_sum_count_distinct* item);
public:
Item_sum_count_distinct(List<Item> &list)
:Item_sum_int(list),table(0),used_table_cache(~(table_map) 0),
- tmp_table_param(0),always_null(0)
+ tmp_table_param(0),use_tree(0),always_null(0)
{ quick_group=0; }
~Item_sum_count_distinct();
table_map used_tables() const { return used_table_cache; }
@@ -162,6 +193,7 @@ class Item_sum_count_distinct :public Item_sum_int
void update_field(int offset) { return ; } // Never called
const char *func_name() const { return "count_distinct"; }
bool setup(THD *thd);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -177,9 +209,11 @@ public:
enum Type type() const { return FIELD_AVG_ITEM; }
double val();
longlong val_int() { return (longlong) val(); }
+ bool is_null() { (void) val_int(); return null_value; }
String *val_str(String*);
void make_field(Send_field *field);
void fix_length_and_dec() {}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -201,6 +235,7 @@ class Item_sum_avg :public Item_sum_num
Item *result_item(Field *field)
{ return new Item_avg_field(this); }
const char *func_name() const { return "avg"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_std;
@@ -214,8 +249,10 @@ public:
double val();
longlong val_int() { return (longlong) val(); }
String *val_str(String*);
+ bool is_null() { (void) val_int(); return null_value; }
void make_field(Send_field *field);
void fix_length_and_dec() {}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_std :public Item_sum_num
@@ -236,6 +273,7 @@ class Item_sum_std :public Item_sum_num
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -246,6 +284,7 @@ class Item_sum_hybrid :public Item_sum
protected:
String value,tmp_value;
double sum;
+ longlong sum_int;
Item_result hybrid_type;
int cmp_sign;
table_map used_table_cache;
@@ -261,12 +300,13 @@ class Item_sum_hybrid :public Item_sum
void reset()
{
sum=0.0;
+ sum_int=0;
value.length(0);
null_value=1;
add();
}
double val();
- longlong val_int() { return (longlong) val(); } /* Real as default */
+ longlong val_int();
void reset_field();
String *val_str(String *);
void make_const() { used_table_cache=0; }
@@ -276,6 +316,7 @@ class Item_sum_hybrid :public Item_sum
void min_max_update_str_field(int offset);
void min_max_update_real_field(int offset);
void min_max_update_int_field(int offset);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -287,6 +328,7 @@ public:
bool add();
const char *func_name() const { return "min"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -298,6 +340,7 @@ public:
bool add();
const char *func_name() const { return "max"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -313,6 +356,7 @@ class Item_sum_bit :public Item_sum_int
void reset();
longlong val_int();
void reset_field();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -323,6 +367,7 @@ class Item_sum_or :public Item_sum_bit
bool add();
void update_field(int offset);
const char *func_name() const { return "bit_or"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -333,6 +378,7 @@ class Item_sum_and :public Item_sum_bit
bool add();
void update_field(int offset);
const char *func_name() const { return "bit_and"; }
+ unsigned int size_of() { return sizeof(*this);}
};
/*
@@ -363,6 +409,7 @@ public:
bool add();
void reset_field() {};
void update_field(int offset_arg) {};
+ unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index eb9b1423c78..1e222fddcfc 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -672,7 +672,7 @@ String *Item_func_date_format::val_str(String *str)
else
size=format_length(format);
if (format == str)
- str=&value; // Save result here
+ str= &value; // Save result here
if (str->alloc(size))
{
null_value=1;
@@ -683,7 +683,7 @@ String *Item_func_date_format::val_str(String *str)
/* Create the result string */
const char *ptr=format->ptr();
const char *end=ptr+format->length();
- for ( ; ptr != end ; ptr++)
+ for (; ptr != end ; ptr++)
{
if (*ptr != '%' || ptr+1 == end)
str->append(*ptr);
@@ -691,7 +691,7 @@ String *Item_func_date_format::val_str(String *str)
{
switch (*++ptr) {
case 'M':
- if(!l_time.month)
+ if (!l_time.month)
{
null_value=1;
return 0;
@@ -699,7 +699,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(month_names[l_time.month-1]);
break;
case 'b':
- if(!l_time.month)
+ if (!l_time.month)
{
null_value=1;
return 0;
@@ -707,7 +707,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(month_names[l_time.month-1].ptr(),3);
break;
case 'W':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -716,7 +716,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(day_names[weekday]);
break;
case 'a':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -725,7 +725,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(day_names[weekday].ptr(),3);
break;
case 'D':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -791,7 +791,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(intbuff);
break;
case 'j':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -1123,3 +1123,13 @@ longlong Item_extract::val_int()
}
return 0; // Impossible
}
+
+
+void Item_typecast::print(String *str)
+{
+ str->append("CAST(");
+ args[0]->print(str);
+ str->append(" AS ");
+ str->append(func_name());
+ str->append(')');
+}
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 720f8ba2882..6b0d1850d8c 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -175,6 +175,7 @@ public:
const char *func_name() const { return "weekday"; }
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_dayname :public Item_func_weekday
@@ -200,6 +201,7 @@ public:
{
decimals=0; max_length=10;
}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -229,6 +231,35 @@ public:
const char *func_name() const { return "date"; }
void fix_length_and_dec() { decimals=0; max_length=10; }
bool save_in_field(Field *to);
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATE);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_date(maybe_null, name, t_arg);
+ }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_date_func :public Item_str_func
+{
+public:
+ Item_date_func() :Item_str_func() {}
+ Item_date_func(Item *a) :Item_str_func(a) {}
+ Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {}
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATETIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_datetime(maybe_null, name, t_arg);
+ }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -247,6 +278,16 @@ public:
{ str_value.set(buff,buff_length); return &str_value; }
const char *func_name() const { return "curtime"; }
void fix_length_and_dec();
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_TIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_time(maybe_null, name, t_arg);
+ }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -260,18 +301,19 @@ public:
const char *func_name() const { return "curdate"; }
void fix_length_and_dec(); /* Retrieves curtime */
bool get_date(TIME *res,bool fuzzy_date);
+ unsigned int size_of() { return sizeof(*this);}
};
-class Item_func_now :public Item_func
+class Item_func_now :public Item_date_func
{
longlong value;
char buff[20];
uint buff_length;
TIME ltime;
public:
- Item_func_now() :Item_func() {}
- Item_func_now(Item *a) :Item_func(a) {}
+ Item_func_now() :Item_date_func() {}
+ Item_func_now(Item *a) :Item_date_func(a) {}
enum Item_result result_type () const { return STRING_RESULT; }
double val() { return (double) value; }
longlong val_int() { return value; }
@@ -281,6 +323,7 @@ public:
const char *func_name() const { return "now"; }
void fix_length_and_dec();
bool get_date(TIME *res,bool fuzzy_date);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -305,19 +348,20 @@ public:
const char *func_name() const { return "date_format"; }
void fix_length_and_dec();
uint format_length(const String *format);
+ unsigned int size_of() { return sizeof(*this);}
};
-class Item_func_from_unixtime :public Item_func
+class Item_func_from_unixtime :public Item_date_func
{
public:
- Item_func_from_unixtime(Item *a) :Item_func(a) {}
+ Item_func_from_unixtime(Item *a) :Item_date_func(a) {}
double val() { return (double) Item_func_from_unixtime::val_int(); }
longlong val_int();
String *val_str(String *str);
const char *func_name() const { return "from_unixtime"; }
void fix_length_and_dec() { decimals=0; max_length=19; }
- enum Item_result result_type () const { return STRING_RESULT; }
+// enum Item_result result_type () const { return STRING_RESULT; }
bool get_date(TIME *res,bool fuzzy_date);
};
@@ -331,6 +375,15 @@ public:
String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length=13; }
const char *func_name() const { return "sec_to_time"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_TIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_time(maybe_null, name, t_arg);
+ }
};
enum interval_type { INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY,
@@ -340,7 +393,7 @@ enum interval_type { INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY,
INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
INTERVAL_MINUTE_SECOND};
-class Item_date_add_interval :public Item_str_func
+class Item_date_add_interval :public Item_date_func
{
const interval_type int_type;
String value;
@@ -348,13 +401,14 @@ class Item_date_add_interval :public Item_str_func
public:
Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
- :Item_str_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
+ :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
String *val_str(String *);
const char *func_name() const { return "date_add_interval"; }
void fix_length_and_dec() { maybe_null=1; max_length=19; value.alloc(32);}
double val() { return (double) val_int(); }
longlong val_int();
bool get_date(TIME *res,bool fuzzy_date);
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_extract :public Item_int_func
@@ -368,4 +422,64 @@ class Item_extract :public Item_int_func
longlong val_int();
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_typecast :public Item_str_func
+{
+public:
+ Item_typecast(Item *a) :Item_str_func(a) {}
+ String *val_str(String *a)
+ { a=args[0]->val_str(a); null_value=args[0]->null_value; return a; }
+ void fix_length_and_dec() { max_length=args[0]->max_length; }
+ void print(String *str);
+};
+
+
+class Item_date_typecast :public Item_typecast
+{
+public:
+ Item_date_typecast(Item *a) :Item_typecast(a) {}
+ const char *func_name() const { return "date"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATE);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_date(maybe_null, name, t_arg);
+ }
+};
+
+class Item_time_typecast :public Item_typecast
+{
+public:
+ Item_time_typecast(Item *a) :Item_typecast(a) {}
+ const char *func_name() const { return "time"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_TIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_time(maybe_null, name, t_arg);
+ }
+};
+
+class Item_datetime_typecast :public Item_typecast
+{
+public:
+ Item_datetime_typecast(Item *a) :Item_typecast(a) {}
+ const char *func_name() const { return "datetime"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATETIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ if (!t_arg) return result_field;
+ return new Field_datetime(maybe_null, name, t_arg);
+ }
};
diff --git a/sql/item_uniq.cc b/sql/item_uniq.cc
index 80ed6433fd8..88e0cbbc0e6 100644
--- a/sql/item_uniq.cc
+++ b/sql/item_uniq.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/item_uniq.h b/sql/item_uniq.h
index ff11222e2ee..cc087832f49 100644
--- a/sql/item_uniq.h
+++ b/sql/item_uniq.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -29,6 +29,7 @@ public:
:Item_real_func(list) {}
double val() { return 0.0; }
void fix_length_and_dec() { decimals=0; max_length=6; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_unique_users :public Item_sum_num
@@ -43,4 +44,5 @@ public:
void reset_field() {}
void update_field(int offset) {}
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;}
+ unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/key.cc b/sql/key.cc
index f2488ab74cb..d103c07eb72 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -96,7 +96,7 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length)
length=min(key_length,key_part->length);
set_if_smaller(blob_length,length);
int2store(key,(uint) blob_length);
- key+=2; // Skipp length info
+ key+=2; // Skip length info
memcpy(key,pos,blob_length);
}
else
@@ -250,7 +250,7 @@ void key_unpack(String *to,TABLE *table,uint idx)
bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
{
- List_iterator<Item> f(fields);
+ List_iterator_fast<Item> f(fields);
KEY_PART_INFO *key_part,*key_part_end;
for (key_part=table->key_info[idx].key_part,key_part_end=key_part+
table->key_info[idx].key_parts ;
@@ -258,7 +258,7 @@ bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
key_part++)
{
Item_field *field;
-
+
if (key_part->field == table->timestamp_field)
return 1; // Can't be used for update
diff --git a/sql/lex.h b/sql/lex.h
index a242f751053..b13b68d7858 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -30,9 +30,9 @@
#endif
/*
-** Symbols are broken into separated arrays to allow fieldnames with
-** same name as functions
-** These are kept sorted for human lookup (the symbols are hashed)
+ Symbols are broken into separated arrays to allow field names with
+ same name as functions.
+ These are kept sorted for human lookup (the symbols are hashed).
*/
static SYMBOL symbols[] = {
@@ -61,19 +61,21 @@ static SYMBOL symbols[] = {
{ "AVG", SYM(AVG_SYM),0,0},
{ "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH),0,0},
{ "AUTO_INCREMENT", SYM(AUTO_INC),0,0},
- { "AUTOCOMMIT", SYM(AUTOCOMMIT),0,0},
- { "BACKUP", SYM(BACKUP_SYM),0,0},
- { "BEGIN", SYM(BEGIN_SYM),0,0},
+ { "BACKUP", SYM(BACKUP_SYM),0,0},
+ { "BEGIN", SYM(BEGIN_SYM),0,0},
{ "BERKELEYDB", SYM(BERKELEY_DB_SYM),0,0},
{ "BDB", SYM(BERKELEY_DB_SYM),0,0},
{ "BETWEEN", SYM(BETWEEN_SYM),0,0},
{ "BIGINT", SYM(BIGINT),0,0},
{ "BIT", SYM(BIT_SYM),0,0},
{ "BINARY", SYM(BINARY),0,0},
+ { "BINLOG", SYM(BINLOG_SYM),0,0},
{ "BLOB", SYM(BLOB_SYM),0,0},
{ "BOOL", SYM(BOOL_SYM),0,0},
+ { "BOOLEAN", SYM(BOOLEAN_SYM),0,0},
{ "BOTH", SYM(BOTH),0,0},
{ "BY", SYM(BY),0,0},
+ { "CACHE", SYM(CACHE_SYM),0,0},
{ "CASCADE", SYM(CASCADE),0,0},
{ "CASE", SYM(CASE_SYM),0,0},
{ "CHAR", SYM(CHAR_SYM),0,0},
@@ -82,6 +84,9 @@ static SYMBOL symbols[] = {
{ "CHANGED", SYM(CHANGED),0,0},
{ "CHECK", SYM(CHECK_SYM),0,0},
{ "CHECKSUM", SYM(CHECKSUM_SYM),0,0},
+ { "CIPHER", SYM(CIPHER_SYM),0,0},
+ { "CLIENT", SYM(CLIENT_SYM),0,0},
+ { "CLOSE", SYM(CLOSE_SYM),0,0},
{ "COLUMN", SYM(COLUMN_SYM),0,0},
{ "COLUMNS", SYM(COLUMNS),0,0},
{ "COMMENT", SYM(COMMENT_SYM),0,0},
@@ -92,6 +97,7 @@ static SYMBOL symbols[] = {
{ "CONSTRAINT", SYM(CONSTRAINT),0,0},
{ "CREATE", SYM(CREATE),0,0},
{ "CROSS", SYM(CROSS),0,0},
+ { "CUBE", SYM(CUBE_SYM),0,0},
{ "CURRENT_DATE", SYM(CURDATE),0,0},
{ "CURRENT_TIME", SYM(CURTIME),0,0},
{ "CURRENT_TIMESTAMP", SYM(NOW_SYM),0,0},
@@ -106,12 +112,15 @@ static SYMBOL symbols[] = {
{ "DAY_SECOND", SYM(DAY_SECOND_SYM),0,0},
{ "DEC", SYM(DECIMAL_SYM),0,0},
{ "DECIMAL", SYM(DECIMAL_SYM),0,0},
+ { "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0},
{ "DEFAULT", SYM(DEFAULT),0,0},
{ "DELAYED", SYM(DELAYED_SYM),0,0},
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
{ "DELETE", SYM(DELETE_SYM),0,0},
{ "DESC", SYM(DESC),0,0},
{ "DESCRIBE", SYM(DESCRIBE),0,0},
+ { "DIRECTORY", SYM(DIRECTORY_SYM),0,0},
+ { "DISABLE", SYM(DISABLE_SYM),0,0},
{ "DISTINCT", SYM(DISTINCT),0,0},
{ "DISTINCTROW", SYM(DISTINCT),0,0}, /* Access likes this */
{ "DO", SYM(DO_SYM),0,0},
@@ -123,8 +132,11 @@ static SYMBOL symbols[] = {
{ "ELSE", SYM(ELSE),0,0},
{ "ESCAPE", SYM(ESCAPE_SYM),0,0},
{ "ESCAPED", SYM(ESCAPED),0,0},
+ { "ENABLE", SYM(ENABLE_SYM),0,0},
{ "ENCLOSED", SYM(ENCLOSED),0,0},
{ "ENUM", SYM(ENUM),0,0},
+ { "EVENTS", SYM(EVENTS_SYM),0,0},
+ { "EXECUTE", SYM(EXECUTE_SYM),0,0},
{ "EXPLAIN", SYM(DESCRIBE),0,0},
{ "EXISTS", SYM(EXISTS),0,0},
{ "EXTENDED", SYM(EXTENDED_SYM),0,0},
@@ -147,13 +159,12 @@ static SYMBOL symbols[] = {
{ "FULL", SYM(FULL),0,0},
{ "FULLTEXT", SYM(FULLTEXT_SYM),0,0},
{ "FUNCTION", SYM(UDF_SYM),0,0},
- { "GEMINI", SYM(GEMINI_SYM),0,0},
- { "GEMINI_SPIN_RETRIES", SYM(GEMINI_SPIN_RETRIES),0,0},
{ "GLOBAL", SYM(GLOBAL_SYM),0,0},
{ "GRANT", SYM(GRANT),0,0},
{ "GRANTS", SYM(GRANTS),0,0},
{ "GROUP", SYM(GROUP),0,0},
{ "HAVING", SYM(HAVING),0,0},
+ { "HANDLER", SYM(HANDLER_SYM),0,0},
{ "HEAP", SYM(HEAP_SYM),0,0},
{ "HIGH_PRIORITY", SYM(HIGH_PRIORITY),0,0},
{ "HOUR", SYM(HOUR_SYM),0,0},
@@ -164,12 +175,13 @@ static SYMBOL symbols[] = {
{ "IGNORE", SYM(IGNORE_SYM),0,0},
{ "IN", SYM(IN_SYM),0,0},
{ "INDEX", SYM(INDEX),0,0},
+ { "INDEXES", SYM(INDEXES),0,0},
{ "INFILE", SYM(INFILE),0,0},
{ "INNER", SYM(INNER_SYM),0,0},
{ "INNOBASE", SYM(INNOBASE_SYM),0,0},
{ "INNODB", SYM(INNOBASE_SYM),0,0},
{ "INSERT", SYM(INSERT),0,0},
- { "INSERT_ID", SYM(INSERT_ID),0,0},
+ { "INSERT_METHOD", SYM(INSERT_METHOD),0,0},
{ "INT", SYM(INT_SYM),0,0},
{ "INTEGER", SYM(INT_SYM),0,0},
{ "INTERVAL", SYM(INTERVAL_SYM),0,0},
@@ -179,15 +191,17 @@ static SYMBOL symbols[] = {
{ "INT4", SYM(INT_SYM),0,0},
{ "INT8", SYM(BIGINT),0,0},
{ "INTO", SYM(INTO),0,0},
+ { "IO_THREAD", SYM(IO_THREAD),0,0},
{ "IF", SYM(IF),0,0},
{ "IS", SYM(IS),0,0},
{ "ISOLATION", SYM(ISOLATION),0,0},
{ "ISAM", SYM(ISAM_SYM),0,0},
+ { "ISSUER", SYM(ISSUER_SYM),0,0},
{ "JOIN", SYM(JOIN_SYM),0,0},
{ "KEY", SYM(KEY_SYM),0,0},
{ "KEYS", SYM(KEYS),0,0},
{ "KILL", SYM(KILL_SYM),0,0},
- { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0},
+ { "LAST", SYM(LAST_SYM),0,0},
{ "LEADING", SYM(LEADING),0,0},
{ "LEFT", SYM(LEFT),0,0},
{ "LEVEL", SYM(LEVEL_SYM),0,0},
@@ -210,8 +224,12 @@ static SYMBOL symbols[] = {
{ "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM),0,0},
{ "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0},
{ "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0},
+ { "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0},
{ "MASTER_USER", SYM(MASTER_USER_SYM),0,0},
{ "MAX_ROWS", SYM(MAX_ROWS),0,0},
+ { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR), 0,0},
+ { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR), 0,0},
+ { "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR), 0,0},
{ "MATCH", SYM(MATCH),0,0},
{ "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0},
{ "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0},
@@ -229,12 +247,14 @@ static SYMBOL symbols[] = {
{ "MYISAM", SYM(MYISAM_SYM),0,0},
{ "NATURAL", SYM(NATURAL),0,0},
{ "NATIONAL", SYM(NATIONAL_SYM),0,0},
+ { "NEXT", SYM(NEXT_SYM),0,0},
+ { "NEW", SYM(NEW_SYM),0,0},
{ "NCHAR", SYM(NCHAR_SYM),0,0},
- { "NUMERIC", SYM(NUMERIC_SYM),0,0},
{ "NO", SYM(NO_SYM),0,0},
{ "NO_FOREIGN_KEY_CHECKS", SYM(NO_FOREIGN_KEY_CHECKS), 0, 0},
{ "NOT", SYM(NOT),0,0},
{ "NULL", SYM(NULL_SYM),0,0},
+ { "NUMERIC", SYM(NUMERIC_SYM),0,0},
{ "ON", SYM(ON),0,0},
{ "OPEN", SYM(OPEN_SYM),0,0},
{ "OPTIMIZE", SYM(OPTIMIZE),0,0},
@@ -249,24 +269,31 @@ static SYMBOL symbols[] = {
{ "PASSWORD", SYM(PASSWORD),0,0},
{ "PURGE", SYM(PURGE),0,0},
{ "PRECISION", SYM(PRECISION),0,0},
+ { "PREV", SYM(PREV_SYM),0,0},
{ "PRIMARY", SYM(PRIMARY_SYM),0,0},
{ "PROCEDURE", SYM(PROCEDURE),0,0},
{ "PROCESS" , SYM(PROCESS),0,0},
{ "PROCESSLIST", SYM(PROCESSLIST_SYM),0,0},
{ "PRIVILEGES", SYM(PRIVILEGES),0,0},
+ { "QUERY", SYM(QUERY_SYM),0,0},
{ "QUICK", SYM(QUICK),0,0},
{ "RAID0", SYM(RAID_0_SYM),0,0},
{ "READ", SYM(READ_SYM),0,0},
{ "REAL", SYM(REAL),0,0},
{ "REFERENCES", SYM(REFERENCES),0,0},
+ { "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM),0,0},
+ { "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM),0,0},
{ "RELOAD", SYM(RELOAD),0,0},
{ "REGEXP", SYM(REGEXP),0,0},
{ "RELAXED_UNIQUE_CHECKS", SYM(RELAXED_UNIQUE_CHECKS), 0, 0},
{ "RENAME", SYM(RENAME),0,0},
{ "REPAIR", SYM(REPAIR),0,0},
{ "REPLACE", SYM(REPLACE),0,0},
+ { "REPLICATION", SYM(REPLICATION),0,0},
{ "REPEATABLE", SYM(REPEATABLE_SYM),0,0},
+ { "REQUIRE", SYM(REQUIRE_SYM),0,0},
{ "RESET", SYM(RESET_SYM),0,0},
+ { "USER_RESOURCES", SYM(RESOURCES),0,0},
{ "RESTORE", SYM(RESTORE_SYM),0,0},
{ "RESTRICT", SYM(RESTRICT),0,0},
{ "RETURNS", SYM(UDF_RETURNS_SYM),0,0},
@@ -274,6 +301,7 @@ static SYMBOL symbols[] = {
{ "RIGHT", SYM(RIGHT),0,0},
{ "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */
{ "ROLLBACK", SYM(ROLLBACK_SYM),0,0},
+ { "ROLLUP", SYM(ROLLUP_SYM),0,0},
{ "ROW", SYM(ROW_SYM),0,0},
{ "ROWS", SYM(ROWS_SYM),0,0},
{ "SECOND", SYM(SECOND_SYM),0,0},
@@ -281,28 +309,21 @@ static SYMBOL symbols[] = {
{ "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0},
{ "SESSION", SYM(SESSION_SYM),0,0},
{ "SET", SYM(SET),0,0},
+ { "SIGNED", SYM(SIGNED_SYM),0,0},
{ "SHARE", SYM(SHARE_SYM),0,0},
{ "SHOW", SYM(SHOW),0,0},
{ "SHUTDOWN", SYM(SHUTDOWN),0,0},
{ "SLAVE", SYM(SLAVE),0,0},
{ "SMALLINT", SYM(SMALLINT),0,0},
{ "SONAME", SYM(UDF_SONAME_SYM),0,0},
- { "SQL_AUTO_IS_NULL", SYM(SQL_AUTO_IS_NULL),0,0},
{ "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0},
- { "SQL_BIG_SELECTS", SYM(SQL_BIG_SELECTS),0,0},
- { "SQL_BIG_TABLES", SYM(SQL_BIG_TABLES),0,0},
{ "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0},
- { "SQL_LOG_BIN", SYM(SQL_LOG_BIN),0,0},
- { "SQL_LOG_OFF", SYM(SQL_LOG_OFF),0,0},
- { "SQL_LOG_UPDATE", SYM(SQL_LOG_UPDATE),0,0},
- { "SQL_LOW_PRIORITY_UPDATES", SYM(SQL_LOW_PRIORITY_UPDATES),0,0},
- { "SQL_MAX_JOIN_SIZE",SYM(SQL_MAX_JOIN_SIZE), 0, 0},
- { "SQL_QUOTE_SHOW_CREATE",SYM(SQL_QUOTE_SHOW_CREATE), 0, 0},
- { "SQL_SAFE_UPDATES", SYM(SQL_SAFE_UPDATES),0,0},
- { "SQL_SELECT_LIMIT", SYM(SQL_SELECT_LIMIT),0,0},
- { "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0},
+ { "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0},
+ { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0},
+ { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
- { "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0},
+ { "SQL_THREAD", SYM(SQL_THREAD),0,0},
+ { "SSL", SYM(SSL_SYM),0,0},
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
{ "START", SYM(START_SYM),0,0},
{ "STARTING", SYM(STARTING),0,0},
@@ -310,6 +331,8 @@ static SYMBOL symbols[] = {
{ "STRING", SYM(STRING_SYM),0,0},
{ "STOP", SYM(STOP_SYM),0,0},
{ "STRIPED", SYM(RAID_STRIPED_SYM),0,0},
+ { "SUBJECT", SYM(SUBJECT_SYM),0,0},
+ { "SUPER", SYM(SUPER_SYM),0,0},
{ "TABLE", SYM(TABLE_SYM),0,0},
{ "TABLES", SYM(TABLES),0,0},
{ "TEMPORARY", SYM(TEMPORARY),0,0},
@@ -332,6 +355,7 @@ static SYMBOL symbols[] = {
{ "UNLOCK", SYM(UNLOCK_SYM),0,0},
{ "UNSIGNED", SYM(UNSIGNED),0,0},
{ "USE", SYM(USE_SYM),0,0},
+ { "USE_FRM", SYM(USE_FRM),0,0},
{ "USING", SYM(USING),0,0},
{ "UPDATE", SYM(UPDATE_SYM),0,0},
{ "USAGE", SYM(USAGE),0,0},
@@ -345,6 +369,8 @@ static SYMBOL symbols[] = {
{ "WRITE", SYM(WRITE_SYM),0,0},
{ "WHEN", SYM(WHEN_SYM),0,0},
{ "WHERE", SYM(WHERE),0,0},
+ { "XOR", SYM(XOR),0,0},
+ { "X509", SYM(X509_SYM),0,0},
{ "YEAR", SYM(YEAR_SYM),0,0},
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0},
{ "ZEROFILL", SYM(ZEROFILL),0,0},
@@ -356,6 +382,8 @@ static SYMBOL sql_functions[] = {
{ "ABS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)},
{ "ACOS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)},
{ "ADDDATE", SYM(DATE_ADD_INTERVAL),0,0},
+ { "AES_ENCRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_encrypt)},
+ { "AES_DECRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_decrypt)},
{ "ASCII", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ascii)},
{ "ASIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)},
{ "ATAN", SYM(ATAN),0,0},
@@ -365,7 +393,9 @@ static SYMBOL sql_functions[] = {
{ "BIT_COUNT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)},
{ "BIT_OR", SYM(BIT_OR),0,0},
{ "BIT_AND", SYM(BIT_AND),0,0},
+ { "CAST", SYM(CAST_SYM),0,0},
{ "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
+ { "BIT_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)},
{ "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
{ "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
{ "COALESCE", SYM(COALESCE),0,0},
@@ -373,6 +403,7 @@ static SYMBOL sql_functions[] = {
{ "CONCAT_WS", SYM(CONCAT_WS),0,0},
{ "CONNECTION_ID", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)},
{ "CONV", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)},
+ { "CONVERT", SYM(CONVERT_SYM),0,0},
{ "COUNT", SYM(COUNT_SYM),0,0},
{ "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)},
{ "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)},
@@ -387,6 +418,8 @@ static SYMBOL sql_functions[] = {
{ "DAYOFYEAR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofyear)},
{ "DECODE", SYM(DECODE_SYM),0,0},
{ "DEGREES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)},
+ { "DES_ENCRYPT", SYM(DES_ENCRYPT_SYM),0,0},
+ { "DES_DECRYPT", SYM(DES_DECRYPT_SYM),0,0},
{ "ELT", SYM(ELT_FUNC),0,0},
{ "ENCODE", SYM(ENCODE_SYM),0,0},
{ "ENCRYPT", SYM(ENCRYPT),0,0},
@@ -397,6 +430,7 @@ static SYMBOL sql_functions[] = {
{ "FIND_IN_SET", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_find_in_set)},
{ "FLOOR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_floor)},
{ "FORMAT", SYM(FORMAT_SYM),0,0},
+ { "FOUND_ROWS", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_found_rows)},
{ "FROM_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)},
{ "FROM_UNIXTIME", SYM(FROM_UNIXTIME),0,0},
{ "GET_LOCK", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)},
@@ -408,6 +442,8 @@ static SYMBOL sql_functions[] = {
{ "INET_NTOA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)},
{ "INSTR", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)},
{ "ISNULL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)},
+ { "IS_FREE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)},
+ { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0},
{ "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
{ "LEAST", SYM(LEAST_SYM),0,0},
{ "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
@@ -452,6 +488,8 @@ static SYMBOL sql_functions[] = {
{ "SUBDATE", SYM(DATE_SUB_INTERVAL),0,0},
{ "SIGN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sign)},
{ "SIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sin)},
+ { "SHA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
+ { "SHA1", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
{ "SOUNDEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)},
{ "SPACE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)},
{ "SQRT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)},
diff --git a/sql/lex_symbol.h b/sql/lex_symbol.h
index a011e27b59e..9fff1751b1b 100644
--- a/sql/lex_symbol.h
+++ b/sql/lex_symbol.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/lock.cc b/sql/lock.cc
index a9054b99186..93c826f2528 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -55,33 +55,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
Wait until the lock is gone
*/
- if (thd->global_read_lock) // This thread had the read locks
+ if (wait_if_global_read_lock(thd, 1))
{
- my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
- write_lock_used->table_name);
my_free((gptr) sql_lock,MYF(0));
sql_lock=0;
break;
}
-
- pthread_mutex_lock(&LOCK_open);
- thd->mysys_var->current_mutex= &LOCK_open;
- thd->mysys_var->current_cond= &COND_refresh;
- thd->proc_info="Waiting for table";
-
- while (global_read_lock && ! thd->killed &&
- thd->version == refresh_version)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
- pthread_mutex_unlock(&LOCK_open);
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- thd->proc_info= 0;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
-
- if (thd->version != refresh_version || thd->killed)
+ if (thd->version != refresh_version)
{
my_free((gptr) sql_lock,MYF(0));
goto retry;
@@ -155,7 +135,7 @@ static int lock_external(TABLE **tables,uint count)
if ((error=(*tables)->file->external_lock(thd,lock_type)))
{
- for ( ; i-- ; tables--)
+ for (; i-- ; tables--)
{
(*tables)->file->external_lock(thd, F_UNLCK);
(*tables)->current_lock=F_UNLCK;
@@ -401,6 +381,36 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
*****************************************************************************/
/*
+ Lock and wait for the named lock.
+ Returns 0 on ok
+*/
+
+int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
+{
+ int lock_retcode;
+ int error= -1;
+ DBUG_ENTER("lock_and_wait_for_table_name");
+
+ if (wait_if_global_read_lock(thd,0))
+ DBUG_RETURN(1);
+ VOID(pthread_mutex_lock(&LOCK_open));
+ if ((lock_retcode = lock_table_name(thd, table_list)) < 0)
+ goto end;
+ if (lock_retcode && wait_for_locked_table_names(thd, table_list))
+ {
+ unlock_table_name(thd, table_list);
+ goto end;
+ }
+ error=0;
+
+end:
+ pthread_mutex_unlock(&LOCK_open);
+ start_waiting_global_read_lock(thd);
+ DBUG_RETURN(error);
+}
+
+
+/*
Put a not open table with an old refresh version in the table cache.
This will force any other threads that uses the table to release it
as soon as possible.
@@ -411,7 +421,6 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
> 0 table locked, but someone is using it
*/
-
int lock_table_name(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
@@ -429,10 +438,11 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
if (table->in_use == thd)
DBUG_RETURN(0);
- /* Create a table entry with the right key and with an old refresh version */
- /* Note that we must use my_malloc() here as this is freed by the table
- cache */
-
+ /*
+ Create a table entry with the right key and with an old refresh version
+ Note that we must use my_malloc() here as this is freed by the table
+ cache
+ */
if (!(table= (TABLE*) my_malloc(sizeof(*table)+key_length,
MYF(MY_WME | MY_ZEROFILL))))
DBUG_RETURN(-1);
@@ -463,7 +473,7 @@ void unlock_table_name(THD *thd, TABLE_LIST *table_list)
static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
{
- for ( ; table_list ; table_list=table_list->next)
+ for (; table_list ; table_list=table_list->next)
{
if (table_list->table && table_is_used(table_list->table,0))
return 1;
@@ -510,3 +520,102 @@ static void print_lock_error(int error)
DBUG_VOID_RETURN;
}
+
+/****************************************************************************
+ Handling of global read locks
+
+ The global locks are handled through the global variables:
+ global_read_lock
+ waiting_for_read_lock
+ protect_against_global_read_lock
+****************************************************************************/
+
+volatile uint global_read_lock=0;
+static volatile uint protect_against_global_read_lock=0;
+static volatile uint waiting_for_read_lock=0;
+
+bool lock_global_read_lock(THD *thd)
+{
+ DBUG_ENTER("lock_global_read_lock");
+
+ if (!thd->global_read_lock)
+ {
+ (void) pthread_mutex_lock(&LOCK_open);
+ const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
+ "Waiting to get readlock");
+ DBUG_PRINT("info",
+ ("waiting_for: %d protect_against: %d",
+ waiting_for_read_lock, protect_against_global_read_lock));
+
+ waiting_for_read_lock++;
+ while (protect_against_global_read_lock && !thd->killed)
+ pthread_cond_wait(&COND_refresh, &LOCK_open);
+ waiting_for_read_lock--;
+ thd->exit_cond(old_message);
+ if (thd->killed)
+ {
+ (void) pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(1);
+ }
+ thd->global_read_lock=1;
+ global_read_lock++;
+ (void) pthread_mutex_unlock(&LOCK_open);
+ }
+ DBUG_RETURN(0);
+}
+
+void unlock_global_read_lock(THD *thd)
+{
+ uint tmp;
+ thd->global_read_lock=0;
+ pthread_mutex_lock(&LOCK_open);
+ tmp= --global_read_lock;
+ pthread_mutex_unlock(&LOCK_open);
+ /* Send the signal outside the mutex to avoid a context switch */
+ if (!tmp)
+ pthread_cond_broadcast(&COND_refresh);
+}
+
+
+bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
+{
+ const char *old_message;
+ bool result=0;
+ DBUG_ENTER("wait_if_global_read_lock");
+
+ (void) pthread_mutex_lock(&LOCK_open);
+ if (global_read_lock)
+ {
+ if (thd->global_read_lock) // This thread had the read locks
+ {
+ my_error(ER_CANT_UPDATE_WITH_READLOCK,MYF(0));
+ (void) pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(1);
+ }
+ old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
+ "Waiting for release of readlock");
+ while (global_read_lock && ! thd->killed &&
+ (!abort_on_refresh || thd->version == refresh_version))
+ (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
+ if (thd->killed)
+ result=1;
+ thd->exit_cond(old_message);
+ }
+ if (!abort_on_refresh && !result)
+ protect_against_global_read_lock++;
+ pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(result);
+}
+
+
+void start_waiting_global_read_lock(THD *thd)
+{
+ bool tmp;
+ DBUG_ENTER("start_waiting_global_read_lock");
+ (void) pthread_mutex_lock(&LOCK_open);
+ tmp= (!--protect_against_global_read_lock && waiting_for_read_lock);
+ (void) pthread_mutex_unlock(&LOCK_open);
+ if (tmp)
+ pthread_cond_broadcast(&COND_refresh);
+ DBUG_VOID_RETURN;
+}
diff --git a/sql/log.cc b/sql/log.cc
index ee5818fc594..6d9e8215105 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -29,6 +29,7 @@
#include <my_dir.h>
#include <stdarg.h>
#include <m_ctype.h> // For test_if_number
+#include <assert.h>
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
@@ -79,9 +80,10 @@ static int find_uniq_filename(char *name)
DBUG_RETURN(0);
}
-MYSQL_LOG::MYSQL_LOG(): last_time(0), query_start(0),index_file(-1),
- name(0), log_type(LOG_CLOSED),write_error(0),
- inited(0), no_rotate(0)
+MYSQL_LOG::MYSQL_LOG()
+ :bytes_written(0), last_time(0), query_start(0), index_file(-1), name(0),
+ file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
+ no_rotate(0), need_start_event(1)
{
/*
We don't want to intialize LOCK_Log here as the thread system may
@@ -97,6 +99,7 @@ MYSQL_LOG::~MYSQL_LOG()
{
(void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index);
+ (void) pthread_cond_destroy(&update_cond);
}
}
@@ -136,14 +139,19 @@ bool MYSQL_LOG::open_index( int options)
MYF(MY_WME))) < 0);
}
-void MYSQL_LOG::init(enum_log_type log_type_arg)
+void MYSQL_LOG::init(enum_log_type log_type_arg,
+ enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg)
{
log_type = log_type_arg;
+ io_cache_type = io_cache_type_arg;
+ no_auto_events = no_auto_events_arg;
if (!inited)
{
inited=1;
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
+ (void) pthread_cond_init(&update_cond, 0);
}
}
@@ -157,16 +165,19 @@ void MYSQL_LOG::close_index()
}
void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
- const char *new_name)
+ const char *new_name, enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg)
{
MY_STAT tmp_stat;
char buff[512];
File file= -1;
bool do_magic;
-
+ int open_flags = O_CREAT | O_APPEND | O_BINARY;
+ DBUG_ENTER("MYSQL_LOG::open");
+
if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name))
- no_rotate = 1;
- init(log_type_arg);
+ no_rotate = 1;
+ init(log_type_arg,io_cache_type_arg,no_auto_events_arg);
if (!(name=my_strdup(log_name,MYF(MY_WME))))
goto err;
@@ -174,7 +185,12 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
strmov(log_file_name,new_name);
else if (generate_new_name(log_file_name, name))
goto err;
-
+
+ if (io_cache_type == SEQ_READ_APPEND)
+ open_flags |= O_RDWR;
+ else
+ open_flags |= O_WRONLY;
+
if (log_type == LOG_BIN && !index_file_name[0])
fn_format(index_file_name, name, mysql_data_home, ".index", 6);
@@ -182,9 +198,10 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
&tmp_stat, MYF(0)));
- if ((file=my_open(log_file_name,O_CREAT | O_APPEND | O_WRONLY | O_BINARY,
+ open_count++;
+ if ((file=my_open(log_file_name,open_flags,
MYF(MY_WME | ME_WAITTANG))) < 0 ||
- init_io_cache(&log_file, file, IO_SIZE, WRITE_CACHE,
+ init_io_cache(&log_file, file, IO_SIZE, io_cache_type,
my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP)))
goto err;
@@ -220,19 +237,22 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
}
else if (log_type == LOG_BIN)
{
- /*
- Explanation of the boolean black magic:
- if we are supposed to write magic number try write
- clean up if failed
- then if index_file has not been previously opened, try to open it
- clean up if failed
- */
- if ((do_magic && my_b_write(&log_file, (byte*) BINLOG_MAGIC, 4)) ||
- open_index(O_APPEND | O_RDWR | O_CREAT))
- goto err;
- Start_log_event s;
bool error;
- s.write(&log_file);
+ if (do_magic)
+ {
+ if (my_b_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE) ||
+ open_index(O_APPEND | O_RDWR | O_CREAT))
+ goto err;
+ bytes_written += BIN_LOG_HEADER_SIZE;
+ }
+
+ if (need_start_event && !no_auto_events)
+ {
+ Start_log_event s;
+ s.set_log_pos(this);
+ s.write(&log_file);
+ need_start_event=0;
+ }
flush_io_cache(&log_file);
pthread_mutex_lock(&LOCK_index);
error=(my_write(index_file, (byte*) log_file_name, strlen(log_file_name),
@@ -245,7 +265,7 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
goto err;
}
}
- return;
+ DBUG_VOID_RETURN;
err:
sql_print_error("Could not use %s for logging (error %d)", log_name,errno);
@@ -254,9 +274,7 @@ err:
end_io_cache(&log_file);
x_free(name); name=0;
log_type=LOG_CLOSED;
-
- return;
-
+ DBUG_VOID_RETURN;
}
int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
@@ -269,7 +287,9 @@ int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
}
// if log_name is "" we stop at the first entry
-int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
+
+int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name,
+ bool need_mutex)
{
if (index_file < 0)
return LOG_INFO_INVALID;
@@ -278,16 +298,19 @@ int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
uint log_name_len = (uint) strlen(log_name);
IO_CACHE io_cache;
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- pthread_mutex_lock(&LOCK_index);
+ /*
+ Mutex needed because we need to make sure the file pointer does not move
+ from under our feet
+ */
+ if (need_mutex)
+ pthread_mutex_lock(&LOCK_index);
if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME)))
{
error = LOG_INFO_SEEK;
goto err;
}
- for(;;)
+ for (;;)
{
uint length;
if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN-1)))
@@ -309,24 +332,28 @@ int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
error = 0;
err:
- pthread_mutex_unlock(&LOCK_index);
+ if (need_mutex)
+ pthread_mutex_unlock(&LOCK_index);
end_io_cache(&io_cache);
return error;
}
-int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
+int MYSQL_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
{
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- if (index_file < 0) return LOG_INFO_INVALID;
+ /*
+ Mutex needed because we need to make sure the file pointer does not move
+ from under our feet
+ */
+ if (index_file < 0)
+ return LOG_INFO_INVALID;
int error = 0;
char* fname = linfo->log_file_name;
IO_CACHE io_cache;
uint length;
-
- pthread_mutex_lock(&LOCK_index);
+ if (need_lock)
+ pthread_mutex_lock(&LOCK_index);
if (init_io_cache(&io_cache, index_file, IO_SIZE,
READ_CACHE, (my_off_t) linfo->index_file_offset, 0,
MYF(MY_WME)))
@@ -344,16 +371,159 @@ int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
error = 0;
err:
- pthread_mutex_unlock(&LOCK_index);
+ if (need_lock)
+ pthread_mutex_unlock(&LOCK_index);
end_io_cache(&io_cache);
return error;
}
-
+
+int MYSQL_LOG::reset_logs(THD* thd)
+{
+ LOG_INFO linfo;
+ int error=0;
+ const char* save_name;
+ enum_log_type save_log_type;
+
+ pthread_mutex_lock(&LOCK_log);
+ if (find_first_log(&linfo,""))
+ {
+ error=1;
+ goto err;
+ }
+
+ for (;;)
+ {
+ my_delete(linfo.log_file_name, MYF(MY_WME));
+ if (find_next_log(&linfo))
+ break;
+ }
+ save_name=name;
+ name=0;
+ save_log_type=log_type;
+ close(1);
+ my_delete(index_file_name, MYF(MY_WME));
+ if (thd && !thd->slave_thread)
+ need_start_event=1;
+ open(save_name,save_log_type,0,io_cache_type,no_auto_events);
+ my_free((gptr)save_name,MYF(0));
+
+err:
+ pthread_mutex_unlock(&LOCK_log);
+ return error;
+}
+
+
+int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
+{
+ /*
+ Test pre-conditions.
+
+ Assume that we have previously read the first log and
+ stored it in rli->relay_log_name
+ */
+ DBUG_ASSERT(is_open());
+ DBUG_ASSERT(index_file >= 0);
+ DBUG_ASSERT(rli->slave_running == 1);
+ DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name));
+ DBUG_ASSERT(rli->linfo.index_file_offset ==
+ strlen(rli->relay_log_name) + 1);
+
+ int tmp_fd;
+ char* fname, *io_buf;
+ int error = 0;
+
+ if (!(fname= (char*) my_malloc(IO_SIZE+FN_REFLEN, MYF(MY_WME))))
+ return 1;
+ pthread_mutex_lock(&LOCK_index);
+ my_seek(index_file,rli->linfo.index_file_offset,
+ MY_SEEK_SET, MYF(MY_WME));
+ io_buf = fname + FN_REFLEN;
+ strxmov(fname,rli->relay_log_name,".tmp",NullS);
+
+ if ((tmp_fd = my_open(fname,O_CREAT|O_BINARY|O_RDWR, MYF(MY_WME))) < 0)
+ {
+ error = 1;
+ goto err;
+ }
+ for (;;)
+ {
+ int bytes_read;
+ bytes_read = my_read(index_file, (byte*) io_buf, IO_SIZE, MYF(0));
+ if (bytes_read < 0) // error
+ {
+ error=1;
+ goto err;
+ }
+ if (!bytes_read)
+ break; // end of file
+ // otherwise, we've read something and need to write it out
+ if (my_write(tmp_fd, (byte*) io_buf, bytes_read, MYF(MY_WME|MY_NABP)))
+ {
+ error=1;
+ goto err;
+ }
+ }
+
+err:
+ if (tmp_fd)
+ my_close(tmp_fd, MYF(MY_WME));
+ if (error)
+ my_delete(fname, MYF(0)); // do not report error if the file is not there
+ else
+ {
+ MY_STAT s;
+ my_close(index_file, MYF(MY_WME));
+ if (!my_stat(rli->relay_log_name,&s,MYF(0)))
+ {
+ sql_print_error("The first log %s failed to stat during purge",
+ rli->relay_log_name);
+ error=1;
+ goto err;
+ }
+ if (my_rename(fname,index_file_name,MYF(MY_WME)) ||
+ (index_file=my_open(index_file_name,O_BINARY|O_RDWR|O_APPEND,
+ MYF(MY_WME)))<0 ||
+ my_delete(rli->relay_log_name, MYF(MY_WME)))
+ error=1;
+
+ pthread_mutex_lock(&rli->log_space_lock);
+ rli->log_space_total -= s.st_size;
+ pthread_mutex_unlock(&rli->log_space_lock);
+ /*
+ Ok to broadcast after the critical region as there is no risk of
+ the mutex being destroyed by this thread later - this helps save
+ context switches
+ */
+ pthread_cond_broadcast(&rli->log_space_cond);
+
+ if ((error=find_first_log(&rli->linfo,"",0/*no mutex*/)))
+ {
+ char buff[22];
+ sql_print_error("next log error=%d,offset=%s,log=%s",error,
+ llstr(rli->linfo.index_file_offset,buff),
+ rli->linfo.log_file_name);
+ goto err2;
+ }
+ rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
+ strmake(rli->relay_log_name,rli->linfo.log_file_name,
+ sizeof(rli->relay_log_name)-1);
+ flush_relay_log_info(rli);
+ }
+ /*
+ No need to free io_buf because we allocated both fname and io_buf in
+ one malloc()
+ */
+
+err2:
+ pthread_mutex_unlock(&LOCK_index);
+ my_free(fname, MYF(MY_WME));
+ return error;
+}
+
+
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
{
- if (index_file < 0) return LOG_INFO_INVALID;
- if (no_rotate) return LOG_INFO_PURGE_NO_ROTATE;
int error;
char fname[FN_REFLEN];
char *p;
@@ -364,6 +534,10 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
LINT_INIT(purge_offset);
IO_CACHE io_cache;
+ if (index_file < 0)
+ return LOG_INFO_INVALID;
+ if (no_rotate)
+ return LOG_INFO_PURGE_NO_ROTATE;
pthread_mutex_lock(&LOCK_index);
if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0,
@@ -385,28 +559,27 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
goto err;
}
logs_to_keep_inited = 1;
-
- for(;;)
+ for (;;)
{
my_off_t init_purge_offset= my_b_tell(&io_cache);
if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN)))
{
- if(!io_cache.error)
+ if (!io_cache.error)
break;
error = LOG_INFO_IO;
goto err;
}
fname[--fname_len]=0; // kill \n
- if(!memcmp(fname, to_log, fname_len + 1 ))
+ if (!memcmp(fname, to_log, fname_len + 1 ))
{
found_log = 1;
purge_offset = init_purge_offset;
}
// if one of the logs before the target is in use
- if(!found_log && log_in_use(fname))
+ if (!found_log && log_in_use(fname))
{
error = LOG_INFO_IN_USE;
goto err;
@@ -422,13 +595,13 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
}
end_io_cache(&io_cache);
- if(!found_log)
+ if (!found_log)
{
error = LOG_INFO_EOF;
goto err;
}
- for(i = 0; i < logs_to_purge.elements; i++)
+ for (i = 0; i < logs_to_purge.elements; i++)
{
char* l;
get_dynamic(&logs_to_purge, (gptr)&l, i);
@@ -436,9 +609,10 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
sql_print_error("Error deleting %s during purge", l);
}
- // if we get killed -9 here, the sysadmin would have to do a small
- // vi job on the log index file after restart - otherwise, this should
- // be safe
+ /*
+ If we get killed -9 here, the sysadmin would have to edit
+ the log index file after restart - otherwise, this should be safe
+ */
#ifdef HAVE_FTRUNCATE
if (ftruncate(index_file,0))
{
@@ -451,9 +625,9 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
#else
my_close(index_file, MYF(MY_WME));
my_delete(index_file_name, MYF(MY_WME));
- if(!(index_file = my_open(index_file_name,
+ if ((index_file = my_open(index_file_name,
O_CREAT | O_BINARY | O_RDWR | O_APPEND,
- MYF(MY_WME))))
+ MYF(MY_WME)))<0)
{
sql_print_error(
"Could not re-open the binlog index file during log purge for write");
@@ -462,7 +636,7 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
}
#endif
- for(i = 0; i < logs_to_keep.elements; i++)
+ for (i = 0; i < logs_to_keep.elements; i++)
{
char* l;
get_dynamic(&logs_to_keep, (gptr)&l, i);
@@ -480,15 +654,14 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
err:
pthread_mutex_unlock(&LOCK_index);
- if(logs_to_purge_inited)
+ if (logs_to_purge_inited)
delete_dynamic(&logs_to_purge);
- if(logs_to_keep_inited)
+ if (logs_to_keep_inited)
delete_dynamic(&logs_to_keep);
end_io_cache(&io_cache);
return error;
}
-
// we assume that buf has at least FN_REFLEN bytes alloced
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
{
@@ -522,7 +695,7 @@ void MYSQL_LOG::new_file(bool inside_mutex)
if (!no_rotate)
{
/*
- only rotate open logs that are marked non-rotatable
+ Only rotate open logs that are marked non-rotatable
(binlog with constant name are non-rotatable)
*/
if (generate_new_name(new_name, name))
@@ -533,20 +706,39 @@ void MYSQL_LOG::new_file(bool inside_mutex)
}
if (log_type == LOG_BIN)
{
+ if (!no_auto_events)
+ {
+ /*
+ We log the whole file name for log file as the user may decide
+ to change base names at some point.
+ */
+ THD* thd = current_thd;
+ Rotate_log_event r(thd,new_name+dirname_length(new_name));
+ r.set_log_pos(this);
+
+ /*
+ This log rotation could have been initiated by a master of
+ the slave running with log-bin we set the flag on rotate
+ event to prevent inifinite log rotation loop
+ */
+ if (thd && thd->slave_thread)
+ r.flags |= LOG_EVENT_FORCED_ROTATE_F;
+ r.write(&log_file);
+ bytes_written += r.get_event_len();
+ }
/*
- We log the whole file name for log file as the user may decide
- to change base names at some point.
+ Update needs to be signaled even if there is no rotate event
+ log rotation should give the waiting thread a signal to
+ discover EOF and move on to the next log.
*/
- Rotate_log_event r(new_name+dirname_length(new_name));
- r.write(&log_file);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ signal_update();
}
+ else
+ strmov(new_name, old_name); // Reopen old file name
}
- else
- strmov(new_name, old_name); // Reopen old file name
name=0;
close();
- open(old_name, log_type, new_name);
+ open(old_name, log_type, new_name, io_cache_type, no_auto_events);
my_free(old_name,MYF(0));
last_time=query_start=0;
write_error=0;
@@ -555,6 +747,64 @@ void MYSQL_LOG::new_file(bool inside_mutex)
}
}
+bool MYSQL_LOG::append(Log_event* ev)
+{
+ bool error = 0;
+ pthread_mutex_lock(&LOCK_log);
+
+ DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
+ /*
+ Log_event::write() is smart enough to use my_b_write() or
+ my_b_append() depending on the kind of cache we have.
+ */
+ if (ev->write(&log_file))
+ {
+ error=1;
+ goto err;
+ }
+ bytes_written += ev->get_event_len();
+ if ((uint)my_b_append_tell(&log_file) > max_binlog_size)
+ {
+ new_file(1);
+ }
+ signal_update();
+
+err:
+ pthread_mutex_unlock(&LOCK_log);
+ return error;
+}
+
+
+bool MYSQL_LOG::appendv(const char* buf, uint len,...)
+{
+ bool error = 0;
+ va_list(args);
+ va_start(args,len);
+
+ DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
+
+ pthread_mutex_lock(&LOCK_log);
+ do
+ {
+ if (my_b_append(&log_file,(byte*) buf,len))
+ {
+ error = 1;
+ break;
+ }
+ bytes_written += len;
+ } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
+
+ if ((uint) my_b_append_tell(&log_file) > max_binlog_size)
+ {
+ new_file(1);
+ }
+
+ if (!error)
+ signal_update();
+ pthread_mutex_unlock(&LOCK_log);
+ return error;
+}
+
bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
const char *format,...)
@@ -576,7 +826,7 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
if (thd)
{ // Normal thread
if ((thd->options & OPTION_LOG_OFF) &&
- (thd->master_access & PROCESS_ACL))
+ (thd->master_access & SUPER_ACL))
{
VOID(pthread_mutex_unlock(&LOCK_log));
return 0; // No logging
@@ -635,32 +885,36 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
return 0;
}
-/* Write to binary log in a format to be used for replication */
-bool MYSQL_LOG::write(Query_log_event* event_info)
+bool MYSQL_LOG::write(Log_event* event_info)
{
- /* In most cases this is only called if 'is_open()' is true */
bool error=0;
- bool should_rotate = 0;
if (!inited) // Can't use mutex if not init
return 0;
VOID(pthread_mutex_lock(&LOCK_log));
+ /* In most cases this is only called if 'is_open()' is true */
if (is_open())
{
+ bool should_rotate = 0;
THD *thd=event_info->thd;
- IO_CACHE *file = (event_info->cache_stmt ? &thd->transaction.trans_log :
+ const char* db = event_info->get_db();
+#ifdef USING_TRANSACTIONS
+ IO_CACHE *file = ((event_info->get_cache_stmt() && thd) ?
+ &thd->transaction.trans_log :
&log_file);
- if ((!(thd->options & OPTION_BIN_LOG) &&
- (thd->master_access & PROCESS_ACL)) ||
- !db_ok(event_info->db, binlog_do_db, binlog_ignore_db))
+#else
+ IO_CACHE *file = &log_file;
+#endif
+ if ((thd && !(thd->options & OPTION_BIN_LOG) &&
+ (thd->master_access & SUPER_ACL)) ||
+ (db && !db_ok(db, binlog_do_db, binlog_ignore_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
return 0;
}
error=1;
-
if (file == &thd->transaction.trans_log
&& !my_b_tell(&thd->transaction.trans_log)) {
@@ -693,52 +947,63 @@ bool MYSQL_LOG::write(Query_log_event* event_info)
goto err;
}
- if (thd->last_insert_id_used)
+ /*
+ No check for auto events flag here - this write method should
+ never be called if auto-events are enabled
+ */
+ if (thd && thd->last_insert_id_used)
{
- Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id);
- if(thd->server_id)
- e.server_id = thd->server_id;
+ Intvar_log_event e(thd,(uchar)LAST_INSERT_ID_EVENT,thd->last_insert_id);
+ e.set_log_pos(this);
+ if (thd->server_id)
+ e.server_id = thd->server_id;
if (e.write(file))
goto err;
}
- if (thd->insert_id_used)
+ if (thd && thd->insert_id_used)
{
- Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id);
- if(thd->server_id)
- e.server_id = thd->server_id;
+ Intvar_log_event e(thd,(uchar)INSERT_ID_EVENT,thd->last_insert_id);
+ e.set_log_pos(this);
+ if (thd->server_id)
+ e.server_id = thd->server_id;
if (e.write(file))
goto err;
}
- if (thd->convert_set)
+ if (thd && thd->variables.convert_set)
{
char buf[1024] = "SET CHARACTER SET ";
char* p = strend(buf);
- p = strmov(p, thd->convert_set->name);
+ p = strmov(p, thd->variables.convert_set->name);
int save_query_length = thd->query_length;
// just in case somebody wants it later
thd->query_length = (uint)(p - buf);
Query_log_event e(thd, buf);
+ e.set_log_pos(this);
if (e.write(file))
goto err;
thd->query_length = save_query_length; // clean up
}
+ event_info->set_log_pos(this);
if (event_info->write(file) ||
file == &log_file && flush_io_cache(file))
goto err;
error=0;
- should_rotate = (file == &log_file && my_b_tell(file) >= max_binlog_size);
- /* Tell for transactional table handlers up to which position in the
- binlog file we wrote. The table handler can store this info, and
- after crash recovery print for the user the offset of the last
- transactions which were recovered. Actually, we must also call
- the table handler commit here, protected by the LOCK_log mutex,
- because otherwise the transactions may end up in a different order
- in the table handler log! */
+ /*
+ Tell for transactional table handlers up to which position in the
+ binlog file we wrote. The table handler can store this info, and
+ after crash recovery print for the user the offset of the last
+ transactions which were recovered. Actually, we must also call
+ the table handler commit here, protected by the LOCK_log mutex,
+ because otherwise the transactions may end up in a different order
+ in the table handler log!
+ */
- if (file == &log_file) {
+ if (file == &log_file)
+ {
error = ha_report_binlog_offset_and_commit(thd, log_file_name,
- file->pos_in_file);
+ file->pos_in_file);
+ should_rotate= (my_b_tell(file) >= (my_off_t) max_binlog_size);
}
err:
@@ -751,14 +1016,23 @@ err:
write_error=1;
}
if (file == &log_file)
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ signal_update();
+ if (should_rotate)
+ new_file(1); // inside mutex
}
- if (should_rotate)
- new_file(1); // inside mutex
VOID(pthread_mutex_unlock(&LOCK_log));
return error;
}
+uint MYSQL_LOG::next_file_id()
+{
+ uint res;
+ pthread_mutex_lock(&LOCK_log);
+ res = file_id++;
+ pthread_mutex_unlock(&LOCK_log);
+ return res;
+}
+
/*
Write a cached log entry to the binary log
We only come here if there is something in the cache.
@@ -772,8 +1046,13 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
if (is_open())
{
- uint length;
+ /*
+ We come here when the queries to be logged could not fit into memory
+ and part of the queries are stored in a log file on disk.
+ */
+ uint length;
+ /* Read from the file used to cache the queries .*/
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), cache->file_name, errno);
@@ -782,13 +1061,14 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
length=my_b_bytes_in_cache(cache);
do
{
- if (my_b_write(&log_file, cache->rc_pos, length))
+ /* Write data to the binary log file */
+ if (my_b_write(&log_file, cache->read_pos, length))
{
if (!write_error)
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err;
}
- cache->rc_pos=cache->rc_end; // Mark buffer used up
+ cache->read_pos=cache->read_end; // Mark buffer used up
} while ((length=my_b_fill(cache)));
if (flush_io_cache(&log_file))
{
@@ -812,7 +1092,7 @@ err:
if (error)
write_error=1;
else
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ signal_update();
VOID(pthread_mutex_unlock(&LOCK_log));
@@ -820,42 +1100,6 @@ err:
}
-bool MYSQL_LOG::write(Load_log_event* event_info)
-{
- bool error=0;
- bool should_rotate = 0;
-
- if (inited)
- {
- VOID(pthread_mutex_lock(&LOCK_log));
- if (is_open())
- {
- THD *thd=event_info->thd;
- if ((thd->options & OPTION_BIN_LOG) ||
- !(thd->master_access & PROCESS_ACL))
- {
- if (event_info->write(&log_file) || flush_io_cache(&log_file))
- {
- if (!write_error)
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- error=write_error=1;
- }
- should_rotate = (my_b_tell(&log_file) >= max_binlog_size);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
- }
- }
-
- if(should_rotate)
- new_file(1); // inside mutex
-
- VOID(pthread_mutex_unlock(&LOCK_log));
- }
-
-
- return error;
-}
-
-
/* Write update log in a format suitable for incremental backup */
bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
@@ -872,7 +1116,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
char buff[80],*end;
end=buff;
if (!(thd->options & OPTION_UPDATE_LOG) &&
- (thd->master_access & PROCESS_ACL))
+ (thd->master_access & SUPER_ACL))
{
VOID(pthread_mutex_unlock(&LOCK_log));
return 0;
@@ -978,20 +1222,41 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
return error;
}
+void MYSQL_LOG:: wait_for_update(THD* thd)
+{
+ const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log,
+ "Slave: waiting for binlog update");
+ pthread_cond_wait(&update_cond, &LOCK_log);
+ /*
+ This is not a bug:
+ We unlock the mutex for the caller, and expect him to lock it and
+ then not unlock it upon return. This is a rather odd way of doing
+ things, but this is the cleanest way I could think of to solve the
+ race deadlock caused by THD::awake() first acquiring mysys_var
+ mutex and then the current mutex, while wait_for_update being
+ called with the current mutex already aquired and THD::exit_cond()
+ trying to acquire mysys_var mutex. We do need the mutex to be
+ acquired prior to the invocation of wait_for_update in all cases,
+ so mutex acquisition inside wait_for_update() is not an option.
+ */
+ pthread_mutex_unlock(&LOCK_log);
+ thd->exit_cond(old_msg);
+}
+
void MYSQL_LOG::close(bool exiting)
{ // One can't set log_type here!
if (is_open())
{
- File file=log_file.file;
- if (log_type == LOG_BIN)
+ if (log_type == LOG_BIN && !no_auto_events)
{
Stop_log_event s;
+ s.set_log_pos(this);
s.write(&log_file);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ signal_update();
}
end_io_cache(&log_file);
- if (my_close(file,MYF(0)) < 0 && ! write_error)
+ if (my_close(log_file.file,MYF(0)) < 0 && ! write_error)
{
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
@@ -1011,8 +1276,12 @@ void MYSQL_LOG::close(bool exiting)
}
- /* Check if a string is a valid number */
- /* Output: TRUE -> number */
+/*
+ Check if a string is a valid number
+ Return:
+ TRUE String is a number
+ FALSE Error
+*/
static bool test_if_number(register const char *str,
long *res, bool allow_wildcards)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index c30d03adaf5..52e97310d75 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -20,39 +20,390 @@
#pragma implementation // gcc: Class implementation
#endif
#include "mysql_priv.h"
+#include "slave.h"
+#include <my_dir.h>
#endif /* MYSQL_CLIENT */
+#include <assert.h>
-static void pretty_print_char(FILE* file, int c)
+inline int my_b_safe_write(IO_CACHE* file, const byte *buf,
+ int len)
{
+ /*
+ Sasha: We are not writing this with the ? operator to avoid hitting
+ a possible compiler bug. At least gcc 2.95 cannot deal with
+ several layers of ternary operators that evaluated comma(,) operator
+ expressions inside - I do have a test case if somebody wants it
+ */
+ if (file->type == SEQ_READ_APPEND)
+ return my_b_append(file, buf,len);
+ return my_b_write(file, buf,len);
+}
+
+#ifdef MYSQL_CLIENT
+static void pretty_print_str(FILE* file, char* str, int len)
+{
+ char* end = str + len;
fputc('\'', file);
- switch(c) {
- case '\n': fprintf(file, "\\n"); break;
- case '\r': fprintf(file, "\\r"); break;
- case '\\': fprintf(file, "\\\\"); break;
- case '\b': fprintf(file, "\\b"); break;
- case '\'': fprintf(file, "\\'"); break;
- case 0 : fprintf(file, "\\0"); break;
- default:
- fputc(c, file);
- break;
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+ case '\n': fprintf(file, "\\n"); break;
+ case '\r': fprintf(file, "\\r"); break;
+ case '\\': fprintf(file, "\\\\"); break;
+ case '\b': fprintf(file, "\\b"); break;
+ case '\t': fprintf(file, "\\t"); break;
+ case '\'': fprintf(file, "\\'"); break;
+ case 0 : fprintf(file, "\\0"); break;
+ default:
+ fputc(c, file);
+ break;
+ }
}
fputc('\'', file);
}
+#endif
+
+#ifndef MYSQL_CLIENT
+
+inline int ignored_error_code(int err_code)
+{
+ return use_slave_mask && bitmap_is_set(&slave_error_mask, err_code);
+}
+
+
+static void pretty_print_str(String* packet, char* str, int len)
+{
+ char* end = str + len;
+ packet->append('\'');
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+ case '\n': packet->append( "\\n"); break;
+ case '\r': packet->append( "\\r"); break;
+ case '\\': packet->append( "\\\\"); break;
+ case '\b': packet->append( "\\b"); break;
+ case '\t': packet->append( "\\t"); break;
+ case '\'': packet->append( "\\'"); break;
+ case 0 : packet->append( "\\0"); break;
+ default:
+ packet->append((char)c);
+ break;
+ }
+ }
+ packet->append('\'');
+}
+
+
+static inline char* slave_load_file_stem(char*buf, uint file_id,
+ int event_server_id)
+{
+ fn_format(buf,"SQL_LOAD-",slave_load_tmpdir,"",4+32);
+ buf = strend(buf);
+ buf = int10_to_str(::server_id, buf, 10);
+ *buf++ = '-';
+ buf = int10_to_str(event_server_id, buf, 10);
+ *buf++ = '-';
+ return int10_to_str(file_id, buf, 10);
+}
+
+#endif
+
+const char* Log_event::get_type_str()
+{
+ switch(get_type_code()) {
+ case START_EVENT: return "Start";
+ case STOP_EVENT: return "Stop";
+ case QUERY_EVENT: return "Query";
+ case ROTATE_EVENT: return "Rotate";
+ case INTVAR_EVENT: return "Intvar";
+ case LOAD_EVENT: return "Load";
+ case NEW_LOAD_EVENT: return "New_load";
+ case SLAVE_EVENT: return "Slave";
+ case CREATE_FILE_EVENT: return "Create_file";
+ case APPEND_BLOCK_EVENT: return "Append_block";
+ case DELETE_FILE_EVENT: return "Delete_file";
+ case EXEC_LOAD_EVENT: return "Exec_load";
+ default: /* impossible */ return "Unknown";
+ }
+}
+
+#ifndef MYSQL_CLIENT
+Log_event::Log_event(THD* thd_arg, uint16 flags_arg)
+ :exec_time(0), flags(flags_arg), cached_event_len(0),
+ temp_buf(0), thd(thd_arg)
+{
+ if (thd)
+ {
+ server_id = thd->server_id;
+ when = thd->start_time;
+ log_pos = thd->log_pos;
+ }
+ else
+ {
+ server_id = ::server_id;
+ when = time(NULL);
+ log_pos=0;
+ }
+}
+
+
+static void cleanup_load_tmpdir()
+{
+ MY_DIR *dirp;
+ FILEINFO *file;
+ uint i;
+ if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
+ return;
+
+ for (i=0 ; i < (uint)dirp->number_off_files; i++)
+ {
+ file=dirp->dir_entry+i;
+ if (is_prefix(file->name,"SQL_LOAD-"))
+ my_delete(file->name, MYF(0));
+ }
+
+ my_dirend(dirp);
+}
+
+#endif
+
+Log_event::Log_event(const char* buf, bool old_format)
+ :cached_event_len(0), temp_buf(0)
+{
+ when = uint4korr(buf);
+ server_id = uint4korr(buf + SERVER_ID_OFFSET);
+ if (old_format)
+ {
+ log_pos=0;
+ flags=0;
+ }
+ else
+ {
+ log_pos = uint4korr(buf + LOG_POS_OFFSET);
+ flags = uint2korr(buf + FLAGS_OFFSET);
+ }
+#ifndef MYSQL_CLIENT
+ thd = 0;
+#endif
+}
+
+
+#ifndef MYSQL_CLIENT
+
+int Log_event::exec_event(struct st_relay_log_info* rli)
+{
+ if (rli)
+ {
+ rli->inc_pos(get_event_len(),log_pos);
+ DBUG_ASSERT(rli->sql_thd != 0);
+ flush_relay_log_info(rli);
+ }
+ return 0;
+}
+
+void Log_event::pack_info(String* packet)
+{
+ net_store_data(packet, "", 0);
+}
+
+void Query_log_event::pack_info(String* packet)
+{
+ char buf[256];
+ String tmp(buf, sizeof(buf));
+ tmp.length(0);
+ if (db && db_len)
+ {
+ tmp.append("use ");
+ tmp.append(db, db_len);
+ tmp.append("; ", 2);
+ }
+
+ if (query && q_len)
+ tmp.append(query, q_len);
+ net_store_data(packet, (char*)tmp.ptr(), tmp.length());
+}
+
+void Start_log_event::pack_info(String* packet)
+{
+ char buf1[256];
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ char buf[22];
+
+ tmp.append("Server ver: ");
+ tmp.append(server_version);
+ tmp.append(", Binlog ver: ");
+ tmp.append(llstr(binlog_version, buf));
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Load_log_event::pack_info(String* packet)
+{
+ char buf[256];
+ String tmp(buf, sizeof(buf));
+ tmp.length(0);
+ if (db && db_len)
+ {
+ tmp.append("use ");
+ tmp.append(db, db_len);
+ tmp.append("; ", 2);
+ }
+
+ tmp.append("LOAD DATA INFILE '");
+ tmp.append(fname, fname_len);
+ tmp.append("' ", 2);
+ if (sql_ex.opt_flags && REPLACE_FLAG )
+ tmp.append(" REPLACE ");
+ else if (sql_ex.opt_flags && IGNORE_FLAG )
+ tmp.append(" IGNORE ");
+
+ tmp.append("INTO TABLE ");
+ tmp.append(table_name);
+ if (sql_ex.field_term_len)
+ {
+ tmp.append(" FIELDS TERMINATED BY ");
+ pretty_print_str(&tmp, sql_ex.field_term, sql_ex.field_term_len);
+ }
+
+ if (sql_ex.enclosed_len)
+ {
+ if (sql_ex.opt_flags && OPT_ENCLOSED_FLAG )
+ tmp.append(" OPTIONALLY ");
+ tmp.append( " ENCLOSED BY ");
+ pretty_print_str(&tmp, sql_ex.enclosed, sql_ex.enclosed_len);
+ }
+
+ if (sql_ex.escaped_len)
+ {
+ tmp.append( " ESCAPED BY ");
+ pretty_print_str(&tmp, sql_ex.escaped, sql_ex.escaped_len);
+ }
+
+ if (sql_ex.line_term_len)
+ {
+ tmp.append(" LINES TERMINATED BY ");
+ pretty_print_str(&tmp, sql_ex.line_term, sql_ex.line_term_len);
+ }
+
+ if (sql_ex.line_start_len)
+ {
+ tmp.append(" LINES STARTING BY ");
+ pretty_print_str(&tmp, sql_ex.line_start, sql_ex.line_start_len);
+ }
+
+ if ((int)skip_lines > 0)
+ tmp.append( " IGNORE %ld LINES ", (long) skip_lines);
+
+ if (num_fields)
+ {
+ uint i;
+ const char* field = fields;
+ tmp.append(" (");
+ for (i = 0; i < num_fields; i++)
+ {
+ if (i)
+ tmp.append(" ,");
+ tmp.append( field);
+
+ field += field_lens[i] + 1;
+ }
+ tmp.append(')');
+ }
+
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Rotate_log_event::pack_info(String* packet)
+{
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append(new_log_ident, ident_len);
+ tmp.append(";pos=");
+ tmp.append(llstr(pos,buf));
+ if (flags & LOG_EVENT_FORCED_ROTATE_F)
+ tmp.append("; forced by master");
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Intvar_log_event::pack_info(String* packet)
+{
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append(get_var_type_name());
+ tmp.append('=');
+ tmp.append(llstr(val, buf));
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Slave_log_event::pack_info(String* packet)
+{
+ char buf1[256], buf[22], *end;
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append("host=");
+ tmp.append(master_host);
+ tmp.append(",port=");
+ end= int10_to_str((long) master_port, buf, 10);
+ tmp.append(buf, (uint32) (end-buf));
+ tmp.append(",log=");
+ tmp.append(master_log);
+ tmp.append(",pos=");
+ tmp.append(llstr(master_pos,buf));
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+
+void Log_event::init_show_field_list(List<Item>* field_list)
+{
+ field_list->push_back(new Item_empty_string("Log_name", 20));
+ field_list->push_back(new Item_empty_string("Pos", 20));
+ field_list->push_back(new Item_empty_string("Event_type", 20));
+ field_list->push_back(new Item_empty_string("Server_id", 20));
+ field_list->push_back(new Item_empty_string("Orig_log_pos", 20));
+ field_list->push_back(new Item_empty_string("Info", 20));
+}
+
+int Log_event::net_send(THD* thd, const char* log_name, my_off_t pos)
+{
+ String* packet = &thd->packet;
+ const char* p = strrchr(log_name, FN_LIBCHAR);
+ const char* event_type;
+ if (p)
+ log_name = p + 1;
+
+ packet->length(0);
+ net_store_data(packet, log_name, strlen(log_name));
+ net_store_data(packet, (longlong) pos);
+ event_type = get_type_str();
+ net_store_data(packet, event_type, strlen(event_type));
+ net_store_data(packet, server_id);
+ net_store_data(packet, (longlong) log_pos);
+ pack_info(packet);
+ return my_net_write(&thd->net, (char*) packet->ptr(), packet->length());
+}
+
+#endif /* MYSQL_CLIENT */
+
int Query_log_event::write(IO_CACHE* file)
{
return query ? Log_event::write(file) : -1;
}
+
int Log_event::write(IO_CACHE* file)
{
return (write_header(file) || write_data(file)) ? -1 : 0;
}
+
int Log_event::write_header(IO_CACHE* file)
{
- // make sure to change this when the header gets bigger
char buf[LOG_EVENT_HEADER_LEN];
char* pos = buf;
int4store(pos, (ulong) when); // timestamp
@@ -63,7 +414,11 @@ int Log_event::write_header(IO_CACHE* file)
long tmp=get_data_size() + LOG_EVENT_HEADER_LEN;
int4store(pos, tmp);
pos += 4;
- return (my_b_write(file, (byte*) buf, (uint) (pos - buf)));
+ int4store(pos, log_pos);
+ pos += 4;
+ int2store(pos, flags);
+ pos += 2;
+ return (my_b_safe_write(file, (byte*) buf, (uint) (pos - buf)));
}
#ifndef MYSQL_CLIENT
@@ -72,215 +427,210 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock)
{
ulong data_len;
+ int result=0;
char buf[LOG_EVENT_HEADER_LEN];
+
if (log_lock)
pthread_mutex_lock(log_lock);
if (my_b_read(file, (byte*) buf, sizeof(buf)))
{
- if (log_lock) pthread_mutex_unlock(log_lock);
- // if the read hits eof, we must report it as eof
- // so the caller will know it can go into cond_wait to be woken up
- // on the next update to the log
- if(!file->error) return LOG_READ_EOF;
- return file->error > 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ /*
+ If the read hits eof, we must report it as eof so the caller
+ will know it can go into cond_wait to be woken up on the next
+ update to the log.
+ */
+ if (!file->error)
+ result= LOG_READ_EOF;
+ else
+ result= (file->error > 0 ? LOG_READ_TRUNC: LOG_READ_IO);
+ goto end;
}
- data_len = uint4korr(buf + EVENT_LEN_OFFSET);
- if (data_len < LOG_EVENT_HEADER_LEN || data_len > max_allowed_packet)
+ data_len= uint4korr(buf + EVENT_LEN_OFFSET);
+ if (data_len < LOG_EVENT_HEADER_LEN ||
+ data_len > current_thd->variables.max_allowed_packet)
{
- if (log_lock) pthread_mutex_unlock(log_lock);
- return (data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS :
- LOG_READ_TOO_LARGE;
+
+ result= ((data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS :
+ LOG_READ_TOO_LARGE);
+ goto end;
}
packet->append(buf, sizeof(buf));
- data_len -= LOG_EVENT_HEADER_LEN;
+ data_len-= LOG_EVENT_HEADER_LEN;
if (data_len)
{
if (packet->append(file, data_len))
{
- if(log_lock)
- pthread_mutex_unlock(log_lock);
- // here we should never hit eof in a non-error condtion
- // eof means we are reading the event partially, which should
- // never happen
- return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ /*
+ Here we should never hit eof in a non-error condtion
+ eof means we are reading the event partially, which should
+ never happen.
+ */
+ result= file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ /* Implicit goto end; */
}
}
- if (log_lock) pthread_mutex_unlock(log_lock);
- return 0;
+
+end:
+ if (log_lock)
+ pthread_mutex_unlock(log_lock);
+ return result;
}
#endif // MYSQL_CLIENT
#ifndef MYSQL_CLIENT
-#define UNLOCK_MUTEX if(log_lock) pthread_mutex_unlock(log_lock);
+#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
+#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
+#define max_allowed_packet current_thd->variables.max_allowed_packet
#else
#define UNLOCK_MUTEX
+#define LOCK_MUTEX
#endif
// allocates memory - the caller is responsible for clean-up
#ifndef MYSQL_CLIENT
-Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock)
+Log_event* Log_event::read_log_event(IO_CACHE* file,
+ pthread_mutex_t* log_lock,
+ bool old_format)
#else
-Log_event* Log_event::read_log_event(IO_CACHE* file)
+Log_event* Log_event::read_log_event(IO_CACHE* file, bool old_format)
#endif
{
- time_t timestamp;
- uint32 server_id;
-
- char buf[LOG_EVENT_HEADER_LEN-4];
-#ifndef MYSQL_CLIENT
- if(log_lock) pthread_mutex_lock(log_lock);
-#endif
- if (my_b_read(file, (byte *) buf, sizeof(buf)))
- {
- UNLOCK_MUTEX
- return NULL;
- }
- timestamp = uint4korr(buf);
- server_id = uint4korr(buf + 5);
-
- switch(buf[EVENT_TYPE_OFFSET])
- {
- case QUERY_EVENT:
+ char head[LOG_EVENT_HEADER_LEN];
+ uint header_size= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+
+ LOCK_MUTEX;
+ if (my_b_read(file, (byte *) head, header_size))
{
- Query_log_event* q = new Query_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (!q->query)
- {
- delete q;
- q=NULL;
- }
- return q;
+ UNLOCK_MUTEX;
+ return 0;
}
-
- case LOAD_EVENT:
+
+ uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
+ char *buf= 0;
+ const char *error= 0;
+ Log_event *res= 0;
+
+ if (data_len > max_allowed_packet)
{
- Load_log_event* l = new Load_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (!l->table_name)
- {
- delete l;
- l=NULL;
- }
- return l;
+ error = "Event too big";
+ goto err;
}
-
- case ROTATE_EVENT:
+ if (data_len < header_size)
{
- Rotate_log_event* r = new Rotate_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (!r->new_log_ident)
- {
- delete r;
- r=NULL;
- }
- return r;
+ error = "Event too small";
+ goto err;
}
- case INTVAR_EVENT:
+ // some events use the extra byte to null-terminate strings
+ if (!(buf = my_malloc(data_len+1, MYF(MY_WME))))
{
- Intvar_log_event* e = new Intvar_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (e->type == INVALID_INT_EVENT)
- {
- delete e;
- e=NULL;
- }
- return e;
+ error = "Out of memory";
+ goto err;
}
-
- case START_EVENT:
- {
- Start_log_event* e = new Start_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- return e;
- }
- case STOP_EVENT:
- {
- Stop_log_event* e = new Stop_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- return e;
- }
- default:
- break;
+ buf[data_len] = 0;
+ memcpy(buf, head, header_size);
+ if (my_b_read(file, (byte*) buf + header_size, data_len - header_size))
+ {
+ error = "read error";
+ goto err;
}
+ if ((res = read_log_event(buf, data_len, &error, old_format)))
+ res->register_temp_buf(buf);
- // default
- UNLOCK_MUTEX
- return NULL;
+err:
+ UNLOCK_MUTEX;
+ if (error)
+ {
+ sql_print_error("Error in Log_event::read_log_event(): '%s', \
+data_len=%d,event_type=%d",error,data_len,head[EVENT_TYPE_OFFSET]);
+ my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
+ }
+ return res;
}
-Log_event* Log_event::read_log_event(const char* buf, int event_len)
+
+Log_event* Log_event::read_log_event(const char* buf, int event_len,
+ const char **error, bool old_format)
{
- if(event_len < EVENT_LEN_OFFSET ||
- (uint)event_len != uint4korr(buf+EVENT_LEN_OFFSET))
+ if (event_len < EVENT_LEN_OFFSET ||
+ (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
+ {
+ *error="Sanity check failed"; // Needed to free buffer
return NULL; // general sanity check - will fail on a partial read
+ }
- switch(buf[EVENT_TYPE_OFFSET])
- {
+ Log_event* ev = NULL;
+
+ switch(buf[EVENT_TYPE_OFFSET]) {
case QUERY_EVENT:
- {
- Query_log_event* q = new Query_log_event(buf, event_len);
- if (!q->query)
- {
- delete q;
- return NULL;
- }
-
- return q;
- }
-
+ ev = new Query_log_event(buf, event_len, old_format);
+ break;
case LOAD_EVENT:
- {
- Load_log_event* l = new Load_log_event(buf, event_len);
- if (!l->table_name)
- {
- delete l;
- return NULL;
- }
-
- return l;
- }
-
+ ev = new Create_file_log_event(buf, event_len, old_format);
+ break;
+ case NEW_LOAD_EVENT:
+ ev = new Load_log_event(buf, event_len, old_format);
+ break;
case ROTATE_EVENT:
- {
- Rotate_log_event* r = new Rotate_log_event(buf, event_len);
- if (!r->new_log_ident)
- {
- delete r;
- return NULL;
- }
-
- return r;
- }
- case START_EVENT: return new Start_log_event(buf);
- case STOP_EVENT: return new Stop_log_event(buf);
- case INTVAR_EVENT: return new Intvar_log_event(buf);
+ ev = new Rotate_log_event(buf, event_len, old_format);
+ break;
+ case SLAVE_EVENT:
+ ev = new Slave_log_event(buf, event_len);
+ break;
+ case CREATE_FILE_EVENT:
+ ev = new Create_file_log_event(buf, event_len, old_format);
+ break;
+ case APPEND_BLOCK_EVENT:
+ ev = new Append_block_log_event(buf, event_len);
+ break;
+ case DELETE_FILE_EVENT:
+ ev = new Delete_file_log_event(buf, event_len);
+ break;
+ case EXEC_LOAD_EVENT:
+ ev = new Execute_load_log_event(buf, event_len);
+ break;
+ case START_EVENT:
+ ev = new Start_log_event(buf, old_format);
+ break;
+ case STOP_EVENT:
+ ev = new Stop_log_event(buf, old_format);
+ break;
+ case INTVAR_EVENT:
+ ev = new Intvar_log_event(buf, old_format);
+ break;
default:
break;
}
- return NULL; // default value
+ if (!ev || !ev->is_valid())
+ {
+ *error= "Found invalid event in binary log";
+ delete ev;
+ return 0;
+ }
+ ev->cached_event_len = event_len;
+ return ev;
}
+
+#ifdef MYSQL_CLIENT
void Log_event::print_header(FILE* file)
{
+ char llbuff[22];
fputc('#', file);
print_timestamp(file);
- fprintf(file, " server id %d ", server_id);
+ fprintf(file, " server id %d log_pos %s ", server_id,
+ llstr(log_pos,llbuff));
}
void Log_event::print_timestamp(FILE* file, time_t* ts)
{
-#ifdef MYSQL_SERVER
- struct tm tm_tmp;
-#endif
struct tm *res;
if (!ts)
- {
ts = &when;
- }
-#ifdef MYSQL_SERVER
+#ifdef MYSQL_SERVER // This is always false
+ struct tm tm_tmp;
localtime_r(ts,(res= &tm_tmp));
#else
res=localtime(ts);
@@ -321,6 +671,7 @@ void Stop_log_event::print(FILE* file, bool short_form, char* last_db)
void Rotate_log_event::print(FILE* file, bool short_form, char* last_db)
{
+ char buf[22];
if (short_form)
return;
@@ -329,134 +680,128 @@ void Rotate_log_event::print(FILE* file, bool short_form, char* last_db)
if (new_log_ident)
my_fwrite(file, (byte*) new_log_ident, (uint)ident_len,
MYF(MY_NABP | MY_WME));
- fprintf(file, "\n");
+ fprintf(file, " pos: %s\n", llstr(pos, buf));
fflush(file);
}
-Rotate_log_event::Rotate_log_event(IO_CACHE* file, time_t when_arg,
- uint32 server_id):
- Log_event(when_arg, 0, 0, server_id),new_log_ident(NULL),alloced(0)
-{
- char *tmp_ident;
- char buf[4];
+#endif /* #ifdef MYSQL_CLIENT */
- if (my_b_read(file, (byte*) buf, sizeof(buf)))
- return;
- ulong event_len;
- event_len = uint4korr(buf);
- if (event_len < ROTATE_EVENT_OVERHEAD)
- return;
- ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
- if (!(tmp_ident = (char*) my_malloc((uint)ident_len, MYF(MY_WME))))
- return;
- if (my_b_read( file, (byte*) tmp_ident, (uint) ident_len))
- {
- my_free((gptr) tmp_ident, MYF(0));
- return;
- }
-
- new_log_ident = tmp_ident;
- alloced = 1;
-}
-
-Start_log_event::Start_log_event(const char* buf) :Log_event(buf)
+Start_log_event::Start_log_event(const char* buf,
+ bool old_format)
+ :Log_event(buf, old_format)
{
- buf += EVENT_LEN_OFFSET + 4; // skip even length
- binlog_version = uint2korr(buf);
- memcpy(server_version, buf + 2, sizeof(server_version));
- created = uint4korr(buf + 2 + sizeof(server_version));
+ buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ binlog_version = uint2korr(buf+ST_BINLOG_VER_OFFSET);
+ memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
+ ST_SERVER_VER_LEN);
+ created = uint4korr(buf+ST_CREATED_OFFSET);
}
int Start_log_event::write_data(IO_CACHE* file)
{
- char buff[sizeof(server_version)+2+4];
- int2store(buff,binlog_version);
- memcpy(buff+2,server_version,sizeof(server_version));
- int4store(buff+2+sizeof(server_version),created);
- return (my_b_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
+ char buff[START_HEADER_LEN];
+ int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
+ memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
+ int4store(buff + ST_CREATED_OFFSET,created);
+ return (my_b_safe_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
}
-Rotate_log_event::Rotate_log_event(const char* buf, int event_len):
- Log_event(buf),new_log_ident(NULL),alloced(0)
+
+Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
+ bool old_format)
+ :Log_event(buf, old_format),new_log_ident(NULL),alloced(0)
{
- // the caller will ensure that event_len is what we have at
- // EVENT_LEN_OFFSET
- if(event_len < ROTATE_EVENT_OVERHEAD)
+ // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
+ int header_size = (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ uint ident_offset;
+ if (event_len < header_size)
return;
-
- ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
- if (!(new_log_ident = (char*) my_memdup((byte*) buf + LOG_EVENT_HEADER_LEN,
+ buf += header_size;
+ if (old_format)
+ {
+ ident_len = (uchar)(event_len - OLD_HEADER_LEN);
+ pos = 4;
+ ident_offset = 0;
+ }
+ else
+ {
+ ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
+ pos = uint8korr(buf + R_POS_OFFSET);
+ ident_offset = ROTATE_HEADER_LEN;
+ }
+ if (!(new_log_ident = (char*) my_memdup((byte*) buf + ident_offset,
(uint) ident_len, MYF(MY_WME))))
return;
alloced = 1;
}
+
int Rotate_log_event::write_data(IO_CACHE* file)
{
- return my_b_write(file, (byte*) new_log_ident, (uint) ident_len) ? -1 :0;
+ char buf[ROTATE_HEADER_LEN];
+ int8store(buf, pos + R_POS_OFFSET);
+ return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
+ my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
}
-Query_log_event::Query_log_event(IO_CACHE* file, time_t when_arg,
- uint32 server_id):
- Log_event(when_arg,0,0,server_id),data_buf(0),query(NULL),db(NULL)
-{
- char buf[QUERY_HEADER_LEN + 4];
- ulong data_len;
- if (my_b_read(file, (byte*) buf, sizeof(buf)))
- return; // query == NULL will tell the
- // caller there was a problem
- data_len = uint4korr(buf);
- if (data_len < QUERY_EVENT_OVERHEAD)
- return; // tear-drop attack protection :)
-
- data_len -= QUERY_EVENT_OVERHEAD;
- exec_time = uint4korr(buf + 8);
- db_len = (uint)buf[12];
- error_code = uint2korr(buf + 13);
-
- /* Allocate one byte extra for end \0 */
- if (!(data_buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
- return;
- if (my_b_read( file, (byte*) data_buf, data_len))
- {
- my_free((gptr) data_buf, MYF(0));
- data_buf = 0;
- return;
- }
- thread_id = uint4korr(buf + 4);
- db = data_buf;
- query=data_buf + db_len + 1;
- q_len = data_len - 1 - db_len;
- *((char*) query + q_len) = 0; // Safety
+#ifndef MYSQL_CLIENT
+Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
+ bool using_trans)
+ :Log_event(thd_arg), data_buf(0), query(query_arg), db(thd_arg->db),
+ q_len(thd_arg->query_length),
+ error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
+ thread_id(thd_arg->thread_id),
+ cache_stmt(using_trans &&
+ (thd_arg->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+{
+ time_t end_time;
+ time(&end_time);
+ exec_time = (ulong) (end_time - thd->start_time);
+ db_len = (db) ? (uint32) strlen(db) : 0;
}
+#endif
-Query_log_event::Query_log_event(const char* buf, int event_len):
- Log_event(buf),data_buf(0), query(NULL), db(NULL)
+Query_log_event::Query_log_event(const char* buf, int event_len,
+ bool old_format)
+ :Log_event(buf, old_format),data_buf(0), query(NULL), db(NULL)
{
- if ((uint)event_len < QUERY_EVENT_OVERHEAD)
- return;
ulong data_len;
- buf += EVENT_LEN_OFFSET;
- data_len = event_len - QUERY_EVENT_OVERHEAD;
+ if (old_format)
+ {
+ if ((uint)event_len < OLD_HEADER_LEN + QUERY_HEADER_LEN)
+ return;
+ data_len = event_len - (QUERY_HEADER_LEN + OLD_HEADER_LEN);
+ buf += OLD_HEADER_LEN;
+ }
+ else
+ {
+ if ((uint)event_len < QUERY_EVENT_OVERHEAD)
+ return;
+ data_len = event_len - QUERY_EVENT_OVERHEAD;
+ buf += LOG_EVENT_HEADER_LEN;
+ }
- exec_time = uint4korr(buf + 8);
- error_code = uint2korr(buf + 13);
+ exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
+ error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
if (!(data_buf = (char*) my_malloc(data_len + 1, MYF(MY_WME))))
return;
- memcpy(data_buf, buf + QUERY_HEADER_LEN + 4, data_len);
- thread_id = uint4korr(buf + 4);
+ memcpy(data_buf, buf + Q_DATA_OFFSET, data_len);
+ thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
db = data_buf;
- db_len = (uint)buf[12];
+ db_len = (uint)buf[Q_DB_LEN_OFFSET];
query=data_buf + db_len + 1;
q_len = data_len - 1 - db_len;
*((char*)query+q_len) = 0;
}
+
+#ifdef MYSQL_CLIENT
+
void Query_log_event::print(FILE* file, bool short_form, char* last_db)
{
char buff[40],*end; // Enough for SET TIMESTAMP
@@ -469,11 +814,11 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db)
bool same_db = 0;
- if(db && last_db)
- {
- if(!(same_db = !memcmp(last_db, db, db_len + 1)))
- memcpy(last_db, db, db_len + 1);
- }
+ if (db && last_db)
+ {
+ if (!(same_db = !memcmp(last_db, db, db_len + 1)))
+ memcpy(last_db, db, db_len + 1);
+ }
if (db && db[0] && !same_db)
fprintf(file, "use %s;\n", db);
@@ -484,170 +829,334 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db)
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
fprintf(file, ";\n");
}
+#endif
+
int Query_log_event::write_data(IO_CACHE* file)
{
- if (!query) return -1;
+ if (!query)
+ return -1;
char buf[QUERY_HEADER_LEN];
- char* pos = buf;
- int4store(pos, thread_id);
- pos += 4;
- int4store(pos, exec_time);
- pos += 4;
- *pos++ = (char)db_len;
- int2store(pos, error_code);
- pos += 2;
-
- return (my_b_write(file, (byte*) buf, (uint)(pos - buf)) ||
- my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
- my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
+ int4store(buf + Q_THREAD_ID_OFFSET, thread_id);
+ int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
+ buf[Q_DB_LEN_OFFSET] = (char) db_len;
+ int2store(buf + Q_ERR_CODE_OFFSET, error_code);
+
+ return (my_b_safe_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
+ my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
+ my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0;
}
-Intvar_log_event:: Intvar_log_event(IO_CACHE* file, time_t when_arg,
- uint32 server_id)
- :Log_event(when_arg,0,0,server_id), type(INVALID_INT_EVENT)
+Intvar_log_event::Intvar_log_event(const char* buf, bool old_format)
+ :Log_event(buf, old_format)
{
- char buf[9+4];
- if (!my_b_read(file, (byte*) buf, sizeof(buf)))
- {
- type = buf[4];
- val = uint8korr(buf+1+4);
- }
+ buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ type = buf[I_TYPE_OFFSET];
+ val = uint8korr(buf+I_VAL_OFFSET);
}
-Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
+const char* Intvar_log_event::get_var_type_name()
{
- buf += LOG_EVENT_HEADER_LEN;
- type = buf[0];
- val = uint8korr(buf+1);
+ switch(type) {
+ case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
+ case INSERT_ID_EVENT: return "INSERT_ID";
+ default: /* impossible */ return "UNKNOWN";
+ }
}
int Intvar_log_event::write_data(IO_CACHE* file)
{
char buf[9];
- buf[0] = type;
- int8store(buf + 1, val);
- return my_b_write(file, (byte*) buf, sizeof(buf));
+ buf[I_TYPE_OFFSET] = type;
+ int8store(buf + I_VAL_OFFSET, val);
+ return my_b_safe_write(file, (byte*) buf, sizeof(buf));
}
+#ifdef MYSQL_CLIENT
void Intvar_log_event::print(FILE* file, bool short_form, char* last_db)
{
char llbuff[22];
- if(!short_form)
+ const char *msg;
+ LINT_INIT(msg);
+
+ if (!short_form)
{
print_header(file);
fprintf(file, "\tIntvar\n");
}
fprintf(file, "SET ");
- switch(type)
- {
+ switch (type) {
case LAST_INSERT_ID_EVENT:
- fprintf(file, "LAST_INSERT_ID = ");
+ msg="LAST_INSERT_ID";
break;
case INSERT_ID_EVENT:
- fprintf(file, "INSERT_ID = ");
+ msg="INSERT_ID";
break;
}
- fprintf(file, "%s;\n", llstr(val,llbuff));
+ fprintf(file, "%s=%s;\n", msg, llstr(val,llbuff));
fflush(file);
-
}
+#endif
-int Load_log_event::write_data(IO_CACHE* file)
+
+int Load_log_event::write_data_header(IO_CACHE* file)
{
char buf[LOAD_HEADER_LEN];
- int4store(buf, thread_id);
- int4store(buf + 4, exec_time);
- int4store(buf + 8, skip_lines);
- buf[12] = (char)table_name_len;
- buf[13] = (char)db_len;
- int4store(buf + 14, num_fields);
-
- if(my_b_write(file, (byte*)buf, sizeof(buf)) ||
- my_b_write(file, (byte*)&sql_ex, sizeof(sql_ex)))
- return 1;
+ int4store(buf + L_THREAD_ID_OFFSET, thread_id);
+ int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
+ int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
+ buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
+ buf[L_DB_LEN_OFFSET] = (char)db_len;
+ int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
+ return my_b_safe_write(file, (byte*)buf, LOAD_HEADER_LEN);
+}
+int Load_log_event::write_data_body(IO_CACHE* file)
+{
+ if (sql_ex.write_data(file))
+ return 1;
if (num_fields && fields && field_lens)
{
- if(my_b_write(file, (byte*)field_lens, num_fields) ||
- my_b_write(file, (byte*)fields, field_block_len))
+ if (my_b_safe_write(file, (byte*)field_lens, num_fields) ||
+ my_b_safe_write(file, (byte*)fields, field_block_len))
return 1;
}
- if(my_b_write(file, (byte*)table_name, table_name_len + 1) ||
- my_b_write(file, (byte*)db, db_len + 1) ||
- my_b_write(file, (byte*)fname, fname_len))
+ return (my_b_safe_write(file, (byte*)table_name, table_name_len + 1) ||
+ my_b_safe_write(file, (byte*)db, db_len + 1) ||
+ my_b_safe_write(file, (byte*)fname, fname_len));
+}
+
+
+
+static bool write_str(IO_CACHE *file, char *str, byte length)
+{
+ return (my_b_safe_write(file, &length, 1) ||
+ my_b_safe_write(file, (byte*) str, (int) length));
+}
+
+
+int sql_ex_info::write_data(IO_CACHE* file)
+{
+ if (new_format())
+ {
+ return (write_str(file, field_term, field_term_len) ||
+ write_str(file, enclosed, enclosed_len) ||
+ write_str(file, line_term, line_term_len) ||
+ write_str(file, line_start, line_start_len) ||
+ write_str(file, escaped, escaped_len) ||
+ my_b_safe_write(file,(byte*) &opt_flags,1));
+ }
+ else
+ {
+ old_sql_ex old_ex;
+ old_ex.field_term= *field_term;
+ old_ex.enclosed= *enclosed;
+ old_ex.line_term= *line_term;
+ old_ex.line_start= *line_start;
+ old_ex.escaped= *escaped;
+ old_ex.opt_flags= opt_flags;
+ old_ex.empty_flags=empty_flags;
+ return my_b_safe_write(file, (byte*) &old_ex, sizeof(old_ex));
+ }
+}
+
+
+static inline int read_str(char * &buf, char *buf_end, char * &str,
+ uint8 &len)
+{
+ if (buf + (uint) (uchar) *buf >= buf_end)
return 1;
+ len = (uint8) *buf;
+ str= buf+1;
+ buf+= (uint) len+1;
return 0;
}
-Load_log_event::Load_log_event(IO_CACHE* file, time_t when, uint32 server_id):
- Log_event(when,0,0,server_id),data_buf(0),num_fields(0),
- fields(0),field_lens(0),field_block_len(0),
- table_name(0),db(0),fname(0)
+
+char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
{
- char buf[LOAD_HEADER_LEN + 4];
- ulong data_len;
- if (my_b_read(file, (byte*)buf, sizeof(buf)) ||
- my_b_read(file, (byte*)&sql_ex, sizeof(sql_ex)))
- return;
+ cached_new_format = use_new_format;
+ if (use_new_format)
+ {
+ empty_flags=0;
+ /*
+ The code below assumes that buf will not disappear from
+ under our feet during the lifetime of the event. This assumption
+ holds true in the slave thread if the log is in new format, but is not
+ the case when we have old format because we will be reusing net buffer
+ to read the actual file before we write out the Create_file event.
+ */
+ if (read_str(buf, buf_end, field_term, field_term_len) ||
+ read_str(buf, buf_end, enclosed, enclosed_len) ||
+ read_str(buf, buf_end, line_term, line_term_len) ||
+ read_str(buf, buf_end, line_start, line_start_len) ||
+ read_str(buf, buf_end, escaped, escaped_len))
+ return 0;
+ opt_flags = *buf++;
+ }
+ else
+ {
+ field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
+ field_term = buf++; // Use first byte in string
+ enclosed= buf++;
+ line_term= buf++;
+ line_start= buf++;
+ escaped= buf++;
+ opt_flags = *buf++;
+ empty_flags= *buf++;
+ if (empty_flags & FIELD_TERM_EMPTY)
+ field_term_len=0;
+ if (empty_flags & ENCLOSED_EMPTY)
+ enclosed_len=0;
+ if (empty_flags & LINE_TERM_EMPTY)
+ line_term_len=0;
+ if (empty_flags & LINE_START_EMPTY)
+ line_start_len=0;
+ if (empty_flags & ESCAPED_EMPTY)
+ escaped_len=0;
+ }
+ return buf;
+}
- data_len = uint4korr(buf) - LOAD_EVENT_OVERHEAD;
- if (!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
- return;
- if (my_b_read(file, (byte*)data_buf, data_len))
- return;
- copy_log_event(buf,data_len);
+
+#ifndef MYSQL_CLIENT
+Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
+ const char* db_arg, const char* table_name_arg,
+ List<Item>& fields_arg,
+ enum enum_duplicates handle_dup)
+ :Log_event(thd),thread_id(thd->thread_id), num_fields(0),fields(0),
+ field_lens(0),field_block_len(0),
+ table_name(table_name_arg ? table_name_arg : ""),
+ db(db_arg), fname(ex->file_name)
+{
+ time_t end_time;
+ time(&end_time);
+ exec_time = (ulong) (end_time - thd->start_time);
+ /* db can never be a zero pointer in 4.0 */
+ db_len = (uint32) strlen(db);
+ table_name_len = (uint32) strlen(table_name);
+ fname_len = (fname) ? (uint) strlen(fname) : 0;
+ sql_ex.field_term = (char*) ex->field_term->ptr();
+ sql_ex.field_term_len = (uint8) ex->field_term->length();
+ sql_ex.enclosed = (char*) ex->enclosed->ptr();
+ sql_ex.enclosed_len = (uint8) ex->enclosed->length();
+ sql_ex.line_term = (char*) ex->line_term->ptr();
+ sql_ex.line_term_len = (uint8) ex->line_term->length();
+ sql_ex.line_start = (char*) ex->line_start->ptr();
+ sql_ex.line_start_len = (uint8) ex->line_start->length();
+ sql_ex.escaped = (char*) ex->escaped->ptr();
+ sql_ex.escaped_len = (uint8) ex->escaped->length();
+ sql_ex.opt_flags = 0;
+ sql_ex.cached_new_format = -1;
+
+ if (ex->dumpfile)
+ sql_ex.opt_flags |= DUMPFILE_FLAG;
+ if (ex->opt_enclosed)
+ sql_ex.opt_flags |= OPT_ENCLOSED_FLAG;
+
+ sql_ex.empty_flags = 0;
+
+ switch (handle_dup) {
+ case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
+ case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
+ case DUP_ERROR: break;
+ }
+
+ if (!ex->field_term->length())
+ sql_ex.empty_flags |= FIELD_TERM_EMPTY;
+ if (!ex->enclosed->length())
+ sql_ex.empty_flags |= ENCLOSED_EMPTY;
+ if (!ex->line_term->length())
+ sql_ex.empty_flags |= LINE_TERM_EMPTY;
+ if (!ex->line_start->length())
+ sql_ex.empty_flags |= LINE_START_EMPTY;
+ if (!ex->escaped->length())
+ sql_ex.empty_flags |= ESCAPED_EMPTY;
+
+ skip_lines = ex->skip_lines;
+
+ List_iterator<Item> li(fields_arg);
+ field_lens_buf.length(0);
+ fields_buf.length(0);
+ Item* item;
+ while ((item = li++))
+ {
+ num_fields++;
+ uchar len = (uchar) strlen(item->name);
+ field_block_len += len + 1;
+ fields_buf.append(item->name, len + 1);
+ field_lens_buf.append((char*)&len, 1);
+ }
+
+ field_lens = (const uchar*)field_lens_buf.ptr();
+ fields = fields_buf.ptr();
}
-Load_log_event::Load_log_event(const char* buf, int event_len):
- Log_event(buf),data_buf(0),num_fields(0),fields(0),
+#endif
+
+/*
+ The caller must do buf[event_len] = 0 before he starts using the
+ constructed event.
+*/
+
+Load_log_event::Load_log_event(const char* buf, int event_len,
+ bool old_format):
+ Log_event(buf, old_format),num_fields(0),fields(0),
field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0)
{
- ulong data_len;
-
- if((uint)event_len < (LOAD_EVENT_OVERHEAD + LOG_EVENT_HEADER_LEN))
- return;
- buf += EVENT_LEN_OFFSET;
- memcpy(&sql_ex, buf + LOAD_HEADER_LEN + 4, sizeof(sql_ex));
- data_len = event_len;
-
- if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ if (!event_len) // derived class, will call copy_log_event() itself
return;
- memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len);
- copy_log_event(buf, data_len);
+ copy_log_event(buf, event_len, old_format);
}
-void Load_log_event::copy_log_event(const char *buf, ulong data_len)
+int Load_log_event::copy_log_event(const char *buf, ulong event_len,
+ bool old_format)
{
- thread_id = uint4korr(buf+4);
- exec_time = uint4korr(buf+8);
- skip_lines = uint4korr(buf + 12);
- table_name_len = (uint)buf[16];
- db_len = (uint)buf[17];
- num_fields = uint4korr(buf + 18);
+ uint data_len;
+ char* buf_end = (char*)buf + event_len;
+ const char* data_head = buf + ((old_format) ?
+ OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN);
+ thread_id = uint4korr(data_head + L_THREAD_ID_OFFSET);
+ exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
+ skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
+ table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
+ db_len = (uint)data_head[L_DB_LEN_OFFSET];
+ num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
+ int body_offset = ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
+ LOAD_HEADER_LEN + OLD_HEADER_LEN :
+ get_data_body_offset());
+
+ if ((int) event_len < body_offset)
+ return 1;
+ /*
+ Sql_ex.init() on success returns the pointer to the first byte after
+ the sql_ex structure, which is the start of field lengths array.
+ */
+ if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset,
+ buf_end,
+ buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
+ return 1;
+
+ data_len = event_len - body_offset;
if (num_fields > data_len) // simple sanity check against corruption
- return;
-
- field_lens = (uchar*) data_buf;
- uint i;
- for (i = 0; i < num_fields; i++)
- {
+ return 1;
+ for (uint i = 0; i < num_fields; i++)
field_block_len += (uint)field_lens[i] + 1;
- }
+
fields = (char*)field_lens + num_fields;
-
- *((char*)data_buf+data_len) = 0;
table_name = fields + field_block_len;
db = table_name + table_name_len + 1;
fname = db + db_len + 1;
- fname_len = data_len - 2 - db_len - table_name_len - num_fields -
- field_block_len;
+ fname_len = strlen(fname);
+ // null termination is accomplished by the caller doing buf[event_len]=0
+ return 0;
}
+#ifdef MYSQL_CLIENT
void Load_log_event::print(FILE* file, bool short_form, char* last_db)
{
@@ -659,67 +1168,66 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
}
bool same_db = 0;
-
- if(db && last_db)
- {
- if(!(same_db = !memcmp(last_db, db, db_len + 1)))
- memcpy(last_db, db, db_len + 1);
- }
+ if (db && last_db)
+ {
+ if (!(same_db = !memcmp(last_db, db, db_len + 1)))
+ memcpy(last_db, db, db_len + 1);
+ }
- if(db && db[0] && !same_db)
+ if (db && db[0] && !same_db)
fprintf(file, "use %s;\n", db);
- fprintf(file, "LOAD DATA INFILE '%s' ", fname);
+ fprintf(file, "LOAD DATA INFILE '%-*s' ", fname_len, fname);
- if(sql_ex.opt_flags && REPLACE_FLAG )
+ if (sql_ex.opt_flags && REPLACE_FLAG )
fprintf(file," REPLACE ");
- else if(sql_ex.opt_flags && IGNORE_FLAG )
+ else if (sql_ex.opt_flags && IGNORE_FLAG )
fprintf(file," IGNORE ");
fprintf(file, "INTO TABLE %s ", table_name);
- if(!(sql_ex.empty_flags & FIELD_TERM_EMPTY))
+ if (sql_ex.field_term)
{
fprintf(file, " FIELDS TERMINATED BY ");
- pretty_print_char(file, sql_ex.field_term);
+ pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len);
}
- if(!(sql_ex.empty_flags & ENCLOSED_EMPTY))
+ if (sql_ex.enclosed)
{
- if(sql_ex.opt_flags && OPT_ENCLOSED_FLAG )
+ if (sql_ex.opt_flags && OPT_ENCLOSED_FLAG )
fprintf(file," OPTIONALLY ");
fprintf(file, " ENCLOSED BY ");
- pretty_print_char(file, sql_ex.enclosed);
+ pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len);
}
- if(!(sql_ex.empty_flags & ESCAPED_EMPTY))
+ if (sql_ex.escaped)
{
fprintf(file, " ESCAPED BY ");
- pretty_print_char(file, sql_ex.escaped);
+ pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len);
}
- if(!(sql_ex.empty_flags & LINE_TERM_EMPTY))
+ if (sql_ex.line_term)
{
fprintf(file," LINES TERMINATED BY ");
- pretty_print_char(file, sql_ex.line_term);
+ pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len);
}
- if(!(sql_ex.empty_flags & LINE_START_EMPTY))
+ if (sql_ex.line_start)
{
fprintf(file," LINES STARTING BY ");
- pretty_print_char(file, sql_ex.line_start);
+ pretty_print_str(file, sql_ex.line_start, sql_ex.line_start_len);
}
- if((int)skip_lines > 0)
+ if ((int)skip_lines > 0)
fprintf(file, " IGNORE %ld LINES ", (long) skip_lines);
if (num_fields)
{
uint i;
const char* field = fields;
- fprintf( file, " (");
- for(i = 0; i < num_fields; i++)
+ fprintf(file, " (");
+ for (i = 0; i < num_fields; i++)
{
- if(i)
+ if (i)
fputc(',', file);
fprintf(file, field);
@@ -731,18 +1239,812 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
fprintf(file, ";\n");
}
+#endif /* #ifdef MYSQL_CLIENT */
+
#ifndef MYSQL_CLIENT
+void Log_event::set_log_pos(MYSQL_LOG* log)
+{
+ if (!log_pos)
+ log_pos = my_b_tell(&log->log_file);
+}
+
+
void Load_log_event::set_fields(List<Item> &fields)
{
uint i;
const char* field = this->fields;
- for(i = 0; i < num_fields; i++)
+ for (i = 0; i < num_fields; i++)
+ {
+ fields.push_back(new Item_field(db, table_name, field));
+ field += field_lens[i] + 1;
+ }
+}
+
+
+Slave_log_event::Slave_log_event(THD* thd_arg,
+ struct st_relay_log_info* rli):
+ Log_event(thd_arg),mem_pool(0),master_host(0)
+{
+ DBUG_ENTER("Slave_log_event");
+ if (!rli->inited)
+ DBUG_VOID_RETURN;
+
+ MASTER_INFO* mi = rli->mi;
+ // TODO: re-write this better without holding both locks at the same time
+ pthread_mutex_lock(&mi->data_lock);
+ pthread_mutex_lock(&rli->data_lock);
+ master_host_len = strlen(mi->host);
+ master_log_len = strlen(rli->master_log_name);
+ // on OOM, just do not initialize the structure and print the error
+ if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
+ MYF(MY_WME))))
+ {
+ master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
+ memcpy(master_host, mi->host, master_host_len + 1);
+ master_log = master_host + master_host_len + 1;
+ memcpy(master_log, rli->master_log_name, master_log_len + 1);
+ master_port = mi->port;
+ master_pos = rli->master_log_pos;
+ DBUG_PRINT("info", ("master_log: %s pos: %d", master_log,
+ (ulong) master_pos));
+ }
+ else
+ sql_print_error("Out of memory while recording slave event");
+ pthread_mutex_unlock(&rli->data_lock);
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_VOID_RETURN;
+}
+
+#endif /* ! MYSQL_CLIENT */
+
+
+Slave_log_event::~Slave_log_event()
+{
+ my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
+}
+
+#ifdef MYSQL_CLIENT
+
+void Slave_log_event::print(FILE* file, bool short_form, char* last_db)
+{
+ char llbuff[22];
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "Slave: master_host: '%s' master_port: %d \
+master_log: '%s' master_pos: %s\n",
+ master_host, master_port, master_log, llstr(master_pos, llbuff));
+}
+
+#endif /* MYSQL_CLIENT */
+
+int Slave_log_event::get_data_size()
+{
+ return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
+}
+
+int Slave_log_event::write_data(IO_CACHE* file)
+{
+ int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
+ int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
+ // log and host are already there
+ return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
+}
+
+
+void Slave_log_event::init_from_mem_pool(int data_size)
+{
+ master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
+ master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
+ master_host = mem_pool + SL_MASTER_HOST_OFFSET;
+ master_host_len = strlen(master_host);
+ // safety
+ master_log = master_host + master_host_len + 1;
+ if (master_log > mem_pool + data_size)
+ {
+ master_host = 0;
+ return;
+ }
+ master_log_len = strlen(master_log);
+}
+
+Slave_log_event::Slave_log_event(const char* buf, int event_len)
+ :Log_event(buf,0),mem_pool(0),master_host(0)
+{
+ event_len -= LOG_EVENT_HEADER_LEN;
+ if (event_len < 0)
+ return;
+ if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
+ return;
+ memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
+ mem_pool[event_len] = 0;
+ init_from_mem_pool(event_len);
+}
+
+#ifndef MYSQL_CLIENT
+Create_file_log_event::Create_file_log_event(THD* thd_arg, sql_exchange* ex,
+ const char* db_arg, const char* table_name_arg,
+ List<Item>& fields_arg, enum enum_duplicates handle_dup,
+ char* block_arg, uint block_len_arg)
+ :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup),
+ fake_base(0),block(block_arg),block_len(block_len_arg),
+ file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
+{
+ sql_ex.force_new_format();
+}
+#endif
+
+int Create_file_log_event::write_data_body(IO_CACHE* file)
+{
+ int res;
+ if ((res = Load_log_event::write_data_body(file)) || fake_base)
+ return res;
+ return (my_b_safe_write(file, (byte*) "", 1) ||
+ my_b_safe_write(file, (byte*) block, block_len));
+}
+
+int Create_file_log_event::write_data_header(IO_CACHE* file)
+{
+ int res;
+ if ((res = Load_log_event::write_data_header(file)) || fake_base)
+ return res;
+ byte buf[CREATE_FILE_HEADER_LEN];
+ int4store(buf + CF_FILE_ID_OFFSET, file_id);
+ return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN);
+}
+
+int Create_file_log_event::write_base(IO_CACHE* file)
+{
+ int res;
+ fake_base = 1; // pretend we are Load event
+ res = write(file);
+ fake_base = 0;
+ return res;
+}
+
+Create_file_log_event::Create_file_log_event(const char* buf, int len,
+ bool old_format)
+ :Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0)
+{
+ int block_offset;
+ if (copy_log_event(buf,len,old_format))
+ return;
+ if (!old_format)
+ {
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
+ + LOAD_HEADER_LEN + CF_FILE_ID_OFFSET);
+ // + 1 for \0 terminating fname
+ block_offset = (LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() +
+ CREATE_FILE_HEADER_LEN + 1);
+ if (len < block_offset)
+ return;
+ block = (char*)buf + block_offset;
+ block_len = len - block_offset;
+ }
+ else
+ {
+ sql_ex.force_new_format();
+ inited_from_old = 1;
+ }
+}
+
+
+#ifdef MYSQL_CLIENT
+void Create_file_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ if (short_form)
+ return;
+ Load_log_event::print(file, 1, last_db);
+ fprintf(file, " file_id: %d block_len: %d\n", file_id, block_len);
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+void Create_file_log_event::pack_info(String* packet)
+{
+ char buf1[256],buf[22], *end;
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append("db=");
+ tmp.append(db, db_len);
+ tmp.append(";table=");
+ tmp.append(table_name, table_name_len);
+ tmp.append(";file_id=");
+ end= int10_to_str((long) file_id, buf, 10);
+ tmp.append(buf, (uint32) (end-buf));
+ tmp.append(";block_len=");
+ end= int10_to_str((long) block_len, buf, 10);
+ tmp.append(buf, (uint32) (end-buf));
+ net_store_data(packet, (char*) tmp.ptr(), tmp.length());
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg,
+ uint block_len_arg)
+ :Log_event(thd_arg), block(block_arg),block_len(block_len_arg),
+ file_id(thd_arg->file_id)
+{
+}
+#endif
+
+Append_block_log_event::Append_block_log_event(const char* buf, int len)
+ :Log_event(buf, 0),block(0)
+{
+ if ((uint)len < APPEND_BLOCK_EVENT_OVERHEAD)
+ return;
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET);
+ block = (char*)buf + APPEND_BLOCK_EVENT_OVERHEAD;
+ block_len = len - APPEND_BLOCK_EVENT_OVERHEAD;
+}
+
+int Append_block_log_event::write_data(IO_CACHE* file)
+{
+ byte buf[APPEND_BLOCK_HEADER_LEN];
+ int4store(buf + AB_FILE_ID_OFFSET, file_id);
+ return (my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
+ my_b_safe_write(file, (byte*) block, block_len));
+}
+
+#ifdef MYSQL_CLIENT
+void Append_block_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "#Append_block: file_id: %d block_len: %d\n",
+ file_id, block_len);
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+void Append_block_log_event::pack_info(String* packet)
+{
+ char buf1[256];
+ sprintf(buf1, ";file_id=%u;block_len=%u", file_id, block_len);
+ net_store_data(packet, buf1);
+}
+
+Delete_file_log_event::Delete_file_log_event(THD* thd_arg)
+ :Log_event(thd_arg),file_id(thd_arg->file_id)
+{
+}
+#endif
+
+
+Delete_file_log_event::Delete_file_log_event(const char* buf, int len)
+ :Log_event(buf, 0),file_id(0)
+{
+ if ((uint)len < DELETE_FILE_EVENT_OVERHEAD)
+ return;
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET);
+}
+
+
+int Delete_file_log_event::write_data(IO_CACHE* file)
+{
+ byte buf[DELETE_FILE_HEADER_LEN];
+ int4store(buf + DF_FILE_ID_OFFSET, file_id);
+ return my_b_safe_write(file, buf, DELETE_FILE_HEADER_LEN);
+}
+
+#ifdef MYSQL_CLIENT
+void Delete_file_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "#Delete_file: file_id=%u\n", file_id);
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+void Delete_file_log_event::pack_info(String* packet)
+{
+ char buf1[64];
+ sprintf(buf1, ";file_id=%u", (uint) file_id);
+ net_store_data(packet, buf1);
+}
+#endif
+
+
+#ifndef MYSQL_CLIENT
+Execute_load_log_event::Execute_load_log_event(THD* thd_arg)
+ :Log_event(thd_arg),file_id(thd_arg->file_id)
+{
+}
+#endif
+
+Execute_load_log_event::Execute_load_log_event(const char* buf,int len)
+ :Log_event(buf, 0),file_id(0)
+{
+ if ((uint)len < EXEC_LOAD_EVENT_OVERHEAD)
+ return;
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + EL_FILE_ID_OFFSET);
+}
+
+int Execute_load_log_event::write_data(IO_CACHE* file)
+{
+ byte buf[EXEC_LOAD_HEADER_LEN];
+ int4store(buf + EL_FILE_ID_OFFSET, file_id);
+ return my_b_safe_write(file, buf, EXEC_LOAD_HEADER_LEN);
+}
+
+#ifdef MYSQL_CLIENT
+void Execute_load_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "#Exec_load: file_id=%d\n",
+ file_id);
+}
+#endif
+#ifndef MYSQL_CLIENT
+void Execute_load_log_event::pack_info(String* packet)
+{
+ char buf[64];
+ sprintf(buf, ";file_id=%u", (uint) file_id);
+ net_store_data(packet, buf);
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+int Query_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ int expected_error,actual_error = 0;
+ init_sql_alloc(&thd->mem_root, 8192,0);
+ thd->db = rewrite_db((char*)db);
+ DBUG_ASSERT(q_len == strlen(query));
+ if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
+ {
+ thd->query = (char*)query;
+ thd->set_time((time_t)when);
+ thd->current_tablenr = 0;
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->query_id = query_id++;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ thd->query_error = 0; // clear error
+ thd->net.last_errno = 0;
+ thd->net.last_error[0] = 0;
+ thd->slave_proxy_id = thread_id; // for temp tables
+
+ /*
+ Sanity check to make sure the master did not get a really bad
+ error on the query.
+ */
+ if (ignored_error_code((expected_error = error_code)) ||
+ !check_expected_error(thd,rli,expected_error))
{
- fields.push_back(new Item_field(db, table_name, field));
- field += field_lens[i] + 1;
+ mysql_parse(thd, thd->query, q_len);
+ if ((expected_error != (actual_error = thd->net.last_errno)) &&
+ expected_error &&
+ !ignored_error_code(actual_error) &&
+ !ignored_error_code(expected_error))
+ {
+ const char* errmsg = "Slave: did not get the expected error\
+ running query from master - expected: '%s' (%d), got '%s' (%d)";
+ sql_print_error(errmsg, ER_SAFE(expected_error),
+ expected_error,
+ actual_error ? thd->net.last_error: "no error",
+ actual_error);
+ thd->query_error = 1;
+ }
+ else if (expected_error == actual_error ||
+ ignored_error_code(actual_error))
+ {
+ thd->query_error = 0;
+ *rli->last_slave_error = 0;
+ rli->last_slave_errno = 0;
+ }
+ }
+ else
+ {
+ // master could be inconsistent, abort and tell DBA to check/fix it
+ thd->db = thd->query = 0;
+ thd->variables.convert_set = 0;
+ close_thread_tables(thd);
+ free_root(&thd->mem_root,0);
+ return 1;
}
+ }
+ thd->db= 0; // prevent db from being freed
+ thd->query= 0; // just to be sure
+ // assume no convert for next query unless set explictly
+ thd->variables.convert_set = 0;
+ close_thread_tables(thd);
+
+ if (thd->query_error || thd->fatal_error)
+ {
+ slave_print_error(rli,actual_error, "error '%s' on query '%s'",
+ actual_error ? thd->net.last_error :
+ "unexpected success or fatal error", query);
+ free_root(&thd->mem_root,0);
+ return 1;
+ }
+ free_root(&thd->mem_root,0);
+ return Log_event::exec_event(rli);
+}
+
+
+int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
+{
+ init_sql_alloc(&thd->mem_root, 8192,0);
+ thd->db = rewrite_db((char*)db);
+ thd->query = 0;
+ thd->query_error = 0;
+
+ if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
+ {
+ thd->set_time((time_t)when);
+ thd->current_tablenr = 0;
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->query_id = query_id++;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+
+ TABLE_LIST tables;
+ bzero((char*) &tables,sizeof(tables));
+ tables.db = thd->db;
+ tables.name = tables.real_name = (char*)table_name;
+ tables.lock_type = TL_WRITE;
+ // the table will be opened in mysql_load
+ if (table_rules_on && !tables_ok(thd, &tables))
+ {
+ // TODO: this is a bug - this needs to be moved to the I/O thread
+ if (net)
+ skip_load_data_infile(net);
+ }
+ else
+ {
+ char llbuff[22];
+ enum enum_duplicates handle_dup = DUP_IGNORE;
+ if (sql_ex.opt_flags && REPLACE_FLAG)
+ handle_dup = DUP_REPLACE;
+ sql_exchange ex((char*)fname, sql_ex.opt_flags &&
+ DUMPFILE_FLAG );
+ String field_term(sql_ex.field_term,sql_ex.field_term_len);
+ String enclosed(sql_ex.enclosed,sql_ex.enclosed_len);
+ String line_term(sql_ex.line_term,sql_ex.line_term_len);
+ String line_start(sql_ex.line_start,sql_ex.line_start_len);
+ String escaped(sql_ex.escaped,sql_ex.escaped_len);
+
+ ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
+ if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
+ ex.field_term->length(0);
+
+ ex.skip_lines = skip_lines;
+ List<Item> fields;
+ set_fields(fields);
+ thd->slave_proxy_id = thd->thread_id;
+ if (net)
+ {
+ // mysql_load will use thd->net to read the file
+ thd->net.vio = net->vio;
+ /*
+ Make sure the client does not get confused about the packet sequence
+ */
+ thd->net.pkt_nr = net->pkt_nr;
+ }
+ if (mysql_load(thd, &ex, &tables, fields, handle_dup, net != 0,
+ TL_WRITE))
+ thd->query_error = 1;
+ if (thd->cuted_fields)
+ sql_print_error("Slave: load data infile at position %s in log \
+'%s' produced %d warning(s)", llstr(rli->master_log_pos,llbuff), RPL_LOG_NAME,
+ thd->cuted_fields );
+ if (net)
+ net->pkt_nr= thd->net.pkt_nr;
+ }
+ }
+ else
+ {
+ /*
+ We will just ask the master to send us /dev/null if we do not
+ want to load the data.
+ TODO: this a bug - needs to be done in I/O thread
+ */
+ if (net)
+ skip_load_data_infile(net);
+ }
+
+ thd->net.vio = 0;
+ thd->db= 0; // prevent db from being freed
+ close_thread_tables(thd);
+ if (thd->query_error)
+ {
+ int sql_error = thd->net.last_errno;
+ if (!sql_error)
+ sql_error = ER_UNKNOWN_ERROR;
+
+ slave_print_error(rli,sql_error,
+ "Slave: Error '%s' running load data infile ",
+ ER_SAFE(sql_error));
+ free_root(&thd->mem_root,0);
+ return 1;
+ }
+ free_root(&thd->mem_root,0);
+
+ if (thd->fatal_error)
+ {
+ sql_print_error("Slave: Fatal error running LOAD DATA INFILE ");
+ return 1;
+ }
+
+ return Log_event::exec_event(rli);
+}
+
+
+int Start_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ close_temporary_tables(thd);
+ /*
+ If we have old format, load_tmpdir is cleaned up by the I/O thread
+
+ TODO: cleanup_load_tmpdir() needs to remove only the files associated
+ with the server id that has just started
+ */
+ if (!rli->mi->old_format)
+ cleanup_load_tmpdir();
+ return Log_event::exec_event(rli);
+}
+
+
+int Stop_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ // do not clean up immediately after rotate event
+ if (rli->master_log_pos > BIN_LOG_HEADER_SIZE)
+ {
+ close_temporary_tables(thd);
+ cleanup_load_tmpdir();
+ }
+ /*
+ We do not want to update master_log pos because we get a rotate event
+ before stop, so by now master_log_name is set to the next log
+ if we updated it, we will have incorrect master coordinates and this
+ could give false triggers in MASTER_POS_WAIT() that we have reached
+ the targed position when in fact we have not
+ */
+ rli->inc_pos(get_event_len(), 0);
+ flush_relay_log_info(rli);
+ return 0;
+}
+
+int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ bool rotate_binlog = 0, write_slave_event = 0;
+ char* log_name = rli->master_log_name;
+ DBUG_ENTER("Rotate_log_event::exec_event");
+
+ pthread_mutex_lock(&rli->data_lock);
+ /*
+ TODO: probably needs re-write
+ rotate local binlog only if the name of remote has changed
+ */
+ if (!*log_name || !(log_name[ident_len] == 0 &&
+ !memcmp(log_name, new_log_ident, ident_len)))
+ {
+ write_slave_event = (!(flags & LOG_EVENT_FORCED_ROTATE_F)
+ && mysql_bin_log.is_open());
+ rotate_binlog = (*log_name && write_slave_event);
+ if (ident_len >= sizeof(rli->master_log_name))
+ {
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(1);
+ }
+ memcpy(log_name, new_log_ident,ident_len);
+ log_name[ident_len] = 0;
+ }
+ rli->master_log_pos = pos;
+ rli->relay_log_pos += get_event_len();
+ if (rotate_binlog)
+ {
+ mysql_bin_log.new_file();
+ rli->master_log_pos = 4;
+ }
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) rli->master_log_pos));
+ pthread_cond_broadcast(&rli->data_cond);
+ pthread_mutex_unlock(&rli->data_lock);
+ flush_relay_log_info(rli);
+
+ if (write_slave_event)
+ {
+ Slave_log_event s(thd, rli);
+ if (s.master_host)
+ {
+ s.set_log_pos(&mysql_bin_log);
+ s.server_id = ::server_id;
+ mysql_bin_log.write(&s);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+int Intvar_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ switch (type) {
+ case LAST_INSERT_ID_EVENT:
+ thd->last_insert_id_used = 1;
+ thd->last_insert_id = val;
+ break;
+ case INSERT_ID_EVENT:
+ thd->next_insert_id = val;
+ break;
+ }
+ rli->inc_pending(get_event_len());
+ return 0;
+}
+
+int Slave_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ if (mysql_bin_log.is_open())
+ mysql_bin_log.write(this);
+ return Log_event::exec_event(rli);
+}
+
+int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname_buf[FN_REFLEN+10];
+ char *p;
+ int fd = -1;
+ IO_CACHE file;
+ int error = 1;
+
+ bzero((char*)&file, sizeof(file));
+ p = slave_load_file_stem(fname_buf, file_id, server_id);
+ strmov(p, ".info"); // strmov takes less code than memcpy
+ if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
+ MYF(MY_WME))) < 0 ||
+ init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
+ MYF(MY_WME|MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf);
+ goto err;
+ }
+ // a trick to avoid allocating another buffer
+ strmov(p, ".data");
+ fname = fname_buf;
+ fname_len = (uint)(p-fname) + 5;
+ if (write_base(&file))
+ {
+ strmov(p, ".info"); // to have it right in the error message
+ slave_print_error(rli,my_errno, "Could not write to file '%s'", fname_buf);
+ goto err;
+ }
+ end_io_cache(&file);
+ my_close(fd, MYF(0));
+
+ // fname_buf now already has .data, not .info, because we did our trick
+ if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
+ MYF(MY_WME))) < 0)
+ {
+ slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf);
+ goto err;
+ }
+ if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf);
+ goto err;
+ }
+ if (mysql_bin_log.is_open())
+ mysql_bin_log.write(this);
+ error=0; // Everything is ok
+
+err:
+ if (error)
+ end_io_cache(&file);
+ if (fd >= 0)
+ my_close(fd, MYF(0));
+ return error ? 1 : Log_event::exec_event(rli);
}
-#endif
+int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname[FN_REFLEN+10];
+ char *p= slave_load_file_stem(fname, file_id, server_id);
+ memcpy(p, ".data", 6);
+ (void) my_delete(fname, MYF(MY_WME));
+ memcpy(p, ".info", 6);
+ (void) my_delete(fname, MYF(MY_WME));
+ if (mysql_bin_log.is_open())
+ mysql_bin_log.write(this);
+ return Log_event::exec_event(rli);
+}
+
+int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname[FN_REFLEN+10];
+ char *p= slave_load_file_stem(fname, file_id, server_id);
+ int fd;
+ int error = 1;
+
+ memcpy(p, ".data", 6);
+ if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
+ {
+ slave_print_error(rli,my_errno, "Could not open file '%s'", fname);
+ goto err;
+ }
+ if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Write to '%s' failed", fname);
+ goto err;
+ }
+ if (mysql_bin_log.is_open())
+ mysql_bin_log.write(this);
+ error=0;
+
+err:
+ if (fd >= 0)
+ my_close(fd, MYF(0));
+ return error ? error : Log_event::exec_event(rli);
+}
+
+int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname[FN_REFLEN+10];
+ char *p= slave_load_file_stem(fname, file_id, server_id);
+ int fd;
+ int error = 1;
+ ulong save_options;
+ IO_CACHE file;
+ Load_log_event* lev = 0;
+
+ memcpy(p, ".info", 6);
+ if ((fd = my_open(fname, O_RDONLY|O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
+ MYF(MY_WME|MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Could not open file '%s'", fname);
+ goto err;
+ }
+ if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
+ (pthread_mutex_t*)0,
+ (bool)0)) ||
+ lev->get_type_code() != NEW_LOAD_EVENT)
+ {
+ slave_print_error(rli,0, "File '%s' appears corrupted", fname);
+ goto err;
+ }
+ /*
+ We want to disable binary logging in slave thread because we need the file
+ events to appear in the same order as they do on the master relative to
+ other events, so that we can preserve ascending order of log sequence
+ numbers - needed to handle failover .
+ */
+ save_options = thd->options;
+ thd->options &= ~ (ulong) (OPTION_BIN_LOG);
+ lev->thd = thd;
+ if (lev->exec_event(0,0))
+ {
+ slave_print_error(rli,my_errno, "Failed executing load from '%s'", fname);
+ thd->options = save_options;
+ goto err;
+ }
+ thd->options = save_options;
+ (void) my_delete(fname, MYF(MY_WME));
+ memcpy(p, ".data", 6);
+ (void) my_delete(fname, MYF(MY_WME));
+ if (mysql_bin_log.is_open())
+ mysql_bin_log.write(this);
+ error = 0;
+
+err:
+ delete lev;
+ if (fd >= 0)
+ {
+ my_close(fd, MYF(0));
+ end_io_cache(&file);
+ }
+ return error ? error : Log_event::exec_event(rli);
+}
+
+#endif /* !MYSQL_CLIENT */
diff --git a/sql/log_event.h b/sql/log_event.h
index 7cd84a8c001..9b8145f14b0 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -15,8 +15,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef _LOG_EVENT_H
-#define _LOG_EVENT_H
+#ifndef _log_event_h
+#define _log_event_h
#ifdef __EMX__
#undef write // remove pthread.h macro definition, conflict with write() class member
@@ -34,46 +34,230 @@
#define LOG_READ_TOO_LARGE -7
#define LOG_EVENT_OFFSET 4
-#define BINLOG_VERSION 1
+#define BINLOG_VERSION 3
+
+/*
+ We could have used SERVER_VERSION_LENGTH, but this introduces an
+ obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
+ this would have broke the replication protocol
+*/
+#define ST_SERVER_VER_LEN 50
+
+#define DUMPFILE_FLAG 0x1
+#define OPT_ENCLOSED_FLAG 0x2
+#define REPLACE_FLAG 0x4
+#define IGNORE_FLAG 0x8
+
+#define FIELD_TERM_EMPTY 0x1
+#define ENCLOSED_EMPTY 0x2
+#define LINE_TERM_EMPTY 0x4
+#define LINE_START_EMPTY 0x8
+#define ESCAPED_EMPTY 0x10
+
+struct old_sql_ex
+{
+ char field_term;
+ char enclosed;
+ char line_term;
+ char line_start;
+ char escaped;
+ char opt_flags;
+ char empty_flags;
+};
+
+#define NUM_LOAD_DELIM_STRS 5
+
+struct sql_ex_info
+{
+ char* field_term;
+ char* enclosed;
+ char* line_term;
+ char* line_start;
+ char* escaped;
+ int cached_new_format;
+ uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len;
+ char opt_flags;
+ char empty_flags;
+
+ // store in new format even if old is possible
+ void force_new_format() { cached_new_format = 1;}
+ int data_size()
+ {
+ return (new_format() ?
+ field_term_len + enclosed_len + line_term_len +
+ line_start_len + escaped_len + 6 : 7);
+ }
+ int write_data(IO_CACHE* file);
+ char* init(char* buf,char* buf_end,bool use_new_format);
+ bool new_format()
+ {
+ return ((cached_new_format != -1) ? cached_new_format :
+ (cached_new_format=(field_term_len > 1 ||
+ enclosed_len > 1 ||
+ line_term_len > 1 || line_start_len > 1 ||
+ escaped_len > 1)));
+ }
+};
+
+/*
+ Binary log consists of events. Each event has a fixed length header,
+ followed by possibly variable ( depending on the type of event) length
+ data body. The data body consists of an optional fixed length segment
+ (post-header), and an optional variable length segment. See #defines and
+ comments below for the format specifics
+*/
+
+/* event-specific post-header sizes */
+#define LOG_EVENT_HEADER_LEN 19
+#define OLD_HEADER_LEN 13
+#define QUERY_HEADER_LEN (4 + 4 + 1 + 2)
+#define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4)
+#define START_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4)
+#define ROTATE_HEADER_LEN 8
+#define CREATE_FILE_HEADER_LEN 4
+#define APPEND_BLOCK_HEADER_LEN 4
+#define EXEC_LOAD_HEADER_LEN 4
+#define DELETE_FILE_HEADER_LEN 4
+
+/* event header offsets */
-#define LOG_EVENT_HEADER_LEN 13
-#define QUERY_HEADER_LEN (sizeof(uint32) + sizeof(uint32) + \
- sizeof(uchar) + sizeof(uint16))
-#define LOAD_HEADER_LEN (sizeof(uint32) + sizeof(uint32) + \
- + sizeof(uint32) + 2 + sizeof(uint32))
-#define EVENT_LEN_OFFSET 9
#define EVENT_TYPE_OFFSET 4
-#define QUERY_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
-#define ROTATE_EVENT_OVERHEAD LOG_EVENT_HEADER_LEN
-#define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN+sizeof(sql_ex_info))
+#define SERVER_ID_OFFSET 5
+#define EVENT_LEN_OFFSET 9
+#define LOG_POS_OFFSET 13
+#define FLAGS_OFFSET 17
+
+/* start event post-header */
+
+#define ST_BINLOG_VER_OFFSET 0
+#define ST_SERVER_VER_OFFSET 2
+#define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
+
+/* slave event post-header */
+
+#define SL_MASTER_PORT_OFFSET 8
+#define SL_MASTER_POS_OFFSET 0
+#define SL_MASTER_HOST_OFFSET 10
+
+/* query event post-header */
+
+#define Q_THREAD_ID_OFFSET 0
+#define Q_EXEC_TIME_OFFSET 4
+#define Q_DB_LEN_OFFSET 8
+#define Q_ERR_CODE_OFFSET 9
+#define Q_DATA_OFFSET QUERY_HEADER_LEN
+
+/* Intvar event post-header */
+
+#define I_TYPE_OFFSET 0
+#define I_VAL_OFFSET 1
+
+/* Load event post-header */
+
+#define L_THREAD_ID_OFFSET 0
+#define L_EXEC_TIME_OFFSET 4
+#define L_SKIP_LINES_OFFSET 8
+#define L_TBL_LEN_OFFSET 12
+#define L_DB_LEN_OFFSET 13
+#define L_NUM_FIELDS_OFFSET 14
+#define L_SQL_EX_OFFSET 18
+#define L_DATA_OFFSET LOAD_HEADER_LEN
+
+/* Rotate event post-header */
+
+#define R_POS_OFFSET 0
+#define R_IDENT_OFFSET 8
+
+#define CF_FILE_ID_OFFSET 0
+#define CF_DATA_OFFSET CREATE_FILE_HEADER_LEN
+
+#define AB_FILE_ID_OFFSET 0
+#define AB_DATA_OFFSET APPEND_BLOCK_HEADER_LEN
+
+#define EL_FILE_ID_OFFSET 0
+
+#define DF_FILE_ID_OFFSET 0
+
+#define QUERY_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
+#define QUERY_DATA_OFFSET (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
+#define ROTATE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+ROTATE_HEADER_LEN)
+#define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN)
+#define CREATE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+\
+ +LOAD_HEADER_LEN+CREATE_FILE_HEADER_LEN)
+#define DELETE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+DELETE_FILE_HEADER_LEN)
+#define EXEC_LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+EXEC_LOAD_HEADER_LEN)
+#define APPEND_BLOCK_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+APPEND_BLOCK_HEADER_LEN)
+
#define BINLOG_MAGIC "\xfe\x62\x69\x6e"
-enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2,
- STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5,
- LOAD_EVENT=6};
-enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
- };
+#define LOG_EVENT_TIME_F 0x1
+#define LOG_EVENT_FORCED_ROTATE_F 0x2
+
+enum Log_event_type
+{
+ START_EVENT = 1, QUERY_EVENT =2, STOP_EVENT=3, ROTATE_EVENT = 4,
+ INTVAR_EVENT=5, LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8,
+ APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11,
+ NEW_LOAD_EVENT=12
+};
+
+enum Int_event_type
+{
+ INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
+};
+
#ifndef MYSQL_CLIENT
class String;
+class MYSQL_LOG;
+class THD;
#endif
-extern uint32 server_id;
+struct st_relay_log_info;
class Log_event
{
public:
time_t when;
ulong exec_time;
- int valid_exec_time; // if false, the exec time setting is bogus
uint32 server_id;
+ my_off_t log_pos;
+ uint16 flags;
+ int cached_event_len;
+ char* temp_buf;
+
+#ifndef MYSQL_CLIENT
+ THD* thd;
+
+ Log_event(THD* thd_arg, uint16 flags_arg = 0);
+ // if mutex is 0, the read will proceed without mutex
+ static Log_event* read_log_event(IO_CACHE* file,
+ pthread_mutex_t* log_lock,
+ bool old_format);
+ static int read_log_event(IO_CACHE* file, String* packet,
+ pthread_mutex_t* log_lock);
+ void set_log_pos(MYSQL_LOG* log);
+ virtual void pack_info(String* packet);
+ int net_send(THD* thd, const char* log_name, my_off_t pos);
+ static void init_show_field_list(List<Item>* field_list);
+ virtual int exec_event(struct st_relay_log_info* rli);
+ virtual const char* get_db()
+ {
+ return thd ? thd->db : 0;
+ }
+#else
+ // avoid having to link mysqlbinlog against libpthread
+ static Log_event* read_log_event(IO_CACHE* file, bool old_format);
+ virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
+ void print_timestamp(FILE* file, time_t *ts = 0);
+ void print_header(FILE* file);
+#endif
static void *operator new(size_t size)
{
return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
}
-
static void operator delete(void *ptr, size_t size)
{
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
@@ -81,43 +265,36 @@ public:
int write(IO_CACHE* file);
int write_header(IO_CACHE* file);
- virtual int write_data(IO_CACHE* file __attribute__((unused))) { return 0; }
+ virtual int write_data(IO_CACHE* file)
+ { return write_data_header(file) || write_data_body(file); }
+ virtual int write_data_header(IO_CACHE* file __attribute__((unused)))
+ { return 0; }
+ virtual int write_data_body(IO_CACHE* file __attribute__((unused)))
+ { return 0; }
virtual Log_event_type get_type_code() = 0;
- Log_event(time_t when_arg, ulong exec_time_arg = 0,
- int valid_exec_time_arg = 0, uint32 server_id_arg = 0):
- when(when_arg), exec_time(exec_time_arg),
- valid_exec_time(valid_exec_time_arg)
+ virtual bool is_valid() = 0;
+ virtual bool get_cache_stmt() { return 0; }
+ Log_event(const char* buf, bool old_format);
+ virtual ~Log_event() { free_temp_buf();}
+ void register_temp_buf(char* buf) { temp_buf = buf; }
+ void free_temp_buf()
{
- server_id = server_id_arg ? server_id_arg : (::server_id);
+ if (temp_buf)
+ {
+ my_free(temp_buf, MYF(0));
+ temp_buf = 0;
+ }
}
-
- Log_event(const char* buf): valid_exec_time(0)
+ virtual int get_data_size() { return 0;}
+ virtual int get_data_body_offset() { return 0; }
+ int get_event_len()
{
- when = uint4korr(buf);
- server_id = uint4korr(buf + 5);
+ return (cached_event_len ? cached_event_len :
+ (cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()));
}
-
- virtual ~Log_event() {}
-
- virtual int get_data_size() { return 0;}
- virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
-
- void print_timestamp(FILE* file, time_t *ts = 0);
- void print_header(FILE* file);
-
-#ifndef MYSQL_CLIENT
- // if mutex is 0, the read will proceed without mutex
- static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
-#else // avoid having to link mysqlbinlog against libpthread
- static Log_event* read_log_event(IO_CACHE* file);
-#endif
- static Log_event* read_log_event(const char* buf, int event_len);
-
-#ifndef MYSQL_CLIENT
- static int read_log_event(IO_CACHE* file, String* packet,
- pthread_mutex_t* log_lock);
-#endif
-
+ static Log_event* read_log_event(const char* buf, int event_len,
+ const char **error, bool old_format);
+ const char* get_type_str();
};
@@ -128,35 +305,29 @@ protected:
public:
const char* query;
const char* db;
- uint32 q_len; // if we already know the length of the query string
- // we pass it here, so we would not have to call strlen()
- // otherwise, set it to 0, in which case, we compute it with strlen()
+ /*
+ If we already know the length of the query string
+ we pass it with q_len, so we would not have to call strlen()
+ otherwise, set it to 0, in which case, we compute it with strlen()
+ */
+ uint32 q_len;
uint32 db_len;
uint16 error_code;
ulong thread_id;
-#if !defined(MYSQL_CLIENT)
- THD* thd;
+#ifndef MYSQL_CLIENT
bool cache_stmt;
- Query_log_event(THD* thd_arg, const char* query_arg, bool using_trans=0):
- Log_event(thd_arg->start_time,0,1,thd_arg->server_id), data_buf(0),
- query(query_arg), db(thd_arg->db), q_len(thd_arg->query_length),
- error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
- thread_id(thd_arg->thread_id), thd(thd_arg),
- cache_stmt(using_trans &&
- (thd_arg->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
- {
- time_t end_time;
- time(&end_time);
- exec_time = (ulong) (end_time - thd->start_time);
- db_len = (db) ? (uint32) strlen(db) : 0;
- // do not log stray system errors such as EE_WRITE
- if (error_code < ERRMOD)
- error_code = 0;
- }
+
+ Query_log_event(THD* thd_arg, const char* query_arg,
+ bool using_trans=0);
+ const char* get_db() { return db; }
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+ bool get_cache_stmt() { return cache_stmt; }
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
- Query_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg);
- Query_log_event(const char* buf, int event_len);
+ Query_log_event(const char* buf, int event_len, bool old_format);
~Query_log_event()
{
if (data_buf)
@@ -167,46 +338,51 @@ public:
Log_event_type get_type_code() { return QUERY_EVENT; }
int write(IO_CACHE* file);
int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
+ bool is_valid() { return query != 0; }
int get_data_size()
{
- return q_len + db_len + 2 +
- sizeof(uint32) // thread_id
- + sizeof(uint32) // exec_time
- + sizeof(uint16) // error_code
- ;
+ return (q_len + db_len + 2
+ + 4 // thread_id
+ + 4 // exec_time
+ + 2 // error_code
+ );
}
-
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
};
-#define DUMPFILE_FLAG 0x1
-#define OPT_ENCLOSED_FLAG 0x2
-#define REPLACE_FLAG 0x4
-#define IGNORE_FLAG 0x8
-#define FIELD_TERM_EMPTY 0x1
-#define ENCLOSED_EMPTY 0x2
-#define LINE_TERM_EMPTY 0x4
-#define LINE_START_EMPTY 0x8
-#define ESCAPED_EMPTY 0x10
+class Slave_log_event: public Log_event
+{
+protected:
+ char* mem_pool;
+ void init_from_mem_pool(int data_size);
+public:
+ my_off_t master_pos;
+ char* master_host;
+ char* master_log;
+ int master_host_len;
+ int master_log_len;
+ uint16 master_port;
+#ifndef MYSQL_CLIENT
+ Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
-struct sql_ex_info
- {
- char field_term;
- char enclosed;
- char line_term;
- char line_start;
- char escaped;
- char opt_flags; // flags for the options
- char empty_flags; // flags to indicate which of the terminating charact
- } ;
+ Slave_log_event(const char* buf, int event_len);
+ ~Slave_log_event();
+ int get_data_size();
+ bool is_valid() { return master_host != 0; }
+ Log_event_type get_type_code() { return SLAVE_EVENT; }
+ int write_data(IO_CACHE* file );
+};
class Load_log_event: public Log_event
{
protected:
- char* data_buf;
- void copy_log_event(const char *buf, ulong data_len);
+ int copy_log_event(const char *buf, ulong event_len, bool old_format);
public:
ulong thread_id;
@@ -217,7 +393,6 @@ public:
const char* fields;
const uchar* field_lens;
uint32 field_block_len;
-
const char* table_name;
const char* db;
@@ -225,101 +400,43 @@ public:
uint32 skip_lines;
sql_ex_info sql_ex;
-#if !defined(MYSQL_CLIENT)
- THD* thd;
+#ifndef MYSQL_CLIENT
String field_lens_buf;
String fields_buf;
- Load_log_event(THD* thd, sql_exchange* ex,
- const char *db_arg, const char* table_name_arg,
- List<Item>& fields_arg, enum enum_duplicates handle_dup ):
- Log_event(thd->start_time),data_buf(0),thread_id(thd->thread_id),
- num_fields(0),fields(0),field_lens(0),field_block_len(0),
- table_name(table_name_arg ? table_name_arg : ""),
- db(db_arg ? db_arg : ""),
- fname(ex->file_name),
- thd(thd)
+
+ Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
+ const char* table_name_arg,
+ List<Item>& fields_arg, enum enum_duplicates handle_dup);
+ void set_fields(List<Item> &fields_arg);
+ void pack_info(String* packet);
+ const char* get_db() { return db; }
+ int exec_event(struct st_relay_log_info* rli)
{
- time_t end_time;
- time(&end_time);
- exec_time = (ulong) (end_time - thd->start_time);
- valid_exec_time = 1;
- db_len = (uint32) strlen(db);
- table_name_len = (uint32) strlen(table_name);
- fname_len = (fname) ? (uint) strlen(fname) : 0;
- sql_ex.field_term = (*ex->field_term)[0];
- sql_ex.enclosed = (*ex->enclosed)[0];
- sql_ex.line_term = (*ex->line_term)[0];
- sql_ex.line_start = (*ex->line_start)[0];
- sql_ex.escaped = (*ex->escaped)[0];
- sql_ex.opt_flags = 0;
- if(ex->dumpfile)
- sql_ex.opt_flags |= DUMPFILE_FLAG;
- if(ex->opt_enclosed)
- sql_ex.opt_flags |= OPT_ENCLOSED_FLAG;
-
- sql_ex.empty_flags = 0;
-
- switch(handle_dup) {
- case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
- case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
- case DUP_ERROR: break;
- }
-
- if(!ex->field_term->length())
- sql_ex.empty_flags |= FIELD_TERM_EMPTY;
- if(!ex->enclosed->length())
- sql_ex.empty_flags |= ENCLOSED_EMPTY;
- if(!ex->line_term->length())
- sql_ex.empty_flags |= LINE_TERM_EMPTY;
- if(!ex->line_start->length())
- sql_ex.empty_flags |= LINE_START_EMPTY;
- if(!ex->escaped->length())
- sql_ex.empty_flags |= ESCAPED_EMPTY;
-
- skip_lines = ex->skip_lines;
-
- List_iterator<Item> li(fields_arg);
- field_lens_buf.length(0);
- fields_buf.length(0);
- Item* item;
- while((item = li++))
- {
- num_fields++;
- uchar len = (uchar) strlen(item->name);
- field_block_len += len + 1;
- fields_buf.append(item->name, len + 1);
- field_lens_buf.append((char*)&len, 1);
- }
-
- field_lens = (const uchar*)field_lens_buf.ptr();
- fields = fields_buf.ptr();
+ return exec_event(thd->slave_net,rli);
}
- void set_fields(List<Item> &fields_arg);
+ int exec_event(NET* net, struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
- Load_log_event(IO_CACHE * file, time_t when, uint32 server_id_arg);
- Load_log_event(const char* buf, int event_len);
+ Load_log_event(const char* buf, int event_len, bool old_format);
~Load_log_event()
- {
- if (data_buf)
- {
- my_free((gptr) data_buf, MYF(0));
- }
- }
- Log_event_type get_type_code() { return LOAD_EVENT; }
- int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
+ {}
+ Log_event_type get_type_code() { return sql_ex.new_format() ?
+ NEW_LOAD_EVENT: LOAD_EVENT; }
+ int write_data_header(IO_CACHE* file);
+ int write_data_body(IO_CACHE* file);
+ bool is_valid() { return table_name != 0; }
int get_data_size()
{
- return table_name_len + 2 + db_len + 2 + fname_len
- + 4 // thread_id
- + 4 // exec_time
- + 4 // skip_lines
- + 4 // field block len
- + sizeof(sql_ex) + field_block_len + num_fields*sizeof(uchar) ;
- ;
+ return (table_name_len + 2 + db_len + 2 + fname_len
+ + 4 // thread_id
+ + 4 // exec_time
+ + 4 // skip_lines
+ + 4 // field block len
+ + sql_ex.data_size() + field_block_len + num_fields);
}
-
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
+ int get_data_body_offset() { return LOAD_EVENT_OVERHEAD; }
};
extern char server_version[SERVER_VERSION_LENGTH];
@@ -329,101 +446,234 @@ class Start_log_event: public Log_event
public:
uint32 created;
uint16 binlog_version;
- char server_version[50];
-
- Start_log_event() :Log_event(time(NULL)),binlog_version(BINLOG_VERSION)
+ char server_version[ST_SERVER_VER_LEN];
+
+#ifndef MYSQL_CLIENT
+ Start_log_event() :Log_event((THD*)0),binlog_version(BINLOG_VERSION)
{
created = (uint32) when;
- memcpy(server_version, ::server_version, sizeof(server_version));
+ memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
}
- Start_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id_arg) :
- Log_event(when_arg, 0, 0, server_id_arg)
- {
- char buf[sizeof(server_version) + 2 + 4 + 4];
- if (my_b_read(file, (byte*) buf, sizeof(buf)))
- return;
- binlog_version = uint2korr(buf+4);
- memcpy(server_version, buf + 6, sizeof(server_version));
- server_version[sizeof(server_version)-1]=0;
- created = uint4korr(buf + 6 + sizeof(server_version));
- }
- Start_log_event(const char* buf);
-
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Start_log_event(const char* buf, bool old_format);
~Start_log_event() {}
Log_event_type get_type_code() { return START_EVENT;}
int write_data(IO_CACHE* file);
+ bool is_valid() { return 1; }
int get_data_size()
{
- // sizeof(binlog_version) + sizeof(server_version) sizeof(created)
- return 2 + sizeof(server_version) + 4;
+ return START_HEADER_LEN;
}
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
};
+
class Intvar_log_event: public Log_event
{
public:
ulonglong val;
uchar type;
- Intvar_log_event(uchar type_arg, ulonglong val_arg)
- :Log_event(time(NULL)),val(val_arg),type(type_arg)
+
+#ifndef MYSQL_CLIENT
+ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
+ :Log_event(thd_arg),val(val_arg),type(type_arg)
{}
- Intvar_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg);
- Intvar_log_event(const char* buf);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Intvar_log_event(const char* buf, bool old_format);
~Intvar_log_event() {}
Log_event_type get_type_code() { return INTVAR_EVENT;}
+ const char* get_var_type_name();
int get_data_size() { return sizeof(type) + sizeof(val);}
int write_data(IO_CACHE* file);
-
-
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
+ bool is_valid() { return 1; }
};
+
class Stop_log_event: public Log_event
{
public:
- Stop_log_event() :Log_event(time(NULL))
+#ifndef MYSQL_CLIENT
+ Stop_log_event() :Log_event((THD*)0)
+ {}
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Stop_log_event(const char* buf, bool old_format):
+ Log_event(buf, old_format)
{}
- Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id_arg):
- Log_event(when_arg,0,0,server_id_arg)
- {
- byte skip[4];
- my_b_read(file, skip, sizeof(skip)); // skip the event length
- }
- Stop_log_event(const char* buf):Log_event(buf)
- {
- }
~Stop_log_event() {}
Log_event_type get_type_code() { return STOP_EVENT;}
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
+ bool is_valid() { return 1; }
};
+
class Rotate_log_event: public Log_event
{
public:
const char* new_log_ident;
uchar ident_len;
+ ulonglong pos;
bool alloced;
-
- Rotate_log_event(const char* new_log_ident_arg, uint ident_len_arg = 0) :
- Log_event(time(NULL)),
- new_log_ident(new_log_ident_arg),
- ident_len(ident_len_arg ? ident_len_arg : (uint) strlen(new_log_ident_arg)),
+#ifndef MYSQL_CLIENT
+ Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
+ uint ident_len_arg = 0,ulonglong pos_arg = 4)
+ : Log_event(thd_arg), new_log_ident(new_log_ident_arg),
+ ident_len(ident_len_arg ? ident_len_arg :
+ (uint) strlen(new_log_ident_arg)), pos(pos_arg),
alloced(0)
{}
-
- Rotate_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg) ;
- Rotate_log_event(const char* buf, int event_len);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Rotate_log_event(const char* buf, int event_len, bool old_format);
~Rotate_log_event()
{
if (alloced)
my_free((gptr) new_log_ident, MYF(0));
}
Log_event_type get_type_code() { return ROTATE_EVENT;}
- int get_data_size() { return ident_len;}
+ int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
+ bool is_valid() { return new_log_ident != 0; }
int write_data(IO_CACHE* file);
-
+};
+
+/* the classes below are for the new LOAD DATA INFILE logging */
+
+class Create_file_log_event: public Load_log_event
+{
+protected:
+ /*
+ Pretend we are Load event, so we can write out just
+ our Load part - used on the slave when writing event out to
+ SQL_LOAD-*.info file
+ */
+ bool fake_base;
+public:
+ char* block;
+ uint block_len;
+ uint file_id;
+ bool inited_from_old;
+
+#ifndef MYSQL_CLIENT
+ Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
+ const char* table_name_arg,
+ List<Item>& fields_arg,
+ enum enum_duplicates handle_dup,
+ char* block_arg, uint block_len_arg);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Create_file_log_event(const char* buf, int event_len, bool old_format);
+ ~Create_file_log_event() {}
+
+ Log_event_type get_type_code()
+ {
+ return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
+ }
+ int get_data_size()
+ {
+ return (fake_base ? Load_log_event::get_data_size() :
+ Load_log_event::get_data_size() +
+ 4 + 1 + block_len);
+ }
+ int get_data_body_offset()
+ {
+ return (fake_base ? LOAD_EVENT_OVERHEAD:
+ LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_LEN);
+ }
+ bool is_valid() { return inited_from_old || block != 0; }
+ int write_data_header(IO_CACHE* file);
+ int write_data_body(IO_CACHE* file);
+ /*
+ Cut out Create_file extentions and
+ write it as Load event - used on the slave
+ */
+ int write_base(IO_CACHE* file);
};
+
+class Append_block_log_event: public Log_event
+{
+public:
+ char* block;
+ uint block_len;
+ uint file_id;
+
+#ifndef MYSQL_CLIENT
+ Append_block_log_event(THD* thd, char* block_arg,
+ uint block_len_arg);
+ int exec_event(struct st_relay_log_info* rli);
+ void pack_info(String* packet);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
+
+ Append_block_log_event(const char* buf, int event_len);
+ ~Append_block_log_event() {}
+ Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
+ int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
+ bool is_valid() { return block != 0; }
+ int write_data(IO_CACHE* file);
+};
+
+
+class Delete_file_log_event: public Log_event
+{
+public:
+ uint file_id;
+
+#ifndef MYSQL_CLIENT
+ Delete_file_log_event(THD* thd);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Delete_file_log_event(const char* buf, int event_len);
+ ~Delete_file_log_event() {}
+ Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
+ int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
+ bool is_valid() { return file_id != 0; }
+ int write_data(IO_CACHE* file);
+};
+
+class Execute_load_log_event: public Log_event
+{
+public:
+ uint file_id;
+
+#ifndef MYSQL_CLIENT
+ Execute_load_log_event(THD* thd);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Execute_load_log_event(const char* buf, int event_len);
+ ~Execute_load_log_event() {}
+ Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
+ int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
+ bool is_valid() { return file_id != 0; }
+ int write_data(IO_CACHE* file);
+};
+
+#endif /* _log_event_h */
diff --git a/sql/matherr.c b/sql/matherr.c
index 8523a78ce94..ea0c15d2feb 100644
--- a/sql/matherr.c
+++ b/sql/matherr.c
@@ -1,22 +1,22 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Fix that we got POSTFIX_ERROR when doing unreasonable math (not core) */
-#include <global.h>
+#include <my_global.h>
#include <errno.h>
/* Fix that we gets POSTFIX_ERROR when error in math */
diff --git a/sql/md5.c b/sql/md5.c
deleted file mode 100644
index 4c2e80107b8..00000000000
--- a/sql/md5.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
-*/
-
-/*
- Changes by Monty:
- Replace of MD5_memset and MD5_memcpy with memset & memcpy
-*/
-
-#include <global.h>
-#include <m_string.h>
-#include "md5.h"
-
-/* Constants for MD5Transform routine. */
-
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-
-static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
-static void Encode PROTO_LIST
- ((unsigned char *, UINT4 *, unsigned int));
-static void Decode PROTO_LIST
- ((UINT4 *, unsigned char *, unsigned int));
-#ifdef OLD_CODE
-static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
-#else
-#define MD5_memcpy(A,B,C) memcpy((char*) (A),(char*) (B), (C))
-#define MD5_memset(A,B,C) memset((char*) (A),(B), (C))
-#endif
-
-static unsigned char PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context.
- */
-void MD5Init (MD5_CTX *context) /* context */
-{
- context->count[0] = context->count[1] = 0;
- /* Load magic initialization constants.
-*/
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/* MD5 block update operation. Continues an MD5 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void MD5Update (
-MD5_CTX *context, /* context */
-unsigned char *input, /* input block */
-unsigned int inputLen) /* length of input block */
-{
- unsigned int i, idx, partLen;
-
- /* Compute number of bytes mod 64 */
- idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
-
- /* Update number of bits */
- if ((context->count[0] += ((UINT4)inputLen << 3))
- < ((UINT4)inputLen << 3))
- context->count[1]++;
- context->count[1] += ((UINT4)inputLen >> 29);
-
- partLen = 64 - idx;
-
- /* Transform as many times as possible.
-*/
- if (inputLen >= partLen) {
- MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
- MD5Transform(context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD5Transform (context->state, &input[i]);
-
- idx = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
- inputLen-i);
-}
-
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
- the message digest and zeroizing the context.
- */
-void MD5Final (
-unsigned char digest[16], /* message digest */
-MD5_CTX *context) /* context */
-{
- unsigned char bits[8];
- unsigned int idx, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64.
-*/
- idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (idx < 56) ? (56 - idx) : (120 - idx);
- MD5Update (context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5Update (context, bits, 8);
-
- /* Store state in digest */
- Encode (digest, context->state, 16);
-
- /* Zeroize sensitive information.
-*/
- MD5_memset ((POINTER)context, 0, sizeof (*context));
-}
-
-/* MD5 basic transformation. Transforms state based on block.
- */
-static void MD5Transform (
-UINT4 state[4],
-unsigned char block[64])
-{
- UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information.
-*/
- MD5_memset ((POINTER)x, 0, sizeof (x));
-}
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
- a multiple of 4.
- */
-static void Encode (
-unsigned char *output,
-UINT4 *input,
-unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (unsigned char)(input[i] & 0xff);
- output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
- output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
- output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
- }
-}
-
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
- a multiple of 4.
- */
-static void Decode (
-UINT4 *output,
-unsigned char *input,
-unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
- (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
-
-/* Note: Replace "for loop" with standard memcpy if possible.
- */
-
-#ifndef MD5_memcpy
-static void MD5_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- output[i] = input[i];
-}
-#endif
-
-/* Note: Replace "for loop" with standard memset if possible.
- */
-
-#ifndef MD5_memset
-static void MD5_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
-}
-#endif
diff --git a/sql/md5.h b/sql/md5.h
deleted file mode 100644
index 862129391f1..00000000000
--- a/sql/md5.h
+++ /dev/null
@@ -1,80 +0,0 @@
-
-/* MD5.H - header file for MD5C.C
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/* GLOBAL.H - RSAREF types and constants
- */
-
-/* PROTOTYPES should be set to one if and only if the compiler supports
- function argument prototyping.
-The following makes PROTOTYPES default to 0 if it has not already
- been defined with C compiler flags.
- */
-
-/* egcs 1.1.2 under linux didn't defined it.... :( */
-
-#ifndef PROTOTYPES
-#define PROTOTYPES 1 /* Assume prototypes */
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-
-/* UINT2 defines a two byte word */
-typedef uint16 UINT2; /* Fix for MySQL / Alpha */
-
-/* UINT4 defines a four byte word */
-typedef uint32 UINT4; /* Fix for MySQL / Alpha */
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
-If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
- returns an empty list.
- */
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else
-#define PROTO_LIST(list) ()
-#endif
-
-
-/* MD5 context. */
-typedef struct {
- UINT4 state[4]; /* state (ABCD) */
- UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
- unsigned char buffer[64]; /* input buffer */
-} MD5_CTX;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void MD5Init PROTO_LIST ((MD5_CTX *));
- void MD5Update PROTO_LIST
- ((MD5_CTX *, unsigned char *, unsigned int));
- void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc
index cddacaa820f..1bc65eebd23 100644
--- a/sql/mf_iocache.cc
+++ b/sql/mf_iocache.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -42,293 +42,6 @@ static void my_aiowait(my_aio_result *result);
extern "C" {
/*
- ** if cachesize == 0 then use default cachesize (from s-file)
- ** if file == -1 then real_open_cached_file() will be called.
- ** returns 0 if ok
- */
-
-int init_io_cache(IO_CACHE *info, File file, uint cachesize,
- enum cache_type type, my_off_t seek_offset,
- pbool use_async_io, myf cache_myflags)
-{
- uint min_cache;
- DBUG_ENTER("init_io_cache");
- DBUG_PRINT("enter",("type: %d pos: %ld",(int) type, (ulong) seek_offset));
-
- /* There is no file in net_reading */
- info->file= file;
- if (!cachesize)
- if (! (cachesize= my_default_record_cache_size))
- DBUG_RETURN(1); /* No cache requested */
- min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
- if (type == READ_CACHE)
- { /* Assume file isn't growing */
- if (cache_myflags & MY_DONT_CHECK_FILESIZE)
- {
- cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
- }
- else
- {
- my_off_t file_pos,end_of_file;
- if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
- DBUG_RETURN(1);
- end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
- if (end_of_file < seek_offset)
- end_of_file=seek_offset;
- VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
- if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
- {
- cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No nead to use async */
- }
- }
- }
- if ((int) type < (int) READ_NET)
- {
- for (;;)
- {
- cachesize=(uint) ((ulong) (cachesize + min_cache-1) &
- (ulong) ~(min_cache-1));
- if (cachesize < min_cache)
- cachesize = min_cache;
- if ((info->buffer=
- (byte*) my_malloc(cachesize,
- MYF((cache_myflags & ~ MY_WME) |
- (cachesize == min_cache ? MY_WME : 0)))) != 0)
- break; /* Enough memory found */
- if (cachesize == min_cache)
- DBUG_RETURN(2); /* Can't alloc cache */
- cachesize= (uint) ((long) cachesize*3/4); /* Try with less memory */
- }
- }
- else
- info->buffer=0;
- DBUG_PRINT("info",("init_io_cache: cachesize = %u",cachesize));
- info->pos_in_file= seek_offset;
- info->read_length=info->buffer_length=cachesize;
- info->seek_not_done= test(file >= 0 && type != READ_FIFO &&
- type != READ_NET);
- info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
- info->rc_request_pos=info->rc_pos=info->buffer;
-
- if (type == READ_CACHE || type == READ_NET || type == READ_FIFO)
- {
- info->rc_end=info->buffer; /* Nothing in cache */
- }
- else /* type == WRITE_CACHE */
- {
- info->rc_end=info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
- }
- /* end_of_file may be changed by user later */
- info->end_of_file= ((type == READ_NET || type == READ_FIFO ) ? 0
- : ~(my_off_t) 0);
- info->type=type;
- info->error=0;
- info->read_function=(type == READ_NET) ? _my_b_net_read : _my_b_read; /* net | file */
-#ifdef HAVE_AIOWAIT
- if (use_async_io && ! my_disable_async_io)
- {
- DBUG_PRINT("info",("Using async io"));
- info->read_length/=2;
- info->read_function=_my_b_async_read;
- }
- info->inited=info->aio_result.pending=0;
-#endif
- DBUG_RETURN(0);
-} /* init_io_cache */
-
-
- /* Wait until current request is ready */
-
-#ifdef HAVE_AIOWAIT
-static void my_aiowait(my_aio_result *result)
-{
- if (result->pending)
- {
- struct aio_result_t *tmp;
- for (;;)
- {
- if ((int) (tmp=aiowait((struct timeval *) 0)) == -1)
- {
- if (errno == EINTR)
- continue;
- DBUG_PRINT("error",("No aio request, error: %d",errno));
- result->pending=0; /* Assume everythings is ok */
- break;
- }
- ((my_aio_result*) tmp)->pending=0;
- if ((my_aio_result*) tmp == result)
- break;
- }
- }
- return;
-}
-#endif
-
- /* Use this to reset cache to start or other type */
- /* Some simple optimizing is done when reinit in current buffer */
-
-my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
- my_off_t seek_offset,
- pbool use_async_io __attribute__((unused)),
- pbool clear_cache)
-{
- DBUG_ENTER("reinit_io_cache");
-
- info->seek_not_done= test(info->file >= 0); /* Seek not done */
-
- /* If the whole file is in memory, avoid flushing to disk */
- if (! clear_cache &&
- seek_offset >= info->pos_in_file &&
- seek_offset <= info->pos_in_file +
- (uint) (info->rc_end - info->rc_request_pos))
- { /* use current buffer */
- if (info->type == WRITE_CACHE && type == READ_CACHE)
- {
- info->rc_end=info->rc_pos;
- info->end_of_file=my_b_tell(info);
- }
- else if (type == WRITE_CACHE)
- {
- if (info->type == READ_CACHE)
- info->rc_end=info->buffer+info->buffer_length;
- info->end_of_file = ~(my_off_t) 0;
- }
- info->rc_pos=info->rc_request_pos+(seek_offset-info->pos_in_file);
-#ifdef HAVE_AIOWAIT
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
-#endif
- }
- else
- {
- /*
- If we change from WRITE_CACHE to READ_CACHE, assume that everything
- after the current positions should be ignored
- */
- if (info->type == WRITE_CACHE && type == READ_CACHE)
- info->end_of_file=my_b_tell(info);
- /* No need to flush cache if we want to reuse it */
- if ((type != WRITE_CACHE || !clear_cache) && flush_io_cache(info))
- DBUG_RETURN(1);
- if (info->pos_in_file != seek_offset)
- {
- info->pos_in_file=seek_offset;
- info->seek_not_done=1;
- }
- info->rc_request_pos=info->rc_pos=info->buffer;
- if (type == READ_CACHE || type == READ_NET || type == READ_FIFO)
- {
- info->rc_end=info->buffer; /* Nothing in cache */
- }
- else
- {
- info->rc_end=info->buffer+info->buffer_length-
- (seek_offset & (IO_SIZE-1));
- info->end_of_file= ((type == READ_NET || type == READ_FIFO) ? 0 :
- ~(my_off_t) 0);
- }
- }
- info->type=type;
- info->error=0;
- info->read_function=(type == READ_NET) ? _my_b_net_read : _my_b_read;
-#ifdef HAVE_AIOWAIT
- if (type != READ_NET)
- {
- if (use_async_io && ! my_disable_async_io &&
- ((ulong) info->buffer_length <
- (ulong) (info->end_of_file - seek_offset)))
- {
- info->read_length=info->buffer_length/2;
- info->read_function=_my_b_async_read;
- }
- }
- info->inited=0;
-#endif
- DBUG_RETURN(0);
-} /* init_io_cache */
-
-
-
- /*
- Read buffered. Returns 1 if can't read requested characters
- This function is only called from the my_b_read() macro
- when there isn't enough characters in the buffer to
- satisfy the request.
- Returns 0 we succeeded in reading all data
- */
-
-int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
-{
- uint length,diff_length,left_length;
- my_off_t max_length, pos_in_file;
-
- if ((left_length=(uint) (info->rc_end-info->rc_pos)))
- {
- dbug_assert(Count >= left_length); /* User is not using my_b_read() */
- memcpy(Buffer,info->rc_pos, (size_t) (left_length));
- Buffer+=left_length;
- Count-=left_length;
- }
- /* pos_in_file always point on where info->buffer was read */
- pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
- if (info->seek_not_done)
- { /* File touched, do seek */
- VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
- info->seek_not_done=0;
- }
- diff_length=(uint) (pos_in_file & (IO_SIZE-1));
- if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length)))
- { /* Fill first intern buffer */
- uint read_length;
- if (info->end_of_file == pos_in_file)
- { /* End of file */
- info->error=(int) left_length;
- return 1;
- }
- length=(Count & (uint) ~(IO_SIZE-1))-diff_length;
- if ((read_length=my_read(info->file,Buffer,(uint) length,info->myflags))
- != (uint) length)
- {
- info->error= read_length == (uint) -1 ? -1 :
- (int) (read_length+left_length);
- return 1;
- }
- Count-=length;
- Buffer+=length;
- pos_in_file+=length;
- left_length+=length;
- diff_length=0;
- }
- max_length=info->read_length-diff_length;
- if (info->type != READ_FIFO &&
- (info->end_of_file - pos_in_file) < max_length)
- max_length = info->end_of_file - pos_in_file;
- if (!max_length)
- {
- if (Count)
- {
- info->error= left_length; /* We only got this many char */
- return 1;
- }
- length=0; /* Didn't read any chars */
- }
- else if ((length=my_read(info->file,info->buffer,(uint) max_length,
- info->myflags)) < Count ||
- length == (uint) -1)
- {
- if (length != (uint) -1)
- memcpy(Buffer,info->buffer,(size_t) length);
- info->error= length == (uint) -1 ? -1 : (int) (length+left_length);
- return 1;
- }
- info->rc_pos=info->buffer+Count;
- info->rc_end=info->buffer+length;
- info->pos_in_file=pos_in_file;
- memcpy(Buffer,info->buffer,(size_t) Count);
- return 0;
-}
-
- /*
** Read buffered from the net.
** Returns 1 if can't read requested characters
** Returns 0 if record read
@@ -337,353 +50,34 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
int _my_b_net_read(register IO_CACHE *info, byte *Buffer,
uint Count __attribute__((unused)))
{
- int read_length;
+ ulong read_length;
NET *net= &(current_thd)->net;
+ DBUG_ENTER("_my_b_net_read");
- if (info->end_of_file)
- return 1; /* because my_b_get (no _) takes 1 byte at a time */
+ if (!info->end_of_file)
+ DBUG_RETURN(1); /* because my_b_get (no _) takes 1 byte at a time */
read_length=my_net_read(net);
- if (read_length == (int) packet_error)
+ if (read_length == packet_error)
{
info->error= -1;
- return 1;
+ DBUG_RETURN(1);
}
if (read_length == 0)
{
- /* End of file from client */
- info->end_of_file = 1; return 1;
+ info->end_of_file= 0; /* End of file from client */
+ DBUG_RETURN(1);
}
/* to set up stuff for my_b_get (no _) */
- info->rc_end = (info->rc_pos = (byte*) net->read_pos) + read_length;
- Buffer[0] = info->rc_pos[0]; /* length is always 1 */
- info->rc_pos++;
- return 0;
-}
-
-#ifdef HAVE_AIOWAIT
-
-int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
-{
- uint length,read_length,diff_length,left_length,use_length,org_Count;
- my_off_t max_length;
- my_off_t next_pos_in_file;
- byte *read_buffer;
-
- memcpy(Buffer,info->rc_pos,
- (size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
- Buffer+=left_length;
- org_Count=Count;
- Count-=left_length;
-
- if (info->inited)
- { /* wait for read block */
- info->inited=0; /* No more block to read */
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
- if (info->aio_result.result.aio_errno)
- {
- if (info->myflags & MY_WME)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(info->file),
- info->aio_result.result.aio_errno);
- my_errno=info->aio_result.result.aio_errno;
- info->error= -1;
- return(1);
- }
- if (! (read_length = (uint) info->aio_result.result.aio_return) ||
- read_length == (uint) -1)
- {
- my_errno=0; /* For testing */
- info->error= (read_length == (uint) -1 ? -1 :
- (int) (read_length+left_length));
- return(1);
- }
- info->pos_in_file+=(uint) (info->rc_end - info->rc_request_pos);
-
- if (info->rc_request_pos != info->buffer)
- info->rc_request_pos=info->buffer;
- else
- info->rc_request_pos=info->buffer+info->read_length;
- info->rc_pos=info->rc_request_pos;
- next_pos_in_file=info->aio_read_pos+read_length;
-
- /* Check if pos_in_file is changed
- (_ni_read_cache may have skipped some bytes) */
-
- if (info->aio_read_pos < info->pos_in_file)
- { /* Fix if skipped bytes */
- if (info->aio_read_pos + read_length < info->pos_in_file)
- {
- read_length=0; /* Skipp block */
- next_pos_in_file=info->pos_in_file;
- }
- else
- {
- my_off_t offset= (info->pos_in_file - info->aio_read_pos);
- info->pos_in_file=info->aio_read_pos; /* Whe are here */
- info->rc_pos=info->rc_request_pos+offset;
- read_length-=offset; /* Bytes left from rc_pos */
- }
- }
-#ifndef DBUG_OFF
- if (info->aio_read_pos > info->pos_in_file)
- {
- my_errno=EINVAL;
- return(info->read_length= -1);
- }
-#endif
- /* Copy found bytes to buffer */
- length=min(Count,read_length);
- memcpy(Buffer,info->rc_pos,(size_t) length);
- Buffer+=length;
- Count-=length;
- left_length+=length;
- info->rc_end=info->rc_pos+read_length;
- info->rc_pos+=length;
- }
- else
- next_pos_in_file=(info->pos_in_file+ (uint)
- (info->rc_end - info->rc_request_pos));
-
- /* If reading large blocks, or first read or read with skipp */
- if (Count)
- {
- if (next_pos_in_file == info->end_of_file)
- {
- info->error=(int) (read_length+left_length);
- return 1;
- }
- VOID(my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0)));
- read_length=IO_SIZE*2- (uint) (next_pos_in_file & (IO_SIZE-1));
- if (Count < read_length)
- { /* Small block, read to cache */
- if ((read_length=my_read(info->file,info->rc_request_pos,
- read_length, info->myflags)) == (uint) -1)
- return info->error= -1;
- use_length=min(Count,read_length);
- memcpy(Buffer,info->rc_request_pos,(size_t) use_length);
- info->rc_pos=info->rc_request_pos+Count;
- info->rc_end=info->rc_request_pos+read_length;
- info->pos_in_file=next_pos_in_file; /* Start of block in cache */
- next_pos_in_file+=read_length;
-
- if (Count != use_length)
- { /* Didn't find hole block */
- if (info->myflags & (MY_WME | MY_FAE | MY_FNABP) && Count != org_Count)
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(info->file),my_errno);
- info->error=(int) (read_length+left_length);
- return 1;
- }
- }
- else
- { /* Big block, don't cache it */
- if ((read_length=my_read(info->file,Buffer,(uint) Count,info->myflags))
- != Count)
- {
- info->error= read_length == (uint) -1 ? -1 : read_length+left_length;
- return 1;
- }
- info->rc_pos=info->rc_end=info->rc_request_pos;
- info->pos_in_file=(next_pos_in_file+=Count);
- }
- }
-
- /* Read next block with asyncronic io */
- max_length=info->end_of_file - next_pos_in_file;
- diff_length=(next_pos_in_file & (IO_SIZE-1));
-
- if (max_length > (my_off_t) info->read_length - diff_length)
- max_length= (my_off_t) info->read_length - diff_length;
- if (info->rc_request_pos != info->buffer)
- read_buffer=info->buffer;
- else
- read_buffer=info->buffer+info->read_length;
- info->aio_read_pos=next_pos_in_file;
- if (max_length)
- {
- info->aio_result.result.aio_errno=AIO_INPROGRESS; /* Marker for test */
- DBUG_PRINT("aioread",("filepos: %ld length: %ld",
- (ulong) next_pos_in_file,(ulong) max_length));
- if (aioread(info->file,read_buffer,(int) max_length,
- (my_off_t) next_pos_in_file,MY_SEEK_SET,
- &info->aio_result.result))
- { /* Skipp async io */
- my_errno=errno;
- DBUG_PRINT("error",("got error: %d, aio_result: %d from aioread, async skipped",
- errno, info->aio_result.result.aio_errno));
- if (info->rc_request_pos != info->buffer)
- {
- bmove(info->buffer,info->rc_request_pos,
- (uint) (info->rc_end - info->rc_pos));
- info->rc_request_pos=info->buffer;
- info->rc_pos-=info->read_length;
- info->rc_end-=info->read_length;
- }
- info->read_length=info->buffer_length; /* Use hole buffer */
- info->read_function=_my_b_read; /* Use normal IO_READ next */
- }
- else
- info->inited=info->aio_result.pending=1;
- }
- return 0; /* Block read, async in use */
-} /* _my_b_async_read */
-#endif
-
-
-/* Read one byte when buffer is empty */
-
-int _my_b_get(IO_CACHE *info)
-{
- byte buff;
- if ((*(info)->read_function)(info,&buff,1))
- return my_b_EOF;
- return (int) (uchar) buff;
-}
-
- /* Returns != 0 if error on write */
-
-int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
-{
- uint rest_length,length;
-
- rest_length=(uint) (info->rc_end - info->rc_pos);
- memcpy(info->rc_pos,Buffer,(size_t) rest_length);
- Buffer+=rest_length;
- Count-=rest_length;
- info->rc_pos+=rest_length;
- if (info->pos_in_file+info->buffer_length > info->end_of_file)
- {
- my_errno=errno=EFBIG;
- return info->error = -1;
- }
- if (flush_io_cache(info))
- return 1;
- if (Count >= IO_SIZE)
- { /* Fill first intern buffer */
- length=Count & (uint) ~(IO_SIZE-1);
- if (info->seek_not_done)
- { /* File touched, do seek */
- VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)));
- info->seek_not_done=0;
- }
- if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
- return info->error= -1;
- Count-=length;
- Buffer+=length;
- info->pos_in_file+=length;
- }
- memcpy(info->rc_pos,Buffer,(size_t) Count);
- info->rc_pos+=Count;
- return 0;
-}
-
-
-/*
- Write a block to disk where part of the data may be inside the record
- buffer. As all write calls to the data goes through the cache,
- we will never get a seek over the end of the buffer
-*/
-
-int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
- my_off_t pos)
-{
- uint length;
- int error=0;
-
- if (pos < info->pos_in_file)
- {
- /* Of no overlap, write everything without buffering */
- if (pos + Count <= info->pos_in_file)
- return my_pwrite(info->file, Buffer, Count, pos,
- info->myflags | MY_NABP);
- /* Write the part of the block that is before buffer */
- length= (uint) (info->pos_in_file - pos);
- if (my_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
- info->error=error=-1;
- Buffer+=length;
- pos+= length;
- Count-= length;
- }
-
- /* Check if we want to write inside the used part of the buffer.*/
- length= (uint) (info->rc_end - info->buffer);
- if (pos < info->pos_in_file + length)
- {
- uint offset= (uint) (pos - info->pos_in_file);
- length-=offset;
- if (length > Count)
- length=Count;
- memcpy(info->buffer+offset, Buffer, length);
- Buffer+=length;
- Count-= length;
- /* Fix length of buffer if the new data was larger */
- if (info->buffer+length > info->rc_pos)
- info->rc_pos=info->buffer+length;
- if (!Count)
- return (error);
- }
- /* Write at the end of the current buffer; This is the normal case */
- if (_my_b_write(info, Buffer, Count))
- error= -1;
- return error;
-}
-
- /* Flush write cache */
-
-int flush_io_cache(IO_CACHE *info)
-{
- uint length;
- DBUG_ENTER("flush_io_cache");
-
- if (info->type == WRITE_CACHE)
- {
- if (info->file == -1)
- {
- if (real_open_cached_file(info))
- DBUG_RETURN((info->error= -1));
- }
- if (info->rc_pos != info->buffer)
- {
- length=(uint) (info->rc_pos - info->buffer);
- if (info->seek_not_done)
- { /* File touched, do seek */
- if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
- MY_FILEPOS_ERROR)
- DBUG_RETURN((info->error= -1));
- info->seek_not_done=0;
- }
- info->rc_pos=info->buffer;
- info->pos_in_file+=length;
- info->rc_end=(info->buffer+info->buffer_length-
- (info->pos_in_file & (IO_SIZE-1)));
- if (my_write(info->file,info->buffer,length,info->myflags | MY_NABP))
- DBUG_RETURN((info->error= -1));
- DBUG_RETURN(0);
- }
- }
-#ifdef HAVE_AIOWAIT
- else if (info->type != READ_NET)
- {
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
- info->inited=0;
- }
-#endif
+ info->read_end = (info->read_pos = (byte*) net->read_pos) + read_length;
+ Buffer[0] = info->read_pos[0]; /* length is always 1 */
+ info->read_pos++;
+
+ /*
+ info->request_pos is used by log_loaded_block() to know the size
+ of the current block
+ */
+ info->request_pos=info->read_pos;
DBUG_RETURN(0);
}
-
-int end_io_cache(IO_CACHE *info)
-{
- int error=0;
- DBUG_ENTER("end_io_cache");
- if (info->buffer)
- {
- if (info->file != -1) /* File doesn't exist */
- error=flush_io_cache(info);
- my_free((gptr) info->buffer,MYF(MY_WME));
- info->buffer=info->rc_pos=(byte*) 0;
- }
- DBUG_RETURN(error);
-} /* end_io_cache */
-
} /* extern "C" */
diff --git a/sql/mini_client.cc b/sql/mini_client.cc
index 453f27822d9..f6a5d6af8ae 100644
--- a/sql/mini_client.cc
+++ b/sql/mini_client.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,27 +20,17 @@
Note: all file-global symbols must begin with mc_ , even the static ones, just
in case we decide to make them external at some point
- */
-
-#define DONT_USE_RAID
-#if defined(__WIN__)
-#include <winsock.h>
-#include <odbcinst.h>
-/* Disable alarms */
-typedef my_bool ALARM;
-#define thr_alarm_init(A) (*(A))=0
-#define thr_alarm_in_use(A) (*(A))
-#define thr_end_alarm(A)
-#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
-inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
-{
- *A=1;
- return 0;
-}
-#define thr_got_alarm(A) 0
-#endif
+*/
-#include <global.h>
+#include <my_global.h>
+/* my_pthread must be included early to be able to fix things */
+#if defined(THREAD)
+#include <my_pthread.h> /* because of signal() */
+#endif
+#include <thr_alarm.h>
+#include <mysql_embed.h>
+#include <mysql_com.h>
+#include <violite.h>
#include <my_sys.h>
#include <mysys_err.h>
#include <m_string.h>
@@ -50,15 +40,12 @@ inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __a
#include "mysql_version.h"
#include "mysqld_error.h"
#include "errmsg.h"
-#include <violite.h>
-#if defined( OS2) && defined( MYSQL_SERVER)
+#if defined( OS2) && defined(MYSQL_SERVER)
#undef ER
#define ER CER
#endif
-extern ulong net_read_timeout;
-
extern "C" { // Because of SCO 3.2V4.2
#include <sys/stat.h>
#include <signal.h>
@@ -76,23 +63,31 @@ extern "C" { // Because of SCO 3.2V4.2
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
-#endif
+#endif /*!defined(MSDOS) && !defined(__WIN__) */
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
-#if defined(THREAD)
-#include <my_pthread.h> /* because of signal() */
-#include <thr_alarm.h>
-#endif
#ifndef INADDR_NONE
#define INADDR_NONE -1
#endif
-
}
-static void mc_end_server(MYSQL *mysql);
+static void mc_free_rows(MYSQL_DATA *cur);
+static MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
+ my_bool default_value,
+ my_bool long_flag_protocol);
+
+void mc_end_server(MYSQL *mysql);
static int mc_sock_connect(File s, const struct sockaddr *name, uint namelen, uint to);
static void mc_free_old_query(MYSQL *mysql);
+static int mc_send_file_to_server(MYSQL *mysql, const char *filename);
+static my_ulonglong mc_net_field_length_ll(uchar **packet);
+static ulong mc_net_field_length(uchar **packet);
+static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
+ ulong *lengths);
+static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ uint fields);
+
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
@@ -189,8 +184,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
** Init MySQL structure or allocate one
****************************************************************************/
-MYSQL * STDCALL
-mc_mysql_init(MYSQL *mysql)
+MYSQL *mc_mysql_init(MYSQL *mysql)
{
init_client_errs();
if (!mysql)
@@ -213,7 +207,7 @@ mc_mysql_init(MYSQL *mysql)
** Shut down connection
**************************************************************************/
-static void
+void
mc_end_server(MYSQL *mysql)
{
DBUG_ENTER("mc_end_server");
@@ -335,11 +329,11 @@ static int mc_sock_connect(my_socket s, const struct sockaddr *name,
** or packet is an error message
*****************************************************************************/
-uint STDCALL
+ulong
mc_net_safe_read(MYSQL *mysql)
{
NET *net= &mysql->net;
- uint len=0;
+ ulong len=0;
if (net->vio != 0)
len=my_net_read(net);
@@ -351,7 +345,7 @@ mc_net_safe_read(MYSQL *mysql)
if (socket_errno != SOCKET_EINTR)
{
mc_end_server(mysql);
- if(net->last_errno != ER_NET_PACKET_TOO_LARGE)
+ if (net->last_errno != ER_NET_PACKET_TOO_LARGE)
{
net->last_errno=CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
@@ -372,7 +366,7 @@ max_allowed_packet on this server");
net->last_errno=uint2korr(pos);
pos+=2;
len-=2;
- if(!net->last_errno)
+ if (!net->last_errno)
net->last_errno = CR_UNKNOWN_ERROR;
}
else
@@ -396,17 +390,18 @@ max_allowed_packet on this server");
}
-char * STDCALL mc_mysql_error(MYSQL *mysql)
+char *mc_mysql_error(MYSQL *mysql)
{
return (mysql)->net.last_error;
}
-int STDCALL mc_mysql_errno(MYSQL *mysql)
+int mc_mysql_errno(MYSQL *mysql)
{
return (mysql)->net.last_errno;
}
-my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
+
+my_bool mc_mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
DBUG_ENTER("mc_mysql_reconnect");
@@ -417,8 +412,8 @@ my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
mc_mysql_init(&tmp_mysql);
tmp_mysql.options=mysql->options;
if (!mc_mysql_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
- mysql->db, mysql->port, mysql->unix_socket,
- mysql->client_flag))
+ mysql->db, mysql->port, mysql->unix_socket,
+ mysql->client_flag, mysql->net.read_timeout))
{
tmp_mysql.reconnect=0;
mc_mysql_close(&tmp_mysql);
@@ -436,7 +431,7 @@ my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
-int STDCALL
+int
mc_simple_command(MYSQL *mysql,enum enum_server_command command,
const char *arg, uint length, my_bool skipp_check)
{
@@ -489,19 +484,21 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command,
}
-MYSQL * STDCALL
+MYSQL *
mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *passwd, const char *db,
- uint port, const char *unix_socket,uint client_flag)
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag,
+ uint net_read_timeout)
{
char buff[100],*end,*host_info;
my_socket sock;
ulong ip_addr;
struct sockaddr_in sock_addr;
- uint pkt_length;
+ ulong pkt_length;
NET *net= &mysql->net;
thr_alarm_t alarmed;
- ALARM alarm_buff;
+ ALARM alarm_buff;
+ ulong max_allowed_packet;
#ifdef __WIN__
HANDLE hPipe=INVALID_HANDLE_VALUE;
@@ -516,7 +513,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
db ? db : "(Null)",
user ? user : "(Null)"));
thr_alarm_init(&alarmed);
- thr_alarm(&alarmed,(uint) net_read_timeout,&alarm_buff);
+ thr_alarm(&alarmed, net_read_timeout, &alarm_buff);
bzero((char*) &mysql->options,sizeof(mysql->options));
net->vio = 0; /* If something goes wrong */
@@ -753,6 +750,20 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag=client_flag;
#ifdef HAVE_OPENSSL
+ if ((mysql->server_capabilities & CLIENT_SSL) &&
+ (mysql->options.use_ssl || (client_flag & CLIENT_SSL)))
+ {
+ DBUG_PRINT("info", ("Changing IO layer to SSL"));
+ client_flag |= CLIENT_SSL;
+ }
+ else
+ {
+ if (client_flag & CLIENT_SSL)
+ {
+ DBUG_PRINT("info", ("Leaving IO layer intact because server doesn't support SSL"));
+ }
+ client_flag &= ~CLIENT_SSL;
+ }
/* Oops.. are we careful enough to not send ANY information */
/* without encryption? */
if (client_flag & CLIENT_SSL)
@@ -761,21 +772,21 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
goto error;
/* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress..."));
- VioSSLConnectorFd* connector_fd = (VioSSLConnectorFd*)
- (mysql->connector_fd);
- VioSocket* vio_socket = (VioSocket*)(mysql->net.vio);
- VioSSL* vio_ssl = connector_fd->connect(vio_socket);
- mysql->net.vio = (NetVio*)(vio_ssl);
+ DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_));
+ sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio,60L);
+ DBUG_PRINT("info", ("IO layer change done!"));
}
#endif /* HAVE_OPENSSL */
-
+ max_allowed_packet=mysql->net.max_packet;
int3store(buff+2,max_allowed_packet);
+
+
if (user && user[0])
strmake(buff+5,user,32);
else
{
user = getenv("USER");
- if(!user) user = "mysql";
+ if (!user) user = "mysql";
strmov((char*) buff+5, user );
}
@@ -808,12 +819,38 @@ error:
DBUG_RETURN(0);
}
+
+#ifdef HAVE_OPENSSL
+/*
+**************************************************************************
+** Free strings in the SSL structure and clear 'use_ssl' flag.
+** NB! Errors are not reported until you do mysql_real_connect.
+**************************************************************************
+*/
+int
+mysql_ssl_clear(MYSQL *mysql)
+{
+ my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.ssl_key = 0;
+ mysql->options.ssl_cert = 0;
+ mysql->options.ssl_ca = 0;
+ mysql->options.ssl_capath = 0;
+ mysql->options.use_ssl = FALSE;
+ my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->connector_fd = 0;
+ return 0;
+}
+#endif /* HAVE_OPENSSL */
+
/*************************************************************************
** Send a QUIT to the server and close the connection
** If handle is alloced by mysql connect free it.
*************************************************************************/
-void STDCALL
+void
mc_mysql_close(MYSQL *mysql)
{
DBUG_ENTER("mysql_close");
@@ -836,11 +873,502 @@ mc_mysql_close(MYSQL *mysql)
bzero((char*) &mysql->options,sizeof(mysql->options));
mysql->net.vio = 0;
#ifdef HAVE_OPENSSL
- ((VioConnectorFd*)(mysql->connector_fd))->delete();
- mysql->connector_fd = 0;
+ mysql_ssl_clear(mysql);
#endif /* HAVE_OPENSSL */
if (mysql->free_me)
my_free((gptr) mysql,MYF(0));
}
DBUG_VOID_RETURN;
}
+
+void mc_mysql_free_result(MYSQL_RES *result)
+{
+ DBUG_ENTER("mc_mysql_free_result");
+ DBUG_PRINT("enter",("mysql_res: %lx",result));
+ if (result)
+ {
+ if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT)
+ {
+ DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows"));
+ for (;;)
+ {
+ ulong pkt_len;
+ if ((pkt_len=mc_net_safe_read(result->handle)) == packet_error)
+ break;
+ if (pkt_len == 1 && result->handle->net.read_pos[0] == 254)
+ break; /* End of data */
+ }
+ result->handle->status=MYSQL_STATUS_READY;
+ }
+ mc_free_rows(result->data);
+ if (result->fields)
+ free_root(&result->field_alloc,MYF(0));
+ if (result->row)
+ my_free((gptr) result->row,MYF(0));
+ my_free((gptr) result,MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+static void mc_free_rows(MYSQL_DATA *cur)
+{
+ if (cur)
+ {
+ free_root(&cur->alloc,MYF(0));
+ my_free((gptr) cur,MYF(0));
+ }
+}
+
+static MYSQL_FIELD *
+mc_unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
+ my_bool default_value, my_bool long_flag_protocol)
+{
+ MYSQL_ROWS *row;
+ MYSQL_FIELD *field,*result;
+ DBUG_ENTER("unpack_fields");
+
+ field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields);
+ if (!result)
+ DBUG_RETURN(0);
+
+ for (row=data->data; row ; row = row->next,field++)
+ {
+ field->table= strdup_root(alloc,(char*) row->data[0]);
+ field->name= strdup_root(alloc,(char*) row->data[1]);
+ field->length= (uint) uint3korr(row->data[2]);
+ field->type= (enum enum_field_types) (uchar) row->data[3][0];
+ if (long_flag_protocol)
+ {
+ field->flags= uint2korr(row->data[4]);
+ field->decimals=(uint) (uchar) row->data[4][2];
+ }
+ else
+ {
+ field->flags= (uint) (uchar) row->data[4][0];
+ field->decimals=(uint) (uchar) row->data[4][1];
+ }
+ if (INTERNAL_NUM_FIELD(field))
+ field->flags|= NUM_FLAG;
+ if (default_value && row->data[5])
+ field->def=strdup_root(alloc,(char*) row->data[5]);
+ else
+ field->def=0;
+ field->max_length= 0;
+ }
+ mc_free_rows(data); /* Free old data */
+ DBUG_RETURN(result);
+}
+
+int
+mc_mysql_send_query(MYSQL* mysql, const char* query, uint length)
+{
+ return mc_simple_command(mysql, COM_QUERY, query, length, 1);
+}
+
+int mc_mysql_read_query_result(MYSQL *mysql)
+{
+ uchar *pos;
+ ulong field_count;
+ MYSQL_DATA *fields;
+ ulong length;
+ DBUG_ENTER("mc_mysql_read_query_result");
+
+ if ((length = mc_net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(-1);
+ mc_free_old_query(mysql); /* Free old result */
+get_info:
+ pos=(uchar*) mysql->net.read_pos;
+ if ((field_count= mc_net_field_length(&pos)) == 0)
+ {
+ mysql->affected_rows= mc_net_field_length_ll(&pos);
+ mysql->insert_id= mc_net_field_length_ll(&pos);
+ if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
+ {
+ mysql->server_status=uint2korr(pos); pos+=2;
+ }
+ if (pos < mysql->net.read_pos+length && mc_net_field_length(&pos))
+ mysql->info=(char*) pos;
+ DBUG_RETURN(0);
+ }
+ if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
+ {
+ int error=mc_send_file_to_server(mysql,(char*) pos);
+ if ((length=mc_net_safe_read(mysql)) == packet_error || error)
+ DBUG_RETURN(-1);
+ goto get_info; /* Get info packet */
+ }
+ if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
+ mysql->server_status|= SERVER_STATUS_IN_TRANS;
+
+ mysql->extra_info= mc_net_field_length_ll(&pos); /* Maybe number of rec */
+ if (!(fields=mc_read_rows(mysql,(MYSQL_FIELD*) 0,5)))
+ DBUG_RETURN(-1);
+ if (!(mysql->fields=mc_unpack_fields(fields,&mysql->field_alloc,
+ (uint) field_count,0,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG))))
+ DBUG_RETURN(-1);
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ mysql->field_count=field_count;
+ DBUG_RETURN(0);
+}
+
+int mc_mysql_query(MYSQL *mysql, const char *query, uint length)
+{
+ DBUG_ENTER("mysql_real_query");
+ DBUG_PRINT("enter",("handle: %lx",mysql));
+ DBUG_PRINT("query",("Query = \"%s\"",query));
+ if (!length)
+ length = strlen(query);
+ if (mc_simple_command(mysql,COM_QUERY,query,length,1))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(mc_mysql_read_query_result(mysql));
+}
+
+static int mc_send_file_to_server(MYSQL *mysql, const char *filename)
+{
+ int fd, readcount, result= -1;
+ uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
+ char *buf, tmp_name[FN_REFLEN];
+ DBUG_ENTER("send_file_to_server");
+
+ if (!(buf=my_malloc(packet_length,MYF(0))))
+ {
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY));
+ DBUG_RETURN(-1);
+ }
+
+ fn_format(tmp_name,filename,"","",4); /* Convert to client format */
+ if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0)
+ {
+ my_net_write(&mysql->net,"",0); // Server needs one packet
+ net_flush(&mysql->net);
+ mysql->net.last_errno=EE_FILENOTFOUND;
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ EE(mysql->net.last_errno),tmp_name, errno);
+ goto err;
+ }
+
+ while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0)
+ {
+ if (my_net_write(&mysql->net,buf,readcount))
+ {
+ DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
+ mysql->net.last_errno=CR_SERVER_LOST;
+ strmov(mysql->net.last_error,ER(mysql->net.last_errno));
+ goto err;
+ }
+ }
+ /* Send empty packet to mark end of file */
+ if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net))
+ {
+ mysql->net.last_errno=CR_SERVER_LOST;
+ sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno);
+ goto err;
+ }
+ if (readcount < 0)
+ {
+ mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ tmp_name,errno);
+ goto err;
+ }
+ result=0; // Ok
+
+err:
+ if (fd >= 0)
+ (void) my_close(fd,MYF(0));
+ my_free(buf,MYF(0));
+ DBUG_RETURN(result);
+}
+
+
+/* Get the length of next field. Change parameter to point at fieldstart */
+static ulong mc_net_field_length(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (ulong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (ulong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (ulong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+ return (ulong) uint4korr(pos+1);
+}
+
+/* Same as above, but returns ulonglong values */
+
+static my_ulonglong mc_net_field_length_ll(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (my_ulonglong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (my_ulonglong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+#ifdef NO_CLIENT_LONGLONG
+ return (my_ulonglong) uint4korr(pos+1);
+#else
+ return (my_ulonglong) uint8korr(pos+1);
+#endif
+}
+
+/* Read all rows (fields or data) from server */
+
+static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ uint fields)
+{
+ uint field;
+ ulong pkt_len;
+ ulong len;
+ uchar *cp;
+ char *to;
+ MYSQL_DATA *result;
+ MYSQL_ROWS **prev_ptr,*cur;
+ NET *net = &mysql->net;
+ DBUG_ENTER("mc_read_rows");
+
+ if ((pkt_len=mc_net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(0);
+ if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
+ MYF(MY_ZEROFILL))))
+ {
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
+ result->alloc.min_malloc=sizeof(MYSQL_ROWS);
+ prev_ptr= &result->data;
+ result->rows=0;
+ result->fields=fields;
+
+ while (*(cp=net->read_pos) != 254 || pkt_len != 1)
+ {
+ result->rows++;
+ if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
+ sizeof(MYSQL_ROWS))) ||
+ !(cur->data= ((MYSQL_ROW)
+ alloc_root(&result->alloc,
+ (fields+1)*sizeof(char *)+pkt_len))))
+ {
+ mc_free_rows(result);
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ *prev_ptr=cur;
+ prev_ptr= &cur->next;
+ to= (char*) (cur->data+fields+1);
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) mc_net_field_length(&cp)) == NULL_LENGTH)
+ { /* null field */
+ cur->data[field] = 0;
+ }
+ else
+ {
+ cur->data[field] = to;
+ memcpy(to,(char*) cp,len); to[len]=0;
+ to+=len+1;
+ cp+=len;
+ if (mysql_fields)
+ {
+ if (mysql_fields[field].max_length < len)
+ mysql_fields[field].max_length=len;
+ }
+ }
+ }
+ cur->data[field]=to; /* End of last field */
+ if ((pkt_len=mc_net_safe_read(mysql)) == packet_error)
+ {
+ mc_free_rows(result);
+ DBUG_RETURN(0);
+ }
+ }
+ *prev_ptr=0; /* last pointer is null */
+ DBUG_PRINT("exit",("Got %d rows",result->rows));
+ DBUG_RETURN(result);
+}
+
+
+/*
+** Read one row. Uses packet buffer as storage for fields.
+** When next packet is read, the previous field values are destroyed
+*/
+
+
+static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
+ ulong *lengths)
+{
+ uint field;
+ ulong pkt_len,len;
+ uchar *pos,*prev_pos;
+
+ if ((pkt_len=mc_net_safe_read(mysql)) == packet_error)
+ return -1;
+ if (pkt_len == 1 && mysql->net.read_pos[0] == 254)
+ return 1; /* End of data */
+ prev_pos= 0; /* allowed to write at packet[-1] */
+ pos=mysql->net.read_pos;
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) mc_net_field_length(&pos)) == NULL_LENGTH)
+ { /* null field */
+ row[field] = 0;
+ *lengths++=0;
+ }
+ else
+ {
+ row[field] = (char*) pos;
+ pos+=len;
+ *lengths++=len;
+ }
+ if (prev_pos)
+ *prev_pos=0; /* Terminate prev field */
+ prev_pos=pos;
+ }
+ row[field]=(char*) prev_pos+1; /* End of last field */
+ *prev_pos=0; /* Terminate last field */
+ return 0;
+}
+
+my_ulonglong mc_mysql_num_rows(MYSQL_RES *res)
+{
+ return res->row_count;
+}
+
+unsigned int mc_mysql_num_fields(MYSQL_RES *res)
+{
+ return res->field_count;
+}
+
+void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
+{
+ MYSQL_ROWS *tmp=0;
+ DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
+ if (result->data)
+ for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ;
+ result->current_row=0;
+ result->data_cursor = tmp;
+}
+
+MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res)
+{
+ DBUG_ENTER("mc_mysql_fetch_row");
+ if (!res->data)
+ { /* Unbufferred fetch */
+ if (!res->eof)
+ {
+ if (!(mc_read_one_row(res->handle,res->field_count,res->row,
+ res->lengths)))
+ {
+ res->row_count++;
+ DBUG_RETURN(res->current_row=res->row);
+ }
+ else
+ {
+ DBUG_PRINT("info",("end of data"));
+ res->eof=1;
+ res->handle->status=MYSQL_STATUS_READY;
+ }
+ }
+ DBUG_RETURN((MYSQL_ROW) NULL);
+ }
+ {
+ MYSQL_ROW tmp;
+ if (!res->data_cursor)
+ {
+ DBUG_PRINT("info",("end of data"));
+ DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
+ }
+ tmp = res->data_cursor->data;
+ res->data_cursor = res->data_cursor->next;
+ DBUG_RETURN(res->current_row=tmp);
+ }
+}
+
+int mc_mysql_select_db(MYSQL *mysql, const char *db)
+{
+ int error;
+ DBUG_ENTER("mysql_select_db");
+ DBUG_PRINT("enter",("db: '%s'",db));
+
+ if ((error=mc_simple_command(mysql,COM_INIT_DB,db,(uint) strlen(db),0)))
+ DBUG_RETURN(error);
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->db=my_strdup(db,MYF(MY_WME));
+ DBUG_RETURN(0);
+}
+
+
+MYSQL_RES *mc_mysql_store_result(MYSQL *mysql)
+{
+ MYSQL_RES *result;
+ DBUG_ENTER("mysql_store_result");
+
+ if (!mysql->fields)
+ DBUG_RETURN(0);
+ if (mysql->status != MYSQL_STATUS_GET_RESULT)
+ {
+ strmov(mysql->net.last_error,
+ ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ DBUG_RETURN(0);
+ }
+ mysql->status=MYSQL_STATUS_READY; /* server is ready */
+ if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
+ sizeof(ulong)*mysql->field_count,
+ MYF(MY_ZEROFILL))))
+ {
+ mysql->net.last_errno=CR_OUT_OF_MEMORY;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ DBUG_RETURN(0);
+ }
+ result->eof=1; /* Marker for buffered */
+ result->lengths=(ulong*) (result+1);
+ if (!(result->data=mc_read_rows(mysql,mysql->fields,mysql->field_count)))
+ {
+ my_free((gptr) result,MYF(0));
+ DBUG_RETURN(0);
+ }
+ mysql->affected_rows= result->row_count= result->data->rows;
+ result->data_cursor= result->data->data;
+ result->fields= mysql->fields;
+ result->field_alloc= mysql->field_alloc;
+ result->field_count= mysql->field_count;
+ result->current_field=0;
+ result->current_row=0; /* Must do a fetch first */
+ mysql->fields=0; /* fields is now in result */
+ DBUG_RETURN(result); /* Data fetched */
+}
diff --git a/sql/mini_client.h b/sql/mini_client.h
index f7d95a1b66e..24c13646170 100644
--- a/sql/mini_client.h
+++ b/sql/mini_client.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,30 +18,29 @@
#define _MINI_CLIENT_H
-MYSQL* STDCALL
-mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *passwd, const char *db,
- uint port, const char *unix_socket,uint client_flag);
-
-int STDCALL
-mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
- uint length, my_bool skipp_check);
-void STDCALL
-mc_mysql_close(MYSQL *mysql);
-
-MYSQL * STDCALL
-mc_mysql_init(MYSQL *mysql);
-
-void STDCALL
-mc_mysql_debug(const char *debug);
-
-uint STDCALL
-mc_net_safe_read(MYSQL *mysql);
-
-char * STDCALL mc_mysql_error(MYSQL *mysql);
-int STDCALL mc_mysql_errno(MYSQL *mysql);
-my_bool STDCALL mc_mysql_reconnect(MYSQL* mysql);
-
+MYSQL* mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag,
+ uint net_read_timeout);
+int mc_simple_command(MYSQL *mysql,enum enum_server_command command,
+ const char *arg, uint length, my_bool skipp_check);
+void mc_mysql_close(MYSQL *mysql);
+MYSQL *mc_mysql_init(MYSQL *mysql);
+void mc_mysql_debug(const char *debug);
+ulong mc_net_safe_read(MYSQL *mysql);
+char *mc_mysql_error(MYSQL *mysql);
+int mc_mysql_errno(MYSQL *mysql);
+my_bool mc_mysql_reconnect(MYSQL* mysql);
+int mc_mysql_send_query(MYSQL* mysql, const char* query, uint length);
+int mc_mysql_read_query_result(MYSQL *mysql);
+int mc_mysql_query(MYSQL *mysql, const char *query, uint length);
+MYSQL_RES * mc_mysql_store_result(MYSQL *mysql);
+void mc_mysql_free_result(MYSQL_RES *result);
+void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row);
+my_ulonglong mc_mysql_num_rows(MYSQL_RES *res);
+unsigned int mc_mysql_num_fields(MYSQL_RES *res);
+MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res);
+int mc_mysql_select_db(MYSQL *mysql, const char *db);
+void mc_end_server(MYSQL *mysql);
#endif
-
diff --git a/sql/my_lock.c b/sql/my_lock.c
index 647c07a03c3..4d451fcff22 100644
--- a/sql/my_lock.c
+++ b/sql/my_lock.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,7 +19,7 @@
#else
#undef MAP_TO_USE_RAID /* Avoid RAID mappings */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <mysys_err.h>
#include <my_pthread.h>
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 6b2721f4ab7..712107a0074 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -14,22 +14,19 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef _MYSQL_PRIV_H
-#define _MYSQL_PRIV_H
-
-#include <global.h>
+#include <my_global.h>
+#include <mysql_version.h>
+#include <mysql_embed.h>
#include <my_sys.h>
#include <m_string.h>
-#include "mysql_version.h"
#include <hash.h>
#include <signal.h>
#include <thr_lock.h>
#include <my_base.h> /* Needed by field.h */
#include <my_bitmap.h>
-#include <violite.h>
#ifdef __EMX__
-#undef write // remove pthread.h macro definition for EMX
+#undef write /* remove pthread.h macro definition for EMX */
#endif
typedef ulong table_map; /* Used for table bits in join */
@@ -37,6 +34,7 @@ typedef ulong key_map; /* Used for finding keys */
typedef ulong key_part_map; /* Used for finding key parts */
#include "mysql_com.h"
+#include <violite.h>
#include "unireg.h"
void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size);
@@ -47,6 +45,8 @@ char *sql_strmake(const char *str,uint len);
gptr sql_memdup(const void * ptr,unsigned size);
void sql_element_free(void *ptr);
void kill_one_thread(THD *thd, ulong id);
+bool net_request_file(NET* net, const char* fname);
+char* query_table_status(THD *thd,const char *db,const char *table_name);
#define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
#define safeFree(x) { if(x) { my_free((gptr) x,MYF(0)); x = NULL; } }
@@ -69,18 +69,17 @@ void kill_one_thread(THD *thd, ulong id);
#define HASH_PASSWORD_LENGTH 16
#define HOST_CACHE_SIZE 128
#define MAX_ACCEPT_RETRY 10 // Test accept this many times
-#define MAX_BLOB_WIDTH 8192 // Default width for blob
#define MAX_FIELDS_BEFORE_HASH 32
#define USER_VARS_HASH_SIZE 16
#define STACK_MIN_SIZE 8192 // Abort if less stack during eval.
-#define STACK_BUFF_ALLOC 32 // For stack overrun checks
+#define STACK_BUFF_ALLOC 64 // For stack overrun checks
#ifndef MYSQLD_NET_RETRY_COUNT
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
#endif
#define TEMP_POOL_SIZE 128
/*
The following parameters is to decide when to use an extra cache to
- optimise seeks when reading a big table in sorted order
+ optimise seeks when reading a big table in sorted order
*/
#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024)
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
@@ -155,52 +154,69 @@ void kill_one_thread(THD *thd, ulong id);
#define SELECT_DESCRIBE 4
#define SELECT_SMALL_RESULT 8
#define SELECT_BIG_RESULT 16
-#define SELECT_HIGH_PRIORITY 64 /* Intern */
-#define SELECT_USE_CACHE 256 /* Intern */
-#define SELECT_COUNT_DISTINCT 512 /* Intern */
+#define OPTION_FOUND_ROWS 32
+#define OPTION_TO_QUERY_CACHE 64
+#define SELECT_NO_JOIN_CACHE 256 /* Intern */
#define OPTION_BIG_TABLES 512 /* for SQL OPTION */
#define OPTION_BIG_SELECTS 1024 /* for SQL OPTION */
#define OPTION_LOG_OFF 2048
#define OPTION_UPDATE_LOG 4096 /* update log flag */
-#define OPTION_LOW_PRIORITY_UPDATES 8192
+#define TMP_TABLE_ALL_COLUMNS 8192
#define OPTION_WARNINGS 16384
#define OPTION_AUTO_IS_NULL 32768
#define OPTION_FOUND_COMMENT 65536L
#define OPTION_SAFE_UPDATES OPTION_FOUND_COMMENT*2
#define OPTION_BUFFER_RESULT OPTION_SAFE_UPDATES*2
#define OPTION_BIN_LOG OPTION_BUFFER_RESULT*2
-#define OPTION_NOT_AUTO_COMMIT OPTION_BIN_LOG*2
-#define OPTION_BEGIN OPTION_NOT_AUTO_COMMIT*2
+#define OPTION_NOT_AUTOCOMMIT OPTION_BIN_LOG*2
+#define OPTION_BEGIN OPTION_NOT_AUTOCOMMIT*2
#define OPTION_TABLE_LOCK OPTION_BEGIN*2
#define OPTION_QUICK OPTION_TABLE_LOCK*2
#define OPTION_QUOTE_SHOW_CREATE OPTION_QUICK*2
#define OPTION_INTERNAL_SUBTRANSACTIONS OPTION_QUOTE_SHOW_CREATE*2
/* Set if we are updating a non-transaction safe table */
-#define OPTION_STATUS_NO_TRANS_UPDATE OPTION_INTERNAL_SUBTRANSACTIONS*2
+#define OPTION_STATUS_NO_TRANS_UPDATE OPTION_INTERNAL_SUBTRANSACTIONS*2
/* The following is set when parsing the query */
#define QUERY_NO_INDEX_USED OPTION_STATUS_NO_TRANS_UPDATE*2
#define QUERY_NO_GOOD_INDEX_USED QUERY_NO_INDEX_USED*2
/* The following can be set when importing tables in a 'wrong order'
to suppress foreign key checks */
-#define OPTION_NO_FOREIGN_KEY_CHECKS QUERY_NO_GOOD_INDEX_USED*2
+#define OPTION_NO_FOREIGN_KEY_CHECKS QUERY_NO_GOOD_INDEX_USED*2
/* The following speeds up inserts to InnoDB tables by suppressing unique
key checks in some cases */
-#define OPTION_RELAXED_UNIQUE_CHECKS OPTION_NO_FOREIGN_KEY_CHECKS*2
-/* NOTE: we have now used 31 bits of the OPTION flag! */
+#define OPTION_RELAXED_UNIQUE_CHECKS OPTION_NO_FOREIGN_KEY_CHECKS*2
+#define SELECT_NO_UNLOCK ((ulong) OPTION_RELAXED_UNIQUE_CHECKS*2)
+/* NOTE: we have now used up all 32 bits of the OPTION flag! */
/* Bits for different SQL modes modes (including ANSI mode) */
-#define MODE_REAL_AS_FLOAT 1
-#define MODE_PIPES_AS_CONCAT 2
-#define MODE_ANSI_QUOTES 4
-#define MODE_IGNORE_SPACE 8
-#define MODE_SERIALIZABLE 16
-#define MODE_ONLY_FULL_GROUP_BY 32
+#define MODE_REAL_AS_FLOAT 1
+#define MODE_PIPES_AS_CONCAT 2
+#define MODE_ANSI_QUOTES 4
+#define MODE_IGNORE_SPACE 8
+#define MODE_SERIALIZABLE 16
+#define MODE_ONLY_FULL_GROUP_BY 32
+#define MODE_NO_UNSIGNED_SUBTRACTION 64
#define RAID_BLOCK_SIZE 1024
+#ifdef EXTRA_DEBUG
+/*
+ Sync points allow us to force the server to reach a certain line of code
+ and block there until the client tells the server it is ok to go on.
+ The client tells the server to block with SELECT GET_LOCK()
+ and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult
+ concurrency problems
+*/
+#define DBUG_SYNC_POINT(lock_name,lock_timeout) \
+ debug_sync_point(lock_name,lock_timeout)
+void debug_sync_point(const char* lock_name, uint lock_timeout);
+#else
+#define DBUG_SYNC_POINT(lock_name,lock_timeout)
+#endif /* EXTRA_DEBUG */
+
/* BINLOG_DUMP options */
#define BINLOG_DUMP_NON_BLOCK 1
@@ -248,16 +264,50 @@ inline THD *_current_thd(void)
#include "sql_class.h"
#include "opt_range.h"
-
-void mysql_create_db(THD *thd, char *db, uint create_info);
+#ifdef HAVE_QUERY_CACHE
+#include "sql_cache.h"
+#define query_cache_store_query(A, B) query_cache.store_query(A, B)
+#define query_cache_destroy() query_cache.destroy()
+#define query_cache_result_size_limit(A) query_cache.result_size_limit(A)
+#define query_cache_resize(A) query_cache.resize(A)
+#define query_cache_invalidate3(A, B, C) query_cache.invalidate(A, B, C)
+#define query_cache_invalidate1(A) query_cache.invalidate(A)
+#define query_cache_send_result_to_client(A, B, C) \
+ query_cache.send_result_to_client(A, B, C)
+#define query_cache_invalidate_by_MyISAM_filename_ref \
+ &query_cache_invalidate_by_MyISAM_filename
+#else
+#define query_cache_store_query(A, B)
+#define query_cache_destroy()
+#define query_cache_result_size_limit(A)
+#define query_cache_resize(A)
+#define query_cache_invalidate3(A, B, C)
+#define query_cache_invalidate1(A)
+#define query_cache_send_result_to_client(A, B, C) 0
+#define query_cache_invalidate_by_MyISAM_filename_ref NULL
+
+#define query_cache_abort(A)
+#define query_cache_end_of_result(A)
+#define query_cache_invalidate_by_MyISAM_filename_ref NULL
+#endif /*HAVE_QUERY_CACHE*/
+
+int mysql_create_db(THD *thd, char *db, uint create_info, 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);
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists);
+int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
+ bool log_query);
+int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
+ bool if_exists,
+ bool log_query);
int quick_rm_table(enum db_type base,const char *db,
const char *table_name);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool mysql_change_db(THD *thd,const char *name);
void mysql_parse(THD *thd,char *inBuf,uint length);
void mysql_init_select(LEX *lex);
+bool mysql_new_select(LEX *lex);
+void mysql_init_multi_delete(LEX *lex);
void init_max_user_conn(void);
void free_max_user_conn(void);
pthread_handler_decl(handle_one_connection,arg);
@@ -267,22 +317,20 @@ void end_thread(THD *thd,bool put_in_cache);
void flush_thread_cache();
void mysql_execute_command(void);
bool do_command(THD *thd);
+bool dispatch_command(enum enum_server_command command, THD *thd,
+ char* packet, uint packet_length);
bool check_stack_overrun(THD *thd,char *dummy);
-bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables);
-void mysql_rm_db(THD *thd,char *db,bool if_exists);
+bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables);
void table_cache_init(void);
void table_cache_free(void);
uint cached_tables(void);
void kill_mysql(void);
void close_connection(NET *net,uint errcode=0,bool lock=1);
-bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0,
- bool no_grant=0);
-bool check_table_access(THD *thd,uint want_access,TABLE_LIST *tables);
-bool check_process_priv(THD *thd=0);
-
-int generate_table(THD *thd, TABLE_LIST *table_list,
- TABLE *locked_table);
-
+bool check_access(THD *thd, ulong access, const char *db=0, ulong *save_priv=0,
+ bool no_grant=0, bool no_errors=0);
+bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
+ bool no_errors=0);
+bool check_global_access(THD *thd, ulong want_access);
int mysql_backup_table(THD* thd, TABLE_LIST* table_list);
int mysql_restore_table(THD* thd, TABLE_LIST* table_list);
@@ -295,9 +343,9 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt);
int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt);
+bool check_simple_select();
/* net_pkg.c */
-void send_error(NET *net,uint sql_errno=0, const char *err=0);
void send_warning(NET *net, uint sql_errno, const char *err=0);
void net_printf(NET *net,uint sql_errno, ...);
void send_ok(NET *net,ha_rows affected_rows=0L,ulonglong id=0L,
@@ -324,19 +372,18 @@ SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
int setup_order(THD *thd,TABLE_LIST *tables, List<Item> &fields,
List <Item> &all_fields, ORDER *order);
+int handle_select(THD *thd, LEX *lex, select_result *result);
int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
- uint select_type,select_result *result);
-Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
+ ulong select_type,select_result *result);
+int mysql_union(THD *thd,LEX *lex,select_result *result);
+Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item_result_field ***copy_func, Field **from_field,
bool group,bool modify_item);
int mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<create_field> &fields, List<Key> &keys,
bool tmp_table, bool no_log);
-// no_log is needed for the case of CREATE TABLE ... SELECT , as the logging
-// will be done later in sql_insert.cc
-
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
const char *db, const char *name,
List<create_field> *extra_fields,
@@ -351,7 +398,9 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List<Alter_column> &alter_list,
ORDER *order,
bool drop_primary,
- enum enum_duplicates handle_duplicates);
+ enum enum_duplicates handle_duplicates,
+ enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
+ bool simple_alter=0);
bool mysql_rename_table(enum db_type base,
const char *old_db,
const char * old_name,
@@ -362,15 +411,17 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop_list);
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
- List<Item> &values,COND *conds, ha_rows limit,
+ List<Item> &values,COND *conds,
+ ORDER *order, ha_rows limit,
enum enum_duplicates handle_duplicates,
thr_lock_type lock_type);
int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, enum_duplicates flag,
thr_lock_type lock_type);
void kill_delayed_threads(void);
-int mysql_delete(THD *thd,TABLE_LIST *table,COND *conds,ha_rows rows,
- thr_lock_type lock_type, ulong options);
+int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, ORDER *order,
+ ha_rows rows, thr_lock_type lock_type, ulong options);
+int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok=0);
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update);
TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias,
bool *refresh);
@@ -388,13 +439,28 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name);
Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables);
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
bool check_grant,bool allow_rowid);
+#ifdef HAVE_OPENSSL
+struct st_des_keyblock
+{
+ des_cblock key1, key2, key3;
+};
+struct st_des_keyschedule
+{
+ des_key_schedule ks1, ks2, ks3;
+};
+extern char *des_key_file;
+extern struct st_des_keyschedule des_keyschedule[10];
+extern uint des_default_key;
+extern pthread_mutex_t LOCK_des_key_file;
+bool load_des_key_file(const char *file_name);
+#endif /* HAVE_OPENSSL */
/* sql_do.cc */
int mysql_do(THD *thd, List<Item> &values);
/* sql_list.c */
int mysqld_show_dbs(THD *thd,const char *wild);
-int mysqld_show_open_tables(THD *thd,const char *db,const char *wild);
+int mysqld_show_open_tables(THD *thd,const char *wild);
int mysqld_show_tables(THD *thd,const char *db,const char *wild);
int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild);
int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild,
@@ -408,7 +474,14 @@ int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
void mysqld_list_processes(THD *thd,const char *user,bool verbose);
int mysqld_show_status(THD *thd);
int mysqld_show_variables(THD *thd,const char *wild);
-int mysqld_show(THD *thd, const char *wild, show_var_st *variables);
+int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
+ enum enum_var_type value_type);
+
+/* sql_handler.cc */
+int mysql_ha_open(THD *thd, TABLE_LIST *tables);
+int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok=0);
+int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
+ List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
/* sql_base.cc */
void set_item_name(Item *item,char *pos,uint length);
@@ -431,9 +504,13 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
table_map read_tables, COND *conds, int *error);
Item ** find_item_in_list(Item *item,List<Item> &items);
+bool insert_fields(THD *thd,TABLE_LIST *tables,
+ const char *db_name, const char *table_name,
+ List_iterator<Item> *it);
bool setup_tables(TABLE_LIST *tables);
int setup_fields(THD *thd,TABLE_LIST *tables,List<Item> &item,
- bool set_query_id,List<Item> *sum_func_list);
+ bool set_query_id,List<Item> *sum_func_list,
+ bool allow_sum_func);
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
int setup_ftfuncs(THD *thd);
int init_ftfuncs(THD *thd, bool no_order);
@@ -448,6 +525,7 @@ bool send_fields(THD *thd,List<Item> &item,uint send_field_count);
void free_io_cache(TABLE *entry);
void intern_close_table(TABLE *entry);
void close_thread_tables(THD *thd,bool locked=0);
+bool close_thread_table(THD *thd, TABLE **table_ptr);
void close_temporary_tables(THD *thd);
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
bool close_temporary_table(THD *thd, const char *db, const char *table_name);
@@ -462,8 +540,7 @@ bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
void copy_field_from_tmp_record(Field *field,int offset);
int fill_record(List<Item> &fields,List<Item> &values);
int fill_record(Field **field,List<Item> &values);
-int list_open_tables(THD *thd,List<char> *files, const char *db,const char *wild);
-char* query_table_status(THD *thd,const char *db,const char *table_name);
+OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild);
/* sql_calc.cc */
bool eval_const_cond(COND *cond);
@@ -478,18 +555,15 @@ int write_record(TABLE *table,COPY_INFO *info);
/* bits set in manager_status */
#define MANAGER_BERKELEY_LOG_CLEANUP (1L << 0)
extern ulong volatile manager_status;
-extern bool volatile manager_thread_in_use;
+extern bool volatile manager_thread_in_use, mqh_used;
extern pthread_t manager_thread;
-extern pthread_mutex_t LOCK_manager;
-extern pthread_cond_t COND_manager;
pthread_handler_decl(handle_manager, arg);
/* sql_test.cc */
#ifndef DBUG_OFF
void print_where(COND *cond,const char *info);
void print_cached_tables(void);
-void TEST_filesort(TABLE **form,SORT_FIELD *sortorder,uint s_length,
- ha_rows special);
+void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special);
#endif
void mysql_print_status(THD *thd);
/* key.cc */
@@ -504,29 +578,73 @@ void init_errmessage(void);
void sql_perror(const char *message);
void sql_print_error(const char *format,...)
__attribute__ ((format (printf, 1, 2)));
+bool fn_format_relative_to_data_home(my_string to, const char *name,
+ const char *dir, const char *extension);
+void open_log(MYSQL_LOG *log, const char *hostname,
+ const char *opt_name, const char *extension,
+ enum_log_type type, bool read_append = 0,
+ bool no_auto_events = 0);
+
+/*
+ External variables
+*/
-extern uint32 server_id;
-extern char mysql_data_home[2],server_version[SERVER_VERSION_LENGTH],
- max_sort_char, mysql_real_data_home[];
-extern my_string mysql_unix_port,mysql_tmpdir;
+extern time_t start_time;
+extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
+ max_sort_char, mysql_real_data_home[], *charsets_list;
+extern my_string mysql_tmpdir;
+extern const char *command_name[];
extern const char *first_keyword, *localhost, *delayed_user;
-extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables,
- created_tmp_tables, created_tmp_disk_tables,
- aborted_threads,aborted_connects,
- delayed_insert_timeout,
- delayed_insert_limit, delayed_queue_size,
- delayed_insert_threads, delayed_insert_writes,
- delayed_rows_in_use,delayed_insert_errors;
+extern const char **errmesg; /* Error messages */
+extern const char *myisam_recover_options_str;
+extern uchar *days_in_month;
+extern char language[LIBLEN],reg_ext[FN_EXTLEN];
+extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
+extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
+extern char blob_newline;
+extern double log_10[32];
+extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
+extern ulong created_tmp_tables, created_tmp_disk_tables;
+extern ulong aborted_threads,aborted_connects;
+extern ulong delayed_insert_timeout;
+extern ulong delayed_insert_limit, delayed_queue_size;
+extern ulong delayed_insert_threads, delayed_insert_writes;
+extern ulong delayed_rows_in_use,delayed_insert_errors;
extern ulong filesort_rows, filesort_range_count, filesort_scan_count;
extern ulong filesort_merge_passes;
extern ulong select_range_check_count, select_range_count, select_scan_count;
-extern ulong select_full_range_join_count,select_full_join_count,
- slave_open_temp_tables;
-extern uint test_flags,select_errors,mysql_port,ha_open_options;
+extern ulong select_full_range_join_count,select_full_join_count;
+extern ulong slave_open_temp_tables, query_cache_size;
extern ulong thd_startup_options, slow_launch_threads, slow_launch_time;
-extern time_t start_time;
-extern const char *command_name[];
-extern I_List<THD> threads;
+extern ulong server_id;
+extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count;
+extern ulong ha_read_key_count, ha_read_next_count, ha_read_prev_count;
+extern ulong ha_read_first_count, ha_read_last_count;
+extern ulong ha_read_rnd_count, ha_read_rnd_next_count;
+extern ulong ha_commit_count, ha_rollback_count, mysqld_net_retry_count;
+extern ulong keybuff_size,table_cache_size;
+extern ulong max_connections,max_connect_errors, connect_timeout;
+extern ulong max_insert_delayed_threads, max_user_connections;
+extern ulong long_query_count, what_to_log,flush_time,opt_sql_mode;
+extern ulong query_buff_size, thread_stack,thread_stack_min;
+extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
+extern ulong max_binlog_size, rpl_recovery_rank, thread_cache_size;
+extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log;
+extern ulong specialflag, current_pid;
+
+extern uint test_flags,select_errors,ha_open_options;
+extern uint protocol_version,dropping_tables;
+extern bool opt_endinfo, using_udf_functions, locked_in_memory;
+extern bool opt_using_transactions, use_temp_pool, mysql_embedded;
+extern bool using_update_log, opt_large_files;
+extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
+extern bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
+extern bool opt_disable_networking, opt_skip_show_db;
+extern bool volatile abort_loop, shutdown_in_progress, grant_option;
+extern uint volatile thread_count, thread_running, global_read_lock;
+extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names;
+extern char f_fyllchar;
+
extern MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file;
extern pthread_key(MEM_ROOT*,THR_MALLOC);
@@ -535,52 +653,25 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_grant, LOCK_error_log, LOCK_delayed_insert,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
- LOCK_binlog_update, LOCK_slave, LOCK_server_id;
-extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update,
- COND_slave_stopped, COND_slave_start;
+ LOCK_server_id, LOCK_slave_list, LOCK_active_mi, LOCK_manager,
+ LOCK_global_system_variables;
+extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
extern pthread_attr_t connection_attrib;
-extern bool opt_endinfo, using_udf_functions, locked_in_memory,
- opt_using_transactions, use_temp_pool, opt_local_infile;
-extern char f_fyllchar;
-extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
- ha_read_key_count, ha_read_next_count, ha_read_prev_count,
- ha_read_first_count, ha_read_last_count,
- ha_read_rnd_count, ha_read_rnd_next_count;
+extern I_List<THD> threads;
extern MY_BITMAP temp_pool;
-extern uchar *days_in_month;
extern DATE_FORMAT dayord;
-extern double log_10[32];
-extern uint protocol_version,dropping_tables;
-extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
- max_join_size,join_buff_size,tmp_table_size,
- max_connections,max_connect_errors,long_query_time,
- max_insert_delayed_threads, max_user_connections,
- long_query_count,net_wait_timeout,net_interactive_timeout,
- net_read_timeout,net_write_timeout,
- what_to_log,flush_time, opt_sql_mode,
- max_tmp_tables,max_heap_table_size,query_buff_size,
- lower_case_table_names,thread_stack,thread_stack_min,
- binlog_cache_size, max_binlog_cache_size, record_rnd_cache_size;
-extern ulong com_stat[(uint) SQLCOM_END], com_other;
-extern ulong specialflag, current_pid;
-extern bool low_priority_updates, using_update_log,opt_warnings;
-extern bool opt_sql_bin_update, opt_safe_show_db, opt_safe_user_create;
-extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline;
-extern const char **errmesg; /* Error messages */
-extern const char *default_tx_isolation_name;
extern String empty_string;
-extern struct show_var_st init_vars[];
-extern struct show_var_st status_vars[];
-extern enum db_type default_table_type;
-extern enum enum_tx_isolation default_tx_isolation;
+extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
+extern struct system_variables global_system_variables;
+extern struct system_variables max_system_variables;
+
+extern SHOW_COMP_OPTION have_isam, have_raid, have_openssl, have_symlink;
+extern SHOW_COMP_OPTION have_query_cache;
#ifndef __WIN__
extern pthread_t signal_thread;
#endif
-extern bool volatile abort_loop, shutdown_in_progress, grant_option;
-extern uint volatile thread_count, thread_running, global_read_lock;
-
MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **table,uint count);
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
@@ -588,8 +679,13 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
void mysql_lock_abort(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
+bool lock_global_read_lock(THD *thd);
+void unlock_global_read_lock(THD *thd);
+bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh);
+void start_waiting_global_read_lock(THD *thd);
/* Lock based on name */
+int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
int lock_table_name(THD *thd, TABLE_LIST *table_list);
void unlock_table_name(THD *thd, TABLE_LIST *table_list);
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
@@ -632,7 +728,7 @@ void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
SQL_SELECT *select,
int use_record_cache, bool print_errors);
void end_read_record(READ_RECORD *info);
-ha_rows filesort(TABLE **form,struct st_sort_field *sortorder, uint s_length,
+ha_rows filesort(TABLE *form,struct st_sort_field *sortorder, uint s_length,
SQL_SELECT *select, ha_rows special,ha_rows max_rows,
ha_rows *examined_rows);
void change_double_for_sort(double nr,byte *to);
@@ -673,17 +769,19 @@ void hostname_cache_free();
void hostname_cache_refresh(void);
bool get_interval_info(const char *str,uint length,uint count,
long *values);
-/* sql_cache */
-
+/* sql_cache.cc */
extern bool sql_cache_init();
extern void sql_cache_free();
extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
+/* item.cc */
+Item *get_system_var(enum_var_type var_type, LEX_STRING name);
+
/* Some inline functions for more speed */
inline bool add_item_to_list(Item *item)
{
- return current_lex->item_list.push_back(item);
+ return current_lex->select->item_list.push_back(item);
}
inline bool add_value_to_list(Item *value)
{
@@ -691,11 +789,11 @@ inline bool add_value_to_list(Item *value)
}
inline bool add_order_to_list(Item *item,bool asc)
{
- return add_to_list(current_lex->order_list,item,asc);
+ return add_to_list(current_lex->select->order_list,item,asc);
}
inline bool add_group_to_list(Item *item,bool asc)
{
- return add_to_list(current_lex->group_list,item,asc);
+ return add_to_list(current_lex->select->group_list,item,asc);
}
inline void mark_as_null_row(TABLE *table)
{
@@ -703,5 +801,3 @@ inline void mark_as_null_row(TABLE *table)
table->status|=STATUS_NULL_ROW;
bfill(table->null_flags,table->null_bytes,255);
}
-
-#endif
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 251dda77d34..6c9e934071d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -15,21 +15,18 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
-#include <mysql.h>
#include <m_ctype.h>
#include <my_dir.h>
#include "sql_acl.h"
#include "slave.h"
#include "sql_repl.h"
+#include "repl_failsafe.h"
#include "stacktrace.h"
#ifdef HAVE_BERKELEY_DB
#include "ha_berkeley.h"
#endif
#ifdef HAVE_INNOBASE_DB
-#include "ha_innobase.h"
-#endif
-#ifdef HAVE_GEMINI_DB
-#include "ha_gemini.h"
+#include "ha_innodb.h"
#endif
#include "ha_myisam.h"
#include <nisam.h>
@@ -40,10 +37,26 @@
#define ONE_THREAD
#endif
+#ifdef SAFEMALLOC
+#define SHUTDOWN_THD shutdown_th=pthread_self();
+#define MAIN_THD main_th=pthread_self();
+#define SIGNAL_THD signal_th=pthread_self();
+#else
+#define SHUTDOWN_THD
+#define MAIN_THD
+#define SIGNAL_THD
+#endif
+
+/* stack traces are only supported on linux intel */
+#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK)
+#define HAVE_STACK_TRACE_ON_SEGV
+#include "../pstack/pstack.h"
+char pstack_file_name[80];
+#endif /* __linux__ */
+
#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ)
#define HAVE_CLOSE_SERVER_SOCK 1
-void close_server_sock();
-#endif
+#endif
extern "C" { // Because of SCO 3.2V4.2
#include <errno.h>
@@ -51,7 +64,7 @@ extern "C" { // Because of SCO 3.2V4.2
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ // Skip warnings in getopt.h
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#ifdef HAVE_SYSENT_H
#include <sysent.h>
#endif
@@ -77,9 +90,7 @@ extern "C" { // Because of SCO 3.2V4.2
#include <sys/select.h>
#endif
#include <sys/utsname.h>
-#else
-#include <windows.h>
-#endif // __WIN__
+#endif /* __WIN__ */
#ifdef HAVE_LIBWRAP
#include <tcpd.h>
@@ -197,17 +208,12 @@ SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_NO;
#endif
-#ifdef HAVE_GEMINI_DB
-SHOW_COMP_OPTION have_gemini=SHOW_OPTION_YES;
-#else
-SHOW_COMP_OPTION have_gemini=SHOW_OPTION_NO;
-#endif
#ifdef HAVE_INNOBASE_DB
SHOW_COMP_OPTION have_innodb=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_innodb=SHOW_OPTION_NO;
#endif
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
SHOW_COMP_OPTION have_isam=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_isam=SHOW_OPTION_NO;
@@ -218,96 +224,135 @@ SHOW_COMP_OPTION have_raid=SHOW_OPTION_YES;
SHOW_COMP_OPTION have_raid=SHOW_OPTION_NO;
#endif
#ifdef HAVE_OPENSSL
-SHOW_COMP_OPTION have_ssl=SHOW_OPTION_YES;
+SHOW_COMP_OPTION have_openssl=SHOW_OPTION_YES;
#else
-SHOW_COMP_OPTION have_ssl=SHOW_OPTION_NO;
+SHOW_COMP_OPTION have_openssl=SHOW_OPTION_NO;
#endif
+#ifdef HAVE_BROKEN_REALPATH
+SHOW_COMP_OPTION have_symlink=SHOW_OPTION_NO;
+#else
+SHOW_COMP_OPTION have_symlink=SHOW_OPTION_YES;
+#endif
+#ifdef HAVE_QUERY_CACHE
+SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_YES;
+#else
+SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO;
+#endif
+
+bool opt_large_files= sizeof(my_off_t) > 4;
+/*
+ Variables to store startup options
+*/
+
+bool opt_skip_slave_start = 0; // If set, slave is not autostarted
+/*
+ If set, some standard measures to enforce slave data integrity will not
+ be performed
+*/
+bool opt_reckless_slave = 0;
-static bool opt_skip_slave_start = 0; // if set, slave is not autostarted
+ulong back_log, connect_timeout;
+char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], time_zone[30];
+bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
+bool opt_disable_networking=0, opt_skip_show_db=0;
+my_bool opt_local_infile, opt_external_locking;
+
+static bool opt_do_pstack = 0;
static ulong opt_specialflag=SPECIAL_ENGLISH;
+static ulong concurrency;
+static ulong opt_myisam_block_size;
static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
-static ulong back_log,connect_timeout,concurrency;
static my_string opt_logname=0,opt_update_logname=0,
opt_binlog_index_name = 0,opt_slow_logname=0;
-static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
+
+static char* mysql_home_ptr= mysql_home;
+static char* pidfile_name_ptr= pidfile_name;
static pthread_t select_thread;
-static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
- opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
- opt_myisam_log=0,
- opt_large_files=sizeof(my_off_t) > 4;
-bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0,
- opt_safe_user_create=0;
+static bool opt_noacl, opt_bootstrap=0, opt_myisam_log=0;
+bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
+bool opt_safe_user_create = 0, opt_no_mix_types = 0;
+my_bool opt_safe_show_db=0, lower_case_table_names, opt_old_rpl_compat;
+my_bool opt_show_slave_auth_info;
+volatile bool mqh_used = 0;
FILE *bootstrap_file=0;
int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
-extern MASTER_INFO glob_mi;
-extern int init_master_info(MASTER_INFO* mi);
-// if sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync,
-// and are treated as aliases for each other
+/*
+ If sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync,
+ and are treated as aliases for each other
+*/
static bool kill_in_progress=FALSE;
static struct rand_struct sql_rand;
static int cleanup_done;
-static char **defaults_argv,time_zone[30];
-static const char *default_table_type_name;
-static char glob_hostname[FN_REFLEN];
+static char **defaults_argv;
+char glob_hostname[FN_REFLEN];
+#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
-static bool opt_use_ssl = FALSE;
-static char *opt_ssl_key = 0;
-static char *opt_ssl_cert = 0;
-static char *opt_ssl_ca = 0;
-static char *opt_ssl_capath = 0;
-static VioSSLAcceptorFd* ssl_acceptor_fd = 0;
+char *des_key_file = 0;
+struct st_VioSSLAcceptorFd *ssl_acceptor_fd= 0;
#endif /* HAVE_OPENSSL */
-
I_List <i_string_pair> replicate_rewrite_db;
I_List<i_string> replicate_do_db, replicate_ignore_db;
// allow the user to tell us which db to replicate and which to ignore
I_List<i_string> binlog_do_db, binlog_ignore_db;
/* if we guessed server_id , we need to know about it */
-uint32 server_id = 0;
+ulong server_id= 0; // Must be long becasue of set_var.cc
bool server_id_supplied = 0;
uint mysql_port;
-uint test_flags, select_errors=0, dropping_tables=0,ha_open_options=0;
+uint test_flags = 0, select_errors=0, dropping_tables=0,ha_open_options=0;
uint volatile thread_count=0, thread_running=0, kill_cached_threads=0,
- wake_thread=0, global_read_lock=0;
+ wake_thread=0;
ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL |
OPTION_BIN_LOG | OPTION_QUOTE_SHOW_CREATE );
uint protocol_version=PROTOCOL_VERSION;
-ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
- max_join_size,join_buff_size,tmp_table_size,thread_stack,
- thread_stack_min,net_wait_timeout,what_to_log= ~ (1L << (uint) COM_TIME),
- query_buff_size, lower_case_table_names, mysqld_net_retry_count,
- net_interactive_timeout, slow_launch_time = 2L,
- net_read_timeout,net_write_timeout,slave_open_temp_tables=0,
- open_files_limit=0, max_binlog_size, record_rnd_cache_size;
+struct system_variables global_system_variables;
+struct system_variables max_system_variables;
+ulong keybuff_size,table_cache_size,
+ thread_stack,
+ thread_stack_min,what_to_log= ~ (1L << (uint) COM_TIME),
+ query_buff_size, mysqld_net_retry_count,
+ slow_launch_time = 2L,
+ slave_open_temp_tables=0,
+ open_files_limit=0, max_binlog_size;
ulong com_stat[(uint) SQLCOM_END], com_other;
ulong slave_net_timeout;
ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
+ulong query_cache_size=0;
+#ifdef HAVE_QUERY_CACHE
+ulong query_cache_limit=0;
+Query_cache query_cache;
+#endif
+
volatile ulong cached_thread_count=0;
// replication parameters, if master_host is not NULL, we are a slave
my_string master_user = (char*) "test", master_password = 0, master_host=0,
- master_info_file = (char*) "master.info";
+ master_info_file = (char*) "master.info",
+ relay_log_info_file = (char*) "relay-log.info",
+ master_ssl_key=0, master_ssl_cert=0;
+my_string report_user = 0, report_password = 0, report_host=0;
+
const char *localhost=LOCAL_HOST;
const char *delayed_user="DELAYED";
uint master_port = MYSQL_PORT, master_connect_retry = 60;
+uint report_port = MYSQL_PORT;
+bool master_ssl = 0;
-ulong max_tmp_tables,max_heap_table_size,master_retry_count=0;
+ulong master_retry_count=0;
ulong bytes_sent = 0L, bytes_received = 0L;
-bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
-bool opt_using_transactions, using_update_log, opt_warnings=0;
-bool opt_local_infile=1;
+bool opt_endinfo,using_udf_functions, locked_in_memory;
+bool opt_using_transactions, using_update_log;
bool volatile abort_loop,select_thread_in_use,grant_option;
bool volatile ready_to_exit,shutdown_in_progress;
ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */
-ulong query_id=1L,long_query_count,long_query_time,aborted_threads,
+ulong query_id=1L,long_query_count,aborted_threads,
aborted_connects,delayed_insert_timeout,delayed_insert_limit,
delayed_queue_size,delayed_insert_threads,delayed_insert_writes,
delayed_rows_in_use,delayed_insert_errors,flush_time, thread_created;
@@ -321,26 +366,31 @@ ulong max_connections,max_insert_delayed_threads,max_used_connections,
max_connect_errors, max_user_connections = 0;
ulong thread_id=1L,current_pid;
ulong slow_launch_threads = 0;
-ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size;
char mysql_real_data_home[FN_REFLEN],
- mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN],
- default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
+ language[LIBLEN],reg_ext[FN_EXTLEN],
+ mysql_charsets_dir[FN_REFLEN], *charsets_list,
blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
*opt_init_file;
+char *language_ptr= language;
+#ifndef EMBEDDED_LIBRARY
+char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff;
+bool mysql_embedded=0;
+#else
+char *mysql_data_home=mysql_real_data_home;
+bool mysql_embedded=1;
+#endif
+
char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
+char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
const char *first_keyword="first";
const char **errmesg; /* Error messages */
const char *myisam_recover_options_str="OFF";
const char *sql_mode_str="OFF";
-const char *default_tx_isolation_name;
-enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED;
+ulong rpl_recovery_rank=0;
-#ifdef HAVE_GEMINI_DB
-const char *gemini_recovery_options_str="FULL";
-#endif
-my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
+my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL, mysql_tmpdir=NULL;
ulong my_bind_addr; /* the address we bind to */
DATE_FORMAT dayord;
double log_10[32]; /* 10 potences */
@@ -350,8 +400,8 @@ time_t start_time;
ulong opt_sql_mode = 0L;
const char *sql_mode_names[] =
{ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
- "SERIALIZE","ONLY_FULL_GROUP_BY", NullS };
-TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"",
+ "SERIALIZE","ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",NullS };
+TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"",
sql_mode_names};
MY_BITMAP temp_pool;
@@ -365,23 +415,25 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_error_log,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
- LOCK_binlog_update, LOCK_slave, LOCK_server_id,
- LOCK_user_conn;
+ LOCK_server_id, LOCK_global_system_variables,
+ LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
-pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update,
- COND_slave_stopped, COND_slave_start;
+pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
+ COND_slave_start;
pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
pthread_t signal_thread;
pthread_attr_t connection_attrib;
-enum db_type default_table_type=DB_TYPE_MYISAM;
#ifdef __WIN__
#undef getpid
#include <process.h>
+#if !defined(EMBEDDED_LIBRARY)
HANDLE hEventShutdown;
+static char *event_name;
#include "nt_servc.h"
static NTService Service; // Service object for WinNT
#endif
+#endif
#ifdef OS2
pthread_cond_t eventShutdown;
@@ -396,6 +448,7 @@ static void fix_paths(void);
static pthread_handler_decl(handle_connections_sockets,arg);
static pthread_handler_decl(kill_server_thread,arg);
static int bootstrap(FILE *file);
+static void close_server_sock();
static bool read_init_file(char *file_name);
#ifdef __NT__
static pthread_handler_decl(handle_connections_namedpipes,arg);
@@ -445,15 +498,7 @@ static void close_connections(void)
if (pthread_kill(select_thread,THR_CLIENT_ALARM))
break; // allready dead
#endif
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time(NULL)+2; // Bsd 2.1
- abstime.ts_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+2;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
+ set_timespec(abstime, 2);
for (uint tmp=0 ; tmp < 10 ; tmp++)
{
error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
@@ -465,9 +510,7 @@ static void close_connections(void)
if (error != 0 && !count++)
sql_print_error("Got error %d from pthread_cond_timedwait",error);
#endif
-#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ)
close_server_sock();
-#endif
}
(void) pthread_mutex_unlock(&LOCK_thread_count);
#endif /* __WIN__ */
@@ -485,28 +528,28 @@ static void close_connections(void)
}
}
#ifdef __NT__
-if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
-{
- HANDLE temp;
- DBUG_PRINT( "quit", ("Closing named pipes") );
-
- /* Create connection to the handle named pipe handler to break the loop */
- if ((temp = CreateFile(szPipeName,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL )) != INVALID_HANDLE_VALUE)
+ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
{
- WaitNamedPipe(szPipeName, 1000);
- DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
- SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
- CancelIo(temp);
- DisconnectNamedPipe(temp);
- CloseHandle(temp);
+ HANDLE temp;
+ DBUG_PRINT( "quit", ("Closing named pipes") );
+
+ /* Create connection to the handle named pipe handler to break the loop */
+ if ((temp = CreateFile(szPipeName,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL )) != INVALID_HANDLE_VALUE)
+ {
+ WaitNamedPipe(szPipeName, 1000);
+ DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
+ SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
+ CancelIo(temp);
+ DisconnectNamedPipe(temp);
+ CloseHandle(temp);
+ }
}
- }
#endif
#ifdef HAVE_SYS_UN_H
if (unix_sock != INVALID_SOCKET)
@@ -547,13 +590,11 @@ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
if (thread_count)
- {
sleep(1); // Give threads time to die
- }
/* Force remaining threads to die by closing the connection to the client */
- (void) my_net_init(&net, (Vio*) 0);
+ (void) my_net_init(&net, (st_vio*) 0);
for (;;)
{
DBUG_PRINT("quit",("Locking LOCK_thread_count"));
@@ -594,59 +635,68 @@ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
DBUG_VOID_RETURN;
}
-#ifdef HAVE_CLOSE_SERVER_SOCK
-void close_server_sock()
+static void close_server_sock()
{
+#ifdef HAVE_CLOSE_SERVER_SOCK
DBUG_ENTER("close_server_sock");
- if (ip_sock != INVALID_SOCKET)
+ my_socket tmp_sock;
+ tmp_sock=ip_sock;
+ if (tmp_sock != INVALID_SOCKET)
{
- DBUG_PRINT("info",("closing TCP/IP socket"));
- VOID(shutdown(ip_sock,2));
- VOID(closesocket(ip_sock));
ip_sock=INVALID_SOCKET;
+ DBUG_PRINT("info",("closing TCP/IP socket"));
+ VOID(shutdown(tmp_sock,2));
+ VOID(closesocket(tmp_sock));
}
- if (unix_sock != INVALID_SOCKET)
+ tmp_sock=unix_sock;
+ if (tmp_sock != INVALID_SOCKET)
{
+ unix_sock=INVALID_SOCKET;
DBUG_PRINT("info",("closing Unix socket"));
- VOID(shutdown(unix_sock,2));
- VOID(closesocket(unix_sock));
+ VOID(shutdown(tmp_sock,2));
+ VOID(closesocket(tmp_sock));
VOID(unlink(mysql_unix_port));
- unix_sock=INVALID_SOCKET;
}
DBUG_VOID_RETURN;
-}
#endif
+}
void kill_mysql(void)
{
DBUG_ENTER("kill_mysql");
+
#ifdef SIGNALS_DONT_BREAK_READ
close_server_sock(); /* force accept to wake up */
-#endif
+#endif
+
#if defined(__WIN__)
+#if !defined(EMBEDDED_LIBRARY)
{
if (!SetEvent(hEventShutdown))
{
DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
}
- // or:
- // HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
- // SetEvent(hEventShutdown);
- // CloseHandle(hEvent);
+ /*
+ or:
+ HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
+ SetEvent(hEventShutdown);
+ CloseHandle(hEvent);
+ */
}
+#endif
#elif defined(OS2)
pthread_cond_signal( &eventShutdown); // post semaphore
#elif defined(HAVE_PTHREAD_KILL)
- if (pthread_kill(signal_thread,MYSQL_KILL_SIGNAL))// End everything nicely
+ if (pthread_kill(signal_thread,SIGTERM)) /* End everything nicely */
{
DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
}
#elif !defined(SIGNALS_DONT_BREAK_READ)
- kill(current_pid,MYSQL_KILL_SIGNAL);
+ kill(current_pid,SIGTERM);
#endif
DBUG_PRINT("quit",("After pthread_kill"));
shutdown_in_progress=1; // Safety if kill didn't work
-#ifdef SIGNALS_DONT_BREAK_READ
+#ifdef SIGNALS_DONT_BREAK_READ
if (!abort_loop)
{
pthread_t tmp;
@@ -676,8 +726,7 @@ static void __cdecl kill_server(int sig_ptr)
int sig=(int) (long) sig_ptr; // This is passed a int
DBUG_ENTER("kill_server");
- // if there is a signal during the kill in progress, we do not need
- // another one
+ // if there is a signal during the kill in progress, ignore the other
if (kill_in_progress) // Safety
RETURN_FROM_KILL_SERVER;
kill_in_progress=TRUE;
@@ -689,6 +738,7 @@ static void __cdecl kill_server(int sig_ptr)
sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
#if defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2)
+ SHUTDOWN_THD;
my_thread_init(); // If this is a new thread
#endif
close_connections();
@@ -702,8 +752,9 @@ static void __cdecl kill_server(int sig_ptr)
#ifdef USE_ONE_SIGNAL_HAND
-pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
+static pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
{
+ SHUTDOWN_THD;
my_thread_init(); // Initialize new thread
kill_server(0);
my_thread_end(); // Normally never reached
@@ -711,9 +762,14 @@ pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
}
#endif
+#if defined(__amiga__)
+#undef sigset
+#define sigset signal
+#endif
+
static sig_handler print_signal_warning(int sig)
{
- if (opt_warnings)
+ if (global_system_variables.log_warnings)
sql_print_error("Warning: Got signal %d from thread %d",
sig,my_thread_id());
#ifdef DONT_REMEMBER_SIGNAL
@@ -729,15 +785,19 @@ static sig_handler print_signal_warning(int sig)
void unireg_end(int signal_number __attribute__((unused)))
{
clean_up();
+ my_thread_end();
pthread_exit(0); // Exit is in main thread
}
void unireg_abort(int exit_code)
{
+ DBUG_ENTER("unireg_abort");
if (exit_code)
sql_print_error("Aborting\n");
clean_up(); /* purecov: inspected */
+ DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
+ my_thread_end();
exit(exit_code); /* purecov: inspected */
}
@@ -751,11 +811,12 @@ void clean_up(bool print_message)
bitmap_free(&slave_error_mask);
acl_free(1);
grant_free();
- sql_cache_free();
+ query_cache_destroy();
table_cache_free();
hostname_cache_free();
item_user_lock_free();
lex_free(); /* Free some memory */
+ set_var_free();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_free();
@@ -765,27 +826,43 @@ void clean_up(bool print_message)
#ifdef USE_RAID
end_raid();
#endif
- free_defaults(defaults_argv);
+#ifdef HAVE_OPENSSL
+ my_free(opt_ssl_key,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_cert,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_ca,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_capath,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_ssl_cipher,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
+ opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0;
+#endif /* HAVE_OPENSSL */
+
+ if (defaults_argv)
+ free_defaults(defaults_argv);
my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql_tmpdir,MYF(0));
+ my_free(mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
x_free(opt_bin_logname);
+ x_free(opt_relay_logname);
bitmap_free(&temp_pool);
free_max_user_conn();
-#ifndef __WIN__
+ end_slave_list();
+
+#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
#endif
- if (print_message)
+ if (print_message && errmesg)
sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
- my_thread_end();
-
+ DBUG_PRINT("quit", ("Error messages freed"));
/* Tell main we are ready */
(void) pthread_mutex_lock(&LOCK_thread_count);
+ DBUG_PRINT("quit", ("got thread count lock"));
ready_to_exit=1;
/* do the broadcast inside the lock to ensure that my_end() is not called */
(void) pthread_cond_broadcast(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ DBUG_PRINT("quit", ("done with cleanup"));
} /* clean_up */
@@ -845,20 +922,33 @@ static void set_user(const char *user)
if (!strcmp(user,"root"))
return; // Avoid problem with dynamic libraries
+ uid_t uid;
if (!(ent = getpwnam(user)))
{
- fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
- unireg_abort(1);
+ // allow a numeric uid to be used
+ const char *pos;
+ for (pos=user; isdigit(*pos); pos++) ;
+ if (*pos) // Not numeric id
+ {
+ fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
+ unireg_abort(1);
+ }
+ uid=atoi(user); // Use numberic uid
}
+ else
+ {
#ifdef HAVE_INITGROUPS
- initgroups((char*) user,ent->pw_gid);
+ initgroups((char*) user,ent->pw_gid);
#endif
- if (setgid(ent->pw_gid) == -1)
- {
- sql_perror("setgid");
- unireg_abort(1);
+ if (setgid(ent->pw_gid) == -1)
+ {
+ sql_perror("setgid");
+ unireg_abort(1);
+ }
+ uid=ent->pw_uid;
}
- if (setuid(ent->pw_uid) == -1)
+
+ if (setuid(uid) == -1)
{
sql_perror("setuid");
unireg_abort(1);
@@ -928,15 +1018,12 @@ static void server_init(void)
if (listen(ip_sock,(int) back_log) < 0)
{
sql_perror("Can't start server: listen() on TCP/IP port");
- sql_print_error("Warning: listen() on TCP/IP failed with error %d",
+ sql_print_error("Error: listen() on TCP/IP failed with error %d",
socket_errno);
unireg_abort(1);
}
}
- if (mysqld_chroot)
- set_root(mysqld_chroot);
-
- set_user(mysqld_user); // set_user now takes care of mysqld_user==NULL
+ set_user(mysqld_user); // Works also with mysqld_user==NULL
#ifdef __NT__
/* create named pipe */
@@ -966,8 +1053,8 @@ static void server_init(void)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_variables.net_buffer_length,
+ (int) global_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) == INVALID_HANDLE_VALUE)
{
@@ -1039,7 +1126,7 @@ void yyerror(const char *s)
void close_connection(NET *net,uint errcode,bool lock)
{
- Vio* vio;
+ st_vio* vio;
DBUG_ENTER("close_connection");
DBUG_PRINT("enter",("fd: %s error: '%s'",
net->vio? vio_description(net->vio):"(not connected)",
@@ -1105,6 +1192,7 @@ void end_thread(THD *thd, bool put_in_cache)
/* Tell main we are ready */
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ /* It's safe to broadcast outside a lock (COND... is not deleted here) */
(void) pthread_cond_broadcast(&COND_thread_count);
DBUG_PRINT("info", ("unlocked thread_count mutex"))
#ifdef ONE_THREAD
@@ -1117,21 +1205,6 @@ void end_thread(THD *thd, bool put_in_cache)
DBUG_VOID_RETURN;
}
-#ifdef SIGNALS_DONT_BREAK_READ
-inline void kill_broken_server()
-{
- /* hack to get around signals ignored in syscalls for problem OS's */
- if (unix_sock == INVALID_SOCKET ||
- (!opt_disable_networking && ip_sock == INVALID_SOCKET))
- {
- select_thread_in_use = 0;
- kill_server((void*)MYSQL_KILL_SIGNAL); /* never returns */
- }
-}
-#define MAYBE_BROKEN_SYSCALL kill_broken_server();
-#else
-#define MAYBE_BROKEN_SYSCALL
-#endif
/* Start a cached thread. LOCK_thread_count is locked on entry */
@@ -1158,11 +1231,11 @@ void flush_thread_cache()
}
- /*
- ** Aborts a thread nicely. Commes here on SIGPIPE
- ** TODO: One should have to fix that thr_alarm know about this
- ** thread too
- */
+/*
+ Aborts a thread nicely. Commes here on SIGPIPE
+ TODO: One should have to fix that thr_alarm know about this
+ thread too.
+*/
#ifdef THREAD_SPECIFIC_SIGPIPE
static sig_handler abort_thread(int sig __attribute__((unused)))
@@ -1176,9 +1249,9 @@ static sig_handler abort_thread(int sig __attribute__((unused)))
#endif
/******************************************************************************
-** Setup a signal thread with handles all signals
-** Because linux doesn't support scemas use a mutex to check that
-** the signal thread is ready before continuing
+ Setup a signal thread with handles all signals.
+ Because Linux doesn't support schemas use a mutex to check that
+ the signal thread is ready before continuing
******************************************************************************/
#if defined(__WIN__) || defined(OS2)
@@ -1199,22 +1272,10 @@ static void start_signal_handler(void)
}
#elif defined(__EMX__)
-static void init_signals(void)
-{
- signal(SIGQUIT, sig_kill);
- signal(SIGKILL, sig_kill);
- signal(SIGTERM, sig_kill);
- signal(SIGINT, sig_kill);
- signal(SIGHUP, sig_reload); // Flush everything
- signal(SIGALRM, SIG_IGN);
- signal(SIGBREAK,SIG_IGN);
- signal_thread = pthread_self();
-}
-
-
static void sig_reload(int signo)
{
- reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0); // Flush everything
+ // Flush everything
+ reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0);
signal(signo, SIG_ACK);
}
@@ -1228,10 +1289,23 @@ static void sig_kill(int signo)
signal(signo, SIG_ACK);
}
+static void init_signals(void)
+{
+ signal(SIGQUIT, sig_kill);
+ signal(SIGKILL, sig_kill);
+ signal(SIGTERM, sig_kill);
+ signal(SIGINT, sig_kill);
+ signal(SIGHUP, sig_reload); // Flush everything
+ signal(SIGALRM, SIG_IGN);
+ signal(SIGBREAK,SIG_IGN);
+ signal_thread = pthread_self();
+ SIGNAL_THD;
+}
static void start_signal_handler(void)
{
}
+
#else /* if ! __WIN__ && ! __EMX__ */
#ifdef HAVE_LINUXTHREADS
@@ -1242,10 +1316,10 @@ static sig_handler handle_segfault(int sig)
{
THD *thd=current_thd;
/*
- Strictly speaking, we should need a mutex here
+ Strictly speaking, one needs a mutex here
but since we have got SIGSEGV already, things are a mess
so not having the mutex is not as bad as possibly using a buggy
- mutex - so we keep things simple.
+ mutex - so we keep things simple
*/
if (segfaulted)
{
@@ -1257,43 +1331,42 @@ static sig_handler handle_segfault(int sig)
fprintf(stderr,"\
mysqld got signal %d;\n\
This could be because you hit a bug. It is also possible that this binary\n\
-or one of the libraries it was linked agaist is corrupt, improperly built,\n\
+or one of the libraries it was linked against is corrupt, improperly built,\n\
or misconfigured. This error can also be caused by malfunctioning hardware.\n",
sig);
fprintf(stderr, "\
We will try our best to scrape up some info that will hopefully help diagnose\n\
the problem, but since we have already crashed, something is definitely wrong\n\
-and this may fail\n\n");
+and this may fail.\n\n");
fprintf(stderr, "key_buffer_size=%ld\n", keybuff_size);
- fprintf(stderr, "record_buffer=%ld\n", my_default_record_cache_size);
- fprintf(stderr, "sort_buffer=%ld\n", sortbuff_size);
+ fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
+ fprintf(stderr, "sort_buffer_size=%ld\n", thd->variables.sortbuff_size);
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
fprintf(stderr, "max_connections=%ld\n", max_connections);
fprintf(stderr, "threads_connected=%d\n", thread_count);
fprintf(stderr, "It is possible that mysqld could use up to \n\
-key_buffer_size + (record_buffer + sort_buffer)*max_connections = %ld K\n\
-bytes of memory\n", (keybuff_size + (my_default_record_cache_size +
- sortbuff_size) * max_connections)/ 1024);
- fprintf(stderr, "Hope that's ok, if not, decrease some variables in the equation\n\n");
+key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
+bytes of memory\n", (keybuff_size + (global_system_variables.read_buff_size +
+ thd->variables.sortbuff_size) *
+ max_connections)/ 1024);
+ fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
#if defined(HAVE_LINUXTHREADS)
if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
{
fprintf(stderr, "\
You seem to be running 32-bit Linux and have %d concurrent connections.\n\
-If you have not changed STACK_SIZE in LinuxThreads and build the binary \n\
-yourself, LinuxThreads is quite likely to steal a part of global heap for\n\
+If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\
+yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\
the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
thread_count);
}
#endif /* HAVE_LINUXTHREADS */
#ifdef HAVE_STACKTRACE
- if(!(test_flags & TEST_NO_STACKTRACE))
+ if (!(test_flags & TEST_NO_STACKTRACE))
{
-#ifdef HAVE_GEMINI_DB
- utrace();
-#endif
+ fprintf(stderr,"thd=%p\n",thd);
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
thread_stack);
}
@@ -1306,12 +1379,12 @@ Some pointers may be invalid and cause the dump to abort...\n");
fprintf(stderr, "\n\
Successfully dumped variables, if you ran with --log, take a look at the\n\
details of what thread %ld did to cause the crash. In some cases of really\n\
-bad corruption, the values shown above may be invalid\n\n",
+bad corruption, the values shown above may be invalid.\n\n",
thd->thread_id);
}
fprintf(stderr, "\
The manual page at http://www.mysql.com/doc/C/r/Crashing.html contains\n\
-information that should help you find out what is causing the crash\n");
+information that should help you find out what is causing the crash.\n");
fflush(stderr);
#endif /* HAVE_STACKTRACE */
@@ -1343,12 +1416,17 @@ static void init_signals(void)
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
init_stacktrace();
+#if defined(__amiga__)
+ sa.sa_handler=(void(*)())handle_segfault;
+#else
sa.sa_handler=handle_segfault;
+#endif
sigaction(SIGSEGV, &sa, NULL);
#ifdef SIGBUS
sigaction(SIGBUS, &sa, NULL);
#endif
sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
}
(void) sigemptyset(&set);
#ifdef THREAD_SPECIFIC_SIGPIPE
@@ -1362,8 +1440,8 @@ static void init_signals(void)
sigaddset(&set,SIGQUIT);
sigaddset(&set,SIGTERM);
sigaddset(&set,SIGHUP);
- sigset(SIGTERM,print_signal_warning); // If it's blocked by parent
- signal(SIGHUP,print_signal_warning); // If it's blocked by parent
+ signal(SIGTERM,SIG_DFL); // If it's blocked by parent
+ signal(SIGHUP,SIG_DFL); // If it's blocked by parent
#ifdef SIGTSTP
sigaddset(&set,SIGTSTP);
#endif
@@ -1405,9 +1483,7 @@ static void start_signal_handler(void)
}
-/*
-** This threads handles all signals and alarms
-*/
+/* This threads handles all signals and alarms */
/* ARGSUSED */
static void *signal_hand(void *arg __attribute__((unused)))
@@ -1416,7 +1492,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
int sig;
my_thread_init(); // Init new thread
DBUG_ENTER("signal_hand");
-
+ SIGNAL_THD;
/* Setup alarm handler */
init_thr_alarm(max_connections+max_insert_delayed_threads);
#if SIGINT != THR_KILL_SIGNAL
@@ -1447,6 +1523,13 @@ static void *signal_hand(void *arg __attribute__((unused)))
(void) my_close(pidFile,MYF(0));
}
}
+#ifdef HAVE_STACK_TRACE_ON_SEGV
+ if (opt_do_pstack)
+ {
+ sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid());
+ pstack_install_segv_action(pstack_file_name);
+ }
+#endif /* HAVE_STACK_TRACE_ON_SEGV */
// signal to start_signal_handler that we are ready
(void) pthread_mutex_lock(&LOCK_thread_count);
@@ -1458,13 +1541,16 @@ static void *signal_hand(void *arg __attribute__((unused)))
int error; // Used when debugging
if (shutdown_in_progress && !abort_loop)
{
- sig= MYSQL_KILL_SIGNAL;
+ sig=SIGTERM;
error=0;
}
else
while ((error=my_sigwait(&set,&sig)) == EINTR) ;
if (cleanup_done)
+ {
+ my_thread_end();
pthread_exit(0); // Safety
+ }
switch (sig) {
case SIGTERM:
case SIGQUIT:
@@ -1481,15 +1567,18 @@ static void *signal_hand(void *arg __attribute__((unused)))
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
- (void*) 0))
+ (void*) sig))
sql_print_error("Error: Can't create thread to kill server");
#else
- kill_server((void*) sig); // MIT THREAD has a alarm thread
+ kill_server((void*) sig); // MIT THREAD has a alarm thread
#endif
}
break;
case SIGHUP:
- reload_acl_and_cache((THD*) 0,REFRESH_LOG,
+ reload_acl_and_cache((THD*) 0,
+ (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
+ REFRESH_STATUS | REFRESH_GRANT | REFRESH_THREADS |
+ REFRESH_HOSTS),
(TABLE_LIST*) 0); // Flush logs
mysql_print_status((THD*) 0); // Send debug some info
break;
@@ -1512,8 +1601,8 @@ static void *signal_hand(void *arg __attribute__((unused)))
/*
-** All global error messages are sent here where the first one is stored for
-** the client
+ All global error messages are sent here where the first one is stored for
+ the client
*/
@@ -1555,12 +1644,14 @@ int uname(struct utsname *a)
pthread_handler_decl(handle_shutdown,arg)
{
MSG msg;
+ SHUTDOWN_THD;
my_thread_init();
/* this call should create the message queue for this thread */
PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
-
+#if !defined(EMBEDDED_LIBRARY)
if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
+#endif
kill_server(MYSQL_KILL_SIGNAL);
return 0;
}
@@ -1580,6 +1671,7 @@ int __stdcall handle_kill(ulong ctrl_type)
#ifdef OS2
pthread_handler_decl(handle_shutdown,arg)
{
+ SHUTDOWN_THD;
my_thread_init();
// wait semaphore
@@ -1588,8 +1680,10 @@ pthread_handler_decl(handle_shutdown,arg)
// close semaphore and kill server
pthread_cond_destroy( &eventShutdown);
- // exit main loop on main thread, so kill will be done from
- // main thread (this is thread 2)
+ /*
+ Exit main loop on main thread, so kill will be done from
+ main thread (this is thread 2)
+ */
abort_loop = 1;
// unblock select()
@@ -1600,21 +1694,24 @@ pthread_handler_decl(handle_shutdown,arg)
}
#endif
+
const char *load_default_groups[]= { "mysqld","server",0 };
#ifdef HAVE_LIBWRAP
char *libwrapName=NULL;
#endif
-static void open_log(MYSQL_LOG *log, const char *hostname,
+void open_log(MYSQL_LOG *log, const char *hostname,
const char *opt_name, const char *extension,
- enum_log_type type)
+ enum_log_type type, bool read_append,
+ bool no_auto_events)
{
char tmp[FN_REFLEN];
if (!opt_name || !opt_name[0])
{
- /* TODO: The following should be using fn_format(); We just need to
- first change fn_format() to cut the file name if it's too long.
+ /*
+ TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,hostname,FN_REFLEN-5);
strmov(strcend(tmp,'.'),extension);
@@ -1631,7 +1728,8 @@ static void open_log(MYSQL_LOG *log, const char *hostname,
opt_name=tmp;
}
}
- log->open(opt_name,type);
+ log->open(opt_name,type,0,(read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
+ no_auto_events);
}
@@ -1646,6 +1744,14 @@ int main(int argc, char **argv)
my_umask=0660; // Default umask for new files
my_umask_dir=0700; // Default umask for new directories
+ MAIN_THD;
+ /*
+ Initialize signal_th and shutdown_th to main_th for default value
+ as we need to initialize them to something safe. They are used
+ when compiled with safemalloc.
+ */
+ SIGNAL_THD;
+ SHUTDOWN_THD;
MY_INIT(argv[0]); // init my_sys library & pthreads
tzset(); // Set tzname
@@ -1692,15 +1798,17 @@ int main(int argc, char **argv)
#endif
load_defaults("my",load_default_groups,&argc,&argv);
defaults_argv=argv;
- mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
+
+ /* Get default temporary directory */
+ opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
#if defined( __WIN__) || defined(OS2)
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TEMP");
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TEMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TMP");
#endif
- if (!mysql_tmpdir || !mysql_tmpdir[0])
- mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
+ if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
+ opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
set_options();
get_options(argc,argv);
@@ -1727,33 +1835,36 @@ int main(int argc, char **argv)
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
- (void) pthread_mutex_init(&LOCK_binlog_update, MY_MUTEX_INIT_FAST); // QQ NOT USED
- (void) pthread_mutex_init(&LOCK_slave, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_server_id, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
(void) pthread_cond_init(&COND_thread_count,NULL);
(void) pthread_cond_init(&COND_refresh,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
- (void) pthread_cond_init(&COND_binlog_update, NULL);
- (void) pthread_cond_init(&COND_slave_stopped, NULL);
- (void) pthread_cond_init(&COND_slave_start, NULL);
+ (void) pthread_cond_init(&COND_rpl_status, NULL);
init_signals();
- if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
- unireg_abort(1);
+ if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
+ exit(1);
charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
{
- ssl_acceptor_fd = VioSSLAcceptorFd_new(opt_ssl_key, opt_ssl_cert,
- opt_ssl_ca, opt_ssl_capath);
+ /* having ssl_acceptor_fd != 0 signals the use of SSL */
+ ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
+ opt_ssl_ca, opt_ssl_capath,
+ opt_ssl_cipher);
+ DBUG_PRINT("info",("ssl_acceptor_fd: %p", ssl_acceptor_fd));
if (!ssl_acceptor_fd)
- opt_use_ssl=0;
- /* having ssl_acceptor_fd!=0 signals the use of SSL */
+ opt_use_ssl = 0;
}
+ if (des_key_file)
+ load_des_key_file(des_key_file);
#endif /* HAVE_OPENSSL */
#ifdef HAVE_LIBWRAP
@@ -1774,7 +1885,7 @@ int main(int argc, char **argv)
pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
- /* connections and databases neads lots of files */
+ /* connections and databases needs lots of files */
{
uint wanted_files=10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
@@ -1796,6 +1907,7 @@ int main(int argc, char **argv)
init_errmessage(); /* Read error messages from file */
lex_init();
item_init();
+ set_var_init();
mysys_uses_curses=0;
#ifdef USE_REGEX
regex_init();
@@ -1806,7 +1918,7 @@ int main(int argc, char **argv)
unireg_abort(1);
/*
- ** We have enough space for fiddling with the argv, continue
+ We have enough space for fiddling with the argv, continue
*/
umask(((~my_umask) & 0666));
if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
@@ -1818,14 +1930,12 @@ int main(int argc, char **argv)
server_init();
table_cache_init();
hostname_cache_init();
- sql_cache_init();
+ query_cache_result_size_limit(query_cache_limit);
+ query_cache_resize(query_cache_size);
randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
reset_floating_point_exceptions();
init_thr_lock();
-
- /* Fix varibles that are base 1024*1024 */
- myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
- myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
+ init_slave_list();
/* Setup log files */
if (opt_log)
@@ -1836,56 +1946,7 @@ int main(int argc, char **argv)
LOG_NEW);
using_update_log=1;
}
-
- //make sure slave thread gets started
- // if server_id is set, valid master.info is present, and master_host has
- // not been specified
- if(server_id && !master_host)
- {
- char fname[FN_REFLEN+128];
- MY_STAT stat_area;
- fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
- if(my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi))
- master_host = glob_mi.host;
- }
-
- if (opt_bin_log && !server_id)
- {
- server_id= !master_host ? 1 : 2;
- switch (server_id) {
-#ifdef EXTRA_DEBUG
- case 1:
- sql_print_error("\
-Warning: You have enabled the binary log, but you haven't set server-id:\n\
-Updates will be logged to the binary log, but connections to slaves will\n\
-not be accepted.");
- break;
-#endif
- case 2:
- sql_print_error("\
-Warning: You should set server-id to a non-0 value if master_host is set.\n\
-The server will not act as a slave.");
- break;
- }
- }
- if (opt_bin_log)
- {
- if (!opt_bin_logname)
- {
- char tmp[FN_REFLEN];
- /* TODO: The following should be using fn_format(); We just need to
- first change fn_format() to cut the file name if it's too long.
- */
- strmake(tmp,glob_hostname,FN_REFLEN-5);
- strmov(strcend(tmp,'.'),"-bin");
- opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
- }
- mysql_bin_log.set_index_file_name(opt_binlog_index_name);
- open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
- LOG_BIN);
- using_update_log=1;
- }
-
+
if (opt_slow_log)
open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
LOG_NORMAL);
@@ -1915,15 +1976,15 @@ The server will not act as a slave.");
}
#else
locked_in_memory=0;
-#endif
+#endif
if (opt_myisam_log)
(void) mi_log( 1 );
- ft_init_stopwords(ft_precompiled_stopwords); /* SerG */
+ ft_init_stopwords(ft_precompiled_stopwords);
#ifdef __WIN__
if (!opt_console)
- FreeConsole(); // Remove window
+ FreeConsole(); // Remove window
#endif
/*
@@ -1944,19 +2005,58 @@ The server will not act as a slave.");
(void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL);
#ifndef __WIN__
if (!opt_bootstrap)
- (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore
+ (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
#endif
exit(1);
}
if (!opt_noacl)
(void) grant_init();
- if (max_user_connections)
- init_max_user_conn();
+ init_max_user_conn();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_init();
#endif
+ /* init_slave() must be called after the thread keys are created */
+ init_slave();
+
+ if (opt_bin_log && !server_id)
+ {
+ server_id= !master_host ? 1 : 2;
+ switch (server_id) {
+#ifdef EXTRA_DEBUG
+ case 1:
+ sql_print_error("\
+Warning: You have enabled the binary log, but you haven't set server-id:\n\
+Updates will be logged to the binary log, but connections to slaves will\n\
+not be accepted.");
+ break;
+#endif
+ case 2:
+ sql_print_error("\
+Warning: You should set server-id to a non-0 value if master_host is set.\n\
+The server will not act as a slave.");
+ break;
+ }
+ }
+ if (opt_bin_log)
+ {
+ if (!opt_bin_logname)
+ {
+ char tmp[FN_REFLEN];
+ /* TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
+ */
+ strmake(tmp,glob_hostname,FN_REFLEN-5);
+ strmov(strcend(tmp,'.'),"-bin");
+ opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
+ }
+ mysql_bin_log.set_index_file_name(opt_binlog_index_name);
+ open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
+ LOG_BIN);
+ using_update_log=1;
+ }
+
if (opt_bootstrap)
{
@@ -1973,9 +2073,9 @@ The server will not act as a slave.");
}
}
(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, event_name);
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
sql_print_error("Warning: Can't create thread to handle shutdown requests");
@@ -2004,17 +2104,6 @@ The server will not act as a slave.");
sql_print_error("Warning: Can't create thread to manage maintenance");
}
- // slave thread
- if (master_host)
- {
- pthread_t hThread;
- if (!opt_skip_slave_start &&
- pthread_create(&hThread, &connection_attrib, handle_slave, 0))
- sql_print_error("Warning: Can't create thread to handle slave");
- else if(opt_skip_slave_start)
- init_master_info(&glob_mi);
- }
-
printf(ER(ER_READY),my_progname,server_version,"");
fflush(stdout);
@@ -2061,7 +2150,7 @@ The server will not act as a slave.");
}
#else
handle_connections_sockets(0);
-#ifdef EXTRA_DEBUG
+#ifdef EXTRA_DEBUG2
sql_print_error("Exiting main thread");
#endif
#endif /* __NT__ */
@@ -2071,17 +2160,18 @@ The server will not act as a slave.");
DBUG_PRINT("quit",("Exiting main thread"));
#ifndef __WIN__
-#ifdef EXTRA_DEBUG
+#ifdef EXTRA_DEBUG2
sql_print_error("Before Lock_thread_count");
#endif
(void) pthread_mutex_lock(&LOCK_thread_count);
+ DBUG_PRINT("quit", ("Got thread_count mutex"));
select_thread_in_use=0; // For close_connections
(void) pthread_cond_broadcast(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
-#ifdef EXTRA_DEBUG
+#ifdef EXTRA_DEBUG2
sql_print_error("After lock_thread_count");
#endif
-#endif
+#endif /* __WIN__ */
/* Wait until cleanup is done */
(void) pthread_mutex_lock(&LOCK_thread_count);
@@ -2090,22 +2180,16 @@ The server will not act as a slave.");
pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
}
(void) pthread_mutex_unlock(&LOCK_thread_count);
-#ifdef __WIN__
- if (Service.IsNT())
- {
- if(start_mode)
- Service.Stop();
- else
- {
- Service.SetShutdownEvent(0);
- if(hEventShutdown) CloseHandle(hEventShutdown);
- }
- }
- else
- {
+
+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
+ if (Service.IsNT() && start_mode)
+ Service.Stop();
+ else
+ {
Service.SetShutdownEvent(0);
- if(hEventShutdown) CloseHandle(hEventShutdown);
- }
+ if (hEventShutdown)
+ CloseHandle(hEventShutdown);
+ }
#endif
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(0);
@@ -2113,11 +2197,12 @@ The server will not act as a slave.");
}
-#ifdef __WIN__
-/* ------------------------------------------------------------------------
- main and thread entry function for Win32
- (all this is needed only to run mysqld as a service on WinNT)
- -------------------------------------------------------------------------- */
+/****************************************************************************
+ Main and thread entry function for Win32
+ (all this is needed only to run mysqld as a service on WinNT)
+****************************************************************************/
+
+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
int mysql_service(void *p)
{
win_main(Service.my_argc, Service.my_argv);
@@ -2126,61 +2211,92 @@ int mysql_service(void *p)
int main(int argc, char **argv)
{
- // check environment variable OS
- if (Service.GetOS()) // "OS" defined; Should be NT
+ if (Service.GetOS()) /* true NT family */
{
+ char file_path[FN_REFLEN];
+ my_path(file_path, argv[0], ""); /* Find name in path */
+ fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */
+
if (argc == 2)
+ {
+ if (Service.got_service_option(argv, "install"))
+ {
+ Service.Install(1, MYSQL_SERVICENAME, MYSQL_SERVICENAME, file_path);
+ return 0;
+ }
+ else if (Service.got_service_option(argv, "install-manual"))
+ {
+ Service.Install(0, MYSQL_SERVICENAME, MYSQL_SERVICENAME, file_path);
+ return 0;
+ }
+ else if (Service.got_service_option(argv, "remove"))
+ {
+ Service.Remove(MYSQL_SERVICENAME);
+ return 0;
+ }
+ else if (Service.IsService(argv[1]))
+ {
+ /* start an optional service */
+ load_default_groups[0]= argv[1];
+ event_name= argv[1];
+ start_mode= 1;
+ Service.Init(event_name, mysql_service );
+ return 0;
+ }
+ }
+ else if (argc == 3) /* install or remove any optional service */
{
- char path[FN_REFLEN];
- my_path(path, argv[0], ""); // Find name in path
- fn_format(path,argv[0],path,"",1+4+16); // Force use of full path
-
- if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
+ uint length=strlen(file_path);
+ file_path[sizeof(file_path)-1]=0;
+ strxnmov(file_path + length, sizeof(file_path)-2, " ", argv[2], NullS);
+ if (Service.got_service_option(argv, "install"))
{
- Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
- return 0;
+ Service.Install(1, argv[2], argv[2], file_path);
+ return 0;
}
- else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual"))
+ else if (Service.got_service_option(argv, "install-manual"))
{
- Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
- return 0;
+ Service.Install(0, argv[2], argv[2], file_path);
+ return 0;
}
- else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
+ else if (Service.got_service_option(argv, "remove"))
{
- Service.Remove(MYSQL_SERVICENAME);
- return 0;
+ Service.Remove(argv[2]);
+ return 0;
}
}
- else if (argc == 1) // No arguments; start as a service
+ else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
{
- // init service
- start_mode = 1;
- long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service);
+ /* start the default service */
+ start_mode= 1;
+ event_name= "MySqlShutdown";
+ Service.Init(MYSQL_SERVICENAME, mysql_service);
return 0;
}
}
-
- // This is a WIN95 machine or a start of mysqld as a standalone program
- // we have to pass the arguments, in case of NT-service this will be done
- // by ServiceMain()
-
+ /* Start as standalone server */
Service.my_argc=argc;
Service.my_argv=argv;
mysql_service(NULL);
return 0;
}
-/* ------------------------------------------------------------------------ */
#endif
+/*
+ Execute all commands from a file. Used by the mysql_install_db script to
+ create MySQL privilege tables without having to start a full MySQL server.
+*/
+
static int bootstrap(FILE *file)
{
THD *thd= new THD;
int error;
+
thd->bootstrap=1;
thd->client_capabilities=0;
- my_net_init(&thd->net,(Vio*) 0);
- thd->max_packet_length=thd->net.max_packet;
+ my_net_init(&thd->net,(st_vio*) 0);
+ thd->max_client_packet_length= thd->net.max_packet;
thd->master_access= ~0;
thd->thread_id=thread_id++;
thread_count++;
@@ -2225,7 +2341,7 @@ static void create_new_thread(THD *thd)
DBUG_ENTER("create_new_thread");
NET *net=&thd->net; // For easy ref
- net->timeout = (uint) connect_timeout; // Timeout for read
+ net->read_timeout = (uint) connect_timeout;
if (protocol_version > 9)
net->return_errno=1;
@@ -2304,6 +2420,21 @@ static void create_new_thread(THD *thd)
DBUG_VOID_RETURN;
}
+#ifdef SIGNALS_DONT_BREAK_READ
+inline void kill_broken_server()
+{
+ /* hack to get around signals ignored in syscalls for problem OS's */
+ if (unix_sock == INVALID_SOCKET ||
+ (!opt_disable_networking && ip_sock == INVALID_SOCKET))
+ {
+ select_thread_in_use = 0;
+ kill_server((void*)MYSQL_KILL_SIGNAL); /* never returns */
+ }
+}
+#define MAYBE_BROKEN_SYSCALL kill_broken_server();
+#else
+#define MAYBE_BROKEN_SYSCALL
+#endif
/* Handle new connections and spawn new process to handle them */
@@ -2316,7 +2447,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
THD *thd;
struct sockaddr_in cAddr;
int ip_flags=0,socket_flags=0,flags;
- Vio *vio_tmp;
+ st_vio *vio_tmp;
DBUG_ENTER("handle_connections_sockets");
LINT_INIT(new_sock);
@@ -2354,17 +2485,17 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
if (!select_errors++ && !abort_loop) /* purecov: inspected */
sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
}
- MAYBE_BROKEN_SYSCALL;
+ MAYBE_BROKEN_SYSCALL
continue;
}
#endif /* HPUX */
if (abort_loop)
+ {
+ MAYBE_BROKEN_SYSCALL;
break;
+ }
- /*
- ** Is this a new connection request
- */
-
+ /* Is this a new connection request ? */
#ifdef HAVE_SYS_UN_H
if (FD_ISSET(unix_sock,&readFDs))
{
@@ -2473,7 +2604,8 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
if (!(thd= new THD))
{
- (void) shutdown(new_sock,2); VOID(closesocket(new_sock));
+ (void) shutdown(new_sock,2);
+ VOID(closesocket(new_sock));
continue;
}
if (!(vio_tmp=vio_new(new_sock,
@@ -2540,8 +2672,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_variables.net_buffer_length,
+ (int) global_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) ==
INVALID_HANDLE_VALUE )
@@ -2558,8 +2690,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_variables.net_buffer_length,
+ (int) global_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity)) ==
INVALID_HANDLE_VALUE)
@@ -2601,505 +2733,865 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
******************************************************************************/
enum options {
- OPT_ISAM_LOG=256, OPT_SKIP_NEW,
- OPT_SKIP_GRANT, OPT_SKIP_LOCK,
- OPT_ENABLE_LOCK, OPT_USE_LOCKING,
- OPT_SOCKET, OPT_UPDATE_LOG,
- OPT_BIN_LOG, OPT_SKIP_RESOLVE,
- OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
- OPT_BIND_ADDRESS, OPT_PID_FILE,
- OPT_SKIP_PRIOR, OPT_BIG_TABLES,
- OPT_STANDALONE, OPT_ONE_THREAD,
- OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
- OPT_SKIP_HOST_CACHE, OPT_LONG_FORMAT,
- OPT_FLUSH, OPT_SAFE,
- OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
- OPT_TABLE_TYPE, OPT_INIT_FILE,
- OPT_DELAY_KEY_WRITE, OPT_SLOW_QUERY_LOG,
- OPT_SKIP_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
- OPT_BDB_HOME, OPT_BDB_LOG,
- OPT_BDB_TMP, OPT_BDB_NOSYNC,
- OPT_BDB_LOCK, OPT_BDB_SKIP,
- OPT_BDB_NO_RECOVER, OPT_BDB_SHARED,
- OPT_MASTER_HOST, OPT_MASTER_USER,
- OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
- OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
- OPT_MASTER_RETRY_COUNT,
- OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
- OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
- OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
- OPT_WANT_CORE, OPT_SKIP_CONCURRENT_INSERT,
- OPT_MEMLOCK, OPT_MYISAM_RECOVER,
- OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
- OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE,
- OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
- OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
- OPT_REPLICATE_WILD_IGNORE_TABLE,
- OPT_DISCONNECT_SLAVE_EVENT_COUNT,
- OPT_ABORT_SLAVE_EVENT_COUNT,
- OPT_INNODB_DATA_HOME_DIR,
- OPT_INNODB_DATA_FILE_PATH,
- OPT_INNODB_LOG_GROUP_HOME_DIR,
- OPT_INNODB_LOG_ARCH_DIR,
- OPT_INNODB_LOG_ARCHIVE,
- OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
- OPT_INNODB_FAST_SHUTDOWN,
- OPT_INNODB_UNIX_FILE_FLUSH_METHOD,
- OPT_SAFE_SHOW_DB,
- OPT_GEMINI_SKIP, OPT_INNODB_SKIP,
- OPT_TEMP_POOL, OPT_TX_ISOLATION,
- OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER,
- OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC,
- OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
- OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
- OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
- OPT_HAVE_NAMED_PIPE,
- OPT_SLAVE_SKIP_ERRORS, OPT_LOCAL_INFILE
+ OPT_ISAM_LOG=256, OPT_SKIP_NEW,
+ OPT_SKIP_GRANT, OPT_SKIP_LOCK,
+ OPT_ENABLE_LOCK, OPT_USE_LOCKING,
+ OPT_SOCKET, OPT_UPDATE_LOG,
+ OPT_BIN_LOG, OPT_SKIP_RESOLVE,
+ OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
+ OPT_BIND_ADDRESS, OPT_PID_FILE,
+ OPT_SKIP_PRIOR, OPT_BIG_TABLES,
+ OPT_STANDALONE, OPT_ONE_THREAD,
+ OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
+ OPT_SKIP_HOST_CACHE, OPT_LONG_FORMAT,
+ OPT_FLUSH, OPT_SAFE,
+ OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
+ OPT_TABLE_TYPE, OPT_INIT_FILE,
+ OPT_DELAY_KEY_WRITE, OPT_SLOW_QUERY_LOG,
+ OPT_USE_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
+ OPT_BDB_HOME, OPT_BDB_LOG,
+ OPT_BDB_TMP, OPT_BDB_NOSYNC,
+ OPT_BDB_LOCK, OPT_BDB_SKIP,
+ OPT_BDB_NO_RECOVER, OPT_BDB_SHARED,
+ OPT_MASTER_HOST, OPT_MASTER_USER,
+ OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
+ OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
+ OPT_MASTER_RETRY_COUNT,
+ OPT_MASTER_SSL, OPT_MASTER_SSL_KEY,
+ OPT_MASTER_SSL_CERT,
+ OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
+ OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
+ OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
+ OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
+ OPT_MEMLOCK, OPT_MYISAM_RECOVER,
+ OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
+ OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE,
+ OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
+ OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
+ OPT_REPLICATE_WILD_IGNORE_TABLE,
+ OPT_DISCONNECT_SLAVE_EVENT_COUNT,
+ OPT_ABORT_SLAVE_EVENT_COUNT,
+ OPT_INNODB_DATA_HOME_DIR,
+ OPT_INNODB_DATA_FILE_PATH,
+ OPT_INNODB_LOG_GROUP_HOME_DIR,
+ OPT_INNODB_LOG_ARCH_DIR,
+ OPT_INNODB_LOG_ARCHIVE,
+ OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
+ OPT_INNODB_FLUSH_METHOD,
+ OPT_INNODB_FAST_SHUTDOWN,
+ OPT_SAFE_SHOW_DB,
+ OPT_INNODB_SKIP, OPT_SKIP_SAFEMALLOC,
+ OPT_TEMP_POOL, OPT_TX_ISOLATION,
+ OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
+ OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
+ OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
+ OPT_HAVE_NAMED_PIPE,
+ OPT_DO_PSTACK, OPT_REPORT_HOST,
+ OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
+ OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
+ OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
+ OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
+ OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
+ OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
+ OPT_RECKLESS_SLAVE,
+ OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
+ OPT_SSL_CAPATH, OPT_SSL_CIPHER,
+ OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
+ OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
+ OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
+ OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN,
+ OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT,
+ OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
+ OPT_KEY_BUFFER_SIZE, OPT_LONG_QUERY_TIME,
+ OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
+ OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
+ OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
+ OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
+ OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH,
+ OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
+ OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
+ OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
+ OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
+ OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
+ OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
+ OPT_OPEN_FILES_LIMIT,
+ OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_SIZE,
+ OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER,
+ OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT,
+ OPT_SLAVE_NET_TIMEOUT, OPT_SLOW_LAUNCH_TIME,
+ OPT_SORT_BUFFER, OPT_TABLE_CACHE,
+ OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
+ OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
+ OPT_WAIT_TIMEOUT,
+ OPT_INNODB_MIRRORED_LOG_GROUPS,
+ OPT_INNODB_LOG_FILES_IN_GROUP,
+ OPT_INNODB_LOG_FILE_SIZE,
+ OPT_INNODB_LOG_BUFFER_SIZE,
+ OPT_INNODB_BUFFER_POOL_SIZE,
+ OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
+ OPT_INNODB_FILE_IO_THREADS,
+ OPT_INNODB_LOCK_WAIT_TIMEOUT,
+ OPT_INNODB_THREAD_CONCURRENCY,
+ OPT_INNODB_FORCE_RECOVERY,
+ OPT_BDB_CACHE_SIZE,
+ OPT_BDB_LOG_BUFFER_SIZE,
+ OPT_BDB_MAX_LOCK
};
-static struct option long_options[] = {
- {"ansi", no_argument, 0, 'a'},
- {"basedir", required_argument, 0, 'b'},
+
+#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
+
+struct my_option my_long_options[] =
+{
+ {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"basedir", 'b',
+ "Path to installation directory. All paths are usually resolved relative to this.",
+ (gptr*) &mysql_home_ptr, (gptr*) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#ifdef HAVE_BERKELEY_DB
- {"bdb-home", required_argument, 0, (int) OPT_BDB_HOME},
- {"bdb-lock-detect", required_argument, 0, (int) OPT_BDB_LOCK},
- {"bdb-logdir", required_argument, 0, (int) OPT_BDB_LOG},
- {"bdb-no-recover", no_argument, 0, (int) OPT_BDB_NO_RECOVER},
- {"bdb-no-sync", no_argument, 0, (int) OPT_BDB_NOSYNC},
- {"bdb-shared-data", no_argument, 0, (int) OPT_BDB_SHARED},
- {"bdb-tmpdir", required_argument, 0, (int) OPT_BDB_TMP},
-#endif
- {"big-tables", no_argument, 0, (int) OPT_BIG_TABLES},
- {"binlog-do-db", required_argument, 0, (int) OPT_BINLOG_DO_DB},
- {"binlog-ignore-db", required_argument, 0, (int) OPT_BINLOG_IGNORE_DB},
- {"bind-address", required_argument, 0, (int) OPT_BIND_ADDRESS},
- {"bootstrap", no_argument, 0, (int) OPT_BOOTSTRAP},
+ {"bdb-home", OPT_BDB_HOME, "Berkeley home directory", (gptr*) &berkeley_home,
+ (gptr*) &berkeley_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-lock-detect", OPT_BDB_LOCK,
+ "Berkeley lock detect (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-logdir", OPT_BDB_LOG, "Berkeley DB log file directory",
+ (gptr*) &berkeley_logdir, (gptr*) &berkeley_logdir, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-no-recover", OPT_BDB_NO_RECOVER,
+ "Don't try to recover Berkeley DB tables on start", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-no-sync", OPT_BDB_NOSYNC, "Don't synchronously flush logs", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-shared-data", OPT_BDB_SHARED,
+ "Start Berkeley DB in multi-process mode", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"bdb-tmpdir", OPT_BDB_TMP, "Berkeley DB tempfile name",
+ (gptr*) &berkeley_tmpdir, (gptr*) &berkeley_tmpdir, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif /* HAVE_BERKELEY_DB */
+ {"skip-bdb", OPT_BDB_SKIP, "Don't use berkeley db (will save memory)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"big-tables", OPT_BIG_TABLES,
+ "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"binlog-do-db", OPT_BINLOG_DO_DB,
+ "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
+ "Tells the master that updates to the given database should not be logged tothe binary log",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", OPT_BIND_ADDRESS, "Ip address to bind to",
+ (gptr*) &my_bind_addr, (gptr*) &my_bind_addr, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"console", no_argument, 0, (int) OPT_CONSOLE},
-#endif
- {"core-file", no_argument, 0, (int) OPT_WANT_CORE},
- {"chroot", required_argument, 0, 'r'},
- {"character-sets-dir", required_argument, 0, (int) OPT_CHARSETS_DIR},
- {"datadir", required_argument, 0, 'h'},
- {"debug", optional_argument, 0, '#'},
- {"default-character-set", required_argument, 0, 'C'},
- {"default-table-type", required_argument, 0, (int) OPT_TABLE_TYPE},
- {"delay-key-write-for-all-tables",
- no_argument, 0, (int) OPT_DELAY_KEY_WRITE},
- {"enable-locking", no_argument, 0, (int) OPT_ENABLE_LOCK},
- {"enable-named-pipe", no_argument, 0, (int) OPT_HAVE_NAMED_PIPE},
- {"exit-info", optional_argument, 0, 'T'},
- {"flush", no_argument, 0, (int) OPT_FLUSH},
-#ifdef HAVE_GEMINI_DB
- {"gemini-flush-log-at-commit",no_argument, 0, (int) OPT_GEMINI_FLUSH_LOG},
- {"gemini-recovery", required_argument, 0, (int) OPT_GEMINI_RECOVER},
- {"gemini-unbuffered-io", no_argument, 0, (int) OPT_GEMINI_UNBUFFERED_IO},
-#endif
- /* We must always support this option to make scripts like mysqltest easier
- to do */
- {"innodb_data_file_path", required_argument, 0,
- OPT_INNODB_DATA_FILE_PATH},
+ {"console", OPT_CONSOLE, "Don't remove the console window",
+ (gptr*) &opt_console, (gptr*) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"standalone", OPT_STANDALONE,
+ "Dummy option to start as a standalone program (NT)", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"core-file", OPT_WANT_CORE, "Write core on errors", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"chroot", 'r', "Chroot mysqld daemon during startup.",
+ (gptr*) &mysqld_chroot, (gptr*) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"datadir", 'h', "Path to the database root", (gptr*) &mysql_data_home,
+ (gptr*) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef DBUG_OFF
+ {"debug", '#', "Debug log.", (gptr*) &default_dbug_option,
+ (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef SAFEMALLOC
+ {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
+ "Don't use the memory allocation checking", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+#endif
+#ifdef HAVE_OPENSSL
+ {"des-key-file", OPT_DES_KEY_FILE,
+ "Load keys for des_encrypt() and des_encrypt from given file",
+ (gptr*) &des_key_file, (gptr*) &des_key_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif /* HAVE_OPENSSL */
+ {"default-character-set", 'C', "Set the default character set",
+ (gptr*) &sys_charset.value, (gptr*) &sys_charset.value, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ {"default-table-type", OPT_TABLE_TYPE,
+ "Set the default table type for tables", 0, 0,
+ 0, GET_NO_ARG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE,
+ "Don't flush key buffers between writes for any MyISAM table", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"enable-locking", OPT_ENABLE_LOCK,
+ "Depricated option, use --external-locking instead",
+ (gptr*) &opt_external_locking, (gptr*) &opt_external_locking,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef __NT__
+ {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT)",
+ (gptr*) &opt_enable_named_pipe, (gptr*) &opt_enable_named_pipe, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure",
+ (gptr*) &opt_do_pstack, (gptr*) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
+ GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ /* We must always support the next option to make scripts like mysqltest
+ easier to do */
+ {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role", 0, 0, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH,
+ "Path to individual files and their sizes",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_INNOBASE_DB
- {"innodb_data_home_dir", required_argument, 0,
- OPT_INNODB_DATA_HOME_DIR},
- {"innodb_log_group_home_dir", required_argument, 0,
- OPT_INNODB_LOG_GROUP_HOME_DIR},
- {"innodb_log_arch_dir", required_argument, 0,
- OPT_INNODB_LOG_ARCH_DIR},
- {"innodb_log_archive", optional_argument, 0,
- OPT_INNODB_LOG_ARCHIVE},
- {"innodb_flush_log_at_trx_commit", optional_argument, 0,
- OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT},
- {"innodb_fast_shutdown", optional_argument, 0,
- OPT_INNODB_FAST_SHUTDOWN},
- {"innodb_flush_method", required_argument, 0,
- OPT_INNODB_UNIX_FILE_FLUSH_METHOD},
-#endif
- {"help", no_argument, 0, '?'},
- {"init-file", required_argument, 0, (int) OPT_INIT_FILE},
- {"log", optional_argument, 0, 'l'},
- {"language", required_argument, 0, 'L'},
- {"local-infile", optional_argument, 0, (int) OPT_LOCAL_INFILE},
- {"log-bin", optional_argument, 0, (int) OPT_BIN_LOG},
- {"log-bin-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX},
- {"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG},
- {"log-update", optional_argument, 0, (int) OPT_UPDATE_LOG},
- {"log-slow-queries", optional_argument, 0, (int) OPT_SLOW_QUERY_LOG},
- {"log-long-format", no_argument, 0, (int) OPT_LONG_FORMAT},
- {"log-slave-updates", no_argument, 0, (int) OPT_LOG_SLAVE_UPDATES},
- {"low-priority-updates", no_argument, 0, (int) OPT_LOW_PRIORITY_UPDATES},
- {"master-host", required_argument, 0, (int) OPT_MASTER_HOST},
- {"master-user", required_argument, 0, (int) OPT_MASTER_USER},
- {"master-password", required_argument, 0, (int) OPT_MASTER_PASSWORD},
- {"master-port", required_argument, 0, (int) OPT_MASTER_PORT},
- {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY},
- {"master-retry-count", required_argument, 0, (int) OPT_MASTER_RETRY_COUNT},
- {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE},
- {"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER},
- {"memlock", no_argument, 0, (int) OPT_MEMLOCK},
- // needs to be available for the test case to pass in non-debugging mode
- // is a no-op
- {"disconnect-slave-event-count", required_argument, 0,
- (int) OPT_DISCONNECT_SLAVE_EVENT_COUNT},
- {"abort-slave-event-count", required_argument, 0,
- (int) OPT_ABORT_SLAVE_EVENT_COUNT},
- {"max-binlog-dump-events", required_argument, 0,
- (int) OPT_MAX_BINLOG_DUMP_EVENTS},
- {"sporadic-binlog-dump-fail", no_argument, 0,
- (int) OPT_SPORADIC_BINLOG_DUMP_FAIL},
- {"safemalloc-mem-limit", required_argument, 0, (int)
- OPT_SAFEMALLOC_MEM_LIMIT},
- {"new", no_argument, 0, 'n'},
- {"old-protocol", no_argument, 0, 'o'},
+ {"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR,
+ "The common part for Innodb table spaces", (gptr*) &innobase_data_home_dir,
+ (gptr*) &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR,
+ "Path to innodb log files.", (gptr*) &innobase_log_group_home_dir,
+ (gptr*) &innobase_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
+ "Where full logs should be archived", (gptr*) &innobase_log_arch_dir,
+ (gptr*) &innobase_log_arch_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"innodb_log_archive", OPT_INNODB_LOG_ARCHIVE,
+ "Set to 1 if you want to have logs archived", 0, 0, 0, GET_LONG, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"innodb_flush_log_at_trx_commit", OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
+ "Set to 0 if you don't want to flush logs",
+ &innobase_flush_log_at_trx_commit, &innobase_flush_log_at_trx_commit,
+ 0, GET_LONG, OPT_ARG, 0, 0, 10, 0, 0, 0},
+ {"innodb_flush_method", OPT_INNODB_FLUSH_METHOD,
+ "With which method to flush data", (gptr*) &innobase_unix_file_flush_method,
+ (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN,
+ "Speeds up server shutdown process", (gptr*) &innobase_fast_shutdown,
+ (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+#endif /* End HAVE_INNOBASE_DB */
+ {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup",
+ (gptr*) &opt_init_file, (gptr*) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"log", 'l', "Log connections and queries to file", (gptr*) &opt_logname,
+ (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"language", 'L',
+ "Client error messages in given language. May be given as a full path",
+ (gptr*) &language_ptr, (gptr*) &language_ptr, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"local-infile", OPT_LOCAL_INFILE,
+ "Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0)",
+ (gptr*) &opt_local_infile,
+ (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
+ 1, 0, 0, 0, 0, 0},
+ {"log-bin", OPT_BIN_LOG,
+ "Log queries in new binary format (for replication)",
+ (gptr*) &opt_bin_logname, (gptr*) &opt_bin_logname, 0, GET_STR_ALLOC,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-bin-index", OPT_BIN_LOG_INDEX,
+ "File that holds the names for last binary log files",
+ (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file",
+ (gptr*) &myisam_log_filename, (gptr*) &myisam_log_filename, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-update", OPT_UPDATE_LOG,
+ "Log updates to file.# where # is a unique number if not given.",
+ (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-slow-queries", OPT_SLOW_QUERY_LOG,
+ "Log slow queries to this log file. Defaults logging to hostname-slow.log",
+ (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"log-long-format", OPT_LONG_FORMAT,
+ "Log some extra information to update log", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
+ "Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves.",
+ (gptr*) &opt_log_slave_updates, (gptr*) &opt_log_slave_updates, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
+ "INSERT/DELETE/UPDATE has lower priority than selects",
+ (gptr*) &global_system_variables.low_priority_updates,
+ (gptr*) &max_system_variables.low_priority_updates,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-host", OPT_MASTER_HOST,
+ "Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.",
+ (gptr*) &master_host, (gptr*) &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"master-user", OPT_MASTER_USER,
+ "The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read.",
+ (gptr*) &master_user, (gptr*) &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"master-password", OPT_MASTER_PASSWORD,
+ "The password the slave thread will authenticate with when connecting to the master. If not set, an empty password is assumed.The value in master.info will take precedence if it can be read.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-port", OPT_MASTER_PORT,
+ "The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read",
+ (gptr*) &master_port, (gptr*) &master_port, 0, GET_UINT, REQUIRED_ARG,
+ MYSQL_PORT, 0, 0, 0, 0, 0},
+ {"master-connect-retry", OPT_MASTER_CONNECT_RETRY,
+ "The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is lost.",
+ (gptr*) &master_connect_retry, (gptr*) &master_connect_retry, 0, GET_UINT,
+ REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
+ {"master-retry-count", OPT_MASTER_RETRY_COUNT,
+ "The number of tries the slave will make to connect to the master before giving up.",
+ (gptr*) &master_retry_count, (gptr*) &master_retry_count, 0, GET_ULONG,
+ REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
+ {"master-info-file", OPT_MASTER_INFO_FILE,
+ "The location of the file that remembers where we left off on the master during the replication process. The default is `master.info' in the data directory. You should not need to change this.",
+ (gptr*) &master_info_file, (gptr*) &master_info_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-ssl", OPT_MASTER_SSL,
+ "Turn SSL on for replication. Be warned that is this is a relatively new feature.",
+ (gptr*) &master_ssl, (gptr*) &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"master-ssl-key", OPT_MASTER_SSL_KEY,
+ "Master SSL keyfile name. Only applies if you have enabled master-ssl.",
+ (gptr*) &master_ssl_key, (gptr*) &master_ssl_key, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"master-ssl-cert", OPT_MASTER_SSL_CERT,
+ "Master SSL certificate file name. Only applies if you have enabled master-ssl.",
+ (gptr*) &master_ssl_cert, (gptr*) &master_ssl_cert, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"myisam-recover", OPT_MYISAM_RECOVER,
+ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP or FORCE.",
+ (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
+ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ /*
+ Option needs to be available for the test case to pass in non-debugging
+ mode. is a no-op.
+ */
+ {"memlock", OPT_MEMLOCK, "Lock mysqld in memory", (gptr*) &locked_in_memory,
+ (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
+ "Undocumented: Meant for debugging and testing of replication",
+ (gptr*) &disconnect_slave_event_count,
+ (gptr*) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
+ "Undocumented: Meant for debugging and testing of replication",
+ (gptr*) &abort_slave_event_count, (gptr*) &abort_slave_event_count,
+ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS, "Undocumented",
+ (gptr*) &max_binlog_dump_events, (gptr*) &max_binlog_dump_events, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL, "Undocumented",
+ (gptr*) &opt_sporadic_binlog_dump_fail,
+ (gptr*) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT,
+ "Simulate memory shortage when compiled with the --with-debug=full option",
+ 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"new", 'n', "Use very new possible 'unsafe' functions", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef NOT_YET
+ {"no-mix-table-types", OPT_NO_MIX_TYPE, "Don't allow commands with uses two different table types",
+ (gptr*) &opt_no_mix_types, (gptr*) &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+ {"old-protocol", 'o', "Use the old (3.20) protocol",
+ (gptr*) &protocol_version, (gptr*) &protocol_version, 0, GET_UINT, NO_ARG,
+ PROTOCOL_VERSION, 0, 0, 0, 0, 0},
+ {"old-rpl-compat", OPT_OLD_RPL_COMPAT,
+ "Use old LOAD DATA format in the binary log (don't save data in file)",
+ (gptr*) &opt_old_rpl_compat, (gptr*) &opt_old_rpl_compat, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef ONE_THREAD
- {"one-thread", no_argument, 0, (int) OPT_ONE_THREAD},
-#endif
- {"pid-file", required_argument, 0, (int) OPT_PID_FILE},
- {"port", required_argument, 0, 'P'},
- {"replicate-do-db", required_argument, 0, (int) OPT_REPLICATE_DO_DB},
- {"replicate-do-table", required_argument, 0,
- (int) OPT_REPLICATE_DO_TABLE},
- {"replicate-wild-do-table", required_argument, 0,
- (int) OPT_REPLICATE_WILD_DO_TABLE},
- {"replicate-ignore-db", required_argument, 0,
- (int) OPT_REPLICATE_IGNORE_DB},
- {"replicate-ignore-table", required_argument, 0,
- (int) OPT_REPLICATE_IGNORE_TABLE},
- {"replicate-wild-ignore-table", required_argument, 0,
- (int) OPT_REPLICATE_WILD_IGNORE_TABLE},
- {"replicate-rewrite-db", required_argument, 0,
- (int) OPT_REPLICATE_REWRITE_DB},
- {"safe-mode", no_argument, 0, (int) OPT_SAFE},
- {"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB},
- {"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE},
- {"server-id", required_argument, 0, (int) OPT_SERVER_ID},
- {"set-variable", required_argument, 0, 'O'},
- {"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP},
- {"skip-innodb", no_argument, 0, (int) OPT_INNODB_SKIP},
- {"skip-gemini", no_argument, 0, (int) OPT_GEMINI_SKIP},
- {"skip-concurrent-insert", no_argument, 0, (int) OPT_SKIP_CONCURRENT_INSERT},
- {"skip-delay-key-write", no_argument, 0, (int) OPT_SKIP_DELAY_KEY_WRITE},
- {"skip-grant-tables", no_argument, 0, (int) OPT_SKIP_GRANT},
- {"skip-locking", no_argument, 0, (int) OPT_SKIP_LOCK},
- {"skip-host-cache", no_argument, 0, (int) OPT_SKIP_HOST_CACHE},
- {"skip-name-resolve", no_argument, 0, (int) OPT_SKIP_RESOLVE},
- {"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING},
- {"skip-new", no_argument, 0, (int) OPT_SKIP_NEW},
- {"skip-safemalloc", no_argument, 0, (int) OPT_SKIP_SAFEMALLOC},
- {"skip-show-database", no_argument, 0, (int) OPT_SKIP_SHOW_DB},
- {"skip-slave-start", no_argument, 0, (int) OPT_SKIP_SLAVE_START},
- {"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE},
- {"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS},
- {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR},
- {"slave-skip-errors", required_argument,0,
- (int) OPT_SLAVE_SKIP_ERRORS},
- {"socket", required_argument, 0, (int) OPT_SOCKET},
- {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME},
- {"sql-mode", required_argument, 0, (int) OPT_SQL_MODE},
+ {"one-thread", OPT_ONE_THREAD,
+ "Only use one thread (for debugging under Linux)", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld",
+ (gptr*) &pidfile_name_ptr, (gptr*) &pidfile_name_ptr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &mysql_port,
+ (gptr*) &mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"reckless-slave", OPT_RECKLESS_SLAVE, "For debugging", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-do-db", OPT_REPLICATE_DO_DB,
+ "Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
+ "Tells the slave thread to restrict replication to the specified table. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates, in contrast to replicate-do-db.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
+ "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
+ "Tells the slave thread to not replicate to the specified database. To specify more than one database to ignore, use the directive multiple times, once for each database. This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-ignore-table=db_name.%. ",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
+ "Tells the slave thread to not replicate to the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-datbase updates, in contrast to replicate-ignore-db.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
+ "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
+ "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ // In replication, we may need to tell the other servers how to connect
+ {"report-host", OPT_REPORT_HOST,
+ "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.",
+ (gptr*) &report_host, (gptr*) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"report-user", OPT_REPORT_USER, "Undocumented", (gptr*) &report_user,
+ (gptr*) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"report-password", OPT_REPORT_PASSWORD, "Undocumented",
+ (gptr*) &report_password, (gptr*) &report_password, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"report-port", OPT_REPORT_PORT,
+ "Port for connecting to slave reported to the master during slave registration. Set it only if the slave is listening on a non-default port or if you have a special tunnel from the master or other clients to the slave. If not sure, leave this option unset.",
+ (gptr*) &report_port, (gptr*) &report_port, 0, GET_UINT, REQUIRED_ARG,
+ MYSQL_PORT, 0, 0, 0, 0, 0},
+ {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented",
+ (gptr*) &rpl_recovery_rank, (gptr*) &rpl_recovery_rank, 0, GET_UINT,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"relay-log", OPT_RELAY_LOG, "Undocumented",
+ (gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0,
+ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"relay-log-index", OPT_RELAY_LOG_INDEX, "Undocumented",
+ (gptr*) &opt_relaylog_index_name, (gptr*) &opt_relaylog_index_name, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef TO_BE_DELETED
+ {"safe-show-database", OPT_SAFE_SHOW_DB,
+ "Depricated option; One should use GRANT SHOW DATABASES instead...",
+ (gptr*) &opt_safe_show_db, (gptr*) &opt_safe_show_db, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+ {"safe-user-create", OPT_SAFE_USER_CREATE,
+ "Don't allow new user creation by the user who has no write privileges to the mysql.user table",
+ (gptr*) &opt_safe_user_create, (gptr*) &opt_safe_user_create, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"server-id", OPT_SERVER_ID,
+ "Uniquely identifies the server instance in the community of replication partners",
+ (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
+ "Show user and password in SHOW SLAVE STATUS",
+ (gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"concurrent-insert", OPT_CONCURRENT_INSERT,
+ "Use concurrent insert with MyISAM. Disable with prefix --skip-",
+ (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert,
+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"delay-key-write", OPT_USE_DELAY_KEY_WRITE,
+ "Use delay_key_write option for all tables. Disable with prefix --skip-",
+ (gptr*) &myisam_delay_key_write, (gptr*) &myisam_delay_key_write, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-grant-tables", OPT_SKIP_GRANT,
+ "Start without grant tables. This gives all users FULL ACCESS to all tables!",
+ (gptr*) &opt_noacl, (gptr*) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"skip-innodb", OPT_INNODB_SKIP, "Don't use Innodb (will save memory)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-locking", OPT_SKIP_LOCK,
+ "Depricated option, use --skip-external-locking instead",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-name-resolve", OPT_SKIP_RESOLVE,
+ "Don't resolve hostnames. All hostnames are IP's or 'localhost'",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-networking", OPT_SKIP_NETWORKING,
+ "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-show-database", OPT_SKIP_SHOW_DB,
+ "Don't allow 'SHOW DATABASE' commands", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"skip-slave-start", OPT_SKIP_SLAVE_START,
+ "If set, slave is not autostarted.", (gptr*) &opt_skip_slave_start,
+ (gptr*) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
+ "Don't print a stack trace on failure", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-thread-priority", OPT_SKIP_PRIOR,
+ "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, "Undocumented",
+ (gptr*) &relay_log_info_file, (gptr*) &relay_log_info_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, "Undocumented",
+ (gptr*) &slave_load_tmpdir, (gptr*) &slave_load_tmpdir, 0, GET_STR_ALLOC,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
+ "Tells the slave thread to continue replication when a query returns an error from the provided list",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", OPT_SOCKET, "Socket file to use for connection",
+ (gptr*) &mysql_unix_port, (gptr*) &mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
+ "If set, setting SQL_LOG_BIN to a value will automatically set SQL_LOG_UPDATE to the same value and vice versa.",
+ (gptr*) &opt_sql_bin_update, (gptr*) &opt_sql_bin_update, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sql-mode", OPT_SQL_MODE,
+ "Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
+ (gptr*) &sql_mode_str, (gptr*) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+#ifdef HAVE_OPENSSL
#include "sslopt-longopts.h"
-#ifdef __WIN__
- {"standalone", no_argument, 0, (int) OPT_STANDALONE},
#endif
- {"transaction-isolation", required_argument, 0, (int) OPT_TX_ISOLATION},
- {"temp-pool", no_argument, 0, (int) OPT_TEMP_POOL},
- {"tmpdir", required_argument, 0, 't'},
- {"use-locking", no_argument, 0, (int) OPT_USE_LOCKING},
+ {"temp-pool", OPT_TEMP_POOL,
+ "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
+ (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"tmpdir", 't', "Path for temporary files", (gptr*) &opt_mysql_tmpdir,
+ (gptr*) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"transaction-isolation", OPT_TX_ISOLATION,
+ "Default transaction isolation level", 0, 0, 0, GET_NO_ARG, REQUIRED_ARG, 0,
+ 0, 0, 0,
+ 0, 0},
+ {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running",
+ (gptr*) &opt_external_locking, (gptr*) &opt_external_locking,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef USE_SYMDIR
- {"use-symbolic-links", no_argument, 0, 's'},
-#endif
- {"user", required_argument, 0, 'u'},
- {"version", no_argument, 0, 'V'},
- {"warnings", no_argument, 0, 'W'},
- {0, 0, 0, 0}
-};
-
-#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
-
-CHANGEABLE_VAR changeable_vars[] = {
- { "back_log", (long*) &back_log,
- 50, 1, 65535, 0, 1 },
+ {"use-symbolic-links", 's', "Enable symbolic link support",
+ (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+#endif
+ {"user", 'u', "Run mysqld daemon as user", (gptr*) &mysqld_user,
+ (gptr*) &mysqld_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'v', "Synonym for option -v", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"log-warnings", 'W', "Log some not critical warnings to the log file",
+ (gptr*) &global_system_variables.log_warnings,
+ (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"warnings", 'W', "Deprecated ; Use --log-warnings instead",
+ (gptr*) &global_system_variables.log_warnings,
+ (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ { "back_log", OPT_BACK_LOG,
+ "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.", (gptr*) &back_log, (gptr*) &back_log, 0, GET_ULONG,
+ REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
#ifdef HAVE_BERKELEY_DB
- { "bdb_cache_size", (long*) &berkeley_cache_size,
- KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE },
- {"bdb_log_buffer_size", (long*) &berkeley_log_buffer_size, 0, 256*1024L,
- ~0L, 0, 1024},
- { "bdb_max_lock", (long*) &berkeley_max_lock,
- 10000, 0, (long) ~0, 0, 1 },
- /* QQ: The following should be removed soon! */
- { "bdb_lock_max", (long*) &berkeley_max_lock,
- 10000, 0, (long) ~0, 0, 1 },
-#endif
- { "binlog_cache_size", (long*) &binlog_cache_size,
- 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE },
- { "connect_timeout", (long*) &connect_timeout,
- CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1 },
- { "delayed_insert_timeout", (long*) &delayed_insert_timeout,
- DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "delayed_insert_limit", (long*) &delayed_insert_limit,
- DELAYED_LIMIT, 1, ~0L, 0, 1 },
- { "delayed_queue_size", (long*) &delayed_queue_size,
- DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 },
- { "flush_time", (long*) &flush_time,
- FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1 },
-#ifdef HAVE_GEMINI_DB
- { "gemini_buffer_cache", (long*) &gemini_buffer_cache,
- 128 * 8192, 16, LONG_MAX, 0, 1 },
- { "gemini_connection_limit", (long*) &gemini_connection_limit,
- 100, 10, LONG_MAX, 0, 1 },
- { "gemini_io_threads", (long*) &gemini_io_threads,
- 2, 0, 256, 0, 1 },
- { "gemini_log_cluster_size", (long*) &gemini_log_cluster_size,
- 256 * 1024, 16 * 1024, LONG_MAX, 0, 1 },
- { "gemini_lock_table_size", (long*) &gemini_locktablesize,
- 4096, 1024, LONG_MAX, 0, 1 },
- { "gemini_lock_wait_timeout",(long*) &gemini_lock_wait_timeout,
- 10, 1, LONG_MAX, 0, 1 },
- { "gemini_spin_retries", (long*) &gemini_spin_retries,
- 1, 0, LONG_MAX, 0, 1 },
-#endif
+ { "bdb_cache_size", OPT_BDB_CACHE_SIZE,
+ "The buffer that is allocated to cache index and rows for BDB tables.",
+ (gptr*) &berkeley_cache_size, (gptr*) &berkeley_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE, 0},
+ {"bdb_log_buffer_size", OPT_BDB_LOG_BUFFER_SIZE,
+ "The buffer that is allocated to cache index and rows for BDB tables.",
+ (gptr*) &berkeley_log_buffer_size, (gptr*) &berkeley_log_buffer_size, 0,
+ GET_ULONG, REQUIRED_ARG, 0, 256*1024L, ~0L, 0, 1024, 0},
+ {"bdb_max_lock", OPT_BDB_MAX_LOCK,
+ "The maximum number of locks you can have active on a BDB table.",
+ (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG,
+ REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0},
+ /* QQ: The following should be removed soon! */
+ {"bdb_lock_max", OPT_BDB_MAX_LOCK, "Synonym for bdb_max_lock",
+ (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG,
+ REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0},
+#endif /* HAVE_BERKELEY_DB */
+ {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
+ "The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.",
+ (gptr*) &binlog_cache_size, (gptr*) &binlog_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT,
+ "The number of seconds the mysqld server is waiting for a connect packet before responding with Bad handshake",
+ (gptr*) &connect_timeout, (gptr*) &connect_timeout,
+ 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
+ {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
+ "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
+ (gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0,
+ GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
+ "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.",
+ (gptr*) &delayed_insert_limit, (gptr*) &delayed_insert_limit, 0, GET_ULONG,
+ REQUIRED_ARG, DELAYED_LIMIT, 1, ~0L, 0, 1, 0},
+ { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
+ "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.",
+ (gptr*) &delayed_queue_size, (gptr*) &delayed_queue_size, 0, GET_ULONG,
+ REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1, 0},
+ { "flush_time", OPT_FLUSH_TIME,
+ "A dedicated thread is created to flush all tables at the given interval.",
+ (gptr*) &flush_time, (gptr*) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
+ FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
+ { "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
+ "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
+ (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_ULONG,
+ REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, 0, 1, 0},
+ { "ft_max_word_len", OPT_FT_MAX_WORD_LEN,
+ "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
+ (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_ULONG,
+ REQUIRED_ARG, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0},
+ { "ft_max_word_len_for_sort", OPT_FT_MAX_WORD_LEN_FOR_SORT,
+ "Undocumented", (gptr*) &ft_max_word_len_for_sort,
+ (gptr*) &ft_max_word_len_for_sort, 0, GET_ULONG, REQUIRED_ARG, 20, 4,
+ HA_FT_MAXLEN, 0, 1, 0},
#ifdef HAVE_INNOBASE_DB
- {"innodb_mirrored_log_groups",
- (long*) &innobase_mirrored_log_groups, 1, 1, 10, 0, 1},
- {"innodb_log_files_in_group",
- (long*) &innobase_log_files_in_group, 2, 2, 100, 0, 1},
- {"innodb_log_file_size",
- (long*) &innobase_log_file_size, 5*1024*1024L, 1*1024*1024L,
- ~0L, 0, 1024*1024L},
- {"innodb_log_buffer_size",
- (long*) &innobase_log_buffer_size, 1024*1024L, 256*1024L,
- ~0L, 0, 1024},
- {"innodb_buffer_pool_size",
- (long*) &innobase_buffer_pool_size, 8*1024*1024L, 1024*1024L,
- ~0L, 0, 1024*1024L},
- {"innodb_additional_mem_pool_size",
- (long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L,
- ~0L, 0, 1024},
- {"innodb_file_io_threads",
- (long*) &innobase_file_io_threads, 4, 4, 64, 0, 1},
- {"innodb_lock_wait_timeout",
- (long*) &innobase_lock_wait_timeout, 50, 1,
- 1024 * 1024 * 1024, 0, 1},
- {"innodb_thread_concurrency",
- (long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1},
- {"innodb_force_recovery",
- (long*) &innobase_force_recovery, 0, 0, 6, 0, 1},
-#endif
- { "interactive_timeout", (long*) &net_interactive_timeout,
- NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "join_buffer_size", (long*) &join_buff_size,
- 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
- { "key_buffer_size", (long*) &keybuff_size,
- KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
- { "long_query_time", (long*) &long_query_time,
- 10, 1, LONG_TIMEOUT, 0, 1 },
- { "lower_case_table_names", (long*) &lower_case_table_names,
- IF_WIN(1,0), 0, 1, 0, 1 },
- { "max_allowed_packet", (long*) &max_allowed_packet,
- 1024*1024L, 80, 64*1024*1024L, MALLOC_OVERHEAD, 1024 },
- { "max_binlog_cache_size", (long*) &max_binlog_cache_size,
- ~0L, IO_SIZE, ~0L, 0, IO_SIZE },
- { "max_binlog_size", (long*) &max_binlog_size,
- 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1 },
- { "max_connections", (long*) &max_connections,
- 100, 1, 16384, 0, 1 },
- { "max_connect_errors", (long*) &max_connect_errors,
- MAX_CONNECT_ERRORS, 1, ~0L, 0, 1 },
- { "max_delayed_threads", (long*) &max_insert_delayed_threads,
- 20, 1, 16384, 0, 1 },
- { "max_heap_table_size", (long*) &max_heap_table_size,
- 16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024 },
- { "max_join_size", (long*) &max_join_size,
- ~0L, 1, ~0L, 0, 1 },
- { "max_sort_length", (long*) &max_item_sort_length,
- 1024, 4, 8192*1024L, 0, 1 },
- { "max_tmp_tables", (long*) &max_tmp_tables,
- 32, 1, ~0L, 0, 1 },
- { "max_user_connections", (long*) &max_user_connections,
- 0, 1, ~0L, 0, 1 },
- { "max_write_lock_count", (long*) &max_write_lock_count,
- ~0L, 1, ~0L, 0, 1 },
- { "myisam_max_extra_sort_file_size",
- (long*) &myisam_max_extra_sort_file_size,
- (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 },
- { "myisam_max_sort_file_size", (long*) &myisam_max_sort_file_size,
- (long) (LONG_MAX/(1024L*1024L)), 0, ~0L, 0, 1 },
- { "myisam_sort_buffer_size", (long*) &myisam_sort_buffer_size,
- 8192*1024, 4, ~0L, 0, 1 },
- { "net_buffer_length", (long*) &net_buffer_length,
- 16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024 },
- { "net_retry_count", (long*) &mysqld_net_retry_count,
- MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1 },
- { "net_read_timeout", (long*) &net_read_timeout,
- NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "net_write_timeout", (long*) &net_write_timeout,
- NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "open_files_limit", (long*) &open_files_limit,
- 0, 0, 65535, 0, 1},
- { "query_buffer_size", (long*) &query_buff_size,
- 0, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
- { "record_buffer", (long*) &my_default_record_cache_size,
- 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
- { "record_rnd_buffer", (long*) &record_rnd_cache_size,
- 0, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
- { "slave_net_timeout", (long*) &slave_net_timeout,
- SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "slow_launch_time", (long*) &slow_launch_time,
- 2L, 0L, LONG_TIMEOUT, 0, 1 },
- { "sort_buffer", (long*) &sortbuff_size,
- MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1 },
- { "table_cache", (long*) &table_cache_size,
- 64, 1, 16384, 0, 1 },
- { "thread_concurrency", (long*) &concurrency,
- DEFAULT_CONCURRENCY, 1, 512, 0, 1 },
- { "thread_cache_size", (long*) &thread_cache_size,
- 0, 0, 16384, 0, 1 },
- { "tmp_table_size", (long*) &tmp_table_size,
- 32*1024*1024L, 1024, ~0L, 0, 1 },
- { "thread_stack", (long*) &thread_stack,
- DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024 },
- { "wait_timeout", (long*) &net_wait_timeout,
- NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { NullS, (long*) 0, 0, 0, 0, 0, 0}
+ {"innodb_mirrored_log_groups", OPT_INNODB_MIRRORED_LOG_GROUPS,
+ "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
+ (gptr*) &innobase_mirrored_log_groups,
+ (gptr*) &innobase_mirrored_log_groups, 0, GET_LONG, REQUIRED_ARG, 1, 1, 10,
+ 0, 1, 0},
+ {"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP,
+ "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
+ (gptr*) &innobase_log_files_in_group, (gptr*) &innobase_log_files_in_group,
+ 0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0},
+ {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE,
+ "Size of each log file in a log group in megabytes.",
+ (gptr*) &innobase_log_file_size, (gptr*) &innobase_log_file_size, 0,
+ GET_LONG, REQUIRED_ARG, 5*1024*1024L, 1*1024*1024L, ~0L, 0, 1024*1024L, 0},
+ {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE,
+ "The size of the buffer which InnoDB uses to write log to the log files on disk.",
+ (gptr*) &innobase_log_buffer_size, (gptr*) &innobase_log_buffer_size, 0,
+ GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, ~0L, 0, 1024, 0},
+ {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE,
+ "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
+ (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0,
+ GET_LONG, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, ~0L, 0, 1024*1024L, 0},
+ {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
+ "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
+ (gptr*) &innobase_additional_mem_pool_size,
+ (gptr*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG,
+ 1*1024*1024L, 512*1024L, ~0L, 0, 1024, 0},
+ {"innodb_file_io_threads", OPT_INNODB_FILE_IO_THREADS,
+ "Number of file I/O threads in InnoDB.", (gptr*) &innobase_file_io_threads,
+ (gptr*) &innobase_file_io_threads, 0, GET_LONG, REQUIRED_ARG, 4, 4, 64, 0,
+ 1, 0},
+ {"innodb_lock_wait_timeout", OPT_INNODB_LOCK_WAIT_TIMEOUT,
+ "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back.",
+ (gptr*) &innobase_lock_wait_timeout, (gptr*) &innobase_lock_wait_timeout,
+ 0, GET_LONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
+ {"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
+ "Helps in performance tuning in heavily concurrent environments.",
+ (gptr*) &innobase_thread_concurrency, (gptr*) &innobase_thread_concurrency,
+ 0, GET_LONG, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0},
+ {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY,
+ "Helps to save your data in case the disk image of the database becomes corrupt.",
+ (gptr*) &innobase_force_recovery, (gptr*) &innobase_force_recovery, 0,
+ GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0},
+#endif /* HAVE_INNOBASE_DB */
+ {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
+ "The number of seconds the server waits for activity on an interactive connection before closing it.",
+ (gptr*) &global_system_variables.net_interactive_timeout,
+ (gptr*) &max_system_variables.net_interactive_timeout, 0,
+ GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
+ "The size of the buffer that is used for full joins.",
+ (gptr*) &global_system_variables.join_buff_size,
+ (gptr*) &max_system_variables.join_buff_size, 0, GET_ULONG,
+ REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD,
+ IO_SIZE, 0},
+ {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
+ "The size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
+ (gptr*) &keybuff_size, (gptr*) &keybuff_size, 0, GET_ULONG, REQUIRED_ARG,
+ KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"long_query_time", OPT_LONG_QUERY_TIME,
+ "Log all queries that have taken more than long_query_time seconds to execute to file.",
+ (gptr*) &global_system_variables.long_query_time,
+ (gptr*) &max_system_variables.long_query_time, 0, GET_ULONG,
+ REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
+ "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.",
+ (gptr*) &lower_case_table_names,
+ (gptr*) &lower_case_table_names, 0,
+ GET_BOOL, REQUIRED_ARG, IF_WIN(1,0), 0, 1, 0, 1, 0},
+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
+ "Max packetlength to send/receive from to server.",
+ (gptr*) &global_system_variables.max_allowed_packet,
+ (gptr*) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
+ REQUIRED_ARG, 1024*1024L, 80, 64*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
+ {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
+ "Can be used to restrict the total size used to cache a multi-transaction query.",
+ (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0,
+ GET_ULONG, REQUIRED_ARG, ~0L, IO_SIZE, ~0L, 0, IO_SIZE, 0},
+ {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
+ "Binary log will be rotated automatically when the size crosses the limit.",
+ (gptr*) &max_binlog_size, (gptr*) &max_binlog_size, 0, GET_ULONG,
+ REQUIRED_ARG, 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1, 0},
+ {"max_connections", OPT_MAX_CONNECTIONS,
+ "The number of simultaneous clients allowed.", (gptr*) &max_connections,
+ (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1,
+ 0},
+ {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
+ "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
+ (gptr*) &max_connect_errors, (gptr*) &max_connect_errors, 0, GET_ULONG,
+ REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0},
+ {"max_delayed_threads", OPT_MAX_DELAYED_THREADS,
+ "Don't start more than this number of threads to handle INSERT DELAYED statements.",
+ (gptr*) &max_insert_delayed_threads, (gptr*) &max_insert_delayed_threads,
+ 0, GET_ULONG, REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
+ {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
+ "Don't allow creation of heap tables bigger than this.",
+ (gptr*) &global_system_variables.max_heap_table_size,
+ (gptr*) &max_system_variables.max_heap_table_size, 0, GET_ULONG,
+ REQUIRED_ARG, 16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024, 0},
+ {"max_join_size", OPT_MAX_JOIN_SIZE,
+ "Joins that are probably going to read more than max_join_size records return an error.",
+ (gptr*) &global_system_variables.max_join_size,
+ (gptr*) &max_system_variables.max_join_size, 0, GET_ULONG, REQUIRED_ARG,
+ ~0L, 1, ~0L, 0, 1, 0},
+ {"max_sort_length", OPT_MAX_SORT_LENGTH,
+ "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).",
+ (gptr*) &global_system_variables.max_sort_length,
+ (gptr*) &max_system_variables.max_sort_length, 0, GET_ULONG,
+ REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
+ {"max_tmp_tables", OPT_MAX_TMP_TABLES,
+ "Maximum number of temporary tables a client can keep open at a time.",
+ (gptr*) &global_system_variables.max_tmp_tables,
+ (gptr*) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
+ REQUIRED_ARG, 32, 1, ~0L, 0, 1, 0},
+ {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
+ "The maximum number of active connections for a single user (0 = no limit).",
+ (gptr*) &max_user_connections, (gptr*) &max_user_connections, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 1, ~0L, 0, 1, 0},
+ {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
+ "After this many write locks, allow some read locks to run in between.",
+ (gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG,
+ REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0},
+ {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
+ "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
+ (gptr*) &global_system_variables.bulk_insert_buff_size,
+ (gptr*) &max_system_variables.bulk_insert_buff_size,
+ 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ~0L, 0, 1, 0},
+ {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
+ "Block size to be used for MyISAM index pages",
+ (gptr*) &opt_myisam_block_size,
+ (gptr*) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
+ MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
+ 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
+ {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
+ "Used to help MySQL to decide when to use the slow but safe key cache index create method",
+ (gptr*) &global_system_variables.myisam_max_extra_sort_file_size,
+ (gptr*) &max_system_variables.myisam_max_extra_sort_file_size,
+ 0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
+ 0, ~0L, 0, 1, 0},
+ {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
+ "Don't use the fast sort index method to created index if the temporary file would get bigger than this!",
+ (gptr*) &global_system_variables.myisam_max_sort_file_size,
+ (gptr*) &max_system_variables.myisam_max_sort_file_size, 0,
+ GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, ~0L, 0, 1024*1024, 0},
+ {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
+ "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
+ (gptr*) &global_system_variables.myisam_sort_buff_size,
+ (gptr*) &max_system_variables.myisam_sort_buff_size, 0,
+ GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
+ "Buffer length for TCP/IP and socket communication.",
+ (gptr*) &global_system_variables.net_buffer_length,
+ (gptr*) &max_system_variables.net_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
+ {"net_retry_count", OPT_NET_RETRY_COUNT,
+ "If a read on a communication port is interrupted, retry this many times before giving up.",
+ (gptr*) &mysqld_net_retry_count, (gptr*) &mysqld_net_retry_count, 0,
+ GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0},
+ {"net_read_timeout", OPT_NET_READ_TIMEOUT,
+ "Number of seconds to wait for more data from a connection before aborting the read.",
+ (gptr*) &global_system_variables.net_read_timeout,
+ (gptr*) &max_system_variables.net_read_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
+ "Number of seconds to wait for a block to be written to a connection before aborting the write.",
+ (gptr*) &global_system_variables.net_write_timeout,
+ (gptr*) &max_system_variables.net_write_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"open_files_limit", OPT_OPEN_FILES_LIMIT,
+ "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
+ (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, 65535, 0, 1, 0},
+#ifdef HAVE_QUERY_CACHE
+ {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
+ "Don't cache results that are bigger than this.",
+ (gptr*) &query_cache_limit, (gptr*) &query_cache_limit, 0, GET_ULONG,
+ REQUIRED_ARG, 1024*1024L, 0, (longlong) ULONG_MAX, 0, 1, 0},
+#endif /*HAVE_QUERY_CACHE*/
+ {"query_cache_size", OPT_QUERY_CACHE_SIZE,
+ "The memory allocated to store results from old queries.",
+ (gptr*) &query_cache_size, (gptr*) &query_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
+#ifdef HAVE_QUERY_CACHE
+ {"query_cache_type", OPT_QUERY_CACHE_TYPE,
+ "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.",
+ (gptr*) &global_system_variables.query_cache_type,
+ (gptr*) &max_system_variables.query_cache_type,
+ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
+#endif /*HAVE_QUERY_CACHE*/
+ {"read_buffer_size", OPT_RECORD_BUFFER,
+ "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
+ (gptr*) &global_system_variables.read_buff_size,
+ (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
+ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
+ "When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer.",
+ (gptr*) &global_system_variables.read_rnd_buff_size,
+ (gptr*) &max_system_variables.read_rnd_buff_size, 0,
+ GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
+ ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"record_buffer", OPT_RECORD_BUFFER,
+ "Alias for read_buffer_size",
+ (gptr*) &global_system_variables.read_buff_size,
+ (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
+ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
+ "Undocumented", (gptr*) &relay_log_space_limit,
+ (gptr*) &relay_log_space_limit, 0, GET_ULONG, REQUIRED_ARG, 0L, 0L,
+ (longlong) ULONG_MAX, 0, 1, 0},
+ {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
+ "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
+ (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0,
+ GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
+ "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
+ (gptr*) &slow_launch_time, (gptr*) &slow_launch_time, 0, GET_ULONG,
+ REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
+ {"sort_buffer_size", OPT_SORT_BUFFER,
+ "Each thread that needs to do a sort allocates a buffer of this size.",
+ (gptr*) &global_system_variables.sortbuff_size,
+ (gptr*) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
+ MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
+ 1, 0},
+ {"table_cache", OPT_TABLE_CACHE,
+ "The number of open tables for all threads.", (gptr*) &table_cache_size,
+ (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 16384, 0, 1,
+ 0},
+ {"thread_concurrency", OPT_THREAD_CONCURRENCY,
+ "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.",
+ (gptr*) &concurrency, (gptr*) &concurrency, 0, GET_ULONG, REQUIRED_ARG,
+ DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0},
+ {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
+ "How many threads we should keep in a cache for reuse.",
+ (gptr*) &thread_cache_size, (gptr*) &thread_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
+ {"tmp_table_size", OPT_TMP_TABLE_SIZE,
+ "If an in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM table.",
+ (gptr*) &global_system_variables.tmp_table_size,
+ (gptr*) &max_system_variables.tmp_table_size, 0, GET_ULONG,
+ REQUIRED_ARG, 32*1024*1024L, 1024, ~0L, 0, 1, 0},
+ {"thread_stack", OPT_THREAD_STACK,
+ "The stack size for each thread.", (gptr*) &thread_stack,
+ (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
+ 1024*32, ~0L, 0, 1024, 0},
+ {"wait_timeout", OPT_WAIT_TIMEOUT,
+ "The number of seconds the server waits for activity on a connection before closing it",
+ (gptr*) &global_system_variables.net_wait_timeout,
+ (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-struct show_var_st init_vars[]= {
- {"back_log", (char*) &back_log, SHOW_LONG},
- {"basedir", mysql_home, SHOW_CHAR},
-#ifdef HAVE_BERKELEY_DB
- {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
- {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
- {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
- {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
- {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
- {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
- {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
- {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR},
-#endif
- {"binlog_cache_size", (char*) &binlog_cache_size, SHOW_LONG},
- {"character_set", default_charset, SHOW_CHAR},
- {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
- {"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL},
- {"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
- {"datadir", mysql_real_data_home, SHOW_CHAR},
- {"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL},
- {"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG},
- {"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG},
- {"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
- {"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
- {"flush_time", (char*) &flush_time, SHOW_LONG},
-#ifdef HAVE_GEMINI_DB
- {"gemini_buffer_cache", (char*) &gemini_buffer_cache, SHOW_LONG},
- {"gemini_connection_limit", (char*) &gemini_connection_limit, SHOW_LONG},
- {"gemini_io_threads", (char*) &gemini_io_threads, SHOW_LONG},
- {"gemini_log_cluster_size", (char*) &gemini_log_cluster_size, SHOW_LONG},
- {"gemini_lock_table_size", (char*) &gemini_locktablesize, SHOW_LONG},
- {"gemini_lock_wait_timeout",(char*) &gemini_lock_wait_timeout, SHOW_LONG},
- {"gemini_recovery_options", (char*) &gemini_recovery_options_str, SHOW_CHAR_PTR},
- {"gemini_spin_retries", (char*) &gemini_spin_retries, SHOW_LONG},
-#endif
- {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
- {"have_gemini", (char*) &have_gemini, SHOW_HAVE},
- {"have_innodb", (char*) &have_innodb, SHOW_HAVE},
- {"have_isam", (char*) &have_isam, SHOW_HAVE},
- {"have_raid", (char*) &have_raid, SHOW_HAVE},
- {"have_openssl", (char*) &have_ssl, SHOW_HAVE},
- {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
-#ifdef HAVE_INNOBASE_DB
- {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
- {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG },
- {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
- {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
- {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
- {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
- {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
- {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_LONG},
- {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
- {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
- {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
- {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
- {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL},
- {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
- {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONG},
- {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG},
- {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
- {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
-#endif
- {"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG},
- {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
- {"key_buffer_size", (char*) &keybuff_size, SHOW_LONG},
- {"language", language, SHOW_CHAR},
- {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
-#ifdef HAVE_MLOCKALL
- {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
-#endif
- {"log", (char*) &opt_log, SHOW_BOOL},
- {"log_update", (char*) &opt_update_log, SHOW_BOOL},
- {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
- {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_BOOL},
- {"log_long_queries", (char*) &opt_slow_log, SHOW_BOOL},
- {"long_query_time", (char*) &long_query_time, SHOW_LONG},
- {"low_priority_updates", (char*) &low_priority_updates, SHOW_BOOL},
- {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_LONG},
- {"max_allowed_packet", (char*) &max_allowed_packet, SHOW_LONG},
- {"max_binlog_cache_size", (char*) &max_binlog_cache_size, SHOW_LONG},
- {"max_binlog_size", (char*) &max_binlog_size, SHOW_LONG},
- {"max_connections", (char*) &max_connections, SHOW_LONG},
- {"max_connect_errors", (char*) &max_connect_errors, SHOW_LONG},
- {"max_delayed_threads", (char*) &max_insert_delayed_threads, SHOW_LONG},
- {"max_heap_table_size", (char*) &max_heap_table_size, SHOW_LONG},
- {"max_join_size", (char*) &max_join_size, SHOW_LONG},
- {"max_sort_length", (char*) &max_item_sort_length, SHOW_LONG},
- {"max_user_connections", (char*) &max_user_connections, SHOW_LONG},
- {"max_tmp_tables", (char*) &max_tmp_tables, SHOW_LONG},
- {"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG},
- {"myisam_max_extra_sort_file_size", (char*) &myisam_max_extra_sort_file_size,
- SHOW_LONG},
- {"myisam_max_sort_file_size",(char*) &myisam_max_sort_file_size, SHOW_LONG},
- {"myisam_recover_options", (char*) &myisam_recover_options, SHOW_LONG},
- {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
-#ifdef __NT__
- {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_BOOL},
-#endif
- {"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
- {"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
- {"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
- {"net_write_timeout", (char*) &net_write_timeout, SHOW_LONG},
- {"open_files_limit", (char*) &open_files_limit, SHOW_LONG},
- {"pid_file", (char*) pidfile_name, SHOW_CHAR},
- {"port", (char*) &mysql_port, SHOW_INT},
- {"protocol_version", (char*) &protocol_version, SHOW_INT},
- {"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG},
- {"record_rnd_buffer", (char*) &record_rnd_cache_size, SHOW_LONG},
- {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
- {"safe_show_database", (char*) &opt_safe_show_db, SHOW_BOOL},
- {"server_id", (char*) &server_id, SHOW_LONG},
- {"slave_net_timeout", (char*) &slave_net_timeout, SHOW_LONG},
- {"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
- {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
- {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
- {"slow_launch_time", (char*) &slow_launch_time, SHOW_LONG},
- {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
- {"sort_buffer", (char*) &sortbuff_size, SHOW_LONG},
- {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG},
- {"table_cache", (char*) &table_cache_size, SHOW_LONG},
- {"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR},
- {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
-#ifdef HAVE_THR_SETCONCURRENCY
- {"thread_concurrency", (char*) &concurrency, SHOW_LONG},
-#endif
- {"thread_stack", (char*) &thread_stack, SHOW_LONG},
- {"transaction_isolation", (char*) &default_tx_isolation_name, SHOW_CHAR_PTR},
-#ifdef HAVE_TZNAME
- {"timezone", time_zone, SHOW_CHAR},
-#endif
- {"tmp_table_size", (char*) &tmp_table_size, SHOW_LONG},
- {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR},
- {"version", server_version, SHOW_CHAR},
- {"wait_timeout", (char*) &net_wait_timeout, SHOW_LONG},
- {NullS, NullS, SHOW_LONG}
-};
-
struct show_var_st status_vars[]= {
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
@@ -3119,16 +3611,21 @@ struct show_var_st status_vars[]= {
{"Com_create_index", (char*) (com_stat+(uint) SQLCOM_CREATE_INDEX),SHOW_LONG},
{"Com_create_table", (char*) (com_stat+(uint) SQLCOM_CREATE_TABLE),SHOW_LONG},
{"Com_delete", (char*) (com_stat+(uint) SQLCOM_DELETE),SHOW_LONG},
+ {"Com_delete_multi", (char*) (com_stat+(uint) SQLCOM_DELETE_MULTI),SHOW_LONG},
{"Com_drop_db", (char*) (com_stat+(uint) SQLCOM_DROP_DB),SHOW_LONG},
{"Com_drop_function", (char*) (com_stat+(uint) SQLCOM_DROP_FUNCTION),SHOW_LONG},
{"Com_drop_index", (char*) (com_stat+(uint) SQLCOM_DROP_INDEX),SHOW_LONG},
{"Com_drop_table", (char*) (com_stat+(uint) SQLCOM_DROP_TABLE),SHOW_LONG},
{"Com_flush", (char*) (com_stat+(uint) SQLCOM_FLUSH),SHOW_LONG},
{"Com_grant", (char*) (com_stat+(uint) SQLCOM_GRANT),SHOW_LONG},
+ {"Com_ha_close", (char*) (com_stat+(uint) SQLCOM_HA_CLOSE),SHOW_LONG},
+ {"Com_ha_open", (char*) (com_stat+(uint) SQLCOM_HA_OPEN),SHOW_LONG},
+ {"Com_ha_read", (char*) (com_stat+(uint) SQLCOM_HA_READ),SHOW_LONG},
{"Com_insert", (char*) (com_stat+(uint) SQLCOM_INSERT),SHOW_LONG},
{"Com_insert_select", (char*) (com_stat+(uint) SQLCOM_INSERT_SELECT),SHOW_LONG},
{"Com_kill", (char*) (com_stat+(uint) SQLCOM_KILL),SHOW_LONG},
{"Com_load", (char*) (com_stat+(uint) SQLCOM_LOAD),SHOW_LONG},
+ {"Com_load_master_data", (char*) (com_stat+(uint) SQLCOM_LOAD_MASTER_DATA),SHOW_LONG},
{"Com_load_master_table", (char*) (com_stat+(uint) SQLCOM_LOAD_MASTER_TABLE),SHOW_LONG},
{"Com_lock_tables", (char*) (com_stat+(uint) SQLCOM_LOCK_TABLES),SHOW_LONG},
{"Com_optimize", (char*) (com_stat+(uint) SQLCOM_OPTIMIZE),SHOW_LONG},
@@ -3143,6 +3640,7 @@ struct show_var_st status_vars[]= {
{"Com_rollback", (char*) (com_stat+(uint) SQLCOM_ROLLBACK),SHOW_LONG},
{"Com_select", (char*) (com_stat+(uint) SQLCOM_SELECT),SHOW_LONG},
{"Com_set_option", (char*) (com_stat+(uint) SQLCOM_SET_OPTION),SHOW_LONG},
+ {"Com_show_binlog_events", (char*) (com_stat+(uint) SQLCOM_SHOW_BINLOG_EVENTS),SHOW_LONG},
{"Com_show_binlogs", (char*) (com_stat+(uint) SQLCOM_SHOW_BINLOGS),SHOW_LONG},
{"Com_show_create", (char*) (com_stat+(uint) SQLCOM_SHOW_CREATE),SHOW_LONG},
{"Com_show_databases", (char*) (com_stat+(uint) SQLCOM_SHOW_DATABASES),SHOW_LONG},
@@ -3151,8 +3649,10 @@ struct show_var_st status_vars[]= {
{"Com_show_keys", (char*) (com_stat+(uint) SQLCOM_SHOW_KEYS),SHOW_LONG},
{"Com_show_logs", (char*) (com_stat+(uint) SQLCOM_SHOW_LOGS),SHOW_LONG},
{"Com_show_master_status", (char*) (com_stat+(uint) SQLCOM_SHOW_MASTER_STAT),SHOW_LONG},
+ {"Com_show_new_master", (char*) (com_stat+(uint) SQLCOM_SHOW_NEW_MASTER),SHOW_LONG},
{"Com_show_open_tables", (char*) (com_stat+(uint) SQLCOM_SHOW_OPEN_TABLES),SHOW_LONG},
{"Com_show_processlist", (char*) (com_stat+(uint) SQLCOM_SHOW_PROCESSLIST),SHOW_LONG},
+ {"Com_show_slave_hosts", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_HOSTS),SHOW_LONG},
{"Com_show_slave_status", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_STAT),SHOW_LONG},
{"Com_show_status", (char*) (com_stat+(uint) SQLCOM_SHOW_STATUS),SHOW_LONG},
{"Com_show_innodb_status", (char*) (com_stat+(uint) SQLCOM_SHOW_INNODB_STATUS),SHOW_LONG},
@@ -3171,6 +3671,7 @@ struct show_var_st status_vars[]= {
{"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
{"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
{"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST},
+ {"Handler_commit", (char*) &ha_commit_count, SHOW_LONG},
{"Handler_delete", (char*) &ha_delete_count, SHOW_LONG},
{"Handler_read_first", (char*) &ha_read_first_count, SHOW_LONG},
{"Handler_read_key", (char*) &ha_read_key_count, SHOW_LONG},
@@ -3178,6 +3679,7 @@ struct show_var_st status_vars[]= {
{"Handler_read_prev", (char*) &ha_read_prev_count, SHOW_LONG},
{"Handler_read_rnd", (char*) &ha_read_rnd_count, SHOW_LONG},
{"Handler_read_rnd_next", (char*) &ha_read_rnd_next_count, SHOW_LONG},
+ {"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG},
{"Handler_update", (char*) &ha_update_count, SHOW_LONG},
{"Handler_write", (char*) &ha_write_count, SHOW_LONG},
{"Key_blocks_used", (char*) &_my_blocks_used, SHOW_LONG_CONST},
@@ -3193,19 +3695,57 @@ struct show_var_st status_vars[]= {
{"Open_streams", (char*) &my_stream_opened, SHOW_INT_CONST},
{"Opened_tables", (char*) &opened_tables, SHOW_LONG},
{"Questions", (char*) 0, SHOW_QUESTION},
+#ifdef HAVE_QUERY_CACHE
+ {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
+ {"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
+ {"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
+ {"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
+ {"Qcache_free_memory", (char*) &query_cache.free_memory,
+ SHOW_LONG_CONST},
+ {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks,
+ SHOW_LONG_CONST},
+ {"Qcache_total_blocks", (char*) &query_cache.total_blocks,
+ SHOW_LONG_CONST},
+#endif /*HAVE_QUERY_CACHE*/
+ {"Rpl_status", (char*) 0, SHOW_RPL_STATUS},
{"Select_full_join", (char*) &select_full_join_count, SHOW_LONG},
{"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG},
{"Select_range", (char*) &select_range_count, SHOW_LONG},
{"Select_range_check", (char*) &select_range_check_count, SHOW_LONG},
{"Select_scan", (char*) &select_scan_count, SHOW_LONG},
- {"Slave_running", (char*) &slave_running, SHOW_BOOL},
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
+ {"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) &long_query_count, SHOW_LONG},
{"Sort_merge_passes", (char*) &filesort_merge_passes, SHOW_LONG},
{"Sort_range", (char*) &filesort_range_count, SHOW_LONG},
{"Sort_rows", (char*) &filesort_rows, SHOW_LONG},
{"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG},
+#ifdef HAVE_OPENSSL
+ {"Ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
+ {"Ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD},
+ {"Ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD},
+ {"Ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
+ {"Ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE},
+ {"Ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS},
+ {"Ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS},
+ {"Ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES},
+ {"Ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS},
+ {"Ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER},
+ {"Ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT},
+ {"Ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL},
+ {"Ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE},
+ {"Ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE},
+ {"Ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED},
+ {"Ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE},
+ {"Ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH},
+ {"Ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE},
+ {"Ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH},
+ {"Ssl_version", (char*) 0, SHOW_SSL_GET_VERSION},
+ {"Ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER},
+ {"Ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST},
+ {"Ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT},
+#endif /* HAVE_OPENSSL */
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST},
@@ -3226,7 +3766,7 @@ static void use_help(void)
{
print_version();
printf("Use '--help' or '--no-defaults --help' for a list of available options\n");
-}
+}
static void usage(void)
{
@@ -3238,212 +3778,53 @@ and you are welcome to modify and redistribute it under the GPL license\n\
Starts the MySQL server\n");
printf("Usage: %s [OPTIONS]\n", my_progname);
- puts("\n\
- --ansi Use ANSI SQL syntax instead of MySQL syntax\n\
- -b, --basedir=path Path to installation directory. All paths are\n\
- usually resolved relative to this\n\
- --big-tables Allow big result sets by saving all temporary sets\n\
- on file (Solves most 'table full' errors)\n\
- --bind-address=IP Ip address to bind to\n\
- --bootstrap Used by mysql installation scripts\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- --chroot=path Chroot mysqld daemon during startup\n\
- --core-file Write core on errors\n\
- -h, --datadir=path Path to the database root");
-#ifndef DBUG_OFF
- printf("\
- -#, --debug[=...] Debug log. Default is '%s'\n",default_dbug_option);
-#ifdef SAFEMALLOC
- puts("\
- --skip-safemalloc Don't use the memory allocation checking");
-#endif
-#endif
- puts("\
- --default-character-set=charset\n\
- Set the default character set\n\
- --default-table-type=type\n\
- Set the default table type for tables\n\
- --delay-key-write-for-all-tables\n\
- Don't flush key buffers between writes for any MyISAM\n\
- table\n\
- --enable-locking Enable system locking\n\
- -T, --exit-info Used for debugging; Use at your own risk!\n\
- --flush Flush tables to disk between SQL commands\n\
- -?, --help Display this help and exit\n\
- --init-file=file Read SQL commands from this file at startup\n\
- -L, --language=... Client error messages in given language. May be\n\
- given as a full path\n\
- --local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\n\
- -l, --log[=file] Log connections and queries to file\n\
- --log-bin[=file] Log queries in new binary format (for replication)\n\
- --log-bin-index=file File that holds the names for last binary log files\n\
- --log-update[=file] Log updates to file.# where # is a unique number\n\
- if not given.\n\
- --log-isam[=file] Log all MyISAM changes to file\n\
- --log-long-format Log some extra information to update log\n\
- --low-priority-updates INSERT/DELETE/UPDATE has lower priority than selects\n\
- --log-slow-queries=[file]\n\
- Log slow queries to this log file. Defaults logging\n\
- to hostname-slow.log\n\
- --pid-file=path Pid file used by safe_mysqld\n\
- --myisam-recover[=option[,option...]] where options is one of DEAULT,\n\
- BACKUP or FORCE.\n\
- --memlock Lock mysqld in memory\n\
- -n, --new Use very new possible 'unsafe' functions\n\
- -o, --old-protocol Use the old (3.20) protocol\n\
- -P, --port=... Port number to use for connection\n");
-#ifdef ONE_THREAD
- puts("\
- --one-thread Only use one thread (for debugging under Linux)\n");
-#endif
- puts("\
- -O, --set-variable var=option\n\
- Give a variable an value. --help lists variables\n\
- -Sg, --skip-grant-tables\n\
- Start without grant tables. This gives all users\n\
- FULL ACCESS to all tables!\n\
- --safe-mode Skip some optimize stages (for testing)\n\
- --safe-show-database Don't show databases for which the user has no\n\
- privileges\n\
- --safe-user-create Don't new users cretaion without privileges to the\n\
- mysql.user table\n\
- --skip-concurrent-insert\n\
- Don't use concurrent insert with MyISAM\n\
- --skip-delay-key-write\n\
- Ignore the delay_key_write option for all tables\n\
- --skip-host-cache Don't cache host names\n\
- --skip-locking Don't use system locking. To use isamchk one has\n\
- to shut down the server.\n\
- --skip-name-resolve Don't resolve hostnames.\n\
- All hostnames are IP's or 'localhost'\n\
- --skip-networking Don't allow connection with TCP/IP.\n\
- --skip-new Don't use new, possible wrong routines.\n");
- /* We have to break the string here because of VC++ limits */
- puts("\
- --skip-stack-trace Don't print a stack trace on failure\n\
- --skip-show-database Don't allow 'SHOW DATABASE' commands\n\
- --skip-thread-priority\n\
- Don't give threads different priorities.\n\
- --socket=... Socket file to use for connection\n\
- -t, --tmpdir=path Path for temporary files\n\
- --sql-mode=option[,option[,option...]] where option can be one of:\n\
- REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES,\n\
- IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY.\n\
- --transaction-isolation\n\
- Default transaction isolation level\n\
- --temp-pool Use a pool of temporary files\n\
- -u, --user=user_name Run mysqld daemon as user\n\
- -V, --version output version information and exit\n\
- -W, --warnings Log some not critical warnings to the log file\n");
#ifdef __WIN__
puts("NT and Win32 specific options:\n\
--console Don't remove the console window\n\
--install Install the default service (NT)\n\
--install-manual Install the default service started manually (NT)\n\
+ --install service_name Install an optional service (NT)\n\
+ --install-manual service_name Install an optional service started manually (NT)\n\
--remove Remove the default service from the service list (NT)\n\
- --enable-named-pipe Enable the named pipe (NT)\n\
- --standalone Dummy option to start as a standalone program (NT)\
+ --remove service_name Remove the service_name from the service list (NT)\n\
+ --enable-named-pipe Only to be used for the default server (NT)\n\
+ --standalone Dummy option to start as a standalone server (NT)\
");
-#ifdef USE_SYMDIR
- puts("--use-symbolic-links Enable symbolic link support");
-#endif
puts("");
#endif
-#ifdef HAVE_BERKELEY_DB
- puts("\
- --bdb-home= directory Berkeley home direcory\n\
- --bdb-lock-detect=# Berkeley lock detect\n\
- (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)\n\
- --bdb-logdir=directory Berkeley DB log file directory\n\
- --bdb-no-sync Don't synchronously flush logs\n\
- --bdb-no-recover Don't try to recover Berkeley DB tables on start\n\
- --bdb-shared-data Start Berkeley DB in multi-process mode\n\
- --bdb-tmpdir=directory Berkeley DB tempfile name\n\
- --skip-bdb Don't use berkeley db (will save memory)\n\
-");
-#endif /* HAVE_BERKELEY_DB */
-#ifdef HAVE_GEMINI_DB
- puts("\
- --gemini-recovery=mode Set Crash Recovery operating mode\n\
- (FULL, NONE, FORCE - default FULL)\n\
- --gemini-flush-log-at-commit\n\
- Every commit forces a write to the reovery log\n\
- --gemini-unbuffered-io Use unbuffered i/o\n\
- --skip-gemini Don't use gemini (will save memory)\n\
-");
-#endif
-#ifdef HAVE_INNOBASE_DB
- puts("\
- --innodb_data_home_dir=dir The common part for Innodb table spaces\n\
- --innodb_data_file_path=dir Path to individual files and their sizes\n\
- --innodb_flush_method=# With which method to flush data\n\
- --innodb_flush_log_at_trx_commit[=#]\n\
- Set to 0 if you don't want to flush logs\n\
- --innodb_log_arch_dir=dir Where full logs should be archived\n\
- --innodb_log_archive[=#] Set to 1 if you want to have logs archived\n\
- --innodb_log_group_home_dir=dir Path to innodb log files.\n\
- --skip-innodb Don't use Innodb (will save memory)\n\
-");
-#endif /* HAVE_INNOBASE_DB */
print_defaults("my",load_default_groups);
puts("");
-
-#include "sslopt-usage.h"
-
fix_paths();
set_ports();
- printf("\
-To see what values a running MySQL server is using, type\n\
-'mysqladmin variables' instead of 'mysqld --help'.\n\
-The default values (after parsing the command line arguments) are:\n\n");
- printf("basedir: %s\n",mysql_home);
- printf("datadir: %s\n",mysql_real_data_home);
- printf("tmpdir: %s\n",mysql_tmpdir);
- printf("language: %s\n",language);
-#ifndef __WIN__
- printf("pid file: %s\n",pidfile_name);
-#endif
- if (opt_logname)
- printf("logfile: %s\n",opt_logname);
- if (opt_update_logname)
- printf("update log: %s\n",opt_update_logname);
- if (opt_bin_log)
- {
- printf("binary log: %s\n",opt_bin_logname ? opt_bin_logname : "");
- printf("binary log index: %s\n",
- opt_binlog_index_name ? opt_binlog_index_name : "");
- }
- if (opt_slow_logname)
- printf("update log: %s\n",opt_slow_logname);
- printf("TCP port: %d\n",mysql_port);
-#if defined(HAVE_SYS_UN_H)
- printf("Unix socket: %s\n",mysql_unix_port);
-#endif
- if (my_disable_locking)
- puts("\nsystem locking is not in use");
- if (opt_noacl)
- puts("\nGrant tables are not used. All users have full access rights");
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (uint i=0 ; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- (ulong) *changeable_vars[i].varptr);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+
+ puts("\n\
+To see what values a running MySQL server is using, type\n\
+'mysqladmin variables' instead of 'mysqld --help'.");
}
static void set_options(void)
{
- set_all_changeable_vars( changeable_vars );
#if !defined( my_pthread_setprio ) && !defined( HAVE_PTHREAD_SETSCHEDPARAM )
opt_specialflag |= SPECIAL_NO_PRIOR;
#endif
- (void) strmake(default_charset, MYSQL_CHARSET, sizeof(default_charset)-1);
+ sys_charset.value= (char*) MYSQL_CHARSET;
(void) strmake(language, LANGUAGE, sizeof(language)-1);
(void) strmake(mysql_real_data_home, get_relative_path(DATADIR),
sizeof(mysql_real_data_home-1));
+
+ /* Set default values for some variables */
+ global_system_variables.table_type=DB_TYPE_MYISAM;
+ global_system_variables.tx_isolation=ISO_READ_COMMITTED;
+ global_system_variables.select_limit= (ulong) HA_POS_ERROR;
+ max_system_variables.select_limit= (ulong) HA_POS_ERROR;
+ global_system_variables.max_join_size= (ulong) HA_POS_ERROR;
+ max_system_variables.max_join_size= (ulong) HA_POS_ERROR;
+
#ifdef __WIN__
/* Allow Win32 users to move MySQL anywhere */
{
@@ -3459,639 +3840,495 @@ static void set_options(void)
(void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
#endif
-#if defined( HAVE_mit_thread ) || defined( __WIN__ ) || defined( HAVE_LINUXTHREADS )
- my_disable_locking = 1;
-#endif
+ my_disable_locking=myisam_single_user= 1;
+ opt_external_locking=0;
my_bind_addr = htonl( INADDR_ANY );
}
- /* Initiates DEBUG - but no debugging here ! */
-static void get_options(int argc,char **argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index=0;
-
- myisam_delay_key_write=1; // Allow use of this
- while ((c=getopt_long(argc,argv,"ab:C:h:#::T::?l::L:O:P:sS::t:u:noVvWI?",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case '#':
+ switch(optid) {
+ case '#':
#ifndef DBUG_OFF
- DBUG_PUSH(optarg ? optarg : default_dbug_option);
-#endif
- opt_endinfo=1; /* unireg: memory allocation */
- break;
- case 'W':
- opt_warnings=1;
- break;
- case 'a':
- opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT |
- MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE
- | MODE_ONLY_FULL_GROUP_BY);
- default_tx_isolation= ISO_SERIALIZABLE;
- break;
- case 'b':
- strmake(mysql_home,optarg,sizeof(mysql_home)-1);
- break;
- case 'l':
- opt_log=1;
- opt_logname=optarg; // Use hostname.log if null
- break;
- case 'h':
- strmake(mysql_real_data_home,optarg, sizeof(mysql_real_data_home)-1);
- break;
- case 'L':
- strmake(language, optarg, sizeof(language)-1);
- break;
- case 'n':
- opt_specialflag|= SPECIAL_NEW_FUNC;
- break;
- case 'o':
- protocol_version=PROTOCOL_VERSION-1;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- use_help();
- exit(1);
- }
- break;
- case 'P':
- mysql_port= (unsigned int) atoi(optarg);
- break;
- case OPT_LOCAL_INFILE:
- opt_local_infile= test(!optarg || atoi(optarg) != 0);
- break;
- case OPT_SLAVE_SKIP_ERRORS:
- init_slave_skip_errors(optarg);
- break;
- case OPT_SAFEMALLOC_MEM_LIMIT:
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+#endif
+ opt_endinfo=1; /* unireg: memory allocation */
+ break;
+ case 'a':
+ opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT |
+ MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE
+ | MODE_ONLY_FULL_GROUP_BY);
+ global_system_variables.tx_isolation= ISO_SERIALIZABLE;
+ break;
+ case 'b':
+ strmake(mysql_home,argument,sizeof(mysql_home)-1);
+ break;
+ case 'l':
+ opt_log=1;
+ break;
+ case 'h':
+ strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
+ break;
+ case 'L':
+ strmake(language, argument, sizeof(language)-1);
+ break;
+ case 'n':
+ opt_specialflag|= SPECIAL_NEW_FUNC;
+ break;
+ case 'o':
+ protocol_version=PROTOCOL_VERSION-1;
+ break;
+ case OPT_SLAVE_SKIP_ERRORS:
+ init_slave_skip_errors(argument);
+ break;
+ case OPT_SAFEMALLOC_MEM_LIMIT:
#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
- safemalloc_mem_limit = atoi(optarg);
+ safemalloc_mem_limit = atoi(argument);
#endif
- break;
- case OPT_SOCKET:
- mysql_unix_port= optarg;
- break;
- case 'r':
- mysqld_chroot=optarg;
- break;
-#ifdef USE_SYMDIR
- case 's':
- my_use_symdir=1; /* Use internal symbolic links */
- break;
-#endif
- case 't':
- mysql_tmpdir=optarg;
- break;
- case OPT_TEMP_POOL:
- use_temp_pool=1;
- break;
- case 'u':
- mysqld_user=optarg;
- break;
- case 'v':
- case 'V':
- print_version();
- exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- case 'T':
- test_flags= optarg ? (uint) atoi(optarg) : 0;
- opt_endinfo=1;
- break;
- case 'S':
- if (!optarg)
- opt_specialflag|= SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE;
- else if (!strcmp(optarg,"l"))
- my_disable_locking=1;
- else if (!strcmp(optarg,"g"))
- opt_noacl=1;
- else
- {
- fprintf(stderr,"%s: Unrecognized option: %s\n",my_progname,optarg);
- use_help();
- exit(1);
- }
- break;
- case (int) OPT_BIG_TABLES:
- thd_startup_options|=OPTION_BIG_TABLES;
- break;
- case (int) OPT_ISAM_LOG:
- opt_myisam_log=1;
- if (optarg)
- myisam_log_filename=optarg;
- break;
- case (int) OPT_UPDATE_LOG:
- opt_update_log=1;
- opt_update_logname=optarg; // Use hostname.# if null
- break;
- case (int) OPT_BIN_LOG_INDEX:
- opt_binlog_index_name = optarg;
- break;
- case (int) OPT_BIN_LOG:
- opt_bin_log=1;
- x_free(opt_bin_logname);
- if (optarg && optarg[0])
- opt_bin_logname=my_strdup(optarg,MYF(0));
- break;
- // needs to be handled (as no-op) in non-debugging mode for test suite
- case (int)OPT_DISCONNECT_SLAVE_EVENT_COUNT:
-#ifndef DBUG_OFF
- disconnect_slave_event_count = atoi(optarg);
-#endif
- break;
- case (int)OPT_ABORT_SLAVE_EVENT_COUNT:
-#ifndef DBUG_OFF
- abort_slave_event_count = atoi(optarg);
-#endif
- break;
- case (int)OPT_SPORADIC_BINLOG_DUMP_FAIL:
-#ifndef DBUG_OFF
- opt_sporadic_binlog_dump_fail = 1;
-#endif
- break;
- case (int)OPT_MAX_BINLOG_DUMP_EVENTS:
-#ifndef DBUG_OFF
- max_binlog_dump_events = atoi(optarg);
-#endif
- break;
-
- case (int) OPT_LOG_SLAVE_UPDATES:
- opt_log_slave_updates = 1;
- break;
+ break;
+ case 'v':
+ case 'V':
+ print_version();
+ exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ case 'T':
+ test_flags= argument ? (uint) atoi(argument) : 0;
+ test_flags&= ~TEST_NO_THREADS;
+ opt_endinfo=1;
+ break;
+ case (int) OPT_BIG_TABLES:
+ thd_startup_options|=OPTION_BIG_TABLES;
+ break;
+ case (int) OPT_ISAM_LOG:
+ opt_myisam_log=1;
+ break;
+ case (int) OPT_UPDATE_LOG:
+ opt_update_log=1;
+ break;
+ case (int) OPT_BIN_LOG:
+ opt_bin_log=1;
+ break;
+ case (int) OPT_INIT_RPL_ROLE:
+ {
+ int role;
+ if ((role=find_type(argument, &rpl_role_typelib, 2)) <= 0)
+ {
+ fprintf(stderr, "Unknown replication role: %s\n", argument);
+ exit(1);
+ }
+ rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
+ break;
+ }
+ case (int)OPT_REPLICATE_IGNORE_DB:
+ {
+ i_string *db = new i_string(argument);
+ replicate_ignore_db.push_back(db);
+ break;
+ }
+ case (int)OPT_REPLICATE_DO_DB:
+ {
+ i_string *db = new i_string(argument);
+ replicate_do_db.push_back(db);
+ break;
+ }
+ case (int)OPT_REPLICATE_REWRITE_DB:
+ {
+ char* key = argument,*p, *val;
+
+ if (!(p= strstr(argument, "->")))
+ {
+ fprintf(stderr,
+ "Bad syntax in replicate-rewrite-db - missing '->'!\n");
+ exit(1);
+ }
+ val= p--;
+ while (isspace(*p) && p > argument)
+ *p-- = 0;
+ if (p == argument)
+ {
+ fprintf(stderr,
+ "Bad syntax in replicate-rewrite-db - empty FROM db!\n");
+ exit(1);
+ }
+ *val= 0;
+ val+= 2;
+ while (*val && isspace(*val))
+ *val++;
+ if (!*val)
+ {
+ fprintf(stderr,
+ "Bad syntax in replicate-rewrite-db - empty TO db!\n");
+ exit(1);
+ }
- case (int)OPT_REPLICATE_IGNORE_DB:
- {
- i_string *db = new i_string(optarg);
- replicate_ignore_db.push_back(db);
- break;
- }
- case (int)OPT_REPLICATE_DO_DB:
- {
- i_string *db = new i_string(optarg);
- replicate_do_db.push_back(db);
- break;
- }
- case (int)OPT_REPLICATE_REWRITE_DB:
- {
- char* key = optarg,*p, *val;
- p = strstr(optarg, "->");
- if (!p)
- {
- fprintf(stderr,
- "Bad syntax in replicate-rewrite-db - missing '->'!\n");
- exit(1);
- }
- val = p--;
- while(isspace(*p) && p > optarg) *p-- = 0;
- if(p == optarg)
- {
- fprintf(stderr,
- "Bad syntax in replicate-rewrite-db - empty FROM db!\n");
- exit(1);
- }
- *val = 0;
- val += 2;
- while(*val && isspace(*val)) *val++;
- if (!*val)
- {
- fprintf(stderr,
- "Bad syntax in replicate-rewrite-db - empty TO db!\n");
- exit(1);
- }
-
- i_string_pair* db_pair = new i_string_pair(key, val);
- replicate_rewrite_db.push_back(db_pair);
- break;
- }
+ i_string_pair *db_pair = new i_string_pair(key, val);
+ replicate_rewrite_db.push_back(db_pair);
+ break;
+ }
- case (int)OPT_BINLOG_IGNORE_DB:
- {
- i_string *db = new i_string(optarg);
- binlog_ignore_db.push_back(db);
- break;
- }
- case (int)OPT_BINLOG_DO_DB:
- {
- i_string *db = new i_string(optarg);
- binlog_do_db.push_back(db);
- break;
- }
- case (int)OPT_REPLICATE_DO_TABLE:
- {
- if (!do_table_inited)
- init_table_rule_hash(&replicate_do_table, &do_table_inited);
- if(add_table_rule(&replicate_do_table, optarg))
- {
- fprintf(stderr, "Could not add do table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int)OPT_REPLICATE_WILD_DO_TABLE:
- {
- if (!wild_do_table_inited)
- init_table_rule_array(&replicate_wild_do_table,
- &wild_do_table_inited);
- if(add_wild_table_rule(&replicate_wild_do_table, optarg))
- {
- fprintf(stderr, "Could not add do table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
- {
- if (!wild_ignore_table_inited)
- init_table_rule_array(&replicate_wild_ignore_table,
- &wild_ignore_table_inited);
- if(add_wild_table_rule(&replicate_wild_ignore_table, optarg))
- {
- fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int)OPT_REPLICATE_IGNORE_TABLE:
- {
- if (!ignore_table_inited)
- init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited);
- if(add_table_rule(&replicate_ignore_table, optarg))
- {
- fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int) OPT_SQL_BIN_UPDATE_SAME:
- opt_sql_bin_update = 1;
- break;
- case (int) OPT_SLOW_QUERY_LOG:
- opt_slow_log=1;
- opt_slow_logname=optarg;
- break;
- case (int)OPT_SKIP_SLAVE_START:
- opt_skip_slave_start = 1;
- break;
- case (int) OPT_SKIP_NEW:
- opt_specialflag|= SPECIAL_NO_NEW_FUNC;
- default_table_type=DB_TYPE_ISAM;
- myisam_delay_key_write=0;
- myisam_concurrent_insert=0;
- myisam_recover_options= HA_RECOVER_NONE;
- my_disable_symlinks=1;
- ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
- break;
- case (int) OPT_SAFE:
- opt_specialflag|= SPECIAL_SAFE_MODE;
- myisam_delay_key_write=0;
- myisam_recover_options= HA_RECOVER_NONE; // To be changed
- ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
- break;
- case (int) OPT_SKIP_CONCURRENT_INSERT:
- myisam_concurrent_insert=0;
- break;
- case (int) OPT_SKIP_PRIOR:
- opt_specialflag|= SPECIAL_NO_PRIOR;
- break;
- case (int) OPT_SKIP_GRANT:
- opt_noacl=1;
- break;
- case (int) OPT_SKIP_LOCK:
- my_disable_locking=1;
- break;
- case (int) OPT_SKIP_HOST_CACHE:
- opt_specialflag|= SPECIAL_NO_HOST_CACHE;
- break;
- case (int) OPT_ENABLE_LOCK:
- my_disable_locking=0;
- break;
- case (int) OPT_USE_LOCKING:
- my_disable_locking=0;
- break;
- case (int) OPT_SKIP_RESOLVE:
- opt_specialflag|=SPECIAL_NO_RESOLVE;
- break;
- case (int) OPT_LONG_FORMAT:
- opt_specialflag|=SPECIAL_LONG_LOG_FORMAT;
- break;
- case (int) OPT_SKIP_NETWORKING:
- opt_disable_networking=1;
- mysql_port=0;
- break;
- case (int) OPT_SKIP_SHOW_DB:
- opt_skip_show_db=1;
- opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
- mysql_port=0;
- break;
- case (int) OPT_MEMLOCK:
- locked_in_memory=1;
- break;
- case (int) OPT_ONE_THREAD:
- test_flags |= TEST_NO_THREADS;
- break;
- case (int) OPT_WANT_CORE:
- test_flags |= TEST_CORE_ON_SIGNAL;
- break;
- case (int) OPT_SKIP_STACK_TRACE:
- test_flags|=TEST_NO_STACKTRACE;
- break;
- case (int) OPT_SKIP_SYMLINKS:
- my_disable_symlinks=1;
- break;
- case (int) OPT_BIND_ADDRESS:
- if (optarg && isdigit(optarg[0]))
- {
- my_bind_addr = (ulong) inet_addr(optarg);
- }
+ case (int)OPT_BINLOG_IGNORE_DB:
+ {
+ i_string *db = new i_string(argument);
+ binlog_ignore_db.push_back(db);
+ break;
+ }
+ case (int)OPT_BINLOG_DO_DB:
+ {
+ i_string *db = new i_string(argument);
+ binlog_do_db.push_back(db);
+ break;
+ }
+ case (int)OPT_REPLICATE_DO_TABLE:
+ {
+ if (!do_table_inited)
+ init_table_rule_hash(&replicate_do_table, &do_table_inited);
+ if (add_table_rule(&replicate_do_table, argument))
+ {
+ fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int)OPT_REPLICATE_WILD_DO_TABLE:
+ {
+ if (!wild_do_table_inited)
+ init_table_rule_array(&replicate_wild_do_table,
+ &wild_do_table_inited);
+ if (add_wild_table_rule(&replicate_wild_do_table, argument))
+ {
+ fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
+ {
+ if (!wild_ignore_table_inited)
+ init_table_rule_array(&replicate_wild_ignore_table,
+ &wild_ignore_table_inited);
+ if (add_wild_table_rule(&replicate_wild_ignore_table, argument))
+ {
+ fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int)OPT_REPLICATE_IGNORE_TABLE:
+ {
+ if (!ignore_table_inited)
+ init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited);
+ if (add_table_rule(&replicate_ignore_table, argument))
+ {
+ fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int) OPT_SLOW_QUERY_LOG:
+ opt_slow_log=1;
+ break;
+ case (int)OPT_RECKLESS_SLAVE:
+ opt_reckless_slave = 1;
+ init_slave_skip_errors("all");
+ break;
+ case (int) OPT_SKIP_NEW:
+ opt_specialflag|= SPECIAL_NO_NEW_FUNC;
+ myisam_delay_key_write=0;
+ myisam_concurrent_insert=0;
+ myisam_recover_options= HA_RECOVER_NONE;
+ my_disable_symlinks=1;
+ my_use_symdir=0;
+ have_symlink=SHOW_OPTION_DISABLED;
+ ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
+#ifdef HAVE_QUERY_CACHE
+ query_cache_size=0;
+#endif
+ break;
+ case (int) OPT_SAFE:
+ opt_specialflag|= SPECIAL_SAFE_MODE;
+ myisam_delay_key_write=0;
+ myisam_recover_options= HA_RECOVER_NONE; // To be changed
+ ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
+ break;
+ case (int) OPT_SKIP_PRIOR:
+ opt_specialflag|= SPECIAL_NO_PRIOR;
+ break;
+ case (int) OPT_SKIP_LOCK:
+ opt_external_locking=0;
+ break;
+ case (int) OPT_SKIP_HOST_CACHE:
+ opt_specialflag|= SPECIAL_NO_HOST_CACHE;
+ break;
+ case (int) OPT_SKIP_RESOLVE:
+ opt_specialflag|=SPECIAL_NO_RESOLVE;
+ break;
+ case (int) OPT_LONG_FORMAT:
+ opt_specialflag|=SPECIAL_LONG_LOG_FORMAT;
+ break;
+ case (int) OPT_SKIP_NETWORKING:
+ opt_disable_networking=1;
+ mysql_port=0;
+ break;
+ case (int) OPT_SKIP_SHOW_DB:
+ opt_skip_show_db=1;
+ opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
+ mysql_port=0;
+ break;
+#ifdef ONE_THREAD
+ case (int) OPT_ONE_THREAD:
+ test_flags |= TEST_NO_THREADS;
+#endif
+ break;
+ case (int) OPT_WANT_CORE:
+ test_flags |= TEST_CORE_ON_SIGNAL;
+ break;
+ case (int) OPT_SKIP_STACK_TRACE:
+ test_flags|=TEST_NO_STACKTRACE;
+ break;
+ case (int) OPT_SKIP_SYMLINKS:
+ my_disable_symlinks=1;
+ my_use_symdir=0;
+ have_symlink=SHOW_OPTION_DISABLED;
+ break;
+ case (int) OPT_BIND_ADDRESS:
+ if (argument && isdigit(argument[0]))
+ {
+ my_bind_addr = (ulong) inet_addr(argument);
+ }
+ else
+ {
+ struct hostent *ent;
+ if (!argument || !argument[0])
+ ent=gethostbyname(argument);
else
{
- struct hostent *ent;
- if (!optarg || !optarg[0])
- ent=gethostbyname(optarg);
- else
- {
- char myhostname[255];
- if (gethostname(myhostname,sizeof(myhostname)) < 0)
- {
- sql_perror("Can't start server: cannot get my own hostname!");
- exit(1);
- }
- ent=gethostbyname(myhostname);
- }
- if (!ent)
+ char myhostname[255];
+ if (gethostname(myhostname,sizeof(myhostname)) < 0)
{
- sql_perror("Can't start server: cannot resolve hostname!");
+ sql_perror("Can't start server: cannot get my own hostname!");
exit(1);
}
- my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
+ ent=gethostbyname(myhostname);
}
- break;
- case (int) OPT_PID_FILE:
- strmake(pidfile_name, optarg, sizeof(pidfile_name)-1);
- break;
- case (int) OPT_INIT_FILE:
- opt_init_file=optarg;
- break;
- case (int) OPT_HAVE_NAMED_PIPE:
-#if __NT__
- opt_enable_named_pipe=1;
-#endif
- break;
-#ifdef __WIN__
- case (int) OPT_STANDALONE: /* Dummy option for NT */
- break;
- case (int) OPT_CONSOLE:
- opt_console=1;
- break;
-#endif
- case (int) OPT_FLUSH:
- nisam_flush=myisam_flush=1;
- flush_time=0; // No auto flush
- break;
- case OPT_LOW_PRIORITY_UPDATES:
- thd_startup_options|=OPTION_LOW_PRIORITY_UPDATES;
- thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
- low_priority_updates=1;
- break;
- case OPT_BOOTSTRAP:
- opt_noacl=opt_bootstrap=1;
- break;
- case OPT_TABLE_TYPE:
- {
- int type;
- if ((type=find_type(optarg, &ha_table_typelib, 2)) <= 0)
+ if (!ent)
{
- fprintf(stderr,"Unknown table type: %s\n",optarg);
+ sql_perror("Can't start server: cannot resolve hostname!");
exit(1);
}
- default_table_type= (enum db_type) type;
- break;
+ my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
}
- case OPT_SERVER_ID:
- server_id = atoi(optarg);
- server_id_supplied = 1;
- break;
- case OPT_DELAY_KEY_WRITE:
- ha_open_options|=HA_OPEN_DELAY_KEY_WRITE;
- myisam_delay_key_write=1;
- break;
- case OPT_SKIP_DELAY_KEY_WRITE:
- myisam_delay_key_write=0;
- break;
- case 'C':
- strmake(default_charset, optarg, sizeof(default_charset)-1);
- break;
- case OPT_CHARSETS_DIR:
- strmake(mysql_charsets_dir, optarg, sizeof(mysql_charsets_dir)-1);
- charsets_dir = mysql_charsets_dir;
- break;
+ break;
+ case (int) OPT_PID_FILE:
+ strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
+ break;
+#ifdef __WIN__
+ case (int) OPT_STANDALONE: /* Dummy option for NT */
+ break;
+#endif
+ case (int) OPT_FLUSH:
+#ifdef HAVE_ISAM
+ nisam_flush=1;
+#endif
+ myisam_flush=1;
+ flush_time=0; // No auto flush
+ break;
+ case OPT_LOW_PRIORITY_UPDATES:
+ thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
+ global_system_variables.low_priority_updates=1;
+ break;
+ case OPT_BOOTSTRAP:
+ opt_noacl=opt_bootstrap=1;
+ break;
+ case OPT_TABLE_TYPE:
+ {
+ int type;
+ if ((type=find_type(argument, &ha_table_typelib, 2)) <= 0)
+ {
+ fprintf(stderr,"Unknown table type: %s\n",argument);
+ exit(1);
+ }
+ global_system_variables.table_type= type-1;
+ break;
+ }
+ case OPT_SERVER_ID:
+ server_id_supplied = 1;
+ break;
+ case OPT_DELAY_KEY_WRITE:
+ ha_open_options|=HA_OPEN_DELAY_KEY_WRITE;
+ myisam_delay_key_write=1;
+ break;
+ case OPT_CHARSETS_DIR:
+ strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
+ charsets_dir = mysql_charsets_dir;
+ break;
+#ifdef HAVE_OPENSSL
#include "sslopt-case.h"
- case OPT_TX_ISOLATION:
+#endif
+ case OPT_DES_KEY_FILE:
+#ifdef HAVE_OPENSSL
+ des_key_file=argument;
+#endif
+ break;
+ case OPT_TX_ISOLATION:
+ {
+ int type;
+ if ((type=find_type(argument, &tx_isolation_typelib, 2)) <= 0)
{
- int type;
- if ((type=find_type(optarg, &tx_isolation_typelib, 2)) <= 0)
- {
- fprintf(stderr,"Unknown transaction isolation type: %s\n",optarg);
- exit(1);
- }
- default_tx_isolation= (enum_tx_isolation) (type-1);
- break;
+ fprintf(stderr,"Unknown transaction isolation type: %s\n",argument);
+ exit(1);
}
+ global_system_variables.tx_isolation= (type-1);
+ break;
+ }
#ifdef HAVE_BERKELEY_DB
- case OPT_BDB_LOG:
- berkeley_logdir=optarg;
- break;
- case OPT_BDB_HOME:
- berkeley_home=optarg;
- break;
- case OPT_BDB_NOSYNC:
- berkeley_env_flags|=DB_TXN_NOSYNC;
- break;
- case OPT_BDB_NO_RECOVER:
- berkeley_init_flags&= ~(DB_RECOVER);
- break;
- case OPT_BDB_TMP:
- berkeley_tmpdir=optarg;
- break;
- case OPT_BDB_LOCK:
+ case OPT_BDB_NOSYNC:
+ berkeley_env_flags|=DB_TXN_NOSYNC;
+ break;
+ case OPT_BDB_NO_RECOVER:
+ berkeley_init_flags&= ~(DB_RECOVER);
+ break;
+ case OPT_BDB_LOCK:
+ {
+ int type;
+ if ((type=find_type(argument, &berkeley_lock_typelib, 2)) > 0)
+ berkeley_lock_type=berkeley_lock_types[type-1];
+ else
{
- int type;
- if ((type=find_type(optarg, &berkeley_lock_typelib, 2)) > 0)
- berkeley_lock_type=berkeley_lock_types[type-1];
+ if (test_if_int(argument,(uint) strlen(argument)))
+ berkeley_lock_scan_time=atoi(argument);
else
{
- if (test_if_int(optarg,(uint) strlen(optarg)))
- berkeley_lock_scan_time=atoi(optarg);
- else
- {
- fprintf(stderr,"Unknown lock type: %s\n",optarg);
- exit(1);
- }
+ fprintf(stderr,"Unknown lock type: %s\n",argument);
+ exit(1);
}
- break;
}
- case OPT_BDB_SHARED:
- berkeley_init_flags&= ~(DB_PRIVATE);
- berkeley_shared_data=1;
- break;
+ break;
+ }
+ case OPT_BDB_SHARED:
+ berkeley_init_flags&= ~(DB_PRIVATE);
+ berkeley_shared_data=1;
+ break;
#endif /* HAVE_BERKELEY_DB */
- case OPT_BDB_SKIP:
+ case OPT_BDB_SKIP:
#ifdef HAVE_BERKELEY_DB
- berkeley_skip=1;
- have_berkeley_db=SHOW_OPTION_DISABLED;
+ berkeley_skip=1;
+ have_berkeley_db=SHOW_OPTION_DISABLED;
#endif
- break;
- case OPT_GEMINI_SKIP:
-#ifdef HAVE_GEMINI_DB
- gemini_skip=1;
- have_gemini=SHOW_OPTION_DISABLED;
- break;
- case OPT_GEMINI_RECOVER:
- gemini_recovery_options_str=optarg;
- if ((gemini_recovery_options=
- find_bit_type(optarg, &gemini_recovery_typelib)) == ~(ulong) 0)
- {
- fprintf(stderr, "Unknown option to gemini-recovery: %s\n",optarg);
- exit(1);
- }
- break;
- case OPT_GEMINI_FLUSH_LOG:
- gemini_options |= GEMOPT_FLUSH_LOG;
- break;
- case OPT_GEMINI_UNBUFFERED_IO:
- gemini_options |= GEMOPT_UNBUFFERED_IO;
-#endif
- break;
- case OPT_INNODB_SKIP:
+ break;
+ case OPT_INNODB_SKIP:
#ifdef HAVE_INNOBASE_DB
- innodb_skip=1;
- have_innodb=SHOW_OPTION_DISABLED;
+ innodb_skip=1;
+ have_innodb=SHOW_OPTION_DISABLED;
#endif
- break;
- case OPT_INNODB_DATA_FILE_PATH:
+ break;
+ case OPT_INNODB_DATA_FILE_PATH:
#ifdef HAVE_INNOBASE_DB
- innobase_data_file_path=optarg;
+ innobase_data_file_path=argument;
#endif
- break;
+ break;
#ifdef HAVE_INNOBASE_DB
- case OPT_INNODB_DATA_HOME_DIR:
- innobase_data_home_dir=optarg;
- break;
- case OPT_INNODB_LOG_GROUP_HOME_DIR:
- innobase_log_group_home_dir=optarg;
- break;
- case OPT_INNODB_LOG_ARCH_DIR:
- innobase_log_arch_dir=optarg;
- break;
- case OPT_INNODB_LOG_ARCHIVE:
- innobase_log_archive= optarg ? test(atoi(optarg)) : 1;
- break;
- case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
- innobase_flush_log_at_trx_commit= optarg ? atoi(optarg) : 1;
- break;
- case OPT_INNODB_FAST_SHUTDOWN:
- innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1;
- break;
- case OPT_INNODB_UNIX_FILE_FLUSH_METHOD:
- innobase_unix_file_flush_method=optarg;
- break;
+ case OPT_INNODB_LOG_ARCHIVE:
+ innobase_log_archive= argument ? test(atoi(argument)) : 1;
+ break;
+ case OPT_INNODB_FAST_SHUTDOWN:
+ innobase_fast_shutdown= argument ? test(atoi(argument)) : 1;
+ break;
#endif /* HAVE_INNOBASE_DB */
- case OPT_MYISAM_RECOVER:
+ case OPT_MYISAM_RECOVER:
+ {
+ if (!argument || !argument[0])
{
- if (!optarg)
- {
- myisam_recover_options= HA_RECOVER_DEFAULT;
- myisam_recover_options_str= myisam_recover_typelib.type_names[0];
- }
- else
- {
- myisam_recover_options_str=optarg;
- if ((myisam_recover_options=
- find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
- {
- fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
- exit(1);
- }
- }
- ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
- break;
+ myisam_recover_options= HA_RECOVER_DEFAULT;
+ myisam_recover_options_str= myisam_recover_typelib.type_names[0];
}
- case OPT_SQL_MODE:
+ else
{
- sql_mode_str = optarg;
- if ((opt_sql_mode =
- find_bit_type(optarg, &sql_mode_typelib)) == ~(ulong) 0)
+ myisam_recover_options_str=argument;
+ if ((myisam_recover_options=
+ find_bit_type(argument, &myisam_recover_typelib)) == ~(ulong) 0)
{
- fprintf(stderr, "Unknown option to sql-mode: %s\n", optarg);
+ fprintf(stderr, "Unknown option to myisam-recover: %s\n",argument);
exit(1);
}
- default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
- ISO_SERIALIZABLE :
- ISO_READ_COMMITTED);
- break;
}
- case OPT_MASTER_HOST:
- master_host=optarg;
- break;
- case OPT_MASTER_USER:
- master_user=optarg;
- break;
- case OPT_MASTER_PASSWORD:
- master_password=optarg;
- break;
- case OPT_MASTER_INFO_FILE:
- master_info_file=optarg;
- break;
- case OPT_MASTER_PORT:
- master_port= atoi(optarg);
- break;
- case OPT_MASTER_CONNECT_RETRY:
- master_connect_retry= atoi(optarg);
- break;
- case OPT_MASTER_RETRY_COUNT:
- master_retry_count= atoi(optarg);
- break;
- case OPT_SAFE_SHOW_DB:
- opt_safe_show_db=1;
- break;
- case OPT_SAFE_USER_CREATE:
- opt_safe_user_create=1;
- break;
- case OPT_SKIP_SAFEMALLOC:
-#ifdef SAFEMALLOC
- sf_malloc_quick=1;
-#endif
- break;
- default:
- fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c);
- use_help();
+ ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
+ break;
+ }
+ case OPT_SQL_MODE:
+ {
+ sql_mode_str = argument;
+ if ((opt_sql_mode =
+ find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to sql-mode: %s\n", argument);
exit(1);
}
+ global_system_variables.tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
+ ISO_SERIALIZABLE :
+ ISO_READ_COMMITTED);
+ break;
}
- // Skipp empty arguments (from shell)
- while (argc != optind && !argv[optind][0])
- optind++;
- if (argc != optind)
- {
- fprintf(stderr,"%s: Too many parameters\n",my_progname);
- use_help();
- exit(1);
+ case OPT_MASTER_PASSWORD:
+ master_password=argument;
+ break;
+ case OPT_SKIP_SAFEMALLOC:
+#ifdef SAFEMALLOC
+ sf_malloc_quick=1;
+#endif
+ break;
}
+ return 0;
+}
+
+ /* Initiates DEBUG - but no debugging here ! */
+
+static void get_options(int argc,char **argv)
+{
+ int ho_error;
+ THD *thd= current_thd;
+
+ myisam_delay_key_write=1; // Allow use of this
+#ifndef HAVE_purify
+ my_use_symdir=1; // Use internal symbolic links
+#else
+ /* Symlinks gives too many warnings with purify */
+ my_disable_symlinks=1;
+ my_use_symdir=0;
+ have_symlink=SHOW_OPTION_DISABLED;
+#endif
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ if (mysqld_chroot)
+ set_root(mysqld_chroot);
fix_paths();
- default_table_type_name=ha_table_typelib.type_names[default_table_type-1];
- default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
- /* To be deleted in MySQL 4.0 */
- if (!record_rnd_cache_size)
- record_rnd_cache_size=my_default_record_cache_size;
+
+ /*
+ Set some global variables from the global_system_variables
+ In most cases the global variables will not be used
+ */
+ my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
+ my_default_record_cache_size=global_system_variables.read_buff_size;
+ myisam_max_temp_length=
+ (my_off_t) min(global_system_variables.myisam_max_sort_file_size,
+ (ulonglong) MAX_FILE_SIZE);
+ myisam_max_extra_temp_length=
+ (my_off_t) min(global_system_variables.myisam_max_extra_sort_file_size,
+ (ulonglong) MAX_FILE_SIZE);
+
+ /* Set global variables based on startup options */
+ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
}
@@ -4109,22 +4346,45 @@ static char *get_relative_path(const char *path)
}
+/*
+ Fix filename and replace extension where 'dir' is relative to
+ mysql_real_data_home.
+ Return 1 if len(path) > FN_REFLEN
+*/
+
+bool
+fn_format_relative_to_data_home(my_string to, const char *name,
+ const char *dir, const char *extension)
+{
+ char tmp_path[FN_REFLEN];
+ if (!test_if_hard_path(dir))
+ {
+ strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
+ dir, NullS);
+ dir=tmp_path;
+ }
+ return !fn_format(to, name, dir, extension,
+ MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
+}
+
+
static void fix_paths(void)
{
+ char buff[FN_REFLEN];
(void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks
- convert_dirname(mysql_home);
- convert_dirname(mysql_real_data_home);
- convert_dirname(language);
+ convert_dirname(mysql_home,mysql_home,NullS);
+ convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
+ convert_dirname(language,language,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
- char buff[FN_REFLEN],*sharedir=get_relative_path(SHAREDIR);
+ char *sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir))
strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
else
strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
- convert_dirname(buff);
+ convert_dirname(buff,buff,NullS);
(void) my_load_path(language,language,buff);
/* If --character-sets-dir isn't given, use shared library dir */
@@ -4135,19 +4395,18 @@ static void fix_paths(void)
charsets_dir=mysql_charsets_dir;
}
- /* Add '/' to TMPDIR if needed */
- char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE));
- if (tmp)
+ char *end=convert_dirname(buff, opt_mysql_tmpdir, NullS);
+ if (!(mysql_tmpdir= my_memdup(buff,(uint) (end-buff)+1, MYF(MY_FAE))))
+ exit(1);
+ if (!slave_load_tmpdir)
{
- strmake(tmp, mysql_tmpdir, FN_REFLEN-1);
- mysql_tmpdir=tmp;
- convert_dirname(mysql_tmpdir);
- mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1,
- MYF(MY_HOLD_ON_ERROR));
+ if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
+ exit(1);
}
}
+
#ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit)
{
@@ -4162,16 +4421,17 @@ static uint set_maximum_open_files(uint max_file_limit)
rlimit.rlim_cur=rlimit.rlim_max=max_file_limit;
if (setrlimit(RLIMIT_NOFILE,&rlimit))
{
- sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %ld",
- old_cur); /* purecov: inspected */
+ sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %lu (request: %u)",
+ old_cur, max_file_limit); /* purecov: inspected */
max_file_limit=old_cur;
}
else
{
(void) getrlimit(RLIMIT_NOFILE,&rlimit);
if ((uint) rlimit.rlim_cur != max_file_limit)
- sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %ld",
- (ulong) rlimit.rlim_cur); /* purecov: inspected */
+ sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %ld (request: %u)",
+ (ulong) rlimit.rlim_cur,
+ max_file_limit); /* purecov: inspected */
max_file_limit=rlimit.rlim_cur;
}
}
@@ -4203,10 +4463,10 @@ static uint set_maximum_open_files(uint max_file_limit)
}
#endif
- /*
- Return a bitfield from a string of substrings separated by ','
- returns ~(ulong) 0 on error.
- */
+/*
+ Return a bitfield from a string of substrings separated by ','
+ returns ~(ulong) 0 on error.
+*/
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
{
@@ -4219,6 +4479,7 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
DBUG_PRINT("enter",("x: '%s'",x));
found=0;
+ found_end= 0;
pos=(my_string) x;
while (*pos == ' ') pos++;
found_end= *pos == 0;
@@ -4227,7 +4488,7 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
if (!*(end=strcend(pos,','))) /* Let end point at fieldend */
{
while (end > pos && end[-1] == ' ')
- end--; /* Skipp end-space */
+ end--; /* Skip end-space */
found_end=1;
}
found_int=0; found_count=0;
@@ -4263,7 +4524,7 @@ skipp: ;
/*****************************************************************************
-** Instantiate templates
+ Instantiate templates
*****************************************************************************/
#ifdef __GNUC__
@@ -4272,4 +4533,6 @@ template class I_List<THD>;
template class I_List_iterator<THD>;
template class I_List<i_string>;
template class I_List<i_string_pair>;
+
+FIX_GCC_LINKING_PROBLEM
#endif
diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc
index 0b50b34c7bd..a8beecd5fb4 100644
--- a/sql/net_pkg.cc
+++ b/sql/net_pkg.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,6 +30,7 @@ void send_error(NET *net, uint sql_errno, const char *err)
err ? err : net->last_error[0] ?
net->last_error : "NULL"));
+ query_cache_abort(net);
if (thd)
thd->query_error = 1; // needed to catch query errors during replication
if (!err)
@@ -51,6 +52,7 @@ void send_error(NET *net, uint sql_errno, const char *err)
{
if (thd && thd->bootstrap)
{
+ /* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
}
DBUG_VOID_RETURN;
@@ -85,9 +87,10 @@ void send_warning(NET *net, uint sql_errno, const char *err)
DBUG_VOID_RETURN;
}
-/**
-** write error package and flush to client
-** It's a little too low level, but I don't want to allow another buffer
+
+/*
+ Write error package and flush to client
+ It's a little too low level, but I don't want to allow another buffer
*/
/* VARARGS3 */
@@ -102,11 +105,17 @@ net_printf(NET *net, uint errcode, ...)
DBUG_ENTER("net_printf");
DBUG_PRINT("enter",("message: %u",errcode));
- if(thd) thd->query_error = 1;
- // if we are here, something is wrong :-)
-
+ if (thd)
+ thd->query_error = 1; // if we are here, something is wrong :-)
+ query_cache_abort(net); // Safety
va_start(args,errcode);
- format=ER(errcode);
+ /*
+ The following is needed to make net_printf() work with 0 argument for
+ errorcode and use the argument after that as the format string. This
+ is useful for rare errors that are not worth the hassle to put in
+ errmsg.sys, but at the same time, the message is not fixed text
+ */
+ format=errcode ? ER(errcode) : va_arg(args,char*);
offset= net->return_errno ? 2 : 0;
text_pos=(char*) net->buff+head_length+offset+1;
(void) vsprintf(my_const_cast(char*) (text_pos),format,args);
@@ -119,6 +128,7 @@ net_printf(NET *net, uint errcode, ...)
{
if (thd && thd->bootstrap)
{
+ /* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
thd->fatal_error=1;
}
@@ -142,7 +152,7 @@ send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message)
{
if (net->no_send_ok) // hack for re-parsing queries
return;
-
+
char buff[MYSQL_ERRMSG_SIZE+10],*pos;
DBUG_ENTER("send_ok");
buff[0]=0; // No fields
@@ -330,9 +340,9 @@ bool net_store_data(String* packet, I_List<i_string>* str_list)
I_List_iterator<i_string> it(*str_list);
i_string* s;
- while((s=it++))
+ while ((s=it++))
{
- if(tmp.length())
+ if (tmp.length())
tmp.append(',');
tmp.append(s->ptr);
}
@@ -360,3 +370,18 @@ net_store_data(String *packet, CONVERT *convert, const char *from)
return convert->store(packet, from, length);
return net_store_data(packet,from,length);
}
+
+/*
+ Function called by my_net_init() to set some check variables
+*/
+
+extern "C" {
+void my_net_local_init(NET *net)
+{
+ net->max_packet= (uint) global_system_variables.net_buffer_length;
+ net->read_timeout= (uint) global_system_variables.net_read_timeout;
+ net->write_timeout=(uint) global_system_variables.net_write_timeout;
+ net->max_packet_size= max(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+}
+}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 750079b39a5..5ff040003d5 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,130 +1,106 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Write and read of logical packets to/from socket
-** Writes are cached into net_buffer_length big packets.
-** Read packets are reallocated dynamicly when reading big packets.
-** Each logical packet has the following pre-info:
-** 3 byte length & 1 byte package-number.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Write and read of logical packets to/from socket
+
+ Writes are cached into net_buffer_length big packets.
+ Read packets are reallocated dynamicly when reading big packets.
+ Each logical packet has the following pre-info:
+ 3 byte length & 1 byte package-number.
*/
#ifdef __WIN__
#include <winsock.h>
#endif
-#include <global.h>
-#include <violite.h>
+#include <my_global.h>
+#include <mysql.h>
+#include <mysql_embed.h>
+#include <mysql_com.h>
+#include <mysqld_error.h>
#include <my_sys.h>
#include <m_string.h>
-#include "mysql.h"
-#include "mysqld_error.h"
+#include <my_net.h>
+#include <violite.h>
#include <signal.h>
#include <errno.h>
-#include <sys/types.h>
+
+/*
+ The following handles the differences when this is linked between the
+ client and the server.
+
+ This gives an error if a too big packet is found
+ The server can change this with the -O switch, but because the client
+ can't normally do this the client should have a bigger max_allowed_packet.
+*/
#ifdef MYSQL_SERVER
-ulong max_allowed_packet=65536;
-extern ulong net_read_timeout,net_write_timeout;
+#define USE_QUERY_CACHE
extern uint test_flags;
+extern void query_cache_insert(NET *net, const char *packet, ulong length);
#else
-ulong max_allowed_packet=16*1024*1024L;
-ulong net_read_timeout= NET_READ_TIMEOUT;
-ulong net_write_timeout= NET_WRITE_TIMEOUT;
#endif
-ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
-#if !defined(__WIN__) && !defined(MSDOS)
-#include <sys/socket.h>
-#else
-#undef MYSQL_SERVER /* Win32 can't handle interrupts */
-#endif
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__)
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
+#if defined(__WIN__) || !defined(MYSQL_SERVER)
+ /* The following is because alarms doesn't work on windows. */
+#define NO_ALARM
#endif
-#endif
-#include "mysqld_error.h"
-#ifdef MYSQL_SERVER
+
+#ifndef NO_ALARM
#include "my_pthread.h"
-#include "thr_alarm.h"
void sql_print_error(const char *format,...);
#define RETRY_COUNT mysqld_net_retry_count
extern ulong mysqld_net_retry_count;
-#else
-
-#ifdef OS2 /* avoid name conflict */
-#define thr_alarm_t thr_alarm_t_net
-#define ALARM ALARM_net
-#endif
-
-typedef my_bool thr_alarm_t;
-typedef my_bool ALARM;
-#define thr_alarm_init(A) (*(A))=0
-#define thr_alarm_in_use(A) (*(A))
-#define thr_end_alarm(A)
-#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
-inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
-{
- *A=1;
- return 0;
-}
-#define thr_got_alarm(A) 0
-#define RETRY_COUNT 1
-#endif
-
-#ifdef MYSQL_SERVER
-extern ulong bytes_sent, bytes_received;
+extern ulong bytes_sent, bytes_received;
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
#else
#undef statistic_add
#define statistic_add(A,B,C)
-#endif
+#define DONT_USE_THR_ALARM
+#define RETRY_COUNT 1
+#endif /* NO_ALARM */
-/*
-** Give error if a too big packet is found
-** The server can change this with the -O switch, but because the client
-** can't normally do this the client should have a bigger max-buffer.
-*/
+#include "thr_alarm.h"
#define TEST_BLOCKING 8
-static int net_write_buff(NET *net,const char *packet,uint len);
+#define MAX_THREE_BYTES 255L*255L*255L
+
+static int net_write_buff(NET *net,const char *packet,ulong len);
/* Init with packet info */
int my_net_init(NET *net, Vio* vio)
{
- if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME))))
+ my_net_local_init(net); /* Set some limits */
+ if (!(net->buff=(uchar*) my_malloc((uint32) net->max_packet+
+ NET_HEADER_SIZE + COMP_HEADER_SIZE,
+ MYF(MY_WME))))
return 1;
- if (net_buffer_length > max_allowed_packet)
- max_allowed_packet=net_buffer_length;
- net->buff_end=net->buff+(net->max_packet=net_buffer_length);
+ net->buff_end=net->buff+net->max_packet;
net->vio = vio;
net->no_send_ok = 0;
net->error=0; net->return_errno=0; net->return_status=0;
- net->timeout=(uint) net_read_timeout; /* Timeout for read */
- net->pkt_nr=0;
+ net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;
net->last_error[0]=0;
net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0;
net->last_errno=0;
+ net->query_cache_query=0;
if (vio != 0) /* If real connection */
{
@@ -138,27 +114,35 @@ int my_net_init(NET *net, Vio* vio)
return 0;
}
+
void net_end(NET *net)
{
my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR));
net->buff=0;
}
+
/* Realloc the packet buffer */
static my_bool net_realloc(NET *net, ulong length)
{
uchar *buff;
ulong pkt_length;
- if (length >= max_allowed_packet)
+ if (length >= net->max_packet_size)
{
DBUG_PRINT("error",("Packet too large (%lu)", length));
net->error=1;
net->last_errno=ER_NET_PACKET_TOO_LARGE;
return 1;
}
- pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
- if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME))))
+ pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
+ /*
+ We must allocate some extra bytes for the end 0 and to be able to
+ read big compressed blocks
+ */
+ if (!(buff=(uchar*) my_realloc((char*) net->buff, (uint32) pkt_length +
+ NET_HEADER_SIZE + COMP_HEADER_SIZE,
+ MYF(MY_WME))))
{
net->error=1;
#ifdef MYSQL_SERVER
@@ -175,22 +159,22 @@ static my_bool net_realloc(NET *net, ulong length)
void net_clear(NET *net)
{
-#ifndef EXTRA_DEBUG
- int count; // One may get 'unused' warning
+#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY)
+ int count; /* One may get 'unused' warn */
bool is_blocking=vio_is_blocking(net->vio);
if (is_blocking)
vio_blocking(net->vio, FALSE);
if (!vio_is_blocking(net->vio)) /* Safety if SSL */
{
while ( (count = vio_read(net->vio, (char*) (net->buff),
- net->max_packet)) > 0)
+ (uint32) net->max_packet)) > 0)
DBUG_PRINT("info",("skipped %d bytes from file: %s",
count,vio_description(net->vio)));
if (is_blocking)
vio_blocking(net->vio, TRUE);
}
#endif /* EXTRA_DEBUG */
- net->pkt_nr=0; /* Ready for new command */
+ net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
net->write_pos=net->buff;
}
@@ -203,9 +187,12 @@ int net_flush(NET *net)
if (net->buff != net->write_pos)
{
error=net_real_write(net,(char*) net->buff,
- (uint) (net->write_pos - net->buff));
+ (ulong) (net->write_pos - net->buff));
net->write_pos=net->buff;
}
+ /* Sync packet number if using compression */
+ if (net->compress)
+ net->pkt_nr=net->compress_pkt_nr;
DBUG_RETURN(error);
}
@@ -214,44 +201,91 @@ int net_flush(NET *net)
** Write something to server/client buffer
*****************************************************************************/
-
/*
** Write a logical packet with packet header
** Format: Packet length (3 bytes), packet number(1 byte)
** When compression is used a 3 byte compression length is added
-** NOTE: If compression is used the original package is destroyed!
+** NOTE: If compression is used the original package is modified!
*/
int
my_net_write(NET *net,const char *packet,ulong len)
{
uchar buff[NET_HEADER_SIZE];
+ /*
+ Big packets are handled by splitting them in packets of MAX_THREE_BYTES
+ length. The last packet is always a packet that is < MAX_THREE_BYTES.
+ (The last packet may even have a lengt of 0)
+ */
+ while (len >= MAX_THREE_BYTES)
+ {
+ const ulong z_size = MAX_THREE_BYTES;
+ int3store(buff, z_size);
+ buff[3]= (uchar) net->pkt_nr++;
+ if (net_write_buff(net, (char*) buff, NET_HEADER_SIZE) ||
+ net_write_buff(net, packet, z_size))
+ return 1;
+ packet += z_size;
+ len-= z_size;
+ }
+ /* Write last packet */
int3store(buff,len);
- buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
+ buff[3]= (uchar) net->pkt_nr++;
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
return 1;
return net_write_buff(net,packet,len);
}
+/*
+ Send a command to the server.
+ As the command is part of the first data packet, we have to do some data
+ juggling to put the command in there, without having to create a new
+ packet.
+ This function will split big packets into sub-packets if needed.
+ (Each sub packet can only be 2^24 bytes)
+*/
+
int
net_write_command(NET *net,uchar command,const char *packet,ulong len)
{
+ ulong length=len+1; /* 1 extra byte for command */
uchar buff[NET_HEADER_SIZE+1];
- uint length=len+1; /* 1 extra byte for command */
+ uint header_size=NET_HEADER_SIZE+1;
+ buff[4]=command; /* For first packet */
+ if (length >= MAX_THREE_BYTES)
+ {
+ /* Take into account that we have the command in the first header */
+ len= MAX_THREE_BYTES -1;
+ do
+ {
+ int3store(buff, MAX_THREE_BYTES);
+ buff[3]= (uchar) net->pkt_nr++;
+ if (net_write_buff(net,(char*) buff, header_size) ||
+ net_write_buff(net,packet,len))
+ return 1;
+ packet+= len;
+ length-= MAX_THREE_BYTES;
+ len=MAX_THREE_BYTES;
+ header_size=NET_HEADER_SIZE;
+ } while (length >= MAX_THREE_BYTES);
+ len=length; /* Data left to be written */
+ }
int3store(buff,length);
- buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
- buff[4]=command;
- if (net_write_buff(net,(char*) buff,5))
- return 1;
- return test(net_write_buff(net,packet,len) || net_flush(net));
+ buff[3]= (uchar) net->pkt_nr++;
+ return test(net_write_buff(net,(char*) buff,header_size) ||
+ net_write_buff(net,packet,len) || net_flush(net));
}
+/*
+ Caching the data in a local buffer before sending it.
+ One can force the buffer to be flushed with 'net_flush'.
+*/
static int
-net_write_buff(NET *net,const char *packet,uint len)
+net_write_buff(NET *net,const char *packet,ulong len)
{
- uint left_length=(uint) (net->buff_end - net->write_pos);
+ ulong left_length=(ulong) (net->buff_end - net->write_pos);
while (len > left_length)
{
@@ -268,21 +302,30 @@ net_write_buff(NET *net,const char *packet,uint len)
return 0;
}
-/* Read and write using timeouts */
+
+/*
+ Read and write one packet using timeouts.
+ If needed, the packet is compressed before sending.
+*/
int
net_real_write(NET *net,const char *packet,ulong len)
{
- int length;
+ long int length;
char *pos,*end;
thr_alarm_t alarmed;
-#if !defined(__WIN__)
+#ifndef NO_ALARM
ALARM alarm_buff;
#endif
uint retry_count=0;
my_bool net_blocking = vio_is_blocking(net->vio);
DBUG_ENTER("net_real_write");
+#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE)
+ if (net->query_cache_query != 0)
+ query_cache_insert(net, packet, len);
+#endif
+
if (net->error == 2)
DBUG_RETURN(-1); /* socket can't be used */
@@ -293,8 +336,8 @@ net_real_write(NET *net,const char *packet,ulong len)
ulong complen;
uchar *b;
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
- if (!(b=(uchar*) my_malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE,
- MYF(MY_WME))))
+ if (!(b=(uchar*) my_malloc((uint32) len + NET_HEADER_SIZE +
+ COMP_HEADER_SIZE, MYF(MY_WME))))
{
#ifdef MYSQL_SERVER
net->last_errno=ER_OUT_OF_RESOURCES;
@@ -313,31 +356,31 @@ net_real_write(NET *net,const char *packet,ulong len)
}
int3store(&b[NET_HEADER_SIZE],complen);
int3store(b,len);
- b[3]=(uchar) (net->pkt_nr++);
+ b[3]=(uchar) (net->compress_pkt_nr++);
len+= header_length;
packet= (char*) b;
}
#endif /* HAVE_COMPRESS */
/* DBUG_DUMP("net",packet,len); */
-#ifdef MYSQL_SERVER
+#ifndef NO_ALARM
thr_alarm_init(&alarmed);
if (net_blocking)
- thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
+ thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff);
#else
alarmed=0;
-#endif /* MYSQL_SERVER */
+#endif /* NO_ALARM */
pos=(char*) packet; end=pos+len;
while (pos != end)
{
- if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0)
+ if ((long) (length=vio_write(net->vio,pos,(uint32) (end-pos))) <= 0)
{
my_bool interrupted = vio_should_retry(net->vio);
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2))
if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
+ if (!thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff))
{ /* Always true for client */
if (!vio_is_blocking(net->vio))
{
@@ -408,20 +451,19 @@ net_real_write(NET *net,const char *packet,ulong len)
** Read something from server/clinet
*****************************************************************************/
-#ifdef MYSQL_SERVER
-
+#ifndef NO_ALARM
/*
Help function to clear the commuication buffer when we get a too
big packet
*/
-static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed)
+static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed)
{
ALARM alarm_buff;
uint retry_count=0;
if (!thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(alarmed,net->timeout,&alarm_buff) ||
+ if (!thr_alarm(alarmed,net->read_timeout,&alarm_buff) ||
(!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0))
return; /* Can't setup, abort */
}
@@ -431,21 +473,27 @@ static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed)
if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
{
my_bool interrupted = vio_should_retry(net->vio);
- if (!thr_got_alarm(alarmed) && interrupted)
+ if (!thr_got_alarm(&alarmed) && interrupted)
{ /* Probably in MIT threads */
if (retry_count++ < RETRY_COUNT)
continue;
}
return;
}
- remain -=(ulong) length;
- statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
+ remain -= (uint32) length;
+ statistic_add(bytes_received,length,&LOCK_bytes_received);
}
}
-#endif /* MYSQL_SERVER */
+#endif /* NO_ALARM */
+
+/*
+ Reads one packet to net->buff + net->where_b
+ Returns length of packet. Long packets are handled by my_net_read().
+ This function reallocates the net->buff buffer if necessary.
+*/
-static uint
+static ulong
my_real_read(NET *net, ulong *complen)
{
uchar *pos;
@@ -453,20 +501,20 @@ my_real_read(NET *net, ulong *complen)
uint i,retry_count=0;
ulong len=packet_error;
thr_alarm_t alarmed;
-#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
+#ifndef NO_ALARM
ALARM alarm_buff;
#endif
my_bool net_blocking=vio_is_blocking(net->vio);
- ulong remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
- NET_HEADER_SIZE);
+ uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
+ NET_HEADER_SIZE);
*complen = 0;
net->reading_or_writing=1;
thr_alarm_init(&alarmed);
-#ifdef MYSQL_SERVER
+#ifndef NO_ALARM
if (net_blocking)
- thr_alarm(&alarmed,net->timeout,&alarm_buff);
-#endif /* MYSQL_SERVER */
+ thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
+#endif /* NO_ALARM */
pos = net->buff + net->where_b; /* net->packet -4 */
for (i=0 ; i < 2 ; i++)
@@ -488,7 +536,7 @@ my_real_read(NET *net, ulong *complen)
*/
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */
+ if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
{
if (!vio_is_blocking(net->vio))
{
@@ -535,7 +583,7 @@ my_real_read(NET *net, ulong *complen)
continue;
}
#endif
- DBUG_PRINT("error",("Couldn't read packet: remain: %d errno: %d length: %d alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
+ DBUG_PRINT("error",("Couldn't read packet: remain: %lu errno: %d length: %ld alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
len= packet_error;
net->error=2; /* Close socket */
#ifdef MYSQL_SERVER
@@ -544,7 +592,7 @@ my_real_read(NET *net, ulong *complen)
#endif
goto end;
}
- remain -= (ulong) length;
+ remain -= (uint32) length;
pos+= (ulong) length;
statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
}
@@ -556,9 +604,9 @@ my_real_read(NET *net, ulong *complen)
if (net->buff[net->where_b] != (uchar) 255)
{
DBUG_PRINT("error",
- ("Packets out of order (Found: %d, expected %d)",
+ ("Packets out of order (Found: %d, expected %u)",
(int) net->buff[net->where_b + 3],
- (uint) (uchar) net->pkt_nr));
+ net->pkt_nr));
#ifdef EXTRA_DEBUG
fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n",
(int) net->buff[net->where_b + 3],
@@ -571,7 +619,7 @@ my_real_read(NET *net, ulong *complen)
#endif
goto end;
}
- net->pkt_nr++;
+ net->compress_pkt_nr= ++net->pkt_nr;
#ifdef HAVE_COMPRESS
if (net->compress)
{
@@ -581,23 +629,24 @@ my_real_read(NET *net, ulong *complen)
#endif
len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
helping = max(len,*complen) + net->where_b;
/* The necessary size of net->buff */
if (helping >= net->max_packet)
{
- /* We must allocate one extra byte for the end null */
- if (net_realloc(net,helping+1))
+ if (net_realloc(net,helping))
{
-#ifdef MYSQL_SERVER
+#ifndef NO_ALARM
if (i == 1)
- my_net_skip_rest(net, len, &alarmed);
+ my_net_skip_rest(net, (uint32) len, &alarmed);
#endif
len= packet_error; /* Return error */
goto end;
}
}
pos=net->buff + net->where_b;
- remain = len;
+ remain = (uint32) len;
}
}
@@ -611,7 +660,21 @@ end:
return(len);
}
-uint
+
+/*
+ Read a packet from the client/server and return it without the internal
+ package header.
+ If the packet is the first packet of a multi-packet packet
+ (which is indicated by the length of the packet = 0xffffff) then
+ all sub packets are read and concatenated.
+ If the packet was compressed, its uncompressed and the length of the
+ uncompressed packet is returned.
+
+ The function returns the length of the found packet or packet_error.
+ net->read_pos points to the read data.
+*/
+
+ulong
my_net_read(NET *net)
{
ulong len,complen;
@@ -620,65 +683,136 @@ my_net_read(NET *net)
if (!net->compress)
{
#endif
- len = my_real_read (net,&complen);
+ len = my_real_read(net,&complen);
+ if (len == MAX_THREE_BYTES)
+ {
+ /* First packet of a multi-packet. Concatenate the packets */
+ ulong save_pos = net->where_b;
+ ulong total_length=0;
+ do
+ {
+ net->where_b += len;
+ total_length += len;
+ len = my_real_read (net,&complen);
+ } while (len == MAX_THREE_BYTES);
+ if (len != packet_error)
+ len+= total_length;
+ net->where_b = save_pos;
+ }
net->read_pos = net->buff + net->where_b;
if (len != packet_error)
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
return len;
#ifdef HAVE_COMPRESS
}
- if (net->remain_in_buf)
- net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
- for (;;)
+ else
{
+ /* We are using the compressed protocol */
+
+ ulong buf_length= net->buf_length;
+ ulong start_of_packet= net->buf_length - net->remain_in_buf;
+ ulong first_packet_offset=start_of_packet;
+ uint read_length, multi_byte_packet=0;
+
if (net->remain_in_buf)
{
- uchar *pos = net->buff + net->buf_length - net->remain_in_buf;
- if (net->remain_in_buf >= 4)
+ /* Restore the character that was overwritten by the end 0 */
+ net->buff[start_of_packet]=net->save_char;
+ }
+ else
+ {
+ /* reuse buffer, as there is noting in it that we need */
+ buf_length=start_of_packet=first_packet_offset=0;
+ }
+ for (;;)
+ {
+ ulong packet_len;
+
+ if (buf_length - start_of_packet >= NET_HEADER_SIZE)
{
- net->length = uint3korr(pos);
- if (net->length <= net->remain_in_buf - 4)
+ read_length = uint3korr(net->buff+start_of_packet);
+ if (!read_length)
+ {
+ /* End of multi-byte packet */
+ start_of_packet += NET_HEADER_SIZE;
+ break;
+ }
+ if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
{
- /* We have a full packet */
- len=net->length;
- net->remain_in_buf -= net->length + 4;
- net->read_pos=pos + 4;
- break; /* We have a full packet */
+ if (multi_byte_packet)
+ {
+ /* Remove packet header for second packet */
+ memmove(net->buff + first_packet_offset + start_of_packet,
+ net->buff + first_packet_offset + start_of_packet +
+ NET_HEADER_SIZE,
+ buf_length - start_of_packet);
+ start_of_packet += read_length;
+ buf_length -= NET_HEADER_SIZE;
+ }
+ else
+ start_of_packet+= read_length + NET_HEADER_SIZE;
+
+ if (read_length != MAX_THREE_BYTES) /* last package */
+ {
+ multi_byte_packet= 0; /* No last zero len packet */
+ break;
+ }
+ multi_byte_packet= NET_HEADER_SIZE;
+ /* Move data down to read next data packet after current one */
+ if (first_packet_offset)
+ {
+ memmove(net->buff,net->buff+first_packet_offset,
+ buf_length-first_packet_offset);
+ buf_length-=first_packet_offset;
+ start_of_packet -= first_packet_offset;
+ first_packet_offset=0;
+ }
+ continue;
}
}
/* Move data down to read next data packet after current one */
- if (net->buf_length != net->remain_in_buf)
+ if (first_packet_offset)
{
- memmove(net->buff,pos,net->remain_in_buf);
- net->buf_length=net->remain_in_buf;
+ memmove(net->buff,net->buff+first_packet_offset,
+ buf_length-first_packet_offset);
+ buf_length-=first_packet_offset;
+ start_of_packet -= first_packet_offset;
+ first_packet_offset=0;
}
- net->where_b=net->buf_length;
- }
- else
- {
- net->where_b=0;
- net->buf_length=0;
- }
- if ((len = my_real_read(net,&complen)) == packet_error)
- break;
- if (my_uncompress((byte*) net->buff + net->where_b, &len, &complen))
- {
- len= packet_error;
- net->error=2; /* caller will close socket */
+ net->where_b=buf_length;
+ if ((packet_len = my_real_read(net,&complen)) == packet_error)
+ return packet_error;
+ if (my_uncompress((byte*) net->buff + net->where_b, &packet_len,
+ &complen))
+ {
+ net->error=2; /* caller will close socket */
#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_UNCOMPRESS_ERROR;
+ net->last_errno=ER_NET_UNCOMPRESS_ERROR;
#endif
- break;
+ return packet_error;
+ }
+ buf_length+=packet_len;
}
- net->buf_length+=len;
- net->remain_in_buf+=len;
- }
- if (len != packet_error)
- {
+
+ net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
+ net->buf_length= buf_length;
+ net->remain_in_buf= (ulong) (buf_length - start_of_packet);
+ len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
+ multi_byte_packet);
net->save_char= net->read_pos[len]; /* Must be saved */
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
}
+#endif /* HAVE_COMPRESS */
return len;
-#endif
+}
+
+bool net_request_file(NET* net, const char* fname)
+{
+ char tmp [FN_REFLEN+1],*end;
+ DBUG_ENTER("net_request_file");
+ tmp[0] = (char) 251; /* NULL_LENGTH */
+ end=strnmov(tmp+1,fname,sizeof(tmp)-2);
+ DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) ||
+ net_flush(net));
}
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
index 8c705a94f55..129df9864e2 100644
--- a/sql/nt_servc.cc
+++ b/sql/nt_servc.cc
@@ -479,3 +479,31 @@ If this condition persist, reboot the machine and try again\n");
return ret_value;
}
+/* ------------------------------------------------------------------------
+ -------------------------------------------------------------------------- */
+BOOL NTService::IsService(LPCSTR ServiceName)
+{
+ BOOL ret_value=FALSE;
+ SC_HANDLE service, scm;
+
+ if (scm = OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE))
+ {
+ if ((service = OpenService(scm,ServiceName, SERVICE_ALL_ACCESS )))
+ {
+ ret_value=TRUE;
+ CloseServiceHandle(service);
+ }
+ CloseServiceHandle(scm);
+ }
+ return ret_value;
+}
+/* ------------------------------------------------------------------------
+ -------------------------------------------------------------------------- */
+BOOL NTService::got_service_option(char **argv, char *service_option)
+{
+ char *option;
+ for (option= argv[1]; *option; option++)
+ if (!strcmp(option, service_option))
+ return TRUE;
+ return FALSE;
+}
diff --git a/sql/nt_servc.h b/sql/nt_servc.h
index 40d1a8c03fa..ab3238e0f41 100644
--- a/sql/nt_servc.h
+++ b/sql/nt_servc.h
@@ -52,6 +52,8 @@ class NTService
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
BOOL Remove(LPCSTR szInternName);
+ BOOL IsService(LPCSTR ServiceName);
+ BOOL got_service_option(char **argv, char *service_option);
void Stop(void); //to be called from app. to stop service
diff --git a/sql/opt_ft.h b/sql/opt_ft.h
index dcbbb8abcec..b055edc107c 100644
--- a/sql/opt_ft.h
+++ b/sql/opt_ft.h
@@ -29,7 +29,7 @@ public:
TABLE_REF *ref;
FT_SELECT(TABLE *table, TABLE_REF *tref) :
- QUICK_SELECT (table,tref->key,1), ref(tref) {}
+ QUICK_SELECT (table,tref->key,1), ref(tref) { init(); }
int init() { return error=file->ft_init(); }
int get_next() { return error=file->ft_read(record); }
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 42f20c0f767..2a76229ecf9 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -33,6 +33,7 @@
#include <m_ctype.h>
#include <nisam.h>
#include "sql_select.h"
+#include <assert.h>
#ifndef EXTRA_DEBUG
@@ -66,7 +67,9 @@ public:
SEL_ARG(Field *field, uint8 part, char *min_value, char *max_value,
uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
SEL_ARG(enum Type type_arg)
- :elements(1),use_count(1),left(0),next_key_part(0),type(type_arg) {}
+ :elements(1),use_count(1),left(0),next_key_part(0),color(BLACK),
+ type(type_arg)
+ {}
inline bool is_same(SEL_ARG *arg)
{
if (type != arg->type)
@@ -279,21 +282,21 @@ public:
typedef struct st_qsel_param {
- uint baseflag,keys,max_key_part;
- table_map prev_tables,read_tables,current_table;
TABLE *table;
- bool quick; // Don't calulate possible keys
KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY];
+ MEM_ROOT *mem_root;
+ table_map prev_tables,read_tables,current_table;
+ uint baseflag,keys,max_key_part;
uint real_keynr[MAX_KEY];
char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
+ bool quick; // Don't calulate possible keys
} PARAM;
-
static SEL_TREE * get_mm_parts(PARAM *param,Field *field,
Item_func::Functype type,Item *value,
Item_result cmp_type);
-static SEL_ARG *get_mm_leaf(Field *field,KEY_PART *key_part,
+static SEL_ARG *get_mm_leaf(PARAM *param,Field *field,KEY_PART *key_part,
Item_func::Functype type,Item *value);
static bool like_range(const char *ptr,uint length,char wild_prefix,
uint field_length, char *min_str,char *max_str,
@@ -382,7 +385,7 @@ SQL_SELECT::~SQL_SELECT()
#undef index // Fix for Unixware 7
QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc)
- :error(0),index(key_nr),max_used_key_length(0),head(table),
+ :dont_free(0),error(0),index(key_nr),max_used_key_length(0),head(table),
it(ranges),range(0)
{
if (!no_alloc)
@@ -399,13 +402,11 @@ QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc)
QUICK_SELECT::~QUICK_SELECT()
{
- file->index_end();
- free_root(&alloc,MYF(0));
-}
-
-int QUICK_SELECT::init()
-{
- return error=file->index_init(index);
+ if (!dont_free)
+ {
+ file->index_end();
+ free_root(&alloc,MYF(0));
+ }
}
QUICK_RANGE::QUICK_RANGE()
@@ -533,7 +534,7 @@ static int sel_cmp(Field *field, char *a,char *b,uint8 a_flag,uint8 b_flag)
}
if (*a)
goto end; // NULL where equal
- a++; b++; // Skipp NULL marker
+ a++; b++; // Skip NULL marker
}
cmp=field->key_cmp((byte*) a,(byte*) b);
if (cmp) return cmp < 0 ? -1 : 1; // The values differed
@@ -586,6 +587,9 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
uint idx;
double scan_time;
DBUG_ENTER("test_quick_select");
+ DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
+ (ulong) keys_to_use, (ulong) prev_tables,
+ (ulong) const_tables));
delete quick;
quick=0;
@@ -593,7 +597,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
if (!cond || (specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range ||
!limit)
DBUG_RETURN(0); /* purecov: inspected */
- if (!((basflag= head->file->option_flag()) & HA_KEYPOS_TO_RNDPOS) &&
+ if (!((basflag= head->file->table_flags()) & HA_KEYPOS_TO_RNDPOS) &&
keys_to_use == (uint) ~0 || !keys_to_use)
DBUG_RETURN(0); /* Not smart database */
records=head->file->records;
@@ -604,7 +608,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
if (limit < records)
read_time=(double) records+scan_time+1; // Force to use index
else if (read_time <= 2.0 && !force_quick_range)
- DBUG_RETURN(0); /* No nead for quick select */
+ DBUG_RETURN(0); /* No need for quick select */
DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time));
@@ -623,6 +627,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
param.current_table= head->map;
param.table=head;
param.keys=0;
+ param.mem_root= &alloc;
current_thd->no_errors=1; // Don't warn about NULL
init_sql_alloc(&alloc,2048,0);
@@ -679,27 +684,27 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
{
ha_rows found_records;
double found_read_time;
-
if (*key)
{
+ uint keynr= param.real_keynr[idx];
if ((*key)->type == SEL_ARG::MAYBE_KEY ||
(*key)->maybe_flag)
- needed_reg|= (key_map) 1 << param.real_keynr[idx];
+ needed_reg|= (key_map) 1 << keynr;
- found_records=check_quick_select(&param,idx, *key);
+ found_records=check_quick_select(&param, idx, *key);
if (found_records != HA_POS_ERROR && found_records > 2 &&
- head->used_keys & ((table_map) 1 << param.real_keynr[idx]) &&
- (head->file->option_flag() & HA_HAVE_KEY_READ_ONLY))
+ head->used_keys & ((table_map) 1 << keynr) &&
+ (head->file->index_flags(keynr) & HA_KEY_READ_ONLY))
{
/*
- ** We can resolve this by only reading through this key
- ** Assume that we will read trough the whole key range
- ** and that all key blocks are half full (normally things are
- ** much better)
+ We can resolve this by only reading through this key.
+ Assume that we will read trough the whole key range
+ and that all key blocks are half full (normally things are
+ much better).
*/
- uint keys_per_block= head->file->block_size/2/
- (head->key_info[param.real_keynr[idx]].key_length+
- head->file->ref_length) + 1;
+ uint keys_per_block= (head->file->block_size/2/
+ (head->key_info[keynr].key_length+
+ head->file->ref_length) + 1);
found_read_time=((double) (found_records+keys_per_block-1)/
(double) keys_per_block);
}
@@ -882,7 +887,7 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
if (value &&
value->used_tables() & ~(param->prev_tables | param->read_tables))
DBUG_RETURN(0);
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
{
if (field->eq(key_part->field))
{
@@ -891,7 +896,7 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
tree=new SEL_TREE();
if (!value || !(value->used_tables() & ~param->read_tables))
{
- sel_arg=get_mm_leaf(key_part->field,key_part,type,value);
+ sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value);
if (!sel_arg)
continue;
if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
@@ -911,7 +916,7 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
static SEL_ARG *
-get_mm_leaf(Field *field,KEY_PART *key_part,
+get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
Item_func::Functype type,Item *value)
{
uint maybe_null=(uint) field->real_maybe_null();
@@ -926,7 +931,7 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
String tmp(buff1,sizeof(buff1)),*res;
uint length,offset,min_length,max_length;
- if (!field->optimize_range())
+ if (!field->optimize_range((uint) key_part->key))
DBUG_RETURN(0); // Can't optimize this
if (!(res= value->val_str(&tmp)))
DBUG_RETURN(&null_element);
@@ -956,7 +961,7 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
field_length=length;
}
length+=offset;
- if (!(min_str= (char*) sql_alloc(length*2)))
+ if (!(min_str= (char*) alloc_root(param->mem_root, length*2)))
DBUG_RETURN(0);
max_str=min_str+length;
if (maybe_null)
@@ -1007,7 +1012,8 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
DBUG_RETURN(tree);
}
- if (!field->optimize_range() && type != Item_func::EQ_FUNC &&
+ if (!field->optimize_range((uint) key_part->key) &&
+ type != Item_func::EQ_FUNC &&
type != Item_func::EQUAL_FUNC)
DBUG_RETURN(0); // Can't optimize this
@@ -1023,7 +1029,8 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
if (type == Item_func::EQUAL_FUNC)
{
/* convert column_name <=> NULL -> column_name IS NULL */
- char *str= (char*) sql_alloc(1); // Get local copy of key
+ // Get local copy of key
+ char *str= (char*) alloc_root(param->mem_root,1);
if (!*str)
DBUG_RETURN(0);
*str = 1;
@@ -1032,7 +1039,8 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
DBUG_RETURN(&null_element); // NULL is never true
}
// Get local copy of key
- char *str= (char*) sql_alloc(key_part->part_length+maybe_null);
+ char *str= (char*) alloc_root(param->mem_root,
+ key_part->part_length+maybe_null);
if (!str)
DBUG_RETURN(0);
if (maybe_null)
@@ -1098,7 +1106,7 @@ static bool like_range(const char *ptr,uint ptr_length,char escape,
{
if (*ptr == escape && ptr+1 != end)
{
- ptr++; // Skipp escape
+ ptr++; // Skip escape
*min_str++= *max_str++ = *ptr;
continue;
}
@@ -2233,7 +2241,7 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
else
{
quick->key_parts=(KEY_PART*)
- sql_memdup(param->key[idx],
+ memdup_root(&quick->alloc,(char*) param->key[idx],
sizeof(KEY_PART)*
param->table->key_info[param->real_keynr[idx]].key_parts);
}
@@ -2404,7 +2412,7 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
(key_info->flags & HA_NOSAME)) ? EQ_RANGE : 0);
if (!(quick->key_parts=key_part=(KEY_PART *)
- sql_alloc(sizeof(KEY_PART)*ref->key_parts)))
+ alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
goto err;
for (part=0 ; part < ref->key_parts ;part++,key_part++)
@@ -2456,8 +2464,8 @@ int QUICK_SELECT::get_next()
if ((error=file->index_first(record)))
DBUG_RETURN(error); // Empty table
if (cmp_next(range) == 0)
- DBUG_RETURN(0); // No matching records
- range=0; // To next range
+ DBUG_RETURN(0);
+ range=0; // No matching records; go to next range
continue;
}
if ((result = file->index_read(record,(byte*) range->min_key,
@@ -2517,6 +2525,225 @@ int QUICK_SELECT::cmp_next(QUICK_RANGE *range)
return (range->flag & NEAR_MAX) ? 1 : 0; // Exact match
}
+
+/*
+ This is a hack: we inherit from QUICK_SELECT so that we can use the
+ get_next() interface, but we have to hold a pointer to the original
+ QUICK_SELECT because its data are used all over the place. What
+ should be done is to factor out the data that is needed into a base
+ class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
+ which handle the ranges and implement the get_next() function. But
+ for now, this seems to work right at least.
+ */
+
+QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts)
+ : QUICK_SELECT(*q), rev_it(rev_ranges)
+{
+ bool not_read_after_key = file->table_flags() & HA_NOT_READ_AFTER_KEY;
+ QUICK_RANGE *r;
+
+ it.rewind();
+ for (r = it++; r; r = it++)
+ {
+ rev_ranges.push_front(r);
+ if (not_read_after_key && range_reads_after_key(r) ||
+ test_if_null_range(r,used_key_parts))
+ {
+ it.rewind(); // Reset range
+ error = HA_ERR_UNSUPPORTED;
+ dont_free=1; // Don't free memory from 'q'
+ return;
+ }
+ }
+ /* Remove EQ_RANGE flag for keys that are not using the full key */
+ for (r = rev_it++; r; r = rev_it++)
+ {
+ if ((r->flag & EQ_RANGE) &&
+ head->key_info[index].key_length != r->max_length)
+ r->flag&= ~EQ_RANGE;
+ }
+ rev_it.rewind();
+ q->dont_free=1; // Don't free shared mem
+ delete q;
+}
+
+
+int QUICK_SELECT_DESC::get_next()
+{
+ DBUG_ENTER("QUICK_SELECT_DESC::get_next");
+
+ /* The max key is handled as follows:
+ * - if there is NO_MAX_RANGE, start at the end and move backwards
+ * - if it is an EQ_RANGE, which means that max key covers the entire
+ * key, go directly to the key and read through it (sorting backwards is
+ * same as sorting forwards)
+ * - if it is NEAR_MAX, go to the key or next, step back once, and
+ * move backwards
+ * - otherwise (not NEAR_MAX == include the key), go after the key,
+ * step back once, and move backwards
+ */
+
+ for (;;)
+ {
+ int result;
+ if (range)
+ { // Already read through key
+ result = ((range->flag & EQ_RANGE)
+ ? file->index_next_same(record, (byte*) range->min_key,
+ range->min_length) :
+ file->index_prev(record));
+ if (!result)
+ {
+ if (cmp_prev(*rev_it.ref()) == 0)
+ DBUG_RETURN(0);
+ }
+ else if (result != HA_ERR_END_OF_FILE)
+ DBUG_RETURN(result);
+ }
+
+ if (!(range=rev_it++))
+ DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
+
+ if (range->flag & NO_MAX_RANGE) // Read last record
+ {
+ int error;
+ if ((error=file->index_last(record)))
+ DBUG_RETURN(error); // Empty table
+ if (cmp_prev(range) == 0)
+ DBUG_RETURN(0);
+ range=0; // No matching records; go to next range
+ continue;
+ }
+
+ if (range->flag & EQ_RANGE)
+ {
+ result = file->index_read(record, (byte*) range->max_key,
+ range->max_length, HA_READ_KEY_EXACT);
+ }
+ else
+ {
+ DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
+ /* Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will
+ * do the right thing - go past all keys which match the prefix */
+ result=file->index_read(record, (byte*) range->max_key,
+ range->max_length,
+ ((range->flag & NEAR_MAX) ?
+ HA_READ_KEY_EXACT : HA_READ_AFTER_KEY));
+ result = file->index_prev(record);
+ }
+ if (result)
+ {
+ if (result != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(result);
+ range=0; // Not found, to next range
+ continue;
+ }
+ if (cmp_prev(range) == 0)
+ {
+ if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
+ range = 0; // Stop searching
+ DBUG_RETURN(0); // Found key is in range
+ }
+ range = 0; // To next range
+ }
+}
+
+/*
+ * Returns 0 if found key is inside range (found key >= range->min_key).
+ */
+int QUICK_SELECT_DESC::cmp_prev(QUICK_RANGE *range)
+{
+ if (range->flag & NO_MIN_RANGE)
+ return (0); /* key can't be to small */
+
+ KEY_PART *key_part = key_parts;
+ for (char *key = range->min_key, *end = key + range->min_length;
+ key < end;
+ key += key_part++->part_length)
+ {
+ int cmp;
+ if (key_part->null_bit)
+ {
+ // this key part allows null values; NULL is lower than everything else
+ if (*key++)
+ {
+ // the range is expecting a null value
+ if (!key_part->field->is_null())
+ return 0; // not null -- still inside the range
+ continue; // null -- exact match, go to next key part
+ }
+ else if (key_part->field->is_null())
+ return 1; // null -- outside the range
+ }
+ if ((cmp = key_part->field->key_cmp((byte*) key,
+ key_part->part_length)) > 0)
+ return 0;
+ if (cmp < 0)
+ return 1;
+ }
+ return (range->flag & NEAR_MIN) ? 1 : 0; // Exact match
+}
+
+/*
+ * True if this range will require using HA_READ_AFTER_KEY
+ See comment in get_next() about this
+ */
+
+bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range)
+{
+ return ((range->flag & (NO_MAX_RANGE | NEAR_MAX)) ||
+ !(range->flag & EQ_RANGE) ||
+ head->key_info[index].key_length != range->max_length) ? 1 : 0;
+}
+
+/* True if we are reading over a key that may have a NULL value */
+
+bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range,
+ uint used_key_parts)
+{
+ uint offset,end;
+ KEY_PART *key_part = key_parts,
+ *key_part_end= key_part+used_key_parts;
+
+ for (offset= 0, end = min(range->min_length, range->max_length) ;
+ offset < end && key_part != key_part_end ;
+ offset += key_part++->part_length)
+ {
+ uint null_length=test(key_part->null_bit);
+ if (!memcmp((char*) range->min_key+offset, (char*) range->max_key+offset,
+ key_part->part_length + null_length))
+ {
+ offset+=null_length;
+ continue;
+ }
+ if (null_length && range->min_key[offset])
+ return 1; // min_key is null and max_key isn't
+ // Range doesn't cover NULL. This is ok if there is no more null parts
+ break;
+ }
+ /*
+ If the next min_range is > NULL, then we can use this, even if
+ it's a NULL key
+ Example: SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;
+
+ */
+ if (key_part != key_part_end && key_part->null_bit)
+ {
+ if (offset >= range->min_length || range->min_key[offset])
+ return 1; // Could be null
+ key_part++;
+ }
+ /*
+ If any of the key parts used in the ORDER BY could be NULL, we can't
+ use the key to sort the data.
+ */
+ for (; key_part != key_part_end ; key_part++)
+ if (key_part->null_bit)
+ return 1; // Covers null part
+ return 0;
+}
+
+
/*****************************************************************************
** Print a quick range for debugging
** TODO:
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 247dd260817..af977eb3093 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -38,25 +38,34 @@ typedef struct st_key_part {
Field *field;
} KEY_PART;
+
class QUICK_RANGE :public Sql_alloc {
public:
char *min_key,*max_key;
uint16 min_length,max_length,flag;
+#ifdef HAVE_purify
+ uint16 dummy; /* Avoid warnings on 'flag' */
+#endif
QUICK_RANGE(); /* Full range */
QUICK_RANGE(const char *min_key_arg,uint min_length_arg,
const char *max_key_arg,uint max_length_arg,
uint flag_arg)
: min_key((char*) sql_memdup(min_key_arg,min_length_arg+1)),
max_key((char*) sql_memdup(max_key_arg,max_length_arg+1)),
- min_length(min_length_arg),
- max_length(max_length_arg),
- flag(flag_arg)
- {}
+ min_length((uint16) min_length_arg),
+ max_length((uint16) max_length_arg),
+ flag((uint16) flag_arg)
+ {
+#ifdef HAVE_purify
+ dummy=0;
+#endif
+ }
};
+
class QUICK_SELECT {
public:
- bool next;
+ bool next,dont_free;
int error;
uint index,max_used_key_length;
TABLE *head;
@@ -74,12 +83,30 @@ public:
QUICK_SELECT(TABLE *table,uint index_arg,bool no_alloc=0);
virtual ~QUICK_SELECT();
void reset(void) { next=0; it.rewind(); }
- virtual int init();
+ int init() { return error=file->index_init(index); }
virtual int get_next();
+ virtual bool reverse_sorted() { return 0; }
int cmp_next(QUICK_RANGE *range);
bool unique_key_range();
};
+
+class QUICK_SELECT_DESC: public QUICK_SELECT
+{
+public:
+ QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts);
+ int get_next();
+ bool reverse_sorted() { return 1; }
+private:
+ int cmp_prev(QUICK_RANGE *range);
+ bool range_reads_after_key(QUICK_RANGE *range);
+ bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
+ void reset(void) { next=0; rev_it.rewind(); }
+ List<QUICK_RANGE> rev_ranges;
+ List_iterator<QUICK_RANGE> rev_it;
+};
+
+
class SQL_SELECT :public Sql_alloc {
public:
QUICK_SELECT *quick; // If quick-select used
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index df49d52d54a..74e7b2ef3be 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -32,7 +32,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field,COND *cond);
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
{
- List_iterator<Item> it(all_fields);
+ List_iterator_fast<Item> it(all_fields);
int const_result=1;
bool recalc_const_item=0;
table_map removed_tables=0;
@@ -55,7 +55,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
TABLE_LIST *table;
for (table=tables; table ; table=table->next)
{
- if (table->on_expr || (table->table->file->option_flag() &
+ if (table->on_expr || (table->table->file->table_flags() &
HA_NOT_EXACT_COUNT))
{
const_result=0; // Can't optimize left join
@@ -141,7 +141,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
break;
}
TABLE *table=((Item_field*) expr)->field->table;
- if ((table->file->option_flag() & HA_NOT_READ_AFTER_KEY))
+ if ((table->file->table_flags() & HA_NOT_READ_AFTER_KEY))
{
const_result=0;
break;
@@ -152,9 +152,9 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
error=table->file->index_last(table->record[0]) !=0;
else
{
- (void) table->file->index_read(table->record[0], key_buff,
- ref.key_length,
- HA_READ_AFTER_KEY);
+ (void)table->file->index_read(table->record[0], key_buff,
+ ref.key_length,
+ HA_READ_AFTER_KEY);
error=table->file->index_prev(table->record[0]) ||
key_cmp(table,key_buff,ref.key,ref.key_length);
}
@@ -205,7 +205,7 @@ uint count_table_entries(COND *cond,TABLE *table)
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
return (cond->used_tables() & table->map) ? MAX_REF_PARTS+1 : 0;
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
uint count=0;
while ((item=li++))
@@ -250,7 +250,7 @@ bool part_of_cond(COND *cond,Field *field)
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
return 0; // Already checked
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
while ((item=li++))
{
@@ -291,21 +291,28 @@ bool part_of_cond(COND *cond,Field *field)
static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
{
if (!(field->flags & PART_KEY_FLAG))
- return 0; // Not part of a key. Skipp it
+ return 0; // Not part of a key. Skip it
TABLE *table=field->table;
- if (table->file->option_flag() & HA_WRONG_ASCII_ORDER)
- return(0); // Can't use key to find last row
uint idx=0;
/* Check if some key has field as first key part */
- if (field->key_start && (! cond || ! (cond->used_tables() & table->map)))
+ if ((field->key_start & field->table->keys_in_use_for_query) &&
+ (! cond || ! (cond->used_tables() & table->map)))
{
- for (key_map key=field->key_start ; !(key & 1) ; idx++)
- key>>=1;
+ for (key_map key=field->key_start ;;)
+ {
+ for (; !(key & 1) ; idx++)
+ key>>=1;
+ if (!(table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER))
+ break; // Key is ok
+ /* Can't use this key, for looking up min() or max(), end if last one */
+ if (key == 1)
+ return 0;
+ }
ref->key_length=0;
ref->key=idx;
- if (field->part_of_key & ((table_map) 1 << idx))
+ if (field->part_of_key & ((key_map) 1 << idx))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
@@ -322,6 +329,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
return 0;
KEY *keyinfo,*keyinfo_end;
+ idx=0;
for (keyinfo=table->key_info, keyinfo_end=keyinfo+table->keys ;
keyinfo != keyinfo_end;
keyinfo++,idx++)
@@ -337,7 +345,8 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
part++)
{
if (!part_of_cond(cond,part->field) ||
- left_length < part->store_length)
+ left_length < part->store_length ||
+ (table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER))
break;
// Save found constant
if (part->null_bit)
@@ -350,7 +359,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
{
ref->key_length= (uint) (key_ptr-ref->key_buff);
ref->key=idx;
- if (field->part_of_key & ((table_map) 1 << idx))
+ if (field->part_of_key & ((key_map) 1 << idx))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
diff --git a/sql/password.c b/sql/password.c
index 1c88aabcce2..48181ea18e6 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -34,7 +34,7 @@
This saves a hashed number as a string in the password field.
*****************************************************************************/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "mysql.h"
diff --git a/sql/procedure.cc b/sql/procedure.cc
index 526bbe0feab..437bd82d6e5 100644
--- a/sql/procedure.cc
+++ b/sql/procedure.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/procedure.h b/sql/procedure.h
index 1583f1169ce..349908a8d84 100644
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -43,6 +43,7 @@ public:
{
init_make_field(tmp_field,field_type());
}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_proc_real :public Item_proc
@@ -62,6 +63,7 @@ public:
double val() { return value; }
longlong val_int() { return (longlong) value; }
String *val_str(String *s) { s->set(value,decimals); return s; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_proc_int :public Item_proc
@@ -79,6 +81,7 @@ public:
double val() { return (double) value; }
longlong val_int() { return value; }
String *val_str(String *s) { s->set(value); return s; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -98,6 +101,7 @@ public:
{
return null_value ? (String*) 0 : (String*) &str_value;
}
+ unsigned int size_of() { return sizeof(*this);}
};
/* The procedure class definitions */
diff --git a/sql/records.cc b/sql/records.cc
index d436f4f58fe..7c3bd1110bb 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -51,12 +51,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
tempfile= &select->file;
else
tempfile= table->io_cache;
- if (select && select->quick && (! tempfile || !tempfile->buffer))
- {
- DBUG_PRINT("info",("using rr_quick"));
- info->read_record=rr_quick;
- }
- else if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
+ if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
{
DBUG_PRINT("info",("using rr_from_tempfile"));
info->read_record=rr_from_tempfile;
@@ -66,7 +61,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
table->file->rnd_init(0);
if (! (specialflag & SPECIAL_SAFE_MODE) &&
- record_rnd_cache_size &&
+ thd->variables.read_rnd_buff_size &&
!table->file->fast_key_read() &&
(table->db_stat & HA_READ_ONLY ||
table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
@@ -84,8 +79,14 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
}
}
+ else if (select && select->quick)
+ {
+ DBUG_PRINT("info",("using rr_quick"));
+ info->read_record=rr_quick;
+ }
else if (table->record_pointers)
{
+ DBUG_PRINT("info",("using record_pointers"));
table->file->rnd_init(0);
info->cache_pos=table->record_pointers;
info->cache_end=info->cache_pos+ table->found_records*info->ref_length;
@@ -101,8 +102,9 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
(int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY ||
!(table->db_options_in_use & HA_OPTION_PACK_RECORD) ||
(use_record_cache < 0 &&
- !(table->file->option_flag() & HA_NOT_DELETE_WITH_CACHE)))
- VOID(table->file->extra(HA_EXTRA_CACHE)); // Cache reads
+ !(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE)))
+ VOID(table->file->extra_opt(HA_EXTRA_CACHE,
+ thd->variables.read_buff_size));
}
DBUG_VOID_RETURN;
} /* init_read_record */
@@ -228,6 +230,8 @@ tryNext:
static int init_rr_cache(READ_RECORD *info)
{
uint rec_cache_size;
+ THD *thd= current_thd;
+
DBUG_ENTER("init_rr_cache");
info->struct_length=3+MAX_REFLENGTH;
@@ -236,7 +240,7 @@ static int init_rr_cache(READ_RECORD *info)
info->reclength=ALIGN_SIZE(info->struct_length);
info->error_offset=info->table->reclength;
- info->cache_records=record_rnd_cache_size/
+ info->cache_records= thd->variables.read_rnd_buff_size /
(info->reclength+info->struct_length);
rec_cache_size=info->cache_records*info->reclength;
info->rec_cache_size=info->cache_records*info->ref_length;
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
new file mode 100644
index 00000000000..f5f5b2de9fc
--- /dev/null
+++ b/sql/repl_failsafe.cc
@@ -0,0 +1,877 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+// Sasha Pachev <sasha@mysql.com> is currently in charge of this file
+
+#include "mysql_priv.h"
+#include "repl_failsafe.h"
+#include "sql_repl.h"
+#include "slave.h"
+#include "sql_acl.h"
+#include "mini_client.h"
+#include "log_event.h"
+#include <mysql.h>
+
+#define SLAVE_LIST_CHUNK 128
+#define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
+
+
+RPL_STATUS rpl_status=RPL_NULL;
+pthread_mutex_t LOCK_rpl_status;
+pthread_cond_t COND_rpl_status;
+HASH slave_list;
+extern const char* any_db;
+
+const char *rpl_role_type[] = {"MASTER","SLAVE",NullS};
+TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"",
+ rpl_role_type};
+
+const char* rpl_status_type[]=
+{
+ "AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", "LOST_SOLDIER","TROOP_SOLDIER",
+ "RECOVERY_CAPTAIN","NULL",NullS
+};
+TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"",
+ rpl_status_type};
+
+
+static Slave_log_event* find_slave_event(IO_CACHE* log,
+ const char* log_file_name,
+ char* errmsg);
+
+
+static int init_failsafe_rpl_thread(THD* thd)
+{
+ DBUG_ENTER("init_failsafe_rpl_thread");
+ thd->system_thread = thd->bootstrap = 1;
+ thd->client_capabilities = 0;
+ my_net_init(&thd->net, 0);
+ thd->net.read_timeout = slave_net_timeout;
+ thd->max_client_packet_length=thd->net.max_packet;
+ thd->master_access= ~0;
+ thd->priv_user = 0;
+ thd->system_thread = 1;
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->thread_id = thread_id++;
+ pthread_mutex_unlock(&LOCK_thread_count);
+
+ if (init_thr_lock() || thd->store_globals())
+ {
+ close_connection(&thd->net,ER_OUT_OF_RESOURCES); // is this needed?
+ end_thread(thd,0);
+ DBUG_RETURN(-1);
+ }
+
+ thd->mysys_var=my_thread_var;
+ thd->dbug_thread_id=my_thread_id();
+#if !defined(__WIN__) && !defined(OS2)
+ sigset_t set;
+ VOID(sigemptyset(&set)); // Get mask in use
+ VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
+#endif
+
+ thd->mem_root.free=thd->mem_root.used=0;
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
+ thd->options|= OPTION_BIG_SELECTS;
+
+ thd->proc_info="Thread initialized";
+ thd->version=refresh_version;
+ thd->set_time();
+ DBUG_RETURN(0);
+}
+
+
+void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
+{
+ pthread_mutex_lock(&LOCK_rpl_status);
+ if (rpl_status == from_status || rpl_status == RPL_ANY)
+ rpl_status = to_status;
+ pthread_cond_signal(&COND_rpl_status);
+ pthread_mutex_unlock(&LOCK_rpl_status);
+}
+
+
+#define get_object(p, obj) \
+{\
+ uint len = (uint)*p++; \
+ if (p + len > p_end || len >= sizeof(obj)) \
+ goto err; \
+ strmake(obj,(char*) p,len); \
+ p+= len; \
+}\
+
+
+static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi)
+{
+ return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name,
+ mi->pos);
+}
+
+
+void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
+{
+ if (thd->server_id)
+ {
+ if (need_mutex)
+ pthread_mutex_lock(&LOCK_slave_list);
+
+ SLAVE_INFO* old_si;
+ if ((old_si = (SLAVE_INFO*)hash_search(&slave_list,
+ (byte*)&thd->server_id, 4)) &&
+ (!only_mine || old_si->thd == thd))
+ hash_delete(&slave_list, (byte*)old_si);
+
+ if (need_mutex)
+ pthread_mutex_unlock(&LOCK_slave_list);
+ }
+}
+
+
+int register_slave(THD* thd, uchar* packet, uint packet_length)
+{
+ SLAVE_INFO *si;
+ int res = 1;
+ uchar* p = packet, *p_end = packet + packet_length;
+
+ if (check_access(thd, REPL_SLAVE_ACL, any_db))
+ return 1;
+
+ if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
+ goto err;
+
+ thd->server_id = si->server_id = uint4korr(p);
+ p += 4;
+ get_object(p,si->host);
+ get_object(p,si->user);
+ get_object(p,si->password);
+ si->port = uint2korr(p);
+ p += 2;
+ si->rpl_recovery_rank = uint4korr(p);
+ p += 4;
+ if (!(si->master_id = uint4korr(p)))
+ si->master_id = server_id;
+ si->thd = thd;
+ pthread_mutex_lock(&LOCK_slave_list);
+
+ unregister_slave(thd,0,0);
+ res = hash_insert(&slave_list, (byte*) si);
+ pthread_mutex_unlock(&LOCK_slave_list);
+ return res;
+
+err:
+ if (si)
+ my_free((gptr) si, MYF(MY_WME));
+ return res;
+}
+
+static uint32* slave_list_key(SLAVE_INFO* si, uint* len,
+ my_bool not_used __attribute__((unused)))
+{
+ *len = 4;
+ return &si->server_id;
+}
+
+static void slave_info_free(void *s)
+{
+ my_free((gptr) s, MYF(MY_WME));
+}
+
+void init_slave_list()
+{
+ hash_init(&slave_list, SLAVE_LIST_CHUNK, 0, 0,
+ (hash_get_key) slave_list_key, slave_info_free, 0);
+ pthread_mutex_init(&LOCK_slave_list, MY_MUTEX_INIT_FAST);
+}
+
+void end_slave_list()
+{
+ /* No protection by a mutex needed as we are only called at shutdown */
+ if (hash_inited(&slave_list))
+ {
+ hash_free(&slave_list);
+ pthread_mutex_destroy(&LOCK_slave_list);
+ }
+}
+
+static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg)
+{
+ my_off_t log_pos = (my_off_t) mi->pos;
+ uint32 target_server_id = mi->server_id;
+
+ for (;;)
+ {
+ Log_event* ev;
+ if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*) 0, 0)))
+ {
+ if (log->error > 0)
+ strmov(errmsg, "Binary log truncated in the middle of event");
+ else if (log->error < 0)
+ strmov(errmsg, "I/O error reading binary log");
+ else
+ strmov(errmsg, "Could not find target event in the binary log");
+ return 1;
+ }
+
+ if (ev->log_pos == log_pos && ev->server_id == target_server_id)
+ {
+ delete ev;
+ mi->pos = my_b_tell(log);
+ return 0;
+ }
+ delete ev;
+ }
+ /* Impossible */
+}
+
+
+int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
+{
+ LOG_INFO linfo;
+ char search_file_name[FN_REFLEN],last_log_name[FN_REFLEN];
+ IO_CACHE log;
+ File file = -1, last_file = -1;
+ pthread_mutex_t *log_lock;
+ const char* errmsg_p;
+ Slave_log_event* sev = 0;
+ my_off_t last_pos = 0;
+ int error = 1;
+ int cmp_res;
+ LINT_INIT(cmp_res);
+
+ if (!mysql_bin_log.is_open())
+ {
+ strmov(errmsg,"Binary log is not open");
+ return 1;
+ }
+
+ if (!server_id_supplied)
+ {
+ strmov(errmsg, "Misconfigured master - server id was not set");
+ return 1;
+ }
+
+ linfo.index_file_offset = 0;
+ search_file_name[0] = 0;
+
+ if (mysql_bin_log.find_first_log(&linfo, search_file_name))
+ {
+ strmov(errmsg,"Could not find first log");
+ return 1;
+ }
+ thd->current_linfo = &linfo;
+
+ bzero((char*) &log,sizeof(log));
+ log_lock = mysql_bin_log.get_log_lock();
+ pthread_mutex_lock(log_lock);
+
+ for (;;)
+ {
+ if ((file=open_binlog(&log, linfo.log_file_name, &errmsg_p)) < 0)
+ {
+ strmov(errmsg, errmsg_p);
+ goto err;
+ }
+
+ if (!(sev = find_slave_event(&log, linfo.log_file_name, errmsg)))
+ goto err;
+
+ cmp_res = cmp_master_pos(sev, mi);
+ delete sev;
+
+ if (!cmp_res)
+ {
+ /* Copy basename */
+ fn_format(mi->log_file_name, linfo.log_file_name, "","",1);
+ mi->pos = my_b_tell(&log);
+ goto mi_inited;
+ }
+ else if (cmp_res > 0)
+ {
+ if (!last_pos)
+ {
+ strmov(errmsg,
+ "Slave event in first log points past the target position");
+ goto err;
+ }
+ end_io_cache(&log);
+ (void) my_close(file, MYF(MY_WME));
+ if (init_io_cache(&log, (file = last_file), IO_SIZE, READ_CACHE, 0, 0,
+ MYF(MY_WME)))
+ {
+ errmsg[0] = 0;
+ goto err;
+ }
+ break;
+ }
+
+ strmov(last_log_name, linfo.log_file_name);
+ last_pos = my_b_tell(&log);
+
+ switch (mysql_bin_log.find_next_log(&linfo)) {
+ case LOG_INFO_EOF:
+ if (last_file >= 0)
+ (void)my_close(last_file, MYF(MY_WME));
+ last_file = -1;
+ goto found_log;
+ case 0:
+ break;
+ default:
+ strmov(errmsg, "Error reading log index");
+ goto err;
+ }
+
+ end_io_cache(&log);
+ if (last_file >= 0)
+ (void) my_close(last_file, MYF(MY_WME));
+ last_file = file;
+ }
+
+found_log:
+ my_b_seek(&log, last_pos);
+ if (find_target_pos(mi,&log,errmsg))
+ goto err;
+ fn_format(mi->log_file_name, last_log_name, "","",1); /* Copy basename */
+
+mi_inited:
+ error = 0;
+err:
+ pthread_mutex_unlock(log_lock);
+ end_io_cache(&log);
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->current_linfo = 0;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ if (file >= 0)
+ (void) my_close(file, MYF(MY_WME));
+ if (last_file >= 0 && last_file != file)
+ (void) my_close(last_file, MYF(MY_WME));
+
+ return error;
+}
+
+
+/*
+ Caller must delete result when done
+*/
+
+static Slave_log_event* find_slave_event(IO_CACHE* log,
+ const char* log_file_name,
+ char* errmsg)
+{
+ Log_event* ev;
+ int i;
+ bool slave_event_found = 0;
+ LINT_INIT(ev);
+
+ for (i = 0; i < 2; i++)
+ {
+ if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*)0, 0)))
+ {
+ my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
+ "Error reading event in log '%s'",
+ (char*)log_file_name);
+ return 0;
+ }
+ if (ev->get_type_code() == SLAVE_EVENT)
+ {
+ slave_event_found = 1;
+ break;
+ }
+ delete ev;
+ }
+ if (!slave_event_found)
+ {
+ my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
+ "Could not find slave event in log '%s'",
+ (char*)log_file_name);
+ delete ev;
+ return 0;
+ }
+
+ return (Slave_log_event*)ev;
+}
+
+
+int show_new_master(THD* thd)
+{
+ DBUG_ENTER("show_new_master");
+ List<Item> field_list;
+ char errmsg[SLAVE_ERRMSG_SIZE];
+ LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
+
+ errmsg[0]=0; // Safety
+ if (translate_master(thd, lex_mi, errmsg))
+ {
+ if (errmsg[0])
+ net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND,
+ "SHOW NEW MASTER", errmsg);
+ else
+ send_error(&thd->net, 0);
+
+ DBUG_RETURN(1);
+ }
+ else
+ {
+ String* packet = &thd->packet;
+ field_list.push_back(new Item_empty_string("Log_name", 20));
+ field_list.push_back(new Item_empty_string("Log_pos", 20));
+ if (send_fields(thd, field_list, 1))
+ DBUG_RETURN(-1);
+ packet->length(0);
+ net_store_data(packet, lex_mi->log_file_name);
+ net_store_data(packet, (longlong)lex_mi->pos);
+ if (my_net_write(&thd->net, packet->ptr(), packet->length()))
+ DBUG_RETURN(-1);
+ send_eof(&thd->net);
+ DBUG_RETURN(0);
+ }
+}
+
+
+int update_slave_list(MYSQL* mysql)
+{
+ MYSQL_RES* res=0;
+ MYSQL_ROW row;
+ const char* error=0;
+ bool have_auth_info;
+ int port_ind;
+
+ if (mc_mysql_query(mysql,"SHOW SLAVE HOSTS",0) ||
+ !(res = mc_mysql_store_result(mysql)))
+ {
+ error = "Query error";
+ goto err;
+ }
+
+ switch (mc_mysql_num_fields(res)) {
+ case 5:
+ have_auth_info = 0;
+ port_ind=2;
+ break;
+ case 7:
+ have_auth_info = 1;
+ port_ind=4;
+ break;
+ default:
+ error = "Invalid number of fields in SHOW SLAVE HOSTS";
+ goto err;
+ }
+
+ pthread_mutex_lock(&LOCK_slave_list);
+
+ while ((row= mc_mysql_fetch_row(res)))
+ {
+ uint32 server_id;
+ SLAVE_INFO* si, *old_si;
+ server_id = atoi(row[0]);
+ if ((old_si= (SLAVE_INFO*)hash_search(&slave_list,
+ (byte*)&server_id,4)))
+ si = old_si;
+ else
+ {
+ if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
+ {
+ error = "Out of memory";
+ pthread_mutex_unlock(&LOCK_slave_list);
+ goto err;
+ }
+ si->server_id = server_id;
+ hash_insert(&slave_list, (byte*)si);
+ }
+ strmake(si->host, row[1], sizeof(si->host)-1);
+ si->port = atoi(row[port_ind]);
+ si->rpl_recovery_rank = atoi(row[port_ind+1]);
+ si->master_id = atoi(row[port_ind+2]);
+ if (have_auth_info)
+ {
+ strmake(si->user, row[2], sizeof(si->user)-1);
+ strmake(si->password, row[3], sizeof(si->password)-1);
+ }
+ }
+ pthread_mutex_unlock(&LOCK_slave_list);
+
+err:
+ if (res)
+ mc_mysql_free_result(res);
+ if (error)
+ {
+ sql_print_error("Error updating slave list:",error);
+ return 1;
+ }
+ return 0;
+}
+
+
+int find_recovery_captain(THD* thd, MYSQL* mysql)
+{
+ return 0;
+}
+
+
+pthread_handler_decl(handle_failsafe_rpl,arg)
+{
+ DBUG_ENTER("handle_failsafe_rpl");
+ THD *thd = new THD;
+ thd->thread_stack = (char*)&thd;
+ MYSQL* recovery_captain = 0;
+ pthread_detach_this_thread();
+ if (init_failsafe_rpl_thread(thd) || !(recovery_captain=mc_mysql_init(0)))
+ {
+ sql_print_error("Could not initialize failsafe replication thread");
+ goto err;
+ }
+ pthread_mutex_lock(&LOCK_rpl_status);
+ while (!thd->killed && !abort_loop)
+ {
+ bool break_req_chain = 0;
+ const char* msg = thd->enter_cond(&COND_rpl_status,
+ &LOCK_rpl_status, "Waiting for request");
+ pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status);
+ thd->proc_info="Processing request";
+ while (!break_req_chain)
+ {
+ switch (rpl_status) {
+ case RPL_LOST_SOLDIER:
+ if (find_recovery_captain(thd, recovery_captain))
+ rpl_status=RPL_TROOP_SOLDIER;
+ else
+ rpl_status=RPL_RECOVERY_CAPTAIN;
+ break_req_chain=1; /* for now until other states are implemented */
+ break;
+ default:
+ break_req_chain=1;
+ break;
+ }
+ }
+ thd->exit_cond(msg);
+ }
+ pthread_mutex_unlock(&LOCK_rpl_status);
+err:
+ if (recovery_captain)
+ mc_mysql_close(recovery_captain);
+ delete thd;
+ my_thread_end();
+ pthread_exit(0);
+ DBUG_RETURN(0);
+}
+
+
+int show_slave_hosts(THD* thd)
+{
+ List<Item> field_list;
+ NET* net = &thd->net;
+ String* packet = &thd->packet;
+ DBUG_ENTER("show_slave_hosts");
+
+ field_list.push_back(new Item_empty_string("Server_id", 20));
+ field_list.push_back(new Item_empty_string("Host", 20));
+ if (opt_show_slave_auth_info)
+ {
+ field_list.push_back(new Item_empty_string("User",20));
+ field_list.push_back(new Item_empty_string("Password",20));
+ }
+ field_list.push_back(new Item_empty_string("Port",20));
+ field_list.push_back(new Item_empty_string("Rpl_recovery_rank", 20));
+ field_list.push_back(new Item_empty_string("Master_id", 20));
+
+ if (send_fields(thd, field_list, 1))
+ DBUG_RETURN(-1);
+
+ pthread_mutex_lock(&LOCK_slave_list);
+
+ for (uint i = 0; i < slave_list.records; ++i)
+ {
+ SLAVE_INFO* si = (SLAVE_INFO*) hash_element(&slave_list, i);
+ packet->length(0);
+ net_store_data(packet, si->server_id);
+ net_store_data(packet, si->host);
+ if (opt_show_slave_auth_info)
+ {
+ net_store_data(packet, si->user);
+ net_store_data(packet, si->password);
+ }
+ net_store_data(packet, (uint32) si->port);
+ net_store_data(packet, si->rpl_recovery_rank);
+ net_store_data(packet, si->master_id);
+ if (my_net_write(net, (char*)packet->ptr(), packet->length()))
+ {
+ pthread_mutex_unlock(&LOCK_slave_list);
+ DBUG_RETURN(-1);
+ }
+ }
+ pthread_mutex_unlock(&LOCK_slave_list);
+ send_eof(net);
+ DBUG_RETURN(0);
+}
+
+
+int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi)
+{
+ if (!mi->host || !*mi->host) /* empty host */
+ return 1;
+
+ if (!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
+ mi->port, 0, 0,
+ slave_net_timeout))
+ {
+ sql_print_error("Connection to master failed: %s",
+ mc_mysql_error(mysql));
+ return 1;
+ }
+ return 0;
+}
+
+
+static inline void cleanup_mysql_results(MYSQL_RES* db_res,
+ MYSQL_RES** cur, MYSQL_RES** start)
+{
+ for (; cur >= start; --cur)
+ {
+ if (*cur)
+ mc_mysql_free_result(*cur);
+ }
+ mc_mysql_free_result(db_res);
+}
+
+
+static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db,
+ MYSQL_RES* table_res, MASTER_INFO* mi)
+{
+ MYSQL_ROW row;
+ for (row = mc_mysql_fetch_row(table_res); row;
+ row = mc_mysql_fetch_row(table_res))
+ {
+ TABLE_LIST table;
+ const char* table_name = row[0];
+ int error;
+ if (table_rules_on)
+ {
+ table.next = 0;
+ table.db = (char*)db;
+ table.real_name = (char*)table_name;
+ table.updating = 1;
+ if (!tables_ok(thd, &table))
+ continue;
+ }
+ if ((error = fetch_master_table(thd, db, table_name, mi, mysql)))
+ return error;
+ }
+ return 0;
+}
+
+
+int load_master_data(THD* thd)
+{
+ MYSQL mysql;
+ MYSQL_RES* master_status_res = 0;
+ bool slave_was_running = 0;
+ int error = 0;
+ const char* errmsg=0;
+ int restart_thread_mask;
+ mc_mysql_init(&mysql);
+
+ /*
+ We do not want anyone messing with the slave at all for the entire
+ duration of the data load.
+ */
+ LOCK_ACTIVE_MI;
+ lock_slave_threads(active_mi);
+ init_thread_mask(&restart_thread_mask,active_mi,0 /*not inverse*/);
+ if (restart_thread_mask &&
+ (error=terminate_slave_threads(active_mi,restart_thread_mask,
+ 1 /*skip lock*/)))
+ {
+ send_error(&thd->net,error);
+ unlock_slave_threads(active_mi);
+ UNLOCK_ACTIVE_MI;
+ return 1;
+ }
+
+ if (connect_to_master(thd, &mysql, active_mi))
+ {
+ net_printf(&thd->net, error = ER_CONNECT_TO_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+
+ // now that we are connected, get all database and tables in each
+ {
+ MYSQL_RES *db_res, **table_res, **table_res_end, **cur_table_res;
+ uint num_dbs;
+
+ if (mc_mysql_query(&mysql, "show databases", 0) ||
+ !(db_res = mc_mysql_store_result(&mysql)))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+
+ if (!(num_dbs = (uint) mc_mysql_num_rows(db_res)))
+ goto err;
+ /*
+ In theory, the master could have no databases at all
+ and run with skip-grant
+ */
+
+ if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*))))
+ {
+ net_printf(&thd->net, error = ER_OUTOFMEMORY);
+ goto err;
+ }
+
+ /*
+ This is a temporary solution until we have online backup
+ capabilities - to be replaced once online backup is working
+ we wait to issue FLUSH TABLES WITH READ LOCK for as long as we
+ can to minimize the lock time.
+ */
+ if (mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 0) ||
+ mc_mysql_query(&mysql, "SHOW MASTER STATUS",0) ||
+ !(master_status_res = mc_mysql_store_result(&mysql)))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+
+ /*
+ Go through every table in every database, and if the replication
+ rules allow replicating it, get it
+ */
+
+ table_res_end = table_res + num_dbs;
+
+ for (cur_table_res = table_res; cur_table_res < table_res_end;
+ cur_table_res++)
+ {
+ // since we know how many rows we have, this can never be NULL
+ MYSQL_ROW row = mc_mysql_fetch_row(db_res);
+ char* db = row[0];
+
+ /*
+ Do not replicate databases excluded by rules
+ also skip mysql database - in most cases the user will
+ mess up and not exclude mysql database with the rules when
+ he actually means to - in this case, he is up for a surprise if
+ his priv tables get dropped and downloaded from master
+ TODO - add special option, not enabled
+ by default, to allow inclusion of mysql database into load
+ data from master
+ */
+
+ if (!db_ok(db, replicate_do_db, replicate_ignore_db) ||
+ !strcmp(db,"mysql"))
+ {
+ *cur_table_res = 0;
+ continue;
+ }
+
+ if (mysql_rm_db(thd, db, 1,1) ||
+ mysql_create_db(thd, db, 0, 1))
+ {
+ send_error(&thd->net, 0, 0);
+ cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
+ goto err;
+ }
+
+ if (mc_mysql_select_db(&mysql, db) ||
+ mc_mysql_query(&mysql, "show tables", 0) ||
+ !(*cur_table_res = mc_mysql_store_result(&mysql)))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
+ goto err;
+ }
+
+ if ((error = fetch_db_tables(thd,&mysql,db,*cur_table_res,active_mi)))
+ {
+ // we do not report the error - fetch_db_tables handles it
+ cleanup_mysql_results(db_res, cur_table_res, table_res);
+ goto err;
+ }
+ }
+
+ cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
+
+ // adjust position in the master
+ if (master_status_res)
+ {
+ MYSQL_ROW row = mc_mysql_fetch_row(master_status_res);
+
+ /*
+ We need this check because the master may not be running with
+ log-bin, but it will still allow us to do all the steps
+ of LOAD DATA FROM MASTER - no reason to forbid it, really,
+ although it does not make much sense for the user to do it
+ */
+ if (row[0] && row[1])
+ {
+ strmake(active_mi->master_log_name, row[0],
+ sizeof(active_mi->master_log_name));
+ active_mi->master_log_pos = strtoull(row[1], (char**) 0, 10);
+ // don't hit the magic number
+ if (active_mi->master_log_pos < BIN_LOG_HEADER_SIZE)
+ active_mi->master_log_pos = BIN_LOG_HEADER_SIZE;
+ active_mi->rli.pending = 0;
+ flush_master_info(active_mi);
+ }
+ mc_mysql_free_result(master_status_res);
+ }
+
+ if (mc_mysql_query(&mysql, "UNLOCK TABLES", 0))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+ }
+ thd->proc_info="purging old relay logs";
+ if (purge_relay_logs(&active_mi->rli,0 /* not only reset, but also reinit */,
+ &errmsg))
+ {
+ send_error(&thd->net, 0, "Failed purging old relay logs");
+ unlock_slave_threads(active_mi);
+ UNLOCK_ACTIVE_MI;
+ return 1;
+ }
+ pthread_mutex_lock(&active_mi->rli.data_lock);
+ active_mi->rli.master_log_pos = active_mi->master_log_pos;
+ strmake(active_mi->rli.master_log_name,active_mi->master_log_name,
+ sizeof(active_mi->rli.master_log_name)-1);
+ flush_relay_log_info(&active_mi->rli);
+ pthread_cond_broadcast(&active_mi->rli.data_cond);
+ pthread_mutex_unlock(&active_mi->rli.data_lock);
+ thd->proc_info = "starting slave";
+ if (restart_thread_mask)
+ {
+ error=start_slave_threads(0 /* mutex not needed */,
+ 1 /* wait for start */,
+ active_mi,master_info_file,relay_log_info_file,
+ restart_thread_mask);
+ }
+
+err:
+ unlock_slave_threads(active_mi);
+ UNLOCK_ACTIVE_MI;
+ thd->proc_info = 0;
+
+ mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init()
+ if (!error)
+ send_ok(&thd->net);
+
+ return error;
+}
diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h
new file mode 100644
index 00000000000..ef1dc1f8778
--- /dev/null
+++ b/sql/repl_failsafe.h
@@ -0,0 +1,37 @@
+#ifndef REPL_FAILSAFE_H
+#define REPL_FAILSAFE_H
+
+#include "mysql.h"
+#include "my_sys.h"
+#include "slave.h"
+
+typedef enum {RPL_AUTH_MASTER=0,RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE,
+ RPL_LOST_SOLDIER,RPL_TROOP_SOLDIER,
+ RPL_RECOVERY_CAPTAIN,RPL_NULL /* inactive */,
+ RPL_ANY /* wild card used by change_rpl_status */ } RPL_STATUS;
+extern RPL_STATUS rpl_status;
+
+extern pthread_mutex_t LOCK_rpl_status;
+extern pthread_cond_t COND_rpl_status;
+extern TYPELIB rpl_role_typelib, rpl_status_typelib;
+extern const char* rpl_role_type[], *rpl_status_type[];
+
+pthread_handler_decl(handle_failsafe_rpl,arg);
+void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status);
+int find_recovery_captain(THD* thd, MYSQL* mysql);
+int update_slave_list(MYSQL* mysql);
+
+extern HASH slave_list;
+
+int load_master_data(THD* thd);
+int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi);
+
+int show_new_master(THD* thd);
+int show_slave_hosts(THD* thd);
+int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg);
+void init_slave_list();
+void end_slave_list();
+int register_slave(THD* thd, uchar* packet, uint packet_length);
+void unregister_slave(THD* thd, bool only_mine, bool need_mutex);
+
+#endif
diff --git a/sql/set_var.cc b/sql/set_var.cc
new file mode 100644
index 00000000000..ec8a9e83ed3
--- /dev/null
+++ b/sql/set_var.cc
@@ -0,0 +1,1293 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Handling of MySQL SQL variables
+
+ To add a new variable, one has to do the following:
+
+ - If the variable is thread specific, add it to 'system_variables' struct.
+ If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
+ - Use one of the 'sys_var... classes from set_var.h or write a specific
+ one for the variable type.
+ - Define it in the 'variable definition list' in this file.
+ - If the variable should be changeable, it should be added to the
+ 'list of all variables' list in this file.
+ - If the variable should be changed from the command line, add a definition
+ of it in the my_option structure list in mysqld.dcc
+ - If the variable should show up in 'show variables' add it to the
+ init_vars[] struct in this file
+
+ TODO:
+ - Add full support for the variable character_set (for 4.1)
+
+ - When updating myisam_delay_key_write, we should do a 'flush tables'
+ of all MyISAM tables to ensure that they are reopen with the
+ new attribute.
+*/
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "slave.h"
+#include "sql_acl.h"
+#include <my_getopt.h>
+#include <myisam.h>
+#ifdef HAVE_BERKELEY_DB
+#include "ha_berkeley.h"
+#endif
+#ifdef HAVE_INNOBASE_DB
+#include "ha_innodb.h"
+#endif
+
+static HASH system_variable_hash;
+const char *bool_type_names[]= { "OFF", "ON", NullS };
+TYPELIB bool_typelib=
+{
+ array_elements(bool_type_names)-1, "", bool_type_names
+};
+
+static bool sys_check_charset(THD *thd, set_var *var);
+static bool sys_update_charset(THD *thd, set_var *var);
+static void sys_set_default_charset(THD *thd, enum_var_type type);
+static bool set_option_bit(THD *thd, set_var *var);
+static bool set_option_autocommit(THD *thd, set_var *var);
+static bool set_log_update(THD *thd, set_var *var);
+static void fix_low_priority_updates(THD *thd, enum_var_type type);
+static void fix_tx_isolation(THD *thd, enum_var_type type);
+static void fix_net_read_timeout(THD *thd, enum_var_type type);
+static void fix_net_write_timeout(THD *thd, enum_var_type type);
+static void fix_max_join_size(THD *thd, enum_var_type type);
+static void fix_query_cache_size(THD *thd, enum_var_type type);
+static void fix_key_buffer_size(THD *thd, enum_var_type type);
+
+/*
+ Variable definition list
+
+ These are variables that can be set from the command line, in
+ alphabetic order
+*/
+
+sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size",
+ &binlog_cache_size);
+sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size",
+ &SV::bulk_insert_buff_size);
+sys_var_str sys_charset("character_set",
+ sys_check_charset,
+ sys_update_charset,
+ sys_set_default_charset);
+sys_var_thd_conv_charset sys_convert_charset("convert_character_set");
+sys_var_bool_ptr sys_concurrent_insert("concurrent_insert",
+ &myisam_concurrent_insert);
+sys_var_long_ptr sys_connect_timeout("connect_timeout",
+ &connect_timeout);
+sys_var_bool_ptr sys_delay_key_write("delay_key_write",
+ &myisam_delay_key_write);
+sys_var_long_ptr sys_delayed_insert_limit("delayed_insert_limit",
+ &delayed_insert_limit);
+sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout",
+ &delayed_insert_timeout);
+sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size",
+ &delayed_queue_size);
+sys_var_bool_ptr sys_flush("flush", &myisam_flush);
+sys_var_long_ptr sys_flush_time("flush_time", &flush_time);
+sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
+ &SV::net_interactive_timeout);
+sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
+ &SV::join_buff_size);
+sys_var_long_ptr sys_key_buffer_size("key_buffer_size",
+ &keybuff_size,
+ fix_key_buffer_size);
+sys_var_bool_ptr sys_local_infile("local_infile",
+ &opt_local_infile);
+sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings);
+sys_var_thd_ulong sys_long_query_time("long_query_time",
+ &SV::long_query_time);
+sys_var_thd_bool sys_low_priority_updates("low_priority_updates",
+ &SV::low_priority_updates,
+ fix_low_priority_updates);
+#ifndef TO_BE_DELETED /* Alias for the low_priority_updates */
+sys_var_thd_bool sys_sql_low_priority_updates("sql_low_priority_updates",
+ &SV::low_priority_updates,
+ fix_low_priority_updates);
+#endif
+sys_var_thd_ulong sys_max_allowed_packet("max_allowed_packet",
+ &SV::max_allowed_packet);
+sys_var_long_ptr sys_max_binlog_cache_size("max_binlog_cache_size",
+ &max_binlog_cache_size);
+sys_var_long_ptr sys_max_binlog_size("max_binlog_size",
+ &max_binlog_size);
+sys_var_long_ptr sys_max_connections("max_connections",
+ &max_connections);
+sys_var_long_ptr sys_max_connect_errors("max_connect_errors",
+ &max_connect_errors);
+sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads",
+ &max_insert_delayed_threads);
+sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size",
+ &SV::max_heap_table_size);
+sys_var_thd_ulong sys_max_join_size("max_join_size",
+ &SV::max_join_size,
+ fix_max_join_size);
+#ifndef TO_BE_DELETED /* Alias for max_join_size */
+sys_var_thd_ulong sys_sql_max_join_size("sql_max_join_size",
+ &SV::max_join_size,
+ fix_max_join_size);
+#endif
+sys_var_thd_ulong sys_max_sort_length("max_sort_length",
+ &SV::max_sort_length);
+sys_var_long_ptr sys_max_user_connections("max_user_connections",
+ &max_user_connections);
+sys_var_thd_ulong sys_max_tmp_tables("max_tmp_tables",
+ &SV::max_tmp_tables);
+sys_var_long_ptr sys_max_write_lock_count("max_write_lock_count",
+ &max_write_lock_count);
+sys_var_thd_ulonglong sys_myisam_max_extra_sort_file_size("myisam_max_extra_sort_file_size", &SV::myisam_max_extra_sort_file_size);
+sys_var_thd_ulonglong sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size);
+sys_var_thd_ulong sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
+sys_var_thd_ulong sys_net_buffer_length("net_buffer_length",
+ &SV::net_buffer_length);
+sys_var_thd_ulong sys_net_read_timeout("net_read_timeout",
+ &SV::net_read_timeout,
+ fix_net_read_timeout);
+sys_var_thd_ulong sys_net_write_timeout("net_write_timeout",
+ &SV::net_write_timeout,
+ fix_net_write_timeout);
+sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
+ &SV::read_buff_size);
+sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
+ &SV::read_rnd_buff_size);
+sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank",
+ &rpl_recovery_rank);
+sys_var_long_ptr sys_query_cache_size("query_cache_size",
+ &query_cache_size,
+ fix_query_cache_size);
+#ifdef HAVE_QUERY_CACHE
+sys_var_long_ptr sys_query_cache_limit("query_cache_limit",
+ &query_cache.query_cache_limit);
+sys_var_thd_enum sys_query_cache_type("query_cache_type",
+ &SV::query_cache_type,
+ &query_cache_type_typelib);
+#endif /* HAVE_QUERY_CACHE */
+sys_var_bool_ptr sys_safe_show_db("safe_show_database",
+ &opt_safe_show_db);
+sys_var_long_ptr sys_server_id("server_id",&server_id);
+sys_var_long_ptr sys_slave_net_timeout("slave_net_timeout",
+ &slave_net_timeout);
+sys_var_long_ptr sys_slow_launch_time("slow_launch_time",
+ &slow_launch_time);
+sys_var_thd_ulong sys_sort_buffer("sort_buffer_size",
+ &SV::sortbuff_size);
+sys_var_thd_enum sys_table_type("table_type", &SV::table_type,
+ &ha_table_typelib);
+sys_var_long_ptr sys_table_cache_size("table_cache",
+ &table_cache_size);
+sys_var_long_ptr sys_thread_cache_size("thread_cache_size",
+ &thread_cache_size);
+sys_var_thd_enum sys_tx_isolation("tx_isolation",
+ &SV::tx_isolation,
+ &tx_isolation_typelib,
+ fix_tx_isolation);
+sys_var_thd_ulong sys_tmp_table_size("tmp_table_size",
+ &SV::tmp_table_size);
+sys_var_thd_ulong sys_net_wait_timeout("wait_timeout",
+ &SV::net_wait_timeout);
+
+
+/*
+ Variables that are bits in THD
+*/
+
+static sys_var_thd_bit sys_autocommit("autocommit",
+ set_option_autocommit,
+ OPTION_NOT_AUTOCOMMIT,
+ 1);
+static sys_var_thd_bit sys_big_tables("big_tables",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+#ifndef TO_BE_DELETED /* Alias for big_tables */
+static sys_var_thd_bit sys_sql_big_tables("sql_big_tables",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+#endif
+static sys_var_thd_bit sys_big_selects("sql_big_selects",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+static sys_var_thd_bit sys_log_off("sql_log_off",
+ set_option_bit,
+ OPTION_LOG_OFF);
+static sys_var_thd_bit sys_log_update("sql_log_update",
+ set_log_update,
+ OPTION_UPDATE_LOG);
+static sys_var_thd_bit sys_log_binlog("sql_log_bin",
+ set_log_update,
+ OPTION_BIN_LOG);
+static sys_var_thd_bit sys_sql_warnings("sql_warnings",
+ set_option_bit,
+ OPTION_WARNINGS);
+static sys_var_thd_bit sys_auto_is_null("sql_auto_is_null",
+ set_option_bit,
+ OPTION_AUTO_IS_NULL);
+static sys_var_thd_bit sys_safe_updates("sql_safe_updates",
+ set_option_bit,
+ OPTION_SAFE_UPDATES);
+static sys_var_thd_bit sys_buffer_results("sql_buffer_result",
+ set_option_bit,
+ OPTION_BUFFER_RESULT);
+static sys_var_thd_bit sys_quote_show_create("sql_quote_show_create",
+ set_option_bit,
+ OPTION_QUOTE_SHOW_CREATE);
+
+/* Local state variables */
+
+static sys_var_thd_ulong sys_select_limit("sql_select_limit",
+ &SV::select_limit);
+static sys_var_timestamp sys_timestamp("timestamp");
+static sys_var_last_insert_id sys_last_insert_id("last_insert_id");
+static sys_var_last_insert_id sys_identity("identity");
+static sys_var_insert_id sys_insert_id("insert_id");
+/* alias for last_insert_id() to be compatible with Sybase */
+static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter");
+
+
+/*
+ List of all variables for initialisation and storage in hash
+ This is sorted in alphabetical order to make it easy to add new variables
+
+ If the variable is not in this list, it can't be changed with
+ SET variable_name=
+*/
+
+sys_var *sys_variables[]=
+{
+ &sys_auto_is_null,
+ &sys_autocommit,
+ &sys_big_tables,
+ &sys_big_selects,
+ &sys_binlog_cache_size,
+ &sys_buffer_results,
+ &sys_bulk_insert_buff_size,
+ &sys_concurrent_insert,
+ &sys_connect_timeout,
+ &sys_convert_charset,
+ &sys_delay_key_write,
+ &sys_delayed_insert_limit,
+ &sys_delayed_insert_timeout,
+ &sys_delayed_queue_size,
+ &sys_flush,
+ &sys_flush_time,
+ &sys_identity,
+ &sys_insert_id,
+ &sys_interactive_timeout,
+ &sys_join_buffer_size,
+ &sys_key_buffer_size,
+ &sys_last_insert_id,
+ &sys_local_infile,
+ &sys_log_binlog,
+ &sys_log_off,
+ &sys_log_update,
+ &sys_log_warnings,
+ &sys_long_query_time,
+ &sys_low_priority_updates,
+ &sys_max_allowed_packet,
+ &sys_max_binlog_cache_size,
+ &sys_max_binlog_size,
+ &sys_max_connect_errors,
+ &sys_max_connections,
+ &sys_max_delayed_threads,
+ &sys_max_heap_table_size,
+ &sys_max_join_size,
+ &sys_max_sort_length,
+ &sys_max_tmp_tables,
+ &sys_max_user_connections,
+ &sys_max_write_lock_count,
+ &sys_myisam_max_extra_sort_file_size,
+ &sys_myisam_max_sort_file_size,
+ &sys_myisam_sort_buffer_size,
+ &sys_net_buffer_length,
+ &sys_net_read_timeout,
+ &sys_net_wait_timeout,
+ &sys_net_write_timeout,
+ &sys_query_cache_size,
+#ifdef HAVE_QUERY_CACHE
+ &sys_query_cache_limit,
+ &sys_query_cache_type,
+#endif HAVE_QUERY_CACHE
+ &sys_quote_show_create,
+ &sys_read_buff_size,
+ &sys_read_rnd_buff_size,
+ &sys_rpl_recovery_rank,
+ &sys_safe_show_db,
+ &sys_safe_updates,
+ &sys_select_limit,
+ &sys_server_id,
+ &sys_slave_net_timeout,
+ &sys_slave_skip_counter,
+ &sys_slow_launch_time,
+ &sys_sort_buffer,
+ &sys_sql_big_tables,
+ &sys_sql_low_priority_updates,
+ &sys_sql_max_join_size,
+ &sys_sql_warnings,
+ &sys_table_cache_size,
+ &sys_table_type,
+ &sys_thread_cache_size,
+ &sys_timestamp,
+ &sys_tmp_table_size,
+ &sys_tx_isolation,
+};
+
+
+/*
+ Variables shown by SHOW variables in alphabetical order
+*/
+
+struct show_var_st init_vars[]= {
+ {"back_log", (char*) &back_log, SHOW_LONG},
+ {"basedir", mysql_home, SHOW_CHAR},
+#ifdef HAVE_BERKELEY_DB
+ {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
+ {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
+ {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
+ {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
+ {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
+ {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
+ {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
+ {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR},
+#endif
+ {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size, SHOW_SYS},
+ {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
+ {sys_charset.name, (char*) &sys_charset, SHOW_SYS},
+ {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
+ {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
+ {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
+ {sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
+ {"datadir", mysql_real_data_home, SHOW_CHAR},
+ {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS},
+ {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
+ {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
+ {sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size, SHOW_SYS},
+ {sys_flush.name, (char*) &sys_flush, SHOW_SYS},
+ {sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
+ {"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG},
+ {"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG},
+ {"ft_max_word_len_for_sort",(char*) &ft_max_word_len_for_sort, SHOW_LONG},
+ {"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR},
+ {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
+ {"have_innodb", (char*) &have_innodb, SHOW_HAVE},
+ {"have_isam", (char*) &have_isam, SHOW_HAVE},
+ {"have_raid", (char*) &have_raid, SHOW_HAVE},
+ {"have_symlink", (char*) &have_symlink, SHOW_HAVE},
+ {"have_openssl", (char*) &have_openssl, SHOW_HAVE},
+ {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE},
+ {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
+#ifdef HAVE_INNOBASE_DB
+ {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
+ {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG },
+ {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
+ {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
+ {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
+ {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
+ {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
+ {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_MY_BOOL},
+ {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
+ {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
+ {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
+ {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
+ {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL},
+ {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
+ {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONG},
+ {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG},
+ {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
+ {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
+#endif
+ {sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},
+ {sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS},
+ {sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS},
+ {"language", language, SHOW_CHAR},
+ {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
+ {sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
+#ifdef HAVE_MLOCKALL
+ {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
+#endif
+ {"log", (char*) &opt_log, SHOW_BOOL},
+ {"log_update", (char*) &opt_update_log, SHOW_BOOL},
+ {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
+ {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_BOOL},
+ {"log_slow_queries", (char*) &opt_slow_log, SHOW_BOOL},
+ {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS},
+ {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS},
+ {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS},
+ {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_MY_BOOL},
+ {sys_max_allowed_packet.name,(char*) &sys_max_allowed_packet, SHOW_SYS},
+ {sys_max_binlog_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS},
+ {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS},
+ {sys_max_connections.name, (char*) &sys_max_connections, SHOW_SYS},
+ {sys_max_connect_errors.name, (char*) &sys_max_connect_errors, SHOW_SYS},
+ {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS},
+ {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS},
+ {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS},
+ {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS},
+ {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
+ {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS},
+ {sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
+ {sys_myisam_max_extra_sort_file_size.name,
+ (char*) &sys_myisam_max_extra_sort_file_size,
+ SHOW_SYS},
+ {sys_myisam_max_sort_file_size.name,
+ (char*) &sys_myisam_max_sort_file_size,
+ SHOW_SYS},
+ {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
+ {sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
+#ifdef __NT__
+ {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_BOOL},
+#endif
+ {sys_net_buffer_length.name,(char*) &sys_net_buffer_length, SHOW_SYS},
+ {sys_net_read_timeout.name, (char*) &sys_net_read_timeout, SHOW_SYS},
+ {"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
+ {sys_net_write_timeout.name,(char*) &sys_net_write_timeout, SHOW_SYS},
+ {"open_files_limit", (char*) &open_files_limit, SHOW_LONG},
+ {"pid_file", (char*) pidfile_name, SHOW_CHAR},
+ {"port", (char*) &mysql_port, SHOW_INT},
+ {"protocol_version", (char*) &protocol_version, SHOW_INT},
+ {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
+ {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS},
+ {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS},
+#ifdef HAVE_QUERTY_CACHE
+ {sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS},
+ {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS},
+ {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS},
+#endif /* HAVE_QUERY_CACHE */
+ {sys_safe_show_db.name, (char*) &sys_safe_show_db, SHOW_SYS},
+ {sys_server_id.name, (char*) &sys_server_id, SHOW_SYS},
+ {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS},
+ {"skip_external_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
+ {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
+ {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
+ {sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS},
+ {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
+ {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS},
+ {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG},
+ {"table_cache", (char*) &table_cache_size, SHOW_LONG},
+ {sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
+ {sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
+#ifdef HAVE_THR_SETCONCURRENCY
+ {"thread_concurrency", (char*) &concurrency, SHOW_LONG},
+#endif
+ {"thread_stack", (char*) &thread_stack, SHOW_LONG},
+ {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
+#ifdef HAVE_TZNAME
+ {"timezone", time_zone, SHOW_CHAR},
+#endif
+ {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS},
+ {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR},
+ {"version", server_version, SHOW_CHAR},
+ {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS},
+ {NullS, NullS, SHOW_LONG}
+};
+
+/*
+ Functions to check and update variables
+*/
+
+/*
+ The following 3 functions need to be changed in 4.1 when we allow
+ one to change character sets
+*/
+
+static bool sys_check_charset(THD *thd, set_var *var)
+{
+ return 0;
+}
+
+
+static bool sys_update_charset(THD *thd, set_var *var)
+{
+ return 0;
+}
+
+
+static void sys_set_default_charset(THD *thd, enum_var_type type)
+{
+}
+
+
+/*
+ If one sets the LOW_PRIORIY UPDATES flag, we also must change the
+ used lock type
+*/
+
+static void fix_low_priority_updates(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->update_lock_default= (thd->variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
+}
+
+
+/*
+ Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR
+*/
+
+static void fix_max_join_size(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ {
+ if (thd->variables.max_join_size == (ulong) HA_POS_ERROR)
+ thd->options|= OPTION_BIG_SELECTS;
+ else
+ thd->options&= ~OPTION_BIG_SELECTS;
+ }
+}
+
+
+/*
+ If one doesn't use the SESSION modifier, the isolation level
+ is only active for the next command
+*/
+
+static void fix_tx_isolation(THD *thd, enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->session_tx_isolation= ((enum_tx_isolation)
+ thd->variables.tx_isolation);
+}
+
+
+/*
+ If we are changing the thread variable, we have to copy it to NET too
+*/
+
+static void fix_net_read_timeout(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.read_timeout=thd->variables.net_read_timeout;
+}
+
+
+static void fix_net_write_timeout(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.write_timeout=thd->variables.net_write_timeout;
+}
+
+
+static void fix_query_cache_size(THD *thd, enum_var_type type)
+{
+#ifdef HAVE_QUERY_CACHE
+ query_cache.resize(query_cache_size);
+#endif
+}
+
+
+static void fix_key_buffer_size(THD *thd, enum_var_type type)
+{
+ ha_resize_key_cache();
+}
+
+
+bool sys_var_long_ptr::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+ if (option_limits)
+ *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ else
+ *value= (ulong) tmp;
+ return 0;
+}
+
+
+void sys_var_long_ptr::set_default(THD *thd, enum_var_type type)
+{
+ *value= (ulong) option_limits->def_value;
+}
+
+
+bool sys_var_bool_ptr::update(THD *thd, set_var *var)
+{
+ *value= (my_bool) var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_bool_ptr::set_default(THD *thd, enum_var_type type)
+{
+ *value= (my_bool) option_limits->def_value;
+}
+
+
+bool sys_var_thd_ulong::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+
+ /* Don't use bigger value than given with --maximum-variable-name=.. */
+ if ((ulong) tmp > max_system_variables.*offset)
+ tmp= max_system_variables.*offset;
+
+ if (option_limits)
+ tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ if (var->type == OPT_GLOBAL)
+ {
+ /* Lock is needed to make things safe on 32 bit systems */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ global_system_variables.*offset=tmp;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ }
+ else
+ thd->variables.*offset= (ulong) tmp;
+ return 0;
+}
+
+
+void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ {
+ /* We will not come here if option_limits is not set */
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ }
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= var->value->val_int();
+ else
+ thd->variables.*offset= var->value->val_int();
+ return 0;
+}
+
+
+void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var_thd_bool::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
+ else
+ thd->variables.*offset= (my_bool) var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_thd_bool::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (my_bool) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names)
+{
+ char buff[80], *value;
+ String str(buff,sizeof(buff)), *res;
+
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ if (!(res=var->value->val_str(&str)) ||
+ ((long) (var->save_result.ulong_value=
+ (ulong) find_type(res->c_ptr(), enum_names, 3)-1))
+ < 0)
+ {
+ value=res->c_ptr();
+ goto err;
+ }
+ }
+ else
+ {
+ ulonglong tmp=var->value->val_int();
+ if (tmp >= enum_names->count)
+ {
+ llstr(tmp,buff);
+ value=buff; // Wrong value is here
+ goto err;
+ }
+ var->save_result.ulong_value= (ulong) tmp; // Save for update
+ }
+ return 0;
+
+err:
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
+ return 1;
+}
+
+/*
+ Return an Item for a variable. Used with @@[global.]variable_name
+
+ If type is not given, return local value if exists, else global
+
+ We have to use netprintf() instead of my_error() here as this is
+ called on the parsing stage.
+*/
+
+Item *sys_var::item(THD *thd, enum_var_type var_type)
+{
+ if (check_type(var_type))
+ {
+ if (var_type != OPT_DEFAULT)
+ {
+ net_printf(&thd->net,
+ var_type == OPT_GLOBAL ? ER_LOCAL_VARIABLE :
+ ER_GLOBAL_VARIABLE, name);
+ return 0;
+ }
+ /* As there was no local variable, return the global value */
+ var_type= OPT_GLOBAL;
+ }
+ switch (type()) {
+ case SHOW_LONG:
+ return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type));
+ case SHOW_LONGLONG:
+ return new Item_int(*(longlong*) value_ptr(thd, var_type));
+ case SHOW_MY_BOOL:
+ return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type),1);
+ case SHOW_CHAR:
+ {
+ char *str= (char*) value_ptr(thd, var_type);
+ return new Item_string(str,strlen(str));
+ }
+ default:
+ net_printf(&thd->net, ER_VAR_CANT_BE_READ, name);
+ }
+ return 0;
+}
+
+
+bool sys_var_thd_enum::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= var->save_result.ulong_value;
+ else
+ thd->variables.*offset= var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type)
+{
+ ulong tmp= ((type == OPT_GLOBAL) ?
+ global_system_variables.*offset :
+ thd->variables.*offset);
+ return (byte*) enum_names->type_names[tmp];
+}
+
+
+bool sys_var_thd_bit::update(THD *thd, set_var *var)
+{
+ bool res= (*update_func)(thd, var);
+ thd->lex.select_lex.options=thd->options;
+ return res;
+}
+
+
+byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type)
+{
+ /*
+ If reverse is 0 (default) return 1 if bit is set.
+ If reverse is 1, return 0 if bit is set
+ */
+ thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
+ !reverse : reverse);
+ return (byte*) &thd->sys_var_tmp.my_bool_value;
+}
+
+
+bool sys_var_thd_conv_charset::check(THD *thd, set_var *var)
+{
+ CONVERT *tmp;
+ char buff[80];
+ String str(buff,sizeof(buff)), *res;
+
+ if (!var->value) // Default value
+ {
+ var->save_result.convert= (var->type != OPT_GLOBAL ?
+ global_system_variables.convert_set
+ : (CONVERT*) 0);
+ return 0;
+ }
+ if (!(res=var->value->val_str(&str)))
+ res= &empty_string;
+
+ if (!(tmp=get_convert_set(res->c_ptr())))
+ {
+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
+ return 1;
+ }
+ var->save_result.convert=tmp; // Save for update
+ return 0;
+}
+
+
+bool sys_var_thd_conv_charset::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.convert_set= var->save_result.convert;
+ else
+ thd->lex.convert_set= thd->variables.convert_set=
+ var->save_result.convert;
+ return 0;
+}
+
+
+byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type)
+{
+ CONVERT *conv= ((type == OPT_GLOBAL) ?
+ global_system_variables.convert_set :
+ thd->variables.convert_set);
+ return conv ? (byte*) conv->name : (byte*) "";
+}
+
+
+
+bool sys_var_timestamp::update(THD *thd, set_var *var)
+{
+ thd->set_time((time_t) var->value->val_int());
+ return 0;
+}
+
+
+void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
+{
+ thd->user_time=0;
+}
+
+
+byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type)
+{
+ thd->sys_var_tmp.long_value= (long) thd->start_time;
+ return (byte*) &thd->sys_var_tmp.long_value;
+}
+
+
+bool sys_var_last_insert_id::update(THD *thd, set_var *var)
+{
+ thd->insert_id(var->value->val_int());
+ return 0;
+}
+
+
+byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type)
+{
+ thd->sys_var_tmp.long_value= (long) thd->insert_id();
+ return (byte*) &thd->last_insert_id;
+}
+
+
+bool sys_var_insert_id::update(THD *thd, set_var *var)
+{
+ thd->next_insert_id=var->value->val_int();
+ return 0;
+}
+
+
+byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type)
+{
+ return (byte*) &thd->current_insert_id;
+}
+
+
+bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
+{
+ bool result=0;
+ LOCK_ACTIVE_MI;
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ if (active_mi->rli.slave_running)
+ {
+ my_error(ER_SLAVE_MUST_STOP, MYF(0));
+ result=1;
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ UNLOCK_ACTIVE_MI;
+ return result;
+}
+
+
+bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
+{
+ LOCK_ACTIVE_MI;
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ /*
+ The following test should normally never be true as we test this
+ in the check function; To be safe against multiple
+ SQL_SLAVE_SKIP_COUNTER request, we do the check anyway
+ */
+ if (!active_mi->rli.slave_running)
+ {
+ pthread_mutex_lock(&active_mi->rli.data_lock);
+ active_mi->rli.slave_skip_counter= var->value->val_int();
+ pthread_mutex_unlock(&active_mi->rli.data_lock);
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ UNLOCK_ACTIVE_MI;
+ return 0;
+}
+
+
+/*
+ Functions to update thd->options bits
+*/
+
+static bool set_option_bit(THD *thd, set_var *var)
+{
+ if (var->save_result.ulong_value == 0)
+ thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
+ else
+ thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
+ return 0;
+}
+
+
+static bool set_option_autocommit(THD *thd, set_var *var)
+{
+ /* The test is negative as the flag we use is NOT autocommit */
+
+ ulong org_options=thd->options;
+
+ if (var->save_result.ulong_value != 0)
+ thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
+ else
+ thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
+
+ if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
+ {
+ if ((org_options & OPTION_NOT_AUTOCOMMIT))
+ {
+ /* We changed to auto_commit mode */
+ thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
+ if (ha_commit(thd))
+ return 1;
+ }
+ else
+ {
+ thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
+ }
+ }
+ return 0;
+}
+
+
+static bool set_log_update(THD *thd, set_var *var)
+{
+ if (opt_sql_bin_update)
+ ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG |
+ OPTION_UPDATE_LOG);
+ set_option_bit(thd, var);
+ return 0;
+}
+
+
+/****************************************************************************
+ Main handling of variables:
+ - Initialisation
+ - Searching during parsing
+ - Update loop
+****************************************************************************/
+
+/*
+ Find variable name in option my_getopt structure used for command line args
+
+ SYNOPSIS
+ find_option()
+ opt option structure array to search in
+ name variable name
+
+ RETURN VALUES
+ 0 Error
+ ptr pointer to option structure
+*/
+
+static struct my_option *find_option(struct my_option *opt, const char *name)
+{
+ uint length=strlen(name);
+ for (; opt->name; opt++)
+ {
+ if (!getopt_compare_strings(opt->name, name, length) &&
+ !opt->name[length])
+ {
+ /*
+ Only accept the option if one can set values through it.
+ If not, there is no default value or limits in the option.
+ */
+ return (opt->value) ? opt : 0;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Return variable name and length for hashing of variables
+*/
+
+static byte *get_sys_var_length(const sys_var *var, uint *length,
+ my_bool first)
+{
+ *length= var->name_length;
+ return (byte*) var->name;
+}
+
+
+/*
+ Initialises sys variables and put them in system_variable_hash
+*/
+
+
+void set_var_init()
+{
+ extern struct my_option my_long_options[]; // From mysqld
+
+ hash_init(&system_variable_hash,array_elements(sys_variables),0,0,
+ (hash_get_key) get_sys_var_length,0, HASH_CASE_INSENSITIVE);
+ sys_var **var, **end;
+ for (var= sys_variables, end= sys_variables+array_elements(sys_variables) ;
+ var < end;
+ var++)
+ {
+ (*var)->name_length= strlen((*var)->name);
+ (*var)->option_limits= find_option(my_long_options, (*var)->name);
+ hash_insert(&system_variable_hash, (byte*) *var);
+ }
+
+ /*
+ Special cases
+ Needed because MySQL can't find the limits for a variable it it has
+ a different name than the command line option.
+ As these variables are deprecated, this code will disappear soon...
+ */
+ sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
+}
+
+
+void set_var_free()
+{
+ hash_free(&system_variable_hash);
+}
+
+
+/*
+ Find a user set-table variable
+
+ SYNOPSIS
+ find_sys_var()
+ str Name of system variable to find
+ length Length of variable. zero means that we should use strlen()
+ on the variable
+
+ NOTE
+ We have to use net_printf() as this is called during the parsing stage
+
+ RETURN VALUES
+ pointer pointer to variable definitions
+ 0 Unknown variable (error message is given)
+*/
+
+sys_var *find_sys_var(const char *str, uint length=0)
+{
+ sys_var *var= (sys_var*) hash_search(&system_variable_hash, str,
+ length ? length :
+ strlen(str));
+ if (!var)
+ net_printf(&current_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str);
+ return var;
+}
+
+
+/*
+ Execute update of all variables
+
+ SYNOPSIS
+
+ sql_set
+ THD Thread id
+ set_var List of variables to update
+
+ DESCRIPTION
+ First run a check of all variables that all updates will go ok.
+ If yes, then execute all updates, returning an error if any one failed.
+
+ This should ensure that in all normal cases none all or variables are
+ updated
+
+ RETURN VALUE
+ 0 ok
+ 1 Something got wrong (normally no variables was updated)
+*/
+
+bool sql_set_variables(THD *thd, List<set_var_base> *var_list)
+{
+ bool error=0;
+ List_iterator<set_var_base> it(*var_list);
+
+ set_var_base *var;
+ while ((var=it++))
+ {
+ if (var->check(thd))
+ return 1;
+ }
+ it.rewind();
+ while ((var=it++))
+ {
+ if (var->update(thd))
+ error=1;
+ }
+ return error;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET mysql_internal_variable=const_expr
+*****************************************************************************/
+
+bool set_var::check(THD *thd)
+{
+ if (var->check_type(type))
+ {
+ my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE,
+ MYF(0),
+ var->name);
+ return 1;
+ }
+ if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
+ return 1;
+
+ /* value is a NULL pointer if we are using SET ... = DEFAULT */
+ if (!value)
+ {
+ if (var->check_default(type))
+ {
+ my_error(ER_NO_DEFAULT, MYF(0), var->name);
+ return 1;
+ }
+ return 0;
+ }
+
+ if (value->fix_fields(thd,0))
+ return 1;
+ if (var->check_update_type(value->result_type()))
+ {
+ my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
+ return 1;
+ }
+ return var->check(thd, this);
+}
+
+
+bool set_var::update(THD *thd)
+{
+ if (!value)
+ var->set_default(thd, type);
+ else if (var->update(thd, this))
+ return 1; // should never happen
+ if (var->after_update)
+ (*var->after_update)(thd, type);
+ return 0;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET @user_variable=const_expr
+*****************************************************************************/
+
+bool set_var_user::check(THD *thd)
+{
+ return user_var_item->fix_fields(thd,0);
+}
+
+
+bool set_var_user::update(THD *thd)
+{
+ if (user_var_item->update())
+ {
+ /* Give an error if it's not given already */
+ send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
+ return 1;
+ }
+ return 0;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET PASSWORD
+*****************************************************************************/
+
+bool set_var_password::check(THD *thd)
+{
+ if (!user->host.str)
+ user->host.str= (char*) thd->host_or_ip;
+ return check_change_password(thd, user->host.str, user->user.str);
+}
+
+bool set_var_password::update(THD *thd)
+{
+ return change_password(thd, user->host.str, user->user.str, password);
+}
+
+/****************************************************************************
+ Used templates
+****************************************************************************/
+
+#ifdef __GNUC__
+template class List<set_var_base>;
+template class List_iterator<set_var_base>;
+#endif
diff --git a/sql/set_var.h b/sql/set_var.h
new file mode 100644
index 00000000000..607e44d2ef3
--- /dev/null
+++ b/sql/set_var.h
@@ -0,0 +1,419 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Classes to support the SET command */
+
+#ifdef __GNUC__
+#pragma interface /* gcc class implementation */
+#endif
+
+/****************************************************************************
+ Variables that are changable runtime are declared using the
+ following classes
+****************************************************************************/
+
+class sys_var;
+class set_var;
+typedef struct system_variables SV;
+extern TYPELIB bool_typelib;
+
+enum enum_var_type
+{
+ OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
+};
+
+typedef bool (*sys_check_func)(THD *, set_var *);
+typedef bool (*sys_update_func)(THD *, set_var *);
+typedef void (*sys_after_update_func)(THD *,enum_var_type);
+typedef void (*sys_set_default_func)(THD *, enum_var_type);
+
+class sys_var
+{
+public:
+ struct my_option *option_limits; /* Updated by by set_var_init() */
+ uint name_length; /* Updated by by set_var_init() */
+ const char *name;
+ sys_after_update_func after_update;
+ sys_var(const char *name_arg) :name(name_arg),after_update(0)
+ {}
+ sys_var(const char *name_arg,sys_after_update_func func)
+ :name(name_arg),after_update(func)
+ {}
+ virtual ~sys_var() {}
+ virtual bool check(THD *thd, set_var *var) { return 0; }
+ bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names);
+ virtual bool update(THD *thd, set_var *var)=0;
+ virtual void set_default(THD *thd, enum_var_type type) {}
+ virtual SHOW_TYPE type() { return SHOW_UNDEF; }
+ virtual byte *value_ptr(THD *thd, enum_var_type type) { return 0; }
+ virtual bool check_type(enum_var_type type)
+ { return type != OPT_GLOBAL; } /* Error if not GLOBAL */
+ virtual bool check_update_type(Item_result type)
+ { return type != INT_RESULT; } /* Assume INT */
+ virtual bool check_default(enum_var_type type)
+ { return option_limits == 0; }
+ Item *item(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_long_ptr :public sys_var
+{
+public:
+ ulong *value;
+ sys_var_long_ptr(const char *name_arg, ulong *value_ptr)
+ :sys_var(name_arg),value(value_ptr) {}
+ sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
+ sys_after_update_func func)
+ :sys_var(name_arg,func), value(value_ptr) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+};
+
+
+class sys_var_bool_ptr :public sys_var
+{
+public:
+ my_bool *value;
+ sys_var_bool_ptr(const char *name_arg, my_bool *value_arg)
+ :sys_var(name_arg),value(value_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_str :public sys_var
+{
+public:
+ char *value; // Pointer to allocated string
+ sys_check_func check_func;
+ sys_update_func update_func;
+ sys_set_default_func set_default_func;
+ sys_var_str(const char *name_arg,
+ sys_check_func check_func_arg,
+ sys_update_func update_func_arg,
+ sys_set_default_func set_default_func_arg)
+ :sys_var(name_arg), check_func(check_func_arg),
+ update_func(update_func_arg),set_default_func(set_default_func_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_func ? (*check_func)(thd, var) : 0;
+ }
+ bool update(THD *thd, set_var *var)
+ {
+ return (*update_func)(thd, var);
+ }
+ void set_default(THD *thd, enum_var_type type)
+ {
+ return (*set_default_func)(thd, type);
+ }
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+ bool check_update_type(Item_result type)
+ {
+ return type != STRING_RESULT; /* Only accept strings */
+ }
+ bool check_default(enum_var_type type) { return 0; }
+};
+
+
+class sys_var_thd :public sys_var
+{
+public:
+ sys_var_thd(const char *name_arg)
+ :sys_var(name_arg)
+ {}
+ sys_var_thd(const char *name_arg, sys_after_update_func func)
+ :sys_var(name_arg,func)
+ {}
+ bool check_type(enum_var_type type) { return 0; }
+ bool check_default(enum_var_type type)
+ {
+ return type == OPT_GLOBAL && !option_limits;
+ }
+};
+
+
+class sys_var_thd_ulong :public sys_var_thd
+{
+public:
+ ulong SV::*offset;
+ sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_thd_ulonglong :public sys_var_thd
+{
+public:
+ ulonglong SV::*offset;
+ sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_thd_bool :public sys_var_thd
+{
+public:
+ my_bool SV::*offset;
+ sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_thd_enum :public sys_var_thd
+{
+ ulong SV::*offset;
+ TYPELIB *enum_names;
+public:
+ sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ TYPELIB *typelib)
+ :sys_var_thd(name_arg), offset(offset_arg), enum_names(typelib)
+ {}
+ sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ TYPELIB *typelib,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg), enum_names(typelib)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, enum_names);
+ }
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_thd_bit :public sys_var_thd
+{
+ sys_update_func update_func;
+public:
+ ulong bit_flag;
+ bool reverse;
+ sys_var_thd_bit(const char *name_arg, sys_update_func func, ulong bit,
+ bool reverse_arg=0)
+ :sys_var_thd(name_arg), update_func(func), bit_flag(bit),
+ reverse(reverse_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool update(THD *thd, set_var *var);
+ bool check_update_type(Item_result type) { return 0; }
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+/* some variables that require special handling */
+
+class sys_var_timestamp :public sys_var
+{
+public:
+ sys_var_timestamp(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ bool check_default(enum_var_type type) { return 0; }
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_last_insert_id :public sys_var
+{
+public:
+ sys_var_last_insert_id(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_insert_id :public sys_var
+{
+public:
+ sys_var_insert_id(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_slave_skip_counter :public sys_var
+{
+public:
+ sys_var_slave_skip_counter(const char *name_arg) :sys_var(name_arg) {}
+ bool check(THD *thd, set_var *var);
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type != OPT_GLOBAL; }
+ /*
+ We can't retrieve the value of this, so we don't have to define
+ type() or value_ptr()
+ */
+};
+
+
+class sys_var_thd_conv_charset :public sys_var_thd
+{
+public:
+ sys_var_thd_conv_charset(const char *name_arg)
+ :sys_var_thd(name_arg)
+ {}
+ bool check(THD *thd, set_var *var);
+ bool update(THD *thd, set_var *var);
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_update_type(Item_result type)
+ {
+ return type != STRING_RESULT; /* Only accept strings */
+ }
+ bool check_default(enum_var_type type) { return 0; }
+};
+
+
+/****************************************************************************
+ Classes for parsing of the SET command
+****************************************************************************/
+
+class set_var_base :public Sql_alloc
+{
+public:
+ set_var_base() {}
+ virtual ~set_var_base() {}
+ virtual bool check(THD *thd)=0; /* To check privileges etc. */
+ virtual bool update(THD *thd)=0; /* To set the value */
+};
+
+
+/* MySQL internal variables, like query_cache_size */
+
+class set_var :public set_var_base
+{
+public:
+ sys_var *var;
+ Item *value;
+ enum_var_type type;
+ union
+ {
+ CONVERT *convert;
+ ulong ulong_value;
+ } save_result;
+
+ set_var(enum_var_type type_arg, sys_var *var_arg, Item *value_arg)
+ :var(var_arg), type(type_arg)
+ {
+ /*
+ If the set value is a field, change it to a string to allow things like
+ SET table_type=MYISAM;
+ */
+ if (value_arg && value_arg->type() == Item::FIELD_ITEM)
+ {
+ Item_field *item= (Item_field*) value_arg;
+ if (!(value=new Item_string(item->field_name, strlen(item->field_name))))
+ value=value_arg; /* Give error message later */
+ }
+ else
+ value=value_arg;
+ }
+ bool check(THD *thd);
+ bool update(THD *thd);
+};
+
+
+/* User variables like @my_own_variable */
+
+class set_var_user: public set_var_base
+{
+ Item_func_set_user_var *user_var_item;
+public:
+ set_var_user(Item_func_set_user_var *item)
+ :user_var_item(item)
+ {}
+ bool check(THD *thd);
+ bool update(THD *thd);
+};
+
+/* For SET PASSWORD */
+
+class set_var_password: public set_var_base
+{
+ LEX_USER *user;
+ char *password;
+public:
+ set_var_password(LEX_USER *user_arg,char *password_arg)
+ :user(user_arg), password(password_arg)
+ {}
+ bool check(THD *thd);
+ bool update(THD *thd);
+};
+
+
+/*
+ Prototypes for helper functions
+*/
+
+void set_var_init();
+void set_var_free();
+sys_var *find_sys_var(const char *str, uint length=0);
+bool sql_set_variables(THD *thd, List<set_var_base> *var_list);
+
+extern sys_var_str sys_charset;
diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am
index b72f7493e20..c70ac9ccf57 100644
--- a/sql/share/Makefile.am
+++ b/sql/share/Makefile.am
@@ -28,5 +28,11 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/charsets/Index $(DESTDIR)$(pkgdatadir)/charsets/Index
$(INSTALL_DATA) $(srcdir)/charsets/*.conf $(DESTDIR)$(pkgdatadir)/charsets
+fix_errors:
+ for lang in @AVAILABLE_LANGUAGES@; \
+ do \
+ ../../extra/comp_err $(srcdir)/$$lang/errmsg.txt $(srcdir)/$$lang/errmsg.sys; \
+ done
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index
index b91e27e7c02..5cf30682cc0 100644
--- a/sql/share/charsets/Index
+++ b/sql/share/charsets/Index
@@ -1,6 +1,7 @@
# sql/share/charsets/Index
#
-# This file lists all of the available character sets.
+# This file lists all of the available character sets. Please keep this
+# file sorted by character set number.
big5 1
@@ -34,3 +35,4 @@ croat 27
gbk 28
cp1257 29
latin5 30
+latin1_de 31
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index 093954c202b..18b4c3ad2a8 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -14,198 +14,198 @@
"isamchk",
"NE",
"ANO",
-"Nemohu vytvo-Bøit soubor '%-.64s' (chybový kód: %d)",-A
-"Nemohu vytvo-Bøit tabulku '%-.64s' (chybový kód: %d)",-A
-"Nemohu vytvo-Bøit databázi '%-.64s', chyba %d",-A
-"Nemohu vytvo-Bøit databázi '%-.64s', databáze ji¾ existuje",-A
-"Nemohu zru-B¹it databázi '%-.64s', databáze neexistuje",-A
-"Chyba p-Bøi ru¹ení databáze (nemohu vymazat '%-.64s', chyba %d)",-A
-"Chyba p-Bøi ru¹ení databáze (nemohu vymazat adresáø '%-.64s', chyba %d)",-A
-"Chyba p-Bøi výmazu '%-.64s' (chybový kód: %d)",-A
-"Nemohu -Bèíst záznam v systémové tabulce",-A
-"Nemohu z-Bískat stav '%-.64s' (chybový kód: %d)",-A
-"Chyba p-Bøi zji¹»ování pracovní adresáø (chybový kód: %d)",-A
-"Nemohu uzamknout soubor (chybov-Bý kód: %d)",-A
-"Nemohu otev-Bøít soubor '%-.64s' (chybový kód: %d)",-A
-"Nemohu naj-Bít soubor '%-.64s' (chybový kód: %d)",-A
-"Nemohu -Bèíst adresáø '%-.64s' (chybový kód: %d)",-A
-"Nemohu zm-Bìnit adresáø na '%-.64s' (chybový kód: %d)",-A
-"Z-Báznam byl zmìnìn od posledního ètení v tabulce '%-.64s'",-A
-"Disk je pln-Bý (%s), èekám na uvolnìní nìjakého místa ...",-A
-"Nemohu zapsat, zdvojen-Bý klíè v tabulce '%-.64s'",-A
-"Chyba p-Bøi zavírání '%-.64s' (chybový kód: %d)",-A
-"Chyba p-Bøi ètení souboru '%-.64s' (chybový kód: %d)",-A
-"Chyba p-Bøi pøejmenování '%-.64s' na '%-.64s' (chybový kód: %d)",-A
-"Chyba p-Bøi zápisu do souboru '%-.64s' (chybový kód: %d)",-A
-"'%-.64s' je zam-Bèen proti zmìnám",-A
-"T-Bøídìní pøeru¹eno",-A
+"Nemohu vytvo-Bøit soubor '%-.64s' (chybový kód: %d)",
+"Nemohu vytvo-Bøit tabulku '%-.64s' (chybový kód: %d)",
+"Nemohu vytvo-Bøit databázi '%-.64s', chyba %d",
+"Nemohu vytvo-Bøit databázi '%-.64s', databáze ji¾ existuje",
+"Nemohu zru-B¹it databázi '%-.64s', databáze neexistuje",
+"Chyba p-Bøi ru¹ení databáze (nemohu vymazat '%-.64s', chyba %d)",
+"Chyba p-Bøi ru¹ení databáze (nemohu vymazat adresáø '%-.64s', chyba %d)",
+"Chyba p-Bøi výmazu '%-.64s' (chybový kód: %d)",
+"Nemohu -Bèíst záznam v systémové tabulce",
+"Nemohu z-Bískat stav '%-.64s' (chybový kód: %d)",
+"Chyba p-Bøi zji¹»ování pracovní adresáø (chybový kód: %d)",
+"Nemohu uzamknout soubor (chybov-Bý kód: %d)",
+"Nemohu otev-Bøít soubor '%-.64s' (chybový kód: %d)",
+"Nemohu naj-Bít soubor '%-.64s' (chybový kód: %d)",
+"Nemohu -Bèíst adresáø '%-.64s' (chybový kód: %d)",
+"Nemohu zm-Bìnit adresáø na '%-.64s' (chybový kód: %d)",
+"Z-Báznam byl zmìnìn od posledního ètení v tabulce '%-.64s'",
+"Disk je pln-Bý (%s), èekám na uvolnìní nìjakého místa ...",
+"Nemohu zapsat, zdvojen-Bý klíè v tabulce '%-.64s'",
+"Chyba p-Bøi zavírání '%-.64s' (chybový kód: %d)",
+"Chyba p-Bøi ètení souboru '%-.64s' (chybový kód: %d)",
+"Chyba p-Bøi pøejmenování '%-.64s' na '%-.64s' (chybový kód: %d)",
+"Chyba p-Bøi zápisu do souboru '%-.64s' (chybový kód: %d)",
+"'%-.64s' je zam-Bèen proti zmìnám",
+"T-Bøídìní pøeru¹eno",
"Pohled '%-.64s' pro '%-.64s' neexistuje",
-"Obsluha tabulky vr-Bátila chybu %d",-A
-"Obsluha tabulky '%-.64s' nem-Bá tento parametr",-A
-"Nemohu naj-Bít záznam v '%-.64s'",-A
-"Nespr-Bávná informace v souboru '%-.64s'",-A
-"Nespr-Bávný klíè pro tabulku '%-.64s'. Pokuste se ho opravit",-A
-"Star-Bý klíèový soubor pro '%-.64s'. Opravte ho.",-A
-"'%-.64s' je jen pro -Bètení",-A
-"M-Bálo pamìti. Pøestartujte daemona a zkuste znovu (je potøeba %d bytù)",-A
-"M-Bálo pamìti pro tøídìní. Zvy¹te velikost tøídícího bufferu",-A
-"Neo-Bèekávaný konec souboru pøi ètení '%-.64s' (chybový kód: %d)",-A
-"P-Bøíli¹ mnoho spojení",-A
-"M-Bálo prostoru/pamìti pro thread",-A
-"Nemohu zjistit jm-Béno stroje pro Va¹i adresu",-A
-"Chyba p-Bøi ustavování spojení",-A
-"P-Bøístup pro u¾ivatele '%-.32s@%-.64s' k databázi '%-.64s' není povolen",-A
-"P-Bøístup pro u¾ivatele '%-.32s@%-.64s' (s heslem %s)",-A
-"Nebyla vybr-Bána ¾ádná databáze",-A
-"Nezn-Bámý pøíkaz",-A
-"Sloupec '%-.64s' nem-Bù¾e být null",-A
-"Nezn-Bámá databáze '%-.64s'",-A
-"Tabulka '%-.64s' ji-B¾ existuje",-A
-"Nezn-Bámá tabulka '%-.64s'",-A
-"Sloupec '%-.64s' v %s nen-Bí zcela jasný",-A
-"Prob-Bíhá ukonèování práce serveru",-A
-"Nezn-Bámý sloupec '%-.64s' v %s",-A
-"Pou-B¾ité '%-.64s' nebylo v group by",-A
-"Nemohu pou-B¾ít group na '%-.64s'",-A
-"P-Bøíkaz obsahuje zároveò funkci sum a sloupce",-A
-"Po-Bèet sloupcù neodpovídá zadané hodnotì",-A
-"Jm-Béno identifikátoru '%-.64s' je pøíli¹ dlouhé",-A
-"Zdvojen-Bé jméno sloupce '%-.64s'",-A
-"Zdvojen-Bé jméno klíèe '%-.64s'",-A
-"Zvojen-Bý klíè '%-.64s' (èíslo klíèe %d)",-A
-"Chybn-Bá specifikace sloupce '%-.64s'",-A
-"%s bl-Bízko '%-.64s' na øádku %d",-A
-"V-Býsledek dotazu je prázdný",-A
-"Nejednozna-Bèná tabulka/alias: '%-.64s'",-A
-"Chybn-Bá defaultní hodnota pro '%-.64s'",-A
-"Definov-Báno více primárních klíèù",-A
-"Zad-Báno pøíli¹ mnoho klíèù, je povoleno nejvíce %d klíèù",-A
-"Zad-Báno pøíli¹ mnoho èást klíèù, je povoleno nejvíce %d èástí",-A
-"Zadan-Bý klíè byl pøíli¹ dlouhý, nejvìt¹í délka klíèe je %d",-A
-"Kl-Bíèový sloupec '%-.64s' v tabulce neexistuje",-A
-"Blob sloupec '%-.64s' nem-Bù¾e být pou¾it jako klíè",-A
-"P-Bøíli¹ velká délka sloupce '%-.64s' (nejvíce %d). Pou¾ijte BLOB",-A
-"M-Bù¾ete mít pouze jedno AUTO pole a to musí být definováno jako klíè",-A
-"%s: p-Bøipraven na spojení\n",-A
-"%s: norm-Bální ukonèení\n",-A
-"%s: p-Bøijat signal %d, konèím\n",-A
-"%s: ukon-Bèení práce hotovo\n",-A
-"%s: n-Básilné uzavøení threadu %ld u¾ivatele '%-.64s'\n",-A
-"Nemohu vytvo-Bøit IP socket",-A
-"Tabulka '%-.64s' nem-Bá index odpovídající CREATE INDEX. Vytvoøte tabulku znovu",-A
-"Argument separ-Bátoru polo¾ek nebyl oèekáván. Pøeètìte si manuál",-A
-"Nen-Bí mo¾né pou¾ít pevný rowlength s BLOBem. Pou¾ijte 'fields terminated by'.",-A
-"Soubor '%-.64s' mus-Bí být v adresáøi databáze nebo èitelný pro v¹echny",-A
-"Soubor '%-.64s' ji-B¾ existuje",-A
-"Z-Báznamù: %ld Vymazáno: %ld Pøeskoèeno: %ld Varování: %ld",-A
-"Z-Báznamù: %ld Zdvojených: %ld",-A
-"Chybn-Bá podèást klíèe -- není to øetìzec nebo je del¹í ne¾ délka èásti klíèe",-A
-"Nen-Bí mo¾né vymazat v¹echny polo¾ky s ALTER TABLE. Pou¾ijte DROP TABLE",-A
-"Nemohu zru-B¹it '%-.64s' (provést DROP). Zkontrolujte, zda neexistují záznamy/klíèe",-A
-"Z-Báznamù: %ld Zdvojených: %ld Varování: %ld",-A
-"INSERT TABLE '%-.64s' nen-Bí dovoleno v seznamu tabulek FROM",-A
-"Nezn-Bámá identifikace threadu: %lu",-A
-"Nejste vlastn-Bíkem threadu %lu",-A
-"Nejsou pou-B¾ity ¾ádné tabulky",-A
-"P-Bøíli¹ mnoho øetìzcù pro sloupec %s a SET",-A
-"Nemohu vytvo-Bøit jednoznaèné jméno logovacího souboru %s.(1-999)\n",-A
-"Tabulka '%-.64s' byla zam-Bèena s READ a nemù¾e být zmìnìna",-A
-"Tabulka '%-.64s' nebyla zam-Bèena s LOCK TABLES",-A
-"Blob polo-B¾ka '%-.64s' nemù¾e mít defaultní hodnotu",-A
-"Nep-Bøípustné jméno databáze '%-.64s'",-A
-"Nep-Bøípustné jméno tabulky '%-.64s'",-A
-"Zadan-Bý SELECT by procházel pøíli¹ mnoho záznamù a trval velmi dlouho. Zkontrolujte tvar WHERE a je-li SELECT v poøádku, pou¾ijte SET OPTION SQL_BIG_SELECTS=1",-A
-"Nezn-Bámá chyba",-A
-"Nezn-Bámá procedura %s",-A
-"Chybn-Bý poèet parametrù procedury %s",-A
-"Chybn-Bé parametry procedury %s",-A
-"Nezn-Bámá tabulka '%-.64s' v %s",-A
-"Polo-B¾ka '%-.64s' je zadána dvakrát",-A
-"Nespr-Bávné pou¾ití funkce group",-A
-"Tabulka '%-.64s' pou-B¾ívá roz¹íøení, které v této verzi MySQL není",-A
-"Tabulka mus-Bí mít alespoò jeden sloupec",-A
-"Tabulka '%-.64s' je pln-Bá",-A
-"Nezn-Bámá znaková sada: '%-.64s'",-A
-"P-Bøíli¹ mnoho tabulek, MySQL jich mù¾e mít v joinu jen %d",-A
-"P-Bøíli¹ mnoho polo¾ek",-A
-"-BØádek je pøíli¹ velký. Maximální velikost øádku, nepoèítaje polo¾ky blob, je %d. Musíte zmìnit nìkteré polo¾ky na blob",-A
-"P-Bøeteèení zásobníku threadu: pou¾ito %ld z %ld. Pou¾ijte 'mysqld -O thread_stack=#' k zadání vìt¹ího zásobníku",-A
-"V OUTER JOIN byl nalezen k-Bøí¾ový odkaz. Provìøte ON podmínky",-A
-"Sloupec '%-.32s' je pou-B¾it s UNIQUE nebo INDEX, ale není definován jako NOT NULL",-A
-"Nemohu na-Bèíst funkci '%-.64s'",-A
+"Obsluha tabulky vr-Bátila chybu %d",
+"Obsluha tabulky '%-.64s' nem-Bá tento parametr",
+"Nemohu naj-Bít záznam v '%-.64s'",
+"Nespr-Bávná informace v souboru '%-.64s'",
+"Nespr-Bávný klíè pro tabulku '%-.64s'. Pokuste se ho opravit",
+"Star-Bý klíèový soubor pro '%-.64s'. Opravte ho.",
+"'%-.64s' je jen pro -Bètení",
+"M-Bálo pamìti. Pøestartujte daemona a zkuste znovu (je potøeba %d bytù)",
+"M-Bálo pamìti pro tøídìní. Zvy¹te velikost tøídícího bufferu",
+"Neo-Bèekávaný konec souboru pøi ètení '%-.64s' (chybový kód: %d)",
+"P-Bøíli¹ mnoho spojení",
+"M-Bálo prostoru/pamìti pro thread",
+"Nemohu zjistit jm-Béno stroje pro Va¹i adresu",
+"Chyba p-Bøi ustavování spojení",
+"P-Bøístup pro u¾ivatele '%-.32s@%-.64s' k databázi '%-.64s' není povolen",
+"P-Bøístup pro u¾ivatele '%-.32s@%-.64s' (s heslem %s)",
+"Nebyla vybr-Bána ¾ádná databáze",
+"Nezn-Bámý pøíkaz",
+"Sloupec '%-.64s' nem-Bù¾e být null",
+"Nezn-Bámá databáze '%-.64s'",
+"Tabulka '%-.64s' ji-B¾ existuje",
+"Nezn-Bámá tabulka '%-.64s'",
+"Sloupec '%-.64s' v %s nen-Bí zcela jasný",
+"Prob-Bíhá ukonèování práce serveru",
+"Nezn-Bámý sloupec '%-.64s' v %s",
+"Pou-B¾ité '%-.64s' nebylo v group by",
+"Nemohu pou-B¾ít group na '%-.64s'",
+"P-Bøíkaz obsahuje zároveò funkci sum a sloupce",
+"Po-Bèet sloupcù neodpovídá zadané hodnotì",
+"Jm-Béno identifikátoru '%-.64s' je pøíli¹ dlouhé",
+"Zdvojen-Bé jméno sloupce '%-.64s'",
+"Zdvojen-Bé jméno klíèe '%-.64s'",
+"Zvojen-Bý klíè '%-.64s' (èíslo klíèe %d)",
+"Chybn-Bá specifikace sloupce '%-.64s'",
+"%s bl-Bízko '%-.64s' na øádku %d",
+"V-Býsledek dotazu je prázdný",
+"Nejednozna-Bèná tabulka/alias: '%-.64s'",
+"Chybn-Bá defaultní hodnota pro '%-.64s'",
+"Definov-Báno více primárních klíèù",
+"Zad-Báno pøíli¹ mnoho klíèù, je povoleno nejvíce %d klíèù",
+"Zad-Báno pøíli¹ mnoho èást klíèù, je povoleno nejvíce %d èástí",
+"Zadan-Bý klíè byl pøíli¹ dlouhý, nejvìt¹í délka klíèe je %d",
+"Kl-Bíèový sloupec '%-.64s' v tabulce neexistuje",
+"Blob sloupec '%-.64s' nem-Bù¾e být pou¾it jako klíè",
+"P-Bøíli¹ velká délka sloupce '%-.64s' (nejvíce %d). Pou¾ijte BLOB",
+"M-Bù¾ete mít pouze jedno AUTO pole a to musí být definováno jako klíè",
+"%s: p-Bøipraven na spojení\n",
+"%s: norm-Bální ukonèení\n",
+"%s: p-Bøijat signal %d, konèím\n",
+"%s: ukon-Bèení práce hotovo\n",
+"%s: n-Básilné uzavøení threadu %ld u¾ivatele '%-.64s'\n",
+"Nemohu vytvo-Bøit IP socket",
+"Tabulka '%-.64s' nem-Bá index odpovídající CREATE INDEX. Vytvoøte tabulku znovu",
+"Argument separ-Bátoru polo¾ek nebyl oèekáván. Pøeètìte si manuál",
+"Nen-Bí mo¾né pou¾ít pevný rowlength s BLOBem. Pou¾ijte 'fields terminated by'.",
+"Soubor '%-.64s' mus-Bí být v adresáøi databáze nebo èitelný pro v¹echny",
+"Soubor '%-.64s' ji-B¾ existuje",
+"Z-Báznamù: %ld Vymazáno: %ld Pøeskoèeno: %ld Varování: %ld",
+"Z-Báznamù: %ld Zdvojených: %ld",
+"Chybn-Bá podèást klíèe -- není to øetìzec nebo je del¹í ne¾ délka èásti klíèe",
+"Nen-Bí mo¾né vymazat v¹echny polo¾ky s ALTER TABLE. Pou¾ijte DROP TABLE",
+"Nemohu zru-B¹it '%-.64s' (provést DROP). Zkontrolujte, zda neexistují záznamy/klíèe",
+"Z-Báznamù: %ld Zdvojených: %ld Varování: %ld",
+"INSERT TABLE '%-.64s' nen-Bí dovoleno v seznamu tabulek FROM",
+"Nezn-Bámá identifikace threadu: %lu",
+"Nejste vlastn-Bíkem threadu %lu",
+"Nejsou pou-B¾ity ¾ádné tabulky",
+"P-Bøíli¹ mnoho øetìzcù pro sloupec %s a SET",
+"Nemohu vytvo-Bøit jednoznaèné jméno logovacího souboru %s.(1-999)\n",
+"Tabulka '%-.64s' byla zam-Bèena s READ a nemù¾e být zmìnìna",
+"Tabulka '%-.64s' nebyla zam-Bèena s LOCK TABLES",
+"Blob polo-B¾ka '%-.64s' nemù¾e mít defaultní hodnotu",
+"Nep-Bøípustné jméno databáze '%-.64s'",
+"Nep-Bøípustné jméno tabulky '%-.64s'",
+"Zadan-Bý SELECT by procházel pøíli¹ mnoho záznamù a trval velmi dlouho. Zkontrolujte tvar WHERE a je-li SELECT v poøádku, pou¾ijte SET OPTION SQL_BIG_SELECTS=1",
+"Nezn-Bámá chyba",
+"Nezn-Bámá procedura %s",
+"Chybn-Bý poèet parametrù procedury %s",
+"Chybn-Bé parametry procedury %s",
+"Nezn-Bámá tabulka '%-.64s' v %s",
+"Polo-B¾ka '%-.64s' je zadána dvakrát",
+"Nespr-Bávné pou¾ití funkce group",
+"Tabulka '%-.64s' pou-B¾ívá roz¹íøení, které v této verzi MySQL není",
+"Tabulka mus-Bí mít alespoò jeden sloupec",
+"Tabulka '%-.64s' je pln-Bá",
+"Nezn-Bámá znaková sada: '%-.64s'",
+"P-Bøíli¹ mnoho tabulek, MySQL jich mù¾e mít v joinu jen %d",
+"P-Bøíli¹ mnoho polo¾ek",
+"-BØádek je pøíli¹ velký. Maximální velikost øádku, nepoèítaje polo¾ky blob, je %d. Musíte zmìnit nìkteré polo¾ky na blob",
+"P-Bøeteèení zásobníku threadu: pou¾ito %ld z %ld. Pou¾ijte 'mysqld -O thread_stack=#' k zadání vìt¹ího zásobníku",
+"V OUTER JOIN byl nalezen k-Bøí¾ový odkaz. Provìøte ON podmínky",
+"Sloupec '%-.32s' je pou-B¾it s UNIQUE nebo INDEX, ale není definován jako NOT NULL",
+"Nemohu na-Bèíst funkci '%-.64s'",
"Nemohu inicializovat funkci '%-.64s'; %-.80s",
-"Pro sd-Bílenou knihovnu nejsou povoleny cesty",-A
-"Funkce '%-.64s' ji-B¾ existuje",-A
-"Nemohu otev-Bøít sdílenou knihovnu '%-.64s' (errno: %d %s)",-A
-"Nemohu naj-Bít funkci '%-.64s' v knihovnì'",-A
-"Funkce '%-.64s' nen-Bí definována",-A
-"Stroj '%-.64s' je zablokov-Bán kvùli mnoha chybám pøi pøipojování. Odblokujete pou¾itím 'mysqladmin flush-hosts'",-A
-"Stroj '%-.64s' nem-Bá povoleno se k tomuto MySQL serveru pøipojit",-A
-"Pou-B¾íváte MySQL jako anonymní u¾ivatel a anonymní u¾ivatelé nemají povoleno mìnit hesla",-A
-"Na zm-Bìnu hesel ostatním musíte mít právo provést update tabulek v databázi mysql",-A
-"V tabulce user nen-Bí ¾ádný odpovídající øádek",-A
-"Nalezen-Bých øádkù: %ld Zmìnìno: %ld Varování: %ld",-A
-"Nemohu vytvo-Bøit nový thread (errno %d). Pokud je je¹tì nìjaká volná pamì», podívejte se do manuálu na èást o chybách specifických pro jednotlivé operaèní systémy",-A
-"Po-Bèet sloupcù neodpovídá poètu hodnot na øádku %ld",-A
-"Nemohu znovuotev-Bøít tabulku: '%-.64s',-A
-"Neplatn-Bé u¾ití hodnoty NULL",-A
-"Regul-Bární výraz vrátil chybu '%-.64s'",-A
-"Pokud nen-Bí ¾ádná GROUP BY klauzule, není dovoleno souèasné pou¾ití GROUP polo¾ek (MIN(),MAX(),COUNT()...) s ne GROUP polo¾kami",-A
-"Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s'",-A
-"%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro tabulku '%-.64s'",-A
-"%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro sloupec '%-.64s' v tabulce '%-.64s'",-A
-"Neplatn-Bý pøíkaz GRANT/REVOKE. Prosím, pøeètìte si v manuálu, jaká privilegia je mo¾né pou¾ít.",-A
-"Argument p-Bøíkazu GRANT u¾ivatel nebo stroj je pøíli¹ dlouhý",-A
-"Tabulka '%-64s.%s' neexistuje",
-"Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s' pro tabulku '%-.64s'",-A
-"Pou-B¾itý pøíkaz není v této verzi MySQL povolen",-A
-"Va-B¹e syntaxe je nìjaká divná",-A
-"Zpo-B¾dìný insert threadu nebyl schopen získat po¾adovaný zámek pro tabulku %-.64s",-A
-"P-Bøíli¹ mnoho zpo¾dìných threadù",-A
-"Zru-B¹eno spojení %ld do databáze: '%-.64s' u¾ivatel: '%-.64s' (%s)",-A
-"Zji-B¹tìn pøíchozí packet del¹í ne¾ 'max_allowed_packet'",-A
-"Zji-B¹tìna chyba pøi ètení z roury spojení",-A
-"Zji-B¹tìna chyba fcntl()",-A
-"P-Bøíchozí packety v chybném poøadí",-A
-"Nemohu rozkomprimovat komunika-Bèní packet",-A
-"Zji-B¹tìna chyba pøi ètení komunikaèního packetu",-A
-"Zji-B¹tìn timeout pøi ètení komunikaèního packetu",-A
-"Zji-B¹tìna chyba pøi zápisu komunikaèního packetu",-A
-"Zji-B¹tìn timeout pøi zápisu komunikaèního packetu",-A
-"V-Býsledný øetìzec je del¹í ne¾ max_allowed_packet",-A
-"Typ pou-B¾ité tabulky nepodporuje BLOB/TEXT sloupce",-A
-"Typ pou-B¾ité tabulky nepodporuje AUTO_INCREMENT sloupce",-A
-"INSERT DELAYED nen-Bí mo¾no s tabulkou '%-.64s' pou¾ít, proto¾e je zamèená pomocí LOCK TABLES",-A
-"Nespr-Bávné jméno sloupce '%-.100s'",-A
-"Handler pou-B¾ité tabulky neumí indexovat sloupce '%-.64s'",-A
-"V-B¹echny tabulky v MERGE tabulce nejsou definovány stejnì",-A
-"Kv-Bùli unique constraintu nemozu zapsat do tabulky '%-.64s'",-A
-"BLOB sloupec '%-.64s' je pou-B¾it ve specifikaci klíèe bez délky",-A
-"V-B¹echny èásti primárního klíèe musejí být NOT NULL; pokud potøebujete NULL, pou¾ijte UNIQUE",-A
-"V-Býsledek obsahuje více ne¾ jeden øádek",-A
-"Tento typ tabulky vy-B¾aduje primární klíè",-A
-"Tato verze MySQL nen-Bí zkompilována s podporou RAID",-A
-"Update tabulky bez WHERE s kl-Bíèem není v módu bezpeèných update dovoleno",-A
-"Kl-Bíè '%-.64s' v tabulce '%-.64s' neexistuje",-A
-"Nemohu otev-Bøít tabulku",-A
+"Pro sd-Bílenou knihovnu nejsou povoleny cesty",
+"Funkce '%-.64s' ji-B¾ existuje",
+"Nemohu otev-Bøít sdílenou knihovnu '%-.64s' (errno: %d %s)",
+"Nemohu naj-Bít funkci '%-.64s' v knihovnì'",
+"Funkce '%-.64s' nen-Bí definována",
+"Stroj '%-.64s' je zablokov-Bán kvùli mnoha chybám pøi pøipojování. Odblokujete pou¾itím 'mysqladmin flush-hosts'",
+"Stroj '%-.64s' nem-Bá povoleno se k tomuto MySQL serveru pøipojit",
+"Pou-B¾íváte MySQL jako anonymní u¾ivatel a anonymní u¾ivatelé nemají povoleno mìnit hesla",
+"Na zm-Bìnu hesel ostatním musíte mít právo provést update tabulek v databázi mysql",
+"V tabulce user nen-Bí ¾ádný odpovídající øádek",
+"Nalezen-Bých øádkù: %ld Zmìnìno: %ld Varování: %ld",
+"Nemohu vytvo-Bøit nový thread (errno %d). Pokud je je¹tì nìjaká volná pamì», podívejte se do manuálu na èást o chybách specifických pro jednotlivé operaèní systémy",
+"Po-Bèet sloupcù neodpovídá poètu hodnot na øádku %ld",
+"Nemohu znovuotev-Bøít tabulku: '%-.64s',
+"Neplatn-Bé u¾ití hodnoty NULL",
+"Regul-Bární výraz vrátil chybu '%-.64s'",
+"Pokud nen-Bí ¾ádná GROUP BY klauzule, není dovoleno souèasné pou¾ití GROUP polo¾ek (MIN(),MAX(),COUNT()...) s ne GROUP polo¾kami",
+"Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s'",
+"%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro tabulku '%-.64s'",
+"%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro sloupec '%-.64s' v tabulce '%-.64s'",
+"Neplatn-Bý pøíkaz GRANT/REVOKE. Prosím, pøeètìte si v manuálu, jaká privilegia je mo¾né pou¾ít.",
+"Argument p-Bøíkazu GRANT u¾ivatel nebo stroj je pøíli¹ dlouhý",
+"Tabulka '%-.64s.%s' neexistuje",
+"Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s' pro tabulku '%-.64s'",
+"Pou-B¾itý pøíkaz není v této verzi MySQL povolen",
+"Va-B¹e syntaxe je nìjaká divná",
+"Zpo-B¾dìný insert threadu nebyl schopen získat po¾adovaný zámek pro tabulku %-.64s",
+"P-Bøíli¹ mnoho zpo¾dìných threadù",
+"Zru-B¹eno spojení %ld do databáze: '%-.64s' u¾ivatel: '%-.64s' (%s)",
+"Zji-B¹tìn pøíchozí packet del¹í ne¾ 'max_allowed_packet'",
+"Zji-B¹tìna chyba pøi ètení z roury spojení",
+"Zji-B¹tìna chyba fcntl()",
+"P-Bøíchozí packety v chybném poøadí",
+"Nemohu rozkomprimovat komunika-Bèní packet",
+"Zji-B¹tìna chyba pøi ètení komunikaèního packetu",
+"Zji-B¹tìn timeout pøi ètení komunikaèního packetu",
+"Zji-B¹tìna chyba pøi zápisu komunikaèního packetu",
+"Zji-B¹tìn timeout pøi zápisu komunikaèního packetu",
+"V-Býsledný øetìzec je del¹í ne¾ max_allowed_packet",
+"Typ pou-B¾ité tabulky nepodporuje BLOB/TEXT sloupce",
+"Typ pou-B¾ité tabulky nepodporuje AUTO_INCREMENT sloupce",
+"INSERT DELAYED nen-Bí mo¾no s tabulkou '%-.64s' pou¾ít, proto¾e je zamèená pomocí LOCK TABLES",
+"Nespr-Bávné jméno sloupce '%-.100s'",
+"Handler pou-B¾ité tabulky neumí indexovat sloupce '%-.64s'",
+"V-B¹echny tabulky v MERGE tabulce nejsou definovány stejnì",
+"Kv-Bùli unique constraintu nemozu zapsat do tabulky '%-.64s'",
+"BLOB sloupec '%-.64s' je pou-B¾it ve specifikaci klíèe bez délky",
+"V-B¹echny èásti primárního klíèe musejí být NOT NULL; pokud potøebujete NULL, pou¾ijte UNIQUE",
+"V-Býsledek obsahuje více ne¾ jeden øádek",
+"Tento typ tabulky vy-B¾aduje primární klíè",
+"Tato verze MySQL nen-Bí zkompilována s podporou RAID",
+"Update tabulky bez WHERE s kl-Bíèem není v módu bezpeèných update dovoleno",
+"Kl-Bíè '%-.64s' v tabulce '%-.64s' neexistuje",
+"Nemohu otev-Bøít tabulku",
"Handler tabulky nepodporuje check/repair",
-"Proveden-Bí tohoto pøíkazu není v transakci dovoleno",-A
-"Chyba %d p-Bøi COMMIT",-A
-"Chyba %d p-Bøi ROLLBACK",-A
-"Chyba %d p-Bøi FLUSH_LOGS",-A
-"Chyba %d p-Bøi CHECKPOINT",-A
-"Spojen-Bí %ld do databáze: '%-.64s' u¾ivatel: '%-.32s' stroj: `%-.64s' (%-.64s) bylo pøeru¹eno",-A
-"Handler tabulky nepodporuje bin-Bární dump",-A
-"Binlog uzav-Bøen pøi pokusu o FLUSH MASTER",-A
-"P-Bøebudování indexu dumpnuté tabulky '%-.64s' nebylo úspì¹né",-A
+"Proveden-Bí tohoto pøíkazu není v transakci dovoleno",
+"Chyba %d p-Bøi COMMIT",
+"Chyba %d p-Bøi ROLLBACK",
+"Chyba %d p-Bøi FLUSH_LOGS",
+"Chyba %d p-Bøi CHECKPOINT",
+"Spojen-Bí %ld do databáze: '%-.64s' u¾ivatel: '%-.32s' stroj: `%-.64s' (%-.64s) bylo pøeru¹eno",
+"Handler tabulky nepodporuje bin-Bární dump",
+"Binlog uzav-Bøen pøi pokusu o FLUSH MASTER",
+"P-Bøebudování indexu dumpnuté tabulky '%-.64s' nebylo úspì¹né",
"Chyba masteru: '%-.64s'",
-"S-Bí»ová chyba pøi ètení z masteru",-A
-"S-Bí»ová chyba pøi zápisu na master",-A
-"-B®ádný sloupec nemá vytvoøen fulltextový index",-A
-"Nemohu prov-Bést zadaný pøíkaz, proto¾e existují aktivní zamèené tabulky nebo aktivní transakce",-A
-"Nezn-Bámá systémová promìnná '%-.64s'",-A
-"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a mìla by být opravena",-A
-"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a poslední (automatická?) oprava se nezdaøila",-A
+"S-Bí»ová chyba pøi ètení z masteru",
+"S-Bí»ová chyba pøi zápisu na master",
+"-B®ádný sloupec nemá vytvoøen fulltextový index",
+"Nemohu prov-Bést zadaný pøíkaz, proto¾e existují aktivní zamèené tabulky nebo aktivní transakce",
+"Nezn-Bámá systémová promìnná '%-.64s'",
+"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a mìla by být opravena",
+"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a poslední (automatická?) oprava se nezdaøila",
"Warning: Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
"This operation cannot be performed with a running slave, run SLAVE STOP first",
@@ -228,3 +228,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index 6ee6e23a18e..7d409e3133f 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -222,3 +222,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index b857eb3104d..4a674999c82 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -2,9 +2,12 @@
This file is public domain and comes with NO WARRANTY of any kind
Dutch error messages (share/dutch/errmsg.txt)
- Arjen G. Lentz (agl@bitbike.com)
+ 2001-08-02 - Arjen Lentz (agl@bitbike.com)
Completed earlier partial translation; worked on consistency and spelling.
- Version: 02-08-2001
+ 2002-01-29 - Arjen Lentz (arjen@mysql.com)
+ 2002-04-11 - Arjen Lentz (arjen@mysql.com)
+ 2002-06-13 - Arjen Lentz (arjen@mysql.com)
+ Translated new error messages.
*/
"hashchk",
@@ -16,9 +19,9 @@
"Kan database '%-.64s' niet aanmaken (Errcode: %d)",
"Kan database '%-.64s' niet aanmaken. Database bestaat reeds",
"Kan database '%-.64s' niet verwijderen. Database bestaat niet",
-"Error verwijderen database (kan '%-.64s' niet verwijderen, Errcode: %d)",
-"Error verwijderen database (kan rmdir '%-.64s' niet uitvoeren, Errcode: %d)",
-"Error bij het verwijderen van '%-.64s' (Errcode: %d)",
+"Fout bij verwijderen database (kan '%-.64s' niet verwijderen, Errcode: %d)",
+"Fout bij verwijderen database (kan rmdir '%-.64s' niet uitvoeren, Errcode: %d)",
+"Fout bij het verwijderen van '%-.64s' (Errcode: %d)",
"Kan record niet lezen in de systeem tabel",
"Kan de status niet krijgen van '%-.64s' (Errcode: %d)",
"Kan de werkdirectory niet krijgen (Errcode: %d)",
@@ -153,7 +156,7 @@
"%-.16s commando geweigerd voor gebruiker: '%-.32s@%-.64s' voor kolom '%-.64s' in tabel '%-.64s'",
"Foutief GRANT/REVOKE commando. Raadpleeg de handleiding welke priveleges gebruikt kunnen worden.",
"De host of gebruiker parameter voor GRANT is te lang",
-"Tabel '%-64s.%s' bestaat niet",
+"Tabel '%-.64s.%s' bestaat niet",
"Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s' op tabel '%-.64s'",
"Het used commando is niet toegestaan in deze MySQL versie",
"Er is iets fout in de gebruikte syntax",
@@ -167,8 +170,8 @@
"Communicatiepakket kon niet worden gedecomprimeerd",
"Fout bij het lezen van communicatiepakketten"
"Timeout bij het lezen van communicatiepakketten",
-"Got an error writing communication packets",
-"Got timeout writing communication packets",
+"Fout bij het schrijven van communicatiepakketten",
+"Timeout bij het schrijven van communicatiepakketten",
"Resultaat string is langer dan max_allowed_packet",
"Het gebruikte tabel type ondersteunt geen BLOB/TEXT kolommen",
"Het gebruikte tabel type ondersteunt geen AUTO_INCREMENT kolommen",
@@ -218,10 +221,28 @@
"DROP DATABASE niet toegestaan terwijl thread een globale 'read lock' bezit",
"CREATE DATABASE niet toegestaan terwijl thread een globale 'read lock' bezit",
"Foutieve parameters voor %s",
-"%-.32s@%-.64s is not allowed to create new users",
-"Incorrect table definition; All MERGE tables must be in the same database",
-"Deadlock found when trying to get lock; Try restarting transaction",
-"The used table type doesn't support FULLTEXT indexes",
-"Cannot add foreign key constraint",
-"Cannot add a child row: a foreign key constraint fails",
-"Cannot delete a parent row: a foreign key constraint fails",
+"%-.32s@%-.64s mag geen nieuwe gebruikers creeren",
+"Incorrecte tabel definitie; Alle MERGE tabellen moeten tot dezelfde database behoren",
+"Deadlock gevonden tijdens lock-aanvraag poging; Probeer herstart van de transactie",
+"Het gebruikte tabel type ondersteund geen FULLTEXT indexen",
+"Kan foreign key beperking niet toevoegen",
+"Kan onderliggende rij niet toevoegen: foreign key beperking gefaald",
+"Kan bovenliggende rij nite verwijderen: foreign key beperking gefaald",
+"Fout bij opbouwen verbinding naar master: %-.128s",
+"Fout bij uitvoeren query op master: %-.128s",
+"Fout tijdens uitvoeren van commando %s: %-.128s",
+"Foutief gebruik van %s en %s",
+"De gebruikte SELECT commando's hebben een verschillend aantal kolommen",
+"Kan de query niet uitvoeren vanwege een conflicterende read lock",
+"Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.",
+"Optie '%s' tweemaal gebruikt in opdracht",
+"Gebruiker '%-.64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)",
+"Toegang geweigerd. U moet het %-.128s privilege hebben voor deze operatie",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt
index b67c1e1a0df..04150b67084 100644
--- a/sql/share/english/errmsg.txt
+++ b/sql/share/english/errmsg.txt
@@ -219,3 +219,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index d57f6871e12..2a0233ca949 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -1,225 +1,244 @@
-/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB
- This file is public domain and comes with NO WARRANTY of any kind
+/*
+ Copyright Abandoned 1997 MySQL AB
+ This file is public domain and comes with NO WARRANTY of any kind
+ Esialgne tõlge: Tõnu Samuel (tonu@spam.ee)
+ Parandanud ja täiendanud: Indrek Siitan (tfr@mysql.com)
- Translated into estonian language by Tonu Samuel
- email: tonu@spam.ee
*/
"hashchk",
"isamchk",
"EI",
"JAH",
-"Ei saa luua tabelit '%-.64s' (vea kood: %d)",
-"Ei saa luua tabelit '%-.64s' (vea kood: %d)",
-"Ei saa luua andmebaasi '%-.64s'. (vea kood: %d)",
-"Ei saa luua andmebaasi '%-.64s'. Andmebaas on juba olemas",
-"Ei saa kustutada andmebaasi '%-.64s'. Andmebaasi ei eksisteeri",
-"Ei saa kustutada andmebaasi (Ei saa kustutada faili '%-.64s', vea kood: %d)",
-"Ei saa kustutada andmebaasi (Ei saa kustutada kataloogi '%-.64s', vea kood: %d)",
-"Viga '%-.64s' kustutamisel (vea kood: %d)",
-"Ei saa lugeda kirjet in süsteemsest tabelist",
-"Ei saa lugeda '%-.64s' olekut (vea kood: %d)",
-"Ei saa teada jooksva kataloogi nime (vea kood: %d)",
-"Ei saa avada lukustusfaili (vea kood: %d)",
-"Ei saa avada faili: '%-.64s'. (vea kood: %d)",
-"Ei leia faili: '%-.64s' (vea kood: %d)",
-"Ei saa lugeda kataloogi '%-.64s' (vea kood: %d)",
-"Ei saa siseneda kataloogi '%-.64s' (vea kood: %d)",
-"Kirje on muutunud võrreldes eelmise lugemisega tabelis '%-.64s'",
-"Ketas on täis (%s). Ootame kuni tekib vaba ruumi....",
-"Ei saa kirjutada, Korduv võti tabelis '%-.64s'",
-"Viga faili '%-.64s' sulgemisel (vea kood: %d)",
-"Viga faili '%-.64s' lugemisel (vea kood: %d)",
-"Viga faili '%-.64s' ringi nimetamisel '%-.64s'-ks (vea kood: %d)",
-"Viga faili '%-.64s' kirjutamisel (vea kood: %d)",
+"Ei suuda luua faili '%-.64s' (veakood: %d)",
+"Ei suuda luua tabelit '%-.64s' (veakood: %d)",
+"Ei suuda luua andmebaasi '%-.64s'. (veakood: %d)",
+"Ei suuda luua andmebaasi '%-.64s': andmebaas juba eksisteerib",
+"Ei suuda kustutada andmebaasi '%-.64s': andmebaasi ei eksisteeri",
+"Viga andmebaasi kustutamisel (ei suuda kustutada faili '%-.64s', veakood: %d)",
+"Viga andmebaasi kustutamisel (ei suuda kustutada kataloogi '%-.64s', veakood: %d)",
+"Viga '%-.64s' kustutamisel (veakood: %d)",
+"Ei suuda lugeda kirjet süsteemsest tabelist",
+"Ei suuda lugeda '%-.64s' olekut (veakood: %d)",
+"Ei suuda identifitseerida jooksvat kataloogi (veakood: %d)",
+"Ei suuda lukustada faili (veakood: %d)",
+"Ei suuda avada faili '%-.64s'. (veakood: %d)",
+"Ei suuda leida faili '%-.64s' (veakood: %d)",
+"Ei suuda lugeda kataloogi '%-.64s' (veakood: %d)",
+"Ei suuda siseneda kataloogi '%-.64s' (veakood: %d)",
+"Kirje tabelis '%-.64s' on muutunud viimasest lugemisest saadik",
+"Ketas täis (%s). Ootame kuni tekib vaba ruumi...",
+"Ei saa kirjutada, korduv võti tabelis '%-.64s'",
+"Viga faili '%-.64s' sulgemisel (veakood: %d)",
+"Viga faili '%-.64s' lugemisel (veakood: %d)",
+"Viga faili '%-.64s' ümbernimetamisel '%-.64s'-ks (veakood: %d)",
+"Viga faili '%-.64s' kirjutamisel (veakood: %d)",
"'%-.64s' on lukustatud muudatuste vastu",
"Sorteerimine katkestatud",
-"Vaade '%-.64s' puudub '%-.64s' jaoks",
-"Viga %d tabelitöötluses",
-"Table handler for '%-.64s' doesn't have this option",
+"Vaade '%-.64s' ei eksisteeri '%-.64s' jaoks",
+"Tabeli handler tagastas vea %d",
+"Tabeli '%-.64s' handler ei toeta antud operatsiooni",
"Ei suuda leida kirjet '%-.64s'-s",
-"Väär informatsiion failis '%-.64s'",
-"Vigastatud võtmefail tabelile '%-.64s'",
-"Vana võtmefail tabelile '%-.64s'. Proovi teda parandada",
-"Tabel '%-.64s' on ainult lugemise õigusega",
-"Mälu sai otsa. Proovi MySQL uuesti käivitada (Puudu jäi %d baiti)",
-"Mälu sai sorteerimie ajal otsa. Suurenda MySQL-i sorteerimispuhvrit",
-"Ootamatu faili lõpp leitud faili '%-.64s' lugemisel (vea kood: %d)",
+"Vigane informatsioon failis '%-.64s'",
+"Tabeli '%-.64s' võtmefail on vigane; Proovi seda parandada",
+"Tabeli '%-.64s' võtmefail on aegunud; Paranda see!",
+"Tabel '%-.64s' on ainult lugemiseks",
+"Mälu sai otsa. Proovi MySQL uuesti käivitada (puudu jäi %d baiti)",
+"Mälu sai sorteerimisel otsa. Suurenda MySQL-i sorteerimispuhvrit",
+"Ootamatu faililõpumärgend faili '%-.64s' lugemisel (veakood: %d)",
"Liiga palju samaaegseid ühendusi",
-"Mälu sai otsa. Võimalik, et aitab swap-i lisamine või käsu 'ulimit' abil MySQL-le rohkema mälu kasutamise lubamine.",
+"Mälu sai otsa. Võimalik, et aitab swap-i lisamine või käsu 'ulimit' abil MySQL-le rohkema mälu kasutamise lubamine",
"Ei suuda lahendada IP aadressi masina nimeks",
"Väär handshake",
-"Ligipääs piiratud kasutajale: '%-.32s@%-.64s' andmebaasi '%-.64s'",
-"Ligipääs piiratud kasutajale: '%-.32s@%-.64s' (Kasutab parooli: %s)",
-"Andmebaas pole valitud",
+"Ligipääs keelatud kasutajale '%-.32s@%-.64s' andmebaasile '%-.64s'",
+"Ligipääs keelatud kasutajale '%-.32s@%-.64s' (kasutab parooli: %s)",
+"Andmebaasi ei ole valitud",
"Tundmatu käsk",
-"Tulp '%-.64s' ei saa olla null",
+"Tulp '%-.64s' ei saa omada nullväärtust",
"Tundmatu andmebaas '%-.64s'",
-"Tabel '%-.64s' on juba olemas",
+"Tabel '%-.64s' juba eksisteerib",
"Tundmatu tabel '%-.64s'",
-"Tulp: '%-.64s' in %-.64s on väär",
+"Väli '%-.64s' %-.64s-s ei ole ühene",
"Serveri seiskamine käib",
-"Tundmatu tulp '%-.64s' in '%-.64s'",
-"'%-.64s' puudub GROUP BY-s",
+"Tundmatu tulp '%-.64s' '%-.64s'-s",
+"'%-.64s' puudub GROUP BY klauslis",
"Ei saa grupeerida '%-.64s' järgi",
-"Lauses on korraga nii tulbad kui summad",
-"Tuplade arv tabelis erineb antud väärtuste arvust",
+"Lauses on korraga nii tulbad kui summeerimisfunktsioonid",
+"Tulpade arv erineb väärtuste arvust",
"Identifikaatori '%-.100s' nimi on liiga pikk",
"Kattuv tulba nimi '%-.64s'",
"Kattuv võtme nimi '%-.64s'",
-"Kattuv nimi '%-.64s' võtmele %d",
-"Väär tulba kirjeldus tulbale '%-.64s'",
-"%s '%-.80s' ligidal reas %d",
+"Kattuv väärtus '%-.64s' võtmele %d",
+"Vigane tulba kirjeldus tulbale '%-.64s'",
+"%s '%-.80s' ligidal real %d",
"Tühi päring",
-"Pole unikaalne tabel/alias '%-.64s'",
-"Vale vaikeväärtus '%-.64s'",
-"Mitut põhivõtit (PRIMARY KEY) ei saa olla",
-"Liiga palju võtmeid määratletud. Maksimaalselt võib olla %d võtit",
+"Ei ole unikaalne tabel/alias '%-.64s'",
+"Vigane vaikeväärtus '%-.64s' jaoks",
+"Mitut primaarset võtit ei saa olla",
+"Liiga palju võtmeid. Maksimaalselt võib olla %d võtit",
"Võti koosneb liiga paljudest osadest. Maksimaalselt võib olla %d osa",
-"Määratletud võti sai liiga pikk. Maksimaalne lubatud pikkus on %d",
-"Võtme tulp '%-.64s' puudub antud tabelis",
-"BLOB tulpa '%-.64s' ei saa kasutada võtmena",
-"Tulba '%-.64s' pikkus on liiga pikk (maksimaalne = %d).",
-"Tabeli kohta saab olla ainult üks auto_increment tulp ja see peab olema samas ka võtmena",
+"Võti on liiga pikk. Maksimaalne võtmepikkus on %d",
+"Võtme tulp '%-.64s' puudub tabelis",
+"BLOB-tüüpi tulpa '%-.64s' ei saa kasutada võtmena",
+"Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %d). Kasuta BLOB väljatüüpi",
+"Vigane tabelikirjeldus; Tabelis tohib olla üks auto_increment tüüpi tulp ning see peab olema defineeritud võtmena",
"%s: ootab ühendusi\n",
"%s: MySQL lõpetas\n",
-"%s: Sain signaali %d. Lõpetan!\n",
+"%s: sain signaali %d. Lõpetan!\n",
"%s: Lõpp\n",
-"%s: Sulgen jõuga threadi %ld kasutaja: '%-.64s'\n",
-"Ei saa luua IP pesa",
+"%s: Sulgen jõuga lõime %ld kasutaja: '%-.32s'\n",
+"Ei suuda luua IP socketit",
"Tabelil '%-.64s' puuduvad võtmed. Loo tabel uuesti",
-"Väljade eraldaja on väär. Vaata kasutamisjuhendisse",
-"BLOB väljadega ei saa kasutada fikseeritud väljapikkust. Seetõttu on vajalik lisaklausel 'fields terminated by'.",
-"Fail '%-.64s' peab asuma andmebaasi kataloogis ning olema loetav",
-"Fail '%-.64s' on juba olemas",
-"Kirjed: %ld Kustutatud: %ld Vahele jäetud: %ld Hoiatusi: %ld",
-"Kirjed: %ld Topelt: %ld",
-"Väär võtme osa. Kasutatud võtme osa ei ole string või on pikkus pikem kui võtme osa",
-"ALTER TABLE abil ei saa koiki tulpasid kustutada. DROP TABLE kustutab terve tabeli",
-"Ei saa kustutada '%-.64s'. On selline tulp või võti üldse olemas?",
-"Kirjed: %ld Topelt: %ld Hoiatusi: %ld",
-"INSERT TABLE '%-.64s' pole lubatud FROM tabelite nimekirjas",
-"Tundmatu threadi id: %lu",
-"Pole threadi %lu omanik",
-"Pole kasutatud tabeleid",
-"Liiga palju stringe tulbale %-.64s ja tüübile SET",
-"Ei saa luua ainulaadset failinime %-.64s.(1-999)\n",
-"Tabel '%-.64s' on lukustatud ainult lugemiseks ja sinna kirjutada ei saa",
-"Tabel '%-.64s' pole lukustatud käsuga LOCK TABLES",
-"BLOB tüüpi tulbal '%-.64s' ei saa olla vaikeväärtust",
-"Väär andmebaasi nimi '%-.100s'",
-"Väär tabeli nimi '%-.100s'",
-"SELECT lause peab läbi vaatama suure hulga kirjeid ja võtaks tõenäoliselt liiga kaua aega. Tasub kontrollide WHERE klauslit ja vajadusel kasutada käsku SET OPTION SQL_BIG_SELECTS=1",
+"Väljade eraldaja erineb oodatust. Tutvu kasutajajuhendiga",
+"BLOB-tüüpi väljade olemasolul ei saa kasutada fikseeritud väljapikkust. Vajalik 'fields terminated by' määrang.",
+"Fail '%-.64s' peab asuma andmebaasi kataloogis või olema kõigile loetav",
+"Fail '%-.80s' juba eksisteerib",
+"Kirjeid: %ld Kustutatud: %ld Vahele jäetud: %ld Hoiatusi: %ld",
+"Kirjeid: %ld Kattuvaid: %ld",
+"Vigane võtme osa. Kasutatud võtmeosa ei ole string tüüpi, määratud pikkus on pikem kui võtmeosa või tabelihandler ei toeta seda tüüpi võtmeid",
+"ALTER TABLE kasutades ei saa kustutada kõiki tulpasid. Kustuta tabel DROP TABLE abil",
+"Ei suuda kustutada '%-.64s'. Kontrolli kas tulp/võti eksisteerib",
+"Kirjeid: %ld Kattuvaid: %ld Hoiatusi: %ld",
+"INSERT TABLE '%-.64s' ei ole lubatud FROM tabelite nimekirjas",
+"Tundmatu lõim: %lu",
+"Ei ole lõime %lu omanik",
+"Ühtegi tabelit pole kasutusel",
+"Liiga palju string tulbale %-.64s tüübile SET",
+"Ei suuda luua unikaalset logifaili nime %-.64s.(1-999)\n",
+"Tabel '%-.64s' on lukustatud READ lukuga ning ei ole muudetav",
+"Tabel '%-.64s' ei ole lukustatud käsuga LOCK TABLES",
+"BLOB-tüüpi tulp '%-.64s' ei saa omada vaikeväärtust",
+"Vigane andmebaasi nimi '%-.100s'",
+"Vigane tabeli nimi '%-.100s'",
+"SELECT lause peab läbi vaatama suure hulga kirjeid ja võtaks tõenäoliselt liiga kaua aega. Tasub kontrollida WHERE klauslit ja vajadusel kasutada käsku SET OPTION SQL_BIG_SELECTS=1",
"Tundmatu viga",
"Tundmatu protseduur '%-.64s'",
-"Väär parameetrite hulk protseduurile '%-.64s'",
-"Valed parameetrid protseduurile '%-.64s'",
-"Tundmatu tabel '%-.64s' %s-s",
+"Vale parameetrite hulk protseduurile '%-.64s'",
+"Vigased parameetrid protseduurile '%-.64s'",
+"Tundmatu tabel '%-.64s' %-.32s-s",
"Tulp '%-.64s' on määratletud topelt",
-"GROUP BY funktsiooni väärkasutamine",
-"Tabel '%-.64s' kasutab laiendit, mis on tundmatu sellele MySQL versioonile",
-"Tabelil peab olema vähemalt üks tulp",
+"Vigane grupeerimisfunktsiooni kasutus",
+"Tabel '%-.64s' kasutab laiendust, mis ei eksisteeri antud MySQL versioonis",
+"Tabelis peab olema vähemalt üks tulp",
"Tabel '%-.64s' on täis",
-"Tundmatu kooditabel: '%-.64s'",
-"Liiga palju tabeleid. MySQL oskab kasutada kuni %d tabelit JOINi puhul",
+"Vigane kooditabel '%-.64s'",
+"Liiga palju tabeleid. MySQL suudab JOINiga ühendada kuni %d tabelit",
"Liiga palju tulpasid",
-"Liiga pikk kirje. Maksimaalne kirje pikkus arvestamata BLOB tüüpi on %d. Võib-olla aitab mõnede väljade muutmine BLOB tüübiks",
-"Threadi stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thlugeda_stack=#' to specify a bigger stack if needed",
-"Ristsõltuvus OUTER JOIN-s. ON tingimused tuleks üle kontrollida",
-"Tulp '%-.64s' on kasutused indeksis kui pole defineeritud tüübiga NOT NULL",
-"Ei saa avada funktsiooni '%-.64s'",
-"Ei saa algväärtustada funktsiooni '%-.64s'; %-.80s",
+"Liiga pikk kirje. Kirje maksimumpikkus arvestamata BLOB-tüüpi välju on %d. Muuda mõned väljad BLOB-tüüpi väljadeks",
+"Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed",
+"Ristsõltuvus OUTER JOIN klauslis. Kontrolli oma ON tingimusi",
+"Tulp '%-.64s' on kasutusel indeksina, kuid ei ole määratletud kui NOT NULL",
+"Ei suuda avada funktsiooni '%-.64s'",
+"Ei suuda algväärtustada funktsiooni '%-.64s'; %-.80s",
"Teegi nimes ei tohi olla kataloogi",
-"Funktsioon '%-.64s' on juba olemas",
-"Ei saa avada teeki '%-.64s' (vea kood: %d %s)",
-"Ei leia funktsiooni '%-.64s' selles teegis'",
-"Funktsiooni '%-.64s' pole defineeritud",
-"Masin '%-.64s' blokeeritud hulgaliste ühendusvigade pärast. Blokeeringu saab eemaldada käsuga 'mysqladmin flush-hosts'",
-"Masinale '%-.64s' pole lubatud ligipääsu sellele MySQL serverile",
+"Funktsioon '%-.64s' juba eksisteerib",
+"Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %-.64s)",
+"Ei leia funktsiooni '%-.64s' antud teegis",
+"Funktsioon '%-.64s' ei ole defineeritud",
+"Masin '%-.64s' on blokeeritud hulgaliste ühendusvigade tõttu. Blokeeringu saab tühistada 'mysqladmin flush-hosts' käsuga",
+"Masinal '%-.64s' puudub ligipääs sellele MySQL serverile",
"Te kasutate MySQL-i anonüümse kasutajana, kelledel pole parooli muutmise õigust",
-"Teil peab olema tabelite muutmise õigus muutmaks teiste paroole",
-"Ei leia kirjet kasutajate tabelis",
-"Sobinud kirjed: %ld Muudetud: %ld Hoiatusi: %ld",
-"Ei saa luua threadi (vea kood %d). Kui mälu pole otsas, tasub operatsioonisüsteemi spetsiifilist viga",
-"Tulpade arv ei vasta väärtuste hulgale reas %ld",
-"Ei saa avada tabelit: '%-.64s',
+"Teiste paroolide muutmiseks on nõutav tabelite muutmisõigus 'mysql' andmebaasis",
+"Ei leia vastavat kirjet kasutajate tabelis",
+"Sobinud kirjeid: %ld Muudetud: %ld Hoiatusi: %ld",
+"Ei suuda luua uut lõime (veakood %d). Kui mälu ei ole otsas, on tõenäoliselt tegemist operatsioonisüsteemispetsiifilise veaga",
+"Tulpade hulk erineb väärtuste hulgast real %ld",
+"Ei suuda taasavada tabelit '%-.64s'",
"NULL väärtuse väärkasutus",
-"Viga '%-.64s' regexp-i käest",
-"GROUP tulpade segamine (MIN(),MAX(),COUNT()...) on väär kui ei kasutata GROUP BY klauslit",
-"Sellist õigust ei ole kasutajale '%-.32s' masinast '%-.64s'",
-"%-.16s käsk pole lubatud kasutajale '%-.32s@%-.64s' tabelile '%-.64s'",
-"%-.16s käsk pole lubatud kasutajale '%-.32s@%-.64s' tulbale '%-.64s' tabelis '%-.64s'",
-"Väär GRANT/REVOKE kasutus",
-"Masina või kasutaja nimi on liiga pikk GRANT lauses",
-"Tabelit '%-64s.%s' ei leitud",
-"Sellist õigust pole kasutajale '%-.32s' masinast '%-.64s' tabelile '%-.64s'",
-"Antud käsk pole lubatud selle MySQL-i versiooniga",
+"regexp tagastas vea '%-.64s'",
+"GROUP tulpade (MIN(),MAX(),COUNT()...) kooskasutamine tavaliste tulpadega ilma GROUP BY klauslita ei ole lubatud",
+"Sellist õigust ei ole defineeritud kasutajale '%-.32s' masinast '%-.64s'",
+"%-.16s käsk ei ole lubatud kasutajale '%-.32s@%-.64s' tabelis '%-.64s'",
+"%-.16s käsk ei ole lubatud kasutajale '%-.32s@%-.64s' tulbale '%-.64s' tabelis '%-.64s'",
+"Vigane GRANT/REVOKE käsk. Tutvu kasutajajuhendiga",
+"Masina või kasutaja nimi GRANT lauses on liiga pikk",
+"Tabelit '%-.64s.%-.64s' ei eksisteeri",
+"Sellist õigust ei ole defineeritud kasutajale '%-.32s' masinast '%-.64s' tabelile '%-.64s'",
+"Antud käsk ei ole lubatud käesolevas MySQL versioonis",
"Viga SQL süntaksis",
-"INSERT DELAYED thread ei saanud nõutavat lukku tabelile %-.64s",
-"Liiga palju DELAYED threade on kasutusel",
-"Ühendus katkestatud %ld andmebaasile '%-.64s' kasutaja '%-.64s' (%s)",
-"Sain lubatust suurema paketi (max_allowed_packet)",
-"Got a read error from the connection pipe",
-"Got an error from fcntl()",
-"Got packets out of order",
-"Ei suuda ühendust lahti pakkida",
-"Viga ühenduse lugemisel",
-"Aeg sai otsa ühenduse lugemisel",
-"Viga ühenduse kirjutamisel",
-"Aeg sai otsa ühenduse kirjutamisel",
-"Tulemuseks saadud string on pikem kui max_allowed_packet väärtus",
-"Kasutatud tabeli tüüp ei toeta BLOB/TEXT tulpasid",
-"Kasutatud tabeli tüüp ei toeta AUTO_INCREMENT tulpasid",
-"INSERT DELAYED käsku ei saa kasutada tabeliga '%-.64s', kuna see on lukus käsuga LOCK TABLES",
-"Väär tulba nimi '%-.100s'",
-"Kasutusel olev tabelite haldur ei oska indekseerida tulpa '%-.64s'",
-"All tables in the MERGE table are not identically defined",
-"Can't write, because of unique constraint, to table '%-.64s'",
-"BLOB column '%-.64s' used in key specification without a key length",
-"All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead",
-"Tulemis on rohkem kui üks kirje",
-"This table type requires a primary key",
-"Antud MySQL ei ole kompileeritud RAID-i toega",
-"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
-"Key '%-.64s' doesn't exist in table '%-.64s'",
-"Ei suuda tabelit avada",
-"See tabelitüüp ei toeta käske CHECK/REPAIR",
-"Puudub õigus selle transaktsioonikäsu andmiseks",
-"Sain vea %d COMMIT käsu täitmisel",
-"Sain vea %d ROLLBACK käsu täitmisel",
-"Sain vea %d FLUSH_LOGS käsu täitmisel",
-"Sain vea %d CHECKPOINT käsu täitmisel",
-"Ühendus %ld katkestatud andmebaas: '%-.64s' kasutaja: '%-.32s' masin: `%-.64s' (%-.64s)",
+"INSERT DELAYED lõim ei suutnud saada soovitud lukku tabelile %-.64s",
+"Liiga palju DELAYED lõimesid kasutusel",
+"Ühendus katkestatud %ld andmebaasile: '%-.64s' kasutajale: '%-.32s' (%-.64s)",
+"Saabus suurem pakett kui lubatud 'max_allowed_packet' muutujaga",
+"Viga ühendustoru lugemisel",
+"fcntl() tagastas vea",
+"Paketid saabusid vales järjekorras",
+"Viga andmepaketi lahtipakkimisel",
+"Viga andmepaketi lugemisel",
+"Kontrollaja ületamine andmepakettide lugemisel",
+"Viga andmepaketi kirjutamisel",
+"Kontrollaja ületamine andmepakettide kirjutamisel",
+"Tulemus on pikem kui lubatud 'max_allowed_packet' muutujaga",
+"Valitud tabelitüüp ei toeta BLOB/TEXT tüüpi välju",
+"Valitud tabelitüüp ei toeta AUTO_INCREMENT tüüpi välju",
+"INSERT DELAYED ei saa kasutada tabeli '%-.64s' peal, kuna see on lukustatud LOCK TABLES käsuga",
+"Vigane tulba nimi '%-.100s'",
+"Tabelihandler ei oska indekseerida tulpa '%-.64s'",
+"Kõik tabelid MERGE tabeli määratluses ei ole identsed",
+"Ei suuda kirjutada tabelisse '%-.64s', kuna see rikub ühesuse kitsendust",
+"BLOB-tüüpi tulp '%-.64s' on kasutusel võtmes ilma pikkust määratlemata",
+"Kõik PRIMARY KEY peavad olema määratletud NOT NULL piiranguga; vajadusel kasuta UNIQUE tüüpi võtit",
+"Tulemis oli rohkem kui üks kirje",
+"Antud tabelitüüp nõuab primaarset võtit",
+"Antud MySQL versioon on kompileeritud ilma RAID toeta",
+"Katse muuta tabelit turvalises rezhiimis ilma WHERE klauslita",
+"Võti '%-.64s' ei eksisteeri tabelis '%-.64s'",
+"Ei suuda avada tabelit",
+"Antud tabelitüüp ei toeta CHECK/REPAIR käske",
+"Seda käsku ei saa kasutada transaktsiooni sees",
+"Viga %d käsu COMMIT täitmisel",
+"Viga %d käsu ROLLBACK täitmisel",
+"Viga %d käsu FLUSH_LOGS täitmisel",
+"Viga %d käsu CHECKPOINT täitmisel",
+"Ühendus katkestatud %ld andmebaas: '%-.64s' kasutaja: '%-.32s' masin: `%-.64s' (%-.64s)",
"The handler for the table does not support binary table dump",
"Binlog closed while trying to FLUSH MASTER",
"Failed rebuilding the index of dumped table '%-.64s'",
"Error from master: '%-.64s'",
"Net error reading from master",
"Net error writing to master",
-"Can't find FULLTEXT index matching the column list",
-"Can't execute the given command because you have active locked tables or an active transaction",
-"Tundmatu süsteemne muutja '%-.64s'",
+"Ei suutnud leida FULLTEXT indeksit, mis kattuks kasutatud tulpadega",
+"Ei suuda täita antud käsku kuna on aktiivseid lukke või käimasolev transaktsioon",
+"Tundmatu süsteemne muutuja '%-.64s'",
"Tabel '%-.64s' on märgitud vigaseks ja tuleb parandada",
-"Tabel '%-.64s' on märgitud vigaseks ja viimane (automaatne?) parandamiskatse ebaõnnestus",
-"Warning: Some non-transactional changed tables couldn't be rolled back",
-"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
+"Tabel '%-.64s' on märgitud vigaseks ja viimane (automaatne?) parandus ebaõnnestus",
+"Hoiatus: mõnesid transaktsioone mittetoetavaid tabeleid ei suudetud tagasi kerida",
+"Mitme lausendiga transaktsioon nõudis rohkem ruumi kui lubatud 'max_binlog_cache_size' muutujaga. Suurenda muutuja väärtust ja proovi uuesti",
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
"Could not initialize master info structure, check permisions on master.info",
"Could not create slave thread, check system resources",
-"User %-.64s has already more than 'max_user_connections' active connections",
-"You may only use constant expressions with SET",
-"Lock wait timeout exceeded",
-"The total number of locks exceeds the lock table size",
-"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
-"DROP DATABASE not allowed while thread is holding global read lock",
-"CREATE DATABASE not allowed while thread is holding global read lock",
-"Wrong arguments to %s",
-"%-.32s@%-.64s is not allowed to create new users",
-"Incorrect table definition; All MERGE tables must be in the same database",
-"Deadlock found when trying to get lock; Try restarting transaction",
-"The used table type doesn't support FULLTEXT indexes",
+"Kasutajal %-.64s on juba rohkem ühendusi kui lubatud 'max_user_connections' muutujaga",
+"Ainult konstantsed suurused on lubatud SET klauslis",
+"Kontrollaeg ületatud luku järel ootamisel; Proovi transaktsiooni otsast alata",
+"Lukkude koguarv ületab lukutabeli suuruse",
+"Uuenduslukke ei saa kasutada READ UNCOMMITTED transaktsiooni käigus",
+"DROP DATABASE ei ole lubatud kui lõim omab globaalset READ lukku",
+"CREATE DATABASE ei ole lubatud kui lõim omab globaalset READ lukku",
+"Vigased parameetrid %s-le",
+"Kasutajal %-.32s@%-.64s ei ole lubatud luua uusi kasutajaid",
+"Vigane tabelimääratlus; kõik MERGE tabeli liikmed peavad asuma samas andmebaasis",
+"Lukustamisel tekkis tupik (deadlock); alusta transaktsiooni otsast",
+"Antud tabelitüüp ei toeta FULLTEXT indekseid",
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Viga käsu %s täitmisel: %-.128s",
+"Vigane %s ja %s kasutus",
+"Tulpade arv kasutatud SELECT lausetes ei kattu",
+"Ei suuda täita päringut konfliktse luku tõttu",
+"Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud",
+"Määrangut '%s' on lauses kasutatud topelt",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index 07b88e1356e..42f83e6eed2 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -147,7 +147,7 @@
"La commande '%-.16s' est interdite à l'utilisateur: '%-.32s@%-.64s' sur la colonne '%-.64s' de la table '%-.64s'",
"Commande GRANT/REVOKE incorrecte. Consultez le manuel.",
"L'hôte ou l'utilisateur donné en argument à GRANT est trop long",
-"La table '%-64s.%s' n'existe pas",
+"La table '%-.64s.%s' n'existe pas",
"Un tel droit n'est pas défini pour l'utilisateur '%-.32s' sur l'hôte '%-.64s' sur la table '%-.64s'",
"Cette commande n'existe pas dans cette version de MySQL",
"Erreur de syntaxe",
@@ -219,3 +219,21 @@
"Impossible d'ajouter des contraintes d'index externe",
"Impossible d'ajouter un enregistrement fils : une constrainte externe l'empèche",
"Impossible de supprimer un enregistrement père : une constrainte externe l'empèche",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index fe76c757d11..0cd3f8cd902 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -222,3 +222,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index b491b0ef1f9..bed0afe8286 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -219,3 +219,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index fc6a9ba0643..a3c4f945351 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -149,7 +149,7 @@
"%-.16s parancs a '%-.32s@%-.64s' felhasznalo szamara nem engedelyezett a '%-.64s' mezo eseten a '%-.64s' tablaban",
"Ervenytelen GRANT/REVOKE parancs. Kerem, nezze meg a kezikonyvben, milyen jogok lehetsegesek",
"A host vagy felhasznalo argumentuma tul hosszu a GRANT parancsban",
-"A '%-64s.%s' tabla nem letezik",
+"A '%-.64s.%s' tabla nem letezik",
"A '%-.32s' felhasznalo szamara a '%-.64s' host '%-.64s' tablajaban ez a parancs nem engedelyezett",
"A hasznalt parancs nem engedelyezett ebben a MySQL verzioban",
"Szintaktikai hiba",
@@ -221,3 +221,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index 4b434573390..39c9635cc91 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -147,7 +147,7 @@
"Comando %-.16s negato per l'utente: '%-.32s@%-.64s' sulla colonna '%-.64s' della tabella '%-.64s'",
"Comando GRANT/REVOKE illegale. Prego consultare il manuale per sapere quali privilegi possono essere usati.",
"L'argomento host o utente per la GRANT e` troppo lungo",
-"La tabella '%-64s.%s' non esiste",
+"La tabella '%-.64s.%s' non esiste",
"GRANT non definita per l'utente '%-.32s' dalla macchina '%-.64s' sulla tabella '%-.64s'",
"Il comando utilizzato non e` supportato in questa versione di MySQL",
"Errore di sintassi nella query SQL",
@@ -219,3 +219,21 @@
"Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint)",
"Impossibile aggiungere la riga: un vincolo d'integrita' referenziale non e' soddisfatto",
"Impossibile cancellare la riga: un vincolo d'integrita' referenziale non e' soddisfatto",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index dc2299e4336..f146f03e687 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -149,7 +149,7 @@
"¥³¥Þ¥ó¥É %-.16s ¤Ï ¥æ¡¼¥¶¡¼ '%-.32s@%-.64s'\n ¥«¥é¥à '%-.64s' ¥Æ¡¼¥Ö¥ë '%-.64s' ¤ËÂФ·¤Æµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -221,3 +221,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index 79bf767a3c8..c3ab3d5d680 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -147,7 +147,7 @@
"'%-.16s' ¸í·ÉÀº ´ÙÀ½ »ç¿ëÀÚ¿¡°Ô °ÅºÎµÇ¾ú½À´Ï´Ù. : '%-.32s@%-.64s' for Ä®·³ '%-.64s' in Å×À̺í '%-.64s'",
"À߸øµÈ GRANT/REVOKE ¸í·É. ¾î¶² ±Ç¸®¿Í ½ÂÀÎÀÌ »ç¿ëµÇ¾î Áú ¼ö ÀÖ´ÂÁö ¸Þ´º¾óÀ» º¸½Ã¿À.",
"½ÂÀÎ(GRANT)À» À§ÇÏ¿© »ç¿ëÇÑ »ç¿ëÀÚ³ª È£½ºÆ®ÀÇ °ªµéÀÌ ³Ê¹« ±é´Ï´Ù.",
-"Å×À̺í '%-64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.",
+"Å×À̺í '%-.64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.",
"»ç¿ëÀÚ '%-.32s'(È£½ºÆ® '%-.64s')´Â Å×À̺í '%-.64s'¸¦ »ç¿ëÇϱâ À§ÇÏ¿© Á¤ÀÇµÈ ½ÂÀÎÀº ¾ø½À´Ï´Ù. ",
"»ç¿ëµÈ ¸í·ÉÀº ÇöÀçÀÇ MySQL ¹öÁ¯¿¡¼­´Â ÀÌ¿ëµÇÁö ¾Ê½À´Ï´Ù.",
"SQL ±¸¹®¿¡ ¿À·ù°¡ ÀÖ½À´Ï´Ù.",
@@ -219,3 +219,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index a583a541b71..a0191ba86d7 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -149,7 +149,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -221,3 +221,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index 85fa1f04f63..8d87c00e1b3 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -149,7 +149,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -221,3 +221,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index af484b4c850..def94b8795a 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -151,7 +151,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -223,3 +223,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index d1d9bbc5681..9c3bf3b32a1 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -219,3 +219,21 @@
"Não pode acrescentar uma restrição de chave estrangeira",
"Não pode acrescentar uma linha filha: uma restrição de chave estrangeira falhou",
"Não pode apagar uma linha pai: uma restrição de chave estrangeira falhou",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index e8927777b8a..fd12a1f3a64 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -223,3 +223,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index 5c94f2ee31b..dfe3b4a2f92 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -222,3 +222,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"ïÛÉÂËÁ ÓÏÅÄÉÎÅÎÉÑ Ó master: %-.128s",
+"ïÛÉÂËÁ ×Ù×ÏÌÎÅÎÉÑ ÚÁÐÒÏÓÁ ÎÁ master: %-.128s",
+"ïÛÉÂËÁ ×ÙÐÏÌÎÅÎÉÑ ËÏÍÁÎÄÙ %s: %-.128s",
+"îÅÐÒÁ×ÉÌØÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ %s É %s",
+"éÓÐÏÌØÚÕÅÍÙÅ SELECT-×ÙÒÁÖÅÎÉÑ ÉÍÅÀÔ ÒÁÚÎÙÅ ËÏÌÉÞÅÓÔ×Á ÓÔÏÌÂÃÏ×",
+"îÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÚÁÐÒÏÓ ÉÚ-ÚÁ ËÏÎÆÌÉËÔÎÏÊ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ",
+"ïÄÎÏ×ÒÅÍÅÎÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ transactional É non-transactional ÔÁÂÌÉà ÏÔËÌÀÞÅÎÏ",
+"ïÐÃÉÑ '%s' ÉÓÐÏÌØÚÏ×ÁÎÁ Ä×ÁÖÄÙ",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index 3f96880bda1..8e9433396fc 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -155,7 +155,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -227,3 +227,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index c718ac93fc4..57314579c63 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -148,7 +148,7 @@
"%-.16s comando negado para usuario: '%-.32s@%-.64s' para columna '%-.64s' en la tabla '%-.64s'",
"Ilegal comando GRANT/REVOKE. Por favor consulte el manual para cuales permisos pueden ser usados.",
"El argumento para servidor o usuario para GRANT es demasiado grande",
-"Tabla '%-64s.%s' no existe",
+"Tabla '%-.64s.%s' no existe",
"No existe tal permiso definido para usuario '%-.32s' en el servidor '%-.64s' en la tabla '%-.64s'",
"El comando usado no es permitido con esta versión de MySQL",
"Algo está equivocado en su sintax",
@@ -220,3 +220,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error de coneccion a master: %-128s",
+"Error executando el query en master: %-128%",
+"Error de %s: %-128%",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/swedish/errmsg.OLD b/sql/share/swedish/errmsg.OLD
index cc54e051e63..3dd14c8b613 100644
--- a/sql/share/swedish/errmsg.OLD
+++ b/sql/share/swedish/errmsg.OLD
@@ -205,11 +205,17 @@
"Kunde inte initializera replications-strukturerna. Kontrollera privilegerna för 'master.info'",
"Kunde inte starta en tråd för replikering",
"Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar",
-"Du kan endast använda konstant-uttryck med SET",
-"Lock wait timeout exceeded",
-"The total number of locks exceeds the lock table size",
-"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
-"DROP DATABASE not allowed while thread is holding global read lock",
-"CREATE DATABASE not allowed while thread is holding global read lock",
-#ER_WRONG_ARGUMENTS
+"Man kan endast använda konstant-uttryck med SET",
+"Fick inte ett lås i tid",
+"Antal lås överskrider antalet reserverade lås",
+"Updaterings-lås kan inte göras när man använder READ UNCOMMITTED",
+"DROP DATABASE är inte tillåtet när man har ett globalt läs-lås",
+"CREATE DATABASE är inte tillåtet när man har ett globalt läs-lås",
"Felaktiga argument till %s",
+"%-.32s@%-.64s har inte rättigheter att skapa nya användare",
+"Fick fel vid anslutning till master: %-.128s",
+"Fick fel vid utförande av command på mastern: %-.128s",
+"Fick fel vid utförande av %s: %-.128s",
+"Felaktig använding av %s and %s",
+"SELECT kommandona har olika antal kolumner"
+"Kan inte utföra kommandot emedan du har ett READ lås",
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index ce6bb0e80f0..7a4d17cfdfa 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -61,7 +61,7 @@
"Kommandot har både sum functions och enkla funktioner",
"Antalet kolumner motsvarar inte antalet värden",
"Kolumn namn '%-.64s' är för långt",
-"Kolumn namn '%-64s finns flera gånger",
+"Kolumn namn '%-.64s finns flera gånger",
"Nyckel namn '%-.64s' finns flera gånger",
"Dubbel nyckel '%-.64s' för nyckel: %d",
"Felaktigt kolumn typ för kolumn: '%-.64s'",
@@ -147,7 +147,7 @@
"%-.16s ej tillåtet för '%-.32s@%-.64s'\n för kolumn '%-.64s' i tabell '%-.64s'",
"Felaktigt GRANT privilegium använt",
"Felaktigt maskinnamn eller användarnamn använt med GRANT",
-"Det finns ingen tabell som heter '%-64s.%s'"
+"Det finns ingen tabell som heter '%-.64s.%s'"
"Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s' för tabell '%-.64s'",
"Du kan inte använda detta kommando med denna MySQL version",
"Du har något fel i din syntax",
@@ -219,3 +219,21 @@
"Kan inte lägga till 'FOREIGN KEY constraint'",
"FOREIGN KEY konflikt: Kan inte skriva barn",
"FOREIGN KEY konflikt: Kan inte radera fader",
+"Fick fel vid anslutning till master: %-.128s",
+"Fick fel vid utförande av command på mastern: %-.128s",
+"Fick fel vid utförande av %s: %-.128s",
+"Felaktig använding av %s and %s",
+"SELECT kommandona har olika antal kolumner"
+"Kan inte utföra kommandot emedan du har ett READ lås",
+"Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat",
+"Option '%s' användes två gånger",
+"Användare '%-.64s' har överskridit '%s' (nuvarande värde: %ld)",
+"Du har inte privlegiet '%-.128s' som behövs för denna operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt
index b167ebd5f3d..d8d9349b56a 100644
--- a/sql/share/ukrainian/errmsg.txt
+++ b/sql/share/ukrainian/errmsg.txt
@@ -224,3 +224,21 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s',"
diff --git a/sql/slave.cc b/sql/slave.cc
index adbf3c106cc..7871f536320 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -20,48 +20,148 @@
#include <myisam.h>
#include "mini_client.h"
#include "slave.h"
+#include "sql_repl.h"
+#include "repl_failsafe.h"
#include <thr_alarm.h>
#include <my_dir.h>
+#include <assert.h>
-#define RPL_LOG_NAME (glob_mi.log_file_name[0] ? glob_mi.log_file_name :\
- "FIRST")
-
-volatile bool slave_running = 0;
-pthread_t slave_real_id;
-MASTER_INFO glob_mi;
-MY_BITMAP slave_error_mask;
bool use_slave_mask = 0;
+MY_BITMAP slave_error_mask;
+
+typedef bool (*CHECK_KILLED_FUNC)(THD*,void*);
+
+volatile bool slave_sql_running = 0, slave_io_running = 0;
+char* slave_load_tmpdir = 0;
+MASTER_INFO main_mi;
+MASTER_INFO* active_mi;
+volatile int active_mi_in_use = 0;
HASH replicate_do_table, replicate_ignore_table;
DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
bool do_table_inited = 0, ignore_table_inited = 0;
bool wild_do_table_inited = 0, wild_ignore_table_inited = 0;
bool table_rules_on = 0;
-uint32 slave_skip_counter = 0;
static TABLE* save_temporary_tables = 0;
-THD* slave_thd = 0;
-// when slave thread exits, we need to remember the temporary tables so we
-// can re-use them on slave start
+/* TODO: fix variables to access ulonglong values and make it ulonglong */
+ulong relay_log_space_limit = 0;
+
+/*
+ When slave thread exits, we need to remember the temporary tables so we
+ can re-use them on slave start.
+
+ TODO: move the vars below under MASTER_INFO
+*/
-static int last_slave_errno = 0;
-static char last_slave_error[1024] = "";
-#ifndef DBUG_OFF
int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
-static int events_till_disconnect = -1, events_till_abort = -1;
+static int events_till_disconnect = -1;
+int events_till_abort = -1;
static int stuck_count = 0;
-#endif
-inline void skip_load_data_infile(NET* net);
-inline bool slave_killed(THD* thd);
-static int init_slave_thread(THD* thd);
+typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
+
+void skip_load_data_infile(NET* net);
+static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev);
+static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev);
+static int queue_old_event(MASTER_INFO* mi, const char* buf,
+ uint event_len);
+static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli);
+static inline bool io_slave_killed(THD* thd,MASTER_INFO* mi);
+static inline bool sql_slave_killed(THD* thd,RELAY_LOG_INFO* rli);
+static int count_relay_log_space(RELAY_LOG_INFO* rli);
+static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
bool suppress_warnings);
-static int safe_sleep(THD* thd, int sec);
-static int request_table_dump(MYSQL* mysql, char* db, char* table);
+static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool reconnect, bool suppress_warnings);
+static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
+ void* thread_killed_arg);
+static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
static int create_table_from_dump(THD* thd, NET* net, const char* db,
const char* table_name);
-inline char* rewrite_db(char* db);
-static int check_expected_error(THD* thd, int expected_error);
+static int check_master_version(MYSQL* mysql, MASTER_INFO* mi);
+
+char* rewrite_db(char* db);
+
+void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse)
+{
+ bool set_io = mi->slave_running, set_sql = mi->rli.slave_running;
+ if (inverse)
+ {
+ /*
+ This makes me think of the Russian idiom "I am not I, and this is
+ not my horse", which is used to deny reponsibility for
+ one's actions.
+ */
+ set_io = !set_io;
+ set_sql = !set_sql;
+ }
+ register int tmp_mask=0;
+ if (set_io)
+ tmp_mask |= SLAVE_IO;
+ if (set_sql)
+ tmp_mask |= SLAVE_SQL;
+ *mask = tmp_mask;
+}
+
+void lock_slave_threads(MASTER_INFO* mi)
+{
+ //TODO: see if we can do this without dual mutex
+ pthread_mutex_lock(&mi->run_lock);
+ pthread_mutex_lock(&mi->rli.run_lock);
+}
+
+void unlock_slave_threads(MASTER_INFO* mi)
+{
+ //TODO: see if we can do this without dual mutex
+ pthread_mutex_unlock(&mi->rli.run_lock);
+ pthread_mutex_unlock(&mi->run_lock);
+}
+
+int init_slave()
+{
+ DBUG_ENTER("init_slave");
+ // TODO (multi-master): replace this with list initialization
+ active_mi = &main_mi;
+
+ // TODO: the code below is a copy-paste mess - clean it up
+ /*
+ make sure slave thread gets started if server_id is set,
+ valid master.info is present, and master_host has not been specified
+ */
+ if (server_id && !master_host)
+ {
+ /*
+ TODO: re-write this to interate through the list of files
+ for multi-master
+ */
+ char fname[FN_REFLEN+128];
+ MY_STAT stat_area;
+ fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
+ if (my_stat(fname, &stat_area, MYF(0)) &&
+ !init_master_info(active_mi,master_info_file,relay_log_info_file))
+ master_host = active_mi->host;
+ }
+ // slave thread
+ if (master_host)
+ {
+ if (!opt_skip_slave_start)
+ {
+ if (start_slave_threads(1 /* need mutex */,
+ 0 /* no wait for start*/,
+ active_mi,
+ master_info_file,
+ relay_log_info_file,
+ SLAVE_IO | SLAVE_SQL))
+ sql_print_error("Warning: Can't create threads to handle slave");
+ }
+ else if (init_master_info(active_mi, master_info_file,
+ relay_log_info_file))
+ sql_print_error("Warning: failed to initialized master info");
+ }
+ DBUG_RETURN(0);
+}
+
static void free_table_ent(TABLE_RULE_ENT* e)
{
@@ -75,10 +175,94 @@ static byte* get_table_key(TABLE_RULE_ENT* e, uint* len,
return (byte*)e->db;
}
+// TODO: check proper initialization of master_log_name/master_log_pos
+
+int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
+ ulonglong pos, bool need_data_lock,
+ const char** errmsg)
+{
+ DBUG_ENTER("init_relay_log_pos");
+
+ *errmsg=0;
+ if (rli->log_pos_current)
+ DBUG_RETURN(0);
+ pthread_mutex_t *log_lock=rli->relay_log.get_log_lock();
+ pthread_mutex_lock(log_lock);
+ if (need_data_lock)
+ pthread_mutex_lock(&rli->data_lock);
+
+ if (rli->cur_log_fd >= 0)
+ {
+ end_io_cache(&rli->cache_buf);
+ my_close(rli->cur_log_fd, MYF(MY_WME));
+ rli->cur_log_fd = -1;
+ }
+
+ if (!log)
+ log = rli->relay_log_name; // already inited
+ if (!pos)
+ pos = rli->relay_log_pos; // already inited
+ else
+ rli->relay_log_pos = pos;
+
+ /*
+ Test to see if the previous run was with the skip of purging
+ If yes, we do not purge when we restart
+ */
+ if (rli->relay_log.find_first_log(&rli->linfo,""))
+ {
+ *errmsg="Could not find first log during relay log initialization";
+ goto err;
+ }
+ if (strcmp(log,rli->linfo.log_file_name))
+ rli->skip_log_purge=1;
+
+ if (rli->relay_log.find_first_log(&rli->linfo,log))
+ {
+ *errmsg="Could not find target log during relay log initialization";
+ goto err;
+ }
+ strmake(rli->relay_log_name,rli->linfo.log_file_name,
+ sizeof(rli->relay_log_name)-1);
+ // to make end_io_cache(&rli->cache_buf) safe in all cases
+ if (!rli->inited)
+ bzero((char*) &rli->cache_buf, sizeof(IO_CACHE));
+ if (rli->relay_log.is_active(rli->linfo.log_file_name))
+ {
+ if (my_b_tell((rli->cur_log=rli->relay_log.get_log_file())) == 0 &&
+ check_binlog_magic(rli->cur_log,errmsg))
+ goto err;
+ rli->cur_log_old_open_count=rli->relay_log.get_open_count();
+ }
+ else
+ {
+ if (rli->inited)
+ end_io_cache(&rli->cache_buf);
+ if (rli->cur_log_fd >= 0)
+ my_close(rli->cur_log_fd,MYF(MY_WME));
+ if ((rli->cur_log_fd=open_binlog(&rli->cache_buf,
+ rli->linfo.log_file_name,errmsg)) < 0)
+ goto err;
+ rli->cur_log = &rli->cache_buf;
+ }
+ if (pos > BIN_LOG_HEADER_SIZE)
+ my_b_seek(rli->cur_log,(off_t)pos);
+ rli->log_pos_current=1;
+
+err:
+ pthread_cond_broadcast(&rli->data_cond);
+ if (need_data_lock)
+ pthread_mutex_unlock(&rli->data_lock);
+ pthread_mutex_unlock(log_lock);
+ DBUG_RETURN ((*errmsg) ? 1 : 0);
+}
+
/* called from get_options() in mysqld.cc on start-up */
-void init_slave_skip_errors(char* arg)
+
+void init_slave_skip_errors(const char* arg)
{
- char* p;
+ const char *p;
+ my_bool last_was_digit = 0;
if (bitmap_init(&slave_error_mask,MAX_SLAVE_ERROR,0))
{
fprintf(stderr, "Badly out of memory, please check your system status\n");
@@ -104,6 +288,239 @@ void init_slave_skip_errors(char* arg)
}
}
+
+/*
+ We assume we have a run lock on rli and that both slave thread
+ are not running
+*/
+
+int purge_relay_logs(RELAY_LOG_INFO* rli, bool just_reset, const char** errmsg)
+{
+ DBUG_ENTER("purge_relay_logs");
+ if (!rli->inited)
+ DBUG_RETURN(0); /* successfully do nothing */
+ int error=0;
+
+ DBUG_ASSERT(rli->slave_running == 0);
+ DBUG_ASSERT(rli->mi->slave_running == 0);
+
+ rli->slave_skip_counter=0;
+ pthread_mutex_lock(&rli->data_lock);
+ rli->pending=0;
+ rli->master_log_name[0]=0;
+ rli->master_log_pos=0; // 0 means uninitialized
+ if (rli->relay_log.reset_logs(rli->sql_thd) ||
+ rli->relay_log.find_first_log(&rli->linfo,""))
+ {
+ *errmsg = "Failed during log reset";
+ error=1;
+ goto err;
+ }
+ strmake(rli->relay_log_name,rli->linfo.log_file_name,
+ sizeof(rli->relay_log_name)-1);
+ // Just first log with magic number and nothing else
+ rli->log_space_total= BIN_LOG_HEADER_SIZE;
+ rli->relay_log_pos= BIN_LOG_HEADER_SIZE;
+ rli->relay_log.reset_bytes_written();
+ rli->log_pos_current=0;
+ if (!just_reset)
+ error = init_relay_log_pos(rli,0,0,0 /* do not need data lock */,errmsg);
+
+err:
+#ifndef DBUG_OFF
+ char buf[22];
+#endif
+ DBUG_PRINT("info",("log_space_total: %s",llstr(rli->log_space_total,buf)));
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(error);
+}
+
+int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
+{
+ if (!mi->inited)
+ return 0; /* successfully do nothing */
+ int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
+ pthread_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
+ pthread_mutex_t *sql_cond_lock,*io_cond_lock;
+
+ sql_cond_lock=sql_lock;
+ io_cond_lock=io_lock;
+
+ if (skip_lock)
+ {
+ sql_lock = io_lock = 0;
+ }
+ if ((thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) && mi->slave_running)
+ {
+ mi->abort_slave=1;
+ if ((error=terminate_slave_thread(mi->io_thd,io_lock,
+ io_cond_lock,
+ &mi->stop_cond,
+ &mi->slave_running)) &&
+ !force_all)
+ return error;
+ }
+ if ((thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) && mi->rli.slave_running)
+ {
+ DBUG_ASSERT(mi->rli.sql_thd != 0) ;
+ mi->rli.abort_slave=1;
+ if ((error=terminate_slave_thread(mi->rli.sql_thd,sql_lock,
+ sql_cond_lock,
+ &mi->rli.stop_cond,
+ &mi->rli.slave_running)) &&
+ !force_all)
+ return error;
+ }
+ return 0;
+}
+
+int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t* term_cond,
+ volatile bool* slave_running)
+{
+ if (term_lock)
+ {
+ pthread_mutex_lock(term_lock);
+ if (!*slave_running)
+ {
+ pthread_mutex_unlock(term_lock);
+ return ER_SLAVE_NOT_RUNNING;
+ }
+ }
+ DBUG_ASSERT(thd != 0);
+ /*
+ Is is criticate to test if the slave is running. Otherwise, we might
+ be referening freed memory trying to kick it
+ */
+ THD_CHECK_SENTRY(thd);
+ if (*slave_running)
+ {
+ KICK_SLAVE(thd);
+ }
+ while (*slave_running)
+ {
+ /*
+ There is a small chance that slave thread might miss the first
+ alarm. To protect againts it, resend the signal until it reacts
+ */
+ struct timespec abstime;
+ set_timespec(abstime,2);
+ pthread_cond_timedwait(term_cond, cond_lock, &abstime);
+ if (*slave_running)
+ {
+ KICK_SLAVE(thd);
+ }
+ }
+ if (term_lock)
+ pthread_mutex_unlock(term_lock);
+ return 0;
+}
+
+int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock,
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t* start_cond,
+ volatile bool* slave_running,
+ MASTER_INFO* mi)
+{
+ pthread_t th;
+ DBUG_ASSERT(mi->inited);
+ if (start_lock)
+ pthread_mutex_lock(start_lock);
+ if (!server_id)
+ {
+ if (start_cond)
+ pthread_cond_broadcast(start_cond);
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ sql_print_error("Server id not set, will not start slave");
+ return ER_BAD_SLAVE;
+ }
+
+ if (*slave_running)
+ {
+ if (start_cond)
+ pthread_cond_broadcast(start_cond);
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ return ER_SLAVE_MUST_STOP;
+ }
+ if (pthread_create(&th, &connection_attrib, h_func, (void*)mi))
+ {
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ return ER_SLAVE_THREAD;
+ }
+ if (start_cond && cond_lock)
+ {
+ THD* thd = current_thd;
+ while (!*slave_running)
+ {
+ const char* old_msg = thd->enter_cond(start_cond,cond_lock,
+ "Waiting for slave thread to start");
+ pthread_cond_wait(start_cond,cond_lock);
+ thd->exit_cond(old_msg);
+ /*
+ TODO: in a very rare case of init_slave_thread failing, it is
+ possible that we can get stuck here since slave_running will not
+ be set. We need to change slave_running to int and have -1 as
+ error code.
+ */
+ if (thd->killed)
+ {
+ pthread_mutex_unlock(cond_lock);
+ return ER_SERVER_SHUTDOWN;
+ }
+ }
+ }
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ return 0;
+}
+
+
+/*
+ SLAVE_FORCE_ALL is not implemented here on purpose since it does not make
+ sense to do that for starting a slave - we always care if it actually
+ started the threads that were not previously running
+*/
+
+int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
+ MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname, int thread_mask)
+{
+ pthread_mutex_t *lock_io=0,*lock_sql=0,*lock_cond_io=0,*lock_cond_sql=0;
+ pthread_cond_t* cond_io=0,*cond_sql=0;
+ int error=0;
+ DBUG_ENTER("start_slave_threads");
+
+ if (need_slave_mutex)
+ {
+ lock_io = &mi->run_lock;
+ lock_sql = &mi->rli.run_lock;
+ }
+ if (wait_for_start)
+ {
+ cond_io = &mi->start_cond;
+ cond_sql = &mi->rli.start_cond;
+ lock_cond_io = &mi->run_lock;
+ lock_cond_sql = &mi->rli.run_lock;
+ }
+ if (init_master_info(mi,master_info_fname,slave_info_fname))
+ DBUG_RETURN(ER_MASTER_INFO);
+
+ if (thread_mask & SLAVE_IO)
+ error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
+ cond_io,&mi->slave_running,
+ mi);
+ if (!error && (thread_mask & SLAVE_SQL))
+ error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
+ cond_sql,
+ &mi->rli.slave_running,mi);
+ DBUG_RETURN(error);
+}
+
+
void init_table_rule_hash(HASH* h, bool* h_inited)
{
hash_init(h, TABLE_RULE_HASH_SIZE,0,0,
@@ -124,11 +541,11 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
uint i;
const char* key_end = key + len;
- for(i = 0; i < a->elements; i++)
+ for (i = 0; i < a->elements; i++)
{
TABLE_RULE_ENT* e ;
get_dynamic(a, (gptr)&e, i);
- if(!wild_case_compare(key, key_end, (const char*)e->db,
+ if (!wild_case_compare(key, key_end, (const char*)e->db,
(const char*)(e->db + e->key_len),'\\'))
return e;
}
@@ -152,7 +569,7 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
if (hash_search(&replicate_do_table, (byte*) hash_key, len))
return 1;
}
- if (ignore_table_inited) // if there are any do's
+ if (ignore_table_inited) // if there are any ignores
{
if (hash_search(&replicate_ignore_table, (byte*) hash_key, len))
return 0;
@@ -165,9 +582,10 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
return 0;
}
- // if no explicit rule found
- // and there was a do list, do not replicate. If there was
- // no do list, go ahead
+ /*
+ If no explicit rule found and there was a do list, do not replicate.
+ If there was no do list, go ahead
+ */
return !do_table_inited && !wild_do_table_inited;
}
@@ -175,12 +593,12 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
int add_table_rule(HASH* h, const char* table_spec)
{
const char* dot = strchr(table_spec, '.');
- if(!dot) return 1;
+ if (!dot) return 1;
// len is always > 0 because we know the there exists a '.'
uint len = (uint)strlen(table_spec);
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
+ len, MYF(MY_WME));
- if(!e) return 1;
+ if (!e) return 1;
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
e->tbl_name = e->db + (dot - table_spec) + 1;
e->key_len = len;
@@ -192,11 +610,11 @@ int add_table_rule(HASH* h, const char* table_spec)
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
{
const char* dot = strchr(table_spec, '.');
- if(!dot) return 1;
+ if (!dot) return 1;
uint len = (uint)strlen(table_spec);
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
+ len, MYF(MY_WME));
- if(!e) return 1;
+ if (!e) return 1;
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
e->tbl_name = e->db + (dot - table_spec) + 1;
e->key_len = len;
@@ -208,7 +626,7 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
static void free_string_array(DYNAMIC_ARRAY *a)
{
uint i;
- for(i = 0; i < a->elements; i++)
+ for (i = 0; i < a->elements; i++)
{
char* p;
get_dynamic(a, (gptr) &p, i);
@@ -217,100 +635,122 @@ static void free_string_array(DYNAMIC_ARRAY *a)
delete_dynamic(a);
}
+static int end_slave_on_walk(MASTER_INFO* mi, gptr /*unused*/)
+{
+ end_master_info(mi);
+ return 0;
+}
+
void end_slave()
{
- pthread_mutex_lock(&LOCK_slave);
- if (slave_running)
- {
- abort_slave = 1;
- thr_alarm_kill(slave_real_id);
-#ifdef SIGNAL_WITH_VIO_CLOSE
- slave_thd->close_active_vio();
-#endif
- while (slave_running)
- pthread_cond_wait(&COND_slave_stopped, &LOCK_slave);
- }
- pthread_mutex_unlock(&LOCK_slave);
-
- end_master_info(&glob_mi);
- if(do_table_inited)
+ /*
+ TODO: replace the line below with
+ list_walk(&master_list, (list_walk_action)end_slave_on_walk,0);
+ once multi-master code is ready.
+ */
+ terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
+ end_master_info(active_mi);
+ if (do_table_inited)
hash_free(&replicate_do_table);
- if(ignore_table_inited)
+ if (ignore_table_inited)
hash_free(&replicate_ignore_table);
- if(wild_do_table_inited)
+ if (wild_do_table_inited)
free_string_array(&replicate_wild_do_table);
- if(wild_ignore_table_inited)
+ if (wild_ignore_table_inited)
free_string_array(&replicate_wild_ignore_table);
}
-inline bool slave_killed(THD* thd)
+static bool io_slave_killed(THD* thd, MASTER_INFO* mi)
+{
+ DBUG_ASSERT(mi->io_thd == thd);
+ DBUG_ASSERT(mi->slave_running == 1); // tracking buffer overrun
+ return mi->abort_slave || abort_loop || thd->killed;
+}
+
+static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli)
{
- return abort_slave || abort_loop || thd->killed;
+ DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
+ return rli->abort_slave || abort_loop || thd->killed;
}
-inline void skip_load_data_infile(NET* net)
+void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...)
+{
+ va_list args;
+ va_start(args,msg);
+ my_vsnprintf(rli->last_slave_error,
+ sizeof(rli->last_slave_error), msg, args);
+ sql_print_error("Slave: %s, error_code=%d", rli->last_slave_error,
+ err_code);
+ rli->last_slave_errno = err_code;
+}
+
+void skip_load_data_infile(NET* net)
{
(void)my_net_write(net, "\xfb/dev/null", 10);
(void)net_flush(net);
- (void)my_net_read(net); // discard response
- send_ok(net); // the master expects it
+ (void)my_net_read(net); // discard response
+ send_ok(net); // the master expects it
}
-inline char* rewrite_db(char* db)
+char* rewrite_db(char* db)
{
- if(replicate_rewrite_db.is_empty() || !db) return db;
+ if (replicate_rewrite_db.is_empty() || !db)
+ return db;
I_List_iterator<i_string_pair> it(replicate_rewrite_db);
i_string_pair* tmp;
- while((tmp=it++))
- {
- if(!strcmp(tmp->key, db))
- return tmp->val;
- }
-
+ while ((tmp=it++))
+ {
+ if (!strcmp(tmp->key, db))
+ return tmp->val;
+ }
return db;
}
+
int db_ok(const char* db, I_List<i_string> &do_list,
I_List<i_string> &ignore_list )
{
- if(do_list.is_empty() && ignore_list.is_empty())
+ if (do_list.is_empty() && ignore_list.is_empty())
return 1; // ok to replicate if the user puts no constraints
- // if the user has specified restrictions on which databases to replicate
- // and db was not selected, do not replicate
- if(!db)
+ /*
+ If the user has specified restrictions on which databases to replicate
+ and db was not selected, do not replicate.
+ */
+ if (!db)
return 0;
- if(!do_list.is_empty()) // if the do's are not empty
- {
- I_List_iterator<i_string> it(do_list);
- i_string* tmp;
+ if (!do_list.is_empty()) // if the do's are not empty
+ {
+ I_List_iterator<i_string> it(do_list);
+ i_string* tmp;
- while((tmp=it++))
- {
- if(!strcmp(tmp->ptr, db))
- return 1; // match
- }
- return 0;
+ while ((tmp=it++))
+ {
+ if (!strcmp(tmp->ptr, db))
+ return 1; // match
}
+ return 0;
+ }
else // there are some elements in the don't, otherwise we cannot get here
- {
- I_List_iterator<i_string> it(ignore_list);
- i_string* tmp;
+ {
+ I_List_iterator<i_string> it(ignore_list);
+ i_string* tmp;
- while((tmp=it++))
- {
- if(!strcmp(tmp->ptr, db))
- return 0; // match
- }
-
- return 1;
+ while ((tmp=it++))
+ {
+ if (!strcmp(tmp->ptr, db))
+ return 0; // match
}
+
+ return 1;
+ }
}
-static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
- char* default_val)
+static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+ const char *default_val)
{
uint length;
if ((length=my_b_gets(f,var, max_size)))
@@ -320,10 +760,12 @@ static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
*last_p = 0; // if we stopped on newline, kill it
else
{
- // if we truncated a line or stopped on last char, remove all chars
- // up to and including newline
+ /*
+ If we truncated a line or stopped on last char, remove all chars
+ up to and including newline.
+ */
int c;
- while( ((c=my_b_get(f)) != '\n' && c != my_b_EOF));
+ while (((c=my_b_get(f)) != '\n' && c != my_b_EOF));
}
return 0;
}
@@ -344,7 +786,7 @@ static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
*var = atoi(buf);
return 0;
}
- else if(default_val)
+ else if (default_val)
{
*var = default_val;
return 0;
@@ -352,16 +794,65 @@ static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
return 1;
}
+static int check_master_version(MYSQL* mysql, MASTER_INFO* mi)
+{
+ MYSQL_RES* res;
+ MYSQL_ROW row;
+ const char* version;
+ const char* errmsg = 0;
+
+ if (mc_mysql_query(mysql, "SELECT VERSION()", 0)
+ || !(res = mc_mysql_store_result(mysql)))
+ {
+ sql_print_error("Error checking master version: %s",
+ mc_mysql_error(mysql));
+ return 1;
+ }
+ if (!(row = mc_mysql_fetch_row(res)))
+ {
+ errmsg = "Master returned no rows for SELECT VERSION()";
+ goto err;
+ }
+ if (!(version = row[0]))
+ {
+ errmsg = "Master reported NULL for the version";
+ goto err;
+ }
+
+ switch (*version) {
+ case '3':
+ mi->old_format = 1;
+ break;
+ case '4':
+ case '5':
+ mi->old_format = 0;
+ break;
+ default:
+ errmsg = "Master reported unrecognized MySQL version";
+ goto err;
+ }
+err:
+ if (res)
+ mc_mysql_free_result(res);
+ if (errmsg)
+ {
+ sql_print_error(errmsg);
+ return 1;
+ }
+ return 0;
+}
+
static int create_table_from_dump(THD* thd, NET* net, const char* db,
const char* table_name)
{
- uint packet_len = my_net_read(net); // read create table statement
+ ulong packet_len = my_net_read(net); // read create table statement
Vio* save_vio;
HA_CHECK_OPT check_opt;
TABLE_LIST tables;
int error= 1;
handler *file;
+ uint save_options;
if (packet_len == packet_error)
{
@@ -387,12 +878,17 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
thd->current_tablenr = 0;
thd->query_error = 0;
thd->net.no_send_ok = 1;
+
+ /* we do not want to log create table statement */
+ save_options = thd->options;
+ thd->options &= ~(ulong) OPTION_BIN_LOG;
thd->proc_info = "Creating table from master dump";
// save old db in case we are creating in a different database
char* save_db = thd->db;
- thd->db = thd->last_nx_db;
+ thd->db = (char*)db;
mysql_parse(thd, thd->query, packet_len); // run create table
thd->db = save_db; // leave things the way the were before
+ thd->options = save_options;
if (thd->query_error)
goto err; // mysql_parse took care of the error send
@@ -420,12 +916,13 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
}
check_opt.init();
- check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM;
- check_opt.quick = 1;
+ check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
thd->proc_info = "Rebuilding the index on master dump table";
- // we do not want repair() to spam us with messages
- // just send them to the error log, and report the failure in case of
- // problems
+ /*
+ We do not want repair() to spam us with messages
+ just send them to the error log, and report the failure in case of
+ problems.
+ */
save_vio = thd->net.vio;
thd->net.vio = 0;
error=file->repair(thd,&check_opt) != 0;
@@ -439,57 +936,62 @@ err:
return error;
}
-int fetch_nx_table(THD* thd, MASTER_INFO* mi)
+int fetch_master_table(THD* thd, const char* db_name, const char* table_name,
+ MASTER_INFO* mi, MYSQL* mysql)
{
- MYSQL* mysql = mc_mysql_init(NULL);
int error = 1;
- int nx_errno = 0;
- if (!mysql)
- {
- sql_print_error("fetch_nx_table: Error in mysql_init()");
- nx_errno = ER_GET_ERRNO;
+ int fetch_errno = 0;
+ bool called_connected = (mysql != NULL);
+ if (!called_connected && !(mysql = mc_mysql_init(NULL)))
+ {
+ sql_print_error("fetch_master_table: Error in mysql_init()");
+ fetch_errno = ER_GET_ERRNO;
goto err;
}
- if (!mi->host || !*mi->host)
+ if (!called_connected)
{
- nx_errno = ER_BAD_HOST_ERROR;
- goto err;
+ if (connect_to_master(thd, mysql, mi))
+ {
+ sql_print_error("Could not connect to master while fetching table\
+ '%-64s.%-64s'", db_name, table_name);
+ fetch_errno = ER_CONNECT_TO_MASTER;
+ goto err;
+ }
}
-
- safe_connect(thd, mysql, mi);
- if (slave_killed(thd))
+ if (thd->killed)
goto err;
- if (request_table_dump(mysql, thd->last_nx_db, thd->last_nx_table))
+ if (request_table_dump(mysql, db_name, table_name))
{
- nx_errno = ER_GET_ERRNO;
- sql_print_error("fetch_nx_table: failed on table dump request ");
+ fetch_errno = ER_GET_ERRNO;
+ sql_print_error("fetch_master_table: failed on table dump request ");
goto err;
}
- if (create_table_from_dump(thd, &mysql->net, thd->last_nx_db,
- thd->last_nx_table))
- {
+ if (create_table_from_dump(thd, &mysql->net, db_name,
+ table_name))
+ {
// create_table_from_dump will have sent the error alread
- sql_print_error("fetch_nx_table: failed on create table ");
+ sql_print_error("fetch_master_table: failed on create table ");
goto err;
}
-
error = 0;
-
err:
- if (mysql)
+ if (mysql && !called_connected)
mc_mysql_close(mysql);
- if (nx_errno && thd->net.vio)
- send_error(&thd->net, nx_errno, "Error in fetch_nx_table");
+ if (fetch_errno && thd->net.vio)
+ send_error(&thd->net, fetch_errno, "Error in fetch_master_table");
thd->net.no_send_ok = 0; // Clear up garbage after create_table_from_dump
return error;
}
void end_master_info(MASTER_INFO* mi)
{
- if(mi->fd >= 0)
+ if (!mi->inited)
+ return;
+ end_relay_log_info(&mi->rli);
+ if (mi->fd >= 0)
{
end_io_cache(&mi->file);
(void)my_close(mi->fd, MYF(MY_WME));
@@ -498,41 +1000,236 @@ void end_master_info(MASTER_INFO* mi)
mi->inited = 0;
}
-int init_master_info(MASTER_INFO* mi)
+int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
{
- if (mi->inited)
- return 0;
- int fd,length,error;
+ DBUG_ENTER("init_relay_log_info");
MY_STAT stat_area;
char fname[FN_REFLEN+128];
- const char *msg;
- fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
+ int info_fd;
+ const char* msg = 0;
+ int error = 0;
+
+ if (rli->inited)
+ DBUG_RETURN(0);
+ fn_format(fname, info_fname, mysql_data_home, "", 4+32);
+ pthread_mutex_lock(&rli->data_lock);
+ info_fd = rli->info_fd;
+ rli->pending = 0;
+ rli->cur_log_fd = -1;
+ rli->slave_skip_counter=0;
+ rli->log_pos_current=0;
+ rli->abort_pos_wait=0;
+ rli->skip_log_purge=0;
+ rli->log_space_limit = relay_log_space_limit;
+ rli->log_space_total = 0;
+ // TODO: make this work with multi-master
+ if (!opt_relay_logname)
+ {
+ char tmp[FN_REFLEN];
+ /*
+ TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
+ */
+ strmake(tmp,glob_hostname,FN_REFLEN-5);
+ strmov(strcend(tmp,'.'),"-relay-bin");
+ opt_relay_logname=my_strdup(tmp,MYF(MY_WME));
+ }
+ rli->relay_log.set_index_file_name(opt_relaylog_index_name);
+ open_log(&rli->relay_log, glob_hostname, opt_relay_logname, "-relay-bin",
+ LOG_BIN, 1 /* read_append cache */,
+ 1 /* no auto events */);
+
+ /* if file does not exist */
+ if (!my_stat(fname, &stat_area, MYF(0)))
+ {
+ /*
+ If someone removed the file from underneath our feet, just close
+ the old descriptor and re-create the old file
+ */
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(MY_WME));
+ if ((info_fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
+ MYF(MY_WME)))
+ {
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(0));
+ rli->info_fd= -1;
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(1);
+ }
+ if (init_relay_log_pos(rli,"",BIN_LOG_HEADER_SIZE,0 /*no data mutex*/,
+ &msg))
+ goto err;
+ rli->master_log_pos = 0; // uninitialized
+ rli->info_fd = info_fd;
+ }
+ else // file exists
+ {
+ if (info_fd >= 0)
+ reinit_io_cache(&rli->info_file, READ_CACHE, 0L,0,0);
+ else if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(&rli->info_file, info_fd,
+ IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME)))
+ {
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(0));
+ rli->info_fd= -1;
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(1);
+ }
+
+ rli->info_fd = info_fd;
+ int relay_log_pos, master_log_pos;
+ if (init_strvar_from_file(rli->relay_log_name,
+ sizeof(rli->relay_log_name), &rli->info_file,
+ "") ||
+ init_intvar_from_file(&relay_log_pos,
+ &rli->info_file, BIN_LOG_HEADER_SIZE) ||
+ init_strvar_from_file(rli->master_log_name,
+ sizeof(rli->master_log_name), &rli->info_file,
+ "") ||
+ init_intvar_from_file(&master_log_pos, &rli->info_file, 0))
+ {
+ msg="Error reading slave log configuration";
+ goto err;
+ }
+ rli->relay_log_pos= relay_log_pos;
+ rli->master_log_pos= master_log_pos;
+
+ if (init_relay_log_pos(rli,0 /* log already inited */,
+ 0 /* pos already inited */,
+ 0 /* no data lock*/,
+ &msg))
+ goto err;
+ }
+ DBUG_ASSERT(rli->relay_log_pos >= BIN_LOG_HEADER_SIZE);
+ DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->relay_log_pos);
+ rli->inited = 1;
+ /*
+ Now change the cache from READ to WRITE - must do this
+ before flush_relay_log_info
+ */
+ reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1);
+ error=test(flush_relay_log_info(rli));
+ if (count_relay_log_space(rli))
+ {
+ msg="Error counting relay log space";
+ goto err;
+ }
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(error);
+
+err:
+ sql_print_error(msg);
+ end_io_cache(&rli->info_file);
+ my_close(info_fd, MYF(0));
+ rli->info_fd= -1;
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(1);
+}
+
+static inline int add_relay_log(RELAY_LOG_INFO* rli,LOG_INFO* linfo)
+{
+ MY_STAT s;
+ DBUG_ENTER("add_relay_log");
+ if (!my_stat(linfo->log_file_name,&s,MYF(0)))
+ {
+ sql_print_error("log %s listed in the index, but failed to stat",
+ linfo->log_file_name);
+ DBUG_RETURN(1);
+ }
+ rli->log_space_total += s.st_size;
+#ifndef DBUG_OFF
+ char buf[22];
+#endif
+ DBUG_PRINT("info",("log_space_total: %s", llstr(rli->log_space_total,buf)));
+ DBUG_RETURN(0);
+}
+
+static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli)
+{
+ bool slave_killed=0;
+ MASTER_INFO* mi = rli->mi;
+ const char* save_proc_info;
+ THD* thd = mi->io_thd;
+
+ DBUG_ENTER("wait_for_relay_log_space");
+ pthread_mutex_lock(&rli->log_space_lock);
+ save_proc_info = thd->proc_info;
+ thd->proc_info = "Waiting for relay log space to free";
+ while (rli->log_space_limit < rli->log_space_total &&
+ !(slave_killed=io_slave_killed(thd,mi)))
+ {
+ pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
+ }
+ thd->proc_info = save_proc_info;
+ pthread_mutex_unlock(&rli->log_space_lock);
+ DBUG_RETURN(slave_killed);
+}
+
+
+static int count_relay_log_space(RELAY_LOG_INFO* rli)
+{
+ LOG_INFO linfo;
+ DBUG_ENTER("count_relay_log_space");
+ rli->log_space_total = 0;
+ if (rli->relay_log.find_first_log(&linfo,""))
+ {
+ sql_print_error("Could not find first log while counting relay log space");
+ DBUG_RETURN(1);
+ }
+ do
+ {
+ if (add_relay_log(rli,&linfo))
+ DBUG_RETURN(1);
+ } while (!rli->relay_log.find_next_log(&linfo));
+ DBUG_RETURN(0);
+}
- // we need a mutex while we are changing master info parameters to
- // keep other threads from reading bogus info
- pthread_mutex_lock(&mi->lock);
- mi->pending = 0;
+int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname)
+{
+ int fd,error;
+ MY_STAT stat_area;
+ char fname[FN_REFLEN+128];
+ DBUG_ENTER("init_master_info");
+
+ if (mi->inited)
+ DBUG_RETURN(0);
+ if (init_relay_log_info(&mi->rli, slave_info_fname))
+ DBUG_RETURN(1);
+ mi->rli.mi = mi;
+ mi->mysql=0;
+ mi->file_id=1;
+ mi->ignore_stop_event=0;
+ fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
+
+ /*
+ We need a mutex while we are changing master info parameters to
+ keep other threads from reading bogus info
+ */
+
+ pthread_mutex_lock(&mi->data_lock);
fd = mi->fd;
// we do not want any messages if the file does not exist
if (!my_stat(fname, &stat_area, MYF(0)))
{
- // if someone removed the file from underneath our feet, just close
- // the old descriptor and re-create the old file
+ /*
+ if someone removed the file from underneath our feet, just close
+ the old descriptor and re-create the old file
+ */
if (fd >= 0)
my_close(fd, MYF(MY_WME));
- if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0
- || init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
- {
- if(fd >= 0)
- my_close(fd, MYF(0));
- pthread_mutex_unlock(&mi->lock);
- return 1;
- }
- mi->log_file_name[0] = 0;
- mi->pos = 4; // skip magic number
+ if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
+ MYF(MY_WME)))
+ goto err;
+
+ mi->master_log_name[0] = 0;
+ mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
mi->fd = fd;
if (master_host)
@@ -546,107 +1243,160 @@ int init_master_info(MASTER_INFO* mi)
}
else // file exists
{
- if(fd >= 0)
+ if (fd >= 0)
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
- else if((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0
- || init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
- 0, MYF(MY_WME)))
- {
- if(fd >= 0)
- my_close(fd, MYF(0));
- pthread_mutex_unlock(&mi->lock);
- return 1;
- }
-
- if ((length=my_b_gets(&mi->file, mi->log_file_name,
- sizeof(mi->log_file_name))) < 1)
- {
- msg="Error reading log file name from master info file ";
- goto error;
- }
-
- mi->log_file_name[length-1]= 0; // kill \n
- /* Reuse fname buffer */
- if(!my_b_gets(&mi->file, fname, sizeof(fname)))
- {
- msg="Error reading log file position from master info file";
- goto error;
- }
- mi->pos = strtoull(fname,(char**) 0, 10);
+ else if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
+ 0, MYF(MY_WME)))
+ goto err;
mi->fd = fd;
- if(init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
- master_host) ||
- init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
- master_user) ||
- init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file,
- master_password) ||
- init_intvar_from_file((int*)&mi->port, &mi->file, master_port) ||
- init_intvar_from_file((int*)&mi->connect_retry, &mi->file,
- master_connect_retry))
+ int port, connect_retry, master_log_pos;
+
+ if (init_strvar_from_file(mi->master_log_name,
+ sizeof(mi->master_log_name), &mi->file,
+ "") ||
+ init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
+ init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
+ master_host) ||
+ init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
+ master_user) ||
+ init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file,
+ master_password) ||
+ init_intvar_from_file(&port, &mi->file, master_port) ||
+ init_intvar_from_file(&connect_retry, &mi->file,
+ master_connect_retry))
{
- msg="Error reading master configuration";
- goto error;
+ sql_print_error("Error reading master configuration");
+ goto err;
}
+ /*
+ This has to be handled here as init_intvar_from_file can't handle
+ my_off_t types
+ */
+ mi->master_log_pos= (my_off_t) master_log_pos;
+ mi->port= (uint) port;
+ mi->connect_retry= (uint) connect_retry;
}
-
+ DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
+ mi->master_log_name,
+ (ulong) mi->master_log_pos));
mi->inited = 1;
- // now change the cache from READ to WRITE - must do this
- // before flush_master_info
- reinit_io_cache(&mi->file, WRITE_CACHE, 0L,0,1);
+ // now change cache READ -> WRITE - must do this before flush_master_info
+ reinit_io_cache(&mi->file, WRITE_CACHE,0L,0,1);
error=test(flush_master_info(mi));
- pthread_mutex_unlock(&mi->lock);
- return error;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(error);
-error:
- sql_print_error(msg);
- end_io_cache(&mi->file);
- my_close(fd, MYF(0));
- pthread_mutex_unlock(&mi->lock);
- return 1;
+err:
+ end_relay_log_info(&mi->rli);
+ if (fd >= 0)
+ {
+ my_close(fd, MYF(0));
+ end_io_cache(&mi->file);
+ }
+ mi->fd= -1;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(1);
+}
+
+int register_slave_on_master(MYSQL* mysql)
+{
+ String packet;
+ char buf[4];
+
+ if (!report_host)
+ return 0;
+
+ int4store(buf, server_id);
+ packet.append(buf, 4);
+
+ net_store_data(&packet, report_host);
+ if (report_user)
+ net_store_data(&packet, report_user);
+ else
+ packet.append((char)0);
+
+ if (report_password)
+ net_store_data(&packet, report_user);
+ else
+ packet.append((char)0);
+
+ int2store(buf, (uint16)report_port);
+ packet.append(buf, 2);
+ int4store(buf, rpl_recovery_rank);
+ packet.append(buf, 4);
+ int4store(buf, 0); /* tell the master will fill in master_id */
+ packet.append(buf, 4);
+
+ if (mc_simple_command(mysql, COM_REGISTER_SLAVE, (char*)packet.ptr(),
+ packet.length(), 0))
+ {
+ sql_print_error("Error on COM_REGISTER_SLAVE: '%s'",
+ mc_mysql_error(mysql));
+ return 1;
+ }
+
+ return 0;
}
-int show_master_info(THD* thd)
+int show_master_info(THD* thd, MASTER_INFO* mi)
{
+ // TODO: fix this for multi-master
DBUG_ENTER("show_master_info");
List<Item> field_list;
field_list.push_back(new Item_empty_string("Master_Host",
- sizeof(glob_mi.host)));
+ sizeof(mi->host)));
field_list.push_back(new Item_empty_string("Master_User",
- sizeof(glob_mi.user)));
+ sizeof(mi->user)));
field_list.push_back(new Item_empty_string("Master_Port", 6));
field_list.push_back(new Item_empty_string("Connect_retry", 6));
- field_list.push_back( new Item_empty_string("Log_File",
+ field_list.push_back(new Item_empty_string("Master_Log_File",
FN_REFLEN));
- field_list.push_back(new Item_empty_string("Pos", 12));
- field_list.push_back(new Item_empty_string("Slave_Running", 3));
+ field_list.push_back(new Item_empty_string("Read_Master_Log_Pos", 12));
+ field_list.push_back(new Item_empty_string("Relay_Log_File",
+ FN_REFLEN));
+ field_list.push_back(new Item_empty_string("Relay_Log_Pos", 12));
+ field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
+ FN_REFLEN));
+ field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
+ field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
field_list.push_back(new Item_empty_string("Replicate_do_db", 20));
field_list.push_back(new Item_empty_string("Replicate_ignore_db", 20));
field_list.push_back(new Item_empty_string("Last_errno", 4));
field_list.push_back(new Item_empty_string("Last_error", 20));
field_list.push_back(new Item_empty_string("Skip_counter", 12));
- if(send_fields(thd, field_list, 1))
+ field_list.push_back(new Item_empty_string("Exec_master_log_pos", 12));
+ field_list.push_back(new Item_empty_string("Relay_log_space", 12));
+ if (send_fields(thd, field_list, 1))
DBUG_RETURN(-1);
String* packet = &thd->packet;
packet->length(0);
- pthread_mutex_lock(&glob_mi.lock);
- net_store_data(packet, glob_mi.host);
- net_store_data(packet, glob_mi.user);
- net_store_data(packet, (uint32) glob_mi.port);
- net_store_data(packet, (uint32) glob_mi.connect_retry);
- net_store_data(packet, glob_mi.log_file_name);
- net_store_data(packet, (uint32) glob_mi.pos); // QQ: Should be fixed
- pthread_mutex_unlock(&glob_mi.lock);
- pthread_mutex_lock(&LOCK_slave);
- net_store_data(packet, slave_running ? "Yes":"No");
- pthread_mutex_unlock(&LOCK_slave);
+ pthread_mutex_lock(&mi->data_lock);
+ pthread_mutex_lock(&mi->rli.data_lock);
+ net_store_data(packet, mi->host);
+ net_store_data(packet, mi->user);
+ net_store_data(packet, (uint32) mi->port);
+ net_store_data(packet, (uint32) mi->connect_retry);
+ net_store_data(packet, mi->master_log_name);
+ net_store_data(packet, (longlong) mi->master_log_pos);
+ net_store_data(packet, mi->rli.relay_log_name +
+ dirname_length(mi->rli.relay_log_name));
+ net_store_data(packet, (longlong) mi->rli.relay_log_pos);
+ net_store_data(packet, mi->rli.master_log_name);
+ net_store_data(packet, mi->slave_running ? "Yes":"No");
+ net_store_data(packet, mi->rli.slave_running ? "Yes":"No");
net_store_data(packet, &replicate_do_db);
net_store_data(packet, &replicate_ignore_db);
- net_store_data(packet, (uint32)last_slave_errno);
- net_store_data(packet, last_slave_error);
- net_store_data(packet, slave_skip_counter);
+ net_store_data(packet, (uint32)mi->rli.last_slave_errno);
+ net_store_data(packet, mi->rli.last_slave_error);
+ net_store_data(packet, mi->rli.slave_skip_counter);
+ net_store_data(packet, (longlong) mi->rli.master_log_pos);
+ net_store_data(packet, (longlong) mi->rli.log_space_total);
+ pthread_mutex_unlock(&mi->rli.data_lock);
+ pthread_mutex_unlock(&mi->data_lock);
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
DBUG_RETURN(-1);
@@ -659,80 +1409,88 @@ int flush_master_info(MASTER_INFO* mi)
{
IO_CACHE* file = &mi->file;
char lbuf[22];
-
+ DBUG_ENTER("flush_master_info");
+ DBUG_PRINT("enter",("master_pos: %ld", (long) mi->master_log_pos));
+
my_b_seek(file, 0L);
- my_b_printf(file, "%s\n%s\n%s\n%s\n%s\n%d\n%d\n",
- mi->log_file_name, llstr(mi->pos, lbuf), mi->host, mi->user,
- mi->password, mi->port, mi->connect_retry);
+ my_b_printf(file, "%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n",
+ mi->master_log_name, llstr(mi->master_log_pos, lbuf),
+ mi->host, mi->user,
+ mi->password, mi->port, mi->connect_retry
+ );
flush_io_cache(file);
- return 0;
+ DBUG_RETURN(0);
}
-int st_master_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos)
+int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
+ ulonglong log_pos)
{
if (!inited) return -1;
- bool pos_reached;
+ bool pos_reached = 0;
int event_count = 0;
- pthread_mutex_lock(&lock);
- while(!thd->killed)
+ pthread_mutex_lock(&data_lock);
+ abort_pos_wait=0; // abort only if master info changes during wait
+ while (!thd->killed || !abort_pos_wait)
{
int cmp_result;
- if (*log_file_name)
+ if (abort_pos_wait)
+ {
+ abort_pos_wait=0;
+ pthread_mutex_unlock(&data_lock);
+ return -1;
+ }
+ DBUG_ASSERT(*master_log_name || master_log_pos == 0);
+ if (*master_log_name)
{
/*
We should use dirname_length() here when we have a version of
this that doesn't modify the argument */
- char *basename = strrchr(log_file_name, FN_LIBCHAR);
+ char *basename = strrchr(master_log_name, FN_LIBCHAR);
if (basename)
++basename;
else
- basename = log_file_name;
+ basename = master_log_name;
cmp_result = strncmp(basename, log_name->ptr(),
log_name->length());
}
else
cmp_result = 0;
- pos_reached = ((!cmp_result && pos >= log_pos) || cmp_result > 0);
+ pos_reached = ((!cmp_result && master_log_pos >= log_pos) ||
+ cmp_result > 0);
if (pos_reached || thd->killed)
break;
- const char* msg = thd->enter_cond(&cond, &lock,
+ const char* msg = thd->enter_cond(&data_cond, &data_lock,
"Waiting for master update");
- pthread_cond_wait(&cond, &lock);
+ pthread_cond_wait(&data_cond, &data_lock);
thd->exit_cond(msg);
event_count++;
}
- pthread_mutex_unlock(&lock);
+ pthread_mutex_unlock(&data_lock);
return thd->killed ? -1 : event_count;
}
-
-static int init_slave_thread(THD* thd)
+static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{
DBUG_ENTER("init_slave_thread");
thd->system_thread = thd->bootstrap = 1;
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
- thd->net.timeout = slave_net_timeout;
- thd->max_packet_length=thd->net.max_packet;
+ thd->net.read_timeout = slave_net_timeout;
thd->master_access= ~0;
thd->priv_user = 0;
thd->slave_thread = 1;
thd->options = (((opt_log_slave_updates) ? OPTION_BIN_LOG:0) | OPTION_AUTO_IS_NULL) ;
thd->system_thread = 1;
thd->client_capabilities = CLIENT_LOCAL_FILES;
- slave_real_id=thd->real_id=pthread_self();
+ thd->real_id=pthread_self();
pthread_mutex_lock(&LOCK_thread_count);
thd->thread_id = thread_id++;
pthread_mutex_unlock(&LOCK_thread_count);
- if (init_thr_lock() ||
- my_pthread_setspecific_ptr(THR_THD, thd) ||
- my_pthread_setspecific_ptr(THR_MALLOC, &thd->mem_root) ||
- my_pthread_setspecific_ptr(THR_NET, &thd->net))
+ if (init_thr_lock() || thd->store_globals())
{
- close_connection(&thd->net,ER_OUT_OF_RESOURCES); // is this needed?
end_thread(thd,0);
DBUG_RETURN(-1);
}
@@ -745,18 +1503,21 @@ static int init_slave_thread(THD* thd)
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
- thd->mem_root.free=thd->mem_root.used=0; // Probably not needed
- if (thd->max_join_size == (ulong) ~0L)
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
- thd->proc_info="Waiting for master update";
+ if (thd_type == SLAVE_THD_SQL)
+ thd->proc_info= "Waiting for the next event in slave queue";
+ else
+ thd->proc_info= "Waiting for master update";
thd->version=refresh_version;
thd->set_time();
-
DBUG_RETURN(0);
}
-static int safe_sleep(THD* thd, int sec)
+
+static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
+ void* thread_killed_arg)
{
thr_alarm_t alarmed;
thr_alarm_init(&alarmed);
@@ -774,36 +1535,44 @@ static int safe_sleep(THD* thd, int sec)
*/
thr_alarm(&alarmed, 2 * nap_time,&alarm_buff);
sleep(nap_time);
- // if we wake up before the alarm goes off, hit the button
- // so it will not wake up the wife and kids :-)
+ /*
+ If we wake up before the alarm goes off, hit the button
+ so it will not wake up the wife and kids :-)
+ */
if (thr_alarm_in_use(&alarmed))
thr_end_alarm(&alarmed);
- if (slave_killed(thd))
+ if ((*thread_killed)(thd,thread_killed_arg))
return 1;
start_time=time((time_t*) 0);
}
return 0;
}
-
-static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
+static int request_dump(MYSQL* mysql, MASTER_INFO* mi,
+ bool *suppress_warnings)
{
char buf[FN_REFLEN + 10];
int len;
int binlog_flags = 0; // for now
- char* logname = mi->log_file_name;
- int4store(buf, mi->pos);
+ char* logname = mi->master_log_name;
+ // TODO if big log files: Change next to int8store()
+ int4store(buf, (longlong) mi->master_log_pos);
int2store(buf + 4, binlog_flags);
int4store(buf + 6, server_id);
len = (uint) strlen(logname);
memcpy(buf + 10, logname,len);
if (mc_simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
{
- // something went wrong, so we will just reconnect and retry later
- // in the future, we should do a better error analysis, but for
- // now we just fill up the error log :-)
- sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
+ /*
+ Something went wrong, so we will just reconnect and retry later
+ in the future, we should do a better error analysis, but for
+ now we just fill up the error log :-)
+ */
+ if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
+ *suppress_warnings= 1; // Suppress reconnect warning
+ else
+ sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
mc_mysql_error(mysql), master_connect_retry);
return 1;
}
@@ -811,17 +1580,17 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
return 0;
}
-static int request_table_dump(MYSQL* mysql, char* db, char* table)
+static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
{
char buf[1024];
char * p = buf;
uint table_len = (uint) strlen(table);
uint db_len = (uint) strlen(db);
- if(table_len + db_len > sizeof(buf) - 2)
- {
- sql_print_error("request_table_dump: Buffer overrun");
- return 1;
- }
+ if (table_len + db_len > sizeof(buf) - 2)
+ {
+ sql_print_error("request_table_dump: Buffer overrun");
+ return 1;
+ }
*p++ = db_len;
memcpy(p, db, db_len);
@@ -839,26 +1608,37 @@ command");
return 0;
}
-
/*
- We set suppress_warnings TRUE when a normal net read timeout has
- caused us to try a reconnect. We do not want to print anything to
- the error log in this case because this a anormal event in an idle
- server.
+ read one event from the master
+
+ SYNOPSIS
+ read_event()
+ mysql MySQL connection
+ mi Master connection information
+ suppress_warnings TRUE when a normal net read timeout has caused us to
+ try a reconnect. We do not want to print anything to
+ the error log in this case because this a anormal
+ event in an idle server.
+ RETURN VALUES
+ 'packet_error' Error
+ number Length of packet
+
*/
-static uint read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
+static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
{
- uint len = packet_error;
+ ulong len = packet_error;
- // my_real_read() will time us out
- // we check if we were told to die, and if not, try reading again
+ /*
+ my_real_read() will time us out
+ We check if we were told to die, and if not, try reading again
+ */
#ifndef DBUG_OFF
if (disconnect_slave_event_count && !(events_till_disconnect--))
return packet_error;
#endif
*suppress_warnings= 0;
-
+
len = mc_net_safe_read(mysql);
if (len == packet_error || (long) len < 1)
@@ -892,351 +1672,73 @@ server_errno=%d)",
return len - 1;
}
-static int check_expected_error(THD* thd, int expected_error)
+
+int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error)
{
- switch(expected_error)
- {
- case ER_NET_READ_ERROR:
- case ER_NET_ERROR_ON_WRITE:
- case ER_SERVER_SHUTDOWN:
- case ER_NEW_ABORTING_CONNECTION:
- my_snprintf(last_slave_error, sizeof(last_slave_error),
- "Slave: query '%s' partially completed on the master \
+ switch (expected_error) {
+ case ER_NET_READ_ERROR:
+ case ER_NET_ERROR_ON_WRITE:
+ case ER_SERVER_SHUTDOWN:
+ case ER_NEW_ABORTING_CONNECTION:
+ my_snprintf(rli->last_slave_error, sizeof(rli->last_slave_error),
+ "Slave: query '%s' partially completed on the master \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the\
slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\
SLAVE START;", thd->query);
- last_slave_errno = expected_error;
- sql_print_error("%s",last_slave_error);
- return 1;
- default:
- return 0;
- }
-}
-
-inline int ignored_error_code(int err_code)
-{
- return use_slave_mask && bitmap_is_set(&slave_error_mask, err_code);
+ rli->last_slave_errno = expected_error;
+ sql_print_error("%s",rli->last_slave_error);
+ return 1;
+ default:
+ return 0;
+ }
}
-static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
+static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
{
- Log_event * ev = Log_event::read_log_event((const char*)net->read_pos + 1,
- event_len);
- char llbuff[22];
-
- mi->event_len = event_len; /* Added by Heikki: InnoDB internally stores the
- master log position it has processed so far;
- position to store is really
- mi->pos + mi->pending + mi->event_len
- since we must store the pos of the END of the
- current log event */
+ DBUG_ASSERT(rli->sql_thd==thd);
+ Log_event * ev = next_event(rli);
+ DBUG_ASSERT(rli->sql_thd==thd);
+ if (sql_slave_killed(thd,rli))
+ return 1;
if (ev)
{
int type_code = ev->get_type_code();
- if (ev->server_id == ::server_id || slave_skip_counter)
+ int exec_res;
+ pthread_mutex_lock(&rli->data_lock);
+ if (ev->server_id == ::server_id ||
+ (rli->slave_skip_counter && type_code != ROTATE_EVENT))
{
- if(type_code == LOAD_EVENT)
- skip_load_data_infile(net);
-
- mi->inc_pos(event_len);
- flush_master_info(mi);
- if(slave_skip_counter && /* protect against common user error of
- setting the counter to 1 instead of 2
- while recovering from an failed
- auto-increment insert */
- !(type_code == INTVAR_EVENT &&
- slave_skip_counter == 1))
- --slave_skip_counter;
+ /* TODO: I/O thread should not even log events with the same server id */
+ rli->inc_pos(ev->get_event_len(),
+ type_code != STOP_EVENT ? ev->log_pos : LL(0),
+ 1/* skip lock*/);
+ flush_relay_log_info(rli);
+
+ /*
+ Protect against common user error of setting the counter to 1
+ instead of 2 while recovering from an failed auto-increment insert
+ */
+ if (rli->slave_skip_counter &&
+ !((type_code == INTVAR_EVENT || type_code == STOP_EVENT) &&
+ rli->slave_skip_counter == 1))
+ --rli->slave_skip_counter;
+ pthread_mutex_unlock(&rli->data_lock);
delete ev;
return 0; // avoid infinite update loops
}
+ pthread_mutex_unlock(&rli->data_lock);
thd->server_id = ev->server_id; // use the original server id for logging
thd->set_time(); // time the query
- if(!ev->when)
+ if (!ev->when)
ev->when = time(NULL);
-
- switch(type_code) {
- case QUERY_EVENT:
- {
- Query_log_event* qev = (Query_log_event*)ev;
- int q_len = qev->q_len;
- int expected_error,actual_error = 0;
- init_sql_alloc(&thd->mem_root, 8192,0);
- thd->db = rewrite_db((char*)qev->db);
- if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
- {
- thd->query = (char*)qev->query;
- thd->set_time((time_t)qev->when);
- thd->current_tablenr = 0;
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query_id = query_id++;
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->last_nx_table = thd->last_nx_db = 0;
- thd->query_error = 0; // clear error
- thd->net.last_errno = 0;
- thd->net.last_error[0] = 0;
- thd->slave_proxy_id = qev->thread_id; // for temp tables
-
- // sanity check to make sure the master did not get a really bad
- // error on the query
- if (ignored_error_code((expected_error=qev->error_code)) ||
- !check_expected_error(thd, expected_error))
- {
- mysql_parse(thd, thd->query, q_len);
- if (expected_error !=
- (actual_error = thd->net.last_errno) && expected_error &&
- !ignored_error_code(actual_error))
- {
- const char* errmsg = "Slave: did not get the expected error\
- running query from master - expected: '%s' (%d), got '%s' (%d)";
- sql_print_error(errmsg, ER_SAFE(expected_error),
- expected_error,
- actual_error ? thd->net.last_error:"no error",
- actual_error);
- thd->query_error = 1;
- }
- else if (expected_error == actual_error ||
- ignored_error_code(actual_error))
- {
- thd->query_error = 0;
- *last_slave_error = 0;
- last_slave_errno = 0;
- }
- }
- else
- {
- // master could be inconsistent, abort and tell DBA to check/fix it
- thd->db = thd->query = 0;
- thd->convert_set = 0;
- close_thread_tables(thd);
- free_root(&thd->mem_root,0);
- delete ev;
- return 1;
- }
- }
- thd->db = 0; // prevent db from being freed
- thd->query = 0; // just to be sure
- // assume no convert for next query unless set explictly
- thd->convert_set = 0;
- close_thread_tables(thd);
-
- if (thd->query_error || thd->fatal_error)
- {
- sql_print_error("Slave: error running query '%s' ",
- qev->query);
- last_slave_errno = actual_error ? actual_error : -1;
- my_snprintf(last_slave_error, sizeof(last_slave_error),
- "error '%s' on query '%s'",
- actual_error ? thd->net.last_error :
- "unexpected success or fatal error",
- qev->query
- );
- free_root(&thd->mem_root,0);
- delete ev;
- return 1;
- }
- free_root(&thd->mem_root,0);
- delete ev;
-
- mi->inc_pos(event_len);
-
- if (!(thd->options & OPTION_BEGIN)) {
-
- /* We only flush the master info position to the master.info file if
- the transaction is not open any more: an incomplete transaction will
- be rolled back automatically in crash recovery in transactional
- table handlers */
-
- flush_master_info(mi);
- }
- break;
- }
-
- case LOAD_EVENT:
- {
- Load_log_event* lev = (Load_log_event*)ev;
- init_sql_alloc(&thd->mem_root, 8192,0);
- thd->db = rewrite_db((char*)lev->db);
- thd->query = 0;
- thd->query_error = 0;
-
- if(db_ok(thd->db, replicate_do_db, replicate_ignore_db))
- {
- thd->set_time((time_t)lev->when);
- thd->current_tablenr = 0;
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query_id = query_id++;
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
-
- TABLE_LIST tables;
- bzero((char*) &tables,sizeof(tables));
- tables.db = thd->db;
- tables.name = tables.real_name = (char*)lev->table_name;
- tables.lock_type = TL_WRITE;
- // the table will be opened in mysql_load
- if(table_rules_on && !tables_ok(thd, &tables))
- {
- skip_load_data_infile(net);
- }
- else
- {
- enum enum_duplicates handle_dup = DUP_IGNORE;
- if(lev->sql_ex.opt_flags && REPLACE_FLAG)
- handle_dup = DUP_REPLACE;
- sql_exchange ex((char*)lev->fname, lev->sql_ex.opt_flags &&
- DUMPFILE_FLAG );
- String field_term(&lev->sql_ex.field_term, 1),
- enclosed(&lev->sql_ex.enclosed, 1),
- line_term(&lev->sql_ex.line_term,1),
- escaped(&lev->sql_ex.escaped, 1),
- line_start(&lev->sql_ex.line_start, 1);
-
- ex.field_term = &field_term;
- if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
- ex.field_term->length(0);
-
- ex.enclosed = &enclosed;
- if(lev->sql_ex.empty_flags & ENCLOSED_EMPTY)
- ex.enclosed->length(0);
-
- ex.line_term = &line_term;
- if(lev->sql_ex.empty_flags & LINE_TERM_EMPTY)
- ex.line_term->length(0);
-
- ex.line_start = &line_start;
- if(lev->sql_ex.empty_flags & LINE_START_EMPTY)
- ex.line_start->length(0);
-
- ex.escaped = &escaped;
- if(lev->sql_ex.empty_flags & ESCAPED_EMPTY)
- ex.escaped->length(0);
-
- ex.opt_enclosed = (lev->sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
- if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
- ex.field_term->length(0);
-
- ex.skip_lines = lev->skip_lines;
-
-
- List<Item> fields;
- lev->set_fields(fields);
- thd->slave_proxy_id = thd->thread_id;
- thd->net.vio = net->vio;
- // mysql_load will use thd->net to read the file
- thd->net.pkt_nr = net->pkt_nr;
- // make sure the client does not get confused
- // about the packet sequence
- if(mysql_load(thd, &ex, &tables, fields, handle_dup, 1,
- TL_WRITE))
- thd->query_error = 1;
- if(thd->cuted_fields)
- sql_print_error("Slave: load data infile at position %s in log \
-'%s' produced %d warning(s)", llstr(glob_mi.pos,llbuff), RPL_LOG_NAME,
- thd->cuted_fields );
- net->pkt_nr = thd->net.pkt_nr;
- }
- }
- else
- {
- // we will just ask the master to send us /dev/null if we do not
- // want to load the data :-)
- skip_load_data_infile(net);
- }
-
- thd->net.vio = 0;
- thd->db = 0;// prevent db from being freed
- close_thread_tables(thd);
- if(thd->query_error)
- {
- int sql_error = thd->net.last_errno;
- if(!sql_error)
- sql_error = ER_UNKNOWN_ERROR;
-
- sql_print_error("Slave: Error '%s' running load data infile ",
- ER(sql_error));
- delete ev;
- free_root(&thd->mem_root,0);
- return 1;
- }
-
- delete ev;
- free_root(&thd->mem_root,0);
-
- if(thd->fatal_error)
- {
- sql_print_error("Slave: Fatal error running query '%s' ",
- thd->query);
- return 1;
- }
-
- mi->inc_pos(event_len);
-
- if (!(thd->options & OPTION_BEGIN))
- flush_master_info(mi);
-
- break;
- }
-
- /* Question: in a START or STOP event, what happens if we have transaction
- open? */
-
- case START_EVENT:
- mi->inc_pos(event_len);
- flush_master_info(mi);
- delete ev;
- break;
-
- case STOP_EVENT:
- if(mi->pos > 4) // stop event should be ignored after rotate event
- {
- close_temporary_tables(thd);
- mi->inc_pos(event_len);
- flush_master_info(mi);
- }
- delete ev;
- break;
- case ROTATE_EVENT:
- {
- Rotate_log_event* rev = (Rotate_log_event*)ev;
- int ident_len = rev->ident_len;
- pthread_mutex_lock(&mi->lock);
- memcpy(mi->log_file_name, rev->new_log_ident,ident_len );
- mi->log_file_name[ident_len] = 0;
- mi->pos = 4; // skip magic number
- pthread_cond_broadcast(&mi->cond);
- pthread_mutex_unlock(&mi->lock);
-
- if (!(thd->options & OPTION_BEGIN))
- flush_master_info(mi);
-#ifndef DBUG_OFF
- if(abort_slave_event_count)
- ++events_till_abort;
-#endif
- delete ev;
- break;
- }
-
- case INTVAR_EVENT:
- {
- Intvar_log_event* iev = (Intvar_log_event*)ev;
- switch(iev->type)
- {
- case LAST_INSERT_ID_EVENT:
- thd->last_insert_id_used = 1;
- thd->last_insert_id = iev->val;
- break;
- case INSERT_ID_EVENT:
- thd->next_insert_id = iev->val;
- break;
-
- }
- mi->inc_pending(event_len);
- delete ev;
- break;
- }
- }
+ ev->thd = thd;
+ thd->log_pos = ev->log_pos;
+ exec_res = ev->exec_event(rli);
+ DBUG_ASSERT(rli->sql_thd==thd);
+ delete ev;
+ return exec_res;
}
else
{
@@ -1246,350 +1748,753 @@ This may also be a network problem, or just a bug in the master or slave code.\
");
return 1;
}
- return 0;
}
-
-// slave thread
-pthread_handler_decl(handle_slave,arg __attribute__((unused)))
+/* slave I/O thread */
+pthread_handler_decl(handle_slave_io,arg)
{
#ifndef DBUG_OFF
- slave_begin:
+slave_begin:
#endif
THD *thd; // needs to be first for thread_stack
MYSQL *mysql = NULL ;
+ MASTER_INFO* mi = (MASTER_INFO*)arg;
char llbuff[22];
-
- pthread_mutex_lock(&LOCK_slave);
- if (!server_id)
- {
- pthread_cond_broadcast(&COND_slave_start);
- pthread_mutex_unlock(&LOCK_slave);
- sql_print_error("Server id not set, will not start slave");
- pthread_exit((void*)1);
- }
+ bool retried_once = 0;
+ ulonglong last_failed_pos = 0; // TODO: see if last_failed_pos is needed
+ DBUG_ASSERT(mi->inited);
- if(slave_running)
- {
- pthread_cond_broadcast(&COND_slave_start);
- pthread_mutex_unlock(&LOCK_slave);
- pthread_exit((void*)1); // safety just in case
- }
- slave_running = 1;
- abort_slave = 0;
+ pthread_mutex_lock(&mi->run_lock);
#ifndef DBUG_OFF
- events_till_abort = abort_slave_event_count;
+ mi->events_till_abort = abort_slave_event_count;
#endif
- pthread_cond_broadcast(&COND_slave_start);
- pthread_mutex_unlock(&LOCK_slave);
-
- // int error = 1;
- bool retried_once = 0;
- ulonglong last_failed_pos = 0;
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init();
- slave_thd = thd = new THD; // note that contructor of THD uses DBUG_ !
- thd->set_time();
- DBUG_ENTER("handle_slave");
+ thd = new THD; // note that contructor of THD uses DBUG_ !
+ DBUG_ENTER("handle_slave_io");
+ THD_CHECK_SENTRY(thd);
pthread_detach_this_thread();
- if (init_slave_thread(thd) || init_master_info(&glob_mi))
- {
- sql_print_error("Failed during slave thread initialization");
- goto err;
- }
+ if (init_slave_thread(thd, SLAVE_THD_IO))
+ {
+ pthread_cond_broadcast(&mi->start_cond);
+ pthread_mutex_unlock(&mi->run_lock);
+ sql_print_error("Failed during slave I/O thread initialization");
+ goto err;
+ }
+ mi->io_thd = thd;
thd->thread_stack = (char*)&thd; // remember where our stack is
- thd->temporary_tables = save_temporary_tables; // restore temp tables
+ thd->store_globals();
threads.append(thd);
- glob_mi.pending = 0; //this should always be set to 0 when the slave thread
- // is started
+ mi->slave_running = 1;
+ mi->abort_slave = 0;
+ pthread_cond_broadcast(&mi->start_cond);
+ pthread_mutex_unlock(&mi->run_lock);
- DBUG_PRINT("info",("master info: log_file_name=%s, position=%s",
- glob_mi.log_file_name, llstr(glob_mi.pos,llbuff)));
-
+ DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
+ mi->master_log_name,
+ llstr(mi->master_log_pos,llbuff)));
- if (!(mysql = mc_mysql_init(NULL)))
+ if (!(mi->mysql = mysql = mc_mysql_init(NULL)))
{
- sql_print_error("Slave thread: error in mc_mysql_init()");
+ sql_print_error("Slave I/O thread: error in mc_mysql_init()");
goto err;
}
thd->proc_info = "connecting to master";
#ifndef DBUG_OFF
- sql_print_error("Slave thread initialized");
+ sql_print_error("Slave I/O thread initialized");
#endif
// we can get killed during safe_connect
- if (!safe_connect(thd, mysql, &glob_mi))
- sql_print_error("Slave: connected to master '%s@%s:%d',\
- replication started in log '%s' at position %s", glob_mi.user,
- glob_mi.host, glob_mi.port,
- RPL_LOG_NAME,
- llstr(glob_mi.pos,llbuff));
+ if (!safe_connect(thd, mysql, mi))
+ sql_print_error("Slave I/O thread: connected to master '%s@%s:%d',\
+ replication started in log '%s' at position %s", mi->user,
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
else
{
- sql_print_error("Slave thread killed while connecting to master");
+ sql_print_error("Slave I/O thread killed while connecting to master");
goto err;
}
-
+
connected:
- mysql->net.timeout=slave_net_timeout;
- while (!slave_killed(thd))
+ thd->slave_net = &mysql->net;
+ thd->proc_info = "Checking master version";
+ if (check_master_version(mysql, mi))
+ goto err;
+ if (!mi->old_format)
{
- thd->proc_info = "Requesting binlog dump";
- if(request_dump(mysql, &glob_mi))
- {
- sql_print_error("Failed on request_dump()");
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while requesting master \
+ /*
+ Register ourselves with the master.
+ If fails, this is not fatal - we just print the error message and go
+ on with life.
+ */
+ thd->proc_info = "Registering slave on master";
+ if (register_slave_on_master(mysql) || update_slave_list(mysql))
+ goto err;
+ }
+
+ while (!io_slave_killed(thd,mi))
+ {
+ bool suppress_warnings= 0;
+ thd->proc_info = "Requesting binlog dump";
+ if (request_dump(mysql, mi, &suppress_warnings))
+ {
+ sql_print_error("Failed on request_dump()");
+ if (io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed while requesting master \
dump");
- goto err;
- }
+ goto err;
+ }
- thd->proc_info = "Waiiting to reconnect after a failed dump request";
- if(mysql->net.vio)
- vio_close(mysql->net.vio);
- // first time retry immediately, assuming that we can recover
- // right away - if first time fails, sleep between re-tries
- // hopefuly the admin can fix the problem sometime
- if(retried_once)
- safe_sleep(thd, glob_mi.connect_retry);
- else
- retried_once = 1;
+ thd->proc_info = "Waiiting to reconnect after a failed dump request";
+ mc_end_server(mysql);
+ /*
+ First time retry immediately, assuming that we can recover
+ right away - if first time fails, sleep between re-tries
+ hopefuly the admin can fix the problem sometime
+ */
+ if (retried_once)
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*)mi);
+ else
+ retried_once = 1;
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while retrying master \
+ if (io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed while retrying master \
dump");
- goto err;
- }
-
- thd->proc_info = "Reconnecting after a failed dump request";
- last_failed_pos=glob_mi.pos;
- sql_print_error("Slave: failed dump request, reconnecting to \
-try again, log '%s' at postion %s", RPL_LOG_NAME,
- llstr(last_failed_pos,llbuff));
- if(safe_reconnect(thd, mysql, &glob_mi, 0) || slave_killed(thd))
- {
- sql_print_error("Slave thread killed during or after reconnect");
- goto err;
- }
-
- goto connected;
- }
+ goto err;
+ }
- while(!slave_killed(thd))
- {
- bool suppress_warnings= 0;
-
- thd->proc_info = "Reading master update";
- uint event_len = read_event(mysql, &glob_mi, &suppress_warnings);
-
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while reading event");
- goto err;
- }
+ thd->proc_info = "Reconnecting after a failed dump request";
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: failed dump request, \
+reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed during or \
+after reconnect");
+ goto err;
+ }
+
+ goto connected;
+ }
+
+ while (!io_slave_killed(thd,mi))
+ {
+ bool suppress_warnings= 0;
+ thd->proc_info = "Reading master update";
+ ulong event_len = read_event(mysql, mi, &suppress_warnings);
+ if (io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed while reading event");
+ goto err;
+ }
- if (event_len == packet_error)
- {
- if(mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE)
- {
- sql_print_error("Log entry on master is longer than \
-max_allowed_packet on slave. Slave thread will be aborted. If the entry is \
-really supposed to be that long, restart the server with a higher value of \
-max_allowed_packet. The current value is %ld", max_allowed_packet);
- goto err;
- }
-
- thd->proc_info = "Waiting to reconnect after a failed read";
- if(mysql->net.vio)
- vio_close(mysql->net.vio);
- if(retried_once) // punish repeat offender with sleep
- safe_sleep(thd, glob_mi.connect_retry);
- else
- retried_once = 1;
+ if (event_len == packet_error)
+ {
+ if (mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE)
+ {
+ sql_print_error("Log entry on master is longer than \
+max_allowed_packet (%ld) on slave. Slave thread will be aborted. If the entry \
+is correct, restart the server with a higher value of max_allowed_packet",
+ thd->variables.max_allowed_packet);
+ goto err;
+ }
+
+ thd->proc_info = "Waiting to reconnect after a failed read";
+ mc_end_server(mysql);
+ if (retried_once) // punish repeat offender with sleep
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*)mi);
+ else
+ retried_once = 1;
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while waiting to \
+ if (io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed while waiting to \
reconnect after a failed read");
- goto err;
- }
- thd->proc_info = "Reconnecting after a failed read";
- last_failed_pos= glob_mi.pos;
-
- if (!suppress_warnings)
- sql_print_error("Slave: Failed reading log event, \
-reconnecting to retry, log '%s' position %s", RPL_LOG_NAME,
- llstr(last_failed_pos, llbuff));
- if(safe_reconnect(thd, mysql, &glob_mi,
- suppress_warnings)
- || slave_killed(thd))
- {
- sql_print_error("Slave thread killed during or after a \
+ goto err;
+ }
+ thd->proc_info = "Reconnecting after a failed read";
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: Failed reading log event, \
+reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos, llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed during or after a \
reconnect done to recover from failed read");
- goto err;
- }
-
- goto connected;
- } // if(event_len == packet_error)
+ goto err;
+ }
+ goto connected;
+ } // if (event_len == packet_error)
- thd->proc_info = "Processing master log event";
- if(exec_event(thd, &mysql->net, &glob_mi, event_len))
- {
- sql_print_error("\
-Error running query, slave aborted. Fix the problem, and re-start \
-the slave thread with \"mysqladmin start-slave\". We stopped at log \
-'%s' position %s",
- RPL_LOG_NAME, llstr(glob_mi.pos, llbuff));
- goto err;
- // there was an error running the query
- // abort the slave thread, when the problem is fixed, the user
- // should restart the slave with mysqladmin start-slave
- }
+ thd->proc_info = "Queueing event from master";
+ if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
+ event_len))
+ {
+ sql_print_error("Slave I/O thread could not queue event \
+from master");
+ goto err;
+ }
+ flush_master_info(mi);
+ if (mi->rli.log_space_limit && mi->rli.log_space_limit <
+ mi->rli.log_space_total)
+ if (wait_for_relay_log_space(&mi->rli))
+ {
+ sql_print_error("Slave I/O thread aborted while waiting for relay \
+log space");
+ goto err;
+ }
+ // TODO: check debugging abort code
#ifndef DBUG_OFF
- if(abort_slave_event_count && !--events_till_abort)
- {
- sql_print_error("Slave: debugging abort");
- goto err;
- }
+ if (abort_slave_event_count && !--events_till_abort)
+ {
+ sql_print_error("Slave I/O thread: debugging abort");
+ goto err;
+ }
#endif
-
- // successful exec with offset advance,
- // the slave repents and his sins are forgiven!
- if(glob_mi.pos > last_failed_pos)
- {
- retried_once = 0;
+ }
+ }
+
+ // error = 0;
+err:
+ // print the current replication position
+ sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s",
+ IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
+ thd->query = thd->db = 0; // extra safety
+ if (mysql)
+ {
+ mc_mysql_close(mysql);
+ mi->mysql=0;
+ }
+ thd->proc_info = "Waiting for slave mutex on exit";
+ pthread_mutex_lock(&mi->run_lock);
+ mi->slave_running = 0;
+ mi->io_thd = 0;
+ // TODO: make rpl_status part of MASTER_INFO
+ change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
+ mi->abort_slave = 0; // TODO: check if this is needed
+ DBUG_ASSERT(thd->net.buff != 0);
+ net_end(&thd->net); // destructor will not free it, because net.vio is 0
+ pthread_mutex_lock(&LOCK_thread_count);
+ THD_CHECK_SENTRY(thd);
+ delete thd;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ my_thread_end(); // clean-up before broadcast
+ pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
+ pthread_mutex_unlock(&mi->run_lock);
#ifndef DBUG_OFF
- stuck_count = 0;
-#endif
- }
+ if (abort_slave_event_count && !events_till_abort)
+ goto slave_begin;
+#endif
+ pthread_exit(0);
+ DBUG_RETURN(0); // Can't return anything here
+}
+
+
+/* slave SQL logic thread */
+
+pthread_handler_decl(handle_slave_sql,arg)
+{
#ifndef DBUG_OFF
- else
- {
- // show a little mercy, allow slave to read one more event
- // before cutting him off - otherwise he gets stuck
- // on Intvar events, since they do not advance the offset
- // immediately
- if (++stuck_count > 2)
- events_till_disconnect++;
- }
-#endif
- } // while(!slave_killed(thd)) - read/exec loop
- } // while(!slave_killed(thd)) - slave loop
+slave_begin:
+#endif
+ THD *thd; /* needs to be first for thread_stack */
+ MYSQL *mysql = NULL ;
+ bool retried_once = 0;
+ ulonglong last_failed_pos = 0; // TODO: see if this can be removed
+ char llbuff[22],llbuff1[22];
+ RELAY_LOG_INFO* rli = &((MASTER_INFO*)arg)->rli;
+ const char* errmsg=0;
+ DBUG_ASSERT(rli->inited);
+ pthread_mutex_lock(&rli->run_lock);
+ DBUG_ASSERT(!rli->slave_running);
+#ifndef DBUG_OFF
+ rli->events_till_abort = abort_slave_event_count;
+#endif
+
+
+ // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
+ my_thread_init();
+ thd = new THD; // note that contructor of THD uses DBUG_ !
+ DBUG_ENTER("handle_slave_sql");
+ THD_CHECK_SENTRY(thd);
+
+ pthread_detach_this_thread();
+ if (init_slave_thread(thd, SLAVE_THD_SQL))
+ {
+ /*
+ TODO: this is currently broken - slave start and change master
+ will be stuck if we fail here
+ */
+ pthread_cond_broadcast(&rli->start_cond);
+ pthread_mutex_unlock(&rli->run_lock);
+ sql_print_error("Failed during slave thread initialization");
+ goto err;
+ }
+ THD_CHECK_SENTRY(thd);
+ thd->thread_stack = (char*)&thd; // remember where our stack is
+ thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
+ thd->store_globals();
+ threads.append(thd);
+ rli->sql_thd = thd;
+ rli->slave_running = 1;
+ rli->abort_slave = 0;
+ pthread_cond_broadcast(&rli->start_cond);
+ pthread_mutex_unlock(&rli->run_lock);
+ // This should always be set to 0 when the slave thread is started
+ rli->pending = 0;
+ if (init_relay_log_pos(rli,0,0,1 /*need data lock*/, &errmsg))
+ {
+ sql_print_error("Error initializing relay log position: %s",
+ errmsg);
+ goto err;
+ }
+ DBUG_ASSERT(rli->relay_log_pos >= BIN_LOG_HEADER_SIZE);
+ DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->relay_log_pos);
+ DBUG_ASSERT(rli->sql_thd == thd);
+
+ DBUG_PRINT("master_info",("log_file_name: %s position: %s",
+ rli->master_log_name,
+ llstr(rli->master_log_pos,llbuff)));
+
+ sql_print_error("Slave SQL thread initialized, starting replication in \
+log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
+ llstr(rli->master_log_pos,llbuff),rli->relay_log_name,
+ llstr(rli->relay_log_pos,llbuff1));
+ while (!sql_slave_killed(thd,rli))
+ {
+ thd->proc_info = "Processing master log event";
+ DBUG_ASSERT(rli->sql_thd == thd);
+ THD_CHECK_SENTRY(thd);
+ if (exec_relay_log_event(thd,rli))
+ {
+ // do not scare the user if SQL thread was simply killed or stopped
+ if (!sql_slave_killed(thd,rli))
+ sql_print_error("\
+Error running query, slave SQL thread aborted. Fix the problem, and restart \
+the slave SQL thread with \"SLAVE START\". We stopped at log \
+'%s' position %s",
+ RPL_LOG_NAME, llstr(rli->master_log_pos, llbuff));
+ goto err;
+ }
+ } // while (!sql_slave_killed(thd,rli)) - read/exec loop
// error = 0;
err:
// print the current replication position
- sql_print_error("Slave thread exiting, replication stopped in log '%s' at \
-position %s",
- RPL_LOG_NAME, llstr(glob_mi.pos,llbuff));
+ sql_print_error("Slave SQL thread exiting, replication stopped in log \
+ '%s' at position %s",
+ RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff));
thd->query = thd->db = 0; // extra safety
- if(mysql)
- mc_mysql_close(mysql);
thd->proc_info = "Waiting for slave mutex on exit";
- pthread_mutex_lock(&LOCK_slave);
- slave_running = 0;
- abort_slave = 0;
- save_temporary_tables = thd->temporary_tables;
+ pthread_mutex_lock(&rli->run_lock);
+ DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
+ rli->slave_running = 0;
+ rli->save_temporary_tables = thd->temporary_tables;
+
+ /*
+ TODO: see if we can do this conditionally in next_event() instead
+ to avoid unneeded position re-init
+ */
+ rli->log_pos_current=0;
thd->temporary_tables = 0; // remove tempation from destructor to close them
- pthread_cond_broadcast(&COND_slave_stopped); // tell the world we are done
- pthread_mutex_unlock(&LOCK_slave);
+ DBUG_ASSERT(thd->net.buff != 0);
net_end(&thd->net); // destructor will not free it, because we are weird
- slave_thd = 0;
+ DBUG_ASSERT(rli->sql_thd == thd);
+ THD_CHECK_SENTRY(thd);
+ rli->sql_thd = 0;
+ pthread_mutex_lock(&LOCK_thread_count);
+ THD_CHECK_SENTRY(thd);
delete thd;
- my_thread_end();
-#ifndef DBUG_OFF
- if(abort_slave_event_count && !events_till_abort)
+ pthread_mutex_unlock(&LOCK_thread_count);
+ my_thread_end(); // clean-up before broadcasting termination
+ pthread_cond_broadcast(&rli->stop_cond);
+ // tell the world we are done
+ pthread_mutex_unlock(&rli->run_lock);
+#ifndef DBUG_OFF // TODO: reconsider the code below
+ if (abort_slave_event_count && !rli->events_till_abort)
goto slave_begin;
#endif
pthread_exit(0);
DBUG_RETURN(0); // Can't return anything here
}
+static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
+{
+ int error = 1;
+ ulong num_bytes;
+ bool cev_not_written;
+ THD* thd;
+ NET* net = &mi->mysql->net;
+ DBUG_ENTER("process_io_create_file");
+
+ if (unlikely(!cev->is_valid()))
+ DBUG_RETURN(1);
+ /*
+ TODO: fix to honor table rules, not only db rules
+ */
+ if (!db_ok(cev->db, replicate_do_db, replicate_ignore_db))
+ {
+ skip_load_data_infile(net);
+ DBUG_RETURN(0);
+ }
+ DBUG_ASSERT(cev->inited_from_old);
+ thd = mi->io_thd;
+ thd->file_id = cev->file_id = mi->file_id++;
+ thd->server_id = cev->server_id;
+ cev_not_written = 1;
+
+ if (unlikely(net_request_file(net,cev->fname)))
+ {
+ sql_print_error("Slave I/O: failed requesting download of '%s'",
+ cev->fname);
+ goto err;
+ }
-/* try to connect until successful or slave killed */
+ /* this dummy block is so we could instantiate Append_block_log_event
+ once and then modify it slightly instead of doing it multiple times
+ in the loop
+ */
+ {
+ Append_block_log_event aev(thd,0,0);
+
+ for (;;)
+ {
+ if (unlikely((num_bytes=my_net_read(net)) == packet_error))
+ {
+ sql_print_error("Network read error downloading '%s' from master",
+ cev->fname);
+ goto err;
+ }
+ if (unlikely(!num_bytes)) /* eof */
+ {
+ send_ok(net); /* 3.23 master wants it */
+ Execute_load_log_event xev(thd);
+ xev.log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(&xev)))
+ {
+ sql_print_error("Slave I/O: error writing Exec_load event to \
+relay log");
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ break;
+ }
+ if (unlikely(cev_not_written))
+ {
+ cev->block = (char*)net->read_pos;
+ cev->block_len = num_bytes;
+ cev->log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(cev)))
+ {
+ sql_print_error("Slave I/O: error writing Create_file event to \
+relay log");
+ goto err;
+ }
+ cev_not_written=0;
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ }
+ else
+ {
+ aev.block = (char*)net->read_pos;
+ aev.block_len = num_bytes;
+ aev.log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(&aev)))
+ {
+ sql_print_error("Slave I/O: error writing Append_block event to \
+relay log");
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
+ }
+ }
+ }
+ error=0;
+err:
+ DBUG_RETURN(error);
+}
-static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
+/*
+ We assume we already locked mi->data_lock
+*/
+
+static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev)
{
- int slave_was_killed;
+ DBUG_ENTER("process_io_rotate");
+
+ if (unlikely(!rev->is_valid()))
+ DBUG_RETURN(1);
+ DBUG_ASSERT(rev->ident_len < sizeof(mi->master_log_name));
+ memcpy(mi->master_log_name,rev->new_log_ident,
+ rev->ident_len);
+ mi->master_log_name[rev->ident_len] = 0;
+ mi->master_log_pos = rev->pos;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
#ifndef DBUG_OFF
- events_till_disconnect = disconnect_slave_event_count;
-#endif
- while(!(slave_was_killed = slave_killed(thd)) &&
- !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
- mi->port, 0, 0))
+ /*
+ If we do not do this, we will be getting the first
+ rotate event forever, so we need to not disconnect after one.
+ */
+ if (disconnect_slave_event_count)
+ events_till_disconnect++;
+#endif
+ DBUG_RETURN(0);
+}
+
+/*
+ TODO: verify the issue with stop events, see if we need them at all
+ in the relay log
+ TODO: test this code before release - it has to be tested on a separte
+ setup with 3.23 master
+*/
+
+static int queue_old_event(MASTER_INFO *mi, const char *buf,
+ ulong event_len)
+{
+ const char *errmsg = 0;
+ bool inc_pos = 1;
+ bool processed_stop_event = 0;
+ char* tmp_buf = 0;
+ DBUG_ENTER("queue_old_event");
+
+ /* if we get Load event, we need to pass a non-reusable buffer
+ to read_log_event, so we do a trick
+ */
+ if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
{
- sql_print_error("Slave thread: error connecting to master: %s (%d),\
- retry in %d sec", mc_mysql_error(mysql), errno, mi->connect_retry);
- safe_sleep(thd, mi->connect_retry);
+ if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
+ {
+ sql_print_error("Slave I/O: out of memory for Load event");
+ DBUG_RETURN(1);
+ }
+ memcpy(tmp_buf,buf,event_len);
+ tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer
+ buf = (const char*)tmp_buf;
}
-
- if(!slave_was_killed)
+ Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
+ 1 /*old format*/ );
+ if (unlikely(!ev))
+ {
+ sql_print_error("Read invalid event from master: '%s',\
+ master could be corrupt but a more likely cause of this is a bug",
+ errmsg);
+ my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
+ DBUG_RETURN(1);
+ }
+ pthread_mutex_lock(&mi->data_lock);
+ ev->log_pos = mi->master_log_pos;
+ switch (ev->get_type_code()) {
+ case ROTATE_EVENT:
+ if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
{
- mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d",
- mi->user, mi->host, mi->port);
-#ifdef SIGNAL_WITH_VIO_CLOSE
- thd->set_active_vio(mysql->net.vio);
-#endif
+ delete ev;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_ASSERT(!tmp_buf);
+ DBUG_RETURN(1);
+ }
+ mi->ignore_stop_event=1;
+ inc_pos = 0;
+ break;
+ case STOP_EVENT:
+ processed_stop_event=1;
+ break;
+ case CREATE_FILE_EVENT:
+ {
+ int error = process_io_create_file(mi,(Create_file_log_event*)ev);
+ delete ev;
+ mi->master_log_pos += event_len;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_ASSERT(tmp_buf);
+ my_free((char*)tmp_buf, MYF(0));
+ DBUG_RETURN(error);
+ }
+ default:
+ mi->ignore_stop_event=0;
+ break;
+ }
+ if (likely(!processed_stop_event || !mi->ignore_stop_event))
+ {
+ if (unlikely(mi->rli.relay_log.append(ev)))
+ {
+ delete ev;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_ASSERT(!tmp_buf);
+ DBUG_RETURN(1);
}
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ }
+ delete ev;
+ if (likely(inc_pos))
+ mi->master_log_pos += event_len;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ if (unlikely(processed_stop_event))
+ mi->ignore_stop_event=1;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_ASSERT(!tmp_buf);
+ DBUG_RETURN(0);
+}
+
+/*
+ TODO: verify the issue with stop events, see if we need them at all
+ in the relay log
+*/
+
+int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
+{
+ int error=0;
+ bool inc_pos = 1;
+ bool processed_stop_event = 0;
+ DBUG_ENTER("queue_event");
+
+ if (mi->old_format)
+ DBUG_RETURN(queue_old_event(mi,buf,event_len));
+
+ pthread_mutex_lock(&mi->data_lock);
- return slave_was_killed;
+ /*
+ TODO: figure out if other events in addition to Rotate
+ require special processing
+ */
+ switch (buf[EVENT_TYPE_OFFSET]) {
+ case STOP_EVENT:
+ processed_stop_event=1;
+ break;
+ case ROTATE_EVENT:
+ {
+ Rotate_log_event rev(buf,event_len,0);
+ if (unlikely(process_io_rotate(mi,&rev)))
+ DBUG_RETURN(1);
+ inc_pos=0;
+ mi->ignore_stop_event=1;
+ break;
+ }
+ default:
+ mi->ignore_stop_event=0;
+ break;
+ }
+
+ if (likely((!processed_stop_event || !mi->ignore_stop_event) &&
+ !(error = mi->rli.relay_log.appendv(buf,event_len,0))))
+ {
+ if (likely(inc_pos))
+ mi->master_log_pos += event_len;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ }
+ if (unlikely(processed_stop_event))
+ mi->ignore_stop_event=1;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(error);
}
+
+void end_relay_log_info(RELAY_LOG_INFO* rli)
+{
+ if (!rli->inited)
+ return;
+ if (rli->info_fd >= 0)
+ {
+ end_io_cache(&rli->info_file);
+ (void)my_close(rli->info_fd, MYF(MY_WME));
+ rli->info_fd = -1;
+ }
+ if (rli->cur_log_fd >= 0)
+ {
+ end_io_cache(&rli->cache_buf);
+ (void)my_close(rli->cur_log_fd, MYF(MY_WME));
+ rli->cur_log_fd = -1;
+ }
+ rli->inited = 0;
+ rli->log_pos_current=0;
+ rli->relay_log.close(1);
+}
+
+/* try to connect until successful or slave killed */
+static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
+{
+ return connect_to_master(thd, mysql, mi, 0, 0);
+}
+
+
/*
Try to connect until successful or slave killed or we have retried
master_retry_count times
*/
-static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool suppress_warnings)
+static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool reconnect, bool suppress_warnings)
{
int slave_was_killed;
int last_errno= -2; // impossible error
ulong err_count=0;
char llbuff[22];
- /*
- If we lost connection after reading a state set event
- we will be re-reading it, so pending needs to be cleared
- */
- mi->pending = 0;
#ifndef DBUG_OFF
events_till_disconnect = disconnect_slave_event_count;
#endif
- while (!(slave_was_killed = slave_killed(thd)) && mc_mysql_reconnect(mysql))
+ while (!(slave_was_killed = io_slave_killed(thd,mi)) &&
+ (reconnect ? mc_mysql_reconnect(mysql) != 0 :
+ !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
+ mi->port, 0, 0,
+ thd->variables.net_read_timeout)))
{
/* Don't repeat last error */
if (mc_mysql_errno(mysql) != last_errno)
{
suppress_warnings= 0;
- sql_print_error("Slave thread: error re-connecting to master: \
-%s, last_errno=%d, retry in %d sec",
+ sql_print_error("Slave I/O thread: error connecting to master \
+'%s@%s:%d': \
+%s, last_errno=%d, retry in %d sec",mi->user,mi->host,mi->port,
mc_mysql_error(mysql), last_errno=mc_mysql_errno(mysql),
mi->connect_retry);
}
- safe_sleep(thd, mi->connect_retry);
- /* if master_retry_count is not set, keep trying until success */
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*)mi);
+ /*
+ By default we try forever. The reason is that failure will trigger
+ master election, so if the user did not set master_retry_count we
+ do not want to have electioin triggered on the first failure to
+ connect
+ */
if (master_retry_count && err_count++ == master_retry_count)
{
slave_was_killed=1;
+ if (reconnect)
+ change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER);
break;
}
}
if (!slave_was_killed)
{
- if (!suppress_warnings)
- sql_print_error("Slave: reconnected to master '%s@%s:%d',\
-replication resumed in log '%s' at position %s", glob_mi.user,
- glob_mi.host, glob_mi.port,
- RPL_LOG_NAME,
- llstr(glob_mi.pos,llbuff));
+ if (reconnect)
+ {
+ if (!suppress_warnings)
+ sql_print_error("Slave: connected to master '%s@%s:%d',\
+replication resumed in log '%s' at position %s", mi->user,
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
+ }
+ else
+ {
+ change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE);
+ mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d",
+ mi->user, mi->host, mi->port);
+ }
#ifdef SIGNAL_WITH_VIO_CLOSE
thd->set_active_vio(mysql->net.vio);
#endif
@@ -1598,6 +2503,263 @@ replication resumed in log '%s' at position %s", glob_mi.user,
return slave_was_killed;
}
+
+/*
+ Try to connect until successful or slave killed or we have retried
+ master_retry_count times
+*/
+
+static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool suppress_warnings)
+{
+ return connect_to_master(thd, mysql, mi, 1, suppress_warnings);
+}
+
+
+int flush_relay_log_info(RELAY_LOG_INFO* rli)
+{
+ register IO_CACHE* file = &rli->info_file;
+ char lbuf[22],lbuf1[22];
+
+ my_b_seek(file, 0L);
+ my_b_printf(file, "%s\n%s\n%s\n%s\n",
+ rli->relay_log_name, llstr(rli->relay_log_pos, lbuf),
+ rli->master_log_name, llstr(rli->master_log_pos, lbuf1)
+ );
+ flush_io_cache(file);
+ flush_io_cache(rli->cur_log);
+ return 0;
+}
+
+
+/*
+ This function is called when we notice that the current "hot" log
+ got rotated under our feet.
+*/
+
+static IO_CACHE *reopen_relay_log(RELAY_LOG_INFO *rli, const char **errmsg)
+{
+ DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
+ DBUG_ASSERT(rli->cur_log_fd == -1);
+ DBUG_ENTER("reopen_relay_log");
+
+ IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
+ if ((rli->cur_log_fd=open_binlog(cur_log,rli->relay_log_name,
+ errmsg)) <0)
+ DBUG_RETURN(0);
+ my_b_seek(cur_log,rli->relay_log_pos);
+ DBUG_RETURN(cur_log);
+}
+
+
+Log_event* next_event(RELAY_LOG_INFO* rli)
+{
+ Log_event* ev;
+ IO_CACHE* cur_log = rli->cur_log;
+ pthread_mutex_t *log_lock = rli->relay_log.get_log_lock();
+ const char* errmsg=0;
+ THD* thd = rli->sql_thd;
+ bool was_killed;
+ DBUG_ENTER("next_event");
+ DBUG_ASSERT(thd != 0);
+
+ /*
+ For most operations we need to protect rli members with data_lock,
+ so we will hold it for the most of the loop below
+ However, we will release it whenever it is worth the hassle,
+ and in the cases when we go into a pthread_cond_wait() with the
+ non-data_lock mutex
+ */
+ pthread_mutex_lock(&rli->data_lock);
+
+ while (!(was_killed=sql_slave_killed(thd,rli)))
+ {
+ /*
+ We can have two kinds of log reading:
+ hot_log:
+ rli->cur_log points at the IO_CACHE of relay_log, which
+ is actively being updated by the I/O thread. We need to be careful
+ in this case and make sure that we are not looking at a stale log that
+ has already been rotated. If it has been, we reopen the log.
+
+ The other case is much simpler:
+ We just have a read only log that nobody else will be updating.
+ */
+ bool hot_log;
+ if ((hot_log = (cur_log != &rli->cache_buf)))
+ {
+ DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor
+ pthread_mutex_lock(log_lock);
+
+ /*
+ Reading xxx_file_id is safe because the log will only
+ be rotated when we hold relay_log.LOCK_log
+ */
+ if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count)
+ {
+ // The master has switched to a new log file; Reopen the old log file
+ cur_log=reopen_relay_log(rli, &errmsg);
+ pthread_mutex_unlock(log_lock);
+ if (!cur_log) // No more log files
+ goto err;
+ hot_log=0; // Using old binary log
+ }
+ }
+ DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
+ DBUG_ASSERT(my_b_tell(cur_log) == rli->relay_log_pos + rli->pending);
+ /*
+ Relay log is always in new format - if the master is 3.23, the
+ I/O thread will convert the format for us
+ */
+ if ((ev=Log_event::read_log_event(cur_log,0,(bool)0 /* new format */)))
+ {
+ DBUG_ASSERT(thd==rli->sql_thd);
+ if (hot_log)
+ pthread_mutex_unlock(log_lock);
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(ev);
+ }
+ DBUG_ASSERT(thd==rli->sql_thd);
+ if (opt_reckless_slave) // For mysql-test
+ cur_log->error = 0;
+ if (cur_log->error < 0)
+ {
+ errmsg = "slave SQL thread aborted because of I/O error";
+ if (hot_log)
+ pthread_mutex_unlock(log_lock);
+ goto err;
+ }
+ if (!cur_log->error) /* EOF */
+ {
+ /*
+ On a hot log, EOF means that there are no more updates to
+ process and we must block until I/O thread adds some and
+ signals us to continue
+ */
+ if (hot_log)
+ {
+ DBUG_ASSERT(rli->relay_log.get_open_count() == rli->cur_log_old_open_count);
+ /*
+ We can, and should release data_lock while we are waiting for
+ update. If we do not, show slave status will block
+ */
+ pthread_mutex_unlock(&rli->data_lock);
+
+ /*
+ IMPORTANT: note that wait_for_update will unlock lock_log, but
+ expects the caller to lock it
+ */
+ rli->relay_log.wait_for_update(rli->sql_thd);
+
+ // re-acquire data lock since we released it earlier
+ pthread_mutex_lock(&rli->data_lock);
+ continue;
+ }
+ /*
+ If the log was not hot, we need to move to the next log in
+ sequence. The next log could be hot or cold, we deal with both
+ cases separately after doing some common initialization
+ */
+ end_io_cache(cur_log);
+ DBUG_ASSERT(rli->cur_log_fd >= 0);
+ my_close(rli->cur_log_fd, MYF(MY_WME));
+ rli->cur_log_fd = -1;
+
+ /*
+ TODO: make skip_log_purge a start-up option. At this point this
+ is not critical priority
+ */
+ if (!rli->skip_log_purge)
+ {
+ // purge_first_log will properly set up relay log coordinates in rli
+ if (rli->relay_log.purge_first_log(rli))
+ {
+ errmsg = "Error purging processed log";
+ goto err;
+ }
+ }
+ else
+ {
+ /*
+ TODO: verify that no lock is ok here. At this point, if we
+ get this wrong, this is actually no big deal - the only time
+ this code will ever be executed is if we are recovering from
+ a bug when a full reload of the slave is not feasible or
+ desirable.
+ */
+ if (rli->relay_log.find_next_log(&rli->linfo,0/*no lock*/))
+ {
+ errmsg = "error switching to the next log";
+ goto err;
+ }
+ rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
+ rli->pending=0;
+ strmake(rli->relay_log_name,rli->linfo.log_file_name,
+ sizeof(rli->relay_log_name)-1);
+ flush_relay_log_info(rli);
+ }
+
+ // next log is hot
+ if (rli->relay_log.is_active(rli->linfo.log_file_name))
+ {
+#ifdef EXTRA_DEBUG
+ sql_print_error("next log '%s' is currently active",
+ rli->linfo.log_file_name);
+#endif
+ rli->cur_log= cur_log= rli->relay_log.get_log_file();
+ rli->cur_log_old_open_count= rli->relay_log.get_open_count();
+ DBUG_ASSERT(rli->cur_log_fd == -1);
+
+ /*
+ Read pointer has to be at the start since we are the only
+ reader
+ */
+ if (check_binlog_magic(cur_log,&errmsg))
+ goto err;
+ continue;
+ }
+ /*
+ if we get here, the log was not hot, so we will have to
+ open it ourselves
+ */
+#ifdef EXTRA_DEBUG
+ sql_print_error("next log '%s' is not active",
+ rli->linfo.log_file_name);
+#endif
+ // open_binlog() will check the magic header
+ if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name,
+ &errmsg)) <0)
+ goto err;
+ }
+ else
+ {
+ /*
+ Read failed with a non-EOF error.
+ TODO: come up with something better to handle this error
+ */
+ if (hot_log)
+ pthread_mutex_unlock(log_lock);
+ sql_print_error("Slave SQL thread: I/O error reading \
+event(errno: %d cur_log->error: %d)",
+ my_errno,cur_log->error);
+ // set read position to the beginning of the event
+ my_b_seek(cur_log,rli->relay_log_pos+rli->pending);
+ /* otherwise, we have had a partial read */
+ errmsg = "Aborting slave SQL thread because of partial event read";
+ /* TODO; see if there is a way to do this without this goto */
+ goto err;
+ }
+ }
+ if (!errmsg && was_killed)
+ errmsg = "slave SQL thread was killed";
+
+err:
+ pthread_mutex_unlock(&rli->data_lock);
+ sql_print_error("Error reading relay log event: %s", errmsg);
+ DBUG_RETURN(0);
+}
+
+
#ifdef __GNUC__
template class I_List_iterator<i_string>;
template class I_List_iterator<i_string_pair>;
diff --git a/sql/slave.h b/sql/slave.h
index 769689ebfa2..e6a5e86bb10 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -1,71 +1,314 @@
#ifndef SLAVE_H
#define SLAVE_H
+#include "mysql.h"
+#include "my_list.h"
#define SLAVE_NET_TIMEOUT 3600
+#define MAX_SLAVE_ERRMSG 1024
#define MAX_SLAVE_ERROR 2000
+/*
+ The replication is accomplished by starting two threads - I/O
+ thread, and SQL thread. I/O thread is associated with its
+ MASTER_INFO struct, so MASTER_INFO can be viewed as I/O thread
+ descriptor. SQL thread is associated with RELAY_LOG_INFO struct.
+
+ I/O thread reads maintains a connection to the master, and reads log
+ events from the master as they arrive, queueing them by writing them
+ out into the temporary slave binary log (relay log). The SQL thread,
+ in turn, reads the slave binary log executing each event.
+
+ Relay log is needed to be able to handle situations when there is a large
+ backlog of unprocessed events from the master (eg. one particular update
+ takes a day to finish), and to be able to restart the slave server without
+ having to re-read the master updates.
+ */
+
extern ulong slave_net_timeout, master_retry_count;
extern MY_BITMAP slave_error_mask;
extern bool use_slave_mask;
+extern char* slave_load_tmpdir;
+extern my_string master_info_file,relay_log_info_file;
+extern my_string opt_relay_logname, opt_relaylog_index_name;
+extern bool opt_skip_slave_start, opt_reckless_slave;
+extern ulong relay_log_space_limit;
+struct st_master_info;
-typedef struct st_master_info
+/*
+ TODO: this needs to be redone, but for now it does not matter since
+ we do not have multi-master yet.
+*/
+
+#define LOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
+ ++active_mi_in_use; \
+ pthread_mutex_unlock(&LOCK_active_mi);}
+
+#define UNLOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
+ --active_mi_in_use; \
+ pthread_mutex_unlock(&LOCK_active_mi); }
+
+/*
+ st_relay_log_info contains information on the current relay log and
+ relay log offset, and master log name and log sequence corresponding to the
+ last update. Additionally, misc information specific to the SQL thread is
+ included.
+
+ st_relay_log_info is initialized from the slave.info file if such exists.
+ Otherwise, data members are intialized with defaults. The initialization is
+ done with init_relay_log_info() call.
+
+ The format of slave.info file:
+
+ relay_log_name
+ relay_log_pos
+ master_log_name
+ master_log_pos
+
+ To clean up, call end_relay_log_info()
+ */
+
+typedef struct st_relay_log_info
{
- char log_file_name[FN_REFLEN];
- ulonglong pos,pending;
- int event_len; /* Added by Heikki: InnoDB internally stores the
- master log position it has processed so far; the
- position to store is really the sum
- pos + pending + event_len
- here since we must store the pos of the END of the
- current log event */
- File fd; // we keep the file open, so we need to remember the file pointer
- IO_CACHE file;
- // the variables below are needed because we can change masters on the fly
- char host[HOSTNAME_LENGTH+1];
- char user[USERNAME_LENGTH+1];
- char password[HASH_PASSWORD_LENGTH+1];
- uint port;
- uint connect_retry;
- pthread_mutex_t lock;
- pthread_cond_t cond;
+ /*** The following variables can only be read when protect by data lock ****/
+
+ /*
+ info_fd - file descriptor of the info file. set only during
+ initialization or clean up - safe to read anytime
+ cur_log_fd - file descriptor of the current read relay log
+ */
+ File info_fd,cur_log_fd;
+ /* name of current read relay log */
+ char relay_log_name[FN_REFLEN];
+ /* master log name corresponding to current read position */
+ char master_log_name[FN_REFLEN];
+ /* original log position of last processed event */
+ volatile my_off_t master_log_pos;
+
+ /*
+ Protected with internal locks.
+ Must get data_lock when resetting the logs.
+ */
+ MYSQL_LOG relay_log;
+ LOG_INFO linfo;
+ IO_CACHE cache_buf,*cur_log;
+
+ /* The following variables are safe to read any time */
+
+ /* IO_CACHE of the info file - set only during init or end */
+ IO_CACHE info_file;
+
+ /*
+ When we restart slave thread we need to have access to the previously
+ created temporary tables. Modified only on init/end and by the SQL
+ thread, read only by SQL thread.
+ */
+ TABLE* save_temporary_tables;
+
+ /*
+ standard lock acquistion order to avoid deadlocks:
+ run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
+ */
+ pthread_mutex_t data_lock,run_lock;
+
+ /*
+ start_cond is broadcast when SQL thread is started
+ stop_cond - when stopped
+ data_cond - when data protected by data_lock changes
+ */
+ pthread_cond_t start_cond, stop_cond, data_cond;
+
+ /* parent master info structure */
+ struct st_master_info *mi;
+
+ /*
+ Needed to deal properly with cur_log getting closed and re-opened with
+ a different log under our feet
+ */
+ uint32 cur_log_old_open_count;
+
+ /*
+ Current offset in the relay log.
+ pending - in some cases we do not increment offset immediately after
+ processing an event, because the following event needs to be processed
+ atomically together with this one ( so far, there is only one type of
+ such event - Intvar_event that sets auto_increment value). However, once
+ both events have been processed, we need to increment by the cumulative
+ offset. pending stored the extra offset to be added to the position.
+ */
+ ulonglong relay_log_pos, pending;
+ ulonglong log_space_limit,log_space_total;
+
+ /*
+ Needed for problems when slave stops and we want to restart it
+ skipping one or more events in the master log that have caused
+ errors, and have been manually applied by DBA already.
+ */
+ volatile uint32 slave_skip_counter;
+ pthread_mutex_t log_space_lock;
+ pthread_cond_t log_space_cond;
+ THD * sql_thd;
+ int last_slave_errno;
+#ifndef DBUG_OFF
+ int events_till_abort;
+#endif
+ char last_slave_error[MAX_SLAVE_ERRMSG];
+
+ /* if not set, the value of other members of the structure are undefined */
bool inited;
+ volatile bool abort_slave, slave_running;
+ bool log_pos_current;
+ bool abort_pos_wait;
+ bool skip_log_purge;
- st_master_info():pending(0),fd(-1),inited(0)
+ st_relay_log_info()
+ :info_fd(-1),cur_log_fd(-1), cur_log_old_open_count(0),
+ inited(0), abort_slave(0), slave_running(0), log_pos_current(0),
+ abort_pos_wait(0), skip_log_purge(0)
{
- host[0] = 0; user[0] = 0; password[0] = 0;
- pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&cond, NULL);
+ relay_log_name[0] = master_log_name[0] = 0;
+ bzero(&info_file,sizeof(info_file));
+ pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&log_space_lock, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&data_cond, NULL);
+ pthread_cond_init(&start_cond, NULL);
+ pthread_cond_init(&stop_cond, NULL);
+ pthread_cond_init(&log_space_cond, NULL);
}
-
- ~st_master_info()
+ ~st_relay_log_info()
{
- pthread_mutex_destroy(&lock);
- pthread_cond_destroy(&cond);
- }
+ pthread_mutex_destroy(&run_lock);
+ pthread_mutex_destroy(&data_lock);
+ pthread_mutex_destroy(&log_space_lock);
+ pthread_cond_destroy(&data_cond);
+ pthread_cond_destroy(&start_cond);
+ pthread_cond_destroy(&stop_cond);
+ pthread_cond_destroy(&log_space_cond);
+ }
inline void inc_pending(ulonglong val)
{
pending += val;
}
- inline void inc_pos(ulonglong val)
+ /* TODO: this probably needs to be fixed */
+ inline void inc_pos(ulonglong val, ulonglong log_pos, bool skip_lock=0)
{
- pthread_mutex_lock(&lock);
- pos += val + pending;
+ if (!skip_lock)
+ pthread_mutex_lock(&data_lock);
+ relay_log_pos += val+pending;
pending = 0;
- pthread_cond_broadcast(&cond);
- pthread_mutex_unlock(&lock);
+ if (log_pos)
+ master_log_pos = log_pos+ val;
+ pthread_cond_broadcast(&data_cond);
+ if (!skip_lock)
+ pthread_mutex_unlock(&data_lock);
}
- // thread safe read of position - not needed if we are in the slave thread,
- // but required otherwise
+ /*
+ thread safe read of position - not needed if we are in the slave thread,
+ but required otherwise
+ */
inline void read_pos(ulonglong& var)
{
- pthread_mutex_lock(&lock);
- var = pos;
- pthread_mutex_unlock(&lock);
+ pthread_mutex_lock(&data_lock);
+ var = relay_log_pos;
+ pthread_mutex_unlock(&data_lock);
}
int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos);
+} RELAY_LOG_INFO;
+
+Log_event* next_event(RELAY_LOG_INFO* rli);
+
+/*
+ st_master_info contains information about how to connect to a master,
+ current master log name, and current log offset, as well as misc
+ control variables
+
+ st_master_info is initialized once from the master.info file if such
+ exists. Otherwise, data members corresponding to master.info fields
+ are initialized with defaults specified by master-* options. The
+ initialization is done through init_master_info() call.
+
+ The format of master.info file:
+
+ log_name
+ log_pos
+ master_host
+ master_user
+ master_pass
+ master_port
+ master_connect_retry
+
+ To write out the contents of master.info file to disk ( needed every
+ time we read and queue data from the master ), a call to
+ flush_master_info() is required.
+
+ To clean up, call end_master_info()
+*/
+
+
+typedef struct st_master_info
+{
+ char master_log_name[FN_REFLEN];
+
+ my_off_t master_log_pos;
+ File fd;
+
+ /*
+ InnoDB internally stores the master log position it has processed
+ so far; the position to store is really the sum of
+ pos + pending + event_len here since we must store the pos of the
+ END of the current log event
+*/
+ int event_len;
+ File fd;
+ IO_CACHE file;
+
+ /* the variables below are needed because we can change masters on the fly */
+ char host[HOSTNAME_LENGTH+1];
+ char user[USERNAME_LENGTH+1];
+ char password[HASH_PASSWORD_LENGTH+1];
+ pthread_mutex_t data_lock,run_lock;
+ pthread_cond_t data_cond,start_cond,stop_cond;
+ THD *io_thd;
+ MYSQL* mysql;
+ uint32 file_id; /* for 3.23 load data infile */
+ RELAY_LOG_INFO rli;
+ uint port;
+ uint connect_retry;
+#ifndef DBUG_OFF
+ int events_till_abort;
+#endif
+ bool inited;
+ bool old_format; /* master binlog is in 3.23 format */
+ volatile bool abort_slave, slave_running;
+ bool ignore_stop_event;
+
+
+ st_master_info():fd(-1), io_thd(0), inited(0), old_format(0),abort_slave(0),
+ slave_running(0)
+ {
+ host[0] = 0; user[0] = 0; password[0] = 0;
+ bzero(&file,sizeof(file));
+ pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&data_cond, NULL);
+ pthread_cond_init(&start_cond, NULL);
+ pthread_cond_init(&stop_cond, NULL);
+ }
+
+ ~st_master_info()
+ {
+ pthread_mutex_destroy(&run_lock);
+ pthread_mutex_destroy(&data_lock);
+ pthread_cond_destroy(&data_cond);
+ pthread_cond_destroy(&start_cond);
+ pthread_cond_destroy(&stop_cond);
+ }
+
} MASTER_INFO;
+int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
+
typedef struct st_table_rule_ent
{
char* db;
@@ -75,64 +318,116 @@ typedef struct st_table_rule_ent
#define TABLE_RULE_HASH_SIZE 16
#define TABLE_RULE_ARR_SIZE 16
+#define MAX_SLAVE_ERRMSG 1024
+
+#define RPL_LOG_NAME (rli->master_log_name[0] ? rli->master_log_name :\
+ "FIRST")
+#define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\
+ "FIRST")
+
+/* masks for start/stop operations on io and sql slave threads */
+#define SLAVE_IO 1
+#define SLAVE_SQL 2
+/*
+ If the following is set, if first gives an error, second will be
+ tried. Otherwise, if first fails, we fail.
+*/
+#define SLAVE_FORCE_ALL 4
+
+int init_slave();
+void init_slave_skip_errors(const char* arg);
int flush_master_info(MASTER_INFO* mi);
+int flush_relay_log_info(RELAY_LOG_INFO* rli);
+int register_slave_on_master(MYSQL* mysql);
+int terminate_slave_threads(MASTER_INFO* mi, int thread_mask,
+ bool skip_lock = 0);
+int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex,
+ pthread_mutex_t* cond_lock,
+ pthread_cond_t* term_cond,
+ volatile bool* slave_running);
+int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
+ MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname, int thread_mask);
+/*
+ cond_lock is usually same as start_lock. It is needed for the case when
+ start_lock is 0 which happens if start_slave_thread() is called already
+ inside the start_lock section, but at the same time we want a
+ pthread_cond_wait() on start_cond,start_lock
+*/
+int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock,
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t* start_cond,
+ volatile bool* slave_running,
+ MASTER_INFO* mi);
+
+/* If fd is -1, dump to NET */
+int mysql_table_dump(THD* thd, const char* db,
+ const char* tbl_name, int fd = -1);
+
+/* retrieve non-exitent table from master */
+int fetch_master_table(THD* thd, const char* db_name, const char* table_name,
+ MASTER_INFO* mi, MYSQL* mysql);
-int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd = -1);
-// if fd is -1, dump to NET
-int fetch_nx_table(THD* thd, MASTER_INFO* mi);
-// retrieve non-exitent table from master
-// the caller must set thd->last_nx_table and thd->last_nx_db first
-int show_master_info(THD* thd);
+int show_master_info(THD* thd, MASTER_INFO* mi);
int show_binlog_info(THD* thd);
+/* See if the query uses any tables that should not be replicated */
int tables_ok(THD* thd, TABLE_LIST* tables);
-// see if the query uses any tables that should not be replicated
+/*
+ Check to see if the database is ok to operate on with respect to the
+ do and ignore lists - used in replication
+*/
int db_ok(const char* db, I_List<i_string> &do_list,
I_List<i_string> &ignore_list );
-// check to see if the database is ok to operate on with respect to the
-// do and ignore lists - used in replication
int add_table_rule(HASH* h, const char* table_spec);
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
-void init_slave_skip_errors(char* arg);
+char* rewrite_db(char* db);
+int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
+void skip_load_data_infile(NET* net);
+void slave_print_error(RELAY_LOG_INFO* rli,int err_code, const char* msg, ...);
-void end_slave(); // clean up
-int init_master_info(MASTER_INFO* mi);
+void end_slave(); /* clean up */
+int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname);
void end_master_info(MASTER_INFO* mi);
+int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
+void end_relay_log_info(RELAY_LOG_INFO* rli);
+void lock_slave_threads(MASTER_INFO* mi);
+void unlock_slave_threads(MASTER_INFO* mi);
+void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse);
+int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos,
+ bool need_data_lock, const char** errmsg);
+
+int purge_relay_logs(RELAY_LOG_INFO* rli,bool just_reset,const char** errmsg);
+
extern bool opt_log_slave_updates ;
-pthread_handler_decl(handle_slave,arg);
-extern bool volatile abort_loop, abort_slave, slave_running;
-extern uint32 slave_skip_counter;
-// needed for problems when slave stops and
-// we want to restart it skipping one or more events in the master log that
-// have caused errors, and have been manually applied by DBA already
-
-extern pthread_t slave_real_id;
-extern THD* slave_thd;
-extern MASTER_INFO glob_mi;
+pthread_handler_decl(handle_slave_io,arg);
+pthread_handler_decl(handle_slave_sql,arg);
+extern bool volatile abort_loop;
+extern MASTER_INFO main_mi, *active_mi; /* active_mi for multi-master */
+extern volatile int active_mi_in_use;
+extern LIST master_list;
extern HASH replicate_do_table, replicate_ignore_table;
extern DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
extern bool do_table_inited, ignore_table_inited,
wild_do_table_inited, wild_ignore_table_inited;
extern bool table_rules_on;
-#ifndef DBUG_OFF
extern int disconnect_slave_event_count, abort_slave_event_count ;
-#endif
-// the master variables are defaults read from my.cnf or command line
-extern uint master_port, master_connect_retry;
+/* the master variables are defaults read from my.cnf or command line */
+extern uint master_port, master_connect_retry, report_port;
extern my_string master_user, master_password, master_host,
- master_info_file;
+ master_info_file, relay_log_info_file, report_user, report_host,
+ report_password;
extern I_List<i_string> replicate_do_db, replicate_ignore_db;
extern I_List<i_string_pair> replicate_rewrite_db;
extern I_List<THD> threads;
#endif
-
-
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index edfc2ceeab8..0b02935e96c 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -29,24 +29,25 @@
#include "sql_acl.h"
#include "hash_filo.h"
#include <m_ctype.h>
+#include <assert.h>
#include <stdarg.h>
-/*
- ACL_HOST is used if no host is specified
- */
-
struct acl_host_and_ip
{
char *hostname;
long ip,ip_mask; // Used with masked ip:s
};
+
class ACL_ACCESS {
public:
ulong sort;
- uint access;
+ ulong access;
};
+
+/* ACL_HOST is used if no host is specified */
+
class ACL_HOST :public ACL_ACCESS
{
public:
@@ -54,15 +55,22 @@ public:
char *db;
};
+
class ACL_USER :public ACL_ACCESS
{
public:
acl_host_and_ip host;
uint hostname_length;
+ USER_RESOURCES user_resource;
char *user,*password;
ulong salt[2];
+#ifdef HAVE_OPENSSL
+ enum SSL_type ssl_type;
+ const char *ssl_cipher, *x509_issuer, *x509_subject;
+#endif /* HAVE_OPENSSL */
};
+
class ACL_DB :public ACL_ACCESS
{
public:
@@ -70,14 +78,16 @@ public:
char *user,*db;
};
+
class acl_entry :public hash_filo_element
{
public:
- uint access;
+ ulong access;
uint16 length;
char key[1]; // Key will be stored here
};
+
static byte* acl_entry_get_key(acl_entry *entry,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -95,7 +105,7 @@ static HASH acl_check_hosts, hash_tables;
static DYNAMIC_ARRAY acl_wild_hosts;
static hash_filo *acl_cache;
static uint grant_version=0;
-static uint get_access(TABLE *form,uint fieldnr);
+static ulong get_access(TABLE *form,uint fieldnr);
static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b);
static ulong get_sort(uint count,...);
static void init_check_host(void);
@@ -106,7 +116,33 @@ static void update_hostname(acl_host_and_ip *host, const char *hostname);
static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
const char *ip);
-int acl_init(bool dont_read_acl_tables)
+extern char uc_update_queries[SQLCOM_END];
+
+static void init_update_queries(void)
+{
+ uc_update_queries[SQLCOM_CREATE_TABLE]=1;
+ uc_update_queries[SQLCOM_CREATE_INDEX]=1;
+ uc_update_queries[SQLCOM_ALTER_TABLE]=1;
+ uc_update_queries[SQLCOM_UPDATE]=1;
+ uc_update_queries[SQLCOM_INSERT]=1;
+ uc_update_queries[SQLCOM_INSERT_SELECT]=1;
+ uc_update_queries[SQLCOM_DELETE]=1;
+ uc_update_queries[SQLCOM_TRUNCATE]=1;
+ uc_update_queries[SQLCOM_DROP_TABLE]=1;
+ uc_update_queries[SQLCOM_LOAD]=1;
+ uc_update_queries[SQLCOM_CREATE_DB]=1;
+ uc_update_queries[SQLCOM_DROP_DB]=1;
+ uc_update_queries[SQLCOM_REPLACE]=1;
+ uc_update_queries[SQLCOM_REPLACE_SELECT]=1;
+ uc_update_queries[SQLCOM_RENAME_TABLE]=1;
+ uc_update_queries[SQLCOM_BACKUP_TABLE]=1;
+ uc_update_queries[SQLCOM_RESTORE_TABLE]=1;
+ uc_update_queries[SQLCOM_DELETE_MULTI]=1;
+ uc_update_queries[SQLCOM_DROP_INDEX]=1;
+ uc_update_queries[SQLCOM_MULTI_UPDATE]=1;
+}
+
+int acl_init(bool dont_read_acl_tables)
{
THD *thd;
TABLE_LIST tables[3];
@@ -128,7 +164,8 @@ int acl_init(bool dont_read_acl_tables)
thd->mysys_var=my_thread_var;
thd->current_tablenr=0;
thd->open_tables=0;
- thd->db=my_strdup("mysql",MYF(0));
+ thd->db= my_strdup("mysql",MYF(0));
+ thd->db_length=5; // Safety
bzero((char*) &tables,sizeof(tables));
tables[0].name=tables[0].real_name=(char*) "host";
tables[1].name=tables[1].real_name=(char*) "user";
@@ -163,10 +200,10 @@ int acl_init(bool dont_read_acl_tables)
{
ACL_HOST host;
update_hostname(&host.host,get_field(&mem, table,0));
- host.db=get_field(&mem, table,1);
- host.access=get_access(table,2);
- host.access=fix_rights_for_db(host.access);
- host.sort=get_sort(2,host.host.hostname,host.db);
+ host.db= get_field(&mem, table,1);
+ host.access= get_access(table,2);
+ host.access= fix_rights_for_db(host.access);
+ host.sort= get_sort(2,host.host.hostname,host.db);
#ifndef TO_BE_REMOVED
if (table->fields == 8)
{ // Without grant
@@ -191,6 +228,7 @@ int acl_init(bool dont_read_acl_tables)
protocol_version=9; /* purecov: tested */
}
+ DBUG_PRINT("info",("user table fields: %d",table->fields));
allow_all_hosts=0;
while (!(read_record_info.read_record(&read_record_info)))
{
@@ -203,7 +241,7 @@ int acl_init(bool dont_read_acl_tables)
protocol_version == PROTOCOL_VERSION)
{
sql_print_error(
- "Found old style password for user '%s'. Ignoring user. (You may want to restart using --old-protocol)",
+ "Found old style password for user '%s'. Ignoring user. (You may want to restart mysqld using --old-protocol)",
user.user ? user.user : ""); /* purecov: tested */
}
else if (length % 8) // This holds true for passwords
@@ -212,19 +250,60 @@ int acl_init(bool dont_read_acl_tables)
"Found invalid password for user: '%s@%s'; Ignoring user",
user.user ? user.user : "",
user.host.hostname ? user.host.hostname : ""); /* purecov: tested */
- continue; /* purecov: tested */
+ continue; /* purecov: tested */
}
get_salt_from_password(user.salt,user.password);
user.access=get_access(table,3);
user.sort=get_sort(2,user.host.hostname,user.user);
- user.hostname_length=user.host.hostname ? (uint) strlen(user.host.hostname) : 0;
-#ifndef TO_BE_REMOVED
- if (table->fields <= 13)
- { // Without grant
- if (user.access & CREATE_ACL)
- user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
+ user.hostname_length= (user.host.hostname ?
+ (uint) strlen(user.host.hostname) : 0);
+ if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
+ {
+#ifdef HAVE_OPENSSL
+ char *ssl_type=get_field(&mem, table, 24);
+ if (!ssl_type)
+ user.ssl_type=SSL_TYPE_NONE;
+ else if (!strcmp(ssl_type, "ANY"))
+ user.ssl_type=SSL_TYPE_ANY;
+ else if (!strcmp(ssl_type, "X509"))
+ user.ssl_type=SSL_TYPE_X509;
+ else /* !strcmp(ssl_type, "SPECIFIED") */
+ user.ssl_type=SSL_TYPE_SPECIFIED;
+
+ user.ssl_cipher= get_field(&mem, table, 25);
+ user.x509_issuer= get_field(&mem, table, 26);
+ user.x509_subject= get_field(&mem, table, 27);
+#endif
+ char *ptr = get_field(&mem, table, 28);
+ user.user_resource.questions=atoi(ptr);
+ ptr = get_field(&mem, table, 29);
+ user.user_resource.updates=atoi(ptr);
+ ptr = get_field(&mem, table, 30);
+ user.user_resource.connections=atoi(ptr);
+ if (user.user_resource.questions || user.user_resource.updates ||
+ user.user_resource.connections)
+ mqh_used=1;
}
+ else
+ {
+#ifdef HAVE_OPENSSL
+ user.ssl_type=SSL_TYPE_NONE;
+#endif
+ bzero(&(user.user_resource),sizeof(user.user_resource));
+#ifndef TO_BE_REMOVED
+ if (table->fields <= 13)
+ { // Without grant
+ if (user.access & CREATE_ACL)
+ user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
+ }
+ /* Convert old privileges */
+ user.access|= LOCK_TABLES_ACL | CREATE_TMP_ACL | SHOW_DB_ACL;
+ if (user.access & FILE_ACL)
+ user.access|= REPL_CLIENT_ACL | REPL_SLAVE_ACL;
+ if (user.access & PROCESS_ACL)
+ user.access|= SUPER_ACL | EXECUTE_ACL;
#endif
+ }
VOID(push_dynamic(&acl_users,(gptr) &user));
if (!user.host.hostname || user.host.hostname[0] == wild_many &&
!user.host.hostname[1])
@@ -262,6 +341,7 @@ int acl_init(bool dont_read_acl_tables)
init_check_host();
mysql_unlock_tables(thd, lock);
+ init_update_queries();
thd->version--; // Force close to free memory
close_thread_tables(thd);
delete thd;
@@ -334,31 +414,38 @@ void acl_reload(void)
}
-/* Get all access bits from table after fieldnr */
+/*
+ Get all access bits from table after fieldnr
+ We know that the access privileges ends when there is no more fields
+ or the field is not an enum with two elements.
+*/
-static uint get_access(TABLE *form,uint fieldnr)
+static ulong get_access(TABLE *form, uint fieldnr)
{
- uint access_bits=0,bit;
+ ulong access_bits=0,bit;
char buff[2];
String res(buff,sizeof(buff));
Field **pos;
- for (pos=form->field+fieldnr,bit=1 ; *pos ; pos++ , bit<<=1)
+ for (pos=form->field+fieldnr, bit=1;
+ *pos && (*pos)->real_type() == FIELD_TYPE_ENUM &&
+ ((Field_enum*) (*pos))->typelib->count == 2 ;
+ pos++ , bit<<=1)
{
(*pos)->val_str(&res,&res);
if (toupper(res[0]) == 'Y')
- access_bits|=bit;
+ access_bits|= bit;
}
return access_bits;
}
/*
- return a number which, if sorted 'desc', puts strings in this order:
- no wildcards
- wildcards
- empty string
- */
+ Return a number which, if sorted 'desc', puts strings in this order:
+ no wildcards
+ wildcards
+ empty string
+*/
static ulong get_sort(uint count,...)
{
@@ -398,18 +485,22 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
}
-/* Get master privilges for user (priviliges for all tables) */
-
+/*
+ Get master privilges for user (priviliges for all tables).
+ Required before connecting to MySQL
+*/
-uint acl_getroot(const char *host, const char *ip, const char *user,
- const char *password,const char *message,char **priv_user,
- bool old_ver)
+ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
+ const char *password,const char *message,char **priv_user,
+ bool old_ver, USER_RESOURCES *mqh)
{
- uint user_access=NO_ACCESS;
+ ulong user_access=NO_ACCESS;
*priv_user=(char*) user;
+ char *ptr=0;
+ bzero(mqh,sizeof(USER_RESOURCES));
if (!initialized)
- return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
+ return (ulong) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
VOID(pthread_mutex_lock(&acl_cache->lock));
/*
@@ -428,7 +519,92 @@ uint acl_getroot(const char *host, const char *ip, const char *user,
!check_scramble(password,message,acl_user->salt,
(my_bool) old_ver)))
{
+#ifdef HAVE_OPENSSL
+ Vio *vio=thd->net.vio;
+ /*
+ In this point we know that user is allowed to connect
+ from given host by given username/password pair. Now
+ we check if SSL is required, if user is using SSL and
+ if X509 certificate attributes are OK
+ */
+ switch (acl_user->ssl_type) {
+ case SSL_TYPE_NONE: /* SSL is not required to connect */
+ user_access=acl_user->access;
+ break;
+ case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
+ if (vio_type(vio) == VIO_TYPE_SSL)
+ user_access=acl_user->access;
+ break;
+ case SSL_TYPE_X509: /* Client should have any valid certificate. */
+ /*
+ Connections with non-valid certificates are dropped already
+ in sslaccept() anyway, so we do not check validity here.
+ */
+ if (SSL_get_peer_certificate(vio->ssl_))
+ user_access=acl_user->access;
+ break;
+ case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
+ /*
+ We do not check for absence of SSL because without SSL it does
+ not pass all checks here anyway.
+ If cipher name is specified, we compare it to actual cipher in
+ use.
+ */
+ if (acl_user->ssl_cipher)
+ DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
+ acl_user->ssl_cipher,
+ SSL_get_cipher(vio->ssl_)));
+ if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_)))
+ user_access=acl_user->access;
+ else
+ {
+ user_access=NO_ACCESS;
+ break;
+ }
+ /* Prepare certificate (if exists) */
+ DBUG_PRINT("info",("checkpoint 1"));
+ X509* cert=SSL_get_peer_certificate(vio->ssl_);
+ DBUG_PRINT("info",("checkpoint 2"));
+ /* If X509 issuer is speified, we check it... */
+ if (acl_user->x509_issuer)
+ {
+ DBUG_PRINT("info",("checkpoint 3"));
+ ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
+ acl_user->x509_issuer, ptr));
+ if (!strcmp(acl_user->x509_issuer,ptr))
+ user_access=acl_user->access;
+ else
+ {
+ user_access=NO_ACCESS;
+ free(ptr);
+ break;
+ }
+ free(ptr);
+ }
+ DBUG_PRINT("info",("checkpoint 4"));
+ /* X509 subject is specified, we check it .. */
+ if (acl_user->x509_subject)
+ {
+ ptr = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing subjects: '%s' and '%s'",
+ acl_user->x509_subject, ptr));
+ if (!strcmp(acl_user->x509_subject,ptr))
+ user_access=acl_user->access;
+ else
+ {
+ user_access=NO_ACCESS;
+ free(ptr);
+ break;
+ }
+ free(ptr);
+ }
+ break;
+ }
+#else /* HAVE_OPENSSL */
user_access=acl_user->access;
+#endif /* HAVE_OPENSSL */
+ *mqh=acl_user->user_resource;
if (!acl_user->user)
*priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */
break;
@@ -457,7 +633,13 @@ static byte* check_get_key(ACL_USER *buff,uint *length,
}
static void acl_update_user(const char *user, const char *host,
- const char *password, uint privileges)
+ const char *password,
+ enum SSL_type ssl_type,
+ const char *ssl_cipher,
+ const char *x509_issuer,
+ const char *x509_subject,
+ USER_RESOURCES *mqh,
+ ulong privileges)
{
for (uint i=0 ; i < acl_users.elements ; i++)
{
@@ -470,6 +652,18 @@ static void acl_update_user(const char *user, const char *host,
acl_user->host.hostname && !strcmp(host,acl_user->host.hostname))
{
acl_user->access=privileges;
+ if (mqh->bits & 1)
+ acl_user->user_resource.questions=mqh->questions;
+ if (mqh->bits & 2)
+ acl_user->user_resource.updates=mqh->updates;
+ if (mqh->bits & 4)
+ acl_user->user_resource.connections=mqh->connections;
+#ifdef HAVE_OPENSSL
+ acl_user->ssl_type=ssl_type;
+ acl_user->ssl_cipher=ssl_cipher;
+ acl_user->x509_issuer=x509_issuer;
+ acl_user->x509_subject=x509_subject;
+#endif /* HAVE_OPENSSL */
if (password)
{
if (!password[0])
@@ -488,16 +682,28 @@ static void acl_update_user(const char *user, const char *host,
static void acl_insert_user(const char *user, const char *host,
- const char *password,
- uint privileges)
+ const char *password,
+ enum SSL_type ssl_type,
+ const char *ssl_cipher,
+ const char *x509_issuer,
+ const char *x509_subject,
+ USER_RESOURCES *mqh,
+ ulong privileges)
{
ACL_USER acl_user;
acl_user.user=strdup_root(&mem,user);
update_hostname(&acl_user.host,strdup_root(&mem,host));
acl_user.password=0;
acl_user.access=privileges;
+ acl_user.user_resource = *mqh;
acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user);
acl_user.hostname_length=(uint) strlen(acl_user.host.hostname);
+#ifdef HAVE_OPENSSL
+ acl_user.ssl_type=ssl_type;
+ acl_user.ssl_cipher=ssl_cipher;
+ acl_user.x509_issuer=x509_issuer;
+ acl_user.x509_subject=x509_subject;
+#endif /* HAVE_OPENSSL */
if (password)
{
acl_user.password=(char*) ""; // Just point at something
@@ -519,7 +725,7 @@ static void acl_insert_user(const char *user, const char *host,
static void acl_update_db(const char *user, const char *host, const char *db,
- uint privileges)
+ ulong privileges)
{
for (uint i=0 ; i < acl_dbs.elements ; i++)
{
@@ -546,7 +752,7 @@ static void acl_update_db(const char *user, const char *host, const char *db,
static void acl_insert_db(const char *user, const char *host, const char *db,
- uint privileges)
+ ulong privileges)
{
ACL_DB acl_db;
/* The acl_cache mutex is locked by mysql_grant */
@@ -565,17 +771,24 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
** Get privilege for a host, user and db combination
*****************************************************************************/
-uint acl_get(const char *host, const char *ip, const char *bin_ip,
+ulong acl_get(const char *host, const char *ip, const char *bin_ip,
const char *user, const char *db)
{
- uint host_access,db_access,i,key_length;
+ ulong host_access,db_access;
+ uint i,key_length;
db_access=0; host_access= ~0;
- char key[ACL_KEY_LENGTH],*end;
+ char key[ACL_KEY_LENGTH],*tmp_db,*end;
acl_entry *entry;
+ THD *thd= current_thd;
VOID(pthread_mutex_lock(&acl_cache->lock));
memcpy_fixed(&key,bin_ip,sizeof(struct in_addr));
- end=strmov(strmov(key+sizeof(struct in_addr),user)+1,db);
+ end=strmov((tmp_db=strmov(key+sizeof(struct in_addr),user)+1),db);
+ if (lower_case_table_names)
+ {
+ casedn_str(tmp_db);
+ db=tmp_db;
+ }
key_length=(uint) (end-key);
if ((entry=(acl_entry*) acl_cache->search(key,key_length)))
{
@@ -641,7 +854,7 @@ int wild_case_compare(const char *str,const char *wildstr)
{
reg3 int flag;
DBUG_ENTER("wild_case_compare");
-
+ DBUG_PRINT("enter",("str: '%s' wildstr: '%s'",str,wildstr));
while (*wildstr)
{
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
@@ -653,7 +866,7 @@ int wild_case_compare(const char *str,const char *wildstr)
if (! *wildstr ) DBUG_RETURN (*str != 0);
if (*wildstr++ == wild_one)
{
- if (! *str++) DBUG_RETURN (1); /* One char; skipp */
+ if (! *str++) DBUG_RETURN (1); /* One char; skip */
}
else
{ /* Found '*' */
@@ -757,44 +970,70 @@ bool acl_check_host(const char *host, const char *ip)
}
/*****************************************************************************
-** Change password for the user if it's not an anonymous user
-** Note: This should write the error directly to the client!
+ Change password for the user if it's not an anonymous user
+ Note: This should write the error directly to the client!
*****************************************************************************/
-bool change_password(THD *thd, const char *host, const char *user,
- char *new_password)
+/*
+ Check if the user is allowed to change password
+
+ SYNOPSIS:
+ check_change_password()
+ thd THD
+ host hostname for the user
+ user user name
+
+ RETURN VALUE
+ 0 OK
+ 1 ERROR ; In this case the error is sent to the client.
+*/
+
+bool check_change_password(THD *thd, const char *host, const char *user)
{
- uint length=0;
if (!initialized)
{
send_error(&thd->net, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */
- return 1; /* purecov: inspected */
+ return(1); /* purecov: inspected */
}
- if (!host)
- host=thd->ip; /* purecov: tested */
- /* password should always be 0 or 16 chars; simple hack to avoid cracking */
- length=(uint) strlen(new_password);
- new_password[length & 16]=0;
-
if (!thd->slave_thread &&
(strcmp(thd->user,user) ||
my_strcasecmp(host,thd->host ? thd->host : thd->ip)))
{
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
- return 1;
+ return(1);
}
if (!thd->slave_thread && !thd->user[0])
{
send_error(&thd->net, ER_PASSWORD_ANONYMOUS_USER);
- return 1;
+ return(1);
}
+ return(0);
+}
+
+
+bool change_password(THD *thd, const char *host, const char *user,
+ char *new_password)
+{
+ uint length=0;
+ DBUG_ENTER("change_password");
+ DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'",
+ host,user,new_password));
+ DBUG_ASSERT(host != 0); // Ensured by parent
+
+ if (check_change_password(thd, host, user))
+ DBUG_RETURN(1);
+
+ /* password should always be 0 or 16 chars; simple hack to avoid cracking */
+ length=(uint) strlen(new_password);
+ new_password[length & 16]=0;
+
VOID(pthread_mutex_lock(&acl_cache->lock));
ACL_USER *acl_user;
if (!(acl_user= find_acl_user(host,user)))
{
send_error(&thd->net, ER_PASSWORD_NO_MATCH);
VOID(pthread_mutex_unlock(&acl_cache->lock));
- return 1;
+ DBUG_RETURN(1);
}
if (update_user_table(thd,
acl_user->host.hostname ? acl_user->host.hostname : "",
@@ -803,7 +1042,7 @@ bool change_password(THD *thd, const char *host, const char *user,
{
VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */
send_error(&thd->net,0); /* purecov: deadcode */
- return 1; /* purecov: deadcode */
+ DBUG_RETURN(1); /* purecov: deadcode */
}
get_salt_from_password(acl_user->salt,new_password);
if (!new_password[0])
@@ -814,7 +1053,7 @@ bool change_password(THD *thd, const char *host, const char *user,
VOID(pthread_mutex_unlock(&acl_cache->lock));
char buff[460];
-
+
Query_log_event qinfo(thd, buff);
qinfo.q_len =
my_sprintf(buff,
@@ -824,7 +1063,7 @@ bool change_password(THD *thd, const char *host, const char *user,
new_password));
mysql_update_log.write(thd,buff,qinfo.q_len);
mysql_bin_log.write(&qinfo);
- return 0;
+ DBUG_RETURN(0);
}
@@ -835,17 +1074,23 @@ bool change_password(THD *thd, const char *host, const char *user,
static ACL_USER *
find_acl_user(const char *host, const char *user)
{
+ DBUG_ENTER("find_acl_user");
+ DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user));
for (uint i=0 ; i < acl_users.elements ; i++)
{
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
+ DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),",
+ user,acl_user->user,(host),(acl_user->host)));
if (!acl_user->user && !user[0] ||
acl_user->user && !strcmp(user,acl_user->user))
{
- if (compare_hostname(&acl_user->host,host,host))
- return acl_user;
+ if (compare_hostname(&(acl_user->host),host,host))
+ {
+ DBUG_RETURN(acl_user);
+ }
}
}
- return 0;
+ DBUG_RETURN(0);
}
/*****************************************************************************
@@ -904,7 +1149,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
/****************************************************************************
-** Code to update grants in the user and database privilege tables
+ Code to update grants in the user and database privilege tables
****************************************************************************/
static bool update_user_table(THD *thd, const char *host, const char *user,
@@ -954,10 +1199,10 @@ static bool test_if_create_new_users(THD *thd)
if (opt_safe_user_create && !(thd->master_access & INSERT_ACL))
{
TABLE_LIST tl;
- uint db_access;
+ ulong db_access;
bzero((char*) &tl,sizeof(tl));
tl.db= (char*) "mysql";
- tl.real_name= (char*) "user";
+ tl.real_name= (char*) "user";
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, tl.db);
if (!(db_access & INSERT_ACL))
@@ -974,13 +1219,14 @@ static bool test_if_create_new_users(THD *thd)
** Handle GRANT commands
****************************************************************************/
-static int replace_user_table(TABLE *table, const LEX_USER &combo,
- uint rights, char what, bool create_user)
+static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
+ ulong rights, bool revoke_grant,
+ bool create_user)
{
int error = -1;
- uint i,j;
bool old_row_exists=0;
char *password,empty_string[1];
+ char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_user_table");
password=empty_string;
@@ -1013,7 +1259,7 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
my_printf_error(ER_NO_PERMISSION_TO_CREATE_USER,
ER(ER_NO_PERMISSION_TO_CREATE_USER),
MYF(0),thd->user,
- thd->host ? thd->host : thd->ip ? thd->ip: "");
+ thd->host_or_ip);
error= -1;
goto end;
}
@@ -1031,15 +1277,60 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
table->field[2]->store(password,(uint) strlen(password));
}
- for (i = 3, j = SELECT_ACL; // starting from reload
- i < table->fields;
- i++, j <<= 1)
+ /* Update table columns with new privileges */
+
+ Field **tmp_field;
+ ulong priv;
+ for (tmp_field= table->field+3, priv = SELECT_ACL;
+ *tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM &&
+ ((Field_enum*) (*tmp_field))->typelib->count == 2 ;
+ tmp_field++, priv <<= 1)
{
- if (j & rights) // set requested privileges
- table->field[i]->store(&what,1);
+ if (priv & rights) // set requested privileges
+ (*tmp_field)->store(&what,1);
}
rights=get_access(table,3);
+ DBUG_PRINT("info",("table->fields: %d",table->fields));
+ if (table->fields >= 31) /* From 4.0.0 we have more fields */
+ {
+#ifdef HAVE_OPENSSL
+ /* We write down SSL related ACL stuff */
+ table->field[25]->store("",0);
+ table->field[26]->store("",0);
+ table->field[27]->store("",0);
+ switch (thd->lex.ssl_type) {
+ case SSL_TYPE_ANY:
+ table->field[24]->store("ANY",3);
+ break;
+ case SSL_TYPE_X509:
+ table->field[24]->store("X509",4);
+ break;
+ case SSL_TYPE_SPECIFIED:
+ table->field[24]->store("SPECIFIED",9);
+ if (thd->lex.ssl_cipher)
+ table->field[25]->store(thd->lex.ssl_cipher,
+ strlen(thd->lex.ssl_cipher));
+ if (thd->lex.x509_issuer)
+ table->field[26]->store(thd->lex.x509_issuer,
+ strlen(thd->lex.x509_issuer));
+ if (thd->lex.x509_subject)
+ table->field[27]->store(thd->lex.x509_subject,
+ strlen(thd->lex.x509_subject));
+ break;
+ default:
+ table->field[24]->store("",0);
+ }
+#endif /* HAVE_OPENSSL */
+ USER_RESOURCES mqh = thd->lex.mqh;
+ if (mqh.bits & 1)
+ table->field[28]->store((longlong) mqh.questions);
+ if (mqh.bits & 2)
+ table->field[29]->store((longlong) mqh.updates);
+ if (mqh.bits & 4)
+ table->field[30]->store((longlong) mqh.connections);
+ mqh_used = mqh_used || mqh.questions || mqh.updates || mqh.connections;
+ }
if (old_row_exists)
{
/*
@@ -1066,16 +1357,28 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
}
error=0; // Privileges granted / revoked
- end:
+end:
if (!error)
{
acl_cache->clear(1); // Clear privilege cache
if (!combo.password.str)
password=0; // No password given on command
if (old_row_exists)
- acl_update_user(combo.user.str,combo.host.str,password,rights);
+ acl_update_user(combo.user.str,combo.host.str,password,
+ thd->lex.ssl_type,
+ thd->lex.ssl_cipher,
+ thd->lex.x509_issuer,
+ thd->lex.x509_subject,
+ &thd->lex.mqh,
+ rights);
else
- acl_insert_user(combo.user.str,combo.host.str,password,rights);
+ acl_insert_user(combo.user.str,combo.host.str,password,
+ thd->lex.ssl_type,
+ thd->lex.ssl_cipher,
+ thd->lex.x509_issuer,
+ thd->lex.x509_subject,
+ &thd->lex.mqh,
+ rights);
}
table->file->index_end();
DBUG_RETURN(error);
@@ -1083,16 +1386,18 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
/*
-** change grants in the mysql.db table
+ change grants in the mysql.db table
*/
static int replace_db_table(TABLE *table, const char *db,
const LEX_USER &combo,
- uint rights, char what)
+ ulong rights, bool revoke_grant)
{
- uint i,j,store_rights;
+ uint i;
+ ulong priv,store_rights;
bool old_row_exists=0;
int error;
+ char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_db_table");
// is there such a user in user table in memory ????
@@ -1128,9 +1433,9 @@ static int replace_db_table(TABLE *table, const char *db,
}
store_rights=get_rights_for_db(rights);
- for (i = 3, j = 1; i < table->fields; i++, j <<= 1)
+ for (i= 3, priv= 1; i < table->fields; i++, priv <<= 1)
{
- if (j & store_rights) // do it if priv is chosen
+ if (priv & store_rights) // do it if priv is chosen
table->field [i]->store(&what,1); // set requested privileges
}
rights=get_access(table,3);
@@ -1178,13 +1483,15 @@ class GRANT_COLUMN :public Sql_alloc
{
public:
char *column;
- uint rights, key_length;
- GRANT_COLUMN(String &c, uint y) :rights (y)
+ ulong rights;
+ uint key_length;
+ GRANT_COLUMN(String &c, ulong y) :rights (y)
{
- column= memdup_root(&memex,c.ptr(),key_length=c.length());
+ column= memdup_root(&memex,c.ptr(), key_length=c.length());
}
};
+
static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -1192,20 +1499,27 @@ static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
return (byte*) buff->column;
}
+
class GRANT_TABLE :public Sql_alloc
{
public:
char *host,*db,*user,*tname, *hash_key;
- uint privs, cols, key_length;
+ ulong privs, cols;
+ uint key_length;
HASH hash_columns;
GRANT_TABLE (const char *h, const char *d,const char *u, const char *t,
- uint p,uint c)
+ ulong p, ulong c)
: privs(p), cols(c)
{
host = strdup_root(&memex,h);
db = strdup_root(&memex,d);
user = strdup_root(&memex,u);
tname= strdup_root(&memex,t);
+ if (lower_case_table_names)
+ {
+ casedn_str(db);
+ casedn_str(tname);
+ }
key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3;
hash_key = (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
@@ -1219,7 +1533,9 @@ public:
host = get_field(&memex,form,0);
db = get_field(&memex,form,1);
- user = get_field(&memex,form,2); if (!user) user=(char*) "";
+ user = get_field(&memex,form,2);
+ if (!user)
+ user=(char*) "";
tname = get_field(&memex,form,3);
if (!host || !db || !tname)
{
@@ -1227,11 +1543,17 @@ public:
privs = cols = 0; /* purecov: inspected */
return; /* purecov: inspected */
}
- key_length = (uint) strlen(db) + (uint) strlen(user) + (uint) strlen (tname) + 3;
+ if (lower_case_table_names)
+ {
+ casedn_str(db);
+ casedn_str(tname);
+ }
+ key_length = ((uint) strlen(db) + (uint) strlen(user) +
+ (uint) strlen(tname) + 3);
hash_key = (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
- privs = (uint) form->field[6]->val_int();
- cols = (uint) form->field[7]->val_int();
+ privs = (ulong) form->field[6]->val_int();
+ cols = (ulong) form->field[7]->val_int();
privs = fix_rights_for_table(privs);
cols = fix_rights_for_column(cols);
@@ -1264,7 +1586,7 @@ public:
GRANT_COLUMN *mem_check;
/* As column name is a string, we don't have to supply a buffer */
res=col_privs->field[4]->val_str(&column_name,&column_name);
- uint priv= (uint) col_privs->field[6]->val_int();
+ ulong priv= (ulong) col_privs->field[6]->val_int();
if (!(mem_check = new GRANT_COLUMN(*res,
fix_rights_for_column(priv))))
{
@@ -1280,6 +1602,7 @@ public:
bool ok() { return privs != 0 || cols != 0; }
};
+
static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -1287,11 +1610,13 @@ static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
return (byte*) buff->hash_key;
}
+
void free_grant_table(GRANT_TABLE *grant_table)
{
hash_free(&grant_table->hash_columns);
}
+
/* Search after a matching grant. Prefer exact grants before not exact ones */
static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
@@ -1328,8 +1653,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
inline GRANT_COLUMN *
-column_hash_search(GRANT_TABLE *t, const char *cname,
- uint length)
+column_hash_search(GRANT_TABLE *t, const char *cname, uint length)
{
return (GRANT_COLUMN*) hash_search(&t->hash_columns, (byte*) cname,length);
}
@@ -1339,7 +1663,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
TABLE *table, const LEX_USER &combo,
List <LEX_COLUMN> &columns,
const char *db, const char *table_name,
- uint rights, bool revoke_grant)
+ ulong rights, bool revoke_grant)
{
int error=0,result=0;
uint key_length;
@@ -1363,7 +1687,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
table->file->index_init(0);
while ((xx=iter++))
{
- uint privileges = xx->rights;
+ ulong privileges = xx->rights;
bool old_row_exists=0;
key_restore(table,key,0,key_length);
table->field[4]->store(xx->column.ptr(),xx->column.length());
@@ -1386,7 +1710,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
}
else
{
- uint tmp= (uint) table->field[6]->val_int();
+ ulong tmp= (ulong) table->field[6]->val_int();
tmp=fix_rights_for_column(tmp);
if (revoke_grant)
@@ -1446,7 +1770,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
// Scan trough all rows with the same host,db,user and table
do
{
- uint privileges = (uint) table->field[6]->val_int();
+ ulong privileges = (ulong) table->field[6]->val_int();
privileges=fix_rights_for_column(privileges);
store_record(table,1);
@@ -1502,19 +1826,21 @@ static int replace_column_table(GRANT_TABLE *g_t,
static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
TABLE *table, const LEX_USER &combo,
const char *db, const char *table_name,
- uint rights, uint kolone, bool revoke_grant)
+ ulong rights, ulong col_rights,
+ bool revoke_grant)
{
char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH];
int old_row_exists = 1;
int error=0;
- uint store_table_rights,store_col_rights;
+ ulong store_table_rights, store_col_rights;
DBUG_ENTER("replace_table_table");
- strxmov(grantor,thd->user,"@",thd->host ? thd->host : thd->ip ? thd->ip :"",
- NullS);
+ strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
- // The following should always succeed as new users are created before
- // this function is called!
+ /*
+ The following should always succeed as new users are created before
+ this function is called!
+ */
if (!find_acl_user(combo.host.str,combo.user.str))
{
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */
@@ -1549,14 +1875,14 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
restore_record(table,1); // Get saved record
}
- store_table_rights=get_rights_for_table(rights);
- store_col_rights=get_rights_for_column(kolone);
+ store_table_rights= get_rights_for_table(rights);
+ store_col_rights= get_rights_for_column(col_rights);
if (old_row_exists)
{
- uint j,k;
+ ulong j,k;
store_record(table,1);
- j = (uint) table->field[6]->val_int();
- k = (uint) table->field[7]->val_int();
+ j = (ulong) table->field[6]->val_int();
+ k = (ulong) table->field[7]->val_int();
if (revoke_grant)
{
@@ -1565,8 +1891,8 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
}
else
{
- store_table_rights|=j;
- store_col_rights|=k;
+ store_table_rights|= j;
+ store_col_rights|= k;
}
}
@@ -1574,7 +1900,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
table->field[6]->store((longlong) store_table_rights);
table->field[7]->store((longlong) store_col_rights);
rights=fix_rights_for_table(store_table_rights);
- kolone=fix_rights_for_column(store_col_rights);
+ col_rights=fix_rights_for_column(store_col_rights);
if (old_row_exists)
{
@@ -1593,10 +1919,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
goto table_error; /* purecov: deadcode */
}
- if (rights | kolone)
+ if (rights | col_rights)
{
- grant_table->privs = rights;
- grant_table->cols = kolone;
+ grant_table->privs= rights;
+ grant_table->cols= col_rights;
}
else
{
@@ -1613,10 +1939,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
List <LEX_USER> &user_list,
- List <LEX_COLUMN> &columns, uint rights,
+ List <LEX_COLUMN> &columns, ulong rights,
bool revoke_grant)
{
- uint column_priv = 0;
+ ulong column_priv = 0;
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str;
TABLE_LIST tables[3];
@@ -1711,11 +2037,8 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
continue;
}
/* Create user if needed */
- if (replace_user_table(tables[0].table,
- *Str,
- 0,
- revoke_grant ? 'N' : 'Y',
- create_new_users))
+ if (replace_user_table(thd, tables[0].table, *Str,
+ 0, revoke_grant, create_new_users))
{
result= -1; // Remember error
continue; // Add next user
@@ -1806,17 +2129,17 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
pthread_mutex_unlock(&LOCK_grant);
if (!result)
send_ok(&thd->net);
- /* Tables are automaticly closed */
+ /* Tables are automatically closed */
DBUG_RETURN(result);
}
-int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
- bool revoke_grant)
+int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
+ ulong rights, bool revoke_grant)
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str;
- char what;
+ char tmp_db[NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
DBUG_ENTER("mysql_grant");
@@ -1827,7 +2150,12 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
return 1; /* purecov: tested */
}
- what = (revoke_grant) ? 'N' : 'Y';
+ if (lower_case_table_names && db)
+ {
+ strmov(tmp_db,db);
+ casedn_str(tmp_db);
+ db=tmp_db;
+ }
/* open the mysql.user and mysql.db tables */
@@ -1867,14 +2195,16 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
result= -1;
continue;
}
- if ((replace_user_table(tables[0].table,
+ if ((replace_user_table(thd,
+ tables[0].table,
*Str,
- (!db ? rights : 0), what, create_new_users)))
+ (!db ? rights : 0), revoke_grant,
+ create_new_users)))
result= -1;
else
{
if (db && replace_db_table(tables[1].table, db, *Str, rights & DB_ACLS,
- what))
+ revoke_grant))
result= -1;
}
}
@@ -1887,7 +2217,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
DBUG_RETURN(result);
}
- /* Free grant array if possible */
+
+/* Free grant array if possible */
void grant_free(void)
{
@@ -1923,7 +2254,8 @@ int grant_init (void)
thd->mysys_var=my_thread_var;
thd->current_tablenr=0;
thd->open_tables=0;
- thd->db=my_strdup("mysql",MYF(0));
+ thd->db= my_strdup("mysql",MYF(0));
+ thd->db_length=5; // Safety
bzero((char*) &tables,sizeof(tables));
tables[0].name=tables[0].real_name= (char*) "tables_priv";
tables[1].name=tables[1].real_name= (char*) "columns_priv";
@@ -1959,7 +2291,7 @@ int grant_init (void)
delete thd;
DBUG_RETURN(0); // Empty table is ok!
}
- grant_option = TRUE;
+ grant_option= TRUE;
t_table->file->index_end();
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
@@ -2023,11 +2355,11 @@ void grant_reload(void)
/****************************************************************************
-** Check grants
-** All errors are written directly to the client if command name is given !
+ Check grants
+ All errors are written directly to the client if command name is given !
****************************************************************************/
-bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
+bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_table, bool no_errors)
{
TABLE_LIST *table;
@@ -2045,8 +2377,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
table->grant.want_privilege=0;
continue; // Already checked
}
- const char *db = table->db ? table->db : thd->db;
- GRANT_TABLE *grant_table = table_hash_search(thd->host,thd->ip,db,user,
+ GRANT_TABLE *grant_table = table_hash_search(thd->host,thd->ip,
+ table->db,user,
table->real_name,0);
if (!grant_table)
{
@@ -2100,7 +2432,7 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR,
command,
thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
+ thd->host_or_ip,
table ? table->real_name : "unknown");
}
return 1;
@@ -2113,7 +2445,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
- uint want_access=table->grant.want_privilege;
+ ulong want_access=table->grant.want_privilege;
if (!want_access)
return 0; // Already checked
@@ -2151,19 +2483,14 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
pthread_mutex_unlock(&LOCK_grant);
if (!show_tables)
{
- const char *command="";
- if (want_access & SELECT_ACL)
- command ="select";
- else if (want_access & INSERT_ACL)
- command = "insert";
- else if (want_access & UPDATE_ACL)
- command = "update";
+ char command[128];
+ get_privilege_desc(command, sizeof(command), want_access);
my_printf_error(ER_COLUMNACCESS_DENIED_ERROR,
ER(ER_COLUMNACCESS_DENIED_ERROR),
MYF(0),
command,
thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
+ thd->host_or_ip,
name,
table ? table->real_name : "unknown");
}
@@ -2171,7 +2498,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
}
-bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
+bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
{
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
@@ -2221,7 +2548,7 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
MYF(0),
command,
thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
+ thd->host_or_ip,
field ? field->field_name : "unknown",
table->real_name);
return 1;
@@ -2229,9 +2556,9 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
/****************************************************************************
-** Check if a user has the right to access a database
-** Access is accepted if he has a grant for any table in the database
-** Return 1 if access is denied
+ Check if a user has the right to access a database
+ Access is accepted if he has a grant for any table in the database
+ Return 1 if access is denied
****************************************************************************/
bool check_grant_db(THD *thd,const char *db)
@@ -2260,10 +2587,10 @@ bool check_grant_db(THD *thd,const char *db)
}
/*****************************************************************************
-** Functions to retrieve the grant for a table/column (for SHOW functions)
+ Functions to retrieve the grant for a table/column (for SHOW functions)
*****************************************************************************/
-uint get_table_grant(THD *thd, TABLE_LIST *table)
+ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
char *user = thd->priv_user;
const char *db = table->db ? table->db : thd->db;
@@ -2281,11 +2608,11 @@ uint get_table_grant(THD *thd, TABLE_LIST *table)
}
-uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
+ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
{
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
- uint priv;
+ ulong priv;
pthread_mutex_lock(&LOCK_grant);
// reload table if someone has modified any grants
@@ -2315,22 +2642,31 @@ uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
/*****************************************************************************
-** SHOW GRANTS : send to client grant-like strings depicting user@host
-** privileges
+ SHOW GRANTS : send to client grant-like strings depicting user@host
+ privileges
*****************************************************************************/
static const char *command_array[]=
-{"SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP","RELOAD","SHUTDOWN",
- "PROCESS","FILE","GRANT","REFERENCES","INDEX","ALTER"};
-static int command_lengths[]={6,6,6,6,6,4,6,8,7,4,5,10,5,5};
+{
+ "SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP", "RELOAD","SHUTDOWN",
+ "PROCESS","FILE","GRANT","REFERENCES","INDEX", "ALTER", "SHOW DATABASES",
+ "SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
+ "REPLICATION SLAVE", "REPLICATION CLIENT",
+};
+static uint command_lengths[]=
+{
+ 6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18
+};
+
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
- uint counter, want_access,index;
+ ulong want_access;
+ uint counter,index;
int error = 0;
ACL_USER *acl_user; ACL_DB *acl_db;
char buff[1024];
- DBUG_ENTER("mysql_grant");
+ DBUG_ENTER("mysql_show_grants");
LINT_INIT(acl_user);
if (!initialized)
@@ -2396,7 +2732,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
else
{
bool found=0;
- uint j,test_access= want_access & ~GRANT_ACL;
+ ulong j,test_access= want_access & ~GRANT_ACL;
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
{
if (test_access & j)
@@ -2421,8 +2757,70 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append(passd_buff);
global.append('\'');
}
- if (want_access & GRANT_ACL)
- global.append(" WITH GRANT OPTION",18);
+#ifdef HAVE_OPENSSL
+ /* "show grants" SSL related stuff */
+ if (acl_user->ssl_type == SSL_TYPE_ANY)
+ global.append(" REQUIRE SSL",12);
+ else if (acl_user->ssl_type == SSL_TYPE_X509)
+ global.append(" REQUIRE X509",13);
+ else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
+ {
+ int ssl_options = 0;
+ global.append(" REQUIRE ",9);
+ if (acl_user->x509_issuer)
+ {
+ ssl_options++;
+ global.append("ISSUER \"",8);
+ global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
+ global.append('\'');
+ }
+ if (acl_user->x509_subject)
+ {
+ if (ssl_options++)
+ global.append(" AND ",5);
+ global.append("SUBJECT \"",9);
+ global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
+ global.append('\'');
+ }
+ if (acl_user->ssl_cipher)
+ {
+ if (ssl_options++)
+ global.append(" AND ",5);
+ global.append("CIPHER '",8);
+ global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
+ global.append('\'');
+ }
+ }
+#endif /* HAVE_OPENSSL */
+ if ((want_access & GRANT_ACL) ||
+ (acl_user->user_resource.questions | acl_user->user_resource.updates |
+ acl_user->user_resource.connections))
+ {
+ global.append(" WITH",5);
+ if (want_access & GRANT_ACL)
+ global.append(" GRANT OPTION",13);
+ if (acl_user->user_resource.questions)
+ {
+ char buff[22], *p; // just as in int2str
+ global.append(" MAX_QUERIES_PER_HOUR ",22);
+ p=int10_to_str(acl_user->user_resource.questions,buff,10);
+ global.append(buff,p-buff);
+ }
+ if (acl_user->user_resource.updates)
+ {
+ char buff[22], *p; // just as in int2str
+ global.append(" MAX_UPDATES_PER_HOUR ",22);
+ p=int10_to_str(acl_user->user_resource.updates,buff,10);
+ global.append(buff,p-buff);
+ }
+ if (acl_user->user_resource.connections)
+ {
+ char buff[22], *p; // just as in int2str
+ global.append(" MAX_CONNECTIONS_PER_HOUR ",26);
+ p=int10_to_str(acl_user->user_resource.connections,buff,10);
+ global.append(buff,p-buff);
+ }
+ }
thd->packet.length(0);
net_store_data(&thd->packet,global.ptr(),global.length());
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
@@ -2458,7 +2856,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
else
{
int found=0, cnt;
- uint j,test_access= want_access & ~GRANT_ACL;
+ ulong j,test_access= want_access & ~GRANT_ACL;
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
{
if (test_access & j)
@@ -2478,7 +2876,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
db.append(lex_user->host.str, lex_user->host.length);
db.append ('\'');
if (want_access & GRANT_ACL)
- db.append(" WITH GRANT OPTION",18);
+ db.append(" WITH GRANT OPTION",18);
thd->packet.length(0);
net_store_data(&thd->packet,db.ptr(),db.length());
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
@@ -2517,7 +2915,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
else
{
int found=0;
- uint j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
+ ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
{
@@ -2585,8 +2983,47 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
+/*
+ Make a clear-text version of the requested privilege.
+*/
+
+void get_privilege_desc(char *to, uint max_length, ulong access)
+{
+ uint pos;
+ char *start=to;
+ DBUG_ASSERT(max_length >= 30); // For end ',' removal
+
+ if (access)
+ {
+ max_length--; // Reserve place for end-zero
+ for (pos=0 ; access ; pos++, access>>=1)
+ {
+ if ((access & 1) &&
+ command_lengths[pos] + (uint) (to-start) < max_length)
+ {
+ to= strmov(to, command_array[pos]);
+ *to++=',';
+ }
+ }
+ to--; // Remove end ','
+ }
+ *to=0;
+}
+
+
+void get_mqh(const char *user, const char *host, USER_CONN *uc)
+{
+ ACL_USER *acl_user;
+ if (initialized && (acl_user= find_acl_user(host,user)))
+ uc->user_resources= acl_user->user_resource;
+ else
+ bzero((char*) &uc->user_resources, sizeof(uc->user_resources));
+}
+
+
+
/*****************************************************************************
-** Instantiate used templates
+ Instantiate used templates
*****************************************************************************/
#ifdef __GNUC__
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index cf9696d51e7..d6cf320c978 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -1,47 +1,63 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define SELECT_ACL 1
-#define INSERT_ACL 2
-#define UPDATE_ACL 4
-#define DELETE_ACL 8
-#define CREATE_ACL 16
-#define DROP_ACL 32
-#define RELOAD_ACL 64
-#define SHUTDOWN_ACL 128
-#define PROCESS_ACL 256
-#define FILE_ACL 512
-#define GRANT_ACL 1024
-#define REFERENCES_ACL 2048
-#define INDEX_ACL 4096
-#define ALTER_ACL 8192
-#define EXTRA_ACL 16384
-#define DB_ACLS (UPDATE_ACL | SELECT_ACL | INSERT_ACL | \
- DELETE_ACL | CREATE_ACL | DROP_ACL | GRANT_ACL | \
- REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
-#define TABLE_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | \
- DELETE_ACL | CREATE_ACL | DROP_ACL | GRANT_ACL | \
- REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
-#define COL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
-#define GLOBAL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL |\
- CREATE_ACL | DROP_ACL | RELOAD_ACL | SHUTDOWN_ACL |\
- PROCESS_ACL | FILE_ACL | GRANT_ACL | REFERENCES_ACL |\
- INDEX_ACL | ALTER_ACL)
-#define NO_ACCESS 32768
+#define SELECT_ACL (1L << 0)
+#define INSERT_ACL (1L << 1)
+#define UPDATE_ACL (1L << 2)
+#define DELETE_ACL (1L << 3)
+#define CREATE_ACL (1L << 4)
+#define DROP_ACL (1L << 5)
+#define RELOAD_ACL (1L << 6)
+#define SHUTDOWN_ACL (1L << 7)
+#define PROCESS_ACL (1L << 8)
+#define FILE_ACL (1L << 9)
+#define GRANT_ACL (1L << 10)
+#define REFERENCES_ACL (1L << 11)
+#define INDEX_ACL (1L << 12)
+#define ALTER_ACL (1L << 13)
+#define SHOW_DB_ACL (1L << 14)
+#define SUPER_ACL (1L << 15)
+#define CREATE_TMP_ACL (1L << 16)
+#define LOCK_TABLES_ACL (1L << 17)
+#define EXECUTE_ACL (1L << 18)
+#define REPL_SLAVE_ACL (1L << 19)
+#define REPL_CLIENT_ACL (1L << 20)
+
+
+#define DB_ACLS \
+(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
+
+#define TABLE_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
+
+#define COL_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
+
+#define GLOBAL_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL | GRANT_ACL | \
+ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
+ CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
+ EXECUTE_ACL)
+
+#define EXTRA_ACL (1L << 29)
+#define NO_ACCESS (1L << 30)
/* defines to change the above bits to how things are stored in tables */
@@ -57,28 +73,31 @@
int acl_init(bool dont_read_acl_tables);
void acl_reload(void);
void acl_free(bool end=0);
-uint acl_get(const char *host, const char *ip, const char *bin_ip,
- const char *user, const char *db);
-uint acl_getroot(const char *host, const char *ip, const char *user,
- const char *password,const char *scramble,char **priv_user,
- bool old_ver);
+ulong acl_get(const char *host, const char *ip, const char *bin_ip,
+ const char *user, const char *db);
+ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
+ const char *password,const char *scramble,char **priv_user,
+ bool old_ver, USER_RESOURCES *max);
bool acl_check_host(const char *host, const char *ip);
+bool check_change_password(THD *thd, const char *host, const char *user);
bool change_password(THD *thd, const char *host, const char *user,
char *password);
int mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
- uint rights, bool revoke);
+ ulong rights, bool revoke);
int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
- List <LEX_COLUMN> &column_list, uint rights,
+ List <LEX_COLUMN> &column_list, ulong rights,
bool revoke);
int grant_init(void);
void grant_free(void);
void grant_reload(void);
-bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
+bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_command=0, bool dont_print_error=0);
-bool check_grant_column (THD *thd,TABLE *table, const char *name,uint length,
+bool check_grant_column (THD *thd,TABLE *table, const char *name, uint length,
uint show_command=0);
-bool check_grant_all_columns(THD *thd, uint want_access, TABLE *table);
+bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table);
bool check_grant_db(THD *thd,const char *db);
-uint get_table_grant(THD *thd, TABLE_LIST *table);
-uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field);
+ulong get_table_grant(THD *thd, TABLE_LIST *table);
+ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field);
int mysql_show_grants(THD *thd, LEX_USER *user);
+void get_privilege_desc(char *to, uint max_length, ulong access);
+void get_mqh(const char *user, const char *host, USER_CONN *uc);
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index de367e8c052..bbe82653190 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -38,6 +38,37 @@
#define UINT_MAX24 0xffffff
#define UINT_MAX32 0xffffffff
+int sortcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b)
+{
+ return sortcmp(a,b);
+}
+
+int stringcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b)
+{
+ return stringcmp(a,b);
+}
+
+int compare_double2(void* cmp_arg __attribute__((unused)),
+ const double *s, const double *t)
+{
+ return compare_double(s,t);
+}
+
+int compare_longlong2(void* cmp_arg __attribute__((unused)),
+ const longlong *s, const longlong *t)
+{
+ return compare_longlong(s,t);
+}
+
+int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
+ const ulonglong *s, const ulonglong *t)
+{
+ return compare_ulonglong(s,t);
+}
+
+
Procedure *
proc_analyse_init(THD *thd, ORDER *param, select_result *result,
List<Item> &field_list)
@@ -59,21 +90,21 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
(*param->item)->val() < 0)
{
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
pc->max_tree_elements = (uint) (*param->item)->val_int();
param = param->next;
if (param->next) // no third parameter possible
{
net_printf(&thd->net, ER_WRONG_PARAMCOUNT_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
// second parameter
if ((*param->item)->type() != Item::INT_ITEM ||
(*param->item)->val() < 0)
{
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
pc->max_treemem = (uint) (*param->item)->val_int();
}
@@ -81,7 +112,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
(*param->item)->val() < 0)
{
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
// if only one parameter was given, it will be the value of max_tree_elements
else
@@ -96,7 +127,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
pc->f_end = pc->f_info + field_list.elements;
pc->fields = field_list;
- List_iterator<Item> it(pc->fields);
+ List_iterator_fast<Item> it(pc->fields);
f_info = pc->f_info;
Item *item;
@@ -117,21 +148,26 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
if (item->result_type() == STRING_RESULT)
*f_info++ = new field_str(item, pc);
}
- return pc;
-} // proc_analyse_init
+ DBUG_RETURN(pc);
+}
-// return 1 if number, else return 0
-// store info about found number in info
-// NOTE:It is expected, that elements of 'info' are all zero!
+/*
+ Return 1 if number, else return 0
+ store info about found number in info
+ NOTE:It is expected, that elements of 'info' are all zero!
+*/
+
bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
{
const char *begin, *end = str + str_len;
DBUG_ENTER("test_if_number");
- // MySQL removes any endspaces of a string, so we must take care only of
- // spaces in front of a string
+ /*
+ MySQL removes any endspaces of a string, so we must take care only of
+ spaces in front of a string
+ */
for (; str != end && isspace(*str); str++) ;
if (str == end)
return 0;
@@ -859,7 +895,7 @@ int collect_string(String *element,
int collect_real(double *element, element_count count __attribute__((unused)),
TREE_INFO *info)
{
- char buff[255];
+ char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff));
if (info->found)
@@ -878,7 +914,7 @@ int collect_longlong(longlong *element,
element_count count __attribute__((unused)),
TREE_INFO *info)
{
- char buff[255];
+ char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff));
if (info->found)
@@ -897,7 +933,7 @@ int collect_ulonglong(ulonglong *element,
element_count count __attribute__((unused)),
TREE_INFO *info)
{
- char buff[255];
+ char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff));
if (info->found)
diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h
index ce5c0af6a96..1c60d0c150f 100644
--- a/sql/sql_analyse.h
+++ b/sql/sql_analyse.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,8 +21,6 @@
#pragma interface /* gcc class implementation */
#endif
-#include <my_tree.h>
-
#define DEC_IN_AVG 4
typedef struct st_number_info
@@ -53,8 +51,14 @@ uint check_ulonglong(const char *str, uint length);
bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num);
bool test_if_number(NUM_INFO *info, const char *str, uint str_len);
int compare_double(const double *s, const double *t);
+int compare_double2(void* cmp_arg __attribute__((unused)),
+ const double *s, const double *t);
int compare_longlong(const longlong *s, const longlong *t);
+int compare_longlong2(void* cmp_arg __attribute__((unused)),
+ const longlong *s, const longlong *t);
int compare_ulonglong(const ulonglong *s, const ulonglong *t);
+int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
+ const ulonglong *s, const ulonglong *t);
Procedure *proc_analyse_init(THD *thd, ORDER *param, select_result *result,
List<Item> &field_list);
void free_string(String*);
@@ -91,6 +95,11 @@ public:
int collect_string(String *element, element_count count,
TREE_INFO *info);
+int sortcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b);
+int stringcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b);
+
class field_str :public field_info
{
String min_arg, max_arg;
@@ -105,9 +114,9 @@ public:
max_arg(""), sum(0),
must_be_blob(0), was_zero_fill(0),
was_maybe_zerofill(0), can_be_still_num(1)
- { init_tree(&tree, 0, sizeof(String), a->binary ?
- (qsort_cmp) stringcmp : (qsort_cmp) sortcmp,
- 0, (void (*)(void*)) free_string); };
+ { init_tree(&tree, 0, 0, sizeof(String), a->binary ?
+ (qsort_cmp2) stringcmp2 : (qsort_cmp2) sortcmp2,
+ 0, (tree_element_free) free_string, NULL); };
void add();
void get_opt_type(String*, ha_rows);
@@ -145,8 +154,8 @@ class field_real: public field_info
public:
field_real(Item* a, analyse* b) :field_info(a,b),
min_arg(0), max_arg(0), sum(0), sum_sqr(0), max_notzero_dec_len(0)
- { init_tree(&tree, 0, sizeof(double),
- (qsort_cmp) compare_double, 0, NULL); }
+ { init_tree(&tree, 0, 0, sizeof(double),
+ (qsort_cmp2) compare_double2, 0, NULL, NULL); }
void add();
void get_opt_type(String*, ha_rows);
@@ -191,8 +200,8 @@ class field_longlong: public field_info
public:
field_longlong(Item* a, analyse* b) :field_info(a,b),
min_arg(0), max_arg(0), sum(0), sum_sqr(0)
- { init_tree(&tree, 0, sizeof(longlong),
- (qsort_cmp) compare_longlong, 0, NULL); }
+ { init_tree(&tree, 0, 0, sizeof(longlong),
+ (qsort_cmp2) compare_longlong2, 0, NULL, NULL); }
void add();
void get_opt_type(String*, ha_rows);
@@ -236,8 +245,8 @@ class field_ulonglong: public field_info
public:
field_ulonglong(Item* a, analyse * b) :field_info(a,b),
min_arg(0), max_arg(0), sum(0),sum_sqr(0)
- { init_tree(&tree, 0, sizeof(ulonglong),
- (qsort_cmp) compare_ulonglong, 0, NULL); }
+ { init_tree(&tree, 0, 0, sizeof(ulonglong),
+ (qsort_cmp2) compare_ulonglong2, 0, NULL, NULL); }
void add();
void get_opt_type(String*, ha_rows);
String *get_min_arg(String *s) { s->set(min_arg); return s; }
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ee8c1097fb2..29cc925218f 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -15,11 +15,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Basic functions neaded by many modules */
+/* Basic functions needed by many modules */
#include "mysql_priv.h"
#include "sql_acl.h"
-#include <thr_alarm.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
@@ -34,8 +33,6 @@ HASH open_cache; /* Used by mysql_test */
static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
const char *name, const char *alias, bool locked);
-static bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
- const char *table_name, List_iterator<Item> *it);
static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void);
static key_map get_key_map_from_key_list(TABLE *table,
@@ -111,75 +108,73 @@ static void check_unused(void)
#define check_unused()
#endif
-int list_open_tables(THD *thd,List<char> *tables, const char *db,
- const char *wild)
+OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
{
int result = 0;
uint col_access=thd->col_access;
+ OPEN_TABLE_LIST **start_list, *open_list;
TABLE_LIST table_list;
+ char name[NAME_LEN*2];
DBUG_ENTER("list_open_tables");
+
VOID(pthread_mutex_lock(&LOCK_open));
bzero((char*) &table_list,sizeof(table_list));
+ start_list= &open_list;
+ open_list=0;
- for (uint idx=0 ; idx < open_cache.records; idx++)
+ for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++)
{
+ OPEN_TABLE_LIST *table;
TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
- if ((!entry->real_name) || strcmp(entry->table_cache_key,db))
- continue;
- if (wild && wild[0] && wild_compare(entry->real_name,wild))
- continue;
- if (db && !(col_access & TABLE_ACLS))
+
+ if ((!entry->real_name))
+ continue; // Shouldn't happen
+ if (wild)
{
- table_list.db= (char*) db;
- table_list.real_name= entry->real_name;/*real name*/
- table_list.grant.privilege=col_access;
- if (check_grant(thd,TABLE_ACLS,&table_list,1,1))
- continue;
+ strxmov(name,entry->table_cache_key,".",entry->real_name,NullS);
+ if (wild_compare(name,wild))
+ continue;
}
- /* need to check if he have't already listed it */
- List_iterator<char> it(*tables);
- char *table_name;
- int check = 0;
- while (check == 0 && (table_name=it++))
+ /* Check if user has SELECT privilege for any column in the table */
+ table_list.db= (char*) entry->table_cache_key;
+ table_list.real_name= entry->real_name;
+ table_list.grant.privilege=0;
+ if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list))
+ continue;
+
+ /* need to check if we haven't already listed it */
+ for (table= open_list ; table ; table=table->next)
{
- if (!strcmp(table_name,entry->real_name))
- check++;
+ if (!strcmp(table->table,entry->real_name) &&
+ !strcmp(table->db,entry->table_cache_key))
+ {
+ if (entry->in_use)
+ table->in_use++;
+ if (entry->locked_by_name)
+ table->locked++;
+ break;
+ }
}
- if (check)
+ if (table)
continue;
-
- if (tables->push_back(thd->strdup(entry->real_name)))
+ if (!(*start_list = (OPEN_TABLE_LIST *)
+ sql_alloc(sizeof(**start_list)+entry->key_length)))
{
- result = -1;
+ open_list=0; // Out of memory
break;
}
+ strmov((*start_list)->table=
+ strmov(((*start_list)->db= (char*) ((*start_list)+1)),
+ entry->table_cache_key)+1,
+ entry->real_name);
+ (*start_list)->in_use= entry->in_use ? 1 : 0;
+ (*start_list)->locked= entry->locked_by_name ? 1 : 0;
+ start_list= &(*start_list)->next;
+ *start_list=0;
}
-
VOID(pthread_mutex_unlock(&LOCK_open));
- DBUG_RETURN(result);
-}
-
-char*
-query_table_status(THD *thd,const char *db,const char *table_name)
-{
- int cached = 0, in_use = 0;
- char info[256];
-
- for (uint idx=0 ; idx < open_cache.records; idx++)
- {
- TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
- if (strcmp(entry->table_cache_key,db) ||
- strcmp(entry->real_name,table_name))
- continue;
-
- cached++;
- if (entry->in_use)
- in_use++;
- }
-
- sprintf(info, "cached=%d, in_use=%d", cached, in_use);
- return thd->strdup(info);
+ DBUG_RETURN(open_list);
}
@@ -195,10 +190,11 @@ query_table_status(THD *thd,const char *db,const char *table_name)
bool
send_fields(THD *thd,List<Item> &list,uint flag)
{
- List_iterator<Item> it(list);
+ List_iterator_fast<Item> it(list);
Item *item;
char buff[80];
- CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set;
+ CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->variables.convert_set;
+ DBUG_ENTER("send_fields");
String tmp((char*) buff,sizeof(buff)),*res,*packet= &thd->packet;
@@ -259,11 +255,11 @@ send_fields(THD *thd,List<Item> &list,uint flag)
if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length()))
break; /* purecov: inspected */
}
- send_eof(&thd->net,(test_flags & TEST_MIT_THREAD) ? 0: 1);
- return 0;
+ send_eof(&thd->net,1);
+ DBUG_RETURN(0);
err:
send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */
- return 1; /* purecov: inspected */
+ DBUG_RETURN(1); /* purecov: inspected */
}
@@ -304,6 +300,7 @@ static void free_cache_entry(TABLE *table)
void free_io_cache(TABLE *table)
{
+ DBUG_ENTER("free_io_cache");
if (table->io_cache)
{
close_cached_file(table->io_cache);
@@ -315,6 +312,7 @@ void free_io_cache(TABLE *table)
my_free((gptr) table->record_pointers,MYF(0));
table->record_pointers=0;
}
+ DBUG_VOID_RETURN;
}
/* Close all tables which aren't in use by any thread */
@@ -418,7 +416,6 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_VOID_RETURN; // LOCK TABLES in use
}
- TABLE *table,*next;
bool found_old_table=0;
if (thd->lock)
@@ -431,41 +428,10 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
- for (table=thd->open_tables ; table ; table=next)
- {
- next=table->next;
- if (table->version != refresh_version ||
- thd->version != refresh_version || !table->db_stat)
- {
- VOID(hash_delete(&open_cache,(byte*) table));
- found_old_table=1;
- }
- else
- {
- if (table->flush_version != flush_version)
- {
- table->flush_version=flush_version;
- table->file->extra(HA_EXTRA_FLUSH);
- }
- else
- {
- // Free memory and reset for next loop
- table->file->extra(HA_EXTRA_RESET);
- }
- table->in_use=0;
- if (unused_tables)
- {
- table->next=unused_tables; /* Link in last */
- table->prev=unused_tables->prev;
- unused_tables->prev=table;
- table->prev->next=table;
- }
- else
- unused_tables=table->next=table->prev=table;
- }
- }
+ while (thd->open_tables)
+ found_old_table|=close_thread_table(thd, &thd->open_tables);
thd->some_tables_deleted=0;
- thd->open_tables=0;
+
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
@@ -481,6 +447,48 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_VOID_RETURN;
}
+/* move one table to free list */
+
+bool close_thread_table(THD *thd, TABLE **table_ptr)
+{
+ DBUG_ENTER("close_thread_table");
+
+ bool found_old_table=0;
+ TABLE *table=*table_ptr;
+
+ *table_ptr=table->next;
+ if (table->version != refresh_version ||
+ thd->version != refresh_version || !table->db_stat)
+ {
+ VOID(hash_delete(&open_cache,(byte*) table));
+ found_old_table=1;
+ }
+ else
+ {
+ if (table->flush_version != flush_version)
+ {
+ table->flush_version=flush_version;
+ table->file->extra(HA_EXTRA_FLUSH);
+ }
+ else
+ {
+ // Free memory and reset for next loop
+ table->file->extra(HA_EXTRA_RESET);
+ }
+ table->in_use=0;
+ if (unused_tables)
+ {
+ table->next=unused_tables; /* Link in last */
+ table->prev=unused_tables->prev;
+ unused_tables->prev=table;
+ table->prev->next=table;
+ }
+ else
+ unused_tables=table->next=table->prev=table;
+ }
+ DBUG_RETURN(found_old_table);
+}
+
/* Close and delete temporary tables */
void close_temporary(TABLE *table,bool delete_table)
@@ -505,7 +513,7 @@ void close_temporary_tables(THD *thd)
const uint init_query_buf_size = 11; // "drop table "
uint query_buf_size;
bool found_user_tables = 0;
-
+
LINT_INIT(end);
query_buf_size = init_query_buf_size;
@@ -583,7 +591,7 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name)
table= *prev;
*prev= table->next;
close_temporary(table);
- if(thd->slave_thread)
+ if (thd->slave_thread)
--slave_open_temp_tables;
return 0;
}
@@ -606,8 +614,6 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
}
-
-
/* move table first in unused links */
static void relink_unused(TABLE *table)
@@ -685,13 +691,14 @@ void wait_for_refresh(THD *thd)
pthread_mutex_unlock(&thd->mysys_var->mutex);
}
+
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("reopen_name_locked_table");
if (thd->killed)
DBUG_RETURN(0);
TABLE* table;
- if(!(table = table_list->table))
+ if (!(table = table_list->table))
DBUG_RETURN(0);
char* db = thd->db ? thd->db : table_list->db;
@@ -704,11 +711,11 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
if (open_unireg_entry(thd, table, db, table_name, table_name, 1) ||
!(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
key_length)))
- {
- closefrm(table);
- pthread_mutex_unlock(&LOCK_open);
- DBUG_RETURN(0);
- }
+ {
+ closefrm(table);
+ pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(0);
+ }
table->key_length=key_length;
table->version=0;
@@ -723,7 +730,8 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
table->const_table=0;
table->outer_join=table->null_row=table->maybe_null=0;
table->status=STATUS_NO_RECORD;
- table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
+ table->keys_in_use_for_query= table->keys_in_use;
+ table->used_keys= table->keys_for_keyread;
DBUG_RETURN(table);
}
@@ -838,25 +846,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
key_length)))
{
- MEM_ROOT* glob_alloc;
- LINT_INIT(glob_alloc);
-
- if (errno == ENOENT &&
- (glob_alloc = my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC)))
- // Sasha: needed for replication
- // remember the name of the non-existent table
- // so we can try to download it from the master
- {
- int table_name_len = (uint) strlen(table_name);
- int db_len = (uint) strlen(db);
- thd->last_nx_db = alloc_root(glob_alloc,db_len + table_name_len + 2);
- if(thd->last_nx_db)
- {
- thd->last_nx_table = thd->last_nx_db + db_len + 1;
- memcpy(thd->last_nx_table, table_name, table_name_len + 1);
- memcpy(thd->last_nx_db, db, db_len + 1);
- }
- }
table->next=table->prev=table;
free_cache_entry(table);
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -896,8 +885,9 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
table->const_table=0;
table->outer_join=table->null_row=table->maybe_null=0;
table->status=STATUS_NO_RECORD;
- table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
- dbug_assert(table->key_read == 0);
+ table->keys_in_use_for_query= table->keys_in_use;
+ table->used_keys= table->keys_for_keyread;
+ DBUG_ASSERT(table->key_read == 0);
DBUG_RETURN(table);
}
@@ -962,7 +952,8 @@ bool reopen_table(TABLE *table,bool locked)
tmp.null_row= table->null_row;
tmp.maybe_null= table->maybe_null;
tmp.status= table->status;
- tmp.keys_in_use_for_query=tmp.used_keys=tmp.keys_in_use;
+ tmp.keys_in_use_for_query= tmp.keys_in_use;
+ tmp.used_keys= tmp.keys_for_keyread;
/* Get state */
tmp.key_length= table->key_length;
@@ -1181,7 +1172,7 @@ bool wait_for_tables(THD *thd)
/* Now we can open all tables without any interference */
thd->proc_info="Reopen tables";
result=reopen_tables(thd,0,0);
-
+
}
pthread_mutex_unlock(&LOCK_open);
thd->proc_info=0;
@@ -1316,7 +1307,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
if (error)
goto err;
}
- (void) entry->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
@@ -1339,7 +1329,7 @@ int open_tables(THD *thd,TABLE_LIST *start)
{
if (!tables->table &&
!(tables->table=open_table(thd,
- tables->db ? tables->db : thd->db,
+ tables->db,
tables->real_name,
tables->name, &refresh)))
{
@@ -1396,7 +1386,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
DBUG_ENTER("open_ltable");
thd->proc_info="Opening table";
- while (!(table=open_table(thd,table_list->db ? table_list->db : thd->db,
+ while (!(table=open_table(thd,table_list->db,
table_list->real_name,table_list->name,
&refresh)) && refresh) ;
if (table)
@@ -1405,11 +1395,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
#if defined( __WIN__) || defined(OS2)
/* Win32 can't drop a file that is open */
- if (lock_type == TL_WRITE_ALLOW_READ
-#ifdef HAVE_GEMINI_DB
- && table->db_type != DB_TYPE_GEMINI
-#endif /* HAVE_GEMINI_DB */
- )
+ if (lock_type == TL_WRITE_ALLOW_READ)
{
lock_type= TL_WRITE;
}
@@ -1518,7 +1504,6 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
DBUG_RETURN(0);
}
- tmp_table->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
tmp_table->reginfo.lock_type=TL_WRITE; // Simulate locked
tmp_table->tmp_table = (tmp_table->file->has_transactions() ?
TRANSACTIONAL_TMP_TABLE : TMP_TABLE);
@@ -1535,8 +1520,8 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
{
tmp_table->next=thd->temporary_tables;
thd->temporary_tables=tmp_table;
- if(thd->slave_thread)
- ++slave_open_temp_tables;
+ if (thd->slave_thread)
+ slave_open_temp_tables++;
}
DBUG_RETURN(tmp_table);
}
@@ -1596,18 +1581,13 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
{
field->query_id=thd->query_id;
table->used_fields++;
- if (field->part_of_key)
- {
- if (!(field->part_of_key & table->ref_primary_key))
- table->used_keys&=field->part_of_key;
- }
- else
- table->used_keys=0;
+ table->used_keys&= field->part_of_key;
}
else
thd->dupp_field=field;
}
- if (check_grants && !thd->master_access && check_grant_column(thd,table,name,length))
+ if (check_grants && !thd->master_access &&
+ check_grant_column(thd,table,name,length))
return WRONG_GRANT;
return field;
}
@@ -1628,9 +1608,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
for (; tables ; tables=tables->next)
{
if (!strcmp(tables->name,table_name) &&
- (!db ||
- (tables->db && !strcmp(db,tables->db)) ||
- (!tables->db && !strcmp(db,thd->db))))
+ (!db || !strcmp(db,tables->db)))
{
found_table=1;
Field *find=find_field_in_table(thd,tables->table,name,length,
@@ -1673,7 +1651,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
for (; tables ; tables=tables->next)
{
Field *field=find_field_in_table(thd,tables->table,name,length,
- grant_option && !thd->master_access, allow_rowid);
+ grant_option &&
+ !thd->master_access, allow_rowid);
if (field)
{
if (field == WRONG_GRANT)
@@ -1754,14 +1733,15 @@ find_item_in_list(Item *find,List<Item> &items)
****************************************************************************/
int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
- bool set_query_id, List<Item> *sum_func_list)
+ bool set_query_id, List<Item> *sum_func_list,
+ bool allow_sum_func)
{
reg2 Item *item;
List_iterator<Item> it(fields);
DBUG_ENTER("setup_fields");
thd->set_query_id=set_query_id;
- thd->allow_sum_func= test(sum_func_list);
+ thd->allow_sum_func= allow_sum_func;
thd->where="field list";
while ((item=it++))
@@ -1777,7 +1757,8 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
{
if (item->fix_fields(thd,tables))
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)
item->split_sum_func(*sum_func_list);
thd->used_tables|=item->used_tables();
}
@@ -1796,27 +1777,41 @@ bool setup_tables(TABLE_LIST *tables)
{
DBUG_ENTER("setup_tables");
uint tablenr=0;
- for (TABLE_LIST *table=tables ; table ; table=table->next,tablenr++)
- {
- table->table->tablenr=tablenr;
- table->table->map= (table_map) 1 << tablenr;
- if ((table->table->outer_join=table->outer_join))
- table->table->maybe_null=1; // LEFT OUTER JOIN ...
- if (table->use_index)
+ for (TABLE_LIST *table_list=tables ; table_list ;
+ table_list=table_list->next,tablenr++)
+ {
+ TABLE *table=table_list->table;
+
+ table->used_fields=0;
+ table->const_table=0;
+ table->outer_join=table->null_row=0;
+ table->status=STATUS_NO_RECORD;
+ table->keys_in_use_for_query= table->keys_in_use;
+ table->used_keys= table->keys_for_keyread;
+ table->maybe_null=test(table->outer_join=table_list->outer_join);
+ table->tablenr=tablenr;
+ table->map= (table_map) 1 << tablenr;
+ if (table_list->use_index)
{
- key_map map= get_key_map_from_key_list(table->table,
- table->use_index);
+ key_map map= get_key_map_from_key_list(table,
+ table_list->use_index);
if (map == ~(key_map) 0)
DBUG_RETURN(1);
- table->table->keys_in_use_for_query=map;
+ table->keys_in_use_for_query=map;
}
- if (table->ignore_index)
+ if (table_list->ignore_index)
{
- key_map map= get_key_map_from_key_list(table->table,
- table->ignore_index);
+ key_map map= get_key_map_from_key_list(table,
+ table_list->ignore_index);
if (map == ~(key_map) 0)
DBUG_RETURN(1);
- table->table->keys_in_use_for_query &= ~map;
+ table->keys_in_use_for_query &= ~map;
+ }
+ if (table_list->shared)
+ {
+ /* Clear query_id that may have been set by previous select */
+ for (Field **ptr=table->field ; *ptr ; ptr++)
+ (*ptr)->query_id=0;
}
}
if (tablenr > MAX_TABLES)
@@ -1832,7 +1827,7 @@ static key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list)
{
key_map map=0;
- List_iterator<String> it(*index_list);
+ List_iterator_fast<String> it(*index_list);
String *name;
uint pos;
while ((name=it++))
@@ -1853,7 +1848,7 @@ static key_map get_key_map_from_key_list(TABLE *table,
** Returns pointer to last inserted field if ok
****************************************************************************/
-static bool
+bool
insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
const char *table_name, List_iterator<Item> *it)
{
@@ -1868,8 +1863,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
check_grant_all_columns(thd,SELECT_ACL,table) )
DBUG_RETURN(-1);
if (!table_name || (!strcmp(table_name,tables->name) &&
- (!db_name || !tables->db ||
- !strcmp(tables->db,db_name))))
+ (!db_name || !strcmp(tables->db,db_name))))
{
Field **ptr=table->field,*field;
thd->used_tables|=table->map;
@@ -1883,14 +1877,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
if (field->query_id == thd->query_id)
thd->dupp_field=field;
field->query_id=thd->query_id;
-
- if (field->part_of_key)
- {
- if (!(field->part_of_key & table->ref_primary_key))
- table->used_keys&=field->part_of_key;
- }
- else
- table->used_keys=0;
+ table->used_keys&= field->part_of_key;
}
/* All fields are used */
table->used_fields=table->fields;
@@ -1958,7 +1945,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
// TODO: This could be optimized to use hashed names if t2 had a hash
for (j=0 ; j < t2->fields ; j++)
{
- key_map tmp_map;
if (!my_strcasecmp(t1->field[i]->field_name,
t2->field[j]->field_name))
{
@@ -1971,20 +1957,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
/* Mark field used for table cache */
t1->field[i]->query_id=t2->field[j]->query_id=thd->query_id;
cond_and->list.push_back(tmp);
- if ((tmp_map=t1->field[i]->part_of_key))
- {
- if (!(tmp_map & t1->ref_primary_key))
- t1->used_keys&=tmp_map;
- }
- else
- t1->used_keys=0;
- if ((tmp_map=t2->field[j]->part_of_key))
- {
- if (!(tmp_map & t2->ref_primary_key))
- t2->used_keys&=tmp_map;
- }
- else
- t2->used_keys=0;
+ t1->used_keys&= t1->field[i]->part_of_key;
+ t2->used_keys&= t2->field[j]->part_of_key;
break;
}
}
@@ -2012,7 +1986,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
int
fill_record(List<Item> &fields,List<Item> &values)
{
- List_iterator<Item> f(fields),v(values);
+ List_iterator_fast<Item> f(fields),v(values);
Item *value;
Item_field *field;
DBUG_ENTER("fill_record");
@@ -2030,7 +2004,7 @@ fill_record(List<Item> &fields,List<Item> &values)
int
fill_record(Field **ptr,List<Item> &values)
{
- List_iterator<Item> v(values);
+ List_iterator_fast<Item> v(values);
Item *value;
DBUG_ENTER("fill_record");
@@ -2093,7 +2067,8 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
create_info.db_type=DB_TYPE_DEFAULT;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
- fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
+ fields, keys, drop, alter, (ORDER*)0, FALSE,
+ DUP_ERROR));
}
@@ -2108,7 +2083,8 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
create_info.db_type=DB_TYPE_DEFAULT;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
- fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
+ fields, keys, drop, alter, (ORDER*)0, FALSE,
+ DUP_ERROR));
}
/*****************************************************************************
@@ -2173,7 +2149,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
THD *in_use;
table->version=0L; /* Free when thread is ready */
if (!(in_use=table->in_use))
+ {
+ DBUG_PRINT("info",("Table was not in use"));
relink_unused(table);
+ }
else if (in_use != thd)
{
in_use->some_tables_deleted=1;
@@ -2203,8 +2182,8 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
int setup_ftfuncs(THD *thd)
{
- List_iterator<Item_func_match> li(thd->lex.ftfunc_list),
- lj(thd->lex.ftfunc_list);
+ List_iterator<Item_func_match> li(thd->lex.select->ftfunc_list),
+ lj(thd->lex.select->ftfunc_list);
Item_func_match *ftf, *ftf2;
while ((ftf=li++))
@@ -2224,16 +2203,17 @@ int setup_ftfuncs(THD *thd)
int init_ftfuncs(THD *thd, bool no_order)
{
- List_iterator<Item_func_match> li(thd->lex.ftfunc_list);
- Item_func_match *ifm;
- DBUG_PRINT("info",("Performing FULLTEXT search"));
- thd->proc_info="FULLTEXT initialization";
-
- while ((ifm=li++))
+ if (thd->lex.select->ftfunc_list.elements)
{
- ifm->init_search(no_order);
- }
+ List_iterator<Item_func_match> li(thd->lex.select->ftfunc_list);
+ Item_func_match *ifm;
+ DBUG_PRINT("info",("Performing FULLTEXT search"));
+ thd->proc_info="FULLTEXT initialization";
+ while ((ifm=li++))
+ {
+ ifm->init_search(no_order);
+ }
+ }
return 0;
}
-
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 09d436c0c9c..cba9f17359a 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1,98 +1,3487 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/*
+ Description of the query cache:
+
+1. Query_cache object consists of
+ - query cache memory pool (cache)
+ - queries hash (queries)
+ - tables hash (tables)
+ - list of blocks ordered as they allocated in memory
+(first_block)
+ - list of queries block (queries_blocks)
+ - list of used tables (tables_blocks)
+
+2. Query cache memory pool (cache) consists of
+ - table of steps of memory bins allocation
+ - table of free memory bins
+ - blocks of memory
+
+3. Memory blocks
+
+Every memory block has the following structure:
+
++----------------------------------------------------------+
+| Block header (Query_cache_block structure) |
++----------------------------------------------------------+
+|Table of database table lists (used for queries & tables) |
++----------------------------------------------------------+
+| Type depended header |
+|(Query_cache_query, Query_cache_table, Query_cache_result)|
++----------------------------------------------------------+
+| Data ... |
++----------------------------------------------------------+
+
+Block header consists of:
+- type:
+ FREE Free memory block
+ QUERY Query block
+ RESULT Ready to send result
+ RES_CONT Result's continuation
+ RES_BEG First block of results, that is not yet complete,
+ written to cache
+ RES_INCOMPLETE Allocated for results data block
+ TABLE Block with database table description
+ INCOMPLETE The destroyed block
+- length of block (length)
+- length of data & headers (used)
+- physical list links (pnext/pprev) - used for the list of
+ blocks ordered as they are allocated in physical memory
+- logical list links (next/prev) - used for queries block list, tables block
+ list, free memory block lists and list of results block in query
+- number of elements in table of database table list (n_tables)
+
+4. Query & results blocks
+
+Query stored in cache consists of following blocks:
+
+more more
+recent+-------------+ old
+<-----|Query block 1|------> double linked list of queries block
+ prev | | next
+ +-------------+
+ <-| table 0 |-> (see "Table of database table lists" description)
+ <-| table 1 |->
+ | ... | +--------------------------+
+ +-------------+ +-------------------------+ |
+NET | | | V V |
+struct| | +-+------------+ +------------+ |
+<-----|query header |----->|Result block|-->|Result block|-+ doublelinked
+writer| |result| |<--| | list of results
+ +-------------+ +------------+ +------------+
+ |charset | +------------+ +------------+ no table of dbtables
+ |encoding + | | result | | result |
+ |query text |<-----| header | | header |------+
+ +-------------+parent| | | |parent|
+ ^ +------------+ +------------+ |
+ | |result data | |result data | |
+ | +------------+ +------------+ |
+ +---------------------------------------------------+
+
+First query is registered. During the registration query block is
+allocated. This query block is included in query hash and is linked
+with appropriate database tables lists (if there is no appropriate
+list exists it will be created).
+
+Later when query has performed results is written into the result blocks.
+A result block cannot be smaller then QUERY_CACHE_MIN_RESULT_DATA_SIZE.
+
+When new result is written to cache it is appended to the last result
+block, if no more free space left in the last block, new block is
+allocated.
+
+5. Table of database table lists.
+
+For quick invalidation of queries all query are linked in lists on used
+database tables basis (when table will be changed (insert/delete/...)
+this queries will be removed from cache).
+
+Root of such list is table block:
+
+ +------------+ list of used tables (used while invalidation of
+<----| Table |-----> whole database)
+ prev| block |next +-----------+
+ | | +-----------+ |Query block|
+ | | |Query block| +-----------+
+ +------------+ +-----------+ | ... |
+ +->| table 0 |------>|table 0 |----->| table N |---+
+ |+-| |<------| |<-----| |<-+|
+ || +------------+ | ... | | ... | ||
+ || |table header| +-----------+ +-----------+ ||
+ || +------------+ | ... | | ... | ||
+ || |db name + | +-----------+ +-----------+ ||
+ || |table name | ||
+ || +------------+ ||
+ |+--------------------------------------------------------+|
+ +----------------------------------------------------------+
+
+Table block is included into the tables hash (tables).
+
+6. Free blocks, free blocks bins & steps of freeblock bins.
+
+When we just started only one free memory block existed. All query
+cache memory (that will be used for block allocation) were
+containing in this block.
+When a new block is allocated we find most suitable memory block
+(minimal of >= required size). If such a block can not be found, we try
+to find max block < required size (if we allocate block for results).
+If there is no free memory, oldest query is removed from cache, and then
+we try to allocate memory. Last step should be repeated until we find
+suitable block or until there is no unlocked query found.
+
+If the block is found and its length more then we need, it should be
+split into 2 blocks.
+New blocks cannot be smaller then min_allocation_unit_bytes.
+
+When a block becomes free, its neighbor-blocks should be tested and if
+there are free blocks among them, they should be joined into one block.
+
+Free memory blocks are stored in bins according to their sizes.
+The bins are stored in size-descending order.
+These bins are distributed (by size) approximately logarithmically.
+
+First bin (number 0) stores free blocks with
+size <= query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2.
+It is first (number 0) step.
+On the next step distributed (1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
+QUERY_CACHE_MEM_BIN_PARTS_MUL bins. This bins allocated in interval from
+query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 to
+query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 >>
+QUERY_CACHE_MEM_BIN_STEP_PWR2
+...
+On each step interval decreases in 2 power of
+QUERY_CACHE_MEM_BIN_STEP_PWR2
+times, number of bins (that distributed on this step) increases. If on
+the previous step there were N bins distributed , on the current there
+would be distributed
+(N + QUERY_CACHE_MEM_BIN_PARTS_INC) * QUERY_CACHE_MEM_BIN_PARTS_MUL
+bins.
+Last distributed bin stores blocks with size near min_allocation_unit
+bytes.
+
+For example:
+ query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 = 100,
+ min_allocation_unit = 17,
+ QUERY_CACHE_MEM_BIN_STEP_PWR2 = 1,
+ QUERY_CACHE_MEM_BIN_PARTS_INC = 1,
+ QUERY_CACHE_MEM_BIN_PARTS_MUL = 1
+ (in followed picture showed right (low) bound of bin):
+
+ | 100>>1 50>>1 |25>>1|
+ | | | | | |
+ | 100 75 50 41 33 25 21 18 15| 12 | - bins right (low) bounds
+
+ |\---/\-----/\--------/\--------|---/ |
+ | 0 1 2 3 | | - steps
+ \-----------------------------/ \---/
+ bins that we store in cache this bin showed for example only
+
+
+Calculation of steps/bins distribution is performed only when query cache
+is resized.
+
+When we need to find appropriate bin, first we should find appropriate
+step, then we should calculate number of bins that are using data
+stored in Query_cache_memory_bin_step structure.
+
+Free memory blocks are sorted in bins in lists with size-ascending order
+(more small blocks needed frequently then bigger one).
+
+7. Packing cache.
+
+Query cache packing is divided into two operation:
+ - pack_cache
+ - join_results
+
+pack_cache moved all blocks to "top" of cache and create one block of free
+space at the "bottom":
+
+ before pack_cache after pack_cache
+ +-------------+ +-------------+
+ | query 1 | | query 1 |
+ +-------------+ +-------------+
+ | table 1 | | table 1 |
+ +-------------+ +-------------+
+ | results 1.1 | | results 1.1 |
+ +-------------+ +-------------+
+ | free | | query 2 |
+ +-------------+ +-------------+
+ | query 2 | | table 2 |
+ +-------------+ ---> +-------------+
+ | table 2 | | results 1.2 |
+ +-------------+ +-------------+
+ | results 1.2 | | results 2 |
+ +-------------+ +-------------+
+ | free | | free |
+ +-------------+ | |
+ | results 2 | | |
+ +-------------+ | |
+ | free | | |
+ +-------------+ +-------------+
+
+pack_cache scan blocks in physical address order and move every non-free
+block "higher".
+
+pack_cach remove every free block it finds. The length of the deleted block
+is accumulated to the "gap". All non free blocks should be shifted with the
+"gap" step.
+
+join_results scans all complete queries. If the results of query are not
+stored in the same block, join_results tries to move results so, that they
+are stored in one block.
+
+ before join_results after join_results
+ +-------------+ +-------------+
+ | query 1 | | query 1 |
+ +-------------+ +-------------+
+ | table 1 | | table 1 |
+ +-------------+ +-------------+
+ | results 1.1 | | free |
+ +-------------+ +-------------+
+ | query 2 | | query 2 |
+ +-------------+ +-------------+
+ | table 2 | | table 2 |
+ +-------------+ ---> +-------------+
+ | results 1.2 | | free |
+ +-------------+ +-------------+
+ | results 2 | | results 2 |
+ +-------------+ +-------------+
+ | free | | results 1 |
+ | | | |
+ | | +-------------+
+ | | | free |
+ | | | |
+ +-------------+ +-------------+
+
+If join_results allocated new block(s) then we need call pack_cache again.
+
+TODO list:
+
+ - 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);
+*/
+
#include "mysql_priv.h"
+#ifdef HAVE_QUERY_CACHE
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
+#include "sql_acl.h"
+#include "ha_myisammrg.h"
+#ifndef MASTER
+#include "../srclib/myisammrg/myrg_def.h"
+#else
+#include "../myisammrg/myrg_def.h"
+#endif
+#include <assert.h>
+
+#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
+#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
+ pthread_mutex_lock(M);}
+#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
+ (ulong)(M))); pthread_mutex_unlock(M);}
+#define RW_WLOCK(M) {DBUG_PRINT("lock", ("rwlock wlock 0x%lx",(ulong)(M))); \
+ if (!rw_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")) \
+ else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
+#define RW_RLOCK(M) {DBUG_PRINT("lock", ("rwlock rlock 0x%lx", (ulong)(M))); \
+ if (!rw_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")) \
+ else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
+#define RW_UNLOCK(M) {DBUG_PRINT("lock", ("rwlock unlock 0x%lx",(ulong)(M))); \
+ if (!rw_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")) \
+ else DBUG_PRINT("lock", ("rwlock unlock FAILED %d", errno)); }
+#define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \
+ pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));}
+#define STRUCT_UNLOCK(M) { \
+ DBUG_PRINT("lock", ("%d struct unlock...",__LINE__)); \
+ pthread_mutex_unlock(M);DBUG_PRINT("lock", ("struct unlock OK"));}
+#define BLOCK_LOCK_WR(B) {DBUG_PRINT("lock", ("%d LOCK_WR 0x%lx",\
+ __LINE__,(ulong)(B))); \
+ B->query()->lock_writing();}
+#define BLOCK_LOCK_RD(B) {DBUG_PRINT("lock", ("%d LOCK_RD 0x%lx",\
+ __LINE__,(ulong)(B))); \
+ B->query()->lock_reading();}
+#define BLOCK_UNLOCK_WR(B) { \
+ DBUG_PRINT("lock", ("%d UNLOCK_WR 0x%lx",\
+ __LINE__,(ulong)(B)));B->query()->unlock_writing();}
+#define BLOCK_UNLOCK_RD(B) { \
+ DBUG_PRINT("lock", ("%d UNLOCK_RD 0x%lx",\
+ __LINE__,(ulong)(B)));B->query()->unlock_reading();}
+#define DUMP(C) DBUG_EXECUTE("qcache", {\
+ (C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();})
+#else
+#define MUTEX_LOCK(M) pthread_mutex_lock(M)
+#define MUTEX_UNLOCK(M) pthread_mutex_unlock(M)
+#define RW_WLOCK(M) rw_wrlock(M)
+#define RW_RLOCK(M) rw_rdlock(M)
+#define RW_UNLOCK(M) rw_unlock(M)
+#define STRUCT_LOCK(M) pthread_mutex_lock(M)
+#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M)
+#define BLOCK_LOCK_WR(B) B->query()->lock_writing()
+#define BLOCK_LOCK_RD(B) B->query()->lock_reading()
+#define BLOCK_UNLOCK_WR(B) B->query()->unlock_writing()
+#define BLOCK_UNLOCK_RD(B) B->query()->unlock_reading()
+#define DUMP(C)
+#endif
+
+const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND",NullS };
+TYPELIB query_cache_type_typelib=
+{
+ array_elements(query_cache_type_names)-1,"", query_cache_type_names
+};
+
+/*****************************************************************************
+ Query_cache_block_table method(s)
+*****************************************************************************/
+
+inline Query_cache_block * Query_cache_block_table::block()
+{
+ return (Query_cache_block *)(((byte*)this) -
+ ALIGN_SIZE(sizeof(Query_cache_block_table)*n) -
+ ALIGN_SIZE(sizeof(Query_cache_block)));
+};
+
+/*****************************************************************************
+ Query_cache_block method(s)
+*****************************************************************************/
+
+void Query_cache_block::init(ulong block_length)
+{
+ DBUG_ENTER("Query_cache_block::init");
+ DBUG_PRINT("qcache", ("init block 0x%lx length: %lu", (ulong) this,
+ block_length));
+ length = block_length;
+ used = 0;
+ type = Query_cache_block::FREE;
+ n_tables = 0;
+ DBUG_VOID_RETURN;
+}
+
+void Query_cache_block::destroy()
+{
+ DBUG_ENTER("Query_cache_block::destroy");
+ DBUG_PRINT("qcache", ("destroy block 0x%lx, type %d",
+ (ulong) this, type));
+ type = INCOMPLETE;
+ DBUG_VOID_RETURN;
+}
+
+inline uint Query_cache_block::headers_len()
+{
+ return (ALIGN_SIZE(sizeof(Query_cache_block_table)*n_tables) +
+ ALIGN_SIZE(sizeof(Query_cache_block)));
+}
+
+inline gptr Query_cache_block::data(void)
+{
+ return (gptr)( ((byte*)this) + headers_len() );
+}
+
+inline Query_cache_query * Query_cache_block::query()
+{
+#ifndef DBUG_OFF
+ if (type != QUERY)
+ query_cache.wreck(__LINE__, "incorrect block type");
+#endif
+ return (Query_cache_query *) data();
+}
+
+inline Query_cache_table * Query_cache_block::table()
+{
+#ifndef DBUG_OFF
+ if (type != TABLE)
+ query_cache.wreck(__LINE__, "incorrect block type");
+#endif
+ return (Query_cache_table *) data();
+}
+
+inline Query_cache_result * Query_cache_block::result()
+{
+#ifndef DBUG_OFF
+ if (type != RESULT && type != RES_CONT && type != RES_BEG &&
+ type != RES_INCOMPLETE)
+ query_cache.wreck(__LINE__, "incorrect block type");
+#endif
+ return (Query_cache_result *) data();
+}
+
+inline Query_cache_block_table * Query_cache_block::table(TABLE_COUNTER_TYPE n)
+{
+ return ((Query_cache_block_table *)
+ (((byte*)this)+ALIGN_SIZE(sizeof(Query_cache_block)) +
+ n*sizeof(Query_cache_block_table)));
+}
+
+
+/*****************************************************************************
+ * Query_cache_table method(s)
+ *****************************************************************************/
+
+extern "C"
+{
+byte *query_cache_table_get_key(const byte *record, uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ Query_cache_block* table_block = (Query_cache_block*) record;
+ *length = (table_block->used - table_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_table)));
+ return (((byte *) table_block->data()) +
+ ALIGN_SIZE(sizeof(Query_cache_table)));
+}
+}
+
+/*****************************************************************************
+ Query_cache_query methods
+*****************************************************************************/
+
+void Query_cache_query::init_n_lock()
+{
+ DBUG_ENTER("Query_cache_query::init_n_lock");
+ res=0; wri = 0; len = 0;
+ my_rwlock_init(&lock, NULL);
+ lock_writing();
+ DBUG_PRINT("qcache", ("inited & locked query for block 0x%lx",
+ ((byte*) this)-ALIGN_SIZE(sizeof(Query_cache_block))));
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache_query::unlock_n_destroy()
+{
+ DBUG_ENTER("Query_cache_query::unlock_n_destroy");
+ DBUG_PRINT("qcache", ("destroyed & unlocked query for block 0x%lx",
+ ((byte*)this)-ALIGN_SIZE(sizeof(Query_cache_block))));
+ /*
+ The following call is not needed on system where one can destroy an
+ active semaphore
+ */
+ this->unlock_writing();
+ rwlock_destroy(&lock);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Following methods work for block read/write locking only in this
+ particular case and in interaction with structure_guard_mutex.
+
+ Lock for write prevents any other locking. (exclusive use)
+ Lock for read prevents only locking for write.
+*/
+
+inline void Query_cache_query::lock_writing()
+{
+ RW_WLOCK(&lock);
+}
+
+
+/*
+ Needed for finding queries, that we may delete from cache.
+ We don't want to wait while block become unlocked. In addition,
+ block locking means that query is now used and we don't need to
+ remove it.
+*/
+
+my_bool Query_cache_query::try_lock_writing()
+{
+ DBUG_ENTER("Query_cache_block::try_lock_writing");
+ if (rw_trywrlock(&lock)!=0)
+ {
+ DBUG_PRINT("info", ("can't lock rwlock"));
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("info", ("rwlock 0x%lx locked", (ulong) &lock));
+ DBUG_RETURN(1);
+}
+
+
+inline void Query_cache_query::lock_reading()
+{
+ RW_RLOCK(&lock);
+}
+
+
+inline void Query_cache_query::unlock_writing()
+{
+ RW_UNLOCK(&lock);
+}
+
+
+inline void Query_cache_query::unlock_reading()
+{
+ RW_UNLOCK(&lock);
+}
+
+extern "C"
+{
+byte *query_cache_query_get_key(const byte *record, uint *length,
+ my_bool not_used)
+{
+ Query_cache_block *query_block = (Query_cache_block*) record;
+ *length = (query_block->used - query_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_query)));
+ return (((byte *) query_block->data()) +
+ ALIGN_SIZE(sizeof(Query_cache_query)));
+}
+}
+
+/*****************************************************************************
+ Functions to store things into the query cache
+*****************************************************************************/
+
+/*
+ Insert the packet into the query cache.
+ This should only be called if net->query_cache_query != 0
+*/
+
+void query_cache_insert(NET *net, const char *packet, ulong length)
+{
+ DBUG_ENTER("query_cache_insert");
+
+#ifndef DBUG_OFF
+ // Check if we have called query_cache.wreck() (which disables the cache)
+ if (query_cache.query_cache_size == 0)
+ DBUG_VOID_RETURN;
+#endif
+
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+ Query_cache_block *query_block = ((Query_cache_block*)
+ net->query_cache_query);
+ if (query_block)
+ {
+ Query_cache_query *header = query_block->query();
+ Query_cache_block *result = header->result();
-#define SQL_CACHE_LENGTH 30 // 300 crashes apple gcc.
+ DUMP(&query_cache);
+ BLOCK_LOCK_WR(query_block);
+ DBUG_PRINT("qcache", ("insert packet %lu bytes long",length));
+
+ /*
+ On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be
+ done by query_cache.append_result_data if success (if not we need
+ query_cache.structure_guard_mutex locked to free query)
+ */
+ if (!query_cache.append_result_data(&result, length, (gptr) packet,
+ query_block))
+ {
+ query_cache.refused++;
+ DBUG_PRINT("warning", ("Can't append data"));
+ header->result(result);
+ DBUG_PRINT("qcache", ("free query 0x%lx", (ulong) query_block));
+ // The following call will remove the lock on query_block
+ query_cache.free_query(query_block);
+ // append_result_data no success => we need unlock
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ DBUG_VOID_RETURN;
+ }
+ header->result(result);
+ BLOCK_UNLOCK_WR(query_block);
+ }
+ else
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+ DBUG_VOID_RETURN;
+}
-HASH sql_cache;
-static LEX lex_array_static[SQL_CACHE_LENGTH];
-LEX * lex_array = lex_array_static;
-int last_lex_array_item = SQL_CACHE_LENGTH - 1;
-/* Function to return a text string from a LEX struct */
-static byte *cache_key(const byte *record, uint *length, my_bool not_used)
+void query_cache_abort(NET *net)
{
-#ifdef QQ
- LEX *lex=(LEX*) record;
- *length = lex->sql_query_length;
- // *length = strlen(lex->ptr);
- return (byte*) lex->sql_query_text;
- // return (byte*) lex->ptr;
+ DBUG_ENTER("query_cache_abort");
+
+#ifndef DBUG_OFF
+ // Check if we have called query_cache.wreck() (which disables the cache)
+ if (query_cache.query_cache_size == 0)
+ DBUG_VOID_RETURN;
#endif
- return 0;
+ if (net->query_cache_query != 0) // Quick check on unlocked structure
+ {
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+ Query_cache_block *query_block = ((Query_cache_block*)
+ net->query_cache_query);
+ if (query_block) // Test if changed by other thread
+ {
+ DUMP(&query_cache);
+ BLOCK_LOCK_WR(query_block);
+ // The following call will remove the lock on query_block
+ query_cache.free_query(query_block);
+ }
+ net->query_cache_query=0;
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void query_cache_end_of_result(NET *net)
+{
+ DBUG_ENTER("query_cache_end_of_result");
+
+#ifndef DBUG_OFF
+ // Check if we have called query_cache.wreck() (which disables the cache)
+ if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN;
+#endif
+
+ if (net->query_cache_query != 0) // Quick check on unlocked structure
+ {
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+ Query_cache_block *query_block = ((Query_cache_block*)
+ net->query_cache_query);
+ if (query_block)
+ {
+ DUMP(&query_cache);
+ 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);
+
+#ifndef DBUG_OFF
+ if (header->result() == 0)
+ {
+ DBUG_PRINT("error", ("end of data whith no result. query '%s'",
+ header->query()));
+ query_cache.wreck(__LINE__, "");
+ DBUG_VOID_RETURN;
+ }
+#endif
+ header->found_rows(current_thd->limit_found_rows);
+ header->result()->type = Query_cache_block::RESULT;
+ header->writer(0);
+ BLOCK_UNLOCK_WR(query_block);
+ }
+ else
+ {
+ // Cache was flushed or resized and query was deleted => do nothing
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ }
+ net->query_cache_query=0;
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+ }
+ DBUG_VOID_RETURN;
+}
+
+void query_cache_invalidate_by_MyISAM_filename(const char *filename)
+{
+ query_cache.invalidate_by_MyISAM_filename(filename);
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+}
+
+
+/*****************************************************************************
+ Query_cache methods
+*****************************************************************************/
+
+Query_cache::Query_cache(ulong query_cache_limit,
+ ulong min_allocation_unit,
+ ulong min_result_data_size,
+ uint def_query_hash_size ,
+ uint def_table_hash_size)
+ :query_cache_size(0),
+ query_cache_limit(query_cache_limit),
+ queries_in_cache(0), hits(0), inserts(0), refused(0),
+ total_blocks(0),
+ min_allocation_unit(ALIGN_SIZE(min_allocation_unit)),
+ min_result_data_size(ALIGN_SIZE(min_result_data_size)),
+ def_query_hash_size(ALIGN_SIZE(def_query_hash_size)),
+ def_table_hash_size(ALIGN_SIZE(def_table_hash_size)),
+ initialized(0)
+{
+ ulong min_needed=(ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_block_table)) +
+ ALIGN_SIZE(sizeof(Query_cache_query)) + 3);
+ set_if_bigger(min_allocation_unit,min_needed);
+ this->min_allocation_unit = ALIGN_SIZE(min_allocation_unit);
+ set_if_bigger(this->min_result_data_size,min_allocation_unit);
+}
+
+
+ulong Query_cache::resize(ulong query_cache_size_arg)
+{
+ DBUG_ENTER("Query_cache::resize");
+ DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size,
+ query_cache_size_arg));
+ free_cache(0);
+ query_cache_size=query_cache_size_arg;
+ DBUG_RETURN(init_cache());
+}
+
+
+void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
+{
+ TABLE_COUNTER_TYPE tables;
+ ulong tot_length;
+ DBUG_ENTER("Query_cache::store_query");
+ if (query_cache_size == 0)
+ DBUG_VOID_RETURN;
+
+ if ((tables = is_cacheable(thd, thd->query_length,
+ thd->query, &thd->lex, tables_used)))
+ {
+ NET *net = &thd->net;
+ byte flags = (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0);
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ if (query_cache_size == 0)
+ DBUG_VOID_RETURN;
+ DUMP(this);
+
+ /* Key is query + database + flag */
+ if (thd->db_length)
+ {
+ memcpy(thd->query+thd->query_length+1, thd->db, thd->db_length);
+ DBUG_PRINT("qcache", ("database : %s length %u",
+ thd->db, thd->db_length));
+ }
+ else
+ {
+ DBUG_PRINT("qcache", ("No active database"));
+ }
+ /*
+ Prepare flags:
+ most significant bit - CLIENT_LONG_FLAG,
+ other - charset number (0 no charset convertion)
+ */
+ if (thd->variables.convert_set != 0)
+ {
+ flags|= (byte) thd->variables.convert_set->number();
+ DBUG_ASSERT(thd->variables.convert_set->number() < 128);
+ }
+ tot_length=thd->query_length+thd->db_length+2;
+ thd->query[tot_length-1] = (char) flags;
+
+ /* Check if another thread is processing the same query? */
+ Query_cache_block *competitor = (Query_cache_block *)
+ hash_search(&queries, (byte*) thd->query, tot_length);
+ DBUG_PRINT("qcache", ("competitor 0x%lx, flags %x", (ulong) competitor,
+ flags));
+ if (competitor == 0)
+ {
+ /* Query is not in cache and no one is working with it; Store it */
+ Query_cache_block *query_block;
+ query_block= write_block_data(tot_length, (gptr) thd->query,
+ ALIGN_SIZE(sizeof(Query_cache_query)),
+ Query_cache_block::QUERY, tables, 1);
+ if (query_block != 0)
+ {
+ DBUG_PRINT("qcache", ("query block 0x%lx allocated, %lu",
+ (ulong) query_block, query_block->used));
+
+ Query_cache_query *header = query_block->query();
+ header->init_n_lock();
+ if (hash_insert(&queries, (byte*) query_block))
+ {
+ refused++;
+ DBUG_PRINT("qcache", ("insertion in query hash"));
+ header->unlock_n_destroy();
+ free_memory_block(query_block);
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ goto end;
+ }
+ if (!register_all_tables(query_block, tables_used, tables))
+ {
+ refused++;
+ DBUG_PRINT("warning", ("tables list including failed"));
+ hash_delete(&queries, (byte *) query_block);
+ header->unlock_n_destroy();
+ free_memory_block(query_block);
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ goto end;
+ }
+ double_linked_list_simple_include(query_block, &queries_blocks);
+ inserts++;
+ queries_in_cache++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
+ net->query_cache_query= (gptr) query_block;
+ header->writer(net);
+ // init_n_lock make query block locked
+ BLOCK_UNLOCK_WR(query_block);
+ }
+ else
+ {
+ // We have not enough memory to store query => do nothing
+ refused++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_PRINT("warning", ("Can't allocate query"));
+ }
+ }
+ else
+ {
+ // Another thread is processing the same query => do nothing
+ refused++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_PRINT("qcache", ("Another thread process same query"));
+ }
+ }
+ else
+ statistic_increment(refused, &structure_guard_mutex);
+
+end:
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Check if the query is in the cache. If it was cached, send it
+ to the user.
+
+ RESULTS
+ 1 Query was not cached.
+ 0 The query was cached and user was sent the result.
+ -1 The query was cached but we didn't have rights to use it.
+ No error is sent to the client yet.
+*/
+
+
+
+int
+Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
+{
+ Query_cache_query *query;
+ Query_cache_block *first_result_block, *result_block;
+ Query_cache_block_table *block_table, *block_table_end;
+ ulong tot_length;
+ byte flags;
+ DBUG_ENTER("Query_cache::send_result_to_client");
+
+ if (query_cache_size == 0 ||
+ /*
+ it is not possible to check has_transactions() function of handler
+ because tables not opened yet
+ */
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
+ thd->variables.query_cache_type == 0)
+
+ {
+ DBUG_PRINT("qcache", ("query cache disabled or not in autocommit mode"));
+ goto err;
+ }
+
+ /* Check that we haven't forgot to reset the query cache variables */
+ DBUG_ASSERT(thd->net.query_cache_query == 0);
+
+ if (!thd->safe_to_cache_query)
+ {
+ DBUG_PRINT("qcache", ("SELECT is non-cacheable"));
+ goto err;
+ }
+
+ /*
+ Test if the query is a SELECT
+ (pre-space is removed in dispatch_command)
+ */
+ if (toupper(sql[0]) != 'S' || toupper(sql[1]) != 'E' ||
+ toupper(sql[2]) !='L')
+ {
+ DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
+ goto err;
+ }
+
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size == 0)
+ {
+ DBUG_PRINT("qcache", ("query cache disabled"));
+ goto err_unlock;
+ }
+ Query_cache_block *query_block;
+
+ tot_length=query_length+thd->db_length+2;
+ if (thd->db_length)
+ {
+ memcpy(sql+query_length+1, thd->db, thd->db_length);
+ DBUG_PRINT("qcache", ("database: '%s' length %u",
+ thd->db, thd->db_length));
+ }
+ else
+ {
+ DBUG_PRINT("qcache", ("No active database"));
+ }
+ /*
+ prepare flags:
+ Most significant bit - CLIENT_LONG_FLAG,
+ Other - charset number (0 no charset convertion)
+ */
+ flags = (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0);
+ if (thd->variables.convert_set != 0)
+ {
+ flags |= (byte) thd->variables.convert_set->number();
+ DBUG_ASSERT(thd->variables.convert_set->number() < 128);
+ }
+ sql[tot_length-1] = (char) flags;
+ query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql,
+ tot_length);
+ /* Quick abort on unlocked data */
+ if (query_block == 0 ||
+ query_block->query()->result() == 0 ||
+ query_block->query()->result()->type != Query_cache_block::RESULT)
+ {
+ DBUG_PRINT("qcache", ("No query in query hash or no results"));
+ goto err_unlock;
+ }
+ DBUG_PRINT("qcache", ("Query in query hash 0x%lx", (ulong)query_block));
+
+ /* Now lock and test that nothing changed while blocks was unlocked */
+ BLOCK_LOCK_RD(query_block);
+
+ query = query_block->query();
+ result_block= first_result_block= query->result();
+
+ if (result_block == 0 || result_block->type != Query_cache_block::RESULT)
+ {
+ /* The query is probably yet processed */
+ DBUG_PRINT("qcache", ("query found, but no data or data incomplete"));
+ BLOCK_UNLOCK_RD(query_block);
+ goto err_unlock;
+ }
+ DBUG_PRINT("qcache", ("Query have result 0x%lx", (ulong) query));
+
+ // Check access;
+ block_table= query_block->table(0);
+ block_table_end= block_table+query_block->n_tables;
+ for (; block_table != block_table_end; block_table++)
+ {
+ TABLE_LIST table_list;
+ bzero((char*) &table_list,sizeof(table_list));
+
+ Query_cache_table *table = block_table->parent;
+ table_list.db = table->db();
+ table_list.name = table_list.real_name = table->table();
+ if (check_table_access(thd,SELECT_ACL,&table_list,1))
+ {
+ DBUG_PRINT("qcache",
+ ("probably no SELECT access to %s.%s => return to normal processing",
+ table_list.db, table_list.name));
+ refused++; // This is actually a hit
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ thd->safe_to_cache_query=0; // Don't try to cache this
+ BLOCK_UNLOCK_RD(query_block);
+ DBUG_RETURN(-1); // Privilege error
+ }
+ if (table_list.grant.want_privilege)
+ {
+ DBUG_PRINT("qcache", ("Need to check column privileges for %s.%s",
+ table_list.db, table_list.name));
+ BLOCK_UNLOCK_RD(query_block);
+ thd->safe_to_cache_query=0; // Don't try to cache this
+ goto err_unlock; // Parse query
+ }
+ }
+ move_to_query_list_end(query_block);
+ hits++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
+ /*
+ Send cached result to client
+ */
+ do
+ {
+ DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)",
+ result_block->length, result_block->used,
+ result_block->headers_len()+
+ ALIGN_SIZE(sizeof(Query_cache_result))));
+
+ Query_cache_result *result = result_block->result();
+ if (net_real_write(&thd->net, result->data(),
+ result_block->used -
+ result_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_result))))
+ break; // Client aborted
+ result_block = result_block->next;
+ } while (result_block != first_result_block);
+
+ thd->limit_found_rows = query->found_rows();
+
+ BLOCK_UNLOCK_RD(query_block);
+ DBUG_RETURN(1); // Result sent to client
+
+err_unlock:
+ STRUCT_UNLOCK(&structure_guard_mutex);
+err:
+ DBUG_RETURN(0); // Query was not cached
+}
+
+/*
+ Remove all cached queries that uses any of the tables in the list
+*/
+
+void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
+ my_bool using_transactions)
+{
+ DBUG_ENTER("Query_cache::invalidate (table list)");
+ if (query_cache_size > 0)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+
+ using_transactions = using_transactions &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ for (; tables_used; tables_used=tables_used->next)
+ {
+ DBUG_ASSERT(!using_transactions || tables_used->table!=0);
+ if (using_transactions &&
+ tables_used->table->file->has_transactions())
+ /*
+ Tables_used->table can't be 0 in transaction.
+ Only 'drop' invalidate not opened table, but 'drop'
+ force transaction finish.
+ */
+ thd->add_changed_table(tables_used->table);
+ else
+ invalidate_table(tables_used);
+ }
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
+{
+ DBUG_ENTER("Query_cache::invalidate (changed table list)");
+ if (query_cache_size > 0 && tables_used)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+ for (; tables_used; tables_used=tables_used->next)
+ {
+ invalidate_table((byte*) tables_used->key, tables_used->key_length);
+ DBUG_PRINT("qcache", (" db %s, table %s", tables_used->key,
+ tables_used->key+
+ strlen(tables_used->key)+1));
+ }
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Remove all cached queries that uses the given table
+*/
+
+void Query_cache::invalidate(THD *thd, TABLE *table,
+ my_bool using_transactions)
+{
+ DBUG_ENTER("Query_cache::invalidate (table)");
+
+ if (query_cache_size > 0)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ using_transactions = using_transactions &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ if (using_transactions && table->file->has_transactions())
+ thd->add_changed_table(table);
+ else
+ invalidate_table(table);
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Remove all cached queries that uses the given database
+*/
+
+void Query_cache::invalidate(char *db)
+{
+ DBUG_ENTER("Query_cache::invalidate (db)");
+ if (query_cache_size > 0)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+ /* invalidate_table reduce list while only root of list remain */
+ while (tables_blocks !=0 )
+ invalidate_table(tables_blocks);
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
+{
+ DBUG_ENTER("Query_cache::invalidate_by_MyISAM_filename");
+ if (query_cache_size > 0)
+ {
+ /* Calculate the key outside the lock to make the lock shorter */
+ char key[MAX_DBKEY_LENGTH];
+ uint32 db_length;
+ uint key_length= filename_2_table_key(key, filename, &db_length);
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0) // Safety if cache removed
+ {
+ Query_cache_block *table_block;
+ if ((table_block = (Query_cache_block*) hash_search(&tables,
+ (byte*) key,
+ key_length)))
+ invalidate_table(table_block);
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+ /* Remove all queries from cache */
+
+void Query_cache::flush()
+{
+ DBUG_ENTER("Query_cache::flush");
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+ flush_cache();
+ DUMP(this);
+ }
+
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_VOID_RETURN;
+}
+
+ /* Join result in cache in 1 block (if result length > join_limit) */
+
+void Query_cache::pack(ulong join_limit, uint iteration_limit)
+{
+ DBUG_ENTER("Query_cache::pack");
+ uint i = 0;
+ do
+ {
+ pack_cache();
+ } while ((++i < iteration_limit) && join_results(join_limit));
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::destroy()
+{
+ DBUG_ENTER("Query_cache::destroy");
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ }
+ else
+ {
+ free_cache(1);
+ pthread_mutex_destroy(&structure_guard_mutex);
+ initialized = 0;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*****************************************************************************
+ init/destroy
+*****************************************************************************/
+
+void Query_cache::init()
+{
+ DBUG_ENTER("Query_cache::init");
+ pthread_mutex_init(&structure_guard_mutex,MY_MUTEX_INIT_FAST);
+ initialized = 1;
+ DBUG_VOID_RETURN;
+}
+
+
+ulong Query_cache::init_cache()
+{
+ uint mem_bin_count, num, step;
+ ulong mem_bin_size, prev_size, inc;
+ ulong additional_data_size, max_mem_bin_size, approx_additional_data_size;
+ int align;
+
+ DBUG_ENTER("Query_cache::init_cache");
+ if (!initialized)
+ init();
+ approx_additional_data_size = (sizeof(Query_cache) +
+ sizeof(gptr)*(def_query_hash_size+
+ def_query_hash_size));
+ if (query_cache_size < approx_additional_data_size)
+ goto err;
+
+ query_cache_size-= approx_additional_data_size;
+ align= query_cache_size % ALIGN_SIZE(1);
+ if (align)
+ {
+ query_cache_size-= align;
+ approx_additional_data_size+= align;
+ }
+
+ /*
+ Count memory bins number.
+ Check section 6. in start comment for the used algorithm.
+ */
+
+ max_mem_bin_size = query_cache_size >> QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2;
+ mem_bin_count = (uint) ((1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
+ QUERY_CACHE_MEM_BIN_PARTS_MUL);
+ mem_bin_num = 1;
+ mem_bin_steps = 1;
+ mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ prev_size = 0;
+ while (mem_bin_size > min_allocation_unit)
+ {
+ mem_bin_num += mem_bin_count;
+ prev_size = mem_bin_size;
+ mem_bin_size >>= QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ mem_bin_steps++;
+ mem_bin_count += QUERY_CACHE_MEM_BIN_PARTS_INC;
+ mem_bin_count = (uint) (mem_bin_count * QUERY_CACHE_MEM_BIN_PARTS_MUL);
+
+ // Prevent too small bins spacing
+ if (mem_bin_count > (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2))
+ mem_bin_count= (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2);
+ }
+ inc = (prev_size - mem_bin_size) / mem_bin_count;
+ mem_bin_num += (mem_bin_count - (min_allocation_unit - mem_bin_size)/inc);
+ mem_bin_steps++;
+ additional_data_size = ((mem_bin_num+1) *
+ ALIGN_SIZE(sizeof(Query_cache_memory_bin))+
+ (mem_bin_steps *
+ ALIGN_SIZE(sizeof(Query_cache_memory_bin_step))));
+
+ if (query_cache_size < additional_data_size)
+ goto err;
+ query_cache_size -= additional_data_size;
+
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size <= min_allocation_unit)
+ {
+ DBUG_PRINT("qcache",
+ (" query_cache_size <= min_allocation_unit => cache disabled"));
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ goto err;
+ }
+
+ if (!(cache = (byte *)
+ my_malloc_lock(query_cache_size+additional_data_size, MYF(0))))
+ {
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ goto err;
+ }
+
+ DBUG_PRINT("qcache", ("cache length %lu, min unit %lu, %u bins",
+ query_cache_size, min_allocation_unit, mem_bin_num));
+
+ steps = (Query_cache_memory_bin_step *) cache;
+ bins = ((Query_cache_memory_bin *)
+ (cache + mem_bin_steps *
+ ALIGN_SIZE(sizeof(Query_cache_memory_bin_step))));
+
+ first_block = (Query_cache_block *) (cache + additional_data_size);
+ first_block->init(query_cache_size);
+ total_blocks++;
+ first_block->pnext=first_block->pprev=first_block;
+ first_block->next=first_block->prev=first_block;
+
+ /* Prepare bins */
+
+ bins[0].init(max_mem_bin_size);
+ steps[0].init(max_mem_bin_size,0,0);
+ mem_bin_count = (uint) ((1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
+ QUERY_CACHE_MEM_BIN_PARTS_MUL);
+ num= step= 1;
+ mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ while (mem_bin_size > min_allocation_unit)
+ {
+ ulong incr = (steps[step-1].size - mem_bin_size) / mem_bin_count;
+ unsigned long size = mem_bin_size;
+ for (uint i= mem_bin_count; i > 0; i--)
+ {
+ bins[num+i-1].init(size);
+ size += incr;
+ }
+ num += mem_bin_count;
+ steps[step].init(mem_bin_size, num-1, incr);
+ mem_bin_size >>= QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ step++;
+ mem_bin_count += QUERY_CACHE_MEM_BIN_PARTS_INC;
+ mem_bin_count = (uint) (mem_bin_count * QUERY_CACHE_MEM_BIN_PARTS_MUL);
+ if (mem_bin_count > (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2))
+ mem_bin_count=(mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2);
+ }
+ inc = (steps[step-1].size - mem_bin_size) / mem_bin_count;
+
+ /*
+ num + mem_bin_count > mem_bin_num, but index never be > mem_bin_num
+ because block with size < min_allocated_unit never will be requested
+ */
+
+ steps[step].init(mem_bin_size, num + mem_bin_count - 1, inc);
+ {
+ uint skiped = (min_allocation_unit - mem_bin_size)/inc;
+ ulong size = mem_bin_size + inc*skiped;
+ uint i = mem_bin_count - skiped;
+ while (i-- > 0)
+ {
+ bins[num+i].init(size);
+ size += inc;
+ }
+ }
+ bins[mem_bin_num].number = 1; // For easy end test in get_free_block
+ free_memory = free_memory_blocks = 0;
+ insert_into_free_memory_list(first_block);
+
+ DUMP(this);
+
+ VOID(hash_init(&queries,def_query_hash_size, 0, 0,
+ query_cache_query_get_key, 0, 0));
+ VOID(hash_init(&tables,def_table_hash_size, 0, 0,
+ query_cache_table_get_key, 0, 0));
+
+ queries_in_cache = 0;
+ queries_blocks = 0;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(query_cache_size +
+ additional_data_size + approx_additional_data_size);
+
+err:
+ make_disabled();
+ DBUG_RETURN(0);
+}
+
+
+/* Disable the use of the query cache */
+
+void Query_cache::make_disabled()
+{
+ DBUG_ENTER("Query_cache::make_disabled");
+ query_cache_size= 0;
+ free_memory= 0;
+ bins= 0;
+ steps= 0;
+ cache= 0;
+ mem_bin_num= mem_bin_steps= 0;
+ queries_in_cache= 0;
+ first_block= 0;
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::free_cache(my_bool destruction)
+{
+ DBUG_ENTER("Query_cache::free_cache");
+ if (query_cache_size > 0)
+ {
+ if (!destruction)
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ flush_cache();
+#ifndef DBUG_OFF
+ if (bins[0].free_blocks == 0)
+ {
+ wreck(__LINE__,"no free memory found in (bins[0].free_blocks");
+ DBUG_VOID_RETURN;
+ }
+#endif
+
+ /* Becasue we did a flush, all cache memory must be in one this block */
+ bins[0].free_blocks->destroy();
+ total_blocks--;
+#ifndef DBUG_OFF
+ if (free_memory != query_cache_size)
+ DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
+ free_memory , query_cache_size));
+#endif
+ my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR));
+ make_disabled();
+ hash_free(&queries);
+ hash_free(&tables);
+ if (!destruction)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*****************************************************************************
+ Free block data
+*****************************************************************************/
+
+/*
+ The following assumes we have a lock on the cache
+*/
+
+void Query_cache::flush_cache()
+{
+ while (queries_blocks != 0)
+ {
+ BLOCK_LOCK_WR(queries_blocks);
+ free_query(queries_blocks);
+ }
+}
+
+/*
+ Free oldest query that is not in use by another thread.
+ Returns 1 if we couldn't remove anything
+*/
+
+my_bool Query_cache::free_old_query()
+{
+ DBUG_ENTER("Query_cache::free_old_query");
+ if (queries_blocks)
+ {
+ /*
+ try_lock_writing used to prevent client because here lock
+ sequence is breached.
+ Also we don't need remove locked queries at this point.
+ */
+ Query_cache_block *query_block = 0;
+ if (queries_blocks != 0)
+ {
+ Query_cache_block *block = queries_blocks;
+ /* Search until we find first query that we can remove */
+ do
+ {
+ Query_cache_query *header = block->query();
+ if (header->result() != 0 &&
+ header->result()->type == Query_cache_block::RESULT &&
+ block->query()->try_lock_writing())
+ {
+ query_block = block;
+ break;
+ }
+ } while ((block=block->next) != queries_blocks );
+ }
+
+ if (query_block != 0)
+ {
+ free_query(query_block);
+ DBUG_RETURN(0);
+ }
+ }
+ DBUG_RETURN(1); // Nothing to remove
+}
+
+/*
+ Free query from query cache.
+ query_block must be locked for writing.
+ This function will remove (and destroy) the lock for the query.
+*/
+
+void Query_cache::free_query(Query_cache_block *query_block)
+{
+ DBUG_ENTER("Query_cache::free_query");
+ DBUG_PRINT("qcache", ("free query 0x%lx %lu bytes result",
+ (ulong) query_block,
+ query_block->query()->length() ));
+
+ queries_in_cache--;
+ hash_delete(&queries,(byte *) query_block);
+
+ Query_cache_query *query = query_block->query();
+
+ if (query->writer() != 0)
+ {
+ /* Tell MySQL that this query should not be cached anymore */
+ query->writer()->query_cache_query = 0;
+ query->writer(0);
+ }
+ double_linked_list_exclude(query_block, &queries_blocks);
+ Query_cache_block_table *table=query_block->table(0);
+
+ for (TABLE_COUNTER_TYPE i=0; i < query_block->n_tables; i++)
+ unlink_table(table++);
+ Query_cache_block *result_block = query->result();
+
+ /*
+ The following is true when query destruction was called and no results
+ in query . (query just registered and then abort/pack/flush called)
+ */
+ if (result_block != 0)
+ {
+ Query_cache_block *block = result_block;
+ do
+ {
+ Query_cache_block *current = block;
+ block = block->next;
+ free_memory_block(current);
+ } while (block != result_block);
+ }
+
+ query->unlock_n_destroy();
+ free_memory_block(query_block);
+
+ DBUG_VOID_RETURN;
+}
+
+/*****************************************************************************
+ Query data creation
+*****************************************************************************/
+
+Query_cache_block *
+Query_cache::write_block_data(ulong data_len, gptr data,
+ ulong header_len,
+ Query_cache_block::block_type type,
+ TABLE_COUNTER_TYPE ntab,
+ my_bool under_guard)
+{
+ ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(ntab*sizeof(Query_cache_block_table)) +
+ header_len);
+ ulong len = data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+ Query_cache_block *block = allocate_block(max(align_len,
+ min_allocation_unit),
+ 1, 0, under_guard);
+ if (block != 0)
+ {
+ block->type = type;
+ block->n_tables = ntab;
+ block->used = len;
+
+ memcpy((void*) (((byte *) block)+ all_headers_len),
+ (void*) data, data_len);
+ }
+ DBUG_RETURN(block);
}
-/* At the moment we do not really want to do anything upon delete */
-static void free_cache_entry(void *entry)
+
+/*
+ On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be done.
+*/
+
+my_bool
+Query_cache::append_result_data(Query_cache_block **current_block,
+ ulong data_len, gptr data,
+ Query_cache_block *query_block)
{
+ DBUG_ENTER("Query_cache::append_result_data");
+ DBUG_PRINT("qcache", ("append %lu bytes to 0x%lx query",
+ data_len, query_block));
+
+ if (query_block->query()->add(data_len) > query_cache_limit)
+ {
+ DBUG_PRINT("qcache", ("size limit reached %lu > %lu",
+ query_block->query()->length(),
+ query_cache_limit));
+ DBUG_RETURN(0);
+ }
+ if (*current_block == 0)
+ {
+ DBUG_PRINT("qcache", ("allocated first result data block %lu", data_len));
+ /*
+ STRUCT_UNLOCK(&structure_guard_mutex) Will be done by
+ write_result_data if success;
+ */
+ DBUG_RETURN(write_result_data(current_block, data_len, data, query_block,
+ Query_cache_block::RES_BEG));
+ }
+ Query_cache_block *last_block = (*current_block)->prev;
+
+ DBUG_PRINT("qcache", ("lastblock 0x%lx len %lu used %lu",
+ (ulong) last_block, last_block->length,
+ last_block->used));
+ my_bool success = 1;
+ ulong last_block_free_space= last_block->length - last_block->used;
+
+ /*
+ We will first allocate and write the 'tail' of data, that doesn't fit
+ in the 'last_block'. Only if this succeeds, we will fill the last_block.
+ This saves us a memcpy if the query doesn't fit in the query cache.
+ */
+
+ // 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 &&
+ append_next_free_block(last_block,
+ max(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+ {
+ DBUG_PRINT("qcache", ("allocate new block for %lu bytes",
+ data_len-last_block_free_space));
+ Query_cache_block *new_block = 0;
+ /*
+ On success STRUCT_UNLOCK(&structure_guard_mutex) will be done
+ by the next call
+ */
+ success = write_result_data(&new_block, data_len-last_block_free_space,
+ (gptr)(((byte*)data)+last_block_free_space),
+ query_block,
+ Query_cache_block::RES_CONT);
+ /*
+ new_block may be != 0 even !success (if write_result_data
+ allocate a small block but failed to allocate continue)
+ */
+ if (new_block != 0)
+ double_linked_list_join(last_block, new_block);
+ }
+ else
+ {
+ // It is success (nobody can prevent us write data)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+ ulong to_copy = min(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((void*) (((byte*) last_block) + last_block->used), (void*) data,
+ to_copy);
+ last_block->used+=to_copy;
+ }
+ DBUG_RETURN(success);
}
-/* Initialization of the SQL cache hash -- should be called during
- the bootstrap stage */
-bool sql_cache_init(void)
+
+my_bool Query_cache::write_result_data(Query_cache_block **result_block,
+ ulong data_len, gptr data,
+ Query_cache_block *query_block,
+ Query_cache_block::block_type type)
{
- if (query_buff_size)
+ DBUG_ENTER("Query_cache::write_result_data");
+ DBUG_PRINT("qcache", ("data_len %lu",data_len));
+
+ /*
+ Reserve block(s) for filling
+ During data allocation we must have structure_guard_mutex locked.
+ As data copy is not a fast operation, it's better if we don't have
+ structure_guard_mutex locked during data coping.
+ Thus we first allocate space and lock query, then unlock
+ structure_guard_mutex and copy data.
+ */
+
+ my_bool success = allocate_data_chain(result_block, data_len, query_block,
+ type == Query_cache_block::RES_BEG);
+ if (success)
+ {
+ // It is success (nobody can prevent us write data)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ byte *rest = (byte*) data;
+ Query_cache_block *block = *result_block;
+ uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ // Now fill list of blocks that created by allocate_data_chain
+ do
+ {
+ block->type = type;
+ ulong length = block->used - headers_len;
+ DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length,
+ (ulong)block));
+ memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length);
+ rest += length;
+ block = block->next;
+ type = Query_cache_block::RES_CONT;
+ } while (block != *result_block);
+ }
+ else
{
- VOID(hash_init(&sql_cache, 4096, 0, 0,
- cache_key,
- (void (*)(void*)) free_cache_entry,
- 0));
+ if (*result_block != 0)
+ {
+ // Destroy list of blocks that was created & locked by lock_result_data
+ Query_cache_block *block = *result_block;
+ do
+ {
+ Query_cache_block *current = block;
+ block = block->next;
+ free_memory_block(current);
+ } while (block != *result_block);
+ *result_block = 0;
+ /*
+ It is not success => not unlock structure_guard_mutex (we need it to
+ free query)
+ */
+ }
}
- return 0;
+ DBUG_PRINT("qcache", ("success %d", (int) 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;
}
-/* Clearing the SQL cache hash -- during shutdown */
-void sql_cache_free(void)
+/*
+ Allocate one or more blocks to hold data
+*/
+
+my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
+ ulong data_len,
+ Query_cache_block *query_block,
+ my_bool first_block)
{
- hash_free(&sql_cache);
+ ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+ DBUG_ENTER("Query_cache::allocate_data_chain");
+ DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
+ data_len, all_headers_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, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size,
+ 1);
+ my_bool success = (*result_block != 0);
+ if (success)
+ {
+ Query_cache_block *new_block= *result_block;
+ new_block->n_tables = 0;
+ new_block->used = 0;
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+ header->parent(query_block);
+
+ if (new_block->length < len)
+ {
+ /*
+ We got less memory then we need (no big memory blocks) =>
+ Continue to allocated more blocks until we got everything we need.
+ */
+ Query_cache_block *next_block;
+ if ((success = allocate_data_chain(&next_block,
+ len - new_block->length,
+ query_block, first_block)))
+ double_linked_list_join(new_block, next_block);
+ }
+ if (success)
+ {
+ new_block->used = min(len, new_block->length);
+
+ DBUG_PRINT("qcache", ("Block len %lu used %lu",
+ new_block->length, new_block->used));
+ }
+ else
+ DBUG_PRINT("warning", ("Can't allocate block for continue"));
+ }
+ else
+ DBUG_PRINT("warning", ("Can't allocate block for results"));
+ DBUG_RETURN(success);
}
-/* Finds whether the SQL command is already in the cache, at any case
- establishes correct LEX structure in the THD (either from
- cache or a new one) */
+/*****************************************************************************
+ Tables management
+*****************************************************************************/
+
+/*
+ Invalidate the first table in the table_list
+*/
+
+void Query_cache::invalidate_table(TABLE_LIST *table_list)
+{
+ if (table_list->table != 0)
+ invalidate_table(table_list->table); // Table is open
+ else
+ {
+ char key[MAX_DBKEY_LENGTH];
+ uint key_length;
+ Query_cache_block *table_block;
+ key_length=(uint) (strmov(strmov(key,table_list->db)+1,
+ table_list->real_name) -key)+ 1;
+
+ // We don't store temporary tables => no key_length+=4 ...
+ if ((table_block = (Query_cache_block*)
+ hash_search(&tables,(byte*) key,key_length)))
+ invalidate_table(table_block);
+ }
+}
-int sql_cache_hit(THD *thd, char *sql, uint length)
+void Query_cache::invalidate_table(TABLE *table)
{
-#ifdef QQ
- LEX *ptr;
- ptr = (LEX *)hash_search(&sql_cache, sql, length);
- if (ptr) {
- fprintf(stderr, "Query `%s' -- hit in the cache (%p)\n", ptr->sql_query_text, ptr);
- thd->lex_ptr = ptr;
- ptr->thd = thd;
- } else {
- thd->lex_ptr = ptr = lex_array + last_lex_array_item--;
+ invalidate_table((byte*) table->table_cache_key, table->key_length);
+}
+
+void Query_cache::invalidate_table(byte * key, uint32 key_length)
+{
+ Query_cache_block *table_block;
+ if ((table_block = ((Query_cache_block*)
+ hash_search(&tables, key, key_length))))
+ invalidate_table(table_block);
+}
+
+void Query_cache::invalidate_table(Query_cache_block *table_block)
+{
+ Query_cache_block_table *list_root = table_block->table(0);
+ while (list_root->next != list_root)
+ {
+ Query_cache_block *query_block = list_root->next->block();
+ BLOCK_LOCK_WR(query_block);
+ free_query(query_block);
+ }
+}
+
+
+my_bool Query_cache::register_all_tables(Query_cache_block *block,
+ TABLE_LIST *tables_used,
+ TABLE_COUNTER_TYPE tables)
+{
+ TABLE_COUNTER_TYPE n;
+ DBUG_PRINT("qcache", ("register tables block 0x%lx, n %d, header %x",
+ (ulong) block, (int) tables,
+ (int) ALIGN_SIZE(sizeof(Query_cache_block))));
+
+ Query_cache_block_table *block_table = block->table(0);
+
+ for (n=0; tables_used; tables_used=tables_used->next, n++, block_table++)
+ {
+ DBUG_PRINT("qcache",
+ ("table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx",
+ tables_used->real_name, tables_used->db,
+ (ulong) tables_used->table,
+ tables_used->table->key_length,
+ (ulong) tables_used->table->table_cache_key));
+ block_table->n=n;
+ if (!insert_table(tables_used->table->key_length,
+ tables_used->table->table_cache_key, block_table,
+ tables_used->db_length))
+ break;
+
+ if (tables_used->table->db_type == DB_TYPE_MRG_MYISAM)
+ {
+ ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file;
+ MYRG_INFO *file = handler->myrg_info();
+ for (MYRG_TABLE *table = file->open_tables;
+ table != file->end_table ;
+ table++)
+ {
+ char key[MAX_DBKEY_LENGTH];
+ uint32 db_length;
+ uint key_length =filename_2_table_key(key, table->table->filename,
+ &db_length);
+ (++block_table)->n= ++n;
+ if (!insert_table(key_length, key, block_table,
+ db_length))
+ goto err;
+ }
+ }
+ }
+
+err:
+ if (tables_used)
+ {
+ DBUG_PRINT("qcache", ("failed at table %d", (int) n));
+ /* Unlink the tables we allocated above */
+ for (Query_cache_block_table *tmp = block->table(0) ;
+ tmp != block_table;
+ tmp++)
+ unlink_table(tmp);
+ }
+ return (tables_used == 0);
+}
+
+/*
+ Insert used tablename in cache
+ Returns 0 on error
+*/
+
+my_bool
+Query_cache::insert_table(uint key_len, char *key,
+ Query_cache_block_table *node,
+ uint32 db_length)
+{
+ DBUG_ENTER("Query_cache::insert_table");
+ DBUG_PRINT("qcache", ("insert table node 0x%lx, len %d",
+ (ulong)node, key_len));
+
+ Query_cache_block *table_block = ((Query_cache_block *)
+ hash_search(&tables, (byte*) key,
+ key_len));
+
+ if (table_block == 0)
+ {
+ DBUG_PRINT("qcache", ("new table block from 0x%lx (%u)",
+ (ulong) key, (int) key_len));
+ table_block = write_block_data(key_len, (gptr) key,
+ ALIGN_SIZE(sizeof(Query_cache_table)),
+ Query_cache_block::TABLE,
+ 1, 1);
+ if (table_block == 0)
+ {
+ DBUG_PRINT("qcache", ("Can't write table name to cache"));
+ DBUG_RETURN(0);
+ }
+ Query_cache_table *header = table_block->table();
+ double_linked_list_simple_include(table_block,
+ &tables_blocks);
+ Query_cache_block_table *list_root = table_block->table(0);
+ list_root->n = 0;
+ list_root->next = list_root->prev = list_root;
+ if (hash_insert(&tables, (const byte *) table_block))
+ {
+ DBUG_PRINT("qcache", ("Can't insert table to hash"));
+ // write_block_data return locked block
+ free_memory_block(table_block);
+ DBUG_RETURN(0);
+ }
+ char *db = header->db();
+ header->table(db + db_length + 1);
+ }
+
+ Query_cache_block_table *list_root = table_block->table(0);
+ node->next = list_root->next;
+ list_root->next = node;
+ node->next->prev = node;
+ node->prev = list_root;
+ node->parent = table_block->table();
+ DBUG_RETURN(1);
+}
+
+
+void Query_cache::unlink_table(Query_cache_block_table *node)
+{
+ DBUG_ENTER("Query_cache::unlink_table");
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ Query_cache_block_table *neighbour = node->next;
+ if (neighbour->next == neighbour)
+ {
+ // list is empty (neighbor is root of list)
+ Query_cache_block *table_block = neighbour->block();
+ double_linked_list_exclude(table_block,
+ &tables_blocks);
+ hash_delete(&tables,(byte *) table_block);
+ free_memory_block(table_block);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*****************************************************************************
+ Free memory management
+*****************************************************************************/
+
+Query_cache_block *
+Query_cache::allocate_block(ulong len, my_bool not_less, ulong min,
+ my_bool under_guard)
+{
+ DBUG_ENTER("Query_cache::allocate_block");
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu, uder_guard %d",
+ len, not_less,min,under_guard));
+
+ if (len >= min(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+ DBUG_RETURN(0); // in any case we don't have such piece of memory
+ }
+
+ if (!under_guard)
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ /* Free old queries until we have enough memory to store this block */
+ Query_cache_block *block;
+ do
+ {
+ block= get_free_block(len, not_less, min);
+ }
+ while (block == 0 && !free_old_query());
+
+ if (block != 0) // If we found a suitable block
+ {
+ if (block->length >= ALIGN_SIZE(len) + min_allocation_unit)
+ split_block(block,ALIGN_SIZE(len));
+ }
+
+ if (!under_guard)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(block);
+}
- lex_start(thd, (uchar *)sql, length);
- if (hash_insert(&sql_cache, (const byte *)ptr)) {
- fprintf(stderr, "Out of memory during hash_insert?\n");
+Query_cache_block *
+Query_cache::get_free_block(ulong len, my_bool not_less, ulong min)
+{
+ Query_cache_block *block = 0, *first = 0;
+ DBUG_ENTER("Query_cache::get_free_block");
+ DBUG_PRINT("qcache",("length %lu, not_less %d, min %lu", len,
+ (int)not_less, min));
+
+ /* Find block with minimal size > len */
+ uint start = find_bin(len);
+ // try matching bin
+ if (bins[start].number != 0)
+ {
+ Query_cache_block *list = bins[start].free_blocks;
+ ulong max_len = list->prev->length;
+ if (list->prev->length >= len) // check block with max size
+ {
+ first = list;
+ uint n = 0;
+ while ( n < QUERY_CACHE_MEM_BIN_TRY &&
+ first->length < len) //we don't need irst->next != list
+ {
+ first=first->next;
+ n++;
+ }
+ if (first->length >= len)
+ block=first;
+ else // we don't need if (first->next != list)
+ {
+ n = 0;
+ block = list->prev;
+ while (n < QUERY_CACHE_MEM_BIN_TRY &&
+ block->length > len)
+ {
+ block=block->prev;
+ n++;
+ }
+ if (block->length < len)
+ block=block->next;
+ }
}
- fprintf(stderr, "Query `%s' not found in the cache -- insert %p from slot %d\n", thd->lex_ptr->ptr, ptr, last_lex_array_item+1);
- if (!hash_search(&sql_cache, sql, length)) {
- fprintf(stderr, "I just enterred a hash key but it's not where -- what's that?\n");
- } else {
- fprintf(stderr, "Inserted to cache\n");
+ else
+ first = list->prev;
+ }
+ if (block == 0 && start > 0)
+ {
+ DBUG_PRINT("qcache",("Try bins with bigger block size"));
+ // Try more big bins
+ int i = start - 1;
+ while (i > 0 && bins[i].number == 0)
+ i--;
+ if (bins[i].number > 0)
+ block = bins[i].free_blocks;
+ }
+
+ // If no big blocks => try less size (if it is possible)
+ if (block == 0 && ! not_less)
+ {
+ DBUG_PRINT("qcache",("Try to allocate a smaller block"));
+ if (first != 0 && first->length > min)
+ block = first;
+ else
+ {
+ uint i = start + 1;
+ /* bins[mem_bin_num].number contains 1 for easy end test */
+ for (i= start+1 ; bins[i].number == 0 ; i++) ;
+ if (i < mem_bin_num && bins[i].free_blocks->prev->length >= min)
+ block = bins[i].free_blocks->prev;
}
- return 0;
}
+ if (block != 0)
+ exclude_from_free_memory_list(block);
+
+ DBUG_PRINT("qcache",("getting block 0x%lx", (ulong) block));
+ DBUG_RETURN(block);
+}
+
+
+void Query_cache::free_memory_block(Query_cache_block *block)
+{
+ DBUG_ENTER("Query_cache::free_memory_block");
+ block->used=0;
+ DBUG_PRINT("qcache",("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx",
+ (ulong) first_block, (ulong) block,block->pnext,
+ (ulong) block->pprev));
+
+ if (block->pnext != first_block && block->pnext->is_free())
+ block = join_free_blocks(block, block->pnext);
+ if (block != first_block && block->pprev->is_free())
+ block = join_free_blocks(block->pprev, block->pprev);
+ insert_into_free_memory_list(block);
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::split_block(Query_cache_block *block, ulong len)
+{
+ DBUG_ENTER("Query_cache::split_block");
+ Query_cache_block *new_block = (Query_cache_block*)(((byte*) block)+len);
+
+ new_block->init(block->length - len);
+ total_blocks++;
+ block->length=len;
+ new_block->pnext = block->pnext;
+ block->pnext = new_block;
+ new_block->pprev = block;
+ new_block->pnext->pprev = 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",
+ (ulong) block, len, (ulong) new_block));
+ DBUG_VOID_RETURN;
+}
+
+
+Query_cache_block *
+Query_cache::join_free_blocks(Query_cache_block *first_block,
+ Query_cache_block *block_in_list)
+{
+ Query_cache_block *second_block;
+ DBUG_ENTER("Query_cache::join_free_blocks");
+ DBUG_PRINT("qcache",
+ ("join first 0x%lx, pnext 0x%lx, in list 0x%lx",
+ (ulong) first_block, (ulong) first_block->pnext,
+ (ulong) block_in_list));
+
+ exclude_from_free_memory_list(block_in_list);
+ second_block = first_block->pnext;
+ // May be was not free block
+ second_block->used=0;
+ second_block->destroy();
+ total_blocks--;
+
+ first_block->length += second_block->length;
+ first_block->pnext = second_block->pnext;
+ second_block->pnext->pprev = first_block;
+
+ DBUG_RETURN(first_block);
+}
+
+
+my_bool Query_cache::append_next_free_block(Query_cache_block *block,
+ ulong add_size)
+{
+ Query_cache_block *next_block = block->pnext;
+ DBUG_ENTER("Query_cache::append_next_free_block");
+ DBUG_PRINT("enter", ("block 0x%lx, add_size %lu", (ulong) block,
+ add_size));
+
+ if (next_block != first_block && next_block->is_free())
+ {
+ ulong old_len = block->length;
+ exclude_from_free_memory_list(next_block);
+ next_block->destroy();
+ total_blocks--;
+
+ block->length += next_block->length;
+ block->pnext = next_block->pnext;
+ next_block->pnext->pprev = block;
+
+ if (block->length > ALIGN_SIZE(old_len + add_size) + min_allocation_unit)
+ split_block(block,ALIGN_SIZE(old_len + add_size));
+ DBUG_PRINT("exit", ("block was appended"));
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+void Query_cache::exclude_from_free_memory_list(Query_cache_block *free_block)
+{
+ DBUG_ENTER("Query_cache::exclude_from_free_memory_list");
+ Query_cache_memory_bin *bin = *((Query_cache_memory_bin **)
+ free_block->data());
+ double_linked_list_exclude(free_block, &bin->free_blocks);
+ bin->number--;
+ free_memory-=free_block->length;
+ free_memory_blocks--;
+ DBUG_PRINT("qcache",("exclude block 0x%lx, bin 0x%lx", (ulong) free_block,
+ (ulong) bin));
+ DBUG_VOID_RETURN;
+}
+
+void Query_cache::insert_into_free_memory_list(Query_cache_block *free_block)
+{
+ DBUG_ENTER("Query_cache::insert_into_free_memory_list");
+ uint idx = find_bin(free_block->length);
+ insert_into_free_memory_sorted_list(free_block, &bins[idx].free_blocks);
+ /*
+ We have enough memory in block for storing bin reference due to
+ min_allocation_unit choice
+ */
+ Query_cache_memory_bin **bin_ptr = ((Query_cache_memory_bin**)
+ free_block->data());
+ *bin_ptr = bins+idx;
+ (*bin_ptr)->number++;
+ DBUG_PRINT("qcache",("insert block 0x%lx, bin[%d] 0x%lx",
+ (ulong) free_block, idx, (ulong) *bin_ptr));
+ DBUG_VOID_RETURN;
+}
+
+uint Query_cache::find_bin(ulong size)
+{
+ DBUG_ENTER("Query_cache::find_bin");
+ // Binary search
+ int left = 0, right = mem_bin_steps;
+ do
+ {
+ int middle = (left + right) / 2;
+ if (steps[middle].size > size)
+ left = middle+1;
+ else
+ right = middle;
+ } while (left < right);
+ if (left == 0)
+ {
+ // first bin not subordinate of common rules
+ DBUG_PRINT("qcache", ("first bin (# 0), size %lu",size));
+ DBUG_RETURN(0);
+ }
+ uint bin = steps[left].idx -
+ (uint)((size - steps[left].size)/steps[left].increment);
+#ifndef DBUG_OFF
+ bins_dump();
#endif
- return 1;
+ DBUG_PRINT("qcache", ("bin %u step %u, size %lu step size %lu",
+ bin, left, size, steps[left].size));
+ DBUG_RETURN(bin);
+}
+
+
+/*****************************************************************************
+ Lists management
+*****************************************************************************/
+
+void Query_cache::move_to_query_list_end(Query_cache_block *query_block)
+{
+ DBUG_ENTER("Query_cache::move_to_query_list_end");
+ double_linked_list_exclude(query_block, &queries_blocks);
+ double_linked_list_simple_include(query_block, &queries_blocks);
+ DBUG_VOID_RETURN;
}
+
+
+void Query_cache::insert_into_free_memory_sorted_list(Query_cache_block *
+ new_block,
+ Query_cache_block **
+ list)
+{
+ DBUG_ENTER("Query_cache::insert_into_free_memory_sorted_list");
+ /*
+ list sorted by size in ascendant order, because we need small blocks
+ more frequently than bigger ones
+ */
+
+ new_block->used = 0;
+ new_block->n_tables = 0;
+ new_block->type = Query_cache_block::FREE;
+
+ if (*list == 0)
+ {
+ *list = new_block->next=new_block->prev=new_block;
+ DBUG_PRINT("qcache", ("inserted into empty list"));
+ }
+ else
+ {
+ Query_cache_block *point = *list;
+ if (point->length >= new_block->length)
+ {
+ point = point->prev;
+ *list = new_block;
+ }
+ else
+ {
+ /* Find right position in sorted list to put block */
+ while (point->next != *list &&
+ point->next->length < new_block->length)
+ point=point->next;
+ }
+ new_block->prev = point;
+ new_block->next = point->next;
+ new_block->next->prev = new_block;
+ point->next = new_block;
+ }
+ free_memory+=new_block->length;
+ free_memory_blocks++;
+ DBUG_VOID_RETURN;
+}
+
+
+void
+Query_cache::double_linked_list_simple_include(Query_cache_block *point,
+ Query_cache_block **
+ list_pointer)
+{
+ DBUG_ENTER("Query_cache::double_linked_list_simple_include");
+ DBUG_PRINT("qcache", ("including block 0x%lx", (ulong) point));
+ if (*list_pointer == 0)
+ *list_pointer=point->next=point->prev=point;
+ else
+ {
+ // insert to the end of list
+ point->next = (*list_pointer);
+ point->prev = (*list_pointer)->prev;
+ point->prev->next = point;
+ (*list_pointer)->prev = point;
+ }
+ DBUG_VOID_RETURN;
+}
+
+void
+Query_cache::double_linked_list_exclude(Query_cache_block *point,
+ Query_cache_block **list_pointer)
+{
+ DBUG_ENTER("Query_cache::double_linked_list_exclude");
+ DBUG_PRINT("qcache", ("excluding block 0x%lx, list 0x%lx",
+ (ulong) point, (ulong) list_pointer));
+ if (point->next == point)
+ *list_pointer = 0; // empty list
+ else
+ {
+ point->next->prev = point->prev;
+ point->prev->next = point->next;
+ if (point == *list_pointer)
+ *list_pointer = point->next;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
+ Query_cache_block *tail_head)
+{
+ Query_cache_block *head_head = head_tail->next,
+ *tail_tail = tail_head->prev;
+ head_head->prev = tail_tail;
+ head_tail->next = tail_head;
+ tail_head->prev = head_tail;
+ tail_tail->next = head_head;
+}
+
+/*****************************************************************************
+ Query
+*****************************************************************************/
+
+/*
+ If query is cacheable return number tables in query
+ (query without tables are not cached)
+*/
+
+TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
+ char *query,
+ LEX *lex, TABLE_LIST *tables_used)
+{
+ TABLE_COUNTER_TYPE tables = 0;
+ DBUG_ENTER("Query_cache::is_cacheable");
+
+ if (lex->sql_command == SQLCOM_SELECT &&
+ thd->temporary_tables == 0 &&
+ (thd->variables.query_cache_type == 1 ||
+ (thd->variables.query_cache_type == 2 && (lex->select->options &
+ OPTION_TO_QUERY_CACHE))) &&
+ thd->safe_to_cache_query)
+ {
+ my_bool has_transactions = 0;
+ DBUG_PRINT("qcache", ("options %lx %lx, type %u",
+ OPTION_TO_QUERY_CACHE,
+ lex->select->options,
+ (int) thd->variables.query_cache_type));
+
+ for (; tables_used; tables_used=tables_used->next)
+ {
+ tables++;
+ DBUG_PRINT("qcache", ("table %s, db %s, type %u",
+ tables_used->real_name,
+ tables_used->db, tables_used->table->db_type));
+ has_transactions = (has_transactions ||
+ tables_used->table->file->has_transactions());
+
+ if (tables_used->table->db_type == DB_TYPE_MRG_ISAM)
+ {
+ DBUG_PRINT("qcache", ("select not cacheable: used MRG_ISAM table(s)"));
+ DBUG_RETURN(0);
+ }
+ if (tables_used->table->db_type == DB_TYPE_MRG_MYISAM)
+ {
+ ha_myisammrg *handler = (ha_myisammrg *)tables_used->table->file;
+ MYRG_INFO *file = handler->myrg_info();
+ tables+= (file->end_table - file->open_tables);
+ }
+ }
+
+ if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ has_transactions)
+ {
+ DBUG_PRINT("qcache", ("not in autocommin mode"));
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("qcache", ("select is using %d tables", tables));
+ DBUG_RETURN(tables);
+ }
+
+ DBUG_PRINT("qcache",
+ ("not interesting query: %d or not cacheable, options %lx %lx, type %u",
+ (int) lex->sql_command,
+ OPTION_TO_QUERY_CACHE,
+ lex->select->options,
+ (int) thd->variables.query_cache_type));
+ DBUG_RETURN(0);
+}
+
+
+/*****************************************************************************
+ Packing
+*****************************************************************************/
+
+void Query_cache::pack_cache()
+{
+ DBUG_ENTER("Query_cache::pack_cache");
+ STRUCT_LOCK(&structure_guard_mutex);
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+
+ byte *border = 0;
+ Query_cache_block *before = 0;
+ ulong gap = 0;
+ my_bool ok = 1;
+ Query_cache_block *block = first_block;
+ DUMP(this);
+
+ if (first_block)
+ {
+ do
+ {
+ Query_cache_block *next=block->pnext;
+ ok = move_by_type(&border, &before, &gap, block);
+ block = next;
+ } while (ok && block != first_block);
+
+ if (border != 0)
+ {
+ Query_cache_block *new_block = (Query_cache_block *) border;
+ new_block->init(gap);
+ total_blocks++;
+ new_block->pnext = before->pnext;
+ before->pnext = new_block;
+ new_block->pprev = before;
+ new_block->pnext->pprev = new_block;
+ insert_into_free_memory_list(new_block);
+ }
+ DUMP(this);
+ }
+
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_VOID_RETURN;
+}
+
+
+my_bool Query_cache::move_by_type(byte **border,
+ Query_cache_block **before, ulong *gap,
+ Query_cache_block *block)
+{
+ DBUG_ENTER("Query_cache::move_by_type");
+
+ my_bool ok = 1;
+ switch (block->type) {
+ case Query_cache_block::FREE:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx FREE", (ulong) block));
+ if (*border == 0)
+ {
+ *border = (byte *) block;
+ *before = block->pprev;
+ DBUG_PRINT("qcache", ("gap beginning here"));
+ }
+ exclude_from_free_memory_list(block);
+ *gap +=block->length;
+ block->pprev->pnext=block->pnext;
+ block->pnext->pprev=block->pprev;
+ block->destroy();
+ total_blocks--;
+ DBUG_PRINT("qcache", ("added to gap (%lu)", *gap));
+ break;
+ }
+ case Query_cache_block::TABLE:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx TABLE", (ulong) block));
+ if (*border == 0)
+ break;
+ ulong len = block->length, used = block->used;
+ Query_cache_block_table *list_root = block->table(0);
+ Query_cache_block_table *tprev = list_root->prev,
+ *tnext = list_root->next;
+ Query_cache_block *prev = block->prev,
+ *next = block->next,
+ *pprev = block->pprev,
+ *pnext = block->pnext,
+ *new_block =(Query_cache_block *) *border;
+ uint tablename_offset = block->table()->table() - block->table()->db();
+ char *data = (char*) block->data();
+ byte *key;
+ uint key_length;
+ key=query_cache_table_get_key((byte*) block, &key_length, 0);
+ hash_search(&tables, (byte*) key, key_length);
+
+ block->destroy();
+ new_block->init(len);
+ new_block->type=Query_cache_block::TABLE;
+ new_block->used=used;
+ new_block->n_tables=1;
+ memmove((char*) new_block->data(), data, len-new_block->headers_len());
+ relink(block, new_block, next, prev, pnext, pprev);
+ if (tables_blocks == block)
+ tables_blocks = new_block;
+
+ Query_cache_block_table *nlist_root = new_block->table(0);
+ nlist_root->n = 0;
+ nlist_root->next = tnext;
+ tnext->prev = nlist_root;
+ nlist_root->prev = tprev;
+ tprev->next = nlist_root;
+ DBUG_PRINT("qcache",
+ ("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,
+ (ulong)tprev->next, (ulong)tnext->prev));
+ /*
+ Go through all queries that uses this table and change them to
+ point to the new table object
+ */
+ Query_cache_table *new_block_table=new_block->table();
+ for (;tnext != nlist_root; tnext=tnext->next)
+ tnext->parent= new_block_table;
+ *border += len;
+ *before = new_block;
+ /* Fix pointer to table name */
+ new_block->table()->table(new_block->table()->db() + tablename_offset);
+ /* Fix hash to point at moved block */
+ hash_replace(&tables, tables.current_record, (byte*) new_block);
+
+ DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
+ len, (ulong) new_block, (ulong) *border));
+ break;
+ }
+ case Query_cache_block::QUERY:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx QUERY", (ulong) block));
+ if (*border == 0)
+ break;
+ BLOCK_LOCK_WR(block);
+ ulong len = block->length, used = block->used;
+ TABLE_COUNTER_TYPE n_tables = block->n_tables;
+ Query_cache_block *prev = block->prev,
+ *next = block->next,
+ *pprev = block->pprev,
+ *pnext = block->pnext,
+ *new_block =(Query_cache_block*) *border;
+ char *data = (char*) block->data();
+ Query_cache_block *first_result_block = ((Query_cache_query *)
+ block->data())->result();
+ byte *key;
+ uint key_length;
+ key=query_cache_query_get_key((byte*) block, &key_length, 0);
+ hash_search(&queries, (byte*) key, key_length);
+ // Move table of used tables
+ memmove((char*) new_block->table(0), (char*) block->table(0),
+ ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
+ block->query()->unlock_n_destroy();
+ block->destroy();
+ new_block->init(len);
+ new_block->type=Query_cache_block::QUERY;
+ new_block->used=used;
+ new_block->n_tables=n_tables;
+ memmove((char*) new_block->data(), data, len - new_block->headers_len());
+ relink(block, new_block, next, prev, pnext, pprev);
+ if (queries_blocks == block)
+ queries_blocks = new_block;
+ for (TABLE_COUNTER_TYPE j=0; j < n_tables; j++)
+ {
+ Query_cache_block_table *block_table = new_block->table(j);
+ block_table->next->prev = block_table;
+ block_table->prev->next = block_table;
+ }
+ DBUG_PRINT("qcache", ("after circle tt"));
+ *border += len;
+ *before = new_block;
+ new_block->query()->result(first_result_block);
+ if (first_result_block != 0)
+ {
+ Query_cache_block *result_block = first_result_block;
+ do
+ {
+ result_block->result()->parent(new_block);
+ result_block = result_block->next;
+ } while ( result_block != first_result_block );
+ }
+ Query_cache_query *new_query= ((Query_cache_query *) new_block->data());
+ my_rwlock_init(&new_query->lock, NULL);
+
+ /*
+ If someone is writing to this block, inform the writer that the block
+ has been moved.
+ */
+ NET *net = new_block->query()->writer();
+ if (net != 0)
+ {
+ net->query_cache_query= (gptr) new_block;
+ }
+ /* Fix hash to point at moved block */
+ hash_replace(&queries, queries.current_record, (byte*) new_block);
+ DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
+ len, (ulong) new_block, (ulong) *border));
+ break;
+ }
+ case Query_cache_block::RES_INCOMPLETE:
+ case Query_cache_block::RES_BEG:
+ case Query_cache_block::RES_CONT:
+ case Query_cache_block::RESULT:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx RES* (%d)", (ulong) block,
+ (int) block->type));
+ if (*border == 0)
+ break;
+ Query_cache_block *query_block = block->result()->parent(),
+ *next = block->next,
+ *prev = block->prev;
+ Query_cache_block::block_type type = block->type;
+ BLOCK_LOCK_WR(query_block);
+ ulong len = block->length, used = block->used;
+ Query_cache_block *pprev = block->pprev,
+ *pnext = block->pnext,
+ *new_block =(Query_cache_block*) *border;
+ char *data = (char*) block->data();
+ block->destroy();
+ new_block->init(len);
+ new_block->type=type;
+ new_block->used=used;
+ memmove((char*) new_block->data(), data, len - new_block->headers_len());
+ relink(block, new_block, next, prev, pnext, pprev);
+ new_block->result()->parent(query_block);
+ Query_cache_query *query = query_block->query();
+ if (query->result() == block)
+ query->result(new_block);
+ *border += len;
+ *before = new_block;
+ /* If result writing complete && we have free space in block */
+ ulong free_space= new_block->length - new_block->used;
+ free_space-= free_space % ALIGN_SIZE(1);
+ if (query->result()->type == Query_cache_block::RESULT &&
+ new_block->length > new_block->used &&
+ *gap + free_space > min_allocation_unit &&
+ new_block->length - free_space > min_allocation_unit)
+ {
+ *border-= free_space;
+ *gap+= free_space;
+ DBUG_PRINT("qcache",
+ ("rest of result free space added to gap (%lu)", *gap));
+ new_block->length -= free_space;
+ }
+ BLOCK_UNLOCK_WR(query_block);
+ DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
+ len, (ulong) new_block, (ulong) *border));
+ break;
+ }
+ default:
+ DBUG_PRINT("error", ("unexpected block type %d, block 0x%lx",
+ (int)block->type, (ulong) block));
+ ok = 0;
+ }
+ DBUG_RETURN(ok);
+}
+
+
+void Query_cache::relink(Query_cache_block *oblock,
+ Query_cache_block *nblock,
+ Query_cache_block *next, Query_cache_block *prev,
+ Query_cache_block *pnext, Query_cache_block *pprev)
+{
+ if (prev == oblock) //check pointer to himself
+ {
+ nblock->prev = nblock;
+ nblock->next = nblock;
+ }
+ else
+ {
+ nblock->prev = prev;
+ prev->next=nblock;
+ }
+ if (next != oblock)
+ {
+ nblock->next = next;
+ next->prev=nblock;
+ }
+ nblock->pprev = pprev; // Physical pointer to himself have only 1 free block
+ nblock->pnext = pnext;
+ pprev->pnext=nblock;
+ pnext->pprev=nblock;
+}
+
+
+my_bool Query_cache::join_results(ulong join_limit)
+{
+ my_bool has_moving = 0;
+ DBUG_ENTER("Query_cache::join_results");
+
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (queries_blocks != 0)
+ {
+ Query_cache_block *block = queries_blocks;
+ do
+ {
+ Query_cache_query *header = block->query();
+ if (header->result() != 0 &&
+ header->result()->type == Query_cache_block::RESULT &&
+ header->length() > join_limit)
+ {
+ Query_cache_block *new_result_block =
+ get_free_block(ALIGN_SIZE(header->length()) +
+ ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)), 1, 0);
+ if (new_result_block != 0)
+ {
+ has_moving = 1;
+ Query_cache_block *first_result = header->result();
+ ulong new_len = (header->length() +
+ ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ if (new_result_block->length >
+ ALIGN_SIZE(new_len) + min_allocation_unit)
+ split_block(new_result_block, ALIGN_SIZE(new_len));
+ BLOCK_LOCK_WR(block);
+ header->result(new_result_block);
+ new_result_block->type = Query_cache_block::RESULT;
+ new_result_block->n_tables = 0;
+ new_result_block->used = new_len;
+
+ new_result_block->next = new_result_block->prev = new_result_block;
+ DBUG_PRINT("qcache", ("new block %lu/%lu (%lu)",
+ new_result_block->length,
+ new_result_block->used,
+ header->length()));
+
+ Query_cache_result *new_result = new_result_block->result();
+ new_result->parent(block);
+ byte *write_to = (byte*) new_result->data();
+ Query_cache_block *result_block = first_result;
+ do
+ {
+ ulong len = (result_block->used - result_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ DBUG_PRINT("loop", ("add block %lu/%lu (%lu)",
+ result_block->length,
+ result_block->used,
+ len));
+ memcpy((char *) write_to,
+ (char*) result_block->result()->data(),
+ len);
+ write_to += len;
+ Query_cache_block *old_result_block = result_block;
+ result_block = result_block->next;
+ free_memory_block(old_result_block);
+ } while (result_block != first_result);
+ BLOCK_UNLOCK_WR(block);
+ }
+ }
+ block = block->next;
+ } while ( block != queries_blocks );
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(has_moving);
+}
+
+
+uint Query_cache::filename_2_table_key (char *key, const char *path,
+ uint32 *db_length)
+{
+ char tablename[FN_REFLEN+2], *filename, *dbname;
+ DBUG_ENTER("Query_cache::filename_2_table_key");
+
+ /* Safety if filename didn't have a directory name */
+ tablename[0]= FN_LIBCHAR;
+ tablename[1]= FN_LIBCHAR;
+ /* Convert filename to this OS's format in tablename */
+ fn_format(tablename + 2, path, "", "", MY_REPLACE_EXT);
+ filename= tablename + dirname_length(tablename + 2) + 2;
+ /* Find start of databasename */
+ for (dbname= filename - 2 ; dbname[-1] != FN_LIBCHAR ; dbname--) ;
+ *db_length= (filename - dbname) - 1;
+ DBUG_PRINT("qcache", ("table '%-.*s.%s'", *db_length, dbname, filename));
+
+ DBUG_RETURN((uint) (strmov(strmake(key, dbname, *db_length) + 1,
+ filename) -key) + 1);
+}
+
+
+/****************************************************************************
+ Functions to be used when debugging
+****************************************************************************/
+
+#if defined(DBUG_OFF) && !defined(USE_QUERY_CACHE_INTEGRITY_CHECK)
+
+void wreck(uint line, const char *message) {}
+void bins_dump() {}
+void cache_dump() {}
+void queries_dump() {}
+void tables_dump() {}
+my_bool check_integrity(bool not_locked) { return 0; }
+my_bool in_list(Query_cache_block * root, Query_cache_block * point,
+ const char *name) { return 0;}
+my_bool in_blocks(Query_cache_block * point) { return 0; }
+
+#else
+
+void Query_cache::wreck(uint line, const char *message)
+{
+ THD *thd=current_thd;
+ DBUG_ENTER("Query_cache::wreck");
+ query_cache_size = 0;
+ if (*message)
+ DBUG_PRINT("error", (" %s", message));
+ DBUG_PRINT("warning", ("=================================="));
+ DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line));
+ DBUG_PRINT("warning", ("=================================="));
+ if (thd)
+ thd->killed = 1;
+ cache_dump();
+ /* check_integrity(0); */ /* Can't call it here because of locks */
+ bins_dump();
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::bins_dump()
+{
+ uint i;
+
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("mem_bin_num=%u, mem_bin_steps=%u",
+ mem_bin_num, mem_bin_steps));
+ DBUG_PRINT("qcache", ("-------------------------"));
+ DBUG_PRINT("qcache", (" size idx step"));
+ DBUG_PRINT("qcache", ("-------------------------"));
+ for (i=0; i < mem_bin_steps; i++)
+ {
+ DBUG_PRINT("qcache", ("%10lu %3d %10lu", steps[i].size, steps[i].idx,
+ steps[i].increment));
+ }
+ DBUG_PRINT("qcache", ("-------------------------"));
+ DBUG_PRINT("qcache", (" size num"));
+ DBUG_PRINT("qcache", ("-------------------------"));
+ for (i=0; i < mem_bin_num; i++)
+ {
+ DBUG_PRINT("qcache", ("%10lu %3d 0x%lx", bins[i].size, bins[i].number,
+ (ulong)&(bins[i])));
+ if (bins[i].free_blocks)
+ {
+ Query_cache_block *block = bins[i].free_blocks;
+ do{
+ DBUG_PRINT("qcache", ("\\-- %lu 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
+ block->length, (ulong)block,
+ (ulong)block->next, (ulong)block->prev,
+ (ulong)block->pnext, (ulong)block->pprev));
+ block = block->next;
+ } while ( block != bins[i].free_blocks );
+ }
+ }
+ DBUG_PRINT("qcache", ("-------------------------"));
+}
+
+
+void Query_cache::cache_dump()
+{
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("-------------------------------------"));
+ DBUG_PRINT("qcache", (" length used t nt"));
+ DBUG_PRINT("qcache", ("-------------------------------------"));
+ Query_cache_block *i = first_block;
+ do
+ {
+ DBUG_PRINT("qcache",
+ ("%10lu %10lu %1d %2d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
+ i->length, i->used, (int)i->type,
+ i->n_tables, (ulong)i,
+ (ulong)i->next, (ulong)i->prev, (ulong)i->pnext,
+ (ulong)i->pprev));
+ i = i->pnext;
+ } while ( i != first_block );
+ DBUG_PRINT("qcache", ("-------------------------------------"));
+}
+
+
+void Query_cache::queries_dump()
+{
+
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("------------------"));
+ DBUG_PRINT("qcache", (" QUERIES"));
+ DBUG_PRINT("qcache", ("------------------"));
+ if (queries_blocks != 0)
+ {
+ Query_cache_block *block = queries_blocks;
+ do
+ {
+ uint len;
+ char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0);
+ len--; // Point at flags
+ uint flags = (uint) (uchar) str[len];
+ str[len]=0;
+ DBUG_PRINT("qcache", ("%u (%u,%u) '%s' '%s'",
+ ((flags & QUERY_CACHE_CLIENT_LONG_FLAG_MASK)? 1:0),
+ (flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len,
+ str,strend(str)+1));
+ DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block,
+ (ulong) block->next, (ulong) block->prev,
+ (ulong)block->pnext, (ulong)block->pprev));
+ str[len]=(char) flags;
+ for (TABLE_COUNTER_TYPE t = 0; t < block->n_tables; t++)
+ {
+ Query_cache_table *table = block->table(t)->parent;
+ DBUG_PRINT("qcache", ("-t- '%s' '%s'", table->db(), table->table()));
+ }
+ Query_cache_query *header = block->query();
+ if (header->result())
+ {
+ Query_cache_block *result_block = header->result();
+ Query_cache_block *result_beg = result_block;
+ do
+ {
+ DBUG_PRINT("qcache", ("-r- %u %lu/%lu 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
+ (uint) result_block->type,
+ result_block->length, result_block->used,
+ (ulong) result_block,
+ (ulong) result_block->next,
+ (ulong) result_block->prev,
+ (ulong) result_block->pnext,
+ (ulong) result_block->pprev));
+ result_block = result_block->next;
+ } while ( result_block != result_beg );
+ }
+ } while ((block=block->next) != queries_blocks);
+ }
+ else
+ {
+ DBUG_PRINT("qcache", ("no queries in list"));
+ }
+ DBUG_PRINT("qcache", ("------------------"));
+}
+
+
+void Query_cache::tables_dump()
+{
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("--------------------"));
+ DBUG_PRINT("qcache", ("TABLES"));
+ DBUG_PRINT("qcache", ("--------------------"));
+ if (tables_blocks != 0)
+ {
+ Query_cache_block *table_block = tables_blocks;
+ do
+ {
+ Query_cache_table *table = table_block->table();
+ DBUG_PRINT("qcache", ("'%s' '%s'", table->db(), table->table()));
+ table_block = table_block->next;
+ } while ( table_block != tables_blocks);
+ }
+ else
+ DBUG_PRINT("qcache", ("no tables in list"));
+ DBUG_PRINT("qcache", ("--------------------"));
+}
+
+
+my_bool Query_cache::check_integrity(bool not_locked)
+{
+ my_bool result = 0;
+ uint i;
+ DBUG_ENTER("check_integrity");
+
+ if (query_cache_size == 0)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ DBUG_RETURN(0);
+ }
+ if (!not_locked)
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ if (hash_check(&queries))
+ {
+ DBUG_PRINT("error", ("queries hash is damaged"));
+ result = 1;
+ }
+
+ if (hash_check(&tables))
+ {
+ DBUG_PRINT("error", ("tables hash is damaged"));
+ result = 1;
+ }
+
+ DBUG_PRINT("qcache", ("physical address check ..."));
+ ulong free=0, used=0;
+ Query_cache_block * block = first_block;
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ // Check allignment
+ if ((((long)block) % (long) ALIGN_SIZE(1)) !=
+ (((long)first_block) % (long)ALIGN_SIZE(1)))
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx do not aligned by %d", (ulong) block,
+ ALIGN_SIZE(1)));
+ result = 1;
+ }
+ // Check memory allocation
+ if (block->pnext == first_block) // Is it last block?
+ {
+ if (((byte*)block) + block->length !=
+ ((byte*)first_block) + query_cache_size)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx, type %u, ended at 0x%lx, but cache ended at 0x%lx",
+ (ulong) block, (uint) block->type,
+ (ulong) (((byte*)block) + block->length),
+ (ulong) (((byte*)first_block) + query_cache_size)));
+ result = 1;
+ }
+ }
+ else
+ if (((byte*)block) + block->length != ((byte*)block->pnext))
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx, type %u, ended at 0x%lx, but next block begining at 0x%lx",
+ (ulong) block, (uint) block->type,
+ (ulong) (((byte*)block) + block->length),
+ (ulong) ((byte*)block->pnext)));
+ }
+ if (block->type == Query_cache_block::FREE)
+ free+= block->length;
+ else
+ used+= block->length;
+ switch(block->type) {
+ case Query_cache_block::FREE:
+ {
+ Query_cache_memory_bin *bin = *((Query_cache_memory_bin **)
+ block->data());
+ //is it correct pointer?
+ if (((byte*)bin) < ((byte*)bins) ||
+ ((byte*)bin) >= ((byte*)first_block))
+ {
+ DBUG_PRINT("error",
+ ("free block 0x%lx have bin pointer 0x%lx beyaond of bins array bounds [0x%lx,0x%lx]",
+ (ulong) block,
+ (ulong) bin,
+ (ulong) bins,
+ (ulong) first_block));
+ result = 1;
+ }
+ else
+ {
+ int idx = (((byte*)bin) - ((byte*)bins)) /
+ sizeof(Query_cache_memory_bin);
+ if (in_list(bins[idx].free_blocks, block, "free memory"))
+ result = 1;
+ }
+ break;
+ }
+ case Query_cache_block::TABLE:
+ if (in_list(tables_blocks, block, "tables"))
+ result = 1;
+ if (in_table_list(block->table(0), block->table(0), "table list root"))
+ result = 1;
+ break;
+ case Query_cache_block::QUERY:
+ {
+ if (in_list(queries_blocks, block, "query"))
+ 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;
+ }
+ case Query_cache_block::RES_INCOMPLETE:
+ // This type of block can be not lincked yet (in multithread environment)
+ break;
+ case Query_cache_block::RES_BEG:
+ case Query_cache_block::RES_CONT:
+ case Query_cache_block::RESULT:
+ {
+ Query_cache_block * query_block = block->result()->parent();
+ if (((byte*)query_block) < ((byte*)first_block) ||
+ ((byte*)query_block) >= (((byte*)first_block) + query_cache_size))
+ {
+ DBUG_PRINT("error",
+ ("result block 0x%lx have query block pointer 0x%lx beyaond of block pool bounds [0x%lx,0x%lx]",
+ (ulong) block,
+ (ulong) query_block,
+ (ulong) first_block,
+ (ulong) (((byte*)first_block) + query_cache_size)));
+ result = 1;
+ }
+ else
+ {
+ BLOCK_LOCK_RD(query_block);
+ if (in_list(queries_blocks, query_block, "query from results"))
+ result = 1;
+ if (in_list(query_block->query()->result(), block,
+ "results"))
+ result = 1;
+ BLOCK_UNLOCK_RD(query_block);
+ }
+ break;
+ }
+ default:
+ DBUG_PRINT("error",
+ ("block 0x%lx have incorrect type %u",
+ block, block->type));
+ result = 1;
+ }
+
+ block = block->pnext;
+ } while (block != first_block);
+
+ if (used + free != query_cache_size)
+ {
+ DBUG_PRINT("error",
+ ("used memory (%lu) + free memory (%lu) != query_cache_size (%lu)",
+ used, free, query_cache_size));
+ result = 1;
+ }
+
+ if (free != free_memory)
+ {
+ DBUG_PRINT("error",
+ ("free memory (%lu) != free_memory (%lu)",
+ free, free_memory));
+ result = 1;
+ }
+
+ DBUG_PRINT("qcache", ("check queries ..."));
+ if ((block = queries_blocks))
+ {
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ uint length;
+ byte *key = query_cache_query_get_key((byte*) block, &length, 0);
+ gptr val = hash_search(&queries, key, length);
+ if (((gptr)block) != val)
+ {
+ DBUG_PRINT("error", ("block 0x%lx found in queries hash like 0x%lx",
+ (ulong) block, (ulong) val));
+ }
+ if (in_blocks(block))
+ result = 1;
+ Query_cache_block * results = block->query()->result();
+ if (results)
+ {
+ Query_cache_block * result_block = results;
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ if (in_blocks(result_block))
+ result = 1;
+
+ result_block = result_block->next;
+ } while (result_block != results);
+ }
+ block = block->next;
+ } while (block != queries_blocks);
+ }
+
+ DBUG_PRINT("qcache", ("check tables ..."));
+ if ((block = tables_blocks))
+ {
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ uint length;
+ byte *key = query_cache_table_get_key((byte*) block, &length, 0);
+ gptr val = hash_search(&tables, key, length);
+ if (((gptr)block) != val)
+ {
+ DBUG_PRINT("error", ("block 0x%lx found in tables hash like 0x%lx",
+ (ulong) block, (ulong) val));
+ }
+
+ if (in_blocks(block))
+ result = 1;
+ block=block->next;
+ } while (block != tables_blocks);
+ }
+
+ DBUG_PRINT("qcache", ("check free blocks"));
+ for (i = 0; i < mem_bin_num; i++)
+ {
+ if ((block = bins[i].free_blocks))
+ {
+ uint count = 0;
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ if (in_blocks(block))
+ result = 1;
+
+ count++;
+ block=block->next;
+ } while (block != bins[i].free_blocks);
+ if (count != bins[i].number)
+ {
+ DBUG_PRINT("error", ("bin[%d].number is %d, but bin have %d blocks",
+ bins[i].number, count));
+ result = 1;
+ }
+ }
+ }
+ DBUG_ASSERT(result == 0);
+ if (!not_locked)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(result);
+}
+
+
+my_bool Query_cache::in_blocks(Query_cache_block * point)
+{
+ my_bool result = 0;
+ Query_cache_block *block = point;
+ //back
+ do
+ {
+ if (block->pprev->pnext != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in physical list is incorrect linked, prev block 0x%lx refered as next to 0x%lx (check from 0x%lx)",
+ (ulong) block, (ulong) block->pprev,
+ (ulong) block->pprev->pnext,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->pnext)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err1;
+ }
+ block = block->pprev;
+ } while (block != first_block && block != point);
+ if (block != first_block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx (0x%lx<-->0x%lx) not owned by pysical list",
+ (ulong) block, (ulong) block->pprev, (ulong )block->pnext));
+ return 1;
+ }
+
+err1:
+ //forward
+ block = point;
+ do
+ {
+ if (block->pnext->pprev != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in physicel list is incorrect linked, next block 0x%lx refered as prev to 0x%lx (check from 0x%lx)",
+ (ulong) block, (ulong) block->pnext,
+ (ulong) block->pnext->pprev,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->pprev)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err2;
+ }
+ block = block->pnext;
+ } while (block != first_block);
+err2:
+ return result;
+}
+
+
+my_bool Query_cache::in_list(Query_cache_block * root,
+ Query_cache_block * point,
+ const char *name)
+{
+ my_bool result = 0;
+ Query_cache_block *block = point;
+ //back
+ do
+ {
+ if (block->prev->next != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in list '%s' 0x%lx is incorrect linked, prev block 0x%lx refered as next to 0x%lx (check from 0x%lx)",
+ (ulong) block, name, (ulong) root, (ulong) block->prev,
+ (ulong) block->prev->next,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->next)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err1;
+ }
+ block = block->prev;
+ } while (block != root && block != point);
+ if (block != root)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx (0x%lx<-->0x%lx) not owned by list '%s' 0x%lx",
+ (ulong) block,
+ (ulong) block->prev, (ulong) block->next,
+ name, (ulong) root));
+ return 1;
+ }
+err1:
+ // forward
+ block = point;
+ do
+ {
+ if (block->next->prev != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in list '%s' 0x%lx is incorrect linked, next block 0x%lx refered as prev to 0x%lx (check from 0x%lx)",
+ (ulong) block, name, (ulong) root, (ulong) block->next,
+ (ulong) block->next->prev,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->prev)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err2;
+ }
+ block = block->next;
+ } while (block != root);
+err2:
+ 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 /*HAVE_QUERY_CACHE*/
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
new file mode 100644
index 00000000000..3088331f19a
--- /dev/null
+++ b/sql/sql_cache.h
@@ -0,0 +1,406 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _SQL_CACHE_H
+#define _SQL_CACHE_H
+
+/* Query cache */
+
+/*
+ Can't create new free memory block if unused memory in block less
+ then QUERY_CACHE_MIN_ALLOCATION_UNIT.
+ if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then
+ QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly
+*/
+#define QUERY_CACHE_MIN_ALLOCATION_UNIT 512
+
+/* inittial size of hashes */
+#define QUERY_CACHE_DEF_QUERY_HASH_SIZE 1024
+#define QUERY_CACHE_DEF_TABLE_HASH_SIZE 1024
+
+/* minimal result data size when data allocated */
+#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)) */
+#define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 4
+#define QUERY_CACHE_MEM_BIN_STEP_PWR2 2
+#define QUERY_CACHE_MEM_BIN_PARTS_INC 1
+#define QUERY_CACHE_MEM_BIN_PARTS_MUL 1.2
+#define QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2 3
+
+/* how many free blocks check when finding most suitable before other 'end'
+ of list of free blocks */
+#define QUERY_CACHE_MEM_BIN_TRY 5
+
+/* query flags masks */
+#define QUERY_CACHE_CLIENT_LONG_FLAG_MASK 0x80
+#define QUERY_CACHE_CHARSET_CONVERT_MASK 0x7F
+
+/* packing parameters */
+#define QUERY_CACHE_PACK_ITERATION 2
+#define QUERY_CACHE_PACK_LIMIT (512*1024L)
+
+#define TABLE_COUNTER_TYPE uint8
+
+struct Query_cache_block;
+struct Query_cache_block_table;
+struct Query_cache_table;
+struct Query_cache_query;
+struct Query_cache_result;
+class Query_cache;
+
+
+struct Query_cache_block_table
+{
+ TABLE_COUNTER_TYPE n; // numbr in table (from 0)
+ Query_cache_block_table *next, *prev;
+ Query_cache_table *parent;
+ inline Query_cache_block *block();
+};
+
+
+struct Query_cache_block
+{
+ enum block_type {FREE, QUERY, RESULT, RES_CONT, RES_BEG,
+ RES_INCOMPLETE, TABLE, INCOMPLETE};
+
+ ulong length; // length of all block
+ ulong used; // length of data
+ /*
+ Not used **pprev, **prev because really needed access to pervious block:
+ *pprev to join free blocks
+ *prev to access to opposite side of list in cyclic sorted list
+ */
+ Query_cache_block *pnext,*pprev, // physical next/previous block
+ *next,*prev; // logical next/previous block
+ block_type type;
+ TABLE_COUNTER_TYPE n_tables; // number of tables in query
+
+ inline my_bool is_free(void) { return type == FREE; }
+ void init(ulong length);
+ void destroy();
+ inline uint headers_len();
+ inline gptr data(void);
+ inline Query_cache_query *query();
+ inline Query_cache_table *table();
+ inline Query_cache_result *result();
+ inline Query_cache_block_table *table(TABLE_COUNTER_TYPE n);
+};
+
+struct Query_cache_query
+{
+ ulonglong limit_found_rows;
+ rw_lock_t lock;
+ Query_cache_block *res;
+ NET *wri;
+ ulong len;
+
+ inline void init_n_lock();
+ void unlock_n_destroy();
+ inline ulonglong found_rows() { return limit_found_rows; }
+ inline void found_rows(ulonglong rows) { limit_found_rows = rows; }
+ inline Query_cache_block *result() { return res; }
+ inline void result(Query_cache_block *p) { res=p; }
+ inline NET *writer() { return wri; }
+ inline void writer(NET *p) { wri=p; }
+ inline ulong length() { return len; }
+ inline ulong add(ulong packet_len) { return(len += packet_len); }
+ inline void length(ulong length) { len = length; }
+ inline gptr query()
+ {
+ return (gptr)(((byte*)this)+
+ ALIGN_SIZE(sizeof(Query_cache_query)));
+ }
+ void lock_writing();
+ void lock_reading();
+ my_bool try_lock_writing();
+ void unlock_writing();
+ void unlock_reading();
+ static byte *cache_key(const byte *record, uint *length, my_bool not_used);
+};
+
+
+struct Query_cache_table
+{
+ char *tbl;
+
+ inline char *db() { return (char *) data(); }
+ inline char *table() { return tbl; }
+ inline void table(char *table) { tbl = table; }
+ inline gptr data()
+ {
+ return (gptr)(((byte*)this)+
+ ALIGN_SIZE(sizeof(Query_cache_table)));
+ }
+};
+
+struct Query_cache_result
+{
+ Query_cache_block *query;
+
+ inline gptr data()
+ {
+ return (gptr)(((byte*) this)+
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ }
+ /* data_continue (if not whole packet contained by this block) */
+ inline Query_cache_block *parent() { return query; }
+ inline void parent (Query_cache_block *p) { query=p; }
+};
+
+
+extern "C" {
+ byte *query_cache_query_get_key(const byte *record, uint *length,
+ my_bool not_used);
+ byte *query_cache_table_get_key(const byte *record, uint *length,
+ my_bool not_used);
+ void query_cache_insert(THD *thd, const char *packet, ulong length);
+ void query_cache_end_of_result(THD *thd);
+ void query_cache_abort(THD *thd);
+ void query_cache_invalidate_by_MyISAM_filename(const char* filename);
+}
+
+struct Query_cache_memory_bin
+{
+#ifndef DBUG_OFF
+ ulong size;
+#endif
+ uint number;
+ Query_cache_block *free_blocks;
+
+ inline void init(ulong size_arg)
+ {
+#ifndef DBUG_OFF
+ size = size_arg;
+#endif
+ number = 0;
+ free_blocks = 0;
+ }
+};
+
+struct Query_cache_memory_bin_step
+{
+ ulong size;
+ ulong increment;
+ uint idx;
+ inline void init(ulong size_arg, uint idx_arg, ulong increment_arg)
+ {
+ size = size_arg;
+ idx = idx_arg;
+ increment = increment_arg;
+ }
+};
+
+class Query_cache
+{
+public:
+ /* Info */
+ ulong query_cache_size, query_cache_limit;
+ /* statistics */
+ ulong free_memory, queries_in_cache, hits, inserts, refused,
+ free_memory_blocks, total_blocks;
+
+protected:
+ /*
+ The following mutex is locked when searching or changing global
+ query, tables lists or hashes. When we are operating inside the
+ query structure we locked an internal query block mutex.
+ LOCK SEQUENCE (to prevent deadlocks):
+ 1. structure_guard_mutex
+ 2. query block (for operation inside query (query block/results))
+ */
+ pthread_mutex_t structure_guard_mutex;
+ byte *cache; // cache memory
+ Query_cache_block *first_block; // physical location block list
+ Query_cache_block *queries_blocks; // query list (LIFO)
+ Query_cache_block *tables_blocks;
+
+ Query_cache_memory_bin *bins; // free block lists
+ Query_cache_memory_bin_step *steps; // bins spacing info
+ HASH queries, tables;
+ /* options */
+ ulong min_allocation_unit, min_result_data_size;
+ uint def_query_hash_size, def_table_hash_size;
+ uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin
+
+ my_bool initialized;
+
+ /* Exclude/include from cyclic double linked list */
+ static void double_linked_list_exclude(Query_cache_block *point,
+ Query_cache_block **list_pointer);
+ static void double_linked_list_simple_include(Query_cache_block *point,
+ Query_cache_block **
+ list_pointer);
+ static void double_linked_list_join(Query_cache_block *head_tail,
+ Query_cache_block *tail_head);
+
+ /* Table key generation */
+ static uint filename_2_table_key (char *key, const char *filename,
+ uint32 *db_langth);
+
+ /* The following functions require that structure_guard_mutex is locked */
+ void flush_cache();
+ my_bool free_old_query();
+ void free_query(Query_cache_block *point);
+ my_bool allocate_data_chain(Query_cache_block **result_block,
+ ulong data_len,
+ Query_cache_block *query_block,
+ my_bool first_block);
+ void invalidate_table(TABLE_LIST *table);
+ void invalidate_table(TABLE *table);
+ void invalidate_table(byte *key, uint32 key_length);
+ void invalidate_table(Query_cache_block *table_block);
+ my_bool register_all_tables(Query_cache_block *block,
+ TABLE_LIST *tables_used,
+ TABLE_COUNTER_TYPE tables);
+ my_bool insert_table(uint key_len, char *key,
+ Query_cache_block_table *node,
+ uint32 db_length);
+ void unlink_table(Query_cache_block_table *node);
+ Query_cache_block *get_free_block (ulong len, my_bool not_less,
+ ulong min);
+ void free_memory_block(Query_cache_block *point);
+ void split_block(Query_cache_block *block, ulong len);
+ Query_cache_block *join_free_blocks(Query_cache_block *first_block,
+ Query_cache_block *block_in_list);
+ my_bool append_next_free_block(Query_cache_block *block,
+ ulong add_size);
+ void exclude_from_free_memory_list(Query_cache_block *free_block);
+ void insert_into_free_memory_list(Query_cache_block *new_block);
+ my_bool move_by_type(byte **border, Query_cache_block **before,
+ ulong *gap, Query_cache_block *i);
+ uint find_bin(ulong size);
+ void move_to_query_list_end(Query_cache_block *block);
+ void insert_into_free_memory_sorted_list(Query_cache_block *new_block,
+ Query_cache_block **list);
+ void pack_cache();
+ void relink(Query_cache_block *oblock,
+ Query_cache_block *nblock,
+ Query_cache_block *next,
+ Query_cache_block *prev,
+ Query_cache_block *pnext,
+ Query_cache_block *pprev);
+ my_bool join_results(ulong join_limit);
+
+ /*
+ Following function control structure_guard_mutex
+ by themself or don't need structure_guard_mutex
+ */
+ void init();
+ ulong init_cache();
+ void make_disabled();
+ void free_cache(my_bool destruction);
+ Query_cache_block *write_block_data(ulong data_len, gptr data,
+ ulong header_len,
+ Query_cache_block::block_type type,
+ TABLE_COUNTER_TYPE ntab = 0,
+ my_bool under_guard=0);
+ my_bool append_result_data(Query_cache_block **result,
+ ulong data_len, gptr data,
+ Query_cache_block *parent);
+ my_bool write_result_data(Query_cache_block **result,
+ ulong data_len, gptr data,
+ Query_cache_block *parent,
+ Query_cache_block::block_type
+ 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,
+ ulong min,
+ my_bool under_guard=0);
+ /*
+ If query is cacheable return number tables in query
+ (query without tables not cached)
+ */
+ TABLE_COUNTER_TYPE is_cacheable(THD *thd, uint32 query_len, char *query,
+ LEX *lex, TABLE_LIST *tables_used);
+ public:
+
+ Query_cache(ulong query_cache_limit = ULONG_MAX,
+ ulong min_allocation_unit = QUERY_CACHE_MIN_ALLOCATION_UNIT,
+ ulong min_result_data_size = QUERY_CACHE_MIN_RESULT_DATA_SIZE,
+ uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
+ uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE);
+
+ /* resize query cache (return real query size, 0 if disabled) */
+ ulong resize(ulong query_cache_size);
+ inline void result_size_limit(ulong limit){query_cache_limit=limit;}
+
+ /* register query in cache */
+ void store_query(THD *thd, TABLE_LIST *used_tables);
+
+ /*
+ Check if the query is in the cache and if this is true send the
+ data to client.
+ */
+ int send_result_to_client(THD *thd, char *query, uint query_length);
+
+ /* Remove all queries that uses any of the listed following tables */
+ void invalidate(THD* thd, TABLE_LIST *tables_used,
+ my_bool using_transactions);
+ void invalidate(CHANGED_TABLE_LIST *tables_used);
+ void invalidate(THD* thd, TABLE *table, my_bool using_transactions);
+
+ /* Remove all queries that uses any of the tables in following database */
+ void invalidate(char *db);
+
+ /* Remove all queries that uses any of the listed following table */
+ void invalidate_by_MyISAM_filename(const char *filename);
+
+ void flush();
+ void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT,
+ uint iteration_limit = QUERY_CACHE_PACK_ITERATION);
+
+ void destroy();
+
+ friend void query_cache_insert(NET *net, const char *packet, ulong length);
+ friend void query_cache_end_of_result(NET *net);
+ friend void query_cache_abort(NET *net);
+
+ /*
+ The following functions are only used when debugging
+ We don't protect these with ifndef DEBUG_OFF to not have to recompile
+ everything if we want to add checks of the cache at some places.
+ */
+ void wreck(uint line, const char *message);
+ void bins_dump();
+ void cache_dump();
+ void queries_dump();
+ void tables_dump();
+ my_bool check_integrity(bool not_locked);
+ my_bool in_list(Query_cache_block * root, Query_cache_block * point,
+ 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);
+};
+
+extern Query_cache query_cache;
+extern TYPELIB query_cache_type_typelib;
+void query_cache_insert(NET *net, const char *packet, ulong length);
+void query_cache_end_of_result(NET *net);
+void query_cache_abort(NET *net);
+
+#endif
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ace7c291ed3..cc2c9fdc6ef 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -34,6 +34,8 @@
#ifdef __WIN__
#include <io.h>
#endif
+#include <mysys_err.h>
+#include <assert.h>
/*****************************************************************************
** Instansiate templates
@@ -80,34 +82,38 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
global_read_lock(0),bootstrap(0)
{
host=user=priv_user=db=query=ip=0;
+ host_or_ip="unknown ip";
locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password=
- query_start_used=0;
- query_length=col_access=0;
+ query_start_used=safe_to_cache_query=0;
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ variables= global_system_variables;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ db_length=query_length=col_access=0;
query_error=0;
next_insert_id=last_insert_id=0;
- open_tables=temporary_tables=0;
+ open_tables=temporary_tables=handler_tables=0;
+ handler_items=0;
tmp_table=0;
lock=locked_tables=0;
used_tables=0;
- gemini_spin_retries=0;
cuted_fields=sent_row_count=0L;
start_time=(time_t) 0;
current_linfo = 0;
slave_thread = 0;
slave_proxy_id = 0;
- last_nx_table = last_nx_db = 0;
+ file_id = 0;
cond_count=0;
- convert_set=0;
mysys_var=0;
+#ifndef DBUG_OFF
+ dbug_sentry=THD_SENTRY_MAGIC;
+#endif
net.vio=0;
ull=0;
system_thread=cleanup_done=0;
+ transaction.changed_tables = 0;
#ifdef __WIN__
real_id = 0;
#endif
-#ifdef HAVE_GEMINI_DB
- bzero((char *)&gemini, sizeof(gemini));
-#endif
#ifdef SIGNAL_WITH_VIO_CLOSE
active_vio = 0;
pthread_mutex_init(&active_vio_lock, MY_MUTEX_INIT_FAST);
@@ -117,22 +123,24 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
proc_info="login";
where="field list";
server_id = ::server_id;
- server_status=SERVER_STATUS_AUTOCOMMIT;
- update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
- options=thd_startup_options;
+ slave_net = 0;
+ log_pos = 0;
+ server_status= SERVER_STATUS_AUTOCOMMIT;
+ update_lock_default= (variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY :
+ TL_WRITE);
+ options= thd_startup_options;
sql_mode=(uint) opt_sql_mode;
- inactive_timeout=net_wait_timeout;
open_options=ha_open_options;
- tx_isolation=session_tx_isolation=default_tx_isolation;
+ session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
command=COM_CONNECT;
set_query_id=1;
- default_select_limit= HA_POS_ERROR;
- max_join_size= ((::max_join_size != ~ (ulong) 0L) ? ::max_join_size :
- HA_POS_ERROR);
db_access=NO_ACCESS;
/* Initialize sub structures */
bzero((char*) &mem_root,sizeof(mem_root));
+ bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root));
+ user_connect=(USER_CONN *)0;
hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
(void (*)(void*)) free_var,0);
@@ -160,6 +168,11 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0;
close_thread_tables(this);
}
+ if (handler_tables)
+ {
+ open_tables=handler_tables; handler_tables=0;
+ close_thread_tables(this);
+ }
close_temporary_tables(this);
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
@@ -174,6 +187,7 @@ void THD::cleanup(void)
THD::~THD()
{
+ THD_CHECK_SENTRY(this);
DBUG_ENTER("~THD()");
/* Close connection */
if (net.vio)
@@ -184,12 +198,7 @@ THD::~THD()
if (!cleanup_done)
cleanup();
if (global_read_lock)
- {
- pthread_mutex_lock(&LOCK_open);
- ::global_read_lock--;
- pthread_cond_broadcast(&COND_refresh);
- pthread_mutex_unlock(&LOCK_open);
- }
+ unlock_global_read_lock(this);
if (ull)
{
pthread_mutex_lock(&LOCK_user_locks);
@@ -199,7 +208,7 @@ THD::~THD()
hash_free(&user_vars);
DBUG_PRINT("info", ("freeing host"));
-
+
if (host != localhost) // If not pointer to constant
safeFree(host);
if (user != delayed_user)
@@ -207,37 +216,51 @@ THD::~THD()
safeFree(db);
safeFree(ip);
free_root(&mem_root,MYF(0));
+ free_root(&transaction.mem_root,MYF(0));
mysys_var=0; // Safety (shouldn't be needed)
#ifdef SIGNAL_WITH_VIO_CLOSE
pthread_mutex_destroy(&active_vio_lock);
+#endif
+#ifndef DBUG_OFF
+ dbug_sentry = THD_SENTRY_GONE;
#endif
DBUG_VOID_RETURN;
}
-void THD::prepare_to_die()
+void THD::awake(bool prepare_to_die)
{
+ THD_CHECK_SENTRY(this);
+ if (prepare_to_die)
+ killed = 1;
thr_alarm_kill(real_id);
- killed = 1;
#ifdef SIGNAL_WITH_VIO_CLOSE
close_active_vio();
#endif
if (mysys_var)
+ {
+ pthread_mutex_lock(&mysys_var->mutex);
+ if (!system_thread) // Don't abort locks
+ mysys_var->abort=1;
+ /*
+ This broadcast could be up in the air if the victim thread
+ exits the cond in the time between read and broadcast, but that is
+ ok since all we want to do is to make the victim thread get out
+ of waiting on current_cond.
+ */
+ if (mysys_var->current_cond)
{
- pthread_mutex_lock(&mysys_var->mutex);
- if (!system_thread) // Don't abort locks
- mysys_var->abort=1;
- if (mysys_var->current_cond)
- {
- pthread_mutex_lock(mysys_var->current_mutex);
- pthread_cond_broadcast(mysys_var->current_cond);
- pthread_mutex_unlock(mysys_var->current_mutex);
- }
- pthread_mutex_unlock(&mysys_var->mutex);
+ pthread_mutex_lock(mysys_var->current_mutex);
+ pthread_cond_broadcast(mysys_var->current_cond);
+ pthread_mutex_unlock(mysys_var->current_mutex);
}
+ pthread_mutex_unlock(&mysys_var->mutex);
+ }
}
-// remember the location of thread info, the structure needed for
-// sql_alloc() and the structure for the net buffer
+/*
+ Remember the location of thread info, the structure needed for
+ sql_alloc() and the structure for the net buffer
+*/
bool THD::store_globals()
{
@@ -246,6 +269,89 @@ bool THD::store_globals()
my_pthread_setspecific_ptr(THR_NET, &net));
}
+
+/* routings to adding tables to list of changed in transaction tables */
+
+inline static void list_include(CHANGED_TABLE_LIST** prev,
+ CHANGED_TABLE_LIST* curr,
+ CHANGED_TABLE_LIST* new_table)
+{
+ if (new_table)
+ {
+ *prev = new_table;
+ (*prev)->next = curr;
+ }
+}
+
+/* add table to list of changed in transaction tables */
+
+void THD::add_changed_table(TABLE *table)
+{
+ DBUG_ENTER("THD::add_changed_table(table)");
+
+ DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ table->file->has_transactions());
+
+ CHANGED_TABLE_LIST** prev = &transaction.changed_tables;
+ CHANGED_TABLE_LIST* curr = transaction.changed_tables;
+
+ for (; curr; prev = &(curr->next), curr = curr->next)
+ {
+ int cmp = (long)curr->key_length - (long)table->key_length;
+ if (cmp < 0)
+ {
+ list_include(prev, curr, changed_table_dup(table));
+ DBUG_PRINT("info",
+ ("key_length %u %u", table->key_length, (*prev)->key_length));
+ DBUG_VOID_RETURN;
+ }
+ else if (cmp == 0)
+ {
+ cmp = memcmp(curr->key ,table->table_cache_key, curr->key_length);
+ if (cmp < 0)
+ {
+ list_include(prev, curr, changed_table_dup(table));
+ DBUG_PRINT("info",
+ ("key_length %u %u", table->key_length,
+ (*prev)->key_length));
+ DBUG_VOID_RETURN;
+ }
+ else if (cmp == 0)
+ {
+ DBUG_PRINT("info", ("already in list"));
+ DBUG_VOID_RETURN;
+ }
+ }
+ }
+ *prev = changed_table_dup(table);
+ DBUG_PRINT("info", ("key_length %u %u", table->key_length,
+ (*prev)->key_length));
+ DBUG_VOID_RETURN;
+}
+
+
+CHANGED_TABLE_LIST* THD::changed_table_dup(TABLE *table)
+{
+ CHANGED_TABLE_LIST* new_table =
+ (CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
+ table->key_length + 1);
+ if (!new_table)
+ {
+ my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
+ ALIGN_SIZE(sizeof(TABLE_LIST)) + table->key_length + 1);
+ killed= 1;
+ return 0;
+ }
+
+ new_table->key = (char *) (((byte*)new_table)+
+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST)));
+ new_table->next = 0;
+ new_table->key_length = table->key_length;
+ ::memcpy(new_table->key, table->table_cache_key, table->key_length);
+ return new_table;
+}
+
+
/*****************************************************************************
** Functions to provide a interface to select results
*****************************************************************************/
@@ -277,7 +383,7 @@ bool select_send::send_fields(List<Item> &list,uint flag)
bool select_send::send_data(List<Item> &items)
{
- List_iterator<Item> li(items);
+ List_iterator_fast<Item> li(items);
String *packet= &thd->packet;
DBUG_ENTER("send_data");
@@ -290,7 +396,7 @@ bool select_send::send_data(List<Item> &items)
Item *item;
while ((item=li++))
{
- if (item->send(packet))
+ if (item->send(thd, packet))
{
packet->free(); // Free used
my_error(ER_OUT_OF_RESOURCES,MYF(0));
@@ -302,12 +408,6 @@ bool select_send::send_data(List<Item> &items)
DBUG_RETURN(error);
}
-
-void select_send::send_error(uint errcode,const char *err)
-{
- ::send_error(&thd->net,errcode,err);
-}
-
bool select_send::send_eof()
{
/* Unlock tables before sending packet to gain some speed */
@@ -370,7 +470,7 @@ select_export::prepare(List<Item> &list)
}
/* Check if there is any blobs in data */
{
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
{
@@ -417,7 +517,7 @@ bool select_export::send_data(List<Item> &items)
Item *item;
char *buff_ptr=buff;
uint used_length=0,items_left=items.elements;
- List_iterator<Item> li(items);
+ List_iterator_fast<Item> li(items);
if (my_b_write(&cache,(byte*) exchange->line_start->ptr(),
exchange->line_start->length()))
@@ -505,7 +605,7 @@ bool select_export::send_data(List<Item> &items)
bfill(space,sizeof(space),' ');
}
uint length=item->max_length-used_length;
- for ( ; length > sizeof(space) ; length-=sizeof(space))
+ for (; length > sizeof(space) ; length-=sizeof(space))
{
if (my_b_write(&cache,(byte*) space,sizeof(space)))
goto err;
@@ -610,7 +710,7 @@ select_dump::prepare(List<Item> &list __attribute__((unused)))
bool select_dump::send_data(List<Item> &items)
{
- List_iterator<Item> li(items);
+ List_iterator_fast<Item> li(items);
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff)),*res;
tmp.length(0);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d9497907926..633f7a4aa76 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,10 +21,14 @@
#pragma interface /* gcc class implementation */
#endif
+// TODO: create log.h and move all the log header stuff there
+
class Query_log_event;
class Load_log_event;
+class Slave_log_event;
-
+enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
+enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE };
enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
@@ -38,6 +42,8 @@ enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
#define LOG_INFO_FATAL -7
#define LOG_INFO_IN_USE -8
+struct st_relay_log_info;
+
typedef struct st_log_info
{
char log_file_name[FN_REFLEN];
@@ -49,58 +55,107 @@ typedef struct st_log_info
~st_log_info() { pthread_mutex_destroy(&lock);}
} LOG_INFO;
+class Log_event;
class MYSQL_LOG {
private:
pthread_mutex_t LOCK_log, LOCK_index;
+ pthread_cond_t update_cond;
+ ulonglong bytes_written;
time_t last_time,query_start;
IO_CACHE log_file;
File index_file;
char *name;
- volatile enum_log_type log_type;
char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
+ // current file sequence number for load data infile binary logging
+ uint file_id;
+ uint open_count; // For replication
+ /*
+ For binlog - if log name can never change we should not try to rotate it
+ or write any rotation events. The user should use FLUSH MASTER instead
+ of FLUSH LOGS for purging.
+ */
+ volatile enum_log_type log_type;
+ enum cache_type io_cache_type;
bool write_error,inited;
- bool no_rotate; // for binlog - if log name can never change
- // we should not try to rotate it or write any rotation events
- // the user should use FLUSH MASTER instead of FLUSH LOGS for
- // purging
+ bool no_rotate;
+ bool need_start_event;
+ bool no_auto_events; // for relay binlog
+ friend class Log_event;
public:
MYSQL_LOG();
~MYSQL_LOG();
- pthread_mutex_t* get_log_lock() { return &LOCK_log; }
+ void reset_bytes_written()
+ {
+ bytes_written = 0;
+ }
+ void harvest_bytes_written(ulonglong* counter)
+ {
+#ifndef DBUG_OFF
+ char buf1[22],buf2[22];
+#endif
+ DBUG_ENTER("harvest_bytes_written");
+ (*counter)+=bytes_written;
+ DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
+ llstr(bytes_written,buf2)));
+ bytes_written=0;
+ DBUG_VOID_RETURN;
+ }
+ void signal_update() { pthread_cond_broadcast(&update_cond);}
+ void wait_for_update(THD* thd);
+ void set_need_start_event() { need_start_event = 1; }
void set_index_file_name(const char* index_file_name = 0);
- void init(enum_log_type log_type_arg);
+ void init(enum_log_type log_type_arg,
+ enum cache_type io_cache_type_arg = WRITE_CACHE,
+ bool no_auto_events_arg = 0);
void open(const char *log_name,enum_log_type log_type,
- const char *new_name=0);
+ const char *new_name, enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg);
void new_file(bool inside_mutex = 0);
bool open_index(int options);
void close_index();
- bool write(THD *thd, enum enum_server_command command,const char *format,...);
+ bool write(THD *thd, enum enum_server_command command,
+ const char *format,...);
bool write(THD *thd, const char *query, uint query_length,
time_t query_start=0);
- bool write(Query_log_event* event_info); // binary log write
- bool write(Load_log_event* event_info);
+ bool write(Log_event* event_info); // binary log write
bool write(THD *thd, IO_CACHE *cache);
+
+ /*
+ v stands for vector
+ invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
+ */
+ bool appendv(const char* buf,uint len,...);
+ bool append(Log_event* ev);
+
int generate_new_name(char *new_name,const char *old_name);
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
int purge_logs(THD* thd, const char* to_log);
- void close(bool exiting = 0); // if we are exiting, we also want to close the
- // index file
+ int purge_first_log(struct st_relay_log_info* rli);
+ int reset_logs(THD* thd);
+ // if we are exiting, we also want to close the index file
+ void close(bool exiting = 0);
// iterating through the log index file
- int find_first_log(LOG_INFO* linfo, const char* log_name);
- int find_next_log(LOG_INFO* linfo);
+ int find_first_log(LOG_INFO* linfo, const char* log_name,
+ bool need_mutex=1);
+ int find_next_log(LOG_INFO* linfo, bool need_mutex=1);
int get_current_log(LOG_INFO* linfo);
+ uint next_file_id();
inline bool is_open() { return log_type != LOG_CLOSED; }
- char* get_index_fname() { return index_file_name;}
- char* get_log_fname() { return log_file_name; }
- void lock_index() { pthread_mutex_lock(&LOCK_index);}
- void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
- File get_index_file() { return index_file;}
+ inline char* get_index_fname() { return index_file_name;}
+ inline char* get_log_fname() { return log_file_name; }
+ inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
+ inline IO_CACHE* get_log_file() { return &log_file; }
+
+ inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
+ inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
+ inline File get_index_file() { return index_file;}
+ inline uint32 get_open_count() { return open_count; }
};
/* character conversion tables */
@@ -114,23 +169,25 @@ class CONVERT
void convert_array(const uchar *mapping,uchar *buff,uint length);
public:
const char *name;
- CONVERT(const char *name_par,uchar *from_par,uchar *to_par)
- :from_map(from_par),to_map(to_par),name(name_par) {}
+ uint numb;
+ CONVERT(const char *name_par,uchar *from_par,uchar *to_par, uint number)
+ :from_map(from_par),to_map(to_par),name(name_par),numb(number) {}
friend CONVERT *get_convert_set(const char *name_ptr);
inline void convert(char *a,uint length)
{
convert_array(from_map, (uchar*) a,length);
}
bool store(String *, const char *,uint);
+ inline uint number() { return numb; }
};
typedef struct st_copy_info {
ha_rows records;
ha_rows deleted;
ha_rows copied;
- ha_rows error;
+ ha_rows error_count;
enum enum_duplicates handle_duplicates;
- int escape_char;
+ int escape_char, last_errno;
} COPY_INFO;
@@ -165,11 +222,13 @@ class Key :public Sql_alloc {
public:
enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT };
enum Keytype type;
+ enum ha_key_alg algorithm;
List<key_part_spec> columns;
const char *Name;
Key(enum Keytype type_par,const char *name_arg,List<key_part_spec> &cols)
- :type(type_par), columns(cols),Name(name_arg) {}
+ :type(type_par), algorithm(HA_KEY_ALG_UNDEF), columns(cols), Name(name_arg)
+ {}
~Key() {}
const char *name() { return Name; }
};
@@ -214,50 +273,136 @@ public:
};
-/****************************************************************************
-** every connection is handle by a thread with a THD
-****************************************************************************/
-
class delayed_insert;
+#define THD_SENTRY_MAGIC 0xfeedd1ff
+#define THD_SENTRY_GONE 0xdeadbeef
+
+#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
+
+struct system_variables
+{
+ ulonglong myisam_max_extra_sort_file_size;
+ ulonglong myisam_max_sort_file_size;
+ ulong bulk_insert_buff_size;
+ ulong join_buff_size;
+ ulong long_query_time;
+ ulong max_allowed_packet;
+ ulong max_heap_table_size;
+ ulong max_sort_length;
+ ulong max_join_size;
+ ulong max_tmp_tables;
+ ulong myisam_sort_buff_size;
+ ulong net_buffer_length;
+ ulong net_interactive_timeout;
+ ulong net_read_timeout;
+ ulong net_wait_timeout;
+ ulong net_write_timeout;
+ ulong query_cache_type;
+ ulong read_buff_size;
+ ulong read_rnd_buff_size;
+ ulong select_limit;
+ ulong sortbuff_size;
+ ulong tmp_table_size;
+ ulong tx_isolation;
+ ulong table_type;
+
+ my_bool log_warnings;
+ my_bool low_priority_updates;
+
+ CONVERT *convert_set;
+};
+
+
+/*
+ For each client connection we create a separate thread with THD serving as
+ a thread/connection descriptor
+*/
+
class THD :public ilink {
public:
- NET net;
- LEX lex;
- MEM_ROOT mem_root;
- HASH user_vars;
- String packet; /* Room for 1 row */
- struct sockaddr_in remote;
- struct rand_struct rand;
- char *query,*thread_stack;
+ NET net; // client connection descriptor
+ LEX lex; // parse tree descriptor
+ MEM_ROOT mem_root; // 1 command-life memory pool
+ HASH user_vars; // hash for user variables
+ String packet; // dynamic buffer for network I/O
+ struct sockaddr_in remote; // client socket address
+ struct rand_struct rand; // used for authentication
+ struct system_variables variables; // Changeable local variables
+
+ char *query; // Points to the current query,
+ /*
+ A pointer to the stack frame of handle_one_connection(),
+ which is called first in the thread for handling a client
+ */
+ char *thread_stack;
+
+ /*
+ host - host of the client
+ user - user of the client, set to NULL until the user has been read from
+ the connection
+ priv_user - not sure why we have it, but it is set to "boot" when we run
+ with --bootstrap
+ db - currently selected database
+ ip - client IP
+ */
+
char *host,*user,*priv_user,*db,*ip;
- const char *proc_info;
- uint client_capabilities,sql_mode,max_packet_length;
- uint master_access,db_access;
- TABLE *open_tables,*temporary_tables;
+ /* Points to info-string that will show in SHOW PROCESSLIST */
+ const char *proc_info;
+ /* points to host if host is available, otherwise points to ip */
+ const char *host_or_ip;
+
+ uint client_capabilities; /* What the client supports */
+ /* Determines if which non-standard SQL behaviour should be enabled */
+ uint sql_mode;
+ uint max_client_packet_length;
+ ulong master_access; /* Global privileges from mysql.user */
+ ulong db_access; /* Privileges for current db */
+
+
+ /*
+ open_tables - list of regular tables in use by this thread
+ temporary_tables - list of temp tables in use by this thread
+ handler_tables - list of tables that were opened with HANDLER OPEN
+ and are still in use by this thread
+ */
+ TABLE *open_tables,*temporary_tables, *handler_tables;
+ // TODO: document the variables below
MYSQL_LOCK *lock,*locked_tables;
ULL *ull;
+#ifndef DBUG_OFF
+ uint dbug_sentry; // watch out for memory corruption
+#endif
struct st_my_thread_var *mysys_var;
enum enum_server_command command;
- uint32 server_id;
+ uint32 server_id;
+ uint32 file_id; // for LOAD DATA INFILE
const char *where;
- char* last_nx_table; // last non-existent table, we need this for replication
- char* last_nx_db; // database of the last nx table
- time_t start_time,time_after_lock,user_time;
- time_t connect_time,thr_create_time; // track down slow pthread_create
+ time_t start_time,time_after_lock,user_time;
+ time_t connect_time,thr_create_time; // track down slow pthread_create
thr_lock_type update_lock_default;
delayed_insert *di;
struct st_transactions {
IO_CACHE trans_log;
- THD_TRANS all; /* Trans since BEGIN WORK */
- THD_TRANS stmt; /* Trans for current statement */
+ THD_TRANS all; // Trans since BEGIN WORK
+ THD_TRANS stmt; // Trans for current statement
uint bdb_lock_count;
+
+ /*
+ Tables changed in transaction (that must be invalidated in query cache).
+ List contain only transactional tables, that not invalidated in query
+ cache (instead of full list of changed in transaction tables).
+ */
+ CHANGED_TABLE_LIST* changed_tables;
+ MEM_ROOT mem_root; // Transaction-life memory allocation pool
+ void cleanup()
+ {
+ changed_tables = 0;
+ free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
+ }
} transaction;
-#ifdef HAVE_GEMINI_DB
- struct st_gemini gemini;
-#endif
- Item *free_list;
- CONVERT *convert_set;
+ Item *free_list, *handler_items;
Field *dupp_field;
#ifndef __WIN__
sigset_t signals,block_signals;
@@ -266,32 +411,51 @@ public:
Vio* active_vio;
pthread_mutex_t active_vio_lock;
#endif
- ulonglong next_insert_id,last_insert_id,current_insert_id;
- ha_rows select_limit,offset_limit,default_select_limit,cuted_fields,
- max_join_size, sent_row_count, examined_row_count;
- table_map used_tables;
- ulong query_id,version, inactive_timeout,options,thread_id;
- ulong gemini_spin_retries;
- long dbug_thread_id;
+ ulonglong next_insert_id,last_insert_id,current_insert_id,
+ limit_found_rows;
+ ha_rows select_limit, offset_limit, cuted_fields,
+ sent_row_count, examined_row_count;
+ table_map used_tables;
+ USER_CONN *user_connect;
+ ulong query_id,version, options,thread_id, col_access;
+ long dbug_thread_id;
pthread_t real_id;
- uint current_tablenr,tmp_table,cond_count,col_access,query_length;
- uint server_status,open_options;
- enum_tx_isolation tx_isolation, session_tx_isolation;
+ uint current_tablenr,tmp_table,cond_count;
+ uint server_status,open_options;
+ uint32 query_length;
+ uint32 db_length;
+ /* variables.transaction_isolation is reset to this after each commit */
+ enum_tx_isolation session_tx_isolation;
char scramble[9];
+ uint8 query_cache_type; // type of query cache processing
bool slave_thread;
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
bool no_errors, allow_sum_func, password, fatal_error;
bool query_start_used,last_insert_id_used,insert_id_used;
bool system_thread,in_lock_tables,global_read_lock;
bool query_error, bootstrap, cleanup_done;
+ bool safe_to_cache_query;
bool volatile killed;
+ /*
+ If we do a purge of binary logs, log index info of the threads
+ that are currently reading it needs to be adjusted. To do that
+ each thread that is using LOG_INFO needs to adjust the pointer to it
+ */
LOG_INFO* current_linfo;
- // if we do a purge of binary logs, log index info of the threads
- // that are currently reading it needs to be adjusted. To do that
- // each thread that is using LOG_INFO needs to adjust the pointer to it
-
- ulong slave_proxy_id; // in slave thread we need to know in behalf of which
- // thread the query is being run to replicate temp tables properly
+ /*
+ In slave thread we need to know in behalf of which
+ thread the query is being run to replicate temp tables properly
+ */
+ ulong slave_proxy_id;
+ NET* slave_net; // network connection from slave -> m.
+ my_off_t log_pos;
+
+ /* Used by the sys_var class to store temporary values */
+ union
+ {
+ my_bool my_bool_value;
+ long long_value;
+ } sys_var_tmp;
THD();
~THD();
@@ -313,15 +477,15 @@ public:
inline void close_active_vio()
{
pthread_mutex_lock(&active_vio_lock);
- if(active_vio)
- {
- vio_close(active_vio);
- active_vio = 0;
- }
+ if (active_vio)
+ {
+ vio_close(active_vio);
+ active_vio = 0;
+ }
pthread_mutex_unlock(&active_vio_lock);
}
#endif
- void prepare_to_die();
+ void awake(bool prepare_to_die);
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
const char* msg)
{
@@ -355,16 +519,18 @@ public:
}
return last_insert_id;
}
+ inline ulonglong found_rows(void)
+ {
+ return limit_found_rows;
+ }
inline bool active_transaction()
{
#ifdef USING_TRANSACTIONS
return (transaction.all.bdb_tid != 0 ||
- transaction.all.innodb_active_trans != 0 ||
- transaction.all.gemini_tid != 0);
+ transaction.all.innodb_active_trans != 0);
#else
return 0;
#endif
-
}
inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); }
inline gptr calloc(unsigned int size)
@@ -376,11 +542,29 @@ public:
}
inline char *strdup(const char *str)
{ return strdup_root(&mem_root,str); }
- inline char *memdup(const char *str, unsigned int size)
+ inline char *strmake(const char *str, uint size)
+ { return strmake_root(&mem_root,str,size); }
+ inline char *memdup(const char *str, uint size)
{ return memdup_root(&mem_root,str,size); }
+ inline char *memdup_w_gap(const char *str, uint size, uint gap)
+ {
+ gptr ptr;
+ if ((ptr=alloc_root(&mem_root,size+gap)))
+ memcpy(ptr,str,size);
+ return ptr;
+ }
+ inline gptr trans_alloc(unsigned int size)
+ {
+ return alloc_root(&transaction.mem_root,size);
+ }
+ void add_changed_table(TABLE *table);
+ CHANGED_TABLE_LIST * changed_table_dup(TABLE *table);
};
-
+/*
+ Used to hold information about file and file structure in exchainge
+ via non-DB file (...INTO OUTFILE..., ...LOAD DATA...)
+*/
class sql_exchange :public Sql_alloc
{
public:
@@ -399,6 +583,10 @@ public:
** This is used to get result from a select
*/
+class JOIN;
+
+void send_error(NET *net,uint sql_errno=0, const char *err=0);
+
class select_result :public Sql_alloc {
protected:
THD *thd;
@@ -408,7 +596,11 @@ public:
virtual int prepare(List<Item> &list) { return 0; }
virtual bool send_fields(List<Item> &list,uint flag)=0;
virtual bool send_data(List<Item> &items)=0;
- virtual void send_error(uint errcode,const char *err)=0;
+ virtual void initialize_tables (JOIN *join=0) {}
+ virtual void send_error(uint errcode,const char *err)
+ {
+ ::send_error(&thd->net,errcode,err);
+ }
virtual bool send_eof()=0;
virtual void abort() {}
};
@@ -419,7 +611,6 @@ public:
select_send() {}
bool send_fields(List<Item> &list,uint flag);
bool send_data(List<Item> &items);
- void send_error(uint errcode,const char *err);
bool send_eof();
};
@@ -443,6 +634,7 @@ public:
bool send_eof();
};
+
class select_dump :public select_result {
sql_exchange *exchange;
File file;
@@ -463,29 +655,28 @@ public:
class select_insert :public select_result {
- protected:
+ public:
TABLE *table;
List<Item> *fields;
- uint save_time_stamp;
ulonglong last_insert_id;
COPY_INFO info;
+ uint save_time_stamp;
-public:
select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic)
- :table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0)
- {
- bzero((char*) &info,sizeof(info));
- info.handle_duplicates=duplic;
- }
+ :table(table_par),fields(fields_par), last_insert_id(0), save_time_stamp(0) {
+ bzero((char*) &info,sizeof(info));
+ info.handle_duplicates=duplic;
+ }
~select_insert();
int prepare(List<Item> &list);
- 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);
void send_error(uint errcode,const char *err);
bool send_eof();
};
+
class select_create: public select_insert {
ORDER *group;
const char *db;
@@ -512,6 +703,23 @@ public:
void abort();
};
+class select_union :public select_result {
+ public:
+ TABLE *table;
+ COPY_INFO info;
+ uint save_time_stamp;
+ TMP_TABLE_PARAM *tmp_table_param;
+
+ select_union(TABLE *table_par);
+ ~select_union();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list, uint flag)
+ { return 0; }
+ bool send_data(List<Item> &items);
+ bool send_eof();
+ bool flush();
+};
+
/* Structs used when sorting */
typedef struct st_sort_field {
@@ -561,3 +769,89 @@ class user_var_entry
Item_result type;
};
+/* Class for unique (removing of duplicates) */
+
+class Unique :public Sql_alloc
+{
+ DYNAMIC_ARRAY file_ptrs;
+ ulong max_elements, max_in_memory_size;
+ IO_CACHE file;
+ TREE tree;
+ byte *record_pointers;
+ bool flush();
+
+public:
+ ulong elements;
+ Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
+ uint size, ulong max_in_memory_size_arg);
+ ~Unique();
+ inline bool unique_add(gptr ptr)
+ {
+ if (tree.elements_in_tree > max_elements && flush())
+ return 1;
+ return !tree_insert(&tree,ptr,0);
+ }
+
+ bool get(TABLE *table);
+
+ friend int unique_write_to_file(gptr key, element_count count, Unique *unique);
+ friend int unique_write_to_ptrs(gptr key, element_count count, Unique *unique);
+};
+
+ class multi_delete : public select_result {
+ TABLE_LIST *delete_tables, *table_being_deleted;
+#ifdef SINISAS_STRIP
+ IO_CACHE **tempfiles;
+ byte *memory_lane;
+#else
+ Unique **tempfiles;
+#endif
+ THD *thd;
+ ha_rows deleted;
+ uint num_of_tables;
+ int error;
+ thr_lock_type lock_option;
+ bool do_delete, not_trans_safe;
+ public:
+ multi_delete(THD *thd, TABLE_LIST *dt, thr_lock_type lock_option_arg,
+ uint num_of_tables);
+ ~multi_delete();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list,
+ uint flag) { return 0; }
+ bool send_data(List<Item> &items);
+ void initialize_tables (JOIN *join);
+ void send_error(uint errcode,const char *err);
+ int do_deletes (bool from_send_error);
+ bool send_eof();
+ };
+
+ class multi_update : public select_result {
+ TABLE_LIST *update_tables, *table_being_updated;
+// Unique **tempfiles;
+ COPY_INFO *infos;
+ TABLE **tmp_tables;
+ THD *thd;
+ ha_rows updated, found;
+ List<Item> fields;
+ List <Item> **fields_by_tables;
+ thr_lock_type lock_option;
+ enum enum_duplicates dupl;
+ uint num_of_tables, num_fields, num_updated, *save_time_stamps, *field_sequence;
+ int error;
+ bool do_update, not_trans_safe;
+ public:
+ multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> &fs,
+ enum enum_duplicates handle_duplicates,
+ thr_lock_type lock_option_arg, uint num);
+ ~multi_update();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list,
+ uint flag) { return 0; }
+ bool send_data(List<Item> &items);
+ void initialize_tables (JOIN *join);
+ void send_error(uint errcode,const char *err);
+ int do_updates (bool from_send_error);
+ bool send_eof();
+ };
+
diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc
index 371d63f8c73..f2e4a8934be 100644
--- a/sql/sql_crypt.cc
+++ b/sql/sql_crypt.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_crypt.h b/sql/sql_crypt.h
index b3a9d54133f..1b27f0a4d27 100644
--- a/sql/sql_crypt.h
+++ b/sql/sql_crypt.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index b3d63f72b8d..87926d0612c 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,45 +25,28 @@
#include <direct.h>
#endif
-static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
+static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
+ const char *db, const char *path,
uint level);
/* db-name is already validated when we come here */
-void mysql_create_db(THD *thd, char *db, uint create_options)
+int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
{
char path[FN_REFLEN+16];
MY_DIR *dirp;
long result=1;
+ int error = 0;
DBUG_ENTER("mysql_create_db");
-
+
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
- VOID(pthread_mutex_lock(&LOCK_open));
// do not create database if another thread is holding read lock
- if (global_read_lock)
+ if (wait_if_global_read_lock(thd,0))
{
- if (thd->global_read_lock)
- {
- net_printf(&thd->net, ER_CREATE_DB_WITH_READ_LOCK);
- VOID(pthread_mutex_unlock(&LOCK_open));
- goto exit;
- }
- while (global_read_lock && ! thd->killed)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
-
- if (thd->killed)
- {
- net_printf(&thd->net, ER_SERVER_SHUTDOWN);
- VOID(pthread_mutex_unlock(&LOCK_open));
- goto exit;
- }
-
+ error= -1;
+ goto exit2;
}
-
- VOID(pthread_mutex_unlock(&LOCK_open));
/* Check directory */
(void)sprintf(path,"%s/%s", mysql_data_home, db);
@@ -73,7 +56,8 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
my_dirend(dirp);
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
{
- net_printf(&thd->net,ER_DB_CREATE_EXISTS,db);
+ my_error(ER_DB_CREATE_EXISTS,MYF(0),db);
+ error = -1;
goto exit;
}
result = 0;
@@ -83,140 +67,148 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
strend(path)[-1]=0; // Remove last '/' from path
if (my_mkdir(path,0777,MYF(0)) < 0)
{
- net_printf(&thd->net,ER_CANT_CREATE_DB,db,my_errno);
+ my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
+ error = -1;
goto exit;
}
}
- if (!thd->query)
- {
- thd->query = path;
- thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)-
- path);
- }
+
+ if (!silent)
{
- mysql_update_log.write(thd,thd->query, thd->query_length);
- if (mysql_bin_log.is_open())
+ if (!thd->query)
{
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
+ thd->query = path;
+ thd->query_length = (uint) (strxmov(path,"create 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);
}
- 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_VOID_RETURN;
+ DBUG_RETURN(error);
}
-const char *del_exts[]=
-{".frm",".ISM",".ISD",".ISM",".HSH",".DAT",".MRG",".MYI",".MYD", ".db", ".BAK", NullS};
+const char *del_exts[]= {".frm", ".BAK", ".TMD", NullS};
static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts};
+const char *known_exts[]=
+{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db",NullS};
+static TYPELIB known_extentions=
+{array_elements(known_exts)-1,"known_exts", known_exts};
-/* db-name is already validated when we come here */
+/*
+ Drop all tables in a database.
+
+ db-name is already validated when we come here
+ If thd == 0, do not write any messages; This is useful in replication
+ when we want to remove a stale database before replacing it with the new one
+*/
-void mysql_rm_db(THD *thd,char *db,bool if_exists)
+
+int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{
long deleted=0;
+ int error = 0;
char path[FN_REFLEN+16];
MY_DIR *dirp;
DBUG_ENTER("mysql_rm_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
- VOID(pthread_mutex_lock(&LOCK_open));
// do not drop database if another thread is holding read lock
- if (global_read_lock)
+ if (wait_if_global_read_lock(thd,0))
{
- if (thd->global_read_lock)
- {
- net_printf(&thd->net, ER_DROP_DB_WITH_READ_LOCK);
- goto exit;
- }
- while (global_read_lock && ! thd->killed)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
-
- if (thd->killed)
- {
- net_printf(&thd->net, ER_SERVER_SHUTDOWN);
- goto exit;
- }
+ error= -1;
+ goto exit2;
}
(void) sprintf(path,"%s/%s",mysql_data_home,db);
unpack_dirname(path,path); // Convert if not unix
/* See if the directory exists */
- if (!(dirp = my_dir(path,MYF(MY_WME | MY_DONT_SORT))))
+ if (!(dirp = my_dir(path,MYF(MY_DONT_SORT))))
{
if (!if_exists)
- net_printf(&thd->net,ER_DB_DROP_EXISTS,db);
- else
+ {
+ error= -1;
+ my_error(ER_DB_DROP_EXISTS,MYF(0),db);
+ }
+ else if (!silent)
send_ok(&thd->net,0);
goto exit;
}
remove_db_from_cache(db);
- if ((deleted=mysql_rm_known_files(thd, dirp, path,0)) >= 0)
+ error = -1;
+ if ((deleted=mysql_rm_known_files(thd, dirp, db, path,0)) >= 0 && thd)
{
- /*
- If there are running queries on the tables, MySQL needs to get
- access to LOCK_open to end them. InnoDB on the other hand waits
- for the queries to end before dropping the database. That is why we
- must do the dropping with LOCK_open released.
- */
- VOID(pthread_mutex_unlock(&LOCK_open));
ha_drop_database(path);
- VOID(pthread_mutex_lock(&LOCK_open));
-
- if (!thd->query)
+ query_cache_invalidate1(db);
+ if (!silent)
{
- thd->query = path;
- thd->query_length = (uint) (strxmov(path,"drop 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;
+ if (!thd->query)
+ {
+ thd->query = path;
+ thd->query_length = (uint) (strxmov(path,"drop 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,(ulong) deleted);
}
- send_ok(&thd->net,(ulong) deleted);
+ error = 0;
}
exit:
- VOID(pthread_mutex_unlock(&LOCK_open));
+ start_waiting_global_read_lock(thd);
+exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
/*
Removes files with known extensions plus all found subdirectories that
are 2 digits (raid directories).
+ thd MUST be set when calling this function!
*/
-static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
- uint level)
+static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
+ const char *org_path, uint level)
{
long deleted=0;
ulong found_other_files=0;
char filePath[FN_REFLEN];
+ TABLE_LIST *tot_list=0, **tot_list_next;
DBUG_ENTER("mysql_rm_known_files");
DBUG_PRINT("enter",("path: %s", org_path));
- /* remove all files with known extensions */
+
+ tot_list_next= &tot_list;
for (uint idx=2 ;
idx < (uint) dirp->number_off_files && !thd->killed ;
@@ -236,7 +228,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
{
DBUG_PRINT("my",("New subdir found: %s", newpath));
- if ((mysql_rm_known_files(thd,new_dirp,newpath,1)) < 0)
+ if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1)) < 0)
{
my_dirend(dirp);
DBUG_RETURN(-1);
@@ -246,27 +238,45 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
}
if (find_type(fn_ext(file->name),&deletable_extentions,1+2) <= 0)
{
- found_other_files++;
+ if (find_type(fn_ext(file->name),&known_extentions,1+2) <= 0)
+ found_other_files++;
continue;
}
strxmov(filePath,org_path,"/",file->name,NullS);
- unpack_filename(filePath,filePath);
- if (my_delete(filePath,MYF(MY_WME)))
+ if (db && !my_strcasecmp(fn_ext(file->name), reg_ext))
{
- net_printf(&thd->net,ER_DB_DROP_DELETE,filePath,my_error);
- my_dirend(dirp);
- DBUG_RETURN(-1);
+ /* Drop the table nicely */
+ *fn_ext(file->name)=0; // Remove extension
+ TABLE_LIST *table_list=(TABLE_LIST*)
+ thd->calloc(sizeof(*table_list)+ strlen(db)+strlen(file->name)+2);
+ if (!table_list)
+ {
+ my_dirend(dirp);
+ DBUG_RETURN(-1);
+ }
+ table_list->db= (char*) (table_list+1);
+ strmov(table_list->real_name=strmov(table_list->db,db)+1,
+ file->name);
+ /* Link into list */
+ (*tot_list_next)= table_list;
+ tot_list_next= &table_list->next;
}
- deleted++;
- }
+ else
+ {
+ if (my_delete_with_symlink(filePath,MYF(MY_WME)))
+ {
+ my_dirend(dirp);
+ DBUG_RETURN(-1);
+ }
+ deleted++;
+ }
+ }
my_dirend(dirp);
- if (thd->killed)
- {
- send_error(&thd->net,ER_SERVER_SHUTDOWN);
+ if (thd->killed ||
+ (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 1)))
DBUG_RETURN(-1);
- }
/*
If the directory is a symbolic link, remove the link first, then
@@ -278,7 +288,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
char *path=unpack_filename(tmp_path,org_path);
#ifdef HAVE_READLINK
int error;
-
+
/* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
pos=strend(path);
if (pos > path && pos[-1] == FN_LIBCHAR)
@@ -293,21 +303,21 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
/* Don't give errors if we can't delete 'RAID' directory */
if (level)
DBUG_RETURN(deleted);
- send_error(&thd->net);
DBUG_RETURN(-1);
}
/* Delete directory symbolic link pointed at */
path= filePath;
}
#endif
- /* Remove last FN_LIBCHAR to not cause a probelm on OS/2 */
+ /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
pos=strend(path);
+
if (pos > path && pos[-1] == FN_LIBCHAR)
*--pos=0;
/* Don't give errors if we can't delete 'RAID' directory */
if (rmdir(path) < 0 && !level)
{
- net_printf(&thd->net,ER_DB_DROP_RMDIR, path,errno);
+ my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
DBUG_RETURN(-1);
}
}
@@ -317,25 +327,27 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
bool mysql_change_db(THD *thd,const char *name)
{
- int length;
+ int length, db_length;
char *dbname=my_strdup((char*) name,MYF(MY_WME));
char path[FN_REFLEN];
uint db_access;
DBUG_ENTER("mysql_change_db");
- if (!dbname || !(length=strip_sp(dbname)))
+ 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 ((length > NAME_LEN) || check_db_name(dbname))
+ if ((db_length > NAME_LEN) || check_db_name(dbname))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, dbname);
x_free(dbname);
DBUG_RETURN(1);
}
- DBUG_PRINT("general",("Use database: %s", dbname));
+ if (lower_case_table_names)
+ casedn_str(dbname);
+ DBUG_PRINT("info",("Use database: %s", dbname));
if (test_all_bits(thd->master_access,DB_ACLS))
db_access=DB_ACLS;
else
@@ -346,11 +358,11 @@ bool mysql_change_db(THD *thd,const char *name)
{
net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
thd->priv_user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown",
+ thd->host_or_ip,
dbname);
mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
thd->priv_user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown",
+ thd->host_or_ip,
dbname);
my_free(dbname,MYF(0));
DBUG_RETURN(1);
@@ -369,6 +381,7 @@ bool mysql_change_db(THD *thd,const char *name)
send_ok(&thd->net);
x_free(thd->db);
thd->db=dbname;
+ thd->db_length=db_length;
thd->db_access=db_access;
DBUG_RETURN(0);
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 278e98533c9..8788a1576dc 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,118 +15,28 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Delete of records */
-
-#include "mysql_priv.h"
-#include "ha_innobase.h"
-
/*
- Optimize delete of all rows by doing a full generate of the table
- This will work even if the .ISM and .ISD tables are destroyed
+ Delete of records and truncate of tables.
+
+ Multi-table deletes were introduced by Monty and Sinisa
*/
-int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table)
-{
- char path[FN_REFLEN];
- int error;
- TABLE **table_ptr;
- DBUG_ENTER("generate_table");
- thd->proc_info="generate_table";
-
- if (global_read_lock)
- {
- if(thd->global_read_lock)
- {
- my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
- table_list->real_name);
- DBUG_RETURN(-1);
- }
- pthread_mutex_lock(&LOCK_open);
- while (global_read_lock && ! thd->killed ||
- thd->version != refresh_version)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
- pthread_mutex_unlock(&LOCK_open);
- }
-
- /* If it is a temporary table, close and regenerate it */
- if ((table_ptr=find_temporary_table(thd,table_list->db,
- table_list->real_name)))
- {
- TABLE *table= *table_ptr;
- HA_CREATE_INFO create_info;
- table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
- bzero((char*) &create_info,sizeof(create_info));
- create_info.auto_increment_value= table->file->auto_increment_value;
- db_type table_type=table->db_type;
-
- strmov(path,table->path);
- *table_ptr= table->next; // Unlink table from list
- close_temporary(table,0);
- *fn_ext(path)=0; // Remove the .frm extension
- ha_create_table(path, &create_info,1);
- if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
- table_list->real_name, 1))))
- {
- (void) rm_temporary_table(table_type, path);
- }
- }
- else
- {
- (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db,
- table_list->real_name,reg_ext);
- fn_format(path,path,"","",4);
- VOID(pthread_mutex_lock(&LOCK_open));
- if (locked_table)
- mysql_lock_abort(thd,locked_table); // end threads waiting on lock
- // close all copies in use
- if (remove_table_from_cache(thd,table_list->db,table_list->real_name))
- {
- if (!locked_table)
- {
- VOID(pthread_mutex_unlock(&LOCK_open));
- DBUG_RETURN(1); // We must get a lock on table
- }
- }
- if (locked_table)
- locked_table->file->extra(HA_EXTRA_FORCE_REOPEN);
- if (thd->locked_tables)
- close_data_tables(thd,table_list->db,table_list->real_name);
- else
- close_thread_tables(thd,1);
- HA_CREATE_INFO create_info;
- bzero((char*) &create_info,sizeof(create_info));
- *fn_ext(path)=0; // Remove the .frm extension
- error= ha_create_table(path,&create_info,1) ? -1 : 0;
- if (thd->locked_tables && reopen_tables(thd,1,0))
- error= -1;
- VOID(pthread_mutex_unlock(&LOCK_open));
- }
- if (!error)
- {
- 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);
- }
- send_ok(&thd->net); // This should return record count
- }
- DBUG_RETURN(error ? -1 : 0);
-}
+#include "mysql_priv.h"
+#include "ha_innodb.h"
+#include "sql_select.h"
-int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
- thr_lock_type lock_type, ulong options)
+int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
+ ha_rows limit, thr_lock_type lock_type, ulong options)
{
int error;
TABLE *table;
- SQL_SELECT *select;
+ SQL_SELECT *select=0;
READ_RECORD info;
- bool using_limit=limit != HA_POS_ERROR;
- bool use_generate_table,using_transactions;
+ bool using_limit=limit != HA_POS_ERROR;
+ bool using_transactions;
+ ha_rows deleted;
DBUG_ENTER("mysql_delete");
if (!table_list->db)
@@ -137,40 +47,39 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
DBUG_RETURN(1);
}
- use_generate_table= (!using_limit && !conds &&
- !(specialflag &
- (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
- !(thd->options &
- (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)));
-#ifdef HAVE_INNOBASE_DB
- /* We need to add code to not generate table based on the table type */
- if (!innodb_skip)
- use_generate_table=0; // Innodb can't use re-generate table
-#endif
- if (use_generate_table && ! thd->open_tables)
- {
- error=generate_table(thd,table_list,(TABLE*) 0);
- if (error <= 0)
- DBUG_RETURN(error); // Error or ok
- }
- if (!(table = open_ltable(thd,table_list,
- limit != HA_POS_ERROR ? TL_WRITE_LOW_PRIORITY :
- lock_type)))
+ if (!(table = open_ltable(thd,table_list, lock_type)))
DBUG_RETURN(-1);
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init";
- if (use_generate_table)
- DBUG_RETURN(generate_table(thd,table_list,table));
table->map=1;
if (setup_conds(thd,table_list,&conds) || setup_ftfuncs(thd))
DBUG_RETURN(-1);
+ /* Test if the user wants to delete all rows */
+ if (!using_limit && (!conds || conds->const_item()) &&
+ !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)))
+ {
+ deleted= table->file->records;
+ if (!(error=table->file->delete_all_rows()))
+ {
+ error= -1; // ok
+ goto cleanup;
+ }
+ if (error != HA_ERR_WRONG_COMMAND)
+ {
+ table->file->print_error(error,MYF(0));
+ error=0;
+ goto cleanup;
+ }
+ /* Handler didn't support fast delete; Delete rows one by one */
+ }
+
table->used_keys=table->quick_keys=0; // Can't use 'only index'
select=make_select(table,0,0,conds,&error);
if (error)
DBUG_RETURN(-1);
if ((select && select->check_quick(test(thd->options & OPTION_SAFE_UPDATES),
- limit)) ||
+ limit)) ||
!limit)
{
delete select;
@@ -181,7 +90,7 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
/* If running in safe sql mode, don't allow updates without keys */
if (!table->quick_keys)
{
- thd->lex.options|=QUERY_NO_INDEX_USED;
+ thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR)
{
delete select;
@@ -189,11 +98,37 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
DBUG_RETURN(1);
}
}
- (void) table->file->extra(HA_EXTRA_NO_READCHECK);
if (options & OPTION_QUICK)
(void) table->file->extra(HA_EXTRA_QUICK);
- init_read_record(&info,thd,table,select,-1,1);
- ulong deleted=0L;
+
+ if (order)
+ {
+ uint length;
+ SORT_FIELD *sortorder;
+ TABLE_LIST tables;
+ List<Item> fields;
+ List<Item> all_fields;
+ ha_rows examined_rows;
+
+ bzero((char*) &tables,sizeof(tables));
+ tables.table = table;
+
+ table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
+ MYF(MY_FAE | MY_ZEROFILL));
+ if (setup_order(thd, &tables, fields, all_fields, order) ||
+ !(sortorder=make_unireg_sortorder(order, &length)) ||
+ (table->found_records = filesort(table, sortorder, length,
+ (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
+ &examined_rows))
+ == HA_POS_ERROR)
+ {
+ delete select;
+ DBUG_RETURN(-1); // This will force out message
+ }
+ }
+
+ init_read_record(&info,thd,table,select,1,1);
+ deleted=0L;
init_ftfuncs(thd,1);
thd->proc_info="updating";
while (!(error=info.read_record(&info)) && !thd->killed)
@@ -221,9 +156,11 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
}
thd->proc_info="end";
end_read_record(&info);
- (void) table->file->extra(HA_EXTRA_READCHECK);
+ free_io_cache(table); // Will not do any harm
if (options & OPTION_QUICK)
(void) table->file->extra(HA_EXTRA_NORMAL);
+
+cleanup:
using_transactions=table->file->has_transactions();
if (deleted && (error <= 0 || !using_transactions))
{
@@ -239,6 +176,10 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
}
if (using_transactions && ha_autocommit_or_rollback(thd,error >= 0))
error=1;
+ if (deleted)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
@@ -255,3 +196,394 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
DBUG_RETURN(0);
}
+
+/***************************************************************************
+ Delete multiple tables from join
+***************************************************************************/
+
+#define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
+
+int refposcmp2(void* arg, const void *a,const void *b)
+{
+ return memcmp(a,b, *(int*) arg);
+}
+
+multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
+ thr_lock_type lock_option_arg,
+ uint num_of_tables_arg)
+ : delete_tables (dt), thd(thd_arg), deleted(0),
+ num_of_tables(num_of_tables_arg), error(0), lock_option(lock_option_arg),
+ do_delete(false)
+{
+ uint counter=0;
+ not_trans_safe=false;
+ tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
+
+ /* Don't use key read with MULTI-TABLE-DELETE */
+ dt->table->used_keys=0;
+ for (dt=dt->next ; dt ; dt=dt->next,counter++)
+ {
+ TABLE *table=dt->table;
+ table->used_keys=0;
+ tempfiles[counter] = new Unique (refposcmp2,
+ (void *) &table->file->ref_length,
+ table->file->ref_length,
+ MEM_STRIP_BUF_SIZE);
+ }
+}
+
+
+int
+multi_delete::prepare(List<Item> &values)
+{
+ DBUG_ENTER("multi_delete::prepare");
+ do_delete = true;
+ thd->proc_info="deleting from main table";
+
+ if (thd->options & OPTION_SAFE_UPDATES)
+ {
+ TABLE_LIST *table_ref;
+ for (table_ref=delete_tables; table_ref; table_ref=table_ref->next)
+ {
+ TABLE *table=table_ref->table;
+ if ((thd->options & OPTION_SAFE_UPDATES) && !table->quick_keys)
+ {
+ my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+void
+multi_delete::initialize_tables(JOIN *join)
+{
+ TABLE_LIST *walk;
+ table_map tables_to_delete_from=0;
+ for (walk= delete_tables ; walk ; walk=walk->next)
+ tables_to_delete_from|= walk->table->map;
+
+ walk= delete_tables;
+ for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
+ tab < end;
+ tab++)
+ {
+ if (tab->table->map & tables_to_delete_from)
+ {
+ /* We are going to delete from this table */
+ TABLE *tbl=walk->table=tab->table;
+ /* Don't use KEYREAD optimization on this table */
+ tbl->no_keyread=1;
+ walk=walk->next;
+ if (!not_trans_safe && !tbl->file->has_transactions())
+ not_trans_safe=true;
+ }
+ }
+ init_ftfuncs(thd,1);
+}
+
+
+multi_delete::~multi_delete()
+{
+ for (table_being_deleted=delete_tables ;
+ table_being_deleted ;
+ table_being_deleted=table_being_deleted->next)
+ {
+ TABLE *t=table_being_deleted->table;
+ free_io_cache(t); // Alloced by unique
+ t->no_keyread=0;
+ }
+
+ for (uint counter = 0; counter < num_of_tables-1; counter++)
+ {
+ if (tempfiles[counter])
+ delete tempfiles[counter];
+ }
+}
+
+
+bool multi_delete::send_data(List<Item> &values)
+{
+ int secure_counter= -1;
+ DBUG_ENTER("multi_delete::send_data");
+
+ for (table_being_deleted=delete_tables ;
+ table_being_deleted ;
+ table_being_deleted=table_being_deleted->next, secure_counter++)
+ {
+ TABLE *table=table_being_deleted->table;
+
+ /* Check if we are using outer join and we didn't find the row */
+ if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
+ continue;
+
+ table->file->position(table->record[0]);
+
+ if (secure_counter < 0)
+ {
+ /* If this is the table we are scanning */
+ table->status|= STATUS_DELETED;
+ if (!(error=table->file->delete_row(table->record[0])))
+ deleted++;
+ else
+ {
+ table->file->print_error(error,MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
+ if (error)
+ {
+ error=-1;
+ DBUG_RETURN(1);
+ }
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+void multi_delete::send_error(uint errcode,const char *err)
+{
+ DBUG_ENTER("multi_delete::send_error");
+
+ /* First send error what ever it is ... */
+ ::send_error(&thd->net,errcode,err);
+
+ /* If nothing deleted return */
+ if (!deleted)
+ DBUG_VOID_RETURN;
+
+ /* Something already deleted so we have to invalidate cache */
+ query_cache_invalidate3(thd, delete_tables, 1);
+
+ /* Below can happen when thread is killed early ... */
+ if (!table_being_deleted)
+ table_being_deleted=delete_tables;
+
+ /*
+ If rows from the first table only has been deleted and it is
+ transactional, just do rollback.
+ The same if all tables are transactional, regardless of where we are.
+ In all other cases do attempt deletes ...
+ */
+ if ((table_being_deleted->table->file->has_transactions() &&
+ table_being_deleted == delete_tables) || !not_trans_safe)
+ ha_rollback_stmt(thd);
+ else if (do_delete)
+ {
+ VOID(do_deletes(1));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Do delete from other tables.
+ Returns values:
+ 0 ok
+ 1 error
+*/
+
+int multi_delete::do_deletes(bool from_send_error)
+{
+ int error = 0, counter = 0;
+
+ if (from_send_error)
+ {
+ /* Found out table number for 'table_being_deleted' */
+ for (TABLE_LIST *aux=delete_tables;
+ aux != table_being_deleted;
+ aux=aux->next)
+ counter++;
+ }
+ else
+ table_being_deleted = delete_tables;
+
+ do_delete = false;
+ for (table_being_deleted=table_being_deleted->next;
+ table_being_deleted ;
+ table_being_deleted=table_being_deleted->next, counter++)
+ {
+ TABLE *table = table_being_deleted->table;
+ if (tempfiles[counter]->get(table))
+ {
+ error=1;
+ break;
+ }
+
+ READ_RECORD info;
+ init_read_record(&info,thd,table,NULL,0,0);
+ while (!(error=info.read_record(&info)) &&
+ (!thd->killed || from_send_error || not_trans_safe))
+ {
+ if ((error=table->file->delete_row(table->record[0])))
+ {
+ table->file->print_error(error,MYF(0));
+ break;
+ }
+ deleted++;
+ }
+ end_read_record(&info);
+ if (error == -1) // End of file
+ error = 0;
+ }
+ return error;
+}
+
+
+/*
+ Send ok to the client
+
+ return: 0 sucess
+ 1 error
+*/
+
+bool multi_delete::send_eof()
+{
+ thd->proc_info="deleting from reference tables";
+
+ /* Does deletes for the last n - 1 tables, returns 0 if ok */
+ int error = do_deletes(0); // returns 0 if success
+
+ /* reset used flags */
+ thd->proc_info="end";
+ if (error)
+ {
+ ::send_error(&thd->net);
+ return 1;
+ }
+
+ /*
+ Write the SQL statement to the binlog if we deleted
+ rows and we succeeded, or also in an error case when there
+ was a non-transaction-safe table involved, since
+ modifications in it cannot be rolled back.
+ */
+ if (deleted || not_trans_safe)
+ {
+ mysql_update_log.write(thd,thd->query,thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query);
+ if (mysql_bin_log.write(&qinfo) &&
+ !not_trans_safe)
+ error=1; // Log write failed: roll back the SQL statement
+ }
+ /* Commit or rollback the current SQL statement */
+ VOID(ha_autocommit_or_rollback(thd,error > 0));
+ }
+ if (deleted)
+ {
+ query_cache_invalidate3(thd, delete_tables, 1);
+ }
+ ::send_ok(&thd->net,deleted);
+ return 0;
+}
+
+
+/***************************************************************************
+ TRUNCATE TABLE
+****************************************************************************/
+
+/*
+ Optimize delete of all rows by doing a full generate of the table
+ This will work even if the .ISM and .ISD tables are destroyed
+
+ dont_send_ok should be set if:
+ - We should always wants to generate the table (even if the table type
+ normally can't safely do this.
+ - We don't want an ok to be sent to the end user.
+ - We don't want to log the truncate command
+ - If we want to have a name lock on the table on exit without errors.
+*/
+
+int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
+{
+ HA_CREATE_INFO create_info;
+ char path[FN_REFLEN];
+ TABLE **table_ptr;
+ int error;
+ DBUG_ENTER("mysql_truncate");
+
+ /* If it is a temporary table, close and regenerate it */
+ if (!dont_send_ok && (table_ptr=find_temporary_table(thd,table_list->db,
+ table_list->real_name)))
+ {
+ TABLE *table= *table_ptr;
+ HA_CREATE_INFO create_info;
+ table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
+ bzero((char*) &create_info,sizeof(create_info));
+ create_info.auto_increment_value= table->file->auto_increment_value;
+ db_type table_type=table->db_type;
+
+ strmov(path,table->path);
+ *table_ptr= table->next; // Unlink table from list
+ close_temporary(table,0);
+ *fn_ext(path)=0; // Remove the .frm extension
+ ha_create_table(path, &create_info,1);
+ // We don't need to call invalidate() because this table is not in cache
+ if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
+ table_list->real_name, 1))))
+ (void) rm_temporary_table(table_type, path);
+ /*
+ Sasha: if we return here we will not have binloged the truncation and
+ we will not send_ok() to the client.
+ */
+ goto end;
+ }
+
+ (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db,
+ table_list->real_name,reg_ext);
+ fn_format(path,path,"","",4);
+
+ if (!dont_send_ok)
+ {
+ db_type table_type;
+ if ((table_type=get_table_type(path)) == DB_TYPE_UNKNOWN)
+ {
+ my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->real_name);
+ DBUG_RETURN(-1);
+ }
+ if (!ha_supports_generate(table_type))
+ {
+ /* Probably InnoDB table */
+ DBUG_RETURN(mysql_delete(thd,table_list, (COND*) 0, (ORDER*) 0,
+ HA_POS_ERROR, TL_WRITE, 0));
+ }
+ if (lock_and_wait_for_table_name(thd, table_list))
+ DBUG_RETURN(-1);
+ }
+
+ bzero((char*) &create_info,sizeof(create_info));
+ *fn_ext(path)=0; // Remove the .frm extension
+ error= ha_create_table(path,&create_info,1) ? -1 : 0;
+ query_cache_invalidate3(thd, table_list, 0);
+end:
+ if (!dont_send_ok)
+ {
+ if (!error)
+ {
+ 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);
+ }
+ send_ok(&thd->net); // This should return record count
+ }
+ VOID(pthread_mutex_lock(&LOCK_open));
+ unlock_table_name(thd, table_list);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ }
+ else if (error)
+ {
+ VOID(pthread_mutex_lock(&LOCK_open));
+ unlock_table_name(thd, table_list);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ }
+ DBUG_RETURN(error ? -1 : 0);
+}
diff --git a/sql/sql_do.cc b/sql/sql_do.cc
index 57a6f88ed63..70124c2d796 100644
--- a/sql/sql_do.cc
+++ b/sql/sql_do.cc
@@ -25,7 +25,7 @@ int mysql_do(THD *thd, List<Item> &values)
List_iterator<Item> li(values);
Item *value;
DBUG_ENTER("mysql_do");
- if (setup_fields(thd,0, values, 0, 0))
+ if (setup_fields(thd,0, values, 0, 0, 0))
DBUG_RETURN(-1);
while ((value = li++))
value->val_int();
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
new file mode 100644
index 00000000000..27d5d431750
--- /dev/null
+++ b/sql/sql_handler.cc
@@ -0,0 +1,278 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* HANDLER ... commands - direct access to ISAM */
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+#include <assert.h>
+
+/* TODO:
+ HANDLER blabla OPEN [ AS foobar ] [ (column-list) ]
+
+ the most natural (easiest, fastest) way to do it is to
+ compute List<Item> field_list not in mysql_ha_read
+ but in mysql_ha_open, and then store it in TABLE structure.
+
+ The problem here is that mysql_parse calls free_item to free all the
+ items allocated at the end of every query. The workaround would to
+ keep two item lists per THD - normal free_list and handler_items.
+ The second is to be freeed only on thread end. mysql_ha_open should
+ then do { handler_items=concat(handler_items, free_list); free_list=0; }
+
+ But !!! do_cammand calls free_root at the end of every query and frees up
+ all the sql_alloc'ed memory. It's harder to work around...
+ */
+
+#define HANDLER_TABLES_HACK(thd) { \
+ TABLE *tmp=thd->open_tables; \
+ thd->open_tables=thd->handler_tables; \
+ thd->handler_tables=tmp; }
+
+static TABLE **find_table_ptr_by_name(THD *thd, const char *db,
+ const char *table_name);
+
+int mysql_ha_open(THD *thd, TABLE_LIST *tables)
+{
+ HANDLER_TABLES_HACK(thd);
+ int err=open_tables(thd,tables);
+ HANDLER_TABLES_HACK(thd);
+ if (err)
+ return -1;
+
+ // there can be only one table in *tables
+ if (!(tables->table->file->table_flags() & HA_CAN_SQL_HANDLER))
+ {
+ my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->name);
+ mysql_ha_close(thd, tables,1);
+ return -1;
+ }
+
+ send_ok(&thd->net);
+ return 0;
+}
+
+int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok)
+{
+ TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->name);
+
+ if (*ptr)
+ {
+ VOID(pthread_mutex_lock(&LOCK_open));
+ close_thread_table(thd, ptr);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ }
+ else
+ {
+ my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),
+ tables->name,"HANDLER");
+ return -1;
+ }
+ if (!dont_send_ok)
+ send_ok(&thd->net);
+ return 0;
+}
+
+static enum enum_ha_read_modes rkey_to_rnext[]=
+ { RNEXT, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV };
+
+
+int mysql_ha_read(THD *thd, TABLE_LIST *tables,
+ enum enum_ha_read_modes mode, char *keyname, List<Item> *key_expr,
+ enum ha_rkey_function ha_rkey_mode, Item *cond,
+ ha_rows select_limit,ha_rows offset_limit)
+{
+ int err, keyno=-1;
+ TABLE *table=*find_table_ptr_by_name(thd, tables->db, tables->name);
+ if (!table)
+ {
+ my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),
+ tables->name,"HANDLER");
+ return -1;
+ }
+ tables->table=table;
+
+ if (cond && cond->fix_fields(thd,tables))
+ return -1;
+
+ if (keyname)
+ {
+ if ((keyno=find_type(keyname, &table->keynames, 1+2)-1)<0)
+ {
+ my_printf_error(ER_KEY_DOES_NOT_EXITS,ER(ER_KEY_DOES_NOT_EXITS),MYF(0),
+ keyname,tables->name);
+ return -1;
+ }
+ }
+
+ List<Item> list;
+ list.push_front(new Item_field(NULL,NULL,"*"));
+ List_iterator<Item> it(list);
+ uint num_rows;
+ it++;
+
+ insert_fields(thd,tables,tables->db,tables->name,&it);
+
+ table->file->index_init(keyno);
+
+ select_limit+=offset_limit;
+ send_fields(thd,list,1);
+
+ HANDLER_TABLES_HACK(thd);
+ MYSQL_LOCK *lock=mysql_lock_tables(thd,&tables->table,1);
+ HANDLER_TABLES_HACK(thd);
+ if (!lock)
+ goto err0; // mysql_lock_tables() printed error message already
+
+ for (num_rows=0; num_rows < select_limit; )
+ {
+ switch(mode) {
+ case RFIRST:
+ err=keyname ?
+ table->file->index_first(table->record[0]) :
+ table->file->rnd_init(1) ||
+ table->file->rnd_next(table->record[0]);
+ mode=RNEXT;
+ break;
+ case RLAST:
+ DBUG_ASSERT(keyname != 0);
+ err=table->file->index_last(table->record[0]);
+ mode=RPREV;
+ break;
+ case RNEXT:
+ err=keyname ?
+ table->file->index_next(table->record[0]) :
+ table->file->rnd_next(table->record[0]);
+ break;
+ case RPREV:
+ DBUG_ASSERT(keyname != 0);
+ err=table->file->index_prev(table->record[0]);
+ break;
+ case RKEY:
+ {
+ DBUG_ASSERT(keyname != 0);
+ KEY *keyinfo=table->key_info+keyno;
+ KEY_PART_INFO *key_part=keyinfo->key_part;
+ uint key_len;
+ byte *key;
+ if (key_expr->elements > keyinfo->key_parts)
+ {
+ my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS),
+ MYF(0),keyinfo->key_parts);
+ goto err;
+ }
+ List_iterator_fast<Item> it_ke(*key_expr);
+ Item *item;
+ for (key_len=0 ; (item=it_ke++) ; key_part++)
+ {
+ item->save_in_field(key_part->field);
+ key_len+=key_part->store_length;
+ }
+ if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len))))
+ {
+ send_error(&thd->net,ER_OUTOFMEMORY);
+ goto err;
+ }
+ key_copy(key, table, keyno, key_len);
+ err=table->file->index_read(table->record[0],
+ key,key_len,ha_rkey_mode);
+ mode=rkey_to_rnext[(int)ha_rkey_mode];
+ break;
+ }
+ default:
+ send_error(&thd->net,ER_ILLEGAL_HA);
+ goto err;
+ }
+
+ if (err)
+ {
+ if (err != HA_ERR_KEY_NOT_FOUND && err != HA_ERR_END_OF_FILE)
+ {
+ sql_print_error("mysql_ha_read: Got error %d when reading table",
+ err);
+ table->file->print_error(err,MYF(0));
+ goto err;
+ }
+ goto ok;
+ }
+ if (cond)
+ {
+ err=err;
+ if (!cond->val_int())
+ continue;
+ }
+ if (num_rows>=offset_limit)
+ {
+ if (!err)
+ {
+ String *packet = &thd->packet;
+ Item *item;
+ packet->length(0);
+ it.rewind();
+ while ((item=it++))
+ {
+ if (item->send(thd,packet))
+ {
+ packet->free(); // Free used
+ my_error(ER_OUT_OF_RESOURCES,MYF(0));
+ goto err;
+ }
+ }
+ my_net_write(&thd->net, (char*)packet->ptr(), packet->length());
+ }
+ }
+ num_rows++;
+ }
+ok:
+ mysql_unlock_tables(thd,lock);
+ send_eof(&thd->net);
+ return 0;
+err:
+ mysql_unlock_tables(thd,lock);
+err0:
+ return -1;
+}
+
+/**************************************************************************
+ 2Monty: It could easily happen, that the following service functions are
+ already defined somewhere in the code, but I failed to find them.
+ If this is the case, just say a word and I'll use old functions here.
+**************************************************************************/
+
+/* Note: this function differs from find_locked_table() because we're looking
+ here for alias, not real table name
+ */
+static TABLE **find_table_ptr_by_name(THD *thd, const char *db,
+ const char *table_name)
+{
+ int dblen;
+ TABLE **ptr;
+
+ if (!db || ! *db)
+ db= thd->db ? thd->db : "";
+ dblen=strlen(db)+1;
+ ptr=&(thd->handler_tables);
+
+ for (TABLE *table=*ptr; table ; table=*ptr)
+ {
+ if (!memcmp(table->table_cache_key, db, dblen) &&
+ !my_strcasecmp(table->table_name,table_name))
+ break;
+ ptr=&(table->next);
+ }
+ return ptr;
+}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 18100996f52..053e96c5fdd 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -60,7 +60,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
if (grant_option &&
check_grant_all_columns(thd,INSERT_ACL,table))
return -1;
- table->time_stamp=0; // This should be saved
+ table->time_stamp=0; // This is saved by caller
}
else
{ // Part field list
@@ -73,12 +73,14 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
}
TABLE_LIST table_list;
bzero((char*) &table_list,sizeof(table_list));
+ table_list.db= table->table_cache_key;
table_list.name=table->table_name;
table_list.table=table;
table_list.grant=table->grant;
thd->dupp_field=0;
- if (setup_tables(&table_list) || setup_fields(thd,&table_list,fields,1,0))
+ if (setup_tables(&table_list) ||
+ setup_fields(thd,&table_list,fields,1,0,0))
return -1;
if (thd->dupp_field)
{
@@ -101,15 +103,15 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
{
int error;
bool log_on= ((thd->options & OPTION_UPDATE_LOG) ||
- !(thd->master_access & PROCESS_ACL));
- bool using_transactions;
+ !(thd->master_access & SUPER_ACL));
+ bool using_transactions, bulk_insert=0;
uint value_count;
uint save_time_stamp;
ulong counter = 1;
ulonglong id;
COPY_INFO info;
TABLE *table;
- List_iterator<List_item> its(values_list);
+ List_iterator_fast<List_item> its(values_list);
List_item *values;
char *query=thd->query;
DBUG_ENTER("mysql_insert");
@@ -151,7 +153,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
save_time_stamp=table->time_stamp;
values= its++;
if (check_insert_fields(thd,table,fields,*values,1) ||
- setup_tables(table_list) || setup_fields(thd,table_list,*values,0,0))
+ setup_tables(table_list) || setup_fields(thd,table_list,*values,0,0,0))
{
table->time_stamp=save_time_stamp;
goto abort;
@@ -168,7 +170,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
table->time_stamp=save_time_stamp;
goto abort;
}
- if (setup_fields(thd,table_list,*values,0,0))
+ if (setup_fields(thd,table_list,*values,0,0,0))
{
table->time_stamp=save_time_stamp;
goto abort;
@@ -176,7 +178,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
}
its.rewind ();
/*
- ** Fill in the given fields and dump it to the table file
+ Fill in the given fields and dump it to the table file
*/
info.records=info.deleted=info.copied=0;
@@ -192,7 +194,17 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
thd->proc_info="update";
if (duplic == DUP_IGNORE || duplic == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- while ((values = its++))
+ if ((bulk_insert= (values_list.elements > 1 &&
+ lock_type != TL_WRITE_DELAYED &&
+ !(specialflag & SPECIAL_SAFE_MODE))))
+ {
+ table->file->extra_opt(HA_EXTRA_WRITE_CACHE,
+ thd->variables.read_buff_size);
+ table->file->extra_opt(HA_EXTRA_BULK_INSERT_BEGIN,
+ thd->variables.bulk_insert_buff_size);
+ }
+
+ while ((values= its++))
{
if (fields.elements || !value_count)
{
@@ -253,9 +265,32 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
info.copied=values_list.elements;
end_delayed_insert(thd);
}
+ if (info.copied || info.deleted)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
}
else
{
+ if (bulk_insert)
+ {
+ if (table->file->extra(HA_EXTRA_NO_CACHE))
+ {
+ if (!error)
+ {
+ table->file->print_error(my_errno,MYF(0));
+ error=1;
+ }
+ }
+ if (table->file->extra(HA_EXTRA_BULK_INSERT_END))
+ {
+ if (!error)
+ {
+ table->file->print_error(my_errno,MYF(0));
+ error=1;
+ }
+ }
+ }
if (id && values_list.elements != 1)
thd->insert_id(id); // For update log
else if (table->next_number_field)
@@ -275,6 +310,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
}
if (using_transactions)
error=ha_autocommit_or_rollback(thd,error);
+ if (info.copied || info.deleted)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
@@ -288,7 +327,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
thd->next_insert_id=0; // Reset this if wrongly used
if (duplic == DUP_IGNORE || duplic == DUP_REPLACE)
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
-
if (error)
goto abort;
@@ -329,7 +367,7 @@ static int last_uniq_key(TABLE *table,uint keynr)
/*
-** Write a record to table with optional deleting of conflicting records
+ Write a record to table with optional deleting of conflicting records
*/
@@ -337,18 +375,18 @@ int write_record(TABLE *table,COPY_INFO *info)
{
int error;
char *key=0;
-
+
info->records++;
if (info->handle_duplicates == DUP_REPLACE)
{
while ((error=table->file->write_row(table->record[0])))
{
- if (error != HA_WRITE_SKIPP)
+ if (error != HA_WRITE_SKIP)
goto err;
uint key_nr;
if ((int) (key_nr = table->file->get_dup_key(error)) < 0)
{
- error=HA_WRITE_SKIPP; /* Database can't find key */
+ error=HA_WRITE_SKIP; /* Database can't find key */
goto err;
}
/*
@@ -359,19 +397,19 @@ int write_record(TABLE *table,COPY_INFO *info)
if (table->next_number_field && key_nr == table->next_number_index &&
table->file->auto_increment_column_changed)
goto err;
- if (table->file->option_flag() & HA_DUPP_POS)
+ if (table->file->table_flags() & HA_DUPP_POS)
{
if (table->file->rnd_pos(table->record[1],table->file->dupp_ref))
goto err;
}
else
{
- if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not neaded with NISAM */
+ if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */
{
error=my_errno;
goto err;
}
-
+
if (!key)
{
if (!(key=(char*) my_safe_alloca(table->max_unique_length,
@@ -416,15 +454,16 @@ int write_record(TABLE *table,COPY_INFO *info)
err:
if (key)
my_afree(key);
+ info->last_errno= error;
table->file->print_error(error,MYF(0));
return 1;
}
/******************************************************************************
- Check that all fields with arn't null_fields are used
- if DONT_USE_DEFAULT_FIELDS isn't defined use default value for not
- set fields.
+ Check that all fields with arn't null_fields are used
+ If DONT_USE_DEFAULT_FIELDS isn't defined use default value for not set
+ fields.
******************************************************************************/
static int check_null_fields(THD *thd __attribute__((unused)),
@@ -447,10 +486,8 @@ static int check_null_fields(THD *thd __attribute__((unused)),
}
/*****************************************************************************
-** Handling of delayed inserts
-**
-** A thread is created for each table that one uses with the DELAYED
-** attribute.
+ Handling of delayed inserts
+ A thread is created for each table that one uses with the DELAYED attribute.
*****************************************************************************/
class delayed_row :public ilink {
@@ -509,7 +546,7 @@ public:
}
~delayed_insert()
{
- /* The following is not really neaded, but just for safety */
+ /* The following is not really needed, but just for safety */
delayed_row *row;
while ((row=rows.get()))
delete row;
@@ -648,7 +685,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
/* Copy error message and abort */
thd->fatal_error=1;
strmov(thd->net.last_error,tmp->thd.net.last_error);
- thd->net.last_errno=thd->net.last_errno;
+ thd->net.last_errno=tmp->thd.net.last_errno;
}
tmp->unlock();
pthread_mutex_unlock(&LOCK_delayed_create);
@@ -712,9 +749,9 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
}
client_thd->proc_info="allocating local table";
- copy= (TABLE*) sql_alloc(sizeof(*copy)+
- (table->fields+1)*sizeof(Field**)+
- table->reclength);
+ copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
+ (table->fields+1)*sizeof(Field**)+
+ table->reclength);
if (!copy)
goto error;
*copy= *table;
@@ -732,7 +769,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
found_next_number_field=table->found_next_number_field;
for (org_field=table->field ; *org_field ; org_field++,field++)
{
- if (!(*field= (*org_field)->new_field(copy)))
+ if (!(*field= (*org_field)->new_field(&client_thd->mem_root,copy)))
return 0;
(*field)->move_field(adjust_ptrs); // Point at copy->record[0]
if (*org_field == found_next_number_field)
@@ -897,9 +934,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
#endif
DBUG_ENTER("handle_delayed_insert");
- if (init_thr_lock() ||
- my_pthread_setspecific_ptr(THR_THD, thd) ||
- my_pthread_setspecific_ptr(THR_NET, &thd->net))
+ if (init_thr_lock() || thd->store_globals())
{
thd->fatal_error=1;
strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
@@ -961,23 +996,12 @@ static pthread_handler_decl(handle_delayed_insert,arg)
if (!di->status && !di->stacked_inserts)
{
struct timespec abstime;
-#if defined(HAVE_TIMESPEC_TS_SEC)
- abstime.ts_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout;
- abstime.ts_nsec=0;
-#elif defined(__WIN__)
- abstime.tv_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout;
- abstime.tv_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+(time_t) delayed_insert_timeout;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
+ set_timespec(abstime, delayed_insert_timeout);
/* Information for pthread_kill */
di->thd.mysys_var->current_mutex= &di->mutex;
di->thd.mysys_var->current_cond= &di->cond;
- di->thd.proc_info=0;
+ di->thd.proc_info="Waiting for INSERT";
DBUG_PRINT("info",("Waiting for someone to insert rows"));
while (!thd->killed)
@@ -1012,6 +1036,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
pthread_mutex_lock(&di->mutex);
}
+ di->thd.proc_info=0;
if (di->tables_in_use && ! thd->lock)
{
@@ -1157,7 +1182,7 @@ bool delayed_insert::handle_inserts(void)
thd.net.last_errno = 0; // reset error for binlog
if (write_record(table,&info))
{
- info.error++; // Ignore errors
+ info.error_count++; // Ignore errors
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
row->log_query = 0;
}
@@ -1200,6 +1225,7 @@ bool delayed_insert::handle_inserts(void)
sql_print_error("%s",thd.net.last_error);
goto err;
}
+ query_cache_invalidate3(&thd, table, 1);
if (thr_reschedule_write_lock(*thd.lock->locks))
{
/* This should never happen */
@@ -1224,6 +1250,7 @@ bool delayed_insert::handle_inserts(void)
sql_print_error("%s",thd.net.last_error);
goto err;
}
+ query_cache_invalidate3(&thd, table, 1);
pthread_mutex_lock(&mutex);
DBUG_RETURN(0);
@@ -1243,7 +1270,7 @@ bool delayed_insert::handle_inserts(void)
/***************************************************************************
-** store records in INSERT ... SELECT *
+ Store records in INSERT ... SELECT *
***************************************************************************/
int
@@ -1257,7 +1284,7 @@ select_insert::prepare(List<Item> &values)
restore_record(table,2); // Get empty record
table->next_number_field=table->found_next_number_field;
- thd->count_cuted_fields=1; /* calc cuted fields */
+ thd->count_cuted_fields=1; // calc cuted fields
thd->cuted_fields=0;
if (info.handle_duplicates != DUP_REPLACE)
table->file->extra(HA_EXTRA_WRITE_CACHE);
@@ -1309,7 +1336,11 @@ void select_insert::send_error(uint errcode,const char *err)
::send_error(&thd->net,errcode,err);
table->file->extra(HA_EXTRA_NO_CACHE);
table->file->activate_all_index(thd);
- ha_rollback(thd);
+ ha_rollback_stmt(thd);
+ if (info.copied || info.deleted)
+ {
+ query_cache_invalidate3(thd, table, 1);
+ }
}
@@ -1321,7 +1352,10 @@ bool select_insert::send_eof()
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
error=error2;
-
+ if (info.copied || info.deleted)
+ {
+ query_cache_invalidate3(thd, table, 1);
+ }
if (error)
{
table->file->print_error(error,MYF(0));
@@ -1353,7 +1387,7 @@ bool select_insert::send_eof()
/***************************************************************************
-** CREATE TABLE (SELECT) ...
+ CREATE TABLE (SELECT) ...
***************************************************************************/
int
@@ -1409,6 +1443,7 @@ bool select_create::send_data(List<Item> &values)
extern HASH open_cache;
+
bool select_create::send_eof()
{
bool tmp=select_insert::send_eof();
@@ -1421,7 +1456,8 @@ bool select_create::send_eof()
mysql_unlock_tables(thd, lock);
if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table);
- lock=0; table=0;
+ lock=0;
+ table=0;
VOID(pthread_mutex_unlock(&LOCK_open));
}
return tmp;
@@ -1449,11 +1485,11 @@ void select_create::abort()
/*****************************************************************************
-** Instansiate templates
+ Instansiate templates
*****************************************************************************/
#ifdef __GNUC__
-template class List_iterator<List_item>;
+template class List_iterator_fast<List_item>;
template class I_List<delayed_insert>;
template class I_List_iterator<delayed_insert>;
template class I_List<delayed_row>;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index a3c3db8947e..9a6eb05ac5d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -142,20 +142,23 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->next_state=STATE_START;
lex->end_of_query=(lex->ptr=buf)+length;
lex->yylineno = 1;
- lex->create_refs=lex->in_comment=0;
+ lex->select->create_refs=lex->in_comment=0;
lex->length=0;
- lex->in_sum_expr=0;
- lex->expr_list.empty();
- lex->ftfunc_list.empty();
- lex->convert_set=thd->convert_set;
+ lex->select->in_sum_expr=0;
+ lex->select->expr_list.empty();
+ lex->select->ftfunc_list.empty();
+ lex->convert_set=(lex->thd=thd)->variables.convert_set;
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE);
+ lex->slave_thd_opt=0;
+ lex->sql_command=SQLCOM_END;
+ bzero(&lex->mi,sizeof(lex->mi));
return lex;
}
void lex_end(LEX *lex)
{
- lex->expr_list.delete_elements(); // If error when parsing sql-varargs
+ lex->select->expr_list.delete_elements(); // If error when parsing sql-varargs
x_free(lex->yacc_yyss);
x_free(lex->yacc_yyvs);
}
@@ -196,12 +199,12 @@ static int find_keyword(LEX *lex, uint len, bool function)
/* make a copy of token before ptr and set yytoklen */
-static inline LEX_STRING get_token(LEX *lex,uint length)
+LEX_STRING get_token(LEX *lex,uint length)
{
LEX_STRING tmp;
yyUnget(); // ptr points now after last token char
tmp.length=lex->yytoklen=length;
- tmp.str=(char*) sql_strmake((char*) lex->tok_start,tmp.length);
+ tmp.str=(char*) lex->thd->strmake((char*) lex->tok_start,tmp.length);
return tmp;
}
@@ -250,7 +253,7 @@ static char *get_text(LEX *lex)
str=lex->tok_start+1;
end=lex->ptr-1;
- if (!(start=(uchar*) sql_alloc((uint) (end-str)+1)))
+ if (!(start=(uchar*) lex->thd->alloc((uint) (end-str)+1)))
return (char*) ""; // Sql_alloc has set error flag
if (!found_escape)
{
@@ -337,7 +340,8 @@ static const char *longlong_str="9223372036854775807";
static const uint longlong_len=19;
static const char *signed_longlong_str="-9223372036854775808";
static const uint signed_longlong_len=19;
-
+static const char *unsigned_longlong_str="18446744073709551615";
+static const uint unsigned_longlong_len=20;
inline static uint int_token(const char *str,uint length)
{
@@ -393,7 +397,13 @@ inline static uint int_token(const char *str,uint length)
else if (length < longlong_len)
return LONG_NUM;
else if (length > longlong_len)
- return REAL_NUM;
+ {
+ if (length > unsigned_longlong_len)
+ return REAL_NUM;
+ cmp=unsigned_longlong_str;
+ smaller=ULONGLONG_NUM;
+ bigger=REAL_NUM;
+ }
else
{
cmp=longlong_str;
@@ -430,7 +440,7 @@ int yylex(void *arg)
switch(state) {
case STATE_OPERATOR_OR_IDENT: // Next is operator or keyword
case STATE_START: // Start of token
- // Skipp startspace
+ // Skip startspace
for (c=yyGet() ; (state_map[c] == STATE_SKIP) ; c= yyGet())
{
if (c == '\n')
@@ -458,6 +468,11 @@ int yylex(void *arg)
return((int) c);
case STATE_IDENT: // Incomplete keyword or ident
+ if ((c == 'x' || c == 'X') && yyPeek() == '\'')
+ { // Found x'hex-number'
+ state=STATE_HEX_NUMBER;
+ break;
+ }
#if defined(USE_MB) && defined(USE_MB_IDENT)
if (use_mb(default_charset_info))
{
@@ -493,7 +508,7 @@ int yylex(void *arg)
length= (uint) (lex->ptr - lex->tok_start)-1;
if (lex->ignore_space)
{
- for ( ; state_map[c] == STATE_SKIP ; c= yyGet());
+ for (; state_map[c] == STATE_SKIP ; c= yyGet());
}
if (c == '.' && (state_map[yyPeek()] == STATE_IDENT ||
state_map[yyPeek()] == STATE_NUMBER_IDENT))
@@ -509,6 +524,8 @@ int yylex(void *arg)
yySkip(); // next state does a unget
}
yylval->lex_str=get_token(lex,length);
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(IDENT);
case STATE_IDENT_SEP: // Found ident and now '.'
@@ -518,7 +535,7 @@ int yylex(void *arg)
c=yyGet(); // should be '.'
return((int) c);
- case STATE_NUMBER_IDENT: // number or ident which starts with num
+ case STATE_NUMBER_IDENT: // number or ident which num-start
while (isdigit((c = yyGet()))) ;
if (state_map[c] != STATE_IDENT)
{ // Can't be identifier
@@ -544,10 +561,10 @@ int yylex(void *arg)
lex->tok_start[0] == '0' )
{ // Varbinary
while (isxdigit((c = yyGet()))) ;
- if ((lex->ptr - lex->tok_start) >= 4)
+ if ((lex->ptr - lex->tok_start) >= 4 && state_map[c] != STATE_IDENT)
{
yylval->lex_str=get_token(lex,yyLength());
- yylval->lex_str.str+=2; // Skipp 0x
+ yylval->lex_str.str+=2; // Skip 0x
yylval->lex_str.length-=2;
lex->yytoklen-=2;
return (HEX_NUM);
@@ -597,10 +614,12 @@ int yylex(void *arg)
case STATE_FOUND_IDENT: // Complete ident
yylval->lex_str=get_token(lex,yyLength());
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(IDENT);
case STATE_USER_VARIABLE_DELIMITER:
- lex->tok_start=lex->ptr; // Skipp first `
+ lex->tok_start=lex->ptr; // Skip first `
#ifdef USE_MB
if (use_mb(default_charset_info))
{
@@ -625,14 +644,17 @@ int yylex(void *arg)
c != (uchar) NAMES_SEP_CHAR) ;
}
yylval->lex_str=get_token(lex,yyLength());
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
if (state_map[c] == STATE_USER_VARIABLE_DELIMITER)
- yySkip(); // Skipp end `
+ yySkip(); // Skip end `
return(IDENT);
case STATE_SIGNED_NUMBER: // Incomplete signed number
if (prev_state == STATE_OPERATOR_OR_IDENT)
{
- if (c == '-' && yyPeek() == '-' && isspace(yyPeek2()))
+ if (c == '-' && yyPeek() == '-' &&
+ (isspace(yyPeek2()) || iscntrl(yyPeek2())))
state=STATE_COMMENT;
else
state= STATE_CHAR; // Must be operator
@@ -672,7 +694,7 @@ int yylex(void *arg)
{
c = yyGet();
if (c == '-' || c == '+')
- c = yyGet(); // Skipp sign
+ c = yyGet(); // Skip sign
if (!isdigit(c))
{ // No digit after sign
state= STATE_CHAR;
@@ -685,6 +707,21 @@ int yylex(void *arg)
yylval->lex_str=get_token(lex,yyLength());
return(REAL_NUM);
+ case STATE_HEX_NUMBER: // Found x'hexstring'
+ yyGet(); // Skip '
+ while (isxdigit((c = yyGet()))) ;
+ length=(lex->ptr - lex->tok_start); // Length of hexnum+3
+ if (!(length & 1) || c != '\'')
+ {
+ return(ABORT_SYM); // Illegal hex constant
+ }
+ yyGet(); // get_token makes an unget
+ yylval->lex_str=get_token(lex,length);
+ yylval->lex_str.str+=2; // Skip x'
+ yylval->lex_str.length-=3; // Don't count x' and last '
+ lex->yytoklen-=3;
+ return (HEX_NUM);
+
case STATE_CMP_OP: // Incomplete comparison operator
if (state_map[yyPeek()] == STATE_CMP_OP ||
state_map[yyPeek()] == STATE_LONG_CMP_OP)
@@ -734,7 +771,7 @@ int yylex(void *arg)
return(TEXT_STRING);
case STATE_COMMENT: // Comment
- lex->options|= OPTION_FOUND_COMMENT;
+ lex->select_lex.options|= OPTION_FOUND_COMMENT;
while ((c = yyGet()) != '\n' && c) ;
yyUnget(); // Safety against eof
state = STATE_START; // Try again
@@ -746,7 +783,7 @@ int yylex(void *arg)
break;
}
yySkip(); // Skip '*'
- lex->options|= OPTION_FOUND_COMMENT;
+ lex->select_lex.options|= OPTION_FOUND_COMMENT;
if (yyPeek() == '!') // MySQL command in comment
{
ulong version=MYSQL_VERSION_ID;
@@ -816,14 +853,12 @@ int yylex(void *arg)
}
break;
case STATE_USER_END: // end '@' of user@hostname
- switch (state_map[yyPeek()])
- {
+ switch (state_map[yyPeek()]) {
case STATE_STRING:
case STATE_USER_VARIABLE_DELIMITER:
break;
case STATE_USER_END:
- lex->next_state=STATE_USER_END;
- yySkip();
+ lex->next_state=STATE_SYSTEM_VAR;
break;
default:
lex->next_state=STATE_HOSTNAME;
@@ -838,6 +873,33 @@ int yylex(void *arg)
c= yyGet()) ;
yylval->lex_str=get_token(lex,yyLength());
return(LEX_HOSTNAME);
+ case STATE_SYSTEM_VAR:
+ yylval->lex_str.str=(char*) lex->ptr;
+ yylval->lex_str.length=1;
+ lex->next_state=STATE_IDENT_OR_KEYWORD;
+ yySkip(); // Skip '@'
+ return((int) '@');
+ case STATE_IDENT_OR_KEYWORD:
+ /*
+ We come here when we have found two '@' in a row.
+ We should now be able to handle:
+ [(global | local | session) .]variable_name
+ */
+
+ while (state_map[c=yyGet()] == STATE_IDENT ||
+ state_map[c] == STATE_NUMBER_IDENT) ;
+ if (c == '.')
+ lex->next_state=STATE_IDENT_SEP;
+ length= (uint) (lex->ptr - lex->tok_start)-1;
+ if ((tokval= find_keyword(lex,length,0)))
+ {
+ yyUnget(); // Put back 'c'
+ return(tokval); // Was keyword
+ }
+ yylval->lex_str=get_token(lex,length);
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
+ return(IDENT);
}
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 7d1df04b852..9be8703b6c5 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,8 +22,12 @@ class Table_ident;
class sql_exchange;
class LEX_COLUMN;
-// The following hack is neaded because mysql_yacc.cc does not define
-// YYSTYPE before including this file
+/*
+ The following hack is needed because mysql_yacc.cc does not define
+ YYSTYPE before including this file
+*/
+
+#include "set_var.h"
#ifdef MYSQL_YACC
#define LEX_YYSTYPE void *
@@ -54,99 +58,127 @@ enum enum_sql_command {
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS,
- SQLCOM_SHOW_OPEN_TABLES, SQLCOM_DO, SQLCOM_EMPTY_QUERY,
+ SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
+ SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
+ SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_MULTI_UPDATE,
+ SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO,
+ SQLCOM_EMPTY_QUERY,
SQLCOM_END
};
-enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
- STATE_IDENT_SEP,
- STATE_IDENT_START,
- STATE_FOUND_IDENT,
- STATE_SIGNED_NUMBER,
- STATE_REAL,
- STATE_CMP_OP,
- STATE_LONG_CMP_OP,
- STATE_STRING,
- STATE_COMMENT,
- STATE_END,
- STATE_OPERATOR_OR_IDENT,
- STATE_NUMBER_IDENT,
- STATE_INT_OR_REAL,
- STATE_REAL_OR_POINT,
- STATE_BOOL,
- STATE_EOL,
- STATE_ESCAPE,
- STATE_LONG_COMMENT,
- STATE_END_LONG_COMMENT,
- STATE_COLON,
- STATE_SET_VAR,
- STATE_USER_END,
- STATE_HOSTNAME,
- STATE_SKIP,
- STATE_USER_VARIABLE_DELIMITER
+enum lex_states
+{
+ STATE_START, STATE_CHAR, STATE_IDENT, STATE_IDENT_SEP, STATE_IDENT_START,
+ STATE_FOUND_IDENT, STATE_SIGNED_NUMBER, STATE_REAL, STATE_HEX_NUMBER,
+ STATE_CMP_OP, STATE_LONG_CMP_OP, STATE_STRING, STATE_COMMENT, STATE_END,
+ STATE_OPERATOR_OR_IDENT, STATE_NUMBER_IDENT, STATE_INT_OR_REAL,
+ STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
+ STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
+ STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR,
+ STATE_IDENT_OR_KEYWORD
};
typedef List<Item> List_item;
typedef struct st_lex_master_info
{
- char* host, *user, *password,*log_file_name;
+ char *host, *user, *password, *log_file_name;
uint port, connect_retry;
ulonglong pos;
+ ulong server_id;
+ char *relay_log_name;
+ ulong relay_log_pos;
} LEX_MASTER_INFO;
+
+enum sub_select_type
+{
+ UNSPECIFIED_TYPE, UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, OLAP_TYPE, NOT_A_SELECT
+};
+
+enum olap_type
+{
+ UNSPECIFIED_OLAP_TYPE, CUBE_TYPE, ROLLUP_TYPE
+};
+
+/* The state of the lex parsing for selects */
+
+typedef struct st_select_lex
+{
+ enum sub_select_type linkage;
+ enum olap_type olap;
+ char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
+ Item *where,*having;
+ ha_rows select_limit,offset_limit;
+ ulong options;
+ List<List_item> expr_list;
+ List<List_item> when_list;
+ SQL_LIST order_list,table_list,group_list;
+ List<Item> item_list;
+ List<String> interval_list,use_index, *use_index_ptr,
+ ignore_index, *ignore_index_ptr;
+ List<Item_func_match> ftfunc_list;
+ uint in_sum_expr, sort_default;
+ bool create_refs, braces;
+ st_select_lex *next;
+} SELECT_LEX;
+
+
/* The state of the lex parsing. This is saved in the THD struct */
-typedef struct st_lex {
+typedef struct st_lex
+{
uint yylineno,yytoklen; /* Simulate lex */
LEX_YYSTYPE yylval;
+ SELECT_LEX select_lex, *select, *last_selects;
uchar *ptr,*tok_start,*tok_end,*end_of_query;
char *length,*dec,*change,*name;
- char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
char *backup_dir; /* For RESTORE/BACKUP */
char* to_log; /* For PURGE MASTER LOGS TO */
+ char* x509_subject,*x509_issuer,*ssl_cipher;
+ enum SSL_type ssl_type; /* defined in violite.h */
String *wild;
sql_exchange *exchange;
- ha_rows select_limit,offset_limit;
- List<List_item> expr_list;
- List<List_item> when_list;
- List<List_item> many_values;
List<key_part_spec> col_list;
List<Alter_drop> drop_list;
List<Alter_column> alter_list;
- List<String> interval_list,use_index,*use_index_ptr,
- ignore_index, *ignore_index_ptr;
- List<st_lex_user> users_list;
+ List<String> interval_list;
+ List<LEX_USER> users_list;
List<LEX_COLUMN> columns;
List<Key> key_list;
List<create_field> create_list;
- List<Item> item_list,*insert_list,field_list,value_list;
- List<Item_func_match> ftfunc_list;
- SQL_LIST order_list,table_list,group_list,proc_list;
+ List<Item> *insert_list,field_list,value_list;
+ List<List_item> many_values;
+ List<set_var_base> var_list;
+ SQL_LIST proc_list, auxilliary_table_list;
TYPELIB *interval;
create_field *last_field;
-
- Item *where,*having,*default_value;
+ Item *default_value;
CONVERT *convert_set;
+ CONVERT *thd_convert_set; // Set with SET CHAR SET
LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs;
+ THD *thd;
udf_func udf;
HA_CHECK_OPT check_opt; // check/repair options
HA_CREATE_INFO create_info;
LEX_MASTER_INFO mi; // used by CHANGE MASTER
+ USER_RESOURCES mqh;
ulong thread_id,type;
- ulong options;
- ulong gemini_spin_retries;
enum_sql_command sql_command;
enum lex_states next_state;
enum enum_duplicates duplicates;
enum enum_tx_isolation tx_isolation;
- uint in_sum_expr,grant,grant_tot_col,which_columns;
+ enum enum_ha_read_modes ha_read_mode;
+ enum ha_rkey_function ha_rkey_mode;
+ enum enum_enable_or_disable alter_keys_onoff;
+ enum enum_var_type option_type;
+ uint grant,grant_tot_col,which_columns, union_option;
thr_lock_type lock_option;
- bool create_refs,drop_primary,drop_if_exists,local_file;
- bool in_comment,ignore_space,verbose;
-
+ bool drop_primary,drop_if_exists,local_file, olap;
+ bool in_comment,ignore_space,verbose,simple_alter;
+ uint slave_thd_opt;
} LEX;
diff --git a/sql/sql_list.cc b/sql/sql_list.cc
index 7d5fc442121..1124605ca24 100644
--- a/sql/sql_list.cc
+++ b/sql/sql_list.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,3 +20,5 @@
#endif
#include "mysql_priv.h"
+
+list_node end_of_list;
diff --git a/sql/sql_list.h b/sql/sql_list.h
index d21f2e658dc..542eef623f0 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -41,25 +41,40 @@ public:
/*
** basic single linked list
** Used for item and item_buffs.
+** All list ends with a pointer to the 'end_of_list' element, which
+** data pointer is a null pointer and the next pointer points to itself.
+** This makes it very fast to traverse lists as we don't have to
+** test for a specialend condition for list that can't contain a null
+** pointer.
*/
+class list_node :public Sql_alloc
+{
+public:
+ list_node *next;
+ void *info;
+ list_node(void *info_par,list_node *next_par)
+ :next(next_par),info(info_par)
+ {}
+ list_node() /* For end_of_list */
+ {
+ info=0;
+ next= this;
+ }
+ friend class base_list;
+ friend class base_list_iterator;
+};
+
+extern list_node end_of_list;
+
class base_list :public Sql_alloc {
protected:
- class list_node :public Sql_alloc
- {
- public:
- list_node *next;
- void *info;
- list_node(void *info_par,list_node *next_par) : next(next_par),info(info_par) {}
- friend class base_list;
- friend class base_list_iterator;
- };
list_node *first,**last;
public:
uint elements;
- inline void empty() { elements=0; first=0; last=&first;}
+ inline void empty() { elements=0; first= &end_of_list; last=&first;}
inline base_list() { empty(); }
inline base_list(const base_list &tmp) :Sql_alloc()
{
@@ -69,7 +84,7 @@ public:
}
inline bool push_back(void *info)
{
- if (((*last)=new list_node(info,0)))
+ if (((*last)=new list_node(info, &end_of_list)))
{
last= &(*last)->next;
elements++;
@@ -82,7 +97,7 @@ public:
list_node *node=new list_node(info,first);
if (node)
{
- if (!first)
+ if (last == &first)
last= &node->next;
first=node;
elements++;
@@ -96,22 +111,21 @@ public:
delete *prev;
*prev=node;
if (!--elements)
- {
last= &first;
- first=0;
- }
}
inline void *pop(void)
{
- if (!first) return 0;
+ if (first == &end_of_list) return 0;
list_node *tmp=first;
first=first->next;
if (!--elements)
last= &first;
return tmp->info;
}
- inline void *head() { return first ? first->info : 0; }
- inline void **head_ref() { return first ? &first->info : 0; }
+ inline void *head() { return first->info; }
+ inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
+ inline bool is_empty() { return first == &end_of_list ; }
+ inline list_node *last_ref() { return &end_of_list; }
friend class base_list_iterator;
protected:
@@ -129,7 +143,7 @@ protected:
class base_list_iterator
{
base_list *list;
- base_list::list_node **el,**prev,*current;
+ list_node **el,**prev,*current;
public:
base_list_iterator(base_list &list_par) :list(&list_par),el(&list_par.first),
prev(0),current(0)
@@ -137,16 +151,22 @@ public:
inline void *next(void)
{
prev=el;
- if (!(current= *el))
- return 0;
+ current= *el;
el= &current->next;
return current->info;
}
+ inline void *next_fast(void)
+ {
+ list_node *tmp;
+ tmp= *el;
+ el= &tmp->next;
+ return tmp->info;
+ }
inline void rewind(void)
{
el= &list->first;
}
- void *replace(void *element)
+ inline void *replace(void *element)
{ // Return old element
void *tmp=current->info;
current->info=element;
@@ -155,7 +175,7 @@ public:
void *replace(base_list &new_list)
{
void *ret_value=current->info;
- if (new_list.first)
+ if (!new_list.is_empty())
{
*new_list.last=current->next;
current->info=new_list.first->info;
@@ -182,7 +202,7 @@ public:
}
inline bool is_last(void)
{
- return *el == 0;
+ return el == &list->last_ref()->next;
}
};
@@ -200,7 +220,7 @@ public:
void delete_elements(void)
{
list_node *element,*next;
- for (element=first; element ; element=next)
+ for (element=first; element != &end_of_list; element=next)
{
next=element->next;
delete (T*) element->info;
@@ -215,18 +235,30 @@ template <class T> class List_iterator :public base_list_iterator
public:
List_iterator(List<T> &a) : base_list_iterator(a) {}
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
- inline void rewind(void) { base_list_iterator::rewind(); }
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
- inline void remove(void) { base_list_iterator::remove(); }
inline void after(T *a) { base_list_iterator::after(a); }
inline T** ref(void) { return (T**) base_list_iterator::ref(); }
- inline bool is_last(void) { return base_list_iterator::is_last(); }
+};
+
+template <class T> class List_iterator_fast :public base_list_iterator
+{
+protected:
+ inline T *replace(T *a) { return (T*) 0; }
+ inline T *replace(List<T> &a) { return (T*) 0; }
+ inline void remove(void) { }
+ inline void after(T *a) { }
+ inline T** ref(void) { return (T**) 0; }
+
+public:
+ List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
+ inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
+ inline void rewind(void) { base_list_iterator::rewind(); }
};
/*
-** An simple intrusive list with automaticly removes element from list
+** A simple intrusive list which automaticly removes element from list
** on delete (for THD element)
*/
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 1dcc8c2130e..e58c7493a0f 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,6 +20,7 @@
#include "mysql_priv.h"
#include <my_dir.h>
#include <m_ctype.h>
+#include "sql_repl.h"
class READ_INFO {
File file;
@@ -32,6 +33,7 @@ class READ_INFO {
int field_term_char,line_term_char,enclosed_char,escape_char;
int *stack,*stack_pos;
bool found_end_of_line,start_of_line,eof;
+ bool need_end_io_cache;
IO_CACHE cache;
NET *io_net;
@@ -50,6 +52,22 @@ public:
char unescape(char chr);
int terminator(char *ptr,uint length);
bool find_start_of_fields();
+ /*
+ We need to force cache close before destructor is invoked to log
+ the last read block
+ */
+ void end_io_cache()
+ {
+ ::end_io_cache(&cache);
+ need_end_io_cache = 0;
+ }
+
+ /*
+ Either this method, or we need to make cache public
+ Arg must be set from mysql_load() since constructor does not see
+ either the table or THD value
+ */
+ void set_io_cache_arg(void* arg) { cache.arg = arg; }
};
static int read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,
@@ -67,20 +85,24 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
File file;
TABLE *table;
int error;
- uint save_skip_lines = ex->skip_lines;
String *field_term=ex->field_term,*escaped=ex->escaped,
*enclosed=ex->enclosed;
bool is_fifo=0;
+ LOAD_FILE_INFO lf_info;
+ char * db = table_list->db ? table_list->db : thd->db;
bool using_transactions;
DBUG_ENTER("mysql_load");
+#ifdef EMBEDDED_LIBRARY
+ read_file_from_client = 0; //server is always in the same process
+#endif
+
if (escaped->length() > 1 || enclosed->length() > 1)
{
my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
MYF(0));
DBUG_RETURN(-1);
}
-
if (!(table = open_ltable(thd,table_list,lock_type)))
DBUG_RETURN(-1);
if (!fields.elements)
@@ -92,7 +114,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
{ // Part field list
thd->dupp_field=0;
- if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0))
+ if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0,0))
DBUG_RETURN(-1);
if (thd->dupp_field)
{
@@ -103,7 +125,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
uint tot_length=0;
bool use_blobs=0,use_timestamp=0;
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item_field *field;
while ((field=(Item_field*) it++))
@@ -133,12 +155,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (read_file_from_client)
{
- char tmp [FN_REFLEN+1],*end;
- DBUG_PRINT("info",("reading local file"));
- tmp[0] = (char) 251; /* NULL_LENGTH */
- end=strnmov(tmp+1,ex->file_name,sizeof(tmp)-2);
- (void) my_net_write(&thd->net,tmp,(uint) (end-tmp));
- (void) net_flush(&thd->net);
+ (void)net_request_file(&thd->net,ex->file_name);
file = -1;
}
else
@@ -161,9 +178,10 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(MY_WME)))
DBUG_RETURN(-1);
-
- // the file must be:
- if (!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
+
+ // if we are not in slave thread, the file must be:
+ if (!thd->slave_thread &&
+ !((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
#ifndef __EMX__
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
#endif
@@ -196,13 +214,27 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_RETURN(-1); // Can't allocate buffers
}
+ if (!opt_old_rpl_compat && mysql_bin_log.is_open())
+ {
+ lf_info.thd = thd;
+ lf_info.ex = ex;
+ lf_info.db = db;
+ lf_info.table_name = table_list->real_name;
+ lf_info.fields = &fields;
+ lf_info.handle_dup = handle_duplicates;
+ lf_info.wrote_create_file = 0;
+ lf_info.last_pos_in_file = HA_POS_ERROR;
+ read_info.set_io_cache_arg((void*) &lf_info);
+ }
restore_record(table,2);
thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0L;
if (ex->line_term->length() && field_term->length())
{
- while (ex->skip_lines--)
+ // ex->skip_lines needs to be preserved for logging
+ uint skip_lines = ex->skip_lines;
+ while (skip_lines--)
{
if (read_info.next_line())
break;
@@ -214,7 +246,10 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (use_timestamp)
table->time_stamp=0;
table->next_number_field=table->found_next_number_field;
- VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
+ VOID(table->file->extra_opt(HA_EXTRA_WRITE_CACHE,
+ thd->variables.read_buff_size));
+ VOID(table->file->extra_opt(HA_EXTRA_BULK_INSERT_BEGIN,
+ thd->variables.bulk_insert_buff_size));
if (handle_duplicates == DUP_IGNORE ||
handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@@ -224,9 +259,10 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
error=read_fixed_length(thd,info,table,fields,read_info);
else
error=read_sep_field(thd,info,table,fields,read_info,*enclosed);
- if (table->file->extra(HA_EXTRA_NO_CACHE) ||
- table->file->activate_all_index(thd))
- error=1; /* purecov: inspected */
+ if (table->file->extra(HA_EXTRA_NO_CACHE))
+ error=1; /* purecov: inspected */
+ if (table->file->activate_all_index(thd))
+ error=1; /* purecov: inspected */
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->time_stamp=save_time_stamp;
table->next_number_field=0;
@@ -245,23 +281,42 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
if (using_transactions)
ha_autocommit_or_rollback(thd,error);
- DBUG_RETURN(-1); // Error on read
+ if (!opt_old_rpl_compat && mysql_bin_log.is_open())
+ {
+ if (lf_info.wrote_create_file)
+ {
+ Delete_file_log_event d(thd);
+ mysql_bin_log.write(&d);
+ }
+ }
+ DBUG_RETURN(-1); // Error on read
}
sprintf(name,ER(ER_LOAD_INFO),info.records,info.deleted,
info.records-info.copied,thd->cuted_fields);
send_ok(&thd->net,info.copied+info.deleted,0L,name);
// on the slave thd->query is never initialized
- if(!thd->slave_thread)
+ if (!thd->slave_thread)
mysql_update_log.write(thd,thd->query,thd->query_length);
-
+
if (!using_transactions)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
- if (!read_file_from_client && mysql_bin_log.is_open())
+ if (mysql_bin_log.is_open())
{
- ex->skip_lines = save_skip_lines;
- Load_log_event qinfo(thd, ex, table->table_cache_key, table->table_name,
- fields, handle_duplicates);
- mysql_bin_log.write(&qinfo);
+ if (opt_old_rpl_compat && !read_file_from_client)
+ {
+ Load_log_event qinfo(thd, ex, db, table->table_name, fields,
+ handle_duplicates);
+ mysql_bin_log.write(&qinfo);
+ }
+ if (!opt_old_rpl_compat)
+ {
+ read_info.end_io_cache(); // make sure last block gets logged
+ if (lf_info.wrote_create_file)
+ {
+ Execute_load_log_event e(thd);
+ mysql_bin_log.write(&e);
+ }
+ }
}
if (using_transactions)
error=ha_autocommit_or_rollback(thd,error);
@@ -277,7 +332,7 @@ static int
read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
READ_INFO &read_info)
{
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item_field *sql_field;
DBUG_ENTER("read_fixed_length");
@@ -325,7 +380,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
DBUG_RETURN(1);
if (table->next_number_field)
table->next_number_field->reset(); // Clear for next record
- if (read_info.next_line()) // Skipp to next line
+ if (read_info.next_line()) // Skip to next line
break;
if (read_info.line_cuted)
thd->cuted_fields++; /* To long row */
@@ -340,7 +395,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
List<Item> &fields, READ_INFO &read_info,
String &enclosed)
{
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item_field *sql_field;
uint enclosed_length;
DBUG_ENTER("read_sep_field");
@@ -390,7 +445,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
{ // Last record
if (sql_field == (Item_field*) fields.head())
break;
- for ( ; sql_field ; sql_field=(Item_field*) it++)
+ for (; sql_field ; sql_field=(Item_field*) it++)
{
sql_field->field->set_null();
sql_field->field->reset();
@@ -401,7 +456,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
DBUG_RETURN(1);
if (table->next_number_field)
table->next_number_field->reset(); // Clear for next record
- if (read_info.next_line()) // Skipp to next line
+ if (read_info.next_line()) // Skip to next line
break;
if (read_info.line_cuted)
thd->cuted_fields++; /* To long row */
@@ -430,8 +485,10 @@ READ_INFO::unescape(char chr)
}
- /* Read a line using buffering */
- /* If last line is empty (in line mode) then it isn't outputed */
+/*
+ Read a line using buffering
+ If last line is empty (in line mode) then it isn't outputed
+*/
READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
@@ -488,6 +545,22 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
my_free((gptr) buffer,MYF(0)); /* purecov: inspected */
error=1;
}
+ else
+ {
+ /*
+ init_io_cache() will not initialize read_function member
+ if the cache is READ_NET. The reason is explained in
+ mysys/mf_iocache.c. So we work around the problem with a
+ manual assignment
+ */
+ if (get_it_from_net)
+ cache.read_function = _my_b_net_read;
+
+ need_end_io_cache = 1;
+ if (!opt_old_rpl_compat && mysql_bin_log.is_open())
+ cache.pre_read = cache.pre_close =
+ (IO_CACHE_CALLBACK) log_loaded_block;
+ }
}
}
@@ -496,7 +569,8 @@ READ_INFO::~READ_INFO()
{
if (!error)
{
- end_io_cache(&cache);
+ if (need_end_io_cache)
+ ::end_io_cache(&cache);
my_free((gptr) buffer,MYF(0));
error=1;
}
@@ -536,10 +610,10 @@ int READ_INFO::read_field()
if (found_end_of_line)
return 1; // One have to call next_line
- /* Skipp until we find 'line_start' */
+ /* Skip until we find 'line_start' */
if (start_of_line)
- { // Skipp until line_start
+ { // Skip until line_start
start_of_line=0;
if (find_start_of_fields())
return 1;
@@ -682,7 +756,7 @@ found_eof:
/*
** One can't use fixed length with multi-byte charset **
*/
-
+
int READ_INFO::read_fixed_length()
{
int chr;
@@ -691,7 +765,7 @@ int READ_INFO::read_fixed_length()
return 1; // One have to call next_line
if (start_of_line)
- { // Skipp until line_start
+ { // Skip until line_start
start_of_line=0;
if (find_start_of_fields())
return 1;
diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc
index 53953c96d0b..13cac83fc3f 100644
--- a/sql/sql_manager.cc
+++ b/sql/sql_manager.cc
@@ -55,13 +55,7 @@ pthread_handler_decl(handle_manager,arg __attribute__((unused)))
{
if (reset_flush_time)
{
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec = time(NULL)+flush_time; // Bsd 2.1
- abstime.ts_nsec = 0;
-#else
- abstime.tv_sec = time(NULL)+flush_time; // Linux or Solairs
- abstime.tv_nsec = 0;
-#endif
+ set_timespec(abstime, flush_time);
reset_flush_time = FALSE;
}
while (!manager_status && !error && !abort_loop)
diff --git a/sql/sql_map.cc b/sql/sql_map.cc
index 4578b85d10a..e7e24f957c6 100644
--- a/sql/sql_map.cc
+++ b/sql/sql_map.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_map.h b/sql/sql_map.h
index 34f2f755b43..632eb6e4f64 100644
--- a/sql/sql_map.h
+++ b/sql/sql_map.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
new file mode 100644
index 00000000000..fa4d23805f4
--- /dev/null
+++ b/sql/sql_olap.cc
@@ -0,0 +1,194 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ OLAP implementation by Sinisa Milivojevic <sinisa@mysql.com>
+ Inspired by code submitted by Srilakshmi <lakshmi@gdit.iiit.net>
+
+ The ROLLUP code in this file has to be complitely rewritten as it's
+ not good enough to satisfy the goals of MySQL.
+
+ In 4.1 we will replace this with a working, superior implementation
+ of ROLLUP.
+*/
+
+#ifdef DISABLED_UNTIL_REWRITTEN_IN_4_1
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+
+/****************************************************************************
+ Functions that recursively actually creates new SELECT's
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+
+static int make_new_olap_select(LEX *lex, SELECT_LEX *select_lex, List<Item> new_fields)
+{
+ THD *thd=current_thd;
+ Item *item, *new_item;
+ Item_string *constant= new Item_string("ALL",3);
+
+ SELECT_LEX *new_select = (SELECT_LEX *) thd->memdup((char*) select_lex, sizeof(*select_lex));
+ if (!new_select)
+ return 1;
+ lex->last_selects->next=new_select;
+ new_select->linkage=OLAP_TYPE;
+ new_select->olap=NON_EXISTING_ONE;
+ new_select->group_list.elements=0;
+ new_select->group_list.first=(byte *)0;
+ new_select->group_list.next=(byte **)&new_select->group_list.first;
+ List<Item> privlist;
+
+ List_iterator<Item> list_it(select_lex->item_list);
+ List_iterator<Item> new_it(new_fields);
+
+ while((item=list_it++))
+ {
+ bool not_found=true;
+ if (item->type()==Item::FIELD_ITEM)
+ {
+ Item_field *iif = (Item_field *)item;
+ new_it.rewind();
+ while ((new_item=new_it++))
+ {
+ if (new_item->type()==Item::FIELD_ITEM &&
+ !strcmp(((Item_field*)new_item)->table_name,iif->table_name) &&
+ !strcmp(((Item_field*)new_item)->field_name,iif->field_name))
+ {
+ not_found=false;
+ ((Item_field*)new_item)->db_name=iif->db_name;
+ Item_field *new_one=new Item_field(iif->db_name, iif->table_name, iif->field_name);
+ privlist.push_back(new_one);
+ if (add_to_list(new_select->group_list,new_one,1))
+ return 1;
+ break;
+ }
+ }
+ }
+ if (not_found)
+ {
+ if (item->type() == Item::FIELD_ITEM)
+ privlist.push_back(constant);
+ else
+ privlist.push_back((Item*)thd->memdup((char *)item,item->size_of()));
+ }
+ }
+ new_select->item_list=privlist;
+
+ lex->last_selects = new_select;
+ return 0;
+}
+
+/****************************************************************************
+ Functions that recursively creates combinations of queries for OLAP
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+static int olap_combos(List<Item> old_fields, List<Item> new_fields, Item *item, LEX *lex,
+ SELECT_LEX *select_lex, int position, int selection, int num_fields,
+ int num_new_fields)
+{
+ int sl_return = 0;
+ if(position == num_new_fields)
+ {
+ if(item)
+ new_fields.push_front(item);
+ sl_return = make_new_olap_select(lex, select_lex, new_fields);
+ }
+ else
+ {
+ if(item)
+ new_fields.push_front(item);
+ while ((num_fields - num_new_fields >= selection - position) && !sl_return)
+ {
+ item = old_fields.pop();
+ sl_return = olap_combos(old_fields, new_fields, item, lex, select_lex, position+1, ++selection, num_fields, num_new_fields);
+ }
+ }
+ return sl_return;
+}
+
+
+/****************************************************************************
+ Top level function for converting OLAP clauses to multiple selects
+ This is also a place where clauses treatment depends on OLAP type
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
+{
+ List<Item> item_list_copy, new_item_list;
+ item_list_copy.empty();
+ new_item_list.empty();
+ int count=select_lex->group_list.elements;
+ int sl_return=0;
+
+// a fix for UNION's
+ for (TABLE_LIST *cursor= (TABLE_LIST *)select_lex->table_list.first;
+ cursor;
+ cursor=cursor->next)
+ {
+ if (cursor->do_redirect)
+ {
+ cursor->table= ((TABLE_LIST*) cursor->table)->table;
+ cursor->do_redirect=false;
+ }
+ }
+
+ lex->last_selects=select_lex;
+
+ for (ORDER *order=(ORDER *)select_lex->group_list.first ; order ; order=order->next)
+ item_list_copy.push_back(*(order->item));
+
+ List<Item> all_fields(select_lex->item_list);
+
+
+ if (setup_tables((TABLE_LIST *)select_lex->table_list.first) ||
+ setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,select_lex->item_list,1,&all_fields,1) ||
+ setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,item_list_copy,1,&all_fields,1))
+ return -1;
+
+ if (select_lex->olap == CUBE_TYPE)
+ {
+ for( int i=count-1; i>=0 && !sl_return; i--)
+ sl_return=olap_combos(item_list_copy, new_item_list, (Item *)0, lex, select_lex, 0, 0, count, i);
+ }
+ else if (select_lex->olap == ROLLUP_TYPE)
+ {
+ for( int i=count-1; i>=0 && !sl_return; i--)
+ {
+ Item *item;
+ item_list_copy.pop();
+ List_iterator<Item> it(item_list_copy);
+ new_item_list.empty();
+ while ((item = it++))
+ new_item_list.push_front(item);
+ sl_return=make_new_olap_select(lex, select_lex, new_item_list);
+ }
+ }
+ else
+ sl_return=1; // impossible
+ return sl_return;
+}
+
+#endif /* DISABLED_UNTIL_REWRITTEN_IN_4_1 */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d97c392bb9f..46ef9e90b7d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,12 +14,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
#include "mysql_priv.h"
#include "sql_acl.h"
#include "sql_repl.h"
+#include "repl_failsafe.h"
#include <m_ctype.h>
-#include <thr_alarm.h>
#include <myisam.h>
#include <my_dir.h>
#include <assert.h>
@@ -28,8 +27,29 @@
#include "ha_innobase.h"
#endif
+#ifdef HAVE_OPENSSL
+/*
+ Without SSL the handshake consists of one packet. This packet
+ has both client capabilites and scrambled password.
+ With SSL the handshake might consist of two packets. If the first
+ packet (client capabilities) has CLIENT_SSL flag set, we have to
+ switch to SSL and read the second packet. The scrambled password
+ is in the second packet and client_capabilites field will be ignored.
+ Maybe it is better to accept flags other than CLIENT_SSL from the
+ second packet?
+*/
+#define SSL_HANDSHAKE_SIZE 2
+#define NORMAL_HANDSHAKE_SIZE 6
+#define MIN_HANDSHAKE_SIZE 2
+#else
+#define MIN_HANDSHAKE_SIZE 6
+#endif /* HAVE_OPENSSL */
#define SCRAMBLE_LENGTH 8
+#define MEM_ROOT_BLOCK_SIZE 8192
+#define MEM_ROOT_PREALLOC 8192
+#define TRANS_MEM_ROOT_BLOCK_SIZE 4096
+#define TRANS_MEM_ROOT_PREALLOC 4096
extern int yyparse(void);
extern "C" pthread_mutex_t THR_LOCK_keycache;
@@ -37,16 +57,17 @@ extern "C" pthread_mutex_t THR_LOCK_keycache;
extern "C" int gethostname(char *name, int namelen);
#endif
-static int check_for_max_user_connections(const char *user, int u_length,
- const char *host);
-static void decrease_user_connections(const char *user, const char *host);
+static int check_for_max_user_connections(USER_CONN *uc);
+static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
-static bool check_dup(THD *thd,const char *db,const char *name,
- TABLE_LIST *tables);
+static bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
static void mysql_init_query(THD *thd);
static void remove_escape(char *name);
static void refresh_status(void);
+static bool append_file_to_dir(THD *thd, char **filename_ptr,
+ char *table_name);
+static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result);
const char *any_db="*any*"; // Special symbol for check_access
@@ -54,13 +75,13 @@ const char *command_name[]={
"Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB",
"Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist",
"Connect","Kill","Debug","Ping","Time","Delayed_insert","Change user",
- "Binlog Dump","Table Dump", "Connect Out"
+ "Binlog Dump","Table Dump", "Connect Out", "Register Slave"
};
bool volatile abort_slave = 0;
#ifdef HAVE_OPENSSL
-extern VioSSLAcceptorFd* ssl_acceptor_fd;
+extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
#ifdef __WIN__
@@ -70,14 +91,14 @@ static void test_signal(int sig_ptr)
MessageBox(NULL,"Test signal","DBUG",MB_OK);
#endif
#if defined(OS2)
- fprintf( stderr, "Test signal %d\n", sig_ptr);
- fflush( stderr);
+ fprintf(stderr, "Test signal %d\n", sig_ptr);
+ fflush(stderr);
#endif
}
static void init_signals(void)
{
int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ;
- for(int i=0 ; i < 7 ; i++)
+ for (int i=0 ; i < 7 ; i++)
signal( signals[i], test_signal) ;
}
#endif
@@ -85,7 +106,7 @@ static void init_signals(void)
inline bool end_active_trans(THD *thd)
{
int error=0;
- if (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN |
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK))
{
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
@@ -97,10 +118,68 @@ inline bool end_active_trans(THD *thd)
}
+static HASH hash_user_connections;
+extern pthread_mutex_t LOCK_user_conn;
+
+static int get_or_create_user_conn(THD *thd, const char *user,
+ const char *host,
+ USER_RESOURCES *mqh)
+{
+ int return_val=0;
+ uint temp_len, user_len, host_len;
+ char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
+ struct user_conn *uc;
+
+ DBUG_ASSERT(user != 0);
+ DBUG_ASSERT(host != 0);
+
+ user_len=strlen(user);
+ host_len=strlen(host);
+ temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
+ (void) pthread_mutex_lock(&LOCK_user_conn);
+ if (!(uc = (struct user_conn *) hash_search(&hash_user_connections,
+ (byte*) temp_user, temp_len)))
+ {
+ /* First connection for user; Create a user connection object */
+ if (!(uc= ((struct user_conn*)
+ my_malloc(sizeof(struct user_conn) + temp_len+1,
+ MYF(MY_WME)))))
+ {
+ send_error(&current_thd->net, 0, NullS); // Out of memory
+ return_val=1;
+ goto end;
+ }
+ uc->user=(char*) (uc+1);
+ memcpy(uc->user,temp_user,temp_len+1);
+ uc->user_len= user_len;
+ uc->host=uc->user + uc->user_len + 1;
+ uc->len = temp_len;
+ uc->connections = 1;
+ uc->questions=uc->updates=uc->conn_per_hour=0;
+ uc->user_resources=*mqh;
+ if (max_user_connections && mqh->connections > max_user_connections)
+ uc->user_resources.connections = max_user_connections;
+ uc->intime=thd->thr_create_time;
+ if (hash_insert(&hash_user_connections, (byte*) uc))
+ {
+ my_free((char*) uc,0);
+ send_error(&current_thd->net, 0, NullS); // Out of memory
+ return_val=1;
+ goto end;
+ }
+ }
+ thd->user_connect=uc;
+end:
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+ return return_val;
+
+}
+
+
/*
-** Check if user is ok
-** Updates:
-** thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access
+ Check if user is ok
+ Updates:
+ thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access
*/
static bool check_user(THD *thd,enum_server_command command, const char *user,
@@ -108,32 +187,34 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
{
NET *net= &thd->net;
thd->db=0;
+ thd->db_length=0;
+ USER_RESOURCES ur;
if (!(thd->user = my_strdup(user, MYF(0))))
{
send_error(net,ER_OUT_OF_RESOURCES);
return 1;
}
- thd->master_access=acl_getroot(thd->host, thd->ip, thd->user,
+ thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
passwd, thd->scramble, &thd->priv_user,
protocol_version == 9 ||
!(thd->client_capabilities &
- CLIENT_LONG_PASSWORD));
- DBUG_PRINT("general",
+ CLIENT_LONG_PASSWORD),&ur);
+ DBUG_PRINT("info",
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
- thd->client_capabilities, thd->max_packet_length,
- thd->host ? thd->host : thd->ip, thd->priv_user,
+ thd->client_capabilities, thd->max_client_packet_length,
+ thd->host_or_ip, thd->priv_user,
passwd[0] ? "yes": "no",
thd->master_access, thd->db ? thd->db : "*none*"));
if (thd->master_access & NO_ACCESS)
{
net_printf(net, ER_ACCESS_DENIED_ERROR,
thd->user,
- thd->host ? thd->host : thd->ip,
+ thd->host_or_ip,
passwd[0] ? ER(ER_YES) : ER(ER_NO));
mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR),
thd->user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
+ thd->host_or_ip,
passwd[0] ? ER(ER_YES) : ER(ER_NO));
return(1); // Error already given
}
@@ -141,7 +222,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
{
VOID(pthread_mutex_lock(&LOCK_thread_count));
bool tmp=(thread_count - delayed_insert_threads >= max_connections &&
- !(thd->master_access & PROCESS_ACL));
+ !(thd->master_access & SUPER_ACL));
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{ // Too many connections
@@ -154,17 +235,21 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
(char*) "%s@%s on %s" :
(char*) "%s@%s as anonymous on %s"),
user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
+ thd->host_or_ip,
db ? db : (char*) "");
thd->db_access=0;
- if (max_user_connections &&
- check_for_max_user_connections(user, strlen(user), thd->host))
+ /* Don't allow user to connect if he has done too many queries */
+ if ((ur.questions || ur.updates || ur.connections) &&
+ get_or_create_user_conn(thd,user,thd->host_or_ip,&ur))
+ return -1;
+ if (thd->user_connect && thd->user_connect->user_resources.connections &&
+ check_for_max_user_connections(thd->user_connect))
return -1;
if (db && db[0])
{
bool error=test(mysql_change_db(thd,db));
- if (error)
- decrease_user_connections(thd->user,thd->host);
+ if (error && thd->user_connect)
+ decrease_user_connections(thd->user_connect);
return error;
}
else
@@ -172,20 +257,12 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
return 0; // ok
}
+
/*
-** check for maximum allowable user connections
-** if mysql server is started with corresponding
-** variable that is greater then 0
+ Check for maximum allowable user connections, if the mysqld server is
+ started with corresponding variable that is greater then 0.
*/
-static HASH hash_user_connections;
-extern pthread_mutex_t LOCK_user_conn;
-
-struct user_conn {
- char *user;
- uint len, connections;
-};
-
static byte* get_key_conn(user_conn *buff, uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -193,8 +270,6 @@ static byte* get_key_conn(user_conn *buff, uint *length,
return (byte*) buff->user;
}
-#define DEF_USER_COUNT 50
-
static void free_user(struct user_conn *uc)
{
my_free((char*) uc,MYF(0));
@@ -202,100 +277,49 @@ static void free_user(struct user_conn *uc)
void init_max_user_conn(void)
{
- (void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0,
+ (void) hash_init(&hash_user_connections,max_connections,0,0,
(hash_get_key) get_key_conn, (void (*)(void*)) free_user,
0);
}
-static int check_for_max_user_connections(const char *user, int u_length,
- const char *host)
+static int check_for_max_user_connections(USER_CONN *uc)
{
- int error=1;
- uint temp_len;
- char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
- struct user_conn *uc;
- if (!user)
- user="";
- if (!host)
- host="";
+ int error=0;
DBUG_ENTER("check_for_max_user_connections");
- DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host));
-
- temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
- NullS) - temp_user);
- (void) pthread_mutex_lock(&LOCK_user_conn);
- uc = (struct user_conn *) hash_search(&hash_user_connections,
- (byte*) temp_user, temp_len);
- if (uc) /* user found ; check for no. of connections */
+
+ if (max_user_connections &&
+ (max_user_connections <= (uint) uc->connections))
{
- if (max_user_connections == (uint) uc->connections)
- {
- net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, temp_user);
- goto end;
- }
- uc->connections++;
+ net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, uc->user);
+ error=1;
+ goto end;
}
- else
+ uc->connections++;
+ if (uc->user_resources.connections &&
+ uc->conn_per_hour++ >= uc->user_resources.connections)
{
- /* the user is not found in the cache; Insert it */
- struct user_conn *uc= ((struct user_conn*)
- my_malloc(sizeof(struct user_conn) + temp_len+1,
- MYF(MY_WME)));
- if (!uc)
- {
- send_error(&current_thd->net, 0, NullS); // Out of memory
- goto end;
- }
- uc->user=(char*) (uc+1);
- memcpy(uc->user,temp_user,temp_len+1);
- uc->len = temp_len;
- uc->connections = 1;
- if (hash_insert(&hash_user_connections, (byte*) uc))
- {
- my_free((char*) uc,0);
- send_error(&current_thd->net, 0, NullS); // Out of memory
- goto end;
- }
+ net_printf(&current_thd->net, ER_USER_LIMIT_REACHED, uc->user,
+ "max_connections",
+ (long) uc->user_resources.connections);
+ error=1;
+ goto end;
}
- error=0;
-
end:
- (void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_RETURN(error);
}
-static void decrease_user_connections(const char *user, const char *host)
+static void decrease_user_connections(USER_CONN *uc)
{
- char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
- int temp_len;
- struct user_conn *uc;
- if (!max_user_connections)
- return;
- if (!user)
- user="";
- if (!host)
- host="";
DBUG_ENTER("decrease_user_connections");
- DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host));
-
- temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
- NullS) - temp_user);
- (void) pthread_mutex_lock(&LOCK_user_conn);
-
- uc = (struct user_conn *) hash_search(&hash_user_connections,
- (byte*) temp_user, temp_len);
- dbug_assert(uc != 0); // We should always find the user
- if (!uc)
- goto end; // Safety; Something went wrong
- if (! --uc->connections)
+ if ((uc->connections && !--uc->connections) && !mqh_used)
{
/* Last connection for user; Delete it */
+ (void) pthread_mutex_lock(&LOCK_user_conn);
(void) hash_delete(&hash_user_connections,(byte*) uc);
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
}
-end:
- (void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_VOID_RETURN;
}
@@ -307,22 +331,112 @@ void free_max_user_conn(void)
/*
-** check connnetion and get priviliges
-** returns 0 on ok, -1 < if error is given > 0 on error.
+ Check if maximum queries per hour limit has been reached
+ returns 0 if OK.
+
+ In theory we would need a mutex in the USER_CONN structure for this to
+ be 100 % safe, but as the worst scenario is that we would miss counting
+ a couple of queries, this isn't critical.
*/
+char uc_update_queries[SQLCOM_END];
+
+static bool check_mqh(THD *thd, uint check_command)
+{
+ bool error=0;
+ time_t check_time = thd->start_time ? thd->start_time : time(NULL);
+ USER_CONN *uc=thd->user_connect;
+ DBUG_ENTER("check_mqh");
+ DBUG_ASSERT(uc != 0);
+
+ /* If more than a hour since last check, reset resource checking */
+ if (check_time - uc->intime >= 3600)
+ {
+ (void) pthread_mutex_lock(&LOCK_user_conn);
+ uc->questions=1;
+ uc->updates=0;
+ uc->conn_per_hour=0;
+ uc->intime=check_time;
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+ }
+ /* Check that we have not done too many questions / hour */
+ if (uc->user_resources.questions &&
+ uc->questions++ >= uc->user_resources.questions)
+ {
+ net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_questions",
+ (long) uc->user_resources.questions);
+ error=1;
+ goto end;
+ }
+ if (check_command < (uint) SQLCOM_END)
+ {
+ /* Check that we have not done too many updates / hour */
+ if (uc->user_resources.updates && uc_update_queries[check_command] &&
+ uc->updates++ >= uc->user_resources.updates)
+ {
+ net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_updates",
+ (long) uc->user_resources.updates);
+ error=1;
+ goto end;
+ }
+ }
+end:
+ DBUG_RETURN(error);
+}
+
+
+static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them=false)
+{
+
+ (void) pthread_mutex_lock(&LOCK_user_conn);
+ if (lu) // for GRANT
+ {
+ USER_CONN *uc;
+ uint temp_len=lu->user.length+lu->host.length+2;
+ char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
+
+ memcpy(temp_user,lu->user.str,lu->user.length);
+ memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length);
+ temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0;
+ if ((uc = (struct user_conn *) hash_search(&hash_user_connections,
+ (byte*) temp_user, temp_len)))
+ {
+ uc->questions=0;
+ get_mqh(temp_user,&temp_user[lu->user.length+1],uc);
+ uc->updates=0;
+ uc->conn_per_hour=0;
+ }
+ }
+ else // for FLUSH PRIVILEGES and FLUSH USER_RESOURCES
+ {
+ for (uint idx=0;idx < hash_user_connections.records; idx++)
+ {
+ USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections, idx);
+ if (get_them)
+ get_mqh(uc->user,uc->host,uc);
+ uc->questions=0;
+ uc->updates=0;
+ uc->conn_per_hour=0;
+ }
+ }
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+}
+
+
+/*
+ Check connnetion and get priviliges
+ Returns 0 on ok, -1 < if error is given > 0 on error.
+*/
static int
check_connections(THD *thd)
{
uint connect_errors=0;
NET *net= &thd->net;
- /*
- ** store the connection details
- */
+ /* Store the connection details */
DBUG_PRINT("info", (("check_connections called by thread %d"),
thd->thread_id));
- DBUG_PRINT("general",("New connection received on %s",
+ DBUG_PRINT("info",("New connection received on %s",
vio_description(net->vio)));
if (!thd->host) // If TCP/IP connection
{
@@ -332,6 +446,7 @@ check_connections(THD *thd)
return (ER_BAD_HOST_ERROR);
if (!(thd->ip = my_strdup(ip,MYF(0))))
return (ER_OUT_OF_RESOURCES);
+ thd->host_or_ip=thd->ip;
#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread)
/* Fast local hostname resolve for Win32 */
if (!strcmp(thd->ip,"127.0.0.1"))
@@ -345,65 +460,50 @@ check_connections(THD *thd)
if (connect_errors > max_connect_errors)
return(ER_HOST_IS_BLOCKED);
}
- DBUG_PRINT("general",("Host: %s ip: %s",
- thd->host ? thd->host : "unknown host",
- thd->ip ? thd->ip : "unknown ip"));
+ DBUG_PRINT("info",("Host: %s ip: %s",
+ thd->host ? thd->host : "unknown host",
+ thd->ip ? thd->ip : "unknown ip"));
if (acl_check_host(thd->host,thd->ip))
return(ER_HOST_NOT_PRIVILEGED);
}
else /* Hostname given means that the connection was on a socket */
{
- DBUG_PRINT("general",("Host: %s",thd->host));
+ DBUG_PRINT("info",("Host: %s",thd->host));
+ thd->host_or_ip=thd->host;
thd->ip=0;
bzero((char*) &thd->remote,sizeof(struct sockaddr));
}
vio_keepalive(net->vio, TRUE);
- /* nasty, but any other way? */
- uint pkt_len = 0;
+ ulong pkt_len=0;
{
/* buff[] needs to big enough to hold the server_version variable */
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+32],*end;
int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB;
+
if (opt_using_transactions)
client_flags|=CLIENT_TRANSACTIONS;
#ifdef HAVE_COMPRESS
client_flags |= CLIENT_COMPRESS;
#endif /* HAVE_COMPRESS */
+#ifdef HAVE_OPENSSL
+ if (ssl_acceptor_fd)
+ client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */
+#endif /* HAVE_OPENSSL */
- end=strmov(buff,server_version)+1;
+ end=strnmov(buff,server_version,SERVER_VERSION_LENGTH)+1;
int4store((uchar*) end,thd->thread_id);
end+=4;
memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
end+=SCRAMBLE_LENGTH +1;
-#ifdef HAVE_OPENSSL
- if (ssl_acceptor_fd)
- client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */
- /*
- * Without SSL the handshake consists of one packet. This packet
- * has both client capabilites and scrambled password.
- * With SSL the handshake might consist of two packets. If the first
- * packet (client capabilities) has CLIENT_SSL flag set, we have to
- * switch to SSL and read the second packet. The scrambled password
- * is in the second packet and client_capabilites field will be ignored.
- * Maybe it is better to accept flags other than CLIENT_SSL from the
- * second packet?
- */
-#define SSL_HANDSHAKE_SIZE 2
-#define NORMAL_HANDSHAKE_SIZE 6
-#define MIN_HANDSHAKE_SIZE 2
-
-#else
-#define MIN_HANDSHAKE_SIZE 6
-#endif /* HAVE_OPENSSL */
int2store(end,client_flags);
- end[2]=MY_CHARSET_CURRENT;
+ end[2]=(char) MY_CHARSET_CURRENT;
int2store(end+3,thd->server_status);
bzero(end+5,13);
end+=18;
- if (net_write_command(net,protocol_version, buff,
+ if (net_write_command(net,(uchar) protocol_version, buff,
(uint) (end-buff)) ||
- (pkt_len=my_net_read(net)) == packet_error ||
+ (pkt_len= my_net_read(net)) == packet_error ||
pkt_len < MIN_HANDSHAKE_SIZE)
{
inc_host_errors(&thd->remote.sin_addr);
@@ -415,30 +515,25 @@ check_connections(THD *thd)
#endif
if (connect_errors)
reset_host_errors(&thd->remote.sin_addr);
- if (thd->packet.alloc(net_buffer_length))
+ if (thd->packet.alloc(thd->variables.net_buffer_length))
return(ER_OUT_OF_RESOURCES);
thd->client_capabilities=uint2korr(net->read_pos);
if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
thd->sql_mode|= MODE_IGNORE_SPACE;
#ifdef HAVE_OPENSSL
- DBUG_PRINT("info",
- ("pkt_len:%d, client capabilities: %d",
- pkt_len, thd->client_capabilities) );
+ DBUG_PRINT("info", ("client capabilities: %d", thd->client_capabilities));
if (thd->client_capabilities & CLIENT_SSL)
{
- DBUG_PRINT("info", ("Agreed to change IO layer to SSL") );
/* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress..."));
- VioSocket* vio_socket = my_reinterpret_cast(VioSocket*)(net->vio);
- VioSSL* vio_ssl = ssl_acceptor_fd->accept(vio_socket);
- net->vio = my_reinterpret_cast(NetVio*) (vio_ssl);
+ sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout);
DBUG_PRINT("info", ("Reading user information over SSL layer"));
if ((pkt_len=my_net_read(net)) == packet_error ||
pkt_len < NORMAL_HANDSHAKE_SIZE)
{
- DBUG_PRINT("info", ("pkt_len:%d", pkt_len));
- DBUG_PRINT("error", ("Failed to read user information"));
+ DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
+ pkt_len));
inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR);
}
@@ -454,7 +549,7 @@ check_connections(THD *thd)
}
#endif
- thd->max_packet_length=uint3korr(net->read_pos+2);
+ thd->max_client_packet_length=uint3korr(net->read_pos+2);
char *user= (char*) net->read_pos+5;
char *passwd= strend(user)+1;
char *db=0;
@@ -463,11 +558,11 @@ check_connections(THD *thd)
if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
db=strend(passwd)+1;
if (thd->client_capabilities & CLIENT_INTERACTIVE)
- thd->inactive_timeout=net_interactive_timeout;
+ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions)
thd->net.return_status= &thd->server_status;
- net->timeout=net_read_timeout;
+ net->read_timeout=(uint) thd->variables.net_read_timeout;
if (check_user(thd,COM_CONNECT, user, passwd, db, 1))
return (-1);
thd->password=test(passwd[0]);
@@ -485,9 +580,9 @@ pthread_handler_decl(handle_one_connection,arg)
pthread_detach_this_thread();
-#if !defined( __WIN__) && !defined(OS2) /* Win32 calls this in pthread_create */
- if (my_thread_init()) // needed to be called first before we call
- // DBUG_ macros
+#if !defined( __WIN__) && !defined(OS2) // Win32 calls this in pthread_create
+ // The following calls needs to be done before we call DBUG_ macros
+ if (!(test_flags & TEST_NO_THREADS) & my_thread_init())
{
close_connection(&thd->net,ER_OUT_OF_RESOURCES);
statistic_increment(aborted_connects,&LOCK_thread_count);
@@ -496,13 +591,13 @@ pthread_handler_decl(handle_one_connection,arg)
}
#endif
- // handle_one_connection() is the only way a thread would start
- // and would always be on top of the stack
- // therefore, the thread stack always starts at the address of the first
- // local variable of handle_one_connection, which is thd
- // we need to know the start of the stack so that we could check for
- // stack overruns
-
+ /*
+ handle_one_connection() is the only way a thread would start
+ and would always be on top of the stack, therefore, the thread
+ stack always starts at the address of the first local variable
+ of handle_one_connection, which is thd. We need to know the
+ start of the stack so that we could check for stack overruns.
+ */
DBUG_PRINT("info", ("handle_one_connection called by thread %d\n",
thd->thread_id));
// now that we've called my_thread_init(), it is safe to call DBUG_*
@@ -534,7 +629,7 @@ pthread_handler_decl(handle_one_connection,arg)
if ((error=check_connections(thd)))
{ // Wrong permissions
if (error > 0)
- net_printf(net,error,thd->host ? thd->host : (thd->ip ? thd->ip : ""));
+ net_printf(net,error,thd->host_or_ip);
#ifdef __NT__
if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
sleep(1); /* must wait after eof() */
@@ -543,7 +638,7 @@ pthread_handler_decl(handle_one_connection,arg)
goto end_thread;
}
- if (thd->max_join_size == HA_POS_ERROR)
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
if (thd->client_capabilities & CLIENT_COMPRESS)
net->compress=1; // Use compression
@@ -552,27 +647,30 @@ pthread_handler_decl(handle_one_connection,arg)
thd->command=COM_SLEEP;
thd->version=refresh_version;
thd->set_time();
- init_sql_alloc(&thd->mem_root,8192,8192);
+ init_sql_alloc(&thd->mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
+ init_sql_alloc(&thd->transaction.mem_root,
+ TRANS_MEM_ROOT_BLOCK_SIZE, TRANS_MEM_ROOT_PREALLOC);
while (!net->error && net->vio != 0 && !thd->killed)
{
if (do_command(thd))
break;
}
+ if (thd->user_connect)
+ decrease_user_connections(thd->user_connect);
free_root(&thd->mem_root,MYF(0));
if (net->error && net->vio != 0)
{
- if (!thd->killed && opt_warnings)
- sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
- thd->thread_id,(thd->db ? thd->db : "unconnected"),
- thd->user ? thd->user : "unauthenticated",
- (thd->host ? thd->host : thd->ip ? thd->ip : "unknown"),
- (net->last_errno ? ER(net->last_errno) :
- ER(ER_UNKNOWN_ERROR)));
+ if (!thd->killed && thd->variables.log_warnings)
+ sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
+ thd->user ? thd->user : "unauthenticated",
+ thd->host_or_ip,
+ (net->last_errno ? ER(net->last_errno) :
+ ER(ER_UNKNOWN_ERROR)));
send_error(net,net->last_errno,NullS);
thread_safe_increment(aborted_threads,&LOCK_thread_count);
}
-
- decrease_user_connections(thd->user,thd->host);
+
end_thread:
close_connection(net);
end_thread(thd,1);
@@ -616,7 +714,7 @@ pthread_handler_decl(handle_bootstrap,arg)
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
- if (thd->max_join_size == (ulong) ~0L)
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
thd->proc_info=0;
@@ -624,7 +722,9 @@ pthread_handler_decl(handle_bootstrap,arg)
thd->priv_user=thd->user=(char*)"boot";
buff= (char*) thd->net.buff;
- init_sql_alloc(&thd->mem_root,8192,8192);
+ init_sql_alloc(&thd->mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
+ init_sql_alloc(&thd->transaction.mem_root,
+ TRANS_MEM_ROOT_BLOCK_SIZE, TRANS_MEM_ROOT_PREALLOC);
while (fgets(buff, thd->net.max_packet, file))
{
uint length=(uint) strlen(buff);
@@ -632,13 +732,23 @@ pthread_handler_decl(handle_bootstrap,arg)
length--;
buff[length]=0;
thd->current_tablenr=0;
- thd->query= thd->memdup(buff,length+1);
+ thd->query_length=length;
+ thd->query= thd->memdup_w_gap(buff, length+1, thd->db_length+1);
+ thd->query[length] = '\0';
thd->query_id=query_id++;
+ if (mqh_used && thd->user_connect && check_mqh(thd, SQLCOM_END))
+ {
+ thd->net.error = 0;
+ close_thread_tables(thd); // Free tables
+ free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
+ break;
+ }
mysql_parse(thd,thd->query,length);
close_thread_tables(thd); // Free tables
if (thd->fatal_error)
break;
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
+ free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
}
thd->priv_user=thd->user=0;
@@ -668,7 +778,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
int error = 0;
DBUG_ENTER("mysql_table_dump");
db = (db && db[0]) ? db : thd->db;
- if (!(table_list = (TABLE_LIST*) sql_calloc(sizeof(TABLE_LIST))))
+ if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(1); // out of memory
table_list->db = db;
table_list->real_name = table_list->name = tbl_name;
@@ -690,21 +800,19 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
goto err;
thd->free_list = 0;
+ thd->query_length=(uint) strlen(tbl_name);
thd->query = tbl_name;
- if((error = mysqld_dump_create_info(thd, table, -1)))
- {
- my_error(ER_GET_ERRNO, MYF(0));
- goto err;
- }
+ if ((error = mysqld_dump_create_info(thd, table, -1)))
+ {
+ my_error(ER_GET_ERRNO, MYF(0));
+ goto err;
+ }
net_flush(&thd->net);
- error = table->file->dump(thd,fd);
- if(error)
- my_error(ER_GET_ERRNO, MYF(0));
+ if ((error = table->file->dump(thd,fd)))
+ my_error(ER_GET_ERRNO, MYF(0));
err:
-
close_thread_tables(thd);
-
DBUG_RETURN(error);
}
@@ -714,69 +822,91 @@ err:
bool do_command(THD *thd)
{
char *packet;
- uint old_timeout,packet_length;
- bool error=0;
+ uint old_timeout;
+ ulong packet_length;
NET *net;
enum enum_server_command command;
- // commands which will always take a long time should be marked with
- // this so that they will not get logged to the slow query log
- bool slow_command=FALSE;
DBUG_ENTER("do_command");
net= &thd->net;
thd->current_tablenr=0;
packet=0;
- old_timeout=net->timeout;
- net->timeout=thd->inactive_timeout; /* Wait max for 8 hours */
+ old_timeout=net->read_timeout;
+ // Wait max for 8 hours
+ net->read_timeout=(uint) thd->variables.net_wait_timeout;
net->last_error[0]=0; // Clear error message
net->last_errno=0;
net_new_transaction(net);
if ((packet_length=my_net_read(net)) == packet_error)
{
- DBUG_PRINT("general",("Got error reading command from socket %s",
- vio_description(net->vio) ));
+ DBUG_PRINT("info",("Got error reading command from socket %s",
+ vio_description(net->vio) ));
return TRUE;
}
else
{
packet=(char*) net->read_pos;
command = (enum enum_server_command) (uchar) packet[0];
- DBUG_PRINT("general",("Command on %s = %d (%s)",
- vio_description(net->vio), command,
- command_name[command]));
+ DBUG_PRINT("info",("Command on %s = %d (%s)",
+ vio_description(net->vio), command,
+ command_name[command]));
}
- net->timeout=old_timeout; /* Timeout */
+ net->read_timeout=old_timeout; // restore it
+ DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
+}
+
+
+bool dispatch_command(enum enum_server_command command, THD *thd,
+ char* packet, uint packet_length)
+{
+ NET *net= &thd->net;
+ bool error=0;
+ /*
+ Commands which will always take a long time should be marked with
+ this so that they will not get logged to the slow query log
+ */
+ bool slow_command=FALSE;
+ DBUG_ENTER("dispatch_command");
+
thd->command=command;
+ thd->set_time();
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id=query_id;
if (command != COM_STATISTICS && command != COM_PING)
query_id++;
thread_running++;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->set_time();
- thd->lex.options=0; // We store status here
- switch(command) {
+
+ thd->lex.select_lex.options=0; // We store status here
+ switch (command) {
case COM_INIT_DB:
thread_safe_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_thread_count);
- if (!mysql_change_db(thd,packet+1))
+ if (!mysql_change_db(thd,packet))
mysql_log.write(thd,command,"%s",thd->db);
break;
+ case COM_REGISTER_SLAVE:
+ {
+ if (register_slave(thd, (uchar*)packet, packet_length))
+ send_error(&thd->net);
+ else
+ send_ok(&thd->net);
+ break;
+ }
case COM_TABLE_DUMP:
{
thread_safe_increment(com_other,&LOCK_thread_count);
slow_command = TRUE;
- char* data = packet + 1;
- uint db_len = *data;
- uint tbl_len = *(data + db_len + 1);
- char* db = sql_alloc(db_len + tbl_len + 2);
- memcpy(db, data + 1, db_len);
+ uint db_len = *(uchar*)packet;
+ uint tbl_len = *(uchar*)(packet + db_len + 1);
+ char* db = thd->alloc(db_len + tbl_len + 2);
+ memcpy(db, packet + 1, db_len);
char* tbl_name = db + db_len;
*tbl_name++ = 0;
- memcpy(tbl_name, data + db_len + 2, tbl_len);
+ memcpy(tbl_name, packet + db_len + 2, tbl_len);
tbl_name[tbl_len] = 0;
- if(mysql_table_dump(thd, db, tbl_name, -1))
+ if (mysql_table_dump(thd, db, tbl_name, -1))
send_error(&thd->net); // dump to NET
break;
@@ -784,16 +914,18 @@ bool do_command(THD *thd)
case COM_CHANGE_USER:
{
thread_safe_increment(com_other,&LOCK_thread_count);
- char *user= (char*) packet+1;
+ char *user= (char*) packet;
char *passwd= strend(user)+1;
char *db= strend(passwd)+1;
/* Save user and privileges */
uint save_master_access=thd->master_access;
uint save_db_access= thd->db_access;
+ uint save_db_length= thd->db_length;
char *save_user= thd->user;
char *save_priv_user= thd->priv_user;
char *save_db= thd->db;
+ USER_CONN *save_uc= thd->user_connect;
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
{ // Check if protocol is ok
@@ -807,11 +939,13 @@ bool do_command(THD *thd)
thd->master_access=save_master_access;
thd->db_access=save_db_access;
thd->db=save_db;
+ thd->db_length=save_db_length;
thd->user=save_user;
thd->priv_user=save_priv_user;
break;
}
- decrease_user_connections (save_user, thd->host);
+ if (max_connections && save_uc)
+ decrease_user_connections(save_uc);
x_free((gptr) save_db);
x_free((gptr) save_user);
thd->password=test(passwd[0]);
@@ -820,28 +954,38 @@ bool do_command(THD *thd)
case COM_QUERY:
{
+ packet_length--; // Remove end null
+ /* Remove garage at start and end of query */
+ while (isspace(packet[0]) && packet_length > 0)
+ {
+ packet++;
+ packet_length--;
+ }
char *pos=packet+packet_length; // Point at end null
- /* Remove garage at end of query */
- while (packet_length > 0 && pos[-1] == ';')
+ while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1])))
{
pos--;
packet_length--;
}
- *pos=0;
- if (!(thd->query= (char*) thd->memdup((gptr) (packet+1),packet_length)))
+ /* We must allocate some extra memory for query cache */
+ if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet),
+ packet_length,
+ thd->db_length+2)))
break;
- thd->packet.shrink(net_buffer_length); // Reclaim some memory
+ thd->query[packet_length]=0;
+ thd->packet.shrink(thd->variables.net_buffer_length);// Reclaim some memory
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
mysql_log.write(thd,command,"%s",thd->query);
DBUG_PRINT("query",("%s",thd->query));
- mysql_parse(thd,thd->query,packet_length-1);
+ /* thd->query_length is set by mysql_parse() */
+ mysql_parse(thd,thd->query,packet_length);
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
DBUG_PRINT("info",("query ready"));
break;
}
- case COM_FIELD_LIST: // This isn't actually neaded
+ case COM_FIELD_LIST: // This isn't actually needed
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
break;
@@ -857,8 +1001,11 @@ bool do_command(THD *thd)
break;
}
thd->free_list=0;
- table_list.name=table_list.real_name=thd->strdup(packet+1);
- thd->query=fields=thd->strdup(strend(packet+1)+1);
+ table_list.name=table_list.real_name=thd->strdup(packet);
+ packet=strend(packet)+1;
+ // command not cachable => no gap for data base name
+ if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1)))
+ break;
mysql_log.write(thd,command,"%s %s",table_list.real_name,fields);
remove_escape(table_list.real_name); // This can't have wildcards
@@ -879,56 +1026,65 @@ bool do_command(THD *thd)
error=TRUE; // End server
break;
- case COM_CREATE_DB:
+ case COM_CREATE_DB: // QQ: To be removed
{
- char *db=thd->strdup(packet+1);
thread_safe_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_thread_count);
+ char *db=thd->strdup(packet);
// null test to handle EOM
if (!db || !strip_sp(db) || check_db_name(db))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break;
}
+ if (lower_case_table_names)
+ casedn_str(db);
if (check_access(thd,CREATE_ACL,db,0,1))
break;
- mysql_log.write(thd,command,packet+1);
- mysql_create_db(thd,db,0);
+ mysql_log.write(thd,command,packet);
+ mysql_create_db(thd,db,0,0);
break;
}
- case COM_DROP_DB:
+ case COM_DROP_DB: // QQ: To be removed
{
- char *db=thd->strdup(packet+1);
thread_safe_increment(com_stat[SQLCOM_DROP_DB],&LOCK_thread_count);
+ char *db=thd->strdup(packet);
// null test to handle EOM
if (!db || !strip_sp(db) || check_db_name(db))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break;
}
- if (check_access(thd,DROP_ACL,db,0,1) || end_active_trans(thd))
+ if (lower_case_table_names)
+ casedn_str(db);
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
break;
+ }
mysql_log.write(thd,command,db);
- mysql_rm_db(thd,db,0);
+ mysql_rm_db(thd,db,0,0);
break;
}
case COM_BINLOG_DUMP:
{
thread_safe_increment(com_other,&LOCK_thread_count);
slow_command = TRUE;
- if(check_access(thd, FILE_ACL, any_db))
+ if (check_global_access(thd, REPL_SLAVE_ACL))
break;
mysql_log.write(thd,command, 0);
ulong pos;
ushort flags;
uint32 slave_server_id;
- pos = uint4korr(packet + 1);
- flags = uint2korr(packet + 5);
+ pos = uint4korr(packet);
+ flags = uint2korr(packet + 4);
pthread_mutex_lock(&LOCK_server_id);
- kill_zombie_dump_threads(slave_server_id = uint4korr(packet+7));
+ thd->server_id=0; /* avoid suicide */
+ kill_zombie_dump_threads(slave_server_id = uint4korr(packet+6));
thd->server_id = slave_server_id;
pthread_mutex_unlock(&LOCK_server_id);
- mysql_binlog_send(thd, thd->strdup(packet + 11), pos, flags);
+ mysql_binlog_send(thd, thd->strdup(packet + 10), pos, flags);
+ unregister_slave(thd,1,1);
// fake COM_QUIT -- if we get here, the thread needs to terminate
error = TRUE;
net->error = 0;
@@ -936,9 +1092,9 @@ bool do_command(THD *thd)
}
case COM_REFRESH:
{
- uint options=(uchar) packet[1];
thread_safe_increment(com_stat[SQLCOM_FLUSH],&LOCK_thread_count);
- if (check_access(thd,RELOAD_ACL,any_db))
+ ulong options= (ulong) (uchar) packet[0];
+ if (check_global_access(thd,RELOAD_ACL))
break;
mysql_log.write(thd,command,NullS);
if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0))
@@ -949,7 +1105,7 @@ bool do_command(THD *thd)
}
case COM_SHUTDOWN:
thread_safe_increment(com_other,&LOCK_thread_count);
- if (check_access(thd,SHUTDOWN_ACL,any_db))
+ if (check_global_access(thd,SHUTDOWN_ACL))
break; /* purecov: inspected */
DBUG_PRINT("quit",("Got shutdown command"));
mysql_log.write(thd,command,NullS);
@@ -963,6 +1119,7 @@ bool do_command(THD *thd)
close_connection(net);
close_thread_tables(thd); // Free before kill
free_root(&thd->mem_root,MYF(0));
+ free_root(&thd->transaction.mem_root,MYF(0));
kill_mysql();
error=TRUE;
break;
@@ -974,7 +1131,7 @@ bool do_command(THD *thd)
char buff[200];
ulong uptime = (ulong) (thd->start_time - start_time);
sprintf((char*) buff,
- "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %d Queries per second avg: %.3f",
+ "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %u Queries per second avg: %.3f",
uptime,
(int) thread_count,thd->query_id,long_query_count,
opened_tables,refresh_version, cached_tables(),
@@ -994,7 +1151,7 @@ bool do_command(THD *thd)
break;
case COM_PROCESS_INFO:
thread_safe_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_thread_count);
- if (!thd->priv_user[0] && check_process_priv(thd))
+ if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break;
mysql_log.write(thd,command,NullS);
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
@@ -1003,13 +1160,13 @@ bool do_command(THD *thd)
case COM_PROCESS_KILL:
{
thread_safe_increment(com_stat[SQLCOM_KILL],&LOCK_thread_count);
- ulong id=(ulong) uint4korr(packet+1);
+ ulong id=(ulong) uint4korr(packet);
kill_one_thread(thd,id);
break;
}
case COM_DEBUG:
thread_safe_increment(com_other,&LOCK_thread_count);
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
break; /* purecov: inspected */
mysql_print_status(thd);
mysql_log.write(thd,command,NullS);
@@ -1040,8 +1197,9 @@ bool do_command(THD *thd)
{
thd->proc_info="logging slow query";
- if ((ulong) (thd->start_time - thd->time_after_lock) > long_query_time ||
- ((thd->lex.options &
+ if ((ulong) (thd->start_time - thd->time_after_lock) >
+ thd->variables.long_query_time ||
+ ((thd->lex.select_lex.options &
(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED)) &&
(specialflag & SPECIAL_LONG_LOG_FORMAT)))
{
@@ -1056,7 +1214,7 @@ bool do_command(THD *thd)
thd->query=0;
thread_running--;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->packet.shrink(net_buffer_length); // Reclaim some memory
+ thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(error);
}
@@ -1072,33 +1230,47 @@ mysql_execute_command(void)
int res=0;
THD *thd=current_thd;
LEX *lex= &thd->lex;
- TABLE_LIST *tables=(TABLE_LIST*) lex->table_list.first;
+ TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
+ SELECT_LEX *select_lex = lex->select;
DBUG_ENTER("mysql_execute_command");
if (thd->slave_thread)
{
- // 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
- if(table_rules_on && tables && !tables_ok(thd,tables))
+ /*
+ 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
+ */
+ if (table_rules_on && tables && !tables_ok(thd,tables))
DBUG_VOID_RETURN;
- // this is a workaround to deal with the shortcoming
- // in 3.23.44-3.23.46 masters
- // in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK() as
- // DO RELEASE_LOCK()
+#ifndef TO_BE_DELETED
+ /*
+ This is a workaround to deal with the shortcoming in 3.23.44-3.23.46
+ masters in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK()
+ as DO RELEASE_LOCK()
+ */
if (lex->sql_command == SQLCOM_SELECT)
{
lex->sql_command = SQLCOM_DO;
- lex->insert_list = &lex->item_list;
+ lex->insert_list = &select_lex->item_list;
}
+#endif
}
+ /*
+ 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
+ */
+ if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) ||
+ (table_rules_on && tables && thd->slave_thread &&
+ !tables_ok(thd,tables)))
+ DBUG_VOID_RETURN;
+
thread_safe_increment(com_stat[lex->sql_command],&LOCK_thread_count);
switch (lex->sql_command) {
case SQLCOM_SELECT:
{
select_result *result;
- if (lex->options & SELECT_DESCRIBE)
+ if (select_lex->options & SELECT_DESCRIBE)
lex->exchange=0;
if (tables)
{
@@ -1116,10 +1288,12 @@ mysql_execute_command(void)
break; // Error message is given
}
- thd->offset_limit=lex->offset_limit;
- thd->select_limit=lex->select_limit+lex->offset_limit;
- if (thd->select_limit < lex->select_limit)
+ thd->offset_limit=select_lex->offset_limit;
+ thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
+ if (thd->select_limit < select_lex->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit
+ if (thd->select_limit == HA_POS_ERROR)
+ select_lex->options&= ~OPTION_FOUND_ROWS;
if (lex->exchange)
{
@@ -1144,8 +1318,8 @@ mysql_execute_command(void)
{
res= -1;
#ifdef DELETE_ITEMS
- delete lex->having;
- delete lex->where;
+ delete select_lex->having;
+ delete select_lex->where;
#endif
break;
}
@@ -1163,22 +1337,11 @@ mysql_execute_command(void)
if (!(res=open_and_lock_tables(thd,tables)))
{
- res=mysql_select(thd,tables,lex->item_list,
- lex->where,
- (ORDER*) lex->order_list.first,
- (ORDER*) lex->group_list.first,
- lex->having,
- (ORDER*) lex->proc_list.first,
- lex->options | thd->options,
- result);
- if (res)
- result->abort();
+ query_cache_store_query(thd, tables);
+ res=handle_select(thd, lex, result);
}
- delete result;
-#ifdef DELETE_ITEMS
- delete lex->having;
- delete lex->where;
-#endif
+ else
+ delete result;
break;
}
case SQLCOM_DO:
@@ -1190,52 +1353,84 @@ mysql_execute_command(void)
break;
case SQLCOM_PURGE:
- {
- if (check_process_priv(thd))
- goto error;
- res = purge_master_logs(thd, lex->to_log);
- break;
- }
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ res = purge_master_logs(thd, lex->to_log);
+ break;
+ }
+ case SQLCOM_SHOW_NEW_MASTER:
+ {
+ if (check_global_access(thd, REPL_SLAVE_ACL))
+ goto error;
+ res = show_new_master(thd);
+ break;
+ }
+ case SQLCOM_SHOW_SLAVE_HOSTS:
+ {
+ if (check_global_access(thd, REPL_SLAVE_ACL))
+ goto error;
+ res = show_slave_hosts(thd);
+ break;
+ }
+ case SQLCOM_SHOW_BINLOG_EVENTS:
+ {
+ if (check_global_access(thd, REPL_SLAVE_ACL))
+ goto error;
+ res = show_binlog_events(thd);
+ break;
+ }
case SQLCOM_BACKUP_TABLE:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd,SELECT_ACL, tables) ||
- check_access(thd, FILE_ACL, any_db))
- goto error; /* purecov: inspected */
- res = mysql_backup_table(thd, tables);
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL, tables) ||
+ check_global_access(thd, FILE_ACL))
+ goto error; /* purecov: inspected */
+ res = mysql_backup_table(thd, tables);
- break;
- }
+ break;
+ }
case SQLCOM_RESTORE_TABLE:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd,INSERT_ACL, tables) ||
- check_access(thd, FILE_ACL, any_db))
- goto error; /* purecov: inspected */
- res = mysql_restore_table(thd, tables);
- break;
- }
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd, INSERT_ACL, tables) ||
+ check_global_access(thd, FILE_ACL))
+ goto error; /* purecov: inspected */
+ res = mysql_restore_table(thd, tables);
+ break;
+ }
case SQLCOM_CHANGE_MASTER:
- {
- if(check_access(thd, PROCESS_ACL, any_db))
- goto error;
- res = change_master(thd);
- break;
- }
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ LOCK_ACTIVE_MI;
+ res = change_master(thd,active_mi);
+ UNLOCK_ACTIVE_MI;
+ break;
+ }
case SQLCOM_SHOW_SLAVE_STAT:
- {
- if (check_process_priv(thd))
- goto error;
- res = show_master_info(thd);
- break;
- }
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ LOCK_ACTIVE_MI;
+ res = show_master_info(thd,active_mi);
+ UNLOCK_ACTIVE_MI;
+ break;
+ }
case SQLCOM_SHOW_MASTER_STAT:
- {
- if (check_process_priv(thd))
- goto error;
- res = show_binlog_info(thd);
- break;
- }
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ res = show_binlog_info(thd);
+ break;
+ }
+
+ case SQLCOM_LOAD_MASTER_DATA: // sync with master
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ res = load_master_data(thd);
+ break;
+
#ifdef HAVE_INNOBASE_DB
case SQLCOM_SHOW_INNODB_STATUS:
{
@@ -1245,8 +1440,9 @@ mysql_execute_command(void)
break;
}
#endif
- case SQLCOM_LOAD_MASTER_TABLE:
+ case SQLCOM_LOAD_MASTER_TABLE:
+ {
if (!tables->db)
tables->db=thd->db;
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege))
@@ -1259,25 +1455,30 @@ mysql_execute_command(void)
bool error=check_grant(thd,CREATE_ACL,tables);
tables->next=tmp_table_list;
if (error)
- goto error;
+ goto error;
}
if (strlen(tables->name) > NAME_LEN)
{
net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->name);
break;
}
-
- thd->last_nx_table = tables->real_name;
- thd->last_nx_db = tables->db;
- if (fetch_nx_table(thd, &glob_mi))
- break; // fetch_nx_table did send the error to the client
- send_ok(&thd->net);
+ LOCK_ACTIVE_MI;
+ // fetch_master_table will send the error to the client on failure
+ if (!fetch_master_table(thd, tables->db, tables->real_name,
+ active_mi, 0))
+ {
+ send_ok(&thd->net);
+ }
+ UNLOCK_ACTIVE_MI;
break;
-
+ }
case SQLCOM_CREATE_TABLE:
+ {
+ ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
+ CREATE_TMP_ACL : CREATE_ACL);
if (!tables->db)
tables->db=thd->db;
- if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege) ||
+ if (check_access(thd,want_priv,tables->db,&tables->grant.privilege) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
@@ -1298,12 +1499,25 @@ mysql_execute_command(void)
res=0;
break;
}
- if (lex->item_list.elements) // With select
+#ifndef HAVE_READLINK
+ lex->create_info.data_file_name=lex->create_info.index_file_name=0;
+#else
+ /* Fix names if symlinked tables */
+ if (append_file_to_dir(thd, &lex->create_info.data_file_name,
+ tables->name) ||
+ append_file_to_dir(thd,&lex->create_info.index_file_name,
+ tables->name))
+ {
+ res=-1;
+ break;
+ }
+#endif
+ if (select_lex->item_list.elements) // With select
{
select_result *result;
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
- check_dup(thd,tables->db,tables->real_name,tables->next))
+ check_dup(tables->db, tables->real_name, tables->next))
{
net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN;
@@ -1316,31 +1530,22 @@ mysql_execute_command(void)
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
- thd->offset_limit=lex->offset_limit;
- thd->select_limit=lex->select_limit+lex->offset_limit;
- if (thd->select_limit < lex->select_limit)
+ thd->offset_limit=select_lex->offset_limit;
+ thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
+ if (thd->select_limit < select_lex->select_limit)
thd->select_limit= HA_POS_ERROR; // No limit
+ /* Skip first table, which is the table we are creating */
+ lex->select_lex.table_list.first=
+ (byte*) (((TABLE_LIST *) lex->select_lex.table_list.first)->next);
if (!(res=open_and_lock_tables(thd,tables->next)))
{
- if ((result=new select_create(tables->db ? tables->db : thd->db,
- tables->real_name, &lex->create_info,
- lex->create_list,
- lex->key_list,
- lex->item_list,lex->duplicates)))
- {
- res=mysql_select(thd,tables->next,lex->item_list,
- lex->where,
- (ORDER*) lex->order_list.first,
- (ORDER*) lex->group_list.first,
- lex->having,
- (ORDER*) lex->proc_list.first,
- lex->options | thd->options,
- result);
- if (res)
- result->abort();
- delete result;
- }
+ if ((result=new select_create(tables->db ? tables->db : thd->db,
+ tables->real_name, &lex->create_info,
+ lex->create_list,
+ lex->key_list,
+ select_lex->item_list,lex->duplicates)))
+ res=handle_select(thd, lex, result);
else
res= -1;
}
@@ -1355,6 +1560,7 @@ mysql_execute_command(void)
send_ok(&thd->net);
}
break;
+ }
case SQLCOM_CREATE_INDEX:
if (!tables->db)
tables->db=thd->db;
@@ -1369,19 +1575,26 @@ mysql_execute_command(void)
break;
case SQLCOM_SLAVE_START:
- start_slave(thd);
+ {
+ LOCK_ACTIVE_MI;
+ start_slave(thd,active_mi,1 /* net report*/);
+ UNLOCK_ACTIVE_MI;
break;
+ }
case SQLCOM_SLAVE_STOP:
- stop_slave(thd);
+ {
+ LOCK_ACTIVE_MI;
+ stop_slave(thd,active_mi,1/* net report*/);
+ UNLOCK_ACTIVE_MI;
break;
-
+ }
case SQLCOM_ALTER_TABLE:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
break;
#else
{
- uint priv=0;
+ ulong priv=0;
if (lex->name && strlen(lex->name) > NAME_LEN)
{
net_printf(&thd->net,ER_WRONG_TABLE_NAME,lex->name);
@@ -1390,10 +1603,10 @@ mysql_execute_command(void)
}
if (!tables->db)
tables->db=thd->db;
- if (!lex->db)
- lex->db=tables->db;
+ if (!select_lex->db)
+ select_lex->db=tables->db;
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
- check_access(thd,INSERT_ACL | CREATE_ACL,lex->db,&priv) ||
+ check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
@@ -1409,22 +1622,27 @@ mysql_execute_command(void)
TABLE_LIST tmp_table;
bzero((char*) &tmp_table,sizeof(tmp_table));
tmp_table.real_name=lex->name;
- tmp_table.db=lex->db;
+ tmp_table.db=select_lex->db;
tmp_table.grant.privilege=priv;
if (check_grant(thd,INSERT_ACL | CREATE_ACL,tables))
goto error;
}
}
+ /* Don't yet allow changing of symlinks with ALTER TABLE */
+ lex->create_info.data_file_name=lex->create_info.index_file_name=0;
/* ALTER TABLE ends previous transaction */
if (end_active_trans(thd))
res= -1;
else
- res= mysql_alter_table(thd, lex->db, lex->name,
+ {
+ res= mysql_alter_table(thd, select_lex->db, lex->name,
&lex->create_info,
tables, lex->create_list,
lex->key_list, lex->drop_list, lex->alter_list,
- (ORDER *) lex->order_list.first,
- lex->drop_primary, lex->duplicates);
+ (ORDER *) select_lex->order_list.first,
+ lex->drop_primary, lex->duplicates,
+ lex->alter_keys_onoff, lex->simple_alter);
+ }
break;
}
#endif
@@ -1448,11 +1666,12 @@ mysql_execute_command(void)
old_list.next=new_list.next=0;
if (check_grant(thd,ALTER_ACL,&old_list) ||
(!test_all_bits(table->next->grant.privilege,
- INSERT_ACL | CREATE_ACL) &&
+ INSERT_ACL | CREATE_ACL) &&
check_grant(thd,INSERT_ACL | CREATE_ACL, &new_list)))
goto error;
}
}
+ query_cache_invalidate3(thd, tables, 0);
if (end_active_trans(thd))
res= -1;
else if (mysql_rename_tables(thd,tables))
@@ -1465,7 +1684,7 @@ mysql_execute_command(void)
DBUG_VOID_RETURN;
#else
{
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
res = show_binlogs(thd);
break;
@@ -1486,21 +1705,21 @@ mysql_execute_command(void)
}
#endif
case SQLCOM_REPAIR:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
- goto error; /* purecov: inspected */
- res = mysql_repair_table(thd, tables, &lex->check_opt);
- break;
- }
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
+ goto error; /* purecov: inspected */
+ res = mysql_repair_table(thd, tables, &lex->check_opt);
+ break;
+ }
case SQLCOM_CHECK:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
- goto error; /* purecov: inspected */
- res = mysql_check_table(thd, tables, &lex->check_opt);
- break;
- }
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
+ goto error; /* purecov: inspected */
+ res = mysql_check_table(thd, tables, &lex->check_opt);
+ break;
+ }
case SQLCOM_ANALYZE:
{
if (check_db_used(thd,tables) ||
@@ -1542,23 +1761,85 @@ mysql_execute_command(void)
goto error;
if (grant_option && check_grant(thd,UPDATE_ACL,tables))
goto error;
- if (lex->item_list.elements != lex->value_list.elements)
+ if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
DBUG_VOID_RETURN;
}
- res = mysql_update(thd,tables,
- lex->item_list,
- lex->value_list,
- lex->where,
- lex->select_limit,
- lex->duplicates,
- lex->lock_option);
+ if (select_lex->table_list.elements == 1)
+ {
+ res = mysql_update(thd,tables,
+ select_lex->item_list,
+ lex->value_list,
+ select_lex->where,
+ (ORDER *) select_lex->order_list.first,
+ select_lex->select_limit,
+ lex->duplicates,
+ lex->lock_option);
#ifdef DELETE_ITEMS
- delete lex->where;
+ delete select_lex->where;
#endif
- break;
+ }
+ else
+ {
+ multi_update *result;
+ uint table_count;
+ TABLE_LIST *auxi;
+ const char *msg=0;
+
+ lex->sql_command=SQLCOM_MULTI_UPDATE;
+ for (auxi=(TABLE_LIST*) tables, table_count=0 ; auxi ; auxi=auxi->next)
+ {
+ table_count++;
+ auxi->lock_type=TL_WRITE;
+ }
+ if (select_lex->order_list.elements)
+ msg="ORDER BY";
+ else if (select_lex->select_limit && select_lex->select_limit !=
+ HA_POS_ERROR)
+ msg="LIMIT";
+
+ if (msg)
+ {
+ net_printf(&thd->net, ER_WRONG_USAGE, "UPDATE", msg);
+ res= 1;
+ break;
+ }
+ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
+ if ((res=open_and_lock_tables(thd,tables)))
+ break;
+ thd->select_limit=HA_POS_ERROR;
+ if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) &&
+ !setup_fields(thd,tables,lex->value_list,0,0,0) &&
+ ! thd->fatal_error &&
+ (result=new multi_update(thd,tables,select_lex->item_list,
+ lex->duplicates, lex->lock_option,
+ table_count)))
+ {
+ List <Item> total_list;
+ List_iterator <Item> field_list(select_lex->item_list);
+ List_iterator <Item> value_list(lex->value_list);
+ Item *item;
+ while ((item=field_list++))
+ total_list.push_back(item);
+ while ((item=value_list++))
+ total_list.push_back(item);
+
+ res=mysql_select(thd,tables,total_list,
+ select_lex->where,
+ (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
+ (ORDER *)NULL,
+ select_lex->options | thd->options |
+ SELECT_NO_JOIN_CACHE,
+ result);
+ delete result;
+ }
+ else
+ res= -1; // Error is not sent
+ close_thread_tables(thd);
+ }
+ break;
case SQLCOM_INSERT:
if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
@@ -1583,11 +1864,14 @@ mysql_execute_command(void)
case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT:
{
- // Check that we have modify privileges for the first table and
- // select privileges for the rest
+
+ /*
+ Check that we have modify privileges for the first table and
+ select privileges for the rest
+ */
{
- uint privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
- INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
+ ulong privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
+ INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
TABLE_LIST *save_next=tables->next;
tables->next=0;
if (check_access(thd, privilege,
@@ -1600,51 +1884,50 @@ mysql_execute_command(void)
}
select_result *result;
- thd->offset_limit=lex->offset_limit;
- thd->select_limit=lex->select_limit+lex->offset_limit;
- if (thd->select_limit < lex->select_limit)
+ thd->offset_limit=select_lex->offset_limit;
+ thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
+ if (thd->select_limit < select_lex->select_limit)
thd->select_limit= HA_POS_ERROR; // No limit
- if (check_dup(thd,tables->db,tables->real_name,tables->next))
+ if (check_dup(tables->db, tables->real_name, tables->next))
{
net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN;
}
- tables->lock_type=TL_WRITE; // update first table
+ tables->lock_type=TL_WRITE; // update first table
{
TABLE_LIST *table;
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
- if (!(res=open_and_lock_tables(thd,tables)))
+
+ /* Skip first table, which is the table we are inserting in */
+ lex->select_lex.table_list.first=
+ (byte*) (((TABLE_LIST *) lex->select_lex.table_list.first)->next);
+ if (!(res=open_and_lock_tables(thd, tables)))
{
if ((result=new select_insert(tables->table,&lex->field_list,
- lex->sql_command == SQLCOM_REPLACE_SELECT ?
- DUP_REPLACE : DUP_IGNORE)))
- {
- res=mysql_select(thd,tables->next,lex->item_list,
- lex->where,
- (ORDER*) lex->order_list.first,
- (ORDER*) lex->group_list.first,
- lex->having,
- (ORDER*) lex->proc_list.first,
- lex->options | thd->options,
- result);
- delete result;
- }
- else
- res= -1;
+ lex->duplicates)))
+ res=handle_select(thd,lex,result);
}
-#ifdef DELETE_ITEMS
- delete lex->having;
- delete lex->where;
-#endif
+ else
+ res= -1;
break;
}
case SQLCOM_TRUNCATE:
- lex->where=0;
- lex->select_limit=HA_POS_ERROR;
- /* Fall through */
+ if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
+ goto error; /* purecov: inspected */
+ /*
+ Don't allow this within a transaction because we want to use
+ re-generate table
+ */
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS);
+ goto error;
+ }
+ res=mysql_truncate(thd,tables);
+ break;
case SQLCOM_DELETE:
{
if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
@@ -1657,20 +1940,88 @@ mysql_execute_command(void)
if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
res= -1;
else
- res = mysql_delete(thd,tables,lex->where,lex->select_limit,
- lex->lock_option, lex->options);
+ res = mysql_delete(thd,tables, select_lex->where,
+ (ORDER*) select_lex->order_list.first,
+ select_lex->select_limit, lex->lock_option,
+ select_lex->options);
break;
}
- case SQLCOM_DROP_TABLE:
+ case SQLCOM_DELETE_MULTI:
+ {
+ TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first;
+ TABLE_LIST *auxi;
+ uint table_count=0;
+ multi_delete *result;
+
+ /* sql_yacc guarantees that tables and aux_tables are not zero */
+ if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
+ check_table_access(thd,SELECT_ACL, tables) ||
+ check_table_access(thd,DELETE_ACL, aux_tables))
+ goto error;
+ if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
+ {
+ send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
+ goto error;
+ }
+ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
{
- if (check_table_access(thd,DROP_ACL,tables))
- goto error; /* purecov: inspected */
- if (end_active_trans(thd))
- res= -1;
- else
- res = mysql_rm_table(thd,tables,lex->drop_if_exists);
+ table_count++;
+ /* All tables in aux_tables must be found in FROM PART */
+ TABLE_LIST *walk;
+ for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next)
+ {
+ if (!strcmp(auxi->real_name,walk->real_name) &&
+ !strcmp(walk->db,auxi->db))
+ break;
+ }
+ if (!walk)
+ {
+ net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name);
+ goto error;
+ }
+ auxi->lock_type=walk->lock_type=TL_WRITE;
+ auxi->table= (TABLE *) walk; // Remember corresponding table
+ }
+ if (add_item_to_list(new Item_null()))
+ {
+ res = -1;
+ break;
}
+ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
+ thd->proc_info="init";
+ if ((res=open_and_lock_tables(thd,tables)))
+ break;
+ /* Fix tables-to-be-deleted-from list to point at opened tables */
+ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
+ auxi->table= ((TABLE_LIST*) auxi->table)->table;
+ if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables,
+ lex->lock_option,
+ table_count)))
+ {
+ res=mysql_select(thd,tables,select_lex->item_list,
+ select_lex->where,
+ (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
+ (ORDER *)NULL,
+ select_lex->options | thd->options |
+ SELECT_NO_JOIN_CACHE,
+ result);
+ delete result;
+ }
+ else
+ res= -1; // Error is not sent
+ close_thread_tables(thd);
break;
+ }
+ case SQLCOM_DROP_TABLE:
+ {
+ if (check_table_access(thd,DROP_ACL,tables))
+ goto error; /* purecov: inspected */
+ if (end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_rm_table(thd,tables,lex->drop_if_exists);
+ }
+ break;
case SQLCOM_DROP_INDEX:
if (!tables->db)
tables->db=thd->db;
@@ -1685,49 +2036,42 @@ mysql_execute_command(void)
break;
case SQLCOM_SHOW_DATABASES:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
- send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
+ send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN;
#else
if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
- check_process_priv(thd))
+ check_global_access(thd, SHOW_DB_ACL))
goto error;
res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS));
break;
#endif
case SQLCOM_SHOW_PROCESSLIST:
- if (!thd->priv_user[0] && check_process_priv(thd))
+ if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break;
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
thd->priv_user,lex->verbose);
break;
case SQLCOM_SHOW_STATUS:
- res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars);
+ res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars,
+ OPT_GLOBAL);
break;
case SQLCOM_SHOW_VARIABLES:
res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS),
- init_vars);
+ init_vars, lex->option_type);
break;
case SQLCOM_SHOW_LOGS:
-#ifdef DONT_ALLOW_SHOW_COMMANDS
- send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
-#else
- {
- if (grant_option && check_access(thd, FILE_ACL, any_db))
- goto error;
- res= mysqld_show_logs(thd);
- break;
- }
-#endif
+ {
+ res= mysqld_show_logs(thd);
+ break;
+ }
case SQLCOM_SHOW_TABLES:
/* FALL THROUGH */
- case SQLCOM_SHOW_OPEN_TABLES:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN;
#else
{
- char *db=lex->db ? lex->db : thd->db;
+ char *db=select_lex->db ? select_lex->db : thd->db;
if (!db)
{
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
@@ -1742,34 +2086,32 @@ mysql_execute_command(void)
if (check_access(thd,SELECT_ACL,db,&thd->col_access))
goto error; /* purecov: inspected */
/* grant is checked in mysqld_show_tables */
- if (lex->sql_command == SQLCOM_SHOW_OPEN_TABLES)
- res= mysqld_show_open_tables(thd,db,
- (lex->wild ? lex->wild->ptr() : NullS));
- else if (lex->options & SELECT_DESCRIBE)
+ if (select_lex->options & SELECT_DESCRIBE)
res= mysqld_extend_show_tables(thd,db,
- (lex->wild ? lex->wild->ptr() : NullS));
+ (lex->wild ? lex->wild->ptr() : NullS));
else
res= mysqld_show_tables(thd,db,
(lex->wild ? lex->wild->ptr() : NullS));
break;
}
#endif
+ case SQLCOM_SHOW_OPEN_TABLES:
+ res= mysqld_show_open_tables(thd,(lex->wild ? lex->wild->ptr() : NullS));
+ break;
case SQLCOM_SHOW_FIELDS:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN;
#else
{
- char *db=tables->db ? tables->db : thd->db;
- if (!db)
+ char *db=tables->db;
+ if (!*db)
{
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
goto error; /* purecov: inspected */
}
remove_escape(db); // Fix escaped '_'
remove_escape(tables->name);
- if (!tables->db)
- tables->db=thd->db;
if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access))
goto error; /* purecov: inspected */
tables->grant.privilege=thd->col_access;
@@ -1787,7 +2129,7 @@ mysql_execute_command(void)
DBUG_VOID_RETURN;
#else
{
- char *db=tables->db ? tables->db : thd->db;
+ char *db=tables->db;
if (!db)
{
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
@@ -1807,7 +2149,7 @@ mysql_execute_command(void)
}
#endif
case SQLCOM_CHANGE_DB:
- mysql_change_db(thd,lex->db);
+ mysql_change_db(thd,select_lex->db);
break;
case SQLCOM_LOAD:
{
@@ -1828,7 +2170,7 @@ mysql_execute_command(void)
goto error;
}
if (check_access(thd,privilege,tables->db,&tables->grant.privilege) ||
- grant_option && check_grant(thd,privilege,tables))
+ grant_option && check_grant(thd,privilege,tables))
goto error;
}
res=mysql_load(thd, lex->exchange, tables, lex->field_list,
@@ -1836,44 +2178,11 @@ mysql_execute_command(void)
break;
}
case SQLCOM_SET_OPTION:
- {
- uint org_options=thd->options;
- thd->options=lex->options;
- thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ?
- TL_WRITE_LOW_PRIORITY : TL_WRITE);
- thd->default_select_limit=lex->select_limit;
- thd->tx_isolation=lex->tx_isolation;
- if (thd->gemini_spin_retries != lex->gemini_spin_retries)
- {
- thd->gemini_spin_retries= lex->gemini_spin_retries;
- ha_set_spin_retries(thd->gemini_spin_retries);
- }
- DBUG_PRINT("info",("options: %ld limit: %ld",
- thd->options,(long) thd->default_select_limit));
-
- /* Check if auto_commit mode changed */
- if ((org_options ^ lex->options) & OPTION_NOT_AUTO_COMMIT)
- {
- if ((org_options & OPTION_NOT_AUTO_COMMIT))
- {
- /* We changed to auto_commit mode */
- thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
- thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
- if (ha_commit(thd))
- {
- res= -1;
- break;
- }
- }
- else
- {
- thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
- thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
- }
- }
- send_ok(&thd->net);
+ if (sql_set_variables(thd, &lex->var_list))
+ res= -1;
+ else
+ send_ok(&thd->net);
break;
- }
case SQLCOM_UNLOCK_TABLES:
if (thd->locked_tables)
{
@@ -1886,13 +2195,7 @@ mysql_execute_command(void)
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
}
if (thd->global_read_lock)
- {
- thd->global_read_lock=0;
- pthread_mutex_lock(&LOCK_open);
- global_read_lock--;
- pthread_cond_broadcast(&COND_refresh);
- pthread_mutex_unlock(&LOCK_open);
- }
+ unlock_global_read_lock(thd);
send_ok(&thd->net);
break;
case SQLCOM_LOCK_TABLES:
@@ -1904,6 +2207,8 @@ mysql_execute_command(void)
}
if (check_db_used(thd,tables) || end_active_trans(thd))
goto error;
+ if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables))
+ goto error;
thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK;
if (!(res=open_and_lock_tables(thd,tables)))
@@ -1917,30 +2222,38 @@ mysql_execute_command(void)
thd->in_lock_tables=0;
break;
case SQLCOM_CREATE_DB:
+ {
+ if (!strip_sp(lex->name) || check_db_name(lex->name))
{
- 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,CREATE_ACL,lex->name,0,1))
- break;
- mysql_create_db(thd,lex->name,lex->create_info.options);
+ net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
break;
}
+ if (lower_case_table_names)
+ casedn_str(lex->name);
+ if (check_access(thd,CREATE_ACL,lex->name,0,1))
+ break;
+ res=mysql_create_db(thd,lex->name,lex->create_info.options,0);
+ break;
+ }
case SQLCOM_DROP_DB:
+ {
+ if (!strip_sp(lex->name) || check_db_name(lex->name))
{
- 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) ||
- end_active_trans(thd))
- break;
- mysql_rm_db(thd,lex->name,lex->drop_if_exists);
+ net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
break;
}
+ if (lower_case_table_names)
+ casedn_str(lex->name);
+ 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=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0);
+ break;
+ }
case SQLCOM_CREATE_FUNCTION:
if (check_access(thd,INSERT_ACL,"mysql",0,1))
break;
@@ -1961,81 +2274,88 @@ mysql_execute_command(void)
res= -1;
#endif
break;
- case SQLCOM_REVOKE:
- case SQLCOM_GRANT:
- {
- if (tables && !tables->db)
- tables->db=thd->db;
- if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
- tables && tables->db ? tables->db : lex->db,
- tables ? &tables->grant.privilege : 0,
- tables ? 0 : 1))
- goto error;
-
- /* Check that the user isn't trying to change a password for another
- user if he doesn't have UPDATE privilege to the MySQL database */
-
- if (thd->user) // If not replication
- {
- LEX_USER *user;
- List_iterator <LEX_USER> user_list(lex->users_list);
- while ((user=user_list++))
- {
- if (user->password.str &&
- (strcmp(thd->user,user->user.str) ||
- user->host.str &&
- my_strcasecmp(user->host.str, thd->host ? thd->host : thd->ip)))
- {
- if (check_access(thd, UPDATE_ACL, "mysql",0,1))
- goto error;
- break; // We are allowed to do changes
- }
- }
- }
- if (tables)
- {
- if (grant_option && check_grant(thd,
- (lex->grant | lex->grant_tot_col |
- GRANT_ACL),
- tables))
- goto error;
- res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
- lex->grant, lex->sql_command == SQLCOM_REVOKE);
- if(!res)
- {
- 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);
- }
- }
- }
- else
- {
- if (lex->columns.elements)
- {
- net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
- res=1;
- }
- else
- res = mysql_grant(thd, lex->db, lex->users_list, lex->grant,
- lex->sql_command == SQLCOM_REVOKE);
- if (!res)
- {
- 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);
- }
- }
- }
- break;
- }
+ case SQLCOM_REVOKE:
+ case SQLCOM_GRANT:
+ {
+ if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
+ tables && tables->db ? tables->db : select_lex->db,
+ tables ? &tables->grant.privilege : 0,
+ tables ? 0 : 1))
+ goto error;
+
+ /*
+ Check that the user isn't trying to change a password for another
+ user if he doesn't have UPDATE privilege to the MySQL database
+ */
+
+ if (thd->user) // If not replication
+ {
+ LEX_USER *user;
+ List_iterator <LEX_USER> user_list(lex->users_list);
+ while ((user=user_list++))
+ {
+ if (user->password.str &&
+ (strcmp(thd->user,user->user.str) ||
+ user->host.str &&
+ my_strcasecmp(user->host.str, thd->host_or_ip)))
+ {
+ if (check_access(thd, UPDATE_ACL, "mysql",0,1))
+ goto error;
+ break; // We are allowed to do changes
+ }
+ }
+ }
+ if (tables)
+ {
+ if (grant_option && check_grant(thd,
+ (lex->grant | lex->grant_tot_col |
+ GRANT_ACL),
+ tables))
+ goto error;
+ if (!(res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
+ lex->grant,
+ lex->sql_command == SQLCOM_REVOKE)))
+ {
+ 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);
+ }
+ }
+ }
+ else
+ {
+ if (lex->columns.elements)
+ {
+ send_error(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ res=1;
+ }
+ else
+ res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
+ lex->sql_command == SQLCOM_REVOKE);
+ if (!res)
+ {
+ 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 (mqh_used && lex->sql_command == SQLCOM_GRANT)
+ {
+ List_iterator <LEX_USER> str_list(lex->users_list);
+ LEX_USER *user;
+ while ((user=str_list++))
+ reset_mqh(thd,user);
+ }
+ }
+ }
+ break;
+ }
case SQLCOM_FLUSH:
case SQLCOM_RESET:
- if (check_access(thd,RELOAD_ACL,any_db) || check_db_used(thd, tables))
+ if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, tables))
goto error;
if (reload_acl_and_cache(thd, lex->type, tables))
send_error(&thd->net,0);
@@ -2047,13 +2367,40 @@ mysql_execute_command(void)
break;
case SQLCOM_SHOW_GRANTS:
res=0;
- if ((thd->priv_user && !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
+ if ((thd->priv_user &&
+ !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
!check_access(thd, SELECT_ACL, "mysql",0,1))
{
res = mysql_show_grants(thd,lex->grant_user);
}
break;
+ case SQLCOM_HA_OPEN:
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL, tables))
+ goto error;
+ res = mysql_ha_open(thd, tables);
+ break;
+ case SQLCOM_HA_CLOSE:
+ if (check_db_used(thd,tables))
+ goto error;
+ res = mysql_ha_close(thd, tables);
+ break;
+ case SQLCOM_HA_READ:
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL, tables))
+ goto error;
+ res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir,
+ lex->insert_list, lex->ha_rkey_mode, select_lex->where,
+ select_lex->select_limit, select_lex->offset_limit);
+ break;
+
case SQLCOM_BEGIN:
+ if (thd->locked_tables)
+ {
+ thd->lock=thd->locked_tables;
+ thd->locked_tables=0; // Will be automaticly closed
+ close_thread_tables(thd); // Free tables
+ }
if (end_active_trans(thd))
{
res= -1;
@@ -2072,13 +2419,17 @@ mysql_execute_command(void)
even if there is a problem with the OPTION_AUTO_COMMIT flag
(Which of course should never happen...)
*/
+ {
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_commit(thd))
+ {
send_ok(&thd->net);
+ }
else
res= -1;
break;
+ }
case SQLCOM_ROLLBACK:
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_rollback(thd))
@@ -2106,49 +2457,54 @@ error:
/****************************************************************************
-** Get the user (global) and database privileges for all used tables
-** Returns true (error) if we can't get the privileges and we don't use
-** table/column grants.
-** The idea of EXTRA_ACL is that one will be granted access to the table if
-** one has the asked privilege on any column combination of the table; For
-** example to be able to check a table one needs to have SELECT privilege on
-** any column of the table.
+ Get the user (global) and database privileges for all used tables
+ Returns true (error) if we can't get the privileges and we don't use
+ table/column grants.
+ The idea of EXTRA_ACL is that one will be granted access to the table if
+ one has the asked privilege on any column combination of the table; For
+ example to be able to check a table one needs to have SELECT privilege on
+ any column of the table.
****************************************************************************/
bool
-check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
- bool dont_check_global_grants)
+check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
+ bool dont_check_global_grants, bool no_errors)
{
- uint db_access,dummy;
+ DBUG_ENTER("check_access");
+ DBUG_PRINT("enter",("want_access: %lu master_access: %lu", want_access,
+ thd->master_access));
+ ulong db_access,dummy;
if (save_priv)
*save_priv=0;
else
save_priv= &dummy;
- if (!db && !thd->db && !dont_check_global_grants)
+ if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
{
- send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */
- return TRUE; /* purecov: tested */
+ if (!no_errors)
+ send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
if ((thd->master_access & want_access) == want_access)
{
*save_priv=thd->master_access;
- return FALSE;
+ DBUG_RETURN(FALSE);
}
- if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) ||
+ if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
! db && dont_check_global_grants)
{ // We can never grant this
- net_printf(&thd->net,ER_ACCESS_DENIED_ERROR,
- thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
- thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
- return TRUE; /* purecov: tested */
+ if (!no_errors)
+ net_printf(&thd->net,ER_ACCESS_DENIED_ERROR,
+ thd->priv_user,
+ thd->host_or_ip,
+ thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
if (db == any_db)
- return FALSE; // Allow select on anything
-
+ DBUG_RETURN(FALSE); // Allow select on anything
+
if (db && (!thd->db || strcmp(db,thd->db)))
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, db); /* purecov: inspected */
@@ -2162,30 +2518,41 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
if (db_access == want_access ||
((grant_option && !dont_check_global_grants) &&
!(want_access & ~TABLE_ACLS)))
- return FALSE; /* Ok */
- net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
- thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
- db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
- return TRUE; /* purecov: tested */
+ DBUG_RETURN(FALSE); /* Ok */
+ if (!no_errors)
+ net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
+ thd->priv_user,
+ thd->host_or_ip,
+ db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
-bool check_process_priv(THD *thd)
+/* check for global access and give descriptive error message if it fails */
+
+bool check_global_access(THD *thd, ulong want_access)
{
- return (check_access(thd ? thd : current_thd,PROCESS_ACL,any_db));
+ char command[128];
+ if ((thd->master_access & want_access) == want_access)
+ return 0;
+ get_privilege_desc(command, sizeof(command), want_access);
+ net_printf(&thd->net,ER_SPECIFIC_ACCESS_DENIED_ERROR,
+ command);
+ return 1;
}
/*
-** Check the privilege for all used tables. Table privileges are cached
-** in the table list for GRANT checking
+ Check the privilege for all used tables. Table privileges are cached
+ in the table list for GRANT checking
*/
bool
-check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
+check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
+ bool no_errors)
{
- uint found=0,found_access=0;
+ uint found=0;
+ ulong found_access=0;
TABLE_LIST *org_tables=tables;
for (; tables ; tables=tables->next)
{
@@ -2198,20 +2565,20 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
tables->grant.privilege=found_access;
else
{
- if (check_access(thd,want_access,tables->db,&tables->grant.privilege))
+ if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
+ 0, no_errors))
return TRUE; // Access denied
found_access=tables->grant.privilege;
found=1;
}
}
- else if (check_access(thd,want_access,tables->db,&tables->grant.privilege))
- return TRUE; // Access denied
+ else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
+ 0, no_errors))
+ return TRUE;
}
if (grant_option)
- {
- want_access &= ~EXTRA_ACL; // Remove SHOW attribute
- return check_grant(thd,want_access,org_tables);
- }
+ return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
+ test(want_access & EXTRA_ACL), no_errors);
return FALSE;
}
@@ -2315,40 +2682,79 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize)
/****************************************************************************
- Initialize global thd variables neaded for query
+ Initialize global thd variables needed for query
****************************************************************************/
static void
mysql_init_query(THD *thd)
{
DBUG_ENTER("mysql_init_query");
- thd->lex.item_list.empty();
+ thd->lex.select_lex.item_list.empty();
thd->lex.value_list.empty();
- thd->lex.table_list.elements=0;
- thd->free_list=0;
-
- thd->lex.table_list.first=0;
- thd->lex.table_list.next= (byte**) &thd->lex.table_list.first;
+ thd->lex.select_lex.table_list.elements=0;
+ thd->free_list=0; thd->lex.union_option=0;
+ thd->lex.select = &thd->lex.select_lex;
+ thd->lex.select_lex.table_list.first=0;
+ thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first;
+ thd->lex.select_lex.next=0;
+ thd->lex.olap=0;
+ thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE;
thd->fatal_error=0; // Safety
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
thd->sent_row_count=thd->examined_row_count=0;
+ thd->safe_to_cache_query=1;
DBUG_VOID_RETURN;
}
void
mysql_init_select(LEX *lex)
{
- lex->where=lex->having=0;
- lex->select_limit=current_thd->default_select_limit;
- lex->offset_limit=0L;
- lex->options=0;
+ SELECT_LEX *select_lex = lex->select;
+ select_lex->where=select_lex->having=0;
+ select_lex->select_limit= lex->thd->variables.select_limit;
+ select_lex->offset_limit=0;
+ select_lex->options=0;
+ select_lex->linkage=UNSPECIFIED_TYPE;
+ select_lex->olap= UNSPECIFIED_OLAP_TYPE;
lex->exchange = 0;
lex->proc_list.first=0;
- lex->order_list.elements=lex->group_list.elements=0;
- lex->order_list.first=0;
- lex->order_list.next= (byte**) &lex->order_list.first;
- lex->group_list.first=0;
- lex->group_list.next= (byte**) &lex->group_list.first;
+ select_lex->order_list.elements=select_lex->group_list.elements=0;
+ select_lex->order_list.first=0;
+ select_lex->order_list.next= (byte**) &select_lex->order_list.first;
+ select_lex->group_list.first=0;
+ select_lex->group_list.next= (byte**) &select_lex->group_list.first;
+ select_lex->next = (SELECT_LEX *)NULL;
+}
+
+
+bool
+mysql_new_select(LEX *lex)
+{
+ SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX));
+ if (!select_lex)
+ return 1;
+ lex->select->next=select_lex;
+ lex->select=select_lex;
+ select_lex->table_list.next= (byte**) &select_lex->table_list.first;
+ select_lex->item_list.empty();
+ select_lex->when_list.empty();
+ select_lex->expr_list.empty();
+ select_lex->interval_list.empty();
+ select_lex->use_index.empty();
+ select_lex->ftfunc_list.empty();
+ return 0;
+}
+
+
+void mysql_init_multi_delete(LEX *lex)
+{
+ lex->sql_command = SQLCOM_DELETE_MULTI;
+ mysql_init_select(lex);
+ lex->select->select_limit=lex->thd->select_limit=HA_POS_ERROR;
+ lex->auxilliary_table_list=lex->select_lex.table_list;
+ lex->select->table_list.elements=0;
+ lex->select->table_list.first=0;
+ lex->select->table_list.next= (byte**) &(lex->select->table_list.first);
}
@@ -2359,12 +2765,32 @@ mysql_parse(THD *thd,char *inBuf,uint length)
mysql_init_query(thd);
thd->query_length = length;
- LEX *lex=lex_start(thd, (uchar*) inBuf, length);
- if (!yyparse() && ! thd->fatal_error)
- mysql_execute_command();
- thd->proc_info="freeing items";
- free_items(thd); /* Free strings used by items */
- lex_end(lex);
+ if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
+ {
+ LEX *lex=lex_start(thd, (uchar*) inBuf, length);
+ if (!yyparse() && ! thd->fatal_error)
+ {
+ if (mqh_used && thd->user_connect &&
+ check_mqh(thd, thd->lex.sql_command))
+ {
+ thd->net.error = 0;
+ }
+ else
+ {
+ mysql_execute_command();
+ query_cache_end_of_result(&thd->net);
+ }
+ }
+ else
+ {
+ DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
+ thd->fatal_error));
+ query_cache_abort(&thd->net);
+ }
+ thd->proc_info="freeing items";
+ free_items(thd); /* Free strings used by items */
+ lex_end(lex);
+ }
DBUG_VOID_RETURN;
}
@@ -2474,6 +2900,7 @@ bool add_field_to_list(char *field_name, enum_field_types type,
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
case FIELD_TYPE_NULL:
+ case FIELD_TYPE_GEOMETRY:
break;
case FIELD_TYPE_DECIMAL:
if (!length)
@@ -2621,7 +3048,7 @@ bool add_field_to_list(char *field_name, enum_field_types type,
if (new_field->length >= MAX_FIELD_WIDTH ||
(!new_field->length && !(new_field->flags & BLOB_FLAG) &&
- type != FIELD_TYPE_STRING))
+ type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING))
{
net_printf(&thd->net,ER_TOO_BIG_FIELDLENGTH,field_name,
MAX_FIELD_WIDTH-1); /* purecov: inspected */
@@ -2672,6 +3099,8 @@ add_proc_to_list(Item *item)
static void remove_escape(char *name)
{
+ if (!*name) // For empty DB names
+ return;
char *to;
#ifdef USE_MB
char *strend=name+(uint) strlen(name);
@@ -2691,7 +3120,7 @@ static void remove_escape(char *name)
}
#endif
if (*name == '\\' && name[1])
- name++; // Skipp '\\'
+ name++; // Skip '\\'
*to++= *name;
}
*to=0;
@@ -2730,7 +3159,6 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
register TABLE_LIST *ptr;
THD *thd=current_thd;
char *alias_str;
- const char *current_db;
DBUG_ENTER("add_table_to_list");
if (!table)
@@ -2745,15 +3173,35 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
}
if (!alias) /* Alias is case sensitive */
- if (!(alias_str=sql_strmake(alias_str,table->table.length)))
+ if (!(alias_str=thd->memdup(alias_str,table->table.length+1)))
DBUG_RETURN(0);
- if (lower_case_table_names)
- casedn_str(table->table.str);
+
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(0); /* purecov: inspected */
- ptr->db= table->db.str;
- ptr->real_name=table->table.str;
+ if (table->db.str)
+ {
+ ptr->db= table->db.str;
+ ptr->db_length= table->db.length;
+ }
+ else if (thd->db)
+ {
+ ptr->db= thd->db;
+ ptr->db_length= thd->db_length;
+ }
+ else
+ {
+ ptr->db= (char*) "";
+ ptr->db_length= 0;
+ }
+
ptr->name=alias_str;
+ if (lower_case_table_names)
+ {
+ casedn_str(ptr->db);
+ casedn_str(table->table.str);
+ }
+ ptr->real_name=table->table.str;
+ ptr->real_name_length=table->table.length;
ptr->lock_type=flags;
ptr->updating=updating;
if (use_index)
@@ -2764,26 +3212,87 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
sizeof(*ignore_index));
/* check that used name is unique */
- current_db=thd->db ? thd->db : "";
-
if (flags != TL_IGNORE)
{
- for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.table_list.first ; tables ;
+ for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ;
+ tables ;
tables=tables->next)
{
- if (!strcmp(alias_str,tables->name) &&
- !strcmp(ptr->db ? ptr->db : current_db,
- tables->db ? tables->db : current_db))
+ if (!strcmp(alias_str,tables->name) && !strcmp(ptr->db, tables->db))
{
net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */
DBUG_RETURN(0); /* purecov: tested */
}
}
}
- link_in_list(&thd->lex.table_list,(byte*) ptr,(byte**) &ptr->next);
+ link_in_list(&thd->lex.select->table_list,(byte*) ptr,(byte**) &ptr->next);
DBUG_RETURN(ptr);
}
+
+/*
+** This is used for UNION to create a new table list of all used tables
+** The table_list->table entry in all used tables are set to point
+** to the entries in this list.
+*/
+
+static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
+{
+ /* Handle the case when we are not using union */
+ if (!lex->select_lex.next)
+ {
+ *result= (TABLE_LIST*) lex->select_lex.table_list.first;
+ return 0;
+ }
+
+ SELECT_LEX *sl;
+ TABLE_LIST **new_table_list= result, *aux;
+
+ *new_table_list=0; // end result list
+ for (sl= &lex->select_lex; sl; sl=sl->next)
+ {
+ if (sl->order_list.first && sl->next && !sl->braces)
+ {
+ net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
+ return 1;
+ }
+ if ((aux= (TABLE_LIST*) sl->table_list.first))
+ {
+ TABLE_LIST *next;
+ for (; aux; aux=next)
+ {
+ TABLE_LIST *cursor;
+ aux->do_redirect=true;
+ next= aux->next;
+ for (cursor= *result; cursor; cursor=cursor->next)
+ if (!strcmp(cursor->db,aux->db) &&
+ !strcmp(cursor->real_name,aux->real_name) &&
+ !strcmp(cursor->name, aux->name))
+ break;
+ if (!cursor)
+ {
+ /* Add not used table to the total table list */
+ aux->lock_type= lex->lock_option;
+ if (!(cursor = (TABLE_LIST *) thd->memdup((char*) aux,
+ sizeof(*aux))))
+ {
+ send_error(&thd->net,0);
+ return 1;
+ }
+ *new_table_list= cursor;
+ new_table_list= &cursor->next;
+ *new_table_list=0; // end result list
+ }
+ else
+ aux->shared=1; // Mark that it's used twice
+ aux->table=(TABLE *) cursor;
+ }
+ }
+ }
+ return 0;
+}
+
+
void add_join_on(TABLE_LIST *b,Item *expr)
{
if (!b->on_expr)
@@ -2803,27 +3312,27 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
/* Check if name is used in table list */
-static bool check_dup(THD *thd,const char *db,const char *name,
- TABLE_LIST *tables)
+static bool check_dup(const char *db, const char *name, TABLE_LIST *tables)
{
- const char *thd_db=thd->db ? thd->db : any_db;
for (; tables ; tables=tables->next)
- if (!strcmp(name,tables->real_name) &&
- !strcmp(db ? db : thd_db, tables->db ? tables->db : thd_db))
+ if (!strcmp(name,tables->real_name) && !strcmp(db,tables->db))
return 1;
return 0;
}
-bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
+bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
{
bool result=0;
select_errors=0; /* Write if more errors */
+ // TODO: figure out what's up with the commented out line below
// mysql_log.flush(); // Flush log
if (options & REFRESH_GRANT)
{
acl_reload();
grant_reload();
+ if (mqh_used)
+ reset_mqh(thd,(LEX_USER *) NULL,true);
}
if (options & REFRESH_LOG)
{
@@ -2834,12 +3343,23 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
if (ha_flush_logs())
result=1;
}
+#ifdef HAVE_QUERY_CACHE
+ if (options & REFRESH_QUERY_CACHE_FREE)
+ {
+ query_cache.pack(); // FLUSH QUERY CACHE
+ options &= ~REFRESH_QUERY_CACHE; //don't flush all cache, just free memory
+ }
+ if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
+ {
+ query_cache.flush(); // RESET QUERY CACHE
+ }
+#endif /*HAVE_QUERY_CACHE*/
if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
{
- if ((options & REFRESH_READ_LOCK) && thd && ! thd->global_read_lock)
+ if ((options & REFRESH_READ_LOCK) && thd)
{
- thd->global_read_lock=1;
- thread_safe_increment(global_read_lock,&LOCK_open);
+ if (lock_global_read_lock(thd))
+ return 1;
}
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
}
@@ -2850,11 +3370,25 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
if (options & REFRESH_THREADS)
flush_thread_cache();
if (options & REFRESH_MASTER)
- reset_master();
- if (options & REFRESH_SLAVE)
- reset_slave();
-
- return result;
+ if (reset_master(thd))
+ result=1;
+#ifdef OPENSSL
+ if (options & REFRESH_DES_KEY_FILE)
+ {
+ if (des_key_file)
+ result=load_des_key_file(des_key_file);
+ }
+#endif
+ if (options & REFRESH_SLAVE)
+ {
+ LOCK_ACTIVE_MI;
+ if (reset_slave(active_mi))
+ result=1;
+ UNLOCK_ACTIVE_MI;
+ }
+ if (options & REFRESH_USER_RESOURCES)
+ reset_mqh(thd,(LEX_USER *) NULL);
+ return result;
}
@@ -2868,10 +3402,10 @@ void kill_one_thread(THD *thd, ulong id)
{
if (tmp->thread_id == id)
{
- if ((thd->master_access & PROCESS_ACL) ||
+ if ((thd->master_access & SUPER_ACL) ||
!strcmp(thd->user,tmp->user))
{
- tmp->prepare_to_die();
+ tmp->awake(1 /*prepare to die*/);
error=0;
}
else
@@ -2900,3 +3434,54 @@ static void refresh_status(void)
pthread_mutex_unlock(&LOCK_status);
pthread_mutex_unlock(&THR_LOCK_keycache);
}
+
+
+ /* If pointer is not a null pointer, append filename to it */
+
+static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name)
+{
+ char buff[FN_REFLEN],*ptr, *end;
+ if (!*filename_ptr)
+ return 0; // nothing to do
+
+ /* Check that the filename is not too long and it's a hard path */
+ if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
+ !test_if_hard_path(*filename_ptr))
+ {
+ my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
+ return 1;
+ }
+ /* Fix is using unix filename format on dos */
+ strmov(buff,*filename_ptr);
+ end=convert_dirname(buff, *filename_ptr, NullS);
+ if (!(ptr=thd->alloc((uint) (end-buff)+(uint) strlen(table_name)+1)))
+ return 1; // End of memory
+ *filename_ptr=ptr;
+ strxmov(ptr,buff,table_name,NullS);
+ return 0;
+}
+
+/*
+ Check if the select is a simple select (not an union)
+
+ SYNOPSIS
+ check_simple_select()
+
+ RETURN VALUES
+ 0 ok
+ 1 error ; In this case the error messege is sent to the client
+*/
+
+bool check_simple_select()
+{
+ THD *thd= current_thd;
+ if (thd->lex.select != &thd->lex.select_lex)
+ {
+ char command[80];
+ strmake(command, thd->lex.yylval->symbol.str,
+ min(thd->lex.yylval->symbol.length, sizeof(command)-1));
+ net_printf(&thd->net, ER_CANT_USE_OPTION_HERE, command);
+ return 1;
+ }
+ return 0;
+}
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index a6614f3f3f6..305491c7346 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -31,19 +31,21 @@ static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
{
- bool error=1,cerror,got_all_locks=1;
+ bool error=1,got_all_locks=1;
TABLE_LIST *lock_table,*ren_table=0;
DBUG_ENTER("mysql_rename_tables");
-
- /* Avoid problems with a rename on a table that we have locked or
- if the user is trying to to do this in a transcation context */
+
+ /*
+ Avoid problems with a rename on a table that we have locked or
+ if the user is trying to to do this in a transcation context
+ */
if (thd->locked_tables || thd->active_transaction())
{
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0));
DBUG_RETURN(1);
}
-
+
VOID(pthread_mutex_lock(&LOCK_open));
for (lock_table=table_list ; lock_table ; lock_table=lock_table->next)
{
@@ -53,13 +55,13 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
if (got_lock)
got_all_locks=0;
}
-
+
if (!got_all_locks && wait_for_locked_table_names(thd,table_list))
goto end;
if (!(ren_table=rename_tables(thd,table_list,0)))
error=0;
-
+
end:
if (ren_table)
{
@@ -80,19 +82,14 @@ end:
for (table=table_list ;
table->next != ren_table ;
table=table->next->next) ;
- table=table->next->next; // Skipp error table
+ table=table->next->next; // Skip error table
/* Revert to old names */
rename_tables(thd, table, 1);
/* Note that lock_table == 0 here, so the unlock loop will work */
}
/* Lets hope this doesn't fail as the result will be messy */
- if ((cerror=ha_commit_rename(thd)))
- {
- my_error(ER_GET_ERRNO,MYF(0),cerror);
- error= 1;
- }
- else if (!error)
+ if (!error)
{
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
@@ -134,7 +131,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
if (!access(name,F_OK))
{
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),name);
- return ren_table; // This can't be skipped
+ DBUG_RETURN(ren_table); // This can't be skipped
}
sprintf(name,"%s/%s/%s%s",mysql_data_home,
ren_table->db,ren_table->real_name,
@@ -143,7 +140,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
if (!skip_error)
- return ren_table;
+ DBUG_RETURN(ren_table);
}
else if (mysql_rename_table(table_type,
ren_table->db, ren_table->real_name,
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 1940ff360c2..3e652a4d5a6 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,102 +15,118 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Sasha Pachev <sasha@mysql.com> is currently in charge of this file
-// Do not mess with it without his permission!
#include "mysql_priv.h"
#include "sql_repl.h"
#include "sql_acl.h"
#include "log_event.h"
-#include <thr_alarm.h>
+#include "mini_client.h"
#include <my_dir.h>
+#include <assert.h>
extern const char* any_db;
-extern pthread_handler_decl(handle_slave,arg);
-#ifndef DBUG_OFF
int max_binlog_dump_events = 0; // unlimited
bool opt_sporadic_binlog_dump_fail = 0;
static int binlog_dump_count = 0;
-#endif
+
+int check_binlog_magic(IO_CACHE* log, const char** errmsg)
+{
+ char magic[4];
+ DBUG_ASSERT(my_b_tell(log) == 0);
+
+ if (my_b_read(log, (byte*) magic, sizeof(magic)))
+ {
+ *errmsg = "I/O error reading the header from the binary log";
+ sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
+ log->error);
+ return 1;
+ }
+ if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
+ {
+ *errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL";
+ return 1;
+ }
+ return 0;
+}
static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
const char**errmsg)
{
- char header[LOG_EVENT_HEADER_LEN];
+ char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN];
memset(header, 0, 4); // when does not matter
header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
- char* p = strrchr(log_file_name, FN_LIBCHAR);
- // find the last slash
- if(p)
- p++;
- else
- p = log_file_name;
+ char* p = log_file_name+dirname_length(log_file_name);
uint ident_len = (uint) strlen(p);
- ulong event_len = ident_len + sizeof(header);
- int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
+ ulong event_len = ident_len + ROTATE_EVENT_OVERHEAD;
+ int4store(header + SERVER_ID_OFFSET, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
+ int2store(header + FLAGS_OFFSET, 0);
+
+ // TODO: check what problems this may cause and fix them
+ int4store(header + LOG_POS_OFFSET, 0);
+
packet->append(header, sizeof(header));
+ /* We need to split the next statement because of problem with cxx */
+ int4store(buf,4); // tell slave to skip magic number
+ int4store(buf+4,0);
+ packet->append(buf, ROTATE_HEADER_LEN);
packet->append(p,ident_len);
- if(my_net_write(net, (char*)packet->ptr(), packet->length()))
- {
- *errmsg = "failed on my_net_write()";
- return -1;
- }
+ if (my_net_write(net, (char*)packet->ptr(), packet->length()))
+ {
+ *errmsg = "failed on my_net_write()";
+ return -1;
+ }
return 0;
}
-
static int send_file(THD *thd)
{
NET* net = &thd->net;
int fd = -1,bytes, error = 1;
char fname[FN_REFLEN+1];
- char *buf;
const char *errmsg = 0;
int old_timeout;
uint packet_len;
+ char buf[IO_SIZE]; // It's safe to alloc this
DBUG_ENTER("send_file");
- // the client might be slow loading the data, give him wait_timeout to do
- // the job
- old_timeout = thd->net.timeout;
- thd->net.timeout = thd->inactive_timeout;
-
- // spare the stack
- if(!(buf = alloc_root(&thd->mem_root,IO_SIZE)))
- {
- errmsg = "Out of memory";
- goto err;
- }
-
- // we need net_flush here because the client will not know it needs to send
- // us the file name until it has processed the load event entry
+ /*
+ The client might be slow loading the data, give him wait_timeout to do
+ the job
+ */
+ old_timeout = thd->net.read_timeout;
+ thd->net.read_timeout = thd->variables.net_wait_timeout;
+
+ /*
+ We need net_flush here because the client will not know it needs to send
+ us the file name until it has processed the load event entry
+ */
if (net_flush(net) || (packet_len = my_net_read(net)) == packet_error)
{
- errmsg = "Failed reading file name";
+ errmsg = "while reading file name";
goto err;
}
- *((char*)net->read_pos + packet_len) = 0; // terminate with \0
- //for fn_format
- fn_format(fname, (char*)net->read_pos + 1, "", "", 4);
+ // terminate with \0 for fn_format
+ *((char*)net->read_pos + packet_len) = 0;
+ fn_format(fname, (char*) net->read_pos + 1, "", "", 4);
// this is needed to make replicate-ignore-db
if (!strcmp(fname,"/dev/null"))
goto end;
- if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0)
+ if ((fd = my_open(fname, O_RDONLY, MYF(0))) < 0)
{
- errmsg = "Failed on my_open()";
+ errmsg = "on open of file";
goto err;
}
- while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE,
- MYF(MY_WME))) > 0)
+ while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE, MYF(0))) > 0)
{
if (my_net_write(net, buf, bytes))
{
- errmsg = "Failed on my_net_write()";
+ errmsg = "while writing data to client";
goto err;
}
}
@@ -119,18 +135,18 @@ static int send_file(THD *thd)
if (my_net_write(net, "", 0) || net_flush(net) ||
(my_net_read(net) == packet_error))
{
- errmsg = "failed negotiating file transfer close";
+ errmsg = "while negotiating file transfer close";
goto err;
}
error = 0;
err:
- thd->net.timeout = old_timeout;
- if(fd >= 0)
- (void) my_close(fd, MYF(MY_WME));
+ thd->net.read_timeout = old_timeout;
+ if (fd >= 0)
+ (void) my_close(fd, MYF(0));
if (errmsg)
{
- sql_print_error("failed in send_file() : %s", errmsg);
+ sql_print_error("Failed in send_file() %s", errmsg);
DBUG_PRINT("error", (errmsg));
}
DBUG_RETURN(error);
@@ -138,61 +154,56 @@ static int send_file(THD *thd)
File open_binlog(IO_CACHE *log, const char *log_file_name,
- const char **errmsg)
+ const char **errmsg)
{
File file;
- char magic[4];
+ DBUG_ENTER("open_binlog");
+
if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
- MYF(MY_WME)))
+ MYF(MY_WME | MY_DONT_CHECK_FILESIZE)))
{
- *errmsg = "Could not open log file"; // This will not be sent
+ *errmsg = "Could not open log file"; // This will not be sent
goto err;
}
-
- if (my_b_read(log, (byte*) magic, sizeof(magic)))
- {
- *errmsg = "I/O error reading binlog magic number";
- goto err;
- }
- if (memcmp(magic, BINLOG_MAGIC, 4))
- {
- *errmsg = "Binlog has bad magic number, fire your magician";
+ if (check_binlog_magic(log,errmsg))
goto err;
- }
- return file;
+ DBUG_RETURN(file);
err:
- if (file > 0)
+ if (file >= 0)
+ {
my_close(file,MYF(0));
- end_io_cache(log);
- return -1;
+ end_io_cache(log);
+ }
+ DBUG_RETURN(-1);
}
void adjust_linfo_offsets(my_off_t purge_offset)
{
THD *tmp;
-
+
pthread_mutex_lock(&LOCK_thread_count);
I_List_iterator<THD> it(threads);
-
- while((tmp=it++))
- {
- LOG_INFO* linfo;
- if((linfo = tmp->current_linfo))
- {
- pthread_mutex_lock(&linfo->lock);
- // no big deal if we just started reading the log
- // nothing to adjust
- if(linfo->index_file_offset < purge_offset)
- linfo->fatal = (linfo->index_file_offset != 0);
- else
- linfo->index_file_offset -= purge_offset;
- pthread_mutex_unlock(&linfo->lock);
- }
- }
+ while ((tmp=it++))
+ {
+ LOG_INFO* linfo;
+ if ((linfo = tmp->current_linfo))
+ {
+ pthread_mutex_lock(&linfo->lock);
+ /* index file offset can be less that purge offset
+ only if we just started reading the index file. In that case
+ we have nothing to adjust
+ */
+ if (linfo->index_file_offset < purge_offset)
+ linfo->fatal = (linfo->index_file_offset != 0);
+ else
+ linfo->index_file_offset -= purge_offset;
+ pthread_mutex_unlock(&linfo->lock);
+ }
+ }
pthread_mutex_unlock(&LOCK_thread_count);
}
@@ -202,21 +213,21 @@ bool log_in_use(const char* log_name)
int log_name_len = strlen(log_name) + 1;
THD *tmp;
bool result = 0;
-
+
pthread_mutex_lock(&LOCK_thread_count);
I_List_iterator<THD> it(threads);
-
- while((tmp=it++))
+
+ while ((tmp=it++))
+ {
+ LOG_INFO* linfo;
+ if ((linfo = tmp->current_linfo))
{
- LOG_INFO* linfo;
- if((linfo = tmp->current_linfo))
- {
- pthread_mutex_lock(&linfo->lock);
- result = !memcmp(log_name, linfo->log_file_name, log_name_len);
- pthread_mutex_unlock(&linfo->lock);
- if(result) break;
- }
- }
+ pthread_mutex_lock(&linfo->lock);
+ result = !memcmp(log_name, linfo->log_file_name, log_name_len);
+ pthread_mutex_unlock(&linfo->lock);
+ if (result) break;
+ }
+ }
pthread_mutex_unlock(&LOCK_thread_count);
return result;
@@ -226,35 +237,35 @@ bool log_in_use(const char* log_name)
int purge_master_logs(THD* thd, const char* to_log)
{
char search_file_name[FN_REFLEN];
+ const char* errmsg = 0;
+
mysql_bin_log.make_log_name(search_file_name, to_log);
int res = mysql_bin_log.purge_logs(thd, search_file_name);
- const char* errmsg = 0;
- switch(res)
- {
- case 0: break;
- case LOG_INFO_EOF: errmsg = "Target log not found in binlog index"; break;
- case LOG_INFO_IO: errmsg = "I/O error reading log index file"; break;
- case LOG_INFO_INVALID: errmsg = "Server configuration does not permit \
+
+ switch(res) {
+ case 0: break;
+ case LOG_INFO_EOF: errmsg = "Target log not found in binlog index"; break;
+ case LOG_INFO_IO: errmsg = "I/O error reading log index file"; break;
+ case LOG_INFO_INVALID: errmsg = "Server configuration does not permit \
binlog purge"; break;
- case LOG_INFO_SEEK: errmsg = "Failed on fseek()"; break;
- case LOG_INFO_PURGE_NO_ROTATE: errmsg = "Cannot purge unrotatable log";
- break;
- case LOG_INFO_MEM: errmsg = "Out of memory"; break;
- case LOG_INFO_FATAL: errmsg = "Fatal error during purge"; break;
- case LOG_INFO_IN_USE: errmsg = "A purgeable log is in use, will not purge";
- break;
- default:
- errmsg = "Unknown error during purge"; break;
- }
-
- if(errmsg)
- {
- send_error(&thd->net, 0, errmsg);
- return 1;
- }
+ case LOG_INFO_SEEK: errmsg = "Failed on fseek()"; break;
+ case LOG_INFO_PURGE_NO_ROTATE: errmsg = "Cannot purge unrotatable log";
+ break;
+ case LOG_INFO_MEM: errmsg = "Out of memory"; break;
+ case LOG_INFO_FATAL: errmsg = "Fatal error during purge"; break;
+ case LOG_INFO_IN_USE: errmsg = "A purgeable log is in use, will not purge";
+ break;
+ default: errmsg = "Unknown error during purge"; break;
+ }
+
+ if (errmsg)
+ {
+ send_error(&thd->net, 0, errmsg);
+ return 1;
+ }
else
send_ok(&thd->net);
-
+
return 0;
}
@@ -272,7 +283,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
NET* net = &thd->net;
#ifndef DBUG_OFF
int left_events = max_binlog_dump_events;
-#endif
+#endif
DBUG_ENTER("mysql_binlog_send");
bzero((char*) &log,sizeof(log));
@@ -282,25 +293,25 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
errmsg = "Master failed COM_BINLOG_DUMP to test if slave can recover";
goto err;
}
-#endif
+#endif
- if(!mysql_bin_log.is_open())
+ if (!mysql_bin_log.is_open())
{
errmsg = "Binary log is not open";
goto err;
}
- if(!server_id_supplied)
- {
- errmsg = "Misconfigured master - server id was not set";
- goto err;
- }
-
+ if (!server_id_supplied)
+ {
+ errmsg = "Misconfigured master - server id was not set";
+ goto err;
+ }
+
if (log_ident[0])
mysql_bin_log.make_log_name(search_file_name, log_ident);
else
search_file_name[0] = 0;
-
+
linfo.index_file_offset = 0;
thd->current_linfo = &linfo;
@@ -315,20 +326,21 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
if (pos < 4)
{
- errmsg = "Client requested master to start repliction from impossible position.\n";
+ errmsg= "Client requested master to start replication from \
+impossible position";
goto err;
}
-
+
my_b_seek(&log, pos); // Seek will done on next read
packet->length(0);
- packet->append("\0", 1);
// we need to start a packet with something other than 255
// to distiquish it from error
+ packet->append("\0", 1);
- // tell the client log name with a fake rotate_event
// if we are at the start of the log
- if(pos == 4)
+ if (pos == 4)
{
+ // tell the client log name with a fake rotate_event
if (fake_rotate_event(net, packet, log_file_name, &errmsg))
goto err;
packet->length(0);
@@ -338,17 +350,17 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
while (!net->error && net->vio != 0 && !thd->killed)
{
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
-
+
while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
{
#ifndef DBUG_OFF
- if(max_binlog_dump_events && !left_events--)
+ if (max_binlog_dump_events && !left_events--)
{
net_flush(net);
errmsg = "Debugging binlog dump abort";
goto err;
}
-#endif
+#endif
if (my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
@@ -358,7 +370,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
(*packet)[LOG_EVENT_OFFSET+1] ));
if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
- if(send_file(thd))
+ if (send_file(thd))
{
errmsg = "failed in send_file()";
goto err;
@@ -367,15 +379,15 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
packet->length(0);
packet->append("\0",1);
}
-
+ // TODO: now that we are logging the offset, check to make sure
+ // the recorded offset and the actual match
if (error != LOG_READ_EOF)
{
- switch(error)
- {
- case LOG_READ_BOGUS:
+ switch(error) {
+ case LOG_READ_BOGUS:
errmsg = "bogus data in log event";
break;
- case LOG_READ_TOO_LARGE:
+ case LOG_READ_TOO_LARGE:
errmsg = "log event entry exceeded max_allowed_packet -\
increase max_allowed_packet on master";
break;
@@ -395,12 +407,12 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
goto err;
}
- if(!(flags & BINLOG_DUMP_NON_BLOCK) &&
+ if (!(flags & BINLOG_DUMP_NON_BLOCK) &&
mysql_bin_log.is_active(log_file_name))
+ {
// block until there is more data in the log
// unless non-blocking mode requested
- {
- if(net_flush(net))
+ if (net_flush(net))
{
errmsg = "failed on net_flush()";
goto err;
@@ -412,64 +424,56 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
// to signal us
{
log.error=0;
-
- // tell the kill thread how to wake us up
- thd->mysys_var->current_mutex = log_lock;
- thd->mysys_var->current_cond = &COND_binlog_update;
- const char* proc_info = thd->proc_info;
- thd->proc_info = "Slave connection: waiting for binlog update";
-
bool read_packet = 0, fatal_error = 0;
#ifndef DBUG_OFF
- if(max_binlog_dump_events && !left_events--)
+ if (max_binlog_dump_events && !left_events--)
{
net_flush(net);
errmsg = "Debugging binlog dump abort";
goto err;
}
-#endif
+#endif
// no one will update the log while we are reading
// now, but we'll be quick and just read one record
pthread_mutex_lock(log_lock);
- switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*) 0))
+ switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*)0))
{
case 0:
+ pthread_mutex_unlock(log_lock);
read_packet = 1;
// we read successfully, so we'll need to send it to the
// slave
break;
case LOG_READ_EOF:
- DBUG_PRINT("wait",("waiting for data on binary log"));
+ DBUG_PRINT("wait",("waiting for data in binary log"));
+ // wait_for_update unlocks the log lock - needed to avoid race
if (!thd->killed)
- pthread_cond_wait(&COND_binlog_update, log_lock);
+ mysql_bin_log.wait_for_update(thd);
+ else
+ pthread_mutex_unlock(log_lock);
+ DBUG_PRINT("wait",("binary log received update"));
break;
default:
+ pthread_mutex_unlock(log_lock);
fatal_error = 1;
break;
}
- pthread_mutex_unlock(log_lock);
-
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- thd->proc_info= proc_info;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
-
- if(read_packet)
+
+ if (read_packet)
{
thd->proc_info = "sending update to slave";
- if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
+ if (my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
goto err;
}
- if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
- if(send_file(thd))
+ if (send_file(thd))
{
errmsg = "failed in send_file()";
goto err;
@@ -481,7 +485,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
// we hit EOF pretty quick
}
- if(fatal_error)
+ if (fatal_error)
{
errmsg = "error reading log entry";
goto err;
@@ -494,8 +498,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
bool loop_breaker = 0;
// need this to break out of the for loop from switch
thd->proc_info = "switching to next log";
- switch(mysql_bin_log.find_next_log(&linfo))
- {
+ switch (mysql_bin_log.find_next_log(&linfo)) {
case LOG_INFO_EOF:
loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
break;
@@ -506,12 +509,12 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
goto err;
}
- if(loop_breaker)
+ if (loop_breaker)
break;
end_io_cache(&log);
(void) my_close(file, MYF(MY_WME));
-
+
// fake Rotate_log event just in case it did not make it to the log
// otherwise the slave make get confused about the offset
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 ||
@@ -525,22 +528,25 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
end_io_cache(&log);
(void)my_close(file, MYF(MY_WME));
-
+
send_eof(&thd->net);
thd->proc_info = "waiting to finalize termination";
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN;
+
err:
thd->proc_info = "waiting to finalize termination";
end_io_cache(&log);
pthread_mutex_lock(&LOCK_thread_count);
- // exclude iteration through thread list
- // this is needed for purge_logs() - it will iterate through
- // thread list and update thd->current_linfo->index_file_offset
- // this mutex will make sure that it never tried to update our linfo
- // after we return from this stack frame
+ /*
+ Exclude iteration through thread list
+ this is needed for purge_logs() - it will iterate through
+ thread list and update thd->current_linfo->index_file_offset
+ this mutex will make sure that it never tried to update our linfo
+ after we return from this stack frame
+ */
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
if (file >= 0)
@@ -549,126 +555,115 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
DBUG_VOID_RETURN;
}
-int start_slave(THD* thd , bool net_report)
+int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
{
- if(!thd) thd = current_thd;
- NET* net = &thd->net;
int slave_errno = 0;
- if (check_access(thd, PROCESS_ACL, any_db))
+ if (!thd) thd = current_thd;
+ NET* net = &thd->net;
+ int thread_mask;
+
+ if (check_access(thd, SUPER_ACL, any_db))
return 1;
- pthread_mutex_lock(&LOCK_slave);
- if(!slave_running)
- {
- if(init_master_info(&glob_mi))
- slave_errno = ER_MASTER_INFO;
- else if(server_id_supplied && *glob_mi.host)
- {
- pthread_t hThread;
- if(pthread_create(&hThread, &connection_attrib, handle_slave, 0))
- {
- slave_errno = ER_SLAVE_THREAD;
- }
- while(!slave_running) // slave might already be running by now
- pthread_cond_wait(&COND_slave_start, &LOCK_slave);
- }
- else
- slave_errno = ER_BAD_SLAVE;
- }
+ lock_slave_threads(mi); // this allows us to cleanly read slave_running
+ init_thread_mask(&thread_mask,mi,1 /* inverse */);
+ if (thd->lex.slave_thd_opt)
+ thread_mask &= thd->lex.slave_thd_opt;
+ if (thread_mask)
+ {
+ if (server_id_supplied && (!mi->inited || (mi->inited && *mi->host)))
+ slave_errno = start_slave_threads(0 /*no mutex */,
+ 1 /* wait for start */,
+ mi,
+ master_info_file,relay_log_info_file,
+ thread_mask);
+ else
+ slave_errno = ER_BAD_SLAVE;
+ }
else
slave_errno = ER_SLAVE_MUST_STOP;
-
- pthread_mutex_unlock(&LOCK_slave);
- if(slave_errno)
- {
- if(net_report) send_error(net, slave_errno);
- return 1;
- }
- else if(net_report)
+
+ unlock_slave_threads(mi);
+
+ if (slave_errno)
+ {
+ if (net_report)
+ send_error(net, slave_errno);
+ return 1;
+ }
+ else if (net_report)
send_ok(net);
return 0;
}
-int stop_slave(THD* thd, bool net_report )
+int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
{
- if(!thd) thd = current_thd;
- NET* net = &thd->net;
int slave_errno = 0;
-
- if (check_access(thd, PROCESS_ACL, any_db))
+ if (!thd) thd = current_thd;
+ NET* net = &thd->net;
+
+ if (check_access(thd, SUPER_ACL, any_db))
return 1;
+ thd->proc_info = "Killing slave";
+ int thread_mask;
+ lock_slave_threads(mi);
+ init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
+ if (thd->lex.slave_thd_opt)
+ thread_mask &= thd->lex.slave_thd_opt;
+ slave_errno = (thread_mask) ?
+ terminate_slave_threads(mi,thread_mask,
+ 1 /*skip lock */) : ER_SLAVE_NOT_RUNNING;
+ unlock_slave_threads(mi);
+ thd->proc_info = 0;
- pthread_mutex_lock(&LOCK_slave);
- if (slave_running)
+ if (slave_errno)
{
- abort_slave = 1;
- KICK_SLAVE;
- // do not abort the slave in the middle of a query, so we do not set
- // thd->killed for the slave thread
- thd->proc_info = "waiting for slave to die";
- while(slave_running)
- {
- /* there is a small chance that slave thread might miss the first
- alarm. To protect againts it, resend the signal until it reacts
- */
-
- struct timespec abstime;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time(NULL)+2;
- abstime.ts_nsec=0;
-#elif defined(__WIN__)
- abstime.tv_sec=time((time_t*) 0)+2;
- abstime.tv_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+2;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
- pthread_cond_timedwait(&COND_slave_stopped, &LOCK_slave, &abstime);
- if (slave_running)
- KICK_SLAVE;
- }
+ if (net_report)
+ send_error(net, slave_errno);
+ return 1;
}
- else
- slave_errno = ER_SLAVE_NOT_RUNNING;
-
- pthread_mutex_unlock(&LOCK_slave);
- thd->proc_info = 0;
-
- if(slave_errno)
- {
- if(net_report) send_error(net, slave_errno);
- return 1;
- }
- else if(net_report)
+ else if (net_report)
send_ok(net);
return 0;
}
-void reset_slave()
+int reset_slave(MASTER_INFO* mi)
{
MY_STAT stat_area;
char fname[FN_REFLEN];
- bool slave_was_running ;
-
- pthread_mutex_lock(&LOCK_slave);
- if((slave_was_running = slave_running))
- {
- pthread_mutex_unlock(&LOCK_slave);
- stop_slave(0,0);
- }
- else
- pthread_mutex_unlock(&LOCK_slave);
+ int restart_thread_mask = 0,error=0;
+ const char* errmsg=0;
+ DBUG_ENTER("reset_slave");
+
+ lock_slave_threads(mi);
+ init_thread_mask(&restart_thread_mask,mi,0 /* not inverse */);
+ if ((error=terminate_slave_threads(mi,restart_thread_mask,1 /*skip lock*/))
+ || (error=purge_relay_logs(&mi->rli,1 /*just reset*/,&errmsg)))
+ goto err;
- end_master_info(&glob_mi);
- fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
- if(my_stat(fname, &stat_area, MYF(0)))
- if(my_delete(fname, MYF(MY_WME)))
- return;
- if(slave_was_running)
- start_slave(0,0);
+ end_master_info(mi);
+ fn_format(fname, master_info_file, mysql_data_home, "", 4+32);
+ if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME)))
+ {
+ error=1;
+ goto err;
+ }
+ fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
+ if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME)))
+ {
+ error=1;
+ goto err;
+ }
+ if (restart_thread_mask)
+ error=start_slave_threads(0 /* mutex not needed */,
+ 1 /* wait for start*/,
+ mi,master_info_file,relay_log_info_file,
+ restart_thread_mask);
+ // TODO: fix error messages so they get to the client
+err:
+ unlock_slave_threads(mi);
+ DBUG_RETURN(error);
}
void kill_zombie_dump_threads(uint32 slave_server_id)
@@ -677,121 +672,273 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
I_List_iterator<THD> it(threads);
THD *tmp;
- while((tmp=it++))
+ while ((tmp=it++))
+ {
+ if (tmp->command == COM_BINLOG_DUMP &&
+ tmp->server_id == slave_server_id)
{
- if(tmp->command == COM_BINLOG_DUMP &&
- tmp->server_id == slave_server_id)
- {
- // here we do not call kill_one_thread()
- // it will be slow because it will iterate through the list
- // again. Plus it double-locks LOCK_thread_count, which
- // make safe_mutex complain and abort
- // so we just to our own thread murder
-
- thr_alarm_kill(tmp->real_id);
- tmp->killed = 1;
- tmp->mysys_var->abort = 1;
- pthread_mutex_lock(&tmp->mysys_var->mutex);
- if(tmp->mysys_var->current_cond)
- {
- pthread_mutex_lock(tmp->mysys_var->current_mutex);
- pthread_cond_broadcast(tmp->mysys_var->current_cond);
- pthread_mutex_unlock(tmp->mysys_var->current_mutex);
- }
- pthread_mutex_unlock(&tmp->mysys_var->mutex);
- }
- }
-
+ /*
+ Here we do not call kill_one_thread() as
+ it will be slow because it will iterate through the list
+ again. Plus it double-locks LOCK_tread_count, which
+ make safe_mutex complain and abort.
+ We just to do kill the thread ourselves.
+ */
+ tmp->awake(1/*prepare to die*/);
+ }
+ }
pthread_mutex_unlock(&LOCK_thread_count);
}
-int change_master(THD* thd)
+
+int change_master(THD* thd, MASTER_INFO* mi)
{
- bool slave_was_running;
+ int error=0,restart_thread_mask;
+ const char* errmsg=0;
+ bool need_relay_log_purge=1;
+ DBUG_ENTER("change_master");
+
// kill slave thread
- pthread_mutex_lock(&LOCK_slave);
- if((slave_was_running = slave_running))
- {
- abort_slave = 1;
- KICK_SLAVE;
- thd->proc_info = "waiting for slave to die";
- while(slave_running)
- pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done
- }
- pthread_mutex_unlock(&LOCK_slave);
+ lock_slave_threads(mi);
+ init_thread_mask(&restart_thread_mask,mi,0 /*not inverse*/);
+ if (restart_thread_mask &&
+ (error=terminate_slave_threads(mi,
+ restart_thread_mask,
+ 1 /*skip lock*/)))
+ {
+ send_error(&thd->net,error);
+ unlock_slave_threads(mi);
+ DBUG_RETURN(1);
+ }
thd->proc_info = "changing master";
LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
+ // TODO: see if needs re-write
+ if (init_master_info(mi,master_info_file,relay_log_info_file))
+ {
+ send_error(&thd->net, 0, "Could not initialize master info");
+ unlock_slave_threads(mi);
+ DBUG_RETURN(1);
+ }
- if(init_master_info(&glob_mi))
- {
- send_error(&thd->net, 0, "Could not initialize master info");
- return 1;
- }
-
- pthread_mutex_lock(&glob_mi.lock);
- if((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
- {
- // if we change host or port, we must reset the postion
- glob_mi.log_file_name[0] = 0;
- glob_mi.pos = 4; // skip magic number
- glob_mi.pending = 0;
- }
+ /* data lock not needed since we have already stopped the running threads,
+ and we have the hold on the run locks which will keep all threads that
+ could possibly modify the data structures from running
+ */
+ if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
+ {
+ // if we change host or port, we must reset the postion
+ mi->master_log_name[0] = 0;
+ mi->master_log_pos= BIN_LOG_HEADER_SIZE;
+ mi->rli.pending = 0;
+ }
- if(lex_mi->log_file_name)
- strmake(glob_mi.log_file_name, lex_mi->log_file_name,
- sizeof(glob_mi.log_file_name));
- if(lex_mi->pos)
+ if (lex_mi->log_file_name)
+ strmake(mi->master_log_name, lex_mi->log_file_name,
+ sizeof(mi->master_log_name));
+ if (lex_mi->pos)
{
- glob_mi.pos = lex_mi->pos;
- glob_mi.pending = 0;
+ mi->master_log_pos= lex_mi->pos;
+ mi->rli.pending = 0;
}
-
- if(lex_mi->host)
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+
+ if (lex_mi->host)
+ strmake(mi->host, lex_mi->host, sizeof(mi->host));
+ if (lex_mi->user)
+ strmake(mi->user, lex_mi->user, sizeof(mi->user));
+ if (lex_mi->password)
+ strmake(mi->password, lex_mi->password, sizeof(mi->password));
+ if (lex_mi->port)
+ mi->port = lex_mi->port;
+ if (lex_mi->connect_retry)
+ mi->connect_retry = lex_mi->connect_retry;
+
+ if (lex_mi->relay_log_name)
+ {
+ need_relay_log_purge = 0;
+ mi->rli.skip_log_purge=1;
+ strmake(mi->rli.relay_log_name,lex_mi->relay_log_name,
+ sizeof(mi->rli.relay_log_name)-1);
+ }
+
+ if (lex_mi->relay_log_pos)
+ {
+ need_relay_log_purge=0;
+ mi->rli.relay_log_pos=lex_mi->relay_log_pos;
+ }
+
+ flush_master_info(mi);
+ if (need_relay_log_purge)
+ {
+ mi->rli.skip_log_purge=0;
+ thd->proc_info="purging old relay logs";
+ if (purge_relay_logs(&mi->rli,0 /* not only reset, but also reinit*/,
+ &errmsg))
+ {
+ net_printf(&thd->net, 0, "Failed purging old relay logs: %s",errmsg);
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ const char* msg;
+ if (init_relay_log_pos(&mi->rli,0/*log already inited*/,
+ 0 /*pos already inited*/,
+ 0 /*no data lock*/,
+ &msg))
{
- strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host));
+ //Sasha: note that I had to change net_printf() to make this work
+ net_printf(&thd->net,0,"Failed initializing relay log position: %s",msg);
+ unlock_slave_threads(mi);
+ DBUG_RETURN(1);
}
- if(lex_mi->user)
- strmake(glob_mi.user, lex_mi->user, sizeof(glob_mi.user));
- if(lex_mi->password)
- strmake(glob_mi.password, lex_mi->password, sizeof(glob_mi.password));
- if(lex_mi->port)
- glob_mi.port = lex_mi->port;
- if(lex_mi->connect_retry)
- glob_mi.connect_retry = lex_mi->connect_retry;
-
- flush_master_info(&glob_mi);
- pthread_mutex_unlock(&glob_mi.lock);
+ }
+ mi->rli.master_log_pos = mi->master_log_pos;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ strmake(mi->rli.master_log_name,mi->master_log_name,
+ sizeof(mi->rli.master_log_name)-1);
+ if (!mi->rli.master_log_name[0]) // uninitialized case
+ mi->rli.master_log_pos=0;
+
+ pthread_mutex_lock(&mi->rli.data_lock);
+ mi->rli.abort_pos_wait = 1;
+ pthread_cond_broadcast(&mi->data_cond);
+ pthread_mutex_unlock(&mi->rli.data_lock);
+
thd->proc_info = "starting slave";
- if(slave_was_running)
- start_slave(0,0);
+ if (restart_thread_mask)
+ error=start_slave_threads(0 /* mutex not needed*/,
+ 1 /* wait for start*/,
+ mi,master_info_file,relay_log_info_file,
+ restart_thread_mask);
+ unlock_slave_threads(mi);
thd->proc_info = 0;
-
- send_ok(&thd->net);
- return 0;
+ if (error)
+ send_error(&thd->net,error);
+ else
+ send_ok(&thd->net);
+ DBUG_RETURN(0);
}
-void reset_master()
+int reset_master(THD* thd)
{
- if(!mysql_bin_log.is_open())
+ if (!mysql_bin_log.is_open())
{
my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG));
- return;
+ return 1;
}
+ return mysql_bin_log.reset_logs(thd);
+}
- LOG_INFO linfo;
- if (mysql_bin_log.find_first_log(&linfo, ""))
- return;
+int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
+ const char* log_file_name2, ulonglong log_pos2)
+{
+ int res;
+ if ((res = strcmp(log_file_name1, log_file_name2)))
+ return res;
+ if (log_pos1 > log_pos2)
+ return 1;
+ else if (log_pos1 == log_pos2)
+ return 0;
+ return -1;
+}
- for(;;)
+int show_binlog_events(THD* thd)
+{
+ DBUG_ENTER("show_binlog_events");
+ List<Item> field_list;
+ const char* errmsg = 0;
+ IO_CACHE log;
+ File file = -1;
+
+ Log_event::init_show_field_list(&field_list);
+ if (send_fields(thd, field_list, 1))
+ DBUG_RETURN(-1);
+
+ if (mysql_bin_log.is_open())
{
- my_delete(linfo.log_file_name, MYF(MY_WME));
- if (mysql_bin_log.find_next_log(&linfo))
- break;
+ LOG_INFO linfo;
+ char search_file_name[FN_REFLEN];
+ LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
+ uint event_count, limit_start, limit_end;
+ const char* log_file_name = lex_mi->log_file_name;
+ Log_event* ev;
+ my_off_t pos = lex_mi->pos;
+
+ limit_start = thd->lex.select->offset_limit;
+ limit_end = thd->lex.select->select_limit + limit_start;
+
+ if (log_file_name)
+ mysql_bin_log.make_log_name(search_file_name, log_file_name);
+ else
+ search_file_name[0] = 0;
+
+ linfo.index_file_offset = 0;
+ thd->current_linfo = &linfo;
+
+ if (mysql_bin_log.find_first_log(&linfo, search_file_name))
+ {
+ errmsg = "Could not find target log";
+ goto err;
+ }
+
+ if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
+ goto err;
+
+ if (pos < 4)
+ {
+ errmsg = "Invalid log position";
+ goto err;
+ }
+
+ pthread_mutex_lock(mysql_bin_log.get_log_lock());
+ my_b_seek(&log, pos);
+
+ for (event_count = 0;
+ (ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,0)); )
+ {
+ if (event_count >= limit_start &&
+ ev->net_send(thd, linfo.log_file_name, pos))
+ {
+ errmsg = "Net error";
+ delete ev;
+ pthread_mutex_unlock(mysql_bin_log.get_log_lock());
+ goto err;
+ }
+
+ pos = my_b_tell(&log);
+ delete ev;
+
+ if (++event_count >= limit_end)
+ break;
+ }
+
+ if (event_count < limit_end && log.error)
+ {
+ errmsg = "Wrong offset or I/O error";
+ pthread_mutex_unlock(mysql_bin_log.get_log_lock());
+ goto err;
+ }
+
+ pthread_mutex_unlock(mysql_bin_log.get_log_lock());
}
- mysql_bin_log.close(1); // exiting close
- my_delete(mysql_bin_log.get_index_fname(), MYF(MY_WME));
- mysql_bin_log.open(opt_bin_logname,LOG_BIN);
+err:
+ if (file >= 0)
+ {
+ end_io_cache(&log);
+ (void) my_close(file, MYF(MY_WME));
+ }
+
+ if (errmsg)
+ {
+ net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND,
+ "SHOW BINLOG EVENTS", errmsg);
+ DBUG_RETURN(1);
+ }
+
+ send_eof(&thd->net);
+ DBUG_RETURN(0);
}
int show_binlog_info(THD* thd)
@@ -803,36 +950,37 @@ int show_binlog_info(THD* thd)
field_list.push_back(new Item_empty_string("Binlog_do_db",20));
field_list.push_back(new Item_empty_string("Binlog_ignore_db",20));
- if(send_fields(thd, field_list, 1))
+ if (send_fields(thd, field_list, 1))
DBUG_RETURN(-1);
String* packet = &thd->packet;
packet->length(0);
- if(mysql_bin_log.is_open())
- {
- LOG_INFO li;
- mysql_bin_log.get_current_log(&li);
- int dir_len = dirname_length(li.log_file_name);
- net_store_data(packet, li.log_file_name + dir_len);
- net_store_data(packet, (longlong)li.pos);
- net_store_data(packet, &binlog_do_db);
- net_store_data(packet, &binlog_ignore_db);
- }
+ if (mysql_bin_log.is_open())
+ {
+ LOG_INFO li;
+ mysql_bin_log.get_current_log(&li);
+ int dir_len = dirname_length(li.log_file_name);
+ net_store_data(packet, li.log_file_name + dir_len);
+ net_store_data(packet, (longlong)li.pos);
+ net_store_data(packet, &binlog_do_db);
+ net_store_data(packet, &binlog_ignore_db);
+ }
else
- {
- net_store_null(packet);
- net_store_null(packet);
- net_store_null(packet);
- net_store_null(packet);
- }
+ {
+ net_store_null(packet);
+ net_store_null(packet);
+ net_store_null(packet);
+ net_store_null(packet);
+ }
- if(my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
+ if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
DBUG_RETURN(-1);
send_eof(&thd->net);
DBUG_RETURN(0);
}
+
int show_binlogs(THD* thd)
{
const char* errmsg = 0;
@@ -843,20 +991,20 @@ int show_binlogs(THD* thd)
String* packet = &thd->packet;
IO_CACHE io_cache;
uint length;
-
- if(!mysql_bin_log.is_open())
+
+ if (!mysql_bin_log.is_open())
{
errmsg = "binlog is not open";
goto err;
}
field_list.push_back(new Item_empty_string("Log_name", 128));
- if(send_fields(thd, field_list, 1))
+ if (send_fields(thd, field_list, 1))
{
sql_print_error("Failed in send_fields");
return 1;
}
-
+
mysql_bin_log.lock_index();
index_file = mysql_bin_log.get_index_file();
if (index_file < 0)
@@ -876,7 +1024,7 @@ int show_binlogs(THD* thd)
int dir_len = dirname_length(fname);
packet->length(0);
net_store_data(packet, fname + dir_len, length-dir_len);
- if(my_net_write(net, (char*) packet->ptr(), packet->length()))
+ if (my_net_write(net, (char*) packet->ptr(), packet->length()))
{
sql_print_error("Failed in my_net_write");
end_io_cache(&io_cache);
@@ -884,10 +1032,10 @@ int show_binlogs(THD* thd)
return 1;
}
}
-
+
mysql_bin_log.unlock_index();
end_io_cache(&io_cache);
- send_eof(net);
+ send_eof(net);
return 0;
err2:
@@ -898,5 +1046,34 @@ err:
return 1;
}
-
-
+int log_loaded_block(IO_CACHE* file)
+{
+ LOAD_FILE_INFO* lf_info;
+ uint block_len ;
+
+ /* file->request_pos contains position where we started last read */
+ char* buffer = (char*) file->request_pos;
+ if (!(block_len = (char*) file->read_end - (char*) buffer))
+ return 0;
+ lf_info = (LOAD_FILE_INFO*) file->arg;
+ if (lf_info->last_pos_in_file != HA_POS_ERROR &&
+ lf_info->last_pos_in_file >= file->pos_in_file)
+ return 0;
+ lf_info->last_pos_in_file = file->pos_in_file;
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, buffer, block_len);
+ mysql_bin_log.write(&a);
+ }
+ else
+ {
+ Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
+ lf_info->table_name, *lf_info->fields,
+ lf_info->handle_dup, buffer,
+ block_len);
+ mysql_bin_log.write(&c);
+ lf_info->wrote_create_file = 1;
+ DBUG_SYNC_POINT("debug_lock.created_file_event",10);
+ }
+ return 0;
+}
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index aa07d859aec..6770f8aa01a 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -1,39 +1,56 @@
-#ifndef SQL_REPL_H
-#define SQL_REPL_H
-
#include "slave.h"
+typedef struct st_slave_info
+{
+ uint32 server_id;
+ uint32 rpl_recovery_rank, master_id;
+ char host[HOSTNAME_LENGTH+1];
+ char user[USERNAME_LENGTH+1];
+ char password[HASH_PASSWORD_LENGTH+1];
+ uint16 port;
+ THD* thd;
+} SLAVE_INFO;
+
+extern my_bool opt_show_slave_auth_info, opt_old_rpl_compat;
extern char* master_host;
extern my_string opt_bin_logname, master_info_file;
-extern uint32 server_id;
extern bool server_id_supplied;
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
-#ifndef DBUG_OFF
extern int max_binlog_dump_events;
extern bool opt_sporadic_binlog_dump_fail;
-#endif
-#ifdef SIGNAL_WITH_VIO_CLOSE
-#define KICK_SLAVE { slave_thd->close_active_vio(); \
- thr_alarm_kill(slave_real_id); }
-#else
-#define KICK_SLAVE thr_alarm_kill(slave_real_id);
-#endif
+#define KICK_SLAVE(thd) thd->awake(0 /* do not prepare to die*/);
File open_binlog(IO_CACHE *log, const char *log_file_name,
- const char **errmsg);
+ const char **errmsg);
-int start_slave(THD* thd = 0, bool net_report = 1);
-int stop_slave(THD* thd = 0, bool net_report = 1);
-int change_master(THD* thd);
-void reset_slave();
-void reset_master();
+int start_slave(THD* thd, MASTER_INFO* mi, bool net_report);
+int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report);
+int change_master(THD* thd, MASTER_INFO* mi);
+int show_binlog_events(THD* thd);
+int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
+ const char* log_file_name2, ulonglong log_pos2);
+int reset_slave(MASTER_INFO* mi);
+int reset_master(THD* thd);
int purge_master_logs(THD* thd, const char* to_log);
bool log_in_use(const char* log_name);
void adjust_linfo_offsets(my_off_t purge_offset);
int show_binlogs(THD* thd);
extern int init_master_info(MASTER_INFO* mi);
void kill_zombie_dump_threads(uint32 slave_server_id);
+int check_binlog_magic(IO_CACHE* log, const char** errmsg);
+
+typedef struct st_load_file_info
+{
+ THD* thd;
+ sql_exchange* ex;
+ List <Item> *fields;
+ enum enum_duplicates handle_dup;
+ char* db;
+ char* table_name;
+ bool wrote_create_file;
+ my_off_t last_pos_in_file;
+} LOAD_FILE_INFO;
-#endif
+int log_loaded_block(IO_CACHE* file);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 939ec003aca..2f12d7d1012 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -41,13 +41,16 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
uint tables,COND *conds,table_map table_map);
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
+static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
+ table_map used_tables);
static void find_best_combination(JOIN *join,table_map rest_tables);
static void find_best(JOIN *join,table_map rest_tables,uint index,
double record_count,double read_time);
static uint cache_record_length(JOIN *join,uint index);
static double prev_record_reads(JOIN *join,table_map found_ref);
static bool get_best_combination(JOIN *join);
-static store_key *get_store_key(KEYUSE *keyuse, table_map used_tables,
+static store_key *get_store_key(THD *thd,
+ KEYUSE *keyuse, table_map used_tables,
KEY_PART_INFO *key_part, char *key_buff,
uint maybe_null);
static bool make_simple_join(JOIN *join,TABLE *tmp_table);
@@ -59,7 +62,7 @@ static void update_depend_map(JOIN *join);
static void update_depend_map(JOIN *join, ORDER *order);
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
bool *simple_order);
-static int return_zero_rows(select_result *res,TABLE_LIST *tables,
+static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
List<Item> &fields, bool send_row,
uint select_options, const char *info,
Item *having, Procedure *proc);
@@ -68,7 +71,7 @@ static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- uint options);
+ ulong options);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
static int sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records);
@@ -83,20 +86,23 @@ static int end_unique_update(JOIN *join,JOIN_TAB *join_tab,
static int end_write_group(JOIN *join, JOIN_TAB *join_tab,
bool end_of_records);
static int test_if_group_changed(List<Item_buff> &list);
-static int join_read_const_tables(JOIN *join);
+static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
static int join_read_system(JOIN_TAB *tab);
static int join_read_const(JOIN_TAB *tab);
static int join_read_key(JOIN_TAB *tab);
static int join_read_always_key(JOIN_TAB *tab);
+static int join_read_last_key(JOIN_TAB *tab);
static int join_no_more_records(READ_RECORD *info);
static int join_read_next(READ_RECORD *info);
static int join_init_quick_read_record(JOIN_TAB *tab);
static int test_if_quick_select(JOIN_TAB *tab);
static int join_init_read_record(JOIN_TAB *tab);
-static int join_init_read_first_with_key(JOIN_TAB *tab);
-static int join_init_read_next_with_key(READ_RECORD *info);
-static int join_init_read_last_with_key(JOIN_TAB *tab);
-static int join_init_read_prev_with_key(READ_RECORD *info);
+static int join_read_first(JOIN_TAB *tab);
+static int join_read_next(READ_RECORD *info);
+static int join_read_next_same(READ_RECORD *info);
+static int join_read_last(JOIN_TAB *tab);
+static int join_read_prev_same(READ_RECORD *info);
+static int join_read_prev(READ_RECORD *info);
static int join_ft_read_first(JOIN_TAB *tab);
static int join_ft_read_next(READ_RECORD *info);
static COND *make_cond_for_table(COND *cond,table_map table,
@@ -104,9 +110,8 @@ static COND *make_cond_for_table(COND *cond,table_map table,
static Item* part_of_refkey(TABLE *form,Field *field);
static uint find_shortest_key(TABLE *table, key_map usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
- ha_rows select_limit);
+ ha_rows select_limit, bool no_changes);
static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit);
-static bool fix_having(JOIN *join, Item **having);
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
Item *having);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
@@ -139,23 +144,70 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
static void init_sum_functions(Item_sum **func);
static bool update_sum_func(Item_sum **func);
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
- bool distinct);
-static void describe_info(THD *thd, const char *info);
+ bool distinct, const char *message=NullS);
+static void describe_info(JOIN *join, const char *info);
+
+/*
+ This handles SELECT with and without UNION
+*/
+
+int handle_select(THD *thd, LEX *lex, select_result *result)
+{
+ int res;
+ register SELECT_LEX *select_lex = &lex->select_lex;
+
+#ifdef DISABLED_UNTIL_REWRITTEN_IN_4_1
+ if (lex->olap)
+ {
+ SELECT_LEX *sl, *sl_next;
+ int error;
+ for (sl= &select_lex; sl; sl=sl_next)
+ {
+ sl_next=sl->next; // Save if sl->next changes
+ if (sl->olap != UNSPECIFIED_OLAP_TYPE)
+ {
+ if ((error=handle_olaps(lex,sl)))
+ return error;
+ lex->last_selects->next=sl_next;
+ }
+ }
+ lex->select = select_lex;
+ }
+#endif DISABLED_UNTIL_REWRITTEN_IN_4_1
+
+ if (select_lex->next)
+ res=mysql_union(thd,lex,result);
+ else
+ res=mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first,
+ select_lex->item_list,
+ select_lex->where,
+ (ORDER*) select_lex->order_list.first,
+ (ORDER*) select_lex->group_list.first,
+ select_lex->having,
+ (ORDER*) lex->proc_list.first,
+ select_lex->options | thd->options,
+ result);
+ if (res && result)
+ result->abort();
+ delete result;
+ return res;
+}
+
/*****************************************************************************
-** check fields, find best join, do the select and output fields.
-** mysql_select assumes that all tables are allready opened
+ Check fields, find best join, do the select and output fields.
+ mysql_select assumes that all tables are already opened
*****************************************************************************/
int
mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
- uint select_options,select_result *result)
+ ulong select_options,select_result *result)
{
TABLE *tmp_table;
- int error,tmp;
+ int error, tmp_error;
bool need_tmp,hidden_group_fields;
- bool simple_order,simple_group,no_order;
+ bool simple_order,simple_group,no_order, skip_sort_order;
Item::cond_result cond_value;
SQL_SELECT *select;
DYNAMIC_ARRAY keyuse;
@@ -163,6 +215,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
Procedure *procedure;
List<Item> all_fields(fields);
bool select_distinct;
+ SELECT_LEX *select_lex = &(thd->lex.select_lex);
+ SELECT_LEX *cur_sel = thd->lex.select;
DBUG_ENTER("mysql_select");
/* Check that all tables, fields, conds and order are ok */
@@ -170,13 +224,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
select_distinct=test(select_options & SELECT_DISTINCT);
tmp_table=0;
select=0;
- no_order=0;
+ no_order=skip_sort_order=0;
bzero((char*) &keyuse,sizeof(keyuse));
thd->proc_info="init";
thd->used_tables=0; // Updated by setup_fields
if (setup_tables(tables) ||
- setup_fields(thd,tables,fields,1,&all_fields) ||
+ setup_fields(thd,tables,fields,1,&all_fields,1) ||
setup_conds(thd,tables,&conds) ||
setup_order(thd,tables,fields,all_fields,order) ||
setup_group(thd,tables,fields,all_fields,group,&hidden_group_fields))
@@ -198,14 +252,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
and no GROUP BY.
TODO: Add check of calculation of GROUP functions and fields:
SELECT COUNT(*)+table.col1 from table1;
- */
+ */
join.table=0;
join.tables=0;
{
if (!group)
{
uint flag=0;
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item *item;
while ((item= it++))
{
@@ -274,12 +328,15 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
count_field_types(&join.tmp_table_param,all_fields,0);
join.const_tables=0;
join.having=0;
+ join.do_send_rows = 1;
join.group= group != 0;
+ join.row_limit= ((select_distinct || order || group) ? HA_POS_ERROR :
+ thd->select_limit);
#ifdef RESTRICTED_GROUP
if (join.sum_func_count && !group && (join.func_count || join.field_count))
{
- my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT));
+ my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
delete procedure;
DBUG_RETURN(-1);
}
@@ -315,7 +372,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (cond_value == Item::COND_FALSE || !thd->select_limit)
{ /* Impossible cond */
- error=return_zero_rows(result, tables, fields,
+ error=return_zero_rows(&join, result, tables, fields,
join.tmp_table_param.sum_func_count != 0 && !group,
select_options,"Impossible WHERE",having,
procedure);
@@ -331,7 +388,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
{
if (res < 0)
{
- error=return_zero_rows(result, tables, fields, !group,
+ error=return_zero_rows(&join, result, tables, fields, !group,
select_options,"No matching min/max row",
having,procedure);
delete procedure;
@@ -339,9 +396,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (select_options & SELECT_DESCRIBE)
{
- describe_info(thd,"Select tables optimized away");
+ describe_info(&join, "Select tables optimized away");
delete procedure;
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
tables=0; // All tables resolved
}
@@ -350,13 +407,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
{ // Only test of functions
error=0;
if (select_options & SELECT_DESCRIBE)
- describe_info(thd,"No tables used");
+ describe_info(&join, "No tables used");
else
{
result->send_fields(fields,1);
if (!having || having->val_int())
{
- if (result->send_data(fields))
+ if (join.do_send_rows && result->send_data(fields))
{
result->send_error(0,NullS); /* purecov: inspected */
error=1;
@@ -368,7 +425,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
error=(int) result->send_eof();
}
delete procedure;
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
error = -1;
@@ -376,28 +433,28 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
/* Calculate how to do the join */
thd->proc_info="statistics";
- if (make_join_statistics(&join,tables,conds,&keyuse) ||
- thd->fatal_error)
+ if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error)
goto err;
thd->proc_info="preparing";
- if ((tmp=join_read_const_tables(&join)) > 0)
- goto err;
- if (tmp && !(select_options & SELECT_DESCRIBE))
+ result->initialize_tables(&join);
+ if (join.const_table_map != join.found_const_table_map &&
+ !(select_options & SELECT_DESCRIBE))
{
- error=return_zero_rows(result,tables,fields,
+ error=return_zero_rows(&join,result,tables,fields,
join.tmp_table_param.sum_func_count != 0 &&
!group,0,"",having,procedure);
goto err;
}
if (!(thd->options & OPTION_BIG_SELECTS) &&
- join.best_read > (double) thd->max_join_size &&
+ join.best_read > (double) thd->variables.max_join_size &&
!(select_options & SELECT_DESCRIBE))
{ /* purecov: inspected */
result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */
error= 1; /* purecov: inspected */
goto err; /* purecov: inspected */
}
- if (join.const_tables && !thd->locked_tables)
+ if (join.const_tables && !thd->locked_tables &&
+ !(select_options & SELECT_NO_UNLOCK))
{
TABLE **table, **end;
for (table=join.table, end=table + join.const_tables ;
@@ -428,7 +485,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (make_join_select(&join,select,conds))
{
- error=return_zero_rows(result,tables,fields,
+ error=return_zero_rows(&join, result, tables, fields,
join.tmp_table_param.sum_func_count != 0 && !group,
select_options,
"Impossible WHERE noticed after reading const tables",
@@ -446,7 +503,12 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
select_distinct=0;
}
else if (select_distinct && join.tables - join.const_tables == 1 &&
- (order || thd->select_limit == HA_POS_ERROR))
+ (thd->select_limit == HA_POS_ERROR ||
+ (join.select_options & OPTION_FOUND_ROWS) ||
+ order &&
+ !(skip_sort_order=
+ test_if_skip_sort_order(&join.join_tab[join.const_tables],
+ order, thd->select_limit,1))))
{
if ((group=create_distinct_group(order,fields)))
{
@@ -477,7 +539,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
(!group && join.tmp_table_param.sum_func_count))
order=0;
- // Can't use sort on head table if using cache
+ // Can't use sort on head table if using row cache
if (join.full_join)
{
if (group)
@@ -486,19 +548,33 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
simple_order=0;
}
+ /*
+ Check if we need to create a temporary table.
+ This has to be done if all tables are not already read (const tables)
+ and one of the following conditions holds:
+ - We are using DISTINCT (simple distinct's are already optimized away)
+ - We are using an ORDER BY or GROUP BY on fields not in the first table
+ - We are using different ORDER BY and GROUP BY orders
+ - The user wants us to buffer the result.
+ */
need_tmp= (join.const_tables != join.tables &&
((select_distinct || !simple_order || !simple_group) ||
- (group && order) ||
+ (group && order) ||
test(select_options & OPTION_BUFFER_RESULT)));
- make_join_readinfo(&join, (select_options & SELECT_DESCRIBE) |
- (thd->lex.ftfunc_list.elements ? 0 : SELECT_USE_CACHE)); // No cache for MATCH
-
- /* Need to tell Innobase that to play it safe, it should fetch all
- columns of the tables: this is because MySQL
- may build row pointers for the rows, and for all columns of the primary
- key the field->query_id has not necessarily been set to thd->query_id
- by MySQL. */
+ // No cache for MATCH
+ make_join_readinfo(&join,
+ (select_options & (SELECT_DESCRIBE |
+ SELECT_NO_JOIN_CACHE)) |
+ (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE :
+ 0));
+ /*
+ Need to tell Innobase that to play it safe, it should fetch all
+ columns of the tables: this is because MySQL may build row
+ pointers for the rows, and for all columns of the primary key the
+ field->query_id has not necessarily been set to thd->query_id by
+ MySQL.
+ */
#ifdef HAVE_INNOBASE_DB
if (need_tmp || select_distinct || group || order)
@@ -506,7 +582,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
for (uint i_h = join.const_tables; i_h < join.tables; i_h++)
{
TABLE* table_h = join.join_tab[i_h].table;
- if (table_h->db_type == DB_TYPE_INNOBASE)
+ if (table_h->db_type == DB_TYPE_INNODB)
table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE);
}
}
@@ -531,7 +607,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
((group && join.const_tables != join.tables &&
(!simple_group ||
!test_if_skip_sort_order(&join.join_tab[join.const_tables], group,
- HA_POS_ERROR))) ||
+ thd->select_limit,0))) ||
select_distinct) &&
join.tmp_table_param.quick_group && !procedure)
{
@@ -546,19 +622,19 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
(join.const_tables == join.tables ||
(simple_order &&
test_if_skip_sort_order(&join.join_tab[join.const_tables], order,
- (group ? HA_POS_ERROR :
- thd->select_limit)))))
+ (join.const_tables != join.tables - 1 ||
+ (join.select_options & OPTION_FOUND_ROWS)) ?
+ HA_POS_ERROR : thd->select_limit,0))))
order=0;
select_describe(&join,need_tmp,
- (order != 0 &&
- (!need_tmp || order != group || simple_group)),
+ order != 0 && !skip_sort_order,
select_distinct);
error=0;
goto err;
}
/* Perform FULLTEXT search before all regular searches */
- init_ftfuncs(thd, test(order));
+ init_ftfuncs(thd,test(order));
/* Create a tmp table if distinct or if the sort is too complicated */
if (need_tmp)
@@ -573,7 +649,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
group : (ORDER*) 0),
group ? 0 : select_distinct,
group && simple_group,
- order == 0,
+ (order == 0 || skip_sort_order) &&
+ !(join.select_options & OPTION_FOUND_ROWS),
join.select_options)))
goto err; /* purecov: inspected */
@@ -623,12 +700,22 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
break;
join_tab->not_used_in_distinct=1;
} while (join_tab-- != join.join_tab);
+ /* Optimize "select distinct b from t1 order by key_part_1 limit #" */
+ if (order && skip_sort_order)
+ {
+ (void) test_if_skip_sort_order(&join.join_tab[join.const_tables],
+ order, thd->select_limit,0);
+ order=0;
+ }
}
/* Copy data to the temporary table */
thd->proc_info="Copying to tmp table";
- if (do_select(&join,(List<Item> *) 0,tmp_table,0))
+ if ((tmp_error=do_select(&join,(List<Item> *) 0,tmp_table,0)))
+ {
+ error=tmp_error;
goto err; /* purecov: inspected */
+ }
if (join.having)
join.having=having=0; // Allready done
@@ -658,11 +745,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
/*
- ** If we have different sort & group then we must sort the data by group
- ** and copy it to another tmp table
- ** This code is also used if we are using distinct something
- ** we haven't been able to store in the temporary table yet
- ** like SEC_TO_TIME(SUM(...)).
+ If we have different sort & group then we must sort the data by group
+ and copy it to another tmp table
+ This code is also used if we are using distinct something
+ we haven't been able to store in the temporary table yet
+ like SEC_TO_TIME(SUM(...)).
*/
if (group && (!test_if_subpart(group,order) || select_distinct) ||
@@ -701,9 +788,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
group=0;
}
thd->proc_info="Copying to group table";
+ tmp_error= -1;
if (make_sum_func_list(&join,all_fields) ||
- do_select(&join,(List<Item> *) 0,tmp_table2,0))
+ (tmp_error=do_select(&join,(List<Item> *) 0,tmp_table2,0)))
{
+ error=tmp_error;
free_tmp_table(thd,tmp_table2);
goto err; /* purecov: inspected */
}
@@ -750,7 +839,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
(procedure && (procedure->flags & PROC_GROUP)))
{
alloc_group_fields(&join,group);
- setup_copy_fields(&join.tmp_table_param,all_fields);
+ setup_copy_fields(thd, &join.tmp_table_param,all_fields);
if (make_sum_func_list(&join,all_fields) || thd->fatal_error)
goto err; /* purecov: inspected */
}
@@ -761,13 +850,34 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
/* If we have already done the group, add HAVING to sorted table */
if (having && ! group && ! join.sort_and_group)
{
- if (fix_having(&join,&having))
- goto err;
+ having->update_used_tables(); // Some tables may have been const
+ JOIN_TAB *table=&join.join_tab[join.const_tables];
+ table_map used_tables= join.const_table_map | table->table->map;
+
+ Item* sort_table_cond=make_cond_for_table(having,used_tables,used_tables);
+ if (sort_table_cond)
+ {
+ if (!table->select)
+ if (!(table->select=new SQL_SELECT))
+ goto err;
+ if (!table->select->cond)
+ table->select->cond=sort_table_cond;
+ else // This should never happen
+ if (!(table->select->cond=new Item_cond_and(table->select->cond,
+ sort_table_cond)))
+ goto err;
+ table->select_cond=table->select->cond;
+ DBUG_EXECUTE("where",print_where(table->select->cond,
+ "select and having"););
+ having=make_cond_for_table(having,~ (table_map) 0,~used_tables);
+ DBUG_EXECUTE("where",print_where(conds,"having after sort"););
+ }
}
if (create_sort_index(&join.join_tab[join.const_tables],
group ? group : order,
(having || group ||
- join.const_tables != join.tables - 1) ?
+ join.const_tables != join.tables - 1 ||
+ (join.select_options & OPTION_FOUND_ROWS)) ?
HA_POS_ERROR : thd->select_limit))
goto err; /* purecov: inspected */
}
@@ -776,7 +886,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
error=do_select(&join,&fields,NULL,procedure);
err:
- thd->examined_row_count=join.examined_rows;
+ thd->limit_found_rows = join.send_records;
+ thd->examined_row_count = join.examined_rows;
thd->proc_info="end";
join.lock=0; // It's faster to unlock later
join_free(&join);
@@ -792,12 +903,12 @@ err:
}
/*****************************************************************************
-** Create JOIN_TABS, make a guess about the table types,
-** Approximate how many records will be used in each table
+ Create JOIN_TABS, make a guess about the table types,
+ Approximate how many records will be used in each table
*****************************************************************************/
static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
- key_map keys)
+ key_map keys,ha_rows limit)
{
int error;
DBUG_ENTER("get_quick_record_count");
@@ -805,7 +916,7 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
{
select->head=table;
table->reginfo.impossible_range=0;
- if ((error=select->test_quick_select(keys,(table_map) 0,HA_POS_ERROR))
+ if ((error=select->test_quick_select(keys,(table_map) 0,limit))
== 1)
DBUG_RETURN(select->quick->records);
if (error == -1)
@@ -825,7 +936,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
{
int error;
uint i,table_count,const_count,found_ref,refs,key,const_ref,eq_part;
- table_map const_table_map,all_table_map;
+ table_map const_table_map,found_const_table_map,all_table_map;
TABLE **table_vector;
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
SQL_SELECT *select;
@@ -845,7 +956,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
join->best_ref=stat_vector;
stat_end=stat+table_count;
- const_table_map=all_table_map=0;
+ const_table_map=found_const_table_map=all_table_map=0;
const_count=0;
for (s=stat,i=0 ; tables ; s++,tables=tables->next,i++)
@@ -860,13 +971,13 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->keys);
all_table_map|= table->map;
s->join=join;
+ s->info=0; // For describe
if ((s->on_expr=tables->on_expr))
{
+ /* Left join */
if (!table->file->records)
{ // Empty table
- s->key_dependent=s->dependent=0;
- s->type=JT_SYSTEM;
- const_table_map|=table->map;
+ s->key_dependent=s->dependent=0; // Ignore LEFT JOIN depend.
set_position(join,const_count++,s,(KEYUSE*) 0);
continue;
}
@@ -885,11 +996,9 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
s->dependent=(table_map) 0;
s->key_dependent=(table_map) 0;
if ((table->system || table->file->records <= 1) && ! s->dependent &&
- !(table->file->option_flag() & HA_NOT_EXACT_COUNT) &&
+ !(table->file->table_flags() & HA_NOT_EXACT_COUNT) &&
!table->fulltext_searched)
{
- s->type=JT_SYSTEM;
- const_table_map|=table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
}
}
@@ -897,10 +1006,10 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
join->outer_join=outer_join;
/*
- ** If outer join: Re-arrange tables in stat_vector so that outer join
- ** tables are after all tables it is dependent of.
- ** For example: SELECT * from A LEFT JOIN B ON B.c=C.c, C WHERE A.C=C.C
- ** Will shift table B after table C.
+ If outer join: Re-arrange tables in stat_vector so that outer join
+ tables are after all tables it is dependent of.
+ For example: SELECT * from A LEFT JOIN B ON B.c=C.c, C WHERE A.C=C.C
+ Will shift table B after table C.
*/
if (outer_join)
{
@@ -937,31 +1046,66 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
conds,~outer_join))
DBUG_RETURN(1);
+ /* Read tables with 0 or 1 rows (system tables) */
+ join->const_table_map=const_table_map;
+
+ for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
+ p_pos < p_end ;
+ p_pos++)
+ {
+ int tmp;
+ s= p_pos->table;
+ s->type=JT_SYSTEM;
+ join->const_table_map|=s->table->map;
+ if ((tmp=join_read_const_table(s, p_pos)))
+ {
+ if (tmp > 0)
+ DBUG_RETURN(1); // Fatal error
+ }
+ else
+ found_const_table_map|= s->table->map;
+ }
+
/* loop until no more const tables are found */
int ref_changed;
do
{
ref_changed = 0;
found_ref=0;
- for (JOIN_TAB **pos=stat_vector+const_count; (s= *pos) ; pos++)
+
+ /*
+ We only have to loop from stat_vector + const_count as
+ set_position() will move all const_tables first in stat_vector
+ */
+
+ for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
{
+ TABLE *table=s->table;
if (s->dependent) // If dependent on some table
{
- if (s->dependent & ~(const_table_map)) // All dep. must be constants
+ // All dep. must be constants
+ if (s->dependent & ~(join->const_table_map))
continue;
- if (s->table->file->records <= 1L &&
- !(s->table->file->option_flag() & HA_NOT_EXACT_COUNT))
+ if (table->file->records <= 1L &&
+ !(table->file->table_flags() & HA_NOT_EXACT_COUNT))
{ // system table
+ int tmp;
s->type=JT_SYSTEM;
- const_table_map|=s->table->map;
+ join->const_table_map|=table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
+ if ((tmp=join_read_const_table(s,join->positions+const_count-1)))
+ {
+ if (tmp > 0)
+ DBUG_RETURN(1); // Fatal error
+ }
+ else
+ found_const_table_map|= table->map;
continue;
}
}
/* check if table can be read by key or table only uses const refs */
if ((keyuse=s->keyuse))
{
- TABLE *table=s->table;
s->type= JT_REF;
while (keyuse->table == table)
{
@@ -974,7 +1118,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
{
if (keyuse->val->type() != Item::NULL_ITEM)
{
- if (!((~const_table_map) & keyuse->used_tables))
+ if (!((~join->const_table_map) & keyuse->used_tables))
const_ref|= (key_map) 1 << keyuse->keypart;
else
refs|=keyuse->used_tables;
@@ -989,10 +1133,22 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
{
if (const_ref == eq_part)
{ // Found everything for ref.
+ int tmp;
+ ref_changed = 1;
s->type=JT_CONST;
- const_table_map|=table->map;
+ join->const_table_map|=table->map;
set_position(join,const_count++,s,start_keyuse);
- ref_changed = 1;
+ if (create_ref_for_key(join, s, start_keyuse,
+ join->const_table_map))
+ DBUG_RETURN(1);
+ if ((tmp=join_read_const_table(s,
+ join->positions+const_count-1)))
+ {
+ if (tmp > 0)
+ DBUG_RETURN(1); // Fatal error
+ }
+ else
+ found_const_table_map|= table->map;
break;
}
else
@@ -1001,7 +1157,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
}
}
}
- } while (const_table_map & found_ref && ref_changed);
+ } while (join->const_table_map & found_ref && ref_changed);
/* Calc how many (possible) matched records in each table */
@@ -1017,8 +1173,11 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
s->found_records=s->records=s->table->file->records;
s->read_time=(ha_rows) s->table->file->scan_time();
- /* Set a max range of how many seeks we can expect when using keys */
- s->worst_seeks= (double) (s->read_time*2);
+ /*
+ Set a max range of how many seeks we can expect when using keys
+ This was (s->read_time*5), but this was too low with small rows
+ */
+ s->worst_seeks= (double) s->found_records / 5;
if (s->worst_seeks < 2.0) // Fix for small tables
s->worst_seeks=2.0;
@@ -1028,10 +1187,11 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
{
ha_rows records;
if (!select)
- select=make_select(s->table,0,
- 0,
+ select=make_select(s->table, join->const_table_map,
+ join->const_table_map,
and_conds(conds,s->on_expr),&error);
- records=get_quick_record_count(select,s->table, s->const_keys);
+ records=get_quick_record_count(select,s->table, s->const_keys,
+ join->row_limit);
s->quick=select->quick;
s->needed_reg=select->needed_reg;
select->quick=0;
@@ -1049,10 +1209,10 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
join->map2table=stat_ref;
join->table= join->all_tables=table_vector;
join->const_tables=const_count;
- join->const_table_map=const_table_map;
+ join->found_const_table_map=found_const_table_map;
if (join->const_tables != join->tables)
- find_best_combination(join,all_table_map & ~const_table_map);
+ find_best_combination(join,all_table_map & ~join->const_table_map);
else
{
memcpy((gptr) join->best_positions,(gptr) join->positions,
@@ -1064,11 +1224,11 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
/*****************************************************************************
-** check with keys are used and with tables references with tables
-** updates in stat:
-** keys Bitmap of all used keys
-** const_keys Bitmap of all keys with may be used with quick_select
-** keyuse Pointer to possible keys
+ Check with keys are used and with tables references with tables
+ Updates in stat:
+ keys Bitmap of all used keys
+ const_keys Bitmap of all keys with may be used with quick_select
+ keyuse Pointer to possible keys
*****************************************************************************/
typedef struct key_field_t { // Used when finding key fields
@@ -1089,7 +1249,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
if (start == new_fields)
return start; // Impossible or
if (new_fields == end)
- return start; // No new fields, skipp all
+ return start; // No new fields, skip all
KEY_FIELD *first_free=new_fields;
@@ -1151,7 +1311,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
// Don't remove column IS NULL on a LEFT JOIN table
if (!eq_func || !value || value->type() != Item::NULL_ITEM ||
!field->table->maybe_null || field->null_ptr)
- return; // Not a key. Skipp it
+ return; // Not a key. Skip it
exists_optimize=1;
}
else
@@ -1170,11 +1330,13 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
else
{
JOIN_TAB *stat=field->table->reginfo.join_tab;
- stat[0].keys|=field->key_start; // Add possible keys
+ key_map possible_keys= (field->key_start &
+ field->table->keys_in_use_for_query);
+ stat[0].keys|= possible_keys; // Add possible keys
if (!value)
{ // Probably BETWEEN or IN
- stat[0].const_keys |= field->key_start;
+ stat[0].const_keys |= possible_keys;
return; // Can't be used as eq key
}
@@ -1188,7 +1350,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
*/
stat[0].key_dependent|=used_tables;
if (value->const_item())
- stat[0].const_keys |= field->key_start;
+ stat[0].const_keys |= possible_keys;
/* We can't always use indexes when comparing a string index to a
number. cmp_type() is checked to allow compare of dates to numbers */
@@ -1215,7 +1377,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
{
if (cond->type() == Item_func::COND_ITEM)
{
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
KEY_FIELD *org_key_fields= *key_fields;
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
@@ -1298,8 +1460,8 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
}
/*
-** Add all keys with uses 'field' for some keypart
-** If field->and_level != and_level then only mark key_part as const_part
+ Add all keys with uses 'field' for some keypart
+ If field->and_level != and_level then only mark key_part as const_part
*/
static uint
@@ -1369,27 +1531,27 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
*arg1=(Item_func *)(func->arguments()[1]);
if ((functype == Item_func::GE_FUNC ||
functype == Item_func::GT_FUNC) &&
- arg0->type() == Item::FUNC_ITEM &&
+ arg0->type() == Item::FUNC_ITEM &&
arg0->functype() == Item_func::FT_FUNC &&
- arg1->const_item() && arg1->val()>=0)
+ arg1->const_item() && arg1->val()>0)
cond_func=(Item_func_match *) arg0;
else if ((functype == Item_func::LE_FUNC ||
functype == Item_func::LT_FUNC) &&
arg1->type() == Item::FUNC_ITEM &&
arg1->functype() == Item_func::FT_FUNC &&
- arg0->const_item() && arg0->val()>=0)
+ arg0->const_item() && arg0->val()>0)
cond_func=(Item_func_match *) arg1;
}
}
else if (cond->type() == Item::COND_ITEM)
{
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
{
Item *item;
/*
- I', (Sergei) too lazy to implement proper recursive descent here,
+ I'm (Sergei) too lazy to implement proper recursive descent here,
and anyway, nobody will use such a stupid queries
that will require it :-)
May be later...
@@ -1406,7 +1568,7 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
}
}
- if(!cond_func)
+ if (!cond_func || cond_func->key == NO_SUCH_KEY)
return;
KEYUSE keyuse;
@@ -1434,9 +1596,9 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
/*
-** Update keyuse array with all possible keys we can use to fetch rows
-** join_tab is a array in tablenr_order
-** stat is a reference array in 'prefered' order.
+ Update keyuse array with all possible keys we can use to fetch rows
+ join_tab is a array in tablenr_order
+ stat is a reference array in 'prefered' order.
*/
static bool
@@ -1469,15 +1631,15 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
add_key_part(keyuse,field);
}
- if (thd->lex.ftfunc_list.elements)
+ if (thd->lex.select->ftfunc_list.elements)
{
add_ft_keys(keyuse,join_tab,cond,normal_tables);
}
/*
- ** remove ref if there is a keypart which is a ref and a const.
- ** remove keyparts without previous keyparts.
- ** Special treatment for ft-keys. SerG.
+ Remove ref if there is a keypart which is a ref and a const.
+ Remove keyparts without previous keyparts.
+ Special treatment for ft-keys.
*/
if (keyuse->elements)
{
@@ -1527,8 +1689,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
/*****************************************************************************
-** Go through all combinations of not marked tables and find the one
-** which uses least records
+ Go through all combinations of not marked tables and find the one
+ which uses least records
*****************************************************************************/
/* Save const tables first as used tables */
@@ -1543,7 +1705,7 @@ set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
/* Move the const table as down as possible in best_ref */
JOIN_TAB **pos=join->best_ref+idx+1;
JOIN_TAB *next=join->best_ref[idx];
- for ( ;next != table ; pos++)
+ for (;next != table ; pos++)
{
JOIN_TAB *tmp=pos[0];
pos[0]=next;
@@ -1569,6 +1731,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
{
ulong rec;
double tmp;
+ THD *thd= current_thd;
if (!rest_tables)
{
@@ -1634,12 +1797,12 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
found_ref|= keyuse->used_tables;
}
/*
- ** If we find a ref, assume this table matches a proportional
- ** part of this table.
- ** For example 100 records matching a table with 5000 records
- ** gives 5000/100 = 50 records per key
- ** Constant tables are ignored and to avoid bad matches,
- ** we don't make rec less than 100.
+ If we find a ref, assume this table matches a proportional
+ part of this table.
+ For example 100 records matching a table with 5000 records
+ gives 5000/100 = 50 records per key
+ Constant tables are ignored and to avoid bad matches,
+ we don't make rec less than 100.
*/
if (keyuse->used_tables &
(map=(keyuse->used_tables & ~join->const_table_map)))
@@ -1660,7 +1823,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
} while (keyuse->table == table && keyuse->key == key);
/*
- ** Assume that that each key matches a proportional part of table.
+ Assume that that each key matches a proportional part of table.
*/
if (!found_part && !ft_key)
continue; // Nothing usable found
@@ -1668,13 +1831,13 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
rec=1L; // Fix for small tables
/*
- ** ft-keys require special treatment
+ ft-keys require special treatment
*/
if (ft_key)
{
/*
- ** Really, there should be records=0.0 (yes!)
- ** but 1.0 would be probably safer
+ Really, there should be records=0.0 (yes!)
+ but 1.0 would be probably safer
*/
tmp=prev_record_reads(join,found_ref);
records=1.0;
@@ -1682,7 +1845,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else
{
/*
- ** Check if we found full key
+ Check if we found full key
*/
if (found_part == PREV_BITS(uint,keyinfo->key_parts))
{ /* use eq key */
@@ -1718,7 +1881,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
{
/* we can use only index tree */
uint keys_per_block= table->file->block_size/2/
- keyinfo->key_length+1;
+ (keyinfo->key_length+table->file->ref_length)+1;
tmp=(record_count*(records+keys_per_block-1)/
keys_per_block);
}
@@ -1729,17 +1892,18 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else
{
/*
- ** Use as much key-parts as possible and a uniq key is better
- ** than a not unique key
- ** Set tmp to (previous record count) * (records / combination)
+ Use as much key-parts as possible and a uniq key is better
+ than a not unique key
+ Set tmp to (previous record count) * (records / combination)
*/
if ((found_part & 1) &&
- !(table->file->option_flag() & HA_ONLY_WHOLE_INDEX))
+ !(table->file->index_flags(key) & HA_ONLY_WHOLE_INDEX))
{
max_key_part=max_part_bit(found_part);
- /* Check if quick_range could determinate how many rows we
- will match */
-
+ /*
+ Check if quick_range could determinate how many rows we
+ will match
+ */
if (table->quick_keys & ((key_map) 1 << key) &&
table->quick_key_parts[key] <= max_key_part)
tmp=records= (double) table->quick_rows[key];
@@ -1751,18 +1915,18 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else
{
/*
- ** Assume that the first key part matches 1% of the file
- ** and that the hole key matches 10 (dupplicates) or 1
- ** (unique) records.
- ** Assume also that more key matches proportionally more
- ** records
- ** This gives the formula:
- ** records= (x * (b-a) + a*c-b)/(c-1)
- **
- ** b = records matched by whole key
- ** a = records matched by first key part (10% of all records?)
- ** c = number of key parts in key
- ** x = used key parts (1 <= x <= c)
+ Assume that the first key part matches 1% of the file
+ and that the hole key matches 10 (dupplicates) or 1
+ (unique) records.
+ Assume also that more key matches proportionally more
+ records
+ This gives the formula:
+ records= (x * (b-a) + a*c-b)/(c-1)
+
+ b = records matched by whole key
+ a = records matched by first key part (10% of all records?)
+ c = number of key parts in key
+ x = used key parts (1 <= x <= c)
*/
double rec_per_key;
if (!(rec_per_key=(double)
@@ -1788,7 +1952,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
{
/* we can use only index tree */
uint keys_per_block= table->file->block_size/2/
- keyinfo->key_length+1;
+ (keyinfo->key_length+table->file->ref_length)+1;
tmp=record_count*(tmp+keys_per_block-1)/keys_per_block;
}
else
@@ -1813,10 +1977,17 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
/*
Don't test table scan if it can't be better.
Prefer key lookup if we would use the same key for scanning.
+
+ Don't do a table scan on InnoDB tables, if we can read the used
+ parts of the row from any of the used index.
+ This is because table scans uses index and we would not win
+ anything by using a table scan.
*/
if ((records >= s->found_records || best > s->read_time) &&
!(s->quick && best_key && s->quick->index == best_key->key &&
- best_max_key_part >= s->table->quick_key_parts[best_key->key]))
+ best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
+ !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
+ s->table->used_keys && best_key))
{ // Check full join
if (s->on_expr)
{
@@ -1827,7 +1998,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
tmp=(double) s->read_time;
/* Calculate time to read through cache */
tmp*=(1.0+floor((double) cache_record_length(join,idx)*
- record_count/(double) join_buff_size));
+ record_count /
+ (double) thd->variables.join_buff_size));
}
if (best == DBL_MAX ||
(tmp + record_count/(double) TIME_FOR_COMPARE*s->found_records <
@@ -1879,7 +2051,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
/*
-** Find how much space the prevous read not const tables takes in cache
+ Find how much space the prevous read not const tables takes in cache
*/
static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
@@ -1955,27 +2127,24 @@ prev_record_reads(JOIN *join,table_map found_ref)
/*****************************************************************************
-** Set up join struct according to best position.
+ Set up join struct according to best position.
*****************************************************************************/
static bool
get_best_combination(JOIN *join)
{
- uint i,key,tablenr;
+ uint i,tablenr;
table_map used_tables;
- TABLE *table;
JOIN_TAB *join_tab,*j;
KEYUSE *keyuse;
- KEY *keyinfo;
uint table_count;
+ THD *thd=join->thd;
table_count=join->tables;
if (!(join->join_tab=join_tab=
- (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB)*table_count)))
+ (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
return TRUE;
- join->const_tables=0; /* for checking */
- join->const_table_map=0;
join->full_join=0;
used_tables=0;
@@ -1984,188 +2153,188 @@ get_best_combination(JOIN *join)
TABLE *form;
*j= *join->best_positions[tablenr].table;
form=join->table[tablenr]=j->table;
- j->ref.key = -1;
- j->ref.key_parts=0;
- j->info=0; // For describe
used_tables|= form->map;
form->reginfo.join_tab=j;
if (!j->on_expr)
form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN
+ if (j->type == JT_CONST)
+ continue; // Handled in make_join_stat..
+
+ j->ref.key = -1;
+ j->ref.key_parts=0;
if (j->type == JT_SYSTEM)
- {
- j->table->const_table=1;
- if (join->const_tables == tablenr)
- {
- join->const_tables++;
- join->const_table_map|=form->map;
- }
continue;
- }
if (!j->keys || !(keyuse= join->best_positions[tablenr].key))
{
j->type=JT_ALL;
if (tablenr != join->const_tables)
join->full_join=1;
}
- else
- {
- uint keyparts,length;
- bool ftkey=(keyuse->keypart == FT_KEYPART);
- /*
- ** Use best key from find_best
- */
- table=j->table;
- key=keyuse->key;
+ else if (create_ref_for_key(join, j, keyuse, used_tables))
+ return TRUE; // Something went wrong
+ }
- keyinfo=table->key_info+key;
- if (ftkey)
- {
- Item_func_match *ifm=(Item_func_match *)keyuse->val;
+ for (i=0 ; i < table_count ; i++)
+ join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
+ update_depend_map(join);
+ return 0;
+}
- length=0;
- keyparts=1;
- ifm->join_key=1;
- }
- else
- {
- keyparts=length=0;
- do
- {
- if (!((~used_tables) & keyuse->used_tables))
- {
- if (keyparts == keyuse->keypart)
- {
- keyparts++;
- length+=keyinfo->key_part[keyuse->keypart].store_length;
- }
- }
- keyuse++;
- } while (keyuse->table == table && keyuse->key == key);
- } /* not ftkey */
-
- /* set up fieldref */
- keyinfo=table->key_info+key;
- j->ref.key_parts=keyparts;
- j->ref.key_length=length;
- j->ref.key=(int) key;
- if (!(j->ref.key_buff= (byte*) sql_calloc(ALIGN_SIZE(length)*2)) ||
- !(j->ref.key_copy= (store_key**) sql_alloc((sizeof(store_key*) *
- (keyparts+1)))) ||
- !(j->ref.items= (Item**) sql_alloc(sizeof(Item*)*keyparts)))
- {
- return TRUE;
- }
- j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
- j->ref.key_err=1;
- keyuse=join->best_positions[tablenr].key;
- store_key **ref_key=j->ref.key_copy;
- byte *key_buff=j->ref.key_buff;
- if (ftkey)
- {
- j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
- if (keyuse->used_tables)
- return TRUE; // not supported yet. SerG
+static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
+ table_map used_tables)
+{
+ KEYUSE *keyuse=org_keyuse;
+ bool ftkey=(keyuse->keypart == FT_KEYPART);
+ THD *thd= join->thd;
+ uint keyparts,length,key;
+ TABLE *table;
+ KEY *keyinfo;
- j->type=JT_FT;
- }
- else
- {
- THD *thd=join->thd;
- for (i=0 ; i < keyparts ; keyuse++,i++)
- {
- while (keyuse->keypart != i ||
- ((~used_tables) & keyuse->used_tables))
- keyuse++; /* Skipp other parts */
-
- uint maybe_null= test(keyinfo->key_part[i].null_bit);
- j->ref.items[i]=keyuse->val; // Save for cond removal
- if (!keyuse->used_tables &&
- !(join->select_options & SELECT_DESCRIBE))
- { // Compare against constant
- store_key_item *tmp=new store_key_item(keyinfo->key_part[i].field,
- (char*)key_buff +
- maybe_null,
- maybe_null ?
- (char*) key_buff : 0,
- keyinfo->key_part[i].length,
- keyuse->val);
- if (thd->fatal_error)
- {
- return TRUE;
- }
- tmp->copy();
- }
- else
- *ref_key++= get_store_key(keyuse,join->const_table_map,
- &keyinfo->key_part[i],
- (char*) key_buff,maybe_null);
- key_buff+=keyinfo->key_part[i].store_length;
- }
- } /* not ftkey */
- *ref_key=0; // end_marker
- if (j->type == JT_FT) /* no-op */;
- else if (j->type == JT_CONST)
+ /*
+ Use best key from find_best
+ */
+ table=j->table;
+ key=keyuse->key;
+ keyinfo=table->key_info+key;
+
+ if (ftkey)
+ {
+ Item_func_match *ifm=(Item_func_match *)keyuse->val;
+
+ length=0;
+ keyparts=1;
+ ifm->join_key=1;
+ }
+ else
+ {
+ keyparts=length=0;
+ do
+ {
+ if (!((~used_tables) & keyuse->used_tables))
{
- j->table->const_table=1;
- if (join->const_tables == tablenr)
+ if (keyparts == keyuse->keypart)
{
- join->const_tables++;
- join->const_table_map|=form->map;
+ keyparts++;
+ length+=keyinfo->key_part[keyuse->keypart].store_length;
}
}
- else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME) ||
- keyparts != keyinfo->key_parts)
- j->type=JT_REF; /* Must read with repeat */
- else if (ref_key == j->ref.key_copy)
- { /* Should never be reached */
- /*
- This happen if we are using a constant expression in the ON part
- of an LEFT JOIN.
- SELECT * FROM a LEFT JOIN b ON b.key=30
- Here we should not mark the table as a 'const' as a field may
- have a 'normal' value or a NULL value.
- */
- j->type=JT_CONST;
- if (join->const_tables == tablenr && !form->fulltext_searched)
+ keyuse++;
+ } while (keyuse->table == table && keyuse->key == key);
+ } /* not ftkey */
+
+ /* set up fieldref */
+ keyinfo=table->key_info+key;
+ j->ref.key_parts=keyparts;
+ j->ref.key_length=length;
+ j->ref.key=(int) key;
+ if (!(j->ref.key_buff= (byte*) thd->calloc(ALIGN_SIZE(length)*2)) ||
+ !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
+ (keyparts+1)))) ||
+ !(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)))
+ {
+ return TRUE;
+ }
+ j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
+ j->ref.key_err=1;
+ keyuse=org_keyuse;
+
+ store_key **ref_key=j->ref.key_copy;
+ byte *key_buff=j->ref.key_buff;
+ if (ftkey)
+ {
+ j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
+ if (keyuse->used_tables)
+ return TRUE; // not supported yet. SerG
+
+ j->type=JT_FT;
+ }
+ else
+ {
+ uint i;
+ for (i=0 ; i < keyparts ; keyuse++,i++)
+ {
+ while (keyuse->keypart != i ||
+ ((~used_tables) & keyuse->used_tables))
+ keyuse++; /* Skip other parts */
+
+ uint maybe_null= test(keyinfo->key_part[i].null_bit);
+ j->ref.items[i]=keyuse->val; // Save for cond removal
+ if (!keyuse->used_tables &&
+ !(join->select_options & SELECT_DESCRIBE))
+ { // Compare against constant
+ store_key_item *tmp=new store_key_item(thd,
+ keyinfo->key_part[i].field,
+ (char*)key_buff +
+ maybe_null,
+ maybe_null ?
+ (char*) key_buff : 0,
+ keyinfo->key_part[i].length,
+ keyuse->val);
+ if (thd->fatal_error)
{
- join->const_tables++;
- join->const_table_map|=form->map;
+ return TRUE;
}
+ tmp->copy();
}
else
- j->type=JT_EQ_REF;
- }
+ *ref_key++= get_store_key(thd,
+ keyuse,join->const_table_map,
+ &keyinfo->key_part[i],
+ (char*) key_buff,maybe_null);
+ key_buff+=keyinfo->key_part[i].store_length;
+ }
+ } /* not ftkey */
+ *ref_key=0; // end_marker
+ if (j->type == JT_FT) /* no-op */;
+ else if (j->type == JT_CONST)
+ j->table->const_table=1;
+ else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY))
+ != HA_NOSAME) ||
+ keyparts != keyinfo->key_parts)
+ j->type=JT_REF; /* Must read with repeat */
+ else if (ref_key == j->ref.key_copy)
+ { /* Should never be reached */
+ /*
+ This happen if we are using a constant expression in the ON part
+ of an LEFT JOIN.
+ SELECT * FROM a LEFT JOIN b ON b.key=30
+ Here we should not mark the table as a 'const' as a field may
+ have a 'normal' value or a NULL value.
+ */
+ j->type=JT_CONST;
}
-
- for (i=0 ; i < table_count ; i++)
- join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
- update_depend_map(join);
+ else
+ j->type=JT_EQ_REF;
return 0;
}
+
static store_key *
-get_store_key(KEYUSE *keyuse, table_map used_tables, KEY_PART_INFO *key_part,
- char *key_buff, uint maybe_null)
+get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
+ KEY_PART_INFO *key_part, char *key_buff, uint maybe_null)
{
if (!((~used_tables) & keyuse->used_tables)) // if const item
{
- return new store_key_const_item(key_part->field,
+ return new store_key_const_item(thd,
+ key_part->field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
keyuse->val);
}
else if (keyuse->val->type() == Item::FIELD_ITEM)
- return new store_key_field(key_part->field,
+ return new store_key_field(thd,
+ key_part->field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
((Item_field*) keyuse->val)->field,
keyuse->val->full_name());
- return new store_key_item(key_part->field,
+ return new store_key_item(thd,
+ key_part->field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
@@ -2173,8 +2342,8 @@ get_store_key(KEYUSE *keyuse, table_map used_tables, KEY_PART_INFO *key_part,
}
/*
-** This function is only called for const items on fields which are keys
-** returns 1 if there was some conversion made when the field was stored.
+ This function is only called for const items on fields which are keys
+ returns 1 if there was some conversion made when the field was stored.
*/
bool
@@ -2203,13 +2372,15 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
join->tables=1;
join->const_tables=0;
join->const_table_map=0;
- join->tmp_table_param.copy_field_count=join->tmp_table_param.field_count=
- join->tmp_table_param.sum_func_count= join->tmp_table_param.func_count=0;
- join->tmp_table_param.copy_field=0;
+ join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
+ join->tmp_table_param.func_count=0;
+ join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
join->first_record=join->sort_and_group=0;
join->sum_funcs=0;
join->send_records=(ha_rows) 0;
join->group=0;
+ join->do_send_rows = 1;
+ join->row_limit=join->thd->select_limit;
join_tab->cache.buff=0; /* No cacheing */
join_tab->table=tmp_table;
@@ -2283,7 +2454,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
DBUG_EXECUTE("where",print_where(tmp,tab->table->table_name););
SQL_SELECT *sel=tab->select=(SQL_SELECT*)
- sql_memdup((gptr) select, sizeof(SQL_SELECT));
+ join->thd->memdup((gptr) select, sizeof(SQL_SELECT));
if (!sel)
DBUG_RETURN(1); // End of memory
tab->select_cond=sel->cond=tmp;
@@ -2325,15 +2496,19 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
if ((tab->keys & ~ tab->const_keys && i > 0) ||
- tab->const_keys && i == join->const_tables &&
- join->thd->select_limit < join->best_positions[i].records_read)
+ (tab->const_keys && i == join->const_tables &&
+ join->thd->select_limit < join->best_positions[i].records_read &&
+ !(join->select_options & OPTION_FOUND_ROWS)))
{
/* Join with outer join condition */
COND *orig_cond=sel->cond;
sel->cond=and_conds(sel->cond,tab->on_expr);
if (sel->test_quick_select(tab->keys,
used_tables & ~ current_map,
- join->thd->select_limit) < 0)
+ (join->select_options &
+ OPTION_FOUND_ROWS ?
+ HA_POS_ERROR :
+ join->thd->select_limit)) < 0)
DBUG_RETURN(1); // Impossible range
sel->cond=orig_cond;
}
@@ -2360,8 +2535,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
current_map)))
{
DBUG_EXECUTE("where",print_where(tmp,"cache"););
- tab->cache.select=(SQL_SELECT*) sql_memdup((gptr) sel,
- sizeof(SQL_SELECT));
+ tab->cache.select=(SQL_SELECT*)
+ join->thd->memdup((gptr) sel, sizeof(SQL_SELECT));
tab->cache.select->cond=tmp;
tab->cache.select->read_tables=join->const_table_map;
}
@@ -2378,6 +2553,7 @@ static void
make_join_readinfo(JOIN *join,uint options)
{
uint i;
+ SELECT_LEX *select_lex = &(join->thd->lex.select_lex);
DBUG_ENTER("make_join_readinfo");
for (i=join->const_tables ; i < join->tables ; i++)
@@ -2410,7 +2586,8 @@ make_join_readinfo(JOIN *join,uint options)
table->file->index_init(tab->ref.key);
tab->read_first_record= join_read_key;
tab->read_record.read_record= join_no_more_records;
- if (table->used_keys & ((key_map) 1 << tab->ref.key))
+ if (table->used_keys & ((key_map) 1 << tab->ref.key) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
@@ -2427,8 +2604,9 @@ make_join_readinfo(JOIN *join,uint options)
tab->quick=0;
table->file->index_init(tab->ref.key);
tab->read_first_record= join_read_always_key;
- tab->read_record.read_record= join_read_next;
- if (table->used_keys & ((key_map) 1 << tab->ref.key))
+ tab->read_record.read_record= join_read_next_same;
+ if (table->used_keys & ((key_map) 1 << tab->ref.key) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
@@ -2442,10 +2620,10 @@ make_join_readinfo(JOIN *join,uint options)
break;
case JT_ALL:
/*
- ** if previous table use cache
+ If previous table use cache
*/
table->status=STATUS_NO_RECORD;
- if (i != join->const_tables && (options & SELECT_USE_CACHE) &&
+ if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
tab->use_quick != 2 && !tab->on_expr)
{
if ((options & SELECT_DESCRIBE) ||
@@ -2458,7 +2636,7 @@ make_join_readinfo(JOIN *join,uint options)
/* These init changes read_record */
if (tab->use_quick == 2)
{
- join->thd->lex.options|=QUERY_NO_GOOD_INDEX_USED;
+ select_lex->options|=QUERY_NO_GOOD_INDEX_USED;
tab->read_first_record= join_init_quick_read_record;
statistic_increment(select_range_check_count, &LOCK_status);
}
@@ -2473,7 +2651,7 @@ make_join_readinfo(JOIN *join,uint options)
}
else
{
- join->thd->lex.options|=QUERY_NO_INDEX_USED;
+ select_lex->options|=QUERY_NO_INDEX_USED;
statistic_increment(select_scan_count, &LOCK_status);
}
}
@@ -2485,22 +2663,25 @@ make_join_readinfo(JOIN *join,uint options)
}
else
{
- join->thd->lex.options|=QUERY_NO_INDEX_USED;
+ select_lex->options|=QUERY_NO_INDEX_USED;
statistic_increment(select_full_join_count, &LOCK_status);
}
}
- if (tab->select && tab->select->quick &&
- table->used_keys & ((key_map) 1 << tab->select->quick->index))
+ if (!table->no_keyread)
{
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
- }
- else if (table->used_keys && ! (tab->select && tab->select->quick))
- { // Only read index tree
- tab->index=find_shortest_key(table, table->used_keys);
- tab->table->file->index_init(tab->index);
- tab->read_first_record= join_init_read_first_with_key;
- tab->type=JT_NEXT; // Read with index_first / index_next
+ if (tab->select && tab->select->quick &&
+ table->used_keys & ((key_map) 1 << tab->select->quick->index))
+ {
+ table->key_read=1;
+ table->file->extra(HA_EXTRA_KEYREAD);
+ }
+ else if (table->used_keys && ! (tab->select && tab->select->quick))
+ { // Only read index tree
+ tab->index=find_shortest_key(table, table->used_keys);
+ tab->table->file->index_init(tab->index);
+ tab->read_first_record= join_read_first;
+ tab->type=JT_NEXT; // Read with index_first / index_next
+ }
}
}
break;
@@ -2551,35 +2732,39 @@ join_free(JOIN *join)
}
join->table=0;
}
- // We are not using tables anymore
- // Unlock all tables. We may be in an INSERT .... SELECT statement.
- if (join->lock && join->thd->lock)
+ /*
+ We are not using tables anymore
+ Unlock all tables. We may be in an INSERT .... SELECT statement.
+ */
+ if (join->lock && join->thd->lock &&
+ !(join->select_options & SELECT_NO_UNLOCK))
{
mysql_unlock_read_tables(join->thd, join->lock);// Don't free join->lock
join->lock=0;
}
join->group_fields.delete_elements();
join->tmp_table_param.copy_funcs.delete_elements();
- delete [] join->tmp_table_param.copy_field;
+ if (join->tmp_table_param.copy_field) // Because of bug in ecc
+ delete [] join->tmp_table_param.copy_field;
join->tmp_table_param.copy_field=0;
DBUG_VOID_RETURN;
}
/*****************************************************************************
-** Remove the following expressions from ORDER BY and GROUP BY:
-** Constant expressions
-** Expression that only uses tables that are of type EQ_REF and the reference
-** is in the ORDER list or if all refereed tables are of the above type.
-**
-** In the following, the X field can be removed:
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
-** SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
-**
-** These can't be optimized:
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
+ Remove the following expressions from ORDER BY and GROUP BY:
+ Constant expressions
+ Expression that only uses tables that are of type EQ_REF and the reference
+ is in the ORDER list or if all refereed tables are of the above type.
+
+ In the following, the X field can be removed:
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
+ SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
+
+ These can't be optimized:
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
*****************************************************************************/
static bool
@@ -2610,7 +2795,7 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
if (order)
{
found++;
- dbug_assert(!(order->used & map));
+ DBUG_ASSERT(!(order->used & map));
order->used|=map;
continue; // Used in ORDER BY
}
@@ -2619,7 +2804,7 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
}
}
/* Check that there was no reference to table before sort order */
- for ( ; found && start_order ; start_order=start_order->next)
+ for (; found && start_order ; start_order=start_order->next)
{
if (start_order->used & map)
{
@@ -2637,7 +2822,7 @@ static bool
only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
{
if (specialflag & SPECIAL_SAFE_MODE)
- return 0; // skip this optimize /* purecov: inspected */
+ return 0; // skip this optimize /* purecov: inspected */
for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
{
if (tables & 1 && !eq_ref_table(join, order, *tab))
@@ -2653,7 +2838,7 @@ static void update_depend_map(JOIN *join)
{
JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
- for ( ; join_tab != end ; join_tab++)
+ for (; join_tab != end ; join_tab++)
{
TABLE_REF *ref= &join_tab->ref;
table_map depend_map=0;
@@ -2677,7 +2862,7 @@ static void update_depend_map(JOIN *join)
static void update_depend_map(JOIN *join, ORDER *order)
{
- for ( ; order ; order=order->next)
+ for (; order ; order=order->next)
{
table_map depend_map;
order->item[0]->update_used_tables();
@@ -2725,7 +2910,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
else if (!(order_tables & not_const_tables))
{
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
- continue; // skipp const item
+ continue; // skip const item
}
else
{
@@ -2760,16 +2945,17 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
DBUG_RETURN(first_order);
}
+
static int
-return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
- bool send_row, uint select_options,const char *info,
- Item *having, Procedure *procedure)
+return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
+ List<Item> &fields, bool send_row, uint select_options,
+ const char *info, Item *having, Procedure *procedure)
{
DBUG_ENTER("return_zero_rows");
if (select_options & SELECT_DESCRIBE)
{
- describe_info(current_thd, info);
+ describe_info(join, info);
DBUG_RETURN(0);
}
if (procedure)
@@ -2784,17 +2970,17 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
if (having && having->val_int() == 0)
send_row=0;
}
- if (!tables || !(result->send_fields(fields,1)))
+ if (!(result->send_fields(fields,1)))
{
if (send_row)
result->send_data(fields);
- if (tables) // Not from do_select()
+ if (tables) // Not from do_select()
{
/* Close open cursors */
for (TABLE_LIST *table=tables; table ; table=table->next)
table->table->file->index_end();
- result->send_eof(); // Should be safe
}
+ result->send_eof(); // Should be safe
}
DBUG_RETURN(0);
}
@@ -2807,12 +2993,12 @@ static void clear_tables(JOIN *join)
}
/*****************************************************************************
-** Make som simple condition optimization:
-** If there is a test 'field = const' change all refs to 'field' to 'const'
-** Remove all dummy tests 'item = item', 'const op const'.
-** Remove all 'item is NULL', when item can never be null!
-** item->marker should be 0 for all items on entry
-** Return in cond_value FALSE if condition is impossible (1 = 2)
+ Make som simple condition optimization:
+ If there is a test 'field = const' change all refs to 'field' to 'const'
+ Remove all dummy tests 'item = item', 'const op const'.
+ Remove all 'item is NULL', when item can never be null!
+ item->marker should be 0 for all items on entry
+ Return in cond_value FALSE if condition is impossible (1 = 2)
*****************************************************************************/
class COND_CMP :public ilink {
@@ -2834,8 +3020,8 @@ template class List_iterator<Item_func_match>;
#endif
/*
-** change field = field to field = const for each found field = const in the
-** and_level
+ change field = field to field = const for each found field = const in the
+ and_level
*/
static void
@@ -2912,7 +3098,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
{
bool and_level= ((Item_cond*) cond)->functype() ==
Item_func::COND_AND_FUNC;
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
I_List<COND_CMP> save;
while ((item=li++))
@@ -2980,8 +3166,8 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
DBUG_EXECUTE("where",print_where(conds,"original"););
propagate_cond_constants((I_List<COND_CMP> *) 0,conds,conds);
/*
- ** Remove all instances of item == item
- ** Remove all and-levels where CONST item != CONST item
+ Remove all instances of item == item
+ Remove all and-levels where CONST item != CONST item
*/
DBUG_EXECUTE("where",print_where(conds,"after const change"););
conds=remove_eq_conds(conds,cond_value) ;
@@ -2991,11 +3177,11 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
/*
-** remove const and eq items. Return new item, or NULL if no condition
-** cond_value is set to according:
-** COND_OK query is possible (field = constant)
-** COND_TRUE always true ( 1 = 1 )
-** COND_FALSE always false ( 1 = 2 )
+ Remove const and eq items. Return new item, or NULL if no condition
+ cond_value is set to according:
+ COND_OK query is possible (field = constant)
+ COND_TRUE always true ( 1 = 1 )
+ COND_FALSE always false ( 1 = 2 )
*/
static COND *
@@ -3066,13 +3252,13 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
{
/*
- ** Handles this special case for some ODBC applications:
- ** The are requesting the row that was just updated with a auto_increment
- ** value with this construct:
- **
- ** SELECT * from table_name where auto_increment_column IS NULL
- ** This will be changed to:
- ** SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
+ Handles this special case for some ODBC applications:
+ The are requesting the row that was just updated with a auto_increment
+ value with this construct:
+
+ SELECT * from table_name where auto_increment_column IS NULL
+ This will be changed to:
+ SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
*/
Item_func_isnull *func=(Item_func_isnull*) cond;
@@ -3085,6 +3271,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
(thd->options & OPTION_AUTO_IS_NULL) &&
thd->insert_id())
{
+ query_cache_abort(&thd->net);
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],
new Item_int("last_insert_id()",
@@ -3128,11 +3315,11 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
}
}
*cond_value=Item::COND_OK;
- return cond; /* Point at next and level */
+ return cond; // Point at next and level
}
/*
-** Return 1 if the item is a const value in all the WHERE clause
+ Return 1 if the item is a const value in all the WHERE clause
*/
static bool
@@ -3142,7 +3329,7 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
{
bool and_level= (((Item_cond*) cond)->functype()
== Item_func::COND_AND_FUNC);
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
while ((item=li++))
{
@@ -3191,13 +3378,13 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
/****************************************************************************
-** Create a temp table according to a field list.
-** Set distinct if duplicates could be removed
-** Given fields field pointers are changed to point at tmp_table
-** for send_fields
+ Create a temp table according to a field list.
+ Set distinct if duplicates could be removed
+ Given fields field pointers are changed to point at tmp_table
+ for send_fields
****************************************************************************/
-Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
+Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item_result_field ***copy_func, Field **from_field,
bool group, bool modify_item)
{
@@ -3230,7 +3417,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
item->name,table,item_sum->decimals);
case INT_RESULT:
return new Field_longlong(item_sum->max_length,maybe_null,
- item->name,table);
+ item->name,table,item->unsigned_flag);
case STRING_RESULT:
if (item_sum->max_length > 255)
return new Field_blob(item_sum->max_length,maybe_null,
@@ -3239,7 +3426,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
item->name,table,item->binary);
}
}
- current_thd->fatal_error=1;
+ thd->fatal_error=1;
return 0; // Error
}
case Item::FIELD_ITEM:
@@ -3247,7 +3434,8 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
Field *org_field=((Item_field*) item)->field,*new_field;
*from_field=org_field;
- if ((new_field= org_field->new_field(table))) // Should always be true
+ // The following should always be true
+ if ((new_field= org_field->new_field(&thd->mem_root,table)))
{
if (modify_item)
((Item_field*) item)->result_field= new_field;
@@ -3281,7 +3469,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
break;
case INT_RESULT:
new_field=new Field_longlong(item->max_length,maybe_null,
- item->name,table);
+ item->name,table, item->unsigned_flag);
break;
case STRING_RESULT:
if (item->max_length > 255)
@@ -3307,13 +3495,14 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
TABLE *
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
- bool allow_distinct_limit, uint select_options)
+ bool allow_distinct_limit, ulong select_options)
{
TABLE *table;
uint i,field_count,reclength,null_count,null_pack_length,
hidden_null_count, hidden_null_pack_length, hidden_field_count,
blob_count,group_null_items;
bool using_unique_constraint=0;
+ bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
char *tmpname,path[FN_REFLEN];
byte *pos,*group_buff;
uchar *null_flags;
@@ -3336,7 +3525,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
temp_pool_slot = bitmap_set_next(&temp_pool);
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
- sprintf(path, "%s%s_%lx_%i", mysql_tmpdir, tmp_file_prefix,
+ sprintf(path, "%s%s_%lx_%i", mysql_tmpdir, tmp_file_prefix,
current_pid, temp_pool_slot);
else // if we run out of slots or we are not using tempool
sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid,
@@ -3347,7 +3536,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!param->quick_group)
group=0; // Can't use group key
else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
+ {
(*tmp->item)->marker=4; // Store null in key
+ if ((*tmp->item)->max_length >= MAX_CHAR_WIDTH)
+ using_unique_constraint=1;
+ }
if (param->group_length >= MAX_BLOB_WIDTH)
using_unique_constraint=1;
if (group)
@@ -3404,24 +3597,27 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
reclength=blob_count=null_count=hidden_null_count=group_null_items=0;
param->using_indirect_summary_function=0;
- List_iterator<Item> li(fields);
+ List_iterator_fast<Item> li(fields);
Item *item;
Field **tmp_from_field=from_field;
while ((item=li++))
{
Item::Type type=item->type();
- if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
+ if (not_all_columns)
{
- /*
- Mark that the we have ignored an item that refers to a summary
- function. We need to know this if someone is going to use
- DISTINCT on the result.
- */
- param->using_indirect_summary_function=1;
- continue;
+ if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
+ {
+ /*
+ Mark that the we have ignored an item that refers to a summary
+ function. We need to know this if someone is going to use
+ DISTINCT on the result.
+ */
+ param->using_indirect_summary_function=1;
+ continue;
+ }
+ if (item->const_item()) // We don't have to store this
+ continue;
}
- if (item->const_item()) // We don't have to store this
- continue;
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
{ /* Can't calc group yet */
((Item_sum*) item)->result_field=0;
@@ -3431,8 +3627,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!arg->const_item())
{
Field *new_field=
- create_tmp_field(table,arg,arg->type(),&copy_func,tmp_from_field,
- group != 0,1);
+ create_tmp_field(thd, table,arg,arg->type(),&copy_func,
+ tmp_from_field, group != 0,not_all_columns);
if (!new_field)
goto err; // Should be OOM
tmp_from_field++;
@@ -3448,8 +3644,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
else
{
- Field *new_field=create_tmp_field(table,item,type,&copy_func,
- tmp_from_field, group != 0,1);
+ Field *new_field=create_tmp_field(thd, table, item,type, &copy_func,
+ tmp_from_field, group != 0,
+ not_all_columns);
if (!new_field)
{
if (thd->fatal_error)
@@ -3499,7 +3696,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (blob_count == 0)
{
/* We need to ensure that first byte is not 0 for the delete link */
- if (hidden_null_count)
+ if (param->hidden_field_count)
hidden_null_count++;
else
null_count++;
@@ -3545,6 +3742,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{
if (field->flags & GROUP_FLAG && !using_unique_constraint)
{
+ /*
+ We have to reserve one byte here for NULL bits,
+ as this is updated by 'end_update()'
+ */
*pos++=0; // Null is stored here
recinfo->length=1;
recinfo->type=FIELD_NORMAL;
@@ -3579,23 +3780,24 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(field->type() == FIELD_TYPE_STRING ||
field->type() == FIELD_TYPE_VAR_STRING) &&
length >= 10 && blob_count)
- recinfo->type=FIELD_SKIPP_ENDSPACE;
+ recinfo->type=FIELD_SKIP_ENDSPACE;
else
recinfo->type=FIELD_NORMAL;
if (!--hidden_field_count)
null_count=(null_count+7) & ~7; // move to next byte
}
- param->copy_field_count=(uint) (copy - param->copy_field);
+ param->copy_field_end=copy;
param->recinfo=recinfo;
store_record(table,2); // Make empty default record
- if (tmp_table_size == ~(ulong) 0) // No limit
+ if (thd->variables.tmp_table_size == ~(ulong) 0) // No limit
table->max_rows= ~(ha_rows) 0;
else
table->max_rows=(((table->db_type == DB_TYPE_HEAP) ?
- min(tmp_table_size, max_heap_table_size) :
- tmp_table_size)/ table->reclength);
+ min(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size)/ table->reclength);
set_if_bigger(table->max_rows,1); // For dummy start options
keyinfo=param->keyinfo;
@@ -3628,19 +3830,22 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!using_unique_constraint)
{
group->buff=(char*) group_buff;
- if (!(group->field=field->new_field(table)))
+ if (!(group->field=field->new_field(&thd->mem_root,table)))
goto err; /* purecov: inspected */
if (maybe_null)
{
/*
- To be able to group on NULL, we move the null bit to be
- just before the column and extend the key to cover the null bit
+ To be able to group on NULL, we reserve place in group_buff
+ for the NULL flag just before the column.
+ The field data is after this flag.
+ The NULL flag is updated by 'end_update()' and 'end_write()'
*/
- *group_buff= 0; // Init null byte
- key_part_info->offset--;
- key_part_info->length++;
- group->field->move_field((char*) group_buff+1, (uchar*) group_buff,
- 1);
+ keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
+ key_part_info->null_bit=field->null_bit;
+ key_part_info->null_offset= (uint) (field->null_ptr -
+ (uchar*) table->record[0]);
+ group->field->move_field((char*) ++group->buff);
+ group_buff++;
}
else
group->field->move_field((char*) group_buff);
@@ -3742,14 +3947,13 @@ static bool open_tmp_table(TABLE *table)
return(1);
}
/* VOID(ha_lock(table,F_WRLCK)); */ /* Single thread table */
- (void) table->file->extra(HA_EXTRA_NO_READCHECK); /* Not needed */
(void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
return(0);
}
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- uint options)
+ ulong options)
{
int error;
MI_KEYDEF keydef;
@@ -3796,10 +4000,10 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
{
Field *field=keyinfo->key_part[i].field;
- seg->flag=0;
- seg->language=MY_CHARSET_CURRENT;
- seg->length=keyinfo->key_part[i].length;
- seg->start=keyinfo->key_part[i].offset;
+ seg->flag= 0;
+ seg->language= MY_CHARSET_CURRENT;
+ seg->length= keyinfo->key_part[i].length;
+ seg->start= keyinfo->key_part[i].offset;
if (field->flags & BLOB_FLAG)
{
seg->type=
@@ -3820,11 +4024,17 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
keyinfo->key_part[i].length > 4)
seg->flag|=HA_SPACE_PACK;
}
- if (using_unique_constraint &&
- !(field->flags & NOT_NULL_FLAG))
+ if (!(field->flags & NOT_NULL_FLAG))
{
seg->null_bit= field->null_bit;
seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
+ /*
+ We are using a GROUP BY on something that contains NULL
+ In this case we have to tell MyISAM that two NULL should
+ on INSERT be compared as equal
+ */
+ if (!using_unique_constraint)
+ keydef.flag|= HA_NULL_ARE_EQUAL;
}
}
}
@@ -3910,12 +4120,18 @@ bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
thd->proc_info="converting HEAP to MyISAM";
if (create_myisam_tmp_table(&new_table,param,
- thd->lex.options | thd->options))
+ thd->lex.select_lex.options | thd->options))
goto err2;
if (open_tmp_table(&new_table))
goto err1;
table->file->index_end();
table->file->rnd_init();
+ if (table->no_rows)
+ {
+ new_table.file->extra(HA_EXTRA_NO_ROWS);
+ new_table.no_rows=1;
+ }
+
/* copy all old rows */
while (!table->file->rnd_next(new_table.record[1]))
{
@@ -3956,9 +4172,12 @@ bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
}
-/*****************************************************************************
-** Make a join of all tables and write it on socket or to table
-*****************************************************************************/
+/****************************************************************************
+ Make a join of all tables and write it on socket or to table
+ Return: 0 if ok
+ 1 if error is sent
+ -1 if error should be sent
+****************************************************************************/
static int
do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
@@ -3970,7 +4189,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
join->procedure=procedure;
/*
- ** Tell the client how many fields there are in a row
+ Tell the client how many fields there are in a row
*/
if (!table)
join->result->send_fields(*fields,1);
@@ -4035,22 +4254,22 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
if (error == -3)
error=0; /* select_limit used */
}
- if (!table) /* If sending data to client */
+
+ /* Return 1 if error is sent; -1 if error should be sent */
+ if (error < 0)
{
- if (error < 0)
- join->result->send_error(0,NullS); /* purecov: inspected */
- else
+ join->result->send_error(0,NullS); /* purecov: inspected */
+ error=1; // Error sent
+ }
+ else
+ {
+ error=0;
+ if (!table) // If sending data to client
{
join_free(join); // Unlock all cursors
if (join->result->send_eof())
- error= -1;
+ error= 1; // Don't send error
}
- }
- else if (error < 0)
- join->result->send_error(0,NullS); /* purecov: inspected */
-
- if (error >= 0)
- {
DBUG_PRINT("info",("%ld records output",join->send_records));
}
if (table)
@@ -4061,15 +4280,15 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
my_errno=tmp;
error= -1;
}
- if (table->file->index_end())
+ if ((tmp=table->file->index_end()))
{
my_errno=tmp;
error= -1;
}
- if (error != old_error)
+ if (error == -1)
table->file->print_error(my_errno,MYF(0));
}
- DBUG_RETURN(error < 0);
+ DBUG_RETURN(error);
}
@@ -4145,10 +4364,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
info->file->unlock_row();
}
} while (!(error=info->read_record(info)));
- if (error > 0) // Fatal error
- return -1;
}
- else if (error > 0)
+ if (error > 0) // Fatal error
return -1;
if (!found && on_expr)
@@ -4234,50 +4451,48 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skipp_last)
/*****************************************************************************
-** The different ways to read a record
-** Returns -1 if row was not found, 0 if row was found and 1 on errors
+ The different ways to read a record
+ Returns -1 if row was not found, 0 if row was found and 1 on errors
*****************************************************************************/
-
static int
-join_read_const_tables(JOIN *join)
+join_read_const_table(JOIN_TAB *tab, POSITION *pos)
{
- uint i;
int error;
- DBUG_ENTER("join_read_const_tables");
- for (i=0 ; i < join->const_tables ; i++)
- {
- TABLE *form=join->table[i];
- form->null_row=0;
- form->status=STATUS_NO_RECORD;
-
- if (join->join_tab[i].type == JT_SYSTEM)
- {
- if ((error=join_read_system(join->join_tab+i)))
- { // Info for DESCRIBE
- join->join_tab[i].info="const row not found";
- join->best_positions[i].records_read=0.0;
- if (!form->outer_join || error > 0)
- DBUG_RETURN(error);
- }
- }
- else
- {
- if ((error=join_read_const(join->join_tab+i)))
- {
- join->join_tab[i].info="unique row not found";
- join->best_positions[i].records_read=0.0;
- if (!form->outer_join || error > 0)
- DBUG_RETURN(error);
- }
+ DBUG_ENTER("join_read_const_table");
+ TABLE *table=tab->table;
+ table->const_table=1;
+ table->null_row=0;
+ table->status=STATUS_NO_RECORD;
+
+ if (tab->type == JT_SYSTEM)
+ {
+ if ((error=join_read_system(tab)))
+ { // Info for DESCRIBE
+ tab->info="const row not found";
+ /* Mark for EXPLAIN that the row was not found */
+ pos->records_read=0.0;
+ if (!table->outer_join || error > 0)
+ DBUG_RETURN(error);
}
- if (join->join_tab[i].on_expr && !form->null_row)
+ }
+ else
+ {
+ if ((error=join_read_const(tab)))
{
- if ((form->null_row= test(join->join_tab[i].on_expr->val_int() == 0)))
- empty_record(form);
+ tab->info="unique row not found";
+ /* Mark for EXPLAIN that the row was not found */
+ pos->records_read=0.0;
+ if (!table->outer_join || error > 0)
+ DBUG_RETURN(error);
}
- if (!form->null_row)
- form->maybe_null=0;
}
+ if (tab->on_expr && !table->null_row)
+ {
+ if ((table->null_row= test(tab->on_expr->val_int() == 0)))
+ empty_record(table);
+ }
+ if (!table->null_row)
+ table->maybe_null=0;
DBUG_RETURN(0);
}
@@ -4289,7 +4504,8 @@ join_read_system(JOIN_TAB *tab)
int error;
if (table->status & STATUS_GARBAGE) // If first read
{
- if ((error=table->file->rnd_first(table->record[0])))
+ if ((error=table->file->read_first_row(table->record[0],
+ table->primary_key)))
{
if (error != HA_ERR_END_OF_FILE)
{
@@ -4403,6 +4619,35 @@ join_read_always_key(JOIN_TAB *tab)
return 0;
}
+/*
+ This function is used when optimizing away ORDER BY in
+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
+*/
+
+static int
+join_read_last_key(JOIN_TAB *tab)
+{
+ int error;
+ TABLE *table= tab->table;
+
+ if (cp_buffer_from_ref(&tab->ref))
+ return -1;
+ if ((error=table->file->index_read_last(table->record[0],
+ tab->ref.key_buff,
+ tab->ref.key_length)))
+ {
+ if (error != HA_ERR_KEY_NOT_FOUND)
+ {
+ sql_print_error("read_const: Got error %d when reading table %s",error,
+ table->path);
+ table->file->print_error(error,MYF(0));
+ return 1;
+ }
+ return -1; /* purecov: inspected */
+ }
+ return 0;
+}
+
/* ARGSUSED */
static int
@@ -4413,7 +4658,7 @@ join_no_more_records(READ_RECORD *info __attribute__((unused)))
static int
-join_read_next(READ_RECORD *info)
+join_read_next_same(READ_RECORD *info)
{
int error;
TABLE *table= info->table;
@@ -4436,6 +4681,37 @@ join_read_next(READ_RECORD *info)
return 0;
}
+static int
+join_read_prev_same(READ_RECORD *info)
+{
+ int error;
+ TABLE *table= info->table;
+ JOIN_TAB *tab=table->reginfo.join_tab;
+
+ if ((error=table->file->index_prev(table->record[0])))
+ {
+ if (error != HA_ERR_END_OF_FILE)
+ {
+ sql_print_error("read_next: Got error %d when reading table %s",error,
+ table->path);
+ table->file->print_error(error,MYF(0));
+ error= 1;
+ }
+ else
+ {
+ table->status= STATUS_GARBAGE;
+ error= -1;
+ }
+ }
+ else if (key_cmp(table, tab->ref.key_buff, tab->ref.key,
+ tab->ref.key_length))
+ {
+ table->status=STATUS_NOT_FOUND;
+ error= -1;
+ }
+ return error;
+}
+
static int
join_init_quick_read_record(JOIN_TAB *tab)
@@ -4466,17 +4742,18 @@ join_init_read_record(JOIN_TAB *tab)
}
static int
-join_init_read_first_with_key(JOIN_TAB *tab)
+join_read_first(JOIN_TAB *tab)
{
int error;
TABLE *table=tab->table;
- if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)))
+ if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
tab->table->status=0;
- tab->read_record.read_record=join_init_read_next_with_key;
+ tab->read_record.read_record=join_read_next;
tab->read_record.table=table;
tab->read_record.file=table->file;
tab->read_record.index=tab->index;
@@ -4496,8 +4773,9 @@ join_init_read_first_with_key(JOIN_TAB *tab)
return 0;
}
+
static int
-join_init_read_next_with_key(READ_RECORD *info)
+join_read_next(READ_RECORD *info)
{
int error=info->file->index_next(info->record);
if (error)
@@ -4514,19 +4792,19 @@ join_init_read_next_with_key(READ_RECORD *info)
return 0;
}
-
static int
-join_init_read_last_with_key(JOIN_TAB *tab)
+join_read_last(JOIN_TAB *tab)
{
TABLE *table=tab->table;
int error;
- if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)))
+ if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
tab->table->status=0;
- tab->read_record.read_record=join_init_read_prev_with_key;
+ tab->read_record.read_record=join_read_prev;
tab->read_record.table=table;
tab->read_record.file=table->file;
tab->read_record.index=tab->index;
@@ -4546,8 +4824,9 @@ join_init_read_last_with_key(JOIN_TAB *tab)
return 0;
}
+
static int
-join_init_read_prev_with_key(READ_RECORD *info)
+join_read_prev(READ_RECORD *info)
{
int error=info->file->index_prev(info->record);
if (error)
@@ -4564,13 +4843,14 @@ join_init_read_prev_with_key(READ_RECORD *info)
return 0;
}
+
static int
join_ft_read_first(JOIN_TAB *tab)
{
int error;
TABLE *table= tab->table;
-#if 0
+#if NOT_USED_YET
if (cp_buffer_from_ref(&tab->ref)) // as ft-key doesn't use store_key's
return -1; // see also FT_SELECT::init()
#endif
@@ -4611,12 +4891,12 @@ join_ft_read_next(READ_RECORD *info)
/*****************************************************************************
-** The different end of select functions
-** These functions returns < 0 when end is reached, 0 on ok and > 0 if a
-** fatal error (like table corruption) was detected
+ The different end of select functions
+ These functions returns < 0 when end is reached, 0 on ok and > 0 if a
+ fatal error (like table corruption) was detected
*****************************************************************************/
- /* ARGSUSED */
+/* ARGSUSED */
static int
end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records)
@@ -4627,14 +4907,49 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
int error;
if (join->having && join->having->val_int() == 0)
DBUG_RETURN(0); // Didn't match having
+ error=0;
if (join->procedure)
error=join->procedure->send_row(*join->fields);
- else
+ else if (join->do_send_rows)
error=join->result->send_data(*join->fields);
if (error)
DBUG_RETURN(-1); /* purecov: inspected */
- if (++join->send_records >= join->thd->select_limit)
+ if (++join->send_records >= join->thd->select_limit &&
+ join->do_send_rows)
+ {
+ if (join->select_options & OPTION_FOUND_ROWS)
+ {
+ JOIN_TAB *jt=join->join_tab;
+ if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
+ && !join->send_group_parts && !join->having && !jt->select_cond &&
+ !(jt->select && jt->select->quick) &&
+ !(jt->table->file->table_flags() & HA_NOT_EXACT_COUNT))
+ {
+ /* Join over all rows in table; Return number of found rows */
+ TABLE *table=jt->table;
+
+ join->select_options ^= OPTION_FOUND_ROWS;
+ if (table->record_pointers ||
+ (table->io_cache && my_b_inited(table->io_cache)))
+ {
+ /* Using filesort */
+ join->send_records= table->found_records;
+ }
+ else
+ {
+ table->file->info(HA_STATUS_VARIABLE);
+ join->send_records = table->file->records;
+ }
+ }
+ else
+ {
+ join->do_send_rows=0;
+ join->thd->select_limit = HA_POS_ERROR;
+ DBUG_RETURN(0);
+ }
+ }
DBUG_RETURN(-3); // Abort nicely
+ }
}
else
{
@@ -4662,12 +4977,12 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->procedure->end_group();
if (idx < (int) join->send_group_parts)
{
- int error;
+ int error=0;
if (join->procedure)
{
if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
- else
+ else if (join->do_send_rows)
error=join->procedure->send_row(*join->fields) ? 1 : 0;
if (end_of_records && join->procedure->end_of_records())
error= 1; // Fatal error
@@ -4682,15 +4997,25 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
- else
+ else if (join->do_send_rows)
error=join->result->send_data(*join->fields) ? 1 : 0;
}
if (error > 0)
DBUG_RETURN(-1); /* purecov: inspected */
if (end_of_records)
+ {
+ join->send_records++;
DBUG_RETURN(0);
- if (!error && ++join->send_records >= join->thd->select_limit)
- DBUG_RETURN(-3); /* Abort nicely */
+ }
+ if (!error &&
+ ++join->send_records >= join->thd->select_limit &&
+ join->do_send_rows)
+ {
+ if (!(join->select_options & OPTION_FOUND_ROWS))
+ DBUG_RETURN(-3); // Abort nicely
+ join->do_send_rows=0;
+ join->thd->select_limit = HA_POS_ERROR;
+ }
}
}
else
@@ -4736,6 +5061,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
copy_fields(&join->tmp_table_param);
copy_funcs(join->tmp_table_param.funcs);
+#ifdef TO_BE_DELETED
if (!table->uniques) // If not unique handling
{
/* Copy null values from group to row */
@@ -4746,10 +5072,11 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (item->maybe_null)
{
Field *field=item->tmp_table_field();
- field->ptr[-1]= (byte) (field->is_null() ? 0 : 1);
+ field->ptr[-1]= (byte) (field->is_null() ? 1 : 0);
}
}
}
+#endif
if (!join->having || join->having->val_int())
{
join->found_records++;
@@ -4761,8 +5088,15 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (create_myisam_from_heap(table, &join->tmp_table_param, error,1))
DBUG_RETURN(1); // Not a table_is_full error
table->uniques=0; // To ensure rows are the same
- if (++join->send_records >= join->tmp_table_param.end_write_records)
+ }
+ if (++join->send_records >= join->tmp_table_param.end_write_records &&
+ join->do_send_rows)
+ {
+ if (!(join->select_options & OPTION_FOUND_ROWS))
DBUG_RETURN(-3);
+ join->do_send_rows=0;
+ join->thd->select_limit = HA_POS_ERROR;
+ DBUG_RETURN(0);
}
}
}
@@ -4797,8 +5131,9 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
Item *item= *group->item;
item->save_org_in_field(group->field);
+ /* Store in the used key if the field was 0 */
if (item->maybe_null)
- group->buff[0]=item->null_value ? 0: 1; // Save reversed value
+ group->buff[-1]=item->null_value ? 1 : 0;
}
// table->file->index_init(0);
if (!table->file->index_read(table->record[1],
@@ -4956,11 +5291,11 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/*****************************************************************************
-** Remove calculation with tables that aren't yet read. Remove also tests
-** against fields that are read through key where the table is not a
-** outer join table.
-** We can't remove tests that are made against columns which are stored
-** in sorted order.
+ Remove calculation with tables that aren't yet read. Remove also tests
+ against fields that are read through key where the table is not a
+ outer join table.
+ We can't remove tests that are made against columns which are stored
+ in sorted order.
*****************************************************************************/
/* Return 1 if right_item is used removable reference key on left_item */
@@ -4976,11 +5311,12 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
{
if (right_item->type() == Item::FIELD_ITEM)
return (field->eq_def(((Item_field *) right_item)->field));
- if (right_item->const_item() &&
- (right_item->val_int() || !right_item->null_value))
+ if (right_item->const_item() && !(right_item->is_null()))
{
- // We can remove binary fields and numerical fields except float,
- // as float comparison isn't 100 % secure
+ /*
+ We can remove binary fields and numerical fields except float,
+ as float comparison isn't 100 % secure
+ */
if (field->binary() &&
(field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0))
{
@@ -5044,9 +5380,9 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
}
/*
- ** Because the following test takes a while and it can be done
- ** table_count times, we mark each item that we have examined with the result
- ** of the test
+ Because the following test takes a while and it can be done
+ table_count times, we mark each item that we have examined with the result
+ of the test
*/
if (cond->marker == 3 || (cond->used_tables() & ~tables))
@@ -5094,13 +5430,15 @@ part_of_refkey(TABLE *table,Field *field)
/*****************************************************************************
-** Test if one can use the key to resolve ORDER BY
-** Returns: 1 if key is ok.
-** 0 if key can't be used
-** -1 if reverse key can be used
+ Test if one can use the key to resolve ORDER BY
+ Returns: 1 if key is ok.
+ 0 if key can't be used
+ -1 if reverse key can be used
+ used_key_parts is set to key parts used if length != 0
*****************************************************************************/
-static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx)
+static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
+ uint *used_key_parts)
{
KEY_PART_INFO *key_part,*key_part_end;
key_part=table->key_info[idx].key_part;
@@ -5132,6 +5470,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx)
reverse=flag; // Remember if reverse
key_part++;
}
+ *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
return reverse;
}
@@ -5154,17 +5493,20 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys)
}
-/*****************************************************************************
-** If not selecting by given key, create a index how records should be read
-** return: 0 ok
-** -1 some fatal error
-** 1 no records
-*****************************************************************************/
+/*
+ Test if we can skip the ORDER BY by using an index.
+
+ If we can use an index, the JOIN_TAB / tab->select struct
+ is changed to use the index.
-/* Return 1 if we don't have to do file sorting */
+ Return:
+ 0 We have to use filesort to do the sorting
+ 1 We can use an index.
+*/
static bool
-test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
+test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
+ bool no_changes)
{
int ref_key;
TABLE *table=tab->table;
@@ -5192,10 +5534,55 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
if (ref_key >= 0)
{
+ /*
+ We come here when there is a REF key.
+ */
+ int order_direction;
+ uint used_key_parts;
/* Check if we get the rows in requested sorted order by using the key */
if ((usable_keys & ((key_map) 1 << ref_key)) &&
- test_if_order_by_key(order,table,ref_key) == 1)
+ (order_direction = test_if_order_by_key(order,table,ref_key,
+ &used_key_parts)))
+ {
+ if (order_direction == -1) // If ORDER BY ... DESC
+ {
+ if (select && select->quick)
+ {
+ /*
+ Don't reverse the sort order, if it's already done.
+ (In some cases test_if_order_by_key() can be called multiple times
+ */
+ if (!select->quick->reverse_sorted())
+ {
+ // ORDER BY range_key DESC
+ QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC(select->quick,
+ used_key_parts);
+ if (!tmp || tmp->error)
+ {
+ delete tmp;
+ DBUG_RETURN(0); // Reverse sort not supported
+ }
+ select->quick=tmp;
+ }
+ DBUG_RETURN(1);
+ }
+ if (tab->ref.key_parts < used_key_parts)
+ {
+ /*
+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
+
+ Use a traversal function that starts by reading the last row
+ with key part (A) and then traverse the index backwards.
+ */
+ if (table->file->table_flags() & HA_NOT_READ_PREFIX_LAST)
+ DBUG_RETURN(1);
+ tab->read_first_record= join_read_last_key;
+ tab->read_record.read_record= join_read_prev_same;
+ /* fall through */
+ }
+ }
DBUG_RETURN(1); /* No need to sort */
+ }
}
else
{
@@ -5214,20 +5601,24 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
for (nr=0; keys ; keys>>=1, nr++)
{
+ uint not_used;
if (keys & 1)
{
int flag;
- if ((flag=test_if_order_by_key(order,table,nr)))
+ if ((flag=test_if_order_by_key(order, table, nr, &not_used)))
{
- tab->index=nr;
- tab->read_first_record= (flag > 0 ? join_init_read_first_with_key:
- join_init_read_last_with_key);
- table->file->index_init(nr);
- tab->type=JT_NEXT; // Read with index_first(), index_next()
- if (table->used_keys & ((key_map) 1 << nr))
+ if (!no_changes)
{
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
+ tab->index=nr;
+ tab->read_first_record= (flag > 0 ? join_read_first:
+ join_read_last);
+ table->file->index_init(nr);
+ tab->type=JT_NEXT; // Read with index_first(), index_next()
+ if (table->used_keys & ((key_map) 1 << nr))
+ {
+ table->key_read=1;
+ table->file->extra(HA_EXTRA_KEYREAD);
+ }
}
DBUG_RETURN(1);
}
@@ -5237,6 +5628,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
DBUG_RETURN(0); // Can't use index.
}
+
+/*****************************************************************************
+ If not selecting by given key, create an index how records should be read
+ return: 0 ok
+ -1 some fatal error
+ 1 no records
+*****************************************************************************/
+
static int
create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
{
@@ -5247,7 +5646,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
SQL_SELECT *select=tab->select;
DBUG_ENTER("create_sort_index");
- if (test_if_skip_sort_order(tab,order,select_limit))
+ if (test_if_skip_sort_order(tab,order,select_limit,0))
DBUG_RETURN(0);
if (!(sortorder=make_unireg_sortorder(order,&length)))
goto err; /* purecov: inspected */
@@ -5280,8 +5679,11 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
goto err;
}
}
- table->found_records=filesort(&table,sortorder,length,
+ if (table->tmp_table)
+ table->file->info(HA_STATUS_VARIABLE); // Get record count
+ table->found_records=filesort(table,sortorder,length,
select, 0L, select_limit, &examined_rows);
+ tab->records=table->found_records; // For SQL_CALC_ROWS
delete select; // filesort did select
tab->select=0;
tab->select_cond=0;
@@ -5298,11 +5700,11 @@ err:
DBUG_RETURN(-1);
}
-
/*
-** Add the HAVING criteria to table->select
+ Add the HAVING criteria to table->select
*/
+#ifdef NOT_YET
static bool fix_having(JOIN *join, Item **having)
{
(*having)->update_used_tables(); // Some tables may have been const
@@ -5330,14 +5732,15 @@ static bool fix_having(JOIN *join, Item **having)
}
return 0;
}
+#endif
/*****************************************************************************
-** Remove duplicates from tmp table
-** This should be recoded to add a uniuqe index to the table and remove
-** dupplicates
-** Table is a locked single thread table
-** fields is the number of fields to check (from the end)
+ Remove duplicates from tmp table
+ This should be recoded to add a unique index to the table and remove
+ duplicates
+ Table is a locked single thread table
+ fields is the number of fields to check (from the end)
*****************************************************************************/
static bool compare_record(TABLE *table, Field **ptr)
@@ -5377,10 +5780,11 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
int error;
ulong reclength,offset;
uint field_count;
+ THD *thd= current_thd;
+
DBUG_ENTER("remove_duplicates");
entry->reginfo.lock_type=TL_WRITE;
- entry->file->extra(HA_EXTRA_NO_READCHECK);
/* Calculate how many saved fields there is in list */
field_count=0;
@@ -5394,7 +5798,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
if (!field_count)
{ // only const items
- join->thd->select_limit=1; // Only send first row
+ join->thd->select_limit=1; // Only send first row
DBUG_RETURN(0);
}
Field **first_field=entry->field+entry->fields - field_count;
@@ -5406,7 +5810,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
if (entry->db_type == DB_TYPE_HEAP ||
(!entry->blob_fields &&
((ALIGN_SIZE(reclength) +sizeof(HASH_LINK)) * entry->file->records <
- sortbuff_size)))
+ thd->variables.sortbuff_size)))
error=remove_dup_with_hash_index(join->thd, entry,
field_count, first_field,
reclength, having);
@@ -5566,7 +5970,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
if ((error=file->delete_row(record)))
goto err;
continue;
- }
+ }
/* copy fields to key buffer */
field_length=field_lengths;
@@ -5727,7 +6131,7 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
cache->length=length+blobs*sizeof(char*);
cache->blobs=blobs;
*blob_ptr=0; /* End sequentel */
- size=max(join_buff_size,cache->length);
+ size=max(thd->variables.join_buff_size, cache->length);
if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
cache->end=cache->buff+size;
@@ -5768,7 +6172,7 @@ store_record_in_cache(JOIN_CACHE *cache)
cache->ptr_record=cache->records;
/*
- ** There is room in cache. Put record there
+ There is room in cache. Put record there
*/
cache->records++;
for (copy=cache->field ; copy < end_field; copy++)
@@ -5894,13 +6298,13 @@ cp_buffer_from_ref(TABLE_REF *ref)
/*****************************************************************************
-** Group and order functions
+ Group and order functions
*****************************************************************************/
/*
-** Find order/group item in requested columns and change the item to point at
-** it. If item doesn't exists, add it first in the field list
-** Return 0 if ok.
+ Find order/group item in requested columns and change the item to point at
+ it. If item doesn't exists, add it first in the field list
+ Return 0 if ok.
*/
static int
@@ -5945,8 +6349,8 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
/*
-** Change order to point at item in select list. If item isn't a number
-** and doesn't exits in the select list, add it the the field list.
+ Change order to point at item in select list. If item isn't a number
+ and doesn't exits in the select list, add it the the field list.
*/
int setup_order(THD *thd,TABLE_LIST *tables,List<Item> &fields,
@@ -5980,7 +6384,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
uint org_fields=all_fields.elements;
thd->where="group statement";
- for ( ; order; order=order->next)
+ for (; order; order=order->next)
{
if (find_order_in_list(thd,tables,order,fields,all_fields))
return 1;
@@ -6015,7 +6419,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
}
/*
-** Add fields with aren't used at start of field list. Return FALSE if ok
+ Add fields with aren't used at start of field list. Return FALSE if ok
*/
static bool
@@ -6027,7 +6431,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
thd->set_query_id=1; // Not really needed, but...
thd->where=0; // Don't give error
- for ( ; new_field ; new_field=new_field->next)
+ for (; new_field ; new_field=new_field->next)
{
if ((item=find_item_in_list(*new_field->item,fields)))
new_field->item=item; /* Change to shared Item */
@@ -6045,9 +6449,9 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
}
/*
-** Create a group by that consist of all non const fields. Try to use
-** the fields in the order given by 'order' to allow one to optimize
-** away 'order by'.
+ Create a group by that consist of all non const fields. Try to use
+ the fields in the order given by 'order' to allow one to optimize
+ away 'order by'.
*/
static ORDER *
@@ -6096,7 +6500,7 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
/*****************************************************************************
-** Update join with count of the different type of fields
+ Update join with count of the different type of fields
*****************************************************************************/
void
@@ -6106,7 +6510,7 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
List_iterator<Item> li(fields);
Item *field;
- param->field_count=param->sum_func_count=param->func_count=
+ param->field_count=param->sum_func_count=param->func_count=
param->hidden_field_count=0;
param->quick_group=1;
while ((field=li++))
@@ -6187,7 +6591,7 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
if (!map || (map & RAND_TABLE_BIT))
DBUG_RETURN(0);
- for ( ; !(map & tables->table->map) ; tables=tables->next) ;
+ for (; !(map & tables->table->map) ; tables=tables->next) ;
if (map != tables->table->map)
DBUG_RETURN(0); // More than one table
DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr));
@@ -6200,7 +6604,8 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
static void
calc_group_buffer(JOIN *join,ORDER *group)
{
- uint key_length=0,parts=0;
+ uint key_length=0, parts=0, null_parts=0;
+
if (group)
join->group= 1;
for (; group ; group=group->next)
@@ -6221,16 +6626,17 @@ calc_group_buffer(JOIN *join,ORDER *group)
key_length+=(*group->item)->max_length;
parts++;
if ((*group->item)->maybe_null)
- key_length++;
+ null_parts++;
}
- join->tmp_table_param.group_length=key_length;
+ join->tmp_table_param.group_length=key_length+null_parts;
join->tmp_table_param.group_parts=parts;
+ join->tmp_table_param.group_null_parts=null_parts;
}
/*
-** Get a list of buffers for saveing last group
-** Groups are saved in reverse order for easyer check loop
+ Get a list of buffers for saveing last group
+ Groups are saved in reverse order for easyer check loop
*/
static bool
@@ -6268,14 +6674,14 @@ test_if_group_changed(List<Item_buff> &list)
/*
-** Setup copy_fields to save fields at start of new group
-** Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
-** Change old item_field to use a new field with points at saved fieldvalue
-** This function is only called before use of send_fields
+ Setup copy_fields to save fields at start of new group
+ Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
+ Change old item_field to use a new field with points at saved fieldvalue
+ This function is only called before use of send_fields
*/
bool
-setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
+setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields)
{
Item *pos;
List_iterator<Item> li(fields);
@@ -6283,7 +6689,7 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
DBUG_ENTER("setup_copy_fields");
if (!(copy=param->copy_field= new Copy_field[param->field_count]))
- goto err;
+ goto err2;
param->copy_funcs.empty();
while ((pos=li++))
@@ -6303,7 +6709,7 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
/* set up save buffer and change result_field to point at saved value */
Field *field= item->field;
- item->result_field=field->new_field(field->table);
+ item->result_field=field->new_field(&thd->mem_root,field->table);
char *tmp=(char*) sql_alloc(field->pack_length()+1);
if (!tmp)
goto err;
@@ -6328,40 +6734,40 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
goto err;
}
}
- param->copy_field_count= (uint) (copy - param->copy_field);
+ param->copy_field_end= copy;
DBUG_RETURN(0);
err:
- delete [] param->copy_field;
+ delete [] param->copy_field; // This is never 0
param->copy_field=0;
+err2:
DBUG_RETURN(TRUE);
}
/*
-** Copy fields and null values between two tables
+ Copy fields and null values between two tables
*/
void
copy_fields(TMP_TABLE_PARAM *param)
{
Copy_field *ptr=param->copy_field;
- Copy_field *end=ptr+param->copy_field_count;
+ Copy_field *end=param->copy_field_end;
- for ( ; ptr != end; ptr++)
+ for (; ptr != end; ptr++)
(*ptr->do_copy)(ptr);
- List_iterator<Item> it(param->copy_funcs);
+ List_iterator_fast<Item> &it=param->copy_funcs_it;
+ it.rewind();
Item_copy_string *item;
while ((item = (Item_copy_string*) it++))
- {
item->copy();
- }
}
/*****************************************************************************
-** Make an array of pointer to sum_functions to speed up sum_func calculation
+ Make an array of pointer to sum_functions to speed up sum_func calculation
*****************************************************************************/
static bool
@@ -6393,7 +6799,7 @@ make_sum_func_list(JOIN *join,List<Item> &fields)
/*
-** Change all funcs and sum_funcs to fields in tmp table
+ Change all funcs and sum_funcs to fields in tmp table
*/
static bool
@@ -6443,8 +6849,8 @@ change_to_use_tmp_fields(List<Item> &items)
/*
-** Change all sum_func refs to fields to point at fields in tmp table
-** Change all funcs to be fields in tmp table
+ Change all sum_func refs to fields to point at fields in tmp table
+ Change all funcs to be fields in tmp table
*/
static bool
@@ -6500,7 +6906,7 @@ change_refs_to_tmp_fields(THD *thd,List<Item> &items)
/******************************************************************************
-** code for calculating functions
+ Code for calculating functions
******************************************************************************/
static void
@@ -6568,8 +6974,8 @@ copy_funcs(Item_result_field **func_ptr)
/*****************************************************************************
-** Create a condition for a const reference and add this to the
-** currenct select for the table
+ Create a condition for a const reference and add this to the
+ currenct select for the table
*****************************************************************************/
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
@@ -6610,178 +7016,221 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
}
/****************************************************************************
-** Send a description about what how the select will be done to stdout
+ Send a description about what how the select will be done to stdout
****************************************************************************/
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
- bool distinct)
+ bool distinct,const char *message)
{
List<Item> field_list;
Item *item;
+ List<Item> item_list;
THD *thd=join->thd;
+ MYSQL_LOCK *save_lock;
+ SELECT_LEX *select_lex = &(join->thd->lex.select_lex);
+ select_result *result=join->result;
+ Item *item_null= new Item_null();
DBUG_ENTER("select_describe");
/* Don't log this into the slow query log */
- join->thd->lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
- field_list.push_back(new Item_empty_string("table",NAME_LEN));
- field_list.push_back(new Item_empty_string("type",10));
- field_list.push_back(item=new Item_empty_string("possible_keys",
+ select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
+ thd->offset_limit=0;
+ if (thd->lex.select == select_lex)
+ {
+ field_list.push_back(new Item_empty_string("table",NAME_LEN));
+ field_list.push_back(new Item_empty_string("type",10));
+ field_list.push_back(item=new Item_empty_string("possible_keys",
NAME_LEN*MAX_KEY));
- item->maybe_null=1;
- field_list.push_back(item=new Item_empty_string("key",NAME_LEN));
- item->maybe_null=1;
- field_list.push_back(item=new Item_int("key_len",0,3));
- item->maybe_null=1;
- field_list.push_back(item=new Item_empty_string("ref",
- NAME_LEN*MAX_REF_PARTS));
- item->maybe_null=1;
- field_list.push_back(new Item_real("rows",0.0,0,10));
- field_list.push_back(new Item_empty_string("Extra",255));
- if (send_fields(thd,field_list,1))
- return; /* purecov: inspected */
+ item->maybe_null=1;
+ field_list.push_back(item=new Item_empty_string("key",NAME_LEN));
+ item->maybe_null=1;
+ field_list.push_back(item=new Item_int("key_len",0,3));
+ item->maybe_null=1;
+ field_list.push_back(item=new Item_empty_string("ref",
+ NAME_LEN*MAX_REF_PARTS));
+ item->maybe_null=1;
+ field_list.push_back(new Item_real("rows",0.0,0,10));
+ field_list.push_back(new Item_empty_string("Extra",255));
+ if (result->send_fields(field_list,1))
+ return;
+ }
- char buff[512],*buff_ptr;
- String tmp(buff,sizeof(buff)),*packet= &thd->packet;
- table_map used_tables=0;
- for (uint i=0 ; i < join->tables ; i++)
+ if (message)
{
- JOIN_TAB *tab=join->join_tab+i;
- TABLE *table=tab->table;
-
- if (tab->type == JT_ALL && tab->select && tab->select->quick)
- tab->type= JT_RANGE;
- packet->length(0);
- net_store_data(packet,table->table_name);
- net_store_data(packet,join_type_str[tab->type]);
- tmp.length(0);
- key_map bits;
- uint j;
- for (j=0,bits=tab->keys ; bits ; j++,bits>>=1)
- {
- if (bits & 1)
+ Item *empty= new Item_empty_string("",0);
+ for (uint i=0 ; i < 7; i++)
+ item_list.push_back(empty);
+ item_list.push_back(new Item_string(message,strlen(message)));
+ if (result->send_data(item_list))
+ result->send_error(0,NullS);
+ }
+ else
+ {
+ table_map used_tables=0;
+ for (uint i=0 ; i < join->tables ; i++)
+ {
+ JOIN_TAB *tab=join->join_tab+i;
+ TABLE *table=tab->table;
+ char buff[512],*buff_ptr=buff;
+ char buff1[512], buff2[512], buff3[512];
+ String tmp1(buff1,sizeof(buff1));
+ String tmp2(buff2,sizeof(buff2));
+ tmp1.length(0);
+ tmp2.length(0);
+ item_list.empty();
+
+ if (tab->type == JT_ALL && tab->select && tab->select->quick)
+ tab->type= JT_RANGE;
+ item_list.push_back(new Item_string(table->table_name,
+ strlen(table->table_name)));
+ item_list.push_back(new Item_string(join_type_str[tab->type],
+ strlen(join_type_str[tab->type])));
+ key_map bits;
+ uint j;
+ for (j=0,bits=tab->keys ; bits ; j++,bits>>=1)
{
- if (tmp.length())
- tmp.append(',');
- tmp.append(table->key_info[j].name);
+ if (bits & 1)
+ {
+ if (tmp1.length())
+ tmp1.append(',');
+ tmp1.append(table->key_info[j].name);
+ }
}
- }
- if (tmp.length())
- net_store_data(packet,tmp.ptr(),tmp.length());
- else
- net_store_null(packet);
- if (tab->ref.key_parts)
- {
- net_store_data(packet,table->key_info[tab->ref.key].name);
- net_store_data(packet,(uint32) tab->ref.key_length);
- tmp.length(0);
- for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
+ if (tmp1.length())
+ item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length()));
+ else
+ item_list.push_back(item_null);
+ if (tab->ref.key_parts)
{
- if (tmp.length())
- tmp.append(',');
- tmp.append((*ref)->name());
+ KEY *key_info=table->key_info+ tab->ref.key;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
+ item_list.push_back(new Item_int((int32) tab->ref.key_length));
+ for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
+ {
+ if (tmp2.length())
+ tmp2.append(',');
+ tmp2.append((*ref)->name());
+ }
+ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length()));
}
- net_store_data(packet,tmp.ptr(),tmp.length());
- }
- else if (tab->type == JT_NEXT)
- {
- net_store_data(packet,table->key_info[tab->index].name);
- net_store_data(packet,(uint32) table->key_info[tab->index].key_length);
- net_store_null(packet);
- }
- else if (tab->select && tab->select->quick)
- {
- net_store_data(packet,table->key_info[tab->select->quick->index].name);;
- net_store_data(packet,(uint32) tab->select->quick->max_used_key_length);
- net_store_null(packet);
- }
- else
- {
- net_store_null(packet);
- net_store_null(packet);
- net_store_null(packet);
- }
- sprintf(buff,"%.0f",join->best_positions[i].records_read);
- net_store_data(packet,buff);
- my_bool key_read=table->key_read;
- if (tab->type == JT_NEXT &&
- ((table->used_keys & ((key_map) 1 << tab->index))))
- key_read=1;
-
- buff_ptr=buff;
- if (tab->info)
- net_store_data(packet,tab->info);
- else if (tab->select)
- {
- if (tab->use_quick == 2)
+ else if (tab->type == JT_NEXT)
+ {
+ KEY *key_info=table->key_info+ tab->index;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
+ item_list.push_back(new Item_int((int32) key_info->key_length));
+ item_list.push_back(item_null);
+ }
+ else if (tab->select && tab->select->quick)
{
- sprintf(buff_ptr,"range checked for each record (index map: %u)",
- tab->keys);
- buff_ptr=strend(buff_ptr);
+ KEY *key_info=table->key_info+ tab->select->quick->index;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
+ item_list.push_back(new Item_int((int32) tab->select->quick->max_used_key_length));
+ item_list.push_back(item_null);
}
else
- buff_ptr=strmov(buff_ptr,"where used");
- }
- if (key_read)
- {
- if (buff != buff_ptr)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ item_list.push_back(item_null);
+ item_list.push_back(item_null);
+ item_list.push_back(item_null);
}
- buff_ptr=strmov(buff_ptr,"Using index");
- }
- if (table->reginfo.not_exists_optimize)
- {
- if (buff != buff_ptr)
+ sprintf(buff3,"%.0f",join->best_positions[i].records_read);
+ item_list.push_back(new Item_string(buff3,strlen(buff3)));
+ my_bool key_read=table->key_read;
+ if (tab->type == JT_NEXT &&
+ ((table->used_keys & ((key_map) 1 << tab->index))))
+ key_read=1;
+
+ if (tab->info)
+ item_list.push_back(new Item_string(tab->info,strlen(tab->info)));
+ else if (tab->select)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ if (tab->use_quick == 2)
+ {
+ sprintf(buff_ptr,"range checked for each record (index map: %u)",
+ tab->keys);
+ buff_ptr=strend(buff_ptr);
+ }
+ else
+ buff_ptr=strmov(buff_ptr,"where used");
}
- buff_ptr=strmov(buff_ptr,"Not exists");
- }
- if (need_tmp_table)
- {
- need_tmp_table=0;
- if (buff != buff_ptr)
+ if (key_read)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ if (buff != buff_ptr)
+ {
+ buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ }
+ buff_ptr=strmov(buff_ptr,"Using index");
}
- buff_ptr=strmov(buff_ptr,"Using temporary");
- }
- if (need_order)
- {
- need_order=0;
- if (buff != buff_ptr)
+ if (table->reginfo.not_exists_optimize)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ if (buff != buff_ptr)
+ {
+ buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ }
+ buff_ptr=strmov(buff_ptr,"Not exists");
}
- buff_ptr=strmov(buff_ptr,"Using filesort");
- }
- if (distinct & test_all_bits(used_tables,thd->used_tables))
- {
- if (buff != buff_ptr)
+ if (need_tmp_table)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ need_tmp_table=0;
+ if (buff != buff_ptr)
+ {
+ buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ }
+ buff_ptr=strmov(buff_ptr,"Using temporary");
}
- buff_ptr=strmov(buff_ptr,"Distinct");
+ if (need_order)
+ {
+ need_order=0;
+ if (buff != buff_ptr)
+ {
+ buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ }
+ buff_ptr=strmov(buff_ptr,"Using filesort");
+ }
+ if (distinct & test_all_bits(used_tables,thd->used_tables))
+ {
+ if (buff != buff_ptr)
+ {
+ buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ }
+ buff_ptr=strmov(buff_ptr,"Distinct");
+ }
+ item_list.push_back(new Item_string(buff,(uint) (buff_ptr - buff)));
+ // For next iteration
+ used_tables|=table->map;
+ if (result->send_data(item_list))
+ result->send_error(0,NullS);
}
- net_store_data(packet,buff,(uint) (buff_ptr - buff));
- if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
- DBUG_VOID_RETURN; /* purecov: inspected */
-
- // For next iteration
- used_tables|=table->map;
}
- send_eof(&thd->net);
+ if (!thd->lex.select->next) // Not union
+ {
+ save_lock=thd->lock;
+ thd->lock=(MYSQL_LOCK *)0;
+ result->send_eof();
+ thd->lock=save_lock;
+ }
DBUG_VOID_RETURN;
}
-static void describe_info(THD *thd, const char *info)
+static void describe_info(JOIN *join, const char *info)
{
+ THD *thd= join->thd;
+
+ if (thd->lex.select_lex.next) /* If in UNION */
+ {
+ select_describe(join,FALSE,FALSE,FALSE,info);
+ return;
+ }
List<Item> field_list;
String *packet= &thd->packet;
/* Don't log this into the slow query log */
- thd->lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
+ thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED |
+ QUERY_NO_GOOD_INDEX_USED);
field_list.push_back(new Item_empty_string("Comment",80));
if (send_fields(thd,field_list,1))
return; /* purecov: inspected */
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 1bf7d7863eb..befa1efde53 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -118,19 +118,22 @@ typedef struct st_position { /* Used in find_best */
class TMP_TABLE_PARAM {
public:
List<Item> copy_funcs;
- Copy_field *copy_field;
+ List_iterator_fast<Item> copy_funcs_it;
+ Copy_field *copy_field, *copy_field_end;
byte *group_buff;
Item_result_field **funcs;
MI_COLUMNDEF *recinfo,*start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
- uint copy_field_count,field_count,sum_func_count,func_count;
+ uint field_count,sum_func_count,func_count;
uint hidden_field_count;
- uint group_parts,group_length;
+ uint group_parts,group_length,group_null_parts;
uint quick_group;
bool using_indirect_summary_function;
- TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0)
+ TMP_TABLE_PARAM()
+ :copy_funcs_it(copy_funcs), copy_field(0), group_parts(0),
+ group_length(0), group_null_parts(0)
{}
~TMP_TABLE_PARAM()
{
@@ -154,7 +157,8 @@ class JOIN {
uint tables,const_tables;
uint send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update;
- table_map const_table_map,outer_join;
+ bool do_send_rows;
+ table_map const_table_map,found_const_table_map,outer_join;
ha_rows send_records,found_records,examined_rows,row_limit;
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
double best_read;
@@ -183,11 +187,11 @@ void TEST_join(JOIN *join);
bool store_val_in_field(Field *field,Item *val);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
- bool allow_distinct_limit, uint select_options);
+ bool allow_distinct_limit, ulong select_options);
void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func);
-bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields);
+bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item_result_field **func_ptr);
bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
@@ -207,7 +211,7 @@ class store_key :public Sql_alloc
char *null_ptr;
char err;
public:
- store_key(Field *field_arg, char *ptr, char *null, uint length)
+ store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length)
:null_ptr(null),err(0)
{
if (field_arg->type() == FIELD_TYPE_BLOB)
@@ -216,7 +220,7 @@ class store_key :public Sql_alloc
field_arg->table, field_arg->binary());
else
{
- to_field=field_arg->new_field(field_arg->table);
+ to_field=field_arg->new_field(&thd->mem_root,field_arg->table);
if (to_field)
to_field->move_field(ptr, (uchar*) null, 1);
}
@@ -232,9 +236,9 @@ class store_key_field: public store_key
Copy_field copy_field;
const char *field_name;
public:
- store_key_field(Field *to_field_arg, char *ptr, char *null_ptr_arg,
+ store_key_field(THD *thd, Field *to_field_arg, char *ptr, char *null_ptr_arg,
uint length, Field *from_field, const char *name_arg)
- :store_key(to_field_arg,ptr,
+ :store_key(thd, to_field_arg,ptr,
null_ptr_arg ? null_ptr_arg : from_field->maybe_null() ? &err
: NullS,length), field_name(name_arg)
{
@@ -257,9 +261,9 @@ class store_key_item :public store_key
protected:
Item *item;
public:
- store_key_item(Field *to_field_arg, char *ptr, char *null_ptr_arg,
+ store_key_item(THD *thd, Field *to_field_arg, char *ptr, char *null_ptr_arg,
uint length, Item *item_arg)
- :store_key(to_field_arg,ptr,
+ :store_key(thd, to_field_arg,ptr,
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
&err : NullS, length), item(item_arg)
{}
@@ -276,10 +280,10 @@ class store_key_const_item :public store_key_item
{
bool inited;
public:
- store_key_const_item(Field *to_field_arg, char *ptr,
+ store_key_const_item(THD *thd, Field *to_field_arg, char *ptr,
char *null_ptr_arg, uint length,
Item *item_arg)
- :store_key_item(to_field_arg,ptr,
+ :store_key_item(thd, to_field_arg,ptr,
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
&err : NullS, length, item_arg), inited(0)
{
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 5db2df85fbf..24f5ddeab7a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -20,6 +20,7 @@
#include "mysql_priv.h"
#include "sql_select.h" // For select_describe
#include "sql_acl.h"
+#include "repl_failsafe.h"
#include <my_dir.h>
#ifdef HAVE_BERKELEY_DB
@@ -45,6 +46,8 @@ store_create_info(THD *thd, TABLE *table, String *packet);
static void
append_identifier(THD *thd, String *packet, const char *name);
+extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
+
/****************************************************************************
** Send list of databases
** A database is a directory in the mysql_data_home directory
@@ -72,16 +75,16 @@ mysqld_show_dbs(THD *thd,const char *wild)
DBUG_RETURN(1);
if (mysql_find_files(thd,&files,NullS,mysql_data_home,wild,1))
DBUG_RETURN(1);
- List_iterator<char> it(files);
+ List_iterator_fast<char> it(files);
while ((file_name=it++))
{
- if (!opt_safe_show_db || thd->master_access ||
+ if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, file_name) ||
(grant_option && !check_grant_db(thd, file_name)))
- {
+ {
thd->packet.length(0);
- net_store_data(&thd->packet,file_name);
+ net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
thd->packet.length()))
DBUG_RETURN(-1);
@@ -95,34 +98,31 @@ mysqld_show_dbs(THD *thd,const char *wild)
** List all open tables in a database
***************************************************************************/
-int mysqld_show_open_tables(THD *thd,const char *db,const char *wild)
+int mysqld_show_open_tables(THD *thd,const char *wild)
{
- Item_string *field=new Item_string("",0);
List<Item> field_list;
- char *end,*table_name;
- List<char> tables;
+ OPEN_TABLE_LIST *open_list;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_open_tables");
- field->name=(char*) thd->alloc(20+(uint) strlen(db)+(wild ? (uint) strlen(wild)+4:0));
- end=strxmov(field->name,"Open_tables_in_",db,NullS);
- if (wild && wild[0])
- strxmov(end," (",wild,")",NullS);
- field->max_length=NAME_LEN;
- field_list.push_back(field);
- field_list.push_back(new Item_empty_string("Comment",80));
+ field_list.push_back(new Item_empty_string("Database",NAME_LEN));
+ field_list.push_back(new Item_empty_string("Table",NAME_LEN));
+ field_list.push_back(new Item_int("In_use",0, 4));
+ field_list.push_back(new Item_int("Name_locked",0, 4));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
- if (list_open_tables(thd,&tables,db,wild))
+ if (!(open_list=list_open_tables(thd,wild)) && thd->fatal_error)
DBUG_RETURN(-1);
- List_iterator<char> it(tables);
- while ((table_name=it++))
+ for (; open_list ; open_list=open_list->next)
{
thd->packet.length(0);
- net_store_data(&thd->packet,table_name);
- net_store_data(&thd->packet,query_table_status(thd,db,table_name));
+ net_store_data(&thd->packet,convert, open_list->db);
+ net_store_data(&thd->packet,convert, open_list->table);
+ net_store_data(&thd->packet,open_list->in_use);
+ net_store_data(&thd->packet,open_list->locked);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
}
@@ -157,11 +157,11 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild)
DBUG_RETURN(1);
if (mysql_find_files(thd,&files,db,path,wild,0))
DBUG_RETURN(-1);
- List_iterator<char> it(files);
+ List_iterator_fast<char> it(files);
while ((file_name=it++))
{
thd->packet.length(0);
- net_store_data(&thd->packet,file_name);
+ net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
}
@@ -257,6 +257,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
char *file_name;
TABLE *table;
String *packet= &thd->packet;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_extend_show_tables");
(void) sprintf(path,"%s/%s",mysql_data_home,db);
@@ -296,20 +297,20 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
if (mysql_find_files(thd,&files,db,path,wild,0))
DBUG_RETURN(-1);
- List_iterator<char> it(files);
+ List_iterator_fast<char> it(files);
while ((file_name=it++))
{
TABLE_LIST table_list;
bzero((char*) &table_list,sizeof(table_list));
packet->length(0);
- net_store_data(packet,file_name);
+ net_store_data(packet,convert, file_name);
table_list.db=(char*) db;
table_list.real_name=table_list.name=file_name;
if (!(table = open_ltable(thd, &table_list, TL_READ)))
{
for (uint i=0 ; i < field_list.elements ; i++)
net_store_null(packet);
- net_store_data(packet,thd->net.last_error);
+ net_store_data(packet,convert, thd->net.last_error);
thd->net.last_error[0]=0;
}
else
@@ -317,8 +318,8 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
struct tm tm_tmp;
handler *file=table->file;
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK);
- net_store_data(packet, file->table_type());
- net_store_data(packet,
+ net_store_data(packet, convert, file->table_type());
+ net_store_data(packet, convert,
(table->db_options_in_use & HA_OPTION_PACK_RECORD) ?
"Dynamic" :
(table->db_options_in_use & HA_OPTION_COMPRESS_RECORD)
@@ -399,7 +400,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE);
ptr=strmov(ptr,buff);
}
- net_store_data(packet, option_buff+1,
+ net_store_data(packet, convert, option_buff+1,
(ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1));
}
{
@@ -432,6 +433,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
handler *file;
char tmp[MAX_FIELD_WIDTH];
Item *item;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_fields");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -487,18 +489,18 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
bool null_default_value=0;
packet->length(0);
- net_store_data(packet,field->field_name);
+ net_store_data(packet,convert,field->field_name);
field->sql_type(type);
- net_store_data(packet,type.ptr(),type.length());
+ net_store_data(packet,convert,type.ptr(),type.length());
pos=(byte*) ((flags & NOT_NULL_FLAG) &&
field->type() != FIELD_TYPE_TIMESTAMP ?
"" : "YES");
- net_store_data(packet,(const char*) pos);
+ net_store_data(packet,convert,(const char*) pos);
pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
- net_store_data(packet,(char*) pos);
+ net_store_data(packet,convert,(char*) pos);
if (field->type() == FIELD_TYPE_TIMESTAMP ||
field->unireg_check == Field::NEXT_NUMBER)
@@ -507,17 +509,17 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
{ // Not null by default
type.set(tmp,sizeof(tmp));
field->val_str(&type,&type);
- net_store_data(packet,type.ptr(),type.length());
+ net_store_data(packet,convert,type.ptr(),type.length());
}
else if (field->maybe_null() || null_default_value)
net_store_null(packet); // Null as default
else
- net_store_data(packet,tmp,0);
+ net_store_data(packet,convert,tmp,0);
char *end=tmp;
if (field->unireg_check == Field::NEXT_NUMBER)
end=strmov(tmp,"auto_increment");
- net_store_data(packet,tmp,(uint) (end-tmp));
+ net_store_data(packet,convert,tmp,(uint) (end-tmp));
if (verbose)
{
@@ -532,7 +534,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
end=strmov(end,grant_types.type_names[bitnr]);
}
}
- net_store_data(packet,tmp+1,end == tmp ? 0 : (uint) (end-tmp-1));
+ net_store_data(packet,convert, tmp+1,end == tmp ? 0 : (uint) (end-tmp-1));
}
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(1);
@@ -547,6 +549,7 @@ int
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_create");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -568,7 +571,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
String *packet = &thd->packet;
{
packet->length(0);
- net_store_data(packet, table->table_name);
+ net_store_data(packet,convert, table->table_name);
/*
A hack - we need to reserve some space for the length before
we know what it is - let's assume that the length of create table
@@ -634,6 +637,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
char buff[256];
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_keys");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -659,6 +663,8 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("Packed",10));
item->maybe_null=1;
+ field_list.push_back(new Item_empty_string("Null",3));
+ field_list.push_back(new Item_empty_string("Index_type",16));
field_list.push_back(new Item_empty_string("Comment",255));
item->maybe_null=1;
@@ -675,16 +681,18 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
{
packet->length(0);
- net_store_data(packet,table->table_name);
- net_store_data(packet,((key_info->flags & HA_NOSAME) ? "0" :"1"), 1);
- net_store_data(packet,key_info->name);
+ net_store_data(packet,convert,table->table_name);
+ net_store_data(packet,convert,((key_info->flags & HA_NOSAME) ? "0" :"1"), 1);
+ net_store_data(packet,convert,key_info->name);
end=int10_to_str((long) (j+1),(char*) buff,10);
- net_store_data(packet,buff,(uint) (end-buff));
- net_store_data(packet,key_part->field ? key_part->field->field_name :
+ net_store_data(packet,convert,buff,(uint) (end-buff));
+ net_store_data(packet,convert,
+ key_part->field ? key_part->field->field_name :
"?unknown field?");
- if (table->file->option_flag() & HA_READ_ORDER)
- net_store_data(packet,((key_part->key_part_flag & HA_REVERSE_SORT)
- ? "D" : "A"), 1);
+ if (table->file->index_flags(i) & HA_READ_ORDER)
+ net_store_data(packet,convert,
+ ((key_part->key_part_flag & HA_REVERSE_SORT) ?
+ "D" : "A"), 1);
else
net_store_null(packet); /* purecov: inspected */
KEY *key=table->key_info+i;
@@ -692,21 +700,30 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
{
ulong records=(table->file->records / key->rec_per_key[j]);
end=int10_to_str((long) records, buff, 10);
- net_store_data(packet,buff,(uint) (end-buff));
+ net_store_data(packet,convert,buff,(uint) (end-buff));
}
else
net_store_null(packet);
+
+ /* Check if we have a key part that only uses part of the field */
if (!key_part->field ||
key_part->length !=
table->field[key_part->fieldnr-1]->key_length())
{
end=int10_to_str((long) key_part->length, buff,10); /* purecov: inspected */
- net_store_data(packet,buff,(uint) (end-buff)); /* purecov: inspected */
+ net_store_data(packet,convert,buff,(uint) (end-buff)); /* purecov: inspected */
}
else
net_store_null(packet);
net_store_null(packet); // No pack_information yet
- net_store_data(packet,key_info->flags & HA_FULLTEXT ? "FULLTEXT":"");
+
+ /* Null flag */
+ uint flags= key_part->field ? key_part->field->flags : 0;
+ char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
+ net_store_data(packet,convert,(const char*) pos);
+ net_store_data(packet,convert,table->file->index_type(i));
+ /* Comment */
+ net_store_data(packet,convert,"");
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(1); /* purecov: inspected */
}
@@ -751,27 +768,29 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
int
mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
{
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_dump_create_info");
DBUG_PRINT("enter",("table: %s",table->real_name));
+
String* packet = &thd->packet;
packet->length(0);
-
- if(store_create_info(thd,table,packet))
+ if (store_create_info(thd,table,packet))
DBUG_RETURN(-1);
- if(fd < 0)
+ if (convert)
+ convert->convert((char*) packet->ptr(), packet->length());
+ if (fd < 0)
{
- if(my_net_write(&thd->net, (char*)packet->ptr(), packet->length()))
+ if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length()))
DBUG_RETURN(-1);
VOID(net_flush(&thd->net));
}
else
{
- if(my_write(fd, (const byte*) packet->ptr(), packet->length(),
- MYF(MY_WME)))
+ if (my_write(fd, (const byte*) packet->ptr(), packet->length(),
+ MYF(MY_WME)))
DBUG_RETURN(-1);
}
-
DBUG_RETURN(0);
}
@@ -999,7 +1018,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
Item *field;
List<Item> field_list;
I_List<thread_info> thread_infos;
- ulong max_query_length= verbose ? max_allowed_packet : PROCESS_LIST_WIDTH;
+ ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
+ PROCESS_LIST_WIDTH);
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_list_processes");
field_list.push_back(new Item_int("Id",0,7));
@@ -1029,10 +1050,13 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thread_info *thd_info=new thread_info;
thd_info->thread_id=tmp->thread_id;
- thd_info->user=thd->strdup(tmp->user ? tmp->user : (tmp->system_thread ?
- "system user" : "unauthenticated user"));
- thd_info->host=thd->strdup(tmp->host ? tmp->host : (tmp->ip ? tmp->ip :
- (tmp->system_thread ? "none" : "connecting host")));
+ thd_info->user=thd->strdup(tmp->user ? tmp->user :
+ (tmp->system_thread ?
+ "system user" : "unauthenticated user"));
+ thd_info->host=thd->strdup(tmp->host ? tmp->host :
+ (tmp->ip ? tmp->ip :
+ (tmp->system_thread ? "none" :
+ "connecting host")));
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
@@ -1064,9 +1088,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->query=0;
if (tmp->query)
{
- uint length=(uint) strlen(tmp->query);
- if (length > max_query_length)
- length=max_query_length;
+ /* query_length is always set before tmp->query */
+ uint length= min(max_query_length, tmp->query_length);
thd_info->query=(char*) thd->memdup(tmp->query,length+1);
thd_info->query[length]=0;
}
@@ -1083,28 +1106,28 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
char buff[20],*end;
packet->length(0);
end=int10_to_str((long) thd_info->thread_id, buff,10);
- net_store_data(packet,buff,(uint) (end-buff));
- net_store_data(packet,thd_info->user);
- net_store_data(packet,thd_info->host);
+ net_store_data(packet,convert,buff,(uint) (end-buff));
+ net_store_data(packet,convert,thd_info->user);
+ net_store_data(packet,convert,thd_info->host);
if (thd_info->db)
- net_store_data(packet,thd_info->db);
+ net_store_data(packet,convert,thd_info->db);
else
net_store_null(packet);
if (thd_info->proc_info)
- net_store_data(packet,thd_info->proc_info);
+ net_store_data(packet,convert,thd_info->proc_info);
else
- net_store_data(packet,command_name[thd_info->command]);
+ net_store_data(packet,convert,command_name[thd_info->command]);
if (thd_info->start_time)
- net_store_data(packet,(uint32)
- (time((time_t*) 0) - thd_info->start_time));
+ net_store_data(packet,
+ (uint32) (time((time_t*) 0) - thd_info->start_time));
else
net_store_null(packet);
if (thd_info->state_info)
- net_store_data(packet,thd_info->state_info);
+ net_store_data(packet,convert,thd_info->state_info);
else
net_store_null(packet);
if (thd_info->query)
- net_store_data(packet,thd_info->query);
+ net_store_data(packet,convert,thd_info->query);
else
net_store_null(packet);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
@@ -1120,12 +1143,15 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
*****************************************************************************/
-int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
+int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
+ enum enum_var_type value_type)
{
- uint i;
char buff[8192];
String packet2(buff,sizeof(buff));
List<Item> field_list;
+ CONVERT *convert=thd->variables.convert_set;
+ ulong offset;
+
DBUG_ENTER("mysqld_show");
field_list.push_back(new Item_empty_string("Variable_name",30));
field_list.push_back(new Item_empty_string("Value",256));
@@ -1134,39 +1160,48 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
/* pthread_mutex_lock(&THR_LOCK_keycache); */
pthread_mutex_lock(&LOCK_status);
- for (i=0; variables[i].name; i++)
+ for (; variables->name; variables++)
{
- if (!(wild && wild[0] && wild_case_compare(variables[i].name,wild)))
+ if (!(wild && wild[0] && wild_case_compare(variables->name,wild)))
{
packet2.length(0);
- net_store_data(&packet2,variables[i].name);
- switch (variables[i].type){
+ net_store_data(&packet2,convert,variables->name);
+ SHOW_TYPE show_type=variables->type;
+ char *value=variables->value;
+ if (show_type == SHOW_SYS)
+ {
+ show_type= ((sys_var*) value)->type();
+ value= ((sys_var*) value)->value_ptr(thd, value_type);
+ }
+
+ switch (show_type) {
case SHOW_LONG:
case SHOW_LONG_CONST:
- net_store_data(&packet2,(uint32) *(ulong*) variables[i].value);
+ net_store_data(&packet2,(uint32) *(ulong*) value);
+ break;
+ case SHOW_LONGLONG:
+ net_store_data(&packet2,(longlong) *(longlong*) value);
break;
case SHOW_BOOL:
- net_store_data(&packet2,(ulong) *(bool*) variables[i].value ?
- "ON" : "OFF");
+ net_store_data(&packet2,(ulong) *(bool*) value ? "ON" : "OFF");
break;
case SHOW_MY_BOOL:
- net_store_data(&packet2,(ulong) *(my_bool*) variables[i].value ?
- "ON" : "OFF");
+ net_store_data(&packet2,(ulong) *(my_bool*) value ? "ON" : "OFF");
break;
case SHOW_INT_CONST:
case SHOW_INT:
- net_store_data(&packet2,(uint32) *(int*) variables[i].value);
+ net_store_data(&packet2,(uint32) *(int*) value);
break;
case SHOW_HAVE:
{
- SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) variables[i].value;
+ SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
net_store_data(&packet2, (tmp == SHOW_OPTION_NO ? "NO" :
tmp == SHOW_OPTION_YES ? "YES" :
"DISABLED"));
break;
}
case SHOW_CHAR:
- net_store_data(&packet2,variables[i].value);
+ net_store_data(&packet2,convert, value);
break;
case SHOW_STARTTIME:
net_store_data(&packet2,(uint32) (thd->query_start() - start_time));
@@ -1174,15 +1209,187 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
case SHOW_QUESTION:
net_store_data(&packet2,(uint32) thd->query_id);
break;
+ case SHOW_RPL_STATUS:
+ net_store_data(&packet2, rpl_status_type[(int)rpl_status]);
+ break;
+ case SHOW_SLAVE_RUNNING:
+ {
+ LOCK_ACTIVE_MI;
+ net_store_data(&packet2, (active_mi->slave_running &&
+ active_mi->rli.slave_running)
+ ? "ON" : "OFF");
+ UNLOCK_ACTIVE_MI;
+ break;
+ }
case SHOW_OPENTABLES:
net_store_data(&packet2,(uint32) cached_tables());
break;
case SHOW_CHAR_PTR:
- {
- char *value= *(char**) variables[i].value;
- net_store_data(&packet2,value ? value : "");
- break;
+ {
+ value= *(char**) value;
+ net_store_data(&packet2,convert, value ? value : "");
+ break;
+ }
+#ifdef HAVE_OPENSSL
+ /* First group - functions relying on CTX */
+ case SHOW_SSL_CTX_SESS_ACCEPT:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_ACCEPT_GOOD:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_CONNECT_GOOD:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_CB_HITS:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_HITS:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_CACHE_FULL:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_MISSES:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_TIMEOUTS:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_NUMBER:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_CONNECT:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_GET_VERIFY_MODE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_GET_VERIFY_DEPTH:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context_)));
+ break;
+ case SHOW_SSL_CTX_GET_SESSION_CACHE_MODE:
+ if (!ssl_acceptor_fd)
+ {
+ net_store_data(&packet2,"NONE" );
+ break;
+ }
+ switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context_))
+ {
+ case SSL_SESS_CACHE_OFF:
+ net_store_data(&packet2,"OFF" );
+ break;
+ case SSL_SESS_CACHE_CLIENT:
+ net_store_data(&packet2,"CLIENT" );
+ break;
+ case SSL_SESS_CACHE_SERVER:
+ net_store_data(&packet2,"SERVER" );
+ break;
+ case SSL_SESS_CACHE_BOTH:
+ net_store_data(&packet2,"BOTH" );
+ break;
+ case SSL_SESS_CACHE_NO_AUTO_CLEAR:
+ net_store_data(&packet2,"NO_AUTO_CLEAR" );
+ break;
+ case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
+ net_store_data(&packet2,"NO_INTERNAL_LOOKUP" );
+ break;
+ default:
+ net_store_data(&packet2,"Unknown");
+ break;
+ }
+ break;
+ /* First group - functions relying on SSL */
+ case SHOW_SSL_GET_VERSION:
+ net_store_data(&packet2, thd->net.vio->ssl_ ?
+ SSL_get_version(thd->net.vio->ssl_) : "");
+ break;
+ case SHOW_SSL_SESSION_REUSED:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_ ?
+ SSL_session_reused(thd->net.vio->ssl_) : 0));
+ break;
+ case SHOW_SSL_GET_DEFAULT_TIMEOUT:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_ ?
+ SSL_get_default_timeout(thd->net.vio->ssl_):0));
+ break;
+ case SHOW_SSL_GET_VERIFY_MODE:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_ ?
+ SSL_get_verify_mode(thd->net.vio->ssl_):0));
+ break;
+ case SHOW_SSL_GET_VERIFY_DEPTH:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_ ?
+ SSL_get_verify_depth(thd->net.vio->ssl_):0));
+ break;
+ case SHOW_SSL_GET_CIPHER:
+ net_store_data(&packet2, thd->net.vio->ssl_ ?
+ SSL_get_cipher(thd->net.vio->ssl_) : "");
+ break;
+ case SHOW_SSL_GET_CIPHER_LIST:
+ if (thd->net.vio->ssl_)
+ {
+ char buf[1024], *pos;
+ pos=buf;
+ for (int i=0 ; i++ ;)
+ {
+ const char *p=SSL_get_cipher_list(thd->net.vio->ssl_,i);
+ if (p == NULL)
+ break;
+ pos=strmov(pos, p);
+ *pos++= ':';
+ }
+ if (pos != buf)
+ pos--; // Remove last ':'
+ *pos=0;
+ net_store_data(&packet2, buf);
}
+ else
+ net_store_data(&packet2, "");
+ break;
+
+#endif /* HAVE_OPENSSL */
+ case SHOW_UNDEF: // Show never happen
+ case SHOW_SYS:
+ net_store_data(&packet2, ""); // Safety
+ break;
}
if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length()))
goto err; /* purecov: inspected */
@@ -1200,6 +1407,6 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
}
#ifdef __GNUC__
-template class List_iterator<char>;
+template class List_iterator_fast<char>;
template class List<char>;
#endif
diff --git a/sql/sql_sort.h b/sql/sql_sort.h
new file mode 100644
index 00000000000..62c5f1cb164
--- /dev/null
+++ b/sql/sql_sort.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Defines used by filesort and uniques */
+
+#define MERGEBUFF 7
+#define MERGEBUFF2 15
+
+typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
+ my_off_t file_pos; /* Where we are in the sort file */
+ uchar *base,*key; /* key pointers */
+ ha_rows count; /* Number of rows in table */
+ ulong mem_count; /* numbers of keys in memory */
+ ulong max_keys; /* Max keys in buffert */
+} BUFFPEK;
+
+
+typedef struct st_sort_param {
+ uint sort_length; /* Length of sort columns */
+ uint keys; /* Max keys / buffert */
+ uint ref_length; /* Length of record ref. */
+ ha_rows max_rows,examined_rows;
+ TABLE *sort_form; /* For quicker make_sortkey */
+ SORT_FIELD *local_sortorder;
+ SORT_FIELD *end;
+ uchar *unique_buff;
+ bool not_killable;
+#ifdef USE_STRCOLL
+ char* tmp_buffer;
+#endif
+} SORTPARAM;
+
+
+int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
+ BUFFPEK *buffpek,
+ uint *maxbuffer, IO_CACHE *t_file);
+uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
+ uint sort_length);
+int merge_buffers(SORTPARAM *param,IO_CACHE *from_file,
+ IO_CACHE *to_file, uchar *sort_buffer,
+ BUFFPEK *lastbuff,BUFFPEK *Fb,
+ BUFFPEK *Tb,int flag);
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index e6cdd089bf1..2dcda2d40c2 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program file is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
@@ -21,7 +20,7 @@
#pragma implementation // gcc: Class implementation
#endif
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
@@ -41,19 +40,16 @@ extern void sql_element_free(void *ptr);
bool String::real_alloc(uint32 arg_length)
{
arg_length=ALIGN_SIZE(arg_length+1);
+ str_length=0;
if (Alloced_length < arg_length)
{
free();
if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME))))
- {
- str_length=0;
return TRUE;
- }
Alloced_length=arg_length;
alloced=1;
}
Ptr[0]=0;
- str_length=0;
return FALSE;
}
@@ -362,6 +358,37 @@ skipp:
return -1;
}
+/*
+ Search after a string without regarding to case
+ This needs to be replaced when we have character sets per string
+*/
+
+int String::strstr_case(const String &s,uint32 offset)
+{
+ if (s.length()+offset <= str_length)
+ {
+ if (!s.length())
+ return ((int) offset); // Empty string is always found
+
+ register const char *str = Ptr+offset;
+ register const char *search=s.ptr();
+ const char *end=Ptr+str_length-s.length()+1;
+ const char *search_end=s.ptr()+s.length();
+skipp:
+ while (str != end)
+ {
+ if (my_sort_order[*str++] == my_sort_order[*search])
+ {
+ register char *i,*j;
+ i=(char*) str; j=(char*) search+1;
+ while (j != search_end)
+ if (my_sort_order[*i++] != my_sort_order[*j++]) goto skipp;
+ return (int) (str-Ptr) -1;
+ }
+ }
+ }
+ return -1;
+}
/*
** Search string from end. Offset is offset to the end of string
@@ -577,7 +604,7 @@ int wild_case_compare(const char *str,const char *str_end,
{
do
{
- if (str == str_end) // Skipp one char if possible
+ if (str == str_end) // Skip one char if possible
return (result);
INC_PTR(str,str_end);
} while (++wildstr < wildend && *wildstr == wild_one);
@@ -588,7 +615,7 @@ int wild_case_compare(const char *str,const char *str_end,
{ // Found wild_many
wildstr++;
/* Remove any '%' and '_' from the wild search string */
- for ( ; wildstr != wildend ; wildstr++)
+ for (; wildstr != wildend ; wildstr++)
{
if (*wildstr == wild_many)
continue;
@@ -668,8 +695,11 @@ int wild_case_compare(const char *str,const char *str_end,
int wild_case_compare(String &match,String &wild, char escape)
{
- return wild_case_compare(match.ptr(),match.ptr()+match.length(),
- wild.ptr(), wild.ptr()+wild.length(),escape);
+ DBUG_ENTER("wild_case_compare");
+ DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
+ ,match.ptr(),wild.ptr(),escape));
+ DBUG_RETURN(wild_case_compare(match.ptr(),match.ptr()+match.length(),
+ wild.ptr(), wild.ptr()+wild.length(),escape));
}
/*
@@ -679,6 +709,9 @@ int wild_case_compare(String &match,String &wild, char escape)
int wild_compare(const char *str,const char *str_end,
const char *wildstr,const char *wildend,char escape)
{
+ DBUG_ENTER("wild_compare");
+ DBUG_PRINT("enter",("str='%s', str_end='%s', wildstr='%s', wildend='%s', escape='%c'"
+ ,str,str_end,wildstr,wildend,escape));
int result= -1; // Not found, using wildcards
while (wildstr != wildend)
{
@@ -687,17 +720,21 @@ int wild_compare(const char *str,const char *str_end,
if (*wildstr == escape && wildstr+1 != wildend)
wildstr++;
if (str == str_end || *wildstr++ != *str++)
- return(1);
+ {
+ DBUG_RETURN(1);
+ }
if (wildstr == wildend)
- return (str != str_end); // Match if both are at end
+ {
+ DBUG_RETURN(str != str_end); // Match if both are at end
+ }
result=1; // Found an anchor char
}
if (*wildstr == wild_one)
{
do
{
- if (str == str_end) // Skipp one char if possible
- return (result);
+ if (str == str_end) // Skip one char if possible
+ DBUG_RETURN(result);
str++;
} while (*++wildstr == wild_one && wildstr != wildend);
if (wildstr == wildend)
@@ -707,24 +744,29 @@ int wild_compare(const char *str,const char *str_end,
{ // Found wild_many
wildstr++;
/* Remove any '%' and '_' from the wild search string */
- for ( ; wildstr != wildend ; wildstr++)
+ for (; wildstr != wildend ; wildstr++)
{
if (*wildstr == wild_many)
continue;
if (*wildstr == wild_one)
{
if (str == str_end)
- return (-1);
+ {
+ DBUG_RETURN(-1);
+ }
str++;
continue;
}
break; // Not a wild character
}
if (wildstr == wildend)
- return(0); // Ok if wild_many is last
+ {
+ DBUG_RETURN(0); // Ok if wild_many is last
+ }
if (str == str_end)
- return -1;
-
+ {
+ DBUG_RETURN(-1);
+ }
char cmp;
if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
cmp= *++wildstr;
@@ -733,22 +775,30 @@ int wild_compare(const char *str,const char *str_end,
{
while (str != str_end && *str != cmp)
str++;
- if (str++ == str_end) return (-1);
+ if (str++ == str_end)
+ {
+ DBUG_RETURN(-1);
+ }
{
int tmp=wild_compare(str,str_end,wildstr,wildend,escape);
if (tmp <= 0)
- return (tmp);
+ {
+ DBUG_RETURN(tmp);
+ }
}
} while (str != str_end && wildstr[0] != wild_many);
- return(-1);
+ DBUG_RETURN(-1);
}
}
- return (str != str_end ? 1 : 0);
+ DBUG_RETURN(str != str_end ? 1 : 0);
}
int wild_compare(String &match,String &wild, char escape)
{
- return wild_compare(match.ptr(),match.ptr()+match.length(),
- wild.ptr(), wild.ptr()+wild.length(),escape);
+ DBUG_ENTER("wild_compare");
+ DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
+ ,match.ptr(),wild.ptr(),escape));
+ DBUG_RETURN(wild_compare(match.ptr(),match.ptr()+match.length(),
+ wild.ptr(), wild.ptr()+wild.length(),escape));
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 31dea9991cc..ad7455ecbf1 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
@@ -161,6 +160,7 @@ public:
bool append(const char *s,uint32 arg_length=0);
bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
+ int strstr_case(const String &s,uint32 offset=0);
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to);
inline bool append(char chr)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index ce3415f10fb..ef2bb807efd 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -26,6 +26,7 @@
#endif
extern HASH open_cache;
+static const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
@@ -43,12 +44,7 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
{
- char path[FN_REFLEN];
- String wrong_tables;
- bool some_tables_deleted=0;
- uint error;
- db_type table_type;
- TABLE_LIST *table;
+ int error;
DBUG_ENTER("mysql_rm_table");
/* mark for close and remove all cached entries */
@@ -72,7 +68,56 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
}
}
-
+ error=mysql_rm_table_part2(thd,tables,if_exists,0);
+
+ err:
+ pthread_mutex_unlock(&LOCK_open);
+ VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
+
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+
+ if (error)
+ DBUG_RETURN(-1);
+ send_ok(&thd->net);
+ DBUG_RETURN(0);
+}
+
+int mysql_rm_table_part2_with_lock(THD *thd,
+ TABLE_LIST *tables, bool if_exists,
+ bool dont_log_query)
+{
+ int error;
+ thd->mysys_var->current_mutex= &LOCK_open;
+ thd->mysys_var->current_cond= &COND_refresh;
+ VOID(pthread_mutex_lock(&LOCK_open));
+
+ error=mysql_rm_table_part2(thd,tables, if_exists, dont_log_query);
+
+ pthread_mutex_unlock(&LOCK_open);
+ VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
+
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+ return error;
+}
+
+
+int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
+ bool dont_log_query)
+{
+ TABLE_LIST *table;
+ char path[FN_REFLEN];
+ String wrong_tables;
+ db_type table_type;
+ int error;
+ bool some_tables_deleted=0;
+ DBUG_ENTER("mysql_rm_table_part2");
+
for (table=tables ; table ; table=table->next)
{
char *db=table->db ? table->db : thd->db;
@@ -91,15 +136,8 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
}
drop_locked_tables(thd,db,table->real_name);
if (thd->killed)
- {
- VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
- VOID(pthread_mutex_unlock(&LOCK_open));
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
DBUG_RETURN(-1);
- }
+
/* remove form file and isam files */
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table->real_name,
reg_ext);
@@ -137,33 +175,25 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
}
if (some_tables_deleted)
{
- mysql_update_log.write(thd, thd->query,thd->query_length);
- if (mysql_bin_log.is_open())
+ query_cache_invalidate3(thd, tables, 0);
+ if (!dont_log_query)
{
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
+ 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);
+ }
}
}
-
- error = 0;
- err:
- VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
- pthread_mutex_unlock(&LOCK_open);
-
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
+ error = 0;
if (wrong_tables.length())
{
my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());
error=1;
}
- if(error)
- DBUG_RETURN(-1);
- send_ok(&thd->net);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
@@ -181,6 +211,52 @@ int quick_rm_table(enum db_type base,const char *db,
return ha_delete_table(base,path) || error;
}
+/*
+ Sort keys in the following order:
+ - PRIMARY KEY
+ - UNIQUE keyws where all column are NOT NULL
+ - Other UNIQUE keys
+ - Normal keys
+ - Fulltext keys
+
+ This will make checking for duplicated keys faster and ensure that
+ PRIMARY keys are prioritized.
+*/
+
+
+static int sort_keys(KEY *a, KEY *b)
+{
+ if (a->flags & HA_NOSAME)
+ {
+ if (!(b->flags & HA_NOSAME))
+ return -1;
+ if ((a->flags ^ b->flags) & HA_NULL_PART_KEY)
+ {
+ /* Sort NOT NULL keys before other keys */
+ return (a->flags & HA_NULL_PART_KEY) ? 1 : -1;
+ }
+ if (a->name == primary_key_name)
+ return -1;
+ if (b->name == primary_key_name)
+ return 1;
+ }
+ else if (b->flags & HA_NOSAME)
+ return 1; // Prefer b
+
+ if ((a->flags ^ b->flags) & HA_FULLTEXT)
+ {
+ return (a->flags & HA_FULLTEXT) ? 1 : -1;
+ }
+ /*
+ 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);
+}
+
+
/*****************************************************************************
* Create a table.
* If one creates a temporary table, this is automaticly opened
@@ -220,7 +296,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
file=get_new_handler((TABLE*) 0, create_info->db_type);
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
- (file->option_flag() & HA_NO_TEMP_TABLES))
+ (file->table_flags() & HA_NO_TEMP_TABLES))
{
my_error(ER_ILLEGAL_HA,MYF(0),table_name);
DBUG_RETURN(-1);
@@ -319,13 +395,13 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
if (auto_increment &&
- (file->option_flag() & HA_WRONG_ASCII_ORDER))
+ (file->table_flags() & HA_NO_AUTO_INCREMENT))
{
my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,MYF(0));
DBUG_RETURN(-1);
}
- if (blob_columns && (file->option_flag() & HA_NO_BLOBS))
+ if (blob_columns && (file->table_flags() & HA_NO_BLOBS))
{
my_error(ER_TABLE_CANT_HANDLE_BLOB,MYF(0));
DBUG_RETURN(-1);
@@ -336,10 +412,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
List_iterator<Key> key_iterator(keys);
uint key_parts=0,key_count=keys.elements;
List<Key> keys_in_order; // Add new keys here
- Key *primary_key=0;
- bool unique_key=0;
+ bool primary_key=0,unique_key=0;
Key *key;
- uint tmp;
+ uint tmp, key_number;
tmp=min(file->max_keys(), MAX_KEY);
if (key_count > tmp)
{
@@ -347,12 +422,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
- /*
- Check keys;
- Put PRIMARY KEY first, then UNIQUE keys and other keys last
- This will make checking for duplicated keys faster and ensure that
- primary keys are prioritized.
- */
+ /* Calculate number of key segements */
while ((key=key_iterator++))
{
@@ -368,33 +438,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
key_parts+=key->columns.elements;
- if (key->type == Key::PRIMARY)
- {
- if (primary_key)
- {
- my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
- DBUG_RETURN(-1);
- }
- primary_key=key;
- }
- else if (key->type == Key::UNIQUE)
- {
- unique_key=1;
- if (keys_in_order.push_front(key))
- DBUG_RETURN(-1);
- }
- else if (keys_in_order.push_back(key))
- DBUG_RETURN(-1);
- }
- if (primary_key)
- {
- if (keys_in_order.push_front(primary_key))
- DBUG_RETURN(-1);
- }
- else if (!unique_key && (file->option_flag() & HA_REQUIRE_PRIMARY_KEY))
- {
- my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
- DBUG_RETURN(-1);
}
key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count);
@@ -402,8 +445,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (!key_info_buffer || ! key_part_info)
DBUG_RETURN(-1); // Out of memory
- List_iterator<Key> key_iterator_in_order(keys_in_order);
- for (; (key=key_iterator_in_order++) ; key_info++)
+ key_iterator.rewind();
+ key_number=0;
+ for (; (key=key_iterator++) ; key_info++, key_number++)
{
uint key_length=0;
key_part_spec *column;
@@ -412,10 +456,13 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
(key->type == Key::FULLTEXT) ? HA_FULLTEXT : HA_NOSAME;
key_info->key_parts=(uint8) key->columns.elements;
key_info->key_part=key_part_info;
+ key_info->usable_key_parts= key_number;
+ key_info->algorithm=key->algorithm;
+ /* TODO: Add proper checks if handler supports key_type and algorithm */
if (key->type == Key::FULLTEXT)
{
- if (file->option_flag() & HA_NO_FULLTEXT_KEY)
+ if (!(file->table_flags() & HA_CAN_FULLTEXT))
{
my_error(ER_TABLE_CANT_HANDLE_FULLTEXT, MYF(0));
DBUG_RETURN(-1);
@@ -439,7 +486,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
if (f_is_blob(sql_field->pack_flag))
{
- if (!(file->option_flag() & HA_BLOB_KEY))
+ if (!(file->table_flags() & HA_BLOB_KEY))
{
my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
column->field_name);
@@ -465,16 +512,17 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
my_error(ER_PRIMARY_CANT_HAVE_NULL, MYF(0));
DBUG_RETURN(-1);
}
- if (!(file->option_flag() & HA_NULL_KEY))
+ if (!(file->table_flags() & HA_NULL_KEY))
{
my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
MYF(0),column->field_name);
DBUG_RETURN(-1);
}
+ key_info->flags|= HA_NULL_PART_KEY;
}
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
{
- if (column_nr == 0 || (file->option_flag() & HA_AUTO_PART_KEY))
+ if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY))
auto_increment--; // Field is used
}
key_part_info->fieldnr= field;
@@ -494,14 +542,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
else if (column->length > length ||
((f_is_packed(sql_field->pack_flag) ||
- ((file->option_flag() & HA_NO_PREFIX_CHAR_KEYS) &&
+ ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
(key_info->flags & HA_NOSAME))) &&
column->length != length))
{
my_error(ER_WRONG_SUB_KEY,MYF(0));
DBUG_RETURN(-1);
}
- if (!(file->option_flag() & HA_NO_PREFIX_CHAR_KEYS))
+ if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS))
length=column->length;
}
else if (length == 0)
@@ -530,7 +578,15 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (column_nr == 0)
{
if (key->type == Key::PRIMARY)
- key_name="PRIMARY";
+ {
+ if (primary_key)
+ {
+ my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ key_name=primary_key_name;
+ primary_key=1;
+ }
else if (!(key_name = key->name()))
key_name=make_unique_key_name(sql_field->field_name,
key_info_buffer,key_info);
@@ -542,18 +598,29 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
key_info->name=(char*) key_name;
}
}
+ if (!(key_info->flags & HA_NULL_PART_KEY))
+ unique_key=1;
key_info->key_length=(uint16) key_length;
- if (key_length > file->max_key_length() && key->type != Key::FULLTEXT)
+ uint max_key_length= max(file->max_key_length(), MAX_KEY_LENGTH);
+ if (key_length > max_key_length && key->type != Key::FULLTEXT)
{
- my_error(ER_TOO_LONG_KEY,MYF(0),file->max_key_length());
+ my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
DBUG_RETURN(-1);
}
}
+ if (!unique_key && !primary_key &&
+ (file->table_flags() & HA_REQUIRE_PRIMARY_KEY))
+ {
+ my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
if (auto_increment > 0)
{
my_error(ER_WRONG_AUTO_KEY,MYF(0));
DBUG_RETURN(-1);
}
+ /* Sort keys in optimized order */
+ qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys);
/* Check if table exists */
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
@@ -670,7 +737,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
DBUG_ENTER("create_table_from_items");
/* Add selected items to field list */
- List_iterator<Item> it(*items);
+ List_iterator_fast<Item> it(*items);
Item *item;
Field *tmp_field;
tmp_table.db_create_options=0;
@@ -688,8 +755,11 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_WRONG_COLUMN_NAME,MYF(0),item->name);
DBUG_RETURN(0);
}
-
- Field *field=create_tmp_field(&tmp_table,item,item->type(),
+ Field *field;
+ if (item->type() == Item::FUNC_ITEM)
+ field=item->tmp_table_field(&tmp_table);
+ else
+ field=create_tmp_field(thd, &tmp_table, item, item->type(),
(Item_result_field***) 0, &tmp_field,0,0);
if (!field ||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
@@ -816,7 +886,9 @@ static int send_check_errmsg(THD* thd, TABLE_LIST* table,
return 1;
}
-static int prepare_for_restore(THD* thd, TABLE_LIST* table)
+
+static int prepare_for_restore(THD* thd, TABLE_LIST* table,
+ HA_CHECK_OPT *check_opt)
{
DBUG_ENTER("prepare_for_restore");
@@ -833,61 +905,102 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
char* table_name = table->name;
char* db = thd->db ? thd->db : table->db;
- if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
+ if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
+ reg_ext))
DBUG_RETURN(-1); // protect buffer overflow
sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
- int lock_retcode;
- pthread_mutex_lock(&LOCK_open);
- if ((lock_retcode = lock_table_name(thd, table)) < 0)
- {
- pthread_mutex_unlock(&LOCK_open);
- DBUG_RETURN(-1);
- }
-
- if (lock_retcode && wait_for_locked_table_names(thd, table))
- {
- unlock_table_name(thd, table);
- pthread_mutex_unlock(&LOCK_open);
+ if (lock_and_wait_for_table_name(thd,table))
DBUG_RETURN(-1);
- }
- pthread_mutex_unlock(&LOCK_open);
if (my_copy(src_path,
- fn_format(dst_path, dst_path,"",
- reg_ext, 4),
- MYF(MY_WME)))
+ fn_format(dst_path, dst_path,"", reg_ext, 4),
+ MYF(MY_WME)))
{
unlock_table_name(thd, table);
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
"Failed copying .frm file"));
}
- bool save_no_send_ok = thd->net.no_send_ok;
- thd->net.no_send_ok = 1;
- // generate table will try to send OK which messes up the output
- // for the client
-
- if (generate_table(thd, table, 0))
+ if (mysql_truncate(thd, table, 1))
{
unlock_table_name(thd, table);
- thd->net.no_send_ok = save_no_send_ok;
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
"Failed generating table from .frm file"));
}
+ }
+
+ /*
+ Now we should be able to open the partially restored table
+ to finish the restore in the handler later on
+ */
+ if (!(table->table = reopen_name_locked_table(thd, table)))
+ unlock_table_name(thd, table);
+ DBUG_RETURN(0);
+}
- thd->net.no_send_ok = save_no_send_ok;
+
+static int prepare_for_repair(THD* thd, TABLE_LIST* table,
+ HA_CHECK_OPT *check_opt)
+{
+ DBUG_ENTER("prepare_for_repair");
+
+ if (!(check_opt->sql_flags & TT_USEFRM))
+ {
+ DBUG_RETURN(0);
+ }
+ else
+ {
+
+ char from[FN_REFLEN],tmp[FN_REFLEN];
+ char* db = thd->db ? thd->db : table->db;
+
+ sprintf(from, "%s/%s/%s", mysql_real_data_home, db, table->name);
+ fn_format(from, from, "", MI_NAME_DEXT, 4);
+ sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
+
+ close_cached_table(thd,table->table);
+
+ if (lock_and_wait_for_table_name(thd,table))
+ DBUG_RETURN(-1);
+
+ if (my_rename(from, tmp, MYF(MY_WME)))
+ {
+ unlock_table_name(thd, table);
+ DBUG_RETURN(send_check_errmsg(thd, table, "repair",
+ "Failed renaming .MYD file"));
+ }
+ if (mysql_truncate(thd, table, 1))
+ {
+ unlock_table_name(thd, table);
+ DBUG_RETURN(send_check_errmsg(thd, table, "repair",
+ "Failed generating table from .frm file"));
+ }
+ if (my_rename(tmp, from, MYF(MY_WME)))
+ {
+ unlock_table_name(thd, table);
+ DBUG_RETURN(send_check_errmsg(thd, table, "repair",
+ "Failed restoring .MYD file"));
+ }
}
+ /*
+ Now we should be able to open the partially repaired table
+ to finish the repair in the handler later on.
+ */
+ if (!(table->table = reopen_name_locked_table(thd, table)))
+ unlock_table_name(thd, table);
DBUG_RETURN(0);
}
+
static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
HA_CHECK_OPT* check_opt,
const char *operator_name,
thr_lock_type lock_type,
- bool open_for_modify, bool restore,
+ bool open_for_modify,
uint extra_open_options,
+ int (*prepare_func)(THD *, TABLE_LIST *, HA_CHECK_OPT *),
int (handler::*operator_func)
(THD *, HA_CHECK_OPT *))
{
@@ -919,18 +1032,13 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
table->table = open_ltable(thd, table, lock_type);
thd->open_options&= ~extra_open_options;
packet->length(0);
- if (restore)
+ if (prepare_func)
{
- switch (prepare_for_restore(thd, table)) {
- case 1: continue; // error, message written to net
- case -1: goto err; // error, message could be written to net
- default: ;// should be 0 otherwise
+ switch ((*prepare_func)(thd, table, check_opt)) {
+ case 1: continue; // error, message written to net
+ case -1: goto err; // error, message could be written to net
+ default: ; // should be 0 otherwise
}
-
- // now we should be able to open the partially restored table
- // to finish the restore in the handler later on
- if (!(table->table = reopen_name_locked_table(thd, table)))
- unlock_table_name(thd, table);
}
if (!table->table)
@@ -957,6 +1065,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
sprintf(buff, ER(ER_OPEN_AS_READONLY), table_name);
net_store_data(packet, buff);
close_thread_tables(thd);
+ table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
packet->length()))
goto err;
@@ -1031,9 +1140,14 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (fatal_error)
table->table->version=0; // Force close of table
else if (open_for_modify)
+ {
remove_table_from_cache(thd, table->table->table_cache_key,
table->table->real_name);
+ /* May be something modified consequently we have to invalidate cache */
+ query_cache_invalidate3(thd, table->table, 0);
+ }
close_thread_tables(thd);
+ table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) packet->ptr(),
packet->length()))
goto err;
@@ -1043,9 +1157,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_RETURN(0);
err:
close_thread_tables(thd); // Shouldn't be needed
+ if (table)
+ table->table=0;
DBUG_RETURN(-1);
}
+
int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("mysql_backup_table");
@@ -1058,7 +1175,8 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("mysql_restore_table");
DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
- "restore", TL_WRITE, 1, 1,0,
+ "restore", TL_WRITE, 1, 0,
+ &prepare_for_restore,
&handler::restore));
}
@@ -1066,7 +1184,8 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("mysql_repair_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "repair", TL_WRITE, 1, 0, HA_OPEN_FOR_REPAIR,
+ "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR,
+ &prepare_for_repair,
&handler::repair));
}
@@ -1105,7 +1224,7 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
DBUG_ENTER("mysql_check_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
"check", lock_type,
- 0, 0, HA_OPEN_FOR_REPAIR,
+ 0, HA_OPEN_FOR_REPAIR, 0,
&handler::check));
}
@@ -1118,24 +1237,28 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
List<Alter_column> &alter_list,
ORDER *order,
bool drop_primary,
- enum enum_duplicates handle_duplicates)
+ enum enum_duplicates handle_duplicates,
+ enum enum_enable_or_disable keys_onoff,
+ bool simple_alter)
{
TABLE *table,*new_table;
int error;
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN],
- *table_name,*db;
+ *table_name,*db;
+ char index_file[FN_REFLEN], data_file[FN_REFLEN];
bool use_timestamp=0;
ha_rows copied,deleted;
ulonglong next_insert_id;
- uint save_time_stamp,db_create_options;
+ uint save_time_stamp,db_create_options, used_fields;
enum db_type old_db_type,new_db_type;
DBUG_ENTER("mysql_alter_table");
thd->proc_info="init";
table_name=table_list->real_name;
db=table_list->db;
- if (!new_db)
+ if (!new_db || !strcmp(new_db,db))
new_db=db;
+ used_fields=create_info->used_fields;
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
@@ -1181,42 +1304,49 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (create_info->db_type == DB_TYPE_DEFAULT)
create_info->db_type=old_db_type;
new_db_type=create_info->db_type= ha_checktype(create_info->db_type);
- if (create_info->row_type == ROW_TYPE_DEFAULT)
+ if (create_info->row_type == ROW_TYPE_NOT_USED)
create_info->row_type=table->row_type;
- /* Check if the user only wants to do a simple RENAME */
+ /* In some simple cases we need not to recreate the table */
thd->proc_info="setup";
- if (new_name != table_name &&
- !fields.elements && !keys.elements && ! drop_list.elements &&
- !alter_list.elements && !drop_primary &&
- new_db_type == old_db_type && create_info->max_rows == 0 &&
- create_info->auto_increment_value == 0 && !table->tmp_table)
+ if (simple_alter && !table->tmp_table)
{
- thd->proc_info="rename";
- VOID(pthread_mutex_lock(&LOCK_open));
- /* Then do a 'simple' rename of the table */
error=0;
- if (!access(new_name_buff,F_OK))
- {
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
- error= -1;
- }
- else
+ if (new_name != table_name || new_db != db)
{
- *fn_ext(new_name)=0;
- close_cached_table(thd,table);
- if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
- error= -1;
+ thd->proc_info="rename";
+ VOID(pthread_mutex_lock(&LOCK_open));
+ /* Then do a 'simple' rename of the table */
+ error=0;
+ if (!access(new_name_buff,F_OK))
+ {
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
+ error= -1;
+ }
+ else
+ {
+ *fn_ext(new_name)=0;
+ close_cached_table(thd,table);
+ if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
+ error= -1;
+ }
+ VOID(pthread_cond_broadcast(&COND_refresh));
+ VOID(pthread_mutex_unlock(&LOCK_open));
}
- if (!error && (error=ha_commit_rename(thd)))
+ if (!error)
{
- my_error(ER_GET_ERRNO,MYF(0),error);
- error=1;
+ switch (keys_onoff) {
+ case LEAVE_AS_IS:
+ break;
+ case ENABLE:
+ error=table->file->activate_all_index(thd);
+ break;
+ case DISABLE:
+ table->file->deactivate_non_unique_index(HA_POS_ERROR);
+ break;
+ }
}
-
- VOID(pthread_cond_broadcast(&COND_refresh));
- VOID(pthread_mutex_unlock(&LOCK_open));
if (!error)
{
mysql_update_log.write(thd, thd->query, thd->query_length);
@@ -1227,7 +1357,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
send_ok(&thd->net);
}
-
DBUG_RETURN(error);
}
@@ -1257,7 +1386,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
/* Reset auto_increment value if it was dropped */
if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
- !(create_info->used_fields & HA_CREATE_USED_AUTO))
+ !(used_fields & HA_CREATE_USED_AUTO))
{
create_info->auto_increment_value=0;
create_info->used_fields|=HA_CREATE_USED_AUTO;
@@ -1282,8 +1411,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
def->field=field;
if (def->sql_type == FIELD_TYPE_TIMESTAMP)
use_timestamp=1;
- create_list.push_back(def);
- def_it.remove();
+ if (!def->after)
+ {
+ create_list.push_back(def);
+ def_it.remove();
+ }
}
else
{ // Use old field value
@@ -1314,7 +1446,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
List_iterator<create_field> find_it(create_list);
while ((def=def_it++)) // Add new columns
{
- if (def->change)
+ if (def->change && ! def->field)
{
my_error(ER_BAD_FIELD_ERROR,MYF(0),def->change,table_name);
DBUG_RETURN(-1);
@@ -1443,20 +1575,25 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
+ db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
(void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid,
thd->thread_id);
create_info->db_type=new_db_type;
- if (!create_info->max_rows)
- create_info->max_rows=table->max_rows;
- if (!create_info->avg_row_length)
- create_info->avg_row_length=table->avg_row_length;
- table->file->update_create_info(create_info);
if (!create_info->comment)
create_info->comment=table->comment;
+
/* let new create options override the old ones */
- db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
- if (create_info->table_options &
- (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS))
+ if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
+ create_info->min_rows=table->min_rows;
+ if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
+ create_info->max_rows=table->max_rows;
+ if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
+ create_info->avg_row_length=table->avg_row_length;
+
+ table->file->update_create_info(create_info);
+ if ((create_info->table_options &
+ (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
+ (used_fields & HA_CREATE_USED_PACK_KEYS))
db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
if (create_info->table_options &
(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
@@ -1470,6 +1607,53 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (table->tmp_table)
create_info->options|=HA_LEX_CREATE_TMP_TABLE;
+ /*
+ Handling of symlinked tables:
+ If no rename:
+ Create new data file and index file on the same disk as the
+ old data and index files.
+ Copy data.
+ Rename new data file over old data file and new index file over
+ old index file.
+ Symlinks are not changed.
+
+ If rename:
+ Create new data file and index file on the same disk as the
+ old data and index files. Create also symlinks to point at
+ the new tables.
+ Copy data.
+ At end, rename temporary tables and symlinks to temporary table
+ to final table name.
+ Remove old table and old symlinks
+
+ If rename is made to another database:
+ Create new tables in new database.
+ Copy data.
+ Remove old table and symlinks.
+ */
+
+ if (!strcmp(db, new_db)) // Ignore symlink if db changed
+ {
+ if (create_info->index_file_name)
+ {
+ /* Fix index_file_name to have 'tmp_name' as basename */
+ strmov(index_file, tmp_name);
+ create_info->index_file_name=fn_same(index_file,
+ create_info->index_file_name,
+ 1);
+ }
+ if (create_info->data_file_name)
+ {
+ /* Fix data_file_name to have 'tmp_name' as basename */
+ strmov(data_file, tmp_name);
+ create_info->data_file_name=fn_same(data_file,
+ create_info->data_file_name,
+ 1);
+ }
+ }
+ else
+ create_info->data_file_name=create_info->index_file_name=0;
+
if ((error=mysql_create_table(thd, new_db, tmp_name,
create_info,
create_list,key_list,1,1))) // no logging
@@ -1557,7 +1741,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->proc_info="rename result table";
sprintf(old_name,"%s2-%lx-%lx", tmp_file_prefix, current_pid,
thd->thread_id);
- if (new_name != table_name)
+ if (new_name != table_name || new_db != db)
{
if (!access(new_name_buff,F_OK))
{
@@ -1575,7 +1759,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
/*
Win32 and InnoDB can't drop a table that is in use, so we must
- close all the original table at before doing the rename
+ close the original table at before doing the rename
*/
table_name=thd->strdup(table_name); // must be saved
if (close_cached_table(thd,table))
@@ -1608,24 +1792,30 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
if (error)
{
- // This shouldn't happen. We solve this the safe way by
- // closing the locked table.
+ /*
+ This shouldn't happen. We solve this the safe way by
+ closing the locked table.
+ */
close_cached_table(thd,table);
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
if (thd->lock || new_name != table_name) // True if WIN32
{
- // Not table locking or alter table with rename
- // free locks and remove old table
+ /*
+ Not table locking or alter table with rename
+ free locks and remove old table
+ */
close_cached_table(thd,table);
VOID(quick_rm_table(old_db_type,db,old_name));
}
else
{
- // Using LOCK TABLES without rename.
- // This code is never executed on WIN32!
- // Remove old renamed table, reopen table and get new locks
+ /*
+ Using LOCK TABLES without rename.
+ This code is never executed on WIN32!
+ Remove old renamed table, reopen table and get new locks
+ */
if (table)
{
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
@@ -1666,6 +1856,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
VOID(pthread_cond_broadcast(&COND_refresh));
VOID(pthread_mutex_unlock(&LOCK_open));
+ table_list->table=0; // For query cache
+ query_cache_invalidate3(thd, table_list, 0);
end_temporary:
sprintf(tmp_name,ER(ER_INSERT_INFO),(ulong) (copied+deleted),
@@ -1675,7 +1867,6 @@ end_temporary:
DBUG_RETURN(0);
err:
- (void) ha_commit_rename(thd); // Just for safety
DBUG_RETURN(-1);
}
@@ -1734,8 +1925,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (setup_order(thd, &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) ||
- (from->found_records = filesort(&from, sortorder, length,
- (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
+ (from->found_records = filesort(from, sortorder, length,
+ (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
&examined_rows))
== HA_POS_ERROR)
goto err;
@@ -1785,7 +1976,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
end_read_record(&info);
free_io_cache(from);
- delete [] copy;
+ delete [] copy; // This is never 0
uint tmp_error;
if ((tmp_error=to->file->extra(HA_EXTRA_NO_CACHE)))
{
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index c4c2855a63e..9c458c27b95 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,6 +21,7 @@
#include "mysql_priv.h"
#include "sql_select.h"
#include <hash.h>
+#include <thr_alarm.h>
/* Intern key cache variables */
extern "C" pthread_mutex_t THR_LOCK_keycache;
@@ -96,8 +97,7 @@ void print_cached_tables(void)
}
-void TEST_filesort(TABLE **table,SORT_FIELD *sortorder,uint s_length,
- ha_rows special)
+void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special)
{
char buff[256],buff2[256];
String str(buff,sizeof(buff)),out(buff2,sizeof(buff2));
@@ -240,6 +240,17 @@ Open streams: %10lu\n",
(ulong) cached_tables(),
(ulong) my_file_opened,
(ulong) my_stream_opened);
+
+ ALARM_INFO alarm_info;
+ thr_alarm_info(&alarm_info);
+ printf("\nAlarm status:\n\
+Active alarms: %u\n\
+Max used alarms: %u\n\
+Next alarm time: %lu\n",
+ alarm_info.active_alarms,
+ alarm_info.max_used_alarms,
+ alarm_info.next_alarm_time);
+
fflush(stdout);
if (thd)
thd->proc_info="malloc";
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 8184ae3b15e..9493f969802 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -1,21 +1,19 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
/* This implements 'user defined functions' */
/*
@@ -52,11 +50,11 @@ extern "C"
{
FreeLibrary((HMODULE)lib);
}
-
+
#elif !defined(OS2)
#include <dlfcn.h>
#endif
-
+
#include <stdarg.h>
#include <hash.h>
}
@@ -141,7 +139,8 @@ void udf_init()
new_thd->version = refresh_version; //current_thd->version;
new_thd->current_tablenr = 0;
new_thd->open_tables = 0;
- new_thd->db = my_strdup("mysql", MYF(0));
+ new_thd->db= my_strdup("mysql", MYF(0));
+ new_thd->db_length=5;
bzero((gptr) &tables,sizeof(tables));
tables.name = tables.real_name = (char*) "func";
diff --git a/sql/sql_udf.h b/sql/sql_udf.h
index d0b20f0a734..1ee9c44ce48 100644
--- a/sql/sql_udf.h
+++ b/sql/sql_udf.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
new file mode 100644
index 00000000000..aeedfeb148b
--- /dev/null
+++ b/sql/sql_union.cc
@@ -0,0 +1,287 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ UNION of select's
+ UNION's were introduced by Monty and Sinisa <sinisa@mysql.com>
+*/
+
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+
+int mysql_union(THD *thd, LEX *lex,select_result *result)
+{
+ SELECT_LEX *sl, *last_sl, *lex_sl;
+ ORDER *order;
+ List<Item> item_list;
+ TABLE *table;
+ int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
+ int res;
+ bool found_rows_for_union=false;
+ TABLE_LIST result_table_list;
+ TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
+ TMP_TABLE_PARAM tmp_table_param;
+ select_union *union_result;
+ DBUG_ENTER("mysql_union");
+
+ /* Fix tables 'to-be-unioned-from' list to point at opened tables */
+ last_sl= &lex->select_lex;
+ for (sl= last_sl;
+ sl && sl->linkage != NOT_A_SELECT;
+ last_sl=sl, sl=sl->next)
+ {
+ for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
+ cursor;
+ cursor=cursor->next)
+ {
+ if (cursor->do_redirect) // False if CUBE/ROLLUP
+ {
+ cursor->table= ((TABLE_LIST*) cursor->table)->table;
+ cursor->do_redirect=false;
+ }
+ }
+ }
+
+ /* last_sel now points at the last select where the ORDER BY is stored */
+ if (sl)
+ {
+ /*
+ The found SL is an extra SELECT_LEX argument that contains
+ the ORDER BY and LIMIT parameter for the whole UNION
+ */
+ lex_sl= sl;
+ order= (ORDER *) lex_sl->order_list.first;
+ found_rows_for_union = (lex->select_lex.options & OPTION_FOUND_ROWS &&
+ !describe && sl->select_limit);
+ if (found_rows_for_union)
+ lex->select_lex.options ^= OPTION_FOUND_ROWS;
+ // This is done to eliminate unnecessary slowing down of the first query
+ if (!order || !describe)
+ last_sl->next=0; // Remove this extra element
+ }
+ else if (!last_sl->braces)
+ {
+ lex_sl= last_sl; // ORDER BY is here
+ order= (ORDER *) lex_sl->order_list.first;
+ }
+ else
+ {
+ lex_sl=0;
+ order=0;
+ }
+
+ if (describe)
+ {
+ Item *item;
+ item_list.push_back(new Item_empty_string("table",NAME_LEN));
+ item_list.push_back(new Item_empty_string("type",10));
+ item_list.push_back(item=new Item_empty_string("possible_keys",
+ NAME_LEN*MAX_KEY));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_empty_string("key",NAME_LEN));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_int("key_len",0,3));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_empty_string("ref",
+ NAME_LEN*MAX_REF_PARTS));
+ item->maybe_null=1;
+ item_list.push_back(new Item_real("rows",0.0,0,10));
+ item_list.push_back(new Item_empty_string("Extra",255));
+ }
+ else
+ {
+ Item *item;
+ List_iterator<Item> it(lex->select_lex.item_list);
+ TABLE_LIST *first_table= (TABLE_LIST*) lex->select_lex.table_list.first;
+
+ /* Create a list of items that will be in the result set */
+ while ((item= it++))
+ if (item_list.push_back(item))
+ DBUG_RETURN(-1);
+ if (setup_fields(thd,first_table,item_list,0,0,1))
+ DBUG_RETURN(-1);
+ }
+
+ bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
+ tmp_table_param.field_count=item_list.elements;
+ if (!(table=create_tmp_table(thd, &tmp_table_param, item_list,
+ (ORDER*) 0, !describe & !lex->union_option,
+ 1, 0,
+ (lex->select_lex.options | thd->options |
+ TMP_TABLE_ALL_COLUMNS))))
+ DBUG_RETURN(-1);
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ bzero((char*) &result_table_list,sizeof(result_table_list));
+ result_table_list.db= (char*) "";
+ result_table_list.real_name=result_table_list.name=(char*) "union";
+ result_table_list.table=table;
+
+ if (!(union_result=new select_union(table)))
+ {
+ res= -1;
+ goto exit;
+ }
+ union_result->save_time_stamp=!describe;
+ union_result->tmp_table_param=&tmp_table_param;
+ for (sl= &lex->select_lex; sl; sl=sl->next)
+ {
+ lex->select=sl;
+ thd->offset_limit=sl->offset_limit;
+ thd->select_limit=sl->select_limit+sl->offset_limit;
+ if (thd->select_limit < sl->select_limit)
+ thd->select_limit= HA_POS_ERROR; // no limit
+ if (thd->select_limit == HA_POS_ERROR)
+ sl->options&= ~OPTION_FOUND_ROWS;
+
+ res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ? first_table : (TABLE_LIST*) sl->table_list.first,
+ sl->item_list,
+ sl->where,
+ (sl->braces) ? (ORDER *)sl->order_list.first : (ORDER *) 0,
+ (ORDER*) sl->group_list.first,
+ sl->having,
+ (ORDER*) NULL,
+ sl->options | thd->options | SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0),
+ union_result);
+ if (res)
+ goto exit;
+ }
+ if (union_result->flush())
+ {
+ res= 1; // Error is already sent
+ goto exit;
+ }
+ delete union_result;
+
+ /* Send result to 'result' */
+ lex->select = &lex->select_lex;
+ res =-1;
+ {
+ /* Create a list of fields in the temporary table */
+ List_iterator<Item> it(item_list);
+ Field **field;
+#if 0
+ List<Item_func_match> ftfunc_list;
+ ftfunc_list.empty();
+#else
+ thd->lex.select_lex.ftfunc_list.empty();
+#endif
+
+ for (field=table->field ; *field ; field++)
+ {
+ (void) it++;
+ (void) it.replace(new Item_field(*field));
+ }
+ if (!thd->fatal_error) // Check if EOM
+ {
+ if (lex_sl)
+ {
+ thd->offset_limit=lex_sl->offset_limit;
+ thd->select_limit=lex_sl->select_limit+lex_sl->offset_limit;
+ if (thd->select_limit < lex_sl->select_limit)
+ thd->select_limit= HA_POS_ERROR; // no limit
+ if (thd->select_limit == HA_POS_ERROR)
+ thd->options&= ~OPTION_FOUND_ROWS;
+ }
+ else
+ {
+ thd->offset_limit= 0;
+ thd->select_limit= thd->variables.select_limit;
+ }
+ if (describe)
+ thd->select_limit= HA_POS_ERROR; // no limit
+ res=mysql_select(thd,&result_table_list,
+ item_list, NULL, (describe) ? 0 : order,
+ (ORDER*) NULL, NULL, (ORDER*) NULL,
+ thd->options, result);
+ if (found_rows_for_union && !res)
+ thd->limit_found_rows = (ulonglong)table->file->records;
+ }
+ }
+
+exit:
+ free_tmp_table(thd,table);
+ DBUG_RETURN(res);
+}
+
+
+/***************************************************************************
+** store records in temporary table for UNION
+***************************************************************************/
+
+select_union::select_union(TABLE *table_par)
+ :table(table_par)
+{
+ bzero((char*) &info,sizeof(info));
+ /*
+ We can always use DUP_IGNORE because the temporary table will only
+ contain a unique key if we are using not using UNION ALL
+ */
+ info.handle_duplicates=DUP_IGNORE;
+}
+
+select_union::~select_union()
+{
+}
+
+
+int select_union::prepare(List<Item> &list)
+{
+ if (save_time_stamp && list.elements != table->fields)
+ {
+ my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
+ ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
+ return -1;
+ }
+ return 0;
+}
+
+bool select_union::send_data(List<Item> &values)
+{
+ if (thd->offset_limit)
+ { // using limit offset,count
+ thd->offset_limit--;
+ return 0;
+ }
+
+ fill_record(table->field,values);
+ if ((write_record(table,&info)))
+ {
+ if (create_myisam_from_heap(table, tmp_table_param, info.last_errno, 0))
+ return 1;
+ }
+ return 0;
+}
+
+bool select_union::send_eof()
+{
+ return 0;
+}
+
+bool select_union::flush()
+{
+ int error;
+ if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
+ {
+ table->file->print_error(error,MYF(0));
+ ::send_error(&thd->net);
+ return 1;
+ }
+ return 0;
+}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 6a4cdb80e5d..fda07721da8 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1,24 +1,27 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Update of records */
+/* Update of records
+ Multi-table updates were introduced by Monty and Sinisa <sinisa@mysql.com>
+*/
#include "mysql_priv.h"
#include "sql_acl.h"
+#include "sql_select.h"
/* Return 0 if row hasn't changed */
@@ -40,8 +43,12 @@ static bool compare_record(TABLE *table, ulong query_id)
}
-int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
- List<Item> &values, COND *conds,
+int mysql_update(THD *thd,
+ TABLE_LIST *table_list,
+ List<Item> &fields,
+ List<Item> &values,
+ COND *conds,
+ ORDER *order,
ha_rows limit,
enum enum_duplicates handle_duplicates,
thr_lock_type lock_type)
@@ -87,7 +94,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
/* Check the fields we are going to modify */
table->grant.want_privilege=want_privilege;
- if (setup_fields(thd,table_list,fields,1,0))
+ if (setup_fields(thd,table_list,fields,1,0,0))
DBUG_RETURN(-1); /* purecov: inspected */
if (table->timestamp_field)
{
@@ -100,7 +107,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
/* Check values */
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
- if (setup_fields(thd,table_list,values,0,0))
+ if (setup_fields(thd,table_list,values,0,0,0))
{
table->time_stamp=save_time_stamp; // Restore timestamp pointer
DBUG_RETURN(-1); /* purecov: inspected */
@@ -126,7 +133,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
/* If running in safe sql mode, don't allow updates without keys */
if (!table->quick_keys)
{
- thd->lex.options|=QUERY_NO_INDEX_USED;
+ thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR)
{
delete select;
@@ -146,7 +153,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
used_key_is_modified=check_if_key_used(table, used_index, fields);
else
used_key_is_modified=0;
- if (used_key_is_modified)
+ if (used_key_is_modified || order)
{
/*
** We can't update table directly; We must first search after all
@@ -166,8 +173,36 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
+
+ if (order)
+ {
+ uint length;
+ SORT_FIELD *sortorder;
+ TABLE_LIST tables;
+ List<Item> fields;
+ List<Item> all_fields;
+ ha_rows examined_rows;
+
+ bzero((char*) &tables,sizeof(tables));
+ tables.table = table;
+
+ table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
+ MYF(MY_FAE | MY_ZEROFILL));
+ if (setup_order(thd, &tables, fields, all_fields, order) ||
+ !(sortorder=make_unireg_sortorder(order, &length)) ||
+ (table->found_records = filesort(table, sortorder, length,
+ (SQL_SELECT *) 0, 0L,
+ HA_POS_ERROR, &examined_rows))
+ == HA_POS_ERROR)
+ {
+ delete select;
+ table->time_stamp=save_time_stamp; // Restore timestamp pointer
+ DBUG_RETURN(-1);
+ }
+ }
+
init_read_record(&info,thd,table,select,0,1);
- thd->proc_info="searching";
+ thd->proc_info="Searching rows for update";
while (!(error=info.read_record(&info)) && !thd->killed)
{
@@ -183,7 +218,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
}
else
{
- if (!(test_flags & 512)) /* For debugging */
+ if (!(test_flags & 512)) /* For debugging */
{
DBUG_DUMP("record",(char*) table->record[0],table->reclength);
}
@@ -205,7 +240,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
select->cond=0;
}
else
- {
+ {
select= new SQL_SELECT;
select->head=table;
}
@@ -216,12 +251,10 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
{
delete select;
table->time_stamp=save_time_stamp; // Restore timestamp pointer
- DBUG_RETURN(-1);
+ DBUG_RETURN(-1);
}
}
- if (!(test_flags & TEST_READCHECK)) /* For debugging */
- VOID(table->file->extra(HA_EXTRA_NO_READCHECK));
if (handle_duplicates == DUP_IGNORE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
init_read_record(&info,thd,table,select,0,1);
@@ -229,7 +262,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
ha_rows updated=0L,found=0L;
thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0L;
- thd->proc_info="updating";
+ thd->proc_info="Updating";
query_id=thd->query_id;
while (!(error=info.read_record(&info)) && !thd->killed)
@@ -266,7 +299,6 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
}
end_read_record(&info);
thd->proc_info="end";
- VOID(table->file->extra(HA_EXTRA_READCHECK));
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
table->time_stamp=save_time_stamp; // Restore auto timestamp pointer
using_transactions=table->file->has_transactions();
@@ -284,11 +316,16 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
}
if (using_transactions && ha_autocommit_or_rollback(thd, error >= 0))
error=1;
+ if (updated)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
+
delete select;
if (error >= 0)
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
@@ -303,5 +340,476 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
DBUG_PRINT("info",("%d records updated",updated));
}
thd->count_cuted_fields=0; /* calc cuted fields */
+ free_io_cache(table);
+ DBUG_RETURN(0);
+}
+
+/***************************************************************************
+ Update multiple tables from join
+***************************************************************************/
+
+multi_update::multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> &fs,
+ enum enum_duplicates handle_duplicates, thr_lock_type lock_option_arg, uint num)
+ : update_tables (ut), thd(thd_arg), updated(0), found(0), fields(fs), lock_option(lock_option_arg),
+ dupl(handle_duplicates), num_of_tables(num), num_fields(0), num_updated(0) , error(0), do_update(false)
+{
+ save_time_stamps = (uint *) sql_calloc (sizeof(uint) * num_of_tables);
+ tmp_tables = (TABLE **)NULL;
+ int counter=0;
+ ulong timestamp_query_id;
+ not_trans_safe=false;
+ for (TABLE_LIST *dt=ut ; dt ; dt=dt->next,counter++)
+ {
+ TABLE *table=ut->table;
+ // (void) ut->table->file->extra(HA_EXTRA_NO_KEYREAD);
+ dt->table->used_keys=0;
+ if (table->timestamp_field)
+ {
+ // Don't set timestamp column if this is modified
+ timestamp_query_id=table->timestamp_field->query_id;
+ table->timestamp_field->query_id=thd->query_id-1;
+ if (table->timestamp_field->query_id == thd->query_id)
+ table->time_stamp=0;
+ else
+ table->timestamp_field->query_id=timestamp_query_id;
+ }
+ save_time_stamps[counter]=table->time_stamp;
+ }
+ error = 1; // In case we do not reach prepare we have to reset timestamps
+}
+
+int
+multi_update::prepare(List<Item> &values)
+{
+ DBUG_ENTER("multi_update::prepare");
+ do_update = true;
+ thd->count_cuted_fields=1;
+ thd->cuted_fields=0L;
+ thd->proc_info="updating the main table";
+ TABLE_LIST *table_ref;
+
+ if (thd->options & OPTION_SAFE_UPDATES)
+ {
+ for (table_ref=update_tables; table_ref; table_ref=table_ref->next)
+ {
+ TABLE *table=table_ref->table;
+ if ((thd->options & OPTION_SAFE_UPDATES) && !table->quick_keys)
+ {
+ my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+ }
+ /*
+ Here I have to connect fields with tables and only update tables that
+ need to be updated.
+ I calculate num_updated and fill-up table_sequence
+ Set table_list->shared to true or false, depending on whether table is
+ to be updated or not
+ */
+
+ Item_field *item;
+ List_iterator<Item> it(fields);
+ num_fields=fields.elements;
+ field_sequence = (uint *) sql_alloc(sizeof(uint)*num_fields);
+ uint *int_ptr=field_sequence;
+ while ((item= (Item_field *)it++))
+ {
+ unsigned int counter=0;
+ for (table_ref=update_tables; table_ref;
+ table_ref=table_ref->next, counter++)
+ {
+ if (table_ref->table == item->field->table && !table_ref->shared)
+ {
+ num_updated++;
+ table_ref->shared=1;
+ if (!not_trans_safe && !table_ref->table->file->has_transactions())
+ not_trans_safe=true;
+ // to be moved if initialize_tables has to be used
+ table_ref->table->no_keyread=1;
+ break;
+ }
+ }
+ if (!table_ref)
+ {
+ error = 1; // A proper error message is due here
+ DBUG_RETURN(1);
+ }
+ else
+ *int_ptr++=counter;
+ }
+ if (!num_updated)
+ {
+ error = 1; // A proper error message is due here
+ DBUG_RETURN(1);
+ }
+
+ /*
+ Here, I have to allocate the array of temporary tables
+ I have to treat a case of num_updated=1 differently in send_data() method.
+ */
+ if (num_updated > 1)
+ {
+ tmp_tables = (TABLE **) sql_calloc(sizeof(TABLE *) * (num_updated - 1));
+ infos = (COPY_INFO *) sql_calloc(sizeof(COPY_INFO) * (num_updated - 1));
+ fields_by_tables = (List_item **)sql_calloc(sizeof(List_item *) * num_updated);
+ unsigned int counter;
+ List<Item> *temp_fields;
+ for (table_ref=update_tables, counter = 0; table_ref; table_ref=table_ref->next)
+ {
+ if (!table_ref->shared)
+ continue;
+ // Here we have to add row offset as an additional field ...
+ if (!(temp_fields = (List_item *)sql_calloc(sizeof(List_item))))
+ {
+ error = 1; // A proper error message is due here
+ DBUG_RETURN(1);
+ }
+ temp_fields->empty();
+ it.rewind(); int_ptr=field_sequence;
+ while ((item= (Item_field *)it++))
+ {
+ if (*int_ptr++ == counter)
+ temp_fields->push_back(item);
+ }
+ if (counter)
+ {
+ Field_string offset(table_ref->table->file->ref_length,false,"offset",table_ref->table,true);
+ temp_fields->push_front(new Item_field(((Field *)&offset)));
+ // Here I make tmp tables
+ int cnt=counter-1;
+ TMP_TABLE_PARAM tmp_table_param;
+ bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
+ tmp_table_param.field_count=temp_fields->elements;
+ if (!(tmp_tables[cnt]=create_tmp_table(thd, &tmp_table_param,
+ *temp_fields,
+ (ORDER*) 0, 1, 0, 0,
+ TMP_TABLE_ALL_COLUMNS)))
+ {
+ error = 1; // A proper error message is due here
+ DBUG_RETURN(1);
+ }
+ tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
+ tmp_tables[cnt]->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ infos[cnt].handle_duplicates=DUP_IGNORE;
+ temp_fields->pop(); // because we shall use those for values only ...
+ }
+ fields_by_tables[counter]=temp_fields;
+ counter++;
+ }
+ }
+ error = 0; // Timestamps do not need to be restored, so far ...
DBUG_RETURN(0);
}
+
+
+void
+multi_update::initialize_tables(JOIN *join)
+{
+#ifdef NOT_YET
+ We skip it as it only makes a mess ...........
+ TABLE_LIST *walk;
+ table_map tables_to_update_from=0;
+ for (walk= update_tables ; walk ; walk=walk->next)
+ tables_to_update_from|= walk->table->map;
+
+ walk= update_tables;
+ for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
+ tab < end;
+ tab++)
+ {
+ if (tab->table->map & tables_to_update_from)
+ {
+ We are going to update from this table
+ TABLE *tbl=walk->table=tab->table;
+ /* Don't use KEYREAD optimization on this table */
+ tbl->no_keyread=1;
+ walk=walk->next;
+ }
+ }
+#endif
+}
+
+
+multi_update::~multi_update()
+{
+ int counter = 0;
+ for (table_being_updated=update_tables ;
+ table_being_updated ;
+ counter++, table_being_updated=table_being_updated->next)
+ {
+ TABLE *table=table_being_updated->table;
+ table->no_keyread=0;
+ if (error)
+ table->time_stamp=save_time_stamps[counter];
+ }
+ if (tmp_tables)
+ for (uint counter = 0; counter < num_updated-1; counter++)
+ if (tmp_tables[counter])
+ free_tmp_table(thd,tmp_tables[counter]);
+}
+
+
+bool multi_update::send_data(List<Item> &values)
+{
+ List<Item> real_values(values);
+ for (uint counter = 0; counter < fields.elements; counter++)
+ real_values.pop();
+ // We have skipped fields ....
+ if (num_updated == 1)
+ {
+ for (table_being_updated=update_tables ;
+ table_being_updated ;
+ table_being_updated=table_being_updated->next)
+ {
+ if (!table_being_updated->shared)
+ continue;
+ TABLE *table=table_being_updated->table;
+ /* Check if we are using outer join and we didn't find the row */
+ if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
+ return 0;
+ table->file->position(table->record[0]);
+ // Only one table being updated receives a completely different treatment
+ table->status|= STATUS_UPDATED;
+ store_record(table,1);
+ if (fill_record(fields,real_values))
+ return 1;
+ found++;
+ if (/* compare_record(table, query_id) && */
+ !(error=table->file->update_row(table->record[1], table->record[0])))
+ updated++;
+ return error;
+ }
+ }
+ else
+ {
+ int secure_counter= -1;
+ for (table_being_updated=update_tables ;
+ table_being_updated ;
+ table_being_updated=table_being_updated->next, secure_counter++)
+ {
+ if (!table_being_updated->shared)
+ continue;
+
+ TABLE *table=table_being_updated->table;
+ /* Check if we are using outer join and we didn't find the row */
+ if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
+ continue;
+ table->file->position(table->record[0]);
+ Item *item;
+ List_iterator<Item> it(real_values);
+ List <Item> values_by_table;
+ uint *int_ptr=field_sequence;
+ while ((item= (Item *)it++))
+ {
+ if (*int_ptr++ == (uint) (secure_counter + 1))
+ values_by_table.push_back(item);
+ }
+ // Here I am breaking values as per each table
+ if (secure_counter < 0)
+ {
+ table->status|= STATUS_UPDATED;
+ store_record(table,1);
+ if (fill_record(*fields_by_tables[0],values_by_table))
+ return 1;
+ found++;
+ if (/*compare_record(table, query_id) && */
+ !(error=table->file->update_row(table->record[1], table->record[0])))
+ updated++;
+ else
+ {
+ table->file->print_error(error,MYF(0));
+ if (!error) error=1;
+ return 1;
+ }
+ }
+ else
+ {
+ // Here we insert into each temporary table
+ values_by_table.push_front(new Item_string((char*) table->file->ref,
+ table->file->ref_length));
+ fill_record(tmp_tables[secure_counter]->field,values_by_table);
+ error= write_record(tmp_tables[secure_counter],
+ &(infos[secure_counter]));
+ if (error)
+ {
+ error=-1;
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void multi_update::send_error(uint errcode,const char *err)
+{
+ /* First send error what ever it is ... */
+ ::send_error(&thd->net,errcode,err);
+
+ /* reset used flags */
+ // update_tables->table->no_keyread=0;
+
+ /* If nothing updated return */
+ if (!updated)
+ return;
+
+ /* Something already updated so we have to invalidate cache */
+ query_cache_invalidate3(thd, update_tables, 1);
+
+ /* Below can happen when thread is killed early ... */
+ if (!table_being_updated)
+ table_being_updated=update_tables;
+
+ /*
+ If rows from the first table only has been updated and it is transactional,
+ just do rollback.
+ The same if all tables are transactional, regardless of where we are.
+ In all other cases do attempt updates ...
+ */
+ if ((table_being_updated->table->file->has_transactions() &&
+ table_being_updated == update_tables) || !not_trans_safe)
+ ha_rollback_stmt(thd);
+ else if (do_update)
+ VOID(do_updates(true));
+}
+
+
+int multi_update::do_updates (bool from_send_error)
+{
+ int error = 0, counter = 0;
+
+ if (num_updated == 1)
+ return 0;
+ if (from_send_error)
+ {
+ /* Found out table number for 'table_being_updated' */
+ for (TABLE_LIST *aux=update_tables;
+ aux != table_being_updated;
+ aux=aux->next)
+ counter++;
+ }
+ else
+ table_being_updated = update_tables;
+
+ do_update = false;
+ for (table_being_updated=table_being_updated->next;
+ table_being_updated ;
+ table_being_updated=table_being_updated->next, counter++)
+ {
+ if (!table_being_updated->shared)
+ continue;
+
+ TABLE *table = table_being_updated->table;
+ TABLE *tmp_table=tmp_tables[counter];
+ if (tmp_table->file->extra(HA_EXTRA_NO_CACHE))
+ {
+ error=1;
+ break;
+ }
+ List<Item> list;
+ Field **ptr=tmp_table->field,*field;
+ // This is supposed to be something like insert_fields
+ thd->used_tables|=tmp_table->map;
+ while ((field = *ptr++))
+ {
+ list.push_back((Item *)new Item_field(field));
+ if (field->query_id == thd->query_id)
+ thd->dupp_field=field;
+ field->query_id=thd->query_id;
+ tmp_table->used_keys&=field->part_of_key;
+ }
+ tmp_table->used_fields=tmp_table->fields;
+ error=0; list.pop(); // we get position some other way ...
+ error = tmp_table->file->rnd_init(1);
+ if (error)
+ return error;
+ while (!(error=tmp_table->file->rnd_next(tmp_table->record[0])) &&
+ (!thd->killed || from_send_error || not_trans_safe))
+ {
+ found++;
+ error= table->file->rnd_pos(table->record[0],
+ (byte*) (*(tmp_table->field))->ptr);
+ if (error)
+ return error;
+ table->status|= STATUS_UPDATED;
+ store_record(table,1);
+ error= fill_record(*fields_by_tables[counter + 1],list) ||
+ /* compare_record(table, query_id) || */
+ table->file->update_row(table->record[1],table->record[0]);
+ if (error)
+ {
+ table->file->print_error(error,MYF(0));
+ break;
+ }
+ else
+ updated++;
+ }
+ if (error == HA_ERR_END_OF_FILE)
+ error = 0;
+ }
+ return error;
+}
+
+
+/* out: 1 if error, 0 if success */
+
+bool multi_update::send_eof()
+{
+ thd->proc_info="updating the reference tables";
+
+ /* Does updates for the last n - 1 tables, returns 0 if ok */
+ int error = do_updates(false); /* do_updates returns 0 if success */
+
+ /* reset used flags */
+#ifndef NOT_USED
+ update_tables->table->no_keyread=0;
+#endif
+ if (error == -1)
+ error = 0;
+ thd->proc_info="end";
+ if (error)
+ send_error(error,"An error occured in multi-table update");
+
+ /*
+ Write the SQL statement to the binlog if we updated
+ rows and we succeeded, or also in an error case when there
+ was a non-transaction-safe table involved, since
+ modifications in it cannot be rolled back.
+ */
+
+ if (updated || not_trans_safe)
+ {
+ mysql_update_log.write(thd,thd->query,thd->query_length);
+ Query_log_event qinfo(thd, thd->query);
+
+ /*
+ mysql_bin_log is not open if binlogging or replication
+ is not used
+ */
+
+ if (mysql_bin_log.is_open() && mysql_bin_log.write(&qinfo) &&
+ !not_trans_safe)
+ error=1; /* Log write failed: roll back the SQL statement */
+
+ /* Commit or rollback the current SQL statement */
+ VOID(ha_autocommit_or_rollback(thd,error > 0));
+ }
+ else
+ error=0; // this can happen only if it is end of file error
+ if (!error) // if the above log write did not fail ...
+ {
+ char buff[80];
+ sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated,
+ (long) thd->cuted_fields);
+ if (updated)
+ {
+ query_cache_invalidate3(thd, update_tables, 1);
+ }
+ ::send_ok(&thd->net,
+ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
+ thd->insert_id_used ? thd->insert_id() : 0L,buff);
+ }
+ thd->count_cuted_fields=0;
+ return 0;
+}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index e258f5d3827..a8a9237ebaf 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2001 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,11 +21,13 @@
#define YYINITDEPTH 100
#define YYMAXDEPTH 3200 /* Because of 64K stack */
#define Lex current_lex
+#define Select Lex->select
#include "mysql_priv.h"
-#include "slave.h"
+#include "slave.h"
#include "sql_acl.h"
#include "lex_symbol.h"
#include <myisam.h>
+#include <myisammrg.h>
extern void yyerror(const char*);
int yylex(void *yylval);
@@ -42,7 +44,7 @@ inline Item *or_or_concat(Item* A, Item* B)
%union {
int num;
ulong ulong_num;
- ulonglong ulonglong_num;
+ ulonglong ulonglong_number;
LEX_STRING lex_str;
LEX_STRING *lex_str_ptr;
LEX_SYMBOL symbol;
@@ -51,17 +53,20 @@ inline Item *or_or_concat(Item* A, Item* B)
Item *item;
List<Item> *item_list;
List<String> *string_list;
- Key::Keytype key_type;
- enum db_type db_type;
- enum row_type row_type;
- enum enum_tx_isolation tx_isolation;
String *string;
key_part_spec *key_part;
TABLE_LIST *table_list;
udf_func *udf;
- interval_type interval;
LEX_USER *lex_user;
+ sys_var *variable;
+ Key::Keytype key_type;
+ enum db_type db_type;
+ enum row_type row_type;
+ enum ha_rkey_function ha_rkey_mode;
+ enum enum_tx_isolation tx_isolation;
+ enum Item_cast cast_type;
enum Item_udftype udf_type;
+ interval_type interval;
}
%{
@@ -72,6 +77,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token END_OF_INPUT
+%token CLOSE_SYM
+%token HANDLER_SYM
+%token LAST_SYM
+%token NEXT_SYM
+%token PREV_SYM
+
%token EQ
%token EQUAL_SYM
%token GE
@@ -84,46 +95,56 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SHIFT_RIGHT
%token SET_VAR
-%token AVG_SYM
-%token COUNT_SYM
-%token MAX_SYM
-%token MIN_SYM
-%token SUM_SYM
-%token STD_SYM
-
+%token ABORT_SYM
%token ADD
-%token ALTER
%token AFTER_SYM
-%token ANALYZE_SYM
-%token BEGIN_SYM
+%token ALTER
+%token ANALYZE_SYM
+%token AVG_SYM
+%token BEGIN_SYM
+%token BINLOG_SYM
%token CHANGE
-%token COMMENT_SYM
-%token COMMIT_SYM
+%token CLIENT_SYM
+%token COMMENT_SYM
+%token COMMIT_SYM
+%token COUNT_SYM
%token CREATE
%token CROSS
+%token CUBE_SYM
%token DELETE_SYM
%token DO_SYM
%token DROP
-%token INSERT
+%token EVENTS_SYM
+%token EXECUTE_SYM
%token FLUSH_SYM
-%token SELECT_SYM
-%token MASTER_SYM
-%token REPAIR
-%token RESET_SYM
-%token PURGE
-%token SLAVE
-%token START_SYM
-%token STOP_SYM
-%token TRUNCATE_SYM
-%token ROLLBACK_SYM
-%token OPTIMIZE
-%token SHOW
-%token UPDATE_SYM
+%token INSERT
+%token IO_THREAD
%token KILL_SYM
%token LOAD
-%token LOCK_SYM
%token LOCKS_SYM
+%token LOCK_SYM
+%token MASTER_SYM
+%token MAX_SYM
+%token MIN_SYM
+%token OPTIMIZE
+%token PURGE
+%token REPAIR
+%token REPLICATION
+%token RESET_SYM
+%token ROLLBACK_SYM
+%token ROLLUP_SYM
+%token SELECT_SYM
+%token SHOW
+%token SLAVE
+%token SQL_THREAD
+%token START_SYM
+%token STD_SYM
+%token STOP_SYM
+%token SUM_SYM
+%token SUPER_SYM
+%token TRUNCATE_SYM
%token UNLOCK_SYM
+%token UPDATE_SYM
%token ACTION
%token AGGREGATE_SYM
@@ -132,23 +153,27 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token AS
%token ASC
%token AUTO_INC
-%token AUTOCOMMIT
%token AVG_ROW_LENGTH
-%token BACKUP_SYM
+%token BACKUP_SYM
%token BERKELEY_DB_SYM
%token BINARY
%token BIT_SYM
%token BOOL_SYM
+%token BOOLEAN_SYM
%token BOTH
%token BY
+%token CACHE_SYM
%token CASCADE
+%token CAST_SYM
%token CHECKSUM_SYM
%token CHECK_SYM
+%token CIPHER
%token COMMITTED_SYM
%token COLUMNS
%token COLUMN_SYM
%token CONCURRENT
%token CONSTRAINT
+%token CONVERT_SYM
%token DATABASES
%token DATA_SYM
%token DEFAULT
@@ -156,10 +181,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DELAY_KEY_WRITE_SYM
%token DESC
%token DESCRIBE
+%token DES_KEY_FILE
+%token DISABLE_SYM
%token DISTINCT
%token DYNAMIC_SYM
+%token ENABLE_SYM
%token ENCLOSED
%token ESCAPED
+%token DIRECTORY_SYM
%token ESCAPE_SYM
%token EXISTS
%token EXTENDED_SYM
@@ -170,10 +199,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FOREIGN
%token FROM
%token FULL
-%token FULLTEXT_SYM
-%token GEMINI_SYM
-%token GEMINI_SPIN_RETRIES
-%token GLOBAL_SYM
+%token FULLTEXT_SYM
+%token GLOBAL_SYM
%token GRANT
%token GRANTS
%token GREATEST_SYM
@@ -186,19 +213,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token IDENT
%token IGNORE_SYM
%token INDEX
+%token INDEXES
%token INFILE
%token INNER_SYM
%token INNOBASE_SYM
%token INTO
%token IN_SYM
-%token ISOLATION
+%token ISOLATION
%token ISAM_SYM
+%token ISSUER
%token JOIN_SYM
%token KEYS
%token KEY_SYM
%token LEADING
%token LEAST_SYM
-%token LEVEL_SYM
+%token LEVEL_SYM
%token LEX_HOSTNAME
%token LIKE
%token LINES
@@ -207,21 +236,29 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token LONG_NUM
%token LONG_SYM
%token LOW_PRIORITY
-%token MASTER_HOST_SYM
-%token MASTER_USER_SYM
-%token MASTER_LOG_FILE_SYM
-%token MASTER_LOG_POS_SYM
-%token MASTER_PASSWORD_SYM
-%token MASTER_PORT_SYM
-%token MASTER_CONNECT_RETRY_SYM
+%token MASTER_HOST_SYM
+%token MASTER_USER_SYM
+%token MASTER_LOG_FILE_SYM
+%token MASTER_LOG_POS_SYM
+%token MASTER_LOG_SEQ_SYM
+%token MASTER_PASSWORD_SYM
+%token MASTER_PORT_SYM
+%token MASTER_CONNECT_RETRY_SYM
+%token MASTER_SERVER_ID_SYM
+%token RELAY_LOG_FILE_SYM
+%token RELAY_LOG_POS_SYM
%token MATCH
%token MAX_ROWS
+%token MAX_CONNECTIONS_PER_HOUR
+%token MAX_QUERIES_PER_HOUR
+%token MAX_UPDATES_PER_HOUR
%token MEDIUM_SYM
%token MERGE_SYM
%token MIN_ROWS
%token MYISAM_SYM
%token NATIONAL_SYM
%token NATURAL
+%token NEW_SYM
%token NCHAR_SYM
%token NOT
%token NO_FOREIGN_KEY_CHECKS
@@ -237,13 +274,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ORDER_SYM
%token OUTER
%token OUTFILE
-%token DUMPFILE
+%token DUMPFILE
%token PACK_KEYS_SYM
%token PARTIAL
%token PRIMARY_SYM
%token PRIVILEGES
%token PROCESS
%token PROCESSLIST_SYM
+%token QUERY_SYM
%token RAID_0_SYM
%token RAID_STRIPED_SYM
%token RAID_TYPE
@@ -257,7 +295,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token RELOAD
%token RENAME
%token REPEATABLE_SYM
-%token RESTORE_SYM
+%token REQUIRE_SYM
+%token RESOURCES
+%token RESTORE_SYM
%token RESTRICT
%token REVOKE
%token ROWS_SYM
@@ -267,9 +307,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SERIALIZABLE_SYM
%token SESSION_SYM
%token SHUTDOWN
+%token SSL_SYM
%token STARTING
%token STATUS_SYM
%token STRAIGHT_JOIN
+%token SUBJECT_SYM
%token TABLES
%token TABLE_SYM
%token TEMPORARY
@@ -286,10 +328,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token UDF_RETURNS_SYM
%token UDF_SONAME_SYM
%token UDF_SYM
-%token UNCOMMITTED_SYM
+%token UNCOMMITTED_SYM
%token UNION_SYM
%token UNIQUE_SYM
%token USAGE
+%token USE_FRM
%token USE_SYM
%token USING
%token VALUES
@@ -297,12 +340,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token WHERE
%token WITH
%token WRITE_SYM
-%token COMPRESSED_SYM
+%token X509_SYM
+%token XOR
+%token COMPRESSED_SYM
%token BIGINT
%token BLOB_SYM
%token CHAR_SYM
-%token CHANGED
+%token CHANGED
%token COALESCE
%token DATETIME
%token DATE_SYM
@@ -320,8 +365,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MEDIUMTEXT
%token NUMERIC_SYM
%token PRECISION
-%token QUICK
+%token QUICK
%token REAL
+%token SIGNED_SYM
%token SMALLINT
%token STRING_SYM
%token TEXT_SYM
@@ -330,20 +376,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token TINYBLOB
%token TINYINT
%token TINYTEXT
+%token ULONGLONG_NUM
%token UNSIGNED
%token VARBINARY
%token VARCHAR
%token VARYING
%token ZEROFILL
-%token AGAINST
+%token AGAINST
%token ATAN
%token BETWEEN_SYM
%token BIT_AND
%token BIT_OR
%token CASE_SYM
%token CONCAT
-%token CONCAT_WS
+%token CONCAT_WS
%token CURDATE
%token CURTIME
%token DATABASE
@@ -354,6 +401,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DAY_SECOND_SYM
%token DAY_SYM
%token DECODE_SYM
+%token DES_ENCRYPT_SYM
+%token DES_DECRYPT_SYM
%token ELSE
%token ELT_FUNC
%token ENCODE_SYM
@@ -370,7 +419,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token HOUR_SYM
%token IDENTIFIED_SYM
%token IF
-%token INSERT_ID
+%token INSERT_METHOD
%token INTERVAL_SYM
%token LAST_INSERT_ID
%token LEFT
@@ -378,7 +427,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MAKE_SET_SYM
%token MINUTE_SECOND_SYM
%token MINUTE_SYM
-%token MODE_SYM
+%token MODE_SYM
%token MODIFY_SYM
%token MONTH_SYM
%token NOW_SYM
@@ -405,30 +454,24 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token USER
%token WEEK_SYM
%token WHEN_SYM
-%token WORK_SYM
+%token WORK_SYM
%token YEAR_MONTH_SYM
%token YEAR_SYM
%token YEARWEEK
-%token BENCHMARK_SYM
-%token END
-%token THEN_SYM
-
-%token SQL_BIG_TABLES
-%token SQL_BIG_SELECTS
-%token SQL_SELECT_LIMIT
-%token SQL_MAX_JOIN_SIZE
-%token SQL_LOG_BIN
-%token SQL_LOG_OFF
-%token SQL_LOG_UPDATE
-%token SQL_LOW_PRIORITY_UPDATES
-%token SQL_SMALL_RESULT
+%token BENCHMARK_SYM
+%token END
+%token THEN_SYM
+
%token SQL_BIG_RESULT
+%token SQL_CACHE_SYM
+%token SQL_CALC_FOUND_ROWS
+%token SQL_NO_CACHE_SYM
+%token SQL_SMALL_RESULT
%token SQL_BUFFER_RESULT
-%token SQL_WARNINGS
-%token SQL_AUTO_IS_NULL
-%token SQL_SAFE_UPDATES
-%token SQL_QUOTE_SHOW_CREATE
-%token SQL_SLAVE_SKIP_COUNTER
+
+%token ISSUER_SYM
+%token SUBJECT_SYM
+%token CIPHER_SYM
%left SET_VAR
%left OR_OR_CONCAT OR
@@ -441,12 +484,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%left '-' '+'
%left '*' '/' '%'
%left NEG '~'
+%left XOR
+%left '^'
%right NOT
%right BINARY
%type <lex_str>
IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME
- field_ident select_alias ident ident_or_text
+ ULONGLONG_NUM field_ident select_alias ident ident_or_text
%type <lex_str_ptr>
opt_table_alias
@@ -459,27 +504,27 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
opt_escape
%type <string>
- text_string
+ text_string
%type <num>
- type int_type real_type order_dir opt_field_spec set_option lock_option
+ type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options
- table_option opt_if_not_exists
+ table_option opt_if_not_exists opt_var_type opt_var_ident_type
%type <ulong_num>
- ULONG_NUM raid_types
+ ULONG_NUM raid_types merge_insert_types
-%type <ulonglong_num>
- ULONGLONG_NUM
+%type <ulonglong_number>
+ ulonglong_num
%type <item>
literal text_literal insert_ident order_ident
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
- using_list
+ using_list expr_or_default set_expr_or_default
%type <item_list>
- expr_list udf_expr_list when_list ident_list
+ expr_list udf_expr_list when_list ident_list ident_list_arg
%type <key_type>
key_type opt_unique_or_fulltext
@@ -503,7 +548,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <row_type> row_types
-%type <tx_isolation> tx_isolation isolation_types
+%type <tx_isolation> isolation_types
+
+%type <ha_rkey_mode> handler_rkey_mode
+
+%type <cast_type> cast_type
%type <udf_type> udf_func_type
@@ -511,6 +560,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <lex_user> user grant_user
+%type <variable> internal_variable_name
+
%type <NONE>
query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename
@@ -521,13 +572,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
select_item_list select_item values_list no_braces
limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
- when_list2 expr_list2
+ when_list2 expr_list2 handler
opt_precision opt_ignore opt_column opt_restrict
grant revoke set lock unlock string_list field_options field_option
field_opt_list opt_binary table_lock_list table_lock varchar
references opt_on_delete opt_on_delete_list opt_on_delete_item use
opt_delete_options opt_delete_option
- opt_outer table_list table opt_option opt_place opt_low_priority
+ opt_outer table_list table_name opt_option opt_place opt_low_priority
opt_attribute opt_attribute_list attribute column_list column_list_id
opt_column_list grant_privileges opt_table user_list grant_option
grant_privilege grant_privilege_list
@@ -535,7 +586,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
equal optional_braces opt_key_definition key_usage_list2
opt_mi_check_type opt_to mi_check_types normal_join
table_to_table_list table_to_table opt_table_list opt_as
- END_OF_INPUT
+ handler_rkey_function handler_read_or_scan
+ single_multi table_wild_list table_wild_one opt_wild union union_list
+ precision union_option
+END_OF_INPUT
%type <NONE>
'-' '+' '*' '/' '%' '(' ')'
@@ -548,7 +602,7 @@ query:
{
THD *thd=current_thd;
if (!thd->bootstrap &&
- (!(thd->lex.options & OPTION_FOUND_COMMENT)))
+ (!(thd->lex.select_lex.options & OPTION_FOUND_COMMENT)))
{
send_error(&current_thd->net,ER_EMPTY_QUERY);
YYABORT;
@@ -558,7 +612,7 @@ query:
thd->lex.sql_command = SQLCOM_EMPTY_QUERY;
}
}
- | verb_clause END_OF_INPUT {}
+ | verb_clause END_OF_INPUT {};
verb_clause:
alter
@@ -593,9 +647,10 @@ verb_clause:
| slave
| show
| truncate
+ | handler
| unlock
| update
- | use
+ | use;
/* change master */
@@ -605,12 +660,11 @@ change:
LEX *lex = Lex;
lex->sql_command = SQLCOM_CHANGE_MASTER;
memset(&lex->mi, 0, sizeof(lex->mi));
- } master_defs
+ } master_defs;
master_defs:
master_def
- |
- master_defs ',' master_def
+ | master_defs ',' master_def;
master_def:
MASTER_HOST_SYM EQ TEXT_STRING
@@ -638,7 +692,7 @@ master_def:
Lex->mi.port = $3;
}
|
- MASTER_LOG_POS_SYM EQ ULONGLONG_NUM
+ MASTER_LOG_POS_SYM EQ ulonglong_num
{
Lex->mi.pos = $3;
}
@@ -647,7 +701,16 @@ master_def:
{
Lex->mi.connect_retry = $3;
}
-
+ |
+ RELAY_LOG_FILE_SYM EQ TEXT_STRING
+ {
+ Lex->mi.relay_log_name = $3.str;
+ }
+ |
+ RELAY_LOG_POS_SYM EQ ULONG_NUM
+ {
+ Lex->mi.relay_log_pos = $3;
+ };
/* create a table */
@@ -667,93 +730,100 @@ create:
lex->change=NullS;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.options=$2 | $4;
- lex->create_info.db_type= default_table_type;
+ lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
}
create2
| CREATE opt_unique_or_fulltext INDEX ident ON table_ident
{
- Lex->sql_command= SQLCOM_CREATE_INDEX;
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_CREATE_INDEX;
if (!add_table_to_list($6,NULL,1))
YYABORT;
- Lex->create_list.empty();
- Lex->key_list.empty();
- Lex->col_list.empty();
- Lex->change=NullS;
+ lex->create_list.empty();
+ lex->key_list.empty();
+ lex->col_list.empty();
+ lex->change=NullS;
}
'(' key_list ')'
{
- Lex->key_list.push_back(new Key($2,$4.str,Lex->col_list));
- Lex->col_list.empty();
+ LEX *lex=Lex;
+ lex->key_list.push_back(new Key($2,$4.str,lex->col_list));
+ lex->col_list.empty();
}
| CREATE DATABASE opt_if_not_exists ident
{
- Lex->sql_command=SQLCOM_CREATE_DB;
- Lex->name=$4.str;
- Lex->create_info.options=$3;
+ LEX *lex=Lex;
+ lex->sql_command=SQLCOM_CREATE_DB;
+ lex->name=$4.str;
+ lex->create_info.options=$3;
}
| CREATE udf_func_type UDF_SYM ident
{
- Lex->sql_command = SQLCOM_CREATE_FUNCTION;
- Lex->udf.name=$4.str;
- Lex->udf.name_length=$4.length;
- Lex->udf.type= $2;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_CREATE_FUNCTION;
+ lex->udf.name=$4.str;
+ lex->udf.name_length=$4.length;
+ lex->udf.type= $2;
}
UDF_RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING
{
- Lex->udf.returns=(Item_result) $7;
- Lex->udf.dl=$9.str;
- }
+ LEX *lex=Lex;
+ lex->udf.returns=(Item_result) $7;
+ lex->udf.dl=$9.str;
+ };
create2:
'(' field_list ')' opt_create_table_options create3 {}
- | opt_create_table_options create3 {}
+ | opt_create_table_options create3 {};
create3:
/* empty */ {}
| opt_duplicate opt_as SELECT_SYM
{
- Lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
- mysql_init_select(Lex);
+ LEX *lex=Lex;
+ lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
+ mysql_init_select(lex);
}
- select_options select_item_list opt_select_from {}
+ select_options select_item_list opt_select_from union {};
opt_as:
/* empty */ {}
- | AS {}
+ | AS {};
opt_table_options:
/* empty */ { $$= 0; }
- | table_options { $$= $1;}
+ | table_options { $$= $1;};
table_options:
table_option { $$=$1; }
- | table_option table_options { $$= $1 | $2; }
+ | table_option table_options { $$= $1 | $2; };
table_option:
- TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }
+ TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; };
opt_if_not_exists:
/* empty */ { $$= 0; }
- | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }
+ | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; };
opt_create_table_options:
/* empty */
- | create_table_options
+ | create_table_options;
create_table_options:
create_table_option
- | create_table_option create_table_options
+ | create_table_option create_table_options;
create_table_option:
TYPE_SYM EQ table_types { Lex->create_info.db_type= $3; }
- | MAX_ROWS EQ ULONGLONG_NUM { Lex->create_info.max_rows= $3; }
- | MIN_ROWS EQ ULONGLONG_NUM { Lex->create_info.min_rows= $3; }
- | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; }
+ | MAX_ROWS EQ ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
+ | MIN_ROWS EQ ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
+ | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
| PASSWORD EQ TEXT_STRING { Lex->create_info.password=$3.str; }
| COMMENT_SYM EQ TEXT_STRING { Lex->create_info.comment=$3.str; }
- | AUTO_INC EQ ULONGLONG_NUM { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
- | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; }
+ | AUTO_INC EQ ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
+ | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
+ | PACK_KEYS_SYM EQ DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
| CHECKSUM_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; }
| DELAY_KEY_WRITE_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; }
| ROW_FORMAT_SYM EQ row_types { Lex->create_info.row_type= $3; }
@@ -764,15 +834,18 @@ create_table_option:
{
/* Move the union list to the merge_list */
LEX *lex=Lex;
- TABLE_LIST *table_list= (TABLE_LIST*) lex->table_list.first;
- lex->create_info.merge_list= lex->table_list;
+ TABLE_LIST *table_list= (TABLE_LIST*) lex->select->table_list.first;
+ lex->create_info.merge_list= lex->select->table_list;
lex->create_info.merge_list.elements--;
lex->create_info.merge_list.first= (byte*) (table_list->next);
- lex->table_list.elements=1;
- lex->table_list.next= (byte**) &(table_list->next);
+ lex->select->table_list.elements=1;
+ lex->select->table_list.next= (byte**) &(table_list->next);
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
+ | 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; }
+ | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
table_types:
ISAM_SYM { $$= DB_TYPE_ISAM; }
@@ -780,36 +853,40 @@ table_types:
| MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; }
| HEAP_SYM { $$= DB_TYPE_HEAP; }
| BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; }
- | INNOBASE_SYM { $$= DB_TYPE_INNOBASE; }
- | GEMINI_SYM { $$= DB_TYPE_GEMINI; }
+ | INNOBASE_SYM { $$= DB_TYPE_INNODB; };
row_types:
DEFAULT { $$= ROW_TYPE_DEFAULT; }
| FIXED_SYM { $$= ROW_TYPE_FIXED; }
| DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; }
- | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
+ | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; };
raid_types:
RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
| RAID_0_SYM { $$= RAID_TYPE_0; }
- | ULONG_NUM { $$=$1;}
+ | ULONG_NUM { $$=$1;};
+
+merge_insert_types:
+ NO_SYM { $$= MERGE_INSERT_DISABLED; }
+ | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; }
+ | LAST_SYM { $$= MERGE_INSERT_TO_LAST; };
opt_select_from:
/* empty */
- | select_from select_lock_type
+ | select_from select_lock_type;
udf_func_type:
/* empty */ { $$ = UDFTYPE_FUNCTION; }
- | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; }
+ | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; };
udf_type:
STRING_SYM {$$ = (int) STRING_RESULT; }
| REAL {$$ = (int) REAL_RESULT; }
- | INT_SYM {$$ = (int) INT_RESULT; }
+ | INT_SYM {$$ = (int) INT_RESULT; };
field_list:
field_list_item
- | field_list ',' field_list_item
+ | field_list ',' field_list_item;
field_list_item:
@@ -820,8 +897,9 @@ field_list_item:
}
| key_type opt_ident '(' key_list ')'
{
- Lex->key_list.push_back(new Key($1,$2,Lex->col_list));
- Lex->col_list.empty(); /* Alloced by sql_alloc */
+ LEX *lex=Lex;
+ lex->key_list.push_back(new Key($1,$2,lex->col_list));
+ lex->col_list.empty(); /* Alloced by sql_alloc */
}
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{
@@ -830,27 +908,29 @@ field_list_item:
| opt_constraint CHECK_SYM '(' expr ')'
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
- }
+ };
opt_constraint:
/* empty */
- | CONSTRAINT opt_ident
+ | CONSTRAINT opt_ident;
field_spec:
field_ident
{
- Lex->length=Lex->dec=0; Lex->type=0; Lex->interval=0;
- Lex->default_value=0;
+ LEX *lex=Lex;
+ lex->length=lex->dec=0; lex->type=0; lex->interval=0;
+ lex->default_value=0;
}
type opt_attribute
{
+ LEX *lex=Lex;
if (add_field_to_list($1.str,
(enum enum_field_types) $3,
- Lex->length,Lex->dec,Lex->type,
- Lex->default_value,Lex->change,
- Lex->interval))
+ lex->length,lex->dec,lex->type,
+ lex->default_value,lex->change,
+ lex->interval))
YYABORT;
- }
+ };
type:
int_type opt_len field_options { Lex->length=$2; $$=$1; }
@@ -900,72 +980,82 @@ type:
{ $$=FIELD_TYPE_DECIMAL;}
| ENUM {Lex->interval_list.empty();} '(' string_list ')'
{
- Lex->interval=typelib(Lex->interval_list);
+ LEX *lex=Lex;
+ lex->interval=typelib(lex->interval_list);
$$=FIELD_TYPE_ENUM;
}
| SET { Lex->interval_list.empty();} '(' string_list ')'
{
- Lex->interval=typelib(Lex->interval_list);
+ LEX *lex=Lex;
+ lex->interval=typelib(lex->interval_list);
$$=FIELD_TYPE_SET;
- }
+ };
char:
CHAR_SYM {}
| NCHAR_SYM {}
- | NATIONAL_SYM CHAR_SYM {}
+ | NATIONAL_SYM CHAR_SYM {};
varchar:
char VARYING {}
| VARCHAR {}
| NATIONAL_SYM VARCHAR {}
- | NCHAR_SYM VARCHAR {}
+ | NCHAR_SYM VARCHAR {};
int_type:
INT_SYM { $$=FIELD_TYPE_LONG; }
| TINYINT { $$=FIELD_TYPE_TINY; }
| SMALLINT { $$=FIELD_TYPE_SHORT; }
| MEDIUMINT { $$=FIELD_TYPE_INT24; }
- | BIGINT { $$=FIELD_TYPE_LONGLONG; }
+ | BIGINT { $$=FIELD_TYPE_LONGLONG; };
real_type:
REAL { $$= current_thd->sql_mode & MODE_REAL_AS_FLOAT ?
FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; }
| DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; }
- | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }
+ | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; };
float_options:
/* empty */ {}
| '(' NUM ')' { Lex->length=$2.str; }
- | '(' NUM ',' NUM ')' { Lex->length=$2.str; Lex->dec=$4.str; }
+ | precision {};
+
+precision:
+ '(' NUM ',' NUM ')'
+ {
+ LEX *lex=Lex;
+ lex->length=$2.str; lex->dec=$4.str;
+ };
field_options:
/* empty */ {}
- | field_opt_list {}
+ | field_opt_list {};
field_opt_list:
field_opt_list field_option {}
- | field_option {}
+ | field_option {};
field_option:
- UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
- | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
+ SIGNED_SYM {}
+ | UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
+ | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; };
opt_len:
/* empty */ { $$=(char*) 0; } /* use default length */
- | '(' NUM ')' { $$=$2.str; }
+ | '(' NUM ')' { $$=$2.str; };
opt_precision:
/* empty */ {}
- | '(' NUM ',' NUM ')' { Lex->length=$2.str; Lex->dec=$4.str; }
+ | precision {};
opt_attribute:
/* empty */ {}
- | opt_attribute_list {}
+ | opt_attribute_list {};
opt_attribute_list:
opt_attribute_list attribute {}
- | attribute
+ | attribute;
attribute:
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
@@ -975,39 +1065,40 @@ attribute:
| PRIMARY_SYM KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; }
| UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; }
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
+ | COMMENT_SYM text_literal {};
opt_binary:
/* empty */ {}
- | BINARY { Lex->type|=BINARY_FLAG; }
+ | BINARY { Lex->type|=BINARY_FLAG; };
references:
REFERENCES table_ident opt_on_delete {}
| REFERENCES table_ident '(' key_list ')' opt_on_delete
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
- }
+ };
opt_on_delete:
/* empty */ {}
- | opt_on_delete_list {}
+ | opt_on_delete_list {};
opt_on_delete_list:
opt_on_delete_list opt_on_delete_item {}
- | opt_on_delete_item {}
+ | opt_on_delete_item {};
opt_on_delete_item:
ON DELETE_SYM delete_option {}
| ON UPDATE_SYM delete_option {}
| MATCH FULL {}
- | MATCH PARTIAL {}
+ | MATCH PARTIAL {};
delete_option:
RESTRICT {}
| CASCADE {}
| SET NULL_SYM {}
| NO_SYM ACTION {}
- | SET DEFAULT {}
+ | SET DEFAULT {};
key_type:
opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; }
@@ -1015,36 +1106,37 @@ key_type:
| FULLTEXT_SYM { $$= Key::FULLTEXT; }
| FULLTEXT_SYM key_or_index { $$= Key::FULLTEXT; }
| opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; }
- | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; }
+ | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; };
key_or_index:
KEY_SYM {}
- | INDEX {}
+ | INDEX {};
keys_or_index:
KEYS {}
| INDEX {}
+ | INDEXES {};
opt_unique_or_fulltext:
/* empty */ { $$= Key::MULTIPLE; }
| UNIQUE_SYM { $$= Key::UNIQUE; }
- | FULLTEXT_SYM { $$= Key::FULLTEXT; }
+ | FULLTEXT_SYM { $$= Key::FULLTEXT; };
key_list:
key_list ',' key_part order_dir { Lex->col_list.push_back($3); }
- | key_part order_dir { Lex->col_list.push_back($1); }
+ | key_part order_dir { Lex->col_list.push_back($1); };
key_part:
ident { $$=new key_part_spec($1.str); }
- | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); }
+ | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); };
opt_ident:
/* empty */ { $$=(char*) 0; } /* Defaultlength */
- | field_ident { $$=$1.str; }
+ | field_ident { $$=$1.str; };
string_list:
text_string { Lex->interval_list.push_back($1); }
- | string_list ',' text_string { Lex->interval_list.push_back($3); }
+ | string_list ',' text_string { Lex->interval_list.push_back($3); };
/*
** Alter table
@@ -1064,93 +1156,143 @@ alter:
lex->col_list.empty();
lex->drop_list.empty();
lex->alter_list.empty();
- lex->order_list.elements=0;
- lex->order_list.first=0;
- lex->order_list.next= (byte**) &lex->order_list.first;
- lex->db=lex->name=0;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
+ lex->select->db=lex->name=0;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.db_type= DB_TYPE_DEFAULT;
+ lex->create_info.row_type= ROW_TYPE_NOT_USED;
+ lex->alter_keys_onoff=LEAVE_AS_IS;
+ lex->simple_alter=1;
}
- alter_list
+ alter_list;
alter_list:
| alter_list_item
- | alter_list ',' alter_list_item
+ | alter_list ',' alter_list_item;
add_column:
- ADD opt_column { Lex->change=0;}
+ ADD opt_column { Lex->change=0; };
alter_list_item:
- add_column field_list_item opt_place
- | add_column '(' field_list ')'
- | CHANGE opt_column field_ident { Lex->change= $3.str; } field_spec
+ add_column field_list_item opt_place { Lex->simple_alter=0; }
+ | add_column '(' field_list ')' { Lex->simple_alter=0; }
+ | CHANGE opt_column field_ident
+ {
+ LEX *lex=Lex;
+ lex->change= $3.str; lex->simple_alter=0;
+ }
+ field_spec opt_place
| MODIFY_SYM opt_column field_ident
{
- Lex->length=Lex->dec=0; Lex->type=0; Lex->interval=0;
- Lex->default_value=0;
+ LEX *lex=Lex;
+ lex->length=lex->dec=0; lex->type=0; lex->interval=0;
+ lex->default_value=0;
+ lex->simple_alter=0;
}
type opt_attribute
{
+ LEX *lex=Lex;
if (add_field_to_list($3.str,
(enum enum_field_types) $5,
- Lex->length,Lex->dec,Lex->type,
- Lex->default_value, $3.str,
- Lex->interval))
- YYABORT;
+ lex->length,lex->dec,lex->type,
+ lex->default_value, $3.str,
+ lex->interval))
+ YYABORT;
}
+ opt_place
| DROP opt_column field_ident opt_restrict
- { Lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
- $3.str)); }
- | DROP PRIMARY_SYM KEY_SYM { Lex->drop_primary=1; }
- | DROP FOREIGN KEY_SYM opt_ident {}
+ {
+ LEX *lex=Lex;
+ lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
+ $3.str)); lex->simple_alter=0;
+ }
+ | DROP PRIMARY_SYM KEY_SYM
+ {
+ LEX *lex=Lex;
+ lex->drop_primary=1; lex->simple_alter=0;
+ }
+ | DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; }
| DROP key_or_index field_ident
- { Lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
- $3.str)); }
+ {
+ LEX *lex=Lex;
+ lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
+ $3.str));
+ lex->simple_alter=0;
+ }
+ | DISABLE_SYM KEYS { Lex->alter_keys_onoff=DISABLE; }
+ | ENABLE_SYM KEYS { Lex->alter_keys_onoff=ENABLE; }
| ALTER opt_column field_ident SET DEFAULT literal
- { Lex->alter_list.push_back(new Alter_column($3.str,$6)); }
+ {
+ LEX *lex=Lex;
+ lex->alter_list.push_back(new Alter_column($3.str,$6));
+ lex->simple_alter=0;
+ }
| ALTER opt_column field_ident DROP DEFAULT
- { Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); }
- | RENAME opt_to table_alias table_ident
- { Lex->db=$4->db.str ; Lex->name= $4->table.str; }
- | create_table_options
- | order_clause
+ {
+ LEX *lex=Lex;
+ lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0));
+ lex->simple_alter=0;
+ }
+ | RENAME opt_to table_ident
+ {
+ LEX *lex=Lex;
+ lex->select->db=$3->db.str;
+ lex->name= $3->table.str;
+ }
+ | create_table_options { Lex->simple_alter=0; }
+ | order_clause { Lex->simple_alter=0; };
opt_column:
/* empty */ {}
- | COLUMN_SYM {}
+ | COLUMN_SYM {};
opt_ignore:
/* empty */ { Lex->duplicates=DUP_ERROR; }
- | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }
+ | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
opt_restrict:
/* empty */ {}
| RESTRICT {}
- | CASCADE {}
+ | CASCADE {};
opt_place:
/* empty */ {}
| AFTER_SYM ident { store_position_for_column($2.str); }
- | FIRST_SYM { store_position_for_column(first_keyword); }
+ | FIRST_SYM { store_position_for_column(first_keyword); };
opt_to:
/* empty */ {}
| TO_SYM {}
- | AS {}
+ | EQ {}
+ | AS {};
slave:
- SLAVE START_SYM
+ SLAVE START_SYM slave_thread_opts
{
- Lex->sql_command = SQLCOM_SLAVE_START;
- Lex->type = 0;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SLAVE_START;
+ lex->type = 0;
}
|
- SLAVE STOP_SYM
+ SLAVE STOP_SYM slave_thread_opts
{
- Lex->sql_command = SQLCOM_SLAVE_STOP;
- Lex->type = 0;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SLAVE_STOP;
+ lex->type = 0;
};
+slave_thread_opts:
+ slave_thread_opt
+ | slave_thread_opts ',' slave_thread_opt;
+
+slave_thread_opt:
+ /*empty*/ {}
+ | SQL_THREAD { Lex->slave_thd_opt|=SLAVE_SQL; }
+ | IO_THREAD { Lex->slave_thd_opt|=SLAVE_IO; }
+ ;
+
restore:
RESTORE_SYM table_or_tables
{
@@ -1159,7 +1301,8 @@ restore:
table_list FROM TEXT_STRING
{
Lex->backup_dir = $6.str;
- }
+ };
+
backup:
BACKUP_SYM table_or_tables
{
@@ -1168,75 +1311,89 @@ backup:
table_list TO_SYM TEXT_STRING
{
Lex->backup_dir = $6.str;
- }
-
+ };
repair:
REPAIR table_or_tables
{
- Lex->sql_command = SQLCOM_REPAIR;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_REPAIR;
+ lex->check_opt.init();
}
- table_list opt_mi_check_type
+ table_list opt_mi_repair_type;
-
-opt_mi_check_type:
+opt_mi_repair_type:
/* empty */ { Lex->check_opt.flags = T_MEDIUM; }
- | TYPE_SYM EQ mi_check_types {}
- | mi_check_types {}
+ | mi_repair_types {};
-mi_check_types:
- mi_check_type {}
- | mi_check_type mi_check_types {}
+mi_repair_types:
+ mi_repair_type {}
+ | mi_repair_type mi_repair_types {};
-mi_check_type:
- QUICK { Lex->check_opt.quick = 1; }
- | FAST_SYM { Lex->check_opt.flags|= T_FAST; }
- | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
+mi_repair_type:
+ QUICK { Lex->check_opt.flags|= T_QUICK; }
| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
- | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
+ | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; };
analyze:
ANALYZE_SYM table_or_tables
{
- Lex->sql_command = SQLCOM_ANALYZE;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_ANALYZE;
+ lex->check_opt.init();
}
- table_list opt_mi_check_type
+ table_list opt_mi_check_type;
check:
CHECK_SYM table_or_tables
{
- Lex->sql_command = SQLCOM_CHECK;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_CHECK;
+ lex->check_opt.init();
}
- table_list opt_mi_check_type
+ table_list opt_mi_check_type;
+
+opt_mi_check_type:
+ /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
+ | mi_check_types {};
+
+mi_check_types:
+ mi_check_type {}
+ | mi_check_type mi_check_types {};
+
+mi_check_type:
+ QUICK { Lex->check_opt.flags|= T_QUICK; }
+ | FAST_SYM { Lex->check_opt.flags|= T_FAST; }
+ | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
+ | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
+ | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; };
optimize:
OPTIMIZE table_or_tables
{
- Lex->sql_command = SQLCOM_OPTIMIZE;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_OPTIMIZE;
+ lex->check_opt.init();
}
- table_list opt_mi_check_type
+ table_list opt_mi_check_type;
rename:
RENAME table_or_tables
{
Lex->sql_command=SQLCOM_RENAME_TABLE;
}
- table_to_table_list
+ table_to_table_list;
table_to_table_list:
table_to_table
- | table_to_table_list ',' table_to_table
+ | table_to_table_list ',' table_to_table;
table_to_table:
table_ident TO_SYM table_ident
{ if (!add_table_to_list($1,NULL,1,TL_IGNORE) ||
!add_table_to_list($3,NULL,1,TL_IGNORE))
YYABORT;
- }
+ };
/*
Select : retrieve data from table
@@ -1244,48 +1401,87 @@ table_to_table:
select:
- SELECT_SYM
+ select_init { Lex->sql_command=SQLCOM_SELECT; };
+
+select_init:
+ SELECT_SYM select_part2 { Select->braces=false; } union
+ |
+ '(' SELECT_SYM select_part2 ')' { Select->braces=true;} union_opt;
+
+
+select_part2:
{
LEX *lex=Lex;
- lex->sql_command= SQLCOM_SELECT;
lex->lock_option=TL_READ;
- mysql_init_select(lex);
+ mysql_init_select(lex);
}
- select_options select_item_list select_into select_lock_type
+ select_options select_item_list select_into select_lock_type;
select_into:
- /* empty */
+ limit_clause {}
| select_from
| opt_into select_from
- | select_from opt_into
+ | select_from opt_into;
select_from:
- FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause
+ FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause;
select_options:
/* empty*/
- | select_option_list
+ | select_option_list;
select_option_list:
select_option_list select_option
- | select_option
+ | select_option;
select_option:
- STRAIGHT_JOIN { Lex->options|= SELECT_STRAIGHT_JOIN; }
- | HIGH_PRIORITY { Lex->lock_option= TL_READ_HIGH_PRIORITY; }
- | DISTINCT { Lex->options|= SELECT_DISTINCT; }
- | SQL_SMALL_RESULT { Lex->options|= SELECT_SMALL_RESULT; }
- | SQL_BIG_RESULT { Lex->options|= SELECT_BIG_RESULT; }
- | SQL_BUFFER_RESULT { Lex->options|= OPTION_BUFFER_RESULT; }
+ STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; }
+ | HIGH_PRIORITY
+ {
+ if (check_simple_select())
+ YYABORT;
+ Lex->lock_option= TL_READ_HIGH_PRIORITY;
+ }
+ | DISTINCT { Select->options|= SELECT_DISTINCT; }
+ | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
+ | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; }
+ | SQL_BUFFER_RESULT
+ {
+ if (check_simple_select())
+ YYABORT;
+ Select->options|= OPTION_BUFFER_RESULT;
+ }
+ | SQL_CALC_FOUND_ROWS
+ {
+ if (check_simple_select())
+ YYABORT;
+ Select->options|= OPTION_FOUND_ROWS;
+ }
+ | SQL_NO_CACHE_SYM { current_thd->safe_to_cache_query=0; }
+ | SQL_CACHE_SYM { Select->options|= OPTION_TO_QUERY_CACHE; }
| ALL {}
+ ;
select_lock_type:
/* empty */
| FOR_SYM UPDATE_SYM
- { Lex->lock_option= TL_WRITE; }
+ {
+ LEX *lex=Lex;
+ if (check_simple_select())
+ YYABORT;
+ lex->lock_option= TL_WRITE;
+ lex->thd->safe_to_cache_query=0;
+ }
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
- { Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; }
+ {
+ LEX *lex=Lex;
+ if (check_simple_select())
+ YYABORT;
+ lex->lock_option= TL_READ_WITH_SHARED_LOCKS;
+ lex->thd->safe_to_cache_query=0;
+ }
+ ;
select_item_list:
select_item_list ',' select_item
@@ -1294,7 +1490,7 @@ select_item_list:
{
if (add_item_to_list(new Item_field(NULL,NULL,"*")))
YYABORT;
- }
+ };
select_item:
@@ -1306,32 +1502,32 @@ select_item:
$2->set_name($4.str);
else if (!$2->name)
$2->set_name($1,(uint) ($3 - $1));
- }
+ };
remember_name:
- { $$=(char*) Lex->tok_start; }
+ { $$=(char*) Lex->tok_start; };
remember_end:
- { $$=(char*) Lex->tok_end; }
+ { $$=(char*) Lex->tok_end; };
select_item2:
table_wild { $$=$1; } /* table.* */
- | expr { $$=$1; }
+ | expr { $$=$1; };
select_alias:
{ $$.str=0;}
| AS ident { $$=$2; }
| AS TEXT_STRING { $$=$2; }
| ident { $$=$1; }
- | TEXT_STRING { $$=$1; }
+ | TEXT_STRING { $$=$1; };
optional_braces:
/* empty */ {}
- | '(' ')' {}
+ | '(' ')' {};
/* all possible expressions */
expr: expr_expr {$$ = $1; }
- | simple_expr {$$ = $1; }
+ | simple_expr {$$ = $1; };
/* expressions that begin with 'expr' */
expr_expr:
@@ -1345,6 +1541,7 @@ expr_expr:
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); }
| expr OR expr { $$= new Item_cond_or($1,$3); }
+ | expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr AND expr { $$= new Item_cond_and($1,$3); }
| expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
| expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5));}
@@ -1366,12 +1563,13 @@ expr_expr:
| expr '*' expr { $$= new Item_func_mul($1,$3); }
| expr '/' expr { $$= new Item_func_div($1,$3); }
| expr '|' expr { $$= new Item_func_bit_or($1,$3); }
+ | expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| expr '%' expr { $$= new Item_func_mod($1,$3); }
| expr '+' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,0); }
| expr '-' INTERVAL_SYM expr interval
- { $$= new Item_date_add_interval($1,$4,$5,1); }
+ { $$= new Item_date_add_interval($1,$4,$5,1); };
/* expressions that begin with 'expr' that do NOT follow IN_SYM */
no_in_expr:
@@ -1381,6 +1579,7 @@ no_in_expr:
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_in_expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); }
| no_in_expr OR expr { $$= new Item_cond_or($1,$3); }
+ | no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_in_expr AND expr { $$= new Item_cond_and($1,$3); }
| no_in_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
| no_in_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
@@ -1402,13 +1601,14 @@ no_in_expr:
| no_in_expr '*' expr { $$= new Item_func_mul($1,$3); }
| no_in_expr '/' expr { $$= new Item_func_div($1,$3); }
| no_in_expr '|' expr { $$= new Item_func_bit_or($1,$3); }
+ | no_in_expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| no_in_expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| no_in_expr '%' expr { $$= new Item_func_mod($1,$3); }
| no_in_expr '+' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,0); }
| no_in_expr '-' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,1); }
- | simple_expr
+ | simple_expr;
/* expressions that begin with 'expr' that does NOT follow AND */
no_and_expr:
@@ -1422,6 +1622,7 @@ no_and_expr:
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); }
| no_and_expr OR expr { $$= new Item_cond_or($1,$3); }
+ | no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_and_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
| no_and_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
| no_and_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
@@ -1442,20 +1643,33 @@ no_and_expr:
| no_and_expr '*' expr { $$= new Item_func_mul($1,$3); }
| no_and_expr '/' expr { $$= new Item_func_div($1,$3); }
| no_and_expr '|' expr { $$= new Item_func_bit_or($1,$3); }
+ | no_and_expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| no_and_expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| no_and_expr '%' expr { $$= new Item_func_mod($1,$3); }
| no_and_expr '+' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,0); }
| no_and_expr '-' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,1); }
- | simple_expr
+ | simple_expr;
simple_expr:
simple_ident
| literal
- | '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); }
- | '@' ident_or_text { $$= new Item_func_get_user_var($2); }
- | '@' '@' ident_or_text { if (!($$= get_system_var($3))) YYABORT; }
+ | '@' ident_or_text SET_VAR expr
+ {
+ $$= new Item_func_set_user_var($2,$4);
+ current_thd->safe_to_cache_query=0;
+ }
+ | '@' ident_or_text
+ {
+ $$= new Item_func_get_user_var($2);
+ current_thd->safe_to_cache_query=0;
+ }
+ | '@' '@' opt_var_ident_type ident_or_text
+ {
+ if (!($$= get_system_var((enum_var_type) $3, $4)))
+ YYABORT;
+ }
| sum_expr
| '-' expr %prec NEG { $$= new Item_func_neg($2); }
| '~' expr %prec NEG { $$= new Item_func_bit_neg($2); }
@@ -1463,15 +1677,17 @@ simple_expr:
| '!' expr %prec NEG { $$= new Item_func_not($2); }
| '(' expr ')' { $$= $2; }
| '{' ident expr '}' { $$= $3; }
- | MATCH '(' ident_list ')' AGAINST '(' expr ')'
- { Lex->ftfunc_list.push_back(
- (Item_func_match *)($$=new Item_func_match(*$3,$7))); }
- | MATCH ident_list AGAINST '(' expr ')'
- { Lex->ftfunc_list.push_back(
- (Item_func_match *)($$=new Item_func_match(*$2,$5))); }
+ | MATCH ident_list_arg AGAINST '(' expr ')'
+ { Select->ftfunc_list.push_back((Item_func_match *)
+ ($$=new Item_func_match_nl(*$2,$5))); }
+ | MATCH ident_list_arg AGAINST '(' expr IN_SYM BOOLEAN_SYM MODE_SYM ')'
+ { Select->ftfunc_list.push_back((Item_func_match *)
+ ($$=new Item_func_match_bool(*$2,$5))); }
| BINARY expr %prec NEG { $$= new Item_func_binary($2); }
+ | CAST_SYM '(' expr AS cast_type ')' { $$= create_func_cast($3, $5); }
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
{ $$= new Item_func_case(* $4, $2, $5 ); }
+ | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); }
| FUNC_ARG0 '(' ')'
{ $$= ((Item*(*)(void))($1.symbol->create_func))();}
| FUNC_ARG1 '(' expr ')'
@@ -1493,27 +1709,45 @@ simple_expr:
| CONCAT_WS '(' expr ',' expr_list ')'
{ $$= new Item_func_concat_ws($3, *$5); }
| CURDATE optional_braces
- { $$= new Item_func_curdate(); }
+ { $$= new Item_func_curdate(); current_thd->safe_to_cache_query=0; }
| CURTIME optional_braces
- { $$= new Item_func_curtime(); }
+ { $$= new Item_func_curtime(); current_thd->safe_to_cache_query=0; }
| CURTIME '(' expr ')'
- { $$= new Item_func_curtime($3); }
+ {
+ $$= new Item_func_curtime($3);
+ current_thd->safe_to_cache_query=0;
+ }
| DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
{ $$= new Item_date_add_interval($3,$6,$7,0); }
| DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
{ $$= new Item_date_add_interval($3,$6,$7,1); }
| DATABASE '(' ')'
- { $$= new Item_func_database(); }
+ {
+ $$= new Item_func_database();
+ current_thd->safe_to_cache_query=0;
+ }
| ELT_FUNC '(' expr ',' expr_list ')'
{ $$= new Item_func_elt($3, *$5); }
| MAKE_SET_SYM '(' expr ',' expr_list ')'
{ $$= new Item_func_make_set($3, *$5); }
- | ENCRYPT '(' expr ')' { $$= new Item_func_encrypt($3); }
+ | ENCRYPT '(' expr ')'
+ {
+ $$= new Item_func_encrypt($3);
+ current_thd->safe_to_cache_query=0;
+ }
| ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); }
| DECODE_SYM '(' expr ',' TEXT_STRING ')'
{ $$= new Item_func_decode($3,$5.str); }
| ENCODE_SYM '(' expr ',' TEXT_STRING ')'
{ $$= new Item_func_encode($3,$5.str); }
+ | DES_DECRYPT_SYM '(' expr ')'
+ { $$= new Item_func_des_decrypt($3); }
+ | DES_DECRYPT_SYM '(' expr ',' expr ')'
+ { $$= new Item_func_des_decrypt($3,$5); }
+ | DES_ENCRYPT_SYM '(' expr ')'
+ { $$= new Item_func_des_encrypt($3); }
+ | DES_ENCRYPT_SYM '(' expr ',' expr ')'
+ { $$= new Item_func_des_encrypt($3,$5); }
| EXPORT_SET '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_export_set($3, $5, $7); }
| EXPORT_SET '(' expr ',' expr ',' expr ',' expr ')'
@@ -1526,7 +1760,7 @@ simple_expr:
{ $$= new Item_func_from_unixtime($3); }
| FROM_UNIXTIME '(' expr ',' expr ')'
{
- $$= new Item_func_date_format(new Item_func_from_unixtime($3),$5,0);
+ $$= new Item_func_date_format (new Item_func_from_unixtime($3),$5,0);
}
| FIELD_FUNC '(' expr ',' expr_list ')'
{ $$= new Item_func_field($3, *$5); }
@@ -1545,10 +1779,12 @@ simple_expr:
{
$$= new Item_int((char*) "last_insert_id()",
current_thd->insert_id(),21);
+ current_thd->safe_to_cache_query=0;
}
| LAST_INSERT_ID '(' expr ')'
{
$$= new Item_func_set_last_insert_id($3);
+ current_thd->safe_to_cache_query=0;
}
| LEFT '(' expr ',' expr ')'
{ $$= new Item_func_left($3,$5); }
@@ -1565,14 +1801,19 @@ simple_expr:
| MONTH_SYM '(' expr ')'
{ $$= new Item_func_month($3); }
| NOW_SYM optional_braces
- { $$= new Item_func_now(); }
+ { $$= new Item_func_now(); current_thd->safe_to_cache_query=0;}
| NOW_SYM '(' expr ')'
- { $$= new Item_func_now($3); }
- | PASSWORD '(' expr ')' { $$= new Item_func_password($3); }
+ { $$= new Item_func_now($3); current_thd->safe_to_cache_query=0;}
+ | PASSWORD '(' expr ')'
+ {
+ $$= new Item_func_password($3);
+ }
| POSITION_SYM '(' no_in_expr IN_SYM expr ')'
{ $$ = new Item_func_locate($5,$3); }
- | RAND '(' expr ')' { $$= new Item_func_rand($3); }
- | RAND '(' ')' { $$= new Item_func_rand(); }
+ | RAND '(' expr ')'
+ { $$= new Item_func_rand($3); current_thd->safe_to_cache_query=0;}
+ | RAND '(' ')'
+ { $$= new Item_func_rand(); current_thd->safe_to_cache_query=0;}
| REPLACE '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_replace($3,$5,$7); }
| RIGHT '(' expr ',' expr ')'
@@ -1610,6 +1851,7 @@ simple_expr:
$$ = new Item_sum_udf_str($1, *$3);
else
$$ = new Item_sum_udf_str($1);
+ current_thd->safe_to_cache_query=0;
}
| UDA_FLOAT_SUM '(' udf_expr_list ')'
{
@@ -1617,6 +1859,7 @@ simple_expr:
$$ = new Item_sum_udf_float($1, *$3);
else
$$ = new Item_sum_udf_float($1);
+ current_thd->safe_to_cache_query=0;
}
| UDA_INT_SUM '(' udf_expr_list ')'
{
@@ -1631,6 +1874,7 @@ simple_expr:
$$ = new Item_func_udf_str($1, *$3);
else
$$ = new Item_func_udf_str($1);
+ current_thd->safe_to_cache_query=0;
}
| UDF_FLOAT_FUNC '(' udf_expr_list ')'
{
@@ -1638,6 +1882,7 @@ simple_expr:
$$ = new Item_func_udf_float($1, *$3);
else
$$ = new Item_func_udf_float($1);
+ current_thd->safe_to_cache_query=0;
}
| UDF_INT_FUNC '(' udf_expr_list ')'
{
@@ -1645,15 +1890,21 @@ simple_expr:
$$ = new Item_func_udf_int($1, *$3);
else
$$ = new Item_func_udf_int($1);
+ current_thd->safe_to_cache_query=0;
}
| UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
- { $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9); }
+ {
+ $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9);
+ }
| UNIX_TIMESTAMP '(' ')'
- { $$= new Item_func_unix_timestamp(); }
+ {
+ $$= new Item_func_unix_timestamp();
+ current_thd->safe_to_cache_query=0;
+ }
| UNIX_TIMESTAMP '(' expr ')'
{ $$= new Item_func_unix_timestamp($3); }
| USER '(' ')'
- { $$= new Item_func_user(); }
+ { $$= new Item_func_user(); current_thd->safe_to_cache_query=0; }
| WEEK_SYM '(' expr ')'
{ $$= new Item_func_week($3,new Item_int((char*) "0",0,1)); }
| WEEK_SYM '(' expr ',' expr ')'
@@ -1665,13 +1916,16 @@ simple_expr:
| YEARWEEK '(' expr ',' expr ')'
{ $$= new Item_func_yearweek($3, $5); }
| BENCHMARK_SYM '(' ULONG_NUM ',' expr ')'
- { $$=new Item_func_benchmark($3,$5); }
+ {
+ $$=new Item_func_benchmark($3,$5);
+ current_thd->safe_to_cache_query=0;
+ }
| EXTRACT_SYM '(' interval FROM expr ')'
- { $$=new Item_extract( $3, $5); }
+ { $$=new Item_extract( $3, $5); };
udf_expr_list:
/* empty */ { $$= NULL; }
- | expr_list { $$= $1;}
+ | expr_list { $$= $1;};
sum_expr:
AVG_SYM '(' in_sum_expr ')'
@@ -1695,62 +1949,78 @@ sum_expr:
| STD_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_std($3); }
| SUM_SYM '(' in_sum_expr ')'
- { $$=new Item_sum_sum($3); }
+ { $$=new Item_sum_sum($3); };
in_sum_expr:
- { Lex->in_sum_expr++; }
+ { Select->in_sum_expr++; }
expr
{
- Lex->in_sum_expr--;
+ Select->in_sum_expr--;
$$=$2;
- }
+ };
+
+cast_type:
+ BINARY { $$=ITEM_CAST_BINARY; }
+ | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; }
+ | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; }
+ | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; }
+ | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; }
+ | DATE_SYM { $$=ITEM_CAST_DATE; }
+ | TIME_SYM { $$=ITEM_CAST_TIME; }
+ | DATETIME { $$=ITEM_CAST_DATETIME; };
expr_list:
- { Lex->expr_list.push_front(new List<Item>); }
+ { Select->expr_list.push_front(new List<Item>); }
expr_list2
- { $$= Lex->expr_list.pop(); }
+ { $$= Select->expr_list.pop(); };
expr_list2:
- expr { Lex->expr_list.head()->push_back($1); }
- | expr_list2 ',' expr { Lex->expr_list.head()->push_back($3); }
+ expr { Select->expr_list.head()->push_back($1); }
+ | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); };
+
+ident_list_arg:
+ ident_list { $$= $1; }
+ | '(' ident_list ')' { $$= $2; };
ident_list:
- { Lex->expr_list.push_front(new List<Item>); }
+ { Select->expr_list.push_front(new List<Item>); }
ident_list2
- { $$= Lex->expr_list.pop(); }
+ { $$= Select->expr_list.pop(); };
ident_list2:
- simple_ident { Lex->expr_list.head()->push_back($1); }
- | ident_list2 ',' simple_ident { Lex->expr_list.head()->push_back($3); }
+ simple_ident { Select->expr_list.head()->push_back($1); }
+ | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); };
opt_expr:
/* empty */ { $$= NULL; }
- | expr { $$= $1; }
+ | expr { $$= $1; };
opt_else:
/* empty */ { $$= NULL; }
- | ELSE expr { $$= $2; }
+ | ELSE expr { $$= $2; };
when_list:
- { Lex->when_list.push_front(new List<Item>); }
+ { Select->when_list.push_front(new List<Item>); }
when_list2
- { $$= Lex->when_list.pop(); }
+ { $$= Select->when_list.pop(); };
when_list2:
expr THEN_SYM expr
{
- Lex->when_list.head()->push_back($1);
- Lex->when_list.head()->push_back($3);
+ SELECT_LEX *sel=Select;
+ sel->when_list.head()->push_back($1);
+ sel->when_list.head()->push_back($3);
}
| when_list2 WHEN_SYM expr THEN_SYM expr
{
- Lex->when_list.head()->push_back($3);
- Lex->when_list.head()->push_back($5);
- }
+ SELECT_LEX *sel=Select;
+ sel->when_list.head()->push_back($3);
+ sel->when_list.head()->push_back($5);
+ };
opt_pad:
/* empty */ { $$=new Item_string(" ",1); }
- | expr { $$=$1; }
+ | expr { $$=$1; };
join_table_list:
'(' join_table_list ')' { $$=$2; }
@@ -1760,15 +2030,21 @@ join_table_list:
| join_table_list INNER_SYM JOIN_SYM join_table ON expr
{ add_join_on($4,$6); $$=$4; }
| join_table_list INNER_SYM JOIN_SYM join_table
- { Lex->db1=$1->db; Lex->table1=$1->name;
- Lex->db2=$4->db; Lex->table2=$4->name; }
+ {
+ SELECT_LEX *sel=Select;
+ sel->db1=$1->db; sel->table1=$1->name;
+ sel->db2=$4->db; sel->table2=$4->name;
+ }
USING '(' using_list ')'
{ add_join_on($4,$8); $$=$4; }
| join_table_list LEFT opt_outer JOIN_SYM join_table ON expr
{ add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| join_table_list LEFT opt_outer JOIN_SYM join_table
- { Lex->db1=$1->db; Lex->table1=$1->name;
- Lex->db2=$5->db; Lex->table2=$5->name; }
+ {
+ SELECT_LEX *sel=Select;
+ sel->db1=$1->db; sel->table1=$1->name;
+ sel->db2=$5->db; sel->table2=$5->name;
+ }
USING '(' using_list ')'
{ add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table
@@ -1776,61 +2052,82 @@ join_table_list:
| join_table_list RIGHT opt_outer JOIN_SYM join_table ON expr
{ add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
| join_table_list RIGHT opt_outer JOIN_SYM join_table
- { Lex->db1=$1->db; Lex->table1=$1->name;
- Lex->db2=$5->db; Lex->table2=$5->name; }
+ {
+ SELECT_LEX *sel=Select;
+ sel->db1=$1->db; sel->table1=$1->name;
+ sel->db2=$5->db; sel->table2=$5->name;
+ }
USING '(' using_list ')'
{ add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
| join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table
{ add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
| join_table_list NATURAL JOIN_SYM join_table
- { add_join_natural($1,$4); $$=$4; }
+ { add_join_natural($1,$4); $$=$4; };
normal_join:
',' {}
| JOIN_SYM {}
- | CROSS JOIN_SYM {}
+ | CROSS JOIN_SYM {};
join_table:
- { Lex->use_index_ptr=Lex->ignore_index_ptr=0; }
+ {
+ SELECT_LEX *sel=Select;
+ sel->use_index_ptr=sel->ignore_index_ptr=0;
+ }
table_ident opt_table_alias opt_key_definition
- { if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, Lex->use_index_ptr,
- Lex->ignore_index_ptr))) YYABORT; }
+ {
+ SELECT_LEX *sel=Select;
+ if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, sel->use_index_ptr,
+ sel->ignore_index_ptr)))
+ YYABORT;
+ }
| '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}'
- { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
+ { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; };
opt_outer:
/* empty */ {}
- | OUTER {}
+ | OUTER {};
opt_key_definition:
/* empty */ {}
| USE_SYM key_usage_list
- { Lex->use_index= *$2; Lex->use_index_ptr= &Lex->use_index; }
+ {
+ SELECT_LEX *sel=Select;
+ sel->use_index= *$2;
+ sel->use_index_ptr= &sel->use_index;
+ }
| IGNORE_SYM key_usage_list
- { Lex->ignore_index= *$2; Lex->ignore_index_ptr= &Lex->ignore_index;}
+ {
+ SELECT_LEX *sel=Select;
+ sel->ignore_index= *$2;
+ sel->ignore_index_ptr= &sel->ignore_index;
+ };
key_usage_list:
- key_or_index { Lex->interval_list.empty(); } '(' key_usage_list2 ')'
- { $$= &Lex->interval_list; }
+ key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')'
+ { $$= &Select->interval_list; };
key_usage_list2:
key_usage_list2 ',' ident
- { Lex->interval_list.push_back(new String((const char*) $3.str,$3.length)); }
+ { Select->interval_list.push_back(new String((const char*) $3.str,$3.length)); }
| ident
- { Lex->interval_list.push_back(new String((const char*) $1.str,$1.length)); }
+ { Select->interval_list.push_back(new String((const char*) $1.str,$1.length)); }
| PRIMARY_SYM
- { Lex->interval_list.push_back(new String("PRIMARY",7)); }
+ { Select->interval_list.push_back(new String("PRIMARY",7)); };
using_list:
ident
- { if (!($$= new Item_func_eq(new Item_field(Lex->db1,Lex->table1, $1.str), new Item_field(Lex->db2,Lex->table2,$1.str))))
+ {
+ SELECT_LEX *sel=Select;
+ if (!($$= new Item_func_eq(new Item_field(sel->db1,sel->table1, $1.str), new Item_field(sel->db2,sel->table2,$1.str))))
YYABORT;
}
| using_list ',' ident
{
- if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(Lex->db1,Lex->table1,$3.str), new Item_field(Lex->db2,Lex->table2,$3.str)), $1)))
+ SELECT_LEX *sel=Select;
+ if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1)))
YYABORT;
- }
+ };
interval:
DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; }
@@ -1845,31 +2142,34 @@ interval:
| MONTH_SYM { $$=INTERVAL_MONTH; }
| SECOND_SYM { $$=INTERVAL_SECOND; }
| YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; }
- | YEAR_SYM { $$=INTERVAL_YEAR; }
+ | YEAR_SYM { $$=INTERVAL_YEAR; };
table_alias:
/* empty */
| AS
- | EQ
+ | EQ;
opt_table_alias:
/* empty */ { $$=0; }
| table_alias ident
- { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); }
+ { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); };
where_clause:
- /* empty */ { Lex->where= 0; }
- | WHERE expr { Lex->where= $2; }
+ /* empty */ { Select->where= 0; }
+ | WHERE expr { Select->where= $2; };
having_clause:
/* empty */
- | HAVING { Lex->create_refs=1; } expr
- { Lex->having= $3; Lex->create_refs=0; }
+ | HAVING { Select->create_refs=1; } expr
+ {
+ SELECT_LEX *sel=Select;
+ sel->having= $3; sel->create_refs=0;
+ };
opt_escape:
ESCAPE_SYM TEXT_STRING { $$= $2.str; }
- | /* empty */ { $$= (char*) "\\"; }
+ | /* empty */ { $$= (char*) "\\"; };
/*
@@ -1878,13 +2178,33 @@ opt_escape:
group_clause:
/* empty */
- | GROUP BY group_list
+ | GROUP BY group_list olap_opt;
group_list:
group_list ',' order_ident order_dir
{ if (add_group_to_list($3,(bool) $4)) YYABORT; }
| order_ident order_dir
- { if (add_group_to_list($1,(bool) $2)) YYABORT; }
+ { if (add_group_to_list($1,(bool) $2)) YYABORT; };
+
+olap_opt:
+ /* empty */ {}
+ | WITH CUBE_SYM
+ {
+ LEX *lex=Lex;
+ lex->olap = true;
+ lex->select->olap= CUBE_TYPE;
+ net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "CUBE");
+ YYABORT; /* To be deleted in 4.1 */
+ }
+ | WITH ROLLUP_SYM
+ {
+ LEX *lex=Lex;
+ lex->olap = true;
+ lex->select->olap= ROLLUP_TYPE;
+ net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "ROLLUP");
+ YYABORT; /* To be deleted in 4.1 */
+ }
+ ;
/*
Order by statement in select
@@ -1892,52 +2212,94 @@ group_list:
opt_order_clause:
/* empty */
- | order_clause
+ | order_clause;
order_clause:
- ORDER_SYM BY order_list
+ ORDER_SYM BY
+ {
+ LEX *lex=Lex;
+ if (lex->sql_command == SQLCOM_MULTI_UPDATE)
+ {
+ net_printf(&lex->thd->net, ER_WRONG_USAGE, "UPDATE", "ORDER BY");
+ YYABORT;
+ }
+ if (lex->select->olap != UNSPECIFIED_OLAP_TYPE)
+ {
+ net_printf(&lex->thd->net, ER_WRONG_USAGE,
+ "CUBE/ROLLUP",
+ "ORDER BY");
+ YYABORT;
+ }
+ lex->select->sort_default=1;
+ } order_list;
order_list:
order_list ',' order_ident order_dir
{ if (add_order_to_list($3,(bool) $4)) YYABORT; }
| order_ident order_dir
- { if (add_order_to_list($1,(bool) $2)) YYABORT; }
+ { if (add_order_to_list($1,(bool) $2)) YYABORT; };
order_dir:
/* empty */ { $$ = 1; }
| ASC { $$ =1; }
- | DESC { $$ =0; }
+ | DESC { $$ =0; };
limit_clause:
- /* empty */
- {
- Lex->select_limit= current_thd->default_select_limit;
- Lex->offset_limit= 0L;
- }
+ /* empty */ {}
| LIMIT ULONG_NUM
- { Lex->select_limit= $2; Lex->offset_limit=0L; }
+ {
+ LEX *lex=Lex;
+ if (lex->select->olap != UNSPECIFIED_OLAP_TYPE)
+ {
+ net_printf(&lex->thd->net, ER_WRONG_USAGE, "CUBE/ROLLUP",
+ "LIMIT");
+ YYABORT;
+ }
+ SELECT_LEX *sel=Select;
+ sel->select_limit= $2;
+ sel->offset_limit= 0L;
+ }
| LIMIT ULONG_NUM ',' ULONG_NUM
- { Lex->select_limit= $4; Lex->offset_limit=$2; }
+ {
+ LEX *lex=Lex;
+ if (lex->select->olap != UNSPECIFIED_OLAP_TYPE)
+ {
+ net_printf(&lex->thd->net, ER_WRONG_USAGE, "CUBE/ROLLUP",
+ "LIMIT");
+ YYABORT;
+ }
+ SELECT_LEX *sel=lex->select;
+ sel->select_limit= $4;
+ sel->offset_limit= $2;
+ };
delete_limit_clause:
/* empty */
{
- Lex->select_limit= HA_POS_ERROR;
+ LEX *lex=Lex;
+ if (lex->sql_command == SQLCOM_MULTI_UPDATE)
+ {
+ net_printf(&lex->thd->net, ER_WRONG_USAGE, "DELETE", "LIMIT");
+ YYABORT;
+ }
+ lex->select->select_limit= HA_POS_ERROR;
}
- | LIMIT ULONGLONG_NUM
- { Lex->select_limit= (ha_rows) $2; }
+ | LIMIT ulonglong_num
+ { Select->select_limit= (ha_rows) $2; };
ULONG_NUM:
- NUM { $$= strtoul($1.str,NULL,10); }
- | REAL_NUM { $$= strtoul($1.str,NULL,10); }
- | FLOAT_NUM { $$= strtoul($1.str,NULL,10); }
-
-ULONGLONG_NUM:
- NUM { $$= (ulonglong) strtoul($1.str,NULL,10); }
- | LONG_NUM { $$= strtoull($1.str,NULL,10); }
- | REAL_NUM { $$= strtoull($1.str,NULL,10); }
- | FLOAT_NUM { $$= strtoull($1.str,NULL,10); }
+ NUM { $$= strtoul($1.str,NULL,10); }
+ | ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); }
+ | REAL_NUM { $$= strtoul($1.str,NULL,10); }
+ | FLOAT_NUM { $$= strtoul($1.str,NULL,10); };
+
+ulonglong_num:
+ NUM { $$= (ulonglong) strtoul($1.str,NULL,10); }
+ | ULONGLONG_NUM { $$= strtoull($1.str,NULL,10); }
+ | LONG_NUM { $$= (ulonglong) strtoul($1.str,NULL,10); }
+ | REAL_NUM { $$= strtoull($1.str,NULL,10); }
+ | FLOAT_NUM { $$= strtoull($1.str,NULL,10); };
procedure_clause:
/* empty */
@@ -1949,17 +2311,18 @@ procedure_clause:
lex->proc_list.next= (byte**) &lex->proc_list.first;
if (add_proc_to_list(new Item_field(NULL,NULL,$2.str)))
YYABORT;
+ current_thd->safe_to_cache_query=0;
}
- '(' procedure_list ')'
+ '(' procedure_list ')';
procedure_list:
/* empty */ {}
- | procedure_list2 {}
+ | procedure_list2 {};
procedure_list2:
procedure_list2 ',' procedure_item
- | procedure_item
+ | procedure_item;
procedure_item:
remember_name expr
@@ -1968,7 +2331,7 @@ procedure_item:
YYABORT;
if (!$2->name)
$2->set_name($1,(uint) ((char*) Lex->tok_end - $1));
- }
+ };
opt_into:
INTO OUTFILE TEXT_STRING
@@ -1981,7 +2344,7 @@ opt_into:
{
if (!(Lex->exchange= new sql_exchange($3.str,1)))
YYABORT;
- }
+ };
/*
DO statement
@@ -1994,7 +2357,7 @@ do: DO_SYM
if (!(lex->insert_list = new List_item))
YYABORT;
}
- values
+ values;
/*
Drop : delete tables or index
*/
@@ -2002,93 +2365,105 @@ do: DO_SYM
drop:
DROP TABLE_SYM if_exists table_list opt_restrict
{
- Lex->sql_command = SQLCOM_DROP_TABLE;
- Lex->drop_if_exists = $3;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_DROP_TABLE;
+ lex->drop_if_exists = $3;
}
| DROP INDEX ident ON table_ident {}
{
- Lex->sql_command= SQLCOM_DROP_INDEX;
- Lex->drop_list.empty();
- Lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_DROP_INDEX;
+ lex->drop_list.empty();
+ lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
$3.str));
if (!add_table_to_list($5,NULL, 1))
YYABORT;
}
| DROP DATABASE if_exists ident
{
- Lex->sql_command= SQLCOM_DROP_DB;
- Lex->drop_if_exists=$3;
- Lex->name=$4.str;
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_DROP_DB;
+ lex->drop_if_exists=$3;
+ lex->name=$4.str;
}
| DROP UDF_SYM ident
{
- Lex->sql_command = SQLCOM_DROP_FUNCTION;
- Lex->udf.name=$3.str;
- }
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_DROP_FUNCTION;
+ lex->udf.name=$3.str;
+ };
table_list:
- table
- | table_list ',' table
+ table_name
+ | table_list ',' table_name;
-table:
+table_name:
table_ident
- { if (!add_table_to_list($1,NULL,1)) YYABORT; }
+ { if (!add_table_to_list($1,NULL,1)) YYABORT; };
if_exists:
/* empty */ { $$=0; }
- | IF EXISTS { $$= 1; }
+ | IF EXISTS { $$= 1; };
/*
** Insert : add new data to table
*/
insert:
- INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec
+ INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec;
replace:
- REPLACE { Lex->sql_command = SQLCOM_REPLACE; } replace_lock_option insert2 insert_field_spec
+ REPLACE
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_REPLACE;
+ lex->duplicates= DUP_REPLACE;
+ }
+ replace_lock_option insert2 insert_field_spec;
insert_lock_option:
/* empty */ { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
| DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; }
- | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; }
+ | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; };
replace_lock_option:
opt_low_priority {}
- | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; }
+ | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; };
insert2:
INTO insert_table {}
- | insert_table {}
+ | insert_table {};
insert_table:
- table
+ table_name
{
- Lex->field_list.empty();
- Lex->many_values.empty();
- Lex->insert_list=0;
- }
+ LEX *lex=Lex;
+ lex->field_list.empty();
+ lex->many_values.empty();
+ lex->insert_list=0;
+ };
insert_field_spec:
opt_field_spec insert_values {}
| SET
{
- if (!(Lex->insert_list = new List_item) ||
- Lex->many_values.push_back(Lex->insert_list))
+ LEX *lex=Lex;
+ if (!(lex->insert_list = new List_item) ||
+ lex->many_values.push_back(lex->insert_list))
YYABORT;
}
- ident_eq_list
+ ident_eq_list;
opt_field_spec:
/* empty */ { }
| '(' fields ')' { }
- | '(' ')' { }
+ | '(' ')' { };
fields:
fields ',' insert_ident { Lex->field_list.push_back($3); }
- | insert_ident { Lex->field_list.push_back($1); }
+ | insert_ident { Lex->field_list.push_back($1); };
insert_values:
VALUES values_list {}
@@ -2100,27 +2475,35 @@ insert_values:
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
mysql_init_select(lex);
}
- select_options select_item_list select_from select_lock_type {}
+ select_options select_item_list select_from select_lock_type
+ union {};
values_list:
values_list ',' no_braces
- | no_braces
+ | no_braces;
ident_eq_list:
ident_eq_list ',' ident_eq_value
|
- ident_eq_value
+ ident_eq_value;
ident_eq_value:
- simple_ident equal expr
+ simple_ident equal expr_or_default
{
- if (Lex->field_list.push_back($1) ||
- Lex->insert_list->push_back($3))
+ LEX *lex=Lex;
+ if (lex->field_list.push_back($1) ||
+ lex->insert_list->push_back($3))
YYABORT;
- }
+ };
equal: EQ {}
| SET_VAR {}
+ ;
+
+opt_equal:
+ /* empty */ {}
+ | equal {}
+ ;
no_braces:
'('
@@ -2130,31 +2513,45 @@ no_braces:
}
opt_values ')'
{
- if (Lex->many_values.push_back(Lex->insert_list))
+ LEX *lex=Lex;
+ if (lex->many_values.push_back(lex->insert_list))
YYABORT;
- }
+ };
opt_values:
/* empty */ {}
- | values
+ | values;
values:
- values ',' expr
+ values ',' expr_or_default
{
if (Lex->insert_list->push_back($3))
YYABORT;
}
- | expr
- {
- if (Lex->insert_list->push_back($1))
- YYABORT;
- }
+ | expr_or_default
+ {
+ if (Lex->insert_list->push_back($1))
+ YYABORT;
+ }
+ ;
+
+expr_or_default:
+ expr { $$= $1;}
+ | DEFAULT {$$= new Item_default(); }
+ ;
/* Update rows in a table */
update:
- UPDATE_SYM opt_low_priority opt_ignore table SET update_list where_clause delete_limit_clause
- { Lex->sql_command = SQLCOM_UPDATE; }
+ UPDATE_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_UPDATE;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
+ }
+ opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause;
update_list:
update_list ',' simple_ident equal expr
@@ -2166,61 +2563,107 @@ update_list:
{
if (add_item_to_list($1) || add_value_to_list($3))
YYABORT;
- }
+ };
opt_low_priority:
/* empty */ { Lex->lock_option= current_thd->update_lock_default; }
- | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
+ | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; };
/* Delete rows from a table */
delete:
DELETE_SYM
- {
- Lex->sql_command= SQLCOM_DELETE; Lex->options=0;
- Lex->lock_option= current_thd->update_lock_default;
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_DELETE; lex->select->options=0;
+ lex->lock_option= lex->thd->update_lock_default;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
}
- opt_delete_options FROM table
- where_clause delete_limit_clause
+ opt_delete_options single_multi {};
+
+single_multi:
+ FROM table_name where_clause opt_order_clause delete_limit_clause {}
+ | table_wild_list
+ { mysql_init_multi_delete(Lex); }
+ FROM join_table_list where_clause
+ | FROM table_wild_list
+ { mysql_init_multi_delete(Lex); }
+ USING join_table_list where_clause;
+
+table_wild_list:
+ table_wild_one {}
+ | table_wild_list ',' table_wild_one {};
+
+table_wild_one:
+ ident opt_wild
+ {
+ if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE))
+ YYABORT;
+ }
+ | ident '.' ident opt_wild
+ {
+ if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE))
+ YYABORT;
+ };
+
+opt_wild:
+ /* empty */ {}
+ | '.' '*' {};
opt_delete_options:
- /* empty */ {}
- | opt_delete_option opt_delete_options {}
+ /* empty */ {}
+ | opt_delete_option opt_delete_options {};
opt_delete_option:
- QUICK { Lex->options|= OPTION_QUICK; }
- | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
+ QUICK { Select->options|= OPTION_QUICK; }
+ | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; };
truncate:
- TRUNCATE_SYM opt_table_sym table
- { Lex->sql_command= SQLCOM_TRUNCATE; Lex->options=0;
- Lex->lock_option= current_thd->update_lock_default; }
+ TRUNCATE_SYM opt_table_sym table_name
+ {
+ LEX* lex = Lex;
+ lex->sql_command= SQLCOM_TRUNCATE;
+ lex->select->options=0;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
+ lex->lock_option= current_thd->update_lock_default; };
opt_table_sym:
/* empty */
- | TABLE_SYM
-
+ | TABLE_SYM;
+
/* Show things */
-show: SHOW { Lex->wild=0;} show_param
+show: SHOW { Lex->wild=0;} show_param;
show_param:
DATABASES wild
{ Lex->sql_command= SQLCOM_SHOW_DATABASES; }
| TABLES opt_db wild
- { Lex->sql_command= SQLCOM_SHOW_TABLES; Lex->db= $2; Lex->options=0;}
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_TABLES;
+ lex->select->db= $2; lex->select->options=0;
+ }
| TABLE_SYM STATUS_SYM opt_db wild
- { Lex->sql_command= SQLCOM_SHOW_TABLES;
- Lex->options|= SELECT_DESCRIBE;
- Lex->db= $3;
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_TABLES;
+ lex->select->options|= SELECT_DESCRIBE;
+ lex->select->db= $3;
}
| OPEN_SYM TABLES opt_db wild
- { Lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- Lex->db= $3;
- Lex->options=0;
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
+ lex->select->db= $3;
+ lex->select->options=0;
}
- | opt_full COLUMNS FROM table_ident opt_db wild
+ | opt_full COLUMNS from_or_in table_ident opt_db wild
{
Lex->sql_command= SQLCOM_SHOW_FIELDS;
if ($5)
@@ -2228,10 +2671,31 @@ show_param:
if (!add_table_to_list($4,NULL,0))
YYABORT;
}
+ | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
+ TEXT_STRING AND MASTER_LOG_POS_SYM EQ ulonglong_num
+ AND MASTER_SERVER_ID_SYM EQ
+ ULONG_NUM
+ {
+ Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
+ Lex->mi.log_file_name = $8.str;
+ Lex->mi.pos = $12;
+ Lex->mi.server_id = $16;
+ }
| MASTER_SYM LOGS_SYM
{
Lex->sql_command = SQLCOM_SHOW_BINLOGS;
- }
+ }
+ | SLAVE HOSTS_SYM
+ {
+ Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS;
+ }
+ | BINLOG_SYM EVENTS_SYM binlog_in binlog_from
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SHOW_BINLOG_EVENTS;
+ lex->select->select_limit= lex->thd->variables.select_limit;
+ lex->select->offset_limit= 0L;
+ } limit_clause
| keys_or_index FROM table_ident opt_db
{
Lex->sql_command= SQLCOM_SHOW_KEYS;
@@ -2246,13 +2710,21 @@ show_param:
{ Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS;}
| opt_full PROCESSLIST_SYM
{ Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
- | VARIABLES wild
- { Lex->sql_command= SQLCOM_SHOW_VARIABLES; }
+ | opt_var_type VARIABLES wild
+ {
+ THD *thd= current_thd;
+ thd->lex.sql_command= SQLCOM_SHOW_VARIABLES;
+ thd->lex.option_type= (enum_var_type) $1;
+ }
| LOGS_SYM
{ Lex->sql_command= SQLCOM_SHOW_LOGS; }
| GRANTS FOR_SYM user
- { Lex->sql_command= SQLCOM_SHOW_GRANTS;
- Lex->grant_user=$3; Lex->grant_user->password.str=NullS; }
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_GRANTS;
+ lex->grant_user=$3;
+ lex->grant_user->password.str=NullS;
+ }
| CREATE TABLE_SYM table_ident
{
Lex->sql_command = SQLCOM_SHOW_CREATE;
@@ -2266,114 +2738,151 @@ show_param:
| SLAVE STATUS_SYM
{
Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
- }
+ };
opt_db:
/* empty */ { $$= 0; }
- | FROM ident { $$= $2.str; }
+ | from_or_in ident { $$= $2.str; };
wild:
/* empty */
- | LIKE text_string { Lex->wild= $2; }
+ | LIKE text_string { Lex->wild= $2; };
opt_full:
/* empty */ { Lex->verbose=0; }
- | FULL { Lex->verbose=1; }
+ | FULL { Lex->verbose=1; };
+
+from_or_in:
+ FROM
+ | IN_SYM;
+
+binlog_in:
+ /* empty */ { Lex->mi.log_file_name = 0; }
+ | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; };
+
+binlog_from:
+ /* empty */ { Lex->mi.pos = 4; /* skip magic number */ }
+ | FROM ulonglong_num { Lex->mi.pos = $2; };
+
/* A Oracle compatible synonym for show */
describe:
describe_command table_ident
{
- Lex->wild=0;
- Lex->verbose=0;
- Lex->sql_command=SQLCOM_SHOW_FIELDS;
+ LEX *lex=Lex;
+ lex->wild=0;
+ lex->verbose=0;
+ lex->sql_command=SQLCOM_SHOW_FIELDS;
if (!add_table_to_list($2, NULL,0))
YYABORT;
}
opt_describe_column
- | describe_command select { Lex->options|= SELECT_DESCRIBE; };
+ | describe_command select
+ { Lex->select_lex.options|= SELECT_DESCRIBE; };
describe_command:
DESC
- | DESCRIBE
+ | DESCRIBE;
opt_describe_column:
/* empty */ {}
| text_string { Lex->wild= $1; }
- | ident { Lex->wild= new String((const char*) $1.str,$1.length); }
+ | ident
+ { Lex->wild= new String((const char*) $1.str,$1.length); };
/* flush things */
flush:
- FLUSH_SYM {Lex->sql_command= SQLCOM_FLUSH; Lex->type=0; } flush_options
+ FLUSH_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_FLUSH; lex->type=0;
+ }
+ flush_options;
flush_options:
flush_options ',' flush_option
- | flush_option
+ | flush_option;
flush_option:
table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list
| TABLES WITH READ_SYM LOCK_SYM { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK; }
+ | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE_FREE; }
| HOSTS_SYM { Lex->type|= REFRESH_HOSTS; }
| PRIVILEGES { Lex->type|= REFRESH_GRANT; }
| LOGS_SYM { Lex->type|= REFRESH_LOG; }
| STATUS_SYM { Lex->type|= REFRESH_STATUS; }
| SLAVE { Lex->type|= REFRESH_SLAVE; }
| MASTER_SYM { Lex->type|= REFRESH_MASTER; }
+ | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }
+ | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; };
opt_table_list:
- /* empty */ {}
- | table_list {}
+ /* empty */ {;}
+ | table_list {;};
reset:
- RESET_SYM {Lex->sql_command= SQLCOM_RESET; Lex->type=0; } reset_options
-
+ RESET_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_RESET; lex->type=0;
+ } reset_options;
reset_options:
reset_options ',' reset_option
- | reset_option
+ | reset_option;
reset_option:
- SLAVE { Lex->type|= REFRESH_SLAVE; }
- | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
+ SLAVE { Lex->type|= REFRESH_SLAVE; }
+ | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
+ | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;};
purge:
- PURGE { Lex->sql_command = SQLCOM_PURGE; Lex->type=0;}
+ PURGE
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_PURGE;
+ lex->type=0;
+ }
MASTER_SYM LOGS_SYM TO_SYM TEXT_STRING
{
Lex->to_log = $6.str;
- }
+ } ;
/* kill threads */
kill:
KILL_SYM expr
{
- if ($2->fix_fields(current_thd,0))
- {
- send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
- YYABORT;
- }
- Lex->sql_command=SQLCOM_KILL;
- Lex->thread_id= (ulong) $2->val_int();
- }
+ LEX *lex=Lex;
+ if ($2->fix_fields(lex->thd,0))
+ {
+ send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY);
+ YYABORT;
+ }
+ lex->sql_command=SQLCOM_KILL;
+ lex->thread_id= (ulong) $2->val_int();
+ };
/* change database */
use: USE_SYM ident
- { Lex->sql_command=SQLCOM_CHANGE_DB; Lex->db= $2.str; }
+ {
+ LEX *lex=Lex;
+ lex->sql_command=SQLCOM_CHANGE_DB; lex->select->db= $2.str;
+ };
/* import, export of files */
load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
{
- LEX *lex= Lex;
+ LEX *lex=Lex;
lex->sql_command= SQLCOM_LOAD;
lex->local_file= $4;
- if (!(Lex->exchange= new sql_exchange($6.str,0)))
+ if (!(lex->exchange= new sql_exchange($6.str,0)))
YYABORT;
- Lex->field_list.empty();
+ lex->field_list.empty();
}
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
opt_ignore_lines opt_field_spec
@@ -2389,60 +2898,69 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
YYABORT;
}
+ |
+ LOAD DATA_SYM FROM MASTER_SYM
+ {
+ Lex->sql_command = SQLCOM_LOAD_MASTER_DATA;
+ };
opt_local:
/* empty */ { $$=0;}
- | LOCAL_SYM { $$=1;}
+ | LOCAL_SYM { $$=1;};
load_data_lock:
/* empty */ { Lex->lock_option= current_thd->update_lock_default; }
| CONCURRENT { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT ; }
- | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
+ | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; };
opt_duplicate:
/* empty */ { Lex->duplicates=DUP_ERROR; }
| REPLACE { Lex->duplicates=DUP_REPLACE; }
- | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }
+ | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
opt_field_term:
/* empty */
- | COLUMNS field_term_list
+ | COLUMNS field_term_list;
field_term_list:
field_term_list field_term
- | field_term
+ | field_term;
field_term:
TERMINATED BY text_string { Lex->exchange->field_term= $3;}
| OPTIONALLY ENCLOSED BY text_string
- { Lex->exchange->enclosed= $4; Lex->exchange->opt_enclosed=1;}
+ {
+ LEX *lex=Lex;
+ lex->exchange->enclosed= $4;
+ lex->exchange->opt_enclosed=1;
+ }
| ENCLOSED BY text_string { Lex->exchange->enclosed= $3;}
- | ESCAPED BY text_string { Lex->exchange->escaped= $3;}
+ | ESCAPED BY text_string { Lex->exchange->escaped= $3;};
opt_line_term:
/* empty */
- | LINES line_term_list
+ | LINES line_term_list;
line_term_list:
line_term_list line_term
- | line_term
+ | line_term;
line_term:
TERMINATED BY text_string { Lex->exchange->line_term= $3;}
- | STARTING BY text_string { Lex->exchange->line_start= $3;}
+ | STARTING BY text_string { Lex->exchange->line_start= $3;};
opt_ignore_lines:
/* empty */
| IGNORE_SYM NUM LINES
- { Lex->exchange->skip_lines=atol($2.str); }
+ { Lex->exchange->skip_lines=atol($2.str); };
/* Common definitions */
text_literal:
TEXT_STRING { $$ = new Item_string($1.str,$1.length); }
| text_literal TEXT_STRING
- { ((Item_string*) $1)->append($2.str,$2.length); }
+ { ((Item_string*) $1)->append($2.str,$2.length); };
text_string:
TEXT_STRING { $$= new String($1.str,$1.length); }
@@ -2450,20 +2968,21 @@ text_string:
{
Item *tmp = new Item_varbinary($1.str,$1.length);
$$= tmp ? tmp->val_str((String*) 0) : (String*) 0;
- }
+ };
literal:
text_literal { $$ = $1; }
| NUM { $$ = new Item_int($1.str, (longlong) atol($1.str),$1.length); }
| LONG_NUM { $$ = new Item_int($1.str); }
+ | ULONGLONG_NUM { $$ = new Item_uint($1.str, $1.length); }
| REAL_NUM { $$ = new Item_real($1.str, $1.length); }
| FLOAT_NUM { $$ = new Item_float($1.str, $1.length); }
| NULL_SYM { $$ = new Item_null();
Lex->next_state=STATE_OPERATOR_OR_IDENT;}
- | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length); }
+ | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);}
| DATE_SYM text_literal { $$ = $2; }
| TIME_SYM text_literal { $$ = $2; }
- | TIMESTAMP text_literal { $$ = $2; }
+ | TIMESTAMP text_literal { $$ = $2; };
/**********************************************************************
** Createing different items.
@@ -2471,51 +2990,66 @@ literal:
insert_ident:
simple_ident { $$=$1; }
- | table_wild { $$=$1; }
+ | table_wild { $$=$1; };
table_wild:
ident '.' '*' { $$ = new Item_field(NullS,$1.str,"*"); }
| ident '.' ident '.' '*'
- { $$ = new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); }
+ { $$ = new Item_field((current_thd->client_capabilities &
+ CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); };
order_ident:
- expr { $$=$1; }
+ expr { $$=$1; };
simple_ident:
ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); }
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str);
+ }
| ident '.' ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str); }
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str);
+ }
| '.' ident '.' ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str); }
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str);
+ }
| ident '.' ident '.' ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); }
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str);
+ };
field_ident:
ident { $$=$1;}
| ident '.' ident { $$=$3;} /* Skipp schema name in create*/
- | '.' ident { $$=$2;} /* For Delphi */
+ | '.' ident { $$=$2;} /* For Delphi */;
table_ident:
ident { $$=new Table_ident($1); }
| ident '.' ident { $$=new Table_ident($1,$3,0);}
- | '.' ident { $$=new Table_ident($2);} /* For Delphi */
+ | '.' ident { $$=new Table_ident($2);}
+ /* For Delphi */;
ident:
IDENT { $$=$1; }
| keyword
{
+ LEX *lex;
$$.str=sql_strmake($1.str,$1.length);
$$.length=$1.length;
- if (Lex->next_state != STATE_END)
- Lex->next_state=STATE_OPERATOR_OR_IDENT;
- }
+ if ((lex=Lex)->next_state != STATE_END)
+ lex->next_state=STATE_OPERATOR_OR_IDENT;
+ };
ident_or_text:
ident { $$=$1;}
| TEXT_STRING { $$=$1;}
- | LEX_HOSTNAME { $$=$1;}
+ | LEX_HOSTNAME { $$=$1;};
user:
ident_or_text
@@ -2529,7 +3063,7 @@ user:
if (!($$=(LEX_USER*) sql_alloc(sizeof(st_lex_user))))
YYABORT;
$$->user = $1; $$->host=$3;
- }
+ };
/* Keyword that we allow for identifiers */
@@ -2538,51 +3072,68 @@ keyword:
| AFTER_SYM {}
| AGAINST {}
| AGGREGATE_SYM {}
- | AUTOCOMMIT {}
| AUTO_INC {}
| AVG_ROW_LENGTH {}
| AVG_SYM {}
| BACKUP_SYM {}
| BEGIN_SYM {}
| BERKELEY_DB_SYM {}
+ | BINLOG_SYM {}
| BIT_SYM {}
| BOOL_SYM {}
+ | BOOLEAN_SYM {}
+ | CACHE_SYM {}
| CHANGED {}
| CHECKSUM_SYM {}
| CHECK_SYM {}
+ | CIPHER_SYM {}
+ | CLIENT_SYM {}
+ | CLOSE_SYM {}
| COMMENT_SYM {}
- | COMMIT_SYM {}
| COMMITTED_SYM {}
+ | COMMIT_SYM {}
| COMPRESSED_SYM {}
| CONCURRENT {}
+ | CUBE_SYM {}
| DATA_SYM {}
| DATETIME {}
| DATE_SYM {}
| DAY_SYM {}
| DELAY_KEY_WRITE_SYM {}
+ | DES_KEY_FILE {}
+ | DIRECTORY_SYM {}
| DO_SYM {}
| DUMPFILE {}
| DYNAMIC_SYM {}
| END {}
| ENUM {}
| ESCAPE_SYM {}
+ | EVENTS_SYM {}
+ | EXECUTE_SYM {}
| EXTENDED_SYM {}
| FAST_SYM {}
+ | DISABLE_SYM {}
+ | ENABLE_SYM {}
| FULL {}
| FILE_SYM {}
| FIRST_SYM {}
| FIXED_SYM {}
| FLUSH_SYM {}
| GRANTS {}
- | GEMINI_SYM {}
| GLOBAL_SYM {}
| HEAP_SYM {}
+ | HANDLER_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
+ | INDEXES {}
| ISOLATION {}
| ISAM_SYM {}
+ | ISSUER_SYM {}
| INNOBASE_SYM {}
+ | INSERT_METHOD {}
+ | IO_THREAD {}
+ | LAST_SYM {}
| LEVEL_SYM {}
| LOCAL_SYM {}
| LOCKS_SYM {}
@@ -2596,6 +3147,9 @@ keyword:
| MASTER_USER_SYM {}
| MASTER_PASSWORD_SYM {}
| MASTER_CONNECT_RETRY_SYM {}
+ | MAX_CONNECTIONS_PER_HOUR {}
+ | MAX_QUERIES_PER_HOUR {}
+ | MAX_UPDATES_PER_HOUR {}
| MEDIUM_SYM {}
| MERGE_SYM {}
| MINUTE_SYM {}
@@ -2606,38 +3160,53 @@ keyword:
| MYISAM_SYM {}
| NATIONAL_SYM {}
| NCHAR_SYM {}
- | NO_FOREIGN_KEY_CHECKS {}
+ | NEXT_SYM {}
+ | NEW_SYM {}
| NO_SYM {}
| OPEN_SYM {}
| PACK_KEYS_SYM {}
| PASSWORD {}
+ | PREV_SYM {}
| PROCESS {}
| PROCESSLIST_SYM {}
+ | QUERY_SYM {}
| QUICK {}
| RAID_0_SYM {}
| RAID_CHUNKS {}
| RAID_CHUNKSIZE {}
| RAID_STRIPED_SYM {}
| RAID_TYPE {}
- | RELAXED_UNIQUE_CHECKS {}
+ | RELAY_LOG_FILE_SYM {}
+ | RELAY_LOG_POS_SYM {}
| RELOAD {}
| REPAIR {}
| REPEATABLE_SYM {}
+ | REPLICATION {}
| RESET_SYM {}
+ | RESOURCES {}
| RESTORE_SYM {}
| ROLLBACK_SYM {}
+ | ROLLUP_SYM {}
| ROWS_SYM {}
| ROW_FORMAT_SYM {}
| ROW_SYM {}
| SECOND_SYM {}
| SERIALIZABLE_SYM {}
| SESSION_SYM {}
+ | SIGNED_SYM {}
| SHARE_SYM {}
| SHUTDOWN {}
+ | SLAVE {}
+ | SQL_CACHE_SYM {}
+ | SQL_BUFFER_RESULT {}
+ | SQL_NO_CACHE_SYM {}
+ | SQL_THREAD {}
| START_SYM {}
| STATUS_SYM {}
| STOP_SYM {}
| STRING_SYM {}
+ | SUBJECT_SYM {}
+ | SUPER_SYM {}
| TEMPORARY {}
| TEXT_SYM {}
| TRANSACTION_SYM {}
@@ -2647,151 +3216,112 @@ keyword:
| TYPE_SYM {}
| UDF_SYM {}
| UNCOMMITTED_SYM {}
+ | USE_FRM {}
| VARIABLES {}
| WORK_SYM {}
- | YEAR_SYM {}
- | SLAVE {}
+ | YEAR_SYM {};
/* Option functions */
set:
SET opt_option
{
- THD *thd=current_thd;
- LEX *lex= &thd->lex;
+ LEX *lex=Lex;
lex->sql_command= SQLCOM_SET_OPTION;
- lex->options=thd->options;
- lex->select_limit=thd->default_select_limit;
- lex->gemini_spin_retries=thd->gemini_spin_retries;
- lex->tx_isolation=thd->tx_isolation;
+ lex->option_type=OPT_DEFAULT;
+ lex->var_list.empty();
}
- option_value_list
+ option_value_list;
opt_option:
/* empty */ {}
- | OPTION {}
+ | OPTION {};
option_value_list:
- option_value
- | option_value_list ',' option_value
+ option_type option_value
+ | option_value_list ',' option_type option_value;
+
+option_type:
+ /* empty */ {}
+ | GLOBAL_SYM { Lex->option_type= OPT_GLOBAL; }
+ | LOCAL_SYM { Lex->option_type= OPT_SESSION; }
+ | SESSION_SYM { Lex->option_type= OPT_SESSION; }
+ ;
+
+opt_var_type:
+ /* empty */ { $$=OPT_SESSION; }
+ | LOCAL_SYM { $$=OPT_SESSION; }
+ | SESSION_SYM { $$=OPT_SESSION; }
+ | GLOBAL_SYM { $$=OPT_GLOBAL; }
+ ;
+
+opt_var_ident_type:
+ /* empty */ { $$=OPT_DEFAULT; }
+ | LOCAL_SYM '.' { $$=OPT_SESSION; }
+ | SESSION_SYM '.' { $$=OPT_SESSION; }
+ | GLOBAL_SYM '.' { $$=OPT_GLOBAL; }
+ ;
option_value:
- set_option equal NUM
- {
- if (atoi($3.str) == 0)
- Lex->options&= ~$1;
- else
- Lex->options|= $1;
- }
- | set_isolation
- | AUTOCOMMIT equal NUM
- {
- if (atoi($3.str) != 0) /* Test NOT AUTOCOMMIT */
- Lex->options&= ~(OPTION_NOT_AUTO_COMMIT);
- else
- Lex->options|= OPTION_NOT_AUTO_COMMIT;
- }
- | SQL_SELECT_LIMIT equal ULONG_NUM
- {
- Lex->select_limit= $3;
- }
- | SQL_SELECT_LIMIT equal DEFAULT
- {
- Lex->select_limit= HA_POS_ERROR;
- }
- | SQL_MAX_JOIN_SIZE equal ULONG_NUM
- {
- current_thd->max_join_size= $3;
- Lex->options&= ~OPTION_BIG_SELECTS;
- }
- | SQL_MAX_JOIN_SIZE equal DEFAULT
- {
- current_thd->max_join_size= HA_POS_ERROR;
- }
- | TIMESTAMP equal ULONG_NUM
- {
- current_thd->set_time((time_t) $3);
- }
- | TIMESTAMP equal DEFAULT
- {
- current_thd->user_time=0;
- }
- | LAST_INSERT_ID equal ULONGLONG_NUM
- {
- current_thd->insert_id($3);
- }
- | INSERT_ID equal ULONGLONG_NUM
- {
- current_thd->next_insert_id=$3;
- }
- | GEMINI_SPIN_RETRIES equal ULONG_NUM
+ '@' ident_or_text equal expr
{
- Lex->gemini_spin_retries= $3;
+ Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4)));
}
- | GEMINI_SPIN_RETRIES equal DEFAULT
- {
- Lex->gemini_spin_retries= 1;
- }
- | CHAR_SYM SET IDENT
- {
- CONVERT *tmp;
- if (!(tmp=get_convert_set($3.str)))
+ | internal_variable_name equal set_expr_or_default
{
- net_printf(&current_thd->net,ER_UNKNOWN_CHARACTER_SET,$3);
- YYABORT;
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type, $1, $3));
}
- current_thd->convert_set=tmp;
- }
- | CHAR_SYM SET DEFAULT
+ | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
+ {
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var((enum_var_type) $3, $4, $6));
+ }
+ | TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
+ {
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type,
+ find_sys_var("transaction_isolation_num"),
+ new Item_int((int) $4)));
+ }
+ | CHAR_SYM SET opt_equal set_expr_or_default
{
- current_thd->convert_set=0;
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type,
+ find_sys_var("convert_character_set"),
+ $4));
}
| PASSWORD equal text_or_password
- {
- if (change_password(current_thd,current_thd->host,
- current_thd->priv_user,$3))
- YYABORT;
- }
- | PASSWORD FOR_SYM user equal text_or_password
- {
- if (change_password(current_thd,
- $3->host.str ? $3->host.str : current_thd->host,
- $3->user.str,$5))
- YYABORT;
- }
- | '@' ident_or_text equal expr
{
- Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
- if (item->fix_fields(current_thd,0) || item->update())
- {
- send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
- YYABORT;
- }
- }
- | SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
- {
- pthread_mutex_lock(&LOCK_slave);
- if(slave_running)
- send_error(&current_thd->net, ER_SLAVE_MUST_STOP);
- else
- slave_skip_counter = $3;
- pthread_mutex_unlock(&LOCK_slave);
- }
- | NO_FOREIGN_KEY_CHECKS equal NUM
- {
- if (atoi($3.str) != 0)
- Lex->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
- else
- Lex->options&= ~(OPTION_NO_FOREIGN_KEY_CHECKS);
+ THD *thd=current_thd;
+ LEX_USER *user;
+ if (!(user=(LEX_USER*) sql_alloc(sizeof(LEX_USER))))
+ YYABORT;
+ user->host.str=0;
+ user->user.str=thd->priv_user;
+ thd->lex.var_list.push_back(new set_var_password(user, $3));
}
- | RELAXED_UNIQUE_CHECKS equal NUM
+ | PASSWORD FOR_SYM user equal text_or_password
{
- if (atoi($3.str) != 0)
- Lex->options|= OPTION_RELAXED_UNIQUE_CHECKS;
- else
- Lex->options&= ~(OPTION_RELAXED_UNIQUE_CHECKS);
+ Lex->var_list.push_back(new set_var_password($3,$5));
}
+internal_variable_name:
+ ident
+ {
+ sys_var *tmp=find_sys_var($1.str, $1.length);
+ if (!tmp)
+ YYABORT;
+ $$=tmp;
+ }
+
+isolation_types:
+ READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
+ | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
+ | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; }
+ | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; }
+ ;
+
text_or_password:
TEXT_STRING { $$=$1.str;}
| PASSWORD '(' TEXT_STRING ')'
@@ -2804,53 +3334,15 @@ text_or_password:
make_scrambled_password(buff,$3.str);
$$=buff;
}
- }
-
-set_option:
- SQL_BIG_TABLES { $$= OPTION_BIG_TABLES; }
- | SQL_BIG_SELECTS { $$= OPTION_BIG_SELECTS; }
- | SQL_LOG_OFF { $$= OPTION_LOG_OFF; }
- | SQL_LOG_UPDATE
- {
- $$= (opt_sql_bin_update)?
- OPTION_UPDATE_LOG|OPTION_BIN_LOG:
- OPTION_UPDATE_LOG ;
- }
- | SQL_LOG_BIN
- {
- $$= (opt_sql_bin_update)?
- OPTION_UPDATE_LOG|OPTION_BIN_LOG:
- OPTION_BIN_LOG ;
- }
- | SQL_WARNINGS { $$= OPTION_WARNINGS; }
- | SQL_LOW_PRIORITY_UPDATES { $$= OPTION_LOW_PRIORITY_UPDATES; }
- | SQL_AUTO_IS_NULL { $$= OPTION_AUTO_IS_NULL; }
- | SQL_SAFE_UPDATES { $$= OPTION_SAFE_UPDATES; }
- | SQL_BUFFER_RESULT { $$= OPTION_BUFFER_RESULT; }
- | SQL_QUOTE_SHOW_CREATE { $$= OPTION_QUOTE_SHOW_CREATE; }
-
+ };
-set_isolation:
- GLOBAL_SYM tx_isolation
- {
- if (check_process_priv())
- YYABORT;
- default_tx_isolation= $2;
- default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
- }
- | SESSION_SYM tx_isolation
- { current_thd->session_tx_isolation= Lex->tx_isolation= $2; }
- | tx_isolation
- { Lex->tx_isolation= $1; }
-tx_isolation:
- TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types { $$=$4; }
+set_expr_or_default:
+ expr { $$=$1; }
+ | DEFAULT { $$=0; }
+ | ON { $$=new Item_string("ON",2); }
+ ;
-isolation_types:
- READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
- | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
- | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; }
- | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; }
/* Lock function */
@@ -2859,133 +3351,242 @@ lock:
{
Lex->sql_command=SQLCOM_LOCK_TABLES;
}
- table_lock_list
+ table_lock_list;
table_or_tables:
TABLE_SYM
- | TABLES
+ | TABLES;
table_lock_list:
table_lock
- | table_lock_list ',' table_lock
+ | table_lock_list ',' table_lock;
table_lock:
table_ident opt_table_alias lock_option
- { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; }
+ { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; };
lock_option:
READ_SYM { $$=TL_READ_NO_INSERT; }
| WRITE_SYM { $$=current_thd->update_lock_default; }
| LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; }
- | READ_SYM LOCAL_SYM { $$= TL_READ; }
+ | READ_SYM LOCAL_SYM { $$= TL_READ; };
unlock:
- UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; }
+ UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; };
+/*
+** Handler: direct access to ISAM functions
+*/
+
+handler:
+ HANDLER_SYM table_ident OPEN_SYM opt_table_alias
+ {
+ Lex->sql_command = SQLCOM_HA_OPEN;
+ if (!add_table_to_list($2,$4,0))
+ YYABORT;
+ }
+ | HANDLER_SYM table_ident CLOSE_SYM
+ {
+ Lex->sql_command = SQLCOM_HA_CLOSE;
+ if (!add_table_to_list($2,0,0))
+ YYABORT;
+ }
+ | HANDLER_SYM table_ident READ_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_HA_READ;
+ lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
+ lex->select->select_limit= 1;
+ lex->select->offset_limit= 0L;
+ if (!add_table_to_list($2,0,0))
+ YYABORT;
+ }
+ handler_read_or_scan where_clause limit_clause { };
+
+handler_read_or_scan:
+ handler_scan_function { Lex->backup_dir= 0; }
+ | ident handler_rkey_function { Lex->backup_dir= $1.str; };
+
+handler_scan_function:
+ FIRST_SYM { Lex->ha_read_mode = RFIRST; }
+ | NEXT_SYM { Lex->ha_read_mode = RNEXT; };
+
+handler_rkey_function:
+ FIRST_SYM { Lex->ha_read_mode = RFIRST; }
+ | NEXT_SYM { Lex->ha_read_mode = RNEXT; }
+ | PREV_SYM { Lex->ha_read_mode = RPREV; }
+ | LAST_SYM { Lex->ha_read_mode = RLAST; }
+ | handler_rkey_mode
+ {
+ LEX *lex=Lex;
+ lex->ha_read_mode = RKEY;
+ lex->ha_rkey_mode=$1;
+ if (!(lex->insert_list = new List_item))
+ YYABORT;
+ } '(' values ')' { };
+
+handler_rkey_mode:
+ EQ { $$=HA_READ_KEY_EXACT; }
+ | GE { $$=HA_READ_KEY_OR_NEXT; }
+ | LE { $$=HA_READ_KEY_OR_PREV; }
+ | GT_SYM { $$=HA_READ_AFTER_KEY; }
+ | LT { $$=HA_READ_BEFORE_KEY; };
+
/* GRANT / REVOKE */
revoke:
REVOKE
{
- Lex->sql_command = SQLCOM_REVOKE;
- Lex->users_list.empty();
- Lex->columns.empty();
- Lex->grant= Lex->grant_tot_col=0;
- Lex->db=0;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_REVOKE;
+ lex->users_list.empty();
+ lex->columns.empty();
+ lex->grant= lex->grant_tot_col=0;
+ lex->select->db=0;
}
- grant_privileges ON opt_table FROM user_list
+ grant_privileges ON opt_table FROM user_list;
grant:
GRANT
{
- Lex->sql_command = SQLCOM_GRANT;
- Lex->users_list.empty();
- Lex->columns.empty();
- Lex->grant= Lex->grant_tot_col=0;
- Lex->db=0;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_GRANT;
+ lex->users_list.empty();
+ lex->columns.empty();
+ lex->grant= lex->grant_tot_col=0;
+ lex->select->db=0;
+ lex->ssl_type=SSL_TYPE_NONE;
+ lex->ssl_cipher=lex->x509_subject=lex->x509_issuer=0;
+ bzero(&(lex->mqh),sizeof(lex->mqh));
}
grant_privileges ON opt_table TO_SYM user_list
- grant_option
+ require_clause grant_options;
grant_privileges:
grant_privilege_list {}
- | ALL PRIVILEGES { Lex->grant = UINT_MAX;}
- | ALL { Lex->grant = UINT_MAX;}
+ | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;}
+ | ALL { Lex->grant = GLOBAL_ACLS;};
grant_privilege_list:
grant_privilege
- | grant_privilege_list ',' grant_privilege
+ | grant_privilege_list ',' grant_privilege;
grant_privilege:
- SELECT_SYM
- { Lex->which_columns = SELECT_ACL;}
- opt_column_list
- | INSERT
- { Lex->which_columns = INSERT_ACL; }
- opt_column_list
- | UPDATE_SYM
- { Lex->which_columns = UPDATE_ACL; }
- opt_column_list
- | DELETE_SYM { Lex->grant |= DELETE_ACL;}
- | REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list
- | USAGE {}
+ SELECT_SYM { Lex->which_columns = SELECT_ACL;} opt_column_list
+ | INSERT { Lex->which_columns = INSERT_ACL;} opt_column_list
+ | UPDATE_SYM { Lex->which_columns = UPDATE_ACL; } opt_column_list
+ | REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list
+ | DELETE_SYM { Lex->grant |= DELETE_ACL;}
+ | USAGE {}
| INDEX { Lex->grant |= INDEX_ACL;}
| ALTER { Lex->grant |= ALTER_ACL;}
| CREATE { Lex->grant |= CREATE_ACL;}
| DROP { Lex->grant |= DROP_ACL;}
+ | EXECUTE_SYM { Lex->grant |= EXECUTE_ACL;}
| RELOAD { Lex->grant |= RELOAD_ACL;}
| SHUTDOWN { Lex->grant |= SHUTDOWN_ACL;}
| PROCESS { Lex->grant |= PROCESS_ACL;}
| FILE_SYM { Lex->grant |= FILE_ACL;}
| GRANT OPTION { Lex->grant |= GRANT_ACL;}
-
+ | SHOW DATABASES { Lex->grant |= SHOW_DB_ACL;}
+ | SUPER_SYM { Lex->grant |= SUPER_ACL;}
+ | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;}
+ | LOCK_SYM TABLES { Lex->grant |= LOCK_TABLES_ACL; }
+ | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL;}
+ | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;}
+ ;
+
+require_list: require_list_element AND require_list
+| require_list_element ;
+
+require_list_element: SUBJECT_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->x509_subject)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "SUBJECT");
+ YYABORT;
+ }
+ lex->x509_subject=$2.str;
+ }
+ | ISSUER_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->x509_issuer)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "ISSUER");
+ YYABORT;
+ }
+ lex->x509_issuer=$2.str;
+ }
+ | CIPHER_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->ssl_cipher)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CIPHER");
+ YYABORT;
+ }
+ lex->ssl_cipher=$2.str;
+ }
+ ;
+
opt_table:
'*'
{
- Lex->db=current_thd->db;
- if (Lex->grant == UINT_MAX)
- Lex->grant = DB_ACLS & ~GRANT_ACL;
- else if (Lex->columns.elements)
+ LEX *lex=Lex;
+ lex->select->db=lex->thd->db;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant = DB_ACLS & ~GRANT_ACL;
+ else if (lex->columns.elements)
{
- net_printf(&current_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
- YYABORT;
- }
+ send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ YYABORT;
+ }
}
| ident '.' '*'
{
- Lex->db = $1.str;
- if (Lex->grant == UINT_MAX)
- Lex->grant = DB_ACLS & ~GRANT_ACL;
- else if (Lex->columns.elements)
+ LEX *lex=Lex;
+ lex->select->db = $1.str;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant = DB_ACLS & ~GRANT_ACL;
+ else if (lex->columns.elements)
{
- net_printf(&current_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
YYABORT;
}
}
| '*' '.' '*'
{
- Lex->db = NULL;
- if (Lex->grant == UINT_MAX)
- Lex->grant = GLOBAL_ACLS & ~GRANT_ACL;
- else if (Lex->columns.elements)
+ LEX *lex=Lex;
+ lex->select->db = NULL;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
+ else if (lex->columns.elements)
{
- net_printf(&current_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
YYABORT;
}
}
| table_ident
{
+ LEX *lex=Lex;
if (!add_table_to_list($1,NULL,0))
YYABORT;
- if (Lex->grant == UINT_MAX)
- Lex->grant = TABLE_ACLS & ~GRANT_ACL;
- }
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant = TABLE_ACLS & ~GRANT_ACL;
+ };
user_list:
- grant_user { if (Lex->users_list.push_back($1)) YYABORT;}
- | user_list ',' grant_user { if (Lex->users_list.push_back($3)) YYABORT;}
+ grant_user { if (Lex->users_list.push_back($1)) YYABORT;}
+ | user_list ',' grant_user
+ {
+ if (Lex->users_list.push_back($3))
+ YYABORT;
+ }
+ ;
grant_user:
@@ -3006,16 +3607,20 @@ grant_user:
| user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
{ $$=$1; $1->password=$5 ; }
| user
- { $$=$1; $1->password.str=NullS; }
+ { $$=$1; $1->password.str=NullS; };
opt_column_list:
- /* empty */ { Lex->grant |= Lex->which_columns; }
- | '(' column_list ')'
+ /* empty */
+ {
+ LEX *lex=Lex;
+ lex->grant |= lex->which_columns;
+ }
+ | '(' column_list ')';
column_list:
column_list ',' column_list_id
- | column_list_id
+ | column_list_id;
column_list_id:
ident
@@ -3023,31 +3628,129 @@ column_list_id:
String *new_str = new String((const char*) $1.str,$1.length);
List_iterator <LEX_COLUMN> iter(Lex->columns);
class LEX_COLUMN *point;
+ LEX *lex=Lex;
while ((point=iter++))
{
if (!my_strcasecmp(point->column.ptr(),new_str->ptr()))
break;
}
- Lex->grant_tot_col|= Lex->which_columns;
+ lex->grant_tot_col|= lex->which_columns;
if (point)
- point->rights |= Lex->which_columns;
+ point->rights |= lex->which_columns;
else
- Lex->columns.push_back(new LEX_COLUMN (*new_str,Lex->which_columns));
- }
+ lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns));
+ };
-grant_option:
+
+require_clause: /* empty */
+ | REQUIRE_SYM require_list
+ {
+ Lex->ssl_type=SSL_TYPE_SPECIFIED;
+ }
+ | REQUIRE_SYM SSL_SYM
+ {
+ Lex->ssl_type=SSL_TYPE_ANY;
+ }
+ | REQUIRE_SYM X509_SYM
+ {
+ Lex->ssl_type=SSL_TYPE_X509;
+ };
+
+grant_options:
/* empty */ {}
- | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ | WITH grant_option_list;
+
+grant_option_list:
+ grant_option_list grant_option {}
+ | grant_option {};
+
+grant_option:
+ GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ | MAX_QUERIES_PER_HOUR ULONG_NUM
+ {
+ Lex->mqh.questions=$2;
+ Lex->mqh.bits |= 1;
+ }
+ | MAX_UPDATES_PER_HOUR ULONG_NUM
+ {
+ Lex->mqh.updates=$2;
+ Lex->mqh.bits |= 2;
+ }
+ | MAX_CONNECTIONS_PER_HOUR ULONG_NUM
+ {
+ Lex->mqh.connections=$2;
+ Lex->mqh.bits |= 4;
+ };
begin:
- BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work
+ BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work;
opt_work:
/* empty */ {}
- | WORK_SYM {}
+ | WORK_SYM {;};
commit:
- COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}
+ COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;};
rollback:
- ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;}
+ ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;};
+
+
+/*
+** UNIONS : glue selects together
+*/
+
+
+union:
+ /* empty */ {}
+ | union_list;
+
+union_list:
+ UNION_SYM union_option
+ {
+ LEX *lex=Lex;
+ if (lex->exchange)
+ {
+ /* Only the last SELECT can have INTO...... */
+ net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO");
+ YYABORT;
+ }
+ if (lex->select->linkage == NOT_A_SELECT)
+ {
+ send_error(&lex->thd->net, ER_SYNTAX_ERROR);
+ YYABORT;
+ }
+ if (mysql_new_select(lex))
+ YYABORT;
+ lex->select->linkage=UNION_TYPE;
+ }
+ select_init
+ ;
+
+union_opt:
+ union {}
+ | optional_order_or_limit {};
+
+optional_order_or_limit:
+ /* empty */ {}
+ |
+ {
+ LEX *lex=Lex;
+ if (!lex->select->braces)
+ {
+ send_error(&lex->thd->net, ER_SYNTAX_ERROR);
+ YYABORT;
+ }
+ if (mysql_new_select(lex))
+ YYABORT;
+ mysql_init_select(lex);
+ lex->select->linkage=NOT_A_SELECT;
+ lex->select->select_limit=lex->thd->variables.select_limit;
+ }
+ opt_order_clause limit_clause
+ ;
+
+union_option:
+ /* empty */ {}
+ | ALL { Lex->union_option=1; }
+ ;
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index f4415571f1b..1aba73dda33 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#include "stacktrace.h"
#include <signal.h>
#include <my_pthread.h>
@@ -122,8 +122,8 @@ terribly wrong...\n");
return;
}
#endif /* __alpha__ */
-
- if (!stack_bottom)
+
+ if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp)
{
ulong tmp= min(0x10000,thread_stack);
/* Assume that the stack starts at the previous even 65K */
@@ -145,12 +145,12 @@ terribly wrong...\n");
fprintf(stderr, "Warning: Alpha stacks are difficult -\
will be taking some wild guesses, stack trace may be incorrect or \
terminate abruptly\n");
- // On Alpha, we need to get pc
+ /* On Alpha, we need to get pc */
__asm __volatile__ ("bsr %0, do_next; do_next: "
:"=r"(pc)
:"r"(pc));
#endif /* __alpha__ */
-
+
while (fp < (uchar**) stack_bottom)
{
#ifdef __i386__
@@ -165,7 +165,7 @@ terribly wrong...\n");
{
new_fp += 90;
}
-
+
if (fp && pc)
{
pc = find_prev_pc(pc, fp);
@@ -195,7 +195,7 @@ terribly wrong...\n");
}
fprintf(stderr, "Stack trace seems successful - bottom reached\n");
-
+
end:
fprintf(stderr, "Please read http://www.mysql.com/doc/U/s/Using_stack_trace.html and follow instructions on how to resolve the stack trace. Resolved\n\
stack trace is much more helpful in diagnosing the problem, so please do \n\
@@ -210,8 +210,8 @@ resolve it\n");
void write_core(int sig)
{
signal(sig, SIG_DFL);
- if (fork() != 0) exit(1); // Abort main program
- // Core will be written at exit
+ if (fork() != 0) exit(1); /* Abort main program */
+ /* Core will be written at exit */
}
#else
void write_core(int sig)
diff --git a/sql/structs.h b/sql/structs.h
index 36f503312c0..bd058a08e46 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -50,14 +50,14 @@ typedef struct st_keyfile_info { /* used with ha_info() */
typedef struct st_key_part_info { /* Info about a key part */
Field *field;
uint offset; /* offset in record (from 0) */
- uint null_offset; // Offset to null_bit in record
+ uint null_offset; /* Offset to null_bit in record */
uint16 length; /* Length of key_part */
uint16 store_length;
uint16 key_type;
uint16 fieldnr; /* Fieldnum in UNIREG */
uint8 key_part_flag; /* 0 or HA_REVERSE_SORT */
uint8 type;
- uint8 null_bit; // Position to null_bit
+ uint8 null_bit; /* Position to null_bit */
} KEY_PART_INFO ;
@@ -67,6 +67,7 @@ typedef struct st_key {
uint key_parts; /* How many key_parts */
uint extra_length;
uint usable_key_parts; /* Should normally be = key_parts */
+ enum ha_key_alg algorithm;
KEY_PART_INFO *key_part;
char *name; /* Name of key */
ulong *rec_per_key; /* Key part distribution */
@@ -123,17 +124,37 @@ typedef struct {
} INTERVAL;
-enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL,
- SHOW_MY_BOOL,SHOW_OPENTABLES,SHOW_STARTTIME,SHOW_QUESTION,
- SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE};
+enum SHOW_TYPE
+{
+ SHOW_UNDEF,
+ SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_BOOL,
+ SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUESTION,
+ SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS,
+#ifdef HAVE_OPENSSL
+ SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD,
+ SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE,
+ SHOW_SSL_CTX_SESS_CB_HITS, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE,
+ SHOW_SSL_CTX_SESS_NUMBER, SHOW_SSL_SESSION_REUSED,
+ SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER,
+ SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE,
+ SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH,
+ SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT,
+ SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD,
+ SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES,
+ SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL,
+ SHOW_SSL_GET_CIPHER_LIST,
+#endif /* HAVE_OPENSSL */
+ SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING
+};
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
+typedef int *(*update_var)(THD *, struct show_var_st *);
-struct show_var_st {
+typedef struct show_var_st {
const char *name;
char *value;
SHOW_TYPE type;
-};
+} SHOW_VAR;
typedef struct lex_string {
char *str;
@@ -144,6 +165,17 @@ typedef struct st_lex_user {
LEX_STRING user, host, password;
} LEX_USER;
+
+typedef struct user_resources {
+ uint questions, updates, connections, bits;
+} USER_RESOURCES;
+
+typedef struct user_conn {
+ char *user, *host;
+ uint len, connections, conn_per_hour, updates, questions, user_len;
+ USER_RESOURCES user_resources;
+ time_t intime;
+} USER_CONN;
/* Bits in form->update */
#define REG_MAKE_DUPP 1 /* Make a copy of record when read */
#define REG_NEW_RECORD 2 /* Write a new record if not found */
@@ -154,13 +186,14 @@ typedef struct st_lex_user {
#define REG_MAY_BE_UPDATED 64
#define REG_AUTO_UPDATE 64 /* Used in D-forms for scroll-tables */
#define REG_OVERWRITE 128
-#define REG_SKIPP_DUPP 256
+#define REG_SKIP_DUP 256
/* Bits in form->status */
#define STATUS_NO_RECORD (1+2) /* Record isn't usably */
#define STATUS_GARBAGE 1
-#define STATUS_NOT_FOUND 2 /* No record in database when neaded */
+#define STATUS_NOT_FOUND 2 /* No record in database when needed */
#define STATUS_NO_PARENT 4 /* Parent record wasn't found */
#define STATUS_NOT_READ 8 /* Record isn't read */
#define STATUS_UPDATED 16 /* Record is updated by formula */
#define STATUS_NULL_ROW 32 /* table->null_row is set */
+#define STATUS_DELETED 64
diff --git a/sql/table.cc b/sql/table.cc
index 4f71dacfa1d..2a284d4c027 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -46,7 +46,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
reg2 uchar *strpos;
int j,error;
uint rec_buff_length,n_length,int_length,records,key_parts,keys,
- interval_count,interval_parts,read_length,db_create_options;
+ interval_count,interval_parts,read_length,db_create_options;
+ uint key_info_length;
ulong pos;
char index_file[FN_REFLEN], *names,*keynames;
uchar head[288],*disk_buff,new_field_pack_flag;
@@ -127,11 +128,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam->min_rows=uint4korr(head+22);
/* Read keyinformation */
+ key_info_length= (uint) uint2korr(head+28);
VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
- if (read_string(file,(gptr*) &disk_buff,(uint) uint2korr(head+28)))
+ if (read_string(file,(gptr*) &disk_buff,key_info_length))
goto err_not_open; /* purecov: inspected */
outparam->keys=keys= disk_buff[0];
- outparam->keys_in_use= set_bits(key_map, keys);
+ outparam->keys_for_keyread= outparam->keys_in_use= set_bits(key_map, keys);
outparam->key_parts=key_parts=disk_buff[1];
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
@@ -187,8 +189,17 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (keyinfo->flags & HA_NOSAME)
set_if_bigger(outparam->max_unique_length,keyinfo->key_length);
}
+ keynames=(char*) key_part;
+ strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
+ /* Test if new 4.0 format */
+ if ((uint) (strpos - disk_buff) < key_info_length)
+ {
+ /* Read key types */
+ keyinfo=outparam->key_info;
+ for (i=0 ; i < keys ; i++, keyinfo++)
+ keyinfo->algorithm= (enum ha_key_alg) *(strpos++);
+ }
- (void) strmov(keynames= (char *) key_part,(char *) strpos);
outparam->reclength = uint2korr((head+16));
if (*(head+26) == 1)
outparam->system=1; /* one-record-database */
@@ -259,7 +270,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam->comment=strdup_root(&outparam->mem_root,
(char*) head+47);
- DBUG_PRINT("form",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length));
+ DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length));
if (!(field_ptr = (Field **)
alloc_root(&outparam->mem_root,
@@ -359,14 +370,24 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
{
uint primary_key=(uint) (find_type((char*) "PRIMARY",&outparam->keynames,
3)-1);
- uint ha_option=outparam->file->option_flag();
+ uint ha_option=outparam->file->table_flags();
keyinfo=outparam->key_info;
key_part=keyinfo->key_part;
for (uint key=0 ; key < outparam->keys ; key++,keyinfo++)
{
uint usable_parts=0;
+ ulong index_flags;
keyinfo->name=(char*) outparam->keynames.type_names[key];
+ /* Fix fulltext keys for old .frm files */
+ if (outparam->key_info[key].flags & HA_FULLTEXT)
+ outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
+
+ /* This has to be done after the above fulltext correction */
+ index_flags=outparam->file->index_flags(key);
+ if (!(index_flags & HA_KEY_READ_ONLY))
+ outparam->keys_for_keyread&= ~((key_map) 1 << key);
+
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
{
/*
@@ -424,7 +445,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
if (i == 0)
field->key_start|= ((key_map) 1 << key);
- if ((ha_option & HA_HAVE_KEY_READ_ONLY) &&
+ if ((index_flags & HA_KEY_READ_ONLY) &&
field->key_length() == key_part->length &&
field->type() != FIELD_TYPE_BLOB)
{
@@ -432,8 +453,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(!(ha_option & HA_KEY_READ_WRONG_STR) &&
!(keyinfo->flags & HA_FULLTEXT)))
field->part_of_key|= ((key_map) 1 << key);
- if (field->key_type() != HA_KEYTYPE_TEXT ||
- !(keyinfo->flags & HA_FULLTEXT))
+ if ((field->key_type() != HA_KEYTYPE_TEXT ||
+ !(keyinfo->flags & HA_FULLTEXT)) &&
+ !(index_flags & HA_WRONG_ASCII_ORDER))
field->part_of_sortkey|= ((key_map) 1 << key);
}
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
@@ -443,15 +465,20 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (key == primary_key)
{
field->flags|= PRI_KEY_FLAG;
+ /*
+ If this field is part of the primary key and all keys contains
+ the primary key, then we can use any key to find this column
+ */
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
- field->part_of_key|= ((key_map) 1 << primary_key);
+ field->part_of_key= outparam->keys_in_use;
}
if (field->key_length() != key_part->length)
{
key_part->key_part_flag|= HA_PART_KEY;
if (field->type() != FIELD_TYPE_BLOB)
{ // Create a new field
- field=key_part->field=field->new_field(outparam);
+ field=key_part->field=field->new_field(&outparam->mem_root,
+ outparam);
field->field_length=key_part->length;
}
}
@@ -468,8 +495,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(outparam->keys_in_use & ((key_map) 1 << primary_key)))
{
outparam->primary_key=primary_key;
- if (outparam->file->option_flag() & HA_PRIMARY_KEY_IN_READ_INDEX)
- outparam->ref_primary_key= (key_map) 1 << primary_key;
/*
If we are using an integer as the primary key then allow the user to
refer to it as '_rowid'
@@ -497,6 +522,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
bfill(outparam->null_flags+outparam->rec_buff_length*2,null_length,255);
}
+
if ((reg_field=outparam->found_next_number_field))
{
if ((int) (outparam->next_number_index= (uint)
@@ -824,7 +850,7 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
*type_name= '\0'; /* End string */
ptr=type_name;
}
- ptr+=2; /* Skipp end mark and last 0 */
+ ptr+=2; /* Skip end mark and last 0 */
}
else
ptr++;
@@ -910,7 +936,7 @@ ulong next_io_size(register ulong pos)
void append_unescaped(String *res,const char *pos)
{
- for ( ; *pos ; pos++)
+ for (; *pos ; pos++)
{
switch (*pos) {
case 0: /* Must be escaped for 'mysql' */
@@ -998,6 +1024,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo,
void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
{
+ DBUG_ENTER("update_create_info_from_table");
create_info->max_rows=table->max_rows;
create_info->min_rows=table->min_rows;
create_info->table_options=table->db_create_options;
@@ -1006,7 +1033,8 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
create_info->raid_type=table->raid_type;
create_info->raid_chunks=table->raid_chunks;
create_info->raid_chunksize=table->raid_chunksize;
-}
+ DBUG_VOID_RETURN;
+}
int
rename_file_ext(const char * from,const char * to,const char * ext)
@@ -1054,7 +1082,8 @@ bool check_db_name(const char *name)
}
}
#endif
- if (*name == '/' || *name == FN_LIBCHAR || *name == FN_EXTCHAR)
+ if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR ||
+ *name == FN_EXTCHAR)
return 1;
name++;
}
diff --git a/sql/table.h b/sql/table.h
index ae785b8a402..229d41a2df7 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -37,8 +37,8 @@ typedef struct st_grant_info
{
GRANT_TABLE *grant_table;
uint version;
- uint privilege;
- uint want_privilege;
+ ulong privilege;
+ ulong want_privilege;
} GRANT_INFO;
enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2};
@@ -61,7 +61,8 @@ struct st_table {
uint uniques;
uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob fields */
- key_map keys_in_use, keys_in_use_for_query;
+ key_map keys_in_use, keys_for_keyread;
+ key_map quick_keys, used_keys, keys_in_use_for_query;
KEY *key_info; /* data of keys in database */
TYPELIB keynames; /* Pointers to keynames */
ha_rows max_rows; /* create information */
@@ -89,7 +90,7 @@ struct st_table {
my_bool copy_blobs; /* copy_blobs when storing */
my_bool null_row; /* All columns are null */
my_bool maybe_null,outer_join; /* Used with OUTER JOIN */
- my_bool distinct,const_table;
+ my_bool distinct,const_table,no_rows;
my_bool key_read;
my_bool crypted;
my_bool db_low_byte_first; /* Portable row format */
@@ -98,6 +99,7 @@ struct st_table {
my_bool fulltext_searched;
my_bool crashed;
my_bool is_view;
+ my_bool no_keyread;
Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */
*rowid_field;
@@ -111,14 +113,13 @@ struct st_table {
char *table_name,*real_name,*path;
uint key_length; /* Length of key */
uint tablenr,used_fields,null_bytes;
- table_map map;
+ table_map map; /* ID bit of table (1,2,4,8,16...) */
ulong version,flush_version;
uchar *null_flags;
IO_CACHE *io_cache; /* If sorted trough file*/
byte *record_pointers; /* If sorted in memory */
ha_rows found_records; /* How many records in sort */
ORDER *group;
- key_map quick_keys, used_keys, ref_primary_key;
ha_rows quick_rows[MAX_KEY];
uint quick_key_parts[MAX_KEY];
key_part_map const_key_parts[MAX_KEY];
@@ -134,16 +135,37 @@ struct st_table {
#define JOIN_TYPE_LEFT 1
#define JOIN_TYPE_RIGHT 2
-typedef struct st_table_list {
+typedef struct st_table_list
+{
struct st_table_list *next;
char *db,*name,*real_name;
+ uint32 db_length, real_name_length;
Item *on_expr; /* Used with outer join */
struct st_table_list *natural_join; /* natural join on this table*/
- List<String> *use_index,*ignore_index;
+ /* ... join ... USE INDEX ... IGNORE INDEX */
+ List<String> *use_index,*ignore_index;
TABLE *table;
GRANT_INFO grant;
thr_lock_type lock_type;
uint outer_join; /* Which join type */
bool straight; /* optimize with prev table */
- bool updating; /* for replicate-do/ignore table */
+ bool updating; /* for replicate-do/ignore table */
+ bool shared; /* Used twice in union */
+ bool do_redirect; /* To get the struct in UNION's */
} TABLE_LIST;
+
+
+typedef struct st_changed_table_list
+{
+ struct st_changed_table_list *next;
+ char *key;
+ uint32 key_length;
+} CHANGED_TABLE_LIST;
+
+
+typedef struct st_open_table_list
+{
+ struct st_open_table_list *next;
+ char *db,*table;
+ uint32 in_use,locked;
+} OPEN_TABLE_LIST;
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index deb304443df..8b9baa6f045 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,7 +22,9 @@
extern "C" {
void sql_alloc_error_handler(void)
{
- current_thd->fatal_error=1; /* purecov: inspected */
+ THD *thd=current_thd;
+ if (thd) // QQ; To be removed
+ thd->fatal_error=1; /* purecov: inspected */
sql_print_error(ER(ER_OUT_OF_RESOURCES));
}
}
diff --git a/sql/time.cc b/sql/time.cc
index 1d7e055f682..817469aa096 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -24,7 +24,7 @@ static ulong const days_at_timestart=719528; /* daynr at 1970.01.01 */
uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037";
- /* Init some variabels neaded when using my_local_time */
+ /* Init some variabels needed when using my_local_time */
/* Currently only my_time_zone is inited */
static long my_time_zone=0;
@@ -54,7 +54,7 @@ void init_time(void)
This code handles also day light saving time.
The idea is to cache the time zone (including daylight saving time)
for the next call to make things faster.
-
+
*/
long my_gmt_sec(TIME *t)
@@ -84,7 +84,7 @@ long my_gmt_sec(TIME *t)
/* Get difference in days */
int days= t->day - l_time->tm_mday;
if (days < -1)
- days= 1; // Month has wrapped
+ days= 1; /* Month has wrapped */
else if (days > 1)
days= -1;
diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) +
@@ -100,15 +100,15 @@ long my_gmt_sec(TIME *t)
{
int days= t->day - l_time->tm_mday;
if (days < -1)
- days=1; // Month has wrapped
+ days=1; /* Month has wrapped */
else if (days > 1)
days= -1;
diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour))+
(long) (60*((int) t->minute - (int) l_time->tm_min)));
if (diff == 3600)
- tmp+=3600 - t->minute*60 - t->second; // Move to next hour
+ tmp+=3600 - t->minute*60 - t->second; /* Move to next hour */
else if (diff == -3600)
- tmp-=t->minute*60 + t->second; // Move to next hour
+ tmp-=t->minute*60 + t->second; /* Move to next hour */
}
if ((my_time_zone >=0 ? my_time_zone: -my_time_zone) > 3600L*12)
my_time_zone=0; /* Wrong date */
@@ -128,7 +128,7 @@ long calc_daynr(uint year,uint month,uint day)
DBUG_ENTER("calc_daynr");
if (year == 0 && month == 0 && day == 0)
- DBUG_RETURN(0); /* Skipp errors */
+ DBUG_RETURN(0); /* Skip errors */
if (year < 200)
{
if ((year=year+1900) < 1900+YY_PART_YEAR)
@@ -176,17 +176,20 @@ uint calc_week(TIME *l_time, bool with_year, bool sunday_first_day_of_week,
ulong first_daynr=calc_daynr(l_time->year,1,1);
uint weekday=calc_weekday(first_daynr,sunday_first_day_of_week);
*year=l_time->year;
- if (l_time->month == 1 && weekday >= 4 && l_time->day <= 7-weekday)
+ if (l_time->month == 1 && l_time->day <= 7-weekday &&
+ ((!sunday_first_day_of_week && weekday >= 4) ||
+ (sunday_first_day_of_week && weekday != 0)))
{
/* Last week of the previous year */
if (!with_year)
return 0;
- with_year=0; // Don't check the week again
+ with_year=0; /* Don't check the week again */
(*year)--;
first_daynr-= (days=calc_days_in_year(*year));
weekday= (weekday + 53*7- days) % 7;
}
- if (weekday >= 4)
+ if ((sunday_first_day_of_week && weekday != 0) ||
+ (!sunday_first_day_of_week && weekday >= 4))
days= daynr - (first_daynr+ (7-weekday));
else
days= daynr - (first_daynr - weekday);
@@ -195,7 +198,7 @@ uint calc_week(TIME *l_time, bool with_year, bool sunday_first_day_of_week,
/* Check if we are on the first week of the next year (or week 53) */
weekday= (weekday + calc_days_in_year(*year)) % 7;
if (weekday < 4)
- { // We are at first week on next year
+ { /* We are at first week on next year */
(*year)++;
return 1;
}
@@ -431,7 +434,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
DBUG_ENTER("str_to_TIME");
DBUG_PRINT("enter",("str: %.*s",length,str));
- for (; str != end && !isdigit(*str) ; str++) ; // Skipp garbage
+ for (; str != end && !isdigit(*str) ; str++) ; /* Skip garbage */
if (str == end)
DBUG_RETURN(TIMESTAMP_NONE);
/*
@@ -453,18 +456,18 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
}
date[i]=tmp_value;
if (i == 2 && str != end && *str == 'T')
- str++; // ISO8601: CCYYMMDDThhmmss
- else if ( i != 5 ) // Skip inter-field delimiters
+ str++; /* ISO8601: CCYYMMDDThhmmss */
+ else if ( i != 5 ) /* Skip inter-field delimiters */
{
while (str != end && (ispunct(*str) || isspace(*str)))
{
- // Only allow space between days and hours
+ /* Only allow space between days and hours */
if (isspace(*str) && i != 2)
DBUG_RETURN(TIMESTAMP_NONE);
str++;
}
}
- field_length=1; // Rest fields can only be 2
+ field_length=1; /* Rest fields can only be 2 */
}
/* Handle second fractions */
if (i == 6 && (uint) (end-str) >= 2 && *str == '.' && isdigit(str[1]))
@@ -493,7 +496,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
}
if (str != end && current_thd->count_cuted_fields)
{
- for ( ; str != end ; str++)
+ for (; str != end ; str++)
{
if (!isspace(*str))
{
@@ -569,9 +572,9 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
/* Check first if this is a full TIMESTAMP */
if (length >= 12)
- { // Probably full timestamp
+ { /* Probably full timestamp */
if (str_to_TIME(str,length,l_time,1) == TIMESTAMP_FULL)
- return 0; // Was an ok timestamp
+ return 0; /* Was an ok timestamp */
}
/* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
@@ -587,19 +590,19 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
LINT_INIT(state);
found_days=found_hours=0;
if ((uint) (end-str) > 1 && (*str == ' ' && isdigit(str[1])))
- { // days !
+ { /* days ! */
date[0]=value;
- state=1; // Assume next is hours
+ state=1; /* Assume next is hours */
found_days=1;
- str++; // Skipp space;
+ str++; /* Skip space; */
}
else if ((end-str) > 1 && *str == ':' && isdigit(str[1]))
{
- date[0]=0; // Assume we found hours
+ date[0]=0; /* Assume we found hours */
date[1]=value;
state=2;
found_hours=1;
- str++; // skipp ':'
+ str++; /* skip ':' */
}
else
{
@@ -620,11 +623,11 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
date[state++]=value;
if (state == 4 || (end-str) < 2 || *str != ':' || !isdigit(str[1]))
break;
- str++; // Skipp ':'
+ str++; /* Skip ':' */
}
if (state != 4)
- { // Not HH:MM:SS
+ { /* Not HH:MM:SS */
/* Fix the date to assume that seconds was given */
if (!found_hours && !found_days)
{
diff --git a/sql/udf_example.cc b/sql/udf_example.cc
index a91db5ee1cc..f5ff9fe67b5 100644
--- a/sql/udf_example.cc
+++ b/sql/udf_example.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -110,7 +110,7 @@
#include <stdio.h>
#include <string.h>
#else
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#endif
#include <mysql.h>
@@ -271,7 +271,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
* characters and converting to uppercase.
*-------------------------------------------------------*/
- for ( n = ntrans + 1, n_end = ntrans + sizeof(ntrans)-2;
+ for (n = ntrans + 1, n_end = ntrans + sizeof(ntrans)-2;
word != w_end && n < n_end; word++ )
if ( isalpha ( *word ))
*n++ = toupper ( *word );
@@ -324,7 +324,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
KSflag = 0; /* state flag for KS translation */
- for ( metaph_end = result + MAXMETAPH, n_start = n;
+ for (metaph_end = result + MAXMETAPH, n_start = n;
n <= n_end && result < metaph_end; n++ )
{
@@ -402,7 +402,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
n[2] != 'G' ) ?
(char)'J' : (char)'K';
else
- if( n[1] == 'H' &&
+ if ( n[1] == 'H' &&
!NOGHTOF( *( n - 3 )) &&
*( n - 4 ) != 'H')
*result++ = 'F';
@@ -440,7 +440,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
case 'T': /* TIO, TIA = X ("sh" sound) */
/* TH = 0, ("th" sound ) */
- if( *( n + 1 ) == 'I' && ( n[2] == 'O'
+ if ( *( n + 1 ) == 'I' && ( n[2] == 'O'
|| n[2] == 'A') )
*result++ = 'X';
else
diff --git a/sql/uniques.cc b/sql/uniques.cc
new file mode 100644
index 00000000000..60905567ba0
--- /dev/null
+++ b/sql/uniques.cc
@@ -0,0 +1,166 @@
+/* Copyright (C) 2001 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Function to handle quick removal of duplicates
+ This code is used when doing multi-table deletes to find the rows in
+ reference tables that needs to be deleted.
+
+ The basic idea is as follows:
+
+ Store first all strings in a binary tree, ignoring duplicates.
+ When the tree uses more memory than 'max_heap_table_size',
+ write the tree (in sorted order) out to disk and start with a new tree.
+ When all data has been generated, merge the trees (removing any found
+ duplicates).
+
+ The unique entries will be returned in sort order, to ensure that we do the
+ deletes in disk order.
+*/
+
+#include "mysql_priv.h"
+#include "sql_sort.h"
+
+
+int unique_write_to_file(gptr key, element_count count, Unique *unique)
+{
+ return my_b_write(&unique->file, (byte*) key,
+ unique->tree.size_of_element) ? 1 : 0;
+}
+
+int unique_write_to_ptrs(gptr key, element_count count, Unique *unique)
+{
+ memcpy(unique->record_pointers, key, unique->tree.size_of_element);
+ unique->record_pointers+=unique->tree.size_of_element;
+ return 0;
+}
+
+Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
+ uint size, ulong max_in_memory_size_arg)
+ :max_in_memory_size(max_in_memory_size_arg),elements(0)
+{
+ my_b_clear(&file);
+ init_tree(&tree, max_in_memory_size / 16, 0, size, comp_func, 0, NULL, comp_func_fixed_arg);
+ /* If the following fail's the next add will also fail */
+ my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16);
+ max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size);
+ open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
+ MYF(MY_WME));
+}
+
+
+Unique::~Unique()
+{
+ close_cached_file(&file);
+ delete_tree(&tree);
+ delete_dynamic(&file_ptrs);
+}
+
+
+ /* Write tree to disk; clear tree */
+bool Unique::flush()
+{
+ BUFFPEK file_ptr;
+ elements+= tree.elements_in_tree;
+ file_ptr.count=tree.elements_in_tree;
+ file_ptr.file_pos=my_b_tell(&file);
+ if (tree_walk(&tree, (tree_walk_action) unique_write_to_file,
+ (void*) this, left_root_right) ||
+ insert_dynamic(&file_ptrs, (gptr) &file_ptr))
+ return 1;
+ delete_tree(&tree);
+ return 0;
+}
+
+
+/*
+ Modify the TABLE element so that when one calls init_records()
+ the rows will be read in priority order.
+*/
+
+bool Unique::get(TABLE *table)
+{
+ SORTPARAM sort_param;
+ table->found_records=elements+tree.elements_in_tree;
+
+ if (my_b_tell(&file) == 0)
+ {
+ /* Whole tree is in memory; Don't use disk if you don't need to */
+ if ((record_pointers=table->record_pointers= (byte*)
+ my_malloc(tree.size_of_element * tree.elements_in_tree, MYF(0))))
+ {
+ (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs,
+ this, left_root_right);
+ return 0;
+ }
+ }
+ /* Not enough memory; Save the result to file */
+ if (flush())
+ return 1;
+
+ IO_CACHE *outfile=table->io_cache;
+ BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
+ uint maxbuffer= file_ptrs.elements - 1;
+ uchar *sort_buffer;
+ my_off_t save_pos;
+ bool error=1;
+
+ /* Open cached file if it isn't open */
+ outfile=table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
+ MYF(MY_ZEROFILL));
+
+ if (!outfile || ! my_b_inited(outfile) &&
+ open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
+ MYF(MY_WME)))
+ return 1;
+ reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
+
+ bzero((char*) &sort_param,sizeof(sort_param));
+ sort_param.max_rows= elements;
+ sort_param.sort_form=table;
+ sort_param.sort_length=sort_param.ref_length=tree.size_of_element;
+ sort_param.keys= max_in_memory_size / sort_param.sort_length;
+ sort_param.not_killable=1;
+
+ if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
+ sort_param.sort_length,
+ MYF(0))))
+ return 1;
+ sort_param.unique_buff= sort_buffer+(sort_param.keys*
+ sort_param.sort_length);
+
+ /* Merge the buffers to one file, removing duplicates */
+ if (merge_many_buff(&sort_param,sort_buffer,file_ptr,&maxbuffer,&file))
+ goto err;
+ if (flush_io_cache(&file) ||
+ reinit_io_cache(&file,READ_CACHE,0L,0,0))
+ goto err;
+ if (merge_buffers(&sort_param, &file, outfile, sort_buffer, file_ptr,
+ file_ptr, file_ptr+maxbuffer,0))
+ goto err;
+ error=0;
+err:
+ x_free((gptr) sort_buffer);
+ if (flush_io_cache(outfile))
+ error=1;
+
+ /* Setup io_cache for reading */
+ save_pos=outfile->pos_in_file;
+ if (reinit_io_cache(outfile,READ_CACHE,0L,0,0))
+ error=1;
+ outfile->end_of_file=save_pos;
+ return error;
+}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index f7b040adebe..7d0201f75ae 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@
struct.
In the following functions FIELD * is an ordinary field-structure with
the following exeptions:
- sc_length,typepos,row,kol,dtype,regnr and field nead not to be set.
+ sc_length,typepos,row,kol,dtype,regnr and field need not to be set.
str is a (long) to record position where 0 is the first position.
*/
@@ -105,7 +105,7 @@ int rea_create_table(my_string file_name,
fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
(create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length);
- strnmov((char*) forminfo+47,create_info->comment ? create_info->comment : "",
+ strmake((char*) forminfo+47,create_info->comment ? create_info->comment : "",
60);
forminfo[46]=(uchar) strlen((char*)forminfo+47); // Length of comment
@@ -246,7 +246,7 @@ static uchar * pack_screens(List<create_field> &create_fields,
static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo)
{
uint key_parts,length;
- uchar *pos,*keyname_pos;
+ uchar *pos, *keyname_pos, *key_alg_pos;
KEY *key,*end;
KEY_PART_INFO *key_part,*key_part_end;
DBUG_ENTER("pack_keys");
@@ -290,11 +290,18 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo)
}
*(pos++)=0;
+ /* For MySQL 4.0; Store key algoritms last */
+ key_alg_pos= pos;
+ for (key=keyinfo ; key != end ; key++)
+ {
+ *(pos++)= (uchar) key->algorithm;
+ }
+
keybuff[0]=(uchar) key_count;
keybuff[1]=(uchar) key_parts;
length=(uint) (keyname_pos-keybuff);
int2store(keybuff+2,length);
- length=(uint) (pos-keyname_pos);
+ length=(uint) (key_alg_pos-keyname_pos);
int2store(keybuff+4,length);
DBUG_RETURN((uint) (pos-keybuff));
} /* pack_keys */
@@ -391,8 +398,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
int2store(forminfo+272,int_parts);
int2store(forminfo+274,int_length);
int2store(forminfo+276,time_stamp_pos);
- int2store(forminfo+278,80); /* Columns neaded */
- int2store(forminfo+280,22); /* Rows neaded */
+ int2store(forminfo+278,80); /* Columns needed */
+ int2store(forminfo+280,22); /* Rows needed */
int2store(forminfo+282,null_fields);
DBUG_RETURN(0);
} /* pack_header */
diff --git a/sql/unireg.h b/sql/unireg.h
index f8f5edd5156..2cfa709bbdc 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -46,6 +46,7 @@
#define MAX_DBKEY_LENGTH (FN_LEN*2+6) /* extra 4 bytes for slave tmp
* tables */
#define MAX_FIELD_NAME 34 /* Max colum name length +2 */
+#define MAX_SYS_VAR_LENGTH 32
#define MAX_KEY 32 /* Max used keys */
#define MAX_REF_PARTS 16 /* Max parts used as ref */
#define MAX_KEY_LENGTH 500 /* max possible key */
@@ -80,7 +81,7 @@
#define MYF_RW MYF(MY_WME+MY_NABP) /* Vid my_read & my_write */
#define SPECIAL_USE_LOCKS 1 /* Lock used databases */
-#define SPECIAL_NO_NEW_FUNC 2 /* Skipp new functions */
+#define SPECIAL_NO_NEW_FUNC 2 /* Skip new functions */
#define SPECIAL_NEW_FUNC 4 /* New nonstandard functions */
#define SPECIAL_WAIT_IF_LOCKED 8 /* Wait if locked database */
#define SPECIAL_SAME_DB_NAME 16 /* form name = file name */
@@ -122,6 +123,17 @@ bfill((A)->null_flags,(A)->null_bytes,255);\
#define TE_INFO_LENGTH 3
#define MTYP_NOEMPTY_BIT 128
+/*
+ * Minimum length pattern before Turbo Boyer-Moore is used
+ * for SELECT "text" LIKE "%pattern%", excluding the two
+ * wildcards in class Item_func_like.
+ */
+#define MIN_TURBOBM_PATTERN_LEN 3
+
+/* Defines for binary logging */
+
+#define BIN_LOG_HEADER_SIZE 4
+
/* Include prototypes for unireg */
#include "mysqld_error.h"
diff --git a/sql/violite.c b/sql/violite.c
deleted file mode 100644
index 37fee6fad3d..00000000000
--- a/sql/violite.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*
- Note that we can't have assertion on file descriptors; The reason for
- this is that during mysql shutdown, another thread can close a file
- we are working on. In this case we should just return read errors from
- the file descriptior.
-*/
-
-#include <global.h>
-
-#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
-
-#include <errno.h>
-#include <assert.h>
-#include <violite.h>
-#include <my_sys.h>
-#include <my_net.h>
-#include <m_string.h>
-#ifdef HAVE_POLL
-#include <sys/poll.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__FreeBSD__)
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
-#endif
-#endif
-
-#if defined(__EMX__) || defined(OS2)
-#define ioctlsocket ioctl
-#endif /* defined(__EMX__) */
-
-#if defined(MSDOS) || defined(__WIN__)
-#define O_NONBLOCK 1 /* For emulation of fcntl() */
-#endif
-#ifndef EWOULDBLOCK
-#define SOCKET_EWOULDBLOCK SOCKET_EAGAIN
-#endif
-
-#ifndef __WIN__
-#define HANDLE void *
-#endif
-
-struct st_vio
-{
- my_socket sd; /* my_socket - real or imaginary */
- HANDLE hPipe;
- my_bool localhost; /* Are we from localhost? */
- int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
- enum enum_vio_type type; /* Type of connection */
- char desc[30]; /* String description */
-};
-
-typedef void *vio_ptr;
-typedef char *vio_cstring;
-
-/*
- * Helper to fill most of the Vio* with defaults.
- */
-
-static void vio_reset(Vio* vio, enum enum_vio_type type,
- my_socket sd, HANDLE hPipe,
- my_bool localhost)
-{
- bzero((char*) vio, sizeof(*vio));
- vio->type = type;
- vio->sd = sd;
- vio->hPipe = hPipe;
- vio->localhost= localhost;
-}
-
-/* Open the socket or TCP/IP connection and read the fnctl() status */
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
-{
- Vio *vio;
- DBUG_ENTER("vio_new");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
- {
- vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc,
- (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
- vio->sd);
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
- vio->fcntl_mode = fcntl(sd, F_GETFL);
-#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
- /* Non blocking sockets doesn't work good on HPUX 11.0 */
- (void) ioctl(sd,FIOSNBIO,0);
-#endif
-#else /* !defined(__WIN__) && !defined(__EMX__) */
- {
- /* set to blocking mode by default */
- ulong arg=0, r;
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif
- }
- DBUG_RETURN(vio);
-}
-
-
-#ifdef __WIN__
-
-Vio *vio_new_win32pipe(HANDLE hPipe)
-{
- Vio *vio;
- DBUG_ENTER("vio_new_handle");
- if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
- {
- vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
- strmov(vio->desc, "named pipe");
- }
- DBUG_RETURN(vio);
-}
-
-#endif
-
-void vio_delete(Vio * vio)
-{
- /* It must be safe to delete null pointers. */
- /* This matches the semantics of C++'s delete operator. */
- if (vio)
- {
- if (vio->type != VIO_CLOSED)
- vio_close(vio);
- my_free((gptr) vio,MYF(0));
- }
-}
-
-int vio_errno(Vio *vio __attribute__((unused)))
-{
- return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
-}
-
-
-int vio_read(Vio * vio, gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_read");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosRead((HFILE)vio->hPipe, buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = recv(vio->sd, buf, size,0);
-#else
- errno=0; /* For linux */
- r = read(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_write(Vio * vio, const gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_write");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if ( vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosWrite((HFILE)vio->hPipe, (char*) buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = send(vio->sd, buf, size,0);
-#else
- r = write(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_blocking(Vio * vio, my_bool set_blocking_mode)
-{
- int r=0;
- DBUG_ENTER("vio_blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
-
- if (vio->sd >= 0)
- {
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- else
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- if (old_fcntl != vio->fcntl_mode)
- r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
- }
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN__) && !defined(__EMX__) */
-#ifndef __EMX__
- if (vio->type != VIO_TYPE_NAMEDPIPE)
-#endif
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- {
- arg = 0;
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- }
- else
- {
- arg = 1;
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- }
- if (old_fcntl != vio->fcntl_mode)
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif /* !defined(__WIN__) && !defined(__EMX__) */
- DBUG_RETURN(r);
-}
-
-my_bool
-vio_is_blocking(Vio * vio)
-{
- my_bool r;
- DBUG_ENTER("vio_is_blocking");
- r = !(vio->fcntl_mode & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int) r));
- DBUG_RETURN(r);
-}
-
-
-int vio_fastsend(Vio * vio __attribute__((unused)))
-{
- int r=0;
- DBUG_ENTER("vio_fastsend");
-
-#ifdef IPTOS_THROUGHPUT
- {
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
- sizeof(nodelay))) {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int vio_keepalive(Vio* vio, my_bool set_keep_alive)
-{
- int r=0;
- uint opt = 0;
- DBUG_ENTER("vio_keepalive");
- DBUG_PRINT("enter", ("sd=%d set_keep_alive=%d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- if (set_keep_alive)
- opt = 1;
- r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_should_retry(Vio * vio __attribute__((unused)))
-{
- int en = socket_errno;
- return en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK;
-}
-
-
-int vio_close(Vio * vio)
-{
- int r;
- DBUG_ENTER("vio_close");
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else if (vio->type != VIO_CLOSED)
-#endif /* __WIN__ */
- {
- r=0;
- if (shutdown(vio->sd,2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio->type= VIO_CLOSED;
- vio->sd= -1;
- DBUG_RETURN(r);
-}
-
-
-const char *vio_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_peer_addr(Vio * vio, char *buf)
-{
- DBUG_ENTER("vio_peer_addr");
- DBUG_PRINT("enter", ("sd=%d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(vio->remote.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-void vio_in_addr(Vio *vio, struct in_addr *in)
-{
- DBUG_ENTER("vio_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in)); /* This should never be executed */
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-
-/* Return 0 if there is data to be read */
-
-my_bool vio_poll_read(Vio *vio,uint timeout)
-{
-#ifndef HAVE_POLL
- return 0;
-#else
- struct pollfd fds;
- int res;
- DBUG_ENTER("vio_poll");
- fds.fd=vio->sd;
- fds.events=POLLIN;
- fds.revents=0;
- if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
- {
- DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
- }
- DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
-#endif
-}
-
-#endif /* HAVE_VIO */
diff --git a/strings/Makefile.am b/strings/Makefile.am
index d3bb4b54dcf..433b4398b61 100644
--- a/strings/Makefile.am
+++ b/strings/Makefile.am
@@ -22,7 +22,7 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X
if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s
-CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c llstr.c ctype.c strnlen.c
+CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c ctype.c strnlen.c
else
if ASSEMBLER_sparc
# These file MUST all be on the same line!! Otherwise automake
@@ -43,7 +43,7 @@ noinst_PROGRAMS = conf_to_src
# Default charset definitions
EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \
ctype-gb2312.c ctype-gbk.c ctype-sjis.c \
- ctype-tis620.c ctype-ujis.c \
+ ctype-tis620.c ctype-ujis.c ctype-latin1_de.c \
ctype_autoconf.c \
strto.c strings-x86.s \
longlong2str.c longlong2str-x86.s \
diff --git a/strings/atof.c b/strings/atof.c
index 1ce16027089..0e0aa598718 100644
--- a/strings/atof.c
+++ b/strings/atof.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
A quicker atof. About 2-10 times faster than standard atof on sparc.
@@ -23,7 +22,7 @@
Must be inited with init_my_atof to handle possibly overflows.
*/
-#include <global.h>
+#include <my_global.h>
#ifdef USE_MY_ATOF /* Skipp if we don't want it */
#include <m_ctype.h>
#include <floatingpoint.h>
diff --git a/strings/bchange.c b/strings/bchange.c
index 99066cf1e95..034dd3382e1 100644
--- a/strings/bchange.c
+++ b/strings/bchange.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : bchange.c
Author : Michael widenius
@@ -25,10 +24,11 @@
src in a buffer with tot_length bytes.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
-void bchange(register char *dst, uint old_length, register const char *src, uint new_length, uint tot_length)
+void bchange(register char *dst, uint old_length, register const char *src,
+ uint new_length, uint tot_length)
{
uint rest=tot_length-old_length;
if (old_length < new_length)
diff --git a/strings/bcmp.c b/strings/bcmp.c
index 3dce5025b64..64a6b72c443 100644
--- a/strings/bcmp.c
+++ b/strings/bcmp.c
@@ -1,30 +1,35 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
bcmp(s1, s2, len) returns 0 if the "len" bytes starting at "s1" are
identical to the "len" bytes starting at "s2", non-zero if they are
different.
- Now only used with purify.
+ Now only used with purify because purify gives wrong warnings when
+ comparing a shorter string with bcmp.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
+#ifdef HAVE_purify
+#undef bcmp
+#undef HAVE_BCMP
+#endif
+
#if !defined(bcmp) && !defined(HAVE_BCMP)
#if defined(MC68000) && defined(DS90)
@@ -46,14 +51,11 @@ uint len; /* 0 <= len <= 65535 */
#else
-#ifdef HAVE_purify
-int my_bcmp(s1, s2, len)
+#ifndef HAVE_purify
+int bcmp(register const char *s1,register const char *s2, register uint len)
#else
-int bcmp(s1, s2, len)
+int my_bcmp(register const char *s1,register const char *s2, register uint len)
#endif
- register const char *s1;
- register const char *s2;
- register uint len;
{
while (len-- != 0 && *s1++ == *s2++) ;
return len+1;
diff --git a/strings/bcopy-duff.c b/strings/bcopy-duff.c
index 2f5a709c3a0..5ac6a716dab 100644
--- a/strings/bcopy-duff.c
+++ b/strings/bcopy-duff.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define IFACTOR 4
diff --git a/strings/bfill.c b/strings/bfill.c
index 9f5db7201d0..85d21483b41 100644
--- a/strings/bfill.c
+++ b/strings/bfill.c
@@ -29,7 +29,7 @@
code is presented for your interest and amusement.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if !defined(bfill) && !defined(HAVE_BFILL)
diff --git a/strings/bmove.c b/strings/bmove.c
index 466bf74db75..09fe067adcd 100644
--- a/strings/bmove.c
+++ b/strings/bmove.c
@@ -36,7 +36,7 @@
code is presented for your interest and amusement.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if !defined(HAVE_BMOVE) && !defined(bmove)
diff --git a/strings/bmove512.c b/strings/bmove512.c
index 11dc282d05c..30ac4b744b6 100644
--- a/strings/bmove512.c
+++ b/strings/bmove512.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : bmove512.c
Author : Michael Widenius;
@@ -27,7 +26,7 @@
fastest way to move a mutiple of 512 byte.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifndef bmove512
diff --git a/strings/bmove_upp.c b/strings/bmove_upp.c
index af6575ebf41..5319cd9611a 100644
--- a/strings/bmove_upp.c
+++ b/strings/bmove_upp.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : bmove.c
Author : Michael widenius
@@ -24,7 +23,7 @@
"src-len" to the destination "dst-len" counting downwards.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if defined(MC68000) && defined(DS90)
diff --git a/strings/bzero.c b/strings/bzero.c
index cc628e05277..a2b780cb396 100644
--- a/strings/bzero.c
+++ b/strings/bzero.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : bzero.c
Author : Richard A. O'Keefe.
Michael Widenius; ifdef MC68000
diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c
index 89415d31820..22e04337b14 100644
--- a/strings/conf_to_src.c
+++ b/strings/conf_to_src.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* can't use -lmysys because this prog is used to create -lstrings */
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index cccf6730046..44f8a100897 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* This file is basicly usa7 character sets with some extra functions
@@ -28,7 +27,7 @@
* .configure. mbmaxlen_big5=2
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c
index b47eaf3a63f..70f95e0d5d6 100644
--- a/strings/ctype-czech.c
+++ b/strings/ctype-czech.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File strings/ctype-czech.c for MySQL.
@@ -67,7 +66,7 @@
#ifdef REAL_MYSQL
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#else
@@ -427,7 +426,7 @@ my_bool my_like_range_czech(const char *ptr,uint ptr_length,pchar escape,
*
* definition table reworked by Jaromir Dolecek <dolecek@ics.muni.cz>
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_czech[257] = {
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index df6f8c496bc..d05ca518283 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* This file is for Korean EUC charset, and created by powerm90@tinc.co.kr.
@@ -27,7 +26,7 @@
* .configure. mbmaxlen_euc_kr=2
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_euc_kr[257] =
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index a587d72905e..28717d98403 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is for Chinese EUC character sets (GB2312), and created by Miles Tsai (net-bull@126.com).
*/
@@ -25,7 +24,7 @@
* .configure. mbmaxlen_gb2312=2
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_gb2312[257] =
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index a5d55789bb8..9fccce175d8 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is for Chinese character sets GBK, created by Wei He
(hewei@mail.ied.ac.cn)
@@ -28,7 +27,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
@@ -2629,12 +2628,12 @@ int my_strnxfrm_gbk(uchar * dest, const uchar * src, int len, int srclen)
}
return srclen;
}
-
+
int my_strxfrm_gbk(uchar * dest, const uchar * src, int len)
{
return my_strnxfrm_gbk(dest,src,len,(uint) strlen((char*) src));
}
-
+
/*
** Calculate min_str and max_str that ranges a LIKE string.
** Arguments:
diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c
new file mode 100644
index 00000000000..01d377f91c3
--- /dev/null
+++ b/strings/ctype-latin1_de.c
@@ -0,0 +1,361 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ * This file is the latin1 character set with German sorting
+ *
+ * The modern sort order is used, where:
+ *
+ * 'ä' -> "ae"
+ * 'ö' -> "oe"
+ * 'ü' -> "ue"
+ * 'ß' -> "ss"
+ */
+
+/*
+ * This comment is parsed by configure to create ctype.c,
+ * so don't change it unless you know what you are doing.
+ *
+ * .configure. strxfrm_multiply_latin1_de=2
+ */
+
+#include <my_global.h>
+#include "m_string.h"
+#include "m_ctype.h"
+
+uchar ctype_latin1_de[] = {
+ 0,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
+ 16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16,
+ 16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2
+};
+
+uchar to_lower_latin1_de[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,215,248,249,250,251,252,253,254,223,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
+};
+
+uchar to_upper_latin1_de[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255
+};
+
+/*
+ * This is a simple latin1 mapping table, which maps all accented
+ * characters to their non-accented equivalents. Note: in this
+ * table, 'ä' is mapped to 'A', 'ÿ' is mapped to 'Y', etc. - all
+ * accented characters except the following are treated the same way.
+ * Ü, ü, Ö, ö, Ä, ä
+ */
+
+uchar sort_order_latin1_de[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 65, 65, 65, 65,196, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
+ 68, 78, 79, 79, 79, 79,214,215,216, 85, 85, 85,220, 89,222,223,
+ 65, 65, 65, 65,196, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
+ 68, 78, 79, 79, 79, 79,214,247,216, 85, 85, 85,220, 89,222, 89
+};
+
+#define L1_AE 196
+#define L1_ae 228
+#define L1_OE 214
+#define L1_oe 246
+#define L1_UE 220
+#define L1_ue 252
+#define L1_ss 223
+
+
+/*
+ Some notes about the following comparison rules:
+ By definition, my_strnncoll_latin_de must works exactly as if had called
+ my_strnxfrm_latin_de() on both strings and compared the result strings.
+
+ This means that:
+ Ä must also matches ÁE and Aè, because my_strxn_frm_latin_de() will convert
+ both to AE.
+
+ The other option would be to not do any accent removal in
+ sort_order_latin_de[] at all
+*/
+
+
+#define CHECK_S1_COMBO(ch1, ch2, str1, str1_end, res_if_str1_smaller, str2, fst, snd, accent) \
+ /* Invariant: ch1 == fst == sort_order_latin1_de[accent] && ch1 != ch2 */ \
+ if (ch2 != accent) \
+ { \
+ ch1= fst; \
+ goto normal; \
+ } \
+ if (str1 == str1_end) \
+ return res_if_str1_smaller; \
+ { \
+ int diff = (int) sort_order_latin1_de[*str1] - snd; \
+ if (diff) \
+ return diff*(-(res_if_str1_smaller)); \
+ /* They are equal (e.g., "Ae" == 'ä') */ \
+ str1++; \
+ }
+
+
+int my_strnncoll_latin1_de(const uchar * s1, int len1,
+ const uchar * s2, int len2)
+{
+ const uchar *e1 = s1 + len1;
+ const uchar *e2 = s2 + len2;
+
+ while (s1 < e1 && s2 < e2)
+ {
+ /*
+ Because sort_order_latin1_de doesn't convert 'Ä', Ü or ß we
+ can use it here.
+ */
+ uchar c1 = sort_order_latin1_de[*s1++];
+ uchar c2 = sort_order_latin1_de[*s2++];
+ if (c1 != c2)
+ {
+ switch (c1) {
+ case 'A':
+ CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'A', 'E', L1_AE);
+ break;
+ case 'O':
+ CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'O', 'E', L1_OE);
+ break;
+ case 'U':
+ CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'U', 'E', L1_UE);
+ break;
+ case 'S':
+ CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'S', 'S', L1_ss);
+ break;
+ case L1_AE:
+ CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'A', 'E', 'A');
+ break;
+ case L1_OE:
+ CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'O', 'E', 'O');
+ break;
+ case L1_UE:
+ CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'U', 'E', 'U');
+ break;
+ case L1_ss:
+ CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'S', 'S', 'S');
+ break;
+ default:
+ /*
+ Handle the case where 'c2' is a special character
+ If this is true, we know that c1 can't match this character.
+ */
+ normal:
+ switch (c2) {
+ case L1_AE:
+ return (int) c1 - (int) 'A';
+ case L1_OE:
+ return (int) c1 - (int) 'O';
+ case L1_UE:
+ return (int) c1 - (int) 'U';
+ case L1_ss:
+ return (int) c1 - (int) 'S';
+ default:
+ {
+ int diff= (int) c1 - (int) c2;
+ if (diff)
+ return diff;
+ }
+ break;
+ }
+ }
+ }
+ }
+ /* A simple test of string lengths won't work -- we test to see
+ * which string ran out first */
+ return s1 < e1 ? 1 : s2 < e2 ? -1 : 0;
+}
+
+
+int my_strnxfrm_latin1_de(uchar * dest, const uchar * src, int len, int srclen)
+{
+ const uchar *dest_orig = dest;
+ const uchar *de = dest + len;
+ const uchar *se = src + srclen;
+ while (src < se && dest < de)
+ {
+ uchar chr=sort_order_latin1_de[*src];
+ switch (chr) {
+ case L1_AE:
+ *dest++ = 'A';
+ if (dest < de)
+ *dest++ = 'E';
+ break;
+ case L1_OE:
+ *dest++ = 'O';
+ if (dest < de)
+ *dest++ = 'E';
+ break;
+ case L1_UE:
+ *dest++ = 'U';
+ if (dest < de)
+ *dest++ = 'E';
+ break;
+ case L1_ss:
+ *dest++ = 'S';
+ if (dest < de)
+ *dest++ = 'S';
+ break;
+ default:
+ *dest++= chr;
+ break;
+ }
+ ++src;
+ }
+ return dest - dest_orig;
+}
+
+
+int my_strcoll_latin1_de(const uchar * s1, const uchar * s2)
+{
+ /* XXX QQ: This should be fixed to not call strlen */
+ return my_strnncoll_latin1_de(s1, strlen((char*) s1),
+ s2, strlen((char*) s2));
+}
+
+int my_strxfrm_latin1_de(uchar * dest, const uchar * src, int len)
+{
+ /* XXX QQ: This should be fixed to not call strlen */
+ return my_strnxfrm_latin1_de(dest, src, len, strlen((char*) src));
+}
+
+/*
+ * Calculate min_str and max_str that ranges a LIKE string.
+ * Arguments:
+ * ptr IN: Pointer to LIKE string.
+ * ptr_length IN: Length of LIKE string.
+ * escape IN: Escape character in LIKE. (Normally '\').
+ * No escape characters should appear in min_str or max_str
+ * res_length IN: Length of min_str and max_str.
+ * min_str IN/OUT: Smallest case sensitive string that ranges LIKE.
+ * Should be space padded to res_length.
+ * max_str IN/OUT: Largest case sensitive string that ranges LIKE.
+ * Normally padded with the biggest character sort value.
+ * min_length OUT: Length of min_str without space padding.
+ * max_length OUT: Length of max_str without space padding.
+ *
+ * The function should return 0 if ok and 1 if the LIKE string can't be
+ * optimized !
+ */
+
+#define min_sort_char ((char) 0)
+#define max_sort_char ((char) 255)
+#define wild_one '_'
+#define wild_many '%'
+
+my_bool my_like_range_latin1_de(const char *ptr, uint ptr_length,
+ pchar escape, uint res_length,
+ char *min_str, char *max_str,
+ uint *min_length, uint *max_length)
+{
+ const char *end = ptr + ptr_length;
+ char *min_org = min_str;
+ char *min_end = min_str + res_length;
+
+ for (; ptr != end && min_str != min_end; ptr++)
+ {
+ if (*ptr == escape && ptr + 1 != end)
+ {
+ ptr++; /* Skip escape */
+ *min_str++ = *max_str++ = *ptr;
+ continue;
+ }
+ if (*ptr == wild_one) /* '_' in SQL */
+ {
+ *min_str++ = min_sort_char;
+ *max_str++ = max_sort_char;
+ continue;
+ }
+ if (*ptr == wild_many) /* '%' in SQL */
+ {
+ *min_length = (uint)(min_str - min_org);
+ *max_length = res_length;
+ do {
+ *min_str++ = ' '; /* Because if key compression */
+ *max_str++ = max_sort_char;
+ } while (min_str != min_end);
+ return 0;
+ }
+ *min_str++ = *max_str++ = *ptr;
+ }
+ *min_length = *max_length = (uint) (min_str - min_org);
+
+ /* Temporary fix for handling wild_one at end of string (key compression) */
+ {
+ char *tmp;
+ for (tmp= min_str ; tmp > min_org && tmp[-1] == '\0';)
+ *--tmp=' ';
+ }
+
+ while (min_str != min_end)
+ *min_str++ = *max_str++ = ' '; /* Because if key compression */
+ return 0;
+}
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 9f23d69eb12..5d5f64cc5fe 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -1,24 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is for Shift JIS charset, and created by tommy@valley.ne.jp.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index 1c0acc38e24..d5181dc4db0 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/*
Copyright (C) 2001 by Korakot Chaovavanich <korakot@iname.com> and
Apisilp Trunganont <apisilp@pantip.inet.co.th>
@@ -27,7 +43,7 @@
* .configure. strxfrm_multiply_tis620=4
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "m_string.h"
#include "m_ctype.h"
@@ -444,8 +460,8 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
const uchar* p = tstr;
uchar *outBuf;
-// uchar *pRight1, *pRight2, *pRight3, *pRight4;
-// uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4;
+/* uchar *pRight1, *pRight2, *pRight3, *pRight4; */
+/* uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4; */
uchar *pRight1, *pRight2, *pRight3;
uchar *pLeft1, *pLeft2, *pLeft3;
uint bufSize;
@@ -480,11 +496,11 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
*pRight1++ = t_ctype[p[1]][0];
*pRight2++ = t_ctype[p[1]][1];
*pRight3++ = t_ctype[p[1]][2];
-// *pRight4++ = t_ctype[p[1]][3];
+/* *pRight4++ = t_ctype[p[1]][3]; */
*pRight1++ = t_ctype[*p][0];
*pRight2++ = t_ctype[*p][1];
*pRight3++ = t_ctype[*p][2];
-// *pRight4++ = t_ctype[*p][3];
+/* *pRight4++ = t_ctype[*p][3]; */
len--;
p += 2;
} else {
@@ -501,17 +517,17 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
}
*pRight1++ = L2_BLANK;
*pRight2++ = L3_BLANK;
-// *pRight3++ = L4_BLANK;
+/* *pRight3++ = L4_BLANK; */
*pRight3++ = '\0';
-// *pRight4++ = '\0';
+/* *pRight4++ = '\0'; */
memcpy(pRight1, pLeft2, pRight2 - pLeft2);
pRight1 += pRight2 - pLeft2;
memcpy(pRight1, pLeft3, pRight3 - pLeft3);
-// pRight1 += pRight3 - pLeft3;
-// memcpy(pRight1, pLeft4, pRight4 - pLeft4);
+/* pRight1 += pRight3 - pLeft3; */
+/* memcpy(pRight1, pLeft4, pRight4 - pLeft4); */
free(pLeft2);
free(pLeft3);
-// free(pLeft4);
+/* free(pLeft4); */
return(outBuf);
}
@@ -603,22 +619,22 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
{
if (*ptr == escape && ptr+1 != end)
{
- ptr++; // Skipp escape
+ ptr++; /* Skipp escape */
*min_str++= *max_str++ = *ptr;
continue;
}
- if (*ptr == wild_one) // '_' in SQL
+ if (*ptr == wild_one) /* '_' in SQL */
{
- *min_str++='\0'; // This should be min char
+ *min_str++='\0'; /* This should be min char */
*max_str++=max_sort_chr;
continue;
}
- if (*ptr == wild_many) // '%' in SQL
+ if (*ptr == wild_many) /* '%' in SQL */
{
*min_length= (uint) (min_str - min_org);
*max_length=res_length;
do {
- *min_str++ = ' '; // Because if key compression
+ *min_str++ = ' '; /* Because if key compression */
*max_str++ = max_sort_chr;
} while (min_str != min_end);
return 0;
@@ -628,7 +644,7 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
*min_length= *max_length = (uint) (min_str - min_org);
while (min_str != min_end)
- *min_str++ = *max_str++ = ' '; // Because if key compression
+ *min_str++ = *max_str++ = ' '; /* Because if key compression */
return 0;
}
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index 5356978976f..650182bfda1 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -25,7 +25,7 @@
* .configure. mbmaxlen_ujis=3
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_ujis[257] =
diff --git a/strings/ctype.c b/strings/ctype.c
index e66c9771d78..8e3571b1b88 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -1,23 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
+#ifndef SCO
#include <m_string.h>
+#endif
/* generated by make, using conf_to_src */
#include "ctype_extra_sources.c"
diff --git a/strings/do_ctype.c b/strings/do_ctype.c
index e05926bf8d3..14ede6891da 100644
--- a/strings/do_ctype.c
+++ b/strings/do_ctype.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Prints case-convert and sort-convert tabell on stdout. This is used to
make _ctype.c easyer */
@@ -22,7 +21,7 @@
#undef DBUG_OFF
#endif
-#include <global.h>
+#include <my_global.h>
#include <ctype.h>
#include <my_sys.h>
#include "m_string.h"
diff --git a/strings/int2str.c b/strings/int2str.c
index 4003e8a6167..38e8a5182a3 100644
--- a/strings/int2str.c
+++ b/strings/int2str.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Defines: int2str(), itoa(), ltoa()
@@ -39,7 +38,7 @@
itoa assumes that 10 -base numbers are allways signed and other arn't.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
char NEAR _dig_vec[] =
diff --git a/strings/is_prefix.c b/strings/is_prefix.c
index d3f2b148de2..37d8002703b 100644
--- a/strings/is_prefix.c
+++ b/strings/is_prefix.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : is_prefix.c
Author : Michael Widenius
@@ -23,7 +22,7 @@
A empty t is allways a prefix.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
int is_prefix(register const char *s, register const char *t)
diff --git a/strings/llstr.c b/strings/llstr.c
index 470645a4f65..966b347ac7e 100644
--- a/strings/llstr.c
+++ b/strings/llstr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Defines: llstr();
@@ -26,7 +25,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
char *llstr(longlong value,char *buff)
diff --git a/strings/longlong2str.c b/strings/longlong2str.c
index 5c4eaf98c85..a991c57b4d9 100644
--- a/strings/longlong2str.c
+++ b/strings/longlong2str.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Defines: longlong2str();
@@ -39,7 +38,7 @@
itoa assumes that 10 -base numbers are allways signed and other arn't.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if defined(HAVE_LONG_LONG) && !defined(longlong2str) && !defined(HAVE_LONGLONG2STR)
diff --git a/strings/memcmp.c b/strings/memcmp.c
index 1bb8deaeac0..2f1e4e2ea1f 100644
--- a/strings/memcmp.c
+++ b/strings/memcmp.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* memcmp(lhs, rhs, len)
compares the two memory areas lhs[0..len-1] ?? rhs[0..len-1]. It
diff --git a/strings/memcpy.c b/strings/memcpy.c
index 4fc84fb6052..de79e43ae72 100644
--- a/strings/memcpy.c
+++ b/strings/memcpy.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
memcpy(dst, src, len)
diff --git a/strings/memset.c b/strings/memset.c
index 57c8fea5ebe..53383beb170 100644
--- a/strings/memset.c
+++ b/strings/memset.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : memset.c
Author : Richard A. O'Keefe.
Updated: 25 May 1984
@@ -27,7 +43,7 @@ char *memset(char *dst,int chr, int len)
char *memset(char *dst, register pchar chr, register int len)
{
register char *d;
-
+
for (d = dst; --len >= 0; *d++ = chr) ;
return dst;
}
diff --git a/strings/r_strinstr.c b/strings/r_strinstr.c
index 882a4eda412..76d310a3fda 100644
--- a/strings/r_strinstr.c
+++ b/strings/r_strinstr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Author : David
@@ -24,7 +23,7 @@
the pattern counted from the begining of the string.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uint r_strinstr(reg1 my_string str,int from, reg4 my_string search)
diff --git a/strings/str2int.c b/strings/str2int.c
index 55fcd56adb9..58669287473 100644
--- a/strings/str2int.c
+++ b/strings/str2int.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
str2int(src, radix, lower, upper, &val)
@@ -39,7 +38,7 @@
call has no problems.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
#include "my_sys.h" /* defines errno */
@@ -50,7 +49,8 @@
X >= 'a' && X <= 'z' ? X-'a'+10 :\
'\177')
-char *str2int(register const char *src, register int radix, long int lower, long int upper, long int *val)
+char *str2int(register const char *src, register int radix, long int lower,
+ long int upper, long int *val)
{
int sign; /* is number negative (+1) or positive (-1) */
int n; /* number of digits yet to be converted */
diff --git a/strings/str_test.c b/strings/str_test.c
index bd54bc6d806..bef48814f6d 100644
--- a/strings/str_test.c
+++ b/strings/str_test.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Test of all stringfunktions that is coded in assembler */
-#include <global.h>
+#include <my_global.h>
#include <stdarg.h>
#include "m_string.h"
diff --git a/strings/strappend.c b/strings/strappend.c
index d5defaeb0bf..9912bd5197d 100644
--- a/strings/strappend.c
+++ b/strings/strappend.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strappend.c
Author : Monty
@@ -25,7 +24,7 @@
trunked. The des+len character is allways set to NULL.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
@@ -39,5 +38,3 @@ void strappend(register char *s, uint len, pchar fill)
while (s<endpos) *(s++) = fill;
*(endpos) = '\0';
} /* strappend */
-
-
diff --git a/strings/strcat.c b/strings/strcat.c
index 699729cd7b5..3c571514701 100644
--- a/strings/strcat.c
+++ b/strings/strcat.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strcat.c
Author : Richard A. O'Keefe.
Updated: 10 April 1984
diff --git a/strings/strcend.c b/strings/strcend.c
index 246b81d7f7b..a3f00a1057b 100644
--- a/strings/strcend.c
+++ b/strings/strcend.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strcend.c
Author : Michael Widenius: ifdef MC68000
@@ -24,7 +23,7 @@
occurs, or a pointer to the end-null of s if c does not occur in s.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if defined(MC68000) && defined(DS90)
diff --git a/strings/strchr.c b/strings/strchr.c
index ef117d85635..3f1a569c296 100644
--- a/strings/strchr.c
+++ b/strings/strchr.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strchr.c
Author : Richard A. O'Keefe.
Michael Widenius: ifdef MC68000
diff --git a/strings/strcmp.c b/strings/strcmp.c
index d911b2daa17..d673c035dbc 100644
--- a/strings/strcmp.c
+++ b/strings/strcmp.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strcmp.c
Author : Richard A. O'Keefe.
Updated: 10 April 1984
diff --git a/strings/strcont.c b/strings/strcont.c
index 5c7d5d2e55f..1d89be89517 100644
--- a/strings/strcont.c
+++ b/strings/strcont.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strcont.c
Author : Monty
@@ -26,7 +25,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
my_string strcont(reg1 const char *str,reg2 const char *set)
diff --git a/strings/strend.c b/strings/strend.c
index 3affb9bd5f6..0e9c0333fc8 100644
--- a/strings/strend.c
+++ b/strings/strend.c
@@ -27,7 +27,7 @@
Beware: the asm version works only if strlen(s) < 65535.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if VaxAsm
diff --git a/strings/strfill.c b/strings/strfill.c
index ef0ccb567d1..0ef56a67706 100644
--- a/strings/strfill.c
+++ b/strings/strfill.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strfill.c
Author : Monty
@@ -25,7 +24,7 @@
strfill() returns pointer to dest+len;
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
my_string strfill(my_string s,uint len,pchar fill)
diff --git a/strings/strings-not-used.h b/strings/strings-not-used.h
index fa4dff318f5..e0dc1eac3a5 100644
--- a/strings/strings-not-used.h
+++ b/strings/strings-not-used.h
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strings.h
Author : Richard A. O'Keefe.
Updated: 1 June 1984
@@ -13,7 +29,7 @@
#ifndef NullS
-#include <global.h> /* Define standar vars */
+#include <my_global.h> /* Define standar vars */
#include "m_string.h"
#define NUL '\0'
diff --git a/strings/strinstr.c b/strings/strinstr.c
index e1d502f4004..1c814d19d47 100644
--- a/strings/strinstr.c
+++ b/strings/strinstr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strinstr.c
Author : Monty & David
@@ -27,7 +26,7 @@
char is 1.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uint strinstr(reg1 const char *str,reg4 const char *search)
diff --git a/strings/strlen.c b/strings/strlen.c
index c142a7f2b14..b9be374fa6e 100644
--- a/strings/strlen.c
+++ b/strings/strlen.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strlen.c
Author : Richard A. O'Keefe. / Monty
Michael Widenius; ifdef MC68000
diff --git a/strings/strmake.c b/strings/strmake.c
index 66a230338a1..2e384fc168a 100644
--- a/strings/strmake.c
+++ b/strings/strmake.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strmake.c
Author : Michael Widenius
@@ -26,7 +25,7 @@
strmake() returns pointer to closing null
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifdef BAD_STRING_COMPILER
diff --git a/strings/strmov.c b/strings/strmov.c
index 8f5beb41f41..507c2b6d997 100644
--- a/strings/strmov.c
+++ b/strings/strmov.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
strmov(dst, src) moves all the characters of src (including the
@@ -23,7 +22,7 @@
into dst, which seems useful.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifdef BAD_STRING_COMPILER
diff --git a/strings/strnlen.c b/strings/strnlen.c
index 3d625f7d48a..fc8879b3a41 100644
--- a/strings/strnlen.c
+++ b/strings/strnlen.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strnlen.c
Author : Michael Widenius
@@ -22,7 +21,7 @@
strnlen(s, len) returns the length of s or len if s is longer than len.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifndef HAVE_STRNLEN
diff --git a/strings/strnmov.c b/strings/strnmov.c
index ffc4a62f75e..362f3d6c4a8 100644
--- a/strings/strnmov.c
+++ b/strings/strnmov.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
strnmov(dst,src,length) moves length characters, or until end, of src to
@@ -22,7 +21,7 @@
truncated.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
char *strnmov(register char *dst, register const char *src, uint n)
diff --git a/strings/strrchr.c b/strings/strrchr.c
index 5a045ac3740..fb588c015f2 100644
--- a/strings/strrchr.c
+++ b/strings/strrchr.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strrchr.c
Author : Richard A. O'Keefe.
Updated: 10 April 1984
diff --git a/strings/strstr.c b/strings/strstr.c
index 01b29db0068..ca845568ddb 100644
--- a/strings/strstr.c
+++ b/strings/strstr.c
@@ -27,7 +27,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifndef HAVE_STRSTR
diff --git a/strings/strto.c b/strings/strto.c
index d3392c794e9..84dccbcbeb8 100644
--- a/strings/strto.c
+++ b/strings/strto.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
strtol,strtoul,strtoll,strtoull
@@ -36,7 +35,7 @@
it can be compiled with the UNSIGNED and/or LONGLONG flag set
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
#include "my_sys.h" /* defines errno */
diff --git a/strings/strtol.c b/strings/strtol.c
index 87fe0d22cf3..10d7f8f9da6 100644
--- a/strings/strtol.c
+++ b/strings/strtol.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This defines strtol() if neaded */
-#include <global.h>
+#include <my_global.h>
#if !defined(MSDOS) && !defined(HAVE_STRTOL) && !defined(__WIN__)
#include "strto.c"
#endif
diff --git a/strings/strtoll.c b/strings/strtoll.c
index 678c28649ef..8d0ba21d576 100644
--- a/strings/strtoll.c
+++ b/strings/strtoll.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This is defines strtoll() if neaded */
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#if !defined(HAVE_STRTOLL) && defined(HAVE_LONG_LONG)
#define USE_LONGLONG
diff --git a/strings/strtoul.c b/strings/strtoul.c
index e49a9ebea6a..00e1f820942 100644
--- a/strings/strtoul.c
+++ b/strings/strtoul.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This is defines strtoul() if neaded */
-#include <global.h>
+#include <my_global.h>
#if !defined(MSDOS) && !defined(HAVE_STRTOUL)
#define USE_UNSIGNED
#include "strto.c"
diff --git a/strings/strtoull.c b/strings/strtoull.c
index 74dab95b801..25201e546ce 100644
--- a/strings/strtoull.c
+++ b/strings/strtoull.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This is defines strtoull() */
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG)
#define USE_UNSIGNED
diff --git a/strings/strxmov.c b/strings/strxmov.c
index 3ef120a691e..fe1e88c13d0 100644
--- a/strings/strxmov.c
+++ b/strings/strxmov.c
@@ -30,7 +30,7 @@
character pointer, or not the same bit pattern as NullS.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include <stdarg.h>
diff --git a/strings/strxnmov.c b/strings/strxnmov.c
index ec3b6fe71e8..3ef0e57650c 100644
--- a/strings/strxnmov.c
+++ b/strings/strxnmov.c
@@ -37,7 +37,7 @@
needed.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include <stdarg.h>
diff --git a/strings/t_ctype.h b/strings/t_ctype.h
index 6699244c1f4..ac1fa408c0e 100644
--- a/strings/t_ctype.h
+++ b/strings/t_ctype.h
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/*
Copyright (C) 1998, 1999 by Pruet Boonma, all rights reserved.
Copyright (C) 1998 by Theppitak Karoonboonyanan, all rights reserved.
@@ -125,7 +141,7 @@ enum l1_symbols {
L1_SARA_AI_MAIMUAN,
L1_SARA_AI_MAIMALAI
};
-
+
// level 2 symbols & order
enum l2_symbols {
L2_BLANK = TOT_LEVELS,
@@ -139,7 +155,7 @@ enum l2_symbols {
L2_TONE3,
L2_TONE4
};
-
+
// level 3 symbols & order
enum l3_symbols {
L3_BLANK = TOT_LEVELS,
diff --git a/strings/udiv.c b/strings/udiv.c
index 07af323a706..25f3f4685f0 100644
--- a/strings/udiv.c
+++ b/strings/udiv.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Do udiv and urem if machine dosn't have it */
-#include <global.h>
+#include <my_global.h>
#include <math.h>
unsigned long udiv(long unsigned int a, long unsigned int b)
diff --git a/support-files/binary-configure.sh b/support-files/binary-configure.sh
index 682ea570b25..107f468bffc 100644
--- a/support-files/binary-configure.sh
+++ b/support-files/binary-configure.sh
@@ -20,5 +20,5 @@ then
echo "Starting the mysqld server. You can test that it is up and running"
echo "with the command:"
echo "./bin/mysqladmin version"
- ./bin/safe_mysqld &
+ ./bin/mysqld_safe &
fi
diff --git a/support-files/build-tags b/support-files/build-tags
new file mode 100755
index 00000000000..d5f9fbf5100
--- /dev/null
+++ b/support-files/build-tags
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+rm -f TAGS
+filter='\.cc$\|\.c$\|\.h$\|\.yy$'
+files=`bk -r sfiles -gU | grep $filter `
+for f in $files ;
+do
+ etags -o TAGS --append $f
+done
diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh
index 6c204abd4c7..50a14b0fc96 100644
--- a/support-files/my-huge.cnf.sh
+++ b/support-files/my-huge.cnf.sh
@@ -35,8 +35,23 @@ set-variable = thread_cache=8
# Try number of CPU's*2 for thread_concurrency
set-variable = thread_concurrency=8
set-variable = myisam_sort_buffer_size=64M
-log-bin
-server-id = 1
+
+# Replication Master Server (default)
+log-bin # required for replication
+server-id = 1 # required unique id between 1 and 2^32 - 1
+ # defaults to 1 if master-host is not set
+ # but will not function as a master if omitted
+
+# Replication Slave Server (comment out master section to use this)
+#master-host = # MUST BE SET
+#master-user = # MUST BE SET
+#master-password = # MUST BE SET
+#master-port = # optional--defaults to 3306
+#log-bin # not required for slaves, but recommended
+#server-id = 2 # required unique id between 2 and 2^32 - 1
+ # (and different from the master)
+ # defaults to 2 if master-host is set
+ # but will not function as a slave if omitted
# Point the following paths to different dedicated disks
#tmpdir = /tmp/
diff --git a/support-files/mysql-max.spec.sh b/support-files/mysql-max.spec.sh
index 49f131154c0..5c4b16f0e9d 100644
--- a/support-files/mysql-max.spec.sh
+++ b/support-files/mysql-max.spec.sh
@@ -208,7 +208,7 @@ chmod -R og-rw $mysql_datadir/mysql
# Restart in the same way that mysqld will be started normally.
/etc/rc.d/init.d/mysql start
-# Allow safe_mysqld to start mysqld and print a message before we exit
+# Allow mysqld_safe to start mysqld and print a message before we exit
sleep 2
%preun
@@ -244,7 +244,7 @@ fi
%attr(755, root, root) /usr/bin/perror
%attr(755, root, root) /usr/bin/replace
%attr(755, root, root) /usr/bin/resolveip
-%attr(755, root, root) /usr/bin/safe_mysqld
+%attr(755, root, root) /usr/bin/mysqld_safe
%attr(755, root, root) /usr/bin/mysqld_multi
%attr(755, root, root) /usr/bin/my_print_defaults
diff --git a/support-files/mysql-multi.server.sh b/support-files/mysql-multi.server.sh
index 6c940630427..31020029354 100644
--- a/support-files/mysql-multi.server.sh
+++ b/support-files/mysql-multi.server.sh
@@ -133,14 +133,14 @@ case "$mode" in
'start')
# Start daemon
- if test -x $bindir/safe_mysqld
+ if test -x $bindir/mysqld_safe
then
# We only need to specify datadir and pid-file here and we
# get all other instance-specific config from $datadir/my.cnf.
# We have to explicitly pass --defaults-extra-file because it
# reads the config files before the command line options.
- # Also it must be first because of the way safe_mysqld works.
- $bindir/safe_mysqld --defaults-extra-file=$datadir/my.cnf \
+ # Also it must be first because of the way mysqld_safe works.
+ $bindir/mysqld_safe --defaults-extra-file=$datadir/my.cnf \
--datadir=$datadir --pid-file=$pid_file &
# Make lock for RedHat / SuSE
if test -d /var/lock/subsys
@@ -148,7 +148,7 @@ case "$mode" in
touch /var/lock/subsys/mysql
fi
else
- echo "Can't execute $bindir/safe_mysqld"
+ echo "Can't execute $bindir/mysqld_safe"
fi
;;
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index 62381ccf0d3..48bf004d758 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -13,6 +13,18 @@
# chkconfig: 2345 90 90
# description: A very fast and reliable SQL database engine.
+# Comments to support LSB init script conventions
+### BEGIN INIT INFO
+# Provides: mysql
+# Required-Start: $local_fs $network $remote_fs
+# Required-Stop: $local_fs $network $remote_fs
+# Default-Start: 3 5
+# Default-Stop: 3 5
+# Short-Description: start and stop MySLQ
+# Description: MySQL is a very fast and reliable SQL database engine.
+### END INIT INFO
+
+
# The following variables are only set for letting mysql.server find things.
# If you want to affect other MySQL variables, you should make your changes
# in the /etc/my.cnf or other configuration files.
@@ -100,25 +112,25 @@ case "$mode" in
'start')
# Start daemon
- if test -x $bindir/safe_mysqld
+ if test -x $bindir/mysqld_safe
then
# Give extra arguments to mysqld with the my.cnf file. This script may
# be overwritten at next upgrade.
- $bindir/safe_mysqld --datadir=$datadir --pid-file=$pid_file &
+ $bindir/mysqld_safe --datadir=$datadir --pid-file=$pid_file &
# Make lock for RedHat / SuSE
if test -w /var/lock/subsys
then
touch /var/lock/subsys/mysql
fi
else
- echo "Can't execute $bindir/safe_mysqld"
+ echo "Can't execute $bindir/mysqld_safe"
fi
;;
'stop')
# Stop daemon. We use a signal here to avoid having to know the
# root password.
- if test -f "$pid_file"
+ if test -s "$pid_file"
then
mysqld_pid=`cat $pid_file`
echo "Killing mysqld with pid $mysqld_pid"
@@ -128,7 +140,7 @@ case "$mode" in
sleep 1
while [ -s $pid_file -a "$flags" != aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ]
do
- [ -z "$flags" ] && echo "Wait for mysqld to exit\c" || echo ".\c"
+ [ -z "$flags" ] && echo -n "Wait for mysqld to exit" || echo -n "."
flags=a$flags
sleep 1
done
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 4c37ff31a0b..77c1b467c0f 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -1,12 +1,12 @@
%define mysql_version @VERSION@
%define shared_lib_version @SHARED_LIB_VERSION@
-%define release 1
+%define release 0
%define mysqld_user mysql
%define see_base For a description of MySQL see the base MySQL RPM or http://www.mysql.com
Name: MySQL
-Summary: MySQL: a very fast and reliable SQL database engine
+Summary: MySQL: a very fast and reliable SQL database server
Group: Applications/Databases
Summary(pt_BR): MySQL: Um servidor SQL rápido e confiável.
Group(pt_BR): Aplicações/Banco_de_Dados
@@ -18,54 +18,39 @@ Icon: mysql.gif
URL: http://www.mysql.com/
Packager: Lenz Grimmer <lenz@mysql.com>
Vendor: MySQL AB
+Requires: fileutils sh-utils
Provides: msqlormysql MySQL-server mysql
Obsoletes: mysql
# Think about what you use here since the first step is to
# run a rm -rf
-BuildRoot: /var/tmp/mysql
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
# From the manual
%description
-MySQL is a true multi-user, multi-threaded SQL (Structured Query
-Language) database server. MySQL is a client/server implementation
-that consists of a server daemon (mysqld) and many different client
-programs/libraries.
-
-The main goals of MySQL are speed, robustness and ease of use. MySQL
-was originally developed because we needed a SQL server that could
-handle very big databases with magnitude higher speed than what any
-database vendor could offer to us. And since we did not need all the
-features that made their server slow we made our own. We have now been
-using MySQL since 1996 in a environment with more than 40 databases,
-10,000 tables, of which more than 500 have more than 7 million
-rows. This is about 200G of data.
-
-The base upon which MySQL is built is a set of routines that have been
-used in a highly demanding production environment for many
-years. While MySQL is still in development, it already offers a rich
-and highly useful function set.
-
-See the documentation for more information.
-
-%description -l pt_BR
-O MySQL é um servidor de banco de dados SQL realmente multiusuário e\
-multi-tarefa. A linguagem SQL é a mais popular linguagem para banco de\
-dados no mundo. O MySQL é uma implementação cliente/servidor que\
-consiste de um servidor chamado mysqld e diversos\
-programas/bibliotecas clientes. Os principais objetivos do MySQL são:\
-velocidade, robustez e facilidade de uso. O MySQL foi originalmente\
-desenvolvido porque nós na Tcx precisávamos de um servidor SQL que\
-pudesse lidar com grandes bases de dados e com uma velocidade muito\
-maior do que a que qualquer vendedor podia nos oferecer. Estamos\
-usando\
-o MySQL desde 1996 em um ambiente com mais de 40 bases de dados com 10.000\
-tabelas, das quais mais de 500 têm mais de 7 milhões de linhas. Isto é o\
-equivalente a aproximadamente 50G de dados críticos. A base da construção do\
-MySQL é uma série de rotinas que foram usadas em um ambiente de produção com\
-alta demanda por muitos anos. Mesmo o MySQL estando ainda em desenvolvimento,\
-ele já oferece um conjunto de funções muito ricas e úteis. Veja a documentação\
-para maiores informações.
+The MySQL(TM) software delivers a very fast, multi-threaded, multi-user,
+and robust SQL (Structured Query Language) database server. MySQL Server
+is intended for mission-critical, heavy-load production systems as well
+as for embedding into mass-deployed software. MySQL is a trademark of
+MySQL AB.
+
+The MySQL software has Dual Licensing, which means you can use the MySQL
+software free of charge under the GNU General Public License
+(http://www.gnu.org/licenses/). You can also purchase commercial MySQL
+licenses from MySQL AB if you do not wish to be bound by the terms of
+the GPL. See the chapter "Licensing and Support" in the manual for
+further info.
+
+The MySQL web site (http://www.mysql.com/) provides the latest
+news and information about the MySQL software. Also please see the
+documentation and the manual for more information.
+
+This package includes the MySQL server binary (statically linked,
+compiled with InnoDB support) as well as related utilities to run
+and administrate a MySQL server.
+
+If you want to access and work with the database, you have to install
+package "MySQL-client" as well!
%package client
Release: %{release}
@@ -86,7 +71,7 @@ Este pacote contém os clientes padrão para o MySQL.
%package bench
Release: %{release}
-Requires: MySQL-client MySQL-DBI-perl-bin perl
+Requires: %{name}-client MySQL-DBI-perl-bin perl
Summary: MySQL - Benchmarks and test system
Group: Applications/Databases
Summary(pt_BR): MySQL - Medições de desempenho
@@ -104,7 +89,7 @@ Este pacote contém medições de desempenho de scripts e dados do MySQL.
%package devel
Release: %{release}
-Requires: MySQL-client
+Requires: %{name}-client
Summary: MySQL - Development header files and libraries
Group: Applications/Databases
Summary(pt_BR): MySQL - Medições de desempenho
@@ -133,15 +118,40 @@ languages and applications need to dynamically load and use MySQL.
%package Max
Release: %{release}
-Summary: MySQL - server with Berkeley DB and Innodb support
+Summary: MySQL - server with Berkeley DB, OpenSSL and UDF support
Group: Applications/Databases
Provides: mysql-Max
Obsoletes: mysql-Max
%description Max
-Optional MySQL server binary that supports features
-like transactional tables. To active this binary, just install this
-package after the MySQL package.
+Optional MySQL server binary that supports additional features like
+Berkeley DB, OpenSSL support and User Defined Functions (UDF).
+To activate this binary, just install this package in addition to
+the standard MySQL package.
+
+Please note that this is a dynamically linked binary!
+
+%package embedded
+Release: %{release}
+Requires: %{name}-devel
+Summary: MySQL - embedded library
+Group: Applications/Databases
+Summary(pt_BR): MySQL - Medições de desempenho
+Group(pt_BR): Aplicações/Banco_de_Dados
+Obsoletes: mysql-embedded
+
+%description embedded
+This package contains the MySQL server as an embedded library.
+
+The embedded MySQL server library makes it possible to run a
+full-featured MySQL server inside the client application.
+The main benefits are increased speed and more simple management
+for embedded applications.
+
+The API is identical for the embedded MySQL version and the
+client/server version.
+
+%{see_base}
%prep
%setup -n mysql-%{mysql_version}
@@ -174,9 +184,11 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-/bin:/usr/bin}\" \
--sysconfdir=/etc \
--datadir=/usr/share \
--localstatedir=/var/lib/mysql \
- --infodir=/usr/info \
+ --infodir=%{_infodir} \
--includedir=/usr/include \
- --mandir=/usr/man \
+ --mandir=%{_mandir} \
+ --with-embedded-server \
+ --enable-thread-safe-client \
--with-comment=\"Official MySQL RPM\";
# Add this for more debugging support
# --with-debug
@@ -201,12 +213,9 @@ fi
RBR=$RPM_BUILD_ROOT
MBD=$RPM_BUILD_DIR/mysql-%{mysql_version}
-if test -z "$RBR" -o "$RBR" = "/"
-then
- echo "RPM_BUILD_ROOT has insecure value"
- exit 1
-fi
-rm -rf $RBR
+
+# Clean up the BuildRoot first
+[ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR;
mkdir -p $RBR
#
@@ -215,10 +224,15 @@ mkdir -p $RBR
PATH=${MYSQL_BUILD_PATH:-/bin:/usr/bin}
export PATH
-# We need to build shared libraries separate from mysqld-max because we
-# are using --with-other-libc
+# Build the 4.0 Max binary (includes BDB and OpenSSL and therefore
+# cannot be linked statically against the patched glibc)
-BuildMySQL "--disable-shared $USE_OTHER_LIBC_DIR --with-berkeley-db --with-innodb --with-mysqld-ldflags='-all-static' --with-server-suffix='-Max'"
+BuildMySQL "--enable-shared \
+ --with-berkeley-db \
+ --with-innodb \
+ --with-openssl \
+ --with-vio \
+ --with-server-suffix='-Max'"
# Save everything for debug
# tar cf $RBR/all.tar .
@@ -227,13 +241,7 @@ BuildMySQL "--disable-shared $USE_OTHER_LIBC_DIR --with-berkeley-db --with-innod
mv sql/mysqld sql/mysqld-max
nm --numeric-sort sql/mysqld-max > sql/mysqld-max.sym
-# Save manual to avoid rebuilding
-mv Docs/manual.ps Docs/manual.ps.save
-make distclean
-mv Docs/manual.ps.save Docs/manual.ps
-
-#now build and save shared libraries
-BuildMySQL "--enable-shared --enable-thread-safe-client --without-server "
+# Save libraries
(cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*)
(cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*)
@@ -245,32 +253,36 @@ mv Docs/manual.ps.save Docs/manual.ps
# RPM:s destroys Makefile.in files, so we generate them here
automake
-BuildMySQL "--disable-shared" \
- "--with-mysqld-ldflags='-all-static'" \
- "--with-client-ldflags='-all-static'" \
- "$USE_OTHER_LIBC_DIR" \
- "--without-berkeley-db --without-innodb"
+# Now build the statically linked 4.0 binary (which includes InnoDB)
+BuildMySQL "--disable-shared \
+ --with-mysqld-ldflags='-all-static' \
+ --with-client-ldflags='-all-static' \
+ $USE_OTHER_LIBC_DIR \
+ --without-berkeley-db \
+ --with-innodb \
+ --without-vio \
+ --without-openssl"
nm --numeric-sort sql/mysqld > sql/mysqld.sym
%install -n mysql-%{mysql_version}
RBR=$RPM_BUILD_ROOT
MBD=$RPM_BUILD_DIR/mysql-%{mysql_version}
+
# Ensure that needed directories exists
install -d $RBR/etc/{logrotate.d,rc.d/init.d}
install -d $RBR/var/lib/mysql/mysql
-install -d $RBR/usr/share/sql-bench
-install -d $RBR/usr/share/mysql-test
-install -d $RBR/usr/{sbin,share,man,include}
-install -d $RBR/usr/doc/MySQL-%{mysql_version}
-install -d $RBR/usr/lib
-# Make install
-make install DESTDIR=$RBR benchdir_root=/usr/share/
+install -d $RBR/usr/share/{sql-bench,mysql-test}
+install -d $RBR%{_mandir}
+install -d $RBR/usr/{sbin,lib,include}
+
+# Install all binaries stripped
+make install-strip DESTDIR=$RBR benchdir_root=/usr/share/
# Install shared libraries (Disable for architectures that don't support it)
(cd $RBR/usr/lib; tar xf $RBR/shared-libs.tar)
# install saved mysqld-max
-install -m755 $MBD/sql/mysqld-max $RBR/usr/sbin/mysqld-max
+install -s -m755 $MBD/sql/mysqld-max $RBR/usr/sbin/mysqld-max
# install symbol files ( for stack trace resolution)
install -m644 $MBD/sql/mysqld-max.sym $RBR/usr/lib/mysql/mysqld-max.sym
@@ -280,18 +292,6 @@ install -m644 $MBD/sql/mysqld.sym $RBR/usr/lib/mysql/mysqld.sym
install -m644 $MBD/support-files/mysql-log-rotate $RBR/etc/logrotate.d/mysql
install -m755 $MBD/support-files/mysql.server $RBR/etc/rc.d/init.d/mysql
-# Install docs
-install -m644 $RPM_BUILD_DIR/mysql-%{mysql_version}/Docs/mysql.info \
- $RBR/usr/info/mysql.info
-for file in README COPYING COPYING.LIB Docs/manual_toc.html Docs/manual.html \
- Docs/manual.txt Docs/manual.texi Docs/manual.ps \
- support-files/my-huge.cnf support-files/my-large.cnf \
- support-files/my-medium.cnf support-files/my-small.cnf
-do
- b=`basename $file`
- install -m644 $MBD/$file $RBR/usr/doc/MySQL-%{mysql_version}/$b
-done
-
%pre
if test -x /etc/rc.d/init.d/mysql
then
@@ -358,32 +358,50 @@ fi
# We do not remove the mysql user since it may still own a lot of
# database files.
+# Clean up the BuildRoot
+%clean
+[ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR;
+
%files
-%attr(-, root, root) %doc /usr/doc/MySQL-%{mysql_version}/
+%defattr(755 root, root)
+
+%doc %attr(644, root, root) COPYING COPYING.LIB README
+%doc %attr(644, root, root) Docs/manual.{html,ps,texi,txt} Docs/manual_toc.html
+%doc %attr(644, root, root) support-files/my-*.cnf
+
+%doc %attr(644, root, root) %{_infodir}/mysql.info*
+
+%doc %attr(644, root, man) %{_mandir}/man1/isamchk.1*
+%doc %attr(644, root, man) %{_mandir}/man1/isamlog.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqld.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1*
+%doc %attr(644, root, man) %{_mandir}/man1/perror.1*
+%doc %attr(644, root, man) %{_mandir}/man1/replace.1*
%attr(755, root, root) /usr/bin/isamchk
%attr(755, root, root) /usr/bin/isamlog
-%attr(755, root, root) /usr/bin/pack_isam
+%attr(755, root, root) /usr/bin/my_print_defaults
%attr(755, root, root) /usr/bin/myisamchk
%attr(755, root, root) /usr/bin/myisamlog
%attr(755, root, root) /usr/bin/myisampack
-%attr(755, root, root) /usr/bin/mysql_fix_privilege_tables
%attr(755, root, root) /usr/bin/mysql_convert_table_format
+%attr(755, root, root) /usr/bin/mysql_explain_log
+%attr(755, root, root) /usr/bin/mysql_fix_privilege_tables
%attr(755, root, root) /usr/bin/mysql_install_db
%attr(755, root, root) /usr/bin/mysql_setpermission
%attr(755, root, root) /usr/bin/mysql_zap
%attr(755, root, root) /usr/bin/mysqlbug
-%attr(755, root, root) /usr/bin/mysqltest
+%attr(755, root, root) /usr/bin/mysqld_multi
+%attr(755, root, root) /usr/bin/mysqld_safe
%attr(755, root, root) /usr/bin/mysqlhotcopy
+%attr(755, root, root) /usr/bin/mysqltest
+%attr(755, root, root) /usr/bin/pack_isam
%attr(755, root, root) /usr/bin/perror
%attr(755, root, root) /usr/bin/replace
-%attr(755, root, root) /usr/bin/resolveip
%attr(755, root, root) /usr/bin/resolve_stack_dump
-%attr(755, root, root) /usr/bin/safe_mysqld
-%attr(755, root, root) /usr/bin/mysqld_multi
-%attr(755, root, root) /usr/bin/my_print_defaults
-
-%attr(644, root, root) /usr/info/mysql.info*
+%attr(755, root, root) /usr/bin/resolveip
%attr(755, root, root) /usr/sbin/mysqld
%attr(644, root, root) /usr/lib/mysql/mysqld.sym
@@ -396,28 +414,20 @@ fi
%files client
%attr(755, root, root) /usr/bin/msql2mysql
%attr(755, root, root) /usr/bin/mysql
+%attr(755, root, root) /usr/bin/mysql_find_rows
%attr(755, root, root) /usr/bin/mysqlaccess
%attr(755, root, root) /usr/bin/mysqladmin
+%attr(755, root, root) /usr/bin/mysqlbinlog
%attr(755, root, root) /usr/bin/mysqlcheck
-%attr(755, root, root) /usr/bin/mysql_find_rows
%attr(755, root, root) /usr/bin/mysqldump
%attr(755, root, root) /usr/bin/mysqlimport
%attr(755, root, root) /usr/bin/mysqlshow
-%attr(755, root, root) /usr/bin/mysqlbinlog
-%attr(644, root, man) %doc /usr/man/man1/mysql.1*
-%attr(644, root, man) %doc /usr/man/man1/isamchk.1*
-%attr(644, root, man) %doc /usr/man/man1/isamlog.1*
-%attr(644, root, man) %doc /usr/man/man1/mysql_zap.1*
-%attr(644, root, man) %doc /usr/man/man1/mysqlaccess.1*
-%attr(644, root, man) %doc /usr/man/man1/mysqladmin.1*
-%attr(644, root, man) %doc /usr/man/man1/mysqld.1*
-%attr(644, root, man) %doc /usr/man/man1/mysqld_multi.1*
-%attr(644, root, man) %doc /usr/man/man1/mysqldump.1*
-%attr(644, root, man) %doc /usr/man/man1/mysqlshow.1*
-%attr(644, root, man) %doc /usr/man/man1/perror.1*
-%attr(644, root, man) %doc /usr/man/man1/replace.1*
-%attr(644, root, man) %doc /usr/man/man1/safe_mysqld.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysql.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqlaccess.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqladmin.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqldump.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqlshow.1*
%post shared
/sbin/ldconfig
@@ -426,32 +436,79 @@ fi
/sbin/ldconfig
%files devel
+%defattr(644 root, root)
%attr(755, root, root) /usr/bin/comp_err
-%attr(755, root, root) /usr/include/mysql/
-%attr(755, root, root) /usr/lib/mysql/*.a
%attr(755, root, root) /usr/bin/mysql_config
+%dir %attr(755, root, root) /usr/include/mysql
+%dir %attr(755, root, root) /usr/lib/mysql
+/usr/include/mysql/*
+/usr/lib/mysql/libdbug.a
+/usr/lib/mysql/libheap.a
+/usr/lib/mysql/libmerge.a
+/usr/lib/mysql/libmyisam.a
+/usr/lib/mysql/libmyisammrg.a
+/usr/lib/mysql/libmysqlclient.a
+/usr/lib/mysql/libmysqlclient.la
+/usr/lib/mysql/libmysqlclient_r.a
+/usr/lib/mysql/libmysqlclient_r.la
+/usr/lib/mysql/libmystrings.a
+/usr/lib/mysql/libmysys.a
+/usr/lib/mysql/libnisam.a
+/usr/lib/mysql/libvio.a
%files shared
+%defattr(755 root, root)
# Shared libraries (omit for architectures that don't support them)
-%attr(755, root, root) /usr/lib/*.so*
+/usr/lib/*.so*
%files bench
%attr(-, root, root) /usr/share/sql-bench
%attr(-, root, root) /usr/share/mysql-test
+%attr(755, root, root) /usr/bin/mysqlmanager
+%attr(755, root, root) /usr/bin/mysqlmanager-pwgen
+%attr(755, root, root) /usr/bin/mysqlmanagerc
%files Max
%attr(755, root, root) /usr/sbin/mysqld-max
%attr(644, root, root) /usr/lib/mysql/mysqld-max.sym
+%files embedded
+%attr(644, root, root) /usr/lib/mysql/libmysqld.a
+
%changelog
+* Thu Jul 18 2002 Lenz Grimmer <lenz@mysql.com>
+
+- Reworked the build steps a little bit: the Max binary is supposed
+ to include OpenSSL, which cannot be linked statically, thus trying
+ to statically link against a special glibc is futile anyway
+- because of this, it is not required to make yet another build run
+ just to compile the shared libs (saves a lot of time)
+- updated package description of the Max subpackage
+- clean up the BuildRoot directory afterwards
+
* Mon Jul 15 2002 Lenz Grimmer <lenz@mysql.com>
-- updated Packager tag
+- Updated Packager information
+- Fixed the build options: the regular package is supposed to
+ include InnoDB and linked statically, while the Max package
+ should include BDB and SSL support
+
+* Fri May 03 2002 Lenz Grimmer <lenz@mysql.com>
+
+- Use more RPM macros (e.g. infodir, mandir) to make the spec
+ file more portable
+- reorganized the installation of documentation files: let RPM
+ take care of this
+- reorganized the file list: actually install man pages along
+ with the binaries of the respective subpackage
+- don't include libmysqld.a in the devel subpackage as well, if we
+ have a special "embedded" subpackage
+- reworked the package descriptions
-* Fri Feb 15 2002 Sasha
+* Mon Oct 8 2001 Monty
-- changed build to use --with-other-libc
+- Added embedded server as a separate RPM
* Fri Apr 13 2001 Monty
diff --git a/tests/fork2_test.pl b/tests/fork2_test.pl
index b5564e99c3f..19fab5a67d6 100755
--- a/tests/fork2_test.pl
+++ b/tests/fork2_test.pl
@@ -92,7 +92,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
diff --git a/tests/fork_big.pl b/tests/fork_big.pl
index e082225604c..c72eb59946b 100755
--- a/tests/fork_big.pl
+++ b/tests/fork_big.pl
@@ -106,7 +106,7 @@ $running_insert_threads=$opt_threads+$numtables;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
if ($work{$pid} =~ /^insert/)
{
if (!--$running_insert_threads)
diff --git a/tests/grant.pl b/tests/grant.pl
index 0219fdb71ee..6da4326d465 100644
--- a/tests/grant.pl
+++ b/tests/grant.pl
@@ -8,9 +8,10 @@ use DBI;
use Getopt::Long;
use strict;
-use vars qw($dbh $user_dbh $opt_help $opt_Information $opt_force $opt_debug
- $opt_verbose $opt_server $opt_root_user $opt_password $opt_user
- $opt_database $opt_host $version $user $tables_cols $columns_cols);
+use vars qw($dbh $user_dbh $opt_help $opt_Information $opt_force $opt_debug
+ $opt_verbose $opt_server $opt_root_user $opt_password $opt_user
+ $opt_database $opt_host $version $user $tables_cols $columns_cols
+ $tmp_table);
$version="1.0";
$opt_help=$opt_Information=$opt_force=$opt_debug=$opt_verbose=0;
@@ -35,6 +36,8 @@ $|=1;
$tables_cols="Host, Db, User, Table_name, Grantor, Table_priv, Column_priv";
$columns_cols="Host, Db, User, Table_name, Column_name, Column_priv";
+$tmp_table="/tmp/mysql-grant.test"; # Can't use $$ as we are logging result
+unlink($tmp_table);
#
# clear grant tables
@@ -72,6 +75,7 @@ user_connect(0);
user_query("select * from mysql.user where user = '$opt_user'");
user_query("select * from mysql.db where user = '$opt_user'");
safe_query("grant select on *.* to $user,$user");
+safe_query("show grants for $user");
# The following should fail
user_query("insert into mysql.user (host,user) values ('error','$opt_user')",1);
@@ -294,6 +298,7 @@ safe_query("select $tables_cols from mysql.tables_priv");
safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user");
safe_query("select $tables_cols from mysql.tables_priv");
safe_query("revoke GRANT OPTION on $opt_database.test from $user",1);
+
#
# Test grants on database level
#
@@ -378,20 +383,80 @@ safe_query("select $tables_cols from mysql.tables_priv where user = '$opt_user'"
safe_query("select $columns_cols from mysql.columns_priv where user = '$opt_user'");
#
-# Test IDENTIFIED BY
-#
+# Clear up privileges to make future tests easier
safe_query("delete from user where user='$opt_user'");
+safe_query("delete from db where user='$opt_user'");
safe_query("flush privileges");
+safe_query("show grants for $user",1);
+
+#
+# Test IDENTIFIED BY
+#
+
safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'dummy', ${opt_user}\@127.0.0.1 identified by 'dummy2'");
user_connect(0,"dummy");
safe_query("grant SELECT on $opt_database.* to $user identified by ''");
user_connect(0);
+safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user identified by ''");
+safe_query("revoke ALL PRIVILEGES on $opt_database.* from $user identified by ''");
+safe_query("show grants for $user");
+
+#
+# Test bug reported in SELECT INTO OUTFILE
+#
+
+safe_query("create table $opt_database.test3 (a int)");
+safe_query("grant SELECT on $opt_database.test3 to $user");
+safe_query("grant FILE on *.* to $user");
+safe_query("insert into $opt_database.test3 values (1)");
+user_connect(0);
+user_query("select * into outfile '$tmp_table' from $opt_database.test3");
+safe_query("revoke SELECT on $opt_database.test3 from $user");
+safe_query("revoke FILE on *.* from $user");
+safe_query("drop table $opt_database.test3");
+
+#
+# Test privileges needed for LOCK TABLES
+#
+
+safe_query("create table $opt_database.test3 (a int)");
+user_connect(1);
+safe_query("grant INSERT on $opt_database.test3 to $user");
+user_connect(0);
+user_query("select * into outfile '$tmp_table' from $opt_database.test3",1);
+safe_query("grant SELECT on $opt_database.test3 to $user");
+user_connect(0);
+user_query("LOCK TABLES $opt_database.test3 READ",1);
+safe_query("grant LOCK TABLES on *.* to $user");
+safe_query("show grants for $user");
+safe_query("select * from mysql.user where user='$opt_user'");
+user_connect(0);
+user_query("LOCK TABLES $opt_database.test3 READ");
+user_query("UNLOCK TABLES");
+safe_query("revoke SELECT,INSERT,UPDATE,DELETE on $opt_database.test3 from $user");
+user_connect(1);
+safe_query("revoke LOCK TABLES on *.* from $user");
+safe_query("drop table $opt_database.test3");
+
+#
+# test new privileges in 4.0.2
+#
+
+safe_query("show grants for $user");
+safe_query("grant all on *.* to $user WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3");
+safe_query("show grants for $user");
+safe_query("revoke LOCK TABLES on *.* from $user");
+safe_query("flush privileges");
+safe_query("show grants for $user");
+safe_query("revoke ALL PRIVILEGES on *.* from $user");
+safe_query("show grants for $user");
#
# Clean up things
#
+unlink($tmp_table);
safe_query("drop database $opt_database");
safe_query("delete from user where user='$opt_user'");
safe_query("delete from db where user='$opt_user'");
diff --git a/tests/grant.res b/tests/grant.res
index 37266facc61..b54fec94514 100644
--- a/tests/grant.res
+++ b/tests/grant.res
@@ -19,10 +19,13 @@ Access denied for user: 'grant_user@localhost' (Using password: NO)
set password FOR grant_user=''
Connecting grant_user
select * from mysql.user where user = 'grant_user'
-localhost grant_user Y N N N N N N N N N N N N N
+localhost grant_user Y N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
grant select on *.* to grant_user@localhost,grant_user@localhost
+show grants for grant_user@localhost
+GRANT SELECT ON *.* TO 'grant_user'@'localhost'
+
insert into mysql.user (host,user) values ('error','grant_user')
Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
update mysql.user set host='error' WHERE user='grant_user'
@@ -48,7 +51,7 @@ Error in execute: The host or user argument to GRANT is too long
grant select on grant_test.test to grant_user with grant option
Error in execute: grant command denied to user: 'grant_user@localhost' for table 'test'
set password FOR ''@''=''
-Error in execute: You are using MySQL as an anonymous users and anonymous users are not allowed to change passwords
+Error in execute: Can't find any matching row in the user table
set password FOR root@localhost = password('test')
Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
revoke select on *.* from grant_user@localhost
@@ -93,7 +96,7 @@ delete from user where user='grant_user'
flush privileges
grant select on grant_test.* to grant_user@localhost
select * from mysql.user where user = 'grant_user'
-localhost grant_user N N N N N N N N N N N N N N
+localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
localhost grant_test grant_user Y N N N N N N N N N
@@ -152,7 +155,7 @@ insert into mysql.user (host,user) values ('error','grant_user',0)
Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost
select * from mysql.user where user = 'grant_user'
-localhost grant_user N N N N N N N N N N N N N N
+localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
Connecting grant_user
@@ -168,7 +171,7 @@ Error in execute: select command denied to user: 'grant_user@localhost' for tabl
show keys from test
Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
show columns from test2
-a int(11) 0
+a int(11) 0
show keys from test2
select * from test
@@ -311,8 +314,8 @@ revoke GRANT OPTION on grant_test.test from grant_user@localhost
Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost' on table 'test'
grant select(a) on grant_test.test to grant_user@localhost
show columns from test
-a int(11) YES NULL select
-b int(11) YES NULL
+a int(11) YES NULL
+b int(11) YES NULL
grant insert (b), update (b) on grant_test.test to grant_user@localhost
select count(a) from test
@@ -432,11 +435,66 @@ localhost grant_test grant_user N Y N N N N N N N N
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv where user = 'grant_user'
select Host, Db, User, Table_name, Column_name, Column_priv from mysql.columns_priv where user = 'grant_user'
delete from user where user='grant_user'
+delete from db where user='grant_user'
flush privileges
+show grants for grant_user@localhost
+Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost'
grant ALL PRIVILEGES on grant_test.test to grant_user@localhost identified by 'dummy', grant_user@127.0.0.1 identified by 'dummy2'
Connecting grant_user
grant SELECT on grant_test.* to grant_user@localhost identified by ''
Connecting grant_user
+revoke ALL PRIVILEGES on grant_test.test from grant_user@localhost identified by ''
+revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost identified by ''
+show grants for grant_user@localhost
+create table grant_test.test3 (a int)
+grant SELECT on grant_test.test3 to grant_user@localhost
+grant FILE on *.* to grant_user@localhost
+insert into grant_test.test3 values (1)
+Connecting grant_user
+select * into outfile '/tmp/mysql-grant.test' from grant_test.test3
+revoke SELECT on grant_test.test3 from grant_user@localhost
+revoke FILE on *.* from grant_user@localhost
+drop table grant_test.test3
+create table grant_test.test3 (a int)
+Connecting grant_user
+Access denied for user: 'grant_user@localhost' to database 'grant_test'
+grant INSERT on grant_test.test3 to grant_user@localhost
+Connecting grant_user
+select * into outfile '/tmp/mysql-grant.test' from grant_test.test3
+Error in execute: Access denied for user: 'grant_user@localhost' (Using password: NO)
+grant SELECT on grant_test.test3 to grant_user@localhost
+Connecting grant_user
+LOCK TABLES grant_test.test3 READ
+Error in execute: Access denied for user: 'grant_user@localhost' (Using password: NO)
+grant LOCK TABLES on *.* to grant_user@localhost
+show grants for grant_user@localhost
+GRANT LOCK TABLES ON *.* TO 'grant_user'@'localhost'
+GRANT SELECT, INSERT ON grant_test.test3 TO 'grant_user'@'localhost'
+
+select * from mysql.user where user='grant_user'
+127.0.0.1 grant_user 7f70e8b858ee6782 N N N N N N N N N N N N N N N N N N N N N 0 0 0
+localhost grant_user N N N N N N N N N N N N N N N N N Y N N N 0 0 0
+
+Connecting grant_user
+LOCK TABLES grant_test.test3 READ
+UNLOCK TABLES
+revoke SELECT,INSERT,UPDATE,DELETE on grant_test.test3 from grant_user@localhost
+Connecting grant_user
+Access denied for user: 'grant_user@localhost' to database 'grant_test'
+revoke LOCK TABLES on *.* from grant_user@localhost
+drop table grant_test.test3
+show grants for grant_user@localhost
+grant all on *.* to grant_user@localhost WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+show grants for grant_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+
+revoke LOCK TABLES on *.* from grant_user@localhost
+flush privileges
+show grants for grant_user@localhost
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+
+revoke ALL PRIVILEGES on *.* from grant_user@localhost
+show grants for grant_user@localhost
drop database grant_test
delete from user where user='grant_user'
delete from db where user='grant_user'
diff --git a/tests/insert_and_repair.pl b/tests/insert_and_repair.pl
index 4d68c2ab9a0..1c7186bb651 100755
--- a/tests/insert_and_repair.pl
+++ b/tests/insert_and_repair.pl
@@ -56,7 +56,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
diff --git a/tests/mail_to_db.pl b/tests/mail_to_db.pl
index b758a171c77..671e8b23599 100755
--- a/tests/mail_to_db.pl
+++ b/tests/mail_to_db.pl
@@ -17,7 +17,7 @@ use DBI;
use Getopt::Long;
$| = 1;
-$VER = "2.3";
+$VER = "2.6";
$opt_help = 0;
$opt_version = 0;
@@ -152,19 +152,77 @@ sub main
$dbh->disconnect if (!$opt_test);
$ignored = ($mail_no_from_f + $mail_no_subject_f + $mail_no_txt_f +
- $mail_too_big + $mail_duplicates);
- print "Mails inserted:\t\t\t$mail_inserted\n";
- print "Mails ignored:\t\t\t$ignored\n";
- print "Mails without \"From:\" -field:\t$mail_no_from_f\n";
- print "Mails without message:\t\t$mail_no_txt_f\n";
- print "Mails without subject:\t\t$mail_no_subject_f\n";
- print "Too big mails (> $opt_max_mail_size):\t$mail_too_big\n";
- print "Duplicate mails:\t\t$mail_duplicates\n";
- print "Forwarded mails:\t\t$mail_forwarded\n";
- print "Total number of mails:\t\t";
+ $mail_too_big + $mail_duplicates + $mail_fixed);
+ print "################################ Mail Report #################################\n\n";
+ print "Mails inserted:\t\t\t\t\t$mail_inserted\n";
+ print "--------------- ";
+ print "=" . "=" x length("$mail_inserted") . "=\n\n";
+ if ($ignored)
+ {
+ print "Ignored mails\n";
+ print "-------------\n";
+ if ($mail_no_from_f)
+ {
+ print "Reason: mail without \"From:\" -field:\t\t$mail_no_from_f\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_no_txt_f)
+ {
+ print "Reason: mail without message:\t\t\t$mail_no_txt_f\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_no_subject_f)
+ {
+ print "Reason: mail without subject:\t\t\t$mail_no_subject_f\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_too_big)
+ {
+ print "Reason: mail too big, over $opt_max_mail_size bytes:\t\t";
+ print $mail_too_big;
+ print " (see --max_mail_size=#)\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_duplicates)
+ {
+ print "Reason: duplicate mail, or in db already:\t$mail_duplicates\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_fixed)
+ {
+ print "Reason: mail was an unsubscribe - mail:\t\t$mail_fixed\n";
+ }
+ else
+ {
+ print "";
+ }
+ print " ";
+ print "=" . "=" x length("$ignored") . "=\n";
+ print "Total number of ignored mails:\t\t\t$ignored\n\n";
+ }
+ print "Total number of mails:\t\t\t\t";
print $mail_inserted + $ignored;
- print "\n";
- print "Mails with unsubscribe removed:\t$mail_fixed\n";
+ print " (OK: ";
+ print sprintf("%.1f", (($mail_inserted / ($mail_inserted+$ignored)) * 100));
+ print "% Ignored: ";
+ print sprintf("%.1f", (($ignored / ($mail_inserted + $ignored)) * 100));
+ print "%)\n";
+ print "################################ End Report ##################################\n";
exit(0);
}
@@ -213,10 +271,10 @@ sub process_mail_file
%values = ();
$type = "";
$check = 0;
-
while (<FILE>)
{
chop;
+ chop if (substr($_, -1, 1) eq "\r");
if ($type ne "message")
{
if (/^Reply-To: (.*)/i)
@@ -269,7 +327,8 @@ sub process_mail_file
$values{$type} .= "\n" . $_;
$check--;
}
- elsif (/^From .* \d\d:\d\d:\d\d\s\d\d\d\d$/)
+ elsif (/^From .* \d\d:\d\d:\d\d\s\d\d\d\d/ ||
+ /^From .* \d\d\d\d\s\d\d:\d\d:\d\d/)
{
$values{'hash'} = checksum("$values{'message'}");
update_table($dbh, $file_name, \%values);
@@ -288,8 +347,11 @@ sub process_mail_file
$values{$type} .= "\n" . $_;
}
}
- $values{'hash'} = checksum("$values{'message'}");
- update_table($dbh, $file_name, \%values);
+ if (defined($values{'message'}))
+ {
+ $values{'hash'} = checksum("$values{'message'}");
+ update_table($dbh, $file_name, \%values);
+ }
}
####
@@ -335,26 +397,26 @@ sub date_parser
sub update_table
{
my($dbh, $file_name, $values) = @_;
- my($q,$tail,$message);
+ my($q, $tail, $message);
if (!defined($values->{'subject'}) || !defined($values->{'to'}))
{
$mail_no_subject_f++;
return; # Ignore these
}
- $message=$values->{'message'};
- $message =~ s/^\s*//; #removes whitespaces from the beginning
+ $message = $values->{'message'};
+ $message =~ s/^\s*//; # removes whitespaces from the beginning
restart:
- $message =~ s/[\s\n>]*$//; #removes whitespaces and '>' from the end
- $values->{'message'}=$message;
+ $message =~ s/[\s\n>]*$//; # removes whitespaces and '>' from the end
+ $values->{'message'} = $message;
foreach $tail (@remove_tail)
{
$message =~ s/$tail//;
}
if ($message ne $values->{'message'})
{
- $message =~ s/\s*$//; #removes whitespaces from the end
+ $message =~ s/\s*$//; # removes whitespaces from the end
$mail_fixed++;
goto restart; # Some mails may have duplicated messages
}
@@ -442,7 +504,7 @@ sub update_table
sub checksum
{
my ($txt)= @_;
- my ($crc,$i,$count);
+ my ($crc, $i, $count);
$count = length($txt);
for ($crc = $i = 0; $i < $count ; $i++)
{
diff --git a/tests/myisam-big-rows.tst b/tests/myisam-big-rows.tst
new file mode 100644
index 00000000000..56c06f4820f
--- /dev/null
+++ b/tests/myisam-big-rows.tst
@@ -0,0 +1,72 @@
+#
+# Test rows with length above > 16M
+# Note that for this to work, you should start mysqld with
+# -O max_allowed_packet=32M
+#
+
+drop table if exists t1;
+create table t1 (a tinyint not null auto_increment, b longblob not null, primary key (a)) checksum=1;
+
+insert into t1 (b) values(repeat(char(65),10));
+insert into t1 (b) values(repeat(char(66),10));
+insert into t1 (b) values(repeat(char(67),10));
+update t1 set b=repeat(char(68),16777216) where a=1;
+check table t1;
+update t1 set b=repeat(char(69),16777000) where a=2;
+update t1 set b=repeat(char(70),167) where a=3;
+update t1 set b=repeat(char(71),16778000) where a=1;
+update t1 set b=repeat(char(72),16778000) where a=3;
+select a,length(b) from t1;
+set @a=1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+update t1 set b=('A') where a=5;
+delete from t1 where a=7;
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+update t1 set b=repeat(char(73+@a+1),17000000+@a) where a=last_insert_id();
+
+select a,mid(b,1,5),length(b) from t1;
+check table t1;
+repair table t1;
+check table t1;
+select a from table where b<>repeat(mid(b,1,1),length(b));
+delete from t1 where (a & 1);
+select a from table where b<>repeat(mid(b,1,1),length(b));
+check table t1;
+repair table t1;
+check table t1;
+drop table t1;
diff --git a/tests/rename_test.pl b/tests/rename_test.pl
index bdfb14be927..edf3216a62f 100755
--- a/tests/rename_test.pl
+++ b/tests/rename_test.pl
@@ -79,7 +79,7 @@ print "Total time: " .
exit(0);
#
-# Insert records in the table. Delete table when test is finnished
+# Insert records in the table. Delete table when test is finished
#
sub test_insert
diff --git a/tests/test_delayed_insert.pl b/tests/test_delayed_insert.pl
index e49d73a19bd..c7a8f0ca4b7 100755
--- a/tests/test_delayed_insert.pl
+++ b/tests/test_delayed_insert.pl
@@ -65,7 +65,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
diff --git a/tests/truncate.pl b/tests/truncate.pl
new file mode 100755
index 00000000000..57b50cf96b6
--- /dev/null
+++ b/tests/truncate.pl
@@ -0,0 +1,125 @@
+#!/usr/bin/perl -w
+#
+# This is a test with uses many processes to test a MySQL server.
+#
+
+$opt_loop_count=10000; # Change this to make test harder/easier
+
+##################### Standard benchmark inits ##############################
+
+use DBI;
+use Getopt::Long;
+use Benchmark;
+
+package main;
+
+$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
+$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
+$opt_threads=2;
+$opt_host=$opt_user=$opt_password=""; $opt_db="test";
+
+GetOptions("host=s","db=s","user=s","password=s","loop-count=i","skip-create","skip-in","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","threads=i") || die "Aborted";
+$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$opt_force=undef; # Ignore warnings from these
+
+print "Testing truncate from $opt_threads multiple connections $opt_loop_count times\n";
+
+@testtables = ( ["bench_f31", "type=heap"]);
+
+####
+#### Start timeing and start test
+####
+
+$start_time=new Benchmark;
+$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
+ $opt_user, $opt_password,
+ { PrintError => 0}) || die $DBI::errstr;
+if (!$opt_skip_create)
+{
+ my $table_def;
+ foreach $table_def (@testtables)
+ {
+ my ($table,$extra)= ($table_def->[0], $table_def->[1]);
+ print "Creating table $table in database $opt_db\n";
+ $dbh->do("drop table if exists $table");
+ $dbh->do("create table $table".
+ " (id int(6) not null,".
+ " info varchar(32)," .
+ " marker timestamp," .
+ " flag int not null," .
+ " primary key(id)) $extra")
+
+ or die $DBI::errstr;
+ }
+}
+
+$dbh->disconnect; $dbh=0; # Close handler
+$|= 1; # Autoflush
+
+####
+#### Start the tests
+####
+
+for ($i=0 ; $i < $opt_threads ; $i ++)
+{
+ test_truncate() if (($pid=fork()) == 0); $work{$pid}="truncate";
+}
+
+print "Started $opt_threads threads\n";
+
+$errors=0;
+$running_insert_threads=$opt_threads;
+while (($pid=wait()) != -1)
+{
+ $ret=$?/256;
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
+ --$running_insert_threads;
+ $errors++ if ($ret != 0);
+}
+
+#
+# Cleanup
+#
+
+if (!$opt_skip_delete && !$errors)
+{
+ my $table_def;
+ $dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
+ $opt_user, $opt_password,
+ { PrintError => 0}) || die $DBI::errstr;
+
+ foreach $table_def (@testtables)
+ {
+ $dbh->do("drop table " . $table_def->[0]);
+ }
+ $dbh->disconnect; $dbh=0; # Close handler
+}
+
+print ($errors ? "Test failed\n" :"Test ok\n");
+$end_time=new Benchmark;
+print "Total time: " .
+ timestr(timediff($end_time, $start_time),"noc") . "\n";
+
+exit(0);
+
+
+#
+# Insert records in the table
+#
+
+sub test_truncate
+{
+ my ($dbh,$i,$j,$count,$table_def,$table);
+
+ $dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
+ $opt_user, $opt_password,
+ { PrintError => 0}) || die $DBI::errstr;
+
+ for ($count=0; $count < $opt_loop_count ; $count++)
+ {
+ my ($table)= ($testtables[0]->[0]);
+ $dbh->do("truncate table $table") || die "Got error on truncate: $DBI::errstr\n";
+ }
+ $dbh->disconnect; $dbh=0;
+ print "Test_truncate: Run $count times\n";
+ exit(0);
+}
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 00000000000..e5130865a89
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,20 @@
+INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include \
+ $(openssl_includes) -I../include
+LDADD= @CLIENT_EXTRA_LDFLAGS@ ../libmysql_r/libmysqlclient_r.la @openssl_libs@
+bin_PROGRAMS= mysqlmanager
+mysqlmanager_SOURCES= mysqlmanager.c
+mysqlmanager_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
+DEF= -DUNDEF_THREADS_HACK
+
+OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
+ __math.h time.h __time.h unistd.h __unistd.h types.h \
+ xtypes.h ac-types.h posix.h string.h __string.h \
+ errno.h socket.h inet.h dirent.h netdb.h \
+ cleanup.h cond.h debug_out.h fd.h kernel.h mutex.h \
+ prio_queue.h pthread_attr.h pthread_once.h queue.h\
+ sleep.h specific.h version.h pwd.h timers.h uio.h \
+ cdefs.h machdep.h signal.h __signal.h util.h lex.h \
+ wait.h
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/tools/managertest1.nc b/tools/managertest1.nc
new file mode 100644
index 00000000000..bf1b82ed406
--- /dev/null
+++ b/tools/managertest1.nc
@@ -0,0 +1,16 @@
+def_exec server /usr/sbin/mysqld --socket=/tmp/temp.sock --skip-grant --skip-net --datadir=/tmp
+set_exec_con server root localhost /tmp/temp.sock
+set_exec_stdout server /tmp/mysqld.err
+set_exec_stderr server /tmp/mysqld.err
+start_exec server 3
+show_exec
+query server show variables like '%max_heap%';
+stop_exec server 3
+def_exec server /usr/sbin/mysqld --socket=/tmp/temp.sock --skip-grant --skip-net --datadir=/tmp -O max_heap_table_size=5000
+show_exec
+start_exec server 3
+query server show variables like '%max_heap%';
+show_exec
+stop_exec server 3
+show_exec
+quit
diff --git a/tools/mysqlmanager-sample.pwd b/tools/mysqlmanager-sample.pwd
new file mode 100644
index 00000000000..51c1ade1b77
--- /dev/null
+++ b/tools/mysqlmanager-sample.pwd
@@ -0,0 +1 @@
+root:5ebe2294ecd0e0f08eab7690d2a6ee69
diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c
new file mode 100644
index 00000000000..e6fab63c5b3
--- /dev/null
+++ b/tools/mysqlmanager.c
@@ -0,0 +1,1848 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ MySQL server management daemon
+
+ Written by:
+ Sasha Pachev <sasha@mysql.com>
+*/
+
+#include <my_global.h>
+#include <my_pthread.h>
+#include <mysql.h>
+#include <mysql_version.h>
+#include <mysqld_error.h>
+#include <my_sys.h>
+#include <my_dir.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include <hash.h>
+#include <my_getopt.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <violite.h>
+#include <md5.h>
+#include <signal.h>
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#define MANAGER_VERSION "1.2"
+#define MANAGER_GREETING "MySQL Server Management Daemon v. 1.2"
+
+#define LOG_ERR 1
+#define LOG_WARN 2
+#define LOG_INFO 3
+#define LOG_DEBUG 4
+
+#define CHILD_START 1
+#define CHILD_STOP 2
+
+#ifndef MANAGER_PORT
+#define MANAGER_PORT 23546
+#endif
+
+#ifndef MANAGER_CONNECT_RETRIES
+#define MANAGER_CONNECT_RETRIES 5
+#endif
+
+#ifndef MANAGER_MAX_CMD_LEN
+#define MANAGER_MAX_CMD_LEN 16384
+#endif
+
+#ifndef MANAGER_LOG_FILE
+#define MANAGER_LOG_FILE "/var/log/mysqlmanager.log"
+#endif
+
+#ifndef MANAGER_BACK_LOG
+#define MANAGER_BACK_LOG 50
+#endif
+
+#ifndef MAX_USER_NAME
+#define MAX_USER_NAME 16
+#endif
+
+#ifndef MANAGER_PW_FILE
+#define MANAGER_PW_FILE "/etc/mysqlmanager.passwd"
+#endif
+
+#ifndef MAX_HOST
+#define MAX_HOST 128
+#endif
+
+#ifndef MAX_LAUNCHER_MSG
+#define MAX_LAUNCHER_MSG 256
+#endif
+
+#define MAX_RETRY_COUNT 100
+
+/*
+ Variable naming convention - if starts with manager_, either is set
+ directly by the user, or used closely in ocnjunction with a variable
+ set by the user
+*/
+
+#if defined(__i386__) && defined(HAVE_LINUXTHREADS)
+#define DO_STACKTRACE 1
+#endif
+
+uint manager_port;
+FILE* errfp;
+const char* manager_log_file = MANAGER_LOG_FILE;
+pthread_mutex_t lock_log,lock_shutdown,lock_exec_hash,lock_launch_thd;
+pthread_cond_t cond_launch_thd;
+pthread_t loop_th,launch_msg_th;
+int manager_sock = -1;
+uchar* stack_bottom=0;
+struct sockaddr_in manager_addr;
+ulong manager_bind_addr;
+int manager_back_log;
+int in_shutdown = 0, shutdown_requested=0;
+int manager_connect_retries;
+const char* manager_greeting = MANAGER_GREETING;
+uint manager_max_cmd_len;
+const char* manager_pw_file=MANAGER_PW_FILE;
+my_bool one_thread; /* for debugging */
+
+typedef enum {PARAM_STDOUT,PARAM_STDERR} PARAM_TYPE;
+
+/* messages */
+
+#define MAX_CLIENT_MSG_LEN 256
+#define NET_BLOCK 2048
+#define MD5_LEN 16
+#define ESCAPE_CHAR '\\'
+#define EOL_CHAR '\n'
+
+/* access flags */
+
+#define PRIV_SHUTDOWN 1
+
+struct manager_thd
+{
+ NET net;
+ char user[MAX_USER_NAME+1];
+ int priv_flags;
+ char* cmd_buf;
+ int fatal,finished;
+};
+
+struct manager_user
+{
+ char user[MAX_USER_NAME+1];
+ char md5_pass[MD5_LEN];
+ int user_len;
+ const char* error;
+};
+
+HASH exec_hash,user_hash;
+struct manager_exec* cur_launch_exec=0;
+
+static struct manager_thd* manager_thd_new(Vio* vio);
+
+static struct manager_exec* manager_exec_new(char* arg_start,char* arg_end);
+static void manager_exec_print(NET* net,struct manager_exec* e);
+static void manager_thd_free(struct manager_thd* thd);
+static void manager_exec_free(void* e);
+static void manager_exec_connect(struct manager_exec* e);
+static int manager_exec_launch(struct manager_exec* e);
+static struct manager_exec* manager_exec_by_pid(pid_t pid);
+
+static struct manager_user* manager_user_new(char* buf);
+static void manager_user_free(void* u);
+
+static char* arg_strmov(char* dest, const char* src, int n);
+static byte* get_exec_key(const byte* e, uint* len,
+ my_bool __attribute__((unused)) t);
+static byte* get_user_key(const byte* u, uint* len,
+ my_bool __attribute__((unused)) t);
+static uint tokenize_args(char* arg_start,char** arg_end);
+static void init_arg_array(char* arg_str,char** args,uint arg_count);
+static int hex_val(char c);
+static int open_and_dup(int fd,char* path);
+static void update_req_len(struct manager_exec* e);
+
+typedef int (*manager_cmd_handler)(struct manager_thd*,char*,char*);
+
+static void handle_child(int __attribute__((unused)) sig);
+static void handle_sigpipe(int __attribute__((unused)) sig);
+
+/*
+ exec() in a threaded application is full of problems.
+ To solve this, we fork off a launcher at the very start
+ and communicate with it through a pipe
+*/
+
+static void fork_launcher();
+static void run_launcher_loop();
+int to_launcher_pipe[2],from_launcher_pipe[2];
+pid_t launcher_pid;
+int in_segfault=0;
+const char* pid_file = "/var/run/mysqlmanager.pid";
+int created_pid_file = 0;
+
+struct manager_cmd
+{
+ const char* name;
+ const char* help;
+ manager_cmd_handler handler_func;
+ int len;
+};
+
+struct manager_exec
+{
+ char* ident;
+ int ident_len;
+ const char* error;
+ char* bin_path;
+ char** args;
+ char con_user[16];
+ char con_pass[16];
+ int con_port;
+ pid_t pid;
+ int exit_code;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+ pthread_t th;
+ char con_sock[FN_REFLEN];
+ char con_host[MAX_HOST];
+ char stderr_path[FN_REFLEN];
+ char stdout_path[FN_REFLEN];
+ MYSQL mysql;
+ char* data_buf;
+ int req_len;
+ int start_wait_timeout;
+ int stderr_path_size,stdout_path_size,data_buf_size;
+ int num_args;
+};
+
+static int set_exec_param(struct manager_thd* thd, char* args_start,
+ char* args_end, PARAM_TYPE param_type);
+
+#define HANDLE_DECL(com) \
+static int com(struct manager_thd* thd, char* args_start,char* args_end)
+#define HANDLE_NOARG_DECL(com) \
+static int com(struct manager_thd *thd,\
+ char *args_start __attribute__((unused)),\
+ char* args_end __attribute__((unused)))
+
+HANDLE_NOARG_DECL(handle_ping);
+HANDLE_NOARG_DECL(handle_quit);
+HANDLE_NOARG_DECL(handle_help);
+HANDLE_NOARG_DECL(handle_shutdown);
+HANDLE_DECL(handle_def_exec);
+HANDLE_DECL(handle_start_exec);
+HANDLE_DECL(handle_stop_exec);
+HANDLE_DECL(handle_set_exec_con);
+HANDLE_DECL(handle_set_exec_stdout);
+HANDLE_DECL(handle_set_exec_stderr);
+HANDLE_NOARG_DECL(handle_show_exec);
+HANDLE_DECL(handle_query);
+
+
+struct manager_cmd commands[] =
+{
+ {"ping", "Check if this server is alive", handle_ping,4},
+ {"quit", "Finish session", handle_quit,4},
+ {"shutdown", "Shutdown this server", handle_shutdown,8},
+ {"def_exec", "Define executable entry", handle_def_exec,8},
+ {"start_exec", "Launch process defined by executable entry",
+ handle_start_exec,10},
+ {"stop_exec", "Stop process defined by executable entry",
+ handle_stop_exec,9},
+ {"set_exec_con", "Set connection parameters for executable entry",
+ handle_set_exec_con,12},
+ {"set_exec_stdout", "Set stdout path for executable entry",
+ handle_set_exec_stdout,15},
+ {"set_exec_stderr", "Set stderr path for executable entry",
+ handle_set_exec_stderr,15},
+ {"query","Run query against MySQL server",handle_query,5},
+ {"show_exec","Show defined executable entries",handle_show_exec,9},
+ {"help", "Print this message", handle_help,4},
+ {0,0,0,0}
+};
+
+
+static struct my_option my_long_options[] =
+{
+#ifndef DBUG_OFF
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to listen on.", (gptr*) &manager_port,
+ (gptr*) &manager_port, 0, GET_UINT, REQUIRED_ARG, MANAGER_PORT, 0, 0, 0,
+ 0, 0},
+ {"log", 'l', "Path to log file.", (gptr*) &manager_log_file,
+ (gptr*) &manager_log_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", 'b', "Address to listen on.", (gptr*) &manager_bind_addr,
+ (gptr*) &manager_bind_addr, 0, GET_ULONG, REQUIRED_ARG, INADDR_ANY, 0,
+ 0, 0, 0, 0},
+ {"tcp-backlog", 'B', "Size of TCP/IP listen queue.",
+ (gptr*) &manager_back_log, (gptr*) &manager_back_log, 0, GET_INT,
+ REQUIRED_ARG, MANAGER_BACK_LOG, 0, 0, 0, 0, 0},
+ {"greeting", 'g', "Set greeting on connect", (gptr*) &manager_greeting,
+ (gptr*) &manager_greeting, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"max-command-len", 'm', "Maximum command length",
+ (gptr*) &manager_max_cmd_len, (gptr*) &manager_max_cmd_len, 0, GET_UINT,
+ REQUIRED_ARG, MANAGER_MAX_CMD_LEN, 0, 0, 0, 0, 0},
+ {"one-thread", 'd', "Use one thread ( for debugging)", (gptr*) &one_thread,
+ (gptr*) &one_thread, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect-retries", 'C', "Number of attempts to establish MySQL connection",
+ (gptr*) &manager_connect_retries, (gptr*) &manager_connect_retries, 0,
+ GET_INT, REQUIRED_ARG, MANAGER_CONNECT_RETRIES, 0, 0, 0, 0, 0},
+ {"password-file", 'p', "Password file for manager",
+ (gptr*) &manager_pw_file, (gptr*) &manager_pw_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"pid-file", 'f', "Pid file to use", (gptr*) &pid_file, (gptr*) &pid_file,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void die(const char* fmt,...);
+static void print_time(FILE* fp);
+static void clean_up();
+static struct manager_cmd* lookup_cmd(char* s,int len);
+static int client_msg(NET* net,int err_code,const char* fmt,...);
+static int client_msg_pre(NET* net,int err_code,const char* fmt,...);
+static int client_msg_raw(NET* net,int err_code,int pre,const char* fmt,
+ va_list args);
+static int authenticate(struct manager_thd* thd);
+/* returns pointer to end of line */
+static char* read_line(struct manager_thd* thd);
+static pthread_handler_decl(process_connection, arg);
+static pthread_handler_decl(process_launcher_messages, arg);
+static int exec_line(struct manager_thd* thd,char* buf,char* buf_end);
+
+#ifdef DO_STACKTRACE
+void print_stacktrace();
+#endif
+
+static void log_msg(const char* fmt, int msg_type, va_list args);
+
+/* No 'inline' here becasue functions with ... can't do that portable */
+#define LOG_MSG_FUNC(type,TYPE) static void type \
+ (const char* fmt,...) { \
+ va_list args; \
+ va_start(args,fmt); \
+ log_msg(fmt,TYPE,args);\
+ }
+
+LOG_MSG_FUNC(log_err,LOG_ERR)
+LOG_MSG_FUNC(log_warn,LOG_WARN)
+LOG_MSG_FUNC(log_info,LOG_INFO)
+
+#ifndef DBUG_OFF
+LOG_MSG_FUNC(log_debug,LOG_DEBUG)
+#else
+void log_debug(const char* __attribute__((unused)) fmt,...) {}
+#endif
+
+static void handle_sigterm(int sig __attribute__((unused)))
+{
+ log_info("Got SIGTERM");
+ if (!one_thread)
+ {
+ kill(launcher_pid,SIGTERM);
+ pthread_kill(loop_th,SIGTERM);
+ }
+ clean_up();
+ exit(0);
+}
+
+#ifdef DO_STACKTRACE
+static void handle_segfault(int sig)
+{
+ if (in_segfault)
+ exit(1);
+ in_segfault=1;
+ fprintf(errfp,"Got fatal signal %d\n",sig);
+ print_stacktrace();
+ exit(1);
+}
+#endif
+
+static void handle_sigpipe(int __attribute__((unused)) sig)
+{
+ signal(SIGPIPE,handle_sigpipe);
+}
+
+#ifdef DO_STACKTRACE
+
+#define MAX_DEPTH 25
+#define SIGRETURN_FRAME_COUNT 1
+
+void print_stacktrace()
+{
+ uchar** fp;
+ int i;
+ LINT_INIT(fp);
+ fprintf(errfp,"Fatal errror, stacktrace follows:\n");
+#ifdef __i386__
+ __asm__ __volatile__("movl %%ebp,%0" :"=r"(fp) :"r"(fp));
+#endif
+ if (!fp)
+ {
+ fprintf(errfp,"frame points is NULL, cannot trace stack\n");
+ return;
+ }
+ for (i=0;i<MAX_DEPTH && fp<(uchar**)stack_bottom;i++)
+ {
+#ifdef __i386__
+ uchar** new_fp = (uchar**)*fp;
+ fprintf(errfp, "%p\n", i == SIGRETURN_FRAME_COUNT ?
+ *(fp+17) : *(fp+1));
+#endif /* __386__ */
+ if (new_fp <= fp )
+ {
+ fprintf(errfp, "New value of fp=%p failed sanity check,\
+ terminating stack trace!\n", new_fp);
+ return;
+ }
+ fp = new_fp;
+ }
+ fprintf(errfp,"Stack trace successful\n");
+ fflush(errfp);
+}
+#endif
+
+static int exec_line(struct manager_thd* thd,char* buf,char* buf_end)
+{
+ char* p=buf;
+ struct manager_cmd* cmd;
+ for (;p<buf_end && !isspace(*p);p++)
+ *p=tolower(*p);
+ log_info("Command '%s'", buf);
+ if (!(cmd=lookup_cmd(buf,(int)(p-buf))))
+ {
+ if (client_msg(&thd->net,MANAGER_CLIENT_ERR,
+ "Unrecognized command '%s', type help to see list of supported\
+ commands", buf))
+ thd->fatal=1;
+ return 1;
+ }
+ for (;p<buf_end && isspace(*p);p++);
+ return cmd->handler_func(thd,p,buf_end);
+}
+
+static struct manager_cmd* lookup_cmd(char* s,int len)
+{
+ struct manager_cmd* cmd = commands;
+ for (;cmd->name;cmd++)
+ {
+ if (cmd->len == len && !memcmp(cmd->name,s,len))
+ return cmd;
+ }
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_ping)
+{
+ client_msg(&thd->net,MANAGER_OK,"Server management daemon is alive");
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_quit)
+{
+ client_msg(&thd->net,MANAGER_OK,"Goodbye");
+ thd->finished=1;
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_help)
+{
+ struct manager_cmd* cmd = commands;
+ NET* net = &thd->net;
+ client_msg_pre(net,MANAGER_INFO,"Available commands:");
+ for (;cmd->name;cmd++)
+ {
+ client_msg_pre(net,MANAGER_INFO,"%s - %s", cmd->name, cmd->help);
+ }
+ client_msg_pre(net,MANAGER_INFO,"End of help");
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_shutdown)
+{
+ client_msg(&thd->net,MANAGER_OK,"Shutdown started, goodbye");
+ thd->finished=1;
+ shutdown_requested = 1;
+ if (!one_thread)
+ {
+ kill(launcher_pid,SIGTERM);
+ pthread_kill(loop_th,SIGTERM);
+ }
+ return 0;
+}
+
+HANDLE_DECL(handle_set_exec_con)
+{
+ int num_args;
+ const char* error=0;
+ struct manager_exec* e;
+ char* arg_p;
+ if ((num_args=tokenize_args(args_start,&args_end))<2)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ arg_p=args_start;
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,arg_p,
+ strlen(arg_p))))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ arg_p+=strlen(arg_p)+1;
+ arg_p+=(strnmov(e->con_user,arg_p,sizeof(e->con_user))-e->con_user)+1;
+ if (num_args >= 3)
+ {
+ arg_p+=(strnmov(e->con_host,arg_p,sizeof(e->con_host))-e->con_host)+1;
+ if (num_args == 4)
+ {
+ if (!(e->con_port=atoi(arg_p)))
+ strnmov(e->con_sock,arg_p,sizeof(e->con_sock));
+ else
+ e->con_sock[0]=0;
+ }
+ else if (num_args > 4)
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Too many arguments";
+ goto err;
+ }
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_OK,"Entry updated");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_set_exec_stdout)
+{
+ return set_exec_param(thd,args_start,args_end,PARAM_STDOUT);
+}
+
+HANDLE_DECL(handle_set_exec_stderr)
+{
+ return set_exec_param(thd,args_start,args_end,PARAM_STDERR);
+}
+
+static int set_exec_param(struct manager_thd* thd, char* args_start,
+ char* args_end, PARAM_TYPE param_type)
+{
+ int num_args;
+ const char* error=0;
+ struct manager_exec* e;
+ char* arg_p;
+ char* param;
+ int param_size;
+
+ if ((num_args=tokenize_args(args_start,&args_end))<2)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ arg_p=args_start;
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,arg_p,
+ strlen(arg_p))))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ arg_p+=strlen(arg_p)+1;
+ param_size=strlen(arg_p)+1;
+ switch (param_type) {
+ case PARAM_STDOUT:
+ param=e->stdout_path;
+ e->req_len+=(param_size-e->stdout_path_size);
+ e->stdout_path_size=param_size;
+ break;
+ case PARAM_STDERR:
+ param=e->stderr_path;
+ e->req_len+=(param_size-e->stderr_path_size);
+ e->stderr_path_size=param_size;
+ break;
+ default:
+ error="Internal error";
+ goto err;
+ }
+ strnmov(param,arg_p,FN_REFLEN);
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_OK,"Entry updated");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+
+HANDLE_DECL(handle_start_exec)
+{
+ int num_args;
+ struct manager_exec* e;
+ int ident_len;
+ const char* error=0;
+ struct timespec t;
+ if ((num_args=tokenize_args(args_start,&args_end))<1)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ ident_len=strlen(args_start);
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,args_start,
+ ident_len)))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ manager_exec_launch(e);
+ if ((error=e->error))
+ goto err;
+ pthread_mutex_lock(&e->lock);
+ t.tv_sec=time(0)+(e->start_wait_timeout=atoi(args_start+ident_len+1));
+ t.tv_nsec=0;
+ if (!e->pid)
+ pthread_cond_timedwait(&e->cond,&e->lock,&t);
+ if (!e->pid)
+ {
+ pthread_mutex_unlock(&e->lock);
+ error="Process failed to start withing alotted time";
+ goto err;
+ }
+ mysql_close(&e->mysql);
+ manager_exec_connect(e);
+ error=e->error;
+ pthread_mutex_unlock(&e->lock);
+ if (error)
+ goto err;
+ client_msg(&thd->net,MANAGER_OK,"'%s' started",e->ident);
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_stop_exec)
+{
+ int num_args;
+ struct timespec abstime;
+ struct manager_exec* e;
+ int ident_len;
+ const char* error=0;
+ if ((num_args=tokenize_args(args_start,&args_end))<2)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ ident_len=strlen(args_start);
+ abstime.tv_sec=time(0)+atoi(args_start+1+ident_len);
+ abstime.tv_nsec=0;
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,args_start,
+ ident_len)))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ pthread_mutex_lock(&e->lock);
+ e->th=pthread_self();
+ if (!e->pid)
+ {
+ /* e->th=0; */ /* th may be a struct */
+ pthread_mutex_unlock(&e->lock);
+ error="Process not running";
+ goto err;
+ }
+ if (mysql_shutdown(&e->mysql))
+ {
+ /* e->th=0; */ /* th may be a struct */
+ pthread_mutex_unlock(&e->lock);
+ error="Could not send shutdown command";
+ goto err;
+ }
+ if (e->pid)
+ pthread_cond_timedwait(&e->cond,&e->lock,&abstime);
+ if (e->pid)
+ error="Process failed to terminate within alotted time";
+ /* e->th=0; */ /* th may be a struct */
+ pthread_mutex_unlock(&e->lock);
+ if (!error)
+ {
+ client_msg(&thd->net,MANAGER_OK,"'%s' terminated",e->ident);
+ return 0;
+ }
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_query)
+{
+ const char* error=0;
+ struct manager_exec* e;
+ MYSQL_RES* res=0;
+ MYSQL_ROW row;
+ MYSQL_FIELD* fields;
+ int num_fields,i,ident_len;
+ char* ident,*query;
+ query=ident=args_start;
+ while (!isspace(*query))
+ query++;
+ if (query == ident)
+ {
+ error="Missing server identifier";
+ goto err;
+ }
+ ident_len=(int)(query-ident);
+ while (query<args_end && isspace(*query))
+ query++;
+ if (query == args_end)
+ {
+ error="Missing query";
+ goto err;
+ }
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,ident,
+ ident_len)))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ pthread_mutex_lock(&e->lock);
+ if (!e->pid)
+ {
+ error="Process is not running";
+ pthread_mutex_unlock(&e->lock);
+ goto err;
+ }
+
+ if (mysql_query(&e->mysql,query))
+ {
+ error=mysql_error(&e->mysql);
+ pthread_mutex_unlock(&e->lock);
+ goto err;
+ }
+ if ((res=mysql_store_result(&e->mysql)))
+ {
+ char buf[MAX_CLIENT_MSG_LEN],*p,*buf_end;
+ fields=mysql_fetch_fields(res);
+ num_fields=mysql_num_fields(res);
+ p=buf;
+ buf_end=buf+sizeof(buf);
+ for (i=0;i<num_fields && p<buf_end-2;i++)
+ {
+ p=arg_strmov(p,fields[i].name,buf_end-p-2);
+ *p++='\t';
+ }
+ *p=0;
+ client_msg_pre(&thd->net,MANAGER_OK,buf);
+
+ while ((row=mysql_fetch_row(res)))
+ {
+ p=buf;
+ for (i=0;i<num_fields && p<buf_end-2;i++)
+ {
+ p=arg_strmov(p,row[i],buf_end-p-2);
+ *p++='\t';
+ }
+ *p=0;
+ client_msg_pre(&thd->net,MANAGER_OK,buf);
+ }
+ }
+ pthread_mutex_unlock(&e->lock);
+ client_msg(&thd->net,MANAGER_OK,"End");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_def_exec)
+{
+ struct manager_exec* e=0,*old_e;
+ const char* error=0;
+ if (!(e=manager_exec_new(args_start,args_end)))
+ {
+ error="Out of memory";
+ goto err;
+ }
+ if (e->error)
+ {
+ error=e->error;
+ goto err;
+ }
+ pthread_mutex_lock(&lock_exec_hash);
+ if ((old_e=(struct manager_exec*)hash_search(&exec_hash,(byte*)e->ident,
+ e->ident_len)))
+ {
+ strnmov(e->stdout_path,old_e->stdout_path,sizeof(e->stdout_path));
+ strnmov(e->stderr_path,old_e->stderr_path,sizeof(e->stderr_path));
+ strnmov(e->con_user,old_e->con_user,sizeof(e->con_user));
+ strnmov(e->con_host,old_e->con_host,sizeof(e->con_host));
+ strnmov(e->con_sock,old_e->con_sock,sizeof(e->con_sock));
+ e->con_port=old_e->con_port;
+ update_req_len(e);
+ hash_delete(&exec_hash,(byte*)old_e);
+ }
+ hash_insert(&exec_hash,(byte*)e);
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_OK,"Exec definition created");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ if (e)
+ manager_exec_free(e);
+ return 1;
+}
+
+HANDLE_NOARG_DECL(handle_show_exec)
+{
+ uint i;
+ client_msg_pre(&thd->net,MANAGER_INFO,"Exec_def\tPid\tExit_status\tCon_info\
+\tStdout\tStderr\tArguments");
+ pthread_mutex_lock(&lock_exec_hash);
+ for (i=0;i<exec_hash.records;i++)
+ {
+ struct manager_exec* e=(struct manager_exec*)hash_element(&exec_hash,i);
+ manager_exec_print(&thd->net,e);
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_INFO,"End");
+ return 0;
+}
+
+static struct manager_exec* manager_exec_by_pid(pid_t pid)
+{
+ struct manager_exec* e;
+ uint i;
+ pthread_mutex_lock(&lock_exec_hash);
+ for (i=0;i<exec_hash.records;i++)
+ {
+ e=(struct manager_exec*)hash_element(&exec_hash,i);
+ if (e->pid==pid)
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ return e;
+ }
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ return 0;
+}
+
+static void manager_exec_connect(struct manager_exec* e)
+{
+ int i;
+ int connect_retries;
+
+ if (!(connect_retries=e->start_wait_timeout))
+ connect_retries=manager_connect_retries;
+
+ for (i=0;i<connect_retries;i++)
+ {
+ if (mysql_real_connect(&e->mysql,e->con_host,e->con_user,e->con_pass,0,
+ e->con_port,e->con_sock,0))
+ return;
+ sleep(1);
+ }
+ e->error="Could not connect to MySQL server withing the number of tries";
+}
+
+static int manager_exec_launch(struct manager_exec* e)
+{
+ if (one_thread)
+ {
+ pid_t tmp_pid;
+ switch ((tmp_pid=fork())) {
+ case -1:
+ e->error="Cannot fork";
+ return 1;
+ case 0:
+ {
+ int err_code;
+ close(manager_sock);
+ err_code=execv(e->bin_path,e->args);
+ exit(err_code);
+ }
+ default:
+ e->pid=tmp_pid;
+ manager_exec_connect(e);
+ return 0;
+ }
+ }
+ else
+ {
+ if (my_write(to_launcher_pipe[1],(byte*)&e->req_len,
+ sizeof(int),MYF(MY_NABP))||
+ my_write(to_launcher_pipe[1],(byte*)&e->num_args,
+ sizeof(int),MYF(MY_NABP)) ||
+ my_write(to_launcher_pipe[1],e->stdout_path,e->stdout_path_size,
+ MYF(MY_NABP)) ||
+ my_write(to_launcher_pipe[1],e->stderr_path,e->stderr_path_size,
+ MYF(MY_NABP)) ||
+ my_write(to_launcher_pipe[1],e->data_buf,e->data_buf_size,
+ MYF(MY_NABP)))
+ {
+ e->error="Failed write request to launcher";
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static char* arg_strmov(char* dest, const char* src, int n)
+{
+ char* dest_end = dest+n-1;
+ char c;
+ for (;dest<dest_end && (c=*src++);)
+ {
+ if (c=='%')
+ *dest++='%';
+ *dest++=c;
+ }
+ return dest;
+}
+
+static void manager_exec_print(NET* net,struct manager_exec* e)
+{
+ char buf[MAX_MYSQL_MANAGER_MSG];
+ char* p=buf,*buf_end=buf+sizeof(buf)-1;
+ char** args=e->args;
+
+ p=arg_strmov(p,e->ident,(int)(buf_end-p)-1);
+ *p++='\t';
+ if (p>buf_end-15)
+ goto end;
+ p=int10_to_str(e->pid,p,10);
+ *p++='\t';
+ p=int10_to_str(e->exit_code,p,10);
+ *p++='\t';
+
+ p=arg_strmov(p,e->con_user,(int)(buf_end-p)-1);
+ *p++='@';
+ if (p==buf_end)
+ goto end;
+ p=arg_strmov(p,e->con_host,(int)(buf_end-p)-11);
+ *p++=':';
+ if (p==buf_end-10)
+ goto end;
+ if (e->con_sock[0])
+ {
+ p=arg_strmov(p,e->con_sock,(int)(buf_end-p)-1);
+ }
+ else
+ {
+ p=int10_to_str(e->con_port,p,10);
+ }
+ *p++='\t';
+ p=arg_strmov(p,e->stdout_path,(int)(buf_end-p)-1);
+ if (p==buf_end-1)
+ goto end;
+ *p++='\t';
+ p=arg_strmov(p,e->stderr_path,(int)(buf_end-p)-1);
+ if (p==buf_end-1)
+ goto end;
+ *p++='\t';
+
+ for (;p<buf_end && *args;args++)
+ {
+ p=arg_strmov(p,*args,(int)(buf_end-p)-1);
+ *p++='\t';
+ }
+end:
+ *p=0;
+ client_msg_pre(net,MANAGER_INFO,buf);
+ return;
+}
+
+static int authenticate(struct manager_thd* thd)
+{
+ char* buf_end,*buf,*p,*p_end;
+ my_MD5_CTX context;
+ uchar digest[MD5_LEN];
+ struct manager_user* u;
+ char c;
+
+ client_msg(&thd->net,MANAGER_INFO, manager_greeting);
+ if (!(buf_end=read_line(thd)))
+ return -1;
+ for (buf=thd->cmd_buf,p=thd->user,p_end=p+MAX_USER_NAME;
+ buf<buf_end && (c=*buf) && p<p_end; buf++,p++)
+ {
+ if (isspace(c))
+ {
+ *p=0;
+ break;
+ }
+ else
+ *p=c;
+ }
+ if (p==p_end || buf==buf_end)
+ return 1;
+ if (!(u=(struct manager_user*)hash_search(&user_hash,thd->user,
+ (uint)(p-thd->user))))
+ return 1;
+ for (;isspace(*buf) && buf<buf_end;buf++) /* empty */;
+
+ my_MD5Init(&context);
+ my_MD5Update(&context,(uchar*) buf,(uint)(buf_end-buf));
+ my_MD5Final(digest,&context);
+ if (memcmp(u->md5_pass,digest,MD5_LEN))
+ return 1;
+ client_msg(&thd->net,MANAGER_OK,"OK");
+ return 0;
+}
+
+static void print_time(FILE* fp)
+{
+ struct tm now;
+ time_t t;
+ time(&t);
+ localtime_r(&t,&now);
+ fprintf(fp,"[%d-%02d-%02d %02d:%02d:%02d] ", now.tm_year+1900,
+ now.tm_mon+1,now.tm_mday,now.tm_hour,now.tm_min,
+ now.tm_sec);
+}
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ va_start(args,fmt);
+ if (fmt)
+ {
+ if (errfp==stderr)
+ fprintf(errfp, "%s: ", my_progname);
+ else
+ {
+ print_time(errfp);
+ fprintf(errfp,"Fatal error: ");
+ }
+ vfprintf(errfp, fmt, args);
+ if (errno)
+ fprintf(errfp, " errno=%d", errno);
+ fprintf(errfp, "\n");
+ fflush(errfp);
+ }
+ va_end(args);
+ clean_up();
+ exit(1);
+}
+
+void print_msg_type(int msg_type)
+{
+ const char* msg;
+ switch (msg_type) {
+ case LOG_ERR: msg = "ERROR"; break;
+ case LOG_WARN: msg = "WARNING"; break;
+ case LOG_INFO: msg = "INFO"; break;
+#ifndef DBUG_OFF
+ case LOG_DEBUG: msg = "DEBUG"; break;
+#endif
+ default: msg = "UNKNOWN TYPE"; break;
+ }
+ fprintf(errfp," %s: ", msg);
+}
+
+static void log_msg(const char* fmt, int msg_type, va_list args)
+{
+ pthread_mutex_lock(&lock_log);
+ print_time(errfp);
+ print_msg_type(msg_type);
+ vfprintf(errfp,fmt,args);
+ fputc('\n',errfp);
+ fflush(errfp);
+ pthread_mutex_unlock(&lock_log);
+}
+
+static pthread_handler_decl(process_launcher_messages,
+ args __attribute__((unused)))
+{
+ my_thread_init();
+ for (;!in_shutdown;)
+ {
+ pid_t pid;
+ struct manager_exec* e;
+ char buf[MAX_LAUNCHER_MSG];
+ if (read(from_launcher_pipe[0],buf,MAX_LAUNCHER_MSG)<0)
+ {
+ log_err("error reading launcher message");
+ sleep(1);
+ continue;
+ }
+ switch (buf[0]) {
+ case CHILD_START:
+ {
+ char* ident=buf+1;
+ int ident_len=strlen(ident);
+ memcpy(&pid,ident+ident_len+1,sizeof(pid));
+ log_debug("process message - ident=%s ident_len=%d pid=%d",ident,
+ ident_len,pid);
+ pthread_mutex_lock(&lock_exec_hash);
+ log_debug("hash has %d records",exec_hash.records);
+ e=(struct manager_exec*)hash_search(&exec_hash,ident,ident_len);
+ if (e)
+ {
+ pthread_mutex_lock(&e->lock);
+ e->pid=pid;
+ pthread_cond_broadcast(&e->cond);
+ pthread_mutex_unlock(&e->lock);
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ log_debug("unlocked mutex");
+ break;
+ }
+ case CHILD_STOP:
+ memcpy(&pid,buf+1,sizeof(pid));
+ e=manager_exec_by_pid(pid);
+ if (e)
+ {
+ pthread_mutex_lock(&e->lock);
+ e->pid=0;
+ memcpy(&e->exit_code,buf+1+sizeof(pid),sizeof(int));
+ pthread_cond_broadcast(&e->cond);
+ pthread_mutex_unlock(&e->lock);
+ }
+ break;
+ default:
+ log_err("Got invalid launcher message");
+ break;
+ }
+ }
+ return 0;
+}
+
+static pthread_handler_decl(process_connection,arg)
+{
+ struct manager_thd* thd = (struct manager_thd*)arg;
+ my_thread_init();
+ pthread_detach_this_thread();
+ for (;!thd->finished;)
+ {
+ char* buf_end;
+ if ((!(buf_end=read_line(thd)) || exec_line(thd,thd->cmd_buf,buf_end))
+ && thd->fatal)
+ {
+ log_err("Thread aborted");
+ break;
+ }
+ }
+ manager_thd_free(thd);
+ pthread_exit(0);
+ return 0; /* Don't get cc warning */
+}
+
+static int client_msg_raw(NET* net, int err_code, int pre, const char* fmt,
+ va_list args)
+{
+ char buf[MAX_CLIENT_MSG_LEN],*p,*buf_end;
+ p=buf;
+ buf_end=buf+sizeof(buf);
+ p=int10_to_str(err_code,p,10);
+ if (pre)
+ *p++='-';
+ *p++=' ';
+ p+=my_vsnprintf(p,buf_end-p,fmt,args);
+ if (p>buf_end-2)
+ p=buf_end - 2;
+ *p++='\r';
+ *p++='\n';
+ log_debug("message to client: %-.*s",p-buf-2,buf);
+ if (my_net_write(net,buf,(uint)(p-buf)) || net_flush(net))
+ {
+ p[-2]=0;
+ log_err("Failed writing '%s' to client: errno=%d",buf,errno);
+ net_end(net);
+ return 1;
+ }
+ return 0;
+}
+
+static int client_msg(NET* net, int err_code, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args,fmt);
+ return client_msg_raw(net,err_code,0,fmt,args);
+}
+
+static int client_msg_pre(NET* net, int err_code, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args,fmt);
+ return client_msg_raw(net,err_code,1,fmt,args);
+}
+
+static char* read_line(struct manager_thd* thd)
+{
+ int len;
+ char* p, *buf_end;
+ if ((len=my_net_read(&thd->net)) == (int)packet_error || !len)
+ {
+ log_err("Error reading command from client (Error: %d)",
+ errno);
+ thd->fatal=1;
+ return 0;
+ }
+ buf_end=thd->cmd_buf+len;
+ for (p=thd->cmd_buf;p<buf_end;p++)
+ if (*p == '\r' || *p == '\n')
+ {
+ *p=0;
+ break;
+ }
+
+ return p;
+}
+
+static void handle_child(int __attribute__((unused)) sig)
+{
+ pid_t child;
+ int child_status;
+
+ for (;(child=waitpid(-1,&child_status,WNOHANG))>0;)
+ {
+ char msg_buf[1+sizeof(int)+sizeof(int)];
+ msg_buf[0]=CHILD_STOP;
+ memcpy(msg_buf+1,&child,sizeof(int));
+ memcpy(msg_buf+1+sizeof(int),&child_status,sizeof(int));
+ if (write(from_launcher_pipe[1],msg_buf,sizeof(msg_buf))!=sizeof(msg_buf))
+ log_err("launcher: error writing message on child exit");
+ }
+ signal(SIGCHLD,handle_child);
+}
+
+struct manager_thd* manager_thd_new(Vio* vio)
+{
+ struct manager_thd* tmp;
+ if (!(tmp=(struct manager_thd*)my_malloc(sizeof(*tmp),
+ MYF(0))))
+ {
+ log_err("Out of memory in manager_thd_new");
+ return 0;
+ }
+ my_net_init(&tmp->net,vio);
+ tmp->user[0]=0;
+ tmp->priv_flags=0;
+ tmp->fatal=tmp->finished=0;
+ tmp->cmd_buf= (char*) tmp->net.read_pos;
+ return tmp;
+}
+
+static void manager_thd_free(struct manager_thd* thd)
+{
+ NET* net=&thd->net;
+ if (net->vio)
+ {
+ vio_delete(net->vio);
+ net->vio=0;
+ }
+ net_end(&thd->net);
+}
+
+static void clean_up()
+{
+ pthread_mutex_lock(&lock_shutdown);
+ if (in_shutdown)
+ {
+ pthread_mutex_unlock(&lock_shutdown);
+ return;
+ }
+ in_shutdown = 1;
+ pthread_mutex_unlock(&lock_shutdown);
+ log_info("Shutdown started");
+ if (manager_sock)
+ close(manager_sock);
+ log_info("Ended");
+ if (errfp != stderr)
+ my_fclose(errfp, MYF(0));
+ hash_free(&exec_hash);
+ if (created_pid_file)
+ my_delete(pid_file, MYF(0));
+}
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MANAGER_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+static void usage()
+{
+ print_version();
+ printf("MySQL AB, by Sasha\n");
+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
+ printf("Manages instances of MySQL server.\n\n");
+ printf("Usage: %s [OPTIONS]\n\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/mysqlmgrd.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+
+static int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
+static int init_server()
+{
+ int arg=1;
+ log_info("Started");
+ if ((manager_sock=socket(PF_INET,SOCK_STREAM,0)) < 0)
+ die("Could not create socket");
+ bzero((char*) &manager_addr, sizeof(manager_addr));
+ manager_addr.sin_family = AF_INET;
+ manager_addr.sin_addr.s_addr = manager_bind_addr;
+ manager_addr.sin_port = htons(manager_port);
+ setsockopt(manager_sock,SOL_SOCKET, SO_REUSEADDR,(char*)&arg,sizeof(arg));
+ if (bind(manager_sock,(struct sockaddr*)&manager_addr, sizeof(manager_addr))
+ < 0)
+ die("Could not bind");
+ if (listen(manager_sock,manager_back_log) < 0)
+ die("Could not listen");
+
+ return 0;
+}
+
+static int run_server_loop()
+{
+ pthread_t th;
+ struct manager_thd *thd;
+ int client_sock;
+ Vio* vio;
+ pthread_attr_t thr_attr;
+ (void) pthread_attr_init(&thr_attr);
+#if !defined(HAVE_DEC_3_2_THREADS)
+ pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
+ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
+#endif
+
+ for (;!shutdown_requested;)
+ {
+ size_socket len=sizeof(struct sockaddr_in);
+ if ((client_sock=accept(manager_sock,(struct sockaddr*)&manager_addr,
+ &len)) <0)
+ {
+ if (shutdown_requested)
+ break;
+ if (errno != EAGAIN)
+ {
+ log_warn("Error in accept, errno=%d", errno);
+ sleep(1); /* avoid tying up CPU if accept is broken */
+ }
+ continue;
+ }
+ if (shutdown_requested)
+ break;
+ if (!(vio=vio_new(client_sock,VIO_TYPE_TCPIP,FALSE)))
+ {
+ log_err("Could not create I/O object");
+ close(client_sock);
+ continue;
+ }
+ if (!(thd=manager_thd_new(vio)))
+ {
+ log_err("Could not create thread object");
+ vio_close(vio);
+ continue;
+ }
+ if (authenticate(thd))
+ {
+ client_msg(&thd->net,MANAGER_ACCESS, "Access denied");
+ manager_thd_free(thd);
+ log_info("Client failed to authenticate");
+ continue;
+ }
+ if (shutdown_requested)
+ {
+ manager_thd_free(thd);
+ break;
+ }
+ if (one_thread)
+ {
+ process_connection((void*)thd);
+ manager_thd_free(thd);
+ continue;
+ }
+ else if (pthread_create(&th,&thr_attr,process_connection,(void*)thd))
+ {
+ client_msg(&thd->net,MANAGER_INTERNAL_ERR,
+ "Could not create thread, errno=%d",
+ errno);
+ manager_thd_free(thd);
+ continue;
+ }
+ }
+ (void) pthread_attr_destroy(&thr_attr);
+ return 0;
+}
+
+static FILE* open_log_stream()
+{
+ FILE* fp;
+ if (!(fp=my_fopen(manager_log_file, O_APPEND | FILE_BINARY, MYF(MY_WME))))
+ {
+ clean_up();
+ exit(1);
+ }
+ return fp;
+}
+
+static byte* get_user_key(const byte* u, uint* len,
+ my_bool __attribute__((unused)) t)
+{
+ register const char* key;
+ key = ((struct manager_user*)u)->user;
+ *len = ((struct manager_user*)u)->user_len;
+ return (byte*)key;
+}
+
+static byte* get_exec_key(const byte* e, uint* len,
+ my_bool __attribute__((unused)) t)
+{
+ register const char* key;
+ key = ((struct manager_exec*)e)->ident;
+ *len = ((struct manager_exec*)e)->ident_len;
+ return (byte*)key;
+}
+
+static void init_arg_array(char* arg_str,char** args,uint arg_count)
+{
+ char* p = arg_str;
+ for (;arg_count>0;arg_count--)
+ {
+ *args++=p;
+ p += strlen(p)+1;
+ }
+ *args=0;
+}
+
+static uint tokenize_args(char* arg_start,char** arg_end)
+{
+ char* p, *p_write,*p_end;
+ uint arg_count=0;
+ int quoted=0,escaped=0,last_space=0;
+ p_end=*arg_end;
+ p_write=p=arg_start;
+ for (; p < p_end ; p++)
+ {
+ char c = *p;
+ switch (c) {
+ case ' ':
+ case '\r':
+ case '\n':
+ if (!quoted)
+ {
+ if (!last_space)
+ {
+ *p_write++=0;
+ arg_count++;
+ last_space=1;
+ }
+ }
+ else
+ *p_write++=c;
+ escaped=0;
+ break;
+ case '"':
+ if (!escaped)
+ quoted=!quoted;
+ else
+ *p_write++=c;
+ last_space=0;
+ escaped=0;
+ break;
+ case '\\':
+ if (!escaped)
+ escaped=1;
+ else
+ {
+ *p_write++=c;
+ escaped=0;
+ }
+ last_space=0;
+ break;
+ default:
+ escaped=last_space=0;
+ *p_write++=c;
+ break;
+ }
+ }
+ if (!last_space && p_write>arg_start)
+ arg_count++;
+ *p_write=0;
+ *arg_end=p_write;
+ log_debug("arg_count: %d arg_start: '%s'",arg_count,arg_start);
+ return arg_count;
+}
+
+static void update_req_len(struct manager_exec* e)
+{
+ e->req_len=(e->data_buf_size+
+ (e->stdout_path_size=strlen(e->stdout_path)+1)+
+ (e->stderr_path_size=strlen(e->stderr_path)+1));
+}
+
+static struct manager_exec* manager_exec_new(char* arg_start,char* arg_end)
+{
+ struct manager_exec* tmp;
+ char* first_arg;
+ uint arg_len,num_args;
+ num_args=tokenize_args(arg_start,&arg_end);
+ arg_len=(uint)(arg_end-arg_start)+1; /* include \0 terminator*/
+ if (!(tmp=(struct manager_exec*)my_malloc(sizeof(*tmp)+arg_len+
+ sizeof(char*)*num_args,
+ MYF(MY_ZEROFILL))))
+ return 0;
+ if (num_args<2)
+ {
+ tmp->error="Too few arguments";
+ return tmp;
+ }
+ /* We have to allocate 'args' first as this must be alligned */
+ tmp->args=(char**)(tmp +1);
+ tmp->data_buf= (char*) (tmp->args + num_args);
+ memcpy(tmp->data_buf,arg_start,arg_len);
+ tmp->data_buf_size=arg_len;
+ tmp->num_args=num_args;
+ tmp->ident=tmp->data_buf;
+ tmp->ident_len=strlen(tmp->ident);
+ first_arg=tmp->ident+tmp->ident_len+1;
+ init_arg_array(first_arg,tmp->args,num_args-1);
+ strmov(tmp->con_user,"root");
+ tmp->con_port=MYSQL_PORT;
+ memcpy(tmp->con_host,"localhost",10);
+ tmp->bin_path=tmp->args[0];
+ tmp->stdout_path_size=tmp->stderr_path_size=1;
+ tmp->req_len=tmp->data_buf_size+2;
+ pthread_mutex_init(&tmp->lock,0);
+ pthread_cond_init(&tmp->cond,0);
+ mysql_init(&tmp->mysql);
+ return tmp;
+}
+
+static void manager_exec_free(void* e)
+{
+ mysql_close(&((struct manager_exec*)e)->mysql);
+ my_free(e,MYF(0));
+}
+
+static int hex_val(char c)
+{
+ if (isdigit(c))
+ return c-'0';
+ c=tolower(c);
+ return c-'a'+10;
+}
+
+static struct manager_user* manager_user_new(char* buf)
+{
+ struct manager_user* tmp;
+ char* p,*user_end,*p_end;
+ char c;
+ if (!(tmp=(struct manager_user*)my_malloc(sizeof(*tmp),MYF(0))))
+ return 0;
+ p=tmp->user;
+ tmp->error=0;
+ user_end=p+MAX_USER_NAME;
+ for (;(c=*buf) && p<user_end;buf++)
+ {
+ if (c == ':')
+ {
+ *p=0;
+ tmp->user_len=p-tmp->user;
+ buf++;
+ break;
+ }
+ else
+ *p++=c;
+ }
+ if (!c)
+ tmp->error="Missing ':'";
+ if (p == user_end)
+ tmp->error="Username too long";
+ if (tmp->error)
+ return tmp;
+ if (strlen(buf) < 2*MD5_LEN)
+ {
+ tmp->error="Invalid MD5 sum, too short";
+ return tmp;
+ }
+ p=tmp->md5_pass;
+ p_end=p+MD5_LEN;
+ for (; p<p_end;p++,buf+=2)
+ {
+ *p=hex_val(*buf)*16+hex_val(buf[1]);
+ }
+
+ return tmp;
+}
+
+static void manager_user_free(void* u)
+{
+ my_free((gptr)u,MYF(0));
+}
+
+static void init_user_hash()
+{
+ FILE* f;
+ char buf[80];
+ int line_num=1;
+ if (hash_init(&user_hash,1024,0,0,get_user_key,manager_user_free,MYF(0)))
+ die("Could not initialize user hash");
+ if (!(f=my_fopen(manager_pw_file, O_RDONLY | O_BINARY, MYF(MY_WME))))
+ {
+ clean_up();
+ exit(1);
+ }
+ for (;;line_num++)
+ {
+ struct manager_user* u;
+ if (!fgets(buf,sizeof(buf),f) || feof(f))
+ break;
+ if (buf[0] == '#')
+ continue;
+ if (!(u=manager_user_new(buf)))
+ die("Out of memory while reading user line");
+ if (u->error)
+ {
+ die("Error on line %d of '%s': %s",line_num,manager_pw_file, u->error);
+ }
+ else
+ {
+ hash_insert(&user_hash,(gptr)u);
+ }
+ }
+ my_fclose(f, MYF(0));
+}
+
+
+static void init_pid_file()
+{
+ FILE* fp = my_fopen(pid_file, O_WRONLY | O_BINARY, MYF(MY_WME));
+ if (!fp)
+ {
+ clean_up();
+ exit(1);
+ }
+ created_pid_file=1;
+ fprintf(fp, "%d\n", (int) getpid());
+ my_fclose(fp, MYF(0));
+}
+
+
+static void init_globals()
+{
+ pthread_attr_t thr_attr;
+ if (hash_init(&exec_hash,1024,0,0,get_exec_key,manager_exec_free,MYF(0)))
+ die("Exec hash initialization failed");
+ if (!one_thread)
+ {
+ (void) pthread_attr_init(&thr_attr);
+#if !defined(HAVE_DEC_3_2_THREADS)
+ pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
+ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
+#endif
+ fork_launcher();
+ if (pthread_create(&launch_msg_th,&thr_attr,process_launcher_messages,0))
+ die("Could not start launcher message handler thread");
+ /* (void) pthread_attr_destroy(&thr_attr); */
+ }
+ init_user_hash();
+ init_pid_file();
+ loop_th=pthread_self();
+ signal(SIGPIPE,handle_sigpipe);
+ signal(SIGTERM,handle_sigterm);
+}
+
+static int open_and_dup(int fd,char* path)
+{
+ int old_fd;
+ if ((old_fd=my_open(path,O_WRONLY|O_APPEND|O_CREAT,MYF(0)))<0)
+ {
+ log_err("Could not open '%s' for append, errno=%d",path,errno);
+ return 1;
+ }
+ if (dup2(old_fd,fd)<0)
+ {
+ log_err("Failed in dup2(), errno=%d",errno);
+ return 1;
+ }
+ my_close(old_fd,MYF(0));
+ return 0;
+}
+
+static void run_launcher_loop()
+{
+ for (;;)
+ {
+ int req_len,ident_len,num_args;
+ char* request_buf=0;
+ pid_t pid;
+ char* exec_path,*ident,*stdout_path,*stderr_path;
+ char** args=0;
+
+ if (my_read(to_launcher_pipe[0],(byte*)&req_len,
+ sizeof(int),MYF(MY_NABP|MY_FULL_IO)) ||
+ my_read(to_launcher_pipe[0],(byte*)&num_args,
+ sizeof(int),MYF(MY_NABP|MY_FULL_IO)) ||
+ !(request_buf=(char*)my_malloc(req_len+sizeof(pid)+2,MYF(0))) ||
+ !(args=(char**)my_malloc(num_args*sizeof(char*),MYF(0))) ||
+ my_read(to_launcher_pipe[0],request_buf,req_len,
+ MYF(MY_NABP|MY_FULL_IO)))
+ {
+ log_err("launcher: Error reading request");
+ my_free((gptr)request_buf,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr)args,MYF(MY_ALLOW_ZERO_PTR));
+ sleep(1);
+ continue;
+ }
+ stdout_path=request_buf;
+ stderr_path=stdout_path+strlen(stdout_path)+1;
+ request_buf=stderr_path+strlen(stderr_path); /* black magic */
+ ident=request_buf+1;
+ ident_len=strlen(ident);
+ exec_path=ident+ident_len+1;
+ log_debug("num_args=%d,req_len=%d,ident=%s,ident_len=%d,exec_path=%s,\
+stdout_path=%s,stderr_path=%s",
+ num_args,
+ req_len,ident,ident_len,exec_path,stdout_path,stderr_path);
+ init_arg_array(exec_path,args,num_args-1);
+
+ switch ((pid=fork())) {
+ case -1:
+ log_err("launcher: cannot fork");
+ sleep(1);
+ break;
+ case 0:
+ if (open_and_dup(1,stdout_path) || open_and_dup(2,stderr_path))
+ exit(1);
+ if (execv(exec_path,args))
+ log_err("launcher: cannot exec %s",exec_path);
+ exit(1);
+ default:
+ request_buf[0]=CHILD_START;
+ memcpy(request_buf+ident_len+2,&pid,sizeof(pid));
+ if (write(from_launcher_pipe[1],request_buf,ident_len+2+sizeof(pid))<0)
+ log_err("launcher: error sending launch status report");
+ break;
+ }
+ my_free((gptr)(stdout_path),MYF(0));
+ my_free((gptr)args,MYF(0));
+ }
+}
+
+static void fork_launcher()
+{
+ if (pipe(to_launcher_pipe) || pipe(from_launcher_pipe))
+ die("Could not create launcher pipes");
+ switch ((launcher_pid=fork())) {
+ case 0:
+ signal(SIGCHLD,handle_child);
+ run_launcher_loop();
+ exit(0);
+ case -1: die("Could not fork the launcher");
+ default: return;
+ }
+}
+
+static int daemonize()
+{
+ switch (fork()) {
+ case -1:
+ die("Cannot fork");
+ case 0:
+ errfp = open_log_stream();
+ init_globals();
+ close(0);
+ close(1);
+ close(2);
+ init_server();
+ run_server_loop();
+ clean_up();
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ char c;
+ stack_bottom= (uchar *) &c;
+ MY_INIT(argv[0]);
+ errfp = stderr;
+ parse_args(argc,argv);
+ pthread_mutex_init(&lock_log,0);
+ pthread_mutex_init(&lock_shutdown,0);
+ pthread_mutex_init(&lock_exec_hash,0);
+ pthread_mutex_init(&lock_launch_thd,0);
+ pthread_cond_init(&cond_launch_thd,0);
+#ifdef DO_STACKTRACE
+ signal(SIGSEGV,handle_segfault);
+#endif
+ if (one_thread)
+ {
+ init_globals();
+ init_server();
+ run_server_loop();
+ clean_up();
+ return 0;
+ }
+ else
+ return daemonize();
+}
diff --git a/vio/Makefile.am b/vio/Makefile.am
index 9bb8691eee6..b512ec33777 100644
--- a/vio/Makefile.am
+++ b/vio/Makefile.am
@@ -14,20 +14,21 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-INCLUDES = -I$(srcdir)/../include -I../include \
- @OPENSSL_INCLUDES@
-LDADD = libvio.la
-pkglib_LTLIBRARIES = libvio.la
-noinst_PROGRAMS =
+INCLUDES = -I$(srcdir)/../include -I../include $(openssl_includes)
+LDADD = @CLIENT_EXTRA_LDFLAGS@ libvio.a $(openssl_libs)
+pkglib_LIBRARIES = libvio.a
+noinst_PROGRAMS = test-ssl test-sslserver test-sslclient
noinst_HEADERS =
-libvio_la_SOURCES = \
- Vio.cc VioAcceptorFd.cc \
- VioConnectorFd.cc VioFd.cc \
- VioHandle.cc VioSSL.cc \
- VioSSLFactoriesFd.cc VioSocket.cc \
- auto.cc hostnamexx.cc \
- vdbug.cc version.cc \
- vmem.cc violitexx.cc
+test_ssl_SOURCES = test-ssl.c
+test_ssl_LDADD = @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a ../mysys/libmysys.a \
+ ../strings/libmystrings.a libvio.a $(openssl_libs)
+test_sslserver_SOURCES = test-sslserver.c
+test_sslserver_LDADD = @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a ../mysys/libmysys.a \
+ ../strings/libmystrings.a libvio.a $(openssl_libs)
+test_sslclient_SOURCES = test-sslclient.c
+test_sslclient_LDADD = @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a ../mysys/libmysys.a \
+ ../strings/libmystrings.a libvio.a $(openssl_libs)
+libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
__math.h time.h __time.h unistd.h __unistd.h types.h \
diff --git a/vio/Vio.cc b/vio/Vio.cc
deleted file mode 100644
index b15f9cfa6d2..00000000000
--- a/vio/Vio.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-#include "vio-global.h"
-
-VIO_NS_BEGIN
-
-void
-Vio::release()
-{
- delete this;
-}
-
-Vio::~Vio()
-{
-}
-
-VIO_NS_END
diff --git a/vio/Vio.h b/vio/Vio.h
deleted file mode 100644
index 959d472873f..00000000000
--- a/vio/Vio.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Abstract Virtual IO interface - class Vio. Heavily
- * influenced by Berkeley sockets and oriented toward MySQL.
- */
-
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-** Modified by Monty
-*/
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
- VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
-
-class Vio {
-public:
- virtual bool is_open() const = 0;
- virtual int read(vio_ptr buf, int size) = 0;
- virtual int write(const vio_ptr buf, int size) = 0;
- virtual int blocking(bool onoff) = 0;
- virtual bool blocking() const = 0;
- virtual bool fcntl() const = 0;
- virtual int fastsend(bool onoff = true) = 0;
- virtual int keepalive(bool onoff) = 0;
- virtual bool should_retry() const = 0;
- virtual int close() = 0;
- virtual void release();
- virtual const char* description() const = 0;
- virtual bool peer_addr(char *buf) const = 0;
- virtual const char* cipher_description() const = 0;
- virtual int vio_errno();
- virtual ~Vio();
-};
-
-/* Macros to simulate the violite C interface */
-
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type,
- my_bool localhost);
-#ifdef __WIN__
-Vio* vio_new_win32pipe(HANDLE hPipe);
-#endif
-
-#define vio_delete(vio) delete vio
-#define vio_read(vio,buf,size) vio->read(buf,size)
-#define vio_write(vio,buf,size) vio->write(buf,size)
-#define vio_blocking(vio,mode) vio->blocking(mode)
-#define vio_is_blocking(vio) vio->is_blocking()
-#define vio_fastsend(vio,mode) vio->fastsend(mode)
-#define vio_keepalive(vio,mode) vio->keepalive(mode)
-#define vio_shouldretry(vio) vio->shouldretry(mode)
-#define vio_close(vio) vio->close()
-#define vio_description(vio) vio->description()
-#define vio_errno(Vio *vio) vio->errno()
-#define vio_peer_addr(vio,buf) vio->peer_addr(buf)
-#define vio_in_addr(vio,in) vio->in_addr(in)
-
-VIO_NS_END
diff --git a/vio/VioAcceptorFd.cc b/vio/VioAcceptorFd.cc
deleted file mode 100644
index 4572e2cb71b..00000000000
--- a/vio/VioAcceptorFd.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#include "vio-global.h"
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-VioAcceptorFd::~VioAcceptorFd()
-{
-}
-
-VIO_NS_END
diff --git a/vio/VioAcceptorFd.h b/vio/VioAcceptorFd.h
deleted file mode 100644
index e0441780db9..00000000000
--- a/vio/VioAcceptorFd.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * Abstract acceptor.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioAcceptorFd
-{
-public:
- virtual ~VioAcceptorFd();
- virtual Vio* accept( int fd) = 0;
-};
-
-VIO_NS_END
diff --git a/vio/VioConnectorFd.cc b/vio/VioConnectorFd.cc
deleted file mode 100644
index 49f81077a84..00000000000
--- a/vio/VioConnectorFd.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/*
- * Unneccessary virtual destructor.
- */
-
-#include "vio-global.h"
-#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#include "viotypes.h"
-#include "Vio.h"
-#include "VioConnectorFd.h"
-
-VIO_NS_BEGIN
-
-VioConnectorFd::~VioConnectorFd()
-{
-}
-
-VIO_NS_END
-
diff --git a/vio/VioConnectorFd.h b/vio/VioConnectorFd.h
deleted file mode 100644
index da684df5f1b..00000000000
--- a/vio/VioConnectorFd.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Abstract connector. The file (or socket) descriptor has to be
- * prepared.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioConnectorFd
-{
-public:
- virtual ~VioConnectorFd();
- virtual Vio* connect(int fd) = 0;
-};
-
-VIO_NS_END
diff --git a/vio/VioFd.cc b/vio/VioFd.cc
deleted file mode 100644
index da59798fc25..00000000000
--- a/vio/VioFd.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
-** Virtual I/O library for files
-** Written by Andrei Errapart <andreie@no.spam.ee>
-** Checked and modfied by Monty
-*/
-
-#include "vio-global.h"
-#include <assert.h>
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-VioFd::VioFd( int fd) : fd_(fd)
-{
- sprintf(desc_, "VioFd(%d)", fd_);
-}
-
-VioFd:: ~VioFd()
-{
- if (fd_ >= 0)
- {
- it r = ::close(fd_);
- if ( r < 0)
- {
- /* FIXME: error handling (Not Critical for MySQL) */
- }
- }
-}
-
-
-bool
-VioFd::open() const
-{
- return fd_ >= 0;
-}
-
-int
-VioFd::read(vio_ptr buf, int size)
-{
- assert(fd_>=0);
- return ::read(fd_, buf, size);
-}
-
-int
-VioFd::write(const vio_ptr buf, int size)
-{
- assert(fd_>=0);
- return ::write(fd_, buf, size);
-}
-
-int
-VioFd::blocking(bool onoff)
-{
- if (onoff)
- return 0;
- else
- return -1;
-}
-
-bool
-VioFd::blocking() const
-{
- return true;
-}
-
-int
-VioFd::fastsend(bool tmp)
-{
- return 0;
-}
-
-
-int
-VioFd::keepalive(boolonoff)
-{
- return -2; // Why -2 ? (monty)
-}
-
-bool
-VioFd::fcntl() const
-{
- return FALSE;
-}
-
-bool
-VioFd::should_retry() const
-{
- return FALSE;
-}
-
-int
-VioFd::fcntl(int cmd)
-{
- assert(fd_>=0);
- return ::fcntl(fd_, cmd);
-}
-
-int
-VioFd::fcntl(int cmd, long arg)
-{
- assert(fd_>=0);
- return ::fcntl(fd_, cmd, arg);
-}
-
-int
-VioFd::fcntl(int cmd, struct flock* lock)
-{
- assert(fd_>=0);
- return ::fcntl(fd_, cmd, lock);
-}
-
-int
-VioFd::close()
-{
- int r = -2;
- if (fd_>=0)
- {
-
- if ((r= ::close(fd_)) == 0)
- fd_ = -1;
- }
- else
- {
- /* FIXME: error handling */
- }
- return r;
-}
-
-const char*
-VioFd::description() const
-{
- return desc_;
-}
-
-const char*
-VioFd::peer_addr() const
-{
- return "";
-}
-
-const char*
-VioFd::peer_name() const
-{
- return "localhost";
-}
-
-const char*
-VioFd::cipher_description() const
-{
- return "";
-}
-
-VIO_NS_END
diff --git a/vio/VioFd.h b/vio/VioFd.h
deleted file mode 100644
index f1c009d848c..00000000000
--- a/vio/VioFd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Concrete Vio around a file descriptor.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioFd : public Vio
-{
-public:
- VioFd( int fd);
- virtual ~VioFd();
- virtual bool open() const;
- virtual int read( vio_ptr buf, int size);
- virtual int write( const vio_ptr buf, int size);
- virtual bool blocking() const;
- virtual int blocking(bool onoff);
- virtual int fastsend(bool onoff=true);
- virtual int keepalive( bool onoff);
- virtual bool fcntl() const;
- virtual bool should_retry() const;
- virtual int fcntl( int cmd);
- virtual int fcntl( int cmd, long arg);
- virtual int fcntl( int cmd, struct flock* lock);
- virtual int close();
- virtual const char* description() const;
- virtual const char* peer_addr() const;
- virtual bool peer_name(char *buf) const;
- virtual const char* cipher_description() const;
-private:
- int fd_;
- char desc_[100];
-};
-
-VIO_NS_END
diff --git a/vio/VioPipe.cc b/vio/VioPipe.cc
deleted file mode 100644
index 5d6f9f36496..00000000000
--- a/vio/VioPipe.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-** Virtual I/O library for Windows named pipes
-** Written by Monty
-*/
-
-
-#ifdef __WIN32__
-#include "vio-global.h"
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-
-
-
-
-
-
-
-VIO_NS_END
-
-#endif /* WIN32 */
diff --git a/vio/VioPipe.h b/vio/VioPipe.h
deleted file mode 100644
index a6bb587c548..00000000000
--- a/vio/VioPipe.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Concrete Vio around Handle.
- */
-
-#ifdef __WIN__
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioPipe : public Vio
-{
-public:
- VioPipe(int fd);
- virtual ~VioPipe();
- virtual bool is_open() const;
- virtual int read(vio_ptr buf, int size);
- virtual int write(const vio_ptr buf, int size);
- virtual int blocking(bool onoff);
- virtual bool blocking() const;
- virtual bool fcntl() const;
- virtual int fastsend(bool onoff = true);
- virtual int keepalive(bool onoff);
- virtual bool should_retry() const;
- virtual int close();
- virtual void release();
- virtual const char* description() const;
- virtual bool peer_addr(char *buf) const;
- virtual const char* cipher_description() const { return "";}
- virtual int vio_errno();
-private:
-};
-
-VIO_NS_END
-
-#endif /* WIN32 */
diff --git a/vio/VioSSL.cc b/vio/VioSSL.cc
deleted file mode 100644
index 15964c09aba..00000000000
--- a/vio/VioSSL.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
-** Virtual I/O library for SSL wrapper
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * This file has some huge DBUG_ statements. Boy, this is silly...
- */
-
-#include "vio-global.h"
-#ifdef VIO_HAVE_OPENSSL
-#include <assert.h>
-#include <netinet/in.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-#define this_ssl_con my_static_cast(SSL*)(this->ssl_con_)
-#define this_bio my_static_cast(BIO*)(this->bio_)
-typedef char* dataptr_t;
-
-static void
-report_errors()
-{
- unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
- DBUG_ENTER("VioSSLConnectorFd::report_errors");
-
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
- {
- char buf[200];
- DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
- file,line,(flags&ERR_TXT_STRING)?data:"")) ;
- }
- DBUG_VOID_RETURN;
-}
-
-//FIXME: duplicate code!
-VioSSL::VioSSL(int fd,
- vio_ptr ssl_context,
- int state)
- : bio_(0), ssl_con_(0), open_(FALSE), sd_(new VioSocket(fd))
-{
- DBUG_ENTER("VioSSL::VioSSL");
- DBUG_PRINT("enter", ("this=%p, fd=%d, ssl_context=%p, state=%d",
- this, fd, ssl_context, state));
- assert(fd!=0);
- assert(ssl_context!=0);
- assert(state==state_connect || state==state_accept);
-
- if (!init_bio_(fd, ssl_context, state, BIO_NOCLOSE))
- open_ = true;
- DBUG_VOID_RETURN;
-}
-
-
-VioSSL::VioSSL(VioSocket* sd,
- vio_ptr ssl_context,
- int state)
- :bio_(0), ssl_con_(0), open_(FALSE), sd_(sd)
-{
- DBUG_ENTER("VioSSL::VioSSL");
- DBUG_PRINT("enter",
- ("this=%p, sd=%s, ssl_context=%p, state=%d",
- this, sd ? sd->description() : "0", ssl_context, state));
- assert(sd != 0);
- assert(ssl_context != 0);
- assert(state == state_connect || state==state_accept);
-
- if (!init_bio_(sd->sd_, ssl_context, state, BIO_NOCLOSE))
- open_ = true;
- DBUG_VOID_RETURN;
-}
-
-VioSSL::~VioSSL()
-{
- DBUG_ENTER("VioSSL::~VioSSL");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_con_!=0)
- {
- SSL_shutdown(this_ssl_con);
- SSL_free(this_ssl_con);
- }
- if (sd_!=0)
- delete sd_;
- /* FIXME: no need to close bio? */
- /*
- if (bio_!=0)
- BIO_free(this_bio);
- */
- DBUG_VOID_RETURN;
-}
-
-bool
-VioSSL::is_open() const
-{
- return open_;
-}
-
-int
-VioSSL::read(vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSSL::read");
- DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
- assert(this_ssl_con != 0);
- r = SSL_read(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
- if ( r< 0)
- report_errors();
- DBUG_PRINT("exit", ("r=%d", r));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::write(const vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSSL::write");
- DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
- assert(this_ssl_con!=0);
- r = SSL_write(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
- if (r<0)
- report_errors();
- DBUG_PRINT("exit", ("r=%d", r));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::blocking(bool onoff)
-{
- int r;
- DBUG_ENTER("VioSSL::blocking");
- DBUG_PRINT("enter", ("this=%p, onoff=%s", this, onoff?"true":"false"));
- r = sd_->blocking(onoff);
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-bool
-VioSSL::blocking() const
-{
- bool r;
- DBUG_ENTER("VioSSL::blocking");
- DBUG_PRINT("enter", ("this=%p", this));
- r = sd_->blocking();
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::fastsend(bool onoff)
-{
- int r;
- DBUG_ENTER("VioSSL::fastsend");
- DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
- r = sd_->fastsend(onoff);
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-int VioSSL::keepalive(bool onoff)
-{
- int r;
- DBUG_ENTER("VioSSL::keepalive");
- DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
- r = sd_->keepalive(onoff);
- DBUG_PRINT("exit", ("r=%d", int(r) ));
- DBUG_RETURN(r);
-}
-
-bool
-VioSSL::fcntl() const
-{
- bool r;
- DBUG_ENTER("VioSSL::fcntl");
- DBUG_PRINT("enter", ("this=%p", this));
- r = sd_->fcntl();
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-bool
-VioSSL::should_retry() const
-{
- bool r;
- DBUG_ENTER("VioSSL::should_retry");
- DBUG_PRINT("enter", ("this=%p", this));
- r = sd_->should_retry();
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::close()
-{
- int r= -2;
- DBUG_ENTER("VioSSL::close");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_con)
- {
- r = SSL_shutdown(this_ssl_con);
- SSL_free(this_ssl_con);
- ssl_con_ = 0;
- BIO_free(this_bio);
- bio_ = 0;
- }
- DBUG_PRINT("exit", ("r=%d", r));
- DBUG_RETURN(r);
-}
-
-const char*
-VioSSL::description() const
-{
- return desc_;
-}
-
-const char*
-VioSSL::peer_addr() const
-{
- if (sd_!=0)
- return sd != 0 ? sd_->peer_addr() : "";
-}
-
-const char*
-VioSSL::peer_name() const
-{
- return sd != 0 ? sd_->peer_name() : "";
-}
-
-const char*
-VioSSL::cipher_description() const
-{
- return SSL_get_cipher_name(this_ssl_con);
-}
-
-
-int
-VioSSL::init_bio_(int fd,
- vio_ptr ssl_context,
- int state,
- int bio_flags)
-{
- DBUG_ENTER("VioSSL::init_bio_");
- DBUG_PRINT("enter",
- ("this=%p, fd=%p, ssl_context=%p, state=%d, bio_flags=%d",
- this, fd, ssl_context, state, bio_flags));
-
-
- if (!(ssl_con_ = SSL_new(my_static_cast(SSL_CTX*)(ssl_context))))
- {
- DBUG_PRINT("error", ("SSL_new failure"));
- report_errors();
- DBUG_RETURN(-1);
- }
- if (!(bio_ = BIO_new_socket(fd, bio_flags)))
- {
- DBUG_PRINT("error", ("BIO_new_socket failure"));
- report_errors();
- SSL_free(ssl_con_);
- ssl_con_ =0;
- DBUG_RETURN(-1);
- }
- SSL_set_bio(this_ssl_con, this_bio, this_bio);
- switch(state) {
- case state_connect:
- SSL_set_connect_state(this_ssl_con);
- break;
- case state_accept:
- SSL_set_accept_state(this_ssl_con);
- break;
- default:
- assert(0);
- }
- sprintf(desc_, "VioSSL(%d)", fd);
- ssl_cip_ = new SSL_CIPHER ;
- DBUG_RETURN(0);
-}
-
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
-
diff --git a/vio/VioSSL.h b/vio/VioSSL.h
deleted file mode 100644
index 6446c10700e..00000000000
--- a/vio/VioSSL.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Concrete Vio around OpenSSL's SSL structure.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioSocket;
-
-class VioSSL : public Vio
-{
-public:
- enum {
- state_connect = 1,
- state_accept = 2
- };
-public:
- VioSSL(int fd, vio_ptr ssl_context, int state);
- VioSSL(VioSocket* sd, vio_ptr ssl_context, int state);
- virtual ~VioSSL();
- virtual bool open() const;
- virtual int read( vio_ptr buf, int size);
- virtual int write( const vio_ptr buf, int size);
- virtual bool blocking() const;
- virtual int blocking(bool onoff);
- virtual int fastsend(bool onoff=true);
- virtual int keepalive(bool onoff);
- virtual bool fcntl() const;
- virtual bool should_retry() const;
- virtual int close();
- virtual const char* description() const;
- virtual const char* peer_addr() const;
- virtual const char* peer_name() const;
- virtual const char* cipher_description() const;
-
-private:
- int init_bio_(int fd,
- vio_ptr ssl_context,
- int state,
- int bio_flags);
- vio_ptr bio_;
- vio_ptr ssl_con_;
- vio_ptr ssl_cip_;
- char desc_[100];
- bool open_;
- VioSocket* sd_;
-};
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
diff --git a/vio/VioSSLAcceptorFd.cc b/vio/VioSSLAcceptorFd.cc
deleted file mode 100644
index f821685430e..00000000000
--- a/vio/VioSSLAcceptorFd.cc
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
diff --git a/vio/VioSSLFactoriesFd.cc b/vio/VioSSLFactoriesFd.cc
deleted file mode 100644
index bd64202770a..00000000000
--- a/vio/VioSSLFactoriesFd.cc
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#include "vio-global.h"
-
-#ifdef VIO_HAVE_OPENSSL
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include <netinet/in.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/asn1.h>
-
-VIO_NS_BEGIN
-
-#define this_ssl_method my_static_cast(SSL_METHOD*)(this->ssl_method_)
-#define this_ssl_context my_static_cast(SSL_CTX*)(this->ssl_context_)
-typedef unsigned char* ssl_data_ptr_t;
-
-static bool ssl_algorithms_added = FALSE;
-static bool ssl_error_strings_loaded= FALSE;
-static int verify_depth = 0;
-static int verify_error = X509_V_OK;
-
-static int
-vio_verify_callback(int ok, X509_STORE_CTX *ctx)
-{
- DBUG_ENTER("vio_verify_callback");
- DBUG_PRINT("enter", ("ok=%d, ctx=%p", ok, ctx));
- char buf[256];
- X509* err_cert;
- int err,depth;
-
- err_cert=X509_STORE_CTX_get_current_cert(ctx);
- err= X509_STORE_CTX_get_error(ctx);
- depth= X509_STORE_CTX_get_error_depth(ctx);
-
- X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buff));
- if (!ok)
- {
- DBUG_PRINT("error",("verify error:num=%d:%s\n",err,
- X509_verify_cert_error_string(err)));
- if (verify_depth >= depth)
- {
- ok=1;
- verify_error=X509_V_OK;
- }
- else
- {
- ok=0;
- verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
- }
- }
- switch (ctx->error) {
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
- DBUG_PRINT("info",("issuer= %s\n",buf));
- break;
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- DBUG_PRINT("error", ("notBefore"));
- //ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));
- break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- DBUG_PRINT("error", ("notAfter error"));
- //ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));
- break;
- }
- DBUG_PRINT("exit", ("r=%d", ok));
- DBUG_RETURN(ok);
-}
-
-
-static int
-vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
-{
- DBUG_ENTER("vio_set_cert_stuff");
- DBUG_PRINT("enter", ("ctx=%p, cert_file=%p, key_file=%p",
- ctx, cert_file, key_file));
- if (cert_file != NULL)
- {
- if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0)
- {
- DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file));
- /* FIX stderr */
- ERR_print_errors_fp(stderr);
- DBUG_RETURN(0);
- }
- if (key_file == NULL)
- key_file = cert_file;
- if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
- SSL_FILETYPE_PEM) <= 0)
- {
- DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file));
- /* FIX stderr */
- ERR_print_errors_fp(stderr);
- DBUG_RETURN(0);
- }
-
- /* If we are using DSA, we can copy the parameters from
- * the private key */
- /* Now we know that a key and cert have been set against
- * the SSL context */
- if (!SSL_CTX_check_private_key(ctx))
- {
- DBUG_PRINT("error", ("Private key does not match the certificate public key\n"));
- DBUG_RETURN(0);
- }
- }
- DBUG_RETURN(1);
-}
-
-/************************ VioSSLConnectorFd **********************************/
-VioSSLConnectorFd::VioSSLConnectorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path)
-:ssl_context_(0),ssl_method_(0)
-{
- DBUG_ENTER("VioSSLConnectorFd::VioSSLConnectorFd");
- DBUG_PRINT("enter",
- ("this=%p, key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
- this, key_file, cert_file, ca_path, ca_file));
-
- /* FIXME: constants! */
- int verify = SSL_VERIFY_PEER;
-
- if (!ssl_algorithms_added)
- {
- DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()"));
- ssl_algorithms_added = true;
- SSLeay_add_ssl_algorithms();
- }
- if (!ssl_error_strings_loaded)
- {
- DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
- ssl_error_strings_loaded = true;
- SSL_load_error_strings();
- }
- ssl_method_ = SSLv3_client_method();
- ssl_context_ = SSL_CTX_new(this_ssl_method);
- if (ssl_context_ == 0)
- {
- DBUG_PRINT("error", ("SSL_CTX_new failed"));
- report_errors();
- goto ctor_failure;
- }
- /*
- * SSL_CTX_set_options
- * SSL_CTX_set_info_callback
- * SSL_CTX_set_cipher_list
- */
- SSL_CTX_set_verify(this_ssl_context, verify, vio_verify_callback);
- if (vio_set_cert_stuff(this_ssl_context, cert_file, key_file) == -1)
- {
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
- report_errors();
- goto ctor_failure;
- }
- if (SSL_CTX_load_verify_locations( this_ssl_context, ca_file,ca_path)==0)
- {
- DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(this_ssl_context)==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
- report_errors();
- goto ctor_failure;
- }
- }
- DBUG_VOID_RETURN;
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- DBUG_VOID_RETURN;
-}
-
-VioSSLConnectorFd::~VioSSLConnectorFd()
-{
- DBUG_ENTER("VioSSLConnectorFd::~VioSSLConnectorFd");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_context_!=0)
- SSL_CTX_free(this_ssl_context);
- DBUG_VOID_RETURN;
-}
-
-VioSSL* VioSSLConnectorFd::connect( int fd)
-{
- DBUG_ENTER("VioSSLConnectorFd::connect");
- DBUG_PRINT("enter", ("this=%p, fd=%d", this, fd));
- DBUG_RETURN(new VioSSL(fd, ssl_context_, VioSSL::state_connect));
-}
-
-VioSSL*
-VioSSLConnectorFd::connect( VioSocket* sd)
-{
- DBUG_ENTER("VioSSLConnectorFd::connect");
- DBUG_PRINT("enter", ("this=%p, sd=%s", this, sd->description()));
- DBUG_RETURN(new VioSSL(sd, ssl_context_, VioSSL::state_connect));
-}
-
-void
-VioSSLConnectorFd::report_errors()
-{
- unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
-
- DBUG_ENTER("VioSSLConnectorFd::report_errors");
- DBUG_PRINT("enter", ("this=%p", this));
-
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
- {
- char buf[200];
- DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
- file,line,(flags&ERR_TXT_STRING)?data:"")) ;
- }
- DBUG_VOID_RETURN;
-}
-
-/************************ VioSSLAcceptorFd **********************************/
-
-VioSSLAcceptorFd::VioSSLAcceptorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path)
- :ssl_context_(0), ssl_method_(0)
-{
- DBUG_ENTER("VioSSLAcceptorFd::VioSSLAcceptorFd");
- DBUG_PRINT("enter",
- ("this=%p, key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
- this, key_file, cert_file, ca_path, ca_file));
-
- /* FIXME: constants! */
- int verify = (SSL_VERIFY_PEER |
- SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
- SSL_VERIFY_CLIENT_ONCE);
- session_id_context_ = static_cast<vio_ptr>(this);
-
- if (!ssl_algorithms_added)
- {
- DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()"));
- ssl_algorithms_added = true;
- SSLeay_add_ssl_algorithms();
- }
- if (!ssl_error_strings_loaded)
- {
- DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
- ssl_error_strings_loaded = true;
- SSL_load_error_strings();
- }
- ssl_method_ = SSLv3_server_method();
- ssl_context_ = SSL_CTX_new(this_ssl_method);
- if (ssl_context_==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_new failed"));
- report_errors();
- goto ctor_failure;
- }
- /*
- * SSL_CTX_set_quiet_shutdown(ctx,1);
- *
- */
- SSL_CTX_sess_set_cache_size(this_ssl_context,128);
-
- /* DH?
- */
- SSL_CTX_set_verify(this_ssl_context, verify, vio_verify_callback);
- /*
- * Double cast needed at least for egcs-1.1.2 to
- * supress warnings:
- * 1) ANSI C++ blaah implicit cast from 'void*' to 'unsigned char*'
- * 2) static_cast from 'void**' to 'unsigned char*'
- * Wish I had a copy of standard handy...
- */
- SSL_CTX_set_session_id_context(this_ssl_context,
- my_static_cast(ssl_data_ptr_t)
- (my_static_cast(void*)(&session_id_context_)),
- sizeof(session_id_context_));
-
- /*
- * SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
- */
- if (vio_set_cert_stuff(this_ssl_context, cert_file, key_file) == -1)
- {
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
- report_errors();
- goto ctor_failure;
- }
- if (SSL_CTX_load_verify_locations( this_ssl_context, ca_file, ca_path)==0)
- {
- DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(this_ssl_context)==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
- report_errors();
- goto ctor_failure;
- }
- }
- DBUG_VOID_RETURN;
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- DBUG_VOID_RETURN;
-}
-
-VioSSLAcceptorFd::~VioSSLAcceptorFd()
-{
- DBUG_ENTER("VioSSLAcceptorFd::~VioSSLAcceptorFd");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_context_!=0)
- SSL_CTX_free(this_ssl_context);
- DBUG_VOID_RETURN;
-}
-
-VioSSL*
-VioSSLAcceptorFd::accept(int fd)
-{
- DBUG_ENTER("VioSSLAcceptorFd::accept");
- DBUG_PRINT("enter", ("this=%p, fd=%d", this, fd));
- DBUG_RETURN(new VioSSL(fd, ssl_context_, VioSSL::state_accept));
-}
-
-VioSSL*
-VioSSLAcceptorFd::accept(VioSocket* sd)
-{
- DBUG_ENTER("VioSSLAcceptorFd::accept");
- DBUG_PRINT("enter", ("this=%p, sd=%s", this, sd->description()));
- DBUG_RETURN(new VioSSL(sd, ssl_context_, VioSSL::state_accept));
-}
-
-void
-VioSSLAcceptorFd::report_errors()
-{
- unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
-
- DBUG_ENTER("VioSSLConnectorFd::report_errors");
- DBUG_PRINT("enter", ("this=%p", this));
-
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
- {
- char buf[200];
- DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
- file,line,(flags&ERR_TXT_STRING)?data:"")) ;
- }
- DBUG_VOID_RETURN;
-}
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
diff --git a/vio/VioSSLFactoriesFd.h b/vio/VioSSLFactoriesFd.h
deleted file mode 100644
index ed5a24f6b4a..00000000000
--- a/vio/VioSSLFactoriesFd.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Wrapper around SSL_CTX.
- */
-
-#ifdef VIO_HAVE_OPENSSL
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioSSLAcceptorFd : public VioAcceptorFd
-{
-public:
- VioSSLAcceptorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path);
-
- virtual ~VioSSLAcceptorFd();
- virtual VioSSL* accept(int fd);
- virtual VioSSL* accept(VioSocket* sd);
-private:
- VioSSLAcceptorFd(const VioSSLAcceptorFd& rhs);//undefined
- VioSSLAcceptorFd& operator=(const VioSSLAcceptorFd& rhs);//undefined
-private:
- void report_errors();
- vio_ptr ssl_;
- vio_ptr ssl_context_;
- vio_ptr ssl_method_;
- vio_ptr session_id_context_;
-};
-
-VIO_NS_END
-
-/*
- * The Factory where Vio's are made!
- */
-
-class VioSSLConnectorFd : public VioConnectorFd
-{
-public:
- VioSSLConnectorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path);
-
- virtual ~VioSSLConnectorFd();
- virtual VioSSL* connect(int fd);
- virtual VioSSL* connect(VioSocket* sd);
-private:
- VioSSLConnectorFd(const VioSSLConnectorFd& rhs);//undefined
- VioSSLConnectorFd& operator=(const VioSSLConnectorFd& rhs);//undefined
-private:
- void report_errors();
- vio_ptr ssl_context_;
- vio_ptr ssl_method_;
- vio_ptr ssl_;
-};
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
diff --git a/vio/VioSocket.cc b/vio/VioSocket.cc
deleted file mode 100644
index e8390edb98a..00000000000
--- a/vio/VioSocket.cc
+++ /dev/null
@@ -1,326 +0,0 @@
-/* Copyright Abandoned 2000 Monty Program KB
-
- This file is public domain and comes with NO WARRANTY of any kind */
-
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#include "vio-global.h"
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-#include <assert.h>
-
-/*
- * Probably no need to clean this up
- */
-
-#ifdef _WIN32
-#include <winsock.h>
-#endif
-#include <sys/types.h>
-#if !defined(__WIN32__) && !defined(MSDOS)
-#include <sys/socket.h>
-#endif
-#if !defined(MSDOS) && !defined(__WIN32__) && !defined(HAVE_BROKEN_NETINET_INCLUDES)
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
-#endif
-#if defined(__EMX__)
-#include <sys/ioctl.h>
-#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
-#undef HAVE_FCNTL
-#endif
-#endif
-
-#if defined(MSDOS) || defined(__WIN32__)
-#ifdef __WIN32__
-#undef errno
-#undef EINTR
-#undef EAGAIN
-#define errno WSAGetLastError()
-#define EINTR WSAEINTR
-#define EAGAIN WSAEINPROGRESS
-#endif
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK EAGAIN
-#endif
-
-#ifdef __cplusplus
-extern "C" { // Because of SCO 3.2V4.2
-#endif
-#ifndef __WIN32__
-#include <sys/resource.h>
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-#include <netdb.h>
-#include <sys/utsname.h>
-#endif // __WIN32__
-#ifdef __cplusplus
-}
-#endif
-
-VIO_NS_BEGIN
-
-#define this_ssl_cip my_static_cast(SSL_CIPHER*)(this->ssl_cip_)
-
-VioSocket::VioSocket(vio_socket sd, enum_vio_type type, bool localhost)
-:sd_(sd), localhost_(localhost), fcntl_(0),
- fcntl_set_(FALSE), cipher_description_(0)
-{
- DBUG_ENTER("VioSocket::VioSocket");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if (type == VIO_TYPE_SOCKET)
- sprintf(desc_,"Socket (%d)",sd_);
- else
- sprintf(desc_,"TCP/IP (%d)",sd_);
- DBUG_VOID_RETURN;
-}
-
-VioSocket::~VioSocket()
-{
- DBUG_ENTER("VioSocket::~VioSocket");
- DBUG_PRINT("enter", ("sd_=%d", sd_));
- if (sd_>=0)
- close();
- DBUG_VOID_RETURN;
-}
-
-bool
-VioSocket::is_open() const
-{
- return sd_>=0;
-}
-
-int
-VioSocket::read(vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSocket::read");
- DBUG_PRINT("enter", ("sd_=%d, buf=%p, size=%d", sd_, buf, size));
- assert(sd_>=0);
-#if defined(MSDOS) || defined(__WIN32__)
- r = ::recv(sd_, buf, size,0);
-#else
- r = ::read(sd_, buf, size);
-#endif
-#ifndef DBUG_OFF
- if ( r < 0)
- {
- DBUG_PRINT("error", ("Got error %d during read",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int
-VioSocket::write(vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSocket::write");
- DBUG_PRINT("enter", ("sd_=%d, buf=%p, size=%d", sd_, buf, size));
- assert(sd_>=0);
-#if defined(__WIN32__)
- r = ::send(sd_, buf, size,0);
-#else
- r = ::write(sd_, buf, size);
-#endif /* __WIN32__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("error", ("Got error %d on write",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_RETURN(r);
-}
-
-int
-VioSocket::blocking(bool set_blocking_mode)
-{
- int r= 0;
- DBUG_ENTER("VioSocket::blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN32__) && !defined(__EMX__)
-#if !defined(NO_FCNTL_NONBLOCK)
- assert(sd_>=0);
-
- int old_fcntl=fcntl_;
- if (!fcntl_set_)
- {
- fcntl_set_ = true;
- old_fcntl= fcntl_ = fcntl(F_GETFL);
- }
- if (set_blocking_mode)
- fcntl_&=~O_NONBLOCK; //clear bit
- else
- fcntl_|=O_NONBLOCK; //set bit
- if (old_fcntl != fcntl_)
- r = ::fcntl(sd_, F_SETFL, fcntl_);
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN32__) && !defined(__EMX__) */
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (!vio->fcntl_set)
- {
- vio->fcntl_set = TRUE;
- old_fnctl=vio->fcntl_mode=0;
- }
- if (set_blocking_mode)
- {
- arg = 0;
- fcntl_&=~ O_NONBLOCK; //clear bit
- }
- else
- {
- arg = 1;
- fcntl_|= O_NONBLOCK; //set bit
- }
- if (old_fcntl != fcntl_)
- r = ioctlsocket(sd_,FIONBIO,(void*)&arg,sizeof(arg));
- }
-#endif
- DBUG_RETURN(r);
-}
-
-bool
-VioSocket::blocking() const
-{
- DBUG_ENTER("VioSocket::blocking");
- bool r = !(fcntl_ & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int)r));
- DBUG_RETURN(r);
-}
-
-int
-VioSocket::fastsend(bool onoff)
-{
- int r=0;
- DBUG_ENTER("VioSocket::fastsend");
- DBUG_PRINT("enter", ("onoff:%d", (int)onoff));
- assert(sd_>=0);
-
-#ifdef IPTOS_THROUGHPUT
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(sd_, IPPROTO_IP, IP_TOS, (void*) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(sd_, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay,
- sizeof(nodelay)))
- {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(0);
-}
-
-
-int
-VioSocket::keepalive(bool set_keep_alive)
-{
- DBUG_ENTER("VioSocket::keepalive");
- DBUG_PRINT("enter", ("sd_=%d, set_keep_alive=%d", sd_,
- (int) set_keep_alive));
- assert(sd_>=0);
- uint opt= set_keep_alive ? 1 : 0;
- DBUG_RETURN(setsockopt(sd_, SOL_SOCKET, SO_KEEPALIVE, (char*) &opt,
- sizeof(opt)));
-}
-
-
-bool
-VioSocket::should_retry() const
-{
- int en = errno;
- return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
-}
-
-int
-VioSocket::close()
-{
- DBUG_ENTER("VioSocket::close");
- assert(sd_>=0);
- int r=0;
- if (::shutdown(sd_,2))
- r= -1;
- if (::closesocket(sd_))
- r= -1;
- if (r)
- {
- DBUG_PRINT("error", ("close() failed, error: %d",errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- sd_ = -1;
- DBUG_RETURN(r);
-}
-
-
-int
-VioSocket::shutdown(int how)
-{
- DBUG_ENTER("VioSocket::shutdown");
- DBUG_PRINT("enter", ("how=%d", how));
- assert(sd_>=0);
- int r = ::shutdown(sd_, how);
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-const char*
-VioSocket::description() const
-{
- return desc_;
-}
-
-
-bool
-VioSocket::peer_addr(char *buf) const
-{
- DBUG_ENTER("VioSocket::peer_addr");
- DBUG_PRINT("enter", ("sd_=%d", sd_));
- if (localhost_)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen= sizeof(struct sockaddr);
- if (getpeername(sd_, my_reinterpret_cast(struct sockaddr *) (&remote_),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(remote_.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-const char*
-VioSocket::cipher_description() const
-{
- DBUG_ENTER("VioSocket::cipher_description");
- char *r = cipher_description_ ? cipher_description_:"";
- DBUG_PRINT("exit", ("name: %s", r));
- DBUG_RETURN(r);
-}
-
-VIO_NS_END
diff --git a/vio/VioSocket.h b/vio/VioSocket.h
deleted file mode 100644
index e2c6eafa516..00000000000
--- a/vio/VioSocket.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * Concrete Vio around socket. Doesn't differ much from VioFd.
- */
-
-#ifdef WIN32
- typedef SOCKET vio_socket;
-#else
- typedef int vio_socket;
-#endif /* WIN32 */
-
-VIO_NS_BEGIN
-
-class VioSSL;
-class VioSocket : public Vio
-{
-public:
- VioSocket(vio_socket sd, bool localhost=true);
- virtual ~VioSocket();
- virtual bool is_open() const;
- virtual int read(vio_ptr buf, int size);
- virtual int write(const vio_ptr buf, int size);
- virtual int blocking(bool onoff);
- virtual bool blocking() const;
- virtual int fastsend(bool onoff=true);
- virtual int keepalive(bool onoff);
- virtual bool should_retry() const;
- virtual int close();
- virtual const char* description() const;
- virtual bool peer_addr(char *buf) const;
- virtual const char* cipher_description() const;
- virtual int vio_errno();
- int shutdown(int how);
-
-private:
- vio_socket sd_;
- const bool localhost_;
- int fcntl_;
- bool fcntl_set_;
- char desc_[30];
- mutable struct sockaddr_in local_;
- mutable struct sockaddr_in remote_;
- mutable char* cipher_description_;
-
- friend class VioSSL; // he wants to tinker with this->sd_;
-};
-
-VIO_NS_END
-
-#endif /* vio_VioSocket_h_ */
-
diff --git a/vio/test-ssl.c b/vio/test-ssl.c
new file mode 100644
index 00000000000..9fdab86e9b9
--- /dev/null
+++ b/vio/test-ssl.c
@@ -0,0 +1,147 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#ifndef __GNU_LIBRARY__
+#define __GNU_LIBRARY__ // Skip warnings in getopt.h
+#endif
+#include <my_getopt.h>
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,-";
+#endif
+
+void
+fatal_error( const char* r)
+{
+ perror(r);
+ exit(0);
+}
+
+void
+print_usage()
+{
+ printf("viossl-test: testing SSL virtual IO. Usage:\n");
+ printf("viossl-test server-key server-cert client-key client-cert [CAfile] [CApath]\n");
+}
+
+int
+main( int argc,
+ char** argv)
+{
+ char* server_key = 0, *server_cert = 0;
+ char* client_key = 0, *client_cert = 0;
+ char* ca_file = 0, *ca_path = 0;
+ char* cipher=0;
+ int child_pid,sv[2];
+ struct st_VioSSLAcceptorFd* ssl_acceptor=0;
+ struct st_VioSSLConnectorFd* ssl_connector=0;
+ Vio* client_vio=0, *server_vio=0;
+ MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+ if (argc<5)
+ {
+ print_usage();
+ return 1;
+ }
+
+ server_key = argv[1];
+ server_cert = argv[2];
+ client_key = argv[3];
+ client_cert = argv[4];
+ if (argc>5)
+ ca_file = argv[5];
+ if (argc>6)
+ ca_path = argv[6];
+ printf("Server key/cert : %s/%s\n", server_key, server_cert);
+ printf("Client key/cert : %s/%s\n", client_key, client_cert);
+ if (ca_file!=0)
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
+ fatal_error("socketpair");
+
+ ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path, cipher);
+ ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher);
+
+ client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ client_vio->sd = sv[0];
+ client_vio->vioblocking(client_vio,0);
+ sslconnect(ssl_connector,client_vio,60L);
+ server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ server_vio->sd = sv[1];
+ server_vio->vioblocking(client_vio,0);
+ sslaccept(ssl_acceptor,server_vio,60L);
+
+ printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
+
+ child_pid = fork();
+ if (child_pid==-1) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("fork");
+ }
+ if (child_pid==0) {
+ //child, therefore, client
+ char xbuf[100];
+ int r = client_vio->read(client_vio,xbuf, sizeof(xbuf));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("client:SSL_read");
+ }
+ xbuf[r] = 0;
+ printf("client:got %s\n", xbuf);
+ my_free((gptr)client_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ } else {
+ const char* s = "Huhuhuh";
+ int r = server_vio->write(server_vio,(gptr)s, strlen(s));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("server:SSL_write");
+ }
+ my_free((gptr)server_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ }
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c
new file mode 100644
index 00000000000..84853e45485
--- /dev/null
+++ b/vio/test-sslclient.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#ifndef __GNU_LIBRARY__
+#define __GNU_LIBRARY__ // Skip warnings in getopt.h
+#endif
+#include <my_getopt.h>
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,-";
+#endif
+
+void
+fatal_error( const char* r)
+{
+ perror(r);
+ exit(0);
+}
+
+int
+main( int argc __attribute__((unused)),
+ char** argv)
+{
+ char client_key[] = "../SSL/client-key.pem", client_cert[] = "../SSL/client-cert.pem";
+ char ca_file[] = "../SSL/cacert.pem", *ca_path = 0, *cipher=0;
+ struct st_VioSSLConnectorFd* ssl_connector=0;
+ struct sockaddr_in sa;
+ Vio* client_vio=0;
+ int err;
+ char xbuf[100]="Ohohhhhoh1234";
+ MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+ printf("Client key/cert : %s/%s\n", client_key, client_cert);
+ if (ca_file!=0)
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+ ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher);
+ if(!ssl_connector) {
+ fatal_error("client:new_VioSSLConnectorFd failed");
+ }
+
+ /* ----------------------------------------------- */
+ /* Create a socket and connect to server using normal socket calls. */
+
+ client_vio = vio_new(socket (AF_INET, SOCK_STREAM, 0), VIO_TYPE_TCPIP, TRUE);
+
+ memset (&sa, '\0', sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); /* Server IP */
+ sa.sin_port = htons (1111); /* Server Port number */
+
+ err = connect(client_vio->sd, (struct sockaddr*) &sa,
+ sizeof(sa));
+
+ /* ----------------------------------------------- */
+ /* Now we have TCP conncetion. Start SSL negotiation. */
+ read(client_vio->sd,xbuf, sizeof(xbuf));
+ sslconnect(ssl_connector,client_vio,60L);
+ err = client_vio->read(client_vio,xbuf, sizeof(xbuf));
+ if (err<=0) {
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("client:SSL_read");
+ }
+ xbuf[err] = 0;
+ printf("client:got %s\n", xbuf);
+ my_free((gptr)client_vio,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c
new file mode 100644
index 00000000000..f0116a2817d
--- /dev/null
+++ b/vio/test-sslserver.c
@@ -0,0 +1,159 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#ifndef __GNU_LIBRARY__
+#define __GNU_LIBRARY__ // Skip warnings in getopt.h
+#endif
+#include <my_getopt.h>
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,-";
+#endif
+
+#if 0
+static void
+fatal_error( const char* r)
+{
+ perror(r);
+ exit(0);
+}
+#endif
+
+typedef struct {
+ int sd;
+ struct st_VioSSLAcceptorFd* ssl_acceptor;
+} TH_ARGS;
+
+static void
+do_ssl_stuff( TH_ARGS* args)
+{
+ const char* s = "Huhuhuhuuu";
+ Vio* server_vio;
+ int err;
+ DBUG_ENTER("do_ssl_stuff");
+
+ server_vio = vio_new(args->sd, VIO_TYPE_TCPIP, TRUE);
+
+ /* ----------------------------------------------- */
+ /* TCP connection is ready. Do server side SSL. */
+
+ err = write(server_vio->sd,(gptr)s, strlen(s));
+ sslaccept(args->ssl_acceptor,server_vio,60L);
+ err = server_vio->write(server_vio,(gptr)s, strlen(s));
+ DBUG_VOID_RETURN;
+}
+
+static void*
+client_thread( void* arg)
+{
+ my_thread_init();
+ do_ssl_stuff((TH_ARGS*)arg);
+ return 0;
+}
+
+int
+main(int argc __attribute__((unused)), char** argv)
+{
+ char server_key[] = "../SSL/server-key.pem",
+ server_cert[] = "../SSL/server-cert.pem";
+ char ca_file[] = "../SSL/cacert.pem",
+ *ca_path = 0,
+ *cipher = 0;
+ struct st_VioSSLAcceptorFd* ssl_acceptor;
+ pthread_t th;
+ TH_ARGS th_args;
+
+
+ struct sockaddr_in sa_serv;
+ struct sockaddr_in sa_cli;
+ int listen_sd;
+ int err;
+ size_t client_len;
+ int reuseaddr = 1; /* better testing, uh? */
+
+ MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+ printf("Server key/cert : %s/%s\n", server_key, server_cert);
+ if (ca_file!=0)
+
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+ th_args.ssl_acceptor = ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path,cipher);
+
+ /* ----------------------------------------------- */
+ /* Prepare TCP socket for receiving connections */
+
+ listen_sd = socket (AF_INET, SOCK_STREAM, 0);
+ setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(&reuseaddr));
+
+ memset (&sa_serv, '\0', sizeof(sa_serv));
+ sa_serv.sin_family = AF_INET;
+ sa_serv.sin_addr.s_addr = INADDR_ANY;
+ sa_serv.sin_port = htons (1111); /* Server Port number */
+
+ err = bind(listen_sd, (struct sockaddr*) &sa_serv,
+ sizeof (sa_serv));
+
+ /* Receive a TCP connection. */
+
+ err = listen (listen_sd, 5);
+ client_len = sizeof(sa_cli);
+ th_args.sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
+ close (listen_sd);
+
+ printf ("Connection from %lx, port %x\n",
+ (long)sa_cli.sin_addr.s_addr, sa_cli.sin_port);
+
+ /* ----------------------------------------------- */
+ /* TCP connection is ready. Do server side SSL. */
+
+ err = pthread_create(&th, NULL, client_thread, (void*)&th_args);
+ DBUG_PRINT("info", ("pthread_create: %d", err));
+ pthread_join(th, NULL);
+
+#if 0
+ if (err<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ fatal_error("server:SSL_write");
+ }
+#endif /* 0 */
+
+ my_free((gptr)ssl_acceptor,MYF(0));
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/version.cc b/vio/version.cc
deleted file mode 100644
index 7c09d431a9d..00000000000
--- a/vio/version.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "vio-global.h"
-
-extern "C" const char*
-vio_version()
-{
- return "0.2";
-}
diff --git a/vio/vio-global.h b/vio/vio-global.h
deleted file mode 100644
index 0c3d279695d..00000000000
--- a/vio/vio-global.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <global.h>
-
-#if !defined(VIO_HAVE_OPENSSL) && defined(HAVE_OPENSSL)
-#define VIO_HAVE_OPENSSL HAVE_OPENSSL
-#endif /* !defined(VIO_HAVE_OPENSSL) && defined(HAVE_OPENSSL) */
-
-#include "viotypes.h"
-#include "Vio.h"
-#include "VioAcceptorFd.h"
-#include "VioFd.h"
-#include "VioPipe.h"
-#include "VioSocket.h"
-#ifdef VIO_HAVE_OPENSSL
-#include "VioSSL.h"
-#include "VioSSLFactoriesFd.h"
-#endif /* VIO_HAVE_OPENSSL */
-
-
-#if VIO_HAVE_NAMESPACES
-#define VIO_STD_NS std
-#define VIO_STD_NS_USING using namespace std;
-#define VIO_NS VirtualIO
-#define VIO_NS_BEGIN namespace VIO_NS {
-#define VIO_NS_END }
-#define VIO_NS_USING using namespace VIO_NS;
-#else
-#define VIO_STD_NS
-#define VIO_STD_NS_USING
-#define VIO_NS
-#define VIO_NS_BEGIN
-#define VIO_NS_END
-#define VIO_NS_USING
-#endif
diff --git a/vio/vio.c b/vio/vio.c
new file mode 100644
index 00000000000..67cb7ec95cd
--- /dev/null
+++ b/vio/vio.c
@@ -0,0 +1,132 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#define DONT_MAP_VIO
+#include <my_global.h>
+#include <mysql_com.h>
+#include <violite.h>
+#include <errno.h>
+#include <my_sys.h>
+#include <my_net.h>
+#include <m_string.h>
+
+/*
+ * Helper to fill most of the Vio* with defaults.
+ */
+
+void vio_reset(Vio* vio, enum enum_vio_type type,
+ my_socket sd, HANDLE hPipe,
+ my_bool localhost)
+{
+ DBUG_ENTER("vio_reset");
+ DBUG_PRINT("enter", ("type=%d sd=%d localhost=%d", type, sd, localhost));
+
+ bzero((char*) vio, sizeof(*vio));
+ vio->type = type;
+ vio->sd = sd;
+ vio->hPipe = hPipe;
+ vio->localhost= localhost;
+#ifdef HAVE_VIO
+#ifdef HAVE_OPENSSL
+ if (type == VIO_TYPE_SSL)
+ {
+ vio->viodelete =vio_ssl_delete;
+ vio->vioerrno =vio_ssl_errno;
+ vio->read =vio_ssl_read;
+ vio->write =vio_ssl_write;
+ vio->fastsend =vio_ssl_fastsend;
+ vio->viokeepalive =vio_ssl_keepalive;
+ vio->should_retry =vio_ssl_should_retry;
+ vio->vioclose =vio_ssl_close;
+ vio->peer_addr =vio_ssl_peer_addr;
+ vio->in_addr =vio_ssl_in_addr;
+ vio->vioblocking =vio_blocking;
+ vio->is_blocking =vio_is_blocking;
+ }
+ else /* default is VIO_TYPE_TCPIP */
+#endif /* HAVE_OPENSSL */
+ {
+ vio->viodelete =vio_delete;
+ vio->vioerrno =vio_errno;
+ vio->read =vio_read;
+ vio->write =vio_write;
+ vio->fastsend =vio_fastsend;
+ vio->viokeepalive =vio_keepalive;
+ vio->should_retry =vio_should_retry;
+ vio->vioclose =vio_close;
+ vio->peer_addr =vio_peer_addr;
+ vio->in_addr =vio_in_addr;
+ vio->vioblocking =vio_blocking;
+ vio->is_blocking =vio_is_blocking;
+ }
+#endif /* HAVE_VIO */
+ DBUG_VOID_RETURN;
+}
+
+/* Open the socket or TCP/IP connection and read the fnctl() status */
+
+Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
+{
+ Vio *vio;
+ DBUG_ENTER("vio_new");
+ DBUG_PRINT("enter", ("sd=%d", sd));
+ if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
+ {
+ vio_reset(vio, type, sd, 0, localhost);
+ sprintf(vio->desc,
+ (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
+ vio->sd);
+#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(NO_FCNTL_NONBLOCK)
+ vio->fcntl_mode = fcntl(sd, F_GETFL);
+#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
+ /* Non blocking sockets doesn't work good on HPUX 11.0 */
+ (void) ioctl(sd,FIOSNBIO,0);
+#endif
+#else /* !defined(__WIN__) && !defined(__EMX__) */
+ {
+ /* set to blocking mode by default */
+ ulong arg=0, r;
+ r = ioctlsocket(sd,FIONBIO,(void*) &arg, sizeof(arg));
+ }
+#endif
+ }
+ DBUG_RETURN(vio);
+}
+
+
+#ifdef __WIN__
+
+Vio *vio_new_win32pipe(HANDLE hPipe)
+{
+ Vio *vio;
+ DBUG_ENTER("vio_new_handle");
+ if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
+ {
+ vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
+ strmov(vio->desc, "named pipe");
+ }
+ DBUG_RETURN(vio);
+}
+
+#endif
diff --git a/vio/vioelitexx.cc b/vio/vioelitexx.cc
deleted file mode 100644
index 0eac28eaf55..00000000000
--- a/vio/vioelitexx.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright Abandoned 2000 Monty Program KB
- This file is public domain and comes with NO WARRANTY of any kind */
-
-/*
- * Renamed of violite.cc to violitexx.cc because of clashes
- * with violite.c
- * This file implements the same functions as in violite.c, but now using
- * the Vio class
- */
-
-#include "vio-global.h"
-
-Vio*
-vio_new(my_socket sd, enum_vio_type type, my_bool localhost)
-{
- return my_reinterpret_cast(Vio*) (new VioSocket(sd, type, localhost));
-}
-
-
-#ifdef __WIN32__
-Vio
-*vio_new_win32pipe(HANDLE hPipe)
-{
- return my_reinterpret_cast(Vio*) (new VioPipe(hPipe));
-}
-#endif
diff --git a/vio/violite.h b/vio/violite.h
deleted file mode 100644
index fc480f59db1..00000000000
--- a/vio/violite.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright Abandoned 2000 Monty Program KB
- This file is public domain and comes with NO WARRANTY of any kind */
-
-/*
- * Vio Lite.
- * Purpose: include file for Vio that will work with C and C++
- */
-
-#ifndef vio_violite_h_
-#define vio_violite_h_
-
-#include "my_net.h" /* needed because of struct in_addr */
-
-#ifdef HAVE_VIO
-#include <Vio.h> /* Full VIO interface */
-#else
-
-/* Simple vio interface in C; The functions are implemented in violite.c */
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#ifndef Vio_defined
-#define Vio_defined
-struct st_vio; /* Only C */
-typedef struct st_vio Vio;
-#endif
-
-enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
- VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
-
-Vio* vio_new(my_socket sd,
- enum enum_vio_type type,
- my_bool localhost);
-#ifdef __WIN__
-Vio* vio_new_win32pipe(HANDLE hPipe);
-#endif
-void vio_delete(Vio* vio);
-
-/*
- * vio_read and vio_write should have the same semantics
- * as read(2) and write(2).
- */
-int vio_read( Vio* vio,
- gptr buf, int size);
-int vio_write( Vio* vio,
- const gptr buf,
- int size);
-/*
- * Whenever the socket is set to blocking mode or not.
- */
-int vio_blocking( Vio* vio,
- my_bool onoff);
-my_bool vio_is_blocking( Vio* vio);
-/*
- * setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
- */
-int vio_fastsend( Vio* vio,
- my_bool onoff);
-/*
- * setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
- */
-int vio_keepalive( Vio* vio,
- my_bool onoff);
-/*
- * Whenever we should retry the last read/write operation.
- */
-my_bool vio_should_retry( Vio* vio);
-/*
- * When the workday is over...
- */
-int vio_close( Vio* vio);
-/*
- * Short text description of the socket for those, who are curious..
- */
-const char* vio_description( Vio* vio);
-
-/* Return the type of the connection */
- enum enum_vio_type vio_type(Vio* vio);
-
-/* Return last error number */
-int vio_errno(Vio *vio);
-
-/* Get socket number */
-my_socket vio_fd(Vio *vio);
-
-/*
- * Remote peer's address and name in text form.
- */
-my_bool vio_peer_addr(Vio * vio, char *buf);
-
-/* Remotes in_addr */
-
-void vio_in_addr(Vio *vio, struct in_addr *in);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* HAVE_VIO */
-#endif /* vio_violite_h_ */
diff --git a/vio/viosocket.c b/vio/viosocket.c
new file mode 100644
index 00000000000..dc2bfaa6e0c
--- /dev/null
+++ b/vio/viosocket.c
@@ -0,0 +1,327 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#define DONT_MAP_VIO
+#include <my_global.h>
+#include <mysql_com.h>
+
+#include <errno.h>
+#include <violite.h>
+#include <my_sys.h>
+#include <my_net.h>
+#include <m_string.h>
+
+#ifndef __WIN__
+#define HANDLE void *
+#endif
+
+void vio_delete(Vio* vio)
+{
+ /* It must be safe to delete null pointers. */
+ /* This matches the semantics of C++'s delete operator. */
+ if (vio)
+ {
+ if (vio->type != VIO_CLOSED)
+ vio_close(vio);
+ my_free((gptr) vio,MYF(0));
+ }
+}
+
+int vio_errno(Vio *vio __attribute__((unused)))
+{
+ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+}
+
+
+int vio_read(Vio * vio, gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_read");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
+#ifdef __WIN__
+ if (vio->type == VIO_TYPE_NAMEDPIPE)
+ {
+ DWORD length;
+ if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(length);
+ }
+ r = recv(vio->sd, buf, size,0);
+#else
+ errno=0; /* For linux */
+ r = read(vio->sd, buf, size);
+#endif /* __WIN__ */
+#ifndef DBUG_OFF
+ if (r < 0)
+ {
+ DBUG_PRINT("vio_error", ("Got error %d during read",errno));
+ }
+#endif /* DBUG_OFF */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_write(Vio * vio, const gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_write");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
+#if defined( __WIN__)
+ if ( vio->type == VIO_TYPE_NAMEDPIPE)
+ {
+ DWORD length;
+ if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(length);
+ }
+ r = send(vio->sd, buf, size, 0);
+#else
+ r = write(vio->sd, buf, size);
+#endif /* __WIN__ */
+#ifndef DBUG_OFF
+ if (r < 0)
+ {
+ DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
+ }
+#endif /* DBUG_OFF */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode)
+{
+ int r=0;
+ DBUG_ENTER("vio_blocking");
+ DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
+
+#if !defined(HAVE_OPENSSL)
+#if !defined(___WIN__) && !defined(__EMX__)
+#if !defined(NO_FCNTL_NONBLOCK)
+
+ if (vio->sd >= 0)
+ {
+ int old_fcntl=vio->fcntl_mode;
+ if (set_blocking_mode)
+ vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
+ else
+ vio->fcntl_mode |= O_NONBLOCK; /* set bit */
+ if (old_fcntl != vio->fcntl_mode)
+ r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
+ }
+#endif /* !defined(NO_FCNTL_NONBLOCK) */
+#else /* !defined(__WIN__) && !defined(__EMX__) */
+#ifndef __EMX__
+ if (vio->type != VIO_TYPE_NAMEDPIPE)
+#endif
+ {
+ ulong arg;
+ int old_fcntl=vio->fcntl_mode;
+ if (set_blocking_mode)
+ {
+ arg = 0;
+ vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
+ }
+ else
+ {
+ arg = 1;
+ vio->fcntl_mode |= O_NONBLOCK; /* set bit */
+ }
+ if (old_fcntl != vio->fcntl_mode)
+ r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
+ }
+#endif /* !defined(__WIN__) && !defined(__EMX__) */
+#endif /* !defined (HAVE_OPENSSL) */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+my_bool
+vio_is_blocking(Vio * vio)
+{
+ my_bool r;
+ DBUG_ENTER("vio_is_blocking");
+ r = !(vio->fcntl_mode & O_NONBLOCK);
+ DBUG_PRINT("exit", ("%d", (int) r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_fastsend(Vio * vio __attribute__((unused)))
+{
+ int r=0;
+ DBUG_ENTER("vio_fastsend");
+
+#ifdef IPTOS_THROUGHPUT
+ {
+#ifndef __EMX__
+ int tos = IPTOS_THROUGHPUT;
+ if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
+#endif /* !__EMX__ */
+ {
+ int nodelay = 1;
+ if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
+ sizeof(nodelay))) {
+ DBUG_PRINT("warning",
+ ("Couldn't set socket option for fast send"));
+ r= -1;
+ }
+ }
+ }
+#endif /* IPTOS_THROUGHPUT */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+int vio_keepalive(Vio* vio, my_bool set_keep_alive)
+{
+ int r=0;
+ uint opt = 0;
+ DBUG_ENTER("vio_keepalive");
+ DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int)
+ set_keep_alive));
+ if (vio->type != VIO_TYPE_NAMEDPIPE)
+ {
+ if (set_keep_alive)
+ opt = 1;
+ r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
+ sizeof(opt));
+ }
+ DBUG_RETURN(r);
+}
+
+
+my_bool
+vio_should_retry(Vio * vio __attribute__((unused)))
+{
+ int en = socket_errno;
+ return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
+ en == SOCKET_EWOULDBLOCK);
+}
+
+
+int vio_close(Vio * vio)
+{
+ int r;
+ DBUG_ENTER("vio_close");
+#ifdef __WIN__
+ if (vio->type == VIO_TYPE_NAMEDPIPE)
+ {
+#if defined(__NT__) && defined(MYSQL_SERVER)
+ CancelIo(vio->hPipe);
+ DisconnectNamedPipe(vio->hPipe);
+#endif
+ r=CloseHandle(vio->hPipe);
+ }
+ else if (vio->type != VIO_CLOSED)
+#endif /* __WIN__ */
+ {
+ r=0;
+ if (shutdown(vio->sd,2))
+ r= -1;
+ if (closesocket(vio->sd))
+ r= -1;
+ }
+ if (r)
+ {
+ DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
+ /* FIXME: error handling (not critical for MySQL) */
+ }
+ vio->type= VIO_CLOSED;
+ vio->sd= -1;
+ DBUG_RETURN(r);
+}
+
+
+const char *vio_description(Vio * vio)
+{
+ return vio->desc;
+}
+
+enum enum_vio_type vio_type(Vio* vio)
+{
+ return vio->type;
+}
+
+my_socket vio_fd(Vio* vio)
+{
+ return vio->sd;
+}
+
+
+my_bool vio_peer_addr(Vio * vio, char *buf)
+{
+ DBUG_ENTER("vio_peer_addr");
+ DBUG_PRINT("enter", ("sd: %d", vio->sd));
+ if (vio->localhost)
+ {
+ strmov(buf,"127.0.0.1");
+ }
+ else
+ {
+ size_socket addrLen = sizeof(struct sockaddr);
+ if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
+ &addrLen) != 0)
+ {
+ DBUG_PRINT("exit", ("getpeername gave error: %d", socket_errno));
+ DBUG_RETURN(1);
+ }
+ my_inet_ntoa(vio->remote.sin_addr,buf);
+ }
+ DBUG_PRINT("exit", ("addr: %s", buf));
+ DBUG_RETURN(0);
+}
+
+
+void vio_in_addr(Vio *vio, struct in_addr *in)
+{
+ DBUG_ENTER("vio_in_addr");
+ if (vio->localhost)
+ bzero((char*) in, sizeof(*in)); /* This should never be executed */
+ else
+ *in=vio->remote.sin_addr;
+ DBUG_VOID_RETURN;
+}
+
+
+/* Return 0 if there is data to be read */
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+#ifndef HAVE_POLL
+ return 0;
+#else
+ struct pollfd fds;
+ int res;
+ DBUG_ENTER("vio_poll");
+ fds.fd=vio->sd;
+ fds.events=POLLIN;
+ fds.revents=0;
+ if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
+ {
+ DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
+ }
+ DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
+#endif
+}
diff --git a/vio/viossl.c b/vio/viossl.c
new file mode 100644
index 00000000000..6d85b119f20
--- /dev/null
+++ b/vio/viossl.c
@@ -0,0 +1,360 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#include <my_global.h>
+
+#ifdef HAVE_OPENSSL
+
+#include <mysql_com.h>
+
+#include <errno.h>
+#include <assert.h>
+#include <violite.h>
+#include <my_sys.h>
+#include <my_net.h>
+#include <m_string.h>
+
+#ifndef __WIN__
+#define HANDLE void *
+#endif
+
+static void
+report_errors()
+{
+ unsigned long l;
+ const char* file;
+ const char* data;
+ int line,flags, any_ssl_error = 0;
+ DBUG_ENTER("report_errors");
+
+ while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
+ {
+ char buf[200];
+ any_ssl_error = 1;
+ DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
+ file,line,(flags&ERR_TXT_STRING)?data:"")) ;
+ }
+ if (!any_ssl_error) {
+ DBUG_PRINT("info", ("No OpenSSL errors."));
+ }
+ DBUG_PRINT("info", ("BTW, errno=%d", socket_errno));
+ DBUG_VOID_RETURN;
+}
+
+
+void vio_ssl_delete(Vio * vio)
+{
+ /* It must be safe to delete null pointers. */
+ /* This matches the semantics of C++'s delete operator. */
+ if (vio)
+ {
+ if (vio->type != VIO_CLOSED)
+ vio_close(vio);
+ my_free((gptr) vio,MYF(0));
+ }
+}
+
+int vio_ssl_errno(Vio *vio __attribute__((unused)))
+{
+ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+}
+
+
+int vio_ssl_read(Vio * vio, gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_ssl_read");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d, ssl_=%p",
+ vio->sd, buf, size, vio->ssl_));
+
+#ifndef DBUG_OFF
+ errno = 0;
+#endif /* DBUG_OFF */
+ r = SSL_read(vio->ssl_, buf, size);
+#ifndef DBUG_OFF
+ if ( r<= 0) {
+ r=SSL_get_error(vio->ssl_, r);
+ DBUG_PRINT("info",("SSL_get_error returned %d",r));
+ report_errors();
+ }
+#endif /* DBUG_OFF */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_ssl_write(Vio * vio, const gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_ssl_write");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
+
+#ifndef DBUG_OFF
+ errno = 0;
+#endif /* DBUG_OFF */
+ r = SSL_write(vio->ssl_, buf, size);
+#ifndef DBUG_OFF
+ if (r<0)
+ report_errors();
+#endif /* DBUG_OFF */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_ssl_fastsend(Vio * vio __attribute__((unused)))
+{
+ int r=0;
+ DBUG_ENTER("vio_ssl_fastsend");
+
+#ifdef IPTOS_THROUGHPUT
+ {
+#ifndef __EMX__
+ int tos = IPTOS_THROUGHPUT;
+ if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
+#endif /* !__EMX__ */
+ {
+ int nodelay = 1;
+ if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
+ sizeof(nodelay))) {
+ DBUG_PRINT("warning",
+ ("Couldn't set socket option for fast send"));
+ r= -1;
+ }
+ }
+ }
+#endif /* IPTOS_THROUGHPUT */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive)
+{
+ int r=0;
+ uint opt = 0;
+ DBUG_ENTER("vio_ssl_keepalive");
+ DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int)
+ set_keep_alive));
+ if (vio->type != VIO_TYPE_NAMEDPIPE)
+ {
+ if (set_keep_alive)
+ opt = 1;
+ r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
+ sizeof(opt));
+ }
+ DBUG_RETURN(r);
+}
+
+
+my_bool
+vio_ssl_should_retry(Vio * vio __attribute__((unused)))
+{
+ int en = socket_errno;
+ return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
+ en == SOCKET_EWOULDBLOCK);
+}
+
+
+int vio_ssl_close(Vio * vio)
+{
+ int r;
+ DBUG_ENTER("vio_ssl_close");
+ r=0;
+ if (vio->ssl_)
+ {
+ r = SSL_shutdown(vio->ssl_);
+ SSL_free(vio->ssl_);
+ vio->ssl_= 0;
+ }
+ if (shutdown(vio->sd,2))
+ r= -1;
+ if (closesocket(vio->sd))
+ r= -1;
+ if (r)
+ {
+ DBUG_PRINT("error", ("close() failed, error: %d",socket_errno));
+ report_errors();
+ /* FIXME: error handling (not critical for MySQL) */
+ }
+ vio->type= VIO_CLOSED;
+ vio->sd= -1;
+ DBUG_RETURN(r);
+}
+
+
+const char *vio_ssl_description(Vio * vio)
+{
+ return vio->desc;
+}
+
+enum enum_vio_type vio_ssl_type(Vio* vio)
+{
+ return vio->type;
+}
+
+my_socket vio_ssl_fd(Vio* vio)
+{
+ return vio->sd;
+}
+
+
+my_bool vio_ssl_peer_addr(Vio * vio, char *buf)
+{
+ DBUG_ENTER("vio_ssl_peer_addr");
+ DBUG_PRINT("enter", ("sd=%d", vio->sd));
+ if (vio->localhost)
+ {
+ strmov(buf,"127.0.0.1");
+ }
+ else
+ {
+ size_socket addrLen = sizeof(struct sockaddr);
+ if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
+ &addrLen) != 0)
+ {
+ DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
+ DBUG_RETURN(1);
+ }
+ /* FIXME */
+/* my_inet_ntoa(vio->remote.sin_addr,buf); */
+ }
+ DBUG_PRINT("exit", ("addr=%s", buf));
+ DBUG_RETURN(0);
+}
+
+
+void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
+{
+ DBUG_ENTER("vio_ssl_in_addr");
+ if (vio->localhost)
+ bzero((char*) in, sizeof(*in)); /* This should never be executed */
+ else
+ *in=vio->remote.sin_addr;
+ DBUG_VOID_RETURN;
+}
+
+
+void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
+{
+ char *str;
+ char buf[1024];
+ X509* client_cert;
+ DBUG_ENTER("sslaccept");
+ DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr));
+ vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
+ vio->ssl_=0;
+ vio->open_=FALSE;
+ if (!(vio->ssl_ = SSL_new(ptr->ssl_context_)))
+ {
+ DBUG_PRINT("error", ("SSL_new failure"));
+ report_errors();
+ DBUG_VOID_RETURN;
+ }
+ DBUG_PRINT("info", ("ssl_=%p timeout=%ld",vio->ssl_, timeout));
+ SSL_clear(vio->ssl_);
+ vio_blocking(vio, FALSE);
+ SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout);
+ SSL_set_fd(vio->ssl_,vio->sd);
+ SSL_set_accept_state(vio->ssl_);
+ SSL_do_handshake(vio->ssl_);
+ vio->open_ = TRUE;
+#ifndef DBUF_OFF
+ DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
+ ,SSL_get_cipher_name(vio->ssl_)));
+ client_cert = SSL_get_peer_certificate (vio->ssl_);
+ if (client_cert != NULL) {
+ DBUG_PRINT("info",("Client certificate:"));
+ str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
+ DBUG_PRINT("info",("\t subject: %s", str));
+ free (str);
+
+ str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);
+ DBUG_PRINT("info",("\t issuer: %s", str));
+ free (str);
+
+ X509_free (client_cert);
+ } else
+ DBUG_PRINT("info",("Client does not have certificate."));
+
+ str=SSL_get_shared_ciphers(vio->ssl_, buf, sizeof(buf));
+ if(str)
+ {
+ DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str));
+ }
+ else
+ {
+ DBUG_PRINT("info",("no shared ciphers!"));
+ }
+
+#endif
+ DBUG_VOID_RETURN;
+}
+
+void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout)
+{
+ char *str;
+ X509* server_cert;
+ DBUG_ENTER("sslconnect");
+ DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context_));
+ vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
+ vio->ssl_=0;
+ vio->open_=FALSE;
+ if (!(vio->ssl_ = SSL_new(ptr->ssl_context_)))
+ {
+ DBUG_PRINT("error", ("SSL_new failure"));
+ report_errors();
+ DBUG_VOID_RETURN;
+ }
+ DBUG_PRINT("info", ("ssl_=%p timeout=%ld",vio->ssl_, timeout));
+ SSL_clear(vio->ssl_);
+ vio_blocking(vio, FALSE);
+ SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout);
+ SSL_set_fd (vio->ssl_, vio->sd);
+ SSL_set_connect_state(vio->ssl_);
+ SSL_do_handshake(vio->ssl_);
+ vio->open_ = TRUE;
+#ifndef DBUG_OFF
+ DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
+ ,SSL_get_cipher_name(vio->ssl_)));
+ server_cert = SSL_get_peer_certificate (vio->ssl_);
+ if (server_cert != NULL) {
+ DBUG_PRINT("info",("Server certificate:"));
+ str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0);
+ DBUG_PRINT("info",("\t subject: %s", str));
+ free (str);
+
+ str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0);
+ DBUG_PRINT("info",("\t issuer: %s", str));
+ free (str);
+
+ /* We could do all sorts of certificate verification stuff here before
+ * deallocating the certificate. */
+
+ X509_free (server_cert);
+ } else
+ DBUG_PRINT("info",("Server does not have certificate."));
+#endif
+ DBUG_VOID_RETURN;
+}
+
+#endif /* HAVE_OPENSSL */
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
new file mode 100644
index 00000000000..23a35f540f6
--- /dev/null
+++ b/vio/viosslfactories.c
@@ -0,0 +1,352 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+
+#ifdef HAVE_OPENSSL
+
+#include <my_sys.h>
+#include <mysql_com.h>
+#include <violite.h>
+
+
+static bool ssl_algorithms_added = FALSE;
+static bool ssl_error_strings_loaded= FALSE;
+static int verify_depth = 0;
+static int verify_error = X509_V_OK;
+
+static unsigned char dh512_p[]=
+{
+ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+ 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+ 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+ 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+ 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+ 0x47,0x74,0xE8,0x33,
+};
+
+static unsigned char dh512_g[]={
+ 0x02,
+};
+
+static DH *get_dh512(void)
+{
+ DH *dh;
+ if ((dh=DH_new()))
+ {
+ dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+ dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+ if (! dh->p || ! dh->g)
+ {
+ DH_free(dh);
+ dh=0;
+ }
+ }
+ return(dh);
+}
+
+
+static void
+report_errors()
+{
+ unsigned long l;
+ const char* file;
+ const char* data;
+ int line,flags;
+
+ DBUG_ENTER("report_errors");
+
+ while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
+ {
+ char buf[200];
+ DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
+ file,line,(flags & ERR_TXT_STRING) ? data : "")) ;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+static int
+vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
+{
+ DBUG_ENTER("vio_set_cert_stuff");
+ DBUG_PRINT("enter", ("ctx=%p, cert_file=%s, key_file=%s",
+ ctx, cert_file, key_file));
+ if (cert_file != NULL)
+ {
+ if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0)
+ {
+ DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file));
+ /* FIX stderr */
+ ERR_print_errors_fp(stderr);
+ DBUG_RETURN(0);
+ }
+ if (key_file == NULL)
+ key_file = cert_file;
+ if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
+ SSL_FILETYPE_PEM) <= 0)
+ {
+ DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file));
+ /* FIX stderr */
+ ERR_print_errors_fp(stderr);
+ DBUG_RETURN(0);
+ }
+
+ /*
+ If we are using DSA, we can copy the parameters from the private key
+ Now we know that a key and cert have been set against the SSL context
+ */
+ if (!SSL_CTX_check_private_key(ctx))
+ {
+ DBUG_PRINT("error",
+ ("Private key does not match the certificate public key\n"));
+ DBUG_RETURN(0);
+ }
+ }
+ DBUG_RETURN(1);
+}
+
+
+static int
+vio_verify_callback(int ok, X509_STORE_CTX *ctx)
+{
+ char buf[256];
+ X509* err_cert;
+ int err,depth;
+
+ DBUG_ENTER("vio_verify_callback");
+ DBUG_PRINT("enter", ("ok=%d, ctx=%p", ok, ctx));
+ err_cert=X509_STORE_CTX_get_current_cert(ctx);
+ err= X509_STORE_CTX_get_error(ctx);
+ depth= X509_STORE_CTX_get_error_depth(ctx);
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
+ if (!ok)
+ {
+ DBUG_PRINT("error",("verify error: num: %d : '%s'\n",err,
+ X509_verify_cert_error_string(err)));
+ if (verify_depth >= depth)
+ {
+ ok=1;
+ verify_error=X509_V_OK;
+ }
+ else
+ {
+ verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+ }
+ switch (ctx->error) {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
+ DBUG_PRINT("info",("issuer= %s\n",buf));
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ DBUG_PRINT("error", ("notBefore"));
+ /*ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));*/
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ DBUG_PRINT("error", ("notAfter error"));
+ /*ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));*/
+ break;
+ }
+ DBUG_PRINT("exit", ("%d", ok));
+ DBUG_RETURN(ok);
+}
+
+
+/************************ VioSSLConnectorFd **********************************/
+struct st_VioSSLConnectorFd *
+new_VioSSLConnectorFd(const char* key_file,
+ const char* cert_file,
+ const char* ca_file,
+ const char* ca_path,
+ const char* cipher)
+{
+ int verify = SSL_VERIFY_PEER;
+ struct st_VioSSLConnectorFd* ptr;
+ int result;
+ DH *dh=NULL;
+ DBUG_ENTER("new_VioSSLConnectorFd");
+ DBUG_PRINT("enter",
+ ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
+ key_file, cert_file, ca_path, ca_file, cipher));
+
+ if (!(ptr=((struct st_VioSSLConnectorFd*)
+ my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
+ DBUG_RETURN(0);
+
+ ptr->ssl_context_= 0;
+ ptr->ssl_method_= 0;
+ /* FIXME: constants! */
+
+ if (!ssl_algorithms_added)
+ {
+ DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
+ ssl_algorithms_added = TRUE;
+ OpenSSL_add_all_algorithms();
+ }
+ if (!ssl_error_strings_loaded)
+ {
+ DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
+ ssl_error_strings_loaded = TRUE;
+ SSL_load_error_strings();
+ }
+ ptr->ssl_method_ = TLSv1_client_method();
+ ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_);
+ DBUG_PRINT("info", ("ssl_context_: %p",ptr->ssl_context_));
+ if (ptr->ssl_context_ == 0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_new failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ /*
+ SSL_CTX_set_options
+ SSL_CTX_set_info_callback
+ */
+ if (cipher)
+ {
+ result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher);
+ DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ }
+ SSL_CTX_set_verify(ptr->ssl_context_, verify, vio_verify_callback);
+ if (vio_set_cert_stuff(ptr->ssl_context_, cert_file, key_file) == -1)
+ {
+ DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ if (SSL_CTX_load_verify_locations( ptr->ssl_context_, ca_file,ca_path) == 0)
+ {
+ DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
+ if (SSL_CTX_set_default_verify_paths(ptr->ssl_context_) == 0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ }
+
+ /* DH stuff */
+ dh=get_dh512();
+ SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh);
+ DH_free(dh);
+
+ DBUG_RETURN(ptr);
+ctor_failure:
+ DBUG_PRINT("exit", ("there was an error"));
+ my_free((gptr)ptr,MYF(0));
+ DBUG_RETURN(0);
+}
+
+
+/************************ VioSSLAcceptorFd **********************************/
+
+struct st_VioSSLAcceptorFd*
+new_VioSSLAcceptorFd(const char *key_file,
+ const char *cert_file,
+ const char *ca_file,
+ const char *ca_path,
+ const char *cipher)
+{
+ int verify = (SSL_VERIFY_PEER |
+ SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
+ SSL_VERIFY_CLIENT_ONCE);
+ struct st_VioSSLAcceptorFd* ptr;
+ int result;
+ DH *dh=NULL;
+ DBUG_ENTER("new_VioSSLAcceptorFd");
+ DBUG_PRINT("enter",
+ ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
+ key_file, cert_file, ca_path, ca_file, cipher));
+
+ ptr= ((struct st_VioSSLAcceptorFd*)
+ my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)));
+ ptr->ssl_context_=0;
+ ptr->ssl_method_=0;
+ /* FIXME: constants! */
+ ptr->session_id_context_ = ptr;
+
+ if (!ssl_algorithms_added)
+ {
+ DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
+ ssl_algorithms_added = TRUE;
+ OpenSSL_add_all_algorithms();
+
+ }
+ if (!ssl_error_strings_loaded)
+ {
+ DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
+ ssl_error_strings_loaded = TRUE;
+ SSL_load_error_strings();
+ }
+ ptr->ssl_method_= TLSv1_server_method();
+ ptr->ssl_context_= SSL_CTX_new(ptr->ssl_method_);
+ if (ptr->ssl_context_ == 0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_new failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ if (cipher)
+ {
+ result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher);
+ DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ }
+ /* SSL_CTX_set_quiet_shutdown(ctx,1); */
+ SSL_CTX_sess_set_cache_size(ptr->ssl_context_,128);
+
+ /* DH? */
+ SSL_CTX_set_verify(ptr->ssl_context_, verify, vio_verify_callback);
+ SSL_CTX_set_session_id_context(ptr->ssl_context_,
+ (const uchar*) &(ptr->session_id_context_),
+ sizeof(ptr->session_id_context_));
+
+ /*
+ SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+ */
+ if (vio_set_cert_stuff(ptr->ssl_context_, cert_file, key_file) == -1)
+ {
+ DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ if (SSL_CTX_load_verify_locations( ptr->ssl_context_, ca_file, ca_path) == 0)
+ {
+ DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
+ if (SSL_CTX_set_default_verify_paths(ptr->ssl_context_)==0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ }
+ /* DH stuff */
+ dh=get_dh512();
+ SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh);
+ DH_free(dh);
+ DBUG_RETURN(ptr);
+
+ctor_failure:
+ DBUG_PRINT("exit", ("there was an error"));
+ my_free((gptr) ptr,MYF(0));
+ DBUG_RETURN(0);
+}
+
+
+#endif /* HAVE_OPENSSL */
diff --git a/vio/viotest-ssl.c b/vio/viotest-ssl.c
new file mode 100644
index 00000000000..1a766a3fc97
--- /dev/null
+++ b/vio/viotest-ssl.c
@@ -0,0 +1,156 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#ifndef __GNU_LIBRARY__
+#define __GNU_LIBRARY__ // Skip warnings in getopt.h
+#endif
+#include <my_getopt.h>
+//#include "my_readline.h"
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,/tmp/viotest-ssl.trace";
+#endif
+
+void
+fatal_error( const char* r)
+{
+ perror(r);
+ exit(0);
+}
+
+void
+print_usage()
+{
+ printf("viossl-test: testing SSL virtual IO. Usage:\n");
+ printf("viossl-test server-key server-cert client-key client-cert [CAfile] [CApath]\n");
+}
+
+int
+main( int argc,
+ char** argv)
+{
+ char* server_key = 0;
+ char* server_cert = 0;
+ char* client_key = 0;
+ char* client_cert = 0;
+ char* ca_file = 0;
+ char* ca_path = 0;
+ int child_pid,sv[2];
+ struct st_VioSSLAcceptorFd* ssl_acceptor=0;
+ struct st_VioSSLConnectorFd* ssl_connector=0;
+ Vio* client_vio=0;
+ Vio* server_vio=0;
+ MY_INIT(argv[0]);
+// DBUG_ENTER("main");
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+
+
+ if (argc<5)
+ {
+ print_usage();
+ return 1;
+ }
+
+ server_key = argv[1];
+ server_cert = argv[2];
+ client_key = argv[3];
+ client_cert = argv[4];
+ if (argc>5)
+ ca_file = argv[5];
+ if (argc>6)
+ ca_path = argv[6];
+ printf("Server key/cert : %s/%s\n", server_key, server_cert);
+ printf("Client key/cert : %s/%s\n", client_key, client_cert);
+ if (ca_file!=0)
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
+ fatal_error("socketpair");
+
+ ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path);
+ ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path);
+
+ client_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ client_vio->sd = sv[0];
+ sslconnect(ssl_connector,client_vio);
+ server_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ server_vio->sd = sv[1];
+ sslaccept(ssl_acceptor,server_vio);
+
+ printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
+
+ child_pid = fork();
+ if (child_pid==-1) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("fork");
+ }
+ if (child_pid==0) {
+ //child, therefore, client
+ char xbuf[100];
+ int r = vio_ssl_read(client_vio,xbuf, sizeof(xbuf));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("client:SSL_read");
+ }
+// printf("*** client cipher %s\n",client_vio->cipher_description());
+ xbuf[r] = 0;
+ printf("client:got %s\n", xbuf);
+ my_free((gptr)client_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ sleep(1);
+ } else {
+ const char* s = "Huhuhuh";
+ int r = vio_ssl_write(server_vio,(gptr)s, strlen(s));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("server:SSL_write");
+ }
+// printf("*** server cipher %s\n",server_vio->cipher_description());
+ my_free((gptr)server_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ sleep(1);
+ }
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/viotest-ssl.cc b/vio/viotest-ssl.cc
deleted file mode 100644
index a3ad92a7c9c..00000000000
--- a/vio/viotest-ssl.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "all.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdio.h>
-#include <unistd.h>
-
-
-void
-fatal_error( const char* r)
-{
- perror(r);
- exit(0);
-}
-
-void
-print_usage()
-{
- printf("viossltest: testing SSL virtual IO. Usage:\n");
- printf("viossltest server-key server-cert client-key client-cert [CAfile] [CApath]\n");
-}
-
-int
-main( int argc,
- char** argv)
-{
- char* server_key = 0;
- char* server_cert = 0;
- char* client_key = 0;
- char* client_cert = 0;
- char* ca_file = 0;
- char* ca_path = 0;
- int sv[2];
-
- if (argc<5)
- {
- print_usage();
- return 1;
- }
-
- if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
- fatal_error("socketpair");
-
- server_key = argv[1];
- server_cert = argv[2];
- client_key = argv[3];
- client_cert = argv[4];
- if (argc>5)
- ca_file = argv[5];
- if (argc>6)
- ca_path = argv[6];
- printf("Server key/cert : %s/%s\n", server_key, server_cert);
- printf("Client key/cert : %s/%s\n", client_key, client_cert);
- if (ca_file!=0)
- printf("CAfile : %s\n", ca_file);
- if (ca_path!=0)
- printf("CApath : %s\n", ca_path);
-
- VIO_NS::VioSSLAcceptorFd* ssl_acceptor = new VIO_NS::VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path);
- VIO_NS::VioSSLConnectorFd* ssl_connector = new VIO_NS::VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path);
-
- printf("Socketpair: %d , %d\n", sv[0], sv[1]);
-
- VIO_NS::VioSSL* client_vio = ssl_connector->connect(sv[0]);
- VIO_NS::VioSSL* server_vio = ssl_acceptor->accept(sv[1]);
-
-
- int child_pid = fork();
- if (child_pid==-1) {
- delete ssl_acceptor;
- delete ssl_connector;
- fatal_error("fork");
- }
- if (child_pid==0) {
- //child, therefore, client
- char xbuf[100];
- int r = client_vio->read(xbuf, sizeof(xbuf));
- if (r<=0) {
- delete ssl_acceptor;
- delete ssl_connector;
- fatal_error("client:SSL_read");
- }
- printf("*** client cipher %s\n",client_vio->cipher_description());
- xbuf[r] = 0;
- printf("client:got %s\n", xbuf);
- delete client_vio;
- delete ssl_acceptor;
- delete ssl_connector;
- sleep(1);
- } else {
- const char* s = "Huhuhuh";
- int r = server_vio->write((void *)s, strlen(s));
- if (r<=0) {
- delete ssl_acceptor;
- delete ssl_connector;
- fatal_error("server:SSL_write");
- }
- printf("*** server cipher %s\n",server_vio->cipher_description());
- delete server_vio;
- delete ssl_acceptor;
- delete ssl_connector;
- sleep(1);
- }
-}
diff --git a/vio/viotypes.h b/vio/viotypes.h
deleted file mode 100644
index 8d36a35c86f..00000000000
--- a/vio/viotypes.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * Some typedefs to external types.
- */
-#ifndef vio_viotypes_h_
-#define vio_viotypes_h_
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-typedef int vio_bool_t;
-typedef void* vio_ptr_t;
-
-#ifdef __cplusplus
-VIO_NS_BEGIN
-
-typedef vio_ptr_t vio_ptr;
-typedef char* vio_cstring;
-typedef int32_t vio_int32;
-typedef u_int32_t vio_uint32;
-typedef vio_bool_t vio_bool;
-
-VIO_NS_END
-#endif /* __cplusplus */
-
-#endif /* vio_types_h_ */
-